diff --git a/drivers/misc/mediatek/Makefile b/drivers/misc/mediatek/Makefile index be95574a6ae82d4d0d994379f41e52c9f78705aa..f216172c1b3b8949e52bea489ed9a5acfb35146e 100644 --- a/drivers/misc/mediatek/Makefile +++ b/drivers/misc/mediatek/Makefile @@ -6,6 +6,7 @@ subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/ subdir-ccflags-y += -I$(srctree)/drivers/mmc/host/mediatek/$(MTK_PLATFORM) obj-$(CONFIG_MTK_MET) += met_drv/ +obj-y += met_drv_v2/ obj-$(CONFIG_MTK_BASE_POWER) += base/ obj-$(CONFIG_MTK_PWM) += pwm/ obj-$(CONFIG_MTK_IRTX_PWM_SUPPORT) += irtx/ @@ -119,3 +120,4 @@ obj-$(CONFIG_MTK_GIC_EXT) += ext_gic/ obj-$(CONFIG_MTK_SYS_CIRQ) += cirq/ obj-$(CONFIG_MTK_SECURITY_SW_SUPPORT) += masp/ obj-y += rps/ +obj-$(CONFIG_MTK_FPSGO_V3) += fpsgo_cus/ diff --git a/drivers/misc/mediatek/connectivity/Makefile b/drivers/misc/mediatek/connectivity/Makefile index 1db2b3532be421020b844613b0f877b40e956760..387dd83709ac5df41e4993fc21f80c2ab140cb6e 100644 --- a/drivers/misc/mediatek/connectivity/Makefile +++ b/drivers/misc/mediatek/connectivity/Makefile @@ -37,6 +37,13 @@ ifneq ($(KERNELRELEASE),) ifeq ($(CONFIG_MTK_COMBO), y) ccflags-y += -D CFG_CONNADP_BUILD_IN endif + + # for gen4m options + export CONFIG_MTK_COMBO_WIFI_HIF=axi + export MTK_COMBO_CHIP=CONNAC + export WLAN_CHIP_ID=6765 + export MTK_ANDROID_WMT=y + # Do build-in for Makefile checking # export CONFIG_WLAN_DRV_BUILD_IN=y @@ -72,12 +79,6 @@ ifneq ($(KERNELRELEASE),) $(shell ln -s $(ABS_PATH_TO_WLAN_CHR_DRV) $(srctree)/$(src)/wmt_chrdev_wifi) $(shell ln -s $(ABS_PATH_TO_WLAN_DRV) $(srctree)/$(src)/wlan_drv_gen4m) - # for gen4m options - export CONFIG_MTK_COMBO_WIFI_HIF=axi - export MTK_COMBO_CHIP=CONNAC - export WLAN_CHIP_ID=6765 - export MTK_ANDROID_WMT=y - # Do build-in for xxx.c checking subdir-ccflags-y += -D MTK_WCN_REMOVE_KERNEL_MODULE subdir-ccflags-y += -D MTK_WCN_BUILT_IN_DRIVER @@ -86,6 +87,13 @@ ifneq ($(KERNELRELEASE),) obj-y += wlan_drv_gen4m/ endif + obj-$(CONFIG_MTK_COMBO) += common/ + obj-$(CONFIG_MTK_COMBO_WIFI) += wlan/adaptor/ + obj-$(CONFIG_MTK_COMBO_CHIP_CONSYS_6765) += wlan/core/gen4m/ + obj-$(CONFIG_MTK_BTIF) += bt/mt66xx/legacy/ + obj-$(CONFIG_MTK_COMBO_GPS) += gps/ + obj-$(CONFIG_MTK_FMRADIO) += fmradio/ + # Otherwise we were called directly from the command line; # invoke the kernel build system. else diff --git a/drivers/misc/mediatek/connectivity/bt/mt66xx/legacy/Makefile b/drivers/misc/mediatek/connectivity/bt/mt66xx/legacy/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..21d897d14398f29fc8edc7a9e67aef394e904c29 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/bt/mt66xx/legacy/Makefile @@ -0,0 +1,49 @@ +MTK_PLATFORM := $(subst ",,$(CONFIG_MTK_PLATFORM)) +############################################################################### +# Bluetooth character device driver + +ifneq ($(CFG_BT_PM_QOS_CONTROL),) + $(warning set PM_QOS_CONTROL=1) + ccflags-y += -D PM_QOS_CONTROL=1 +else + ccflags-y += -D PM_QOS_CONTROL=0 +endif + +# Force build fail on modpost warning +KBUILD_MODPOST_FAIL_ON_WARNINGS := y +############################################################################### +# To add WMT dependent Macro and header file, will be removed later + +ccflags-y += -D MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT +ccflags-y += -I$(srctree)/drivers/misc/mediatek/include +ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat +ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include + +ifeq ($(CONFIG_MTK_CONN_LTE_IDC_SUPPORT),y) + ccflags-y += -D WMT_IDC_SUPPORT=1 +else + ccflags-y += -D WMT_IDC_SUPPORT=0 +endif + +############################################################################### +# To include BT driver dependent header file + +WMT_SRC_FOLDER := $(srctree)/drivers/misc/mediatek/connectivity/common +ccflags-y += -I$(WMT_SRC_FOLDER)/common_main/include +ccflags-y += -I$(WMT_SRC_FOLDER)/common_main/linux/include +ifneq ($(CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH),) +ccflags-y += -I$(WMT_SRC_FOLDER)/debug_utility +endif + +############################################################################### + +MODULE_NAME := bt_drv +obj-m += $(MODULE_NAME).o + +ccflags-y += -D CREATE_NODE_DYNAMIC=1 + +$(MODULE_NAME)-objs += stp_chrdev_bt.o +$(MODULE_NAME)-objs += dbg_bt.o +ifneq ($(CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH),) +$(MODULE_NAME)-objs += fw_log_bt.o +endif diff --git a/drivers/misc/mediatek/connectivity/bt/mt66xx/legacy/bt.h b/drivers/misc/mediatek/connectivity/bt/mt66xx/legacy/bt.h new file mode 100644 index 0000000000000000000000000000000000000000..febe31c2dba447823321e791d83cfdeecf2ff630 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/bt/mt66xx/legacy/bt.h @@ -0,0 +1,138 @@ +/* +* Copyright (C) 2016 MediaTek Inc. +* +* This program is free software: you can redistribute it and/or modify it under the terms of the +* GNU General Public License version 2 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. +* +* You should have received a copy of the GNU General Public License along with this program. +* If not, see . +*/ + +#ifndef _BT_EXP_H_ +#define _BT_EXP_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wmt_exp.h" +#include "stp_exp.h" + + +#define TRUE 1 +#define FALSE 0 + +/* Flags to control BT FW log flow */ +#define OFF 0x00 +#define ON 0xff + +#define PFX "[MTK-BT]" +#define BT_LOG_DBG 4 +#define BT_LOG_INFO 3 +#define BT_LOG_WARN 2 +#define BT_LOG_ERR 1 +#define RAW_MAX_BYTES 30 + +static uint8_t raw_buf[RAW_MAX_BYTES * 5 + 10]; +extern UINT32 gBtDbgLevel; + +#define BT_LOG_PRT_DBG(fmt, arg...) \ + do { if (gBtDbgLevel >= BT_LOG_DBG) pr_info(PFX "%s: " fmt, __func__, ##arg); } while (0) +#define BT_LOG_PRT_INFO(fmt, arg...) \ + do { if (gBtDbgLevel >= BT_LOG_INFO) pr_info(PFX "%s: " fmt, __func__, ##arg); } while (0) +#define BT_LOG_PRT_WARN(fmt, arg...) \ + do { if (gBtDbgLevel >= BT_LOG_WARN) pr_info(PFX "%s: " fmt, __func__, ##arg); } while (0) +#define BT_LOG_PRT_ERR(fmt, arg...) \ + do { if (gBtDbgLevel >= BT_LOG_ERR) pr_info(PFX "%s: " fmt, __func__, ##arg); } while (0) +#define BT_LOG_PRT_INFO_RATELIMITED(fmt, arg...) \ + do { if (gBtDbgLevel >= BT_LOG_ERR) pr_info_ratelimited(PFX "%s: " fmt, __func__, ##arg); } while (0) + +#define BT_LOG_PRT_DBG_RAW(p, l, fmt, ...) \ + do { \ + if (gBtDbgLevel >= BT_LOG_DBG) { \ + int cnt_ = 0; \ + int len_ = (l <= RAW_MAX_BYTES ? l : RAW_MAX_BYTES); \ + const unsigned char *ptr = p; \ + for (cnt_ = 0; cnt_ < len_; ++cnt_) { \ + if (snprintf(raw_buf+5*cnt_, 6, "0x%02X ", ptr[cnt_]) < 0) { \ + pr_info("snprintf error\n"); \ + break; \ + } \ + } \ + raw_buf[5*cnt_] = '\0'; \ + if (l <= RAW_MAX_BYTES) { \ + pr_info(PFX" "fmt"%s\n", ##__VA_ARGS__, raw_buf); \ + } else { \ + pr_info(PFX" "fmt"%s (prtail)\n", ##__VA_ARGS__, raw_buf); \ + } \ + } \ + } while (0) + +#define BT_LOG_PRT_INFO_RAW(p, l, fmt, ...) \ + do { \ + if (gBtDbgLevel >= BT_LOG_INFO) { \ + int cnt_ = 0; \ + int len_ = (l <= RAW_MAX_BYTES ? l : RAW_MAX_BYTES); \ + const unsigned char *ptr = p; \ + for (cnt_ = 0; cnt_ < len_; ++cnt_) { \ + if (snprintf(raw_buf+5*cnt_, 6, "0x%02X ", ptr[cnt_]) < 0) { \ + pr_info("snprintf error\n"); \ + break; \ + } \ + } \ + raw_buf[5*cnt_] = '\0'; \ + if (l <= RAW_MAX_BYTES) { \ + pr_info(PFX" "fmt"%s\n", ##__VA_ARGS__, raw_buf); \ + } else { \ + pr_info(PFX" "fmt"%s (prtail)\n", ##__VA_ARGS__, raw_buf); \ + } \ + } \ + } while (0) + +struct bt_dbg_st { + bool trx_enable; + uint16_t trx_opcode; + struct completion trx_comp; + void(*trx_cb) (char *buf, int len); + int rx_len; + char rx_buf[64]; +}; + +struct pm_qos_ctrl { + struct semaphore sem; + struct workqueue_struct *task; + struct delayed_work work; + u_int8_t is_hold; +}; + +/* ***************************************************************************************** + * BT Logger Tool will send 3 levels(Low, SQC and Debug) + * Driver will not check its range so we can provide capability of extention. + ******************************************************************************************/ +#define DEFAULT_LEVEL 0x02 /* 0x00:OFF, 0x01: LOW POWER, 0x02: SQC, 0x03: DEBUG */ + +extern int fw_log_bt_init(void); +extern void fw_log_bt_exit(void); +extern void bt_state_notify(UINT32 on_off); +extern ssize_t send_hci_frame(const PUINT8 buf, size_t count); + +#endif + diff --git a/drivers/misc/mediatek/connectivity/bt/mt66xx/legacy/dbg_bt.c b/drivers/misc/mediatek/connectivity/bt/mt66xx/legacy/dbg_bt.c new file mode 100755 index 0000000000000000000000000000000000000000..313ffe747bc3095c9f9bf0a363b902f9e36bcdfb --- /dev/null +++ b/drivers/misc/mediatek/connectivity/bt/mt66xx/legacy/dbg_bt.c @@ -0,0 +1,367 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#include +#include +#include +#include "bt.h" + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ +#define BT_DBG_PROCNAME "driver/bt_dbg" +#define BUF_LEN_MAX 384 +#define BT_DBG_DUMP_BUF_SIZE 1024 +#define BT_DBG_PASSWD "4w2T8M65K5?2af+a " +#define BT_DBG_USER_TRX_PREFIX "[user-trx] " + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ +typedef int(*BT_DEV_DBG_FUNC) (int par1, int par2, int par3); +typedef struct { + BT_DEV_DBG_FUNC func; + bool turn_off_availavle; // function can be work when bt off +} tBT_DEV_DBG_STRUCT; + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +static int bt_dbg_get_bt_state(int par1, int par2, int par3); +static int bt_dbg_setlog_level(int par1, int par2, int par3); + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ +extern struct bt_dbg_st g_bt_dbg_st; +extern UINT32 gBtDbgLevel; +static struct proc_dir_entry *g_bt_dbg_entry; +static struct mutex g_bt_lock; +static char g_bt_dump_buf[BT_DBG_DUMP_BUF_SIZE]; +static char *g_bt_dump_buf_ptr; +static int g_bt_dump_buf_len; +static bool g_bt_turn_on = FALSE; +static bool g_bt_dbg_enable = FALSE; + +static const tBT_DEV_DBG_STRUCT bt_dev_dbg_struct[] = { + [0xb] = {bt_dbg_setlog_level, TRUE}, + [0xe] = {bt_dbg_get_bt_state, TRUE}, +}; + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +void _bt_dbg_reset_dump_buf(void) +{ + memset(g_bt_dump_buf, '\0', BT_DBG_DUMP_BUF_SIZE); + g_bt_dump_buf_ptr = g_bt_dump_buf; + g_bt_dump_buf_len = 0; +} + +int bt_dbg_get_bt_state(int par1, int par2, int par3) +{ + // 0x01: bt on, 0x00: bt off + BT_LOG_PRT_INFO("g_bt_turn_on[%d]\n", g_bt_turn_on); + _bt_dbg_reset_dump_buf(); + g_bt_dump_buf[0] = g_bt_turn_on; + g_bt_dump_buf[1] = '\0'; + g_bt_dump_buf_len = 2; + return 0; +} + +int bt_dbg_setlog_level(int par1, int par2, int par3) +{ + if (par2 < BT_LOG_ERR || par2 > BT_LOG_DBG) { + gBtDbgLevel = BT_LOG_INFO; + } else { + gBtDbgLevel = par2; + } + BT_LOG_PRT_INFO("gBtDbgLevel = %d\n", gBtDbgLevel); + return 0; +} + +ssize_t bt_dbg_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) +{ + int ret = 0; + int dump_len; + + ret = mutex_lock_killable(&g_bt_lock); + if (ret) { + BT_LOG_PRT_ERR("dump_lock fail!!\n"); + return ret; + } + + if (g_bt_dump_buf_len == 0) + goto exit; + + if (*f_pos == 0) + g_bt_dump_buf_ptr = g_bt_dump_buf; + + dump_len = g_bt_dump_buf_len >= count ? count : g_bt_dump_buf_len; + ret = copy_to_user(buf, g_bt_dump_buf_ptr, dump_len); + if (ret) { + BT_LOG_PRT_ERR("copy to dump info buffer failed, ret:%d\n", ret); + ret = -EFAULT; + goto exit; + } + + *f_pos += dump_len; + g_bt_dump_buf_len -= dump_len; + g_bt_dump_buf_ptr += dump_len; + BT_LOG_PRT_INFO("after read, wmt for dump info buffer len(%d)\n", g_bt_dump_buf_len); + + ret = dump_len; +exit: + + mutex_unlock(&g_bt_lock); + return ret; +} + +int _osal_strtol(const char *str, unsigned int adecimal, long *res) +{ + if (sizeof(long) == 4) + return kstrtou32(str, adecimal, (unsigned int *) res); + else + return kstrtol(str, adecimal, res); +} + +void bt_dbg_user_trx_cb(char *buf, int len) +{ + unsigned char *ptr = g_bt_dbg_st.rx_buf; + unsigned int i = 0, evt_len = 0; + int ret = 0; + + /* 1. bluedroid use partial read, this callback will enter several times + 2. this function read and parse the command_complete event */ + memcpy(&g_bt_dbg_st.rx_buf[g_bt_dbg_st.rx_len], buf, len); + g_bt_dbg_st.rx_len += len; + + // check the complete packet is read out by bluedroid + if(g_bt_dbg_st.rx_len != (g_bt_dbg_st.rx_buf[2] + 3)) + return; + + // if this event is not the desire one, skip and reset buffer + if((g_bt_dbg_st.rx_buf[4] + (g_bt_dbg_st.rx_buf[5] << 8)) != g_bt_dbg_st.trx_opcode) { + g_bt_dbg_st.rx_len = 0; + memset(g_bt_dbg_st.rx_buf, 0, sizeof(g_bt_dbg_st.rx_buf)); + return; + } + + // desire rx event is received, write to read buffer as string + evt_len = g_bt_dbg_st.rx_len; + BT_LOG_PRT_INFO_RAW(g_bt_dbg_st.rx_buf, evt_len, "%s: len[%ud], RxEvt: ", __func__, evt_len); + if(evt_len * 5 + 2 > BT_DBG_DUMP_BUF_SIZE) + return; + + _bt_dbg_reset_dump_buf(); + for (i = 0; i < evt_len; i++) { + ret = snprintf(g_bt_dump_buf + 5*i, 6, "0x%02X ", ptr[i]); + if (ret < 0) { + BT_LOG_PRT_ERR("error snprintf return value = [%d]\n", ret); + return; + } + } + + g_bt_dump_buf[5*evt_len] = '\n'; + g_bt_dump_buf[5*evt_len + 1] = '\0'; + g_bt_dump_buf_len = 5*evt_len + 1; + + // complete trx process + complete(&g_bt_dbg_st.trx_comp); +} + +void bt_dbg_user_trx_proc(char *cmd_raw) +{ +#define LEN_64 64 + unsigned char hci_cmd[LEN_64]; + unsigned int len = 0; + long tmp = 0; + char *ptr = NULL, *pRaw = NULL; + + // Parse command raw data + memset(hci_cmd, 0, sizeof(hci_cmd)); + pRaw = cmd_raw; + ptr = cmd_raw; + while(*ptr != '\0' && pRaw != NULL) { + if (len > LEN_64 - 1) { + BT_LOG_PRT_INFO("%s: skip since cmd length exceed!", __func__); + return; + } + ptr = strsep(&pRaw, " "); + if (ptr != NULL) { + _osal_strtol(ptr, 16, &tmp); + hci_cmd[len++] = (unsigned char)tmp; + } + } + + // Initialize rx variables + g_bt_dbg_st.rx_len = 0; + g_bt_dbg_st.trx_opcode = hci_cmd[1] + (hci_cmd[2] << 8); + memset(g_bt_dbg_st.rx_buf, 0, sizeof(g_bt_dbg_st.rx_buf)); + BT_LOG_PRT_INFO_RAW(hci_cmd, len, "%s: len[%ud], TxCmd: ", __func__, len); + + // Send command and wait for command_complete event + g_bt_dbg_st.trx_enable = TRUE; + send_hci_frame(hci_cmd, len); + if (!wait_for_completion_timeout(&g_bt_dbg_st.trx_comp, msecs_to_jiffies(2000))) + BT_LOG_PRT_ERR("%s: wait event timeout!", __func__); + g_bt_dbg_st.trx_enable = FALSE; +} + +ssize_t bt_dbg_write(struct file *filp, const char __user *buffer, size_t count, loff_t *f_pos) +{ + bool is_passwd = FALSE, is_turn_on = FALSE; + size_t len = count; + char buf[256], *pBuf; + int x = 0, y = 0, z = 0; + long res = 0; + char* pToken = NULL; + char* pDelimiter = " \t"; + + if (len <= 0 || len >= sizeof(buf)) { + BT_LOG_PRT_ERR("input handling fail!\n"); + len = sizeof(buf) - 1; + return -1; + } + + memset(buf, 0, sizeof(buf)); + if (copy_from_user(buf, buffer, len)) + return -EFAULT; + buf[len] = '\0'; + BT_LOG_PRT_INFO("g_bt_turn_on[%d], dbg_enable[%d], len[%d], data = %s\n", + g_bt_turn_on, g_bt_dbg_enable, (int)len, buf); + + /* Check debug function is enabled or not + * - not enable yet: user should enable it + * - already enabled: user can disable it + */ + if (len > strlen(BT_DBG_PASSWD) && + 0 == memcmp(buf, BT_DBG_PASSWD, strlen(BT_DBG_PASSWD))) { + is_passwd = TRUE; + if (0 == memcmp(buf + strlen(BT_DBG_PASSWD), "ON", strlen("ON"))) + is_turn_on = TRUE; + } + if(!g_bt_dbg_enable) { + if(is_passwd && is_turn_on) + g_bt_dbg_enable = TRUE; + return len; + } else { + if(is_passwd && !is_turn_on) { + g_bt_dbg_enable = FALSE; + return len; + } + } + + /* Mode 1: User trx flow: send command, get response */ + if (0 == memcmp(buf, BT_DBG_USER_TRX_PREFIX, strlen(BT_DBG_USER_TRX_PREFIX))) { + if(!g_bt_turn_on) // only work when bt on + return len; + buf[len - 1] = '\0'; + bt_dbg_user_trx_proc(buf + strlen(BT_DBG_USER_TRX_PREFIX)); + return len; + } + + /* Mode 2: Debug cmd flow, parse three parameters */ + pBuf = buf; + pToken = strsep(&pBuf, pDelimiter); + if (pToken != NULL) { + _osal_strtol(pToken, 16, &res); + x = (int)res; + } else { + x = 0; + } + + pToken = strsep(&pBuf, "\t\n "); + if (pToken != NULL) { + _osal_strtol(pToken, 16, &res); + y = (int)res; + BT_LOG_PRT_INFO("y = 0x%08x\n", y); + } else { + y = 3000; + /*efuse, register read write default value */ + if (0x5 == x || 0x6 == x) + y = 0x80000000; + } + + pToken = strsep(&pBuf, "\t\n "); + if (pToken != NULL) { + _osal_strtol(pToken, 16, &res); + z = (int)res; + } else { + z = 10; + /*efuse, register read write default value */ + if (0x5 == x || 0x6 == x) + z = 0xffffffff; + } + + BT_LOG_PRT_INFO("x(0x%08x), y(0x%08x), z(0x%08x)\n", x, y, z); + if (ARRAY_SIZE(bt_dev_dbg_struct) > x && NULL != bt_dev_dbg_struct[x].func) { + if(!g_bt_turn_on && !bt_dev_dbg_struct[x].turn_off_availavle) { + BT_LOG_PRT_WARN("command id(0x%08x) only work when bt on!\n", x); + } else { + (*bt_dev_dbg_struct[x].func) (x, y, z); + } + } else { + BT_LOG_PRT_WARN("command id(0x%08x) no handler defined!\n", x); + } + + return len; +} + +int bt_dev_dbg_init(void) +{ + int i_ret = 0; + static const struct file_operations bt_dbg_fops = { + .owner = THIS_MODULE, + .read = bt_dbg_read, + .write = bt_dbg_write, + }; + + // initialize debug function struct + g_bt_dbg_st.trx_enable = FALSE; + g_bt_dbg_st.trx_opcode = 0; + g_bt_dbg_st.trx_cb = bt_dbg_user_trx_cb; + init_completion(&g_bt_dbg_st.trx_comp); + + g_bt_dbg_entry = proc_create(BT_DBG_PROCNAME, 0664, NULL, &bt_dbg_fops); + if (g_bt_dbg_entry == NULL) { + BT_LOG_PRT_ERR("Unable to create [%s] bt proc entry\n", BT_DBG_PROCNAME); + i_ret = -1; + } + + mutex_init(&g_bt_lock); + + BT_LOG_PRT_INFO("create [%s] done\n", BT_DBG_PROCNAME); + return i_ret; +} + +int bt_dev_dbg_deinit(void) +{ + mutex_destroy(&g_bt_lock); + + if (g_bt_dbg_entry != NULL) { + proc_remove(g_bt_dbg_entry); + g_bt_dbg_entry = NULL; + } + + return 0; +} + + +int bt_dev_dbg_set_state(bool turn_on) +{ + g_bt_turn_on = turn_on; + return 0; +} diff --git a/drivers/misc/mediatek/connectivity/bt/mt66xx/legacy/fw_log_bt.c b/drivers/misc/mediatek/connectivity/bt/mt66xx/legacy/fw_log_bt.c new file mode 100644 index 0000000000000000000000000000000000000000..de10bf7c6f1461cd5f62462a0a50cf49db14f59c --- /dev/null +++ b/drivers/misc/mediatek/connectivity/bt/mt66xx/legacy/fw_log_bt.c @@ -0,0 +1,347 @@ +/* +* Copyright (C) 2016 MediaTek Inc. +* +* This program is free software: you can redistribute it and/or modify it under the terms of the +* GNU General Public License version 2 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. +* +* You should have received a copy of the GNU General Public License along with this program. +* If not, see . +*/ + +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH +#include "bt.h" +#include "connsys_debug_utility.h" + +MODULE_LICENSE("Dual BSD/GPL"); + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +#define BT_LOG_NODE_NAME "fw_log_bt" + +#define BT_FW_LOG_IOC_MAGIC (0xfc) +#define BT_FW_LOG_IOCTL_ON_OFF _IOW(BT_FW_LOG_IOC_MAGIC, 0, int) +#define BT_FW_LOG_IOCTL_SET_LEVEL _IOW(BT_FW_LOG_IOC_MAGIC, 1, int) +#define BT_FW_LOG_IOCTL_GET_LEVEL _IOW(BT_FW_LOG_IOC_MAGIC, 2, int) + +static unsigned char g_bt_on = OFF; +static unsigned char g_log_on = OFF; +static unsigned char g_log_level = DEFAULT_LEVEL; +static unsigned char g_log_current = OFF; + +#define BT_LOG_BUFFER_SIZE 512 + +static struct cdev log_cdev; +#if CREATE_NODE_DYNAMIC +static struct class *log_class; +static struct device *log_dev; +#endif +static dev_t devno; + +wait_queue_head_t BT_log_wq; + +static struct semaphore ioctl_mtx; + +static int ascii_to_hex(unsigned char ascii, unsigned char *hex) +{ + int ret = 0; + + if('0' <= ascii && ascii <= '9') + *hex = ascii - '0'; + else if ('a' <= ascii && ascii <= 'f') + *hex = ascii - 'a' + 10; + else if ('A' <= ascii && ascii <= 'F') + *hex = ascii - 'A' + 10; + else + ret = -1; + + return ret; +} + +static int set_fw_log(unsigned char flag) +{ + ssize_t retval = 0; + + /* Opcode 0xfc5d TCI_MTK_DEBUG_VERSION_INFO */ + unsigned char HCI_CMD_FW_LOG_DEBUG[] = {0x01, 0x5d, 0xfc, 0x04, 0x02, 0x00, 0x01, 0xff}; // Via EMI + + HCI_CMD_FW_LOG_DEBUG[7] = flag; + BT_LOG_PRT_INFO("hci_cmd: %02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x\n", + HCI_CMD_FW_LOG_DEBUG[0], HCI_CMD_FW_LOG_DEBUG[1], + HCI_CMD_FW_LOG_DEBUG[2], HCI_CMD_FW_LOG_DEBUG[3], + HCI_CMD_FW_LOG_DEBUG[4], HCI_CMD_FW_LOG_DEBUG[5], + HCI_CMD_FW_LOG_DEBUG[6], HCI_CMD_FW_LOG_DEBUG[7]); + + retval = send_hci_frame(HCI_CMD_FW_LOG_DEBUG, sizeof(HCI_CMD_FW_LOG_DEBUG)); + + if (likely(retval == sizeof(HCI_CMD_FW_LOG_DEBUG))) + return 0; + else if (retval < 0) + return retval; + else { + BT_LOG_PRT_ERR("Only partial sent %zu bytes, but hci cmd has %zu bytes", retval, sizeof(HCI_CMD_FW_LOG_DEBUG)); + return -EFAULT; + } +} + +void bt_state_notify(UINT32 on_off) +{ + BT_LOG_PRT_INFO("g_bt_on %d, on_off %d\n", g_bt_on, on_off); + + if (g_bt_on == on_off) { + // no change. + } else { + // changed. + if (on_off == OFF) { // should turn off. + g_bt_on = OFF; + BT_LOG_PRT_INFO("BT func off, no need to send hci cmd\n"); + } else { + g_bt_on = ON; + if(g_log_current) + set_fw_log(g_log_current); + } + } +} + +long fw_log_bt_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + long retval = 0; + unsigned char log_tmp = OFF; + + down(&ioctl_mtx); + switch (cmd) { + case BT_FW_LOG_IOCTL_ON_OFF: + /* connsyslogger daemon dynamically enable/disable Picus log */ + BT_LOG_PRT_INFO("BT_FW_LOG_IOCTL_ON_OFF: arg(%lu), g_bt_on(0x%02x), g_log_on(0x%02x), g_log_level(0x%02x), g_log_current(0x%02x)\n", + arg, g_bt_on, g_log_on, g_log_level, g_log_current); + log_tmp = (arg == 0 ? OFF: ON); + if (log_tmp == g_log_on) // no change + break; + else { // changed + g_log_on = log_tmp; + g_log_current = g_log_on & g_log_level; + if (g_bt_on) + retval = set_fw_log(g_log_current); + } + break; + case BT_FW_LOG_IOCTL_SET_LEVEL: + /* connsyslogger daemon dynamically set Picus log level */ + BT_LOG_PRT_INFO("BT_FW_LOG_IOCTL_SET_LEVEL: arg(%lu), g_bt_on(0x%02x), g_log_on(0x%02x), g_log_level(0x%02x), g_log_current(0x%02x)\n", + arg, g_bt_on, g_log_on, g_log_level, g_log_current); + log_tmp = (unsigned char)arg; + if(log_tmp == g_log_level) // no change + break; + else { + g_log_level = log_tmp; + g_log_current = g_log_on & g_log_level; + if (g_bt_on & g_log_on) // driver on and log on + retval = set_fw_log(g_log_current); + } + break; + case BT_FW_LOG_IOCTL_GET_LEVEL: + retval = g_log_level; + BT_LOG_PRT_INFO("BT_FW_LOG_IOCTL_GET_LEVEL: %ld\n", retval); + break; + default: + BT_LOG_PRT_ERR("Unknown cmd: 0x%08x\n", cmd); + retval = -EOPNOTSUPP; + break; + } + + up(&ioctl_mtx); + return retval; +} + +long fw_log_bt_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + return fw_log_bt_unlocked_ioctl(filp, cmd, arg); +} + +static void fw_log_bt_event_cb(void) +{ + BT_LOG_PRT_DBG("fw_log_bt_event_cb"); + wake_up_interruptible(&BT_log_wq); +} + +static unsigned int fw_log_bt_poll(struct file *file, poll_table *wait) +{ + unsigned int mask = 0; + + poll_wait(file, &BT_log_wq, wait); + if (connsys_log_get_buf_size(CONNLOG_TYPE_BT) > 0) { + mask = (POLLIN | POLLRDNORM); + } + return mask; +} + +static ssize_t fw_log_bt_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) +{ + ssize_t retval = 0; + UINT8 tmp_buf[BT_LOG_BUFFER_SIZE] = {0}; + UINT8 hci_cmd[BT_LOG_BUFFER_SIZE] = {0}; + UINT8 tmp = 0, tmp_h = 0; + size_t i = 0, j = 0, k = 0; + + if(count >= BT_LOG_BUFFER_SIZE) { + BT_LOG_PRT_ERR("write count %zd exceeds max buffer size %d", count, BT_LOG_BUFFER_SIZE); + retval = -EINVAL; + goto OUT; + } + + if (copy_from_user(tmp_buf, buf, count)) { + BT_LOG_PRT_ERR("copy_from_user failed!\n"); + retval = -EFAULT; + } else { + BT_LOG_PRT_INFO("adb input: %s, len %zd\n", tmp_buf, strlen(tmp_buf)); + if (0 == memcmp(tmp_buf, "raw-hex,", strlen("raw-hex,"))) { + // Skip prefix + for(i = strlen("raw-hex,"); i < strlen(tmp_buf); i++) { + if(tmp_buf[i] == ' ') // get space + continue; + else if(tmp_buf[i] == '\r' || tmp_buf[i] =='\n') // get 0x0a('\n') or 0x0d('\r') + break; + // Two input char should turn to one byte + if (ascii_to_hex(tmp_buf[i], &tmp) == 0) { + if (j%2 == 0) + tmp_h = tmp; + else { + hci_cmd[k] = tmp_h * 16 + tmp; + BT_LOG_PRT_DBG("hci_cmd[%zd] = 0x%02x\n", k, hci_cmd[k]); + k++; + } + } else { + BT_LOG_PRT_ERR("get unexpected char %c\n", tmp_buf[i]); + retval = -EINVAL; + goto OUT; + } + j++; + } + } + // ONLY send hci cmd when BT func on + if (!g_bt_on) { + retval = -EIO; + BT_LOG_PRT_ERR("BT func off, skip to send hci cmd\n"); + } else + retval = send_hci_frame(hci_cmd, k); + + } +OUT: + + return retval; +} + +static ssize_t fw_log_bt_read(struct file *filp, char __user *buf, size_t len, loff_t *f_pos) +{ + size_t ret = 0; + + ret = connsys_log_read_to_user(CONNLOG_TYPE_BT, buf, len); + BT_LOG_PRT_DBG("BT F/W log from connsys len %zd\n", ret); + return ret; +} + +static int fw_log_bt_open(struct inode *inode, struct file *file) +{ + BT_LOG_PRT_INFO("major %d minor %d (pid %d)\n", imajor(inode), iminor(inode), current->pid); + return 0; +} + +static int fw_log_bt_close(struct inode *inode, struct file *file) +{ + BT_LOG_PRT_INFO("major %d minor %d (pid %d)\n", imajor(inode), iminor(inode), current->pid); + return 0; +} + +struct file_operations log_fops = { + .open = fw_log_bt_open, + .release = fw_log_bt_close, + .read = fw_log_bt_read, + .write = fw_log_bt_write, + .unlocked_ioctl = fw_log_bt_unlocked_ioctl, + .compat_ioctl = fw_log_bt_compat_ioctl, + .poll = fw_log_bt_poll +}; + +int fw_log_bt_init(void) +{ + INT32 alloc_ret = 0; + INT32 cdv_err = 0; + + connsys_log_init(CONNLOG_TYPE_BT); + + init_waitqueue_head(&BT_log_wq); + connsys_log_register_event_cb(CONNLOG_TYPE_BT, fw_log_bt_event_cb); + sema_init(&ioctl_mtx, 1); + + /* Allocate char device */ + alloc_ret = alloc_chrdev_region(&devno, 0, 1, BT_LOG_NODE_NAME); + if (alloc_ret) { + BT_LOG_PRT_ERR("Failed to register device numbers\n"); + return alloc_ret; + } + + cdev_init(&log_cdev, &log_fops); + log_cdev.owner = THIS_MODULE; + + cdv_err = cdev_add(&log_cdev, devno, 1); + if (cdv_err) + goto error; + +#if CREATE_NODE_DYNAMIC /* mknod replace */ + log_class = class_create(THIS_MODULE, BT_LOG_NODE_NAME); + if (IS_ERR(log_class)) + goto error; + + log_dev = device_create(log_class, NULL, devno, NULL, BT_LOG_NODE_NAME); + if (IS_ERR(log_dev)) + goto error; +#endif + + BT_LOG_PRT_INFO("%s driver(major %d, minor %d) installed\n", BT_LOG_NODE_NAME, MAJOR(devno), MINOR(devno)); + return 0; + +error: + +#if CREATE_NODE_DYNAMIC + if (log_dev && !IS_ERR(log_dev)) { + device_destroy(log_class, devno); + log_dev = NULL; + } + if (log_class && !IS_ERR(log_class)) { + class_destroy(log_class); + log_class = NULL; + } +#endif + if (cdv_err == 0) + cdev_del(&log_cdev); + + if (alloc_ret == 0) + unregister_chrdev_region(devno, 1); + + return -1; +} + +void fw_log_bt_exit(void) +{ + connsys_log_deinit(CONNLOG_TYPE_BT); + + cdev_del(&log_cdev); + unregister_chrdev_region(devno, 1); + +#if CREATE_NODE_DYNAMIC + if (log_dev && !IS_ERR(log_dev)) { + device_destroy(log_class, devno); + log_dev = NULL; + } + if (log_class && !IS_ERR(log_class)) { + class_destroy(log_class); + log_class = NULL; + } +#endif + BT_LOG_PRT_INFO("%s driver removed\n", BT_LOG_NODE_NAME); +} +#endif diff --git a/drivers/misc/mediatek/connectivity/bt/mt66xx/legacy/init.bt_drv.rc b/drivers/misc/mediatek/connectivity/bt/mt66xx/legacy/init.bt_drv.rc new file mode 100644 index 0000000000000000000000000000000000000000..b857ffba811c51c9c73f506a19fce8719edec8d7 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/bt/mt66xx/legacy/init.bt_drv.rc @@ -0,0 +1,4 @@ +# load bt_drv +on property:vendor.connsys.driver.ready=yes + insmod /vendor/lib/modules/bt_drv.ko + chown bluetooth bluetooth /proc/driver/bt_dbg \ No newline at end of file diff --git a/drivers/misc/mediatek/connectivity/bt/mt66xx/legacy/stp_chrdev_bt.c b/drivers/misc/mediatek/connectivity/bt/mt66xx/legacy/stp_chrdev_bt.c new file mode 100644 index 0000000000000000000000000000000000000000..9cf910b731a263c8e73a12153aec34af8e6abbc6 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/bt/mt66xx/legacy/stp_chrdev_bt.c @@ -0,0 +1,891 @@ +/* +* Copyright (C) 2016 MediaTek Inc. +* +* This program is free software: you can redistribute it and/or modify it under the terms of the +* GNU General Public License version 2 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. +* +* You should have received a copy of the GNU General Public License along with this program. +* If not, see . +*/ + +#include "bt.h" +#include +#include +#include +#include +#include +#include + +MODULE_LICENSE("Dual BSD/GPL"); + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +#define BT_DRIVER_NAME "mtk_stp_bt_chrdev" +#define BT_DEV_MAJOR 192 + +#define VERSION "2.0" + +#define COMBO_IOC_MAGIC 0xb0 +#define COMBO_IOCTL_FW_ASSERT _IOW(COMBO_IOC_MAGIC, 0, int) +#define COMBO_IOCTL_BT_SET_PSM _IOW(COMBO_IOC_MAGIC, 1, bool) +#define COMBO_IOCTL_BT_IC_HW_VER _IOR(COMBO_IOC_MAGIC, 2, void*) +#define COMBO_IOCTL_BT_IC_FW_VER _IOR(COMBO_IOC_MAGIC, 3, void*) + +#define BT_BUFFER_SIZE 2048 +#define FTRACE_STR_LOG_SIZE 256 +#define REG_READL(addr) readl((volatile uint32_t *)(addr)) + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ +static INT32 BT_devs = 1; +static INT32 BT_major = BT_DEV_MAJOR; +module_param(BT_major, uint, 0); +static struct cdev BT_cdev; +#if CREATE_NODE_DYNAMIC +static struct class *stpbt_class; +static struct device *stpbt_dev; +#endif + +static UINT8 i_buf[BT_BUFFER_SIZE]; /* Input buffer for read */ +static UINT8 o_buf[BT_BUFFER_SIZE]; /* Output buffer for write */ + +static struct semaphore wr_mtx, rd_mtx; +static struct wakeup_source *bt_wakelock; +/* Wait queue for poll and read */ +static wait_queue_head_t inq; +static DECLARE_WAIT_QUEUE_HEAD(BT_wq); +static INT32 flag; +static INT32 bt_ftrace_flag; +static bool btonflag = 0; +UINT32 gBtDbgLevel = BT_LOG_INFO; +struct bt_dbg_st g_bt_dbg_st; +#if (PM_QOS_CONTROL == 1) +static struct pm_qos_request qos_req; +static struct pm_qos_ctrl qos_ctrl; +#endif + +/* + * Reset flag for whole chip reset scenario, to indicate reset status: + * 0 - normal, no whole chip reset occurs + * 1 - reset start + * 2 - reset end, have not sent Hardware Error event yet + * 3 - reset end, already sent Hardware Error event + */ +static UINT32 rstflag; +static UINT8 HCI_EVT_HW_ERROR[] = {0x04, 0x10, 0x01, 0x00}; +static loff_t rd_offset; + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +extern int bt_dev_dbg_init(void); +extern int bt_dev_dbg_deinit(void); +extern int bt_dev_dbg_set_state(bool turn_on); + +static INT32 ftrace_print(const PINT8 str, ...) +{ +#ifdef CONFIG_TRACING + va_list args; + int ret = 0; + INT8 temp_string[FTRACE_STR_LOG_SIZE]; + + if (bt_ftrace_flag) { + va_start(args, str); + ret = vsnprintf(temp_string, FTRACE_STR_LOG_SIZE, str, args); + va_end(args); + if (ret < 0) { + BT_LOG_PRT_ERR("error return value in vsnprintf ret = [%d]\n", ret); + return 0; + } + trace_printk("%s\n", temp_string); + } +#endif + return 0; +} + +static size_t bt_report_hw_error(char *buf, size_t count, loff_t *f_pos) +{ + size_t bytes_rest, bytes_read; + + if (*f_pos == 0) + BT_LOG_PRT_INFO("Send Hardware Error event to stack to restart Bluetooth\n"); + + bytes_rest = sizeof(HCI_EVT_HW_ERROR) - *f_pos; + bytes_read = count < bytes_rest ? count : bytes_rest; + memcpy(buf, HCI_EVT_HW_ERROR + *f_pos, bytes_read); + *f_pos += bytes_read; + + return bytes_read; +} + +static uint32_t inline bt_read_cr(unsigned char *cr_name, uint32_t addr) +{ + uint32_t value = 0; + uint8_t *base = ioremap_nocache(addr, 0x10); + + if (base == NULL) { + BT_LOG_PRT_WARN("remapping 0x%08x fail\n", addr); + } else { + value = REG_READL(base); + iounmap(base); + BT_LOG_PRT_INFO("%s[0x%08x], read[0x%08x]\n", cr_name, addr, value); + } + return value; +} + +/* +static struct notifier_block bt_fb_notifier; +static int bt_fb_notifier_callback(struct notifier_block + *self, unsigned long event, void *data) +{ + struct fb_event *evdata = data; + int32_t blank = 0; + + if ((event != FB_EVENT_BLANK)) + return 0; + + blank = *(int32_t *)evdata->data; + switch (blank) { + case FB_BLANK_UNBLANK: + case FB_BLANK_POWERDOWN: + if(btonflag == 1 && rstflag == 0) { + BT_LOG_PRT_INFO("blank state [%ld]", blank); + bt_read_cr("HOST_MAILBOX_BT_ADDR", 0x18007124); + } + break; + default: + break; + } + + return 0; +} + +static int bt_fb_notify_register(void) +{ + int32_t ret; + + bt_fb_notifier.notifier_call = bt_fb_notifier_callback; + + ret = fb_register_client(&bt_fb_notifier); + if (ret) + BT_LOG_PRT_WARN("Register bt_fb_notifier failed:%d\n", ret); + else + BT_LOG_PRT_DBG("Register bt_fb_notifier succeed\n"); + + return ret; +} + +static void bt_fb_notify_unregister(void) +{ + fb_unregister_client(&bt_fb_notifier); +} +*/ + +static struct notifier_block bt_pm_notifier; +static int bt_pm_notifier_callback(struct notifier_block *nb, + unsigned long event, void *dummy) +{ + BT_LOG_PRT_INFO("%s: btonflag[%d], event[%ld]", __func__, btonflag, event); + switch (event) { + case PM_SUSPEND_PREPARE: + case PM_POST_SUSPEND: + if(btonflag == 1 && rstflag == 0) { + // for fw debug power issue + bt_read_cr("HOST_MAILBOX_BT_ADDR", 0x18007124); + } + break; + default: + break; + } + return NOTIFY_DONE; +} + +static int bt_pm_notify_register(void) +{ + int32_t ret; + + bt_pm_notifier.notifier_call = bt_pm_notifier_callback; + + ret = register_pm_notifier(&bt_pm_notifier); + if (ret) + BT_LOG_PRT_ERR("Register bt_pm_notifier failed:%d\n", ret); + else + BT_LOG_PRT_INFO("Register bt_pm_notifier succeed\n"); + + return ret; +} + +static void bt_pm_notify_unregister(void) +{ + unregister_pm_notifier(&bt_pm_notifier); +} + +/******************************************************************* +* WHOLE CHIP RESET message handler +******************************************************************** +*/ +static VOID bt_cdev_rst_cb(ENUM_WMTDRV_TYPE_T src, + ENUM_WMTDRV_TYPE_T dst, ENUM_WMTMSG_TYPE_T type, PVOID buf, UINT32 sz) +{ + ENUM_WMTRSTMSG_TYPE_T rst_msg; + + if (sz > sizeof(ENUM_WMTRSTMSG_TYPE_T)) { + BT_LOG_PRT_WARN("Invalid message format!\n"); + return; + } + + memcpy((PINT8)&rst_msg, (PINT8)buf, sz); + BT_LOG_PRT_DBG("src = %d, dst = %d, type = %d, buf = 0x%x sz = %d, max = %d\n", + src, dst, type, rst_msg, sz, WMTRSTMSG_RESET_MAX); + if ((src == WMTDRV_TYPE_WMT) && (dst == WMTDRV_TYPE_BT) && (type == WMTMSG_TYPE_RESET)) { + switch (rst_msg) { + case WMTRSTMSG_RESET_START: +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH + bt_state_notify(OFF); +#endif + BT_LOG_PRT_INFO("Whole chip reset start!\n"); + rstflag = 1; + break; + + case WMTRSTMSG_RESET_END: + case WMTRSTMSG_RESET_END_FAIL: + if (rst_msg == WMTRSTMSG_RESET_END) + BT_LOG_PRT_INFO("Whole chip reset end!\n"); + else + BT_LOG_PRT_INFO("Whole chip reset fail!\n"); + rd_offset = 0; + rstflag = 2; + flag = 1; + wake_up_interruptible(&inq); + wake_up(&BT_wq); + break; + + default: + break; + } + } +} + +static VOID BT_event_cb(VOID) +{ + BT_LOG_PRT_DBG("BT_event_cb\n"); + ftrace_print("%s get called", __func__); + + /* + * Hold wakelock for 100ms to avoid system enter suspend in such case: + * FW has sent data to host, STP driver received the data and put it + * into BT rx queue, then send sleep command and release wakelock as + * quick sleep mechanism for low power, BT driver will wake up stack + * hci thread stuck in poll or read. + * But before hci thread comes to read data, system enter suspend, + * hci command timeout timer keeps counting during suspend period till + * expires, then the RTC interrupt wakes up system, command timeout + * handler is executed and meanwhile the event is received. + * This will false trigger FW assert and should never happen. + */ + __pm_wakeup_event(bt_wakelock, 100); + +#if (PM_QOS_CONTROL == 1) + /* pm qos control: + * Set pm_qos to higher level for mass data transfer. + * When rx packet reveived, schedule a work to restore pm_qos setting after 500ms. + * If next packet is receiving before 500ms, this work will be cancel & re-schedule. + * (500ms: better power performance after experiment) + */ + down(&qos_ctrl.sem); + if(qos_ctrl.task != NULL ) { + cancel_delayed_work(&qos_ctrl.work); + if(qos_ctrl.is_hold == FALSE) { + pm_qos_update_request(&qos_req, 1000); + qos_ctrl.is_hold = TRUE; + BT_LOG_PRT_INFO("[qos] is_hold[%d]\n", qos_ctrl.is_hold); + } + queue_delayed_work(qos_ctrl.task, &qos_ctrl.work, (500 * HZ) >> 10); + } + up(&qos_ctrl.sem); +#endif + + /* + * Finally, wake up any reader blocked in poll or read + */ + flag = 1; + wake_up_interruptible(&inq); + wake_up(&BT_wq); + ftrace_print("%s wake_up triggered", __func__); +} + +unsigned int BT_poll(struct file *filp, poll_table *wait) +{ + UINT32 mask = 0; + + if ((mtk_wcn_stp_is_rxqueue_empty(BT_TASK_INDX) && rstflag == 0) || + (rstflag == 1) || (rstflag == 3)) { + /* + * BT rx queue is empty, or whole chip reset start, or already sent Hardware Error event + * for whole chip reset end, add to wait queue. + */ + poll_wait(filp, &inq, wait); + /* + * Check if condition changes before poll_wait return, in case of + * wake_up_interruptible is called before add_wait_queue, otherwise, + * do_poll will get into sleep and never be waken up until timeout. + */ + if (!((mtk_wcn_stp_is_rxqueue_empty(BT_TASK_INDX) && rstflag == 0) || + (rstflag == 1) || (rstflag == 3))) + mask |= POLLIN | POLLRDNORM; /* Readable */ + } else { + /* BT rx queue has valid data, or whole chip reset end, have not sent Hardware Error event yet */ + mask |= POLLIN | POLLRDNORM; /* Readable */ + } + + /* Do we need condition here? */ + mask |= POLLOUT | POLLWRNORM; /* Writable */ + ftrace_print("%s: return mask = 0x%04x", __func__, mask); + + return mask; +} + +static ssize_t __bt_write(const PUINT8 buffer, size_t count) +{ + INT32 retval = 0; + + retval = mtk_wcn_stp_send_data(buffer, count, BT_TASK_INDX); + + if (retval < 0) + BT_LOG_PRT_ERR("mtk_wcn_stp_send_data fail, retval %d\n", retval); + else if (retval == 0) { + /* Device cannot process data in time, STP queue is full and no space is available for write, + * native program should not call writev with no delay. + */ + BT_LOG_PRT_INFO_RATELIMITED("write count %zd, sent bytes %d, no space is available!\n", count, retval); + retval = -EAGAIN; + } else + BT_LOG_PRT_DBG("write count %zd, sent bytes %d\n", count, retval); + + return retval; +} + +ssize_t send_hci_frame(const PUINT8 buff, size_t count) +{ + ssize_t retval = 0; + int retry = 0; + + down(&wr_mtx); + + do { + if (retry > 0) { + msleep(30); + BT_LOG_PRT_ERR("Send hci cmd failed, retry %d time(s)\n", retry); + } + retval = __bt_write(buff, count); + retry++; + } while (retval == -EAGAIN && retry < 3); + + up(&wr_mtx); + + return retval; +} + +ssize_t BT_write_iter(struct kiocb *iocb, struct iov_iter *from) +{ + INT32 retval = 0; + size_t count = iov_iter_count(from); + + ftrace_print("%s get called, count %zu", __func__, count); + down(&wr_mtx); + + BT_LOG_PRT_DBG("count %zd\n", count); + + if (rstflag) { + BT_LOG_PRT_ERR("whole chip reset occurs! rstflag=%d\n", rstflag); + retval = -EIO; + goto OUT; + } + + if (count > 0) { + if (count > BT_BUFFER_SIZE) { + BT_LOG_PRT_ERR("write count %zd exceeds max buffer size %d", count, BT_BUFFER_SIZE); + retval = -EINVAL; + goto OUT; + } + + if (copy_from_iter(o_buf, count, from) != count) { + retval = -EFAULT; + goto OUT; + } + + BT_LOG_PRT_DBG_RAW(o_buf, count, "%s: len[%d], TX: ", __func__, count); + retval = __bt_write(o_buf, count); + } + +OUT: + up(&wr_mtx); + return retval; +} + +ssize_t BT_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) +{ + INT32 retval = 0; + + ftrace_print("%s get called, count %zu", __func__, count); + down(&wr_mtx); + + BT_LOG_PRT_DBG("count %zd pos %lld\n", count, *f_pos); + + if (rstflag) { + BT_LOG_PRT_ERR("whole chip reset occurs! rstflag=%d\n", rstflag); + retval = -EIO; + goto OUT; + } + + if (count > 0) { + if (count > BT_BUFFER_SIZE) { + BT_LOG_PRT_ERR("write count %zd exceeds max buffer size %d", count, BT_BUFFER_SIZE); + retval = -EINVAL; + goto OUT; + } + + if (copy_from_user(o_buf, buf, count)) { + retval = -EFAULT; + goto OUT; + } + + BT_LOG_PRT_DBG_RAW(o_buf, count, "%s: len[%d], TX: ", __func__, count); + retval = __bt_write(o_buf, count); + } + +OUT: + up(&wr_mtx); + return retval; +} + +ssize_t BT_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) +{ + INT32 retval = 0; + + ftrace_print("%s get called, count %zu", __func__, count); + down(&rd_mtx); + + BT_LOG_PRT_DBG("count %zd pos %lld\n", count, *f_pos); + + if (rstflag) { + while (rstflag != 2) { + /* + * If nonblocking mode, return directly. + * O_NONBLOCK is specified during open() + */ + if (filp->f_flags & O_NONBLOCK) { + BT_LOG_PRT_ERR("Non-blocking read, whole chip reset occurs! rstflag=%d\n", rstflag); + retval = -EIO; + goto OUT; + } + + wait_event(BT_wq, flag != 0); + flag = 0; + } + /* + * Reset end, send Hardware Error event to stack only once. + * To avoid high frequency read from stack before process is killed, set rstflag to 3 + * to block poll and read after Hardware Error event is sent. + */ + retval = bt_report_hw_error(i_buf, count, &rd_offset); + if (rd_offset == sizeof(HCI_EVT_HW_ERROR)) { + rd_offset = 0; + rstflag = 3; + } + + if (copy_to_user(buf, i_buf, retval)) { + retval = -EFAULT; + if (rstflag == 3) + rstflag = 2; + } + + goto OUT; + } + + if (count > BT_BUFFER_SIZE) { + count = BT_BUFFER_SIZE; + BT_LOG_PRT_WARN("Shorten read count from %zd to %d\n", count, BT_BUFFER_SIZE); + } + + do { + retval = mtk_wcn_stp_receive_data(i_buf, count, BT_TASK_INDX); + if (retval < 0) { + BT_LOG_PRT_ERR("mtk_wcn_stp_receive_data fail, retval %d\n", retval); + goto OUT; + } else if (retval == 0) { /* Got nothing, wait for STP's signal */ + /* + * If nonblocking mode, return directly. + * O_NONBLOCK is specified during open() + */ + if (filp->f_flags & O_NONBLOCK) { + BT_LOG_PRT_ERR("Non-blocking read, no data is available!\n"); + retval = -EAGAIN; + goto OUT; + } + + wait_event(BT_wq, flag != 0); + flag = 0; + } else { /* Got something from STP driver */ + // for bt_dbg user trx function + if (g_bt_dbg_st.trx_enable) { + g_bt_dbg_st.trx_cb(i_buf, retval); + } + //BT_LOG_PRT_DBG("Read bytes %d\n", retval); + BT_LOG_PRT_DBG_RAW(i_buf, retval, "%s: len[%d], RX: ", __func__, retval); + break; + } + } while (!mtk_wcn_stp_is_rxqueue_empty(BT_TASK_INDX) && rstflag == 0); + + if (retval == 0) { + if (rstflag != 2) { /* Should never happen */ + WARN(1, "Blocking read is waken up with no data but rstflag=%d\n", rstflag); + retval = -EIO; + goto OUT; + } else { /* Reset end, send Hardware Error event only once */ + retval = bt_report_hw_error(i_buf, count, &rd_offset); + if (rd_offset == sizeof(HCI_EVT_HW_ERROR)) { + rd_offset = 0; + rstflag = 3; + } + } + } + + if (copy_to_user(buf, i_buf, retval)) { + retval = -EFAULT; + if (rstflag == 3) + rstflag = 2; + } + +OUT: + up(&rd_mtx); + return retval; +} + +/* int BT_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) */ +long BT_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + INT32 retval = 0; + UINT32 reason; + UINT32 ver = 0; + + BT_LOG_PRT_DBG("cmd: 0x%08x\n", cmd); + + switch (cmd) { + case COMBO_IOCTL_FW_ASSERT: + /* Trigger FW assert for debug */ + reason = (UINT32)arg & 0xFFFF; + BT_LOG_PRT_INFO("Host trigger FW assert......, reason:%d\n", reason); + if (reason == 31) /* HCI command timeout */ + BT_LOG_PRT_INFO("HCI command timeout OpCode 0x%04x\n", ((UINT32)arg >> 16) & 0xFFFF); + + if (mtk_wcn_wmt_assert(WMTDRV_TYPE_BT, reason) == MTK_WCN_BOOL_TRUE) { + BT_LOG_PRT_INFO("Host trigger FW assert succeed\n"); + retval = 0; + } else { + BT_LOG_PRT_ERR("Host trigger FW assert failed\n"); + retval = -EBUSY; + } + break; + case COMBO_IOCTL_BT_SET_PSM: + /* BT stack may need to dynamically enable/disable Power Saving Mode + * in some scenarios for performance, e.g. A2DP chopping. + */ + BT_LOG_PRT_INFO("BT stack change PSM setting: %lu\n", arg); + retval = mtk_wcn_wmt_psm_ctrl((MTK_WCN_BOOL)arg); + break; + case COMBO_IOCTL_BT_IC_HW_VER: + ver = mtk_wcn_wmt_ic_info_get(WMTCHIN_HWVER); + BT_LOG_PRT_INFO("HW ver: 0x%x\n", ver); + if (copy_to_user((UINT32 __user *)arg, &ver, sizeof(ver))) + retval = -EFAULT; + break; + case COMBO_IOCTL_BT_IC_FW_VER: + ver = mtk_wcn_wmt_ic_info_get(WMTCHIN_FWVER); + BT_LOG_PRT_INFO("FW ver: 0x%x\n", ver); + if (copy_to_user((UINT32 __user *)arg, &ver, sizeof(ver))) + retval = -EFAULT; + break; + default: + BT_LOG_PRT_ERR("Unknown cmd: 0x%08x\n", cmd); + retval = -EOPNOTSUPP; + break; + } + + return retval; +} + +long BT_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + return BT_unlocked_ioctl(filp, cmd, arg); +} + +#if (PM_QOS_CONTROL == 1) +static void pm_qos_release(struct work_struct *pwork) +{ + pm_qos_update_request(&qos_req, PM_QOS_DEFAULT_VALUE); + qos_ctrl.is_hold = FALSE; + BT_LOG_PRT_INFO("[qos] is_hold[%d]\n", qos_ctrl.is_hold); +} +#endif + +static int BT_open(struct inode *inode, struct file *file) +{ + if(btonflag) { + BT_LOG_PRT_WARN("BT already on!\n"); + return -EIO; + } + BT_LOG_PRT_INFO("major %d minor %d (pid %d)\n", imajor(inode), iminor(inode), current->pid); + + /* Turn on BT */ + if (mtk_wcn_wmt_func_on(WMTDRV_TYPE_BT) == MTK_WCN_BOOL_FALSE) { + BT_LOG_PRT_WARN("WMT turn on BT fail!\n"); + return -EIO; + } + + BT_LOG_PRT_INFO("WMT turn on BT OK!\n"); + + if (mtk_wcn_stp_is_ready() == MTK_WCN_BOOL_FALSE) { + + BT_LOG_PRT_ERR("STP is not ready!\n"); + mtk_wcn_wmt_func_off(WMTDRV_TYPE_BT); + return -EIO; + } + + mtk_wcn_stp_set_bluez(0); + + BT_LOG_PRT_INFO("Now it's in MTK Bluetooth Mode\n"); + BT_LOG_PRT_INFO("STP is ready!\n"); + + BT_LOG_PRT_DBG("Register BT event callback!\n"); + mtk_wcn_stp_register_event_cb(BT_TASK_INDX, BT_event_cb); + + BT_LOG_PRT_DBG("Register BT reset callback!\n"); + mtk_wcn_wmt_msgcb_reg(WMTDRV_TYPE_BT, bt_cdev_rst_cb); + + rstflag = 0; + bt_ftrace_flag = 1; + btonflag = 1; + + sema_init(&wr_mtx, 1); + sema_init(&rd_mtx, 1); + +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH + bt_state_notify(ON); +#endif + bt_dev_dbg_set_state(TRUE); + +#if (PM_QOS_CONTROL == 1) + down(&qos_ctrl.sem); + pm_qos_update_request(&qos_req, PM_QOS_DEFAULT_VALUE); + qos_ctrl.is_hold = FALSE; + qos_ctrl.task = create_singlethread_workqueue("pm_qos_task"); + if (!qos_ctrl.task){ + BT_LOG_PRT_ERR("fail to create pm_qos_task"); + return -EIO; + } + INIT_DELAYED_WORK(&qos_ctrl.work, pm_qos_release); + up(&qos_ctrl.sem); +#endif + bt_pm_notify_register(); + + return 0; +} + +static int BT_close(struct inode *inode, struct file *file) +{ + BT_LOG_PRT_INFO("major %d minor %d (pid %d)\n", imajor(inode), iminor(inode), current->pid); + + bt_pm_notify_unregister(); + bt_dev_dbg_set_state(FALSE); +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH + bt_state_notify(OFF); +#endif + + rstflag = 0; + bt_ftrace_flag = 0; + btonflag = 0; + + mtk_wcn_wmt_msgcb_unreg(WMTDRV_TYPE_BT); + mtk_wcn_stp_register_event_cb(BT_TASK_INDX, NULL); + +#if (PM_QOS_CONTROL == 1) + down(&qos_ctrl.sem); + if(qos_ctrl.task != NULL) { + BT_LOG_PRT_INFO("[qos] cancel delayed work\n"); + cancel_delayed_work(&qos_ctrl.work); + flush_workqueue(qos_ctrl.task); + destroy_workqueue(qos_ctrl.task); + qos_ctrl.task = NULL; + } + pm_qos_update_request(&qos_req, PM_QOS_DEFAULT_VALUE); + qos_ctrl.is_hold = FALSE; + up(&qos_ctrl.sem); +#endif + + if (mtk_wcn_wmt_func_off(WMTDRV_TYPE_BT) == MTK_WCN_BOOL_FALSE) { + BT_LOG_PRT_ERR("WMT turn off BT fail!\n"); + return -EIO; /* Mostly, native program will not check this return value. */ + } + + BT_LOG_PRT_INFO("WMT turn off BT OK!\n"); + return 0; +} + +const struct file_operations BT_fops = { + .open = BT_open, + .release = BT_close, + .read = BT_read, + .write = BT_write, + .write_iter = BT_write_iter, + /* .ioctl = BT_ioctl, */ + .unlocked_ioctl = BT_unlocked_ioctl, + .compat_ioctl = BT_compat_ioctl, + .poll = BT_poll +}; + +static int BT_init(void) +{ + dev_t dev; + INT32 alloc_ret = 0; + INT32 cdv_err = 0; + dev = MKDEV(BT_major, 0); + + /* Initialize wait queue */ + init_waitqueue_head(&(inq)); + /* Initialize wake lock */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 149) + BT_LOG_PRT_INFO("wakeup_source_register() with kernel-4.14.149\n"); + bt_wakelock = wakeup_source_register(NULL, "bt_drv"); +#else + bt_wakelock = wakeup_source_register("bt_drv"); +#endif + if(!bt_wakelock) { + BT_LOG_PRT_ERR("%s: init bt_wakelock failed!\n", __func__); + } + + /* Allocate char device */ + alloc_ret = register_chrdev_region(dev, BT_devs, BT_DRIVER_NAME); + if (alloc_ret) { + BT_LOG_PRT_ERR("Failed to register device numbers\n"); + return alloc_ret; + } + + cdev_init(&BT_cdev, &BT_fops); + BT_cdev.owner = THIS_MODULE; + + cdv_err = cdev_add(&BT_cdev, dev, BT_devs); + if (cdv_err) + goto error; + +#if CREATE_NODE_DYNAMIC /* mknod replace */ + stpbt_class = class_create(THIS_MODULE, "stpbt"); + if (IS_ERR(stpbt_class)) + goto error; + stpbt_dev = device_create(stpbt_class, NULL, dev, NULL, "stpbt"); + if (IS_ERR(stpbt_dev)) + goto error; +#endif + + BT_LOG_PRT_INFO("%s driver(major %d) installed\n", BT_DRIVER_NAME, BT_major); + +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH + fw_log_bt_init(); +#endif + bt_dev_dbg_init(); + +#if (PM_QOS_CONTROL == 1) + pm_qos_add_request(&qos_req, PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE); + sema_init(&qos_ctrl.sem, 1); +#endif + + return 0; + +error: +#if CREATE_NODE_DYNAMIC + if (stpbt_dev && !IS_ERR(stpbt_dev)) { + device_destroy(stpbt_class, dev); + stpbt_dev = NULL; + } + if (stpbt_class && !IS_ERR(stpbt_class)) { + class_destroy(stpbt_class); + stpbt_class = NULL; + } +#endif + if (cdv_err == 0) + cdev_del(&BT_cdev); + + if (alloc_ret == 0) + unregister_chrdev_region(dev, BT_devs); + + return -1; +} + +static void BT_exit(void) +{ + dev_t dev; + +#if (PM_QOS_CONTROL == 1) + pm_qos_remove_request(&qos_req); +#endif + + bt_dev_dbg_deinit(); +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH + fw_log_bt_exit(); +#endif + + dev = MKDEV(BT_major, 0); + /* Destroy wake lock*/ + wakeup_source_unregister(bt_wakelock); + +#if CREATE_NODE_DYNAMIC + if (stpbt_dev && !IS_ERR(stpbt_dev)) { + device_destroy(stpbt_class, dev); + stpbt_dev = NULL; + } + if (stpbt_class && !IS_ERR(stpbt_class)) { + class_destroy(stpbt_class); + stpbt_class = NULL; + } +#endif + + cdev_del(&BT_cdev); + unregister_chrdev_region(dev, BT_devs); + + BT_LOG_PRT_INFO("%s driver removed\n", BT_DRIVER_NAME); +} + +#ifdef MTK_WCN_REMOVE_KERNEL_MODULE + +int mtk_wcn_stpbt_drv_init(void) +{ + return BT_init(); +} +EXPORT_SYMBOL(mtk_wcn_stpbt_drv_init); + +void mtk_wcn_stpbt_drv_exit(void) +{ + return BT_exit(); +} +EXPORT_SYMBOL(mtk_wcn_stpbt_drv_exit); + +#else + +module_init(BT_init); +module_exit(BT_exit); + +#endif diff --git a/drivers/misc/mediatek/connectivity/common/Makefile b/drivers/misc/mediatek/connectivity/common/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..f390aff160e6d781f5a162e8484651eecdbb94fa --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/Makefile @@ -0,0 +1,290 @@ +ifeq ($(MTK_PLATFORM),) +ifneq ($(MTK_PLATFORM_WMT),) +MTK_PLATFORM := $(shell echo $(MTK_PLATFORM_WMT) | tr A-Z a-z) +endif +endif + +ifeq ($(MTK_PLATFORM),) +ifneq ($(CONFIG_MTK_PLATFORM),) +MTK_PLATFORM := $(subst ",,$(CONFIG_MTK_PLATFORM)) +endif +endif + +CONNSYS_PLATFORM := $(TARGET_BOARD_PLATFORM_WMT) +PRIORITY_TABLE_MTK_PLATFORM := mt6735 + +ifeq ($(CONNSYS_PLATFORM),) +CONNSYS_PLATFORM := $(MTK_PLATFORM) +else +ifneq ($(filter $(PRIORITY_TABLE_MTK_PLATFORM), $(MTK_PLATFORM)),) +CONNSYS_PLATFORM := $(MTK_PLATFORM) +endif +endif + +ifneq ($(CONFIG_MTK_COMBO),) + +ifeq ($(CONFIG_MTK_COMBO_CHIP),) + $(error CONFIG_MTK_COMBO_CHIP not defined) +endif + +# Force build fail on modpost warning +KBUILD_MODPOST_FAIL_ON_WARNINGS := y +############################################################################### + +#ccflags-y += -D MTK_WCN_REMOVE_KERNEL_MODULE +ifeq ($(CONFIG_ARM64), y) + ccflags-y += -D CONFIG_MTK_WCN_ARM64 +endif + +ifeq ($(CONFIG_MTK_CONN_LTE_IDC_SUPPORT),y) + ccflags-y += -D WMT_IDC_SUPPORT=1 +else + ccflags-y += -D WMT_IDC_SUPPORT=0 +endif +ccflags-y += -D MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT + +ccflags-y += -I$(srctree)/drivers/misc/mediatek/include +ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include +ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include/mach +ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat +ccflags-y += -I$(srctree)/drivers/misc/mediatek/base/power/$(MTK_PLATFORM) +ccflags-y += -I$(srctree)/drivers/misc/mediatek/base/power/include +ccflags-y += -I$(srctree)/drivers/misc/mediatek/base/power/include/clkbuf_v1 +ccflags-y += -I$(srctree)/drivers/misc/mediatek/base/power/include/clkbuf_v1/$(MTK_PLATFORM) +ccflags-y += -I$(srctree)/drivers/misc/mediatek/btif/common/inc +ifeq ($(strip $(MTK_PLATFORM)), mt6735) +ccflags-y += -I$(srctree)/drivers/misc/mediatek/eccci1 +ccflags-y += -I$(srctree)/drivers/misc/mediatek/eccci1/$(MTK_PLATFORM) +else +ccflags-y += -I$(srctree)/drivers/misc/mediatek/eccci +ccflags-y += -I$(srctree)/drivers/misc/mediatek/eccci/$(MTK_PLATFORM) +endif +ccflags-y += -I$(srctree)/drivers/misc/mediatek/eemcs +ccflags-y += -I$(srctree)/drivers/misc/mediatek/conn_md/include +ccflags-y += -I$(srctree)/drivers/misc/mediatek/mach/$(MTK_PLATFORM)/include/mach +ccflags-y += -I$(srctree)/drivers/misc/mediatek/emi/submodule +ccflags-y += -I$(srctree)/drivers/misc/mediatek/emi/$(MTK_PLATFORM) +ifeq ($(CONFIG_MTK_PMIC_CHIP_MT6359),y) +ccflags-y += -I$(srctree)/drivers/misc/mediatek/pmic/include/mt6359 +endif +ifeq ($(CONFIG_MTK_PMIC_CHIP_MT6359P),y) +ccflags-y += -I$(srctree)/drivers/misc/mediatek/pmic/include/mt6359p +endif +ccflags-y += -I$(srctree)/drivers/mmc/core +ccflags-y += -I$(srctree)/drivers/misc/mediatek/connectivity/common +ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat +############################################################################### + + +ccflags-y += -Werror + +ifneq ($(filter "MT6628",$(CONFIG_MTK_COMBO_CHIP)),) + ccflags-y += -D MT6628 + ccflags-y += -D MERGE_INTERFACE_SUPPORT +endif +ifneq ($(filter "MT6630",$(CONFIG_MTK_COMBO_CHIP)),) + ccflags-y += -D MT6630 +ifneq ($(CONFIG_ARCH_MT2601),y) + ccflags-y += -D MERGE_INTERFACE_SUPPORT +endif +endif + +ifneq ($(filter "MT6632",$(CONFIG_MTK_COMBO_CHIP)),) + ccflags-y += -D MT6632 + ccflags-y += -D MERGE_INTERFACE_SUPPORT +endif + +#obj-y += common_main/ +#obj-y += common_detect/ + +ifneq ($(filter MT6631,$(MTK_CONSYS_ADIE)),) + ccflags-y += -D CONSYS_PMIC_CTRL_6635=0 +else + ccflags-y += -D CONSYS_PMIC_CTRL_6635=1 +endif + +############################################################################### +MODULE_NAME := wmt_drv +ifeq ($(CONFIG_WLAN_DRV_BUILD_IN),y) +$(warning $(MODULE_NAME) build-in boot.img) +obj-y += $(MODULE_NAME).o +else +$(warning $(MODULE_NAME) is kernel module) +obj-m += $(MODULE_NAME).o +endif + +############################################################################### +# common_detect +############################################################################### +ccflags-y += -I$(srctree)/arch/arm/mach-$(MTK_PLATFORM)/$(ARCH_MTK_PROJECT)/dct/dct +ccflags-y += -DWMT_PLAT_ALPS=1 + +COMBO_CHIP_SUPPORT := false +ifneq ($(filter "MT6620E3",$(CONFIG_MTK_COMBO_CHIP)),) + COMBO_CHIP_SUPPORT := true +endif +ifneq ($(filter "MT6628",$(CONFIG_MTK_COMBO_CHIP)),) + COMBO_CHIP_SUPPORT := true +endif +ifneq ($(filter "MT6630",$(CONFIG_MTK_COMBO_CHIP)),) + COMBO_CHIP_SUPPORT := true +endif +ifneq ($(filter "MT6632",$(CONFIG_MTK_COMBO_CHIP)),) + COMBO_CHIP_SUPPORT := true +endif +ifeq ($(COMBO_CHIP_SUPPORT), true) + ccflags-y += -D MTK_WCN_COMBO_CHIP_SUPPORT +endif + +ifneq ($(filter "CONSYS_%",$(CONFIG_MTK_COMBO_CHIP)),) + ccflags-y += -D MTK_WCN_SOC_CHIP_SUPPORT +endif + +ccflags-y += -I$(src)/common_main/linux/include +ccflags-y += -I$(src)/common_detect/drv_init/inc +ccflags-y += -I$(src)/common_detect +ccflags-y += -I$(src)/debug_utility + +$(MODULE_NAME)-objs += common_detect/wmt_detect_pwr.o +$(MODULE_NAME)-objs += common_detect/wmt_detect.o +$(MODULE_NAME)-objs += common_detect/sdio_detect.o +$(MODULE_NAME)-objs += common_detect/mtk_wcn_stub_alps.o +$(MODULE_NAME)-objs += common_detect/wmt_gpio.o + + +ifneq ($(filter "MT6630",$(CONFIG_MTK_COMBO_CHIP)),) + ccflags-y += -D MTK_WCN_WLAN_GEN3 +endif + +ifneq ($(filter "MT6632",$(CONFIG_MTK_COMBO_CHIP)),) + ccflags-y += -D MTK_WCN_WLAN_GEN4 +endif + +ifneq ($(filter "CONSYS_6797" "CONSYS_6759" "CONSYS_6758" "CONSYS_6771" "CONSYS_6775",$(CONFIG_MTK_COMBO_CHIP)),) + ccflags-y += -D MTK_WCN_WLAN_GEN3 +else ifneq ($(filter "CONSYS_%",$(CONFIG_MTK_COMBO_CHIP)),) + ccflags-y += -D MTK_WCN_WLAN_GEN2 +endif + +$(MODULE_NAME)-objs += common_detect/drv_init/fm_drv_init.o +$(MODULE_NAME)-objs += common_detect/drv_init/conn_drv_init.o +$(MODULE_NAME)-objs += common_detect/drv_init/bluetooth_drv_init.o +$(MODULE_NAME)-objs += common_detect/drv_init/wlan_drv_init.o +$(MODULE_NAME)-objs += common_detect/drv_init/common_drv_init.o +$(MODULE_NAME)-objs += common_detect/drv_init/gps_drv_init.o + + +############################################################################### +# common_main +############################################################################### +ccflags-y += -I$(src)/common_main/linux/include +ccflags-y += -I$(src)/common_main/linux/pri/include +ccflags-y += -I$(src)/common_main/platform/include +ccflags-y += -I$(src)/common_main/core/include +ccflags-y += -I$(src)/common_main/include + +ccflags-y += -D WMT_PLAT_ALPS=1 +ccflags-y += -D WMT_UART_RX_MODE_WORK=0 # 1. work thread 0. tasklet +ccflags-y += -D WMT_SDIO_MODE=1 +ccflags-y += -D WMT_CREATE_NODE_DYNAMIC=1 + +ifneq ($(TARGET_BUILD_VARIANT),eng) +ifeq ($(CONFIG_EXTREME_LOW_RAM), y) +ccflags-y += -DLOG_STP_DEBUG_DISABLE +endif +endif + +ifneq ($(TARGET_BUILD_VARIANT), user) + ccflags-y += -D WMT_DBG_SUPPORT=1 +else + ccflags-y += -D WMT_DBG_SUPPORT=0 +endif + +ifeq ($(CONFIG_MTK_DEVAPC),y) + ccflags-y += -D WMT_DEVAPC_DBG_SUPPORT=1 +else + ccflags-y += -D WMT_DEVAPC_DBG_SUPPORT=0 +endif + +ifeq ($(CONFIG_ARCH_MT6580), y) +ccflags-y += -D CFG_WMT_READ_EFUSE_VCN33 +endif + +# STEP: (Support Connac) +# MTK eng/userdebug/user load: Support +# Customer eng/userdebug load: Support +# Customer user load: Not support + +ifneq ($(TARGET_BUILD_VARIANT),user) + ccflags-y += -D CFG_WMT_STEP +endif + +ifeq ($(findstring evb, $(MTK_PROJECT)), evb) +ccflags-y += -D CFG_WMT_EVB +endif + +ifneq ($(filter "CONSYS_%",$(CONFIG_MTK_COMBO_CHIP)),) +$(MODULE_NAME)-objs += common_main/platform/$(CONNSYS_PLATFORM).o +endif + +#$(MODULE_NAME)-objs += common_main/platform/wmt_plat_stub.o +$(MODULE_NAME)-objs += common_main/platform/wmt_plat_alps.o +$(MODULE_NAME)-objs += common_main/platform/mtk_wcn_consys_hw.o +$(MODULE_NAME)-objs += common_main/platform/mtk_wcn_cmb_hw.o + +$(MODULE_NAME)-objs += common_main/core/wmt_ic_6628.o +$(MODULE_NAME)-objs += common_main/core/wmt_conf.o +$(MODULE_NAME)-objs += common_main/core/stp_core.o +$(MODULE_NAME)-objs += common_main/core/wmt_ctrl.o +$(MODULE_NAME)-objs += common_main/core/wmt_func.o +$(MODULE_NAME)-objs += common_main/core/wmt_core.o +$(MODULE_NAME)-objs += common_main/core/psm_core.o +$(MODULE_NAME)-objs += common_main/core/wmt_ic_soc.o +$(MODULE_NAME)-objs += common_main/core/wmt_lib.o +$(MODULE_NAME)-objs += common_main/core/wmt_ic_6620.o +$(MODULE_NAME)-objs += common_main/core/stp_exp.o +$(MODULE_NAME)-objs += common_main/core/wmt_ic_6632.o +$(MODULE_NAME)-objs += common_main/core/wmt_exp.o +$(MODULE_NAME)-objs += common_main/core/btm_core.o +$(MODULE_NAME)-objs += common_main/core/wmt_ic_6630.o + +$(MODULE_NAME)-objs += common_main/linux/hif_sdio.o +$(MODULE_NAME)-objs += common_main/linux/stp_dbg_soc.o +$(MODULE_NAME)-objs += common_main/linux/stp_dbg_combo.o +$(MODULE_NAME)-objs += common_main/linux/osal.o +$(MODULE_NAME)-objs += common_main/linux/wmt_dev.o +$(MODULE_NAME)-objs += common_main/linux/stp_sdio.o +$(MODULE_NAME)-objs += common_main/linux/bgw_desense.o +$(MODULE_NAME)-objs += common_main/linux/wmt_idc.o +$(MODULE_NAME)-objs += common_main/linux/stp_uart.o +$(MODULE_NAME)-objs += common_main/linux/wmt_dbg.o +$(MODULE_NAME)-objs += common_main/linux/stp_dbg.o +$(MODULE_NAME)-objs += common_main/linux/wmt_user_proc.o + +$(MODULE_NAME)-objs += common_main/linux/wmt_proc_dbg.o +$(MODULE_NAME)-objs += common_main/linux/wmt_alarm.o + +ifneq ($(CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH),) +$(MODULE_NAME)-objs += common_main/linux/fw_log_wmt.o +endif +$(MODULE_NAME)-objs += common_main/linux/wmt_step.o + +ifeq ($(CONFIG_MTK_BTIF),$(filter $(CONFIG_MTK_BTIF),y m)) +$(MODULE_NAME)-objs += common_main/linux/stp_btif.o +endif + +$(MODULE_NAME)-objs += debug_utility/ring.o +$(MODULE_NAME)-objs += debug_utility/ring_emi.o +$(MODULE_NAME)-objs += debug_utility/connsys_debug_utility.o +############################################################################### +# test +############################################################################### +ifeq ($(TARGET_BUILD_VARIANT),eng) +ccflags-y += -I$(src)/test/include +endif + +ifeq ($(TARGET_BUILD_VARIANT),eng) +$(MODULE_NAME)-objs += test/wmt_step_test.o +endif + +endif diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/bluetooth_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/bluetooth_drv_init.c new file mode 100644 index 0000000000000000000000000000000000000000..d89d5da4357b61fdb983aab7219504fb00e0fdde --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/bluetooth_drv_init.c @@ -0,0 +1,43 @@ +/* +* Copyright (C) 2011-2014 MediaTek Inc. +* +* This program is free software: you can redistribute it and/or modify it under the terms of the +* GNU General Public License version 2 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. +* +* You should have received a copy of the GNU General Public License along with this program. +* If not, see . +*/ + +#ifdef DFT_TAG +#undef DFT_TAG +#endif +#define DFT_TAG "[BT-MOD-INIT]" + +#include "wmt_detect.h" +#include "bluetooth_drv_init.h" + +#ifdef CONFIG_MTK_COMBO_BT +int __attribute__((weak)) mtk_wcn_stpbt_drv_init() +{ + WMT_DETECT_PR_INFO("Not implement mtk_wcn_stpbt_drv_init\n"); + return 0; +} +#endif + +int do_bluetooth_drv_init(int chip_id) +{ + int i_ret = -1; + +#ifdef CONFIG_MTK_COMBO_BT + WMT_DETECT_PR_INFO("start to do bluetooth driver init\n"); + i_ret = mtk_wcn_stpbt_drv_init(); + WMT_DETECT_PR_INFO("finish bluetooth driver init, i_ret:%d\n", i_ret); +#else + WMT_DETECT_PR_INFO("CONFIG_MTK_COMBO_BT is not defined\n"); +#endif + return i_ret; +} diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/common_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/common_drv_init.c new file mode 100644 index 0000000000000000000000000000000000000000..e6c64529eaff714bf2d23cd03ef70c8b71a87d58 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/common_drv_init.c @@ -0,0 +1,59 @@ +/* +* Copyright (C) 2011-2014 MediaTek Inc. +* +* This program is free software: you can redistribute it and/or modify it under the terms of the +* GNU General Public License version 2 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. +* +* You should have received a copy of the GNU General Public License along with this program. +* If not, see . +*/ + +#ifdef DFT_TAG +#undef DFT_TAG +#endif +#define DFT_TAG "[WMT-MOD-INIT]" + +#include "wmt_detect.h" +#include "common_drv_init.h" + + +#if (MTK_WCN_REMOVE_KO) +int do_common_drv_init(int chip_id) +{ + int i_ret = 0; + int i_ret_tmp = 0; + + WMT_DETECT_PR_INFO("start to do common driver init, chipid:0x%08x\n", chip_id); + + wmt_detect_set_chip_type(chip_id); + + /* HIF-SDIO driver init */ + i_ret_tmp = mtk_wcn_hif_sdio_drv_init(); + i_ret += i_ret_tmp; + WMT_DETECT_PR_DBG("HIF-SDIO driver init, i_ret:%d\n", i_ret); + + /* WMT driver init */ + i_ret_tmp = mtk_wcn_common_drv_init(); + i_ret += i_ret_tmp; + WMT_DETECT_PR_DBG("COMBO COMMON driver init, i_ret:%d\n", i_ret); + + /* STP-UART driver init */ + i_ret_tmp = mtk_wcn_stp_uart_drv_init(); + i_ret += i_ret_tmp; + WMT_DETECT_PR_DBG("STP-UART driver init, i_ret:%d\n", i_ret); + + /* STP-SDIO driver init */ + i_ret_tmp = mtk_wcn_stp_sdio_drv_init(); + i_ret += i_ret_tmp; + WMT_DETECT_PR_DBG("STP-SDIO driver init, i_ret:%d\n", i_ret); + + WMT_DETECT_PR_INFO("common driver init finish:%d\n", i_ret); + return i_ret; + +} +#endif + diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/conn_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/conn_drv_init.c new file mode 100644 index 0000000000000000000000000000000000000000..ab03a5b14fe788b7fc9c5c0e58ce1bfe64f89b43 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/conn_drv_init.c @@ -0,0 +1,70 @@ +/* +* Copyright (C) 2011-2014 MediaTek Inc. +* +* This program is free software: you can redistribute it and/or modify it under the terms of the +* GNU General Public License version 2 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. +* +* You should have received a copy of the GNU General Public License along with this program. +* If not, see . +*/ + +#ifdef DFT_TAG +#undef DFT_TAG +#endif +#define DFT_TAG "[WCN-MOD-INIT]" + +#include "wmt_detect.h" +#include "conn_drv_init.h" +#include "common_drv_init.h" +#include "fm_drv_init.h" +#include "wlan_drv_init.h" +#include "bluetooth_drv_init.h" +#include "gps_drv_init.h" + +#if (MTK_WCN_REMOVE_KO) +int do_connectivity_driver_init(int chip_id) +{ + int i_ret = 0; + int tmp_ret = 0; + static int init_before; + + /* To avoid invoking more than once.*/ + if (init_before) + return 0; + init_before = 1; + + tmp_ret = do_common_drv_init(chip_id); + i_ret += tmp_ret; + if (tmp_ret) { + WMT_DETECT_PR_ERR("do common driver not ready, ret:%d\n abort!\n", tmp_ret); + return i_ret; + } + + tmp_ret = do_bluetooth_drv_init(chip_id); + i_ret += tmp_ret; + if (tmp_ret) + WMT_DETECT_PR_ERR("do common driver init failed, ret:%d\n", tmp_ret); + + tmp_ret = do_gps_drv_init(chip_id); + i_ret += tmp_ret; + if (tmp_ret) + WMT_DETECT_PR_ERR("do common driver init failed, ret:%d\n", tmp_ret); + + tmp_ret = do_fm_drv_init(chip_id); + i_ret += tmp_ret; + if (tmp_ret) + WMT_DETECT_PR_ERR("do fm module init failed, ret:%d\n", tmp_ret); + + tmp_ret = do_wlan_drv_init(chip_id); + i_ret += tmp_ret; + if (tmp_ret) + WMT_DETECT_PR_ERR("do wlan module init failed, ret:%d\n", tmp_ret); + + return i_ret; +} +#endif + diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/fm_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/fm_drv_init.c new file mode 100644 index 0000000000000000000000000000000000000000..4ec149e77046a6a1f1e78a752442e9029fc01f80 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/fm_drv_init.c @@ -0,0 +1,41 @@ +/* +* Copyright (C) 2011-2014 MediaTek Inc. +* +* This program is free software: you can redistribute it and/or modify it under the terms of the +* GNU General Public License version 2 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. +* +* You should have received a copy of the GNU General Public License along with this program. +* If not, see . +*/ + +#ifdef DFT_TAG +#undef DFT_TAG +#endif +#define DFT_TAG "[FM-MOD-INIT]" + +#include "wmt_detect.h" +#include "fm_drv_init.h" + +#ifdef CONFIG_MTK_FMRADIO +int __attribute__((weak)) mtk_wcn_fm_init() +{ + WMT_DETECT_PR_INFO("no impl. mtk_wcn_fm_init\n"); + return 0; +} +#endif + +int do_fm_drv_init(int chip_id) +{ + WMT_DETECT_PR_INFO("start to do fm module init\n"); + +#ifdef CONFIG_MTK_FMRADIO + mtk_wcn_fm_init(); +#endif + + WMT_DETECT_PR_INFO("finish fm module init\n"); + return 0; +} diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/gps_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/gps_drv_init.c new file mode 100644 index 0000000000000000000000000000000000000000..ac48b231a3d0e8a8cbfa22ed63d62e8c0821abed --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/gps_drv_init.c @@ -0,0 +1,43 @@ +/* +* Copyright (C) 2011-2014 MediaTek Inc. +* +* This program is free software: you can redistribute it and/or modify it under the terms of the +* GNU General Public License version 2 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. +* +* You should have received a copy of the GNU General Public License along with this program. +* If not, see . +*/ + +#ifdef DFT_TAG +#undef DFT_TAG +#endif +#define DFT_TAG "[GPS-MOD-INIT]" + +#include "wmt_detect.h" +#include "gps_drv_init.h" + +#ifdef CONFIG_MTK_COMBO_GPS +int __attribute__((weak)) mtk_wcn_stpgps_drv_init() +{ + WMT_DETECT_PR_INFO("no impl. mtk_wcn_stpgps_drv_init\n"); + return 0; +} +#endif + +int do_gps_drv_init(int chip_id) +{ + int i_ret = -1; +#ifdef CONFIG_MTK_COMBO_GPS + WMT_DETECT_PR_INFO("start to do gps driver init\n"); + i_ret = mtk_wcn_stpgps_drv_init(); + WMT_DETECT_PR_INFO("finish gps driver init, i_ret:%d\n", i_ret); +#else + WMT_DETECT_PR_INFO("CONFIG_MTK_COMBO_GPS is not defined\n"); +#endif + return i_ret; + +} diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/bluetooth_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/bluetooth_drv_init.h new file mode 100644 index 0000000000000000000000000000000000000000..8a847d361fc8c66158a07b328133906e87480ee6 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/bluetooth_drv_init.h @@ -0,0 +1,20 @@ +/* +* Copyright (C) 2011-2014 MediaTek Inc. +* +* This program is free software: you can redistribute it and/or modify it under the terms of the +* GNU General Public License version 2 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. +* +* You should have received a copy of the GNU General Public License along with this program. +* If not, see . +*/ + +#ifndef _BLUETOOTH_DRIVER_INIT_H_ +#define _BLUETOOTH_DRIVER_INIT_H_ + +extern int do_bluetooth_drv_init(int chip_id); +extern int mtk_wcn_stpbt_drv_init(void); +#endif diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/common_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/common_drv_init.h new file mode 100644 index 0000000000000000000000000000000000000000..dae155e1d4039c8b699b2704bba6a4b158083abb --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/common_drv_init.h @@ -0,0 +1,25 @@ +/* +* Copyright (C) 2011-2014 MediaTek Inc. +* +* This program is free software: you can redistribute it and/or modify it under the terms of the +* GNU General Public License version 2 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. +* +* You should have received a copy of the GNU General Public License along with this program. +* If not, see . +*/ + +#ifndef _COMMON_DRV_INIT_H_ +#define _COMMON_DRV_INIT_H_ +extern int do_common_drv_init(int chip_id); + +extern int mtk_wcn_common_drv_init(void); +extern int mtk_wcn_hif_sdio_drv_init(void); +extern int mtk_wcn_stp_uart_drv_init(void); +extern int mtk_wcn_stp_sdio_drv_init(void); + + +#endif diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/conn_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/conn_drv_init.h new file mode 100644 index 0000000000000000000000000000000000000000..971193eade9e9b5226f49cf0145809f0556f06e2 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/conn_drv_init.h @@ -0,0 +1,18 @@ +/* +* Copyright (C) 2011-2014 MediaTek Inc. +* +* This program is free software: you can redistribute it and/or modify it under the terms of the +* GNU General Public License version 2 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. +* +* You should have received a copy of the GNU General Public License along with this program. +* If not, see . +*/ + +#ifndef _CONNECTIVITY_DRV_INIT_H_ +#define _CONNECTIVITY_DRV_INIT_H_ +extern int do_connectivity_driver_init(int chip_id); +#endif diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/fm_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/fm_drv_init.h new file mode 100644 index 0000000000000000000000000000000000000000..f6ea30addc5da1f231e2bb0e0213e209b7ea80fc --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/fm_drv_init.h @@ -0,0 +1,20 @@ +/* +* Copyright (C) 2011-2014 MediaTek Inc. +* +* This program is free software: you can redistribute it and/or modify it under the terms of the +* GNU General Public License version 2 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. +* +* You should have received a copy of the GNU General Public License along with this program. +* If not, see . +*/ + +#ifndef _FM_DRV_INIT_H_ +#define _FM_DRV_INIT_H_ +extern int do_fm_drv_init(int chip_id); +extern int mtk_wcn_fm_init(void); +extern void mtk_wcn_fm_exit(void); +#endif diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/gps_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/gps_drv_init.h new file mode 100644 index 0000000000000000000000000000000000000000..006ce072c53b6680b79e3f73c8689c06950aa352 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/gps_drv_init.h @@ -0,0 +1,19 @@ +/* +* Copyright (C) 2011-2014 MediaTek Inc. +* +* This program is free software: you can redistribute it and/or modify it under the terms of the +* GNU General Public License version 2 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. +* +* You should have received a copy of the GNU General Public License along with this program. +* If not, see . +*/ + +#ifndef _GPS_DRIVER_INIT_H_ +#define _GPS_DRIVER_INIT_H_ +extern int do_gps_drv_init(int chip_id); +extern int mtk_wcn_stpgps_drv_init(void); +#endif diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/wlan_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/wlan_drv_init.h new file mode 100644 index 0000000000000000000000000000000000000000..6ed7d4e458d1e824240300b0aef5a6f6faac3943 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/wlan_drv_init.h @@ -0,0 +1,29 @@ +/* +* Copyright (C) 2011-2014 MediaTek Inc. +* +* This program is free software: you can redistribute it and/or modify it under the terms of the +* GNU General Public License version 2 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. +* +* You should have received a copy of the GNU General Public License along with this program. +* If not, see . +*/ + +#ifndef _WLAN_DRV_INIT_H_ +#define _WLAN_DRV_INIT_H_ + + +extern int do_wlan_drv_init(int chip_id); + +extern int mtk_wcn_wmt_wifi_init(void); + +extern int mtk_wcn_wlan_gen2_init(void); + +extern int mtk_wcn_wlan_gen3_init(void); + +extern int mtk_wcn_wlan_gen4_init(void); + +#endif diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/wlan_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/wlan_drv_init.c new file mode 100644 index 0000000000000000000000000000000000000000..7b28ad934f83f4ea0f5654254a27e462a2855a2a --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/wlan_drv_init.c @@ -0,0 +1,89 @@ +/* +* Copyright (C) 2011-2014 MediaTek Inc. +* +* This program is free software: you can redistribute it and/or modify it under the terms of the +* GNU General Public License version 2 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. +* +* You should have received a copy of the GNU General Public License along with this program. +* If not, see . +*/ + +#ifdef DFT_TAG +#undef DFT_TAG +#endif +#define DFT_TAG "[WLAN-MOD-INIT]" + +#include "wmt_detect.h" +#include "wlan_drv_init.h" + +int __attribute__((weak)) mtk_wcn_wlan_gen4_init() +{ + WMT_DETECT_PR_INFO("no impl. mtk_wcn_wlan_gen4_init\n"); + return 0; +} + +int __attribute__((weak)) mtk_wcn_wlan_gen3_init() +{ + WMT_DETECT_PR_INFO("no impl. mtk_wcn_wlan_gen3_init\n"); + return 0; +} + +int __attribute__((weak)) mtk_wcn_wlan_gen2_init() +{ + WMT_DETECT_PR_INFO("no impl. mtk_wcn_wlan_gen2_init\n"); + return 0; +} + +int __attribute__((weak)) mtk_wcn_wmt_wifi_init() +{ + WMT_DETECT_PR_INFO("no impl. mtk_wcn_wmt_wifi_init\n"); + return 0; +} + +int do_wlan_drv_init(int chip_id) +{ + int i_ret = 0; + int ret = 0; + + WMT_DETECT_PR_INFO("start to do wlan module init 0x%x\n", chip_id); + + /* WMT-WIFI char dev init */ + ret = mtk_wcn_wmt_wifi_init(); + WMT_DETECT_PR_INFO("WMT-WIFI char dev init, ret:%d\n", ret); + i_ret += ret; + + switch (chip_id) { + case 0x6580: + case 0x6739: + ret = mtk_wcn_wlan_gen2_init(); + WMT_DETECT_PR_INFO("WLAN-GEN2 driver init, ret:%d\n", ret); + break; + + case 0x6630: + case 0x6797: + case 0x6758: + case 0x6759: + case 0x6775: + case 0x6771: + /* WLAN driver init */ + ret = mtk_wcn_wlan_gen3_init(); + WMT_DETECT_PR_INFO("WLAN-GEN3 driver init, ret:%d\n", ret); + break; + + default: + /* WLAN driver init */ + ret = mtk_wcn_wlan_gen4_init(); + WMT_DETECT_PR_INFO("WLAN-GEN4 driver init, ret:%d\n", ret); + break; + } + + i_ret += ret; + + WMT_DETECT_PR_INFO("finish wlan module init\n"); + + return i_ret; +} diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/mtk_wcn_stub_alps.c b/drivers/misc/mediatek/connectivity/common/common_detect/mtk_wcn_stub_alps.c new file mode 100644 index 0000000000000000000000000000000000000000..cf281b416d85875c155256d170a985a3815d482d --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_detect/mtk_wcn_stub_alps.c @@ -0,0 +1,621 @@ +/* +* Copyright (C) 2011-2014 MediaTek Inc. +* +* This program is free software: you can redistribute it and/or modify it under the terms of the +* GNU General Public License version 2 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. +* +* You should have received a copy of the GNU General Public License along with this program. +* If not, see . +*/ + +/* + * ! \file + * \brief Declaration of library functions + * Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. + */ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + + +/* kernel wmt_build_in_adapter.c already has these, so always ignored */ +#ifdef MTK_WCN_REMOVE_KERNEL_MODULE +#undef MTK_WCN_REMOVE_KERNEL_MODULE +#endif + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +#define CMB_STUB_DBG_LOG 3 +#define CMB_STUB_INFO_LOG 2 +#define CMB_STUB_WARN_LOG 1 + +int gCmbStubLogLevel = CMB_STUB_INFO_LOG; + +#define CMB_STUB_LOG_PR_INFO(fmt, arg...) \ +do { \ + if (gCmbStubLogLevel >= CMB_STUB_INFO_LOG) \ + pr_info(fmt, ##arg); \ +} while (0) +#define CMB_STUB_LOG_PR_WARN(fmt, arg...) \ +do { \ + if (gCmbStubLogLevel >= CMB_STUB_WARN_LOG) \ + pr_warn(fmt, ##arg); \ +} while (0) +#define CMB_STUB_LOG_PR_DBG(fmt, arg...) \ +do { \ + if (gCmbStubLogLevel >= CMB_STUB_DBG_LOG) \ + pr_info(fmt, ##arg); \ +} while (0) + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wmt_detect.h" + + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +int gConnectivityChipId = -1; + +/* +* current used uart port name, default is "ttyMT2", +* will be changed when wmt driver init +*/ +char *wmt_uart_port_desc = "ttyMT2"; +EXPORT_SYMBOL(wmt_uart_port_desc); + +#ifdef MTK_WCN_REMOVE_KERNEL_MODULE +static void mtk_wcn_cmb_sdio_request_eirq(msdc_sdio_irq_handler_t irq_handler, void *data); +static void mtk_wcn_cmb_sdio_enable_eirq(void); +static void mtk_wcn_cmb_sdio_disable_eirq(void); +static void mtk_wcn_cmb_sdio_register_pm(pm_callback_t pm_cb, void *data); + +struct sdio_ops mt_sdio_ops[4] = { + {NULL, NULL, NULL, NULL}, + {NULL, NULL, NULL, NULL}, + {mtk_wcn_cmb_sdio_request_eirq, mtk_wcn_cmb_sdio_enable_eirq, + mtk_wcn_cmb_sdio_disable_eirq, mtk_wcn_cmb_sdio_register_pm}, + {mtk_wcn_cmb_sdio_request_eirq, mtk_wcn_cmb_sdio_enable_eirq, + mtk_wcn_cmb_sdio_disable_eirq, mtk_wcn_cmb_sdio_register_pm} +}; +#endif + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +static wmt_aif_ctrl_cb cmb_stub_aif_ctrl_cb; +static wmt_func_ctrl_cb cmb_stub_func_ctrl_cb; +static wmt_thermal_query_cb cmb_stub_thermal_ctrl_cb; +static wmt_trigger_assert_cb cmb_stub_trigger_assert_cb; +static enum CMB_STUB_AIF_X cmb_stub_aif_stat = CMB_STUB_AIF_0; +static wmt_deep_idle_ctrl_cb cmb_stub_deep_idle_ctrl_cb; +static wmt_func_do_reset cmb_stub_do_reset_cb; +static wmt_clock_fail_dump_cb cmb_stub_clock_fail_dump_cb; +/* A temp translation table between COMBO_AUDIO_STATE_X and CMB_STUB_AIF_X. + * This is used for ALPS backward compatible ONLY!!! Remove this table, related + * functions, and type definition after modifying other kernel built-in modules, + * such as AUDIO. [FixMe][GeorgeKuo] + */ +#if 0 +static enum CMB_STUB_AIF_X audio2aif[] = { + [COMBO_AUDIO_STATE_0] = CMB_STUB_AIF_0, + [COMBO_AUDIO_STATE_1] = CMB_STUB_AIF_1, + [COMBO_AUDIO_STATE_2] = CMB_STUB_AIF_2, + [COMBO_AUDIO_STATE_3] = CMB_STUB_AIF_3, +}; +#endif + +#ifdef MTK_WCN_REMOVE_KERNEL_MODULE +static msdc_sdio_irq_handler_t mtk_wcn_cmb_sdio_eirq_handler; +static atomic_t sdio_claim_irq_enable_flag; +static atomic_t irq_enable_flag; +static pm_callback_t mtk_wcn_cmb_sdio_pm_cb; +static void *mtk_wcn_cmb_sdio_pm_data; +static void *mtk_wcn_cmb_sdio_eirq_data; + +static u32 wifi_irq = 0xffffffff; +#endif +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +#ifndef MTK_WCN_REMOVE_KERNEL_MODULE +static int _mtk_wcn_cmb_stub_query_ctrl(void); +static int _mtk_wcn_cmb_stub_trigger_assert(void); +static void _mtk_wcn_cmb_stub_clock_fail_dump(void); +#endif /* MTK_WCN_REMOVE_KERNEL_MODULE */ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +/*! + * \brief A registration function for WMT-PLAT to register itself to CMB-STUB. + * + * An MTK-WCN-CMB-STUB registration function provided to WMT-PLAT to register + * itself and related callback functions when driver being loaded into kernel. + * + * \param p_stub_cb a pointer carrying CMB_STUB_CB information + * + * \retval 0 operation success + * \retval -1 invalid parameters + */ +int mtk_wcn_cmb_stub_reg(struct _CMB_STUB_CB_ *p_stub_cb) +{ +#ifndef MTK_WCN_REMOVE_KERNEL_MODULE + struct wmt_platform_bridge pbridge; + + memset(&pbridge, 0, sizeof(struct wmt_platform_bridge)); +#endif + + if ((!p_stub_cb) + || (p_stub_cb->size != sizeof(struct _CMB_STUB_CB_))) { + CMB_STUB_LOG_PR_WARN("[cmb_stub] invalid p_stub_cb:0x%p size(%d)\n", + p_stub_cb, (p_stub_cb) ? p_stub_cb->size : 0); + return -1; + } + + CMB_STUB_LOG_PR_DBG("[cmb_stub] registered, p_stub_cb:0x%p size(%d)\n", + p_stub_cb, p_stub_cb->size); + + cmb_stub_aif_ctrl_cb = p_stub_cb->aif_ctrl_cb; + cmb_stub_func_ctrl_cb = p_stub_cb->func_ctrl_cb; + cmb_stub_thermal_ctrl_cb = p_stub_cb->thermal_query_cb; + cmb_stub_trigger_assert_cb = p_stub_cb->trigger_assert_cb; + cmb_stub_deep_idle_ctrl_cb = p_stub_cb->deep_idle_ctrl_cb; + cmb_stub_do_reset_cb = p_stub_cb->wmt_do_reset_cb; + cmb_stub_clock_fail_dump_cb = p_stub_cb->clock_fail_dump_cb; + +#ifndef MTK_WCN_REMOVE_KERNEL_MODULE + pbridge.thermal_query_cb = _mtk_wcn_cmb_stub_query_ctrl; + pbridge.trigger_assert_cb = _mtk_wcn_cmb_stub_trigger_assert; + pbridge.clock_fail_dump_cb = _mtk_wcn_cmb_stub_clock_fail_dump; + wmt_export_platform_bridge_register(&pbridge); +#endif + + return 0; +} +EXPORT_SYMBOL(mtk_wcn_cmb_stub_reg); +/*! + * \brief A unregistration function for WMT-PLAT to unregister from CMB-STUB. + * + * An MTK-WCN-CMB-STUB unregistration function provided to WMT-PLAT to + * unregister itself and clear callback function references. + * + * \retval 0 operation success + */ +int mtk_wcn_cmb_stub_unreg(void) +{ +#ifndef MTK_WCN_REMOVE_KERNEL_MODULE + wmt_export_platform_bridge_unregister(); +#endif + + cmb_stub_aif_ctrl_cb = NULL; + cmb_stub_func_ctrl_cb = NULL; + cmb_stub_thermal_ctrl_cb = NULL; + cmb_stub_deep_idle_ctrl_cb = NULL; + cmb_stub_do_reset_cb = NULL; + cmb_stub_clock_fail_dump_cb = NULL; + CMB_STUB_LOG_PR_INFO("[cmb_stub] unregistered\n"); /* KERN_DEBUG */ + + return 0; +} +EXPORT_SYMBOL(mtk_wcn_cmb_stub_unreg); + +/* stub functions for kernel to control audio path pin mux */ +int mtk_wcn_cmb_stub_aif_ctrl(enum CMB_STUB_AIF_X state, enum CMB_STUB_AIF_CTRL ctrl) +{ + int ret; + + if ((state >= CMB_STUB_AIF_MAX) + || (ctrl >= CMB_STUB_AIF_CTRL_MAX)) { + + CMB_STUB_LOG_PR_WARN("[cmb_stub] aif_ctrl invalid (%d, %d)\n", + state, ctrl); + return -1; + } + + /* avoid the early interrupt before we register the eirq_handler */ + if (cmb_stub_aif_ctrl_cb) { + ret = (*cmb_stub_aif_ctrl_cb) (state, ctrl); + CMB_STUB_LOG_PR_INFO("aif state(%d->%d) ctrl(%d) ret(%d)\n", + cmb_stub_aif_stat, state, ctrl, ret); /* KERN_DEBUG */ + + cmb_stub_aif_stat = state; + } else { + CMB_STUB_LOG_PR_WARN("[cmb_stub] aif_ctrl_cb null\n"); + ret = -2; + } + return ret; +} +EXPORT_SYMBOL(mtk_wcn_cmb_stub_aif_ctrl); + +/* Use a temp translation table between COMBO_AUDIO_STATE_X and CMB_STUB_AIF_X + * for ALPS backward compatible ONLY!!! Remove this table, related functions, + * and type definition after modifying other kernel built-in modules, such as + * AUDIO. [FixMe][GeorgeKuo] + */ + +void mtk_wcn_cmb_stub_func_ctrl(unsigned int type, unsigned int on) +{ + if (cmb_stub_func_ctrl_cb) + (*cmb_stub_func_ctrl_cb) (type, on); + else + CMB_STUB_LOG_PR_WARN("[cmb_stub] func_ctrl_cb null\n"); +} +EXPORT_SYMBOL(mtk_wcn_cmb_stub_func_ctrl); + +#ifdef MTK_WCN_REMOVE_KERNEL_MODULE +int mtk_wcn_cmb_stub_query_ctrl(void) +#else +static int _mtk_wcn_cmb_stub_query_ctrl(void) +#endif +{ + signed long temp = 0; + + if (cmb_stub_thermal_ctrl_cb) + temp = (*cmb_stub_thermal_ctrl_cb) (); + else + CMB_STUB_LOG_PR_WARN("[cmb_stub] thermal_ctrl_cb null\n"); + + return temp; +} + +#ifdef MTK_WCN_REMOVE_KERNEL_MODULE +int mtk_wcn_cmb_stub_trigger_assert(void) +#else +static int _mtk_wcn_cmb_stub_trigger_assert(void) +#endif +{ + int ret = 0; + + if (cmb_stub_trigger_assert_cb) + ret = (*cmb_stub_trigger_assert_cb) (); + else + CMB_STUB_LOG_PR_WARN("[cmb_stub] trigger_assert_cb null\n"); + + return ret; +} + +#ifndef MTK_WCN_REMOVE_KERNEL_MODULE +void _mtk_wcn_cmb_stub_clock_fail_dump(void) +{ + if (cmb_stub_clock_fail_dump_cb) + (*cmb_stub_clock_fail_dump_cb) (); + else + CMB_STUB_LOG_PR_WARN("[cmb_stub] clock_fail_dump_cb null\n"); +} +#endif + +/*platform-related APIs*/ +/* void clr_device_working_ability(UINT32 clockId, MT6573_STATE state); */ +/* void set_device_working_ability(UINT32 clockId, MT6573_STATE state); */ + +static int _mt_combo_plt_do_deep_idle(enum COMBO_IF src, int enter) +{ + int ret = -1; + +#if 0 + if (src != COMBO_IF_UART && src != COMBO_IF_MSDC && src != COMBO_IF_BTIF) { + CMB_STUB_LOG_PR_WARN("src = %d is error\n", src); + return ret; + } + if (src >= 0 && src < COMBO_IF_MAX) + CMB_STUB_LOG_PR_INFO("src = %s, to enter deep idle? %d\n", + combo_if_name[src], enter); +#endif + /* + * TODO: For Common SDIO configuration, we need to do some judgement between STP and WIFI + * to decide if the msdc will enter deep idle safely + */ + + switch (src) { + case COMBO_IF_UART: + if (enter == 0) { + /* clr_device_working_ability(MT65XX_PDN_PERI_UART3, DEEP_IDLE_STATE); */ + /* disable_dpidle_by_bit(MT65XX_PDN_PERI_UART2); */ +#ifdef MTK_WCN_COMBO_CHIP_SUPPORT +#if 0 + ret = mtk_uart_pdn_enable(wmt_uart_port_desc, 0); + if (ret < 0) + CMB_STUB_LOG_PR_WARN("%s exit deepidle failed", + wmt_uart_port_desc); +#endif +#endif + } else { + /* set_device_working_ability(MT65XX_PDN_PERI_UART3, DEEP_IDLE_STATE); */ + /* enable_dpidle_by_bit(MT65XX_PDN_PERI_UART2); */ +#ifdef MTK_WCN_COMBO_CHIP_SUPPORT +#if 0 + ret = mtk_uart_pdn_enable(wmt_uart_port_desc, 1); + if (ret < 0) + CMB_STUB_LOG_PR_WARN("%s enter deepidle failed", + wmt_uart_port_desc); +#endif +#endif + } + ret = 0; + break; + + case COMBO_IF_MSDC: + if (enter == 0) { + /* for common sdio hif */ + /* clr_device_working_ability(MT65XX_PDN_PERI_MSDC2, DEEP_IDLE_STATE); */ + } else { + /* for common sdio hif */ + /* set_device_working_ability(MT65XX_PDN_PERI_MSDC2, DEEP_IDLE_STATE); */ + } + ret = 0; + break; + + case COMBO_IF_BTIF: + if (cmb_stub_deep_idle_ctrl_cb) + ret = (*cmb_stub_deep_idle_ctrl_cb) (enter); + else + CMB_STUB_LOG_PR_WARN("NULL function pointer\n"); + + if (ret) + CMB_STUB_LOG_PR_WARN("%s deep idle fail(%d)\n", + enter == 1 ? "enter" : "exit", ret); + else + CMB_STUB_LOG_PR_DBG("%s deep idle ok(%d)\n", + enter == 1 ? "enter" : "exit", ret); + break; + default: + break; + } + + return ret; +} + +int mt_combo_plt_enter_deep_idle(enum COMBO_IF src) +{ + /* return 0; */ + /* TODO: [FixMe][GeorgeKuo] handling this depends on common UART or common SDIO */ + return _mt_combo_plt_do_deep_idle(src, 1); +} +EXPORT_SYMBOL(mt_combo_plt_enter_deep_idle); + +int mt_combo_plt_exit_deep_idle(enum COMBO_IF src) +{ + /* return 0; */ + /* TODO: [FixMe][GeorgeKuo] handling this depends on common UART or common SDIO */ + return _mt_combo_plt_do_deep_idle(src, 0); +} +EXPORT_SYMBOL(mt_combo_plt_exit_deep_idle); + +int mtk_wcn_wmt_chipid_query(void) +{ + CMB_STUB_LOG_PR_INFO("query current consys chipid (0x%x)\n", + gConnectivityChipId); + return gConnectivityChipId; +} +EXPORT_SYMBOL(mtk_wcn_wmt_chipid_query); + +void mtk_wcn_wmt_set_chipid(int chipid) +{ + CMB_STUB_LOG_PR_INFO("set current consys chipid (0x%x)\n", chipid); + gConnectivityChipId = chipid; +} +EXPORT_SYMBOL(mtk_wcn_wmt_set_chipid); + +int mtk_wcn_cmb_stub_do_reset(unsigned int type) +{ + if (cmb_stub_do_reset_cb) + return (*cmb_stub_do_reset_cb) (type); + else + return -1; +} +EXPORT_SYMBOL(mtk_wcn_cmb_stub_do_reset); + +#ifdef MTK_WCN_REMOVE_KERNEL_MODULE +static void mtk_wcn_cmb_sdio_enable_eirq(void) +{ + if (atomic_read(&irq_enable_flag)) + CMB_STUB_LOG_PR_DBG("wifi eint has been enabled\n"); + else { + atomic_set(&irq_enable_flag, 1); + if (wifi_irq != 0xffffffff) { + enable_irq(wifi_irq); + CMB_STUB_LOG_PR_DBG(" enable WIFI EINT irq %d !!\n", + wifi_irq); + } + } +} + +static void mtk_wcn_cmb_sdio_disable_eirq(void) +{ + if (!atomic_read(&irq_enable_flag)) + CMB_STUB_LOG_PR_DBG("wifi eint has been disabled!\n"); + else { + if (wifi_irq != 0xffffffff) { + disable_irq_nosync(wifi_irq); + CMB_STUB_LOG_PR_DBG("disable WIFI EINT irq %d !!\n", + wifi_irq); + } + atomic_set(&irq_enable_flag, 0); + } +} + +irqreturn_t mtk_wcn_cmb_sdio_eirq_handler_stub(int irq, void *data) +{ + if ((mtk_wcn_cmb_sdio_eirq_handler != NULL) && (atomic_read(&sdio_claim_irq_enable_flag) != 0)) + mtk_wcn_cmb_sdio_eirq_handler(mtk_wcn_cmb_sdio_eirq_data); + return IRQ_HANDLED; +} + +static void mtk_wcn_cmb_sdio_request_eirq(msdc_sdio_irq_handler_t irq_handler, void *data) +{ + struct device_node *node; + int ret = -EINVAL; +#if 0 + unsigned int gpio_wifi_eint_pin; +#endif + + CMB_STUB_LOG_PR_INFO("enter %s\n", __func__); + mtk_wcn_sdio_irq_flag_set(0); + atomic_set(&irq_enable_flag, 1); + mtk_wcn_cmb_sdio_eirq_data = data; + mtk_wcn_cmb_sdio_eirq_handler = irq_handler; + + node = (struct device_node *)of_find_compatible_node(NULL, NULL, "mediatek,connectivity-combo"); + if (node) { +#if 0 + gpio_wifi_eint_pin = of_get_gpio(node, 5); + CMB_STUB_LOG_PR_INFO("WIFI EINT pin %d !!\n", + gpio_wifi_eint_pin); + wifi_irq = gpio_to_irq(gpio_wifi_eint_pin); +#else + wifi_irq = irq_of_parse_and_map(node, 0);/* get wifi eint num */ +#endif +#if 1 + ret = request_irq(wifi_irq, mtk_wcn_cmb_sdio_eirq_handler_stub, IRQF_TRIGGER_LOW, + "WIFI-eint", NULL); + CMB_STUB_LOG_PR_DBG("WIFI EINT irq %d !!\n", wifi_irq); +#endif + + if (ret) + CMB_STUB_LOG_PR_WARN("EINT IRQ LINE NOT AVAILABLE!!\n"); + else + mtk_wcn_cmb_sdio_disable_eirq();/*not ,chip state is power off*/ + } else + CMB_STUB_LOG_PR_WARN("[%s] can't find device node\n", __func__); + + CMB_STUB_LOG_PR_INFO("exit %s\n", __func__); +} + +static void mtk_wcn_cmb_sdio_register_pm(pm_callback_t pm_cb, void *data) +{ + CMB_STUB_LOG_PR_DBG("mtk_wcn_cmb_sdio_register_pm (0x%p, 0x%p)\n", + pm_cb, data); + /* register pm change callback */ + mtk_wcn_cmb_sdio_pm_cb = pm_cb; + mtk_wcn_cmb_sdio_pm_data = data; +} +#endif /* MTK_WCN_REMOVE_KERNEL_MODULE */ + +static void mtk_wcn_cmb_sdio_on(int sdio_port_num) +{ + pm_message_t state = {.event = PM_EVENT_USER_RESUME }; + + CMB_STUB_LOG_PR_INFO("mtk_wcn_cmb_sdio_on (%d)\n", sdio_port_num); + + /* 1. disable sdio eirq */ +#ifdef MTK_WCN_REMOVE_KERNEL_MODULE + mtk_wcn_cmb_sdio_disable_eirq(); +#else + wmt_export_mtk_wcn_cmb_sdio_disable_eirq(); +#endif + + /* 2. call sd callback */ + if (mtk_wcn_cmb_sdio_pm_cb) { + /* pr_warn("mtk_wcn_cmb_sdio_pm_cb(PM_EVENT_USER_RESUME, 0x%p, 0x%p)\n", + * mtk_wcn_cmb_sdio_pm_cb, mtk_wcn_cmb_sdio_pm_data); + */ + mtk_wcn_cmb_sdio_pm_cb(state, mtk_wcn_cmb_sdio_pm_data); + } else + CMB_STUB_LOG_PR_WARN("mtk_wcn_cmb_sdio_on no sd callback!!\n"); +} + +static void mtk_wcn_cmb_sdio_off(int sdio_port_num) +{ + pm_message_t state = {.event = PM_EVENT_USER_SUSPEND }; + + CMB_STUB_LOG_PR_INFO("mtk_wcn_cmb_sdio_off (%d)\n", sdio_port_num); + + /* 1. call sd callback */ + if (mtk_wcn_cmb_sdio_pm_cb) { + /* pr_warn("mtk_wcn_cmb_sdio_off(PM_EVENT_USER_SUSPEND, 0x%p, 0x%p)\n", + * mtk_wcn_cmb_sdio_pm_cb, mtk_wcn_cmb_sdio_pm_data); + */ + mtk_wcn_cmb_sdio_pm_cb(state, mtk_wcn_cmb_sdio_pm_data); + } else + CMB_STUB_LOG_PR_WARN("mtk_wcn_cmb_sdio_off no sd callback!!\n"); + + /* 2. disable sdio eirq */ +#ifdef MTK_WCN_REMOVE_KERNEL_MODULE + mtk_wcn_cmb_sdio_disable_eirq(); +#else + wmt_export_mtk_wcn_cmb_sdio_disable_eirq(); +#endif +} + +int board_sdio_ctrl(unsigned int sdio_port_num, unsigned int on) +{ + CMB_STUB_LOG_PR_DBG("mt_mtk_wcn_cmb_sdio_ctrl (%d, %d)\n", + sdio_port_num, on); + if (on) { +#if 1 + CMB_STUB_LOG_PR_DBG("board_sdio_ctrl force off before on\n"); + mtk_wcn_cmb_sdio_off(sdio_port_num); +#else + CMB_STUB_LOG_PR_WARN("skip sdio off before on\n"); +#endif + /* off -> on */ + mtk_wcn_cmb_sdio_on(sdio_port_num); + if (wifi_irq != 0xffffffff) + irq_set_irq_wake(wifi_irq, 1); + else + CMB_STUB_LOG_PR_WARN("wifi_irq is not available\n"); + } else { + if (wifi_irq != 0xffffffff) + irq_set_irq_wake(wifi_irq, 0); + else + CMB_STUB_LOG_PR_WARN("wifi_irq is not available\n"); + /* on -> off */ + mtk_wcn_cmb_sdio_off(sdio_port_num); + } + + return 0; +} +EXPORT_SYMBOL(board_sdio_ctrl); + +#ifdef MTK_WCN_REMOVE_KERNEL_MODULE +int mtk_wcn_sdio_irq_flag_set(int flag) +{ + if (flag != 0) + atomic_set(&sdio_claim_irq_enable_flag, 1); + else + atomic_set(&sdio_claim_irq_enable_flag, 0); + + CMB_STUB_LOG_PR_DBG("sdio_claim_irq_enable_flag:%d\n", + atomic_read(&sdio_claim_irq_enable_flag)); + + return atomic_read(&sdio_claim_irq_enable_flag); +} +EXPORT_SYMBOL(mtk_wcn_sdio_irq_flag_set); +#endif diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.c b/drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.c new file mode 100644 index 0000000000000000000000000000000000000000..42dbafecd265d0cca0cf1741c00cc0d462938d62 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.c @@ -0,0 +1,249 @@ +/* +* Copyright (C) 2011-2014 MediaTek Inc. +* +* This program is free software: you can redistribute it and/or modify it under the terms of the +* GNU General Public License version 2 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. +* +* You should have received a copy of the GNU General Public License along with this program. +* If not, see . +*/ + +#ifdef DFT_TAG +#undef DFT_TAG +#endif +#define DFT_TAG "[SDIO-DETECT]" + +#include "wmt_detect.h" + +unsigned int gComboChipId = -1; +struct sdio_func *g_func; +unsigned int gDrvRegistered; + +MTK_WCN_HIF_SDIO_CHIP_INFO gChipInfoArray[] = { + /* MT6620 *//* Not an SDIO standard class device */ + {{SDIO_DEVICE(0x037A, 0x020A)}, 0x6620}, /* SDIO1:FUNC1:WIFI */ + {{SDIO_DEVICE(0x037A, 0x020B)}, 0x6620}, /* SDIO2:FUNC1:BT+FM+GPS */ + {{SDIO_DEVICE(0x037A, 0x020C)}, 0x6620}, /* 2-function (SDIO2:FUNC1:BT+FM+GPS, FUNC2:WIFI) */ + + /* MT6628 *//* SDIO1: Wi-Fi, SDIO2: BGF */ + {{SDIO_DEVICE(0x037A, 0x6628)}, 0x6628}, + + /* MT6630 *//* SDIO1: Wi-Fi, SDIO2: BGF */ + {{SDIO_DEVICE(0x037A, 0x6630)}, 0x6630}, + + /* MT6632 *//* SDIO1: Wi-Fi */ + {{SDIO_DEVICE(0x037A, 0x6602)}, 0x6632}, + + /* MT6632 *//* SDIO2: BGF */ + {{SDIO_DEVICE(0x037A, 0x6632)}, 0x6632}, + +}; + +/* Supported SDIO device table */ +static const struct sdio_device_id mtk_sdio_id_tbl[] = { + /* MT6618 *//* Not an SDIO standard class device */ + {SDIO_DEVICE(0x037A, 0x018A)}, /* SDIO1:WIFI */ + {SDIO_DEVICE(0x037A, 0x018B)}, /* SDIO2:FUNC1:BT+FM */ + {SDIO_DEVICE(0x037A, 0x018C)}, /* 2-function (SDIO2:FUNC1:BT+FM, FUNC2:WIFI) */ + + /* MT6619 *//* Not an SDIO standard class device */ + {SDIO_DEVICE(0x037A, 0x6619)}, /* SDIO2:FUNC1:BT+FM+GPS */ + + /* MT6620 *//* Not an SDIO standard class device */ + {SDIO_DEVICE(0x037A, 0x020A)}, /* SDIO1:FUNC1:WIFI */ + {SDIO_DEVICE(0x037A, 0x020B)}, /* SDIO2:FUNC1:BT+FM+GPS */ + {SDIO_DEVICE(0x037A, 0x020C)}, /* 2-function (SDIO2:FUNC1:BT+FM+GPS, FUNC2:WIFI) */ + + /* MT5921 *//* Not an SDIO standard class device */ + {SDIO_DEVICE(0x037A, 0x5921)}, + + /* MT6628 *//* SDIO1: Wi-Fi, SDIO2: BGF */ + {SDIO_DEVICE(0x037A, 0x6628)}, + + /* MT6630 *//* SDIO1: Wi-Fi, SDIO2: BGF */ + {SDIO_DEVICE(0x037A, 0x6630)}, + + /* MT6632 *//* SDIO1: Wi-Fi */ + {SDIO_DEVICE(0x037A, 0x6602)}, + + /* MT6632 *//* SDIO2: BGF */ + {SDIO_DEVICE(0x037A, 0x6632)}, + { /* end: all zeroes */ }, +}; + +static int sdio_detect_probe(struct sdio_func *func, const struct sdio_device_id *id); + +static void sdio_detect_remove(struct sdio_func *func); + +static struct sdio_driver mtk_sdio_client_drv = { + .name = "mtk_sdio_client", /* MTK SDIO Client Driver */ + .id_table = mtk_sdio_id_tbl, /* all supported struct sdio_device_id table */ + .probe = sdio_detect_probe, + .remove = sdio_detect_remove, +}; + +static int hif_sdio_match_chipid_by_dev_id(const struct sdio_device_id *id); + +int hif_sdio_is_chipid_valid(int chipId) +{ + int index = -1; + + int left = 0; + int middle = 0; + int right = ARRAY_SIZE(gChipInfoArray) - 1; + + if ((chipId < gChipInfoArray[left].chipId) || (chipId > gChipInfoArray[right].chipId)) + return index; + + middle = (left + right) / 2; + + while (left <= right) { + if (chipId > gChipInfoArray[middle].chipId) { + left = middle + 1; + } else if (chipId < gChipInfoArray[middle].chipId) { + right = middle - 1; + } else { + index = middle; + break; + } + middle = (left + right) / 2; + } + + if (index < 0) + WMT_DETECT_PR_ERR("no supported chipid found\n"); + else + WMT_DETECT_PR_INFO("index:%d, chipId:0x%x\n", index, gChipInfoArray[index].chipId); + + return index; +} + +int hif_sdio_match_chipid_by_dev_id(const struct sdio_device_id *id) +{ + int maxIndex = ARRAY_SIZE(gChipInfoArray); + int index = 0; + struct sdio_device_id *localId = NULL; + int chipId = -1; + + for (index = 0; index < maxIndex; index++) { + localId = &(gChipInfoArray[index].deviceId); + if ((localId->vendor == id->vendor) && (localId->device == id->device)) { + chipId = gChipInfoArray[index].chipId; + WMT_DETECT_PR_INFO + ("valid chipId found, index(%d), vendor id(0x%x), device id(0x%x), chip id(0x%x)\n", index, + localId->vendor, localId->device, chipId); + mtk_wcn_wmt_set_chipid(chipId); + gComboChipId = chipId; + break; + } + } + if (chipId < 0) { + WMT_DETECT_PR_ERR("No valid chipId found, vendor id(0x%x), device id(0x%x)\n", id->vendor, + id->device); + } + + return chipId; +} + +int sdio_detect_query_chipid(int waitFlag) +{ + unsigned int timeSlotMs = 200; + unsigned int maxTimeSlot = 30; + unsigned int counter = 0; + /* gComboChipId = 0x6628; */ + if (waitFlag == 0) + return gComboChipId; + if (hif_sdio_is_chipid_valid(gComboChipId) >= 0) + return gComboChipId; + + while (counter < maxTimeSlot) { + if (hif_sdio_is_chipid_valid(gComboChipId) >= 0) + break; + msleep(timeSlotMs); + counter++; + } + + return gComboChipId; +} + +int sdio_detect_do_autok(int chipId) +{ + int i_ret = 0; + + WMT_DETECT_PR_INFO("autok was move to sdio driver\n"); + return i_ret; +} + +/*! + * \brief hif_sdio probe function + * + * hif_sdio probe function called by mmc driver when any matched SDIO function + * is detected by it. + * + * \param func + * \param id + * + * \retval 0 register successfully + * \retval < 0 list error code here + */ +static int sdio_detect_probe(struct sdio_func *func, const struct sdio_device_id *id) +{ + int chipId = 0; + + WMT_DETECT_PR_INFO("vendor(0x%x) device(0x%x) num(0x%x)\n", func->vendor, func->device, func->num); + chipId = hif_sdio_match_chipid_by_dev_id(id); + + if ((chipId == 0x6630 || chipId == 0x6632) && (func->num == 1)) { + int ret = 0; + + g_func = func; + WMT_DETECT_PR_INFO("autok function detected, func:0x%p\n", g_func); + + sdio_claim_host(func); + ret = sdio_enable_func(func); + sdio_release_host(func); + if (ret) + WMT_DETECT_PR_ERR("sdio_enable_func failed!\n"); + } + + return 0; +} + +static void sdio_detect_remove(struct sdio_func *func) +{ + if (g_func == func) { + sdio_claim_host(func); + sdio_disable_func(func); + sdio_release_host(func); + g_func = NULL; + } + WMT_DETECT_PR_INFO("do sdio remove\n"); +} + +int sdio_detect_init(void) +{ + int ret = 0; + /* register to mmc driver */ + if (gDrvRegistered == 0) { + ret = sdio_register_driver(&mtk_sdio_client_drv); + if (ret == 0) + gDrvRegistered = 1; + } + WMT_DETECT_PR_INFO("sdio_register_driver() ret=%d\n", ret); + return ret; +} + +int sdio_detect_exit(void) +{ + g_func = NULL; + /* unregister to mmc driver */ + if (gDrvRegistered == 1) { + sdio_unregister_driver(&mtk_sdio_client_drv); + gDrvRegistered = 0; + } + WMT_DETECT_PR_INFO("sdio_unregister_driver\n"); + return 0; +} diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.h b/drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.h new file mode 100644 index 0000000000000000000000000000000000000000..274261d6075d1c04c02c77aeb89cfe0da6ff60b7 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.h @@ -0,0 +1,36 @@ +/* +* Copyright (C) 2011-2014 MediaTek Inc. +* +* This program is free software: you can redistribute it and/or modify it under the terms of the +* GNU General Public License version 2 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. +* +* You should have received a copy of the GNU General Public License along with this program. +* If not, see . +*/ + +#ifndef _SDIO_DETECT_H_ +#define _SDIO_DETECT_H_ + +#include +#include +#include +#include +#include + +typedef struct _MTK_WCN_HIF_SDIO_CHIP_INFO_ { + struct sdio_device_id deviceId; + unsigned int chipId; +} MTK_WCN_HIF_SDIO_CHIP_INFO, *P_MTK_WCN_HIF_SDIO_CHIP_INFO; + +extern int sdio_detect_exit(void); +extern int sdio_detect_init(void); +extern int sdio_detect_query_chipid(int waitFlag); +extern int hif_sdio_is_chipid_valid(int chipId); + +extern int sdio_detect_do_autok(int chipId); + +#endif diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.c b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.c new file mode 100644 index 0000000000000000000000000000000000000000..ade16a12be1c8f772ba6ccb999c6d4d986a1fe56 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.c @@ -0,0 +1,407 @@ +/* +* Copyright (C) 2011-2014 MediaTek Inc. +* +* This program is free software: you can redistribute it and/or modify it under the terms of the +* GNU General Public License version 2 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. +* +* You should have received a copy of the GNU General Public License along with this program. +* If not, see . +*/ + +#include +#include + +#ifdef DFT_TAG +#undef DFT_TAG +#endif +#define DFT_TAG "[WMT-DETECT]" + +#include "wmt_detect.h" +#include "wmt_gpio.h" +#include "wmt_dev.h" + +#if MTK_WCN_REMOVE_KO +#include "conn_drv_init.h" +#endif +#ifdef CONFIG_COMPAT +#include +#endif + +#define WMT_DETECT_MAJOR 154 +#define WMT_DETECT_DEV_NUM 1 +#define WMT_DETECT_DRVIER_NAME "mtk_wcn_detect" +#define WMT_DETECT_DEVICE_NAME "wmtdetect" + +struct class *pDetectClass; +struct device *pDetectDev; +static int gWmtDetectMajor = WMT_DETECT_MAJOR; +static struct cdev gWmtDetectCdev; +int gWmtDetectDbgLvl = WMT_DETECT_LOG_INFO; +static ENUM_WMT_CHIP_TYPE g_chip_type = WMT_CHIP_TYPE_INVALID; + +static int wmt_detect_open(struct inode *inode, struct file *file) +{ + WMT_DETECT_PR_INFO("open major %d minor %d (pid %d)\n", imajor(inode), iminor(inode), current->pid); + + return 0; +} + +static int wmt_detect_close(struct inode *inode, struct file *file) +{ + WMT_DETECT_PR_INFO("close major %d minor %d (pid %d)\n", imajor(inode), iminor(inode), current->pid); + + return 0; +} + +static ssize_t wmt_detect_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) +{ + WMT_DETECT_PR_INFO(" ++\n"); + WMT_DETECT_PR_INFO(" --\n"); + + return 0; +} + +ssize_t wmt_detect_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) +{ + WMT_DETECT_PR_INFO(" ++\n"); + WMT_DETECT_PR_INFO(" --\n"); + + return 0; +} + +static long wmt_detect_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + int retval = 0; + + WMT_DETECT_PR_INFO("cmd (%d),arg(%ld)\n", cmd, arg); + + switch (cmd) { + case COMBO_IOCTL_GET_CHIP_ID: + /*just get chipid from sdio-detect module */ + /*check if external combo chip exists or not */ + /*if yes, just return combo chip id */ + /*if no, get soc chipid */ + retval = mtk_wcn_wmt_chipid_query(); + break; + + case COMBO_IOCTL_SET_CHIP_ID: + WMT_DETECT_PR_INFO("chipid(%ld)\n", arg); + mtk_wcn_wmt_set_chipid(arg); + wmt_detect_set_chip_type(arg); + break; + + case COMBO_IOCTL_EXT_CHIP_PWR_ON: + retval = wmt_detect_ext_chip_pwr_on(); + break; + + case COMBO_IOCTL_EXT_CHIP_DETECT: + retval = wmt_detect_ext_chip_detect(); + break; + + case COMBO_IOCTL_EXT_CHIP_PWR_OFF: + retval = wmt_detect_ext_chip_pwr_off(); + break; + + case COMBO_IOCTL_DO_SDIO_AUDOK: + retval = sdio_detect_do_autok(arg); + break; + + case COMBO_IOCTL_GET_SOC_CHIP_ID: + retval = wmt_plat_get_soc_chipid(); + /*get soc chipid by HAL interface */ + break; + + case COMBO_IOCTL_GET_ADIE_CHIP_ID: + retval = wmt_plat_get_adie_chipid(); + break; + + case COMBO_IOCTL_MODULE_CLEANUP: + retval = sdio_detect_exit(); + break; + + case COMBO_IOCTL_DO_MODULE_INIT: +#if (MTK_WCN_REMOVE_KO) + /*deinit SDIO-DETECT module */ + WMT_DETECT_PR_INFO("built-in mode\n"); + retval = do_connectivity_driver_init(arg); +#else + WMT_DETECT_PR_INFO("kernel object mode\n"); + retval = mtk_wcn_common_drv_init(); +#endif + break; + + default: + WMT_DETECT_PR_WARN("unknown cmd (%d)\n", cmd); + retval = 0; + break; + } + return retval; +} +#ifdef CONFIG_COMPAT +static long WMT_compat_detect_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + long ret; + + WMT_DETECT_PR_INFO("cmd (%d)\n", cmd); + ret = wmt_detect_unlocked_ioctl(filp, cmd, arg); + return ret; +} +#endif +const struct file_operations gWmtDetectFops = { + .open = wmt_detect_open, + .release = wmt_detect_close, + .read = wmt_detect_read, + .write = wmt_detect_write, + .unlocked_ioctl = wmt_detect_unlocked_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = WMT_compat_detect_ioctl, +#endif +}; + +int wmt_detect_ext_chip_pwr_on(void) +{ + /*pre power on external chip */ + /* wmt_plat_pwr_ctrl(FUNC_ON); */ +#ifdef MTK_WCN_COMBO_CHIP_SUPPORT + WMT_DETECT_PR_INFO("++\n"); + if (wmt_detect_chip_pwr_ctrl(1) != 0) + return -2; + if (wmt_detect_sdio_pwr_ctrl(1) != 0) + return -3; + return 0; +#else + WMT_DETECT_PR_INFO("combo chip is not supported\n"); + return -1; +#endif +} + +int wmt_detect_ext_chip_pwr_off(void) +{ + /*pre power off external chip */ + /* wmt_plat_pwr_ctrl(FUNC_OFF); */ +#ifdef MTK_WCN_COMBO_CHIP_SUPPORT + WMT_DETECT_PR_INFO("--\n"); + wmt_detect_sdio_pwr_ctrl(0); + return wmt_detect_chip_pwr_ctrl(0); +#else + WMT_DETECT_PR_INFO("combo chip is not supported\n"); + return 0; +#endif +} + +int wmt_detect_ext_chip_detect(void) +{ + int iRet = -1; +#ifdef MTK_WCN_COMBO_CHIP_SUPPORT + unsigned int chipId = -1; + /*if there is no external combo chip, return -1 */ + int bgfEintStatus = -1; + + WMT_DETECT_PR_INFO("++\n"); + /*wait for a stable time */ + msleep(20); + + /*read BGF_EINT_PIN status */ + bgfEintStatus = wmt_detect_read_ext_cmb_status(); + + if (bgfEintStatus == 0) { + /*external chip does not exist */ + WMT_DETECT_PR_INFO("external combo chip not detected\n"); + iRet = -2; + } else if (bgfEintStatus == 1) { + /*combo chip exists */ + WMT_DETECT_PR_INFO("external combo chip detected\n"); + + /*detect chipid by sdio_detect module */ + chipId = sdio_detect_query_chipid(1); + if (hif_sdio_is_chipid_valid(chipId) >= 0) + WMT_DETECT_PR_INFO("valid external combo chip id (0x%x)\n", chipId); + else + WMT_DETECT_PR_INFO("invalid external combo chip id (0x%x)\n", chipId); + iRet = 0; + } else { + /*Error exists */ + WMT_DETECT_PR_ERR("error happens when detecting combo chip\n"); + iRet = -3; + } + WMT_DETECT_PR_INFO("--\n"); + /*return 0 */ +#endif + return iRet; + /*todo: if there is external combo chip, power on chip return 0 */ +} + +#ifdef MTK_WCN_COMBO_CHIP_SUPPORT +static int wmt_detect_probe(struct platform_device *pdev) +{ + int ret = 0; + + WMT_DETECT_PR_INFO("platform name: %s\n", pdev->name); + ret = wmt_gpio_init(pdev); + if (-1 == ret) + WMT_DETECT_PR_ERR("gpio init fail ret:%d\n", ret); + return ret; +} + +static int wmt_detect_remove(struct platform_device *pdev) +{ + wmt_gpio_deinit(); + return 0; +} +#endif + +int wmt_detect_set_chip_type(int chip_id) +{ + switch (chip_id) { + case 0x6620: + case 0x6628: + case 0x6630: + case 0x6632: + g_chip_type = WMT_CHIP_TYPE_COMBO; + break; + case -1: + break; + default: + g_chip_type = WMT_CHIP_TYPE_SOC; + break; + } + return 0; +} +ENUM_WMT_CHIP_TYPE wmt_detect_get_chip_type(void) +{ + return g_chip_type; +} + + +#ifdef MTK_WCN_COMBO_CHIP_SUPPORT +static const struct of_device_id wmt_detect_match[] = { + { .compatible = "mediatek,connectivity-combo", }, + {} +}; +MODULE_DEVICE_TABLE(of, wmt_detect_match); + +static struct platform_driver wmt_detect_driver = { + .probe = wmt_detect_probe, + .remove = wmt_detect_remove, + .driver = { + .owner = THIS_MODULE, + .name = "mediatek,connectivity-combo", + .of_match_table = wmt_detect_match, + }, +}; +#endif + +/*module_platform_driver(wmt_detect_driver);*/ +static int wmt_detect_driver_init(void) +{ + dev_t devID = MKDEV(gWmtDetectMajor, 0); + int cdevErr = -1; + int ret = -1; + + /*init SDIO-DETECT module */ + sdio_detect_init(); + +#ifdef MTK_WCN_COMBO_CHIP_SUPPORT + ret = platform_driver_register(&wmt_detect_driver); + if (ret) + WMT_DETECT_PR_ERR("platform driver register fail ret:%d\n", ret); +#endif + + ret = register_chrdev_region(devID, WMT_DETECT_DEV_NUM, WMT_DETECT_DRVIER_NAME); + if (ret) { + WMT_DETECT_PR_ERR("fail to register chrdev\n"); + goto err0; + } + + cdev_init(&gWmtDetectCdev, &gWmtDetectFops); + gWmtDetectCdev.owner = THIS_MODULE; + + cdevErr = cdev_add(&gWmtDetectCdev, devID, WMT_DETECT_DEV_NUM); + if (cdevErr) { + WMT_DETECT_PR_ERR("cdev_add() fails (%d)\n", cdevErr); + goto err1; + } + + pDetectClass = class_create(THIS_MODULE, WMT_DETECT_DEVICE_NAME); + if (IS_ERR(pDetectClass)) { + WMT_DETECT_PR_ERR("class create fail, error code(%ld)\n", PTR_ERR(pDetectClass)); + goto err1; + } + + pDetectDev = device_create(pDetectClass, NULL, devID, NULL, WMT_DETECT_DEVICE_NAME); + if (IS_ERR(pDetectDev)) { + WMT_DETECT_PR_ERR("device create fail, error code(%ld)\n", PTR_ERR(pDetectDev)); + goto err2; + } + + WMT_DETECT_PR_INFO("driver(major %d) installed success\n", gWmtDetectMajor); + + return 0; + +err2: + + if (pDetectClass) { + class_destroy(pDetectClass); + pDetectClass = NULL; + } + +err1: + + if (cdevErr == 0) + cdev_del(&gWmtDetectCdev); + + if (ret == 0) { + unregister_chrdev_region(devID, WMT_DETECT_DEV_NUM); + gWmtDetectMajor = -1; + } + +err0: + sdio_detect_exit(); + +#ifdef MTK_WCN_COMBO_CHIP_SUPPORT + platform_driver_unregister(&wmt_detect_driver); +#endif + + return ret ? ret : -1; +} + +static void wmt_detect_driver_exit(void) +{ + dev_t dev = MKDEV(gWmtDetectMajor, 0); + + mtk_wcn_common_drv_exit(); + + if (pDetectDev) { + device_destroy(pDetectClass, dev); + pDetectDev = NULL; + } + + if (pDetectClass) { + class_destroy(pDetectClass); + pDetectClass = NULL; + } + + cdev_del(&gWmtDetectCdev); + unregister_chrdev_region(dev, WMT_DETECT_DEV_NUM); + + sdio_detect_exit(); + +#ifdef MTK_WCN_COMBO_CHIP_SUPPORT + if (wmt_detect_driver.driver.p) + platform_driver_unregister(&wmt_detect_driver); +#endif + + WMT_DETECT_PR_INFO("done\n"); +} + +module_init(wmt_detect_driver_init); +module_exit(wmt_detect_driver_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Zhiguo.Niu & Chaozhong.Liang @ MBJ/WCNSE/SS1"); + +module_param(gWmtDetectMajor, uint, 0); diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.h b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.h new file mode 100644 index 0000000000000000000000000000000000000000..b6ca8857beab2bacac9dde90bd5f72821a300075 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.h @@ -0,0 +1,120 @@ +/* +* Copyright (C) 2011-2014 MediaTek Inc. +* +* This program is free software: you can redistribute it and/or modify it under the terms of the +* GNU General Public License version 2 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. +* +* You should have received a copy of the GNU General Public License along with this program. +* If not, see . +*/ + +#ifndef _WMT_DETECT_H_ +#define _WMT_DETECT_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ +#ifdef MTK_WCN_REMOVE_KERNEL_MODULE +#define MTK_WCN_REMOVE_KO 1 +#else +#define MTK_WCN_REMOVE_KO 0 +#endif + +#include "sdio_detect.h" +#include "wmt_detect_pwr.h" +#include + +#define WMT_DETECT_LOG_LOUD 4 +#define WMT_DETECT_LOG_DBG 3 +#define WMT_DETECT_LOG_INFO 2 +#define WMT_DETECT_LOG_WARN 1 +#define WMT_DETECT_LOG_ERR 0 + +extern int gWmtDetectDbgLvl; + +#define WMT_DETECT_PR_LOUD(fmt, arg...) \ +do { \ + if (gWmtDetectDbgLvl >= WMT_DETECT_LOG_LOUD) \ + pr_info(DFT_TAG"[L]%s:" fmt, __func__, ##arg); \ +} while (0) +#define WMT_DETECT_PR_DBG(fmt, arg...) \ +do { \ + if (gWmtDetectDbgLvl >= WMT_DETECT_LOG_DBG) \ + pr_info(DFT_TAG"[D]%s:" fmt, __func__, ##arg); \ +} while (0) +#define WMT_DETECT_PR_INFO(fmt, arg...) \ +do { \ + if (gWmtDetectDbgLvl >= WMT_DETECT_LOG_INFO) \ + pr_info(DFT_TAG"[I]%s:" fmt, __func__, ##arg); \ +} while (0) +#define WMT_DETECT_PR_WARN(fmt, arg...) \ +do { \ + if (gWmtDetectDbgLvl >= WMT_DETECT_LOG_WARN) \ + pr_warn(DFT_TAG"[W]%s(%d):" fmt, __func__, __LINE__, ##arg); \ +} while (0) +#define WMT_DETECT_PR_ERR(fmt, arg...) \ +do { \ + if (gWmtDetectDbgLvl >= WMT_DETECT_LOG_ERR) \ + pr_err(DFT_TAG"[E]%s(%d):" fmt, __func__, __LINE__, ##arg); \ +} while (0) + +#define WMT_DETECT_IOC_MAGIC 'w' +#define COMBO_IOCTL_GET_CHIP_ID _IOR(WMT_DETECT_IOC_MAGIC, 0, int) +#define COMBO_IOCTL_SET_CHIP_ID _IOW(WMT_DETECT_IOC_MAGIC, 1, int) +#define COMBO_IOCTL_EXT_CHIP_DETECT _IOR(WMT_DETECT_IOC_MAGIC, 2, int) +#define COMBO_IOCTL_GET_SOC_CHIP_ID _IOR(WMT_DETECT_IOC_MAGIC, 3, int) +#define COMBO_IOCTL_DO_MODULE_INIT _IOR(WMT_DETECT_IOC_MAGIC, 4, int) +#define COMBO_IOCTL_MODULE_CLEANUP _IOR(WMT_DETECT_IOC_MAGIC, 5, int) +#define COMBO_IOCTL_EXT_CHIP_PWR_ON _IOR(WMT_DETECT_IOC_MAGIC, 6, int) +#define COMBO_IOCTL_EXT_CHIP_PWR_OFF _IOR(WMT_DETECT_IOC_MAGIC, 7, int) +#define COMBO_IOCTL_DO_SDIO_AUDOK _IOR(WMT_DETECT_IOC_MAGIC, 8, int) +#define COMBO_IOCTL_GET_ADIE_CHIP_ID _IOR(WMT_DETECT_IOC_MAGIC, 9, int) + +typedef enum _ENUM_WMT_CHIP_TYPE_T { + WMT_CHIP_TYPE_COMBO, + WMT_CHIP_TYPE_SOC, + WMT_CHIP_TYPE_INVALID +} ENUM_WMT_CHIP_TYPE; +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +********************************************************************************/ +extern int wmt_detect_ext_chip_detect(void); +extern int wmt_detect_ext_chip_pwr_on(void); +extern int wmt_detect_ext_chip_pwr_off(void); + +extern unsigned int wmt_plat_get_soc_chipid(void); +extern int wmt_plat_get_adie_chipid(void); + +#ifdef MTK_WCN_COMBO_CHIP_SUPPORT +/* mtk_uart_pdn_enable -- request uart port enter/exit deep idle mode, this API is defined in uart driver + * + * @ port - uart port name, Eg: "ttyMT0", "ttyMT1", "ttyMT2" + * @ enable - "1", enable deep idle; "0", disable deep idle + * + * Return 0 if success, else -1 + */ +extern unsigned int mtk_uart_pdn_enable(char *port, int enable); +#endif +extern int wmt_detect_set_chip_type(int chip_id); +extern ENUM_WMT_CHIP_TYPE wmt_detect_get_chip_type(void); +#endif diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.c b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.c new file mode 100644 index 0000000000000000000000000000000000000000..7d26c2df4f21048be73c99be8fdceea6321d9119 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.c @@ -0,0 +1,259 @@ +/* +* Copyright (C) 2011-2014 MediaTek Inc. +* +* This program is free software: you can redistribute it and/or modify it under the terms of the +* GNU General Public License version 2 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. +* +* You should have received a copy of the GNU General Public License along with this program. +* If not, see . +*/ + +/* ALPS header files */ +#include + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0)) +#ifndef CONFIG_RTC_DRV_MT6397 +#include +#else +#include +#endif +#endif + +#ifdef DFT_TAG +#undef DFT_TAG +#endif +#define DFT_TAG "[WMT-DETECT]" + +#include "wmt_detect.h" +#include "wmt_gpio.h" + +#define INVALID_PIN_ID (0xFFFFFFFF) + +/*copied form WMT module*/ +static int wmt_detect_dump_pin_conf(void) +{ + WMT_DETECT_PR_DBG("[WMT-DETECT]=>dump wmt pin configuration start<=\n"); + + WMT_DETECT_PR_INFO("LDO(GPIO%d), PMU(GPIO%d), PMUV28(GPIO%d)\n", + gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num, + gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num, + gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMUV28_EN_PIN].gpio_num); + + WMT_DETECT_PR_INFO("RST(GPIO%d), BGF_EINT(GPIO%d), BGF_EINT_NUM(%d)\n", + gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num, + gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_BGF_EINT_PIN].gpio_num, + gpio_to_irq(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_BGF_EINT_PIN].gpio_num)); + + WMT_DETECT_PR_INFO("WIFI_EINT(GPIO%d), WIFI_EINT_NUM(%d)\n", + gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num, + gpio_to_irq(gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num)); + + WMT_DETECT_PR_DBG("[WMT-PLAT]=>dump wmt pin configuration ends<=\n"); + + return 0; +} + +int _wmt_detect_output_low(unsigned int id) +{ + if (gpio_ctrl_info.gpio_ctrl_state[id].gpio_num != INVALID_PIN_ID) { + gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num, 0); + WMT_DETECT_PR_INFO("WMT-DETECT: set GPIO%d to output %d\n", + gpio_ctrl_info.gpio_ctrl_state[id].gpio_num-280, + gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num)); + } + + return 0; +} + +int _wmt_detect_output_high(unsigned int id) +{ + if (gpio_ctrl_info.gpio_ctrl_state[id].gpio_num != INVALID_PIN_ID) { + gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num, 1); + WMT_DETECT_PR_INFO("WMT-DETECT: set GPIO%d to output %d\n", + gpio_ctrl_info.gpio_ctrl_state[id].gpio_num-280, + gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num)); + } + + return 0; +} + +int _wmt_detect_read_gpio_input(unsigned int id) +{ + int retval = 0; + + if (gpio_ctrl_info.gpio_ctrl_state[id].gpio_num != INVALID_PIN_ID) { + retval = gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num); + WMT_DETECT_PR_DBG("WMT-DETECT: get GPIO%d val%d\n", + gpio_ctrl_info.gpio_ctrl_state[id].gpio_num, retval); + } else + WMT_DETECT_PR_ERR("WMT-DETECT: GPIO%d invalid\n", + gpio_ctrl_info.gpio_ctrl_state[id].gpio_num); + + return retval; +} + +/*This power on sequence must support all combo chip's basic power on sequence + * 1. LDO control is a must, if external LDO exist + * 2. PMU control is a must + * 3. RST control is a must + * 4. WIFI_EINT pin control is a must, used for GPIO mode for EINT status checkup + * 5. RTC32k clock control is a must + * + */ +static int wmt_detect_chip_pwr_on(void) +{ + int retval = -1; + + /*setting validiation check*/ + if ((gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num == INVALID_PIN_ID) || + (gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num == INVALID_PIN_ID)) { + WMT_DETECT_PR_ERR("WMT-DETECT: either PMU(%d) or WIFI_EINT(%d) is not set\n", + gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num, + gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num); + + return retval; + } + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num == INVALID_PIN_ID) { + WMT_DETECT_PR_WARN("WMT-DETECT: RST(%d) is not set, if it`s not 6632 project, please check it\n", + gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num); + + } + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_URXD_PIN].gpio_state[GPIO_PULL_DIS]) { + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, + gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_URXD_PIN]. + gpio_state[GPIO_PULL_DIS]); + } else + pr_err("wmt_gpio:set GPIO_COMBO_URXD_PIN to GPIO_PULL_DIS fail, is NULL!\n"); + + WMT_DETECT_PR_DBG("WMT-DETECT: GPIO_COMBO_URXD_PIN out 0\n"); + _wmt_detect_output_low(GPIO_COMBO_URXD_PIN); + + /*set LDO/PMU/RST to output 0, no pull*/ + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num != INVALID_PIN_ID) + _wmt_detect_output_low(GPIO_COMBO_LDO_EN_PIN); + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_state[GPIO_PULL_DIS]) { + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, + gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_state[GPIO_PULL_DIS]); + WMT_DETECT_PR_INFO("wmt_gpio:set GPIO_COMBO_PMU_EN_PIN to GPIO_PULL_DIS done!\n"); + } else + WMT_DETECT_PR_ERR("wmt_gpio:set GPIO_COMBO_PMU_EN_PIN to GPIO_PULL_DIS fail, is NULL!\n"); + _wmt_detect_output_low(GPIO_COMBO_PMU_EN_PIN); + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_state[GPIO_PULL_DIS]) { + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, + gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_state[GPIO_PULL_DIS]); + WMT_DETECT_PR_INFO("wmt_gpio:set GPIO_COMBO_RST_PIN to GPIO_PULL_DIS done!\n"); + } else + WMT_DETECT_PR_ERR("wmt_gpio:set GPIO_COMBO_RST_PIN to GPIO_PULL_DIS fail, is NULL!\n"); + _wmt_detect_output_low(GPIO_COMBO_RST_PIN); + +#if 0 + _wmt_detect_output_high(GPIO_WIFI_EINT_PIN); +#endif + + /*pull high LDO*/ + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num != INVALID_PIN_ID) + _wmt_detect_output_high(GPIO_COMBO_LDO_EN_PIN); + /*sleep for LDO stable time*/ + msleep(MAX_LDO_STABLE_TIME); + + /*export RTC clock, sleep for RTC stable time*/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0)) + rtc_gpio_enable_32k(RTC_GPIO_USER_GPS); +#endif + msleep(MAX_RTC_STABLE_TIME); + /*PMU output low, RST output low, to make chip power off completely*/ + /*always done*/ + /*sleep for power off stable time*/ + msleep(MAX_OFF_STABLE_TIME); + /*PMU output high, and sleep for reset stable time*/ + _wmt_detect_output_high(GPIO_COMBO_PMU_EN_PIN); +#ifdef CONFIG_MTK_COMBO_COMM_NPWR + if ((gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_I2S_DAT_PIN].gpio_num != INVALID_PIN_ID) && + (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAISYNC_PIN].gpio_num != INVALID_PIN_ID)) { + msleep(20); + _wmt_detect_output_high(GPIO_PCM_DAISYNC_PIN); + + msleep(20); + _wmt_detect_output_high(GPIO_COMBO_I2S_DAT_PIN); + + msleep(20); + _wmt_detect_output_low(GPIO_COMBO_I2S_DAT_PIN); + + msleep(20); + _wmt_detect_output_low(GPIO_PCM_DAISYNC_PIN); + + msleep(20); + } +#endif + msleep(MAX_RST_STABLE_TIME); + /*RST output high, and sleep for power on stable time */ + _wmt_detect_output_high(GPIO_COMBO_RST_PIN); + msleep(MAX_ON_STABLE_TIME); + retval = 0; + return retval; +} + +static int wmt_detect_chip_pwr_off(void) +{ + + /*set RST pin to input low status*/ + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num != INVALID_PIN_ID) + _wmt_detect_output_low(GPIO_COMBO_LDO_EN_PIN); + /*set RST pin to input low status*/ + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num != INVALID_PIN_ID) + _wmt_detect_output_low(GPIO_COMBO_RST_PIN); + /*set PMU pin to input low status*/ + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num != INVALID_PIN_ID) + _wmt_detect_output_low(GPIO_COMBO_PMU_EN_PIN); + return 0; +} + +int wmt_detect_read_ext_cmb_status(void) +{ + int retval = 0; + /*read WIFI_EINT pin status*/ + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num == INVALID_PIN_ID) { + retval = 0; + WMT_DETECT_PR_ERR("WMT-DETECT: no WIFI_EINT pin set\n"); + } else { + retval = _wmt_detect_read_gpio_input(GPIO_WIFI_EINT_PIN); + WMT_DETECT_PR_INFO("WMT-DETECT: WIFI_EINT input status:%d\n", retval); + } + return retval; +} + +int wmt_detect_chip_pwr_ctrl(int on) +{ + int retval = -1; + + if (on == 0) { + /*power off combo chip */ + retval = wmt_detect_chip_pwr_off(); + } else { + wmt_detect_dump_pin_conf(); + /*power on combo chip */ + retval = wmt_detect_chip_pwr_on(); + } + return retval; +} + +int wmt_detect_sdio_pwr_ctrl(int on) +{ + int retval = -1; +#ifdef MTK_WCN_COMBO_CHIP_SUPPORT + if (on == 0) { + /*power off SDIO slot */ + retval = board_sdio_ctrl(1, 0); + } else { + /*power on SDIO slot */ + retval = board_sdio_ctrl(1, 1); + } +#else + WMT_DETECT_PR_WARN("WMT-DETECT: MTK_WCN_COMBO_CHIP_SUPPORT is not set\n"); +#endif + return retval; +} diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.h b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.h new file mode 100644 index 0000000000000000000000000000000000000000..32e661520fd0d09ac92244c950258df291cf695e --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.h @@ -0,0 +1,29 @@ +/* +* Copyright (C) 2011-2014 MediaTek Inc. +* +* This program is free software: you can redistribute it and/or modify it under the terms of the +* GNU General Public License version 2 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. +* +* You should have received a copy of the GNU General Public License along with this program. +* If not, see . +*/ + +#ifndef __WMT_DETECT_PWR_H_ +#define __WMT_DETECT_PWR_H_ + +#define MAX_RTC_STABLE_TIME 100 +#define MAX_LDO_STABLE_TIME 100 +#define MAX_RST_STABLE_TIME 30 +#define MAX_OFF_STABLE_TIME 10 +#define MAX_ON_STABLE_TIME 30 + +extern int board_sdio_ctrl(unsigned int sdio_port_num, unsigned int on); +extern int wmt_detect_chip_pwr_ctrl(int on); +extern int wmt_detect_sdio_pwr_ctrl(int on); +extern int wmt_detect_read_ext_cmb_status(void); + +#endif diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.c b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.c new file mode 100644 index 0000000000000000000000000000000000000000..55a483895f8faae045b2dd7d3f1d210d30bc6b0d --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.c @@ -0,0 +1,496 @@ +/* +* Copyright (C) 2011-2014 MediaTek Inc. +* +* This program is free software: you can redistribute it and/or modify it under the terms of the +* GNU General Public License version 2 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. +* +* You should have received a copy of the GNU General Public License along with this program. +* If not, see . +*/ + +#include "wmt_gpio.h" +#if (LINUX_VERSION_CODE >> 8) == 0x40E +#include +#endif + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ +const PUINT8 gpio_state_name[GPIO_PIN_ID_MAX][GPIO_STATE_MAX] = {{"gpio_ldo_en_pull_dis", + "", + "", + "", + "", + "", + "", + "", + "gpio_ldo_en_in_pulldown", + ""}, + {"gpio_pmuv28_pull_dis", + "", + "", + "", + "", + "", + "", + "", + "gpio_pmuv28_in_pulldown", + ""}, + {"gpio_pmu_en_pull_dis", + "", + "", + "", + "", + "", + "", + "", + "gpio_pmu_en_in_pulldown", + ""}, + {"gpio_rst_pull_dis", + "", + "", + "", + "", + "", + "", + "", + "gpio_rst_in_pulldown", + ""}, + {"", + "", + "", + "", + "", + "", + "", + "gpio_bgf_eint_in_pull_dis", + "gpio_bgf_eint_in_pulldown", + "gpio_bgf_eint_in_pullup"}, + {"", + "", + "", + "", + "", + "", + "", + "gpio_wifi_eint_in_pull_dis", + "", + "gpio_wifi_eint_in_pullup"}, + {"", + "", + "", + "", + "", + "", + "", + "", + "gpio_all_eint_in_pulldown", + "gpio_all_eint_in_pullup"}, + {"gpio_urxd_uart_pull_dis", + "", + "", + "gpio_urxd_uart_out_low", + "", + "", + "", + "gpio_urxd_gpio_in_pull_dis", + "", + "gpio_urxd_gpio_in_pullup"}, + {"gpio_utxd_uart_pull_dis", + "", + "", + "", + "", + "", + "", + "", + "", + ""}, + {"gpio_pcm_daiclk_pull_dis", + "", + "", + "", + "", + "", + "", + "", + "", + ""}, + {"gpio_pcm_daipcmin_pull_dis", + "", + "", + "", + "", + "", + "", + "", + "", + ""}, + {"gpio_pcm_daipcmout_pull_dis", + "", + "", + "", + "", + "", + "", + "", + "", + ""}, + {"gpio_pcm_daisync_pull_dis", + "", + "", + "", + "", + "", + "", + "", + "", + ""}, + {"gpio_i2s_ck_pull_dis", + "", + "", + "", + "", + "", + "", + "", + "", + ""}, + {"gpio_i2s_ws_pull_dis", + "", + "", + "", + "", + "", + "", + "", + "", + ""}, + {"gpio_i2s_dat_pull_dis", + "", + "", + "", + "", + "", + "", + "", + "", + ""}, + {"gpio_gps_sync_pull_dis", + "", + "", + "", + "", + "", + "", + "", + "", + ""}, + {"gpio_gps_lna_pull_dis", + "", + "", + "", + "", + "", + "", + "", + "", + ""}, + {"", + "", + "", + "", + "", + "gpio_chip_deep_sleep_in_pull_dis", + "", + "", + "", + ""}, + {"", + "", + "gpio_chip_wake_up_pullup", + "", + "", + "", + "", + "", + "", + ""} +}; + +const PUINT8 gpio_pin_name[GPIO_PIN_ID_MAX] = {"gpio_combo_ldo_en_pin", + "gpio_combo_pmuv28_en_pin", + "gpio_combo_pmu_en_pin", + "gpio_combo_rst_pin", + "gpio_combo_bgf_eint_pin", + "gpio_wifi_eint_pin", + "gpio_all_eint_pin", + "gpio_combo_urxd_pin", + "gpio_combo_utxd_pin", + "gpio_pcm_daiclk_pin", + "gpio_pcm_daipcmin_pin", + "gpio_pcm_daipcmout_pin", + "gpio_pcm_daisync_pin", + "gpio_combo_i2s_ck_pin", + "gpio_combo_i2s_ws_pin", + "gpio_combo_i2s_dat_pin", + "gpio_gps_sync_pin", + "gpio_gps_lna_pin", + "gpio_chip_deep_sleep_pin", + "gpio_chip_wake_up_pin" + }; + +GPIO_CTRL_INFO gpio_ctrl_info; + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +int __weak mt_get_gpio_mode_base(unsigned long pin) +{ + return 0; +} + +int __weak mt_get_gpio_pull_select_base(unsigned long pin) +{ + return 0; +} + +int __weak mt_get_gpio_in_base(unsigned long pin) +{ + return 0; +} + +int __weak mt_get_gpio_out_base(unsigned long pin) +{ + return 0; +} + +int __weak mt_get_gpio_pull_enable_base(unsigned long pin) +{ + return 0; +} + +int __weak mt_get_gpio_dir_base(unsigned long pin) +{ + return 0; +} + +int __weak mt_get_gpio_ies_base(unsigned long pin) +{ + return 0; +} + +INT32 wmt_gpio_init(struct platform_device *pdev) +{ + INT32 iret = 0; + UINT32 i, j; + struct device_node *node; + + node = of_find_compatible_node(NULL, NULL, "mediatek,connectivity-combo"); + if (!node) { + for (i = 0; i < GPIO_PIN_ID_MAX; i++) + gpio_ctrl_info.gpio_ctrl_state[i].gpio_num = DEFAULT_PIN_ID; + pr_err("wmt_gpio:can't find device tree node!\n"); + iret = -1; + goto err; + } + + gpio_ctrl_info.pinctrl_info = devm_pinctrl_get(&pdev->dev); + if (gpio_ctrl_info.pinctrl_info) { + for (i = 0; i < GPIO_PIN_ID_MAX; i++) { + gpio_ctrl_info.gpio_ctrl_state[i].gpio_num = of_get_named_gpio(node, + gpio_pin_name[i], 0); + if (gpio_ctrl_info.gpio_ctrl_state[i].gpio_num < 0) + gpio_ctrl_info.gpio_ctrl_state[i].gpio_num = DEFAULT_PIN_ID; + if (gpio_ctrl_info.gpio_ctrl_state[i].gpio_num != DEFAULT_PIN_ID) { + for (j = 0; j < GPIO_STATE_MAX; j++) { + if (strlen(gpio_state_name[i][j]) != 0) { + gpio_ctrl_info.gpio_ctrl_state[i].gpio_state[j] = + pinctrl_lookup_state(gpio_ctrl_info.pinctrl_info, + gpio_state_name[i][j]); + } else + gpio_ctrl_info.gpio_ctrl_state[i].gpio_state[j] = NULL; + } + } else { + for (j = 0; j < GPIO_STATE_MAX; j++) + gpio_ctrl_info.gpio_ctrl_state[i].gpio_state[j] = NULL; + } + } + + pr_info("wmt_gpio: gpio init start!\n"); + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_URXD_PIN].gpio_state[GPIO_PULL_DIS]) { + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, + gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_URXD_PIN]. + gpio_state[GPIO_PULL_DIS]); + } else + pr_err("wmt_gpio:set GPIO_COMBO_URXD_PIN to GPIO_PULL_DIS fail, is NULL!\n"); + + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_UTXD_PIN].gpio_state[GPIO_PULL_DIS]) { + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, + gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_UTXD_PIN]. + gpio_state[GPIO_PULL_DIS]); + } else + pr_err("wmt_gpio:set GPIO_COMBO_UTXD_PIN to GPIO_PULL_DIS fail, is NULL!\n"); + + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_state[GPIO_PULL_DIS]) { + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, + gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN]. + gpio_state[GPIO_PULL_DIS]); + } else + pr_err("wmt_gpio:set GPIO_COMBO_PMU_EN_PIN to GPIO_PULL_DIS fail, is NULL!\n"); + + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num != DEFAULT_PIN_ID) { + gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num, + 0); + pr_err("wmt_gpio:set GPIO_COMBO_PMU_EN_PIN out to 0: %d!\n", + gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num)); + } + + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_state[GPIO_PULL_DIS]) { + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, + gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_state[GPIO_PULL_DIS]); + } else + pr_err("wmt_gpio:set GPIO_COMBO_RST_PIN to GPIO_PULL_DIS fail, is NULL!\n"); + + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num != DEFAULT_PIN_ID) { + gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num, + 0); + pr_err("wmt_gpio:set GPIO_COMBO_RST_PIN out to 0: %d!\n", + gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num)); + } + + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_state[GPIO_IN_PULLUP]) { + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, + gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_state[GPIO_IN_PULLUP]); + } else + pr_err("wmt_gpio:set GPIO_WIFI_EINT_PIN to GPIO_IN_PULLUP fail, is NULL!\n"); + + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAICLK_PIN].gpio_state[GPIO_PULL_DIS]) { + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, + gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAICLK_PIN].gpio_state[GPIO_PULL_DIS]); + } else + pr_err("wmt_gpio:set GPIO_PCM_DAICLK_PIN to GPIO_PULL_DIS fail, is NULL!\n"); + + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAIPCMIN_PIN].gpio_state[GPIO_PULL_DIS]) { + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, + gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAIPCMIN_PIN]. + gpio_state[GPIO_PULL_DIS]); + } else + pr_err("wmt_gpio:set GPIO_PCM_DAIPCMIN_PIN to GPIO_PULL_DIS fail, is NULL!\n"); + + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAIPCMOUT_PIN].gpio_state[GPIO_PULL_DIS]) { + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, + gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAIPCMOUT_PIN]. + gpio_state[GPIO_PULL_DIS]); + } else + pr_err("wmt_gpio:set GPIO_PCM_DAIPCMOUT_PIN to GPIO_PULL_DIS fail, is NULL!\n"); + + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAISYNC_PIN].gpio_state[GPIO_PULL_DIS]) { + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, + gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAISYNC_PIN]. + gpio_state[GPIO_PULL_DIS]); + } else + pr_err("wmt_gpio:set GPIO_PCM_DAISYNC_PIN to GPIO_PULL_DIS fail, is NULL!\n"); + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_CHIP_DEEP_SLEEP_PIN].gpio_state[GPIO_IN_DIS]) { + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, + gpio_ctrl_info.gpio_ctrl_state[GPIO_CHIP_DEEP_SLEEP_PIN]. + gpio_state[GPIO_IN_DIS]); + } else + pr_warn("wmt_gpio:it may not be 6632 project, GPIO_CHIP_DEEP_SLEEP_PIN no need config!\n"); + + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_CHIP_WAKE_UP_PIN].gpio_state[GPIO_PULL_UP]) { + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, + gpio_ctrl_info.gpio_ctrl_state[GPIO_CHIP_WAKE_UP_PIN]. + gpio_state[GPIO_PULL_UP]); + } else + pr_warn("wmt_gpio:it may not be 6632 project, GPIO_CHIP_WAKE_UP_PIN no need config!\n"); + + pr_info("wmt_gpio: gpio init done!\n"); + } else { + pr_err("wmt_gpio:can't find pinctrl dev!\n"); + iret = -1; + } + +#if (LINUX_VERSION_CODE >> 8) == 0x40E + KERNEL_mtk_wcn_cmb_sdio_request_eirq(); +#endif +err: + return iret; +} + +INT32 wmt_gpio_deinit(VOID) +{ + INT32 iret = 0; + UINT32 i; + UINT32 j; + + for (i = 0; i < GPIO_PIN_ID_MAX; i++) { + gpio_ctrl_info.gpio_ctrl_state[i].gpio_num = DEFAULT_PIN_ID; + if (gpio_ctrl_info.gpio_ctrl_state[i].gpio_num != DEFAULT_PIN_ID) { + for (j = 0; j < GPIO_STATE_MAX; j++) { + if (strlen(gpio_state_name[i][j]) != 0) + gpio_ctrl_info.gpio_ctrl_state[i].gpio_state[j] = NULL; + } + } + } + if (gpio_ctrl_info.pinctrl_info) { + devm_pinctrl_put(gpio_ctrl_info.pinctrl_info); + gpio_ctrl_info.pinctrl_info = NULL; + } + + return iret; +} + +VOID _wmt_dump_gpio_regs(INT32 idx) +{ + ULONG idxl = (ULONG)idx; + + pr_info("PIN: [MODE] [PULL_SEL] [DIN] [DOUT] [PULL EN] [DIR] [IES]\n"); + pr_info("idx = %3d: %d %d %d %d %d %d %d\n", + idx, mt_get_gpio_mode_base(idxl), + mt_get_gpio_pull_select_base(idxl), + mt_get_gpio_in_base(idxl), + mt_get_gpio_out_base(idxl), + mt_get_gpio_pull_enable_base(idxl), + mt_get_gpio_dir_base(idxl), + mt_get_gpio_ies_base(idxl)); +} + +VOID _wmt_gpio_pre_regs(INT32 num, WMT_GPIO_STATE_INFO *gpio_state) +{ + gpio_state->gpio_num = num; + gpio_state->mode = mt_get_gpio_mode_base(num); + gpio_state->pull_sel = mt_get_gpio_pull_select_base(num); + gpio_state->in = mt_get_gpio_in_base(num); + gpio_state->out = mt_get_gpio_out_base(num); + gpio_state->pull_en = mt_get_gpio_pull_enable_base(num); + gpio_state->dir = mt_get_gpio_dir_base(num); + gpio_state->ies = mt_get_gpio_ies_base(num); + +} + +VOID _wmt_dump_gpio_pre_regs(WMT_GPIO_STATE_INFO gpio_state) +{ + pr_info("PIN: [MODE] [PULL_SEL] [DIN] [DOUT] [PULL EN] [DIR] [IES]\n"); + pr_info("idx = %3d: %d %d %d %d %d %d %d\n", + gpio_state.gpio_num, gpio_state.mode, + gpio_state.pull_sel, gpio_state.in, + gpio_state.out, gpio_state.pull_en, + gpio_state.dir, gpio_state.ies); +} diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.h b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..4e42dba212a15ef16b6a2a4fec379e3100f60fec --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.h @@ -0,0 +1,127 @@ +/* +* Copyright (C) 2011-2014 MediaTek Inc. +* +* This program is free software: you can redistribute it and/or modify it under the terms of the +* GNU General Public License version 2 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. +* +* You should have received a copy of the GNU General Public License along with this program. +* If not, see . +*/ + +#ifndef _WMT_GPIO_H_ +#define _WMT_GPIO_H_ + +#include +#include +#include +#include +#include +#include +#include "osal.h" + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +#define DEFAULT_PIN_ID (0xffffffff) + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ +typedef enum _ENUM_GPIO_PIN_ID { + GPIO_COMBO_LDO_EN_PIN = 0, + GPIO_COMBO_PMUV28_EN_PIN, + GPIO_COMBO_PMU_EN_PIN, + GPIO_COMBO_RST_PIN, + GPIO_COMBO_BGF_EINT_PIN, + GPIO_WIFI_EINT_PIN, + GPIO_COMBO_ALL_EINT_PIN, + GPIO_COMBO_URXD_PIN, + GPIO_COMBO_UTXD_PIN, + GPIO_PCM_DAICLK_PIN, + GPIO_PCM_DAIPCMIN_PIN, + GPIO_PCM_DAIPCMOUT_PIN, + GPIO_PCM_DAISYNC_PIN, + GPIO_COMBO_I2S_CK_PIN, + GPIO_COMBO_I2S_WS_PIN, + GPIO_COMBO_I2S_DAT_PIN, + GPIO_GPS_SYNC_PIN, + GPIO_GPS_LNA_PIN, + GPIO_CHIP_DEEP_SLEEP_PIN, + GPIO_CHIP_WAKE_UP_PIN, + GPIO_PIN_ID_MAX +} ENUM_GPIO_PIN_ID, *P_ENUM_GPIO_PIN_ID; + +typedef enum _ENUM_GPIO_STATE_ID { + GPIO_PULL_DIS = 0, + GPIO_PULL_DOWN, + GPIO_PULL_UP, + GPIO_OUT_LOW, + GPIO_OUT_HIGH, + GPIO_IN_DIS, + GPIO_IN_EN, + GPIO_IN_PULL_DIS, + GPIO_IN_PULLDOWN, + GPIO_IN_PULLUP, + GPIO_STATE_MAX, +} ENUM_GPIO_STATE_ID, *P_ENUM_GPIO_STATE_ID; + +typedef struct _GPIO_CTRL_STATE { + INT32 gpio_num; + struct pinctrl_state *gpio_state[GPIO_STATE_MAX]; +} GPIO_CTRL_STATE, *P_GPIO_CTRL_STATE; + +typedef struct _WMT_GPIO_STATE_INFO { + INT32 gpio_num; + INT32 mode; + INT32 pull_sel; + INT32 in; + INT32 out; + INT32 pull_en; + INT32 dir; + INT32 ies; +} WMT_GPIO_STATE_INFO; + +typedef struct _GPIO_CTRL_INFO { + struct pinctrl *pinctrl_info; + GPIO_CTRL_STATE gpio_ctrl_state[GPIO_PIN_ID_MAX]; +} GPIO_CTRL_INFO, *P_GPIO_CTRL_INFO; + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +extern const PUINT8 gpio_state_name[GPIO_PIN_ID_MAX][GPIO_STATE_MAX]; +extern const PUINT8 gpio_pin_name[GPIO_PIN_ID_MAX]; +extern GPIO_CTRL_INFO gpio_ctrl_info; + +extern int mt_get_gpio_mode_base(unsigned long pin); +extern int mt_get_gpio_pull_select_base(unsigned long pin); +extern int mt_get_gpio_in_base(unsigned long pin); +extern int mt_get_gpio_out_base(unsigned long pin); +extern int mt_get_gpio_pull_enable_base(unsigned long pin); +extern int mt_get_gpio_dir_base(unsigned long pin); +extern int mt_get_gpio_ies_base(unsigned long pin); + + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +INT32 wmt_gpio_init(struct platform_device *pdev); +VOID _wmt_dump_gpio_regs(INT32 idx); +VOID _wmt_gpio_pre_regs(INT32 num, WMT_GPIO_STATE_INFO *gpio_state); +VOID _wmt_dump_gpio_pre_regs(WMT_GPIO_STATE_INFO gpio_state); +INT32 wmt_gpio_deinit(VOID); + +#endif diff --git a/drivers/misc/mediatek/connectivity/common/common_main/core/btm_core.c b/drivers/misc/mediatek/connectivity/common/common_main/core/btm_core.c new file mode 100644 index 0000000000000000000000000000000000000000..162fb765bf0248b3cca911ecf56ac19cff16f619 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/core/btm_core.c @@ -0,0 +1,779 @@ +/* +* Copyright (C) 2011-2014 MediaTek Inc. +* +* This program is free software: you can redistribute it and/or modify it under the terms of the +* GNU General Public License version 2 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. +* +* You should have received a copy of the GNU General Public License along with this program. +* If not, see . +*/ + +#include +#include "osal_typedef.h" +#include "osal.h" +#include "stp_dbg.h" +#include "stp_core.h" +#include "btm_core.h" +#include "wmt_plat.h" +#include "wmt_step.h" +#include "wmt_detect.h" +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH +#include "connsys_debug_utility.h" +#endif +#include + +#define PFX_BTM "[STP-BTM] " +#define STP_BTM_LOG_LOUD 4 +#define STP_BTM_LOG_DBG 3 +#define STP_BTM_LOG_INFO 2 +#define STP_BTM_LOG_WARN 1 +#define STP_BTM_LOG_ERR 0 + +INT32 gBtmDbgLevel = STP_BTM_LOG_INFO; + +#define STP_BTM_PR_LOUD(fmt, arg...) \ +do { \ + if (gBtmDbgLevel >= STP_BTM_LOG_LOUD) \ + pr_info(PFX_BTM "%s: " fmt, __func__, ##arg); \ +} while (0) +#define STP_BTM_PR_DBG(fmt, arg...) \ +do { \ + if (gBtmDbgLevel >= STP_BTM_LOG_DBG) \ + pr_info(PFX_BTM "%s: " fmt, __func__, ##arg); \ +} while (0) +#define STP_BTM_PR_INFO(fmt, arg...) \ +do { \ + if (gBtmDbgLevel >= STP_BTM_LOG_INFO) \ + pr_info(PFX_BTM "[I]%s: " fmt, __func__, ##arg); \ +} while (0) +#define STP_BTM_PR_WARN(fmt, arg...) \ +do { \ + if (gBtmDbgLevel >= STP_BTM_LOG_WARN) \ + pr_warn(PFX_BTM "[W]%s: " fmt, __func__, ##arg); \ +} while (0) +#define STP_BTM_PR_ERR(fmt, arg...) \ +do { \ + if (gBtmDbgLevel >= STP_BTM_LOG_ERR) \ + pr_err(PFX_BTM "[E]%s(%d):ERROR! " fmt, __func__, __LINE__, ##arg); \ +} while (0) + +#define ASSERT(expr) + +MTKSTP_BTM_T stp_btm_i; +MTKSTP_BTM_T *stp_btm = &stp_btm_i; + +const PINT8 g_btm_op_name[] = { + [0x0] = "STP_OPID_BTM_RETRY", + [0x1] = "STP_OPID_BTM_RST", + [0x2] = "STP_OPID_BTM_DBG_DUMP", + [0x3] = "STP_OPID_BTM_DUMP_TIMEOUT", + [0x4] = "STP_OPID_BTM_POLL_CPUPCR", + [0x5] = "STP_OPID_BTM_PAGED_DUMP", + [0x6] = "STP_OPID_BTM_FULL_DUMP", + [0x7] = "STP_OPID_BTM_PAGED_TRACE", + [0x8] = "STP_OPID_BTM_FORCE_FW_ASSERT", +#if CFG_WMT_LTE_COEX_HANDLING + [0x9] = "STP_OPID_BTM_WMT_LTE_COEX", +#endif + [0xa] = "STP_OPID_BTM_ASSERT_TIMEOUT", + [0xb] = "STP_OPID_BTM_EMI_DUMP_END", + [0xc] = "STP_OPID_BTM_EXIT" +}; + +static VOID stp_btm_trigger_assert_timeout_handler(timer_handler_arg arg) +{ + ULONG data; + + GET_HANDLER_DATA(arg, data); + if (mtk_wcn_stp_coredump_start_get() == 0) + stp_btm_notify_assert_timeout_wq((MTKSTP_BTM_T *)data); +} + +static INT32 _stp_btm_handler(MTKSTP_BTM_T *stp_btm, P_STP_BTM_OP pStpOp) +{ + INT32 ret = -1; + /* core dump target, 0: aee; 1: netlink */ + INT32 dump_sink = mtk_wcn_stp_coredump_flag_get(); + + if (pStpOp == NULL) + return -1; + + switch (pStpOp->opId) { + case STP_OPID_BTM_EXIT: + /* TODO: clean all up? */ + ret = 0; + break; + + /*tx timeout retry */ + case STP_OPID_BTM_RETRY: + if (mtk_wcn_stp_coredump_start_get() == 0) + stp_do_tx_timeout(); + ret = 0; + break; + + /*whole chip reset */ + case STP_OPID_BTM_RST: + STP_BTM_PR_INFO("whole chip reset start!\n"); + if (wmt_detect_get_chip_type() == WMT_CHIP_TYPE_SOC && + mtk_wcn_stp_coredump_flag_get() != 0 && chip_reset_only == 0) { +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH + connsys_dedicated_log_flush_emi(); +#endif + stp_dbg_core_dump_flush(0, MTK_WCN_BOOL_FALSE); + } + STP_BTM_PR_INFO("....+\n"); + WMT_STEP_DO_ACTIONS_FUNC(STEP_TRIGGER_POINT_BEFORE_CHIP_RESET); + if (stp_btm->wmt_notify) { + stp_btm->wmt_notify(BTM_RST_OP); + ret = 0; + } else { + STP_BTM_PR_ERR("stp_btm->wmt_notify is NULL."); + ret = -1; + } + + STP_BTM_PR_INFO("whole chip reset end!\n"); + WMT_STEP_DO_ACTIONS_FUNC(STEP_TRIGGER_POINT_AFTER_CHIP_RESET); + break; + + case STP_OPID_BTM_DBG_DUMP: + /*Notify the wmt to get dump data */ + STP_BTM_PR_DBG("wmt dmp notification\n"); + set_user_nice(stp_btm->BTMd.pThread, -20); + ret = stp_dbg_core_dump(dump_sink); + set_user_nice(stp_btm->BTMd.pThread, 0); + break; + + case STP_OPID_BTM_DUMP_TIMEOUT: + /* append fake coredump end message */ + if (dump_sink == 2 && wmt_detect_get_chip_type() == WMT_CHIP_TYPE_COMBO) { + stp_dbg_set_coredump_timer_state(CORE_DUMP_DOING); + STP_BTM_PR_WARN("generate fake coredump message\n"); + stp_dbg_nl_send_data(FAKECOREDUMPEND, osal_sizeof(FAKECOREDUMPEND)); + } + stp_dbg_poll_cpupcr(5, 1, 1); + if (wmt_detect_get_chip_type() == WMT_CHIP_TYPE_COMBO) { + /* Flush dump data, and reset compressor */ + STP_BTM_PR_INFO("Flush dump data\n"); + stp_dbg_core_dump_flush(0, MTK_WCN_BOOL_TRUE); + } + ret = mtk_wcn_stp_coredump_timeout_handle(); + break; +#if CFG_WMT_LTE_COEX_HANDLING + case STP_OPID_BTM_WMT_LTE_COEX: + ret = wmt_idc_msg_to_lte_handing(); + break; +#endif + case STP_OPID_BTM_ASSERT_TIMEOUT: + mtk_wcn_stp_assert_timeout_handle(); + ret = 0; + break; + case STP_OPID_BTM_EMI_DUMP_END: + STP_BTM_PR_INFO("emi dump end notification.\n"); + stp_dbg_stop_emi_dump(); + mtk_wcn_stp_ctx_restore(); + ret = 0; + break; + default: + ret = -1; + break; + } + + return ret; +} + +static P_OSAL_OP _stp_btm_get_op(MTKSTP_BTM_T *stp_btm, P_OSAL_OP_Q pOpQ) +{ + P_OSAL_OP pOp; + /* INT32 ret = 0; */ + + if (!pOpQ) { + STP_BTM_PR_WARN("!pOpQ\n"); + return NULL; + } + + osal_lock_unsleepable_lock(&(stp_btm->wq_spinlock)); + /* acquire lock success */ + RB_GET(pOpQ, pOp); + osal_unlock_unsleepable_lock(&(stp_btm->wq_spinlock)); + + if (!pOp) + STP_BTM_PR_DBG("RB_GET fail\n"); + return pOp; +} + +static INT32 _stp_btm_put_op(MTKSTP_BTM_T *stp_btm, P_OSAL_OP_Q pOpQ, P_OSAL_OP pOp) +{ + INT32 ret; + P_OSAL_OP pOp_latest = NULL; + P_OSAL_OP pOp_current = NULL; + INT32 flag_latest = 1; + INT32 flag_current = 1; + + if (!pOpQ || !pOp) { + STP_BTM_PR_WARN("invalid input param: 0x%p, 0x%p\n", pOpQ, pOp); + return 0; /* ;MTK_WCN_BOOL_FALSE; */ + } + ret = 0; + + osal_lock_unsleepable_lock(&(stp_btm->wq_spinlock)); + /* acquire lock success */ + if (&stp_btm->rFreeOpQ == pOpQ) { + if (!RB_FULL(pOpQ)) + RB_PUT(pOpQ, pOp); + else + ret = -1; + } else if (pOp->op.opId == STP_OPID_BTM_RST || + pOp->op.opId == STP_OPID_BTM_ASSERT_TIMEOUT || + pOp->op.opId == STP_OPID_BTM_DUMP_TIMEOUT || + pOp->op.opId == STP_OPID_BTM_EMI_DUMP_END) { + if (!RB_FULL(pOpQ)) { + RB_PUT(pOpQ, pOp); + STP_BTM_PR_DBG("RB_PUT: 0x%x\n", pOp->op.opId); + } else + ret = -1; + } else { + pOp_current = stp_btm_get_current_op(stp_btm); + if (pOp_current) { + if (pOp_current->op.opId == STP_OPID_BTM_RST || + pOp_current->op.opId == STP_OPID_BTM_DUMP_TIMEOUT || + (pOp_current->op.opId == STP_OPID_BTM_ASSERT_TIMEOUT && + pOp->op.opId != STP_OPID_BTM_DBG_DUMP)) { + STP_BTM_PR_DBG("current: 0x%x\n", pOp_current->op.opId); + flag_current = 0; + } + } + + RB_GET_LATEST(pOpQ, pOp_latest); + if (pOp_latest) { + if (pOp_latest->op.opId == STP_OPID_BTM_RST || + pOp_latest->op.opId == STP_OPID_BTM_ASSERT_TIMEOUT || + pOp_latest->op.opId == STP_OPID_BTM_DUMP_TIMEOUT) { + STP_BTM_PR_DBG("latest: 0x%x\n", pOp_latest->op.opId); + flag_latest = 0; + } + if (pOp_latest->op.opId == pOp->op.opId +#if CFG_WMT_LTE_COEX_HANDLING + && pOp->op.opId != STP_OPID_BTM_WMT_LTE_COEX +#endif + ) { + flag_latest = 0; + STP_BTM_PR_DBG("With the latest a command repeat: latest 0x%x,current 0x%x\n", + pOp_latest->op.opId, pOp->op.opId); + } + } + if (flag_current && flag_latest) { + if (!RB_FULL(pOpQ)) { + RB_PUT(pOpQ, pOp); + STP_BTM_PR_DBG("RB_PUT: 0x%x\n", pOp->op.opId); + } else + ret = -1; + } else + ret = 0; + + } + + if (ret) { + STP_BTM_PR_DBG("RB_FULL(0x%p) %d ,rFreeOpQ = %p, rActiveOpQ = %p\n", + pOpQ, RB_COUNT(pOpQ), &stp_btm->rFreeOpQ, &stp_btm->rActiveOpQ); + osal_opq_dump_locked("FreeOpQ", &stp_btm->rFreeOpQ); + osal_opq_dump_locked("ActiveOpQ", &stp_btm->rActiveOpQ); + } + + osal_unlock_unsleepable_lock(&(stp_btm->wq_spinlock)); + return ret ? 0 : 1; +} + +P_OSAL_OP _stp_btm_get_free_op(MTKSTP_BTM_T *stp_btm) +{ + P_OSAL_OP pOp; + + if (stp_btm) { + pOp = _stp_btm_get_op(stp_btm, &stp_btm->rFreeOpQ); + if (pOp) { + osal_memset(pOp, 0, osal_sizeof(OSAL_OP)); + } + + return pOp; + } else + return NULL; +} + +INT32 _stp_btm_put_act_op(MTKSTP_BTM_T *stp_btm, P_OSAL_OP pOp) +{ + INT32 bRet = 0; + INT32 wait_ret = -1; + + P_OSAL_SIGNAL pSignal = NULL; + + if (!stp_btm || !pOp) { + STP_BTM_PR_ERR("Input NULL pointer\n"); + return bRet; + } + do { + pSignal = &pOp->signal; + + if (pSignal->timeoutValue) { + pOp->result = -9; + osal_signal_init(&pOp->signal); + } + + /* Init ref_count to 2, as one is held by current thread, the second by btm thread */ + atomic_set(&pOp->ref_count, 2); + + /* put to active Q */ + bRet = _stp_btm_put_op(stp_btm, &stp_btm->rActiveOpQ, pOp); + if (bRet == 0) { + STP_BTM_PR_DBG("put active queue fail\n"); + atomic_dec(&pOp->ref_count); + break; + } + /* wake up wmtd */ + osal_trigger_event(&stp_btm->STPd_event); + + if (pSignal->timeoutValue == 0) { + bRet = 1; /* MTK_WCN_BOOL_TRUE; */ + break; + } + + /* check result */ + wait_ret = osal_wait_for_signal_timeout(&pOp->signal, &stp_btm->BTMd); + + STP_BTM_PR_DBG("wait completion:%d\n", wait_ret); + if (!wait_ret) { + STP_BTM_PR_ERR("wait completion timeout\n"); + /* TODO: how to handle it? retry? */ + } else { + if (pOp->result) + STP_BTM_PR_WARN("op(%d) result:%d\n", pOp->op.opId, pOp->result); + bRet = (pOp->result) ? 0 : 1; + } + } while (0); + + if (pOp && atomic_dec_and_test(&pOp->ref_count)) { + /* put Op back to freeQ */ + _stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, pOp); + } + + return bRet; +} + +static INT32 _stp_btm_wait_for_msg(PVOID pvData) +{ + MTKSTP_BTM_T *stp_btm = (MTKSTP_BTM_T *) pvData; + + return (!RB_EMPTY(&stp_btm->rActiveOpQ)) || osal_thread_should_stop(&stp_btm->BTMd); +} + +static INT32 _stp_btm_proc(PVOID pvData) +{ + MTKSTP_BTM_T *stp_btm = (MTKSTP_BTM_T *) pvData; + P_OSAL_OP pOp; + INT32 id; + INT32 result; + + if (!stp_btm) { + STP_BTM_PR_WARN("!stp_btm\n"); + return -1; + } + + for (;;) { + pOp = NULL; + + osal_wait_for_event(&stp_btm->STPd_event, _stp_btm_wait_for_msg, (PVOID) stp_btm); + + if (osal_thread_should_stop(&stp_btm->BTMd)) { + STP_BTM_PR_INFO("should stop now...\n"); + /* TODO: clean up active opQ */ + break; + } + + if (stp_btm->gDumplogflag) { + /* pr_warn("enter place1\n"); */ + stp_btm->gDumplogflag = 0; + continue; + } + + /* get Op from activeQ */ + pOp = _stp_btm_get_op(stp_btm, &stp_btm->rActiveOpQ); + + if (!pOp) { + STP_BTM_PR_WARN("get_lxop activeQ fail\n"); + continue; + } + osal_op_history_save(&stp_btm->op_history, pOp); + + id = osal_op_get_id(pOp); + + if ((id >= STP_OPID_BTM_NUM) || (id < 0)) { + STP_BTM_PR_WARN("abnormal opid id: 0x%x\n", id); + result = -1; + goto handler_done; + } + + STP_BTM_PR_DBG("======> lxop_get_opid = %d, %s, remaining count = *%d*\n", id, + g_btm_op_name[id], RB_COUNT(&stp_btm->rActiveOpQ)); + + osal_lock_unsleepable_lock(&(stp_btm->wq_spinlock)); + stp_btm_set_current_op(stp_btm, pOp); + osal_unlock_unsleepable_lock(&(stp_btm->wq_spinlock)); + result = _stp_btm_handler(stp_btm, &pOp->op); + osal_lock_unsleepable_lock(&(stp_btm->wq_spinlock)); + stp_btm_set_current_op(stp_btm, NULL); + osal_unlock_unsleepable_lock(&(stp_btm->wq_spinlock)); + + if (result) { + STP_BTM_PR_WARN("opid id(0x%x)(%s) error(%d)\n", id, + g_btm_op_name[id], result); + } + +handler_done: + + if (atomic_dec_and_test(&pOp->ref_count)) { + _stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, pOp); + } else if (osal_op_is_wait_for_signal(pOp)) { + osal_op_raise_signal(pOp, result); + } + + if (id == STP_OPID_BTM_EXIT) { + break; + } else if (id == STP_OPID_BTM_RST) { + /* prevent multi reset case */ + stp_btm_reset_btm_wq(stp_btm); + } + } + + STP_BTM_PR_INFO("exits\n"); + + return 0; +} + +static inline INT32 _stp_btm_dump_type(MTKSTP_BTM_T *stp_btm, ENUM_STP_BTM_OPID_T opid) +{ + P_OSAL_OP pOp; + INT32 bRet; + INT32 retval; + + pOp = _stp_btm_get_free_op(stp_btm); + if (!pOp) { + STP_BTM_PR_WARN("get_free_lxop fail\n"); + return -1; /* break; */ + } + + pOp->op.opId = opid; + pOp->signal.timeoutValue = 0; + bRet = _stp_btm_put_act_op(stp_btm, pOp); + STP_BTM_PR_DBG("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); + retval = (bRet == 0) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS; + + return retval; +} + +static inline INT32 _stp_btm_notify_wmt_rst_wq(MTKSTP_BTM_T *stp_btm) +{ + INT32 retval; + + if (stp_btm == NULL) + return STP_BTM_OPERATION_FAIL; + + retval = _stp_btm_dump_type(stp_btm, STP_OPID_BTM_RST); + return retval; +} + +static inline INT32 _stp_btm_notify_stp_retry_wq(MTKSTP_BTM_T *stp_btm) +{ + INT32 retval; + + if (stp_btm == NULL) + return STP_BTM_OPERATION_FAIL; + + retval = _stp_btm_dump_type(stp_btm, STP_OPID_BTM_RETRY); + return retval; +} + + +static inline INT32 _stp_btm_notify_coredump_timeout_wq(MTKSTP_BTM_T *stp_btm) +{ + INT32 retval; + + if (!stp_btm) + return STP_BTM_OPERATION_FAIL; + + stp_btm_reset_btm_wq(stp_btm); + retval = _stp_btm_dump_type(stp_btm, STP_OPID_BTM_DUMP_TIMEOUT); + return retval; +} + +static inline INT32 _stp_btm_notify_assert_timeout_wq(MTKSTP_BTM_T *stp_btm) +{ + INT32 retval; + + if (!stp_btm) + return STP_BTM_OPERATION_FAIL; + + retval = _stp_btm_dump_type(stp_btm, STP_OPID_BTM_ASSERT_TIMEOUT); + return retval; +} + +static inline INT32 _stp_btm_notify_wmt_dmp_wq(MTKSTP_BTM_T *stp_btm) +{ + + INT32 retval; + + if (stp_btm == NULL) + return STP_BTM_OPERATION_FAIL; + + /* Paged dump */ + retval = _stp_btm_dump_type(stp_btm, STP_OPID_BTM_DBG_DUMP); + + return retval; +} + +static inline INT32 _stp_btm_notify_emi_dump_end_wq(MTKSTP_BTM_T *stp_btm) +{ + INT32 retval; + + if (!stp_btm) + return STP_BTM_OPERATION_FAIL; + + retval = _stp_btm_dump_type(stp_btm, STP_OPID_BTM_EMI_DUMP_END); + return retval; +} + +INT32 stp_btm_notify_wmt_rst_wq(MTKSTP_BTM_T *stp_btm) +{ + return _stp_btm_notify_wmt_rst_wq(stp_btm); +} + +INT32 stp_btm_notify_stp_retry_wq(MTKSTP_BTM_T *stp_btm) +{ + return _stp_btm_notify_stp_retry_wq(stp_btm); +} + +INT32 stp_btm_notify_coredump_timeout_wq(MTKSTP_BTM_T *stp_btm) +{ + return _stp_btm_notify_coredump_timeout_wq(stp_btm); +} + +INT32 stp_btm_notify_assert_timeout_wq(MTKSTP_BTM_T *stp_btm) +{ + return _stp_btm_notify_assert_timeout_wq(stp_btm); +} + +INT32 stp_btm_notify_wmt_dmp_wq(MTKSTP_BTM_T *stp_btm) +{ + return _stp_btm_notify_wmt_dmp_wq(stp_btm); +} + +INT32 stp_btm_notify_emi_dump_end(MTKSTP_BTM_T *stp_btm) +{ + return _stp_btm_notify_emi_dump_end_wq(stp_btm); +} + +INT32 stp_notify_btm_poll_cpupcr_ctrl(UINT32 en) +{ + return stp_dbg_poll_cpupcr_ctrl(en); +} + + +#if CFG_WMT_LTE_COEX_HANDLING + +static inline INT32 _stp_notify_btm_handle_wmt_lte_coex(MTKSTP_BTM_T *stp_btm) +{ + INT32 retval; + + if (stp_btm == NULL) + return STP_BTM_OPERATION_FAIL; + + retval = _stp_btm_dump_type(stp_btm, STP_OPID_BTM_WMT_LTE_COEX); + return retval; +} + +INT32 stp_notify_btm_handle_wmt_lte_coex(MTKSTP_BTM_T *stp_btm) +{ + return _stp_notify_btm_handle_wmt_lte_coex(stp_btm); +} + +#endif +MTKSTP_BTM_T *stp_btm_init(VOID) +{ + INT32 i = 0x0; + INT32 ret = -1; + + osal_unsleepable_lock_init(&stp_btm->wq_spinlock); + osal_event_init(&stp_btm->STPd_event); + stp_btm->wmt_notify = wmt_lib_btm_cb; + + RB_INIT(&stp_btm->rFreeOpQ, STP_BTM_OP_BUF_SIZE); + RB_INIT(&stp_btm->rActiveOpQ, STP_BTM_OP_BUF_SIZE); + + /* Put all to free Q */ + for (i = 0; i < STP_BTM_OP_BUF_SIZE; i++) { + osal_signal_init(&(stp_btm->arQue[i].signal)); + _stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, &(stp_btm->arQue[i])); + } + + stp_btm_init_trigger_assert_timer(stp_btm); + osal_op_history_init(&stp_btm->op_history, 16); + + /*Generate PSM thread, to servie STP-CORE for packet retrying and core dump receiving */ + stp_btm->BTMd.pThreadData = (PVOID) stp_btm; + stp_btm->BTMd.pThreadFunc = (PVOID) _stp_btm_proc; + osal_memcpy(stp_btm->BTMd.threadName, BTM_THREAD_NAME, osal_strlen(BTM_THREAD_NAME)); + + ret = osal_thread_create(&stp_btm->BTMd); + if (ret < 0) { + STP_BTM_PR_ERR("osal_thread_create fail...\n"); + goto ERR_EXIT1; + } + + /* Start STPd thread */ + ret = osal_thread_run(&stp_btm->BTMd); + if (ret < 0) { + STP_BTM_PR_ERR("osal_thread_run FAILS\n"); + goto ERR_EXIT1; + } + + return stp_btm; + +ERR_EXIT1: + + return NULL; + +} + +INT32 stp_btm_deinit(MTKSTP_BTM_T *stp_btm) +{ + + INT32 ret = -1; + + STP_BTM_PR_INFO("btm deinit\n"); + + if (!stp_btm) + return STP_BTM_OPERATION_FAIL; + + ret = osal_thread_destroy(&stp_btm->BTMd); + if (ret < 0) { + STP_BTM_PR_ERR("osal_thread_destroy FAILS\n"); + return STP_BTM_OPERATION_FAIL; + } + + return STP_BTM_OPERATION_SUCCESS; +} + + +INT32 stp_btm_reset_btm_wq(MTKSTP_BTM_T *stp_btm) +{ + UINT32 i = 0; + + osal_lock_unsleepable_lock(&(stp_btm->wq_spinlock)); + RB_INIT(&stp_btm->rFreeOpQ, STP_BTM_OP_BUF_SIZE); + RB_INIT(&stp_btm->rActiveOpQ, STP_BTM_OP_BUF_SIZE); + osal_unlock_unsleepable_lock(&(stp_btm->wq_spinlock)); + /* Put all to free Q */ + for (i = 0; i < STP_BTM_OP_BUF_SIZE; i++) { + osal_signal_init(&(stp_btm->arQue[i].signal)); + _stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, &(stp_btm->arQue[i])); + } + + return 0; +} + + +INT32 stp_notify_btm_dump(MTKSTP_BTM_T *stp_btm) +{ + /* pr_warn("%s:enter++\n",__func__); */ + if (stp_btm == NULL) { + osal_dbg_print("%s: NULL POINTER\n", __func__); + return -1; + } + stp_btm->gDumplogflag = 1; + osal_trigger_event(&stp_btm->STPd_event); + return 0; +} + +static inline INT32 _stp_btm_do_fw_assert(MTKSTP_BTM_T *stp_btm) +{ + INT32 status = -1; + MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; + + /* send assert command */ + STP_BTM_PR_INFO("trigger stp assert process\n"); + if (mtk_wcn_stp_is_sdio_mode()) { + bRet = stp_btm->wmt_notify(BTM_TRIGGER_STP_ASSERT_OP); + if (bRet == MTK_WCN_BOOL_FALSE) { + STP_BTM_PR_INFO("trigger stp assert failed\n"); + return status; + } + status = 0; + } else if (mtk_wcn_stp_is_btif_fullset_mode()) { +#if BTIF_RXD_BE_BLOCKED_DETECT + stp_dbg_is_btif_rxd_be_blocked(); +#endif + status = wmt_plat_force_trigger_assert(STP_FORCE_TRG_ASSERT_DEBUG_PIN); + } + + stp_btm_start_trigger_assert_timer(stp_btm); + + if (status == 0) + STP_BTM_PR_INFO("trigger stp assert succeed\n"); + + return status; +} + + +INT32 stp_notify_btm_do_fw_assert(MTKSTP_BTM_T *stp_btm) +{ + return _stp_btm_do_fw_assert(stp_btm); +} + +INT32 wmt_btm_trigger_reset(VOID) +{ + return stp_btm_notify_wmt_rst_wq(stp_btm); +} + +INT32 stp_btm_set_current_op(MTKSTP_BTM_T *stp_btm, P_OSAL_OP pOp) +{ + if (stp_btm) { + stp_btm->pCurOP = pOp; + STP_BTM_PR_DBG("pOp=0x%p\n", pOp); + return 0; + } + STP_BTM_PR_ERR("Invalid pointer\n"); + return -1; +} + +P_OSAL_OP stp_btm_get_current_op(MTKSTP_BTM_T *stp_btm) +{ + if (stp_btm) + return stp_btm->pCurOP; + STP_BTM_PR_ERR("Invalid pointer\n"); + return NULL; +} + +INT32 stp_btm_init_trigger_assert_timer(MTKSTP_BTM_T *stp_btm) +{ + stp_btm->trigger_assert_timer.timeoutHandler = stp_btm_trigger_assert_timeout_handler; + stp_btm->trigger_assert_timer.timeroutHandlerData = (ULONG)stp_btm; + stp_btm->timeout = 1000; + + return osal_timer_create(&stp_btm->trigger_assert_timer); +} + +INT32 stp_btm_start_trigger_assert_timer(MTKSTP_BTM_T *stp_btm) +{ + return osal_timer_start(&stp_btm->trigger_assert_timer, stp_btm->timeout); +} + +INT32 stp_btm_stop_trigger_assert_timer(MTKSTP_BTM_T *stp_btm) +{ + return osal_timer_stop(&stp_btm->trigger_assert_timer); +} + +VOID stp_btm_print_op_history(VOID) +{ + osal_op_history_print(&stp_btm->op_history, "_stp_btm_proc"); +} diff --git a/drivers/misc/mediatek/connectivity/common/common_main/core/include/btm_core.h b/drivers/misc/mediatek/connectivity/common/common_main/core/include/btm_core.h new file mode 100644 index 0000000000000000000000000000000000000000..305e46cc76f5cd7e1bac99652f789678ede08446 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/core/include/btm_core.h @@ -0,0 +1,154 @@ +/* +* Copyright (C) 2011-2014 MediaTek Inc. +* +* This program is free software: you can redistribute it and/or modify it under the terms of the +* GNU General Public License version 2 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. +* +* You should have received a copy of the GNU General Public License along with this program. +* If not, see . +*/ + + +#ifndef _BTM_CORE_H +#define _BTM_CORE_H + +#include "osal_typedef.h" +#include "osal.h" +#include "stp_wmt.h" +#include "wmt_plat.h" +#include "wmt_idc.h" +#include "osal.h" +#include "mtk_btif_exp.h" +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +#define STP_BTM_OPERATION_FAIL (-1) +#define STP_BTM_OPERATION_SUCCESS (0) + +#define STP_BTM_OP_BUF_SIZE (64) + +#define BTM_THREAD_NAME "mtk_stp_btm" +#define STP_PAGED_DUMP_TIME_LIMIT 3500 +#define STP_FULL_DUMP_TIME 3 +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + + + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ +typedef enum _ENUM_STP_BTM_OPID_T { + STP_OPID_BTM_RETRY = 0x0, + STP_OPID_BTM_RST = 0x1, + STP_OPID_BTM_DBG_DUMP = 0x2, + STP_OPID_BTM_DUMP_TIMEOUT = 0x3, + STP_OPID_BTM_POLL_CPUPCR = 0x4, + STP_OPID_BTM_PAGED_DUMP = 0x5, + STP_OPID_BTM_FULL_DUMP = 0x6, + STP_OPID_BTM_PAGED_TRACE = 0x7, + STP_OPID_BTM_FORCE_FW_ASSERT = 0x8, +#if CFG_WMT_LTE_COEX_HANDLING + STP_OPID_BTM_WMT_LTE_COEX = 0x9, +#endif + STP_OPID_BTM_ASSERT_TIMEOUT = 0xa, + STP_OPID_BTM_EMI_DUMP_END = 0xb, + STP_OPID_BTM_EXIT = 0xc, + STP_OPID_BTM_NUM +} ENUM_STP_BTM_OPID_T, *P_ENUM_STP_BTM_OPID_T; + +typedef OSAL_OP_DAT STP_BTM_OP; +typedef P_OSAL_OP_DAT P_STP_BTM_OP; + +typedef struct mtk_stp_btm { + OSAL_THREAD BTMd; /* main thread (wmtd) handle */ + OSAL_EVENT STPd_event; + OSAL_UNSLEEPABLE_LOCK wq_spinlock; + + OSAL_OP_Q rFreeOpQ; /* free op queue */ + OSAL_OP_Q rActiveOpQ; /* active op queue */ + OSAL_OP arQue[STP_BTM_OP_BUF_SIZE]; /* real op instances */ + P_OSAL_OP pCurOP; /* current op */ + INT32 gDumplogflag; + + /*wmt_notify */ + INT32 (*wmt_notify)(MTKSTP_BTM_WMT_OP_T); + + OSAL_TIMER trigger_assert_timer; + UINT32 timeout; + struct osal_op_history op_history; +} MTKSTP_BTM_T; + + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +INT32 stp_btm_notify_wmt_rst_wq(MTKSTP_BTM_T *stp_btm); +INT32 stp_btm_notify_stp_retry_wq(MTKSTP_BTM_T *stp_btm); +INT32 stp_btm_notify_coredump_timeout_wq(MTKSTP_BTM_T *stp_btm); +INT32 stp_btm_notify_assert_timeout_wq(MTKSTP_BTM_T *stp_btm); +INT32 stp_btm_notify_wmt_dmp_wq(MTKSTP_BTM_T *stp_btm); +INT32 stp_btm_notify_emi_dump_end(MTKSTP_BTM_T *stp_btm); +INT32 stp_btm_deinit(MTKSTP_BTM_T *stp_btm); +INT32 stp_btm_reset_btm_wq(MTKSTP_BTM_T *stp_btm); +INT32 stp_notify_btm_poll_cpupcr(MTKSTP_BTM_T *stp_btm, UINT32 times, UINT32 sleep); +INT32 stp_notify_btm_poll_cpupcr_ctrl(UINT32 en); +INT32 stp_btm_sort_btm_wq(MTKSTP_BTM_T *stp_btm); +INT32 stp_notify_btm_dump(MTKSTP_BTM_T *stp_btm); +INT32 stp_notify_btm_do_fw_assert(MTKSTP_BTM_T *stp_btm); +INT32 stp_notify_btm_handle_wmt_lte_coex(MTKSTP_BTM_T *stp_btm); +INT32 wcn_psm_flag_trigger_collect_ftrace(void); +#if BTIF_RXD_BE_BLOCKED_DETECT +INT32 wcn_btif_rxd_blocked_collect_ftrace(void); +MTK_WCN_BOOL is_btif_rxd_be_blocked(void); +#endif + +INT32 wmt_btm_trigger_reset(VOID); +INT32 stp_btm_init_trigger_assert_timer(MTKSTP_BTM_T *stp_btm); +INT32 stp_btm_start_trigger_assert_timer(MTKSTP_BTM_T *stp_btm); +INT32 stp_btm_stop_trigger_assert_timer(MTKSTP_BTM_T *stp_btm); +INT32 stp_btm_set_current_op(MTKSTP_BTM_T *stp_btm, P_OSAL_OP pOp); +P_OSAL_OP stp_btm_get_current_op(MTKSTP_BTM_T *stp_btm); + +MTKSTP_BTM_T *stp_btm_init(VOID); +extern unsigned int chip_reset_only; + +VOID stp_btm_print_op_history(VOID); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif diff --git a/drivers/misc/mediatek/connectivity/common/common_main/core/include/dbg_core.h b/drivers/misc/mediatek/connectivity/common/common_main/core/include/dbg_core.h new file mode 100644 index 0000000000000000000000000000000000000000..d57740edfeae698c785424dc1471a23fab9f6a98 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/core/include/dbg_core.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + + + + +#ifndef _DBG_CORE_H +#define _DBG_CORE_H + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + + + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif diff --git a/drivers/misc/mediatek/connectivity/common/common_main/core/include/psm_core.h b/drivers/misc/mediatek/connectivity/common/common_main/core/include/psm_core.h new file mode 100644 index 0000000000000000000000000000000000000000..393d0f41227dd99fa35472edda341ab2b82d5993 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/core/include/psm_core.h @@ -0,0 +1,275 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + + + + +#ifndef _PSM_CORE_H +#define _PSM_CORE_H + +#include "osal_typedef.h" +#include "stp_wmt.h" +#include "osal.h" + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +#define PFX_PSM "[STP-PSM] " +#define STP_PSM_LOG_LOUD 4 +#define STP_PSM_LOG_DBG 3 +#define STP_PSM_LOG_INFO 2 +#define STP_PSM_LOG_WARN 1 +#define STP_PSM_LOG_ERR 0 + +#define ASSERT(expr) +#define STP_PSM_FIFO_SIZE 0x2000 /* 8kbytes */ +#define STP_PSM_TX_SIZE 0x800 /* 2kbytes */ + +#define STP_PSM_OPERATION_FAIL (-1) +#define STP_PSM_OPERATION_SUCCESS (0) + +#define STP_PSM_PACKET_SIZE_MAX (2000) +#if (WMT_UART_RX_MODE_WORK || WMT_SDIO_MODE) +#define CFG_PSM_CORE_FIFO_SPIN_LOCK 0 +#else +#define CFG_PSM_CORE_FIFO_SPIN_LOCK 1 +#endif + + +#define PSM_HANDLING 127 + +#define STP_PSM_WMT_PS_TASK_HANDLING_TIME 30 /* 20 milli-seconds */ +#define STP_PSM_IDLE_TIME_SLEEP 30 /* temporary for stress testing */ +#define STP_PSM_IDLE_TIME_SLEEP_1000 1000 /* for high speed transmission e.g. BT OPP*/ +#define STP_PSM_SDIO_IDLE_TIME_SLEEP 100 /* temporary for SDIO stress testing */ +#define STP_PSM_WAIT_EVENT_TIMEOUT 18500 /* set same as MAX_FUNC_ON_TIME */ + +#if 0 +#define STP_PSM_WMT_EVENT_SLEEP_EN (0x1UL << 0) +#define STP_PSM_WMT_EVENT_WAKEUP_EN (0x1UL << 1) +#define STP_PSM_BLOCK_DATA_EN (0x1UL << 2) +#define STP_PSM_WMT_EVENT_DISABLE_MONITOR (0x1UL << 3) +#define STP_PSM_WMT_EVENT_ROLL_BACK_EN (0x1UL << 4) +#define STP_PSM_RESET_EN (0x1UL << 5) +#define STP_PSM_WMT_EVENT_HOST_WAKEUP_EN (0x1UL << 6) +#define STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY (0x1UL << 7) +#define STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY (0x1UL << 8) +#endif + +#define STP_PSM_WMT_EVENT_SLEEP_EN (0) +#define STP_PSM_WMT_EVENT_WAKEUP_EN (1) +#define STP_PSM_BLOCK_DATA_EN (2) +#define STP_PSM_WMT_EVENT_DISABLE_MONITOR (3) +#define STP_PSM_WMT_EVENT_ROLL_BACK_EN (4) +#define STP_PSM_RESET_EN (5) +#define STP_PSM_WMT_EVENT_HOST_WAKEUP_EN (6) +#define STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY (7) +#define STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY (8) + +#define STP_PSM_DBG_SIZE (48) + +/* OP command ring buffer : must be power of 2 */ +#define STP_OP_BUF_SIZE (16) + +#define PSM_THREAD_NAME "mtk_stp_psm" + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + + + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ +typedef enum { + ACT = 0, + ACT_INACT = 1, + INACT = 2, + INACT_ACT = 3, + STP_PSM_MAX_STATE = 4, +} MTKSTP_PSM_STATE_T; + +typedef enum _ENUM_STP_OPID_T { + STP_OPID_PSM_SLEEP = 0, + STP_OPID_PSM_WAKEUP, + STP_OPID_PSM_HOST_AWAKE, + STP_OPID_PSM_EXIT, + STP_OPID_PSM_NUM, + STP_OPID_PSM_INALID = STP_OPID_PSM_NUM, +} ENUM_STP_OPID_T, *P_ENUM_STP_OPID_T; + +typedef enum { + MON = 0, + UNMON, +} MTKSTP_PSM_MONSTATE_T; + +typedef INT32(*wmt_notify_t) (MTKSTP_PSM_ACTION_T action); +typedef INT32(*stp_tx_cb_t) (PUINT8 buffer, UINT32 length, UINT8 type); + +typedef OSAL_OP_DAT STP_OP; +typedef P_OSAL_OP_DAT P_STP_OP; +#if 0 +#if CFG_PSM_CORE_FIFO_SPIN_LOCK +typedef OSAL_UNSLEEPABLE_LOCK PSM_FIFO_LOCK, *PPSM_FIFO_LOCK; +#else +typedef OSAL_SLEEPABLE_LOCK PSM_FIFO_LOCK, *PPSM_FIFO_LOCK; +#endif +#endif +typedef struct mtk_stp_psm { + OSAL_THREAD PSMd; /* main thread (wmtd) handle */ + OSAL_EVENT STPd_event; + + OSAL_OP_Q rFreeOpQ; /* free op queue */ + OSAL_OP_Q rActiveOpQ; /* active op queue */ + OSAL_OP arQue[STP_OP_BUF_SIZE]; /* real op instances */ + + /* OSAL_OP current_active_op; */ + /* P_OSAL_OP current_active_op; */ + UINT32 last_active_opId; + MTKSTP_PSM_STATE_T work_state; /*working state */ + OSAL_BIT_OP_VAR flag; + + /* in normal cases, sleep op is always enabled; but in error cases, we can't execute sleep cmd, + * Eg: FW assert, core dump + */ + INT32 sleep_en; + +/* OSAL_UNSLEEPABLE_LOCK flagSpinlock; */ + INT32 idle_time_to_sleep; + OSAL_WAKE_LOCK wake_lock; + OSAL_TIMER psm_timer; /*monitor if active */ + OSAL_EVENT wait_wmt_q; + OSAL_FIFO hold_fifo; + + /* PSM_FIFO_LOCK hold_fifo_lock; */ + OSAL_SLEEPABLE_LOCK hold_fifo_spinlock_global; + + OSAL_UNSLEEPABLE_LOCK wq_spinlock; + OSAL_SLEEPABLE_LOCK user_lock; + OSAL_SLEEPABLE_LOCK stp_psm_lock; + INT32 (*wmt_notify)(MTKSTP_PSM_ACTION_T action); + INT32 (*stp_tx_cb)(PUINT8 buffer, UINT32 length, UINT8 type); + MTK_WCN_BOOL (*is_wmt_quick_ps_support)(VOID); + INT32 (*update_wmt_fw_patch_chip_rst)(VOID); + UINT8 out_buf[STP_PSM_TX_SIZE]; + struct osal_op_history op_history; +} MTKSTP_PSM_T; + +typedef struct { + UINT32 prev_flag; + UINT32 cur_flag; + UINT32 line_num; + UINT32 package_no; + UINT32 sec; + UINT32 usec; + UINT32 pid; + UINT64 l_sec; + ULONG l_nsec; +} STP_PSM_ENTRY_T; + +typedef struct stp_psm_record { + STP_PSM_ENTRY_T queue[STP_PSM_DBG_SIZE]; + UINT32 in; + UINT32 out; + UINT32 size; + OSAL_UNSLEEPABLE_LOCK lock; +} STP_PSM_RECORD_T; + +typedef struct stp_psm_opid_record { + STP_PSM_ENTRY_T queue[STP_PSM_DBG_SIZE]; + UINT32 in; + UINT32 out; + UINT32 size; + OSAL_UNSLEEPABLE_LOCK lock; +} STP_PSM_OPID_RECORD, *P_STP_PSM_OPID_RECORD; +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ +#define PSM_USE_COUNT_PACKAGE 0 + +#if PSM_USE_COUNT_PACKAGE +#define MTK_COMBO_PSM_RX_TH_DEFAULT (1600) +#define MTK_COMBO_PSM_TX_TH_DEFAULT (300) +INT32 stp_psm_disable_by_tx_rx_density(MTKSTP_PSM_T *stp_psm, INT32 dir); +#else +#define SAMPLE_DURATION 1 /*1 second */ +#define RTX_SPEED_THRESHOLD 50000 /*50KB/s */ +INT32 stp_psm_disable_by_tx_rx_density(MTKSTP_PSM_T *stp_psm, INT32 dir, INT32 length); +#endif + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +/*stp-psm external function*/ +INT32 stp_psm_notify_stp(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_ACTION_T action); +INT32 stp_psm_notify_wmt_wakeup(MTKSTP_PSM_T *stp_psm); +INT32 stp_psm_notify_wmt_sleep(MTKSTP_PSM_T *stp_psm); + +INT32 stp_psm_start_monitor(MTKSTP_PSM_T *stp_psm); +INT32 stp_psm_is_to_block_traffic(MTKSTP_PSM_T *stp_psm); +INT32 stp_psm_is_disable(MTKSTP_PSM_T *stp_psm); +INT32 stp_psm_has_pending_data(MTKSTP_PSM_T *stp_psm); +INT32 stp_psm_release_data(MTKSTP_PSM_T *stp_psm); +INT32 stp_psm_hold_data(MTKSTP_PSM_T *stp_psm, + const PUINT8 buffer, const UINT32 len, const UINT8 type); +INT32 stp_psm_do_wakeup(MTKSTP_PSM_T *stp_psm); +INT32 stp_psm_reset(MTKSTP_PSM_T *stp_psm); +INT32 stp_psm_disable(MTKSTP_PSM_T *stp_psm); +INT32 stp_psm_enable(MTKSTP_PSM_T *stp_psm, INT32 idle_time_to_sleep); +struct mtk_stp_psm *stp_psm_init(void); +INT32 stp_psm_deinit(MTKSTP_PSM_T *stp_psm); +MTK_WCN_BOOL mtk_wcn_stp_psm_dbg_level(INT32 dbglevel); +INT32 stp_psm_sleep_for_thermal(MTKSTP_PSM_T *stp_psm); +INT32 stp_psm_thread_lock_aquire(MTKSTP_PSM_T *stp_psm); +INT32 stp_psm_thread_lock_release(MTKSTP_PSM_T *stp_psm); +INT32 stp_psm_set_state(MTKSTP_PSM_T *stp_psm, MTKSTP_PSM_STATE_T state); +MTK_WCN_BOOL stp_psm_is_quick_ps_support(VOID); + +INT32 stp_psm_set_sleep_enable(MTKSTP_PSM_T *stp_psm); +INT32 stp_psm_set_sleep_disable(MTKSTP_PSM_T *stp_psm); +INT32 stp_psm_check_sleep_enable(MTKSTP_PSM_T *stp_psm); + +VOID stp_psm_print_op_history(VOID); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif diff --git a/drivers/misc/mediatek/connectivity/common/common_main/core/include/stp_core.h b/drivers/misc/mediatek/connectivity/common/common_main/core/include/stp_core.h new file mode 100644 index 0000000000000000000000000000000000000000..2099131738bedde3c361eec1a523dcefcabb8710 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/core/include/stp_core.h @@ -0,0 +1,699 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + + + +#ifndef _STP_CORE_H +#define _STP_CORE_H +#include "osal_typedef.h" +#include "osal.h" +#include "stp_exp.h" +#include "psm_core.h" +#include "btm_core.h" +#include "stp_btif.h" +#include "stp_wmt.h" +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ +#define WMT_LTE_COEX_FLAG (0x16) +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +#define CONFIG_POWER_SAVING_SUPPORT +#if (WMT_UART_RX_MODE_WORK || WMT_SDIO_MODE) +#define CFG_STP_CORE_CTX_SPIN_LOCK 0 +#else +#define CFG_STP_CORE_CTX_SPIN_LOCK 1 +#endif + + + +#define PFX "[STP] " +#define STP_LOG_DBG 4 +#define STP_LOG_PKHEAD 3 +#define STP_LOG_INFO 2 +#define STP_LOG_WARN 1 +#define STP_LOG_ERR 0 + +extern INT32 gStpDbgLvl; + +#define STP_DBG_FUNC(fmt, arg...) do {\ + if (gStpDbgLvl >= STP_LOG_DBG)\ + osal_warn_print(PFX "%s: " fmt, __func__, ##arg);\ +} while (0) + +#define STP_INFO_FUNC(fmt, arg...) do {\ + if (gStpDbgLvl >= STP_LOG_INFO)\ + osal_warn_print(PFX "%s:[I] " fmt, __func__, ##arg);\ +} while (0) + +#define STP_WARN_RATELIMITED_FUNC(fmt, arg...) do {\ + static DEFINE_RATELIMIT_STATE(_rs, HZ, 5);\ + if (gStpDbgLvl >= STP_LOG_WARN && __ratelimit(&_rs))\ + osal_warn_print(PFX "%s:[W] " fmt, __func__, ##arg);\ +} while (0) + +#define STP_WARN_FUNC(fmt, arg...) do {\ + if (gStpDbgLvl >= STP_LOG_WARN)\ + osal_warn_print(PFX "%s:[W] " fmt, __func__, ##arg);\ +} while (0) + +#define STP_ERR_FUNC(fmt, arg...) do {\ + if (gStpDbgLvl >= STP_LOG_ERR)\ + osal_err_print(PFX "%s:[E] " fmt, __func__, ##arg);\ +} while (0) + +#define STP_TRC_FUNC(f) do {\ + if (gStpDbgLvl >= STP_LOG_DBG)\ + osal_warn_print(PFX "<%s> <%d>\n", __func__, __LINE__);\ +} while (0) + +#define STP_DUMP_PACKET_HEAD(a, b, c) do {\ + if (gStpDbgLvl >= STP_LOG_PKHEAD)\ + stp_dump_data(a, b, c);\ +} while (0) + +#define STP_TRACE_FUNC(fmt, arg...) do {\ + if (gStpDbgLvl >= STP_LOG_DBG)\ + osal_warn_print(PFX "%s: " fmt, __func__, ##arg);\ +} while (0) + +#define STP_MODE_BIT(x) (0x1UL << x) +#define MTKSTP_UART_FULL_MODE STP_MODE_BIT(0) +#define MTKSTP_UART_MAND_MODE STP_MODE_BIT(1) +#define MTKSTP_BTIF_FULL_MODE STP_MODE_BIT(2) +#define MTKSTP_BTIF_MAND_MODE STP_MODE_BIT(3) +#define MTKSTP_SDIO_MODE STP_MODE_BIT(4) + +#define MTKSTP_BUFFER_SIZE (16384) +#define PARSER_CORE_DUMP_NUM 200 +#define CORE_DUMP_NUM 100 +/*To check function driver's status by the the interface*/ +/*Operation definition*/ +#define OP_FUNCTION_ACTIVE 0 + +/*Driver's status*/ +#define STATUS_OP_INVALID 0 +#define STATUS_FUNCTION_INVALID 1 + +#define STATUS_FUNCTION_ACTIVE 31 +#define STATUS_FUNCTION_INACTIVE 32 + +#define MTKSTP_CRC_SIZE (2) +#define MTKSTP_HEADER_SIZE (4) +#define MTKSTP_SEQ_SIZE (8) + +/*#define MTKSTP_WINSIZE (4)*/ +#define MTKSTP_WINSIZE (7) +#define MTKSTP_TX_TIMEOUT (180) /*TODO: Baudrate to decide this */ +#define MTKSTP_RETRY_LIMIT (10) + +#define INDEX_INC(idx) \ +{ \ + idx++; \ + idx &= 0x7; \ +} + +#define INDEX_DEC(idx) \ +{ \ + idx--; \ + idx &= 0x7; \ +} + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + + + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ +typedef INT32(*IF_TX) (const PUINT8 data, const UINT32 size, PUINT32 written_size); +typedef INT32(*RX_HAS_PENDING_DATA) (VOID); +typedef INT32(*TX_HAS_PENDING_DATA) (VOID); +typedef P_OSAL_THREAD(*RX_THREAD_GET) (VOID); +/* event/signal */ +typedef INT32(*EVENT_SET) (UINT8 function_type); +typedef INT32(*EVENT_TX_RESUME) (UINT8 winspace); +typedef INT32(*FUNCTION_STATUS) (UINT8 type, UINT8 op); +typedef INT32(*WMT_NOTIFY_FUNC_T) (UINT32 action); +typedef INT32(*BTM_NOTIFY_WMT_FUNC_T) (INT32); + +#if CFG_STP_CORE_CTX_SPIN_LOCK +typedef OSAL_UNSLEEPABLE_LOCK STP_CTX_LOCK, *PSTP_CTX_LOCK; +#else +typedef OSAL_SLEEPABLE_LOCK STP_CTX_LOCK, *PSTP_CTX_LOCK; +#endif + +typedef struct { + /* common interface */ + IF_TX cb_if_tx; + RX_HAS_PENDING_DATA cb_rx_has_pending_data; + TX_HAS_PENDING_DATA cb_tx_has_pending_data; + RX_THREAD_GET cb_rx_thread_get; + /* event/signal */ + EVENT_SET cb_event_set; + EVENT_TX_RESUME cb_event_tx_resume; + FUNCTION_STATUS cb_check_funciton_status; +} mtkstp_callback; + +typedef enum { + MTKSTP_SYNC = 0, + MTKSTP_SEQ, + MTKSTP_ACK, + MTKSTP_NAK, + MTKSTP_TYPE, + MTKSTP_LENGTH, + MTKSTP_CHECKSUM, + MTKSTP_DATA, + MTKSTP_CRC1, + MTKSTP_CRC2, + MTKSTP_RESYNC1, + MTKSTP_RESYNC2, + MTKSTP_RESYNC3, + MTKSTP_RESYNC4, + MTKSTP_FW_MSG, +} mtkstp_parser_state; + +typedef struct { + mtkstp_parser_state state; + UINT8 seq; + UINT8 ack; + UINT8 nak; + UINT8 type; + UINT16 length; + UINT8 checksum; + UINT16 crc; +} mtkstp_parser_context_struct; + +typedef struct { + UINT8 txseq; /* last tx pkt's seq + 1 */ + UINT8 txack; /* last tx pkt's ack */ + UINT8 rxack; /* last rx pkt's ack */ + UINT8 winspace; /* current sliding window size */ + UINT8 expected_rxseq; /* last rx pkt's seq + 1 */ + UINT8 retry_times; + UINT8 tx_timeout_loop; /* for extend tx timeout */ + UINT8 rx_resync; /* num of 7f7f7f7f before expected_rxseq pkt, indicates if recv series of resync pkt */ + UINT8 rx_resync_seq; /* last resync pkg's seq (0xFF if not set), only valid if rx_resync != 0 */ +} mtkstp_sequence_context_struct; + +typedef struct { + /* MTK_WCN_MUTEX mtx; */ + OSAL_UNSLEEPABLE_LOCK mtx; + UINT8 buffer[MTKSTP_BUFFER_SIZE]; + UINT32 read_p; + UINT32 write_p; +} mtkstp_ring_buffer_struct; + +typedef struct { + UINT8 inband_rst_set; + UINT32 assert_info_cnt; + UINT32 rx_counter; /* size of current processing pkt in rx_buf[] */ + UINT8 rx_buf[MTKSTP_BUFFER_SIZE]; /* input buffer of STP, room for current processing pkt */ + UINT32 tx_read; /* read ptr of tx_buf[] */ + UINT32 tx_write; /* write ptr of tx_buf[] */ + UINT8 tx_buf[MTKSTP_BUFFER_SIZE]; /* output buffer of STP */ + UINT32 tx_start_addr[MTKSTP_SEQ_SIZE]; /* ptr of each pkt in tx_buf[] */ + UINT32 tx_length[MTKSTP_SEQ_SIZE]; /* length of each pkt in tx_buf[] */ + mtkstp_ring_buffer_struct ring[MTKSTP_MAX_TASK_NUM]; /* ring buffers for each function driver */ + mtkstp_parser_context_struct parser; /* current rx pkt's content */ + mtkstp_sequence_context_struct sequence; /* state machine's current status */ + /* MTK_WCN_MUTEX stp_mutex; */ +#if CFG_STP_CORE_CTX_SPIN_LOCK + OSAL_UNSLEEPABLE_LOCK stp_mutex; +#else + OSAL_SLEEPABLE_LOCK stp_mutex; +#endif + /* MTK_WCN_TIMER tx_timer; // timer for tx timeout handling */ + OSAL_TIMER tx_timer; + + MTKSTP_PSM_T *psm; + MTKSTP_BTM_T *btm; + UINT8 f_enable; /* default disabled */ + UINT8 f_ready; /* default non-ready */ + UINT8 f_pending_type; + UINT8 f_coredump; /*block tx flag, for now, only when f/w assert happens, we will set this bit on */ + UINT8 en_coredump; + UINT8 f_emidump; + /* Flag to identify Blueztooth is Bluez/or MTK Stack */ + MTK_WCN_BOOL f_bluez; + MTK_WCN_BOOL f_dbg_en; + MTK_WCN_BOOL f_autorst_en; + + + + /* Flag to identify STP by SDIO or UART */ + UINT32 f_mode; + + /* Flag to indicate the last WMT CLOSE */ + UINT32 f_wmt_last_close; + /* Flag to indicate evt err has triggered assert or not */ + UINT32 f_evt_err_assert; + /* Flag to indicate assert process is ongoing or not */ + UINT32 f_assert_in_progress; + + /* Flag to identify support GPSL5 */ + MTK_WCN_BOOL f_gpsl5_en; +} mtkstp_context_struct; + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +INT32 stp_send_data_no_ps(PUINT8 buffer, UINT32 length, UINT8 type); + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_init +* DESCRIPTION +* init STP kernel +* PARAMETERS +* cb_func [IN] function pointers of system APIs +* RETURNS +* INT32 0 = success, others = failure +*****************************************************************************/ +extern INT32 mtk_wcn_stp_init(const mtkstp_callback * const cb_func); + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_deinit +* DESCRIPTION +* deinit STP kernel +* PARAMETERS +* void +* RETURNS +* INT32 0 = success, others = failure +*****************************************************************************/ +extern INT32 mtk_wcn_stp_deinit(VOID); + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_enable +* DESCRIPTION +* enable/disable STP +* PARAMETERS +* value [IN] 0 = disable, others = enable +* RETURNS +* INT32 0 = success, others = error +*****************************************************************************/ +extern INT32 mtk_wcn_stp_enable(INT32 value); + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_is_enable +* DESCRIPTION +* get STP enable/disable status +* PARAMETERS +* none. +* RETURNS +* INT32 0 = disable, 1 = enable +*****************************************************************************/ +extern INT32 mtk_wcn_stp_is_enable(VOID); + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_ready +* DESCRIPTION +* ready/non-ready STP +* PARAMETERS +* value [IN] 0 = non-ready, others = ready +* RETURNS +* INT32 0 = success, others = error +*****************************************************************************/ +extern INT32 mtk_wcn_stp_ready(INT32 value); + + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_coredump_start_ctrl +* DESCRIPTION +* set f/w assert flag in STP context +* PARAMETERS +* value [IN] 0=assert end, others=assert begins +* RETURNS +* INT32 0=success, others=error +*****************************************************************************/ +extern INT32 mtk_wcn_stp_coredump_start_ctrl(UINT32 value); + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_coredump_start_get +* DESCRIPTION +* get f/w assert flag in STP context +* PARAMETERS +* VOID +* RETURNS +* INT32 0= f/w assert flag is not set, others=f/w assert flag is set +*****************************************************************************/ +extern INT32 mtk_wcn_stp_coredump_start_get(VOID); + + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_send_data_raw +* DESCRIPTION +* send raw data to common interface, bypass STP +* PARAMETERS +* buffer [IN] data buffer +* length [IN] data buffer length +* type [IN] subfunction type +* RETURNS +* INT32 length transmitted +*****************************************************************************/ +extern INT32 mtk_wcn_stp_send_data_raw(const PUINT8 buffer, const UINT32 length, const UINT8 type); + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_set_sdio_mode +* DESCRIPTION +* Set stp for SDIO mode +* PARAMETERS +* sdio_flag [IN] sdio mode flag (TRUE:SDIO mode, FALSE:UART mode) +* RETURNS +* void +*****************************************************************************/ +extern VOID mtk_wcn_stp_set_mode(UINT32 sdio_flag); + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_is_uart_fullset_mode +* DESCRIPTION +* Is stp use UART Fullset mode? +* PARAMETERS +* none. +* RETURNS +* MTK_WCN_BOOL TRUE:UART Fullset, FALSE:UART Fullset +*****************************************************************************/ +extern MTK_WCN_BOOL mtk_wcn_stp_is_uart_fullset_mode(VOID); + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_is_uart_mand_mode +* DESCRIPTION +* Is stp use UART Mandatory mode? +* PARAMETERS +* none. +* RETURNS +* MTK_WCN_BOOL TRUE:UART Mandatory, FALSE:UART Mandatory +*****************************************************************************/ +extern MTK_WCN_BOOL mtk_wcn_stp_is_uart_mand_mode(VOID); + +extern MTK_WCN_BOOL mtk_wcn_stp_is_uart_mand_mode(VOID); +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_is_btif_fullset_mode +* DESCRIPTION +* Is stp use BTIF Fullset mode? +* PARAMETERS +* none. +* RETURNS +* MTK_WCN_BOOL TRUE:BTIF Fullset, FALSE:BTIF Fullset +*****************************************************************************/ +extern MTK_WCN_BOOL mtk_wcn_stp_is_btif_fullset_mode(VOID); + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_is_btif_mand_mode +* DESCRIPTION +* Is stp use BTIF Mandatory mode? +* PARAMETERS +* none. +* RETURNS +* MTK_WCN_BOOL TRUE:BTIF Mandatory, FALSE:BTIF Mandatory +*****************************************************************************/ +extern MTK_WCN_BOOL mtk_wcn_stp_is_btif_mand_mode(void); + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_is_sdio_mode +* DESCRIPTION +* Is stp use SDIO mode? +* PARAMETERS +* none. +* RETURNS +* MTK_WCN_BOOL TRUE:SDIO mode, FALSE:UART mode +*****************************************************************************/ +extern MTK_WCN_BOOL mtk_wcn_stp_is_sdio_mode(VOID); + + +/***************************************************************************** +* FUNCTION +* stp_send_inband_reset +* DESCRIPTION +* To sync to oringnal stp state with f/w stp +* PARAMETERS +* none. +* RETURNS +* none +*****************************************************************************/ +extern VOID mtk_wcn_stp_inband_reset(VOID); + +/***************************************************************************** +* FUNCTION +* stp_send_inband_reset +* DESCRIPTION +* To send testing command to chip +* PARAMETERS +* none. +* RETURNS +* none +*****************************************************************************/ +extern VOID mtk_wcn_stp_test_cmd(INT32 no); + +/***************************************************************************** +* FUNCTION +* stp_send_inband_reset +* DESCRIPTION +* To control STP debugging mechanism +* PARAMETERS +* func_no: function control, func_op: dumpping filer, func_param: dumpping parameter +* RETURNS +* none +*****************************************************************************/ +extern VOID mtk_wcn_stp_debug_ctrl(INT32 func_no, INT32 func_op, INT32 func_param); +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_flush +* DESCRIPTION +* flush all stp context +* PARAMETERS +* none. +* RETURNS +* none +*****************************************************************************/ +extern VOID mtk_wcn_stp_flush_context(VOID); + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_rx_queue +* DESCRIPTION +* flush all stp rx queue +* PARAMETERS +* none. +* RETURNS +* none +*****************************************************************************/ +extern VOID mtk_wcn_stp_flush_rx_queue(UINT32 type); + +/***************************************************************************** +* FUNCTION +* set stp debugging mdoe +* DESCRIPTION +* set stp debugging mdoe +* PARAMETERS +* dbg_mode: switch to dbg mode ? +* RETURNS +* void +*****************************************************************************/ +extern VOID mtk_wcn_stp_set_dbg_mode(MTK_WCN_BOOL dbg_mode); + +/***************************************************************************** +* FUNCTION +* set stp auto reset mdoe +* DESCRIPTION +* set stp auto reset mdoe +* PARAMETERS +* auto_rst: switch to auto reset mode ? +* RETURNS +* void +*****************************************************************************/ +extern VOID mtk_wcn_stp_set_auto_rst(MTK_WCN_BOOL auto_rst); + +/*stp_psm support*/ + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_psm_notify_stp +* DESCRIPTION +* WMT notification to STP that power saving job is done or not +* PARAMETERS +* +* RETURNS +* 0: Sccuess Negative value: Fail +*****************************************************************************/ +extern INT32 mtk_wcn_stp_psm_notify_stp(const MTKSTP_PSM_ACTION_T action); + +extern INT32 mtk_wcn_stp_set_psm_state(MTKSTP_PSM_STATE_T state); + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_psm_enabla +* DESCRIPTION +* enable STP PSM +* PARAMETERS +* int idle_time_to_sleep: IDLE time to sleep +* RETURNS +* 0: Sccuess Negative value: Fail +*****************************************************************************/ +extern INT32 mtk_wcn_stp_psm_enable(INT32 idle_time_to_sleep); + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_psm_disable +* DESCRIPTION +* disable STP PSM +* PARAMETERS +* void +* RETURNS +* 0: Sccuess Negative value: Fail +*****************************************************************************/ +extern INT32 mtk_wcn_stp_psm_disable(VOID); + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_psm_reset +* DESCRIPTION +* reset STP PSM (used on whole chip reset) +* PARAMETERS +* void +* RETURNS +* 0: Sccuess Negative value: Fail +*****************************************************************************/ +extern INT32 mtk_wcn_stp_psm_reset(VOID); +extern VOID stp_do_tx_timeout(VOID); + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_btm_get_dmp +* DESCRIPTION +* get stp dump related information +* PARAMETERS +* buffer: dump placement, len: dump size +* RETURNS +* 0: Success Negative Value: Fail +*****************************************************************************/ +extern INT32 mtk_wcn_stp_btm_get_dmp(PINT8 buf, PINT32 len); + +extern INT32 mtk_wcn_stp_dbg_enable(VOID); + +extern INT32 mtk_wcn_stp_dbg_disable(VOID); + +extern VOID mtk_wcn_stp_set_if_tx_type(ENUM_STP_TX_IF_TYPE stp_if_type); + +extern INT32 mtk_wcn_sys_if_rx(PUINT8 data, INT32 size); + +extern MTK_WCN_BOOL mtk_wcn_stp_dbg_level(INT32 dbglevel); + +extern INT32 mtk_wcn_stp_dbg_dump_package(VOID); + +extern INT32 stp_drv_init(VOID); + +extern VOID stp_drv_exit(VOID); + +extern INT32 mtk_wcn_stp_dbg_log_ctrl(UINT32 on); + +extern INT32 mtk_wcn_stp_coredump_flag_ctrl(UINT32 on); + +extern INT32 mtk_wcn_stp_coredump_flag_get(VOID); +extern INT32 mtk_wcn_stp_notify_sleep_for_thermal(VOID); +extern INT32 mtk_wcn_stp_emi_dump_flag_ctrl(UINT32 on); +extern INT32 mtk_wcn_stp_emi_dump_flag_get(VOID); + +extern INT32 mtk_wcn_stp_set_wmt_last_close(UINT32 value); +extern INT32 mtk_wcn_stp_is_wmt_last_close(VOID); + +/*stp btif API declared*/ +extern INT32 mtk_wcn_stp_open_btif(VOID); +extern INT32 mtk_wcn_stp_close_btif(VOID); +extern INT32 mtk_wcn_stp_rxcb_register(MTK_WCN_BTIF_RX_CB rx_cb); +extern INT32 mtk_wcn_stp_tx(UINT8 *pBuf, UINT32 len, UINT32 *written_len); +extern INT32 mtk_wcn_stp_wakeup_consys(VOID); +extern INT32 mtk_wcn_stp_dpidle_ctrl(UINT32 en_flag); +extern INT32 mtk_wcn_stp_lpbk_ctrl(enum _ENUM_BTIF_LPBK_MODE_ mode); +extern INT32 mtk_wcn_stp_logger_ctrl(enum _ENUM_BTIF_DBG_ID_ flag); +extern VOID mtk_wcn_stp_ctx_save(VOID); +extern VOID mtk_wcn_stp_ctx_restore(VOID); + +extern INT32 mtk_wcn_stp_wmt_trg_assert(VOID); +extern UINT32 mtk_wcn_stp_get_wmt_trg_assert(VOID); +extern VOID mtk_wcn_stp_set_wmt_trg_assert(UINT32 value); +extern INT32 mtk_wcn_stp_assert_timeout_handle(VOID); +extern INT32 mtk_wcn_stp_coredump_timeout_handle(VOID); +extern VOID mtk_wcn_stp_dbg_pkt_log(INT32 type, INT32 dir); + +extern INT32 mtk_wcn_sys_if_rx(UINT8 *data, INT32 size); + +/* + * API to get/set assert process is ongoing. + * It includes assert, coredump and chip reset process. + */ +extern VOID mtk_wcn_stp_assert_flow_ctrl(UINT32 on); +extern UINT32 mtk_wcn_stp_assert_flow_get(VOID); + +extern VOID mtk_wcn_stp_set_support_gpsl5(MTK_WCN_BOOL support_gpsl5); +extern INT32 mtk_wcn_stp_is_support_gpsl5(VOID); + +VOID mtk_stp_sdio_retry_flag_ctrl(INT32 flag); +VOID mtk_stp_dbg_sdio_retry_flag_ctrl(INT32 flag); +INT32 mtk_stp_sdio_retry_flag_get(VOID); +VOID mtk_stp_dump_sdio_register(VOID); +VOID mtk_stp_notify_emi_dump_end(VOID); +INT32 mtk_stp_check_rx_has_pending_data(VOID); +INT32 mtk_stp_dbg_dmp_append(PUINT8 buf, INT32 max_len); +P_OSAL_THREAD mtk_stp_rx_thread_get(VOID); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _STP_CORE_H_ */ diff --git a/drivers/misc/mediatek/connectivity/common/common_main/core/include/stp_wmt.h b/drivers/misc/mediatek/connectivity/common/common_main/core/include/stp_wmt.h new file mode 100644 index 0000000000000000000000000000000000000000..63d237a058b22886abb12b320972b6cb79fe0ea2 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/core/include/stp_wmt.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + + + +#ifndef _STP_WMT_H +#define _STP_WMT_H + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + + + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +typedef enum { + BTM_RST_OP = 0, + BTM_DMP_OP = 1, + BTM_GET_AEE_SUPPORT_FLAG = 2, + BTM_TRIGGER_STP_ASSERT_OP = 3, + BTM_MAX_OP, +} MTKSTP_BTM_WMT_OP_T; + +typedef enum { + SLEEP = 0, + HOST_AWAKE, + WAKEUP, + EIRQ, + ROLL_BACK, + STP_PSM_MAX_ACTION +} MTKSTP_PSM_ACTION_T; + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +extern MTK_WCN_BOOL wmt_lib_btm_cb(MTKSTP_BTM_WMT_OP_T op); + +extern INT32 wmt_lib_ps_stp_cb(MTKSTP_PSM_ACTION_T action); +extern MTK_WCN_BOOL wmt_lib_is_quick_ps_support(VOID); + +extern INT32 wmt_lib_ps_set_idle_time(UINT32 psIdleTime); + +extern INT32 wmt_lib_update_fw_patch_chip_rst(VOID); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _STP_WMT_H_ */ diff --git a/drivers/misc/mediatek/connectivity/common/common_main/core/include/wmt_conf.h b/drivers/misc/mediatek/connectivity/common/common_main/core/include/wmt_conf.h new file mode 100644 index 0000000000000000000000000000000000000000..99788d3d2c63ac14f8ba5cf7fc27da5e10d70850 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/core/include/wmt_conf.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + + + +#ifndef _WMT_CONF_H_ +#define _WMT_CONF_H_ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +#define CUST_CFG_WMT "WMT.cfg" +#define CUST_CFG_WMT_SOC "WMT_SOC.cfg" + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + + + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + + + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + + + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + + + + + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +INT32 wmt_conf_read_file(VOID); +P_WMT_GEN_CONF wmt_conf_get_cfg(VOID); +INT32 wmt_conf_set_cfg_file(const PINT8 name); +INT32 wmt_conf_deinit(VOID); + +#endif /* _WMT_CONF_H_ */ diff --git a/drivers/misc/mediatek/connectivity/common/common_main/core/include/wmt_core.h b/drivers/misc/mediatek/connectivity/common/common_main/core/include/wmt_core.h new file mode 100644 index 0000000000000000000000000000000000000000..7ac2b51cdb6b61ec4eb7445f4100b3886c8cdd25 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/core/include/wmt_core.h @@ -0,0 +1,585 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + + + + +#ifndef _WMT_CORE_H_ +#define _WMT_CORE_H_ + +#include "wmt_ctrl.h" +#include "wmt_exp.h" +#include "wmt_plat.h" +#include "osal.h" +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ +#if defined(MT6620E3) || defined(MT6620E6) /* need modify this part */ +#define CFG_CORE_MT6620_SUPPORT 1 /* whether MT6620 is supported or not */ +#else +#define CFG_CORE_MT6620_SUPPORT 1 /* whether MT6620 is supported or not */ +#endif + +#if defined(MT6628) +#define CFG_CORE_MT6628_SUPPORT 1 /* whether MT6628 is supported or not */ +#else +#define CFG_CORE_MT6628_SUPPORT 1 /* whether MT6628 is supported or not */ +#endif + +#if defined(MT6630) +#define CFG_CORE_MT6630_SUPPORT 1 /* whether MT6630 is supported or not */ +#else +#define CFG_CORE_MT6630_SUPPORT 1 /* whether MT6630 is supported or not */ +#endif + +#if defined(MT6632) +#define CFG_CORE_MT6632_SUPPORT 1 /* whether MT6632 is supported or not */ +#else +#define CFG_CORE_MT6632_SUPPORT 1 /* whether MT6632 is supported or not */ +#endif + +#define CFG_CORE_SOC_SUPPORT 1 +/* TODO:[ChangeFeature][George] move this definition outside so that wmt_dev can remove wmt_core.h inclusion. */ +#define defaultPatchName "mt66xx_patch_hdr.bin" + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +#define BCNT_PATCH_BUF_HEADROOM (8) + +#define BCNT_PATCH_BUF_CHECKSUM (2) + +#define DWCNT_HIF_CONF (4) +#define DWCNT_STRAP_CONF (4) +#define DWCNT_RESERVED (8) +#define DWCNT_CTRL_DATA (16) + + +#if 0 /* TODO: [obsolete][GeorgeKuo]: remove ubsolete definitions */ +#define WMT_SET (1) +#define WMT_QUERY (0) +#define WMT_PKT_FMT_RAW (1) +#define WMT_PKT_FMT_STP (0) +#endif + +#define WMT_FUNC_CTRL_ON (MTK_WCN_BOOL_TRUE) +#define WMT_FUNC_CTRL_OFF (MTK_WCN_BOOL_FALSE) + +#define WMT_HDR_LEN (4) /* header length */ +#define WMT_STS_LEN (1) /* status length */ +#define WMT_FLAG_LEN (1) +#define WMT_HIF_UART_INFO_LEN (4) +#define WMT_FUNC_CTRL_PARAM_LEN (1) +#define WMT_LPBK_CMD_LEN (5) +#define WMT_LPBK_BUF_LEN (1024+WMT_LPBK_CMD_LEN) +#define WMT_DEFAULT_BAUD_RATE (115200) + +#define INIT_CMD(c, e, s) {.cmd = c, .cmdSz = sizeof(c), .evt = e, .evtSz = sizeof(e), .str = s} + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +typedef enum _ENUM_WMT_FM_T { + WMT_FM_INVALID = 0, + WMT_FM_I2C = 1, + WMT_FM_COMM = 2, + WMT_FM_MAX +} ENUM_WMT_FM_T, *P_ENUM_WMT_FM_T; + +typedef enum _ENUM_WMT_HIF_T { + WMT_HIF_UART = 0, + WMT_HIF_SDIO = 1, + WMT_HIF_BTIF = 2, + WMT_HIF_MAX +} ENUM_WMT_HIF_T, *P_ENUM_WMT_HIF_T; + +#if 0 /* [George] moved to wmt_exp.h for hif_sdio's use */ +typedef enum { + WMT_SDIO_SLOT_INVALID = 0, + WMT_SDIO_SLOT_SDIO1 = 1, /* Wi-Fi dedicated SDIO1 */ + WMT_SDIO_SLOT_SDIO2 = 2, + WMT_SDIO_SLOT_MAX +} WMT_SDIO_SLOT_NUM; + +typedef enum { + WMT_SDIO_FUNC_STP = 0, + WMT_SDIO_FUNC_WIFI = 1, + WMT_SDIO_FUNC_MAX +} WMT_SDIO_FUNC_TYPE; +#endif + +typedef enum _ENUM_WMT_OPID_T { + WMT_OPID_HIF_CONF = 0, + WMT_OPID_PWR_ON = 1, + WMT_OPID_PWR_OFF = 2, + WMT_OPID_FUNC_ON = 3, + WMT_OPID_FUNC_OFF = 4, + WMT_OPID_REG_RW = 5, /* TODO:[ChangeFeature][George] is this OP obsoleted? */ + WMT_OPID_EXIT = 6, + WMT_OPID_PWR_SV = 7, + WMT_OPID_DSNS = 8, + WMT_OPID_LPBK = 9, + WMT_OPID_CMD_TEST = 10, + WMT_OPID_HW_RST = 11, + WMT_OPID_SW_RST = 12, + WMT_OPID_BAUD_RST = 13, + WMT_OPID_STP_RST = 14, + WMT_OPID_THERM_CTRL = 15, + WMT_OPID_EFUSE_RW = 16, + WMT_OPID_GPIO_CTRL = 17, + WMT_OPID_SDIO_CTRL = 18, + WMT_OPID_FW_COREDMP = 19, + WMT_OPID_GPIO_STATE = 20, + WMT_OPID_BGW_DS = 21, + WMT_OPID_SET_MCU_CLK = 22, + WMT_OPID_ADIE_LPBK_TEST = 23, +#ifdef CONFIG_MTK_COMBO_ANT + WMT_OPID_ANT_RAM_DOWN = 24, + WMT_OPID_ANT_RAM_STA_GET = 25, +#endif +#if CFG_WMT_LTE_COEX_HANDLING + WMT_OPID_IDC_MSG_HANDLING = 26, +#endif + WMT_OPID_TRIGGER_STP_ASSERT = 27, + WMT_OPID_FLASH_PATCH_DOWN = 28, + WMT_OPID_FLASH_PATCH_VER_GET = 29, + WMT_OPID_UTC_TIME_SYNC = 30, + WMT_OPID_FW_LOG_CTRL = 31, + WMT_OPID_WLAN_PROBE = 32, + WMT_OPID_WLAN_REMOVE = 33, + WMT_OPID_GPS_MCU_CTRL = 34, + WMT_OPID_TRY_PWR_OFF = 35, + WMT_OPID_BLANK_STATUS_CTRL = 36, + WMT_OPID_MET_CTRL = 37, + WMT_OPID_GPS_SUSPEND = 38, + WMT_OPID_GET_CONSYS_STATE = 39, + WMT_OPID_MAX +} ENUM_WMT_OPID_T, *P_ENUM_WMT_OPID_T; + +typedef OSAL_OP_DAT WMT_OP; +typedef P_OSAL_OP_DAT P_WMT_OP; + +typedef enum _ENUM_WMT_UART_FC_T { + WMT_UART_NO_FC = 0, + WMT_UART_MTK_SW_FC = 1, + WMT_UART_LUX_SW_FC = 2, + WMT_UART_HW_FC = 3, + WMT_UART_MAX +} ENUM_WMT_UART_FC_T, *P_ENUM_UART_FC_T; + + +typedef struct _WMT_HIF_CONF { + UINT32 hifType; /* HIF Type */ + UINT32 uartFcCtrl; /* UART FC config */ + UINT32 au4HifConf[DWCNT_HIF_CONF]; /* HIF Config */ + UINT32 au4StrapConf[DWCNT_STRAP_CONF]; /* Strap Config */ +} WMT_HIF_CONF, *P_WMT_HIF_CONF; + +typedef INT32(*WMT_OPID_FUNC) (P_WMT_OP); + +struct WMT_BYTE_ARRAY { + UINT32 size; + PUINT8 data; +}; + +typedef struct _WMT_GEN_CONF { + UINT8 cfgExist; + + UINT8 coex_wmt_ant_mode; + UINT8 coex_wmt_ant_mode_ex; + UINT8 coex_wmt_ext_component; + UINT8 coex_wmt_wifi_time_ctl; + UINT8 coex_wmt_ext_pta_dev_on; + /*combo chip and LTE coex filter mode setting */ + UINT8 coex_wmt_filter_mode; + + UINT8 coex_bt_rssi_upper_limit; + UINT8 coex_bt_rssi_mid_limit; + UINT8 coex_bt_rssi_lower_limit; + UINT8 coex_bt_pwr_high; + UINT8 coex_bt_pwr_mid; + UINT8 coex_bt_pwr_low; + + UINT8 coex_wifi_rssi_upper_limit; + UINT8 coex_wifi_rssi_mid_limit; + UINT8 coex_wifi_rssi_lower_limit; + UINT8 coex_wifi_pwr_high; + UINT8 coex_wifi_pwr_mid; + UINT8 coex_wifi_pwr_low; + + UINT8 coex_ext_pta_hi_tx_tag; + UINT8 coex_ext_pta_hi_rx_tag; + UINT8 coex_ext_pta_lo_tx_tag; + UINT8 coex_ext_pta_lo_rx_tag; + UINT16 coex_ext_pta_sample_t1; + UINT16 coex_ext_pta_sample_t2; + UINT8 coex_ext_pta_wifi_bt_con_trx; + + UINT32 coex_misc_ext_pta_on; + UINT32 coex_misc_ext_feature_set; + /*GPS LNA setting */ + UINT8 wmt_gps_lna_pin; + UINT8 wmt_gps_lna_enable; + /*GPS HW suspend setting */ + UINT8 wmt_gps_suspend_ctrl; + /*Power on sequence */ + UINT8 pwr_on_rtc_slot; + UINT8 pwr_on_ldo_slot; + UINT8 pwr_on_rst_slot; + UINT8 pwr_on_off_slot; + UINT8 pwr_on_on_slot; + UINT8 co_clock_flag; + + /*deep sleep feature flag*/ + UINT8 disable_deep_sleep_cfg; + + /* Combo chip side SDIO driving setting */ + UINT32 sdio_driving_cfg; + + /* Combo chip WiFi path setting */ + UINT16 coex_wmt_wifi_path; + /* Combo chip WiFi eLAN gain setting */ + UINT8 coex_wmt_ext_elna_gain_p1_support; + UINT32 coex_wmt_ext_elna_gain_p1_D0; + UINT32 coex_wmt_ext_elna_gain_p1_D1; + UINT32 coex_wmt_ext_elna_gain_p1_D2; + UINT32 coex_wmt_ext_elna_gain_p1_D3; + PINT8 coex_wmt_antsel_invert_support; + UINT8 coex_wmt_ext_epa_mode; + + struct WMT_BYTE_ARRAY *coex_wmt_epa_elna; + + UINT8 bt_tssi_from_wifi; + UINT16 bt_tssi_target; + + UINT8 coex_config_bt_ctrl; + UINT8 coex_config_bt_ctrl_mode; + UINT8 coex_config_bt_ctrl_rw; + + UINT8 coex_config_addjust_opp_time_ratio; + UINT8 coex_config_addjust_opp_time_ratio_bt_slot; + UINT8 coex_config_addjust_opp_time_ratio_wifi_slot; + + UINT8 coex_config_addjust_ble_scan_time_ratio; + UINT8 coex_config_addjust_ble_scan_time_ratio_bt_slot; + UINT8 coex_config_addjust_ble_scan_time_ratio_wifi_slot; + + /* wifi ant swap feature */ + UINT8 wifi_ant_swap_mode; + UINT8 wifi_main_ant_polarity; + UINT8 wifi_ant_swap_ant_sel_gpio; + + struct WMT_BYTE_ARRAY *wifi_config; +} WMT_GEN_CONF, *P_WMT_GEN_CONF; + +typedef enum _ENUM_DRV_STS_ { +#if 0 + DRV_STS_INVALID = 0, + DRV_STS_UNREG = 1, /* Initial State */ +#endif + DRV_STS_POWER_OFF = 0, /* initial state */ + DRV_STS_POWER_ON = 1, /* powered on, only WMT */ + DRV_STS_FUNC_ON = 2, /* FUNC ON */ + DRV_STS_MAX +} ENUM_DRV_STS, *P_ENUM_DRV_STS; + +typedef enum _WMT_IC_PIN_ID_ { + WMT_IC_PIN_AUDIO = 0, + WMT_IC_PIN_EEDI = 1, + WMT_IC_PIN_EEDO = 2, + WMT_IC_PIN_GSYNC = 3, + WMT_IC_PIN_MAX +} WMT_IC_PIN_ID, *P_WMT_IC_PIN_ID; + + +typedef enum _WMT_IC_PIN_STATE_ { + WMT_IC_PIN_EN = 0, + WMT_IC_PIN_DIS = 1, + WMT_IC_AIF_0 = 2, /* = CMB_STUB_AIF_0, */ + WMT_IC_AIF_1 = 3, /* = CMB_STUB_AIF_1, */ + WMT_IC_AIF_2 = 4, /* = CMB_STUB_AIF_2, */ + WMT_IC_AIF_3 = 5, /* = CMB_STUB_AIF_3, */ + WMT_IC_PIN_MUX = 6, + WMT_IC_PIN_GPIO = 7, + WMT_IC_PIN_GPIO_HIGH = 8, + WMT_IC_PIN_GPIO_LOW = 9, + WMT_IC_PIN_STATE_MAX +} WMT_IC_PIN_STATE, *P_WMT_IC_PIN_STATE; + +typedef enum _WMT_CO_CLOCK_ { + WMT_CO_CLOCK_DIS = 0, + WMT_CO_CLOCK_EN = 1, + WMT_CO_CLOCK_DCXO = 2, + WMT_CO_CLOCK_MAX +} WMT_CO_CLOCK, *P_WMT_CO_CLOCK; + + +typedef INT32(*SW_INIT) (P_WMT_HIF_CONF pWmtHifConf); +typedef INT32(*SW_DEINIT) (P_WMT_HIF_CONF pWmtHifConf); +typedef INT32(*IC_PIN_CTRL) (WMT_IC_PIN_ID id, WMT_IC_PIN_STATE state, UINT32 flag); +typedef INT32(*IC_VER_CHECK) (VOID); +typedef INT32(*CO_CLOCK_CTRL) (WMT_CO_CLOCK on); +typedef MTK_WCN_BOOL(*IS_QUICK_SLEEP_SUPPORT) (VOID); +typedef MTK_WCN_BOOL(*IS_AEE_DUMP_SUPPORT) (VOID); +typedef MTK_WCN_BOOL(*TRIGGER_STP_ASSERT) (VOID); +typedef MTK_WCN_BOOL(*DEEP_SLEEP_CONTROL) (INT32 value); + + +typedef struct _WMT_IC_OPS_ { + UINT32 icId; + UINT64 options; + SW_INIT sw_init; + SW_DEINIT sw_deinit; + IC_PIN_CTRL ic_pin_ctrl; + IC_VER_CHECK ic_ver_check; + CO_CLOCK_CTRL co_clock_ctrl; + IS_QUICK_SLEEP_SUPPORT is_quick_sleep; + IS_AEE_DUMP_SUPPORT is_aee_dump_support; + TRIGGER_STP_ASSERT trigger_stp_assert; + DEEP_SLEEP_CONTROL deep_sleep_ctrl; +} WMT_IC_OPS, *P_WMT_IC_OPS; + +typedef struct _WMT_CTX_ { + ENUM_DRV_STS eDrvStatus[WMTDRV_TYPE_MAX]; /* Controlled driver status */ + UINT32 wmtInfoBit; /* valid info bit */ + WMT_HIF_CONF wmtHifConf; /* HIF information */ + + /* Pointer to WMT_IC_OPS. Shall be assigned to a correct table in stp_init + * if and only if getting chip id successfully. hwver and fwver are kept in + * WMT-IC module only. + */ + P_WMT_IC_OPS p_ic_ops; + UINT32 wmtBlankStatus; /* Controlled blank status */ +} WMT_CTX, *P_WMT_CTX; + +/* TODO:[ChangeFeature][George] remove WMT_PKT. replace it with hardcoded arrays. */ +/* Using this struct relies on compiler's implementation and pack() settings */ +typedef struct _WMT_PKT_ { + UINT8 eType; /* WMT_PKT_TYPE_* */ + UINT8 eOpCode; /* OPCODE_* */ + UINT16 u2SduLen; /* 2 bytes length, little endian */ + UINT8 aucParam[32]; +} WMT_PKT, *P_WMT_PKT; + +/* WMT Packet Format */ +typedef enum _ENUM_WMT_PKT_TYPE { + WMT_PKT_TYPE_INVALID = 0, + WMT_PKT_TYPE_CMD = 1, + WMT_PKT_TYPE_EVENT = 2, + WMT_PKT_TYPE_MAX +} ENUM_WMT_PKT_TYPE, *P_ENUM_WMT_PKT_TYPE; + +typedef enum _ENUM_OPCODE { + OPCODE_INVALID = 0, + OPCODE_PATCH = 1, + OPCODE_TEST = 2, + OPCODE_WAKEUP = 3, + OPCODE_HIF = 4, + OPCODE_STRAP_CONF = 5, + OPCODE_FUNC_CTRL = 6, + OPCODE_RESET = 7, + OPCODE_INT = 8, + OPCODE_MAX +} ENUM_OPCODE, *P_ENUM_OPCODE; + +typedef enum { + WMT_STP_CONF_EN = 0, + WMT_STP_CONF_RDY = 1, + WMT_STP_CONF_MODE = 2, + WMT_STP_CONF_MAX +} WMT_STP_CONF_TYPE; + +struct init_script { + PUINT8 cmd; + UINT32 cmdSz; + PUINT8 evt; + UINT32 evtSz; + PUINT8 str; +}; + +typedef struct _WMT_PATCH { + UINT8 ucDateTime[16]; + UINT8 ucPLat[4]; + UINT16 u2HwVer; + UINT16 u2SwVer; + UINT32 u4PatchVer; +} WMT_PATCH, *P_WMT_PATCH; + +struct wmt_rom_patch { + UINT8 ucDateTime[16]; + UINT8 ucPLat[4]; + UINT16 u2HwVer; + UINT16 u2SwVer; + UINT32 u4PatchAddr; + UINT32 u4PatchType; + UINT32 u4CRC[4]; +}; + + +#define WMT_CORE_DMP_CPUPCR_NUM 10 +enum wmt_consys_dump_status { + WMT_DUMP_STATE_NONE = 0, + WMT_DUMP_STATE_SCHEDULED = 1, + WMT_DUMP_STATE_ONGOING = 2 +}; + +typedef struct consys_state_dmp_info { + UINT32 cpu_pcr[WMT_CORE_DMP_CPUPCR_NUM]; + CONSYS_STATE state; +} CONSYS_STATE_DMP_INFO, *P_CONSYS_STATE_DMP_INFO; + +typedef struct consys_state_dmp_op { + enum wmt_consys_dump_status status; + OSAL_SLEEPABLE_LOCK lock; + UINT32 times; + UINT32 cpu_sleep_ms; + CONSYS_STATE_DMP_INFO dmp_info; + ULONG version; +} CONSYS_STATE_DMP_OP, *P_CONSYS_STATE_DMP_OP; + + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +extern INT32 wmt_core_init(VOID); +extern INT32 wmt_core_deinit(VOID); + +/***************************************************************************** +* FUNCTION +* mtk_wcn_wmtd +* DESCRIPTION +* deinit STP kernel +* PARAMETERS +* void +* RETURNS +* INT32 0 = success, others = failure +*****************************************************************************/ +extern INT32 wmt_core_opid(P_WMT_OP pWmtOp); + +extern INT32 wmt_core_ctrl(ENUM_WMT_CTRL_T ctrId, PULONG pPa1, PULONG pPa2); + +extern INT32 wmt_core_func_ctrl_cmd(ENUM_WMTDRV_TYPE_T type, MTK_WCN_BOOL fgEn); + +extern INT32 wmt_core_reg_rw_raw(UINT32 isWrite, UINT32 offset, PUINT32 pVal, UINT32 mask); + +extern VOID wmt_core_dump_data(PUINT8 pData, PUINT8 pTitle, UINT32 len); + +extern MTK_WCN_BOOL wmt_core_patch_check(UINT32 u4PatchVer, UINT32 u4HwVer); + +extern INT32 wmt_core_init_script_retry(struct init_script *script, INT32 count, INT32 retry, INT32 dump_err_log); + +extern INT32 wmt_core_init_script(struct init_script *script, INT32 count); + +extern INT32 wmt_core_rx(PUINT8 pBuf, UINT32 bufLen, PUINT32 readSize); + +extern INT32 +wmt_core_tx(const PUINT8 pData, UINT32 size, PUINT32 writtenSize, MTK_WCN_BOOL bRawFlag); +extern MTK_WCN_BOOL wmt_core_is_quick_ps_support(VOID); + +extern MTK_WCN_BOOL wmt_core_get_aee_dump_flag(VOID); +extern MTK_WCN_BOOL wmt_core_trigger_stp_assert(VOID); +#ifdef CONFIG_MTK_COMBO_CHIP_DEEP_SLEEP_SUPPORT +extern MTK_WCN_BOOL wmt_core_deep_sleep_ctrl(INT32 value); +#endif +extern VOID wmt_core_set_coredump_state(ENUM_DRV_STS state); + +#if CFG_CORE_INTERNAL_TXRX +extern INT32 wmt_core_lpbk_do_stp_init(void); +extern INT32 wmt_core_lpbk_do_stp_deinit(void); +#endif + +extern VOID wmt_core_set_coredump_state(ENUM_DRV_STS state); +extern ENUM_DRV_STS wmt_core_get_drv_status(ENUM_WMTDRV_TYPE_T type); +#if CFG_WMT_LTE_COEX_HANDLING +extern VOID wmt_core_set_flag_for_test(UINT32 enable); +extern UINT32 wmt_core_get_flag_for_test(VOID); +#endif + +#if CFG_CORE_MT6620_SUPPORT +extern WMT_IC_OPS wmt_ic_ops_mt6620; +#endif + +#if CFG_CORE_MT6628_SUPPORT +extern WMT_IC_OPS wmt_ic_ops_mt6628; +#endif + +#if CFG_CORE_MT6630_SUPPORT +extern WMT_IC_OPS wmt_ic_ops_mt6630; +#endif + +#if CFG_CORE_MT6632_SUPPORT +extern WMT_IC_OPS wmt_ic_ops_mt6632; +#endif + +#if CFG_CORE_SOC_SUPPORT +extern WMT_IC_OPS wmt_ic_ops_soc; +#endif + +extern P_WMT_GEN_CONF wmt_get_gen_conf_pointer(VOID); + +VOID wmt_core_set_blank_status(UINT32 on_off_flag); +extern UINT32 wmt_core_get_blank_status(VOID); + +INT32 wmt_blank_status_ctrl(UINT32 on_off_flag); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +static _osal_inline_ MTK_WCN_BOOL wmt_core_ic_ops_check(P_WMT_IC_OPS p_ops) +{ + if (!p_ops) + return MTK_WCN_BOOL_FALSE; + if ((p_ops->sw_init == NULL) + || (p_ops->sw_deinit == NULL) + || (p_ops->ic_ver_check == NULL) + || (p_ops->ic_pin_ctrl == NULL)) { + return MTK_WCN_BOOL_FALSE; + } + return MTK_WCN_BOOL_TRUE; +} + +#endif /* _WMT_CORE_H_ */ diff --git a/drivers/misc/mediatek/connectivity/common/common_main/core/include/wmt_ctrl.h b/drivers/misc/mediatek/connectivity/common/common_main/core/include/wmt_ctrl.h new file mode 100644 index 0000000000000000000000000000000000000000..6bb71ba0e2fd3f76989fb2f71c408fa3b607a1d3 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/core/include/wmt_ctrl.h @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + + + +#ifndef _WMT_CTRL_H_ +#define _WMT_CTRL_H_ + +#include "osal.h" +#include "stp_exp.h" +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +#define DWCNT_CTRL_DATA (16) + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + + + + + + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + + + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +typedef struct _WMT_CTRL_DATA_ { + UINT32 ctrlId; + SIZE_T au4CtrlData[DWCNT_CTRL_DATA]; +} WMT_CTRL_DATA, *P_WMT_CTRL_DATA; + +typedef enum _ENUM_WMT_CTRL_T { + WMT_CTRL_HW_PWR_OFF = 0, /* whole chip power off */ + WMT_CTRL_HW_PWR_ON = 1, /* whole chip power on */ + WMT_CTRL_HW_RST = 2, /* whole chip reset */ + WMT_CTRL_STP_CLOSE = 3, + WMT_CTRL_STP_OPEN = 4, + WMT_CTRL_STP_CONF = 5, + WMT_CTRL_FREE_PATCH = 6, + WMT_CTRL_GET_PATCH = 7, + WMT_CTRL_GET_PATCH_NAME = 8, + WMT_CTRL_HOST_BAUDRATE_SET = 9, + WMT_CTRL_SDIO_HW = 10, /* enable/disable SDIO1/2 of combo chip */ + WMT_CTRL_SDIO_FUNC = 11, /* probe/remove STP/Wi-Fi driver in SDIO1/2 of combo chip */ + WMT_CTRL_HWIDVER_SET = 12, /* TODO: rename this and add chip id information in addition to chip version */ + WMT_CTRL_HWVER_GET = 13, /* TODO: [FixMe][GeorgeKuo] remove unused functions */ + WMT_CTRL_STP_RST = 14, + WMT_CTRL_GET_WMT_CONF = 15, + WMT_CTRL_TX = 16, /* [FixMe][GeorgeKuo]: to be removed by Sean's stp integration */ + WMT_CTRL_RX = 17, /* [FixMe][GeorgeKuo]: to be removed by Sean's stp integration */ + WMT_CTRL_RX_FLUSH = 18, /* [FixMe][SeanWang]: to be removed by Sean's stp integration */ + WMT_CTRL_GPS_SYNC_SET = 19, + WMT_CTRL_GPS_LNA_SET = 20, + WMT_CTRL_PATCH_SEARCH = 21, + WMT_CTRL_CRYSTAL_TRIMING_GET = 22, + WMT_CTRL_CRYSTAL_TRIMING_PUT = 23, + WMT_CTRL_HW_STATE_DUMP = 24, + WMT_CTRL_GET_PATCH_NUM = 25, + WMT_CTRL_GET_PATCH_INFO = 26, + WMT_CTRL_SOC_PALDO_CTRL = 27, + WMT_CTRL_SOC_WAKEUP_CONSYS = 28, + WMT_CTRL_SET_STP_DBG_INFO = 29, + WMT_CTRL_BGW_DESENSE_CTRL = 30, + WMT_CTRL_TRG_ASSERT = 31, +#if CFG_WMT_LTE_COEX_HANDLING + WMT_CTRL_GET_TDM_REQ_ANTSEL = 32, +#endif + WMT_CTRL_EVT_PARSER = 33, + WMT_CTRL_GET_ROM_PATCH_INFO = 34, + WMT_CTRL_UPDATE_PATCH_VERSION = 35, + WMT_CTRL_MAX +} ENUM_WMT_CTRL_T, *P_ENUM_WMT_CTRL_T; + +typedef INT32(*WMT_CTRL_FUNC) (P_WMT_CTRL_DATA); + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + + + + + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +extern INT32 wmt_ctrl(P_WMT_CTRL_DATA pWmtCtrlData); + +extern INT32 +wmt_ctrl_tx_ex(const PUINT8 pData, + const UINT32 size, PUINT32 writtenSize, const MTK_WCN_BOOL bRawFlag); + + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + + + +#endif /* _WMT_CTRL_H_ */ diff --git a/drivers/misc/mediatek/connectivity/common/common_main/core/include/wmt_func.h b/drivers/misc/mediatek/connectivity/common/common_main/core/include/wmt_func.h new file mode 100644 index 0000000000000000000000000000000000000000..9145bb205ba8c887f876734c585950d7f114e38c --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/core/include/wmt_func.h @@ -0,0 +1,169 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + + +#ifndef _WMT_FUNC_H_ +#define _WMT_FUNC_H_ + +#include "wmt_core.h" +#include "wmt_plat.h" +#include "osal.h" +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +#if 1 /* defined(CONFIG_MTK_COMBO_HCI_DRIVER) || defined(CONFIG_MTK_COMBO_BT) */ +#define CFG_FUNC_BT_SUPPORT 1 +#else +#define CFG_FUNC_BT_SUPPORT 0 +#endif + + +#if IS_ENABLED(CONFIG_MTK_FMRADIO) +#define CFG_FUNC_FM_SUPPORT 1 +#else +#define CFG_FUNC_FM_SUPPORT 0 +#endif + +#if IS_ENABLED(CONFIG_MTK_COMBO_GPS) +#define CFG_FUNC_GPS_SUPPORT 1 +#define CFG_FUNC_GPSL5_SUPPORT 1 +#else +#define CFG_FUNC_GPS_SUPPORT 0 +#define CFG_FUNC_GPSL5_SUPPORT 0 +#endif + +#if 1 /* IS_ENABLED(CONFIG_MTK_COMBO_WIFI) */ +#define CFG_FUNC_WIFI_SUPPORT 1 +#else +#define CFG_FUNC_WIFI_SUPPORT 0 +#endif + +#if 1 +#define CFG_FUNC_ANT_SUPPORT 1 +#else +#define CFG_FUNC_ANT_SUPPORT 0 +#endif + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +typedef INT32 (*SUBSYS_FUNC_ON)(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); +typedef INT32 (*SUBSYS_FUNC_OFF)(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); + +typedef struct _WMT_FUNC_OPS_ { + SUBSYS_FUNC_ON func_on; + SUBSYS_FUNC_OFF func_off; +} WMT_FUNC_OPS, *P_WMT_FUNC_OPS; + +typedef struct _CMB_PIN_CTRL_REG_ { + UINT32 regAddr; + UINT32 regValue; + UINT32 regMask; + +} CMB_PIN_CTRL_REG, *P_CMB_PIN_CTRL_REG; + +typedef struct _CMB_PIN_CTRL_ { + UINT32 pinId; + UINT32 regNum; + P_CMB_PIN_CTRL_REG pFuncOnArray; + P_CMB_PIN_CTRL_REG pFuncOffArray; + +} CMB_PIN_CTRL, *P_CMB_PIN_CTRL; + +typedef enum _ENUM_CMP_PIN_ID_ { + CMB_PIN_EEDI_ID = 0, + CMB_PIN_EEDO_ID = 1, + CMB_PIN_GSYNC_ID = 2, +} ENUM_CMP_PIN_ID, *P_ENUM_CMP_PIN_ID; + + + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +#if CFG_FUNC_BT_SUPPORT +extern WMT_FUNC_OPS wmt_func_bt_ops; +#endif + +#if CFG_FUNC_FM_SUPPORT +extern WMT_FUNC_OPS wmt_func_fm_ops; +#endif + +#if CFG_FUNC_GPS_SUPPORT +extern WMT_FUNC_OPS wmt_func_gps_ops; +#endif + +#if CFG_FUNC_GPSL5_SUPPORT +extern WMT_FUNC_OPS wmt_func_gpsl5_ops; +#endif + +#if CFG_FUNC_WIFI_SUPPORT +extern WMT_FUNC_OPS wmt_func_wifi_ops; +#endif + +#if CFG_FUNC_ANT_SUPPORT +extern WMT_FUNC_OPS wmt_func_ant_ops; +#endif + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + + + + + + + +#endif /* _WMT_FUNC_H_ */ diff --git a/drivers/misc/mediatek/connectivity/common/common_main/core/include/wmt_ic.h b/drivers/misc/mediatek/connectivity/common/common_main/core/include/wmt_ic.h new file mode 100644 index 0000000000000000000000000000000000000000..aa44dff600b4831ddad6cc9f66a4ac5d98af211c --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/core/include/wmt_ic.h @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + + + +#ifndef _WMT_IC_H_ +#define _WMT_IC_H_ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +#include "wmt_core.h" +#include "wmt_exp.h" + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +#define WMT_IC_NAME_MT6620 "MT6620" +#define WMT_IC_NAME_MT6628 "MT6628" +#define WMT_IC_NAME_MT6630 "MT6630" +#define WMT_IC_NAME_MT6632 "MT6632" +#define WMT_IC_NAME_DEFAULT "SOC_CONSYS" + +#define WMT_IC_VER_E1 "E1" +#define WMT_IC_VER_E2 "E2" +#define WMT_IC_VER_E3 "E3" +#define WMT_IC_VER_E4 "E4" +#define WMT_IC_VER_E5 "E5" +#define WMT_IC_VER_E6 "E6" +#define WMT_IC_VER_E7 "E7" + +#define WMT_IC_PATCH_DUMMY_EXT "_ex" +#define WMT_IC_PATCH_NO_EXT "" +#define WMT_IC_PATCH_E1_EXT "_e1" +#define WMT_IC_PATCH_E2_EXT "_e2" +#define WMT_IC_PATCH_E3_EXT "_e3" +#define WMT_IC_PATCH_E4_EXT "_e4" +#define WMT_IC_PATCH_E5_EXT "_e5" +#define WMT_IC_PATCH_E6_EXT "_e6" + +#define WMT_IC_PATCH_TAIL "_hdr.bin" + +#define WMT_IC_INVALID_CHIP_ID 0xFFFF + +#define MAJORNUM(x) (x & 0x00F0) +#define MINORNUM(x) (x & 0x000F) + +/******************************************************************************* +* R E G I S T E R M A P +******************************************************************************** +*/ +/* General definition used for ALL/UNKNOWN CHIPS */ +/* Now MT6620 uses these definitions */ +#define GEN_CONFG_BASE (0x80000000UL) +#define GEN_HVR (GEN_CONFG_BASE + 0x0UL) /* HW_VER */ +#define GEN_FVR (GEN_CONFG_BASE + 0x4UL) /* FW_VER */ +#define GEN_VER_MASK (0x0000FFFFUL) /* HW_VER and FW_VER valid bits mask */ +#define GEN_HCR (GEN_CONFG_BASE + 0x8UL) /* HW_CODE, chip id */ +#define GEN_HCR_MASK (0x0000FFFFUL) /* HW_CODE valid bits mask */ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +typedef struct _WMT_IC_INFO_S { + UINT32 u4HwVer; /* u4HwId */ + PUINT8 cChipName; + PUINT8 cChipVersion; + PUINT8 cPatchNameExt; + MTK_WCN_BOOL bPsmSupport; + MTK_WCN_BOOL bWorkWithoutPatch; +} WMT_IC_INFO_S, *P_WMT_IC_INFO_S; + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +INT32 mtk_wcn_soc_rom_patch_dwn(UINT32 ip_ver, UINT32 fw_ver); +VOID mtk_wcn_soc_restore_wifi_cal_result(VOID); + +#endif /* _WMT_IC_H_ */ diff --git a/drivers/misc/mediatek/connectivity/common/common_main/core/include/wmt_lib.h b/drivers/misc/mediatek/connectivity/common/common_main/core/include/wmt_lib.h new file mode 100644 index 0000000000000000000000000000000000000000..afec898f8d5318109dd6b47b25f5f8f532314bb2 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/core/include/wmt_lib.h @@ -0,0 +1,493 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + + + +#ifndef _WMT_LIB_H_ +#define _WMT_LIB_H_ + + +#include "wmt_core.h" +#include "wmt_exp.h" +#include +#include "stp_wmt.h" +#include "wmt_plat.h" +#include "wmt_idc.h" +#include "osal.h" +#include "mtk_wcn_consys_hw.h" + + + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ +#define USE_NEW_PROC_FS_FLAG 1 + + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +#define WMT_OP_BUF_SIZE (16) +#if 0 /* moved to wmt_exp.h */ +#define WMT_LOG_LOUD 4 +#define WMT_LOG_DBG 3 +#define WMT_LOG_INFO 2 +#define WMT_LOG_WARN 1 +#define WMT_LOG_ERR 0 +#endif +typedef enum _ENUM_WMTRSTRET_TYPE_T { + WMTRSTRET_SUCCESS = 0x0, + WMTRSTRET_FAIL = 0x1, + WMTRSTRET_ONGOING = 0x2, + WMTRSTRET_RETRY = 0x3, + WMTRSTRET_MAX +} ENUM_WMTRSTRET_TYPE_T, *P_ENUM_WMTRSTRET_TYPE_T; + +#define MAX_ANT_RAM_CODE_DOWN_TIME 3000 +/* +*3(retry times) * 180 (STP retry time out) +*+ 10 (firmware process time) + +*10 (transmit time) + +*10 (uart process -> WMT response pool) + +*230 (others) +*/ +#define WMT_LIB_RX_TIMEOUT 2000 /*800-->cover v1.2phone BT function on time (~830ms) */ +/* Since GPS timeout is 6 seconds */ +#define WMT_LIB_RX_EXTEND_TIMEOUT 4000 +/* +*open wifi during wifi power on procedure +*(because wlan is insert to system after mtk_hif_sdio module, +*so wifi card is not registered to hif module +*when mtk_wcn_wmt_func_on is called by wifi through rfkill) +*/ +#define MAX_WIFI_ON_TIME 5500 + +#define WMT_PWRON_RTY_DFT 2 +#define MAX_RETRY_TIME_DUE_TO_RX_TIMEOUT (WMT_PWRON_RTY_DFT * WMT_LIB_RX_TIMEOUT) +#define MAX_EACH_FUNC_ON_WHEN_CHIP_POWER_ON_ALREADY WMT_LIB_RX_TIMEOUT /*each WMT command */ +#define MAX_FUNC_ON_TIME (MAX_WIFI_ON_TIME + MAX_RETRY_TIME_DUE_TO_RX_TIMEOUT +\ + MAX_EACH_FUNC_ON_WHEN_CHIP_POWER_ON_ALREADY * 3 + MAX_ANT_RAM_CODE_DOWN_TIME) + +/*1000->WMT_LIB_RX_TIMEOUT + 1000, logical judgement */ +#define MAX_EACH_FUNC_OFF (WMT_LIB_RX_TIMEOUT + 1000) +#define MAX_FUNC_OFF_TIME (MAX_EACH_FUNC_OFF * 4) + +/*1000->WMT_LIB_RX_TIMEOUT + 1000, logical judgement */ +#define MAX_EACH_WMT_CMD (WMT_LIB_RX_TIMEOUT + 1000) + +/* For WMT OP who will have trouble if timeout really happens */ +#define MAX_WMT_OP_TIMEOUT (30000) + +#define MAX_GPIO_CTRL_TIME (2000) /* [FixMe][GeorgeKuo] a temp value */ + +#define UTC_SYNC_TIME (60 * 60 * 1000) + +#define WMT_IDC_MSG_BUFFER 2048 +#define WMT_IDC_MSG_MAX_SIZE (WMT_IDC_MSG_BUFFER - 7) /* Subtract STP payload cmd size */ + +#define MAX_PATCH_NUM (10) + +#define WMT_FIRMWARE_VERSION_LENGTH (14) +#define WMT_FIRMWARE_MAX_FILE_NAME_LENGTH (50) + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/* AIF FLAG definition */ +/* bit(0): share pin or not */ +#define WMT_LIB_AIF_FLAG_MASK (0x1UL) +#define WMT_LIB_AIF_FLAG_SHARE (0x1UL << 0) +#define WMT_LIB_AIF_FLAG_SEPARATE (0x0UL << 0) + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/* bit field offset definition */ +typedef enum { + WMT_STAT_PWR = 0, /* is powered on */ + WMT_STAT_STP_REG = 1, /* is STP driver registered: */ + WMT_STAT_STP_OPEN = 2, /* is STP opened: default FALSE */ + WMT_STAT_STP_EN = 3, /* is STP enabled: default FALSE */ + WMT_STAT_STP_RDY = 4, /* is STP ready for client: default FALSE */ + WMT_STAT_RX = 5, /* is rx data available */ + WMT_STAT_CMD = 6, /* is cmd string to be read */ + WMT_STAT_SDIO1_ON = 7, /* is SDIO1 on */ + WMT_STAT_SDIO2_ON = 8, /* is SDIO2 on */ + WMT_STAT_SDIO_WIFI_ON = 9, /* is Wi-Fi SDIO function on */ + WMT_STAT_SDIO_STP_ON = 10, /* is STP SDIO function on */ + WMT_STAT_RST_ON = 11, + WMT_STAT_MAX +} WMT_STAT; + +typedef enum _ENUM_WMTRSTSRC_TYPE_T { + WMTRSTSRC_RESET_BT = 0x0, + WMTRSTSRC_RESET_FM = 0x1, + WMTRSTSRC_RESET_GPS = 0x2, + WMTRSTSRC_RESET_WIFI = 0x3, + WMTRSTSRC_RESET_STP = 0x4, + WMTRSTSRC_RESET_TEST = 0x5, + WMTRSTSRC_RESET_MAX +} ENUM_WMTRSTSRC_TYPE_T, *P_ENUM_WMTRSTSRC_TYPE_T; + +enum wmt_fw_log_type { + WMT_FWLOG_MCU = 0, + WMT_FWLOG_MAX +}; + +typedef struct { + PF_WMT_CB fDrvRst[WMTDRV_TYPE_MAX]; +} WMT_FDRV_CB, *P_WMT_FDRV_CB; + + +typedef struct { + UINT32 dowloadSeq; + UINT8 addRess[4]; + UINT8 patchName[256]; +} WMT_PATCH_INFO, *P_WMT_PATCH_INFO; + +struct wmt_rom_patch_info { + UINT32 type; + UINT8 addRess[4]; + UINT8 patchName[256]; +}; + +struct wmt_vendor_patch { + union { + INT32 id; + INT32 type; + }; + UINT8 file_name[WMT_FIRMWARE_MAX_FILE_NAME_LENGTH + 1]; + UINT8 version[WMT_FIRMWARE_VERSION_LENGTH + 1]; +}; + +struct vendor_patch_table { + UINT32 capacity; + UINT32 num; + INT8 status; + INT8 need_update; + PUINT8 *active_version; + struct wmt_vendor_patch *patch; +}; + +enum wmt_patch_type { + WMT_PATCH_TYPE_ROM = 0, + WMT_PATCH_TYPE_RAM, + WMT_PATCH_TYPE_WIFI +}; + +enum wmt_cp_status { + WMT_CP_INIT = 0, + WMT_CP_READY_TO_CHECK, + WMT_CP_CHECK_DONE +}; + +#define WMT_LIB_DMP_SLOT 2 +struct consys_state_dmp_req { + struct consys_state_dmp_op consys_ops[WMT_LIB_DMP_SLOT]; + atomic_t version; +}; + +/* OS independent wrapper for WMT_OP */ +typedef struct _DEV_WMT_ { + + OSAL_SLEEPABLE_LOCK psm_lock; + OSAL_SLEEPABLE_LOCK idc_lock; + OSAL_SLEEPABLE_LOCK wlan_lock; + OSAL_SLEEPABLE_LOCK assert_lock; + OSAL_SLEEPABLE_LOCK mpu_lock; + OSAL_SLEEPABLE_LOCK power_lock; + /* WMTd thread information */ + /* struct task_struct *pWmtd; *//* main thread (wmtd) handle */ + OSAL_THREAD thread; + /* wait_queue_head_t rWmtdWq; *//*WMTd command wait queue */ + OSAL_EVENT rWmtdWq; /* rename */ + OSAL_THREAD worker_thread; + OSAL_EVENT rWmtdWorkerWq; + /* ULONG state; *//* bit field of WMT_STAT */ + OSAL_BIT_OP_VAR state; + + /* STP context information */ + /* wait_queue_head_t rWmtRxWq; *//* STP Rx wait queue */ + OSAL_EVENT rWmtRxWq; /* rename */ + /* WMT_STP_FUNC rStpFunc; *//* STP functions */ + WMT_FDRV_CB rFdrvCb; + + /* WMT Configurations */ + WMT_HIF_CONF rWmtHifConf; + WMT_GEN_CONF rWmtGenConf; + + /* Patch information */ + UINT8 cPatchName[NAME_MAX + 1]; + UINT8 cFullPatchName[NAME_MAX + 1]; + UINT32 patchNum; + + const osal_firmware *pPatch; + + UINT8 cWmtcfgName[NAME_MAX + 1]; + + const osal_firmware *pWmtCfg; + + const osal_firmware *pNvram; + + /* Current used UART port description */ + INT8 cUartName[NAME_MAX + 1]; + + OSAL_OP_Q rFreeOpQ; /* free op queue */ + OSAL_OP_Q rActiveOpQ; /* active op queue */ + OSAL_OP_Q rWorkerOpQ; + OSAL_OP arQue[WMT_OP_BUF_SIZE]; /* real op instances */ + P_OSAL_OP pCurOP; /* current op */ + P_OSAL_OP pWorkerOP; /* current op on worker thread */ + + /* cmd str buffer */ + UINT8 cCmd[NAME_MAX + 1]; + INT32 cmdResult; +/* struct completion cmd_comp; */ + /* wait_queue_head_t cmd_wq; *//* read command queues */ + OSAL_SIGNAL cmdResp; + OSAL_EVENT cmdReq; + + /* WMT loopback Thread Information */ +/* WMT_CMB_VER combo_ver; */ + /* P_WMT_CMB_CHIP_INFO_S pChipInfo; */ + UINT32 chip_id; + UINT32 hw_ver; + UINT32 fw_ver; + UINT32 ip_ver; + + UINT32 ext_ldo_flag; + P_WMT_PATCH_INFO pWmtPatchInfo; + struct wmt_rom_patch_info *pWmtRomPatchInfo[WMTDRV_TYPE_ANT]; + /* MET thread information */ + OSAL_THREAD met_thread; + INT32 met_log_ctrl; + /* Timer to sync UTC time with connsys */ + OSAL_TIMER utc_sync_timer; + struct work_struct utcSyncWorker; + /* Timer for wmt_worker_thread */ + OSAL_TIMER worker_timer; + struct work_struct wmtd_worker_thread_work; + struct osal_op_history wmtd_op_history; + struct osal_op_history worker_op_history; + UINT8 msg_local_buffer[WMT_IDC_MSG_BUFFER]; + struct vendor_patch_table patch_table; + + struct consys_state_dmp_req state_dmp_req; + +} DEV_WMT, *P_DEV_WMT; + + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +extern DEV_WMT gDevWmt; +extern INT32 wmt_lib_init(VOID); +extern INT32 wmt_lib_deinit(VOID); +extern INT32 wmt_lib_tx(PUINT8 data, UINT32 size, PUINT32 writtenSize); +extern INT32 wmt_lib_tx_raw(PUINT8 data, UINT32 size, PUINT32 writtenSize); +extern INT32 wmt_lib_rx(PUINT8 buff, UINT32 buffLen, PUINT32 readSize); +extern VOID wmt_lib_flush_rx(VOID); +extern UINT32 wmt_lib_co_clock_flag_get(VOID); +extern INT32 wmt_lib_sdio_reg_rw(INT32 func_num, INT32 direction, UINT32 offset, UINT32 value); + + +#if WMT_PLAT_ALPS +extern PINT8 wmt_uart_port_desc; /* defined in mtk_wcn_cmb_stub_alps.cpp */ +#endif + +#if CFG_WMT_PS_SUPPORT +extern INT32 wmt_lib_ps_set_idle_time(UINT32 psIdleTime); +extern INT32 wmt_lib_ps_init(VOID); +extern INT32 wmt_lib_ps_deinit(VOID); +extern INT32 wmt_lib_ps_enable(VOID); +extern INT32 wmt_lib_ps_ctrl(UINT32 state); + +extern INT32 wmt_lib_ps_disable(VOID); +extern VOID wmt_lib_ps_irq_cb(VOID); +#endif +extern VOID wmt_lib_ps_set_sdio_psop(PF_WMT_SDIO_PSOP own_cb); +#ifdef CONFIG_MTK_COMBO_CHIP_DEEP_SLEEP_SUPPORT +extern VOID wmt_lib_sdio_deep_sleep_flag_set_cb_reg(PF_WMT_SDIO_DEEP_SLEEP flag_cb); +#endif +extern VOID wmt_lib_sdio_reg_rw_cb(PF_WMT_SDIO_DEBUG reg_rw_cb); +extern INT32 wmt_lib_register_thermal_ctrl_cb(thermal_query_ctrl_cb thermal_ctrl); +extern INT32 wmt_lib_register_trigger_assert_cb(trigger_assert_cb trigger_assert); + +/* LXOP functions: */ +extern P_OSAL_OP wmt_lib_get_free_op(VOID); +extern INT32 wmt_lib_put_op_to_free_queue(P_OSAL_OP pOp); +extern MTK_WCN_BOOL wmt_lib_put_act_op(P_OSAL_OP pOp); +extern MTK_WCN_BOOL wmt_lib_put_worker_op(P_OSAL_OP pOp); + +/* extern ENUM_WMTHWVER_TYPE_T wmt_lib_get_hwver (VOID); */ +extern UINT32 wmt_lib_get_icinfo(ENUM_WMT_CHIPINFO_TYPE_T type); + +extern MTK_WCN_BOOL wmt_lib_is_therm_ctrl_support(ENUM_WMTTHERM_TYPE_T eType); +extern MTK_WCN_BOOL wmt_lib_is_dsns_ctrl_support(VOID); +extern INT32 wmt_lib_trigger_cmd_signal(INT32 result); +extern PUINT8 wmt_lib_get_cmd(VOID); +extern P_OSAL_EVENT wmt_lib_get_cmd_event(VOID); +extern INT32 wmt_lib_set_patch_name(PUINT8 cPatchName); +extern INT32 wmt_lib_set_uart_name(PINT8 cUartName); +extern INT32 wmt_lib_set_hif(ULONG hifconf); +extern P_WMT_HIF_CONF wmt_lib_get_hif(VOID); +extern MTK_WCN_BOOL wmt_lib_get_cmd_status(VOID); + +/* GeorgeKuo: replace set_chip_gpio() with more specific ones */ +#if 0 /* moved to wmt_exp.h */ +extern INT32 wmt_lib_set_aif(enum CMB_STUB_AIF_X aif, MTK_WCN_BOOL share); /* set AUDIO interface options */ +#endif +extern INT32 wmt_lib_host_awake_get(VOID); +extern INT32 wmt_lib_host_awake_put(VOID); +extern UINT32 wmt_lib_dbg_level_set(UINT32 level); +#ifdef CONFIG_MTK_COMBO_CHIP_DEEP_SLEEP_SUPPORT +extern INT32 wmt_lib_deep_sleep_ctrl(INT32 value); +extern MTK_WCN_BOOL wmt_lib_deep_sleep_flag_set(MTK_WCN_BOOL flag); +#endif +extern INT32 wmt_lib_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb); + +extern INT32 wmt_lib_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType); +ENUM_WMTRSTRET_TYPE_T wmt_lib_cmb_rst(ENUM_WMTRSTSRC_TYPE_T src); +MTK_WCN_BOOL wmt_lib_sw_rst(INT32 baudRst); +MTK_WCN_BOOL wmt_lib_hw_rst(VOID); +INT32 wmt_lib_reg_rw(UINT32 isWrite, UINT32 offset, PUINT32 pvalue, UINT32 mask); +INT32 wmt_lib_efuse_rw(UINT32 isWrite, UINT32 offset, PUINT32 pvalue, UINT32 mask); +INT32 wmt_lib_sdio_ctrl(UINT32 on); +INT32 wmt_lib_met_ctrl(INT32 met_ctrl, INT32 log_ctrl); +INT32 wmt_lib_gps_mcu_ctrl(PUINT8 p_tx_data_buf, UINT32 tx_data_len, PUINT8 p_rx_data_buf, + UINT32 rx_data_buf_len, PUINT32 p_rx_data_len); +VOID wmt_lib_set_ext_ldo(UINT32 flag); +UINT32 wmt_lib_get_ext_ldo(VOID); +INT32 wmt_lib_try_pwr_off(VOID); +P_WMT_PATCH_INFO wmt_lib_get_patch_info(VOID); +INT32 wmt_lib_met_cmd(UINT32 value); + +INT32 wmt_lib_blank_status_ctrl(UINT32 on_off_flag); +VOID wmt_lib_set_blank_status(UINT32 on_off_flag); +extern UINT32 wmt_lib_get_blank_status(VOID); + +extern INT32 DISABLE_PSM_MONITOR(VOID); +extern VOID ENABLE_PSM_MONITOR(VOID); +extern INT32 wmt_lib_notify_stp_sleep(VOID); +extern VOID wmt_lib_psm_lock_release(VOID); +extern INT32 wmt_lib_psm_lock_aquire(VOID); +extern INT32 wmt_lib_psm_lock_trylock(VOID); +extern VOID wmt_lib_idc_lock_release(VOID); +extern INT32 wmt_lib_idc_lock_aquire(VOID); +extern VOID wmt_lib_wlan_lock_release(VOID); +extern INT32 wmt_lib_wlan_lock_trylock(VOID); +extern INT32 wmt_lib_wlan_lock_aquire(VOID); +extern VOID wmt_lib_assert_lock_release(VOID); +extern INT32 wmt_lib_assert_lock_trylock(VOID); +extern INT32 wmt_lib_assert_lock_aquire(VOID); +extern VOID wmt_lib_mpu_lock_release(VOID); +extern INT32 wmt_lib_mpu_lock_aquire(VOID); +extern VOID wmt_lib_power_lock_release(VOID); +extern INT32 wmt_lib_power_lock_trylock(VOID); +extern INT32 wmt_lib_power_lock_aquire(VOID); +extern INT32 wmt_lib_set_stp_wmt_last_close(UINT32 value); + +extern VOID wmt_lib_set_patch_num(UINT32 num); +extern VOID wmt_lib_set_patch_info(P_WMT_PATCH_INFO pPatchinfo); +extern VOID wmt_lib_set_rom_patch_info(struct wmt_rom_patch_info *PatchInfo, ENUM_WMTDRV_TYPE_T type); +extern MTK_WCN_BOOL wmt_lib_stp_is_btif_fullset_mode(VOID); + +extern INT32 wmt_lib_set_current_op(P_DEV_WMT pWmtDev, P_OSAL_OP pOp); +extern P_OSAL_OP wmt_lib_get_current_op(P_DEV_WMT pWmtDev); +extern INT32 wmt_lib_set_worker_op(P_DEV_WMT pWmtDev, P_OSAL_OP pOp); +extern P_OSAL_OP wmt_lib_get_worker_op(P_DEV_WMT pWmtDev); +extern PUINT8 wmt_lib_get_fwinfor_from_emi(UINT8 section, UINT32 offset, PUINT8 buff, UINT32 len); +extern INT32 wmt_lib_merge_if_flag_ctrl(UINT32 enable); +extern INT32 wmt_lib_merge_if_flag_get(UINT32 enable); + +extern PUINT8 wmt_lib_get_cpupcr_xml_format(PUINT32 len); +extern PUINT8 wmt_lib_get_cpupcr_reg_info(PUINT32 len, PUINT32 consys_reg); +extern UINT32 wmt_lib_set_host_assert_info(UINT32 type, UINT32 reason, UINT32 en); +extern INT8 wmt_lib_co_clock_get(VOID); +extern UINT32 wmt_lib_soc_set_wifiver(UINT32 wifiver); +extern VOID wmt_lib_dump_wmtd_backtrace(VOID); + +#if CFG_WMT_LTE_COEX_HANDLING +extern MTK_WCN_BOOL wmt_lib_handle_idc_msg(conn_md_ipc_ilm_t *idc_infor); +#endif +extern UINT32 wmt_lib_get_drv_status(UINT32 type); +extern INT32 wmt_lib_tm_temp_query(VOID); +extern INT32 wmt_lib_trigger_reset(VOID); +extern INT32 wmt_lib_trigger_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason); +extern INT32 wmt_lib_trigger_assert_keyword(ENUM_WMTDRV_TYPE_T type, UINT32 reason, PUINT8 keyword); +extern VOID wmt_lib_trigger_assert_keyword_delay(ENUM_WMTDRV_TYPE_T type, UINT32 reason, PUINT8 keyword); +extern INT32 wmt_lib_wifi_fem_cfg_report(PVOID pvInfoBuf); +#if CFG_WMT_PS_SUPPORT +extern UINT32 wmt_lib_quick_sleep_ctrl(UINT32 en); +#endif +extern UINT32 wmt_lib_fw_patch_update_rst_ctrl(UINT32 en); +#if CONSYS_ENALBE_SET_JTAG +extern UINT32 wmt_lib_jtag_flag_set(UINT32 en); +#endif + +UINT32 wmt_lib_get_gps_lna_pin_num(VOID); +extern INT32 wmt_lib_fw_log_ctrl(enum wmt_fw_log_type type, UINT8 onoff, UINT8 level); +VOID wmt_lib_print_wmtd_op_history(VOID); +VOID wmt_lib_print_worker_op_history(VOID); +extern INT32 wmt_lib_get_vendor_patch_num(VOID); +extern INT32 wmt_lib_set_vendor_patch_version(struct wmt_vendor_patch *p); +extern INT32 wmt_lib_get_vendor_patch_version(struct wmt_vendor_patch *p); +extern INT32 wmt_lib_set_check_patch_status(INT32 status); +extern INT32 wmt_lib_get_check_patch_status(VOID); +extern INT32 wmt_lib_set_active_patch_version(struct wmt_vendor_patch *p); +extern INT32 wmt_lib_get_active_patch_version(struct wmt_vendor_patch *p); +extern INT32 wmt_lib_get_need_update_patch_version(VOID); +extern INT32 wmt_lib_set_need_update_patch_version(INT32 need); +extern VOID wmt_lib_set_bt_link_status(INT32 type, INT32 value); +VOID mtk_lib_set_mcif_mpu_protection(MTK_WCN_BOOL enable); +INT32 wmt_lib_dmp_consys_state(P_CONSYS_STATE_DMP_INFO dmp_info, + UINT32 cpupcr_times, UINT32 slp_ms); + +extern INT32 wmt_lib_reg_readable(VOID); +extern INT32 wmt_lib_reg_readable_by_addr(SIZE_T addr); +extern INT32 wmt_lib_utc_time_sync(VOID); +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _WMT_LIB_H_ */ diff --git a/drivers/misc/mediatek/connectivity/common/common_main/core/psm_core.c b/drivers/misc/mediatek/connectivity/common/common_main/core/psm_core.c new file mode 100644 index 0000000000000000000000000000000000000000..5e7220c86fcbf21e956ee5be848fb1333cfea9b9 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/core/psm_core.c @@ -0,0 +1,2080 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +#include "osal_typedef.h" +#include "osal.h" +#include "psm_core.h" +#include "stp_core.h" +#include "stp_dbg.h" +#include "wmt_detect.h" +#include "wmt_exp.h" +#include +#include + +INT32 gPsmDbgLevel = STP_PSM_LOG_INFO; +MTKSTP_PSM_T stp_psm_i; +MTKSTP_PSM_T *stp_psm = &stp_psm_i; + +STP_PSM_RECORD_T *g_stp_psm_dbg; +static UINT32 g_record_num; + +P_STP_PSM_OPID_RECORD g_stp_psm_opid_dbg; +static UINT32 g_opid_record_num; + +static UINT32 stp_traffic_start; +static UINT32 stp_traffic_current; + +#define STP_PSM_PR_LOUD(fmt, arg...) \ +do { \ + if (gPsmDbgLevel >= STP_PSM_LOG_LOUD) \ + pr_info(PFX_PSM "%s: " fmt, __func__, ##arg); \ +} while (0) +#define STP_PSM_PR_DBG(fmt, arg...) \ +do { \ + if (gPsmDbgLevel >= STP_PSM_LOG_DBG) \ + pr_info(PFX_PSM "%s: " fmt, __func__, ##arg); \ +} while (0) +#define STP_PSM_PR_INFO(fmt, arg...) \ +do { \ + if (gPsmDbgLevel >= STP_PSM_LOG_INFO) \ + pr_info(PFX_PSM "[I]%s: " fmt, __func__, ##arg); \ +} while (0) +#define STP_PSM_PR_WARN(fmt, arg...) \ +do { \ + if (gPsmDbgLevel >= STP_PSM_LOG_WARN) \ + pr_warn(PFX_PSM "[W]%s: " fmt, __func__, ##arg); \ +} while (0) +#define STP_PSM_PR_ERR(fmt, arg...) \ +do { \ + if (gPsmDbgLevel >= STP_PSM_LOG_ERR) \ + pr_err(PFX_PSM "[E]%s(%d):ERROR! " fmt, __func__, __LINE__, ##arg); \ +} while (0) + + +static inline INT32 _stp_psm_notify_wmt(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_ACTION_T action); +static INT32 _stp_psm_thread_lock_aquire(MTKSTP_PSM_T *stp_psm); +static INT32 _stp_psm_thread_lock_release(MTKSTP_PSM_T *stp_psm); +static INT32 _stp_psm_dbg_dmp_in(STP_PSM_RECORD_T *stp_psm_dbg, UINT32 flag, UINT32 line_num); +static INT32 _stp_psm_dbg_out_printk(STP_PSM_RECORD_T *stp_psm_dbg); +static INT32 _stp_psm_opid_dbg_dmp_in(P_STP_PSM_OPID_RECORD p_opid_dbg, UINT32 opid, UINT32 line_num); +static INT32 _stp_psm_opid_dbg_out_printk(P_STP_PSM_OPID_RECORD p_opid_dbg); + + +static const PINT8 g_psm_state[STP_PSM_MAX_STATE] = { + "ACT", + "ACT_INACT", + "INACT", + "INACT_ACT" +}; + +static const PINT8 g_psm_action[STP_PSM_MAX_ACTION] = { + "SLEEP", + "HOST_AWAKE", + "WAKEUP", + "EIRQ", + "ROLL_BACK" +}; + +static const PINT8 g_psm_op_name[STP_OPID_PSM_NUM] = { + "STP_OPID_PSM_SLEEP", + "STP_OPID_PSM_WAKEUP", + "STP_OPID_PSM_HOST_AWAKE", + "STP_OPID_PSM_EXIT" +}; + +static INT32 _stp_psm_release_data(MTKSTP_PSM_T *stp_psm); + +static inline INT32 _stp_psm_get_state(MTKSTP_PSM_T *stp_psm); + +static INT32 _stp_psm_is_redundant_active_op(P_OSAL_OP pOp, P_OSAL_OP_Q pOpQ); + +static INT32 _stp_psm_clean_up_redundant_active_op(P_OSAL_OP_Q pOpQ); +static MTK_WCN_BOOL _stp_psm_is_quick_ps_support(VOID); + +ENUM_STP_TX_IF_TYPE __weak wmt_plat_get_comm_if_type(VOID) +{ + return STP_MAX_IF_TX; +} + +MTK_WCN_BOOL mtk_wcn_stp_psm_dbg_level(INT32 dbglevel) +{ + if (dbglevel >= 0 && dbglevel <= 4) { + gPsmDbgLevel = dbglevel; + STP_PSM_PR_INFO("gPsmDbgLevel = %d\n", gPsmDbgLevel); + return true; + } + STP_PSM_PR_INFO("invalid psm debug level. gPsmDbgLevel = %d\n", gPsmDbgLevel); + return false; +} +#if 0 +/* change from macro to static function to enforce type checking on parameters. */ +static INT32 psm_fifo_lock_init(MTKSTP_PSM_T *psm) +{ + + +#if CFG_PSM_CORE_FIFO_SPIN_LOCK +#if defined(CONFIG_PROVE_LOCKING) + osal_unsleepable_lock_init(&(psm->hold_fifo_lock)); + return 0; +#else + return osal_unsleepable_lock_init(&(psm->hold_fifo_lock)); +#endif +#else +#if defined(CONFIG_PROVE_LOCKING) + osal_sleepable_lock_init(&(psm->hold_fifo_lock)); + return 0; +#else + return osal_sleepable_lock_init(&(psm->hold_fifo_lock)); +#endif +#endif +} + +static INT32 psm_fifo_lock_deinit(MTKSTP_PSM_T *psm) +{ +#if CFG_PSM_CORE_FIFO_SPIN_LOCK + return osal_unsleepable_lock_deinit(&(psm->hold_fifo_lock)); +#else + return osal_sleepable_lock_deinit(&(psm->hold_fifo_lock)); +#endif +} + +static INT32 psm_fifo_lock(MTKSTP_PSM_T *psm) +{ + + +#if CFG_PSM_CORE_FIFO_SPIN_LOCK + return osal_lock_unsleepable_lock(&(psm->hold_fifo_lock)); +#else + return osal_lock_sleepable_lock(&(psm->hold_fifo_lock)); +#endif +} + +static INT32 psm_fifo_unlock(MTKSTP_PSM_T *psm) +{ + + +#if CFG_PSM_CORE_FIFO_SPIN_LOCK + return osal_unlock_unsleepable_lock(&(psm->hold_fifo_lock)); +#else + return osal_unlock_sleepable_lock(&(psm->hold_fifo_lock)); +#endif +} +#endif +static INT32 _stp_psm_handler(MTKSTP_PSM_T *stp_psm, P_STP_OP pStpOp) +{ + INT32 ret = -1; + + /* if (NULL == pStpOp) */ + /* { */ + /* return -1; */ + /* } */ + ret = _stp_psm_thread_lock_aquire(stp_psm); + if (ret) { + STP_PSM_PR_ERR("--->lock psm_thread_lock failed ret=%d\n", ret); + return ret; + } + + switch (pStpOp->opId) { + case STP_OPID_PSM_EXIT: + /* TODO: clean all up? */ + ret = 0; + break; + + case STP_OPID_PSM_SLEEP: + if (stp_psm_check_sleep_enable(stp_psm) > 0) + ret = _stp_psm_notify_wmt(stp_psm, SLEEP); + else + STP_PSM_PR_INFO("cancel sleep request\n"); + break; + + case STP_OPID_PSM_WAKEUP: + ret = _stp_psm_notify_wmt(stp_psm, WAKEUP); + break; + + case STP_OPID_PSM_HOST_AWAKE: + ret = _stp_psm_notify_wmt(stp_psm, HOST_AWAKE); + break; + + default: + STP_PSM_PR_ERR("invalid operation id (%d)\n", pStpOp->opId); + ret = -1; + break; + } + _stp_psm_thread_lock_release(stp_psm); + return ret; +} + +static P_OSAL_OP _stp_psm_get_op(MTKSTP_PSM_T *stp_psm, P_OSAL_OP_Q pOpQ) +{ + P_OSAL_OP pOp; + + if (!pOpQ) { + STP_PSM_PR_WARN("pOpQ == NULL\n"); + return NULL; + } + + osal_lock_unsleepable_lock(&(stp_psm->wq_spinlock)); + /* acquire lock success */ + RB_GET(pOpQ, pOp); + + if ((pOpQ == &stp_psm->rActiveOpQ) && (pOp != NULL)) { + /* stp_psm->current_active_op = pOp; */ + stp_psm->last_active_opId = pOp->op.opId; + } + osal_unlock_unsleepable_lock(&(stp_psm->wq_spinlock)); + + if ((pOpQ == &stp_psm->rActiveOpQ) && (pOp != NULL)) + STP_PSM_PR_DBG("last_active_opId(%d)\n", stp_psm->last_active_opId); + + if (!pOp) + STP_PSM_PR_WARN("RB_GET fail\n"); + + return pOp; +} + +static INT32 _stp_psm_dump_active_q(P_OSAL_OP_Q pOpQ) +{ + UINT32 read_idx; + UINT32 write_idx; + UINT32 opId; + + if (pOpQ == &stp_psm->rActiveOpQ) { + read_idx = stp_psm->rActiveOpQ.read; + write_idx = stp_psm->rActiveOpQ.write; + + STP_PSM_PR_DBG("Active op list:++\n"); + while ((read_idx & RB_MASK(pOpQ)) != (write_idx & RB_MASK(pOpQ))) { + opId = pOpQ->queue[read_idx & RB_MASK(pOpQ)]->op.opId; + if (opId < STP_OPID_PSM_NUM) + STP_PSM_PR_DBG("%s\n", g_psm_op_name[opId]); + else + STP_PSM_PR_WARN("Unknown OP Id\n"); + ++read_idx; + } + STP_PSM_PR_DBG("Active op list:--\n"); + } else + STP_PSM_PR_DBG("%s: not active queue, dont dump\n", __func__); + + return 0; +} + +static INT32 _stp_psm_is_redundant_active_op(P_OSAL_OP pOp, P_OSAL_OP_Q pOpQ) +{ + UINT32 opId = 0; + UINT32 prev_opId = 0; + + /* if((pOpQ == &stp_psm->rActiveOpQ) && (NULL != stp_psm->current_active_op)) */ + if ((pOpQ == &stp_psm->rActiveOpQ) && (stp_psm->last_active_opId != STP_OPID_PSM_INALID)) { + opId = pOp->op.opId; + + if (opId == STP_OPID_PSM_SLEEP) { + if (RB_EMPTY(pOpQ)) { + /* prev_opId = stp_psm->current_active_op->op.opId; */ + prev_opId = stp_psm->last_active_opId; + } else { + prev_opId = pOpQ->queue[(pOpQ->write - 1) & RB_MASK(pOpQ)]->op.opId; + } + + if (prev_opId == STP_OPID_PSM_SLEEP) { + STP_PSM_PR_DBG("redundant sleep opId found\n"); + return 1; + } else { + return 0; + } + } else { + if (RB_EMPTY(pOpQ)) { + /* prev_opId = stp_psm->current_active_op->op.opId; */ + prev_opId = stp_psm->last_active_opId; + } else { + prev_opId = pOpQ->queue[(pOpQ->write - 1) & RB_MASK(pOpQ)]->op.opId; + } + + if (((opId == STP_OPID_PSM_WAKEUP) && (prev_opId == STP_OPID_PSM_WAKEUP)) || + ((opId == STP_OPID_PSM_HOST_AWAKE) + && (prev_opId == STP_OPID_PSM_WAKEUP)) + || ((opId == STP_OPID_PSM_HOST_AWAKE) + && (prev_opId == STP_OPID_PSM_HOST_AWAKE)) + || ((opId == STP_OPID_PSM_WAKEUP) + && (prev_opId == STP_OPID_PSM_HOST_AWAKE)) + ) { + STP_PSM_PR_DBG("redundant opId found, opId(%d), preOpid(%d)\n", + opId, prev_opId); + return 1; + } else { + return 0; + } + } + } else { + return 0; + } + +} + +static INT32 _stp_psm_clean_up_redundant_active_op(P_OSAL_OP_Q pOpQ) +{ + UINT32 prev_opId = 0; + UINT32 prev_prev_opId = 0; + + P_OSAL_OP pOp; + P_OSAL_OP_Q pFreeOpQ = &stp_psm->rFreeOpQ; + + if (pOpQ == &stp_psm->rActiveOpQ) { + /* sleep , wakeup | sleep, --> null | sleep (x) */ + /* wakeup , sleep , wakeup | sleep --> wakeup | sleep (v) */ + /* sleep , wakeup , sleep | wakeup --> sleep | wakeup (v) */ + /* xxx, sleep | sleep --> xxx, sleep (v) */ + /* xxx, wakeup | wakeup --> xxx, wakeup (v) */ + /* xxx, awake | awake --> xxx, awake (v) --> should never happen */ + while (RB_COUNT(pOpQ) > 2) { + prev_opId = pOpQ->queue[(pOpQ->write - 1) & RB_MASK(pOpQ)]->op.opId; + prev_prev_opId = pOpQ->queue[(pOpQ->write - 2) & RB_MASK(pOpQ)]->op.opId; + + if ((prev_opId == STP_OPID_PSM_SLEEP + && prev_prev_opId == STP_OPID_PSM_WAKEUP) + || (prev_opId == STP_OPID_PSM_SLEEP + && prev_prev_opId == STP_OPID_PSM_HOST_AWAKE) + || (prev_opId == STP_OPID_PSM_WAKEUP + && prev_prev_opId == STP_OPID_PSM_SLEEP) + || (prev_opId == STP_OPID_PSM_HOST_AWAKE + && prev_prev_opId == STP_OPID_PSM_SLEEP) + ) { + RB_GET(pOpQ, pOp); + RB_PUT(pFreeOpQ, pOp); + RB_GET(pOpQ, pOp); + RB_PUT(pFreeOpQ, pOp); + } else if (prev_opId == prev_prev_opId) { + RB_GET(pOpQ, pOp); + if (!pOp) { + STP_PSM_PR_DBG("RB_GET pOp == NULL\n"); + } else { + STP_PSM_PR_DBG("redundant opId(%d) found, remove it\n", + pOp->op.opId); + } + RB_PUT(pFreeOpQ, pOp); + } else + if ((prev_opId == STP_OPID_PSM_WAKEUP + && prev_prev_opId == STP_OPID_PSM_HOST_AWAKE) + || (prev_opId == STP_OPID_PSM_HOST_AWAKE + && prev_prev_opId == STP_OPID_PSM_WAKEUP)) { + STP_PSM_PR_WARN("prev_opId(%d), prev_prev_opId(%d)\n", prev_opId, + prev_prev_opId); + RB_GET(pOpQ, pOp); + RB_PUT(pFreeOpQ, pOp); + } else { + STP_PSM_PR_ERR + ("prev_opId(%d), prev_prev_opId(%d), this should never happen!!!\n", + prev_opId, prev_prev_opId); + break; + } + } + } + + return 0; +} + +static INT32 _stp_psm_put_op(MTKSTP_PSM_T *stp_psm, P_OSAL_OP_Q pOpQ, P_OSAL_OP pOp) +{ + INT32 ret; + + /* if (!pOpQ || !pOp) */ + /* { */ + /* STP_PSM_PR_WARN("pOpQ = 0x%p, pLxOp = 0x%p\n", pOpQ, pOp); */ + /* return 0; */ + /* } */ + ret = 0; + + osal_lock_unsleepable_lock(&(stp_psm->wq_spinlock)); + /* acquire lock success */ + if (pOpQ == &stp_psm->rActiveOpQ) { + if (!_stp_psm_is_redundant_active_op(pOp, pOpQ)) { + /* acquire lock success */ + if (!RB_FULL(pOpQ)) { + RB_PUT(pOpQ, pOp); + STP_PSM_PR_DBG("opId(%d) enqueue\n", pOp->op.opId); + } else { + STP_PSM_PR_INFO("************ Active Queue Full ************\n"); + ret = -1; + } + + _stp_psm_clean_up_redundant_active_op(pOpQ); + } else { + /*redundant opId, mark ret as success */ + P_OSAL_OP_Q pFreeOpQ = &stp_psm->rFreeOpQ; + + if (!RB_FULL(pFreeOpQ)) + RB_PUT(pFreeOpQ, pOp); + else + osal_assert(!RB_FULL(pFreeOpQ)); + ret = 0; + } + } else { + if (!RB_FULL(pOpQ)) + RB_PUT(pOpQ, pOp); + else + ret = -1; + } + + if (pOpQ == &stp_psm->rActiveOpQ) + _stp_psm_dump_active_q(&stp_psm->rActiveOpQ); + + + if (ret) { + STP_PSM_PR_WARN("RB_FULL, RB_COUNT=%d , RB_SIZE=%d\n", RB_COUNT(pOpQ), + RB_SIZE(pOpQ)); + osal_opq_dump_locked("FreeOpQ", &stp_psm->rFreeOpQ); + osal_opq_dump_locked("ActiveOpQ", &stp_psm->rActiveOpQ); + } + + osal_unlock_unsleepable_lock(&(stp_psm->wq_spinlock)); + return ret ? 0 : 1; +} + +P_OSAL_OP _stp_psm_get_free_op(MTKSTP_PSM_T *stp_psm) +{ + P_OSAL_OP pOp; + + if (stp_psm) { + pOp = _stp_psm_get_op(stp_psm, &stp_psm->rFreeOpQ); + if (pOp) { + osal_memset(pOp, 0, osal_sizeof(OSAL_OP)); + } + return pOp; + } + return NULL; +} + +INT32 _stp_psm_put_act_op(MTKSTP_PSM_T *stp_psm, P_OSAL_OP pOp) +{ + INT32 bRet = 0; /* MTK_WCN_BOOL_FALSE; */ + INT32 wait_ret = -1; + P_OSAL_SIGNAL pSignal = NULL; + INT32 ret = 0; + + do { + if (!stp_psm || !pOp) { + STP_PSM_PR_ERR("stp_psm = %p, pOp = %p\n", stp_psm, pOp); + break; + } + + pSignal = &pOp->signal; + + if (pSignal->timeoutValue) { + pOp->result = -9; + osal_signal_init(&pOp->signal); + } + + /* Init ref_count to 2, as one is held by current thread, the second by psm thread */ + atomic_set(&pOp->ref_count, 2); + + /* put to active Q */ + bRet = _stp_psm_put_op(stp_psm, &stp_psm->rActiveOpQ, pOp); + + if (bRet == 0) { + STP_PSM_PR_WARN("+++++++++++ Put op Active queue Fail\n"); + atomic_dec(&pOp->ref_count); + break; + } + _stp_psm_opid_dbg_dmp_in(g_stp_psm_opid_dbg, pOp->op.opId, __LINE__); + /* wake up wmtd */ + ret = osal_trigger_event(&stp_psm->STPd_event); + + if (pSignal->timeoutValue == 0) { + bRet = 1; /* MTK_WCN_BOOL_TRUE; */ + break; + } + + /* check result */ + wait_ret = osal_wait_for_signal_timeout(&pOp->signal, &stp_psm->PSMd); + STP_PSM_PR_DBG("wait completion:%d\n", wait_ret); + if (!wait_ret) { + STP_PSM_PR_ERR("wait completion timeout\n"); + /* TODO: how to handle it? retry? */ + } else { + if (pOp->result) + STP_PSM_PR_WARN("op(%d) result:%d\n", pOp->op.opId, pOp->result); + /* op completes, check result */ + bRet = (pOp->result) ? 0 : 1; + } + } while (0); + + if (pOp && atomic_dec_and_test(&pOp->ref_count)) { + /* put Op back to freeQ */ + bRet = _stp_psm_put_op(stp_psm, &stp_psm->rFreeOpQ, pOp); + if (bRet == 0) + STP_PSM_PR_WARN("+++++++++++ Put op active free fail, maybe disable/enable psm\n"); + } + + return bRet; +} + +static INT32 _stp_psm_wait_for_msg(PVOID pvData) +{ + MTKSTP_PSM_T *stp_psm = (MTKSTP_PSM_T *)pvData; + + STP_PSM_PR_DBG("%s: stp_psm->rActiveOpQ = %d\n", __func__, + RB_COUNT(&stp_psm->rActiveOpQ)); + + return (!RB_EMPTY(&stp_psm->rActiveOpQ)) || osal_thread_should_stop(&stp_psm->PSMd); +} + +static INT32 _stp_psm_proc(PVOID pvData) +{ + MTKSTP_PSM_T *stp_psm = (MTKSTP_PSM_T *) pvData; + P_OSAL_OP pOp; + UINT32 id; + INT32 result; + + if (!stp_psm) { + STP_PSM_PR_WARN("!stp_psm\n"); + return -1; + } +/* STP_PSM_PR_INFO("wmtd starts running: pWmtDev(0x%p) [pol, rt_pri, n_pri, pri]=[%d, %d, %d, %d]\n", */ +/* stp_psm, current->policy, current->rt_priority, current->normal_prio, current->prio); */ + + for (;;) { + + pOp = NULL; + osal_wait_for_event(&stp_psm->STPd_event, _stp_psm_wait_for_msg, (PVOID) stp_psm); + + /* we set reset flag when calling stp_reset after cleanup all op. */ + if (osal_test_bit(STP_PSM_RESET_EN, &stp_psm->flag)) { + osal_clear_bit(STP_PSM_RESET_EN, &stp_psm->flag); + _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); + } + if (osal_thread_should_stop(&stp_psm->PSMd)) { + STP_PSM_PR_INFO("should stop now...\n"); + /* TODO: clean up active opQ */ + break; + } + + /* get Op from activeQ */ + pOp = _stp_psm_get_op(stp_psm, &stp_psm->rActiveOpQ); + if (!pOp) { + STP_PSM_PR_WARN + ("+++++++++++ Get op from activeQ fail, maybe disable/enable psm\n"); + continue; + } + osal_op_history_save(&stp_psm->op_history, pOp); + + id = osal_op_get_id(pOp); + + if (id >= STP_OPID_PSM_NUM) { + STP_PSM_PR_WARN("abnormal opid id: 0x%x\n", id); + result = -1; + goto handler_done; + } + + result = _stp_psm_handler(stp_psm, &pOp->op); + + +handler_done: + + if (result) + STP_PSM_PR_WARN("opid id(0x%x)(%s) error(%d)\n", id, + (id >= 4) ? ("???") : (g_psm_op_name[id]), result); + + if (atomic_dec_and_test(&pOp->ref_count)) { + /* put Op back to freeQ */ + if (_stp_psm_put_op(stp_psm, &stp_psm->rFreeOpQ, pOp) == 0) + STP_PSM_PR_WARN + ("+++++++++++ Put op to FreeOpQ fail, maybe disable/enable psm\n"); + } else if (osal_op_is_wait_for_signal(pOp)) { + osal_op_raise_signal(pOp, result); + } + + if (id == STP_OPID_PSM_EXIT) + break; + } + STP_PSM_PR_INFO("exits\n"); + + return 0; +}; + +static inline INT32 _stp_psm_get_time(VOID) +{ + if (gPsmDbgLevel >= STP_PSM_LOG_LOUD) + osal_printtimeofday(">>>"); + + return 0; +} + +static inline INT32 _stp_psm_get_state(MTKSTP_PSM_T *stp_psm) +{ + if (stp_psm == NULL) + return STP_PSM_OPERATION_FAIL; + if (stp_psm->work_state < STP_PSM_MAX_STATE) + return stp_psm->work_state; + STP_PSM_PR_ERR("work_state = %d, invalid\n", stp_psm->work_state); + return -STP_PSM_OPERATION_FAIL; +} + +static inline INT32 _stp_psm_set_state(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_STATE_T state) +{ + if (stp_psm == NULL) + return STP_PSM_OPERATION_FAIL; + if (stp_psm->work_state < STP_PSM_MAX_STATE) { + _stp_psm_get_time(); + /* STP_PSM_PR_INFO("work_state = %s --> %s\n", + * g_psm_state[stp_psm->work_state], g_psm_state[state]); + */ + stp_psm->work_state = state; + if (stp_psm->work_state != ACT) { + /* osal_lock_unsleepable_lock(&stp_psm->flagSpinlock); */ + osal_set_bit(STP_PSM_BLOCK_DATA_EN, &stp_psm->flag); + /* osal_unlock_unsleepable_lock(&stp_psm->flagSpinlock); */ + } + } else + STP_PSM_PR_ERR("work_state = %d, invalid\n", stp_psm->work_state); + + return STP_PSM_OPERATION_SUCCESS; +} + +static inline INT32 _stp_psm_start_monitor(MTKSTP_PSM_T *stp_psm) +{ + + if (!stp_psm) + return STP_PSM_OPERATION_FAIL; + + if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag)) { + STP_PSM_PR_DBG("STP-PSM DISABLE, DONT restart monitor!\n\r"); + return STP_PSM_OPERATION_SUCCESS; + } + + + STP_PSM_PR_LOUD("start monitor\n"); + stp_traffic_start = stp_traffic_current; + osal_timer_modify(&stp_psm->psm_timer, stp_psm->idle_time_to_sleep); + + return STP_PSM_OPERATION_SUCCESS; +} + +static inline INT32 _stp_psm_stop_monitor(MTKSTP_PSM_T *stp_psm) +{ + if (!stp_psm) + return STP_PSM_OPERATION_FAIL; + STP_PSM_PR_DBG("stop monitor\n"); + osal_timer_stop_sync(&stp_psm->psm_timer); + return STP_PSM_OPERATION_SUCCESS; +} + +INT32 +_stp_psm_hold_data(MTKSTP_PSM_T *stp_psm, const PUINT8 buffer, const UINT32 len, const UINT8 type) +{ + INT32 available_space = 0; + INT32 needed_space = 0; + UINT8 delimiter[] = { 0xbb, 0xbb }; + + if (!stp_psm) + return STP_PSM_OPERATION_FAIL; + /*psm_fifo_lock(stp_psm);*/ + osal_lock_sleepable_lock(&stp_psm->hold_fifo_spinlock_global); + available_space = STP_PSM_FIFO_SIZE - osal_fifo_len(&stp_psm->hold_fifo); + needed_space = len + sizeof(UINT8) + sizeof(UINT32) + 2; + /* STP_PSM_PR_INFO("*******FIFO Available(%d), Need(%d)\n", + * available_space, needed_space); + */ + if (available_space < needed_space) { + STP_PSM_PR_ERR("FIFO Available!! Reset FIFO\n"); + osal_fifo_reset(&stp_psm->hold_fifo); + } + /* type */ + osal_fifo_in(&stp_psm->hold_fifo, (PUINT8) &type, sizeof(UINT8)); + /* length */ + osal_fifo_in(&stp_psm->hold_fifo, (PUINT8) &len, sizeof(UINT32)); + /* buffer */ + osal_fifo_in(&stp_psm->hold_fifo, (PUINT8) buffer, len); + /* delimiter */ + osal_fifo_in(&stp_psm->hold_fifo, (PUINT8) delimiter, 2); + /*psm_fifo_unlock(stp_psm);*/ + osal_unlock_sleepable_lock(&stp_psm->hold_fifo_spinlock_global); + return len; +} + +INT32 _stp_psm_has_pending_data(MTKSTP_PSM_T *stp_psm) +{ + return osal_fifo_len(&stp_psm->hold_fifo); +} + +INT32 _stp_psm_release_data(MTKSTP_PSM_T *stp_psm) +{ + + INT32 i = 20; /*Max buffered packet number */ + INT32 ret = 0; + UINT8 type = 0; + UINT32 len = 0; + UINT8 delimiter[2] = {0}; + INT32 winspace_flag = 0; + + /* STP_PSM_PR_ERR("++++++++++release data++len=%d\n", osal_fifo_len(&stp_psm->hold_fifo)); */ + while ((osal_fifo_len(&stp_psm->hold_fifo) && i > 0) || winspace_flag > 0) { + /* acquire spinlock */ + /* psm_fifo_lock(stp_psm); */ + osal_lock_sleepable_lock(&stp_psm->hold_fifo_spinlock_global); + + if (winspace_flag == 0) { + ret = osal_fifo_out(&stp_psm->hold_fifo, (PUINT8)&type, sizeof(UINT8)); + ret = osal_fifo_out(&stp_psm->hold_fifo, (PUINT8)&len, sizeof(UINT32)); + + if (len > STP_PSM_PACKET_SIZE_MAX) { + STP_PSM_PR_ERR("***psm packet's length too Long!****\n"); + STP_PSM_PR_INFO("***reset psm's fifo***\n"); + } else { + osal_memset(stp_psm->out_buf, 0, STP_PSM_TX_SIZE); + ret = osal_fifo_out(&stp_psm->hold_fifo, (PUINT8) stp_psm->out_buf, len); + } + + ret = osal_fifo_out(&stp_psm->hold_fifo, (PUINT8)delimiter, 2); + } + + if (delimiter[0] == 0xbb && delimiter[1] == 0xbb) { + /* osal_buffer_dump(stp_psm->out_buf, "psm->out_buf", len, 32); */ + ret = stp_send_data_no_ps(stp_psm->out_buf, len, type); + if (ret == 0) + winspace_flag++; + else + winspace_flag = 0; + } else { + STP_PSM_PR_ERR("***psm packet fifo parsing fail****\n"); + STP_PSM_PR_INFO("***reset psm's fifo***\n"); + + osal_fifo_reset(&stp_psm->hold_fifo); + } + + if (winspace_flag == 0) + i--; + /* psm_fifo_unlock(stp_psm); */ + osal_unlock_sleepable_lock(&stp_psm->hold_fifo_spinlock_global); + + if (winspace_flag > 0 && winspace_flag < 10) + osal_sleep_ms(2); + else if (winspace_flag >= 10) { + STP_PSM_PR_ERR("***More than 20ms no winspace available***\n"); + break; + } + } + return STP_PSM_OPERATION_SUCCESS; +} + +static inline INT32 _stp_psm_notify_wmt_host_awake_wq(MTKSTP_PSM_T *stp_psm) +{ + + P_OSAL_OP pOp; + INT32 bRet; + INT32 retval; + + if (stp_psm == NULL) + return STP_PSM_OPERATION_FAIL; + pOp = _stp_psm_get_free_op(stp_psm); + if (!pOp) { + STP_PSM_PR_DBG("get_free_lxop fail\n"); + return -1; /* break; */ + } + pOp->op.opId = STP_OPID_PSM_HOST_AWAKE; + pOp->signal.timeoutValue = 0; + bRet = _stp_psm_put_act_op(stp_psm, pOp); + STP_PSM_PR_DBG("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); + retval = (bRet == 0) ? (STP_PSM_OPERATION_FAIL) : 0; + return retval; +} + +static inline INT32 _stp_psm_notify_wmt_wakeup_wq(MTKSTP_PSM_T *stp_psm) +{ + P_OSAL_OP pOp; + INT32 bRet; + INT32 retval; + + if (stp_psm == NULL) + return STP_PSM_OPERATION_FAIL; + pOp = _stp_psm_get_free_op(stp_psm); + if (!pOp) { + STP_PSM_PR_DBG("get_free_lxop fail\n"); + return -1; /* break; */ + } + pOp->op.opId = STP_OPID_PSM_WAKEUP; + pOp->signal.timeoutValue = 0; + bRet = _stp_psm_put_act_op(stp_psm, pOp); + if (bRet == 0) { + STP_PSM_PR_WARN("OPID(%d) type(%zd) bRet(%s)\n\n", + pOp->op.opId, pOp->op.au4OpData[0], "fail"); + } + retval = (bRet == 0) ? (STP_PSM_OPERATION_FAIL) : (STP_PSM_OPERATION_SUCCESS); + return retval; +} + +static inline INT32 _stp_psm_notify_wmt_sleep_wq(MTKSTP_PSM_T *stp_psm) +{ + P_OSAL_OP pOp; + INT32 bRet; + INT32 retval; + + if (stp_psm == NULL) + return STP_PSM_OPERATION_FAIL; + if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY, &stp_psm->flag)) + return 0; +#if PSM_USE_COUNT_PACKAGE + if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY, &stp_psm->flag)) + return 0; +#endif + if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag)) + return 0; + pOp = _stp_psm_get_free_op(stp_psm); + if (!pOp) { + STP_PSM_PR_DBG("get_free_lxop fail\n"); + return -1; /* break; */ + } + pOp->op.opId = STP_OPID_PSM_SLEEP; + pOp->signal.timeoutValue = 0; + bRet = _stp_psm_put_act_op(stp_psm, pOp); + STP_PSM_PR_DBG("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); + retval = (bRet == 0) ? (STP_PSM_OPERATION_FAIL) : 1; + return retval; +} + +/*internal function*/ + +static inline INT32 _stp_psm_reset(MTKSTP_PSM_T *stp_psm) +{ + INT32 i = 0; + P_OSAL_OP_Q pOpQ; + P_OSAL_OP pOp; + INT32 ret = 0; + + STP_PSM_PR_DBG("PSM MODE RESET=============================>\n\r"); + STP_PSM_PR_DBG("_stp_psm_reset\n"); + STP_PSM_PR_DBG("reset-wake_lock(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock)); + osal_wake_unlock(&stp_psm->wake_lock); + STP_PSM_PR_DBG("reset-wake_lock(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock)); + /* --> serialized the request from wmt <--// */ + ret = osal_lock_sleepable_lock(&stp_psm->user_lock); + if (ret) { + STP_PSM_PR_ERR("--->lock stp_psm->user_lock failed, ret=%d\n", ret); + return ret; + } + /* --> disable psm <--// */ + stp_psm->flag.data = 0; + osal_set_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag); + _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); + _stp_psm_stop_monitor(stp_psm); + /* --> prepare the op list <--// */ + osal_lock_unsleepable_lock(&(stp_psm->wq_spinlock)); + RB_INIT(&stp_psm->rFreeOpQ, STP_OP_BUF_SIZE); + RB_INIT(&stp_psm->rActiveOpQ, STP_OP_BUF_SIZE); + /* stp_psm->current_active_op = NULL; */ + stp_psm->last_active_opId = STP_OPID_PSM_INALID; + pOpQ = &stp_psm->rFreeOpQ; + for (i = 0; i < STP_OP_BUF_SIZE; i++) { + if (!RB_FULL(pOpQ)) { + pOp = &stp_psm->arQue[i]; + RB_PUT(pOpQ, pOp); + } + } + osal_unlock_unsleepable_lock(&(stp_psm->wq_spinlock)); + /* --> clean up interal data structure<--// */ + _stp_psm_set_state(stp_psm, ACT); + /*psm_fifo_lock(stp_psm);*/ + osal_lock_sleepable_lock(&stp_psm->hold_fifo_spinlock_global); + osal_fifo_reset(&stp_psm->hold_fifo); + /*psm_fifo_unlock(stp_psm);*/ + osal_unlock_sleepable_lock(&stp_psm->hold_fifo_spinlock_global); + /* --> stop psm thread wait <--*/ + osal_set_bit(STP_PSM_RESET_EN, &stp_psm->flag); + _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); + osal_trigger_event(&stp_psm->wait_wmt_q); + osal_unlock_sleepable_lock(&stp_psm->user_lock); + STP_PSM_PR_DBG("PSM MODE RESET<============================\n\r"); + return STP_PSM_OPERATION_SUCCESS; +} + +static INT32 _stp_psm_wait_wmt_event(PVOID pvData) +{ + MTKSTP_PSM_T *stp_psm = (MTKSTP_PSM_T *) pvData; + + STP_PSM_PR_DBG("%s, stp_psm->flag= %ld\n", __func__, stp_psm->flag.data); + osal_ftrace_print("%s, stp_psm->flag= %ld\n", __func__, stp_psm->flag.data); + + return (osal_test_bit(STP_PSM_WMT_EVENT_SLEEP_EN, &stp_psm->flag)) || + (osal_test_bit(STP_PSM_WMT_EVENT_WAKEUP_EN, &stp_psm->flag)) || + (osal_test_bit(STP_PSM_WMT_EVENT_ROLL_BACK_EN, &stp_psm->flag)) || + (osal_test_bit(STP_PSM_RESET_EN, &stp_psm->flag)); + +} + + +static inline INT32 _stp_psm_wait_wmt_event_wq(MTKSTP_PSM_T *stp_psm) +{ + + INT32 retval = 0; + PUINT8 pbuf = NULL; + INT32 len = 0; + + if (stp_psm == NULL) + return STP_PSM_OPERATION_FAIL; + osal_wait_for_event_timeout(&stp_psm->wait_wmt_q, _stp_psm_wait_wmt_event, (PVOID) stp_psm); + + if (mtk_wcn_stp_get_wmt_trg_assert() == 1 || mtk_wcn_stp_coredump_start_get() == 1) { + STP_PSM_PR_INFO("Host/Fw already triggered assert. Skip psm operation.\n"); + return STP_PSM_OPERATION_FAIL; + } + + if (osal_test_bit(STP_PSM_WMT_EVENT_WAKEUP_EN, &stp_psm->flag)) { + osal_clear_bit(STP_PSM_WMT_EVENT_WAKEUP_EN, &stp_psm->flag); + _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); + /* osal_lock_unsleepable_lock(&stp_psm->flagSpinlock); */ + /* STP send data here: STP enqueue data to psm buffer. */ + _stp_psm_release_data(stp_psm); + /* STP send data here: STP enqueue data to psm buffer. We release packet by the next one. */ + osal_clear_bit(STP_PSM_BLOCK_DATA_EN, &stp_psm->flag); + _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); + /* STP send data here: STP sends data directly without PSM. */ + _stp_psm_set_state(stp_psm, ACT); + /* osal_unlock_unsleepable_lock(&stp_psm->flagSpinlock); */ + if (stp_psm_is_quick_ps_support()) + stp_psm_notify_wmt_sleep(stp_psm); + else + _stp_psm_start_monitor(stp_psm); + } else if (osal_test_bit(STP_PSM_WMT_EVENT_SLEEP_EN, &stp_psm->flag)) { + osal_clear_bit(STP_PSM_WMT_EVENT_SLEEP_EN, &stp_psm->flag); + _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); + _stp_psm_set_state(stp_psm, INACT); + STP_PSM_PR_DBG("mt_combo_plt_enter_deep_idle++\n"); + if (wmt_detect_get_chip_type() == WMT_CHIP_TYPE_SOC) + mt_combo_plt_enter_deep_idle(COMBO_IF_BTIF); + else { + switch (wmt_plat_get_comm_if_type()) { + case STP_UART_IF_TX: + mt_combo_plt_enter_deep_idle(COMBO_IF_UART); + break; + case STP_SDIO_IF_TX: + mt_combo_plt_enter_deep_idle(COMBO_IF_MSDC); + break; + default: + break; + } + } + STP_PSM_PR_DBG("mt_combo_plt_enter_deep_idle--\n"); + STP_PSM_PR_DBG("sleep-wake_lock(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock)); + osal_wake_unlock(&stp_psm->wake_lock); + STP_PSM_PR_DBG("sleep-wake_lock#(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock)); + + if (osal_wake_lock_count(&stp_psm->wake_lock) == 0 && stp_psm->update_wmt_fw_patch_chip_rst != NULL) + stp_psm->update_wmt_fw_patch_chip_rst(); + } else if (osal_test_bit(STP_PSM_WMT_EVENT_ROLL_BACK_EN, &stp_psm->flag)) { + osal_clear_bit(STP_PSM_WMT_EVENT_ROLL_BACK_EN, &stp_psm->flag); + _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); + if (_stp_psm_get_state(stp_psm) == ACT_INACT) { + /* osal_lock_unsleepable_lock(&stp_psm->flagSpinlock); */ + _stp_psm_release_data(stp_psm); + osal_clear_bit(STP_PSM_BLOCK_DATA_EN, &stp_psm->flag); + _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); + _stp_psm_set_state(stp_psm, ACT); + /* osal_unlock_unsleepable_lock(&stp_psm->flagSpinlock); */ + } else if (_stp_psm_get_state(stp_psm) == INACT_ACT) { + _stp_psm_set_state(stp_psm, INACT); + STP_PSM_PR_INFO("[WARNING]PSM state rollback due too wakeup fail\n"); + } + } else if (osal_test_bit(STP_PSM_RESET_EN, &stp_psm->flag)) { + osal_clear_bit(STP_PSM_WMT_EVENT_ROLL_BACK_EN, &stp_psm->flag); + _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); + } else { + STP_PSM_PR_ERR("state = %d, flag = %ld<== Abnormal flag be set!!\n\r", + stp_psm->work_state, stp_psm->flag.data); + mtk_wcn_wmt_dump_wmtd_backtrace(); + /* wcn_psm_flag_trigger_collect_ftrace(); */ /* trigger collect SYS_FTRACE */ + pbuf = "Abnormal PSM flag be set, just collect SYS_FTRACE to DB"; + len = osal_strlen(pbuf); + stp_dbg_trigger_collect_ftrace(pbuf, len); + _stp_psm_dbg_out_printk(g_stp_psm_dbg); + } + retval = STP_PSM_OPERATION_SUCCESS; + return retval; +} + +static inline INT32 _stp_psm_notify_stp(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_ACTION_T action) +{ + + INT32 retval = STP_PSM_OPERATION_SUCCESS; + + if (action < 0 || action >= STP_PSM_MAX_ACTION) + return STP_PSM_OPERATION_FAIL; + + if (action == EIRQ) { + STP_PSM_PR_DBG("Call _stp_psm_notify_wmt_host_awake_wq\n\r"); + _stp_psm_notify_wmt_host_awake_wq(stp_psm); + return STP_PSM_OPERATION_FAIL; + } + if ((_stp_psm_get_state(stp_psm) < STP_PSM_MAX_STATE) && (_stp_psm_get_state(stp_psm) >= 0)) { + STP_PSM_PR_DBG("state = %s, action=%s\n\r", + g_psm_state[_stp_psm_get_state(stp_psm)], g_psm_action[action]); + } + /* If STP trigger WAKEUP and SLEEP, to do the job below */ + switch (_stp_psm_get_state(stp_psm)) { + /* stp trigger */ + case ACT_INACT: + if (action == SLEEP) { + STP_PSM_PR_LOUD("Action = %s, ACT_INACT state, ready to INACT\n\r", + g_psm_action[action]); + osal_clear_bit(STP_PSM_WMT_EVENT_WAKEUP_EN, &stp_psm->flag); + _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); + osal_set_bit(STP_PSM_WMT_EVENT_SLEEP_EN, &stp_psm->flag); + _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); + /* wake_up(&stp_psm->wait_wmt_q); */ + osal_trigger_event(&stp_psm->wait_wmt_q); + } else if (action == ROLL_BACK) { + STP_PSM_PR_LOUD("Action = %s, ACT_INACT state, back to ACT\n\r", + g_psm_action[action]); + /* stp_psm->flag &= ~STP_PSM_WMT_EVENT_ROLL_BACK_EN; */ + osal_set_bit(STP_PSM_WMT_EVENT_ROLL_BACK_EN, &stp_psm->flag); + _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); + /* wake_up(&stp_psm->wait_wmt_q); */ + osal_trigger_event(&stp_psm->wait_wmt_q); + } else { + if (action < STP_PSM_MAX_ACTION) { + STP_PSM_PR_ERR("Action = %s, state = %d, flag = %ld, abnormal!\n", + g_psm_action[action], + stp_psm->work_state, stp_psm->flag.data); + } else { + STP_PSM_PR_ERR("Invalid Action!!\n\r"); + } + _stp_psm_dbg_out_printk(g_stp_psm_dbg); + + retval = STP_PSM_OPERATION_FAIL; + } + break; + /* stp trigger */ + case INACT_ACT: + if (action == WAKEUP) { + STP_PSM_PR_LOUD("Action = %s, INACT_ACT state, ready to ACT\n\r", + g_psm_action[action]); + osal_clear_bit(STP_PSM_WMT_EVENT_SLEEP_EN, &stp_psm->flag); + _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); + osal_set_bit(STP_PSM_WMT_EVENT_WAKEUP_EN, &stp_psm->flag); + _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); + /* wake_up(&stp_psm->wait_wmt_q); */ + osal_trigger_event(&stp_psm->wait_wmt_q); + } else if (action == HOST_AWAKE) { + STP_PSM_PR_LOUD("Action = %s, INACT_ACT state, ready to ACT\n\r", + g_psm_action[action]); + osal_clear_bit(STP_PSM_WMT_EVENT_SLEEP_EN, &stp_psm->flag); + _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); + osal_set_bit(STP_PSM_WMT_EVENT_WAKEUP_EN, &stp_psm->flag); + _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); + /* wake_up(&stp_psm->wait_wmt_q); */ + osal_trigger_event(&stp_psm->wait_wmt_q); + } else if (action == ROLL_BACK) { + STP_PSM_PR_LOUD("Action = %s, INACT_ACT state, back to INACT\n\r", + g_psm_action[action]); + /* stp_psm->flag &= ~STP_PSM_WMT_EVENT_ROLL_BACK_EN; */ + osal_set_bit(STP_PSM_WMT_EVENT_ROLL_BACK_EN, &stp_psm->flag); + _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); + /* wake_up(&stp_psm->wait_wmt_q); */ + osal_trigger_event(&stp_psm->wait_wmt_q); + } else { + if (action < STP_PSM_MAX_ACTION) { + STP_PSM_PR_ERR("Action = %s, state = %d, flag = %ld, abnormal!\n", + g_psm_action[action], + stp_psm->work_state, stp_psm->flag.data); + } else { + STP_PSM_PR_ERR("Invalid Action!!\n\r"); + } + _stp_psm_dbg_out_printk(g_stp_psm_dbg); + retval = STP_PSM_OPERATION_FAIL; + } + break; + case INACT: + if (action < STP_PSM_MAX_ACTION) { + STP_PSM_PR_ERR("Action = %s, state = %d, flag = %ld, abnormal!\n", + g_psm_action[action], + stp_psm->work_state, stp_psm->flag.data); + } else { + STP_PSM_PR_ERR("Invalid Action!!\n\r"); + } + _stp_psm_dbg_out_printk(g_stp_psm_dbg); + retval = -1; + break; + case ACT: + if (action < STP_PSM_MAX_ACTION) { + STP_PSM_PR_ERR("Action = %s, state = %d, flag = %ld, abnormal!\n", + g_psm_action[action], + stp_psm->work_state, stp_psm->flag.data); + } else { + STP_PSM_PR_ERR("Invalid Action!!\n\r"); + } + _stp_psm_dbg_out_printk(g_stp_psm_dbg); + + retval = STP_PSM_OPERATION_FAIL; + break; + default: + /*invalid */ + if (action < STP_PSM_MAX_ACTION) { + STP_PSM_PR_ERR("Action = %s, state = %d, flag = %ld, abnormal!\n", + g_psm_action[action], + stp_psm->work_state, stp_psm->flag.data); + } else { + STP_PSM_PR_ERR("Invalid Action!!\n\r"); + } + _stp_psm_dbg_out_printk(g_stp_psm_dbg); + + retval = STP_PSM_OPERATION_FAIL; + break; + } + return retval; +} + +static inline INT32 _stp_psm_notify_wmt(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_ACTION_T action) +{ + INT32 ret = STP_PSM_OPERATION_SUCCESS; + + if (stp_psm == NULL || action < 0 || action >= STP_PSM_MAX_ACTION) + return STP_PSM_OPERATION_FAIL; + + switch (_stp_psm_get_state(stp_psm)) { + case ACT: + + if (action == SLEEP) { + osal_lock_sleepable_lock(&stp_psm->user_lock); + if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag)) { + STP_PSM_PR_ERR("psm monitor disabled, can't do sleep op\n"); + osal_unlock_sleepable_lock(&stp_psm->user_lock); + return STP_PSM_OPERATION_FAIL; + } + + _stp_psm_set_state(stp_psm, ACT_INACT); + osal_unlock_sleepable_lock(&stp_psm->user_lock); + _stp_psm_release_data(stp_psm); + + if (stp_psm->wmt_notify) { + ret = stp_psm->wmt_notify(SLEEP); + if (!ret) + _stp_psm_wait_wmt_event_wq(stp_psm); + else + STP_PSM_PR_ERR("stp_psm->wmt_notify return fail\n"); + + } else { + STP_PSM_PR_ERR("stp_psm->wmt_notify = NULL\n"); + ret = STP_PSM_OPERATION_FAIL; + } + } else if (action == WAKEUP || action == HOST_AWAKE) { + STP_PSM_PR_DBG("In ACT state, dont do WAKEUP/HOST_AWAKE again\n"); + _stp_psm_release_data(stp_psm); + } else { + STP_PSM_PR_ERR("Action = %s, state = %d, flag = %ld, abnormal!\n", + g_psm_action[action], + stp_psm->work_state, stp_psm->flag.data); + _stp_psm_dbg_out_printk(g_stp_psm_dbg); + ret = STP_PSM_OPERATION_FAIL; + + } + + break; + + case INACT: + + if (action == WAKEUP) { + _stp_psm_set_state(stp_psm, INACT_ACT); + + if (stp_psm->wmt_notify) { + STP_PSM_PR_DBG("wakeup +wake_lock(%d)\n", + osal_wake_lock_count(&stp_psm->wake_lock)); + osal_wake_lock(&stp_psm->wake_lock); + STP_PSM_PR_DBG("wakeup +wake_lock(%d)#\n", + osal_wake_lock_count(&stp_psm->wake_lock)); + + STP_PSM_PR_DBG("mt_combo_plt_exit_deep_idle++\n"); + if (wmt_detect_get_chip_type() == WMT_CHIP_TYPE_SOC) + mt_combo_plt_exit_deep_idle(COMBO_IF_BTIF); + else { + switch (wmt_plat_get_comm_if_type()) { + case STP_UART_IF_TX: + mt_combo_plt_exit_deep_idle(COMBO_IF_UART); + break; + case STP_SDIO_IF_TX: + mt_combo_plt_exit_deep_idle(COMBO_IF_MSDC); + break; + default: + break; + } + } + STP_PSM_PR_DBG("mt_combo_plt_exit_deep_idle--\n"); + + ret = stp_psm->wmt_notify(WAKEUP); + if (!ret) + _stp_psm_wait_wmt_event_wq(stp_psm); + else + STP_PSM_PR_ERR("stp_psm->wmt_notify return fail\n"); + } else { + STP_PSM_PR_ERR("stp_psm->wmt_notify = NULL\n"); + ret = STP_PSM_OPERATION_FAIL; + } + } else if (action == HOST_AWAKE) { + _stp_psm_set_state(stp_psm, INACT_ACT); + + if (stp_psm->wmt_notify) { + STP_PSM_PR_DBG("host awake +wake_lock(%d)\n", + osal_wake_lock_count(&stp_psm->wake_lock)); + osal_wake_lock(&stp_psm->wake_lock); + STP_PSM_PR_DBG("host awake +wake_lock(%d)#\n", + osal_wake_lock_count(&stp_psm->wake_lock)); + + STP_PSM_PR_DBG("mt_combo_plt_exit_deep_idle++\n"); + if (wmt_detect_get_chip_type() == WMT_CHIP_TYPE_SOC) + mt_combo_plt_exit_deep_idle(COMBO_IF_BTIF); + else { + switch (wmt_plat_get_comm_if_type()) { + case STP_UART_IF_TX: + mt_combo_plt_exit_deep_idle(COMBO_IF_UART); + break; + case STP_SDIO_IF_TX: + mt_combo_plt_exit_deep_idle(COMBO_IF_MSDC); + break; + default: + break; + } + } + STP_PSM_PR_DBG("mt_combo_plt_exit_deep_idle--\n"); + + ret = stp_psm->wmt_notify(HOST_AWAKE); + if (!ret) + _stp_psm_wait_wmt_event_wq(stp_psm); + else + STP_PSM_PR_ERR("stp_psm->wmt_notify return fail\n"); + } else { + STP_PSM_PR_ERR("stp_psm->wmt_notify = NULL\n"); + ret = STP_PSM_OPERATION_FAIL; + } + } else if (action == SLEEP) { + STP_PSM_PR_INFO("In INACT state, dont do SLEEP again\n"); + } else { + STP_PSM_PR_ERR("Action = %s, state = %d, flag = %ld, abnormal!\n", + g_psm_action[action], + stp_psm->work_state, stp_psm->flag.data); + _stp_psm_dbg_out_printk(g_stp_psm_dbg); + ret = STP_PSM_OPERATION_FAIL; + } + + break; + + default: + + /*invalid */ + STP_PSM_PR_ERR("Action = %s, state = %d, flag = %ld, abnormal!\n", + g_psm_action[action], + stp_psm->work_state, stp_psm->flag.data); + _stp_psm_dbg_out_printk(g_stp_psm_dbg); + ret = STP_PSM_OPERATION_FAIL; + + break; + } + return ret; +} + +static inline VOID _stp_psm_stp_is_idle(timer_handler_arg arg) +{ + ULONG data; + MTKSTP_PSM_T *stp_psm; + + GET_HANDLER_DATA(arg, data); + stp_psm = (MTKSTP_PSM_T *) data; + osal_clear_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY, &stp_psm->flag); + _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); + osal_clear_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY, &stp_psm->flag); + _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); + + if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag)) { + STP_PSM_PR_DBG("STP-PSM DISABLE!\n"); + return; + } + + if (stp_traffic_start != stp_traffic_current) { + STP_PSM_PR_DBG("Timer extension due to ongoing traffic (%d, %d)\n", + stp_traffic_start, stp_traffic_current); + stp_psm_start_monitor(stp_psm); + return; + } + + STP_PSM_PR_DBG("**IDLE is over %d msec, go to sleep!!!**\n", stp_psm->idle_time_to_sleep); + osal_ftrace_print("**IDLE is over %d msec, go to sleep!!!**\n", stp_psm->idle_time_to_sleep); + _stp_psm_notify_wmt_sleep_wq(stp_psm); +} + +static inline INT32 _stp_psm_init_monitor(MTKSTP_PSM_T *stp_psm) +{ + if (!stp_psm) + return STP_PSM_OPERATION_FAIL; + STP_PSM_PR_DBG("init monitor\n"); + stp_psm->psm_timer.timeoutHandler = _stp_psm_stp_is_idle; + stp_psm->psm_timer.timeroutHandlerData = (ULONG)stp_psm; + osal_timer_create(&stp_psm->psm_timer); + return STP_PSM_OPERATION_SUCCESS; +} + +static inline INT32 _stp_psm_deinit_monitor(MTKSTP_PSM_T *stp_psm) +{ + if (!stp_psm) + return STP_PSM_OPERATION_FAIL; + STP_PSM_PR_INFO("deinit monitor\n"); + osal_timer_stop_sync(&stp_psm->psm_timer); + return 0; +} +static inline INT32 _stp_psm_is_to_block_traffic(MTKSTP_PSM_T *stp_psm) +{ + INT32 iRet = -1; + /* osal_lock_unsleepable_lock(&stp_psm->flagSpinlock); */ + if (osal_test_bit(STP_PSM_BLOCK_DATA_EN, &stp_psm->flag)) + iRet = 1; + else + iRet = 0; + /* osal_unlock_unsleepable_lock(&stp_psm->flagSpinlock); */ + return iRet; +} + +static inline INT32 _stp_psm_is_disable(MTKSTP_PSM_T *stp_psm) +{ + if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag)) + return 1; + return 0; +} + +static inline INT32 _stp_psm_do_wait(MTKSTP_PSM_T *stp_psm, MTKSTP_PSM_STATE_T state) +{ +#define POLL_WAIT 20 /* 200 */ +#define POLL_WAIT_TIME 2000 + INT32 i = 0; + INT32 limit = POLL_WAIT_TIME / POLL_WAIT; + UINT64 sec = 0; + ULONG usec = 0; + + if (state < 0 || state >= STP_PSM_MAX_STATE) + return STP_PSM_OPERATION_FAIL; + + osal_get_local_time(&sec, &usec); + while (_stp_psm_get_state(stp_psm) != state && i < limit && mtk_wcn_stp_is_enable()) { + i++; + if (i < 3) + STP_PSM_PR_INFO("STP is waiting state for %s, i=%d, state = %d\n", + g_psm_state[state], i, _stp_psm_get_state(stp_psm)); + osal_sleep_ms(POLL_WAIT); + if (i == 10) { + STP_PSM_PR_WARN("-Wait for %s takes %d msec\n", g_psm_state[state], i * POLL_WAIT); + _stp_psm_opid_dbg_out_printk(g_stp_psm_opid_dbg); + } + } + if (mtk_wcn_stp_is_enable() == 0) { + STP_PSM_PR_INFO("STP disable, maybe do chip reset"); + return STP_PSM_OPERATION_FAIL; + } + + if (i == limit) { + STP_PSM_PR_WARN("-Wait for %s takes %llu usec\n", g_psm_state[state], osal_elapsed_us(sec, usec)); + mtk_wcn_wmt_dump_wmtd_backtrace(); + _stp_psm_opid_dbg_out_printk(g_stp_psm_opid_dbg); + return STP_PSM_OPERATION_FAIL; + } + if (i > 0) + STP_PSM_PR_INFO("+Total waits for %s takes %llu usec\n", + g_psm_state[state], osal_elapsed_us(sec, usec)); + return STP_PSM_OPERATION_SUCCESS; +} + +static inline INT32 _stp_psm_do_wakeup(MTKSTP_PSM_T *stp_psm) +{ + INT32 ret = 0; + INT32 retry = 10; + P_OSAL_OP_Q pOpQ; + P_OSAL_OP pOp; + + STP_PSM_PR_LOUD("*** Do Force Wakeup!***\n\r"); + /* <1>If timer is active, we will stop it. */ + _stp_psm_stop_monitor(stp_psm); + osal_lock_unsleepable_lock(&(stp_psm->wq_spinlock)); + pOpQ = &stp_psm->rFreeOpQ; + while (!RB_EMPTY(&stp_psm->rActiveOpQ)) { + RB_GET(&stp_psm->rActiveOpQ, pOp); + if (pOp != NULL && !RB_FULL(pOpQ)) + RB_PUT(pOpQ, pOp); + else + STP_PSM_PR_ERR("clear up active queue fail, freeQ full\n"); + } + osal_unlock_unsleepable_lock(&(stp_psm->wq_spinlock)); + /* <5>We issue wakeup request into op queue. and wait for active. */ + do { + ret = _stp_psm_notify_wmt_wakeup_wq(stp_psm); + if (ret == STP_PSM_OPERATION_SUCCESS) { + ret = _stp_psm_do_wait(stp_psm, ACT); + /* STP_PSM_PR_INFO("<< wait ret = %d, num of activeQ = %d\n", ret, + * RB_COUNT(&stp_psm->rActiveOpQ)); + */ + if (ret == STP_PSM_OPERATION_SUCCESS) + break; + } else + STP_PSM_PR_ERR("_stp_psm_notify_wmt_wakeup_wq fail, retry = %d !!\n", retry); + /* STP_PSM_PR_INFO("retry = %d\n", retry); */ + retry--; + if (retry == 0) + break; + } while (1); + if (retry == 0) + return STP_PSM_OPERATION_FAIL; + return STP_PSM_OPERATION_SUCCESS; +} + +static inline INT32 _stp_psm_disable(MTKSTP_PSM_T *stp_psm) +{ + INT32 ret = STP_PSM_OPERATION_FAIL; + P_OSAL_THREAD psm_thread; + + STP_PSM_PR_DBG("PSM Disable start\n\r"); + ret = osal_lock_sleepable_lock(&stp_psm->user_lock); + if (ret) { + STP_PSM_PR_ERR("--->lock stp_psm->user_lock failed, ret=%d\n", ret); + return ret; + } + osal_set_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag); + _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); + ret = _stp_psm_do_wakeup(stp_psm); + osal_unlock_sleepable_lock(&stp_psm->user_lock); + if (ret == STP_PSM_OPERATION_SUCCESS) + STP_PSM_PR_DBG("PSM Disable Success\n"); + else { + STP_PSM_PR_ERR("***PSM Disable Fail***\n"); + psm_thread = &stp_psm_i.PSMd; + osal_thread_show_stack(psm_thread); + } + return ret; +} + +static inline INT32 _stp_psm_enable(MTKSTP_PSM_T *stp_psm, INT32 idle_time_to_sleep) +{ + INT32 ret = STP_PSM_OPERATION_FAIL; + + STP_PSM_PR_LOUD("PSM Enable start\n\r"); + ret = osal_lock_sleepable_lock(&stp_psm->user_lock); + if (ret) { + STP_PSM_PR_ERR("--->lock stp_psm->user_lock failed, ret=%d\n", ret); + return ret; + } + osal_set_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag); + _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); + ret = _stp_psm_do_wakeup(stp_psm); + if (ret == STP_PSM_OPERATION_SUCCESS) { + osal_clear_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag); + _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); + stp_psm->idle_time_to_sleep = idle_time_to_sleep; + if (osal_wake_lock_count(&stp_psm->wake_lock) == 0) { + STP_PSM_PR_DBG("psm_en+wake_lock(%d)\n", + osal_wake_lock_count(&stp_psm->wake_lock)); + osal_wake_lock(&stp_psm->wake_lock); + STP_PSM_PR_DBG("psm_en+wake_lock(%d)#\n", + osal_wake_lock_count(&stp_psm->wake_lock)); + } + _stp_psm_start_monitor(stp_psm); + STP_PSM_PR_DBG("PSM Enable succeed\n\r"); + } else + STP_PSM_PR_ERR("***PSM Enable Fail***\n"); + osal_unlock_sleepable_lock(&stp_psm->user_lock); + return ret; +} + +INT32 _stp_psm_thread_lock_aquire(MTKSTP_PSM_T *stp_psm) +{ + return osal_lock_sleepable_lock(&stp_psm->stp_psm_lock); +} + +INT32 _stp_psm_thread_lock_release(MTKSTP_PSM_T *stp_psm) +{ + osal_unlock_sleepable_lock(&stp_psm->stp_psm_lock); + return 0; +} + +MTK_WCN_BOOL _stp_psm_is_quick_ps_support(VOID) +{ + if (stp_psm->is_wmt_quick_ps_support) + return (*(stp_psm->is_wmt_quick_ps_support)) (); + STP_PSM_PR_DBG("stp_psm->is_wmt_quick_ps_support is NULL, return false\n\r"); + return MTK_WCN_BOOL_FALSE; +} + + +MTK_WCN_BOOL stp_psm_is_quick_ps_support(VOID) +{ + return _stp_psm_is_quick_ps_support(); +} + +#if PSM_USE_COUNT_PACKAGE +INT32 stp_psm_disable_by_tx_rx_density(MTKSTP_PSM_T *stp_psm, INT32 dir) +{ + /* easy the variable maintain beween stp tx, rx thread. */ + /* so we create variable for tx, rx respectively. */ + static INT32 tx_cnt; + static INT32 rx_cnt; + INT32 tx_cnt_th = MTK_COMBO_PSM_TX_TH_DEFAULT; + INT32 rx_cnt_th = MTK_COMBO_PSM_RX_TH_DEFAULT; + static INT32 is_tx_first = 1; + static INT32 is_rx_first = 1; + static ULONG tx_end_time; + static ULONG rx_end_time; + long res; + + /* */ + /* BT A2DP TX CNT = 220, RX CNT = 843 */ + /* BT FTP Transferring TX CNT = 574, RX CNT = 2233 (1228~1588) */ + /* BT FTP Receiving TX CNT = 204, RX CNT = 3301 (2072~2515) */ + /* BT OPP Tx TX_CNT= 330, RX CNT = 1300~1800 */ + /* BT OPP Rx TX_CNT= (109~157), RX CNT = 1681~2436 */ +/* #if defined(MTK_COMBO_PSM_RX_TH) +* osal_strtol(MTK_COMBO_PSM_RX_TH, 10, &res); +* rx_cnt_th = (INT32)res; +* #endif +* #if defined(MTK_COMBO_PSM_TX_TH) +* osal_strtol(MTK_COMBO_PSM_TX_TH, 10, &res); +* tx_cnt_th = (INT32)res; +* #endif +*/ + STP_PSM_PR_DBG("RX TH:%d; TX TH:%d\n\r", rx_cnt_th, tx_cnt_th); + stp_traffic_current++; + if (dir == 0) { /* tx */ + tx_cnt++; + if (((long)jiffies - (long)tx_end_time >= 0) || (is_tx_first)) { + tx_end_time = jiffies + (3 * HZ); + STP_PSM_PR_INFO("tx cnt = %d in the previous 3 sec,tx_th = %d\n", tx_cnt, + tx_cnt_th); + /* if(tx_cnt > 400)//for high traffic , not to do sleep. */ + if (tx_cnt > tx_cnt_th) { + osal_set_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY, + &stp_psm->flag); + _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); + stp_psm_start_monitor(stp_psm); + } else { + osal_clear_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY, + &stp_psm->flag); + _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); + } + tx_cnt = 0; + if (is_tx_first) + is_tx_first = 0; + } + } else { + rx_cnt++; + + if (((long)jiffies - (long)rx_end_time >= 0) || (is_rx_first)) { + rx_end_time = jiffies + (3 * HZ); + STP_PSM_PR_INFO("rx cnt = %d in the previous 3 sec, rx_th = %d\n", rx_cnt, + rx_cnt_th); + + /* if(rx_cnt > 2000)//for high traffic , not to do sleep. */ + if (rx_cnt > rx_cnt_th) { /* for high traffic , not to do sleep. */ + osal_set_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY, + &stp_psm->flag); + _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); + stp_psm_start_monitor(stp_psm); + } else { + osal_clear_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY, + &stp_psm->flag); + _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); + } + rx_cnt = 0; + if (is_rx_first) + is_rx_first = 0; + } + } + + return 0; +} +#else +static struct timeval tv_now, tv_end; +static INT32 sample_start; +static INT32 tx_sum_len; +static INT32 rx_sum_len; + +INT32 stp_psm_disable_by_tx_rx_density(MTKSTP_PSM_T *stp_psm, INT32 dir, INT32 length) +{ + stp_traffic_current++; + if (sample_start) { + if (dir) + rx_sum_len += length; + else + tx_sum_len += length; + + osal_do_gettimeofday(&tv_now); + /* STP_PSM_PR_INFO("tv_now:%d.%d tv_end:%d.%d\n", tv_now.tv_sec, tv_now.tv_usec, + * tv_end.tv_sec,tv_end.tv_usec); + */ + if (((tv_now.tv_sec == tv_end.tv_sec) && (tv_now.tv_usec > tv_end.tv_usec)) || + (tv_now.tv_sec > tv_end.tv_sec)) { + STP_PSM_PR_INFO("STP speed rx:%d tx:%d\n", rx_sum_len, tx_sum_len); + if ((rx_sum_len + tx_sum_len) > RTX_SPEED_THRESHOLD) { + STP_PSM_PR_INFO("High speed,Disable monitor\n"); + osal_set_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY, &stp_psm->flag); + stp_psm->idle_time_to_sleep = STP_PSM_IDLE_TIME_SLEEP_1000; + stp_psm_start_monitor(stp_psm); + } else { + STP_PSM_PR_INFO("Low speed,Enable monitor\n"); + stp_psm->idle_time_to_sleep = STP_PSM_IDLE_TIME_SLEEP; + osal_clear_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY, &stp_psm->flag); + } + wmt_lib_ps_set_idle_time(stp_psm->idle_time_to_sleep); + sample_start = 0; + rx_sum_len = 0; + tx_sum_len = 0; + } + } else { + sample_start = 1; + osal_do_gettimeofday(&tv_now); + tv_end = tv_now; + tv_end.tv_sec += SAMPLE_DURATION; + } + + return 0; +} +#endif + +/*external function for WMT module to do sleep/wakeup*/ +INT32 stp_psm_set_state(MTKSTP_PSM_T *stp_psm, MTKSTP_PSM_STATE_T state) +{ + return _stp_psm_set_state(stp_psm, state); +} + + +INT32 stp_psm_thread_lock_aquire(MTKSTP_PSM_T *stp_psm) +{ + return _stp_psm_thread_lock_aquire(stp_psm); +} + + +INT32 stp_psm_thread_lock_release(MTKSTP_PSM_T *stp_psm) +{ + return _stp_psm_thread_lock_release(stp_psm); +} + + + +INT32 stp_psm_do_wakeup(MTKSTP_PSM_T *stp_psm) +{ + return _stp_psm_do_wakeup(stp_psm); +} + +INT32 stp_psm_notify_stp(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_ACTION_T action) +{ + + return _stp_psm_notify_stp(stp_psm, action); +} + +INT32 stp_psm_notify_wmt_wakeup(MTKSTP_PSM_T *stp_psm) +{ + return _stp_psm_notify_wmt_wakeup_wq(stp_psm); +} + +INT32 stp_psm_notify_wmt_sleep(MTKSTP_PSM_T *stp_psm) +{ + + return _stp_psm_notify_wmt_sleep_wq(stp_psm); +} + +INT32 stp_psm_start_monitor(MTKSTP_PSM_T *stp_psm) +{ + return _stp_psm_start_monitor(stp_psm); +} + +INT32 stp_psm_is_to_block_traffic(MTKSTP_PSM_T *stp_psm) +{ + return _stp_psm_is_to_block_traffic(stp_psm); +} + +INT32 stp_psm_is_disable(MTKSTP_PSM_T *stp_psm) +{ + return _stp_psm_is_disable(stp_psm); +} + +INT32 stp_psm_has_pending_data(MTKSTP_PSM_T *stp_psm) +{ + return _stp_psm_has_pending_data(stp_psm); +} + +INT32 stp_psm_release_data(MTKSTP_PSM_T *stp_psm) +{ + return _stp_psm_release_data(stp_psm); +} + +INT32 +stp_psm_hold_data(MTKSTP_PSM_T *stp_psm, const PUINT8 buffer, const UINT32 len, const UINT8 type) +{ + return _stp_psm_hold_data(stp_psm, buffer, len, type); +} + +INT32 stp_psm_disable(MTKSTP_PSM_T *stp_psm) +{ + return _stp_psm_disable(stp_psm); +} + +INT32 stp_psm_enable(MTKSTP_PSM_T *stp_psm, INT32 idle_time_to_sleep) +{ + return _stp_psm_enable(stp_psm, idle_time_to_sleep); +} + +INT32 stp_psm_reset(MTKSTP_PSM_T *stp_psm) +{ + stp_psm_set_sleep_enable(stp_psm); + + return _stp_psm_reset(stp_psm); +} + +INT32 stp_psm_sleep_for_thermal(MTKSTP_PSM_T *stp_psm) +{ + return _stp_psm_notify_wmt_sleep_wq(stp_psm); +} + + +INT32 stp_psm_set_sleep_enable(MTKSTP_PSM_T *stp_psm) +{ + INT32 ret = 0; + + if (stp_psm) { + stp_psm->sleep_en = 1; + STP_PSM_PR_DBG("\n"); + ret = 0; + } else { + STP_PSM_PR_INFO("Null pointer\n"); + ret = -1; + } + + return ret; +} + + +INT32 stp_psm_set_sleep_disable(MTKSTP_PSM_T *stp_psm) +{ + INT32 ret = 0; + + if (stp_psm) { + stp_psm->sleep_en = 0; + STP_PSM_PR_DBG("\n"); + ret = 0; + } else { + STP_PSM_PR_INFO("Null pointer\n"); + ret = -1; + } + + return ret; +} + + +/* stp_psm_check_sleep_enable - to check if sleep cmd is enabled or not + * @ stp_psm - pointer of psm + * + * return 1 if sleep is enabled; else return 0 if disabled; else error code + */ +INT32 stp_psm_check_sleep_enable(MTKSTP_PSM_T *stp_psm) +{ + INT32 ret = 0; + + if (stp_psm) { + ret = stp_psm->sleep_en; + STP_PSM_PR_DBG("%s\n", ret ? "enabled" : "disabled"); + } else { + STP_PSM_PR_INFO("Null pointer\n"); + ret = -1; + } + + return ret; +} + +static INT32 _stp_psm_dbg_dmp_in(STP_PSM_RECORD_T *stp_psm_dbg, UINT32 flag, UINT32 line_num) +{ + INT32 index = 0; + struct timeval now; + + if (stp_psm_dbg) { + osal_lock_unsleepable_lock(&stp_psm_dbg->lock); + osal_do_gettimeofday(&now); + index = stp_psm_dbg->in - 1; + index = (index + STP_PSM_DBG_SIZE) % STP_PSM_DBG_SIZE; + STP_PSM_PR_DBG("index(%d)\n", index); + stp_psm_dbg->queue[stp_psm_dbg->in].prev_flag = stp_psm_dbg->queue[index].cur_flag; + stp_psm_dbg->queue[stp_psm_dbg->in].cur_flag = flag; + stp_psm_dbg->queue[stp_psm_dbg->in].line_num = line_num; + stp_psm_dbg->queue[stp_psm_dbg->in].package_no = g_record_num++; + stp_psm_dbg->queue[stp_psm_dbg->in].sec = now.tv_sec; + stp_psm_dbg->queue[stp_psm_dbg->in].usec = now.tv_usec; + stp_psm_dbg->size++; + STP_PSM_PR_DBG("pre_Flag = %d, cur_flag = %d\n", stp_psm_dbg->queue[stp_psm_dbg->in].prev_flag, + stp_psm_dbg->queue[stp_psm_dbg->in].cur_flag); + stp_psm_dbg->size = (stp_psm_dbg->size > STP_PSM_DBG_SIZE) ? STP_PSM_DBG_SIZE : stp_psm_dbg->size; + stp_psm_dbg->in = (stp_psm_dbg->in >= (STP_PSM_DBG_SIZE - 1)) ? (0) : (stp_psm_dbg->in + 1); + STP_PSM_PR_DBG("record size = %d, in = %d num = %d\n", stp_psm_dbg->size, stp_psm_dbg->in, line_num); + + osal_unlock_unsleepable_lock(&stp_psm_dbg->lock); + } + return 0; +} + +static INT32 _stp_psm_dbg_out_printk(STP_PSM_RECORD_T *stp_psm_dbg) +{ + + UINT32 dumpSize = 0; + UINT32 inIndex = 0; + UINT32 outIndex = 0; + + if (!stp_psm_dbg) { + STP_PSM_PR_ERR("NULL g_stp_psm_dbg reference\n"); + return -1; + } + osal_lock_unsleepable_lock(&stp_psm_dbg->lock); + + inIndex = stp_psm_dbg->in; + dumpSize = stp_psm_dbg->size; + if (dumpSize == STP_PSM_DBG_SIZE) + outIndex = inIndex; + else + outIndex = ((inIndex + STP_PSM_DBG_SIZE) - dumpSize) % STP_PSM_DBG_SIZE; + + STP_PSM_PR_INFO("loged record size = %d, in(%d), out(%d)\n", dumpSize, inIndex, outIndex); + while (dumpSize > 0) { + + pr_info("STP-PSM:%d.%ds, n(%d)pre_flag(%d)cur_flag(%d)line_no(%d)\n", + stp_psm_dbg->queue[outIndex].sec, + stp_psm_dbg->queue[outIndex].usec, + stp_psm_dbg->queue[outIndex].package_no, + stp_psm_dbg->queue[outIndex].prev_flag, + stp_psm_dbg->queue[outIndex].cur_flag, stp_psm_dbg->queue[outIndex].line_num); + + outIndex = (outIndex >= (STP_PSM_DBG_SIZE - 1)) ? (0) : (outIndex + 1); + dumpSize--; + + } + + osal_unlock_unsleepable_lock(&stp_psm_dbg->lock); + + return 0; +} + +static INT32 _stp_psm_opid_dbg_dmp_in(P_STP_PSM_OPID_RECORD p_opid_dbg, UINT32 opid, UINT32 line_num) +{ + INT32 index = 0; + struct timeval now; + UINT64 ts; + ULONG nsec; + + osal_get_local_time(&ts, &nsec); + if (p_opid_dbg) { + osal_lock_unsleepable_lock(&p_opid_dbg->lock); + osal_do_gettimeofday(&now); + index = p_opid_dbg->in - 1; + index = (index + STP_PSM_DBG_SIZE) % STP_PSM_DBG_SIZE; + STP_PSM_PR_DBG("index(%d)\n", index); + p_opid_dbg->queue[p_opid_dbg->in].prev_flag = p_opid_dbg->queue[index].cur_flag; + p_opid_dbg->queue[p_opid_dbg->in].cur_flag = opid; + p_opid_dbg->queue[p_opid_dbg->in].line_num = line_num; + p_opid_dbg->queue[p_opid_dbg->in].package_no = g_opid_record_num++; + p_opid_dbg->queue[p_opid_dbg->in].sec = now.tv_sec; + p_opid_dbg->queue[p_opid_dbg->in].usec = now.tv_usec; + p_opid_dbg->queue[p_opid_dbg->in].pid = current->pid; + p_opid_dbg->queue[p_opid_dbg->in].l_sec = ts; + p_opid_dbg->queue[p_opid_dbg->in].l_nsec = nsec; + p_opid_dbg->size++; + STP_PSM_PR_DBG("pre_opid = %d, cur_opid = %d\n", p_opid_dbg->queue[p_opid_dbg->in].prev_flag, + p_opid_dbg->queue[p_opid_dbg->in].cur_flag); + p_opid_dbg->size = (p_opid_dbg->size > STP_PSM_DBG_SIZE) ? STP_PSM_DBG_SIZE : p_opid_dbg->size; + p_opid_dbg->in = (p_opid_dbg->in >= (STP_PSM_DBG_SIZE - 1)) ? (0) : (p_opid_dbg->in + 1); + STP_PSM_PR_DBG("opid record size = %d, in = %d num = %d\n", p_opid_dbg->size, p_opid_dbg->in, + line_num); + + osal_unlock_unsleepable_lock(&p_opid_dbg->lock); + } + return 0; + +} + +static INT32 _stp_psm_opid_dbg_out_printk(P_STP_PSM_OPID_RECORD p_opid_dbg) +{ + UINT32 dumpSize = 0; + UINT32 inIndex = 0; + UINT32 outIndex = 0; + + if (!p_opid_dbg) { + STP_PSM_PR_ERR("NULL p_opid_dbg reference\n"); + return -1; + } + osal_lock_unsleepable_lock(&p_opid_dbg->lock); + + inIndex = p_opid_dbg->in; + dumpSize = p_opid_dbg->size; + if (dumpSize == STP_PSM_DBG_SIZE) + outIndex = inIndex; + else + outIndex = ((inIndex + STP_PSM_DBG_SIZE) - dumpSize) % STP_PSM_DBG_SIZE; + + STP_PSM_PR_INFO("loged record size = %d, in(%d), out(%d)\n", dumpSize, inIndex, outIndex); + while (dumpSize > 0) { + + pr_info("STP-PSM:%d.%ds, time[%llu.%06lu], n(%d)pre_flag(%d)cur_flag(%d)line_no(%d) pid(%d)\n", + p_opid_dbg->queue[outIndex].sec, + p_opid_dbg->queue[outIndex].usec, + p_opid_dbg->queue[outIndex].l_sec, + p_opid_dbg->queue[outIndex].l_nsec, + p_opid_dbg->queue[outIndex].package_no, + p_opid_dbg->queue[outIndex].prev_flag, + p_opid_dbg->queue[outIndex].cur_flag, + p_opid_dbg->queue[outIndex].line_num, p_opid_dbg->queue[outIndex].pid); + + outIndex = (outIndex >= (STP_PSM_DBG_SIZE - 1)) ? (0) : (outIndex + 1); + dumpSize--; + + } + + osal_unlock_unsleepable_lock(&p_opid_dbg->lock); + + return 0; + +} + +VOID stp_psm_print_op_history(VOID) +{ + osal_op_history_print(&stp_psm->op_history, "_stp_psm_proc"); +} + +MTKSTP_PSM_T *stp_psm_init(VOID) +{ + INT32 err = 0; + INT32 i = 0; + INT32 ret = -1; + + STP_PSM_PR_DBG("psm init\n"); + + stp_psm->work_state = ACT; + stp_psm->wmt_notify = wmt_lib_ps_stp_cb; + stp_psm->is_wmt_quick_ps_support = wmt_lib_is_quick_ps_support; + stp_psm->idle_time_to_sleep = STP_PSM_IDLE_TIME_SLEEP; + stp_psm->update_wmt_fw_patch_chip_rst = wmt_lib_update_fw_patch_chip_rst; + stp_psm->flag.data = 0; + stp_psm->stp_tx_cb = NULL; + stp_psm_set_sleep_enable(stp_psm); + + ret = osal_fifo_init(&stp_psm->hold_fifo, NULL, STP_PSM_FIFO_SIZE); + if (ret < 0) { + STP_PSM_PR_ERR("FIFO INIT FAILS\n"); + goto ERR_EXIT4; + } + + osal_fifo_reset(&stp_psm->hold_fifo); + osal_sleepable_lock_init(&stp_psm->user_lock); + /*psm_fifo_lock_init(stp_psm);*/ + osal_sleepable_lock_init(&stp_psm->hold_fifo_spinlock_global); + osal_unsleepable_lock_init(&stp_psm->wq_spinlock); + osal_sleepable_lock_init(&stp_psm->stp_psm_lock); + +/* osal_unsleepable_lock_init(&stp_psm->flagSpinlock); */ + + osal_memcpy(stp_psm->wake_lock.name, "MT662x", 6); + stp_psm->wake_lock.init_flag = 0; + osal_wake_lock_init(&stp_psm->wake_lock); + osal_event_init(&stp_psm->STPd_event); + RB_INIT(&stp_psm->rFreeOpQ, STP_OP_BUF_SIZE); + RB_INIT(&stp_psm->rActiveOpQ, STP_OP_BUF_SIZE); + /* Put all to free Q */ + for (i = 0; i < STP_OP_BUF_SIZE; i++) { + osal_signal_init(&(stp_psm->arQue[i].signal)); + _stp_psm_put_op(stp_psm, &stp_psm->rFreeOpQ, &(stp_psm->arQue[i])); + } + /* stp_psm->current_active_op = NULL; */ + stp_psm->last_active_opId = STP_OPID_PSM_INALID; + osal_op_history_init(&stp_psm->op_history, 16); + /*Generate PSM thread, to servie STP-CORE and WMT-CORE for sleeping, waking up and host awake */ + stp_psm->PSMd.pThreadData = (PVOID) stp_psm; + stp_psm->PSMd.pThreadFunc = (PVOID) _stp_psm_proc; + osal_memcpy(stp_psm->PSMd.threadName, PSM_THREAD_NAME, osal_strlen(PSM_THREAD_NAME)); + + ret = osal_thread_create(&stp_psm->PSMd); + if (ret < 0) { + STP_PSM_PR_ERR("osal_thread_create fail...\n"); + goto ERR_EXIT5; + } + /* init_waitqueue_head(&stp_psm->wait_wmt_q); */ + stp_psm->wait_wmt_q.timeoutValue = STP_PSM_WAIT_EVENT_TIMEOUT; + osal_event_init(&stp_psm->wait_wmt_q); + + err = _stp_psm_init_monitor(stp_psm); + if (err) { + STP_PSM_PR_ERR("__stp_psm_init ERROR\n"); + goto ERR_EXIT6; + } + /* Start STPd thread */ + ret = osal_thread_run(&stp_psm->PSMd); + if (ret < 0) { + STP_PSM_PR_ERR("osal_thread_run FAILS\n"); + goto ERR_EXIT6; + } + + g_stp_psm_dbg = (STP_PSM_RECORD_T *) osal_malloc(osal_sizeof(STP_PSM_RECORD_T)); + if (!g_stp_psm_dbg) { + STP_PSM_PR_ERR("stp psm dbg allocate memory fail!\n"); + return NULL; + } + osal_memset(g_stp_psm_dbg, 0, osal_sizeof(STP_PSM_RECORD_T)); + osal_unsleepable_lock_init(&g_stp_psm_dbg->lock); + + g_stp_psm_opid_dbg = (STP_PSM_OPID_RECORD *) osal_malloc(osal_sizeof(STP_PSM_OPID_RECORD)); + if (!g_stp_psm_opid_dbg) { + STP_PSM_PR_ERR("stp psm dbg allocate memory fail!\n"); + return NULL; + } + osal_memset(g_stp_psm_opid_dbg, 0, osal_sizeof(STP_PSM_OPID_RECORD)); + osal_unsleepable_lock_init(&g_stp_psm_opid_dbg->lock); + + return stp_psm; + +ERR_EXIT6: + + ret = osal_thread_destroy(&stp_psm->PSMd); + if (ret < 0) { + STP_PSM_PR_ERR("osal_thread_destroy FAILS\n"); + goto ERR_EXIT5; + } +ERR_EXIT5: + osal_fifo_deinit(&stp_psm->hold_fifo); +ERR_EXIT4: + + return NULL; +} + +INT32 stp_psm_deinit(MTKSTP_PSM_T *stp_psm) +{ + INT32 ret = -1; + + STP_PSM_PR_INFO("psm deinit\n"); + if (g_stp_psm_dbg) { + osal_unsleepable_lock_deinit(&g_stp_psm_dbg->lock); + osal_free(g_stp_psm_dbg); + g_stp_psm_dbg = NULL; + } + + if (!stp_psm) + return STP_PSM_OPERATION_FAIL; + + ret = osal_thread_destroy(&stp_psm->PSMd); + if (ret < 0) + STP_PSM_PR_ERR("osal_thread_destroy FAILS\n"); + + ret = _stp_psm_deinit_monitor(stp_psm); + if (ret < 0) + STP_PSM_PR_ERR("_stp_psm_deinit_monitor ERROR\n"); + + osal_wake_lock_deinit(&stp_psm->wake_lock); + osal_fifo_deinit(&stp_psm->hold_fifo); + osal_sleepable_lock_deinit(&stp_psm->user_lock); + /*psm_fifo_lock_deinit(stp_psm);*/ + osal_sleepable_lock_deinit(&stp_psm->hold_fifo_spinlock_global); + osal_unsleepable_lock_deinit(&stp_psm->wq_spinlock); + osal_sleepable_lock_deinit(&stp_psm->stp_psm_lock); +/* osal_unsleepable_lock_deinit(&stp_psm->flagSpinlock); */ + + return STP_PSM_OPERATION_SUCCESS; +} diff --git a/drivers/misc/mediatek/connectivity/common/common_main/core/stp_core.c b/drivers/misc/mediatek/connectivity/common/common_main/core/stp_core.c new file mode 100644 index 0000000000000000000000000000000000000000..198e7393b924da7c1637705bd7ae0c49a7c526b7 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/core/stp_core.c @@ -0,0 +1,3591 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +#include "osal_typedef.h" +#include "stp_core.h" +#include "psm_core.h" +#include "btm_core.h" +#include "stp_dbg.h" +#include "stp_sdio.h" +#include "stp_btif.h" +#include "wmt_lib.h" +#include "wmt_step.h" +#include "wmt_detect.h" + +#define PFX "[STP] " +#define STP_LOG_DBG 4 +#define STP_LOG_PKHEAD 3 +#define STP_LOG_INFO 2 +#define STP_LOG_WARN 1 +#define STP_LOG_ERR 0 + +#define STP_DEL_SIZE 2 /* STP delimiter length */ +#define STP_MAX_TX_TIMEOUT_LOOP 3 + +INT32 gStpDbgLvl = STP_LOG_INFO; +unsigned int chip_reset_only; +INT32 wmt_dbg_sdio_retry_ctrl = 1; +INT32 gCrcErrorCount; + +#define STP_POLL_CPUPCR_NUM 5 +#define STP_POLL_CPUPCR_DELAY 1 + +/* global variables */ +static const UINT8 stp_delimiter[STP_DEL_SIZE] = { 0x55, 0x55 }; + +static INT32 fgEnableNak; /* 0=enable NAK; 1=disable NAK */ +static INT32 fgEnableDelimiter; /* 0=disable Delimiter; 1=enable Delimiter */ +/* common interface */ +static IF_TX sys_if_tx; +static RX_HAS_PENDING_DATA sys_rx_has_pending_data; +static TX_HAS_PENDING_DATA sys_tx_has_pending_data; +static RX_THREAD_GET sys_rx_thread_get; +/* event/signal */ +static EVENT_SET sys_event_set; +static EVENT_TX_RESUME sys_event_tx_resume; +static FUNCTION_STATUS sys_check_function_status; +/* kernel lib */ +/* INT32 g_block_tx = 0; */ +static mtkstp_context_struct stp_core_ctx = { 0 }; + +#define STP_PSM_CORE(x) ((x).psm) +#define STP_SET_PSM_CORE(x, v) ((x).psm = (v)) + +#define STP_BTM_CORE(x) ((x).btm) +#define STP_SET_BTM_CORE(x, v) ((x).btm = (v)) + +#define STP_IS_ENABLE(x) ((x).f_enable != 0) +#define STP_NOT_ENABLE(x) ((x).f_enable == 0) +#define STP_SET_ENABLE(x, v) ((x).f_enable = (v)) + +#define STP_IS_READY(x) ((x).f_ready != 0) +#define STP_NOT_READY(x) ((x).f_ready == 0) +#define STP_SET_READY(x, v) ((x).f_ready = (v)) + +#define STP_PENDING_TYPE(x) ((x).f_pending_type) +#define STP_SET_PENDING_TYPE(x, v) ((x).f_pending_type = (v)) + +#define STP_BLUE_ANGEL (0) +#define STP_BLUE_Z (1) +#define STP_BT_STK(x) ((x).f_bluez) +#define STP_BT_STK_IS_BLUEZ(x) ((x).f_bluez == (STP_BLUE_Z)) +#define STP_SET_BT_STK(x, v) ((x).f_bluez = (v)) + +#define STP_IS_ENABLE_DBG(x) ((x).f_dbg_en != 0) +#define STP_NOT_ENABLE_DBG(x) ((x).f_dbg_en == 0) +#define STP_SET_ENABLE_DBG(x, v) ((x).f_dbg_en = (v)) + +#define STP_IS_ENABLE_RST(x) ((x).f_autorst_en != 0) +#define STP_NOT_ENABLE_RST(x) ((x).f_autorst_en == 0) +#define STP_SET_ENABLE_RST(x, v) ((x).f_autorst_en = (v)) + +#define STP_SUPPORT_PROTOCOL(x) ((x).f_mode) +#define STP_SET_SUPPORT_PROTOCOL(x, v) ((x).f_mode = (v)) + +#define STP_FW_COREDUMP_FLAG(x) ((x).f_coredump) +#define STP_SET_FW_COREDUMP_FLAG(x, v) ((x).f_coredump = (v)) +#define STP_ENABLE_FW_COREDUMP(x, v) ((x).en_coredump = (v)) +#define STP_ENABLE_FW_COREDUMP_FLAG(x) ((x).en_coredump) +#define STP_EMI_DUMP_FLAG(x) ((x).f_emidump) +#define STP_SET_EMI_DUMP_FLAG(x, v) ((x).f_emidump = (v)) + +#define STP_WMT_LAST_CLOSE(x) ((x).f_wmt_last_close) +#define STP_SET_WMT_LAST_CLOSE(x, v) ((x).f_wmt_last_close = (v)) + +#define STP_ASSERT(x) ((x).f_evt_err_assert) +#define STP_SET_ASSERT(x, v) ((x).f_evt_err_assert = (v)) + +#define STP_ASSERT_IN_PROGRESS(x) ((x).f_assert_in_progress) +#define STP_SET_ASSERT_IN_PROGRESS(x, v) ((x).f_assert_in_progress = (v)) + +#define STP_IS_SUPPORT_GPSL5(x) ((x).f_gpsl5_en != 0) +#define STP_NOT_SUPPORT_GPSL5(x) ((x).f_gpsl5_en == 0) +#define STP_SET_SUPPORT_GPSL5(x, v) ((x).f_gpsl5_en = (v)) + + +/*[PatchNeed]Need to calculate the timeout value*/ +static UINT32 mtkstp_tx_timeout = MTKSTP_TX_TIMEOUT; +static mtkstp_parser_state prev_state = -1; + + +#define CONFIG_DEBUG_STP_TRAFFIC_SUPPORT +#ifdef CONFIG_DEBUG_STP_TRAFFIC_SUPPORT +static MTKSTP_DBG_T *g_mtkstp_dbg; +#endif +static VOID stp_dbg_pkt_log(INT32 type, INT32 txAck, INT32 seq, INT32 crc, INT32 dir, + const PUINT8 pBuf, INT32 len); +static MTK_WCN_BOOL stp_check_crc(PUINT8 buffer, UINT32 length, UINT16 crc); +static VOID stp_update_tx_queue(UINT32 txseq); +static VOID stp_rest_ctx_state(VOID); +static VOID stp_change_rx_state(mtkstp_parser_state next); +static void stp_tx_timeout_handler(timer_handler_arg arg); +static VOID stp_dump_data(const PUINT8 buf, const PUINT8 title, const UINT32 len); +static VOID stp_dump_tx_queue(UINT32 txseq); +static INT32 stp_is_apply_powersaving(VOID); +#if 0 +static INT32 stp_is_privileges_cmd(const UINT8 *buffer, const UINT32 length, const UINT8 type); +#endif +static MTK_WCN_BOOL stp_is_tx_res_available(UINT32 length); +static VOID stp_add_to_tx_queue(const PUINT8 buffer, UINT32 length); +static INT32 stp_add_to_rx_queue(PUINT8 buffer, UINT32 length, UINT8 type); +static VOID stp_send_tx_queue(UINT32 txseq); +static VOID stp_send_ack(UINT8 txAck, UINT8 nak); +static INT32 stp_process_rxack(VOID); +static VOID stp_process_packet(VOID); +static VOID stp_process_header_only_packet(VOID); +static VOID stp_sdio_process_packet(VOID); +static VOID stp_trace32_dump(VOID); +static VOID stp_sdio_trace32_dump(VOID); +static LONG stp_parser_dmp_num(PUINT8 str); +static INT32 wmt_parser_data(PUINT8 buffer, UINT32 length, UINT8 type); +static MTK_WCN_BOOL mtk_wcn_stp_is_info_task(VOID); + +INT32 __weak mtk_wcn_consys_stp_btif_logger_ctrl(enum _ENUM_BTIF_DBG_ID_ flag) +{ + STP_INFO_FUNC("in combo flow, mtk_wcn_consys_stp_btif_logger_ctrl is not define!!\n"); + return 0; +} +INT32 __weak mtk_wcn_consys_stp_btif_open(VOID) +{ + STP_INFO_FUNC("in combo flow, mtk_wcn_consys_stp_btif_open is not define!!\n"); + + return 0; +} + +INT32 __weak mtk_wcn_consys_stp_btif_close(VOID) +{ + STP_INFO_FUNC("in combo flow, mtk_wcn_consys_stp_btif_close is not define!!\n"); + + return 0; +} + +INT32 __weak mtk_wcn_consys_stp_btif_rx_cb_register(MTK_WCN_BTIF_RX_CB rx_cb) +{ + STP_INFO_FUNC("in combo flow, mtk_wcn_consys_stp_btif_rx_cb_register is not define!!\n"); + return 0; +} + +INT32 __weak mtk_wcn_consys_stp_btif_tx(const PUINT8 pBuf, const UINT32 len, PUINT32 written_len) +{ + STP_INFO_FUNC("in combo flow, mtk_wcn_consys_stp_btif_tx is not define!!\n"); + + return 0; +} + +INT32 __weak mtk_wcn_consys_stp_btif_wakeup(VOID) +{ + STP_INFO_FUNC("in combo flow, mtk_wcn_consys_stp_btif_wakeup is not define!!\n"); + + return 0; +} + +INT32 __weak mtk_wcn_consys_stp_btif_lpbk_ctrl(enum _ENUM_BTIF_LPBK_MODE_ mode) +{ + STP_INFO_FUNC("in combo flow, mtk_wcn_consys_stp_btif_lpbk_ctrl is not define!!\n"); + + return 0; +} + +static INT32 stp_ctx_lock_init(mtkstp_context_struct *pctx) +{ +#if CFG_STP_CORE_CTX_SPIN_LOCK +#if defined(CONFIG_PROVE_LOCKING) + osal_unsleepable_lock_init(&((pctx)->stp_mutex)); + return 0; +#else + return osal_unsleepable_lock_init(&((pctx)->stp_mutex)); +#endif +#else +#if defined(CONFIG_PROVE_LOCKING) + osal_sleepable_lock_init(&((pctx)->stp_mutex)); + return 0; +#else + return osal_sleepable_lock_init(&((pctx)->stp_mutex)); +#endif +#endif +} + +static INT32 stp_ctx_lock_deinit(mtkstp_context_struct *pctx) +{ +#if CFG_STP_CORE_CTX_SPIN_LOCK + return osal_unsleepable_lock_deinit(&((pctx)->stp_mutex)); +#else + return osal_sleepable_lock_deinit(&((pctx)->stp_mutex)); +#endif +} + +static INT32 stp_ctx_lock(mtkstp_context_struct *pctx) +{ + /* dump_stack(); */ + /* pr_debug("stp_lock\n\r"); */ +#if CFG_STP_CORE_CTX_SPIN_LOCK + return osal_lock_unsleepable_lock(&((pctx)->stp_mutex)); +#else + return osal_lock_sleepable_lock(&((pctx)->stp_mutex)); +#endif +} + +static INT32 stp_ctx_unlock(mtkstp_context_struct *pctx) +{ + /* dump_stack(); */ + /* pr_debug("stp_unlock\n\r"); */ + +#if CFG_STP_CORE_CTX_SPIN_LOCK + return osal_unlock_unsleepable_lock(&((pctx)->stp_mutex)); +#else + return osal_unlock_sleepable_lock(&((pctx)->stp_mutex)); +#endif +} + + +MTK_WCN_BOOL mtk_wcn_stp_dbg_level(INT32 dbglevel) +{ + if (dbglevel >= 0 && dbglevel <= 4) { + gStpDbgLvl = dbglevel; + STP_INFO_FUNC("gStpDbgLvl = %d\n", gStpDbgLvl); + return MTK_WCN_BOOL_TRUE; + } + STP_INFO_FUNC("invalid stp debug level. gStpDbgLvl = %d\n", gStpDbgLvl); + return MTK_WCN_BOOL_FALSE; +} + +static VOID stp_sdio_process_packet(VOID) +{ + MTK_WCN_BOOL is_function_active = 0; + + if ((stp_core_ctx.parser.type == BT_TASK_INDX) && STP_BT_STK_IS_BLUEZ(stp_core_ctx)) { + INT32 b; + /*Indicate packet to hci_stp */ + if (gStpDbgLvl >= STP_LOG_DBG) + stp_dump_data(stp_core_ctx.rx_buf, "indicate_to_bt_core", stp_core_ctx.rx_counter); + b = mtk_wcn_sys_if_rx(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter); + if (b) + STP_ERR_FUNC("mtk_wcn_sys_if_rx is NULL\n"); + } else { + is_function_active = ((*sys_check_function_status)(stp_core_ctx.parser.type, + OP_FUNCTION_ACTIVE) == STATUS_FUNCTION_ACTIVE); + /*check type and function if active? */ + if ((stp_core_ctx.parser.type < MTKSTP_MAX_TASK_NUM) && + (is_function_active == MTK_WCN_BOOL_TRUE)) { + if (stp_core_ctx.parser.type == WMT_TASK_INDX) + wmt_parser_data(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter, + stp_core_ctx.parser.type); + else { + stp_add_to_rx_queue(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter, + stp_core_ctx.parser.type); + + /*notify corresponding subfunction of incoming data */ + (*sys_event_set)(stp_core_ctx.parser.type); + } + } else { + if (is_function_active == MTK_WCN_BOOL_FALSE) { + STP_ERR_FUNC("function type = %d is inactive, so no en-queue to rx\n", + stp_core_ctx.parser.type); + } else { + STP_ERR_FUNC("mtkstp_process_packet: type = %x, the type is invalid\n", + stp_core_ctx.parser.type); + } + } + } +} + +static MTK_WCN_BOOL mtk_wcn_stp_is_info_task(VOID) +{ + if (STP_NOT_SUPPORT_GPSL5(stp_core_ctx) && (stp_core_ctx.parser.type == INFO_TASK_INDX)) + return MTK_WCN_BOOL_TRUE; + else + return MTK_WCN_BOOL_FALSE; +} + +static VOID stp_trace32_dump(VOID) +{ + if (STP_IS_ENABLE_DBG(stp_core_ctx) && (stp_core_ctx.parser.type == STP_TASK_INDX)) { + STP_INFO_FUNC("[len=%d][type=%d]%s\n", stp_core_ctx.rx_counter, + stp_core_ctx.parser.type, stp_core_ctx.rx_buf); + } + /*Runtime FW Log */ + else if (STP_IS_ENABLE_DBG(stp_core_ctx) && mtk_wcn_stp_is_info_task()) { + stp_dbg_log_pkt(g_mtkstp_dbg, STP_DBG_FW_LOG, STP_TASK_INDX, 5, 0, 0, 0, + (stp_core_ctx.rx_counter + 1), stp_core_ctx.rx_buf); + mtk_wcn_stp_dbg_dump_package(); + } + /*Normal mode: whole chip reset */ + else { + /*Aee Kernel Warning Message Shown First */ + /* (*sys_dbg_assert_aee)("[MT662x]f/w Assert", stp_core_ctx.rx_buf); */ + mtk_wcn_stp_dbg_dump_package(); + + osal_dbg_assert_aee(stp_core_ctx.rx_buf, stp_core_ctx.rx_buf); + /*Whole Chip Reset Procedure Invoke */ + if (STP_IS_ENABLE_RST(stp_core_ctx)) { + STP_SET_READY(stp_core_ctx, 0); + stp_btm_notify_wmt_rst_wq(STP_BTM_CORE(stp_core_ctx)); + } else + STP_INFO_FUNC("No to launch whole chip reset! for debugging purpose\n"); + } +} + +static LONG stp_parser_dmp_num(PUINT8 str) +{ + PUINT8 pParserDmpStr = "Dump="; + PUINT8 pStr = NULL; + PUINT8 pDtr = NULL; + PUINT8 pTemp = NULL; + INT32 ret = -1; + UINT32 len = 0; + UINT8 tempBuf[64] = {0}; + LONG res; + + + if (!str) { + STP_DBG_PR_ERR("NULL string source\n"); + return -1; + } + + pStr = str; + pDtr = osal_strstr(pStr, pParserDmpStr); + if (pDtr != NULL) { + pDtr += osal_strlen(pParserDmpStr); + pTemp = pDtr; + while (*pTemp >= '0' && *pTemp <= '9') + pTemp++; + } else { + STP_DBG_PR_WARN("parser string 'Dump=' is not found\n"); + return -2; + } + len = pTemp - pDtr; + osal_memcpy(&tempBuf[0], pDtr, len); + tempBuf[len] = '\0'; + ret = osal_strtol(tempBuf, 10, &res); + if (ret) { + STP_DBG_PR_ERR(" get 'Dump=' from firmware failed (%d)", ret); + return -4; + } + + return res; +} + +static VOID stp_sdio_trace32_dump(VOID) +{ + LONG dmp_num = 0; + int coredump_end_str_len = osal_strlen("coredump end"); + int len; + + if (STP_IS_ENABLE_DBG(stp_core_ctx) && (stp_core_ctx.parser.type == STP_TASK_INDX) && + (mtk_wcn_stp_coredump_flag_get() != 0)) { + if (stp_core_ctx.rx_counter != 0) { + STP_SET_READY(stp_core_ctx, 0); + mtk_wcn_stp_ctx_save(); + if (stp_core_ctx.assert_info_cnt == 0) { + dmp_num = stp_parser_dmp_num(stp_core_ctx.rx_buf); + if (dmp_num > 0 && dmp_num < PARSER_CORE_DUMP_NUM) { + STP_INFO_FUNC("parser dmp_num is %ld\n", dmp_num); + stp_dbg_dump_num(dmp_num); + } else if (dmp_num > PARSER_CORE_DUMP_NUM) { + STP_INFO_FUNC("parser dmp_num is out of range %ld\n", + dmp_num); + stp_dbg_dump_num(PARSER_CORE_DUMP_NUM); + } else { + STP_INFO_FUNC("parser dmp_num not found %ld\n", dmp_num); + stp_dbg_dump_num(CORE_DUMP_NUM); + } + } + /*STP_DBG_FW_ASSERT */ + stp_dbg_log_pkt(g_mtkstp_dbg, STP_DBG_FW_DMP, STP_TASK_INDX, 0, 0, 0, 0, + (stp_core_ctx.rx_counter + 1), stp_core_ctx.rx_buf); + } + stp_core_ctx.assert_info_cnt++; + if (stp_core_ctx.assert_info_cnt == 20) + STP_INFO_FUNC("only dump 20 packages from the beginning\n"); + else if (stp_core_ctx.assert_info_cnt < 20) + osal_err_print("[len=%d][type=%d]counter[%d]\n%s\n", stp_core_ctx.rx_counter, + stp_core_ctx.parser.type, stp_core_ctx.assert_info_cnt, stp_core_ctx.rx_buf); + + len = stp_core_ctx.rx_counter - coredump_end_str_len - 2; + if ((len >= 0) && + (stp_core_ctx.rx_counter < MTKSTP_BUFFER_SIZE) && + (osal_strncmp("coredump end", stp_core_ctx.rx_buf + + len, coredump_end_str_len) == 0)) { + STP_INFO_FUNC("%d coredump packets received\n", stp_core_ctx.assert_info_cnt); + STP_ERR_FUNC("coredump end\n"); + mtk_wcn_stp_ctx_restore(); + } + } + /*Runtime FW Log */ + else if (STP_IS_ENABLE_DBG(stp_core_ctx) && mtk_wcn_stp_is_info_task()) { + stp_dbg_log_pkt(g_mtkstp_dbg, STP_DBG_FW_LOG, STP_TASK_INDX, 5, 0, 0, 0, + (stp_core_ctx.rx_counter + 1), stp_core_ctx.rx_buf); + mtk_wcn_stp_dbg_dump_package(); + } + /*Normal mode: whole chip reset */ + else { + /*Aee Kernel Warning Message Shown First */ + /* (*sys_dbg_assert_aee)("[MT662x]f/w Assert", stp_core_ctx.rx_buf); */ + mtk_wcn_stp_dbg_dump_package(); + if (mtk_wcn_stp_coredump_flag_get() == 0) { + osal_err_print("[len=%d][type=%d]\n%s\n", stp_core_ctx.rx_counter, + stp_core_ctx.parser.type, stp_core_ctx.rx_buf); + STP_ERR_FUNC("fw error happened but coredump disabled\n"); + } else + osal_dbg_assert_aee(stp_core_ctx.rx_buf, stp_core_ctx.rx_buf); + /*Whole Chip Reset Procedure Invoke */ + if (STP_IS_ENABLE_RST(stp_core_ctx)) { + STP_SET_READY(stp_core_ctx, 0); + stp_btm_notify_wmt_rst_wq(STP_BTM_CORE(stp_core_ctx)); + } else + STP_INFO_FUNC("No to launch whole chip reset! for debugging purpose\n"); + } +} + +static VOID stp_process_header_only_packet(VOID) +{ + if (stp_core_ctx.parser.length == 0) { + INT32 fgTriggerResume = (-1); + /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ + stp_ctx_lock(&stp_core_ctx); + if (stp_core_ctx.inband_rst_set == 0) { + stp_dbg_pkt_log(STP_TASK_INDX, + stp_core_ctx.parser.ack, + stp_core_ctx.parser.seq, + 5, /* STP type id */ + PKT_DIR_RX, + NULL, + 0); + fgTriggerResume = stp_process_rxack(); + } else { + STP_WARN_FUNC + ("Now it's inband reset process and drop ACK packet.\n"); + } + if (fgTriggerResume == 0) { + /* notify adaptation layer for + * possible tx resume mechanism + */ + (*sys_event_tx_resume) (stp_core_ctx.sequence.winspace); + } + stp_ctx_unlock(&stp_core_ctx); + /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ + stp_change_rx_state(MTKSTP_SYNC); + stp_core_ctx.rx_counter = 0; + } else { + stp_change_rx_state(MTKSTP_DATA); + stp_core_ctx.rx_counter = 0; + } +} + +#if 0 +/***************************************************************************** +* FUNCTION +* crc16 +* DESCRIPTION +* Compute the CRC-16 for the data buffer +* PARAMETERS +* crc [IN] previous CRC value +* buffer [IN] data buffer +* length [IN] data buffer length +* RETURNS +* the updated CRC value +*****************************************************************************/ +static UINT16 crc16(const UINT8 *buffer, const UINT32 length) +{ + UINT32 crc, i; + + /* FIXME: Add STP checksum feature */ + crc = 0; + for (i = 0; i < length; i++, buffer++) + crc = (crc >> 8) ^ crc16_table[(crc ^ (*buffer)) & 0xff]; + return crc; +} + +#endif + + +VOID stp_dbg_pkt_log(INT32 type, INT32 txAck, INT32 seq, INT32 crc, INT32 dir, const PUINT8 pBuf, + INT32 len) +{ + +#ifndef CONFIG_LOG_STP_INTERNAL + return; +#endif + + if (STP_IS_ENABLE_DBG(stp_core_ctx)) { + if (STP_IS_READY(stp_core_ctx) || + (!STP_IS_READY(stp_core_ctx) && (type > WIFI_TASK_INDX) + && (type != ANT_TASK_INDX) && (len != 0))) + stp_dbg_log_pkt(g_mtkstp_dbg, STP_DBG_PKT, type, /* type */ + txAck, /* ack */ + seq, /* seq */ + crc, /* crc */ + dir, /* dir */ + len, /* len */ + pBuf); /* body */ + } else { + STP_DBG_FUNC("stp_dbg not enabled or not ready or len is 0\n"); + } +} + +/***************************************************************************** +* FUNCTION +* stp_check_crc +* DESCRIPTION +* check the check sum of packet payload +* PARAMETERS +* pdata [IN] the data want to check +* length [IN] the length of pdata +* crc [IN] the crc of pdata +* RETURNS +* KAL_TRUE crc is ok +* KAL_FALSE crc is wrong +*****************************************************************************/ +static MTK_WCN_BOOL stp_check_crc(PUINT8 buffer, UINT32 length, UINT16 crc) +{ + /*----------------------------------------------------------------*/ + /* Local Variables */ + /*----------------------------------------------------------------*/ + UINT16 checksum; + + /*----------------------------------------------------------------*/ + /* Code Body */ + /*----------------------------------------------------------------*/ + + /* FIXME: Add STP feature: check or skip crc */ + + checksum = osal_crc16(buffer, length); + if (checksum == crc) + return MTK_WCN_BOOL_TRUE; + STP_ERR_FUNC("CRC fail, length = %d, rx = %x, calc = %x \r\n", length, crc, checksum); + return MTK_WCN_BOOL_FALSE; +} + +/***************************************************************************** +* FUNCTION +* stp_update_tx_queue +* DESCRIPTION +* update packet's ACK field +* PARAMETERS +* txseq [IN] index of the tx packet which we want to update +* RETURNS +* void +*****************************************************************************/ +static void stp_update_tx_queue(UINT32 txseq) +{ + INT32 tx_read, i; + UINT8 checksum = 0; + + tx_read = stp_core_ctx.tx_start_addr[txseq]; + if (tx_read < 0) + return; + + stp_core_ctx.tx_buf[tx_read] &= 0xf8; + stp_core_ctx.tx_buf[tx_read] |= stp_core_ctx.sequence.txack; + + for (i = 0; i < 3; i++) { + checksum += stp_core_ctx.tx_buf[tx_read]; + tx_read++; + if (tx_read >= MTKSTP_BUFFER_SIZE) + tx_read -= MTKSTP_BUFFER_SIZE; + } + + stp_core_ctx.tx_buf[tx_read] = checksum; +} + +/***************************************************************************** +* FUNCTION +* stp_rest_ctx_state +* DESCRIPTION +* Reset stp context state variables only. Mutex and timer resources are not touched. +* +* PARAMETERS +* void +* RETURNS +* void +*****************************************************************************/ +static VOID stp_rest_ctx_state(VOID) +{ + INT32 i; + + stp_ctx_lock(&stp_core_ctx); + stp_core_ctx.rx_counter = 0; + + /*reset rx buffer pointer */ + for (i = 0; i < MTKSTP_MAX_TASK_NUM; i++) { + stp_core_ctx.ring[i].read_p = 0; + stp_core_ctx.ring[i].write_p = 0; + } + + /*reset tx buffer pointer */ + stp_core_ctx.tx_write = 0; + stp_core_ctx.tx_read = 0; + + /*reset STP protocol context */ + stp_core_ctx.parser.state = MTKSTP_SYNC; + stp_core_ctx.sequence.txseq = 0; + stp_core_ctx.sequence.txack = 7; + stp_core_ctx.sequence.rxack = 7; + stp_core_ctx.sequence.winspace = MTKSTP_WINSIZE; + stp_core_ctx.sequence.expected_rxseq = 0; + stp_core_ctx.sequence.retry_times = 0; + stp_core_ctx.sequence.tx_timeout_loop = 0; + stp_core_ctx.sequence.rx_resync = 0; + stp_core_ctx.sequence.rx_resync_seq = 0xFF; + stp_core_ctx.inband_rst_set = 0; + + stp_ctx_unlock(&stp_core_ctx); +} + +/***************************************************************************** +* FUNCTION +* stp_change_rx_state +* DESCRIPTION +* change the rx fsm of STP to "next" +* PARAMETERS +* next [IN] the next state of rx fsm +* RETURNS +* void +*****************************************************************************/ +static VOID stp_change_rx_state(mtkstp_parser_state next) +{ + prev_state = stp_core_ctx.parser.state; + stp_core_ctx.parser.state = next; +} + +/* static void stp_tx_timeout_handler(void){ */ +static void stp_tx_timeout_handler(timer_handler_arg arg) +{ + if (mtk_wcn_stp_coredump_start_get() == 1) { + STP_WARN_FUNC("Starting coredump, skip tx retry.\n"); + return; + } + STP_WARN_FUNC("call retry btm retry wq ...\n"); + /*shorten the softirq lattency */ + stp_btm_notify_stp_retry_wq(STP_BTM_CORE(stp_core_ctx)); +} + +VOID stp_do_tx_timeout(VOID) +{ + UINT32 seq; + UINT32 ret; + UINT8 resync[4]; + INT32 tx_pending_state; + INT32 rx_pending_state; + + STP_WARN_FUNC + ("==============================================================================\n"); + osal_dump_thread_state("btif_rxd"); + if (!mtk_wcn_stp_is_sdio_mode()) + mtk_wcn_consys_stp_btif_logger_ctrl(BTIF_DUMP_BTIF_IRQ); + + tx_pending_state = sys_tx_has_pending_data(); + /* Sys_rx_has_pending_data cannot be called after stp_ctx_lock(&stp_core_ctx), + * there will be a deadlock problem, because sys_rx_has_pending_data will take + * the mutex of btif_rxd, and btif_rxd may need to return TX ack during parsing + * data process. This will take stp_ctx_lock(&stp_core_ctx), causing deadlock + */ + rx_pending_state = sys_rx_has_pending_data(); + STP_INFO_FUNC("check tx/rx has pending data(%d/%d).\n", tx_pending_state, rx_pending_state); + stp_ctx_lock(&stp_core_ctx); + + if (stp_core_ctx.sequence.retry_times > (MTKSTP_RETRY_LIMIT)) { + STP_INFO_FUNC("STP retry times(%d) have reached retry limit,stop it\n", + stp_core_ctx.sequence.retry_times); + stp_ctx_unlock(&stp_core_ctx); + return; + } + + seq = stp_core_ctx.sequence.rxack; + INDEX_INC(seq); + + if (seq != stp_core_ctx.sequence.txseq) { + osal_memset(&resync[0], 0x7f, 4); + (*sys_if_tx) (&resync[0], 4, &ret); + if (ret != 4) { + STP_ERR_FUNC("mtkstp_tx_timeout_handler: send resync fail\n"); + osal_assert(0); + } + + do { + /* rxack (=last rx ack), txack (=last rx seq), txseq (=next tx seq) */ + STP_WARN_FUNC("[stp.ctx]rxack/txack/txseq=%d/%d/%d(Resend from%d->%d)\n", + stp_core_ctx.sequence.rxack, + stp_core_ctx.sequence.txack, + stp_core_ctx.sequence.txseq, + seq, + (stp_core_ctx.sequence.txseq <= 0) ? (7) : + (stp_core_ctx.sequence.txseq - 1)); + stp_dump_tx_queue(seq); + + stp_send_tx_queue(seq); + INDEX_INC(seq); + } while (seq != stp_core_ctx.sequence.txseq); + + } + + osal_timer_stop(&stp_core_ctx.tx_timer); + osal_timer_start(&stp_core_ctx.tx_timer, mtkstp_tx_timeout); + + if (stp_core_ctx.sequence.winspace == MTKSTP_WINSIZE) { + osal_timer_stop(&stp_core_ctx.tx_timer); + STP_ERR_FUNC("mtkstp_tx_timeout_handler: wmt_stop_timer\n"); + } else { + stp_core_ctx.sequence.retry_times++; + STP_ERR_FUNC("mtkstp_tx_timeout_handler, retry = %d\n", + stp_core_ctx.sequence.retry_times); + + /*If retry too much, try to recover STP by return back to initializatin state */ + /*And not to retry again */ + if (stp_core_ctx.sequence.retry_times > MTKSTP_RETRY_LIMIT) { + do { + int reason = 42; + + if (tx_pending_state > 0 || (tx_pending_state == 0 && rx_pending_state > 0)) { + if (stp_core_ctx.sequence.tx_timeout_loop < STP_MAX_TX_TIMEOUT_LOOP) { + stp_core_ctx.sequence.retry_times = 0; + stp_core_ctx.sequence.tx_timeout_loop++; + STP_INFO_FUNC("extend tx retry only.\n"); + break; + } + + STP_ERR_FUNC("there are still some data in tx/rx buffer.\n"); + /* Reason number 45 means that stp data path still has data, + * possibly a driver problem + */ + reason = 45; + } + + WMT_STEP_COMMAND_TIMEOUT_DO_ACTIONS_FUNC("STP TX no ack timeout"); + osal_timer_stop(&stp_core_ctx.tx_timer); + stp_ctx_unlock(&stp_core_ctx); + + STP_ERR_FUNC("mtkstp_tx_timeout_handler: wmt_stop_timer\n"); + + STP_ERR_FUNC("TX retry limit = %d\n", MTKSTP_RETRY_LIMIT); + osal_assert(0); + stp_notify_btm_dump(STP_BTM_CORE(stp_core_ctx)); + + /*Whole Chip Reset Procedure Invoke */ + stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); + STP_INFO_FUNC("**STP NoAck trigger firmware assert**\n"); + wmt_lib_trigger_assert(WMTDRV_TYPE_WMT, 42); + return; + } while (0); + } + } + + stp_ctx_unlock(&stp_core_ctx); + /*polling cpupcr when no ack occurs at first retry */ + stp_dbg_poll_cpupcr(STP_POLL_CPUPCR_NUM, STP_POLL_CPUPCR_DELAY, 1); + STP_WARN_FUNC + ("==============================================================================#\n"); +} + +static VOID stp_dump_data(const PUINT8 buf, const PUINT8 title, const UINT32 len) +{ + osal_buffer_dump(buf, title, len, 32); +} + +/***************************************************************************** + * FUNCTION + * stp_tx_timeout_handler + * DESCRIPTION + * tx timeout handler, send resync & retransmitt + * PARAMETERS + * void + * RETURNS + * void + *****************************************************************************/ +static VOID stp_dump_tx_queue(UINT32 txseq) +{ + INT32 tx_read, tx_length, last_len; + + tx_read = stp_core_ctx.tx_start_addr[txseq]; + tx_length = stp_core_ctx.tx_length[txseq]; + + STP_ERR_FUNC("tx_seq=%d ..", txseq); + + if (tx_read + tx_length < MTKSTP_BUFFER_SIZE) + stp_dump_data(&stp_core_ctx.tx_buf[tx_read], "tx_q", (tx_length >= 8) ? (8) : (tx_length)); + else { + last_len = MTKSTP_BUFFER_SIZE - tx_read; + stp_dump_data(&stp_core_ctx.tx_buf[tx_read], "tx_q_0", (last_len >= 8) ? (8) : (last_len)); + stp_dump_data(&stp_core_ctx.tx_buf[0], "tx_q_0", + ((tx_length - last_len) ? (8) : (tx_length - last_len))); + } +} + +/***************************************************************************** +* FUNCTION +* stp_is_apply_powersaving +* DESCRIPTION +* Check if STP support power saving mode. +* PARAMETERS +* +* RETURNS +* True: support power saving False: not support power saving +*****************************************************************************/ +static INT32 stp_is_apply_powersaving(VOID) +{ + + if (STP_IS_READY(stp_core_ctx) && !stp_psm_is_disable(STP_PSM_CORE(stp_core_ctx))) { + /* osal_dbg_print("apply power saving\n"); */ + return MTK_WCN_BOOL_TRUE; + } + if (mtk_wcn_stp_is_sdio_mode()) + return MTK_WCN_BOOL_FALSE; + STP_DBG_FUNC("not apply power saving\n"); + return MTK_WCN_BOOL_FALSE; +} + +#if 0 +/***************************************************************************** +* FUNCTION +* stp_is_privileges_cmd +* DESCRIPTION +* Check if the data is privilege command +* PARAMETERS +* +* RETURNS +* True/False +*****************************************************************************/ + +static INT32 stp_is_privileges_cmd(const UINT8 *buffer, const UINT32 length, const UINT8 type) +{ + typedef struct privileges_cmd { + UINT32 length; + UINT8 type; + UINT8 buf[7]; /* MAX length of target command is only 5 currently */ + } p_cmd_t; + + p_cmd_t p_cmd_table[] = { + {0x05, WMT_TASK_INDX, {0x01, 0x03, 0x01, 0x00, 0x01} }, /* sleep command */ + {0x05, WMT_TASK_INDX, {0x01, 0x03, 0x01, 0x00, 0x02} }, /* host_awake command */ + }; + + UINT32 i; + UINT32 size = ARRAY_SIZE(p_cmd_table)); + + for (i = 0; i < size; i++) { + if (type != p_cmd_table[i].type) + continue; + + if (length != p_cmd_table[i].length) + continue; + + if (osal_memcmp(p_cmd_table[i].buf, buffer, length)) + continue; + /* matched entry is found */ + STP_DBG_FUNC("It's p_cmd_t\n"); + return MTK_WCN_BOOL_TRUE; + } + + return MTK_WCN_BOOL_FALSE; +} +#endif +/***************************************************************************** +* FUNCTION +* tx_queue_room_available +* DESCRIPTION +* check room if available, +* PARAMETERS +* buffer [IN] data buffer +* length [IN] data buffer length +* RETURNS +* void +*****************************************************************************/ +static MTK_WCN_BOOL stp_is_tx_res_available(UINT32 length) +{ + UINT32 roomLeft; + + /* + * Get available space of TX Queue + */ + if (stp_core_ctx.tx_read <= stp_core_ctx.tx_write) + roomLeft = MTKSTP_BUFFER_SIZE - stp_core_ctx.tx_write + stp_core_ctx.tx_read - 1; + else + roomLeft = stp_core_ctx.tx_read - stp_core_ctx.tx_write - 1; + if (roomLeft < length) { + STP_ERR_FUNC("%s: tx queue room shortage\n", __func__); + return MTK_WCN_BOOL_FALSE; + } + return MTK_WCN_BOOL_TRUE; +} + +/***************************************************************************** +* FUNCTION +* stp_add_to_tx_queue +* DESCRIPTION +* put data to tx queue +* PARAMETERS +* buffer [IN] data buffer +* length [IN] data buffer length +* RETURNS +* void +*****************************************************************************/ +static VOID stp_add_to_tx_queue(const PUINT8 buffer, UINT32 length) +{ + UINT32 last_len; + + /* Get available space of TX Queue */ + if (length + stp_core_ctx.tx_write < MTKSTP_BUFFER_SIZE) { + osal_memcpy(stp_core_ctx.tx_buf + stp_core_ctx.tx_write, buffer, length); + stp_core_ctx.tx_write += length; + } else { + last_len = MTKSTP_BUFFER_SIZE - stp_core_ctx.tx_write; + osal_memcpy(stp_core_ctx.tx_buf + stp_core_ctx.tx_write, buffer, last_len); + osal_memcpy(stp_core_ctx.tx_buf, buffer + last_len, length - last_len); + stp_core_ctx.tx_write = length - last_len; + } +} + +/***************************************************************************** +* FUNCTION +* stp_add_to_rx_queue +* DESCRIPTION +* put data to corresponding task's rx queue and notify corresponding task +* PARAMETERS +* buffer [IN] data buffer +* length [IN] data buffer length +* type [IN] corresponding task index +* RETURNS +* INT32 0=success, others=error +*****************************************************************************/ +static INT32 stp_add_to_rx_queue(UINT8 *buffer, UINT32 length, UINT8 type) +{ + UINT32 roomLeft, last_len; + + osal_lock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); + + if (stp_core_ctx.ring[type].read_p <= stp_core_ctx.ring[type].write_p) + roomLeft = MTKSTP_BUFFER_SIZE - stp_core_ctx.ring[type].write_p + stp_core_ctx.ring[type].read_p - 1; + else + roomLeft = stp_core_ctx.ring[type].read_p - stp_core_ctx.ring[type].write_p - 1; + + if (roomLeft < length) { + osal_unlock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); + STP_WARN_RATELIMITED_FUNC( + "Queue full, type(%d), remain buf(%d), len(%d), w_p(%d), r_p(%d)\n", + type, roomLeft, length, + stp_core_ctx.ring[type].write_p, + stp_core_ctx.ring[type].read_p); + osal_assert(0); + return -1; + } + + if (length + stp_core_ctx.ring[type].write_p < MTKSTP_BUFFER_SIZE) { + osal_memcpy(stp_core_ctx.ring[type].buffer + stp_core_ctx.ring[type].write_p, buffer, length); + stp_core_ctx.ring[type].write_p += length; + } else { + last_len = MTKSTP_BUFFER_SIZE - stp_core_ctx.ring[type].write_p; + osal_memcpy(stp_core_ctx.ring[type].buffer + stp_core_ctx.ring[type].write_p, buffer, last_len); + osal_memcpy(stp_core_ctx.ring[type].buffer, buffer + last_len, length - last_len); + stp_core_ctx.ring[type].write_p = length - last_len; + } + + osal_unlock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); + + return 0; +} + +/***************************************************************************** +* FUNCTION +* wmt_parser_data +* DESCRIPTION +* push data to wmt parser engine +* PARAMETERS +* buffer [IN] data buffer +* length [IN] data buffer length +* type [IN] corresponding task index +* RETURNS +* INT32 0=success, others=error +*****************************************************************************/ +static INT32 wmt_parser_data(PUINT8 buffer, UINT32 length, UINT8 type) +{ + UINT8 wmtsubtype; + INT32 fgRxOk = -1; + UINT32 parser_length = 0; + UINT32 packet_length = 0; + + while (parser_length < length) { + wmtsubtype = buffer[parser_length + 1]; + packet_length = buffer[parser_length + 3] << 8; + packet_length += buffer[parser_length + 2]; + STP_DBG_FUNC("wmt sub type (%d)\n", wmtsubtype); + if (wmtsubtype == WMT_LTE_COEX_FLAG) { +#if CFG_WMT_LTE_COEX_HANDLING + fgRxOk = stp_add_to_rx_queue(buffer + parser_length, packet_length + 4, COEX_TASK_INDX); + if (fgRxOk == 0) { + STP_DBG_FUNC("wmt/lte coex package!\n"); + stp_notify_btm_handle_wmt_lte_coex(STP_BTM_CORE(stp_core_ctx)); + } else + osal_buffer_dump(buffer, "coex_packet_print", length, 128); +#else + STP_WARN_FUNC("BT/WIFI & LTE coex in non-LTE projects,drop it...\n"); +#endif + } else { + fgRxOk = stp_add_to_rx_queue(buffer + parser_length, packet_length + 4, type); + if (fgRxOk == 0) { + STP_DBG_FUNC("wmt package!\n"); + (*sys_event_set)(type); + } else + osal_buffer_dump(buffer, "wmt_packet_print", length, 128); + } + parser_length += packet_length + 4; + } + + return fgRxOk; +} + +/***************************************************************************** +* FUNCTION +* stp_send_tx_queue +* DESCRIPTION +* send data in tx buffer to common interface +* PARAMETERS +* txseq [IN] sequence number of outgoing packet in tx buffer +* RETURNS +* void +*****************************************************************************/ +static VOID stp_send_tx_queue(UINT32 txseq) +{ + UINT32 ret; + INT32 tx_read, tx_length, last_len; + + tx_read = stp_core_ctx.tx_start_addr[txseq]; + tx_length = stp_core_ctx.tx_length[txseq]; + + stp_update_tx_queue(txseq); + + if (tx_read + tx_length < MTKSTP_BUFFER_SIZE) { + + (*sys_if_tx) (&stp_core_ctx.tx_buf[tx_read], tx_length, &ret); + + if (ret != tx_length) { + STP_ERR_FUNC("stp_send_tx_queue, %d/%d\n", tx_length, ret); + osal_assert(0); + } + } else { + last_len = MTKSTP_BUFFER_SIZE - tx_read; + (*sys_if_tx) (&stp_core_ctx.tx_buf[tx_read], last_len, &ret); + + if (ret != last_len) { + STP_ERR_FUNC("stp_send_tx_queue, %d/%d\n", last_len, ret); + osal_assert(0); + } + + (*sys_if_tx) (&stp_core_ctx.tx_buf[0], tx_length - last_len, &ret); + + if (ret != tx_length - last_len) { + STP_ERR_FUNC("stp_send_tx_queue, %d/%d\n", tx_length - last_len, ret); + osal_assert(0); + } + } +} + + +/***************************************************************************** +* FUNCTION +* stp_send_ack +* DESCRIPTION +* send ack packet to the peer +* PARAMETERS +* txAck [IN] Ack number +* nak [IN] 0 = ack; !0 = NAK +* RETURNS +* void +*****************************************************************************/ +static VOID stp_send_ack(UINT8 txAck, UINT8 nak) +{ + UINT8 mtkstp_header[MTKSTP_HEADER_SIZE]; + UINT32 ret; + INT32 iStatus; + + mtkstp_header[0] = 0x80 + (0 << 3) + txAck; /* stp_core_ctx.sequence.txack; */ + + if (fgEnableNak == 0) + mtkstp_header[1] = 0x00; /* disable NAK */ + else + mtkstp_header[1] = ((nak == 0) ? 0x00 : 0x80); + + mtkstp_header[2] = 0; + mtkstp_header[3] = (mtkstp_header[0] + mtkstp_header[1] + mtkstp_header[2]) & 0xff; + + stp_dbg_pkt_log(STP_TASK_INDX, txAck, 0, 0, PKT_DIR_TX, NULL, 0); + + if (fgEnableDelimiter == 1) { + iStatus = (*sys_if_tx) ((const PUINT8)(&stp_delimiter[0]), STP_DEL_SIZE, &ret); + STP_DUMP_PACKET_HEAD((PUINT8)(&stp_delimiter[0]), "tx del", STP_DEL_SIZE); + if (ret != STP_DEL_SIZE) { + STP_ERR_FUNC("stp_send_ack, %d/%d status %d\n", STP_DEL_SIZE, ret, iStatus); + osal_assert(0); + } + } + + iStatus = (*sys_if_tx) (&mtkstp_header[0], MTKSTP_HEADER_SIZE, &ret); + + if (ret != MTKSTP_HEADER_SIZE) { + STP_ERR_FUNC("stp_send_ack, %d/%d status %d\n", MTKSTP_HEADER_SIZE, ret, iStatus); + osal_assert(0); + } +} + + + +INT32 stp_send_data_no_ps(PUINT8 buffer, UINT32 length, UINT8 type) +{ + UINT8 mtkstp_header[MTKSTP_HEADER_SIZE], temp[2]; + PUINT8 p_tx_buf = NULL; + UINT16 crc; + INT32 ret = 0; + + stp_ctx_lock(&stp_core_ctx); + + /*Only WMT can set raw data */ + if (STP_NOT_ENABLE(stp_core_ctx) && WMT_TASK_INDX != type) { + /* no op */ + } else if (STP_NOT_ENABLE(stp_core_ctx) && WMT_TASK_INDX == type) { + /* ret = mtk_wcn_stp_send_data_raw(buffer, length, type); */ + } else if ((mtk_wcn_stp_is_sdio_mode() || mtk_wcn_stp_is_uart_mand_mode() || + mtk_wcn_stp_is_btif_mand_mode()) && STP_IS_ENABLE(stp_core_ctx)) { + /* STP over SDIO */ + /* osal_printtimeofday("[ STP][SDIO][ B][W]"); */ + + mtkstp_header[0] = 0x80; + mtkstp_header[1] = (type << 4) + (((length) >> 8) & 0x0f); + mtkstp_header[2] = (length) & 0xff; + mtkstp_header[3] = 0x00; + + p_tx_buf = &stp_core_ctx.tx_buf[0]; + osal_memcpy(p_tx_buf, mtkstp_header, MTKSTP_HEADER_SIZE); + p_tx_buf += MTKSTP_HEADER_SIZE; + + osal_memcpy(p_tx_buf, buffer, length); + p_tx_buf += length; + + temp[0] = 0x00; + temp[1] = 0x00; + osal_memcpy(p_tx_buf, temp, 2); + stp_dbg_pkt_log(type, + stp_core_ctx.sequence.txack, + stp_core_ctx.sequence.txseq, 0, PKT_DIR_TX, buffer, length); + (*sys_if_tx) (&stp_core_ctx.tx_buf[0], (MTKSTP_HEADER_SIZE + length + 2), &ret); + if ((MTKSTP_HEADER_SIZE + length + 2) != ret) { + STP_ERR_FUNC("stp send tx packet: %d, maybe stp_if_tx == NULL\n", ret); + osal_assert(0); + ret = 0; + } else + ret = (INT32) length; + /* osal_printtimeofday("[ STP][SDIO][ E][W]"); */ + } else if ((mtk_wcn_stp_is_uart_fullset_mode() || mtk_wcn_stp_is_btif_fullset_mode()) + && STP_IS_ENABLE(stp_core_ctx)) { + /* STP over UART OR BTIF*/ + if ((stp_core_ctx.sequence.winspace > 0) && + (stp_is_tx_res_available(MTKSTP_HEADER_SIZE + length + MTKSTP_CRC_SIZE))) { + mtkstp_header[0] = + 0x80 + (stp_core_ctx.sequence.txseq << 3) + stp_core_ctx.sequence.txack; + mtkstp_header[1] = (type << 4) + ((length & 0xf00) >> 8); + mtkstp_header[2] = length & 0xff; + mtkstp_header[3] = + (mtkstp_header[0] + mtkstp_header[1] + mtkstp_header[2]) & 0xff; + + stp_core_ctx.tx_start_addr[stp_core_ctx.sequence.txseq] = + stp_core_ctx.tx_write; + stp_core_ctx.tx_length[stp_core_ctx.sequence.txseq] = + MTKSTP_HEADER_SIZE + length + 2; + + if (fgEnableDelimiter == 1) { + stp_core_ctx.tx_length[stp_core_ctx.sequence.txseq] += STP_DEL_SIZE; + stp_add_to_tx_queue((const PUINT8)(&stp_delimiter[0]), + STP_DEL_SIZE); + } + + stp_add_to_tx_queue(mtkstp_header, MTKSTP_HEADER_SIZE); + + /*Make Payload */ + stp_add_to_tx_queue(buffer, length); + + /*Make CRC */ + crc = osal_crc16(buffer, length); + temp[0] = crc & 0xff; + temp[1] = (crc & 0xff00) >> 8; + stp_add_to_tx_queue(temp, 2); + + stp_dbg_pkt_log(type, + stp_core_ctx.sequence.txack, + stp_core_ctx.sequence.txseq, + crc, PKT_DIR_TX, buffer, length); + + /*Kick to UART */ + stp_send_tx_queue(stp_core_ctx.sequence.txseq); + INDEX_INC(stp_core_ctx.sequence.txseq); + stp_core_ctx.sequence.winspace--; + + /*Setup the Retry Timer */ + osal_timer_stop(&stp_core_ctx.tx_timer); + if (stp_core_ctx.sequence.winspace != MTKSTP_WINSIZE) + osal_timer_start(&stp_core_ctx.tx_timer, mtkstp_tx_timeout); + else + STP_ERR_FUNC("mtk_wcn_stp_send_data: wmt_stop_timer\n"); + ret = (INT32) length; + } else { + /* No winspace to send. Let caller retry */ + STP_ERR_FUNC("%s: There is no winspace/txqueue to send !!!\n", + __func__); + ret = 0; + } + } + + stp_ctx_unlock(&stp_core_ctx); + + return ret; +} + +/***************************************************************************** +* FUNCTION +* stp_process_rxack +* DESCRIPTION +* process ack packet +* PARAMETERS +* void +* RETURNS +* INT32 0=success, others=error +*****************************************************************************/ +static INT32 stp_process_rxack(VOID) +{ + INT32 j, k; + UINT8 rxack; + INT32 fgResult = -1; + + if (stp_core_ctx.sequence.rxack != stp_core_ctx.parser.ack) { + j = k = 0; + rxack = stp_core_ctx.sequence.rxack; + INDEX_INC(rxack); + while (rxack != stp_core_ctx.sequence.txseq) { + j++; + if (rxack == stp_core_ctx.parser.ack) { + k = 1; + break; + } + INDEX_INC(rxack); + } + if (k == 1) { + stp_core_ctx.sequence.rxack = stp_core_ctx.parser.ack; + stp_core_ctx.tx_read = + stp_core_ctx.tx_start_addr[rxack] + stp_core_ctx.tx_length[rxack]; + if (stp_core_ctx.tx_read >= MTKSTP_BUFFER_SIZE) + stp_core_ctx.tx_read -= MTKSTP_BUFFER_SIZE; + stp_core_ctx.sequence.winspace += j; + stp_core_ctx.sequence.retry_times = 0; + stp_core_ctx.sequence.tx_timeout_loop = 0; + + osal_timer_stop(&stp_core_ctx.tx_timer); + if (stp_core_ctx.sequence.winspace != MTKSTP_WINSIZE) + osal_timer_start(&stp_core_ctx.tx_timer, mtkstp_tx_timeout); + fgResult = 0; + } + } + + return fgResult; +} + +/***************************************************************************** +* FUNCTION +* stp_process_packet +* DESCRIPTION +* process STP packet +* PARAMETERS +* void +* RETURNS +* void +*****************************************************************************/ +static VOID stp_process_packet(VOID) +{ + INT32 fgTriggerResume = (-1); + UINT8 txAck = 0; + static INT32 fgRxOk; + MTK_WCN_BOOL b; + MTK_WCN_BOOL is_function_active = 0; + static INT32 stp_process_packet_fail_count; + + stp_dbg_pkt_log(stp_core_ctx.parser.type, + stp_core_ctx.parser.ack, + stp_core_ctx.parser.seq, + stp_core_ctx.parser.crc, PKT_DIR_RX, stp_core_ctx.rx_buf, stp_core_ctx.parser.length); + /*Optimization */ + /*If bluez, direct send packet to hci_core not through RX buffer! */ + if ((stp_core_ctx.sequence.expected_rxseq == stp_core_ctx.parser.seq) && + (stp_core_ctx.parser.type == BT_TASK_INDX) && STP_BT_STK_IS_BLUEZ(stp_core_ctx)) { + stp_core_ctx.sequence.rx_resync = 0; + + /*Indicate packet to hci_stp */ + STP_DBG_FUNC("Send Packet to BT_SUBFUCTION, len = %d\n", stp_core_ctx.rx_counter); + + b = mtk_wcn_sys_if_rx(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter); + if (b) + STP_ERR_FUNC("mtk_wcn_sys_if_rx is NULL\n"); + + /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ + stp_ctx_lock(&stp_core_ctx); + /*Process rx ack */ + fgTriggerResume = stp_process_rxack(); + stp_core_ctx.sequence.txack = stp_core_ctx.parser.seq; + INDEX_INC(stp_core_ctx.sequence.expected_rxseq); + txAck = stp_core_ctx.sequence.txack; + + /*Send ack back */ + stp_send_ack(txAck, 0); + + /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ + stp_ctx_unlock(&stp_core_ctx); + fgRxOk = 0; + } + /* sequence matches expected, enqueue packet */ + else if (stp_core_ctx.sequence.expected_rxseq == stp_core_ctx.parser.seq) { + stp_core_ctx.sequence.rx_resync = 0; + + is_function_active = + ((*sys_check_function_status) (stp_core_ctx.parser.type, OP_FUNCTION_ACTIVE) == + STATUS_FUNCTION_ACTIVE); + /*If type is valid and function works, then try to enqueue */ + if ((stp_core_ctx.parser.type < MTKSTP_MAX_TASK_NUM) && (is_function_active == MTK_WCN_BOOL_TRUE)) { + + stp_ctx_lock(&stp_core_ctx); + + fgTriggerResume = stp_process_rxack(); + stp_core_ctx.sequence.txack = stp_core_ctx.parser.seq; + INDEX_INC(stp_core_ctx.sequence.expected_rxseq); + + /*Send tx ack */ + txAck = stp_core_ctx.sequence.txack; + stp_send_ack(txAck, 0); + + stp_ctx_unlock(&stp_core_ctx); + + if (stp_core_ctx.parser.type == WMT_TASK_INDX) + fgRxOk = + wmt_parser_data(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter, + stp_core_ctx.parser.type); + else + fgRxOk = + stp_add_to_rx_queue(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter, + stp_core_ctx.parser.type); + } else { + if (is_function_active == MTK_WCN_BOOL_FALSE) { + STP_ERR_FUNC("function type = %d is inactive, so no en-queue to rx\n", + stp_core_ctx.parser.type); + fgRxOk = 0; /*drop packet */ + } else { + STP_ERR_FUNC("mtkstp_process_packet: type = %x, the type is invalid\n", + stp_core_ctx.parser.type); + fgRxOk = 0; /*drop packet */ + } + stp_ctx_lock(&stp_core_ctx); + + fgTriggerResume = stp_process_rxack(); + stp_core_ctx.sequence.txack = stp_core_ctx.parser.seq; + INDEX_INC(stp_core_ctx.sequence.expected_rxseq); + + /*Send tx ack */ + txAck = stp_core_ctx.sequence.txack; + stp_send_ack(txAck, 0); + + stp_ctx_unlock(&stp_core_ctx); + } + + /* enqueue successfully */ + if (fgRxOk == 0) { + stp_process_packet_fail_count = 0; + /*notify corresponding subfunction of incoming data */ + if (stp_core_ctx.parser.type != WMT_TASK_INDX) + (*sys_event_set) (stp_core_ctx.parser.type); + } else { + /*Queue is full */ + switch (stp_core_ctx.parser.type) { + case GPS_TASK_INDX: + /*Clear Rx Queue if GPS */ + mtk_wcn_stp_flush_rx_queue(GPS_TASK_INDX); + break; + case BT_TASK_INDX: + /* just ignore this case */ + /*notify corresponding subfunction of incoming data */ + (*sys_event_set) (stp_core_ctx.parser.type); + break; + default: + stp_process_packet_fail_count++; + /*notify corresponding subfunction of incoming data */ + (*sys_event_set) (stp_core_ctx.parser.type); + break; + } + /*enqueue fail, don't send ack and wait for peer retry */ + STP_WARN_RATELIMITED_FUNC("%s %d queue is full\n", + "Enqueue to Rx queue fail, maybe function", + stp_core_ctx.parser.type); + } + } + /*sequence not match && previous packet enqueue successfully, send the previous ACK */ + else if (fgRxOk == 0) { + STP_ERR_FUNC("mtkstp_process_packet: expected_rxseq = %d, parser.seq = %d, rx_resync = %d\n", + stp_core_ctx.sequence.expected_rxseq, + stp_core_ctx.parser.seq, + stp_core_ctx.sequence.rx_resync); + + stp_ctx_lock(&stp_core_ctx); + /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ + txAck = stp_core_ctx.sequence.txack; + stp_send_ack(txAck, 1); + stp_ctx_unlock(&stp_core_ctx); + /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ + + if (stp_core_ctx.sequence.rx_resync) { + STP_ERR_FUNC("resync'd packets, discard and send the previous (ack no =%d)\n", txAck); + if (stp_core_ctx.sequence.rx_resync_seq == 0xFF) + stp_core_ctx.sequence.rx_resync_seq = stp_core_ctx.parser.seq; + else { + INDEX_INC(stp_core_ctx.sequence.rx_resync_seq); + if (stp_core_ctx.sequence.rx_resync_seq != stp_core_ctx.parser.seq) { + STP_ERR_FUNC("resync'd packet seq not match, %d expected\n", + stp_core_ctx.sequence.rx_resync_seq); + stp_process_packet_fail_count++; + stp_core_ctx.sequence.rx_resync = 0; + } + } + } else { + stp_process_packet_fail_count++; + STP_ERR_FUNC + ("seq not match && previous packet enqueue success, send the previous (ack no =%d)\n", + txAck); + } + } + /*sequence not match && previous packet enqueue failed, do nothing, make the other side timeout */ + else { + stp_process_packet_fail_count++; + STP_ERR_FUNC + ("seq not match && previous packet enqueue failed, make the other side timeout\n"); + } + + if (fgTriggerResume == 0) { + /*[PatchNeed]Just Notificaiton, not blocking call */ + /* notify adaptation layer for possible tx resume mechanism */ + (*sys_event_tx_resume) (stp_core_ctx.sequence.winspace); + } + + if (stp_process_packet_fail_count > MTKSTP_RETRY_LIMIT) { + stp_process_packet_fail_count = 0; + STP_ERR_FUNC("The process packet fail count > 10 lastly, host trigger assert\n"); + /*Whole Chip Reset Procedure Invoke */ + wmt_lib_trigger_assert(WMTDRV_TYPE_WMT, 43); + } +} + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_init +* DESCRIPTION +* init STP kernel +* PARAMETERS +* cb_func [IN] function pointers of system APIs +* RETURNS +* INT32 0 = success, others = failure +*****************************************************************************/ +INT32 mtk_wcn_stp_init(const mtkstp_callback * const cb_func) +{ + INT32 ret = 0; + INT32 i = 0; + + /* Function pointer to point to the currently used transmission interface + */ + sys_if_tx = cb_func->cb_if_tx; + + /* Used to check tx/rx has pending data*/ + sys_rx_has_pending_data = cb_func->cb_rx_has_pending_data; + sys_tx_has_pending_data = cb_func->cb_tx_has_pending_data; + + /* Used to get rx thread */ + sys_rx_thread_get = cb_func->cb_rx_thread_get; + + /* Used to inform the function driver has received the corresponding type of information */ + sys_event_set = cb_func->cb_event_set; + + /* Used to inform the function driver can continue to send information and + * STP has resources to deal with + */ + sys_event_tx_resume = cb_func->cb_event_tx_resume; + + /* STP driver determines whether the function is enable. If not enable and + * STP has received the kind of information, and STP have the right to put it away. + */ + sys_check_function_status = cb_func->cb_check_funciton_status; + + stp_ctx_lock_init(&stp_core_ctx); + + /* Setup timer to be used to check if f/w receive the data in the specific time + * interval after being sent + */ + for (i = 0; i < MTKSTP_MAX_TASK_NUM; i++) + osal_unsleepable_lock_init(&stp_core_ctx.ring[i].mtx); + stp_core_ctx.tx_timer.timeoutHandler = stp_tx_timeout_handler; + stp_core_ctx.tx_timer.timeroutHandlerData = 0; + osal_timer_create(&stp_core_ctx.tx_timer); + + STP_SET_BT_STK(stp_core_ctx, 0); + STP_SET_ENABLE(stp_core_ctx, 0); + STP_SET_ENABLE_DBG(stp_core_ctx, 0); + STP_SET_ENABLE_RST(stp_core_ctx, 0); + STP_SET_PENDING_TYPE(stp_core_ctx, 0); + STP_SET_READY(stp_core_ctx, 0); + STP_SET_SUPPORT_PROTOCOL(stp_core_ctx, 0); + STP_SET_PSM_CORE(stp_core_ctx, stp_psm_init()); + STP_SET_FW_COREDUMP_FLAG(stp_core_ctx, 0); + STP_ENABLE_FW_COREDUMP(stp_core_ctx, 0); + STP_SET_WMT_LAST_CLOSE(stp_core_ctx, 0); + STP_SET_EMI_DUMP_FLAG(stp_core_ctx, 0); + STP_SET_ASSERT(stp_core_ctx, 0); + STP_SET_ASSERT_IN_PROGRESS(stp_core_ctx, 0); + STP_SET_SUPPORT_GPSL5(stp_core_ctx, 0); + + if (!STP_PSM_CORE(stp_core_ctx)) { + ret = (-3); + goto ERROR; + } + + STP_SET_BTM_CORE(stp_core_ctx, stp_btm_init()); + if (!STP_BTM_CORE(stp_core_ctx)) { + STP_ERR_FUNC("STP_BTM_CORE(stp_core_ctx) initialization fail!\n"); + ret = (-3); + goto ERROR; + } + + if (STP_BTM_CORE(stp_core_ctx) != NULL) + g_mtkstp_dbg = stp_dbg_init(STP_BTM_CORE(stp_core_ctx)); + else + g_mtkstp_dbg = stp_dbg_init(NULL); + + if (!g_mtkstp_dbg) { + STP_ERR_FUNC("g_mtkstp_dbg initialization fail!\n"); + ret = (-3); + goto ERROR; + } + STP_SET_ENABLE_RST(stp_core_ctx, 1); + + mtk_wcn_stp_dbg_enable(); + + /* set coredump flag for debugging earlier */ + mtk_wcn_stp_coredump_flag_ctrl(1); + + goto RETURN; + +ERROR: + stp_psm_deinit(STP_PSM_CORE(stp_core_ctx)); + +RETURN: + return ret; + +} + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_deinit +* DESCRIPTION +* deinit STP kernel +* PARAMETERS +* void +* RETURNS +* INT32 0 = success, others = failure +*****************************************************************************/ +INT32 mtk_wcn_stp_deinit(VOID) +{ + INT32 i = 0; + + sys_if_tx = NULL; + sys_event_set = NULL; + sys_event_tx_resume = NULL; + sys_check_function_status = NULL; + + stp_dbg_deinit(g_mtkstp_dbg); + stp_btm_deinit(STP_BTM_CORE(stp_core_ctx)); + stp_psm_deinit(STP_PSM_CORE(stp_core_ctx)); + + for (i = 0; i < MTKSTP_MAX_TASK_NUM; i++) + osal_unsleepable_lock_deinit(&stp_core_ctx.ring[i].mtx); + + stp_ctx_lock_deinit(&stp_core_ctx); + return 0; +} + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_btm_get_dmp +* DESCRIPTION +* get stp dump related information +* PARAMETERS +* buffer: dump placement, len: dump size +* RETURNS +* 0: Success Negative Value: Fail +*****************************************************************************/ + +INT32 mtk_wcn_stp_btm_get_dmp(PINT8 buf, PINT32 len) +{ + return stp_dbg_dmp_out(g_mtkstp_dbg, buf, len); +} + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_psm_notify_stp +* DESCRIPTION +* WMT notification to STP that power saving job is done or not +* PARAMETERS +* +* RETURNS +* 0: Sccuess Negative value: Fail +*****************************************************************************/ +INT32 mtk_wcn_stp_psm_notify_stp(const MTKSTP_PSM_ACTION_T action) +{ + return stp_psm_notify_stp(STP_PSM_CORE(stp_core_ctx), action); +} + +INT32 mtk_wcn_stp_set_psm_state(MTKSTP_PSM_STATE_T state) +{ + return stp_psm_set_state(STP_PSM_CORE(stp_core_ctx), state); +} + + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_psm_enable +* DESCRIPTION +* enable STP sleep/wakeup support +* PARAMETERS +* void +* RETURNS +* 0: Sccuess Negative value: Fail +*****************************************************************************/ +INT32 mtk_wcn_stp_psm_enable(INT32 idle_time_to_sleep) +{ + if (mtk_wcn_stp_is_ready() && mtk_wcn_stp_is_enable() && (mtk_wcn_stp_is_uart_fullset_mode() + || mtk_wcn_stp_is_sdio_mode() || mtk_wcn_stp_is_btif_fullset_mode())) + return stp_psm_enable(STP_PSM_CORE(stp_core_ctx), idle_time_to_sleep); + + STP_WARN_FUNC("STP Not Ready, Dont do Sleep/Wakeup\n"); + return -1; +} + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_psm_disable +* DESCRIPTION +* disable STP sleep/wakeup support +* PARAMETERS +* void +* RETURNS +* 0: Sccuess Negative value: Fail +*****************************************************************************/ +INT32 mtk_wcn_stp_psm_disable(VOID) +{ + if (mtk_wcn_stp_is_ready() && mtk_wcn_stp_is_enable() && (mtk_wcn_stp_is_uart_fullset_mode() + || mtk_wcn_stp_is_sdio_mode() || mtk_wcn_stp_is_btif_fullset_mode())) + return stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); + + STP_WARN_FUNC("STP Not Ready, Dont do Sleep/Wakeup\n"); + return 0; +} + +INT32 mtk_wcn_stp_psm_reset(VOID) +{ + return stp_psm_reset(STP_PSM_CORE(stp_core_ctx)); +} + +INT32 mtk_wcn_stp_dbg_disable(VOID) +{ + if (STP_IS_ENABLE_DBG(stp_core_ctx)) { + STP_INFO_FUNC("STP dbg mode is turned off\n"); + STP_SET_ENABLE_DBG(stp_core_ctx, 0); + stp_dbg_disable(g_mtkstp_dbg); + } else + STP_WARN_FUNC("STP dbg mode has been turned off\n"); + + return 0; +} + +INT32 mtk_wcn_stp_dbg_enable(VOID) +{ + if (STP_NOT_ENABLE_DBG(stp_core_ctx)) { + STP_DBG_FUNC("STP dbg mode is turned on\n"); + STP_SET_ENABLE_DBG(stp_core_ctx, 1); + stp_dbg_enable(g_mtkstp_dbg); + } else + STP_WARN_FUNC("STP dbg mode has been turned on\n"); + + return 0; +} + +INT32 mtk_wcn_stp_dbg_log_ctrl(UINT32 on) +{ + stp_dbg_log_ctrl(on); + return 0; +} + +INT32 mtk_wcn_stp_coredump_flag_ctrl(UINT32 on) +{ + static INT32 pre_coredump_mode; + + STP_ENABLE_FW_COREDUMP(stp_core_ctx, on); + STP_INFO_FUNC("%s coredump function.\n", 0 == on ? "disable" : "enable"); + if (pre_coredump_mode != on) { + if (on == 1 || on == 2) + stp_dbg_nl_init(); + else + stp_dbg_nl_deinit(); + } + pre_coredump_mode = on; + return 0; +} + +INT32 mtk_wcn_stp_coredump_flag_get(VOID) +{ + return STP_ENABLE_FW_COREDUMP_FLAG(stp_core_ctx); +} + +INT32 mtk_wcn_stp_emi_dump_flag_ctrl(UINT32 on) +{ + STP_SET_EMI_DUMP_FLAG(stp_core_ctx, on); + return 0; +} + +INT32 mtk_wcn_stp_emi_dump_flag_get(VOID) +{ + return STP_EMI_DUMP_FLAG(stp_core_ctx); +} + +static INT32 stp_parser_data_in_mand_mode(UINT32 length, UINT8 *p_data) +{ + UINT8 padding_len = 0; + INT32 remain_length = 0; + INT32 i = 0; + INT32 i_ret = 0; + + i = length; + while (i > 0) { + switch (stp_core_ctx.parser.state) { + case MTKSTP_SYNC: /* b'10 */ + /* Must be 0x80 */ + if (*p_data == 0x80) { + stp_change_rx_state(MTKSTP_NAK); + stp_core_ctx.rx_counter++; + } else { + STP_WARN_FUNC("non-0x80 (0x%x) detected, discard %d bytes\n", + *p_data, i); + osal_buffer_dump(p_data, "mandatory mode abnormal data", i, 0); + i = 0; + /* Drop them and keep at MTKSTP_SYNC state */ + continue; + } + break; + + case MTKSTP_NAK: + stp_change_rx_state(MTKSTP_LENGTH); + stp_core_ctx.parser.type = (*p_data & 0x70) >> 4; + if (stp_core_ctx.parser.type <= MTKSTP_MAX_TASK_NUM) { + stp_core_ctx.parser.length = (*p_data & 0x0f) << 8; + stp_core_ctx.rx_counter++; + } else { + STP_WARN_FUNC("abnormal type (0x%x) detected, discard %d bytes\n", + stp_core_ctx.parser.type, i); + osal_buffer_dump(p_data, "mandatory mode abnormal data", i, 0); + + /* Drop them and back to MTKSTP_SYNC state */ + i = 0; + STP_WARN_FUNC("nak to sync\n"); + stp_change_rx_state(MTKSTP_SYNC); + continue; + } + break; + + case MTKSTP_LENGTH: + stp_change_rx_state(MTKSTP_CHECKSUM); + stp_core_ctx.parser.length += *p_data; + + /*Valid length checking */ + if (stp_core_ctx.parser.length < 2000) + stp_core_ctx.rx_counter++; + else { + STP_WARN_FUNC("abnormal length (0x%x) detected, discard %d bytes\n", + stp_core_ctx.parser.length, i); + osal_buffer_dump(p_data, "mandatory mode abnormal data", i, 0); + + /* Drop them and back to MTKSTP_SYNC state */ + i = 0; + stp_change_rx_state(MTKSTP_SYNC); + stp_core_ctx.rx_counter = 0; + continue; + } + break; + + case MTKSTP_CHECKSUM: + if ((stp_core_ctx.parser.type == STP_TASK_INDX) || mtk_wcn_stp_is_info_task()) { + stp_change_rx_state(MTKSTP_FW_MSG); + stp_core_ctx.rx_counter = 0; + i -= 1; + if (i != 0) + p_data += 1; + continue; + } + if (stp_core_ctx.parser.length == 0) { + STP_WARN_FUNC("checksum to sync\n"); + stp_change_rx_state(MTKSTP_SYNC); + stp_core_ctx.rx_counter = 0; + } else { + stp_change_rx_state(MTKSTP_DATA); + stp_core_ctx.rx_counter = 0; + } + break; + + case MTKSTP_DATA: + /* block copy instead of byte copy */ + if (stp_core_ctx.parser.length < stp_core_ctx.rx_counter) { + STP_ERR_FUNC("Abnormal length in STP_DATA phase 0x%x, 0x%x\n", + stp_core_ctx.parser.length, stp_core_ctx.rx_counter); + osal_assert(0); + } + remain_length = stp_core_ctx.parser.length - stp_core_ctx.rx_counter; + if (i >= remain_length) { + /*boundary checking */ + if (stp_core_ctx.rx_counter + remain_length >= MTKSTP_BUFFER_SIZE) { + STP_ERR_FUNC("Abnormal!! Memory operation over boundary!!\n"); + stp_change_rx_state(MTKSTP_SYNC); + stp_core_ctx.rx_counter = 0; + return -1; + } + osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, remain_length); + i -= remain_length; + p_data += remain_length; + stp_core_ctx.rx_counter = stp_core_ctx.parser.length; + stp_core_ctx.parser.state = MTKSTP_CRC1; + continue; + + } else { /* only copy by data length */ + /*fixed klocwork insight issue */ + /*boundary checking */ + if (i + stp_core_ctx.rx_counter >= MTKSTP_BUFFER_SIZE) { + STP_ERR_FUNC("Abnormal!! Memory operation over boundary 2!!\n"); + stp_core_ctx.rx_counter = 0; + return -1; + } + + osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, i); + stp_core_ctx.rx_counter += i; /* all remain buffer are data */ + i = 0; + p_data += i; + continue; + } + break; + + case MTKSTP_CRC1: + stp_change_rx_state(MTKSTP_CRC2); + stp_core_ctx.parser.crc = *p_data; + break; + + case MTKSTP_CRC2: + stp_core_ctx.parser.crc += (*p_data) << 8; + if (stp_core_ctx.parser.crc != 0x00) + STP_ERR_FUNC + ("CRC (0x%x) is not 0 under SDIO/MAND mode, maybe something is wrong.\n", + stp_core_ctx.parser.crc); + /*SDIO mode do it. */ + if (mtk_wcn_stp_is_sdio_mode()) { + /*STP packet 4-bytes alignment */ + /*Discard padding bytes , otherwise make parser state machine disorder */ + if (i <= 4) { + p_data += (i - 1); + i -= (i - 1); + } else { + padding_len = (0x04 - ((stp_core_ctx.parser.length + 6) & 0x03)) & 0x03; + p_data += padding_len; + i -= padding_len; + } + } + stp_dbg_pkt_log(stp_core_ctx.parser.type, + 0, + 0, + 0, + PKT_DIR_RX, + stp_core_ctx.rx_buf, stp_core_ctx.rx_counter); + stp_sdio_process_packet(); + + stp_core_ctx.rx_counter = 0; + stp_change_rx_state(MTKSTP_SYNC); + + break; + + case MTKSTP_FW_MSG: + i_ret = -2; + if (stp_core_ctx.parser.length == 0) { + STP_INFO_FUNC("FW Assert len = 0, ignore this pkg\n"); + /*discard CRC */ + if (i > 2) { + STP_DBG_FUNC("crc discard.. i = %d\n", i); + i -= 2; + p_data += 2; + } else if (i == 2) { + STP_DBG_FUNC("crc discard.. i = %d\n", i); + i -= 2; + } + /*STP packet 4-bytes alignment */ + /*Discard padding bytes , otherwise make parser state machine disorder */ + if (i == 0) { + /*STP_DBG_FUNC("\n[STP]FW_EVENT======= no padding byte =======\n"); */ + /*do nothing */ + } else if (i <= 4) { + STP_INFO_FUNC + ("\n[STP]FW_EVENT========= block padding %d bytes =========\n", i); + p_data += i; + i -= i; + } else { + padding_len = (0x04 - ((stp_core_ctx.parser.length + 6) & 0x03)) & 0x03; + p_data += padding_len; + i -= padding_len; + STP_INFO_FUNC + ("\n[STP]FW_EVENT========= STP Agg padding %d bytes =========\n", + padding_len); + } + continue; + } + mtk_wcn_stp_assert_flow_ctrl(1); + mtk_wcn_stp_coredump_start_ctrl(1); + if (mtk_wcn_stp_get_wmt_trg_assert() == 1) + stp_btm_stop_trigger_assert_timer(STP_BTM_CORE(stp_core_ctx)); + if (STP_IS_READY(stp_core_ctx)) { + mtk_wcn_stp_dbg_dump_package(); + stp_notify_btm_dump(STP_BTM_CORE(stp_core_ctx)); + } + STP_SET_READY(stp_core_ctx, 0); + /*stp inband reset */ + if (stp_core_ctx.parser.type == STP_TASK_INDX && + stp_core_ctx.parser.seq == 0 && + stp_core_ctx.parser.ack == 0 && + stp_core_ctx.parser.length == 0 && + stp_core_ctx.inband_rst_set == 1) { + STP_INFO_FUNC("Inband reset event get! Resync STP with firmware!\n\r"); + stp_rest_ctx_state(); + stp_change_rx_state(MTKSTP_RESYNC1); + stp_core_ctx.inband_rst_set = 0; + STP_TRACE_FUNC("--\n"); + return 0; + } + /*f/w assert and exception information */ + if (stp_core_ctx.parser.length < stp_core_ctx.rx_counter) { + STP_ERR_FUNC("Abnormal length in STP_DATA phase 0x%x, 0x%x\n", + stp_core_ctx.parser.length, stp_core_ctx.rx_counter); + osal_assert(0); + } + + remain_length = + stp_core_ctx.parser.length - stp_core_ctx.rx_counter; + if (i >= remain_length) { + osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, remain_length); + i -= remain_length; + p_data += remain_length; + stp_core_ctx.rx_counter = stp_core_ctx.parser.length; + stp_change_rx_state(MTKSTP_SYNC); + *(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter) = '\0'; + /* STP_ERR_FUNC("%s [%d]\n", stp_core_ctx.rx_buf, stp_core_ctx.rx_counter); */ + + /*Trace32 Dump */ + stp_sdio_trace32_dump(); + + /*discard CRC */ + if (i > 2) { + STP_DBG_FUNC("crc discard.. i = %d\n", i); + i -= 2; + p_data += 2; + } else if (i == 2) { + STP_DBG_FUNC("crc discard.. i = %d\n", i); + i -= 2; + } + /*STP packet 4-bytes alignment */ + /*Discard padding bytes , otherwise make parser state machine disorder */ + if (i == 0) + STP_DBG_FUNC + ("\n[STP]FW_EVENT========= no padding byte =========\n"); + else if (i <= 4) { + STP_DBG_FUNC + ("\n[STP]FW_EVENT========= block padding %d bytes =========\n", i); + p_data += i; + i -= i; + } else { + padding_len = (0x04 - ((stp_core_ctx.parser.length + 6) & 0x03)) & 0x03; + p_data += padding_len; + i -= padding_len; + STP_DBG_FUNC + ("\n[STP]FW_EVENT========= STP Agg padding %d bytes =========\n", + padding_len); + } + continue; + } else { /* only copy by data length */ + + /*fixed klocwork insight issue */ + if (i + stp_core_ctx.rx_counter >= MTKSTP_BUFFER_SIZE) { + STP_ERR_FUNC + ("Fail to handle Packet, maybe it doesn't follow STP protocol.\n"); + stp_change_rx_state(MTKSTP_RESYNC1); + stp_core_ctx.rx_counter = 0; + return -1; + } + osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, i); + stp_core_ctx.rx_counter += i; /* all remain buffer are data */ + i = 0; + p_data += i; + continue; + } + break; + default: + break; + } + p_data++; + i--; + } + return 0; +} + +static INT32 stp_parser_data_in_full_mode(UINT32 length, UINT8 *p_data) +{ + INT32 remain_length; /* GeorgeKuo: sync from MAUI, change to unsigned */ + INT32 i = length; + static DEFINE_RATELIMIT_STATE(_rs, 2 * HZ, 1); + + while (i > 0) { + switch (stp_core_ctx.parser.state) { + + case MTKSTP_RESYNC1: /* RESYNC must be 4 _continuous_ 0x7f */ + if (*p_data == 0x7f) + stp_change_rx_state(MTKSTP_RESYNC2); + else + stp_change_rx_state(MTKSTP_RESYNC1); + break; + case MTKSTP_RESYNC2: + if (*p_data == 0x7f) + stp_change_rx_state(MTKSTP_RESYNC3); + else + stp_change_rx_state(MTKSTP_RESYNC1); + break; + case MTKSTP_RESYNC3: + if (*p_data == 0x7f) + stp_change_rx_state(MTKSTP_RESYNC4); + else + stp_change_rx_state(MTKSTP_RESYNC1); + break; + case MTKSTP_RESYNC4: + if (*p_data == 0x7f) { + stp_change_rx_state(MTKSTP_SYNC); + if (stp_core_ctx.sequence.rx_resync < 0xFF) + stp_core_ctx.sequence.rx_resync++; + stp_core_ctx.sequence.rx_resync_seq = 0xFF; + } else + stp_change_rx_state(MTKSTP_RESYNC1); + break; + case MTKSTP_SYNC: /* b'10 */ + STP_DUMP_PACKET_HEAD(p_data, "rx (uart):", length > 4 ? 4 : length); + if (((*p_data & 0x80) == 0x80) && ((*p_data & 0x40) == 0x00)) { + stp_change_rx_state(MTKSTP_NAK); + stp_core_ctx.parser.seq = (*p_data & 0x38) >> 3; + stp_core_ctx.parser.ack = *p_data & 0x07; + stp_core_ctx.rx_buf[0] = *p_data; + } else if ((*p_data == 0x7f) && (prev_state == MTKSTP_RESYNC4)) { + /* if this 0x7f is continuous to resync pattern */ + /* skip this continuous 0x7f, remain current & prev state */ + STP_ERR_FUNC("MTKSTP_SYNC: continuous resync pattern, buff = %x\n", *p_data); + } else if (*p_data == 0x7f) { /* a start of 0x7f, maybe this is resync pattern */ + stp_change_rx_state(MTKSTP_RESYNC2); + STP_ERR_FUNC("MTKSTP_SYNC: go to MTKSTP_RESYNC2, buff = %x\n", *p_data); + } else if (*p_data == 0x55) { /* STP delimiter */ + /* do nothing for delimiter */ + } else { /* unexpected, drop them */ + osal_assert(0); + if (__ratelimit(&_rs)) { + STP_WARN_FUNC("error header(0x%x) detected, discard %d bytes\n", + *p_data, i); + osal_buffer_dump(p_data, "full mode unexpected header", i, 0); + } + i = 0; + continue; + } + break; + + case MTKSTP_NAK: + if (fgEnableNak == 0) + stp_core_ctx.parser.nak = 0; /* disable NAK */ + else + stp_core_ctx.parser.nak = (*p_data & 0x80) >> 7; + stp_core_ctx.parser.type = (*p_data & 0x70) >> 4; + stp_core_ctx.parser.length = (*p_data & 0x0f) << 8; + stp_core_ctx.rx_buf[1] = *p_data; + if (stp_core_ctx.parser.nak) + STP_ERR_FUNC("MTKSTP_NAK TRUE: buff = %x\n", *p_data); + + if (stp_core_ctx.parser.type < MTKSTP_MAX_TASK_NUM) + stp_change_rx_state(MTKSTP_LENGTH); + else + stp_change_rx_state(MTKSTP_SYNC); + break; + + case MTKSTP_LENGTH: + stp_change_rx_state(MTKSTP_CHECKSUM); + stp_core_ctx.parser.length += *p_data; + /* Valid length checking */ + if (stp_core_ctx.parser.length > 2048) { + STP_ERR_FUNC("The length of STP packet is not valid !!! length = %d\n", + stp_core_ctx.parser.length); + stp_change_rx_state(MTKSTP_RESYNC1); + stp_core_ctx.rx_counter = 0; + STP_WARN_FUNC("error length(0x%x) detected, discard %d bytes\n", + stp_core_ctx.parser.length, i); + osal_buffer_dump(p_data, "full mode unexpected length", i, 0); + i = 0; + continue; + } + stp_core_ctx.rx_buf[2] = *p_data; + break; + + case MTKSTP_CHECKSUM: + if (((stp_core_ctx.rx_buf[0] + + stp_core_ctx.rx_buf[1] + stp_core_ctx.rx_buf[2]) & 0xff) == *p_data) { + if ((stp_core_ctx.parser.type == STP_TASK_INDX) || mtk_wcn_stp_is_info_task()) { + stp_change_rx_state(MTKSTP_FW_MSG); + stp_core_ctx.rx_counter = 0; + i -= 1; + if (i != 0) + p_data += 1; + continue; + } + /* header only packet */ + stp_process_header_only_packet(); + } else { + STP_ERR_FUNC("The checksum of header is error !!! %02x %02x %02x %02x\n", + stp_core_ctx.rx_buf[0], stp_core_ctx.rx_buf[1], + stp_core_ctx.rx_buf[2], *p_data); + stp_change_rx_state(MTKSTP_RESYNC1); + stp_core_ctx.rx_counter = 0; + /* since checksum error is usually related to interface + * buffer overflow, so we just let timeout mechanism to + * handle such error. + */ + /*stp_send_ack(1); NAK mechanism is removed */ + osal_buffer_dump(p_data, "full mode unexpected checksum", i, 0); + i = 0; + continue; + } + break; + + case MTKSTP_DATA: + /* block copy instead of byte copy */ + if (stp_core_ctx.parser.length < stp_core_ctx.rx_counter) { + STP_ERR_FUNC("Abnormal length in STP_DATA phase 0x%x, 0x%x\n", + stp_core_ctx.parser.length, stp_core_ctx.rx_counter); + osal_assert(0); + } + remain_length = stp_core_ctx.parser.length - stp_core_ctx.rx_counter; + if (i >= remain_length) { + osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, remain_length); + i -= remain_length; + p_data += remain_length; + stp_core_ctx.rx_counter = stp_core_ctx.parser.length; + stp_core_ctx.parser.state = MTKSTP_CRC1; + continue; + } else { /* only copy by data length */ + /*fixed klocwork insight issue */ + if (i + stp_core_ctx.rx_counter >= MTKSTP_BUFFER_SIZE) { + STP_ERR_FUNC + ("Fail to handle Packet, maybe it doesn't follow STP protocol.\n"); + stp_change_rx_state(MTKSTP_RESYNC1); + stp_core_ctx.rx_counter = 0; + STP_TRACE_FUNC("--\n"); + return -1; + } + + osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, i); + stp_core_ctx.rx_counter += i; /* all remain buffer are data */ + i = 0; + p_data += i; + continue; + } + break; + + case MTKSTP_CRC1: + stp_change_rx_state(MTKSTP_CRC2); + stp_core_ctx.parser.crc = *p_data; + break; + case MTKSTP_CRC2: + stp_change_rx_state(MTKSTP_SYNC); + stp_core_ctx.parser.crc += (*p_data) << 8; + if (stp_check_crc(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter, stp_core_ctx.parser.crc) + == MTK_WCN_BOOL_TRUE) { + if (stp_core_ctx.inband_rst_set == 0) + stp_process_packet(); + else + STP_WARN_FUNC("inband reset state,drop the packet\n"); + } else { + STP_ERR_FUNC("[%d]CRC error, drop the packet\n", gCrcErrorCount++); + osal_buffer_dump(&stp_core_ctx.rx_buf[0], "CRC data", stp_core_ctx.rx_counter, 0); + stp_change_rx_state(MTKSTP_SYNC); + stp_core_ctx.rx_counter = 0; + + /* since checksum error is usually related to interface + * buffer overflow, so we just let timeout mechanism to + * handle such error. + */ + STP_TRACE_FUNC("--\n"); + /* return and purge COMM port */ + return -1; + /*stp_send_ack(1); NAK mechanism is removed */ + } + break; + + case MTKSTP_FW_MSG: + if (((length > 11) && (osal_strncmp(p_data, "{reset}", 7) == 0)) || + (stp_core_ctx.parser.length == 7)) { + STP_INFO_FUNC("MCU need chip reset only! len=%d,pkt_len=%d!\n", + length, stp_core_ctx.parser.length); + chip_reset_only = 1; + } +#if CFG_WMT_DUMP_INT_STATUS + if (wmt_plat_dump_BGF_irq_status() == MTK_WCN_BOOL_TRUE) + wmt_plat_BGF_irq_dump_status(); +#endif + + if (mtk_wcn_stp_get_wmt_trg_assert() == 1) + stp_btm_stop_trigger_assert_timer(STP_BTM_CORE(stp_core_ctx)); + if (STP_IS_READY(stp_core_ctx)) + mtk_wcn_stp_dbg_dump_package(); + + STP_SET_READY(stp_core_ctx, 0); + /*stp inband reset */ + if (stp_core_ctx.parser.type == STP_TASK_INDX && + stp_core_ctx.parser.seq == 0 && + stp_core_ctx.parser.ack == 0 && + stp_core_ctx.parser.length == 0 && stp_core_ctx.inband_rst_set == 1) { + STP_INFO_FUNC("Inband reset event get! Resync STP with firmware!\n\r"); + stp_rest_ctx_state(); + stp_change_rx_state(MTKSTP_RESYNC1); + stp_core_ctx.inband_rst_set = 0; + STP_TRACE_FUNC("--\n"); + return 0; + } + + /*f/w assert and exception information */ + if (stp_core_ctx.parser.length < stp_core_ctx.rx_counter) { + STP_ERR_FUNC("Abnormal length in STP_DATA phase 0x%x, 0x%x\n", + stp_core_ctx.parser.length, stp_core_ctx.rx_counter); + osal_assert(0); + } + + mtk_wcn_stp_assert_flow_ctrl(1); + if (mtk_wcn_stp_coredump_start_get() == 0 && stp_core_ctx.rx_counter == 0 && + STP_IS_ENABLE_DBG(stp_core_ctx) && (stp_core_ctx.parser.type == STP_TASK_INDX)) { + mtk_wcn_stp_coredump_start_ctrl(1); + mtk_wcn_stp_ctx_save(); + STP_INFO_FUNC("++ start to read paged dump and paged trace ++\n"); + stp_btm_notify_wmt_dmp_wq(stp_core_ctx.btm); + STP_INFO_FUNC("++ start to read paged dump and paged trace --\n"); + /* Dump CRC error count for debug only */ + STP_INFO_FUNC("gCrcErrorCount = %d\n", gCrcErrorCount); + } + + remain_length = stp_core_ctx.parser.length - stp_core_ctx.rx_counter; + if (i >= remain_length) { + osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, + remain_length); + i -= remain_length; + p_data += remain_length; + stp_core_ctx.rx_counter = stp_core_ctx.parser.length; + stp_change_rx_state(MTKSTP_SYNC); + *(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter) = '\0'; + /*Trace32 Dump */ + stp_trace32_dump(); + /*discard CRC */ + if (i >= 2) { + STP_DBG_FUNC("crc discard.. i = %d\n", i); + i -= 2; + if (i > 0) + p_data += 2; + } + continue; + } else { /* only copy by data length */ + + /*fixed klocwork insight issue */ + if (i + stp_core_ctx.rx_counter >= MTKSTP_BUFFER_SIZE) { + STP_ERR_FUNC + ("Fail to handle Packet, it doesn't follow STP protocol.\n"); + stp_change_rx_state(MTKSTP_RESYNC1); + stp_core_ctx.rx_counter = 0; + return -1; + } + osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, i); + stp_core_ctx.rx_counter += i; /* all remain buffer are data */ + i = 0; + p_data += i; + continue; + } + + break; + default: + break; + } + p_data++; + i--; + } + + return 0; +} + + + + + + + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_parser_data +* DESCRIPTION +* push data to serial transport protocol parser engine +* PARAMETERS +* buffer [IN] data buffer +* length [IN] data buffer length +* RETURNS +* INT32 0 = success; -1 = crc/checksum error +*****************************************************************************/ +#if STP_EXP_HID_API_EXPORT +INT32 _mtk_wcn_stp_parser_data(PUINT8 buffer, UINT32 length) +#else +INT32 mtk_wcn_stp_parser_data(PUINT8 buffer, UINT32 length) +#endif +{ + /*----------------------------------------------------------------*/ + /* Local Variables */ + /*----------------------------------------------------------------*/ + INT32 i; + PUINT8 p_data; + INT32 ret = 0; +#ifdef DEBUG_DUMP_PACKET_HEAD + static UINT32 counter; + + STP_TRACE_FUNC("++, rx (cnt=%d,len=%d)\n", ++counter, length); +#endif + + i = length; + p_data = (PUINT8) buffer; + + /* STP is not enabled and only WMT can use Raw data path */ + if (STP_NOT_ENABLE(stp_core_ctx) && WMT_TASK_INDX == STP_PENDING_TYPE(stp_core_ctx)) { + stp_add_to_rx_queue(buffer, i, STP_PENDING_TYPE(stp_core_ctx)); + + /* mike: notify corresponding subfunction of incoming data */ + (*sys_event_set) (STP_PENDING_TYPE(stp_core_ctx)); + } + /* Mandatory or SDIO mode */ + else if ((mtk_wcn_stp_is_sdio_mode() || mtk_wcn_stp_is_uart_mand_mode() || + mtk_wcn_stp_is_btif_mand_mode()) && STP_IS_ENABLE(stp_core_ctx)) { + ret = stp_parser_data_in_mand_mode(i, p_data); + } + /* Full mode */ + else if ((mtk_wcn_stp_is_btif_fullset_mode() || mtk_wcn_stp_is_uart_fullset_mode()) + && STP_IS_ENABLE(stp_core_ctx)) { + ret = stp_parser_data_in_full_mode(i, p_data); + } + STP_TRACE_FUNC("--\n"); + return ret; +} +#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT +EXPORT_SYMBOL(mtk_wcn_stp_parser_data); +#endif + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_enable +* DESCRIPTION +* enable/disable STP +* PARAMETERS +* value [IN] 0=disable, others=enable +* RETURNS +* INT32 0=success, others=error +*****************************************************************************/ +INT32 mtk_wcn_stp_enable(INT32 value) +{ + STP_DBG_FUNC("%s: set the current enable = (%d)\n", __func__, value); + + stp_rest_ctx_state(); + STP_SET_ENABLE(stp_core_ctx, value); + if (!value) + mtk_wcn_stp_psm_reset(); + else { +/* g_block_tx = 0; */ + mtk_wcn_stp_coredump_start_ctrl(0); + mtk_wcn_stp_set_wmt_trg_assert(0); + } + return 0; +} + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_is_enable +* DESCRIPTION +* get STP enable/disable status +* PARAMETERS +* none. +* RETURNS +* INT32 0 = disable, 1 = enable +*****************************************************************************/ +INT32 mtk_wcn_stp_is_enable(VOID) +{ + return STP_IS_ENABLE(stp_core_ctx); +} + +INT32 mtk_wcn_stp_dbg_dump_package(VOID) +{ + if (STP_NOT_ENABLE(stp_core_ctx)) + STP_INFO_FUNC("STP dbg mode is off\n"); + else { + STP_INFO_FUNC("STP dbg mode is on\n"); + wmt_lib_print_wmtd_op_history(); + wmt_lib_print_worker_op_history(); + stp_psm_print_op_history(); + stp_btm_print_op_history(); + + if (mtk_wcn_stp_coredump_start_get() == 0 && + mtk_wcn_stp_get_wmt_trg_assert() == 0) { + if (mtk_wcn_stp_is_sdio_mode()) { + stp_dbg_dmp_print(g_mtkstp_dbg); + STP_INFO_FUNC("STP_SDIO TX data dump start\n"); + stp_sdio_txdbg_dump(); + } else { + mtk_wcn_consys_stp_btif_logger_ctrl(BTIF_DUMP_BTIF_REG); + mtk_wcn_consys_stp_btif_logger_ctrl(BTIF_DUMP_LOG); + stp_dbg_dmp_print(g_mtkstp_dbg); + } + } else + STP_INFO_FUNC("assert start flag is set, disable packet dump function\n"); + } + return 0; +} + + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_ready +* DESCRIPTION +* ready/un-ready STP +* PARAMETERS +* value [IN] 0=un-ready, others=ready +* RETURNS +* INT32 0=success, others=error +*****************************************************************************/ +INT32 mtk_wcn_stp_ready(INT32 value) +{ + STP_DBG_FUNC("set ready (%d)\n", value); + + STP_SET_READY(stp_core_ctx, value); + /*if whole chip reset, reset the debuggine mode */ +#ifndef CONFIG_LOG_STP_INTERNAL + /* mtk_wcn_stp_dbg_disable(); */ +#endif + + if (stp_is_apply_powersaving()) { + STP_INFO_FUNC("Restart the stp-psm monitor !!\n"); + stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); + } + + return 0; +} + + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_coredump_start_ctrl +* DESCRIPTION +* set f/w assert flag in STP context +* PARAMETERS +* value [IN] 0=assert end, others=assert begins +* RETURNS +* INT32 0=success, others=error +*****************************************************************************/ +INT32 mtk_wcn_stp_coredump_start_ctrl(UINT32 value) +{ + if (value != STP_FW_COREDUMP_FLAG(stp_core_ctx)) { + STP_INFO_FUNC("set f/w assert (%d)\n", value); + STP_SET_FW_COREDUMP_FLAG(stp_core_ctx, value); + } + return 0; +} + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_coredump_start_get +* DESCRIPTION +* get f/w assert flag in STP context +* PARAMETERS +* VOID +* RETURNS +* INT32 0= f/w assert flag is not set, others=f/w assert flag is set +*****************************************************************************/ +#if STP_EXP_HID_API_EXPORT +INT32 _mtk_wcn_stp_coredump_start_get(VOID) +#else +INT32 mtk_wcn_stp_coredump_start_get(VOID) +#endif +{ + return STP_FW_COREDUMP_FLAG(stp_core_ctx); +} +#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT +EXPORT_SYMBOL(mtk_wcn_stp_coredump_start_get); +#endif + +/* mtk_wcn_stp_set_wmt_last_close -- set the state of link(UART or SDIO) + * @ value - 1, link already be closed; 0, link is open + * + * Return 0 if success; else error code + */ +INT32 mtk_wcn_stp_set_wmt_last_close(UINT32 value) +{ + STP_INFO_FUNC("set wmt_last_close flag (%d)\n", value); + + /* test whether last_close can be removed safely */ + /* STP_SET_WMT_LAST_CLOSE(stp_core_ctx, value); */ + + return 0; +} + +INT32 mtk_wcn_stp_is_wmt_last_close(VOID) +{ + return STP_WMT_LAST_CLOSE(stp_core_ctx); +} + + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_send_data +* DESCRIPTION +* subfunction send data through STP +* PARAMETERS +* buffer [IN] data buffer +* length [IN] data buffer length +* type [IN] subfunction type +* RETURNS +* INT32 > 0: length transmitted; = 0: error +*****************************************************************************/ +#if STP_EXP_HID_API_EXPORT +INT32 _mtk_wcn_stp_send_data(const PUINT8 buffer, const UINT32 length, const UINT8 type) +#else +INT32 mtk_wcn_stp_send_data(const PUINT8 buffer, const UINT32 length, const UINT8 type) +#endif +{ + UINT8 mtkstp_header[MTKSTP_HEADER_SIZE], temp[2]; + PUINT8 p_tx_buf = NULL; + UINT16 crc; + INT32 ret = 0; + + /* osal_buffer_dump(buffer,"tx", length, 32); */ + osal_ftrace_print("%s|S|T%d|L%d\n", __func__, type, length); + + if (STP_WMT_LAST_CLOSE(stp_core_ctx) != 0) { + STP_ERR_FUNC("WMT lats close,should not have tx request!\n"); + return length; + } + /* if(g_block_tx) */ + if (mtk_wcn_stp_coredump_start_get() != 0) { + STP_WARN_RATELIMITED_FUNC("STP fw coredump start flag set...\n"); + return length; + } +#ifdef CONFIG_POWER_SAVING_SUPPORT + if (type != WMT_TASK_INDX) { +#if PSM_USE_COUNT_PACKAGE + stp_psm_disable_by_tx_rx_density(STP_PSM_CORE(stp_core_ctx), 0); +#else + stp_psm_disable_by_tx_rx_density(STP_PSM_CORE(stp_core_ctx), 0, length); +#endif + } + + if (type == WMT_TASK_INDX) + goto DONT_MONITOR; + if ((type == BT_TASK_INDX) && (wmt_plat_get_comm_if_type() == STP_SDIO_IF_TX)) { + if (stp_psm_is_to_block_traffic(STP_PSM_CORE(stp_core_ctx))) + stp_psm_notify_wmt_wakeup(STP_PSM_CORE(stp_core_ctx)); + goto DONT_MONITOR; + } + /*-----------------------------STP_PSM_Lock----------------------------------------*/ + ret = stp_psm_thread_lock_aquire(STP_PSM_CORE(stp_core_ctx)); + if (ret) { + STP_ERR_FUNC("--->lock psm_thread_lock failed ret=%d\n", ret); + return ret; + } + + if (!stp_psm_is_to_block_traffic(STP_PSM_CORE(stp_core_ctx))) { + if (stp_psm_has_pending_data(STP_PSM_CORE(stp_core_ctx))) { + STP_WARN_FUNC("***** Release psm hold data before send normal data *****\n"); + stp_psm_release_data(STP_PSM_CORE(stp_core_ctx)); + } + } else { + ret = stp_psm_hold_data(STP_PSM_CORE(stp_core_ctx), buffer, length, type); + stp_psm_notify_wmt_wakeup(STP_PSM_CORE(stp_core_ctx)); + /*-----------------------------STP_PSM_UnLock-----------------------------------*/ + stp_psm_thread_lock_release(STP_PSM_CORE(stp_core_ctx)); + return ret; + } +DONT_MONITOR: +#endif + + ret = stp_ctx_lock(&stp_core_ctx); + if (ret) { + STP_ERR_FUNC("stp context lock failed, ret=%d\n", ret); + ret = 0; + goto STP_LOCK_FAIL; + } + /*Only WMT can set raw data */ + if (STP_NOT_ENABLE(stp_core_ctx) && WMT_TASK_INDX != type) { + /* no-op */ + } else if (STP_NOT_ENABLE(stp_core_ctx) && WMT_TASK_INDX == type) { + /* ret = mtk_wcn_stp_send_data_raw(buffer, length, type); */ + } else if ((mtk_wcn_stp_is_sdio_mode() || mtk_wcn_stp_is_uart_mand_mode() || mtk_wcn_stp_is_btif_mand_mode()) + && STP_IS_ENABLE(stp_core_ctx)) { + + /*mtkstp_header[0] = 0x80;*/ + mtkstp_header[0] = 0x80 + (stp_core_ctx.sequence.txseq << 3); /* for debug purpose */ + mtkstp_header[1] = (type << 4) + (((length) >> 8) & 0x0f); + mtkstp_header[2] = (length) & 0xff; + mtkstp_header[3] = 0x00; + + /* HEADER */ + p_tx_buf = &stp_core_ctx.tx_buf[0]; + osal_memcpy(p_tx_buf, mtkstp_header, MTKSTP_HEADER_SIZE); + p_tx_buf += MTKSTP_HEADER_SIZE; + + /* PAYLOAD */ + osal_memcpy(p_tx_buf, buffer, length); + p_tx_buf += length; + + /* CRC */ + temp[0] = 0x00; + temp[1] = 0x00; + osal_memcpy(p_tx_buf, temp, 2); + stp_dbg_pkt_log(type, 0, 0, 0, PKT_DIR_TX, buffer, length); + (*sys_if_tx) (&stp_core_ctx.tx_buf[0], (MTKSTP_HEADER_SIZE + length + 2), &ret); + + if ((MTKSTP_HEADER_SIZE + length + 2) != ret) { + STP_ERR_FUNC("stp send tx packet: %d, maybe stp_if_tx == NULL\n", ret); + osal_assert(0); + ret = 0; + } else + ret = (INT32) length; + } + else if ((mtk_wcn_stp_is_uart_fullset_mode() || mtk_wcn_stp_is_btif_fullset_mode()) + && STP_IS_ENABLE(stp_core_ctx)) { + + if ((stp_core_ctx.sequence.winspace > 0) && + (stp_core_ctx.inband_rst_set == 0) && + (stp_is_tx_res_available(MTKSTP_HEADER_SIZE + length + MTKSTP_CRC_SIZE))) { + /*Make Header */ + mtkstp_header[0] = + 0x80 + (stp_core_ctx.sequence.txseq << 3) + stp_core_ctx.sequence.txack; + mtkstp_header[1] = (type << 4) + ((length & 0xf00) >> 8); + mtkstp_header[2] = length & 0xff; + mtkstp_header[3] = + (mtkstp_header[0] + mtkstp_header[1] + mtkstp_header[2]) & 0xff; + stp_core_ctx.tx_start_addr[stp_core_ctx.sequence.txseq] = + stp_core_ctx.tx_write; + stp_core_ctx.tx_length[stp_core_ctx.sequence.txseq] = + MTKSTP_HEADER_SIZE + length + 2; + if (fgEnableDelimiter == 1) { + stp_core_ctx.tx_length[stp_core_ctx.sequence.txseq] += STP_DEL_SIZE; + stp_add_to_tx_queue((const PUINT8)(&stp_delimiter[0]), + STP_DEL_SIZE); + } + stp_add_to_tx_queue(mtkstp_header, MTKSTP_HEADER_SIZE); + + /*Make Payload */ + stp_add_to_tx_queue(buffer, length); + + /*Make CRC */ + crc = osal_crc16(buffer, length); + temp[0] = crc & 0xff; + temp[1] = (crc & 0xff00) >> 8; + stp_add_to_tx_queue(temp, 2); + stp_dbg_pkt_log(type, + stp_core_ctx.sequence.txack, + stp_core_ctx.sequence.txseq, + crc, PKT_DIR_TX, buffer, length); + + /*Kick to BUS */ + stp_send_tx_queue(stp_core_ctx.sequence.txseq); + + INDEX_INC(stp_core_ctx.sequence.txseq); + stp_core_ctx.sequence.winspace--; + + /*Setup the Retry Timer */ + osal_timer_stop(&stp_core_ctx.tx_timer); + if (stp_core_ctx.sequence.winspace != MTKSTP_WINSIZE) + osal_timer_start(&stp_core_ctx.tx_timer, mtkstp_tx_timeout); + else + STP_ERR_FUNC("mtk_wcn_stp_send_data: wmt_stop_timer\n"); + ret = (INT32) length; + } else { + /* + * No winspace to send. Let caller retry + */ + if (stp_core_ctx.inband_rst_set == 1) + STP_WARN_RATELIMITED_FUNC + ("Now it's inband reset process and drop sent packet.\n"); + else + STP_WARN_RATELIMITED_FUNC("%s: There is no winspace/txqueue to send !!!\n", + __func__); + ret = 0; + } + } + stp_ctx_unlock(&stp_core_ctx); +STP_LOCK_FAIL: +#ifdef CONFIG_POWER_SAVING_SUPPORT + + if (stp_psm_is_quick_ps_support() == MTK_WCN_BOOL_TRUE) { + stp_psm_notify_wmt_sleep(STP_PSM_CORE(stp_core_ctx)); + } + /*-----------------------------STP_PSM_UnLock----------------------------------------*/ + if (type != WMT_TASK_INDX) { + if (!((type == BT_TASK_INDX) && (wmt_plat_get_comm_if_type() == STP_SDIO_IF_TX))) + stp_psm_thread_lock_release(STP_PSM_CORE(stp_core_ctx)); + } +#endif + + osal_ftrace_print("%s|E|T|%d|L|%d\n", __func__, type, length); + return ret; +} +#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT +EXPORT_SYMBOL(mtk_wcn_stp_send_data); +#endif + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_send_data_raw +* DESCRIPTION +* send raw data to common interface, bypass STP +* PARAMETERS +* buffer [IN] data buffer +* length [IN] data buffer length +* type [IN] subfunction type +* RETURNS +* INT32 >= 0: length transmitted; < 0: error +*****************************************************************************/ +#if STP_EXP_HID_API_EXPORT +INT32 _mtk_wcn_stp_send_data_raw(const PUINT8 buffer, const UINT32 length, const UINT8 type) +#else +INT32 mtk_wcn_stp_send_data_raw(const PUINT8 buffer, const UINT32 length, const UINT8 type) +#endif +{ + UINT32 written = 0; + INT32 ret = 0; + + if (STP_WMT_LAST_CLOSE(stp_core_ctx) != 0) { + STP_ERR_FUNC("WMT lats close, should not have tx request!"); + return length; + } + + if (length >= 6) + STP_DBG_FUNC("mtk_wcn_stp_send_data_raw, type = %d data = %x %x %x %x %x %x ", type, + buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]); + else if (length > 0) + STP_DBG_FUNC("mtk_wcn_stp_send_data_raw, type = %d data = %x", type, buffer[0]); + + /* remember tx type, forward following rx to this type */ + STP_SET_PENDING_TYPE(stp_core_ctx, type); + + stp_ctx_lock(&stp_core_ctx); + stp_dbg_pkt_log(type, 0, 0, 0, PKT_DIR_TX, buffer, length); + (*sys_if_tx) (&buffer[0], length, &written); + stp_ctx_unlock(&stp_core_ctx); + + if (written == 0) + stp_dump_data(&buffer[0], "tx raw failed:", length); + + if (written == length) + ret = (INT32) written; + else + ret = (-1); + + return ret; +} +#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT +EXPORT_SYMBOL(mtk_wcn_stp_send_data_raw); +#endif + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_receive_data +* DESCRIPTION +* receive data from serial protocol engine +* PARAMETERS +* buffer [IN] data buffer +* length [IN] data buffer length +* type [IN] subfunction type +* RETURNS +* INT32 >= 0: size of data received; < 0: error +*****************************************************************************/ +#if STP_EXP_HID_API_EXPORT +INT32 _mtk_wcn_stp_receive_data(PUINT8 buffer, UINT32 length, UINT8 type) +#else +INT32 mtk_wcn_stp_receive_data(PUINT8 buffer, UINT32 length, UINT8 type) +#endif +{ + /* GeorgeKuo modify: reduce "if" branch */ + UINT16 copyLen = 0; + UINT16 tailLen = 0; + + osal_ftrace_print("%s|S|T|%d|L|%d\n", __func__, type, length); + osal_lock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); + while (stp_core_ctx.ring[type].read_p != stp_core_ctx.ring[type].write_p) { + /* GeorgeKuo modify: reduce if branch */ + if (stp_core_ctx.ring[type].write_p > stp_core_ctx.ring[type].read_p) { + copyLen = stp_core_ctx.ring[type].write_p - stp_core_ctx.ring[type].read_p; + if (copyLen > length) + copyLen = length; + osal_memcpy(buffer, + stp_core_ctx.ring[type].buffer + stp_core_ctx.ring[type].read_p, + copyLen); + stp_core_ctx.ring[type].read_p += copyLen; + break; + } + tailLen = MTKSTP_BUFFER_SIZE - stp_core_ctx.ring[type].read_p; + if (tailLen > length) { /* exclude equal case to skip wrap check */ + copyLen = length; + osal_memcpy(buffer, stp_core_ctx.ring[type].buffer + + stp_core_ctx.ring[type].read_p, copyLen); + stp_core_ctx.ring[type].read_p += copyLen; + } else { + /* part 1: copy tailLen */ + osal_memcpy(buffer, stp_core_ctx.ring[type].buffer + + stp_core_ctx.ring[type].read_p, tailLen); + buffer += tailLen; /* update buffer offset */ + /* part 2: check if head length is enough */ + copyLen = length - tailLen; + copyLen = (stp_core_ctx.ring[type].write_p < + copyLen) ? stp_core_ctx.ring[type].write_p : copyLen; + if (copyLen) + osal_memcpy(buffer, stp_core_ctx.ring[type].buffer + 0, copyLen); + /* Update read_p final position */ + stp_core_ctx.ring[type].read_p = copyLen; + /* update return length: head + tail */ + copyLen += tailLen; + } + break; + } + + osal_unlock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); + + if ((stp_psm_is_quick_ps_support() == MTK_WCN_BOOL_TRUE) && (type != WMT_TASK_INDX)) { +#if PSM_USE_COUNT_PACKAGE + stp_psm_disable_by_tx_rx_density(STP_PSM_CORE(stp_core_ctx), 1); +#else + stp_psm_disable_by_tx_rx_density(STP_PSM_CORE(stp_core_ctx), 1, copyLen); +#endif + } + + osal_ftrace_print("%s|E|T|%d|L|%d\n", __func__, type, copyLen); + return copyLen; +} +#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT +EXPORT_SYMBOL(mtk_wcn_stp_receive_data); +#endif + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_is_rxqueue_empty +* DESCRIPTION +* Is certain rx queue empty? +* PARAMETERS +* type [IN] subfunction type +* RETURNS +* INT32 0: queue is NOT empyt; !0: queue is empty +*****************************************************************************/ +#if STP_EXP_HID_API_EXPORT +INT32 _mtk_wcn_stp_is_rxqueue_empty(UINT8 type) +#else +INT32 mtk_wcn_stp_is_rxqueue_empty(UINT8 type) +#endif +{ + INT32 ret; + + osal_lock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); + + if (stp_core_ctx.ring[type].read_p == stp_core_ctx.ring[type].write_p) + ret = 1; /* queue is empty */ + else + ret = 0; /* queue is not empty */ + + osal_unlock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); + + return ret; +} +#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT +EXPORT_SYMBOL(mtk_wcn_stp_is_rxqueue_empty); +#endif + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_set_sdio_mode +* DESCRIPTION +* Set stp for SDIO mode +* PARAMETERS +* sdio_flag [IN] sdio mode flag (TRUE:SDIO mode, FALSE:UART mode) +* RETURNS +* void +*****************************************************************************/ + +void mtk_wcn_stp_set_mode(UINT32 mode) +{ + STP_SET_SUPPORT_PROTOCOL(stp_core_ctx, mode); + STP_DBG_FUNC("STP_SUPPORT_PROTOCOL = %08x\n", STP_SUPPORT_PROTOCOL(stp_core_ctx)); +} + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_is_uart_fullset_mode +* DESCRIPTION +* Is stp use UART fullset mode? +* PARAMETERS +* none. +* RETURNS +* MTK_WCN_BOOL TRUE:Uart Fullset mode, FALSE:Not UART Fullset mode +*****************************************************************************/ +MTK_WCN_BOOL mtk_wcn_stp_is_uart_fullset_mode(VOID) +{ + /* + * bit 0: uart fullset mode + * bit 1: uart mandatory mode + * bit 2: sdio mode + */ + if (STP_SUPPORT_PROTOCOL(stp_core_ctx) & MTKSTP_UART_FULL_MODE) + return MTK_WCN_BOOL_TRUE; + else + return MTK_WCN_BOOL_FALSE; +} + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_is_uart_mand_mode +* DESCRIPTION +* Is stp use UART mandatory mode? +* PARAMETERS +* none. +* RETURNS +* MTK_WCN_BOOL TRUE:Uart Mandatory mode, FALSE:Not UART Mandotary mode +*****************************************************************************/ +MTK_WCN_BOOL mtk_wcn_stp_is_uart_mand_mode(VOID) +{ + /* + * bit 0: uart fullset mode + * bit 1: uart mandatory mode + * bit 2: sdio mode + */ + if (STP_SUPPORT_PROTOCOL(stp_core_ctx) & MTKSTP_UART_MAND_MODE) + return MTK_WCN_BOOL_TRUE; + else + return MTK_WCN_BOOL_FALSE; +} + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_is_sdio_mode +* DESCRIPTION +* Is stp use SDIO mode? +* PARAMETERS +* none. +* RETURNS +* MTK_WCN_BOOL TRUE:SDIO mode, FALSE:UART mode +*****************************************************************************/ +MTK_WCN_BOOL mtk_wcn_stp_is_sdio_mode(VOID) +{ + /* + * bit 0: uart fullset mode + * bit 1: uart mandatory mode + * bit 2: sdio mode + */ + if (STP_SUPPORT_PROTOCOL(stp_core_ctx) & MTKSTP_SDIO_MODE) + return MTK_WCN_BOOL_TRUE; + else + return MTK_WCN_BOOL_FALSE; +} + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_is_btif_fullset_mode +* DESCRIPTION +* Is stp use BTIF fullset mode? +* PARAMETERS +* none. +* RETURNS +* MTK_WCN_BOOL TRUE:BTIF Fullset mode, FALSE:Not BTIF Fullset mode +*****************************************************************************/ +MTK_WCN_BOOL mtk_wcn_stp_is_btif_fullset_mode(VOID) +{ + + if (STP_SUPPORT_PROTOCOL(stp_core_ctx) & MTKSTP_BTIF_FULL_MODE) + return MTK_WCN_BOOL_TRUE; + else + return MTK_WCN_BOOL_FALSE; +} + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_is_btif_mand_mode +* DESCRIPTION +* Is stp use BTIF mandatory mode? +* PARAMETERS +* none. +* RETURNS +* MTK_WCN_BOOL TRUE:BTIF Mandatory mode, FALSE:Not BTIF Mandotary mode +*****************************************************************************/ + +MTK_WCN_BOOL mtk_wcn_stp_is_btif_mand_mode(void) +{ + + if (STP_SUPPORT_PROTOCOL(stp_core_ctx) & MTKSTP_BTIF_MAND_MODE) + return MTK_WCN_BOOL_TRUE; + else + return MTK_WCN_BOOL_FALSE; +} + +/***************************************************************************** +* FUNCTION +* stp_send_inband_reset +* DESCRIPTION +* To sync to oringnal stp state with f/w stp +* PARAMETERS +* none. +* RETURNS +* none +*****************************************************************************/ +VOID mtk_wcn_stp_inband_reset(VOID) +{ + UINT8 inband_reset_packet[64]; + UINT32 txseq = 0; + UINT32 txack = 0; + UINT32 crc = 0; + UINT32 ret = 0; + UINT32 reset_payload_len = 0; + + /*512 bytes */ + UINT8 reset_payload[] = { + 0xc0, 0x01, 0xc0, 0xde, 0x3e, 0xd1, 0xa7, 0xef + }; + + stp_ctx_lock(&stp_core_ctx); + + /*RESYNC*/ inband_reset_packet[0] = 0x7f; + inband_reset_packet[1] = 0x7f; + inband_reset_packet[2] = 0x7f; + inband_reset_packet[3] = 0x7f; + inband_reset_packet[4] = 0x7f; + inband_reset_packet[5] = 0x7f; + inband_reset_packet[6] = 0x7f; + inband_reset_packet[7] = 0x7f; + + /*header */ + reset_payload_len = ARRAY_SIZE(reset_payload); + inband_reset_packet[8] = 0x80 + (txseq << 3) + txack; + inband_reset_packet[9] = (STP_TASK_INDX << 4) + ((reset_payload_len & 0xf00) >> 8); + inband_reset_packet[10] = reset_payload_len & 0xff; + inband_reset_packet[11] = + (inband_reset_packet[8] + inband_reset_packet[9] + inband_reset_packet[10]) & 0xff; + + /*payload */ + osal_memcpy(&inband_reset_packet[12], reset_payload, reset_payload_len); + + /*crc */ + crc = osal_crc16(&reset_payload[0], reset_payload_len); + inband_reset_packet[12 + reset_payload_len] = crc & 0xff; + inband_reset_packet[12 + reset_payload_len + 1] = (crc & 0xff00) >> 8; + + (*sys_if_tx)(&inband_reset_packet[0], 14 + reset_payload_len, &ret); + + if (ret != (14 + reset_payload_len)) + STP_ERR_FUNC("Inband sending error, sending %d , but ret = %d\n", + 10 + reset_payload_len, ret); + + stp_core_ctx.inband_rst_set = 1; + stp_ctx_unlock(&stp_core_ctx); +} + +void mtk_wcn_stp_debug_ctrl(INT32 op, INT32 filter, INT32 filter_param) +{ +} + +void mtk_wcn_stp_test_cmd(INT32 cmd_no) +{ + UINT8 test_packet[64]; + UINT32 txseq = 0; + UINT32 txack = 0; + UINT32 crc = 0; + UINT32 ret = 0; + UINT32 reset_payload_len = 0; + + UINT8 test_payload[] = { + 0xAA, 0xAA, 0xC0, 0xDE, 0x3E, 0xD1, 0xA7, 0xEF + }; +/* */ +/* select your test command by cmd_no */ +/* */ + if (cmd_no == 0) { + /* to test new command to chip */ + stp_ctx_lock(&stp_core_ctx); + + /*RESYNC*/ test_packet[0] = 0x7f; + test_packet[1] = 0x7f; + test_packet[2] = 0x7f; + test_packet[3] = 0x7f; + test_packet[4] = 0x7f; + test_packet[5] = 0x7f; + test_packet[6] = 0x7f; + test_packet[7] = 0x7f; + + /*header */ + reset_payload_len = ARRAY_SIZE(test_payload); + test_packet[8] = 0x80 + (txseq << 3) + txack; + test_packet[9] = (STP_TASK_INDX << 4) + ((reset_payload_len & 0xf00) >> 8); + test_packet[10] = reset_payload_len & 0xff; + test_packet[11] = (test_packet[8] + test_packet[9] + test_packet[10]) & 0xff; + + /*payload */ + osal_memcpy(&test_packet[12], test_payload, reset_payload_len); + + /*crc */ + crc = osal_crc16(&test_payload[0], reset_payload_len); + test_packet[12 + reset_payload_len] = crc & 0xff; + test_packet[12 + reset_payload_len + 1] = (crc & 0xff00) >> 8; + + (*sys_if_tx)(&test_packet[0], 14 + reset_payload_len, &ret); + if (ret != (14 + reset_payload_len)) + STP_ERR_FUNC("stp test sending error, sending %d , but ret = %d\n", + 10 + reset_payload_len, ret); + + stp_ctx_unlock(&stp_core_ctx); + } + +} + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_flush_context +* DESCRIPTION +* Flush STP Context +* PARAMETERS +* none. +* RETURNS +* none +*****************************************************************************/ +VOID mtk_wcn_stp_flush_context(VOID) +{ + stp_rest_ctx_state(); +} + + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_flush_rx_queue +* DESCRIPTION +* Flush STP Rx Queue +* PARAMETERS +* none. +* RETURNS +* none +*****************************************************************************/ + +VOID mtk_wcn_stp_flush_rx_queue(UINT32 type) +{ + INT32 ret = 0; + + if (type < MTKSTP_MAX_TASK_NUM) { + ret = osal_lock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); + if (ret != 0) { + STP_WARN_FUNC("stp context lock failed, ret=%d\n", ret); + return; + } + stp_core_ctx.ring[type].read_p = 0; + stp_core_ctx.ring[type].write_p = 0; + osal_unlock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); + } +} + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_is_enable +* DESCRIPTION +* STP is ready? +* PARAMETERS +* none. +* RETURNS +* none +*****************************************************************************/ +#if STP_EXP_HID_API_EXPORT +MTK_WCN_BOOL _mtk_wcn_stp_is_ready(VOID) +#else +MTK_WCN_BOOL mtk_wcn_stp_is_ready(VOID) +#endif +{ + return STP_IS_READY(stp_core_ctx); +} +#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT +EXPORT_SYMBOL(mtk_wcn_stp_is_ready); +#endif + +/***************************************************************************** +* FUNCTION +* set_bluetooth_rx_interface +* DESCRIPTION +* Set bluetooth rx interface +* PARAMETERS +* rx interface type +* RETURNS +* void +*****************************************************************************/ +#if STP_EXP_HID_API_EXPORT +VOID _mtk_wcn_stp_set_bluez(MTK_WCN_BOOL bluez_flag) +#else +VOID mtk_wcn_stp_set_bluez(MTK_WCN_BOOL bluez_flag) +#endif +{ + /* g_mtkstp_bluez_flag = bluez_flag; */ + STP_SET_BT_STK(stp_core_ctx, bluez_flag); +} +#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT +EXPORT_SYMBOL(mtk_wcn_stp_set_bluez); +#endif + +/***************************************************************************** +* FUNCTION +* set stp debugging mdoe +* DESCRIPTION +* set stp debugging mdoe +* PARAMETERS +* dbg_mode: switch to dbg mode ? +* RETURNS +* void +*****************************************************************************/ +VOID mtk_wcn_stp_set_dbg_mode(MTK_WCN_BOOL dbg_mode) +{ + STP_SET_ENABLE_DBG(stp_core_ctx, dbg_mode); +} + +/***************************************************************************** +* FUNCTION +* set stp auto reset mdoe +* DESCRIPTION +* set stp auto reset mdoe +* PARAMETERS +* auto_rst: switch to auto reset mode ? +* RETURNS +* void +*****************************************************************************/ +VOID mtk_wcn_stp_set_auto_rst(MTK_WCN_BOOL auto_rst) +{ + STP_SET_ENABLE_RST(stp_core_ctx, auto_rst); +} + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_open_btif +* DESCRIPTION +* init btif hw & sw by owner stp +* PARAMETERS +* VOID +* RETURNS +* INT32 0-success,other fail. +*****************************************************************************/ +INT32 mtk_wcn_stp_open_btif(VOID) +{ + return mtk_wcn_consys_stp_btif_open(); +} + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_open_close +* DESCRIPTION +* close btif hw & sw by owner stp +* PARAMETERS +* VOID +* RETURNS +* INT32 0-success,other fail. +*****************************************************************************/ +INT32 mtk_wcn_stp_close_btif(VOID) +{ + return mtk_wcn_consys_stp_btif_close(); +} + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_rx_cb_register +* DESCRIPTION +* register stp rx cb to btif +* PARAMETERS +* MTK_WCN_BTIF_RX_CB stp rx handle function +* RETURNS +* INT32 0-success,other fail. +*****************************************************************************/ +INT32 mtk_wcn_stp_rxcb_register(MTK_WCN_BTIF_RX_CB rx_cb) +{ + return mtk_wcn_consys_stp_btif_rx_cb_register(rx_cb); +} + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_tx +* DESCRIPTION +* send stp package by btif +* PARAMETERS +* pBuf:package buffer pointer,len:package length +* written_len:package written length +* RETURNS +* INT32 package length-success,other fail. +*****************************************************************************/ +INT32 mtk_wcn_stp_tx(UINT8 *pBuf, UINT32 len, UINT32 *written_len) +{ + INT32 iRet = -1; + + iRet = mtk_wcn_consys_stp_btif_tx(pBuf, len, written_len); + return iRet; +} + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_wakeup_consys +* DESCRIPTION +* STP wakeup consys by btif +* PARAMETERS +* VOID +* RETURNS +* INT32 0-success,other fail. +*****************************************************************************/ +INT32 mtk_wcn_stp_wakeup_consys(VOID) +{ + /*log wakeup int for debug */ + stp_dbg_pkt_log(7, 0, 0, 0, PKT_DIR_TX, NULL, 0); + return mtk_wcn_consys_stp_btif_wakeup(); +} + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_dpidle_ctrl +* DESCRIPTION +* decide AP enter or exit deep idle +* PARAMETERS +* en_flag:1,enter,0,exit +* RETURNS +* always 0 +*****************************************************************************/ +INT32 mtk_wcn_stp_dpidle_ctrl(UINT32 en_flag) +{ + mtk_wcn_consys_stp_btif_dpidle_ctrl(en_flag); + + return 0; +} + +INT32 mtk_wcn_stp_notify_sleep_for_thermal(VOID) +{ + return stp_psm_sleep_for_thermal(STP_PSM_CORE(stp_core_ctx)); +} + +VOID mtk_wcn_stp_set_wmt_trg_assert(UINT32 value) +{ + STP_DBG_FUNC("set evt err tigger assert flag to %d\n", value); + STP_SET_ASSERT(stp_core_ctx, value); +} + +UINT32 mtk_wcn_stp_get_wmt_trg_assert(VOID) +{ + return STP_ASSERT(stp_core_ctx); +} + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_lpbk_ctrl +* DESCRIPTION +* enable stp internal lpbk test or not +* PARAMETERS +* mode:1,enable,0,disabel +* RETURNS +* INT32 0-success,other fail. +*****************************************************************************/ +INT32 mtk_wcn_stp_lpbk_ctrl(enum _ENUM_BTIF_LPBK_MODE_ mode) +{ + return mtk_wcn_consys_stp_btif_lpbk_ctrl(mode); +} + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_logger_ctrl +* DESCRIPTION +* dump btif buffer or register status when No ACK or assert occurs +* PARAMETERS +* flag:see enum value in enum _ENUM_BTIF_DBG_ID_ +* RETURNS +* INT32 0-success,other fail. +*****************************************************************************/ +INT32 mtk_wcn_stp_logger_ctrl(enum _ENUM_BTIF_DBG_ID_ flag) +{ + return mtk_wcn_consys_stp_btif_logger_ctrl(flag); +} + +VOID mtk_wcn_stp_ctx_save(void) +{ + STP_DBG_FUNC("start ++\n"); + stp_psm_set_sleep_disable(stp_core_ctx.psm); + STP_DBG_FUNC("exit --\n"); +} + +VOID mtk_wcn_stp_ctx_restore(void) +{ + stp_core_ctx.assert_info_cnt = 0; + + stp_psm_set_sleep_enable(stp_core_ctx.psm); + stp_btm_reset_btm_wq(STP_BTM_CORE(stp_core_ctx)); + + if (STP_IS_ENABLE_RST(stp_core_ctx)) + stp_btm_notify_wmt_rst_wq(STP_BTM_CORE(stp_core_ctx)); + else + STP_INFO_FUNC("No to launch whole chip reset! for debugging purpose\n"); +} + +INT32 mtk_wcn_stp_wmt_trg_assert(VOID) +{ + INT32 ret = -1; + + if (mtk_wcn_stp_coredump_start_get() != 0) { + STP_INFO_FUNC("firmware assert has been triggered\n"); + return 1; + } + ret = stp_notify_btm_do_fw_assert(STP_BTM_CORE(stp_core_ctx)); + + if (ret) { + STP_ERR_FUNC("trigger assert fail,do chip reset to recovery\n"); + if (STP_IS_ENABLE_RST(stp_core_ctx)) + stp_btm_notify_wmt_rst_wq(STP_BTM_CORE(stp_core_ctx)); + else + STP_INFO_FUNC("No to launch whole chip reset! for debugging purpose\n"); + } + + return ret; +} + +INT32 mtk_wcn_stp_assert_timeout_handle(VOID) +{ + INT32 ret = 0; + P_CONSYS_EMI_ADDR_INFO p_ecsi; + + if (wmt_detect_get_chip_type() == WMT_CHIP_TYPE_COMBO) { + mtk_wcn_stp_ctx_restore(); + return ret; + } + + p_ecsi = wmt_plat_get_emi_phy_add(); + /* dump btif data */ + mtk_wcn_consys_stp_btif_logger_ctrl(BTIF_DUMP_BTIF_REG); + mtk_wcn_consys_stp_btif_logger_ctrl(BTIF_DUMP_LOG); + mtk_wcn_stp_coredump_start_ctrl(1); + if (p_ecsi != NULL && wmt_plat_get_dump_info(p_ecsi->p_ecso->emi_apmem_ctrl_assert_flag)) { + STP_INFO_FUNC("EMI assert flag was set. To do coredump.\n"); + mtk_wcn_stp_ctx_save(); + ret = stp_btm_notify_wmt_dmp_wq(STP_BTM_CORE(stp_core_ctx)); + } else { + /*host trigger assert timeout and no coredump packet. To dump EMI data*/ + STP_INFO_FUNC("host trigger fw assert timeout!\n"); + WMT_STEP_COMMAND_TIMEOUT_DO_ACTIONS_FUNC("Trigger assert timeout"); + if (mtk_wcn_stp_coredump_flag_get() != 0) + ret = stp_dbg_start_emi_dump(); + else + mtk_wcn_stp_ctx_restore(); + } + return ret; +} + +INT32 mtk_wcn_stp_coredump_timeout_handle(VOID) +{ + /* dump btif data */ + mtk_wcn_consys_stp_btif_logger_ctrl(BTIF_DUMP_BTIF_REG); + mtk_wcn_consys_stp_btif_logger_ctrl(BTIF_DUMP_LOG); + + WMT_STEP_COMMAND_TIMEOUT_DO_ACTIONS_FUNC("Coredump timeout"); + if (wmt_detect_get_chip_type() == WMT_CHIP_TYPE_COMBO) + mtk_wcn_stp_ctx_restore(); + return 0; +} + +VOID mtk_wcn_stp_dbg_pkt_log(INT32 type, INT32 dir) +{ + stp_dbg_pkt_log(type, 0, 0, 0, dir, NULL, 0); +} + +VOID mtk_stp_sdio_retry_flag_ctrl(INT32 flag) +{ + if (flag) { + if (flag != wmt_dbg_sdio_retry_ctrl) + flag = wmt_dbg_sdio_retry_ctrl; + } + stp_sdio_retry_flag_ctrl(flag == 0 ? 0 : 1); +} + +VOID mtk_stp_dbg_sdio_retry_flag_ctrl(INT32 flag) +{ + wmt_dbg_sdio_retry_ctrl = flag == 0 ? 0 : 1; +} + +INT32 mtk_stp_sdio_retry_flag_get(VOID) +{ + return stp_sdio_retry_flag_get(); +} + +VOID mtk_stp_dump_sdio_register(VOID) +{ + stp_sdio_dump_register(); +} + +INT32 mtk_stp_dbg_dmp_append(PUINT8 buf, INT32 max_len) +{ + return stp_dbg_dmp_append(g_mtkstp_dbg, buf, max_len); +} + +VOID mtk_stp_notify_emi_dump_end(VOID) +{ + stp_btm_notify_emi_dump_end(STP_BTM_CORE(stp_core_ctx)); +} + +INT32 mtk_stp_check_rx_has_pending_data(VOID) +{ + return sys_rx_has_pending_data(); +} + +P_OSAL_THREAD mtk_stp_rx_thread_get(VOID) +{ + return sys_rx_thread_get(); +} + +VOID mtk_wcn_stp_assert_flow_ctrl(UINT32 on) +{ + STP_DBG_FUNC("Set assert progress flag to %d\n", on); + STP_SET_ASSERT_IN_PROGRESS(stp_core_ctx, on); +} + +UINT32 mtk_wcn_stp_assert_flow_get(VOID) +{ + return STP_ASSERT_IN_PROGRESS(stp_core_ctx); +} + +VOID mtk_wcn_stp_set_support_gpsl5(MTK_WCN_BOOL support_gpsl5) +{ + STP_SET_SUPPORT_GPSL5(stp_core_ctx, support_gpsl5); +} + +INT32 mtk_wcn_stp_is_support_gpsl5(VOID) +{ + return STP_IS_SUPPORT_GPSL5(stp_core_ctx); +} diff --git a/drivers/misc/mediatek/connectivity/common/common_main/core/stp_exp.c b/drivers/misc/mediatek/connectivity/common/common_main/core/stp_exp.c new file mode 100644 index 0000000000000000000000000000000000000000..f695778f328f12919b7b1ad7864a2405f32fce49 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/core/stp_exp.c @@ -0,0 +1,374 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#if 0 /* to do---- need check why need this header file */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include /* udelay() */ + +#include +#include +#endif +#include "osal_typedef.h" +#include "stp_core.h" +#include "stp_exp.h" +#include "hif_sdio.h" +#include "stp_sdio.h" +#include "stp_dbg.h" + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ +static MTK_WCN_STP_IF_TX stp_uart_if_tx; +static MTK_WCN_STP_IF_TX stp_sdio_if_tx; +static MTK_WCN_STP_IF_TX stp_btif_if_tx; +static MTK_WCN_STP_RX_HAS_PENDING_DATA stp_btif_rx_has_pending_data; +static MTK_WCN_STP_TX_HAS_PENDING_DATA stp_btif_tx_has_pending_data; +static MTK_WCN_STP_RX_THREAD_GET stp_btif_rx_thread_get; +static ENUM_STP_TX_IF_TYPE g_stp_if_type = STP_MAX_IF_TX; +static MTK_WCN_STP_IF_RX stp_if_rx; +static MTK_WCN_STP_EVENT_CB event_callback_tbl[MTKSTP_MAX_TASK_NUM] = { 0x0 }; +static MTK_WCN_STP_EVENT_CB tx_event_callback_tbl[MTKSTP_MAX_TASK_NUM] = { 0x0 }; + +/****************************************************************************** +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************* +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +INT32 mtk_wcn_sys_if_rx(PUINT8 data, INT32 size) +{ + if (stp_if_rx == 0x0) + return -1; + (*stp_if_rx)(data, size); + return 0; +} + +static INT32 mtk_wcn_sys_if_tx(const PUINT8 data, const UINT32 size, PUINT32 written_size) +{ + if (g_stp_if_type == STP_UART_IF_TX) + return stp_uart_if_tx != NULL ? (*stp_uart_if_tx)(data, size, written_size) : -1; + else if (g_stp_if_type == STP_SDIO_IF_TX) + return stp_sdio_if_tx != NULL ? (*stp_sdio_if_tx)(data, size, written_size) : -1; + else if (g_stp_if_type == STP_BTIF_IF_TX) + return stp_btif_if_tx != NULL ? (*stp_btif_if_tx) (data, size, written_size) : -1; + /*if (g_stp_if_type >= STP_MAX_IF_TX) *//* George: remove ALWAYS TRUE condition */ + return -1; +} + +static INT32 mtk_wcn_sys_rx_has_pending_data(VOID) +{ + if (g_stp_if_type == STP_BTIF_IF_TX) + return stp_btif_rx_has_pending_data != NULL ? (*stp_btif_rx_has_pending_data) () : -1; + return -1; +} + +static INT32 mtk_wcn_sys_tx_has_pending_data(VOID) +{ + if (g_stp_if_type == STP_BTIF_IF_TX) + return stp_btif_tx_has_pending_data != NULL ? (*stp_btif_tx_has_pending_data) () : -1; + return -1; +} + +static P_OSAL_THREAD mtk_wcn_sys_rx_thread_get(VOID) +{ + if (g_stp_if_type == STP_BTIF_IF_TX) + return stp_btif_rx_thread_get != NULL ? (*stp_btif_rx_thread_get) () : NULL; + return NULL; +} + +static INT32 mtk_wcn_sys_event_set(UINT8 function_type) +{ + if ((function_type < MTKSTP_MAX_TASK_NUM) && (event_callback_tbl[function_type] != 0x0)) + (*event_callback_tbl[function_type])(); + else { + /* FIXME: error handling */ + osal_dbg_print("[%s] STP set event fail. It seems the function is not active.\n", + __func__); + } + + return 0; +} + +static INT32 mtk_wcn_sys_event_tx_resume(UINT8 winspace) +{ + int type = 0; + + for (type = 0; type < MTKSTP_MAX_TASK_NUM; type++) { + if (tx_event_callback_tbl[type]) + tx_event_callback_tbl[type](); + } + + return 0; +} + +static INT32 mtk_wcn_sys_check_function_status(UINT8 type, UINT8 op) +{ + + /*op == FUNCTION_ACTIVE, to check if funciton[type] is active ? */ + if (type >= MTKSTP_MAX_TASK_NUM) + return STATUS_FUNCTION_INVALID; + + if (op == OP_FUNCTION_ACTIVE) { + if (event_callback_tbl[type] != 0x0) + return STATUS_FUNCTION_ACTIVE; + return STATUS_FUNCTION_INACTIVE; + } + /*you can define more operation here ..., to queury function's status/information */ + + return STATUS_OP_INVALID; +} + +#if STP_EXP_HID_API_EXPORT +INT32 _mtk_wcn_stp_register_if_rx(MTK_WCN_STP_IF_RX func) +#else +INT32 mtk_wcn_stp_register_if_rx(MTK_WCN_STP_IF_RX func) +#endif +{ + stp_if_rx = func; + + return 0; +} +#if !STP_EXP_HID_API_EXPORT +EXPORT_SYMBOL(mtk_wcn_stp_register_if_rx); +#endif + +VOID mtk_wcn_stp_set_if_tx_type(ENUM_STP_TX_IF_TYPE stp_if_type) +{ + g_stp_if_type = stp_if_type; + osal_dbg_print("[%s] set STP_IF_TX to %s.\n", + __func__, + (STP_UART_IF_TX == + stp_if_type) ? "UART" : ((STP_SDIO_IF_TX == + stp_if_type) ? "SDIO" : "NULL")); +} + +#if STP_EXP_HID_API_EXPORT +INT32 _mtk_wcn_stp_register_if_tx(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func) +#else +INT32 mtk_wcn_stp_register_if_tx(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func) +#endif +{ + if (stp_if == STP_UART_IF_TX) + stp_uart_if_tx = func; + else if (stp_if == STP_SDIO_IF_TX) + stp_sdio_if_tx = func; + else if (stp_if == STP_BTIF_IF_TX) + stp_btif_if_tx = func; + else { + osal_dbg_print("[%s] STP_IF_TX(%d) out of boundary.\n", __func__, stp_if); + return -1; + } + + return 0; +} +#if !STP_EXP_HID_API_EXPORT +EXPORT_SYMBOL(mtk_wcn_stp_register_if_tx); +#endif + +#if STP_EXP_HID_API_EXPORT +INT32 _mtk_wcn_stp_register_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func) +#else +INT32 mtk_wcn_stp_register_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func) +#endif +{ + if ((type < MTKSTP_MAX_TASK_NUM) && (type >= BT_TASK_INDX)) { + event_callback_tbl[type] = func; + + /*clear rx queue */ + mtk_wcn_stp_flush_rx_queue(type); + } + + return 0; +} +#if !STP_EXP_HID_API_EXPORT +EXPORT_SYMBOL(mtk_wcn_stp_register_event_cb); +#endif + +#if STP_EXP_HID_API_EXPORT +INT32 _mtk_wcn_stp_register_tx_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func) +#else +INT32 mtk_wcn_stp_register_tx_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func) +#endif +{ + if ((type < MTKSTP_MAX_TASK_NUM) && (type >= BT_TASK_INDX)) + tx_event_callback_tbl[type] = func; + else + osal_bug_on(0); + + return 0; +} +#if !STP_EXP_HID_API_EXPORT +EXPORT_SYMBOL(mtk_wcn_stp_register_tx_event_cb); +#endif + +#if STP_EXP_HID_API_EXPORT +INT32 _mtk_wcn_stp_register_rx_has_pending_data(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_RX_HAS_PENDING_DATA func) +#else +INT32 mtk_wcn_stp_register_rx_has_pending_data(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_RX_HAS_PENDING_DATA func) +#endif +{ + if (stp_if == STP_BTIF_IF_TX) + stp_btif_rx_has_pending_data = func; + else { + osal_dbg_print("[%s] STP_IF_TX(%d) out of boundary.\n", __func__, stp_if); + return -1; + } + + return 0; +} +#if !STP_EXP_HID_API_EXPORT +EXPORT_SYMBOL(mtk_wcn_stp_register_rx_has_pending_data); +#endif + +#if STP_EXP_HID_API_EXPORT +INT32 _mtk_wcn_stp_register_tx_has_pending_data(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_TX_HAS_PENDING_DATA func) +#else +INT32 mtk_wcn_stp_register_tx_has_pending_data(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_TX_HAS_PENDING_DATA func) +#endif +{ + if (stp_if == STP_BTIF_IF_TX) + stp_btif_tx_has_pending_data = func; + else { + osal_dbg_print("[%s] STP_IF_TX(%d) out of boundary.\n", __func__, stp_if); + return -1; + } + + return 0; +} +#if !STP_EXP_HID_API_EXPORT +EXPORT_SYMBOL(mtk_wcn_stp_register_tx_has_pending_data); +#endif + +#if STP_EXP_HID_API_EXPORT +INT32 _mtk_wcn_stp_register_rx_thread_get(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_RX_THREAD_GET func) +#else +INT32 mtk_wcn_stp_register_rx_thread_get(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_RX_THREAD_GET func) +#endif +{ + if (stp_if == STP_BTIF_IF_TX) + stp_btif_rx_thread_get = func; + else { + osal_dbg_print("[%s] STP_IF_TX(%d) out of boundary.\n", __func__, stp_if); + return -1; + } + + return 0; +} +#if !STP_EXP_HID_API_EXPORT +EXPORT_SYMBOL(mtk_wcn_stp_register_rx_thread_get); +#endif + +INT32 stp_drv_init(VOID) +{ + INT32 ret = 0; + + mtkstp_callback cb = { + .cb_if_tx = mtk_wcn_sys_if_tx, + .cb_rx_has_pending_data = mtk_wcn_sys_rx_has_pending_data, + .cb_tx_has_pending_data = mtk_wcn_sys_tx_has_pending_data, + .cb_rx_thread_get = mtk_wcn_sys_rx_thread_get, + .cb_event_set = mtk_wcn_sys_event_set, + .cb_event_tx_resume = mtk_wcn_sys_event_tx_resume, + .cb_check_funciton_status = mtk_wcn_sys_check_function_status + }; +#if 0 +#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT + MTK_WCN_STP_EXP_CB_INFO stpExpCb = { + .stp_send_data_cb = _mtk_wcn_stp_send_data, + .stp_send_data_raw_cb = _mtk_wcn_stp_send_data_raw, + .stp_parser_data_cb = _mtk_wcn_stp_parser_data, + .stp_receive_data_cb = _mtk_wcn_stp_receive_data, + .stp_is_rxqueue_empty_cb = _mtk_wcn_stp_is_rxqueue_empty, + .stp_is_ready_cb = _mtk_wcn_stp_is_ready, + .stp_set_bluez_cb = _mtk_wcn_stp_set_bluez, + .stp_if_tx_cb = _mtk_wcn_stp_register_if_tx, + .stp_if_rx_cb = _mtk_wcn_stp_register_if_rx, + .stp_reg_event_cb = _mtk_wcn_stp_register_event_cb, + .stp_reg_tx_event_cb = _mtk_wcn_stp_register_tx_event_cb, + .stp_coredump_start_get_cb = _mtk_wcn_stp_coredump_start_get + }; + mtk_wcn_stp_exp_cb_reg(&stpExpCb); + +#endif +#endif + ret = mtk_wcn_stp_init(&cb); + + return ret; +} + +VOID stp_drv_exit(VOID) +{ + mtk_wcn_stp_deinit(); +#if 0 +#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT + mtk_wcn_stp_exp_cb_unreg(); +#endif +#endif +} + +INT32 mtk_wcn_stp_sdio_wake_up_ctrl(MTK_WCN_HIF_SDIO_CLTCTX ctx) +{ + stp_sdio_wake_up_ctrl(ctx); + return 0; +} +EXPORT_SYMBOL(mtk_wcn_stp_sdio_wake_up_ctrl); + +INT32 mtk_stp_dbg_poll_cpupcr(UINT32 times, UINT32 sleep, UINT32 cmd) +{ + return stp_dbg_poll_cpupcr(times, sleep, cmd); +} +EXPORT_SYMBOL(mtk_stp_dbg_poll_cpupcr); diff --git a/drivers/misc/mediatek/connectivity/common/common_main/core/wmt_conf.c b/drivers/misc/mediatek/connectivity/common/common_main/core/wmt_conf.c new file mode 100644 index 0000000000000000000000000000000000000000..5d1d387c7a8a7623941fc251742345ea8b42bc7b --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/core/wmt_conf.c @@ -0,0 +1,695 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +#ifdef DFT_TAG +#undef DFT_TAG +#endif +#define DFT_TAG "[WMT-CONF]" + + +#include "osal_typedef.h" +/* #include "osal.h" */ +#include "wmt_lib.h" +#include "wmt_dev.h" +#include "wmt_conf.h" +#include "wmt_detect.h" + + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ +struct parse_data { + PINT8 name; + INT32 (*parser)(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 value); + PINT8 (*writer)(P_DEV_WMT pWmtDev, const struct parse_data *data); + /*PCHAR param1, *param2, *param3; */ + /* TODO:[FixMe][George] CLARIFY WHAT SHOULD BE USED HERE!!! */ + PINT8 param1; + PINT8 param2; + PINT8 param3; +}; + + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + + +/****************************************************************************** +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************* +*/ +static INT32 wmt_conf_parse_char(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos); + +static PINT8 wmt_conf_write_char(P_DEV_WMT pWmtDev, const struct parse_data *data); + +static INT32 wmt_conf_parse_short(P_DEV_WMT pWmtDev, + const struct parse_data *data, const PINT8 pos); + +static PINT8 wmt_conf_write_short(P_DEV_WMT pWmtDev, const struct parse_data *data); + +static INT32 wmt_conf_parse_int(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos); + +static PINT8 wmt_conf_write_int(P_DEV_WMT pWmtDev, const struct parse_data *data); + +static INT32 wmt_conf_parse_byte_array(P_DEV_WMT pWmtDev, const struct parse_data *data, + const PINT8 pos); + +static PINT8 wmt_conf_write_byte_array(P_DEV_WMT pWmtDev, const struct parse_data *data); + +static INT32 wmt_conf_parse_string(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos); + +static PINT8 wmt_conf_write_string(P_DEV_WMT pWmtDev, const struct parse_data *data); + +static INT32 wmt_conf_parse_pair(P_DEV_WMT pWmtDev, const PINT8 pKey, const PINT8 pVal); + +static INT32 wmt_conf_parse(P_DEV_WMT pWmtDev, const PINT8 pInBuf, UINT32 size); + +#define OFFSET(v) ((void *) &((P_DEV_WMT) 0)->v) + +#define CHAR(f) {#f, wmt_conf_parse_char, wmt_conf_write_char, OFFSET(rWmtGenConf.f), NULL, NULL} + +#define SHORT(f) {#f, wmt_conf_parse_short, wmt_conf_write_short, OFFSET(rWmtGenConf.f), NULL, NULL} + +#define INT(f) {#f, wmt_conf_parse_int, wmt_conf_write_int, OFFSET(rWmtGenConf.f), NULL, NULL} + +#define BYTE_ARRAY(f) {#f, wmt_conf_parse_byte_array, wmt_conf_write_byte_array, \ + OFFSET(rWmtGenConf.f), NULL, NULL} + +#define STRING(f) {#f, wmt_conf_parse_string, wmt_conf_write_string, OFFSET(rWmtGenConf.f), NULL, NULL} + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +static const struct parse_data wmtcfg_fields[] = { + CHAR(coex_wmt_ant_mode), + CHAR(coex_wmt_ant_mode_ex), + CHAR(coex_wmt_ext_component), + CHAR(coex_wmt_wifi_time_ctl), + CHAR(coex_wmt_ext_pta_dev_on), + CHAR(coex_wmt_filter_mode), + + CHAR(coex_bt_rssi_upper_limit), + CHAR(coex_bt_rssi_mid_limit), + CHAR(coex_bt_rssi_lower_limit), + CHAR(coex_bt_pwr_high), + CHAR(coex_bt_pwr_mid), + CHAR(coex_bt_pwr_low), + + CHAR(coex_wifi_rssi_upper_limit), + CHAR(coex_wifi_rssi_mid_limit), + CHAR(coex_wifi_rssi_lower_limit), + CHAR(coex_wifi_pwr_high), + CHAR(coex_wifi_pwr_mid), + CHAR(coex_wifi_pwr_low), + + CHAR(coex_ext_pta_hi_tx_tag), + CHAR(coex_ext_pta_hi_rx_tag), + CHAR(coex_ext_pta_lo_tx_tag), + CHAR(coex_ext_pta_lo_rx_tag), + SHORT(coex_ext_pta_sample_t1), + SHORT(coex_ext_pta_sample_t2), + CHAR(coex_ext_pta_wifi_bt_con_trx), + + INT(coex_misc_ext_pta_on), + INT(coex_misc_ext_feature_set), + + CHAR(wmt_gps_lna_pin), + CHAR(wmt_gps_lna_enable), + + CHAR(pwr_on_rtc_slot), + CHAR(pwr_on_ldo_slot), + CHAR(pwr_on_rst_slot), + CHAR(pwr_on_off_slot), + CHAR(pwr_on_on_slot), + CHAR(co_clock_flag), + + CHAR(disable_deep_sleep_cfg), + + INT(sdio_driving_cfg), + + SHORT(coex_wmt_wifi_path), + + CHAR(coex_wmt_ext_elna_gain_p1_support), + INT(coex_wmt_ext_elna_gain_p1_D0), + INT(coex_wmt_ext_elna_gain_p1_D1), + INT(coex_wmt_ext_elna_gain_p1_D2), + INT(coex_wmt_ext_elna_gain_p1_D3), + STRING(coex_wmt_antsel_invert_support), + CHAR(coex_wmt_ext_epa_mode), + + BYTE_ARRAY(coex_wmt_epa_elna), + + CHAR(bt_tssi_from_wifi), + SHORT(bt_tssi_target), + + CHAR(coex_config_bt_ctrl), + CHAR(coex_config_bt_ctrl_mode), + CHAR(coex_config_bt_ctrl_rw), + + CHAR(coex_config_addjust_opp_time_ratio), + CHAR(coex_config_addjust_opp_time_ratio_bt_slot), + CHAR(coex_config_addjust_opp_time_ratio_wifi_slot), + + CHAR(coex_config_addjust_ble_scan_time_ratio), + CHAR(coex_config_addjust_ble_scan_time_ratio_bt_slot), + CHAR(coex_config_addjust_ble_scan_time_ratio_wifi_slot), + + CHAR(wifi_ant_swap_mode), + CHAR(wifi_main_ant_polarity), + CHAR(wifi_ant_swap_ant_sel_gpio), + + /* This is an open config whose actual purpose is decided by WIFI. */ + BYTE_ARRAY(wifi_config), +}; + +#define NUM_WMTCFG_FIELDS (osal_sizeof(wmtcfg_fields) / osal_sizeof(wmtcfg_fields[0])) + +static INT32 wmt_conf_parse_char(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos) +{ + PUINT8 dst; + long res = 0; + + dst = (PINT8)(((PUINT8) pWmtDev) + (long)data->param1); + + if ((osal_strlen(pos) > 2) && ((*pos) == '0') && (*(pos + 1) == 'x')) { + osal_strtol(pos + 2, 16, &res); + *dst = (UINT8)res; + WMT_DBG_FUNC("wmtcfg==> %s=0x%x\n", data->name, *dst); + } else { + osal_strtol(pos, 10, &res); + *dst = (UINT8)res; + WMT_DBG_FUNC("wmtcfg==> %s=%d\n", data->name, *dst); + } + return 0; +} + +static PINT8 wmt_conf_write_char(P_DEV_WMT pWmtDev, const struct parse_data *data) +{ + PINT8 src; + INT32 res; + PINT8 value; + + src = (PINT8) (((PUINT8) pWmtDev) + (long)data->param1); + + value = osal_malloc(20); + if (value == NULL) + return NULL; + res = osal_snprintf(value, 20, "0x%x", *src); + if (res < 0 || res >= 20) { + osal_free(value); + return NULL; + } + value[20 - 1] = '\0'; + return value; +} + +static INT32 wmt_conf_parse_short(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos) +{ + PUINT16 dst; + long res = 0; + + dst = (PINT16)(((PUINT8) pWmtDev) + (long)data->param1); + + /* WMT_INFO_FUNC(">strlen(pos)=%d\n", strlen(pos)); */ + + if ((osal_strlen(pos) > 2) && ((*pos) == '0') && (*(pos + 1) == 'x')) { + osal_strtol(pos + 2, 16, &res); + *dst = (UINT16)res; + WMT_DBG_FUNC("wmtcfg==> %s=0x%x\n", data->name, *dst); + } else { + osal_strtol(pos, 10, &res); + *dst = (UINT16)res; + WMT_DBG_FUNC("wmtcfg==> %s=%d\n", data->name, *dst); + } + + return 0; +} + +static PINT8 wmt_conf_write_short(P_DEV_WMT pWmtDev, const struct parse_data *data) +{ + PINT16 src; + INT32 res; + PINT8 value; + + /* TODO: [FixMe][George] FIX COMPILE WARNING HERE! */ + src = (PINT16) (((PUINT8) pWmtDev) + (long)data->param1); + + value = osal_malloc(20); + if (value == NULL) + return NULL; + res = osal_snprintf(value, 20, "0x%x", *src); + if (res < 0 || res >= 20) { + osal_free(value); + return NULL; + } + value[20 - 1] = '\0'; + return value; +} + +static INT32 wmt_conf_parse_int(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos) +{ + PUINT32 dst; + long res = 0; + + dst = (PINT32)(((PUINT8) pWmtDev) + (long)data->param1); + + /* WMT_INFO_FUNC(">strlen(pos)=%d\n", strlen(pos)); */ + + if ((osal_strlen(pos) > 2) && ((*pos) == '0') && (*(pos + 1) == 'x')) { + osal_strtol(pos + 2, 16, &res); + *dst = (UINT32)res; + WMT_DBG_FUNC("wmtcfg==> %s=0x%x\n", data->name, *dst); + } else { + osal_strtol(pos, 10, &res); + *dst = (UINT32)res; + WMT_DBG_FUNC("wmtcfg==> %s=%d\n", data->name, *dst); + } + + return 0; +} + +static PINT8 wmt_conf_write_int(P_DEV_WMT pWmtDev, const struct parse_data *data) +{ + PINT32 src; + INT32 res; + PINT8 value; + + src = (PUINT32) (((PUINT8) pWmtDev) + (long) data->param1); + + value = osal_malloc(20); + if (value == NULL) + return NULL; + res = osal_snprintf(value, 20, "0x%x", *src); + if (res < 0 || res >= 20) { + osal_free(value); + return NULL; + } + value[20 - 1] = '\0'; + return value; +} + +static INT32 wmt_conf_parse_string(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos) +{ + PUINT8 *dst = NULL; + PUINT8 buffer; + + buffer = osal_malloc(osal_strlen(pos)+1); + if (buffer == NULL) { + WMT_ERR_FUNC("wmtcfg==> %s malloc fail, size %d\n", data->name, osal_strlen(pos)+1); + return -1; + } + + osal_strcpy(buffer, pos); + dst = (PUINT8 *)(((PUINT8) pWmtDev) + (long)data->param1); + *dst = (PUINT8)buffer; + WMT_DBG_FUNC("wmtcfg==> %s=%s\n", data->name, *dst); + + return 0; +} + +static PINT8 wmt_conf_write_string(P_DEV_WMT pWmtDev, const struct parse_data *data) +{ + PUINT8 *src; + INT32 res; + PINT8 value; + UINT32 str_size; + + src = (PUINT8 *)(((PUINT8) pWmtDev) + (long)data->param1); + if (*src == NULL) + return NULL; + + str_size = osal_strlen(*src) + 1; + value = osal_malloc(str_size); + if (value == NULL) + return NULL; + + res = osal_snprintf(value, str_size, "%s", *src); + if (res < 0 || res >= str_size) { + osal_free(value); + return NULL; + } + + value[str_size - 1] = '\0'; + return value; +} + +static INT32 wmt_conf_parse_byte_array(P_DEV_WMT pWmtDev, + const struct parse_data *data, const PINT8 pos) +{ + PUINT8 *dst = NULL; + struct WMT_BYTE_ARRAY *ba = NULL; + PUINT8 buffer; + INT32 size = osal_strlen(pos) / 2; + UINT8 temp[3]; + INT32 i; + long value; + + if (size <= 1) { + WMT_ERR_FUNC("wmtcfg==> %s has no value assigned\n", + data->name); + return -1; + } else if (size & 0x1) { + WMT_ERR_FUNC("wmtcfg==> %s, length should be even\n", data->name); + return -1; + } + + ba = (struct WMT_BYTE_ARRAY *)osal_malloc(sizeof(struct WMT_BYTE_ARRAY)); + if (ba == NULL) { + WMT_ERR_FUNC("wmtcfg==> %s malloc fail\n", data->name); + return -1; + } + + buffer = osal_malloc(size); + if (buffer == NULL) { + osal_free(ba); + WMT_ERR_FUNC("wmtcfg==> %s malloc fail, size %d\n", data->name, size); + return -1; + } + + temp[2] = '\0'; + for (i = 0; i < size; i++) { + osal_memcpy(temp, &pos[i * 2], 2); + if (osal_strtol(temp, 16, &value) < 0) { + WMT_ERR_FUNC("wmtcfg==> %s should be hexadecimal format\n", data->name); + osal_free(ba); + osal_free(buffer); + return -1; + } + buffer[i] = (UINT8)value; + } + ba->data = buffer; + ba->size = size; + + dst = (PUINT8 *)(((PUINT8) pWmtDev) + (long)data->param1); + *dst = (PUINT8)ba; + + return 0; +} + +static PINT8 wmt_conf_write_byte_array(P_DEV_WMT pWmtDev, const struct parse_data *data) +{ + PUINT8 *src = NULL; + PINT8 value; + struct WMT_BYTE_ARRAY *ba = NULL; + INT32 i; + + src = (PUINT8 *) (((PUINT8) pWmtDev) + (long)data->param1); + if (*src == NULL) + return NULL; + + ba = (struct WMT_BYTE_ARRAY *)*src; + + value = osal_malloc(ba->size * 2 + 1); + if (value == NULL) + return NULL; + + for (i = 0; i < ba->size; i++) + osal_snprintf(&value[i * 2], 3, "%x", ba->data[i]); + + return value; +} + +static INT32 wmt_conf_parse_pair(P_DEV_WMT pWmtDev, const PINT8 pKey, const PINT8 pVal) +{ + INT32 i = 0; + INT32 ret = 0; + + /* WMT_INFO_FUNC( DBG_NAME "cfg(%s) val(%s)\n", pKey, pVal); */ + + for (i = 0; i < NUM_WMTCFG_FIELDS; i++) { + const struct parse_data *field = &wmtcfg_fields[i]; + + if (osal_strcmp(pKey, field->name) != 0) + continue; + if (field->parser(pWmtDev, field, pVal)) { + WMT_ERR_FUNC("failed to parse %s '%s'.\n", pKey, pVal); + ret = -1; + } + break; + } + if (i == NUM_WMTCFG_FIELDS) { + WMT_ERR_FUNC("unknown field '%s'.\n", pKey); + ret = -1; + } + + return ret; +} + +static INT32 wmt_conf_parse(P_DEV_WMT pWmtDev, const PINT8 pInBuf, UINT32 size) +{ + PINT8 pch; + PINT8 pBuf; + PINT8 pLine; + PINT8 pKey; + PINT8 pVal; + PINT8 pPos; + INT32 ret = 0; + INT32 i = 0; + PINT8 pa = NULL; + + pBuf = osal_malloc(size+1); + if (!pBuf) + return -1; + + osal_memcpy(pBuf, pInBuf, size); + pBuf[size] = '\0'; + + pch = pBuf; + /* pch is to be updated by strsep(). Keep pBuf unchanged!! */ + +#if 0 + { + PINT8 buf_ptr = pBuf; + INT32 k = 0; + + WMT_INFO_FUNC("%s len=%d", "wmcfg.content:", size); + for (k = 0; k < size; k++) { + /* if(k%16 == 0) WMT_INFO_FUNC("\n"); */ + WMT_INFO_FUNC("%c", buf_ptr[k]); + } + WMT_INFO_FUNC("--end\n"); + } +#endif + + while ((pLine = osal_strsep(&pch, "\r\n")) != NULL) { + /* pch is updated to the end of pLine by strsep() and updated to '\0' */ + /*WMT_INFO_FUNC("strsep offset(%d), char(%d, '%c' )\n", pLine-pBuf, *pLine, *pLine); */ + /* parse each line */ + + /* WMT_INFO_FUNC("==> Line = (%s)\n", pLine); */ + + if (!*pLine) + continue; + + pVal = osal_strchr(pLine, '='); + if (!pVal) { + WMT_WARN_FUNC("mal-format cfg string(%s)\n", pLine); + continue; + } + + /* |<-pLine->|'='<-pVal->|'\n' ('\0')| */ + *pVal = '\0'; /* replace '=' with '\0' to get key */ + /* |<-pKey->|'\0'|<-pVal->|'\n' ('\0')| */ + pKey = pLine; + + if ((pVal - pBuf) < size) + pVal++; + + /*key handling */ + pPos = pKey; + /*skip space characeter */ + while (((*pPos) == ' ') || ((*pPos) == '\t') || ((*pPos) == '\n')) { + if ((pPos - pBuf) >= size) + break; + pPos++; + } + /*key head */ + pKey = pPos; + while (((*pPos) != ' ') && ((*pPos) != '\t') && ((*pPos) != '\0') + && ((*pPos) != '\n')) { + if ((pPos - pBuf) >= size) + break; + pPos++; + } + /*key tail */ + (*pPos) = '\0'; + + /*value handling */ + pPos = pVal; + /*skip space characeter */ + while (((*pPos) == ' ') || ((*pPos) == '\t') || ((*pPos) == '\n')) { + if ((pPos - pBuf) >= size) + break; + pPos++; + } + /*value head */ + pVal = pPos; + while (((*pPos) != ' ') && ((*pPos) != '\t') && ((*pPos) != '\0') + && ((*pPos) != '\n')) { + if ((pPos - pBuf) >= size) + break; + pPos++; + } + /*value tail */ + (*pPos) = '\0'; + + /* WMT_DBG_FUNC("parse (key: #%s#, value: #%s#)\n", pKey, pVal); */ + ret = wmt_conf_parse_pair(pWmtDev, pKey, pVal); + WMT_DBG_FUNC("parse (%s, %s, %d)\n", pKey, pVal, ret); + if (ret) + WMT_WARN_FUNC("parse fail (%s, %s, %d)\n", pKey, pVal, ret); + } + + for (i = 0; i < NUM_WMTCFG_FIELDS; i++) { + const struct parse_data *field = &wmtcfg_fields[i]; + + pa = field->writer(pWmtDev, field); + if (pa) { + WMT_DBG_FUNC("#%d(%s)=>%s\n", i, field->name, pa); + osal_free(pa); + } else + WMT_ERR_FUNC("failed to parse '%s'.\n", field->name); + } + osal_free(pBuf); + return 0; +} + + +INT32 wmt_conf_set_cfg_file(const PINT8 name) +{ + if (name == NULL) { + WMT_ERR_FUNC("name is NULL\n"); + return -1; + } + if (osal_strlen(name) >= osal_sizeof(gDevWmt.cWmtcfgName)) { + WMT_ERR_FUNC("name is too long, length=%d, expect to < %zu\n", osal_strlen(name), + osal_sizeof(gDevWmt.cWmtcfgName)); + return -2; + } + osal_memset(&gDevWmt.cWmtcfgName[0], 0, osal_sizeof(gDevWmt.cWmtcfgName)); + osal_strcpy(&(gDevWmt.cWmtcfgName[0]), name); + WMT_ERR_FUNC("WMT config file is set to (%s)\n", &(gDevWmt.cWmtcfgName[0])); + + return 0; +} + + +INT32 wmt_conf_read_file(VOID) +{ + INT32 ret = -1; + ENUM_WMT_CHIP_TYPE chip_type; + + osal_memset(&gDevWmt.rWmtGenConf, 0, osal_sizeof(gDevWmt.rWmtGenConf)); + osal_memset(&gDevWmt.pWmtCfg, 0, osal_sizeof(gDevWmt.pWmtCfg)); + chip_type = wmt_detect_get_chip_type(); + if (chip_type == WMT_CHIP_TYPE_SOC) { + osal_memset(&gDevWmt.cWmtcfgName[0], 0, osal_sizeof(gDevWmt.cWmtcfgName)); + + osal_strncat(&(gDevWmt.cWmtcfgName[0]), CUST_CFG_WMT_SOC, osal_sizeof(CUST_CFG_WMT_SOC)); + } + + if (!osal_strlen(&(gDevWmt.cWmtcfgName[0]))) { + WMT_ERR_FUNC("empty Wmtcfg name\n"); + osal_assert(0); + return ret; + } + WMT_DBG_FUNC("WMT config file:%s\n", &(gDevWmt.cWmtcfgName[0])); + if (0 == + wmt_dev_patch_get(&gDevWmt.cWmtcfgName[0], (osal_firmware **) &gDevWmt.pWmtCfg)) { + /*get full name patch success */ + WMT_DBG_FUNC("get full file name(%s) buf(0x%p) size(%zu)\n", + &gDevWmt.cWmtcfgName[0], gDevWmt.pWmtCfg->data, + gDevWmt.pWmtCfg->size); + if (0 == + wmt_conf_parse(&gDevWmt, (const PINT8)gDevWmt.pWmtCfg->data, + gDevWmt.pWmtCfg->size)) { + /*config file exists */ + gDevWmt.rWmtGenConf.cfgExist = 1; + WMT_DBG_FUNC("&gDevWmt.rWmtGenConf=%p\n", &gDevWmt.rWmtGenConf); + ret = 0; + } else { + WMT_ERR_FUNC("wmt conf parsing fail\n"); + osal_assert(0); + ret = -1; + } + wmt_dev_patch_put((osal_firmware **) &gDevWmt.pWmtCfg); +/* +* if (gDevWmt.pWmtCfg) +* { +* if (gDevWmt.pWmtCfg->data) +* { +* osal_free(gDevWmt.pWmtCfg->data); +* } +* osal_free(gDevWmt.pWmtCfg); +* gDevWmt.pWmtCfg = 0; +* } +*/ + return ret; + } + WMT_ERR_FUNC("read %s file fails\n", &(gDevWmt.cWmtcfgName[0])); + osal_assert(0); + gDevWmt.rWmtGenConf.cfgExist = 0; + return ret; +} + +P_WMT_GEN_CONF wmt_conf_get_cfg(VOID) +{ + if (gDevWmt.rWmtGenConf.cfgExist == 0) + return NULL; + + return &gDevWmt.rWmtGenConf; +} + +INT32 wmt_conf_deinit(VOID) +{ + P_WMT_GEN_CONF pWmtGenConf = wmt_conf_get_cfg(); + + if (pWmtGenConf == NULL) + return -1; + + if (pWmtGenConf->coex_wmt_epa_elna != NULL) { + if (pWmtGenConf->coex_wmt_epa_elna->data != NULL) { + osal_free(pWmtGenConf->coex_wmt_epa_elna->data); + pWmtGenConf->coex_wmt_epa_elna->data = NULL; + } + osal_free(pWmtGenConf->coex_wmt_epa_elna); + pWmtGenConf->coex_wmt_epa_elna = NULL; + } + + if (pWmtGenConf->coex_wmt_antsel_invert_support != NULL) { + osal_free(pWmtGenConf->coex_wmt_antsel_invert_support); + pWmtGenConf->coex_wmt_antsel_invert_support = NULL; + } + + if (pWmtGenConf->wifi_config != NULL) { + if (pWmtGenConf->wifi_config->data != NULL) { + osal_free(pWmtGenConf->wifi_config->data); + pWmtGenConf->wifi_config->data = NULL; + } + osal_free(pWmtGenConf->wifi_config); + pWmtGenConf->wifi_config = NULL; + } + + return 0; +} + diff --git a/drivers/misc/mediatek/connectivity/common/common_main/core/wmt_core.c b/drivers/misc/mediatek/connectivity/common/common_main/core/wmt_core.c new file mode 100644 index 0000000000000000000000000000000000000000..382905526a537cd808e5a87085b8944d56ed096b --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/core/wmt_core.c @@ -0,0 +1,3820 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +#ifdef DFT_TAG +#undef DFT_TAG +#endif +#define DFT_TAG "[WMT-CORE]" + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include +#include "osal_typedef.h" +#include "connsys_debug_utility.h" +#include "wmt_lib.h" +#include "wmt_core.h" +#include "wmt_ctrl.h" +#include "wmt_ic.h" +#include "wmt_conf.h" + +#include "wmt_func.h" +#include "stp_core.h" +#include "psm_core.h" +#include "wmt_exp.h" +#include "wmt_detect.h" +#include "wmt_plat.h" +#include "wmt_dev.h" + +P_WMT_FUNC_OPS gpWmtFuncOps[WMTDRV_TYPE_MAX] = { +#if CFG_FUNC_BT_SUPPORT + [WMTDRV_TYPE_BT] = &wmt_func_bt_ops, +#else + [WMTDRV_TYPE_BT] = NULL, +#endif + +#if CFG_FUNC_FM_SUPPORT + [WMTDRV_TYPE_FM] = &wmt_func_fm_ops, +#else + [WMTDRV_TYPE_FM] = NULL, +#endif + +#if CFG_FUNC_GPS_SUPPORT + [WMTDRV_TYPE_GPS] = &wmt_func_gps_ops, +#else + [WMTDRV_TYPE_GPS] = NULL, +#endif + +#if CFG_FUNC_GPSL5_SUPPORT + [WMTDRV_TYPE_GPSL5] = &wmt_func_gpsl5_ops, +#else + [WMTDRV_TYPE_GPSL5] = NULL, +#endif + +#if CFG_FUNC_WIFI_SUPPORT + [WMTDRV_TYPE_WIFI] = &wmt_func_wifi_ops, +#else + [WMTDRV_TYPE_WIFI] = NULL, +#endif + +#if CFG_FUNC_ANT_SUPPORT + [WMTDRV_TYPE_ANT] = &wmt_func_ant_ops, +#else + [WMTDRV_TYPE_ANT] = NULL, +#endif + + +}; + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ +/* TODO:[FixMe][GeorgeKuo]: is it an MT6620 only or general general setting? + * move to wmt_ic_6620 temporarily. + */ +/* #define CFG_WMT_BT_PORT2 (1) *//* BT Port 2 Feature. */ +#define CFG_CHECK_WMT_RESULT (1) + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +static WMT_CTX gMtkWmtCtx; +static UINT8 gLpbkBuf[WMT_LPBK_BUF_LEN] = { 0 }; +#ifdef CONFIG_MTK_COMBO_ANT +static UINT8 gAntBuf[1024] = { 0 }; +#endif +#if CFG_WMT_LTE_COEX_HANDLING +static UINT32 g_open_wmt_lte_flag; +#endif +static UINT8 gFlashBuf[1024] = { 0 }; +#if CFG_WMT_LTE_COEX_HANDLING +static UINT8 msg_local_buffer[WMT_IDC_MSG_BUFFER] = { 0 }; +#endif +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +static INT32 opfunc_hif_conf(P_WMT_OP pWmtOp); +static INT32 opfunc_pwr_on(P_WMT_OP pWmtOp); +static INT32 opfunc_pwr_off(P_WMT_OP pWmtOp); +static INT32 opfunc_func_on(P_WMT_OP pWmtOp); +static INT32 opfunc_func_off(P_WMT_OP pWmtOp); +static INT32 opfunc_reg_rw(P_WMT_OP pWmtOp); +static INT32 opfunc_exit(P_WMT_OP pWmtOp); +static INT32 opfunc_pwr_sv(P_WMT_OP pWmtOp); +static INT32 opfunc_dsns(P_WMT_OP pWmtOp); +static INT32 opfunc_lpbk(P_WMT_OP pWmtOp); +static INT32 opfunc_cmd_test(P_WMT_OP pWmtOp); +static INT32 opfunc_hw_rst(P_WMT_OP pWmtOp); +static INT32 opfunc_sw_rst(P_WMT_OP pWmtOp); +static INT32 opfunc_stp_rst(P_WMT_OP pWmtOp); +static INT32 opfunc_efuse_rw(P_WMT_OP pWmtOp); +static INT32 opfunc_therm_ctrl(P_WMT_OP pWmtOp); +static INT32 opfunc_gpio_ctrl(P_WMT_OP pWmtOp); +static INT32 opfunc_sdio_ctrl(P_WMT_OP pWmtOp); +static INT32 opfunc_pin_state(P_WMT_OP pWmtOp); +static INT32 opfunc_bgw_ds(P_WMT_OP pWmtOp); +static INT32 opfunc_set_mcu_clk(P_WMT_OP pWmtOp); +static INT32 opfunc_adie_lpbk_test(P_WMT_OP pWmtOp); +static INT32 wmt_core_gen2_set_mcu_clk(UINT32 kind); +static INT32 wmt_core_gen3_set_mcu_clk(UINT32 kind); +static INT32 wmt_core_set_mcu_clk(UINT32 kind); +static VOID wmt_core_dump_func_state(PINT8 pSource); +static INT32 wmt_core_stp_init(VOID); +static INT32 wmt_core_trigger_assert(VOID); +static INT32 wmt_core_stp_deinit(VOID); +static INT32 wmt_core_hw_check(VOID); +#ifdef CONFIG_MTK_COMBO_ANT +static INT32 opfunc_ant_ram_down(P_WMT_OP pWmtOp); +static INT32 opfunc_ant_ram_stat_get(P_WMT_OP pWmtOp); +#endif +#if CFG_WMT_LTE_COEX_HANDLING +static INT32 opfunc_idc_msg_handling(P_WMT_OP pWmtOp); +#endif +static INT32 opfunc_trigger_stp_assert(P_WMT_OP pWmtOp); +static INT32 opfunc_flash_patch_down(P_WMT_OP pWmtOp); +static INT32 opfunc_flash_patch_ver_get(P_WMT_OP pWmtOp); +static INT32 opfunc_utc_time_sync(P_WMT_OP pWmtOp); +static INT32 opfunc_fw_log_ctrl(P_WMT_OP pWmtOp); +static INT32 opfunc_wlan_probe(P_WMT_OP pWmtOp); +static INT32 opfunc_wlan_remove(P_WMT_OP pWmtOp); +static INT32 opfunc_try_pwr_off(P_WMT_OP pWmtOp); +static INT32 opfunc_gps_mcu_ctrl(P_WMT_OP pWmtOp); +static INT32 opfunc_blank_status_ctrl(P_WMT_OP pWmtOp); +static INT32 opfunc_met_ctrl(P_WMT_OP pWmtOp); +static INT32 opfunc_gps_suspend(P_WMT_OP pWmtOp); +static INT32 opfunc_get_consys_state(P_WMT_OP pWmtOp); + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +static const UINT8 WMT_SLEEP_CMD[] = { 0x01, 0x03, 0x01, 0x00, 0x01 }; +static const UINT8 WMT_SLEEP_EVT[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x01 }; + +static const UINT8 WMT_HOST_AWAKE_CMD[] = { 0x01, 0x03, 0x01, 0x00, 0x02 }; +static const UINT8 WMT_HOST_AWAKE_EVT[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x02 }; + +static const UINT8 WMT_WAKEUP_CMD[] = { 0xFF }; +static const UINT8 WMT_WAKEUP_EVT[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x03 }; + +static UINT8 WMT_THERM_CMD[] = { 0x01, 0x11, 0x01, 0x00, + 0x00 /*thermal sensor operation */ +}; +static UINT8 WMT_THERM_CTRL_EVT[] = { 0x02, 0x11, 0x01, 0x00, 0x00 }; +static UINT8 WMT_THERM_READ_EVT[] = { 0x02, 0x11, 0x02, 0x00, 0x00, 0x00 }; + +static UINT8 WMT_EFUSE_CMD[] = { 0x01, 0x0D, 0x08, 0x00, + 0x01, /*[4]operation, 0:init, 1:write 2:read */ + 0x01, /*[5]Number of register setting */ + 0xAA, 0xAA, /*[6-7]Address */ + 0xBB, 0xBB, 0xBB, 0xBB /*[8-11] Value */ +}; + +static UINT8 WMT_EFUSE_EVT[] = { 0x02, 0x0D, 0x08, 0x00, + 0xAA, /*[4]operation, 0:init, 1:write 2:read */ + 0xBB, /*[5]Number of register setting */ + 0xCC, 0xCC, /*[6-7]Address */ + 0xDD, 0xDD, 0xDD, 0xDD /*[8-11] Value */ +}; + +static UINT8 WMT_DSNS_CMD[] = { 0x01, 0x0E, 0x02, 0x00, 0x01, + 0x00 /*desnse type */ +}; +static UINT8 WMT_DSNS_EVT[] = { 0x02, 0x0E, 0x01, 0x00, 0x00 }; + +/* TODO:[NewFeature][GeorgeKuo] Update register group in ONE CMD/EVT */ +static UINT8 WMT_SET_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ + , 0x00 /*op: w(1) & r(2) */ + , 0x01 /*type: reg */ + , 0x00 /*res */ + , 0x01 /*1 register */ + , 0x00, 0x00, 0x00, 0x00 /* addr */ + , 0x00, 0x00, 0x00, 0x00 /* value */ + , 0xFF, 0xFF, 0xFF, 0xFF /*mask */ +}; + +static UINT8 WMT_SET_REG_WR_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ + , 0x00 /*S: 0 */ + , 0x00 /*type: reg */ + , 0x00 /*rev */ + , 0x01 /*1 register */ + /* , 0x00, 0x00, 0x00, 0x00 *//* addr */ + /* , 0x00, 0x00, 0x00, 0x00 *//* value */ +}; + +static UINT8 WMT_SET_REG_RD_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ + , 0x00 /*S: 0 */ + , 0x00 /*type: reg */ + , 0x00 /*rev */ + , 0x01 /*1 register */ + , 0x00, 0x00, 0x00, 0x00 /* addr */ + , 0x00, 0x00, 0x00, 0x00 /* value */ +}; + +#ifdef CONFIG_MTK_COMBO_ANT +static UINT8 WMT_ANT_RAM_STA_GET_CMD[] = { 0x01, 0x06, 0x02, 0x00, 0x05, 0x02 +}; +static UINT8 WMT_ANT_RAM_STA_GET_EVT[] = { 0x02, 0x06, 0x03, 0x00 /*length */ + , 0x05, 0x02, 0x00 /*S: result */ +}; +static UINT8 WMT_ANT_RAM_DWN_CMD[] = { 0x01, 0x15, 0x00, 0x00, 0x01 +}; +static UINT8 WMT_ANT_RAM_DWN_EVT[] = { 0x02, 0x15, 0x01, 0x00 /*length */ + , 0x00 +}; +#endif + +static UINT8 WMT_FLASH_PATCH_VER_GET_CMD[] = { 0x01, 0x01, 0x05, 0x00 /*length*/ + , 0x06, 0x00, 0x00, 0x00, 0x00 /*flash patch type*/ +}; + +static UINT8 WMT_FLASH_PATCH_VER_GET_EVT[] = { 0x02, 0x01, 0x09, 0x00 /*length */ + , 0x06, 0x00, 0x00, 0x00, 0x00 /*flash patch type*/ + , 0x00, 0x00, 0x00, 0x00 /*flash patch version*/ +}; + +static UINT8 WMT_FLASH_PATCH_DWN_CMD[] = { 0x01, 0x01, 0x0d, 0x00, 0x05 +}; + +static UINT8 WMT_FLASH_PATCH_DWN_EVT[] = { 0x02, 0x01, 0x01, 0x00 /*length */ + , 0x00 +}; + +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH +static UINT8 WMT_UTC_SYNC_CMD[] = { 0x01, 0xF0, 0x09, 0x00, 0x02 + , 0x00, 0x00, 0x00, 0x00 /*UTC time second unit*/ + , 0x00, 0x00, 0x00, 0x00 /*UTC time microsecond unit*/ +}; +static UINT8 WMT_UTC_SYNC_EVT[] = { 0x02, 0xF0, 0x02, 0x00, 0x02, 0x00 +}; + +static UINT8 WMT_BLANK_STATUS_CMD[] = { 0x01, 0xF0, 0x02, 0x00, 0x03, 0x00 }; +static UINT8 WMT_BLANK_STATUS_EVT[] = { 0x02, 0xF0, 0x02, 0x00, 0x03, 0x00 }; +#endif + +static UINT8 WMT_FW_LOG_CTRL_CMD[] = { 0x01, 0xF0, 0x04, 0x00, 0x01 + , 0x00 /* subsys type */ + , 0x00 /* on/off */ + , 0x00 /* level (subsys-specific) */ +}; +static UINT8 WMT_FW_LOG_CTRL_EVT[] = { 0x02, 0xF0, 0x02, 0x00, 0x01, 0x00 }; + +/* GeorgeKuo: Use designated initializers described in + * http://gcc.gnu.org/onlinedocs/gcc-4.0.4/gcc/Designated-Inits.html + */ + +static const WMT_OPID_FUNC wmt_core_opfunc[] = { + [WMT_OPID_HIF_CONF] = opfunc_hif_conf, + [WMT_OPID_PWR_ON] = opfunc_pwr_on, + [WMT_OPID_PWR_OFF] = opfunc_pwr_off, + [WMT_OPID_FUNC_ON] = opfunc_func_on, + [WMT_OPID_FUNC_OFF] = opfunc_func_off, + [WMT_OPID_REG_RW] = opfunc_reg_rw, /* TODO:[ChangeFeature][George] is this OP obsoleted? */ + [WMT_OPID_EXIT] = opfunc_exit, + [WMT_OPID_PWR_SV] = opfunc_pwr_sv, + [WMT_OPID_DSNS] = opfunc_dsns, + [WMT_OPID_LPBK] = opfunc_lpbk, + [WMT_OPID_CMD_TEST] = opfunc_cmd_test, + [WMT_OPID_HW_RST] = opfunc_hw_rst, + [WMT_OPID_SW_RST] = opfunc_sw_rst, + [WMT_OPID_STP_RST] = opfunc_stp_rst, + [WMT_OPID_THERM_CTRL] = opfunc_therm_ctrl, + [WMT_OPID_EFUSE_RW] = opfunc_efuse_rw, + [WMT_OPID_GPIO_CTRL] = opfunc_gpio_ctrl, + [WMT_OPID_SDIO_CTRL] = opfunc_sdio_ctrl, + [WMT_OPID_GPIO_STATE] = opfunc_pin_state, + [WMT_OPID_BGW_DS] = opfunc_bgw_ds, + [WMT_OPID_SET_MCU_CLK] = opfunc_set_mcu_clk, + [WMT_OPID_ADIE_LPBK_TEST] = opfunc_adie_lpbk_test, +#ifdef CONFIG_MTK_COMBO_ANT + [WMT_OPID_ANT_RAM_DOWN] = opfunc_ant_ram_down, + [WMT_OPID_ANT_RAM_STA_GET] = opfunc_ant_ram_stat_get, +#endif +#if CFG_WMT_LTE_COEX_HANDLING + [WMT_OPID_IDC_MSG_HANDLING] = opfunc_idc_msg_handling, +#endif + [WMT_OPID_TRIGGER_STP_ASSERT] = opfunc_trigger_stp_assert, + [WMT_OPID_FLASH_PATCH_DOWN] = opfunc_flash_patch_down, + [WMT_OPID_FLASH_PATCH_VER_GET] = opfunc_flash_patch_ver_get, + [WMT_OPID_UTC_TIME_SYNC] = opfunc_utc_time_sync, + [WMT_OPID_FW_LOG_CTRL] = opfunc_fw_log_ctrl, + [WMT_OPID_WLAN_PROBE] = opfunc_wlan_probe, + [WMT_OPID_WLAN_REMOVE] = opfunc_wlan_remove, + [WMT_OPID_GPS_MCU_CTRL] = opfunc_gps_mcu_ctrl, + [WMT_OPID_TRY_PWR_OFF] = opfunc_try_pwr_off, + [WMT_OPID_BLANK_STATUS_CTRL] = opfunc_blank_status_ctrl, + [WMT_OPID_MET_CTRL] = opfunc_met_ctrl, + [WMT_OPID_GPS_SUSPEND] = opfunc_gps_suspend, + [WMT_OPID_GET_CONSYS_STATE] = opfunc_get_consys_state, +}; + +atomic_t g_wifi_on_off_ready; + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +INT32 wmt_core_init(VOID) +{ + INT32 i = 0; + + osal_memset(&gMtkWmtCtx, 0, osal_sizeof(gMtkWmtCtx)); + /* gMtkWmtCtx.p_ops is cleared to NULL */ + + /* default FUNC_OFF state */ + for (i = 0; i < WMTDRV_TYPE_MAX; ++i) { + /* WinMo is default to DRV_STS_UNREG; */ + gMtkWmtCtx.eDrvStatus[i] = DRV_STS_POWER_OFF; + } + + atomic_set(&g_wifi_on_off_ready, 0); + + return 0; +} + +INT32 wmt_core_deinit(VOID) +{ + /* return to init state */ + osal_memset(&gMtkWmtCtx, 0, osal_sizeof(gMtkWmtCtx)); + /* gMtkWmtCtx.p_ops is cleared to NULL */ + return 0; +} + +/* TODO: [ChangeFeature][George] Is wmt_ctrl a good interface? maybe not...... */ +/* parameters shall be copied in/from ctrl buffer, which is also a size-wasting buffer. */ +INT32 +wmt_core_tx(const PUINT8 pData, const UINT32 size, PUINT32 writtenSize, const MTK_WCN_BOOL bRawFlag) +{ + INT32 iRet = 0; + INT32 retry_times = 0; + INT32 max_retry_times = 0; + INT32 retry_delay_ms = 0; + ENUM_WMT_CHIP_TYPE chip_type; + + chip_type = wmt_detect_get_chip_type(); + iRet = wmt_ctrl_tx_ex(pData, size, writtenSize, bRawFlag); + if (*writtenSize == 0 && (chip_type == WMT_CHIP_TYPE_SOC)) { + retry_times = 0; + max_retry_times = 3; + retry_delay_ms = 360; + WMT_WARN_FUNC("WMT-CORE: wmt_ctrl_tx_ex failed and written ret:%d, maybe no winspace in STP layer\n", + *writtenSize); + while ((*writtenSize == 0) && (retry_times < max_retry_times)) { + WMT_ERR_FUNC("WMT-CORE: retrying, wait for %d ms\n", retry_delay_ms); + osal_sleep_ms(retry_delay_ms); + + iRet = wmt_ctrl_tx_ex(pData, size, writtenSize, bRawFlag); + retry_times++; + } + } + return iRet; +} + +INT32 wmt_core_rx(PUINT8 pBuf, UINT32 bufLen, PUINT32 readSize) +{ + INT32 iRet; + WMT_CTRL_DATA ctrlData; + + ctrlData.ctrlId = WMT_CTRL_RX; + ctrlData.au4CtrlData[0] = (SIZE_T) pBuf; + ctrlData.au4CtrlData[1] = bufLen; + ctrlData.au4CtrlData[2] = (SIZE_T) readSize; + + iRet = wmt_ctrl(&ctrlData); + if (iRet) { + /* ERROR */ + WMT_ERR_FUNC("WMT-CORE: wmt_core_ctrl failed: WMT_CTRL_RX, iRet:%d\n", iRet); + osal_assert(0); + } + return iRet; +} + +INT32 wmt_core_rx_flush(UINT32 type) +{ + INT32 iRet; + WMT_CTRL_DATA ctrlData; + + ctrlData.ctrlId = WMT_CTRL_RX_FLUSH; + ctrlData.au4CtrlData[0] = (UINT32) type; + + iRet = wmt_ctrl(&ctrlData); + if (iRet) { + /* ERROR */ + WMT_ERR_FUNC("WMT-CORE: wmt_core_ctrl failed: WMT_CTRL_RX_FLUSH, iRet:%d\n", iRet); + osal_assert(0); + } + return iRet; +} + +INT32 wmt_core_func_ctrl_cmd(ENUM_WMTDRV_TYPE_T type, MTK_WCN_BOOL fgEn) +{ + INT32 iRet = 0; + UINT32 u4WmtCmdPduLen; + UINT32 u4WmtEventPduLen; + UINT32 u4ReadSize; + UINT32 u4WrittenSize; + WMT_PKT rWmtPktCmd; + WMT_PKT rWmtPktEvent; + MTK_WCN_BOOL fgFail; + + /* TODO:[ChangeFeature][George] remove WMT_PKT. replace it with hardcoded arrays. */ + /* Using this struct relies on compiler's implementation and pack() settings */ + osal_memset(&rWmtPktCmd, 0, osal_sizeof(rWmtPktCmd)); + osal_memset(&rWmtPktEvent, 0, osal_sizeof(rWmtPktEvent)); + + rWmtPktCmd.eType = (UINT8) WMT_PKT_TYPE_CMD; + rWmtPktCmd.eOpCode = (UINT8) OPCODE_FUNC_CTRL; + + /* Flag field: driver type */ + rWmtPktCmd.aucParam[0] = (UINT8) type; + /* Parameter field: ON/OFF */ + rWmtPktCmd.aucParam[1] = (fgEn == WMT_FUNC_CTRL_ON) ? 1 : 0; + rWmtPktCmd.u2SduLen = WMT_FLAG_LEN + WMT_FUNC_CTRL_PARAM_LEN; /* (2) */ + + /* WMT Header + WMT SDU */ + u4WmtCmdPduLen = WMT_HDR_LEN + rWmtPktCmd.u2SduLen; /* (6) */ + u4WmtEventPduLen = WMT_HDR_LEN + WMT_STS_LEN; /* (5) */ + + do { + fgFail = MTK_WCN_BOOL_TRUE; +/* iRet = (*kal_stp_tx)((PUINT8)&rWmtPktCmd, u4WmtCmdPduLen, &u4WrittenSize); */ + iRet = + wmt_core_tx((PUINT8) &rWmtPktCmd, u4WmtCmdPduLen, &u4WrittenSize, + MTK_WCN_BOOL_FALSE); + if (iRet) { + WMT_ERR_FUNC("WMT-CORE: wmt_func_ctrl_cmd kal_stp_tx failed\n"); + break; + } + + iRet = wmt_core_rx((PUINT8) &rWmtPktEvent, u4WmtEventPduLen, &u4ReadSize); + if (iRet) { + WMT_ERR_FUNC + ("WMT firwmare no rx event, trigger f/w assert. sub-driver type:%d, state(%d)\n", + type, fgEn); + wmt_lib_trigger_assert(WMTDRV_TYPE_WMT, 32); + break; + } + + /* Error Checking */ + if (rWmtPktEvent.eType != WMT_PKT_TYPE_EVENT) { + WMT_ERR_FUNC + ("WMT-CORE: wmt_func_ctrl_cmd WMT_PKT_TYPE_EVENT != rWmtPktEvent.eType %d\n", + rWmtPktEvent.eType); + break; + } + + if (rWmtPktCmd.eOpCode != rWmtPktEvent.eOpCode) { + WMT_ERR_FUNC + ("WMT-CORE: wmt_func_ctrl_cmd rWmtPktCmd.eOpCode(0x%x) != rWmtPktEvent.eType(0x%x)\n", + rWmtPktCmd.eOpCode, rWmtPktEvent.eOpCode); + break; + } + + if (u4WmtEventPduLen != (rWmtPktEvent.u2SduLen + WMT_HDR_LEN)) { + WMT_ERR_FUNC + ("WMT-CORE: wmt_func_ctrl_cmd u4WmtEventPduLen(0x%x) != rWmtPktEvent.u2SduLen(0x%x)+4\n", + u4WmtEventPduLen, rWmtPktEvent.u2SduLen); + break; + } + /* Status field of event check */ + if (rWmtPktEvent.aucParam[0] != 0) { + WMT_ERR_FUNC("WMT-CORE: wmt_func_ctrl_cmd, 0 != status(%d)\n", + rWmtPktEvent.aucParam[0]); + break; + } + + fgFail = MTK_WCN_BOOL_FALSE; + } while (0); + + if (fgFail == MTK_WCN_BOOL_FALSE) { + /* WMT_INFO_FUNC("WMT-CORE: wmt_func_ctrl_cmd OK!\n"); */ + return 0; + } + WMT_ERR_FUNC("WMT-CORE: wmt_func_ctrl_cmd 0x%x FAIL\n", rWmtPktCmd.aucParam[0]); + return -2; +} + +INT32 wmt_core_opid_handler(P_WMT_OP pWmtOp) +{ + UINT32 opId; + INT32 ret; + + opId = pWmtOp->opId; + + if (wmt_core_opfunc[opId]) { + ret = (*(wmt_core_opfunc[opId])) (pWmtOp); /*wmtCoreOpidHandlerPack[].opHandler */ + return ret; + } + WMT_ERR_FUNC("WMT-CORE: null handler (%d)\n", pWmtOp->opId); + return -2; +} + +INT32 wmt_core_opid(P_WMT_OP pWmtOp) +{ + + /*sanity check */ + if (pWmtOp == NULL) { + WMT_ERR_FUNC("null pWmtOP\n"); + /*print some message with error info */ + return -1; + } + + if (pWmtOp->opId >= WMT_OPID_MAX) { + WMT_ERR_FUNC("WMT-CORE: invalid OPID(%d)\n", pWmtOp->opId); + return -2; + } + /* TODO: [FixMe][GeorgeKuo] do sanity check to const function table when init and skip checking here */ + return wmt_core_opid_handler(pWmtOp); +} + +INT32 wmt_core_ctrl(ENUM_WMT_CTRL_T ctrId, PULONG pPa1, PULONG pPa2) +{ + INT32 iRet = -1; + WMT_CTRL_DATA ctrlData; + SIZE_T val1 = (pPa1) ? *pPa1 : 0; + SIZE_T val2 = (pPa2) ? *pPa2 : 0; + + ctrlData.ctrlId = (SIZE_T) ctrId; + ctrlData.au4CtrlData[0] = val1; + ctrlData.au4CtrlData[1] = val2; + + iRet = wmt_ctrl(&ctrlData); + if (iRet) { + /* ERROR */ + WMT_ERR_FUNC + ("WMT-CORE: wmt_core_ctrl failed: id(%d), type(%zu), value(%zu) iRet:(%d)\n", + ctrId, val1, val2, iRet); + osal_assert(0); + } else { + if (pPa1) + *pPa1 = ctrlData.au4CtrlData[0]; + if (pPa2) + *pPa2 = ctrlData.au4CtrlData[1]; + } + return iRet; +} + + +VOID wmt_core_dump_data(PUINT8 pData, PUINT8 pTitle, UINT32 len) +{ + PUINT8 ptr = pData; + INT32 k = 0; + + WMT_INFO_FUNC("%s len=%d\n", pTitle, len); + for (k = 0; k < len; k++) { + if (k % 16 == 0) + WMT_INFO_FUNC("\n"); + WMT_INFO_FUNC("0x%02x ", *ptr); + ptr++; + } + WMT_INFO_FUNC("--end\n"); +} + +/*! + * \brief An WMT-CORE function to support read, write, and read after write to + * an internal register. + * + * Detailed description. + * + * \param isWrite 1 for write, 0 for read + * \param offset of register to be written or read + * \param pVal a pointer to the 32-bit value to be writtern or read + * \param mask a 32-bit mask to be applied for the read or write operation + * + * \retval 0 operation success + * \retval -1 invalid parameters + * \retval -2 tx cmd fail + * \retval -3 rx event fail + * \retval -4 read check error + */ +INT32 wmt_core_reg_rw_raw(UINT32 isWrite, UINT32 offset, PUINT32 pVal, UINT32 mask) +{ + INT32 iRet; + UINT32 u4Res; + UINT32 evtLen; + UINT8 evtBuf[16] = { 0 }; + + WMT_SET_REG_CMD[4] = (isWrite) ? 0x1 : 0x2; /* w:1, r:2 */ + osal_memcpy(&WMT_SET_REG_CMD[8], &offset, 4); /* offset */ + osal_memcpy(&WMT_SET_REG_CMD[12], pVal, 4); /* [2] is var addr */ + osal_memcpy(&WMT_SET_REG_CMD[16], &mask, 4); /* mask */ + + /* send command */ + iRet = wmt_core_tx(WMT_SET_REG_CMD, sizeof(WMT_SET_REG_CMD), &u4Res, MTK_WCN_BOOL_FALSE); + if ((iRet) || (u4Res != sizeof(WMT_SET_REG_CMD))) { + WMT_ERR_FUNC("Tx REG_CMD fail!(%d) len (%d, %zu)\n", iRet, u4Res, + sizeof(WMT_SET_REG_CMD)); + return -2; + } + + /* receive event */ + evtLen = (isWrite) ? sizeof(WMT_SET_REG_WR_EVT) : sizeof(WMT_SET_REG_RD_EVT); + iRet = wmt_core_rx(evtBuf, evtLen, &u4Res); + if ((iRet) || (u4Res != evtLen)) { + WMT_ERR_FUNC("Rx REG_EVT fail!(%d) len(%d, %d)\n", iRet, u4Res, evtLen); + if (isWrite) + WMT_INFO_FUNC("buf:[%2X,%2X,%2X,%2X,%2X] evt:[%2X,%2X,%2X,%2X,%2X]\n", + evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], + WMT_SET_REG_WR_EVT[0], WMT_SET_REG_WR_EVT[1], + WMT_SET_REG_WR_EVT[2], WMT_SET_REG_WR_EVT[3], + WMT_SET_REG_WR_EVT[4]); + else + WMT_INFO_FUNC("buf:[%2X,%2X,%2X,%2X,%2X] evt:[%2X,%2X,%2X,%2X,%2X]\n", + evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], + WMT_SET_REG_RD_EVT[0], WMT_SET_REG_RD_EVT[1], + WMT_SET_REG_RD_EVT[2], WMT_SET_REG_RD_EVT[3], + WMT_SET_REG_RD_EVT[4]); + mtk_wcn_stp_dbg_dump_package(); + wmt_core_trigger_assert(); + return -3; + } + + if (!isWrite) { + UINT32 rxEvtAddr; + UINT32 txCmdAddr; + + osal_memcpy(&txCmdAddr, &WMT_SET_REG_CMD[8], 4); + osal_memcpy(&rxEvtAddr, &evtBuf[8], 4); + + /* check read result */ + if (txCmdAddr != rxEvtAddr) { + WMT_ERR_FUNC("Check read addr fail (0x%08x, 0x%08x)\n", rxEvtAddr, + txCmdAddr); + return -4; + } + WMT_DBG_FUNC("Check read addr(0x%08x) ok\n", rxEvtAddr); + osal_memcpy(pVal, &evtBuf[12], 4); + } + + /* no error here just return 0 */ + return 0; +} + +INT32 wmt_core_init_script_retry(struct init_script *script, INT32 count, INT32 retry, INT32 dump_err_log) +{ + UINT8 evtBuf[256]; + UINT32 u4Res; + INT32 i = 0; + INT32 iRet; + INT32 err = 0; + + do { + err = 0; + for (i = 0; i < count; i++) { + WMT_DBG_FUNC("WMT-CORE: init_script operation %s start\n", script[i].str); + /* CMD */ + /* iRet = (*kal_stp_tx)(script[i].cmd, script[i].cmdSz, &u4Res); */ + iRet = wmt_core_tx(script[i].cmd, script[i].cmdSz, &u4Res, MTK_WCN_BOOL_FALSE); + if (iRet || (u4Res != script[i].cmdSz)) { + WMT_ERR_FUNC("WMT-CORE: write (%s) iRet(%d) cmd len err(%d, %d)\n", + script[i].str, iRet, u4Res, script[i].cmdSz); + + err = -1; + break; + } + /* EVENT BUF */ + + osal_memset(evtBuf, 0, sizeof(evtBuf)); + iRet = wmt_core_rx(evtBuf, script[i].evtSz, &u4Res); + if (iRet || (u4Res != script[i].evtSz)) { + WMT_ERR_FUNC("WMT-CORE: read (%s) iRet(%d) evt len err(rx:%d, exp:%d)\n", + script[i].str, iRet, u4Res, script[i].evtSz); + if (dump_err_log == 1) + mtk_wcn_stp_dbg_dump_package(); + + err = -1; + break; + } + /* RESULT */ + if (evtBuf[1] != 0x14) { /*workaround RF calibration data EVT, do not care this EVT*/ + if (osal_memcmp(evtBuf, script[i].evt, script[i].evtSz) != 0) { + WMT_ERR_FUNC("WMT-CORE:compare %s result error\n", script[i].str); + WMT_ERR_FUNC + ("WMT-CORE:rx(%d):[%02X,%02X,%02X,%02X,%02X]\n", + u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4]); + WMT_ERR_FUNC + ("WMT-CORE:exp(%d):[%02X,%02X,%02X,%02X,%02X]\n", + script[i].evtSz, script[i].evt[0], script[i].evt[1], script[i].evt[2], + script[i].evt[3], script[i].evt[4]); + if (dump_err_log == 1) + mtk_wcn_stp_dbg_dump_package(); + + err = -1; + break; + } + } + WMT_DBG_FUNC("init_script operation %s ok\n", script[i].str); + } + retry--; + } while (retry >= 0 && err < 0); + + return (i == count) ? 0 : -1; +} + + +INT32 wmt_core_init_script(struct init_script *script, INT32 count) +{ + return wmt_core_init_script_retry(script, count, 0, 1); +} + +static INT32 wmt_core_trigger_assert(VOID) +{ + INT32 ret = 0; + UINT32 u4Res; + UINT32 tstCmdSz = 0; + UINT32 tstEvtSz = 0; + UINT8 tstCmd[64]; + UINT8 tstEvt[64]; + UINT8 WMT_ASSERT_CMD[] = { 0x01, 0x02, 0x01, 0x00, 0x08 }; + UINT8 WMT_ASSERT_EVT[] = { 0x02, 0x02, 0x00, 0x00, 0x00 }; + + WMT_INFO_FUNC("Send Assert command !\n"); + tstCmdSz = osal_sizeof(WMT_ASSERT_CMD); + tstEvtSz = osal_sizeof(WMT_ASSERT_EVT); + osal_memcpy(tstCmd, WMT_ASSERT_CMD, tstCmdSz); + osal_memcpy(tstEvt, WMT_ASSERT_EVT, tstEvtSz); + + ret = wmt_core_tx((PUINT8) tstCmd, tstCmdSz, &u4Res, MTK_WCN_BOOL_FALSE); + if (ret || (u4Res != tstCmdSz)) { + WMT_ERR_FUNC("WMT-CORE: wmt_cmd_test iRet(%d) cmd len err(%d, %d)\n", ret, u4Res, + tstCmdSz); + ret = -1; + } + return ret; +} + +static INT32 wmt_core_stp_init(VOID) +{ + INT32 iRet = 0; + ULONG ctrlPa1; + ULONG ctrlPa2; + UINT8 co_clock_type; + P_WMT_CTX pctx = &gMtkWmtCtx; + P_WMT_GEN_CONF pWmtGenConf = NULL; + + if (wmt_detect_get_chip_type() == WMT_CHIP_TYPE_COMBO) + wmt_conf_read_file(); + gDevWmt.rWmtGenConf.co_clock_flag = wmt_lib_co_clock_flag_get(); + + pWmtGenConf = wmt_conf_get_cfg(); + if (pWmtGenConf == NULL) + WMT_ERR_FUNC("WMT-CORE: wmt_conf_get_cfg return NULL!!\n"); + if (!(pctx->wmtInfoBit & WMT_OP_HIF_BIT)) { + WMT_ERR_FUNC("WMT-CORE: no hif info!\n"); + osal_assert(0); + return -WMT_ERRCODE_NO_HIF_INFO; + } + + /* 4 <0> turn on SDIO2 for common SDIO */ + if (pctx->wmtHifConf.hifType == WMT_HIF_SDIO) { + ctrlPa1 = WMT_SDIO_SLOT_SDIO2; + ctrlPa2 = 1; /* turn on SDIO2 slot */ + iRet = wmt_core_ctrl(WMT_CTRL_SDIO_HW, &ctrlPa1, &ctrlPa2); + if (iRet) { + WMT_ERR_FUNC("WMT-CORE: turn on SLOT_SDIO2 fail (%d)\n", iRet); + osal_assert(0); + + return -WMT_ERRCODE_SDIO_SLOT_SDIO2_FAIL; + } + pctx->eDrvStatus[WMTDRV_TYPE_SDIO2] = DRV_STS_FUNC_ON; + + ctrlPa1 = WMT_SDIO_FUNC_STP; + ctrlPa2 = 1; /* turn on STP driver */ + iRet = wmt_core_ctrl(WMT_CTRL_SDIO_FUNC, &ctrlPa1, &ctrlPa2); + if (iRet) { + WMT_ERR_FUNC("WMT-CORE: turn on SDIO_FUNC_STP func fail (%d)\n", iRet); + + /* check all sub-func and do power off */ + return -WMT_ERRCODE_SDIO_FUNC_STP_FAIL; + } + } + /* 4 <1> open stp */ + ctrlPa1 = 0; + ctrlPa2 = 0; + iRet = wmt_core_ctrl(WMT_CTRL_STP_OPEN, &ctrlPa1, &ctrlPa2); + if (iRet) { + WMT_ERR_FUNC("WMT-CORE: wmt open stp failed.\n"); + return -WMT_ERRCODE_OPEN_STP_FAIL; + } + + if (pctx->wmtHifConf.hifType == WMT_HIF_UART) { + ctrlPa1 = WMT_DEFAULT_BAUD_RATE; + ctrlPa2 = 0; + iRet = wmt_core_ctrl(WMT_CTRL_HOST_BAUDRATE_SET, &ctrlPa1, &ctrlPa2); + if (iRet) { + WMT_ERR_FUNC("WMT-CORE: change host baudrate(%d) fails\n", + pctx->wmtHifConf.au4HifConf[0]); + return -WMT_ERRCODE_UART_BAUDRATE_FAIL; + } + } + /* WMT_DBG_FUNC("WMT-CORE: change host baudrate(%d) ok\n", gMtkWmtCtx.wmtHifConf.au4HifConf[0]); */ + + /* 4 <1.5> disable and un-ready stp */ + ctrlPa1 = WMT_STP_CONF_EN; + ctrlPa2 = 0; + iRet = wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); + if (iRet) { + WMT_ERR_FUNC("disable WMT_STP_CONF_EN fail!\n"); + return -WMT_ERRCODE_STP_CONFIG_FAIL; + } + + ctrlPa1 = WMT_STP_CONF_RDY; + ctrlPa2 = 0; + iRet = wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); + if (iRet) { + WMT_ERR_FUNC("un-ready WMT_STP_CONF_RDY fail!\n"); + return -WMT_ERRCODE_STP_CONFIG_FAIL; + } + + /* 4 <2> set mode and enable */ + if (pctx->wmtHifConf.hifType == WMT_HIF_UART) { + ctrlPa1 = WMT_STP_CONF_MODE; + ctrlPa2 = MTKSTP_UART_MAND_MODE; + iRet = wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); + if (iRet) { + WMT_ERR_FUNC("config MTKSTP_UART_MAND_MODE fail!\n"); + return -WMT_ERRCODE_STP_CONFIG_FAIL; + } + } else if (pctx->wmtHifConf.hifType == WMT_HIF_SDIO) { + + ctrlPa1 = WMT_STP_CONF_MODE; + ctrlPa2 = MTKSTP_SDIO_MODE; + iRet = wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); + if (iRet) { + WMT_ERR_FUNC("config MTKSTP_SDIO_MODE fail!\n"); + return -WMT_ERRCODE_STP_CONFIG_FAIL; + } + } else if (pctx->wmtHifConf.hifType == WMT_HIF_BTIF) { + ctrlPa1 = WMT_STP_CONF_MODE; + ctrlPa2 = MTKSTP_BTIF_MAND_MODE; + iRet = wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); + if (iRet) { + WMT_ERR_FUNC("config MTKSTP_BTIF_MAND_MODE fail!\n"); + return -WMT_ERRCODE_STP_CONFIG_FAIL; + } + } + ctrlPa1 = WMT_STP_CONF_EN; + ctrlPa2 = 1; + iRet = wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); + if (iRet) { + WMT_ERR_FUNC("enable WMT_STP_CONF_EN fail:%d\n", iRet); + return -WMT_ERRCODE_STP_CONFIG_FAIL; + } + /* TODO: [ChangeFeature][GeorgeKuo] can we apply raise UART baud rate firstly for ALL supported chips??? */ + +#ifdef CONFIG_MTK_COMBO_CHIP_DEEP_SLEEP_SUPPORT + WMT_DBG_FUNC("disable deep sleep featrue before the first command to firmware\n"); + wmt_lib_deep_sleep_flag_set(MTK_WCN_BOOL_FALSE); +#endif + + iRet = wmt_core_hw_check(); + if (iRet) { + WMT_ERR_FUNC("hw_check fail:%d\n", iRet); + return iRet; + } + /* mtkWmtCtx.p_ic_ops is identified and checked ok */ + if ((pctx->p_ic_ops->co_clock_ctrl != NULL) && (pWmtGenConf != NULL)) { + co_clock_type = (pWmtGenConf->co_clock_flag & 0x0f); + (*(pctx->p_ic_ops->co_clock_ctrl)) (co_clock_type == 0 ? WMT_CO_CLOCK_DIS : WMT_CO_CLOCK_EN); + } else { + WMT_WARN_FUNC("pctx->p_ic_ops->co_clock_ctrl(%p), pWmtGenConf(%p)\n", pctx->p_ic_ops->co_clock_ctrl, + pWmtGenConf); + } + osal_assert(pctx->p_ic_ops->sw_init != NULL); + if (pctx->p_ic_ops->sw_init != NULL) { + iRet = (*(pctx->p_ic_ops->sw_init)) (&pctx->wmtHifConf); + } else { + WMT_ERR_FUNC("gMtkWmtCtx.p_ic_ops->sw_init is NULL\n"); + return -WMT_ERRCODE_NULL_FUNC_POINTER; + } + if (iRet) { + WMT_ERR_FUNC("gMtkWmtCtx.p_ic_ops->sw_init fail:%d\n", iRet); + return iRet; + } + + /* send UTC time sync command after connsys power on or chip reset */ + opfunc_utc_time_sync(NULL); + + /* 4 <10> set stp ready */ + ctrlPa1 = WMT_STP_CONF_RDY; + ctrlPa2 = 1; + iRet = wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); + if (iRet) { + WMT_ERR_FUNC("set WMT_STP_CONF_RDY fail!\n"); + return -WMT_ERRCODE_STP_CONFIG_FAIL; + } + + return 0; +} + +static INT32 wmt_core_stp_deinit(VOID) +{ + INT32 iRet; + ULONG ctrlPa1; + ULONG ctrlPa2; + + WMT_DBG_FUNC(" start\n"); + + if (gMtkWmtCtx.p_ic_ops == NULL) { + WMT_WARN_FUNC("gMtkWmtCtx.p_ic_ops is NULL\n"); + goto deinit_ic_ops_done; + } + if (gMtkWmtCtx.p_ic_ops->sw_deinit != NULL) { + iRet = (*(gMtkWmtCtx.p_ic_ops->sw_deinit)) (&gMtkWmtCtx.wmtHifConf); + /* unbind WMT-IC */ + gMtkWmtCtx.p_ic_ops = NULL; + } else { + WMT_ERR_FUNC("gMtkWmtCtx.p_ic_ops->sw_init is NULL\n"); + } + +deinit_ic_ops_done: + + /* 4 <1> un-ready, disable, and close stp. */ + ctrlPa1 = WMT_STP_CONF_RDY; + ctrlPa2 = 0; + iRet = wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); + ctrlPa1 = WMT_STP_CONF_EN; + ctrlPa2 = 0; + iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); + ctrlPa1 = 0; + ctrlPa2 = 0; + iRet += wmt_core_ctrl(WMT_CTRL_STP_CLOSE, &ctrlPa1, &ctrlPa2); + + /* 4 <1.1> turn off SDIO2 for common SDIO */ + if (gMtkWmtCtx.wmtHifConf.hifType == WMT_HIF_SDIO) { + ctrlPa1 = WMT_SDIO_FUNC_STP; + ctrlPa2 = 0; /* turn off STP driver */ + iRet = wmt_core_ctrl(WMT_CTRL_SDIO_FUNC, &ctrlPa1, &ctrlPa2); + if (iRet) { + WMT_WARN_FUNC("turn off SDIO_FUNC_STP fail (%d)\n", iRet); + /* Anyway, continue turning SDIO HW off */ + } else { + WMT_DBG_FUNC("turn off SDIO_FUNC_STP ok\n"); + } + + ctrlPa1 = WMT_SDIO_SLOT_SDIO2; + ctrlPa2 = 0; /* turn off SDIO2 slot */ + iRet = wmt_core_ctrl(WMT_CTRL_SDIO_HW, &ctrlPa1, &ctrlPa2); + if (iRet) { + WMT_WARN_FUNC("turn off SDIO2 HW fail (%d)\n", iRet); + /* Anyway, continue turning STP SDIO to POWER OFF state */ + } else + WMT_DBG_FUNC("turn off SDIO2 HW ok\n"); + gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_SDIO2] = DRV_STS_POWER_OFF; + } + + if (iRet) + WMT_WARN_FUNC("end with fail:%d\n", iRet); + + return iRet; +} + +static VOID wmt_core_dump_func_state(PINT8 pSource) +{ + WMT_INFO_FUNC + ("[%s]status(b:%d f:%d g:%d gl5:%d w:%d lpbk:%d coredump:%d wmt:%d ant:%d sd1:%d sd2:%d stp:%d)\n", + (pSource == NULL ? (PINT8) "CORE" : pSource), gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT], + gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_FM], gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_GPS], + gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_GPSL5], + gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI], gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_LPBK], + gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_COREDUMP], gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT], + gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_ANT], gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_SDIO1], + gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_SDIO2], gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_STP] + ); + return; + +} + +ENUM_DRV_STS wmt_core_get_drv_status(ENUM_WMTDRV_TYPE_T type) +{ + if ((type < WMTDRV_TYPE_BT) || (type >= WMTDRV_TYPE_MAX)) + return DRV_STS_POWER_OFF; + return gMtkWmtCtx.eDrvStatus[type]; +} + +MTK_WCN_BOOL wmt_core_patch_check(UINT32 u4PatchVer, UINT32 u4HwVer) +{ + if (MAJORNUM(u4HwVer) != MAJORNUM(u4PatchVer)) { + /*major no. does not match */ + WMT_ERR_FUNC("WMT-CORE: chip version(0x%x) does not match patch version(0x%x)\n", + u4HwVer, u4PatchVer); + return MTK_WCN_BOOL_FALSE; + } + return MTK_WCN_BOOL_TRUE; +} + +static INT32 wmt_core_hw_check(VOID) +{ + UINT32 chipid; + P_WMT_IC_OPS p_ops; + INT32 iret; + + /* 1. get chip id */ + chipid = 0; + WMT_LOUD_FUNC("before read hwcode (chip id)\n"); + iret = wmt_core_reg_rw_raw(0, GEN_HCR, &chipid, GEN_HCR_MASK); /* read 0x80000008 */ + if (iret) { +#if defined(KERNEL_clk_buf_show_status_info) + KERNEL_clk_buf_show_status_info(); /* dump clock buffer */ +#endif + WMT_ERR_FUNC("get hwcode (chip id) fail (%d)\n", iret); + return -WMT_ERRCODE_HW_CHECK_FAIL; + } + if (wmt_detect_get_chip_type() == WMT_CHIP_TYPE_SOC) { + if (wmt_lib_get_icinfo(WMTCHIN_IPVER)) + chipid = wmt_plat_get_soc_chipid(); + } + WMT_INFO_FUNC("get hwcode (chip id) (0x%x)\n", chipid); + + /* TODO:[ChangeFeature][George]: use a better way to select a correct ops table based on chip id */ + switch (chipid) { +#if CFG_CORE_MT6620_SUPPORT + case 0x6620: + p_ops = &wmt_ic_ops_mt6620; + break; +#endif +#if CFG_CORE_MT6628_SUPPORT + case 0x6628: + p_ops = &wmt_ic_ops_mt6628; + break; +#endif + +#if CFG_CORE_MT6630_SUPPORT + case 0x6630: + p_ops = &wmt_ic_ops_mt6630; + break; +#endif + +#if CFG_CORE_MT6632_SUPPORT + case 0x6632: + p_ops = &wmt_ic_ops_mt6632; + break; +#endif +#if CFG_CORE_SOC_SUPPORT + case 0x0690: + case 0x6572: + case 0x6582: + case 0x6592: + case 0x8127: + case 0x6571: + case 0x6752: + case 0x0279: + case 0x0326: + case 0x0321: + case 0x0335: + case 0x0337: + case 0x8163: + case 0x6580: + case 0x0551: + case 0x8167: + case 0x0507: + case 0x0688: + case 0x0699: + case 0x0633: + case 0x0713: + case 0x0788: + case 0x6765: + case 0x6761: + case 0x6779: + case 0x6768: + case 0x6785: + case 0x6833: + case 0x6853: + case 0x6873: + case 0x8168: + p_ops = &wmt_ic_ops_soc; + break; +#endif + + default: + p_ops = (P_WMT_IC_OPS) NULL; +#if CFG_CORE_SOC_SUPPORT + if (chipid - 0x600 == 0x7f90) { + p_ops = &wmt_ic_ops_soc; + chipid -= 0xf6d; + } +#endif + break; + } + + if (p_ops == NULL) { + WMT_ERR_FUNC("unsupported chip id (hw_code): 0x%x\n", chipid); + return -WMT_ERRCODE_CHIPID_NOT_SUPPORT; + } else if (wmt_core_ic_ops_check(p_ops) == MTK_WCN_BOOL_FALSE) { + WMT_ERR_FUNC + ("chip id(0x%x) with null operation fp: init(0x%p), deinit(0x%p), pin_ctrl(0x%p), ver_chk(0x%p)\n", + chipid, p_ops->sw_init, p_ops->sw_deinit, p_ops->ic_pin_ctrl, + p_ops->ic_ver_check); + return -WMT_ERRCODE_NULL_FUNC_POINTER; + } + WMT_DBG_FUNC("chip id(0x%x) fp: init(0x%p), deinit(0x%p), pin_ctrl(0x%p), ver_chk(0x%p)\n", + chipid, p_ops->sw_init, p_ops->sw_deinit, p_ops->ic_pin_ctrl, + p_ops->ic_ver_check); + if (wmt_detect_get_chip_type() == WMT_CHIP_TYPE_SOC) { + wmt_ic_ops_soc.icId = chipid; + wmt_ic_ops_soc.options = mtk_wcn_consys_get_options(); + WMT_INFO_FUNC("options = %llx", wmt_ic_ops_soc.options); + } + iret = p_ops->ic_ver_check(); + if (iret) { + WMT_ERR_FUNC("chip id(0x%x) ver_check error:%d\n", chipid, iret); + return -WMT_ERRCODE_VER_CHECK_FAIL; + } + + WMT_DBG_FUNC("chip id(0x%x) ver_check ok\n", chipid); + gMtkWmtCtx.p_ic_ops = p_ops; + return 0; +} + +static INT32 opfunc_hif_conf(P_WMT_OP pWmtOp) +{ + if (!(pWmtOp->u4InfoBit & WMT_OP_HIF_BIT)) { + WMT_ERR_FUNC("WMT-CORE: no HIF_BIT in WMT_OP!\n"); + return -1; + } + + if (gMtkWmtCtx.wmtInfoBit & WMT_OP_HIF_BIT) { + WMT_ERR_FUNC("WMT-CORE: WMT HIF already exist. Just return\n"); + return 0; + } else { + gMtkWmtCtx.wmtInfoBit |= WMT_OP_HIF_BIT; + WMT_ERR_FUNC("WMT-CORE: WMT HIF info added\n"); + } + + osal_memcpy(&gMtkWmtCtx.wmtHifConf, + &pWmtOp->au4OpData[0], osal_sizeof(gMtkWmtCtx.wmtHifConf)); + return 0; + +} + +static INT32 opfunc_pwr_on(P_WMT_OP pWmtOp) +{ + INT32 iRet; + INT32 iErrHandle = 0; + ULONG ctrlPa1; + ULONG ctrlPa2; + + if (gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] != DRV_STS_POWER_OFF) { + WMT_ERR_FUNC("WMT-CORE: already powered on, WMT DRV_STS_[0x%x]\n", + gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]); + osal_assert(0); + return -WMT_ERRCODE_ALREADY_ON; + } + + /* power on control */ + ctrlPa1 = 0; + ctrlPa2 = 0; + iRet = wmt_core_ctrl(WMT_CTRL_HW_PWR_ON, &ctrlPa1, &ctrlPa2); + if (iRet) { + WMT_ERR_FUNC("WMT-CORE: WMT_CTRL_HW_PWR_ON fail iRet(%d)\n", iRet); + iErrHandle = opfunc_pwr_off(pWmtOp); + if (iErrHandle) + WMT_ERR_FUNC("opfunc_pwr_off fail\n"); + return (iErrHandle) ? iErrHandle : iRet; + } + gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_ON; + + /* init stp */ + iRet = wmt_core_stp_init(); + if (iRet) { + WMT_ERR_FUNC("WMT-CORE: wmt_core_stp_init fail (%d)\n", iRet); + osal_assert(0); + if (mtk_wcn_stp_get_wmt_trg_assert() == 0) { + iErrHandle = wmt_core_stp_deinit(); + if (iErrHandle) + WMT_ERR_FUNC("wmt_core_stp_deinit() failed, Err=%d\n", iErrHandle); + iErrHandle = opfunc_pwr_off(pWmtOp); + if (iErrHandle) + WMT_ERR_FUNC("opfunc_pwr_off fail, Err=%d\n", iErrHandle); + } + return (iErrHandle) ? iErrHandle : iRet; + } + + WMT_DBG_FUNC("WMT-CORE: WMT [FUNC_ON]\n"); + gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_FUNC_ON; + + /* update blank status when ConnSys power on */ + wmt_blank_status_ctrl(wmt_dev_get_blank_state()); + + mtk_wcn_consys_sleep_info_restore(); + + /* What to do when state is changed from POWER_OFF to POWER_ON? + * 1. STP driver does s/w reset + * 2. UART does 0xFF wake up + * 3. SDIO does re-init command(changed to trigger by host) + */ + return 0; +} + +static INT32 opfunc_pwr_off(P_WMT_OP pWmtOp) +{ + + INT32 iRet; + ULONG ctrlPa1; + ULONG ctrlPa2; + + if (gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] == DRV_STS_POWER_OFF) { + WMT_WARN_FUNC("WMT-CORE: WMT already off, WMT DRV_STS_[0x%x]\n", + gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]); + osal_assert(0); + return -WMT_ERRCODE_ALREADY_OFF; + } + if (g_pwr_off_flag == MTK_WCN_BOOL_FALSE) { + WMT_WARN_FUNC("CONNSYS power off be disabled, maybe need trigger core dump!\n"); + osal_assert(0); + return -WMT_ERRCODE_READYTO_OFF; + } + /* wmt and stp are initialized successfully */ + if (gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] == DRV_STS_FUNC_ON) { + iRet = wmt_core_stp_deinit(); + if (iRet) { + WMT_WARN_FUNC("wmt_core_stp_deinit fail (%d)\n", iRet); + /*should let run to power down chip */ + } + } + + if (wmt_lib_power_lock_aquire() == 0) { + gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_OFF; + wmt_lib_power_lock_release(); + } else { + gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_OFF; + WMT_INFO_FUNC("wmt_lib_power_lock_aquire failed\n"); + } + + /* power off control */ + ctrlPa1 = 0; + ctrlPa2 = 0; + iRet = wmt_core_ctrl(WMT_CTRL_HW_PWR_OFF, &ctrlPa1, &ctrlPa2); + if (iRet) + WMT_WARN_FUNC("HW_PWR_OFF fail (%d)\n", iRet); + else + WMT_DBG_FUNC("HW_PWR_OFF ok\n"); + + return iRet; + +} + +static INT32 opfunc_func_on(P_WMT_OP pWmtOp) +{ + INT32 iRet = -1; + UINT32 drvType = pWmtOp->au4OpData[0]; + + /* Check abnormal type */ + if (drvType >= WMTDRV_TYPE_MAX) { + WMT_ERR_FUNC("abnormal Fun(%d)\n", drvType); + osal_assert(0); + return -1; + } + + /* Check abnormal state */ + if ((gMtkWmtCtx.eDrvStatus[drvType] < DRV_STS_POWER_OFF) + || (gMtkWmtCtx.eDrvStatus[drvType] >= DRV_STS_MAX)) { + WMT_ERR_FUNC("func(%d) status[0x%x] abnormal\n", + drvType, gMtkWmtCtx.eDrvStatus[drvType]); + osal_assert(0); + return -2; + } + + if (WMTDRV_TYPE_GPSL5 == drvType) + mtk_wcn_stp_set_support_gpsl5(1); + + /* check if func already on */ + if (gMtkWmtCtx.eDrvStatus[drvType] == DRV_STS_FUNC_ON) { + WMT_WARN_FUNC("func(%d) already on\n", drvType); + return 0; + } + /*enable power off flag, if flag=0, power off connsys will not be executed */ + mtk_wcn_set_connsys_power_off_flag(MTK_WCN_BOOL_TRUE); + /* check if chip power on is needed */ + if (gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] != DRV_STS_FUNC_ON) { + iRet = opfunc_pwr_on(pWmtOp); + if (iRet) { + WMT_ERR_FUNC("func(%d) pwr_on fail(%d)\n", drvType, iRet); + osal_assert(0); + + /* check all sub-func and do power off */ + return -3; + } + } + + if (WMTDRV_TYPE_WMT > drvType || WMTDRV_TYPE_ANT == drvType || WMTDRV_TYPE_GPSL5 == drvType) { + if (gpWmtFuncOps[drvType] && gpWmtFuncOps[drvType]->func_on) { + + /* special handling for Wi-Fi */ + if (drvType == WMTDRV_TYPE_WIFI) { + P_OSAL_OP pOp = wmt_lib_get_current_op(&gDevWmt); + atomic_set(&g_wifi_on_off_ready, 1); + + pOp->op.opId = WMT_OPID_WLAN_PROBE; + if (wmt_lib_put_worker_op(pOp) == MTK_WCN_BOOL_FALSE) { + WMT_WARN_FUNC("put to activeWorker queue fail\n"); + atomic_set(&g_wifi_on_off_ready, 0); + return -4; + } + return 0; + } + + iRet = (*(gpWmtFuncOps[drvType]->func_on)) (gMtkWmtCtx.p_ic_ops, wmt_conf_get_cfg()); + if (iRet != 0) + gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_POWER_OFF; + else + gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_FUNC_ON; + } else { + WMT_WARN_FUNC("WMT-CORE: ops for type(%d) not found\n", drvType); + iRet = -5; + } + } else { + if (drvType == WMTDRV_TYPE_LPBK) + gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_FUNC_ON; + else if (drvType == WMTDRV_TYPE_COREDUMP) + gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_FUNC_ON; + iRet = 0; + } + + if (iRet) { + WMT_ERR_FUNC("WMT-CORE:type(0x%x) function on failed, ret(%d)\n", drvType, iRet); + opfunc_try_pwr_off(pWmtOp); + return iRet; + } + + /* send UTC time sync command after function on */ + opfunc_utc_time_sync(NULL); + wmt_core_dump_func_state("AF FUNC ON"); + + return 0; +} + +static INT32 opfunc_func_off(P_WMT_OP pWmtOp) +{ + INT32 iRet = -1; + UINT32 drvType = pWmtOp->au4OpData[0]; + + /* Check abnormal type */ + if (drvType >= WMTDRV_TYPE_MAX) { + WMT_ERR_FUNC("WMT-CORE: abnormal Fun(%d) in wmt_func_off\n", drvType); + osal_assert(0); + return -1; + } + + /* Check abnormal state */ + if (gMtkWmtCtx.eDrvStatus[drvType] >= DRV_STS_MAX) { + WMT_ERR_FUNC("WMT-CORE: Fun(%d) DRV_STS_[0x%x] abnormal in wmt_func_off\n", + drvType, gMtkWmtCtx.eDrvStatus[drvType]); + osal_assert(0); + return -2; + } + + if (gMtkWmtCtx.eDrvStatus[drvType] != DRV_STS_FUNC_ON) { + WMT_WARN_FUNC + ("WMT-CORE: Fun(%d) DRV_STS_[0x%x] already non-FUN_ON in wmt_func_off\n", + drvType, gMtkWmtCtx.eDrvStatus[drvType]); + /* needs to check 4 subsystem's state? */ + return 0; + } else if (WMTDRV_TYPE_WMT > drvType || WMTDRV_TYPE_ANT == drvType || WMTDRV_TYPE_GPSL5 == drvType) { + if (gpWmtFuncOps[drvType] && gpWmtFuncOps[drvType]->func_off) { + /* special handling for Wi-Fi */ + if (drvType == WMTDRV_TYPE_WIFI) { + P_OSAL_OP pOp = wmt_lib_get_current_op(&gDevWmt); + atomic_set(&g_wifi_on_off_ready, 1); + + pOp->op.opId = WMT_OPID_WLAN_REMOVE; + if (wmt_lib_put_worker_op(pOp) == MTK_WCN_BOOL_FALSE) { + WMT_WARN_FUNC("put to activeWorker queue fail\n"); + atomic_set(&g_wifi_on_off_ready, 0); + return -4; + } + return 0; + } + iRet = (*(gpWmtFuncOps[drvType]->func_off)) (gMtkWmtCtx.p_ic_ops, wmt_conf_get_cfg()); + } else { + WMT_WARN_FUNC("WMT-CORE: ops for type(%d) not found\n", drvType); + iRet = -3; + } + } else { + if (drvType == WMTDRV_TYPE_LPBK) + gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_POWER_OFF; + else if (drvType == WMTDRV_TYPE_COREDUMP) + gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_POWER_OFF; + iRet = 0; + } + + if (drvType != WMTDRV_TYPE_WMT) + gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_POWER_OFF; + + if (iRet) { + WMT_ERR_FUNC("WMT-CORE: type(0x%x) function off failed, ret(%d)\n", drvType, iRet); + osal_assert(0); + /* no matter subsystem function control fail or not, chip should be powered off + * when no subsystem is active + * return iRet; + */ + } + + /* check all sub-func and do power off */ + opfunc_try_pwr_off(pWmtOp); + wmt_core_dump_func_state("AF FUNC OFF"); + return iRet; +} + +static INT32 opfunc_gps_suspend_by_type(ENUM_WMTDRV_TYPE_T type, P_WMT_OP pWmtOp) +{ + INT32 iRet = -1; + P_WMT_GEN_CONF pWmtGenConf = NULL; + MTK_WCN_BOOL suspend = (pWmtOp->au4OpData[0] != 0); + UINT32 suspend_flag = WMT_GPS_SUSPEND; + + if (WMTDRV_TYPE_GPS != type && WMTDRV_TYPE_GPSL5 != type) + return 0; + + if (WMTDRV_TYPE_GPSL5 == type) + suspend_flag = WMT_GPSL5_SUSPEND; + + pWmtGenConf = wmt_conf_get_cfg(); + + if (gMtkWmtCtx.eDrvStatus[type] != DRV_STS_FUNC_ON) { + WMT_WARN_FUNC("WMT-CORE: GPS(%d) driver non-FUN_ON in opfunc_gps_suspend\n", type); + return 0; + } + + if (MTK_WCN_BOOL_TRUE == suspend) { + if (osal_test_bit(suspend_flag, &gGpsFmState)) { + WMT_WARN_FUNC("WMT-CORE: GPS(%d) already suspend\n", type); + return 0; + } + } else { + if (!osal_test_bit(suspend_flag, &gGpsFmState)) { + WMT_WARN_FUNC("WMT-CORE: GPS(%d) already resume on\n", type); + return 0; + } + } + + if (MTK_WCN_BOOL_TRUE == suspend) { + if (gpWmtFuncOps[type] && gpWmtFuncOps[type]->func_off) { + if (pWmtGenConf != NULL) + pWmtGenConf->wmt_gps_suspend_ctrl = 1; + iRet = (*(gpWmtFuncOps[type]->func_off)) (gMtkWmtCtx.p_ic_ops, wmt_conf_get_cfg()); + if (pWmtGenConf != NULL) + pWmtGenConf->wmt_gps_suspend_ctrl = 0; + } else { + WMT_WARN_FUNC("WMT-CORE: GPS(%d) suspend ops not found\n", type); + iRet = -3; + } + } else { + /*enable power off flag, if flag=0, power off connsys will not be executed */ + mtk_wcn_set_connsys_power_off_flag(MTK_WCN_BOOL_TRUE); + /* check if chip power on is needed */ + if (gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] != DRV_STS_FUNC_ON) { + iRet = opfunc_pwr_on(pWmtOp); + if (iRet) { + WMT_ERR_FUNC("WMT-CORE: func(%d) hw resume fail(%d)\n", type, iRet); + osal_assert(0); + + /* check all sub-func and do power off */ + return -5; + } + } + + if (gpWmtFuncOps[type] && gpWmtFuncOps[type]->func_on) { + if (pWmtGenConf != NULL) + pWmtGenConf->wmt_gps_suspend_ctrl = 1; + iRet = (*(gpWmtFuncOps[type]->func_on)) (gMtkWmtCtx.p_ic_ops, wmt_conf_get_cfg()); + if (pWmtGenConf != NULL) + pWmtGenConf->wmt_gps_suspend_ctrl = 0; + } else { + WMT_WARN_FUNC("WMT-CORE: GPS(%d) resume ops not found\n", type); + iRet = -7; + } + } + + if (iRet) { + WMT_ERR_FUNC("WMT-CORE: gps(%d) %s function failed, ret(%d)\n", + type, ((pWmtOp->au4OpData[0] != 0) ? "suspend" : "resume"), iRet); + osal_assert(0); + } + + if (MTK_WCN_BOOL_FALSE == suspend) + opfunc_utc_time_sync(NULL); + + return iRet; +} + +static INT32 opfunc_gps_suspend(P_WMT_OP pWmtOp) +{ + if (pWmtOp->au4OpData[1] == 1) + opfunc_gps_suspend_by_type(WMTDRV_TYPE_GPS, pWmtOp); + + if (pWmtOp->au4OpData[2] == 1) + opfunc_gps_suspend_by_type(WMTDRV_TYPE_GPSL5, pWmtOp); + + return 0; +} + +/* TODO:[ChangeFeature][George] is this OP obsoleted? */ +static INT32 opfunc_reg_rw(P_WMT_OP pWmtOp) +{ + INT32 iret; + + if (gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] != DRV_STS_FUNC_ON) { + WMT_ERR_FUNC("reg_rw when WMT is powered off\n"); + return -1; + } + iret = wmt_core_reg_rw_raw(pWmtOp->au4OpData[0], + pWmtOp->au4OpData[1], + (PUINT32) pWmtOp->au4OpData[2], pWmtOp->au4OpData[3]); + + return iret; +} + +static INT32 opfunc_exit(P_WMT_OP pWmtOp) +{ + /* TODO: [FixMe][George] is ok to leave this function empty??? */ + WMT_WARN_FUNC("EMPTY FUNCTION\n"); + return 0; +} + +static INT32 opfunc_pwr_sv(P_WMT_OP pWmtOp) +{ + INT32 ret = -1; + UINT32 u4_result = 0; + UINT32 evt_len; + UINT8 evt_buf[16] = { 0 }; + ULONG ctrlPa1 = 0; + ULONG ctrlPa2 = 0; + + typedef INT32(*STP_PSM_CB) (const MTKSTP_PSM_ACTION_T); + STP_PSM_CB psm_cb = NULL; + + if (pWmtOp->au4OpData[0] == SLEEP) { + WMT_DBG_FUNC("**** Send sleep command\n"); + /* mtk_wcn_stp_set_psm_state(ACT_INACT); */ + /* (*kal_stp_flush_rx)(WMT_TASK_INDX); */ + ret = + wmt_core_tx((const PUINT8)(&WMT_SLEEP_CMD[0]), sizeof(WMT_SLEEP_CMD), + &u4_result, 0); + if (ret || (u4_result != sizeof(WMT_SLEEP_CMD))) { + WMT_ERR_FUNC("wmt_core: SLEEP_CMD ret(%d) cmd len err(%d, %zu) ", ret, + u4_result, sizeof(WMT_SLEEP_CMD)); + goto pwr_sv_done; + } + + evt_len = sizeof(WMT_SLEEP_EVT); + ret = wmt_core_rx(evt_buf, evt_len, &u4_result); + if (ret || (u4_result != evt_len)) { + wmt_core_rx_flush(WMT_TASK_INDX); + WMT_ERR_FUNC + ("wmt_core: read SLEEP_EVT fail(%d) len(%d, %d), host trigger firmware assert\n", + ret, u4_result, evt_len); + + wmt_lib_trigger_assert(WMTDRV_TYPE_WMT, 33); + goto pwr_sv_done; + } + + if (osal_memcmp(evt_buf, (const PVOID)WMT_SLEEP_EVT, sizeof(WMT_SLEEP_EVT)) != 0) { + WMT_ERR_FUNC("wmt_core: compare WMT_SLEEP_EVT error\n"); + wmt_core_rx_flush(WMT_TASK_INDX); + WMT_ERR_FUNC("rx(%d):[%2X,%2X,%2X,%2X,%2X,%2X] exp(%zu):[%2X,%2X,%2X,%2X,%2X,%2X]\n", + u4_result, evt_buf[0], evt_buf[1], evt_buf[2], evt_buf[3], evt_buf[4], + evt_buf[5], sizeof(WMT_SLEEP_EVT), WMT_SLEEP_EVT[0], WMT_SLEEP_EVT[1], + WMT_SLEEP_EVT[2], WMT_SLEEP_EVT[3], WMT_SLEEP_EVT[4], + WMT_SLEEP_EVT[5]); + mtk_wcn_stp_dbg_dump_package(); + goto pwr_sv_done; + } + WMT_DBG_FUNC("Send sleep command OK!\n"); + } else if (pWmtOp->au4OpData[0] == WAKEUP) { + if (mtk_wcn_stp_is_btif_fullset_mode()) { + WMT_DBG_FUNC("wakeup connsys by btif"); + ret = wmt_core_ctrl(WMT_CTRL_SOC_WAKEUP_CONSYS, &ctrlPa1, &ctrlPa2); + if (ret) { + WMT_ERR_FUNC("wmt-core:WAKEUP_CONSYS by BTIF fail(%d)", ret); + goto pwr_sv_done; + } + } else if (mtk_wcn_stp_is_sdio_mode()) { + WMT_DBG_FUNC("**** Send wakeup command\n"); + ret = + wmt_core_tx((const PUINT8)WMT_WAKEUP_CMD, sizeof(WMT_WAKEUP_CMD), &u4_result, 1); + if (ret || (u4_result != sizeof(WMT_WAKEUP_CMD))) { + wmt_core_rx_flush(WMT_TASK_INDX); + WMT_ERR_FUNC("wmt_core: WAKEUP_CMD ret(%d) cmd len err(%d, %zu)\n", + ret, u4_result, sizeof(WMT_WAKEUP_CMD)); + goto pwr_sv_done; + } + } + evt_len = sizeof(WMT_WAKEUP_EVT); + ret = wmt_core_rx(evt_buf, evt_len, &u4_result); + if (ret || (u4_result != evt_len)) { + WMT_ERR_FUNC + ("wmt_core: read WAKEUP_EVT fail(%d) len(%d, %d), host grigger firmaware assert\n", + ret, u4_result, evt_len); + + wmt_lib_trigger_assert(WMTDRV_TYPE_WMT, 34); + goto pwr_sv_done; + } + + if (osal_memcmp(evt_buf, (const PVOID)WMT_WAKEUP_EVT, sizeof(WMT_WAKEUP_EVT)) != 0) { + WMT_ERR_FUNC("wmt_core: compare WMT_WAKEUP_EVT error\n"); + wmt_core_rx_flush(WMT_TASK_INDX); + WMT_ERR_FUNC("rx(%d):[%2X,%2X,%2X,%2X,%2X,%2X] exp(%zu):[%2X,%2X,%2X,%2X,%2X,%2X]\n", + u4_result, evt_buf[0], evt_buf[1], evt_buf[2], evt_buf[3], evt_buf[4], + evt_buf[5], sizeof(WMT_WAKEUP_EVT), WMT_WAKEUP_EVT[0], + WMT_WAKEUP_EVT[1], WMT_WAKEUP_EVT[2], WMT_WAKEUP_EVT[3], + WMT_WAKEUP_EVT[4], WMT_WAKEUP_EVT[5]); + mtk_wcn_stp_dbg_dump_package(); + goto pwr_sv_done; + } + WMT_DBG_FUNC("Send wakeup command OK!\n"); + } else if (pWmtOp->au4OpData[0] == HOST_AWAKE) { + + WMT_DBG_FUNC("**** Send host awake command\n"); + + psm_cb = (STP_PSM_CB) pWmtOp->au4OpData[1]; + /* (*kal_stp_flush_rx)(WMT_TASK_INDX); */ + ret = + wmt_core_tx((const PUINT8)WMT_HOST_AWAKE_CMD, sizeof(WMT_HOST_AWAKE_CMD), + &u4_result, 0); + if (ret || (u4_result != sizeof(WMT_HOST_AWAKE_CMD))) { + WMT_ERR_FUNC("wmt_core: HOST_AWAKE_CMD ret(%d) cmd len err(%d, %zu) ", ret, + u4_result, sizeof(WMT_HOST_AWAKE_CMD)); + goto pwr_sv_done; + } + + evt_len = sizeof(WMT_HOST_AWAKE_EVT); + ret = wmt_core_rx(evt_buf, evt_len, &u4_result); + if (ret || (u4_result != evt_len)) { + wmt_core_rx_flush(WMT_TASK_INDX); + WMT_ERR_FUNC + ("wmt_core:read HOST_AWAKE_EVT fail(%d) len(%d, %d), host trigger f/w assert\n", + ret, u4_result, evt_len); + + wmt_lib_trigger_assert(WMTDRV_TYPE_WMT, 35); + goto pwr_sv_done; + } + + if (osal_memcmp + (evt_buf, (const PVOID)WMT_HOST_AWAKE_EVT, sizeof(WMT_HOST_AWAKE_EVT)) != 0) { + WMT_ERR_FUNC("wmt_core: compare WMT_HOST_AWAKE_EVT error\n"); + wmt_core_rx_flush(WMT_TASK_INDX); + WMT_ERR_FUNC("rx(%d):[%2X,%2X,%2X,%2X,%2X,%2X] exp(%zu):[%2X,%2X,%2X,%2X,%2X,%2X]\n", + u4_result, evt_buf[0], evt_buf[1], evt_buf[2], evt_buf[3], evt_buf[4], + evt_buf[5], sizeof(WMT_HOST_AWAKE_EVT), WMT_HOST_AWAKE_EVT[0], + WMT_HOST_AWAKE_EVT[1], WMT_HOST_AWAKE_EVT[2], WMT_HOST_AWAKE_EVT[3], + WMT_HOST_AWAKE_EVT[4], WMT_HOST_AWAKE_EVT[5]); + mtk_wcn_stp_dbg_dump_package(); + /* goto pwr_sv_done; */ + } else { + WMT_DBG_FUNC("Send host awake command OK!\n"); + } + } +pwr_sv_done: + + if (pWmtOp->au4OpData[0] < STP_PSM_MAX_ACTION) { + psm_cb = (STP_PSM_CB) pWmtOp->au4OpData[1]; + WMT_DBG_FUNC("Do STP-CB! %zu %p\n", pWmtOp->au4OpData[0], + (PVOID) pWmtOp->au4OpData[1]); + if (psm_cb != NULL) { + psm_cb(pWmtOp->au4OpData[0]); + } else { + WMT_ERR_FUNC + ("fatal error !!!, psm_cb = %p, god, someone must have corrupted our memory.\n", + psm_cb); + } + } + + return ret; +} + +static INT32 opfunc_dsns(P_WMT_OP pWmtOp) +{ + + INT32 iRet = -1; + UINT32 u4Res; + UINT32 evtLen; + UINT8 evtBuf[16] = { 0 }; + + WMT_DSNS_CMD[4] = pWmtOp->au4OpData[0]; + WMT_DSNS_CMD[5] = pWmtOp->au4OpData[1]; + + /* send command */ + /* iRet = (*kal_stp_tx)(WMT_DSNS_CMD, osal_sizeof(WMT_DSNS_CMD), &u4Res); */ + iRet = + wmt_core_tx((PUINT8) WMT_DSNS_CMD, osal_sizeof(WMT_DSNS_CMD), &u4Res, + MTK_WCN_BOOL_FALSE); + if (iRet || (u4Res != osal_sizeof(WMT_DSNS_CMD))) { + WMT_ERR_FUNC("WMT-CORE: DSNS_CMD iRet(%d) cmd len err(%d, %zu)\n", iRet, u4Res, + osal_sizeof(WMT_DSNS_CMD)); + return iRet; + } + + evtLen = osal_sizeof(WMT_DSNS_EVT); + + iRet = wmt_core_rx(evtBuf, evtLen, &u4Res); + if (iRet || (u4Res != evtLen)) { + WMT_ERR_FUNC("WMT-CORE: read DSNS_EVT fail(%d) len(%d, %d)\n", iRet, u4Res, evtLen); + mtk_wcn_stp_dbg_dump_package(); + return iRet; + } + + if (osal_memcmp(evtBuf, WMT_DSNS_EVT, osal_sizeof(WMT_DSNS_EVT)) != 0) { + WMT_ERR_FUNC("WMT-CORE: compare WMT_DSNS_EVT error\n"); + WMT_ERR_FUNC + ("WMT-CORE: rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%zu):[%02X,%02X,%02X,%02X,%02X]\n", + u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], + osal_sizeof(WMT_DSNS_EVT), WMT_DSNS_EVT[0], WMT_DSNS_EVT[1], WMT_DSNS_EVT[2], + WMT_DSNS_EVT[3], WMT_DSNS_EVT[4]); + } else { + WMT_INFO_FUNC("Send WMT_DSNS_CMD command OK!\n"); + } + + return iRet; +} + +#if CFG_CORE_INTERNAL_TXRX +INT32 wmt_core_lpbk_do_stp_init(void) +{ + INT32 iRet = 0; + ULONG ctrlPa1 = 0; + ULONG ctrlPa2 = 0; + + ctrlPa1 = 0; + ctrlPa2 = 0; + iRet = wmt_core_ctrl(WMT_CTRL_STP_OPEN, &ctrlPa1, &ctrlPa2); + if (iRet) { + WMT_ERR_FUNC("WMT-CORE: wmt open stp\n"); + return -1; + } + + ctrlPa1 = WMT_STP_CONF_MODE; + ctrlPa2 = MTKSTP_BTIF_MAND_MODE; + iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); + + ctrlPa1 = WMT_STP_CONF_EN; + ctrlPa2 = 1; + iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); + if (iRet) { + WMT_ERR_FUNC("WMT-CORE: stp_init <1><2> fail:%d\n", iRet); + return -2; + } +} + +INT32 wmt_core_lpbk_do_stp_deinit(void) +{ + INT32 iRet = 0; + ULONG ctrlPa1 = 0; + ULONG ctrlPa2 = 0; + + ctrlPa1 = 0; + ctrlPa2 = 0; + iRet = wmt_core_ctrl(WMT_CTRL_STP_CLOSE, &ctrlPa1, &ctrlPa2); + if (iRet) { + WMT_ERR_FUNC("WMT-CORE: wmt open stp\n"); + return -1; + } + + return 0; +} +#endif + + +static INT32 opfunc_lpbk(P_WMT_OP pWmtOp) +{ + + INT32 iRet; + UINT32 u4WrittenSize = 0; + UINT32 u4ReadSize = 0; + UINT32 buf_length = 0; + PUINT32 pbuffer = NULL; + UINT16 len_in_cmd; + /* UINT32 offset; */ + UINT8 WMT_TEST_LPBK_CMD[] = { 0x1, 0x2, 0x0, 0x0, 0x7 }; + UINT8 WMT_TEST_LPBK_EVT[] = { 0x2, 0x2, 0x0, 0x0, 0x0 }; + /* UINT8 lpbk_buf[1024 + 5] = {0}; */ + MTK_WCN_BOOL fgFail; + + buf_length = pWmtOp->au4OpData[0]; /* packet length */ + pbuffer = (PUINT32) pWmtOp->au4OpData[1]; /* packet buffer pointer */ + WMT_DBG_FUNC("WMT-CORE: -->wmt_do_lpbk\n"); + /*check if WMTDRV_TYPE_LPBK function is already on */ + if (gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_LPBK] != DRV_STS_FUNC_ON + || buf_length + osal_sizeof(WMT_TEST_LPBK_CMD) > osal_sizeof(gLpbkBuf)) { + WMT_ERR_FUNC("WMT-CORE: abnormal LPBK in wmt_do_lpbk\n"); + osal_assert(0); + return -2; + } + /*package loopback for STP */ + + /* init buffer */ + osal_memset(gLpbkBuf, 0, osal_sizeof(gLpbkBuf)); + + len_in_cmd = buf_length + 1; /* add flag field */ + + osal_memcpy(&WMT_TEST_LPBK_CMD[2], &len_in_cmd, 2); + osal_memcpy(&WMT_TEST_LPBK_EVT[2], &len_in_cmd, 2); + + /* wmt cmd */ + osal_memcpy(gLpbkBuf, WMT_TEST_LPBK_CMD, osal_sizeof(WMT_TEST_LPBK_CMD)); + osal_memcpy(gLpbkBuf + osal_sizeof(WMT_TEST_LPBK_CMD), pbuffer, buf_length); + + do { + fgFail = MTK_WCN_BOOL_TRUE; + /*send packet through STP */ + /* iRet = (*kal_stp_tx)((PUINT8)gLpbkBuf, osal_sizeof(WMT_TEST_LPBK_CMD) + + * buf_length, &u4WrittenSize); + */ + iRet = + wmt_core_tx((PUINT8) gLpbkBuf, (osal_sizeof(WMT_TEST_LPBK_CMD) + buf_length), + &u4WrittenSize, MTK_WCN_BOOL_FALSE); + if (iRet) { + WMT_ERR_FUNC("opfunc_lpbk wmt_core_tx failed\n"); + break; + } + /*receive firmware response from STP */ + iRet = + wmt_core_rx((PUINT8) gLpbkBuf, (osal_sizeof(WMT_TEST_LPBK_EVT) + buf_length), + &u4ReadSize); + if (iRet) { + WMT_ERR_FUNC("opfunc_lpbk wmt_core_rx failed\n"); + break; + } + /*check if loopback response ok or not */ + if (u4ReadSize != (osal_sizeof(WMT_TEST_LPBK_CMD) + buf_length)) { + WMT_ERR_FUNC("lpbk event read size wrong(%d, %zu)\n", u4ReadSize, + (osal_sizeof(WMT_TEST_LPBK_CMD) + buf_length)); + break; + } + if (osal_memcmp(WMT_TEST_LPBK_EVT, gLpbkBuf, osal_sizeof(WMT_TEST_LPBK_EVT))) { + WMT_ERR_FUNC + ("WMT-CORE WMT_TEST_LPBK_EVT error! read len %d [%02x,%02x,%02x,%02x,%02x]\n", + (INT32) u4ReadSize, gLpbkBuf[0], gLpbkBuf[1], gLpbkBuf[2], gLpbkBuf[3], + gLpbkBuf[4] + ); + break; + } + pWmtOp->au4OpData[0] = u4ReadSize - osal_sizeof(WMT_TEST_LPBK_EVT); + osal_memcpy((PVOID) pWmtOp->au4OpData[1], + gLpbkBuf + osal_sizeof(WMT_TEST_LPBK_CMD), buf_length); + fgFail = MTK_WCN_BOOL_FALSE; + } while (0); + /*return result */ + /* WMT_DBG_FUNC("WMT-CORE: <--wmt_do_lpbk, fgFail = %d\n", fgFail); */ + if (fgFail == MTK_WCN_BOOL_TRUE) { + WMT_ERR_FUNC("LPBK fail and trigger assert\n"); + wmt_lib_trigger_assert(WMTDRV_TYPE_WMT, 37); + } + return fgFail; + +} + +static INT32 opfunc_cmd_test(P_WMT_OP pWmtOp) +{ + + INT32 iRet = 0; + UINT32 cmdNo = 0; + UINT32 cmdNoPa = 0; + + UINT8 tstCmd[64]; + UINT8 tstEvt[64]; + UINT8 tstEvtTmp[64]; + UINT32 u4Res; + UINT32 tstCmdSz = 0; + UINT32 tstEvtSz = 0; + + PUINT8 pRes = NULL; + UINT32 resBufRoom = 0; + /*test command list */ + /*1 */ + UINT8 WMT_ASSERT_CMD[] = { 0x01, 0x02, 0x01, 0x00, 0x08 }; + UINT8 WMT_ASSERT_EVT[] = { 0x02, 0x02, 0x00, 0x00, 0x00 }; + UINT8 WMT_NOACK_CMD[] = { 0x01, 0x02, 0x01, 0x00, 0x0A }; + UINT8 WMT_NOACK_EVT[] = { 0x02, 0x02, 0x00, 0x00, 0x00 }; + UINT8 WMT_WARNRST_CMD[] = { 0x01, 0x02, 0x01, 0x00, 0x0B }; + UINT8 WMT_WARNRST_EVT[] = { 0x02, 0x02, 0x00, 0x00, 0x00 }; + UINT8 WMT_FWLOGTST_CMD[] = { 0x01, 0x02, 0x01, 0x00, 0x0C }; + UINT8 WMT_FWLOGTST_EVT[] = { 0x02, 0x02, 0x00, 0x00, 0x00 }; + + UINT8 WMT_EXCEPTION_CMD[] = { 0x01, 0x02, 0x01, 0x00, 0x09 }; + UINT8 WMT_EXCEPTION_EVT[] = { 0x02, 0x02, 0x00, 0x00, 0x00 }; + /*2 */ + UINT8 WMT_COEXDBG_CMD[] = { 0x01, 0x10, 0x02, 0x00, + 0x08, + 0xAA /*Debugging Parameter */ + }; + UINT8 WMT_COEXDBG_1_EVT[] = { 0x02, 0x10, 0x05, 0x00, + 0x00, + 0xAA, 0xAA, 0xAA, 0xAA /*event content */ + }; + UINT8 WMT_COEXDBG_2_EVT[] = { 0x02, 0x10, 0x07, 0x00, + 0x00, + 0xAA, 0xAA, 0xAA, 0xAA, 0xBB, 0xBB /*event content */ + }; + UINT8 WMT_COEXDBG_3_EVT[] = { 0x02, 0x10, 0x0B, 0x00, + 0x00, + 0xAA, 0xAA, 0xAA, 0xAA, 0xBB, 0xBB, 0xBB, 0xBB /*event content */ + }; + /*test command list -end */ + + cmdNo = pWmtOp->au4OpData[0]; + + WMT_INFO_FUNC("Send Test command %d!\n", cmdNo); + if (cmdNo == 0) { + /*dead command */ + WMT_INFO_FUNC("Send Assert command !\n"); + tstCmdSz = osal_sizeof(WMT_ASSERT_CMD); + tstEvtSz = osal_sizeof(WMT_ASSERT_EVT); + osal_memcpy(tstCmd, WMT_ASSERT_CMD, tstCmdSz); + osal_memcpy(tstEvt, WMT_ASSERT_EVT, tstEvtSz); + } else if (cmdNo == 1) { + /*dead command */ + WMT_INFO_FUNC("Send Exception command !\n"); + tstCmdSz = osal_sizeof(WMT_EXCEPTION_CMD); + tstEvtSz = osal_sizeof(WMT_EXCEPTION_EVT); + osal_memcpy(tstCmd, WMT_EXCEPTION_CMD, tstCmdSz); + osal_memcpy(tstEvt, WMT_EXCEPTION_EVT, tstEvtSz); + } else if (cmdNo == 2) { + cmdNoPa = pWmtOp->au4OpData[1]; + pRes = (PUINT8) pWmtOp->au4OpData[2]; + resBufRoom = pWmtOp->au4OpData[3]; + if (cmdNoPa <= 0xf) { + WMT_INFO_FUNC("Send Coexistence Debug command [0x%x]!\n", cmdNoPa); + tstCmdSz = osal_sizeof(WMT_COEXDBG_CMD); + osal_memcpy(tstCmd, WMT_COEXDBG_CMD, tstCmdSz); + if (tstCmdSz > 5) + tstCmd[5] = cmdNoPa; + + /*setup the expected event length */ + if (cmdNoPa <= 0x4) { + tstEvtSz = osal_sizeof(WMT_COEXDBG_1_EVT); + osal_memcpy(tstEvt, WMT_COEXDBG_1_EVT, tstEvtSz); + } else if (cmdNoPa == 0x5) { + tstEvtSz = osal_sizeof(WMT_COEXDBG_2_EVT); + osal_memcpy(tstEvt, WMT_COEXDBG_2_EVT, tstEvtSz); + } else if (cmdNoPa >= 0x6 && cmdNoPa <= 0xf) { + tstEvtSz = osal_sizeof(WMT_COEXDBG_3_EVT); + osal_memcpy(tstEvt, WMT_COEXDBG_3_EVT, tstEvtSz); + } else { + + } + } else { + WMT_ERR_FUNC("cmdNoPa is wrong\n"); + return iRet; + } + } else if (cmdNo == 3) { + /*dead command */ + WMT_INFO_FUNC("Send No Ack command !\n"); + tstCmdSz = osal_sizeof(WMT_NOACK_CMD); + tstEvtSz = osal_sizeof(WMT_NOACK_EVT); + osal_memcpy(tstCmd, WMT_NOACK_CMD, tstCmdSz); + osal_memcpy(tstEvt, WMT_NOACK_EVT, tstEvtSz); + } else if (cmdNo == 4) { + /*dead command */ + WMT_INFO_FUNC("Send Warm reset command !\n"); + tstCmdSz = osal_sizeof(WMT_WARNRST_CMD); + tstEvtSz = osal_sizeof(WMT_WARNRST_EVT); + osal_memcpy(tstCmd, WMT_WARNRST_CMD, tstCmdSz); + osal_memcpy(tstEvt, WMT_WARNRST_EVT, tstEvtSz); + } else if (cmdNo == 5) { + /*dead command */ + WMT_INFO_FUNC("Send f/w log test command !\n"); + tstCmdSz = osal_sizeof(WMT_FWLOGTST_CMD); + tstEvtSz = osal_sizeof(WMT_FWLOGTST_EVT); + osal_memcpy(tstCmd, WMT_FWLOGTST_CMD, tstCmdSz); + osal_memcpy(tstEvt, WMT_FWLOGTST_EVT, tstEvtSz); + } + + /* send command */ + /* iRet = (*kal_stp_tx)(tstCmd, tstCmdSz, &u4Res); */ + iRet = wmt_core_tx((PUINT8) tstCmd, tstCmdSz, &u4Res, MTK_WCN_BOOL_FALSE); + if (iRet || (u4Res != tstCmdSz)) { + WMT_ERR_FUNC("WMT-CORE: wmt_cmd_test iRet(%d) cmd len err(%d, %d)\n", iRet, u4Res, + tstCmdSz); + return -1; + } + + if ((cmdNo == 0) || (cmdNo == 1) || cmdNo == 3) { + WMT_INFO_FUNC("WMT-CORE: not to rx event for assert command\n"); + return 0; + } + + iRet = wmt_core_rx(tstEvtTmp, tstEvtSz, &u4Res); + + /*Event Post Handling */ + if (cmdNo == 2) { + WMT_INFO_FUNC("#=========================================================#\n"); + WMT_INFO_FUNC("coext debugging id = %d", cmdNoPa); + if (tstEvtSz > 5) + wmt_core_dump_data(&tstEvtTmp[5], "coex debugging ", tstEvtSz - 5); + else + WMT_ERR_FUNC("error coex debugging event\n"); + /*put response to buffer for shell to read */ + if (pRes != NULL && resBufRoom > 0) { + pWmtOp->au4OpData[3] = + resBufRoom < tstEvtSz - 5 ? resBufRoom : tstEvtSz - 5; + osal_memcpy(pRes, &tstEvtTmp[5], pWmtOp->au4OpData[3]); + } else + pWmtOp->au4OpData[3] = 0; + WMT_INFO_FUNC("#=========================================================#\n"); + } + + return iRet; + +} + +static INT32 opfunc_hw_rst(P_WMT_OP pWmtOp) +{ + + INT32 iRet = -1; + ULONG ctrlPa1 = 0; + ULONG ctrlPa2 = 0; + + wmt_core_dump_func_state("BE HW RST"); + /*-->Reset WMT data structure*/ + gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_STP] = DRV_STS_POWER_OFF; + gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_ANT] = DRV_STS_POWER_OFF; + gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_COREDUMP] = DRV_STS_POWER_OFF; + /*enable power off flag, if flag=0, power off connsys will not be executed */ + mtk_wcn_set_connsys_power_off_flag(MTK_WCN_BOOL_TRUE); + + /* if wmt is poweroff, we need poweron chip first */ + if (gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] == DRV_STS_POWER_OFF) { + WMT_WARN_FUNC("WMT-CORE: WMT is off, need re-poweron\n"); + /* power on control */ + ctrlPa1 = 0; + ctrlPa2 = 0; + iRet = wmt_core_ctrl(WMT_CTRL_HW_PWR_ON, &ctrlPa1, &ctrlPa2); + if (iRet) { + WMT_ERR_FUNC("WMT-CORE: WMT_CTRL_HW_PWR_ON fail iRet(%d)\n", iRet); + return -1; + } + gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_ON; + } + + if (gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT] == DRV_STS_FUNC_ON) { + if (mtk_wcn_stp_is_btif_fullset_mode()) { + ctrlPa1 = BT_PALDO; + ctrlPa2 = PALDO_OFF; + iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); + if (iRet) + WMT_ERR_FUNC("WMT-CORE: wmt_ctrl_soc_paldo_ctrl failed(%d)(%lu)(%lu)\n", + iRet, ctrlPa1, ctrlPa2); + } + gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT] = DRV_STS_POWER_OFF; + } + + if (gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_GPS] == DRV_STS_FUNC_ON || + gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_GPSL5] == DRV_STS_FUNC_ON || + gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_FM] == DRV_STS_FUNC_ON) { + if (mtk_wcn_stp_is_btif_fullset_mode()) { + ctrlPa1 = GPS_PALDO; + ctrlPa2 = PALDO_OFF; + iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); + if (iRet) + WMT_ERR_FUNC("WMT-CORE: wmt_ctrl_soc_paldo_ctrl failed(%d)(%lu)(%lu)\n", + iRet, ctrlPa1, ctrlPa2); + } + gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_FM] = DRV_STS_POWER_OFF; + gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_GPS] = DRV_STS_POWER_OFF; + gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_GPSL5] = DRV_STS_POWER_OFF; + } + + iRet = wmt_lib_wlan_lock_aquire(); + if (iRet) { + WMT_ERR_FUNC("--->lock wlan_lock failed, iRet=%d\n", iRet); + return iRet; + } + + /*--> reset SDIO function/slot additionally if wifi ON*/ + if (gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI] == DRV_STS_FUNC_ON) { + if (mtk_wcn_stp_is_sdio_mode()) { + ctrlPa1 = WMT_SDIO_FUNC_WIFI; + ctrlPa2 = 0; /* turn off Wi-Fi driver */ + iRet = wmt_core_ctrl(WMT_CTRL_SDIO_FUNC, &ctrlPa1, &ctrlPa2); + if (iRet) { + WMT_ERR_FUNC("WMT-CORE: turn off SDIO_WIFI func fail (%d)\n", iRet); + /* check all sub-func and do power off */ + } else + WMT_INFO_FUNC("wmt core: turn off SDIO WIFI func ok!!\n"); + /* Anyway, turn off Wi-Fi Function */ + } else if (mtk_wcn_stp_is_btif_fullset_mode()) { + if (gpWmtFuncOps[WMTDRV_TYPE_WIFI] != NULL && + gpWmtFuncOps[WMTDRV_TYPE_WIFI]->func_off != NULL) { + iRet = gpWmtFuncOps[WMTDRV_TYPE_WIFI]->func_off(gMtkWmtCtx.p_ic_ops, + wmt_conf_get_cfg()); + if (iRet) { + WMT_ERR_FUNC("WMT-CORE: turn off WIFI func fail (%d)\n", iRet); + + /* check all sub-func and do power off */ + } else { + WMT_INFO_FUNC("wmt core: turn off WIFI func ok!!\n"); + } + } + } + /* Anyway, turn off Wi-Fi Function */ + gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI] = DRV_STS_POWER_OFF; + + if (gMtkWmtCtx.wmtHifConf.hifType == WMT_HIF_UART) { + ctrlPa1 = WMT_SDIO_SLOT_SDIO1; + ctrlPa2 = 0; /* turn off SDIO1 slot */ + iRet = wmt_core_ctrl(WMT_CTRL_SDIO_HW, &ctrlPa1, &ctrlPa2); + if (iRet) { + WMT_ERR_FUNC("WMT-CORE: turn off SLOT_SDIO1 fail (%d)\n", iRet); + osal_assert(0); + + /* check all sub-func and do power off */ + } else + WMT_INFO_FUNC("WMT-CORE: turn off SLOT_SDIO1 successfully (%d)\n", iRet); + gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_SDIO1] = DRV_STS_POWER_OFF; + } + gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI] = DRV_STS_POWER_OFF; + } + wmt_lib_wlan_lock_release(); + + mtk_wcn_wmt_system_state_reset(); + + if (gMtkWmtCtx.wmtHifConf.hifType == WMT_HIF_SDIO) { + ctrlPa1 = WMT_SDIO_FUNC_STP; + ctrlPa2 = 0; /* turn off STP driver */ + iRet = wmt_core_ctrl(WMT_CTRL_SDIO_FUNC, &ctrlPa1, &ctrlPa2); + if (iRet) { + WMT_ERR_FUNC("WMT-CORE: turn off SDIO_FUNC_STP func fail (%d)\n", iRet); + + /* check all sub-func and do power off */ + /* goto stp_deinit_done; */ + } else + WMT_INFO_FUNC("WMT-CORE: turn off SDIO_FUNC_STP func successfully (%d)\n", iRet); + + ctrlPa1 = WMT_SDIO_SLOT_SDIO2; + ctrlPa2 = 0; /* turn off SDIO2 slot */ + iRet = wmt_core_ctrl(WMT_CTRL_SDIO_HW, &ctrlPa1, &ctrlPa2); + if (iRet) { + WMT_ERR_FUNC("WMT-CORE: turn off SLOT_SDIO2 fail (%d)\n", iRet); + osal_assert(0); + + /* check all sub-func and do power off */ + /* goto stp_deinit_done; */ + } else + WMT_INFO_FUNC("WMT-CORE: turn off SLOT_SDIO2 successfully (%d)\n", iRet); + gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_SDIO2] = DRV_STS_POWER_OFF; + } +#if 0 + /*<4>Power off Combo chip */ + ctrlPa1 = 0; + ctrlPa2 = 0; + iRet = wmt_core_ctrl(WMT_CTRL_HW_RST, &ctrlPa1, &ctrlPa2); + if (iRet) + WMT_ERR_FUNC("WMT-CORE: [HW RST] WMT_CTRL_POWER_OFF fail (%d)", iRet); + else + WMT_INFO_FUNC("WMT-CORE: [HW RST] WMT_CTRL_POWER_OFF ok (%d)", iRet); +#endif + gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_OFF; + + /*-->PesetCombo chip*/ + iRet = wmt_core_ctrl(WMT_CTRL_HW_RST, &ctrlPa1, &ctrlPa2); + if (iRet) + WMT_ERR_FUNC("WMT-CORE: -->[HW RST] fail iRet(%d)\n", iRet); + else + WMT_INFO_FUNC("WMT-CORE: -->[HW RST] ok\n"); + + /* 4 close stp */ + ctrlPa1 = 0; + ctrlPa2 = 0; + iRet = wmt_core_ctrl(WMT_CTRL_STP_CLOSE, &ctrlPa1, &ctrlPa2); + if (iRet) { + WMT_ERR_FUNC("WMT-CORE: wmt close stp failed\n"); + return -1; + } + + wmt_core_dump_func_state("AF HW RST"); + return iRet; +} + +static INT32 opfunc_sw_rst(P_WMT_OP pWmtOp) +{ + INT32 iRet = -1; + + iRet = wmt_core_stp_init(); + if (iRet == 0) { + WMT_INFO_FUNC("WMT-CORE: SW Rst succeed\n"); + gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_FUNC_ON; + } else { + WMT_ERR_FUNC("WMT-CORE: SW Rst failed\n"); + gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_OFF; + } + + return iRet; +} + +static INT32 opfunc_stp_rst(P_WMT_OP pWmtOp) +{ + + return 0; +} + +static INT32 opfunc_therm_ctrl(P_WMT_OP pWmtOp) +{ + + INT32 iRet = -1; + UINT32 u4Res; + UINT32 evtLen; + UINT8 evtBuf[16] = { 0 }; + + WMT_THERM_CMD[4] = pWmtOp->au4OpData[0]; /*CMD type, refer to ENUM_WMTTHERM_TYPE_T */ + + /* send command */ + /* iRet = (*kal_stp_tx)(WMT_THERM_CMD, osal_sizeof(WMT_THERM_CMD), &u4Res); */ + iRet = + wmt_core_tx((PUINT8) WMT_THERM_CMD, osal_sizeof(WMT_THERM_CMD), &u4Res, + MTK_WCN_BOOL_FALSE); + if (iRet || (u4Res != osal_sizeof(WMT_THERM_CMD))) { + WMT_ERR_FUNC("WMT-CORE: THERM_CTRL_CMD iRet(%d) cmd len err(%d, %zu)\n", iRet, + u4Res, osal_sizeof(WMT_THERM_CMD)); + return iRet; + } + + evtLen = 16; + + iRet = wmt_core_rx(evtBuf, evtLen, &u4Res); + if (iRet || ((u4Res != osal_sizeof(WMT_THERM_CTRL_EVT)) && (u4Res != osal_sizeof(WMT_THERM_READ_EVT)))) { + WMT_ERR_FUNC("WMT-CORE: read THERM_CTRL_EVT/THERM_READ_EVENT fail(%d) len(%d)\n", iRet, u4Res); + wmt_lib_trigger_assert(WMTDRV_TYPE_WMT, 36); + return iRet; + } + if (u4Res == osal_sizeof(WMT_THERM_CTRL_EVT)) { + if (osal_memcmp(evtBuf, WMT_THERM_CTRL_EVT, osal_sizeof(WMT_THERM_CTRL_EVT)) != 0) { + WMT_ERR_FUNC("WMT-CORE: compare WMT_THERM_CTRL_EVT error\n"); + WMT_ERR_FUNC + ("WMT-CORE: rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%zu):[%02X,%02X,%02X,%02X,%02X]\n", + u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], + osal_sizeof(WMT_THERM_CTRL_EVT), WMT_THERM_CTRL_EVT[0], + WMT_THERM_CTRL_EVT[1], WMT_THERM_CTRL_EVT[2], WMT_THERM_CTRL_EVT[3], + WMT_THERM_CTRL_EVT[4]); + pWmtOp->au4OpData[1] = MTK_WCN_BOOL_FALSE; /*will return to function driver */ + mtk_wcn_stp_dbg_dump_package(); + } else { + WMT_DBG_FUNC("Send WMT_THERM_CTRL_CMD command OK!\n"); + pWmtOp->au4OpData[1] = MTK_WCN_BOOL_TRUE; /*will return to function driver */ + } + } else { + /*no need to judge the real thermal value */ + if (osal_memcmp(evtBuf, WMT_THERM_READ_EVT, osal_sizeof(WMT_THERM_READ_EVT) - 1) != + 0) { + WMT_ERR_FUNC("WMT-CORE: compare WMT_THERM_READ_EVT error\n"); + WMT_ERR_FUNC + ("WMT-CORE: rx(%d):[%02X,%02X,%02X,%02X,%02X,%02X] exp(%zu):[%02X,%02X,%02X,%02X]\n", + u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], + evtBuf[5], osal_sizeof(WMT_THERM_READ_EVT), WMT_THERM_READ_EVT[0], + WMT_THERM_READ_EVT[1], WMT_THERM_READ_EVT[2], WMT_THERM_READ_EVT[3]); + pWmtOp->au4OpData[1] = 0xFF; /*will return to function driver */ + mtk_wcn_stp_dbg_dump_package(); + } else { + WMT_DBG_FUNC("Send WMT_THERM_READ_CMD command OK!\n"); + pWmtOp->au4OpData[1] = evtBuf[5]; /*will return to function driver */ + } + } + + return iRet; + +} + +static INT32 opfunc_efuse_rw(P_WMT_OP pWmtOp) +{ + + INT32 iRet = -1; + UINT32 u4Res; + UINT32 evtLen; + UINT8 evtBuf[16] = { 0 }; + + if (gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] != DRV_STS_FUNC_ON) { + WMT_ERR_FUNC("WMT-CORE: wmt_efuse_rw fail: chip is powered off\n"); + return -1; + } + + WMT_EFUSE_CMD[4] = (pWmtOp->au4OpData[0]) ? 0x1 : 0x2; /* w:2, r:1 */ + osal_memcpy(&WMT_EFUSE_CMD[6], (PUINT8) &pWmtOp->au4OpData[1], 2); /* address */ + osal_memcpy(&WMT_EFUSE_CMD[8], (PUINT32) pWmtOp->au4OpData[2], 4); /* value */ + + wmt_core_dump_data(&WMT_EFUSE_CMD[0], "efuse_cmd", osal_sizeof(WMT_EFUSE_CMD)); + + /* send command */ + /* iRet = (*kal_stp_tx)(WMT_EFUSE_CMD, osal_sizeof(WMT_EFUSE_CMD), &u4Res); */ + iRet = + wmt_core_tx((PUINT8) WMT_EFUSE_CMD, osal_sizeof(WMT_EFUSE_CMD), &u4Res, + MTK_WCN_BOOL_FALSE); + if (iRet || (u4Res != osal_sizeof(WMT_EFUSE_CMD))) { + WMT_ERR_FUNC("WMT-CORE: EFUSE_CMD iRet(%d) cmd len err(%d, %zu)\n", iRet, u4Res, + osal_sizeof(WMT_EFUSE_CMD)); + return iRet; + } + + evtLen = osal_sizeof(WMT_EFUSE_EVT); + iRet = wmt_core_rx(evtBuf, evtLen, &u4Res); + if (iRet || (u4Res != evtLen)) { + WMT_ERR_FUNC("WMT-CORE: read REG_EVB fail(%d) len(%d, %d)\n", iRet, u4Res, evtLen); + WMT_INFO_FUNC("buf:[%2X,%2X,%2X,%2X,%2X] evt:[%2X,%2X,%2X,%2X,%2X]\n", + evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], + WMT_EFUSE_EVT[0], WMT_EFUSE_EVT[1], WMT_EFUSE_EVT[2], + WMT_EFUSE_EVT[3], WMT_EFUSE_EVT[4]); + } + wmt_core_dump_data(&evtBuf[0], "efuse_evt", osal_sizeof(evtBuf)); + + return iRet; +} + +static INT32 opfunc_gpio_ctrl(P_WMT_OP pWmtOp) +{ + INT32 iRet = -1; + WMT_IC_PIN_ID id; + WMT_IC_PIN_STATE stat; + UINT32 flag; + + if (gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] != DRV_STS_FUNC_ON) { + WMT_ERR_FUNC("WMT-CORE: wmt_gpio_ctrl fail: chip is powered off\n"); + return -1; + } + + if (!gMtkWmtCtx.p_ic_ops->ic_pin_ctrl) { + WMT_ERR_FUNC("WMT-CORE: error, gMtkWmtCtx.p_ic_ops->ic_pin_ctrl(NULL)\n"); + return -1; + } + + id = pWmtOp->au4OpData[0]; + stat = pWmtOp->au4OpData[1]; + flag = pWmtOp->au4OpData[2]; + + WMT_INFO_FUNC("ic pin id:%d, stat:%d, flag:0x%x\n", id, stat, flag); + + iRet = (*(gMtkWmtCtx.p_ic_ops->ic_pin_ctrl)) (id, stat, flag); + + return iRet; +} + +/* turn on/off sdio function */ +INT32 opfunc_sdio_ctrl(P_WMT_OP pWmtOp) +{ + ULONG ctrlPa1 = 0; + ULONG ctrlPa2 = 0; + UINT32 iRet = 0; + + ctrlPa1 = + WMT_HIF_SDIO == + gMtkWmtCtx.wmtHifConf.hifType ? WMT_SDIO_SLOT_SDIO2 : WMT_SDIO_SLOT_SDIO1; + ctrlPa2 = pWmtOp->au4OpData[0]; /* turn off/on SDIO slot */ + iRet = wmt_core_ctrl(WMT_CTRL_SDIO_HW, &ctrlPa1, &ctrlPa2); + if (iRet) { + WMT_WARN_FUNC("SDIO hw ctrl fail ret(%d)\n", iRet); + /* Anyway, continue turning STP SDIO to POWER OFF/ON state */ + gMtkWmtCtx.eDrvStatus[ctrlPa1] = DRV_STS_POWER_OFF; + } else { + WMT_INFO_FUNC("SDIO hw ctrl succeed\n"); + gMtkWmtCtx.eDrvStatus[ctrlPa1] = + ctrlPa2 == 0 ? DRV_STS_POWER_OFF : DRV_STS_POWER_ON; + } + + return 0; + +} + +INT32 opfunc_trigger_stp_assert(P_WMT_OP pWmtOp) +{ + if (wmt_core_trigger_stp_assert() == MTK_WCN_BOOL_TRUE) { + WMT_INFO_FUNC("trigger STP assert succeed\n"); + return 0; + } + WMT_WARN_FUNC("trigger STP assert failed\n"); + return -1; +} + +MTK_WCN_BOOL wmt_core_is_quick_ps_support(VOID) +{ + P_WMT_CTX pctx = &gMtkWmtCtx; + + if ((pctx->p_ic_ops != NULL) && (pctx->p_ic_ops->is_quick_sleep != NULL)) + return (*(pctx->p_ic_ops->is_quick_sleep))(); + return MTK_WCN_BOOL_FALSE; +} + +MTK_WCN_BOOL wmt_core_get_aee_dump_flag(VOID) +{ + MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; + P_WMT_CTX pctx = &gMtkWmtCtx; + + if ((pctx->p_ic_ops != NULL) && (pctx->p_ic_ops->is_aee_dump_support != NULL)) + bRet = (*(pctx->p_ic_ops->is_aee_dump_support))(); + else + bRet = MTK_WCN_BOOL_FALSE; + + return bRet; +} + +static INT32 opfunc_bgw_ds(P_WMT_OP pWmtOp) +{ + INT32 iRet = -1; + UINT32 u4WrittenSize = 0; + UINT32 u4ReadSize = 0; + UINT32 buf_len = 0; + UINT8 *buffer = NULL; + UINT8 evt_buffer[8] = { 0 }; + MTK_WCN_BOOL fgFail; + + UINT8 WMT_BGW_DESENSE_CMD[] = { + 0x01, 0x0e, 0x0f, 0x00, + 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 + }; + UINT8 WMT_BGW_DESENSE_EVT[] = { 0x02, 0x0e, 0x01, 0x00, 0x00 }; + + buf_len = pWmtOp->au4OpData[0]; + buffer = (PUINT8) pWmtOp->au4OpData[1]; + + osal_memcpy(&WMT_BGW_DESENSE_CMD[5], buffer, buf_len); + + do { + fgFail = MTK_WCN_BOOL_TRUE; + + iRet = + wmt_core_tx(&WMT_BGW_DESENSE_CMD[0], osal_sizeof(WMT_BGW_DESENSE_CMD), &u4WrittenSize, + MTK_WCN_BOOL_FALSE); + if (iRet || (u4WrittenSize != osal_sizeof(WMT_BGW_DESENSE_CMD))) { + WMT_ERR_FUNC("bgw desense tx CMD fail(%d),size(%d)\n", iRet, u4WrittenSize); + break; + } + + iRet = wmt_core_rx(evt_buffer, osal_sizeof(WMT_BGW_DESENSE_EVT), &u4ReadSize); + if (iRet || (u4ReadSize != osal_sizeof(WMT_BGW_DESENSE_EVT))) { + WMT_ERR_FUNC("bgw desense rx EVT fail(%d),size(%d)\n", iRet, u4ReadSize); + break; + } + + if (osal_memcmp(evt_buffer, WMT_BGW_DESENSE_EVT, osal_sizeof(WMT_BGW_DESENSE_EVT)) != 0) { + WMT_ERR_FUNC + ("bgw desense WMT_BGW_DESENSE_EVT compare fail:0x%02x,0x%02x,0x%02x,0x%02x,0x%02x\n", + evt_buffer[0], evt_buffer[1], evt_buffer[2], evt_buffer[3], evt_buffer[4]); + break; + } + + fgFail = MTK_WCN_BOOL_FALSE; + + } while (0); + + return fgFail; +} + +static INT32 wmt_core_gen2_set_mcu_clk(UINT32 kind) +{ + INT32 iRet = -1; + UINT32 u4WrittenSize = 0; + UINT32 u4ReadSize = 0; + UINT8 evt_buffer[12] = { 0 }; + MTK_WCN_BOOL fgFail; + PUINT8 set_mcu_clk_str[] = { + "Enable GEN2 MCU PLL", + "SET GEN2 MCU CLK to 26M", + "SET GEN2 MCU CLK to 37M", + "SET GEN2 MCU CLK to 64M", + "SET GEN2 MCU CLK to 69M", + "SET GEN2 MCU CLK to 104M", + "SET GEN2 MCU CLK to 118.857M", + "SET GEN2 MCU CLK to 138.67M", + "Disable GEN2 MCU PLL" + }; + UINT8 WMT_SET_MCU_CLK_CMD[] = { + 0x01, 0x08, 0x10, 0x00, + 0x01, 0x01, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff + }; + UINT8 WMT_SET_MCU_CLK_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; + + UINT8 WMT_EN_MCU_CLK_CMD[] = { 0x34, 0x03, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00 }; /* enable pll clk */ + UINT8 WMT_26_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x00, 0x4d, 0x84, 0x00 }; /* set 26M */ + UINT8 WMT_37_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x1e, 0x4d, 0x84, 0x00 }; /* set 37.8M */ + UINT8 WMT_64_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x1d, 0x4d, 0x84, 0x00 }; /* set 64M */ + UINT8 WMT_69_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x1c, 0x4d, 0x84, 0x00 }; /* set 69M */ + UINT8 WMT_104_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x5b, 0x4d, 0x84, 0x00 }; /* set 104M */ + UINT8 WMT_108_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x5a, 0x4d, 0x84, 0x00 }; /* set 118.857M */ + UINT8 WMT_138_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x59, 0x4d, 0x84, 0x00 }; /* set 138.67M */ + UINT8 WMT_DIS_MCU_CLK_CMD[] = { 0x34, 0x03, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00 }; /* disable pll clk */ + + WMT_INFO_FUNC("do %s\n", set_mcu_clk_str[kind]); + + switch (kind) { + case 0: + osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_EN_MCU_CLK_CMD[0], osal_sizeof(WMT_EN_MCU_CLK_CMD)); + break; + case 1: + osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_26_MCU_CLK_CMD[0], osal_sizeof(WMT_26_MCU_CLK_CMD)); + break; + case 2: + osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_37_MCU_CLK_CMD[0], osal_sizeof(WMT_37_MCU_CLK_CMD)); + break; + case 3: + osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_64_MCU_CLK_CMD[0], osal_sizeof(WMT_64_MCU_CLK_CMD)); + break; + case 4: + osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_69_MCU_CLK_CMD[0], osal_sizeof(WMT_69_MCU_CLK_CMD)); + break; + case 5: + osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_104_MCU_CLK_CMD[0], osal_sizeof(WMT_104_MCU_CLK_CMD)); + break; + case 6: + osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_108_MCU_CLK_CMD[0], osal_sizeof(WMT_108_MCU_CLK_CMD)); + break; + case 7: + osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_138_MCU_CLK_CMD[0], osal_sizeof(WMT_138_MCU_CLK_CMD)); + break; + case 8: + osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_DIS_MCU_CLK_CMD[0], osal_sizeof(WMT_DIS_MCU_CLK_CMD)); + break; + default: + WMT_ERR_FUNC("unknown kind\n"); + break; + } + + do { + fgFail = MTK_WCN_BOOL_TRUE; + + iRet = + wmt_core_tx(&WMT_SET_MCU_CLK_CMD[0], osal_sizeof(WMT_SET_MCU_CLK_CMD), &u4WrittenSize, + MTK_WCN_BOOL_FALSE); + if (iRet || (u4WrittenSize != osal_sizeof(WMT_SET_MCU_CLK_CMD))) { + WMT_ERR_FUNC("WMT_SET_MCU_CLK_CMD fail(%d),size(%d)\n", iRet, u4WrittenSize); + break; + } + + iRet = wmt_core_rx(evt_buffer, osal_sizeof(WMT_SET_MCU_CLK_EVT), &u4ReadSize); + if (iRet || (u4ReadSize != osal_sizeof(WMT_SET_MCU_CLK_EVT))) { + WMT_ERR_FUNC("WMT_SET_MCU_CLK_EVT fail(%d),size(%d)\n", iRet, u4ReadSize); + mtk_wcn_stp_dbg_dump_package(); + break; + } + + if (osal_memcmp(evt_buffer, WMT_SET_MCU_CLK_EVT, osal_sizeof(WMT_SET_MCU_CLK_EVT)) != 0) { + WMT_ERR_FUNC("WMT_SET_MCU_CLK_EVT compare fail, [0-3]:0x%02x,0x%02x,0x%02x,0x%02x\n", + evt_buffer[0], evt_buffer[1], evt_buffer[2], evt_buffer[3]); + WMT_ERR_FUNC("WMT_SET_MCU_CLK_EVT compare fail, [4-7]:0x%02x,0x%02x,0x%02x,0x%02x\n", + evt_buffer[4], evt_buffer[5], evt_buffer[6], evt_buffer[7]); + break; + } + + fgFail = MTK_WCN_BOOL_FALSE; + + } while (0); + + if (fgFail == MTK_WCN_BOOL_FALSE) + WMT_INFO_FUNC("wmt-core:%s: ok!\n", set_mcu_clk_str[kind]); + else + WMT_INFO_FUNC("wmt-core:%s: fail!\n", set_mcu_clk_str[kind]); + + return fgFail; +} + +static INT32 wmt_core_gen3_set_mcu_clk(UINT32 kind) +{ + INT32 iRet = -1; + UINT32 u4WrittenSize = 0; + UINT32 u4ReadSize = 0; + UINT8 evt_buffer[12] = { 0 }; + MTK_WCN_BOOL fgFail; + PUINT8 set_mcu_clk_str[] = { + "SET GEN3 MCU CLK to 26M", + "SET GEN3 MCU CLK to 46M", + "SET GEN3 MCU CLK to 97M", + "SET GEN3 MCU CLK to 104M", + "SET GEN3 MCU CLK to 184M", + "SET GEN3 MCU CLK to 208M", + }; + UINT8 set_mcu_clk_vel[] = { + 0x1a, /* set 26M*/ + 0x2e, /* set 46M*/ + 0x61, /* set 97M*/ + 0x68, /* set 104M */ + 0xb8, /* set 184M */ + 0xd0, /* set 208M */ + }; + UINT8 WMT_SET_MCU_CLK_CMD[] = { 0x01, 0x0a, 0x04, 0x00, 0x09, 0x03, 0x00, 0x00 }; + UINT8 WMT_SET_MCU_CLK_EVT[] = { 0x02, 0x0a, 0x01, 0x00, 0x00 }; + + + if (kind < osal_sizeof(set_mcu_clk_vel)) { + WMT_INFO_FUNC("do %s\n", set_mcu_clk_str[kind]); + WMT_SET_MCU_CLK_CMD[6] = set_mcu_clk_vel[kind]; + } else { + WMT_ERR_FUNC("unknown kind(%d)!\n", kind); + return MTK_WCN_BOOL_TRUE; + } + + do { + fgFail = MTK_WCN_BOOL_TRUE; + + iRet = wmt_core_tx(&WMT_SET_MCU_CLK_CMD[0], osal_sizeof(WMT_SET_MCU_CLK_CMD), &u4WrittenSize, + MTK_WCN_BOOL_FALSE); + if (iRet || (u4WrittenSize != osal_sizeof(WMT_SET_MCU_CLK_CMD))) { + WMT_ERR_FUNC("WMT_SET_MCU_CLK_CMD fail(%d),size(%d)\n", iRet, u4WrittenSize); + break; + } + + iRet = wmt_core_rx(evt_buffer, osal_sizeof(WMT_SET_MCU_CLK_EVT), &u4ReadSize); + if (iRet || (u4ReadSize != osal_sizeof(WMT_SET_MCU_CLK_EVT))) { + WMT_ERR_FUNC("WMT_SET_MCU_CLK_EVT fail(%d),size(%d)\n", iRet, u4ReadSize); + mtk_wcn_stp_dbg_dump_package(); + break; + } + + if (osal_memcmp(evt_buffer, WMT_SET_MCU_CLK_EVT, osal_sizeof(WMT_SET_MCU_CLK_EVT)) != 0) { + WMT_ERR_FUNC("WMT_SET_MCU_CLK_EVT compare fail, [0-3]:0x%02x,0x%02x,0x%02x,0x%02x\n", + evt_buffer[0], evt_buffer[1], evt_buffer[2], evt_buffer[3]); + WMT_ERR_FUNC("WMT_SET_MCU_CLK_EVT compare fail, [4-7]:0x%02x,0x%02x,0x%02x,0x%02x\n", + evt_buffer[4], evt_buffer[5], evt_buffer[6], evt_buffer[7]); + break; + } + + fgFail = MTK_WCN_BOOL_FALSE; + + } while (0); + + if (fgFail == MTK_WCN_BOOL_FALSE) + WMT_INFO_FUNC("wmt-core:%s: ok!\n", set_mcu_clk_str[kind]); + else + WMT_INFO_FUNC("wmt-core:%s: fail!\n", set_mcu_clk_str[kind]); + + return fgFail; +} + +static INT32 wmt_core_set_mcu_clk(UINT32 kind) +{ + INT32 iRet = -1; + UINT32 u4WrittenSize = 0; + UINT32 u4ReadSize = 0; + UINT8 evt_buffer[12] = { 0 }; + MTK_WCN_BOOL fgFail; + + UINT8 WMT_SET_MCU_CLK_CMD[] = { 0x01, 0x0a, 0x04, 0x00, 0x09, 0x01, 0x00, 0x00 }; + UINT8 WMT_SET_MCU_CLK_EVT[] = { 0x02, 0x0a, 0x01, 0x00, 0x00 }; + + + WMT_INFO_FUNC("clock frequency 0x%x\n", kind); + WMT_SET_MCU_CLK_CMD[6] = (kind & 0xff); + + do { + fgFail = MTK_WCN_BOOL_TRUE; + + iRet = wmt_core_tx(&WMT_SET_MCU_CLK_CMD[0], osal_sizeof(WMT_SET_MCU_CLK_CMD), &u4WrittenSize, + MTK_WCN_BOOL_FALSE); + if (iRet || (u4WrittenSize != osal_sizeof(WMT_SET_MCU_CLK_CMD))) { + WMT_ERR_FUNC("WMT_SET_MCU_CLK_CMD fail(%d),size(%d)\n", iRet, u4WrittenSize); + break; + } + + iRet = wmt_core_rx(evt_buffer, osal_sizeof(WMT_SET_MCU_CLK_EVT), &u4ReadSize); + if (iRet || (u4ReadSize != osal_sizeof(WMT_SET_MCU_CLK_EVT))) { + WMT_ERR_FUNC("WMT_SET_MCU_CLK_EVT fail(%d),size(%d)\n", iRet, u4ReadSize); + mtk_wcn_stp_dbg_dump_package(); + break; + } + + if (osal_memcmp(evt_buffer, WMT_SET_MCU_CLK_EVT, osal_sizeof(WMT_SET_MCU_CLK_EVT)) != 0) { + WMT_ERR_FUNC("WMT_SET_MCU_CLK_EVT compare fail, [0-3]:0x%02x,0x%02x,0x%02x,0x%02x\n", + evt_buffer[0], evt_buffer[1], evt_buffer[2], evt_buffer[3]); + WMT_ERR_FUNC("WMT_SET_MCU_CLK_EVT compare fail, [4-7]:0x%02x,0x%02x,0x%02x,0x%02x\n", + evt_buffer[4], evt_buffer[5], evt_buffer[6], evt_buffer[7]); + break; + } + + fgFail = MTK_WCN_BOOL_FALSE; + + } while (0); + + if (fgFail == MTK_WCN_BOOL_FALSE) + WMT_INFO_FUNC("wmt-core:set mcu clock ok!\n"); + else + WMT_INFO_FUNC("wmt-core:set mcu clock fail!\n"); + + return fgFail; +} + +static INT32 opfunc_set_mcu_clk(P_WMT_OP pWmtOp) +{ + UINT32 kind = 0; + UINT32 version = 0; + MTK_WCN_BOOL ret; + + kind = pWmtOp->au4OpData[0]; + version = pWmtOp->au4OpData[1]; + + switch (version) { + case 0: + ret = wmt_core_gen2_set_mcu_clk(kind); + break; + case 1: + ret = wmt_core_gen3_set_mcu_clk(kind); + break; + case 2: + ret = wmt_core_set_mcu_clk(kind); + break; + default: + WMT_ERR_FUNC("wmt-core: version(%d) is not support!\n", version); + ret = MTK_WCN_BOOL_TRUE; + } + + return ret; +} + +static INT32 opfunc_adie_lpbk_test(P_WMT_OP pWmtOp) +{ + UINT8 *buffer = NULL; + MTK_WCN_BOOL fgFail; + UINT32 u4Res; + UINT32 aDieChipid = 0; + UINT8 soc_adie_chipid_cmd[] = { 0x01, 0x13, 0x04, 0x00, 0x02, 0x04, 0x24, 0x00 }; + UINT8 soc_adie_chipid_evt[] = { 0x02, 0x13, 0x09, 0x00, 0x00, 0x02, 0x04, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00 }; + UINT8 evtbuf[20]; + INT32 iRet = -1; + + buffer = (PUINT8) pWmtOp->au4OpData[1]; + + do { + fgFail = MTK_WCN_BOOL_TRUE; + + /* read A die chipid by wmt cmd */ + iRet = + wmt_core_tx((PUINT8) &soc_adie_chipid_cmd[0], osal_sizeof(soc_adie_chipid_cmd), &u4Res, + MTK_WCN_BOOL_FALSE); + if (iRet || (u4Res != osal_sizeof(soc_adie_chipid_cmd))) { + WMT_ERR_FUNC("wmt_core:read A die chipid CMD fail(%d),size(%d)\n", iRet, u4Res); + break; + } + osal_memset(evtbuf, 0, osal_sizeof(evtbuf)); + iRet = wmt_core_rx(evtbuf, osal_sizeof(soc_adie_chipid_evt), &u4Res); + if (iRet || (u4Res != osal_sizeof(soc_adie_chipid_evt))) { + WMT_ERR_FUNC("wmt_core:read A die chipid EVT fail(%d),size(%d)\n", iRet, u4Res); + break; + } + osal_memcpy(&aDieChipid, &evtbuf[u4Res - 2], 2); + osal_memcpy(buffer, &evtbuf[u4Res - 2], 2); + pWmtOp->au4OpData[0] = 2; + WMT_INFO_FUNC("get SOC A die chipid(0x%x)\n", aDieChipid); + + fgFail = MTK_WCN_BOOL_FALSE; + + } while (0); + + return fgFail; +} + +MTK_WCN_BOOL wmt_core_trigger_stp_assert(VOID) +{ + MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; + P_WMT_CTX pctx = &gMtkWmtCtx; + + if (mtk_wcn_stp_coredump_flag_get() == 0) { + WMT_INFO_FUNC("coredump is disabled, omit trigger STP assert\n"); + wmt_lib_trigger_reset(); + return MTK_WCN_BOOL_FALSE; + } + + if ((pctx->p_ic_ops != NULL) && (pctx->p_ic_ops->trigger_stp_assert != NULL)) { + WMT_INFO_FUNC("trigger stp assert function is supported by 0x%X\n", + pctx->p_ic_ops->icId); + bRet = (*(pctx->p_ic_ops->trigger_stp_assert)) (); + } else { + if (pctx->p_ic_ops != NULL) + WMT_INFO_FUNC("trigger stp assert function is not supported by 0x%X\n", + pctx->p_ic_ops->icId); + bRet = MTK_WCN_BOOL_FALSE; + } + + return bRet; +} +#ifdef CONFIG_MTK_COMBO_CHIP_DEEP_SLEEP_SUPPORT +MTK_WCN_BOOL wmt_core_deep_sleep_ctrl(INT32 value) +{ + MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; + P_WMT_CTX pctx = &gMtkWmtCtx; + + if ((pctx->p_ic_ops != NULL) && (pctx->p_ic_ops->deep_sleep_ctrl != NULL)) { + bRet = (*(pctx->p_ic_ops->deep_sleep_ctrl)) (value); + } else { + if (pctx->p_ic_ops != NULL) + WMT_INFO_FUNC("deep sleep function is not supported by 0x%x\n", + pctx->p_ic_ops->icId); + bRet = MTK_WCN_BOOL_FALSE; + } + return bRet; +} +#endif +INT32 opfunc_pin_state(P_WMT_OP pWmtOp) +{ + ULONG ctrlPa1 = 0; + ULONG ctrlPa2 = 0; + INT32 iRet = 0; + + iRet = wmt_core_ctrl(WMT_CTRL_HW_STATE_DUMP, &ctrlPa1, &ctrlPa2); + return iRet; +} + +#ifdef CONFIG_MTK_COMBO_ANT +INT32 opfunc_ant_ram_down(P_WMT_OP pWmtOp) +{ + INT32 iRet = 0; + size_t ctrlPa1 = pWmtOp->au4OpData[0]; + UINT32 ctrlPa2 = pWmtOp->au4OpData[1]; + PUINT8 pbuf = (PUINT8) ctrlPa1; + UINT32 fragSeq = 0; + UINT16 fragSize = 0; + UINT16 wmtCmdLen; + UINT16 wmtPktLen; + UINT32 u4Res = 0; + UINT8 antEvtBuf[osal_sizeof(WMT_ANT_RAM_DWN_EVT)]; +#if 1 + UINT32 ctrlPa3 = pWmtOp->au4OpData[2]; + + do { + fragSize = ctrlPa2; + fragSeq = ctrlPa3; + gAntBuf[5] = fragSeq; + + + wmtPktLen = fragSize + sizeof(WMT_ANT_RAM_DWN_CMD) + 1; + + /*WMT command length cal */ + wmtCmdLen = wmtPktLen - 4; +#if 0 + WMT_ANT_RAM_DWN_CMD[2] = wmtCmdLen & 0xFF; + WMT_ANT_RAM_DWN_CMD[3] = (wmtCmdLen & 0xFF00) >> 16; +#else + osal_memcpy(&WMT_ANT_RAM_DWN_CMD[2], &wmtCmdLen, 2); +#endif + + + + WMT_ANT_RAM_DWN_CMD[4] = 1; /*RAM CODE download */ + + osal_memcpy(gAntBuf, WMT_ANT_RAM_DWN_CMD, sizeof(WMT_ANT_RAM_DWN_CMD)); + + /*copy ram code content to global buffer */ + osal_memcpy(&gAntBuf[osal_sizeof(WMT_ANT_RAM_DWN_CMD) + 1], pbuf, fragSize); + + iRet = wmt_core_tx(gAntBuf, wmtPktLen, &u4Res, MTK_WCN_BOOL_FALSE); + if (iRet || (u4Res != wmtPktLen)) { + WMT_ERR_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) fail(%d)\n", fragSeq, + wmtPktLen, u4Res, iRet); + iRet = -4; + break; + } + WMT_DBG_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) ok\n", + fragSeq, wmtPktLen, u4Res); + + osal_memset(antEvtBuf, 0, sizeof(antEvtBuf)); + + WMT_ANT_RAM_DWN_EVT[4] = 0; /*download result; 0 */ + + iRet = wmt_core_rx(antEvtBuf, sizeof(WMT_ANT_RAM_DWN_EVT), &u4Res); + if (iRet || (u4Res != sizeof(WMT_ANT_RAM_DWN_EVT))) { + WMT_ERR_FUNC("wmt_core: read WMT_ANT_RAM_DWN_EVT length(%zu, %d) fail(%d)\n", + sizeof(WMT_ANT_RAM_DWN_EVT), u4Res, iRet); + iRet = -5; + break; + } +#if CFG_CHECK_WMT_RESULT + if (osal_memcmp(antEvtBuf, WMT_ANT_RAM_DWN_EVT, sizeof(WMT_ANT_RAM_DWN_EVT)) != 0) { + WMT_ERR_FUNC("wmt_core: compare WMT_ANT_RAM_DWN_EVT result error\n"); + WMT_ERR_FUNC("rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%zu):[%02X,%02X,%02X,%02X,%02X]\n", + u4Res, antEvtBuf[0], antEvtBuf[1], antEvtBuf[2], antEvtBuf[3], + antEvtBuf[4], sizeof(WMT_ANT_RAM_DWN_EVT), WMT_ANT_RAM_DWN_EVT[0], + WMT_ANT_RAM_DWN_EVT[1], WMT_ANT_RAM_DWN_EVT[2], WMT_ANT_RAM_DWN_EVT[3], + WMT_ANT_RAM_DWN_EVT[4]); + iRet = -6; + break; + } +#endif + WMT_DBG_FUNC("wmt_core: read WMT_ANT_RAM_DWN_EVT length(%zu, %d) ok\n", + sizeof(WMT_ANT_RAM_DWN_EVT), u4Res); + + } while (0); +#else + UINT32 patchSize = ctrlPa2; + UINT32 patchSizePerFrag = 1000; + UINT32 offset; + UINT32 fragNum = 0; + /*cal patch fragNum */ + fragNum = (patchSize + patchSizePerFrag - 1) / patchSizePerFrag; + if (fragNum <= 2) { + WMT_WARN_FUNC("ANT ramcode size(%d) too short\n", patchSize); + return -1; + } + + while (fragSeq < fragNum) { + /*update fragNum */ + fragSeq++; + + if (fragSeq == 1) { + fragSize = patchSizePerFrag; + /*first package */ + gAntBuf[5] = 1; /*RAM CODE start */ + } else if (fragNum == fragSeq) { + /*last package */ + fragSize = patchSizePerFrag; + gAntBuf[5] = 3; /*RAM CODE end */ + } else { + /*middle package */ + fragSize = patchSize - ((fragNum - 1) * patchSizePerFrag); + gAntBuf[5] = 2; /*RAM CODE confinue */ + } + wmtPktLen = fragSize + sizeof(WMT_ANT_RAM_OP_CMD) + 1; + + /*WMT command length cal */ + wmtCmdLen = wmtPktLen - 4; + + WMT_ANT_RAM_OP_CMD[2] = wmtCmdLen & 0xFF; + WMT_ANT_RAM_OP_CMD[3] = (wmtCmdLen & 0xFF00) >> 16; + + WMT_ANT_RAM_OP_CMD[4] = 1; /*RAM CODE download */ + + osal_memcpy(gAntBuf, WMT_ANT_RAM_OP_CMD, sizeof(WMT_ANT_RAM_OP_CMD)); + + /*copy ram code content to global buffer */ + osal_memcpy(&gAntBuf[6], pbuf, fragSize); + + /*update offset */ + offset += fragSize; + pbuf += offset; + + iRet = wmt_core_tx(gAntBuf, wmtPktLen, &u4Res, MTK_WCN_BOOL_FALSE); + if (iRet || (u4Res != wmtPktLen)) { + WMT_ERR_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) fail(%d)\n", fragSeq, + wmtPktLen, u4Res, iRet); + iRet = -4; + break; + } + WMT_DBG_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) ok\n", + fragSeq, wmtPktLen, u4Res); + + osal_memset(antEvtBuf, 0, sizeof(antEvtBuf)); + + WMT_SET_RAM_OP_EVT[4] = 0; /*download result; 0 */ + + iRet = wmt_core_rx(antEvtBuf, sizeof(WMT_SET_RAM_OP_EVT), &u4Res); + if (iRet || (u4Res != sizeof(WMT_SET_RAM_OP_EVT))) { + WMT_ERR_FUNC("wmt_core: read WMT_SET_RAM_OP_EVT length(%d, %d) fail(%d)\n", + sizeof(WMT_SET_RAM_OP_EVT), u4Res, iRet); + iRet = -5; + break; + } +#if CFG_CHECK_WMT_RESULT + if (osal_memcmp(antEvtBuf, WMT_SET_RAM_OP_EVT, sizeof(WMT_SET_RAM_OP_EVT)) != 0) { + WMT_ERR_FUNC("wmt_core: compare WMT_SET_RAM_OP_EVT result error\n"); + WMT_ERR_FUNC("rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%d):[%02X,%02X,%02X,%02X,%02X]\n", + u4Res, antEvtBuf[0], antEvtBuf[1], antEvtBuf[2], antEvtBuf[3], + antEvtBuf[4], sizeof(WMT_SET_RAM_OP_EVT), WMT_SET_RAM_OP_EVT[0], + WMT_SET_RAM_OP_EVT[1], WMT_SET_RAM_OP_EVT[2], WMT_SET_RAM_OP_EVT[3], + WMT_SET_RAM_OP_EVT[4]); + iRet = -6; + break; + } +#endif + WMT_DBG_FUNC("wmt_core: read WMT_SET_RAM_OP_EVT length(%d, %d) ok\n", + sizeof(WMT_SET_RAM_OP_EVT), u4Res); + + + } + if (fragSeq != fragNum) + iRet = -7; +#endif + return iRet; +} + + +INT32 opfunc_ant_ram_stat_get(P_WMT_OP pWmtOp) +{ + INT32 iRet = 0; + UINT32 u4Res = 0; + UINT32 wmtPktLen = osal_sizeof(WMT_ANT_RAM_STA_GET_CMD); + UINT32 u4AntRamStatus = 0; + UINT8 antEvtBuf[osal_sizeof(WMT_ANT_RAM_STA_GET_EVT)]; + + + iRet = wmt_core_tx(WMT_ANT_RAM_STA_GET_CMD, wmtPktLen, &u4Res, MTK_WCN_BOOL_FALSE); + if (iRet || (u4Res != wmtPktLen)) { + WMT_ERR_FUNC + ("wmt_core: write wmt and ramcode status query command failed, (%d, %d), iRet(%d)\n", + wmtPktLen, u4Res, iRet); + iRet = -4; + return iRet; + } + + + iRet = wmt_core_rx(antEvtBuf, sizeof(WMT_ANT_RAM_STA_GET_EVT), &u4Res); + if (iRet || (u4Res != sizeof(WMT_ANT_RAM_STA_GET_EVT))) { + WMT_ERR_FUNC("wmt_core: read WMT_ANT_RAM_STA_GET_EVT length(%zu, %d) fail(%d)\n", + sizeof(WMT_ANT_RAM_STA_GET_EVT), u4Res, iRet); + iRet = -5; + return iRet; + } +#if CFG_CHECK_WMT_RESULT + if (osal_memcmp(antEvtBuf, WMT_ANT_RAM_STA_GET_EVT, sizeof(WMT_ANT_RAM_STA_GET_EVT) - 1) != + 0) { + WMT_ERR_FUNC("wmt_core: compare WMT_ANT_RAM_STA_GET_EVT result error\n"); + WMT_ERR_FUNC("rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%zu):[%02X,%02X,%02X,%02X,%02X]\n", + u4Res, antEvtBuf[0], antEvtBuf[1], antEvtBuf[2], antEvtBuf[3], antEvtBuf[4], + sizeof(WMT_ANT_RAM_STA_GET_EVT), WMT_ANT_RAM_STA_GET_EVT[0], + WMT_ANT_RAM_STA_GET_EVT[1], WMT_ANT_RAM_STA_GET_EVT[2], + WMT_ANT_RAM_STA_GET_EVT[3], WMT_ANT_RAM_STA_GET_EVT[4]); + iRet = -6; + return iRet; + } +#endif + if (iRet == 0) { + u4AntRamStatus = antEvtBuf[sizeof(WMT_ANT_RAM_STA_GET_EVT) - 1]; + pWmtOp->au4OpData[2] = u4AntRamStatus; + WMT_INFO_FUNC("ANT ram code %s\n", + u4AntRamStatus == 1 ? "exist already" : "not exist"); + } + return iRet; +} +#endif +VOID wmt_core_set_coredump_state(ENUM_DRV_STS state) +{ + WMT_INFO_FUNC("wmt-core: set coredump state(%d)\n", state); + gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_COREDUMP] = state; +} + +INT32 opfunc_flash_patch_down(P_WMT_OP pWmtOp) +{ + INT32 iRet = 0; + PUINT8 u4pbuf = (PUINT8)pWmtOp->au4OpData[0]; + UINT16 u4PatchSize = pWmtOp->au4OpData[1]; + UINT32 u4PatchSeq = pWmtOp->au4OpData[2]; + UINT32 u4PatchType = pWmtOp->au4OpData[3]; + UINT32 u4PatchVersion = pWmtOp->au4OpData[4]; + UINT32 u4PatchChecksum = pWmtOp->au4OpData[5]; + UINT16 wmtCmdLen; + UINT16 wmtPktLen = 0; + UINT32 u4Res = 0; + UINT8 evtBuf[osal_sizeof(WMT_FLASH_PATCH_DWN_EVT)]; + UINT32 i = 0; + + do { + osal_memcpy(gFlashBuf, WMT_FLASH_PATCH_DWN_CMD, sizeof(WMT_FLASH_PATCH_DWN_CMD)); + + switch (u4PatchSeq) { + case WMT_FLASH_PATCH_HEAD_PKT: + /*WMT command length cal */ + wmtPktLen = sizeof(WMT_FLASH_PATCH_DWN_CMD) + WMT_FLASH_PATCH_DWN_CMD[2] - 1; + osal_memcpy(&gFlashBuf[5], &u4PatchType, sizeof(u4PatchType)); + osal_memcpy(&gFlashBuf[9], &u4PatchVersion, sizeof(u4PatchVersion)); + osal_memcpy(&gFlashBuf[13], &u4PatchChecksum, sizeof(u4PatchChecksum)); + break; + case WMT_FLASH_PATCH_START_PKT: + case WMT_FLASH_PATCH_CONTINUE_PKT: + case WMT_FLASH_PATCH_END_PKT: + gFlashBuf[4] = u4PatchSeq; + /*WMT command length cal */ + wmtCmdLen = u4PatchSize + 1; + wmtPktLen = u4PatchSize + sizeof(WMT_FLASH_PATCH_DWN_CMD); + gFlashBuf[2] = wmtCmdLen & 0xFF; + gFlashBuf[3] = (wmtCmdLen & 0xFF00) >> 8; + /*copy ram code content to global buffer */ + osal_memcpy(&gFlashBuf[osal_sizeof(WMT_FLASH_PATCH_DWN_CMD)], u4pbuf, u4PatchSize); + break; + default: + break; + } + + iRet = wmt_core_tx(gFlashBuf, wmtPktLen, &u4Res, MTK_WCN_BOOL_FALSE); + if (iRet || (u4Res != wmtPktLen)) { + WMT_ERR_FUNC("wmt_core: write PatchSeq(%d) size(%d, %d) fail(%d)\n", u4PatchSeq, + wmtPktLen, u4Res, iRet); + iRet = -4; + u4Res = -1; + break; + } + WMT_DBG_FUNC("wmt_core: write PatchSeq(%d) size(%d, %d) ok\n", + u4PatchSeq, wmtPktLen, u4Res); + + osal_memset(evtBuf, 0, sizeof(evtBuf)); + + /* flash patch download time longer than WMT command timeout */ + for (i = 0; i < 3; i++) { + iRet = wmt_core_rx(evtBuf, sizeof(WMT_FLASH_PATCH_DWN_EVT), &u4Res); + if (!iRet) + break; + } + if (iRet || (u4Res != sizeof(WMT_FLASH_PATCH_DWN_EVT))) { + WMT_ERR_FUNC("wmt_core: read WMT_FLASH_PATCH_DWN_EVT length(%zu, %d) fail(%d)\n", + sizeof(WMT_FLASH_PATCH_DWN_EVT), u4Res, iRet); + wmt_lib_trigger_assert(WMTDRV_TYPE_WMT, 39); + + iRet = -5; + u4Res = -2; + break; + } +#if CFG_CHECK_WMT_RESULT + if (osal_memcmp(evtBuf, WMT_FLASH_PATCH_DWN_EVT, sizeof(WMT_FLASH_PATCH_DWN_EVT)) != 0) { + WMT_ERR_FUNC("wmt_core: compare WMT_FLASH_PATCH_DWN_EVT result error\n"); + WMT_ERR_FUNC("rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%zu):[%02X,%02X,%02X,%02X,%02X]\n", + u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], + sizeof(WMT_FLASH_PATCH_DWN_EVT), WMT_FLASH_PATCH_DWN_EVT[0], + WMT_FLASH_PATCH_DWN_EVT[1], WMT_FLASH_PATCH_DWN_EVT[2], + WMT_FLASH_PATCH_DWN_EVT[3], WMT_FLASH_PATCH_DWN_EVT[4]); + iRet = -6; + u4Res = -3; + break; + } +#endif + u4Res = 0; + WMT_DBG_FUNC("wmt_core: read WMT_FLASH_PATCH_DWN_EVT length(%zu, %d) ok\n", + sizeof(WMT_FLASH_PATCH_DWN_EVT), u4Res); + + } while (0); + + pWmtOp->au4OpData[6] = u4Res; + return iRet; +} + +INT32 opfunc_flash_patch_ver_get(P_WMT_OP pWmtOp) +{ + INT32 iRet = 0; + UINT32 u4Res = 0; + UINT32 wmtPktLen = osal_sizeof(WMT_FLASH_PATCH_VER_GET_CMD); + UINT32 u4PatchType = pWmtOp->au4OpData[3]; + UINT32 u4PatchVer = 0; + UINT8 evtBuf[osal_sizeof(WMT_FLASH_PATCH_VER_GET_EVT)]; + + do { + osal_memcpy(&WMT_FLASH_PATCH_VER_GET_CMD[5], &u4PatchType, sizeof(u4PatchType)); + + iRet = wmt_core_tx(WMT_FLASH_PATCH_VER_GET_CMD, wmtPktLen, &u4Res, MTK_WCN_BOOL_FALSE); + if (iRet || (u4Res != wmtPktLen)) { + WMT_ERR_FUNC + ("wmt_core: write wmt and flash patch query command failed, (%d, %d), iRet(%d)\n", + wmtPktLen, u4Res, iRet); + iRet = -4; + u4Res = -1; + break; + } + + iRet = wmt_core_rx(evtBuf, sizeof(WMT_FLASH_PATCH_VER_GET_EVT), &u4Res); + if (iRet || (u4Res != sizeof(WMT_FLASH_PATCH_VER_GET_EVT))) { + WMT_ERR_FUNC("wmt_core: read WMT_FLASH_PATCH_VER_GET_EVT length(%zu, %d) fail(%d)\n", + sizeof(WMT_FLASH_PATCH_VER_GET_EVT), u4Res, iRet); + wmt_lib_trigger_assert(WMTDRV_TYPE_WMT, 38); + + iRet = -5; + u4Res = -2; + break; + } +#if CFG_CHECK_WMT_RESULT + if (osal_memcmp(evtBuf, WMT_FLASH_PATCH_VER_GET_EVT, + sizeof(WMT_FLASH_PATCH_VER_GET_EVT) - 8) != 0) { + WMT_ERR_FUNC("wmt_core: compare WMT_FLASH_PATCH_VER_GET_EVT result error\n"); + WMT_ERR_FUNC("rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%zu):[%02X,%02X,%02X,%02X,%02X]\n", + u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], + sizeof(WMT_FLASH_PATCH_VER_GET_EVT), WMT_FLASH_PATCH_VER_GET_EVT[0], + WMT_FLASH_PATCH_VER_GET_EVT[1], WMT_FLASH_PATCH_VER_GET_EVT[2], + WMT_FLASH_PATCH_VER_GET_EVT[3], WMT_FLASH_PATCH_VER_GET_EVT[4]); + iRet = -6; + u4Res = -3; + break; + } +#endif + if (iRet == 0) { + osal_memcpy(&u4PatchVer, &evtBuf[9], sizeof(u4PatchVer)); + pWmtOp->au4OpData[4] = u4PatchVer; + u4Res = 0; + WMT_INFO_FUNC("flash patch type: %x, flash patch version %x\n", + u4PatchType, u4PatchVer); + } + } while (0); + + pWmtOp->au4OpData[6] = u4Res; + return iRet; +} + +#if CFG_WMT_LTE_COEX_HANDLING +static INT32 opfunc_idc_msg_handling(P_WMT_OP pWmtOp) +{ + MTK_WCN_BOOL fgFail; + UINT32 u4Res; + UINT8 host_lte_btwf_coex_cmd[] = { 0x01, 0x10, 0x00, 0x00, 0x00 }; + UINT8 host_lte_btwf_coex_evt[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; + UINT8 *pTxBuf = NULL; + UINT8 evtbuf[8] = { 0 }; + INT32 iRet = -1; + UINT16 msg_len = 0; + UINT32 total_len = 0; + UINT32 index = 0; + UINT32 evtLen; + + pTxBuf = (UINT8 *) pWmtOp->au4OpData[0]; + if (pTxBuf == NULL) { + WMT_ERR_FUNC("idc msg buffer is NULL\n"); + return -1; + } + iRet = wmt_lib_idc_lock_aquire(); + if (iRet) { + WMT_ERR_FUNC("--->lock idc_lock failed, ret=%d\n", iRet); + return iRet; + } + osal_memcpy(&msg_len, &pTxBuf[0], osal_sizeof(msg_len)); + if (msg_len > WMT_IDC_MSG_MAX_SIZE) { + wmt_lib_idc_lock_release(); + WMT_ERR_FUNC("abnormal idc msg len:%d\n", msg_len); + return -2; + } + msg_len += 1; /*flag byte */ + osal_memcpy(&host_lte_btwf_coex_cmd[2], &msg_len, 2); + host_lte_btwf_coex_cmd[4] = (pWmtOp->au4OpData[1] & 0x00ff); + osal_memcpy(&msg_local_buffer[0], &host_lte_btwf_coex_cmd[0], + osal_sizeof(host_lte_btwf_coex_cmd)); + osal_memcpy(&msg_local_buffer[osal_sizeof(host_lte_btwf_coex_cmd)], + &pTxBuf[osal_sizeof(msg_len)], msg_len - 1); + wmt_lib_idc_lock_release(); + total_len = osal_sizeof(host_lte_btwf_coex_cmd) + msg_len - 1; + WMT_DBG_FUNC("wmt_core:idc msg payload len form lte(%d),wmt msg total len(%d)\n", + msg_len - 1, total_len); + WMT_DBG_FUNC("wmt_core:idc msg payload:\n"); + for (index = 0; index < total_len; index++) + WMT_DBG_FUNC("0x%02x ", msg_local_buffer[index]); + do { + fgFail = MTK_WCN_BOOL_TRUE; + + /* read A die chipid by wmt cmd */ + iRet = + wmt_core_tx((PUINT8) &msg_local_buffer[0], total_len, &u4Res, + MTK_WCN_BOOL_FALSE); + if (iRet || (u4Res != total_len)) { + WMT_ERR_FUNC("wmt_core:send lte idc msg to connsys fail(%d),size(%d)\n", + iRet, u4Res); + break; + } + osal_memset(evtbuf, 0, osal_sizeof(evtbuf)); + evtLen = osal_sizeof(host_lte_btwf_coex_evt); + iRet = wmt_core_rx(evtbuf, evtLen, &u4Res); + if (iRet || (u4Res != evtLen)) { + WMT_ERR_FUNC("wmt_core:recv host_lte_btwf_coex_evt fail(%d) len(%d, %d)\n", + iRet, u4Res, evtLen); + wmt_lib_trigger_assert(WMTDRV_TYPE_WMT, 41); + break; + } + + fgFail = MTK_WCN_BOOL_FALSE; + + } while (0); + + return fgFail; +} + +/*TEST CODE*/ +VOID wmt_core_set_flag_for_test(UINT32 enable) +{ + WMT_INFO_FUNC("%s wmt_lte_flag\n", enable ? "enable" : "disable"); + g_open_wmt_lte_flag = enable; +} + +UINT32 wmt_core_get_flag_for_test(VOID) +{ + return g_open_wmt_lte_flag; +} + +#endif + +static INT32 opfunc_utc_time_sync(P_WMT_OP pWmtOp) +{ +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH + INT32 iRet; + UINT32 u4Res; + UINT32 evtLen; + UINT8 evtBuf[16] = { 0 }; + UINT32 tsec; + UINT32 tusec; + + connsys_dedicated_log_get_utc_time(&tsec, &tusec); + /* UTC time second unit */ + osal_memcpy(&WMT_UTC_SYNC_CMD[5], &tsec, 4); + /* UTC time microsecond unit */ + osal_memcpy(&WMT_UTC_SYNC_CMD[9], &tusec, 4); + + /* send command */ + iRet = wmt_core_tx(WMT_UTC_SYNC_CMD, sizeof(WMT_UTC_SYNC_CMD), + &u4Res, MTK_WCN_BOOL_FALSE); + if (iRet) { + WMT_ERR_FUNC("Tx WMT_UTC_SYNC_CMD fail!(%d) len (%d, %zu)\n", + iRet, u4Res, sizeof(WMT_UTC_SYNC_CMD)); + return -1; + } + + /* receive event */ + evtLen = osal_sizeof(WMT_UTC_SYNC_EVT); + iRet = wmt_core_rx(evtBuf, evtLen, &u4Res); + if (iRet || (u4Res != evtLen)) { + WMT_ERR_FUNC("WMT-CORE: read WMT_UTC_SYNC_EVT fail(%d) len(%d, %d)\n", + iRet, u4Res, evtLen); + osal_assert(0); + return iRet; + } + + if (osal_memcmp(evtBuf, WMT_UTC_SYNC_EVT, + osal_sizeof(WMT_UTC_SYNC_EVT)) != 0) { + WMT_ERR_FUNC("WMT-CORE: compare WMT_UTC_SYNC_EVT error\n"); + WMT_ERR_FUNC("WMT-CORE: rx(%d):[%02X,%02X,%02X,%02X,%02X,%02X]\n", + u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], evtBuf[5]); + WMT_ERR_FUNC("WMT-CORE: exp(%zu):[%02X,%02X,%02X,%02X,%02X,%02X]\n", + osal_sizeof(WMT_UTC_SYNC_EVT), WMT_UTC_SYNC_EVT[0], + WMT_UTC_SYNC_EVT[1], WMT_UTC_SYNC_EVT[2], WMT_UTC_SYNC_EVT[3], + WMT_UTC_SYNC_EVT[4], WMT_UTC_SYNC_EVT[5]); + } else { + WMT_INFO_FUNC("Send WMT_UTC_SYNC_CMD command OK!\n"); + } + return 0; +#else + return -1; +#endif +} + +static INT32 opfunc_fw_log_ctrl(P_WMT_OP pWmtOp) +{ + INT32 iRet; + UINT32 u4Res; + UINT32 evtLen; + UINT8 evtBuf[osal_sizeof(WMT_FW_LOG_CTRL_EVT)]; + + /* fill command parameters */ + WMT_FW_LOG_CTRL_CMD[5] = (UINT8)pWmtOp->au4OpData[0]; /* type */ + WMT_FW_LOG_CTRL_CMD[6] = (UINT8)pWmtOp->au4OpData[1]; /* on/off */ + WMT_FW_LOG_CTRL_CMD[7] = (UINT8)pWmtOp->au4OpData[2]; /* log level */ + + /* send command */ + iRet = wmt_core_tx(WMT_FW_LOG_CTRL_CMD, sizeof(WMT_FW_LOG_CTRL_CMD), &u4Res, MTK_WCN_BOOL_FALSE); + if (iRet) { + WMT_ERR_FUNC("Tx WMT_FW_LOG_CTRL_CMD fail!(%d) len (%d, %zu)\n", iRet, u4Res, + sizeof(WMT_FW_LOG_CTRL_CMD)); + return -1; + } + + /* receive event */ + evtLen = osal_sizeof(WMT_FW_LOG_CTRL_EVT); + iRet = wmt_core_rx(evtBuf, evtLen, &u4Res); + if (iRet || (u4Res != evtLen)) { + WMT_ERR_FUNC("WMT-CORE: read WMT_FW_LOG_CTRL_EVT fail(%d) len(%d, %d)\n", iRet, u4Res, evtLen); + osal_assert(0); + return iRet; + } + + if (osal_memcmp(evtBuf, WMT_FW_LOG_CTRL_EVT, evtLen) != 0) { + WMT_ERR_FUNC("WMT-CORE: compare WMT_FW_LOG_CTRL_EVT error\n"); + WMT_ERR_FUNC("WMT-CORE: tx(%zu):[%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x]\n", + osal_sizeof(WMT_FW_LOG_CTRL_CMD), WMT_FW_LOG_CTRL_CMD[0], WMT_FW_LOG_CTRL_CMD[1], + WMT_FW_LOG_CTRL_CMD[2], WMT_FW_LOG_CTRL_CMD[3], WMT_FW_LOG_CTRL_CMD[4], + WMT_FW_LOG_CTRL_CMD[5], WMT_FW_LOG_CTRL_CMD[6], WMT_FW_LOG_CTRL_CMD[7]); + WMT_ERR_FUNC("WMT-CORE: rx(%u):[%02x,%02x,%02x,%02x,%02x]\n", + u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4]); + } else { + WMT_INFO_FUNC("Send WMT_FW_LOG_CTRL_EVT command OK!\n"); + } + return 0; +} + +static INT32 opfunc_wlan_probe(P_WMT_OP pWmtOp) +{ + ULONG ctrlPa1; + ULONG ctrlPa2; + INT32 iRet; + UINT32 drvType = pWmtOp->au4OpData[0]; + + + iRet = wmt_lib_wlan_lock_aquire(); + atomic_set(&g_wifi_on_off_ready, 0); + if (iRet) { + WMT_ERR_FUNC("--->lock wlan_lock failed, iRet=%d\n", iRet); + return iRet; + } + + if (gMtkWmtCtx.eDrvStatus[drvType] == DRV_STS_FUNC_ON) { + WMT_WARN_FUNC("func(%d) already on\n", drvType); + iRet = 0; + wmt_lib_wlan_lock_release(); + goto done; + } + + if (gMtkWmtCtx.wmtHifConf.hifType == WMT_HIF_UART) { + ctrlPa1 = WMT_SDIO_SLOT_SDIO1; + ctrlPa2 = 1; /* turn on SDIO1 slot */ + iRet = wmt_core_ctrl(WMT_CTRL_SDIO_HW, &ctrlPa1, &ctrlPa2); + if (iRet) { + WMT_ERR_FUNC("turn on SLOT_SDIO1 fail (%d)\n", + iRet); + osal_assert(0); + } else { + gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_SDIO1] = + DRV_STS_FUNC_ON; + } + } else if (gMtkWmtCtx.wmtHifConf.hifType == WMT_HIF_SDIO) { + if (gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_SDIO2] == DRV_STS_FUNC_ON) { + WMT_DBG_FUNC("SLOT_SDIO2 ready for WIFI\n"); + } else { + /* SDIO2 slot power shall be either turned on in STP init + * procedures already, or failed in STP init before. Here is + * the assert condition. + **/ + WMT_ERR_FUNC("turn on Wi-Fi SDIO2 but SDIO in FUNC_OFF state(0x%x)\n", + gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_SDIO2]); + osal_assert(0); + iRet = -4; + wmt_lib_wlan_lock_release(); + goto done; + } + } else { + WMT_ERR_FUNC("not implemented yet hifType: 0x%x, unspecified wifi_hif\n", + gMtkWmtCtx.wmtHifConf.hifType); + /* TODO: Wi-Fi/WMT uses other interfaces. NOT IMPLEMENTED YET! */ + } + + iRet = (*(gpWmtFuncOps[drvType]->func_on)) (gMtkWmtCtx.p_ic_ops, wmt_conf_get_cfg()); + if (iRet != 0) { + if (WMT_HIF_UART == gMtkWmtCtx.wmtHifConf.hifType) { + /*need to power SDIO off when Power on Wi-Fi fail, in case of power leakage and + * right SDIO power status maintain + */ + ctrlPa1 = WMT_SDIO_SLOT_SDIO1; + ctrlPa2 = 0; /* turn off SDIO1 slot */ + wmt_core_ctrl(WMT_CTRL_SDIO_HW, &ctrlPa1, &ctrlPa2); + /* does not need to check turn off result */ + gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_SDIO1] = DRV_STS_POWER_OFF; + } + gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_POWER_OFF; + } else + gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_FUNC_ON; + + /* wlan_lock must release before try_pwr_off */ + wmt_lib_wlan_lock_release(); + if (iRet) { + WMT_ERR_FUNC("WMT-CORE:type(0x%x) function on failed, ret(%d)\n", drvType, iRet); + /* FIX-ME:[Chaozhong Liang], Error handling? check subsystem state and do pwr off if necessary? */ + /* check all sub-func and do power off */ + wmt_lib_try_pwr_off(); + } + +done: + wmt_core_dump_func_state("AF FUNC ON"); + return iRet; +} + +static INT32 opfunc_wlan_remove(P_WMT_OP pWmtOp) +{ + ULONG ctrlPa1; + ULONG ctrlPa2; + INT32 iRet; + UINT32 drvType = pWmtOp->au4OpData[0]; + + iRet = wmt_lib_wlan_lock_aquire(); + atomic_set(&g_wifi_on_off_ready, 0); + if (iRet) { + WMT_ERR_FUNC("--->lock wlan_lock failed, iRet=%d\n", iRet); + return iRet; + } + + if (gMtkWmtCtx.eDrvStatus[drvType] != DRV_STS_FUNC_ON) { + WMT_WARN_FUNC("WMT-CORE: Fun(%d) DRV_STS_[0x%x] already non-FUN_ON in wmt_func_off\n", + drvType, gMtkWmtCtx.eDrvStatus[drvType]); + iRet = 0; + wmt_lib_wlan_lock_release(); + goto done; + } + + iRet = (*(gpWmtFuncOps[drvType]->func_off)) (gMtkWmtCtx.p_ic_ops, wmt_conf_get_cfg()); + + if (WMT_HIF_UART == gMtkWmtCtx.wmtHifConf.hifType) { + UINT32 iRet = 0; + + ctrlPa1 = WMT_SDIO_SLOT_SDIO1; + ctrlPa2 = 0; /* turn off SDIO1 slot */ + iRet = wmt_core_ctrl(WMT_CTRL_SDIO_HW, &ctrlPa1, &ctrlPa2); + if (iRet) { + WMT_ERR_FUNC("WMT-CORE: turn on SLOT_SDIO1 fail (%d)\n", + iRet); + osal_assert(0); + } + /* Anyway, turn SDIO1 state to POWER_OFF state */ + gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_SDIO1] = DRV_STS_POWER_OFF; + } + + gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_POWER_OFF; + + if (iRet) { + WMT_ERR_FUNC("WMT-CORE: type(0x%x) function off failed, ret(%d)\n", drvType, iRet); + osal_assert(0); + /* no matter subsystem function control fail or not, chip should be powered off + * when no subsystem is active + * return iRet; + */ + } + + /* wlan_lock must release before try_pwr_off */ + wmt_lib_wlan_lock_release(); + /* check all sub-func and do power off */ + wmt_lib_try_pwr_off(); + +done: + wmt_core_dump_func_state("AF FUNC OFF"); + return iRet; +} + +static INT32 opfunc_try_pwr_off(P_WMT_OP pWmtOp) +{ + INT32 iRet = 0; + UINT32 drvType = pWmtOp->au4OpData[0]; + + if (atomic_read(&g_wifi_on_off_ready) == 1) { + WMT_INFO_FUNC("wlan on/off procedure will be started, do not power off now.\n"); + return iRet; + } + + /* Why it can use try lock? + * Because only wmtd_worker_thread get wlan lock for wifi on/off in current design. + * It means it can decide whether to do Connsys power off after Wifi function on/off complete. + */ + if (wmt_lib_wlan_lock_trylock() == 0) { + WMT_INFO_FUNC("Can't lock wlan mutex which might be held by wlan on/off procedure.\n"); + return iRet; + } + + if ((gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT] == DRV_STS_POWER_OFF) && + (gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_GPS] == DRV_STS_POWER_OFF) && + (gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_GPSL5] == DRV_STS_POWER_OFF) && + (gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_FM] == DRV_STS_POWER_OFF) && + (gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI] == DRV_STS_POWER_OFF) && + (gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_LPBK] == DRV_STS_POWER_OFF) && + (gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_ANT] == DRV_STS_POWER_OFF) && + (gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_COREDUMP] == DRV_STS_POWER_OFF)) { + WMT_INFO_FUNC("WMT-CORE:Fun(%d) [POWER_OFF] and power down chip\n", drvType); + mtk_wcn_wmt_system_state_reset(); + iRet = opfunc_pwr_off(pWmtOp); + if (iRet) { + WMT_ERR_FUNC("WMT-CORE: wmt_pwr_off fail(%d) when turn off func(%d)\n", + iRet, drvType); + osal_assert(0); + } + } + wmt_lib_wlan_lock_release(); + return iRet; +} + +static INT32 opfunc_gps_mcu_ctrl(P_WMT_OP pWmtOp) +{ + INT32 iRet = -1; + UINT32 u4WrittenSize = 0; + UINT32 u4ReadSize = 0; + INT32 fgFail = -1; + PUINT8 p_tx_data_buf; + UINT32 tx_data_len; + PUINT8 p_rx_data_buf; + UINT32 rx_data_buf_len; + PUINT32 p_rx_data_len; + UINT8 WMT_GPS_MCU_CTRL_CMD[] = {0x01, 0x32, 0x00, 0x00}; + PUINT8 p_tx_buf = NULL; + PUINT8 p_rx_buf = NULL; + + p_tx_data_buf = (PUINT8)pWmtOp->au4OpData[0]; + tx_data_len = pWmtOp->au4OpData[1]; + p_rx_data_buf = (PUINT8)pWmtOp->au4OpData[2]; + rx_data_buf_len = pWmtOp->au4OpData[3]; + p_rx_data_len = (PINT32)(pWmtOp->au4OpData[4]); + + if ((!p_tx_data_buf) || (tx_data_len == 0) || (!p_rx_data_buf) || (rx_data_buf_len == 0)) { + pWmtOp->au4OpData[5] = -1; + WMT_ERR_FUNC("Parameter error!\n"); + return fgFail; + } + + p_tx_buf = osal_malloc(tx_data_len + osal_sizeof(WMT_GPS_MCU_CTRL_CMD)); + if (!p_tx_buf) { + pWmtOp->au4OpData[5] = -2; + WMT_ERR_FUNC("p_tx_buf alloc fail!\n"); + return fgFail; + } + + p_rx_buf = osal_malloc(rx_data_buf_len + osal_sizeof(WMT_GPS_MCU_CTRL_CMD)); + if (!p_rx_buf) { + osal_free(p_tx_buf); + pWmtOp->au4OpData[5] = -3; + WMT_ERR_FUNC("p_rx_buf alloc fail!\n"); + return fgFail; + } + + WMT_GPS_MCU_CTRL_CMD[2] = (tx_data_len & 0x000000ff); + WMT_GPS_MCU_CTRL_CMD[3] = ((tx_data_len & 0x0000ff00) >> 8); + osal_memcpy(p_tx_buf, WMT_GPS_MCU_CTRL_CMD, osal_sizeof(WMT_GPS_MCU_CTRL_CMD)); + osal_memcpy(p_tx_buf + osal_sizeof(WMT_GPS_MCU_CTRL_CMD), p_tx_data_buf, tx_data_len); + + do { + + iRet = wmt_core_tx(p_tx_buf, tx_data_len + osal_sizeof(WMT_GPS_MCU_CTRL_CMD), &u4WrittenSize, + MTK_WCN_BOOL_FALSE); + if (iRet || (u4WrittenSize != (tx_data_len + osal_sizeof(WMT_GPS_MCU_CTRL_CMD)))) { + WMT_ERR_FUNC("gps mcu ctrl tx CMD fail(%d),size(%d)\n", iRet, u4WrittenSize); + break; + } + + iRet = wmt_core_rx(p_rx_buf, rx_data_buf_len + osal_sizeof(WMT_GPS_MCU_CTRL_CMD), + &u4ReadSize); + if (iRet || (p_rx_buf[1] != WMT_GPS_MCU_CTRL_CMD[1])) { + WMT_ERR_FUNC("gps mcu ctrl rx EVT fail(%d),size(%d)\n", iRet, u4ReadSize); + break; + } + *p_rx_data_len = (p_rx_buf[2] | (p_rx_buf[3] << 8)); + osal_memcpy(p_rx_data_buf, p_rx_buf + osal_sizeof(WMT_GPS_MCU_CTRL_CMD), + *p_rx_data_len > rx_data_buf_len ? rx_data_buf_len : *p_rx_data_len); + + fgFail = 0; + } while (0); + + osal_free(p_tx_buf); + osal_free(p_rx_buf); + + return fgFail; +} + +P_WMT_GEN_CONF wmt_get_gen_conf_pointer(VOID) +{ + P_WMT_GEN_CONF pWmtGenConf = NULL; + + pWmtGenConf = wmt_conf_get_cfg(); + return pWmtGenConf; +} + +VOID wmt_core_set_blank_status(UINT32 on_off_flag) +{ + gMtkWmtCtx.wmtBlankStatus = on_off_flag; +} + +UINT32 wmt_core_get_blank_status(VOID) +{ + return gMtkWmtCtx.wmtBlankStatus; +} + +INT32 wmt_blank_status_ctrl(UINT32 on_off_flag) +{ + INT32 iRet = 0; +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH + UINT32 u4Res; + UINT32 evtLen; + UINT8 evtBuf[16] = { 0 }; + + WMT_BLANK_STATUS_CMD[5] = (on_off_flag) ? 0x1 : 0x0; + + /* send command */ + iRet = wmt_core_tx((PUINT8)WMT_BLANK_STATUS_CMD, osal_sizeof(WMT_BLANK_STATUS_CMD), &u4Res, + MTK_WCN_BOOL_FALSE); + + if (iRet || (u4Res != osal_sizeof(WMT_BLANK_STATUS_CMD))) { + WMT_ERR_FUNC("WMT-CORE: WMT_BLANK_STATUS_CMD iRet(%d) cmd len err(%d, %zu)\n", + (iRet == 0 ? -1 : iRet), u4Res, osal_sizeof(WMT_BLANK_STATUS_CMD)); + return iRet; + } + + evtLen = osal_sizeof(WMT_BLANK_STATUS_EVT); + iRet = wmt_core_rx(evtBuf, evtLen, &u4Res); + if (iRet || (u4Res != evtLen)) { + WMT_ERR_FUNC("WMT-CORE: read WMT_BLANK_STATUS_EVT fail(%d) len(%d, %d)\n", + iRet, u4Res, evtLen); + WMT_INFO_FUNC("buf:[%2X,%2X,%2X,%2X,%2X] evt:[%2X,%2X,%2X,%2X,%2X]\n", + evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], + WMT_BLANK_STATUS_EVT[0], WMT_BLANK_STATUS_EVT[1], + WMT_BLANK_STATUS_EVT[2], WMT_BLANK_STATUS_EVT[3], + WMT_BLANK_STATUS_EVT[4]); + } + else + wmt_lib_set_blank_status(WMT_BLANK_STATUS_CMD[5]); +#endif + return iRet; +} + +static INT32 opfunc_blank_status_ctrl(P_WMT_OP pWmtOp) +{ + return wmt_blank_status_ctrl(pWmtOp->au4OpData[0]); +} + +static INT32 opfunc_met_ctrl(P_WMT_OP pWmtOp) +{ + INT32 iRet; + UINT32 u4Res; + UINT32 evtLen; + UINT8 evtBuf[16] = { 0 }; + UINT32 value; + UINT8 WMT_MET_CTRL_CMD[] = { 0x01, 0x31, 0x05, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00}; + UINT8 WMT_MET_CTRL_EVT[] = { 0x02, 0x31, 0x01, 0x00, 0x00 }; + + value = pWmtOp->au4OpData[0]; + WMT_MET_CTRL_CMD[5] = (value & 0x000000ff); + WMT_MET_CTRL_CMD[6] = (value & 0x0000ff00) >> 8; + WMT_MET_CTRL_CMD[7] = (value & 0x00ff0000) >> 16; + WMT_MET_CTRL_CMD[8] = (value & 0xff000000) >> 24; + + /* send command */ + iRet = wmt_core_tx(WMT_MET_CTRL_CMD, sizeof(WMT_MET_CTRL_CMD), &u4Res, MTK_WCN_BOOL_FALSE); + if ((iRet) || (u4Res != sizeof(WMT_MET_CTRL_CMD))) { + WMT_ERR_FUNC("Tx MET_CTRL_CMD fail!(%d) len (%d, %zu)\n", iRet, u4Res, + sizeof(WMT_MET_CTRL_CMD)); + return -2; + } + + /* receive event */ + evtLen = sizeof(WMT_MET_CTRL_EVT); + iRet = wmt_core_rx(evtBuf, evtLen, &u4Res); + if ((iRet) || (u4Res != evtLen)) { + WMT_ERR_FUNC("Rx MET_CTRL_EVT fail!(%d) len(%d, %d)\n", iRet, u4Res, evtLen); + mtk_wcn_stp_dbg_dump_package(); + wmt_core_trigger_assert(); + return -3; + } + + return 0; +} + +static INT32 opfunc_get_consys_state(P_WMT_OP pWmtOp) +{ + INT32 ret = 0, i; + INT32 times = 0, slp_ms; + P_CONSYS_STATE_DMP_OP dmp_op = (P_CONSYS_STATE_DMP_OP)pWmtOp->au4OpData[0]; + ULONG ver = (ULONG)pWmtOp->au4OpData[1]; + + osal_lock_sleepable_lock(&dmp_op->lock); + if (dmp_op->status == WMT_DUMP_STATE_NONE + || dmp_op->version != ver) { + ret = -1; + goto done; + } + + /* WMT should be ON */ + if (gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] != DRV_STS_FUNC_ON) { + WMT_INFO_FUNC("WMT is not on"); + ret = -1; + goto done; + } + + if (mtk_wcn_consys_sleep_info_read_all_ctrl(&dmp_op->dmp_info.state) != 0) + ret = -1; + + /* Consys register should be readable */ + if (mtk_consys_check_reg_readable() == 0) { + WMT_INFO_FUNC("cr cannot readable"); + ret = -1; + goto done; + } + + times = dmp_op->times; + slp_ms = dmp_op->cpu_sleep_ms; + + /* dmp cpu_pcr */ + for (i = 0; i < times; i++) { + dmp_op->dmp_info.cpu_pcr[i] = wmt_plat_read_cpupcr(); + if (slp_ms > 0) + osal_sleep_ms(slp_ms); + } + + ret = mtk_consys_dump_osc_state(&dmp_op->dmp_info.state); + if (ret != MTK_WCN_BOOL_TRUE) + ret = -2; + + ret = mtk_wcn_consys_dump_gating_state(&dmp_op->dmp_info.state); + if (ret != MTK_WCN_BOOL_TRUE) + ret = -3; + +done: + osal_unlock_sleepable_lock(&dmp_op->lock); + return 0; +} diff --git a/drivers/misc/mediatek/connectivity/common/common_main/core/wmt_ctrl.c b/drivers/misc/mediatek/connectivity/common/common_main/core/wmt_ctrl.c new file mode 100644 index 0000000000000000000000000000000000000000..8f94dd002bd6c53d82347004a6e7696b2325d500 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/core/wmt_ctrl.c @@ -0,0 +1,1197 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +#ifdef DFT_TAG +#undef DFT_TAG +#endif +#define DFT_TAG "[WMT-CTRL]" + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include "osal_typedef.h" +#include "osal.h" + +#include "wmt_ctrl.h" +#include "wmt_core.h" +#include "wmt_lib.h" +#include "wmt_dev.h" +#include "wmt_plat.h" +#include "hif_sdio.h" +#include "stp_core.h" +#include "stp_dbg.h" +#include "wmt_ic.h" +#include "wmt_step.h" + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + + + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +/* moved to wmt_ctrl.h */ +/*static INT32 wmt_ctrl_tx_ex (UINT8 *pData, UINT32 size, UINT32 *writtenSize, MTK_WCN_BOOL bRawFlag);*/ + +static INT32 wmt_ctrl_stp_conf_ex(WMT_STP_CONF_TYPE type, UINT32 value); + +static INT32 wmt_ctrl_hw_pwr_off(P_WMT_CTRL_DATA); +static INT32 wmt_ctrl_hw_pwr_on(P_WMT_CTRL_DATA); +static INT32 wmt_ctrl_hw_rst(P_WMT_CTRL_DATA); +static INT32 wmt_ctrl_stp_close(P_WMT_CTRL_DATA); +static INT32 wmt_ctrl_stp_open(P_WMT_CTRL_DATA); +static INT32 wmt_ctrl_stp_conf(P_WMT_CTRL_DATA); +static INT32 wmt_ctrl_free_patch(P_WMT_CTRL_DATA); +static INT32 wmt_ctrl_get_patch(P_WMT_CTRL_DATA); +static INT32 wmt_ctrl_host_baudrate_set(P_WMT_CTRL_DATA); +static INT32 wmt_ctrl_sdio_hw(P_WMT_CTRL_DATA); +static INT32 wmt_ctrl_sdio_func(P_WMT_CTRL_DATA); +static INT32 wmt_ctrl_hwidver_set(P_WMT_CTRL_DATA); +static INT32 wmt_ctrl_stp_rst(P_WMT_CTRL_DATA); +static INT32 wmt_ctrl_get_wmt_conf(P_WMT_CTRL_DATA); +static INT32 wmt_ctrl_others(P_WMT_CTRL_DATA); +static INT32 wmt_ctrl_tx(P_WMT_CTRL_DATA); +static INT32 wmt_ctrl_rx(P_WMT_CTRL_DATA); +static INT32 wmt_ctrl_patch_search(P_WMT_CTRL_DATA); +static INT32 wmt_ctrl_crystal_triming_put(P_WMT_CTRL_DATA pWmtCtrlData); +static INT32 wmt_ctrl_crystal_triming_get(P_WMT_CTRL_DATA pWmtCtrlData); +static INT32 wmt_ctrl_hw_state_show(P_WMT_CTRL_DATA pWmtCtrlData); +static INT32 wmt_ctrl_get_patch_num(P_WMT_CTRL_DATA); +static INT32 wmt_ctrl_get_patch_info(P_WMT_CTRL_DATA); +static INT32 wmt_ctrl_rx_flush(P_WMT_CTRL_DATA); +static INT32 wmt_ctrl_soc_paldo_ctrl(P_WMT_CTRL_DATA); +static INT32 wmt_ctrl_soc_wakeup_consys(P_WMT_CTRL_DATA); +static INT32 wmt_ctrl_set_stp_dbg_info(P_WMT_CTRL_DATA); +static INT32 wmt_ctrl_bgw_desense_ctrl(P_WMT_CTRL_DATA); +static INT32 wmt_ctrl_trg_assert(P_WMT_CTRL_DATA); +static INT32 wmt_ctrl_evt_parser(P_WMT_CTRL_DATA pWmtCtrlData); +#if CFG_WMT_LTE_COEX_HANDLING +static INT32 wmt_ctrl_get_tdm_req_antsel(P_WMT_CTRL_DATA); +#endif + +static INT32 wmt_ctrl_gps_sync_set(P_WMT_CTRL_DATA pData); + +static INT32 wmt_ctrl_gps_lna_set(P_WMT_CTRL_DATA pData); + +static INT32 wmt_ctrl_get_patch_name(P_WMT_CTRL_DATA pWmtCtrlData); + +static INT32 wmt_ctrl_get_rom_patch_info(P_WMT_CTRL_DATA pWmtCtrlData); + +static INT32 wmt_ctrl_update_patch_version(P_WMT_CTRL_DATA); + +/* TODO: [FixMe][GeorgeKuo]: remove unused function */ +/*static INT32 wmt_ctrl_hwver_get(P_WMT_CTRL_DATA);*/ + + + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/* GeorgeKuo: Use designated initializers described in + * http://gcc.gnu.org/onlinedocs/gcc-4.0.4/gcc/Designated-Inits.html + */ +static const WMT_CTRL_FUNC wmt_ctrl_func[] = { + [WMT_CTRL_HW_PWR_OFF] = wmt_ctrl_hw_pwr_off, + [WMT_CTRL_HW_PWR_ON] = wmt_ctrl_hw_pwr_on, + [WMT_CTRL_HW_RST] = wmt_ctrl_hw_rst, + [WMT_CTRL_STP_CLOSE] = wmt_ctrl_stp_close, + [WMT_CTRL_STP_OPEN] = wmt_ctrl_stp_open, + [WMT_CTRL_STP_CONF] = wmt_ctrl_stp_conf, + [WMT_CTRL_FREE_PATCH] = wmt_ctrl_free_patch, + [WMT_CTRL_GET_PATCH] = wmt_ctrl_get_patch, + [WMT_CTRL_GET_PATCH_NAME] = wmt_ctrl_get_patch_name, + [WMT_CTRL_HOST_BAUDRATE_SET] = wmt_ctrl_host_baudrate_set, + [WMT_CTRL_SDIO_HW] = wmt_ctrl_sdio_hw, + [WMT_CTRL_SDIO_FUNC] = wmt_ctrl_sdio_func, + [WMT_CTRL_HWIDVER_SET] = wmt_ctrl_hwidver_set, + [WMT_CTRL_HWVER_GET] = NULL, /* TODO: [FixMe][GeorgeKuo]: remove unused function. */ + [WMT_CTRL_STP_RST] = wmt_ctrl_stp_rst, + [WMT_CTRL_GET_WMT_CONF] = wmt_ctrl_get_wmt_conf, + [WMT_CTRL_TX] = wmt_ctrl_tx, + [WMT_CTRL_RX] = wmt_ctrl_rx, + [WMT_CTRL_RX_FLUSH] = wmt_ctrl_rx_flush, + [WMT_CTRL_GPS_SYNC_SET] = wmt_ctrl_gps_sync_set, + [WMT_CTRL_GPS_LNA_SET] = wmt_ctrl_gps_lna_set, + [WMT_CTRL_PATCH_SEARCH] = wmt_ctrl_patch_search, + [WMT_CTRL_CRYSTAL_TRIMING_GET] = wmt_ctrl_crystal_triming_get, + [WMT_CTRL_CRYSTAL_TRIMING_PUT] = wmt_ctrl_crystal_triming_put, + [WMT_CTRL_HW_STATE_DUMP] = wmt_ctrl_hw_state_show, + [WMT_CTRL_GET_PATCH_NUM] = wmt_ctrl_get_patch_num, + [WMT_CTRL_GET_PATCH_INFO] = wmt_ctrl_get_patch_info, + [WMT_CTRL_SOC_PALDO_CTRL] = wmt_ctrl_soc_paldo_ctrl, + [WMT_CTRL_SOC_WAKEUP_CONSYS] = wmt_ctrl_soc_wakeup_consys, + [WMT_CTRL_SET_STP_DBG_INFO] = wmt_ctrl_set_stp_dbg_info, + [WMT_CTRL_BGW_DESENSE_CTRL] = wmt_ctrl_bgw_desense_ctrl, + [WMT_CTRL_TRG_ASSERT] = wmt_ctrl_trg_assert, + #if CFG_WMT_LTE_COEX_HANDLING + [WMT_CTRL_GET_TDM_REQ_ANTSEL] = wmt_ctrl_get_tdm_req_antsel, +#endif + [WMT_CTRL_EVT_PARSER] = wmt_ctrl_evt_parser, + [WMT_CTRL_GET_ROM_PATCH_INFO] = wmt_ctrl_get_rom_patch_info, + [WMT_CTRL_UPDATE_PATCH_VERSION] = wmt_ctrl_update_patch_version, + [WMT_CTRL_MAX] = wmt_ctrl_others, +}; + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +INT32 __weak mtk_wcn_consys_stp_btif_parser_wmt_evt(const PUINT8 str, UINT32 len) +{ + return 0; +} + +INT32 wmt_ctrl(P_WMT_CTRL_DATA pWmtCtrlData) +{ + UINT32 ctrlId = 0; + + if (pWmtCtrlData == NULL) { + osal_assert(0); + return -1; + } + + ctrlId = pWmtCtrlData->ctrlId; + /*1sanity check, including wmtCtrlId */ + if ((pWmtCtrlData == NULL) + || (ctrlId >= WMT_CTRL_MAX)) + /* || (ctrlId < WMT_CTRL_HW_PWR_OFF) ) [FixMe][GeorgeKuo]: useless comparison */ + { + osal_assert(pWmtCtrlData != NULL); + osal_assert(ctrlId < WMT_CTRL_MAX); + /* osal_assert(ctrlId >= WMT_CTRL_HW_PWR_OFF); [FixMe][GeorgeKuo]: useless comparison */ + return -2; + } + /* TODO: [FixMe][GeorgeKuo] do sanity check to const function table when init and skip checking here */ + if (wmt_ctrl_func[ctrlId]) { + /*call servicd handling API */ + return (*(wmt_ctrl_func[ctrlId])) (pWmtCtrlData); /* serviceHandlerPack[ctrlId].serviceHandler */ + } + osal_assert(wmt_ctrl_func[ctrlId] != NULL); + return -3; +} + +INT32 wmt_ctrl_tx(P_WMT_CTRL_DATA pWmtCtrlData /*UINT8 *pData, UINT32 size, UINT32 *writtenSize */) +{ + PUINT8 pData = (PUINT8) pWmtCtrlData->au4CtrlData[0]; + UINT32 size = pWmtCtrlData->au4CtrlData[1]; + PUINT32 writtenSize = (PUINT32) pWmtCtrlData->au4CtrlData[2]; + MTK_WCN_BOOL bRawFlag = pWmtCtrlData->au4CtrlData[3]; + + return wmt_ctrl_tx_ex(pData, size, writtenSize, bRawFlag); +} + +static VOID wmt_ctrl_show_sched_stats_log(P_OSAL_THREAD pThread, P_OSAL_THREAD_SCHEDSTATS pSchedstats) +{ + if ((pThread) && (pThread->pThread) && (pSchedstats)) + WMT_ERR_FUNC("WMT rx_timeout, pid[%d/%s] stats duration:%llums, sched(x%llu/r%llu/i%llu)\n", + pThread->pThread->pid, + pThread->threadName, + pSchedstats->time, + pSchedstats->exec, + pSchedstats->runnable, + pSchedstats->iowait); +} + +INT32 wmt_ctrl_rx(P_WMT_CTRL_DATA pWmtCtrlData /*UINT8 *pBuff, UINT32 buffLen, UINT32 *readSize */) +{ + P_DEV_WMT pDev = &gDevWmt; /* single instance */ + INT32 readLen; + INT32 waitRet = -1; + INT32 loopCnt = 1; + INT32 leftCnt; + PUINT8 pBuff = (PUINT8) pWmtCtrlData->au4CtrlData[0]; + UINT32 buffLen = pWmtCtrlData->au4CtrlData[1]; + PUINT32 readSize = (PUINT32) pWmtCtrlData->au4CtrlData[2]; + INT32 stpRxState; + INT32 extended = 0; + P_OSAL_THREAD p_rx_thread = NULL; + OSAL_THREAD_SCHEDSTATS schedstats; + + if (readSize) + *readSize = 0; + + /* sanity check */ + if (!buffLen) { + WMT_WARN_FUNC("buffLen = 0\n"); + osal_assert(buffLen); + return 0; + } + + if (!osal_test_bit(WMT_STAT_STP_OPEN, &pDev->state)) { + WMT_WARN_FUNC("state(0x%lx)\n", pDev->state.data); + osal_assert(osal_test_bit(WMT_STAT_STP_OPEN, &pDev->state)); + return -2; + } + if (wmt_lib_get_drv_status(WMTDRV_TYPE_WMT) == DRV_STS_FUNC_ON) + loopCnt = 4; + leftCnt = loopCnt; + + /* sanity ok, proceeding rx operation */ + readLen = mtk_wcn_stp_receive_data(pBuff, buffLen, WMT_TASK_INDX); + p_rx_thread = mtk_stp_rx_thread_get(); + osal_thread_sched_mark(p_rx_thread, &schedstats); + + while (readLen == 0 && leftCnt > 0) { /* got nothing, wait for STP's signal */ + /* if assert happen, do not wait for any signal again */ + if (mtk_wcn_stp_get_wmt_trg_assert() == 1 + && mtk_wcn_stp_is_wmt_last_close() == 0) + break; + pDev->rWmtRxWq.timeoutValue = WMT_LIB_RX_TIMEOUT/loopCnt; + waitRet = wmt_dev_rx_timeout(&pDev->rWmtRxWq); + if (waitRet == 0) { + leftCnt--; + /* dump btif_rxd's backtrace to check whether it is blocked or not */ + osal_dump_thread_state("btif_rxd"); + stp_dbg_poll_cpupcr(5, 1, 1); + if (!mtk_wcn_stp_is_sdio_mode()) + mtk_wcn_consys_stp_btif_logger_ctrl(BTIF_DUMP_BTIF_IRQ); + + if (leftCnt <= 0) { + if (extended == 0) { + stpRxState = mtk_stp_check_rx_has_pending_data(); + WMT_INFO_FUNC("check rx pending data(%d)\n", stpRxState); + readLen = mtk_wcn_stp_receive_data(pBuff, buffLen, WMT_TASK_INDX); + if (readLen > 0) { + WMT_INFO_FUNC("rx data received, rx done.\n"); + break; + } else if (stpRxState > 0) { + osal_thread_sched_unmark(p_rx_thread, &schedstats); + wmt_ctrl_show_sched_stats_log(p_rx_thread, &schedstats); + WMT_INFO_FUNC("stp has pending data, extend ~4 seconds\n"); + leftCnt = WMT_LIB_RX_EXTEND_TIMEOUT/pDev->rWmtRxWq.timeoutValue; + extended = 1; + osal_thread_sched_mark(p_rx_thread, &schedstats); + continue; + } + /* wmt is closed, device is shuting down */ + if (wmt_dev_is_close() || mtk_wcn_stp_is_wmt_last_close() == 1) { + leftCnt = 10; + continue; + } + } + + osal_thread_sched_unmark(p_rx_thread, &schedstats); + wmt_ctrl_show_sched_stats_log(p_rx_thread, &schedstats); + stp_dbg_poll_cpupcr(5, 1, 1); + WMT_ERR_FUNC("wmt_dev_rx_timeout: timeout,jiffies(%lu),timeoutvalue(%d)\n", + jiffies, pDev->rWmtRxWq.timeoutValue); + WMT_STEP_COMMAND_TIMEOUT_DO_ACTIONS_FUNC("STP RX timeout"); + + /* Reason number 44 means that stp data path still has data, + * possibly a driver problem + */ + if (stpRxState != 0) + wmt_lib_trigger_assert(WMTDRV_TYPE_WMT, 44); + return -1; + } + } else if (waitRet < 0) { + WMT_WARN_FUNC("wmt_dev_rx_timeout: interrupted by signal (%d)\n", waitRet); + WMT_STEP_COMMAND_TIMEOUT_DO_ACTIONS_FUNC("STP RX timeout"); + return waitRet; + } + readLen = mtk_wcn_stp_receive_data(pBuff, buffLen, WMT_TASK_INDX); + + if (readLen == 0) + WMT_DBG_FUNC("wmt_ctrl_rx be signaled, but no rx data(%d)\n", waitRet); + WMT_DBG_FUNC("stp_receive_data: readLen(%d)\n", readLen); + } + + if (readSize) + *readSize = readLen; + + return 0; +} + + +INT32 +wmt_ctrl_tx_ex(const PUINT8 pData, + const UINT32 size, PUINT32 writtenSize, const MTK_WCN_BOOL bRawFlag) +{ + P_DEV_WMT pDev = &gDevWmt; /* single instance */ + INT32 iRet; + + if (writtenSize != NULL) + *writtenSize = 0; + + /* sanity check */ + if (size == 0) { + WMT_WARN_FUNC("size to tx is 0\n"); + osal_assert(size); + return -1; + } + + /* if STP is not enabled yet, can't use this function. Use tx_raw instead */ + if (!osal_test_bit(WMT_STAT_STP_OPEN, &pDev->state) || + !osal_test_bit(WMT_STAT_STP_EN, &pDev->state)) { + WMT_ERR_FUNC("wmt state(0x%lx)\n", pDev->state.data); + osal_assert(osal_test_bit(WMT_STAT_STP_EN, &pDev->state)); + osal_assert(osal_test_bit(WMT_STAT_STP_OPEN, &pDev->state)); + iRet = -2; + if (writtenSize) + *writtenSize = iRet; + return iRet; + } + + /* sanity ok, proceeding tx operation */ + /*retval = mtk_wcn_stp_send_data(data, size, WMTDRV_TYPE_WMT); */ + mtk_wcn_stp_flush_rx_queue(WMT_TASK_INDX); + if (bRawFlag) + iRet = mtk_wcn_stp_send_data_raw(pData, size, WMT_TASK_INDX); + else + iRet = mtk_wcn_stp_send_data(pData, size, WMT_TASK_INDX); + + if (iRet != size) { + WMT_WARN_FUNC("write(%d) written(%d)\n", size, iRet); + osal_assert(iRet == size); + } + + if (writtenSize) + *writtenSize = iRet; + + return 0; + +} + +INT32 wmt_ctrl_rx_flush(P_WMT_CTRL_DATA pWmtCtrlData) +{ + UINT32 type = pWmtCtrlData->au4CtrlData[0]; + + WMT_INFO_FUNC("flush rx %d queue\n", type); + mtk_wcn_stp_flush_rx_queue(type); + + return 0; +} + + +INT32 wmt_ctrl_hw_pwr_off(P_WMT_CTRL_DATA pWmtCtrlData) +{ + INT32 iret; + /*psm should be disabled before wmt_ic_deinit*/ + P_DEV_WMT pDev = &gDevWmt; + + if (osal_test_and_clear_bit(WMT_STAT_PWR, &pDev->state)) { + WMT_DBG_FUNC("on->off\n"); + iret = wmt_plat_pwr_ctrl(FUNC_OFF); + } else { + WMT_WARN_FUNC("already off\n"); + iret = 0; + } + + return iret; +} + +INT32 wmt_ctrl_hw_pwr_on(P_WMT_CTRL_DATA pWmtCtrlData) +{ + INT32 iret; + /*psm should be enabled right after wmt_ic_init */ + P_DEV_WMT pDev = &gDevWmt; + + if (osal_test_and_set_bit(WMT_STAT_PWR, &pDev->state)) { + WMT_WARN_FUNC("already on\n"); + iret = 0; + } else { + WMT_DBG_FUNC("off->on\n"); + iret = wmt_plat_pwr_ctrl(FUNC_ON); + } + + return iret; +} + +INT32 wmt_ctrl_ul_cmd(P_DEV_WMT pWmtDev, const PUINT8 pCmdStr) +{ + INT32 waitRet = -1; + P_OSAL_SIGNAL pCmdSignal; + P_OSAL_EVENT pCmdReq; + + if (osal_test_and_set_bit(WMT_STAT_CMD, &pWmtDev->state)) { + WMT_WARN_FUNC("cmd buf is occupied by (%s)\n", pWmtDev->cCmd); + return -1; + } + + /* indicate baud rate change to user space app */ +#if 0 + INIT_COMPLETION(pWmtDev->cmd_comp); + pWmtDev->cmd_result = -1; + strncpy(pWmtDev->cCmd, pCmdStr, NAME_MAX); + pWmtDev->cCmd[NAME_MAX] = '\0'; + wake_up_interruptible(&pWmtDev->cmd_wq); +#endif + + pCmdSignal = &pWmtDev->cmdResp; + osal_signal_init(pCmdSignal); + pCmdSignal->timeoutValue = 6000; + osal_strncpy(pWmtDev->cCmd, pCmdStr, NAME_MAX); + pWmtDev->cCmd[NAME_MAX] = '\0'; + + pCmdReq = &pWmtDev->cmdReq; + + osal_trigger_event(&pWmtDev->cmdReq); + WMT_DBG_FUNC("str(%s) request ok\n", pCmdStr); + +/* waitRet = wait_for_completion_interruptible_timeout(&pWmtDev->cmd_comp, msecs_to_jiffies(2000)); */ + waitRet = osal_wait_for_signal_timeout(pCmdSignal, NULL); + WMT_LOUD_FUNC("wait signal iRet:%d\n", waitRet); + if (waitRet == 0) { + WMT_ERR_FUNC("wait signal timeout\n"); + return -2; + } + + WMT_DBG_FUNC("str(%s) result(%d)\n", pCmdStr, pWmtDev->cmdResult); + + return pWmtDev->cmdResult; +} + +INT32 wmt_ctrl_hw_rst(P_WMT_CTRL_DATA pWmtCtrlData) +{ + wmt_plat_pwr_ctrl(FUNC_RST); + return 0; +} + +INT32 wmt_ctrl_hw_state_show(P_WMT_CTRL_DATA pWmtCtrlData) +{ + wmt_plat_pwr_ctrl(FUNC_STAT); + return 0; +} + +INT32 wmt_ctrl_stp_close(P_WMT_CTRL_DATA pWmtCtrlData) +{ + P_DEV_WMT pDev = &gDevWmt; /* single instance */ + INT32 iRet = 0; + UINT8 cmdStr[NAME_MAX + 1] = { 0 }; + /* un-register to STP-core for rx */ + + iRet = mtk_wcn_stp_register_event_cb(WMT_TASK_INDX, NULL); /* mtk_wcn_stp_register_event_cb */ + if (iRet) { + WMT_WARN_FUNC("stp_reg cb unregister fail(%d)\n", iRet); + return -1; + } + + if (pDev->rWmtHifConf.hifType == WMT_HIF_UART) { + + osal_snprintf(cmdStr, NAME_MAX, "close_stp"); + + iRet = wmt_ctrl_ul_cmd(pDev, cmdStr); + if (iRet) { + WMT_WARN_FUNC("wmt_ctrl_ul_cmd fail(%d)\n", iRet); + return -2; + } + } + if (pDev->rWmtHifConf.hifType == WMT_HIF_BTIF) { + /*un-register rxcb to btif */ + iRet = mtk_wcn_stp_rxcb_register(NULL); + if (iRet) { + WMT_WARN_FUNC("mtk_wcn_stp_rxcb_unregister fail(%d)\n", iRet); + return -2; + } + + iRet = mtk_wcn_stp_close_btif(); + if (iRet) { + WMT_WARN_FUNC("mtk_wcn_stp_close_btif fail(%d)\n", iRet); + return -3; + } + } + + osal_clear_bit(WMT_STAT_STP_OPEN, &pDev->state); + + return 0; +} + +INT32 wmt_ctrl_stp_open(P_WMT_CTRL_DATA pWmtCtrlData) +{ + P_DEV_WMT pDev = &gDevWmt; /* single instance */ + INT32 iRet; + UINT8 cmdStr[NAME_MAX + 1] = { 0 }; + + if (pDev->rWmtHifConf.hifType == WMT_HIF_UART) { + osal_snprintf(cmdStr, NAME_MAX, "open_stp"); + iRet = wmt_ctrl_ul_cmd(pDev, cmdStr); + if (iRet) { + WMT_WARN_FUNC("wmt_ctrl_ul_cmd fail(%d)\n", iRet); + return -1; + } + } + if (pDev->rWmtHifConf.hifType == WMT_HIF_BTIF) { + iRet = mtk_wcn_stp_open_btif(); + if (iRet) { + WMT_WARN_FUNC("mtk_wcn_stp_open_btif fail(%d)\n", iRet); + return -1; + } + + /*register stp rx call back to btif */ + iRet = mtk_wcn_stp_rxcb_register((MTK_WCN_BTIF_RX_CB)mtk_wcn_stp_parser_data); + if (iRet) { + WMT_WARN_FUNC("mtk_wcn_stp_rxcb_register fail(%d)\n", iRet); + return -2; + } + } + /* register to STP-core for rx */ + /* mtk_wcn_stp_register_event_cb */ + iRet = mtk_wcn_stp_register_event_cb(WMT_TASK_INDX, wmt_dev_rx_event_cb); + if (iRet) { + WMT_WARN_FUNC("stp_reg cb fail(%d)\n", iRet); + return -2; + } + + osal_set_bit(WMT_STAT_STP_OPEN, &pDev->state); +#if 0 + iRet = mtk_wcn_stp_lpbk_ctrl(1); +#endif + + return 0; +} + + +INT32 wmt_ctrl_patch_search(P_WMT_CTRL_DATA pWmtCtrlData) +{ + P_DEV_WMT pDev = &gDevWmt; /* single instance */ + INT32 iRet; + UINT8 cmdStr[NAME_MAX + 1] = { 0 }; + + osal_snprintf(cmdStr, NAME_MAX, "srh_patch"); + iRet = wmt_ctrl_ul_cmd(pDev, cmdStr); + if (iRet) { + WMT_WARN_FUNC("wmt_ctrl_ul_cmd fail(%d)\n", iRet); + return -1; + } + return 0; +} + + +INT32 wmt_ctrl_get_patch_num(P_WMT_CTRL_DATA pWmtCtrlData) +{ + P_DEV_WMT pDev = &gDevWmt; /* single instance */ + + pWmtCtrlData->au4CtrlData[0] = pDev->patchNum; + return 0; +} + + +INT32 wmt_ctrl_get_patch_info(P_WMT_CTRL_DATA pWmtCtrlData) +{ + P_DEV_WMT pDev = &gDevWmt; /* single instance */ + UINT32 downLoadSeq = 0; + P_WMT_PATCH_INFO pPatchinfo = NULL; + PUINT8 pNbuf = NULL; + PUINT8 pAbuf = NULL; + + if (pDev->pWmtPatchInfo == NULL) { + WMT_ERR_FUNC("pWmtPatchInfo is NULL\n"); + return -1; + } + + downLoadSeq = pWmtCtrlData->au4CtrlData[0]; + WMT_DBG_FUNC("download seq is %d\n", downLoadSeq); + + pPatchinfo = pDev->pWmtPatchInfo + downLoadSeq - 1; + pNbuf = (PUINT8) pWmtCtrlData->au4CtrlData[1]; + pAbuf = (PUINT8) pWmtCtrlData->au4CtrlData[2]; + if (pPatchinfo) { + osal_memcpy(pNbuf, pPatchinfo->patchName, osal_sizeof(pPatchinfo->patchName)); + osal_memcpy(pAbuf, pPatchinfo->addRess, osal_sizeof(pPatchinfo->addRess)); + WMT_DBG_FUNC("get 4 address bytes is 0x%2x,0x%2x,0x%2x,0x%2x", pAbuf[0], pAbuf[1], + pAbuf[2], pAbuf[3]); + } else + WMT_ERR_FUNC("NULL patchinfo pointer\n"); + + return 0; +} + +INT32 wmt_ctrl_get_rom_patch_info(P_WMT_CTRL_DATA pWmtCtrlData) +{ + P_DEV_WMT pDev = &gDevWmt; /* single instance */ + UINT32 type = 0; + struct wmt_rom_patch_info *pPatchinfo = NULL; + PUINT8 pNbuf = NULL; + PUINT8 pAbuf = NULL; + INT32 ret = 0; + UINT8 cmdStr[NAME_MAX + 1] = { 0 }; + + type = pWmtCtrlData->au4CtrlData[0]; + WMT_DBG_FUNC("rom patch type is %d\n", type); + pDev->ip_ver = pWmtCtrlData->au4CtrlData[3]; + pDev->fw_ver = pWmtCtrlData->au4CtrlData[4]; + WMT_DBG_FUNC("ip version is [%x] [%x]\n", pDev->ip_ver, pDev->fw_ver); + + if (!pDev->pWmtRomPatchInfo[WMTDRV_TYPE_WMT]) { + osal_snprintf(cmdStr, NAME_MAX, "srh_rom_patch"); + ret = wmt_ctrl_ul_cmd(pDev, cmdStr); + if (ret) { + WMT_WARN_FUNC("wmt_ctrl_ul_cmd fail(%d)\n", ret); + return -1; + } + } + + if (type < WMTDRV_TYPE_ANT) { + pPatchinfo = pDev->pWmtRomPatchInfo[type]; + pNbuf = (PUINT8) pWmtCtrlData->au4CtrlData[1]; + pAbuf = (PUINT8) pWmtCtrlData->au4CtrlData[2]; + if (pPatchinfo) { + osal_memcpy(pNbuf, pPatchinfo->patchName, osal_sizeof(pPatchinfo->patchName)); + osal_memcpy(pAbuf, pPatchinfo->addRess, osal_sizeof(pPatchinfo->addRess)); + WMT_DBG_FUNC("get 4 address bytes is 0x%2x,0x%2x,0x%2x,0x%2x", + pAbuf[0], pAbuf[1], pAbuf[2], pAbuf[3]); + } else { + WMT_ERR_FUNC("NULL patchinfo pointer\n"); + ret = 1; + } + } else { + WMT_ERR_FUNC("rom patch type %d is error!\n", type); + ret = -1; + } + + return ret; +} + +INT32 wmt_ctrl_update_patch_version(P_WMT_CTRL_DATA pWmtCtrlData) +{ + P_DEV_WMT pDev = &gDevWmt; /* single instance */ + INT32 iRet; + UINT8 cmdStr[NAME_MAX + 1] = { 0 }; + + osal_snprintf(cmdStr, NAME_MAX, "update_patch_version"); + iRet = wmt_ctrl_ul_cmd(pDev, cmdStr); + if (iRet) { + WMT_WARN_FUNC("wmt_ctrl_ul_cmd fail(%d)\n", iRet); + return -1; + } + return 0; +} + +INT32 wmt_ctrl_soc_paldo_ctrl(P_WMT_CTRL_DATA pWmtCtrlData) +{ + INT32 iRet = 0; + ENUM_PALDO_TYPE ept = pWmtCtrlData->au4CtrlData[0]; + ENUM_PALDO_OP epo = pWmtCtrlData->au4CtrlData[1]; + + WMT_DBG_FUNC("ept(%d),epo(%d)\n", ept, epo); + iRet = wmt_plat_soc_paldo_ctrl(ept, epo); + if (iRet) { + if (ept == PMIC_CHIPID_PALDO) { + /* special handling for PMIC CHIPID */ + pWmtCtrlData->au4CtrlData[2] = iRet; + } else { + /* for other PA handling */ + WMT_ERR_FUNC("soc palod ctrl fail(%d)\n", iRet); + } + } + + return iRet; +} + +INT32 wmt_ctrl_soc_wakeup_consys(P_WMT_CTRL_DATA pWmtCtrlData) +{ + INT32 iRet = 0; + + iRet = mtk_wcn_stp_wakeup_consys(); + if (iRet) + WMT_ERR_FUNC("soc palod ctrl fail(%d)\n", iRet); + + return iRet; +} + +static INT32 wmt_ctrl_bgw_desense_ctrl(P_WMT_CTRL_DATA pWmtCtrlData) +{ + UINT32 cmd = pWmtCtrlData->au4CtrlData[0]; + + WMT_INFO_FUNC("wmt-ctrl:send native cmd(%d)\n", cmd); + wmt_dev_send_cmd_to_daemon(cmd); + + return 0; +} + +#if CFG_WMT_LTE_COEX_HANDLING +static INT32 wmt_ctrl_get_tdm_req_antsel(P_WMT_CTRL_DATA pWmtCtrlData) +{ + INT32 antsel_index = wmt_plat_get_tdm_antsel_index(); + + if (antsel_index >= 0) + pWmtCtrlData->au4CtrlData[0] = antsel_index; + else + pWmtCtrlData->au4CtrlData[0] = 0xff; + + WMT_INFO_FUNC("get tdm req antsel index is %d\n", antsel_index); + + return 0; +} +#endif + +static INT32 wmt_ctrl_evt_parser(P_WMT_CTRL_DATA pWmtCtrlData) +{ + INT32 ret = -1; + UINT32 evt_idx = (UINT32) pWmtCtrlData->au4CtrlData[0]; + UINT8 *p_buf = NULL; + + static UINT8 sleep_evt[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x01 }; + static UINT8 wakeup_evt[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x03 }; + static UINT8 hostawake_evt[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x02 }; + static UINT8 *evt_array[] = { sleep_evt, wakeup_evt, hostawake_evt }; + + p_buf = evt_array[evt_idx - 1]; + + WMT_INFO_FUNC("evt index:%d,p_buf:%p\n", evt_idx, p_buf); + + ret = mtk_wcn_consys_stp_btif_parser_wmt_evt(p_buf, 6); + if (ret == 1) { + WMT_INFO_FUNC("parser wmt evt from BTIF buf is OK\n"); + return 0; + } + WMT_ERR_FUNC("parser wmt evt from BTIF buf fail(%d)\n", ret); + return -1; +} + +INT32 wmt_ctrl_stp_conf_ex(WMT_STP_CONF_TYPE type, UINT32 value) +{ + INT32 iRet = -1; + + switch (type) { + case WMT_STP_CONF_EN: + iRet = mtk_wcn_stp_enable(value); + break; + + case WMT_STP_CONF_RDY: + iRet = mtk_wcn_stp_ready(value); + break; + + case WMT_STP_CONF_MODE: + mtk_wcn_stp_set_mode(value); + iRet = 0; + break; + + default: + WMT_WARN_FUNC("invalid type(%d) value(%d)\n", type, value); + break; + } + return iRet; +} + + +INT32 wmt_ctrl_stp_conf(P_WMT_CTRL_DATA pWmtCtrlData) +{ + INT32 iRet = -1; + P_DEV_WMT pDev = &gDevWmt; /* single instance */ + UINT32 type; + UINT32 value; + + if (!osal_test_bit(WMT_STAT_STP_OPEN, &pDev->state)) { + WMT_WARN_FUNC("CTRL_STP_ENABLE but invalid Handle of WmtStp\n"); + return -1; + } + + type = pWmtCtrlData->au4CtrlData[0]; + value = pWmtCtrlData->au4CtrlData[1]; + iRet = wmt_ctrl_stp_conf_ex(type, value); + + if (!iRet) { + if (type == WMT_STP_CONF_EN) { + if (value) { + osal_set_bit(WMT_STAT_STP_EN, &pDev->state); + WMT_DBG_FUNC("enable STP\n"); + } else { + osal_clear_bit(WMT_STAT_STP_EN, &pDev->state); + WMT_DBG_FUNC("disable STP\n"); + } + } + if (type == WMT_STP_CONF_RDY) { + if (value) { + osal_set_bit(WMT_STAT_STP_RDY, &pDev->state); + WMT_DBG_FUNC("STP ready\n"); + } else { + osal_clear_bit(WMT_STAT_STP_RDY, &pDev->state); + WMT_DBG_FUNC("STP not ready\n"); + } + } + } + + return iRet; +} + + +INT32 wmt_ctrl_free_patch(P_WMT_CTRL_DATA pWmtCtrlData) +{ + UINT32 patchSeq = pWmtCtrlData->au4CtrlData[0]; + + WMT_DBG_FUNC("BF free patch, gDevWmt.pPatch(%p)\n", gDevWmt.pPatch); + if (gDevWmt.pPatch != NULL) + wmt_dev_patch_put((osal_firmware **) &(gDevWmt.pPatch)); + WMT_DBG_FUNC("AF free patch, gDevWmt.pPatch(%p)\n", gDevWmt.pPatch); + if (patchSeq == gDevWmt.patchNum) + WMT_DBG_FUNC("the %d patch has been download\n", patchSeq); + return 0; +} + +INT32 wmt_ctrl_get_patch_name(P_WMT_CTRL_DATA pWmtCtrlData) +{ + PUINT8 pBuf = (PUINT8) pWmtCtrlData->au4CtrlData[0]; + + osal_memcpy(pBuf, gDevWmt.cPatchName, osal_sizeof(gDevWmt.cPatchName)); + return 0; +} + +INT32 wmt_ctrl_crystal_triming_put(P_WMT_CTRL_DATA pWmtCtrlData) +{ + WMT_DBG_FUNC("BF free patch, gDevWmt.pPatch(%p)\n", gDevWmt.pPatch); + if (gDevWmt.pNvram != NULL) + wmt_dev_patch_put((osal_firmware **) &(gDevWmt.pNvram)); + WMT_DBG_FUNC("AF free patch, gDevWmt.pNvram(%p)\n", gDevWmt.pNvram); + return 0; +} + + +INT32 wmt_ctrl_crystal_triming_get(P_WMT_CTRL_DATA pWmtCtrlData) +{ + INT32 iRet = 0x0; + PUINT8 pFileName = (PUINT8) pWmtCtrlData->au4CtrlData[0]; + PPUINT8 ppBuf = (PPUINT8) pWmtCtrlData->au4CtrlData[1]; + PUINT32 pSize = (PUINT32) pWmtCtrlData->au4CtrlData[2]; + osal_firmware *pNvram = NULL; + + if ((pFileName == NULL) || (pSize == NULL)) { + WMT_ERR_FUNC("parameter error, pFileName(%p), pSize(%p)\n", pFileName, pSize); + iRet = -1; + return iRet; + } + if (wmt_dev_patch_get(pFileName, &pNvram) == 0) { + *ppBuf = (PUINT8)(pNvram)->data; + *pSize = (pNvram)->size; + gDevWmt.pNvram = pNvram; + return 0; + } + return -1; +} + + +INT32 wmt_ctrl_get_patch(P_WMT_CTRL_DATA pWmtCtrlData) +{ + PUINT8 pFullPatchName = NULL; + PUINT8 pDefPatchName = NULL; + PPUINT8 ppBuf = (PPUINT8) pWmtCtrlData->au4CtrlData[2]; + PUINT32 pSize = (PUINT32) pWmtCtrlData->au4CtrlData[3]; + osal_firmware *pPatch = NULL; + + pFullPatchName = (PUINT8) pWmtCtrlData->au4CtrlData[1]; + WMT_DBG_FUNC("BF get patch, pPatch(%p)\n", pPatch); + if ((pFullPatchName != NULL) + && (wmt_dev_patch_get(pFullPatchName, &pPatch) == 0)) { + /*get full name patch success */ + WMT_DBG_FUNC("get full patch name(%s) buf(0x%p) size(%zu)\n", + pFullPatchName, (pPatch)->data, (pPatch)->size); + WMT_DBG_FUNC("AF get patch, pPatch(%p)\n", pPatch); + *ppBuf = (PUINT8)(pPatch)->data; + *pSize = (pPatch)->size; + gDevWmt.pPatch = pPatch; + return 0; + } + + pDefPatchName = (PUINT8) pWmtCtrlData->au4CtrlData[0]; + if ((pDefPatchName != NULL) + && (wmt_dev_patch_get(pDefPatchName, &pPatch) == 0)) { + WMT_DBG_FUNC("get def patch name(%s) buf(0x%p) size(%zu)\n", + pDefPatchName, (pPatch)->data, (pPatch)->size); + WMT_DBG_FUNC("AF get patch, pPatch(%p)\n", pPatch); + /*get full name patch success */ + *ppBuf = (PUINT8)(pPatch)->data; + *pSize = (pPatch)->size; + gDevWmt.pPatch = pPatch; + return 0; + } + return -1; + +} + +INT32 wmt_ctrl_host_baudrate_set(P_WMT_CTRL_DATA pWmtCtrlData) +{ + INT32 iRet = -1; + INT8 cmdStr[NAME_MAX + 1] = { 0 }; + UINT32 u4Baudrate = pWmtCtrlData->au4CtrlData[0]; + UINT32 u4FlowCtrl = pWmtCtrlData->au4CtrlData[1]; + + WMT_DBG_FUNC("baud(%d), flowctrl(%d)\n", u4Baudrate, u4FlowCtrl); + + if (osal_test_bit(WMT_STAT_STP_OPEN, &gDevWmt.state)) { + osal_snprintf(cmdStr, NAME_MAX, "baud_%d_%d", u4Baudrate, u4FlowCtrl); + iRet = wmt_ctrl_ul_cmd(&gDevWmt, cmdStr); + if (iRet) + WMT_WARN_FUNC("CTRL_BAUDRATE baud(%d), flowctrl(%zu) fail(%d)\n", + u4Baudrate, pWmtCtrlData->au4CtrlData[1], iRet); + else + WMT_DBG_FUNC("CTRL_BAUDRATE baud(%d), flowctrl(%d) ok\n", + u4Baudrate, u4FlowCtrl); + } else + WMT_INFO_FUNC("CTRL_BAUDRATE but invalid Handle of WmtStp\n"); + return iRet; +} + +INT32 wmt_ctrl_sdio_hw(P_WMT_CTRL_DATA pWmtCtrlData) +{ + INT32 iRet = 0; + UINT32 statBit = WMT_STAT_SDIO1_ON; + P_DEV_WMT pDev = &gDevWmt; /* single instance */ + + WMT_SDIO_SLOT_NUM sdioSlotNum = pWmtCtrlData->au4CtrlData[0]; + ENUM_FUNC_STATE funcState = pWmtCtrlData->au4CtrlData[1]; + + if ((sdioSlotNum == WMT_SDIO_SLOT_INVALID) + || (sdioSlotNum >= WMT_SDIO_SLOT_MAX)) { + WMT_WARN_FUNC("CTRL_SDIO_SLOT(%d) but invalid slot num\n", sdioSlotNum); + return -1; + } + + WMT_DBG_FUNC("WMT_CTRL_SDIO_HW (0x%x, %d)\n", sdioSlotNum, funcState); + + if (sdioSlotNum == WMT_SDIO_SLOT_SDIO2) + statBit = WMT_STAT_SDIO2_ON; + + if (funcState) { + if (osal_test_and_set_bit(statBit, &pDev->state)) { + WMT_WARN_FUNC("CTRL_SDIO_SLOT slotNum(%d) already ON\n", sdioSlotNum); + /* still return 0 */ + iRet = 0; + } else + iRet = wmt_plat_sdio_ctrl(sdioSlotNum, FUNC_ON); + } else { + if (osal_test_and_clear_bit(statBit, &pDev->state)) + iRet = wmt_plat_sdio_ctrl(sdioSlotNum, FUNC_OFF); + else { + WMT_WARN_FUNC("CTRL_SDIO_SLOT slotNum(%d) already OFF\n", sdioSlotNum); + /* still return 0 */ + iRet = 0; + } + } + + return iRet; +} + +INT32 wmt_ctrl_sdio_func(P_WMT_CTRL_DATA pWmtCtrlData) +{ + INT32 iRet = -1; + UINT32 statBit = WMT_STAT_SDIO_WIFI_ON; + INT32 retry = 10; + P_DEV_WMT pDev = &gDevWmt; /* single instance */ + WMT_SDIO_FUNC_TYPE sdioFuncType = pWmtCtrlData->au4CtrlData[0]; + UINT32 u4On = pWmtCtrlData->au4CtrlData[1]; + + if (sdioFuncType >= WMT_SDIO_FUNC_MAX) { + WMT_ERR_FUNC("CTRL_SDIO_FUNC, invalid func type (%d)\n", sdioFuncType); + return -1; + } + + if (sdioFuncType == WMT_SDIO_FUNC_STP) + statBit = WMT_STAT_SDIO_STP_ON; + + if (u4On) { + if (osal_test_bit(statBit, &pDev->state)) { + WMT_WARN_FUNC("CTRL_SDIO_FUNC(%d) but already ON\n", sdioFuncType); + iRet = 0; + } else { + while (retry-- > 0 && iRet != 0) { + if (iRet) { + /* sleep 150ms before sdio slot ON ready */ + osal_sleep_ms(150); + } + iRet = + mtk_wcn_hif_sdio_wmt_control(sdioFuncType, MTK_WCN_BOOL_TRUE); + if (iRet == HIF_SDIO_ERR_NOT_PROBED) { + /* not probed case, retry */ + continue; + } else if (iRet == HIF_SDIO_ERR_CLT_NOT_REG) { + /* For WiFi, client not reg yet, no need to retry, + * WiFi function can work any time when wlan.ko is insert into system + */ + iRet = 0; + } else { + /* other fail cases, stop */ + break; + } + } + if (iRet) + WMT_ERR_FUNC + ("mtk_wcn_hif_sdio_wmt_control(%d, TRUE) fail(%d) retry(%d)\n", + sdioFuncType, iRet, retry); + else + osal_set_bit(statBit, &pDev->state); + } + } else { + if (osal_test_bit(statBit, &pDev->state)) { + iRet = mtk_wcn_hif_sdio_wmt_control(sdioFuncType, MTK_WCN_BOOL_FALSE); + if (iRet) + WMT_ERR_FUNC("mtk_wcn_hif_sdio_wmt_control(%d, FALSE) fail(%d)\n", + sdioFuncType, iRet); + /*any way, set to OFF state */ + osal_clear_bit(statBit, &pDev->state); + } else { + WMT_WARN_FUNC("CTRL_SDIO_FUNC(%d) but already OFF\n", sdioFuncType); + iRet = 0; + } + } + + return iRet; +} + +#if 0 +/* TODO: [FixMe][GeorgeKuo]: remove unused function. get hwver from core is not needed. */ +INT32 wmt_ctrl_hwver_get(P_WMT_CTRL_DATA pWmtCtrlData) +{ + P_DEV_WMT pDev = &gDevWmt; /* single instance */ + + return 0; +} +#endif + +INT32 wmt_ctrl_hwidver_set(P_WMT_CTRL_DATA pWmtCtrlData) +{ + P_DEV_WMT pDev = &gDevWmt; /* single instance */ + + /* input sanity check is done in wmt_ctrl() */ + pDev->chip_id = (pWmtCtrlData->au4CtrlData[0] & 0xFFFF0000) >> 16; + pDev->hw_ver = pWmtCtrlData->au4CtrlData[0] & 0x0000FFFF; + pDev->fw_ver = pWmtCtrlData->au4CtrlData[1] & 0x0000FFFF; + + return 0; +} + +static INT32 wmt_ctrl_gps_sync_set(P_WMT_CTRL_DATA pData) +{ + INT32 iret; + + WMT_DBG_FUNC("ctrl GPS_SYNC(%d)\n", + (pData->au4CtrlData[0] == 0) ? PIN_STA_DEINIT : PIN_STA_MUX); + iret = + wmt_plat_gpio_ctrl(PIN_GPS_SYNC, + (pData->au4CtrlData[0] == 0) ? PIN_STA_DEINIT : PIN_STA_MUX); + + if (iret) + WMT_WARN_FUNC("ctrl GPS_SYNC(%d) fail!(%d) ignore it...\n", + (pData->au4CtrlData[0] == 0) ? PIN_STA_DEINIT : PIN_STA_MUX, iret); + + return 0; +} + + +static INT32 wmt_ctrl_gps_lna_set(P_WMT_CTRL_DATA pData) +{ + INT32 iret; + + WMT_DBG_FUNC("ctrl GPS_LNA(%d)\n", + (pData->au4CtrlData[0] == 0) ? PIN_STA_DEINIT : PIN_STA_OUT_H); + iret = + wmt_plat_gpio_ctrl(PIN_GPS_LNA, + (pData->au4CtrlData[0] == 0) ? PIN_STA_DEINIT : PIN_STA_OUT_H); + + if (iret) + WMT_WARN_FUNC("ctrl GPS_SYNC(%d) fail!(%d) ignore it...\n", + (pData->au4CtrlData[0] == 0) ? PIN_STA_DEINIT : PIN_STA_OUT_H, iret); + + return 0; +} + + +INT32 wmt_ctrl_stp_rst(P_WMT_CTRL_DATA pWmtCtrlData) +{ + return 0; +} + +INT32 wmt_ctrl_get_wmt_conf(P_WMT_CTRL_DATA pWmtCtrlData) +{ + P_DEV_WMT pDev = &gDevWmt; /* single instance */ + + pWmtCtrlData->au4CtrlData[0] = (size_t) &pDev->rWmtGenConf; + + return 0; +} + +INT32 wmt_ctrl_others(P_WMT_CTRL_DATA pWmtCtrlData) +{ + WMT_ERR_FUNC("wmt_ctrl_others, invalid CTRL ID (%d)\n", pWmtCtrlData->ctrlId); + return -1; +} + + +INT32 wmt_ctrl_set_stp_dbg_info(P_WMT_CTRL_DATA pWmtCtrlData) +{ + PUINT8 pRomVer = NULL; + P_WMT_PATCH pPatch = NULL; + UINT32 chipID = 0; + + chipID = pWmtCtrlData->au4CtrlData[0]; + pRomVer = (PUINT8) (pWmtCtrlData->au4CtrlData[1]); + pPatch = (P_WMT_PATCH)(pWmtCtrlData->au4CtrlData[2]); + if (!pRomVer) { + WMT_ERR_FUNC("pRomVer null pointer\n"); + return -1; + } + + if (!pPatch) { + WMT_ERR_FUNC("pPatch null pointer\n"); + return -2; + } + WMT_DBG_FUNC("chipid(0x%x),rom(%s),patch date(%s),patch plat(%s)\n", chipID, pRomVer, + pPatch->ucDateTime, pPatch->ucPLat); + return stp_dbg_set_version_info(chipID, pRomVer, &(pPatch->ucDateTime[0]), + &(pPatch->ucPLat[0])); +} + +static INT32 wmt_ctrl_trg_assert(P_WMT_CTRL_DATA pWmtCtrlData) +{ + INT32 iRet = -1; + + ENUM_WMTDRV_TYPE_T drv_type; + UINT32 reason = 0; + PUINT8 keyword; + + drv_type = pWmtCtrlData->au4CtrlData[0]; + reason = pWmtCtrlData->au4CtrlData[1]; + keyword = (PUINT8) pWmtCtrlData->au4CtrlData[2]; + WMT_INFO_FUNC("wmt-ctrl:drv_type(%d),reason(%d),keyword(%s)\n", drv_type, reason, keyword); + + if (wmt_dev_is_close()) + WMT_INFO_FUNC("WMT is closing, don't trigger assert\n"); + else if (chip_reset_only == 1) + WMT_INFO_FUNC("Do chip reset only, don't trigger assert\n"); + else if (mtk_wcn_stp_get_wmt_trg_assert() == 0) { + mtk_wcn_stp_dbg_dump_package(); + mtk_wcn_stp_set_wmt_trg_assert(1); + mtk_wcn_stp_assert_flow_ctrl(1); + + iRet = mtk_wcn_stp_wmt_trg_assert(); + if (iRet == 0) { + wmt_lib_set_host_assert_info(drv_type, reason, 1); + stp_dbg_set_keyword(keyword); + } + } else + WMT_INFO_FUNC("do trigger assert & chip reset in stp noack\n"); + + return 0; +} diff --git a/drivers/misc/mediatek/connectivity/common/common_main/core/wmt_exp.c b/drivers/misc/mediatek/connectivity/common/common_main/core/wmt_exp.c new file mode 100644 index 0000000000000000000000000000000000000000..0cc26da0c2cfd87b6e515690ab28a18e0c80c449 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/core/wmt_exp.c @@ -0,0 +1,876 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +#ifdef DFT_TAG +#undef DFT_TAG +#endif +#define DFT_TAG "[WMT-EXP]" + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include "osal_typedef.h" +#include "wmt_step.h" + +#include +#include +#include +#include +#include +#include +#include + + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ +wmt_wlan_probe_cb mtk_wcn_wlan_probe; +wmt_wlan_remove_cb mtk_wcn_wlan_remove; +wmt_wlan_bus_cnt_get_cb mtk_wcn_wlan_bus_tx_cnt; +wmt_wlan_bus_cnt_clr_cb mtk_wcn_wlan_bus_tx_cnt_clr; +wmt_wlan_emi_mpu_set_protection_cb mtk_wcn_wlan_emi_mpu_set_protection; +wmt_wlan_is_wifi_drv_own_cb mtk_wcn_wlan_is_wifi_drv_own; + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ +OSAL_BIT_OP_VAR gBtWifiGpsState; +OSAL_BIT_OP_VAR gGpsFmState; +UINT32 gWifiProbed; +INT32 gWmtDbgLvl = WMT_LOG_INFO; +MTK_WCN_BOOL g_pwr_off_flag = MTK_WCN_BOOL_TRUE; + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +static MTK_WCN_BOOL mtk_wcn_wmt_pwr_on(VOID); +static MTK_WCN_BOOL mtk_wcn_wmt_func_ctrl(ENUM_WMTDRV_TYPE_T type, ENUM_WMT_OPID_T opId); +static MTK_WCN_BOOL mtk_wmt_gps_suspend_ctrl_by_type(MTK_WCN_BOOL gps_l1, MTK_WCN_BOOL gps_l5, MTK_WCN_BOOL suspend); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +static MTK_WCN_BOOL mtk_wcn_wmt_pwr_on(VOID) +{ + P_OSAL_OP pOp; + MTK_WCN_BOOL bRet; + P_OSAL_SIGNAL pSignal; + + pOp = wmt_lib_get_free_op(); + if (!pOp) { + WMT_DBG_FUNC("get_free_lxop fail\n"); + return MTK_WCN_BOOL_FALSE; + } + pSignal = &pOp->signal; + + pOp->op.opId = WMT_OPID_PWR_ON; + pSignal->timeoutValue = MAX_FUNC_ON_TIME; + pOp->op.au4OpData[0] = WMTDRV_TYPE_WMT; + + wmt_lib_host_awake_get(); + if (DISABLE_PSM_MONITOR()) { + WMT_ERR_FUNC("wake up failed,OPID(%d) type(%zu) abort\n", pOp->op.opId, pOp->op.au4OpData[0]); + wmt_lib_put_op_to_free_queue(pOp); + wmt_lib_host_awake_put(); + return MTK_WCN_BOOL_FALSE; + } + + bRet = wmt_lib_put_act_op(pOp); + + ENABLE_PSM_MONITOR(); + wmt_lib_host_awake_put(); + + if (bRet == MTK_WCN_BOOL_FALSE) + WMT_WARN_FUNC("OPID(%d) type(%zu) fail\n", pOp->op.opId, pOp->op.au4OpData[0]); + + return bRet; +} + +static MTK_WCN_BOOL mtk_wcn_wmt_func_ctrl(ENUM_WMTDRV_TYPE_T type, ENUM_WMT_OPID_T opId) +{ + P_OSAL_OP pOp; + MTK_WCN_BOOL bRet; + P_OSAL_SIGNAL pSignal; + MTK_WCN_BOOL bOffload; + MTK_WCN_BOOL bExplicitPwrOn; + + bOffload = (type == WMTDRV_TYPE_WIFI); + bExplicitPwrOn = (bOffload && opId == WMT_OPID_FUNC_ON && + wmt_lib_get_drv_status(WMTDRV_TYPE_WMT) != DRV_STS_FUNC_ON); + + /* WIFI on no need to disable psm and prevent WIFI on blocked by psm lock. */ + /* So we power on connsys separately from function on flow. */ + if (bExplicitPwrOn) + mtk_wcn_wmt_pwr_on(); + + pOp = wmt_lib_get_free_op(); + if (!pOp) { + WMT_DBG_FUNC("get_free_lxop fail\n"); + return MTK_WCN_BOOL_FALSE; + } + + pSignal = &pOp->signal; + + pOp->op.opId = opId; + pOp->op.au4OpData[0] = type; + if (type == WMTDRV_TYPE_WIFI) + pSignal->timeoutValue = 4000; + else + pSignal->timeoutValue = (pOp->op.opId == WMT_OPID_FUNC_ON) ? MAX_FUNC_ON_TIME : MAX_FUNC_OFF_TIME; + + WMT_INFO_FUNC("wmt-exp: OPID(%d) type(%zu) start\n", pOp->op.opId, pOp->op.au4OpData[0]); + WMT_STEP_FUNC_CTRL_DO_ACTIONS_FUNC(type, opId); + + /*do not check return value, we will do this either way */ + wmt_lib_host_awake_get(); + /* wake up chip first */ + if (!bOffload) { + if (DISABLE_PSM_MONITOR()) { + WMT_ERR_FUNC("wake up failed,OPID(%d) type(%zu) abort\n", pOp->op.opId, pOp->op.au4OpData[0]); + wmt_lib_put_op_to_free_queue(pOp); + wmt_lib_host_awake_put(); + return MTK_WCN_BOOL_FALSE; + } + } + + bRet = wmt_lib_put_act_op(pOp); + if (!bOffload) + ENABLE_PSM_MONITOR(); + wmt_lib_host_awake_put(); + + if (bRet == MTK_WCN_BOOL_FALSE) + WMT_WARN_FUNC("OPID(%d) type(%zu) fail\n", pOp->op.opId, pOp->op.au4OpData[0]); + else + WMT_INFO_FUNC("OPID(%d) type(%zu) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); + + return bRet; +} + +INT32 mtk_wcn_wmt_psm_ctrl(MTK_WCN_BOOL flag) +{ + return -EFAULT; +} +EXPORT_SYMBOL(mtk_wcn_wmt_psm_ctrl); + +MTK_WCN_BOOL mtk_wcn_wmt_func_off(ENUM_WMTDRV_TYPE_T type) +{ + MTK_WCN_BOOL ret; + + if (type == WMTDRV_TYPE_BT) { + osal_printtimeofday("############ BT OFF ====>"); + } + + ret = mtk_wcn_wmt_func_ctrl(type, WMT_OPID_FUNC_OFF); + + if (type == WMTDRV_TYPE_BT) + osal_printtimeofday("############ BT OFF <===="); + + return ret; +} +EXPORT_SYMBOL(mtk_wcn_wmt_func_off); + +MTK_WCN_BOOL mtk_wcn_wmt_func_on(ENUM_WMTDRV_TYPE_T type) +{ + MTK_WCN_BOOL ret; + + if (type == WMTDRV_TYPE_BT) + osal_printtimeofday("############ BT ON ====>"); + + ret = mtk_wcn_wmt_func_ctrl(type, WMT_OPID_FUNC_ON); + + if (type == WMTDRV_TYPE_BT) + osal_printtimeofday(" ############BT ON <===="); + + return ret; +} +EXPORT_SYMBOL(mtk_wcn_wmt_func_on); + +/* +*return value: +*enable/disable thermal sensor function: true(1)/false(0) +*read thermal sensor function:thermal value +*/ +VOID mtk_wcn_wmt_func_ctrl_for_plat(UINT32 on, ENUM_WMTDRV_TYPE_T type) +{ + MTK_WCN_BOOL ret; + + if (on) + ret = mtk_wcn_wmt_func_on(type); + else + ret = mtk_wcn_wmt_func_off(type); + + WMT_INFO_FUNC("on=%d type=%d ret=%d\n", on, type, ret); +} + +INT8 mtk_wcn_wmt_therm_ctrl(ENUM_WMTTHERM_TYPE_T eType) +{ + P_OSAL_OP pOp; + P_WMT_OP pOpData; + MTK_WCN_BOOL bRet; + P_OSAL_SIGNAL pSignal; + + /*parameter validation check */ + if (eType > WMTTHERM_MAX || eType < WMTTHERM_ENABLE) { + WMT_ERR_FUNC("invalid thermal control command (%d)\n", eType); + return MTK_WCN_BOOL_FALSE; + } + + /*check if chip support thermal control function or not */ + bRet = wmt_lib_is_therm_ctrl_support(eType); + if (bRet == MTK_WCN_BOOL_FALSE) { + WMT_DBG_FUNC("thermal ctrl function not supported\n"); + return MTK_WCN_BOOL_FALSE; + } + + pOp = wmt_lib_get_free_op(); + if (!pOp) { + WMT_DBG_FUNC("get_free_lxop fail\n"); + return MTK_WCN_BOOL_FALSE; + } + + pSignal = &pOp->signal; + pOpData = &pOp->op; + pOpData->opId = WMT_OPID_THERM_CTRL; + /*parameter fill */ + pOpData->au4OpData[0] = eType; + pSignal->timeoutValue = MAX_EACH_WMT_CMD; + + WMT_DBG_FUNC("OPID(%d) type(%zu) start\n", pOp->op.opId, pOp->op.au4OpData[0]); + WMT_STEP_DO_ACTIONS_FUNC(STEP_TRIGGER_POINT_BEFORE_READ_THERMAL); + + if (DISABLE_PSM_MONITOR()) { + WMT_ERR_FUNC("wake up failed,OPID(%d) type(%zu) abort!\n", pOp->op.opId, pOp->op.au4OpData[0]); + wmt_lib_put_op_to_free_queue(pOp); + return -1; + } + + bRet = wmt_lib_put_act_op(pOp); + ENABLE_PSM_MONITOR(); + + if (bRet == MTK_WCN_BOOL_FALSE) { + WMT_WARN_FUNC("OPID(%d) type(%zu) fail\n\n", pOpData->opId, pOpData->au4OpData[0]); + /*0xFF means read error occurs */ + /*will return to function driver */ + pOpData->au4OpData[1] = (eType == WMTTHERM_READ) ? 0xFF : MTK_WCN_BOOL_FALSE; + } else + WMT_DBG_FUNC("OPID(%d) type(%zu) return(%zu) ok\n\n", + pOpData->opId, pOpData->au4OpData[0], pOpData->au4OpData[1]); + /*return value will be put to lxop->op.au4OpData[1] */ + WMT_DBG_FUNC("therm ctrl type(%d), iRet(0x%08zx)\n", eType, pOpData->au4OpData[1]); + + return (INT8) pOpData->au4OpData[1]; +} +EXPORT_SYMBOL(mtk_wcn_wmt_therm_ctrl); + +ENUM_WMTHWVER_TYPE_T mtk_wcn_wmt_hwver_get(VOID) +{ + /* TODO: [ChangeFeature][GeorgeKuo] Reconsider usage of this type */ + /* TODO: how do we extend for new chip and newer revision? */ + /* TODO: This way is hard to extend */ + return wmt_lib_get_icinfo(WMTCHIN_MAPPINGHWVER); +} +EXPORT_SYMBOL(mtk_wcn_wmt_hwver_get); + +UINT32 mtk_wcn_wmt_ic_info_get(ENUM_WMT_CHIPINFO_TYPE_T type) +{ + return wmt_lib_get_icinfo(type); +} +EXPORT_SYMBOL(mtk_wcn_wmt_ic_info_get); + +MTK_WCN_BOOL mtk_wcn_wmt_dsns_ctrl(ENUM_WMTDSNS_TYPE_T eType) +{ + P_OSAL_OP pOp; + P_WMT_OP pOpData; + MTK_WCN_BOOL bRet; + P_OSAL_SIGNAL pSignal; + + if (eType >= WMTDSNS_MAX) { + WMT_ERR_FUNC("invalid desense control command (%d)\n", eType); + return MTK_WCN_BOOL_FALSE; + } + + /*check if chip support thermal control function or not */ + bRet = wmt_lib_is_dsns_ctrl_support(); + if (bRet == MTK_WCN_BOOL_FALSE) { + WMT_ERR_FUNC("thermal ctrl function not supported\n"); + return MTK_WCN_BOOL_FALSE; + } + + pOp = wmt_lib_get_free_op(); + if (!pOp) { + WMT_DBG_FUNC("get_free_lxop fail\n"); + return MTK_WCN_BOOL_FALSE; + } + + pSignal = &pOp->signal; + pOpData = &pOp->op; + pOpData->opId = WMT_OPID_DSNS; + pSignal->timeoutValue = MAX_EACH_WMT_CMD; + /*parameter fill */ + if ((eType >= WMTDSNS_FM_DISABLE) && (eType <= WMTDSNS_FM_GPS_ENABLE)) { + pOpData->au4OpData[0] = WMTDRV_TYPE_FM; + pOpData->au4OpData[1] = eType; + } + + WMT_INFO_FUNC("OPID(%d) type(%zu) start\n", pOp->op.opId, pOp->op.au4OpData[0]); + + if (DISABLE_PSM_MONITOR()) { + WMT_ERR_FUNC("wake up failed,OPID(%d) type(%zu) abort!\n", pOp->op.opId, pOp->op.au4OpData[0]); + wmt_lib_put_op_to_free_queue(pOp); + return MTK_WCN_BOOL_FALSE; + } + + bRet = wmt_lib_put_act_op(pOp); + ENABLE_PSM_MONITOR(); + + if (bRet == MTK_WCN_BOOL_FALSE) + WMT_WARN_FUNC("OPID(%d) type(%zu) fail\n\n", pOpData->opId, pOpData->au4OpData[0]); + else + WMT_INFO_FUNC("OPID(%d) type(%zu) ok\n\n", pOpData->opId, pOpData->au4OpData[0]); + + return bRet; +} +EXPORT_SYMBOL(mtk_wcn_wmt_dsns_ctrl); + +INT32 mtk_wcn_wmt_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb) +{ + return (INT32) wmt_lib_msgcb_reg(eType, pCb); +} +EXPORT_SYMBOL(mtk_wcn_wmt_msgcb_reg); + +INT32 mtk_wcn_wmt_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType) +{ + return (INT32) wmt_lib_msgcb_unreg(eType); +} +EXPORT_SYMBOL(mtk_wcn_wmt_msgcb_unreg); + +INT32 mtk_wcn_stp_wmt_sdio_op_reg(PF_WMT_SDIO_PSOP own_cb) +{ + wmt_lib_ps_set_sdio_psop(own_cb); + return 0; +} +EXPORT_SYMBOL(mtk_wcn_stp_wmt_sdio_op_reg); + +#ifdef CONFIG_MTK_COMBO_CHIP_DEEP_SLEEP_SUPPORT +INT32 mtk_wcn_wmt_sdio_deep_sleep_flag_cb_reg(PF_WMT_SDIO_DEEP_SLEEP flag_cb) +{ + wmt_lib_sdio_deep_sleep_flag_set_cb_reg(flag_cb); + return 0; +} +EXPORT_SYMBOL(mtk_wcn_wmt_sdio_deep_sleep_flag_cb_reg); +#endif + +INT32 mtk_wcn_wmt_sdio_rw_cb_reg(PF_WMT_SDIO_DEBUG reg_rw_cb) +{ + wmt_lib_sdio_reg_rw_cb(reg_rw_cb); + return 0; +} + +INT32 mtk_wcn_stp_wmt_sdio_host_awake(VOID) +{ + wmt_lib_ps_irq_cb(); + return 0; +} +EXPORT_SYMBOL(mtk_wcn_stp_wmt_sdio_host_awake); + +MTK_WCN_BOOL mtk_wcn_wmt_assert_timeout(ENUM_WMTDRV_TYPE_T type, UINT32 reason, INT32 timeout) +{ + MTK_WCN_BOOL bRet; + + bRet = wmt_lib_trigger_assert(type, reason); + + return bRet == 0 ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE; +} +EXPORT_SYMBOL(mtk_wcn_wmt_assert_timeout); + +MTK_WCN_BOOL mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason) +{ + return mtk_wcn_wmt_assert_timeout(type, reason, MAX_EACH_WMT_CMD); +} +EXPORT_SYMBOL(mtk_wcn_wmt_assert); + +MTK_WCN_BOOL mtk_wcn_wmt_assert_keyword(ENUM_WMTDRV_TYPE_T type, PUINT8 keyword) +{ + MTK_WCN_BOOL bRet; + + bRet = wmt_lib_trigger_assert_keyword(type, 0, keyword); + + return bRet == 0 ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE; +} +EXPORT_SYMBOL(mtk_wcn_wmt_assert_keyword); + +/* +* ctrlId: get flash patch version opId or flash patch download opId +* pBuf: pointer to flash patch +* length: total length of flash patch +* type: flash patch type +* version: flash patch version +* checksum: flash patch checksum +*/ +ENUM_WMT_FLASH_PATCH_STATUS mtk_wcn_wmt_flash_patch_ctrl(ENUM_WMT_FLASH_PATCH_CTRL ctrlId, + PUINT8 pBuf, UINT32 length, ENUM_WMT_FLASH_PATCH_SEQ seq, ENUM_WMT_FLASH_PATCH_TYPE type, + PUINT32 version, UINT32 checksum) +{ + ENUM_WMT_FLASH_PATCH_STATUS eRet = 0; + P_OSAL_OP pOp = NULL; + MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; + P_OSAL_SIGNAL pSignal; + + /*1. parameter validation check */ + /*for WMT_FLASH_PATCH_VERSION_GET, ignore pBuf and length */ + /*for WMT_ANT_RAM_DOWNLOAD, + * pBuf must not be NULL, kernel space memory pointer + * length must be large than 0 + */ + switch (ctrlId) { + case WMT_FLASH_PATCH_VERSION_GET: + break; + case WMT_FLASH_PATCH_DOWNLOAD: + if ((pBuf == NULL) || (length <= 0) || (length > 1000)) { + WMT_ERR_FUNC("error parameter detected, ctrlId:%d, pBuf:%p,length(0x%x).\n", + ctrlId, pBuf, length); + eRet = WMT_FLASH_PATCH_PARA_ERR; + goto exit; + } else + break; + default: + WMT_ERR_FUNC("error ctrlId:%d detected.\n", ctrlId); + eRet = WMT_FLASH_PATCH_PARA_ERR; + goto exit; + } + + /*get WMT opId */ + pOp = wmt_lib_get_free_op(); + if (!pOp) { + WMT_DBG_FUNC("get_free_lxop fail\n"); + eRet = WMT_FLASH_PATCH_OP_ERR; + goto exit; + } + + pSignal = &pOp->signal; + pSignal->timeoutValue = + (ctrlId == WMT_FLASH_PATCH_DOWNLOAD) ? MAX_FUNC_ON_TIME : MAX_EACH_WMT_CMD; + + pOp->op.opId = (ctrlId == WMT_FLASH_PATCH_DOWNLOAD) ? + WMT_OPID_FLASH_PATCH_DOWN : WMT_OPID_FLASH_PATCH_VER_GET; + pOp->op.au4OpData[0] = (size_t) pBuf; + pOp->op.au4OpData[1] = length; + pOp->op.au4OpData[2] = seq; + pOp->op.au4OpData[3] = type; + pOp->op.au4OpData[4] = *version; + pOp->op.au4OpData[5] = checksum; + + /*disable PSM monitor */ + if (DISABLE_PSM_MONITOR()) { + WMT_ERR_FUNC("wake up failed\n"); + wmt_lib_put_op_to_free_queue(pOp); + eRet = WMT_FLASH_PATCH_OP_ERR; + goto exit; + } + /*wakeup wmtd thread */ + bRet = wmt_lib_put_act_op(pOp); + + /*enable PSM monitor */ + ENABLE_PSM_MONITOR(); + + WMT_INFO_FUNC("CMD_TEST, opid (%d), ret(%d),retVal(%zu) result(%s)\n", + pOp->op.opId, + bRet, + pOp->op.au4OpData[6], MTK_WCN_BOOL_FALSE == bRet ? "failed" : "succeed"); + + /*check return value and return result */ + if (bRet == MTK_WCN_BOOL_FALSE) { + eRet = WMT_FLASH_PATCH_OP_ERR; + } else { + switch (ctrlId) { + case WMT_FLASH_PATCH_VERSION_GET: + if (pOp->op.au4OpData[6] == 0) { + *version = pOp->op.au4OpData[4]; + eRet = WMT_FLASH_PATCH_VERSION_GET_OK; + } else + eRet = WMT_FLASH_PATCH_VERSION_GET_FAIL; + break; + case WMT_FLASH_PATCH_DOWNLOAD: + eRet = (pOp->op.au4OpData[6] == 0) ? + WMT_FLASH_PATCH_DOWNLOAD_OK : WMT_FLASH_PATCH_DOWNLOAD_FAIL; + break; + default: + WMT_ERR_FUNC("error ctrlId:%d detected.\n", ctrlId); + eRet = WMT_FLASH_PATCH_PARA_ERR; + break; + } + } + +exit: + return eRet; +} +EXPORT_SYMBOL(mtk_wcn_wmt_flash_patch_ctrl); + +#if !(DELETE_HIF_SDIO_CHRDEV) +extern INT32 mtk_wcn_wmt_chipid_query(VOID) +{ + return mtk_wcn_hif_sdio_query_chipid(0); +} +EXPORT_SYMBOL(mtk_wcn_wmt_chipid_query); +#endif + +INT8 mtk_wcn_wmt_co_clock_flag_get(void) +{ + return wmt_lib_co_clock_get(); +} +EXPORT_SYMBOL(mtk_wcn_wmt_co_clock_flag_get); + +INT32 mtk_wcn_wmt_system_state_reset(void) +{ + osal_memset(&gBtWifiGpsState, 0, osal_sizeof(gBtWifiGpsState)); + osal_memset(&gGpsFmState, 0, osal_sizeof(gGpsFmState)); + + return 0; +} + +INT32 mtk_wcn_wmt_wlan_reg(P_MTK_WCN_WMT_WLAN_CB_INFO pWmtWlanCbInfo) +{ + INT32 iRet = -1; + + if (!pWmtWlanCbInfo) { + WMT_ERR_FUNC("wlan cb info in null!\n"); + return -1; + } + + WMT_INFO_FUNC("wmt wlan cb register\n"); + mtk_wcn_wlan_probe = pWmtWlanCbInfo->wlan_probe_cb; + mtk_wcn_wlan_remove = pWmtWlanCbInfo->wlan_remove_cb; + mtk_wcn_wlan_bus_tx_cnt = pWmtWlanCbInfo->wlan_bus_cnt_get_cb; + mtk_wcn_wlan_bus_tx_cnt_clr = pWmtWlanCbInfo->wlan_bus_cnt_clr_cb; + mtk_wcn_wlan_emi_mpu_set_protection = pWmtWlanCbInfo->wlan_emi_mpu_set_protection_cb; + mtk_wcn_wlan_is_wifi_drv_own = pWmtWlanCbInfo->wlan_is_wifi_drv_own_cb; + + if (gWifiProbed) { + WMT_INFO_FUNC("wlan has been done power on,call probe directly\n"); + iRet = (*mtk_wcn_wlan_probe) (); + if (!iRet) { + WMT_INFO_FUNC("call wlan probe OK when do wlan register to wmt\n"); + gWifiProbed = 0; + } else { + WMT_ERR_FUNC("call wlan probe fail(%d) when do wlan register to wmt\n", iRet); + return -2; + } + } + return 0; +} +EXPORT_SYMBOL(mtk_wcn_wmt_wlan_reg); + +INT32 mtk_wcn_wmt_wlan_unreg(void) +{ + WMT_INFO_FUNC("wmt wlan cb unregister\n"); + mtk_wcn_wlan_probe = NULL; + mtk_wcn_wlan_remove = NULL; + mtk_wcn_wlan_bus_tx_cnt = NULL; + mtk_wcn_wlan_bus_tx_cnt_clr = NULL; + mtk_wcn_wlan_emi_mpu_set_protection = NULL; + mtk_wcn_wlan_is_wifi_drv_own = NULL; + + return 0; +} +EXPORT_SYMBOL(mtk_wcn_wmt_wlan_unreg); + +MTK_WCN_BOOL mtk_wcn_set_connsys_power_off_flag(MTK_WCN_BOOL value) +{ + g_pwr_off_flag = value; + if (g_pwr_off_flag) + WMT_DBG_FUNC("enable connsys power off flag\n"); + else + WMT_INFO_FUNC("disable connsys power off, maybe need trigger coredump!\n"); + return g_pwr_off_flag; +} +EXPORT_SYMBOL(mtk_wcn_set_connsys_power_off_flag); + +#ifdef CONFIG_MTK_COMBO_ANT +/* +* ctrlId: get ram code status opId or ram code download opId +* pBuf: pointer to ANT ram code +* length: total length of ANT ram code +*/ +ENUM_WMT_ANT_RAM_STATUS mtk_wcn_wmt_ant_ram_ctrl(ENUM_WMT_ANT_RAM_CTRL ctrlId, PUINT8 pBuf, + UINT32 length, ENUM_WMT_ANT_RAM_SEQ seq) +{ + ENUM_WMT_ANT_RAM_STATUS eRet = 0; + P_OSAL_OP pOp = NULL; + MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; + P_OSAL_SIGNAL pSignal; + + /*1. parameter validation check */ + /*for WMT_ANT_RAM_GET_STATUS, ignore pBuf and length */ + /*for WMT_ANT_RAM_DOWNLOAD, + * pBuf must not be NULL, kernel space memory pointer + * length must be large than 0 + */ + if ((ctrlId < WMT_ANT_RAM_GET_STATUS) || (ctrlId >= WMT_ANT_RAM_CTRL_MAX)) { + WMT_ERR_FUNC("error ctrlId:%d detected.\n", ctrlId); + eRet = WMT_ANT_RAM_PARA_ERR; + return eRet; + } + + if ((ctrlId == WMT_ANT_RAM_DOWNLOAD) && ((pBuf == NULL) || (length <= 0) || + (length > 1000) || (seq >= WMT_ANT_RAM_SEQ_MAX) || (seq < WMT_ANT_RAM_START_PKT))) { + eRet = WMT_ANT_RAM_PARA_ERR; + WMT_ERR_FUNC + ("error parameter detected, ctrlId:%d, pBuf:%p,length(0x%x),seq(%d) .\n", + ctrlId, pBuf, length, seq); + return eRet; + } + /*get WMT opId */ + pOp = wmt_lib_get_free_op(); + if (!pOp) { + WMT_DBG_FUNC("get_free_lxop fail\n"); + return MTK_WCN_BOOL_FALSE; + } + + pSignal = &pOp->signal; + pSignal->timeoutValue = + (ctrlId == WMT_ANT_RAM_DOWNLOAD) ? MAX_FUNC_ON_TIME : MAX_EACH_WMT_CMD; + + pOp->op.opId = + (ctrlId == WMT_ANT_RAM_DOWNLOAD) ? WMT_OPID_ANT_RAM_DOWN : WMT_OPID_ANT_RAM_STA_GET; + pOp->op.au4OpData[0] = (size_t) pBuf; + pOp->op.au4OpData[1] = length; + pOp->op.au4OpData[2] = seq; + + + /*disable PSM monitor */ + if (DISABLE_PSM_MONITOR()) { + WMT_ERR_FUNC("wake up failed\n"); + wmt_lib_put_op_to_free_queue(pOp); + return MTK_WCN_BOOL_FALSE; + } + /*wakeup wmtd thread */ + bRet = wmt_lib_put_act_op(pOp); + + /*enable PSM monitor */ + ENABLE_PSM_MONITOR(); + + WMT_INFO_FUNC("CMD_TEST, opid (%d), ret(%d),retVal(%zu) result(%s)\n", + pOp->op.opId, + bRet, + pOp->op.au4OpData[2], MTK_WCN_BOOL_FALSE == bRet ? "failed" : "succeed"); + + /*check return value and return result */ + if (bRet == MTK_WCN_BOOL_FALSE) { + eRet = WMT_ANT_RAM_OP_ERR; + } else { + eRet = (ctrlId == WMT_ANT_RAM_DOWNLOAD) ? + WMT_ANT_RAM_DOWN_OK : + ((pOp->op.au4OpData[2] == 1) ? WMT_ANT_RAM_EXIST : WMT_ANT_RAM_NOT_EXIST); + } + + return eRet; + +} +EXPORT_SYMBOL(mtk_wcn_wmt_ant_ram_ctrl); +#endif +MTK_WCN_BOOL mtk_wcn_wmt_do_reset(ENUM_WMTDRV_TYPE_T type) +{ + INT32 iRet = -1; + UINT8 *drv_name[] = { + [0] = "DRV_TYPE_BT", + [1] = "DRV_TYPE_FM", + [2] = "DRV_TYPE_GPS", + [3] = "DRV_TYPE_WIFI", + [4] = "DRV_TYPE_WMT", + [5] = "DRV_TYPE_ANT", + [11] = "DRV_TYPE_GPSL5", + }; + + if ((type < WMTDRV_TYPE_BT) || (type > WMTDRV_TYPE_ANT)) { + WMT_INFO_FUNC("Wrong driver type: %d, do not trigger reset.\n", type); + return MTK_WCN_BOOL_FALSE; + } + + WMT_INFO_FUNC("Subsystem trigger whole chip reset, reset source: %s\n", drv_name[type]); + if (mtk_wcn_stp_get_wmt_trg_assert() == 0) + iRet = wmt_lib_trigger_reset(); + else { + WMT_INFO_FUNC("assert has been triggered that no chip reset is required\n"); + iRet = 0; + } + + return iRet == 0 ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE; +} +EXPORT_SYMBOL(mtk_wcn_wmt_do_reset); + +MTK_WCN_BOOL mtk_wcn_wmt_do_reset_only(ENUM_WMTDRV_TYPE_T type) +{ + INT32 iRet = -1; + + WMT_INFO_FUNC("Whole chip reset without trigger assert\n"); + if (mtk_wcn_stp_get_wmt_trg_assert() == 0) { + chip_reset_only = 1; + iRet = wmt_lib_trigger_reset(); + } else { + WMT_INFO_FUNC("assert has been triggered already\n"); + iRet = 0; + } + + return iRet == 0 ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE; +} +EXPORT_SYMBOL(mtk_wcn_wmt_do_reset_only); + +VOID mtk_wcn_wmt_set_wifi_ver(UINT32 Value) +{ + wmt_lib_soc_set_wifiver(Value); +} +EXPORT_SYMBOL(mtk_wcn_wmt_set_wifi_ver); + +INT32 mtk_wcn_wmt_wifi_fem_cfg_report(PVOID pvInfoBuf) +{ + INT32 iRet = -1; + + iRet = wmt_lib_wifi_fem_cfg_report(pvInfoBuf); + return iRet; +} +EXPORT_SYMBOL(mtk_wcn_wmt_wifi_fem_cfg_report); + +VOID mtk_wcn_wmt_dump_wmtd_backtrace(VOID) +{ + wmt_lib_dump_wmtd_backtrace(); +} +EXPORT_SYMBOL(mtk_wcn_wmt_dump_wmtd_backtrace); + +UINT32 mtk_wmt_get_gps_lna_pin_num(VOID) +{ + return wmt_lib_get_gps_lna_pin_num(); +} +EXPORT_SYMBOL(mtk_wmt_get_gps_lna_pin_num); + +VOID mtk_wmt_set_ext_ldo(UINT32 flag) +{ + wmt_lib_set_ext_ldo(flag); +} +EXPORT_SYMBOL(mtk_wmt_set_ext_ldo); + +INT32 mtk_wmt_gps_mcu_ctrl(PUINT8 p_tx_data_buf, UINT32 tx_data_len, PUINT8 p_rx_data_buf, + UINT32 rx_data_buf_len, PUINT32 p_rx_data_len) +{ + return wmt_lib_gps_mcu_ctrl(p_tx_data_buf, tx_data_len, p_rx_data_buf, rx_data_buf_len, + p_rx_data_len); +} +EXPORT_SYMBOL(mtk_wmt_gps_mcu_ctrl); + +VOID mtk_wcn_wmt_set_mcif_mpu_protection(MTK_WCN_BOOL enable) +{ + mtk_consys_set_mcif_mpu_protection(enable); +} +EXPORT_SYMBOL(mtk_wcn_wmt_set_mcif_mpu_protection); + +static MTK_WCN_BOOL mtk_wmt_gps_suspend_ctrl_by_type(MTK_WCN_BOOL gps_l1, MTK_WCN_BOOL gps_l5, MTK_WCN_BOOL suspend) +{ + P_OSAL_OP pOp; + MTK_WCN_BOOL bRet; + P_OSAL_SIGNAL pSignal; + + pOp = wmt_lib_get_free_op(); + if (!pOp) { + WMT_DBG_FUNC("get_free_lxop fail\n"); + return MTK_WCN_BOOL_FALSE; + } + + pSignal = &pOp->signal; + + pOp->op.opId = WMT_OPID_GPS_SUSPEND; + pOp->op.au4OpData[0] = (MTK_WCN_BOOL_FALSE == suspend ? 0 : 1); + pOp->op.au4OpData[1] = (MTK_WCN_BOOL_FALSE == gps_l1 ? 0 : 1); + pOp->op.au4OpData[2] = (MTK_WCN_BOOL_FALSE == gps_l5 ? 0 : 1); + pSignal->timeoutValue = (MTK_WCN_BOOL_FALSE == suspend) ? MAX_FUNC_ON_TIME : MAX_FUNC_OFF_TIME; + + WMT_INFO_FUNC("wmt-exp: OPID(%d) type(%zu) start\n", pOp->op.opId, pOp->op.au4OpData[0]); + + /*do not check return value, we will do this either way */ + wmt_lib_host_awake_get(); + /* wake up chip first */ + if (DISABLE_PSM_MONITOR()) { + WMT_ERR_FUNC("wake up failed,OPID(%d) type(%zu) abort\n", pOp->op.opId, pOp->op.au4OpData[0]); + wmt_lib_put_op_to_free_queue(pOp); + wmt_lib_host_awake_put(); + return MTK_WCN_BOOL_FALSE; + } + + bRet = wmt_lib_put_act_op(pOp); + ENABLE_PSM_MONITOR(); + wmt_lib_host_awake_put(); + + if (bRet == MTK_WCN_BOOL_FALSE) + WMT_WARN_FUNC("OPID(%d) type(%zu) fail\n", pOp->op.opId, pOp->op.au4OpData[0]); + else + WMT_INFO_FUNC("OPID(%d) type(%zu) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); + + return bRet; +} + +MTK_WCN_BOOL mtk_wmt_gps_suspend_ctrl(MTK_WCN_BOOL suspend) +{ + return mtk_wmt_gps_suspend_ctrl_by_type(MTK_WCN_BOOL_TRUE, MTK_WCN_BOOL_TRUE, suspend); +} +EXPORT_SYMBOL(mtk_wmt_gps_suspend_ctrl); + +MTK_WCN_BOOL mtk_wmt_gps_l1_suspend_ctrl(MTK_WCN_BOOL suspend) +{ + return mtk_wmt_gps_suspend_ctrl_by_type(MTK_WCN_BOOL_TRUE, MTK_WCN_BOOL_FALSE, suspend); +} +EXPORT_SYMBOL(mtk_wmt_gps_l1_suspend_ctrl); + +MTK_WCN_BOOL mtk_wmt_gps_l5_suspend_ctrl(MTK_WCN_BOOL suspend) +{ + return mtk_wmt_gps_suspend_ctrl_by_type(MTK_WCN_BOOL_FALSE, MTK_WCN_BOOL_TRUE, suspend); +} +EXPORT_SYMBOL(mtk_wmt_gps_l5_suspend_ctrl); + +INT32 mtk_wcn_wmt_mpu_lock_aquire(VOID) +{ + return wmt_lib_mpu_lock_aquire(); +} +EXPORT_SYMBOL(mtk_wcn_wmt_mpu_lock_aquire); + +VOID mtk_wcn_wmt_mpu_lock_release(VOID) +{ + wmt_lib_mpu_lock_release(); +} +EXPORT_SYMBOL(mtk_wcn_wmt_mpu_lock_release); + diff --git a/drivers/misc/mediatek/connectivity/common/common_main/core/wmt_func.c b/drivers/misc/mediatek/connectivity/common/common_main/core/wmt_func.c new file mode 100644 index 0000000000000000000000000000000000000000..d0374a4727e6b6a5ccdeeaee4a41169dddb1356a --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/core/wmt_func.c @@ -0,0 +1,838 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +#ifdef DFT_TAG +#undef DFT_TAG +#endif +#define DFT_TAG "[WMT-FUNC]" + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include "osal_typedef.h" + +#include "wmt_func.h" +#include "wmt_lib.h" +#include "wmt_core.h" +#include "wmt_exp.h" +#include "wmt_detect.h" + + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + + + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ +#if CFG_FUNC_BT_SUPPORT + +static INT32 wmt_func_bt_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); +static INT32 wmt_func_bt_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); + +WMT_FUNC_OPS wmt_func_bt_ops = { + /* BT subsystem function on/off */ + .func_on = wmt_func_bt_on, + .func_off = wmt_func_bt_off +}; +#endif + +#if CFG_FUNC_FM_SUPPORT + +static INT32 wmt_func_fm_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); +static INT32 wmt_func_fm_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); + +WMT_FUNC_OPS wmt_func_fm_ops = { + /* FM subsystem function on/off */ + .func_on = wmt_func_fm_on, + .func_off = wmt_func_fm_off +}; +#endif + +#if CFG_FUNC_GPS_SUPPORT + +static INT32 wmt_func_gps_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); +static INT32 wmt_func_gps_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); + +WMT_FUNC_OPS wmt_func_gps_ops = { + /* GPS subsystem function on/off */ + .func_on = wmt_func_gps_on, + .func_off = wmt_func_gps_off +}; + +#endif + +#if CFG_FUNC_GPSL5_SUPPORT + +static INT32 wmt_func_gpsl5_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); +static INT32 wmt_func_gpsl5_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); + +WMT_FUNC_OPS wmt_func_gpsl5_ops = { + /* GPS subsystem function on/off */ + .func_on = wmt_func_gpsl5_on, + .func_off = wmt_func_gpsl5_off +}; + +#endif + +#if CFG_FUNC_WIFI_SUPPORT +static INT32 wmt_func_wifi_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); +static INT32 wmt_func_wifi_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); + +WMT_FUNC_OPS wmt_func_wifi_ops = { + /* Wi-Fi subsystem function on/off */ + .func_on = wmt_func_wifi_on, + .func_off = wmt_func_wifi_off +}; +#endif + + +#if CFG_FUNC_ANT_SUPPORT + +static INT32 wmt_func_ant_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); +static INT32 wmt_func_ant_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); + +WMT_FUNC_OPS wmt_func_ant_ops = { + /* BT subsystem function on/off */ + .func_on = wmt_func_ant_on, + .func_off = wmt_func_ant_off +}; +#endif + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ +#if CFG_FUNC_GPS_SUPPORT +CMB_PIN_CTRL_REG eediPinOhRegs[] = { + { + /* pull down ctrl register */ + .regAddr = 0x80050020, + .regValue = ~(0x1L << 5), + .regMask = 0x00000020L, + }, + { + /* pull up ctrl register */ + .regAddr = 0x80050000, + .regValue = 0x1L << 5, + .regMask = 0x00000020L, + }, + { + /* iomode ctrl register */ + .regAddr = 0x80050110, + .regValue = 0x1L << 0, + .regMask = 0x00000007L, + }, + { + /* output high/low ctrl register */ + .regAddr = 0x80050040, + .regValue = 0x1L << 5, + .regMask = 0x00000020L, + } + +}; + +CMB_PIN_CTRL_REG eediPinOlRegs[] = { + { + .regAddr = 0x80050020, + .regValue = 0x1L << 5, + .regMask = 0x00000020L, + }, + { + .regAddr = 0x80050000, + .regValue = ~(0x1L << 5), + .regMask = 0x00000020L, + }, + { + .regAddr = 0x80050110, + .regValue = 0x1L << 0, + .regMask = 0x00000007L, + }, + { + .regAddr = 0x80050040, + .regValue = ~(0x1L << 5), + .regMask = 0x00000020L, + } +}; + +CMB_PIN_CTRL_REG eedoPinOhRegs[] = { + { + .regAddr = 0x80050020, + .regValue = ~(0x1L << 7), + .regMask = 0x00000080L, + }, + { + .regAddr = 0x80050000, + .regValue = 0x1L << 7, + .regMask = 0x00000080L, + }, + { + .regAddr = 0x80050110, + .regValue = 0x1L << 12, + .regMask = 0x00007000L, + }, + { + .regAddr = 0x80050040, + .regValue = 0x1L << 7, + .regMask = 0x00000080L, + } +}; + + +CMB_PIN_CTRL_REG eedoPinOlRegs[] = { + { + .regAddr = 0x80050020, + .regValue = 0x1L << 7, + .regMask = 0x00000080L, + }, + { + .regAddr = 0x80050000, + .regValue = ~(0x1L << 7), + .regMask = 0x00000080L, + }, + { + .regAddr = 0x80050110, + .regValue = 0x1L << 12, + .regMask = 0x00007000L, + }, + { + .regAddr = 0x80050040, + .regValue = ~(0x1L << 7), + .regMask = 0x00000080L, + } + +}; + +CMB_PIN_CTRL_REG gsyncPinOnRegs[] = { + { + .regAddr = 0x80050110, + .regValue = 0x3L << 20, + .regMask = 0x7L << 20, + } + +}; + +CMB_PIN_CTRL_REG gsyncPinOffRegs[] = { + { + .regAddr = 0x80050110, + .regValue = 0x0L << 20, + .regMask = 0x7L << 20, + } +}; + +/* templete usage for GPIO control */ +CMB_PIN_CTRL gCmbPinCtrl[3] = { + { + .pinId = CMB_PIN_EEDI_ID, + .regNum = 4, + .pFuncOnArray = eediPinOhRegs, + .pFuncOffArray = eediPinOlRegs, + }, + { + .pinId = CMB_PIN_EEDO_ID, + .regNum = 4, + .pFuncOnArray = eedoPinOhRegs, + .pFuncOffArray = eedoPinOlRegs, + }, + { + .pinId = CMB_PIN_GSYNC_ID, + .regNum = 1, + .pFuncOnArray = gsyncPinOnRegs, + .pFuncOffArray = gsyncPinOffRegs, + } +}; +#endif + + + + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#if CFG_FUNC_BT_SUPPORT + +INT32 _osal_inline_ wmt_func_bt_ctrl(ENUM_FUNC_STATE funcState) +{ + /*only need to send turn BT subsystem wmt command */ + return wmt_core_func_ctrl_cmd(WMTDRV_TYPE_BT, + (FUNC_ON == + funcState) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE); +} + +INT32 wmt_func_bt_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) +{ + INT32 iRet = -1; + ULONG ctrlPa1; + ULONG ctrlPa2; + + if (wmt_detect_get_chip_type() == WMT_CHIP_TYPE_COMBO) + return wmt_core_func_ctrl_cmd(WMTDRV_TYPE_BT, MTK_WCN_BOOL_TRUE); + + ctrlPa1 = BT_PALDO; + ctrlPa2 = PALDO_ON; + iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); + if (iRet) { + WMT_ERR_FUNC("wmt-func: wmt_ctrl_soc_paldo_ctrl failed(%d)(%lu)(%lu)\n", + iRet, ctrlPa1, ctrlPa2); + return -1; + } + iRet = wmt_core_func_ctrl_cmd(WMTDRV_TYPE_BT, MTK_WCN_BOOL_TRUE); + if (iRet) { + WMT_ERR_FUNC("wmt-func: wmt_core_func_ctrl_cmd(bt_on) failed(%d)\n", iRet); + ctrlPa1 = BT_PALDO; + ctrlPa2 = PALDO_OFF; + wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); + + return -2; + } + osal_set_bit(WMT_BT_ON, &gBtWifiGpsState); + return 0; +} + +INT32 wmt_func_bt_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) +{ + INT32 iRet1 = -1; + INT32 iRet2 = -1; + ULONG ctrlPa1; + ULONG ctrlPa2; + + if (wmt_detect_get_chip_type() == WMT_CHIP_TYPE_COMBO) + return wmt_core_func_ctrl_cmd(WMTDRV_TYPE_BT, MTK_WCN_BOOL_FALSE); + + iRet1 = wmt_core_func_ctrl_cmd(WMTDRV_TYPE_BT, MTK_WCN_BOOL_FALSE); + if (iRet1) + WMT_ERR_FUNC("wmt-func: wmt_core_func_ctrl_cmd(bt_off) failed(%d)\n", iRet1); + + ctrlPa1 = BT_PALDO; + ctrlPa2 = PALDO_OFF; + iRet2 = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); + if (iRet2) + WMT_ERR_FUNC("wmt-func: wmt_ctrl_soc_paldo_ctrl(bt_off) failed(%d)\n", iRet2); + + if (iRet1 + iRet2) + return -1; + + osal_clear_bit(WMT_BT_ON, &gBtWifiGpsState); + return 0; +} + +#endif +#if CFG_FUNC_ANT_SUPPORT + +INT32 _osal_inline_ wmt_func_ant_ctrl(ENUM_FUNC_STATE funcState) +{ + /*only need to send turn BT subsystem wmt command */ + return wmt_core_func_ctrl_cmd(WMTDRV_TYPE_ANT, + (FUNC_ON == + funcState) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE); +} + +INT32 wmt_func_ant_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) +{ + return wmt_core_func_ctrl_cmd(WMTDRV_TYPE_ANT, MTK_WCN_BOOL_TRUE); +} + +INT32 wmt_func_ant_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) +{ + return wmt_core_func_ctrl_cmd(WMTDRV_TYPE_ANT, MTK_WCN_BOOL_FALSE); +} + +#endif + +#if CFG_FUNC_GPS_SUPPORT + +INT32 _osal_inline_ wmt_func_gps_ctrl(ENUM_FUNC_STATE funcState) +{ + /*send turn GPS subsystem wmt command */ + return wmt_core_func_ctrl_cmd(WMTDRV_TYPE_GPS, + (FUNC_ON == + funcState) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE); +} + +INT32 wmt_func_gps_pre_ctrl(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf, ENUM_FUNC_STATE funcStatus) +{ + UINT32 i = 0; + UINT32 iRet = 0; + UINT32 regAddr = 0; + UINT32 regValue = 0; + UINT32 regMask = 0; + UINT32 regNum = 0; + P_CMB_PIN_CTRL_REG pReg; + P_CMB_PIN_CTRL pCmbPinCtrl = &gCmbPinCtrl[CMB_PIN_GSYNC_ID]; + WMT_CTRL_DATA ctrlData; + WMT_IC_PIN_ID wmtIcPinId = WMT_IC_PIN_MAX; + /* sanity check */ + if (FUNC_ON != funcStatus && FUNC_OFF != funcStatus) { + WMT_ERR_FUNC("invalid funcStatus(%d)\n", funcStatus); + return -1; + } + /* turn on GPS sync function on both side */ + ctrlData.ctrlId = WMT_CTRL_GPS_SYNC_SET; + ctrlData.au4CtrlData[0] = (funcStatus == FUNC_ON) ? 1 : 0; + iRet = wmt_ctrl(&ctrlData); + if (iRet) { + /*we suppose this would never print */ + WMT_ERR_FUNC("ctrl GPS_SYNC_SET(%d) fail, ret(%d)\n", funcStatus, iRet); + /* TODO:[FixMe][George] error handling? */ + return -2; + } + WMT_DBG_FUNC("ctrl GPS_SYNC_SET(%d) ok\n", funcStatus); + + if ((pOps->ic_pin_ctrl == NULL) || (pOps->ic_pin_ctrl(WMT_IC_PIN_GSYNC, FUNC_ON == + funcStatus ? WMT_IC_PIN_MUX : WMT_IC_PIN_GPIO, 1) < 0)) { + /*WMT_IC_PIN_GSYNC */ + pCmbPinCtrl = &gCmbPinCtrl[CMB_PIN_GSYNC_ID]; + regNum = pCmbPinCtrl->regNum; + for (i = 0; i < regNum; i++) { + pReg = + FUNC_ON == + funcStatus ? &pCmbPinCtrl-> + pFuncOnArray[i] : &pCmbPinCtrl->pFuncOffArray[i]; + regAddr = pReg->regAddr; + regValue = pReg->regValue; + regMask = pReg->regMask; + + iRet = wmt_core_reg_rw_raw(1, regAddr, ®Value, regMask); + if (iRet) { + WMT_ERR_FUNC("set reg for GPS_SYNC function fail(%d)\n", iRet); + /* TODO:[FixMe][Chaozhong] error handling? */ + return -2; + } + + } + } else { + WMT_DBG_FUNC("set reg for GPS_SYNC function okay by chip ic_pin_ctrl\n"); + } + WMT_DBG_FUNC("ctrl combo chip gps sync function succeed\n"); + /* turn on GPS lna ctrl function */ + if (pConf != NULL) { + if (pConf->wmt_gps_lna_enable == 0) { + + WMT_INFO_FUNC("host pin used for gps lna\n"); + /* host LNA ctrl pin needed */ + ctrlData.ctrlId = WMT_CTRL_GPS_LNA_SET; + ctrlData.au4CtrlData[0] = funcStatus == FUNC_ON ? 1 : 0; + iRet = wmt_ctrl(&ctrlData); + if (iRet) { + /*we suppose this would never print */ + WMT_ERR_FUNC("ctrl host GPS_LNA output high fail, ret(%d)\n", iRet); + /* TODO:[FixMe][Chaozhong] error handling? */ + return -3; + } + WMT_INFO_FUNC("GPS LNA pin number(%d)\n", mtk_wmt_get_gps_lna_pin_num()); + WMT_DBG_FUNC("ctrl host gps lna function succeed\n"); + } else { + WMT_INFO_FUNC("combo chip pin(%s) used for gps lna\n", + pConf->wmt_gps_lna_pin == 0 ? "EEDI" : "EEDO"); + wmtIcPinId = + pConf->wmt_gps_lna_pin == 0 ? WMT_IC_PIN_EEDI : WMT_IC_PIN_EEDO; + if ((pOps->ic_pin_ctrl == NULL) || (pOps->ic_pin_ctrl(wmtIcPinId, FUNC_ON == + funcStatus ? WMT_IC_PIN_GPIO_HIGH : WMT_IC_PIN_GPIO_LOW, 1) < 0)) { + /*WMT_IC_PIN_GSYNC */ + if (pConf->wmt_gps_lna_pin == 0) { + /* EEDI needed */ + pCmbPinCtrl = &gCmbPinCtrl[CMB_PIN_EEDI_ID]; + } else if (pConf->wmt_gps_lna_pin == 1) { + /* EEDO needed */ + pCmbPinCtrl = &gCmbPinCtrl[CMB_PIN_EEDO_ID]; + } + regNum = pCmbPinCtrl->regNum; + for (i = 0; i < regNum; i++) { + pReg = + funcStatus == FUNC_ON ? &pCmbPinCtrl->pFuncOnArray[i] : + &pCmbPinCtrl->pFuncOffArray[i]; + regAddr = pReg->regAddr; + regValue = pReg->regValue; + regMask = pReg->regMask; + + iRet = wmt_core_reg_rw_raw(1, regAddr, ®Value, regMask); + if (iRet) { + WMT_ERR_FUNC + ("set reg for GPS_LNA function fail(%d)\n", + iRet); + /* TODO:[FixMe][Chaozhong] error handling? */ + return -3; + } + } + WMT_INFO_FUNC("ctrl combo chip gps lna succeed\n"); + } else { + WMT_INFO_FUNC + ("set reg for GPS_LNA function okay by chip ic_pin_ctrl\n"); + } + } + } + return 0; + +} + +INT32 wmt_func_gps_pre_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) +{ + return wmt_func_gps_pre_ctrl(pOps, pConf, FUNC_ON); +} + +INT32 wmt_func_gps_pre_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) +{ + + return wmt_func_gps_pre_ctrl(pOps, pConf, FUNC_OFF); +} + + +INT32 wmt_func_gps_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) +{ + INT32 iRet = 0; + unsigned long ctrlPa1; + unsigned long ctrlPa2; + UINT8 co_clock_type = 0; + + if (!pConf) + return -1; + + co_clock_type = (pConf->co_clock_flag & 0x0f); + + if (wmt_detect_get_chip_type() == WMT_CHIP_TYPE_SOC) { + if ((co_clock_type) && (pConf->wmt_gps_lna_enable == 0)) { /* use SOC external LNA */ + if (!osal_test_bit(WMT_FM_ON, &gGpsFmState) && !osal_test_bit(WMT_GPSL5_ON, &gGpsFmState)) { + ctrlPa1 = GPS_PALDO; + ctrlPa2 = PALDO_ON; + wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); + } else { + WMT_INFO_FUNC("LDO VCN28 has been turn on by FM or GPSL5\n"); + } + } + } + if (!osal_test_bit(WMT_GPSL5_ON, &gGpsFmState)) + iRet = wmt_func_gps_pre_on(pOps, pConf); + else + WMT_INFO_FUNC("gps has been pre on by GPSL5\n"); + if (iRet == 0) { + if (!pConf || pConf->wmt_gps_suspend_ctrl == 0) + iRet = wmt_func_gps_ctrl(FUNC_ON); + if (wmt_detect_get_chip_type() == WMT_CHIP_TYPE_SOC) { + if (!iRet) { + osal_set_bit(WMT_GPS_ON, &gBtWifiGpsState); + if ((co_clock_type) && (pConf->wmt_gps_lna_enable == 0)) /* use SOC external LNA */ + osal_set_bit(WMT_GPS_ON, &gGpsFmState); + osal_clear_bit(WMT_GPS_SUSPEND, &gGpsFmState); + } + } + } + return iRet; +} + +INT32 wmt_func_gps_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) +{ + INT32 iRet = 0; + unsigned long ctrlPa1 = 0; + unsigned long ctrlPa2 = 0; + UINT8 co_clock_type = 0; + + if (!pConf) + return -1; + + co_clock_type = (pConf->co_clock_flag & 0x0f); + + if (osal_test_bit(WMT_GPSL5_ON, &gGpsFmState)) + WMT_INFO_FUNC("GPSL5 is still on, do not pre off gps\n"); + else if (!osal_test_bit(WMT_GPS_SUSPEND, &gGpsFmState)) + iRet = wmt_func_gps_pre_off(pOps, pConf); + if (iRet == 0) { + if (!pConf || pConf->wmt_gps_suspend_ctrl == 0) + iRet = wmt_func_gps_ctrl(FUNC_OFF); + if (wmt_detect_get_chip_type() == WMT_CHIP_TYPE_SOC) { + if (!iRet) + osal_clear_bit(WMT_GPS_ON, &gBtWifiGpsState); + } + } + if (wmt_detect_get_chip_type() == WMT_CHIP_TYPE_SOC) { + if ((co_clock_type) && (pConf->wmt_gps_lna_enable == 0)) { /* use SOC external LNA */ + if (osal_test_bit(WMT_FM_ON, &gGpsFmState) || osal_test_bit(WMT_GPSL5_ON, &gGpsFmState)) + WMT_INFO_FUNC("FM or GPSL5 is still on, do not turn off LDO VCN28\n"); + else if (osal_test_bit(WMT_GPS_SUSPEND, &gGpsFmState)) + WMT_INFO_FUNC("It's GPS suspend mode, LDO VCN28 has been turned off\n"); + else { + ctrlPa1 = GPS_PALDO; + ctrlPa2 = PALDO_OFF; + wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); + } + osal_clear_bit(WMT_GPS_ON, &gGpsFmState); + } + if (pConf->wmt_gps_suspend_ctrl == 1) + osal_set_bit(WMT_GPS_SUSPEND, &gGpsFmState); + } + return iRet; + +} +#endif + +#if CFG_FUNC_GPSL5_SUPPORT +INT32 _osal_inline_ wmt_func_gpsl5_ctrl(ENUM_FUNC_STATE funcState) +{ + /*send turn GPS subsystem wmt command */ + return wmt_core_func_ctrl_cmd(6, + (FUNC_ON == + funcState) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE); +} + +INT32 wmt_func_gpsl5_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) +{ + INT32 iRet = 0; + unsigned long ctrlPa1; + unsigned long ctrlPa2; + UINT8 co_clock_type = 0; + + if (!pConf) { + WMT_INFO_FUNC("pConf == NULL\n"); + return -1; + } + + co_clock_type = (pConf->co_clock_flag & 0x0f); + + if (wmt_detect_get_chip_type() == WMT_CHIP_TYPE_SOC) { + if ((co_clock_type) && (pConf->wmt_gps_lna_enable == 0)) { /* use SOC external LNA */ + if (!osal_test_bit(WMT_FM_ON, &gGpsFmState) && + !osal_test_bit(WMT_GPS_ON, &gGpsFmState)) { + ctrlPa1 = GPS_PALDO; + ctrlPa2 = PALDO_ON; + wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); + } else { + WMT_INFO_FUNC("LDO VCN28 has been turn on by FM or GPSL1\n"); + } + } + } + if (!osal_test_bit(WMT_GPS_ON, &gGpsFmState)) + iRet = wmt_func_gps_pre_on(pOps, pConf); + else + WMT_INFO_FUNC("gps has been pre on by GPSL1\n"); + if (iRet == 0) { + if (pConf->wmt_gps_suspend_ctrl == 0) + iRet = wmt_func_gpsl5_ctrl(FUNC_ON); + if (wmt_detect_get_chip_type() == WMT_CHIP_TYPE_SOC) { + if (!iRet) { + osal_set_bit(WMT_GPSL5_ON, &gBtWifiGpsState); + if ((co_clock_type) && (pConf->wmt_gps_lna_enable == 0)) /* use SOC external LNA */ + osal_set_bit(WMT_GPSL5_ON, &gGpsFmState); + osal_clear_bit(WMT_GPSL5_SUSPEND, &gGpsFmState); + } + } + } + return iRet; +} + +INT32 wmt_func_gpsl5_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) +{ + INT32 iRet = 0; + unsigned long ctrlPa1 = 0; + unsigned long ctrlPa2 = 0; + UINT8 co_clock_type = 0; + + if (!pConf) { + WMT_INFO_FUNC("pConf == NULL\n"); + return -1; + } + + co_clock_type = (pConf->co_clock_flag & 0x0f); + + if (osal_test_bit(WMT_GPS_ON, &gGpsFmState)) + WMT_INFO_FUNC("GPSL1 is still on, do not pre off gps\n"); + else if (!osal_test_bit(WMT_GPSL5_SUSPEND, &gGpsFmState)) + iRet = wmt_func_gps_pre_off(pOps, pConf); + if (iRet == 0) { + if (pConf->wmt_gps_suspend_ctrl == 0) + iRet = wmt_func_gpsl5_ctrl(FUNC_OFF); + if (wmt_detect_get_chip_type() == WMT_CHIP_TYPE_SOC) { + if (!iRet) + osal_clear_bit(WMT_GPSL5_ON, &gBtWifiGpsState); + } + } + if (wmt_detect_get_chip_type() == WMT_CHIP_TYPE_SOC) { + if ((co_clock_type) && (pConf->wmt_gps_lna_enable == 0)) { /* use SOC external LNA */ + if (osal_test_bit(WMT_FM_ON, &gGpsFmState) || osal_test_bit(WMT_GPS_ON, &gGpsFmState)) + WMT_INFO_FUNC("FM or GPSL1 is still on, do not turn off LDO VCN28\n"); + else if (osal_test_bit(WMT_GPSL5_SUSPEND, &gGpsFmState)) + WMT_INFO_FUNC("It's GPS suspend mode, LDO VCN28 has been turned off\n"); + else { + ctrlPa1 = GPS_PALDO; + ctrlPa2 = PALDO_OFF; + wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); + } + osal_clear_bit(WMT_GPSL5_ON, &gGpsFmState); + } + if (pConf->wmt_gps_suspend_ctrl == 1) + osal_set_bit(WMT_GPSL5_SUSPEND, &gGpsFmState); + } + return iRet; + +} +#endif + +#if CFG_FUNC_FM_SUPPORT + +INT32 _osal_inline_ wmt_func_fm_ctrl(ENUM_FUNC_STATE funcState) +{ + /*only need to send turn FM subsystem wmt command */ + return wmt_core_func_ctrl_cmd(WMTDRV_TYPE_FM, + (FUNC_ON == + funcState) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE); +} + + +INT32 wmt_func_fm_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) +{ + ULONG ctrlPa1 = 0; + ULONG ctrlPa2 = 0; + INT32 iRet = -1; + UINT8 co_clock_type = (pConf->co_clock_flag & 0x0f); + + if (wmt_detect_get_chip_type() == WMT_CHIP_TYPE_SOC) { + if (co_clock_type) { + if (!osal_test_bit(WMT_GPS_ON, &gGpsFmState) && !osal_test_bit(WMT_GPSL5_ON, &gGpsFmState)) { + ctrlPa1 = FM_PALDO; + ctrlPa2 = PALDO_ON; + wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); + } else { + WMT_INFO_FUNC("LDO VCN28 has been turn on by GPS\n"); + } + } else + WMT_ERR_FUNC("wmt-func: co_clock_type is not 1!\n"); + iRet = wmt_core_func_ctrl_cmd(WMTDRV_TYPE_FM, MTK_WCN_BOOL_TRUE); + if (!iRet) { + if (co_clock_type) + osal_set_bit(WMT_FM_ON, &gGpsFmState); + } + return iRet; + } + return wmt_core_func_ctrl_cmd(WMTDRV_TYPE_FM, MTK_WCN_BOOL_TRUE); +} + +INT32 wmt_func_fm_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) +{ + ULONG ctrlPa1 = 0; + ULONG ctrlPa2 = 0; + INT32 iRet = -1; + UINT8 co_clock_type = (pConf->co_clock_flag & 0x0f); + + if (wmt_detect_get_chip_type() == WMT_CHIP_TYPE_SOC) { + iRet = wmt_core_func_ctrl_cmd(WMTDRV_TYPE_FM, MTK_WCN_BOOL_FALSE); + if (co_clock_type) { + if (osal_test_bit(WMT_GPS_ON, &gGpsFmState) || osal_test_bit(WMT_GPSL5_ON, &gGpsFmState)) { + WMT_INFO_FUNC("GPS is still on, do not turn off LDO VCN28\n"); + } else { + ctrlPa1 = FM_PALDO; + ctrlPa2 = PALDO_OFF; + wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); + } + osal_clear_bit(WMT_FM_ON, &gGpsFmState); + } + return iRet; + } + return wmt_core_func_ctrl_cmd(WMTDRV_TYPE_FM, MTK_WCN_BOOL_FALSE); +} + +#endif + +#if CFG_FUNC_WIFI_SUPPORT + +INT32 wmt_func_wifi_ctrl(ENUM_FUNC_STATE funcState) +{ + INT32 iRet = 0; + ULONG ctrlPa1 = WMT_SDIO_FUNC_WIFI; + ULONG ctrlPa2 = (funcState == FUNC_ON) ? 1 : 0; /* turn on Wi-Fi driver */ + + iRet = wmt_core_ctrl(WMT_CTRL_SDIO_FUNC, &ctrlPa1, &ctrlPa2); + if (iRet) { + WMT_ERR_FUNC("WMT-FUNC: turn on WIFI function fail (%d)", iRet); + return -1; + } + return 0; +} + + +INT32 wmt_func_wifi_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) +{ + INT32 iRet = 0; + + if (wmt_detect_get_chip_type() == WMT_CHIP_TYPE_COMBO) + return wmt_func_wifi_ctrl(FUNC_ON); + + if (mtk_wcn_wlan_probe != NULL) { + WMT_WARN_FUNC("WMT-FUNC: wmt wlan func on before wlan probe\n"); + iRet = (*mtk_wcn_wlan_probe) (); + if (iRet) { + WMT_ERR_FUNC("WMT-FUNC: wmt call wlan probe fail(%d)\n", iRet); + iRet = -1; + } else { + WMT_WARN_FUNC("WMT-FUNC: wmt call wlan probe ok\n"); + } + } else { + WMT_ERR_FUNC("WMT-FUNC: null pointer mtk_wcn_wlan_probe\n"); + gWifiProbed = 1; + iRet = -2; + } + if (!iRet) + osal_set_bit(WMT_WIFI_ON, &gBtWifiGpsState); + return iRet; +} + +INT32 wmt_func_wifi_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) +{ + INT32 iRet = 0; + + if (wmt_detect_get_chip_type() == WMT_CHIP_TYPE_COMBO) + return wmt_func_wifi_ctrl(FUNC_OFF); + + if (mtk_wcn_wlan_remove != NULL) { + WMT_WARN_FUNC("WMT-FUNC: wmt wlan func on before wlan remove\n"); + iRet = (*mtk_wcn_wlan_remove) (); + if (iRet) { + WMT_ERR_FUNC("WMT-FUNC: wmt call wlan remove fail(%d)\n", iRet); + iRet = -1; + } else { + WMT_WARN_FUNC("WMT-FUNC: wmt call wlan remove ok\n"); + } + } else { + WMT_ERR_FUNC("WMT-FUNC: null pointer mtk_wcn_wlan_remove\n"); + iRet = -2; + } + if (!iRet) + osal_clear_bit(WMT_WIFI_ON, &gBtWifiGpsState); + return iRet; +} +#endif diff --git a/drivers/misc/mediatek/connectivity/common/common_main/core/wmt_ic_6620.c b/drivers/misc/mediatek/connectivity/common/common_main/core/wmt_ic_6620.c new file mode 100644 index 0000000000000000000000000000000000000000..9b033ad92dd4c42183bc86b441884bede8a69d49 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/core/wmt_ic_6620.c @@ -0,0 +1,1909 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +#ifdef DFT_TAG +#undef DFT_TAG +#endif +#define DFT_TAG "[WMT-IC]" + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include "osal_typedef.h" +#include "osal.h" +#include "wmt_ic.h" +#include "wmt_core.h" +#include "wmt_lib.h" +#include "stp_core.h" + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +#define DEFAULT_PATCH_FRAG_SIZE (1000) +#define MT6620E2_PATCH_FRAG_SIZE (900) +#define WMT_PATCH_FRAG_1ST (0x1) +#define WMT_PATCH_FRAG_MID (0x2) +#define WMT_PATCH_FRAG_LAST (0x3) + +#define CFG_CHECK_WMT_RESULT (1) +/* BT Port 2 Feature. this command does not need after coex command is downconfirmed by LC, */ +#define CFG_WMT_BT_PORT2 (0) + +#define CFG_SET_OPT_REG (0) +#define CFG_WMT_I2S_DBGUART_SUPPORT (0) +#define CFG_SET_OPT_REG_SWLA (0) +#define CFG_SET_OPT_REG_MCUCLK (0) +#define CFG_SET_OPT_REG_MCUIRQ (0) + +#define CFG_WMT_COREDUMP_ENABLE 0 + +#define CFG_WMT_MULTI_PATCH (1) +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ +#if !(CFG_WMT_MULTI_PATCH) +static UINT8 gDefPatchName[NAME_MAX + 1]; +#endif +static UINT8 gFullPatchName[NAME_MAX + 1]; +static const WMT_IC_INFO_S *gp_mt6620_info; +static WMT_PATCH gp_mt6620_patch_info; + +static UINT8 WMT_WAKEUP_DIS_GATE_CMD[] = { 0x1, 0x3, 0x01, 0x00, 0x04 }; +static UINT8 WMT_WAKEUP_DIS_GATE_EVT[] = { 0x2, 0x3, 0x02, 0x0, 0x0, 0x04 }; + +#if 0 +static UINT8 WMT_WAKEUP_EN_GATE_CMD[] = { 0x1, 0x3, 0x01, 0x00, 0x05 }; +static UINT8 WMT_WAKEUP_EN_GATE_EVT[] = { 0x2, 0x3, 0x02, 0x0, 0x0, 0x05 }; +#endif +static UINT8 WMT_QUERY_BAUD_CMD[] = { 0x01, 0x04, 0x01, 0x00, 0x02 }; +static UINT8 WMT_QUERY_BAUD_EVT_115200[] = { 0x02, 0x04, 0x06, 0x00, 0x00, 0x02, 0x00, 0xC2, 0x01, 0x00 }; +static UINT8 WMT_QUERY_BAUD_EVT_X[] = { 0x02, 0x04, 0x06, 0x00, 0x00, 0x02, 0xAA, 0xAA, 0xAA, 0xBB }; +static UINT8 WMT_QUERY_STP_CMD[] = { 0x01, 0x04, 0x01, 0x00, 0x04 }; +static UINT8 WMT_QUERY_STP_EVT_DEFAULT[] = { 0x02, 0x04, 0x06, 0x00, 0x00, 0x04, 0x11, 0x00, 0x00, 0x00 }; +static UINT8 WMT_QUERY_STP_EVT_UART[] = { 0x02, 0x04, 0x06, 0x00, 0x00, 0x04, 0xDF, 0x0E, 0x68, 0x01 }; +static UINT8 WMT_SET_BAUD_CMD_X[] = { 0x01, 0x04, 0x05, 0x00, 0x01, 0xAA, 0xAA, 0xAA, 0xBB }; +static UINT8 WMT_SET_BAUD_EVT[] = { 0x02, 0x04, 0x02, 0x00, 0x00, 0x01 }; +static UINT8 WMT_SET_WAKEUP_WAKE_CMD_RAW[] = { 0xFF }; +static UINT8 WMT_SET_WAKEUP_WAKE_EVT[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x03 }; + +#if CFG_WMT_MULTI_PATCH +static UINT8 WMT_PATCH_ADDRESS_CMD[] = { 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, + 0x64, 0x0E, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff +}; +static UINT8 WMT_PATCH_ADDRESS_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; + +static UINT8 WMT_PATCH_P_ADDRESS_CMD[] = { 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, + 0x38, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff +}; +static UINT8 WMT_PATCH_P_ADDRESS_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; +#endif + +static UINT8 WMT_PATCH_CMD[] = { 0x01, 0x01, 0x00, 0x00, 0x00 }; +static UINT8 WMT_PATCH_EVT[] = { 0x02, 0x01, 0x01, 0x00, 0x00 }; +static UINT8 WMT_RESET_CMD[] = { 0x01, 0x07, 0x01, 0x00, 0x04 }; +static UINT8 WMT_RESET_EVT[] = { 0x02, 0x07, 0x01, 0x00, 0x00 }; + +#if CFG_WMT_BT_PORT2 +static UINT8 WMT_BTP2_CMD[] = { 0x01, 0x10, 0x03, 0x00, 0x01, 0x03, 0x01 }; +static UINT8 WMT_BTP2_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; +#endif +/*coex cmd/evt++*/ +static UINT8 WMT_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x04, 0x00, 0x01, 0xAA, 0xBB, 0xCC }; +static UINT8 WMT_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; + +static UINT8 WMT_BT_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x0B, + 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, + 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0xAA +}; +static UINT8 WMT_BT_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; + +static UINT8 WMT_WIFI_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x0C, + 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0xAA +}; +static UINT8 WMT_WIFI_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; + +static UINT8 WMT_PTA_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x0A, + 0x00, 0x04, + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xEE, 0xFF, 0xFF, 0xFE +}; +static UINT8 WMT_PTA_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; + +static UINT8 WMT_MISC_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x09, + 0x00, 0x05, + 0xAA, 0xAA, 0xAA, 0xAA, + 0xBB, 0xBB, 0xBB, 0xBB +}; +static UINT8 WMT_MISC_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; + +/*coex cmd/evt--*/ +static UINT8 WMT_SET_STP_CMD[] = { 0x01, 0x04, 0x05, 0x00, 0x03, 0xDF, 0x0E, 0x68, 0x01 }; +static UINT8 WMT_SET_STP_EVT[] = { 0x02, 0x04, 0x02, 0x00, 0x00, 0x03 }; +static UINT8 WMT_STRAP_CONF_CMD_FM_COMM[] = { 0x01, 0x05, 0x02, 0x00, 0x02, 0x02 }; +static UINT8 WMT_STRAP_CONF_EVT[] = { 0x02, 0x05, 0x02, 0x00, 0x00, 0x02 }; + +#if 0 +static UINT8 WMT_SET_OSC32K_BYPASS_CMD[] = { 0x01, 0x0A, 0x01, 0x00, 0x05 }; +static UINT8 WMT_SET_OSC32K_BYPASS_EVT[] = { 0x02, 0x0A, 0x01, 0x00, 0x00 }; +#endif + +static UINT8 WMT_CORE_DUMP_LEVEL_04_CMD[] = { 0x1, 0x0F, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +static UINT8 WMT_CORE_DUMP_LEVEL_04_EVT[] = { 0x2, 0x0F, 0x01, 0x00, 0x00 }; + +/* enable all interrupt */ +static UINT8 WMT_SET_ALLINT_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ + , 0x01 /* op: w */ + , 0x01 /*type: reg */ + , 0x00 /*rev */ + , 0x01 /*1 registers */ + , 0x00, 0x03, 0x05, 0x80 /*addr:0x80050300 */ + , 0x00, 0xC4, 0x00, 0x00 /*value:0x0000C400 */ + , 0x00, 0xC4, 0x00, 0x00 /*mask:0x0000C400 */ +}; + +static UINT8 WMT_SET_ALLINT_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ + , 0x00 /*S: 0 */ + , 0x00 /*type: reg */ + , 0x00 /*rev */ + , 0x01 /*1 registers */ +}; + +#if CFG_SET_OPT_REG_SWLA /* enable swla: eesk(7) eecs(8) oscen(19) sck0(24) scs0(25) */ +static UINT8 WMT_SET_SWLA_REG_CMD[] = { 0x01, 0x08, 0x1C, 0x00 /*length */ + , 0x01 /* op: w */ + , 0x01 /*type: reg */ + , 0x00 /*rev */ + , 0x02 /*2 registers */ + , 0x10, 0x01, 0x05, 0x80 /*addr:0x80050110 */ + , 0x10, 0x10, 0x01, 0x00 /*value:0x00011010 */ + , 0xF0, 0xF0, 0x0F, 0x00 /*mask:0x000FF0F0 */ + , 0x40, 0x01, 0x05, 0x80 /*addr:0x80050140 */ + , 0x00, 0x10, 0x01, 0x00 /*value:0x00011000 */ + , 0x00, 0xF0, 0x0F, 0x00 /*mask:0x000FF000 */ +}; + +static UINT8 WMT_SET_SWLA_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ + , 0x00 /*S: 0 */ + , 0x00 /*type: reg */ + , 0x00 /*rev */ + , 0x02 /*2 registers */ +}; +#endif + +#if CFG_SET_OPT_REG_MCUCLK /* enable mcu clk: antsel_4, eedi */ +static UINT8 WMT_SET_MCUCLK_REG_CMD[] = { 0x01, 0x08, (4 + 12 * 4), 0x00 /*length */ + , 0x01 /* op: w */ + , 0x01 /* type: reg */ + , 0x00 /* rev */ + , 0x04 /* 4 registers */ + , 0x00, 0x04, 0x00, 0x80 /* addr:0x8000 0400 */ + , 0x00, 0x14, 0x00, 0x00 /* value:0x0000 1400(osc, hclk), 0x0000 1501(PLL, en) */ + , 0xFF, 0xFF, 0x00, 0x00 /* mask:0x0000 FFFF */ + , 0x80, 0x01, 0x05, 0x80 /* addr:0x8005 0180 */ + , 0x12, 0x13, 0x00, 0x00 /* value:0x0000 1312(osc, hclk), 0x0000 1a19(PLL, en) */ + , 0xFF, 0xFF, 0x00, 0x00 /* mask:0x0000 FFFF */ + , 0x00, 0x01, 0x05, 0x80 /* addr:0x8005 0100 */ + , 0x00, 0x00, 0x02, 0x00 /* value:0x0002 0000 */ + , 0x00, 0x00, 0x0F, 0x00 /* mask:0x000F 0000 */ + , 0x10, 0x01, 0x05, 0x80 /* addr:0x8005 0110 */ + , 0x02, 0x00, 0x00, 0x00 /* value:0x0000 0002 */ + , 0x0F, 0x00, 0x00, 0x00 /* mask:0x0000 000F */ +}; + +static UINT8 WMT_SET_MCUCLK_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ + , 0x00 /* S: 0 */ + , 0x00 /* type: reg */ + , 0x00 /* rev */ + , 0x04 /* 4 registers */ +}; +#endif + +#if CFG_WMT_I2S_DBGUART_SUPPORT /* register write for debug uart */ +static UINT8 WMT_SET_DBGUART_REG_CMD[] = { 0x01, 0x08, 0x1C, 0x00 /*length */ + , 0x01 /* op: w */ + , 0x01 /*type: reg */ + , 0x00 /*rev */ + , 0x02 /*2 registers */ + , 0x30, 0x01, 0x05, 0x80 /*addr:0x80050130 */ + , 0x00, 0x00, 0x00, 0x00 /*value:0x00000000 */ + , 0xF0, 0x0F, 0x00, 0x00 /*mask:0x00000FF0 */ + , 0x40, 0x01, 0x05, 0x80 /*addr:0x80050140 */ + , 0x00, 0x01, 0x00, 0x00 /*value:0x00000100 */ + , 0x00, 0x01, 0x00, 0x00 /*mask:0x00000100 */ +}; + +static UINT8 WMT_SET_DBGUART_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ + , 0x00 /*S: 0 */ + , 0x00 /*type: reg */ + , 0x00 /*rev */ + , 0x02 /*2 registers */ +}; +#endif + +#if CFG_SET_OPT_REG_MCUIRQ /* enable mcu irq: antsel_4, wlan_act */ +#if 1 /* Ray */ +static UINT8 WMT_SET_MCUIRQ_REG_CMD[] = { 0x01, 0x08, (4 + 12 * 4), 0x00 /*length */ + , 0x01 /* op: w */ + , 0x01 /* type: reg */ + , 0x00 /* rev */ + , 0x04 /* 4 registers */ + , 0x00, 0x04, 0x00, 0x80 /* addr:0x8000_0400 */ + , 0x03, 0x14, 0x00, 0x00 /* value:0x0000_1403 check confg debug flag 3 low word */ + , 0xFF, 0xFF, 0x00, 0x00 /* mask:0x0000_FFFF */ + /* cirq_int_n */ + , 0x10, 0x01, 0x05, 0x80 /* addr:0x8005_0110 */ + , 0x02, 0x00, 0x00, 0x00 /* value:0x0000_0002 set EEDI as cirq_int_n debug flag (monitor flag2) */ + , 0x07, 0x00, 0x00, 0x00 /* mask:0x0000_0007 */ + , 0x00, 0x01, 0x05, 0x80 /* addr:0x8005_0100 */ + , 0x00, 0x00, 0x02, 0x00 /* value:0x0002_0000 (ANTSEL4=>monitor flag 0, ahb_x2_gt_ck debug flag) */ + , 0x00, 0x00, 0x07, 0x00 /* mask:0x0007_0000 */ + /* 1. ARM irq_b, monitor flag 0 */ + , 0x80, 0x01, 0x05, 0x80 /* addr:0x8005_0180 */ + , 0x1F, 0x1E, 0x00, 0x00 /* value:0x0000_1E1F check mcusys debug flag */ + , 0x7F, 0x7F, 0x00, 0x00 /* mask:0x0000_7F7F */ +}; + +static UINT8 WMT_SET_MCUIRQ_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ + , 0x00 /* S: 0 */ + , 0x00 /* type: reg */ + , 0x00 /* rev */ + , 0x04 /* 5 registers */ +}; +#elif 0 /* KC */ +static UINT8 WMT_SET_MCUIRQ_REG_CMD[] = { 0x01, 0x08, (4 + 12 * 5), 0x00 /*length */ + , 0x01 /* op: w */ + , 0x01 /* type: reg */ + , 0x00 /* rev */ + , 0x05 /* 5 registers */ + , 0x00, 0x04, 0x00, 0x80 /* addr:0x8000_0400 */ + , 0x00, 0x02, 0x00, 0x00 /* value:0x0000_0200 [15:8]=0x2 arm irq_b, 0xA irq_bus[5] bt_timcon_irq_b */ + , 0x00, 0xFF, 0x00, 0x00 /* mask:0x0000_FF00 */ + /* 1. ARM irq_b, monitor flag 0 */ + , 0x80, 0x01, 0x05, 0x80 /* addr:0x8005_0180 */ + , 0x18, 0x00, 0x00, 0x00 /* value:0x0000_0018 [6:0]=001_1000 (monitor flag 0 select, MCUSYS, SEL:8) */ + , 0x7F, 0x00, 0x00, 0x00 /* mask:0x0000_007F */ + , 0x00, 0x01, 0x05, 0x80 /* addr:0x8005_0100 */ + , 0x00, 0x00, 0x02, 0x00 /* value:0x0002_0000 (ANTSEL4=>monitor flag 0) */ + , 0x00, 0x00, 0x07, 0x00 /* mask:0x0007_0000 */ + /* 2. irq_bus[5] bt_timcon_irq_b monitor flag 15 */ + , 0xB0, 0x01, 0x05, 0x80 /* addr:0x8005_01B0 */ + , 0x00, 0x00, 0x00, 0x16 /* value:0x1600_0000 [30:24]=001_0110 (monitor flag 15 select, MCUSYS, SEL:6) */ + , 0x00, 0x00, 0x00, 0x7F /* mask:0x7F00_0000 */ + , 0x30, 0x01, 0x05, 0x80 /* addr:0x8005_0130 */ + , 0x00, 0x20, 0x00, 0x00 /* value:0x0000_2000 (WLAN_ACT=>monitor flag 15) */ + , 0x00, 0x70, 0x00, 0x00 /* mask:0x0000_7000 */ +}; + +static UINT8 WMT_SET_MCUIRQ_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ + , 0x00 /* S: 0 */ + , 0x00 /* type: reg */ + , 0x00 /* rev */ + , 0x05 /* 5 registers */ +}; +#endif +#endif + +/* stp sdio init scripts */ +static struct init_script init_table_1_1[] = { + /* table_1_1 is only applied to common SDIO interface */ + INIT_CMD(WMT_SET_ALLINT_REG_CMD, WMT_SET_ALLINT_REG_EVT, "enable all interrupt"), + /* only applied to MT6620 E1/E2? */ + INIT_CMD(WMT_WAKEUP_DIS_GATE_CMD, WMT_WAKEUP_DIS_GATE_EVT, "disable gating"), +}; + + +static struct init_script init_table_1_2[] = { + INIT_CMD(WMT_QUERY_BAUD_CMD, WMT_QUERY_BAUD_EVT_115200, "query baud 115200"), + INIT_CMD(WMT_QUERY_STP_CMD, WMT_QUERY_STP_EVT_DEFAULT, "query stp default"), + INIT_CMD(WMT_SET_BAUD_CMD_X, WMT_SET_BAUD_EVT, "set baud rate"), +}; + +static struct init_script init_table_2[] = { + INIT_CMD(WMT_QUERY_BAUD_CMD, WMT_QUERY_BAUD_EVT_X, "query baud X"), +}; + +static struct init_script init_table_3[] = { + INIT_CMD(WMT_RESET_CMD, WMT_RESET_EVT, "wmt reset"), +#if CFG_WMT_BT_PORT2 + INIT_CMD(WMT_BTP2_CMD, WMT_BTP2_EVT, "set bt port2"), +#endif +}; + +#if 0 +static struct init_script init_table_3_1[] = { + INIT_CMD(WMT_WAKEUP_EN_GATE_CMD, WMT_WAKEUP_EN_GATE_EVT, "ensable gating"), +}; +#endif + +static struct init_script init_table_4[] = { + INIT_CMD(WMT_SET_STP_CMD, WMT_SET_STP_EVT, "set stp"), +}; + +static struct init_script init_table_5[] = { + INIT_CMD(WMT_QUERY_STP_CMD, WMT_QUERY_STP_EVT_UART, "query stp uart"), + INIT_CMD(WMT_QUERY_BAUD_CMD, WMT_QUERY_BAUD_EVT_X, "query baud X"), +}; + +static struct init_script init_table_5_1[] = { + INIT_CMD(WMT_STRAP_CONF_CMD_FM_COMM, WMT_STRAP_CONF_EVT, "configure FM comm"), +}; + +static struct init_script init_table_6[] = { +#if 0 + INIT_CMD(WMT_SET_OSC32K_BYPASS_CMD, WMT_SET_OSC32K_BYPASS_EVT, "set OSC32k by pass mode."), +#endif + INIT_CMD(WMT_CORE_DUMP_LEVEL_04_CMD, WMT_CORE_DUMP_LEVEL_04_EVT, "setup core dump level"), +}; + +#if defined(CFG_SET_OPT_REG) && CFG_SET_OPT_REG +static struct init_script set_registers[] = { + /* INIT_CMD(WMT_SET_GPS_REG_CMD, WMT_SET_GPS_REG_EVT, "set wmt registers"), */ + /* INIT_CMD(WMT_SET_SDIODRV_REG_CMD, WMT_SET_SDIODRV_REG_EVT, "set SDIO driving registers") */ +#if CFG_WMT_I2S_DBGUART_SUPPORT + INIT_CMD(WMT_SET_DBGUART_REG_CMD, WMT_SET_DBGUART_REG_EVT, "set debug uart registers"), +#endif +#if CFG_SET_OPT_REG_SWLA + INIT_CMD(WMT_SET_SWLA_REG_CMD, WMT_SET_SWLA_REG_EVT, "set swla registers"), +#endif +#if CFG_SET_OPT_REG_MCUCLK + INIT_CMD(WMT_SET_MCUCLK_REG_CMD, WMT_SET_MCUCLK_REG_EVT, "set mcuclk dbg registers"), +#endif +#if CFG_SET_OPT_REG_MCUIRQ + INIT_CMD(WMT_SET_MCUIRQ_REG_CMD, WMT_SET_MCUIRQ_REG_EVT, "set mcu irq dbg registers"), +#endif +}; +#endif + +static struct init_script coex_table[] = { + INIT_CMD(WMT_COEX_SETTING_CONFIG_CMD, WMT_COEX_SETTING_CONFIG_EVT, "coex_wmt"), + INIT_CMD(WMT_BT_COEX_SETTING_CONFIG_CMD, WMT_BT_COEX_SETTING_CONFIG_EVT, "coex_bt"), + INIT_CMD(WMT_WIFI_COEX_SETTING_CONFIG_CMD, WMT_WIFI_COEX_SETTING_CONFIG_EVT, "coex_wifi"), + INIT_CMD(WMT_PTA_COEX_SETTING_CONFIG_CMD, WMT_PTA_COEX_SETTING_CONFIG_EVT, "coex_ext_pta"), + INIT_CMD(WMT_MISC_COEX_SETTING_CONFIG_CMD, WMT_MISC_COEX_SETTING_CONFIG_EVT, "coex_misc"), +}; + +/* MT6620 Chip Version and Info Table */ +static const WMT_IC_INFO_S mt6620_info_table[] = { + { + .u4HwVer = 0x8A00, + .cChipName = WMT_IC_NAME_MT6620, + .cChipVersion = WMT_IC_VER_E1, + .cPatchNameExt = WMT_IC_PATCH_NO_EXT, + .bWorkWithoutPatch = MTK_WCN_BOOL_FALSE, + .bPsmSupport = MTK_WCN_BOOL_FALSE, + }, + { + .u4HwVer = 0x8A01, + .cChipName = WMT_IC_NAME_MT6620, + .cChipVersion = WMT_IC_VER_E2, + .cPatchNameExt = WMT_IC_PATCH_NO_EXT, + .bWorkWithoutPatch = MTK_WCN_BOOL_FALSE, + .bPsmSupport = MTK_WCN_BOOL_FALSE, + }, + { + .u4HwVer = 0x8A10, + .cChipName = WMT_IC_NAME_MT6620, + .cChipVersion = WMT_IC_VER_E3, + .cPatchNameExt = WMT_IC_PATCH_E3_EXT, + .bWorkWithoutPatch = MTK_WCN_BOOL_FALSE, + .bPsmSupport = MTK_WCN_BOOL_TRUE, + }, + { + .u4HwVer = 0x8A11, + .cChipName = WMT_IC_NAME_MT6620, + .cChipVersion = WMT_IC_VER_E4, + .cPatchNameExt = WMT_IC_PATCH_E3_EXT, + .bWorkWithoutPatch = MTK_WCN_BOOL_FALSE, + .bPsmSupport = MTK_WCN_BOOL_TRUE, + }, + { + .u4HwVer = 0x8A30, + .cChipName = WMT_IC_NAME_MT6620, + .cChipVersion = WMT_IC_VER_E6, + .cPatchNameExt = WMT_IC_PATCH_E6_EXT, + .bWorkWithoutPatch = MTK_WCN_BOOL_TRUE /*MTK_WCN_BOOL_FALSE */, + .bPsmSupport = MTK_WCN_BOOL_TRUE, + }, + { + .u4HwVer = 0x8B30, + .cChipName = WMT_IC_NAME_MT6620, + .cChipVersion = WMT_IC_VER_E6, + .cPatchNameExt = WMT_IC_PATCH_E6_EXT, + .bWorkWithoutPatch = MTK_WCN_BOOL_TRUE /*MTK_WCN_BOOL_FALSE */, + .bPsmSupport = MTK_WCN_BOOL_TRUE, + }, + { + .u4HwVer = 0x8B31, + .cChipName = WMT_IC_NAME_MT6620, + .cChipVersion = WMT_IC_VER_E7, + .cPatchNameExt = WMT_IC_PATCH_E6_EXT, + .bWorkWithoutPatch = MTK_WCN_BOOL_TRUE /*MTK_WCN_BOOL_FALSE */, + .bPsmSupport = MTK_WCN_BOOL_TRUE, + }, +}; + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +static INT32 mt6620_sw_init(P_WMT_HIF_CONF pWmtHifConf); + +static INT32 mt6620_sw_deinit(P_WMT_HIF_CONF pWmtHifConf); + +static INT32 mt6620_pin_ctrl(WMT_IC_PIN_ID id, WMT_IC_PIN_STATE state, UINT32 flag); + +static INT32 mt6620_aif_ctrl(WMT_IC_PIN_STATE state, UINT32 flag); + +static INT32 mt6620_ver_check(VOID); + +static const WMT_IC_INFO_S *mt6620_find_wmt_ic_info(const UINT32 hw_ver); + +static INT32 wmt_stp_init_coex(VOID); + +#if CFG_WMT_MULTI_PATCH +static INT32 mt6620_patch_dwn(UINT32 index); +static INT32 mt6620_patch_info_prepare(VOID); +#else +static INT32 mt6620_update_patch_name(VOID); + +static INT32 mt6620_patch_dwn(VOID); +#endif +static MTK_WCN_BOOL mt6620_quick_sleep_flag_get(VOID); + +static MTK_WCN_BOOL mt6620_aee_dump_flag_get(VOID); + + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/* MT6620 Operation Function Table */ +WMT_IC_OPS wmt_ic_ops_mt6620 = { + .icId = 0x6620, + .sw_init = mt6620_sw_init, + .sw_deinit = mt6620_sw_deinit, + .ic_pin_ctrl = mt6620_pin_ctrl, + .ic_ver_check = mt6620_ver_check, + .co_clock_ctrl = NULL, + .is_quick_sleep = mt6620_quick_sleep_flag_get, + .is_aee_dump_support = mt6620_aee_dump_flag_get, + .trigger_stp_assert = NULL, + .deep_sleep_ctrl = NULL, +}; + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +#if 0 +static INT32 mt6620_sw_init(P_WMT_HIF_CONF pWmtHifConf) +{ + INT32 iRet = -1; + UINT32 u4Res = 0; + UINT8 evtBuf[256]; + unsigned long ctrlPa1; + unsigned long ctrlPa2; + UINT32 hw_ver; + + WMT_DBG_FUNC(" start\n"); + + osal_assert(gp_mt6620_info != NULL); + if ((gp_mt6620_info == NULL) + || (pWmtHifConf == NULL) + ) { + WMT_ERR_FUNC("null pointers: gp_mt6620_info(0x%p), pWmtHifConf(0x%p)\n", + gp_mt6620_info, pWmtHifConf); + return -1; + } + + hw_ver = gp_mt6620_info->u4HwVer; + + /* 4 <3.1> start init for sdio */ + if (pWmtHifConf->hifType == WMT_HIF_SDIO) { + /* 1. enable all INT32 */ + /* 2. disable mcu gate (only MT6620E1/E2) */ + iRet = wmt_core_init_script(init_table_1_1, osal_array_size(init_table_1_1)); + if (iRet) { + WMT_ERR_FUNC("init_table_1_1 fail:%d\n", iRet); + osal_assert(0); + return -1; + } + } + /* 4 <3.2> start init for uart */ + if (pWmtHifConf->hifType == WMT_HIF_UART) { + /* init variable fields for script execution */ + osal_memcpy(&WMT_SET_BAUD_CMD_X[5], &pWmtHifConf->au4HifConf[0], + osal_sizeof(UINT32)); + WMT_SET_BAUD_CMD_X[8] = (UINT8) 0x00; /* 0xC0 MTK Flow Control no flow control */ + osal_memcpy(&WMT_QUERY_BAUD_EVT_X[6], &pWmtHifConf->au4HifConf[0], + osal_sizeof(UINT32)); + WMT_QUERY_BAUD_EVT_X[9] = (UINT8) 0x00; /* 0xC0 MTK Flow Control no flow control */ + /* 3. Query chip baud rate (TEST-ONLY) */ + /* 4. Query chip STP options (TEST-ONLY) */ + /* 5. Change chip baud rate: t_baud */ + /* WMT_DBG_FUNC("WMT-CORE: init_table_1_2 set chip baud:%d", pWmtHifConf->au4HifConf[0]); + */ + iRet = wmt_core_init_script(init_table_1_2, osal_array_size(init_table_1_2)); + if (iRet) { + WMT_ERR_FUNC("init_table_1_2 fail(%d)\n", iRet); + osal_assert(0); + return -2; + } + + /* 6. Set host baudrate and flow control */ + ctrlPa1 = pWmtHifConf->au4HifConf[0]; + ctrlPa2 = 0; + iRet = wmt_core_ctrl(WMT_CTRL_HOST_BAUDRATE_SET, &ctrlPa1, &ctrlPa2); + if (iRet) { + WMT_ERR_FUNC("change baudrate(%d) fail(%d)\n", pWmtHifConf->au4HifConf[0], + iRet); + return -3; + } + WMT_INFO_FUNC("WMT-CORE: change baudrate(%d) ok\n", pWmtHifConf->au4HifConf[0]); + + /* 7. Wake up chip and check event */ +/* iRet = (*kal_stp_tx_raw)(&WMT_SET_WAKEUP_WAKE_CMD_RAW[0], 1, &u4Res); */ + iRet = + wmt_core_tx((PUINT8)&WMT_SET_WAKEUP_WAKE_CMD_RAW[0], 1, &u4Res, + MTK_WCN_BOOL_TRUE); + if (iRet || (u4Res != 1)) { + WMT_ERR_FUNC("write raw iRet(%d) written(%d)\n", iRet, u4Res); + return -4; + } + + osal_memset(evtBuf, 0, osal_sizeof(evtBuf)); + iRet = wmt_core_rx(evtBuf, osal_sizeof(WMT_SET_WAKEUP_WAKE_EVT), &u4Res); +#ifdef CFG_DUMP_EVT + WMT_DBG_FUNC("WAKEUP_WAKE_EVT read len %d [%02x,%02x,%02x,%02x,%02x,%02x]\n", + (INT32) u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], + evtBuf[5]); +#endif + if (iRet || (u4Res != osal_sizeof(WMT_SET_WAKEUP_WAKE_EVT))) { + WMT_ERR_FUNC("read WAKEUP_WAKE_EVT fail(%d)\n", iRet); + return -5; + } + /* WMT_DBG_FUNC("WMT-CORE: read WMT_SET_WAKEUP_WAKE_EVT ok"); */ + +#if CFG_CHECK_WMT_RESULT + if (osal_memcmp + (evtBuf, WMT_SET_WAKEUP_WAKE_EVT, osal_sizeof(WMT_SET_WAKEUP_WAKE_EVT)) != 0) { + WMT_ERR_FUNC("WMT-CORE: write WMT_SET_WAKEUP_WAKE_CMD_RAW status fail\n"); + return -6; + } +#endif + + /* 8. Query baud rate (TEST-ONLY) */ + iRet = wmt_core_init_script(init_table_2, osal_array_size(init_table_2)); + if (iRet) { + WMT_ERR_FUNC("init_table_2 fail(%d)\n", iRet); + return -7; + } + } + + /* 9. download patch */ + iRet = mt6620_patch_dwn(); + + WMT_INFO_FUNC("Not to check the patch validity\n"); +#if 0 + if (iRet) { + WMT_ERR_FUNC("patch dwn fail (%d)\n", iRet); + return -8; + } + WMT_INFO_FUNC("patch dwn ok\n"); +#endif + /* 10. WMT Reset command */ + iRet = wmt_core_init_script(init_table_3, osal_array_size(init_table_3)); + if (iRet) { + WMT_ERR_FUNC("init_table_3 fail(%d)\n", iRet); + return -9; + } + iRet = wmt_stp_init_coex(); + if (iRet) { + WMT_ERR_FUNC("init_coex fail(%d)\n", iRet); + return -10; + } + WMT_INFO_FUNC("init_coex ok\n"); + +#if 0 + /*10-2 enable 32K By Pass Mode */ + /* if hwVer = E3/E4, please enable 32K by pass mode. */ + /* does not support mt6620E1/E2, always enable 32k bypass mode */ + /* if ((hwVer == 0x8a10 || hwVer == 0x8a11)) */ + { + WMT_INFO_FUNC("WMT-CORE: init_table_6 OSC32K"); + iRet = wmt_core_init_script(init_table_6, osal_array_size(init_table_6)); + if (iRet == 0) { + WMT_DBG_FUNC("WMT-CORE: init_table_6 OSC32K, successful\n"); + } else { + WMT_WARN_FUNC("init table 6 OSC32K fail, continue init...\n"); + /*return -11; */ + } + } +#endif + + if (pWmtHifConf->hifType == WMT_HIF_UART) { + /* 11. Set chip STP options */ + iRet = wmt_core_init_script(init_table_4, osal_array_size(init_table_4)); + if (iRet) { + WMT_ERR_FUNC("init_table_4 fail(%d)\n", iRet); + return -12; + } + + /* 12. Enable host STP-UART mode */ + ctrlPa1 = WMT_STP_CONF_MODE; + ctrlPa2 = MTKSTP_UART_FULL_MODE; + iRet = wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); + ctrlPa1 = WMT_STP_CONF_EN; + ctrlPa2 = 1; + iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); + if (iRet) { + WMT_ERR_FUNC("enable host STP-UART-FULL mode fail(%d)\n", iRet); + return -13; + } + WMT_INFO_FUNC("enable host STP-UART-FULL mode\n"); + /*13. wait for 10ms, enough for chip do mechanism switch.(at least 2ms is needed) */ + osal_sleep_ms(10); + /* 14. Query chip STP options (TEST-ONLY) */ + /* 15. Query baud rate (stp, TEST-ONLY) */ + iRet = wmt_core_init_script(init_table_5, osal_array_size(init_table_5)); + if (iRet) { + WMT_ERR_FUNC("init_table_5 fail(%d)\n", iRet); + return -14; + } + } + + /* 15. Set FM strap */ + WMT_STRAP_CONF_CMD_FM_COMM[5] = (UINT8) pWmtHifConf->au4StrapConf[0]; + WMT_STRAP_CONF_EVT[5] = (UINT8) pWmtHifConf->au4StrapConf[0]; + iRet = wmt_core_init_script(init_table_5_1, osal_array_size(init_table_5_1)); + if (iRet) { + WMT_ERR_FUNC("init_table_5_1 fm mode(%d) fail(%d)\n", + pWmtHifConf->au4StrapConf[0], iRet); + return -15; + } + WMT_INFO_FUNC("set fm mode (%d) ok\n", pWmtHifConf->au4StrapConf[0]); + +#if CFG_SET_OPT_REG /*set registers */ + iRet = wmt_core_init_script(set_registers, osal_array_size(set_registers)); + if (iRet) { + WMT_ERR_FUNC("set_registers fail(%d)", iRet); + return -16; + } +#endif + +#if 0 + /* 16. trace32 dump when fw assert */ + { + INT32 val = 0x00000001; + + WMT_INFO_FUNC("WMT-CORE: enable assert dump"); + wmt_reg_rw_raw(1, 0x0100092c, &val, 0xFFFFFFFF); + } +#endif + +#if CFG_WMT_PS_SUPPORT + osal_assert(gp_mt6620_info != NULL); + if (gp_mt6620_info != NULL) { + if (gp_mt6620_info->bPsmSupport != MTK_WCN_BOOL_FALSE) + wmt_lib_ps_enable(); + else + wmt_lib_ps_disable(); + } +#endif + + return 0; +} +#endif + +static INT32 mt6620_sw_init(P_WMT_HIF_CONF pWmtHifConf) +{ + INT32 iRet = -1; + UINT32 u4Res = 0; + UINT8 evtBuf[256]; + ULONG ctrlPa1; + ULONG ctrlPa2; + UINT32 hw_ver; + UINT32 patch_num = 0; + UINT32 patch_index = 0; + WMT_CTRL_DATA ctrlData; + + WMT_DBG_FUNC(" start\n"); + + osal_assert(gp_mt6620_info != NULL); + if ((gp_mt6620_info == NULL) + || (pWmtHifConf == NULL) + ) { + WMT_ERR_FUNC("null pointers: gp_mt6620_info(0x%p), pWmtHifConf(0x%p)\n", + gp_mt6620_info, pWmtHifConf); + return -1; + } + + hw_ver = gp_mt6620_info->u4HwVer; + + /* 4 <3.1> start init for sdio */ + if (pWmtHifConf->hifType == WMT_HIF_SDIO) { + /* 1. enable all INT32 */ + /* 2. disable mcu gate (only MT6620E1/E2) */ + iRet = wmt_core_init_script(init_table_1_1, osal_array_size(init_table_1_1)); + if (iRet) { + WMT_ERR_FUNC("init_table_1_1 fail:%d\n", iRet); + osal_assert(0); + return -1; + } + } + /* 4 <3.2> start init for uart */ + if (pWmtHifConf->hifType == WMT_HIF_UART) { + + /* init variable fields for script execution */ + osal_memcpy(&WMT_SET_BAUD_CMD_X[5], &pWmtHifConf->au4HifConf[0], + osal_sizeof(UINT32)); + osal_memcpy(&WMT_QUERY_BAUD_EVT_X[6], &pWmtHifConf->au4HifConf[0], + osal_sizeof(UINT32)); + if (pWmtHifConf->uartFcCtrl == WMT_UART_MTK_SW_FC) { + WMT_INFO_FUNC("enable MTK SW Flow Control\n"); + WMT_SET_BAUD_CMD_X[8] = (UINT8) 0x80; /* MTK SW flow control */ + WMT_QUERY_BAUD_EVT_X[9] = (UINT8) 0x80; /* MTK SW flow control */ + } else if (pWmtHifConf->uartFcCtrl == WMT_UART_LUX_SW_FC) { + WMT_INFO_FUNC("enable Linux SW Flow Control\n"); + WMT_SET_BAUD_CMD_X[8] = (UINT8) 0x80; /* Linux SW flow control */ + WMT_QUERY_BAUD_EVT_X[9] = (UINT8) 0x80; /* Linux SW flow control */ + } else if (pWmtHifConf->uartFcCtrl == WMT_UART_HW_FC) { + WMT_INFO_FUNC("enable HW Flow Control\n"); + WMT_SET_BAUD_CMD_X[8] = (UINT8) 0xC0; /* HW flow control */ + WMT_QUERY_BAUD_EVT_X[9] = (UINT8) 0xC0; /* HW flow control */ + } else { + /* WMT_UART_NO_FC and all other cases!!! */ + WMT_INFO_FUNC("no Flow Control (uartFcCtrl:%d)\n", pWmtHifConf->uartFcCtrl); + WMT_SET_BAUD_CMD_X[8] = (UINT8) 0x00; /* no flow control */ + WMT_QUERY_BAUD_EVT_X[9] = (UINT8) 0x00; /* no flow control */ + } + + /* 3. Query chip baud rate (TEST-ONLY) */ + /* 4. Query chip STP options (TEST-ONLY) */ + /* 5. Change chip baud rate: t_baud */ + /* WMT_DBG_FUNC("WMT-CORE: init_table_1_2 set chip baud:%d", pWmtHifConf->au4HifConf[0]); */ + iRet = wmt_core_init_script(init_table_1_2, osal_array_size(init_table_1_2)); + if (iRet) { + WMT_ERR_FUNC("init_table_1_2 fail(%d)\n", iRet); + osal_assert(0); + return -2; + } + + /* 6. Set host baudrate and flow control */ + ctrlPa1 = pWmtHifConf->au4HifConf[0]; + ctrlPa2 = 0; + iRet = wmt_core_ctrl(WMT_CTRL_HOST_BAUDRATE_SET, &ctrlPa1, &ctrlPa2); + if (iRet) { + WMT_ERR_FUNC("change baudrate(%d) fail(%d)\n", pWmtHifConf->au4HifConf[0], + iRet); + return -3; + } + WMT_INFO_FUNC("WMT-CORE: change baudrate(%d) ok\n", pWmtHifConf->au4HifConf[0]); + + /* 7. Wake up chip and check event */ +/* iRet = (*kal_stp_tx_raw)(&WMT_SET_WAKEUP_WAKE_CMD_RAW[0], 1, &u4Res); */ + iRet = + wmt_core_tx((PUINT8)&WMT_SET_WAKEUP_WAKE_CMD_RAW[0], 1, &u4Res, + MTK_WCN_BOOL_TRUE); + if (iRet || (u4Res != 1)) { + WMT_ERR_FUNC("write raw iRet(%d) written(%d)\n", iRet, u4Res); + return -4; + } + + osal_memset(evtBuf, 0, osal_sizeof(evtBuf)); + iRet = wmt_core_rx(evtBuf, osal_sizeof(WMT_SET_WAKEUP_WAKE_EVT), &u4Res); +#ifdef CFG_DUMP_EVT + WMT_DBG_FUNC("WAKEUP_WAKE_EVT read len %d [%02x,%02x,%02x,%02x,%02x,%02x]\n", + (INT32) u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], + evtBuf[5]); +#endif + if (iRet || (u4Res != osal_sizeof(WMT_SET_WAKEUP_WAKE_EVT))) { + WMT_ERR_FUNC("read WAKEUP_WAKE_EVT fail(%d)\n", iRet); + return -5; + } + /* WMT_DBG_FUNC("WMT-CORE: read WMT_SET_WAKEUP_WAKE_EVT ok"); */ + +#if CFG_CHECK_WMT_RESULT + if (osal_memcmp + (evtBuf, WMT_SET_WAKEUP_WAKE_EVT, osal_sizeof(WMT_SET_WAKEUP_WAKE_EVT)) != 0) { + WMT_ERR_FUNC("WMT-CORE: write WMT_SET_WAKEUP_WAKE_CMD_RAW status fail\n"); + return -6; + } +#endif + + /* 8. Query baud rate (TEST-ONLY) */ + iRet = wmt_core_init_script(init_table_2, osal_array_size(init_table_2)); + if (iRet) { + WMT_ERR_FUNC("init_table_2 fail(%d)\n", iRet); + return -7; + } + } + if (pWmtHifConf->hifType == WMT_HIF_UART) { + /* 9. Set chip STP options */ + iRet = wmt_core_init_script(init_table_4, osal_array_size(init_table_4)); + if (iRet) { + WMT_ERR_FUNC("init_table_4 fail(%d)\n", iRet); + return -8; + } + + /* 10. Enable host STP-UART mode */ + ctrlPa1 = WMT_STP_CONF_MODE; + ctrlPa2 = MTKSTP_UART_FULL_MODE; + iRet = wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); + ctrlPa1 = WMT_STP_CONF_EN; + ctrlPa2 = 1; + iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); + if (iRet) { + WMT_ERR_FUNC("enable host STP-UART-FULL mode fail(%d)\n", iRet); + return -9; + } + WMT_INFO_FUNC("enable host STP-UART-FULL mode\n"); + /*10. wait for 10ms, enough for chip do mechanism switch.(at least 2ms is needed) */ + osal_sleep_ms(10); + /* 11. Query chip STP options (TEST-ONLY) */ + /* 12. Query baud rate (stp, TEST-ONLY) */ + iRet = wmt_core_init_script(init_table_5, osal_array_size(init_table_5)); + if (iRet) { + WMT_ERR_FUNC("init_table_5 fail(%d)\n", iRet); + return -10; + } + } + /* 13. download patch */ +#if CFG_WMT_MULTI_PATCH + iRet = mt6620_patch_info_prepare(); + if (iRet) { + WMT_ERR_FUNC("patch info perpare fail(%d)\n", iRet); + return -11; + } + + ctrlPa1 = 0; + ctrlPa2 = 0; + wmt_core_ctrl(WMT_CTRL_GET_PATCH_NUM, &ctrlPa1, &ctrlPa2); + patch_num = ctrlPa1; + WMT_INFO_FUNC("patch total num = [%d]\n", patch_num); + + for (patch_index = 0; patch_index < patch_num; patch_index++) { + iRet = mt6620_patch_dwn(patch_index); + if (iRet) { + WMT_ERR_FUNC("patch dwn fail (%d),patch_index(%d)\n", iRet, patch_index); + return -12; + } + iRet = wmt_core_init_script(init_table_3, osal_array_size(init_table_3)); + if (iRet) { + WMT_ERR_FUNC("init_table_3 fail(%d)\n", iRet); + return -13; + } + } +#else + iRet = mt6620_patch_dwn(); + + WMT_INFO_FUNC("Not to check the patch validity\n"); +#if 0 + if (iRet) { + WMT_ERR_FUNC("patch dwn fail (%d)\n", iRet); + return -11; + } + WMT_INFO_FUNC("patch dwn ok\n"); +#endif + /* 14. WMT Reset command */ + iRet = wmt_core_init_script(init_table_3, osal_array_size(init_table_3)); + if (iRet) { + WMT_ERR_FUNC("init_table_3 fail(%d)\n", iRet); + return -13; + } +#endif + iRet = wmt_stp_init_coex(); + if (iRet) { + WMT_ERR_FUNC("init_coex fail(%d)\n", iRet); + return -14; + } + WMT_INFO_FUNC("init_coex ok\n"); + +#if 0 + /*10-2 enable 32K By Pass Mode */ + /* if hwVer = E3/E4, please enable 32K by pass mode. */ + /* does not support mt6620E1/E2, always enable 32k bypass mode */ + /* if ((hwVer == 0x8a10 || hwVer == 0x8a11)) */ + { + WMT_INFO_FUNC("WMT-CORE: init_table_6 OSC32K"); + iRet = wmt_core_init_script(init_table_6, osal_array_size(init_table_6)); + if (iRet == 0) { + WMT_DBG_FUNC("WMT-CORE: init_table_6 OSC32K, successful\n"); + } else { + WMT_WARN_FUNC("init table 6 OSC32K fail, continue init...\n"); + /*return -14; */ + } + } +#endif + + + + /* 15. Set FM strap */ + WMT_STRAP_CONF_CMD_FM_COMM[5] = (UINT8) pWmtHifConf->au4StrapConf[0]; + WMT_STRAP_CONF_EVT[5] = (UINT8) pWmtHifConf->au4StrapConf[0]; + iRet = wmt_core_init_script(init_table_5_1, osal_array_size(init_table_5_1)); + if (iRet) { + WMT_ERR_FUNC("init_table_5_1 fm mode(%d) fail(%d)\n", + pWmtHifConf->au4StrapConf[0], iRet); + return -15; + } + WMT_INFO_FUNC("set fm mode (%d) ok\n", pWmtHifConf->au4StrapConf[0]); + +#if CFG_SET_OPT_REG /*set registers */ + iRet = wmt_core_init_script(set_registers, osal_array_size(set_registers)); + if (iRet) { + WMT_ERR_FUNC("set_registers fail(%d)", iRet); + return -16; + } +#endif + +#if 0 + /* 16. trace32 dump when fw assert */ + { + INT32 val = 0x00000001; + + WMT_INFO_FUNC("WMT-CORE: enable assert dump"); + wmt_reg_rw_raw(1, 0x0100092c, &val, 0xFFFFFFFF); + } +#endif + +#if CFG_WMT_COREDUMP_ENABLE + /*Open Core Dump Function @QC begin */ + mtk_wcn_stp_coredump_flag_ctrl(1); +#endif + if (mtk_wcn_stp_coredump_flag_get() != 0) { + iRet = wmt_core_init_script(init_table_6, osal_array_size(init_table_6)); + if (iRet) { + WMT_ERR_FUNC("init_table_6 core dump setting fail(%d)\n", iRet); + return -17; + } + WMT_INFO_FUNC("enable mt662x firmware coredump\n"); + } else + WMT_INFO_FUNC("disable mt662x firmware coredump\n"); + +#if 1 + ctrlData.ctrlId = WMT_CTRL_SET_STP_DBG_INFO; + ctrlData.au4CtrlData[0] = wmt_ic_ops_mt6620.icId; + ctrlData.au4CtrlData[1] = (size_t) gp_mt6620_info->cChipVersion; + ctrlData.au4CtrlData[2] = (size_t) &gp_mt6620_patch_info; + iRet = wmt_ctrl(&ctrlData); + if (iRet) { + WMT_ERR_FUNC("set dump info fail(%d)\n", iRet); + return -16; + } +#endif + +#if CFG_WMT_PS_SUPPORT + osal_assert(gp_mt6620_info != NULL); + if (gp_mt6620_info != NULL) { + if (gp_mt6620_info->bPsmSupport != MTK_WCN_BOOL_FALSE) + wmt_lib_ps_enable(); + else + wmt_lib_ps_disable(); + } +#endif + + return 0; +} + + +static INT32 mt6620_sw_deinit(P_WMT_HIF_CONF pWmtHifConf) +{ + WMT_DBG_FUNC(" start\n"); + +#if CFG_WMT_PS_SUPPORT + osal_assert(gp_mt6620_info != NULL); + if ((gp_mt6620_info != NULL) + && (gp_mt6620_info->bPsmSupport != MTK_WCN_BOOL_FALSE)) { + wmt_lib_ps_disable(); + } +#endif + + gp_mt6620_info = NULL; + + return 0; +} + +static INT32 mt6620_aif_ctrl(WMT_IC_PIN_STATE state, UINT32 flag) +{ + INT32 ret = -1; + UINT32 val; + + if ((flag & WMT_LIB_AIF_FLAG_MASK) == WMT_LIB_AIF_FLAG_SHARE) { + WMT_INFO_FUNC("PCM & I2S PIN SHARE\n"); + switch (state) { + case WMT_IC_AIF_0: + /* BT_PCM_OFF & FM line in/out */ + val = 0x00000770; + ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); + val = 0x00000000; + ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); + break; + + case WMT_IC_AIF_1: + /* BT_PCM_ON & FM line in/out */ + val = 0x00000700; + ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); + val = 0x00000000; + ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); + break; + + case WMT_IC_AIF_2: + /* BT_PCM_OFF & FM I2S */ + val = 0x00000710; + ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); + val = 0x00000800; /* 800:3-wire, 000: 4-wire */ + ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); + break; + default: + WMT_ERR_FUNC("unsupported state (%d)\n", state); + ret = -1; + break; + } + } else { + /*PCM & I2S separate */ + WMT_INFO_FUNC("PCM & I2S PIN SEPARATE\n"); + switch (state) { + case WMT_IC_AIF_0: + /* BT_PCM_OFF & FM line in/out */ + val = 0x00000770; + ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); + val = 0x00000000; + ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); + break; + + case WMT_IC_AIF_1: + /* BT_PCM_ON & FM line in/out */ + val = 0x00000700; + ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); + val = 0x00000000; + ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); + break; + + case WMT_IC_AIF_2: + /* BT_PCM_OFF & FM I2S */ + val = 0x00000070; + ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); + val = 0x00000800; /* 800:3-wire, 000: 4-wire */ + ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); + + break; + case WMT_IC_AIF_3: + val = 0x00000000; + ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); + val = 0x00000800; /* 800:3-wire, 000: 4-wire */ + ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); + break; + default: + WMT_ERR_FUNC("unsupported state (%d)\n", state); + ret = -1; + break; + } + } + + if (!ret) + WMT_INFO_FUNC("new state(%d) ok\n", state); + else + WMT_WARN_FUNC("new state(%d) fail(%d)\n", state, ret); + + return ret; +} + +static INT32 mt6620_pin_ctrl(WMT_IC_PIN_ID id, WMT_IC_PIN_STATE state, UINT32 flag) +{ + INT32 ret; + + WMT_DBG_FUNC("ic pin id:%d, state:%d, flag:0x%x\n", id, state, flag); + + ret = -1; + switch (id) { + case WMT_IC_PIN_AUDIO: + ret = mt6620_aif_ctrl(state, flag); + break; + + case WMT_IC_PIN_EEDI: + WMT_WARN_FUNC("TBD!!"); + ret = -1; + break; + + case WMT_IC_PIN_EEDO: + WMT_WARN_FUNC("TBD!!"); + ret = -1; + break; + case WMT_IC_PIN_GSYNC: + ret = -1; + WMT_WARN_FUNC("TBD!!"); + break; + default: + break; + } + WMT_INFO_FUNC("ret = (%d)\n", ret); + + return ret; +} + + +static MTK_WCN_BOOL mt6620_quick_sleep_flag_get(VOID) +{ + return MTK_WCN_BOOL_FALSE; +} + +static MTK_WCN_BOOL mt6620_aee_dump_flag_get(VOID) +{ + return MTK_WCN_BOOL_TRUE; +} + + +static INT32 mt6620_ver_check(VOID) +{ + UINT32 hw_ver = 0; + UINT32 fw_ver = 0; + INT32 iret; + const WMT_IC_INFO_S *p_info = NULL; + ULONG ctrlPa1; + ULONG ctrlPa2; + + /* 1. identify chip versions: HVR(HW_VER) and FVR(FW_VER) */ + WMT_LOUD_FUNC("MT6620: before read hw_ver (hw version)\n"); + iret = wmt_core_reg_rw_raw(0, GEN_HVR, &hw_ver, GEN_VER_MASK); + if (iret) { + WMT_ERR_FUNC("MT6620: read hw_ver fail:%d\n", iret); + return -2; + } + WMT_INFO_FUNC("MT6620: read hw_ver (hw version) (0x%x)\n", hw_ver); + + WMT_LOUD_FUNC("MT6620: before fw_ver (rom version)\n"); + wmt_core_reg_rw_raw(0, GEN_FVR, &fw_ver, GEN_VER_MASK); + if (iret) { + WMT_ERR_FUNC("MT6620: read fw_ver fail:%d\n", iret); + return -2; + } + WMT_INFO_FUNC("MT6620: read fw_ver (rom version) (0x%x)\n", fw_ver); + + p_info = mt6620_find_wmt_ic_info(hw_ver); + if (p_info == NULL) { + WMT_ERR_FUNC("MT6620: hw_ver(0x%x) find wmt ic info fail\n", hw_ver); + return -3; + } + + WMT_INFO_FUNC("MT6620: wmt ic info: %s.%s (0x%x, patch_ext:%s)\n", + p_info->cChipName, p_info->cChipVersion, + p_info->u4HwVer, p_info->cPatchNameExt); + + /* hw id & version */ + ctrlPa1 = (0x00006620UL << 16) | (hw_ver & 0x0000FFFF); + /* translated fw rom version */ + ctrlPa2 = (fw_ver & 0x0000FFFF); + + iret = wmt_core_ctrl(WMT_CTRL_HWIDVER_SET, &ctrlPa1, &ctrlPa2); + if (iret) + WMT_WARN_FUNC("MT6620: WMT_CTRL_HWIDVER_SET fail(%d)\n", iret); + + gp_mt6620_info = p_info; + return 0; +} + +static const WMT_IC_INFO_S *mt6620_find_wmt_ic_info(const UINT32 hw_ver) +{ + /* match chipversion with u4HwVer item in mt6620_info_table */ + const UINT32 size = osal_array_size(mt6620_info_table); + INT32 index; + + /* George: reverse the search order to favor newer version products */ + /* TODO:[FixMe][GeorgeKuo] Remove full match once API wmt_lib_get_hwver() + * is changed correctly in the future!! + */ + /* Leave full match here is a workaround for GPS to distinguish E3/E4 ICs. */ + index = size - 1; + /* full match */ + while ((index >= 0) + && (hw_ver != mt6620_info_table[index].u4HwVer) /* full match */ + ) { + --index; + } + if (index >= 0) { + WMT_INFO_FUNC("found ic info(0x%x) by full match! index:%d\n", hw_ver, index); + return &mt6620_info_table[index]; + } + WMT_WARN_FUNC("find no ic info for (0x%x) by full match!try major num match!\n", hw_ver); + + /* George: The ONLY CORRECT method to find supported hw table. Match MAJOR + * NUM only can help us support future minor hw ECO, or fab switch, etc. + * FULL matching eliminate such flexibility and software package have to be + * updated EACH TIME even when minor hw ECO or fab switch!!! + */ + /* George: reverse the search order to favor newer version products */ + index = size - 1; + /* major num match */ + while ((index >= 0) + && (MAJORNUM(hw_ver) != MAJORNUM(mt6620_info_table[index].u4HwVer)) + ) { + --index; + } + if (index >= 0) { + WMT_INFO_FUNC("MT6620: found ic info for hw_ver(0x%x) by major num! index:%d\n", + hw_ver, index); + return &mt6620_info_table[index]; + } + + WMT_ERR_FUNC + ("MT6620: find no ic info for hw_ver(0x%x) by full match nor major num match!\n", + hw_ver); + return NULL; +} + + +static INT32 wmt_stp_init_coex(VOID) +{ + INT32 iRet; + ULONG addr = 0; + WMT_GEN_CONF *pWmtGenConf = NULL; + +#define COEX_WMT 0 +#define COEX_BT 1 +#define COEX_WIFI 2 +#define COEX_PTA 3 +#define COEX_MISC 4 + + /*Get wmt config */ + iRet = wmt_core_ctrl(WMT_CTRL_GET_WMT_CONF, &addr, 0); + if (iRet) { + WMT_ERR_FUNC("ctrl GET_WMT_CONF fail(%d)\n", iRet); + return -2; + } + WMT_INFO_FUNC("ctrl GET_WMT_CONF ok(0x%08lx)\n", addr); + + pWmtGenConf = (P_WMT_GEN_CONF) addr; + + /*Check if WMT.cfg exists */ + if (pWmtGenConf->cfgExist == 0) { + WMT_INFO_FUNC("cfgExist == 0, skip config chip\n"); + /*if WMT.cfg not existed, still return success and adopt the default value */ + return 0; + } + + /*Dump the coex-related info */ + WMT_DBG_FUNC("coex_wmt:0x%x 0x%x 0x%x\n", + pWmtGenConf->coex_wmt_ant_mode, + pWmtGenConf->coex_wmt_wifi_time_ctl, pWmtGenConf->coex_wmt_ext_pta_dev_on); + WMT_DBG_FUNC("coex_bt:0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", + pWmtGenConf->coex_bt_rssi_upper_limit, + pWmtGenConf->coex_bt_rssi_mid_limit, + pWmtGenConf->coex_bt_rssi_lower_limit, + pWmtGenConf->coex_bt_pwr_high, + pWmtGenConf->coex_bt_pwr_mid, pWmtGenConf->coex_bt_pwr_low); + WMT_DBG_FUNC("coex_wifi:0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", + pWmtGenConf->coex_wifi_rssi_upper_limit, + pWmtGenConf->coex_wifi_rssi_mid_limit, + pWmtGenConf->coex_wifi_rssi_lower_limit, + pWmtGenConf->coex_wifi_pwr_high, + pWmtGenConf->coex_wifi_pwr_mid, pWmtGenConf->coex_wifi_pwr_low); + WMT_DBG_FUNC("coex_ext_pta:0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", + pWmtGenConf->coex_ext_pta_hi_tx_tag, + pWmtGenConf->coex_ext_pta_hi_rx_tag, + pWmtGenConf->coex_ext_pta_lo_tx_tag, + pWmtGenConf->coex_ext_pta_lo_rx_tag, + pWmtGenConf->coex_ext_pta_sample_t1, + pWmtGenConf->coex_ext_pta_sample_t2, + pWmtGenConf->coex_ext_pta_wifi_bt_con_trx); + WMT_DBG_FUNC("coex_misc:0x%x 0x%x\n", + pWmtGenConf->coex_misc_ext_pta_on, pWmtGenConf->coex_misc_ext_feature_set); + + /*command adjustion due to WMT.cfg */ + coex_table[COEX_WMT].cmd[5] = pWmtGenConf->coex_wmt_ant_mode; + coex_table[COEX_WMT].cmd[6] = pWmtGenConf->coex_wmt_wifi_time_ctl; + coex_table[COEX_WMT].cmd[7] = pWmtGenConf->coex_wmt_ext_pta_dev_on; + if (gWmtDbgLvl >= WMT_LOG_DBG) { + wmt_core_dump_data(&coex_table[COEX_WMT].cmd[0], + coex_table[COEX_WMT].str, coex_table[COEX_WMT].cmdSz); + } + + coex_table[COEX_BT].cmd[9] = pWmtGenConf->coex_bt_rssi_upper_limit; + coex_table[COEX_BT].cmd[10] = pWmtGenConf->coex_bt_rssi_mid_limit; + coex_table[COEX_BT].cmd[11] = pWmtGenConf->coex_bt_rssi_lower_limit; + coex_table[COEX_BT].cmd[12] = pWmtGenConf->coex_bt_pwr_high; + coex_table[COEX_BT].cmd[13] = pWmtGenConf->coex_bt_pwr_mid; + coex_table[COEX_BT].cmd[14] = pWmtGenConf->coex_bt_pwr_low; + if (gWmtDbgLvl >= WMT_LOG_DBG) { + wmt_core_dump_data(&coex_table[COEX_BT].cmd[0], + coex_table[COEX_BT].str, coex_table[COEX_BT].cmdSz); + } + coex_table[COEX_WIFI].cmd[10] = pWmtGenConf->coex_wifi_rssi_upper_limit; + coex_table[COEX_WIFI].cmd[11] = pWmtGenConf->coex_wifi_rssi_mid_limit; + coex_table[COEX_WIFI].cmd[12] = pWmtGenConf->coex_wifi_rssi_lower_limit; + coex_table[COEX_WIFI].cmd[13] = pWmtGenConf->coex_wifi_pwr_high; + coex_table[COEX_WIFI].cmd[14] = pWmtGenConf->coex_wifi_pwr_mid; + coex_table[COEX_WIFI].cmd[15] = pWmtGenConf->coex_wifi_pwr_low; + if (gWmtDbgLvl >= WMT_LOG_DBG) { + wmt_core_dump_data(&coex_table[COEX_WIFI].cmd[0], + coex_table[COEX_WIFI].str, coex_table[COEX_WIFI].cmdSz); + } + coex_table[COEX_PTA].cmd[5] = pWmtGenConf->coex_ext_pta_hi_tx_tag; + coex_table[COEX_PTA].cmd[6] = pWmtGenConf->coex_ext_pta_hi_rx_tag; + coex_table[COEX_PTA].cmd[7] = pWmtGenConf->coex_ext_pta_lo_tx_tag; + coex_table[COEX_PTA].cmd[8] = pWmtGenConf->coex_ext_pta_lo_rx_tag; + coex_table[COEX_PTA].cmd[9] = ((pWmtGenConf->coex_ext_pta_sample_t1 & 0xff00) >> 8); + coex_table[COEX_PTA].cmd[10] = ((pWmtGenConf->coex_ext_pta_sample_t1 & 0x00ff) >> 0); + coex_table[COEX_PTA].cmd[11] = ((pWmtGenConf->coex_ext_pta_sample_t2 & 0xff00) >> 8); + coex_table[COEX_PTA].cmd[12] = ((pWmtGenConf->coex_ext_pta_sample_t2 & 0x00ff) >> 0); + coex_table[COEX_PTA].cmd[13] = pWmtGenConf->coex_ext_pta_wifi_bt_con_trx; + if (gWmtDbgLvl >= WMT_LOG_DBG) { + wmt_core_dump_data(&coex_table[COEX_PTA].cmd[0], + coex_table[COEX_PTA].str, coex_table[COEX_PTA].cmdSz); + } + + osal_memcpy(&coex_table[COEX_MISC].cmd[5], &pWmtGenConf->coex_misc_ext_pta_on, + sizeof(pWmtGenConf->coex_misc_ext_pta_on)); + osal_memcpy(&coex_table[COEX_MISC].cmd[9], &pWmtGenConf->coex_misc_ext_feature_set, + sizeof(pWmtGenConf->coex_misc_ext_feature_set)); + if (gWmtDbgLvl >= WMT_LOG_DBG) { + wmt_core_dump_data(&coex_table[COEX_MISC].cmd[0], coex_table[COEX_MISC].str, + coex_table[COEX_MISC].cmdSz); + } + iRet = wmt_core_init_script(coex_table, ARRAY_SIZE(coex_table)); + + return iRet; +} + +#if CFG_WMT_MULTI_PATCH + +static INT32 mt6620_patch_info_prepare(VOID) +{ + INT32 iRet = -1; + WMT_CTRL_DATA ctrlData; + + ctrlData.ctrlId = WMT_CTRL_PATCH_SEARCH; + iRet = wmt_ctrl(&ctrlData); + + return iRet; +} + +static INT32 mt6620_patch_dwn(UINT32 index) +{ + INT32 iRet = -1; + P_WMT_PATCH patchHdr = NULL; + PUINT8 pbuf = NULL; + UINT32 patchSize = 0; + UINT32 fragSeq = 0; + UINT32 fragNum = 0; + UINT16 fragSize = 0; + UINT16 cmdLen; + UINT32 offset; + UINT32 u4Res; + UINT8 patchevtBuf[8]; + UINT8 addressevtBuf[12]; + UINT8 addressByte[4]; + PINT8 cDataTime = NULL; + /*PINT8 cPlat = NULL; */ + UINT16 u2HwVer = 0; + UINT16 u2SwVer = 0; + UINT32 u4PatchVer = 0; + UINT32 patchSizePerFrag = 0; + WMT_CTRL_DATA ctrlData; + + /*1.check hardware information */ + if (gp_mt6620_info == NULL) { + WMT_ERR_FUNC("null gp_mt6620_info!\n"); + return -1; + } + + osal_memset(gFullPatchName, 0, osal_sizeof(gFullPatchName)); + + ctrlData.ctrlId = WMT_CTRL_GET_PATCH_INFO; + ctrlData.au4CtrlData[0] = index + 1; + ctrlData.au4CtrlData[1] = (size_t) &gFullPatchName; + ctrlData.au4CtrlData[2] = (size_t) &addressByte; + iRet = wmt_ctrl(&ctrlData); + WMT_INFO_FUNC("the %d time valid patch found: (%s)\n", index + 1, gFullPatchName); + /* <2.2> read patch content */ + ctrlData.ctrlId = WMT_CTRL_GET_PATCH; + ctrlData.au4CtrlData[0] = (size_t) NULL; + ctrlData.au4CtrlData[1] = (size_t) &gFullPatchName; + + ctrlData.au4CtrlData[2] = (size_t) &pbuf; + ctrlData.au4CtrlData[3] = (size_t) &patchSize; + iRet = wmt_ctrl(&ctrlData); + if (iRet) { + WMT_ERR_FUNC("wmt_core: WMT_CTRL_GET_PATCH fail:%d\n", iRet); + iRet -= 1; + goto done; + } + + /* |<-BCNT_PATCH_BUF_HEADROOM(8) bytes dummy allocated->|<-patch file->| */ + pbuf += BCNT_PATCH_BUF_HEADROOM; + /* patch file with header: + * |<-patch header: 28 Bytes->|<-patch body: X Bytes ----->| + */ + patchHdr = (P_WMT_PATCH) pbuf; + /* check patch file information */ + + cDataTime = patchHdr->ucDateTime; + u2HwVer = patchHdr->u2HwVer; + u2SwVer = patchHdr->u2SwVer; + u4PatchVer = patchHdr->u4PatchVer; + /*cPlat = &patchHdr->ucPLat[0]; */ + cDataTime[15] = '\0'; + + /* remove patch header: + * |<-patch body: X Bytes (X=patchSize)--->| + */ + if (patchSize < sizeof(WMT_PATCH)) { + WMT_ERR_FUNC("error patch size\n"); + iRet = -1; + goto done; + } + patchSize -= sizeof(WMT_PATCH); + pbuf += sizeof(WMT_PATCH); + + if (index == 0) { + WMT_INFO_FUNC("===========================================\n"); + WMT_INFO_FUNC("[Combo Patch] Built Time = %s\n", cDataTime); + WMT_INFO_FUNC("[Combo Patch] Hw Ver = 0x%x\n", + ((u2HwVer & 0x00ff) << 8) | ((u2HwVer & 0xff00) >> 8)); + WMT_INFO_FUNC("[Combo Patch] Sw Ver = 0x%x\n", + ((u2SwVer & 0x00ff) << 8) | ((u2SwVer & 0xff00) >> 8)); + WMT_INFO_FUNC("[Combo Patch] Ph Ver = 0x%04x\n", + ((u4PatchVer & 0xff000000) >> 24) | ((u4PatchVer & 0x00ff0000) >> + 16)); + WMT_INFO_FUNC("[Combo Patch] Platform = %c%c%c%c\n", patchHdr->ucPLat[0], + patchHdr->ucPLat[1], patchHdr->ucPLat[2], patchHdr->ucPLat[3]); + WMT_INFO_FUNC("[Combo Patch] Content Size = 0x%x\n", patchSize); + WMT_INFO_FUNC("[Combo Patch] Content CRC = 0x%04x\n", osal_crc16(pbuf, patchSize)); + WMT_INFO_FUNC("===========================================\n"); + } + + patchSizePerFrag = (MAJORNUM(gp_mt6620_info->u4HwVer) != 0) ? + DEFAULT_PATCH_FRAG_SIZE : MT6620E2_PATCH_FRAG_SIZE; + + /* reserve 1st patch cmd space before patch body + * |<-WMT_CMD: 5Bytes->|<-patch body: X Bytes (X=patchSize)----->| + */ + osal_memcpy(&gp_mt6620_patch_info, patchHdr, osal_sizeof(WMT_PATCH)); + pbuf -= sizeof(WMT_PATCH_CMD); + + fragNum = patchSize / patchSizePerFrag; + fragNum += ((fragNum * patchSizePerFrag) == patchSize) ? 0 : 1; + + WMT_DBG_FUNC("patch size(%d) fragNum(%d)\n", patchSize, fragNum); + + /*send wmt part patch address command */ + iRet = + wmt_core_tx((PUINT8) &WMT_PATCH_ADDRESS_CMD[0], sizeof(WMT_PATCH_ADDRESS_CMD), &u4Res, + MTK_WCN_BOOL_FALSE); + if (iRet || (u4Res != sizeof(WMT_PATCH_ADDRESS_CMD))) { + WMT_ERR_FUNC("wmt_core:wmt patch address CMD fail(%d),size(%d)\n", iRet, u4Res); + iRet -= 1; + goto done; + } + osal_memset(addressevtBuf, 0, sizeof(addressevtBuf)); + iRet = wmt_core_rx(addressevtBuf, sizeof(WMT_PATCH_ADDRESS_EVT), &u4Res); + if (iRet || (u4Res != sizeof(WMT_PATCH_ADDRESS_EVT))) { + WMT_ERR_FUNC("wmt_core:wmt patch address EVT fail(%d),size(%d)\n", iRet, u4Res); + iRet -= 1; + goto done; + } +#if CFG_CHECK_WMT_RESULT + if (osal_memcmp(addressevtBuf, WMT_PATCH_ADDRESS_EVT, osal_sizeof(WMT_PATCH_ADDRESS_EVT)) != + 0) { + WMT_ERR_FUNC("wmt_core: write WMT_PATCH_ADDRESS_CMD status fail\n"); + iRet -= 1; + goto done; + } +#endif + + /*send part patch address command */ + osal_memcpy(&WMT_PATCH_P_ADDRESS_CMD[12], addressByte, osal_sizeof(addressByte)); + WMT_INFO_FUNC("4 bytes address command:0x%02x,0x%02x,0x%02x,0x%02x", + WMT_PATCH_P_ADDRESS_CMD[12], WMT_PATCH_P_ADDRESS_CMD[13], + WMT_PATCH_P_ADDRESS_CMD[14], WMT_PATCH_P_ADDRESS_CMD[15]); + iRet = + wmt_core_tx((PUINT8) &WMT_PATCH_P_ADDRESS_CMD[0], sizeof(WMT_PATCH_P_ADDRESS_CMD), + &u4Res, MTK_WCN_BOOL_FALSE); + if (iRet || (u4Res != sizeof(WMT_PATCH_P_ADDRESS_CMD))) { + WMT_ERR_FUNC("wmt_core:wmt part patch address CMD fail(%d),size(%d),index(%d)\n", + iRet, u4Res, index); + iRet -= 1; + goto done; + } + osal_memset(addressevtBuf, 0, sizeof(addressevtBuf)); + iRet = wmt_core_rx(addressevtBuf, sizeof(WMT_PATCH_P_ADDRESS_EVT), &u4Res); + if (iRet || (u4Res != sizeof(WMT_PATCH_P_ADDRESS_EVT))) { + WMT_ERR_FUNC("wmt_core:wmt patch address EVT fail(%d),size(%d),index(%d)\n", iRet, + u4Res, index); + iRet -= 1; + goto done; + } +#if CFG_CHECK_WMT_RESULT + if (osal_memcmp(addressevtBuf, WMT_PATCH_P_ADDRESS_EVT, osal_sizeof(WMT_PATCH_ADDRESS_EVT)) + != 0) { + WMT_ERR_FUNC("wmt_core: write WMT_PATCH_ADDRESS_CMD status fail,index(%d)\n", + index); + iRet -= 1; + goto done; + } +#endif + /* send all fragments */ + offset = sizeof(WMT_PATCH_CMD); + fragSeq = 0; + while (fragSeq < fragNum) { + WMT_DBG_FUNC("patch size(%d) fragNum(%d)\n", patchSize, fragNum); + if (fragSeq == (fragNum - 1)) { + /* last fragment */ + fragSize = patchSize - fragSeq * patchSizePerFrag; + WMT_PATCH_CMD[4] = WMT_PATCH_FRAG_LAST; + } else { + fragSize = patchSizePerFrag; + WMT_PATCH_CMD[4] = (fragSeq == 0) ? WMT_PATCH_FRAG_1ST : WMT_PATCH_FRAG_MID; + } + /* update length field in CMD:flag+frag */ + cmdLen = 1 + fragSize; + osal_memcpy(&WMT_PATCH_CMD[2], &cmdLen, 2); + /* copy patch CMD to buf (overwrite last 5-byte in prev frag) */ + osal_memcpy(pbuf + offset - sizeof(WMT_PATCH_CMD), WMT_PATCH_CMD, + sizeof(WMT_PATCH_CMD)); + /* iRet = (*kal_stp_tx)(pbuf + offset - sizeof(WMT_PATCH_CMD), + * fragSize + sizeof(WMT_PATCH_CMD), &u4Res); + */ + iRet = + wmt_core_tx(pbuf + offset - sizeof(WMT_PATCH_CMD), + fragSize + sizeof(WMT_PATCH_CMD), &u4Res, MTK_WCN_BOOL_FALSE); + if (iRet || (u4Res != fragSize + sizeof(WMT_PATCH_CMD))) { + WMT_ERR_FUNC("wmt_core: write fragSeq(%d) size(%zu, %d) fail(%d)\n", fragSeq, + fragSize + sizeof(WMT_PATCH_CMD), u4Res, iRet); + iRet = -4; + break; + } + WMT_DBG_FUNC("wmt_core: write fragSeq(%d) size(%zu, %d) ok\n", + fragSeq, fragSize + sizeof(WMT_PATCH_CMD), u4Res); + + osal_memset(patchevtBuf, 0, sizeof(patchevtBuf)); + /* iRet = (*kal_stp_rx)(evtBuf, sizeof(WMT_PATCH_EVT), &u4Res); */ + iRet = wmt_core_rx(patchevtBuf, sizeof(WMT_PATCH_EVT), &u4Res); + if (iRet || (u4Res != sizeof(WMT_PATCH_EVT))) { + WMT_ERR_FUNC("wmt_core: read WMT_PATCH_EVT length(%zu, %d) fail(%d)\n", + sizeof(WMT_PATCH_EVT), u4Res, iRet); + iRet = -5; + break; + } +#if CFG_CHECK_WMT_RESULT + if (osal_memcmp(patchevtBuf, WMT_PATCH_EVT, sizeof(WMT_PATCH_EVT)) != 0) { + WMT_ERR_FUNC("rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%zu):[%02X,%02X,%02X,%02X,%02X]\n", + u4Res, patchevtBuf[0], patchevtBuf[1], patchevtBuf[2], patchevtBuf[3], + patchevtBuf[4], sizeof(WMT_PATCH_EVT), WMT_PATCH_EVT[0], + WMT_PATCH_EVT[1], WMT_PATCH_EVT[2], WMT_PATCH_EVT[3], + WMT_PATCH_EVT[4]); + iRet = -6; + break; + } +#endif + WMT_DBG_FUNC("wmt_core: read WMT_PATCH_EVT length(%zu, %d) ok\n", + sizeof(WMT_PATCH_EVT), u4Res); + +#if 0 + WMT_DBG_FUNC("wmt_core: send patch frag(%d) [%02X,%02X,%02X,%02X,%02X] (%d) ok", + fragSeq, WMT_PATCH_CMD[0], WMT_PATCH_CMD[1], WMT_PATCH_CMD[2], + WMT_PATCH_CMD[3], WMT_PATCH_CMD[4], fragSize); +#endif + + offset += patchSizePerFrag; + ++fragSeq; + } + + WMT_INFO_FUNC("wmt_core: patch dwn:%d frag(%d, %d) %s\n", + iRet, fragSeq, fragSize, (!iRet && (fragSeq == fragNum)) ? "ok" : "fail"); + + if (fragSeq != fragNum) + iRet = -7; +done: + /* WMT_CTRL_FREE_PATCH always return 0 */ + ctrlData.ctrlId = WMT_CTRL_FREE_PATCH; + ctrlData.au4CtrlData[0] = index + 1; + wmt_ctrl(&ctrlData); + /* wmt_core_ctrl(WMT_CTRL_FREE_PATCH, NULL, NULL); */ + if ((iRet == -2) || (iRet == -3)) { + /*no patch found or patch version does not match with hw version, + * we check if patch is mandatory or not, if yes, return iRet, if not return 0 + */ + if (gp_mt6620_info->bWorkWithoutPatch != MTK_WCN_BOOL_FALSE) + iRet = 0; + } + + return iRet; +} + + +#else +static INT32 mt6620_patch_dwn(VOID) +{ + INT32 iRet = -1; + P_WMT_PATCH patchHdr; + PUINT8 pbuf; + UINT32 patchSize; + UINT32 fragSeq; + UINT32 fragNum; + UINT16 fragSize = 0; + UINT16 cmdLen; + UINT32 offset; + UINT32 u4Res; + UINT8 evtBuf[8]; + PINT8 cDataTime = NULL; + /*PINT8 cPlat = NULL; */ + UINT16 u2HwVer = 0; + UINT16 u2SwVer = 0; + UINT32 u4PatchVer = 0; + UINT32 patchSizePerFrag = 0; + WMT_CTRL_DATA ctrlData; + + /*1.check hardware information */ + if (gp_mt6620_info == NULL) { + WMT_ERR_FUNC("null gp_mt6620_info!\n"); + return -1; + } +#if 0 + ctrlData.ctrlId = WMT_CTRL_GET_PATCH_NAME; + ctrlData.au4CtrlData[0] = (UINT32) &gDefPatchName; + iRet = wmt_ctrl(&ctrlData); + + if (mt6620_update_patch_name()) { + WMT_ERR_FUNC("invalid patch name, ommit patch download process.\n"); + return -1; + } + + ctrlData.ctrlId = WMT_CTRL_GET_PATCH; + ctrlData.au4CtrlData[0] = (UINT32) &gDefPatchName; + ctrlData.au4CtrlData[1] = (UINT32) &gFullPatchName; + ctrlData.au4CtrlData[2] = (UINT32) &pbuf; + ctrlData.au4CtrlData[3] = (UINT32) &patchSize; + iRet = wmt_ctrl(&ctrlData); + if (iRet) { + WMT_ERR_FUNC("wmt_core: WMT_CTRL_GET_PATCH fail:%d\n", iRet); + iRet = -2; + goto done; + } +#else + /* <2> search patch and read patch content */ + /* <2.1> search patch */ + ctrlData.ctrlId = WMT_CTRL_PATCH_SEARCH; + iRet = wmt_ctrl(&ctrlData); + if (iRet == 0) { + /* patch with correct Hw Ver Major Num found */ + ctrlData.ctrlId = WMT_CTRL_GET_PATCH_NAME; + ctrlData.au4CtrlData[0] = (size_t) &gFullPatchName; + iRet = wmt_ctrl(&ctrlData); + + WMT_INFO_FUNC("valid patch found: (%s)\n", gFullPatchName); + /* <2.2> read patch content */ + ctrlData.ctrlId = WMT_CTRL_GET_PATCH; + ctrlData.au4CtrlData[0] = (size_t) NULL; + ctrlData.au4CtrlData[1] = (size_t) &gFullPatchName; + + } else { + iRet -= 1; + return iRet; + } + ctrlData.au4CtrlData[2] = (size_t) &pbuf; + ctrlData.au4CtrlData[3] = (size_t) &patchSize; + iRet = wmt_ctrl(&ctrlData); + if (iRet) { + WMT_ERR_FUNC("wmt_core: WMT_CTRL_GET_PATCH fail:%d\n", iRet); + iRet -= 1; + goto done; + } +#endif + + /* |<-BCNT_PATCH_BUF_HEADROOM(8) bytes dummy allocated->|<-patch file->| */ + pbuf += BCNT_PATCH_BUF_HEADROOM; + /* patch file with header: + * |<-patch header: 28 Bytes->|<-patch body: X Bytes ----->| + */ + patchHdr = (P_WMT_PATCH) pbuf; + /* check patch file information */ + + cDataTime = patchHdr->ucDateTime; + u2HwVer = patchHdr->u2HwVer; + u2SwVer = patchHdr->u2SwVer; + u4PatchVer = patchHdr->u4PatchVer; + /*cPlat = &patchHdr->ucPLat[0]; */ + + cDataTime[15] = '\0'; + + /* remove patch header: + * |<-patch body: X Bytes (X=patchSize)--->| + */ + if (patchSize < sizeof(WMT_PATCH)) { + WMT_ERR_FUNC("error patch size\n"); + return -1; + } + patchSize -= sizeof(WMT_PATCH); + pbuf += sizeof(WMT_PATCH); + WMT_INFO_FUNC("===========================================\n"); + WMT_INFO_FUNC("[Combo Patch] Built Time = %s\n", cDataTime); + WMT_INFO_FUNC("[Combo Patch] Hw Ver = 0x%x\n", + ((u2HwVer & 0x00ff) << 8) | ((u2HwVer & 0xff00) >> 8)); + WMT_INFO_FUNC("[Combo Patch] Sw Ver = 0x%x\n", + ((u2SwVer & 0x00ff) << 8) | ((u2SwVer & 0xff00) >> 8)); + WMT_INFO_FUNC("[Combo Patch] Ph Ver = 0x%04x\n", + ((u4PatchVer & 0xff000000) >> 24) | ((u4PatchVer & 0x00ff0000) >> 16)); + WMT_INFO_FUNC("[Combo Patch] Platform = %c%c%c%c\n", patchHdr->ucPLat[0], + patchHdr->ucPLat[1], patchHdr->ucPLat[2], patchHdr->ucPLat[3]); + WMT_INFO_FUNC("[Combo Patch] Content Size = 0x%x\n", patchSize); + WMT_INFO_FUNC("[Combo Patch] Content CRC = 0x%04x\n", osal_crc16(pbuf, patchSize)); + WMT_INFO_FUNC("===========================================\n"); + + patchSizePerFrag = (MAJORNUM(gp_mt6620_info->u4HwVer) != 0) ? + DEFAULT_PATCH_FRAG_SIZE : MT6620E2_PATCH_FRAG_SIZE; + + /* reserve 1st patch cmd space before patch body + * |<-WMT_CMD: 5Bytes->|<-patch body: X Bytes (X=patchSize)----->| + */ + osal_memcpy(&gp_mt6620_patch_info, patchHdr, osal_sizeof(WMT_PATCH)); + pbuf -= sizeof(WMT_PATCH_CMD); + + fragNum = patchSize / patchSizePerFrag; + fragNum += ((fragNum * patchSizePerFrag) == patchSize) ? 0 : 1; + + WMT_DBG_FUNC("patch size(%d) fragNum(%d)\n", patchSize, fragNum); + + + /* send all fragments */ + offset = sizeof(WMT_PATCH_CMD); + fragSeq = 0; + while (fragSeq < fragNum) { + WMT_DBG_FUNC("patch size(%d) fragNum(%d)\n", patchSize, fragNum); + if (fragSeq == (fragNum - 1)) { + /* last fragment */ + fragSize = patchSize - fragSeq * patchSizePerFrag; + WMT_PATCH_CMD[4] = WMT_PATCH_FRAG_LAST; + } else { + fragSize = patchSizePerFrag; + WMT_PATCH_CMD[4] = (fragSeq == 0) ? WMT_PATCH_FRAG_1ST : WMT_PATCH_FRAG_MID; + } + /* update length field in CMD:flag+frag */ + cmdLen = 1 + fragSize; + osal_memcpy(&WMT_PATCH_CMD[2], &cmdLen, 2); + /* copy patch CMD to buf (overwrite last 5-byte in prev frag) */ + osal_memcpy(pbuf + offset - sizeof(WMT_PATCH_CMD), WMT_PATCH_CMD, + sizeof(WMT_PATCH_CMD)); + + /* iRet = (*kal_stp_tx)(pbuf + offset - sizeof(WMT_PATCH_CMD), + * fragSize + sizeof(WMT_PATCH_CMD), &u4Res); + */ + iRet = + wmt_core_tx(pbuf + offset - sizeof(WMT_PATCH_CMD), + fragSize + sizeof(WMT_PATCH_CMD), &u4Res, MTK_WCN_BOOL_FALSE); + if (iRet || (u4Res != fragSize + sizeof(WMT_PATCH_CMD))) { + WMT_ERR_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) fail(%d)\n", fragSeq, + fragSize + sizeof(WMT_PATCH_CMD), u4Res, iRet); + iRet = -4; + break; + } + WMT_DBG_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) ok\n", + fragSeq, fragSize + sizeof(WMT_PATCH_CMD), u4Res); + + osal_memset(evtBuf, 0, sizeof(evtBuf)); + /* iRet = (*kal_stp_rx)(evtBuf, sizeof(WMT_PATCH_EVT), &u4Res); */ + iRet = wmt_core_rx(evtBuf, sizeof(WMT_PATCH_EVT), &u4Res); + if (iRet || (u4Res != sizeof(WMT_PATCH_EVT))) { + WMT_ERR_FUNC("wmt_core: read WMT_PATCH_EVT length(%d, %d) fail(%d)\n", + sizeof(WMT_PATCH_EVT), u4Res, iRet); + iRet = -5; + break; + } +#if CFG_CHECK_WMT_RESULT + if (osal_memcmp(evtBuf, WMT_PATCH_EVT, sizeof(WMT_PATCH_EVT)) != 0) { + WMT_ERR_FUNC("rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%d):[%02X,%02X,%02X,%02X,%02X]\n", + u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], + sizeof(WMT_PATCH_EVT), WMT_PATCH_EVT[0], WMT_PATCH_EVT[1], + WMT_PATCH_EVT[2], WMT_PATCH_EVT[3], WMT_PATCH_EVT[4]); + iRet = -6; + break; + } +#endif + WMT_DBG_FUNC("wmt_core: read WMT_PATCH_EVT length(%d, %d) ok\n", + sizeof(WMT_PATCH_EVT), u4Res); + +#if 0 + WMT_DBG_FUNC("wmt_core: send patch frag(%d) [%02X,%02X,%02X,%02X,%02X] (%d) ok", + fragSeq, WMT_PATCH_CMD[0], WMT_PATCH_CMD[1], WMT_PATCH_CMD[2], + WMT_PATCH_CMD[3], WMT_PATCH_CMD[4], fragSize); +#endif + + offset += patchSizePerFrag; + ++fragSeq; + } + + WMT_INFO_FUNC("wmt_core: patch dwn:%d frag(%d, %d) %s\n", + iRet, fragSeq, fragSize, (!iRet && (fragSeq == fragNum)) ? "ok" : "fail"); + + if (fragSeq != fragNum) + iRet = -7; +done: + /* WMT_CTRL_FREE_PATCH always return 0 */ + wmt_core_ctrl(WMT_CTRL_FREE_PATCH, NULL, NULL); + if ((iRet == -2) || (iRet == -3)) { + /*no patch found or patch version does not match with hw version, + * we check if patch is mandatory or not, if yes, return iRet, if not return 0 + */ + if (gp_mt6620_info->bWorkWithoutPatch != MTK_WCN_BOOL_FALSE) + iRet = 0; + } + + return iRet; +} + +static INT32 mt6620_update_patch_name(VOID) +{ + INT32 len; + UINT8 cTmpPatchName[NAME_MAX + 1] = { 0 }; + + /*init.get hardware version */ + /* TODO:[FixMe][GeorgeKuo]: check using memcpy or strncpy??? */ + /*osal_memcpy (gFullPatchName, gDefPatchName, osal_strlen(gDefPatchName)); */ + osal_strncpy(gFullPatchName, gDefPatchName, osal_sizeof(gFullPatchName)); + + /*1.check hardware information */ + if (gp_mt6620_info == NULL) { + WMT_ERR_FUNC("null gp_mt6620_info!\n"); + osal_memset(gFullPatchName, 0, osal_sizeof(gFullPatchName)); + return -1; + } + + /*2.make possible firmware patch name with original name and hardware version */ + if ((osal_strlen(gDefPatchName) > osal_strlen(WMT_IC_PATCH_TAIL)) + && ((osal_strlen(gDefPatchName) + osal_strlen(WMT_IC_PATCH_DUMMY_EXT) <= NAME_MAX)) + ) { + len = osal_strlen(gDefPatchName) - osal_strlen(WMT_IC_PATCH_TAIL); + osal_memcpy(cTmpPatchName, gDefPatchName, len > NAME_MAX ? NAME_MAX : len); + osal_memcpy(cTmpPatchName + osal_strlen(cTmpPatchName), + gp_mt6620_info->cPatchNameExt, + osal_strlen(gp_mt6620_info->cPatchNameExt)); + osal_memcpy(cTmpPatchName + osal_strlen(cTmpPatchName), WMT_IC_PATCH_TAIL, + osal_strlen(WMT_IC_PATCH_TAIL)); + cTmpPatchName[osal_strlen(cTmpPatchName)] = '\0'; + } else { + WMT_ERR_FUNC("invalid default firmware patch name (%s)\n", gDefPatchName); + osal_memset(gFullPatchName, 0, osal_sizeof(gFullPatchName)); + return -2; + } + + /*patch with versioned name exist , update cFullPatchName with full named patch */ + osal_memcpy(gFullPatchName, cTmpPatchName, osal_strlen(cTmpPatchName)); + *(gFullPatchName + osal_strlen(cTmpPatchName)) = '\0'; + WMT_INFO_FUNC("full firmware patch name: %s\n", cTmpPatchName); + + return 0; +} +#endif diff --git a/drivers/misc/mediatek/connectivity/common/common_main/core/wmt_ic_6628.c b/drivers/misc/mediatek/connectivity/common/common_main/core/wmt_ic_6628.c new file mode 100644 index 0000000000000000000000000000000000000000..68b5336e3022015b26c492adf3f8f924182786aa --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/core/wmt_ic_6628.c @@ -0,0 +1,1981 @@ +/* +* Copyright (C) 2016 MediaTek Inc. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. +*/ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + + + + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +#ifdef DFT_TAG +#undef DFT_TAG +#endif +#define DFT_TAG "[WMT-IC]" +#define CFG_IC_MT6628 1 + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include "osal_typedef.h" +#include "wmt_ic.h" +#include "wmt_core.h" +#include "wmt_lib.h" +#include "stp_core.h" + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +#define DEFAULT_PATCH_FRAG_SIZE (1000) +#define WMT_PATCH_FRAG_1ST (0x1) +#define WMT_PATCH_FRAG_MID (0x2) +#define WMT_PATCH_FRAG_LAST (0x3) + +#define CFG_CHECK_WMT_RESULT (1) +/* BT Port 2 Feature. this command does not need after coex command is downconfirmed by LC, */ +#define CFG_WMT_BT_PORT2 (0) + +#define CFG_SET_OPT_REG (0) +#define CFG_WMT_I2S_DBGUART_SUPPORT (0) +#define CFG_SET_OPT_REG_SWLA (0) +#define CFG_SET_OPT_REG_MCUCLK (0) +#define CFG_SET_OPT_REG_MCUIRQ (0) + +#define CFG_SUBSYS_COEX_NEED 0 + +#define CFG_WMT_COREDUMP_ENABLE 0 + +#define CFG_WMT_MULTI_PATCH (1) + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +static UINT8 gFullPatchName[NAME_MAX + 1]; +static const WMT_IC_INFO_S *gp_mt6628_info; +static WMT_PATCH gp_mt6628_patch_info; +static WMT_CO_CLOCK gCoClockEn = WMT_CO_CLOCK_DIS; +#if 0 +static UINT8 WMT_WAKEUP_DIS_GATE_CMD[] = { 0x1, 0x3, 0x01, 0x00, 0x04 }; +static UINT8 WMT_WAKEUP_DIS_GATE_EVT[] = { 0x2, 0x3, 0x02, 0x0, 0x0, 0x04 }; + +static UINT8 WMT_WAKEUP_EN_GATE_CMD[] = { 0x1, 0x3, 0x01, 0x00, 0x05 }; +static UINT8 WMT_WAKEUP_EN_GATE_EVT[] = { 0x2, 0x3, 0x02, 0x0, 0x0, 0x05 }; +#endif + +static UINT8 WMT_QUERY_BAUD_CMD[] = { 0x01, 0x04, 0x01, 0x00, 0x02 }; +static UINT8 WMT_QUERY_BAUD_EVT_115200[] = { 0x02, 0x04, 0x06, 0x00, 0x00, 0x02, 0x00, 0xC2, 0x01, 0x00 }; +static UINT8 WMT_QUERY_BAUD_EVT_X[] = { 0x02, 0x04, 0x06, 0x00, 0x00, 0x02, 0xAA, 0xAA, 0xAA, 0xBB }; +static UINT8 WMT_QUERY_STP_CMD[] = { 0x01, 0x04, 0x01, 0x00, 0x04 }; +static UINT8 WMT_QUERY_STP_EVT_DEFAULT[] = { 0x02, 0x04, 0x06, 0x00, 0x00, 0x04, 0x11, 0x00, 0x00, 0x00 }; +static UINT8 WMT_QUERY_STP_EVT_UART[] = { 0x02, 0x04, 0x06, 0x00, 0x00, 0x04, 0xDF, 0x0E, 0x68, 0x01 }; +static UINT8 WMT_SET_BAUD_CMD_X[] = { 0x01, 0x04, 0x05, 0x00, 0x01, 0xAA, 0xAA, 0xAA, 0xBB }; +static UINT8 WMT_SET_BAUD_EVT[] = { 0x02, 0x04, 0x02, 0x00, 0x00, 0x01 }; +static UINT8 WMT_SET_WAKEUP_WAKE_CMD_RAW[] = { 0xFF }; +static UINT8 WMT_SET_WAKEUP_WAKE_EVT[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x03 }; +static UINT8 WMT_PATCH_CMD[] = { 0x01, 0x01, 0x00, 0x00, 0x00 }; +static UINT8 WMT_PATCH_EVT[] = { 0x02, 0x01, 0x01, 0x00, 0x00 }; +static UINT8 WMT_RESET_CMD[] = { 0x01, 0x07, 0x01, 0x00, 0x04 }; +static UINT8 WMT_RESET_EVT[] = { 0x02, 0x07, 0x01, 0x00, 0x00 }; + +#if CFG_WMT_BT_PORT2 +static UINT8 WMT_BTP2_CMD[] = { 0x01, 0x10, 0x03, 0x00, 0x01, 0x03, 0x01 }; +static UINT8 WMT_BTP2_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; +#endif + +#if CFG_WMT_MULTI_PATCH +static UINT8 WMT_PATCH_ADDRESS_CMD[] = { 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, + 0xD4, 0x01, 0x09, 0xF0, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xff, 0xff +}; +static UINT8 WMT_PATCH_ADDRESS_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; + +static UINT8 WMT_PATCH_P_ADDRESS_CMD[] = { 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, + 0x48, 0x03, 0x09, 0xF0, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xff, 0xff +}; +static UINT8 WMT_PATCH_P_ADDRESS_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; +#endif + +/*coex cmd/evt++*/ +static UINT8 WMT_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x01, 0x00 }; +static UINT8 WMT_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; + +#if CFG_SUBSYS_COEX_NEED +static UINT8 WMT_BT_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x0B, + 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, + 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0xAA +}; +static UINT8 WMT_BT_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; + +static UINT8 WMT_WIFI_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x0C, + 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0xAA +}; +static UINT8 WMT_WIFI_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; + +static UINT8 WMT_PTA_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x0A, + 0x00, 0x04, + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xEE, 0xFF, 0xFF, 0xFE +}; +static UINT8 WMT_PTA_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; + +static UINT8 WMT_MISC_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x09, + 0x00, 0x05, + 0xAA, 0xAA, 0xAA, 0xAA, + 0xBB, 0xBB, 0xBB, 0xBB +}; +static UINT8 WMT_MISC_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; +#endif + +/*coex cmd/evt--*/ +static UINT8 WMT_SET_STP_CMD[] = { 0x01, 0x04, 0x05, 0x00, 0x03, 0xDF, 0x0E, 0x68, 0x01 }; +static UINT8 WMT_SET_STP_EVT[] = { 0x02, 0x04, 0x02, 0x00, 0x00, 0x03 }; +static UINT8 WMT_STRAP_CONF_CMD_FM_COMM[] = { 0x01, 0x05, 0x02, 0x00, 0x02, 0x02 }; +static UINT8 WMT_STRAP_CONF_EVT[] = { 0x02, 0x05, 0x02, 0x00, 0x00, 0x02 }; + +#if 0 +static UINT8 WMT_SET_OSC32K_BYPASS_CMD[] = { 0x01, 0x0A, 0x01, 0x00, 0x05 }; +static UINT8 WMT_SET_OSC32K_BYPASS_EVT[] = { 0x02, 0x0A, 0x01, 0x00, 0x00 }; +#endif + +#if 0 +/* to enable dump feature */ +static UINT8 WMT_CORE_DUMP_EN_CMD[] = { 0x01, 0x0F, 0x02, 0x00, 0x03, 0x01 }; +static UINT8 WMT_CORE_DUMP_EN_EVT[] = { 0x02, 0x0F, 0x01, 0x00, 0x00 }; + +/* to get system stack dump when f/w assert */ +static UINT8 WMT_CORE_DUMP_LEVEL_01_CMD[] = { 0x1, 0x0F, 0x07, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +static UINT8 WMT_CORE_DUMP_LEVEL_01_EVT[] = { 0x2, 0x0F, 0x01, 0x00, 0x00 }; + +/* to get task and system stack dump when f/w assert */ +static UINT8 WMT_CORE_DUMP_LEVEL_02_CMD[] = { 0x1, 0x0F, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +static UINT8 WMT_CORE_DUMP_LEVEL_02_EVT[] = { 0x2, 0x0F, 0x01, 0x00, 0x00 }; + +/* to get bt related memory dump when f/w assert */ +static UINT8 WMT_CORE_DUMP_LEVEL_03_CMD[] = { 0x1, 0x0F, 0x07, 0x00, 0x03, 0x00, 0x00, 0x09, 0xF0, 0x00, 0x0A }; +static UINT8 WMT_CORE_DUMP_LEVEL_03_EVT[] = { 0x2, 0x0F, 0x01, 0x00, 0x00 }; +#endif +/* to get full dump when f/w assert */ +static UINT8 WMT_CORE_DUMP_LEVEL_04_CMD[] = { 0x1, 0x0F, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +static UINT8 WMT_CORE_DUMP_LEVEL_04_EVT[] = { 0x2, 0x0F, 0x01, 0x00, 0x00 }; + +static UINT8 WMT_CORE_CO_CLOCK_CMD[] = { 0x1, 0x0A, 0x02, 0x00, 0x08, 0x03 }; +static UINT8 WMT_CORE_CO_CLOCK_EVT[] = { 0x2, 0x0A, 0x01, 0x00, 0x00 }; + + +#if (MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT) +static UINT8 WMT_SET_I2S_SLAVE_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ + , 0x01 /* op: w */ + , 0x01 /*type: reg */ + , 0x00 /*rev */ + , 0x01 /*1 registers */ + , 0x78, 0x00, 0x05, 0x80 /*addr:0x80050078 */ + , 0x00, 0x00, 0x11, 0x01 /*value:0x11010000 */ + , 0x00, 0x00, 0x77, 0x07 /*mask:0x07770000 */ +}; + +static UINT8 WMT_SET_I2S_SLAVE_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ + , 0x00 /*S: 0 */ + , 0x00 /*type: reg */ + , 0x00 /*rev */ + , 0x01 /*1 registers */ +}; + +static UINT8 WMT_SET_DAI_TO_PAD_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ + , 0x01 /* op: w */ + , 0x01 /*type: reg */ + , 0x00 /*rev */ + , 0x01 /*1 registers */ + , 0x74, 0x00, 0x05, 0x80 /*addr:0x80050074 */ + , 0x44, 0x44, 0x00, 0x00 /*value:0x11010000 */ + , 0x77, 0x77, 0x00, 0x00 /*mask:0x07770000 */ +}; + +static UINT8 WMT_SET_DAI_TO_PAD_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ + , 0x00 /*S: 0 */ + , 0x00 /*type: reg */ + , 0x00 /*rev */ + , 0x01 /*1 registers */ +}; + +static UINT8 WMT_SET_DAI_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ + , 0x01 /* op: w */ + , 0x01 /*type: reg */ + , 0x00 /*rev */ + , 0x01 /*1 registers */ + , 0xA0, 0x00, 0x05, 0x80 /*addr:0x80050074 */ + , 0x04, 0x00, 0x00, 0x00 /*value:0x11010000 */ + , 0x04, 0x00, 0x00, 0x00 /*mask:0x07770000 */ +}; + +static UINT8 WMT_SET_DAI_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ + , 0x00 /*S: 0 */ + , 0x00 /*type: reg */ + , 0x00 /*rev */ + , 0x01 /*1 registers */ +}; +#endif + + +#ifndef CFG_IC_MT6628 /* For MT6628 no need to set ALLEINT registers, done in f/w */ +/* enable all interrupt */ +static UINT8 WMT_SET_ALLINT_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ + , 0x01 /* op: w */ + , 0x01 /*type: reg */ + , 0x00 /*rev */ + , 0x01 /*1 registers */ + , 0x00, 0x03, 0x05, 0x80 /*addr:0x80050300 */ + , 0x00, 0xC4, 0x00, 0x00 /*value:0x0000C400 */ + , 0x00, 0xC4, 0x00, 0x00 /*mask:0x0000C400 */ +}; + +static UINT8 WMT_SET_ALLINT_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ + , 0x00 /*S: 0 */ + , 0x00 /*type: reg */ + , 0x00 /*rev */ + , 0x01 /*1 registers */ +}; + +#endif + +#if CFG_SET_OPT_REG_SWLA /* enable swla: eesk(7) eecs(8) oscen(19) sck0(24) scs0(25) */ +static UINT8 WMT_SET_SWLA_REG_CMD[] = { 0x01, 0x08, 0x1C, 0x00 /*length */ + , 0x01 /* op: w */ + , 0x01 /*type: reg */ + , 0x00 /*rev */ + , 0x02 /*2 registers */ + , 0x10, 0x01, 0x05, 0x80 /*addr:0x80050110 */ + , 0x10, 0x10, 0x01, 0x00 /*value:0x00011010 */ + , 0xF0, 0xF0, 0x0F, 0x00 /*mask:0x000FF0F0 */ + , 0x40, 0x01, 0x05, 0x80 /*addr:0x80050140 */ + , 0x00, 0x10, 0x01, 0x00 /*value:0x00011000 */ + , 0x00, 0xF0, 0x0F, 0x00 /*mask:0x000FF000 */ +}; + +static UINT8 WMT_SET_SWLA_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ + , 0x00 /*S: 0 */ + , 0x00 /*type: reg */ + , 0x00 /*rev */ + , 0x02 /*2 registers */ +}; +#endif + +#if CFG_SET_OPT_REG_MCUCLK /* enable mcu clk: antsel_4, eedi */ +static UINT8 WMT_SET_MCUCLK_REG_CMD[] = { 0x01, 0x08, (4 + 12 * 4), 0x00 /*length */ + , 0x01 /* op: w */ + , 0x01 /* type: reg */ + , 0x00 /* rev */ + , 0x04 /* 4 registers */ + , 0x00, 0x04, 0x00, 0x80 /* addr:0x8000 0400 */ + , 0x00, 0x14, 0x00, 0x00 /* value:0x0000 1400(osc, hclk), 0x0000 1501(PLL, en) */ + , 0xFF, 0xFF, 0x00, 0x00 /* mask:0x0000 FFFF */ + , 0x80, 0x01, 0x05, 0x80 /* addr:0x8005 0180 */ + , 0x12, 0x13, 0x00, 0x00 /* value:0x0000 1312(osc, hclk), 0x0000 1a19(PLL, en) */ + , 0xFF, 0xFF, 0x00, 0x00 /* mask:0x0000 FFFF */ + , 0x00, 0x01, 0x05, 0x80 /* addr:0x8005 0100 */ + , 0x00, 0x00, 0x02, 0x00 /* value:0x0002 0000 */ + , 0x00, 0x00, 0x0F, 0x00 /* mask:0x000F 0000 */ + , 0x10, 0x01, 0x05, 0x80 /* addr:0x8005 0110 */ + , 0x02, 0x00, 0x00, 0x00 /* value:0x0000 0002 */ + , 0x0F, 0x00, 0x00, 0x00 /* mask:0x0000 000F */ +}; + +static UINT8 WMT_SET_MCUCLK_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ + , 0x00 /* S: 0 */ + , 0x00 /* type: reg */ + , 0x00 /* rev */ + , 0x04 /* 4 registers */ +}; +#endif + +#if CFG_WMT_I2S_DBGUART_SUPPORT /* register write for debug uart */ +static UINT8 WMT_SET_DBGUART_REG_CMD[] = { 0x01, 0x08, 0x1C, 0x00 /*length */ + , 0x01 /* op: w */ + , 0x01 /*type: reg */ + , 0x00 /*rev */ + , 0x02 /*2 registers */ + , 0x30, 0x01, 0x05, 0x80 /*addr:0x80050130 */ + , 0x00, 0x00, 0x00, 0x00 /*value:0x00000000 */ + , 0xF0, 0x0F, 0x00, 0x00 /*mask:0x00000FF0 */ + , 0x40, 0x01, 0x05, 0x80 /*addr:0x80050140 */ + , 0x00, 0x01, 0x00, 0x00 /*value:0x00000100 */ + , 0x00, 0x01, 0x00, 0x00 /*mask:0x00000100 */ +}; + +static UINT8 WMT_SET_DBGUART_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ + , 0x00 /*S: 0 */ + , 0x00 /*type: reg */ + , 0x00 /*rev */ + , 0x02 /*2 registers */ +}; +#endif + +#if CFG_SET_OPT_REG_MCUIRQ /* enable mcu irq: antsel_4, wlan_act */ +#if 1 /* Ray */ +static UINT8 WMT_SET_MCUIRQ_REG_CMD[] = { 0x01, 0x08, (4 + 12 * 4), 0x00 /*length */ + , 0x01 /* op: w */ + , 0x01 /* type: reg */ + , 0x00 /* rev */ + , 0x04 /* 4 registers */ + , 0x00, 0x04, 0x00, 0x80 /* addr:0x8000_0400 */ + , 0x03, 0x14, 0x00, 0x00 /* value:0x0000_1403 check confg debug flag 3 low word */ + , 0xFF, 0xFF, 0x00, 0x00 /* mask:0x0000_FFFF */ + /* cirq_int_n */ + , 0x10, 0x01, 0x05, 0x80 /* addr:0x8005_0110 */ + , 0x02, 0x00, 0x00, 0x00 /* value:0x0000_0002 set EEDI as cirq_int_n debug flag (monitor flag2) */ + , 0x07, 0x00, 0x00, 0x00 /* mask:0x0000_0007 */ + , 0x00, 0x01, 0x05, 0x80 /* addr:0x8005_0100 */ + , 0x00, 0x00, 0x02, 0x00 /* value:0x0002_0000 (ANTSEL4=>monitor flag 0, ahb_x2_gt_ck debug flag) */ + , 0x00, 0x00, 0x07, 0x00 /* mask:0x0007_0000 */ + /* 1. ARM irq_b, monitor flag 0 */ + , 0x80, 0x01, 0x05, 0x80 /* addr:0x8005_0180 */ + , 0x1F, 0x1E, 0x00, 0x00 /* value:0x0000_1E1F check mcusys debug flag */ + , 0x7F, 0x7F, 0x00, 0x00 /* mask:0x0000_7F7F */ +}; + +static UINT8 WMT_SET_MCUIRQ_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ + , 0x00 /* S: 0 */ + , 0x00 /* type: reg */ + , 0x00 /* rev */ + , 0x04 /* 5 registers */ +}; +#elif 0 /* KC */ +static UINT8 WMT_SET_MCUIRQ_REG_CMD[] = { 0x01, 0x08, (4 + 12 * 5), 0x00 /*length */ + , 0x01 /* op: w */ + , 0x01 /* type: reg */ + , 0x00 /* rev */ + , 0x05 /* 5 registers */ + , 0x00, 0x04, 0x00, 0x80 /* addr:0x8000_0400 */ + , 0x00, 0x02, 0x00, 0x00 /* value:0x0000_0200 [15:8]=0x2 arm irq_b, 0xA irq_bus[5] bt_timcon_irq_b */ + , 0x00, 0xFF, 0x00, 0x00 /* mask:0x0000_FF00 */ + /* 1. ARM irq_b, monitor flag 0 */ + , 0x80, 0x01, 0x05, 0x80 /* addr:0x8005_0180 */ + , 0x18, 0x00, 0x00, 0x00 /* value:0x0000_0018 [6:0]=001_1000 (monitor flag 0 select, MCUSYS, SEL:8) */ + , 0x7F, 0x00, 0x00, 0x00 /* mask:0x0000_007F */ + , 0x00, 0x01, 0x05, 0x80 /* addr:0x8005_0100 */ + , 0x00, 0x00, 0x02, 0x00 /* value:0x0002_0000 (ANTSEL4=>monitor flag 0) */ + , 0x00, 0x00, 0x07, 0x00 /* mask:0x0007_0000 */ + /* 2. irq_bus[5] bt_timcon_irq_b monitor flag 15 */ + , 0xB0, 0x01, 0x05, 0x80 /* addr:0x8005_01B0 */ + , 0x00, 0x00, 0x00, 0x16 /* value:0x1600_0000 [30:24]=001_0110 (monitor flag 15 select, MCUSYS, SEL:6) */ + , 0x00, 0x00, 0x00, 0x7F /* mask:0x7F00_0000 */ + , 0x30, 0x01, 0x05, 0x80 /* addr:0x8005_0130 */ + , 0x00, 0x20, 0x00, 0x00 /* value:0x0000_2000 (WLAN_ACT=>monitor flag 15) */ + , 0x00, 0x70, 0x00, 0x00 /* mask:0x0000_7000 */ +}; + +static UINT8 WMT_SET_MCUIRQ_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ + , 0x00 /* S: 0 */ + , 0x00 /* type: reg */ + , 0x00 /* rev */ + , 0x05 /* 5 registers */ +}; +#endif +#endif + +static UINT8 WMT_SET_CRYSTAL_TRIMING_CMD[] = { 0x01, 0x12, 0x02, 0x00, 0x01, 0x00 }; +static UINT8 WMT_SET_CRYSTAL_TRIMING_EVT[] = { 0x02, 0x12, 0x02, 0x00, 0x01, 0x00 }; + +static UINT8 WMT_GET_CRYSTAL_TRIMING_CMD[] = { 0x01, 0x12, 0x02, 0x00, 0x00, 0x00 }; +static UINT8 WMT_GET_CRYSTAL_TRIMING_EVT[] = { 0x02, 0x12, 0x02, 0x00, 0x00, 0x00 }; + +/* set sdio driving */ +static UINT8 WMT_SET_SDIO_DRV_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ + , 0x01 /* op: w */ + , 0x01 /*type: reg */ + , 0x00 /*rev */ + , 0x01 /*1 registers */ + , 0x50, 0x00, 0x05, 0x80 /*addr:0x80050050 */ + , 0x44, 0x44, 0x04, 0x00 /*value:0x00044444 */ + , 0x77, 0x77, 0x07, 0x00 /*mask:0x00077777 */ +}; + +static UINT8 WMT_SET_SDIO_DRV_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ + , 0x00 /*S: 0 */ + , 0x00 /*type: reg */ + , 0x00 /*rev */ + , 0x01 /*1 registers */ +}; + + +#ifndef CFG_IC_MT6628 + +/* stp sdio init scripts */ +static struct init_script init_table_1_1[] = { + /* table_1_1 is only applied to common SDIO interface */ + INIT_CMD(WMT_SET_ALLINT_REG_CMD, WMT_SET_ALLINT_REG_EVT, "enable all interrupt"), + /* applied to MT6628 ? */ + INIT_CMD(WMT_WAKEUP_DIS_GATE_CMD, WMT_WAKEUP_DIS_GATE_EVT, "disable gating"), +}; + +#endif + +static struct init_script init_table_1_2[] = { + INIT_CMD(WMT_QUERY_BAUD_CMD, WMT_QUERY_BAUD_EVT_115200, "query baud 115200"), + INIT_CMD(WMT_QUERY_STP_CMD, WMT_QUERY_STP_EVT_DEFAULT, "query stp default"), + INIT_CMD(WMT_SET_BAUD_CMD_X, WMT_SET_BAUD_EVT, "set baud rate"), +}; + + +static struct init_script init_table_2[] = { + INIT_CMD(WMT_QUERY_BAUD_CMD, WMT_QUERY_BAUD_EVT_X, "query baud X"), +}; + +static struct init_script init_table_3[] = { + INIT_CMD(WMT_RESET_CMD, WMT_RESET_EVT, "wmt reset"), +#if CFG_WMT_BT_PORT2 + INIT_CMD(WMT_BTP2_CMD, WMT_BTP2_EVT, "set bt port2"), +#endif +}; + +static struct init_script set_crystal_timing_script[] = { + INIT_CMD(WMT_SET_CRYSTAL_TRIMING_CMD, WMT_SET_CRYSTAL_TRIMING_EVT, + "set crystal trim value"), +}; + +static struct init_script get_crystal_timing_script[] = { + INIT_CMD(WMT_GET_CRYSTAL_TRIMING_CMD, WMT_GET_CRYSTAL_TRIMING_EVT, + "get crystal trim value"), +}; + + +#if 0 +static struct init_script init_table_3_1[] = { + INIT_CMD(WMT_WAKEUP_EN_GATE_CMD, WMT_WAKEUP_EN_GATE_EVT, "ensable gating"), +}; +#endif + +static struct init_script init_table_4[] = { + INIT_CMD(WMT_SET_STP_CMD, WMT_SET_STP_EVT, "set stp"), +}; + +static struct init_script init_table_5[] = { + INIT_CMD(WMT_QUERY_STP_CMD, WMT_QUERY_STP_EVT_UART, "query stp uart"), + INIT_CMD(WMT_QUERY_BAUD_CMD, WMT_QUERY_BAUD_EVT_X, "query baud X"), +}; + +static struct init_script init_table_5_1[] = { + INIT_CMD(WMT_STRAP_CONF_CMD_FM_COMM, WMT_STRAP_CONF_EVT, "configure FM comm"), +}; + +static struct init_script init_table_6[] = { +#if 0 + INIT_CMD(WMT_CORE_DUMP_EN_CMD, WMT_CORE_DUMP_EN_EVT, "configure memory and core dump"), +#endif + INIT_CMD(WMT_CORE_DUMP_LEVEL_04_CMD, WMT_CORE_DUMP_LEVEL_04_EVT, "setup core dump level"), +}; + +#if 0 +static struct init_script init_table_6[] = { + INIT_CMD(WMT_SET_OSC32K_BYPASS_CMD, WMT_SET_OSC32K_BYPASS_EVT, "set OSC32k by pass mode."), +}; +#endif + +#if defined(CFG_SET_OPT_REG) && CFG_SET_OPT_REG +static struct init_script set_registers[] = { + /* INIT_CMD(WMT_SET_GPS_REG_CMD, WMT_SET_GPS_REG_EVT, "set wmt registers"), */ + /* INIT_CMD(WMT_SET_SDIODRV_REG_CMD, WMT_SET_SDIODRV_REG_EVT, "set SDIO driving registers") */ +#if CFG_WMT_I2S_DBGUART_SUPPORT + INIT_CMD(WMT_SET_DBGUART_REG_CMD, WMT_SET_DBGUART_REG_EVT, "set debug uart registers"), +#endif +#if CFG_SET_OPT_REG_SWLA + INIT_CMD(WMT_SET_SWLA_REG_CMD, WMT_SET_SWLA_REG_EVT, "set swla registers"), +#endif +#if CFG_SET_OPT_REG_MCUCLK + INIT_CMD(WMT_SET_MCUCLK_REG_CMD, WMT_SET_MCUCLK_REG_EVT, "set mcuclk dbg registers"), +#endif +#if CFG_SET_OPT_REG_MCUIRQ + INIT_CMD(WMT_SET_MCUIRQ_REG_CMD, WMT_SET_MCUIRQ_REG_EVT, "set mcu irq dbg registers"), +#endif +}; +#endif + +static struct init_script coex_table[] = { + INIT_CMD(WMT_COEX_SETTING_CONFIG_CMD, WMT_COEX_SETTING_CONFIG_EVT, "coex_wmt"), + +#if CFG_SUBSYS_COEX_NEED +/* no need in MT6628 */ + INIT_CMD(WMT_BT_COEX_SETTING_CONFIG_CMD, WMT_BT_COEX_SETTING_CONFIG_EVT, "coex_bt"), + INIT_CMD(WMT_WIFI_COEX_SETTING_CONFIG_CMD, WMT_WIFI_COEX_SETTING_CONFIG_EVT, "coex_wifi"), + INIT_CMD(WMT_PTA_COEX_SETTING_CONFIG_CMD, WMT_PTA_COEX_SETTING_CONFIG_EVT, "coex_ext_pta"), + INIT_CMD(WMT_MISC_COEX_SETTING_CONFIG_CMD, WMT_MISC_COEX_SETTING_CONFIG_EVT, "coex_misc"), +#endif +}; + +static struct init_script osc_type_table[] = { + INIT_CMD(WMT_CORE_CO_CLOCK_CMD, WMT_CORE_CO_CLOCK_EVT, "osc_type"), +}; + +#if (MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT) +static struct init_script merge_pcm_table[] = { + INIT_CMD(WMT_SET_I2S_SLAVE_REG_CMD, WMT_SET_I2S_SLAVE_REG_EVT, "I2S_Slave"), + INIT_CMD(WMT_SET_DAI_TO_PAD_REG_CMD, WMT_SET_DAI_TO_PAD_REG_EVT, "DAI_PAD"), + INIT_CMD(WMT_SET_DAI_REG_CMD, WMT_SET_DAI_REG_EVT, "DAI_EVT"), +}; +#endif + + +static struct init_script sdio_driving_table[] = { + INIT_CMD(WMT_SET_SDIO_DRV_REG_CMD, WMT_SET_SDIO_DRV_REG_EVT, "sdio_driving"), +}; + + +/* MT6628 Chip Version and Info Table */ +static const WMT_IC_INFO_S mt6628_info_table[] = { + { + .u4HwVer = 0x8A00, + .cChipName = WMT_IC_NAME_MT6628, + .cChipVersion = WMT_IC_VER_E1, + .cPatchNameExt = WMT_IC_PATCH_E1_EXT, + .bWorkWithoutPatch = MTK_WCN_BOOL_FALSE, + .bPsmSupport = MTK_WCN_BOOL_TRUE, + }, + { + .u4HwVer = 0x8A10, + .cChipName = WMT_IC_NAME_MT6628, + .cChipVersion = WMT_IC_VER_E2, + .cPatchNameExt = WMT_IC_PATCH_E2_EXT, + .bWorkWithoutPatch = MTK_WCN_BOOL_FALSE, + .bPsmSupport = MTK_WCN_BOOL_TRUE, + }, + { + .u4HwVer = 0x8B10, + .cChipName = WMT_IC_NAME_MT6628, + .cChipVersion = WMT_IC_VER_E3, + .cPatchNameExt = WMT_IC_PATCH_E2_EXT, + .bWorkWithoutPatch = MTK_WCN_BOOL_FALSE, + .bPsmSupport = MTK_WCN_BOOL_TRUE, + }, + { + .u4HwVer = 0x8B11, + .cChipName = WMT_IC_NAME_MT6628, + .cChipVersion = WMT_IC_VER_E4, + .cPatchNameExt = WMT_IC_PATCH_E2_EXT, + .bWorkWithoutPatch = MTK_WCN_BOOL_FALSE, + .bPsmSupport = MTK_WCN_BOOL_TRUE, + }, + { + .u4HwVer = 0x8a11, + .cChipName = WMT_IC_NAME_MT6628, + .cChipVersion = WMT_IC_VER_E5, + .cPatchNameExt = WMT_IC_PATCH_E2_EXT, + .bWorkWithoutPatch = MTK_WCN_BOOL_FALSE, + .bPsmSupport = MTK_WCN_BOOL_TRUE, + } +}; + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +static INT32 mt6628_sw_init(P_WMT_HIF_CONF pWmtHifConf); + +static INT32 mt6628_sw_deinit(P_WMT_HIF_CONF pWmtHifConf); + +static INT32 mt6628_pin_ctrl(WMT_IC_PIN_ID id, WMT_IC_PIN_STATE state, UINT32 flag); + +static INT32 mt6628_aif_ctrl(WMT_IC_PIN_STATE state, UINT32 flag); + +static INT32 mt6628_ver_check(VOID); + +static const WMT_IC_INFO_S *mt6628_find_wmt_ic_info(const UINT32 hw_ver); + +static INT32 wmt_stp_init_coex(VOID); + +#if CFG_WMT_MULTI_PATCH +static INT32 mt6628_patch_dwn(UINT32 index); +static INT32 mt6628_patch_info_prepare(VOID); +#else +static INT32 mt6628_patch_dwn(VOID); +#endif + +static INT32 mt6628_co_clock_ctrl(WMT_CO_CLOCK on); +static WMT_CO_CLOCK mt6628_co_clock_get(VOID); + +static INT32 mt6628_crystal_triming_set(VOID); + + +static MTK_WCN_BOOL mt6628_quick_sleep_flag_get(VOID); + +static MTK_WCN_BOOL mt6628_aee_dump_flag_get(VOID); + +static INT32 mt6628_set_sdio_driving(VOID); + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/* MT6628 Operation Function Table */ +WMT_IC_OPS wmt_ic_ops_mt6628 = { + .icId = 0x6628, + .sw_init = mt6628_sw_init, + .sw_deinit = mt6628_sw_deinit, + .ic_pin_ctrl = mt6628_pin_ctrl, + .ic_ver_check = mt6628_ver_check, + .co_clock_ctrl = mt6628_co_clock_ctrl, + .is_quick_sleep = mt6628_quick_sleep_flag_get, + .is_aee_dump_support = mt6628_aee_dump_flag_get, + .trigger_stp_assert = NULL, + .deep_sleep_ctrl = NULL, +}; + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +static INT32 mt6628_sw_init(P_WMT_HIF_CONF pWmtHifConf) +{ + INT32 iRet = -1; + UINT32 u4Res = 0; + UINT8 evtBuf[256]; + unsigned long ctrlPa1; + unsigned long ctrlPa2; + UINT32 hw_ver; +#if CFG_WMT_MULTI_PATCH + UINT32 patch_num = 0; + UINT32 patch_index = 0; +#endif + WMT_CTRL_DATA ctrlData; + + WMT_DBG_FUNC(" start\n"); + + osal_assert(gp_mt6628_info != NULL); + if ((gp_mt6628_info == NULL) + || (pWmtHifConf == NULL) + ) { + WMT_ERR_FUNC("null pointers: gp_mt6628_info(0x%p), pWmtHifConf(0x%p)\n", + gp_mt6628_info, pWmtHifConf); + return -1; + } + + hw_ver = gp_mt6628_info->u4HwVer; + + /* 4 <3.1> start init for sdio */ +#ifndef CFG_IC_MT6628 /* For MT6628 no need to do this operation */ + if (pWmtHifConf->hifType == WMT_HIF_SDIO) { + wmt_lib_ps_set_idle_time(STP_PSM_SDIO_IDLE_TIME_SLEEP); + /* 1. enable all INT32 */ + /* 2. disable mcu gate (only MT6628E1/E2) */ + iRet = wmt_core_init_script(init_table_1_1, ARRAY_SIZE(init_table_1_1)); + if (iRet) { + WMT_ERR_FUNC("init_table_1_1 fail:%d\n", iRet); + osal_assert(0); + return -1; + } + } +#endif + /* 4 <3.2> start init for uart */ + if (pWmtHifConf->hifType == WMT_HIF_UART) { + /* init variable fields for script execution */ + osal_memcpy(&WMT_SET_BAUD_CMD_X[5], &pWmtHifConf->au4HifConf[0], + osal_sizeof(UINT32)); + WMT_SET_BAUD_CMD_X[8] = (UINT8) 0x00; /* 0xC0 MTK Flow Control *//* no flow control */ + osal_memcpy(&WMT_QUERY_BAUD_EVT_X[6], &pWmtHifConf->au4HifConf[0], + osal_sizeof(UINT32)); + WMT_QUERY_BAUD_EVT_X[9] = (UINT8) 0x00; /* 0xC0 MTK Flow Control *//* no flow control */ + + /* 3. Query chip baud rate (TEST-ONLY) */ + /* 4. Query chip STP options (TEST-ONLY) */ + /* 5. Change chip baud rate: t_baud */ + /* WMT_DBG_FUNC("WMT-CORE: init_table_1_2 set chip baud:%d", pWmtHifConf->au4HifConf[0]); */ + iRet = wmt_core_init_script(init_table_1_2, ARRAY_SIZE(init_table_1_2)); + if (iRet) { + WMT_ERR_FUNC("init_table_1_2 fail(%d)\n", iRet); + osal_assert(0); + return -2; + } + + /* 6. Set host baudrate and flow control */ + ctrlPa1 = pWmtHifConf->au4HifConf[0]; + ctrlPa2 = 0; + iRet = wmt_core_ctrl(WMT_CTRL_HOST_BAUDRATE_SET, &ctrlPa1, &ctrlPa2); + if (iRet) { + WMT_ERR_FUNC("change baudrate(%d) fail(%d)\n", pWmtHifConf->au4HifConf[0], + iRet); + return -3; + } + WMT_INFO_FUNC("WMT-CORE: change baudrate(%d) ok\n", pWmtHifConf->au4HifConf[0]); + + /* 7. Wake up chip and check event */ + /* iRet = (*kal_stp_tx_raw)(&WMT_SET_WAKEUP_WAKE_CMD_RAW[0], 1, &u4Res); */ + iRet = + wmt_core_tx((PUINT8)&WMT_SET_WAKEUP_WAKE_CMD_RAW[0], 1, &u4Res, + MTK_WCN_BOOL_TRUE); + if (iRet || (u4Res != 1)) { + WMT_ERR_FUNC("write raw iRet(%d) written(%d)\n", iRet, u4Res); + return -4; + } + + osal_memset(evtBuf, 0, osal_sizeof(evtBuf)); + iRet = wmt_core_rx(evtBuf, osal_sizeof(WMT_SET_WAKEUP_WAKE_EVT), &u4Res); +#ifdef CFG_DUMP_EVT + WMT_DBG_FUNC("WAKEUP_WAKE_EVT read len %d [%02x,%02x,%02x,%02x,%02x,%02x]\n", + (INT32) u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], + evtBuf[5]); +#endif + if (iRet || (u4Res != osal_sizeof(WMT_SET_WAKEUP_WAKE_EVT))) { + WMT_ERR_FUNC("read WAKEUP_WAKE_EVT fail(%d)\n", iRet); + return -5; + } + /* WMT_DBG_FUNC("WMT-CORE: read WMT_SET_WAKEUP_WAKE_EVT ok"); */ + +#if CFG_CHECK_WMT_RESULT + if (osal_memcmp + (evtBuf, WMT_SET_WAKEUP_WAKE_EVT, osal_sizeof(WMT_SET_WAKEUP_WAKE_EVT)) != 0) { + WMT_ERR_FUNC("WMT-CORE: write WMT_SET_WAKEUP_WAKE_CMD_RAW status fail\n"); + return -6; + } +#endif + + /* 8. Query baud rate (TEST-ONLY) */ + iRet = wmt_core_init_script(init_table_2, ARRAY_SIZE(init_table_2)); + if (iRet) { + WMT_ERR_FUNC("init_table_2 fail(%d)\n", iRet); + return -7; + } + } + + /* 9. download patch */ +#if CFG_WMT_MULTI_PATCH + /* 9.1 Let launcher to search patch info */ + iRet = mt6628_patch_info_prepare(); + if (iRet) { + WMT_ERR_FUNC("patch info perpare fail(%d)\n", iRet); + return -8; + } + + /* 9.2 Read patch number */ + ctrlPa1 = 0; + ctrlPa2 = 0; + wmt_core_ctrl(WMT_CTRL_GET_PATCH_NUM, &ctrlPa1, &ctrlPa2); + patch_num = ctrlPa1; + WMT_INFO_FUNC("patch total num = [%d]\n", patch_num); + + /* 9.3 Multi-patch Patch download */ + for (patch_index = 0; patch_index < patch_num; patch_index++) { + iRet = mt6628_patch_dwn(patch_index); + if (iRet) { + WMT_ERR_FUNC("patch dwn fail (%d),patch_index(%d)\n", iRet, patch_index); + return -12; + } + iRet = wmt_core_init_script(init_table_3, ARRAY_SIZE(init_table_3)); + if (iRet) { + WMT_ERR_FUNC("init_table_3 fail(%d)\n", iRet); + return -13; + } + } +#else + /* 9.3 Patch download */ + iRet = mt6628_patch_dwn(); + /* If patch download fail, we just ignore this error and let chip init process goes on */ + if (iRet) + WMT_ERR_FUNC("patch dwn fail (%d), just omit\n", iRet); +#endif /* End of #if CFG_WMT_MULTI_PATCH */ + + /* 10. WMT Reset command */ + iRet = wmt_core_init_script(init_table_3, ARRAY_SIZE(init_table_3)); + if (iRet) { + WMT_ERR_FUNC("init_table_3 fail(%d)\n", iRet); + return -9; + } + iRet = wmt_stp_init_coex(); + if (iRet) { + WMT_ERR_FUNC("init_coex fail(%d)\n", iRet); + return -10; + } + WMT_INFO_FUNC("init_coex ok\n"); + + mt6628_crystal_triming_set(); + + mt6628_set_sdio_driving(); + + if (pWmtHifConf->hifType == WMT_HIF_UART) { + /* 11. Set chip STP options */ + iRet = wmt_core_init_script(init_table_4, ARRAY_SIZE(init_table_4)); + if (iRet) { + WMT_ERR_FUNC("init_table_4 fail(%d)\n", iRet); + return -12; + } + + /* 12. Enable host STP-UART mode */ + ctrlPa1 = WMT_STP_CONF_MODE; + ctrlPa2 = MTKSTP_UART_FULL_MODE; + iRet = wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); + ctrlPa1 = WMT_STP_CONF_EN; + ctrlPa2 = 1; + iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); + if (iRet) { + WMT_ERR_FUNC("enable host STP-UART-FULL mode fail(%d)\n", iRet); + return -13; + } + WMT_INFO_FUNC("enable host STP-UART-FULL mode\n"); + /*13. wait for 10ms, enough for chip do mechanism switch.(at least 2ms is needed) */ + osal_sleep_ms(10); + /* 14. Query chip STP options (TEST-ONLY) */ + /* 15. Query baud rate (stp, TEST-ONLY) */ + iRet = wmt_core_init_script(init_table_5, ARRAY_SIZE(init_table_5)); + if (iRet) { + WMT_ERR_FUNC("init_table_5 fail(%d)\n", iRet); + return -14; + } + } + + if (mt6628_co_clock_get() == WMT_CO_CLOCK_EN) { + WMT_INFO_FUNC("co-clock enabled.\n"); + + iRet = wmt_core_init_script(osc_type_table, ARRAY_SIZE(osc_type_table)); + if (iRet) { + WMT_ERR_FUNC("osc_type_table fail(%d), goes on\n", iRet); + return -15; + } + } else { + WMT_INFO_FUNC("co-clock disabled.\n"); + } +#if (MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT) + iRet = wmt_core_init_script(merge_pcm_table, ARRAY_SIZE(merge_pcm_table)); + if (iRet) { + WMT_ERR_FUNC("merge_pcm_table fail(%d), goes on\n", iRet); + return -15; + } +#endif + + /* 15. Set FM strap */ + WMT_STRAP_CONF_CMD_FM_COMM[5] = (UINT8) pWmtHifConf->au4StrapConf[0]; + WMT_STRAP_CONF_EVT[5] = (UINT8) pWmtHifConf->au4StrapConf[0]; + iRet = wmt_core_init_script(init_table_5_1, ARRAY_SIZE(init_table_5_1)); + if (iRet) { + WMT_ERR_FUNC("init_table_5_1 fm mode(%d) fail(%d)\n", + pWmtHifConf->au4StrapConf[0], iRet); + return -16; + } + WMT_INFO_FUNC("set fm mode (%d) ok\n", pWmtHifConf->au4StrapConf[0]); + +#if CFG_SET_OPT_REG /*set registers */ + iRet = wmt_core_init_script(set_registers, ARRAY_SIZE(set_registers)); + if (iRet) { + WMT_ERR_FUNC("set_registers fail(%d)", iRet); + return -17; + } +#endif + +#if CFG_WMT_COREDUMP_ENABLE + /*Open Core Dump Function @QC begin */ + mtk_wcn_stp_coredump_flag_ctrl(1); +#endif + if (mtk_wcn_stp_coredump_flag_get() != 0) { + iRet = wmt_core_init_script(init_table_6, ARRAY_SIZE(init_table_6)); + if (iRet) { + WMT_ERR_FUNC("init_table_6 core dump setting fail(%d)\n", iRet); + return -18; + } + WMT_INFO_FUNC("enable mt662x firmware coredump\n"); + } else + WMT_INFO_FUNC("disable mt662x firmware coredump. hifType: %d\n", + pWmtHifConf->hifType); + +#if 1 + ctrlData.ctrlId = WMT_CTRL_SET_STP_DBG_INFO; + ctrlData.au4CtrlData[0] = wmt_ic_ops_mt6628.icId; + ctrlData.au4CtrlData[1] = (size_t) gp_mt6628_info->cChipVersion; + ctrlData.au4CtrlData[2] = (size_t) &gp_mt6628_patch_info; + iRet = wmt_ctrl(&ctrlData); + if (iRet) { + WMT_ERR_FUNC("set dump info fail(%d)\n", iRet); + return -16; + } +#endif + +#if CFG_WMT_PS_SUPPORT + if (pWmtHifConf->hifType == WMT_HIF_UART) { + osal_assert(gp_mt6628_info != NULL); + if (gp_mt6628_info != NULL) { + if (gp_mt6628_info->bPsmSupport != MTK_WCN_BOOL_FALSE) + wmt_lib_ps_enable(); + else + wmt_lib_ps_disable(); + } + } else if (pWmtHifConf->hifType == WMT_HIF_SDIO) { + /* COMMON SDIO is used different PS from UART, so disable current ps support + * Note: using wmt_lib_ps_ctrl() due to wmt_lib_ps_disable() cannot clear gPsEnable setting + */ + wmt_lib_ps_ctrl(0); + } +#endif + + return 0; +} + +static INT32 mt6628_sw_deinit(P_WMT_HIF_CONF pWmtHifConf) +{ + WMT_DBG_FUNC(" start\n"); + +#if CFG_WMT_PS_SUPPORT + if (pWmtHifConf->hifType == WMT_HIF_UART) { + osal_assert(gp_mt6628_info != NULL); + if ((gp_mt6628_info != NULL) + && (gp_mt6628_info->bPsmSupport != MTK_WCN_BOOL_FALSE)) { + wmt_lib_ps_disable(); + } + } +#endif + + gp_mt6628_info = NULL; + + return 0; +} + +static INT32 mt6628_aif_ctrl(WMT_IC_PIN_STATE state, UINT32 flag) +{ + INT32 ret = -1; + UINT32 val; + + if ((flag & WMT_LIB_AIF_FLAG_MASK) == WMT_LIB_AIF_FLAG_SHARE) { + WMT_INFO_FUNC("PCM & I2S PIN SHARE\n"); +#if 0 + switch (state) { + case WMT_IC_AIF_0: + /* BT_PCM_OFF & FM line in/out */ + val = 0x00000770; + ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); + val = 0x00000000; + ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); + break; + + case WMT_IC_AIF_1: + /* BT_PCM_ON & FM line in/out */ + val = 0x00000700; + ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); + val = 0x00000000; + ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); + break; + + case WMT_IC_AIF_2: + /* BT_PCM_OFF & FM I2S */ + val = 0x00000710; + ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); + val = 0x00000800; /* 800:3-wire, 000: 4-wire */ + ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); + break; + default: + WMT_ERR_FUNC("unsupported state (%d)\n", state); + ret = -1; + break; + } +#else + WMT_WARN_FUNC("TBD!!"); + ret = 0; +#endif + } else { + /*PCM & I2S separate */ + WMT_INFO_FUNC("PCM & I2S PIN SEPARATE\n"); +#if 0 + switch (state) { + case WMT_IC_AIF_0: + /* BT_PCM_OFF & FM line in/out */ + val = 0x00000770; + ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); + val = 0x00000000; + ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); + break; + + case WMT_IC_AIF_1: + /* BT_PCM_ON & FM line in/out */ + val = 0x00000700; + ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); + val = 0x00000000; + ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); + break; + + case WMT_IC_AIF_2: + /* BT_PCM_OFF & FM I2S */ + val = 0x00000070; + ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); + val = 0x00000800; /* 800:3-wire, 000: 4-wire */ + ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); + + break; + case WMT_IC_AIF_3: + val = 0x00000000; + ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); + val = 0x00000800; /* 800:3-wire, 000: 4-wire */ + ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); + + break; + default: + WMT_ERR_FUNC("unsupported state (%d)\n", state); + ret = -1; + break; + } +#else + switch (state) { + case WMT_IC_AIF_0: + /* BT_PCM_OFF & FM line in/out */ + ret = 0; + break; + case WMT_IC_AIF_1: + /* BT_PCM_ON & FM line in/out */ + ret = 0; + break; + + case WMT_IC_AIF_2: + /* BT_PCM_OFF & FM I2S */ + val = 0x01110000; + ret = wmt_core_reg_rw_raw(1, 0x80050078, &val, 0x0FFF0000); + + break; + case WMT_IC_AIF_3: + ret = 0; + break; + + default: + WMT_ERR_FUNC("unsupported state (%d)\n", state); + ret = -1; + break; + } +#endif + } + + if (!ret) + WMT_INFO_FUNC("new state(%d) ok\n", state); + else + WMT_WARN_FUNC("new state(%d) fail(%d)\n", state, ret); + + return ret; +} + +static INT32 mt6628_gps_sync_ctrl(WMT_IC_PIN_STATE state, UINT32 flag) +{ + INT32 ret = -1; + UINT32 uVal = 0; + + if (state == WMT_IC_PIN_MUX) + uVal = 0x1 << 28; + else + uVal = 0x5 << 28; + ret = wmt_core_reg_rw_raw(1, 0x80050078, &uVal, 0x7 << 28); + if (ret != 0) + WMT_ERR_FUNC("gps_sync pin ctrl failed, ret(%d)\n", ret); + /* anyway, we return 0 */ + return 0; +} + + +static INT32 mt6628_pin_ctrl(WMT_IC_PIN_ID id, WMT_IC_PIN_STATE state, UINT32 flag) +{ + INT32 ret; + + WMT_DBG_FUNC("ic pin id:%d, state:%d, flag:0x%x\n", id, state, flag); + + ret = -1; + switch (id) { + case WMT_IC_PIN_AUDIO: + ret = mt6628_aif_ctrl(state, flag); + break; + + case WMT_IC_PIN_EEDI: + WMT_WARN_FUNC("TBD!!"); + /* We just return 0 here, prevent from WMT-FUNC do other register read/write */ + ret = 0; + break; + + case WMT_IC_PIN_EEDO: + WMT_WARN_FUNC("TBD!!"); + /* We just return 0 here, prevent from WMT-FUNC do other register read/write */ + ret = 0; + break; + case WMT_IC_PIN_GSYNC: + ret = mt6628_gps_sync_ctrl(state, flag); + break; + default: + break; + } + WMT_INFO_FUNC("ret = (%d)\n", ret); + + return ret; +} + +INT32 mt6628_co_clock_ctrl(WMT_CO_CLOCK on) +{ + INT32 iRet = 0; + + if ((on >= WMT_CO_CLOCK_DIS) && (on < WMT_CO_CLOCK_MAX)) + gCoClockEn = on; + else { + WMT_DBG_FUNC("MT6628: error parameter:%d\n", on); + iRet = -1; + } + WMT_DBG_FUNC("MT6628: Co-clock %s\n", + (gCoClockEn == WMT_CO_CLOCK_DIS) ? "disabled" : "enabled"); + + return iRet; +} + +static MTK_WCN_BOOL mt6628_quick_sleep_flag_get(VOID) +{ + return MTK_WCN_BOOL_TRUE; +} + + +static MTK_WCN_BOOL mt6628_aee_dump_flag_get(VOID) +{ + return MTK_WCN_BOOL_TRUE; +} + + +WMT_CO_CLOCK mt6628_co_clock_get(VOID) +{ + return gCoClockEn; +} + + + +static INT32 mt6628_ver_check(VOID) +{ + UINT32 hw_ver = 0; + UINT32 fw_ver = 0; + INT32 iret; + const WMT_IC_INFO_S *p_info = NULL; + unsigned long ctrlPa1; + unsigned long ctrlPa2; + + /* 1. identify chip versions: HVR(HW_VER) and FVR(FW_VER) */ + WMT_LOUD_FUNC("MT6628: before read hw_ver (hw version)\n"); + iret = wmt_core_reg_rw_raw(0, GEN_HVR, &hw_ver, GEN_VER_MASK); + if (iret) { + WMT_ERR_FUNC("MT6628: read hw_ver fail:%d\n", iret); + return -2; + } + WMT_INFO_FUNC("MT6628: read hw_ver (hw version) (0x%x)\n", hw_ver); + + WMT_LOUD_FUNC("MT6628: before fw_ver (rom version)\n"); + wmt_core_reg_rw_raw(0, GEN_FVR, &fw_ver, GEN_VER_MASK); + if (iret) { + WMT_ERR_FUNC("MT6628: read fw_ver fail:%d\n", iret); + return -2; + } + WMT_INFO_FUNC("MT6628: read fw_ver (rom version) (0x%x)\n", fw_ver); + + p_info = mt6628_find_wmt_ic_info(hw_ver); + if (p_info == NULL) { + WMT_ERR_FUNC("MT6628: hw_ver(0x%x) find wmt ic info fail\n", hw_ver); + return -3; + } + + WMT_INFO_FUNC("MT6628: wmt ic info: %s.%s (0x%x, patch_ext:%s)\n", + p_info->cChipName, p_info->cChipVersion, + p_info->u4HwVer, p_info->cPatchNameExt); + + /* hw id & version */ + ctrlPa1 = (0x00006628UL << 16) | (hw_ver & 0x0000FFFF); + /* translated fw rom version */ + ctrlPa2 = (fw_ver & 0x0000FFFF); + + iret = wmt_core_ctrl(WMT_CTRL_HWIDVER_SET, &ctrlPa1, &ctrlPa2); + if (iret) + WMT_WARN_FUNC("MT6628: WMT_CTRL_HWIDVER_SET fail(%d)\n", iret); + + gp_mt6628_info = p_info; + return 0; +} + +static const WMT_IC_INFO_S *mt6628_find_wmt_ic_info(const UINT32 hw_ver) +{ + /* match chipversion with u4HwVer item in mt6628_info_table */ + const UINT32 size = ARRAY_SIZE(mt6628_info_table); + INT32 index; + + /* George: reverse the search order to favor newer version products */ + /* TODO:[FixMe][GeorgeKuo] Remove full match once API wmt_lib_get_hwver() + * is changed correctly in the future!! + * Leave full match here is a workaround for GPS to distinguish E3/E4 ICs. + */ + index = size - 1; + /* full match */ + while ((index >= 0) + && (hw_ver != mt6628_info_table[index].u4HwVer) /* full match */ + ) { + --index; + } + if (index >= 0) { + WMT_INFO_FUNC("found ic info(0x%x) by full match! index:%d\n", hw_ver, index); + return &mt6628_info_table[index]; + } + + WMT_WARN_FUNC("find no ic info for (0x%x) by full match!try major num match!\n", hw_ver); + + /* George: The ONLY CORRECT method to find supported hw table. Match MAJOR + * NUM only can help us support future minor hw ECO, or fab switch, etc. + * FULL matching eliminate such flexibility and software package have to be + * updated EACH TIME even when minor hw ECO or fab switch!!! + */ + /* George: reverse the search order to favor newer version products */ + index = size - 1; + /* major num match */ + while ((index >= 0) + && (MAJORNUM(hw_ver) != MAJORNUM(mt6628_info_table[index].u4HwVer)) + ) { + --index; + } + if (index >= 0) { + WMT_INFO_FUNC("MT6628: found ic info for hw_ver(0x%x) by major num! index:%d\n", + hw_ver, index); + return &mt6628_info_table[index]; + } + + WMT_ERR_FUNC + ("MT6628: find no ic info for hw_ver(0x%x) by full match nor major num match!\n", + hw_ver); + return NULL; +} + + +static INT32 wmt_stp_init_coex(VOID) +{ + INT32 iRet; + ULONG addr = 0; + WMT_GEN_CONF *pWmtGenConf = NULL; + +#define COEX_WMT 0 + +#if CFG_SUBSYS_COEX_NEED + /* no need for MT6628 */ +#define COEX_BT 1 +#define COEX_WIFI 2 +#define COEX_PTA 3 +#define COEX_MISC 4 +#endif + /*Get wmt config */ + iRet = wmt_core_ctrl(WMT_CTRL_GET_WMT_CONF, &addr, 0); + if (iRet) { + WMT_ERR_FUNC("ctrl GET_WMT_CONF fail(%d)\n", iRet); + return -2; + } + WMT_INFO_FUNC("ctrl GET_WMT_CONF ok(0x%08lx\n", addr); + + pWmtGenConf = (P_WMT_GEN_CONF) addr; + + /*Check if WMT.cfg exists */ + if (pWmtGenConf->cfgExist == 0) { + WMT_INFO_FUNC("cfgExist == 0, skip config chip\n"); + /*if WMT.cfg not existed, still return success and adopt the default value */ + return 0; + } + + + /*Dump the coex-related info */ + WMT_DBG_FUNC("coex_wmt:0x%x\n", pWmtGenConf->coex_wmt_ant_mode); +#if CFG_SUBSYS_COEX_NEED + WMT_DBG_FUNC("coex_bt:0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", + pWmtGenConf->coex_bt_rssi_upper_limit, + pWmtGenConf->coex_bt_rssi_mid_limit, + pWmtGenConf->coex_bt_rssi_lower_limit, + pWmtGenConf->coex_bt_pwr_high, + pWmtGenConf->coex_bt_pwr_mid, pWmtGenConf->coex_bt_pwr_low); + WMT_DBG_FUNC("coex_wifi:0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", + pWmtGenConf->coex_wifi_rssi_upper_limit, + pWmtGenConf->coex_wifi_rssi_mid_limit, + pWmtGenConf->coex_wifi_rssi_lower_limit, + pWmtGenConf->coex_wifi_pwr_high, + pWmtGenConf->coex_wifi_pwr_mid, pWmtGenConf->coex_wifi_pwr_low); + WMT_DBG_FUNC("coex_ext_pta:0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", + pWmtGenConf->coex_ext_pta_hi_tx_tag, + pWmtGenConf->coex_ext_pta_hi_rx_tag, + pWmtGenConf->coex_ext_pta_lo_tx_tag, + pWmtGenConf->coex_ext_pta_lo_rx_tag, + pWmtGenConf->coex_ext_pta_sample_t1, + pWmtGenConf->coex_ext_pta_sample_t2, + pWmtGenConf->coex_ext_pta_wifi_bt_con_trx); + WMT_DBG_FUNC("coex_misc:0x%x 0x%x 0x%x\n", + pWmtGenConf->coex_misc_ext_pta_on, pWmtGenConf->coex_misc_ext_feature_set); +#endif + + /*command adjustion due to WMT.cfg */ + coex_table[COEX_WMT].cmd[5] = pWmtGenConf->coex_wmt_ant_mode; + if (gWmtDbgLvl >= WMT_LOG_DBG) { + wmt_core_dump_data(&coex_table[COEX_WMT].cmd[0], + coex_table[COEX_WMT].str, coex_table[COEX_WMT].cmdSz); + } +#if CFG_SUBSYS_COEX_NEED + coex_table[COEX_BT].cmd[9] = pWmtGenConf->coex_bt_rssi_upper_limit; + coex_table[COEX_BT].cmd[10] = pWmtGenConf->coex_bt_rssi_mid_limit; + coex_table[COEX_BT].cmd[11] = pWmtGenConf->coex_bt_rssi_lower_limit; + coex_table[COEX_BT].cmd[12] = pWmtGenConf->coex_bt_pwr_high; + coex_table[COEX_BT].cmd[13] = pWmtGenConf->coex_bt_pwr_mid; + coex_table[COEX_BT].cmd[14] = pWmtGenConf->coex_bt_pwr_low; + if (gWmtDbgLvl >= WMT_LOG_DBG) { + wmt_core_dump_data(&coex_table[COEX_BT].cmd[0], + coex_table[COEX_BT].str, coex_table[COEX_BT].cmdSz); + } + coex_table[COEX_WIFI].cmd[10] = pWmtGenConf->coex_wifi_rssi_upper_limit; + coex_table[COEX_WIFI].cmd[11] = pWmtGenConf->coex_wifi_rssi_mid_limit; + coex_table[COEX_WIFI].cmd[12] = pWmtGenConf->coex_wifi_rssi_lower_limit; + coex_table[COEX_WIFI].cmd[13] = pWmtGenConf->coex_wifi_pwr_high; + coex_table[COEX_WIFI].cmd[14] = pWmtGenConf->coex_wifi_pwr_mid; + coex_table[COEX_WIFI].cmd[15] = pWmtGenConf->coex_wifi_pwr_low; + if (gWmtDbgLvl >= WMT_LOG_DBG) { + wmt_core_dump_data(&coex_table[COEX_WIFI].cmd[0], + coex_table[COEX_WIFI].str, coex_table[COEX_WIFI].cmdSz); + } + coex_table[COEX_PTA].cmd[5] = pWmtGenConf->coex_ext_pta_hi_tx_tag; + coex_table[COEX_PTA].cmd[6] = pWmtGenConf->coex_ext_pta_hi_rx_tag; + coex_table[COEX_PTA].cmd[7] = pWmtGenConf->coex_ext_pta_lo_tx_tag; + coex_table[COEX_PTA].cmd[8] = pWmtGenConf->coex_ext_pta_lo_rx_tag; + coex_table[COEX_PTA].cmd[9] = ((pWmtGenConf->coex_ext_pta_sample_t1 & 0xff00) >> 8); + coex_table[COEX_PTA].cmd[10] = ((pWmtGenConf->coex_ext_pta_sample_t1 & 0x00ff) >> 0); + coex_table[COEX_PTA].cmd[11] = ((pWmtGenConf->coex_ext_pta_sample_t2 & 0xff00) >> 8); + coex_table[COEX_PTA].cmd[12] = ((pWmtGenConf->coex_ext_pta_sample_t2 & 0x00ff) >> 0); + coex_table[COEX_PTA].cmd[13] = pWmtGenConf->coex_ext_pta_wifi_bt_con_trx; + if (gWmtDbgLvl >= WMT_LOG_DBG) { + wmt_core_dump_data(&coex_table[COEX_PTA].cmd[0], + coex_table[COEX_PTA].str, coex_table[COEX_PTA].cmdSz); + } + + osal_memcpy(&coex_table[COEX_MISC].cmd[5], &pWmtGenConf->coex_misc_ext_pta_on, + sizeof(pWmtGenConf->coex_misc_ext_pta_on)); + osal_memcpy(&coex_table[COEX_MISC].cmd[9], &pWmtGenConf->coex_misc_ext_feature_set, + sizeof(pWmtGenConf->coex_misc_ext_feature_set)); + + wmt_core_dump_data(&coex_table[COEX_MISC].cmd[0], coex_table[COEX_MISC].str, + coex_table[COEX_MISC].cmdSz); +#endif + + iRet = wmt_core_init_script(coex_table, ARRAY_SIZE(coex_table)); + + return iRet; +} + + +static INT32 mt6628_set_sdio_driving(VOID) +{ + INT32 ret = 0; + + ULONG addr = 0; + WMT_GEN_CONF *pWmtGenConf = NULL; + UINT32 drv_val = 0; + + /*Get wmt config */ + ret = wmt_core_ctrl(WMT_CTRL_GET_WMT_CONF, &addr, 0); + if (ret) { + WMT_ERR_FUNC("ctrl GET_WMT_CONF fail(%d)\n", ret); + return -1; + } + WMT_INFO_FUNC("ctrl GET_WMT_CONF ok(0x%8lx)\n", addr); + + pWmtGenConf = (P_WMT_GEN_CONF) addr; + + /*Check if WMT.cfg exists */ + if (pWmtGenConf->cfgExist == 0) { + WMT_INFO_FUNC("cfgExist == 0, skip config chip\n"); + /*if WMT.cfg not existed, still return success and adopt the default value */ + return 0; + } + + drv_val = pWmtGenConf->sdio_driving_cfg; + + /*Dump the sdio driving related info */ + WMT_INFO_FUNC("sdio driving:0x%x\n", drv_val); + + sdio_driving_table[0].cmd[12] = (UINT8) ((drv_val & 0x00000077UL) >> 0); /* DAT0 and DAT1 */ + sdio_driving_table[0].cmd[13] = (UINT8) ((drv_val & 0x00007700UL) >> 8); /* DAT2 and DAT3 */ + sdio_driving_table[0].cmd[14] = (UINT8) ((drv_val & 0x00070000UL) >> 16); /* CMD */ + + ret = wmt_core_init_script(sdio_driving_table, ARRAY_SIZE(sdio_driving_table)); + + return ret; +} + + +static INT32 mt6628_crystal_triming_set(VOID) +{ + INT32 iRet = 0; + PUINT8 pbuf = NULL; + UINT32 bufLen = 0; + WMT_CTRL_DATA ctrlData; + UINT32 uCryTimOffset = 0x6D; + MTK_WCN_BOOL bIsNvramExist = MTK_WCN_BOOL_FALSE; + INT8 cCrystalTimingOffset = 0x0; + UINT8 cCrystalTiming = 0x0; + INT32 iCrystalTiming = 0x0; + MTK_WCN_BOOL bIsCrysTrimEnabled = MTK_WCN_BOOL_FALSE; + UINT32 u4Res; + + bIsNvramExist = MTK_WCN_BOOL_FALSE; + ctrlData.ctrlId = WMT_CTRL_CRYSTAL_TRIMING_GET; + ctrlData.au4CtrlData[0] = (size_t) "/data/nvram/APCFG/APRDEB/WIFI"; + ctrlData.au4CtrlData[1] = (size_t) &pbuf; + ctrlData.au4CtrlData[2] = (size_t) &bufLen; + + iRet = wmt_ctrl(&ctrlData); + if (iRet != 0) { + WMT_ERR_FUNC("MT6628: WMT_CTRL_CRYSTAL_TRIMING_GET fail:%d\n", iRet); + bIsNvramExist = MTK_WCN_BOOL_FALSE; + bIsCrysTrimEnabled = MTK_WCN_BOOL_FALSE; + cCrystalTimingOffset = 0x0; + cCrystalTiming = 0x0; + iRet = -1; + } else { + WMT_DBG_FUNC("MT6628: nvram pBuf(%p), bufLen(%d)\n", pbuf, bufLen); + if (bufLen < (uCryTimOffset + 1)) { + WMT_ERR_FUNC + ("MT6628: nvram len(%d) too short, crystalTimging value offset(%d)\n", + bufLen, uCryTimOffset); + bIsNvramExist = MTK_WCN_BOOL_FALSE; + bIsCrysTrimEnabled = MTK_WCN_BOOL_FALSE; + cCrystalTimingOffset = 0x0; + cCrystalTiming = 0x0; + } else { + bIsNvramExist = MTK_WCN_BOOL_TRUE; + cCrystalTimingOffset = *(pbuf + uCryTimOffset); + if (cCrystalTimingOffset & 0x80) { + bIsCrysTrimEnabled = MTK_WCN_BOOL_TRUE; + cCrystalTimingOffset = (UINT8) cCrystalTimingOffset & 0x7f; + } + WMT_DBG_FUNC("cCrystalTimingOffset (%d), bIsCrysTrimEnabled(%d)\n", + cCrystalTimingOffset, bIsCrysTrimEnabled); + } + ctrlData.ctrlId = WMT_CTRL_CRYSTAL_TRIMING_PUT; + ctrlData.au4CtrlData[0] = (size_t) "/data/nvram/APCFG/APRDEB/WIFI"; + iRet = wmt_ctrl(&ctrlData); + if (iRet != 0) { + WMT_ERR_FUNC("MT6628: WMT_CTRL_CRYSTAL_TRIMING_PUT fail:%d\n", iRet); + iRet = -2; + } else { + WMT_DBG_FUNC("MT6628: WMT_CTRL_CRYSTAL_TRIMING_PUT succeed\n"); + } + } + if ((bIsNvramExist == MTK_WCN_BOOL_TRUE) && (bIsCrysTrimEnabled == MTK_WCN_BOOL_TRUE)) { + /*get CrystalTiming value before set it */ + iRet = + wmt_core_tx(get_crystal_timing_script[0].cmd, + get_crystal_timing_script[0].cmdSz, &u4Res, MTK_WCN_BOOL_FALSE); + if (iRet || (u4Res != get_crystal_timing_script[0].cmdSz)) { + WMT_ERR_FUNC("WMT-CORE: write (%s) iRet(%d) cmd len err(%d, %d)\n", + get_crystal_timing_script[0].str, iRet, u4Res, + get_crystal_timing_script[0].cmdSz); + iRet = -3; + goto done; + } + /* EVENT BUF */ + osal_memset(get_crystal_timing_script[0].evt, 0, + get_crystal_timing_script[0].evtSz); + iRet = + wmt_core_rx(get_crystal_timing_script[0].evt, + get_crystal_timing_script[0].evtSz, &u4Res); + if (iRet || (u4Res != get_crystal_timing_script[0].evtSz)) { + WMT_ERR_FUNC("WMT-CORE: read (%s) iRet(%d) evt len err(rx:%d, exp:%d)\n", + get_crystal_timing_script[0].str, iRet, u4Res, + get_crystal_timing_script[0].evtSz); + mtk_wcn_stp_dbg_dump_package(); + iRet = -4; + goto done; + } + + iCrystalTiming = WMT_GET_CRYSTAL_TRIMING_EVT[5] & 0x7f; + if (cCrystalTimingOffset & 0x40) { + /*nagative offset value */ + iCrystalTiming = iCrystalTiming + cCrystalTimingOffset - 128; + } else { + iCrystalTiming += cCrystalTimingOffset; + } + WMT_DBG_FUNC("iCrystalTiming (0x%x)\n", iCrystalTiming); + if (iCrystalTiming > 0x7f) + cCrystalTiming = 0x7f; + else if (iCrystalTiming < 0) + cCrystalTiming = 0; + else + cCrystalTiming = iCrystalTiming; + WMT_DBG_FUNC("cCrystalTiming (0x%x)\n", cCrystalTiming); + /* set_crystal_timing_script */ + WMT_SET_CRYSTAL_TRIMING_CMD[5] = cCrystalTiming; + WMT_GET_CRYSTAL_TRIMING_EVT[5] = cCrystalTiming; + + iRet = + wmt_core_init_script(set_crystal_timing_script, + osal_array_size(set_crystal_timing_script)); + if (iRet) { + WMT_ERR_FUNC("set_crystal_timing_script fail(%d)\n", iRet); + iRet = -5; + } else { + WMT_DBG_FUNC("set crystal timing value (0x%x) succeed\n", + WMT_SET_CRYSTAL_TRIMING_CMD[5]); + iRet = + wmt_core_init_script(get_crystal_timing_script, + osal_array_size(get_crystal_timing_script)); + if (iRet) { + WMT_ERR_FUNC("get_crystal_timing_script fail(%d)\n", iRet); + iRet = -6; + } else { + WMT_INFO_FUNC("succeed, updated crystal timing value (0x%x)\n", + WMT_GET_CRYSTAL_TRIMING_EVT[5]); + iRet = 0x0; + } + } + } +done: + return iRet; +} + + +#if CFG_WMT_MULTI_PATCH +static INT32 mt6628_patch_info_prepare(VOID) +{ + INT32 iRet = -1; + WMT_CTRL_DATA ctrlData; + + ctrlData.ctrlId = WMT_CTRL_PATCH_SEARCH; + iRet = wmt_ctrl(&ctrlData); + + return iRet; +} + + +static INT32 mt6628_patch_dwn(UINT32 index) +{ + INT32 iRet = -1; + P_WMT_PATCH patchHdr; + PUINT8 pbuf; + UINT32 patchSize; + UINT32 fragSeq; + UINT32 fragNum; + UINT16 fragSize = 0; + UINT16 cmdLen; + UINT32 offset; + UINT32 u4Res; + UINT8 evtBuf[8]; + UINT8 addressevtBuf[12]; + UINT8 addressByte[4]; + PINT8 cDataTime = NULL; + /*PINT8 cPlat = NULL; */ + UINT16 u2HwVer = 0; + UINT16 u2SwVer = 0; + UINT32 u4PatchVer = 0; + UINT32 patchSizePerFrag = 0; + WMT_CTRL_DATA ctrlData; + + /*1.check hardware information */ + if (gp_mt6628_info == NULL) { + WMT_ERR_FUNC("null gp_mt6628_info!\n"); + return -1; + } + + osal_memset(gFullPatchName, 0, osal_sizeof(gFullPatchName)); + + ctrlData.ctrlId = WMT_CTRL_GET_PATCH_INFO; + ctrlData.au4CtrlData[0] = index + 1; + ctrlData.au4CtrlData[1] = (size_t) &gFullPatchName; + ctrlData.au4CtrlData[2] = (size_t) &addressByte; + iRet = wmt_ctrl(&ctrlData); + WMT_INFO_FUNC("the %d time valid patch found: (%s)\n", index + 1, gFullPatchName); + + /* <2.2> read patch content */ + ctrlData.ctrlId = WMT_CTRL_GET_PATCH; + ctrlData.au4CtrlData[0] = (size_t) NULL; + ctrlData.au4CtrlData[1] = (size_t) &gFullPatchName; + ctrlData.au4CtrlData[2] = (size_t) &pbuf; + ctrlData.au4CtrlData[3] = (size_t) &patchSize; + iRet = wmt_ctrl(&ctrlData); + if (iRet) { + WMT_ERR_FUNC("wmt_core: WMT_CTRL_GET_PATCH fail:%d\n", iRet); + iRet -= 1; + goto done; + } + + /* |<-BCNT_PATCH_BUF_HEADROOM(8) bytes dummy allocated->|<-patch file->| */ + pbuf += BCNT_PATCH_BUF_HEADROOM; + /* patch file with header: + * |<-patch header: 28 Bytes->|<-patch body: X Bytes ----->| + */ + patchHdr = (P_WMT_PATCH) pbuf; + /* check patch file information */ + + cDataTime = patchHdr->ucDateTime; + u2HwVer = patchHdr->u2HwVer; + u2SwVer = patchHdr->u2SwVer; + u4PatchVer = patchHdr->u4PatchVer; + /*cPlat = &patchHdr->ucPLat[0]; */ + + cDataTime[15] = '\0'; + if (index == 0) { + WMT_INFO_FUNC("===========================================\n"); + WMT_INFO_FUNC("[Combo Patch] Built Time = %s\n", cDataTime); + WMT_INFO_FUNC("[Combo Patch] Hw Ver = 0x%x\n", + ((u2HwVer & 0x00ff) << 8) | ((u2HwVer & 0xff00) >> 8)); + WMT_INFO_FUNC("[Combo Patch] Sw Ver = 0x%x\n", + ((u2SwVer & 0x00ff) << 8) | ((u2SwVer & 0xff00) >> 8)); + WMT_INFO_FUNC("[Combo Patch] Ph Ver = 0x%04x\n", + ((u4PatchVer & 0xff000000) >> 24) | ((u4PatchVer & 0x00ff0000) >> + 16)); + WMT_INFO_FUNC("[Combo Patch] Platform = %c%c%c%c\n", patchHdr->ucPLat[0], + patchHdr->ucPLat[1], patchHdr->ucPLat[2], patchHdr->ucPLat[3]); + WMT_INFO_FUNC("===========================================\n"); + } + + /* remove patch header: + * |<-patch body: X Bytes (X=patchSize)--->| + */ + if (patchSize < sizeof(WMT_PATCH)) { + WMT_ERR_FUNC("error patch size\n"); + iRet = -1; + goto done; + } + patchSize -= sizeof(WMT_PATCH); + pbuf += sizeof(WMT_PATCH); + patchSizePerFrag = DEFAULT_PATCH_FRAG_SIZE; + /* reserve 1st patch cmd space before patch body + * |<-WMT_CMD: 5Bytes->|<-patch body: X Bytes (X=patchSize)----->| + */ + osal_memcpy(&gp_mt6628_patch_info, patchHdr, osal_sizeof(WMT_PATCH)); + pbuf -= sizeof(WMT_PATCH_CMD); + + fragNum = patchSize / patchSizePerFrag; + fragNum += ((fragNum * patchSizePerFrag) == patchSize) ? 0 : 1; + + WMT_DBG_FUNC("patch size(%d) fragNum(%d)\n", patchSize, fragNum); + + + /*send wmt part patch address command */ + iRet = + wmt_core_tx((PUINT8) &WMT_PATCH_ADDRESS_CMD[0], sizeof(WMT_PATCH_ADDRESS_CMD), &u4Res, + MTK_WCN_BOOL_FALSE); + if (iRet || (u4Res != sizeof(WMT_PATCH_ADDRESS_CMD))) { + WMT_ERR_FUNC("wmt_core:wmt patch address CMD fail(%d),size(%d)\n", iRet, u4Res); + iRet -= 1; + goto done; + } + osal_memset(addressevtBuf, 0, sizeof(addressevtBuf)); + iRet = wmt_core_rx(addressevtBuf, sizeof(WMT_PATCH_ADDRESS_EVT), &u4Res); + if (iRet || (u4Res != sizeof(WMT_PATCH_ADDRESS_EVT))) { + WMT_ERR_FUNC("wmt_core:wmt patch address EVT fail(%d),size(%d)\n", iRet, u4Res); + iRet -= 1; + goto done; + } +#if CFG_CHECK_WMT_RESULT + if (osal_memcmp(addressevtBuf, WMT_PATCH_ADDRESS_EVT, osal_sizeof(WMT_PATCH_ADDRESS_EVT)) != + 0) { + WMT_ERR_FUNC("wmt_core: write WMT_PATCH_ADDRESS_CMD status fail\n"); + iRet -= 1; + goto done; + } +#endif + + /*send part patch address command */ + osal_memcpy(&WMT_PATCH_P_ADDRESS_CMD[12], addressByte, osal_sizeof(addressByte)); + WMT_INFO_FUNC("4 bytes address command:0x%02x,0x%02x,0x%02x,0x%02x", + WMT_PATCH_P_ADDRESS_CMD[12], + WMT_PATCH_P_ADDRESS_CMD[13], + WMT_PATCH_P_ADDRESS_CMD[14], WMT_PATCH_P_ADDRESS_CMD[15]); + iRet = + wmt_core_tx((PUINT8) &WMT_PATCH_P_ADDRESS_CMD[0], sizeof(WMT_PATCH_P_ADDRESS_CMD), + &u4Res, MTK_WCN_BOOL_FALSE); + if (iRet || (u4Res != sizeof(WMT_PATCH_P_ADDRESS_CMD))) { + WMT_ERR_FUNC("wmt_core:wmt part patch address CMD fail(%d),size(%d),index(%d)\n", + iRet, u4Res, index); + iRet -= 1; + goto done; + } + osal_memset(addressevtBuf, 0, sizeof(addressevtBuf)); + iRet = wmt_core_rx(addressevtBuf, sizeof(WMT_PATCH_P_ADDRESS_EVT), &u4Res); + if (iRet || (u4Res != sizeof(WMT_PATCH_P_ADDRESS_EVT))) { + WMT_ERR_FUNC("wmt_core:wmt patch address EVT fail(%d),size(%d),index(%d)\n", iRet, + u4Res, index); + iRet -= 1; + goto done; + } +#if CFG_CHECK_WMT_RESULT + if (osal_memcmp(addressevtBuf, WMT_PATCH_P_ADDRESS_EVT, osal_sizeof(WMT_PATCH_ADDRESS_EVT)) + != 0) { + WMT_ERR_FUNC("wmt_core: write WMT_PATCH_ADDRESS_CMD status fail,index(%d)\n", + index); + iRet -= 1; + goto done; + } +#endif + + /* send all fragments */ + offset = sizeof(WMT_PATCH_CMD); + fragSeq = 0; + while (fragSeq < fragNum) { + WMT_DBG_FUNC("patch size(%d) fragNum(%d)\n", patchSize, fragNum); + if (fragSeq == (fragNum - 1)) { + /* last fragment */ + fragSize = patchSize - fragSeq * patchSizePerFrag; + WMT_PATCH_CMD[4] = WMT_PATCH_FRAG_LAST; + } else { + fragSize = patchSizePerFrag; + WMT_PATCH_CMD[4] = (fragSeq == 0) ? WMT_PATCH_FRAG_1ST : WMT_PATCH_FRAG_MID; + } + /* update length field in CMD:flag+frag */ + cmdLen = 1 + fragSize; + osal_memcpy(&WMT_PATCH_CMD[2], &cmdLen, 2); + /* copy patch CMD to buf (overwrite last 5-byte in prev frag) */ + osal_memcpy(pbuf + offset - sizeof(WMT_PATCH_CMD), WMT_PATCH_CMD, + sizeof(WMT_PATCH_CMD)); + /* iRet = (*kal_stp_tx)(pbuf + offset - sizeof(WMT_PATCH_CMD), + * fragSize + sizeof(WMT_PATCH_CMD), &u4Res); + */ + iRet = + wmt_core_tx(pbuf + offset - sizeof(WMT_PATCH_CMD), + fragSize + sizeof(WMT_PATCH_CMD), &u4Res, MTK_WCN_BOOL_FALSE); + if (iRet || (u4Res != fragSize + sizeof(WMT_PATCH_CMD))) { + WMT_ERR_FUNC("wmt_core: write fragSeq(%d) size(%zu, %d) fail(%d)\n", fragSeq, + fragSize + sizeof(WMT_PATCH_CMD), u4Res, iRet); + iRet -= 1; + break; + } + WMT_DBG_FUNC("wmt_core: write fragSeq(%d) size(%zu, %d) ok\n", + fragSeq, fragSize + sizeof(WMT_PATCH_CMD), u4Res); + + osal_memset(evtBuf, 0, sizeof(evtBuf)); + /* iRet = (*kal_stp_rx)(evtBuf, sizeof(WMT_PATCH_EVT), &u4Res); */ + iRet = wmt_core_rx(evtBuf, sizeof(WMT_PATCH_EVT), &u4Res); + if (iRet || (u4Res != sizeof(WMT_PATCH_EVT))) { + WMT_ERR_FUNC("wmt_core: read WMT_PATCH_EVT length(%zu, %d) fail(%d)\n", + sizeof(WMT_PATCH_EVT), u4Res, iRet); + iRet -= 1; + break; + } +#if CFG_CHECK_WMT_RESULT + if (osal_memcmp(evtBuf, WMT_PATCH_EVT, sizeof(WMT_PATCH_EVT)) != 0) { + WMT_ERR_FUNC("rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%zu):[%02X,%02X,%02X,%02X,%02X]\n", + u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], + sizeof(WMT_PATCH_EVT), WMT_PATCH_EVT[0], WMT_PATCH_EVT[1], + WMT_PATCH_EVT[2], WMT_PATCH_EVT[3], WMT_PATCH_EVT[4]); + iRet -= 1; + break; + } +#endif + WMT_DBG_FUNC("wmt_core: read WMT_PATCH_EVT length(%zu, %d) ok\n", + sizeof(WMT_PATCH_EVT), u4Res); + offset += patchSizePerFrag; + ++fragSeq; + } + + WMT_INFO_FUNC("wmt_core: patch dwn:%d frag(%d, %d) %s\n", + iRet, fragSeq, fragSize, (!iRet && (fragSeq == fragNum)) ? "ok" : "fail"); + + if (fragSeq != fragNum) + iRet -= 1; +done: + /* WMT_CTRL_FREE_PATCH always return 0 */ + /* wmt_core_ctrl(WMT_CTRL_FREE_PATCH, NULL, NULL); */ + ctrlData.ctrlId = WMT_CTRL_FREE_PATCH; + ctrlData.au4CtrlData[0] = index + 1; + wmt_ctrl(&ctrlData); + + return iRet; +} + +#else +static INT32 mt6628_patch_dwn(VOID) +{ + INT32 iRet = -1; + P_WMT_PATCH patchHdr; + PUINT8 pbuf; + UINT32 patchSize; + UINT32 fragSeq; + UINT32 fragNum; + UINT16 fragSize = 0; + UINT16 cmdLen; + UINT32 offset; + UINT32 u4Res; + UINT8 evtBuf[8]; + PINT8 cDataTime = NULL; + /*PINT8 cPlat = NULL; */ + UINT16 u2HwVer = 0; + UINT16 u2SwVer = 0; + UINT32 u4PatchVer = 0; + UINT32 patchSizePerFrag = 0; + WMT_CTRL_DATA ctrlData; + + /*1.check hardware information */ + if (gp_mt6628_info == NULL) { + WMT_ERR_FUNC("null gp_mt6628_info!\n"); + return -1; + } + /* <2> search patch and read patch content */ + /* <2.1> search patch */ + ctrlData.ctrlId = WMT_CTRL_PATCH_SEARCH; + iRet = wmt_ctrl(&ctrlData); + if (iRet == 0) { + /* patch with correct Hw Ver Major Num found */ + ctrlData.ctrlId = WMT_CTRL_GET_PATCH_NAME; + ctrlData.au4CtrlData[0] = (size_t) &gFullPatchName; + iRet = wmt_ctrl(&ctrlData); + + WMT_INFO_FUNC("valid patch found: (%s)\n", gFullPatchName); + /* <2.2> read patch content */ + ctrlData.ctrlId = WMT_CTRL_GET_PATCH; + ctrlData.au4CtrlData[0] = (size_t) NULL; + ctrlData.au4CtrlData[1] = (size_t) &gFullPatchName; + + } else { + iRet -= 1; + return iRet; + } + ctrlData.au4CtrlData[2] = (size_t) &pbuf; + ctrlData.au4CtrlData[3] = (size_t) &patchSize; + iRet = wmt_ctrl(&ctrlData); + if (iRet) { + WMT_ERR_FUNC("wmt_core: WMT_CTRL_GET_PATCH fail:%d\n", iRet); + iRet -= 1; + goto done; + } + + /* |<-BCNT_PATCH_BUF_HEADROOM(8) bytes dummy allocated->|<-patch file->| */ + pbuf += BCNT_PATCH_BUF_HEADROOM; + /* patch file with header: + * |<-patch header: 28 Bytes->|<-patch body: X Bytes ----->| + */ + patchHdr = (P_WMT_PATCH) pbuf; + /* check patch file information */ + + cDataTime = patchHdr->ucDateTime; + u2HwVer = patchHdr->u2HwVer; + u2SwVer = patchHdr->u2SwVer; + u4PatchVer = patchHdr->u4PatchVer; + /*cPlat = &patchHdr->ucPLat[0]; */ + + cDataTime[15] = '\0'; + WMT_INFO_FUNC("===========================================\n"); + WMT_INFO_FUNC("[Combo Patch] Built Time = %s\n", cDataTime); + WMT_INFO_FUNC("[Combo Patch] Hw Ver = 0x%x\n", + ((u2HwVer & 0x00ff) << 8) | ((u2HwVer & 0xff00) >> 8)); + WMT_INFO_FUNC("[Combo Patch] Sw Ver = 0x%x\n", + ((u2SwVer & 0x00ff) << 8) | ((u2SwVer & 0xff00) >> 8)); + WMT_INFO_FUNC("[Combo Patch] Ph Ver = 0x%04x\n", + ((u4PatchVer & 0xff000000) >> 24) | ((u4PatchVer & 0x00ff0000) >> 16)); + WMT_INFO_FUNC("[Combo Patch] Platform = %c%c%c%c\n", patchHdr->ucPLat[0], + patchHdr->ucPLat[1], patchHdr->ucPLat[2], patchHdr->ucPLat[3]); + WMT_INFO_FUNC("===========================================\n"); + + /* remove patch header: + * |<-patch body: X Bytes (X=patchSize)--->| + */ + if (patchSize < sizeof(WMT_PATCH)) { + WMT_ERR_FUNC("error patch size\n"); + return -1; + } + patchSize -= sizeof(WMT_PATCH); + pbuf += sizeof(WMT_PATCH); + patchSizePerFrag = DEFAULT_PATCH_FRAG_SIZE; + /* reserve 1st patch cmd space before patch body + * |<-WMT_CMD: 5Bytes->|<-patch body: X Bytes (X=patchSize)----->| + */ + osal_memcpy(&gp_mt6628_patch_info, patchHdr, osal_sizeof(WMT_PATCH)); + pbuf -= sizeof(WMT_PATCH_CMD); + + fragNum = patchSize / patchSizePerFrag; + fragNum += ((fragNum * patchSizePerFrag) == patchSize) ? 0 : 1; + + WMT_DBG_FUNC("patch size(%d) fragNum(%d)\n", patchSize, fragNum); + + + /* send all fragments */ + offset = sizeof(WMT_PATCH_CMD); + fragSeq = 0; + while (fragSeq < fragNum) { + WMT_DBG_FUNC("patch size(%d) fragNum(%d)\n", patchSize, fragNum); + if (fragSeq == (fragNum - 1)) { + /* last fragment */ + fragSize = patchSize - fragSeq * patchSizePerFrag; + WMT_PATCH_CMD[4] = WMT_PATCH_FRAG_LAST; + } else { + fragSize = patchSizePerFrag; + WMT_PATCH_CMD[4] = (fragSeq == 0) ? WMT_PATCH_FRAG_1ST : WMT_PATCH_FRAG_MID; + } + /* update length field in CMD:flag+frag */ + cmdLen = 1 + fragSize; + osal_memcpy(&WMT_PATCH_CMD[2], &cmdLen, 2); + /* copy patch CMD to buf (overwrite last 5-byte in prev frag) */ + osal_memcpy(pbuf + offset - sizeof(WMT_PATCH_CMD), WMT_PATCH_CMD, + sizeof(WMT_PATCH_CMD)); + + /* iRet = (*kal_stp_tx)(pbuf + offset - sizeof(WMT_PATCH_CMD), + * fragSize + sizeof(WMT_PATCH_CMD), &u4Res); + */ + iRet = + wmt_core_tx(pbuf + offset - sizeof(WMT_PATCH_CMD), + fragSize + sizeof(WMT_PATCH_CMD), &u4Res, MTK_WCN_BOOL_FALSE); + if (iRet || (u4Res != fragSize + sizeof(WMT_PATCH_CMD))) { + WMT_ERR_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) fail(%d)\n", fragSeq, + fragSize + sizeof(WMT_PATCH_CMD), u4Res, iRet); + iRet -= 1; + break; + } + WMT_DBG_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) ok\n", + fragSeq, fragSize + sizeof(WMT_PATCH_CMD), u4Res); + + osal_memset(evtBuf, 0, sizeof(evtBuf)); + /* iRet = (*kal_stp_rx)(evtBuf, sizeof(WMT_PATCH_EVT), &u4Res); */ + iRet = wmt_core_rx(evtBuf, sizeof(WMT_PATCH_EVT), &u4Res); + if (iRet || (u4Res != sizeof(WMT_PATCH_EVT))) { + WMT_ERR_FUNC("wmt_core: read WMT_PATCH_EVT length(%d, %d) fail(%d)\n", + sizeof(WMT_PATCH_EVT), u4Res, iRet); + iRet -= 1; + break; + } +#if CFG_CHECK_WMT_RESULT + if (osal_memcmp(evtBuf, WMT_PATCH_EVT, sizeof(WMT_PATCH_EVT)) != 0) { + WMT_ERR_FUNC("rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%d):[%02X,%02X,%02X,%02X,%02X]\n", + u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], + sizeof(WMT_PATCH_EVT), WMT_PATCH_EVT[0], WMT_PATCH_EVT[1], + WMT_PATCH_EVT[2], WMT_PATCH_EVT[3], WMT_PATCH_EVT[4]); + iRet -= 1; + break; + } +#endif + WMT_DBG_FUNC("wmt_core: read WMT_PATCH_EVT length(%d, %d) ok\n", + sizeof(WMT_PATCH_EVT), u4Res); + offset += patchSizePerFrag; + ++fragSeq; + } + + WMT_INFO_FUNC("wmt_core: patch dwn:%d frag(%d, %d) %s\n", + iRet, fragSeq, fragSize, (!iRet && (fragSeq == fragNum)) ? "ok" : "fail"); + + if (fragSeq != fragNum) + iRet -= 1; +done: + /* WMT_CTRL_FREE_PATCH always return 0 */ + wmt_core_ctrl(WMT_CTRL_FREE_PATCH, NULL, NULL); + + return iRet; +} + +#endif + diff --git a/drivers/misc/mediatek/connectivity/common/common_main/core/wmt_ic_6630.c b/drivers/misc/mediatek/connectivity/common/common_main/core/wmt_ic_6630.c new file mode 100644 index 0000000000000000000000000000000000000000..31974df9853fbfbeb7a348a296e7db647edc0c9a --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/core/wmt_ic_6630.c @@ -0,0 +1,2043 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + + + + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +#ifdef DFT_TAG +#undef DFT_TAG +#endif +#define DFT_TAG "[WMT-IC]" +#define CFG_IC_MT6630 1 + +#define MT6630_BRINGUP 0 +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include "osal_typedef.h" +#include "wmt_ic.h" +#include "wmt_core.h" +#include "wmt_lib.h" +#include "stp_core.h" + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +#define DEFAULT_PATCH_FRAG_SIZE (1000) +#define WMT_PATCH_FRAG_1ST (0x1) +#define WMT_PATCH_FRAG_MID (0x2) +#define WMT_PATCH_FRAG_LAST (0x3) + +#define CFG_CHECK_WMT_RESULT (1) +/* BT Port 2 Feature. this command does not need after coex command is downconfirmed by LC, */ +#define CFG_WMT_BT_PORT2 (0) + +#define CFG_SET_OPT_REG (0) +#define CFG_WMT_I2S_DBGUART_SUPPORT (0) +#define CFG_SET_OPT_REG_SWLA (0) +#define CFG_SET_OPT_REG_MCUCLK (0) +#define CFG_SET_OPT_REG_MCUIRQ (0) + +#define CFG_SUBSYS_COEX_NEED 0 + +#define CFG_WMT_COREDUMP_ENABLE 0 + +#define CFG_WMT_MULTI_PATCH (1) + +#define CFG_WMT_CRYSTAL_TIMING_SET (0) + +#if CFG_WMT_LTE_COEX_HANDLING +#define CFG_WMT_FILTER_MODE_SETTING (1) +#else +#define CFG_WMT_FILTER_MODE_SETTING (0) +#endif +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +static UINT8 gFullPatchName[NAME_MAX + 1]; +static const WMT_IC_INFO_S *gp_mt6630_info; +static WMT_PATCH gp_mt6630_patch_info; +static WMT_CO_CLOCK gCoClockEn = WMT_CO_CLOCK_DIS; + +static UINT8 WMT_QUERY_BAUD_CMD[] = { 0x01, 0x04, 0x01, 0x00, 0x02 }; +static UINT8 WMT_QUERY_BAUD_EVT_115200[] = { + 0x02, 0x04, 0x06, 0x00, 0x00, 0x02, 0x00, 0xC2, 0x01, 0x00 }; +static UINT8 WMT_QUERY_BAUD_EVT_X[] = { + 0x02, 0x04, 0x06, 0x00, 0x00, 0x02, 0xAA, 0xAA, 0xAA, 0xBB }; +static UINT8 WMT_QUERY_STP_CMD[] = { 0x01, 0x04, 0x01, 0x00, 0x04 }; +static UINT8 WMT_QUERY_STP_EVT_DEFAULT[] = { + 0x02, 0x04, 0x06, 0x00, 0x00, 0x04, 0x11, 0x00, 0x00, 0x00 }; +static UINT8 WMT_QUERY_STP_EVT_UART[] = { + 0x02, 0x04, 0x06, 0x00, 0x00, 0x04, 0xDF, 0x0E, 0x68, 0x01 }; +static UINT8 WMT_SET_BAUD_CMD_X[] = { 0x01, 0x04, 0x05, 0x00, 0x01, 0xAA, 0xAA, 0xAA, 0xBB }; +static UINT8 WMT_SET_BAUD_EVT[] = { 0x02, 0x04, 0x02, 0x00, 0x00, 0x01 }; +static UINT8 WMT_SET_WAKEUP_WAKE_CMD_RAW[] = { 0xFF }; +static UINT8 WMT_SET_WAKEUP_WAKE_EVT[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x03 }; +static UINT8 WMT_PATCH_CMD[] = { 0x01, 0x01, 0x00, 0x00, 0x00 }; +static UINT8 WMT_PATCH_EVT[] = { 0x02, 0x01, 0x01, 0x00, 0x00 }; +static UINT8 WMT_RESET_CMD[] = { 0x01, 0x07, 0x01, 0x00, 0x04 }; +static UINT8 WMT_RESET_EVT[] = { 0x02, 0x07, 0x01, 0x00, 0x00 }; + +#if CFG_WMT_BT_PORT2 +static UINT8 WMT_BTP2_CMD[] = { 0x01, 0x10, 0x03, 0x00, 0x01, 0x03, 0x01 }; +static UINT8 WMT_BTP2_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; +#endif + +#if CFG_WMT_MULTI_PATCH +static UINT8 WMT_PATCH_ADDRESS_CMD[] = { 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, +0xD4, 0x03, 0x09, 0x02, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff }; + +static UINT8 WMT_PATCH_ADDRESS_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; + +static UINT8 WMT_PATCH_P_ADDRESS_CMD[] = { 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, +0xfc, 0x08, 0x09, 0x02, 0x00, 0x00, 0x08, 0x00, 0xff, 0xff, 0xff, 0xff }; + +static UINT8 WMT_PATCH_P_ADDRESS_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; +#endif + +/*coex cmd/evt++*/ +static UINT8 WMT_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x01, 0x00 }; +static UINT8 WMT_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; + +#if CFG_SUBSYS_COEX_NEED +static UINT8 WMT_BT_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x0B, + 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, + 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0xAA +}; +static UINT8 WMT_BT_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; + +static UINT8 WMT_WIFI_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x0C, + 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0xAA +}; +static UINT8 WMT_WIFI_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; + +static UINT8 WMT_PTA_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x0A, + 0x00, 0x04, + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xEE, 0xFF, 0xFF, 0xFE +}; +static UINT8 WMT_PTA_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; + +static UINt8 WMT_MISC_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x09, + 0x00, 0x05, + 0xAA, 0xAA, 0xAA, 0xAA, + 0xBB, 0xBB, 0xBB, 0xBB +}; +static UINT8 WMT_MISC_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; +#endif + +/*coex cmd/evt--*/ +static UINT8 WMT_SET_STP_CMD[] = { 0x01, 0x04, 0x05, 0x00, 0x03, 0xDF, 0x0E, 0x68, 0x01 }; +static UINT8 WMT_SET_STP_EVT[] = { 0x02, 0x04, 0x02, 0x00, 0x00, 0x03 }; +static UINT8 WMT_STRAP_CONF_CMD_FM_COMM[] = { 0x01, 0x05, 0x02, 0x00, 0x02, 0x02 }; +static UINT8 WMT_STRAP_CONF_EVT[] = { 0x02, 0x05, 0x02, 0x00, 0x00, 0x02 }; + +/* to get full dump when f/w assert */ +static UINT8 WMT_CORE_DUMP_LEVEL_04_CMD[] = { + 0x1, 0x0F, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +static UINT8 WMT_CORE_DUMP_LEVEL_04_EVT[] = { 0x2, 0x0F, 0x01, 0x00, 0x00 }; + +static UINT8 WMT_CORE_CO_CLOCK_CMD[] = { 0x1, 0x0A, 0x02, 0x00, 0x08, 0x03 }; +static UINT8 WMT_CORE_CO_CLOCK_EVT[] = { 0x2, 0x0A, 0x01, 0x00, 0x00 }; + + +#if (MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT) + + +static UINT8 WMT_SET_DAI_MODE_REG_CMD[] = { 0x01, 0x08, 0x28, 0x00 /*length */ + , 0x01 /* op: w */ + , 0x01 /*type: reg */ + , 0x00 /*rev */ + , 0x03 /*2 registers */ + , 0x6c, 0x50, 0x02, 0x80 /*addr:0x8002506c */ + , 0x00, 0x00, 0x10, 0x11 /*value:0x11100000 */ + , 0x00, 0x00, 0xf0, 0xff /*mask:0xfff00000 */ + , 0x70, 0x50, 0x02, 0x80 /*addr:0x80025070 */ + , 0x01, 0x00, 0x00, 0x00 /*value:0x00000001 */ + , 0x0f, 0x00, 0x00, 0x00 /*mask:0x0000000f */ + , 0x00, 0x53, 0x02, 0x80 /*addr:0x80025300 */ + , 0x04, 0x00, 0x00, 0x00 /*value:0x00000004 */ + , 0x04, 0x00, 0x00, 0x00 /*mask:0x00000004 */ +}; + +static UINT8 WMT_SET_DAI_MODE_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ + , 0x00 /*S: 0 */ + , 0x00 /*type: reg */ + , 0x00 /*rev */ + , 0x03 /*2 registers */ +}; + + +#endif + + +#if CFG_SET_OPT_REG_SWLA /* enable swla: eesk(7) eecs(8) oscen(19) sck0(24) scs0(25) */ +static UINT8 WMT_SET_SWLA_REG_CMD[] = { 0x01, 0x08, 0x1C, 0x00 /*length */ + , 0x01 /* op: w */ + , 0x01 /*type: reg */ + , 0x00 /*rev */ + , 0x02 /*2 registers */ + , 0x10, 0x01, 0x05, 0x80 /*addr:0x80050110 */ + , 0x10, 0x10, 0x01, 0x00 /*value:0x00011010 */ + , 0xF0, 0xF0, 0x0F, 0x00 /*mask:0x000FF0F0 */ + , 0x40, 0x01, 0x05, 0x80 /*addr:0x80050140 */ + , 0x00, 0x10, 0x01, 0x00 /*value:0x00011000 */ + , 0x00, 0xF0, 0x0F, 0x00 /*mask:0x000FF000 */ +}; + +static UINT8 WMT_SET_SWLA_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ + , 0x00 /*S: 0 */ + , 0x00 /*type: reg */ + , 0x00 /*rev */ + , 0x02 /*2 registers */ +}; +#endif + +#if CFG_SET_OPT_REG_MCUCLK /* enable mcu clk: antsel_4, eedi */ +static UINT8 WMT_SET_MCUCLK_REG_CMD[] = { 0x01, 0x08, (4 + 12 * 4), 0x00 /*length */ + , 0x01 /* op: w */ + , 0x01 /* type: reg */ + , 0x00 /* rev */ + , 0x04 /* 4 registers */ + , 0x00, 0x04, 0x00, 0x80 /* addr:0x8000 0400 */ + , 0x00, 0x14, 0x00, 0x00 /* value:0x0000 1400(osc, hclk), 0x0000 1501(PLL, en) */ + , 0xFF, 0xFF, 0x00, 0x00 /* mask:0x0000 FFFF */ + , 0x80, 0x01, 0x05, 0x80 /* addr:0x8005 0180 */ + , 0x12, 0x13, 0x00, 0x00 /* value:0x0000 1312(osc, hclk), 0x0000 1a19(PLL, en) */ + , 0xFF, 0xFF, 0x00, 0x00 /* mask:0x0000 FFFF */ + , 0x00, 0x01, 0x05, 0x80 /* addr:0x8005 0100 */ + , 0x00, 0x00, 0x02, 0x00 /* value:0x0002 0000 */ + , 0x00, 0x00, 0x0F, 0x00 /* mask:0x000F 0000 */ + , 0x10, 0x01, 0x05, 0x80 /* addr:0x8005 0110 */ + , 0x02, 0x00, 0x00, 0x00 /* value:0x0000 0002 */ + , 0x0F, 0x00, 0x00, 0x00 /* mask:0x0000 000F */ +}; + +static UINT8 WMT_SET_MCUCLK_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ + , 0x00 /* S: 0 */ + , 0x00 /* type: reg */ + , 0x00 /* rev */ + , 0x04 /* 4 registers */ +}; +#endif + +#if CFG_WMT_I2S_DBGUART_SUPPORT /* register write for debug uart */ +static UINT8 WMT_SET_DBGUART_REG_CMD[] = { 0x01, 0x08, 0x1C, 0x00 /*length */ + , 0x01 /* op: w */ + , 0x01 /*type: reg */ + , 0x00 /*rev */ + , 0x02 /*2 registers */ + , 0x30, 0x01, 0x05, 0x80 /*addr:0x80050130 */ + , 0x00, 0x00, 0x00, 0x00 /*value:0x00000000 */ + , 0xF0, 0x0F, 0x00, 0x00 /*mask:0x00000FF0 */ + , 0x40, 0x01, 0x05, 0x80 /*addr:0x80050140 */ + , 0x00, 0x01, 0x00, 0x00 /*value:0x00000100 */ + , 0x00, 0x01, 0x00, 0x00 /*mask:0x00000100 */ +}; + +static UINT8 WMT_SET_DBGUART_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ + , 0x00 /*S: 0 */ + , 0x00 /*type: reg */ + , 0x00 /*rev */ + , 0x02 /*2 registers */ +}; +#endif + +#if CFG_SET_OPT_REG_MCUIRQ /* enable mcu irq: antsel_4, wlan_act */ +static UINT8 WMT_SET_MCUIRQ_REG_CMD[] = { 0x01, 0x08, (4 + 12 * 4), 0x00 /*length */ + , 0x01 /* op: w */ + , 0x01 /* type: reg */ + , 0x00 /* rev */ + , 0x04 /* 4 registers */ + , 0x00, 0x04, 0x00, 0x80 /* addr:0x8000_0400 */ + , 0x03, 0x14, 0x00, 0x00 /* value:0x0000_1403 check confg debug flag 3 low word */ + , 0xFF, 0xFF, 0x00, 0x00 /* mask:0x0000_FFFF */ + /* cirq_int_n */ + , 0x10, 0x01, 0x05, 0x80 /* addr:0x8005_0110 */ + , 0x02, 0x00, 0x00, 0x00 /* value:0x0000_0002 set EEDI as cirq_int_n debug flag (monitor flag2) */ + , 0x07, 0x00, 0x00, 0x00 /* mask:0x0000_0007 */ + , 0x00, 0x01, 0x05, 0x80 /* addr:0x8005_0100 */ + , 0x00, 0x00, 0x02, 0x00 /* value:0x0002_0000 (ANTSEL4=>monitor flag 0, ahb_x2_gt_ck debug flag) */ + , 0x00, 0x00, 0x07, 0x00 /* mask:0x0007_0000 */ + /* 1. ARM irq_b, monitor flag 0 */ + , 0x80, 0x01, 0x05, 0x80 /* addr:0x8005_0180 */ + , 0x1F, 0x1E, 0x00, 0x00 /* value:0x0000_1E1F check mcusys debug flag */ + , 0x7F, 0x7F, 0x00, 0x00 /* mask:0x0000_7F7F */ +}; + +static UINT8 WMT_SET_MCUIRQ_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ + , 0x00 /* S: 0 */ + , 0x00 /* type: reg */ + , 0x00 /* rev */ + , 0x04 /* 5 registers */ +}; +#endif + +static UINT8 WMT_SET_CRYSTAL_TRIMING_CMD[] = { 0x01, 0x12, 0x02, 0x00, 0x01, 0x00 }; +static UINT8 WMT_SET_CRYSTAL_TRIMING_EVT[] = { 0x02, 0x12, 0x02, 0x00, 0x01, 0x00 }; + +#if CFG_WMT_CRYSTAL_TIMING_SET +static UINT8 WMT_GET_CRYSTAL_TRIMING_CMD[] = { 0x01, 0x12, 0x02, 0x00, 0x00, 0x00 }; +static UINT8 WMT_GET_CRYSTAL_TRIMING_EVT[] = { 0x02, 0x12, 0x02, 0x00, 0x00, 0x00 }; +#endif + + +#if CFG_WMT_FILTER_MODE_SETTING +static UINT8 WMT_COEX_EXT_COMPONENT_CMD[] = { 0x01, 0x10, 0x03, 0x00, 0x0d, 0x00, 0x00 }; + +static UINT8 WMT_COEX_FILTER_SPEC_CMD_TEST[] = { 0x01, 0x10, 0x45, 0x00, 0x11, + 0x00, 0x00, 0x01, 0x00, 0x11, + 0x11, 0x16, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x63, 0x63, 0x63, + 0x00, 0x39, 0x43, 0x63, 0x63, + 0x02, 0x02, 0x03, 0x00, 0x01, + 0x01, 0x01, 0x01, 0x0e, 0x0e, + 0x0e, 0x00, 0x0a, 0x0c, 0x0e, + 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +static UINT8 WMT_COEX_LTE_FREQ_IDX_TABLE_CMD[] = { 0x01, 0x10, 0x21, 0x00, 0x12, + 0xfc, 0x08, 0x15, 0x09, 0x2e, + 0x09, 0x47, 0x09, 0xc4, 0x09, + 0xd4, 0x09, 0xe3, 0x09, 0x5a, + 0x0a, 0x14, 0x09, 0x2d, 0x09, + 0x46, 0x09, 0x60, 0x09, 0xd3, + 0x09, 0xe2, 0x09, 0x59, 0x0a, + 0x8B, 0x0a +}; + +static UINT8 WMT_COEX_LTE_CHAN_UNSAFE_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x13, 0x00 }; + +#if CFG_WMT_LTE_ENABLE_MSGID_MAPPING +#else +static UINT8 WMT_COEX_IS_LTE_L_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x21, 0x01 }; +#endif + +static UINT8 WMT_COEX_IS_LTE_PROJ_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x15, 0x01 }; + +static UINT8 WMT_COEX_SPLIT_MODE_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; +#endif + +static struct init_script init_table_1_2[] = { + INIT_CMD(WMT_QUERY_BAUD_CMD, WMT_QUERY_BAUD_EVT_115200, "query baud 115200"), + INIT_CMD(WMT_QUERY_STP_CMD, WMT_QUERY_STP_EVT_DEFAULT, "query stp default"), + INIT_CMD(WMT_SET_BAUD_CMD_X, WMT_SET_BAUD_EVT, "set baud rate"), +}; + + +static struct init_script init_table_2[] = { + INIT_CMD(WMT_QUERY_BAUD_CMD, WMT_QUERY_BAUD_EVT_X, "query baud X"), +}; + +static struct init_script init_table_3[] = { + INIT_CMD(WMT_RESET_CMD, WMT_RESET_EVT, "wmt reset"), +#if CFG_WMT_BT_PORT2 + INIT_CMD(WMT_BTP2_CMD, WMT_BTP2_EVT, "set bt port2"), +#endif +}; + +static struct init_script set_crystal_timing_script[] = { + INIT_CMD(WMT_SET_CRYSTAL_TRIMING_CMD, WMT_SET_CRYSTAL_TRIMING_EVT, + "set crystal trim value"), +}; + +#if CFG_WMT_CRYSTAL_TIMING_SET +static struct init_script get_crystal_timing_script[] = { + INIT_CMD(WMT_GET_CRYSTAL_TRIMING_CMD, WMT_GET_CRYSTAL_TRIMING_EVT, + "get crystal trim value"), +}; +#endif + +static struct init_script init_table_4[] = { + INIT_CMD(WMT_SET_STP_CMD, WMT_SET_STP_EVT, "set stp"), +}; + +static struct init_script init_table_5[] = { + INIT_CMD(WMT_QUERY_STP_CMD, WMT_QUERY_STP_EVT_UART, "query stp uart"), + INIT_CMD(WMT_QUERY_BAUD_CMD, WMT_QUERY_BAUD_EVT_X, "query baud X"), +}; + +static struct init_script init_table_5_1[] = { + INIT_CMD(WMT_STRAP_CONF_CMD_FM_COMM, WMT_STRAP_CONF_EVT, "configure FM comm"), +}; + +static struct init_script init_table_6[] = { + INIT_CMD(WMT_CORE_DUMP_LEVEL_04_CMD, WMT_CORE_DUMP_LEVEL_04_EVT, "setup core dump level"), +}; + + +#if defined(CFG_SET_OPT_REG) && CFG_SET_OPT_REG +static struct init_script set_registers[] = { + /* INIT_CMD(WMT_SET_GPS_REG_CMD, WMT_SET_GPS_REG_EVT, "set wmt registers"), */ + /* INIT_CMD(WMT_SET_SDIODRV_REG_CMD, WMT_SET_SDIODRV_REG_EVT, "set SDIO driving registers") */ +#if CFG_WMT_I2S_DBGUART_SUPPORT + INIT_CMD(WMT_SET_DBGUART_REG_CMD, WMT_SET_DBGUART_REG_EVT, "set debug uart registers"), +#endif +#if CFG_SET_OPT_REG_SWLA + INIT_CMD(WMT_SET_SWLA_REG_CMD, WMT_SET_SWLA_REG_EVT, "set swla registers"), +#endif +#if CFG_SET_OPT_REG_MCUCLK + INIT_CMD(WMT_SET_MCUCLK_REG_CMD, WMT_SET_MCUCLK_REG_EVT, "set mcuclk dbg registers"), +#endif +#if CFG_SET_OPT_REG_MCUIRQ + INIT_CMD(WMT_SET_MCUIRQ_REG_CMD, WMT_SET_MCUIRQ_REG_EVT, "set mcu irq dbg registers"), +#endif +}; +#endif + +static struct init_script coex_table[] = { + INIT_CMD(WMT_COEX_SETTING_CONFIG_CMD, WMT_COEX_SETTING_CONFIG_EVT, "coex_wmt"), + +#if CFG_SUBSYS_COEX_NEED +/* no need in MT6630 */ + INIT_CMD(WMT_BT_COEX_SETTING_CONFIG_CMD, WMT_BT_COEX_SETTING_CONFIG_EVT, "coex_bt"), + INIT_CMD(WMT_WIFI_COEX_SETTING_CONFIG_CMD, WMT_WIFI_COEX_SETTING_CONFIG_EVT, "coex_wifi"), + INIT_CMD(WMT_PTA_COEX_SETTING_CONFIG_CMD, WMT_PTA_COEX_SETTING_CONFIG_EVT, "coex_ext_pta"), + INIT_CMD(WMT_MISC_COEX_SETTING_CONFIG_CMD, WMT_MISC_COEX_SETTING_CONFIG_EVT, "coex_misc"), +#endif +}; + +static struct init_script osc_type_table[] = { + INIT_CMD(WMT_CORE_CO_CLOCK_CMD, WMT_CORE_CO_CLOCK_EVT, "osc_type"), +}; + +#if (MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT) +static struct init_script merge_pcm_table[] = { + INIT_CMD(WMT_SET_DAI_MODE_REG_CMD, WMT_SET_DAI_MODE_REG_EVT, "DAI_PAD"), +}; +#endif + +#if CFG_WMT_FILTER_MODE_SETTING +#if CFG_WMT_LTE_ENABLE_MSGID_MAPPING +static struct init_script set_wifi_lte_coex_table_0[] = { + INIT_CMD(WMT_COEX_EXT_COMPONENT_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi lte ext component"), + INIT_CMD(WMT_COEX_FILTER_SPEC_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi lte coex filter"), + INIT_CMD(WMT_COEX_LTE_FREQ_IDX_TABLE_CMD, WMT_COEX_SPLIT_MODE_EVT, + "wifi lte freq id table"), + INIT_CMD(WMT_COEX_LTE_CHAN_UNSAFE_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi lte unsafe channel"), + INIT_CMD(WMT_COEX_IS_LTE_PROJ_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi coex is lte project"), +}; +#else +static struct init_script set_wifi_lte_coex_table_0[] = { + INIT_CMD(WMT_COEX_EXT_COMPONENT_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi lte ext component"), + INIT_CMD(WMT_COEX_FILTER_SPEC_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi lte coex filter"), + INIT_CMD(WMT_COEX_LTE_FREQ_IDX_TABLE_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi lte freq id table"), + INIT_CMD(WMT_COEX_LTE_CHAN_UNSAFE_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi lte unsafe channel"), + INIT_CMD(WMT_COEX_IS_LTE_L_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi coex is L branch"), + INIT_CMD(WMT_COEX_IS_LTE_PROJ_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi coex is lte project"), +}; +#endif +#endif + +/* MT6630 Chip Version and Info Table */ +static const WMT_IC_INFO_S mt6630_info_table[] = { + { + .u4HwVer = 0x8A00, + .cChipName = WMT_IC_NAME_MT6630, + .cChipVersion = WMT_IC_VER_E1, + .cPatchNameExt = WMT_IC_PATCH_E1_EXT, + .bWorkWithoutPatch = MTK_WCN_BOOL_FALSE, + .bPsmSupport = MTK_WCN_BOOL_TRUE, + }, + { + .u4HwVer = 0x8A10, + .cChipName = WMT_IC_NAME_MT6630, + .cChipVersion = WMT_IC_VER_E2, + .cPatchNameExt = WMT_IC_PATCH_E2_EXT, + .bWorkWithoutPatch = MTK_WCN_BOOL_FALSE, + .bPsmSupport = MTK_WCN_BOOL_TRUE, + }, + { + .u4HwVer = 0x8A11, + .cChipName = WMT_IC_NAME_MT6630, + .cChipVersion = WMT_IC_VER_E3, + .cPatchNameExt = WMT_IC_PATCH_E2_EXT, + .bWorkWithoutPatch = MTK_WCN_BOOL_FALSE, + .bPsmSupport = MTK_WCN_BOOL_TRUE, + }, + { + .u4HwVer = 0x8B11, + .cChipName = WMT_IC_NAME_MT6630, + .cChipVersion = WMT_IC_VER_E4, + .cPatchNameExt = WMT_IC_PATCH_E2_EXT, + .bWorkWithoutPatch = MTK_WCN_BOOL_FALSE, + .bPsmSupport = MTK_WCN_BOOL_TRUE, + } +}; + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +static INT32 mt6630_sw_init(P_WMT_HIF_CONF pWmtHifConf); + +static INT32 mt6630_sw_deinit(P_WMT_HIF_CONF pWmtHifConf); + +static INT32 mt6630_pin_ctrl(WMT_IC_PIN_ID id, WMT_IC_PIN_STATE state, UINT32 flag); + +static INT32 mt6630_aif_ctrl(WMT_IC_PIN_STATE state, UINT32 flag); + +static INT32 mt6630_ver_check(VOID); + +static const WMT_IC_INFO_S *mt6630_find_wmt_ic_info(const UINT32 hw_ver); + +static INT32 wmt_stp_init_coex(VOID); + +#if CFG_WMT_MULTI_PATCH +static INT32 mt6630_patch_dwn(UINT32 index); +static INT32 mt6630_patch_info_prepare(VOID); +#else +static INT32 mt6630_patch_dwn(VOID); +#endif + +static INT32 mt6630_co_clock_ctrl(WMT_CO_CLOCK on); +static WMT_CO_CLOCK mt6630_co_clock_get(VOID); + +#if CFG_WMT_CRYSTAL_TIMING_SET +static INT32 mt6630_crystal_triming_set(VOID); +#endif + +static MTK_WCN_BOOL mt6630_quick_sleep_flag_get(VOID); + +static MTK_WCN_BOOL mt6630_aee_dump_flag_get(VOID); +#if 0 +/* set sdio driving */ +static UINT8 WMT_SET_SDIO_DRV_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ + , 0x01 /* op: w */ + , 0x01 /*type: reg */ + , 0x00 /*rev */ + , 0x01 /*1 registers */ + , 0x50, 0x00, 0x05, 0x80 /*addr:0x80050050 */ + , 0x44, 0x44, 0x04, 0x00 /*value:0x00044444 */ + , 0x77, 0x77, 0x07, 0x00 /*mask:0x00077777 */ +}; + +static UINT8 WMT_SET_SDIO_DRV_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ + , 0x00 /*S: 0 */ + , 0x00 /*type: reg */ + , 0x00 /*rev */ + , 0x01 /*1 registers */ +}; + +static INT32 mt6630_set_sdio_driving(void); +static struct init_script sdio_driving_table[] = { + INIT_CMD(WMT_SET_SDIO_DRV_REG_CMD, WMT_SET_SDIO_DRV_REG_EVT, "sdio_driving"), +}; + +#endif +static MTK_WCN_BOOL mt6630_trigger_stp_assert(VOID); +#if CFG_WMT_FILTER_MODE_SETTING +static INT32 wmt_stp_wifi_lte_coex(VOID); +#endif + + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/* MT6630 Operation Function Table */ +WMT_IC_OPS wmt_ic_ops_mt6630 = { + .icId = 0x6630, + .sw_init = mt6630_sw_init, + .sw_deinit = mt6630_sw_deinit, + .ic_pin_ctrl = mt6630_pin_ctrl, + .ic_ver_check = mt6630_ver_check, + .co_clock_ctrl = mt6630_co_clock_ctrl, + .is_quick_sleep = mt6630_quick_sleep_flag_get, + .is_aee_dump_support = mt6630_aee_dump_flag_get, + .trigger_stp_assert = mt6630_trigger_stp_assert, + .deep_sleep_ctrl = NULL, +}; + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +static INT32 mt6630_sw_init(P_WMT_HIF_CONF pWmtHifConf) +{ + INT32 iRet = -1; + UINT32 u4Res = 0; + UINT8 evtBuf[256]; + ULONG ctrlPa1; + ULONG ctrlPa2; + UINT32 hw_ver; +#if CFG_WMT_MULTI_PATCH + UINT32 patch_num = 0; + UINT32 patch_index = 0; +#endif + WMT_CTRL_DATA ctrlData; + + WMT_DBG_FUNC(" start\n"); + + osal_assert(gp_mt6630_info != NULL); + + if ((gp_mt6630_info == NULL) + || (pWmtHifConf == NULL) + ) { + WMT_ERR_FUNC("null pointers: gp_mt6630_info(0x%p), pWmtHifConf(0x%p)\n", + gp_mt6630_info, pWmtHifConf); + return -1; + } + + hw_ver = gp_mt6630_info->u4HwVer; + + /* 4 <3.1> start init for sdio */ + + /* 4 <3.2> start init for uart */ + if (pWmtHifConf->hifType == WMT_HIF_UART) { + /* init variable fields for script execution */ + osal_memcpy(&WMT_SET_BAUD_CMD_X[5], &pWmtHifConf->au4HifConf[0], + osal_sizeof(UINT32)); + WMT_SET_BAUD_CMD_X[8] = (UINT8) 0x00; /* 0xC0 MTK Flow Control *//* no flow control */ + osal_memcpy(&WMT_QUERY_BAUD_EVT_X[6], &pWmtHifConf->au4HifConf[0], + osal_sizeof(UINT32)); + WMT_QUERY_BAUD_EVT_X[9] = (UINT8) 0x00; /* 0xC0 MTK Flow Control *//* no flow control */ + + /* 3. Query chip baud rate (TEST-ONLY) */ + /* 4. Query chip STP options (TEST-ONLY) */ + /* 5. Change chip baud rate: t_baud */ + /* WMT_DBG_FUNC("WMT-CORE: init_table_1_2 set chip baud:%d", pWmtHifConf->au4HifConf[0]); */ + iRet = wmt_core_init_script(init_table_1_2, ARRAY_SIZE(init_table_1_2)); + + if (iRet) { + WMT_ERR_FUNC("init_table_1_2 fail(%d)\n", iRet); + osal_assert(0); + return -2; + } + + /* 6. Set host baudrate and flow control */ + ctrlPa1 = pWmtHifConf->au4HifConf[0]; + ctrlPa2 = 0; + iRet = wmt_core_ctrl(WMT_CTRL_HOST_BAUDRATE_SET, &ctrlPa1, &ctrlPa2); + + if (iRet) { + WMT_ERR_FUNC("change baudrate(%d) fail(%d)\n", pWmtHifConf->au4HifConf[0], + iRet); + return -3; + } + + WMT_DBG_FUNC("WMT-CORE: change baudrate(%d) ok\n", pWmtHifConf->au4HifConf[0]); + + /* 7. Wake up chip and check event */ +/* iRet = (*kal_stp_tx_raw)(&WMT_SET_WAKEUP_WAKE_CMD_RAW[0], 1, &u4Res); */ + iRet = + wmt_core_tx((PUINT8)&WMT_SET_WAKEUP_WAKE_CMD_RAW[0], 1, &u4Res, + MTK_WCN_BOOL_TRUE); + + if (iRet || (u4Res != 1)) { + WMT_ERR_FUNC("write raw iRet(%d) written(%d)\n", iRet, u4Res); + return -4; + } + + osal_memset(evtBuf, 0, osal_sizeof(evtBuf)); + iRet = wmt_core_rx(evtBuf, osal_sizeof(WMT_SET_WAKEUP_WAKE_EVT), &u4Res); +#ifdef CFG_DUMP_EVT + WMT_DBG_FUNC("WAKEUP_WAKE_EVT read len %d [%02x,%02x,%02x,%02x,%02x,%02x]\n", + (INT32) u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], + evtBuf[5]); +#endif + + if (iRet || (u4Res != osal_sizeof(WMT_SET_WAKEUP_WAKE_EVT))) { + WMT_ERR_FUNC("read WAKEUP_WAKE_EVT fail(%d)\n", iRet); + mtk_wcn_stp_dbg_dump_package(); + return -5; + } + /* WMT_DBG_FUNC("WMT-CORE: read WMT_SET_WAKEUP_WAKE_EVT ok"); */ + +#if CFG_CHECK_WMT_RESULT + + if (osal_memcmp + (evtBuf, WMT_SET_WAKEUP_WAKE_EVT, osal_sizeof(WMT_SET_WAKEUP_WAKE_EVT)) != 0) { + WMT_ERR_FUNC("WMT-CORE: write WMT_SET_WAKEUP_WAKE_CMD_RAW status fail\n"); + return -6; + } +#endif + + /* 8. Query baud rate (TEST-ONLY) */ + iRet = wmt_core_init_script(init_table_2, osal_array_size(init_table_2)); + + if (iRet) { + WMT_ERR_FUNC("init_table_2 fail(%d)\n", iRet); + return -7; + } + } + + /* 9. download patch */ +#if CFG_WMT_MULTI_PATCH + /* 9.1 Let launcher to search patch info */ + iRet = mt6630_patch_info_prepare(); + + if (iRet) { + WMT_ERR_FUNC("patch info perpare fail(%d)\n", iRet); + return -8; + } + + /* 9.2 Read patch number */ + ctrlPa1 = 0; + ctrlPa2 = 0; + wmt_core_ctrl(WMT_CTRL_GET_PATCH_NUM, &ctrlPa1, &ctrlPa2); + patch_num = ctrlPa1; + WMT_INFO_FUNC("patch total num = [%d]\n", patch_num); + + /* 9.3 Multi-patch Patch download */ + for (patch_index = 0; patch_index < patch_num; patch_index++) { + iRet = mt6630_patch_dwn(patch_index); + + if (iRet) { + WMT_ERR_FUNC("patch dwn fail (%d),patch_index(%d)\n", iRet, patch_index); + return -12; + } + + iRet = wmt_core_init_script(init_table_3, ARRAY_SIZE(init_table_3)); + + if (iRet) { + WMT_ERR_FUNC("init_table_3 fail(%d)\n", iRet); + return -13; + } + } + +#else + /* 9.3 Patch download */ + iRet = mt6630_patch_dwn(); + + /* If patch download fail, we just ignore this error and let chip init process goes on */ + if (iRet) + WMT_ERR_FUNC("patch dwn fail (%d), just omit\n", iRet); +#endif /* End of #if CFG_WMT_MULTI_PATCH */ + + /* 10. WMT Reset command */ + iRet = wmt_core_init_script(init_table_3, ARRAY_SIZE(init_table_3)); + + if (iRet) { + WMT_ERR_FUNC("init_table_3 fail(%d)\n", iRet); + return -9; + } + + iRet = wmt_stp_init_coex(); + + if (iRet) { + WMT_ERR_FUNC("init_coex fail(%d)\n", iRet); + return -10; + } + WMT_DBG_FUNC("init_coex ok\n"); + +#if CFG_WMT_CRYSTAL_TIMING_SET + mt6630_crystal_triming_set(); +#endif + +#if MT6630_BRINGUP + WMT_INFO_FUNC("Bring up period, skip sdio driving settings\n"); +#else + WMT_DBG_FUNC("Temp solution, skip sdio driving settings\n"); + /* 6630_set_sdio_driving(); */ +#endif + if (pWmtHifConf->hifType == WMT_HIF_UART) { + /* 11. Set chip STP options */ + iRet = wmt_core_init_script(init_table_4, ARRAY_SIZE(init_table_4)); + + if (iRet) { + WMT_ERR_FUNC("init_table_4 fail(%d)\n", iRet); + return -12; + } + + /* 12. Enable host STP-UART mode */ + ctrlPa1 = WMT_STP_CONF_MODE; + ctrlPa2 = MTKSTP_UART_FULL_MODE; + iRet = wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); + ctrlPa1 = WMT_STP_CONF_EN; + ctrlPa2 = 1; + iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); + + if (iRet) { + WMT_ERR_FUNC("enable host STP-UART-FULL mode fail(%d)\n", iRet); + return -13; + } + + WMT_INFO_FUNC("enable host STP-UART-FULL mode\n"); + /*13. wait for 10ms, enough for chip do mechanism switch.(at least 2ms is needed) */ + osal_sleep_ms(10); + /* 14. Query chip STP options (TEST-ONLY) */ + /* 15. Query baud rate (stp, TEST-ONLY) */ + iRet = wmt_core_init_script(init_table_5, ARRAY_SIZE(init_table_5)); + + if (iRet) { + WMT_ERR_FUNC("init_table_5 fail(%d)\n", iRet); + return -14; + } + } + + if (mt6630_co_clock_get() == WMT_CO_CLOCK_EN) { + WMT_INFO_FUNC("co-clock enabled.\n"); + + iRet = wmt_core_init_script(osc_type_table, ARRAY_SIZE(osc_type_table)); + + if (iRet) { + WMT_ERR_FUNC("osc_type_table fail(%d), goes on\n", iRet); + return -15; + } + } else if (mt6630_co_clock_get() == WMT_CO_CLOCK_DCXO) { + WMT_SET_CRYSTAL_TRIMING_CMD[4] = 0x2; + WMT_SET_CRYSTAL_TRIMING_CMD[5] = 0x2; + WMT_SET_CRYSTAL_TRIMING_EVT[4] = 0x2; + WMT_SET_CRYSTAL_TRIMING_EVT[5] = 0x0; + iRet = wmt_core_init_script(set_crystal_timing_script, ARRAY_SIZE(set_crystal_timing_script)); + if (iRet == 0) + WMT_INFO_FUNC("set to Xtal mode suceed\n"); + else + WMT_INFO_FUNC("set to Xtal mode failed, iRet:%d.\n", iRet); + + + } else + WMT_DBG_FUNC("co-clock disabled.\n"); +#if MT6630_BRINGUP + WMT_INFO_FUNC("Bring up period, skip merge interface settings\n"); +#else + +#if (MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT) + iRet = wmt_core_init_script(merge_pcm_table, ARRAY_SIZE(merge_pcm_table)); + + if (iRet) { + WMT_ERR_FUNC("merge_pcm_table fail(%d), goes on\n", iRet); + return -15; + } +#endif +#endif + /* 15. Set FM strap */ + WMT_STRAP_CONF_CMD_FM_COMM[5] = (UINT8) pWmtHifConf->au4StrapConf[0]; + WMT_STRAP_CONF_EVT[5] = (UINT8) pWmtHifConf->au4StrapConf[0]; + iRet = wmt_core_init_script(init_table_5_1, ARRAY_SIZE(init_table_5_1)); + + if (iRet) { + WMT_ERR_FUNC("init_table_5_1 fm mode(%d) fail(%d)\n", + pWmtHifConf->au4StrapConf[0], iRet); + return -16; + } + + WMT_INFO_FUNC("set fm mode (%d) ok\n", pWmtHifConf->au4StrapConf[0]); + +#if CFG_SET_OPT_REG /*set registers */ + iRet = wmt_core_init_script(set_registers, ARRAY_SIZE(set_registers)); + + if (iRet) { + WMT_ERR_FUNC("set_registers fail(%d)", iRet); + return -17; + } +#endif + +#if CFG_WMT_COREDUMP_ENABLE + /*Open Core Dump Function @QC begin */ + mtk_wcn_stp_coredump_flag_ctrl(1); +#endif + + if (mtk_wcn_stp_coredump_flag_get() != 0) { + iRet = wmt_core_init_script(init_table_6, ARRAY_SIZE(init_table_6)); + + if (iRet) { + WMT_ERR_FUNC("init_table_6 core dump setting fail(%d)\n", iRet); + return -18; + } + WMT_INFO_FUNC("enable mt662x firmware coredump\n"); + } else + WMT_INFO_FUNC("disable mt662x firmware coredump\n"); + + ctrlData.ctrlId = WMT_CTRL_SET_STP_DBG_INFO; + ctrlData.au4CtrlData[0] = wmt_ic_ops_mt6630.icId; + ctrlData.au4CtrlData[1] = (size_t) gp_mt6630_info->cChipVersion; + ctrlData.au4CtrlData[2] = (size_t) &gp_mt6630_patch_info; + iRet = wmt_ctrl(&ctrlData); + if (iRet) { + WMT_ERR_FUNC("set dump info fail(%d)\n", iRet); + return -16; + } +#if CFG_WMT_FILTER_MODE_SETTING + wmt_stp_wifi_lte_coex(); +#endif + +#if CFG_WMT_PS_SUPPORT + osal_assert(gp_mt6630_info != NULL); + + if (gp_mt6630_info != NULL) { + if (gp_mt6630_info->bPsmSupport != MTK_WCN_BOOL_FALSE) + wmt_lib_ps_enable(); + else + wmt_lib_ps_disable(); + } +#endif + + return 0; +} + +static INT32 mt6630_sw_deinit(P_WMT_HIF_CONF pWmtHifConf) +{ + WMT_DBG_FUNC(" start\n"); + +#if CFG_WMT_PS_SUPPORT + osal_assert(gp_mt6630_info != NULL); + + if ((gp_mt6630_info != NULL) + && (gp_mt6630_info->bPsmSupport != MTK_WCN_BOOL_FALSE)) { + wmt_lib_ps_disable(); + } +#endif + + gp_mt6630_info = NULL; + + return 0; +} + +static INT32 mt6630_aif_ctrl(WMT_IC_PIN_STATE state, UINT32 flag) +{ + INT32 ret = -1; + +#if MT6630_BRINGUP + ret = 0; + WMT_INFO_FUNC("Bring up period, skip aif settings\n"); +#else + + if ((flag & WMT_LIB_AIF_FLAG_MASK) == WMT_LIB_AIF_FLAG_SHARE) { + WMT_INFO_FUNC("PCM & I2S PIN SHARE\n"); + + WMT_WARN_FUNC("TBD!!"); + ret = 0; + } else { + /*PCM & I2S separate */ + WMT_INFO_FUNC("PCM & I2S PIN SEPARATE\n"); + + switch (state) { + case WMT_IC_AIF_0: + /* BT_PCM_OFF & FM line in/out */ + ret = 0; + break; + + case WMT_IC_AIF_1: + /* BT_PCM_ON & FM line in/out */ + ret = 0; + break; + + case WMT_IC_AIF_2: + /* BT_PCM_OFF & FM I2S */ +#if 0 + val = 0x01110000; + ret = wmt_core_reg_rw_raw(1, 0x80050078, &val, 0x0FFF0000); +#else + ret = 0; + WMT_INFO_FUNC("Bring up period, skip WMT_IC_AIF_2 settings\n"); +#endif + break; + + case WMT_IC_AIF_3: + ret = 0; + break; + + default: + WMT_ERR_FUNC("unsupported state (%d)\n", state); + ret = -1; + break; + } + } + + if (!ret) + WMT_INFO_FUNC("new state(%d) ok\n", state); + else + WMT_WARN_FUNC("new state(%d) fail(%d)\n", state, ret); +#endif + return ret; +} + +static INT32 mt6630_gps_sync_ctrl(WMT_IC_PIN_STATE state, UINT32 flag) +{ +#if 0 + INT32 iRet = -1; + UINT32 uVal = 0; + + if (state == WMT_IC_PIN_MUX) + uVal = 0x1 << 4; + else + uVal = 0x0 << 4; + /*0x80025070[7:4]: 1-A-GPS_SYNC mode, 0-Jtag mode */ +#if MT6630_BRINGUP + iRet = 0; + WMT_INFO_FUNC("Bring up period, skip gps sync settings\n"); + +#else + iRet = wmt_core_reg_rw_raw(1, 0x80025070, &uVal, 0xf << 4); +#endif + if (iRet != 0) + WMT_ERR_FUNC("gps_sync pin ctrl failed, iRet(%d)\n", iRet); +#endif + /* anyway, we return 0 */ + return 0; +} + + +static INT32 mt6630_pin_ctrl(WMT_IC_PIN_ID id, WMT_IC_PIN_STATE state, UINT32 flag) +{ + INT32 ret; + + WMT_DBG_FUNC("ic pin id:%d, state:%d, flag:0x%x\n", id, state, flag); + + ret = -1; + + switch (id) { + case WMT_IC_PIN_AUDIO: + ret = mt6630_aif_ctrl(state, flag); + break; + + case WMT_IC_PIN_EEDI: + WMT_WARN_FUNC("TBD!!"); + /* We just return 0 here, prevent from WMT-FUNC do other register read/write */ + ret = 0; + break; + + case WMT_IC_PIN_EEDO: + WMT_WARN_FUNC("TBD!!"); + /* We just return 0 here, prevent from WMT-FUNC do other register read/write */ + ret = 0; + break; + + case WMT_IC_PIN_GSYNC: + ret = mt6630_gps_sync_ctrl(state, flag); + break; + + default: + break; + } + + WMT_INFO_FUNC("ret = (%d)\n", ret); + + return ret; +} + +INT32 mt6630_co_clock_ctrl(WMT_CO_CLOCK on) +{ + INT32 iRet = 0; + + if ((on >= WMT_CO_CLOCK_DIS) && (on < WMT_CO_CLOCK_MAX)) { + gCoClockEn = on; + } else { + WMT_DBG_FUNC("MT6630: error parameter:%d\n", on); + iRet = -1; + } + + WMT_DBG_FUNC("MT6630: Co-clock type: %d\n", gCoClockEn); + + return iRet; +} + +static MTK_WCN_BOOL mt6630_quick_sleep_flag_get(VOID) +{ + return MTK_WCN_BOOL_TRUE; +} + + +static MTK_WCN_BOOL mt6630_aee_dump_flag_get(VOID) +{ + if (mtk_wcn_stp_coredump_flag_get() == 1) + return MTK_WCN_BOOL_TRUE; + else + return MTK_WCN_BOOL_FALSE; +} + +static MTK_WCN_BOOL mt6630_trigger_stp_assert(VOID) +{ + INT32 iRet = -1; + UINT32 u4Res = 0; + MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; + UINT8 STP_DO_ASSERT_CMD[] = { 0x80, 0x50, 0x0a, 0x00, 'd', 'o', 'c', 'o', 'r', 'e', 'd', 'u', 'm', 'p', 0x00, + 0x00 + }; + + iRet = + wmt_core_tx((PUINT8)&STP_DO_ASSERT_CMD[0], sizeof(STP_DO_ASSERT_CMD), &u4Res, + MTK_WCN_BOOL_TRUE); + if (iRet || (u4Res != sizeof(STP_DO_ASSERT_CMD))) { + WMT_ERR_FUNC("wmt_core:send STP ASSERT COMMAND fail(%d),size(%d)\n", iRet, u4Res); + bRet = MTK_WCN_BOOL_FALSE; + } else + bRet = MTK_WCN_BOOL_TRUE; + return bRet; +} + +WMT_CO_CLOCK mt6630_co_clock_get(VOID) +{ + return gCoClockEn; +} + + + +static INT32 mt6630_ver_check(VOID) +{ + UINT32 hw_ver = 0; + UINT32 fw_ver = 0; + INT32 iret; + const WMT_IC_INFO_S *p_info = NULL; + ULONG ctrlPa1; + ULONG ctrlPa2; + + /* 1. identify chip versions: HVR(HW_VER) and FVR(FW_VER) */ + WMT_LOUD_FUNC("MT6630: before read hw_ver (hw version)\n"); + iret = wmt_core_reg_rw_raw(0, GEN_HVR, &hw_ver, GEN_VER_MASK); + + if (iret) { + WMT_ERR_FUNC("MT6630: read hw_ver fail:%d\n", iret); + return -2; + } + + WMT_LOUD_FUNC("MT6630: before fw_ver (rom version)\n"); + wmt_core_reg_rw_raw(0, GEN_FVR, &fw_ver, GEN_VER_MASK); + + if (iret) { + WMT_ERR_FUNC("MT6630: read fw_ver fail:%d\n", iret); + return -2; + } + + WMT_INFO_FUNC("MT6630: read (hw version)(0x%x), (fw version version)(0x%x)\n", hw_ver, fw_ver); + + p_info = mt6630_find_wmt_ic_info(hw_ver); + + if (p_info == NULL) { + WMT_ERR_FUNC("MT6630: hw_ver(0x%x) find wmt ic info fail\n", hw_ver); + return -3; + } + + WMT_INFO_FUNC("MT6630: wmt ic info: %s.%s (0x%x, patch_ext:%s)\n", + p_info->cChipName, p_info->cChipVersion, + p_info->u4HwVer, p_info->cPatchNameExt); + + /* hw id & version */ + ctrlPa1 = (0x00006630UL << 16) | (hw_ver & 0x0000FFFF); + /* translated fw rom version */ + ctrlPa2 = (fw_ver & 0x0000FFFF); + + iret = wmt_core_ctrl(WMT_CTRL_HWIDVER_SET, &ctrlPa1, &ctrlPa2); + + if (iret) + WMT_WARN_FUNC("MT6630: WMT_CTRL_HWIDVER_SET fail(%d)\n", iret); + + gp_mt6630_info = p_info; + return 0; +} + +static const WMT_IC_INFO_S *mt6630_find_wmt_ic_info(const UINT32 hw_ver) +{ + /* match chipversion with u4HwVer item in mt6630_info_table */ + const UINT32 size = ARRAY_SIZE(mt6630_info_table); + INT32 index; + + /* Leave full match here is a workaround for GPS to distinguish E3/E4 ICs. */ + index = size - 1; + + /* full match */ + while ((index >= 0) + && (hw_ver != mt6630_info_table[index].u4HwVer) /* full match */ + ) { + --index; + } + + if (index >= 0) { + WMT_INFO_FUNC("found ic info(0x%x) by full match! index:%d\n", hw_ver, index); + return &mt6630_info_table[index]; + } + + WMT_WARN_FUNC("find no ic info for (0x%x) by full match!try major num match!\n", hw_ver); + + /* George: The ONLY CORRECT method to find supported hw table. Match MAJOR + * NUM only can help us support future minor hw ECO, or fab switch, etc. + * FULL matching eliminate such flexibility and software package have to be + * updated EACH TIME even when minor hw ECO or fab switch!!! + */ + /* George: reverse the search order to favor newer version products */ + index = size - 1; + + /* major num match */ + while ((index >= 0) + && (MAJORNUM(hw_ver) != MAJORNUM(mt6630_info_table[index].u4HwVer)) + ) { + --index; + } + + if (index >= 0) { + WMT_INFO_FUNC("MT6630: found ic info for hw_ver(0x%x) by major num! index:%d\n", + hw_ver, index); + return &mt6630_info_table[index]; + } + + WMT_ERR_FUNC + ("MT6630: find no ic info for hw_ver(0x%x) by full match nor major num match!\n", + hw_ver); + return NULL; +} + + +static INT32 wmt_stp_init_coex(VOID) +{ + INT32 iRet; + ULONG addr = 0; + WMT_GEN_CONF *pWmtGenConf = NULL; + +#define COEX_WMT 0 + +#if CFG_SUBSYS_COEX_NEED + /* no need for MT6630 */ +#define COEX_BT 1 +#define COEX_WIFI 2 +#define COEX_PTA 3 +#define COEX_MISC 4 +#endif + /*Get wmt config */ + iRet = wmt_core_ctrl(WMT_CTRL_GET_WMT_CONF, &addr, 0); + + if (iRet) { + WMT_ERR_FUNC("ctrl GET_WMT_CONF fail(%d)\n", iRet); + return -2; + } + + WMT_INFO_FUNC("ctrl GET_WMT_CONF ok(0x%08lx)\n", addr); + + pWmtGenConf = (P_WMT_GEN_CONF) addr; + + /*Check if WMT.cfg exists */ + if (pWmtGenConf->cfgExist == 0) { + WMT_INFO_FUNC("cfgExist == 0, skip config chip\n"); + /*if WMT.cfg not existed, still return success and adopt the default value */ + return 0; + } + + + /*Dump the coex-related info */ + WMT_DBG_FUNC("coex_wmt:0x%x\n", pWmtGenConf->coex_wmt_ant_mode); +#if CFG_SUBSYS_COEX_NEED + WMT_DBG_FUNC("coex_bt:0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", + pWmtGenConf->coex_bt_rssi_upper_limit, + pWmtGenConf->coex_bt_rssi_mid_limit, + pWmtGenConf->coex_bt_rssi_lower_limit, + pWmtGenConf->coex_bt_pwr_high, + pWmtGenConf->coex_bt_pwr_mid, pWmtGenConf->coex_bt_pwr_low); + WMT_DBG_FUNC("coex_wifi:0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", + pWmtGenConf->coex_wifi_rssi_upper_limit, + pWmtGenConf->coex_wifi_rssi_mid_limit, + pWmtGenConf->coex_wifi_rssi_lower_limit, + pWmtGenConf->coex_wifi_pwr_high, + pWmtGenConf->coex_wifi_pwr_mid, pWmtGenConf->coex_wifi_pwr_low); + WMT_DBG_FUNC("coex_ext_pta:0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", + pWmtGenConf->coex_ext_pta_hi_tx_tag, + pWmtGenConf->coex_ext_pta_hi_rx_tag, + pWmtGenConf->coex_ext_pta_lo_tx_tag, + pWmtGenConf->coex_ext_pta_lo_rx_tag, + pWmtGenConf->coex_ext_pta_sample_t1, + pWmtGenConf->coex_ext_pta_sample_t2, + pWmtGenConf->coex_ext_pta_wifi_bt_con_trx); + WMT_DBG_FUNC("coex_misc:0x%x 0x%x 0x%x\n", + pWmtGenConf->coex_misc_ext_pta_on, pWmtGenConf->coex_misc_ext_feature_set); +#endif + + /*command adjustion due to WMT.cfg */ + coex_table[COEX_WMT].cmd[5] = pWmtGenConf->coex_wmt_ant_mode; + + if (gWmtDbgLvl >= WMT_LOG_DBG) { + wmt_core_dump_data(&coex_table[COEX_WMT].cmd[0], + coex_table[COEX_WMT].str, coex_table[COEX_WMT].cmdSz); + } +#if CFG_SUBSYS_COEX_NEED + coex_table[COEX_BT].cmd[9] = pWmtGenConf->coex_bt_rssi_upper_limit; + coex_table[COEX_BT].cmd[10] = pWmtGenConf->coex_bt_rssi_mid_limit; + coex_table[COEX_BT].cmd[11] = pWmtGenConf->coex_bt_rssi_lower_limit; + coex_table[COEX_BT].cmd[12] = pWmtGenConf->coex_bt_pwr_high; + coex_table[COEX_BT].cmd[13] = pWmtGenConf->coex_bt_pwr_mid; + coex_table[COEX_BT].cmd[14] = pWmtGenConf->coex_bt_pwr_low; + + if (gWmtDbgLvl >= WMT_LOG_DBG) { + wmt_core_dump_data(&coex_table[COEX_BT].cmd[0], + coex_table[COEX_BT].str, coex_table[COEX_BT].cmdSz); + } + + coex_table[COEX_WIFI].cmd[10] = pWmtGenConf->coex_wifi_rssi_upper_limit; + coex_table[COEX_WIFI].cmd[11] = pWmtGenConf->coex_wifi_rssi_mid_limit; + coex_table[COEX_WIFI].cmd[12] = pWmtGenConf->coex_wifi_rssi_lower_limit; + coex_table[COEX_WIFI].cmd[13] = pWmtGenConf->coex_wifi_pwr_high; + coex_table[COEX_WIFI].cmd[14] = pWmtGenConf->coex_wifi_pwr_mid; + coex_table[COEX_WIFI].cmd[15] = pWmtGenConf->coex_wifi_pwr_low; + + if (gWmtDbgLvl >= WMT_LOG_DBG) { + wmt_core_dump_data(&coex_table[COEX_WIFI].cmd[0], + coex_table[COEX_WIFI].str, coex_table[COEX_WIFI].cmdSz); + } + + coex_table[COEX_PTA].cmd[5] = pWmtGenConf->coex_ext_pta_hi_tx_tag; + coex_table[COEX_PTA].cmd[6] = pWmtGenConf->coex_ext_pta_hi_rx_tag; + coex_table[COEX_PTA].cmd[7] = pWmtGenConf->coex_ext_pta_lo_tx_tag; + coex_table[COEX_PTA].cmd[8] = pWmtGenConf->coex_ext_pta_lo_rx_tag; + coex_table[COEX_PTA].cmd[9] = ((pWmtGenConf->coex_ext_pta_sample_t1 & 0xff00) >> 8); + coex_table[COEX_PTA].cmd[10] = ((pWmtGenConf->coex_ext_pta_sample_t1 & 0x00ff) >> 0); + coex_table[COEX_PTA].cmd[11] = ((pWmtGenConf->coex_ext_pta_sample_t2 & 0xff00) >> 8); + coex_table[COEX_PTA].cmd[12] = ((pWmtGenConf->coex_ext_pta_sample_t2 & 0x00ff) >> 0); + coex_table[COEX_PTA].cmd[13] = pWmtGenConf->coex_ext_pta_wifi_bt_con_trx; + + if (gWmtDbgLvl >= WMT_LOG_DBG) { + wmt_core_dump_data(&coex_table[COEX_PTA].cmd[0], + coex_table[COEX_PTA].str, coex_table[COEX_PTA].cmdSz); + } + + osal_memcpy(&coex_table[COEX_MISC].cmd[5], &pWmtGenConf->coex_misc_ext_pta_on, + sizeof(pWmtGenConf->coex_misc_ext_pta_on)); + osal_memcpy(&coex_table[COEX_MISC].cmd[9], &pWmtGenConf->coex_misc_ext_feature_set, + sizeof(pWmtGenConf->coex_misc_ext_feature_set)); + + wmt_core_dump_data(&coex_table[COEX_MISC].cmd[0], coex_table[COEX_MISC].str, + coex_table[COEX_MISC].cmdSz); +#endif + + iRet = wmt_core_init_script(coex_table, ARRAY_SIZE(coex_table)); + + return iRet; +} + +#if 0 +static INT32 mt6630_set_sdio_driving(void) +{ + INT32 ret = 0; + + UINT32 addr = 0; + WMT_GEN_CONF *pWmtGenConf; + UINT32 drv_val = 0; + + /*Get wmt config */ + ret = wmt_core_ctrl(WMT_CTRL_GET_WMT_CONF, &addr, 0); + + if (ret) { + WMT_ERR_FUNC("ctrl GET_WMT_CONF fail(%d)\n", ret); + return -1; + } + + WMT_INFO_FUNC("ctrl GET_WMT_CONF ok(0x%x)\n", addr); + + pWmtGenConf = (P_WMT_GEN_CONF) addr; + + /*Check if WMT.cfg exists */ + if (pWmtGenConf->cfgExist == 0) { + WMT_INFO_FUNC("cfgExist == 0, skip config chip\n"); + /*if WMT.cfg not existed, still return success and adopt the default value */ + return 0; + } + + drv_val = pWmtGenConf->sdio_driving_cfg; + + /*Dump the sdio driving related info */ + WMT_INFO_FUNC("sdio driving:0x%x\n", drv_val); + + sdio_driving_table[0].cmd[12] = (UINT8) ((drv_val & 0x00000077UL) >> 0); /* DAT0 and DAT1 */ + sdio_driving_table[0].cmd[13] = (UINT8) ((drv_val & 0x00007700UL) >> 8); /* DAT2 and DAT3 */ + sdio_driving_table[0].cmd[14] = (UINT8) ((drv_val & 0x00070000UL) >> 16); /* CMD */ + + ret = wmt_core_init_script(sdio_driving_table, ARRAY_SIZE(sdio_driving_table)); + + return ret; +} +#endif + +#if CFG_WMT_CRYSTAL_TIMING_SET +static INT32 mt6630_crystal_triming_set(VOID) +{ + INT32 iRet = 0; + PUINT8 pbuf = NULL; + UINT32 bufLen = 0; + WMT_CTRL_DATA ctrlData; + UINT32 uCryTimOffset = 0x6D; + MTK_WCN_BOOL bIsNvramExist = MTK_WCN_BOOL_FALSE; + INT8 cCrystalTimingOffset = 0x0; + UINT8 cCrystalTiming = 0x0; + INT32 iCrystalTiming = 0x0; + MTK_WCN_BOOL bIsCrysTrimEnabled = MTK_WCN_BOOL_FALSE; + UINT32 u4Res; + + bIsNvramExist = MTK_WCN_BOOL_FALSE; + ctrlData.ctrlId = WMT_CTRL_CRYSTAL_TRIMING_GET; + ctrlData.au4CtrlData[0] = (size_t) "/data/nvram/APCFG/APRDEB/WIFI"; + ctrlData.au4CtrlData[1] = (size_t) &pbuf; + ctrlData.au4CtrlData[2] = (size_t) &bufLen; + + iRet = wmt_ctrl(&ctrlData); + + if (iRet != 0) { + WMT_ERR_FUNC("MT6630: WMT_CTRL_CRYSTAL_TRIMING_GET fail:%d\n", iRet); + bIsNvramExist = MTK_WCN_BOOL_FALSE; + bIsCrysTrimEnabled = MTK_WCN_BOOL_FALSE; + cCrystalTimingOffset = 0x0; + cCrystalTiming = 0x0; + iRet = -1; + } else { + WMT_DBG_FUNC("MT6630: nvram pBuf(%p), bufLen(%d)\n", pbuf, bufLen); + + if (bufLen < (uCryTimOffset + 1)) { + WMT_ERR_FUNC + ("MT6630: nvram len(%d) too short, crystalTimging value offset(%d)\n", + bufLen, uCryTimOffset); + bIsNvramExist = MTK_WCN_BOOL_FALSE; + bIsCrysTrimEnabled = MTK_WCN_BOOL_FALSE; + cCrystalTimingOffset = 0x0; + cCrystalTiming = 0x0; + } else { + bIsNvramExist = MTK_WCN_BOOL_TRUE; + cCrystalTimingOffset = *(pbuf + uCryTimOffset); + + if (cCrystalTimingOffset & 0x80) { + bIsCrysTrimEnabled = MTK_WCN_BOOL_TRUE; + cCrystalTimingOffset = (UINT8) cCrystalTimingOffset & 0x7f; + } + + WMT_DBG_FUNC("cCrystalTimingOffset (%d), bIsCrysTrimEnabled(%d)\n", + cCrystalTimingOffset, bIsCrysTrimEnabled); + } + + ctrlData.ctrlId = WMT_CTRL_CRYSTAL_TRIMING_PUT; + ctrlData.au4CtrlData[0] = (size_t) "/data/nvram/APCFG/APRDEB/WIFI"; + iRet = wmt_ctrl(&ctrlData); + + if (iRet != 0) { + WMT_ERR_FUNC("MT6630: WMT_CTRL_CRYSTAL_TRIMING_PUT fail:%d\n", iRet); + iRet = -2; + } else { + WMT_DBG_FUNC("MT6630: WMT_CTRL_CRYSTAL_TRIMING_PUT succeed\n"); + } + } + + if ((bIsNvramExist == MTK_WCN_BOOL_TRUE) && (bIsCrysTrimEnabled == MTK_WCN_BOOL_TRUE)) { + /*get CrystalTiming value before set it */ + iRet = + wmt_core_tx(get_crystal_timing_script[0].cmd, + get_crystal_timing_script[0].cmdSz, &u4Res, MTK_WCN_BOOL_FALSE); + + if (iRet || (u4Res != get_crystal_timing_script[0].cmdSz)) { + WMT_ERR_FUNC("WMT-CORE: write (%s) iRet(%d) cmd len err(%d, %d)\n", + get_crystal_timing_script[0].str, iRet, u4Res, + get_crystal_timing_script[0].cmdSz); + iRet = -3; + goto done; + } + + /* EVENT BUF */ + osal_memset(get_crystal_timing_script[0].evt, 0, + get_crystal_timing_script[0].evtSz); + iRet = + wmt_core_rx(get_crystal_timing_script[0].evt, + get_crystal_timing_script[0].evtSz, &u4Res); + + if (iRet || (u4Res != get_crystal_timing_script[0].evtSz)) { + WMT_ERR_FUNC("WMT-CORE: read (%s) iRet(%d) evt len err(rx:%d, exp:%d)\n", + get_crystal_timing_script[0].str, iRet, u4Res, + get_crystal_timing_script[0].evtSz); + mtk_wcn_stp_dbg_dump_package(); + iRet = -4; + goto done; + } + + iCrystalTiming = WMT_GET_CRYSTAL_TRIMING_EVT[5] & 0x7f; + + if (cCrystalTimingOffset & 0x40) { + /*nagative offset value */ + iCrystalTiming = iCrystalTiming + cCrystalTimingOffset - 128; + } else { + iCrystalTiming += cCrystalTimingOffset; + } + + WMT_DBG_FUNC("iCrystalTiming (0x%x)\n", iCrystalTiming); + if (iCrystalTiming > 0x7f) + cCrystalTiming = 0x7f; + else if (iCrystalTiming < 0) + cCrystalTiming = 0; + else + cCrystalTiming = iCrystalTiming; + WMT_DBG_FUNC("cCrystalTiming (0x%x)\n", cCrystalTiming); + /* set_crystal_timing_script */ + /*set crystal trim value command*/ + WMT_SET_CRYSTAL_TRIMING_CMD[4] = 0x1; + WMT_SET_CRYSTAL_TRIMING_EVT[4] = 0x1; + + WMT_SET_CRYSTAL_TRIMING_CMD[5] = cCrystalTiming; + WMT_GET_CRYSTAL_TRIMING_EVT[5] = cCrystalTiming; + + iRet = + wmt_core_init_script(set_crystal_timing_script, + ARRAY_SIZE(set_crystal_timing_script)); + + if (iRet) { + WMT_ERR_FUNC("set_crystal_timing_script fail(%d)\n", iRet); + iRet = -5; + } else { + WMT_DBG_FUNC("set crystal timing value (0x%x) succeed\n", + WMT_SET_CRYSTAL_TRIMING_CMD[5]); + iRet = + wmt_core_init_script(get_crystal_timing_script, + ARRAY_SIZE(get_crystal_timing_script)); + + if (iRet) { + WMT_ERR_FUNC("get_crystal_timing_script fail(%d)\n", iRet); + iRet = -6; + } else { + WMT_INFO_FUNC("succeed, updated crystal timing value (0x%x)\n", + WMT_GET_CRYSTAL_TRIMING_EVT[5]); + iRet = 0x0; + } + } + } + +done: + return iRet; +} +#endif + +#if CFG_WMT_MULTI_PATCH +static INT32 mt6630_patch_info_prepare(VOID) +{ + INT32 iRet = -1; + WMT_CTRL_DATA ctrlData; + + ctrlData.ctrlId = WMT_CTRL_PATCH_SEARCH; + iRet = wmt_ctrl(&ctrlData); + + return iRet; +} + + +static INT32 mt6630_patch_dwn(UINT32 index) +{ + INT32 iRet = -1; + P_WMT_PATCH patchHdr = NULL; + PUINT8 pBuf = NULL; + PUINT8 pPatchBuf = NULL; + UINT32 patchSize; + UINT32 fragSeq; + UINT32 fragNum; + UINT16 fragSize = 0; + UINT16 cmdLen; + UINT32 offset; + UINT32 u4Res; + UINT8 evtBuf[8]; + UINT8 addressevtBuf[12]; + UINT8 addressByte[4]; + PINT8 cDataTime = NULL; + /*PINT8 cPlat = NULL; */ + UINT16 u2HwVer = 0; + UINT16 u2SwVer = 0; + UINT32 u4PatchVer = 0; + UINT32 patchSizePerFrag = 0; + WMT_CTRL_DATA ctrlData; + + /*1.check hardware information */ + if (gp_mt6630_info == NULL) { + WMT_ERR_FUNC("null gp_mt6630_info!\n"); + return -1; + } + + osal_memset(gFullPatchName, 0, osal_sizeof(gFullPatchName)); + + ctrlData.ctrlId = WMT_CTRL_GET_PATCH_INFO; + ctrlData.au4CtrlData[0] = index + 1; + ctrlData.au4CtrlData[1] = (size_t) &gFullPatchName; + ctrlData.au4CtrlData[2] = (size_t) &addressByte; + iRet = wmt_ctrl(&ctrlData); + WMT_INFO_FUNC("the %d time valid patch found: (%s)\n", index + 1, gFullPatchName); + + /* <2.2> read patch content */ + ctrlData.ctrlId = WMT_CTRL_GET_PATCH; + ctrlData.au4CtrlData[0] = (size_t) NULL; + ctrlData.au4CtrlData[1] = (size_t) &gFullPatchName; + ctrlData.au4CtrlData[2] = (size_t) &pBuf; + ctrlData.au4CtrlData[3] = (size_t) &patchSize; + iRet = wmt_ctrl(&ctrlData); + + if (iRet) { + WMT_ERR_FUNC("wmt_core: WMT_CTRL_GET_PATCH fail:%d\n", iRet); + iRet -= 1; + goto done; + } + + /* |<-BCNT_PATCH_BUF_HEADROOM(8) bytes dummy allocated->|<-patch file->| */ + /* patch file with header: + * |<-patch header: 28 Bytes->|<-patch body: X Bytes ----->| + */ + pPatchBuf = osal_malloc(patchSize); + if (pPatchBuf == NULL) { + WMT_ERR_FUNC("vmalloc pPatchBuf for patch download fail\n"); + return -2; + } + osal_memcpy(pPatchBuf, pBuf, patchSize); + /* check patch file information */ + + patchHdr = (P_WMT_PATCH) pPatchBuf; + + cDataTime = patchHdr->ucDateTime; + u2HwVer = patchHdr->u2HwVer; + u2SwVer = patchHdr->u2SwVer; + u4PatchVer = patchHdr->u4PatchVer; + + osal_memcpy(&gp_mt6630_patch_info, patchHdr, osal_sizeof(WMT_PATCH)); + + /*cPlat = &patchHdr->ucPLat[0]; */ + + cDataTime[15] = '\0'; + + if (index == 0) { + WMT_INFO_FUNC("Combo Patch:Build Time(%s)Hw(0x%x) Sw(0x%x) Ph(0x%04x)Platform(%c%c%c%c)\n", + cDataTime, ((u2HwVer & 0x00ff) << 8) | ((u2HwVer & 0xff00) >> 8), + ((u2SwVer & 0x00ff) << 8) | ((u2SwVer & 0xff00) >> 8), + ((u4PatchVer & 0xff000000) >> 24) | ((u4PatchVer & 0x00ff0000) >> 16), + patchHdr->ucPLat[0], patchHdr->ucPLat[1], patchHdr->ucPLat[2], patchHdr->ucPLat[3]); + } + + /* remove patch header: + * |<-patch body: X Bytes (X=patchSize)--->| + */ + if (patchSize < sizeof(WMT_PATCH)) { + WMT_ERR_FUNC("error patch size\n"); + iRet = -1; + goto done; + } + patchSize -= sizeof(WMT_PATCH); + pPatchBuf += sizeof(WMT_PATCH); + patchSizePerFrag = DEFAULT_PATCH_FRAG_SIZE; + /* reserve 1st patch cmd space before patch body + * |<-WMT_CMD: 5Bytes->|<-patch body: X Bytes (X=patchSize)----->| + */ + pPatchBuf -= sizeof(WMT_PATCH_CMD); + + fragNum = patchSize / patchSizePerFrag; + fragNum += ((fragNum * patchSizePerFrag) == patchSize) ? 0 : 1; + + WMT_DBG_FUNC("patch size(%d) fragNum(%d)\n", patchSize, fragNum); + + + /*send wmt part patch address command */ + iRet = + wmt_core_tx((PUINT8) &WMT_PATCH_ADDRESS_CMD[0], sizeof(WMT_PATCH_ADDRESS_CMD), &u4Res, + MTK_WCN_BOOL_FALSE); + + if (iRet || (u4Res != sizeof(WMT_PATCH_ADDRESS_CMD))) { + WMT_ERR_FUNC("wmt_core:wmt patch address CMD fail(%d),size(%d)\n", iRet, u4Res); + iRet -= 1; + goto done; + } + + osal_memset(addressevtBuf, 0, sizeof(addressevtBuf)); + iRet = wmt_core_rx(addressevtBuf, sizeof(WMT_PATCH_ADDRESS_EVT), &u4Res); + + if (iRet || (u4Res != sizeof(WMT_PATCH_ADDRESS_EVT))) { + WMT_ERR_FUNC("wmt_core:wmt patch address EVT fail(%d),size(%d)\n", iRet, u4Res); + mtk_wcn_stp_dbg_dump_package(); + iRet -= 1; + goto done; + } +#if CFG_CHECK_WMT_RESULT + + if (osal_memcmp(addressevtBuf, WMT_PATCH_ADDRESS_EVT, osal_sizeof(WMT_PATCH_ADDRESS_EVT)) != + 0) { + WMT_ERR_FUNC("wmt_core: write WMT_PATCH_ADDRESS_CMD status fail\n"); + iRet -= 1; + goto done; + } +#endif + + /*send part patch address command */ + osal_memcpy(&WMT_PATCH_P_ADDRESS_CMD[12], addressByte, osal_sizeof(addressByte)); + WMT_INFO_FUNC("4 bytes address command:0x%02x,0x%02x,0x%02x,0x%02x", + WMT_PATCH_P_ADDRESS_CMD[12], + WMT_PATCH_P_ADDRESS_CMD[13], + WMT_PATCH_P_ADDRESS_CMD[14], WMT_PATCH_P_ADDRESS_CMD[15]); + iRet = + wmt_core_tx((PUINT8) &WMT_PATCH_P_ADDRESS_CMD[0], sizeof(WMT_PATCH_P_ADDRESS_CMD), + &u4Res, MTK_WCN_BOOL_FALSE); + + if (iRet || (u4Res != sizeof(WMT_PATCH_P_ADDRESS_CMD))) { + WMT_ERR_FUNC("wmt_core:wmt part patch address CMD fail(%d),size(%d),index(%d)\n", + iRet, u4Res, index); + iRet -= 1; + goto done; + } + + osal_memset(addressevtBuf, 0, sizeof(addressevtBuf)); + iRet = wmt_core_rx(addressevtBuf, sizeof(WMT_PATCH_P_ADDRESS_EVT), &u4Res); + + if (iRet || (u4Res != sizeof(WMT_PATCH_P_ADDRESS_EVT))) { + WMT_ERR_FUNC("wmt_core:wmt patch address EVT fail(%d),size(%d),index(%d)\n", iRet, + u4Res, index); + mtk_wcn_stp_dbg_dump_package(); + iRet -= 1; + goto done; + } +#if CFG_CHECK_WMT_RESULT + + if (osal_memcmp(addressevtBuf, WMT_PATCH_P_ADDRESS_EVT, osal_sizeof(WMT_PATCH_ADDRESS_EVT)) + != 0) { + WMT_ERR_FUNC("wmt_core: write WMT_PATCH_ADDRESS_CMD status fail,index(%d)\n", + index); + iRet -= 1; + goto done; + } +#endif + + /* send all fragments */ + offset = sizeof(WMT_PATCH_CMD); + fragSeq = 0; + + while (fragSeq < fragNum) { + WMT_DBG_FUNC("patch size(%d) fragNum(%d)\n", patchSize, fragNum); + + if (fragSeq == (fragNum - 1)) { + /* last fragment */ + fragSize = patchSize - fragSeq * patchSizePerFrag; + WMT_PATCH_CMD[4] = WMT_PATCH_FRAG_LAST; + } else { + fragSize = patchSizePerFrag; + WMT_PATCH_CMD[4] = (fragSeq == 0) ? WMT_PATCH_FRAG_1ST : WMT_PATCH_FRAG_MID; + } + + /* update length field in CMD:flag+frag */ + cmdLen = 1 + fragSize; + osal_memcpy(&WMT_PATCH_CMD[2], &cmdLen, 2); + /* copy patch CMD to buf (overwrite last 5-byte in prev frag) */ + osal_memcpy(pPatchBuf + offset - sizeof(WMT_PATCH_CMD), WMT_PATCH_CMD, + sizeof(WMT_PATCH_CMD)); + + iRet = + wmt_core_tx(pPatchBuf + offset - sizeof(WMT_PATCH_CMD), + fragSize + sizeof(WMT_PATCH_CMD), &u4Res, MTK_WCN_BOOL_FALSE); + + if (iRet || (u4Res != fragSize + sizeof(WMT_PATCH_CMD))) { + WMT_ERR_FUNC("wmt_core: write fragSeq(%d) size(%zu, %d) fail(%d)\n", fragSeq, + fragSize + sizeof(WMT_PATCH_CMD), u4Res, iRet); + iRet -= 1; + break; + } + + WMT_DBG_FUNC("wmt_core: write fragSeq(%d) size(%zu, %d) ok\n", + fragSeq, fragSize + sizeof(WMT_PATCH_CMD), u4Res); + + osal_memset(evtBuf, 0, sizeof(evtBuf)); + /* iRet = (*kal_stp_rx)(evtBuf, sizeof(WMT_PATCH_EVT), &u4Res); */ + iRet = wmt_core_rx(evtBuf, sizeof(WMT_PATCH_EVT), &u4Res); + + if (iRet || (u4Res != sizeof(WMT_PATCH_EVT))) { + WMT_ERR_FUNC("wmt_core: read WMT_PATCH_EVT length(%zu, %d) fail(%d)\n", + sizeof(WMT_PATCH_EVT), u4Res, iRet); + mtk_wcn_stp_dbg_dump_package(); + iRet -= 1; + break; + } +#if CFG_CHECK_WMT_RESULT + + if (osal_memcmp(evtBuf, WMT_PATCH_EVT, sizeof(WMT_PATCH_EVT)) != 0) { + WMT_ERR_FUNC("rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%zu):[%02X,%02X,%02X,%02X,%02X]\n", + u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], + sizeof(WMT_PATCH_EVT), WMT_PATCH_EVT[0], WMT_PATCH_EVT[1], + WMT_PATCH_EVT[2], WMT_PATCH_EVT[3], WMT_PATCH_EVT[4]); + iRet -= 1; + break; + } +#endif + WMT_DBG_FUNC("wmt_core: read WMT_PATCH_EVT length(%zu, %d) ok\n", + sizeof(WMT_PATCH_EVT), u4Res); + offset += patchSizePerFrag; + ++fragSeq; + } + + WMT_INFO_FUNC("wmt_core: patch dwn:%d frag(%d, %d) %s\n", + iRet, fragSeq, fragSize, (!iRet && (fragSeq == fragNum)) ? "ok" : "fail"); + + if (fragSeq != fragNum) + iRet -= 1; + +done: + if (patchHdr != NULL) { + osal_free(patchHdr); + pPatchBuf = NULL; + patchHdr = NULL; + } + /* WMT_CTRL_FREE_PATCH always return 0 */ + /* wmt_core_ctrl(WMT_CTRL_FREE_PATCH, NULL, NULL); */ + ctrlData.ctrlId = WMT_CTRL_FREE_PATCH; + ctrlData.au4CtrlData[0] = index + 1; + wmt_ctrl(&ctrlData); + + return iRet; +} + +#else +static INT32 mt6630_patch_dwn(VOID) +{ + INT32 iRet = -1; + P_WMT_PATCH patchHdr; + PUINT8 pbuf; + UINT32 patchSize; + UINT32 fragSeq; + UINT32 fragNum; + UINT16 fragSize = 0; + UINT16 cmdLen; + UINT32 offset; + UINT32 u4Res; + UINT8 evtBuf[8]; + PINT8 cDataTime = NULL; + /*PINT8 cPlat = NULL; */ + UINT16 u2HwVer = 0; + UINT16 u2SwVer = 0; + UINT32 u4PatchVer = 0; + UINT32 patchSizePerFrag = 0; + WMT_CTRL_DATA ctrlData; + + /*1.check hardware information */ + if (gp_mt6630_info == NULL) { + WMT_ERR_FUNC("null gp_mt6630_info!\n"); + return -1; + } + /* <2> search patch and read patch content */ + /* <2.1> search patch */ + ctrlData.ctrlId = WMT_CTRL_PATCH_SEARCH; + iRet = wmt_ctrl(&ctrlData); + + if (iRet == 0) { + /* patch with correct Hw Ver Major Num found */ + ctrlData.ctrlId = WMT_CTRL_GET_PATCH_NAME; + ctrlData.au4CtrlData[0] = (size_t) &gFullPatchName; + iRet = wmt_ctrl(&ctrlData); + + WMT_INFO_FUNC("valid patch found: (%s)\n", gFullPatchName); + /* <2.2> read patch content */ + ctrlData.ctrlId = WMT_CTRL_GET_PATCH; + ctrlData.au4CtrlData[0] = (size_t) NULL; + ctrlData.au4CtrlData[1] = (size_t) &gFullPatchName; + + } else { + iRet -= 1; + return iRet; + } + + ctrlData.au4CtrlData[2] = (size_t) &pbuf; + ctrlData.au4CtrlData[3] = (size_t) &patchSize; + iRet = wmt_ctrl(&ctrlData); + + if (iRet) { + WMT_ERR_FUNC("wmt_core: WMT_CTRL_GET_PATCH fail:%d\n", iRet); + iRet -= 1; + goto done; + } + + /* |<-BCNT_PATCH_BUF_HEADROOM(8) bytes dummy allocated->|<-patch file->| */ + pbuf += BCNT_PATCH_BUF_HEADROOM; + /* patch file with header: + * |<-patch header: 28 Bytes->|<-patch body: X Bytes ----->| + */ + patchHdr = (P_WMT_PATCH) pbuf; + /* check patch file information */ + + cDataTime = patchHdr->ucDateTime; + u2HwVer = patchHdr->u2HwVer; + u2SwVer = patchHdr->u2SwVer; + u4PatchVer = patchHdr->u4PatchVer; + + osal_memcpy(&gp_mt6630_patch_info, patchHdr, osal_sizeof(WMT_PATCH)); + /*cPlat = &patchHdr->ucPLat[0]; */ + + cDataTime[15] = '\0'; + WMT_INFO_FUNC("===========================================\n"); + WMT_INFO_FUNC("[Combo Patch] Built Time = %s\n", cDataTime); + WMT_INFO_FUNC("[Combo Patch] Hw Ver = 0x%x\n", + ((u2HwVer & 0x00ff) << 8) | ((u2HwVer & 0xff00) >> 8)); + WMT_INFO_FUNC("[Combo Patch] Sw Ver = 0x%x\n", + ((u2SwVer & 0x00ff) << 8) | ((u2SwVer & 0xff00) >> 8)); + WMT_INFO_FUNC("[Combo Patch] Ph Ver = 0x%04x\n", + ((u4PatchVer & 0xff000000) >> 24) | ((u4PatchVer & 0x00ff0000) >> 16)); + WMT_INFO_FUNC("[Combo Patch] Platform = %c%c%c%c\n", patchHdr->ucPLat[0], + patchHdr->ucPLat[1], patchHdr->ucPLat[2], patchHdr->ucPLat[3]); + WMT_INFO_FUNC("===========================================\n"); + + /* remove patch header: + * |<-patch body: X Bytes (X=patchSize)--->| + */ + if (patchSize < sizeof(WMT_PATCH)) { + WMT_ERR_FUNC("error patch size\n"); + return -1; + } + patchSize -= sizeof(WMT_PATCH); + pbuf += sizeof(WMT_PATCH); + patchSizePerFrag = DEFAULT_PATCH_FRAG_SIZE; + /* reserve 1st patch cmd space before patch body + * |<-WMT_CMD: 5Bytes->|<-patch body: X Bytes (X=patchSize)----->| + */ + pbuf -= sizeof(WMT_PATCH_CMD); + + fragNum = patchSize / patchSizePerFrag; + fragNum += ((fragNum * patchSizePerFrag) == patchSize) ? 0 : 1; + + WMT_DBG_FUNC("patch size(%d) fragNum(%d)\n", patchSize, fragNum); + + + /* send all fragments */ + offset = sizeof(WMT_PATCH_CMD); + fragSeq = 0; + + while (fragSeq < fragNum) { + WMT_DBG_FUNC("patch size(%d) fragNum(%d)\n", patchSize, fragNum); + + if (fragSeq == (fragNum - 1)) { + /* last fragment */ + fragSize = patchSize - fragSeq * patchSizePerFrag; + WMT_PATCH_CMD[4] = WMT_PATCH_FRAG_LAST; + } else { + fragSize = patchSizePerFrag; + WMT_PATCH_CMD[4] = (fragSeq == 0) ? WMT_PATCH_FRAG_1ST : WMT_PATCH_FRAG_MID; + } + + /* update length field in CMD:flag+frag */ + cmdLen = 1 + fragSize; + osal_memcpy(&WMT_PATCH_CMD[2], &cmdLen, 2); + /* copy patch CMD to buf (overwrite last 5-byte in prev frag) */ + osal_memcpy(pbuf + offset - sizeof(WMT_PATCH_CMD), WMT_PATCH_CMD, + sizeof(WMT_PATCH_CMD)); + + /* iRet = (*kal_stp_tx)(pbuf + offset - sizeof(WMT_PATCH_CMD), + * fragSize + sizeof(WMT_PATCH_CMD), &u4Res); + */ + iRet = + wmt_core_tx(pbuf + offset - sizeof(WMT_PATCH_CMD), + fragSize + sizeof(WMT_PATCH_CMD), &u4Res, MTK_WCN_BOOL_FALSE); + + if (iRet || (u4Res != fragSize + sizeof(WMT_PATCH_CMD))) { + WMT_ERR_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) fail(%d)\n", fragSeq, + fragSize + sizeof(WMT_PATCH_CMD), u4Res, iRet); + iRet -= 1; + break; + } + + WMT_DBG_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) ok\n", + fragSeq, fragSize + sizeof(WMT_PATCH_CMD), u4Res); + + osal_memset(evtBuf, 0, sizeof(evtBuf)); + /* iRet = (*kal_stp_rx)(evtBuf, sizeof(WMT_PATCH_EVT), &u4Res); */ + iRet = wmt_core_rx(evtBuf, sizeof(WMT_PATCH_EVT), &u4Res); + + if (iRet || (u4Res != sizeof(WMT_PATCH_EVT))) { + WMT_ERR_FUNC("wmt_core: read WMT_PATCH_EVT length(%d, %d) fail(%d)\n", + sizeof(WMT_PATCH_EVT), u4Res, iRet); + mtk_wcn_stp_dbg_dump_package(); + iRet -= 1; + break; + } +#if CFG_CHECK_WMT_RESULT + + if (osal_memcmp(evtBuf, WMT_PATCH_EVT, sizeof(WMT_PATCH_EVT)) != 0) { + WMT_ERR_FUNC("rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%d):[%02X,%02X,%02X,%02X,%02X]\n", + u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], + sizeof(WMT_PATCH_EVT), WMT_PATCH_EVT[0], WMT_PATCH_EVT[1], + WMT_PATCH_EVT[2], WMT_PATCH_EVT[3], WMT_PATCH_EVT[4]); + iRet -= 1; + break; + } +#endif + WMT_DBG_FUNC("wmt_core: read WMT_PATCH_EVT length(%d, %d) ok\n", + sizeof(WMT_PATCH_EVT), u4Res); + offset += patchSizePerFrag; + ++fragSeq; + } + + WMT_INFO_FUNC("wmt_core: patch dwn:%d frag(%d, %d) %s\n", + iRet, fragSeq, fragSize, (!iRet && (fragSeq == fragNum)) ? "ok" : "fail"); + + if (fragSeq != fragNum) + iRet -= 1; + +done: + /* WMT_CTRL_FREE_PATCH always return 0 */ + wmt_core_ctrl(WMT_CTRL_FREE_PATCH, NULL, NULL); + + return iRet; +} + +#endif + +#if CFG_WMT_FILTER_MODE_SETTING +static INT32 wmt_stp_wifi_lte_coex(VOID) +{ + INT32 iRet; + ULONG addr = 0; + WMT_GEN_CONF *pWmtGenConf = NULL; + + /*Get wmt config */ + iRet = wmt_core_ctrl(WMT_CTRL_GET_WMT_CONF, &addr, 0); + if (iRet) { + WMT_ERR_FUNC("ctrl GET_WMT_CONF fail(%d)\n", iRet); + return -2; + } + WMT_INFO_FUNC("ctrl GET_WMT_CONF ok(0x%08lx)\n", addr); + + pWmtGenConf = (P_WMT_GEN_CONF) addr; + + /*Check if WMT.cfg exists */ + if (pWmtGenConf->cfgExist == 0) { + WMT_INFO_FUNC("cfgExist == 0, skip config chip\n"); + /*if WMT.cfg not existed, still return success and adopt the default value */ + return 0; + } + + if (pWmtGenConf->coex_wmt_filter_mode == 0) { + /*add WMT_COXE_CONFIG_EXT_COMPONENT_OPCODE command for 2G4 xLNA demand*/ + if (pWmtGenConf->coex_wmt_ext_component) { + WMT_INFO_FUNC("coex_wmt_ext_component:0x%x\n", pWmtGenConf->coex_wmt_ext_component); + set_wifi_lte_coex_table_0[0].cmd[5] = pWmtGenConf->coex_wmt_ext_component; + } + iRet = + wmt_core_init_script(set_wifi_lte_coex_table_0, + ARRAY_SIZE(set_wifi_lte_coex_table_0)); + if (iRet) + WMT_ERR_FUNC("wmt_core:set_wifi_lte_coex_table_0 fail(%d)\n", iRet); + else + WMT_INFO_FUNC("wmt_core:set_wifi_lte_coex_table_0 ok\n"); + } + + return iRet; +} +#endif diff --git a/drivers/misc/mediatek/connectivity/common/common_main/core/wmt_ic_6632.c b/drivers/misc/mediatek/connectivity/common/common_main/core/wmt_ic_6632.c new file mode 100644 index 0000000000000000000000000000000000000000..20847f00a4a1511d8ecbf272f98b2fc1ed829f11 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/core/wmt_ic_6632.c @@ -0,0 +1,1989 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + + + + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +#ifdef DFT_TAG +#undef DFT_TAG +#endif +#define DFT_TAG "[WMT-IC]" +#define CFG_IC_MT6632 1 + +#define MT6632_BRINGUP 0 +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include "osal_typedef.h" +#include "wmt_ic.h" +#include "wmt_core.h" +#include "wmt_lib.h" +#include "stp_core.h" + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +#define DEFAULT_PATCH_FRAG_SIZE (1000) +#define WMT_PATCH_FRAG_1ST (0x1) +#define WMT_PATCH_FRAG_MID (0x2) +#define WMT_PATCH_FRAG_LAST (0x3) + +#define CFG_CHECK_WMT_RESULT (1) +/* BT Port 2 Feature. this command does not need after coex command is downconfirmed by LC, */ +#define CFG_WMT_BT_PORT2 (0) + +#define CFG_SET_OPT_REG (0) +#define CFG_WMT_I2S_DBGUART_SUPPORT (0) +#define CFG_SET_OPT_REG_SWLA (0) +#define CFG_SET_OPT_REG_MCUCLK (0) +#define CFG_SET_OPT_REG_MCUIRQ (0) + +#define CFG_SUBSYS_COEX_NEED 0 + +#define CFG_WMT_COREDUMP_ENABLE 0 + +#ifdef CONFIG_MTK_COMBO_CHIP_DEEP_SLEEP_SUPPORT +INT32 g_deep_sleep_flag = 1; +#else +INT32 g_deep_sleep_flag; +#endif + +#if CFG_WMT_LTE_COEX_HANDLING +#define CFG_WMT_FILTER_MODE_SETTING (1) +#else +#define CFG_WMT_FILTER_MODE_SETTING (0) +#endif +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +static UINT8 gFullPatchName[NAME_MAX + 1]; +static const WMT_IC_INFO_S *gp_mt6632_info; +static WMT_PATCH gp_mt6632_patch_info; +static WMT_CO_CLOCK gCoClockEn = WMT_CO_CLOCK_DIS; + +static UINT8 WMT_QUERY_BAUD_CMD[] = { 0x01, 0x04, 0x01, 0x00, 0x02 }; +static UINT8 WMT_QUERY_BAUD_EVT_115200[] = { + 0x02, 0x04, 0x06, 0x00, 0x00, 0x02, 0x00, 0xC2, 0x01, 0x00 }; +static UINT8 WMT_QUERY_BAUD_EVT_X[] = { + 0x02, 0x04, 0x06, 0x00, 0x00, 0x02, 0xAA, 0xAA, 0xAA, 0xBB }; +static UINT8 WMT_QUERY_STP_CMD[] = { 0x01, 0x04, 0x01, 0x00, 0x04 }; +static UINT8 WMT_QUERY_STP_EVT_DEFAULT[] = { + 0x02, 0x04, 0x06, 0x00, 0x00, 0x04, 0x11, 0x00, 0x00, 0x00 }; +static UINT8 WMT_QUERY_STP_EVT_UART[] = { + 0x02, 0x04, 0x06, 0x00, 0x00, 0x04, 0xDF, 0x0E, 0x68, 0x01 }; +static UINT8 WMT_SET_BAUD_CMD_X[] = { 0x01, 0x04, 0x05, 0x00, 0x01, 0xAA, 0xAA, 0xAA, 0xBB }; +static UINT8 WMT_SET_BAUD_EVT[] = { 0x02, 0x04, 0x02, 0x00, 0x00, 0x01 }; +static UINT8 WMT_SET_WAKEUP_WAKE_CMD_RAW[] = { 0xFF }; +static UINT8 WMT_SET_WAKEUP_WAKE_EVT[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x03 }; +static UINT8 WMT_PATCH_CMD[] = { 0x01, 0x01, 0x00, 0x00, 0x00 }; +static UINT8 WMT_PATCH_EVT[] = { 0x02, 0x01, 0x01, 0x00, 0x00 }; + +#ifdef CONFIG_MTK_COMBO_CHIP_DEEP_SLEEP_SUPPORT +UINT8 WMT_DEEP_SLEEP_CMD[] = { 0x01, 0x02, 0x02, 0x00, 0x11, 0x00 }; +UINT8 WMT_DEEP_SLEEP_EVT[] = { 0x02, 0x02, 0x01, 0x00, 0x00 }; +#endif + +UINT8 WMT_CLOCK_RATE_CMD[] = {0x01, 0x0A, 0x04, 0x00, 0x09, 0x01, 0x00, 0x00}; +UINT8 WMT_CLOCK_RATE_EVT[] = {0x02, 0x0A, 0x01, 0x00, 0x00}; +UINT8 WMT_PATCH_DWN_USE_DMA_CMD[] = {0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, + 0x01, 0xc0, 0x0a, 0x01, 0x02, 0x04, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF}; +UINT8 WMT_PATCH_DWN_USE_DMA_EVT[] = {0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01}; + +static UINT8 WMT_RESET_CMD[] = { 0x01, 0x07, 0x01, 0x00, 0x04 }; +static UINT8 WMT_RESET_EVT[] = { 0x02, 0x07, 0x01, 0x00, 0x00 }; + +#if CFG_WMT_BT_PORT2 +static UINT8 WMT_BTP2_CMD[] = { 0x01, 0x10, 0x03, 0x00, 0x01, 0x03, 0x01 }; +static UINT8 WMT_BTP2_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; +#endif + +static UINT8 WMT_PATCH_ADDRESS_CMD[] = { 0x01, 0x01, 0x05, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00}; + +static UINT8 WMT_PATCH_ADDRESS_EVT[] = { 0x02, 0x01, 0x01, 0x00, 0x00}; + +/*coex cmd/evt++*/ +static UINT8 WMT_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x01, 0x00 }; +static UINT8 WMT_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; + +#if CFG_SUBSYS_COEX_NEED +static UINT8 WMT_BT_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x0B, + 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, + 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0xAA +}; +static UINT8 WMT_BT_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; + +static UINT8 WMT_WIFI_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x0C, + 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0xAA +}; +static UINT8 WMT_WIFI_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; + +static UINT8 WMT_PTA_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x0A, + 0x00, 0x04, + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xEE, 0xFF, 0xFF, 0xFE +}; +static UINT8 WMT_PTA_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; + +static UINt8 WMT_MISC_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x09, + 0x00, 0x05, + 0xAA, 0xAA, 0xAA, 0xAA, + 0xBB, 0xBB, 0xBB, 0xBB +}; +static UINT8 WMT_MISC_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; +#else +static UINT8 WMT_COEX_WIFI_PATH_CMD[] = { 0x01, 0x10, 0x03, 0x00, 0x1A, 0x0F, 0x00 }; +static UINT8 WMT_COEX_WIFI_PATH_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; + +static UINT8 WMT_COEX_EXT_ELAN_GAIN_P1_CMD[] = { 0x01, 0x10, 0x12, 0x00, 0x1B, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; +static UINT8 WMT_COEX_EXT_ELAN_GAIN_P1_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; +#endif + +/*coex cmd/evt--*/ +static UINT8 WMT_SET_STP_CMD[] = { 0x01, 0x04, 0x05, 0x00, 0x03, 0xDF, 0x0E, 0x68, 0x01 }; +static UINT8 WMT_SET_STP_EVT[] = { 0x02, 0x04, 0x02, 0x00, 0x00, 0x03 }; + +static UINT8 WMT_SET_SDIO_RETRY_CMD[] = { 0x01, 0x02, 0x02, 0x00, 0x18, 0x01 }; +static UINT8 WMT_SET_SDIO_RETRY_EVT[] = { 0x02, 0x02, 0x01, 0x00, 0x01 }; + +/* to get full dump when f/w assert */ +static UINT8 WMT_CORE_DUMP_LEVEL_04_CMD[] = { + 0x1, 0x0F, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +static UINT8 WMT_CORE_DUMP_LEVEL_04_EVT[] = { 0x2, 0x0F, 0x01, 0x00, 0x00 }; + +static UINT8 WMT_CORE_CO_CLOCK_CMD[] = { 0x1, 0x0A, 0x02, 0x00, 0x08, 0x03 }; +static UINT8 WMT_CORE_CO_CLOCK_EVT[] = { 0x2, 0x0A, 0x01, 0x00, 0x00 }; + + +#if (MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT) + + +static UINT8 WMT_SET_DAI_MODE_REG_CMD[] = { 0x01, 0x08, 0x1c, 0x00 /*length */ + , 0x01 /* op: w */ + , 0x01 /*type: reg */ + , 0x00 /*rev */ + , 0x02 /*2 registers */ + , 0x54, 0x30, 0x02, 0x81 /*addr:0x81023054 */ + , 0x00, 0x00, 0x33, 0x33 /*value:0x33330000 */ + , 0x00, 0x00, 0xff, 0xff /*mask:0xffff0000 */ + , 0x00, 0x53, 0x02, 0x80 /*addr:0x80025300 */ + , 0x04, 0x00, 0x00, 0x00 /*value:0x00000004 */ + , 0x04, 0x00, 0x00, 0x00 /*mask:0x00000004 */ +}; + +static UINT8 WMT_SET_DAI_MODE_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ + , 0x00 /*S: 0 */ + , 0x00 /*type: reg */ + , 0x00 /*rev */ + , 0x02 /*2 registers */ +}; + + +#endif + + +#if CFG_SET_OPT_REG_SWLA /* enable swla: eesk(7) eecs(8) oscen(19) sck0(24) scs0(25) */ +static UINT8 WMT_SET_SWLA_REG_CMD[] = { 0x01, 0x08, 0x1C, 0x00 /*length */ + , 0x01 /* op: w */ + , 0x01 /*type: reg */ + , 0x00 /*rev */ + , 0x02 /*2 registers */ + , 0x10, 0x01, 0x05, 0x80 /*addr:0x80050110 */ + , 0x10, 0x10, 0x01, 0x00 /*value:0x00011010 */ + , 0xF0, 0xF0, 0x0F, 0x00 /*mask:0x000FF0F0 */ + , 0x40, 0x01, 0x05, 0x80 /*addr:0x80050140 */ + , 0x00, 0x10, 0x01, 0x00 /*value:0x00011000 */ + , 0x00, 0xF0, 0x0F, 0x00 /*mask:0x000FF000 */ +}; + +static UINT8 WMT_SET_SWLA_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ + , 0x00 /*S: 0 */ + , 0x00 /*type: reg */ + , 0x00 /*rev */ + , 0x02 /*2 registers */ +}; +#endif + +#if CFG_SET_OPT_REG_MCUCLK /* enable mcu clk: antsel_4, eedi */ +static UINT8 WMT_SET_MCUCLK_REG_CMD[] = { 0x01, 0x08, (4 + 12 * 4), 0x00 /*length */ + , 0x01 /* op: w */ + , 0x01 /* type: reg */ + , 0x00 /* rev */ + , 0x04 /* 4 registers */ + , 0x00, 0x04, 0x00, 0x80 /* addr:0x8000 0400 */ + , 0x00, 0x14, 0x00, 0x00 /* value:0x0000 1400(osc, hclk), 0x0000 1501(PLL, en) */ + , 0xFF, 0xFF, 0x00, 0x00 /* mask:0x0000 FFFF */ + , 0x80, 0x01, 0x05, 0x80 /* addr:0x8005 0180 */ + , 0x12, 0x13, 0x00, 0x00 /* value:0x0000 1312(osc, hclk), 0x0000 1a19(PLL, en) */ + , 0xFF, 0xFF, 0x00, 0x00 /* mask:0x0000 FFFF */ + , 0x00, 0x01, 0x05, 0x80 /* addr:0x8005 0100 */ + , 0x00, 0x00, 0x02, 0x00 /* value:0x0002 0000 */ + , 0x00, 0x00, 0x0F, 0x00 /* mask:0x000F 0000 */ + , 0x10, 0x01, 0x05, 0x80 /* addr:0x8005 0110 */ + , 0x02, 0x00, 0x00, 0x00 /* value:0x0000 0002 */ + , 0x0F, 0x00, 0x00, 0x00 /* mask:0x0000 000F */ +}; + +static UINT8 WMT_SET_MCUCLK_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ + , 0x00 /* S: 0 */ + , 0x00 /* type: reg */ + , 0x00 /* rev */ + , 0x04 /* 4 registers */ +}; +#endif + +#if CFG_WMT_I2S_DBGUART_SUPPORT /* register write for debug uart */ +static UINT8 WMT_SET_DBGUART_REG_CMD[] = { 0x01, 0x08, 0x1C, 0x00 /*length */ + , 0x01 /* op: w */ + , 0x01 /*type: reg */ + , 0x00 /*rev */ + , 0x02 /*2 registers */ + , 0x30, 0x01, 0x05, 0x80 /*addr:0x80050130 */ + , 0x00, 0x00, 0x00, 0x00 /*value:0x00000000 */ + , 0xF0, 0x0F, 0x00, 0x00 /*mask:0x00000FF0 */ + , 0x40, 0x01, 0x05, 0x80 /*addr:0x80050140 */ + , 0x00, 0x01, 0x00, 0x00 /*value:0x00000100 */ + , 0x00, 0x01, 0x00, 0x00 /*mask:0x00000100 */ +}; + +static UINT8 WMT_SET_DBGUART_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ + , 0x00 /*S: 0 */ + , 0x00 /*type: reg */ + , 0x00 /*rev */ + , 0x02 /*2 registers */ +}; +#endif + +#if CFG_SET_OPT_REG_MCUIRQ /* enable mcu irq: antsel_4, wlan_act */ +static UINT8 WMT_SET_MCUIRQ_REG_CMD[] = { 0x01, 0x08, (4 + 12 * 4), 0x00 /*length */ + , 0x01 /* op: w */ + , 0x01 /* type: reg */ + , 0x00 /* rev */ + , 0x04 /* 4 registers */ + , 0x00, 0x04, 0x00, 0x80 /* addr:0x8000_0400 */ + , 0x03, 0x14, 0x00, 0x00 /* value:0x0000_1403 check confg debug flag 3 low word */ + , 0xFF, 0xFF, 0x00, 0x00 /* mask:0x0000_FFFF */ + /* cirq_int_n */ + , 0x10, 0x01, 0x05, 0x80 /* addr:0x8005_0110 */ + , 0x02, 0x00, 0x00, 0x00 /* value:0x0000_0002 set EEDI as cirq_int_n debug flag (monitor flag2) */ + , 0x07, 0x00, 0x00, 0x00 /* mask:0x0000_0007 */ + , 0x00, 0x01, 0x05, 0x80 /* addr:0x8005_0100 */ + , 0x00, 0x00, 0x02, 0x00 /* value:0x0002_0000 (ANTSEL4=>monitor flag 0, ahb_x2_gt_ck debug flag) */ + , 0x00, 0x00, 0x07, 0x00 /* mask:0x0007_0000 */ + /* 1. ARM irq_b, monitor flag 0 */ + , 0x80, 0x01, 0x05, 0x80 /* addr:0x8005_0180 */ + , 0x1F, 0x1E, 0x00, 0x00 /* value:0x0000_1E1F check mcusys debug flag */ + , 0x7F, 0x7F, 0x00, 0x00 /* mask:0x0000_7F7F */ +}; + +static UINT8 WMT_SET_MCUIRQ_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ + , 0x00 /* S: 0 */ + , 0x00 /* type: reg */ + , 0x00 /* rev */ + , 0x04 /* 5 registers */ +}; +#endif + +static UINT8 WMT_SET_CRYSTAL_TRIMING_CMD[] = { 0x01, 0x12, 0x02, 0x00, 0x01, 0x00 }; +static UINT8 WMT_SET_CRYSTAL_TRIMING_EVT[] = { 0x02, 0x12, 0x02, 0x00, 0x01, 0x00 }; + +/* +* static UINT8 WMT_GET_CRYSTAL_TRIMING_CMD[] = { 0x01, 0x12, 0x02, 0x00, 0x00, 0x00 }; +* static UINT8 WMT_GET_CRYSTAL_TRIMING_EVT[] = { 0x02, 0x12, 0x02, 0x00, 0x00, 0x00 }; +*/ + + +#if CFG_WMT_FILTER_MODE_SETTING +static UINT8 WMT_COEX_EXT_COMPONENT_CMD[] = { 0x01, 0x10, 0x03, 0x00, 0x0d, 0x00, 0x00 }; + +static UINT8 WMT_COEX_FILTER_SPEC_CMD_TEST[] = { 0x01, 0x10, 0x45, 0x00, 0x11, + 0x00, 0x00, 0x01, 0x00, 0x11, + 0x11, 0x16, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x63, 0x63, 0x63, + 0x00, 0x39, 0x43, 0x63, 0x63, + 0x02, 0x02, 0x03, 0x00, 0x01, + 0x01, 0x01, 0x01, 0x0e, 0x0e, + 0x0e, 0x00, 0x0a, 0x0c, 0x0e, + 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +static UINT8 WMT_COEX_LTE_FREQ_IDX_TABLE_CMD[] = { 0x01, 0x10, 0x21, 0x00, 0x12, + 0xfc, 0x08, 0x15, 0x09, 0x2e, + 0x09, 0x47, 0x09, 0xc4, 0x09, + 0xd4, 0x09, 0xe3, 0x09, 0x5a, + 0x0a, 0x14, 0x09, 0x2d, 0x09, + 0x46, 0x09, 0x60, 0x09, 0xd3, + 0x09, 0xe2, 0x09, 0x59, 0x0a, + 0x8B, 0x0a +}; + +static UINT8 WMT_COEX_LTE_CHAN_UNSAFE_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x13, 0x00 }; + +#if CFG_WMT_LTE_ENABLE_MSGID_MAPPING +#else +static UINT8 WMT_COEX_IS_LTE_L_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x21, 0x01 }; +#endif + +static UINT8 WMT_COEX_IS_LTE_PROJ_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x15, 0x01 }; + +static UINT8 WMT_COEX_SPLIT_MODE_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; +#endif + +static struct init_script init_table_1_2[] = { + INIT_CMD(WMT_QUERY_BAUD_CMD, WMT_QUERY_BAUD_EVT_115200, "query baud 115200"), + INIT_CMD(WMT_QUERY_STP_CMD, WMT_QUERY_STP_EVT_DEFAULT, "query stp default"), + INIT_CMD(WMT_SET_BAUD_CMD_X, WMT_SET_BAUD_EVT, "set baud rate"), +}; + + +static struct init_script init_table_2[] = { + INIT_CMD(WMT_QUERY_BAUD_CMD, WMT_QUERY_BAUD_EVT_X, "query baud X"), +}; + +static struct init_script init_table_3[] = { + INIT_CMD(WMT_RESET_CMD, WMT_RESET_EVT, "wmt reset"), +#if CFG_WMT_BT_PORT2 + INIT_CMD(WMT_BTP2_CMD, WMT_BTP2_EVT, "set bt port2"), +#endif +}; + +#ifdef CONFIG_MTK_COMBO_CHIP_DEEP_SLEEP_SUPPORT +static struct init_script init_deep_sleep_script[] = { + INIT_CMD(WMT_DEEP_SLEEP_CMD, WMT_DEEP_SLEEP_EVT, "chip deep sleep"), +}; +#endif + +static struct init_script clock_rate_modify[] = { + INIT_CMD(WMT_CLOCK_RATE_CMD, WMT_CLOCK_RATE_EVT, "clock rate modify"), +}; + +/* WMT_CLOCK_RATE_CMD[6] = 0xD0, promote the XTAL(26MHz) rate to 208MHz */ +static struct init_script clock_rate_pro_and_use_dma[] = { + INIT_CMD(WMT_CLOCK_RATE_CMD, WMT_CLOCK_RATE_EVT, "clock rate modify"), + INIT_CMD(WMT_PATCH_DWN_USE_DMA_CMD, WMT_PATCH_DWN_USE_DMA_EVT, "patch dwn use DMA"), +}; + + +static struct init_script set_crystal_timing_script[] = { + INIT_CMD(WMT_SET_CRYSTAL_TRIMING_CMD, WMT_SET_CRYSTAL_TRIMING_EVT, + "set crystal trim value"), +}; +/* +* static struct init_script get_crystal_timing_script[] = { +* INIT_CMD(WMT_GET_CRYSTAL_TRIMING_CMD, WMT_GET_CRYSTAL_TRIMING_EVT, +* "get crystal trim value"), +* }; +*/ + +static struct init_script init_table_4[] = { + INIT_CMD(WMT_SET_STP_CMD, WMT_SET_STP_EVT, "set stp"), +}; + +static struct init_script set_sdio_retry_script[] = { + INIT_CMD(WMT_SET_SDIO_RETRY_CMD, WMT_SET_SDIO_RETRY_EVT, "set sdio retry"), +}; + +static struct init_script init_table_5[] = { + INIT_CMD(WMT_QUERY_STP_CMD, WMT_QUERY_STP_EVT_UART, "query stp uart"), + INIT_CMD(WMT_QUERY_BAUD_CMD, WMT_QUERY_BAUD_EVT_X, "query baud X"), +}; + +static struct init_script init_table_6[] = { + INIT_CMD(WMT_CORE_DUMP_LEVEL_04_CMD, WMT_CORE_DUMP_LEVEL_04_EVT, "setup core dump level"), +}; + + +#if defined(CFG_SET_OPT_REG) && CFG_SET_OPT_REG +static struct init_script set_registers[] = { + /* INIT_CMD(WMT_SET_GPS_REG_CMD, WMT_SET_GPS_REG_EVT, "set wmt registers"), */ + /* INIT_CMD(WMT_SET_SDIODRV_REG_CMD, WMT_SET_SDIODRV_REG_EVT, "set SDIO driving registers") */ +#if CFG_WMT_I2S_DBGUART_SUPPORT + INIT_CMD(WMT_SET_DBGUART_REG_CMD, WMT_SET_DBGUART_REG_EVT, "set debug uart registers"), +#endif +#if CFG_SET_OPT_REG_SWLA + INIT_CMD(WMT_SET_SWLA_REG_CMD, WMT_SET_SWLA_REG_EVT, "set swla registers"), +#endif +#if CFG_SET_OPT_REG_MCUCLK + INIT_CMD(WMT_SET_MCUCLK_REG_CMD, WMT_SET_MCUCLK_REG_EVT, "set mcuclk dbg registers"), +#endif +#if CFG_SET_OPT_REG_MCUIRQ + INIT_CMD(WMT_SET_MCUIRQ_REG_CMD, WMT_SET_MCUIRQ_REG_EVT, "set mcu irq dbg registers"), +#endif +}; +#endif + +static struct init_script coex_table[] = { + INIT_CMD(WMT_COEX_SETTING_CONFIG_CMD, WMT_COEX_SETTING_CONFIG_EVT, "coex_wmt"), + +#if CFG_SUBSYS_COEX_NEED +/* no need in MT6632 */ + INIT_CMD(WMT_BT_COEX_SETTING_CONFIG_CMD, WMT_BT_COEX_SETTING_CONFIG_EVT, "coex_bt"), + INIT_CMD(WMT_WIFI_COEX_SETTING_CONFIG_CMD, WMT_WIFI_COEX_SETTING_CONFIG_EVT, "coex_wifi"), + INIT_CMD(WMT_PTA_COEX_SETTING_CONFIG_CMD, WMT_PTA_COEX_SETTING_CONFIG_EVT, "coex_ext_pta"), + INIT_CMD(WMT_MISC_COEX_SETTING_CONFIG_CMD, WMT_MISC_COEX_SETTING_CONFIG_EVT, "coex_misc"), +#else + INIT_CMD(WMT_COEX_WIFI_PATH_CMD, WMT_COEX_WIFI_PATH_EVT, "wifi path"), + INIT_CMD(WMT_COEX_EXT_ELAN_GAIN_P1_CMD, WMT_COEX_EXT_ELAN_GAIN_P1_EVT, "wifi elan gain p1"), +#endif +}; + +static struct init_script osc_type_table[] = { + INIT_CMD(WMT_CORE_CO_CLOCK_CMD, WMT_CORE_CO_CLOCK_EVT, "osc_type"), +}; + +#if (MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT) +static struct init_script merge_pcm_table[] = { + INIT_CMD(WMT_SET_DAI_MODE_REG_CMD, WMT_SET_DAI_MODE_REG_EVT, "DAI_PAD"), +}; +#endif + +#if CFG_WMT_FILTER_MODE_SETTING +#if CFG_WMT_LTE_ENABLE_MSGID_MAPPING +static struct init_script set_wifi_lte_coex_table_0[] = { + INIT_CMD(WMT_COEX_EXT_COMPONENT_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi lte ext component"), + INIT_CMD(WMT_COEX_FILTER_SPEC_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi lte coex filter"), + INIT_CMD(WMT_COEX_LTE_FREQ_IDX_TABLE_CMD, WMT_COEX_SPLIT_MODE_EVT, + "wifi lte freq id table"), + INIT_CMD(WMT_COEX_LTE_CHAN_UNSAFE_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi lte unsafe channel"), + INIT_CMD(WMT_COEX_IS_LTE_PROJ_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi coex is lte project"), +}; +#else +static struct init_script set_wifi_lte_coex_table_0[] = { + INIT_CMD(WMT_COEX_EXT_COMPONENT_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi lte ext component"), + INIT_CMD(WMT_COEX_FILTER_SPEC_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi lte coex filter"), + INIT_CMD(WMT_COEX_LTE_FREQ_IDX_TABLE_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi lte freq id table"), + INIT_CMD(WMT_COEX_LTE_CHAN_UNSAFE_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi lte unsafe channel"), + INIT_CMD(WMT_COEX_IS_LTE_L_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi coex is L branch"), + INIT_CMD(WMT_COEX_IS_LTE_PROJ_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi coex is lte project"), +}; +#endif +#endif + +/* MT6632 Chip Version and Info Table */ +static const WMT_IC_INFO_S mt6632_info_table[] = { + { + .u4HwVer = 0x8A00, + .cChipName = WMT_IC_NAME_MT6632, + .cChipVersion = WMT_IC_VER_E1, + .cPatchNameExt = WMT_IC_PATCH_E1_EXT, + .bWorkWithoutPatch = MTK_WCN_BOOL_FALSE, + .bPsmSupport = MTK_WCN_BOOL_TRUE, + }, + { + .u4HwVer = 0x8A10, + .cChipName = WMT_IC_NAME_MT6632, + .cChipVersion = WMT_IC_VER_E2, + .cPatchNameExt = WMT_IC_PATCH_E2_EXT, + .bWorkWithoutPatch = MTK_WCN_BOOL_FALSE, + .bPsmSupport = MTK_WCN_BOOL_TRUE, + }, + { + .u4HwVer = 0x8A11, + .cChipName = WMT_IC_NAME_MT6632, + .cChipVersion = WMT_IC_VER_E3, + .cPatchNameExt = WMT_IC_PATCH_E2_EXT, + .bWorkWithoutPatch = MTK_WCN_BOOL_FALSE, + .bPsmSupport = MTK_WCN_BOOL_TRUE, + }, + { + .u4HwVer = 0x8B11, + .cChipName = WMT_IC_NAME_MT6632, + .cChipVersion = WMT_IC_VER_E4, + .cPatchNameExt = WMT_IC_PATCH_E2_EXT, + .bWorkWithoutPatch = MTK_WCN_BOOL_FALSE, + .bPsmSupport = MTK_WCN_BOOL_TRUE, + } +}; + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +static INT32 mt6632_sw_init(P_WMT_HIF_CONF pWmtHifConf); + +static INT32 mt6632_sw_deinit(P_WMT_HIF_CONF pWmtHifConf); + +static INT32 mt6632_pin_ctrl(WMT_IC_PIN_ID id, WMT_IC_PIN_STATE state, UINT32 flag); + +static INT32 mt6632_aif_ctrl(WMT_IC_PIN_STATE state, UINT32 flag); + +static INT32 mt6632_ver_check(VOID); + +static const WMT_IC_INFO_S *mt6632_find_wmt_ic_info(const UINT32 hw_ver); + +static INT32 wmt_stp_init_coex(VOID); + +static INT32 mt6632_patch_dwn(UINT32 index); +static INT32 mt6632_patch_info_prepare(VOID); + +static INT32 mt6632_co_clock_ctrl(WMT_CO_CLOCK on); +static WMT_CO_CLOCK mt6632_co_clock_get(VOID); + +/*static INT32 mt6632_crystal_triming_set(VOID);*/ + + +static MTK_WCN_BOOL mt6632_quick_sleep_flag_get(VOID); + +static MTK_WCN_BOOL mt6632_aee_dump_flag_get(VOID); +#if 0 +/* set sdio driving */ +static UINT8 WMT_SET_SDIO_DRV_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ + , 0x01 /* op: w */ + , 0x01 /*type: reg */ + , 0x00 /*rev */ + , 0x01 /*1 registers */ + , 0x50, 0x00, 0x05, 0x80 /*addr:0x80050050 */ + , 0x44, 0x44, 0x04, 0x00 /*value:0x00044444 */ + , 0x77, 0x77, 0x07, 0x00 /*mask:0x00077777 */ +}; + +static UINT8 WMT_SET_SDIO_DRV_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ + , 0x00 /*S: 0 */ + , 0x00 /*type: reg */ + , 0x00 /*rev */ + , 0x01 /*1 registers */ +}; + +static INT32 mt6632_set_sdio_driving(void); +static struct init_script sdio_driving_table[] = { + INIT_CMD(WMT_SET_SDIO_DRV_REG_CMD, WMT_SET_SDIO_DRV_REG_EVT, "sdio_driving"), +}; + +#endif +static MTK_WCN_BOOL mt6632_trigger_stp_assert(VOID); +#ifdef CONFIG_MTK_COMBO_CHIP_DEEP_SLEEP_SUPPORT +static MTK_WCN_BOOL mt6632_deep_sleep_ctrl(INT32 value); +static INT32 wmt_stp_get_deep_sleep_flag_from_cfg(VOID); +#endif + +#if CFG_WMT_FILTER_MODE_SETTING +static INT32 wmt_stp_wifi_lte_coex(VOID); +#endif + + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/* MT6632 Operation Function Table */ +WMT_IC_OPS wmt_ic_ops_mt6632 = { + .icId = 0x6632, + .sw_init = mt6632_sw_init, + .sw_deinit = mt6632_sw_deinit, + .ic_pin_ctrl = mt6632_pin_ctrl, + .ic_ver_check = mt6632_ver_check, + .co_clock_ctrl = mt6632_co_clock_ctrl, + .is_quick_sleep = mt6632_quick_sleep_flag_get, + .is_aee_dump_support = mt6632_aee_dump_flag_get, + .trigger_stp_assert = mt6632_trigger_stp_assert, +#ifdef CONFIG_MTK_COMBO_CHIP_DEEP_SLEEP_SUPPORT + .deep_sleep_ctrl = mt6632_deep_sleep_ctrl, +#else + .deep_sleep_ctrl = NULL, +#endif + +}; + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +static INT32 mt6632_sw_init(P_WMT_HIF_CONF pWmtHifConf) +{ + INT32 iRet = -1; + UINT32 u4Res = 0; + UINT8 evtBuf[256]; + ULONG ctrlPa1; + ULONG ctrlPa2; + UINT32 hw_ver; + UINT32 patch_num = 0; + UINT32 patch_index = 0; + WMT_CTRL_DATA ctrlData; +#ifdef CONFIG_MTK_COMBO_CHIP_DEEP_SLEEP_SUPPORT + INT32 deep_sleep_flag_from_cfg; +#endif + WMT_DBG_FUNC(" start\n"); + + osal_assert(gp_mt6632_info != NULL); + + if ((gp_mt6632_info == NULL) + || (pWmtHifConf == NULL) + ) { + WMT_ERR_FUNC("null pointers: gp_mt6632_info(0x%p), pWmtHifConf(0x%p)\n", + gp_mt6632_info, pWmtHifConf); + return -1; + } + + hw_ver = gp_mt6632_info->u4HwVer; + + /* 4 <3.1> start init for sdio */ + + /* 4 <3.2> start init for uart */ + if (pWmtHifConf->hifType == WMT_HIF_UART) { + /* init variable fields for script execution */ + osal_memcpy(&WMT_SET_BAUD_CMD_X[5], &pWmtHifConf->au4HifConf[0], + osal_sizeof(UINT32)); + WMT_SET_BAUD_CMD_X[8] = (UINT8) 0x00; /* 0xC0 MTK Flow Control *//* no flow control */ + osal_memcpy(&WMT_QUERY_BAUD_EVT_X[6], &pWmtHifConf->au4HifConf[0], + osal_sizeof(UINT32)); + WMT_QUERY_BAUD_EVT_X[9] = (UINT8) 0x00; /* 0xC0 MTK Flow Control *//* no flow control */ + + /* 3. Query chip baud rate (TEST-ONLY) */ + /* 4. Query chip STP options (TEST-ONLY) */ + /* 5. Change chip baud rate: t_baud */ + /* WMT_DBG_FUNC("WMT-CORE: init_table_1_2 set chip baud:%d", pWmtHifConf->au4HifConf[0]); */ + iRet = wmt_core_init_script(init_table_1_2, ARRAY_SIZE(init_table_1_2)); + + if (iRet) { + WMT_ERR_FUNC("init_table_1_2 fail(%d)\n", iRet); + osal_assert(0); + return -2; + } + + /* 6. Set host baudrate and flow control */ + ctrlPa1 = pWmtHifConf->au4HifConf[0]; + ctrlPa2 = 0; + iRet = wmt_core_ctrl(WMT_CTRL_HOST_BAUDRATE_SET, &ctrlPa1, &ctrlPa2); + + if (iRet) { + WMT_ERR_FUNC("change baudrate(%d) fail(%d)\n", pWmtHifConf->au4HifConf[0], + iRet); + return -3; + } + + WMT_INFO_FUNC("WMT-CORE: change baudrate(%d) ok\n", pWmtHifConf->au4HifConf[0]); + + /* 7. Wake up chip and check event */ +/* iRet = (*kal_stp_tx_raw)(&WMT_SET_WAKEUP_WAKE_CMD_RAW[0], 1, &u4Res); */ + iRet = + wmt_core_tx((PUINT8)&WMT_SET_WAKEUP_WAKE_CMD_RAW[0], 1, &u4Res, + MTK_WCN_BOOL_TRUE); + + if (iRet || (u4Res != 1)) { + WMT_ERR_FUNC("write raw iRet(%d) written(%d)\n", iRet, u4Res); + return -4; + } + + osal_memset(evtBuf, 0, osal_sizeof(evtBuf)); + iRet = wmt_core_rx(evtBuf, osal_sizeof(WMT_SET_WAKEUP_WAKE_EVT), &u4Res); +#ifdef CFG_DUMP_EVT + WMT_DBG_FUNC("WAKEUP_WAKE_EVT read len %d [%02x,%02x,%02x,%02x,%02x,%02x]\n", + (INT32) u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], + evtBuf[5]); +#endif + + if (iRet || (u4Res != osal_sizeof(WMT_SET_WAKEUP_WAKE_EVT))) { + WMT_ERR_FUNC("read WAKEUP_WAKE_EVT fail(%d)\n", iRet); + mtk_wcn_stp_dbg_dump_package(); + return -5; + } + /* WMT_DBG_FUNC("WMT-CORE: read WMT_SET_WAKEUP_WAKE_EVT ok"); */ + +#if CFG_CHECK_WMT_RESULT + + if (osal_memcmp + (evtBuf, WMT_SET_WAKEUP_WAKE_EVT, osal_sizeof(WMT_SET_WAKEUP_WAKE_EVT)) != 0) { + WMT_ERR_FUNC("WMT-CORE: write WMT_SET_WAKEUP_WAKE_CMD_RAW status fail\n"); + return -6; + } +#endif + + /* 8. Query baud rate (TEST-ONLY) */ + iRet = wmt_core_init_script(init_table_2, osal_array_size(init_table_2)); + + if (iRet) { + WMT_ERR_FUNC("init_table_2 fail(%d)\n", iRet); + return -7; + } + } + + /* 9. download patch */ + /* 9.1 Let launcher to search patch info */ + iRet = mt6632_patch_info_prepare(); + + if (iRet) { + WMT_ERR_FUNC("patch info perpare fail(%d)\n", iRet); + return -8; + } + + /* 9.2 Read patch number */ + ctrlPa1 = 0; + ctrlPa2 = 0; + wmt_core_ctrl(WMT_CTRL_GET_PATCH_NUM, &ctrlPa1, &ctrlPa2); + patch_num = ctrlPa1; + WMT_DBG_FUNC("patch total num = [%d]\n", patch_num); + + /* improve patch down load speed */ + WMT_DBG_FUNC("improve patch dwn speed, clock rate promote, copy data use DMA at firmware side\n"); + WMT_CLOCK_RATE_CMD[6] = 0xD0; + /* If WMT_CLOCK_RATE_CMD[6] = 0xD0, promote the XTAL(26MHz) rate to 208MHz + * copy data use DMA at firmware side + */ + iRet = wmt_core_init_script(clock_rate_pro_and_use_dma, ARRAY_SIZE(clock_rate_pro_and_use_dma)); + if (iRet) { + WMT_ERR_FUNC("clock_rate_pro_and_use_dma fail(%d)\n", iRet); + return -30; + } + /* 9.3 Multi-patch Patch download */ + for (patch_index = 0; patch_index < patch_num; patch_index++) { + iRet = mt6632_patch_dwn(patch_index); + + if (iRet) { + WMT_ERR_FUNC("patch dwn fail (%d),patch_index(%d)\n", iRet, patch_index); + return -12; + } + + /* 10. WMT Reset command */ + iRet = wmt_core_init_script(init_table_3, ARRAY_SIZE(init_table_3)); + + if (iRet) { + WMT_ERR_FUNC("init_table_3 fail(%d)\n", iRet); + return -13; + } + } + /*close clock rate promote*/ + WMT_CLOCK_RATE_CMD[6] = 0x00; + WMT_DBG_FUNC("close clock rate promote, made XTAL to 26MHz\n"); + iRet = wmt_core_init_script(clock_rate_modify, ARRAY_SIZE(clock_rate_modify)); + if (iRet) { + WMT_ERR_FUNC("close clock rate promote fail(%d)\n", iRet); + return -31; + } + + /* SDIO data patch retry feature enable/disable */ + mtk_stp_sdio_retry_flag_ctrl(1); + if (mtk_stp_sdio_retry_flag_get()) { + iRet = wmt_core_init_script(set_sdio_retry_script, ARRAY_SIZE(set_sdio_retry_script)); + + if (iRet) { + WMT_ERR_FUNC("set_sdio_retry_script fail(%d)\n", iRet); + mtk_stp_sdio_retry_flag_ctrl(0); + } + } + +#ifdef CONFIG_MTK_COMBO_CHIP_DEEP_SLEEP_SUPPORT + if (g_deep_sleep_flag) { + /*get flag form mt6632_ant_m1.cfg*/ + deep_sleep_flag_from_cfg = wmt_stp_get_deep_sleep_flag_from_cfg(); + if (deep_sleep_flag_from_cfg == 1) { + WMT_DEEP_SLEEP_CMD[5] = 1; + iRet = wmt_core_init_script(init_deep_sleep_script, ARRAY_SIZE(init_deep_sleep_script)); + if (iRet) { + WMT_ERR_FUNC("enalbe deep sleep feature fail\n"); + return -20; + } + WMT_DBG_FUNC("chip deep sleep feature is enable\n"); + wmt_lib_deep_sleep_flag_set(MTK_WCN_BOOL_TRUE); + } else { + WMT_DEEP_SLEEP_CMD[5] = 0; + iRet = wmt_core_init_script(init_deep_sleep_script, ARRAY_SIZE(init_deep_sleep_script)); + if (iRet) { + WMT_ERR_FUNC("disable deep sleep feature fail\n"); + return -21; + } + WMT_INFO_FUNC("chip deep sleep feature is disable\n"); + wmt_lib_deep_sleep_flag_set(MTK_WCN_BOOL_FALSE); + } + } else { + WMT_DEEP_SLEEP_CMD[5] = 0; + iRet = wmt_core_init_script(init_deep_sleep_script, ARRAY_SIZE(init_deep_sleep_script)); + if (iRet) { + WMT_ERR_FUNC("disable deep sleep feature fail\n"); + return -22; + } + WMT_INFO_FUNC("chip deep sleep feature is disable\n"); + wmt_lib_deep_sleep_flag_set(MTK_WCN_BOOL_FALSE); + } +#endif + iRet = wmt_stp_init_coex(); + + if (iRet) { + WMT_ERR_FUNC("init_coex fail(%d)\n", iRet); + return -10; + } + WMT_DBG_FUNC("init_coex ok\n"); + /*If TCXO or co-clock is applied in mt6632, remove the triming patch*/ + /*mt6632_crystal_triming_set();*/ +#if MT6632_BRINGUP + WMT_DBG_FUNC("Bring up period, skip sdio driving settings\n"); +#else + WMT_DBG_FUNC("Temp solution, skip sdio driving settings\n"); + /* 6632_set_sdio_driving(); */ +#endif + if (pWmtHifConf->hifType == WMT_HIF_UART) { + /* 11. Set chip STP options */ + iRet = wmt_core_init_script(init_table_4, ARRAY_SIZE(init_table_4)); + + if (iRet) { + WMT_ERR_FUNC("init_table_4 fail(%d)\n", iRet); + return -12; + } + + /* 12. Enable host STP-UART mode */ + ctrlPa1 = WMT_STP_CONF_MODE; + ctrlPa2 = MTKSTP_UART_FULL_MODE; + iRet = wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); + ctrlPa1 = WMT_STP_CONF_EN; + ctrlPa2 = 1; + iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); + + if (iRet) { + WMT_ERR_FUNC("enable host STP-UART-FULL mode fail(%d)\n", iRet); + return -13; + } + + WMT_INFO_FUNC("enable host STP-UART-FULL mode\n"); + /*13. wait for 10ms, enough for chip do mechanism switch.(at least 2ms is needed) */ + osal_sleep_ms(10); + /* 14. Query chip STP options (TEST-ONLY) */ + /* 15. Query baud rate (stp, TEST-ONLY) */ + iRet = wmt_core_init_script(init_table_5, ARRAY_SIZE(init_table_5)); + + if (iRet) { + WMT_ERR_FUNC("init_table_5 fail(%d)\n", iRet); + return -14; + } + } + + if (mt6632_co_clock_get() == WMT_CO_CLOCK_EN) { + WMT_INFO_FUNC("co-clock enabled.\n"); + + iRet = wmt_core_init_script(osc_type_table, ARRAY_SIZE(osc_type_table)); + + if (iRet) { + WMT_ERR_FUNC("osc_type_table fail(%d), goes on\n", iRet); + return -15; + } + } else if (mt6632_co_clock_get() == WMT_CO_CLOCK_DCXO) { + WMT_SET_CRYSTAL_TRIMING_CMD[4] = 0x2; + WMT_SET_CRYSTAL_TRIMING_CMD[5] = 0x2; + WMT_SET_CRYSTAL_TRIMING_EVT[4] = 0x2; + WMT_SET_CRYSTAL_TRIMING_EVT[5] = 0x0; + iRet = wmt_core_init_script(set_crystal_timing_script, ARRAY_SIZE(set_crystal_timing_script)); + if (iRet == 0) + WMT_INFO_FUNC("set to Xtal mode suceed\n"); + else + WMT_INFO_FUNC("set to Xtal mode failed, iRet:%d.\n", iRet); + + + } else + WMT_INFO_FUNC("co-clock disabled.\n"); +#if MT6632_BRINGUP + WMT_INFO_FUNC("Bring up period, skip merge interface settings\n"); +#else + +#if (MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT) + iRet = wmt_core_init_script(merge_pcm_table, ARRAY_SIZE(merge_pcm_table)); + + if (iRet) { + WMT_ERR_FUNC("merge_pcm_table fail(%d), goes on\n", iRet); + return -15; + } +#endif +#endif + +#if CFG_SET_OPT_REG /*set registers */ + iRet = wmt_core_init_script(set_registers, ARRAY_SIZE(set_registers)); + + if (iRet) { + WMT_ERR_FUNC("set_registers fail(%d)", iRet); + return -17; + } +#endif + +#if CFG_WMT_COREDUMP_ENABLE + /*Open Core Dump Function @QC begin */ + mtk_wcn_stp_coredump_flag_ctrl(1); +#endif + + if (mtk_wcn_stp_coredump_flag_get() != 0) { + iRet = wmt_core_init_script(init_table_6, ARRAY_SIZE(init_table_6)); + + if (iRet) { + WMT_ERR_FUNC("init_table_6 core dump setting fail(%d)\n", iRet); + return -18; + } + WMT_INFO_FUNC("enable mt662x firmware coredump\n"); + } else + WMT_INFO_FUNC("disable mt662x firmware coredump\n"); + + ctrlData.ctrlId = WMT_CTRL_SET_STP_DBG_INFO; + ctrlData.au4CtrlData[0] = wmt_ic_ops_mt6632.icId; + ctrlData.au4CtrlData[1] = (size_t) gp_mt6632_info->cChipVersion; + ctrlData.au4CtrlData[2] = (size_t) &gp_mt6632_patch_info; + iRet = wmt_ctrl(&ctrlData); + if (iRet) { + WMT_ERR_FUNC("set dump info fail(%d)\n", iRet); + return -16; + } +#if CFG_WMT_FILTER_MODE_SETTING + wmt_stp_wifi_lte_coex(); +#endif + +#if CFG_WMT_PS_SUPPORT + osal_assert(gp_mt6632_info != NULL); + + if (gp_mt6632_info != NULL) { + if (gp_mt6632_info->bPsmSupport != MTK_WCN_BOOL_FALSE) + wmt_lib_ps_enable(); + else + wmt_lib_ps_disable(); + } +#endif + + return 0; +} + +static INT32 mt6632_sw_deinit(P_WMT_HIF_CONF pWmtHifConf) +{ + WMT_DBG_FUNC(" start\n"); + +#if CFG_WMT_PS_SUPPORT + osal_assert(gp_mt6632_info != NULL); + + if ((gp_mt6632_info != NULL) + && (gp_mt6632_info->bPsmSupport != MTK_WCN_BOOL_FALSE)) { + wmt_lib_ps_disable(); + } +#endif + + gp_mt6632_info = NULL; + + return 0; +} + +static INT32 mt6632_aif_ctrl(WMT_IC_PIN_STATE state, UINT32 flag) +{ + INT32 ret = -1; + +#if MT6632_BRINGUP + ret = 0; + WMT_INFO_FUNC("Bring up period, skip aif settings\n"); +#else + + if ((flag & WMT_LIB_AIF_FLAG_MASK) == WMT_LIB_AIF_FLAG_SHARE) { + WMT_INFO_FUNC("PCM & I2S PIN SHARE\n"); + + WMT_WARN_FUNC("TBD!!"); + ret = 0; + } else { + /*PCM & I2S separate */ + WMT_INFO_FUNC("PCM & I2S PIN SEPARATE\n"); + + switch (state) { + case WMT_IC_AIF_0: + /* BT_PCM_OFF & FM line in/out */ + ret = 0; + break; + + case WMT_IC_AIF_1: + /* BT_PCM_ON & FM line in/out */ + ret = 0; + break; + + case WMT_IC_AIF_2: + /* BT_PCM_OFF & FM I2S */ +#if 0 + val = 0x01110000; + ret = wmt_core_reg_rw_raw(1, 0x80050078, &val, 0x0FFF0000); +#else + ret = 0; + WMT_INFO_FUNC("Bring up period, skip WMT_IC_AIF_2 settings\n"); +#endif + break; + + case WMT_IC_AIF_3: + ret = 0; + break; + + default: + WMT_ERR_FUNC("unsupported state (%d)\n", state); + ret = -1; + break; + } + } + + if (!ret) + WMT_INFO_FUNC("new state(%d) ok\n", state); + else + WMT_WARN_FUNC("new state(%d) fail(%d)\n", state, ret); +#endif + return ret; +} + +static INT32 mt6632_gps_sync_ctrl(WMT_IC_PIN_STATE state, UINT32 flag) +{ + WMT_DBG_FUNC("MT6632 do not need gps sync settings\n"); + + /* anyway, we return 0 */ + return 0; +} + + +static INT32 mt6632_pin_ctrl(WMT_IC_PIN_ID id, WMT_IC_PIN_STATE state, UINT32 flag) +{ + INT32 ret; + + WMT_DBG_FUNC("ic pin id:%d, state:%d, flag:0x%x\n", id, state, flag); + + ret = -1; + + switch (id) { + case WMT_IC_PIN_AUDIO: + ret = mt6632_aif_ctrl(state, flag); + break; + + case WMT_IC_PIN_EEDI: + WMT_WARN_FUNC("TBD!!"); + /* We just return 0 here, prevent from WMT-FUNC do other register read/write */ + ret = 0; + break; + + case WMT_IC_PIN_EEDO: + WMT_WARN_FUNC("TBD!!"); + /* We just return 0 here, prevent from WMT-FUNC do other register read/write */ + ret = 0; + break; + + case WMT_IC_PIN_GSYNC: + ret = mt6632_gps_sync_ctrl(state, flag); + break; + + default: + break; + } + + WMT_DBG_FUNC("ret = (%d)\n", ret); + + return ret; +} + +INT32 mt6632_co_clock_ctrl(WMT_CO_CLOCK on) +{ + INT32 iRet = 0; + + if ((on >= WMT_CO_CLOCK_DIS) && (on < WMT_CO_CLOCK_MAX)) { + gCoClockEn = on; + } else { + WMT_DBG_FUNC("MT6632: error parameter:%d\n", on); + iRet = -1; + } + + WMT_DBG_FUNC("MT6632: Co-clock type: %d\n", gCoClockEn); + + return iRet; +} + +static MTK_WCN_BOOL mt6632_quick_sleep_flag_get(VOID) +{ + return MTK_WCN_BOOL_TRUE; +} + + +static MTK_WCN_BOOL mt6632_aee_dump_flag_get(VOID) +{ + if (mtk_wcn_stp_coredump_flag_get() == 1) + return MTK_WCN_BOOL_TRUE; + else + return MTK_WCN_BOOL_FALSE; +} + +static MTK_WCN_BOOL mt6632_trigger_stp_assert(VOID) +{ + INT32 iRet = -1; + UINT32 u4Res = 0; + MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; + UINT8 STP_DO_ASSERT_CMD[] = { 0x80, 0x50, 0x0a, 0x00, 'd', 'o', 'c', 'o', 'r', 'e', 'd', 'u', 'm', 'p', 0x00, + 0x00 + }; + + iRet = + wmt_core_tx((PUINT8)&STP_DO_ASSERT_CMD[0], sizeof(STP_DO_ASSERT_CMD), &u4Res, + MTK_WCN_BOOL_TRUE); + if (iRet || (u4Res != sizeof(STP_DO_ASSERT_CMD))) { + WMT_ERR_FUNC("wmt_core:send STP ASSERT COMMAND fail(%d),size(%d)\n", iRet, u4Res); + bRet = MTK_WCN_BOOL_FALSE; + } else + bRet = MTK_WCN_BOOL_TRUE; + return bRet; +} +#ifdef CONFIG_MTK_COMBO_CHIP_DEEP_SLEEP_SUPPORT +static MTK_WCN_BOOL mt6632_deep_sleep_ctrl(INT32 value) +{ + INT32 ret = 0; + + g_deep_sleep_flag = value; + if (value) { + WMT_DEEP_SLEEP_CMD[5] = 1; + WMT_INFO_FUNC("enable chip deep sleep feature from wmt_dbg command\n"); + } else { + WMT_DEEP_SLEEP_CMD[5] = 0; + WMT_INFO_FUNC("disable chip deep sleep feature from wmt_dbg command\n"); + } + ret = wmt_core_init_script(init_deep_sleep_script, ARRAY_SIZE(init_deep_sleep_script)); + if (ret == 0) + return MTK_WCN_BOOL_TRUE; + else + return MTK_WCN_BOOL_FALSE; +} + +static INT32 wmt_stp_get_deep_sleep_flag_from_cfg(VOID) +{ + WMT_GEN_CONF *pWmtGenConf = NULL; + ULONG addr; + INT32 ret; + + /*Get wmt config */ + ret = wmt_core_ctrl(WMT_CTRL_GET_WMT_CONF, &addr, 0); + + if (ret) { + WMT_ERR_FUNC("ctrl GET_WMT_CONF fail(%d)\n", ret); + return -2; + } + + WMT_DBG_FUNC("ctrl GET_WMT_CONF ok(0x%lx)\n", addr); + + pWmtGenConf = (P_WMT_GEN_CONF) addr; + + /*Check if WMT.cfg exists */ + if (pWmtGenConf->cfgExist == 0) { + WMT_INFO_FUNC("cfgExist == 0, skip config chip\n"); + /*if WMT.cfg not existed, still return success and adopt the default value */ + return -1; + } + if (pWmtGenConf->disable_deep_sleep_cfg == 0) { + WMT_DBG_FUNC("disable_deep_sleep_cfg (%d) get form mt6632_ant_m1.cfg, enable deep sleep feature\n", + pWmtGenConf->disable_deep_sleep_cfg); + ret = 1; + } else { + WMT_DBG_FUNC("disable_deep_sleep_cfg (%d) get form mt6632_ant_m1.cfg, disable deep sleep feature\n", + pWmtGenConf->disable_deep_sleep_cfg); + ret = 0; + } + return ret; +} + +#endif + +WMT_CO_CLOCK mt6632_co_clock_get(VOID) +{ + return gCoClockEn; +} + + + +static INT32 mt6632_ver_check(VOID) +{ + UINT32 hw_ver = 0; + UINT32 fw_ver = 0; + INT32 iret; + const WMT_IC_INFO_S *p_info = NULL; + ULONG ctrlPa1; + ULONG ctrlPa2; + + + /* 1. identify chip versions: HVR(HW_VER) and FVR(FW_VER) */ + WMT_LOUD_FUNC("MT6632: before read hw_ver (hw version)\n"); + iret = wmt_core_reg_rw_raw(0, GEN_HVR, &hw_ver, GEN_VER_MASK); + + if (iret) { + WMT_ERR_FUNC("MT6632: read hw_ver fail:%d\n", iret); + return -2; + } + + WMT_LOUD_FUNC("MT6632: before fw_ver (rom version)\n"); + wmt_core_reg_rw_raw(0, GEN_FVR, &fw_ver, GEN_VER_MASK); + + if (iret) { + WMT_ERR_FUNC("MT6632: read fw_ver fail:%d\n", iret); + return -2; + } + WMT_INFO_FUNC("MT6632: read (hw version)(0x%x), (fw version version)(0x%x)\n", hw_ver, fw_ver); + + p_info = mt6632_find_wmt_ic_info(hw_ver); + + if (p_info == NULL) { + WMT_ERR_FUNC("MT6632: hw_ver(0x%x) find wmt ic info fail\n", hw_ver); + return -3; + } + + WMT_DBG_FUNC("MT6632: wmt ic info: %s.%s (0x%x, patch_ext:%s)\n", + p_info->cChipName, p_info->cChipVersion, + p_info->u4HwVer, p_info->cPatchNameExt); + + /* hw id & version */ + ctrlPa1 = (0x00006632UL << 16) | (hw_ver & 0x0000FFFF); + /* translated fw rom version */ + ctrlPa2 = (fw_ver & 0x0000FFFF); + + iret = wmt_core_ctrl(WMT_CTRL_HWIDVER_SET, &ctrlPa1, &ctrlPa2); + + if (iret) + WMT_WARN_FUNC("MT6632: WMT_CTRL_HWIDVER_SET fail(%d)\n", iret); + + gp_mt6632_info = p_info; + return 0; +} + +static const WMT_IC_INFO_S *mt6632_find_wmt_ic_info(const UINT32 hw_ver) +{ + /* match chipversion with u4HwVer item in mt6632_info_table */ + const UINT32 size = ARRAY_SIZE(mt6632_info_table); + INT32 index; + + /* Leave full match here is a workaround for GPS to distinguish E3/E4 ICs. */ + index = size - 1; + + /* full match */ + while ((index >= 0) + && (hw_ver != mt6632_info_table[index].u4HwVer) /* full match */ + ) { + --index; + } + + if (index >= 0) { + WMT_DBG_FUNC("found ic info(0x%x) by full match! index:%d\n", hw_ver, index); + return &mt6632_info_table[index]; + } + + WMT_WARN_FUNC("find no ic info for (0x%x) by full match!try major num match!\n", hw_ver); + + /* George: The ONLY CORRECT method to find supported hw table. Match MAJOR + * NUM only can help us support future minor hw ECO, or fab switch, etc. + * FULL matching eliminate such flexibility and software package have to be + * updated EACH TIME even when minor hw ECO or fab switch!!! + */ + /* George: reverse the search order to favor newer version products */ + index = size - 1; + + /* major num match */ + while ((index >= 0) + && (MAJORNUM(hw_ver) != MAJORNUM(mt6632_info_table[index].u4HwVer)) + ) { + --index; + } + + if (index >= 0) { + WMT_INFO_FUNC("MT6632: found ic info for hw_ver(0x%x) by major num! index:%d\n", + hw_ver, index); + return &mt6632_info_table[index]; + } + + WMT_ERR_FUNC + ("MT6632: find no ic info for hw_ver(0x%x) by full match nor major num match!\n", + hw_ver); + return NULL; +} + + +static INT32 wmt_stp_init_coex(VOID) +{ + INT32 iRet; + ULONG addr = 0; + WMT_GEN_CONF *pWmtGenConf = NULL; + +#define COEX_WMT 0 + +#if CFG_SUBSYS_COEX_NEED + /* no need for MT6632 */ +#define COEX_BT 1 +#define COEX_WIFI 2 +#define COEX_PTA 3 +#define COEX_MISC 4 +#else +#define COEX_WIFI_PATH 1 +#define COEX_EXT_ELAN_GAIN_P1 2 +#endif +#define WMT_COXE_CONFIG_ADJUST_ANTENNA_OPCODE 6 + + /*Get wmt config */ + iRet = wmt_core_ctrl(WMT_CTRL_GET_WMT_CONF, &addr, 0); + + if (iRet) { + WMT_ERR_FUNC("ctrl GET_WMT_CONF fail(%d)\n", iRet); + return -2; + } + + WMT_DBG_FUNC("ctrl GET_WMT_CONF ok(0x%lx)\n", addr); + + pWmtGenConf = (P_WMT_GEN_CONF) addr; + + /*Check if WMT.cfg exists */ + if (pWmtGenConf->cfgExist == 0) { + WMT_INFO_FUNC("cfgExist == 0, skip config chip\n"); + /*if WMT.cfg not existed, still return success and adopt the default value */ + return 0; + } + + + /*Dump the coex-related info */ + WMT_DBG_FUNC("coex_wmt_ant_mode:0x%x, coex_wmt_wifi_path:0x%x\n", + pWmtGenConf->coex_wmt_ant_mode, pWmtGenConf->coex_wmt_wifi_path); +#if CFG_SUBSYS_COEX_NEED + WMT_DBG_FUNC("coex_bt:0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", + pWmtGenConf->coex_bt_rssi_upper_limit, + pWmtGenConf->coex_bt_rssi_mid_limit, + pWmtGenConf->coex_bt_rssi_lower_limit, + pWmtGenConf->coex_bt_pwr_high, + pWmtGenConf->coex_bt_pwr_mid, pWmtGenConf->coex_bt_pwr_low); + WMT_DBG_FUNC("coex_wifi:0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", + pWmtGenConf->coex_wifi_rssi_upper_limit, + pWmtGenConf->coex_wifi_rssi_mid_limit, + pWmtGenConf->coex_wifi_rssi_lower_limit, + pWmtGenConf->coex_wifi_pwr_high, + pWmtGenConf->coex_wifi_pwr_mid, pWmtGenConf->coex_wifi_pwr_low); + WMT_DBG_FUNC("coex_ext_pta:0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", + pWmtGenConf->coex_ext_pta_hi_tx_tag, + pWmtGenConf->coex_ext_pta_hi_rx_tag, + pWmtGenConf->coex_ext_pta_lo_tx_tag, + pWmtGenConf->coex_ext_pta_lo_rx_tag, + pWmtGenConf->coex_ext_pta_sample_t1, + pWmtGenConf->coex_ext_pta_sample_t2, + pWmtGenConf->coex_ext_pta_wifi_bt_con_trx); + WMT_DBG_FUNC("coex_misc:0x%x 0x%x 0x%x\n", + pWmtGenConf->coex_misc_ext_pta_on, pWmtGenConf->coex_misc_ext_feature_set); +#endif + + /*command adjustion due to WMT.cfg */ + coex_table[COEX_WMT].cmd[4] = WMT_COXE_CONFIG_ADJUST_ANTENNA_OPCODE; + coex_table[COEX_WMT].cmd[5] = pWmtGenConf->coex_wmt_ant_mode; + + if (gWmtDbgLvl >= WMT_LOG_DBG) { + wmt_core_dump_data(&coex_table[COEX_WMT].cmd[0], + coex_table[COEX_WMT].str, coex_table[COEX_WMT].cmdSz); + } + +#if CFG_SUBSYS_COEX_NEED + coex_table[COEX_BT].cmd[9] = pWmtGenConf->coex_bt_rssi_upper_limit; + coex_table[COEX_BT].cmd[10] = pWmtGenConf->coex_bt_rssi_mid_limit; + coex_table[COEX_BT].cmd[11] = pWmtGenConf->coex_bt_rssi_lower_limit; + coex_table[COEX_BT].cmd[12] = pWmtGenConf->coex_bt_pwr_high; + coex_table[COEX_BT].cmd[13] = pWmtGenConf->coex_bt_pwr_mid; + coex_table[COEX_BT].cmd[14] = pWmtGenConf->coex_bt_pwr_low; + + if (gWmtDbgLvl >= WMT_LOG_DBG) { + wmt_core_dump_data(&coex_table[COEX_BT].cmd[0], + coex_table[COEX_BT].str, coex_table[COEX_BT].cmdSz); + } + + coex_table[COEX_WIFI].cmd[10] = pWmtGenConf->coex_wifi_rssi_upper_limit; + coex_table[COEX_WIFI].cmd[11] = pWmtGenConf->coex_wifi_rssi_mid_limit; + coex_table[COEX_WIFI].cmd[12] = pWmtGenConf->coex_wifi_rssi_lower_limit; + coex_table[COEX_WIFI].cmd[13] = pWmtGenConf->coex_wifi_pwr_high; + coex_table[COEX_WIFI].cmd[14] = pWmtGenConf->coex_wifi_pwr_mid; + coex_table[COEX_WIFI].cmd[15] = pWmtGenConf->coex_wifi_pwr_low; + + if (gWmtDbgLvl >= WMT_LOG_DBG) { + wmt_core_dump_data(&coex_table[COEX_WIFI].cmd[0], + coex_table[COEX_WIFI].str, coex_table[COEX_WIFI].cmdSz); + } + + coex_table[COEX_PTA].cmd[5] = pWmtGenConf->coex_ext_pta_hi_tx_tag; + coex_table[COEX_PTA].cmd[6] = pWmtGenConf->coex_ext_pta_hi_rx_tag; + coex_table[COEX_PTA].cmd[7] = pWmtGenConf->coex_ext_pta_lo_tx_tag; + coex_table[COEX_PTA].cmd[8] = pWmtGenConf->coex_ext_pta_lo_rx_tag; + coex_table[COEX_PTA].cmd[9] = ((pWmtGenConf->coex_ext_pta_sample_t1 & 0xff00) >> 8); + coex_table[COEX_PTA].cmd[10] = ((pWmtGenConf->coex_ext_pta_sample_t1 & 0x00ff) >> 0); + coex_table[COEX_PTA].cmd[11] = ((pWmtGenConf->coex_ext_pta_sample_t2 & 0xff00) >> 8); + coex_table[COEX_PTA].cmd[12] = ((pWmtGenConf->coex_ext_pta_sample_t2 & 0x00ff) >> 0); + coex_table[COEX_PTA].cmd[13] = pWmtGenConf->coex_ext_pta_wifi_bt_con_trx; + + if (gWmtDbgLvl >= WMT_LOG_DBG) { + wmt_core_dump_data(&coex_table[COEX_PTA].cmd[0], + coex_table[COEX_PTA].str, coex_table[COEX_PTA].cmdSz); + } + + osal_memcpy(&coex_table[COEX_MISC].cmd[5], &pWmtGenConf->coex_misc_ext_pta_on, + sizeof(pWmtGenConf->coex_misc_ext_pta_on)); + osal_memcpy(&coex_table[COEX_MISC].cmd[9], &pWmtGenConf->coex_misc_ext_feature_set, + sizeof(pWmtGenConf->coex_misc_ext_feature_set)); + + wmt_core_dump_data(&coex_table[COEX_MISC].cmd[0], coex_table[COEX_MISC].str, + coex_table[COEX_MISC].cmdSz); +#else + coex_table[COEX_WIFI_PATH].cmd[5] = + (UINT8)((pWmtGenConf->coex_wmt_wifi_path & 0x00FF) >> 0); + coex_table[COEX_WIFI_PATH].cmd[6] = + (UINT8)((pWmtGenConf->coex_wmt_wifi_path & 0xFF00) >> 8); + + if (gWmtDbgLvl >= WMT_LOG_DBG) { + wmt_core_dump_data(&coex_table[COEX_WIFI_PATH].cmd[0], + coex_table[COEX_WIFI_PATH].str, coex_table[COEX_WIFI_PATH].cmdSz); + } + + coex_table[COEX_EXT_ELAN_GAIN_P1].cmd[5] = pWmtGenConf->coex_wmt_ext_elna_gain_p1_support; + /* wmt_ext_elna_gain_p1 D0*/ + coex_table[COEX_EXT_ELAN_GAIN_P1].cmd[6] = + (UINT8)((pWmtGenConf->coex_wmt_ext_elna_gain_p1_D0 & 0x000000FF) >> 0); + coex_table[COEX_EXT_ELAN_GAIN_P1].cmd[7] = + (UINT8)((pWmtGenConf->coex_wmt_ext_elna_gain_p1_D0 & 0x0000FF00) >> 8); + coex_table[COEX_EXT_ELAN_GAIN_P1].cmd[8] = + (UINT8)((pWmtGenConf->coex_wmt_ext_elna_gain_p1_D0 & 0x00FF0000) >> 16); + coex_table[COEX_EXT_ELAN_GAIN_P1].cmd[9] = + (UINT8)((pWmtGenConf->coex_wmt_ext_elna_gain_p1_D0 & 0xFF000000) >> 24); + /* wmt_ext_elna_gain_p1 D1*/ + coex_table[COEX_EXT_ELAN_GAIN_P1].cmd[10] = + (UINT8)((pWmtGenConf->coex_wmt_ext_elna_gain_p1_D1 & 0x000000FF) >> 0); + coex_table[COEX_EXT_ELAN_GAIN_P1].cmd[11] = + (UINT8)((pWmtGenConf->coex_wmt_ext_elna_gain_p1_D1 & 0x0000FF00) >> 8); + coex_table[COEX_EXT_ELAN_GAIN_P1].cmd[12] = + (UINT8)((pWmtGenConf->coex_wmt_ext_elna_gain_p1_D1 & 0x00FF0000) >> 16); + coex_table[COEX_EXT_ELAN_GAIN_P1].cmd[13] = + (UINT8)((pWmtGenConf->coex_wmt_ext_elna_gain_p1_D1 & 0xFF000000) >> 24); + /* wmt_ext_elna_gain_p1 D2*/ + coex_table[COEX_EXT_ELAN_GAIN_P1].cmd[14] = + (UINT8)((pWmtGenConf->coex_wmt_ext_elna_gain_p1_D2 & 0x000000FF) >> 0); + coex_table[COEX_EXT_ELAN_GAIN_P1].cmd[15] = + (UINT8)((pWmtGenConf->coex_wmt_ext_elna_gain_p1_D2 & 0x0000FF00) >> 8); + coex_table[COEX_EXT_ELAN_GAIN_P1].cmd[16] = + (UINT8)((pWmtGenConf->coex_wmt_ext_elna_gain_p1_D2 & 0x00FF0000) >> 16); + coex_table[COEX_EXT_ELAN_GAIN_P1].cmd[17] = + (UINT8)((pWmtGenConf->coex_wmt_ext_elna_gain_p1_D2 & 0xFF000000) >> 24); + /* wmt_ext_elna_gain_p1 D3*/ + coex_table[COEX_EXT_ELAN_GAIN_P1].cmd[18] = + (UINT8)((pWmtGenConf->coex_wmt_ext_elna_gain_p1_D3 & 0x000000FF) >> 0); + coex_table[COEX_EXT_ELAN_GAIN_P1].cmd[19] = + (UINT8)((pWmtGenConf->coex_wmt_ext_elna_gain_p1_D3 & 0x0000FF00) >> 8); + coex_table[COEX_EXT_ELAN_GAIN_P1].cmd[20] = + (UINT8)((pWmtGenConf->coex_wmt_ext_elna_gain_p1_D3 & 0x00FF0000) >> 16); + coex_table[COEX_EXT_ELAN_GAIN_P1].cmd[21] = + (UINT8)((pWmtGenConf->coex_wmt_ext_elna_gain_p1_D3 & 0xFF000000) >> 24); + + if (gWmtDbgLvl >= WMT_LOG_DBG) { + wmt_core_dump_data(&coex_table[COEX_EXT_ELAN_GAIN_P1].cmd[0], + coex_table[COEX_EXT_ELAN_GAIN_P1].str, coex_table[COEX_EXT_ELAN_GAIN_P1].cmdSz); + } + +#endif + + iRet = wmt_core_init_script(coex_table, ARRAY_SIZE(coex_table)); + + return iRet; +} + +#if 0 +static INT32 mt6632_set_sdio_driving(void) +{ + INT32 ret = 0; + + UINT32 addr = 0; + WMT_GEN_CONF *pWmtGenConf; + UINT32 drv_val = 0; + + /*Get wmt config */ + ret = wmt_core_ctrl(WMT_CTRL_GET_WMT_CONF, &addr, 0); + + if (ret) { + WMT_ERR_FUNC("ctrl GET_WMT_CONF fail(%d)\n", ret); + return -1; + } + + WMT_INFO_FUNC("ctrl GET_WMT_CONF ok(0x%x)\n", addr); + + pWmtGenConf = (P_WMT_GEN_CONF) addr; + + /*Check if WMT.cfg exists */ + if (pWmtGenConf->cfgExist == 0) { + WMT_INFO_FUNC("cfgExist == 0, skip config chip\n"); + /*if WMT.cfg not existed, still return success and adopt the default value */ + return 0; + } + + drv_val = pWmtGenConf->sdio_driving_cfg; + + /*Dump the sdio driving related info */ + WMT_INFO_FUNC("sdio driving:0x%x\n", drv_val); + + sdio_driving_table[0].cmd[12] = (UINT8) ((drv_val & 0x00000077UL) >> 0); /* DAT0 and DAT1 */ + sdio_driving_table[0].cmd[13] = (UINT8) ((drv_val & 0x00007700UL) >> 8); /* DAT2 and DAT3 */ + sdio_driving_table[0].cmd[14] = (UINT8) ((drv_val & 0x00070000UL) >> 16); /* CMD */ + + ret = wmt_core_init_script(sdio_driving_table, ARRAY_SIZE(sdio_driving_table)); + + return ret; +} + +static INT32 mt6632_crystal_triming_set(VOID) +{ + INT32 iRet = 0; + PUINT8 pbuf = NULL; + UINT32 bufLen = 0; + WMT_CTRL_DATA ctrlData; + UINT32 uCryTimOffset = 0x6D; + MTK_WCN_BOOL bIsNvramExist = MTK_WCN_BOOL_FALSE; + INT8 cCrystalTimingOffset = 0x0; + UINT8 cCrystalTiming = 0x0; + INT32 iCrystalTiming = 0x0; + MTK_WCN_BOOL bIsCrysTrimEnabled = MTK_WCN_BOOL_FALSE; + UINT32 u4Res; + + bIsNvramExist = MTK_WCN_BOOL_FALSE; + ctrlData.ctrlId = WMT_CTRL_CRYSTAL_TRIMING_GET; + ctrlData.au4CtrlData[0] = (size_t) "/data/nvram/APCFG/APRDEB/WIFI"; + ctrlData.au4CtrlData[1] = (size_t) &pbuf; + ctrlData.au4CtrlData[2] = (size_t) &bufLen; + + iRet = wmt_ctrl(&ctrlData); + + if (iRet != 0) { + WMT_ERR_FUNC("MT6632: WMT_CTRL_CRYSTAL_TRIMING_GET fail:%d\n", iRet); + bIsNvramExist = MTK_WCN_BOOL_FALSE; + bIsCrysTrimEnabled = MTK_WCN_BOOL_FALSE; + cCrystalTimingOffset = 0x0; + cCrystalTiming = 0x0; + iRet = -1; + } else { + WMT_DBG_FUNC("MT6632: nvram pBuf(%p), bufLen(%d)\n", pbuf, bufLen); + + if (bufLen < (uCryTimOffset + 1)) { + WMT_ERR_FUNC + ("MT6632: nvram len(%d) too short, crystalTimging value offset(%d)\n", + bufLen, uCryTimOffset); + bIsNvramExist = MTK_WCN_BOOL_FALSE; + bIsCrysTrimEnabled = MTK_WCN_BOOL_FALSE; + cCrystalTimingOffset = 0x0; + cCrystalTiming = 0x0; + } else { + bIsNvramExist = MTK_WCN_BOOL_TRUE; + cCrystalTimingOffset = *(pbuf + uCryTimOffset); + + if (cCrystalTimingOffset & 0x80) { + bIsCrysTrimEnabled = MTK_WCN_BOOL_TRUE; + cCrystalTimingOffset = (UINT8) cCrystalTimingOffset & 0x7f; + } + + WMT_DBG_FUNC("cCrystalTimingOffset (%d), bIsCrysTrimEnabled(%d)\n", + cCrystalTimingOffset, bIsCrysTrimEnabled); + } + + ctrlData.ctrlId = WMT_CTRL_CRYSTAL_TRIMING_PUT; + ctrlData.au4CtrlData[0] = (size_t) "/data/nvram/APCFG/APRDEB/WIFI"; + iRet = wmt_ctrl(&ctrlData); + + if (iRet != 0) { + WMT_ERR_FUNC("MT6632: WMT_CTRL_CRYSTAL_TRIMING_PUT fail:%d\n", iRet); + iRet = -2; + } else { + WMT_DBG_FUNC("MT6632: WMT_CTRL_CRYSTAL_TRIMING_PUT succeed\n"); + } + } + + if ((bIsNvramExist == MTK_WCN_BOOL_TRUE) && (bIsCrysTrimEnabled == MTK_WCN_BOOL_TRUE)) { + /*get CrystalTiming value before set it */ + iRet = + wmt_core_tx(get_crystal_timing_script[0].cmd, + get_crystal_timing_script[0].cmdSz, &u4Res, MTK_WCN_BOOL_FALSE); + + if (iRet || (u4Res != get_crystal_timing_script[0].cmdSz)) { + WMT_ERR_FUNC("WMT-CORE: write (%s) iRet(%d) cmd len err(%d, %d)\n", + get_crystal_timing_script[0].str, iRet, u4Res, + get_crystal_timing_script[0].cmdSz); + iRet = -3; + goto done; + } + + /* EVENT BUF */ + osal_memset(get_crystal_timing_script[0].evt, 0, + get_crystal_timing_script[0].evtSz); + iRet = + wmt_core_rx(get_crystal_timing_script[0].evt, + get_crystal_timing_script[0].evtSz, &u4Res); + + if (iRet || (u4Res != get_crystal_timing_script[0].evtSz)) { + WMT_ERR_FUNC("WMT-CORE: read (%s) iRet(%d) evt len err(rx:%d, exp:%d)\n", + get_crystal_timing_script[0].str, iRet, u4Res, + get_crystal_timing_script[0].evtSz); + mtk_wcn_stp_dbg_dump_package(); + iRet = -4; + goto done; + } + + iCrystalTiming = WMT_GET_CRYSTAL_TRIMING_EVT[5] & 0x7f; + + if (cCrystalTimingOffset & 0x40) { + /*nagative offset value */ + iCrystalTiming = iCrystalTiming + cCrystalTimingOffset - 128; + } else { + iCrystalTiming += cCrystalTimingOffset; + } + + WMT_DBG_FUNC("iCrystalTiming (0x%x)\n", iCrystalTiming); + if (iCrystalTiming > 0x7f) + cCrystalTiming = 0x7f; + else if (iCrystalTiming < 0) + cCrystalTiming = 0; + else + cCrystalTiming = iCrystalTiming; + WMT_DBG_FUNC("cCrystalTiming (0x%x)\n", cCrystalTiming); + /* set_crystal_timing_script */ + /*set crystal trim value command*/ + WMT_SET_CRYSTAL_TRIMING_CMD[4] = 0x1; + WMT_SET_CRYSTAL_TRIMING_EVT[4] = 0x1; + + WMT_SET_CRYSTAL_TRIMING_CMD[5] = cCrystalTiming; + WMT_GET_CRYSTAL_TRIMING_EVT[5] = cCrystalTiming; + + iRet = + wmt_core_init_script(set_crystal_timing_script, + ARRAY_SIZE(set_crystal_timing_script)); + + if (iRet) { + WMT_ERR_FUNC("set_crystal_timing_script fail(%d)\n", iRet); + iRet = -5; + } else { + WMT_DBG_FUNC("set crystal timing value (0x%x) succeed\n", + WMT_SET_CRYSTAL_TRIMING_CMD[5]); + iRet = + wmt_core_init_script(get_crystal_timing_script, + ARRAY_SIZE(get_crystal_timing_script)); + + if (iRet) { + WMT_ERR_FUNC("get_crystal_timing_script fail(%d)\n", iRet); + iRet = -6; + } else { + WMT_INFO_FUNC("succeed, updated crystal timing value (0x%x)\n", + WMT_GET_CRYSTAL_TRIMING_EVT[5]); + iRet = 0x0; + } + } + } + +done: + return iRet; +} +#endif + +static INT32 mt6632_patch_info_prepare(VOID) +{ + INT32 iRet = -1; + WMT_CTRL_DATA ctrlData; + + ctrlData.ctrlId = WMT_CTRL_PATCH_SEARCH; + iRet = wmt_ctrl(&ctrlData); + + return iRet; +} + + +static INT32 mt6632_patch_dwn(UINT32 index) +{ + INT32 iRet = -1; + P_WMT_PATCH patchHdr = NULL; + PUINT8 pBuf = NULL; + PUINT8 pPatchBuf = NULL; + UINT32 patchSize; + UINT32 fragSeq; + UINT32 fragNum; + UINT16 fragSize = 0; + UINT16 cmdLen; + UINT32 offset; + UINT32 u4Res; + UINT8 evtBuf[8]; + UINT8 addressevtBuf[12]; + UINT8 addressByte[4]; + PINT8 cDataTime = NULL; + /*PINT8 cPlat = NULL; */ + UINT16 u2HwVer = 0; + UINT16 u2SwVer = 0; + UINT32 u4PatchVer = 0; + UINT32 patchSizePerFrag = 0; + WMT_CTRL_DATA ctrlData; + + /*1.check hardware information */ + if (gp_mt6632_info == NULL) { + WMT_ERR_FUNC("null gp_mt6632_info!\n"); + return -1; + } + + osal_memset(gFullPatchName, 0, osal_sizeof(gFullPatchName)); + + ctrlData.ctrlId = WMT_CTRL_GET_PATCH_INFO; + ctrlData.au4CtrlData[0] = index + 1; + ctrlData.au4CtrlData[1] = (size_t) &gFullPatchName; + ctrlData.au4CtrlData[2] = (size_t) &addressByte; + iRet = wmt_ctrl(&ctrlData); + WMT_INFO_FUNC("the %d time valid patch found: (%s)\n", index + 1, gFullPatchName); + + /* <2.2> read patch content */ + ctrlData.ctrlId = WMT_CTRL_GET_PATCH; + ctrlData.au4CtrlData[0] = (size_t) NULL; + ctrlData.au4CtrlData[1] = (size_t) &gFullPatchName; + ctrlData.au4CtrlData[2] = (size_t) &pBuf; + ctrlData.au4CtrlData[3] = (size_t) &patchSize; + iRet = wmt_ctrl(&ctrlData); + + if (iRet) { + WMT_ERR_FUNC("wmt_core: WMT_CTRL_GET_PATCH fail:%d\n", iRet); + iRet -= 1; + goto done; + } + + /* |<-BCNT_PATCH_BUF_HEADROOM(8) bytes dummy allocated->|<-patch file->| */ + /* patch file with header: + * |<-patch header: 28 Bytes->|<-patch body: X Bytes ----->| + */ + pPatchBuf = osal_malloc(patchSize); + if (pPatchBuf == NULL) { + WMT_ERR_FUNC("vmalloc pPatchBuf for patch download fail\n"); + return -2; + } + osal_memcpy(pPatchBuf, pBuf, patchSize); + patchHdr = (P_WMT_PATCH) pPatchBuf; + + /* check patch file information */ + + cDataTime = patchHdr->ucDateTime; + u2HwVer = patchHdr->u2HwVer; + u2SwVer = patchHdr->u2SwVer; + u4PatchVer = patchHdr->u4PatchVer; + + osal_memcpy(&gp_mt6632_patch_info, patchHdr, osal_sizeof(WMT_PATCH)); + + /*cPlat = &patchHdr->ucPLat[0]; */ + + cDataTime[15] = '\0'; + + if (index == 0) { + WMT_INFO_FUNC("Combo Patch:Build Time(%s)Hw(0x%x) Sw(0x%x) Ph(0x%04x)Platform(%c%c%c%c)\n", + cDataTime, ((u2HwVer & 0x00ff) << 8) | ((u2HwVer & 0xff00) >> 8), + ((u2SwVer & 0x00ff) << 8) | ((u2SwVer & 0xff00) >> 8), + ((u4PatchVer & 0xff000000) >> 24) | ((u4PatchVer & 0x00ff0000) >> 16), + patchHdr->ucPLat[0], patchHdr->ucPLat[1], patchHdr->ucPLat[2], patchHdr->ucPLat[3]); + } + + /* remove patch header: + * |<-patch body: X Bytes (X=patchSize)--->| + */ + if (patchSize < sizeof(WMT_PATCH)) { + WMT_ERR_FUNC("error patch size\n"); + iRet = -1; + goto done; + } + patchSize -= sizeof(WMT_PATCH); + pPatchBuf += sizeof(WMT_PATCH); + patchSizePerFrag = DEFAULT_PATCH_FRAG_SIZE; + + /* remove patch checksum, MT6632 no need: + * |<-patch checksum: 2Bytes->|<-patch body: X Bytes (X=patchSize)--->| + */ + pPatchBuf += BCNT_PATCH_BUF_CHECKSUM; + patchSize -= BCNT_PATCH_BUF_CHECKSUM; + + /* reserve 1st patch cmd space before patch body + * |<-WMT_CMD: 5Bytes->|<-patch body: X Bytes (X=patchSize)----->| + */ + pPatchBuf -= sizeof(WMT_PATCH_CMD); + + fragNum = patchSize / patchSizePerFrag; + fragNum += ((fragNum * patchSizePerFrag) == patchSize) ? 0 : 1; + + WMT_DBG_FUNC("patch size(%d) fragNum(%d)\n", patchSize, fragNum); + + /*send patch address command */ + osal_memcpy(&WMT_PATCH_ADDRESS_CMD[5], addressByte, osal_sizeof(addressByte)); + WMT_INFO_FUNC("4 bytes address command:0x%02x,0x%02x,0x%02x,0x%02x", + WMT_PATCH_ADDRESS_CMD[5], WMT_PATCH_ADDRESS_CMD[6], + WMT_PATCH_ADDRESS_CMD[7], WMT_PATCH_ADDRESS_CMD[8]); + iRet = wmt_core_tx((PUINT8) &WMT_PATCH_ADDRESS_CMD[0], sizeof(WMT_PATCH_ADDRESS_CMD), &u4Res, + MTK_WCN_BOOL_FALSE); + + if (iRet || (u4Res != sizeof(WMT_PATCH_ADDRESS_CMD))) { + WMT_ERR_FUNC("wmt_core:wmt part patch address CMD fail(%d),size(%d),index(%d)\n", + iRet, u4Res, index); + iRet -= 1; + goto done; + } + + osal_memset(addressevtBuf, 0, sizeof(addressevtBuf)); + iRet = wmt_core_rx(addressevtBuf, sizeof(WMT_PATCH_ADDRESS_EVT), &u4Res); + + if (iRet || (u4Res != sizeof(WMT_PATCH_ADDRESS_EVT))) { + WMT_ERR_FUNC("wmt_core:wmt patch address EVT fail(%d),size(%d),index(%d)\n", iRet, + u4Res, index); + mtk_wcn_stp_dbg_dump_package(); + iRet -= 1; + goto done; + } +#if CFG_CHECK_WMT_RESULT + + if (osal_memcmp(addressevtBuf, WMT_PATCH_ADDRESS_EVT, osal_sizeof(WMT_PATCH_ADDRESS_EVT)) + != 0) { + WMT_ERR_FUNC("wmt_core: write WMT_PATCH_ADDRESS_CMD status fail,index(%d)\n", + index); + iRet -= 1; + goto done; + } +#endif + + /* send all fragments */ + offset = sizeof(WMT_PATCH_CMD); + fragSeq = 0; + + while (fragSeq < fragNum) { + WMT_DBG_FUNC("patch size(%d) fragNum(%d)\n", patchSize, fragNum); + + if (fragSeq == (fragNum - 1)) { + /* last fragment */ + fragSize = patchSize - fragSeq * patchSizePerFrag; + WMT_PATCH_CMD[4] = WMT_PATCH_FRAG_LAST; + } else { + fragSize = patchSizePerFrag; + WMT_PATCH_CMD[4] = (fragSeq == 0) ? WMT_PATCH_FRAG_1ST : WMT_PATCH_FRAG_MID; + } + + /* update length field in CMD:flag+frag */ + cmdLen = 1 + fragSize; + osal_memcpy(&WMT_PATCH_CMD[2], &cmdLen, 2); + /* copy patch CMD to buf (overwrite last 5-byte in prev frag) */ + osal_memcpy(pPatchBuf + offset - sizeof(WMT_PATCH_CMD), WMT_PATCH_CMD, + sizeof(WMT_PATCH_CMD)); + + iRet = + wmt_core_tx(pPatchBuf + offset - sizeof(WMT_PATCH_CMD), + fragSize + sizeof(WMT_PATCH_CMD), &u4Res, MTK_WCN_BOOL_FALSE); + + if (iRet || (u4Res != fragSize + sizeof(WMT_PATCH_CMD))) { + WMT_ERR_FUNC("wmt_core: write fragSeq(%d) size(%zu, %d) fail(%d)\n", fragSeq, + fragSize + sizeof(WMT_PATCH_CMD), u4Res, iRet); + iRet -= 1; + break; + } + + WMT_DBG_FUNC("wmt_core: write fragSeq(%d) size(%zu, %d) ok\n", + fragSeq, fragSize + sizeof(WMT_PATCH_CMD), u4Res); + + osal_memset(evtBuf, 0, sizeof(evtBuf)); + /* iRet = (*kal_stp_rx)(evtBuf, sizeof(WMT_PATCH_EVT), &u4Res); */ + iRet = wmt_core_rx(evtBuf, sizeof(WMT_PATCH_EVT), &u4Res); + + if (iRet || (u4Res != sizeof(WMT_PATCH_EVT))) { + WMT_ERR_FUNC("wmt_core: read WMT_PATCH_EVT length(%zu, %d) fail(%d)\n", + sizeof(WMT_PATCH_EVT), u4Res, iRet); + mtk_wcn_stp_dbg_dump_package(); + iRet -= 1; + break; + } +#if CFG_CHECK_WMT_RESULT + + if (osal_memcmp(evtBuf, WMT_PATCH_EVT, sizeof(WMT_PATCH_EVT)) != 0) { + WMT_ERR_FUNC("rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%zu):[%02X,%02X,%02X,%02X,%02X]\n", + u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], + sizeof(WMT_PATCH_EVT), WMT_PATCH_EVT[0], WMT_PATCH_EVT[1], + WMT_PATCH_EVT[2], WMT_PATCH_EVT[3], WMT_PATCH_EVT[4]); + iRet -= 1; + break; + } +#endif + WMT_DBG_FUNC("wmt_core: read WMT_PATCH_EVT length(%zu, %d) ok\n", + sizeof(WMT_PATCH_EVT), u4Res); + offset += patchSizePerFrag; + ++fragSeq; + } + + WMT_INFO_FUNC("wmt_core: patch dwn:%d frag(%d, %d) %s\n", + iRet, fragSeq, fragSize, (!iRet && (fragSeq == fragNum)) ? "ok" : "fail"); + + if (fragSeq != fragNum) + iRet -= 1; + +done: + if (patchHdr != NULL) { + osal_free(patchHdr); + pPatchBuf = NULL; + patchHdr = NULL; + } + + /* WMT_CTRL_FREE_PATCH always return 0 */ + /* wmt_core_ctrl(WMT_CTRL_FREE_PATCH, NULL, NULL); */ + ctrlData.ctrlId = WMT_CTRL_FREE_PATCH; + ctrlData.au4CtrlData[0] = index + 1; + wmt_ctrl(&ctrlData); + + return iRet; +} + +#if CFG_WMT_FILTER_MODE_SETTING +static INT32 wmt_stp_wifi_lte_coex(VOID) +{ + INT32 iRet; + ULONG addr = 0; + WMT_GEN_CONF *pWmtGenConf = NULL; + + /*Get wmt config */ + iRet = wmt_core_ctrl(WMT_CTRL_GET_WMT_CONF, &addr, 0); + if (iRet) { + WMT_ERR_FUNC("ctrl GET_WMT_CONF fail(%d)\n", iRet); + return -2; + } + WMT_DBG_FUNC("ctrl GET_WMT_CONF ok(0x%08lx)\n", addr); + + pWmtGenConf = (P_WMT_GEN_CONF) addr; + + /*Check if WMT.cfg exists */ + if (pWmtGenConf->cfgExist == 0) { + WMT_INFO_FUNC("cfgExist == 0, skip config chip\n"); + /*if WMT.cfg not existed, still return success and adopt the default value */ + return 0; + } + + if (pWmtGenConf->coex_wmt_filter_mode == 0) { + iRet = + wmt_core_init_script(set_wifi_lte_coex_table_0, + ARRAY_SIZE(set_wifi_lte_coex_table_0)); + if (iRet) + WMT_ERR_FUNC("wmt_core:set_wifi_lte_coex_table_0 fail(%d)\n", iRet); + else + WMT_DBG_FUNC("wmt_core:set_wifi_lte_coex_table_0 ok\n"); + } + + return iRet; +} +#endif diff --git a/drivers/misc/mediatek/connectivity/common/common_main/core/wmt_ic_soc.c b/drivers/misc/mediatek/connectivity/common/common_main/core/wmt_ic_soc.c new file mode 100644 index 0000000000000000000000000000000000000000..15138c9b695712b21738973988436e050a773aad --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/core/wmt_ic_soc.c @@ -0,0 +1,4074 @@ +/* +* Copyright (C) 2011-2014 MediaTek Inc. +* +* This program is free software: you can redistribute it and/or modify it under the terms of the +* GNU General Public License version 2 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. +* +* You should have received a copy of the GNU General Public License along with this program. +* If not, see . +*/ + +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +#ifdef DFT_TAG +#undef DFT_TAG +#endif +#define DFT_TAG "[WMT-IC]" +#define CFG_IC_SOC 1 + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include "osal_typedef.h" +#include "wmt_ic.h" +#include "wmt_core.h" +#include "wmt_lib.h" +#include "stp_core.h" +#include "mtk_wcn_consys_hw.h" +#include "wmt_step.h" + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +#define DEFAULT_PATCH_FRAG_SIZE (1000) +#define WMT_PATCH_FRAG_1ST (0x1) +#define WMT_PATCH_FRAG_MID (0x2) +#define WMT_PATCH_FRAG_LAST (0x3) + +#define CFG_CHECK_WMT_RESULT (1) +/* BT Port 2 Feature. this command does not need + * after coex command is downconfirmed by LC, + */ +#define CFG_WMT_BT_PORT2 (0) + +#define CFG_SET_OPT_REG (0) +#define CFG_WMT_I2S_DBGUART_SUPPORT (0) +#define CFG_SET_OPT_REG_SWLA (0) +#define CFG_SET_OPT_REG_MCUCLK (0) +#define CFG_SET_OPT_REG_MCUIRQ (0) + +#define CFG_SUBSYS_COEX_NEED 0 + +#define CFG_WMT_COREDUMP_ENABLE 0 + +#define CFG_WMT_MULTI_PATCH (1) + +#define CFG_WMT_CRYSTAL_TIMING_SET (0) + +#define CFG_WMT_SDIO_DRIVING_SET (0) + +#define CFG_WMT_UART_HIF_USE (0) + +#define CFG_WMT_WIFI_5G_SUPPORT (1) + +#define CFG_WMT_PATCH_DL_OPTM (1) +#if CFG_WMT_LTE_COEX_HANDLING +#define CFG_WMT_FILTER_MODE_SETTING (1) +#else +#define CFG_WMT_FILTER_MODE_SETTING (0) +#endif +/* #define MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT (0) */ + +#define CFG_WMT_POWER_ON_DLM (1) + +/* Define local option for debug purpose */ +#define CFG_CALIBRATION_BACKUP_RESTORE (1) +#define CALIBRATION_BACKUP_RESTORE_BUFFER_SIZE (640) + +#define PATCH_BUILD_TIME_SIZE (16) +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +static UINT8 gFullPatchName[NAME_MAX + 1]; +static const WMT_IC_INFO_S *gp_soc_info; +static WMT_PATCH gp_soc_patch_info; +static WMT_CO_CLOCK gCoClockEn = WMT_CO_CLOCK_DIS; + +#if CFG_CALIBRATION_BACKUP_RESTORE +static PUINT8 gBTCalResult; +static UINT16 gBTCalResultSize; +static UINT32 gWiFiCalAddrOffset; +static UINT32 gWiFiCalSize; +static PUINT8 gWiFiCalResult; +#endif + +#if 0 +static UINT8 WMT_WAKEUP_DIS_GATE_CMD[] = { 0x1, 0x3, 0x01, 0x00, 0x04 }; +static UINT8 WMT_WAKEUP_DIS_GATE_EVT[] = { 0x2, 0x3, 0x02, 0x0, 0x0, 0x04 }; + +static UINT8 WMT_WAKEUP_EN_GATE_CMD[] = { 0x1, 0x3, 0x01, 0x00, 0x05 }; +static UINT8 WMT_WAKEUP_EN_GATE_EVT[] = { 0x2, 0x3, 0x02, 0x0, 0x0, 0x05 }; +#endif + +#if CFG_WMT_UART_HIF_USE +static UINT8 WMT_QUERY_BAUD_CMD[] = { 0x01, 0x04, 0x01, 0x00, 0x02 }; +static UINT8 WMT_QUERY_BAUD_EVT_115200[] = { 0x02, 0x04, 0x06, 0x00, 0x00, 0x02, 0x00, 0xC2, 0x01, 0x00 }; +static UINT8 WMT_QUERY_BAUD_EVT_X[] = { 0x02, 0x04, 0x06, 0x00, 0x00, 0x02, 0xAA, 0xAA, 0xAA, 0xBB }; +static UINT8 WMT_SET_BAUD_CMD_X[] = { 0x01, 0x04, 0x05, 0x00, 0x01, 0xAA, 0xAA, 0xAA, 0xBB }; +static UINT8 WMT_SET_BAUD_EVT[] = { 0x02, 0x04, 0x02, 0x00, 0x00, 0x01 }; +static UINT8 WMT_SET_WAKEUP_WAKE_CMD_RAW[] = { 0xFF }; +static UINT8 WMT_SET_WAKEUP_WAKE_EVT[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x03 }; +#endif +static UINT8 WMT_QUERY_STP_CMD[] = { 0x01, 0x04, 0x01, 0x00, 0x04 }; +static UINT8 WMT_QUERY_STP_EVT_DEFAULT[] = { 0x02, 0x04, 0x06, 0x00, 0x00, 0x04, 0x11, 0x00, 0x00, 0x00 }; +static UINT8 WMT_QUERY_STP_EVT[] = { 0x02, 0x04, 0x06, 0x00, 0x00, 0x04, 0xDB, 0x0E, 0x68, 0x01 }; +static UINT8 WMT_PATCH_CMD[] = { 0x01, 0x01, 0x00, 0x00, 0x00 }; +static UINT8 WMT_PATCH_EVT[] = { 0x02, 0x01, 0x01, 0x00, 0x00 }; +static UINT8 WMT_RESET_CMD[] = { 0x01, 0x07, 0x01, 0x00, 0x04 }; +static UINT8 WMT_RESET_EVT[] = { 0x02, 0x07, 0x01, 0x00, 0x00 }; + +static UINT8 WMT_SET_CHIP_ID_CMD[] = { 0x01, 0x02, 0x05, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00 }; +static UINT8 WMT_SET_CHIP_ID_EVT[] = { 0x02, 0x02, 0x01, 0x00, 0x00}; + +#if CFG_WMT_BT_PORT2 +static UINT8 WMT_BTP2_CMD[] = { 0x01, 0x10, 0x03, 0x00, 0x01, 0x03, 0x01 }; +static UINT8 WMT_BTP2_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; +#endif + +static UINT8 WMT_QUERY_A_DIE_CMD[] = { 0x01, 0x02, 0x01, 0x00, 0x12 }; +static UINT8 WMT_QUERY_A_DIE_EVT[] = { 0x02, 0x02, 0x05, 0x00, 0x00 }; + +/*soc patial patch address cmd & evt need firmware owner provide*/ +#if CFG_WMT_MULTI_PATCH +static UINT8 WMT_PATCH_ADDRESS_CMD[] = { + 0x01, 0x08, 0x10, 0x00, + 0x01, 0x01, 0x00, 0x01, + 0x3c, 0x02, 0x09, 0x02, + 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff +}; +static UINT8 WMT_PATCH_ADDRESS_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; + +static UINT8 WMT_PATCH_P_ADDRESS_CMD[] = { + 0x01, 0x08, 0x10, 0x00, + 0x01, 0x01, 0x00, 0x01, + 0xc4, 0x04, 0x09, 0x02, + 0x00, 0x3f, 0x00, 0x01, + 0xff, 0xff, 0xff, 0xff +}; +static UINT8 WMT_PATCH_P_ADDRESS_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; + +static UINT8 WMT_PATCH_PDA_CFG_CMD[] = { + 0x01, 0x01, 0x11, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*Target address*/ + 0x00, 0x00, 0x00, 0x00, /*Download size*/ + 0x00, 0x00, 0x00, 0x00, /*Scramble key*/ + 0x2f, 0x02, 0x02, 0x00 /*Configuration*/ +}; +static UINT8 WMT_PATCH_PDA_CFG_EVT[] = { 0x02, 0x01, 0x01, 0x00, 0x00}; + +static UINT8 WMT_PATCH_ADDRESS_CMD_NEW[] = { 0x01, 0x01, 0x05, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00}; + +static UINT8 WMT_PATCH_ADDRESS_EVT_NEW[] = { 0x02, 0x01, 0x01, 0x00, 0x00}; +#endif + +/*coex cmd/evt++*/ +static UINT8 WMT_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x01, 0x00 }; +static UINT8 WMT_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; + +#if CFG_SUBSYS_COEX_NEED +static UINT8 WMT_BT_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x0B, + 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, + 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0xAA +}; +static UINT8 WMT_BT_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; + +static UINT8 WMT_WIFI_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x0C, + 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0xAA +}; +static UINT8 WMT_WIFI_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; + +static UINT8 WMT_PTA_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x0A, + 0x00, 0x04, + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xEE, 0xFF, 0xFF, 0xFE +}; +static UINT8 WMT_PTA_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; + +static UINT8 WMT_MISC_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x09, + 0x00, 0x05, + 0xAA, 0xAA, 0xAA, 0xAA, + 0xBB, 0xBB, 0xBB, 0xBB +}; +static UINT8 WMT_MISC_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; +#else +static UINT8 WMT_COEX_WIFI_PATH_CMD[] = { 0x01, 0x10, 0x03, 0x00, 0x1A, 0x0F, 0x00 }; +static UINT8 WMT_COEX_WIFI_PATH_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; + +static UINT8 WMT_COEX_EXT_ELAN_GAIN_P1_CMD[] = { 0x01, 0x10, 0x12, 0x00, 0x1B, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; +static UINT8 WMT_COEX_EXT_ELAN_GAIN_P1_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; + +static UINT8 WMT_COEX_EXT_EPA_MODE_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x1D, 0x00 }; +static UINT8 WMT_COEX_EXT_EPA_MODE_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; +#endif + +static UINT8 WMT_EPA_SETTING_CONFIG_CMD[] = { 0x01, 0x02, 0x02, 0x00, 0x0E, 0x00 }; +static UINT8 WMT_EPA_SETTING_CONFIG_EVT[] = { 0x02, 0x02, 0x01, 0x00, 0x00 }; + +static UINT8 WMT_EPA_ELNA_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; + +/*coex cmd/evt--*/ +static UINT8 WMT_SET_STP_CMD[] = { 0x01, 0x04, 0x05, 0x00, 0x03, 0xDB, 0x0E, 0x68, 0x01 }; +static UINT8 WMT_SET_STP_EVT[] = { 0x02, 0x04, 0x02, 0x00, 0x00, 0x03 }; +static UINT8 WMT_STRAP_CONF_CMD_FM_COMM[] = { 0x01, 0x05, 0x02, 0x00, 0x02, 0x02 }; +static UINT8 WMT_STRAP_CONF_EVT[] = { 0x02, 0x05, 0x02, 0x00, 0x00, 0x02 }; + +#if 0 +static UINT8 WMT_SET_OSC32K_BYPASS_CMD[] = { 0x01, 0x0A, 0x01, 0x00, 0x05 }; +static UINT8 WMT_SET_OSC32K_BYPASS_EVT[] = { 0x02, 0x0A, 0x01, 0x00, 0x00 }; +#endif + +#if 0 +/* to enable dump feature */ +static UINT8 WMT_CORE_DUMP_EN_CMD[] = { 0x01, 0x0F, 0x02, 0x00, 0x03, 0x01 }; +static UINT8 WMT_CORE_DUMP_EN_EVT[] = { 0x02, 0x0F, 0x01, 0x00, 0x00 }; + +/* to get system stack dump when f/w assert */ +static UINT8 WMT_CORE_DUMP_LEVEL_01_CMD[] = { 0x1, 0x0F, 0x07, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +static UINT8 WMT_CORE_DUMP_LEVEL_01_EVT[] = { 0x2, 0x0F, 0x01, 0x00, 0x00 }; + +/* to get task and system stack dump when f/w assert */ +static UINT8 WMT_CORE_DUMP_LEVEL_02_CMD[] = { 0x1, 0x0F, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +static UINT8 WMT_CORE_DUMP_LEVEL_02_EVT[] = { 0x2, 0x0F, 0x01, 0x00, 0x00 }; + +/* to get bt related memory dump when f/w assert */ +static UINT8 WMT_CORE_DUMP_LEVEL_03_CMD[] = { 0x1, 0x0F, 0x07, 0x00, 0x03, 0x00, 0x00, 0x09, 0xF0, 0x00, 0x0A }; +static UINT8 WMT_CORE_DUMP_LEVEL_03_EVT[] = { 0x2, 0x0F, 0x01, 0x00, 0x00 }; +#endif +/* to get full dump when f/w assert */ +static UINT8 WMT_CORE_DUMP_LEVEL_04_CMD[] = { 0x1, 0x0F, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +static UINT8 WMT_CORE_DUMP_LEVEL_04_EVT[] = { 0x2, 0x0F, 0x01, 0x00, 0x00 }; + +static UINT8 WMT_CORE_CO_CLOCK_CMD[] = { 0x1, 0x0A, 0x02, 0x00, 0x08, 0x03 }; +static UINT8 WMT_CORE_CO_CLOCK_EVT[] = { 0x2, 0x0A, 0x01, 0x00, 0x00 }; + +static UINT8 WMT_CORE_START_RF_CALIBRATION_CMD[] = { 0x1, 0x14, 0x1, 0x00, 0x01 }; +static UINT8 WMT_CORE_START_RF_CALIBRATION_EVT[] = { 0x2, 0x14, 0x02, 0x00, 0x00, 0x01 }; + +#if CFG_CALIBRATION_BACKUP_RESTORE +static UINT8 WMT_CORE_GET_RF_CALIBRATION_CMD[] = { 0x1, 0x14, 0x01, 0x00, 0x03 }; +/* byte[2] & byte[3] is left for length */ +static UINT8 WMT_CORE_SEND_RF_CALIBRATION_CMD[] = { 0x1, 0x14, 0x00, 0x00, 0x02, 0x00, 0x00 }; +static UINT8 WMT_CORE_SEND_RF_CALIBRATION_EVT_OK[] = { 0x2, 0x14, 0x02, 0x00, 0x00, 0x02 }; +static UINT8 WMT_CORE_SEND_RF_CALIBRATION_EVT_RECAL[] = { 0x2, 0x14, 0x02, 0x00, 0x01, 0x02 }; +#endif + +#if (MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT) +static UINT8 WMT_SET_I2S_SLAVE_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ + , 0x01 /* op: w */ + , 0x01 /*type: reg */ + , 0x00 /*rev */ + , 0x01 /*1 registers */ + , 0x78, 0x00, 0x05, 0x80 /*addr:0x80050078 */ + , 0x00, 0x00, 0x11, 0x01 /*value:0x11010000 */ + , 0x00, 0x00, 0x77, 0x07 /*mask:0x07770000 */ +}; + +static UINT8 WMT_SET_I2S_SLAVE_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ + , 0x00 /*S: 0 */ + , 0x00 /*type: reg */ + , 0x00 /*rev */ + , 0x01 /*1 registers */ +}; + +static UINT8 WMT_SET_DAI_TO_PAD_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ + , 0x01 /* op: w */ + , 0x01 /*type: reg */ + , 0x00 /*rev */ + , 0x01 /*1 registers */ + , 0x74, 0x00, 0x05, 0x80 /*addr:0x80050074 */ + , 0x44, 0x44, 0x00, 0x00 /*value:0x11010000 */ + , 0x77, 0x77, 0x00, 0x00 /*mask:0x07770000 */ +}; + +static UINT8 WMT_SET_DAI_TO_PAD_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ + , 0x00 /*S: 0 */ + , 0x00 /*type: reg */ + , 0x00 /*rev */ + , 0x01 /*1 registers */ +}; + +static UINT8 WMT_SET_DAI_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ + , 0x01 /* op: w */ + , 0x01 /*type: reg */ + , 0x00 /*rev */ + , 0x01 /*1 registers */ + , 0xA0, 0x00, 0x05, 0x80 /*addr:0x80050074 */ + , 0x04, 0x00, 0x00, 0x00 /*value:0x11010000 */ + , 0x04, 0x00, 0x00, 0x00 /*mask:0x07770000 */ +}; + +static UINT8 WMT_SET_DAI_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ + , 0x00 /*S: 0 */ + , 0x00 /*type: reg */ + , 0x00 /*rev */ + , 0x01 /*1 registers */ +}; +#endif + +#if !(CFG_IC_SOC) /* For MT6628 no need to set ALLEINT registers, done in f/w */ +/* enable all interrupt */ +static UINT8 WMT_SET_ALLINT_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ + , 0x01 /* op: w */ + , 0x01 /*type: reg */ + , 0x00 /*rev */ + , 0x01 /*1 registers */ + , 0x00, 0x03, 0x05, 0x80 /*addr:0x80050300 */ + , 0x00, 0xC4, 0x00, 0x00 /*value:0x0000C400 */ + , 0x00, 0xC4, 0x00, 0x00 /*mask:0x0000C400 */ +}; + +static UINT8 WMT_SET_ALLINT_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ + , 0x00 /*S: 0 */ + , 0x00 /*type: reg */ + , 0x00 /*rev */ + , 0x01 /*1 registers */ +}; + +#endif + +#if CFG_SET_OPT_REG_SWLA /* enable swla: eesk(7) eecs(8) oscen(19) sck0(24) scs0(25) */ +static UINT8 WMT_SET_SWLA_REG_CMD[] = { 0x01, 0x08, 0x1C, 0x00 /*length */ + , 0x01 /* op: w */ + , 0x01 /*type: reg */ + , 0x00 /*rev */ + , 0x02 /*2 registers */ + , 0x10, 0x01, 0x05, 0x80 /*addr:0x80050110 */ + , 0x10, 0x10, 0x01, 0x00 /*value:0x00011010 */ + , 0xF0, 0xF0, 0x0F, 0x00 /*mask:0x000FF0F0 */ + , 0x40, 0x01, 0x05, 0x80 /*addr:0x80050140 */ + , 0x00, 0x10, 0x01, 0x00 /*value:0x00011000 */ + , 0x00, 0xF0, 0x0F, 0x00 /*mask:0x000FF000 */ +}; + +static UINT8 WMT_SET_SWLA_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ + , 0x00 /*S: 0 */ + , 0x00 /*type: reg */ + , 0x00 /*rev */ + , 0x02 /*2 registers */ +}; +#endif + +#if CFG_SET_OPT_REG_MCUCLK /* enable mcu clk: antsel_4, eedi */ +static UINT8 WMT_SET_MCUCLK_REG_CMD[] = { 0x01, 0x08, (4 + 12 * 4), 0x00 /*length */ + , 0x01 /* op: w */ + , 0x01 /* type: reg */ + , 0x00 /* rev */ + , 0x04 /* 4 registers */ + , 0x00, 0x04, 0x00, 0x80 /* addr:0x8000 0400 */ + , 0x00, 0x14, 0x00, 0x00 /* value:0x0000 1400(osc, hclk), 0x0000 1501(PLL, en) */ + , 0xFF, 0xFF, 0x00, 0x00 /* mask:0x0000 FFFF */ + , 0x80, 0x01, 0x05, 0x80 /* addr:0x8005 0180 */ + , 0x12, 0x13, 0x00, 0x00 /* value:0x0000 1312(osc, hclk), 0x0000 1a19(PLL, en) */ + , 0xFF, 0xFF, 0x00, 0x00 /* mask:0x0000 FFFF */ + , 0x00, 0x01, 0x05, 0x80 /* addr:0x8005 0100 */ + , 0x00, 0x00, 0x02, 0x00 /* value:0x0002 0000 */ + , 0x00, 0x00, 0x0F, 0x00 /* mask:0x000F 0000 */ + , 0x10, 0x01, 0x05, 0x80 /* addr:0x8005 0110 */ + , 0x02, 0x00, 0x00, 0x00 /* value:0x0000 0002 */ + , 0x0F, 0x00, 0x00, 0x00 /* mask:0x0000 000F */ +}; + +static UINT8 WMT_SET_MCUCLK_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ + , 0x00 /* S: 0 */ + , 0x00 /* type: reg */ + , 0x00 /* rev */ + , 0x04 /* 4 registers */ +}; +#endif + +#if CFG_WMT_I2S_DBGUART_SUPPORT /* register write for debug uart */ +static UINT8 WMT_SET_DBGUART_REG_CMD[] = { 0x01, 0x08, 0x1C, 0x00 /*length */ + , 0x01 /* op: w */ + , 0x01 /*type: reg */ + , 0x00 /*rev */ + , 0x02 /*2 registers */ + , 0x30, 0x01, 0x05, 0x80 /*addr:0x80050130 */ + , 0x00, 0x00, 0x00, 0x00 /*value:0x00000000 */ + , 0xF0, 0x0F, 0x00, 0x00 /*mask:0x00000FF0 */ + , 0x40, 0x01, 0x05, 0x80 /*addr:0x80050140 */ + , 0x00, 0x01, 0x00, 0x00 /*value:0x00000100 */ + , 0x00, 0x01, 0x00, 0x00 /*mask:0x00000100 */ +}; + +static UINT8 WMT_SET_DBGUART_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ + , 0x00 /*S: 0 */ + , 0x00 /*type: reg */ + , 0x00 /*rev */ + , 0x02 /*2 registers */ +}; +#endif + +#if CFG_SET_OPT_REG_MCUIRQ /* enable mcu irq: antsel_4, wlan_act */ +#if 1 /* Ray */ +static UINT8 WMT_SET_MCUIRQ_REG_CMD[] = { 0x01, 0x08, (4 + 12 * 4), 0x00 /*length */ + , 0x01 /* op: w */ + , 0x01 /* type: reg */ + , 0x00 /* rev */ + , 0x04 /* 4 registers */ + , 0x00, 0x04, 0x00, 0x80 /* addr:0x8000_0400 */ + , 0x03, 0x14, 0x00, 0x00 /* value:0x0000_1403 check confg debug flag 3 low word */ + , 0xFF, 0xFF, 0x00, 0x00 /* mask:0x0000_FFFF */ + /* cirq_int_n */ + , 0x10, 0x01, 0x05, 0x80 /* addr:0x8005_0110 */ + , 0x02, 0x00, 0x00, 0x00 /* value:0x0000_0002 set EEDI as cirq_int_n debug flag (monitor flag2) */ + , 0x07, 0x00, 0x00, 0x00 /* mask:0x0000_0007 */ + , 0x00, 0x01, 0x05, 0x80 /* addr:0x8005_0100 */ + , 0x00, 0x00, 0x02, 0x00 /* value:0x0002_0000 (ANTSEL4=>monitor flag 0, ahb_x2_gt_ck debug flag) */ + , 0x00, 0x00, 0x07, 0x00 /* mask:0x0007_0000 */ + /* 1. ARM irq_b, monitor flag 0 */ + , 0x80, 0x01, 0x05, 0x80 /* addr:0x8005_0180 */ + , 0x1F, 0x1E, 0x00, 0x00 /* value:0x0000_1E1F check mcusys debug flag */ + , 0x7F, 0x7F, 0x00, 0x00 /* mask:0x0000_7F7F */ +}; + +static UINT8 WMT_SET_MCUIRQ_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ + , 0x00 /* S: 0 */ + , 0x00 /* type: reg */ + , 0x00 /* rev */ + , 0x04 /* 5 registers */ +}; +#elif 0 /* KC */ +static UINT8 WMT_SET_MCUIRQ_REG_CMD[] = { 0x01, 0x08, (4 + 12 * 5), 0x00 /*length */ + , 0x01 /* op: w */ + , 0x01 /* type: reg */ + , 0x00 /* rev */ + , 0x05 /* 5 registers */ + , 0x00, 0x04, 0x00, 0x80 /* addr:0x8000_0400 */ + , 0x00, 0x02, 0x00, 0x00 /* value:0x0000_0200 [15:8]=0x2 arm irq_b, 0xA irq_bus[5] bt_timcon_irq_b */ + , 0x00, 0xFF, 0x00, 0x00 /* mask:0x0000_FF00 */ + /* 1. ARM irq_b, monitor flag 0 */ + , 0x80, 0x01, 0x05, 0x80 /* addr:0x8005_0180 */ + , 0x18, 0x00, 0x00, 0x00 /* value:0x0000_0018 [6:0]=001_1000 (monitor flag 0 select, MCUSYS, SEL:8) */ + , 0x7F, 0x00, 0x00, 0x00 /* mask:0x0000_007F */ + , 0x00, 0x01, 0x05, 0x80 /* addr:0x8005_0100 */ + , 0x00, 0x00, 0x02, 0x00 /* value:0x0002_0000 (ANTSEL4=>monitor flag 0) */ + , 0x00, 0x00, 0x07, 0x00 /* mask:0x0007_0000 */ + /* 2. irq_bus[5] bt_timcon_irq_b monitor flag 15 */ + , 0xB0, 0x01, 0x05, 0x80 /* addr:0x8005_01B0 */ + , 0x00, 0x00, 0x00, 0x16 /* value:0x1600_0000 [30:24]=001_0110 (monitor flag 15 select, MCUSYS, SEL:6) */ + , 0x00, 0x00, 0x00, 0x7F /* mask:0x7F00_0000 */ + , 0x30, 0x01, 0x05, 0x80 /* addr:0x8005_0130 */ + , 0x00, 0x20, 0x00, 0x00 /* value:0x0000_2000 (WLAN_ACT=>monitor flag 15) */ + , 0x00, 0x70, 0x00, 0x00 /* mask:0x0000_7000 */ +}; + +static UINT8 WMT_SET_MCUIRQ_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ + , 0x00 /* S: 0 */ + , 0x00 /* type: reg */ + , 0x00 /* rev */ + , 0x05 /* 5 registers */ +}; +#endif +#endif + +#if CFG_WMT_CRYSTAL_TIMING_SET +static UINT8 WMT_SET_CRYSTAL_TRIMING_CMD[] = { 0x01, 0x12, 0x02, 0x00, 0x01, 0x00 }; +static UINT8 WMT_SET_CRYSTAL_TRIMING_EVT[] = { 0x02, 0x12, 0x02, 0x00, 0x01, 0x00 }; + +static UINT8 WMT_GET_CRYSTAL_TRIMING_CMD[] = { 0x01, 0x12, 0x02, 0x00, 0x00, 0x00 }; +static UINT8 WMT_GET_CRYSTAL_TRIMING_EVT[] = { 0x02, 0x12, 0x02, 0x00, 0x00, 0x00 }; +#endif + +#ifdef CFG_WMT_READ_EFUSE_VCN33 +static UINT8 WMT_GET_EFUSE_VCN33_CMD[] = { 0x01, 0x12, 0x02, 0x00, 0x04, 0x00 }; +static UINT8 WMT_GET_EFUSE_VCN33_EVT[] = { 0x02, 0x12, 0x02, 0x00, 0x04, 0x00 }; +#endif + +/* set sdio driving */ +#if CFG_WMT_SDIO_DRIVING_SET +static UINT8 WMT_SET_SDIO_DRV_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ + , 0x01 /* op: w */ + , 0x01 /*type: reg */ + , 0x00 /*rev */ + , 0x01 /*1 registers */ + , 0x50, 0x00, 0x05, 0x80 /*addr:0x80050050 */ + , 0x44, 0x44, 0x04, 0x00 /*value:0x00044444 */ + , 0x77, 0x77, 0x07, 0x00 /*mask:0x00077777 */ +}; + +static UINT8 WMT_SET_SDIO_DRV_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ + , 0x00 /*S: 0 */ + , 0x00 /*type: reg */ + , 0x00 /*rev */ + , 0x01 /*1 registers */ +}; +#endif + +#if CFG_WMT_WIFI_5G_SUPPORT +static UINT8 WMT_GET_SOC_ADIE_CHIPID_CMD[] = { 0x01, 0x13, 0x04, 0x00, 0x02, 0x04, 0x24, 0x00 }; +static UINT8 WMT_GET_SOC_ADIE_CHIPID_EVT[] = { + 0x02, 0x13, 0x09, 0x00, 0x00, 0x02, 0x04, 0x24, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; +static UINT8 WMT_GET_SOC_6625_L_CMD[] = { 0x01, 0x13, 0x04, 0x00, 0x02, 0x04, 0x20, 0x01 }; +static UINT8 WMT_GET_SOC_6625_L_EVT[] = { + 0x02, 0x13, 0x09, 0x00, 0x00, 0x02, 0x04, 0x20, + 0x01, 0x00, 0x00, 0x00, 0x00 +}; +#endif + +#if CFG_WMT_PATCH_DL_OPTM +static UINT8 WMT_SET_MCU_CLK_EN_CMD[] = { + 0x01, 0x08, 0x10, 0x00, + 0x01, 0x01, 0x00, 0x01, + 0x34, 0x03, 0x00, 0x80, + 0x00, 0x00, 0x01, 0x00, + 0xff, 0xff, 0xff, 0xff +}; +static UINT8 WMT_SET_MCU_CLK_EN_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; + +static UINT8 WMT_SET_MCU_CLK_138_CMD[] = { + 0x01, 0x08, 0x10, 0x00, + 0x01, 0x01, 0x00, 0x01, + 0x0c, 0x01, 0x00, 0x80, + 0x59, 0x4d, 0x84, 0x00, + 0xff, 0xff, 0xff, 0xff +}; +static UINT8 WMT_SET_MCU_CLK_138_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; + +static UINT8 WMT_SET_MCU_CLK_26_CMD[] = { + 0x01, 0x08, 0x10, 0x00, + 0x01, 0x01, 0x00, 0x01, + 0x0c, 0x01, 0x00, 0x80, + 0x00, 0x4d, 0x84, 0x00, + 0xff, 0xff, 0xff, 0xff +}; +static UINT8 WMT_SET_MCU_CLK_26_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; + +static UINT8 WMT_SET_MCU_CLK_DIS_CMD[] = { + 0x01, 0x08, 0x10, 0x00, + 0x01, 0x01, 0x00, 0x01, + 0x34, 0x03, 0x00, 0x80, + 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff +}; +static UINT8 WMT_SET_MCU_CLK_DIS_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; + +/*only for 6797,enable high clock frequency*/ +/*CLK EN*/ +static UINT8 WMT_SET_MCU_CLK_EN_6797[] = { + 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, + 0x10, 0x11, 0x02, 0x81, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x10 +}; +/*RATIO SET*/ +static UINT8 WMT_SET_MCU_RATIO_SET_6797[] = { + 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, + 0x0c, 0x01, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00, + 0xc0, 0x00, 0x00, 0x00 +}; +/*DIV SET*/ +static UINT8 WMT_SET_MCU_DIV_SET_6797[] = { + 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, + 0x18, 0x11, 0x02, 0x80, 0x07, 0x00, 0x00, 0x00, + 0x3f, 0x00, 0x00, 0x00 +}; +/*HCLK SET*/ +static UINT8 WMT_SET_MCU_HCLK_SET_6797[] = { + 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, + 0x00, 0x11, 0x02, 0x81, 0x04, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00 +}; + +/*Change clock to 26MHz*/ +/*HCLK DIS*/ +static UINT8 WMT_SET_MCU_HCLK_DIS_6797[] = { + 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, + 0x00, 0x11, 0x02, 0x81, 0x00, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00 +}; +/*RATIO DIS*/ +static UINT8 WMT_SET_MCU_RATIO_DIS_6797[] = { + 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, + 0x0c, 0x01, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0x00, 0x00, 0x00 +}; +/*CLK DIS*/ +static UINT8 WMT_SET_MCU_CLK_DIS_6797[] = { + 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, + 0x10, 0x11, 0x02, 0x81, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10 +}; + +static UINT8 WMT_SET_MCU_CLK_EVT_6797[] = { + 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 +}; + +#endif + + +static UINT8 WMT_COEX_CONFIG_BT_CTRL_CMD[] = { + 0x01, 0x10, 0x04, 0x00, 0x1A, 0x00, 0x00, 0x00 }; +static UINT8 WMT_COEX_CONFIG_ADDJUST_OPP_TIME_RATIO_CMD[] = { + 0x01, 0x10, 0x04, 0x00, 0x1B, 0x00, 0x00, 0x00 }; +static UINT8 WMT_COEX_CONFIG_ADDJUST_BLE_SCAN_TIME_RATIO_CMD[] = { + 0x01, 0x10, 0x04, 0x00, 0x1C, 0x00, 0x00, 0x00 }; + +static UINT8 WMT_COEX_SPLIT_MODE_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; + +#if CFG_WMT_FILTER_MODE_SETTING +static UINT8 WMT_COEX_TDM_REQ_ANTSEL_NUM_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x14, 0x00 }; +static UINT8 WMT_COEX_FILTER_SPEC_CMD_TEST[] = { + 0x01, 0x10, 0x45, 0x00, 0x11, 0x00, 0x00, 0x01, + 0x00, 0x11, 0x11, 0x16, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x63, 0x63, 0x63, 0x00, 0x39, 0x43, 0x63, + 0x63, 0x02, 0x02, 0x03, 0x00, 0x01, 0x01, 0x01, + 0x01, 0x0e, 0x0e, 0x0e, 0x00, 0x0a, 0x0c, 0x0e, + 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; +static UINT8 WMT_COEX_LTE_FREQ_IDX_TABLE_CMD[] = { + 0x01, 0x10, 0x21, 0x00, 0x12, 0xfc, 0x08, 0x15, + 0x09, 0x2e, 0x09, 0x47, 0x09, 0xc4, 0x09, 0xd4, + 0x09, 0xe3, 0x09, 0x5a, 0x0a, 0x14, 0x09, 0x2d, + 0x09, 0x46, 0x09, 0x60, 0x09, 0xd3, 0x09, 0xe2, + 0x09, 0x59, 0x0a, 0x8B, 0x0a}; +static UINT8 WMT_COEX_LTE_CHAN_UNSAFE_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x13, 0x00 }; +static UINT8 WMT_COEX_IS_LTE_L_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x21, 0x01 }; + +#if 0 +static UINT8 WMT_COEX_SPLIT_FILTER_CMD_TEST[] = { + 0x01, 0x10, 0x19, 0x00, 0x0F, 0x00, 0x00, 0x00, + 0x00, 0x6c, 0x09, 0x8a, 0x09, 0x8a, 0x09, 0x9e, + 0x09, 0x01, 0x07, 0x07, 0x0b, 0x07, 0x07, 0x00, + 0x32, 0x27, 0x4e, 0x27, 0x32 +}; + +static UINT8 WMT_COEX_FILTER_SPEC_CMD_TEST[] = { + 0x01, 0x10, 0x45, 0x00, 0x11, 0x00, 0x00, 0x01, + 0x00, 0x07, 0x07, 0x07, 0x54, 0x54, 0x00, 0x00, + 0x00, 0x50, 0x50, 0x50, 0x54, 0x54, 0x39, 0x39, + 0x39, 0x02, 0x02, 0x02, 0x0e, 0x0e, 0x01, 0x01, + 0x01, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0a, 0x0a, + 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 +}; + +static UINT8 WMT_COEX_LTE_FREQ_IDX_TABLE_CMD_TEST[] = { + 0x01, 0x10, 0x21, 0x00, 0x12, 0xfc, 0x08, 0x15, + 0x09, 0x2e, 0x09, 0x47, 0x09, 0xc4, 0x09, 0xdd, + 0x09, 0xf6, 0x09, 0x0f, 0xaf, 0x14, 0x09, 0x2d, + 0x09, 0x46, 0x09, 0x5f, 0x09, 0xdd, 0x09, 0xf5, + 0x09, 0x0d, 0x0a, 0x27, 0x0a +}; +static UINT8 WMT_COEX_LTE_CHAN_UNSAFE_CMD_TEST[] = { 0x01, 0x10, 0x02, 0x00, 0x13, 0x00 }; +static UINT8 WMT_COEX_EXT_COMPONENT_CMD_TEST[] = { 0x01, 0x10, 0x03, 0x00, 0x0d, 0x7f, 0x03 }; +#endif + +static UINT8 WMT_COEX_FILTER_SPEC_CMD_0[] = { + 0x01, 0x10, 0x45, 0x00, 0x11, 0x00, 0x00, 0x01, + 0x00, 0x16, 0x16, 0x16, 0x16, 0x00, 0x00, 0x00, + 0x00, 0x63, 0x63, 0x63, 0x63, 0x3c, 0x3c, 0x3c, + 0x3c, 0x04, 0x04, 0x04, 0x04, 0x01, 0x01, 0x01, + 0x01, 0x0e, 0x0e, 0x0e, 0x0e, 0x0b, 0x0b, 0x0b, + 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 +}; + +static UINT8 WMT_COEX_LTE_FREQ_IDX_TABLE_CMD_0[] = { + 0x01, 0x10, 0x21, 0x00, 0x12, 0xfc, 0x08, 0x15, + 0x09, 0x2e, 0x09, 0x47, 0x09, 0xc4, 0x09, 0xdd, + 0x09, 0xf6, 0x09, 0x0f, 0x0a, 0x14, 0x09, 0x2d, + 0x09, 0x46, 0x09, 0x5f, 0x09, 0xdd, 0x09, 0xf5, + 0x09, 0x0d, 0x0a, 0x27, 0x0a +}; +static UINT8 WMT_COEX_IS_LTE_PROJ_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x15, 0x01 }; + +static UINT8 WMT_COEX_FILTER_SPEC_CMD_6752[] = { + 0x01, 0x10, 0x45, 0x00, 0x11, 0x00, 0x00, 0x01, + 0x00, 0x11, 0x11, 0x16, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x63, 0x63, 0x63, 0x00, 0x39, 0x43, 0x63, + 0x63, 0x02, 0x02, 0x03, 0x00, 0x01, 0x01, 0x01, + 0x01, 0x0E, 0x0E, 0x0E, 0x00, 0x0A, 0x0C, 0x0E, + 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 +}; + +static UINT8 WMT_COEX_LTE_FREQ_IDX_TABLE_CMD_6752[] = { + 0x01, 0x10, 0x21, 0x00, 0x12, 0xFC, 0x08, 0x15, + 0x09, 0x2E, 0x09, 0x47, 0x09, 0xC4, 0x09, 0xD4, + 0x09, 0xE3, 0x09, 0x5A, 0x0A, 0x14, 0x09, 0x2D, + 0x09, 0x46, 0x09, 0x60, 0x09, 0xD3, 0x09, 0xE2, + 0x09, 0x59, 0x0A, 0x8B, 0x0A +}; +#endif + +static UINT8 WMT_BT_TSSI_FROM_WIFI_CONFIG_CMD[] = { + 0x01, 0x02, 0x04, 0x00, 0x0D, 0x01, 0x1E, 0x00 +}; + +static UINT8 WMT_BT_TSSI_FROM_WIFI_EVENT[] = { + 0x02, 0x02, 0x01, 0x00, 0x00 +}; + +#if CFG_WMT_POWER_ON_DLM +static UINT8 WMT_POWER_CTRL_DLM_CMD1[] = { + 0x01, 0x08, 0x10, 0x00, + 0x01, 0x01, 0x00, 0x01, + 0x60, 0x00, 0x10, 0x80, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0f, 0x00, 0x00 +}; + +static UINT8 WMT_POWER_CTRL_DLM_CMD2[] = { + 0x01, 0x08, 0x10, 0x00, + 0x01, 0x01, 0x00, 0x01, + 0x60, 0x00, 0x10, 0x80, + 0x00, 0x00, 0x00, 0x00, + 0xf0, 0x00, 0x00, 0x00 +}; + +static UINT8 WMT_POWER_CTRL_DLM_CMD3[] = { + 0x01, 0x08, 0x10, 0x00, + 0x01, 0x01, 0x00, 0x01, + 0x60, 0x00, 0x10, 0x80, + 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00 +}; +static UINT8 WMT_POWER_CTRL_DLM_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; +#endif + +static UINT8 WMT_WIFI_ANT_SWAP_CMD[] = { 0x01, 0x14, 0x04, 0x00, 0x07, 0x02, 0x00, 0x00 }; +static UINT8 WMT_WIFI_ANT_SWAP_EVT[] = { 0x02, 0x14, 0x02, 0x00, 0x00, 0x07 }; + +static UINT8 WMT_WIFI_CONFIG_EVT[] = { 0x02, 0x02, 0x01, 0x00, 0x00 }; + +#if (!CFG_IC_SOC) + +/* stp sdio init scripts */ +static struct init_script init_table_1_1[] = { + /* table_1_1 is only applied to common SDIO interface */ + INIT_CMD(WMT_SET_ALLINT_REG_CMD, WMT_SET_ALLINT_REG_EVT, "enable all interrupt"), + /* applied to MT6628 ? */ + INIT_CMD(WMT_WAKEUP_DIS_GATE_CMD, WMT_WAKEUP_DIS_GATE_EVT, "disable gating"), +}; + +#endif + +static struct init_script init_table_1_2[] = { + INIT_CMD(WMT_QUERY_STP_CMD, WMT_QUERY_STP_EVT_DEFAULT, "query stp default"), +}; + +#if CFG_WMT_UART_HIF_USE +static struct init_script init_table_2[] = { + INIT_CMD(WMT_QUERY_BAUD_CMD, WMT_QUERY_BAUD_EVT_X, "query baud X"), +}; +#endif + +static struct init_script init_table_3[] = { + INIT_CMD(WMT_RESET_CMD, WMT_RESET_EVT, "wmt reset"), +#if CFG_WMT_BT_PORT2 + INIT_CMD(WMT_BTP2_CMD, WMT_BTP2_EVT, "set bt port2"), +#endif +}; + +static struct init_script set_chipid_script[] = { + INIT_CMD(WMT_SET_CHIP_ID_CMD, WMT_SET_CHIP_ID_EVT, "wmt set chipid"), +}; + +#if CFG_WMT_CRYSTAL_TIMING_SET +static struct init_script set_crystal_timing_script[] = { + INIT_CMD(WMT_SET_CRYSTAL_TRIMING_CMD, WMT_SET_CRYSTAL_TRIMING_EVT, "set crystal trim value"), +}; + +static struct init_script get_crystal_timing_script[] = { + INIT_CMD(WMT_GET_CRYSTAL_TRIMING_CMD, WMT_GET_CRYSTAL_TRIMING_EVT, "get crystal trim value"), +}; +#endif +#ifdef CFG_WMT_READ_EFUSE_VCN33 +static struct init_script get_efuse_vcn33_script[] = { + INIT_CMD(WMT_GET_EFUSE_VCN33_CMD, WMT_GET_EFUSE_VCN33_EVT, "get efuse vcn33 value"), +}; +#endif + +static struct init_script get_a_die_script[] = { + INIT_CMD(WMT_QUERY_A_DIE_CMD, WMT_QUERY_A_DIE_EVT, "query A-die"), +}; + +static struct init_script init_table_4[] = { + INIT_CMD(WMT_SET_STP_CMD, WMT_SET_STP_EVT, "set stp"), +}; + +static struct init_script init_table_5[] = { + INIT_CMD(WMT_QUERY_STP_CMD, WMT_QUERY_STP_EVT, "query stp"), +}; + +static struct init_script init_table_5_1[] = { + INIT_CMD(WMT_STRAP_CONF_CMD_FM_COMM, WMT_STRAP_CONF_EVT, "configure FM comm"), +}; + +static struct init_script init_table_6[] = { + INIT_CMD(WMT_CORE_DUMP_LEVEL_04_CMD, WMT_CORE_DUMP_LEVEL_04_EVT, "setup core dump level"), +}; + +static struct init_script calibration_table[] = { + INIT_CMD(WMT_CORE_START_RF_CALIBRATION_CMD, WMT_CORE_START_RF_CALIBRATION_EVT, "start RF calibration data"), +}; + +#if CFG_WMT_PATCH_DL_OPTM +static struct init_script set_mcuclk_table_1[] = { + INIT_CMD(WMT_SET_MCU_CLK_EN_CMD, WMT_SET_MCU_CLK_EN_EVT, "enable set mcu clk"), + INIT_CMD(WMT_SET_MCU_CLK_138_CMD, WMT_SET_MCU_CLK_138_EVT, "set mcu clk to 138.67MH"), +}; + +static struct init_script set_mcuclk_table_2[] = { + INIT_CMD(WMT_SET_MCU_CLK_26_CMD, WMT_SET_MCU_CLK_26_EVT, "set mcu clk to 26MH"), + INIT_CMD(WMT_SET_MCU_CLK_DIS_CMD, WMT_SET_MCU_CLK_DIS_EVT, "disable set mcu clk"), +}; + +static struct init_script set_mcuclk_table_3[] = { + INIT_CMD(WMT_SET_MCU_CLK_EN_6797, WMT_SET_MCU_CLK_EVT_6797, "enable set mcu clk"), + INIT_CMD(WMT_SET_MCU_RATIO_SET_6797, WMT_SET_MCU_CLK_EVT_6797, "mcu ratio set"), + INIT_CMD(WMT_SET_MCU_DIV_SET_6797, WMT_SET_MCU_CLK_EVT_6797, "mcu div set"), + INIT_CMD(WMT_SET_MCU_HCLK_SET_6797, WMT_SET_MCU_CLK_EVT_6797, "set mcu clk to hclk"), +}; +static struct init_script set_mcuclk_table_4[] = { + INIT_CMD(WMT_SET_MCU_HCLK_DIS_6797, WMT_SET_MCU_CLK_EVT_6797, "disable mcu hclk"), + INIT_CMD(WMT_SET_MCU_RATIO_DIS_6797, WMT_SET_MCU_CLK_EVT_6797, "disable mcu ratio set"), + INIT_CMD(WMT_SET_MCU_CLK_DIS_6797, WMT_SET_MCU_CLK_EVT_6797, "disable mcu clk set"), +}; + +#endif + +static UINT8 WMT_COEX_EXT_COMPONENT_CMD[] = {0x01, 0x10, 0x03, 0x00, 0x0d, 0x00, 0x00}; + +static struct init_script set_wifi_ext_component_table[] = { + INIT_CMD(WMT_COEX_EXT_COMPONENT_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi ext component"), +}; + +#if CFG_WMT_FILTER_MODE_SETTING +static struct init_script set_wifi_lte_coex_table_1[] = { + INIT_CMD(WMT_COEX_FILTER_SPEC_CMD_6752, WMT_COEX_SPLIT_MODE_EVT, "wifi lte coex filter spec"), + INIT_CMD(WMT_COEX_LTE_FREQ_IDX_TABLE_CMD_6752, WMT_COEX_SPLIT_MODE_EVT, "wifi lte freq idx"), + INIT_CMD(WMT_COEX_IS_LTE_PROJ_CMD, WMT_COEX_SPLIT_MODE_EVT, "set LTE project"), +}; + +static struct init_script set_wifi_lte_coex_table_2[] = { + INIT_CMD(WMT_COEX_FILTER_SPEC_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi lte coex filter"), + INIT_CMD(WMT_COEX_LTE_FREQ_IDX_TABLE_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi lte freq id table"), + INIT_CMD(WMT_COEX_LTE_CHAN_UNSAFE_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi lte unsafe channel"), + INIT_CMD(WMT_COEX_IS_LTE_L_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi coex is L branch"), +}; + +static struct init_script set_wifi_lte_coex_table_3[] = { + INIT_CMD(WMT_COEX_IS_LTE_PROJ_CMD, WMT_COEX_SPLIT_MODE_EVT, "set LTE project"), +}; + +static struct init_script set_wifi_lte_coex_table_0[] = { +#if 0 + INIT_CMD(WMT_COEX_SPLIT_FILTER_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi lte coex split filter"), + INIT_CMD(WMT_COEX_FILTER_SPEC_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi lte coex filter spec"), + INIT_CMD(WMT_COEX_LTE_FREQ_IDX_TABLE_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi lte freq idx"), + INIT_CMD(WMT_COEX_LTE_CHAN_UNSAFE_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi lte channel unsafe"), + INIT_CMD(WMT_COEX_EXT_COMPONENT_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi coex ext component"), +#endif + INIT_CMD(WMT_COEX_FILTER_SPEC_CMD_0, WMT_COEX_SPLIT_MODE_EVT, "def wifi lte coex filter spec"), + INIT_CMD(WMT_COEX_LTE_FREQ_IDX_TABLE_CMD_0, WMT_COEX_SPLIT_MODE_EVT, "def wifi lte freq idx"), +}; + +static struct init_script get_tdm_req_antsel_num_table[] = { + INIT_CMD(WMT_COEX_TDM_REQ_ANTSEL_NUM_CMD, WMT_COEX_SPLIT_MODE_EVT, "get tdm req antsel num"), +}; +#endif + +static struct init_script bt_tssi_from_wifi_table[] = { + INIT_CMD(WMT_BT_TSSI_FROM_WIFI_CONFIG_CMD, WMT_BT_TSSI_FROM_WIFI_EVENT, "get bt tssi value from wifi"), +}; + +static struct init_script coex_config_addjust_table[] = { + INIT_CMD(WMT_COEX_CONFIG_BT_CTRL_CMD, WMT_COEX_SPLIT_MODE_EVT, "coex config bt ctrl"), + INIT_CMD(WMT_COEX_CONFIG_ADDJUST_OPP_TIME_RATIO_CMD, WMT_COEX_SPLIT_MODE_EVT, "opp time ratio"), + INIT_CMD(WMT_COEX_CONFIG_ADDJUST_BLE_SCAN_TIME_RATIO_CMD, WMT_COEX_SPLIT_MODE_EVT, "ble scan time ratio"), + +}; + +#if CFG_SET_OPT_REG +static struct init_script set_registers[] = { + /* INIT_CMD(WMT_SET_GPS_REG_CMD, WMT_SET_GPS_REG_EVT, "set wmt registers"), */ + /* INIT_CMD(WMT_SET_SDIODRV_REG_CMD, WMT_SET_SDIODRV_REG_EVT, "set SDIO driving registers") */ +#if CFG_WMT_I2S_DBGUART_SUPPORT + INIT_CMD(WMT_SET_DBGUART_REG_CMD, WMT_SET_DBGUART_REG_EVT, "set debug uart registers"), +#endif +#if CFG_SET_OPT_REG_SWLA + INIT_CMD(WMT_SET_SWLA_REG_CMD, WMT_SET_SWLA_REG_EVT, "set swla registers"), +#endif +#if CFG_SET_OPT_REG_MCUCLK + INIT_CMD(WMT_SET_MCUCLK_REG_CMD, WMT_SET_MCUCLK_REG_EVT, "set mcuclk dbg registers"), +#endif +#if CFG_SET_OPT_REG_MCUIRQ + INIT_CMD(WMT_SET_MCUIRQ_REG_CMD, WMT_SET_MCUIRQ_REG_EVT, "set mcu irq dbg registers"), +#endif +}; +#endif + +static struct init_script coex_table[] = { + INIT_CMD(WMT_COEX_SETTING_CONFIG_CMD, WMT_COEX_SETTING_CONFIG_EVT, "coex_wmt"), + +#if CFG_SUBSYS_COEX_NEED +/* no need in MT6628 */ + INIT_CMD(WMT_BT_COEX_SETTING_CONFIG_CMD, WMT_BT_COEX_SETTING_CONFIG_EVT, "coex_bt"), + INIT_CMD(WMT_WIFI_COEX_SETTING_CONFIG_CMD, WMT_WIFI_COEX_SETTING_CONFIG_EVT, "coex_wifi"), + INIT_CMD(WMT_PTA_COEX_SETTING_CONFIG_CMD, WMT_PTA_COEX_SETTING_CONFIG_EVT, "coex_ext_pta"), + INIT_CMD(WMT_MISC_COEX_SETTING_CONFIG_CMD, WMT_MISC_COEX_SETTING_CONFIG_EVT, "coex_misc"), +#else + INIT_CMD(WMT_COEX_WIFI_PATH_CMD, WMT_COEX_WIFI_PATH_EVT, "wifi path"), + INIT_CMD(WMT_COEX_EXT_ELAN_GAIN_P1_CMD, WMT_COEX_EXT_ELAN_GAIN_P1_EVT, "wifi elan gain p1"), + INIT_CMD(WMT_COEX_EXT_EPA_MODE_CMD, WMT_COEX_EXT_EPA_MODE_EVT, "wifi ext epa mode"), +#endif +}; + +static struct init_script epa_table[] = { + INIT_CMD(WMT_EPA_SETTING_CONFIG_CMD, WMT_EPA_SETTING_CONFIG_EVT, "coex_wmt_epa"), +}; + +static struct init_script osc_type_table[] = { + INIT_CMD(WMT_CORE_CO_CLOCK_CMD, WMT_CORE_CO_CLOCK_EVT, "osc_type"), +}; + +#if (MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT) +static struct init_script merge_pcm_table[] = { + INIT_CMD(WMT_SET_I2S_SLAVE_REG_CMD, WMT_SET_I2S_SLAVE_REG_EVT, "I2S_Slave"), + INIT_CMD(WMT_SET_DAI_TO_PAD_REG_CMD, WMT_SET_DAI_TO_PAD_REG_EVT, "DAI_PAD"), + INIT_CMD(WMT_SET_DAI_REG_CMD, WMT_SET_DAI_REG_EVT, "DAI_EVT"), +}; +#endif + +#if CFG_WMT_SDIO_DRIVING_SET +static struct init_script sdio_driving_table[] = { + INIT_CMD(WMT_SET_SDIO_DRV_REG_CMD, WMT_SET_SDIO_DRV_REG_EVT, "sdio_driving"), +}; +#endif + +#if CFG_WMT_POWER_ON_DLM +static struct init_script wmt_power_on_dlm_table[] = { + INIT_CMD(WMT_POWER_CTRL_DLM_CMD1, WMT_POWER_CTRL_DLM_EVT, "power on dlm cmd1"), + INIT_CMD(WMT_POWER_CTRL_DLM_CMD2, WMT_POWER_CTRL_DLM_EVT, "power on dlm cmd2"), + INIT_CMD(WMT_POWER_CTRL_DLM_CMD3, WMT_POWER_CTRL_DLM_EVT, "power on dlm cmd3") +}; +#endif + + +static struct init_script wifi_ant_swap_table[] = { + INIT_CMD(WMT_WIFI_ANT_SWAP_CMD, WMT_WIFI_ANT_SWAP_EVT, "ant swap"), +}; + +/* SOC Chip Version and Info Table */ +static const WMT_IC_INFO_S mtk_wcn_soc_info_table[] = { + { + .u4HwVer = 0x8A00, + .cChipName = WMT_IC_NAME_DEFAULT, + .cChipVersion = WMT_IC_VER_E1, + .cPatchNameExt = WMT_IC_PATCH_E1_EXT, + .bWorkWithoutPatch = MTK_WCN_BOOL_FALSE, + .bPsmSupport = MTK_WCN_BOOL_TRUE, + }, + { + .u4HwVer = 0x8A01, + .cChipName = WMT_IC_NAME_DEFAULT, + .cChipVersion = WMT_IC_VER_E2, + .cPatchNameExt = WMT_IC_PATCH_E1_EXT, + .bWorkWithoutPatch = MTK_WCN_BOOL_FALSE, + .bPsmSupport = MTK_WCN_BOOL_TRUE, + }, + { + .u4HwVer = 0x8B00, + .cChipName = WMT_IC_NAME_DEFAULT, + .cChipVersion = WMT_IC_VER_E2, + .cPatchNameExt = WMT_IC_PATCH_E1_EXT, + .bWorkWithoutPatch = MTK_WCN_BOOL_FALSE, + .bPsmSupport = MTK_WCN_BOOL_TRUE, + }, + { + .u4HwVer = 0x8B01, + .cChipName = WMT_IC_NAME_DEFAULT, + .cChipVersion = WMT_IC_VER_E3, + .cPatchNameExt = WMT_IC_PATCH_E1_EXT, + .bWorkWithoutPatch = MTK_WCN_BOOL_FALSE, + .bPsmSupport = MTK_WCN_BOOL_TRUE, + }, + { + .u4HwVer = 0x8C00, + .cChipName = WMT_IC_NAME_DEFAULT, + .cChipVersion = WMT_IC_VER_E2, + .cPatchNameExt = WMT_IC_PATCH_E1_EXT, + .bWorkWithoutPatch = MTK_WCN_BOOL_FALSE, + .bPsmSupport = MTK_WCN_BOOL_TRUE, + } +}; + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +static MTK_WCN_BOOL mtk_wcn_soc_trigger_assert(VOID); + +static INT32 mtk_wcn_soc_sw_init(P_WMT_HIF_CONF pWmtHifConf); + +static INT32 mtk_wcn_soc_sw_deinit(P_WMT_HIF_CONF pWmtHifConf); + +static INT32 mtk_wcn_soc_pin_ctrl(WMT_IC_PIN_ID id, WMT_IC_PIN_STATE state, UINT32 flag); + +static INT32 mtk_wcn_soc_aif_ctrl(WMT_IC_PIN_STATE state, UINT32 flag); + +static INT32 mtk_wcn_soc_ver_check(VOID); + +static const WMT_IC_INFO_S *mtk_wcn_soc_find_wmt_ic_info(const UINT32 hw_ver); + +static INT32 wmt_stp_init_coex(VOID); + +static INT32 wmt_stp_init_epa(VOID); + +static INT32 wmt_stp_init_epa_elna(VOID); + +static INT32 wmt_stp_init_epa_elna_invert_cr(VOID); + +static INT32 wmt_init_wifi_config(VOID); + +#if CFG_WMT_FILTER_MODE_SETTING +static INT32 wmt_stp_wifi_lte_coex(VOID); +#endif + +#if CFG_WMT_MULTI_PATCH +static INT32 mtk_wcn_soc_patch_dwn(UINT32 index); +static INT32 mtk_wcn_soc_patch_info_prepare(VOID); +static UINT32 mtk_wcn_soc_get_patch_num(VOID); +static INT32 mtk_wcn_soc_normal_patch_dwn(PUINT8 pPatchBuf, UINT32 patchSize, PUINT8 addressByte); +static INT32 mtk_wcn_soc_pda_patch_dwn(PUINT8 pPatchBuf, UINT32 patchSize, PUINT8 addressByte); +#else +static INT32 mtk_wcn_soc_patch_dwn(VOID); +#endif + +static INT32 mtk_wcn_soc_co_clock_ctrl(WMT_CO_CLOCK on); + +#if CFG_WMT_CRYSTAL_TIMING_SET +static INT32 mtk_wcn_soc_crystal_triming_set(VOID); +#endif + +static MTK_WCN_BOOL mtk_wcn_soc_quick_sleep_flag_get(VOID); + +static MTK_WCN_BOOL mtk_wcn_soc_aee_dump_flag_get(VOID); + +#if CFG_WMT_SDIO_DRIVING_SET +static INT32 mtk_wcn_soc_set_sdio_driving(void); +#endif +static UINT32 mtk_wcn_soc_update_patch_version(VOID); + +static INT32 mtk_wcn_soc_calibration(void); +static INT32 mtk_wcn_soc_do_calibration(void); +#if CFG_CALIBRATION_BACKUP_RESTORE +static INT32 mtk_wcn_soc_calibration_backup(void); +static INT32 mtk_wcn_soc_calibration_restore(void); +#endif + +static INT32 wmt_stp_init_wifi_ant_swap(VOID); + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/* SOC Operation Function Table */ +WMT_IC_OPS wmt_ic_ops_soc = { + .icId = 0x0000, /* soc may have mt6572/82/71/83,but they have the same sw init flow */ + .options = 0, + .sw_init = mtk_wcn_soc_sw_init, + .sw_deinit = mtk_wcn_soc_sw_deinit, + .ic_pin_ctrl = mtk_wcn_soc_pin_ctrl, + .ic_ver_check = mtk_wcn_soc_ver_check, + .co_clock_ctrl = mtk_wcn_soc_co_clock_ctrl, + .is_quick_sleep = mtk_wcn_soc_quick_sleep_flag_get, + .is_aee_dump_support = mtk_wcn_soc_aee_dump_flag_get, + .trigger_stp_assert = mtk_wcn_soc_trigger_assert, + .deep_sleep_ctrl = NULL, +}; + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +static INT32 _wmt_soc_mode_ctrl(UINT32 mode) +{ + INT32 iRet = -1; + unsigned long ctrlPa1; + unsigned long ctrlPa2; + + /* only consider full mode situation for the moment */ + if (mode != MTKSTP_BTIF_FULL_MODE) + return -1; + + /* 1. Query chip STP default options */ + iRet = wmt_core_init_script(init_table_1_2, osal_array_size(init_table_1_2)); + if (iRet) { + WMT_ERR_FUNC("init_table_1_2 fail(%d)\n", iRet); + osal_assert(0); + return -2; + } + + /* 2. Set chip STP options */ + iRet = wmt_core_init_script(init_table_4, osal_array_size(init_table_4)); + if (iRet) { + WMT_ERR_FUNC("init_table_4 fail(%d)\n", iRet); + return -3; + } + + /* 3. Enable host full mode */ + ctrlPa1 = WMT_STP_CONF_MODE; + ctrlPa2 = MTKSTP_BTIF_FULL_MODE; + iRet = wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); + ctrlPa1 = WMT_STP_CONF_EN; + ctrlPa2 = 1; + iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); + if (iRet) { + WMT_ERR_FUNC("enable host STP-BTIF-FULL mode fail(%d)\n", iRet); + return -4; + } + WMT_DBG_FUNC("enable host STP-BTIF-FULL mode\n"); + + /*4. wait for 10ms, enough for chip do mechanism switch.(at least 2ms is needed) */ + osal_sleep_ms(10); + + /* 5. Query chip STP options */ + iRet = wmt_core_init_script(init_table_5, osal_array_size(init_table_5)); + if (iRet) { + WMT_ERR_FUNC("init_table_5 fail(%d)\n", iRet); + return -5; + } + + return 0; +} + +static INT32 mtk_wcn_soc_sw_init(P_WMT_HIF_CONF pWmtHifConf) +{ + INT32 iRet = -1; + INT32 retry = 3; + unsigned long ctrlPa1; + unsigned long ctrlPa2; + UINT32 hw_ver; + WMT_CTRL_DATA ctrlData; + UINT32 chipid = 0; +#ifdef CFG_WMT_READ_EFUSE_VCN33 + UINT32 efuse_d3_vcn33 = 2; /*default voltage is 3.5V*/ +#endif +#if CFG_WMT_MULTI_PATCH + UINT32 patch_num = 0; + UINT32 patch_index = 0; +#endif +#if CFG_WMT_WIFI_5G_SUPPORT + UINT32 dDieChipid = 0; + UINT32 aDieChipid = 0; + UINT8 evtbuf[20]; + UINT32 u4Res; + UINT32 pmicChipid = 0; +#endif + P_WMT_GEN_CONF pWmtGenConf = NULL; + P_CONSYS_EMI_ADDR_INFO emiInfo = NULL; + + WMT_DBG_FUNC(" start\n"); + + osal_assert(gp_soc_info != NULL); + if ((gp_soc_info == NULL) + || (pWmtHifConf == NULL) + ) { + WMT_ERR_FUNC("null pointers: gp_soc_info(0x%p), pWmtHifConf(0x%p)\n", gp_soc_info, pWmtHifConf); + return -WMT_ERRCODE_NULL_FUNC_POINTER; + } + + hw_ver = gp_soc_info->u4HwVer; + + /* 4 <3.2> start init for BTIF */ + if (pWmtHifConf->hifType == WMT_HIF_BTIF) { + + emiInfo = mtk_wcn_consys_soc_get_emi_phy_add(); + if (!emiInfo) { + WMT_ERR_FUNC("get emi info fail!\n"); + return -WMT_ERRCODE_EMI_NOT_READY; + } + /* non-PDA mode, enable full mode before patch download */ + if (!emiInfo->pda_dl_patch_flag) { + iRet = _wmt_soc_mode_ctrl(MTKSTP_BTIF_FULL_MODE); + if (iRet) { + WMT_ERR_FUNC("config btif full mode fail!\n"); + return -WMT_ERRCODE_STP_CONFIG_FAIL; + } + } + } + + /* Check whether need to update property of patch version. + * If yes, notify stp_launcher to update. + */ + if (wmt_lib_get_need_update_patch_version()) { + wmt_lib_set_need_update_patch_version(0); + mtk_wcn_soc_update_patch_version(); + WMT_INFO_FUNC("wmt update patch version\n"); + } + +#if CFG_WMT_POWER_ON_DLM + if (wmt_ic_ops_soc.options & OPT_POWER_ON_DLM_TABLE) { + iRet = wmt_core_init_script(wmt_power_on_dlm_table, + osal_array_size(wmt_power_on_dlm_table)); + if (iRet) { + WMT_ERR_FUNC("wmt_power_on_dlm_table fail(%d)\n", iRet); + return -WMT_ERRCODE_INIT_DLM_TABLE_FAIL; + } + WMT_DBG_FUNC("wmt_power_on_dlm_table ok\n"); + } +#endif + /* 6. download patch */ +#if CFG_WMT_MULTI_PATCH + /* 6.1 Let launcher to search patch info */ + /* 6.2 Read patch number */ + /* If patch number is 0, it's first time connys power on */ + if ((wmt_ic_ops_soc.options & OPT_DISABLE_ROM_PATCH_DWN) == 0) { + patch_num = mtk_wcn_soc_get_patch_num(); + while (patch_num == 0 || wmt_lib_get_patch_info() == NULL) { + if (retry-- <= 0) { + WMT_ERR_FUNC("patch info retry fail, patch num = %d\n", patch_num); + return -WMT_ERRCODE_PATCH_INFO_FAIL; + } + iRet = mtk_wcn_soc_patch_info_prepare(); + if (iRet) + WMT_ERR_FUNC("patch info perpare fail(%d)\n", iRet); + patch_num = mtk_wcn_soc_get_patch_num(); + } + WMT_INFO_FUNC("patch total num = [%d]\n", patch_num); + } else + patch_num = 0; +#if CFG_WMT_PATCH_DL_OPTM + if (patch_num != 0) { + if (wmt_ic_ops_soc.options & OPT_SET_MCUCLK_TABLE_1_2) { + iRet = wmt_core_init_script(set_mcuclk_table_1, osal_array_size(set_mcuclk_table_1)); + if (iRet) { + WMT_ERR_FUNC("set_mcuclk_table_1 fail(%d)\n", iRet); + return -WMT_ERRCODE_INIT_MCUCLK_TABLE_FAIL; + } + } else if (wmt_ic_ops_soc.options & OPT_SET_MCUCLK_TABLE_3_4) { + iRet = wmt_core_init_script(set_mcuclk_table_3, osal_array_size(set_mcuclk_table_3)); + if (iRet) { + WMT_ERR_FUNC("set_mcuclk_table_3 fail(%d)\n", iRet); + return -WMT_ERRCODE_INIT_MCUCLK_TABLE_FAIL; + } + } + } +#endif + /* 6.3 Multi-patch Patch download */ + WMT_STEP_DO_ACTIONS_FUNC(STEP_TRIGGER_POINT_POWER_ON_BEFORE_SEND_DOWNLOAD_PATCH); + for (patch_index = 0; patch_index < patch_num; patch_index++) { + iRet = mtk_wcn_soc_patch_dwn(patch_index); + if (iRet) { + WMT_ERR_FUNC("patch dwn fail (%d),patch_index(%d)\n", iRet, patch_index); + return -WMT_ERRCODE_PATCH_DWN_FAIL; + } + if (patch_index == (patch_num - 1)) + WMT_STEP_DO_ACTIONS_FUNC(STEP_TRIGGER_POINT_POWER_ON_BEFORE_CONNSYS_RESET); + + iRet = wmt_core_init_script(init_table_3, osal_array_size(init_table_3)); + if (iRet) { + WMT_ERR_FUNC("init_table_3 fail(%d)\n", iRet); + return -WMT_ERRCODE_PATCH_DWN_FAIL; + } + } + +#if CFG_WMT_PATCH_DL_OPTM + if (patch_num != 0) { + if (wmt_ic_ops_soc.options & OPT_SET_MCUCLK_TABLE_1_2) { + iRet = wmt_core_init_script(set_mcuclk_table_2, osal_array_size(set_mcuclk_table_2)); + if (iRet) { + WMT_ERR_FUNC("set_mcuclk_table_2 fail(%d)\n", iRet); + return -WMT_ERRCODE_INIT_MCUCLK_TABLE_FAIL; + } + } else if (wmt_ic_ops_soc.options & OPT_SET_MCUCLK_TABLE_3_4) { + iRet = wmt_core_init_script(set_mcuclk_table_4, osal_array_size(set_mcuclk_table_4)); + if (iRet) { + WMT_ERR_FUNC("set_mcuclk_table_4 fail(%d)\n", iRet); + return -WMT_ERRCODE_INIT_MCUCLK_TABLE_FAIL; + } + } + } +#endif + +#else + /* 6.3 Patch download */ + if ((wmt_ic_ops_soc.options & OPT_DISABLE_ROM_PATCH_DWN) == 0) { + WMT_STEP_DO_ACTIONS_FUNC(STEP_TRIGGER_POINT_POWER_ON_BEFORE_SEND_DOWNLOAD_PATCH); + iRet = mtk_wcn_soc_patch_dwn(); + /* If patch download fail, we just ignore this error and let chip init process goes on */ + if (iRet) + WMT_ERR_FUNC("patch dwn fail (%d), just omit\n", iRet); + + /* 6.4. WMT Reset command */ + WMT_STEP_DO_ACTIONS_FUNC(STEP_TRIGGER_POINT_POWER_ON_BEFORE_CONNSYS_RESET); + iRet = wmt_core_init_script(init_table_3, osal_array_size(init_table_3)); + if (iRet) { + WMT_ERR_FUNC("init_table_3 fail(%d)\n", iRet); + return -WMT_ERRCODE_INIT_RESET_CMD_FAIL; + } + } +#endif + + /* PDA mode, enable full mode after patch download */ + if (pWmtHifConf->hifType == WMT_HIF_BTIF && + emiInfo->pda_dl_patch_flag) { + iRet = _wmt_soc_mode_ctrl(MTKSTP_BTIF_FULL_MODE); + if (iRet) { + WMT_ERR_FUNC("config btif full mode fail!\n"); + return -WMT_ERRCODE_STP_CONFIG_FAIL; + } + } + + chipid = wmt_plat_get_soc_chipid(); + WMT_SET_CHIP_ID_CMD[5] = chipid & 0xff; + WMT_SET_CHIP_ID_CMD[6] = (chipid >> 8) & 0xff; + iRet = wmt_core_init_script(set_chipid_script, osal_array_size(set_chipid_script)); + if (iRet) + WMT_ERR_FUNC("wmt_core:set_chipid_script %s(%d)\n", iRet ? "fail" : "ok", iRet); + + if (wmt_ic_ops_soc.options & OPT_QUERY_ADIE) { + iRet = wmt_core_init_script_retry(get_a_die_script, osal_array_size(get_a_die_script), 1, 0); + if (iRet) { + WMT_ERR_FUNC("get_a_die_script fail(%d)\n", iRet); +#ifdef CFG_WMT_EVB + /* prevent printing too much log */ + osal_sleep_ms(1000); +#else + osal_dbg_assert_aee("Connsys A-die is not exist", "Please check Connsys A-die\0"); +#endif + return -WMT_ERRCODE_ADIE_NOT_EXIST; + } + } + + iRet = wmt_init_wifi_config(); + if (iRet) { + WMT_ERR_FUNC("init_wifi_config fail(%d)\n", iRet); + return -WMT_ERRCODE_INIT_WIFI_CONFIG_FAIL; + } + +#ifdef CFG_WMT_READ_EFUSE_VCN33 + /*get CrystalTiming value before set it */ + iRet = wmt_core_tx(get_efuse_vcn33_script[0].cmd, get_efuse_vcn33_script[0].cmdSz, &u4Res, + MTK_WCN_BOOL_FALSE); + if (iRet || (u4Res != get_efuse_vcn33_script[0].cmdSz)) { + WMT_ERR_FUNC("WMT-CORE: write (%s) iRet(%d) cmd len err(%d, %d)\n", + get_efuse_vcn33_script[0].str, iRet, u4Res, get_efuse_vcn33_script[0].cmdSz); + } + /* EVENT BUF */ + osal_memset(get_efuse_vcn33_script[0].evt, 0, get_efuse_vcn33_script[0].evtSz); + iRet = wmt_core_rx(get_efuse_vcn33_script[0].evt, get_efuse_vcn33_script[0].evtSz, &u4Res); + if (iRet || (u4Res != get_efuse_vcn33_script[0].evtSz)) { + WMT_ERR_FUNC("WMT-CORE: read (%s) iRet(%d) evt len err(rx:%d, exp:%d)\n", + get_efuse_vcn33_script[0].str, iRet, u4Res, get_efuse_vcn33_script[0].evtSz); + mtk_wcn_stp_dbg_dump_package(); + } + efuse_d3_vcn33 = WMT_GET_EFUSE_VCN33_EVT[5] & 0x03; + WMT_INFO_FUNC("Read efuse to set PMIC voltage:(%d)\n", efuse_d3_vcn33); + wmt_set_pmic_voltage(efuse_d3_vcn33); +#endif + pWmtGenConf = wmt_get_gen_conf_pointer(); + if (wmt_ic_ops_soc.options & OPT_SET_WIFI_EXT_COMPONENT) { + /* add WMT_COXE_CONFIG_EXT_COMPONENT_OPCODE command for 2G4 eLNA demand*/ + if (pWmtGenConf->coex_wmt_ext_component) { + WMT_INFO_FUNC("coex_wmt_ext_component:0x%x\n", pWmtGenConf->coex_wmt_ext_component); + set_wifi_ext_component_table[0].cmd[5] = pWmtGenConf->coex_wmt_ext_component; + } + iRet = wmt_core_init_script(set_wifi_ext_component_table, + osal_array_size(set_wifi_ext_component_table)); + if (iRet) + WMT_ERR_FUNC("wmt_core:set_wifi_ext_component_table %s(%d)\n", + iRet ? "fail" : "ok", iRet); + } + +#if CFG_WMT_FILTER_MODE_SETTING + if (wmt_ic_ops_soc.options & OPT_WIFI_LTE_COEX) { + wmt_stp_wifi_lte_coex(); + WMT_DBG_FUNC("wmt_stp_wifi_lte_coex done!\n"); + } + if (wmt_ic_ops_soc.options & OPT_COEX_TDM_REQ_ANTSEL_NUM) { + /*get gpio tdm req antsel number */ + ctrlPa1 = 0; + ctrlPa2 = 0; + wmt_core_ctrl(WMT_CTRL_GET_TDM_REQ_ANTSEL, &ctrlPa1, &ctrlPa2); + WMT_INFO_FUNC("get GPIO TDM REQ ANTSEL number(%lu)\n", ctrlPa1); + /*set gpio tdm req antsel number to firmware */ + WMT_COEX_TDM_REQ_ANTSEL_NUM_CMD[5] = ctrlPa1; + iRet = wmt_core_init_script(get_tdm_req_antsel_num_table, + osal_array_size(get_tdm_req_antsel_num_table)); + if (iRet) + WMT_ERR_FUNC("get_tdm_req_antsel_num_table fail(%d)\n", iRet); + } +#endif + WMT_INFO_FUNC("bt_tssi_from_wifi=%d, bt_tssi_target=%d\n", + pWmtGenConf->bt_tssi_from_wifi, pWmtGenConf->bt_tssi_target); + if (pWmtGenConf->bt_tssi_from_wifi) { + if (wmt_ic_ops_soc.options & OPT_BT_TSSI_FROM_WIFI_CONFIG_NEW_OPID) + WMT_BT_TSSI_FROM_WIFI_CONFIG_CMD[4] = 0x10; + + WMT_BT_TSSI_FROM_WIFI_CONFIG_CMD[5] = pWmtGenConf->bt_tssi_from_wifi; + WMT_BT_TSSI_FROM_WIFI_CONFIG_CMD[6] = (pWmtGenConf->bt_tssi_target & 0x00FF) >> 0; + WMT_BT_TSSI_FROM_WIFI_CONFIG_CMD[7] = (pWmtGenConf->bt_tssi_target & 0xFF00) >> 8; + iRet = wmt_core_init_script(bt_tssi_from_wifi_table, osal_array_size(bt_tssi_from_wifi_table)); + if (iRet) + WMT_ERR_FUNC("bt_tssi_from_wifi_table fail(%d)\n", iRet); + } + + /* init epa before start RF calibration */ + /* for chip 0x6739 */ + iRet = wmt_stp_init_epa(); + + if (iRet) { + WMT_ERR_FUNC("init_epa fail(%d)\n", iRet); + return -WMT_ERRCODE_INIT_EPA_FAIL; + } + + /* for chip 0x6779 */ + iRet = wmt_stp_init_epa_elna(); + + if (iRet) { + WMT_ERR_FUNC("init_epa_elna fail(%d)\n", iRet); + return -WMT_ERRCODE_INIT_EPA_ELNA_FAIL; + } + + iRet = wmt_stp_init_epa_elna_invert_cr(); + if (iRet) { + WMT_ERR_FUNC("init_invert_cr fail(%d)\n", iRet); + return -WMT_ERRCODE_INIT_EPA_ELNA_INVERT_CR_FAIL; + } + + /* init coex before start RF calibration */ + if (wmt_ic_ops_soc.options & OPT_INIT_COEX_BEFORE_RF_CALIBRATION) { + iRet = wmt_stp_init_coex(); + if (iRet) { + WMT_ERR_FUNC("init_coex fail(%d)\n", iRet); + return -WMT_ERRCODE_INIT_COEX_FAIL; + } + WMT_DBG_FUNC("init_coex ok\n"); + } + + iRet = wmt_stp_init_wifi_ant_swap(); + + if (iRet) { + WMT_ERR_FUNC("init_wifi_ant_swap fail(%d)\n", iRet); + WMT_INFO_FUNC("A-DIE chip id=0x%x", mtk_wcn_consys_get_adie_chipid()); + } + + /* 7. start RF calibration data */ + iRet = mtk_wcn_soc_calibration(); + if (iRet) { + WMT_ERR_FUNC("calibration failed\n"); + return -WMT_ERRCODE_CALIBRATION_FAIL; + } + + /* turn off VCN28 after reading efuse */ + ctrlPa1 = EFUSE_PALDO; + ctrlPa2 = PALDO_OFF; + iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); + + if (wmt_ic_ops_soc.options & OPT_INIT_COEX_AFTER_RF_CALIBRATION) { + iRet = wmt_stp_init_coex(); + if (iRet) { + WMT_ERR_FUNC("init_coex fail(%d)\n", iRet); + return -WMT_ERRCODE_INIT_COEX_FAIL; + } + WMT_DBG_FUNC("init_coex ok\n"); + } + + if (wmt_ic_ops_soc.options & OPT_COEX_CONFIG_ADJUST) { + WMT_INFO_FUNC("coex_config_bt_ctrl:0x%x\n", pWmtGenConf->coex_config_bt_ctrl); + coex_config_addjust_table[0].cmd[5] = pWmtGenConf->coex_config_bt_ctrl; + WMT_INFO_FUNC("coex_config_bt_ctrl_mode:0x%x\n", pWmtGenConf->coex_config_bt_ctrl_mode); + coex_config_addjust_table[0].cmd[6] = pWmtGenConf->coex_config_bt_ctrl_mode; + WMT_INFO_FUNC("coex_config_bt_ctrl_rw:0x%x\n", pWmtGenConf->coex_config_bt_ctrl_rw); + coex_config_addjust_table[0].cmd[7] = pWmtGenConf->coex_config_bt_ctrl_rw; + + WMT_INFO_FUNC("coex_config_addjust_opp_time_ratio:0x%x\n", + pWmtGenConf->coex_config_addjust_opp_time_ratio); + coex_config_addjust_table[1].cmd[5] = pWmtGenConf->coex_config_addjust_opp_time_ratio; + WMT_INFO_FUNC("coex_config_addjust_opp_time_ratio_bt_slot:0x%x\n", + pWmtGenConf->coex_config_addjust_opp_time_ratio_bt_slot); + coex_config_addjust_table[1].cmd[6] = + pWmtGenConf->coex_config_addjust_opp_time_ratio_bt_slot; + WMT_INFO_FUNC("coex_config_addjust_opp_time_ratio_wifi_slot:0x%x\n", + pWmtGenConf->coex_config_addjust_opp_time_ratio_wifi_slot); + coex_config_addjust_table[1].cmd[7] = + pWmtGenConf->coex_config_addjust_opp_time_ratio_wifi_slot; + + WMT_INFO_FUNC("coex_config_addjust_ble_scan_time_ratio:0x%x\n", + pWmtGenConf->coex_config_addjust_ble_scan_time_ratio); + coex_config_addjust_table[2].cmd[5] = + pWmtGenConf->coex_config_addjust_ble_scan_time_ratio; + WMT_INFO_FUNC("coex_config_addjust_ble_scan_time_ratio_bt_slot:0x%x\n", + pWmtGenConf->coex_config_addjust_ble_scan_time_ratio_bt_slot); + coex_config_addjust_table[2].cmd[6] = + pWmtGenConf->coex_config_addjust_ble_scan_time_ratio_bt_slot; + WMT_INFO_FUNC("coex_config_addjust_ble_scan_time_ratio_wifi_slot:0x%x\n", + pWmtGenConf->coex_config_addjust_ble_scan_time_ratio_wifi_slot); + coex_config_addjust_table[2].cmd[7] = + pWmtGenConf->coex_config_addjust_ble_scan_time_ratio_wifi_slot; + + /* COEX flag is different in these project. */ + if (wmt_ic_ops_soc.options & OPT_COEX_CONFIG_ADJUST_NEW_FLAG) { + coex_config_addjust_table[0].cmd[4] = 0x1e; + coex_config_addjust_table[1].cmd[4] = 0x1f; + coex_config_addjust_table[2].cmd[4] = 0x20; + } + + iRet = wmt_core_init_script(coex_config_addjust_table, + osal_array_size(coex_config_addjust_table)); + if (iRet) + WMT_ERR_FUNC("wmt_core:coex_config_addjust_table %s(%d)\n", + iRet ? "fail" : "ok", iRet); + } + +#if CFG_WMT_CRYSTAL_TIMING_SET + mtk_wcn_soc_crystal_triming_set(); +#endif + +#if CFG_WMT_SDIO_DRIVING_SET + mtk_wcn_soc_set_sdio_driving(); +#endif + + if (wmt_ic_ops_soc.options & OPT_SET_OSC_TYPE) { + if (wmt_plat_soc_co_clock_flag_get() == WMT_CO_CLOCK_EN) { + WMT_INFO_FUNC("co-clock enabled.\n"); + + iRet = wmt_core_init_script(osc_type_table, osal_array_size(osc_type_table)); + if (iRet) { + WMT_ERR_FUNC("osc_type_table fail(%d), goes on\n", iRet); + return -WMT_ERRCODE_INIT_COCLOCK_TYPE_FAIL; + } + } else { + WMT_WARN_FUNC("co-clock disabled.\n"); + } + } +#if (MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT) + iRet = wmt_core_init_script(merge_pcm_table, osal_array_size(merge_pcm_table)); + if (iRet) { + WMT_ERR_FUNC("merge_pcm_table fail(%d), goes on\n", iRet); + return -WMT_ERRCODE_INIT_MERGE_PCM_TABLE_FAIL; + } +#endif + + /* 15. Set FM strap */ + WMT_STRAP_CONF_CMD_FM_COMM[5] = (UINT8) pWmtHifConf->au4StrapConf[0]; + WMT_STRAP_CONF_EVT[5] = (UINT8) pWmtHifConf->au4StrapConf[0]; + iRet = wmt_core_init_script(init_table_5_1, osal_array_size(init_table_5_1)); + if (iRet) { + WMT_ERR_FUNC("init_table_5_1 fm mode(%d) fail(%d)\n", pWmtHifConf->au4StrapConf[0], iRet); + return -WMT_ERRCODE_INIT_FM_MODE_FAIL; + } + WMT_DBG_FUNC("set fm mode (%d) ok\n", pWmtHifConf->au4StrapConf[0]); + +#if CFG_SET_OPT_REG /*set registers */ + iRet = wmt_core_init_script(set_registers, osal_array_size(set_registers)); + if (iRet) { + WMT_ERR_FUNC("set_registers fail(%d)", iRet); + return -WMT_ERRCODE_INIT_SET_REGISTER_FAIL; + } +#endif + + if (wmt_ic_ops_soc.options & OPT_SET_COREDUMP_LEVEL) { + if (mtk_wcn_stp_coredump_flag_get() != 0) { + iRet = wmt_core_init_script(init_table_6, osal_array_size(init_table_6)); + if (iRet) { + WMT_ERR_FUNC("init_table_6 core dump setting fail(%d)\n", iRet); + return -WMT_ERRCODE_INIT_SET_COREDUMP_FAIL; + } + WMT_DBG_FUNC("enable soc_consys firmware coredump\n"); + } else { + WMT_DBG_FUNC("disable soc_consys firmware coredump\n"); + } + } + +#if CFG_WMT_WIFI_5G_SUPPORT + dDieChipid = wmt_ic_ops_soc.icId; + WMT_DBG_FUNC("current SOC chipid is 0x%x\n", dDieChipid); + if (wmt_ic_ops_soc.options & OPT_WIFI_5G_PALDO) { + /* read A die chipid by wmt cmd */ + iRet = + wmt_core_tx((PUINT8) &WMT_GET_SOC_ADIE_CHIPID_CMD[0], sizeof(WMT_GET_SOC_ADIE_CHIPID_CMD), &u4Res, + MTK_WCN_BOOL_FALSE); + if (iRet || (u4Res != sizeof(WMT_GET_SOC_ADIE_CHIPID_CMD))) { + WMT_ERR_FUNC("wmt_core:read A die chipid CMD fail(%d),size(%d)\n", iRet, u4Res); + return -WMT_ERRCODE_READ_ADIE_TX_CMD_FAIL; + } + osal_memset(evtbuf, 0, sizeof(evtbuf)); + iRet = wmt_core_rx(evtbuf, sizeof(WMT_GET_SOC_ADIE_CHIPID_EVT), &u4Res); + if (iRet || (u4Res != sizeof(WMT_GET_SOC_ADIE_CHIPID_EVT))) { + WMT_ERR_FUNC("wmt_core:read A die chipid EVT fail(%d),size(%d)\n", iRet, u4Res); + WMT_INFO_FUNC("buf:[%2X,%2X,%2X,%2X,%2X] evt:[%2X,%2X,%2X,%2X,%2X]\n", + evtbuf[0], evtbuf[1], evtbuf[2], evtbuf[3], evtbuf[4], + WMT_GET_SOC_ADIE_CHIPID_EVT[0], + WMT_GET_SOC_ADIE_CHIPID_EVT[1], + WMT_GET_SOC_ADIE_CHIPID_EVT[2], + WMT_GET_SOC_ADIE_CHIPID_EVT[3], + WMT_GET_SOC_ADIE_CHIPID_EVT[4]); + mtk_wcn_stp_dbg_dump_package(); + return -WMT_ERRCODE_READ_ADIE_RX_EVT_FAIL; + } + + osal_memcpy(&aDieChipid, &evtbuf[u4Res - 2], 2); + WMT_INFO_FUNC("get SOC A die chipid(0x%x)\n", aDieChipid); + + if (aDieChipid == 0x6625) { + iRet = + wmt_core_tx((PUINT8) &WMT_GET_SOC_6625_L_CMD[0], sizeof(WMT_GET_SOC_6625_L_CMD), &u4Res, + MTK_WCN_BOOL_FALSE); + if (iRet || (u4Res != sizeof(WMT_GET_SOC_6625_L_CMD))) + WMT_ERR_FUNC("wmt_core:read A die efuse CMD fail(%d),size(%d)\n", iRet, u4Res); + osal_memset(evtbuf, 0, sizeof(evtbuf)); + iRet = wmt_core_rx(evtbuf, sizeof(WMT_GET_SOC_6625_L_EVT), &u4Res); + if (iRet || (u4Res != sizeof(WMT_GET_SOC_6625_L_EVT))) { + WMT_ERR_FUNC("wmt_core:read A die efuse EVT fail(%d),size(%d)\n", iRet, u4Res); + WMT_INFO_FUNC("buf:[%2X,%2X,%2X,%2X] evt:[%2X,%2X,%2X,%2X]\n", + evtbuf[0], evtbuf[1], evtbuf[2], evtbuf[3], + WMT_GET_SOC_6625_L_EVT[0], + WMT_GET_SOC_6625_L_EVT[1], + WMT_GET_SOC_6625_L_EVT[2], + WMT_GET_SOC_6625_L_EVT[3]); + mtk_wcn_stp_dbg_dump_package(); + } + WMT_INFO_FUNC("read SOC Adie Efuse(0x120) value:0x%2x,0x%2x,0x%2x,0x%2x -> %s\n", + evtbuf[u4Res - 4], evtbuf[u4Res - 3], evtbuf[u4Res - 2], evtbuf[u4Res - 1], + evtbuf[u4Res - 2] == 0x31 ? "MT6625L" : "MT6625"); + } + /* get PMIC chipid */ + + ctrlData.ctrlId = WMT_CTRL_SOC_PALDO_CTRL; + ctrlData.au4CtrlData[0] = PMIC_CHIPID_PALDO; + ctrlData.au4CtrlData[1] = 0; + iRet = wmt_ctrl(&ctrlData); + if (iRet < 0) { + WMT_ERR_FUNC("wmt_core: read PMIC chipid fail(%d)\n", iRet); + return -WMT_ERRCODE_READ_PMIC_CHIPID_FAIL; + } + pmicChipid = ctrlData.au4CtrlData[2]; + WMT_INFO_FUNC("current PMIC chipid(0x%x)\n", pmicChipid); + + /* MT6625 & MT6322, write 1 to 0x0414[12] */ + /* MT6625 & MT6323, assert */ + /* MT6627 & (MT6322 or MT6323),write 0 to 0x0414[12] */ + + switch (aDieChipid) { + case 0x6625: + if (pmicChipid == 0x6322 || pmicChipid == 0x6356) { + WMT_INFO_FUNC("wmt-core:enable wifi 5G support\n"); + ctrlPa1 = WIFI_5G_PALDO; + ctrlPa2 = PALDO_ON; + wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); + } else if (pmicChipid == 0x6323) { + osal_assert(0); + } else { + WMT_WARN_FUNC("wmt-core: unknown PMIC chipid\n"); + } + break; + case 0x6627: + if ((pmicChipid == 0x6322) || (pmicChipid == 0x6323)) { + WMT_INFO_FUNC("wmt-core: disable wifi 5G support\n"); + ctrlPa1 = WIFI_5G_PALDO; + ctrlPa2 = PALDO_OFF; + wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); + } else { + WMT_WARN_FUNC("wmt-core: unknown PMIC chipid\n"); + } + break; + default: + WMT_WARN_FUNC("wmt-core: unknown A die chipid(0x%x)\n", aDieChipid); + break; + } + } +#endif + +#if 1 + ctrlData.ctrlId = WMT_CTRL_SET_STP_DBG_INFO; + ctrlData.au4CtrlData[0] = wmt_ic_ops_soc.icId; + ctrlData.au4CtrlData[1] = (SIZE_T) gp_soc_info->cChipVersion; + ctrlData.au4CtrlData[2] = (SIZE_T) &gp_soc_patch_info; + iRet = wmt_ctrl(&ctrlData); + if (iRet) { + WMT_ERR_FUNC("set stp dbg info fail(%d)\n", iRet); + return -WMT_ERRCODE_SET_STP_DBG_INFO_FAIL; + } +#endif + +#if CFG_WMT_PS_SUPPORT + osal_assert(gp_soc_info != NULL); + if (gp_soc_info != NULL) { + if (gp_soc_info->bPsmSupport != MTK_WCN_BOOL_FALSE) + wmt_lib_ps_enable(); + else + wmt_lib_ps_disable(); + } +#endif + + WMT_STEP_DO_ACTIONS_FUNC(STEP_TRIGGER_POINT_POWER_ON_END); + + return 0; +} + +static INT32 mtk_wcn_soc_sw_deinit(P_WMT_HIF_CONF pWmtHifConf) +{ + WMT_DBG_FUNC(" start\n"); + +#if CFG_WMT_PS_SUPPORT + osal_assert(gp_soc_info != NULL); + if ((gp_soc_info != NULL) + && (gp_soc_info->bPsmSupport != MTK_WCN_BOOL_FALSE)) { + wmt_lib_ps_disable(); + } +#endif + + gp_soc_info = NULL; + + return 0; +} + +static INT32 mtk_wcn_soc_aif_ctrl(WMT_IC_PIN_STATE state, UINT32 flag) +{ + INT32 ret = -1; + UINT32 val; + + if ((flag & WMT_LIB_AIF_FLAG_MASK) == WMT_LIB_AIF_FLAG_SHARE) { + WMT_INFO_FUNC("PCM & I2S PIN SHARE\n"); +#if 0 + switch (state) { + case WMT_IC_AIF_0: + /* BT_PCM_OFF & FM line in/out */ + val = 0x00000770; + ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); + val = 0x00000000; + ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); + break; + + case WMT_IC_AIF_1: + /* BT_PCM_ON & FM line in/out */ + val = 0x00000700; + ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); + val = 0x00000000; + ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); + break; + + case WMT_IC_AIF_2: + /* BT_PCM_OFF & FM I2S */ + val = 0x00000710; + ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); + val = 0x00000800; /* 800:3-wire, 000: 4-wire */ + ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); + break; + default: + WMT_ERR_FUNC("unsupported state (%d)\n", state); + ret = -1; + break; + } +#else + WMT_WARN_FUNC("TBD!!"); + ret = 0; +#endif + } else { + /*PCM & I2S separate */ + WMT_INFO_FUNC("PCM & I2S PIN SEPARATE\n"); +#if 0 + switch (state) { + case WMT_IC_AIF_0: + /* BT_PCM_OFF & FM line in/out */ + val = 0x00000770; + ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); + val = 0x00000000; + ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); + break; + + case WMT_IC_AIF_1: + /* BT_PCM_ON & FM line in/out */ + val = 0x00000700; + ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); + val = 0x00000000; + ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); + break; + + case WMT_IC_AIF_2: + /* BT_PCM_OFF & FM I2S */ + val = 0x00000070; + ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); + val = 0x00000800; /* 800:3-wire, 000: 4-wire */ + ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); + + break; + case WMT_IC_AIF_3: + val = 0x00000000; + ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); + val = 0x00000800; /* 800:3-wire, 000: 4-wire */ + ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); + + break; + default: + WMT_ERR_FUNC("unsupported state (%d)\n", state); + ret = -1; + break; + } +#else + switch (state) { + case WMT_IC_AIF_0: + /* BT_PCM_OFF & FM line in/out */ + ret = 0; + break; + case WMT_IC_AIF_1: + /* BT_PCM_ON & FM line in/out */ + ret = 0; + break; + + case WMT_IC_AIF_2: + /* BT_PCM_OFF & FM I2S */ + val = 0x01110000; + ret = wmt_core_reg_rw_raw(1, 0x80050078, &val, 0x0FFF0000); + + break; + case WMT_IC_AIF_3: + ret = 0; + break; + + default: + WMT_ERR_FUNC("unsupported state (%d)\n", state); + ret = -1; + break; + } +#endif + } + + if (!ret) + WMT_WARN_FUNC("new state(%d) fail(%d)\n", state, ret); + WMT_INFO_FUNC("new state(%d) ok\n", state); + + return ret; +} + +static INT32 mtk_wcn_soc_gps_sync_ctrl(WMT_IC_PIN_STATE state, UINT32 flag) +{ + INT32 iRet = -1; + UINT32 uVal = 0; + + /* gen3(6631) CONSYS can not access reg:0x80050078 and no need to do GPS SYNC + * may cause bus hang + */ + if (wmt_ic_ops_soc.options & OPT_GPS_SYNC) { + if (state == WMT_IC_PIN_MUX) + uVal = 0x1 << 28; + else + uVal = 0x5 << 28; + iRet = wmt_core_reg_rw_raw(1, 0x80050078, &uVal, 0x7 << 28); + if (iRet) + WMT_ERR_FUNC("gps_sync pin ctrl failed, iRet(%d)\n", iRet); + } else + WMT_INFO_FUNC("This chip no need to sync GPS and MODEM!\n"); + + /* anyway, we return 0 */ + return 0; +} + +static INT32 mtk_wcn_soc_pin_ctrl(WMT_IC_PIN_ID id, WMT_IC_PIN_STATE state, UINT32 flag) +{ + INT32 ret; + + WMT_DBG_FUNC("ic pin id:%d, state:%d, flag:0x%x\n", id, state, flag); + + ret = -1; + switch (id) { + case WMT_IC_PIN_AUDIO: + ret = mtk_wcn_soc_aif_ctrl(state, flag); + break; + + case WMT_IC_PIN_EEDI: + WMT_WARN_FUNC("TBD!!"); + /* We just return 0 here, prevent from WMT-FUNC do other register read/write */ + ret = 0; + break; + + case WMT_IC_PIN_EEDO: + WMT_WARN_FUNC("TBD!!"); + /* We just return 0 here, prevent from WMT-FUNC do other register read/write */ + ret = 0; + break; + case WMT_IC_PIN_GSYNC: + ret = mtk_wcn_soc_gps_sync_ctrl(state, flag); + break; + default: + break; + } + WMT_INFO_FUNC("ret = (%d)\n", ret); + + return ret; +} + +INT32 mtk_wcn_soc_co_clock_ctrl(WMT_CO_CLOCK on) +{ + INT32 iRet = 0; + + if ((on >= WMT_CO_CLOCK_DIS) && (on < WMT_CO_CLOCK_MAX)) { + gCoClockEn = on; + } else { + WMT_DBG_FUNC("0x%x: error parameter:%d\n", wmt_ic_ops_soc.icId, on); + iRet = -1; + } + WMT_DBG_FUNC("0x%x: Co-clock %s\n", wmt_ic_ops_soc.icId, + (gCoClockEn == WMT_CO_CLOCK_DIS) ? "disabled" : "enabled"); + + return iRet; +} + +static MTK_WCN_BOOL mtk_wcn_soc_quick_sleep_flag_get(VOID) +{ + return MTK_WCN_BOOL_TRUE; +} + +static MTK_WCN_BOOL mtk_wcn_soc_aee_dump_flag_get(VOID) +{ + return MTK_WCN_BOOL_FALSE; +} +static MTK_WCN_BOOL mtk_wcn_soc_trigger_assert(VOID) +{ + INT32 ret = 0; + UINT32 u4Res; + UINT32 tstCmdSz = 0; + UINT32 tstEvtSz = 0; + UINT8 tstCmd[64]; + UINT8 tstEvt[64]; + UINT8 WMT_ASSERT_CMD[] = { 0x01, 0x02, 0x01, 0x00, 0x08 }; + UINT8 WMT_ASSERT_EVT[] = { 0x02, 0x02, 0x00, 0x00, 0x00 }; + + WMT_INFO_FUNC("Send Assert command !\n"); + tstCmdSz = osal_sizeof(WMT_ASSERT_CMD); + tstEvtSz = osal_sizeof(WMT_ASSERT_EVT); + osal_memcpy(tstCmd, WMT_ASSERT_CMD, tstCmdSz); + osal_memcpy(tstEvt, WMT_ASSERT_EVT, tstEvtSz); + + ret = wmt_core_tx((PUINT8) tstCmd, tstCmdSz, &u4Res, MTK_WCN_BOOL_FALSE); + if (ret || (u4Res != tstCmdSz)) { + WMT_ERR_FUNC("WMT-CORE: wmt_cmd_test iRet(%d) cmd len err(%d, %d)\n", ret, u4Res, + tstCmdSz); + ret = -1; + } + return (ret == 0); +} + +static INT32 mtk_wcn_soc_ver_check(VOID) +{ + UINT32 hw_ver = 0; + UINT32 fw_ver = 0; + INT32 iret; + const WMT_IC_INFO_S *p_info = NULL; + unsigned long ctrlPa1; + unsigned long ctrlPa2; + + /* 1. identify chip versions: HVR(HW_VER) and FVR(FW_VER) */ + WMT_LOUD_FUNC("0x%x: before read hw_ver (hw version)\n", wmt_ic_ops_soc.icId); + iret = wmt_core_reg_rw_raw(0, GEN_HVR, &hw_ver, GEN_VER_MASK); + if (iret) { + WMT_ERR_FUNC("0x%x: read hw_ver fail:%d\n", wmt_ic_ops_soc.icId, iret); + return -2; + } + WMT_DBG_FUNC("0x%x: read hw_ver (hw version) (0x%x)\n", wmt_ic_ops_soc.icId, hw_ver); + + WMT_LOUD_FUNC("0x%x: before fw_ver (rom version)\n", wmt_ic_ops_soc.icId); + wmt_core_reg_rw_raw(0, GEN_FVR, &fw_ver, GEN_VER_MASK); + if (iret) { + WMT_ERR_FUNC("0x%x: read fw_ver fail:%d\n", wmt_ic_ops_soc.icId, iret); + return -2; + } + WMT_DBG_FUNC("0x%x: read fw_ver (rom version) (0x%x)\n", wmt_ic_ops_soc.icId, fw_ver); + + p_info = mtk_wcn_soc_find_wmt_ic_info(hw_ver); + if (p_info == NULL) { + WMT_ERR_FUNC("0x%x: hw_ver(0x%x) find wmt ic info fail\n", wmt_ic_ops_soc.icId, hw_ver); + return -3; + } + WMT_WARN_FUNC("0x%x: ic info: %s.%s (0x%x/0x%x, HWVER:0x%04x, patch_ext:%s)\n", + wmt_ic_ops_soc.icId, p_info->cChipName, p_info->cChipVersion, + hw_ver, fw_ver, p_info->u4HwVer, p_info->cPatchNameExt); + + /* hw id & version */ + ctrlPa1 = (wmt_ic_ops_soc.icId << 16) | (hw_ver & 0x0000FFFF); + /* translated fw rom version */ + ctrlPa2 = (fw_ver & 0x0000FFFF); + + iret = wmt_core_ctrl(WMT_CTRL_HWIDVER_SET, &ctrlPa1, &ctrlPa2); + if (iret) + WMT_WARN_FUNC("0x%x: WMT_CTRL_HWIDVER_SET fail(%d)\n", wmt_ic_ops_soc.icId, iret); + + gp_soc_info = p_info; + return 0; +} + +static const WMT_IC_INFO_S *mtk_wcn_soc_find_wmt_ic_info(const UINT32 hw_ver) +{ + /* match chipversion with u4HwVer item in mtk_wcn_soc_info_table */ + const UINT32 size = osal_array_size(mtk_wcn_soc_info_table); + INT32 index = 0; + + /* George: reverse the search order to favor newer version products + * TODO:[FixMe][GeorgeKuo] Remove full match once API wmt_lib_get_hwver() + * is changed correctly in the future!! + * Leave full match here is a workaround for GPS to distinguish E3/E4 ICs. + */ + index = size - 1; + /* full match */ + while ((index >= 0) && (hw_ver != mtk_wcn_soc_info_table[index].u4HwVer)) + --index; + if (index >= 0) { + WMT_DBG_FUNC("found ic info(0x%x) by full match! index:%d\n", hw_ver, index); + return &mtk_wcn_soc_info_table[index]; + } + + WMT_WARN_FUNC("find no ic info for (0x%x) by full match!try major num match!\n", hw_ver); + + /* George: The ONLY CORRECT method to find supported hw table. Match MAJOR + * NUM only can help us support future minor hw ECO, or fab switch, etc. + * FULL matching eliminate such flexibility and software package have to be + * updated EACH TIME even when minor hw ECO or fab switch!!! + */ + /* George: reverse the search order to favor newer version products */ + index = size - 1; + /* major num match */ + while ((index >= 0) && + (MAJORNUM(hw_ver) != MAJORNUM(mtk_wcn_soc_info_table[index].u4HwVer))) { + --index; + } + if (index >= 0) { + WMT_DBG_FUNC("0x%x: found ic info for hw_ver(0x%x) by major num! index:%d\n", + wmt_ic_ops_soc.icId, hw_ver, index); + return &mtk_wcn_soc_info_table[index]; + } + + WMT_ERR_FUNC("0x%x: find no ic info for hw_ver(0x%x) by full match nor major num match!\n", + wmt_ic_ops_soc.icId, hw_ver); + WMT_ERR_FUNC("Set default chip version: E1!\n"); + return &mtk_wcn_soc_info_table[0]; +} + +#if CFG_WMT_FILTER_MODE_SETTING +static INT32 wmt_stp_wifi_lte_coex(VOID) +{ + INT32 iRet; + unsigned long addr = 0; + WMT_GEN_CONF *pWmtGenConf = NULL; + + /*Get wmt config */ + iRet = wmt_core_ctrl(WMT_CTRL_GET_WMT_CONF, &addr, 0); + if (iRet) { + WMT_ERR_FUNC("ctrl GET_WMT_CONF fail(%d)\n", iRet); + return -2; + } + WMT_DBG_FUNC("ctrl GET_WMT_CONF ok(0x%08lx)\n", addr); + + pWmtGenConf = (P_WMT_GEN_CONF) addr; + + /*Check if WMT.cfg exists */ + if (pWmtGenConf->cfgExist == 0) { + WMT_INFO_FUNC("cfgExist == 0, skip config chip\n"); + /*if WMT.cfg not existed, still return success and adopt the default value */ + return 0; + } + + osal_sleep_ms(5); + + if (pWmtGenConf->coex_wmt_filter_mode == 0) { + WMT_STEP_DO_ACTIONS_FUNC(STEP_TRIGGER_POINT_POWER_ON_BEFORE_SET_WIFI_LTE_COEX); + if (wmt_ic_ops_soc.options & OPT_WIFI_LTE_COEX_TABLE_1) { + iRet = + wmt_core_init_script(set_wifi_lte_coex_table_1, osal_array_size(set_wifi_lte_coex_table_1)); + WMT_DBG_FUNC("wmt_core:set_wifi_lte_coex_table_1 %s(%d)\n", iRet ? "fail" : "ok", iRet); + } else if (wmt_ic_ops_soc.options & OPT_WIFI_LTE_COEX_TABLE_2) { + /* add WMT_COXE_CONFIG_EXT_COMPONENT_OPCODE command for 2G4 eLNA demand*/ + if (pWmtGenConf->coex_wmt_ext_component) { + WMT_INFO_FUNC("coex_wmt_ext_component:0x%x\n", pWmtGenConf->coex_wmt_ext_component); + set_wifi_lte_coex_table_2[0].cmd[5] = pWmtGenConf->coex_wmt_ext_component; + } + iRet = + wmt_core_init_script(set_wifi_lte_coex_table_2, osal_array_size(set_wifi_lte_coex_table_2)); + WMT_DBG_FUNC("wmt_core:set_wifi_lte_coex_table_2 %s(%d)\n", iRet ? "fail" : "ok", iRet); + } else if (wmt_ic_ops_soc.options & OPT_WIFI_LTE_COEX_TABLE_3) { + iRet = + wmt_core_init_script(set_wifi_lte_coex_table_3, + osal_array_size(set_wifi_lte_coex_table_3)); + WMT_DBG_FUNC("wmt_core:set_wifi_lte_coex_table_3 %s(%d)\n", + iRet ? "fail" : "ok", iRet); + } else { + iRet = + wmt_core_init_script(set_wifi_lte_coex_table_0, osal_array_size(set_wifi_lte_coex_table_0)); + WMT_DBG_FUNC("wmt_core:set_wifi_lte_coex_table_0 %s(%d)\n", iRet ? "fail" : "ok", iRet); + } + } + + return iRet; +} +#endif + +static INT32 wmt_stp_init_coex(VOID) +{ + INT32 iRet; + unsigned long addr = 0; + WMT_GEN_CONF *pWmtGenConf = NULL; + +#define COEX_WMT 0 + +#if CFG_SUBSYS_COEX_NEED + /* no need for MT6628 */ +#define COEX_BT 1 +#define COEX_WIFI 2 +#define COEX_PTA 3 +#define COEX_MISC 4 +#else +#define COEX_WIFI_PATH 1 +#define COEX_EXT_ELAN_GAIN_P1 2 +#define COEX_EXT_EPA_MODE 3 +#endif +#define WMT_COXE_CONFIG_ADJUST_ANTENNA_OPCODE 6 + + /*Get wmt config */ + iRet = wmt_core_ctrl(WMT_CTRL_GET_WMT_CONF, &addr, 0); + if (iRet) { + WMT_ERR_FUNC("ctrl GET_WMT_CONF fail(%d)\n", iRet); + return -2; + } + WMT_INFO_FUNC("ctrl GET_WMT_CONF ok(0x%08lx)\n", addr); + + pWmtGenConf = (P_WMT_GEN_CONF) addr; + + /*Check if WMT.cfg exists */ + if (pWmtGenConf->cfgExist == 0) { + WMT_INFO_FUNC("cfgExist == 0, skip config chip\n"); + /*if WMT.cfg not existed, still return success and adopt the default value */ + return 0; + } + + if (wmt_ic_ops_soc.options & OPT_COEX_EXT_ELNA_GAIN_P1_SUPPORT) { + WMT_INFO_FUNC("elna_gain_p1_support:0x%x\n", pWmtGenConf->coex_wmt_ext_elna_gain_p1_support); + if (pWmtGenConf->coex_wmt_ext_elna_gain_p1_support != 1) + return 0; + } + + /*Dump the coex-related info */ + WMT_DBG_FUNC("coex_wmt_ant_mode:0x%x, coex_wmt_wifi_path:0x%x\n", + pWmtGenConf->coex_wmt_ant_mode, pWmtGenConf->coex_wmt_wifi_path); +#if CFG_SUBSYS_COEX_NEED + WMT_DBG_FUNC("coex_bt:0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", + pWmtGenConf->coex_bt_rssi_upper_limit, + pWmtGenConf->coex_bt_rssi_mid_limit, + pWmtGenConf->coex_bt_rssi_lower_limit, + pWmtGenConf->coex_bt_pwr_high, pWmtGenConf->coex_bt_pwr_mid, pWmtGenConf->coex_bt_pwr_low); + WMT_DBG_FUNC("coex_wifi:0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", + pWmtGenConf->coex_wifi_rssi_upper_limit, + pWmtGenConf->coex_wifi_rssi_mid_limit, + pWmtGenConf->coex_wifi_rssi_lower_limit, + pWmtGenConf->coex_wifi_pwr_high, pWmtGenConf->coex_wifi_pwr_mid, pWmtGenConf->coex_wifi_pwr_low); + WMT_DBG_FUNC("coex_ext_pta:0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", + pWmtGenConf->coex_ext_pta_hi_tx_tag, + pWmtGenConf->coex_ext_pta_hi_rx_tag, + pWmtGenConf->coex_ext_pta_lo_tx_tag, + pWmtGenConf->coex_ext_pta_lo_rx_tag, + pWmtGenConf->coex_ext_pta_sample_t1, + pWmtGenConf->coex_ext_pta_sample_t2, pWmtGenConf->coex_ext_pta_wifi_bt_con_trx); + WMT_DBG_FUNC("coex_misc:0x%x 0x%x 0x%x\n", + pWmtGenConf->coex_misc_ext_pta_on, pWmtGenConf->coex_misc_ext_feature_set); +#endif + + /*command adjustion due to WMT.cfg */ + coex_table[COEX_WMT].cmd[4] = WMT_COXE_CONFIG_ADJUST_ANTENNA_OPCODE; + coex_table[COEX_WMT].cmd[5] = pWmtGenConf->coex_wmt_ant_mode; + if (gWmtDbgLvl >= WMT_LOG_DBG) + wmt_core_dump_data(&coex_table[COEX_WMT].cmd[0], coex_table[COEX_WMT].str, coex_table[COEX_WMT].cmdSz); + +#if CFG_SUBSYS_COEX_NEED + coex_table[COEX_BT].cmd[9] = pWmtGenConf->coex_bt_rssi_upper_limit; + coex_table[COEX_BT].cmd[10] = pWmtGenConf->coex_bt_rssi_mid_limit; + coex_table[COEX_BT].cmd[11] = pWmtGenConf->coex_bt_rssi_lower_limit; + coex_table[COEX_BT].cmd[12] = pWmtGenConf->coex_bt_pwr_high; + coex_table[COEX_BT].cmd[13] = pWmtGenConf->coex_bt_pwr_mid; + coex_table[COEX_BT].cmd[14] = pWmtGenConf->coex_bt_pwr_low; + if (gWmtDbgLvl >= WMT_LOG_DBG) + wmt_core_dump_data(&coex_table[COEX_BT].cmd[0], coex_table[COEX_BT].str, coex_table[COEX_BT].cmdSz); + + coex_table[COEX_WIFI].cmd[10] = pWmtGenConf->coex_wifi_rssi_upper_limit; + coex_table[COEX_WIFI].cmd[11] = pWmtGenConf->coex_wifi_rssi_mid_limit; + coex_table[COEX_WIFI].cmd[12] = pWmtGenConf->coex_wifi_rssi_lower_limit; + coex_table[COEX_WIFI].cmd[13] = pWmtGenConf->coex_wifi_pwr_high; + coex_table[COEX_WIFI].cmd[14] = pWmtGenConf->coex_wifi_pwr_mid; + coex_table[COEX_WIFI].cmd[15] = pWmtGenConf->coex_wifi_pwr_low; + if (gWmtDbgLvl >= WMT_LOG_DBG) + wmt_core_dump_data(&coex_table[COEX_WIFI].cmd[0], + coex_table[COEX_WIFI].str, coex_table[COEX_WIFI].cmdSz); + + coex_table[COEX_PTA].cmd[5] = pWmtGenConf->coex_ext_pta_hi_tx_tag; + coex_table[COEX_PTA].cmd[6] = pWmtGenConf->coex_ext_pta_hi_rx_tag; + coex_table[COEX_PTA].cmd[7] = pWmtGenConf->coex_ext_pta_lo_tx_tag; + coex_table[COEX_PTA].cmd[8] = pWmtGenConf->coex_ext_pta_lo_rx_tag; + coex_table[COEX_PTA].cmd[9] = ((pWmtGenConf->coex_ext_pta_sample_t1 & 0xff00) >> 8); + coex_table[COEX_PTA].cmd[10] = ((pWmtGenConf->coex_ext_pta_sample_t1 & 0x00ff) >> 0); + coex_table[COEX_PTA].cmd[11] = ((pWmtGenConf->coex_ext_pta_sample_t2 & 0xff00) >> 8); + coex_table[COEX_PTA].cmd[12] = ((pWmtGenConf->coex_ext_pta_sample_t2 & 0x00ff) >> 0); + coex_table[COEX_PTA].cmd[13] = pWmtGenConf->coex_ext_pta_wifi_bt_con_trx; + if (gWmtDbgLvl >= WMT_LOG_DBG) + wmt_core_dump_data(&coex_table[COEX_PTA].cmd[0], coex_table[COEX_PTA].str, coex_table[COEX_PTA].cmdSz); + + osal_memcpy(&coex_table[COEX_MISC].cmd[5], &pWmtGenConf->coex_misc_ext_pta_on, + sizeof(pWmtGenConf->coex_misc_ext_pta_on)); + osal_memcpy(&coex_table[COEX_MISC].cmd[9], &pWmtGenConf->coex_misc_ext_feature_set, + sizeof(pWmtGenConf->coex_misc_ext_feature_set)); + + wmt_core_dump_data(&coex_table[COEX_MISC].cmd[0], coex_table[COEX_MISC].str, coex_table[COEX_MISC].cmdSz); +#else + coex_table[COEX_WIFI_PATH].cmd[5] = + (UINT8)((pWmtGenConf->coex_wmt_wifi_path & 0x00FF) >> 0); + coex_table[COEX_WIFI_PATH].cmd[6] = + (UINT8)((pWmtGenConf->coex_wmt_wifi_path & 0xFF00) >> 8); + + if (gWmtDbgLvl >= WMT_LOG_DBG) { + wmt_core_dump_data(&coex_table[COEX_WIFI_PATH].cmd[0], + coex_table[COEX_WIFI_PATH].str, coex_table[COEX_WIFI_PATH].cmdSz); + } + + coex_table[COEX_EXT_ELAN_GAIN_P1].cmd[5] = pWmtGenConf->coex_wmt_ext_elna_gain_p1_support; + /* wmt_ext_elna_gain_p1 D0*/ + coex_table[COEX_EXT_ELAN_GAIN_P1].cmd[6] = + (UINT8)((pWmtGenConf->coex_wmt_ext_elna_gain_p1_D0 & 0x000000FF) >> 0); + coex_table[COEX_EXT_ELAN_GAIN_P1].cmd[7] = + (UINT8)((pWmtGenConf->coex_wmt_ext_elna_gain_p1_D0 & 0x0000FF00) >> 8); + coex_table[COEX_EXT_ELAN_GAIN_P1].cmd[8] = + (UINT8)((pWmtGenConf->coex_wmt_ext_elna_gain_p1_D0 & 0x00FF0000) >> 16); + coex_table[COEX_EXT_ELAN_GAIN_P1].cmd[9] = + (UINT8)((pWmtGenConf->coex_wmt_ext_elna_gain_p1_D0 & 0xFF000000) >> 24); + /* wmt_ext_elna_gain_p1 D1*/ + coex_table[COEX_EXT_ELAN_GAIN_P1].cmd[10] = + (UINT8)((pWmtGenConf->coex_wmt_ext_elna_gain_p1_D1 & 0x000000FF) >> 0); + coex_table[COEX_EXT_ELAN_GAIN_P1].cmd[11] = + (UINT8)((pWmtGenConf->coex_wmt_ext_elna_gain_p1_D1 & 0x0000FF00) >> 8); + coex_table[COEX_EXT_ELAN_GAIN_P1].cmd[12] = + (UINT8)((pWmtGenConf->coex_wmt_ext_elna_gain_p1_D1 & 0x00FF0000) >> 16); + coex_table[COEX_EXT_ELAN_GAIN_P1].cmd[13] = + (UINT8)((pWmtGenConf->coex_wmt_ext_elna_gain_p1_D1 & 0xFF000000) >> 24); + /* wmt_ext_elna_gain_p1 D2*/ + coex_table[COEX_EXT_ELAN_GAIN_P1].cmd[14] = + (UINT8)((pWmtGenConf->coex_wmt_ext_elna_gain_p1_D2 & 0x000000FF) >> 0); + coex_table[COEX_EXT_ELAN_GAIN_P1].cmd[15] = + (UINT8)((pWmtGenConf->coex_wmt_ext_elna_gain_p1_D2 & 0x0000FF00) >> 8); + coex_table[COEX_EXT_ELAN_GAIN_P1].cmd[16] = + (UINT8)((pWmtGenConf->coex_wmt_ext_elna_gain_p1_D2 & 0x00FF0000) >> 16); + coex_table[COEX_EXT_ELAN_GAIN_P1].cmd[17] = + (UINT8)((pWmtGenConf->coex_wmt_ext_elna_gain_p1_D2 & 0xFF000000) >> 24); + /* wmt_ext_elna_gain_p1 D3*/ + coex_table[COEX_EXT_ELAN_GAIN_P1].cmd[18] = + (UINT8)((pWmtGenConf->coex_wmt_ext_elna_gain_p1_D3 & 0x000000FF) >> 0); + coex_table[COEX_EXT_ELAN_GAIN_P1].cmd[19] = + (UINT8)((pWmtGenConf->coex_wmt_ext_elna_gain_p1_D3 & 0x0000FF00) >> 8); + coex_table[COEX_EXT_ELAN_GAIN_P1].cmd[20] = + (UINT8)((pWmtGenConf->coex_wmt_ext_elna_gain_p1_D3 & 0x00FF0000) >> 16); + coex_table[COEX_EXT_ELAN_GAIN_P1].cmd[21] = + (UINT8)((pWmtGenConf->coex_wmt_ext_elna_gain_p1_D3 & 0xFF000000) >> 24); + + if (gWmtDbgLvl >= WMT_LOG_DBG) { + wmt_core_dump_data(&coex_table[COEX_EXT_ELAN_GAIN_P1].cmd[0], + coex_table[COEX_EXT_ELAN_GAIN_P1].str, + coex_table[COEX_EXT_ELAN_GAIN_P1].cmdSz); + } + + coex_table[COEX_EXT_EPA_MODE].cmd[5] = pWmtGenConf->coex_wmt_ext_epa_mode; +#endif + + iRet = wmt_core_init_script(coex_table, ARRAY_SIZE(coex_table)); + + return iRet; +} + +static INT32 wmt_stp_init_epa(VOID) +{ + INT32 iRet; + unsigned long addr = 0; + WMT_GEN_CONF *pWmtGenConf = NULL; + + /*Get wmt config */ + iRet = wmt_core_ctrl(WMT_CTRL_GET_WMT_CONF, &addr, 0); + if (iRet) { + WMT_ERR_FUNC("ctrl GET_WMT_CONF fail(%d)\n", iRet); + return -2; + } + WMT_DBG_FUNC("ctrl GET_WMT_CONF ok(0x%08lx)\n", addr); + + pWmtGenConf = (P_WMT_GEN_CONF) addr; + + /*Check if WMT.cfg exists */ + if (pWmtGenConf->cfgExist == 0) { + WMT_DBG_FUNC("cfgExist == 0, skip config chip\n"); + /*if WMT.cfg not existed, still return success and adopt the default value */ + return 0; + } + + WMT_INFO_FUNC("epa_mode:0x%x\n", pWmtGenConf->coex_wmt_ant_mode_ex); + + if (pWmtGenConf->coex_wmt_ant_mode_ex != 1) + return 0; + + epa_table[0].cmd[5] = pWmtGenConf->coex_wmt_ant_mode_ex; + if (gWmtDbgLvl >= WMT_LOG_DBG) + wmt_core_dump_data(&epa_table[0].cmd[0], epa_table[0].str, epa_table[0].cmdSz); + iRet = wmt_core_init_script(epa_table, ARRAY_SIZE(epa_table)); + + return iRet; +} + +static INT32 wmt_stp_init_epa_elna(VOID) +{ + INT32 iRet; + unsigned long addr = 0; + WMT_GEN_CONF *pWmtGenConf = NULL; + struct init_script script[1]; + struct WMT_BYTE_ARRAY *ba = NULL; + INT32 cmd_size; + INT32 data_size; + PUINT8 cmd; + UINT16 index = 0; + + /*Get wmt config */ + iRet = wmt_core_ctrl(WMT_CTRL_GET_WMT_CONF, &addr, 0); + if (iRet) { + WMT_ERR_FUNC("ctrl GET_WMT_CONF fail(%d)\n", iRet); + return -2; + } + WMT_DBG_FUNC("ctrl GET_WMT_CONF ok(0x%08lx)\n", addr); + + pWmtGenConf = (P_WMT_GEN_CONF) addr; + + /*Check if WMT.cfg exists */ + if (pWmtGenConf->cfgExist == 0) { + WMT_DBG_FUNC("cfgExist == 0, skip config chip\n"); + /*if WMT.cfg not existed, still return success and adopt the default value */ + return 0; + } + + if (pWmtGenConf->coex_wmt_epa_elna == NULL) + return 0; + + ba = pWmtGenConf->coex_wmt_epa_elna; + + /* cmd_size = direction(1) + op(1) + length(2) + coex op(1) + data */ + cmd_size = ba->size + 5; + cmd = (PUINT8)osal_malloc(cmd_size); + + if (cmd == NULL) { + WMT_ERR_FUNC("failed to malloc when init epa elna\n"); + return -1; + } + + /* 0x1: direction, 0x10: op code */ + cmd[index++] = 0x1; + cmd[index++] = 0x10; + + /* add 1 for coex op id */ + data_size = ba->size + 1; + /* assign data length */ + cmd[index++] = (data_size & 0x00FF) >> 0; + cmd[index++] = (data_size & 0xFF00) >> 8; + /* assign coex op id: 0x1D */ + cmd[index++] = 0x1D; + + osal_memcpy(&cmd[index], ba->data, ba->size); + + script[0].cmd = cmd; + script[0].cmdSz = cmd_size; + script[0].evt = WMT_EPA_ELNA_SETTING_CONFIG_EVT; + script[0].evtSz = sizeof(WMT_EPA_ELNA_SETTING_CONFIG_EVT); + script[0].str = "coex_wmt_epa_elna"; + + if (gWmtDbgLvl >= WMT_LOG_DBG) + wmt_core_dump_data(&(script[0].cmd[0]), script[0].str, + script[0].cmdSz); + + iRet = wmt_core_init_script(script, ARRAY_SIZE(script)); + + osal_free(cmd); + return iRet; +} + +static INT32 wmt_stp_init_epa_elna_invert_cr(VOID) +{ + INT32 iRet; + UINT32 uVal = 0; + unsigned long addr = 0; + WMT_GEN_CONF *pWmtGenConf = NULL; + UINT32 default_invert_cr[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + UINT32 default_invert_bit[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + PINT8 pbuf; + long res = 0; + PINT8 tok1, tok2; + UINT32 item1, item2, item_index; + UINT32 invert_cr, invert_bit; + + mtk_wcn_consys_ic_get_ant_sel_cr_addr(default_invert_cr, default_invert_bit); + pWmtGenConf = (P_WMT_GEN_CONF) addr; + + /*Get wmt config */ + iRet = wmt_core_ctrl(WMT_CTRL_GET_WMT_CONF, &addr, 0); + if (iRet) { + WMT_ERR_FUNC("ctrl GET_WMT_CONF fail(%d)\n", iRet); + return -2; + } + WMT_INFO_FUNC("ctrl GET_WMT_CONF ok(0x%08lx)\n", addr); + + pWmtGenConf = (P_WMT_GEN_CONF) addr; + + /*Check if WMT.cfg exists */ + if (pWmtGenConf->cfgExist == 0) { + WMT_DBG_FUNC("cfgExist == 0, skip config chip\n"); + /*if WMT.cfg not existed, still return success and adopt the default value */ + return 0; + } + + WMT_DBG_FUNC("pWmtGenConf->coex_wmt_antsel_invert_support=[%s]\n", + pWmtGenConf->coex_wmt_antsel_invert_support); + + if (pWmtGenConf->coex_wmt_antsel_invert_support == NULL || + osal_strlen(pWmtGenConf->coex_wmt_antsel_invert_support) <= 0) + return 0; + + pbuf = osal_malloc(osal_strlen(pWmtGenConf->coex_wmt_antsel_invert_support)+1); + if (pbuf == NULL) { + WMT_ERR_FUNC("init_invert_cr, malloc fail, size %d\n", + osal_strlen(pWmtGenConf->coex_wmt_antsel_invert_support)+1); + return -1; + } + + osal_strcpy(pbuf, pWmtGenConf->coex_wmt_antsel_invert_support); + + while ((tok1 = osal_strsep(&pbuf, " /\\")) != NULL) { + if (*tok1 == '\0') + continue; + if (!*tok1) + continue; + item1 = 0; + item2 = 0; + item_index = 0; + while ((tok2 = osal_strsep(&tok1, " ,")) != NULL) { + if (*tok2 == '\0') + continue; + if (!*tok2) + continue; + if ((osal_strlen(tok2) > 2) && ((*tok2) == '0') && (*(tok2 + 1) == 'x')) + osal_strtol(tok2 + 2, 16, &res); + else + osal_strtol(tok2, 10, &res); + if (item_index == 0) + item1 = res; + else if (item_index == 1) + item2 = res; + item_index++; + } + + if (item_index != 1 && item_index != 2) + continue; + if ((item_index == 1) && (item1 > 7 || item1 < 0)) + continue; + if ((item_index == 2) && (item2 > 31 || item2 < 0)) + continue; + + if (item_index == 1) { + invert_cr = default_invert_cr[item1]; + invert_bit = default_invert_bit[item1]; + } else if (item_index == 2) { + invert_cr = item1; + invert_bit = item2; + } + + if (invert_cr == 0) + continue; + + uVal = 0; + iRet = wmt_core_reg_rw_raw(0, invert_cr, &uVal, 0xFFFFFFFF); + if (iRet) { + WMT_ERR_FUNC("init_invert_cr, read 0x%x[%d](before write) fail(%d)\n", + invert_cr, invert_bit, iRet); + continue; + } + WMT_DBG_FUNC("init_invert_cr, 0x%x[%d](before write) = 0x%x\n", + invert_cr, invert_bit, uVal); + + uVal = 0x1 << invert_bit; + iRet = wmt_core_reg_rw_raw(1, invert_cr, &uVal, 0x1 << invert_bit); + if (iRet) { + WMT_ERR_FUNC("init_invert_cr, write 0x%x[%d]=1 fail(%d)\n", + invert_cr, invert_bit, iRet); + continue; + } + + uVal = 0; + iRet = wmt_core_reg_rw_raw(0, invert_cr, &uVal, 0xFFFFFFFF); + if (iRet) { + WMT_ERR_FUNC("init_invert_cr, read 0x%x[%d](after write) fail(%d)\n", + invert_cr, invert_bit, iRet); + continue; + } + WMT_DBG_FUNC("init_invert_cr, 0x%x[%d](after write) = 0x%x\n", + invert_cr, invert_bit, uVal); + } + + if (pbuf != NULL) { + osal_free(pbuf); + pbuf = NULL; + } + + return 0; +} + +static INT32 wmt_stp_init_wifi_ant_swap(VOID) +{ + INT32 iRet; + unsigned long addr = 0; + WMT_GEN_CONF *pWmtGenConf = NULL; + UINT8 ant_swap_mode, polarity, ant_sel; + + /*Get wmt config */ + iRet = wmt_core_ctrl(WMT_CTRL_GET_WMT_CONF, &addr, 0); + if (iRet) { + WMT_ERR_FUNC("ctrl GET_WMT_CONF fail(%d)\n", iRet); + return -2; + } + WMT_DBG_FUNC("ctrl GET_WMT_CONF ok(0x%08lx)\n", addr); + + pWmtGenConf = (P_WMT_GEN_CONF) addr; + + /*Check if WMT.cfg exists */ + if (pWmtGenConf->cfgExist == 0) { + WMT_DBG_FUNC("cfgExist == 0, skip config chip\n"); + /*if WMT.cfg not existed, still return success and adopt the default value */ + return 0; + } + + ant_swap_mode = pWmtGenConf->wifi_ant_swap_mode; + polarity = pWmtGenConf->wifi_main_ant_polarity; + ant_sel = pWmtGenConf->wifi_ant_swap_ant_sel_gpio; + + WMT_INFO_FUNC("ant swap mode = %d, main_polarity = %d, ant_sel = %d\n", + ant_swap_mode, polarity, ant_sel); + + if (ant_swap_mode <= 0 || ant_swap_mode > 2) + return 0; + + if (ant_swap_mode == 2 && + mtk_consys_is_ant_swap_enable_by_hwid() == 0) + return 0; + + wifi_ant_swap_table[0].cmd[6] = polarity; + + if (ant_sel > 0) + wifi_ant_swap_table[0].cmd[7] = ant_sel; + else { + /* backward compatible */ + wifi_ant_swap_table[0].cmdSz = sizeof(WMT_WIFI_ANT_SWAP_CMD) - 1; + wifi_ant_swap_table[0].cmd[2] = 3; /* length */ + wifi_ant_swap_table[0].cmd[4] = 6; /* op id */ + wifi_ant_swap_table[0].evt[5] = 6; /* op id */ + } + + iRet = wmt_core_init_script(wifi_ant_swap_table, ARRAY_SIZE(wifi_ant_swap_table)); + + return iRet; +} + +static INT32 wmt_init_wifi_config(VOID) +{ + INT32 iRet; + unsigned long addr = 0; + WMT_GEN_CONF *pWmtGenConf = NULL; + struct init_script script[1]; + struct WMT_BYTE_ARRAY *ba = NULL; + INT32 cmd_size; + INT32 data_size; + PUINT8 cmd; + UINT16 index = 0; + + /*Get wmt config */ + iRet = wmt_core_ctrl(WMT_CTRL_GET_WMT_CONF, &addr, 0); + if (iRet) { + WMT_ERR_FUNC("ctrl GET_WMT_CONF fail(%d)\n", iRet); + return -2; + } + WMT_DBG_FUNC("ctrl GET_WMT_CONF ok(0x%08lx)\n", addr); + + pWmtGenConf = (P_WMT_GEN_CONF) addr; + + /*Check if WMT.cfg exists */ + if (pWmtGenConf->cfgExist == 0) { + WMT_DBG_FUNC("cfgExist == 0, skip config chip\n"); + /*if WMT.cfg not existed, still return success and adopt the default value */ + return 0; + } + + if (pWmtGenConf->wifi_config == NULL) + return 0; + + ba = pWmtGenConf->wifi_config; + + /* cmd_size = direction(1) + op(1) + length(2) + sub op(1) + data_len(1) + data */ + cmd_size = ba->size + 6; + cmd = (PUINT8)osal_malloc(cmd_size); + + if (cmd == NULL) { + WMT_ERR_FUNC("failed to malloc when init wifi config\n"); + return -1; + } + + /* 0x1: direction, 0x2: op code */ + cmd[index++] = 0x1; + cmd[index++] = 0x2; + + /* add 2 for test op id and data length */ + data_size = ba->size + 2; + /* assign data length */ + cmd[index++] = (data_size & 0x00FF) >> 0; + cmd[index++] = (data_size & 0xFF00) >> 8; + /* assign op id: 0x14 */ + cmd[index++] = 0x14; + /* assign data length */ + /* A byte to store data length is because firmware test op handler cannot see data length*/ + cmd[index++] = (UINT8)ba->size; + + osal_memcpy(&cmd[index], ba->data, ba->size); + + script[0].cmd = cmd; + script[0].cmdSz = cmd_size; + script[0].evt = WMT_WIFI_CONFIG_EVT; + script[0].evtSz = sizeof(WMT_WIFI_CONFIG_EVT); + script[0].str = "wifi_config"; + + if (gWmtDbgLvl >= WMT_LOG_DBG) + wmt_core_dump_data(&(script[0].cmd[0]), script[0].str, + script[0].cmdSz); + + iRet = wmt_core_init_script(script, ARRAY_SIZE(script)); + + osal_free(cmd); + + return iRet; +} + +#if CFG_WMT_SDIO_DRIVING_SET +static INT32 mtk_wcn_soc_set_sdio_driving(void) +{ + INT32 ret = 0; + + unsigned long addr = 0; + WMT_GEN_CONF *pWmtGenConf = NULL; + UINT32 drv_val = 0; + + /*Get wmt config */ + ret = wmt_core_ctrl(WMT_CTRL_GET_WMT_CONF, &addr, 0); + if (ret) { + WMT_ERR_FUNC("ctrl GET_WMT_CONF fail(%d)\n", ret); + return -1; + } + WMT_INFO_FUNC("ctrl GET_WMT_CONF ok(0x%08lx)\n", addr); + + pWmtGenConf = (P_WMT_GEN_CONF) addr; + + /*Check if WMT.cfg exists */ + if (pWmtGenConf->cfgExist == 0) { + WMT_INFO_FUNC("cfgExist == 0, skip config chip\n"); + /*if WMT.cfg not existed, still return success and adopt the default value */ + return 0; + } + + drv_val = pWmtGenConf->sdio_driving_cfg; + + /*Dump the sdio driving related info */ + WMT_INFO_FUNC("sdio driving:0x%x\n", drv_val); + + sdio_driving_table[0].cmd[12] = (UINT8) ((drv_val & 0x00000077UL) >> 0); /* DAT0 and DAT1 */ + sdio_driving_table[0].cmd[13] = (UINT8) ((drv_val & 0x00007700UL) >> 8); /* DAT2 and DAT3 */ + sdio_driving_table[0].cmd[14] = (UINT8) ((drv_val & 0x00070000UL) >> 16); /* CMD */ + + ret = wmt_core_init_script(sdio_driving_table, ARRAY_SIZE(sdio_driving_table)); + + return ret; +} +#endif + +#if CFG_WMT_CRYSTAL_TIMING_SET +static INT32 mtk_wcn_soc_crystal_triming_set(VOID) +{ + INT32 iRet = 0; + PUINT8 pbuf = NULL; + UINT32 bufLen = 0; + WMT_CTRL_DATA ctrlData; + UINT32 uCryTimOffset = 0x6D; + MTK_WCN_BOOL bIsNvramExist = MTK_WCN_BOOL_FALSE; + INT8 cCrystalTimingOffset = 0x0; + UINT8 cCrystalTiming = 0x0; + INT32 iCrystalTiming = 0x0; + MTK_WCN_BOOL bIsCrysTrimEnabled = MTK_WCN_BOOL_FALSE; + UINT32 u4Res; + + bIsNvramExist = MTK_WCN_BOOL_FALSE; + /**/ ctrlData.ctrlId = WMT_CTRL_CRYSTAL_TRIMING_GET; + ctrlData.au4CtrlData[0] = (UINT32) "/data/nvram/APCFG/APRDEB/WIFI"; + ctrlData.au4CtrlData[1] = (UINT32) &pbuf; + ctrlData.au4CtrlData[2] = (UINT32) &bufLen; + + iRet = wmt_ctrl(&ctrlData); + if (iRet != 0) { + WMT_ERR_FUNC("0x%x: WMT_CTRL_CRYSTAL_TRIMING_GET fail:%d\n", wmt_ic_ops_soc.icId, iRet); + bIsNvramExist = MTK_WCN_BOOL_FALSE; + bIsCrysTrimEnabled = MTK_WCN_BOOL_FALSE; + cCrystalTimingOffset = 0x0; + cCrystalTiming = 0x0; + iRet = -1; + } else { + WMT_DBG_FUNC("0x%x: nvram pBuf(0x%08x), bufLen(%d)\n", wmt_ic_ops_soc.icId, pbuf, bufLen); + if (bufLen < (uCryTimOffset + 1)) { + WMT_ERR_FUNC("0x%x: nvram len(%d) too short, crystalTimging value offset(%d)\n", + wmt_ic_ops_soc.icId, bufLen, uCryTimOffset); + bIsNvramExist = MTK_WCN_BOOL_FALSE; + bIsCrysTrimEnabled = MTK_WCN_BOOL_FALSE; + cCrystalTimingOffset = 0x0; + cCrystalTiming = 0x0; + } else { + bIsNvramExist = MTK_WCN_BOOL_TRUE; + cCrystalTimingOffset = *(pbuf + uCryTimOffset); + if (cCrystalTimingOffset & 0x80) { + bIsCrysTrimEnabled = MTK_WCN_BOOL_TRUE; + cCrystalTimingOffset = (UINT8) cCrystalTimingOffset & 0x7f; + } + WMT_DBG_FUNC("cCrystalTimingOffset (%d), bIsCrysTrimEnabled(%d)\n", cCrystalTimingOffset, + bIsCrysTrimEnabled); + } + ctrlData.ctrlId = WMT_CTRL_CRYSTAL_TRIMING_PUT; + ctrlData.au4CtrlData[0] = (UINT32) "/data/nvram/APCFG/APRDEB/WIFI"; + iRet = wmt_ctrl(&ctrlData); + if (iRet != 0) { + WMT_ERR_FUNC("0x%x: WMT_CTRL_CRYSTAL_TRIMING_PUT fail:%d\n", wmt_ic_ops_soc.icId, iRet); + iRet = -2; + } else { + WMT_DBG_FUNC("0x%x: WMT_CTRL_CRYSTAL_TRIMING_PUT succeed\n", wmt_ic_ops_soc.icId); + } + } + if ((bIsNvramExist == MTK_WCN_BOOL_TRUE) && (bIsCrysTrimEnabled == MTK_WCN_BOOL_TRUE)) { + /*get CrystalTiming value before set it */ + iRet = + wmt_core_tx(get_crystal_timing_script[0].cmd, get_crystal_timing_script[0].cmdSz, &u4Res, + MTK_WCN_BOOL_FALSE); + if (iRet || (u4Res != get_crystal_timing_script[0].cmdSz)) { + WMT_ERR_FUNC("WMT-CORE: write (%s) iRet(%d) cmd len err(%d, %d)\n", + get_crystal_timing_script[0].str, iRet, u4Res, get_crystal_timing_script[0].cmdSz); + iRet = -3; + goto done; + } + /* EVENT BUF */ + osal_memset(get_crystal_timing_script[0].evt, 0, get_crystal_timing_script[0].evtSz); + iRet = wmt_core_rx(get_crystal_timing_script[0].evt, get_crystal_timing_script[0].evtSz, &u4Res); + if (iRet || (u4Res != get_crystal_timing_script[0].evtSz)) { + WMT_ERR_FUNC("WMT-CORE: read (%s) iRet(%d) evt len err(rx:%d, exp:%d)\n", + get_crystal_timing_script[0].str, iRet, u4Res, get_crystal_timing_script[0].evtSz); + mtk_wcn_stp_dbg_dump_package(); + iRet = -4; + goto done; + } + + iCrystalTiming = WMT_GET_CRYSTAL_TRIMING_EVT[5] & 0x7f; + if (cCrystalTimingOffset & 0x40) { + /*nagative offset value */ + iCrystalTiming = iCrystalTiming + cCrystalTimingOffset - 128; + } else { + iCrystalTiming += cCrystalTimingOffset; + } + WMT_DBG_FUNC("iCrystalTiming (0x%x)\n", iCrystalTiming); + if (iCrystalTiming > 0x7f) + cCrystalTiming = 0x7f; + else if (iCrystalTiming < 0) + cCrystalTiming = 0; + else + cCrystalTiming = iCrystalTiming; + WMT_DBG_FUNC("cCrystalTiming (0x%x)\n", cCrystalTiming); + /* set_crystal_timing_script */ + WMT_SET_CRYSTAL_TRIMING_CMD[5] = cCrystalTiming; + WMT_GET_CRYSTAL_TRIMING_EVT[5] = cCrystalTiming; + + iRet = wmt_core_init_script(set_crystal_timing_script, osal_array_size(set_crystal_timing_script)); + if (iRet) { + WMT_ERR_FUNC("set_crystal_timing_script fail(%d)\n", iRet); + iRet = -5; + } else { + WMT_DBG_FUNC("set crystal timing value (0x%x) succeed\n", WMT_SET_CRYSTAL_TRIMING_CMD[5]); + iRet = + wmt_core_init_script(get_crystal_timing_script, osal_array_size(get_crystal_timing_script)); + if (iRet) { + WMT_ERR_FUNC("get_crystal_timing_script fail(%d)\n", iRet); + iRet = -6; + } else { + WMT_INFO_FUNC("succeed, updated crystal timing value (0x%x)\n", + WMT_GET_CRYSTAL_TRIMING_EVT[5]); + iRet = 0x0; + } + } + } +done: + return iRet; +} +#endif + +#if CFG_WMT_MULTI_PATCH +static INT32 mtk_wcn_soc_patch_info_prepare(VOID) +{ + INT32 iRet = -1; + WMT_CTRL_DATA ctrlData; + + ctrlData.ctrlId = WMT_CTRL_PATCH_SEARCH; + iRet = wmt_ctrl(&ctrlData); + + return iRet; +} + +static UINT32 mtk_wcn_soc_get_patch_num(VOID) +{ + ULONG ctrlPa1 = 0; + ULONG ctrlPa2 = 0; + + wmt_core_ctrl(WMT_CTRL_GET_PATCH_NUM, &ctrlPa1, &ctrlPa2); + WMT_DBG_FUNC("patch total num = [%lu]\n", ctrlPa1); + return ctrlPa1; +} + +static UINT32 mtk_wcn_soc_update_patch_version(VOID) +{ + return wmt_core_ctrl(WMT_CTRL_UPDATE_PATCH_VERSION, NULL, NULL); +} + +static INT32 mtk_wcn_soc_normal_patch_dwn(PUINT8 pPatchBuf, UINT32 patchSize, PUINT8 addressByte) +{ + INT32 iRet = -1; + UINT32 patchSizePerFrag = 0; + UINT32 fragSeq; + UINT32 fragNum; + UINT16 fragSize = 0; + UINT16 cmdLen; + UINT32 offset; + UINT32 u4Res; + UINT8 evtBuf[8]; + UINT8 addressevtBuf[12]; + + patchSizePerFrag = DEFAULT_PATCH_FRAG_SIZE; + /* reserve 1st patch cmd space before patch body + * |<-WMT_CMD: 5Bytes->|<-patch body: X Bytes (X=patchSize)----->| + */ + pPatchBuf -= sizeof(WMT_PATCH_CMD); + + fragNum = patchSize / patchSizePerFrag; + fragNum += ((fragNum * patchSizePerFrag) == patchSize) ? 0 : 1; + + WMT_INFO_FUNC("normal patch download patch size(%d) fragNum(%d)\n", patchSize, fragNum); + + /*send wmt part patch address command */ + if (wmt_ic_ops_soc.options & OPT_NORMAL_PATCH_DWN_0) { + /* ROMv2 patch RAM base */ + WMT_PATCH_ADDRESS_CMD[8] = 0x40; + WMT_PATCH_P_ADDRESS_CMD[8] = 0xc8; + } + /*send wmt part patch address command */ + if (wmt_ic_ops_soc.options & OPT_NORMAL_PATCH_DWN_1) { + /* ROMv3 patch RAM base */ + WMT_PATCH_ADDRESS_CMD[8] = 0x08; + WMT_PATCH_ADDRESS_CMD[9] = 0x05; + WMT_PATCH_P_ADDRESS_CMD[8] = 0x2c; + WMT_PATCH_P_ADDRESS_CMD[9] = 0x0b; + } + + if (wmt_ic_ops_soc.options & OPT_NORMAL_PATCH_DWN_2) { + /* ROMv4 patch RAM base */ + WMT_PATCH_ADDRESS_CMD[8] = 0x18; + WMT_PATCH_ADDRESS_CMD[9] = 0x05; + WMT_PATCH_P_ADDRESS_CMD[8] = 0x7c; + WMT_PATCH_P_ADDRESS_CMD[9] = 0x0b; + } + + if (wmt_ic_ops_soc.options & OPT_NORMAL_PATCH_DWN_3) { + /*send part patch address command */ + WMT_PATCH_ADDRESS_CMD_NEW[5] = addressByte[0]; + WMT_PATCH_ADDRESS_CMD_NEW[6] = addressByte[1]; + WMT_PATCH_ADDRESS_CMD_NEW[7] = addressByte[2]; + WMT_PATCH_ADDRESS_CMD_NEW[8] = addressByte[3]; + WMT_DBG_FUNC("4 bytes address command:0x%02x,0x%02x,0x%02x,0x%02x", + WMT_PATCH_ADDRESS_CMD_NEW[5], + WMT_PATCH_ADDRESS_CMD_NEW[6], + WMT_PATCH_ADDRESS_CMD_NEW[7], + WMT_PATCH_ADDRESS_CMD_NEW[8]); + iRet = wmt_core_tx((PUINT8) &WMT_PATCH_ADDRESS_CMD_NEW[0], sizeof(WMT_PATCH_ADDRESS_CMD_NEW), + &u4Res, MTK_WCN_BOOL_FALSE); + if (iRet || (u4Res != sizeof(WMT_PATCH_ADDRESS_CMD_NEW))) { + WMT_ERR_FUNC("wmt_core:wmt part patch address CMD fail(%d),size(%d)\n", iRet, u4Res); + return -1; + } + osal_memset(addressevtBuf, 0, sizeof(addressevtBuf)); + iRet = wmt_core_rx(addressevtBuf, sizeof(WMT_PATCH_ADDRESS_EVT_NEW), &u4Res); + if (iRet || (u4Res != sizeof(WMT_PATCH_ADDRESS_EVT_NEW))) { + WMT_ERR_FUNC("wmt_core:wmt patch address EVT fail(%d),size(%d)\n", iRet, u4Res); + WMT_INFO_FUNC("buf:[%2X,%2X,%2X,%2X,%2X] evt:[%2X,%2X,%2X,%2X,%2X]\n", + addressevtBuf[0], addressevtBuf[1], addressevtBuf[2], + addressevtBuf[3], addressevtBuf[4], + WMT_PATCH_ADDRESS_EVT_NEW[0], WMT_PATCH_ADDRESS_EVT_NEW[1], + WMT_PATCH_ADDRESS_EVT_NEW[2], WMT_PATCH_ADDRESS_EVT_NEW[3], + WMT_PATCH_ADDRESS_EVT_NEW[4]); + mtk_wcn_stp_dbg_dump_package(); + return -1; + } + goto patch_download; + } + + /*send wmt part patch address command */ + iRet = + wmt_core_tx((PUINT8) &WMT_PATCH_ADDRESS_CMD[0], sizeof(WMT_PATCH_ADDRESS_CMD), &u4Res, MTK_WCN_BOOL_FALSE); + if (iRet || (u4Res != sizeof(WMT_PATCH_ADDRESS_CMD))) { + WMT_ERR_FUNC("wmt_core:wmt patch address CMD fail(%d),size(%d)\n", iRet, u4Res); + return -1; + } + osal_memset(addressevtBuf, 0, sizeof(addressevtBuf)); + iRet = wmt_core_rx(addressevtBuf, sizeof(WMT_PATCH_ADDRESS_EVT), &u4Res); + if (iRet || (u4Res != sizeof(WMT_PATCH_ADDRESS_EVT))) { + WMT_ERR_FUNC("wmt_core:wmt patch address EVT fail(%d),size(%d)\n", iRet, u4Res); + mtk_wcn_stp_dbg_dump_package(); + return -1; + } +#if CFG_CHECK_WMT_RESULT + if (osal_memcmp(addressevtBuf, WMT_PATCH_ADDRESS_EVT, osal_sizeof(WMT_PATCH_ADDRESS_EVT)) != 0) { + WMT_ERR_FUNC("wmt_core: write WMT_PATCH_ADDRESS_CMD status fail\n"); + return -1; + } +#endif + + /*send part patch address command */ + WMT_PATCH_P_ADDRESS_CMD[12] = addressByte[0]; + WMT_PATCH_P_ADDRESS_CMD[13] = addressByte[1]; + WMT_PATCH_P_ADDRESS_CMD[14] = addressByte[2]; + WMT_PATCH_P_ADDRESS_CMD[15] = addressByte[3]; + WMT_DBG_FUNC("4 bytes address command:0x%02x,0x%02x,0x%02x,0x%02x", + WMT_PATCH_P_ADDRESS_CMD[12], + WMT_PATCH_P_ADDRESS_CMD[13], WMT_PATCH_P_ADDRESS_CMD[14], WMT_PATCH_P_ADDRESS_CMD[15]); + iRet = + wmt_core_tx((PUINT8) &WMT_PATCH_P_ADDRESS_CMD[0], sizeof(WMT_PATCH_P_ADDRESS_CMD), &u4Res, + MTK_WCN_BOOL_FALSE); + if (iRet || (u4Res != sizeof(WMT_PATCH_P_ADDRESS_CMD))) { + WMT_ERR_FUNC("wmt_core:wmt part patch address CMD fail(%d),size(%d)\n", iRet, u4Res); + return -1; + } + osal_memset(addressevtBuf, 0, sizeof(addressevtBuf)); + iRet = wmt_core_rx(addressevtBuf, sizeof(WMT_PATCH_P_ADDRESS_EVT), &u4Res); + if (iRet || (u4Res != sizeof(WMT_PATCH_P_ADDRESS_EVT))) { + WMT_ERR_FUNC("wmt_core:wmt patch address EVT fail(%d),size(%d)\n", iRet, u4Res); + mtk_wcn_stp_dbg_dump_package(); + return -1; + } +#if CFG_CHECK_WMT_RESULT + if (osal_memcmp(addressevtBuf, WMT_PATCH_P_ADDRESS_EVT, osal_sizeof(WMT_PATCH_ADDRESS_EVT)) != 0) { + WMT_ERR_FUNC("wmt_core: write WMT_PATCH_ADDRESS_CMD status fail\n"); + return -1; + } +#endif + +patch_download: + /* send all fragments */ + offset = sizeof(WMT_PATCH_CMD); + fragSeq = 0; + while (fragSeq < fragNum) { + WMT_DBG_FUNC("patch size(%d) fragNum(%d)\n", patchSize, fragNum); + if (fragSeq == (fragNum - 1)) { + /* last fragment */ + fragSize = patchSize - fragSeq * patchSizePerFrag; + WMT_PATCH_CMD[4] = WMT_PATCH_FRAG_LAST; + } else { + fragSize = patchSizePerFrag; + WMT_PATCH_CMD[4] = (fragSeq == 0) ? WMT_PATCH_FRAG_1ST : WMT_PATCH_FRAG_MID; + } + /* update length field in CMD:flag+frag */ + cmdLen = 1 + fragSize; + osal_memcpy(&WMT_PATCH_CMD[2], &cmdLen, 2); + /* copy patch CMD to buf (overwrite last 5-byte in prev frag) */ + osal_memcpy(pPatchBuf + offset - sizeof(WMT_PATCH_CMD), WMT_PATCH_CMD, sizeof(WMT_PATCH_CMD)); + + /* iRet = + *(*kal_stp_tx)(pbuf + offset - sizeof(WMT_PATCH_CMD), fragSize + sizeof(WMT_PATCH_CMD), + *&u4Res); + */ + iRet = + wmt_core_tx(pPatchBuf + offset - sizeof(WMT_PATCH_CMD), fragSize + sizeof(WMT_PATCH_CMD), + &u4Res, MTK_WCN_BOOL_FALSE); + if (iRet || (u4Res != fragSize + sizeof(WMT_PATCH_CMD))) { + WMT_ERR_FUNC("wmt_core: write fragSeq(%d) size(%lu, %d) fail(%d)\n", fragSeq, + fragSize + sizeof(WMT_PATCH_CMD), u4Res, iRet); + iRet = -1; + break; + } + WMT_DBG_FUNC("wmt_core: write fragSeq(%d) size(%lu, %d) ok\n", + fragSeq, fragSize + sizeof(WMT_PATCH_CMD), u4Res); + + osal_memset(evtBuf, 0, sizeof(evtBuf)); + /* iRet = (*kal_stp_rx)(evtBuf, sizeof(WMT_PATCH_EVT), &u4Res); */ + iRet = wmt_core_rx(evtBuf, sizeof(WMT_PATCH_EVT), &u4Res); + if (iRet || (u4Res != sizeof(WMT_PATCH_EVT))) { + WMT_ERR_FUNC("wmt_core: read WMT_PATCH_EVT length(%lu, %d) fail(%d)\n", sizeof(WMT_PATCH_EVT), + u4Res, iRet); + mtk_wcn_stp_dbg_dump_package(); + iRet = -1; + break; + } +#if CFG_CHECK_WMT_RESULT + if (osal_memcmp(evtBuf, WMT_PATCH_EVT, sizeof(WMT_PATCH_EVT)) != 0) { + WMT_ERR_FUNC("wmt_core: compare WMT_PATCH_EVT error rx(%d):[%02X,%02X,%02X,%02X,%02X]\n", + u4Res, + evtBuf[0], + evtBuf[1], + evtBuf[2], + evtBuf[3], + evtBuf[4]); + WMT_ERR_FUNC("wmt_core: exp(%lu):[%02X,%02X,%02X,%02X,%02X]\n", + sizeof(WMT_PATCH_EVT), + WMT_PATCH_EVT[0], + WMT_PATCH_EVT[1], + WMT_PATCH_EVT[2], + WMT_PATCH_EVT[3], + WMT_PATCH_EVT[4]); + iRet = -1; + break; + } +#endif + WMT_DBG_FUNC("wmt_core: read WMT_PATCH_EVT length(%lu, %d) ok\n", sizeof(WMT_PATCH_EVT), u4Res); + offset += patchSizePerFrag; + ++fragSeq; + } + + WMT_WARN_FUNC("wmt_core: patch dwn:%d frag(%d, %d) %s\n", + iRet, fragSeq, fragSize, (!iRet && (fragSeq == fragNum)) ? "ok" : "fail"); + + if (fragSeq != fragNum) + return -1; + + return 0; +} + +static INT32 mtk_wcn_soc_pda_patch_dwn(PUINT8 pPatchBuf, UINT32 patchSize, PUINT8 addressByte) +{ +#define PDAHDRLEN 12 + UINT32 u4Res; + UINT8 evtBuf[8]; + INT32 iRet = -1; + UINT32 fragSeq; + UINT32 fragNum; + UINT16 fragSize = 0; + UINT32 patchSizePerFrag = 0; + UINT32 offset; + UINT8 pdaHdr[PDAHDRLEN]; + + /* PDA download address, LSB */ + WMT_PATCH_PDA_CFG_CMD[5] = addressByte[0]; + WMT_PATCH_PDA_CFG_CMD[6] = addressByte[1]; + WMT_PATCH_PDA_CFG_CMD[7] = addressByte[2]; + WMT_PATCH_PDA_CFG_CMD[8] = addressByte[3]; + + /* PDA download size, LSB */ + WMT_PATCH_PDA_CFG_CMD[9] = (patchSize & 0x000000FF); + WMT_PATCH_PDA_CFG_CMD[10] = (patchSize & 0x0000FF00) >> 8; + WMT_PATCH_PDA_CFG_CMD[11] = (patchSize & 0x00FF0000) >> 16; + WMT_PATCH_PDA_CFG_CMD[12] = (patchSize & 0xFF000000) >> 24; + + iRet = wmt_core_tx((PUINT8) &WMT_PATCH_PDA_CFG_CMD[0], sizeof(WMT_PATCH_PDA_CFG_CMD), &u4Res, + MTK_WCN_BOOL_FALSE); + if (iRet || (u4Res != sizeof(WMT_PATCH_PDA_CFG_CMD))) { + WMT_ERR_FUNC("wmt_core:wmt part patch PDA config CMD fail(%d),size(%d)\n", + iRet, u4Res); + return -1; + } + osal_memset(evtBuf, 0, sizeof(evtBuf)); + iRet = wmt_core_rx(evtBuf, sizeof(WMT_PATCH_PDA_CFG_EVT), &u4Res); + if (iRet || (u4Res != sizeof(WMT_PATCH_PDA_CFG_EVT))) { + WMT_ERR_FUNC("wmt_core:wmt patch PDA config EVT fail(%d),size(%d)\n", + iRet, u4Res); + WMT_INFO_FUNC("buf:[%2X,%2X,%2X,%2X,%2X] evt:[%2X,%2X,%2X,%2X,%2X]\n", + evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], + WMT_PATCH_PDA_CFG_EVT[0], WMT_PATCH_PDA_CFG_EVT[1], + WMT_PATCH_PDA_CFG_EVT[2], WMT_PATCH_PDA_CFG_EVT[3], + WMT_PATCH_PDA_CFG_EVT[4]); + mtk_wcn_stp_dbg_dump_package(); + return -1; + } + + patchSizePerFrag = DEFAULT_PATCH_FRAG_SIZE; + fragNum = patchSize / patchSizePerFrag; + fragNum += ((fragNum * patchSizePerFrag) == patchSize) ? 0 : 1; + + osal_memset(pdaHdr, 0, PDAHDRLEN); + pdaHdr[0] = (patchSize + PDAHDRLEN) & 0x000000FF; + pdaHdr[1] = ((patchSize + PDAHDRLEN) & 0x0000FF00) >> 8; + pdaHdr[2] = ((patchSize + PDAHDRLEN) & 0x00FF0000) >> 16; + pdaHdr[3] = ((patchSize + PDAHDRLEN) & 0xFF000000) >> 24; + + iRet = wmt_core_tx(pdaHdr, PDAHDRLEN, &u4Res, MTK_WCN_BOOL_TRUE); + if (iRet || (u4Res != PDAHDRLEN)) { + WMT_ERR_FUNC("wmt_core: set length:%d fails, u4Res:%d\n", PDAHDRLEN, u4Res); + return -1; + } + + /* send all fragments */ + offset = 0; + fragSeq = 0; + while (fragSeq < fragNum) { + if (fragSeq == (fragNum - 1)) { + /* last fragment */ + fragSize = patchSize - fragSeq * patchSizePerFrag; + } else + fragSize = patchSizePerFrag; + + iRet = wmt_core_tx(pPatchBuf + offset, fragSize, &u4Res, MTK_WCN_BOOL_TRUE); + if (iRet || (u4Res != fragSize)) { + WMT_ERR_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) fail(%d)\n", + fragSeq, fragSize, u4Res, iRet); + iRet = -1; + break; + } + + WMT_DBG_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) ok\n", + fragSeq, fragSize, u4Res); + + offset += patchSizePerFrag; + ++fragSeq; + } + + WMT_INFO_FUNC("wmt_core: patch dwn:%d frag(%d, %d) %s\n", + iRet, fragSeq, fragSize, (!iRet && (fragSeq == fragNum)) ? "ok" : "fail"); + + if (fragSeq != fragNum) + return -1; + + return 0; +} + +static INT32 mtk_wcn_soc_patch_dwn(UINT32 index) +{ + INT32 iRet = -1; + P_WMT_PATCH patchHdr = NULL; + PUINT8 pBuf = NULL; + PUINT8 pPatchBuf = NULL; + PUINT8 patchBuildTimeAddr; + UINT32 patchSize; + PINT8 cDataTime = NULL; + UINT16 u2HwVer = 0; + UINT16 u2SwVer = 0; + UINT32 u4PatchVer = 0; + WMT_CTRL_DATA ctrlData; + P_CONSYS_EMI_ADDR_INFO emiInfo; + UINT8 addressByte[4]; + + /*1.check hardware information */ + if (gp_soc_info == NULL) { + WMT_ERR_FUNC("null gp_soc_info!\n"); + return -1; + } + + osal_memset(gFullPatchName, 0, osal_sizeof(gFullPatchName)); + + ctrlData.ctrlId = WMT_CTRL_GET_PATCH_INFO; + ctrlData.au4CtrlData[0] = index + 1; + ctrlData.au4CtrlData[1] = (SIZE_T)&gFullPatchName; + ctrlData.au4CtrlData[2] = (SIZE_T)&addressByte; + iRet = wmt_ctrl(&ctrlData); + WMT_DBG_FUNC("the %d time valid patch found: (%s)\n", index + 1, gFullPatchName); + + if (iRet) { + WMT_ERR_FUNC("wmt_core: WMT_CTRL_GET_PATCH_INFO fail:%d\n", iRet); + goto done; + } + + /* <2.2> read patch content */ + ctrlData.ctrlId = WMT_CTRL_GET_PATCH; + ctrlData.au4CtrlData[0] = (SIZE_T)NULL; + ctrlData.au4CtrlData[1] = (SIZE_T)&gFullPatchName; + ctrlData.au4CtrlData[2] = (SIZE_T)&pBuf; + ctrlData.au4CtrlData[3] = (SIZE_T)&patchSize; + iRet = wmt_ctrl(&ctrlData); + if (iRet) { + WMT_ERR_FUNC("wmt_core: WMT_CTRL_GET_PATCH fail:%d\n", iRet); + iRet -= 1; + goto done; + } + + /* |<-BCNT_PATCH_BUF_HEADROOM(8) bytes dummy allocated->|<-patch file->| */ + /* patch file with header: + * |<-patch header: 28 Bytes->|<-patch body: X Bytes ----->| + */ + pPatchBuf = osal_malloc(patchSize); + if (pPatchBuf == NULL) { + WMT_ERR_FUNC("vmalloc pPatchBuf for patch download fail\n"); + return -2; + } + osal_memcpy(pPatchBuf, pBuf, patchSize); + /* check patch file information */ + patchHdr = (P_WMT_PATCH) pPatchBuf; + + cDataTime = patchHdr->ucDateTime; + u2HwVer = patchHdr->u2HwVer; + u2SwVer = patchHdr->u2SwVer; + u4PatchVer = patchHdr->u4PatchVer; + + cDataTime[15] = '\0'; + if (index == 0) { + WMT_INFO_FUNC("[Patch]BuiltTime=%s,HVer=0x%x,SVer=0x%x,PhVer=0x%04x,Platform=%c%c%c%c\n", + cDataTime, ((u2HwVer & 0x00ff) << 8) | ((u2HwVer & 0xff00) >> 8), + ((u2SwVer & 0x00ff) << 8) | ((u2SwVer & 0xff00) >> 8), + ((u4PatchVer & 0xff000000) >> 24) | ((u4PatchVer & 0x00ff0000) >> 16), + patchHdr->ucPLat[0], patchHdr->ucPLat[1], + patchHdr->ucPLat[2], patchHdr->ucPLat[3]); + } + osal_memcpy(&gp_soc_patch_info, patchHdr, osal_sizeof(WMT_PATCH)); + + /* remove patch header: + * |<-patch body: X Bytes (X=patchSize)--->| + */ + if (patchSize < sizeof(WMT_PATCH)) { + WMT_ERR_FUNC("error patch size\n"); + iRet = -1; + goto done; + } + patchSize -= sizeof(WMT_PATCH); + pPatchBuf += sizeof(WMT_PATCH); + + if (wmt_ic_ops_soc.options & OPT_PATCH_CHECKSUM) { + /* remove patch checksum: + * |<-patch checksum: 2Bytes->|<-patch body: X Bytes (X=patchSize)--->| + */ + pPatchBuf += BCNT_PATCH_BUF_CHECKSUM; + patchSize -= BCNT_PATCH_BUF_CHECKSUM; + } + + emiInfo = mtk_wcn_consys_soc_get_emi_phy_add(); + if (!emiInfo) { + WMT_ERR_FUNC("get emi info fail!\n"); + iRet = -1; + goto done; + } + + if (emiInfo->pda_dl_patch_flag) + iRet = mtk_wcn_soc_pda_patch_dwn(pPatchBuf, patchSize, addressByte); + else + iRet = mtk_wcn_soc_normal_patch_dwn(pPatchBuf, patchSize, addressByte); + + /* Set FW patch buildtime into EMI for debugging */ + if (emiInfo->emi_ram_mcu_buildtime_offset) { + patchBuildTimeAddr = ioremap_nocache(emiInfo->emi_ap_phy_addr + + emiInfo->emi_patch_mcu_buildtime_offset, PATCH_BUILD_TIME_SIZE); + if (patchBuildTimeAddr) { + osal_memcpy_toio(patchBuildTimeAddr, cDataTime, PATCH_BUILD_TIME_SIZE); + iounmap(patchBuildTimeAddr); + } else + WMT_ERR_FUNC("ioremap_nocache fail\n"); + } +done: + if (patchHdr != NULL) { + osal_free(patchHdr); + pPatchBuf = NULL; + patchHdr = NULL; + } + + /* WMT_CTRL_FREE_PATCH always return 0 */ + ctrlData.ctrlId = WMT_CTRL_FREE_PATCH; + ctrlData.au4CtrlData[0] = index + 1; + wmt_ctrl(&ctrlData); + + return iRet; +} + +#else +static INT32 mtk_wcn_soc_patch_dwn(VOID) +{ + INT32 iRet = -1; + P_WMT_PATCH patchHdr; + PUINT8 pbuf; + UINT32 patchSize; + UINT32 fragSeq; + UINT32 fragNum; + UINT16 fragSize = 0; + UINT16 cmdLen; + UINT32 offset; + UINT32 u4Res; + UINT8 evtBuf[8]; + PINT8 cDataTime = NULL; + /*PINT8 cPlat = NULL; */ + UINT16 u2HwVer = 0; + UINT16 u2SwVer = 0; + UINT32 u4PatchVer = 0; + UINT32 patchSizePerFrag = 0; + WMT_CTRL_DATA ctrlData; + + /*1.check hardware information */ + if (gp_soc_info == NULL) { + WMT_ERR_FUNC("null gp_soc_info!\n"); + return -1; + } + /* <2> search patch and read patch content */ + /* <2.1> search patch */ + ctrlData.ctrlId = WMT_CTRL_PATCH_SEARCH; + iRet = wmt_ctrl(&ctrlData); + if (iRet == 0) { + /* patch with correct Hw Ver Major Num found */ + ctrlData.ctrlId = WMT_CTRL_GET_PATCH_NAME; + ctrlData.au4CtrlData[0] = (UINT32) &gFullPatchName; + iRet = wmt_ctrl(&ctrlData); + + WMT_INFO_FUNC("valid patch found: (%s)\n", gFullPatchName); + /* <2.2> read patch content */ + ctrlData.ctrlId = WMT_CTRL_GET_PATCH; + ctrlData.au4CtrlData[0] = (UINT32) NULL; + ctrlData.au4CtrlData[1] = (UINT32) &gFullPatchName; + + } else { + iRet -= 1; + return iRet; + } + ctrlData.au4CtrlData[2] = (UINT32) &pbuf; + ctrlData.au4CtrlData[3] = (UINT32) &patchSize; + iRet = wmt_ctrl(&ctrlData); + if (iRet) { + WMT_ERR_FUNC("wmt_core: WMT_CTRL_GET_PATCH fail:%d\n", iRet); + iRet -= 1; + goto done; + } + + /* |<-BCNT_PATCH_BUF_HEADROOM(8) bytes dummy allocated->|<-patch file->| */ + pbuf += BCNT_PATCH_BUF_HEADROOM; + /* patch file with header: + * |<-patch header: 28 Bytes->|<-patch body: X Bytes ----->| + */ + patchHdr = (P_WMT_PATCH) pbuf; + /* check patch file information */ + + cDataTime = patchHdr->ucDateTime; + u2HwVer = patchHdr->u2HwVer; + u2SwVer = patchHdr->u2SwVer; + u4PatchVer = patchHdr->u4PatchVer; + /*cPlat = &patchHdr->ucPLat[0]; */ + + cDataTime[15] = '\0'; + WMT_DBG_FUNC("===========================================\n"); + WMT_INFO_FUNC("[ConsysPatch]BuiltTime = %s, HVer = 0x%x, SVer = 0x%x, PhVer = 0x%04x,Platform = %c%c%c%c\n", + cDataTime, ((u2HwVer & 0x00ff) << 8) | ((u2HwVer & 0xff00) >> 8), + ((u2SwVer & 0x00ff) << 8) | ((u2SwVer & 0xff00) >> 8), + ((u4PatchVer & 0xff000000) >> 24) | ((u4PatchVer & 0x00ff0000) >> 16), + patchHdr->ucPLat[0], patchHdr->ucPLat[1], patchHdr->ucPLat[2], patchHdr->ucPLat[3]); + WMT_DBG_FUNC("[Consys Patch] Hw Ver = 0x%x\n", ((u2HwVer & 0x00ff) << 8) | ((u2HwVer & 0xff00) >> 8)); + WMT_DBG_FUNC("[Consys Patch] Sw Ver = 0x%x\n", ((u2SwVer & 0x00ff) << 8) | ((u2SwVer & 0xff00) >> 8)); + WMT_DBG_FUNC("[Consys Patch] Ph Ver = 0x%04x\n", + ((u4PatchVer & 0xff000000) >> 24) | ((u4PatchVer & 0x00ff0000) >> 16)); + WMT_DBG_FUNC("[Consys Patch] Platform = %c%c%c%c\n", patchHdr->ucPLat[0], patchHdr->ucPLat[1], + patchHdr->ucPLat[2], patchHdr->ucPLat[3]); + WMT_DBG_FUNC("===========================================\n"); + + /* remove patch header: + * |<-patch body: X Bytes (X=patchSize)--->| + */ + if (patchSize < sizeof(WMT_PATCH)) { + WMT_ERR_FUNC("error patch size\n"); + return -1; + } + patchSize -= sizeof(WMT_PATCH); + pbuf += sizeof(WMT_PATCH); + patchSizePerFrag = DEFAULT_PATCH_FRAG_SIZE; + /* reserve 1st patch cmd space before patch body + * |<-WMT_CMD: 5Bytes->|<-patch body: X Bytes (X=patchSize)----->| + */ + pbuf -= sizeof(WMT_PATCH_CMD); + + fragNum = patchSize / patchSizePerFrag; + fragNum += ((fragNum * patchSizePerFrag) == patchSize) ? 0 : 1; + + WMT_DBG_FUNC("patch size(%d) fragNum(%d)\n", patchSize, fragNum); + + /* send all fragments */ + offset = sizeof(WMT_PATCH_CMD); + fragSeq = 0; + while (fragSeq < fragNum) { + WMT_DBG_FUNC("patch size(%d) fragNum(%d)\n", patchSize, fragNum); + if (fragSeq == (fragNum - 1)) { + /* last fragment */ + fragSize = patchSize - fragSeq * patchSizePerFrag; + WMT_PATCH_CMD[4] = WMT_PATCH_FRAG_LAST; + } else { + fragSize = patchSizePerFrag; + WMT_PATCH_CMD[4] = (fragSeq == 0) ? WMT_PATCH_FRAG_1ST : WMT_PATCH_FRAG_MID; + } + /* update length field in CMD:flag+frag */ + cmdLen = 1 + fragSize; + osal_memcpy(&WMT_PATCH_CMD[2], &cmdLen, 2); + /* copy patch CMD to buf (overwrite last 5-byte in prev frag) */ + osal_memcpy(pbuf + offset - sizeof(WMT_PATCH_CMD), WMT_PATCH_CMD, sizeof(WMT_PATCH_CMD)); + + /* iRet = + * (*kal_stp_tx)(pbuf + offset - sizeof(WMT_PATCH_CMD), fragSize + sizeof(WMT_PATCH_CMD), + * &u4Res); + */ + iRet = + wmt_core_tx(pbuf + offset - sizeof(WMT_PATCH_CMD), fragSize + sizeof(WMT_PATCH_CMD), &u4Res, + MTK_WCN_BOOL_FALSE); + if (iRet || (u4Res != fragSize + sizeof(WMT_PATCH_CMD))) { + WMT_ERR_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) fail(%d)\n", fragSeq, + fragSize + sizeof(WMT_PATCH_CMD), u4Res, iRet); + iRet -= 1; + break; + } + WMT_DBG_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) ok\n", + fragSeq, fragSize + sizeof(WMT_PATCH_CMD), u4Res); + + osal_memset(evtBuf, 0, sizeof(evtBuf)); + /* iRet = (*kal_stp_rx)(evtBuf, sizeof(WMT_PATCH_EVT), &u4Res); */ + iRet = wmt_core_rx(evtBuf, sizeof(WMT_PATCH_EVT), &u4Res); + if (iRet || (u4Res != sizeof(WMT_PATCH_EVT))) { + WMT_ERR_FUNC("wmt_core: read WMT_PATCH_EVT length(%d, %d) fail(%d)\n", sizeof(WMT_PATCH_EVT), + u4Res, iRet); + mtk_wcn_stp_dbg_dump_package(); + iRet -= 1; + break; + } +#if CFG_CHECK_WMT_RESULT + if (osal_memcmp(evtBuf, WMT_PATCH_EVT, sizeof(WMT_PATCH_EVT)) != 0) { + WMT_ERR_FUNC("wmt_core: compare WMT_PATCH_EVT error rx(%d):[%02X,%02X,%02X,%02X,%02X]\n", + u4Res, + evtBuf[0], + evtBuf[1], + evtBuf[2], + evtBuf[3], + evtBuf[4]); + WMT_ERR_FUNC("wmt_core: exp(%d):[%02X,%02X,%02X,%02X,%02X]\n", + sizeof(WMT_PATCH_EVT), + WMT_PATCH_EVT[0], + WMT_PATCH_EVT[1], + WMT_PATCH_EVT[2], + WMT_PATCH_EVT[3], + WMT_PATCH_EVT[4]); + iRet -= 1; + break; + } +#endif + WMT_DBG_FUNC("wmt_core: read WMT_PATCH_EVT length(%d, %d) ok\n", sizeof(WMT_PATCH_EVT), u4Res); + offset += patchSizePerFrag; + ++fragSeq; + } + + WMT_WARN_FUNC("wmt_core: patch dwn:%d frag(%d, %d) %s\n", + iRet, fragSeq, fragSize, (!iRet && (fragSeq == fragNum)) ? "ok" : "fail"); + + if (fragSeq != fragNum) + iRet -= 1; +done: + /* WMT_CTRL_FREE_PATCH always return 0 */ + wmt_core_ctrl(WMT_CTRL_FREE_PATCH, NULL, NULL); + + return iRet; +} + +#endif + +INT32 mtk_wcn_soc_rom_patch_dwn(UINT32 ip_ver, UINT32 fw_ver) +{ + INT32 iRet = -1; + struct wmt_rom_patch *patchHdr = NULL; + PUINT8 pBuf = NULL; + PUINT8 pPatchBuf = NULL; + UINT32 patchSize; + UINT8 addressByte[4]; + PINT8 cDataTime = NULL; + UINT16 u2HwVer = 0; + UINT16 u2SwVer = 0; + UINT32 u4PatchType = 0; + UINT32 type; + UINT32 patchEmiOffset; + PUINT8 patchAddr; + UINT32 patchBuildTimeOffset = 0; + PUINT8 patchBuildTimeAddr; + WMT_CTRL_DATA ctrlData; + P_CONSYS_EMI_ADDR_INFO emiInfo; + + for (type = WMTDRV_TYPE_BT; type < WMTDRV_TYPE_ANT; type++) { + osal_memset(gFullPatchName, 0, osal_sizeof(gFullPatchName)); + + ctrlData.ctrlId = WMT_CTRL_GET_ROM_PATCH_INFO; + ctrlData.au4CtrlData[0] = type; + ctrlData.au4CtrlData[1] = (SIZE_T)&gFullPatchName; + ctrlData.au4CtrlData[2] = (SIZE_T)&addressByte; + ctrlData.au4CtrlData[3] = ip_ver; + ctrlData.au4CtrlData[4] = fw_ver; + iRet = wmt_ctrl(&ctrlData); + if (iRet > 0) { + WMT_INFO_FUNC("There is no need to download (%d) type patch!\n", type); + continue; + } else if (iRet < 0) { + WMT_ERR_FUNC("failed to get patch (type: %d, ret: %d)\n", type, iRet); + goto done; + } + + /* <2.2> read patch content */ + ctrlData.ctrlId = WMT_CTRL_GET_PATCH; + ctrlData.au4CtrlData[0] = (SIZE_T)NULL; + ctrlData.au4CtrlData[1] = (SIZE_T)&gFullPatchName; + ctrlData.au4CtrlData[2] = (SIZE_T)&pBuf; + ctrlData.au4CtrlData[3] = (SIZE_T)&patchSize; + iRet = wmt_ctrl(&ctrlData); + if (iRet) { + WMT_ERR_FUNC("wmt_core: WMT_CTRL_GET_PATCH fail:%d\n", iRet); + iRet = -1; + goto done; + } + + /* |<-BCNT_PATCH_BUF_HEADROOM(8) bytes dummy allocated->|<-patch file->| + * patch file with header: + * |<-patch header: 32 Bytes->|<-patch body: X Bytes ----->| + */ + pPatchBuf = osal_malloc(patchSize); + if (pPatchBuf == NULL) { + WMT_ERR_FUNC("vmalloc pPatchBuf for patch download fail\n"); + iRet = -2; + goto done; + } + osal_memcpy(pPatchBuf, pBuf, patchSize); + /* check patch file information */ + patchHdr = (struct wmt_rom_patch *) pPatchBuf; + + cDataTime = patchHdr->ucDateTime; + u2HwVer = patchHdr->u2HwVer; + u2SwVer = patchHdr->u2SwVer; + u4PatchType = patchHdr->u4PatchType; + + cDataTime[15] = '\0'; + WMT_INFO_FUNC("[RomPatch]BTime=%s,HVer=0x%x,SVer=0x%x,Platform=%c%c%c%c\n,Type=%x\n", + cDataTime, + ((u2HwVer & 0x00ff) << 8) | ((u2HwVer & 0xff00) >> 8), + ((u2SwVer & 0x00ff) << 8) | ((u2SwVer & 0xff00) >> 8), + patchHdr->ucPLat[0], patchHdr->ucPLat[1], + patchHdr->ucPLat[2], patchHdr->ucPLat[3], + u4PatchType); + + /* remove patch header: + * |<-patch body: X Bytes (X=patchSize)--->| + */ + if (patchSize < sizeof(struct wmt_rom_patch)) { + WMT_ERR_FUNC("error patch size\n"); + iRet = -3; + goto done; + } + patchSize -= sizeof(struct wmt_rom_patch); + pPatchBuf += sizeof(struct wmt_rom_patch); + + patchEmiOffset = (addressByte[2] << 16) | (addressByte[1] << 8) | addressByte[0]; + + emiInfo = mtk_wcn_consys_soc_get_emi_phy_add(); + if (!emiInfo) { + WMT_ERR_FUNC("get emi info fail!\n"); + iRet = -4; + goto done; + } + + if (patchEmiOffset + patchSize < emiInfo->emi_size) { + WMT_INFO_FUNC("[Rom Patch] emiInfo: emi_ap_phy_addr=0x%x emi_size=%d emi_phy_addr=0x%x\n", + emiInfo->emi_ap_phy_addr, emiInfo->emi_size, emiInfo->emi_phy_addr); + WMT_INFO_FUNC("[Rom Patch]Name=%s,EmiOffset=0x%x,Size=0x%x\n", + gFullPatchName, patchEmiOffset, patchSize); + + if (type == WMTDRV_TYPE_WIFI) { + wmt_lib_mpu_lock_aquire(); + if (mtk_wcn_wlan_emi_mpu_set_protection) + (*mtk_wcn_wlan_emi_mpu_set_protection)(false); + } + + patchAddr = ioremap_nocache(emiInfo->emi_ap_phy_addr + patchEmiOffset, patchSize); + WMT_INFO_FUNC("physAddr=0x%x, size=%d virAddr=0x%p\n", + emiInfo->emi_ap_phy_addr + patchEmiOffset, patchSize, patchAddr); + if (patchAddr) { + osal_memcpy_toio(patchAddr, pPatchBuf, patchSize); + iounmap(patchAddr); + } else + WMT_ERR_FUNC("ioremap_nocache fail\n"); + + if (type == WMTDRV_TYPE_BT) + patchBuildTimeOffset = emiInfo->emi_ram_bt_buildtime_offset; + else if (type == WMTDRV_TYPE_WIFI) + patchBuildTimeOffset = emiInfo->emi_ram_wifi_buildtime_offset; + else if (type == WMTDRV_TYPE_WMT) + patchBuildTimeOffset = emiInfo->emi_ram_mcu_buildtime_offset; + /* Set ROM patch buildtime into EMI for debugging */ + if (patchBuildTimeOffset) { + patchBuildTimeAddr = ioremap_nocache(emiInfo->emi_ap_phy_addr + + patchBuildTimeOffset, PATCH_BUILD_TIME_SIZE); + if (patchBuildTimeAddr) { + osal_memcpy_toio(patchBuildTimeAddr, cDataTime, + PATCH_BUILD_TIME_SIZE); + iounmap(patchBuildTimeAddr); + } else + WMT_ERR_FUNC("ioremap_nocache fail\n"); + } + + if (type == WMTDRV_TYPE_WIFI) { + if (mtk_wcn_wlan_emi_mpu_set_protection) + (*mtk_wcn_wlan_emi_mpu_set_protection)(true); + wmt_lib_mpu_lock_release(); + } + } else + WMT_ERR_FUNC("The rom patch is too big to overflow on EMI\n"); + +done: + if (patchHdr != NULL) { + osal_free(patchHdr); + pPatchBuf = NULL; + patchHdr = NULL; + } + + /* WMT_CTRL_FREE_PATCH always return 0 */ + ctrlData.ctrlId = WMT_CTRL_FREE_PATCH; + ctrlData.au4CtrlData[0] = type; + wmt_ctrl(&ctrlData); + if (iRet) + break; + } + + return iRet; +} + + +VOID mtk_wcn_soc_restore_wifi_cal_result(VOID) +{ +#if CFG_CALIBRATION_BACKUP_RESTORE + P_CONSYS_EMI_ADDR_INFO emiInfo = mtk_wcn_consys_soc_get_emi_phy_add(); + PUINT8 wifiCalAddr = NULL; + + if (!emiInfo) { + WMT_ERR_FUNC("Get EMI info failed.\n"); + return; + } + + if (mtk_consys_is_calibration_backup_restore_support() == 0 || + mtk_wcn_stp_assert_flow_get() == 0) { + WMT_INFO_FUNC( + "Skip restore, chip id=%x mtk_wcn_stp_assert_flow_get()=%d\n", + wmt_ic_ops_soc.icId, mtk_wcn_stp_assert_flow_get()); + return; + } + /* Disable Wi-Fi MPU to touch Wi-Fi calibration data */ + if (mtk_wcn_wlan_emi_mpu_set_protection) + (*mtk_wcn_wlan_emi_mpu_set_protection)(false); + WMT_STEP_DO_ACTIONS_FUNC(STEP_TRIGGER_POINT_BEFORE_RESTORE_CAL_RESULT); + /* Write Wi-Fi data to EMI */ + if (gWiFiCalAddrOffset + gWiFiCalSize < emiInfo->emi_size) { + wifiCalAddr = ioremap_nocache(emiInfo->emi_ap_phy_addr + gWiFiCalAddrOffset, + gWiFiCalSize); + if (wifiCalAddr) { + osal_memcpy_toio(wifiCalAddr, gWiFiCalResult, gWiFiCalSize); + iounmap(wifiCalAddr); + WMT_STEP_DO_ACTIONS_FUNC(STEP_TRIGGER_POINT_AFTER_RESTORE_CAL_RESULT); + } else { + WMT_ERR_FUNC("ioremap_nocache fail\n"); + } + } + if (mtk_wcn_wlan_emi_mpu_set_protection) + (*mtk_wcn_wlan_emi_mpu_set_protection)(true); +#else + WMT_INFO_FUNC("Skip restore because it is not supported.\n"); +#endif +} + +#if CFG_CALIBRATION_BACKUP_RESTORE +/* + * To restore calibration data + * For BT, send by STP command. + * For Wi-Fi write to EMI directly. + * + * Return value: + * 0: restore success + * 1: recalibration happened. Caller need to re-get calibration data + * < 0: fail. Caller need to re-send calibration command. + */ +static INT32 mtk_wcn_soc_calibration_restore(void) +{ + INT32 iRet = 0; + PUINT8 evtBuf = NULL; + UINT32 u4Res; + UINT16 len = 0; + + /* Allocate event buffer */ + evtBuf = osal_malloc(CALIBRATION_BACKUP_RESTORE_BUFFER_SIZE); + if (evtBuf == NULL) { + WMT_ERR_FUNC("allocate event buffer failed\n"); + return -1; + } + + if ((gBTCalResultSize != 0 && gBTCalResult != NULL && + (gBTCalResultSize + sizeof(WMT_CORE_SEND_RF_CALIBRATION_CMD)) < CALIBRATION_BACKUP_RESTORE_BUFFER_SIZE) && + (gWiFiCalResult != NULL && gWiFiCalSize != 0 && gWiFiCalAddrOffset != 0)) { + WMT_INFO_FUNC("Send calibration data size=%d\n", gBTCalResultSize); + WMT_INFO_FUNC("Send calibration data start\n"); + /* Construct send calibration cmd for BT + * Format: 0x01 0x14 [ X+3 (2 bytes)] 0x02 + * [BT data len (2 bytes)] [BT data (X bytes)] + */ + /* clear buffer */ + osal_memset(&evtBuf[0], 0, CALIBRATION_BACKUP_RESTORE_BUFFER_SIZE); + /* copy cmd template */ + osal_memcpy( + &evtBuf[0], + WMT_CORE_SEND_RF_CALIBRATION_CMD, + sizeof(WMT_CORE_SEND_RF_CALIBRATION_CMD)); + /* Setup length to byte 2&3 */ + len = gBTCalResultSize + 3; + osal_memcpy(&evtBuf[2], &len, 2); + osal_memcpy(&evtBuf[5], &gBTCalResultSize, 2); + osal_memcpy(&evtBuf[7], gBTCalResult, gBTCalResultSize); + len = sizeof(WMT_CORE_SEND_RF_CALIBRATION_CMD) + gBTCalResultSize; + iRet = wmt_core_tx(evtBuf, len, &u4Res, MTK_WCN_BOOL_FALSE); + if (iRet || u4Res != len) { + WMT_ERR_FUNC("Send calibration data TX failed (%d), %d bytes writes, expect %d\n", + iRet, u4Res, len); + iRet = -4; + goto restore_end; + } + /* RX: 02 14 02 00 XX 02 + * XX means status + * 0: OK + * 1: recalibration happened + */ + iRet = wmt_core_rx(evtBuf, CALIBRATION_BACKUP_RESTORE_BUFFER_SIZE, &u4Res); + WMT_INFO_FUNC("Send calibration data end\n"); + if (iRet || u4Res != sizeof(WMT_CORE_SEND_RF_CALIBRATION_EVT_OK)) { + WMT_ERR_FUNC("Send calibration data event failed(%d), %d bytes get, expect %lu\n", + iRet, u4Res, sizeof(WMT_CORE_SEND_RF_CALIBRATION_EVT_OK)); + iRet = -5; + goto restore_end; + } + /* Check return */ + if (osal_memcmp(&evtBuf[0], WMT_CORE_SEND_RF_CALIBRATION_EVT_OK, + sizeof(WMT_CORE_SEND_RF_CALIBRATION_EVT_OK)) == 0) { + WMT_INFO_FUNC("Send calibration data OK.\n"); + iRet = 0; + } else if (osal_memcmp(&evtBuf[0], WMT_CORE_SEND_RF_CALIBRATION_EVT_RECAL, + sizeof(WMT_CORE_SEND_RF_CALIBRATION_EVT_RECAL)) == 0) { + WMT_INFO_FUNC("Recalibration happened. Re-get calibration data\n"); + iRet = 1; + goto restore_end; + } else { + /* Do calibration */ + WMT_ERR_FUNC("Send calibration event error. 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x\n", + evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], evtBuf[5]); + iRet = -5; + goto restore_end; + } + } else { + WMT_ERR_FUNC("Did not restore calibration data. Buf=0x%p, size=%d\n", + gBTCalResult, gBTCalResultSize); + iRet = -6; + goto restore_end; + } + +restore_end: + if (mtk_wcn_wlan_emi_mpu_set_protection) + (*mtk_wcn_wlan_emi_mpu_set_protection)(false); + WMT_STEP_DO_ACTIONS_FUNC(STEP_TRIGGER_POINT_AFTER_RESTORE_CAL_CMD); + if (mtk_wcn_wlan_emi_mpu_set_protection) + (*mtk_wcn_wlan_emi_mpu_set_protection)(true); + osal_free(evtBuf); + return iRet; +} + +/* + * To backup calibration data + * For BT, get data by STP command. + * For Wi-Fi, get EMI offset and length from STP command and then + * backup data from EMI + * + * Return value: + * 0: backup success + * < 0: fail + */ +static INT32 mtk_wcn_soc_calibration_backup(void) +{ + INT32 iRet = 0; + PUINT8 evtBuf; + UINT32 u4Res; + UINT16 len = 0; + P_CONSYS_EMI_ADDR_INFO emiInfo = mtk_wcn_consys_soc_get_emi_phy_add(); + UINT32 wifiOffset = 0; + UINT32 wifiLen = 0; + void __iomem *virWiFiAddrBase; + + /* Allocate RX event buffer */ + evtBuf = osal_malloc(CALIBRATION_BACKUP_RESTORE_BUFFER_SIZE); + if (evtBuf == NULL) { + WMT_ERR_FUNC("Allocate event buffer failed\n"); + return -1; + } + /* Get calibration data TX */ + iRet = wmt_core_tx(WMT_CORE_GET_RF_CALIBRATION_CMD, + sizeof(WMT_CORE_GET_RF_CALIBRATION_CMD), + &u4Res, MTK_WCN_BOOL_FALSE); + if (iRet || u4Res != sizeof(WMT_CORE_GET_RF_CALIBRATION_CMD)) { + WMT_ERR_FUNC("Write get calibration cmd failed(%d), exp: %lu but write %d\n", + iRet, sizeof(WMT_CORE_GET_RF_CALIBRATION_CMD), u4Res); + goto get_calibration_fail; + } + osal_memset(&evtBuf[0], 0, CALIBRATION_BACKUP_RESTORE_BUFFER_SIZE); + iRet = wmt_core_rx(evtBuf, CALIBRATION_BACKUP_RESTORE_BUFFER_SIZE, &u4Res); + /* RX expected format: + * 02 14 [X+14 (2 bytes)] 00 03 + * [BT size = X (2 bytes)] [BT Cal. Data (X bytes)] + * [WiFi Size = 8 (2 bytes)] [WiFi Offset (4 bytes)] [WiFi len(4 bytes)] + */ + if (iRet || u4Res < 8) { + WMT_ERR_FUNC("Get calibration event failed(%d), get %d bytes\n", iRet, u4Res); + goto get_calibration_fail; + } + /* Check data validaness */ + if (evtBuf[0] != 0x02 || evtBuf[1] != 0x14 || + evtBuf[4] != 0x00 || evtBuf[5] != 0x03) { + WMT_ERR_FUNC("Get calibration event error. 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x\n", + evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], evtBuf[5]); + goto get_calibration_fail; + } + /* Get data success, backup it. + * Data size is not the same as previous, realloc memory + */ + osal_memcpy(&len, &evtBuf[6], 2); + if (len != gBTCalResultSize) { + gBTCalResultSize = len; + if (gBTCalResult != NULL) { + osal_free(gBTCalResult); + gBTCalResult = NULL; + } + } + if (gBTCalResult == NULL) + gBTCalResult = osal_malloc(gBTCalResultSize); + if (gBTCalResult == NULL) { + WMT_ERR_FUNC("Allocate BT calibration buffer failed.\n"); + goto get_calibration_fail; + } + osal_memcpy(gBTCalResult, &evtBuf[8], gBTCalResultSize); + /* Get Wi-Fi info */ + osal_memcpy(&wifiOffset, &evtBuf[10 + gBTCalResultSize], 4); + osal_memcpy(&wifiLen, &evtBuf[14 + gBTCalResultSize], 4); + if (wifiLen != gWiFiCalSize) { + gWiFiCalSize = wifiLen; + if (gWiFiCalResult != NULL) { + osal_free(gWiFiCalResult); + gWiFiCalResult = NULL; + } + } + if (gWiFiCalResult == NULL) + gWiFiCalResult = osal_malloc(gWiFiCalSize); + if (gWiFiCalResult == NULL) { + WMT_ERR_FUNC("Allocate Wi-Fi calibration buffer failed.\n"); + goto get_calibration_fail; + } + /* Start to backup Wi-Fi data */ + if (!emiInfo) { + WMT_ERR_FUNC("get emi info fail!\n"); + goto get_calibration_fail; + } + /* Before copy, disable Wi-Fi MPU to access EMI */ + if (mtk_wcn_wlan_emi_mpu_set_protection) + (*mtk_wcn_wlan_emi_mpu_set_protection)(false); + WMT_STEP_DO_ACTIONS_FUNC( + STEP_TRIGGER_POINT_POWER_ON_AFTER_BT_WIFI_CALIBRATION); + gWiFiCalAddrOffset = wifiOffset; + virWiFiAddrBase = ioremap_nocache( + emiInfo->emi_ap_phy_addr + gWiFiCalAddrOffset, + gWiFiCalSize); + if (virWiFiAddrBase) { + osal_memcpy_fromio(gWiFiCalResult, virWiFiAddrBase, gWiFiCalSize); + iounmap(virWiFiAddrBase); + } else { + WMT_ERR_FUNC("Remap Wi-Fi EMI fail: offset=%d size=%d\n", + gWiFiCalAddrOffset, gWiFiCalSize); + goto get_calibration_fail; + } + /* Enable Wi-Fi MPU after finished. */ + if (mtk_wcn_wlan_emi_mpu_set_protection) + (*mtk_wcn_wlan_emi_mpu_set_protection)(true); + WMT_INFO_FUNC("gBTCalResultSize=%d gWiFiCalResult=0x%p gWiFiCalSize=%d gWiFiCalAddrOffset=0x%x\n", + gBTCalResultSize, + gWiFiCalResult, + gWiFiCalSize, + gWiFiCalAddrOffset); + osal_free(evtBuf); + return 0; +get_calibration_fail: + WMT_ERR_FUNC("Get calibration failed.\n"); + if (emiInfo) { + WMT_ERR_FUNC("emiInfo: emi_ap_phy_addr=0x%x emi_size=%d emi_phy_addr=0x%x\n", + emiInfo->emi_ap_phy_addr, + emiInfo->emi_size, + emiInfo->emi_phy_addr); + } + WMT_ERR_FUNC("gBTCalResultSize=%d gWiFiCalResult=0x%p gWiFiCalSize=%d gWiFiCalAddrOffset=0x%x\n", + gBTCalResultSize, gWiFiCalResult, + gWiFiCalSize, gWiFiCalAddrOffset); + if (gBTCalResult != NULL) { + osal_free(gBTCalResult); + gBTCalResult = NULL; + } + gBTCalResultSize = 0; + if (gWiFiCalResult != NULL) { + osal_free(gWiFiCalResult); + gWiFiCalResult = NULL; + } + gWiFiCalSize = 0; + gWiFiCalAddrOffset = 0; + /* Enable Wi-Fi MPU after finished. */ + if (mtk_wcn_wlan_emi_mpu_set_protection) + (*mtk_wcn_wlan_emi_mpu_set_protection)(true); + osal_free(evtBuf); + return -1; +} +#endif + +static INT32 mtk_wcn_soc_do_calibration(void) +{ + INT32 iRet = 0; + +#if CFG_CALIBRATION_BACKUP_RESTORE + /* When chip reset is caused by assert, skip calibration. + * Restore old data. + */ + if (mtk_consys_is_calibration_backup_restore_support() == 0 || + mtk_wcn_stp_assert_flow_get() == 0) { + WMT_INFO_FUNC( + "Skip restore, chip id=%x mtk_wcn_stp_assert_flow_get()=%d\n", + wmt_ic_ops_soc.icId, mtk_wcn_stp_assert_flow_get()); + goto do_calibration; + } + + iRet = mtk_wcn_soc_calibration_restore(); + if (iRet == 0) { + WMT_INFO_FUNC("Restore success\n"); + return 0; + } else if (iRet == 1) { + WMT_INFO_FUNC("Recal happened. Re-get calibration data.\n"); + goto get_calibration; + } else + /* For all other case, re-cali. */ + WMT_ERR_FUNC("Re-cal because restore fail(%d)\n", iRet); + +do_calibration: +#endif /* CFG_CALIBRATION_BACKUP_RESTORE */ + /* Do calibration */ + WMT_INFO_FUNC("Calibration start\n"); + iRet = wmt_core_init_script( + calibration_table, + osal_array_size(calibration_table)); + WMT_INFO_FUNC("Calibration end\n"); + if (iRet) { + #if CFG_CALIBRATION_BACKUP_RESTORE + /* Calibration failed. Clear backup data. */ + if (gBTCalResult != NULL) { + osal_free(gBTCalResult); + gBTCalResult = NULL; + } + gBTCalResultSize = 0; + if (gWiFiCalResult != NULL) { + osal_free(gWiFiCalResult); + gWiFiCalResult = NULL; + } + gWiFiCalSize = 0; + gWiFiCalAddrOffset = 0; + #endif + WMT_ERR_FUNC("do calibration failed (%d)\n", iRet); + return -1; + } + +#if CFG_CALIBRATION_BACKUP_RESTORE + if (mtk_consys_is_calibration_backup_restore_support() == 0) + return 0; + +get_calibration: + iRet = mtk_wcn_soc_calibration_backup(); + /* Backup process should not influence power on sequence. + * Hence, even it return error, just record it and + * report calibration success. + */ + if (iRet == 0) + WMT_INFO_FUNC("Backup success\n"); + else + WMT_ERR_FUNC("Backup failed(%d)\n", iRet); +#endif + return 0; +} + +static INT32 mtk_wcn_soc_calibration(void) +{ + INT32 iRet = -1; + INT32 iCalRet = -1; + unsigned long ctrlPa1; + unsigned long ctrlPa2; + + /* Turn on BT/Wi-Fi */ + ctrlPa1 = BT_PALDO; + ctrlPa2 = PALDO_ON; + iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); + ctrlPa1 = WIFI_PALDO; + ctrlPa2 = PALDO_ON; + iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); + + WMT_INFO_FUNC("mtk_wcn_soc_do_calibration start\n"); + iCalRet = mtk_wcn_soc_do_calibration(); + WMT_INFO_FUNC("mtk_wcn_soc_do_calibration end\n"); + + /* Turn off BT/Wi-Fi */ + ctrlPa1 = BT_PALDO; + ctrlPa2 = PALDO_OFF; + iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); + ctrlPa1 = WIFI_PALDO; + ctrlPa2 = PALDO_OFF; + iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); + + if (iCalRet) { + /* pwrap_read(0x0210,&ctrlPa1); */ + /* pwrap_read(0x0212,&ctrlPa2); */ + /* WMT_ERR_FUNC("power status: 210:(%d),212:(%d)!\n", ctrlPa1, ctrlPa2); */ + WMT_ERR_FUNC("calibration_table fail(%d)\n", iCalRet); + return -1; + } + return 0; +} diff --git a/drivers/misc/mediatek/connectivity/common/common_main/core/wmt_lib.c b/drivers/misc/mediatek/connectivity/common/common_main/core/wmt_lib.c new file mode 100644 index 0000000000000000000000000000000000000000..13ebe4c8ad096b68842a6a3dae247d9e3289656d --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/core/wmt_lib.c @@ -0,0 +1,3382 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +#ifdef DFT_TAG +#undef DFT_TAG +#endif +#define DFT_TAG "[WMT-LIB]" + + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include "osal_typedef.h" +#include "wmt_dbg.h" + +#include "wmt_dev.h" +#include "wmt_lib.h" +#include "wmt_conf.h" +#include "wmt_core.h" +#include "wmt_plat.h" +#include "wmt_plat_stub.h" +#include "wmt_detect.h" +#include "mtk_wcn_consys_hw.h" + +#include "stp_core.h" +#include "btm_core.h" +#include "psm_core.h" +#include "stp_sdio.h" +#include "stp_dbg.h" +#include "wmt_step.h" +#include +#include + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + + + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/* A table for translation: enum CMB_STUB_AIF_X=>WMT_IC_PIN_STATE */ +static const WMT_IC_PIN_STATE cmb_aif2pin_stat[] = { + [CMB_STUB_AIF_0] = WMT_IC_AIF_0, + [CMB_STUB_AIF_1] = WMT_IC_AIF_1, + [CMB_STUB_AIF_2] = WMT_IC_AIF_2, + [CMB_STUB_AIF_3] = WMT_IC_AIF_3, + [CMB_STUB_AIF_4] = WMT_IC_PIN_STATE_MAX, +}; + +#if CFG_WMT_PS_SUPPORT +static UINT32 gPsIdleTime = STP_PSM_IDLE_TIME_SLEEP; +static UINT32 gPsEnable = 1; +static PF_WMT_SDIO_PSOP sdio_own_ctrl; +static PF_WMT_SDIO_DEBUG sdio_reg_rw; +#endif +#ifdef CONFIG_MTK_COMBO_CHIP_DEEP_SLEEP_SUPPORT +static PF_WMT_SDIO_DEEP_SLEEP sdio_deep_sleep_flag_set; +#endif + + +#define WMT_STP_CPUPCR_BUF_SIZE 73728 +static UINT8 g_cpupcr_buf[WMT_STP_CPUPCR_BUF_SIZE] = { 0 }; +static UINT32 g_quick_sleep_ctrl = 1; +static UINT32 g_fw_patch_update_rst; +static u64 fw_patch_rst_time; + +#define ASSERT_KEYWORD_LENGTH 20 +struct assert_work_st { + struct work_struct work; + ENUM_WMTDRV_TYPE_T type; + UINT32 reason; + UINT8 keyword[ASSERT_KEYWORD_LENGTH]; +}; + +static struct assert_work_st wmt_assert_work; + +static INT32 g_bt_no_acl_link = 1; +static INT32 g_bt_no_br_acl_link = 1; + +#define CONSYS_MET_WAIT (1000*10) /* ms */ +#define MET_DUMP_MAX_NUM (1) +#define MET_DUMP_SIZE (4*MET_DUMP_MAX_NUM) +#define EMI_MET_READ_OFFSET 0x0 +#define EMI_MET_WRITE_OFFSET 0x4 +#define EMI_MET_DATA_OFFSET 0x8 +#define FW_PATCH_UPDATE_RST_DURATION 180 /* 180 seconds */ + +#define WMT_LIB_DMP_CONSYS_MAX_TIMES 10 + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +DEV_WMT gDevWmt; + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +#if CFG_WMT_PS_SUPPORT +static MTK_WCN_BOOL wmt_lib_ps_action(MTKSTP_PSM_ACTION_T action); +static MTK_WCN_BOOL wmt_lib_ps_do_sleep(VOID); +static MTK_WCN_BOOL wmt_lib_ps_do_wakeup(VOID); +static MTK_WCN_BOOL wmt_lib_ps_do_host_awake(VOID); +static INT32 wmt_lib_ps_handler(MTKSTP_PSM_ACTION_T action); +#endif + +static MTK_WCN_BOOL wmt_lib_put_op(P_OSAL_OP_Q pOpQ, P_OSAL_OP pLxOp); + +static P_OSAL_OP wmt_lib_get_op(P_OSAL_OP_Q pOpQ); + +static INT32 wmtd_thread(PVOID pvData); +static INT32 met_thread(PVOID pvData); +static INT32 wmtd_worker_thread(PVOID pvData); + +static INT32 wmt_lib_pin_ctrl(WMT_IC_PIN_ID id, WMT_IC_PIN_STATE stat, UINT32 flag); +static MTK_WCN_BOOL wmt_lib_hw_state_show(VOID); +static VOID wmt_lib_utc_sync_timeout_handler(timer_handler_arg arg); +static VOID wmt_lib_utc_sync_worker_handler(struct work_struct *work); +static VOID wmt_lib_wmtd_worker_thread_timeout_handler(timer_handler_arg); +static VOID wmt_lib_wmtd_worker_thread_work_handler(struct work_struct *work); + +static VOID wmt_lib_assert_work_cb(struct work_struct *work); +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +INT32 __weak mtk_wcn_consys_stp_btif_dpidle_ctrl(UINT32 en_flag) +{ + WMT_ERR_FUNC("mtk_wcn_consys_stp_btif_dpidle_ctrl is not define!!!\n"); + + return 0; +} + +INT32 wmt_lib_wlan_lock_aquire(VOID) +{ + return osal_lock_sleepable_lock(&gDevWmt.wlan_lock); +} + +VOID wmt_lib_wlan_lock_release(VOID) +{ + osal_unlock_sleepable_lock(&gDevWmt.wlan_lock); +} + +INT32 wmt_lib_wlan_lock_trylock(VOID) +{ + return osal_trylock_sleepable_lock(&gDevWmt.wlan_lock); +} + +INT32 wmt_lib_idc_lock_aquire(VOID) +{ + return osal_lock_sleepable_lock(&gDevWmt.idc_lock); +} + +VOID wmt_lib_idc_lock_release(VOID) +{ + osal_unlock_sleepable_lock(&gDevWmt.idc_lock); +} + +INT32 wmt_lib_psm_lock_aquire(VOID) +{ + return osal_lock_sleepable_lock(&gDevWmt.psm_lock); +} + +void wmt_lib_psm_lock_release(VOID) +{ + osal_unlock_sleepable_lock(&gDevWmt.psm_lock); +} + +INT32 wmt_lib_psm_lock_trylock(VOID) +{ + return osal_trylock_sleepable_lock(&gDevWmt.psm_lock); +} + +INT32 wmt_lib_assert_lock_aquire(VOID) +{ + return osal_lock_sleepable_lock(&gDevWmt.assert_lock); +} + +VOID wmt_lib_assert_lock_release(VOID) +{ + osal_unlock_sleepable_lock(&gDevWmt.assert_lock); +} + +INT32 wmt_lib_assert_lock_trylock(VOID) +{ + return osal_trylock_sleepable_lock(&gDevWmt.assert_lock); +} + +INT32 wmt_lib_mpu_lock_aquire(VOID) +{ + return osal_lock_sleepable_lock(&gDevWmt.mpu_lock); +} + +VOID wmt_lib_mpu_lock_release(VOID) +{ + osal_unlock_sleepable_lock(&gDevWmt.mpu_lock); +} + +INT32 wmt_lib_power_lock_aquire(VOID) +{ + return osal_lock_sleepable_lock(&gDevWmt.power_lock); +} + +VOID wmt_lib_power_lock_release(VOID) +{ + osal_unlock_sleepable_lock(&gDevWmt.power_lock); +} + +INT32 wmt_lib_power_lock_trylock(VOID) +{ + return osal_trylock_sleepable_lock(&gDevWmt.power_lock); +} + +INT32 DISABLE_PSM_MONITOR(VOID) +{ + INT32 ret = 0; + PUINT8 pbuf = NULL; + INT32 len = 0; + + /* osal_lock_sleepable_lock(&gDevWmt.psm_lock); */ + ret = wmt_lib_psm_lock_aquire(); + if (ret) { + WMT_ERR_FUNC("--->lock psm_lock failed, ret=%d\n", ret); + return ret; + } +#if CFG_WMT_PS_SUPPORT + ret = wmt_lib_ps_disable(); + if (ret) { + WMT_ERR_FUNC("wmt_lib_ps_disable fail, ret=%d\n", ret); + wmt_lib_psm_lock_release(); + if (mtk_wcn_stp_coredump_start_get() == 0 && + chip_reset_only == 0 && + mtk_wcn_stp_get_wmt_trg_assert() == 0) { + pbuf = "wmt_lib_ps_disable fail, just collect SYS_FTRACE to DB"; + len = osal_strlen(pbuf); + stp_dbg_trigger_collect_ftrace(pbuf, len); + wmt_lib_trigger_reset(); + } + } +#endif + return ret; +} + +VOID ENABLE_PSM_MONITOR(VOID) +{ +#if CFG_WMT_PS_SUPPORT + wmt_lib_ps_enable(); +#endif + /* osal_unlock_sleepable_lock(&gDevWmt.psm_lock); */ + wmt_lib_psm_lock_release(); +} + + +INT32 wmt_lib_init(VOID) +{ + INT32 iRet; + UINT32 i; + P_DEV_WMT pDevWmt; + P_OSAL_THREAD pThread; + P_OSAL_THREAD pWorkerThread; + ENUM_WMT_CHIP_TYPE chip_type; + + /* create->init->start */ + /* 1. create: static allocation with zero initialization */ + pDevWmt = &gDevWmt; + osal_memset(&gDevWmt, 0, sizeof(gDevWmt)); + if (wmt_detect_get_chip_type() == WMT_CHIP_TYPE_SOC) { + iRet = wmt_conf_read_file(); + if (iRet) { + WMT_ERR_FUNC("read wmt config file fail(%d)\n", iRet); + return -1; + } + } + osal_op_history_init(&pDevWmt->wmtd_op_history, 16); + osal_op_history_init(&pDevWmt->worker_op_history, 8); + + pThread = &gDevWmt.thread; + + /* Create mtk_wmtd thread */ + osal_strncpy(pThread->threadName, "mtk_wmtd", sizeof(pThread->threadName)); + pThread->pThreadData = (PVOID) pDevWmt; + pThread->pThreadFunc = (PVOID) wmtd_thread; + iRet = osal_thread_create(pThread); + if (iRet) { + WMT_ERR_FUNC("osal_thread_create(0x%p) fail(%d)\n", pThread, iRet); + return -2; + } + + /* create worker timer */ + gDevWmt.worker_timer.timeoutHandler = wmt_lib_wmtd_worker_thread_timeout_handler; + gDevWmt.worker_timer.timeroutHandlerData = 0; + osal_timer_create(&gDevWmt.worker_timer); + pWorkerThread = &gDevWmt.worker_thread; + INIT_WORK(&pDevWmt->wmtd_worker_thread_work, wmt_lib_wmtd_worker_thread_work_handler); + + /* Create wmtd_worker thread */ + osal_strncpy(pWorkerThread->threadName, "mtk_wmtd_worker", sizeof(pWorkerThread->threadName)); + pWorkerThread->pThreadData = (PVOID) pDevWmt; + pWorkerThread->pThreadFunc = (PVOID) wmtd_worker_thread; + iRet = osal_thread_create(pWorkerThread); + if (iRet) { + WMT_ERR_FUNC("osal_thread_create(0x%p) fail(%d)\n", pWorkerThread, iRet); + return -2; + } + + /* init timer */ + pDevWmt->utc_sync_timer.timeoutHandler = wmt_lib_utc_sync_timeout_handler; + osal_timer_create(&pDevWmt->utc_sync_timer); + osal_timer_start(&pDevWmt->utc_sync_timer, UTC_SYNC_TIME); + INIT_WORK(&pDevWmt->utcSyncWorker, wmt_lib_utc_sync_worker_handler); + + /* 2. initialize */ + /* Initialize wmt_core */ + + iRet = wmt_core_init(); + if (iRet) { + WMT_ERR_FUNC("wmt_core_init() fail(%d)\n", iRet); + return -1; + } + + /* Initialize WMTd Thread Information: Thread */ + osal_event_init(&pDevWmt->rWmtdWq); + osal_event_init(&pDevWmt->rWmtdWorkerWq); + osal_sleepable_lock_init(&pDevWmt->psm_lock); + osal_sleepable_lock_init(&pDevWmt->idc_lock); + osal_sleepable_lock_init(&pDevWmt->wlan_lock); + osal_sleepable_lock_init(&pDevWmt->assert_lock); + osal_sleepable_lock_init(&pDevWmt->mpu_lock); + osal_sleepable_lock_init(&pDevWmt->power_lock); + osal_sleepable_lock_init(&pDevWmt->rActiveOpQ.sLock); + osal_sleepable_lock_init(&pDevWmt->rWorkerOpQ.sLock); + osal_sleepable_lock_init(&pDevWmt->rFreeOpQ.sLock); + pDevWmt->state.data = 0; + + atomic_set(&pDevWmt->state_dmp_req.version, 0); + for (i = 0; i < WMT_LIB_DMP_SLOT; i++) + osal_sleepable_lock_init(&(pDevWmt->state_dmp_req.consys_ops[i].lock)); + + /* Initialize op queue */ + RB_INIT(&pDevWmt->rFreeOpQ, WMT_OP_BUF_SIZE); + RB_INIT(&pDevWmt->rActiveOpQ, WMT_OP_BUF_SIZE); + RB_INIT(&pDevWmt->rWorkerOpQ, WMT_OP_BUF_SIZE); + /* Put all to free Q */ + for (i = 0; i < WMT_OP_BUF_SIZE; i++) { + osal_signal_init(&(pDevWmt->arQue[i].signal)); + wmt_lib_put_op(&pDevWmt->rFreeOpQ, &(pDevWmt->arQue[i])); + } + + /* initialize stp resources */ + osal_event_init(&pDevWmt->rWmtRxWq); + + /*function driver callback */ + for (i = 0; i < WMTDRV_TYPE_WIFI; i++) + pDevWmt->rFdrvCb.fDrvRst[i] = NULL; + + pDevWmt->hw_ver = WMTHWVER_MAX; + WMT_DBG_FUNC("***********Init, hw->ver = %x\n", pDevWmt->hw_ver); + + /* TODO:[FixMe][GeorgeKuo]: wmt_lib_conf_init */ + /* initialize default configurations */ + /* i4Result = wmt_lib_conf_init(VOID); */ + /* WMT_WARN_FUNC("wmt_drv_conf_init(%d)\n", i4Result); */ + + osal_signal_init(&pDevWmt->cmdResp); + osal_event_init(&pDevWmt->cmdReq); + /* initialize platform resources */ + + if (gDevWmt.rWmtGenConf.cfgExist != 0) { + PWR_SEQ_TIME pwrSeqTime; + + pwrSeqTime.ldoStableTime = gDevWmt.rWmtGenConf.pwr_on_ldo_slot; + pwrSeqTime.rstStableTime = gDevWmt.rWmtGenConf.pwr_on_rst_slot; + pwrSeqTime.onStableTime = gDevWmt.rWmtGenConf.pwr_on_on_slot; + pwrSeqTime.offStableTime = gDevWmt.rWmtGenConf.pwr_on_off_slot; + pwrSeqTime.rtcStableTime = gDevWmt.rWmtGenConf.pwr_on_rtc_slot; + WMT_INFO_FUNC("set pwr on seq par to hw conf\n"); + WMT_INFO_FUNC("ldo(%d)rst(%d)on(%d)off(%d)rtc(%d)\n", pwrSeqTime.ldoStableTime, + pwrSeqTime.rstStableTime, pwrSeqTime.onStableTime, + pwrSeqTime.offStableTime, pwrSeqTime.rtcStableTime); + iRet = wmt_plat_init(&pwrSeqTime, gDevWmt.rWmtGenConf.co_clock_flag & 0x0f); + } else { + WMT_ERR_FUNC("no pwr on seq and clk par found\n"); + iRet = wmt_plat_init(NULL, 0); + } + chip_type = wmt_detect_get_chip_type(); + if (chip_type == WMT_CHIP_TYPE_SOC) + gDevWmt.rWmtGenConf.co_clock_flag = wmt_plat_soc_co_clock_flag_get(); + + if (iRet) { + WMT_ERR_FUNC("wmt_plat_init() fail(%d)\n", iRet); + return -3; + } + +#if CFG_WMT_PS_SUPPORT + iRet = wmt_lib_ps_init(); + if (iRet) { + WMT_ERR_FUNC("wmt_lib_ps_init() fail(%d)\n", iRet); + return -4; + } +#endif + + /* 3. start: start running mtk_wmtd */ + iRet = osal_thread_run(pThread); + if (iRet) { + WMT_ERR_FUNC("osal_thread_run(wmtd 0x%p) fail(%d)\n", pThread, iRet); + return -5; + } + + iRet = osal_thread_run(pWorkerThread); + if (iRet) { + WMT_ERR_FUNC("osal_thread_run(worker 0x%p) fail(%d)\n", pWorkerThread, iRet); + return -5; + } + /*4. register irq callback to WMT-PLAT */ + wmt_plat_irq_cb_reg(wmt_lib_ps_irq_cb); + /*5. register audio if control callback to WMT-PLAT */ + wmt_plat_aif_cb_reg(wmt_lib_set_aif); + /*6. register function control callback to WMT-PLAT */ + wmt_plat_func_ctrl_cb_reg(mtk_wcn_wmt_func_ctrl_for_plat); + + wmt_plat_deep_idle_ctrl_cb_reg(mtk_wcn_consys_stp_btif_dpidle_ctrl); + /*7 reset gps/bt state */ + + mtk_wcn_wmt_system_state_reset(); + +#ifndef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT + mtk_wcn_wmt_exp_init(); +#endif + +#if CFG_WMT_LTE_COEX_HANDLING + wmt_idc_init(); +#endif + + INIT_WORK(&(wmt_assert_work.work), wmt_lib_assert_work_cb); + + WMT_DBG_FUNC("init success\n"); + return 0; +} + + +INT32 wmt_lib_deinit(VOID) +{ + INT32 iRet; + P_DEV_WMT pDevWmt; + P_OSAL_THREAD pThread; + P_OSAL_THREAD pWorkerThread; + INT32 i; + INT32 iResult; + struct vendor_patch_table *table = &(gDevWmt.patch_table); + + pDevWmt = &gDevWmt; + pThread = &gDevWmt.thread; + pWorkerThread = &gDevWmt.worker_thread; + iResult = 0; + + /* stop->deinit->destroy */ + + /* 1. stop: stop running mtk_wmtd */ + iRet = osal_thread_stop(pThread); + if (iRet) { + WMT_ERR_FUNC("osal_thread_stop(0x%p) fail(%d)\n", pThread, iRet); + iResult += 1; + } + + iRet = osal_thread_stop(pWorkerThread); + if (iRet) { + WMT_ERR_FUNC("osal_thread_stop(0x%p) fail(%d)\n", pWorkerThread, iRet); + iResult += 1; + } + + /* 2. deinit: */ + +#if CFG_WMT_PS_SUPPORT + iRet = wmt_lib_ps_deinit(); + if (iRet) { + WMT_ERR_FUNC("wmt_lib_ps_deinit fail(%d)\n", iRet); + iResult += 2; + } +#endif + + iRet = wmt_plat_deinit(); + if (iRet) { + WMT_ERR_FUNC("wmt_plat_deinit fail(%d)\n", iRet); + iResult += 4; + } + + osal_event_deinit(&pDevWmt->cmdReq); + osal_signal_deinit(&pDevWmt->cmdResp); + + /* de-initialize stp resources */ + osal_event_deinit(&pDevWmt->rWmtRxWq); + + for (i = 0; i < WMT_OP_BUF_SIZE; i++) + osal_signal_deinit(&(pDevWmt->arQue[i].signal)); + + osal_sleepable_lock_deinit(&pDevWmt->rFreeOpQ.sLock); + osal_sleepable_lock_deinit(&pDevWmt->rActiveOpQ.sLock); + osal_sleepable_lock_deinit(&pDevWmt->rWorkerOpQ.sLock); + osal_sleepable_lock_deinit(&pDevWmt->power_lock); + osal_sleepable_lock_deinit(&pDevWmt->mpu_lock); + osal_sleepable_lock_deinit(&pDevWmt->idc_lock); + osal_sleepable_lock_deinit(&pDevWmt->wlan_lock); + osal_sleepable_lock_deinit(&pDevWmt->assert_lock); + osal_sleepable_lock_deinit(&pDevWmt->psm_lock); + + for (i = 0; i < WMT_LIB_DMP_SLOT; i++) + osal_sleepable_lock_deinit(&(pDevWmt->state_dmp_req.consys_ops[i].lock)); + + osal_event_deinit(&pDevWmt->rWmtdWq); + osal_event_deinit(&pDevWmt->rWmtdWorkerWq); + + for (i = 0; i < WMTDRV_TYPE_ANT; i++) { + kfree(pDevWmt->pWmtRomPatchInfo[i]); + pDevWmt->pWmtRomPatchInfo[i] = NULL; + } + + iRet = wmt_core_deinit(); + if (iRet) { + WMT_ERR_FUNC("wmt_core_deinit fail(%d)\n", iRet); + iResult += 8; + } + + /* 3. destroy */ + iRet = osal_thread_destroy(pThread); + if (iRet) { + WMT_ERR_FUNC("osal_thread_stop(0x%p) fail(%d)\n", pThread, iRet); + iResult += 16; + } + + iRet = osal_thread_destroy(pWorkerThread); + if (iRet) { + WMT_ERR_FUNC("osal_thread_stop(0x%p) fail(%d)\n", pWorkerThread, iRet); + iResult += 32; + } + + iRet = wmt_conf_deinit(); + if (iRet) { + WMT_ERR_FUNC("wmt_conf_deinit fail(%d)\n", iRet); + iResult += 64; + } + + osal_memset(&gDevWmt, 0, sizeof(gDevWmt)); +#if 0 +#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT + mtk_wcn_wmt_exp_deinit(); +#endif +#endif + +#if CFG_WMT_LTE_COEX_HANDLING + wmt_idc_deinit(); +#endif + + if (table->active_version != NULL) { + for (i = 0; i < table->num; i++) { + if (table->active_version[i]) + osal_free(table->active_version[i]); + } + osal_free(table->active_version); + table->active_version = NULL; + } + + WMT_STEP_DEINIT_FUNC(); + + return iResult; +} + +VOID wmt_lib_flush_rx(VOID) +{ + mtk_wcn_stp_flush_rx_queue(WMT_TASK_INDX); +} + +INT32 wmt_lib_trigger_cmd_signal(INT32 result) +{ + P_OSAL_SIGNAL pSignal = &gDevWmt.cmdResp; + + gDevWmt.cmdResult = result; + osal_raise_signal(pSignal); + WMT_DBG_FUNC("wakeup cmdResp\n"); + return 0; +} + +P_OSAL_EVENT wmt_lib_get_cmd_event(VOID) +{ + return &gDevWmt.cmdReq; +} + +INT32 wmt_lib_set_patch_name(PUINT8 cPatchName) +{ + osal_strncpy(gDevWmt.cPatchName, cPatchName, NAME_MAX); + return 0; +} + +INT32 wmt_lib_set_uart_name(PINT8 cUartName) +{ +#if WMT_PLAT_ALPS + + WMT_DBG_FUNC("orig uart: %s\n", wmt_uart_port_desc); +#endif + osal_strncpy(gDevWmt.cUartName, cUartName, NAME_MAX); +#if WMT_PLAT_ALPS + wmt_uart_port_desc = gDevWmt.cUartName; + WMT_DBG_FUNC("new uart: %s\n", wmt_uart_port_desc); +#endif + return 0; +} + +INT32 wmt_lib_set_hif(ULONG hifconf) +{ + UINT32 val; + P_WMT_HIF_CONF pHif = &gDevWmt.rWmtHifConf; + + val = hifconf & 0xF; + switch (val) { + case STP_UART_FULL: + pHif->hifType = WMT_HIF_UART; + pHif->uartFcCtrl = ((hifconf & 0xc) >> 2); + val = (hifconf >> 8); + pHif->au4HifConf[0] = val; + pHif->au4HifConf[1] = val; + mtk_wcn_stp_set_if_tx_type(STP_UART_IF_TX); + wmt_plat_set_comm_if_type(STP_UART_IF_TX); + break; + case STP_SDIO: + pHif->hifType = WMT_HIF_SDIO; + mtk_wcn_stp_set_if_tx_type(STP_SDIO_IF_TX); + wmt_plat_set_comm_if_type(STP_SDIO_IF_TX); + break; + case STP_BTIF_FULL: + pHif->hifType = WMT_HIF_BTIF; + mtk_wcn_stp_set_if_tx_type(STP_BTIF_IF_TX); + break; + default: + WMT_WARN_FUNC("invalid stp mode: %lu %u\n", hifconf, val); + return -1; + } + + val = (hifconf & 0xF0) >> 4; + if (val == WMT_FM_COMM) { + pHif->au4StrapConf[0] = WMT_FM_COMM; + } else if (val == WMT_FM_I2C) { + pHif->au4StrapConf[0] = WMT_FM_I2C; + } else { + WMT_WARN_FUNC("invalid fm mode: %u\n", val); + return -2; + } + + WMT_DBG_FUNC("new hifType:%d, fcCtrl:%d, baud:%d, fm:%d\n", + pHif->hifType, pHif->uartFcCtrl, pHif->au4HifConf[0], pHif->au4StrapConf[0]); + return 0; +} + + +P_WMT_HIF_CONF wmt_lib_get_hif(VOID) +{ + return &gDevWmt.rWmtHifConf; +} + +PUINT8 wmt_lib_get_cmd(VOID) +{ + if (osal_test_and_clear_bit(WMT_STAT_CMD, &gDevWmt.state)) + return gDevWmt.cCmd; + + return NULL; +} + +MTK_WCN_BOOL wmt_lib_get_cmd_status(VOID) +{ + return osal_test_bit(WMT_STAT_CMD, &gDevWmt.state) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE; +} + +MTK_WCN_BOOL wmt_lib_stp_is_btif_fullset_mode(VOID) +{ + return mtk_wcn_stp_is_btif_fullset_mode(); +} + +#if CFG_WMT_PS_SUPPORT +INT32 wmt_lib_ps_set_idle_time(UINT32 psIdleTime) +{ + gPsIdleTime = psIdleTime; + return gPsIdleTime; +} + +INT32 wmt_lib_ps_ctrl(UINT32 state) +{ + if (state == 0) { + wmt_lib_ps_disable(); + gPsEnable = 0; + } else { + gPsEnable = 1; + wmt_lib_ps_enable(); + } + return 0; +} + + +INT32 wmt_lib_ps_enable(VOID) +{ + if (gPsEnable) + mtk_wcn_stp_psm_enable(gPsIdleTime); + + return 0; +} + +INT32 wmt_lib_ps_disable(VOID) +{ + if (gPsEnable) + return mtk_wcn_stp_psm_disable(); + + return 0; +} + +INT32 wmt_lib_ps_init(VOID) +{ + /* mtk_wcn_stp_psm_register_wmt_cb(wmt_lib_ps_stp_cb); */ + return 0; +} + +INT32 wmt_lib_ps_deinit(VOID) +{ + /* mtk_wcn_stp_psm_unregister_wmt_cb(); */ + return 0; +} + +static MTK_WCN_BOOL wmt_lib_ps_action(MTKSTP_PSM_ACTION_T action) +{ + P_OSAL_OP lxop; + MTK_WCN_BOOL bRet; + UINT32 u4Wait; + P_OSAL_SIGNAL pSignal; + + lxop = wmt_lib_get_free_op(); + if (!lxop) { + WMT_DBG_FUNC("get_free_lxop fail\n"); + return MTK_WCN_BOOL_FALSE; + } + + pSignal = &lxop->signal; + pSignal->timeoutValue = 0; + lxop->op.opId = WMT_OPID_PWR_SV; + lxop->op.au4OpData[0] = action; + lxop->op.au4OpData[1] = (SIZE_T) mtk_wcn_stp_psm_notify_stp; + u4Wait = 0; + bRet = wmt_lib_put_act_op(lxop); + return bRet; +} + +#if CFG_WMT_LTE_COEX_HANDLING +MTK_WCN_BOOL wmt_lib_handle_idc_msg(conn_md_ipc_ilm_t *idc_infor) +{ + P_OSAL_OP lxop; + MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; + P_OSAL_SIGNAL pSignal; + INT32 ret = 0; + UINT16 msg_len = 0; + +#if CFG_WMT_LTE_ENABLE_MSGID_MAPPING + MTK_WCN_BOOL unknown_msgid = MTK_WCN_BOOL_FALSE; +#endif + WMT_DBG_FUNC("idc_infor from conn_md is 0x%p\n", idc_infor); + + ret = wmt_lib_idc_lock_aquire(); + if (ret) { + WMT_ERR_FUNC("--->lock idc_lock failed, ret=%d\n", ret); + return MTK_WCN_BOOL_FALSE; + } + msg_len = idc_infor->local_para_ptr->msg_len - osal_sizeof(struct local_para); + if (msg_len > WMT_IDC_MSG_MAX_SIZE) { + wmt_lib_idc_lock_release(); + WMT_ERR_FUNC("abnormal idc msg len:%d\n", msg_len); + return -2; + } + osal_memcpy(&gDevWmt.msg_local_buffer[0], &msg_len, osal_sizeof(msg_len)); + osal_memcpy(&gDevWmt.msg_local_buffer[osal_sizeof(msg_len)], + &(idc_infor->local_para_ptr->data[0]), msg_len - 1); + wmt_lib_idc_lock_release(); + + lxop = wmt_lib_get_free_op(); + if (!lxop) { + WMT_DBG_FUNC("get_free_lxop fail\n"); + return MTK_WCN_BOOL_FALSE; + } + pSignal = &lxop->signal; + pSignal->timeoutValue = MAX_EACH_WMT_CMD; + lxop->op.opId = WMT_OPID_IDC_MSG_HANDLING; + lxop->op.au4OpData[0] = (size_t) gDevWmt.msg_local_buffer; + + /*msg opcode fill rule is still not clrear,need scott comment */ + /***********************************************************/ + WMT_DBG_FUNC("ilm msg id is (0x%08x)\n", idc_infor->msg_id); + +#if CFG_WMT_LTE_ENABLE_MSGID_MAPPING + switch (idc_infor->msg_id) { + case IPC_MSG_ID_EL1_LTE_DEFAULT_PARAM_IND: + lxop->op.au4OpData[1] = WMT_IDC_TX_OPCODE_LTE_PARA; + break; + case IPC_MSG_ID_EL1_LTE_OPER_FREQ_PARAM_IND: + lxop->op.au4OpData[1] = WMT_IDC_TX_OPCODE_LTE_FREQ; + break; + case IPC_MSG_ID_EL1_WIFI_MAX_PWR_IND: + lxop->op.au4OpData[1] = WMT_IDC_TX_OPCODE_WIFI_MAX_POWER; + break; + case IPC_MSG_ID_EL1_LTE_TX_IND: + lxop->op.au4OpData[1] = WMT_IDC_TX_OPCODE_LTE_INDICATION; + break; + case IPC_MSG_ID_EL1_LTE_CONNECTION_STATUS_IND: + lxop->op.au4OpData[1] = WMT_IDC_TX_OPCODE_LTE_CONNECTION_STAS; + break; + case IPC_MSG_ID_EL1_LTE_HW_INTERFACE_IND: + lxop->op.au4OpData[1] = WMT_IDC_TX_OPCODE_LTE_HW_IF_INDICATION; + break; + default: + unknown_msgid = MTK_WCN_BOOL_TRUE; + break; + } + if (unknown_msgid == MTK_WCN_BOOL_FALSE) { + /*wake up chip first */ + if (DISABLE_PSM_MONITOR()) { + WMT_ERR_FUNC("wake up failed\n"); + wmt_lib_put_op_to_free_queue(lxop); + return MTK_WCN_BOOL_FALSE; + } + + bRet = wmt_lib_put_act_op(lxop); + ENABLE_PSM_MONITOR(); + if (bRet == MTK_WCN_BOOL_FALSE) { + WMT_WARN_FUNC("WMT_OPID_IDC_MSG_HANDLING fail(%d)\n", bRet); + } else { + WMT_DBG_FUNC("OPID(%d) type(%zu) ok\n", + lxop->op.opId, lxop->op.au4OpData[1]); + } + } else { + bRet = MTK_WCN_BOOL_FALSE; + wmt_lib_put_op_to_free_queue(lxop); + WMT_ERR_FUNC("unknown msgid from LTE(%d)\n", idc_infor->msg_id); + } +#else + if ((idc_infor->msg_id >= IPC_EL1_MSG_ID_BEGIN) + && (idc_infor->msg_id <= IPC_EL1_MSG_ID_BEGIN + IPC_EL1_MSG_ID_RANGE)) { + lxop->op.au4OpData[1] = idc_infor->msg_id - IPC_EL1_MSG_ID_BEGIN + LTE_MSG_ID_OFFSET - 1; + + /*wake up chip first */ + if (DISABLE_PSM_MONITOR()) { + WMT_ERR_FUNC("wake up failed\n"); + wmt_lib_put_op_to_free_queue(lxop); + return MTK_WCN_BOOL_FALSE; + } + + bRet = wmt_lib_put_act_op(lxop); + ENABLE_PSM_MONITOR(); + if (bRet == MTK_WCN_BOOL_FALSE) { + WMT_WARN_FUNC("WMT_OPID_IDC_MSG_HANDLING fail(%d)\n", bRet); + } else { + WMT_DBG_FUNC("wmt_lib_handle_idc_msg OPID(%d) type(%zu) ok\n", + lxop->op.opId, lxop->op.au4OpData[1]); + } + } else { + wmt_lib_put_op_to_free_queue(lxop); + WMT_ERR_FUNC("msgid(%d) out of range,wmt drop it!\n", idc_infor->msg_id); + } + +#endif + return bRet; +} +#endif + +static MTK_WCN_BOOL wmt_lib_ps_do_sleep(VOID) +{ + return wmt_lib_ps_action(SLEEP); +} + +static MTK_WCN_BOOL wmt_lib_ps_do_wakeup(VOID) +{ + return wmt_lib_ps_action(WAKEUP); +} + +static MTK_WCN_BOOL wmt_lib_ps_do_host_awake(VOID) +{ + return wmt_lib_ps_action(HOST_AWAKE); +} + +/* extern int g_block_tx; */ +static INT32 wmt_lib_ps_handler(MTKSTP_PSM_ACTION_T action) +{ + INT32 ret; + MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; + static DEFINE_RATELIMIT_STATE(_rs, 2 * HZ, 1); + + ret = 0; /* TODO:[FixMe][George] initial value or compile warning? */ + /* if(g_block_tx && (action == SLEEP)) */ + if ((mtk_wcn_stp_coredump_start_get() != 0) && (action == SLEEP)) { + ret = mtk_wcn_stp_psm_notify_stp(SLEEP); + return ret; + } + + /*MT662x Not Ready */ + if (!mtk_wcn_stp_is_ready()) { + if (!mtk_wcn_stp_is_sdio_mode()) { + WMT_DBG_FUNC("MT662x Not Ready, Dont Send Sleep/Wakeup Command\n"); + ret = mtk_wcn_stp_psm_notify_stp(ROLL_BACK); + } else { + WMT_DBG_FUNC("MT662x Not Ready, SDIO mode, skip EIRQ"); + } + return ret; + } + + if (action == SLEEP) { + WMT_DBG_FUNC("send op--------------------------------> sleep job\n"); + + if (!mtk_wcn_stp_is_sdio_mode()) { + bRet = wmt_lib_ps_do_sleep(); + ret = bRet ? 0 : -1; + WMT_DBG_FUNC("enable host eirq\n"); + wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_EN); +#if CFG_WMT_DUMP_INT_STATUS + if (wmt_plat_dump_BGF_irq_status() == MTK_WCN_BOOL_TRUE) + wmt_plat_BGF_irq_dump_status(); +#endif + } else { + /* ret = mtk_wcn_stp_sdio_do_own_set(); */ + if (sdio_own_ctrl) { + ret = (*sdio_own_ctrl) (OWN_SET); + mtk_wcn_stp_dbg_pkt_log(8, PKT_DIR_TX); + } else { + WMT_ERR_FUNC("sdio_own_ctrl is not registered\n"); + ret = -1; + } + + if (!ret) { + mtk_wcn_stp_psm_notify_stp(SLEEP); + } else if (ret == -2) { + mtk_wcn_stp_psm_notify_stp(ROLL_BACK); + WMT_WARN_FUNC + ("========[SDIO-PS] rollback due to tx busy ========%%\n"); + } else { + mtk_wcn_stp_psm_notify_stp(SLEEP); + WMT_ERR_FUNC + ("========[SDIO-PS] set own fails! ========%%\n"); + } + } + + WMT_DBG_FUNC("send op<--------------------------------- sleep job\n"); + } else if (action == WAKEUP) { + WMT_DBG_FUNC("send op --------------------------------> wake job\n"); + + if (!mtk_wcn_stp_is_sdio_mode()) { + WMT_DBG_FUNC("disable host eirq\n"); +#if CFG_WMT_DUMP_INT_STATUS + if (wmt_plat_dump_BGF_irq_status() == MTK_WCN_BOOL_TRUE) + wmt_plat_BGF_irq_dump_status(); +#endif + wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS); + bRet = wmt_lib_ps_do_wakeup(); + ret = bRet ? 0 : -1; + } else { + /* ret = mtk_wcn_stp_sdio_do_own_clr(); */ + + if (sdio_own_ctrl) { + ret = (*sdio_own_ctrl) (OWN_CLR); + } else { + WMT_ERR_FUNC("sdio_own_ctrl is not registered\n"); + ret = -1; + } + + if (!ret) { + mtk_wcn_stp_psm_notify_stp(WAKEUP); + } else { + mtk_wcn_stp_psm_notify_stp(WAKEUP); + WMT_ERR_FUNC + ("========[SDIO-PS] set own back fails! ========%%\n"); + } + } + + WMT_DBG_FUNC("send op<--------------------------------- wake job\n"); + } else if (action == HOST_AWAKE) { + WMT_DBG_FUNC("send op --------------------------------> host awake job\n"); + + if (!mtk_wcn_stp_is_sdio_mode()) { + WMT_DBG_FUNC("disable host eirq\n"); + /* IRQ already disabled */ + /* wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS); */ +#if 0 + if (wmt_plat_dump_BGF_irq_status() == MTK_WCN_BOOL_TRUE) + wmt_plat_BGF_irq_dump_status(); +#endif + bRet = wmt_lib_ps_do_host_awake(); + ret = bRet ? 0 : -1; + } else { + WMT_DBG_FUNC("[SDIO-PS] SDIO host awake! ####\n"); + + /* ret = mtk_wcn_stp_sdio_do_own_clr(); */ + + if (sdio_own_ctrl) { + ret = (*sdio_own_ctrl) (OWN_CLR); + } else { + WMT_ERR_FUNC("sdio_own_ctrl is not registered\n"); + ret = -1; + } + + mtk_wcn_stp_psm_notify_stp(HOST_AWAKE); + } + + WMT_DBG_FUNC("send op<--------------------------------- host awake job\n"); + } else if (action == EIRQ) { + WMT_DBG_FUNC("send op --------------------------------> eirq job\n"); + + if (!mtk_wcn_stp_is_sdio_mode()) { + if (__ratelimit(&_rs)) + pr_info("conn2ap_btif0_wakeup_out_b EIRQ handler\n"); + WMT_DBG_FUNC("disable host eirq\n"); + /* Disable interrupt */ + /*wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS);*/ + ret = mtk_wcn_stp_psm_notify_stp(EIRQ); + } else { + WMT_DBG_FUNC("[SDIO-PS]sdio own-back eirq!######\n"); + ret = mtk_wcn_stp_psm_notify_stp(EIRQ); + } + + WMT_DBG_FUNC("send op<--------------------------------- eirq job\n"); + } + + return ret; +} +#endif /* end of CFG_WMT_PS_SUPPORT */ + +INT32 wmt_lib_ps_stp_cb(MTKSTP_PSM_ACTION_T action) +{ +#if CFG_WMT_PS_SUPPORT + return wmt_lib_ps_handler(action); +#else + WMT_WARN_FUNC("CFG_WMT_PS_SUPPORT is not set\n"); + return 0; +#endif +} + +VOID wmt_lib_set_bt_link_status(INT32 type, INT32 value) +{ + WMT_INFO_FUNC("t = %d, v = %d, no_acl = %d, no_br = %d\n", + type, value, g_bt_no_acl_link, g_bt_no_br_acl_link); + + if (type == 0) + g_bt_no_acl_link = value; + else if (type == 1) + g_bt_no_br_acl_link = value; +} + +/* + * Allow BT to reset as long as one of the conditions is true. + * 1. no ACL link + * 2. no BR ACL link at 2 AM + */ +static INT32 wmt_lib_is_bt_able_to_reset(VOID) +{ + if (g_bt_no_acl_link) + return 1; + else if (g_bt_no_br_acl_link) { + struct timeval time; + ULONG local_time; + struct rtc_time tm; + + osal_do_gettimeofday(&time); + local_time = (ULONG)(time.tv_sec - (sys_tz.tz_minuteswest * 60)); + rtc_time_to_tm(local_time, &tm); + if (tm.tm_hour == 2) + return 1; + } + return 0; +} + +INT32 wmt_lib_update_fw_patch_chip_rst(VOID) +{ + MTK_WCN_BOOL wifiDrvOwn = MTK_WCN_BOOL_FALSE; + + if (g_fw_patch_update_rst == 0) + return 0; + + if (chip_reset_only == 1) + return 0; + + if (time_before_eq64(get_jiffies_64(), fw_patch_rst_time)) + return 0; + + if (wmt_lib_get_drv_status(WMTDRV_TYPE_WIFI) == DRV_STS_FUNC_ON) { + if (wmt_lib_wlan_lock_trylock() == 0) + return 0; + + if (mtk_wcn_wlan_is_wifi_drv_own != NULL) + wifiDrvOwn = ((*mtk_wcn_wlan_is_wifi_drv_own)() == 0) ? MTK_WCN_BOOL_FALSE : MTK_WCN_BOOL_TRUE; + + wmt_lib_wlan_lock_release(); + } + + if (wmt_lib_get_drv_status(WMTDRV_TYPE_BT) == DRV_STS_FUNC_ON && + wmt_lib_is_bt_able_to_reset() == 0) + return 0; + + if (wmt_dev_get_early_suspend_state() == MTK_WCN_BOOL_FALSE + || wmt_lib_get_drv_status(WMTDRV_TYPE_FM) == DRV_STS_FUNC_ON + || mtk_wcn_stp_is_ready() == MTK_WCN_BOOL_FALSE + || wifiDrvOwn == MTK_WCN_BOOL_TRUE) + return 0; + + if (wmt_lib_psm_lock_trylock() == 0) + return 0; + wmt_lib_psm_lock_release(); + + wmt_lib_fw_patch_update_rst_ctrl(0); + chip_reset_only = 1; + fw_patch_rst_time = get_jiffies_64() + (FW_PATCH_UPDATE_RST_DURATION * HZ); + WMT_INFO_FUNC("Invoke whole chip reset from fw patch update!!!\n"); + return wmt_lib_trigger_reset(); +} + +MTK_WCN_BOOL wmt_lib_is_quick_ps_support(VOID) +{ + if ((g_quick_sleep_ctrl) && (wmt_dev_get_early_suspend_state() == MTK_WCN_BOOL_TRUE)) + return wmt_core_is_quick_ps_support(); + else + return MTK_WCN_BOOL_FALSE; +} + +VOID wmt_lib_ps_irq_cb(VOID) +{ +#if CFG_WMT_PS_SUPPORT + wmt_lib_ps_handler(EIRQ); +#else + WMT_DBG_FUNC("CFG_WMT_PS_SUPPORT is not set\n"); + return; +#endif +} + +VOID wmt_lib_ps_set_sdio_psop(PF_WMT_SDIO_PSOP own_cb) +{ +#if CFG_WMT_PS_SUPPORT + sdio_own_ctrl = own_cb; +#endif +} + +#ifdef CONFIG_MTK_COMBO_CHIP_DEEP_SLEEP_SUPPORT +VOID wmt_lib_sdio_deep_sleep_flag_set_cb_reg(PF_WMT_SDIO_DEEP_SLEEP flag_cb) +{ + sdio_deep_sleep_flag_set = flag_cb; +} +#endif + +VOID wmt_lib_sdio_reg_rw_cb(PF_WMT_SDIO_DEBUG reg_rw_cb) +{ + sdio_reg_rw = reg_rw_cb; +} + +UINT32 wmt_lib_wait_event_checker(P_OSAL_THREAD pThread) +{ + P_DEV_WMT pDevWmt; + + if (pThread) { + pDevWmt = (P_DEV_WMT) (pThread->pThreadData); + return !RB_EMPTY(&pDevWmt->rActiveOpQ); + } + WMT_ERR_FUNC("pThread(NULL)\n"); + return 0; +} + +UINT32 wmt_lib_worker_wait_event_checker(P_OSAL_THREAD pThread) +{ + P_DEV_WMT pDevWmt; + + if (pThread) { + pDevWmt = (P_DEV_WMT) (pThread->pThreadData); + return !RB_EMPTY(&pDevWmt->rWorkerOpQ); + } + WMT_ERR_FUNC("pThread(NULL)\n"); + return 0; +} + +static INT32 wmtd_thread(void *pvData) +{ + P_DEV_WMT pWmtDev = (P_DEV_WMT) pvData; + P_OSAL_EVENT pEvent = NULL; + P_OSAL_OP pOp; + INT32 iResult; + + if (pWmtDev == NULL) { + WMT_ERR_FUNC("pWmtDev(NULL)\n"); + return -1; + } + WMT_INFO_FUNC("wmtd thread starts\n"); + + pEvent = &(pWmtDev->rWmtdWq); + + for (;;) { + pOp = NULL; + pEvent->timeoutValue = 0; +/* osal_thread_wait_for_event(&pWmtDev->thread, pEvent);*/ + osal_thread_wait_for_event(&pWmtDev->thread, pEvent, wmt_lib_wait_event_checker); + + if (osal_thread_should_stop(&pWmtDev->thread)) { + WMT_INFO_FUNC("wmtd thread should stop now...\n"); + /* TODO: clean up active opQ */ + break; + } + + /* get Op from activeQ */ + pOp = wmt_lib_get_op(&pWmtDev->rActiveOpQ); + if (!pOp) { + WMT_WARN_FUNC("get_lxop activeQ fail\n"); + continue; + } + + osal_op_history_save(&pWmtDev->wmtd_op_history, pOp); + +#if 0 /* wmt_core_opid_handler will do sanity check on opId, so no usage here */ + id = lxop_get_opid(pLxOp); + if (id >= WMT_OPID_MAX) { + WMT_WARN_FUNC("abnormal opid id: 0x%x\n", id); + iResult = -1; + goto handlerDone; + } +#endif + + if (osal_test_bit(WMT_STAT_RST_ON, &pWmtDev->state)) { + /* when whole chip reset, only HW RST and SW RST cmd can execute */ + if ((pOp->op.opId == WMT_OPID_HW_RST) + || (pOp->op.opId == WMT_OPID_SW_RST) + || (pOp->op.opId == WMT_OPID_GPIO_STATE) + || (pOp->op.opId == WMT_OPID_GET_CONSYS_STATE)) { + iResult = wmt_core_opid(&pOp->op); + } else { + iResult = -2; + WMT_WARN_FUNC + ("Whole chip resetting, opid (0x%x) failed, iRet(%d)\n", + pOp->op.opId, iResult); + } + } else { + wmt_lib_set_current_op(pWmtDev, pOp); + iResult = wmt_core_opid(&pOp->op); + wmt_lib_set_current_op(pWmtDev, NULL); + } + + if (iResult) + WMT_WARN_FUNC("opid (0x%x) failed, iRet(%d)\n", pOp->op.opId, iResult); + + if (iResult == 0 && + (pOp->op.opId == WMT_OPID_WLAN_PROBE || pOp->op.opId == WMT_OPID_WLAN_REMOVE)) + continue; + + if (atomic_dec_and_test(&pOp->ref_count)) { + wmt_lib_put_op(&pWmtDev->rFreeOpQ, pOp); + } else if (osal_op_is_wait_for_signal(pOp)) { + osal_op_raise_signal(pOp, iResult); + } + + if (pOp->op.opId == WMT_OPID_EXIT) { + WMT_INFO_FUNC("wmtd thread received exit signal\n"); + break; + } + } + + WMT_INFO_FUNC("wmtd thread exits succeed\n"); + + return 0; +}; + +static INT32 met_thread(void *pvData) +{ + P_DEV_WMT p_wmtdev = (P_DEV_WMT) pvData; + INT32 log_ctrl; + UINT32 read_ptr = 0; + UINT32 write_ptr = 0; + UINT32 emi_met_size = 0; + UINT32 emi_met_offset = 0; + P_CONSYS_EMI_ADDR_INFO emi_info; + PUINT8 emi_met_base = NULL; + PINT32 met_dump_buf = 0; + UINT32 met_buf_offset = 0; + UINT32 value = 0; + + if (p_wmtdev == NULL) { + WMT_ERR_FUNC("pWmtDev(NULL)\n"); + return -1; + } + + WMT_INFO_FUNC("met thread starts\n"); + + emi_info = mtk_wcn_consys_soc_get_emi_phy_add(); + if (!emi_info) { + WMT_ERR_FUNC("get EMI info failed.\n"); + return -1; + } + + emi_met_size = emi_info->emi_met_size; + if (!emi_met_size) { + WMT_ERR_FUNC("get met emi size fail\n"); + return -1; + } + + emi_met_offset = emi_info->emi_met_data_offset; + if (!emi_met_offset) { + WMT_ERR_FUNC("get met emi offset fail\n"); + return -1; + } + + met_dump_buf = osal_malloc(MET_DUMP_SIZE); + if (!met_dump_buf) { + WMT_ERR_FUNC("alloc dump buffer fail\n"); + return -1; + } + osal_memset(met_dump_buf, 0, MET_DUMP_SIZE); + + emi_met_base = ioremap_nocache(emi_info->emi_ap_phy_addr + emi_met_offset, emi_met_size); + if (!emi_met_base) { + osal_free(met_dump_buf); + WMT_ERR_FUNC("met emi ioremap fail\n"); + return -1; + } + + WMT_INFO_FUNC("emi phy base:%x, emi vir base:%p, met offset:%x, size:%x\n", + emi_info->emi_ap_phy_addr, + emi_met_base, + emi_met_offset, + emi_met_size); + + + log_ctrl = p_wmtdev->met_log_ctrl; + if (log_ctrl) + osal_ftrace_print_ctrl(1); + + for (;;) { + if (osal_thread_should_stop(&p_wmtdev->met_thread)) { + WMT_INFO_FUNC("met thread should stop now...\n"); + goto met_exit; + } + + read_ptr = CONSYS_REG_READ(emi_met_base + EMI_MET_READ_OFFSET); + write_ptr = CONSYS_REG_READ(emi_met_base + EMI_MET_WRITE_OFFSET); + + if (read_ptr == write_ptr) + WMT_DBG_FUNC("read_ptr(0x%x) == write_ptr(0x%x) no met data need dump!!!\n", + read_ptr, write_ptr); + else if (write_ptr > (emi_met_size - EMI_MET_DATA_OFFSET)) { + WMT_ERR_FUNC("write_ptr(0x%x) overflow!!!\n", write_ptr); + wmt_lib_trigger_assert(WMTDRV_TYPE_WMT, 42); + goto met_exit; + } else { + if (read_ptr > write_ptr) { + for (; read_ptr < emi_met_size; read_ptr += 0x4) { + value = CONSYS_REG_READ(emi_met_base + EMI_MET_DATA_OFFSET + read_ptr); + met_dump_buf[met_buf_offset] = value; + met_buf_offset++; + if (met_buf_offset >= MET_DUMP_MAX_NUM) { + met_buf_offset = 0; + osal_buffer_dump_data(met_dump_buf, "MCU_MET_DATA:", + MET_DUMP_MAX_NUM, MET_DUMP_MAX_NUM, + log_ctrl); + } + } + read_ptr = 0; + } + + for (; read_ptr < write_ptr; read_ptr += 0x4) { + value = CONSYS_REG_READ(emi_met_base + EMI_MET_DATA_OFFSET + read_ptr); + met_dump_buf[met_buf_offset] = value; + met_buf_offset++; + if (met_buf_offset >= MET_DUMP_MAX_NUM) { + met_buf_offset = 0; + osal_buffer_dump_data(met_dump_buf, "MCU_MET_DATA:", MET_DUMP_MAX_NUM, + MET_DUMP_MAX_NUM, + log_ctrl); + } + } + CONSYS_REG_WRITE(emi_met_base, read_ptr); + } + osal_usleep_range(CONSYS_MET_WAIT, CONSYS_MET_WAIT); + } + +met_exit: + osal_free(met_dump_buf); + iounmap(emi_met_base); + WMT_INFO_FUNC("met thread exits succeed\n"); + + return 0; +}; + +static VOID wmt_lib_wmtd_worker_thread_timeout_handler(timer_handler_arg arg) +{ + schedule_work(&gDevWmt.wmtd_worker_thread_work); +} + +static VOID wmt_lib_wmtd_worker_thread_work_handler(struct work_struct *work) +{ + PUINT8 pbuf = NULL; + INT32 len = 0; + P_OSAL_OP pOp; + + pOp = wmt_lib_get_worker_op(&gDevWmt); + if (pOp) { + switch (pOp->op.opId) { + case WMT_OPID_WLAN_PROBE: + pbuf = "DrvWMT turn on wifi fail, just collect SYS_FTRACE to DB"; + len = osal_strlen(pbuf); + break; + case WMT_OPID_WLAN_REMOVE: + pbuf = "DrvWMT turn off wifi fail, just collect SYS_FTRACE to DB"; + len = osal_strlen(pbuf); + break; + default: + pbuf = "DrvWMT unknown op fail, just collect SYS_FTRACE to DB"; + len = osal_strlen(pbuf); + break; + } + wmt_lib_trigger_assert_keyword(WMTDRV_TYPE_WIFI, 0, pbuf); + } +} + +static INT32 wmtd_worker_thread(void *pvData) +{ + P_DEV_WMT pWmtDev = (P_DEV_WMT) pvData; + P_OSAL_EVENT pEvent = NULL; + P_OSAL_OP pOp; + INT32 iResult = 0; + + pEvent = &(pWmtDev->rWmtdWorkerWq); + + for (;;) { + osal_thread_wait_for_event(&pWmtDev->worker_thread, pEvent, wmt_lib_worker_wait_event_checker); + + if (osal_thread_should_stop(&pWmtDev->worker_thread)) { + WMT_INFO_FUNC("wmtd worker thread should stop now...\n"); + /* TODO: clean up active opQ */ + break; + } + + /* get Op from activeWorkerQ */ + pOp = wmt_lib_get_op(&pWmtDev->rWorkerOpQ); + if (!pOp) { + WMT_WARN_FUNC("get activeWorkerQ fail\n"); + continue; + } + osal_op_history_save(&pWmtDev->worker_op_history, pOp); + + if (osal_test_bit(WMT_STAT_RST_ON, &pWmtDev->state)) { + iResult = -2; + WMT_WARN_FUNC("Whole chip resetting, opid (0x%x) failed, iRet(%d)\n", pOp->op.opId, iResult); + } else { + WMT_WARN_FUNC("opid: 0x%x", pOp->op.opId); + wmt_lib_set_worker_op(pWmtDev, pOp); + osal_timer_start(&gDevWmt.worker_timer, MAX_FUNC_ON_TIME); + iResult = wmt_core_opid(&pOp->op); + osal_timer_stop(&gDevWmt.worker_timer); + wmt_lib_set_worker_op(pWmtDev, NULL); + } + + if (iResult) + WMT_WARN_FUNC("opid (0x%x) failed, iRet(%d)\n", pOp->op.opId, iResult); + + if (atomic_dec_and_test(&pOp->ref_count)) + wmt_lib_put_op(&pWmtDev->rFreeOpQ, pOp); + else if (osal_op_is_wait_for_signal(pOp)) + osal_op_raise_signal(pOp, iResult); + } + + return 0; +} + +static MTK_WCN_BOOL wmt_lib_put_op(P_OSAL_OP_Q pOpQ, P_OSAL_OP pOp) +{ + INT32 iRet; + + if (!pOpQ || !pOp) { + WMT_WARN_FUNC("invalid input param: pOpQ(0x%p), pLxOp(0x%p)\n", pOpQ, pOp); + osal_assert(pOpQ); + osal_assert(pOp); + return MTK_WCN_BOOL_FALSE; + } + + iRet = osal_lock_sleepable_lock(&pOpQ->sLock); + if (iRet) { + WMT_WARN_FUNC("osal_lock_sleepable_lock iRet(%d)\n", iRet); + return MTK_WCN_BOOL_FALSE; + } + +#if defined(CONFIG_MTK_ENG_BUILD) || defined(CONFIG_MT_ENG_BUILD) + if (osal_opq_has_op(pOpQ, pOp)) { + WMT_ERR_FUNC("Op(%p) already exists in queue(%p)\n", pOp, pOpQ); + iRet = -2; + } +#endif + + /* acquire lock success */ + if (!RB_FULL(pOpQ)) + RB_PUT(pOpQ, pOp); + else { + WMT_WARN_FUNC("RB_FULL(%p -> %p)\n", pOp, pOpQ); + iRet = -1; + } + + osal_unlock_sleepable_lock(&pOpQ->sLock); + + if (iRet) { + osal_opq_dump("FreeOpQ", &gDevWmt.rFreeOpQ); + osal_opq_dump("ActiveOpQ", &gDevWmt.rActiveOpQ); + return MTK_WCN_BOOL_FALSE; + } + return MTK_WCN_BOOL_TRUE; +} + + + +static P_OSAL_OP wmt_lib_get_op(P_OSAL_OP_Q pOpQ) +{ + P_OSAL_OP pOp; + INT32 iRet; + + if (pOpQ == NULL) { + WMT_ERR_FUNC("pOpQ = NULL\n"); + osal_assert(pOpQ); + return NULL; + } + + iRet = osal_lock_sleepable_lock(&pOpQ->sLock); + if (iRet) { + WMT_ERR_FUNC("osal_lock_sleepable_lock iRet(%d)\n", iRet); + return NULL; + } + + /* acquire lock success */ + RB_GET(pOpQ, pOp); + osal_unlock_sleepable_lock(&pOpQ->sLock); + + if (pOp == NULL) { + P_OSAL_OP pCurOp = wmt_lib_get_current_op(&gDevWmt); + + WMT_WARN_FUNC("RB_GET(%p) return NULL\n", pOpQ); + if (pCurOp != NULL) + WMT_WARN_FUNC("Current opId (%d)\n", pCurOp->op.opId); + + wmt_lib_print_wmtd_op_history(); + wmt_lib_print_worker_op_history(); + osal_opq_dump("FreeOpQ", &gDevWmt.rFreeOpQ); + osal_opq_dump("ActiveOpQ", &gDevWmt.rActiveOpQ); + osal_assert(pOp); + } + + return pOp; +} + + +INT32 wmt_lib_put_op_to_free_queue(P_OSAL_OP pOp) +{ + P_DEV_WMT pWmtDev = &gDevWmt; + + if (wmt_lib_put_op(&pWmtDev->rFreeOpQ, pOp) == MTK_WCN_BOOL_FALSE) + return -1; + + return 0; +} + + +P_OSAL_OP wmt_lib_get_free_op(VOID) +{ + P_OSAL_OP pOp = NULL; + P_DEV_WMT pDevWmt = &gDevWmt; + + osal_assert(pDevWmt); + pOp = wmt_lib_get_op(&pDevWmt->rFreeOpQ); + if (pOp) { + osal_memset(pOp, 0, osal_sizeof(OSAL_OP)); + } + return pOp; +} + +MTK_WCN_BOOL wmt_lib_put_act_op(P_OSAL_OP pOp) +{ + P_DEV_WMT pWmtDev = &gDevWmt; + MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; + P_OSAL_SIGNAL pSignal = NULL; + INT32 waitRet = -1; + + osal_assert(pWmtDev); + osal_assert(pOp); + + do { + if (!pWmtDev || !pOp) { + WMT_ERR_FUNC("pWmtDev(0x%p), pOp(0x%p)\n", pWmtDev, pOp); + break; + } + + /* Init ref_count to 1 indicating that current thread holds a ref to it */ + atomic_set(&pOp->ref_count, 1); + + if ((mtk_wcn_stp_coredump_start_get() != 0) && + (pOp->op.opId != WMT_OPID_HW_RST) && + (pOp->op.opId != WMT_OPID_SW_RST) && (pOp->op.opId != WMT_OPID_GPIO_STATE)) { + WMT_WARN_FUNC("block tx flag is set\n"); + break; + } + pSignal = &pOp->signal; +/* pOp->u4WaitMs = u4WaitMs; */ + if (pSignal->timeoutValue) { + pOp->result = -9; + osal_signal_init(pSignal); + } + + /* Increment ref_count by 1 as wmtd thread will hold a reference also, + * this must be done here instead of on target thread, because + * target thread might not be scheduled until a much later time, + * allowing current thread to decrement ref_count at the end of function, + * putting op back to free queue before target thread has a chance to process. + */ + atomic_inc(&pOp->ref_count); + + /* put to active Q */ + bRet = wmt_lib_put_op(&pWmtDev->rActiveOpQ, pOp); + if (bRet == MTK_WCN_BOOL_FALSE) { + WMT_WARN_FUNC("put to active queue fail\n"); + atomic_dec(&pOp->ref_count); + break; + } + + /* wake up wmtd */ + /* wake_up_interruptible(&pWmtDev->rWmtdWq); */ + osal_trigger_event(&pWmtDev->rWmtdWq); + + if (pSignal->timeoutValue == 0) { + bRet = MTK_WCN_BOOL_TRUE; + /* clean it in wmtd */ + break; + } + + /* check result */ + /* wait_ret = wait_for_completion_interruptible_timeout(&pOp->comp, msecs_to_jiffies(u4WaitMs)); */ + /* wait_ret = wait_for_completion_timeout(&pOp->comp, msecs_to_jiffies(u4WaitMs)); */ + if (pOp->op.opId == WMT_OPID_FUNC_ON && + pOp->op.au4OpData[0] == WMTDRV_TYPE_WIFI) + waitRet = osal_wait_for_signal_timeout(pSignal, &pWmtDev->worker_thread); + else + waitRet = osal_wait_for_signal_timeout(pSignal, &pWmtDev->thread); + WMT_DBG_FUNC("osal_wait_for_signal_timeout:%d\n", waitRet); + + /* if (unlikely(!wait_ret)) { */ + if (waitRet == 0) + WMT_ERR_FUNC("opId(%d) completion timeout\n", pOp->op.opId); + else if (pOp->result) + WMT_WARN_FUNC("opId(%d) result:%d\n", pOp->op.opId, pOp->result); + + /* op completes, check result */ + bRet = (pOp->result) ? MTK_WCN_BOOL_FALSE : MTK_WCN_BOOL_TRUE; + } while (0); + + if (pOp && atomic_dec_and_test(&pOp->ref_count)) { + /* put Op back to freeQ */ + wmt_lib_put_op(&pWmtDev->rFreeOpQ, pOp); + } + + return bRet; +} + +MTK_WCN_BOOL wmt_lib_put_worker_op(P_OSAL_OP pOp) +{ + P_DEV_WMT pWmtDev = &gDevWmt; + MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; + + osal_assert(pWmtDev); + osal_assert(pOp); + + do { + if (!pWmtDev || !pOp) { + WMT_ERR_FUNC("pWmtDev(0x%p), pOp(0x%p)\n", pWmtDev, pOp); + break; + } + + /* put to activeWorker Q */ + bRet = wmt_lib_put_op(&pWmtDev->rWorkerOpQ, pOp); + if (bRet == MTK_WCN_BOOL_FALSE) { + WMT_WARN_FUNC("put to ActiveWorker queue fail\n"); + break; + } + + /* wake up wmtd_worker */ + osal_trigger_event(&pWmtDev->rWmtdWorkerWq); + } while (0); + + return bRet; +} + +/* TODO:[ChangeFeature][George] is this function obsoleted? */ +#if 0 +INT32 wmt_lib_reg_rw(UINT32 isWrite, UINT32 offset, PUINT32 pvalue, UINT32 mask) +{ + P_WMT_LXOP lxop; + MTK_WCN_BOOL bRet; + PUINT32 plv = NULL; + UINT32 pbuf[2]; + P_OSAL_EVENT pSignal = NULL; + + if (!pvalue) { + WMT_WARN_FUNC("!pvalue\n"); + return -1; + } + lxop = wmt_lib_get_free_lxop(); + if (!lxop) { + WMT_DBG_FUNC("get_free_lxop fail\n"); + + return -1; + } + + plv = (PUINT32) (((UINT32) pbuf + 0x3) & ~0x3UL); + *plv = *pvalue; + pSignal = &lxop->signal; + WMT_DBG_FUNC("OPID_REG_RW isWrite(%d) offset(0x%x) value(0x%x) mask(0x%x)\n", + isWrite, offset, *pvalue, mask); + + lxop->op.opId = WMT_OPID_REG_RW; + lxop->op.au4OpData[0] = isWrite; + lxop->op.au4OpData[1] = offset; + lxop->op.au4OpData[2] = (UINT32) plv; + lxop->op.au4OpData[3] = mask; + pSignal->timeoutValue = MAX_EACH_WMT_CMD; + + DISABLE_PSM_MONITOR(); + bRet = wmt_lib_put_act_lxop(lxop); + ENABLE_PSM_MONITOR(); + + if (bRet != MTK_WCN_BOOL_FALSE) { + WMT_DBG_FUNC("OPID_REG_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x) ok\n", + isWrite, offset, *plv, mask); + if (!isWrite) + *pvalue = *plv; + } else { + WMT_WARN_FUNC + ("OPID_REG_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x) bRet(%d)\n", + isWrite, offset, *plv, mask, bRet); + } + + return bRet; +} +#endif + +/* TODO:[ChangeFeature][George] is this function obsoleted? */ +#if 0 +static VOID wmt_lib_clear_chip_id(VOID) +{ +/* + * gDevWmt.pChipInfo = NULL; +*/ + gDevWmt.hw_ver = WMTHWVER_INVALID; +} +#endif + +UINT32 wmt_lib_get_icinfo(ENUM_WMT_CHIPINFO_TYPE_T index) +{ + UINT32 chip_id = 0; + + if (index == WMTCHIN_CHIPID) { + if (wmt_detect_get_chip_type() == WMT_CHIP_TYPE_COMBO) + chip_id = gDevWmt.chip_id; + else + chip_id = mtk_wcn_consys_soc_chipid(); + WMT_INFO_FUNC("chip_id=[%x]", chip_id); + return chip_id; + } else if (index == WMTCHIN_HWVER) + return gDevWmt.hw_ver; + else if (index == WMTCHIN_FWVER) + return gDevWmt.fw_ver; + else if (index == WMTCHIN_IPVER) + return gDevWmt.ip_ver; + else if (index == WMTCHIN_ADIE) + return mtk_wcn_consys_get_adie_chipid(); + + return 0; + +} + + +PUINT8 wmt_lib_def_patch_name(VOID) +{ + WMT_INFO_FUNC("wmt-lib: use default patch name (%s)\n", gDevWmt.cPatchName); + return gDevWmt.cPatchName; +} + + +MTK_WCN_BOOL wmt_lib_is_therm_ctrl_support(ENUM_WMTTHERM_TYPE_T eType) +{ + MTK_WCN_BOOL bIsSupportTherm = MTK_WCN_BOOL_TRUE; + /* TODO:[FixMe][GeorgeKuo]: move IC-dependent checking to ic-implementation file */ + if ((gDevWmt.chip_id == 0x6620) && (gDevWmt.hw_ver == 0x8A00 /*E1*/ || gDevWmt.hw_ver == 0x8A01 /*E2*/)) { + WMT_ERR_FUNC("thermal command fail: chip version(HWVER:0x%04x) is not valid\n", + gDevWmt.hw_ver); + bIsSupportTherm = MTK_WCN_BOOL_FALSE; + } + if ((!osal_test_bit(WMT_STAT_STP_EN, &gDevWmt.state)) + || (!osal_test_bit(WMT_STAT_STP_RDY, &gDevWmt.state))) { + if (eType == WMTTHERM_READ) + WMT_INFO_FUNC + ("thermal command can`t send: STP is not enable(%d) or ready(%d)\n", + osal_test_bit(WMT_STAT_STP_EN, &gDevWmt.state), + osal_test_bit(WMT_STAT_STP_RDY, &gDevWmt.state)); + bIsSupportTherm = MTK_WCN_BOOL_FALSE; + } + + return bIsSupportTherm; +} + +MTK_WCN_BOOL wmt_lib_is_dsns_ctrl_support(VOID) +{ + /* TODO:[FixMe][GeorgeKuo]: move IC-dependent checking to ic-implementation file */ + if ((gDevWmt.chip_id == 0x6620) && (gDevWmt.hw_ver == 0x8A00 /*E1*/ || gDevWmt.hw_ver == 0x8A01 /*E2*/)) { + WMT_ERR_FUNC("thermal command fail: chip version(HWVER:0x%04x) is not valid\n", + gDevWmt.hw_ver); + return MTK_WCN_BOOL_FALSE; + } + + return MTK_WCN_BOOL_TRUE; +} + + +/*! + * \brief Update combo chip pin settings (GPIO) + * + * An internal library function to support various settings for chip GPIO. It is + * updated in a grouping way: configure all required pins in a single call. + * + * \param id desired pin ID to be controlled + * \param stat desired pin states to be set + * \param flag supplementary options for this operation + * + * \retval 0 operation success + * \retval -1 invalid id + * \retval -2 invalid stat + * \retval < 0 error for operation fail + */ +static INT32 wmt_lib_pin_ctrl(WMT_IC_PIN_ID id, WMT_IC_PIN_STATE stat, UINT32 flag) +{ + P_OSAL_OP pOp; + MTK_WCN_BOOL bRet; + P_OSAL_SIGNAL pSignal; + + /* input sanity check */ + if (id >= WMT_IC_PIN_MAX) { + WMT_ERR_FUNC("invalid ic pin id(%d)\n", id); + return -1; + } + if (stat >= WMT_IC_PIN_STATE_MAX) { + WMT_ERR_FUNC("invalid ic pin state (%d)\n", stat); + return -2; + } + + pOp = wmt_lib_get_free_op(); + if (!pOp) { + WMT_DBG_FUNC("get_free_lxop fail\n"); + return MTK_WCN_BOOL_FALSE; + } + + WMT_DBG_FUNC("call WMT_OPID_GPIO_CTRL (ic pin id:%d, stat:%d, flag:0x%x)\n", id, stat, + flag); + + pSignal = &pOp->signal; + pOp->op.opId = WMT_OPID_GPIO_CTRL; + pOp->op.au4OpData[0] = id; + pOp->op.au4OpData[1] = stat; + pOp->op.au4OpData[2] = flag; + pSignal->timeoutValue = MAX_EACH_WMT_CMD; + + /*wake up chip first */ + if (DISABLE_PSM_MONITOR()) { + WMT_ERR_FUNC("wake up failed\n"); + wmt_lib_put_op_to_free_queue(pOp); + return -1; + } + + bRet = wmt_lib_put_act_op(pOp); + ENABLE_PSM_MONITOR(); + if (bRet == MTK_WCN_BOOL_FALSE) + WMT_WARN_FUNC("PIN_ID(%d) PIN_STATE(%d) flag(%d) fail\n", id, stat, flag); + else + WMT_DBG_FUNC("OPID(%d) type(%zu) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); + + return 0; +} + +INT32 wmt_lib_reg_rw(UINT32 isWrite, UINT32 offset, PUINT32 pvalue, UINT32 mask) +{ + P_OSAL_OP pOp; + MTK_WCN_BOOL bRet; + UINT32 value; + P_OSAL_SIGNAL pSignal; + + if (!pvalue) { + WMT_WARN_FUNC("!pvalue\n"); + return -1; + } + + pOp = wmt_lib_get_free_op(); + if (!pOp) { + WMT_DBG_FUNC("get_free_lxop fail\n"); + return -1; + } + + pSignal = &pOp->signal; + pSignal->timeoutValue = MAX_WMT_OP_TIMEOUT; + value = *pvalue; + WMT_DBG_FUNC("OPID_REG_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x)\n\n", + isWrite, offset, *pvalue, mask); + pOp->op.opId = WMT_OPID_REG_RW; + pOp->op.au4OpData[0] = isWrite; + pOp->op.au4OpData[1] = offset; + pOp->op.au4OpData[2] = (size_t) &value; + pOp->op.au4OpData[3] = mask; + if (DISABLE_PSM_MONITOR()) { + WMT_ERR_FUNC("wake up failed\n"); + wmt_lib_put_op_to_free_queue(pOp); + return -1; + } + + bRet = wmt_lib_put_act_op(pOp); + ENABLE_PSM_MONITOR(); + + if (bRet != MTK_WCN_BOOL_FALSE) { + WMT_DBG_FUNC("OPID_REG_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x) ok\n", + isWrite, offset, value, mask); + if (!isWrite) + *pvalue = value; + + return 0; + } + WMT_WARN_FUNC("OPID_REG_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x) bRet(%d)\n", + isWrite, offset, value, mask, bRet); + + return -1; +} + +INT32 wmt_lib_efuse_rw(UINT32 isWrite, UINT32 offset, PUINT32 pvalue, UINT32 mask) +{ + P_OSAL_OP pOp; + MTK_WCN_BOOL bRet; + UINT32 value; + P_OSAL_SIGNAL pSignal; + + if (!pvalue) { + WMT_WARN_FUNC("!pvalue\n"); + return -1; + } + + pOp = wmt_lib_get_free_op(); + if (!pOp) { + WMT_DBG_FUNC("get_free_lxop fail\n"); + return -1; + } + + pSignal = &pOp->signal; + pSignal->timeoutValue = MAX_WMT_OP_TIMEOUT; + value = *pvalue; + WMT_DBG_FUNC("OPID_EFUSE_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x)\n\n", + isWrite, offset, *pvalue, mask); + pOp->op.opId = WMT_OPID_EFUSE_RW; + pOp->op.au4OpData[0] = isWrite; + pOp->op.au4OpData[1] = offset; + pOp->op.au4OpData[2] = (size_t) &value; + pOp->op.au4OpData[3] = mask; + if (DISABLE_PSM_MONITOR()) { + WMT_ERR_FUNC("wake up failed\n"); + wmt_lib_put_op_to_free_queue(pOp); + return -1; + } + + bRet = wmt_lib_put_act_op(pOp); + ENABLE_PSM_MONITOR(); + + if (bRet != MTK_WCN_BOOL_FALSE) { + WMT_DBG_FUNC("OPID_EFUSE_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x) ok\n", + isWrite, offset, value, mask); + if (!isWrite) + *pvalue = value; + return 0; + } + WMT_WARN_FUNC("OPID_REG_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x) bRet(%d)\n", + isWrite, offset, value, mask, bRet); + return -1; +} + +INT32 wmt_lib_utc_time_sync(VOID) +{ + P_OSAL_OP pOp; + MTK_WCN_BOOL bRet; + P_OSAL_SIGNAL pSignal; + + pOp = wmt_lib_get_free_op(); + if (!pOp) { + WMT_WARN_FUNC("get_free_lxop fail\n"); + return -1; + } + + pSignal = &pOp->signal; + pSignal->timeoutValue = MAX_EACH_WMT_CMD; + pOp->op.opId = WMT_OPID_UTC_TIME_SYNC; + if (DISABLE_PSM_MONITOR()) { + WMT_ERR_FUNC("wake up failed\n"); + wmt_lib_put_op_to_free_queue(pOp); + return -2; + } + + bRet = wmt_lib_put_act_op(pOp); + ENABLE_PSM_MONITOR(); + if (bRet == MTK_WCN_BOOL_FALSE) { + WMT_WARN_FUNC("WMT_OPID_UTC_TIME_SYNC fail(%d)\n", bRet); + return -3; + } + WMT_DBG_FUNC("wmt_lib_utc_time_sync OPID(%d) ok\n", pOp->op.opId); + + return 0; +} + +INT32 wmt_lib_try_pwr_off(VOID) +{ + P_OSAL_OP pOp; + MTK_WCN_BOOL bRet; + P_OSAL_SIGNAL pSignal; + + pOp = wmt_lib_get_free_op(); + if (!pOp) { + WMT_WARN_FUNC("get_free_lxop fail\n"); + return -1; + } + + pSignal = &pOp->signal; + pSignal->timeoutValue = MAX_FUNC_OFF_TIME; + pOp->op.opId = WMT_OPID_TRY_PWR_OFF; + if (DISABLE_PSM_MONITOR()) { + WMT_ERR_FUNC("wake up failed\n"); + wmt_lib_put_op_to_free_queue(pOp); + return -2; + } + + bRet = wmt_lib_put_act_op(pOp); + ENABLE_PSM_MONITOR(); + if (bRet == MTK_WCN_BOOL_FALSE) { + WMT_WARN_FUNC("WMT_OPID_TRY_PWR_OFF fail(%d)\n", bRet); + return -2; + } + WMT_DBG_FUNC("wmt_lib_try_pwr_off OPID(%d) ok\n", pOp->op.opId); + + return 0; +} + +P_WMT_PATCH_INFO wmt_lib_get_patch_info(VOID) +{ + return gDevWmt.pWmtPatchInfo; +} + +/*! + * \brief update combo chip AUDIO Interface (AIF) settings + * + * A library function to support updating chip AUDIO pin settings. A group of + * pins is updated as a whole. + * + * \param aif desired audio interface state to use + * \param flag whether audio pin is shared or not + * + * \retval 0 operation success + * \retval -1 invalid aif + * \retval < 0 error for invalid parameters or operation fail + */ +INT32 wmt_lib_set_aif(enum CMB_STUB_AIF_X aif, MTK_WCN_BOOL share) +{ + if (aif < 0 || aif >= CMB_STUB_AIF_MAX) { + WMT_ERR_FUNC("invalid aif (%d)\n", aif); + return -1; + } + WMT_DBG_FUNC("call pin_ctrl for aif:%d, share:%d\n", aif, + (share == MTK_WCN_BOOL_TRUE) ? 1 : 0); + /* Translate enum CMB_STUB_AIF_X into WMT_IC_PIN_STATE by array */ + return wmt_lib_pin_ctrl(WMT_IC_PIN_AUDIO, + cmb_aif2pin_stat[aif], + (MTK_WCN_BOOL_TRUE == + share) ? WMT_LIB_AIF_FLAG_SHARE : WMT_LIB_AIF_FLAG_SEPARATE); +} + +INT32 wmt_lib_host_awake_get(VOID) +{ + return wmt_plat_wake_lock_ctrl(WL_OP_GET); +} + +INT32 wmt_lib_host_awake_put(VOID) +{ + return wmt_plat_wake_lock_ctrl(WL_OP_PUT); +} + +MTK_WCN_BOOL wmt_lib_btm_cb(MTKSTP_BTM_WMT_OP_T op) +{ + MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; + + if (op == BTM_RST_OP) { + /* high priority, not to enqueue into the queue of wmtd */ + WMT_INFO_FUNC("Invoke whole chip reset from stp_btm!!!\n"); + wmt_lib_cmb_rst(WMTRSTSRC_RESET_STP); + bRet = MTK_WCN_BOOL_TRUE; + } else if (op == BTM_DMP_OP) { + + WMT_WARN_FUNC("TBD!!!\n"); + } else if (op == BTM_GET_AEE_SUPPORT_FLAG) { + bRet = wmt_core_get_aee_dump_flag(); + } else if (op == BTM_TRIGGER_STP_ASSERT_OP) { + bRet = wmt_core_trigger_stp_assert(); + } + return bRet; +} + +MTK_WCN_BOOL wmt_cdev_rstmsg_snd(ENUM_WMTRSTMSG_TYPE_T msg) +{ + + INT32 i = 0; + P_DEV_WMT pDevWmt = &gDevWmt; + UINT8 *drv_name[] = { + "DRV_TYPE_BT", + "DRV_TYPE_FM", + "DRV_TYPE_GPS", + "DRV_TYPE_WIFI", + "DRV_TYPE_ANT", + "UNKNOWN" + }; + + for (i = 0; i <= WMTDRV_TYPE_ANT; i++) { + /* <1> check if reset callback is registered */ + if (pDevWmt->rFdrvCb.fDrvRst[i]) { + /* <2> send the msg to this subfucntion */ + /*src, dst, msg_type, msg_data, msg_size */ + pDevWmt->rFdrvCb.fDrvRst[i] (WMTDRV_TYPE_WMT, i, WMTMSG_TYPE_RESET, &msg, + sizeof(ENUM_WMTRSTMSG_TYPE_T)); + WMT_INFO_FUNC("type = %s, msg sent\n", drv_name[i]); + } else { + WMT_DBG_FUNC("type = %s, unregistered\n", drv_name[i]); + } + } + + return MTK_WCN_BOOL_TRUE; +} + +VOID wmt_lib_state_init(VOID) +{ + /* UINT32 i = 0; */ + P_DEV_WMT pDevWmt = &gDevWmt; + P_OSAL_OP pOp; + + /* Initialize op queue */ + /* RB_INIT(&pDevWmt->rFreeOpQ, WMT_OP_BUF_SIZE); */ + /* RB_INIT(&pDevWmt->rActiveOpQ, WMT_OP_BUF_SIZE); */ + + while (!RB_EMPTY(&pDevWmt->rActiveOpQ)) { + pOp = wmt_lib_get_op(&pDevWmt->rActiveOpQ); + if (pOp) { + if (atomic_dec_and_test(&pOp->ref_count)) + wmt_lib_put_op(&pDevWmt->rFreeOpQ, pOp); + else if (osal_op_is_wait_for_signal(pOp)) + osal_op_raise_signal(pOp, -1); + } + } +} + + +INT32 wmt_lib_sdio_ctrl(UINT32 on) +{ + + P_OSAL_OP pOp; + MTK_WCN_BOOL bRet; + P_OSAL_SIGNAL pSignal; + + pOp = wmt_lib_get_free_op(); + if (!pOp) { + WMT_DBG_FUNC("get_free_lxop fail\n"); + return MTK_WCN_BOOL_FALSE; + } + + WMT_DBG_FUNC("call WMT_OPID_SDIO_CTRL\n"); + + pSignal = &pOp->signal; + pOp->op.opId = WMT_OPID_SDIO_CTRL; + pOp->op.au4OpData[0] = on; + pSignal->timeoutValue = MAX_GPIO_CTRL_TIME; + + + bRet = wmt_lib_put_act_op(pOp); + if (bRet == MTK_WCN_BOOL_FALSE) { + WMT_WARN_FUNC("WMT_OPID_SDIO_CTRL failed\n"); + return -1; + } + WMT_DBG_FUNC("OPID(WMT_OPID_SDIO_CTRL)ok\n"); + return 0; +} + +MTK_WCN_BOOL wmt_lib_hw_state_show(VOID) +{ + P_OSAL_OP pOp; + MTK_WCN_BOOL bRet; + P_OSAL_SIGNAL pSignal; + + pOp = wmt_lib_get_free_op(); + if (!pOp) { + WMT_DBG_FUNC("get_free_lxop fail\n"); + return MTK_WCN_BOOL_FALSE; + } + + WMT_DBG_FUNC("call WMT_OPID_HW_STATE_SHOW\n"); + + pSignal = &pOp->signal; + pOp->op.opId = WMT_OPID_GPIO_STATE; + pSignal->timeoutValue = MAX_GPIO_CTRL_TIME; + + bRet = wmt_lib_put_act_op(pOp); + if (bRet == MTK_WCN_BOOL_FALSE) { + WMT_WARN_FUNC("WMT_OPID_HW_STATE_SHOW failed\n"); + return MTK_WCN_BOOL_FALSE; + } + WMT_DBG_FUNC("OPID(WMT_OPID_HW_STATE_SHOW)ok\n"); + + return MTK_WCN_BOOL_TRUE; +} + + +MTK_WCN_BOOL wmt_lib_hw_rst(VOID) +{ + + P_OSAL_OP pOp; + MTK_WCN_BOOL bRet; + P_OSAL_SIGNAL pSignal; + P_DEV_WMT pDevWmt = &gDevWmt; + + wmt_lib_state_init(); + + osal_clear_bit(WMT_STAT_STP_REG, &pDevWmt->state); + osal_clear_bit(WMT_STAT_STP_OPEN, &pDevWmt->state); + osal_clear_bit(WMT_STAT_STP_EN, &pDevWmt->state); + osal_clear_bit(WMT_STAT_STP_RDY, &pDevWmt->state); + osal_clear_bit(WMT_STAT_RX, &pDevWmt->state); + osal_clear_bit(WMT_STAT_CMD, &pDevWmt->state); + + /*Before do hardware reset, we show GPIO state to check if others modified our pin state accidentially */ + wmt_lib_hw_state_show(); + pOp = wmt_lib_get_free_op(); + if (!pOp) { + WMT_DBG_FUNC("get_free_lxop fail\n"); + return MTK_WCN_BOOL_FALSE; + } + + WMT_DBG_FUNC("call WMT_OPID_HW_RST\n"); + + pSignal = &pOp->signal; + pOp->op.opId = WMT_OPID_HW_RST; + pSignal->timeoutValue = MAX_GPIO_CTRL_TIME; + + + bRet = wmt_lib_put_act_op(pOp); + if (bRet == MTK_WCN_BOOL_FALSE) { + WMT_WARN_FUNC("WMT_OPID_HW_RST failed\n"); + return MTK_WCN_BOOL_FALSE; + } + WMT_DBG_FUNC("OPID(WMT_OPID_HW_RST)ok\n"); + + return MTK_WCN_BOOL_TRUE; +} + +MTK_WCN_BOOL wmt_lib_sw_rst(INT32 baudRst) +{ + + P_OSAL_OP pOp; + MTK_WCN_BOOL bRet; + P_OSAL_SIGNAL pSignal; + + /* <1> wmt state reset */ + wmt_lib_state_init(); + + /* <2> Reset STP data structure */ + WMT_DBG_FUNC("Cleanup STP context\n"); + mtk_wcn_stp_flush_context(); + stp_dbg_reset(); + + /* <3> Reset STP-PSM data structure */ + WMT_DBG_FUNC("Cleanup STP-PSM context\n"); + mtk_wcn_stp_psm_reset(); + + /* <4> do sw reset in wmt-core */ + pOp = wmt_lib_get_free_op(); + if (!pOp) { + WMT_WARN_FUNC("get_free_lxop fail\n"); + return MTK_WCN_BOOL_FALSE; + } + + WMT_DBG_FUNC("call WMT_OPID_SW_RST\n"); + + pSignal = &pOp->signal; + pSignal->timeoutValue = MAX_FUNC_ON_TIME; + + pOp->op.opId = WMT_OPID_SW_RST; + pOp->op.au4OpData[0] = baudRst; + + + + bRet = wmt_lib_put_act_op(pOp); + if (bRet == MTK_WCN_BOOL_FALSE) { + WMT_WARN_FUNC("WMT_OPID_SW_RST failed\n"); + return MTK_WCN_BOOL_FALSE; + } + WMT_DBG_FUNC("OPID(WMT_OPID_SW_RST)ok\n"); + + return MTK_WCN_BOOL_TRUE; +} + + +ENUM_WMTRSTRET_TYPE_T wmt_lib_cmb_rst(ENUM_WMTRSTSRC_TYPE_T src) +{ +#define RETRYTIMES 10 + MTK_WCN_BOOL bRet; + ENUM_WMTRSTRET_TYPE_T retval = WMTRSTRET_MAX; + ENUM_WMTRSTMSG_TYPE_T rstMsg = WMTRSTMSG_RESET_MAX; + INT32 retries = RETRYTIMES; + P_DEV_WMT pDevWmt = &gDevWmt; + P_OSAL_OP pOp; + UINT8 *srcName[] = { "WMTRSTSRC_RESET_BT", + "WMTRSTSRC_RESET_FM", + "WMTRSTSRC_RESET_GPS", + "WMTRSTSRC_RESET_WIFI", + "WMTRSTSRC_RESET_STP", + "WMTRSTSRC_RESET_TEST" + }; + INT32 coredump_mode = mtk_wcn_stp_coredump_flag_get(); + + WMT_INFO_FUNC("coredump mode == %d. Connsys coredump is %s.", + coredump_mode, coredump_mode ? "enabled" : "disabled"); + + if (src >= 0 && src < WMTRSTSRC_RESET_MAX) + WMT_INFO_FUNC("reset source = %s\n", srcName[src]); + + if (src == WMTRSTSRC_RESET_TEST) { + pOp = wmt_lib_get_current_op(pDevWmt); + if (pOp && ((pOp->op.opId == WMT_OPID_FUNC_ON) + || (pOp->op.opId == WMT_OPID_FUNC_OFF))) { + WMT_INFO_FUNC("can't do reset by test src when func on/off\n"); + return -1; + } + } + /* <1> Consider the multi-context combo_rst case. */ + if (osal_test_and_set_bit(WMT_STAT_RST_ON, &pDevWmt->state)) { + retval = WMTRSTRET_ONGOING; + goto rstDone; + } + /* <2> Block all STP request */ + if (wmt_lib_psm_lock_trylock() == 0) { + if (chip_reset_only == 1) { + wmt_lib_fw_patch_update_rst_ctrl(1); + fw_patch_rst_time = 0; + retval = WMTRSTRET_RETRY; + goto rstDone; + } + mtk_wcn_stp_enable(0); + } else { + mtk_wcn_stp_enable(0); + wmt_lib_psm_lock_release(); + } + + /* <3> RESET_START notification */ + bRet = wmt_cdev_rstmsg_snd(WMTRSTMSG_RESET_START); + if (bRet == MTK_WCN_BOOL_FALSE) { + WMT_ERR_FUNC("[whole chip reset] fail at wmt_lib_rstmsg_snd!\n"); + retval = WMTRSTRET_FAIL; + goto rstDone; + } + /* wakeup blocked opid */ + pOp = wmt_lib_get_current_op(pDevWmt); + if (osal_op_is_wait_for_signal(pOp)) + osal_op_raise_signal(pOp, -1); + /* wakeup blocked cmd */ + wmt_dev_rx_event_cb(); + + /* <4> retry until reset flow successful */ + while (retries > 0) { + /* <4.1> reset combo hw */ + bRet = wmt_lib_hw_rst(); + if (bRet == MTK_WCN_BOOL_FALSE) { + WMT_ERR_FUNC("[whole chip reset] fail at wmt_lib_hw_rst!\n"); + retries--; + continue; + } + /* <4.2> reset driver/combo sw */ + bRet = wmt_lib_sw_rst(1); + if (bRet == MTK_WCN_BOOL_FALSE) { + WMT_ERR_FUNC("[whole chip reset] fail at wmt_lib_sw_rst!\n"); + retries--; + continue; + } + break; + } + osal_clear_bit(WMT_STAT_RST_ON, &pDevWmt->state); + if (bRet == MTK_WCN_BOOL_FALSE) { + rstMsg = WMTRSTMSG_RESET_END_FAIL; + WMT_INFO_FUNC("[whole chip reset] fail! retries = %d\n", RETRYTIMES - retries); + } else { + rstMsg = WMTRSTMSG_RESET_END; + WMT_INFO_FUNC("[whole chip reset] ok! retries = %d\n", RETRYTIMES - retries); + } + + + /* <5> RESET_END notification */ + bRet = wmt_cdev_rstmsg_snd(rstMsg); + if (bRet == MTK_WCN_BOOL_FALSE) { + WMT_ERR_FUNC("[whole chip reset] fail at wmt_lib_rstmsg_snd!\n"); + retval = WMTRSTRET_FAIL; + } else { + retval = rstMsg == WMTRSTMSG_RESET_END ? WMTRSTRET_SUCCESS : WMTRSTRET_FAIL; + } + mtk_wcn_stp_assert_flow_ctrl(0); + mtk_wcn_stp_coredump_start_ctrl(0); + mtk_wcn_stp_set_wmt_trg_assert(0); + mtk_wcn_stp_emi_dump_flag_ctrl(0); +rstDone: + osal_clear_bit(WMT_STAT_RST_ON, &pDevWmt->state); + chip_reset_only = 0; + mtk_wcn_consys_sleep_info_restore(); + return retval; +} + + +MTK_WCN_BOOL wmt_lib_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb) +{ + + MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; + P_DEV_WMT pWmtDev = &gDevWmt; + + if (eType >= 0 && eType <= WMTDRV_TYPE_ANT) { + WMT_DBG_FUNC("reg ok!\n"); + pWmtDev->rFdrvCb.fDrvRst[eType] = pCb; + bRet = MTK_WCN_BOOL_TRUE; + } else { + WMT_WARN_FUNC("reg fail!\n"); + } + + return bRet; +} + +MTK_WCN_BOOL wmt_lib_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType) +{ + MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; + P_DEV_WMT pWmtDev = &gDevWmt; + + if (eType >= 0 && eType <= WMTDRV_TYPE_WIFI) { + WMT_DBG_FUNC("unreg ok!\n"); + pWmtDev->rFdrvCb.fDrvRst[eType] = NULL; + bRet = MTK_WCN_BOOL_TRUE; + } else { + WMT_WARN_FUNC("unreg fail!\n"); + } + + return bRet; +} + + +UINT32 wmt_lib_dbg_level_set(UINT32 level) +{ + gWmtDbgLvl = level > WMT_LOG_LOUD ? WMT_LOG_LOUD : level; + return 0; +} +#ifdef CONFIG_MTK_COMBO_CHIP_DEEP_SLEEP_SUPPORT +INT32 wmt_lib_deep_sleep_ctrl(INT32 value) +{ + MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE; + + WMT_INFO_FUNC("g_deep_sleep_flag value (%d) set form wmt_dbg.\n", value); + ret = wmt_core_deep_sleep_ctrl(value); + if (sdio_deep_sleep_flag_set) { + if (value) + (*sdio_deep_sleep_flag_set)(MTK_WCN_BOOL_TRUE); + else + (*sdio_deep_sleep_flag_set)(MTK_WCN_BOOL_FALSE); + } else { + WMT_ERR_FUNC("sdio_deep_sleep_flag_set is not register"); + return -1; + } + return 0; +} + +MTK_WCN_BOOL wmt_lib_deep_sleep_flag_set(MTK_WCN_BOOL flag) +{ + if (sdio_deep_sleep_flag_set) { + (*sdio_deep_sleep_flag_set)(flag); + } else { + WMT_ERR_FUNC("sdio_deep_sleep_flag_set is not register"); + return MTK_WCN_BOOL_FALSE; + } + return MTK_WCN_BOOL_TRUE; +} +#endif +INT32 wmt_lib_set_stp_wmt_last_close(UINT32 value) +{ + return mtk_wcn_stp_set_wmt_last_close(value); +} + +INT32 wmt_lib_notify_stp_sleep(VOID) +{ + INT32 iRet = 0x0; + + iRet = wmt_lib_psm_lock_aquire(); + if (iRet) { + WMT_ERR_FUNC("--->lock psm_lock failed, iRet=%d\n", iRet); + return iRet; + } + + iRet = mtk_wcn_stp_notify_sleep_for_thermal(); + wmt_lib_psm_lock_release(); + + return iRet; +} + +VOID wmt_lib_set_patch_num(UINT32 num) +{ + P_DEV_WMT pWmtDev = &gDevWmt; + + pWmtDev->patchNum = num; +} + +VOID wmt_lib_set_patch_info(P_WMT_PATCH_INFO pPatchinfo) +{ + P_DEV_WMT pWmtDev = &gDevWmt; + + pWmtDev->pWmtPatchInfo = pPatchinfo; +} + +VOID wmt_lib_set_rom_patch_info(struct wmt_rom_patch_info *PatchInfo, ENUM_WMTDRV_TYPE_T type) +{ + P_DEV_WMT pWmtDev = &gDevWmt; + + if (type < 0) + return; + + /* Allow info of a type to be set only once, to avoid inproper usage */ + if (pWmtDev->pWmtRomPatchInfo[type]) + return; + + pWmtDev->pWmtRomPatchInfo[type] = kcalloc(1, sizeof(struct wmt_rom_patch_info), + GFP_ATOMIC); + + if (pWmtDev->pWmtRomPatchInfo[type]) + osal_memcpy(pWmtDev->pWmtRomPatchInfo[type], PatchInfo, + sizeof(struct wmt_rom_patch_info)); +} + +INT32 wmt_lib_set_current_op(P_DEV_WMT pWmtDev, P_OSAL_OP pOp) +{ + if (pWmtDev) { + pWmtDev->pCurOP = pOp; + WMT_DBG_FUNC("pOp=0x%p\n", pOp); + return 0; + } + WMT_ERR_FUNC("Invalid pointer\n"); + return -1; +} + +P_OSAL_OP wmt_lib_get_current_op(P_DEV_WMT pWmtDev) +{ + if (pWmtDev) + return pWmtDev->pCurOP; + WMT_ERR_FUNC("Invalid pointer\n"); + return NULL; +} + +INT32 wmt_lib_set_worker_op(P_DEV_WMT pWmtDev, P_OSAL_OP pOp) +{ + if (pWmtDev) { + pWmtDev->pWorkerOP = pOp; + WMT_DBG_FUNC("pOp=0x%p\n", pOp); + return 0; + } + WMT_ERR_FUNC("Invalid pointer\n"); + return -1; +} + +P_OSAL_OP wmt_lib_get_worker_op(P_DEV_WMT pWmtDev) +{ + if (pWmtDev) + return pWmtDev->pWorkerOP; + WMT_ERR_FUNC("Invalid pointer\n"); + return NULL; +} + +UINT8 *wmt_lib_get_fwinfor_from_emi(UINT8 section, UINT32 offset, UINT8 *buf, UINT32 len) +{ + UINT8 *pAddr = NULL; + UINT32 sublen1 = 0; + UINT32 sublen2 = 0; + P_CONSYS_EMI_ADDR_INFO p_consys_info; + + p_consys_info = wmt_plat_get_emi_phy_add(); + osal_assert(p_consys_info); + + if (section == 0) { + pAddr = wmt_plat_get_emi_virt_add(0x0); + if (len > 1024) + len = 1024; + if (!pAddr) { + WMT_ERR_FUNC("wmt-lib: get EMI virtual base address fail\n"); + } else { + WMT_INFO_FUNC("vir addr(0x%p)\n", pAddr); + osal_memcpy_fromio(&buf[0], pAddr, len); + } + } else { + if (p_consys_info == NULL) { + WMT_ERR_FUNC("wmt-lib: get EMI physical address fail!\n"); + return 0; + } + + if (offset >= 0x7fff) + offset = 0x0; + + if (offset + len > 32768) { + pAddr = wmt_plat_get_emi_virt_add(offset + p_consys_info->paged_trace_off); + if (!pAddr) { + WMT_ERR_FUNC("wmt-lib: get part1 EMI virtual base address fail\n"); + } else { + WMT_INFO_FUNC("part1 vir addr(0x%p)\n", pAddr); + sublen1 = 0x7fff - offset; + osal_memcpy_fromio(&buf[0], pAddr, sublen1); + } + pAddr = wmt_plat_get_emi_virt_add(p_consys_info->paged_trace_off); + if (!pAddr) { + WMT_ERR_FUNC("wmt-lib: get part2 EMI virtual base address fail\n"); + } else { + WMT_INFO_FUNC("part2 vir addr(0x%p)\n", pAddr); + sublen2 = len - sublen1; + osal_memcpy_fromio(&buf[sublen1], pAddr, sublen2); + } + } else { + pAddr = wmt_plat_get_emi_virt_add(offset + p_consys_info->paged_trace_off); + if (!pAddr) { + WMT_ERR_FUNC("wmt-lib: get EMI virtual base address fail\n"); + } else { + WMT_INFO_FUNC("vir addr(0x%p)\n", pAddr); + osal_memcpy_fromio(&buf[0], pAddr, len); + } + } + } + + return 0; +} +EXPORT_SYMBOL(wmt_lib_get_fwinfor_from_emi); + +INT32 wmt_lib_merge_if_flag_ctrl(UINT32 enable) +{ +#if WMT_PLAT_ALPS + return wmt_plat_merge_if_flag_ctrl(enable); +#endif +} + + +INT32 wmt_lib_merge_if_flag_get(UINT32 enable) +{ +#if WMT_PLAT_ALPS + return wmt_plat_merge_if_flag_get(); +#endif +} + + +PUINT8 wmt_lib_get_cpupcr_xml_format(PUINT32 pLen) +{ + PUINT8 temp; + + osal_memset(&g_cpupcr_buf[0], 0, WMT_STP_CPUPCR_BUF_SIZE); + temp = g_cpupcr_buf; + *pLen += stp_dbg_cpupcr_infor_format(temp, WMT_STP_CPUPCR_BUF_SIZE); + *pLen += mtk_stp_dbg_dmp_append(temp + *pLen, WMT_STP_CPUPCR_BUF_SIZE - *pLen); + + WMT_INFO_FUNC("print xml buffer,len(%d):\n\n", *pLen); + + WMT_INFO_FUNC("%s", g_cpupcr_buf); + + return &g_cpupcr_buf[0]; +} + + +/** + * called by wmt_dev wmt_dev_proc_for_dump_info_read + */ +PUINT8 wmt_lib_get_cpupcr_reg_info(PUINT32 pLen, PUINT32 consys_reg) +{ + osal_memset(&g_cpupcr_buf[0], 0, WMT_STP_CPUPCR_BUF_SIZE); + if (consys_reg != NULL) + *pLen += stp_dbg_dump_cpupcr_reg_info(g_cpupcr_buf, consys_reg[1]); + else + *pLen += osal_sprintf(g_cpupcr_buf + *pLen, "0\n"); + WMT_INFO_FUNC("print buffer,len(%d):\n\n", *pLen); + WMT_INFO_FUNC("%s", g_cpupcr_buf); + return &g_cpupcr_buf[0]; +} + +INT32 wmt_lib_tm_temp_query(VOID) +{ + return wmt_dev_tm_temp_query(); +} + +INT32 wmt_lib_register_thermal_ctrl_cb(thermal_query_ctrl_cb thermal_ctrl) +{ + wmt_plat_thermal_ctrl_cb_reg(thermal_ctrl); + return 0; +} + +INT32 wmt_lib_register_trigger_assert_cb(trigger_assert_cb trigger_assert) +{ + wmt_plat_trigger_assert_cb_reg(trigger_assert); + return 0; +} + +UINT32 wmt_lib_set_host_assert_info(UINT32 type, UINT32 reason, UINT32 en) +{ + return stp_dbg_set_host_assert_info(type, reason, en); +} + +INT8 wmt_lib_co_clock_get(void) +{ + if (gDevWmt.rWmtGenConf.cfgExist) + return gDevWmt.rWmtGenConf.co_clock_flag; + else + return -1; +} + + +UINT32 wmt_lib_get_drv_status(UINT32 type) +{ + return wmt_core_get_drv_status((ENUM_WMTDRV_TYPE_T) type); +} + +INT32 wmt_lib_trigger_reset(VOID) +{ + return wmt_btm_trigger_reset(); +} + +INT32 wmt_lib_trigger_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason) +{ + return wmt_lib_trigger_assert_keyword(type, reason, NULL); +} + +INT32 wmt_lib_trigger_assert_keyword(ENUM_WMTDRV_TYPE_T type, UINT32 reason, PUINT8 keyword) +{ + INT32 iRet = -1; + WMT_CTRL_DATA ctrlData; + + if (wmt_lib_assert_lock_trylock() == 0) { + WMT_INFO_FUNC("Can't lock assert mutex which might be held by another trigger assert procedure.\n"); + return iRet; + } + + wmt_core_set_coredump_state(DRV_STS_FUNC_ON); + + ctrlData.ctrlId = (SIZE_T) WMT_CTRL_TRG_ASSERT; + ctrlData.au4CtrlData[0] = (SIZE_T) type; + ctrlData.au4CtrlData[1] = (SIZE_T) reason; + ctrlData.au4CtrlData[2] = (SIZE_T) keyword; + + iRet = wmt_ctrl(&ctrlData); + if (iRet) { + /* ERROR */ + WMT_ERR_FUNC + ("WMT-CORE: wmt_core_ctrl failed: type(%d), reason(%d), keyword(%s), iRet(%d)\n", + type, reason, keyword, iRet); + osal_assert(0); + } + wmt_lib_assert_lock_release(); + + return iRet; +} + +#if CFG_WMT_PS_SUPPORT +UINT32 wmt_lib_quick_sleep_ctrl(UINT32 en) +{ + WMT_WARN_FUNC("%s quick sleep mode\n", en ? "enable" : "disable"); + g_quick_sleep_ctrl = en; + return 0; +} +#endif + +UINT32 wmt_lib_fw_patch_update_rst_ctrl(UINT32 en) +{ + WMT_WARN_FUNC("%s fw patch update reset\n", en ? "enable" : "disable"); + g_fw_patch_update_rst = en; + return 0; +} + +#if CONSYS_ENALBE_SET_JTAG +UINT32 wmt_lib_jtag_flag_set(UINT32 en) +{ + return wmt_plat_jtag_flag_ctrl(en); +} +#endif + +UINT32 wmt_lib_soc_set_wifiver(UINT32 wifiver) +{ + return stp_dbg_set_wifiver(wifiver); +} + +UINT32 wmt_lib_co_clock_flag_get(VOID) +{ + return wmt_plat_soc_co_clock_flag_get(); +} + +INT32 wmt_lib_wifi_fem_cfg_report(PVOID pvInfoBuf) +{ + INT32 iRet = 0; + ULONG addr = 0; + WMT_GEN_CONF *pWmtGenConf = NULL; + + /* sanity check */ + ASSERT(pvInfoBuf); + + iRet = wmt_core_ctrl(WMT_CTRL_GET_WMT_CONF, &addr, 0); + + if (iRet) { + WMT_ERR_FUNC("ctrl GET_WMT_CONF fail(%d)\n", iRet); + return -2; + } + + pWmtGenConf = (P_WMT_GEN_CONF) addr; + + WMT_DBG_FUNC("pWmtGenConf->coex_wmt_wifi_path=0x%x\n", pWmtGenConf->coex_wmt_wifi_path); + + /* Memory copy */ + osal_memcpy((PUINT8)(pvInfoBuf), &pWmtGenConf->coex_wmt_wifi_path, + osal_sizeof(pWmtGenConf->coex_wmt_wifi_path)); + return iRet; +} + +INT32 wmt_lib_sdio_reg_rw(INT32 func_num, INT32 direction, UINT32 offset, UINT32 value) +{ + INT32 ret = -1; + ENUM_WMT_CHIP_TYPE chip_type; + + chip_type = wmt_detect_get_chip_type(); + + if (chip_type == WMT_CHIP_TYPE_COMBO) { + if (sdio_reg_rw) + ret = sdio_reg_rw(func_num, direction, offset, value); + else + WMT_ERR_FUNC("sdio_reg_rw callback is not set, maybe the sdio funcxx write/read not used\n"); + } else + WMT_ERR_FUNC("It`s soc project, this function is not used\n"); + return ret; +} + +VOID wmt_lib_dump_wmtd_backtrace(VOID) +{ + osal_thread_show_stack(&gDevWmt.thread); +} + +INT32 wmt_lib_met_cmd(UINT32 value) +{ + P_OSAL_OP pOp; + MTK_WCN_BOOL bRet; + P_OSAL_SIGNAL pSignal; + + pOp = wmt_lib_get_free_op(); + if (!pOp) { + WMT_DBG_FUNC("get_free_lxop fail\n"); + return -1; + } + + pSignal = &pOp->signal; + pSignal->timeoutValue = MAX_EACH_WMT_CMD; + WMT_DBG_FUNC("met ctrl value(0x%x)\n", value); + pOp->op.opId = WMT_OPID_MET_CTRL; + pOp->op.au4OpData[0] = value; + if (DISABLE_PSM_MONITOR()) { + WMT_ERR_FUNC("wake up failed\n"); + wmt_lib_put_op_to_free_queue(pOp); + return -1; + } + + bRet = wmt_lib_put_act_op(pOp); + ENABLE_PSM_MONITOR(); + + if (bRet != MTK_WCN_BOOL_FALSE) + return 0; + + return -1; +} + +UINT32 wmt_lib_get_gps_lna_pin_num(VOID) +{ + return mtk_consys_get_gps_lna_pin_num(); +} + +INT32 wmt_lib_met_ctrl(INT32 met_ctrl, INT32 log_ctrl) +{ + P_DEV_WMT p_devwmt; + P_OSAL_THREAD p_thread; + INT32 ret; + P_CONSYS_EMI_ADDR_INFO emi_info; + + emi_info = mtk_wcn_consys_soc_get_emi_phy_add(); + if (emi_info == NULL) { + WMT_ERR_FUNC("get EMI info failed\n"); + return -1; + } + + if (!emi_info->emi_met_size) { + WMT_ERR_FUNC("met debug function is not support\n"); + return -1; + } + + ret = wmt_lib_met_cmd(met_ctrl); + if (ret) { + WMT_ERR_FUNC("send MET ctrl command fail(%d)\n", ret); + return -1; + } + + p_devwmt = &gDevWmt; + p_thread = &gDevWmt.met_thread; + if (met_ctrl & 0x1) { + /*met enable*/ + /* Create mtk_wmt_met thread */ + osal_strncpy(p_thread->threadName, "mtk_wmt_met", sizeof(p_thread->threadName)); + p_devwmt->met_log_ctrl = log_ctrl; + p_thread->pThreadData = (PVOID) p_devwmt; + p_thread->pThreadFunc = (PVOID) met_thread; + ret = osal_thread_create(p_thread); + if (ret) { + WMT_ERR_FUNC("osal_thread_create(0x%p) fail(%d)\n", p_thread, ret); + return -1; + } + /* start running mtk_wmt_met */ + ret = osal_thread_run(p_thread); + if (ret) { + WMT_ERR_FUNC("osal_thread_run(0x%p) fail(%d)\n", p_thread, ret); + return -1; + } + } else { + /*met disable*/ + /* stop running mtk_wmt_met */ + ret = osal_thread_stop(p_thread); + if (ret) { + WMT_ERR_FUNC("osal_thread_stop(0x%p) fail(%d)\n", p_thread, ret); + return -1; + } + } + + return 0; +} + +VOID wmt_lib_set_ext_ldo(UINT32 flag) +{ + gDevWmt.ext_ldo_flag = flag; +} + +UINT32 wmt_lib_get_ext_ldo(VOID) +{ + return gDevWmt.ext_ldo_flag; +} + +static VOID wmt_lib_utc_sync_timeout_handler(timer_handler_arg arg) +{ + schedule_work(&gDevWmt.utcSyncWorker); +} + +static VOID wmt_lib_utc_sync_worker_handler(struct work_struct *work) +{ + wmt_lib_utc_time_sync(); +} + +INT32 wmt_lib_fw_log_ctrl(enum wmt_fw_log_type type, UINT8 onoff, UINT8 level) +{ + P_OSAL_OP pOp; + MTK_WCN_BOOL bRet; + P_OSAL_SIGNAL pSignal; + + pOp = wmt_lib_get_free_op(); + if (!pOp) { + WMT_WARN_FUNC("get_free_lxop fail\n"); + return -1; + } + + pSignal = &pOp->signal; + pSignal->timeoutValue = 0; + pOp->op.opId = WMT_OPID_FW_LOG_CTRL; + pOp->op.au4OpData[0] = type; + pOp->op.au4OpData[1] = onoff; + pOp->op.au4OpData[2] = level; + + if (DISABLE_PSM_MONITOR()) { + WMT_ERR_FUNC("wake up failed\n"); + wmt_lib_put_op_to_free_queue(pOp); + return -2; + } + + bRet = wmt_lib_put_act_op(pOp); + ENABLE_PSM_MONITOR(); + if (bRet == MTK_WCN_BOOL_FALSE) { + WMT_WARN_FUNC("OPID(%d) fail\n", pOp->op.opId); + return -3; + } + WMT_DBG_FUNC("OPID(%d) ok\n", pOp->op.opId); + + return 0; +} + +INT32 wmt_lib_gps_mcu_ctrl(PUINT8 p_tx_data_buf, UINT32 tx_data_len, PUINT8 p_rx_data_buf, + UINT32 rx_data_buf_len, PUINT32 p_rx_data_len) +{ + P_OSAL_OP pOp; + MTK_WCN_BOOL bRet; + P_OSAL_SIGNAL pSignal; + + pOp = wmt_lib_get_free_op(); + if (!pOp) { + WMT_DBG_FUNC("get_free_lxop fail\n"); + return -1; + } + + pSignal = &pOp->signal; + pSignal->timeoutValue = MAX_WMT_OP_TIMEOUT; + pOp->op.opId = WMT_OPID_GPS_MCU_CTRL; + pOp->op.au4OpData[0] = (SIZE_T)p_tx_data_buf; + pOp->op.au4OpData[1] = tx_data_len; + pOp->op.au4OpData[2] = (SIZE_T)p_rx_data_buf; + pOp->op.au4OpData[3] = rx_data_buf_len; + pOp->op.au4OpData[4] = (SIZE_T)p_rx_data_len; + if (DISABLE_PSM_MONITOR()) { + WMT_ERR_FUNC("wake up failed\n"); + wmt_lib_put_op_to_free_queue(pOp); + return -1; + } + + bRet = wmt_lib_put_act_op(pOp); + ENABLE_PSM_MONITOR(); + + if (bRet == MTK_WCN_BOOL_FALSE) { + WMT_WARN_FUNC("WMT_OPID_GPS_MCU_CTRL fail(%zu)\n", pOp->op.au4OpData[5]); + return -1; + } + + return 0; +} + +VOID wmt_lib_print_wmtd_op_history(VOID) +{ + osal_op_history_print(&gDevWmt.wmtd_op_history, "wmtd_thread"); +} + +VOID wmt_lib_print_worker_op_history(VOID) +{ + osal_op_history_print(&gDevWmt.worker_op_history, "wmtd_worker_thread"); +} +VOID wmt_lib_set_blank_status(UINT32 on_off_flag) +{ + wmt_core_set_blank_status(on_off_flag); +} + +UINT32 wmt_lib_get_blank_status(VOID) +{ + return wmt_core_get_blank_status(); +} + +INT32 wmt_lib_blank_status_ctrl(UINT32 on_off_flag) +{ + P_OSAL_OP pOp; + MTK_WCN_BOOL bRet; + P_OSAL_SIGNAL pSignal; + + pOp = wmt_lib_get_free_op(); + if (!pOp) { + WMT_DBG_FUNC("get_free_lxop fail\n"); + return -1; + } + + pSignal = &pOp->signal; + pSignal->timeoutValue = MAX_EACH_WMT_CMD; + WMT_DBG_FUNC("WMT_OPID_BLANK_STATUS_CTRL on_off_flag(0x%x)\n\n", on_off_flag); + pOp->op.opId = WMT_OPID_BLANK_STATUS_CTRL; + pOp->op.au4OpData[0] = on_off_flag; + if (DISABLE_PSM_MONITOR()) { + WMT_ERR_FUNC("wake up failed\n"); + wmt_lib_put_op_to_free_queue(pOp); + return -1; + } + + bRet = wmt_lib_put_act_op(pOp); + ENABLE_PSM_MONITOR(); + + if (bRet != MTK_WCN_BOOL_FALSE) { + WMT_DBG_FUNC("WMT_OPID_BLANK_STATUS_CTRL on_off_flag(0x%x) ok\n", on_off_flag); + return 0; + } + WMT_WARN_FUNC("WMT_OPID_BLANK_STATUS_CTRL on_off_flag(0x%x) bRet(%d)\n", on_off_flag, bRet); + return -1; +} + +/** + * Desinged for native service to get number of patches + * resides in /vendor/firmware + */ +INT32 wmt_lib_get_vendor_patch_num(VOID) +{ + return gDevWmt.patch_table.num; +} + +INT32 wmt_lib_set_vendor_patch_version(struct wmt_vendor_patch *p) +{ + struct vendor_patch_table *table = &(gDevWmt.patch_table); + struct wmt_vendor_patch *patch = table->patch; + + if (patch == NULL) { + INT32 init_capacity = 5; + + patch = (struct wmt_vendor_patch *)osal_malloc( + sizeof(struct wmt_vendor_patch) * init_capacity); + if (patch == NULL) { + WMT_ERR_FUNC("[oom]set vendor patch version"); + return -1; + } + + table->patch = patch; + table->capacity = init_capacity; + table->num = 0; + + table->active_version = (PUINT8 *)osal_malloc(sizeof(PUINT8) * init_capacity); + if (table->active_version == NULL) { + osal_free(table->patch); + table->patch = NULL; + WMT_ERR_FUNC("[oom]alloc active patch"); + return -1; + } + osal_memset(table->active_version, 0, sizeof(PUINT8) * init_capacity); + } + + if (table->capacity == table->num) { + WMT_ERR_FUNC("reach to limit"); + return -1; + } + + /* copy patch info to table */ + patch = patch + table->num; + patch->type = p->type; + osal_strncpy(patch->file_name, p->file_name, sizeof(p->file_name)); + osal_strncpy(patch->version, p->version, sizeof(p->version)); + + table->num++; + WMT_INFO_FUNC("set version %s %s %d", + patch->file_name, patch->version, patch->type); + return 0; +} + +INT32 wmt_lib_get_vendor_patch_version(struct wmt_vendor_patch *p) +{ + struct vendor_patch_table *table = &(gDevWmt.patch_table); + + if (p->id >= table->num || p->id < 0) { + WMT_ERR_FUNC("id %d out of range", p->id); + return -1; + } + + osal_memcpy(p, &table->patch[p->id], sizeof(struct wmt_vendor_patch)); + WMT_INFO_FUNC("get version: %s %s t:%d", + p->file_name, p->version, p->type); + return 0; +} + +INT32 wmt_lib_set_check_patch_status(INT32 status) +{ + gDevWmt.patch_table.status = status; + return 0; +} + +INT32 wmt_lib_get_check_patch_status(VOID) +{ + return gDevWmt.patch_table.status; +} + +INT32 wmt_lib_set_active_patch_version(struct wmt_vendor_patch *p) +{ + struct vendor_patch_table *table = &(gDevWmt.patch_table); + + if (p->id < 0 || p->id >= table->num) { + WMT_ERR_FUNC("patch id: %d is invalid. num = %d", p->id, table->num); + return -1; + } + + if (table->active_version == NULL) { + WMT_ERR_FUNC("active version is NULL"); + return -1; + } + + if (table->active_version[p->id] == NULL) { + table->active_version[p->id] = osal_malloc(sizeof(UINT8) * (WMT_FIRMWARE_VERSION_LENGTH + 1)); + if (table->active_version[p->id] == NULL) { + WMT_ERR_FUNC("oom when alloc active_version"); + return -1; + } + } else if (osal_strcmp(p->version, table->active_version[p->id]) == 0) + return 0; + + wmt_lib_set_need_update_patch_version(1); + osal_strncpy(table->active_version[p->id], p->version, WMT_FIRMWARE_VERSION_LENGTH + 1); + return 0; +} + +INT32 wmt_lib_get_active_patch_version(struct wmt_vendor_patch *p) +{ + struct vendor_patch_table *table = &(gDevWmt.patch_table); + INT32 id = p->id; + + if (id >= table->num || id < 0) { + WMT_ERR_FUNC("id %d out of range", p->id); + return -1; + } + if (table->active_version[id] == NULL) { + WMT_ERR_FUNC("active_version is null: id = %d", id); + return -1; + } + + osal_memcpy(p, &table->patch[id], sizeof(struct wmt_vendor_patch)); + osal_strncpy(p->version, table->active_version[id], + WMT_FIRMWARE_VERSION_LENGTH + 1); + WMT_INFO_FUNC("get active version: %s %s t:%d id:%d", + p->file_name, p->version, p->type, id); + return 0; +} + +INT32 wmt_lib_get_need_update_patch_version(VOID) +{ + return gDevWmt.patch_table.need_update; +} + + +INT32 wmt_lib_set_need_update_patch_version(INT32 need) +{ + gDevWmt.patch_table.need_update = need > 0 ? 1 : 0; + return 0; +} + +VOID mtk_lib_set_mcif_mpu_protection(MTK_WCN_BOOL enable) +{ + mtk_consys_set_mcif_mpu_protection(enable); +} + +static VOID wmt_lib_assert_work_cb(struct work_struct *work) +{ + struct assert_work_st *a = &wmt_assert_work; + + wmt_lib_trigger_assert_keyword(a->type, a->reason, a->keyword); +} + +VOID wmt_lib_trigger_assert_keyword_delay(ENUM_WMTDRV_TYPE_T type, UINT32 reason, PUINT8 keyword) +{ + struct assert_work_st *a = &wmt_assert_work; + + a->type = type; + a->reason = reason; + if (snprintf(a->keyword, sizeof(a->keyword), "%s", keyword) < 0) { + WMT_INFO_FUNC("snprintf a->keyword fail\n"); + } else { + WMT_ERR_FUNC("Assert: type = %d, reason = %d, keyword = %s", type, reason, keyword); + schedule_work(&(a->work)); + } +} + +INT32 wmt_lib_dmp_consys_state(P_CONSYS_STATE_DMP_INFO dmp_info, + unsigned int cpupcr_times, unsigned int slp_ms) +{ + P_OSAL_OP pOp; + MTK_WCN_BOOL bRet = MTK_WCN_BOOL_TRUE; + P_OSAL_SIGNAL pSignal; + P_CONSYS_STATE_DMP_OP dmp_op = NULL; + P_CONSYS_STATE_DMP_OP tmp_op; + int i, wait_ms = 1000, tmp; + struct consys_state_dmp_req *p_req = &gDevWmt.state_dmp_req; + + + if (cpupcr_times > WMT_LIB_DMP_CONSYS_MAX_TIMES) { + pr_warn("dump too many times [%d]\n", cpupcr_times); + return MTK_WCN_BOOL_FALSE; + } + + /* make sure: */ + /* 1. consys already power on */ + /* 2. consys register is readable */ + if (wmt_lib_get_drv_status(WMTDRV_TYPE_WMT) != DRV_STS_FUNC_ON + || osal_test_bit(WMT_STAT_PWR, &gDevWmt.state) == 0) { + return MTK_WCN_BOOL_FALSE; + } + + for (i = 0; i < WMT_LIB_DMP_SLOT; i++) { + tmp_op = &p_req->consys_ops[i]; + if (osal_trylock_sleepable_lock(&tmp_op->lock) == 1) { + if (tmp_op->status == WMT_DUMP_STATE_NONE) { + tmp = atomic_add_return(1, &p_req->version); + dmp_op = tmp_op; + dmp_op->status = WMT_DUMP_STATE_SCHEDULED; + dmp_op->version = tmp; + } + osal_unlock_sleepable_lock(&tmp_op->lock); + if (dmp_op != NULL) + break; + } + } + + if (dmp_op == NULL) + return MTK_WCN_BOOL_FALSE; + + memset(&dmp_op->dmp_info, 0, sizeof(struct consys_state_dmp_info)); + dmp_op->times = cpupcr_times; + dmp_op->cpu_sleep_ms = slp_ms; + + pOp = wmt_lib_get_free_op(); + if (!pOp) { + WMT_DBG_FUNC("get_free_op fail\n"); + bRet = MTK_WCN_BOOL_FALSE; + goto err; + } + + tmp = cpupcr_times * slp_ms; + if (wait_ms < tmp) + wait_ms = tmp + 300; + + pSignal = &pOp->signal; + pOp->op.opId = WMT_OPID_GET_CONSYS_STATE; + pOp->op.au4OpData[0] = (SIZE_T)dmp_op; + pOp->op.au4OpData[1] = (SIZE_T)dmp_op->version; + pSignal->timeoutValue = wait_ms; + + bRet = wmt_lib_put_act_op(pOp); + + if (bRet == MTK_WCN_BOOL_FALSE) { + WMT_WARN_FUNC("WMT_OPID_GET_CONSYS_STATE failed\n"); + goto err; + } + + memcpy(dmp_info, &dmp_op->dmp_info, sizeof(struct consys_state_dmp_info)); +err: + osal_lock_sleepable_lock(&dmp_op->lock); + dmp_op->status = WMT_DUMP_STATE_NONE; + osal_unlock_sleepable_lock(&dmp_op->lock); + return bRet; +} + +INT32 wmt_lib_reg_readable(VOID) +{ + return wmt_lib_reg_readable_by_addr(0); +} + +INT32 wmt_lib_reg_readable_by_addr(SIZE_T addr) +{ + if (wmt_lib_get_drv_status(WMTDRV_TYPE_WMT) == DRV_STS_POWER_OFF + || osal_test_bit(WMT_STAT_PWR, &gDevWmt.state) == 0) { + return MTK_WCN_BOOL_FALSE; + } + return mtk_consys_check_reg_readable_by_addr(addr); +} + diff --git a/drivers/misc/mediatek/connectivity/common/common_main/include/mtk_wcn_cmb_hw.h b/drivers/misc/mediatek/connectivity/common/common_main/include/mtk_wcn_cmb_hw.h new file mode 100644 index 0000000000000000000000000000000000000000..adbd4399a872e2dcf3566f1ea3aeca834eb3cb04 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/include/mtk_wcn_cmb_hw.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + + + +#ifndef _MTK_WCN_CMB_HW_H_ +#define _MTK_WCN_CMB_HW_H_ + + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +#include + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + + + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +typedef struct _PWR_SEQ_TIME_ { + UINT32 rtcStableTime; + UINT32 ldoStableTime; + UINT32 rstStableTime; + UINT32 offStableTime; + UINT32 onStableTime; +} PWR_SEQ_TIME, *P_PWR_SEQ_TIME; + + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + + + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + + + + + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + + + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +extern INT32 mtk_wcn_cmb_hw_pwr_off(VOID); +extern INT32 mtk_wcn_cmb_hw_pwr_on(VOID); +extern INT32 mtk_wcn_cmb_hw_rst(VOID); +extern INT32 mtk_wcn_cmb_hw_init(P_PWR_SEQ_TIME pPwrSeqTime); +extern INT32 mtk_wcn_cmb_hw_deinit(VOID); +extern INT32 mtk_wcn_cmb_hw_state_show(VOID); + + +#endif /* _MTK_WCN_CMB_HW_H_ */ diff --git a/drivers/misc/mediatek/connectivity/common/common_main/include/stp_exp.h b/drivers/misc/mediatek/connectivity/common/common_main/include/stp_exp.h new file mode 100644 index 0000000000000000000000000000000000000000..b1c5e69e03a3572594cc6e6859c5ec2731a70dd1 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/include/stp_exp.h @@ -0,0 +1,317 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#ifndef _STP_EXP_H_ +#define _STP_EXP_H_ + +#include "osal.h" + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + + +#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT + +#if (WMT_IDC_SUPPORT) +#define CFG_WMT_LTE_COEX_HANDLING 1 +#define CFG_WMT_LTE_ENABLE_MSGID_MAPPING 0 +#else +#define CFG_WMT_LTE_COEX_HANDLING 0 +#endif + +#define BT_TASK_INDX (0) +#define FM_TASK_INDX (1) +#define GPS_TASK_INDX (2) +#define WIFI_TASK_INDX (3) +#define WMT_TASK_INDX (4) +#define STP_TASK_INDX (5) +#define GPSL5_TASK_INDX (6) +#define INFO_TASK_INDX (6) +#define ANT_TASK_INDX (7) +#if CFG_WMT_LTE_COEX_HANDLING +#define COEX_TASK_INDX (8) +#define MTKSTP_MAX_TASK_NUM (9) +#else +#define MTKSTP_MAX_TASK_NUM (8) +#endif + +#define MTKSTP_BUFFER_SIZE (16384) /* Size of RX Queue */ + +#define STP_EXP_HID_API_EXPORT 0 + +#else + +#define STP_EXP_HID_API_EXPORT 1 + +#endif + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ +#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT + +typedef VOID (*MTK_WCN_STP_EVENT_CB) (VOID); +typedef INT32 (*MTK_WCN_STP_IF_TX) (const PUINT8 data, const UINT32 size, PUINT32 written_size); +/* export for HIF driver */ +typedef VOID(*MTK_WCN_STP_IF_RX)(const PUINT8 data, INT32 size); +typedef INT32 (*MTK_WCN_STP_RX_HAS_PENDING_DATA) (VOID); +typedef INT32 (*MTK_WCN_STP_TX_HAS_PENDING_DATA) (VOID); +typedef P_OSAL_THREAD (*MTK_WCN_STP_RX_THREAD_GET) (VOID); + +typedef enum { + STP_UART_IF_TX = 0, + STP_SDIO_IF_TX = 1, + STP_BTIF_IF_TX = 2, + STP_MAX_IF_TX +} ENUM_STP_TX_IF_TYPE; +#endif +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_receive_data +* DESCRIPTION +* receive data from serial protocol engine +* PARAMETERS +* buffer [IN] data buffer +* length [IN] data buffer length +* RETURNS +* INT32 >= 0: size of data received; < 0: error +*****************************************************************************/ +extern INT32 mtk_wcn_stp_receive_data(PUINT8 buffer, UINT32 length, UINT8 type); + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_send_data +* DESCRIPTION +* subfunction send data through STP +* PARAMETERS +* buffer [IN] data buffer +* length [IN] data buffer length +* type [IN] subfunction type +* RETURNS +* INT32 >= 0: length transmitted; < 0: error +*****************************************************************************/ +extern INT32 mtk_wcn_stp_send_data(const PUINT8 buffer, const UINT32 length, const UINT8 type); + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_is_rxqueue_empty +* DESCRIPTION +* Is certain rx queue empty? +* PARAMETERS +* type [IN] subfunction type +* RETURNS +* INT32 0: queue is NOT empyt; !0: queue is empty +*****************************************************************************/ +extern MTK_WCN_BOOL mtk_wcn_stp_is_rxqueue_empty(UINT8 type); + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_is_enable +* DESCRIPTION +* Is STP ready? +* PARAMETERS +* none. +* RETURNS +* MTK_WCN_BOOL TRUE:ready, FALSE:not ready +*****************************************************************************/ +extern MTK_WCN_BOOL mtk_wcn_stp_is_ready(VOID); + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_parser_data +* DESCRIPTION +* push data to serial transport protocol parser engine +* PARAMETERS +* buffer [IN] data buffer +* length [IN] data buffer length +* RETURNS +* void +*****************************************************************************/ +extern INT32 mtk_wcn_stp_parser_data(PUINT8 buffer, UINT32 length); + +/***************************************************************************** +* FUNCTION +* set_bluetooth_rx_interface +* DESCRIPTION +* Set bluetooth rx interface +* PARAMETERS +* rx interface type +* RETURNS +* void +*****************************************************************************/ +extern void mtk_wcn_stp_set_bluez(MTK_WCN_BOOL sdio_flag); + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_register_tx_event_cb +* DESCRIPTION +* regiter Tx event callback function +* PARAMETERS +* func +* RETURNS +* INT32: 0:successful , -1: fail +*****************************************************************************/ +extern INT32 mtk_wcn_stp_register_tx_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func); + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_register_event_cb +* DESCRIPTION +* regiter Rx event callback function +* PARAMETERS +* func +* RETURNS +* INT32: 0:successful , -1: fail +*****************************************************************************/ +extern INT32 mtk_wcn_stp_register_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func); + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_register_if_tx +* DESCRIPTION +* regiter Tx event callback function +* PARAMETERS +* stp_if: SDIO or UART, fnnc: Call back function +* RETURNS +* INT32: 0:successful , -1: fail +*****************************************************************************/ +extern INT32 mtk_wcn_stp_register_if_tx(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func); + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_register_if_rx +* DESCRIPTION +* regiter Rx event callback function +* PARAMETERS +* stp_if: SDIO or UART, fnnc: Call back function +* RETURNS +* int: 0:successful , -1: fail +*****************************************************************************/ +extern INT32 mtk_wcn_stp_register_if_rx(MTK_WCN_STP_IF_RX func); + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_coredump_start_get +* DESCRIPTION +* get f/w assert flag in STP context +* PARAMETERS +* VOID +* RETURNS +* INT32 0= f/w assert flag is not set, others=f/w assert flag is set +*****************************************************************************/ +extern INT32 mtk_wcn_stp_coredump_start_get(VOID); + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_register_rx_has_pending_data +* DESCRIPTION +* regiter rx has pending data call back function +* PARAMETERS +* stp_if: SDIO or UART, fnnc: Call back function +* RETURNS +* int: 0:successful , -1: fail +*****************************************************************************/ +extern INT32 mtk_wcn_stp_register_rx_has_pending_data(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_RX_HAS_PENDING_DATA func); + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_register_tx_has_pending_data +* DESCRIPTION +* regiter tx has pending data call back function +* PARAMETERS +* stp_if: SDIO or UART, fnnc: Call back function +* RETURNS +* int: 0:successful , -1: fail +*****************************************************************************/ +extern INT32 mtk_wcn_stp_register_tx_has_pending_data(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_TX_HAS_PENDING_DATA func); + +/***************************************************************************** +* FUNCTION +* mtk_wcn_stp_register_rx_thread_get +* DESCRIPTION +* regiter rx thread call back function +* PARAMETERS +* stp_if: SDIO or UART, fnnc: Call back function +* RETURNS +* int: 0:successful , -1: fail +*****************************************************************************/ +extern INT32 mtk_wcn_stp_register_rx_thread_get(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_RX_THREAD_GET func); + +extern INT32 mtk_stp_dbg_poll_cpupcr(UINT32 times, UINT32 sleep, UINT32 cmd); +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#else +extern INT32 _mtk_wcn_stp_receive_data(PUINT8 buffer, UINT32 length, UINT8 type); +extern INT32 _mtk_wcn_stp_send_data_raw(const PUINT8 buffer, const UINT32 length, const UINT8 type); +extern INT32 _mtk_wcn_stp_send_data(const PUINT8 buffer, const UINT32 length, const UINT8 type); +extern MTK_WCN_BOOL _mtk_wcn_stp_is_rxqueue_empty(UINT8 type); +extern MTK_WCN_BOOL _mtk_wcn_stp_is_ready(VOID); +extern INT32 _mtk_wcn_stp_parser_data(PUINT8 buffer, UINT32 length); +extern VOID _mtk_wcn_stp_set_bluez(MTK_WCN_BOOL sdio_flag); +extern INT32 _mtk_wcn_stp_register_tx_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func); +extern INT32 _mtk_wcn_stp_register_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func); +extern INT32 _mtk_wcn_stp_register_if_tx(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func); +extern INT32 _mtk_wcn_stp_register_if_rx(MTK_WCN_STP_IF_RX func); +extern INT32 _mtk_wcn_stp_coredump_start_get(VOID); +extern INT32 _mtk_wcn_stp_register_rx_has_pending_data(ENUM_STP_TX_IF_TYPE stp_if, + MTK_WCN_STP_RX_HAS_PENDING_DATA func); +extern INT32 _mtk_wcn_stp_register_tx_has_pending_data(ENUM_STP_TX_IF_TYPE stp_if, + MTK_WCN_STP_TX_HAS_PENDING_DATA func); +extern INT32 _mtk_wcn_stp_register_rx_thread_get(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_RX_THREAD_GET func); + +#endif /* MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT */ + +#endif /* _STP_EXP_H_ */ diff --git a/drivers/misc/mediatek/connectivity/common/common_main/include/wmt.h b/drivers/misc/mediatek/connectivity/common/common_main/include/wmt.h new file mode 100644 index 0000000000000000000000000000000000000000..c65f504b48b84a849e4320a6ebaebf4f2b4fdc4b --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/include/wmt.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +#ifndef _MTKWMT_H_ +#define _MTKWMT_H_ +#include "wmt_core.h" + +#endif /*_MTKWMT_H_*/ diff --git a/drivers/misc/mediatek/connectivity/common/common_main/include/wmt_exp.h b/drivers/misc/mediatek/connectivity/common/common_main/include/wmt_exp.h new file mode 100644 index 0000000000000000000000000000000000000000..ea08503a02f30debceada30c40a9e9b7dcc3a217 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/include/wmt_exp.h @@ -0,0 +1,450 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#ifndef _WMT_EXP_H_ +#define _WMT_EXP_H_ + +#include +#include "osal.h" +#include "wmt_plat.h" +#include "osal_typedef.h" +/* not to reference to internal wmt */ +/* #include "wmt_core.h" */ +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +#if 1 /* moved from wmt_lib.h */ +#ifndef DFT_TAG +#define DFT_TAG "[WMT-DFT]" +#endif + +#define WMT_LOUD_FUNC(fmt, arg...) \ +do { \ + if (gWmtDbgLvl >= WMT_LOG_LOUD) \ + osal_warn_print(DFT_TAG "[L]%s:" fmt, __func__, ##arg); \ +} while (0) +#define WMT_INFO_FUNC(fmt, arg...) \ +do { \ + if (gWmtDbgLvl >= WMT_LOG_INFO) \ + osal_warn_print(DFT_TAG "[I]%s:" fmt, __func__, ##arg); \ +} while (0) +#define WMT_WARN_FUNC(fmt, arg...) \ +do { \ + if (gWmtDbgLvl >= WMT_LOG_WARN) \ + osal_warn_print(DFT_TAG "[W]%s:" fmt, __func__, ##arg); \ +} while (0) +#define WMT_ERR_FUNC(fmt, arg...) \ +do { \ + if (gWmtDbgLvl >= WMT_LOG_ERR) \ + osal_err_print(DFT_TAG "[E]%s(%d):" fmt, __func__, __LINE__, ##arg); \ +} while (0) +#define WMT_DBG_FUNC(fmt, arg...) \ +do { \ + if (gWmtDbgLvl >= WMT_LOG_DBG) \ + osal_warn_print(DFT_TAG "[D]%s:" fmt, __func__, ##arg); \ +} while (0) +#define WMT_TRC_FUNC(f) \ +do { \ + if (gWmtDbgLvl >= WMT_LOG_DBG) \ + osal_warn_print(DFT_TAG "<%s> <%d>\n", __func__, __LINE__); \ +} while (0) + +#endif + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#if 1 /* moved from wmt_lib.h */ +extern INT32 gWmtDbgLvl; +#endif +extern OSAL_BIT_OP_VAR gBtWifiGpsState; +extern OSAL_BIT_OP_VAR gGpsFmState; +extern UINT32 gWifiProbed; +extern MTK_WCN_BOOL g_pwr_off_flag; +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ +#if 1 /* moved from wmt_lib.h */ +#define WMT_LOG_LOUD 4 +#define WMT_LOG_DBG 3 +#define WMT_LOG_INFO 2 +#define WMT_LOG_WARN 1 +#define WMT_LOG_ERR 0 +#endif +#define CFG_CORE_INTERNAL_TXRX 0 /*just do TX/RX in host side */ + +#define CFG_WMT_PS_SUPPORT 1 /* moved from wmt_lib.h */ +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ +#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT + +typedef enum _ENUM_WMTDRV_TYPE_T { + WMTDRV_TYPE_BT = 0, + WMTDRV_TYPE_FM = 1, + WMTDRV_TYPE_GPS = 2, + WMTDRV_TYPE_WIFI = 3, + WMTDRV_TYPE_WMT = 4, + WMTDRV_TYPE_ANT = 5, + WMTDRV_TYPE_STP = 6, + WMTDRV_TYPE_SDIO1 = 7, + WMTDRV_TYPE_SDIO2 = 8, + WMTDRV_TYPE_LPBK = 9, + WMTDRV_TYPE_COREDUMP = 10, + WMTDRV_TYPE_GPSL5 = 11, + WMTDRV_TYPE_MAX +} ENUM_WMTDRV_TYPE_T, *P_ENUM_WMTDRV_TYPE_T; + +/* TODO: [ChangeFeature][GeorgeKuo] Reconsider usage of this type */ +/* TODO: how do we extend for new chip and newer revision? */ +/* TODO: This way is hard to extend */ +typedef enum _ENUM_WMTHWVER_TYPE_T { + WMTHWVER_E1 = 0x0, + WMTHWVER_E2 = 0x1, + WMTHWVER_E3 = 0x2, + WMTHWVER_E4 = 0x3, + WMTHWVER_E5 = 0x4, + WMTHWVER_E6 = 0x5, + WMTHWVER_E7 = 0x6, + WMTHWVER_MAX, + WMTHWVER_INVALID = 0xff +} ENUM_WMTHWVER_TYPE_T, *P_ENUM_WMTHWVER_TYPE_T; + +typedef enum _ENUM_WMTDSNS_TYPE_T { + WMTDSNS_FM_DISABLE = 0, + WMTDSNS_FM_ENABLE = 1, + WMTDSNS_FM_GPS_DISABLE = 2, + WMTDSNS_FM_GPS_ENABLE = 3, + WMTDSNS_MAX +} ENUM_WMTDSNS_TYPE_T, *P_ENUM_WMTDSNS_TYPE_T; + +typedef enum _ENUM_WMTTHERM_TYPE_T { + WMTTHERM_ZERO = 0, + WMTTHERM_ENABLE = WMTTHERM_ZERO + 1, + WMTTHERM_READ = WMTTHERM_ENABLE + 1, + WMTTHERM_DISABLE = WMTTHERM_READ + 1, + WMTTHERM_MAX +} ENUM_WMTTHERM_TYPE_T, *P_ENUM_WMTTHERM_TYPE_T; + +typedef enum _ENUM_WMTMSG_TYPE_T { + WMTMSG_TYPE_POWER_ON = 0, + WMTMSG_TYPE_POWER_OFF = 1, + WMTMSG_TYPE_RESET = 2, + WMTMSG_TYPE_STP_RDY = 3, + WMTMSG_TYPE_HW_FUNC_ON = 4, + WMTMSG_TYPE_MAX +} ENUM_WMTMSG_TYPE_T, *P_ENUM_WMTMSG_TYPE_T; + +typedef VOID(*PF_WMT_CB) (ENUM_WMTDRV_TYPE_T, /* Source driver type */ + ENUM_WMTDRV_TYPE_T, /* Destination driver type */ + ENUM_WMTMSG_TYPE_T, /* Message type */ + /* READ-ONLY buffer. Buffer is allocated and freed by WMT_drv. + * Client can't touch this buffer after this function return. + */ + PVOID, + UINT32 /* Buffer size in unit of byte */ + ); + +typedef enum _SDIO_PS_OP { + OWN_SET = 0, + OWN_CLR = 1, + OWN_STATE = 2, +} SDIO_PS_OP; + +typedef INT32(*PF_WMT_SDIO_PSOP) (SDIO_PS_OP); +typedef INT32(*PF_WMT_SDIO_DEEP_SLEEP)(MTK_WCN_BOOL); +typedef INT32(*PF_WMT_SDIO_DEBUG)(INT32, INT32, UINT32, UINT32); + + +typedef enum _ENUM_WMTCHIN_TYPE_T { + WMTCHIN_CHIPID = 0x0, + WMTCHIN_HWVER = WMTCHIN_CHIPID + 1, + WMTCHIN_MAPPINGHWVER = WMTCHIN_HWVER + 1, + WMTCHIN_FWVER = WMTCHIN_MAPPINGHWVER + 1, + WMTCHIN_IPVER = WMTCHIN_FWVER + 1, + WMTCHIN_ADIE = WMTCHIN_IPVER + 1, + WMTCHIN_MAX, +} ENUM_WMT_CHIPINFO_TYPE_T, *P_ENUM_WMT_CHIPINFO_TYPE_T; + +typedef enum _ENUM_WMT_FLASH_PATCH_CTRL_T { + WMT_FLASH_PATCH_VERSION_GET = 0, + WMT_FLASH_PATCH_DOWNLOAD = WMT_FLASH_PATCH_VERSION_GET + 1, + WMT_FLASH_PATCH_CTRL_MAX, +} ENUM_WMT_FLASH_PATCH_CTRL, *P_ENUM_WMT_FLASH_PATCH_CTRL; + +typedef enum _ENUM_WMT_FLASH_PATCH_SEQ_T { + WMT_FLASH_PATCH_HEAD_PKT = 0, + WMT_FLASH_PATCH_START_PKT = WMT_FLASH_PATCH_HEAD_PKT + 1, + WMT_FLASH_PATCH_CONTINUE_PKT = WMT_FLASH_PATCH_START_PKT + 1, + WMT_FLASH_PATCH_END_PKT = WMT_FLASH_PATCH_CONTINUE_PKT + 1, + WMT_FLASH_PATCH_SEQ_MAX, +} ENUM_WMT_FLASH_PATCH_SEQ, *P_ENUM_WMT_FLASH_PATCH_SEQ; + +typedef enum _ENUM_WMT_FLASH_PATCH_TYPE_T { + WMT_FLASH_PATCH_HIF_SW_EFUSE = 0, + WMT_FLASH_PATCH_GATT = WMT_FLASH_PATCH_HIF_SW_EFUSE + 1, + WMT_FLASH_PATCH_SYSROM = WMT_FLASH_PATCH_GATT + 1, + WMT_FLASH_PATCH_ILM = WMT_FLASH_PATCH_SYSROM + 1, + WMT_FLASH_PATCH_FLP1 = WMT_FLASH_PATCH_ILM + 1, + WMT_FLASH_PATCH_FLP2 = WMT_FLASH_PATCH_FLP1 + 1, + WMT_FLASH_PATCH_TYPE_MAX, +} ENUM_WMT_FLASH_PATCH_TYPE, *P_ENUM_WMT_FLASH_PATCH_TYPE; + +typedef enum _ENUM_WMT_FLASH_PATCH_STATUS_T { + WMT_FLASH_PATCH_VERSION_GET_OK = 0, + WMT_FLASH_PATCH_VERSION_GET_FAIL = WMT_FLASH_PATCH_VERSION_GET_OK + 1, + WMT_FLASH_PATCH_DOWNLOAD_OK = WMT_FLASH_PATCH_VERSION_GET_FAIL + 1, + WMT_FLASH_PATCH_DOWNLOAD_FAIL = WMT_FLASH_PATCH_DOWNLOAD_OK + 1, + WMT_FLASH_PATCH_PARA_ERR = WMT_FLASH_PATCH_DOWNLOAD_FAIL + 1, + WMT_FLASH_PATCH_OP_ERR = WMT_FLASH_PATCH_PARA_ERR + 1, + WMT_FLASH_PATCH_MAX +} ENUM_WMT_FLASH_PATCH_STATUS, *P_ENUM_WMT_FLASH_PATCH_STATUS; + +typedef MTK_WCN_BOOL(*MTK_WCN_WMT_FUNC_CTRL) (ENUM_WMTDRV_TYPE_T type); +typedef INT8(*MTK_WCN_WMT_THERM_CTRL) (ENUM_WMTTHERM_TYPE_T eType); +typedef ENUM_WMTHWVER_TYPE_T(*MTK_WCN_WMT_HWVER_GET) (VOID); +typedef MTK_WCN_BOOL(*MTK_WCN_WMT_DSNS_CTRL) (ENUM_WMTDSNS_TYPE_T eType); +typedef INT32(*MTK_WCN_WMT_MSGCB_REG) (ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb); +typedef INT32(*MTK_WCN_WMT_MSGCB_UNREG) (ENUM_WMTDRV_TYPE_T eType); +typedef INT32(*MTK_WCN_WMT_SDIO_OP_REG) (PF_WMT_SDIO_PSOP own_cb); +typedef INT32(*MTK_WCN_WMT_SDIO_HOST_AWAKE) (VOID); +typedef MTK_WCN_BOOL(*MTK_WCN_WMT_ASSERT) (ENUM_WMTDRV_TYPE_T type, UINT32 reason); +typedef MTK_WCN_BOOL(*MTK_WCN_WMT_ASSERT_TIMEOUT)(ENUM_WMTDRV_TYPE_T type, + UINT32 reason, INT32 timeout); +typedef UINT32(*MTK_WCN_WMT_IC_INFO_GET) (ENUM_WMT_CHIPINFO_TYPE_T type); +typedef INT32 (*MTK_WCN_WMT_PSM_CTRL)(MTK_WCN_BOOL flag); + +typedef ENUM_WMT_FLASH_PATCH_STATUS(*MTK_WCN_WMT_FLASH_PATCH_CTRL)(ENUM_WMT_FLASH_PATCH_CTRL ctrlId, + PUINT8 pBuf, UINT32 length, ENUM_WMT_FLASH_PATCH_SEQ seq, ENUM_WMT_FLASH_PATCH_TYPE type, + PUINT32 version, UINT32 checksum); + +typedef struct _MTK_WCN_WMT_EXP_CB_INFO_ { + MTK_WCN_WMT_FUNC_CTRL wmt_func_on_cb; + MTK_WCN_WMT_FUNC_CTRL wmt_func_off_cb; + MTK_WCN_WMT_THERM_CTRL wmt_therm_ctrl_cb; + MTK_WCN_WMT_HWVER_GET wmt_hwver_get_cb; + MTK_WCN_WMT_DSNS_CTRL wmt_dsns_ctrl_cb; + MTK_WCN_WMT_MSGCB_REG wmt_msgcb_reg_cb; + MTK_WCN_WMT_MSGCB_UNREG wmt_msgcb_unreg_cb; + MTK_WCN_WMT_SDIO_OP_REG wmt_sdio_op_reg_cb; + MTK_WCN_WMT_SDIO_HOST_AWAKE wmt_sdio_host_awake_cb; + MTK_WCN_WMT_ASSERT wmt_assert_cb; + MTK_WCN_WMT_ASSERT_TIMEOUT wmt_assert_timeout_cb; + MTK_WCN_WMT_IC_INFO_GET wmt_ic_info_get_cb; + MTK_WCN_WMT_PSM_CTRL wmt_psm_ctrl_cb; + MTK_WCN_WMT_FLASH_PATCH_CTRL wmt_flash_patch_ctrl_cb; +} MTK_WCN_WMT_EXP_CB_INFO, *P_MTK_WCN_WMT_EXP_CB_INFO; + +#endif + +typedef enum _ENUM_WMTRSTMSG_TYPE_T { + WMTRSTMSG_RESET_START = 0x0, + WMTRSTMSG_RESET_END = 0x1, + WMTRSTMSG_RESET_END_FAIL = 0x2, + WMTRSTMSG_RESET_MAX, + WMTRSTMSG_RESET_INVALID = 0xff +} ENUM_WMTRSTMSG_TYPE_T, *P_ENUM_WMTRSTMSG_TYPE_T; + +typedef enum _ENUM_BT_GPS_ONOFF_STATE_T { + WMT_BT_ON = 0, + WMT_GPS_ON = 1, + WMT_WIFI_ON = 2, + WMT_FM_ON = 3, + WMT_GPS_SUSPEND = 4, + WMT_GPSL5_ON = 5, + WMT_GPSL5_SUSPEND = 6, + WMT_BT_GPS_STATE_MAX, + WMT_BT_GPS_STATE_INVALID = 0xff +} ENUM_BT_GPS_ONOFF_STATE_T, *P_ENUM_BT_GPS_ONOFF_STATE_T; + +#if 1 /* moved from wmt_core.h */ +typedef enum { + WMT_SDIO_SLOT_INVALID = 0, + WMT_SDIO_SLOT_SDIO1 = 1, /* Wi-Fi dedicated SDIO1 */ + WMT_SDIO_SLOT_SDIO2 = 2, + WMT_SDIO_SLOT_MAX +} WMT_SDIO_SLOT_NUM; + +typedef enum { + WMT_SDIO_FUNC_STP = 0, + WMT_SDIO_FUNC_WIFI = 1, + WMT_SDIO_FUNC_MAX +} WMT_SDIO_FUNC_TYPE; +#endif + +typedef INT32(*wmt_wlan_probe_cb) (VOID); +typedef INT32(*wmt_wlan_remove_cb) (VOID); +typedef INT32(*wmt_wlan_bus_cnt_get_cb) (VOID); +typedef INT32(*wmt_wlan_bus_cnt_clr_cb) (VOID); +typedef INT32(*wmt_wlan_emi_mpu_set_protection_cb) (bool); +typedef INT32(*wmt_wlan_is_wifi_drv_own_cb) (VOID); + +typedef struct _MTK_WCN_WMT_WLAN_CB_INFO { + wmt_wlan_probe_cb wlan_probe_cb; + wmt_wlan_remove_cb wlan_remove_cb; + wmt_wlan_bus_cnt_get_cb wlan_bus_cnt_get_cb; + wmt_wlan_bus_cnt_clr_cb wlan_bus_cnt_clr_cb; + wmt_wlan_emi_mpu_set_protection_cb wlan_emi_mpu_set_protection_cb; + wmt_wlan_is_wifi_drv_own_cb wlan_is_wifi_drv_own_cb; +} MTK_WCN_WMT_WLAN_CB_INFO, *P_MTK_WCN_WMT_WLAN_CB_INFO; + +#ifdef CONFIG_MTK_COMBO_ANT +typedef enum _ENUM_WMT_ANT_RAM_CTRL_T { + WMT_ANT_RAM_GET_STATUS = 0, + WMT_ANT_RAM_DOWNLOAD = WMT_ANT_RAM_GET_STATUS + 1, + WMT_ANT_RAM_CTRL_MAX +} ENUM_WMT_ANT_RAM_CTRL, *P_ENUM_WMT_ANT_RAM_CTRL; + +typedef enum _ENUM_WMT_ANT_RAM_SEQ_T { + WMT_ANT_RAM_START_PKT = 1, + WMT_ANT_RAM_CONTINUE_PKT = WMT_ANT_RAM_START_PKT + 1, + WMT_ANT_RAM_END_PKT = WMT_ANT_RAM_CONTINUE_PKT + 1, + WMT_ANT_RAM_SEQ_MAX +} ENUM_WMT_ANT_RAM_SEQ, *P_ENUM_WMT_ANT_RAM_SEQ; + +typedef enum _ENUM_WMT_ANT_RAM_STATUS_T { + WMT_ANT_RAM_NOT_EXIST = 0, + WMT_ANT_RAM_EXIST = WMT_ANT_RAM_NOT_EXIST + 1, + WMT_ANT_RAM_DOWN_OK = WMT_ANT_RAM_EXIST + 1, + WMT_ANT_RAM_DOWN_FAIL = WMT_ANT_RAM_DOWN_OK + 1, + WMT_ANT_RAM_PARA_ERR = WMT_ANT_RAM_DOWN_FAIL + 1, + WMT_ANT_RAM_OP_ERR = WMT_ANT_RAM_PARA_ERR + 1, + WMT_ANT_RAM_MAX +} ENUM_WMT_ANT_RAM_STATUS, *P_ENUM_WMT_ANT_RAM_STATUS; +#endif + +extern INT32 mtk_wcn_wmt_wlan_reg(P_MTK_WCN_WMT_WLAN_CB_INFO pWmtWlanCbInfo); +extern INT32 mtk_wcn_wmt_wlan_unreg(VOID); +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ +extern wmt_wlan_probe_cb mtk_wcn_wlan_probe; +extern wmt_wlan_remove_cb mtk_wcn_wlan_remove; +extern wmt_wlan_bus_cnt_get_cb mtk_wcn_wlan_bus_tx_cnt; +extern wmt_wlan_bus_cnt_clr_cb mtk_wcn_wlan_bus_tx_cnt_clr; +extern wmt_wlan_emi_mpu_set_protection_cb mtk_wcn_wlan_emi_mpu_set_protection; +extern wmt_wlan_is_wifi_drv_own_cb mtk_wcn_wlan_is_wifi_drv_own; +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +/*subsystem function ctrl APIs*/ +extern MTK_WCN_BOOL mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason); + +#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT + +extern MTK_WCN_BOOL mtk_wcn_wmt_func_off(ENUM_WMTDRV_TYPE_T type); + +extern MTK_WCN_BOOL mtk_wcn_wmt_func_on(ENUM_WMTDRV_TYPE_T type); + +extern MTK_WCN_BOOL mtk_wcn_wmt_dsns_ctrl(ENUM_WMTDSNS_TYPE_T eType); + +extern MTK_WCN_BOOL mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason); + +extern MTK_WCN_BOOL mtk_wcn_wmt_assert_timeout(ENUM_WMTDRV_TYPE_T type, UINT32 reason, INT32 timeout); + +extern MTK_WCN_BOOL mtk_wcn_wmt_assert_keyword(ENUM_WMTDRV_TYPE_T type, PUINT8 keyword); + +extern MTK_WCN_BOOL mtk_wcn_wmt_do_reset(ENUM_WMTDRV_TYPE_T type); + +extern MTK_WCN_BOOL mtk_wcn_wmt_do_reset_only(ENUM_WMTDRV_TYPE_T type); + +extern INT32 mtk_wcn_wmt_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb); + +extern INT32 mtk_wcn_wmt_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType); + +extern INT32 mtk_wcn_stp_wmt_sdio_op_reg(PF_WMT_SDIO_PSOP own_cb); + +extern INT32 mtk_wcn_stp_wmt_sdio_host_awake(VOID); +/* +*return value: +*enable/disable thermal sensor function: true(1)/false(0) +*read thermal sensor function: thermal value +*/ +extern INT8 mtk_wcn_wmt_therm_ctrl(ENUM_WMTTHERM_TYPE_T eType); + +extern ENUM_WMTHWVER_TYPE_T mtk_wcn_wmt_hwver_get(VOID); + +extern UINT32 mtk_wcn_wmt_ic_info_get(ENUM_WMT_CHIPINFO_TYPE_T type); + + +extern INT32 mtk_wcn_wmt_chipid_query(VOID); + +extern INT32 mtk_wcn_wmt_psm_ctrl(MTK_WCN_BOOL flag); +extern ENUM_WMT_FLASH_PATCH_STATUS mtk_wcn_wmt_flash_patch_ctrl(ENUM_WMT_FLASH_PATCH_CTRL ctrlId, + PUINT8 pBuf, UINT32 length, ENUM_WMT_FLASH_PATCH_SEQ seq, ENUM_WMT_FLASH_PATCH_TYPE type, + PUINT32 version, UINT32 checksum); + +#endif +#ifdef CONFIG_MTK_COMBO_CHIP_DEEP_SLEEP_SUPPORT +extern INT32 mtk_wcn_wmt_sdio_deep_sleep_flag_cb_reg(PF_WMT_SDIO_DEEP_SLEEP flag_cb); +#endif +extern INT32 mtk_wcn_wmt_sdio_rw_cb_reg(PF_WMT_SDIO_DEBUG reg_rw_cb); + +#ifdef CONFIG_MTK_COMBO_ANT +extern ENUM_WMT_ANT_RAM_STATUS mtk_wcn_wmt_ant_ram_ctrl(ENUM_WMT_ANT_RAM_CTRL ctrlId, PUINT8 pBuf, + UINT32 length, ENUM_WMT_ANT_RAM_SEQ seq); +#endif +extern INT32 wmt_lib_set_aif(enum CMB_STUB_AIF_X aif, MTK_WCN_BOOL share); /* set AUDIO interface options */ +extern VOID wmt_lib_ps_irq_cb(VOID); + +extern VOID mtk_wcn_wmt_func_ctrl_for_plat(UINT32 on, ENUM_WMTDRV_TYPE_T type); + +extern INT32 mtk_wcn_wmt_system_state_reset(VOID); +extern MTK_WCN_BOOL mtk_wcn_set_connsys_power_off_flag(MTK_WCN_BOOL value); +#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT +extern VOID mtk_wcn_wmt_exp_init(VOID); +extern VOID mtk_wcn_wmt_exp_deinit(VOID); +#endif +extern INT8 mtk_wcn_wmt_co_clock_flag_get(VOID); +extern INT32 mtk_wcn_wmt_wifi_fem_cfg_report(PVOID pvInfoBuf); +extern VOID mtk_wcn_wmt_dump_wmtd_backtrace(VOID); +extern UINT32 mtk_wmt_get_gps_lna_pin_num(VOID); +extern VOID mtk_wmt_set_ext_ldo(UINT32 flag); +extern INT32 mtk_wmt_gps_mcu_ctrl(PUINT8 p_tx_data_buf, UINT32 tx_data_len, PUINT8 p_rx_data_buf, + UINT32 rx_data_buf_len, PUINT32 p_rx_data_len); +extern VOID mtk_wcn_wmt_set_mcif_mpu_protection(MTK_WCN_BOOL enable); +extern MTK_WCN_BOOL mtk_wmt_gps_suspend_ctrl(MTK_WCN_BOOL suspend); +extern MTK_WCN_BOOL mtk_wmt_gps_l1_suspend_ctrl(MTK_WCN_BOOL suspend); +extern MTK_WCN_BOOL mtk_wmt_gps_l5_suspend_ctrl(MTK_WCN_BOOL suspend); + +extern INT32 mtk_wcn_wmt_mpu_lock_aquire(VOID); +extern VOID mtk_wcn_wmt_mpu_lock_release(VOID); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _WMT_EXP_H_ */ diff --git a/drivers/misc/mediatek/connectivity/common/common_main/include/wmt_plat.h b/drivers/misc/mediatek/connectivity/common/common_main/include/wmt_plat.h new file mode 100644 index 0000000000000000000000000000000000000000..6f0113cf40b09fbfe35bc1ec40a027f9224eb1e9 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/include/wmt_plat.h @@ -0,0 +1,450 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#ifndef _WMT_PLAT_H_ +#define _WMT_PLAT_H_ +#include "osal_typedef.h" +#include "stp_exp.h" +#include +#include "mtk_wcn_cmb_hw.h" + +/* #include "mtk_wcn_consys_hw.h" */ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +#if 1 /* moved from wmt_exp.h */ +#ifndef DFT_TAG +#define DFT_TAG "[WMT-DFT]" +#endif + +#define WMT_PLAT_LOG_LOUD 4 +#define WMT_PLAT_LOG_DBG 3 +#define WMT_PLAT_LOG_INFO 2 +#define WMT_PLAT_LOG_WARN 1 +#define WMT_PLAT_LOG_ERR 0 + +extern INT32 wmtPlatLogLvl; + +#define WMT_PLAT_PR_LOUD(fmt, arg...) \ +do { \ + if (wmtPlatLogLvl >= WMT_PLAT_LOG_LOUD) \ + pr_info(DFT_TAG "[L]%s:" fmt, __func__, ##arg); \ +} while (0) +#define WMT_PLAT_PR_INFO(fmt, arg...) \ +do { \ + if (wmtPlatLogLvl >= WMT_PLAT_LOG_INFO) \ + pr_info(DFT_TAG "[I]%s:" fmt, __func__, ##arg); \ +} while (0) +#define WMT_PLAT_PR_WARN(fmt, arg...) \ +do { \ + if (wmtPlatLogLvl >= WMT_PLAT_LOG_WARN) \ + pr_warn(DFT_TAG "[W]%s:" fmt, __func__, ##arg); \ +} while (0) +#define WMT_PLAT_PR_ERR(fmt, arg...) \ +do { \ + if (wmtPlatLogLvl >= WMT_PLAT_LOG_ERR) \ + pr_err(DFT_TAG "[E]%s(%d):" fmt, __func__, __LINE__, ##arg); \ +} while (0) +#define WMT_PLAT_PR_DBG(fmt, arg...) \ +do { \ + if (wmtPlatLogLvl >= WMT_PLAT_LOG_DBG) \ + pr_info(DFT_TAG "[D]%s:" fmt, __func__, ##arg); \ +} while (0) + +#endif + +#define CFG_WMT_PS_SUPPORT 1 /* moved from wmt_exp.h */ + +#define CFG_WMT_DUMP_INT_STATUS 0 +#define CONSYS_ENALBE_SET_JTAG 1 + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +#if (defined(MT6630) || defined(MT6632)) +#define CONSYS_WMT_REG_SUSPEND_CB_ENABLE 1 +#else +#define CONSYS_WMT_REG_SUSPEND_CB_ENABLE 0 +#endif + +#if defined(MERGE_INTERFACE_SUPPORT) && (defined(MT6628) || defined(MT6630) || defined(MT6632)) +#define MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT 1 +#else +#define MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT 0 +#endif + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ +typedef enum _ENUM_PIN_ID_ { + PIN_LDO = 0, + PIN_PMU = 1, + PIN_RTC = 2, + PIN_RST = 3, + PIN_BGF_EINT = 4, + PIN_WIFI_EINT = 5, + PIN_ALL_EINT = 6, + PIN_UART_GRP = 7, + PIN_PCM_GRP = 8, + PIN_I2S_GRP = 9, + PIN_SDIO_GRP = 10, + PIN_GPS_SYNC = 11, + PIN_GPS_LNA = 12, + PIN_UART_RX = 13, +#if CFG_WMT_LTE_COEX_HANDLING + PIN_TDM_REQ = 14, +#endif + PIN_ID_MAX +} ENUM_PIN_ID, *P_ENUM_PIN_ID; +#if 0 +typedef enum _ENUM_PIN_ID_ { + PIN_BGF_EINT = 0, + PIN_I2S_GRP = 1, + PIN_GPS_SYNC = 2, + PIN_GPS_LNA = 3, +#if CFG_WMT_LTE_COEX_HANDLING + PIN_TDM_REQ = 4, +#endif + PIN_ID_MAX +} ENUM_PIN_ID, *P_ENUM_PIN_ID; +#endif + +typedef enum _ENUM_FUNC_STATE_ { + FUNC_ON = 0, + FUNC_OFF = 1, + FUNC_RST = 2, + FUNC_STAT = 3, + FUNC_CTRL_MAX, +} ENUM_FUNC_STATE, *P_ENUM_FUNC_STATE; + +typedef enum _ENUM_PIN_STATE_ { + PIN_STA_INIT = 0, + PIN_STA_OUT_L = 1, + PIN_STA_OUT_H = 2, + PIN_STA_IN_L = 3, + PIN_STA_MUX = 4, + PIN_STA_EINT_EN = 5, + PIN_STA_EINT_DIS = 6, + PIN_STA_DEINIT = 7, + PIN_STA_SHOW = 8, + PIN_STA_IN_PU = 9, + PIN_STA_IN_NP = 10, + PIN_STA_IN_H = 11, + PIN_STA_MAX +} ENUM_PIN_STATE, *P_ENUM_PIN_STATE; + +typedef enum _CMB_IF_TYPE_ { + CMB_IF_UART = 0, + CMB_IF_WIFI_SDIO = 1, + CMB_IF_BGF_SDIO = 2, + CMB_IF_BGWF_SDIO = 3, + CMB_IF_TYPE_MAX +} CMB_IF_TYPE, *P_CMB_IF_TYPE; + +typedef INT32(*fp_set_pin) (ENUM_PIN_STATE); + +typedef enum _ENUM_WL_OP_ { + WL_OP_GET = 0, + WL_OP_PUT = 1, + WL_OP_MAX +} ENUM_WL_OP, *P_ENUM_WL_OP; + +typedef enum _ENUM_PALDO_TYPE_ { + BT_PALDO = 0, + WIFI_PALDO = 1, + FM_PALDO = 2, + GPS_PALDO = 3, + PMIC_CHIPID_PALDO = 4, + WIFI_5G_PALDO = 5, + EFUSE_PALDO = 6, + PALDO_TYPE_MAX +} ENUM_PALDO_TYPE, *P_ENUM_PALDO_TYPE; + +typedef enum _ENUM_PALDO_OP_ { + PALDO_OFF = 0, + PALDO_ON = 1, + PALDO_OP_MAX +} ENUM_PALDO_OP, *P_ENUM_PALDO_OP; + +typedef enum _ENUM_HOST_DUMP_STATE_T { + STP_HOST_DUMP_NOT_START = 0, + STP_HOST_DUMP_GET = 1, + STP_HOST_DUMP_GET_DONE = 2, + STP_HOST_DUMP_END = 3, + STP_HOST_DUMP_MAX +} ENUM_HOST_DUMP_STATE, *P_ENUM_HOST_DUMP_STATE_T; + +typedef enum _ENUM_FORCE_TRG_ASSERT_T { + STP_FORCE_TRG_ASSERT_EMI = 0, + STP_FORCE_TRG_ASSERT_DEBUG_PIN = 1, + STP_FORCE_TRG_ASSERT_MAX = 2 +} ENUM_FORCE_TRG_ASSERT_T, *P_ENUM_FORCE_TRG_ASSERT_T; + +typedef enum _ENUM_CHIP_DUMP_STATE_T { + STP_CHIP_DUMP_NOT_START = 0, + STP_CHIP_DUMP_PUT = 1, + STP_CHIP_DUMP_PUT_DONE = 2, + STP_CHIP_DUMP_END = 3, + STP_CHIP_DUMP_MAX +} ENUM_CHIP_DUMP_STATE, *P_ENUM_CHIP_DUMP_STATE_T; + +#define CONSYS_BUS_CLK_STATUS_OFFSET 0x00000100 +#define CONSYS_CPU_CLK_STATUS_OFFSET 0x0000010c +#define CONSYS_DBG_CR1_OFFSET 0x00000408 +#define CONSYS_DBG_CR2_OFFSET 0x0000040c +typedef enum _ENUM_CONNSYS_DEBUG_CR { + CONNSYS_CPU_CLK = 0, + CONNSYS_BUS_CLK = 1, + CONNSYS_DEBUG_CR1 = 2, + CONNSYS_DEBUG_CR2 = 3, + CONNSYS_EMI_REMAP = 4, + CONNSYS_CR_MAX +} ENUM_CONNSYS_DEBUG_CR, *P_ENUM_CONNSYS_DEBUG_CR; + +typedef enum { + WMT_SLEEP_COUNT_TOP = 0, + WMT_SLEEP_COUNT_MCU = 1, + WMT_SLEEP_COUNT_BT = 2, + WMT_SLEEP_COUNT_WF = 3, + WMT_SLEEP_COUNT_GPS = 4, + WMT_SLEEP_COUNT_MAX +} WMT_SLEEP_COUNT_TYPE; + +typedef enum { + WMT_ERRCODE_SUCCESS = 0, + WMT_ERRCODE_ALREADY_ON, + WMT_ERRCODE_ALREADY_OFF, + WMT_ERRCODE_READYTO_OFF, + WMT_ERRCODE_EMI_NOT_READY, + WMT_ERRCODE_GPIO_CTRL_FAIL, + WMT_ERRCODE_POLL_CHIPID_FAIL, + WMT_ERRCODE_POLL_NOT_GOTO_IDLE, + WMT_ERRCODE_NO_HIF_INFO, + WMT_ERRCODE_SDIO_SLOT_SDIO2_FAIL, + WMT_ERRCODE_SDIO_FUNC_STP_FAIL, + WMT_ERRCODE_OPEN_STP_FAIL, + WMT_ERRCODE_UART_BAUDRATE_FAIL, + WMT_ERRCODE_STP_CONFIG_FAIL, + WMT_ERRCODE_HW_CHECK_FAIL, + WMT_ERRCODE_VER_CHECK_FAIL, + WMT_ERRCODE_CHIPID_NOT_SUPPORT, + WMT_ERRCODE_NULL_FUNC_POINTER, + WMT_ERRCODE_PATCH_INFO_FAIL, + WMT_ERRCODE_PATCH_DWN_FAIL, + WMT_ERRCODE_ADIE_NOT_EXIST, + WMT_ERRCODE_INIT_TABLE_FAIL, + WMT_ERRCODE_INIT_DLM_TABLE_FAIL, + WMT_ERRCODE_INIT_MCUCLK_TABLE_FAIL, + WMT_ERRCODE_INIT_RESET_CMD_FAIL, + WMT_ERRCODE_INIT_COCLOCK_TYPE_FAIL, + WMT_ERRCODE_INIT_MERGE_PCM_TABLE_FAIL, + WMT_ERRCODE_INIT_FM_MODE_FAIL, + WMT_ERRCODE_INIT_SET_REGISTER_FAIL, + WMT_ERRCODE_INIT_SET_COREDUMP_FAIL, + WMT_ERRCODE_INIT_WIFI_CONFIG_FAIL, + WMT_ERRCODE_INIT_WIFI_ANT_SWAP_FAIL, + WMT_ERRCODE_INIT_EPA_FAIL, + WMT_ERRCODE_INIT_EPA_ELNA_FAIL, + WMT_ERRCODE_INIT_EPA_ELNA_INVERT_CR_FAIL, + WMT_ERRCODE_INIT_COEX_FAIL, + WMT_ERRCODE_CALIBRATION_FAIL, + WMT_ERRCODE_READ_ADIE_TX_CMD_FAIL, + WMT_ERRCODE_READ_ADIE_RX_EVT_FAIL, + WMT_ERRCODE_READ_PMIC_CHIPID_FAIL, + WMT_ERRCODE_SET_STP_DBG_INFO_FAIL, + /* return error code for WMT */ + WMT_ERRCODE_MAX +} WMT_ERRCODE_TYPE; + +typedef struct _EMI_CTRL_STATE_OFFSET_ { + UINT32 emi_apmem_ctrl_state; + UINT32 emi_apmem_ctrl_host_sync_state; + UINT32 emi_apmem_ctrl_host_sync_num; + UINT32 emi_apmem_ctrl_chip_sync_state; + UINT32 emi_apmem_ctrl_chip_sync_num; + UINT32 emi_apmem_ctrl_chip_sync_addr; + UINT32 emi_apmem_ctrl_chip_sync_len; + UINT32 emi_apmem_ctrl_chip_print_buff_start; + UINT32 emi_apmem_ctrl_chip_print_buff_len; + UINT32 emi_apmem_ctrl_chip_print_buff_idx; + UINT32 emi_apmem_ctrl_chip_int_status; + UINT32 emi_apmem_ctrl_chip_paded_dump_end; + UINT32 emi_apmem_ctrl_host_outband_assert_w1; + UINT32 emi_apmem_ctrl_chip_page_dump_num; + UINT32 emi_apmem_ctrl_assert_flag; + UINT32 emi_apmem_ctrl_chip_check_sleep; +} EMI_CTRL_STATE_OFFSET, *P_EMI_CTRL_STATE_OFFSET; + +typedef struct _BGF_IRQ_BALANCE_ { + UINT32 counter; + unsigned long flags; + spinlock_t lock; +} BGF_IRQ_BALANCE, *P_BGF_IRQ_BALANCE; + +typedef struct _CONSYS_EMI_ADDR_INFO_ { + UINT32 emi_phy_addr; + UINT32 emi_ap_phy_addr; + UINT32 paged_trace_off; + UINT32 paged_dump_off; + UINT32 full_dump_off; + UINT32 emi_remap_offset; + P_EMI_CTRL_STATE_OFFSET p_ecso; + UINT32 emi_size; + UINT32 pda_dl_patch_flag; + UINT32 emi_met_size; + UINT32 emi_met_data_offset; + UINT32 emi_core_dump_offset; + UINT32 emi_direct_path_ap_phy_addr; + UINT32 emi_direct_path_size; + UINT32 emi_ram_bt_buildtime_offset; + UINT32 emi_ram_wifi_buildtime_offset; + UINT32 emi_ram_mcu_buildtime_offset; + UINT32 emi_patch_mcu_buildtime_offset; +} CONSYS_EMI_ADDR_INFO, *P_CONSYS_EMI_ADDR_INFO; + +typedef struct _GPIO_TDM_REQ_INFO_ { + UINT32 ant_sel_index; + UINT32 gpio_number; + UINT32 cr_address; +} GPIO_TDM_REQ_INFO, *P_GPIO_TDM_REQ_INFO; + +struct consys_sw_state { + UINT16 clock_hif_ctrl; + UINT16 clock_umac_ctrl; + UINT32 resource_disable_sleep; + UINT32 clock_mcu; + UINT32 info_time; + UINT8 is_gating; + UINT8 sub_system; +}; + +typedef struct consys_state { + UINT32 lp[2]; + UINT32 gating[2]; + UINT64 sleep_counter[WMT_SLEEP_COUNT_MAX]; + UINT64 sleep_timer[WMT_SLEEP_COUNT_MAX]; + struct consys_sw_state sw_state; +} CONSYS_STATE, *P_CONSYS_STATE; + + +typedef VOID(*irq_cb) (VOID); +typedef INT32(*device_audio_if_cb) (enum CMB_STUB_AIF_X aif, MTK_WCN_BOOL share); +typedef VOID(*func_ctrl_cb) (UINT32 on, UINT32 type); +typedef long (*thermal_query_ctrl_cb) (VOID); +typedef INT32(*trigger_assert_cb) (UINT32 type, UINT32 reason); +typedef INT32(*deep_idle_ctrl_cb) (UINT32); + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ +extern INT32 gWmtDbgLvl; +extern struct device *wmt_dev; +#ifdef CFG_WMT_READ_EFUSE_VCN33 +extern INT32 wmt_set_pmic_voltage(UINT32 level); +#endif +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +INT32 wmt_plat_init(P_PWR_SEQ_TIME pPwrSeqTime, UINT32 co_clock_type); +INT32 wmt_plat_deinit(VOID); +INT32 wmt_plat_merge_if_flag_get(VOID); +INT32 wmt_plat_set_comm_if_type(ENUM_STP_TX_IF_TYPE type); +INT32 wmt_plat_merge_if_flag_ctrl(UINT32 enagle); +ENUM_STP_TX_IF_TYPE wmt_plat_get_comm_if_type(VOID); + +INT32 wmt_plat_pwr_ctrl(ENUM_FUNC_STATE state); + +INT32 wmt_plat_gpio_ctrl(ENUM_PIN_ID id, ENUM_PIN_STATE state); + +INT32 wmt_plat_eirq_ctrl(ENUM_PIN_ID id, ENUM_PIN_STATE state); + +INT32 wmt_plat_wake_lock_ctrl(ENUM_WL_OP opId); +INT32 wmt_plat_sdio_ctrl(UINT32 sdioPortNum, ENUM_FUNC_STATE on); + +INT32 wmt_plat_audio_ctrl(enum CMB_STUB_AIF_X state, enum CMB_STUB_AIF_CTRL ctrl); +VOID wmt_lib_plat_irq_cb_reg(irq_cb bgf_irq_cb); +VOID wmt_lib_plat_aif_cb_reg(device_audio_if_cb aif_ctrl_cb); + +VOID wmt_plat_irq_cb_reg(irq_cb bgf_irq_cb); +VOID wmt_plat_aif_cb_reg(device_audio_if_cb aif_ctrl_cb); +VOID wmt_plat_func_ctrl_cb_reg(func_ctrl_cb subsys_func_ctrl); +VOID wmt_plat_thermal_ctrl_cb_reg(thermal_query_ctrl_cb thermal_query_ctrl); +VOID wmt_plat_trigger_assert_cb_reg(trigger_assert_cb trigger_assert); +VOID wmt_plat_deep_idle_ctrl_cb_reg(deep_idle_ctrl_cb deep_idle_ctrl); + +INT32 wmt_plat_soc_paldo_ctrl(ENUM_PALDO_TYPE ePt, ENUM_PALDO_OP ePo); +UINT8 *wmt_plat_get_emi_virt_add(UINT32 offset); +#if CONSYS_ENALBE_SET_JTAG +UINT32 wmt_plat_jtag_flag_ctrl(UINT32 en); +#endif +#if CFG_WMT_DUMP_INT_STATUS +VOID wmt_plat_BGF_irq_dump_status(VOID); +MTK_WCN_BOOL wmt_plat_dump_BGF_irq_status(VOID); +#endif +P_CONSYS_EMI_ADDR_INFO wmt_plat_get_emi_phy_add(VOID); +UINT32 wmt_plat_read_cpupcr(VOID); +UINT32 wmt_plat_read_dmaregs(UINT32); +INT32 wmt_plat_set_host_dump_state(ENUM_HOST_DUMP_STATE state); +UINT32 wmt_plat_force_trigger_assert(ENUM_FORCE_TRG_ASSERT_T type); +INT32 wmt_plat_update_host_sync_num(VOID); +INT32 wmt_plat_get_dump_info(UINT32 offset); +INT32 wmt_plat_write_emi_l(UINT32 offset, UINT32 value); +UINT32 wmt_plat_get_soc_chipid(VOID); +INT32 wmt_plat_get_adie_chipid(VOID); +UINT32 wmt_plat_soc_co_clock_flag_get(VOID); +INT32 wmt_plat_set_dbg_mode(UINT32 flag); +INT32 wmt_plat_set_dynamic_dumpmem(PUINT32 buf); +#if CFG_WMT_LTE_COEX_HANDLING +INT32 wmt_plat_get_tdm_antsel_index(VOID); +#endif +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _WMT_PLAT_H_ */ diff --git a/drivers/misc/mediatek/connectivity/common/common_main/include/wmt_plat_stub.h b/drivers/misc/mediatek/connectivity/common/common_main/include/wmt_plat_stub.h new file mode 100644 index 0000000000000000000000000000000000000000..59d30fa735a2efc6bc31323f3be1b7195e561f0b --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/include/wmt_plat_stub.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + + +#ifndef _WMT_PLAT_STUB_H_ +#define _WMT_PLAT_STUB_H_ + + +INT32 wmt_plat_audio_ctrl(enum CMB_STUB_AIF_X state, enum CMB_STUB_AIF_CTRL ctrl); + +INT32 wmt_plat_stub_init(VOID); + +#endif /*_WMT_PLAT_STUB_H_*/ diff --git a/drivers/misc/mediatek/connectivity/common/common_main/linux/bgw_desense.c b/drivers/misc/mediatek/connectivity/common/common_main/linux/bgw_desense.c new file mode 100644 index 0000000000000000000000000000000000000000..35d6a7c6a00e16d5c5a403cfa5ffcb162ba68137 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/linux/bgw_desense.c @@ -0,0 +1,141 @@ +/* +* Copyright (C) 2011-2014 MediaTek Inc. +* +* This program is free software: you can redistribute it and/or modify it under the terms of the +* GNU General Public License version 2 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. +* +* You should have received a copy of the GNU General Public License along with this program. +* If not, see . +*/ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include "bgw_desense.h" + +static struct sock *g_nl_sk; +/* static struct sockaddr_nl src_addr, des_addr; */ +/* static struct iovec iov; */ +static int pid; +/* static struct msghdr msg; */ + +void bgw_destroy_netlink_kernel(void) +{ + if (g_nl_sk != NULL) { + /* sock_release(g_nl_sk->sk_socket); */ + netlink_kernel_release(g_nl_sk); + MSG("release socket\n"); + return; + } + ERR("no socket yet\n"); +} + +void send_command_to_daemon(const int command /*struct sk_buff *skb */) +{ + struct nlmsghdr *nlh = NULL; + struct sk_buff *nl_skb = NULL; + int res; + + MSG("here we will send command to native daemon\n"); + if (!g_nl_sk) { + ERR("invalid socket\n"); + return; + } + if (pid == 0) { + ERR("invalid native process pid\n"); + return; + } + /*alloc data buffer for sending to native */ + /*malloc data space at least 1500 bytes, which is ethernet data length */ + nl_skb = alloc_skb(NLMSG_SPACE(MAX_NL_MSG_LEN), GFP_ATOMIC); + if (nl_skb == NULL) { + ERR("malloc skb error\n"); + return; + } + MSG("malloc data space done\n"); + +/* nlh = NLMSG_PUT(nl_skb, 0, 0, 0, NLMSG_SPACE(1500)-sizeof(struct nlmsghdr)); */ + nlh = nlmsg_put(nl_skb, 0, 0, 0, MAX_NL_MSG_LEN, 0); + if (nlh == NULL) { + MSG("nlh is NULL\n"); + kfree_skb(nl_skb); + return; + } + NETLINK_CB(nl_skb).portid = 0; + +/* memcpy(NLMSG_DATA(nlh), ACK, 5); */ + *(char *)NLMSG_DATA(nlh) = command; + res = netlink_unicast(g_nl_sk, nl_skb, pid, MSG_DONTWAIT); + if (res == 0) { + MSG("send to user space process error\n"); + return; + } + ERR("send to user space process done, data length = %d\n", res); +} + +static void nl_data_handler(struct sk_buff *__skb) +{ + struct sk_buff *skb = NULL; + struct nlmsghdr *nlh = NULL; + int i; + int len; + char str[128]; + + MSG("we got netlink message\n"); + len = NLMSG_SPACE(MAX_NL_MSG_LEN); + skb = skb_get(__skb); + if (skb == NULL) { + ERR("skb_get return NULL"); + return; + } + if (skb->len >= NLMSG_SPACE(0)) { /*presume there is 5byte payload at leaset */ + MSG("length is enough\n"); + nlh = nlmsg_hdr(skb); /* point to data which include in skb */ + memcpy(str, NLMSG_DATA(nlh), sizeof(str)); + for (i = 0; i < 3; i++) + MSG("str[%d = %c]", i, str[i]); + MSG("str[0] = %d, str[1] = %d, str[2] = %d\n", str[0], str[1], str[2]); + if (str[0] == 'B' && str[1] == 'G' && str[2] == 'W') { + MSG("got native daemon init command, record it's pid\n"); + pid = nlh->nlmsg_pid; /*record the native process PID */ + MSG("native daemon pid is %d\n", pid); + } else { + ERR("this is not BGW message, ignore it\n"); + return; + } + } else { + ERR("not engouth data length\n"); + return; + } + + kfree_skb(skb); + + send_command_to_daemon(ACK); +} + +int bgw_init_socket(void) +{ + struct netlink_kernel_cfg cfg; + + memset(&cfg, 0, sizeof(cfg)); + cfg.input = nl_data_handler; + + g_nl_sk = __netlink_kernel_create(&init_net, NETLINK_TEST, THIS_MODULE, &cfg); + + if (g_nl_sk == NULL) { + ERR("netlink_kernel_create error\n"); + return -1; + } + MSG("netlink_kernel_create ok\n"); + return 0; +} diff --git a/drivers/misc/mediatek/connectivity/common/common_main/linux/fw_log_wmt.c b/drivers/misc/mediatek/connectivity/common/common_main/linux/fw_log_wmt.c new file mode 100644 index 0000000000000000000000000000000000000000..bf495f83f06ed25a0bf173a0d34fa0763650e26d --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/linux/fw_log_wmt.c @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH +#include "fw_log_wmt.h" +#include "connsys_debug_utility.h" +#include +#include +#include +#include +#include "wmt_lib.h" + +#define DRIVER_NAME "fw_log_wmt" +#define WMT_FW_LOG_IOC_MAGIC 0xfc +#define WMT_FW_LOG_IOCTL_ON_OFF _IOW(WMT_FW_LOG_IOC_MAGIC, 0, int) +#define WMT_FW_LOG_IOCTL_SET_LEVEL _IOW(WMT_FW_LOG_IOC_MAGIC, 1, int) + +static dev_t gDevId; +static struct cdev gLogCdev; +static struct class *fw_log_wmt_class; +static struct device *fw_log_wmt_dev; +static wait_queue_head_t wq; + +static int fw_log_wmt_open(struct inode *inode, struct file *file) +{ + pr_info("%s\n", __func__); + return 0; +} + +static int fw_log_wmt_close(struct inode *inode, struct file *file) +{ + pr_info("%s\n", __func__); + return 0; +} + +static ssize_t fw_log_wmt_read(struct file *filp, char __user *buf, + size_t count, loff_t *f_pos) +{ + ssize_t size = 0; + + pr_debug("%s\n", __func__); + size = connsys_log_read_to_user(CONNLOG_TYPE_MCU, buf, count); + return size; +} + +static ssize_t fw_log_wmt_write(struct file *filp, const char __user *buf, + size_t count, loff_t *f_pos) +{ + pr_debug("%s\n", __func__); + return 0; +} + +static unsigned int fw_log_wmt_poll(struct file *filp, poll_table *wait) +{ + pr_debug("%s\n", __func__); + + poll_wait(filp, &wq, wait); + if (connsys_log_get_buf_size(CONNLOG_TYPE_MCU) > 0) + return POLLIN | POLLRDNORM; + + return 0; +} + +static long fw_log_wmt_unlocked_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) +{ + long ret = 0; + + switch (cmd) { + case WMT_FW_LOG_IOCTL_ON_OFF: + pr_debug("ioctl: WMT_FW_LOG_IOCTL_ON_OFF(%lu)", arg); + if (arg == 0 || arg == 1) + wmt_lib_fw_log_ctrl(WMT_FWLOG_MCU, (unsigned char)arg, 0xFF); + break; + case WMT_FW_LOG_IOCTL_SET_LEVEL: + pr_debug("ioctl: WMT_FW_LOG_IOCTL_SET_LEVEL(%lu)", arg); + if (arg <= 4) + wmt_lib_fw_log_ctrl(WMT_FWLOG_MCU, 0xFF, (unsigned char)arg); + break; + default: + /*no action*/ + break; + } + return ret; +} + +#ifdef CONFIG_COMPAT +static long fw_log_wmt_compat_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) +{ + return fw_log_wmt_unlocked_ioctl(filp, cmd, arg); +} +#endif + +const struct file_operations gLogFops = { + .open = fw_log_wmt_open, + .release = fw_log_wmt_close, + .read = fw_log_wmt_read, + .write = fw_log_wmt_write, + .poll = fw_log_wmt_poll, + .unlocked_ioctl = fw_log_wmt_unlocked_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = fw_log_wmt_compat_ioctl, +#endif +}; + +static void fw_log_wmt_event_cb(void) +{ + wake_up_interruptible(&wq); +} + +int fw_log_wmt_init(void) +{ + int cdevErr = -1; + int ret = -1; + + ret = alloc_chrdev_region(&gDevId, 0, 1, DRIVER_NAME); + if (ret) + pr_err("fail to alloc_chrdev_region\n"); + + cdev_init(&gLogCdev, &gLogFops); + gLogCdev.owner = THIS_MODULE; + + cdevErr = cdev_add(&gLogCdev, gDevId, 1); + if (cdevErr) { + pr_err("cdev_add() fails (%d)\n", cdevErr); + goto error; + } + + fw_log_wmt_class = class_create(THIS_MODULE, DRIVER_NAME); + if (IS_ERR(fw_log_wmt_class)) { + pr_err("class_create fail\n"); + goto error; + } + + fw_log_wmt_dev = device_create(fw_log_wmt_class, NULL, gDevId, NULL, + DRIVER_NAME); + if (IS_ERR(fw_log_wmt_dev)) { + pr_err("device_create fail\n"); + goto error; + } + + init_waitqueue_head(&wq); + ret = connsys_log_init(CONNLOG_TYPE_MCU); + if (ret) + pr_err("fail to connsys_log_init\n"); + + ret = connsys_log_register_event_cb(CONNLOG_TYPE_MCU, + fw_log_wmt_event_cb); + if (ret) + pr_err("fail to connsys_log_register_event_cb\n"); + + return 0; + +error: + if (!(IS_ERR(fw_log_wmt_dev))) + device_destroy(fw_log_wmt_class, gDevId); + if (!(IS_ERR(fw_log_wmt_class))) { + class_destroy(fw_log_wmt_class); + fw_log_wmt_class = NULL; + } + + if (cdevErr == 0) + cdev_del(&gLogCdev); + if (ret == 0) + unregister_chrdev_region(gDevId, 1); + pr_err("fw_log_wmt_init fail\n"); + return -1; +} +EXPORT_SYMBOL(fw_log_wmt_init); + +void fw_log_wmt_deinit(void) +{ + connsys_log_deinit(CONNLOG_TYPE_MCU); + if (fw_log_wmt_dev) { + device_destroy(fw_log_wmt_class, gDevId); + fw_log_wmt_dev = NULL; + } + + if (fw_log_wmt_class) { + class_destroy(fw_log_wmt_class); + fw_log_wmt_class = NULL; + } + + cdev_del(&gLogCdev); + unregister_chrdev_region(gDevId, 1); + pr_warn("fw_log_wmt_driver_deinit done\n"); +} +EXPORT_SYMBOL(fw_log_wmt_deinit); +#endif diff --git a/drivers/misc/mediatek/connectivity/common/common_main/linux/hif_sdio.c b/drivers/misc/mediatek/connectivity/common/common_main/linux/hif_sdio.c new file mode 100644 index 0000000000000000000000000000000000000000..207064aa7f87ecab8bd5107f3dfce02bc94b9283 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/linux/hif_sdio.c @@ -0,0 +1,2924 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +/* + * + * 07 25 2010 george.kuo + * + * Move hif_sdio driver to linux directory. + * + * 07 23 2010 george.kuo + * + * Add MT6620 driver source tree + * , including char device driver (wmt, bt, gps), stp driver, + * interface driver (tty ldisc and hif_sdio), and bt hci driver. +** +** +*/ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ +#define HIF_SDIO_UPDATE (1) +#define HIF_SDIO_SUPPORT_SUSPEND (1) +#define HIF_SDIO_SUPPORT_WAKEUP (0) + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +#include +#include "hif_sdio.h" +#include "wmt_gpio.h" +/* #include "hif_sdio_chrdev.h" */ +#include +#include +#include + +#define mmc_power_up_ext(x) +#define mmc_power_off_ext(x) +MTK_WCN_BOOL g_hif_deep_sleep_flag = MTK_WCN_BOOL_FALSE; + +#ifndef MMC_CARD_REMOVED +#define MMC_CARD_REMOVED (1<<4) +#endif + +#ifndef mmc_card_removed +#define mmc_card_removed(c) ((c) && ((c)->state & MMC_CARD_REMOVED)) +#endif +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ +/* #define DRV_NAME "[hif_sdio]" */ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +#if HIF_SDIO_SUPPORT_SUSPEND +static INT32 hif_sdio_suspend(struct device *dev); + +static INT32 hif_sdio_resume(struct device *dev); +#endif +static INT32 hif_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id); + +static VOID hif_sdio_remove(struct sdio_func *func); + +static VOID hif_sdio_irq(struct sdio_func *func); + +static _osal_inline_ INT32 hif_sdio_clt_probe_func(MTK_WCN_HIF_SDIO_REGISTINFO *registinfo_p, + INT8 probe_idx); + +static VOID hif_sdio_clt_probe_worker(struct work_struct *work); + +static _osal_inline_ INT32 hif_sdio_find_probed_list_index_by_func(struct sdio_func *func); + +#if 0 /* TODO:[ChangeFeature][George] remove obsolete function? */ +static INT32 hif_sdio_find_probed_list_index_by_clt_index(INT32 clt_index); +#endif + +static _osal_inline_ INT32 hif_sdio_find_probed_list_index_by_id_func(UINT16 vendor, UINT16 device, + UINT16 func_num); + +static _osal_inline_ VOID hif_sdio_init_clt_list(INT32 index); + +static _osal_inline_ INT32 hif_sdio_find_clt_list_index(UINT16 vendor, UINT16 device, UINT16 func_num); + +static _osal_inline_ INT32 hif_sdio_check_supported_sdio_id(UINT16 vendor, UINT16 device); + +static _osal_inline_ INT32 hif_sdio_check_duplicate_sdio_id(UINT16 vendor, UINT16 device, UINT16 func_num); + +static _osal_inline_ INT32 hif_sdio_add_clt_list(PINT32 clt_index_p, const MTK_WCN_HIF_SDIO_CLTINFO *pinfo, + UINT32 tbl_index); + +static _osal_inline_ INT32 hif_sdio_stp_on(VOID); + +static _osal_inline_ INT32 hif_sdio_stp_off(VOID); + +static _osal_inline_ INT32 hif_sdio_wifi_on(VOID); + +static _osal_inline_ INT32 hif_sdio_wifi_off(VOID); + +static _osal_inline_ INT32 hif_sdio_deep_sleep_info_init(VOID); + +static _osal_inline_ INT32 hif_sdio_deep_sleep_info_set_act(UINT32 chipid, UINT16 func_num, + MTK_WCN_HIF_SDIO_CLTCTX ctx, UINT8 act_flag); + +static INT32 _hif_sdio_wake_up_ctrl(MTK_WCN_HIF_SDIO_CLTCTX ctx); + +static _osal_inline_ INT32 wmt_tra_sdio_update(VOID); + +static _osal_inline_ INT32 hif_sdio_deep_sleep_info_dmp(MTK_WCN_HIF_SDIO_DS_INFO *p_ds_info); + +static _osal_inline_ VOID hif_sdio_dump_probe_list(VOID); + +static _osal_inline_ VOID hif_sdio_init_probed_list(INT32 index); + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/* Supported SDIO device table */ +static const struct sdio_device_id mtk_sdio_id_tbl[] = { + /* MT6618 *//* Not an SDIO standard class device */ + {SDIO_DEVICE(0x037A, 0x018A)}, /* SDIO1:WIFI */ + {SDIO_DEVICE(0x037A, 0x018B)}, /* SDIO2:FUNC1:BT+FM */ + {SDIO_DEVICE(0x037A, 0x018C)}, /* 2-function (SDIO2:FUNC1:BT+FM, FUNC2:WIFI) */ + + /* MT6619 *//* Not an SDIO standard class device */ + {SDIO_DEVICE(0x037A, 0x6619)}, /* SDIO2:FUNC1:BT+FM+GPS */ + + /* MT6620 *//* Not an SDIO standard class device */ + {SDIO_DEVICE(0x037A, 0x020A)}, /* SDIO1:FUNC1:WIFI */ + {SDIO_DEVICE(0x037A, 0x020B)}, /* SDIO2:FUNC1:BT+FM+GPS */ + {SDIO_DEVICE(0x037A, 0x020C)}, /* 2-function (SDIO2:FUNC1:BT+FM+GPS, FUNC2:WIFI) */ + + /* MT5921 *//* Not an SDIO standard class device */ + {SDIO_DEVICE(0x037A, 0x5921)}, + + /* MT6628 *//* SDIO1: Wi-Fi, SDIO2: BGF */ + {SDIO_DEVICE(0x037A, 0x6628)}, + + /* MT6630 *//* SDIO1: Wi-Fi, SDIO2: BGF */ + {SDIO_DEVICE(0x037A, 0x6630)}, + + /* MT6632 *//* SDIO1: Wi-Fi */ + {SDIO_DEVICE(0x037A, 0x6602)}, + + /* MT6632 *//* SDIO2: BGF */ + {SDIO_DEVICE(0x037A, 0x6632)}, + + { /* end: all zeroes */ }, +}; + +#if HIF_SDIO_SUPPORT_SUSPEND +static const struct dev_pm_ops mtk_sdio_pmops = { + .suspend = hif_sdio_suspend, + .resume = hif_sdio_resume, +}; +#endif + +static struct sdio_driver mtk_sdio_client_drv = { + .name = "mtk_sdio_client", /* MTK SDIO Client Driver */ + .id_table = mtk_sdio_id_tbl, /* all supported struct sdio_device_id table */ + .probe = hif_sdio_probe, + .remove = hif_sdio_remove, +#if HIF_SDIO_SUPPORT_SUSPEND + .drv = { + .pm = &mtk_sdio_pmops, + }, +#endif +}; + +/* Registered client driver list */ +/* static list g_hif_sdio_clt_drv_list */ +static MTK_WCN_HIF_SDIO_REGISTINFO g_hif_sdio_clt_drv_list[CFG_CLIENT_COUNT]; + +/* MMC probed function list */ +/* static list g_hif_sdio_probed_func_list */ +static MTK_WCN_HIF_SDIO_PROBEINFO g_hif_sdio_probed_func_list[CFG_CLIENT_COUNT]; + +/* spin lock info for g_hif_sdio_clt_drv_list and g_hif_sdio_probed_func_list */ +static MTK_WCN_HIF_SDIO_LOCKINFO g_hif_sdio_lock_info; + +/* reference count, debug information? */ +static INT32 gRefCount; +static INT32 (*fp_wmt_tra_sdio_update)(VOID); +static atomic_t hif_sdio_irq_enable_flag = ATOMIC_INIT(0); + +/*deep sleep related information*/ +MTK_WCN_HIF_SDIO_DS_INFO g_hif_sdio_ds_info_list[] = { + { + .chip_id = 0x6630, + .reg_offset = 0xF1, + .value = 0x1, + }, + { + .chip_id = 0x6632, + .reg_offset = 0xF1, + .value = 0x1, + }, + { /* end: all zeroes */ } +}; + + + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("MediaTek Inc WCN_SE_CS3"); +MODULE_DESCRIPTION("MediaTek MT6620 HIF SDIO Driver"); + +MODULE_DEVICE_TABLE(sdio, mtk_sdio_id_tbl); + +INT32 gHifSdioDbgLvl = HIF_SDIO_LOG_INFO; + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#if 0 +INT32 __weak mtk_wcn_sdio_irq_flag_set(INT32 falg) +{ + HIF_SDIO_INFO_FUNC("mtk_wcn_sdio_irq_flag_set is not define!!!!!\n"); + + return 0; +} +#endif + +INT32 mtk_wcn_hif_sdio_irq_flag_set(INT32 flag) +{ + + if (flag == 0) { + atomic_dec(&hif_sdio_irq_enable_flag); + if (atomic_read(&hif_sdio_irq_enable_flag) == 0) + wmt_export_mtk_wcn_sdio_irq_flag_set(0); + } else { + atomic_inc(&hif_sdio_irq_enable_flag); + if (atomic_read(&hif_sdio_irq_enable_flag) == 1) + wmt_export_mtk_wcn_sdio_irq_flag_set(1); + } + + return 0; +} + + +/*! + * \brief register the callback funciton for record the timestamp of sdio access + * + * \param callback function + * + * \retval -EINVAL, when registered callback is invalid + * \retval 0, when registered callback is valid + */ +INT32 mtk_wcn_hif_sdio_update_cb_reg(INT32(*ts_update) (VOID)) +{ + if (ts_update) { + fp_wmt_tra_sdio_update = ts_update; + return 0; + } else { + return -EINVAL; + } +} +EXPORT_SYMBOL(mtk_wcn_hif_sdio_update_cb_reg); + +/*! + * \brief update the accessing time of SDIO via callback function + * + * \param void + * + * \retval -EINVAL, when callback is not registered + * \retval returned value of callback + */ +static _osal_inline_ INT32 wmt_tra_sdio_update(VOID) +{ + if (fp_wmt_tra_sdio_update) + return (*fp_wmt_tra_sdio_update) (); + /* HIF_SDIO_WARN_FUNC("wmt_tra_sdio_update == NULL\n"); */ + return -EINVAL; +} + +/*! + * \brief Translate CLTCTX into a pointer to struct sdio_func if it is valid + * + * Translate a CLTCTX into a pointer to struct sdio_func if it is + * 1) probed by mmc_core, and + * 2) client driver is registered, and + * 3) clt_idx of client driver is valid + * + * \param ctx a context provided by client driver + * + * \retval null if any condition is not valie + * \retval a pointer to a struct sdio_func mapped by provided ctx + */ +static _osal_inline_ struct sdio_func *hif_sdio_ctx_to_func(MTK_WCN_HIF_SDIO_CLTCTX ctx) +{ + UINT32 probe_index; + + /* 4 <1> check if ctx is valid, registered, and probed */ + probe_index = CLTCTX_IDX(ctx); + if (unlikely(!CLTCTX_UIDX_VALID(probe_index))) { /* invalid index in CLTCTX */ + HIF_SDIO_WARN_FUNC("invalid ctx(0x%x)\n", ctx); + return NULL; + } + /* the client has not been registered */ + if (unlikely(g_hif_sdio_probed_func_list[probe_index].clt_idx < 0)) { + HIF_SDIO_WARN_FUNC + ("can't find client idx in probed list!ctx(0x%x) prob_idx(%d) clt_idx(%d)\n", + ctx, probe_index, g_hif_sdio_probed_func_list[probe_index].clt_idx); + return NULL; + } + return g_hif_sdio_probed_func_list[probe_index].func; +} + +static _osal_inline_ INT32 hif_sdio_deep_sleep_info_dmp(MTK_WCN_HIF_SDIO_DS_INFO *p_ds_info) +{ + UINT32 i = 0; + MTK_WCN_HIF_SDIO_DS_CLT_INFO *ctl_info = NULL; + UINT32 ctl_info_array_size = ARRAY_SIZE(p_ds_info->clt_info); + + mutex_lock(&p_ds_info->lock); + HIF_SDIO_DBG_FUNC("p_ds_info: %p, chipid:0x%x, reg_offset:0x%x, value:0x%x\n", + p_ds_info, p_ds_info->chip_id, p_ds_info->reg_offset, p_ds_info->value); + + for (i = 0; i < ctl_info_array_size; i++) { + ctl_info = &p_ds_info->clt_info[i]; + + HIF_SDIO_DBG_FUNC + ("ctl_info[%d]--ctx:0x%08x, func_num:%d, act_flag:%d, en_flag:%d\n", i, + ctl_info->ctx, ctl_info->func_num, ctl_info->act_flag, ctl_info->ds_en_flag); + } + mutex_unlock(&p_ds_info->lock); + return 0; +} + +static _osal_inline_ INT32 hif_sdio_deep_sleep_info_init(VOID) +{ + UINT32 array_size = 0; + UINT32 clt_info_size = 0; + UINT32 i = 0; + UINT32 j = 0; + + array_size = ARRAY_SIZE(g_hif_sdio_ds_info_list); + + /*set clt_info segment to 0 by default, when do stp/wifi on, write real information back */ + for (i = 0; i < array_size; i++) { + mutex_init(&g_hif_sdio_ds_info_list[i].lock); + clt_info_size = ARRAY_SIZE(g_hif_sdio_ds_info_list[i].clt_info); + + mutex_lock(&g_hif_sdio_ds_info_list[i].lock); + for (j = 0; j < clt_info_size; j++) + memset(&g_hif_sdio_ds_info_list[i].clt_info[j], + 0, sizeof(MTK_WCN_HIF_SDIO_DS_CLT_INFO)); + mutex_unlock(&g_hif_sdio_ds_info_list[i].lock); + + hif_sdio_deep_sleep_info_dmp(&g_hif_sdio_ds_info_list[i]); + } + + return 0; +} + +static _osal_inline_ INT32 hif_sdio_deep_sleep_info_set_act(UINT32 chipid, UINT16 func_num, + MTK_WCN_HIF_SDIO_CLTCTX ctx, UINT8 act_flag) +{ + UINT32 i = 0; + UINT32 array_size = 0; + UINT32 clt_info_size = 0; + UINT32 idx = 0; + MTK_WCN_HIF_SDIO_DS_CLT_INFO *p_ds_clt_info = NULL; + + array_size = ARRAY_SIZE(g_hif_sdio_ds_info_list); + + /*search write index */ + for (i = 0; i < array_size; i++) { + if (g_hif_sdio_ds_info_list[i].chip_id == chipid) + break; + } + if (i >= array_size) { + HIF_SDIO_WARN_FUNC("no valid ds info found for 0x%x\n", chipid); + return -1; + } + HIF_SDIO_DBG_FUNC("valid ds info found for 0x%x\n", chipid); + + clt_info_size = ARRAY_SIZE(g_hif_sdio_ds_info_list[i].clt_info); + + if (func_num > clt_info_size) { + HIF_SDIO_WARN_FUNC("func num <%d> exceed max clt info size <%d>\n", func_num, + clt_info_size); + return -2; + } + idx = func_num - 1; + p_ds_clt_info = &g_hif_sdio_ds_info_list[i].clt_info[idx]; + + mutex_lock(&g_hif_sdio_ds_info_list[i].lock); + p_ds_clt_info->func_num = func_num; + p_ds_clt_info->ctx = ctx; + p_ds_clt_info->act_flag = act_flag; + p_ds_clt_info->ds_en_flag = 0; + mutex_unlock(&g_hif_sdio_ds_info_list[i].lock); + + HIF_SDIO_DBG_FUNC("set act_flag to %d for ctx:0x%x whose chipid:0x%x, func_num:%d done\n", + act_flag, ctx, chipid, func_num); + /* hif_sdio_deep_sleep_info_dmp(&g_hif_sdio_ds_info_list[0]); */ + + return 0; +} + +static INT32 _hif_sdio_wake_up_ctrl(MTK_WCN_HIF_SDIO_CLTCTX ctx) +{ + INT32 ret = 0; + INT32 gpio_state = -1; + INT32 sec_old = 0; + INT32 usec_old = 0; + INT32 sec = 0; + INT32 usec = 0; + INT32 polling_counter = 0; + UINT8 cccr_value = 0x0; + UINT32 cpupcr_value = 0x00; + INT32 i = 0; + UINT32 delay_us = 500; + WMT_GPIO_STATE_INFO gpio_state_list[2]; + + HIF_SDIO_DBG_FUNC("wakeup chip from deep sleep!\n"); + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_CHIP_WAKE_UP_PIN].gpio_num != DEFAULT_PIN_ID) { + gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[GPIO_CHIP_WAKE_UP_PIN].gpio_num, 1); + HIF_SDIO_DBG_FUNC("wmt_gpio:set GPIO_CHIP_WAKE_UP_PIN out to 1: %d!\n", + gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[GPIO_CHIP_WAKE_UP_PIN].gpio_num)); + } else { + HIF_SDIO_ERR_FUNC("wmt_gpio:get GPIO_CHIP_WAKE_UP_PIN number error!\n"); + return -2; + } + /*1.pull GPIO_CHIP_WAKE_UP_PIN out 0*/ + gpio_state_list[0].gpio_num = gpio_ctrl_info.gpio_ctrl_state[GPIO_CHIP_WAKE_UP_PIN].gpio_num-280; + _wmt_gpio_pre_regs(gpio_state_list[0].gpio_num, &gpio_state_list[0]); + gpio_state_list[1].gpio_num = gpio_ctrl_info.gpio_ctrl_state[GPIO_CHIP_DEEP_SLEEP_PIN].gpio_num-280; + _wmt_gpio_pre_regs(gpio_state_list[1].gpio_num, &gpio_state_list[1]); + + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_CHIP_WAKE_UP_PIN].gpio_num != DEFAULT_PIN_ID) { + gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[GPIO_CHIP_WAKE_UP_PIN].gpio_num, 0); + HIF_SDIO_DBG_FUNC("wmt_gpio:set GPIO_CHIP_WAKE_UP_PIN out to 0: %d!\n", + gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[GPIO_CHIP_WAKE_UP_PIN].gpio_num)); + } else { + HIF_SDIO_ERR_FUNC("wmt_gpio:get GPIO_CHIP_WAKE_UP_PIN number error!\n"); + return -2; + } + /*2.waiting for DEEP_SLEEP_PIN become high*/ + osal_gettimeofday(&sec_old, &usec_old); + HIF_SDIO_DBG_FUNC("wakeup flow, prepare polling DEEP_SLEEP_PIN high state, timing: %d us\n", usec_old); + while (1) { + osal_gettimeofday(&sec, &usec); + gpio_state = + gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[GPIO_CHIP_DEEP_SLEEP_PIN].gpio_num); + if (gpio_state == 0) { + HIF_SDIO_DBG_FUNC("wmt_gpio:Polling GPIO_CHIP_DEEP_SLEEP_PIN low success!\n"); + if (polling_counter >= 20) + HIF_SDIO_WARN_FUNC + ("polling ACK_B pin low success but over 20 count, time:%dus, count:%d\n", + (usec - usec_old), polling_counter); + polling_counter = 0; + break; + } + if (polling_counter >= 60) { + HIF_SDIO_ERR_FUNC + ("wake up fail!, polling ACK_B pin low over 60 count, time:%dus, count:%d\n", + (usec - usec_old), polling_counter); + HIF_SDIO_INFO_FUNC("Dump EINT_B, ACT_B history states!\n"); + _wmt_dump_gpio_pre_regs(gpio_state_list[0]); + _wmt_dump_gpio_pre_regs(gpio_state_list[1]); + HIF_SDIO_INFO_FUNC("Dump EINT_B, ACT_B current states!\n"); + _wmt_dump_gpio_regs(gpio_state_list[0].gpio_num); + _wmt_dump_gpio_regs(gpio_state_list[1].gpio_num); + + HIF_SDIO_INFO_FUNC("read cccr info !\n"); + for (i = 0; i < 8; i++) { + ret = mtk_wcn_hif_sdio_f0_readb(ctx, CCCR_F8 + i, &cccr_value); + if (ret) + HIF_SDIO_ERR_FUNC("read CCCR fail(%d), address(0x%x)\n", ret, CCCR_F8 + i); + else + HIF_SDIO_INFO_FUNC("read CCCR value(0x%x), address(0x%x)\n", + cccr_value, CCCR_F8 + i); + cccr_value = 0x0; + } + + HIF_SDIO_INFO_FUNC("read cpupcr info !\n"); + for (i = 0; i < 5; i++) { + ret = mtk_wcn_hif_sdio_readl(ctx, SWPCDBGR, &cpupcr_value); + if (ret) + HIF_SDIO_ERR_FUNC("read cpupcr fail, ret(%d)\n", ret); + else + HIF_SDIO_ERR_FUNC("read cpupcr value (0x%x)\n", cpupcr_value); + msleep(20); + } + _wmt_dump_gpio_regs(gpio_state_list[0].gpio_num); + _wmt_dump_gpio_regs(gpio_state_list[1].gpio_num); + ret = -11; + break; + } + polling_counter++; + osal_usleep_range(delay_us, 2 * delay_us); + } + /*3.pull GPIO_CHIP_WAKE_UP_PIN high, clear interrupt*/ + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_CHIP_WAKE_UP_PIN].gpio_num != DEFAULT_PIN_ID) { + gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[GPIO_CHIP_WAKE_UP_PIN].gpio_num, 1); + HIF_SDIO_DBG_FUNC("wmt_gpio:set GPIO_CHIP_WAKE_UP_PIN out to 1: %d!\n", + gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[GPIO_CHIP_WAKE_UP_PIN].gpio_num)); + } else { + HIF_SDIO_ERR_FUNC("wmt_gpio:get GPIO_CHIP_WAKE_UP_PIN number error!\n"); + return -3; + } + + return ret; +} +#ifdef CONFIG_MTK_COMBO_CHIP_DEEP_SLEEP_SUPPORT +INT32 mtk_wcn_hif_sdio_deep_sleep_flag_set(MTK_WCN_BOOL flag) +{ + g_hif_deep_sleep_flag = flag; + return 0; +} +#endif +INT32 hif_sdio_wake_up_ctrl(MTK_WCN_HIF_SDIO_CLTCTX ctx) +{ + UINT32 i = 0; + UINT32 j = 0; + INT32 ret = 0; + UINT32 array_size = 0; + UINT32 clt_info_size = 0; + MTK_WCN_HIF_SDIO_DS_CLT_INFO *p_ds_clt_info = NULL; + MTK_WCN_HIF_SDIO_DS_INFO *p_ds_info = NULL; + UINT8 do_ds_op_flag = 0; + + array_size = ARRAY_SIZE(g_hif_sdio_ds_info_list); + /*search write index */ + for (i = 0; i < array_size; i++) { + mutex_lock(&(g_hif_sdio_ds_info_list[i].lock)); + clt_info_size = ARRAY_SIZE(g_hif_sdio_ds_info_list[i].clt_info); + + for (j = 0; j < clt_info_size; j++) { + if (g_hif_sdio_ds_info_list[i].clt_info[j].ctx == ctx) { + do_ds_op_flag = 1; + break; + } + } + + if (do_ds_op_flag != 0) + break; + mutex_unlock(&(g_hif_sdio_ds_info_list[i].lock)); + } + + if ((i >= array_size) || (j >= clt_info_size)) { + HIF_SDIO_ERR_FUNC("mtk_wcn_hif_sdio_wake_up_ctrl, no valid ds info found for ctx 0x%08x\n", ctx); + return -1; + } + HIF_SDIO_DBG_FUNC("mtk_wcn_hif_sdio_wake_up_ctrl, valid ds info found for ctx 0x%08x\n", ctx); + p_ds_info = &g_hif_sdio_ds_info_list[i]; + p_ds_clt_info = &p_ds_info->clt_info[j]; + HIF_SDIO_DBG_FUNC("mtk_wcn_hif_sdio_wake_up_ctrl, func_num:(%d), chid(%x)\n", + p_ds_clt_info->func_num, p_ds_info->chip_id); + if (g_hif_deep_sleep_flag) { + HIF_SDIO_DBG_FUNC("deep sleep feature is enable!\n"); + ret = _hif_sdio_wake_up_ctrl(ctx); + if (ret == -11) { + HIF_SDIO_DBG_FUNC("wake up chip from deep sleep fail, retry wake up operation\n"); + ret = _hif_sdio_wake_up_ctrl(ctx); + if (ret == 0) + HIF_SDIO_INFO_FUNC("retry wake up from deep sleep success\n"); + else if (ret == -11) + HIF_SDIO_INFO_FUNC("retry wake up from deep sleep fail!\n"); + } + } else + HIF_SDIO_DBG_FUNC("deep sleep feature is disable!\n"); + mutex_unlock(&(g_hif_sdio_ds_info_list[i].lock)); + return ret; +} + +/*! + * \brief MTK hif sdio client registration function + * + * Client uses this function to register itself to hif_sdio driver + * + * \param pinfo a pointer of client's information + * + * \retval 0 register successfully + * \retval < 0 list error code here + */ +INT32 mtk_wcn_hif_sdio_client_reg(const MTK_WCN_HIF_SDIO_CLTINFO *pinfo) +{ + INT32 ret = -HIF_SDIO_ERR_FAIL; + INT32 clt_index = -1; + UINT32 i = 0; + UINT32 j = 0; + MTK_WCN_HIF_SDIO_CLT_PROBE_WORKERINFO *clt_probe_worker_info = 0; + + HIF_SDIO_DBG_FUNC("start!\n"); + /* 4 <1> check input pointer is valid */ + HIF_SDIO_ASSERT(pinfo); + + /* 4 <2> check if input parameters are all supported and valid */ + for (i = 0; i < pinfo->func_tbl_size; i++) { + ret = + hif_sdio_check_supported_sdio_id(pinfo->func_tbl[i].manf_id, + pinfo->func_tbl[i].card_id); + if (ret) { + HIF_SDIO_WARN_FUNC + ("vendor id(0x%x) and device id(0x%x) of sdio_func are not supported!\n", + pinfo->func_tbl[i].manf_id, pinfo->func_tbl[i].card_id); + goto out; + } + } + HIF_SDIO_DBG_FUNC("hif_sdio_check_supported_sdio_id() done!\n"); + + /* 4 <3> check if the specific {manf id, card id, function number} tuple is */ + /* 4 already resigstered */ + for (i = 0; i < pinfo->func_tbl_size; i++) { + ret = + hif_sdio_check_duplicate_sdio_id(pinfo->func_tbl[i].manf_id, + pinfo->func_tbl[i].card_id, + pinfo->func_tbl[i].func_num); + if (ret) { + HIF_SDIO_WARN_FUNC("vendor id(0x%x), device id(0x%x), and fun_num(%d) of\n", + pinfo->func_tbl[i].manf_id, pinfo->func_tbl[i].card_id, + pinfo->func_tbl[i].func_num); + HIF_SDIO_WARN_FUNC("sdio_func are duplicated in g_hif_sdio_clt_drv_list!\n"); + goto out; + } + } + HIF_SDIO_DBG_FUNC("hif_sdio_check_duplicate_sdio_id() done!\n"); + + /* + * 4 <4> add the specified {manf id, card id, function number} + * tuple to registered client list + */ + HIF_SDIO_DBG_FUNC("pinfo->func_tbl_size:%d\n", pinfo->func_tbl_size); + for (i = 0; i < pinfo->func_tbl_size; i++) { + ret = hif_sdio_add_clt_list(&clt_index, pinfo, i); + if (ret) { + HIF_SDIO_WARN_FUNC + ("client's info are added in registed client list failed (buffer is full)!\n"); + goto out; + } + HIF_SDIO_DBG_FUNC("hif_sdio_add_clt_list() done (gRefCount=%d)!\n", gRefCount); + + /* 4 <5> if the specific {manf id, card id, function number} tuple has already */ + /* 4 been probed by mmc, schedule another task to call client's .hif_clt_probe() */ + for (j = 0; j < CFG_CLIENT_COUNT; j++) { + /* probed spin lock */ + spin_lock_bh(&g_hif_sdio_lock_info.probed_list_lock); + if (g_hif_sdio_probed_func_list[j].func == 0) { + /* probed spin unlock */ + spin_unlock_bh(&g_hif_sdio_lock_info.probed_list_lock); + continue; + } + /* the function has been probed */ + if ((g_hif_sdio_clt_drv_list[clt_index].func_info->manf_id == + g_hif_sdio_probed_func_list[j].func->vendor) + && (g_hif_sdio_clt_drv_list[clt_index].func_info->card_id == + g_hif_sdio_probed_func_list[j].func->device) + && (g_hif_sdio_clt_drv_list[clt_index].func_info->func_num == + g_hif_sdio_probed_func_list[j].func->num)) { + g_hif_sdio_probed_func_list[j].clt_idx = clt_index; + /* probed spin unlock */ + spin_unlock_bh(&g_hif_sdio_lock_info.probed_list_lock); + if (g_hif_sdio_probed_func_list[j].func->num != 1 + || (g_hif_sdio_probed_func_list[j].on_by_wmt == MTK_WCN_BOOL_TRUE + && g_hif_sdio_probed_func_list[j].func->num == 1)) { + /* use worker thread to perform the client's .hif_clt_probe() */ + clt_probe_worker_info = + vmalloc(sizeof(MTK_WCN_HIF_SDIO_CLT_PROBE_WORKERINFO)); + if (clt_probe_worker_info) { + INIT_WORK(&clt_probe_worker_info->probe_work, + hif_sdio_clt_probe_worker); + clt_probe_worker_info->registinfo_p = + &g_hif_sdio_clt_drv_list[clt_index]; + clt_probe_worker_info->probe_idx = j; + schedule_work(&clt_probe_worker_info->probe_work); + } + /* 4 <5.1> remember to do claim_irq for the */ + /* func if it's irq had been released. */ + if (!(g_hif_sdio_probed_func_list[j].func->irq_handler)) { + sdio_claim_host(g_hif_sdio_probed_func_list[j].func); + ret = + sdio_claim_irq(g_hif_sdio_probed_func_list[j].func, + hif_sdio_irq); + mtk_wcn_hif_sdio_irq_flag_set(1); + sdio_release_host(g_hif_sdio_probed_func_list[j].func); + HIF_SDIO_INFO_FUNC + ("sdio_claim_irq for func(0x%p) j(%d) v(0x%x) d(0x%x) ok\n", + g_hif_sdio_probed_func_list[j].func, j, + g_hif_sdio_probed_func_list[j].func->vendor, + g_hif_sdio_probed_func_list[j].func->device); + } + /* 4 <5.2> Reset the block size of the function provided by client */ + HIF_SDIO_INFO_FUNC("Reset sdio block size: %d!\n", + g_hif_sdio_clt_drv_list[clt_index]. + func_info->blk_sz); + sdio_claim_host(g_hif_sdio_probed_func_list[j].func); + ret = sdio_set_block_size(g_hif_sdio_probed_func_list[j].func, + g_hif_sdio_clt_drv_list + [clt_index].func_info->blk_sz); + sdio_release_host(g_hif_sdio_probed_func_list[j].func); + } + } else { + /* probed spin unlock */ + spin_unlock_bh(&g_hif_sdio_lock_info.probed_list_lock); + } + } + HIF_SDIO_DBG_FUNC + ("map g_hif_sdio_clt_drv_list to g_hif_sdio_probed_func_list done!\n"); + } + ret = HIF_SDIO_ERR_SUCCESS; + gRefCount++; + +out: + /* 4 error handling */ + + HIF_SDIO_DBG_FUNC("end!\n"); + return ret; +} /* end of mtk_wcn_hif_sdio_client_reg() */ +EXPORT_SYMBOL(mtk_wcn_hif_sdio_client_reg); + +/*! + * \brief MTK hif sdio client un-registration function + * + * Client uses this function to un-register itself + * + * \param pinfo a pointer of client's information + * + * \retval 0 register successfully + * \retval < 0 list error code here + */ +INT32 mtk_wcn_hif_sdio_client_unreg(const MTK_WCN_HIF_SDIO_CLTINFO *pinfo) +{ + INT32 ret = -HIF_SDIO_ERR_FAIL; + INT32 clt_list_index = 0; + UINT32 i = 0; + UINT32 j = 0; + + HIF_SDIO_INFO_FUNC("start!\n"); + + /* 4 <1> check if input pointer is valid */ + HIF_SDIO_ASSERT(pinfo); + + /* 4 <2> check if input parameters are all supported and valid */ + for (i = 0; i < pinfo->func_tbl_size; i++) { + ret = + hif_sdio_check_supported_sdio_id(pinfo->func_tbl[i].manf_id, + pinfo->func_tbl[i].card_id); + if (ret) { + HIF_SDIO_WARN_FUNC + ("vendor id(0x%x) and device id(0x%x) of sdio_func are not supported in mtk_sdio_id_tbl!\n", + pinfo->func_tbl[i].manf_id, pinfo->func_tbl[i].card_id); + goto out; + } + } + + /* 4 <3> check if the specific {manf id, card id, function number} tuple is already resigstered */ + /* 4 and find the corresponding client ctx and call client's .hif_clt_remove() in THIS context */ + for (i = 0; i < pinfo->func_tbl_size; i++) { + clt_list_index = + hif_sdio_find_clt_list_index(pinfo->func_tbl[i].manf_id, + pinfo->func_tbl[i].card_id, + pinfo->func_tbl[i].func_num); + if (clt_list_index < 0) { + HIF_SDIO_WARN_FUNC("vendor id(0x%x),", pinfo->func_tbl[i].manf_id); + HIF_SDIO_WARN_FUNC(" device id(0x%x),", pinfo->func_tbl[i].card_id); + HIF_SDIO_WARN_FUNC(" and fun_num(%d)", pinfo->func_tbl[i].func_num); + HIF_SDIO_WARN_FUNC(" client info is not in the client's registed list!\n"); + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } + /* 4 <4> mark the specified {manf id, card id, function number} tuple as */ + /* 4 un-registered and invalidate client's context */ + hif_sdio_init_clt_list(clt_list_index); + + /* un-map g_hif_sdio_clt_drv_list index in g_hif_sdio_probed_func_list */ + for (j = 0; j < CFG_CLIENT_COUNT; j++) { + if (g_hif_sdio_probed_func_list[j].clt_idx == clt_list_index) + g_hif_sdio_probed_func_list[j].clt_idx = -1; + } + } + gRefCount--; + + ret = HIF_SDIO_ERR_SUCCESS; +out: + HIF_SDIO_INFO_FUNC("end (gRefCount=%d) !\n", gRefCount); + return ret; +} /* end of mtk_wcn_hif_sdio_client_unreg() */ +EXPORT_SYMBOL(mtk_wcn_hif_sdio_client_unreg); + +/*! + * \brief + * + * detailed descriptions + * + * \param ctx client's context variable + * + * \retval 0 register successfully + * \retval < 0 list error code here + */ +INT32 mtk_wcn_hif_sdio_readb(MTK_WCN_HIF_SDIO_CLTCTX ctx, UINT32 offset, PUINT8 pvb) +{ +#if HIF_SDIO_UPDATE + INT32 ret; + struct sdio_func *func = NULL; +#else + INT32 ret = -HIF_SDIO_ERR_FAIL; + INT32 probe_index = -1; + struct sdio_func *func = 0; +#endif + + HIF_SDIO_DBG_FUNC("start!\n"); + HIF_SDIO_ASSERT(pvb); + + /* 4 <1> check if ctx is valid, registered, and probed */ +#if HIF_SDIO_UPDATE + ret = -HIF_SDIO_ERR_FAIL; + func = hif_sdio_ctx_to_func(ctx); + if (!func) { + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } +#else + probe_index = CLTCTX_IDX(ctx); + if (unlikely(!CLTCTX_IDX_VALID(probe_index))) { /* invalid index in CLTCTX */ + HIF_SDIO_WARN_FUNC("invalid ctx(0x%x)\n", ctx); + goto out; + } + if (probe_index < 0 || probe_index >= CFG_CLIENT_COUNT) { /* the function has not been probed */ + HIF_SDIO_WARN_FUNC("can't find client in probed list!\n"); + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } else { + if (g_hif_sdio_probed_func_list[probe_index].clt_idx < 0) { /* the client has not been registered */ + HIF_SDIO_WARN_FUNC("can't find client in registered list!\n"); + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } + } + func = g_hif_sdio_probed_func_list[probe_index].func; +#endif + + /* 4 <2> */ + osal_ftrace_print("%s|S\n", __func__); + sdio_claim_host(func); + *pvb = sdio_readb(func, offset, &ret); + sdio_release_host(func); + osal_ftrace_print("%s|E\n", __func__); + + /* 4 <3> check result code and return proper error code */ + +out: + HIF_SDIO_DBG_FUNC("end!\n"); + return ret; +} /* end of mtk_wcn_hif_sdio_client_unreg() */ +EXPORT_SYMBOL(mtk_wcn_hif_sdio_readb); + +/*! + * \brief + * + * detailed descriptions + * + * \param ctx client's context variable + * + * \retval 0 register successfully + * \retval < 0 list error code here + */ +INT32 mtk_wcn_hif_sdio_writeb(MTK_WCN_HIF_SDIO_CLTCTX ctx, UINT32 offset, UINT8 vb) +{ +#if HIF_SDIO_UPDATE + INT32 ret; + struct sdio_func *func = NULL; +#else + INT32 ret = -HIF_SDIO_ERR_FAIL; + INT32 probe_index = -1; + struct sdio_func *func = 0; +#endif + + HIF_SDIO_DBG_FUNC("start!\n"); + + /* 4 <1> check if ctx is valid, registered, and probed */ +#if HIF_SDIO_UPDATE + ret = -HIF_SDIO_ERR_FAIL; + func = hif_sdio_ctx_to_func(ctx); + if (!func) { + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } +#else + probe_index = CLTCTX_IDX(ctx); + if (unlikely(!CLTCTX_IDX_VALID(probe_index))) { /* invalid index in CLTCTX */ + HIF_SDIO_WARN_FUNC("invalid ctx(0x%x)\n", ctx); + goto out; + } + if (probe_index < 0 || probe_index >= CFG_CLIENT_COUNT) { /* the function has not been probed */ + HIF_SDIO_WARN_FUNC("can't find client in probed list!\n"); + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } else { + if (g_hif_sdio_probed_func_list[probe_index].clt_idx < 0) { /* the client has not been registered */ + HIF_SDIO_WARN_FUNC("can't find client in registered list!\n"); + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } + } + func = g_hif_sdio_probed_func_list[probe_index].func; +#endif + + /* 4 <1.1> check if input parameters are valid */ + + /* 4 <2> */ + wmt_tra_sdio_update(); + osal_ftrace_print("%s|S\n", __func__); + sdio_claim_host(func); + sdio_writeb(func, vb, offset, &ret); + sdio_release_host(func); + osal_ftrace_print("%s|E\n", __func__); + + /* 4 <3> check result code and return proper error code */ + +out: + HIF_SDIO_DBG_FUNC("end!\n"); + return ret; +} /* end of mtk_wcn_hif_sdio_client_unreg() */ +EXPORT_SYMBOL(mtk_wcn_hif_sdio_writeb); + +/*! + * \brief + * + * detailed descriptions + * + * \param ctx client's context variable + * + * \retval 0 register successfully + * \retval < 0 list error code here + */ +INT32 mtk_wcn_hif_sdio_readl(MTK_WCN_HIF_SDIO_CLTCTX ctx, UINT32 offset, PUINT32 pvl) +{ +#if HIF_SDIO_UPDATE + INT32 ret; + struct sdio_func *func = NULL; +#else + INT32 ret = -HIF_SDIO_ERR_FAIL; + INT32 probe_index = -1; + struct sdio_func *func = 0; +#endif + + HIF_SDIO_DBG_FUNC("start!\n"); + HIF_SDIO_ASSERT(pvl); + + /* 4 <1> check if ctx is valid, registered, and probed */ +#if HIF_SDIO_UPDATE + ret = -HIF_SDIO_ERR_FAIL; + func = hif_sdio_ctx_to_func(ctx); + if (!func) { + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } +#else + probe_index = CLTCTX_IDX(ctx); + if (unlikely(!CLTCTX_IDX_VALID(probe_index))) { /* invalid index in CLTCTX */ + HIF_SDIO_WARN_FUNC("invalid ctx(0x%x)\n", ctx); + goto out; + } + if (probe_index < 0 || probe_index >= CFG_CLIENT_COUNT) { /* the function has not been probed */ + HIF_SDIO_WARN_FUNC("can't find client in probed list!\n"); + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } else { + if (g_hif_sdio_probed_func_list[probe_index].clt_idx < 0) { /* the client has not been registered */ + HIF_SDIO_WARN_FUNC("can't find client in registered list!\n"); + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } + } + func = g_hif_sdio_probed_func_list[probe_index].func; +#endif + /* 4 <1.1> check if input parameters are valid */ + + /* 4 <2> */ + osal_ftrace_print("%s|S\n", __func__); + sdio_claim_host(func); + *pvl = sdio_readl(func, offset, &ret); + sdio_release_host(func); + osal_ftrace_print("%s|E\n", __func__); + + /* 4 <3> check result code and return proper error code */ + +out: + HIF_SDIO_DBG_FUNC("end!\n"); + return ret; +} /* end of mtk_wcn_hif_sdio_client_unreg() */ +EXPORT_SYMBOL(mtk_wcn_hif_sdio_readl); + +/*! + * \brief + * + * detailed descriptions + * + * \param ctx client's context variable + * + * \retval 0 register successfully + * \retval < 0 list error code here + */ +INT32 mtk_wcn_hif_sdio_writel(MTK_WCN_HIF_SDIO_CLTCTX ctx, UINT32 offset, UINT32 vl) +{ +#if HIF_SDIO_UPDATE + INT32 ret; + struct sdio_func *func = NULL; +#else + INT32 ret = -HIF_SDIO_ERR_FAIL; + INT32 probe_index = -1; + struct sdio_func *func = 0; +#endif + + HIF_SDIO_DBG_FUNC("start!\n"); + + /* 4 <1> check if ctx is valid, registered, and probed */ +#if HIF_SDIO_UPDATE + ret = -HIF_SDIO_ERR_FAIL; + func = hif_sdio_ctx_to_func(ctx); + if (!func) { + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } +#else + probe_index = CLTCTX_IDX(ctx); + if (unlikely(!CLTCTX_IDX_VALID(probe_index))) { /* invalid index in CLTCTX */ + HIF_SDIO_WARN_FUNC("invalid ctx(0x%x)\n", ctx); + goto out; + } + if (probe_index < 0 || probe_index >= CFG_CLIENT_COUNT) { /* the function has not been probed */ + HIF_SDIO_WARN_FUNC("can't find client in probed list!\n"); + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } else { + if (g_hif_sdio_probed_func_list[probe_index].clt_idx < 0) { /* the client has not been registered */ + HIF_SDIO_WARN_FUNC("can't find client in registered list!\n"); + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } + } + func = g_hif_sdio_probed_func_list[probe_index].func; +#endif + /* 4 <1.1> check if input parameters are valid */ + + /* 4 <2> */ + wmt_tra_sdio_update(); + osal_ftrace_print("%s|S\n", __func__); + sdio_claim_host(func); + sdio_writel(func, vl, offset, &ret); + sdio_release_host(func); + osal_ftrace_print("%s|E\n", __func__); + + /* 4 <3> check result code and return proper error code */ + +out: + HIF_SDIO_DBG_FUNC("end!\n"); + return ret; +} /* end of mtk_wcn_hif_sdio_client_unreg() */ +EXPORT_SYMBOL(mtk_wcn_hif_sdio_writel); + +/*! + * \brief + * + * detailed descriptions + * + * \param ctx client's context variable + * + * \retval 0 register successfully + * \retval < 0 list error code here + */ +INT32 mtk_wcn_hif_sdio_read_buf(MTK_WCN_HIF_SDIO_CLTCTX ctx, + UINT32 offset, PUINT32 pbuf, UINT32 len) +{ +#if HIF_SDIO_UPDATE + INT32 ret; + struct sdio_func *func = NULL; +#else + INT32 ret = -HIF_SDIO_ERR_FAIL; + INT32 probe_index = -1; + struct sdio_func *func = 0; +#endif + + HIF_SDIO_DBG_FUNC("start!\n"); + HIF_SDIO_ASSERT(pbuf); + + /* 4 <1> check if ctx is valid, registered, and probed */ +#if HIF_SDIO_UPDATE + ret = -HIF_SDIO_ERR_FAIL; + func = hif_sdio_ctx_to_func(ctx); + if (!func) { + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } +#else + probe_index = CLTCTX_IDX(ctx); + if (unlikely(!CLTCTX_IDX_VALID(probe_index))) { /* invalid index in CLTCTX */ + HIF_SDIO_WARN_FUNC("invalid ctx(0x%x)\n", ctx); + goto out; + } + if (probe_index < 0 || probe_index >= CFG_CLIENT_COUNT) { /* the function has not been probed */ + HIF_SDIO_WARN_FUNC("can't find client in probed list!\n"); + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } else { + if (g_hif_sdio_probed_func_list[probe_index].clt_idx < 0) { /* the client has not been registered */ + HIF_SDIO_WARN_FUNC("can't find client in registered list!\n"); + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } + } + func = g_hif_sdio_probed_func_list[probe_index].func; +#endif + /* 4 <1.1> check if input parameters are valid */ + + /* 4 <2> */ + osal_ftrace_print("%s|S|L|%d\n", __func__, len); + sdio_claim_host(func); + ret = sdio_readsb(func, pbuf, offset, len); + sdio_release_host(func); + osal_ftrace_print("%s|E|L|%d\n", __func__, len); + + /* 4 <3> check result code and return proper error code */ + +out: + HIF_SDIO_DBG_FUNC("end!\n"); + return ret; +} /* end of mtk_wcn_hif_sdio_read_buf() */ +EXPORT_SYMBOL(mtk_wcn_hif_sdio_read_buf); + + +/*! + * \brief + * + * detailed descriptions + * + * \param ctx client's context variable + * + * \retval 0 register successfully + * \retval < 0 list error code here + */ +INT32 mtk_wcn_hif_sdio_write_buf(MTK_WCN_HIF_SDIO_CLTCTX ctx, + UINT32 offset, PUINT32 pbuf, UINT32 len) +{ +#if HIF_SDIO_UPDATE + INT32 ret; + struct sdio_func *func = NULL; +#else + INT32 ret = -HIF_SDIO_ERR_FAIL; + INT32 probe_index = -1; + struct sdio_func *func = 0; +#endif + + HIF_SDIO_DBG_FUNC("start!\n"); + HIF_SDIO_ASSERT(pbuf); + + /* 4 <1> check if ctx is valid, registered, and probed */ +#if HIF_SDIO_UPDATE + ret = -HIF_SDIO_ERR_FAIL; + func = hif_sdio_ctx_to_func(ctx); + if (!func) { + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } +#else + probe_index = CLTCTX_IDX(ctx); + if (unlikely(!CLTCTX_IDX_VALID(probe_index))) { /* invalid index in CLTCTX */ + HIF_SDIO_WARN_FUNC("invalid ctx(0x%x)\n", ctx); + goto out; + } + if (probe_index < 0 || probe_index >= CFG_CLIENT_COUNT) { /* the function has not been probed */ + HIF_SDIO_WARN_FUNC("can't find client in probed list!\n"); + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } else { + if (g_hif_sdio_probed_func_list[probe_index].clt_idx < 0) { /* the client has not been registered */ + HIF_SDIO_WARN_FUNC("can't find client in registered list!\n"); + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } + } + func = g_hif_sdio_probed_func_list[probe_index].func; +#endif + /* 4 <1.1> check if input parameters are valid */ + + /* 4 <2> */ + wmt_tra_sdio_update(); + osal_ftrace_print("%s|S|L|%d\n", __func__, len); + sdio_claim_host(func); + ret = sdio_writesb(func, offset, pbuf, len); + sdio_release_host(func); + osal_ftrace_print("%s|E|L|%d\n", __func__, len); + + /* 4 <3> check result code and return proper error code */ + +out: + HIF_SDIO_DBG_FUNC("ret(%d) end!\n", ret); + + return ret; +} /* end of mtk_wcn_hif_sdio_write_buf() */ +EXPORT_SYMBOL(mtk_wcn_hif_sdio_write_buf); + +/*! + * \brief + * + * detailed descriptions + * + * \param ctx client's context variable + * + * \retval 0 register successfully + * \retval < 0 list error code here + */ +INT32 mtk_wcn_hif_sdio_abort(MTK_WCN_HIF_SDIO_CLTCTX ctx) +{ +#if HIF_SDIO_UPDATE + INT32 ret; + struct sdio_func *func = NULL; +#else + INT32 ret = -HIF_SDIO_ERR_FAIL; + INT32 probe_index = -1; + struct sdio_func *func = 0; +#endif + + HIF_SDIO_DBG_FUNC("start!\n"); + HIF_SDIO_ASSERT(pbuf); + + /* 4 <1> check if ctx is valid, registered, and probed */ +#if HIF_SDIO_UPDATE + ret = -HIF_SDIO_ERR_FAIL; + func = hif_sdio_ctx_to_func(ctx); + if (!func) { + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } +#else + probe_index = CLTCTX_IDX(ctx); + if (unlikely(!CLTCTX_IDX_VALID(probe_index))) { /* invalid index in CLTCTX */ + HIF_SDIO_WARN_FUNC("invalid ctx(0x%x)\n", ctx); + goto out; + } + if (probe_index < 0 || probe_index >= CFG_CLIENT_COUNT) { /* the function has not been probed */ + HIF_SDIO_WARN_FUNC("can't find client in probed list!\n"); + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } else { + if (g_hif_sdio_probed_func_list[probe_index].clt_idx < 0) { /* the client has not been registered */ + HIF_SDIO_WARN_FUNC("can't find client in registered list!\n"); + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } + } + func = g_hif_sdio_probed_func_list[probe_index].func; +#endif + /* 4 <1.1> check if input parameters are valid */ + + /* 4 <2> */ + osal_ftrace_print("%s|S|L|\n", __func__); + sdio_claim_host(func); + /* SDIO Control must be switched to function 2 before the abort command send + * firmware can receive function 2 abort interrupt + * read CTMDPCR1(0xBC) to switch function 2 + */ + sdio_readl(func, 0xBC, &ret); + ret = KERNEL_mmc_io_rw_direct(func->card, 1, 0, SDIO_CCCR_ABORT, func->num, NULL); + sdio_release_host(func); + osal_ftrace_print("%s|E|L|\n", __func__); + + /* 4 <3> check result code and return proper error code */ + +out: + HIF_SDIO_DBG_FUNC("ret(%d) end!\n", ret); + + return ret; +} /* end of mtk_wcn_hif_sdio_write_buf() */ +EXPORT_SYMBOL(mtk_wcn_hif_sdio_abort); + +/*! + * \brief store client driver's private data function. + * + * + * \param clent's MTK_WCN_HIF_SDIO_CLTCTX. + * + * \retval none. + */ +VOID mtk_wcn_hif_sdio_set_drvdata(MTK_WCN_HIF_SDIO_CLTCTX ctx, PVOID private_data_p) +{ + UINT8 probed_idx = CLTCTX_IDX(ctx); + + if (unlikely(!CLTCTX_UIDX_VALID(probed_idx))) { /* invalid index in CLTCTX */ + HIF_SDIO_WARN_FUNC("invalid idx in ctx(0x%x), private_data_p not stored!\n", ctx); + } else { + /* store client driver's private data to dev driver */ + g_hif_sdio_probed_func_list[probed_idx].private_data_p = private_data_p; + HIF_SDIO_DBG_FUNC("private_data_p(0x%p) for ctx(0x%x) probed idx(%d) stored!\n", + private_data_p, ctx, probed_idx); + } +} +EXPORT_SYMBOL(mtk_wcn_hif_sdio_set_drvdata); + +/*! + * \brief get client driver's private data function. + * + * + * \param clent's MTK_WCN_HIF_SDIO_CLTCTX. + * + * \retval private data pointer. + */ +PVOID mtk_wcn_hif_sdio_get_drvdata(MTK_WCN_HIF_SDIO_CLTCTX ctx) +{ + UINT8 probed_idx = CLTCTX_IDX(ctx); + + /* get client driver's private data to dev driver */ + if (likely(CLTCTX_UIDX_VALID(probed_idx))) + return g_hif_sdio_probed_func_list[probed_idx].private_data_p; + /* invalid index in CLTCTX */ + HIF_SDIO_WARN_FUNC("invalid idx in ctx(0x%x), return null!\n", ctx); + return NULL; +} +EXPORT_SYMBOL(mtk_wcn_hif_sdio_get_drvdata); + +/*! + * \brief control stp/wifi on/off from wmt. + * + * + * \param (1)control function type, (2)on/off control. + * + * \retval (1)control results ,(2)unknown type: -5. + * \retval 0:success, -11:not probed, -12:already on, -13:not registered, other errors. + */ +INT32 mtk_wcn_hif_sdio_wmt_control(WMT_SDIO_FUNC_TYPE func_type, MTK_WCN_BOOL is_on) +{ + /* TODO:[FixMe][George]: return value of this function shall distinguish */ + /* 1) not probed by mmc_core yet or */ + /* 2) probed by mmc_core but init fail... */ + switch (func_type) { + case WMT_SDIO_FUNC_STP: + if (is_on == MTK_WCN_BOOL_TRUE) + return hif_sdio_stp_on(); + else + return hif_sdio_stp_off(); + break; + + case WMT_SDIO_FUNC_WIFI: + if (is_on == MTK_WCN_BOOL_TRUE) + return hif_sdio_wifi_on(); + else + return hif_sdio_wifi_off(); + break; + + default: + HIF_SDIO_WARN_FUNC("unknown type(%d)\n", func_type); + return HIF_SDIO_ERR_INVALID_PARAM; + } +} +EXPORT_SYMBOL(mtk_wcn_hif_sdio_wmt_control); + +/*! + * \brief ??? + * + * \detail ??? + * + * \param ctx a context provided by client driver + * \param struct device ** ??? + * + * \retval none + */ +VOID mtk_wcn_hif_sdio_get_dev(MTK_WCN_HIF_SDIO_CLTCTX ctx, struct device **dev) +{ +#if HIF_SDIO_UPDATE + struct sdio_func *func = NULL; +#else + UINT8 probe_index = CLTCTX_IDX(ctx); +#endif + +#if HIF_SDIO_UPDATE + *dev = NULL; /* ensure we does not return any invalid value back. */ + func = hif_sdio_ctx_to_func(ctx); + if (unlikely(!func)) { + HIF_SDIO_WARN_FUNC("no valid *func with ctx(0x%x)\n", ctx); + return; + } + *dev = &(func->dev); + HIF_SDIO_DBG_FUNC("return *dev(0x%p) for ctx(0x%x)\n", *dev, ctx); +#else + if (probe_index < 0) { + HIF_SDIO_WARN_FUNC("func not probed, probe_index = %d", probe_index); + return; + } + *dev = &g_hif_sdio_probed_func_list[probe_index].func->dev; +#endif +} +EXPORT_SYMBOL(mtk_wcn_hif_sdio_get_dev); + +/*! + * \brief client's probe() function. + * + * + * \param work queue structure. + * + * \retval none. + */ +static _osal_inline_ INT32 hif_sdio_clt_probe_func(MTK_WCN_HIF_SDIO_REGISTINFO *registinfo_p, INT8 probe_idx) +{ + UINT16 card_id = 0; + UINT16 func_num = 0; + UINT16 blk_sz = 0; + INT32 ret; + + HIF_SDIO_DBG_FUNC("start!\n"); + HIF_SDIO_ASSERT(registinfo_p); + if (!registinfo_p) { + HIF_SDIO_WARN_FUNC("registinfo_p NULL!!!\n"); + return -1; + } + + /* special case handling: if the clt's unregister is called during probe procedures */ + if (!registinfo_p->func_info || !registinfo_p->sdio_cltinfo) { + HIF_SDIO_WARN_FUNC("client's registinfo_p is cleared !!!\n"); + return -1; + } + + card_id = registinfo_p->func_info->card_id; + func_num = registinfo_p->func_info->func_num; + blk_sz = registinfo_p->func_info->blk_sz; + ret = + registinfo_p->sdio_cltinfo->hif_clt_probe(CLTCTX(card_id, func_num, blk_sz, probe_idx), + registinfo_p->func_info); + + HIF_SDIO_DBG_FUNC + ("clt_probe_func card_id(%x) func_num(%x) blk_sz(%d) prob_idx(%x) ret(%d) %s\n", + card_id, func_num, blk_sz, probe_idx, ret, (ret) ? "fail" : "ok"); + + return ret; +} + +/*! + * \brief client's probe() worker. + * + * + * \param work queue structure. + * + * \retval none. + */ +static VOID hif_sdio_clt_probe_worker(struct work_struct *work) +{ + MTK_WCN_HIF_SDIO_CLT_PROBE_WORKERINFO *clt_worker_info_p = 0; + UINT16 card_id = 0; + UINT16 func_num = 0; + UINT16 blk_sz = 0; + INT8 prob_idx = 0; + + HIF_SDIO_DBG_FUNC("start!\n"); + + HIF_SDIO_ASSERT(work); + + /* get client's information */ + clt_worker_info_p = container_of(work, MTK_WCN_HIF_SDIO_CLT_PROBE_WORKERINFO, probe_work); + HIF_SDIO_ASSERT(clt_worker_info_p); + HIF_SDIO_ASSERT(clt_worker_info_p->registinfo_p); + + /* special case handling: if the clt's unregister is called during probe procedures */ + if ((clt_worker_info_p->registinfo_p->func_info == 0) + || (clt_worker_info_p->registinfo_p->sdio_cltinfo == 0)) { + HIF_SDIO_WARN_FUNC("client's registinfo_p is cleared !!!\n"); + vfree(clt_worker_info_p); + return; + } + + card_id = clt_worker_info_p->registinfo_p->func_info->card_id; + func_num = clt_worker_info_p->registinfo_p->func_info->func_num; + blk_sz = clt_worker_info_p->registinfo_p->func_info->blk_sz; + prob_idx = clt_worker_info_p->probe_idx; + + /* Execute client's probe() func */ + clt_worker_info_p->registinfo_p-> + sdio_cltinfo->hif_clt_probe(CLTCTX(card_id, func_num, blk_sz, prob_idx), + clt_worker_info_p->registinfo_p->func_info); + + vfree(clt_worker_info_p); + + HIF_SDIO_DBG_FUNC("card_id(0x%x) func_num(0x%x) blk_sz(0x%x) prob_idx(0x%x)\n", card_id, + func_num, blk_sz, prob_idx); + HIF_SDIO_DBG_FUNC("end!\n"); +} + +/*! + * \brief client's probe() worker. + * + * + * \param work queue structure. + * + * \retval none. + */ +static _osal_inline_ VOID hif_sdio_dump_probe_list(VOID) +{ + INT32 i; + + HIF_SDIO_DBG_FUNC("== DUMP probed list start ==\n"); + + for (i = 0; i < CFG_CLIENT_COUNT; i++) { + if (g_hif_sdio_probed_func_list[i].func) { + HIF_SDIO_DBG_FUNC("index(%d) func(0x%p) clt_idx(%d)\n", + i, g_hif_sdio_probed_func_list[i].func, + g_hif_sdio_probed_func_list[i].clt_idx); + + HIF_SDIO_DBG_FUNC("vendor(0x%x) device(0x%x) num(0x%x) state(%d)\n", + g_hif_sdio_probed_func_list[i].func->vendor, + g_hif_sdio_probed_func_list[i].func->device, + g_hif_sdio_probed_func_list[i].func->num, + g_hif_sdio_probed_func_list[i].on_by_wmt); + + } + } + + HIF_SDIO_DBG_FUNC("== DUMP probed list end ==\n"); +} + + +/*! + * \brief Initialize g_hif_sdio_probed_func_list + * + * + * \param index of g_hif_sdio_probed_func_list. + * + * \retval none. + */ +static _osal_inline_ VOID hif_sdio_init_probed_list(INT32 index) +{ + if ((index >= 0) && (index < CFG_CLIENT_COUNT)) { + /* probed spin lock */ + spin_lock_bh(&g_hif_sdio_lock_info.probed_list_lock); + g_hif_sdio_probed_func_list[index].func = 0; + g_hif_sdio_probed_func_list[index].clt_idx = -1; + g_hif_sdio_probed_func_list[index].private_data_p = 0; + g_hif_sdio_probed_func_list[index].on_by_wmt = MTK_WCN_BOOL_FALSE; + /* probed spin unlock */ + spin_unlock_bh(&g_hif_sdio_lock_info.probed_list_lock); + } else + HIF_SDIO_ERR_FUNC("index is out of g_hif_sdio_probed_func_list[] boundary!\n"); +} + + +/*! + * \brief Initialize g_hif_sdio_clt_drv_list + * + * + * \param index of g_hif_sdio_clt_drv_list. + * + * \retval none. + */ +static _osal_inline_ VOID hif_sdio_init_clt_list(INT32 index) +{ + /* client list spin lock */ + spin_lock_bh(&g_hif_sdio_lock_info.clt_list_lock); + if ((index >= 0) && (index < CFG_CLIENT_COUNT)) { + g_hif_sdio_clt_drv_list[index].sdio_cltinfo = 0; + g_hif_sdio_clt_drv_list[index].func_info = 0; + } else + HIF_SDIO_ERR_FUNC("index is out of g_hif_sdio_clt_drv_list[] boundary!\n"); + /* client list spin unlock */ + spin_unlock_bh(&g_hif_sdio_lock_info.clt_list_lock); +} + + +/*! + * \brief find matched g_hif_sdio_probed_func_list index from sdio function handler + * + * + * \param sdio function handler + * + * \retval -1 index not found + * \retval >= 0 return found index + */ +static _osal_inline_ INT32 hif_sdio_find_probed_list_index_by_func(struct sdio_func *func) +{ + INT32 i = 0; + + HIF_SDIO_ASSERT(func); + + for (i = 0; i < CFG_CLIENT_COUNT; i++) { + if (g_hif_sdio_probed_func_list[i].func == func) + return i; + } + + return -1; +} + +/*! + * \brief find matched g_hif_sdio_probed_func_list from vendor_id, device_id, and function number + * + * + * \param vendor id, device id, and function number of the sdio card. + * + * \retval -1 index not found + * \retval >= 0 return found index + */ +static _osal_inline_ INT32 hif_sdio_find_probed_list_index_by_id_func(UINT16 vendor, UINT16 device, + UINT16 func_num) +{ + INT32 i; + + for (i = 0; i < CFG_CLIENT_COUNT; i++) { + if (g_hif_sdio_probed_func_list[i].func) { + HIF_SDIO_DBG_FUNC("probed entry: vendor(0x%x) device(0x%x) num(0x%x)\n", + g_hif_sdio_probed_func_list[i].func->vendor, + g_hif_sdio_probed_func_list[i].func->device, + g_hif_sdio_probed_func_list[i].func->num); + } + } + for (i = 0; i < CFG_CLIENT_COUNT; i++) { + if (!g_hif_sdio_probed_func_list[i].func) { + continue; + } else if ((g_hif_sdio_probed_func_list[i].func->vendor == vendor) && + (g_hif_sdio_probed_func_list[i].func->device == device) && + (g_hif_sdio_probed_func_list[i].func->num == func_num)) { + return i; + } + } + + if (i == CFG_CLIENT_COUNT) { + /* + * pr_warn(DRV_NAME "Cannot find vendor:0x%x, device:0x%x, func_num:0x%x, i=%d\n", + * vendor, device, func_num, i); + */ + /* client func has not been probed */ + return -1; + } + return -1; +} + +/*! + * \brief find matched g_hif_sdio_clt_drv_list index + * + * find the matched g_hif_sdio_clt_drv_list index from card_id and function number. + * + * \param vendor id, device id, and function number of the sdio card + * + * \retval -1 index not found + * \retval >= 0 return found index + */ +static _osal_inline_ INT32 hif_sdio_find_clt_list_index(UINT16 vendor, UINT16 device, UINT16 func_num) +{ + INT32 i = 0; + + for (i = 0; i < CFG_CLIENT_COUNT; i++) { + if (g_hif_sdio_clt_drv_list[i].func_info != 0) { + if ((g_hif_sdio_clt_drv_list[i].func_info->manf_id == vendor) && + (g_hif_sdio_clt_drv_list[i].func_info->card_id == device) && + (g_hif_sdio_clt_drv_list[i].func_info->func_num == func_num)) { + return i; + } + } + } + + return -1; +} + + +/*! + * \brief check if the vendor, device ids are supported in mtk_sdio_id_tbl. + * + * + * \param vendor id and device id of the sdio card + * + * \retval (-HIF_SDIO_ERR_FAIL) vendor, device ids are not supported + * \retval HIF_SDIO_ERR_SUCCESS vendor, device ids are supported + */ +static _osal_inline_ INT32 hif_sdio_check_supported_sdio_id(UINT16 vendor, UINT16 device) +{ + INT32 i = 0; + + for (i = 0; i < CFG_CLIENT_COUNT; i++) { + if ((mtk_sdio_id_tbl[i].vendor == vendor) && (mtk_sdio_id_tbl[i].device == device)) + return HIF_SDIO_ERR_SUCCESS; /* mtk_sdio_id is supported */ + } + return -HIF_SDIO_ERR_FAIL; /* mtk_sdio_id is not supported */ +} + + +/*! + * \brief check if the vendor, device ids are duplicated in g_hif_sdio_clt_drv_list. + * + * + * \param vendor id, device id, and function number of the sdio card + * + * \retval (-HIF_SDIO_ERR_DUPLICATED) vendor, device, func_num are duplicated + * \retval HIF_SDIO_ERR_SUCCESS vendor, device, func_num are not duplicated + */ +static _osal_inline_ INT32 hif_sdio_check_duplicate_sdio_id(UINT16 vendor, UINT16 device, UINT16 func_num) +{ + INT32 i = 0; + + for (i = 0; i < CFG_CLIENT_COUNT; i++) { + if (g_hif_sdio_clt_drv_list[i].func_info != 0) { + if ((g_hif_sdio_clt_drv_list[i].func_info->manf_id == vendor) && + (g_hif_sdio_clt_drv_list[i].func_info->card_id == device) && + (g_hif_sdio_clt_drv_list[i].func_info->func_num == func_num)) { + return -HIF_SDIO_ERR_DUPLICATED; /* duplicated */ + } + } + } + return HIF_SDIO_ERR_SUCCESS; /* Not duplicated */ +} + + +/*! + * \brief Add the client info into g_hif_sdio_clt_drv_list. + * + * + * \param [output] client's index pointer. + * \param MTK_WCN_HIF_SDIO_CLTINFO of client's contex. + * + * \retval (-HIF_SDIO_ERR_FAIL) Add to clt_list successfully + * \retval HIF_SDIO_ERR_SUCCESS Add to clt_list failed (buffer is full) + */ +static _osal_inline_ INT32 hif_sdio_add_clt_list(PINT32 clt_index_p, + const MTK_WCN_HIF_SDIO_CLTINFO *pinfo, UINT32 tbl_index) +{ + INT32 i = 0; + + HIF_SDIO_ASSERT(clt_index_p); + HIF_SDIO_ASSERT(pinfo); + + for (i = 0; i < CFG_CLIENT_COUNT; i++) { + /* client list spin lock */ + spin_lock_bh(&g_hif_sdio_lock_info.clt_list_lock); + if (g_hif_sdio_clt_drv_list[i].func_info == 0) { + g_hif_sdio_clt_drv_list[i].func_info = &(pinfo->func_tbl[tbl_index]); + g_hif_sdio_clt_drv_list[i].sdio_cltinfo = pinfo; + /* client list spin unlock */ + spin_unlock_bh(&g_hif_sdio_lock_info.clt_list_lock); + *clt_index_p = i; + return HIF_SDIO_ERR_SUCCESS; /* Add to client list successfully */ + } + /* client list spin unlock */ + spin_unlock_bh(&g_hif_sdio_lock_info.clt_list_lock); + } + return -HIF_SDIO_ERR_FAIL; /* Add to client list failed (buffer is full) */ +} + +#if HIF_SDIO_SUPPORT_SUSPEND +static INT32 hif_sdio_suspend(struct device *dev) +{ + struct sdio_func *func = NULL; + mmc_pm_flag_t flag; + INT32 ret; + + if (!dev) + return -EINVAL; + + func = dev_to_sdio_func(dev); + HIF_SDIO_DBG_FUNC("prepare for func(0x%p)\n", func); + flag = sdio_get_host_pm_caps(func); +#if HIF_SDIO_SUPPORT_WAKEUP + if (!(flag & MMC_PM_KEEP_POWER) || !(flag & MMC_PM_WAKE_SDIO_IRQ)) { + HIF_SDIO_WARN_FUNC + ("neither MMC_PM_KEEP_POWER or MMC_PM_WAKE_SDIO_IRQ is supported by host, return -ENOTSUPP\n"); + return -ENOTSUPP; + } + + /* set both */ + flag |= MMC_PM_KEEP_POWER | MMC_PM_WAKE_SDIO_IRQ; +#else + if (!(flag & MMC_PM_KEEP_POWER)) { + HIF_SDIO_WARN_FUNC + ("neither MMC_PM_KEEP_POWER is supported by host, return -ENOTSUPP\n"); + return -ENOTSUPP; + } + flag |= MMC_PM_KEEP_POWER; +#endif + ret = sdio_set_host_pm_flags(func, flag); + if (ret) { + HIF_SDIO_INFO_FUNC + ("set MMC_PM_KEEP_POWER to host fail(%d)\n", ret); + return -EFAULT; + } +#if HIF_SDIO_SUPPORT_WAKEUP + sdio_claim_host(func); +#endif + HIF_SDIO_INFO_FUNC("set MMC_PM_KEEP_POWER ok\n"); + return 0; +} + +static INT32 hif_sdio_resume(struct device *dev) +{ +#if HIF_SDIO_SUPPORT_WAKEUP + struct sdio_func *func = NULL; +#endif + if (!dev) { + HIF_SDIO_WARN_FUNC("null dev!\n"); + return -EINVAL; + } +#if HIF_SDIO_SUPPORT_WAKEUP + func = dev_to_sdio_func(dev); + sdio_release_host(func); +#endif + HIF_SDIO_INFO_FUNC("do nothing\n"); + + return 0; +} +#endif + +/*! + * \brief hif_sdio probe function + * + * hif_sdio probe function called by mmc driver when any matched SDIO function + * is detected by it. + * + * \param func + * \param id + * + * \retval 0 register successfully + * \retval < 0 list error code here + */ +static INT32 hif_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) +{ + INT32 ret = 0; + INT32 i = 0; + MTK_WCN_HIF_SDIO_PROBEINFO *hif_sdio_probed_funcp = 0; + INT32 probe_index = -1; + INT32 idx; +#if 0 + INT32 clt_index = -1; + MTK_WCN_HIF_SDIO_CLT_PROBE_WORKERINFO *clt_probe_worker_info = 0; +#endif + + HIF_SDIO_DBG_FUNC("start!\n"); + HIF_SDIO_ASSERT(func); +#if !(DELETE_HIF_SDIO_CHRDEV) + hif_sdio_match_chipid_by_dev_id(id); +#endif + /* 4 <0> display debug information */ + HIF_SDIO_INFO_FUNC("vendor(0x%x) device(0x%x) num(0x%x)\n", func->vendor, func->device, + func->num); + for (i = 0; i < func->card->num_info; i++) + HIF_SDIO_DBG_FUNC("card->info[%d]: %s\n", i, func->card->info[i]); + + /* 4 <1> Check if this is supported by us (mtk_sdio_id_tbl) */ + ret = hif_sdio_check_supported_sdio_id(func->vendor, func->device); + if (ret) { + HIF_SDIO_WARN_FUNC + ("vendor id and device id of sdio_func are not supported in mtk_sdio_id_tbl!\n"); + goto out; + } + /* 4 <2> Add this struct sdio_func *func to g_hif_sdio_probed_func_list */ + for (i = 0; i < CFG_CLIENT_COUNT; i++) { + /* probed spin lock */ + spin_lock_bh(&g_hif_sdio_lock_info.probed_list_lock); + if (g_hif_sdio_probed_func_list[i].func == 0) { + hif_sdio_probed_funcp = &g_hif_sdio_probed_func_list[i]; + hif_sdio_probed_funcp->func = func; + hif_sdio_probed_funcp->clt_idx = + hif_sdio_find_clt_list_index(func->vendor, func->device, func->num); + hif_sdio_probed_funcp->on_by_wmt = MTK_WCN_BOOL_FALSE; + hif_sdio_probed_funcp->sdio_irq_enabled = MTK_WCN_BOOL_FALSE; + /* probed spin unlock */ + spin_unlock_bh(&g_hif_sdio_lock_info.probed_list_lock); + probe_index = i; + break; + } + /* probed spin unlock */ + spin_unlock_bh(&g_hif_sdio_lock_info.probed_list_lock); + } + if ((probe_index < 0) || (probe_index >= CFG_CLIENT_COUNT)) { + HIF_SDIO_ERR_FUNC("probe function list if full!\n"); + goto out; + } + /* 4 <3> Initialize this function */ + if (g_hif_sdio_probed_func_list[probe_index].clt_idx < 0) { + for (i = 0; i < CFG_CLIENT_COUNT; i++) { + /* client list spin lock */ + spin_lock_bh(&g_hif_sdio_lock_info.clt_list_lock); + if (g_hif_sdio_clt_drv_list[i].func_info == 0) { + /* client list spin unlock */ + spin_unlock_bh(&g_hif_sdio_lock_info.clt_list_lock); + continue; + } + HIF_SDIO_INFO_FUNC("manf_id:%x, card_id:%x, func_num:%d\n", + g_hif_sdio_clt_drv_list[i].func_info->manf_id, + g_hif_sdio_clt_drv_list[i].func_info->card_id, + g_hif_sdio_clt_drv_list[i].func_info->func_num); + if ((g_hif_sdio_clt_drv_list[i].func_info->manf_id == + g_hif_sdio_probed_func_list[probe_index].func->vendor) + && (g_hif_sdio_clt_drv_list[i].func_info->card_id == + g_hif_sdio_probed_func_list[probe_index].func->device) + && (g_hif_sdio_clt_drv_list[i].func_info->func_num == + g_hif_sdio_probed_func_list[probe_index].func->num)) { + g_hif_sdio_probed_func_list[probe_index].clt_idx = i; + /* client list spin unlock */ + spin_unlock_bh(&g_hif_sdio_lock_info.clt_list_lock); + break; + } + /* client list spin unlock */ + spin_unlock_bh(&g_hif_sdio_lock_info.clt_list_lock); + } + HIF_SDIO_INFO_FUNC("map to g_hif_sdio_clt_drv_list[] done: %d\n", + g_hif_sdio_probed_func_list[probe_index].clt_idx); + } + /* 4 <3.1> enable this function */ + sdio_claim_host(func); + ret = sdio_enable_func(func); + sdio_release_host(func); + if (ret) { + HIF_SDIO_ERR_FUNC("sdio_enable_func failed!\n"); + goto out; + } + + /* 4 <3.2> set block size according to the table storing function characteristics */ + if (hif_sdio_probed_funcp == 0) { + HIF_SDIO_ERR_FUNC("hif_sdio_probed_funcp is null!\n"); + goto out; + } + if (hif_sdio_probed_funcp->clt_idx >= 0 && + hif_sdio_probed_funcp->clt_idx < CFG_CLIENT_COUNT) { + /* The clt contex has been registed */ + sdio_claim_host(func); + idx = hif_sdio_probed_funcp->clt_idx; + ret = sdio_set_block_size(func, g_hif_sdio_clt_drv_list[idx].func_info->blk_sz); + sdio_release_host(func); + } else { /* The clt contex has not been registed */ + + sdio_claim_host(func); + ret = sdio_set_block_size(func, HIF_DEFAULT_BLK_SIZE); + sdio_release_host(func); + } + if (ret) { + HIF_SDIO_ERR_FUNC("set sdio block size failed!\n"); + goto out; + } + + HIF_SDIO_DBG_FUNC("cur_blksize(%d) max(%d), host max blk_size(%d) blk_count(%d)\n", + func->cur_blksize, func->max_blksize, + func->card->host->max_blk_size, func->card->host->max_blk_count); + + + hif_sdio_dump_probe_list(); + +out: + /* 4 error handling */ + return ret; +} + + +/*! + * \brief hif_sdio remove function + * + * hif_sdio probe function called by mmc driver when the probed func should be + * removed. + * + * \param func + * + */ +static VOID hif_sdio_remove(struct sdio_func *func) +{ + INT32 probed_list_index = 0; +#if 0 + INT32 registed_list_index = 0; +#endif + + HIF_SDIO_DBG_FUNC("start!\n"); + HIF_SDIO_ASSERT(func); + + /* 4 <1> check input parameter is valid and has been probed previously */ + if (func == NULL) { + HIF_SDIO_ERR_FUNC("func null(%p)\n", func); + return; + } + /* 4 <2> if this function has been initialized by any client driver, */ + /* 4 call client's .hif_clt_remove() call back in THIS context. */ + probed_list_index = hif_sdio_find_probed_list_index_by_func(func); + if (probed_list_index < 0) { + HIF_SDIO_WARN_FUNC + ("sdio function pointer is not in g_hif_sdio_probed_func_list!\n"); + return; + } +#if 0 + registed_list_index = g_hif_sdio_probed_func_list[probed_list_index].clt_idx; + if (registed_list_index >= 0) { + g_hif_sdio_clt_drv_list[registed_list_index].sdio_cltinfo->hif_clt_remove(CLTCTX + (func-> + device, + func-> + num, + func-> + cur_blksize, + probed_list_index)); + } +#endif + + /* 4 <3> mark this function as de-initialized and invalidate client's context */ + hif_sdio_init_probed_list(probed_list_index); + +#if 0 + /* 4 <4> release irq for this function */ + sdio_claim_host(func); + sdio_release_irq(func); + sdio_release_host(func); +#endif + + /* 4 <5> disable this function */ + sdio_claim_host(func); + sdio_disable_func(func); + sdio_release_host(func); + + /* 4 <6> mark this function as removed */ + + HIF_SDIO_DBG_FUNC("sdio func(0x%p) is removed successfully!\n", func); +} + +/*! + * \brief hif_sdio interrupt handler + * + * detailed descriptions + * + * \param ctx client's context variable + * + */ +static VOID hif_sdio_irq(struct sdio_func *func) +{ + INT32 probed_list_index = -1; + INT32 registed_list_index = -1; + INT32 ret; + + HIF_SDIO_DBG_FUNC("start!\n"); + + osal_ftrace_print("%s|S\n", __func__); + /* 4 <1> check if func is valid */ + HIF_SDIO_ASSERT(func); + + /* 4 <2> if func has valid corresponding hif_sdio client's context, mark it */ + /* 4 host-locked, use it to call client's .hif_clt_irq() callback function in */ + /* 4 THIS context. */ + probed_list_index = hif_sdio_find_probed_list_index_by_func(func); + if ((probed_list_index < 0) || (probed_list_index >= CFG_CLIENT_COUNT)) { + HIF_SDIO_ERR_FUNC("probed_list_index not found!\n"); + return; + } + /* [George] added for sdio irq sync and mmc single_irq workaround. It's set + * enabled later by client driver call mtk_wcn_hif_sdio_enable_irq() + */ + /* skip smp_rmb() here */ + if (g_hif_sdio_probed_func_list[probed_list_index].sdio_irq_enabled == MTK_WCN_BOOL_FALSE) { + HIF_SDIO_WARN_FUNC("func(0x%p),probed_idx(%d) sdio irq not enabled yet\n", + func, probed_list_index); + return; + } + + registed_list_index = g_hif_sdio_probed_func_list[probed_list_index].clt_idx; +/* g_hif_sdio_probed_func_list[probed_list_index].interrupted = MTK_WCN_BOOL_TRUE; */ + if ((registed_list_index >= 0) + && (registed_list_index < CFG_CLIENT_COUNT)) { + HIF_SDIO_DBG_FUNC("[%d]SDIO IRQ (func:0x%p) v(0x%x) d(0x%x) n(0x%x)\n", + probed_list_index, func, func->vendor, func->device, func->num); + + g_hif_sdio_clt_drv_list[registed_list_index].sdio_cltinfo->hif_clt_irq(CLTCTX + (func-> + device, + func->num, + func-> + cur_blksize, + probed_list_index)); + } else { + /* 4 <3> if func has no VALID hif_sdio client's context, release irq for this */ + /* 4 func and mark it in g_hif_sdio_probed_func_list (remember: donnot claim host in irq contex). */ + HIF_SDIO_WARN_FUNC("release irq (func:0x%p) v(0x%x) d(0x%x) n(0x%x)\n", + func, func->vendor, func->device, func->num); + mtk_wcn_hif_sdio_irq_flag_set(0); + ret = sdio_release_irq(func); + if (ret) + HIF_SDIO_WARN_FUNC("sdio_release_irq() fail(%d)\n", ret); + } + osal_ftrace_print("%s|E\n", __func__); +} + +/*! + * \brief hif_sdio init function + * + * detailed descriptions + * + * \retval + */ +static INT32 hif_sdio_init(VOID) +{ + INT32 ret = 0; + INT32 i = 0; + + HIF_SDIO_INFO_FUNC("start!\n"); + + /* 4 <1> init all private variables */ + /* init reference count to 0 */ + gRefCount = 0; + + atomic_set(&hif_sdio_irq_enable_flag, 0); + /* init spin lock information */ + spin_lock_init(&g_hif_sdio_lock_info.probed_list_lock); + spin_lock_init(&g_hif_sdio_lock_info.clt_list_lock); + + /* init probed function list and g_hif_sdio_clt_drv_list */ + for (i = 0; i < CFG_CLIENT_COUNT; i++) { + hif_sdio_init_probed_list(i); + hif_sdio_init_clt_list(i); + } + + /* 4 <2> register to mmc driver */ + ret = sdio_register_driver(&mtk_sdio_client_drv); + if (ret != 0) + HIF_SDIO_INFO_FUNC("sdio_register_driver() fail, ret=%d\n", ret); + +#if !(DELETE_HIF_SDIO_CHRDEV) + /* 4 <3> create thread for query chip id and device node for launcher to access */ + if (hifsdiod_start() == 0) + hif_sdio_create_dev_node(); +#endif + hif_sdio_deep_sleep_info_init(); + HIF_SDIO_DBG_FUNC("end!\n"); + return ret; +} + +/*! + * \brief hif_sdio init function + * + * detailed descriptions + * + * \retval + */ +static VOID hif_sdio_exit(VOID) +{ + HIF_SDIO_INFO_FUNC("start!\n"); + +#if !(DELETE_HIF_SDIO_CHRDEV) + hif_sdio_remove_dev_node(); + hifsdiod_stop(); +#endif + + /* 4 <0> if client driver is not removed yet, we shall NOT be called... */ + + /* 4 <1> check reference count */ + if (gRefCount != 0) + HIF_SDIO_WARN_FUNC("gRefCount=%d !!!\n", gRefCount); + /* 4 <2> check if there is any hif_sdio-registered clients. There should be */ + /* 4 no registered client... */ + + /* 4 <3> Reregister with mmc driver. Our remove handler hif_sdio_remove() */ + /* 4 will be called later by mmc_core. Clean up driver resources there. */ + sdio_unregister_driver(&mtk_sdio_client_drv); + atomic_set(&hif_sdio_irq_enable_flag, 0); + HIF_SDIO_DBG_FUNC("end!\n"); +} /* end of exitWlan() */ + +/*! + * \brief stp on by wmt (probe client driver). + * + * + * \param none. + * + * \retval 0:success, -11:not probed, -12:already on, -13:not registered, other errors. + */ +static _osal_inline_ INT32 hif_sdio_stp_on(VOID) +{ +#if 0 + MTK_WCN_HIF_SDIO_CLT_PROBE_WORKERINFO *clt_probe_worker_info = 0; +#endif + INT32 clt_index = -1; + INT32 probe_index = -1; + INT32 ret = -1; + INT32 ret2 = -1; + struct sdio_func *func = NULL; + UINT32 chip_id = 0; + UINT16 func_num = 0; + + const MTK_WCN_HIF_SDIO_FUNCINFO *func_info = NULL; + + HIF_SDIO_DBG_FUNC("hif_sdio_stp_on, start!\n"); + + /* 4 <1> If stp client drv has not been probed, return error code */ + /* MT6620 */ + probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x020B, 1); + if (probe_index >= 0) + goto stp_on_exist; + probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x020C, 1); + if (probe_index >= 0) + goto stp_on_exist; + + /* MT6628 */ + probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x6628, 2); + if (probe_index >= 0) + goto stp_on_exist; + /* MT6630 */ + probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x6630, 2); + if (probe_index >= 0) { + chip_id = 0x6630; + func_num = 2; + goto stp_on_exist; + } + /* MT6632 */ + probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x6632, 2); + if (probe_index >= 0) { + chip_id = 0x6632; + func_num = 2; + goto stp_on_exist; + } + /* MT6619 */ + probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x6619, 1); + if (probe_index >= 0) + goto stp_on_exist; + + /* MT6618 */ + probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x018B, 1); + if (probe_index >= 0) + goto stp_on_exist; + probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x018C, 1); + if (probe_index >= 0) + goto stp_on_exist; + else { + /* 4 <2> If stp client drv has not been probed, return error code */ + /* client func has not been probed */ + HIF_SDIO_INFO_FUNC("no supported func probed\n"); + return HIF_SDIO_ERR_NOT_PROBED; + } + +stp_on_exist: + /* 4 <3> If stp client drv has been on by wmt, return error code */ + if (g_hif_sdio_probed_func_list[probe_index].on_by_wmt != MTK_WCN_BOOL_FALSE) { + HIF_SDIO_INFO_FUNC("already on...\n"); + return HIF_SDIO_ERR_ALRDY_ON; + } + g_hif_sdio_probed_func_list[probe_index].on_by_wmt = MTK_WCN_BOOL_TRUE; + + clt_index = g_hif_sdio_probed_func_list[probe_index].clt_idx; + if (clt_index >= 0) { /* the function has been registered */ + g_hif_sdio_probed_func_list[probe_index].sdio_irq_enabled = MTK_WCN_BOOL_FALSE; + /* 4 <4> claim irq for this function */ + func = g_hif_sdio_probed_func_list[probe_index].func; + if (unlikely(!(func) || !(func->card) || !(func->card->host) + || mmc_card_removed(func->card))) { + HIF_SDIO_ERR_FUNC("sdio host is missing\n"); + return HIF_SDIO_ERR_NOT_PROBED; + } + sdio_claim_host(func); + ret = sdio_claim_irq(func, hif_sdio_irq); + mtk_wcn_hif_sdio_irq_flag_set(1); + sdio_release_host(func); + if (ret) { + HIF_SDIO_WARN_FUNC("sdio_claim_irq() for stp fail(%d)\n", ret); + return ret; + } + HIF_SDIO_DBG_FUNC("sdio_claim_irq() for stp ok\n"); + + /* 4 <5> If this struct sdio_func *func is supported by any driver in */ + /* 4 g_hif_sdio_clt_drv_list, schedule another task to call client's .hif_clt_probe() */ + /* TODO: [FixMe][George] WHY probe worker is removed??? */ +#if 1 + /* Call client's .hif_clt_probe() */ + ret = hif_sdio_clt_probe_func(&g_hif_sdio_clt_drv_list[clt_index], probe_index); + if (ret) { + HIF_SDIO_WARN_FUNC("clt_probe_func() for stp fail(%d) release irq\n", ret); + sdio_claim_host(func); + mtk_wcn_hif_sdio_irq_flag_set(0); + ret2 = sdio_release_irq(func); + sdio_release_host(func); + if (ret2) + HIF_SDIO_WARN_FUNC("sdio_release_irq() for stp fail(%d)\n", ret2); + + g_hif_sdio_probed_func_list[probe_index].on_by_wmt = MTK_WCN_BOOL_FALSE; + return ret; + } + g_hif_sdio_probed_func_list[probe_index].sdio_irq_enabled = MTK_WCN_BOOL_TRUE; + + /*set deep sleep information to global data struct */ + func_info = g_hif_sdio_clt_drv_list[clt_index].func_info; + hif_sdio_deep_sleep_info_set_act(chip_id, func_num, + CLTCTX(func_info->card_id, func_info->func_num, + func_info->blk_sz, probe_index), 1); + + + HIF_SDIO_DBG_FUNC("hif_sdio_stp_on, ok!\n"); + + return 0; +#else + /* use worker thread to perform the client's .hif_clt_probe() */ + clt_probe_worker_info = vmalloc(sizeof(MTK_WCN_HIF_SDIO_CLT_PROBE_WORKERINFO)); + INIT_WORK(&clt_probe_worker_info->probe_work, hif_sdio_clt_probe_worker); + clt_probe_worker_info->registinfo_p = &g_hif_sdio_clt_drv_list[clt_index]; + clt_probe_worker_info->probe_idx = probe_index; + schedule_work(&clt_probe_worker_info->probe_work); +#endif + } else { + /* TODO: [FixMe][George] check if clt_index is cleared in client's unregister function */ + HIF_SDIO_WARN_FUNC("probed but not registered yet (%d)\n", ret); + return HIF_SDIO_ERR_CLT_NOT_REG; + } +} + +/*! + * \brief stp off by wmt (remove client driver). + * + * + * \param none. + * + * \retval 0:success, -11:not probed, -12:already off, -13:not registered, other errors. + */ +static _osal_inline_ INT32 hif_sdio_stp_off(VOID) +{ + INT32 clt_index = -1; + INT32 probe_index = -1; + INT32 ret = -1; + INT32 ret2 = -1; + struct sdio_func *func = NULL; + UINT32 chip_id = 0; + UINT16 func_num = 0; + const MTK_WCN_HIF_SDIO_FUNCINFO *func_info = NULL; + + HIF_SDIO_DBG_FUNC("hif_sdio_stp_off, start!\n"); + + /* 4 <1> If stp client drv has not been probed, return error code */ + /* MT6620 */ + probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x020B, 1); + if (probe_index >= 0) + goto stp_off_exist; + probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x020C, 1); + if (probe_index >= 0) + goto stp_off_exist; + + /* MT6628 */ + probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x6628, 2); + if (probe_index >= 0) + goto stp_off_exist; + /* MT6630 */ + probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x6630, 2); + if (probe_index >= 0) { + chip_id = 0x6630; + func_num = 2; + goto stp_off_exist; + } + /* MT6632 */ + probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x6632, 2); + if (probe_index >= 0) { + chip_id = 0x6632; + func_num = 2; + goto stp_off_exist; + } + + /* MT6619 */ + probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x6619, 1); + if (probe_index >= 0) + goto stp_off_exist; + + /* MT6618 */ + probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x018B, 1); + if (probe_index >= 0) + goto stp_off_exist; + probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x018C, 1); + if (probe_index >= 0) + goto stp_off_exist; + else { + /* 4 <2> If stp client drv has not been probed, return error code */ + /* client func has not been probed */ + return HIF_SDIO_ERR_NOT_PROBED; + } + +stp_off_exist: + /* 4 <3> If stp client drv has been off by wmt, return error code */ + if (g_hif_sdio_probed_func_list[probe_index].on_by_wmt == MTK_WCN_BOOL_FALSE) { + HIF_SDIO_WARN_FUNC("already off...\n"); + return HIF_SDIO_ERR_ALRDY_OFF; + } + g_hif_sdio_probed_func_list[probe_index].on_by_wmt = MTK_WCN_BOOL_FALSE; + +#if 0 /* TODO: [FixMe][George] moved below as done in stp_on. */ + /* 4 <4> release irq for this function */ + func = g_hif_sdio_probed_func_list[probe_index].func; + sdio_claim_host(func); + ret = sdio_release_irq(func); + sdio_release_host(func); + if (ret) + pr_warn(DRV_NAME "sdio_release_irq for stp fail(%d)\n", ret); + else + pr_warn(DRV_NAME "sdio_release_irq for stp ok\n"); +#endif + clt_index = g_hif_sdio_probed_func_list[probe_index].clt_idx; + if (clt_index >= 0) { /* the function has been registered */ + func = g_hif_sdio_probed_func_list[probe_index].func; + + if (unlikely(!(func) || !(func->card) || !(func->card->host) + || mmc_card_removed(func->card))) { + HIF_SDIO_ERR_FUNC("sdio host is missing\n"); + return HIF_SDIO_ERR_ALRDY_OFF; + } + /* 4 <4> release irq for this function */ + sdio_claim_host(func); + mtk_wcn_hif_sdio_irq_flag_set(0); + ret2 = sdio_release_irq(func); + sdio_release_host(func); + + if (ret2) + HIF_SDIO_WARN_FUNC("sdio_release_irq() for stp fail(%d)\n", ret2); + else + HIF_SDIO_DBG_FUNC("sdio_release_irq() for stp ok\n"); + + /* 4 <5> Callback to client driver's remove() func */ + ret = + g_hif_sdio_clt_drv_list[clt_index]. + sdio_cltinfo->hif_clt_remove(CLTCTX + (func->device, func->num, func->cur_blksize, + probe_index)); + if (ret) + HIF_SDIO_WARN_FUNC("clt_remove for stp fail(%d)\n", ret); + else + HIF_SDIO_DBG_FUNC("hif_sdio_stp_off, ok!\n"); + + /*set deep sleep information to global data struct */ + func_info = g_hif_sdio_clt_drv_list[clt_index].func_info; + hif_sdio_deep_sleep_info_set_act(chip_id, func_num, + CLTCTX(func_info->card_id, func_info->func_num, + func_info->blk_sz, probe_index), 0); + return ret + ret2; + } + /* TODO: [FixMe][George] check if clt_index is cleared in client's unregister function */ + HIF_SDIO_WARN_FUNC("probed but not registered yet (%d)\n", ret); + return HIF_SDIO_ERR_CLT_NOT_REG; +} + +/*! + * \brief wifi on by wmt (probe client driver). + * + * + * \param none. + * + * \retval 0:success, -11:not probed, -12:already on, -13:not registered, other errors. + */ +static _osal_inline_ INT32 hif_sdio_wifi_on(VOID) +{ +#if 0 + MTK_WCN_HIF_SDIO_CLT_PROBE_WORKERINFO *clt_probe_worker_info = 0; +#endif + INT32 clt_index = -1; + INT32 probe_index = -1; + INT32 ret = 0; + INT32 ret2 = 0; + struct sdio_func *func = NULL; + UINT32 chip_id = 0; + UINT16 func_num = 0; + const MTK_WCN_HIF_SDIO_FUNCINFO *func_info = NULL; + + HIF_SDIO_DBG_FUNC("start!\n"); + + /* 4 <1> If wifi client drv has not been probed, return error code */ + /* MT6620 */ + probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x020A, 1); + if (probe_index >= 0) + goto wifi_on_exist; + probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x020C, 2); + if (probe_index >= 0) + goto wifi_on_exist; + /* MT6628 */ + probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x6628, 1); + if (probe_index == 0) + goto wifi_on_exist; + /* MT6630 */ + probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x6630, 1); + if (probe_index >= 0) { + chip_id = 0x6630; + func_num = 1; + goto wifi_on_exist; + } + /* MT6632 */ + probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x6602, 1); + if (probe_index >= 0) { + chip_id = 0x6632; + func_num = 1; + goto wifi_on_exist; + } + + /* MT6618 */ + probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x018A, 1); + if (probe_index == 0) + goto wifi_on_exist; + probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x018C, 2); + if (probe_index >= 0) + goto wifi_on_exist; + else { + /* 4 <2> If wifi client drv has not been probed, return error code */ + /* client func has not been probed */ + return HIF_SDIO_ERR_NOT_PROBED; + } + +wifi_on_exist: + /* 4 <3> If wifi client drv has been on by wmt, return error code */ + if (g_hif_sdio_probed_func_list[probe_index].on_by_wmt) { + HIF_SDIO_INFO_FUNC("probe_index (%d), already on...\n", probe_index); + return HIF_SDIO_ERR_ALRDY_ON; + } + clt_index = g_hif_sdio_probed_func_list[probe_index].clt_idx; + if (clt_index >= 0) { /* the function has been registered */ + g_hif_sdio_probed_func_list[probe_index].sdio_irq_enabled = MTK_WCN_BOOL_FALSE; + /* 4 <4> claim irq for this function */ + func = g_hif_sdio_probed_func_list[probe_index].func; + if (unlikely(!(func) || !(func->card) || !(func->card->host) + || mmc_card_removed(func->card))) { + HIF_SDIO_ERR_FUNC("sdio host is missing\n"); + return HIF_SDIO_ERR_NOT_PROBED; + } + sdio_claim_host(func); + ret = sdio_claim_irq(func, hif_sdio_irq); + mtk_wcn_hif_sdio_irq_flag_set(1); + sdio_release_host(func); + if (ret) { + HIF_SDIO_WARN_FUNC("sdio_claim_irq() for wifi fail(%d)\n", ret); + return ret; + } + HIF_SDIO_INFO_FUNC("sdio_claim_irq() for wifi ok\n"); + + /* 4 <5> If this struct sdio_func *func is supported by any driver in */ + /* 4 g_hif_sdio_clt_drv_list, schedule another task to call client's .hif_clt_probe() */ + /* TODO: [FixMe][George] WHY probe worker is removed??? */ +#if 1 + /*set deep sleep information to global data struct */ + func_info = g_hif_sdio_clt_drv_list[clt_index].func_info; + hif_sdio_deep_sleep_info_set_act(chip_id, func_num, + CLTCTX(func_info->card_id, func_info->func_num, + func_info->blk_sz, probe_index), 1); + + /* Call client's .hif_clt_probe() */ + ret = hif_sdio_clt_probe_func(&g_hif_sdio_clt_drv_list[clt_index], probe_index); + if (ret) { + HIF_SDIO_WARN_FUNC("clt_probe_func() for wifi fail(%d) release irq\n", ret); + sdio_claim_host(func); + mtk_wcn_hif_sdio_irq_flag_set(0); + ret2 = sdio_release_irq(func); + sdio_release_host(func); + if (ret2) + HIF_SDIO_WARN_FUNC("sdio_release_irq() for wifi fail(%d)\n", ret2); + + hif_sdio_deep_sleep_info_set_act(chip_id, func_num, + CLTCTX(func_info->card_id, + func_info->func_num, + func_info->blk_sz, probe_index), + 0); + g_hif_sdio_probed_func_list[probe_index].on_by_wmt = MTK_WCN_BOOL_FALSE; + return ret; + } + g_hif_sdio_probed_func_list[probe_index].on_by_wmt = MTK_WCN_BOOL_TRUE; + + HIF_SDIO_DBG_FUNC("ok!\n"); + return 0; +#else + /* use worker thread to perform the client's .hif_clt_probe() */ + clt_probe_worker_info = vmalloc(sizeof(MTK_WCN_HIF_SDIO_CLT_PROBE_WORKERINFO)); + INIT_WORK(&clt_probe_worker_info->probe_work, hif_sdio_clt_probe_worker); + clt_probe_worker_info->registinfo_p = &g_hif_sdio_clt_drv_list[clt_index]; + clt_probe_worker_info->probe_idx = probe_index; + schedule_work(&clt_probe_worker_info->probe_work); +#endif + } else { + /* TODO: [FixMe][George] check if clt_index is cleared in client's unregister function */ + HIF_SDIO_WARN_FUNC("probed but not registered yet (%d)\n", ret); + g_hif_sdio_probed_func_list[probe_index].on_by_wmt = MTK_WCN_BOOL_TRUE; + return HIF_SDIO_ERR_CLT_NOT_REG; + } +} + +/*! + * \brief wifi off by wmt (remove client driver). + * + * + * \param none. + * + * \retval 0:success, -11:not probed, -12:already off, -13:not registered, other errors. + */ +static _osal_inline_ INT32 hif_sdio_wifi_off(VOID) +{ + INT32 clt_index = -1; + INT32 probe_index = -1; + INT32 ret = -1; + INT32 ret2 = -1; + struct sdio_func *func = NULL; + UINT32 chip_id = 0; + UINT16 func_num = 0; + const MTK_WCN_HIF_SDIO_FUNCINFO *func_info = NULL; + + HIF_SDIO_INFO_FUNC("start!\n"); + + /* 4 <1> If wifi client drv has not been probed, return error code */ + /* MT6620 */ + probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x020A, 1); + if (probe_index >= 0) + goto wifi_off_exist; + probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x020C, 2); + if (probe_index >= 0) + goto wifi_off_exist; + + /* MT6628 */ + probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x6628, 1); + if (probe_index >= 0) + goto wifi_off_exist; + /* MT6630 */ + probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x6630, 1); + if (probe_index >= 0) { + chip_id = 0x6630; + func_num = 1; + goto wifi_off_exist; + } + /* MT6632 */ + probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x6602, 1); + if (probe_index >= 0) { + chip_id = 0x6632; + func_num = 1; + goto wifi_off_exist; + } + + /* MT6618 */ + probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x018A, 1); + if (probe_index >= 0) + goto wifi_off_exist; + probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x018C, 2); + if (probe_index >= 0) + goto wifi_off_exist; + else { + /* 4 <2> If wifi client drv has not been probed, return error code */ + /* client func has not been probed */ + return HIF_SDIO_ERR_NOT_PROBED; + } + +wifi_off_exist: + /* 4 <3> If wifi client drv has been off by wmt, return error code */ + if (g_hif_sdio_probed_func_list[probe_index].on_by_wmt == MTK_WCN_BOOL_FALSE) { + HIF_SDIO_WARN_FUNC("already off...\n"); + return HIF_SDIO_ERR_ALRDY_OFF; + } + g_hif_sdio_probed_func_list[probe_index].on_by_wmt = MTK_WCN_BOOL_FALSE; + + +#if 0 /* TODO: [FixMe][George] moved below as done in wifi_on. */ + /* 4 <4> release irq for this function */ + func = g_hif_sdio_probed_func_list[probe_index].func; + sdio_claim_host(func); + ret = sdio_release_irq(func); + sdio_release_host(func); + if (ret) + pr_warn(DRV_NAME "sdio_release_irq for wifi fail(%d)\n", ret); + else + pr_warn(DRV_NAME "sdio_release_irq for wifi ok\n"); + +#endif + clt_index = g_hif_sdio_probed_func_list[probe_index].clt_idx; + if (clt_index >= 0) { /* the function has been registered */ + func = g_hif_sdio_probed_func_list[probe_index].func; + + /* 4 <4> Callback to client driver's remove() func */ + ret = + g_hif_sdio_clt_drv_list[clt_index]. + sdio_cltinfo->hif_clt_remove(CLTCTX + (func->device, func->num, func->cur_blksize, + probe_index)); + if (ret) + HIF_SDIO_WARN_FUNC("clt_remove for wifi fail(%d)\n", ret); + else + HIF_SDIO_INFO_FUNC("ok!\n"); + + if (unlikely(!(func) || !(func->card) || !(func->card->host) + || mmc_card_removed(func->card))) { + HIF_SDIO_ERR_FUNC("sdio host is missing\n"); + return HIF_SDIO_ERR_ALRDY_OFF; + } + /* 4 <5> release irq for this function */ + sdio_claim_host(func); + mtk_wcn_hif_sdio_irq_flag_set(0); + ret2 = sdio_release_irq(func); + sdio_release_host(func); + g_hif_sdio_probed_func_list[probe_index].sdio_irq_enabled = MTK_WCN_BOOL_FALSE; + if (ret2) + HIF_SDIO_WARN_FUNC("sdio_release_irq() for wifi fail(%d)\n", ret2); + else + HIF_SDIO_INFO_FUNC("sdio_release_irq() for wifi ok\n"); + + /*set deep sleep information to global data struct */ + func_info = g_hif_sdio_clt_drv_list[clt_index].func_info; + hif_sdio_deep_sleep_info_set_act(chip_id, func_num, + CLTCTX(func_info->card_id, func_info->func_num, + func_info->blk_sz, probe_index), 0); + + return ret + ret2; + } + /* TODO: [FixMe][George] check if clt_index is cleared in client's unregister function */ + HIF_SDIO_WARN_FUNC("probed but not registered yet (%d)\n", ret); + return HIF_SDIO_ERR_CLT_NOT_REG; +} + +/*! + * \brief set mmc power up/off + * + * detailed descriptions + * + * \param: 1. ctx client's context variable, 2.power state: 1:power up, other:power off + * + * \retval 0:success, -1:fail + */ +INT32 mtk_wcn_hif_sdio_bus_set_power(MTK_WCN_HIF_SDIO_CLTCTX ctx, UINT32 pwrState) +{ + INT32 probe_index = -1; + struct sdio_func *func = 0; + + HIF_SDIO_INFO_FUNC("turn Bus Power to: %d\n", pwrState); + + probe_index = CLTCTX_IDX(ctx); + if (unlikely(!CLTCTX_IDX_VALID(probe_index))) { /* invalid index in CLTCTX */ + HIF_SDIO_WARN_FUNC("invalid ctx(0x%x)\n", ctx); + return -1; + } + func = g_hif_sdio_probed_func_list[probe_index].func; + + if (!func) { + HIF_SDIO_WARN_FUNC("Cannot find sdio_func !!!\n"); + return -1; + } + + if (pwrState == 1) { + sdio_claim_host(func); + mmc_power_up_ext(func->card->host); + sdio_release_host(func); + HIF_SDIO_WARN_FUNC("SDIO BUS Power UP\n"); + } else { + sdio_claim_host(func); + mmc_power_off_ext(func->card->host); + sdio_release_host(func); + HIF_SDIO_WARN_FUNC("SDIO BUS Power OFF\n"); + } + + return 0; +} +EXPORT_SYMBOL(mtk_wcn_hif_sdio_bus_set_power); + +VOID mtk_wcn_hif_sdio_enable_irq(MTK_WCN_HIF_SDIO_CLTCTX ctx, MTK_WCN_BOOL enable) +{ + UINT8 probed_idx = CLTCTX_IDX(ctx); + + if (unlikely(!CLTCTX_UIDX_VALID(probed_idx))) { /* invalid index in CLTCTX */ + HIF_SDIO_WARN_FUNC("invalid idx in ctx(0x%x), sdio_irq no change\n", ctx); + return; + } + if (unlikely(!CLTCTX_UIDX_VALID(probed_idx))) { /* invalid index in CLTCTX */ + HIF_SDIO_WARN_FUNC("invalid ctx(0x%x)\n", ctx); + return; + } + /* store client driver's private data to dev driver */ + g_hif_sdio_probed_func_list[probed_idx].sdio_irq_enabled = enable; + smp_wmb(); + HIF_SDIO_DBG_FUNC("ctx(0x%x) sdio irq enable(%d)\n", + ctx, (enable == MTK_WCN_BOOL_FALSE) ? 0 : 1); + + +} +EXPORT_SYMBOL(mtk_wcn_hif_sdio_enable_irq); + +/*! + * \brief + * + * detailed descriptions + * + * \param ctx client's context variable + * + * \retval 0 register successfully + * \retval < 0 list error code here + */ +INT32 mtk_wcn_hif_sdio_f0_readb(MTK_WCN_HIF_SDIO_CLTCTX ctx, UINT32 offset, PUINT8 pvb) +{ +#if HIF_SDIO_UPDATE + INT32 ret; + struct sdio_func *func = NULL; +#else + INT32 ret = -HIF_SDIO_ERR_FAIL; + INT32 probe_index = -1; + struct sdio_func *func = 0; +#endif + + HIF_SDIO_DBG_FUNC("start!\n"); + HIF_SDIO_ASSERT(pvb); + +/*4 <1> check if ctx is valid, registered, and probed */ +#if HIF_SDIO_UPDATE + ret = -HIF_SDIO_ERR_FAIL; + func = hif_sdio_ctx_to_func(ctx); + if (!func) { + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } +#else + probe_index = CLTCTX_IDX(ctx); + if (unlikely(!CLTCTX_IDX_VALID(probe_index))) { /* invalid index in CLTCTX */ + HIF_SDIO_WARN_FUNC("invalid ctx(0x%x)\n", ctx); + return -1; + } + if (probe_index < 0 || probe_index >= CFG_CLIENT_COUNT) { /* the function has not been probed */ + HIF_SDIO_WARN_FUNC("can't find client in probed list!\n"); + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } else { + if (g_hif_sdio_probed_func_list[probe_index].clt_idx < 0) { /* the client has not been registered */ + HIF_SDIO_WARN_FUNC("can't find client in registered list!\n"); + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } + } + func = g_hif_sdio_probed_func_list[probe_index].func; +#endif + +/*4 <2>*/ + sdio_claim_host(func); + *pvb = sdio_f0_readb(func, offset, &ret); + sdio_release_host(func); + +/*4 <3> check result code and return proper error code*/ + +out: + HIF_SDIO_DBG_FUNC("end!\n"); + return ret; +} /* end of mtk_wcn_hif_sdio_f0_readb() */ + + +/*! + * \brief + * + * detailed descriptions + * + * \param ctx client's context variable + * + * \retval 0register successfully + * \retval < 0 list error code here + */ +INT32 mtk_wcn_hif_sdio_f0_writeb(MTK_WCN_HIF_SDIO_CLTCTX ctx, UINT32 offset, UINT8 vb) +{ +#if HIF_SDIO_UPDATE + INT32 ret; + struct sdio_func *func = NULL; +#else + INT32 ret = -HIF_SDIO_ERR_FAIL; + INT32 probe_index = -1; + struct sdio_func *func = 0; +#endif + + HIF_SDIO_DBG_FUNC("start!\n"); + +/*4 <1> check if ctx is valid, registered, and probed*/ +#if HIF_SDIO_UPDATE + ret = -HIF_SDIO_ERR_FAIL; + func = hif_sdio_ctx_to_func(ctx); + if (!func) { + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } +#else + probe_index = CLTCTX_IDX(ctx); + if (unlikely(!CLTCTX_IDX_VALID(probe_index))) { /* invalid index in CLTCTX */ + HIF_SDIO_WARN_FUNC("invalid ctx(0x%x)\n", ctx); + goto out; + } + if (probe_index < 0) { /* the function has not been probed */ + HIF_SDIO_WARN_FUNC("can't find client in probed list!\n"); + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } else { + if (g_hif_sdio_probed_func_list[probe_index].clt_idx < 0) { /* the client has not been registered */ + HIF_SDIO_WARN_FUNC("can't find client in registered list!\n"); + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } + } + func = g_hif_sdio_probed_func_list[probe_index].func; +#endif + +/*4 <1.1> check if input parameters are valid*/ + +/*4 <2>*/ + wmt_tra_sdio_update(); + sdio_claim_host(func); + sdio_f0_writeb(func, vb, offset, &ret); + sdio_release_host(func); + +/*4 <3> check result code and return proper error code*/ + +out: + HIF_SDIO_DBG_FUNC("end!\n"); + return ret; +} /* end of mtk_wcn_hif_sdio_f0_writeb() */ + + +INT32 mtk_wcn_hif_sdio_drv_init(VOID) +{ + return hif_sdio_init(); + +} +EXPORT_SYMBOL(mtk_wcn_hif_sdio_drv_init); + +VOID mtk_wcn_hif_sdio_driver_exit(VOID) +{ + return hif_sdio_exit(); +} +EXPORT_SYMBOL(mtk_wcn_hif_sdio_driver_exit); diff --git a/drivers/misc/mediatek/connectivity/common/common_main/linux/include/bgw_desense.h b/drivers/misc/mediatek/connectivity/common/common_main/linux/include/bgw_desense.h new file mode 100644 index 0000000000000000000000000000000000000000..4e9db7cbeb9338b33a812af5a850252e567506af --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/linux/include/bgw_desense.h @@ -0,0 +1,73 @@ +/* +* Copyright (C) 2011-2014 MediaTek Inc. +* +* This program is free software: you can redistribute it and/or modify it under the terms of the +* GNU General Public License version 2 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. +* +* You should have received a copy of the GNU General Public License along with this program. +* If not, see . +*/ + +#ifndef __BGW_DESENSE_H_ +#define __BGW_DESENSE_H_ + +#ifdef MSG +#undef MSG +#endif + +#ifdef ERR +#undef ERR +#endif + +#define PFX1 "[BWG] " +#define MSG(fmt, arg ...) pr_debug(PFX1 "[D]%s: " fmt, __func__, ##arg) +#define ERR(fmt, arg ...) pr_debug(PFX1 "[D]%s: " fmt, __func__, ##arg) + +#ifdef NETLINK_TEST +#undef NETLINK_TEST +#endif + +#define NETLINK_TEST 17 + +#ifdef MAX_NL_MSG_LEN +#undef MAX_NL_MSG_LEN +#endif + +#define MAX_NL_MSG_LEN 1024 + + +#ifdef ON +#undef ON +#endif +#ifdef OFF +#undef OFF +#endif +#ifdef ACK +#undef ACK +#endif + +#define ON 1 +#define OFF 0 +#define ACK 2 + +/* + * used send command to native process + * + * parameter: command could be macro ON: enable co-exist; OFF: disable co-exist; + * ACK: after get native process init message send ACK + */ +extern void send_command_to_daemon(const int command); + +/* + * before use kernel socket, please call init socket first + * return value: 0: ok; -1: fail + */ +extern int bgw_init_socket(void); + +extern void bgw_destroy_netlink_kernel(void); + +#endif diff --git a/drivers/misc/mediatek/connectivity/common/common_main/linux/include/fw_log_wmt.h b/drivers/misc/mediatek/connectivity/common/common_main/linux/include/fw_log_wmt.h new file mode 100644 index 0000000000000000000000000000000000000000..7871f467e64d11701eaf93aab57879537bfc1261 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/linux/include/fw_log_wmt.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +#ifndef _FW_LOG_WMT_H_ +#define _FW_LOG_WMT_H_ + +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH +int fw_log_wmt_init(void); +void fw_log_wmt_deinit(void); +#endif + +#endif /*_FW_LOG_WMT_H_*/ + diff --git a/drivers/misc/mediatek/connectivity/common/common_main/linux/include/hif_sdio.h b/drivers/misc/mediatek/connectivity/common/common_main/linux/include/hif_sdio.h new file mode 100644 index 0000000000000000000000000000000000000000..bafbc26fd8b218129ad16c2603a3572a84791b9e --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/linux/include/hif_sdio.h @@ -0,0 +1,371 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +/*! + * \file "hif_sdio.h" + * \brief + */ + +/* + * + * 07 25 2010 george.kuo + * + * Move hif_sdio driver to linux directory. + * + * 07 23 2010 george.kuo + * + * Add MT6620 driver source tree + * , including char device driver (wmt, bt, gps), stp driver, + * interface driver (tty ldisc and hif_sdio), and bt hci driver. +** +** +*/ + +#ifndef _HIF_SDIO_H +#define _HIF_SDIO_H +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ +#define HIF_SDIO_DEBUG (0) /* 0:turn off debug msg and assert, 1:turn off debug msg and assert */ +#define HIF_SDIO_API_EXTENSION (0) +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "osal_typedef.h" +#include "osal.h" +#include "wmt_exp.h" + + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ +#define CFG_CLIENT_COUNT (12) + +#define HIF_DEFAULT_BLK_SIZE (256) +#define HIF_DEFAULT_VENDOR (0x037A) + +#define HIF_SDIO_LOG_LOUD 4 +#define HIF_SDIO_LOG_DBG 3 +#define HIF_SDIO_LOG_INFO 2 +#define HIF_SDIO_LOG_WARN 1 +#define HIF_SDIO_LOG_ERR 0 + +#define CCCR_F8 (0X00F8) +#define SWPCDBGR (0x0154) + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/* Function info provided by client driver */ +typedef struct _MTK_WCN_HIF_SDIO_FUNCINFO MTK_WCN_HIF_SDIO_FUNCINFO; + +/* Client context provided by hif_sdio driver for the following function call */ +typedef UINT32 MTK_WCN_HIF_SDIO_CLTCTX; + +/* Callback functions provided by client driver */ +typedef INT32 (*MTK_WCN_HIF_SDIO_PROBE)(MTK_WCN_HIF_SDIO_CLTCTX, + const MTK_WCN_HIF_SDIO_FUNCINFO *); +typedef INT32 (*MTK_WCN_HIF_SDIO_REMOVE)(MTK_WCN_HIF_SDIO_CLTCTX); +typedef INT32 (*MTK_WCN_HIF_SDIO_IRQ)(MTK_WCN_HIF_SDIO_CLTCTX); + +/* Function info provided by client driver */ +struct _MTK_WCN_HIF_SDIO_FUNCINFO { + UINT16 manf_id; /* TPLMID_MANF: manufacturer ID */ + UINT16 card_id; /* TPLMID_CARD: card ID */ + UINT16 func_num; /* Function Number */ + UINT16 blk_sz; /* Function block size */ +}; + +/* Client info provided by client driver */ +typedef struct _MTK_WCN_HIF_SDIO_CLTINFO { + const MTK_WCN_HIF_SDIO_FUNCINFO *func_tbl; /* supported function info table */ + UINT32 func_tbl_size; /* supported function table info element number */ + MTK_WCN_HIF_SDIO_PROBE hif_clt_probe; /* callback function for probing */ + MTK_WCN_HIF_SDIO_REMOVE hif_clt_remove; /* callback function for removing */ + MTK_WCN_HIF_SDIO_IRQ hif_clt_irq; /* callback function for interrupt handling */ +} MTK_WCN_HIF_SDIO_CLTINFO; + +/* function info provided by registed function */ +typedef struct _MTK_WCN_HIF_SDIO_REGISTINFO { + const MTK_WCN_HIF_SDIO_CLTINFO *sdio_cltinfo; /* client's MTK_WCN_HIF_SDIO_CLTINFO pointer */ + const MTK_WCN_HIF_SDIO_FUNCINFO *func_info; /* supported function info pointer */ +} MTK_WCN_HIF_SDIO_REGISTINFO; + +/* Card info provided by probed function */ +typedef struct _MTK_WCN_HIF_SDIO_PROBEINFO { + struct sdio_func *func; /* probed sdio function pointer */ + PVOID private_data_p; /* clt's private data pointer */ + MTK_WCN_BOOL on_by_wmt; /* TRUE: on by wmt, FALSE: not on by wmt */ + /* added for sdio irq sync and mmc single_irq workaround */ + MTK_WCN_BOOL sdio_irq_enabled; /* TRUE: can handle sdio irq; FALSE: no sdio irq handling */ + INT32 clt_idx; /* registered function table info element number (initial value is -1) */ +} MTK_WCN_HIF_SDIO_PROBEINFO; + +/* work queue info needed by worker */ +typedef struct _MTK_WCN_HIF_SDIO_CLT_PROBE_WORKERINFO { + struct work_struct probe_work; /* work queue structure */ + MTK_WCN_HIF_SDIO_REGISTINFO *registinfo_p; /* MTK_WCN_HIF_SDIO_REGISTINFO pointer of the client */ + INT8 probe_idx; /* probed function table info element number (initial value is -1) */ +} MTK_WCN_HIF_SDIO_CLT_PROBE_WORKERINFO; + +/* global resource locks info of hif_sdio drv */ +typedef struct _MTK_WCN_HIF_SDIO_LOCKINFO { + spinlock_t probed_list_lock; /* spin lock for probed list */ + spinlock_t clt_list_lock; /* spin lock for client registed list */ +} MTK_WCN_HIF_SDIO_LOCKINFO; + +/* SDIO Deep Sleep Information by chip, maintained by HIF-SDIO itself */ +typedef struct _MTK_WCN_HIF_SDIO_DS_CLT_INFO { + MTK_WCN_HIF_SDIO_CLTCTX ctx; + UINT16 func_num; + UINT8 act_flag; + UINT8 ds_en_flag; +} MTK_WCN_HIF_SDIO_DS_CLT_INFO; + +typedef struct _MTK_WCN_HIF_SDIO_DS_INFO { + UINT32 chip_id; /*chipid */ + UINT32 reg_offset; /*offset in CCCR of control register of deep sleep */ + UINT8 value; /*value to set to CCCR reg_offset, when enable deep sleep */ + MTK_WCN_HIF_SDIO_DS_CLT_INFO clt_info[2]; /*currently, only BGF and WIFI function need this function */ + struct mutex lock; +} MTK_WCN_HIF_SDIO_DS_INFO; + + +/* error code returned by hif_sdio driver (use NEGATIVE number) */ +typedef enum { + HIF_SDIO_ERR_SUCCESS = 0, + HIF_SDIO_ERR_FAIL = HIF_SDIO_ERR_SUCCESS - 1, /* generic error */ + HIF_SDIO_ERR_INVALID_PARAM = HIF_SDIO_ERR_FAIL - 1, + HIF_SDIO_ERR_DUPLICATED = HIF_SDIO_ERR_INVALID_PARAM - 1, + HIF_SDIO_ERR_UNSUP_MANF_ID = HIF_SDIO_ERR_DUPLICATED - 1, + HIF_SDIO_ERR_UNSUP_CARD_ID = HIF_SDIO_ERR_UNSUP_MANF_ID - 1, + HIF_SDIO_ERR_INVALID_FUNC_NUM = HIF_SDIO_ERR_UNSUP_CARD_ID - 1, + HIF_SDIO_ERR_INVALID_BLK_SZ = HIF_SDIO_ERR_INVALID_FUNC_NUM - 1, + HIF_SDIO_ERR_NOT_PROBED = HIF_SDIO_ERR_INVALID_BLK_SZ - 1, + HIF_SDIO_ERR_ALRDY_ON = HIF_SDIO_ERR_NOT_PROBED - 1, + HIF_SDIO_ERR_ALRDY_OFF = HIF_SDIO_ERR_ALRDY_ON - 1, + HIF_SDIO_ERR_CLT_NOT_REG = HIF_SDIO_ERR_ALRDY_OFF - 1, +} MTK_WCN_HIF_SDIO_ERR; + + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/*! + * \brief A macro used to generate hif_sdio client's context + * + * Generate a context for hif_sdio client based on the following input parameters + * |<-card id (16bits)->|<-block size in unit of 256 bytes(8 bits)->|<-function number(4bits)->|<-index(4bits)->| + * + * \param manf the 16 bit manufacturer id + * \param card the 16 bit card id + * \param func the 16 bit function number + * \param b_sz the 16 bit function block size + */ +#define CLTCTX(cid, func, blk_sz, idx) \ +(MTK_WCN_HIF_SDIO_CLTCTX)((((UINT32)(cid) & 0xFFFFUL) << 16) | \ + (((UINT32)(func) & 0xFUL) << 4) | \ + (((UINT32)(blk_sz) & 0xFF00UL) << 0) | \ + (((UINT32)idx & 0xFUL) << 0)) + +/*! + * \brief A set of macros used to get information out of an hif_sdio client context + * + * Generate a context for hif_sdio client based on the following input parameters + */ +#define CLTCTX_CID(ctx) (((ctx) >> 16) & 0xFFFF) +#define CLTCTX_FUNC(ctx) (((ctx) >> 4) & 0xF) +#define CLTCTX_BLK_SZ(ctx) (((ctx) >> 0) & 0xFF00) +#define CLTCTX_IDX(ctx) ((ctx) & 0xF) +#define CLTCTX_IDX_VALID(idx) ((idx >= 0) && (idx < CFG_CLIENT_COUNT)) +#define CLTCTX_UIDX_VALID(idx) (idx < CFG_CLIENT_COUNT) + + +/*! + * \brief A macro used to describe an SDIO function + * + * Fill an MTK_WCN_HIF_SDIO_FUNCINFO structure with function-specific information + * + * \param manf the 16 bit manufacturer id + * \param card the 16 bit card id + * \param func the 16 bit function number + * \param b_sz the 16 bit function block size + */ +#define MTK_WCN_HIF_SDIO_FUNC(manf, card, func, b_sz) \ + .manf_id = (manf), .card_id = (card), .func_num = (func), .blk_sz = (b_sz) + +#ifdef DFT_TAG +#undef DFT_TAG +#endif + +#ifndef DFT_TAG +#define DFT_TAG "[HIF-SDIO]" +#endif + +extern INT32 gHifSdioDbgLvl; + + +#define HIF_SDIO_LOUD_FUNC(fmt, arg...) \ +do { if (gHifSdioDbgLvl >= HIF_SDIO_LOG_LOUD) \ + osal_warn_print(DFT_TAG"[L]%s:" fmt, __func__, ##arg); \ +} while (0) +#define HIF_SDIO_DBG_FUNC(fmt, arg...) \ +do { if (gHifSdioDbgLvl >= HIF_SDIO_LOG_DBG) \ + osal_warn_print(DFT_TAG"[D]%s:" fmt, __func__, ##arg); \ +} while (0) +#define HIF_SDIO_INFO_FUNC(fmt, arg...) \ +do { if (gHifSdioDbgLvl >= HIF_SDIO_LOG_INFO) \ + osal_warn_print(DFT_TAG"[I]%s:" fmt, __func__, ##arg); \ +} while (0) +#define HIF_SDIO_WARN_FUNC(fmt, arg...) \ +do { if (gHifSdioDbgLvl >= HIF_SDIO_LOG_WARN) \ + osal_warn_print(DFT_TAG"[W]%s(%d):" fmt, __func__, __LINE__, ##arg); \ +} while (0) +#define HIF_SDIO_ERR_FUNC(fmt, arg...) \ +do { if (gHifSdioDbgLvl >= HIF_SDIO_LOG_ERR) \ + osal_err_print(DFT_TAG"[E]%s(%d):" fmt, __func__, __LINE__, ##arg); \ +} while (0) + +/*! + * \brief ASSERT function definition. + * + */ +#if HIF_SDIO_DEBUG +#define HIF_SDIO_ASSERT(expr) \ +{ \ + if (!(expr)) { \ + osal_warn_print("assertion failed! %s[%d]: %s\n",\ + __func__, __LINE__, #expr); \ + osal_bug_on(!(expr));\ + } \ +} +#else +#define HIF_SDIO_ASSERT(expr) do {} while (0) +#endif + +/* define function 0 CR */ +#define CCCR_06 (0x06) +#define CCCR_F0 (0xF0) + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/*! + * \brief MTK hif sdio client registration function + * + * Client uses this function to do hif sdio registration + * + * \param pinfo a pointer of client's information + * + * \retval 0 register successfully + * \retval < 0 error code + */ +extern INT32 mtk_wcn_hif_sdio_client_reg(const MTK_WCN_HIF_SDIO_CLTINFO *pinfo); + +extern INT32 mtk_wcn_hif_sdio_client_unreg(const MTK_WCN_HIF_SDIO_CLTINFO *pinfo); + +extern INT32 mtk_wcn_hif_sdio_readb(MTK_WCN_HIF_SDIO_CLTCTX ctx, UINT32 offset, PUINT8 pvb); + +extern INT32 mtk_wcn_hif_sdio_writeb(MTK_WCN_HIF_SDIO_CLTCTX ctx, UINT32 offset, UINT8 vb); + +extern INT32 mtk_wcn_hif_sdio_readl(MTK_WCN_HIF_SDIO_CLTCTX ctx, UINT32 offset, PUINT32 pvl); + +extern INT32 mtk_wcn_hif_sdio_writel(MTK_WCN_HIF_SDIO_CLTCTX ctx, UINT32 offset, UINT32 vl); + +extern INT32 mtk_wcn_hif_sdio_read_buf(MTK_WCN_HIF_SDIO_CLTCTX ctx, + UINT32 offset, PUINT32 pbuf, UINT32 len); + +extern INT32 mtk_wcn_hif_sdio_write_buf(MTK_WCN_HIF_SDIO_CLTCTX ctx, + UINT32 offset, PUINT32 pbuf, UINT32 len); + +extern INT32 mtk_wcn_hif_sdio_abort(MTK_WCN_HIF_SDIO_CLTCTX ctx); + +INT32 hif_sdio_wake_up_ctrl(MTK_WCN_HIF_SDIO_CLTCTX ctx); + +extern VOID mtk_wcn_hif_sdio_set_drvdata(MTK_WCN_HIF_SDIO_CLTCTX ctx, PVOID private_data_p); + +extern PVOID mtk_wcn_hif_sdio_get_drvdata(MTK_WCN_HIF_SDIO_CLTCTX ctx); + +extern INT32 mtk_wcn_hif_sdio_wmt_control(WMT_SDIO_FUNC_TYPE func_type, MTK_WCN_BOOL is_on); + +extern INT32 mtk_wcn_hif_sdio_bus_set_power(MTK_WCN_HIF_SDIO_CLTCTX ctx, UINT32 pwrState); + +extern VOID mtk_wcn_hif_sdio_get_dev(MTK_WCN_HIF_SDIO_CLTCTX ctx, struct device **dev); + +extern INT32 mtk_wcn_hif_sdio_update_cb_reg(INT32(*ts_update)(VOID)); + +extern VOID mtk_wcn_hif_sdio_enable_irq(MTK_WCN_HIF_SDIO_CLTCTX ctx, MTK_WCN_BOOL enable); + +extern INT32 mtk_wcn_hif_sdio_f0_writeb(MTK_WCN_HIF_SDIO_CLTCTX ctx, UINT32 offset, UINT8 vb); + +extern INT32 mtk_wcn_hif_sdio_f0_readb(MTK_WCN_HIF_SDIO_CLTCTX ctx, UINT32 offset, PUINT8 pvb); +#ifdef CONFIG_MTK_COMBO_CHIP_DEEP_SLEEP_SUPPORT +INT32 mtk_wcn_hif_sdio_deep_sleep_flag_set(MTK_WCN_BOOL flag); +#endif + +#define DELETE_HIF_SDIO_CHRDEV 1 +#if !(DELETE_HIF_SDIO_CHRDEV) +INT32 mtk_wcn_hif_sdio_tell_chipid(INT32 chipId); +INT32 mtk_wcn_hif_sdio_query_chipid(INT32 waitFlag); +#endif + + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +#endif /* _HIF_SDIO_H */ diff --git a/drivers/misc/mediatek/connectivity/common/common_main/linux/include/osal.h b/drivers/misc/mediatek/connectivity/common/common_main/linux/include/osal.h new file mode 100644 index 0000000000000000000000000000000000000000..c006d2f5cbaec5044076eecb05fbedd6eadce98e --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/linux/include/osal.h @@ -0,0 +1,443 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + + +/*! \file + * \brief Declaration of library functions + * Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. + */ + +#ifndef _OSAL_H_ +#define _OSAL_H_ + +#include "osal_typedef.h" +#include "../../debug_utility/ring.h" +#include +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +#define OS_BIT_OPS_SUPPORT 1 + +#define _osal_inline_ inline + +#define MAX_THREAD_NAME_LEN 16 +#define MAX_WAKE_LOCK_NAME_LEN 16 +#define MAX_HISTORY_NAME_LEN 16 +#define OSAL_OP_BUF_SIZE 64 + + +#if (defined(CONFIG_MTK_GMO_RAM_OPTIMIZE) && !defined(CONFIG_MTK_ENG_BUILD)) +#define OSAL_OP_DATA_SIZE 8 +#else +#define OSAL_OP_DATA_SIZE 32 +#endif + +#define DBG_LOG_STR_SIZE 256 + +#define osal_sizeof(x) sizeof(x) + +#define osal_array_size(x) ARRAY_SIZE(x) + +#ifndef NAME_MAX +#define NAME_MAX 256 +#endif + +#define WMT_OP_BIT(x) (0x1UL << x) +#define WMT_OP_HIF_BIT WMT_OP_BIT(0) + +#define GET_BIT_MASK(value, mask) ((value) & (mask)) +#define SET_BIT_MASK(pdest, value, mask) (*(pdest) = (GET_BIT_MASK(*(pdest), ~(mask)) | GET_BIT_MASK(value, mask))) +#define GET_BIT_RANGE(data, end, begin) ((data) & GENMASK(end, begin)) +#define SET_BIT_RANGE(pdest, data, end, begin) (SET_BIT_MASK(pdest, data, GENMASK(end, begin))) + +#define RB_LATEST(prb) ((prb)->write - 1) +#define RB_SIZE(prb) ((prb)->size) +#define RB_MASK(prb) (RB_SIZE(prb) - 1) +#define RB_COUNT(prb) ((prb)->write - (prb)->read) +#define RB_FULL(prb) (RB_COUNT(prb) >= RB_SIZE(prb)) +#define RB_EMPTY(prb) ((prb)->write == (prb)->read) + +#define RB_INIT(prb, qsize) \ +do { \ + (prb)->read = (prb)->write = 0; \ + (prb)->size = (qsize); \ +} while (0) + +#define RB_PUT(prb, value) \ +do { \ + if (!RB_FULL(prb)) { \ + (prb)->queue[(prb)->write & RB_MASK(prb)] = value; \ + ++((prb)->write); \ + } \ + else { \ + osal_assert(!RB_FULL(prb)); \ + } \ +} while (0) + +#define RB_GET(prb, value) \ +do { \ + if (!RB_EMPTY(prb)) { \ + value = (prb)->queue[(prb)->read & RB_MASK(prb)]; \ + ++((prb)->read); \ + if (RB_EMPTY(prb)) { \ + (prb)->read = (prb)->write = 0; \ + } \ + } \ + else { \ + value = NULL; \ + osal_assert(!RB_EMPTY(prb)); \ + } \ +} while (0) + +#define RB_GET_LATEST(prb, value) \ +do { \ + if (!RB_EMPTY(prb)) { \ + value = (prb)->queue[RB_LATEST(prb) & RB_MASK(prb)]; \ + if (RB_EMPTY(prb)) { \ + (prb)->read = (prb)->write = 0; \ + } \ + } \ + else { \ + value = NULL; \ + } \ +} while (0) + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) +typedef VOID(*P_TIMEOUT_HANDLER) (struct timer_list *t); +typedef struct timer_list *timer_handler_arg; +#define GET_HANDLER_DATA(arg, data) \ +do { \ + P_OSAL_TIMER osal_timer = from_timer(osal_timer, arg, timer); \ + data = osal_timer->timeroutHandlerData; \ +} while (0) +#else +typedef VOID(*P_TIMEOUT_HANDLER) (ULONG); +typedef ULONG timer_handler_arg; +#define GET_HANDLER_DATA(arg, data) (data = arg) +#endif + +typedef INT32(*P_COND) (PVOID); + +typedef struct _OSAL_TIMER_ { + struct timer_list timer; + P_TIMEOUT_HANDLER timeoutHandler; + ULONG timeroutHandlerData; +} OSAL_TIMER, *P_OSAL_TIMER; + +typedef struct _OSAL_UNSLEEPABLE_LOCK_ { + spinlock_t lock; + ULONG flag; +} OSAL_UNSLEEPABLE_LOCK, *P_OSAL_UNSLEEPABLE_LOCK; + +typedef struct _OSAL_SLEEPABLE_LOCK_ { + struct mutex lock; +} OSAL_SLEEPABLE_LOCK, *P_OSAL_SLEEPABLE_LOCK; + +typedef struct _OSAL_SIGNAL_ { + struct completion comp; + UINT32 timeoutValue; + UINT32 timeoutExtension; /* max number of timeout caused by thread not able to acquire CPU */ +} OSAL_SIGNAL, *P_OSAL_SIGNAL; + +typedef struct _OSAL_EVENT_ { + wait_queue_head_t waitQueue; +/* VOID *pWaitQueueData; */ + UINT32 timeoutValue; + INT32 waitFlag; + +} OSAL_EVENT, *P_OSAL_EVENT; + +/* Data collected from sched_entity and sched_statistics */ +typedef struct _OSAL_THREAD_SCHEDSTATS_ { + UINT64 time; /* when marked: the profiling start time(ms), when unmarked: total duration(ms) */ + UINT64 exec; /* time spent in exec (sum_exec_runtime) */ + UINT64 runnable; /* time spent in run-queue while not being scheduled (wait_sum) */ + UINT64 iowait; /* time spent waiting for I/O (iowait_sum) */ +} OSAL_THREAD_SCHEDSTATS, *P_OSAL_THREAD_SCHEDSTATS; + +typedef struct _OSAL_THREAD_ { + struct task_struct *pThread; + PVOID pThreadFunc; + PVOID pThreadData; + INT8 threadName[MAX_THREAD_NAME_LEN]; +} OSAL_THREAD, *P_OSAL_THREAD; + + +typedef struct _OSAL_FIFO_ { + /*fifo definition */ + PVOID pFifoBody; + spinlock_t fifoSpinlock; + /*fifo operations */ + INT32 (*FifoInit)(struct _OSAL_FIFO_ *pFifo, PUINT8 buf, UINT32); + INT32 (*FifoDeInit)(struct _OSAL_FIFO_ *pFifo); + INT32 (*FifoReset)(struct _OSAL_FIFO_ *pFifo); + INT32 (*FifoSz)(struct _OSAL_FIFO_ *pFifo); + INT32 (*FifoAvailSz)(struct _OSAL_FIFO_ *pFifo); + INT32 (*FifoLen)(struct _OSAL_FIFO_ *pFifo); + INT32 (*FifoIsEmpty)(struct _OSAL_FIFO_ *pFifo); + INT32 (*FifoIsFull)(struct _OSAL_FIFO_ *pFifo); + INT32 (*FifoDataIn)(struct _OSAL_FIFO_ *pFifo, const PVOID buf, UINT32 len); + INT32 (*FifoDataOut)(struct _OSAL_FIFO_ *pFifo, PVOID buf, UINT32 len); +} OSAL_FIFO, *P_OSAL_FIFO; + +typedef struct firmware osal_firmware; + +typedef struct _OSAL_OP_DAT { + UINT32 opId; /* Event ID */ + UINT32 u4InfoBit; /* Reserved */ + SIZE_T au4OpData[OSAL_OP_DATA_SIZE]; /* OP Data */ +} OSAL_OP_DAT, *P_OSAL_OP_DAT; + +typedef struct _OSAL_LXOP_ { + OSAL_OP_DAT op; + OSAL_SIGNAL signal; + INT32 result; + atomic_t ref_count; +} OSAL_OP, *P_OSAL_OP; + +typedef struct _OSAL_LXOP_Q { + OSAL_SLEEPABLE_LOCK sLock; + UINT32 write; + UINT32 read; + UINT32 size; + P_OSAL_OP queue[OSAL_OP_BUF_SIZE]; +} OSAL_OP_Q, *P_OSAL_OP_Q; + +typedef struct _OSAL_WAKE_LOCK_ { + struct wakeup_source *wake_lock; + UINT8 name[MAX_WAKE_LOCK_NAME_LEN]; + INT32 init_flag; +} OSAL_WAKE_LOCK, *P_OSAL_WAKE_LOCK; +#if 1 +typedef struct _OSAL_BIT_OP_VAR_ { + ULONG data; + OSAL_UNSLEEPABLE_LOCK opLock; +} OSAL_BIT_OP_VAR, *P_OSAL_BIT_OP_VAR; +#else +#define OSAL_BIT_OP_VAR unsigned long +#define P_OSAL_BIT_OP_VAR unsigned long * + +#endif +typedef UINT32(*P_OSAL_EVENT_CHECKER) (P_OSAL_THREAD pThread); + +struct osal_op_history_entry { + VOID *opbuf_address; + UINT32 op_id; + UINT32 opbuf_ref_count; + UINT32 op_info_bit; + SIZE_T param_0; + SIZE_T param_1; + SIZE_T param_2; + SIZE_T param_3; + UINT64 ts; + ULONG usec; +}; + +struct osal_op_history { + struct ring ring_buffer; + struct osal_op_history_entry *queue; + spinlock_t lock; + struct ring dump_ring_buffer; + struct work_struct dump_work; + UINT8 name[MAX_HISTORY_NAME_LEN]; +}; + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +UINT32 osal_strlen(const PINT8 str); +INT32 osal_strcmp(const PINT8 dst, const PINT8 src); +INT32 osal_strncmp(const PINT8 dst, const PINT8 src, UINT32 len); +PINT8 osal_strcpy(PINT8 dst, const PINT8 src); +PINT8 osal_strncpy(PINT8 dst, const PINT8 src, UINT32 len); +PINT8 osal_strcat(PINT8 dst, const PINT8 src); +PINT8 osal_strncat(PINT8 dst, const PINT8 src, UINT32 len); +PINT8 osal_strchr(const PINT8 str, UINT8 c); +PINT8 osal_strsep(PPINT8 str, const PINT8 c); +INT32 osal_strtol(const PINT8 str, UINT32 adecimal, PLONG res); +PINT8 osal_strstr(PINT8 str1, const PINT8 str2); +PINT8 osal_strnstr(PINT8 str1, const PINT8 str2, INT32 n); + +VOID osal_bug_on(UINT32 val); + +INT32 osal_snprintf(PINT8 buf, UINT32 len, const PINT8 fmt, ...); +INT32 osal_err_print(const PINT8 str, ...); +INT32 osal_dbg_print(const PINT8 str, ...); +INT32 osal_warn_print(const PINT8 str, ...); + +INT32 osal_dbg_assert(INT32 expr, const PINT8 file, INT32 line); +INT32 osal_dbg_assert_aee(const PINT8 module, const PINT8 detail_description, ...); +INT32 osal_sprintf(PINT8 str, const PINT8 format, ...); +PVOID osal_malloc(UINT32 size); +VOID osal_free(const PVOID dst); +PVOID osal_memset(PVOID buf, INT32 i, UINT32 len); +PVOID osal_memcpy(PVOID dst, const PVOID src, UINT32 len); +VOID osal_memcpy_fromio(PVOID dst, const PVOID src, UINT32 len); +VOID osal_memcpy_toio(PVOID dst, const PVOID src, UINT32 len); +INT32 osal_memcmp(const PVOID buf1, const PVOID buf2, UINT32 len); + +UINT16 osal_crc16(const PUINT8 buffer, const UINT32 length); +VOID osal_thread_show_stack(P_OSAL_THREAD pThread); + +INT32 osal_sleep_ms(UINT32 ms); +INT32 osal_udelay(UINT32 us); +INT32 osal_usleep_range(ULONG min, ULONG max); +INT32 osal_timer_create(P_OSAL_TIMER); +INT32 osal_timer_start(P_OSAL_TIMER, UINT32); +INT32 osal_timer_stop(P_OSAL_TIMER); +INT32 osal_timer_stop_sync(P_OSAL_TIMER pTimer); +INT32 osal_timer_modify(P_OSAL_TIMER, UINT32); +INT32 osal_timer_delete(P_OSAL_TIMER); + +INT32 osal_fifo_init(P_OSAL_FIFO pFifo, PUINT8 buffer, UINT32 size); +VOID osal_fifo_deinit(P_OSAL_FIFO pFifo); +INT32 osal_fifo_reset(P_OSAL_FIFO pFifo); +UINT32 osal_fifo_in(P_OSAL_FIFO pFifo, PUINT8 buffer, UINT32 size); +UINT32 osal_fifo_out(P_OSAL_FIFO pFifo, PUINT8 buffer, UINT32 size); +UINT32 osal_fifo_len(P_OSAL_FIFO pFifo); +UINT32 osal_fifo_sz(P_OSAL_FIFO pFifo); +UINT32 osal_fifo_avail(P_OSAL_FIFO pFifo); +UINT32 osal_fifo_is_empty(P_OSAL_FIFO pFifo); +UINT32 osal_fifo_is_full(P_OSAL_FIFO pFifo); + +INT32 osal_wake_lock_init(P_OSAL_WAKE_LOCK plock); +INT32 osal_wake_lock(P_OSAL_WAKE_LOCK plock); +INT32 osal_wake_unlock(P_OSAL_WAKE_LOCK plock); +INT32 osal_wake_lock_count(P_OSAL_WAKE_LOCK plock); +INT32 osal_wake_lock_deinit(P_OSAL_WAKE_LOCK plock); + +#if defined(CONFIG_PROVE_LOCKING) +#define osal_unsleepable_lock_init(l) { spin_lock_init(&((l)->lock)); } +#else +INT32 osal_unsleepable_lock_init(P_OSAL_UNSLEEPABLE_LOCK); +#endif +INT32 osal_lock_unsleepable_lock(P_OSAL_UNSLEEPABLE_LOCK); +INT32 osal_unlock_unsleepable_lock(P_OSAL_UNSLEEPABLE_LOCK); +INT32 osal_trylock_unsleepable_lock(P_OSAL_UNSLEEPABLE_LOCK); +INT32 osal_unsleepable_lock_deinit(P_OSAL_UNSLEEPABLE_LOCK); + +#if defined(CONFIG_PROVE_LOCKING) +#define osal_sleepable_lock_init(l) { mutex_init(&((l)->lock)); } +#else +INT32 osal_sleepable_lock_init(P_OSAL_SLEEPABLE_LOCK); +#endif +INT32 osal_lock_sleepable_lock(P_OSAL_SLEEPABLE_LOCK); +INT32 osal_unlock_sleepable_lock(P_OSAL_SLEEPABLE_LOCK); +INT32 osal_trylock_sleepable_lock(P_OSAL_SLEEPABLE_LOCK); +INT32 osal_sleepable_lock_deinit(P_OSAL_SLEEPABLE_LOCK); + +INT32 osal_signal_init(P_OSAL_SIGNAL); +INT32 osal_wait_for_signal(P_OSAL_SIGNAL); +INT32 osal_wait_for_signal_timeout(P_OSAL_SIGNAL, P_OSAL_THREAD); +INT32 osal_raise_signal(P_OSAL_SIGNAL); +INT32 osal_signal_active_state(P_OSAL_SIGNAL pSignal); +INT32 osal_signal_deinit(P_OSAL_SIGNAL); + +INT32 osal_event_init(P_OSAL_EVENT); +INT32 osal_wait_for_event(P_OSAL_EVENT, P_COND, PVOID); +INT32 osal_wait_for_event_timeout(P_OSAL_EVENT, P_COND, PVOID); +extern INT32 osal_trigger_event(P_OSAL_EVENT); + +INT32 osal_event_deinit(P_OSAL_EVENT); +LONG osal_wait_for_event_bit_set(P_OSAL_EVENT pEvent, PULONG pState, UINT32 bitOffset); +LONG osal_wait_for_event_bit_clr(P_OSAL_EVENT pEvent, PULONG pState, UINT32 bitOffset); + +INT32 osal_thread_create(P_OSAL_THREAD); +INT32 osal_thread_run(P_OSAL_THREAD); +INT32 osal_thread_should_stop(P_OSAL_THREAD); +INT32 osal_thread_stop(P_OSAL_THREAD); +/*INT32 osal_thread_wait_for_event(P_OSAL_THREAD, P_OSAL_EVENT);*/ +INT32 osal_thread_wait_for_event(P_OSAL_THREAD, P_OSAL_EVENT, P_OSAL_EVENT_CHECKER); +/*check pOsalLxOp and OSAL_THREAD_SHOULD_STOP*/ +INT32 osal_thread_destroy(P_OSAL_THREAD); +INT32 osal_thread_sched_mark(P_OSAL_THREAD, P_OSAL_THREAD_SCHEDSTATS schedstats); +INT32 osal_thread_sched_unmark(P_OSAL_THREAD pThread, P_OSAL_THREAD_SCHEDSTATS schedstats); + +INT32 osal_clear_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData); +INT32 osal_set_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData); +INT32 osal_test_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData); +INT32 osal_test_and_clear_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData); +INT32 osal_test_and_set_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData); + +INT32 osal_gettimeofday(PINT32 sec, PINT32 usec); +void osal_do_gettimeofday(struct timeval *tv); +INT32 osal_printtimeofday(const PUINT8 prefix); +VOID osal_get_local_time(PUINT64 sec, PULONG nsec); +UINT64 osal_elapsed_us(UINT64 ts, ULONG usec); + +VOID osal_buffer_dump(const PUINT8 buf, const PUINT8 title, UINT32 len, UINT32 limit); +VOID osal_buffer_dump_data(const PUINT32 buf, const PUINT8 title, const UINT32 len, const UINT32 limit, + const INT32 flag); + +UINT32 osal_op_get_id(P_OSAL_OP pOp); +MTK_WCN_BOOL osal_op_is_wait_for_signal(P_OSAL_OP pOp); +VOID osal_op_raise_signal(P_OSAL_OP pOp, INT32 result); +VOID osal_set_op_result(P_OSAL_OP pOp, INT32 result); +VOID osal_opq_dump(const char *qName, P_OSAL_OP_Q pOpQ); +VOID osal_opq_dump_locked(const char *qName, P_OSAL_OP_Q pOpQ); +MTK_WCN_BOOL osal_opq_has_op(P_OSAL_OP_Q pOpQ, P_OSAL_OP pOp); + +INT32 osal_ftrace_print(const PINT8 str, ...); +INT32 osal_ftrace_print_ctrl(INT32 flag); + +VOID osal_dump_thread_state(const PUINT8 name); +VOID osal_op_history_init(struct osal_op_history *log_history, INT32 queue_size); +VOID osal_op_history_save(struct osal_op_history *log_history, P_OSAL_OP pOp); +VOID osal_op_history_print(struct osal_op_history *log_history, PINT8 name); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#define osal_assert(condition) \ +do { \ + if (!(condition)) \ + osal_err_print("%s, %d, (%s)\n", __FILE__, __LINE__, #condition); \ +} while (0) + +#endif /* _OSAL_H_ */ diff --git a/drivers/misc/mediatek/connectivity/common/common_main/linux/include/osal_typedef.h b/drivers/misc/mediatek/connectivity/common/common_main/linux/include/osal_typedef.h new file mode 100644 index 0000000000000000000000000000000000000000..ca48a7b7bac512d99dffea3cd7d56cca9dbecdac --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/linux/include/osal_typedef.h @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +/*! \file + * \brief Declaration of library functions + * Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. + */ + +#ifndef _OSAL_TYPEDEF_H_ +#define _OSAL_TYPEDEF_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if defined(WMT_PLAT_ALPS) && WMT_PLAT_ALPS +#if IS_ENABLED(CONFIG_MTK_AEE_AED) +#include +#endif +#endif +#include +#include +#include +#include +#include +#include + +#ifndef _TYPEDEFS_H /*fix redifine */ +typedef signed char INT8; +#endif + +typedef void VOID, *PVOID, **PPVOID; +typedef char *PINT8, **PPINT8; +typedef short INT16, *PINT16, **PPINT16; +typedef int INT32, *PINT32, **PPINT32; +typedef long LONG, *PLONG, **PPLONG; +typedef long long INT64, *PINT64, **PPINT64; + +typedef unsigned char UINT8, *PUINT8, **PPUINT8; +typedef unsigned short UINT16, *PUINT16, **PPUINT16; +typedef unsigned int UINT32, *PUINT32, **PPUINT32; +typedef unsigned long ULONG, *PULONG, **PPULONG; +typedef unsigned long long UINT64, *PUINT64, **PPUINT64; + +typedef size_t SIZE_T; + +typedef int MTK_WCN_BOOL; +#ifndef MTK_WCN_BOOL_TRUE +#define MTK_WCN_BOOL_FALSE ((MTK_WCN_BOOL) 0) +#define MTK_WCN_BOOL_TRUE ((MTK_WCN_BOOL) 1) +#endif + +#endif /*_OSAL_TYPEDEF_H_*/ diff --git a/drivers/misc/mediatek/connectivity/common/common_main/linux/include/stp_btif.h b/drivers/misc/mediatek/connectivity/common/common_main/linux/include/stp_btif.h new file mode 100644 index 0000000000000000000000000000000000000000..68f6d2ae5f9ab542aa6b0ee34898f77e5e1d563f --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/linux/include/stp_btif.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +#ifndef _STP_BTIF_H_ +#define _STP_BTIF_H_ + +#include "osal_typedef.h" +#include "mtk_btif_exp.h" +#include "osal.h" + +struct stp_btif { + ULONG stpBtifId; + OSAL_THREAD btif_thread; +}; + +INT32 mtk_wcn_consys_stp_btif_open(VOID); +INT32 mtk_wcn_consys_stp_btif_close(VOID); +INT32 mtk_wcn_consys_stp_btif_rx_cb_register(MTK_WCN_BTIF_RX_CB rx_cb); +INT32 mtk_wcn_consys_stp_btif_tx(const PUINT8 pBuf, const UINT32 len, PUINT32 written_len); +INT32 mtk_wcn_consys_stp_btif_wakeup(VOID); +INT32 mtk_wcn_consys_stp_btif_dpidle_ctrl(UINT32 en_flag); +INT32 mtk_wcn_consys_stp_btif_lpbk_ctrl(enum _ENUM_BTIF_LPBK_MODE_ mode); +INT32 mtk_wcn_consys_stp_btif_logger_ctrl(enum _ENUM_BTIF_DBG_ID_ flag); +INT32 mtk_wcn_consys_stp_btif_parser_wmt_evt(const PUINT8 str, UINT32 len); +INT32 mtk_wcn_consys_stp_btif_rx_has_pending_data(VOID); +INT32 mtk_wcn_consys_stp_btif_tx_has_pending_data(VOID); +P_OSAL_THREAD mtk_wcn_consys_stp_btif_rx_thread_get(VOID); + +#endif diff --git a/drivers/misc/mediatek/connectivity/common/common_main/linux/include/stp_dbg.h b/drivers/misc/mediatek/connectivity/common/common_main/linux/include/stp_dbg.h new file mode 100644 index 0000000000000000000000000000000000000000..9915eab428536425780004eef9c274616e856454 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/linux/include/stp_dbg.h @@ -0,0 +1,424 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +#ifndef _STP_DEBUG_H_ +#define _STP_DEBUG_H_ + +#include +#include "stp_btif.h" +#include "osal.h" +#include "wmt_exp.h" + +#define CONFIG_LOG_STP_INTERNAL + +#ifndef LOG_STP_DEBUG_DISABLE /* #ifndef CONFIG_LOG_STP_INTERNAL */ +#define STP_PKT_SZ 16 +#define STP_DMP_SZ 2048 +#define STP_PKT_NO 2048 + +#define STP_DBG_LOG_ENTRY_NUM 1024 +#define STP_DBG_LOG_ENTRY_SZ 96 + +#else + +#define STP_PKT_SZ 16 +#define STP_DMP_SZ 16 +#define STP_PKT_NO 16 + +#define STP_DBG_LOG_ENTRY_NUM 28 +#define STP_DBG_LOG_ENTRY_SZ 96 + +#endif +#define EMICOREDUMP_CMD "emicoredump" +#define FAKECOREDUMPEND "coredump end - fake" + +#define MAX_DUMP_HEAD_LEN 512 +/* netlink header packet length is 5 "[M](3 bytes) + length(2 bypes)" */ +#define NL_PKT_HEADER_LEN 5 + +#define PFX_STP_DBG "[STPDbg]" +#define STP_DBG_LOG_LOUD 4 +#define STP_DBG_LOG_DBG 3 +#define STP_DBG_LOG_INFO 2 +#define STP_DBG_LOG_WARN 1 +#define STP_DBG_LOG_ERR 0 + +extern INT32 gStpDbgDbgLevel; + +#define STP_DBG_PR_LOUD(fmt, arg...) \ +do { \ + if (gStpDbgDbgLevel >= STP_DBG_LOG_LOUD) \ + pr_info(PFX_STP_DBG "%s: " fmt, __func__, ##arg); \ +} while (0) +#define STP_DBG_PR_DBG(fmt, arg...) \ +do { \ + if (gStpDbgDbgLevel >= STP_DBG_LOG_DBG) \ + pr_info(PFX_STP_DBG "%s: " fmt, __func__, ##arg); \ +} while (0) +#define STP_DBG_PR_INFO(fmt, arg...) \ +do { \ + if (gStpDbgDbgLevel >= STP_DBG_LOG_INFO) \ + pr_info(PFX_STP_DBG "%s: " fmt, __func__, ##arg); \ +} while (0) +#define STP_DBG_PR_WARN(fmt, arg...) \ +do { \ + if (gStpDbgDbgLevel >= STP_DBG_LOG_WARN) \ + pr_warn(PFX_STP_DBG "%s: " fmt, __func__, ##arg); \ +} while (0) +#define STP_DBG_PR_ERR(fmt, arg...) \ +do { \ + if (gStpDbgDbgLevel >= STP_DBG_LOG_ERR) \ + pr_err(PFX_STP_DBG "%s: " fmt, __func__, ##arg); \ +} while (0) + +typedef enum { + STP_DBG_EN = 0, + STP_DBG_PKT = 1, + STP_DBG_DR = 2, + STP_DBG_FW_ASSERT = 3, + STP_DBG_FW_LOG = 4, + STP_DBG_FW_DMP = 5, + STP_DBG_MAX +} STP_DBG_OP_T; + +typedef enum { + STP_DBG_PKT_FIL_ALL = 0, + STP_DBG_PKT_FIL_BT = 1, + STP_DBG_PKT_FIL_GPS = 2, + STP_DBG_PKT_FIL_FM = 3, + STP_DBG_PKT_FIL_WMT = 4, + STP_DBG_PKT_FIL_MAX +} STP_DBG_PKT_FIL_T; + +static PINT8 const comboStpDbgType[] = { + "< BT>", + "< FM>", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "" +}; + +static PINT8 const socStpDbgType[] = { + "< BT>", + "< FM>", + "", + "", + "", + "", + "", + "", + "" +}; + +enum STP_DBG_TAKS_ID_T { + STP_DBG_TASK_WMT = 0, + STP_DBG_TASK_BT, + STP_DBG_TASK_WIFI, + STP_DBG_TASK_TST, + STP_DBG_TASK_FM, + STP_DBG_TASK_GPS, + STP_DBG_TASK_FLP, + STP_DBG_TASK_BT2, + STP_DBG_TASK_IDLE, + STP_DBG_TASK_DRVSTP, + STP_DBG_TASK_BUS, + STP_DBG_TASK_NATBT, + STP_DBG_TASK_DRVWIFI, + STP_DBG_TASK_DRVGPS, + STP_DBG_TASK_ID_MAX, +}; + +typedef enum { + STP_DBG_DR_MAX = 0, +} STP_DBG_DR_FIL_T; + +typedef enum { + STP_DBG_FW_MAX = 0, +} STP_DBG_FW_FIL_T; + +typedef enum { + PKT_DIR_RX = 0, + PKT_DIR_TX +} STP_DBG_PKT_DIR_T; + +/*simple log system ++*/ + +typedef struct { + /*type: 0. pkt trace 1. fw info + * 2. assert info 3. trace32 dump . + * -1. linked to the the previous + */ + INT32 id; + INT32 len; + INT8 buffer[STP_DBG_LOG_ENTRY_SZ]; +} MTKSTP_LOG_ENTRY_T; + +typedef struct log_sys { + MTKSTP_LOG_ENTRY_T queue[STP_DBG_LOG_ENTRY_NUM]; + UINT32 size; + UINT32 in; + UINT32 out; + spinlock_t lock; + MTKSTP_LOG_ENTRY_T *dump_queue; + UINT32 dump_size; + struct work_struct dump_work; +} MTKSTP_LOG_SYS_T; +/*--*/ + +typedef struct stp_dbg_pkt_hdr { + /* packet information */ + UINT32 sec; + UINT32 usec; + UINT32 dbg_type; + UINT32 last_dbg_type; + UINT32 dmy; + UINT32 no; + UINT32 dir; + + /* packet content */ + UINT32 type; + UINT32 len; + UINT32 ack; + UINT32 seq; + UINT32 chs; + UINT32 crc; + UINT64 l_sec; + ULONG l_nsec; +} STP_DBG_HDR_T; + +typedef struct stp_dbg_pkt { + struct stp_dbg_pkt_hdr hdr; + UINT8 raw[STP_DMP_SZ]; +} STP_PACKET_T; + +typedef struct mtkstp_dbg_t { + /*log_sys */ + INT32 pkt_trace_no; + PVOID btm; + INT32 is_enable; + MTKSTP_LOG_SYS_T *logsys; +} MTKSTP_DBG_T; + +/* extern void aed_combo_exception(const int *, int, const int *, int, const char *); */ +#if WMT_DBG_SUPPORT +#define STP_CORE_DUMP_TIMEOUT (1*60*1000) /* default 1 minutes */ +#else +#define STP_CORE_DUMP_TIMEOUT (10*1000) /* user load default 10 seconds */ +#endif +#if WMT_DBG_SUPPORT +#define STP_EMI_DUMP_TIMEOUT (30*1000) +#else +#define STP_EMI_DUMP_TIMEOUT (5*1000) +#endif +#define STP_OJB_NAME_SZ 20 +#define STP_CORE_DUMP_INFO_SZ 500 +#define STP_CORE_DUMP_INIT_SIZE 512 +typedef enum wcn_compress_algorithm_t { + GZIP = 0, + BZIP2 = 1, + RAR = 2, + LMA = 3, + MAX +} WCN_COMPRESS_ALG_T; + +typedef INT32 (*COMPRESS_HANDLER) (PVOID worker, UINT8 *in_buf, INT32 in_sz, PUINT8 out_buf, PINT32 out_sz, + INT32 finish); +typedef struct wcn_compressor_t { + /* current object name */ + UINT8 name[STP_OJB_NAME_SZ + 1]; + + /* buffer for raw data, named L1 */ + PUINT8 L1_buf; + INT32 L1_buf_sz; + INT32 L1_pos; + + /* target buffer, named L2 */ + PUINT8 L2_buf; + INT32 L2_buf_sz; + INT32 L2_pos; + + /* compress state */ + UINT8 f_done; + UINT16 reserved; + UINT32 uncomp_size; + UINT32 crc32; + + /* compress algorithm */ + UINT8 f_compress_en; + WCN_COMPRESS_ALG_T compress_type; + PVOID worker; + COMPRESS_HANDLER handler; +} WCN_COMPRESSOR_T, *P_WCN_COMPRESSOR_T; + +typedef enum core_dump_state_t { + CORE_DUMP_INIT = 0, + CORE_DUMP_DOING, + CORE_DUMP_TIMEOUT, + CORE_DUMP_DONE, + CORE_DUMP_MAX +} CORE_DUMP_STA; + +typedef struct core_dump_t { + /* compress dump data and buffered */ + P_WCN_COMPRESSOR_T compressor; + + /* timer for monitor timeout */ + OSAL_TIMER dmp_timer; + UINT32 timeout; + LONG dmp_num; + UINT32 count; + OSAL_SLEEPABLE_LOCK dmp_lock; + + /* timer for monitor emi dump */ + OSAL_TIMER dmp_emi_timer; + UINT32 emi_timeout; + + /* state machine for core dump flow */ + CORE_DUMP_STA sm; + + /* dump info */ + INT8 info[STP_CORE_DUMP_INFO_SZ + 1]; + + PUINT8 p_head; + UINT32 head_len; +} WCN_CORE_DUMP_T, *P_WCN_CORE_DUMP_T; + +typedef enum _ENUM_STP_FW_ISSUE_TYPE_ { + STP_FW_ISSUE_TYPE_INVALID = 0x0, + STP_FW_ASSERT_ISSUE = 0x1, + STP_FW_NOACK_ISSUE = 0x2, + STP_FW_WARM_RST_ISSUE = 0x3, + STP_DBG_PROC_TEST = 0x4, + STP_HOST_TRIGGER_FW_ASSERT = 0x5, + STP_HOST_TRIGGER_ASSERT_TIMEOUT = 0x6, + STP_FW_ABT = 0x7, + STP_HOST_TRIGGER_COLLECT_FTRACE = 0x8, + STP_FW_ISSUE_TYPE_MAX +} ENUM_STP_FW_ISSUE_TYPE, *P_ENUM_STP_FW_ISSUE_TYPE; + +/* this was added for support dmareg's issue */ +typedef enum _ENUM_DMA_ISSUE_TYPE_ { + CONNSYS_CLK_GATE_STATUS = 0x00, + CONSYS_EMI_STATUS, + SYSRAM1, + SYSRAM2, + SYSRAM3, + DMA_REGS_MAX +} ENUM_DMA_ISSUE_TYPE; +#define STP_PATCH_TIME_SIZE 12 +#define STP_DBG_CPUPCR_NUM 30 +#define STP_DBG_DMAREGS_NUM 16 +#define STP_PATCH_BRANCH_SZIE 8 +#define STP_ASSERT_INFO_SIZE 164 +#define STP_DBG_ROM_VER_SIZE 4 +#define STP_ASSERT_TYPE_SIZE 64 + +#define STP_DBG_KEYWORD_SIZE 256 +typedef struct stp_dbg_host_assert_t { + UINT32 drv_type; + UINT32 reason; + UINT32 assert_from_host; +} STP_DBG_HOST_ASSERT_T, *P_STP_DBG_HOST_ASSERT_T; + +typedef struct stp_dbg_cpupcr_t { + UINT32 chipId; + UINT8 romVer[STP_DBG_ROM_VER_SIZE]; + UINT8 patchVer[STP_PATCH_TIME_SIZE]; + UINT8 branchVer[STP_PATCH_BRANCH_SZIE]; + UINT32 wifiVer; + UINT32 count; + UINT32 stop_flag; + UINT32 buffer[STP_DBG_CPUPCR_NUM]; + UINT64 sec_buffer[STP_DBG_CPUPCR_NUM]; + ULONG nsec_buffer[STP_DBG_CPUPCR_NUM]; + UINT8 assert_info[STP_ASSERT_INFO_SIZE]; + UINT32 fwTaskId; + UINT32 fwRrq; + UINT32 fwIsr; + STP_DBG_HOST_ASSERT_T host_assert_info; + UINT8 assert_type[STP_ASSERT_TYPE_SIZE]; + ENUM_STP_FW_ISSUE_TYPE issue_type; + UINT8 keyword[STP_DBG_KEYWORD_SIZE]; + OSAL_SLEEPABLE_LOCK lock; +} STP_DBG_CPUPCR_T, *P_STP_DBG_CPUPCR_T; + +typedef struct stp_dbg_dmaregs_t { + UINT32 count; + UINT32 dmaIssue[DMA_REGS_MAX][STP_DBG_DMAREGS_NUM]; + OSAL_SLEEPABLE_LOCK lock; +} STP_DBG_DMAREGS_T, *P_STP_DBG_DMAREGS_T; + +typedef enum _ENUM_ASSERT_INFO_PARSER_TYPE_ { + STP_DBG_ASSERT_INFO = 0x0, + STP_DBG_FW_TASK_ID = 0x1, + STP_DBG_FW_ISR = 0x2, + STP_DBG_FW_IRQ = 0x3, + STP_DBG_ASSERT_TYPE = 0x4, + STP_DBG_PARSER_TYPE_MAX +} ENUM_ASSERT_INFO_PARSER_TYPE, *P_ENUM_ASSERT_INFO_PARSER_TYPE; + +VOID stp_dbg_nl_init(VOID); +VOID stp_dbg_nl_deinit(VOID); +INT32 stp_dbg_core_dump_deinit_gcoredump(VOID); +INT32 stp_dbg_core_dump_flush(INT32 rst, MTK_WCN_BOOL coredump_is_timeout); +INT32 stp_dbg_core_dump(INT32 dump_sink); +INT32 stp_dbg_trigger_collect_ftrace(PUINT8 pbuf, INT32 len); +#if BTIF_RXD_BE_BLOCKED_DETECT +MTK_WCN_BOOL stp_dbg_is_btif_rxd_be_blocked(VOID); +#endif +INT32 stp_dbg_enable(MTKSTP_DBG_T *stp_dbg); +INT32 stp_dbg_disable(MTKSTP_DBG_T *stp_dbg); +INT32 stp_dbg_dmp_print(MTKSTP_DBG_T *stp_dbg); +INT32 stp_dbg_dmp_out(MTKSTP_DBG_T *stp_dbg, PINT8 buf, PINT32 len); +INT32 stp_dbg_dmp_append(MTKSTP_DBG_T *stp_dbg, PUINT8 pBuf, INT32 max_len); + +INT32 stp_dbg_dmp_out_ex(PINT8 buf, PINT32 len); +INT32 stp_dbg_log_pkt(MTKSTP_DBG_T *stp_dbg, INT32 dbg_type, + INT32 type, INT32 ack_no, INT32 seq_no, INT32 crc, INT32 dir, INT32 len, + const PUINT8 body); +INT32 stp_dbg_log_ctrl(UINT32 on); +INT32 stp_dbg_aee_send(PUINT8 aucMsg, INT32 len, INT32 cmd); +INT32 stp_dbg_dump_num(LONG dmp_num); +INT32 stp_dbg_nl_send(PINT8 aucMsg, UINT8 cmd, INT32 len); +INT32 stp_dbg_dump_send_retry_handler(PINT8 tmp, INT32 len); +VOID stp_dbg_set_coredump_timer_state(CORE_DUMP_STA state); +INT32 stp_dbg_get_coredump_timer_state(VOID); +INT32 stp_dbg_poll_cpupcr(UINT32 times, UINT32 sleep, UINT32 cmd); +INT32 stp_dbg_poll_dmaregs(UINT32 times, UINT32 sleep); +INT32 stp_dbg_poll_cpupcr_ctrl(UINT32 en); +INT32 stp_dbg_set_version_info(UINT32 chipid, PUINT8 pRomVer, PUINT8 pPatchVer, PUINT8 pPatchBrh); +INT32 stp_dbg_set_wifiver(UINT32 wifiver); +INT32 stp_dbg_set_host_assert_info(UINT32 drv_type, UINT32 reason, UINT32 en); +VOID stp_dbg_set_keyword(PINT8 keyword); +UINT32 stp_dbg_get_host_trigger_assert(VOID); +INT32 stp_dbg_set_fw_info(PUINT8 issue_info, UINT32 len, ENUM_STP_FW_ISSUE_TYPE issue_type); +INT32 stp_dbg_cpupcr_infor_format(PUINT8 buf, UINT32 max_len); +INT32 stp_dbg_dump_cpupcr_reg_info(PUINT8 buf, UINT32 consys_lp_reg); +VOID stp_dbg_clear_cpupcr_reg_info(VOID); +PUINT8 stp_dbg_id_to_task(UINT32 id); +VOID stp_dbg_reset(VOID); + +MTKSTP_DBG_T *stp_dbg_init(PVOID btm_half); +INT32 stp_dbg_deinit(MTKSTP_DBG_T *stp_dbg); +INT32 stp_dbg_start_coredump_timer(VOID); +INT32 stp_dbg_start_emi_dump(VOID); +INT32 stp_dbg_stop_emi_dump(VOID); +INT32 stp_dbg_nl_send_data(const PINT8 buf, INT32 len); +#endif /* end of _STP_DEBUG_H_ */ diff --git a/drivers/misc/mediatek/connectivity/common/common_main/linux/include/stp_dbg_combo.h b/drivers/misc/mediatek/connectivity/common/common_main/linux/include/stp_dbg_combo.h new file mode 100644 index 0000000000000000000000000000000000000000..ab5a137e56cfaa8f03b5774cf95ead1f17d035c4 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/linux/include/stp_dbg_combo.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +#ifndef _STP_DEBUG_COMBO_H_ +#define _STP_DEBUG_COMBO_H_ + +#include +#include "osal.h" + +INT32 stp_dbg_combo_core_dump(INT32 dump_sink); +PUINT8 stp_dbg_combo_id_to_task(UINT32 id); + +#endif /* end of _STP_DEBUG_COMBO_H_ */ diff --git a/drivers/misc/mediatek/connectivity/common/common_main/linux/include/stp_dbg_soc.h b/drivers/misc/mediatek/connectivity/common/common_main/linux/include/stp_dbg_soc.h new file mode 100644 index 0000000000000000000000000000000000000000..6c070f9a88d3dd40c9c41a95150a9cf60aceaf9a --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/linux/include/stp_dbg_soc.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +#ifndef _STP_DEBUG_SOC_H_ +#define _STP_DEBUG_SOC_H_ + +#include +#include "osal.h" +#include "wmt_plat.h" + +#define STP_DBG_PAGED_DUMP_BUFFER_SIZE (32*1024*sizeof(char)) + +INT32 stp_dbg_soc_core_dump(INT32 dump_sink); +PUINT8 stp_dbg_soc_id_to_task(UINT32 id); +UINT32 stp_dbg_soc_read_debug_crs(ENUM_CONNSYS_DEBUG_CR cr); +INT32 stp_dbg_soc_poll_cpupcr(UINT32 times, UINT32 sleep, UINT32 cmd); + +#endif /* end of _STP_DEBUG_SOC_H_ */ diff --git a/drivers/misc/mediatek/connectivity/common/common_main/linux/include/stp_sdio.h b/drivers/misc/mediatek/connectivity/common/common_main/linux/include/stp_sdio.h new file mode 100644 index 0000000000000000000000000000000000000000..c1b9f45082c9b101ccc52d268480ee06413d039b --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/linux/include/stp_sdio.h @@ -0,0 +1,322 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +/* + * Id: + */ + +/*! \file "stp_sdio.h" + * \brief + */ + +/* + * Log: + */ + +#ifndef _STP_SDIO_H +#define _STP_SDIO_H +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + + +#define KMALLOC_UPDATE 1 + +#if 0 /* NO support for multiple STP-SDIO instances (multiple MT6620) on a single host */ +#define STP_SDIO_HOST_COUNT (1) +#define STP_SDIO_ONLY_ONE_HOST (0) +#endif +#define STP_SDIO_POLL_OWNBACK_INTR (1) + +#define STP_SDIO_NEW_TXRING (0) +/* George: Keep old (0) codes for debugging only! + * Use new code (1) for SQC and MP! + */ + +#define STP_SDIO_OWN_THREAD (1) + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +#include "osal.h" +#include "hif_sdio.h" + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ +/* Common HIF register address */ +#define CCIR (0x0000) +#define CHLPCR (0x0004) +#define CSDIOCSR (0x0008) +#define CHCR (0x000c) +#define CHISR (0x0010) +#define CHIER (0x0014) +#define CTDR (0x0018) +#define CRDR (0x001c) +#define CTFSR (0x0020) +#define CRPLR (0x0024) +#define CTMDPCR0 (0x00B8) +#define CTMDPCR1 (0x00BC) +#define CSR (0x00D8) /* MT6630 & MT6632 only for the moment */ + + + +/* Common HIF register bit field address */ +/* CCCR_F0*/ +#define CCCR_F0_RX_CRC (0x1) +#define CCCR_F0_RX_INT (0x8) + +/* CHLPCR */ +#define C_FW_OWN_REQ_CLR (0x00000200) +#define C_FW_OWN_REQ_SET (0x00000100) +#define C_FW_INT_EN_CLR (0x00000002) +#define C_FW_INT_EN_SET (0x00000001) +#define C_FW_COM_DRV_OWN (0x00000100) + +/* CHIER */ +#define CHISR_EN_15_7 (0x0000ff80) +#define CHISR_EN_3_0 (0x0000000f) +/* CHISR */ +#define RX_PKT_LEN (0xffff0000) +#define FIRMWARE_INT (0x0000fe00) +#define TX_RETRY (0x00000200) +#define TX_FIFO_OVERFLOW (0x00000100) +#define FW_INT_IND_INDICATOR (0x00000080) +#define TX_COMPLETE_COUNT (0x00000070) +#define TX_UNDER_THOLD (0x00000008) +#define TX_EMPTY (0x00000004) +#define RX_DONE (0x00000002) +#define FW_OWN_BACK_INT (0x00000001) + +/* hardware settings */ +#define STP_SDIO_TX_FIFO_SIZE (2080UL) +#define STP_SDIO_RX_FIFO_SIZE (2304UL) /* 256*9 */ +#define STP_SDIO_TX_PKT_MAX_CNT (7) /* Max outstanding tx pkt count, as defined in TX_COMPLETE_COUNT */ +#define STP_SDIO_HDR_SIZE (4) /* hw,fw,sw follow the same format: 2 bytes length + 2 bytes reserved */ + +#define STP_SDIO_DBG_SUPPORT 1 +#define STP_SDIO_RXDBG 1 /* depends on STP_SDIO_DBG_SUPPORT */ +#define STP_SDIO_TXDBG 1 /* depends on STP_SDIO_DBG_SUPPORT */ +#define STP_TXDBG 1 + +/* sdio bus settings */ +#define STP_SDIO_BLK_SIZE (512UL) + +/* software driver settings */ +#define STP_SDIO_TX_BUF_CNT (16UL) /*(7) */ +#define STP_SDIO_TX_BUF_CNT_MASK (STP_SDIO_TX_BUF_CNT - 1) +#define STP_SDIO_TX_PKT_LIST_SIZE (STP_SDIO_TX_BUF_CNT) /* must be 2^x now... */ +#define STP_SDIO_TX_PKT_LIST_SIZE_MASK (STP_SDIO_TX_PKT_LIST_SIZE - 1) + +#define STP_SDIO_FW_CPUPCR_POLLING_CNT (5) + +#define STP_SDIO_RETRY_LIMIT (10) +#define STP_SDIO_MAX_RETRY_NUM (100) + +#define STP_SDIO_RETRY_NONE (0) +#define STP_SDIO_RETRY_CRC_ERROR (1) +#define STP_SDIO_RETRY_INT (2) + +/* tx buffer size for a single entry */ +/* George: SHALL BE a multiple of the used BLK_SIZE!! */ +#if 1 +/* round up: 512*5 = 2560 > 2080 */ +#define STP_SDIO_TX_ENTRY_SIZE ((STP_SDIO_TX_FIFO_SIZE + (STP_SDIO_BLK_SIZE - 1)) & ~(STP_SDIO_BLK_SIZE - 1)) +#else +/* round down: 512*4 = 2048 < 2080 */ +#define STP_SDIO_TX_MAX_BLK_CNT (STP_SDIO_TX_FIFO_SIZE / STP_SDIO_BLK_SIZE) +#define STP_SDIO_TX_ENTRY_SIZE (STP_SDIO_TX_MAX_BLK_CNT * STP_SDIO_BLK_SIZE) +#endif + +/*software rx buffer size */ +/*#define STP_SDIO_RX_BUF_SIZE (STP_SDIO_RX_FIFO_SIZE)*/ +/* George: SHALL BE a multiple of the used BLK_SIZE!! */ +#if 1 +/* round up: 512*5 = 2560 > 2304 */ +#define STP_SDIO_RX_BUF_SIZE ((STP_SDIO_RX_FIFO_SIZE + (STP_SDIO_BLK_SIZE - 1)) & ~(STP_SDIO_BLK_SIZE - 1)) +#else +/* round down: 512*4 = 2048 < 2304 */ +#define STP_SDIO_RX_MAX_BLK_CNT (STP_SDIO_RX_FIFO_SIZE / STP_SDIO_BLK_SIZE) +#define STP_SDIO_RX_BUF_SIZE (STP_SDIO_RX_MAX_BLK_CNT * STP_SDIO_BLK_SIZE) +#endif + +#define COHEC_00006052 (1) +/* #define COHEC_00006052 (0) */ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ +typedef enum _ENUM_STP_SDIO_HIF_TYPE_T { + HIF_TYPE_READB = 0, + HIF_TYPE_READL = HIF_TYPE_READB + 1, + HIF_TYPE_READ_BUF = HIF_TYPE_READL + 1, + HIF_TYPE_WRITEB = HIF_TYPE_READ_BUF + 1, + HIF_TYPE_WRITEL = HIF_TYPE_WRITEB + 1, + HIF_TYPE_WRITE_BUF = HIF_TYPE_WRITEL + 1, + HIF_TYPE_MAX +} ENUM_STP_SDIO_HIF_TYPE_T, *P_ENUM_STP_SDIO_HIF_TYPE_T; + +/* HIF's local packet buffer variables for Tx/Rx */ +typedef struct _MTK_WCN_STP_SDIO_PKT_BUF { + /* Tx entry ring buffer. Entry size is aligned to SDIO block size. */ +#if KMALLOC_UPDATE + PUINT8 tx_buf; +#else + UINT8 tx_buf[STP_SDIO_TX_BUF_CNT][STP_SDIO_TX_ENTRY_SIZE]; +#endif + + /* Tx size ring buffer. Record valid data size in tx_buf. */ + UINT32 tx_buf_sz[STP_SDIO_TX_BUF_CNT]; + /* Tx debug timestamp: 1st time when the entry is filled with data */ + UINT32 tx_buf_ts[STP_SDIO_TX_BUF_CNT]; + UINT64 tx_buf_local_ts[STP_SDIO_TX_BUF_CNT]; + ULONG tx_buf_local_nsec[STP_SDIO_TX_BUF_CNT]; + +#if KMALLOC_UPDATE + PUINT8 rx_buf; +#else + UINT8 rx_buf[STP_SDIO_RX_BUF_SIZE]; /* Rx buffer (not ring) */ +#endif +#if STP_SDIO_NEW_TXRING + atomic_t wr_cnt; /* Tx entry ring buffer write count */ + atomic_t rd_cnt; /* Tx entry ring buffer read count */ + spinlock_t rd_cnt_lock; /* Tx entry ring buffer read count spin lock */ +#else + atomic_t wr_idx; /* Tx ring buffer write index *//*George: obsolete */ + atomic_t rd_idx; /* Tx ring buffer read index *//*George: obsolete */ + spinlock_t rd_idx_lock; /* spin lock for Tx ring buffer read index */ +#endif + MTK_WCN_BOOL full_flag; /* Tx entry ring buffer full flag (TRUE: full, FALSE: not full) */ + /* save interrupt status flag for Tx entry ring buf spin lock */ + ULONG rd_irq_flag; + /* wait queue head for Tx entry ring buf full case */ + wait_queue_head_t fullwait_q; +} MTK_WCN_STP_SDIO_PKT_BUF; + +/* Tx packet list information */ +typedef struct _MTK_WCN_STP_SDIO_Tx_Pkt_LIST { + UINT32 pkt_rd_cnt; + UINT32 pkt_wr_cnt; + UINT16 pkt_size_list[STP_SDIO_TX_PKT_LIST_SIZE]; /*max length is FIFO Size */ + UINT32 out_ts[STP_SDIO_TX_PKT_LIST_SIZE]; + UINT32 in_ts[STP_SDIO_TX_PKT_LIST_SIZE]; +} MTK_WCN_STP_SDIO_Tx_Pkt_LIST; + +/* STP HIF firmware information */ +typedef struct _MTK_WCN_STP_SDIO_FIRMWARE_INFO { + UINT32 tx_fifo_size; /* Current left tx FIFO size */ + UINT32 tx_packet_num; /* Current outstanding tx packet (0~7) */ + atomic_t tx_comp_num; /* Current total tx ok but fifo size not released packet count */ +} MTK_WCN_STP_SDIO_FIRMWARE_INFO; + +/* STP SDIO private information */ +typedef struct _MTK_WCN_STP_SDIO_PRIVATE_INFO { + UINT8 stp_sdio_host_idx; +} MTK_WCN_STP_SDIO_PRIVATE_INFO; + +/* STP SDIO host information */ +typedef struct _MTK_WCN_STP_SDIO_HIF_INFO { + MTK_WCN_HIF_SDIO_CLTCTX sdio_cltctx; + MTK_WCN_STP_SDIO_PKT_BUF pkt_buf; + MTK_WCN_STP_SDIO_Tx_Pkt_LIST tx_pkt_list; + UINT32 rx_pkt_len; /* George: use 32-bit for efficiency. Correct name to pkt for packet */ + MTK_WCN_STP_SDIO_FIRMWARE_INFO firmware_info; + MTK_WCN_STP_SDIO_PRIVATE_INFO private_info; +#if STP_SDIO_OWN_THREAD + /* struct tasklet_struct tx_rx_job; */ + OSAL_THREAD tx_rx_thread; + INT32 irq_pending; + INT32 sleep_flag; + INT32 wakeup_flag; + INT32 awake_flag; + INT32 txwkr_flag; + OSAL_EVENT tx_rx_event; + OSAL_SIGNAL isr_check_complete; + INT32 dump_flag; +#endif + INT32 tx_dbg_dump_flag; + INT32 tx_retry_flag; + INT32 retry_enable_flag; + INT32 tx_retry_count; + INT32 rx_retry_count; + struct work_struct tx_work; + struct work_struct rx_work; +} MTK_WCN_STP_SDIO_HIF_INFO; + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ +extern MTK_WCN_STP_SDIO_HIF_INFO g_stp_sdio_host_info; + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +/* STP_SDIO_TX_PKT_LIST_SIZE must be 2^x */ +#define STP_SDIO_GET_PKT_AR_IDX(idx) ((idx) & STP_SDIO_TX_PKT_LIST_SIZE_MASK) + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/*! + * \brief MTK hif sdio client registration function + * + * Client uses this function to do hif sdio registration + * + * \param pinfo a pointer of client's information + * + * \retval 0 register successfully + * \retval < 0 error code + */ +extern INT32 mtk_wcn_hif_sdio_client_reg(const MTK_WCN_HIF_SDIO_CLTINFO *pinfo); +extern INT32 stp_sdio_reg_rw(INT32 func_num, INT32 direction, UINT32 offset, UINT32 value); + +#if STP_SDIO_DBG_SUPPORT && (STP_SDIO_TXDBG || STP_SDIO_TXPERFDBG) +VOID stp_sdio_txdbg_dump(VOID); +#endif + +extern INT32 mtk_wcn_stp_sdio_do_own_clr(VOID); +#ifdef CONFIG_MTK_COMBO_CHIP_DEEP_SLEEP_SUPPORT +INT32 stp_sdio_deep_sleep_flag_set(MTK_WCN_BOOL flag); +#endif +/* extern INT32 */ +/* mtk_wcn_stp_sdio_do_own_set (void); */ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +INT32 stp_sdio_rw_retry(ENUM_STP_SDIO_HIF_TYPE_T type, UINT32 retry_limit, + MTK_WCN_HIF_SDIO_CLTCTX clt_ctx, UINT32 offset, PUINT32 pData, UINT32 len); +VOID stp_sdio_retry_flag_ctrl(INT32 flag); +INT32 stp_sdio_retry_flag_get(VOID); +INT32 stp_sdio_wake_up_ctrl(MTK_WCN_HIF_SDIO_CLTCTX ctx); +VOID stp_sdio_dump_register(VOID); +INT32 stp_sdio_issue_fake_coredump(UINT8 *str); +VOID stp_sdio_dump_info(MTK_WCN_STP_SDIO_HIF_INFO *p_info); + + +#endif /* _STP_SDIO_H */ diff --git a/drivers/misc/mediatek/connectivity/common/common_main/linux/include/wmt_alarm.h b/drivers/misc/mediatek/connectivity/common/common_main/linux/include/wmt_alarm.h new file mode 100644 index 0000000000000000000000000000000000000000..d45d632770578032de1765665665e5c3dd58f8b8 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/linux/include/wmt_alarm.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef _WMT_ALARM_H_ +#define _WMT_ALARM_H_ + +int wmt_alarm_init(void); +int wmt_alarm_deinit(void); + +int wmt_alarm_start(unsigned int sec); +int wmt_alarm_cancel(void); + +#endif diff --git a/drivers/misc/mediatek/connectivity/common/common_main/linux/include/wmt_dbg.h b/drivers/misc/mediatek/connectivity/common/common_main/linux/include/wmt_dbg.h new file mode 100644 index 0000000000000000000000000000000000000000..bc16dbd6acd3d8d6f6d98765d43898b3755aed3c --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/linux/include/wmt_dbg.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +#ifndef _WMT_DBG_H_ +#define _WMT_DBG_H_ +#include "osal.h" + +#define STP_SDIO 0x04 +#define STP_UART_MAND 0x02 +#define STP_UART_FULL 0x01 + +#if (WMT_DBG_SUPPORT) +#define CFG_WMT_DBG_SUPPORT 1 /* support wmt_dbg or not */ +#else +#define CFG_WMT_DBG_SUPPORT 0 +#endif + +#define CFG_WMT_PROC_FOR_AEE 1 + +typedef struct _COEX_BUF { + UINT8 buffer[128]; + INT32 availSize; +} COEX_BUF, *P_COEX_BUF; + +typedef enum _ENUM_CMD_TYPE_T { + WMTDRV_CMD_ASSERT = 0, + WMTDRV_CMD_EXCEPTION = 1, + WMTDRV_CMD_COEXDBG_00 = 2, + WMTDRV_CMD_COEXDBG_01 = 3, + WMTDRV_CMD_COEXDBG_02 = 4, + WMTDRV_CMD_COEXDBG_03 = 5, + WMTDRV_CMD_COEXDBG_04 = 6, + WMTDRV_CMD_COEXDBG_05 = 7, + WMTDRV_CMD_COEXDBG_06 = 8, + WMTDRV_CMD_COEXDBG_07 = 9, + WMTDRV_CMD_COEXDBG_08 = 10, + WMTDRV_CMD_COEXDBG_09 = 11, + WMTDRV_CMD_COEXDBG_10 = 12, + WMTDRV_CMD_COEXDBG_11 = 13, + WMTDRV_CMD_COEXDBG_12 = 14, + WMTDRV_CMD_COEXDBG_13 = 15, + WMTDRV_CMD_COEXDBG_14 = 16, + WMTDRV_CMD_COEXDBG_15 = 17, + WMTDRV_CMD_NOACK_TEST = 18, + WMTDRV_CMD_WARNRST_TEST = 19, + WMTDRV_CMD_FWTRACE_TEST = 20, + WMTDRV_CMD_MAX +} ENUM_WMTDRV_CMD_T, *P_ENUM_WMTDRV_CMD_T; + + +typedef INT32(*WMT_DEV_DBG_FUNC) (INT32 par1, INT32 par2, INT32 par3); +INT32 wmt_dev_dbg_setup(VOID); +INT32 wmt_dev_dbg_remove(VOID); +INT32 wmt_dbg_fwinfor_from_emi(INT32 par1, INT32 par2, INT32 par3); + +#endif /* _WMT_DBG_H_ */ diff --git a/drivers/misc/mediatek/connectivity/common/common_main/linux/include/wmt_dev.h b/drivers/misc/mediatek/connectivity/common/common_main/linux/include/wmt_dev.h new file mode 100644 index 0000000000000000000000000000000000000000..0aec923213db586304b32036351bd7d23047dbf5 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/linux/include/wmt_dev.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +#ifndef _WMT_DEV_H_ +#define _WMT_DEV_H_ + +#include "osal.h" + +#define STP_UART_FULL 0x01 +#define STP_UART_MAND 0x02 +#define STP_BTIF_FULL 0x03 +#define STP_SDIO 0x04 + +VOID wmt_dev_rx_event_cb(VOID); +INT32 wmt_dev_rx_timeout(P_OSAL_EVENT pEvent); +INT32 wmt_dev_patch_get(PUINT8 pPatchName, osal_firmware **ppPatch); +INT32 wmt_dev_patch_put(osal_firmware **ppPatch); +VOID wmt_dev_patch_info_free(VOID); +VOID wmt_dev_send_cmd_to_daemon(UINT32 cmd); +MTK_WCN_BOOL wmt_dev_get_early_suspend_state(VOID); +INT32 wmt_lpbk_handler(UINT32 on_off_flag, UINT32 retry); +VOID wmt_dev_blank_handler(VOID); +UINT32 wmt_dev_get_blank_state(VOID); +INT32 wmt_dev_apo_ctrl(UINT32 enable); +VOID wmt_dev_set_temp_threshold(INT32 val); +UINT8 wmt_dev_is_close(VOID); +extern LONG wmt_dev_tm_temp_query(VOID); + +INT32 mtk_wcn_common_drv_init(VOID); +VOID mtk_wcn_common_drv_exit(VOID); + +int mtk_wcn_hif_sdio_drv_init(VOID); +int mtk_wcn_stp_uart_drv_init(VOID); +int mtk_wcn_stp_sdio_drv_init(VOID); +int mtk_wcn_hif_sdio_driver_exit(VOID); +int mtk_wcn_stp_sdio_drv_exit(VOID); +int mtk_wcn_stp_uart_drv_exit(VOID); + +#endif /*_WMT_DEV_H_*/ diff --git a/drivers/misc/mediatek/connectivity/common/common_main/linux/include/wmt_idc.h b/drivers/misc/mediatek/connectivity/common/common_main/linux/include/wmt_idc.h new file mode 100644 index 0000000000000000000000000000000000000000..3ea063561949262fb982ee651c4e488a724941bf --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/linux/include/wmt_idc.h @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +#ifndef _WMT_IDC_H_ +#define _WMT_IDC_H_ + +#include "osal.h" +#include "stp_exp.h" + +#if CFG_WMT_LTE_COEX_HANDLING + +#include +#include "conn_md_exp.h" + +#define LTE_IDC_BUFFER_MAX_SIZE 1024 +/*comment from firmware owner,max pckage num is 5,but should not happened*/ +#define WMT_IDC_RX_MAX_LEN 384 +#define LTE_MSG_ID_OFFSET 0x30 + +typedef enum { + WMT_IDC_TX_OPCODE_MIN = 0, + WMT_IDC_TX_OPCODE_LTE_PARA = 0x0a, + WMT_IDC_TX_OPCODE_LTE_FREQ = 0x0b, + WMT_IDC_TX_OPCODE_WIFI_MAX_POWER = 0x0c, + WMT_IDC_TX_OPCODE_DEBUG_MONITOR = 0x0e, + WMT_IDC_TX_OPCODE_SPLIT_FILTER = 0x0f, + WMT_IDC_TX_OPCODE_LTE_CONNECTION_STAS = 0x16, + WMT_IDC_TX_OPCODE_LTE_HW_IF_INDICATION = 0x17, + WMT_IDC_TX_OPCODE_LTE_INDICATION = 0x20, + WMT_IDC_TX_OPCODE_MAX +} WMT_IDC_TX_OPCODE; + +typedef enum { + WMT_IDC_RX_OPCODE_BTWF_DEF_PARA = 0x0, + WMT_IDC_RX_OPCODE_BTWF_CHAN_RAN = 0x1, + /* WMT_IDC_RX_OPCODE_TDM_REQ = 0x10, */ + WMT_IDC_RX_OPCODE_DEBUG_MONITOR = 0x02, + WMT_IDC_RX_OPCODE_LTE_FREQ_IDX_TABLE = 0x03, + WMT_IDC_RX_OPCODE_BTWF_PROFILE_IND = 0x04, + WMT_IDC_RX_OPCODE_UART_PIN_SEL = 0x05, + WMT_IDC_RX_OPCODE_MAX +} WMT_IDC_RX_OPCODE; + +#if (CFG_WMT_LTE_ENABLE_MSGID_MAPPING == 0) +typedef enum { + IPC_L4C_MSG_ID_INVALID = IPC_L4C_MSG_ID_BEGIN, + IPC_L4C_MSG_ID_END, + IPC_EL1_MSG_ID_INVALID = IPC_EL1_MSG_ID_BEGIN, + /* below are EL1 IPC messages sent from AP */ + IPC_MSG_ID_EL1_LTE_TX_ALLOW_IND, + IPC_MSG_ID_EL1_WIFIBT_OPER_DEFAULT_PARAM_IND, + IPC_MSG_ID_EL1_WIFIBT_OPER_FREQ_IND, + IPC_MSG_ID_EL1_WIFIBT_FREQ_IDX_TABLE_IND, + IPC_MSG_ID_EL1_WIFIBT_PROFILE_IND, + + /* below are EL1 messages sent to AP */ + IPC_MSG_ID_EL1_LTE_DEFAULT_PARAM_IND, + IPC_MSG_ID_EL1_LTE_OPER_FREQ_PARAM_IND, + IPC_MSG_ID_EL1_WIFI_MAX_PWR_IND, + IPC_MSG_ID_EL1_LTE_TX_IND, + IPC_MSG_ID_EL1_LTE_CONNECTION_STATUS_IND, + IPC_MSG_ID_EL1_PIN_TYPE_IND, + IPC_MSG_ID_EL1_LTE_HW_INTERFACE_IND, + IPC_MSG_ID_EL1_DUMMY13_IND, + IPC_MSG_ID_EL1_DUMMY14_IND, + IPC_MSG_ID_EL1_DUMMY15_IND, + IPC_MSG_ID_EL1_DUMMY16_IND, + IPC_MSG_ID_EL1_DUMMY17_IND, + IPC_MSG_ID_EL1_DUMMY18_IND, + IPC_MSG_ID_EL1_DUMMY19_IND, + IPC_MSG_ID_EL1_DUMMY20_IND, + IPC_MSG_ID_EL1_DUMMY21_IND, + IPC_MSG_ID_EL1_DUMMY22_IND, + IPC_MSG_ID_EL1_DUMMY23_IND, + IPC_MSG_ID_EL1_DUMMY24_IND, + IPC_MSG_ID_EL1_DUMMY25_IND, + IPC_MSG_ID_EL1_DUMMY26_IND, + IPC_MSG_ID_EL1_DUMMY27_IND, + IPC_MSG_ID_EL1_DUMMY28_IND, + IPC_MSG_ID_EL1_DUMMY29_IND, + IPC_MSG_ID_EL1_DUMMY30_IND, + IPC_MSG_ID_MD_CONSYS_VERIFICATION_IND, + IPC_MSG_ID_MD_CONSYS_VERIFICATION_REQ, + IPC_EL1_MSG_ID_END, +} IPC_MSG_ID_CODE; +#endif + +typedef struct _MTK_WCN_WMT_IDC_INFO_ { + conn_md_ipc_ilm_t iit; + struct conn_md_bridge_ops ops; + UINT8 buffer[LTE_IDC_BUFFER_MAX_SIZE]; +} MTK_WCN_WMT_IDC_INFO, *P_MTK_WCN_WMT_IDC_INFO; + +INT32 wmt_idc_init(VOID); +INT32 wmt_idc_deinit(VOID); +INT32 wmt_idc_msg_from_lte_handing(conn_md_ipc_ilm_t *ilm); +INT32 wmt_idc_msg_to_lte_handing(VOID); +UINT32 wmt_idc_msg_to_lte_handing_for_test(PUINT8 p_buf, UINT32 len); + +#endif /* endif CFG_WMT_LTE_COEX_HANDLING */ + +#endif /* _WMT_IDC_H_ */ diff --git a/drivers/misc/mediatek/connectivity/common/common_main/linux/include/wmt_proc_dbg.h b/drivers/misc/mediatek/connectivity/common/common_main/linux/include/wmt_proc_dbg.h new file mode 100644 index 0000000000000000000000000000000000000000..1e8ed9be99f8d60ac8245e8be949dbc4ce3a3636 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/linux/include/wmt_proc_dbg.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef _WMT_PROC_DBG_H_ +#define _WMT_PROC_DBG_H_ + +#include "osal.h" + +#define CFG_WMT_PROC_FOR_AEE 1 +#define CFG_WMT_PROC_FOR_DUMP_INFO 1 + +#if CFG_WMT_PROC_FOR_DUMP_INFO +INT32 wmt_dev_proc_for_dump_info_setup(VOID); +INT32 wmt_dev_proc_for_dump_info_remove(VOID); +#else +INT32 wmt_dev_proc_for_dump_info_setup(VOID) {} +INT32 wmt_dev_proc_for_dump_info_remove(VOID) {} +#endif + +INT32 wmt_dev_proc_init(VOID); +INT32 wmt_dev_proc_deinit(VOID); + + +#endif /* _WMT_PROC_DBG_H_ */ diff --git a/drivers/misc/mediatek/connectivity/common/common_main/linux/include/wmt_step.h b/drivers/misc/mediatek/connectivity/common/common_main/linux/include/wmt_step.h new file mode 100644 index 0000000000000000000000000000000000000000..8be5dc860b610b1bb058b762cdb9a7ae3e71acb7 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/linux/include/wmt_step.h @@ -0,0 +1,373 @@ +/* + * Copyright (C) 2016 MediaTek Inc. * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +#ifndef _WMT_STEP_H_ +#define _WMT_STEP_H_ + +#include + +#include "osal.h" +#include "wmt_exp.h" +#include "wmt_core.h" + +#define STEP_CONFIG_NAME "WMT_STEP.cfg" +#define STEP_VERSION 2 + +#define STEP_PERIODIC_DUMP_WORK_QUEUE "wmt_step_pd_wq" +#define STEP_PERIODIC_DUMP_THREAD "wmt_pd" + +#define STEP_ACTION_NAME_EMI "_EMI" +#define STEP_ACTION_NAME_REGISTER "_REG" +#define STEP_ACTION_NAME_GPIO "GPIO" +#define STEP_ACTION_NAME_DISABLE_RESET "DRST" +#define STEP_ACTION_NAME_CHIP_RESET "_RST" +#define STEP_ACTION_NAME_KEEP_WAKEUP "WAK+" +#define STEP_ACTION_NAME_CANCEL_WAKEUP "WAK-" +#define STEP_ACTION_NAME_SHOW_STRING "SHOW" +#define STEP_ACTION_NAME_SLEEP "_SLP" +#define STEP_ACTION_NAME_CONDITION "COND" +#define STEP_ACTION_NAME_VALUE "_VAL" +#define STEP_ACTION_NAME_CONDITION_EMI "CEMI" +#define STEP_ACTION_NAME_CONDITION_REGISTER "CREG" + +extern struct platform_device *g_pdev; + +enum step_action_id { + STEP_ACTION_INDEX_NO_DEFINE = 0, + STEP_ACTION_INDEX_EMI = 1, + STEP_ACTION_INDEX_REGISTER, + STEP_ACTION_INDEX_GPIO, + STEP_ACTION_INDEX_DISABLE_RESET, + STEP_ACTION_INDEX_CHIP_RESET, + STEP_ACTION_INDEX_KEEP_WAKEUP, + STEP_ACTION_INDEX_CANCEL_WAKEUP, + STEP_ACTION_INDEX_PERIODIC_DUMP, + STEP_ACTION_INDEX_SHOW_STRING, + STEP_ACTION_INDEX_SLEEP, + STEP_ACTION_INDEX_CONDITION, + STEP_ACTION_INDEX_VALUE, + STEP_ACTION_INDEX_CONDITION_EMI, + STEP_ACTION_INDEX_CONDITION_REGISTER, + STEP_ACTION_INDEX_MAX, +}; + +enum step_trigger_point_id { + STEP_TRIGGER_POINT_NO_DEFINE = 0, + STEP_TRIGGER_POINT_COMMAND_TIMEOUT = 1, + STEP_TRIGGER_POINT_FIRMWARE_TRIGGER_ASSERT, + STEP_TRIGGER_POINT_BEFORE_CHIP_RESET, + STEP_TRIGGER_POINT_AFTER_CHIP_RESET, + STEP_TRIGGER_POINT_BEFORE_WIFI_FUNC_ON, + STEP_TRIGGER_POINT_BEFORE_WIFI_FUNC_OFF, + STEP_TRIGGER_POINT_BEFORE_BT_FUNC_ON, + STEP_TRIGGER_POINT_BEFORE_BT_FUNC_OFF, + STEP_TRIGGER_POINT_BEFORE_FM_FUNC_ON, + STEP_TRIGGER_POINT_BEFORE_FM_FUNC_OFF, + STEP_TRIGGER_POINT_BEFORE_GPS_FUNC_ON, + STEP_TRIGGER_POINT_BEFORE_GPS_FUNC_OFF, + STEP_TRIGGER_POINT_BEFORE_READ_THERMAL, + STEP_TRIGGER_POINT_POWER_ON_START, + STEP_TRIGGER_POINT_POWER_ON_BEFORE_GET_CONNSYS_ID, + STEP_TRIGGER_POINT_POWER_ON_BEFORE_SEND_DOWNLOAD_PATCH, + STEP_TRIGGER_POINT_POWER_ON_BEFORE_CONNSYS_RESET, + STEP_TRIGGER_POINT_POWER_ON_BEFORE_SET_WIFI_LTE_COEX, + STEP_TRIGGER_POINT_POWER_ON_BEFORE_BT_WIFI_CALIBRATION, + STEP_TRIGGER_POINT_POWER_ON_END, + STEP_TRIGGER_POINT_BEFORE_POWER_OFF, + STEP_TRIGGER_POINT_WHEN_AP_SUSPEND, + STEP_TRIGGER_POINT_WHEN_AP_RESUME, + STEP_TRIGGER_POINT_POWER_OFF_HANDSHAKE, + STEP_TRIGGER_POINT_BEFORE_RESTORE_CAL_RESULT, + STEP_TRIGGER_POINT_AFTER_RESTORE_CAL_RESULT, + STEP_TRIGGER_POINT_POWER_ON_AFTER_BT_WIFI_CALIBRATION, + STEP_TRIGGER_POINT_AFTER_RESTORE_CAL_CMD, + STEP_TRIGGER_POINT_WHEN_CLOCK_FAIL, + STEP_TRIGGER_POINT_BEFORE_GPSL5_FUNC_ON, + STEP_TRIGGER_POINT_BEFORE_GPSL5_FUNC_OFF, + STEP_TRIGGER_POINT_MAX, +}; + +enum step_base_address_index { + STEP_MCU_BASE_INDEX = 0, + STEP_TOP_RGU_BASE_INDEX, + STEP_INFRACFG_AO_BASE_INDEX, + STEP_SPM_BASE_INDEX, + STEP_MCU_CONN_HIF_ON_BASE_INDEX, + STEP_MCU_TOP_MISC_OFF_BASE_INDEX, + STEP_MCU_CFG_ON_BASE_INDEX, + STEP_MCU_CIRQ_BASE_INDEX, + STEP_MCU_TOP_MISC_ON_BASE_INDEX, + STEP_BASE_ADDRESS_MAX, +}; + +enum step_register_base_id { + STEP_REGISTER_PHYSICAL_ADDRESS = 0, + STEP_REGISTER_CONN_MCU_CONFIG_BASE, + STEP_REGISTER_AP_RGU_BASE, + STEP_REGISTER_TOPCKGEN_BASE, + STEP_REGISTER_SPM_BASE, + STEP_REGISTER_HIF_ON_BASE, + STEP_REGISTER_MISC_OFF_BASE, + STEP_REGISTER_CFG_ON_BASE, + STEP_CIRQ_BASE, + STEP_MCU_TOP_MISC_ON_BASE, + STEP_REGISTER_MAX, +}; + +enum step_condition_operator_id { + STEP_OPERATOR_GREATER = 0, + STEP_OPERATOR_GREATER_EQUAL, + STEP_OPERATOR_LESS, + STEP_OPERATOR_LESS_EQUAL, + STEP_OPERATOR_EQUAL, + STEP_OPERATOR_NOT_EQUAL, + STEP_OPERATOR_AND, + STEP_OPERATOR_OR, + STEP_OPERATOR_MAX, +}; + +struct step_register_base_struct { + unsigned long vir_addr; + unsigned long long size; +}; + +struct step_action_list { + struct list_head list; +}; + +struct step_pd_entry { + bool is_enable; + unsigned int expires_ms; + struct step_action_list action_list; + struct delayed_work pd_work; + struct list_head list; +}; + +struct step_pd_struct { + bool is_init; + struct workqueue_struct *step_pd_wq; + struct list_head pd_list; +}; + +struct step_action { + struct list_head list; + enum step_action_id action_id; +}; + +typedef int (*STEP_WRITE_ACT_TO_LIST) (struct step_action_list *, enum step_action_id, int, char **); +typedef void (*STEP_DO_EXTRA) (unsigned int, ...); + +#define STEP_OUTPUT_LOG 0 +#define STEP_OUTPUT_REGISTER 1 + +struct step_emi_info { + bool is_write; + unsigned int begin_offset; + unsigned int end_offset; + int value; + unsigned int temp_reg_id; + int output_mode; + int mask; +}; + +struct step_emi_action { + struct step_emi_info info; + struct step_action base; +}; + +struct step_reigster_info { + bool is_write; + enum step_register_base_id address_type; + unsigned long address; + unsigned int offset; + unsigned int times; + unsigned int delay_time; + int value; + int mask; + unsigned int temp_reg_id; + int output_mode; +}; + +struct step_register_action { + struct step_reigster_info info; + struct step_action base; +}; + +struct step_gpio_action { + bool is_write; + unsigned int pin_symbol; + struct step_action base; +}; + +struct step_disable_reset_action { + struct step_action base; +}; + +struct step_chip_reset_action { + struct step_action base; +}; + +struct step_keep_wakeup_action { + struct step_action base; +}; + +struct step_cancel_wakeup_action { + struct step_action base; +}; + +struct step_periodic_dump_action { + struct step_pd_entry *pd_entry; + struct step_action base; +}; + +struct step_show_string_action { + char *content; + struct step_action base; +}; + +struct step_sleep_action { + unsigned int ms; + struct step_action base; +}; + +#define STEP_CONDITION_RIGHT_REGISTER 0 +#define STEP_CONDITION_RIGHT_VALUE 1 +struct step_condition_action { + unsigned int result_temp_reg_id; + unsigned int l_temp_reg_id; + unsigned int r_temp_reg_id; + int value; + int mode; + enum step_condition_operator_id operator_id; + struct step_action base; +}; + +struct step_value_action { + unsigned int temp_reg_id; + int value; + struct step_action base; +}; + +struct step_condition_emi_action { + unsigned int cond_reg_id; + struct step_emi_info info; + struct step_action base; +}; + +struct step_condition_register_action { + unsigned int cond_reg_id; + struct step_reigster_info info; + struct step_action base; +}; + +#define list_entry_action(act_struct, ptr) \ + container_of(ptr, struct step_##act_struct##_action, base) + +struct step_reg_addr_info { + int address_type; + unsigned long address; +}; + +struct step_target_act_list_info { + enum step_trigger_point_id tp_id; + struct step_action_list *p_target_list; + struct step_pd_entry *p_pd_entry; +}; + +#define STEP_PARAMETER_SIZE 10 +struct step_parse_line_data_param_info { + int state; + enum step_action_id act_id; + char *act_params[STEP_PARAMETER_SIZE]; + int param_index; +}; + +typedef struct step_action *(*STEP_CREATE_ACTION) (int, char *[]); +typedef int (*STEP_DO_ACTIONS) (struct step_action *, STEP_DO_EXTRA); +typedef void (*STEP_REMOVE_ACTION) (struct step_action *); +struct step_action_contrl { + STEP_CREATE_ACTION func_create_action; + STEP_DO_ACTIONS func_do_action; + STEP_REMOVE_ACTION func_remove_action; +}; + +#define STEP_REGISTER_BASE_SYMBOL '#' +#define STEP_TEMP_REGISTER_SYMBOL '$' + +#define STEP_VALUE_INFO_UNKNOWN -1 +#define STEP_VALUE_INFO_NUMBER 0 +#define STEP_VALUE_INFO_SYMBOL_REG_BASE 1 +#define STEP_VALUE_INFO_SYMBOL_TEMP_REG 2 + +#define STEP_TEMP_REGISTER_SIZE 10 +struct step_env_struct { + bool is_enable; + bool is_keep_wakeup; + struct step_action_list actions[STEP_TRIGGER_POINT_MAX]; + unsigned char __iomem *emi_base_addr; + struct step_register_base_struct reg_base[STEP_REGISTER_MAX]; + struct step_pd_struct pd_struct; + int temp_register[STEP_TEMP_REGISTER_SIZE]; + bool is_setup; + struct rw_semaphore init_rwsem; +}; + +/******************************************************************************** + * F U N C T I O N D E C L A R A T I O N S +*********************************************************************************/ +void wmt_step_init(void); +void wmt_step_deinit(void); +void wmt_step_do_actions(enum step_trigger_point_id tp_id); +void wmt_step_func_crtl_do_actions(ENUM_WMTDRV_TYPE_T type, ENUM_WMT_OPID_T opId); +void wmt_step_command_timeout_do_actions(char *reason); +#ifdef CFG_WMT_STEP +#define WMT_STEP_INIT_FUNC() wmt_step_init() +#define WMT_STEP_DEINIT_FUNC() wmt_step_deinit() +#define WMT_STEP_DO_ACTIONS_FUNC(tp) wmt_step_do_actions(tp) +#define WMT_STEP_FUNC_CTRL_DO_ACTIONS_FUNC(type, id) wmt_step_func_crtl_do_actions(type, id) +#define WMT_STEP_COMMAND_TIMEOUT_DO_ACTIONS_FUNC(reason) wmt_step_command_timeout_do_actions(reason) +#else +#define WMT_STEP_INIT_FUNC() +#define WMT_STEP_DEINIT_FUNC() +#define WMT_STEP_DO_ACTIONS_FUNC(tp) +#define WMT_STEP_FUNC_CTRL_DO_ACTIONS_FUNC(type, id) +#define WMT_STEP_COMMAND_TIMEOUT_DO_ACTIONS_FUNC(reason) +#endif + +/******************************************************************************** + * D E C L A R E F O R T E S T +*********************************************************************************/ +int wmt_step_read_file(const char *file_name); +int wmt_step_parse_data(const char *in_buf, unsigned int size, STEP_WRITE_ACT_TO_LIST func_act_to_list); +int wmt_step_init_pd_env(void); +int wmt_step_deinit_pd_env(void); +struct step_pd_entry *wmt_step_get_periodic_dump_entry(unsigned int expires); +struct step_action *wmt_step_create_action(enum step_action_id act_id, int param_num, char *params[]); +int wmt_step_do_emi_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra); +int wmt_step_do_register_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra); +int wmt_step_do_gpio_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra); +int wmt_step_do_disable_reset_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra); +int wmt_step_do_chip_reset_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra); +int wmt_step_do_keep_wakeup_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra); +int wmt_step_do_cancel_wakeup_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra); +int wmt_step_do_periodic_dump_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra); +int wmt_step_do_show_string_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra); +int wmt_step_do_sleep_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra); +int wmt_step_do_condition_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra); +int wmt_step_do_value_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra); +int wmt_step_do_condition_emi_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra); +int wmt_step_do_condition_register_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra); +void wmt_step_remove_action(struct step_action *p_act); +void wmt_step_print_version(void); + +#endif /* end of _WMT_STEP_H_ */ + diff --git a/drivers/misc/mediatek/connectivity/common/common_main/linux/include/wmt_user_proc.h b/drivers/misc/mediatek/connectivity/common/common_main/linux/include/wmt_user_proc.h new file mode 100644 index 0000000000000000000000000000000000000000..1bef0e0f78dddee4e3578fb37cbad800e04ffe9c --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/linux/include/wmt_user_proc.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#ifndef _WMT_USER_PROC_H_ +#define _WMT_USER_PROC_H_ +#include "osal.h" + +typedef INT32(*WMT_DEV_USER_PROC_FUNC) (INT32 par1, INT32 par2, INT32 par3); +INT32 wmt_dev_user_proc_setup(VOID); +INT32 wmt_dev_user_proc_remove(VOID); + +#endif /* _WMT_USER_PROC_H_ */ diff --git a/drivers/misc/mediatek/connectivity/common/common_main/linux/osal.c b/drivers/misc/mediatek/connectivity/common/common_main/linux/osal.c new file mode 100644 index 0000000000000000000000000000000000000000..0ef123a87492818c8d6413d27dafba34265cc92d --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/linux/osal.c @@ -0,0 +1,1823 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +/*! \file + * \brief Declaration of library functions + * Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. + */ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +#include "osal.h" +#include "connectivity_build_in_adapter.h" + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +#define GPIO_ASSERT 70 +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/* CRC table for the CRC-16. The poly is 0x8005 (x^16 + x^15 + x^2 + 1) */ +static UINT16 const crc16_table[256] = { + 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, + 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, + 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, + 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, + 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, + 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, + 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, + 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, + 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, + 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, + 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, + 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, + 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, + 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, + 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, + 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, + 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, + 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, + 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, + 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, + 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, + 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, + 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, + 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, + 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, + 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, + 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, + 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, + 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, + 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, + 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, + 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040 +}; + +INT32 ftrace_flag; +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +/*string operations*/ +UINT32 osal_strlen(const PINT8 str) +{ + return strlen(str); +} + +INT32 osal_strcmp(const PINT8 dst, const PINT8 src) +{ + return strcmp(dst, src); +} + +INT32 osal_strncmp(const PINT8 dst, const PINT8 src, UINT32 len) +{ + return strncmp(dst, src, len); +} + +PINT8 osal_strcpy(PINT8 dst, const PINT8 src) +{ + return strncpy(dst, src, strlen(src)+1); +} + +PINT8 osal_strncpy(PINT8 dst, const PINT8 src, UINT32 len) +{ + return strncpy(dst, src, len); +} + +PINT8 osal_strcat(PINT8 dst, const PINT8 src) +{ + return strncat(dst, src, strlen(src)); +} + +PINT8 osal_strncat(PINT8 dst, const PINT8 src, UINT32 len) +{ + return strncat(dst, src, len); +} + +PINT8 osal_strchr(const PINT8 str, UINT8 c) +{ + return strchr(str, c); +} + +PINT8 osal_strsep(PPINT8 str, const PINT8 c) +{ + return strsep(str, c); +} + +INT32 osal_strtol(const PINT8 str, UINT32 adecimal, PLONG res) +{ + if (sizeof(LONG) == 4) + return kstrtou32(str, adecimal, (UINT32 *) res); + else + return kstrtol(str, adecimal, res); +} + +PINT8 osal_strstr(PINT8 str1, const PINT8 str2) +{ + return strstr(str1, str2); +} + +PINT8 osal_strnstr(PINT8 str1, const PINT8 str2, INT32 n) +{ + return strnstr(str1, str2, n); +} + +VOID osal_bug_on(UINT32 val) +{ + WARN_ON(val); +} + +INT32 osal_snprintf(PINT8 buf, UINT32 len, const PINT8 fmt, ...) +{ + INT32 iRet = 0; + va_list args; + + va_start(args, fmt); + iRet = vsnprintf(buf, len, fmt, args); + va_end(args); + + if (iRet < 0) + pr_info("vsnprintf error:%d\n", iRet); + + return iRet; +} + +INT32 osal_err_print(const PINT8 str, ...) +{ + va_list args; + INT32 ret; + INT8 tempString[DBG_LOG_STR_SIZE]; + + va_start(args, str); + ret = vsnprintf(tempString, DBG_LOG_STR_SIZE, str, args); + va_end(args); + + if (ret > 0) + pr_err("%s", tempString); + + return ret; +} + +INT32 osal_dbg_print(const PINT8 str, ...) +{ + va_list args; + INT32 ret; + INT8 tempString[DBG_LOG_STR_SIZE]; + + va_start(args, str); + ret = vsnprintf(tempString, DBG_LOG_STR_SIZE, str, args); + va_end(args); + + if (ret > 0) + pr_debug("%s", tempString); + + return ret; +} + +INT32 osal_warn_print(const PINT8 str, ...) +{ + va_list args; + INT32 ret; + INT8 tempString[DBG_LOG_STR_SIZE]; + + va_start(args, str); + ret = vsnprintf(tempString, DBG_LOG_STR_SIZE, str, args); + va_end(args); + + if (ret > 0) + pr_warn("%s", tempString); + + return ret; +} + +INT32 osal_dbg_assert(INT32 expr, const PINT8 file, INT32 line) +{ + if (!expr) { + pr_warn("%s (%d)\n", file, line); + /*BUG_ON(!expr); */ +#ifdef CFG_COMMON_GPIO_DBG_PIN +/* package this part */ + gpio_direction_output(GPIO_ASSERT, 0); + pr_warn("toggle GPIO_ASSERT = %d\n", GPIO_ASSERT); + udelay(10); + gpio_set_value(GPIO_ASSERT, 1); +#endif + return 1; + } + return 0; + +} + +INT32 osal_dbg_assert_aee(const PINT8 module, const PINT8 detail_description, ...) +{ + INT8 tempString[DBG_LOG_STR_SIZE]; + va_list args; + + va_start(args, detail_description); + if (vsnprintf(tempString, DBG_LOG_STR_SIZE, detail_description, args) > 0) { + osal_err_print("[WMT-ASSERT][E][Module]:%s, [INFO]%s\n", module, tempString); +#ifdef WMT_PLAT_ALPS + /* There exists Format-String vulnerability. For safety, we must use the %s + * format parameter to read data. + */ +#if IS_ENABLED(CONFIG_MTK_AEE_AED) + aee_kernel_warning_api(__FILE__, __LINE__, DB_OPT_WCN_ISSUE_INFO, module, + detail_description, "%s", tempString); +#endif +#endif + } + va_end(args); + return 0; +} + +INT32 osal_sprintf(PINT8 str, const PINT8 format, ...) +{ + INT32 iRet = 0; + va_list args; + + va_start(args, format); + iRet = vsnprintf(str, DBG_LOG_STR_SIZE, format, args); + if (iRet < 0) + osal_err_print("vsnprintf error [%d]\n", iRet); + va_end(args); + + return iRet; +} + +PVOID osal_malloc(UINT32 size) +{ + PVOID p = NULL; + + if (size > (PAGE_SIZE << 1)) + p = vmalloc(size); + else + p = kmalloc(size, GFP_KERNEL); + + /* If there is fragment, kmalloc may not get memory when size > one page. + * For this case, use vmalloc instead. + */ + if (p == NULL && size > PAGE_SIZE) + p = vmalloc(size); + return p; +} + +VOID osal_free(const PVOID dst) +{ + kvfree(dst); +} + +PVOID osal_memset(PVOID buf, INT32 i, UINT32 len) +{ + return memset(buf, i, len); +} + +PVOID osal_memcpy(PVOID dst, const PVOID src, UINT32 len) +{ + return memcpy(dst, src, len); +} + +VOID osal_memcpy_fromio(PVOID dst, const PVOID src, UINT32 len) +{ + return memcpy_fromio(dst, src, len); +} + +VOID osal_memcpy_toio(PVOID dst, const PVOID src, UINT32 len) +{ + return memcpy_toio(dst, src, len); +} + +INT32 osal_memcmp(const PVOID buf1, const PVOID buf2, UINT32 len) +{ + return memcmp(buf1, buf2, len); +} + +UINT16 osal_crc16(const PUINT8 buffer, const UINT32 length) +{ + UINT16 crc = 0; + UINT32 i = 0; + PUINT8 temp = buffer; + + /* FIXME: Add STP checksum feature */ + crc = 0; + for (i = 0; i < length; i++, temp++) + crc = (crc >> 8) ^ crc16_table[(crc ^ (*temp)) & 0xff]; + return crc; +} + +VOID osal_dump_thread_state(const PUINT8 name) +{ +#if defined(KERNEL_dump_thread_state) + return KERNEL_dump_thread_state(name); +#endif +} + +VOID osal_thread_show_stack(P_OSAL_THREAD pThread) +{ + if ((pThread) && (pThread->pThread)) + KERNEL_show_stack(pThread->pThread, NULL); +} + +/* + *OSAL layer Thread Opeartion related APIs + * + * +*/ +INT32 osal_thread_create(P_OSAL_THREAD pThread) +{ + if (!pThread) + return -1; + + pThread->pThread = kthread_create(pThread->pThreadFunc, pThread->pThreadData, pThread->threadName); + if (pThread->pThread == NULL) + return -1; + + return 0; +} + +INT32 osal_thread_run(P_OSAL_THREAD pThread) +{ + if ((pThread) && (pThread->pThread)) { + wake_up_process(pThread->pThread); + return 0; + } else { + return -1; + } +} + +INT32 osal_thread_stop(P_OSAL_THREAD pThread) +{ + INT32 iRet; + + if ((pThread) && (pThread->pThread)) { + iRet = kthread_stop(pThread->pThread); + /* pThread->pThread = NULL; */ + return iRet; + } + return -1; +} + +INT32 osal_thread_should_stop(P_OSAL_THREAD pThread) +{ + if ((pThread) && (pThread->pThread)) + return kthread_should_stop(); + else + return 1; + +} + +INT32 osal_thread_wait_for_event(P_OSAL_THREAD pThread, P_OSAL_EVENT pEvent, P_OSAL_EVENT_CHECKER pChecker) +{ + /* P_DEV_WMT pDevWmt;*/ + + if ((pThread) && (pThread->pThread) && (pEvent) && (pChecker)) { + /* pDevWmt = (P_DEV_WMT)(pThread->pThreadData);*/ + return wait_event_interruptible(pEvent->waitQueue, (/*!RB_EMPTY(&pDevWmt->rActiveOpQ) || */ + osal_thread_should_stop(pThread) + || (*pChecker) (pThread))); + } + return -1; +} + +INT32 osal_thread_destroy(P_OSAL_THREAD pThread) +{ + if (pThread && (pThread->pThread)) { + kthread_stop(pThread->pThread); + pThread->pThread = NULL; + } + return 0; +} + +/* + * osal_thread_sched_retrieve + * Retrieve thread's current scheduling statistics and stored in output "sched". + * Return value: + * 0 : Schedstats successfully retrieved + * -1 : Kernel's schedstats feature not enabled + * -2 : pThread not yet initialized or sched is a NULL pointer + */ +static INT32 osal_thread_sched_retrieve(P_OSAL_THREAD pThread, P_OSAL_THREAD_SCHEDSTATS sched) +{ +#ifdef CONFIG_SCHEDSTATS + struct sched_entity se; + UINT64 sec; + ULONG usec; + + if (!sched) + return -2; + + /* always clear sched to simplify error handling at caller side */ + memset(sched, 0, sizeof(OSAL_THREAD_SCHEDSTATS)); + + if (!pThread || !pThread->pThread) + return -2; + + memcpy(&se, &pThread->pThread->se, sizeof(struct sched_entity)); + osal_get_local_time(&sec, &usec); + + sched->time = sec*1000 + usec/1000; + sched->exec = se.sum_exec_runtime; + sched->runnable = se.statistics.wait_sum; + sched->iowait = se.statistics.iowait_sum; + + return 0; +#else + /* always clear sched to simplify error handling at caller side */ + if (sched) + memset(sched, 0, sizeof(OSAL_THREAD_SCHEDSTATS)); + return -1; +#endif +} + +/* + * osal_thread_sched_mark + * Record the thread's current schedstats and stored in output "schedstats" parameter for profiling at later time. + * Return value: + * 0 : Schedstats successfully recorded + * -1 : Kernel's schedstats feature not enabled + * -2 : pThread not yet initialized or invalid parameters + */ +INT32 osal_thread_sched_mark(P_OSAL_THREAD pThread, P_OSAL_THREAD_SCHEDSTATS schedstats) +{ + return osal_thread_sched_retrieve(pThread, schedstats); +} + +/* + * osal_thread_sched_unmark + * Calculate scheduling statistics against the previously marked point. + * The result will be filled back into the schedstats output parameter. + * Return value: + * 0 : Schedstats successfully calculated + * -1 : Kernel's schedstats feature not enabled + * -2 : pThread not yet initialized or invalid parameters + */ +INT32 osal_thread_sched_unmark(P_OSAL_THREAD pThread, P_OSAL_THREAD_SCHEDSTATS schedstats) +{ + INT32 ret; + OSAL_THREAD_SCHEDSTATS sched_now; + + if (unlikely(!schedstats)) { + ret = -2; + } else { + ret = osal_thread_sched_retrieve(pThread, &sched_now); + if (ret == 0) { + schedstats->time = sched_now.time - schedstats->time; + schedstats->exec = sched_now.exec - schedstats->exec; + schedstats->runnable = sched_now.runnable - schedstats->runnable; + schedstats->iowait = sched_now.iowait - schedstats->iowait; + } + } + return ret; +} + +/* + *OSAL layer Signal Opeartion related APIs + *initialization + *wait for signal + *wait for signal timerout + *raise signal + *destroy a signal + * +*/ + +INT32 osal_signal_init(P_OSAL_SIGNAL pSignal) +{ + if (pSignal) { + init_completion(&pSignal->comp); + return 0; + } else { + return -1; + } +} + +INT32 osal_wait_for_signal(P_OSAL_SIGNAL pSignal) +{ + if (pSignal) { + wait_for_completion_interruptible(&pSignal->comp); + return 0; + } else { + return -1; + } +} + +/* + * osal_wait_for_signal_timeout + * + * Wait for a signal to be triggered by the corresponding thread, within the + * expected timeout specified by the signal's timeoutValue. + * When the pThread parameter is specified, the thread's scheduling ability is + * considered, the timeout will be extended when thread cannot acquire CPU + * resource, and will only extend for a number of times specified by the + * signal's timeoutExtension should the situation continues. + * + * Return value: + * 0 : timeout + * >0 : signal triggered + */ +INT32 osal_wait_for_signal_timeout(P_OSAL_SIGNAL pSignal, P_OSAL_THREAD pThread) +{ + OSAL_THREAD_SCHEDSTATS schedstats; + INT32 waitRet; + + /* return wait_for_completion_interruptible_timeout(&pSignal->comp, msecs_to_jiffies(pSignal->timeoutValue)); */ + /* [ChangeFeature][George] gps driver may be closed by -ERESTARTSYS. + * Avoid using *interruptible" version in order to complete our jobs, such + * as function off gracefully. + */ + if (!pThread || !pThread->pThread) + return wait_for_completion_timeout(&pSignal->comp, msecs_to_jiffies(pSignal->timeoutValue)); + + do { + osal_thread_sched_mark(pThread, &schedstats); + waitRet = wait_for_completion_timeout(&pSignal->comp, msecs_to_jiffies(pSignal->timeoutValue)); + osal_thread_sched_unmark(pThread, &schedstats); + + if (waitRet > 0) + break; + + if (schedstats.runnable > schedstats.exec) { + osal_err_print( + "[E]%s:wait completion timeout, %s cannot get CPU, extension(%d), show backtrace:\n", + __func__, + pThread->threadName, + pSignal->timeoutExtension); + } else { + osal_err_print("[E]%s:wait completion timeout, show %s backtrace:\n", + __func__, + pThread->threadName); + pSignal->timeoutExtension = 0; + } + osal_err_print("[E]%s:\tduration:%llums, sched(x%llu/r%llu/i%llu)\n", + __func__, + schedstats.time, + schedstats.exec, + schedstats.runnable, + schedstats.iowait); + /* + * no need to disginguish combo or A/D die projects + * osal_dump_thread_state will just return if target thread does not exist + */ + osal_dump_thread_state("mtk_wmtd"); + osal_dump_thread_state("mtk_wmtd_worker"); + osal_dump_thread_state("btif_rxd"); + osal_dump_thread_state("mtk_stp_psm"); + osal_dump_thread_state("mtk_stp_btm"); + osal_dump_thread_state("stp_sdio_tx_rx"); + } while (pSignal->timeoutExtension--); + return waitRet; +} + +INT32 osal_raise_signal(P_OSAL_SIGNAL pSignal) +{ + if (pSignal) { + complete(&pSignal->comp); + return 0; + } else + return -1; +} + +INT32 osal_signal_active_state(P_OSAL_SIGNAL pSignal) +{ + if (pSignal) + return pSignal->timeoutValue; + else + return -1; +} + +INT32 osal_signal_deinit(P_OSAL_SIGNAL pSignal) +{ + if (pSignal) { + pSignal->timeoutValue = 0; + return 0; + } else + return -1; +} + +/* + *OSAL layer Event Opeartion related APIs + *initialization + *wait for signal + *wait for signal timerout + *raise signal + *destroy a signal + * +*/ + +INT32 osal_event_init(P_OSAL_EVENT pEvent) +{ + if (pEvent) { + init_waitqueue_head(&pEvent->waitQueue); + return 0; + } + return -1; +} + +INT32 osal_trigger_event(P_OSAL_EVENT pEvent) +{ + INT32 ret = 0; + + if (pEvent) { + wake_up_interruptible(&pEvent->waitQueue); + return ret; + } + return -1; +} + +INT32 osal_wait_for_event(P_OSAL_EVENT pEvent, INT32(*condition) (PVOID), PVOID cond_pa) +{ + if (pEvent) + return wait_event_interruptible(pEvent->waitQueue, condition(cond_pa)); + else + return -1; +} + +INT32 osal_wait_for_event_timeout(P_OSAL_EVENT pEvent, INT32(*condition) (PVOID), PVOID cond_pa) +{ + if (pEvent) + return wait_event_interruptible_timeout(pEvent->waitQueue, + condition(cond_pa), + msecs_to_jiffies(pEvent->timeoutValue)); + return -1; +} + + + +INT32 osal_event_deinit(P_OSAL_EVENT pEvent) +{ + return 0; +} + +LONG osal_wait_for_event_bit_set(P_OSAL_EVENT pEvent, PULONG pState, UINT32 bitOffset) +{ + UINT32 ms = 0; + + if (pEvent) { + ms = pEvent->timeoutValue; + if (ms != 0) + return wait_event_interruptible_timeout(pEvent->waitQueue, + test_bit(bitOffset, pState), + msecs_to_jiffies(ms)); + else + return wait_event_interruptible(pEvent->waitQueue, + test_bit(bitOffset, pState)); + } else + return -1; + +} + +LONG osal_wait_for_event_bit_clr(P_OSAL_EVENT pEvent, PULONG pState, UINT32 bitOffset) +{ + UINT32 ms = 0; + + if (pEvent) { + ms = pEvent->timeoutValue; + if (ms != 0) + return wait_event_interruptible_timeout(pEvent->waitQueue, + !test_bit(bitOffset, pState), + msecs_to_jiffies(ms)); + else + return wait_event_interruptible(pEvent->waitQueue, + !test_bit(bitOffset, pState)); + } else + return -1; +} + +/* + *bit test and set/clear operations APIs + * + * +*/ +#if OS_BIT_OPS_SUPPORT +#define osal_bit_op_lock(x) +#define osal_bit_op_unlock(x) +#else + +INT32 osal_bit_op_lock(P_OSAL_UNSLEEPABLE_LOCK pLock) +{ + + return 0; +} + +INT32 osal_bit_op_unlock(P_OSAL_UNSLEEPABLE_LOCK pLock) +{ + + return 0; +} +#endif +INT32 osal_clear_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData) +{ + if (bitOffset >= BITS_PER_LONG) { + pr_info("bitOffset(%d) is out of range.\n", bitOffset); + return -1; + } + osal_bit_op_lock(&(pData->opLock)); + clear_bit(bitOffset, &pData->data); + osal_bit_op_unlock(&(pData->opLock)); + return 0; +} + +INT32 osal_set_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData) +{ + if (bitOffset >= BITS_PER_LONG) { + pr_info("bitOffset(%d) is out of range.\n", bitOffset); + return -1; + } + osal_bit_op_lock(&(pData->opLock)); + set_bit(bitOffset, &pData->data); + osal_bit_op_unlock(&(pData->opLock)); + return 0; +} + +INT32 osal_test_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData) +{ + UINT32 iRet = 0; + + if (bitOffset >= BITS_PER_LONG) { + pr_info("bitOffset(%d) is out of range.\n", bitOffset); + return -1; + } + osal_bit_op_lock(&(pData->opLock)); + iRet = test_bit(bitOffset, &pData->data); + osal_bit_op_unlock(&(pData->opLock)); + return iRet; +} + +INT32 osal_test_and_clear_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData) +{ + UINT32 iRet = 0; + + if (bitOffset >= BITS_PER_LONG) { + pr_info("bitOffset(%d) is out of range.\n", bitOffset); + return -1; + } + osal_bit_op_lock(&(pData->opLock)); + iRet = test_and_clear_bit(bitOffset, &pData->data); + osal_bit_op_unlock(&(pData->opLock)); + return iRet; + +} + +INT32 osal_test_and_set_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData) +{ + UINT32 iRet = 0; + + if (bitOffset >= BITS_PER_LONG) { + pr_info("bitOffset(%d) is out of range.\n", bitOffset); + return -1; + } + osal_bit_op_lock(&(pData->opLock)); + iRet = test_and_set_bit(bitOffset, &pData->data); + osal_bit_op_unlock(&(pData->opLock)); + return iRet; +} + +/* + *tiemr operations APIs + *create + *stop + * modify + *create + *delete + * +*/ + +INT32 osal_timer_create(P_OSAL_TIMER pTimer) +{ + struct timer_list *timer = &pTimer->timer; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) + timer_setup(timer, pTimer->timeoutHandler, 0); +#else + init_timer(timer); + timer->function = pTimer->timeoutHandler; + timer->data = (ULONG)pTimer->timeroutHandlerData; +#endif + return 0; +} + +INT32 osal_timer_start(P_OSAL_TIMER pTimer, UINT32 ms) +{ + + struct timer_list *timer = &pTimer->timer; + + timer->expires = jiffies + (ms / (1000 / HZ)); + add_timer(timer); + return 0; +} + +INT32 osal_timer_stop(P_OSAL_TIMER pTimer) +{ + struct timer_list *timer = &pTimer->timer; + + del_timer(timer); + return 0; +} + +INT32 osal_timer_stop_sync(P_OSAL_TIMER pTimer) +{ + struct timer_list *timer = &pTimer->timer; + + del_timer_sync(timer); + return 0; +} + +INT32 osal_timer_modify(P_OSAL_TIMER pTimer, UINT32 ms) +{ + + mod_timer(&pTimer->timer, jiffies + (ms) / (1000 / HZ)); + return 0; +} + +INT32 _osal_fifo_init(OSAL_FIFO *pFifo, PUINT8 buf, UINT32 size) +{ + struct kfifo *fifo = NULL; + INT32 ret = -1; + + if (!pFifo) { + pr_err("pFifo must be !NULL\n"); + return -1; + } + if (pFifo->pFifoBody) { + pr_err("pFifo->pFifoBody must be NULL\n"); + pr_err("pFifo(0x%p), pFifo->pFifoBody(0x%p)\n", pFifo, pFifo->pFifoBody); + return -1; + } + fifo = kzalloc(sizeof(struct kfifo), GFP_ATOMIC); + if (!buf) { + /*fifo's buffer is not ready, we allocate automatically */ + ret = kfifo_alloc(fifo, size, /*GFP_KERNEL */ GFP_ATOMIC); + } else { + if (is_power_of_2(size)) { + kfifo_init(fifo, buf, size); + ret = 0; + } else { + kfifo_free(fifo); + fifo = NULL; + ret = -1; + } + } + + pFifo->pFifoBody = fifo; + return (ret < 0) ? (-1) : (0); +} + +INT32 _osal_fifo_deinit(OSAL_FIFO *pFifo) +{ + struct kfifo *fifo = NULL; + + if (!pFifo || !pFifo->pFifoBody) { + pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); + return -1; + } + + fifo = (struct kfifo *)pFifo->pFifoBody; + + if (fifo) + kfifo_free(fifo); + + return 0; +} + +INT32 _osal_fifo_size(OSAL_FIFO *pFifo) +{ + struct kfifo *fifo = NULL; + INT32 ret = 0; + + if (!pFifo || !pFifo->pFifoBody) { + pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); + return -1; + } + + fifo = (struct kfifo *)pFifo->pFifoBody; + + if (fifo) + ret = kfifo_size(fifo); + + return ret; +} + +/*returns unused bytes in fifo*/ +INT32 _osal_fifo_avail_size(OSAL_FIFO *pFifo) +{ + struct kfifo *fifo = NULL; + INT32 ret = 0; + + if (!pFifo || !pFifo->pFifoBody) { + pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); + return -1; + } + + fifo = (struct kfifo *)pFifo->pFifoBody; + + if (fifo) + ret = kfifo_avail(fifo); + + return ret; +} + +/*returns used bytes in fifo*/ +INT32 _osal_fifo_len(OSAL_FIFO *pFifo) +{ + struct kfifo *fifo = NULL; + INT32 ret = 0; + + if (!pFifo || !pFifo->pFifoBody) { + pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); + return -1; + } + + fifo = (struct kfifo *)pFifo->pFifoBody; + + if (fifo) + ret = kfifo_len(fifo); + + return ret; +} + +INT32 _osal_fifo_is_empty(OSAL_FIFO *pFifo) +{ + struct kfifo *fifo = NULL; + INT32 ret = 0; + + if (!pFifo || !pFifo->pFifoBody) { + pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); + return -1; + } + + fifo = (struct kfifo *)pFifo->pFifoBody; + + if (fifo) + ret = kfifo_is_empty(fifo); + + return ret; +} + +INT32 _osal_fifo_is_full(OSAL_FIFO *pFifo) +{ + struct kfifo *fifo = NULL; + INT32 ret = 0; + + if (!pFifo || !pFifo->pFifoBody) { + pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); + return -1; + } + + fifo = (struct kfifo *)pFifo->pFifoBody; + + if (fifo) + ret = kfifo_is_full(fifo); + + return ret; +} + +INT32 _osal_fifo_data_in(OSAL_FIFO *pFifo, const PVOID buf, UINT32 len) +{ + struct kfifo *fifo = NULL; + INT32 ret = 0; + + if (!pFifo || !pFifo->pFifoBody) { + pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); + return -1; + } + + fifo = (struct kfifo *)pFifo->pFifoBody; + + if (fifo && buf && (len <= _osal_fifo_avail_size(pFifo))) { + ret = kfifo_in(fifo, buf, len); + } else { + pr_err("%s: kfifo_in, error, len = %d, _osal_fifo_avail_size = %d, buf=%p\n", + __func__, len, _osal_fifo_avail_size(pFifo), buf); + + ret = 0; + } + + return ret; +} + +INT32 _osal_fifo_data_out(OSAL_FIFO *pFifo, PVOID buf, UINT32 len) +{ + struct kfifo *fifo = NULL; + INT32 ret = 0; + + if (!pFifo || !pFifo->pFifoBody) { + pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); + return -1; + } + + fifo = (struct kfifo *)pFifo->pFifoBody; + + if (fifo && buf && (len <= _osal_fifo_len(pFifo))) { + ret = kfifo_out(fifo, buf, len); + } else { + pr_err("%s: kfifo_out, error, len = %d, osal_fifo_len = %d, buf=%p\n", + __func__, len, _osal_fifo_len(pFifo), buf); + + ret = 0; + } + + return ret; +} + +INT32 _osal_fifo_reset(OSAL_FIFO *pFifo) +{ + struct kfifo *fifo = NULL; + + if (!pFifo || !pFifo->pFifoBody) { + pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); + return -1; + } + + fifo = (struct kfifo *)pFifo->pFifoBody; + + if (fifo) + kfifo_reset(fifo); + + return 0; +} + +INT32 osal_fifo_init(P_OSAL_FIFO pFifo, UINT8 *buffer, UINT32 size) +{ + if (!pFifo) { + pr_err("%s:pFifo = NULL, error\n", __func__); + return -1; + } + + pFifo->FifoInit = _osal_fifo_init; + pFifo->FifoDeInit = _osal_fifo_deinit; + pFifo->FifoSz = _osal_fifo_size; + pFifo->FifoAvailSz = _osal_fifo_avail_size; + pFifo->FifoLen = _osal_fifo_len; + pFifo->FifoIsEmpty = _osal_fifo_is_empty; + pFifo->FifoIsFull = _osal_fifo_is_full; + pFifo->FifoDataIn = _osal_fifo_data_in; + pFifo->FifoDataOut = _osal_fifo_data_out; + pFifo->FifoReset = _osal_fifo_reset; + + if (pFifo->pFifoBody != NULL) { + pr_err("%s:Because pFifo room is avialable, we clear the room and allocate them again.\n", __func__); + pFifo->FifoDeInit(pFifo); + pFifo->pFifoBody = NULL; + } + + pFifo->FifoInit(pFifo, buffer, size); + + return 0; +} + +VOID osal_fifo_deinit(P_OSAL_FIFO pFifo) +{ + if (pFifo) + pFifo->FifoDeInit(pFifo); + else { + pr_err("%s:pFifo = NULL, error\n", __func__); + return; + } + kfree(pFifo->pFifoBody); + pFifo->pFifoBody = NULL; +} + +INT32 osal_fifo_reset(P_OSAL_FIFO pFifo) +{ + INT32 ret = -1; + + if (pFifo) { + ret = pFifo->FifoReset(pFifo); + } else { + pr_err("%s:pFifo = NULL, error\n", __func__); + ret = -1; + } + return ret; +} + +UINT32 osal_fifo_in(P_OSAL_FIFO pFifo, PUINT8 buffer, UINT32 size) +{ + UINT32 ret = 0; + + if (pFifo) { + ret = pFifo->FifoDataIn(pFifo, buffer, size); + } else { + pr_err("%s:pFifo = NULL, error\n", __func__); + ret = 0; + } + + return ret; +} + +UINT32 osal_fifo_out(P_OSAL_FIFO pFifo, PUINT8 buffer, UINT32 size) +{ + UINT32 ret = 0; + + if (pFifo) { + ret = pFifo->FifoDataOut(pFifo, buffer, size); + } else { + pr_err("%s:pFifo = NULL, error\n", __func__); + ret = 0; + } + + return ret; +} + +UINT32 osal_fifo_len(P_OSAL_FIFO pFifo) +{ + UINT32 ret = 0; + + if (pFifo) { + ret = pFifo->FifoLen(pFifo); + } else { + pr_err("%s:pFifo = NULL, error\n", __func__); + ret = 0; + } + + return ret; +} + +UINT32 osal_fifo_sz(P_OSAL_FIFO pFifo) +{ + UINT32 ret = 0; + + if (pFifo) { + ret = pFifo->FifoSz(pFifo); + } else { + pr_err("%s:pFifo = NULL, error\n", __func__); + ret = 0; + } + + return ret; +} + +UINT32 osal_fifo_avail(P_OSAL_FIFO pFifo) +{ + UINT32 ret = 0; + + if (pFifo) { + ret = pFifo->FifoAvailSz(pFifo); + } else { + pr_err("%s:pFifo = NULL, error\n", __func__); + ret = 0; + } + + return ret; +} + +UINT32 osal_fifo_is_empty(P_OSAL_FIFO pFifo) +{ + UINT32 ret = 0; + + if (pFifo) { + ret = pFifo->FifoIsEmpty(pFifo); + } else { + pr_err("%s:pFifo = NULL, error\n", __func__); + ret = 0; + } + + return ret; +} + +UINT32 osal_fifo_is_full(P_OSAL_FIFO pFifo) +{ + UINT32 ret = 0; + + if (pFifo) { + ret = pFifo->FifoIsFull(pFifo); + } else { + pr_err("%s:pFifo = NULL, error\n", __func__); + ret = 0; + } + return ret; +} + +INT32 osal_wake_lock_init(P_OSAL_WAKE_LOCK pLock) +{ + if (!pLock) + return -1; + + if (pLock->init_flag == 0) { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 149)) + pLock->wake_lock = wakeup_source_register(NULL, pLock->name); +#else + pLock->wake_lock = wakeup_source_register(pLock->name); +#endif + pLock->init_flag = 1; + } + + return 0; +} + +INT32 osal_wake_lock_deinit(P_OSAL_WAKE_LOCK pLock) +{ + if (!pLock) + return -1; + + if (pLock->init_flag == 1) { + wakeup_source_unregister(pLock->wake_lock); + pLock->init_flag = 0; + } else + pr_info("%s: wake_lock is not initialized!\n", __func__); + + return 0; +} + +INT32 osal_wake_lock(P_OSAL_WAKE_LOCK pLock) +{ + if (!pLock) + return -1; + + if (pLock->init_flag == 1) + __pm_stay_awake(pLock->wake_lock); + else + pr_info("%s: wake_lock is not initialized!\n", __func__); + + return 0; +} + +INT32 osal_wake_unlock(P_OSAL_WAKE_LOCK pLock) +{ + if (!pLock) + return -1; + + if (pLock->init_flag == 1) + __pm_relax(pLock->wake_lock); + else + pr_info("%s: wake_lock is not initialized!\n", __func__); + + return 0; + +} + +INT32 osal_wake_lock_count(P_OSAL_WAKE_LOCK pLock) +{ + INT32 count = 0; + + if (!pLock) + return -1; + + if (pLock->init_flag == 1) + count = pLock->wake_lock->active; + else + pr_info("%s: wake_lock is not initialized!\n", __func__); + + return count; +} + +/* + *sleepable lock operations APIs + *init + *lock + *unlock + *destroy + * +*/ + +#if !defined(CONFIG_PROVE_LOCKING) +INT32 osal_unsleepable_lock_init(P_OSAL_UNSLEEPABLE_LOCK pUSL) +{ + spin_lock_init(&(pUSL->lock)); + return 0; +} +#endif + +INT32 osal_lock_unsleepable_lock(P_OSAL_UNSLEEPABLE_LOCK pUSL) +{ + spin_lock_irqsave(&(pUSL->lock), pUSL->flag); + return 0; +} + +INT32 osal_unlock_unsleepable_lock(P_OSAL_UNSLEEPABLE_LOCK pUSL) +{ + spin_unlock_irqrestore(&(pUSL->lock), pUSL->flag); + return 0; +} + +INT32 osal_trylock_unsleepable_lock(P_OSAL_UNSLEEPABLE_LOCK pUSL) +{ + return spin_trylock_irqsave(&(pUSL->lock), pUSL->flag); +} + +INT32 osal_unsleepable_lock_deinit(P_OSAL_UNSLEEPABLE_LOCK pUSL) +{ + return 0; +} + +/* + *unsleepable operations APIs + *init + *lock + *unlock + *destroy + + * +*/ + +#if !defined(CONFIG_PROVE_LOCKING) +INT32 osal_sleepable_lock_init(P_OSAL_SLEEPABLE_LOCK pSL) +{ + mutex_init(&pSL->lock); + return 0; +} +#endif + +INT32 osal_lock_sleepable_lock(P_OSAL_SLEEPABLE_LOCK pSL) +{ + return mutex_lock_killable(&pSL->lock); +} + +INT32 osal_unlock_sleepable_lock(P_OSAL_SLEEPABLE_LOCK pSL) +{ + mutex_unlock(&pSL->lock); + return 0; +} + +INT32 osal_trylock_sleepable_lock(P_OSAL_SLEEPABLE_LOCK pSL) +{ + return mutex_trylock(&pSL->lock); +} + +INT32 osal_sleepable_lock_deinit(P_OSAL_SLEEPABLE_LOCK pSL) +{ + mutex_destroy(&pSL->lock); + return 0; +} + +INT32 osal_sleep_ms(UINT32 ms) +{ + msleep(ms); + return 0; +} + +INT32 osal_udelay(UINT32 us) +{ + udelay(us); + return 0; +} + +INT32 osal_usleep_range(ULONG min, ULONG max) +{ + usleep_range(min, max); + return 0; +} + +INT32 osal_gettimeofday(PINT32 sec, PINT32 usec) +{ + INT32 ret = 0; + struct timeval now; + + osal_do_gettimeofday(&now); + + if (sec != NULL) + *sec = now.tv_sec; + else + ret = -1; + + if (usec != NULL) + *usec = now.tv_usec; + else + ret = -1; + + return ret; +} + +void osal_do_gettimeofday(struct timeval *tv) +{ + struct timespec64 now; + + ktime_get_real_ts64(&now); + tv->tv_sec = now.tv_sec; + tv->tv_usec = now.tv_nsec / NSEC_PER_USEC; +} + +INT32 osal_printtimeofday(const PUINT8 prefix) +{ + INT32 ret; + INT32 sec; + INT32 usec; + + ret = osal_gettimeofday(&sec, &usec); + ret += osal_dbg_print("%s>sec=%d, usec=%d\n", prefix, sec, usec); + + return ret; +} + +VOID osal_get_local_time(PUINT64 sec, PULONG nsec) +{ + if (sec != NULL && nsec != NULL) { + *sec = local_clock(); + *nsec = do_div(*sec, 1000000000)/1000; + } else + pr_err("The input parameters error when get local time\n"); +} + +UINT64 osal_elapsed_us(UINT64 ts, ULONG usec) +{ + UINT64 current_ts = 0; + ULONG current_usec = 0; + + osal_get_local_time(¤t_ts, ¤t_usec); + return (current_ts*1000000 + current_usec) - (ts*1000000 + usec); +} + +VOID osal_buffer_dump(const PUINT8 buf, const PUINT8 title, const UINT32 len, const UINT32 limit) +{ + INT32 k; + UINT32 dump_len; + char str[DBG_LOG_STR_SIZE] = {""}; + INT32 strlen = 0; + char *p = NULL; + + pr_info("[%s] len=%d, limit=%d, start dump\n", title, len, limit); + + dump_len = ((limit != 0) && (len > limit)) ? limit : len; + p = str; + for (k = 0; k < dump_len; k++) { + if ((k+1) % 16 != 0) { + strlen = osal_sprintf(p, "%02x ", buf[k]); + p += strlen; + } else { + strlen = osal_sprintf(p, "%02x\n", buf[k]); + pr_info("%s", str); + p = str; + } + } + if (k % 16 != 0) + pr_info("%s\n", str); + + pr_info("end of dump\n"); +} + +VOID osal_buffer_dump_data(const PUINT32 buf, const PUINT8 title, const UINT32 len, const UINT32 limit, + const INT32 flag) +{ + INT32 k; + UINT32 dump_len; + char str[DBG_LOG_STR_SIZE] = {""}; + INT32 strlen = 0; + char *p = NULL; + INT32 count = 0; + + dump_len = ((limit != 0) && (len > limit)) ? limit : len; + p = str; + for (k = 0; k < dump_len; k++) { + count++; + if (count % 8 != 0) { + strlen = osal_sprintf(p, "0x%08x,", buf[k]); + p += strlen; + } else { + strlen = osal_sprintf(p, "0x%08x\n", buf[k]); + if (flag) + osal_ftrace_print("%s%s", title, str); + else + pr_info("%s%s", title, str); + p = str; + } + } + if (count % 8 != 0) { + if (flag) + osal_ftrace_print("%s%s\n", title, str); + else + pr_info("%s%s\n", title, str); + } +} + +UINT32 osal_op_get_id(P_OSAL_OP pOp) +{ + return (pOp) ? pOp->op.opId : 0xFFFFFFFF; +} + +MTK_WCN_BOOL osal_op_is_wait_for_signal(P_OSAL_OP pOp) +{ + return (pOp && pOp->signal.timeoutValue) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE; +} + +VOID osal_op_raise_signal(P_OSAL_OP pOp, INT32 result) +{ + if (pOp) { + pOp->result = result; + osal_raise_signal(&pOp->signal); + } +} + +INT32 osal_ftrace_print(const PINT8 str, ...) +{ + int ret = 0; +#ifdef CONFIG_TRACING + va_list args; + INT8 tempString[DBG_LOG_STR_SIZE]; + + if (ftrace_flag) { + va_start(args, str); + ret = vsnprintf(tempString, DBG_LOG_STR_SIZE, str, args); + va_end(args); + + if (ret > 0) + trace_printk("%s\n", tempString); + } +#endif + return ret; +} + +INT32 osal_ftrace_print_ctrl(INT32 flag) +{ +#ifdef CONFIG_TRACING + if (flag) + ftrace_flag = 1; + else + ftrace_flag = 0; +#endif + return 0; +} + +VOID osal_set_op_result(P_OSAL_OP pOp, INT32 result) +{ + if (pOp) + pOp->result = result; + +} + +static VOID _osal_opq_dump(const char *qName, P_OSAL_OP_Q pOpQ) +{ + /* Line format: + * [LogicalIdx(PhysicalIdx)]Address:OpId(Ref)(Result)-Info-OpData0,OpData1,OpData2,OpData3,OpData5_ + * [LogicalIdx] max 10+2=12 chars (decimal) + * (PhysicalIdx) max 10+2=12 chars (decimal) + * Address: max 16+1=17 chars (hex) + * OpId max 10 chars (decimal) + * (Ref) max 2+2=4 chars (should only be 1 digit, reserve 2 in case of negative number) + * (Result) max 11+2=13 chars (signed decimal) + * -Info- max 8+2=10 chars (hex) + * OpData, max 16+1=17 chars (hex) + */ +#define OPQ_DUMP_OP_PER_LINE 1 +#define OPQ_DUMP_OPDATA_PER_OP 6 +#define OPQ_DUMP_OP_BUF_SIZE (12 + 12 + 17 + 10 + 4 + 13 + 10 + (17 * (OPQ_DUMP_OPDATA_PER_OP)) + 1) +#define OPQ_DUMP_LINE_BUF_SIZE ((OPQ_DUMP_OP_BUF_SIZE * OPQ_DUMP_OP_PER_LINE) + 1) + UINT32 rd; + UINT32 wt; + UINT32 idx = 0; + UINT32 opDataIdx; + UINT32 idxInBuf; + int printed; + P_OSAL_OP op; + char buf[OPQ_DUMP_LINE_BUF_SIZE]; + + rd = pOpQ->read; + wt = pOpQ->write; + + pr_info("%s(%p), sz:%u/%u, rd:%u, wt:%u\n", qName, pOpQ, RB_COUNT(pOpQ), RB_SIZE(pOpQ), rd, wt); + while (rd != wt && idx < RB_SIZE(pOpQ)) { + idxInBuf = idx % OPQ_DUMP_OP_PER_LINE; + op = pOpQ->queue[rd & RB_MASK(pOpQ)]; + + if (idxInBuf == 0) { + printed = 0; + buf[0] = 0; + } + + if (op) { + printed += snprintf(buf + printed, OPQ_DUMP_LINE_BUF_SIZE - printed, + "[%u(%u)]%p:%u(%d)(%d)-%u-", + idx, + (rd & RB_MASK(pOpQ)), + op, + op->op.opId, + atomic_read(&op->ref_count), + op->result, + op->op.u4InfoBit); + for (opDataIdx = 0; opDataIdx < OPQ_DUMP_OPDATA_PER_OP; opDataIdx++) + printed += snprintf(buf + printed, OPQ_DUMP_LINE_BUF_SIZE - printed, + "%zx,", op->op.au4OpData[opDataIdx]); + if (printed > 0) + buf[printed-1] = ' '; + } else { + printed += snprintf(buf + printed, OPQ_DUMP_LINE_BUF_SIZE - printed, + "[%u(%u)]%p ", idx, (rd & RB_MASK(pOpQ)), op); + } + if (printed < 1 || printed >= (sizeof(buf) - 1)) + return; + + buf[printed++] = ' '; + + if (idxInBuf == OPQ_DUMP_OP_PER_LINE - 1 || rd == wt - 1) { + buf[printed - 1] = 0; + pr_info("%s\n", buf); + } + rd++; + idx++; + } +} + +VOID osal_opq_dump(const char *qName, P_OSAL_OP_Q pOpQ) +{ + int err; + + err = osal_lock_sleepable_lock(&pOpQ->sLock); + if (err) { + pr_info("Failed to lock queue (%d)\n", err); + return; + } + + _osal_opq_dump(qName, pOpQ); + + osal_unlock_sleepable_lock(&pOpQ->sLock); +} + +VOID osal_opq_dump_locked(const char *qName, P_OSAL_OP_Q pOpQ) +{ + _osal_opq_dump(qName, pOpQ); +} + +MTK_WCN_BOOL osal_opq_has_op(P_OSAL_OP_Q pOpQ, P_OSAL_OP pOp) +{ + UINT32 rd; + UINT32 wt; + P_OSAL_OP op; + + rd = pOpQ->read; + wt = pOpQ->write; + + while (rd != wt) { + op = pOpQ->queue[rd & RB_MASK(pOpQ)]; + if (op == pOp) + return MTK_WCN_BOOL_TRUE; + rd++; + } + return MTK_WCN_BOOL_FALSE; +} + +static VOID osal_op_history_print_work(struct work_struct *work) +{ + struct osal_op_history *log_history = container_of(work, struct osal_op_history, dump_work); + struct ring *ring_buffer = &log_history->dump_ring_buffer; + struct ring_segment seg; + struct osal_op_history_entry *queue = ring_buffer->base; + struct osal_op_history_entry *entry = NULL; + INT32 index = 0; + + if (queue == NULL) { + pr_info("queue shouldn't be NULL, %s", log_history->name); + return; + } + + RING_READ_FOR_EACH_ITEM(RING_SIZE(ring_buffer), seg, ring_buffer) { + index = seg.ring_pt - ring_buffer->base; + entry = &queue[index]; + pr_info("(%llu.%06lu) %s: pOp(%p):%u(%d)-%x-%zx,%zx,%zx,%zx\n", + entry->ts, + entry->usec, + log_history->name, + entry->opbuf_address, + entry->op_id, + entry->opbuf_ref_count, + entry->op_info_bit, + entry->param_0, + entry->param_1, + entry->param_2, + entry->param_3); + } + kfree(queue); + ring_buffer->base = NULL; +} + +VOID osal_op_history_init(struct osal_op_history *log_history, INT32 queue_size) +{ + int size = queue_size * sizeof(struct osal_op_history_entry); + + spin_lock_init(&(log_history->lock)); + + log_history->queue = kzalloc(size, GFP_ATOMIC); + if (log_history->queue == NULL) + return; + + /* queue_size must be power of 2 */ + ring_init( + &log_history->queue, + queue_size, + 0, + 0, + &log_history->ring_buffer); + + INIT_WORK(&log_history->dump_work, osal_op_history_print_work); +} + +VOID osal_op_history_print(struct osal_op_history *log_history, PINT8 name) +{ + struct osal_op_history_entry *queue = NULL; + struct ring *ring_buffer = NULL, *dump_ring_buffer = NULL; + INT32 queue_size; + ULONG flags; + struct work_struct *work = &log_history->dump_work; + spinlock_t *lock = &(log_history->lock); + + if (log_history->queue == NULL) { + pr_info("Queue is NULL, name: %s\n", name); + return; + } + + spin_lock_irqsave(lock, flags); + ring_buffer = &log_history->ring_buffer; + queue_size = sizeof(struct osal_op_history_entry) + * RING_SIZE(ring_buffer); + + /* Allocate memory before getting lock to save time of holding lock */ + queue = kmalloc(queue_size, GFP_ATOMIC); + if (queue == NULL) { + spin_unlock_irqrestore(lock, flags); + return; + } + dump_ring_buffer = &log_history->dump_ring_buffer; + + if (dump_ring_buffer->base != NULL) { + spin_unlock_irqrestore(lock, flags); + kfree(queue); + pr_info("print is ongoing: %s\n", name); + return; + } + + osal_snprintf(log_history->name, sizeof(log_history->name), "%s", name); + osal_memcpy(queue, log_history->queue, queue_size); + osal_memcpy(dump_ring_buffer, ring_buffer, sizeof(struct ring)); + /* assign value to base after memory copy */ + dump_ring_buffer->base = queue; + spin_unlock_irqrestore(lock, flags); + schedule_work(work); +} + +VOID osal_op_history_save(struct osal_op_history *log_history, P_OSAL_OP pOp) +{ + struct osal_op_history_entry *entry = NULL; + struct ring_segment seg; + INT32 index; + UINT64 sec = 0; + ULONG usec = 0; + ULONG flags; + + if (log_history->queue == NULL) + return; + + osal_get_local_time(&sec, &usec); + + spin_lock_irqsave(&(log_history->lock), flags); + RING_OVERWRITE_FOR_EACH(1, seg, &log_history->ring_buffer) { + index = seg.ring_pt - log_history->ring_buffer.base; + entry = &log_history->queue[index]; + } + + if (entry == NULL) { + pr_info("Entry is null, size %d\n", RING_SIZE(&log_history->ring_buffer)); + spin_unlock_irqrestore(&(log_history->lock), flags); + return; + } + + entry->opbuf_address = pOp; + entry->op_id = pOp->op.opId; + entry->opbuf_ref_count = atomic_read(&pOp->ref_count); + entry->op_info_bit = pOp->op.u4InfoBit; + entry->param_0 = pOp->op.au4OpData[0]; + entry->param_1 = pOp->op.au4OpData[1]; + entry->param_2 = pOp->op.au4OpData[2]; + entry->param_3 = pOp->op.au4OpData[3]; + entry->ts = sec; + entry->usec = usec; + spin_unlock_irqrestore(&(log_history->lock), flags); +} diff --git a/drivers/misc/mediatek/connectivity/common/common_main/linux/stp_btif.c b/drivers/misc/mediatek/connectivity/common/common_main/linux/stp_btif.c new file mode 100644 index 0000000000000000000000000000000000000000..3d26156b878f6d765ff3b7ded0afd133ccee4990 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/linux/stp_btif.c @@ -0,0 +1,304 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +/*file: stp_btif, mainly control stp & btif interaction*/ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +#ifdef DFT_TAG +#undef DFT_TAG +#endif +#define DFT_TAG "[STP-BTIF]" + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include "osal_typedef.h" +#include "wmt_exp.h" +#include "stp_exp.h" +#include "stp_btif.h" + +#include +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ +#define BTIF_OWNER_NAME "CONSYS_STP" + +#define STP_MAX_PACKAGE_ALLOWED (2000) + +#define STP_BTIF_TX_RTY_LMT (10) +#define STP_BTIF_TX_RTY_DLY (5) +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ +struct stp_btif g_stp_btif; +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +INT32 mtk_wcn_consys_stp_btif_open(VOID) +{ + INT32 iRet = -1; + P_OSAL_THREAD thread = &g_stp_btif.btif_thread; + + iRet = mtk_wcn_btif_open(BTIF_OWNER_NAME, &g_stp_btif.stpBtifId); + if (iRet) { + WMT_WARN_FUNC("STP open btif fail(%d)\n", iRet); + return -1; + } + WMT_DBG_FUNC("STP open bitf OK\n"); + + thread->pThread = mtk_btif_exp_rx_thread_get(g_stp_btif.stpBtifId); + if (!thread->pThread) { + WMT_INFO_FUNC("thread->pThread is NULL\n"); + return -1; + } + + osal_strncpy(thread->threadName, thread->pThread->comm, sizeof(thread->pThread->comm)); + mtk_wcn_stp_register_if_tx(STP_BTIF_IF_TX, (MTK_WCN_STP_IF_TX) mtk_wcn_consys_stp_btif_tx); + mtk_wcn_stp_register_rx_has_pending_data(STP_BTIF_IF_TX, + (MTK_WCN_STP_RX_HAS_PENDING_DATA) mtk_wcn_consys_stp_btif_rx_has_pending_data); + mtk_wcn_stp_register_tx_has_pending_data(STP_BTIF_IF_TX, + (MTK_WCN_STP_TX_HAS_PENDING_DATA) mtk_wcn_consys_stp_btif_tx_has_pending_data); + mtk_wcn_stp_register_rx_thread_get(STP_BTIF_IF_TX, + (MTK_WCN_STP_RX_THREAD_GET) mtk_wcn_consys_stp_btif_rx_thread_get); + + return 0; +} + +INT32 mtk_wcn_consys_stp_btif_close(VOID) +{ + INT32 iRet = 0; + + if (!g_stp_btif.stpBtifId) + WMT_WARN_FUNC("NULL BTIF ID reference!\n"); + else { + iRet = mtk_wcn_btif_close(g_stp_btif.stpBtifId); + if (iRet) { + WMT_WARN_FUNC("STP close btif fail(%d)\n", iRet); + iRet = -2; + } else { + g_stp_btif.stpBtifId = 0; + WMT_DBG_FUNC("STP close btif OK\n"); + } + } + + return iRet; +} + +INT32 mtk_wcn_consys_stp_btif_rx_cb_register(MTK_WCN_BTIF_RX_CB rx_cb) +{ + INT32 iRet = 0; + + if (!g_stp_btif.stpBtifId) { + WMT_WARN_FUNC("NULL BTIF ID reference\n!"); + if (rx_cb) + iRet = -1; + } else { + iRet = mtk_wcn_btif_rx_cb_register(g_stp_btif.stpBtifId, rx_cb); + if (iRet) { + WMT_WARN_FUNC("STP register rxcb to btif fail(%d)\n", iRet); + iRet = -2; + } else + WMT_DBG_FUNC("STP register rxcb to btif OK\n"); + } + + return iRet; +} + +INT32 mtk_wcn_consys_stp_btif_tx(const PUINT8 pBuf, const UINT32 len, PUINT32 written_len) +{ + INT32 retry_left = STP_BTIF_TX_RTY_LMT; + INT32 wr_count = 0; + INT32 written = 0; + + if (!g_stp_btif.stpBtifId) { + WMT_WARN_FUNC("NULL BTIF ID reference!\n"); + return -1; + } + + if (len == 0) { + *written_len = 0; + WMT_INFO_FUNC("special case for STP-CORE,pbuf(%p)\n", pBuf); + return 0; + } + + *written_len = 0; + + if (len > STP_MAX_PACKAGE_ALLOWED) { + WMT_WARN_FUNC("abnormal pacage length,len(%d),pid[%d/%s]\n", len, current->pid, current->comm); + return -2; + } + wr_count = mtk_wcn_btif_write(g_stp_btif.stpBtifId, pBuf, len); + + if (wr_count < 0) { + WMT_ERR_FUNC("mtk_wcn_btif_write err(%d)\n", wr_count); + *written_len = 0; + return -3; + } + if (wr_count == len) { + /*perfect case */ + *written_len = wr_count; + return wr_count; + } + + while ((retry_left--) && (wr_count < len)) { + osal_sleep_ms(STP_BTIF_TX_RTY_DLY); + written = mtk_wcn_btif_write(g_stp_btif.stpBtifId, pBuf + wr_count, len - wr_count); + if (written < 0) { + WMT_ERR_FUNC("mtk_wcn_btif_write err(%d)when do recovered\n", written); + break; + } + wr_count += written; + } + + if (wr_count == len) { + WMT_INFO_FUNC("recovered,len(%d),retry_left(%d)\n", len, retry_left); + /*recovered case */ + *written_len = wr_count; + return wr_count; + } + + WMT_ERR_FUNC("stp btif write fail,len(%d),written(%d),retry_left(%d),pid[%d/%s]\n", + len, wr_count, retry_left, current->pid, current->comm); + *written_len = 0; + + return -wr_count; +} + +INT32 mtk_wcn_consys_stp_btif_rx(PUINT8 pBuf, UINT32 len) +{ + return 0; +} + +INT32 mtk_wcn_consys_stp_btif_wakeup(VOID) +{ + INT32 iRet = 0; + + if (!g_stp_btif.stpBtifId) { + WMT_WARN_FUNC("NULL BTIF ID reference!\n"); + iRet = -1; + } else { + iRet = mtk_wcn_btif_wakeup_consys(g_stp_btif.stpBtifId); + if (iRet) { + WMT_WARN_FUNC("STP btif wakeup consys fail(%d)\n", iRet); + iRet = -2; + } else + WMT_DBG_FUNC("STP btif wakeup consys ok\n"); + } + + return iRet; +} + +INT32 mtk_wcn_consys_stp_btif_dpidle_ctrl(UINT32 en_flag) +{ + INT32 iRet = 0; + + if (!g_stp_btif.stpBtifId) { + WMT_WARN_FUNC("NULL BTIF ID reference!\n"); + iRet = -1; + } else { + mtk_wcn_btif_dpidle_ctrl(g_stp_btif.stpBtifId, (enum _ENUM_BTIF_DPIDLE_) en_flag); + WMT_DBG_FUNC("stp btif dpidle ctrl done,en_flag(%d)\n", en_flag); + } + + return iRet; +} + +INT32 mtk_wcn_consys_stp_btif_lpbk_ctrl(enum _ENUM_BTIF_LPBK_MODE_ mode) +{ + INT32 iRet = 0; + + if (!g_stp_btif.stpBtifId) { + WMT_WARN_FUNC("NULL BTIF ID reference!\n"); + iRet = -1; + } else { + iRet = mtk_wcn_btif_loopback_ctrl(g_stp_btif.stpBtifId, mode); + if (iRet) { + WMT_WARN_FUNC("STP btif lpbk ctrl fail(%d)\n", iRet); + iRet = -2; + } else + WMT_INFO_FUNC("stp btif lpbk ctrl ok,mode(%d)\n", mode); + } + + return iRet; +} + +INT32 mtk_wcn_consys_stp_btif_logger_ctrl(enum _ENUM_BTIF_DBG_ID_ flag) +{ + INT32 iRet = 0; + + if (!g_stp_btif.stpBtifId) { + WMT_WARN_FUNC("NULL BTIF ID reference!\n"); + iRet = -1; + } else { + iRet = mtk_wcn_btif_dbg_ctrl(g_stp_btif.stpBtifId, flag); + if (iRet) { + WMT_WARN_FUNC("STP btif log dbg ctrl fail(%d)\n", iRet); + iRet = -2; + } else + WMT_INFO_FUNC("stp btif log dbg ctrl ok,flag(%d)\n", flag); + } + + return iRet; +} + +INT32 mtk_wcn_consys_stp_btif_parser_wmt_evt(const PUINT8 str, UINT32 len) +{ + if (!g_stp_btif.stpBtifId) { + WMT_WARN_FUNC("NULL BTIF ID reference!\n"); + return -1; + } else + return (INT32) mtk_wcn_btif_parser_wmt_evt(g_stp_btif.stpBtifId, str, len); +} + +INT32 mtk_wcn_consys_stp_btif_rx_has_pending_data(VOID) +{ + return mtk_btif_exp_rx_has_pending_data(g_stp_btif.stpBtifId); +} + +INT32 mtk_wcn_consys_stp_btif_tx_has_pending_data(VOID) +{ + return mtk_btif_exp_tx_has_pending_data(g_stp_btif.stpBtifId); +} + +P_OSAL_THREAD mtk_wcn_consys_stp_btif_rx_thread_get(VOID) +{ + return &g_stp_btif.btif_thread; +} diff --git a/drivers/misc/mediatek/connectivity/common/common_main/linux/stp_dbg.c b/drivers/misc/mediatek/connectivity/common/common_main/linux/stp_dbg.c new file mode 100644 index 0000000000000000000000000000000000000000..b8206d50474cd73627daed652e9970fdb2fdc28c --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/linux/stp_dbg.c @@ -0,0 +1,2906 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +#include /* GFP_KERNEL */ +#include /* init_timer, add_time, del_timer_sync */ +#include /* gettimeofday */ +#include +#include /* kzalloc */ +#include /* task's status */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "osal.h" +#include "stp_dbg.h" +#include "stp_dbg_combo.h" +#include "stp_dbg_soc.h" +/* #include "stp_btm.h" */ +#include "btm_core.h" +#include "wmt_plat.h" +#include "wmt_detect.h" +#include "stp_sdio.h" +#include "stp_core.h" +#include "mtk_wcn_consys_hw.h" +#include "wmt_lib.h" + + +UINT32 gStpDbgLogOut; +UINT32 gStpDbgDumpType = STP_DBG_PKT; +INT32 gStpDbgDbgLevel = STP_DBG_LOG_INFO; +static CONSYS_STATE_DMP_INFO g_dmp_info; + +MTKSTP_DBG_T *g_stp_dbg; + +static OSAL_SLEEPABLE_LOCK g_dbg_nl_lock; + +#define STP_DBG_FAMILY_NAME "STP_DBG" +#define MAX_BIND_PROCESS (4) +#ifdef WMT_PLAT_ALPS +#ifndef LOG_STP_DEBUG_DISABLE +#define STP_DBG_AEE_EXP_API (1) +#else +#define STP_DBG_AEE_EXP_API (0) +#endif +#else +#define STP_DBG_AEE_EXP_API (0) +#endif + +#define STP_MAGIC_NUM (0xDEADFEED) + +#ifndef GENL_ID_GENERATE +#define GENL_ID_GENERATE 0 +#endif + +enum { + __STP_DBG_ATTR_INVALID, + STP_DBG_ATTR_MSG, + __STP_DBG_ATTR_MAX, +}; +#define STP_DBG_ATTR_MAX (__STP_DBG_ATTR_MAX - 1) + +enum { + __STP_DBG_COMMAND_INVALID, + STP_DBG_COMMAND_BIND, + STP_DBG_COMMAND_RESET, + __STP_DBG_COMMAND_MAX, +}; +#define MTK_WIFI_COMMAND_MAX (__STP_DBG_COMMAND_MAX - 1) + +/* attribute policy */ +static struct nla_policy stp_dbg_genl_policy[STP_DBG_ATTR_MAX + 1] = { + [STP_DBG_ATTR_MSG] = {.type = NLA_NUL_STRING}, +}; + +static UINT32 stp_dbg_seqnum; +static INT32 num_bind_process; +static pid_t bind_pid[MAX_BIND_PROCESS]; +static P_WCN_CORE_DUMP_T g_core_dump; +static P_STP_DBG_CPUPCR_T g_stp_dbg_cpupcr; +/* just show in log at present */ +static P_STP_DBG_DMAREGS_T g_stp_dbg_dmaregs; + +static VOID stp_dbg_core_dump_timeout_handler(timer_handler_arg arg); +static VOID stp_dbg_dump_emi_timeout_handler(timer_handler_arg arg); +static _osal_inline_ P_WCN_CORE_DUMP_T stp_dbg_core_dump_init(UINT32 timeout); +static _osal_inline_ INT32 stp_dbg_core_dump_deinit(P_WCN_CORE_DUMP_T dmp); +static _osal_inline_ INT32 stp_dbg_core_dump_check_end(PUINT8 buf, INT32 len); +static _osal_inline_ INT32 stp_dbg_core_dump_in(P_WCN_CORE_DUMP_T dmp, PUINT8 buf, INT32 len); +static _osal_inline_ INT32 stp_dbg_core_dump_post_handle(P_WCN_CORE_DUMP_T dmp); +static _osal_inline_ INT32 stp_dbg_core_dump_out(P_WCN_CORE_DUMP_T dmp, PPUINT8 pbuf, PINT32 plen); +static _osal_inline_ INT32 stp_dbg_core_dump_reset(P_WCN_CORE_DUMP_T dmp, UINT32 timeout); +static _osal_inline_ INT32 stp_dbg_core_dump_nl(P_WCN_CORE_DUMP_T dmp, PUINT8 buf, INT32 len); +static _osal_inline_ UINT32 stp_dbg_get_chip_id(VOID); +static _osal_inline_ INT32 stp_dbg_gzip_compressor(PVOID worker, PUINT8 in_buf, INT32 in_sz, PUINT8 out_buf, + PINT32 out_sz, INT32 finish); +static _osal_inline_ P_WCN_COMPRESSOR_T stp_dbg_compressor_init(PUINT8 name, INT32 L1_buf_sz, INT32 L2_buf_sz); +static _osal_inline_ INT32 stp_dbg_compressor_deinit(P_WCN_COMPRESSOR_T cprs); +static _osal_inline_ INT32 stp_dbg_compressor_in(P_WCN_COMPRESSOR_T cprs, + PUINT8 buf, INT32 len, INT32 is_iobuf, INT32 finish); +static _osal_inline_ INT32 stp_dbg_compressor_out(P_WCN_COMPRESSOR_T cprs, PPUINT8 pbuf, PINT32 plen); +static _osal_inline_ INT32 stp_dbg_compressor_reset(P_WCN_COMPRESSOR_T cprs, UINT8 enable, WCN_COMPRESS_ALG_T type); +static _osal_inline_ VOID stp_dbg_dump_data(PUINT8 pBuf, PINT8 title, INT32 len); +static _osal_inline_ INT32 stp_dbg_dmp_in(MTKSTP_DBG_T *stp_dbg, PINT8 buf, INT32 len); +static _osal_inline_ INT32 stp_dbg_notify_btm_dmp_wq(MTKSTP_DBG_T *stp_dbg); +static _osal_inline_ INT32 stp_dbg_get_avl_entry_num(MTKSTP_DBG_T *stp_dbg); +static _osal_inline_ INT32 stp_dbg_fill_hdr(STP_DBG_HDR_T *hdr, INT32 type, INT32 ack, INT32 seq, + INT32 crc, INT32 dir, INT32 len, INT32 dbg_type); +static _osal_inline_ INT32 stp_dbg_add_pkt(MTKSTP_DBG_T *stp_dbg, STP_DBG_HDR_T *hdr, const PUINT8 body); +static INT32 stp_dbg_nl_bind(struct sk_buff *skb, struct genl_info *info); +static INT32 stp_dbg_nl_reset(struct sk_buff *skb, struct genl_info *info); +static _osal_inline_ INT32 stp_dbg_parser_assert_str(PINT8 str, ENUM_ASSERT_INFO_PARSER_TYPE type); +static _osal_inline_ P_STP_DBG_CPUPCR_T stp_dbg_cpupcr_init(VOID); +static _osal_inline_ VOID stp_dbg_cpupcr_deinit(P_STP_DBG_CPUPCR_T pCpupcr); +static _osal_inline_ P_STP_DBG_DMAREGS_T stp_dbg_dmaregs_init(VOID); +static _osal_inline_ VOID stp_dbg_dmaregs_deinit(P_STP_DBG_DMAREGS_T pDmaRegs); + +INT32 __weak mtk_btif_rxd_be_blocked_flag_get(VOID) +{ + STP_DBG_PR_INFO("mtk_btif_rxd_be_blocked_flag_get is not define!!!\n"); + return 0; +} + +/* operation definition */ +static struct genl_ops stp_dbg_gnl_ops_array[] = { + { + .cmd = STP_DBG_COMMAND_BIND, + .flags = 0, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0)) + .policy = stp_dbg_genl_policy, +#endif + .doit = stp_dbg_nl_bind, + .dumpit = NULL, + }, + { + .cmd = STP_DBG_COMMAND_RESET, + .flags = 0, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0)) + .policy = stp_dbg_genl_policy, +#endif + .doit = stp_dbg_nl_reset, + .dumpit = NULL, + }, +}; + +static struct genl_family stp_dbg_gnl_family = { + .id = GENL_ID_GENERATE, + .hdrsize = 0, + .name = STP_DBG_FAMILY_NAME, + .version = 1, + .maxattr = STP_DBG_ATTR_MAX, + .ops = stp_dbg_gnl_ops_array, + .n_ops = ARRAY_SIZE(stp_dbg_gnl_ops_array), +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)) + .policy = stp_dbg_genl_policy, +#endif +}; +/* stp_dbg_core_dump_timeout_handler - handler of coredump timeout + * @ data - core dump object's pointer + * + * No return value + */ +static VOID stp_dbg_core_dump_timeout_handler(timer_handler_arg arg) +{ + stp_dbg_set_coredump_timer_state(CORE_DUMP_TIMEOUT); + stp_btm_notify_coredump_timeout_wq(g_stp_dbg->btm); + STP_DBG_PR_WARN(" coredump timer timeout, coredump maybe not finished successfully\n"); +} + +/* stp_dbg_dump_emi_timeout_handler - handler of emi dump timeout + * @ data - core dump object's pointer + * + * No return value + */ +static VOID stp_dbg_dump_emi_timeout_handler(timer_handler_arg arg) +{ + STP_DBG_PR_ERR("dump emi timeout!\n"); + mtk_stp_notify_emi_dump_end(); +} + +/* stp_dbg_core_dump_init - create core dump sys + * @ packet_num - core dump packet number unit 32k + * @ timeout - core dump time out value + * + * Return object pointer if success, else NULL + */ +static _osal_inline_ P_WCN_CORE_DUMP_T stp_dbg_core_dump_init(UINT32 timeout) +{ + P_WCN_CORE_DUMP_T core_dmp = NULL; + + core_dmp = (P_WCN_CORE_DUMP_T) osal_malloc(sizeof(WCN_CORE_DUMP_T)); + if (!core_dmp) { + STP_DBG_PR_ERR("alloc mem failed!\n"); + return NULL; + } + + osal_memset(core_dmp, 0, sizeof(WCN_CORE_DUMP_T)); + + core_dmp->dmp_timer.timeoutHandler = stp_dbg_core_dump_timeout_handler; + core_dmp->dmp_timer.timeroutHandlerData = (ULONG)core_dmp; + osal_timer_create(&core_dmp->dmp_timer); + core_dmp->timeout = timeout; + core_dmp->dmp_emi_timer.timeoutHandler = stp_dbg_dump_emi_timeout_handler; + core_dmp->dmp_emi_timer.timeroutHandlerData = (ULONG)core_dmp; + osal_timer_create(&core_dmp->dmp_emi_timer); + + osal_sleepable_lock_init(&core_dmp->dmp_lock); + + core_dmp->sm = CORE_DUMP_INIT; + STP_DBG_PR_INFO("create coredump object OK!\n"); + + return core_dmp; +} + + +/* stp_dbg_core_dump_deinit - destroy core dump object + * @ dmp - pointer of object + * + * Retunr 0 if success, else error code + */ +static _osal_inline_ INT32 stp_dbg_core_dump_deinit(P_WCN_CORE_DUMP_T dmp) +{ + if (dmp) { + if (dmp->p_head != NULL) { + osal_free(dmp->p_head); + dmp->p_head = NULL; + } + osal_sleepable_lock_deinit(&dmp->dmp_lock); + osal_timer_stop(&dmp->dmp_timer); + osal_timer_stop(&dmp->dmp_emi_timer); + osal_free(dmp); + dmp = NULL; + } + + return 0; +} + +INT32 stp_dbg_core_dump_deinit_gcoredump(VOID) +{ + stp_dbg_core_dump_deinit(g_core_dump); + return 0; +} + +static _osal_inline_ INT32 stp_dbg_core_dump_check_end(PUINT8 buf, INT32 len) +{ + if (strnstr(buf, "coredump end", len)) + return 1; + else + return 0; +} + +static UINT32 stp_dbg_core_dump_header_init(P_WCN_CORE_DUMP_T dmp) +{ + dmp->head_len = 0; + if (dmp->p_head == NULL) { + dmp->p_head = osal_malloc(MAX_DUMP_HEAD_LEN); + if (dmp->p_head == NULL) { + STP_DBG_PR_ERR("alloc memory for head information failed\n"); + return -1; + } + } + if (dmp->p_head != NULL) + osal_memset(dmp->p_head, 0, MAX_DUMP_HEAD_LEN); + + return 0; +} + +static UINT32 stp_dbg_core_dump_header_append(P_WCN_CORE_DUMP_T dmp, PUINT8 buf, INT32 len) +{ + INT32 tmp = 0; + + if ((dmp->p_head != NULL) && (dmp->head_len < (MAX_DUMP_HEAD_LEN - 1))) { + tmp = + (dmp->head_len + len) > + (MAX_DUMP_HEAD_LEN - 1) ? (MAX_DUMP_HEAD_LEN - 1 - dmp->head_len) : len; + osal_memcpy(dmp->p_head + dmp->head_len, buf, tmp); + dmp->head_len += tmp; + return tmp; + } + return 0; +} + +/* stp_dbg_core_dump_in - add a packet to compressor buffer + * @ dmp - pointer of object + * @ buf - input buffer + * @ len - data length + * + * Retunr 0 if success; return 1 if find end string; else error code + */ +static _osal_inline_ INT32 stp_dbg_core_dump_in(P_WCN_CORE_DUMP_T dmp, PUINT8 buf, INT32 len) +{ + INT32 ret = 0; + + if ((!dmp) || (!buf)) { + STP_DBG_PR_ERR("invalid pointer!\n"); + return -1; + } + + ret = osal_lock_sleepable_lock(&dmp->dmp_lock); + if (ret) { + STP_DBG_PR_ERR("--->lock dmp->dmp_lock failed, ret=%d\n", ret); + return ret; + } + + switch (dmp->sm) { + case CORE_DUMP_INIT: + stp_dbg_compressor_reset(dmp->compressor, 1, GZIP); + stp_dbg_core_dump_header_init(dmp); + /* show coredump start info on UI */ + /* osal_dbg_assert_aee("MT662x f/w coredump start", "MT662x firmware coredump start"); */ + /* parsing data, and check end srting */ + ret = stp_dbg_core_dump_check_end(buf, len); + if (ret == 1) { + STP_DBG_PR_INFO("core dump end!\n"); + dmp->sm = CORE_DUMP_DONE; + stp_dbg_compressor_in(dmp->compressor, buf, len, 0, 0); + } else { + dmp->sm = CORE_DUMP_DOING; + stp_dbg_compressor_in(dmp->compressor, buf, len, 0, 0); + } + break; + + case CORE_DUMP_DOING: + /* parsing data, and check end srting */ + ret = stp_dbg_core_dump_check_end(buf, len); + if (ret == 1) { + STP_DBG_PR_INFO("core dump end!\n"); + dmp->sm = CORE_DUMP_DONE; + stp_dbg_compressor_in(dmp->compressor, buf, len, 0, 0); + } else { + dmp->sm = CORE_DUMP_DOING; + stp_dbg_compressor_in(dmp->compressor, buf, len, 0, 0); + } + break; + + case CORE_DUMP_DONE: + stp_dbg_compressor_reset(dmp->compressor, 1, GZIP); + osal_timer_stop(&dmp->dmp_timer); + stp_dbg_compressor_in(dmp->compressor, buf, len, 0, 0); + dmp->sm = CORE_DUMP_DOING; + break; + + case CORE_DUMP_TIMEOUT: + ret = -1; + break; + default: + break; + } + + stp_dbg_core_dump_header_append(dmp, buf, len); + osal_unlock_sleepable_lock(&dmp->dmp_lock); + + return ret; +} + +static _osal_inline_ INT32 stp_dbg_core_dump_post_handle(P_WCN_CORE_DUMP_T dmp) +{ +#define INFO_HEAD ";CONSYS FW CORE, " + INT32 ret = 0; + INT32 tmp = 0; + ENUM_STP_FW_ISSUE_TYPE issue_type; + + if ((dmp->p_head != NULL) + && ((osal_strnstr(dmp->p_head, "", dmp->head_len)) != NULL || + stp_dbg_get_host_trigger_assert())) { + PINT8 pStr = dmp->p_head; + PINT8 pDtr = NULL; + + if (stp_dbg_get_host_trigger_assert()) + issue_type = STP_HOST_TRIGGER_FW_ASSERT; + else + issue_type = STP_FW_ASSERT_ISSUE; + STP_DBG_PR_INFO("dmp->head_len = %d\n", dmp->head_len); + /*parse f/w assert additional informationi for f/w's analysis */ + ret = stp_dbg_set_fw_info(dmp->p_head, dmp->head_len, issue_type); + if (ret) { + STP_DBG_PR_ERR("set fw issue infor fail(%d),maybe fw warm reset...\n", + ret); + stp_dbg_set_fw_info("Fw Warm reset", osal_strlen("Fw Warm reset"), + STP_FW_WARM_RST_ISSUE); + } + /* first package, copy to info buffer */ + osal_strcpy(&dmp->info[0], INFO_HEAD); + + /* set f/w assert information to warm reset */ + pStr = osal_strnstr(pStr, "", dmp->head_len); + if (pStr != NULL) { + pDtr = osal_strchr(pStr, '-'); + if (pDtr != NULL) { + tmp = STP_CORE_DUMP_INFO_SZ - osal_strlen(INFO_HEAD); + tmp = ((pDtr - pStr) > tmp) ? tmp : (pDtr - pStr); + osal_memcpy(&dmp->info[osal_strlen(INFO_HEAD)], pStr, tmp); + dmp->info[osal_strlen(dmp->info) + 1] = '\0'; + } else { + tmp = STP_CORE_DUMP_INFO_SZ - osal_strlen(INFO_HEAD); + tmp = (dmp->head_len > tmp) ? tmp : dmp->head_len; + osal_memcpy(&dmp->info[osal_strlen(INFO_HEAD)], pStr, tmp); + dmp->info[STP_CORE_DUMP_INFO_SZ] = '\0'; + } + } + } else if ((dmp->p_head != NULL) + && ((osal_strnstr(dmp->p_head, "", dmp->head_len) != NULL) + || (osal_strnstr(dmp->p_head, "ABT", dmp->head_len) != NULL))) { + stp_dbg_set_fw_info(dmp->p_head, dmp->head_len, STP_FW_ABT); + osal_strcpy(&dmp->info[0], INFO_HEAD); + osal_memcpy(&dmp->info[osal_strlen(INFO_HEAD)], "Fw ABT Exception...", + osal_strlen("Fw ABT Exception...")); + dmp->info[osal_strlen(INFO_HEAD) + osal_strlen("Fw ABT Exception...") + 1] = '\0'; + } else { + STP_DBG_PR_INFO(" string not found, dmp->head_len:%d\n", dmp->head_len); + if (dmp->p_head == NULL) + STP_DBG_PR_INFO(" dmp->p_head is NULL\n"); + else + STP_DBG_PR_INFO(" dmp->p_head:%s\n", dmp->p_head); + + /* first package, copy to info buffer */ + osal_strcpy(&dmp->info[0], INFO_HEAD); + /* set f/w assert information to warm reset */ + osal_memcpy(&dmp->info[osal_strlen(INFO_HEAD)], "Fw warm reset exception...", + osal_strlen("Fw warm reset exception...")); + dmp->info[osal_strlen(INFO_HEAD) + osal_strlen("Fw warm reset exception...") + 1] = + '\0'; + + } + dmp->head_len = 0; + + /*set ret value to notify upper layer do dump flush operation */ + ret = 1; + + return ret; +} + +/* stp_dbg_core_dump_out - get compressed data from compressor buffer + * @ dmp - pointer of object + * @ pbuf - target buffer's pointer + * @ len - data length + * + * Retunr 0 if success; else error code + */ +static _osal_inline_ INT32 stp_dbg_core_dump_out(P_WCN_CORE_DUMP_T dmp, PPUINT8 pbuf, PINT32 plen) +{ + INT32 ret = 0; + + if ((!dmp) || (!pbuf) || (!plen)) { + STP_DBG_PR_ERR("invalid pointer!\n"); + return -1; + } + + ret = osal_lock_sleepable_lock(&dmp->dmp_lock); + if (ret) { + STP_DBG_PR_ERR("--->lock dmp->dmp_lock failed, ret=%d\n", ret); + return ret; + } + + ret = stp_dbg_compressor_out(dmp->compressor, pbuf, plen); + + osal_unlock_sleepable_lock(&dmp->dmp_lock); + + return ret; +} + +/* stp_dbg_core_dump_reset - reset core dump sys + * @ dmp - pointer of object + * @ timeout - core dump time out value + * + * Retunr 0 if success, else error code + */ +static _osal_inline_ INT32 stp_dbg_core_dump_reset(P_WCN_CORE_DUMP_T dmp, UINT32 timeout) +{ + if (!dmp) { + STP_DBG_PR_ERR("invalid pointer!\n"); + return -1; + } + + dmp->sm = CORE_DUMP_INIT; + dmp->timeout = timeout; + osal_timer_stop(&dmp->dmp_timer); + osal_timer_stop(&dmp->dmp_emi_timer); + osal_memset(dmp->info, 0, STP_CORE_DUMP_INFO_SZ + 1); + + stp_dbg_core_dump_deinit(dmp); + g_core_dump = stp_dbg_core_dump_init(STP_CORE_DUMP_TIMEOUT); + + return 0; +} + +#define ENABLE_F_TRACE 0 +/* stp_dbg_core_dump_flush - Fulsh dump data and reset core dump sys + * + * Retunr 0 if success, else error code + */ +INT32 stp_dbg_core_dump_flush(INT32 rst, MTK_WCN_BOOL coredump_is_timeout) +{ + PUINT8 pbuf = NULL; + INT32 len = 0; + + if (!g_core_dump) { + STP_DBG_PR_ERR("invalid pointer!\n"); + return -1; + } + + osal_lock_sleepable_lock(&g_core_dump->dmp_lock); + stp_dbg_core_dump_post_handle(g_core_dump); + osal_unlock_sleepable_lock(&g_core_dump->dmp_lock); + stp_dbg_core_dump_out(g_core_dump, &pbuf, &len); + STP_DBG_PR_INFO("buf 0x%zx, len %d\n", (SIZE_T) pbuf, len); + +#if IS_ENABLED(CONFIG_MTK_AEE_AED) + /* show coredump end info on UI */ + /* osal_dbg_assert_aee("MT662x f/w coredump end", "MT662x firmware coredump ends"); */ +#if STP_DBG_AEE_EXP_API +#if ENABLE_F_TRACE + aed_combo_exception_api(NULL, 0, (const PINT32)pbuf, len, (const PINT8)g_core_dump->info, + DB_OPT_FTRACE); +#else + aed_combo_exception(NULL, 0, (const PINT32)pbuf, len, (const PINT8)g_core_dump->info); +#endif +#endif + +#endif + /* reset */ + g_core_dump->count = 0; + stp_dbg_compressor_deinit(g_core_dump->compressor); + stp_dbg_core_dump_reset(g_core_dump, STP_CORE_DUMP_TIMEOUT); + + return 0; +} + +static _osal_inline_ INT32 stp_dbg_core_dump_nl(P_WCN_CORE_DUMP_T dmp, PUINT8 buf, INT32 len) +{ + INT32 ret = 0; + + if ((!dmp) || (!buf)) { + STP_DBG_PR_ERR("invalid pointer!\n"); + return -1; + } + + ret = osal_lock_sleepable_lock(&dmp->dmp_lock); + if (ret) { + STP_DBG_PR_ERR("--->lock dmp->dmp_lock failed, ret=%d\n", ret); + return ret; + } + + switch (dmp->sm) { + case CORE_DUMP_INIT: + STP_DBG_PR_WARN("CONSYS coredump start, please wait up to %d minutes.\n", + STP_CORE_DUMP_TIMEOUT/60000); + stp_dbg_core_dump_header_init(dmp); + /* check end srting */ + ret = stp_dbg_core_dump_check_end(buf, len); + if (ret == 1) { + STP_DBG_PR_INFO("core dump end!\n"); + osal_timer_stop(&dmp->dmp_timer); + dmp->sm = CORE_DUMP_INIT; + } else { + dmp->sm = CORE_DUMP_DOING; + } + break; + + case CORE_DUMP_DOING: + /* check end srting */ + ret = stp_dbg_core_dump_check_end(buf, len); + if (ret == 1) { + STP_DBG_PR_INFO("core dump end!\n"); + osal_timer_stop(&dmp->dmp_timer); + dmp->sm = CORE_DUMP_INIT; + } else { + dmp->sm = CORE_DUMP_DOING; + } + break; + + case CORE_DUMP_DONE: + osal_timer_stop(&dmp->dmp_timer); + dmp->sm = CORE_DUMP_INIT; + break; + + case CORE_DUMP_TIMEOUT: + ret = 32; + break; + default: + break; + } + + /* Skip nl packet header */ + stp_dbg_core_dump_header_append(dmp, buf + NL_PKT_HEADER_LEN, len - NL_PKT_HEADER_LEN); + osal_unlock_sleepable_lock(&dmp->dmp_lock); + + return ret; +} + +INT32 stp_dbg_core_dump(INT32 dump_sink) +{ + ENUM_WMT_CHIP_TYPE chip_type; + INT32 ret = 0; + + chip_type = wmt_detect_get_chip_type(); + switch (chip_type) { + case WMT_CHIP_TYPE_COMBO: + ret = stp_dbg_combo_core_dump(dump_sink); + break; + case WMT_CHIP_TYPE_SOC: + ret = stp_dbg_soc_core_dump(dump_sink); + break; + default: + STP_DBG_PR_ERR("error chip type(%d)\n", chip_type); + } + + return ret; +} + +static _osal_inline_ UINT32 stp_dbg_get_chip_id(VOID) +{ + ENUM_WMT_CHIP_TYPE chip_type; + UINT32 chip_id = 0; + + chip_type = wmt_detect_get_chip_type(); + switch (chip_type) { + case WMT_CHIP_TYPE_COMBO: + chip_id = mtk_wcn_wmt_chipid_query(); + break; + case WMT_CHIP_TYPE_SOC: + chip_id = wmt_plat_get_soc_chipid(); + break; + default: + STP_DBG_PR_ERR("error chip type(%d)\n", chip_type); + } + + return chip_id; +} + +/* stp_dbg_trigger_collect_ftrace - this func can collect SYS_FTRACE + * + * Retunr 0 if success + */ +INT32 stp_dbg_trigger_collect_ftrace(PUINT8 pbuf, INT32 len) +{ + if (!pbuf) { + STP_DBG_PR_ERR("Parameter error\n"); + return -1; + } + + if (mtk_wcn_stp_coredump_start_get()) { + STP_DBG_PR_ERR("assert has been triggered\n"); + return -1; + } + + stp_dbg_set_host_assert_info(WMTDRV_TYPE_WMT, 30, 1); + + if (stp_dbg_set_fw_info(pbuf, len, STP_HOST_TRIGGER_COLLECT_FTRACE)) + return -1; + + if (g_core_dump) { + osal_strncpy(&g_core_dump->info[0], pbuf, len); +#if IS_ENABLED(CONFIG_MTK_AEE_AED) + aed_combo_exception(NULL, 0, (const PINT32)pbuf, len, (const PINT8)g_core_dump->info); +#endif + } else { + STP_DBG_PR_INFO("g_core_dump is not initialized\n"); +#if IS_ENABLED(CONFIG_MTK_AEE_AED) + aed_combo_exception(NULL, 0, (const PINT32)pbuf, len, (const PINT8)pbuf); +#endif + } + + return 0; +} + +#if BTIF_RXD_BE_BLOCKED_DETECT +MTK_WCN_BOOL stp_dbg_is_btif_rxd_be_blocked(VOID) +{ + MTK_WCN_BOOL flag = MTK_WCN_BOOL_FALSE; + + if (mtk_btif_rxd_be_blocked_flag_get()) + flag = MTK_WCN_BOOL_TRUE; + return flag; +} +#endif + +static _osal_inline_ INT32 stp_dbg_gzip_compressor(PVOID worker, PUINT8 in_buf, INT32 in_sz, PUINT8 out_buf, + PINT32 out_sz, INT32 finish) +{ + INT32 ret = 0; + z_stream *stream = NULL; + INT32 tmp = *out_sz; + + STP_DBG_PR_DBG("before compressor:buf 0x%zx, size %d, avalible buf: 0x%zx, size %d\n", + (SIZE_T) in_buf, in_sz, (SIZE_T) out_buf, tmp); + + stream = (z_stream *) worker; + if (!stream) { + STP_DBG_PR_ERR("invalid workspace!\n"); + return -1; + } + + if (in_sz > 0) { +#if 0 + ret = zlib_deflateReset(stream); + if (ret != Z_OK) { + STP_DBG_PR_ERR("reset failed!\n"); + return -2; + } +#endif + stream->next_in = in_buf; + stream->avail_in = in_sz; + stream->next_out = out_buf; + stream->avail_out = tmp; + + zlib_deflate(stream, Z_FULL_FLUSH); + + if (finish) { + while (1) { + INT32 val = zlib_deflate(stream, Z_FINISH); + + if (val == Z_OK) + continue; + else if (val == Z_STREAM_END) + break; + STP_DBG_PR_ERR("finish operation failed %d\n", val); + return -3; + } + } + *out_sz = tmp - stream->avail_out; + } + + STP_DBG_PR_DBG("after compressor,avalible buf: 0x%zx, compress rate %d -> %d\n", + (SIZE_T) out_buf, in_sz, *out_sz); + + return ret; +} + +/* stp_dbg_compressor_init - create a compressor and do init + * @ name - compressor's name + * @ L1_buf_sz - L1 buffer size + * @ L2_buf_sz - L2 buffer size + * + * Retunr object's pointer if success, else NULL + */ +static _osal_inline_ P_WCN_COMPRESSOR_T stp_dbg_compressor_init(PUINT8 name, INT32 L1_buf_sz, + INT32 L2_buf_sz) +{ + INT32 ret = 0; + z_stream *pstream = NULL; + P_WCN_COMPRESSOR_T compress = NULL; + + compress = (P_WCN_COMPRESSOR_T) osal_malloc(sizeof(WCN_COMPRESSOR_T)); + if (!compress) { + STP_DBG_PR_ERR("alloc compressor failed!\n"); + goto fail; + } + + osal_memset(compress, 0, sizeof(WCN_COMPRESSOR_T)); + osal_memcpy(compress->name, name, STP_OJB_NAME_SZ); + + compress->f_compress_en = 0; + compress->compress_type = GZIP; + + if (compress->compress_type == GZIP) { + compress->worker = osal_malloc(sizeof(z_stream)); + if (!compress->worker) { + STP_DBG_PR_ERR("alloc stream failed!\n"); + goto fail; + } + pstream = (z_stream *) compress->worker; + + pstream->workspace = osal_malloc(zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL)); + if (!pstream->workspace) { + STP_DBG_PR_ERR("alloc workspace failed!\n"); + goto fail; + } + ret = zlib_deflateInit2(pstream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -MAX_WBITS, + DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY); + if (ret != Z_OK) { + STP_DBG_PR_INFO("[%s::%d] zlib_deflateInit2 failed!\n", __func__, __LINE__); + goto fail; + } + } + + compress->handler = stp_dbg_gzip_compressor; + compress->L1_buf_sz = L1_buf_sz; + compress->L2_buf_sz = L2_buf_sz; + compress->L1_pos = 0; + compress->L2_pos = 0; + compress->uncomp_size = 0; + compress->crc32 = 0xffffffffUL; + + compress->L1_buf = osal_malloc(compress->L1_buf_sz); + if (!compress->L1_buf) { + STP_DBG_PR_ERR("alloc %d bytes for L1 buf failed!\n", compress->L1_buf_sz); + goto fail; + } + + compress->L2_buf = osal_malloc(compress->L2_buf_sz); + if (!compress->L2_buf) { + STP_DBG_PR_ERR("alloc %d bytes for L2 buf failed!\n", compress->L2_buf_sz); + goto fail; + } + + STP_DBG_PR_INFO("create compressor OK! L1 %d bytes, L2 %d bytes\n", L1_buf_sz, L2_buf_sz); + return compress; + +fail: + if (compress) { + if (compress->L2_buf) { + osal_free(compress->L2_buf); + compress->L2_buf = NULL; + } + + if (compress->L1_buf) { + osal_free(compress->L1_buf); + compress->L1_buf = NULL; + } + + if (compress->worker) { + pstream = (z_stream *) compress->worker; + if ((compress->compress_type == GZIP) && pstream->workspace) { + zlib_deflateEnd(pstream); + osal_free(pstream->workspace); + } + osal_free(compress->worker); + compress->worker = NULL; + } + + if (compress->worker) { + osal_free(compress->worker); + compress->worker = NULL; + } + + osal_free(compress); + compress = NULL; + } + + STP_DBG_PR_ERR("init failed!\n"); + + return NULL; +} + +/* stp_dbg_compressor_deinit - distroy a compressor + * @ cprs - compressor's pointer + * + * Retunr 0 if success, else NULL + */ +static _osal_inline_ INT32 stp_dbg_compressor_deinit(P_WCN_COMPRESSOR_T cprs) +{ + z_stream *pstream = NULL; + + if (cprs) { + if (cprs->L2_buf) { + osal_free(cprs->L2_buf); + cprs->L2_buf = NULL; + } + + if (cprs->L1_buf) { + osal_free(cprs->L1_buf); + cprs->L1_buf = NULL; + } + + if (cprs->worker) { + pstream = (z_stream *) cprs->worker; + if ((cprs->compress_type == GZIP) && pstream->workspace) { + zlib_deflateEnd(pstream); + osal_free(pstream->workspace); + } + osal_free(cprs->worker); + cprs->worker = NULL; + } + + cprs->handler = NULL; + + osal_free(cprs); + } + + STP_DBG_PR_INFO("destroy OK\n"); + + return 0; +} + +/* stp_dbg_compressor_in - put in a raw data, and compress L1 buffer if need + * @ cprs - compressor's pointer + * @ buf - raw data buffer + * @ len - raw data length + * @ is_iobuf - is buf a pointer to EMI? 1: yes, 0: no + * @ finish - core dump finish or not, 1: finished; 0: not finish + * + * Retunr 0 if success, else NULL + */ +static _osal_inline_ INT32 stp_dbg_compressor_in(P_WCN_COMPRESSOR_T cprs, PUINT8 buf, INT32 len, + INT32 is_iobuf, INT32 finish) +{ + INT32 tmp_len = 0; + INT32 ret = 0; + + if (!cprs) { + STP_DBG_PR_ERR("invalid para!\n"); + return -1; + } + + cprs->uncomp_size += len; + + /* check L1 buf valid space */ + if (len > (cprs->L1_buf_sz - cprs->L1_pos)) { + STP_DBG_PR_DBG("L1 buffer full\n"); + + if (cprs->f_compress_en && cprs->handler) { + /* need compress */ + /* compress L1 buffer, and put result to L2 buffer */ + tmp_len = cprs->L2_buf_sz - cprs->L2_pos; + ret = + cprs->handler(cprs->worker, cprs->L1_buf, cprs->L1_pos, + &cprs->L2_buf[cprs->L2_pos], &tmp_len, finish); + if (!ret) { + cprs->crc32 = (crc32(cprs->crc32, cprs->L1_buf, cprs->L1_pos)); + cprs->L2_pos += tmp_len; + if (cprs->L2_pos >= cprs->L2_buf_sz) + STP_DBG_PR_ERR("coredump size too large(%d), L2 buf overflow\n", + cprs->L2_pos); + + if (finish) { + /* Add 8 byte suffix + * === + * 32 bits UNCOMPRESS SIZE + * 32 bits CRC + */ + *(uint32_t *) (&cprs->L2_buf[cprs->L2_pos]) = + (cprs->crc32 ^ 0xffffffffUL); + *(uint32_t *) (&cprs->L2_buf[cprs->L2_pos + 4]) = cprs->uncomp_size; + cprs->L2_pos += 8; + } + STP_DBG_PR_DBG("compress OK!\n"); + } else + STP_DBG_PR_ERR("compress error!\n"); + } else { + /* no need compress */ + /* Flush L1 buffer to L2 buffer */ + STP_DBG_PR_INFO("No need do compress, Put to L2 buf\n"); + + tmp_len = cprs->L2_buf_sz - cprs->L2_pos; + tmp_len = (cprs->L1_pos > tmp_len) ? tmp_len : cprs->L1_pos; + osal_memcpy(&cprs->L2_buf[cprs->L2_pos], cprs->L1_buf, tmp_len); + cprs->L2_pos += tmp_len; + } + + /* reset L1 buf pos */ + cprs->L1_pos = 0; + + /* put curren data to L1 buf */ + if (len > cprs->L1_buf_sz) { + STP_DBG_PR_ERR("len=%d, too long err!\n", len); + } else { + STP_DBG_PR_DBG("L1 Flushed, and Put %d bytes to L1 buf\n", len); + if (is_iobuf) + osal_memcpy_fromio(&cprs->L1_buf[cprs->L1_pos], buf, len); + else + osal_memcpy(&cprs->L1_buf[cprs->L1_pos], buf, len); + cprs->L1_pos += len; + } + } else { + /* put to L1 buffer */ + STP_DBG_PR_DBG("Put %d bytes to L1 buf\n", len); + if (is_iobuf) + osal_memcpy_fromio(&cprs->L1_buf[cprs->L1_pos], buf, len); + else + osal_memcpy(&cprs->L1_buf[cprs->L1_pos], buf, len); + cprs->L1_pos += len; + } + + return ret; +} + +/* stp_dbg_compressor_out - get the result data from L2 buffer + * @ cprs - compressor's pointer + * @ pbuf - point to L2 buffer + * @ plen - out len + * + * Retunr 0 if success, else NULL + */ +static _osal_inline_ INT32 stp_dbg_compressor_out(P_WCN_COMPRESSOR_T cprs, PPUINT8 pbuf, PINT32 plen) +{ + INT32 ret = 0; + INT32 tmp_len = 0; + + if ((!cprs) || (!pbuf) || (!plen)) { + STP_DBG_PR_ERR("invalid para!\n"); + return -1; + } + /* check if there's L1 data need flush to L2 buffer */ + if (cprs->L1_pos > 0) { + tmp_len = cprs->L2_buf_sz - cprs->L2_pos; + + if (cprs->f_compress_en && cprs->handler) { + /* need compress */ + ret = + cprs->handler(cprs->worker, cprs->L1_buf, cprs->L1_pos, + &cprs->L2_buf[cprs->L2_pos], &tmp_len, 1); + + if (!ret) { + cprs->crc32 = (crc32(cprs->crc32, cprs->L1_buf, cprs->L1_pos)); + cprs->L2_pos += tmp_len; + + /* Add 8 byte suffix + * === + * 32 bits UNCOMPRESS SIZE + * 32 bits CRC + */ + *(uint32_t *) (&cprs->L2_buf[cprs->L2_pos]) = (cprs->crc32 ^ 0xffffffffUL); + *(uint32_t *) (&cprs->L2_buf[cprs->L2_pos + 4]) = cprs->uncomp_size; + cprs->L2_pos += 8; + + STP_DBG_PR_INFO("compress OK!\n"); + } else { + STP_DBG_PR_ERR("compress error!\n"); + } + } else { + /* no need compress */ + tmp_len = (cprs->L1_pos > tmp_len) ? tmp_len : cprs->L1_pos; + osal_memcpy(&cprs->L2_buf[cprs->L2_pos], cprs->L1_buf, tmp_len); + cprs->L2_pos += tmp_len; + } + + cprs->L1_pos = 0; + } + + *pbuf = cprs->L2_buf; + *plen = cprs->L2_pos; + + STP_DBG_PR_INFO("0x%zx, len %d, l2_buf_remain %d\n", (SIZE_T)*pbuf, *plen, cprs->L2_buf_sz - cprs->L2_pos); + +#if 1 + ret = zlib_deflateReset((z_stream *) cprs->worker); + if (ret != Z_OK) { + STP_DBG_PR_ERR("reset failed!\n"); + return -2; + } +#endif + return 0; +} + +/* stp_dbg_compressor_reset - reset compressor + * @ cprs - compressor's pointer + * @ enable - enable/disable compress + * @ type - compress algorithm + * + * Retunr 0 if success, else NULL + */ +static _osal_inline_ INT32 stp_dbg_compressor_reset(P_WCN_COMPRESSOR_T cprs, UINT8 enable, + WCN_COMPRESS_ALG_T type) +{ + if (!cprs) { + STP_DBG_PR_ERR("invalid para!\n"); + return -1; + } + + cprs->f_compress_en = enable; + /* cprs->f_compress_en = 0; // disable compress for test */ + cprs->compress_type = type; + cprs->L1_pos = 0; + cprs->L2_pos = 0; + cprs->uncomp_size = 0; + cprs->crc32 = 0xffffffffUL; + + /* zlib_deflateEnd((z_stream*)cprs->worker); */ + + STP_DBG_PR_INFO("OK! compress algorithm %d\n", type); + + return 0; +} + +#if 0 +static _osal_inline_ VOID stp_dbg_dump_data(PUINT8 pBuf, PINT8 title, INT32 len) +{ + INT32 idx = 0; + UINT8 str[240]; + PUINT8 p_str; + + p_str = &str[0]; + pr_debug(" %s-len:%d\n", title, len); + for (idx = 0; idx < len; idx++, pBuf++) { + sprintf(p_str, "%02x ", *pBuf); + p_str += 3; + if (15 == (idx % 16)) { + sprintf(p_str, "--end\n"); + *(p_str + 6) = '\0'; + pr_debug("%s", str); + p_str = 0; + } + } + if (len % 16) { + sprintf(p_str, "--end\n"); + *(p_str + 6) = '\0'; + pr_debug("%s", str); + } +} +#endif +static VOID stp_dbg_dump_data(PUINT8 pBuf, PINT8 title, INT32 len) +{ + INT32 k = 0; + char str[240] = {""}; + char buf_str[32] = {""}; + + pr_warn(" %s-len:%d\n", title, len); + /* pr_warn(" ", title, len); */ + for (k = 0; k < len; k++) { + if (strlen(str) < 200) { + if (snprintf(buf_str, sizeof(buf_str), "0x%02x ", pBuf[k]) > 0) + strncat(str, buf_str, strlen(buf_str)); + } else { + pr_warn("More than 200 of the data is too much\n"); + break; + } + } + strncat(str, "--end\n", strlen("--end\n")); + pr_warn("%s", str); +} + + +INT32 stp_dbg_enable(MTKSTP_DBG_T *stp_dbg) +{ + ULONG flags; + + spin_lock_irqsave(&(stp_dbg->logsys->lock), flags); + stp_dbg->pkt_trace_no = 0; + stp_dbg->is_enable = 1; + spin_unlock_irqrestore(&(stp_dbg->logsys->lock), flags); + + return 0; +} + +INT32 stp_dbg_disable(MTKSTP_DBG_T *stp_dbg) +{ + ULONG flags; + + spin_lock_irqsave(&(stp_dbg->logsys->lock), flags); + stp_dbg->pkt_trace_no = 0; + memset(stp_dbg->logsys, 0, sizeof(MTKSTP_LOG_SYS_T)); + stp_dbg->is_enable = 0; + spin_unlock_irqrestore(&(stp_dbg->logsys->lock), flags); + + return 0; +} + +static PINT8 stp_get_dbg_type_string(const PINT8 *pType, UINT32 type) +{ + PINT8 info_task_type = ""; + + if (!pType) + return NULL; + + if ((mtk_wcn_stp_is_support_gpsl5() == 0) && (type == INFO_TASK_INDX)) + return info_task_type; + else + return pType[type]; +} + +static _osal_inline_ INT32 stp_dbg_dmp_in(MTKSTP_DBG_T *stp_dbg, PINT8 buf, INT32 len) +{ + ULONG flags; + STP_DBG_HDR_T *pHdr = NULL; + PINT8 pBuf = NULL; + UINT32 length = 0; + const PINT8 *pType = NULL; + + pType = wmt_detect_get_chip_type() == WMT_CHIP_TYPE_COMBO ? + comboStpDbgType : socStpDbgType; + + spin_lock_irqsave(&(stp_dbg->logsys->lock), flags); + + stp_dbg->logsys->queue[stp_dbg->logsys->in].id = 0; + stp_dbg->logsys->queue[stp_dbg->logsys->in].len = len; + memset(&(stp_dbg->logsys->queue[stp_dbg->logsys->in].buffer[0]), + 0, ((len >= STP_DBG_LOG_ENTRY_SZ) ? (STP_DBG_LOG_ENTRY_SZ) : (len))); + memcpy(&(stp_dbg->logsys->queue[stp_dbg->logsys->in].buffer[0]), + buf, ((len >= STP_DBG_LOG_ENTRY_SZ) ? (STP_DBG_LOG_ENTRY_SZ) : (len))); + stp_dbg->logsys->size++; + stp_dbg->logsys->size = (stp_dbg->logsys->size > STP_DBG_LOG_ENTRY_NUM) ? + STP_DBG_LOG_ENTRY_NUM : stp_dbg->logsys->size; + if (gStpDbgLogOut != 0) { + pHdr = (STP_DBG_HDR_T *) &(stp_dbg->logsys->queue[stp_dbg->logsys->in].buffer[0]); + pBuf = (PINT8)&(stp_dbg->logsys->queue[stp_dbg->logsys->in].buffer[0]) + + sizeof(STP_DBG_HDR_T); + length = stp_dbg->logsys->queue[stp_dbg->logsys->in].len - sizeof(STP_DBG_HDR_T); + pr_info("STP-DBG:%d.%ds, %s:pT%sn(%d)l(%d)s(%d)a(%d)\n", + pHdr->sec, + pHdr->usec, + pHdr->dir == PKT_DIR_TX ? "Tx" : "Rx", + stp_get_dbg_type_string(pType, pHdr->type), + pHdr->no, pHdr->len, pHdr->seq, pHdr->ack); + + if (length > 0) + stp_dbg_dump_data(pBuf, pHdr->dir == PKT_DIR_TX ? "Tx" : "Rx", length); + } + stp_dbg->logsys->in = + (stp_dbg->logsys->in >= (STP_DBG_LOG_ENTRY_NUM - 1)) ? (0) : (stp_dbg->logsys->in + 1); + STP_DBG_PR_DBG("logsys size = %d, in = %d\n", stp_dbg->logsys->size, stp_dbg->logsys->in); + + spin_unlock_irqrestore(&(stp_dbg->logsys->lock), flags); + + return 0; +} + +static _osal_inline_ INT32 stp_dbg_notify_btm_dmp_wq(MTKSTP_DBG_T *stp_dbg) +{ + INT32 retval = 0; + +/* #ifndef CONFIG_LOG_STP_INTERNAL */ + if (stp_dbg->btm != NULL) + retval += stp_btm_notify_wmt_dmp_wq((MTKSTP_BTM_T *) stp_dbg->btm); +/* #endif */ + + return retval; +} + +static VOID stp_dbg_dmp_print_work(struct work_struct *work) +{ + MTKSTP_LOG_SYS_T *logsys = container_of(work, MTKSTP_LOG_SYS_T, dump_work); + INT32 dumpSize = logsys->dump_size; + MTKSTP_LOG_ENTRY_T *queue = logsys->dump_queue; + INT32 i; + PINT8 pBuf = NULL; + INT32 len = 0; + STP_DBG_HDR_T *pHdr = NULL; + const PINT8 *pType = NULL; + + if (queue == NULL || queue == (MTKSTP_LOG_ENTRY_T *)STP_MAGIC_NUM) + return; + + pType = wmt_detect_get_chip_type() == WMT_CHIP_TYPE_COMBO ? + comboStpDbgType : socStpDbgType; + + for (i = 0; i < dumpSize; i++) { + pHdr = (STP_DBG_HDR_T *) &(queue[i].buffer[0]); + pBuf = &(queue[i].buffer[0]) + sizeof(STP_DBG_HDR_T); + len = queue[i].len - sizeof(STP_DBG_HDR_T); + len = len > STP_PKT_SZ ? STP_PKT_SZ : len; + pr_info("STP-DBG:%d.%ds, %s:pT%sn(%d)l(%d)s(%d)a(%d), time[%llu.%06lu]\n", + pHdr->sec, + pHdr->usec, + pHdr->dir == PKT_DIR_TX ? "Tx" : "Rx", + stp_get_dbg_type_string(pType, pHdr->type), + pHdr->no, pHdr->len, pHdr->seq, + pHdr->ack, pHdr->l_sec, pHdr->l_nsec); + + if (len > 0) + stp_dbg_dump_data(pBuf, pHdr->dir == PKT_DIR_TX ? "Tx" : "Rx", len); + + } + vfree(queue); + logsys->dump_queue = NULL; +} + +INT32 stp_dbg_dmp_print(MTKSTP_DBG_T *stp_dbg) +{ +#define MAX_DMP_NUM 80 + ULONG flags; + UINT32 dumpSize = 0; + UINT32 inIndex = 0; + UINT32 outIndex = 0; + MTKSTP_LOG_ENTRY_T *dump_queue = NULL; + MTKSTP_LOG_ENTRY_T *queue = stp_dbg->logsys->queue; + + spin_lock_irqsave(&(stp_dbg->logsys->lock), flags); + if (stp_dbg->logsys->dump_queue != NULL) { + spin_unlock_irqrestore(&(stp_dbg->logsys->lock), flags); + return 0; + } + + stp_dbg->logsys->dump_queue = (MTKSTP_LOG_ENTRY_T *)STP_MAGIC_NUM; + spin_unlock_irqrestore(&(stp_dbg->logsys->lock), flags); + + /* allocate memory may take long time, thus allocate it before get lock */ + dump_queue = vmalloc(sizeof(MTKSTP_LOG_ENTRY_T) * MAX_DMP_NUM); + if (dump_queue == NULL) { + stp_dbg->logsys->dump_queue = NULL; + pr_info("fail to allocate memory"); + return -1; + } + + if (spin_trylock_irqsave(&(stp_dbg->logsys->lock), flags) == 0) { + stp_dbg->logsys->dump_queue = NULL; + vfree(dump_queue); + pr_info("fail to get lock"); + return -1; + } + /* Not to dequeue from loging system */ + inIndex = stp_dbg->logsys->in; + dumpSize = stp_dbg->logsys->size; + + /* chance is little but still needs to check */ + if (dumpSize == 0) { + stp_dbg->logsys->dump_queue = NULL; + spin_unlock_irqrestore(&(stp_dbg->logsys->lock), flags); + vfree(dump_queue); + return 0; + } + + if (dumpSize == STP_DBG_LOG_ENTRY_NUM) + outIndex = inIndex; + else + outIndex = ((inIndex + STP_DBG_LOG_ENTRY_NUM) - dumpSize) % STP_DBG_LOG_ENTRY_NUM; + + if (dumpSize > MAX_DMP_NUM) { + outIndex += (dumpSize - MAX_DMP_NUM); + outIndex %= STP_DBG_LOG_ENTRY_NUM; + dumpSize = MAX_DMP_NUM; + } + + stp_dbg->logsys->dump_queue = dump_queue; + stp_dbg->logsys->dump_size = dumpSize; + + /* copy content of stp_dbg->logsys->queue out, don't print log while holding */ + /* spinlock to prevent blocking other process */ + if (outIndex + dumpSize > STP_DBG_LOG_ENTRY_NUM) { + UINT32 tailNum = STP_DBG_LOG_ENTRY_NUM - outIndex; + + osal_memcpy(dump_queue, &(queue[outIndex]), sizeof(MTKSTP_LOG_ENTRY_T) * tailNum); + osal_memcpy(dump_queue + tailNum, &(queue[0]), sizeof(MTKSTP_LOG_ENTRY_T) * + (dumpSize - tailNum)); + } else { + osal_memcpy(dump_queue, &(queue[outIndex]), sizeof(MTKSTP_LOG_ENTRY_T) * dumpSize); + } + + spin_unlock_irqrestore(&(stp_dbg->logsys->lock), flags); + STP_DBG_PR_INFO("loged packet size = %d, in(%d), out(%d)\n", dumpSize, inIndex, outIndex); + schedule_work(&(stp_dbg->logsys->dump_work)); + return 0; +} + +INT32 stp_dbg_dmp_out(MTKSTP_DBG_T *stp_dbg, PINT8 buf, PINT32 len) +{ + ULONG flags; + INT32 remaining = 0; + *len = 0; + spin_lock_irqsave(&(stp_dbg->logsys->lock), flags); + + if (stp_dbg->logsys->size > 0) { + if (stp_dbg->logsys->queue[stp_dbg->logsys->out].len >= STP_DBG_LOG_ENTRY_SZ) + stp_dbg->logsys->queue[stp_dbg->logsys->out].len = STP_DBG_LOG_ENTRY_SZ - 1; + memcpy(buf, &(stp_dbg->logsys->queue[stp_dbg->logsys->out].buffer[0]), + stp_dbg->logsys->queue[stp_dbg->logsys->out].len); + + (*len) = stp_dbg->logsys->queue[stp_dbg->logsys->out].len; + stp_dbg->logsys->out = + (stp_dbg->logsys->out >= (STP_DBG_LOG_ENTRY_NUM - 1)) ? + (0) : (stp_dbg->logsys->out + 1); + stp_dbg->logsys->size--; + + STP_DBG_PR_DBG("logsys size = %d, out = %d\n", stp_dbg->logsys->size, + stp_dbg->logsys->out); + } else + STP_DBG_PR_LOUD("logsys EMPTY!\n"); + + remaining = (stp_dbg->logsys->size == 0) ? (0) : (1); + + spin_unlock_irqrestore(&(stp_dbg->logsys->lock), flags); + + return remaining; +} + +INT32 stp_dbg_dmp_out_ex(PINT8 buf, PINT32 len) +{ + return stp_dbg_dmp_out(g_stp_dbg, buf, len); +} + +INT32 stp_dbg_dmp_append(MTKSTP_DBG_T *stp_dbg, PUINT8 pBuf, INT32 max_len) +{ + PUINT8 p = NULL; + UINT32 l = 0; + UINT32 i = 0; + INT32 j = 0; + ULONG flags; + UINT32 len = 0; + UINT32 dumpSize = 0; + STP_DBG_HDR_T *pHdr = NULL; + const PINT8 *pType = NULL; + + if (!pBuf || max_len < 8) { /* 8: length of "\n" */ + STP_DBG_PR_WARN("invalid param, pBuf:%p, max_len:%d\n", pBuf, max_len); + return 0; + } + + pType = wmt_detect_get_chip_type() == WMT_CHIP_TYPE_COMBO ? + comboStpDbgType : socStpDbgType; + spin_lock_irqsave(&(stp_dbg->logsys->lock), flags); + /* Not to dequeue from loging system */ + dumpSize = stp_dbg->logsys->size; + j = stp_dbg->logsys->in; + + /* format */ + len += osal_sprintf(pBuf, "\n" + */ + if ((len + 53 + 3 * l + 4) > max_len) + break; + + pHdr = (STP_DBG_HDR_T *) &(stp_dbg->logsys->queue[j].buffer[0]); + p = (PUINT8)pHdr + sizeof(STP_DBG_HDR_T); + + len += osal_sprintf(pBuf + len, "\t%llu.%06lus, %s:pT%sn(%d)l(%4d)s(%d)a(%d)\t", + pHdr->l_sec, pHdr->l_nsec, + pHdr->dir == PKT_DIR_TX ? "Tx" : "Rx", + stp_get_dbg_type_string(pType, pHdr->type), + pHdr->no, pHdr->len, pHdr->seq, + pHdr->ack); + + for (i = 0; i < l; i++, p++) + len += osal_sprintf(pBuf + len, " %02x", *p, 3); + + pBuf[len] = '\n'; + len += 1; + + dumpSize--; + } + + len += osal_sprintf(pBuf + len, "-->\n"); + + spin_unlock_irqrestore(&(stp_dbg->logsys->lock), flags); + + return len; +} + +static _osal_inline_ INT32 stp_dbg_get_avl_entry_num(MTKSTP_DBG_T *stp_dbg) +{ + if (stp_dbg->logsys->size == 0) + return STP_DBG_LOG_ENTRY_NUM; + else + return (stp_dbg->logsys->in > stp_dbg->logsys->out) ? + (STP_DBG_LOG_ENTRY_NUM - stp_dbg->logsys->in + stp_dbg->logsys->out) : + (stp_dbg->logsys->out - stp_dbg->logsys->in); +} + +static _osal_inline_ INT32 stp_dbg_fill_hdr(STP_DBG_HDR_T *hdr, INT32 type, INT32 ack, INT32 seq, + INT32 crc, INT32 dir, INT32 len, INT32 dbg_type) +{ + + struct timeval now; + UINT64 ts; + ULONG nsec; + + if (!hdr) { + STP_DBG_PR_ERR("function invalid\n"); + return -EINVAL; + } + + osal_do_gettimeofday(&now); + osal_get_local_time(&ts, &nsec); + hdr->last_dbg_type = gStpDbgDumpType; + gStpDbgDumpType = dbg_type; + hdr->dbg_type = dbg_type; + hdr->ack = ack; + hdr->seq = seq; + hdr->sec = now.tv_sec; + hdr->usec = now.tv_usec; + hdr->crc = crc; + hdr->dir = dir; /* rx */ + hdr->dmy = 0xffffffff; + hdr->len = len; + hdr->type = type; + hdr->l_sec = ts; + hdr->l_nsec = nsec; + return 0; +} + +static _osal_inline_ INT32 stp_dbg_add_pkt(MTKSTP_DBG_T *stp_dbg, STP_DBG_HDR_T *hdr, const PUINT8 body) +{ + /* fix the frame size large issues. */ + static STP_PACKET_T stp_pkt; + UINT32 hdr_sz = sizeof(struct stp_dbg_pkt_hdr); + UINT32 body_sz = 0; + ULONG flags; + UINT32 avl_num; + + if (hdr->dbg_type == STP_DBG_PKT) + body_sz = (hdr->len <= STP_PKT_SZ) ? (hdr->len) : (STP_PKT_SZ); + else + body_sz = (hdr->len <= STP_DMP_SZ) ? (hdr->len) : (STP_DMP_SZ); + + hdr->no = stp_dbg->pkt_trace_no++; + memcpy((PUINT8) &stp_pkt.hdr, (PUINT8) hdr, hdr_sz); + if (body != NULL) + memcpy((PUINT8) &stp_pkt.raw[0], body, body_sz); + + if (hdr->dbg_type == STP_DBG_FW_DMP) { + if (hdr->last_dbg_type != STP_DBG_FW_DMP) { + + STP_DBG_PR_INFO + ("reset stp_dbg logsys when queue fw coredump package(%d)\n", + hdr->last_dbg_type); + STP_DBG_PR_INFO("dump 1st fw coredump package len(%d) for confirming\n", + hdr->len); + spin_lock_irqsave(&(stp_dbg->logsys->lock), flags); + stp_dbg->logsys->in = 0; + stp_dbg->logsys->out = 0; + stp_dbg->logsys->size = 0; + spin_unlock_irqrestore(&(stp_dbg->logsys->lock), flags); + } else { + avl_num = stp_dbg_get_avl_entry_num(stp_dbg); + + if (!avl_num) + STP_DBG_PR_ERR("there is no avl entry stp_dbg logsys!!!\n"); + } + } + stp_dbg_dmp_in(stp_dbg, (PINT8) &stp_pkt, hdr_sz + body_sz); + /* Only FW DMP MSG should inform BTM-CORE to dump packet to native process */ + if (hdr->dbg_type == STP_DBG_FW_DMP) + stp_dbg_notify_btm_dmp_wq(stp_dbg); + + return 0; +} + +INT32 stp_dbg_log_pkt(MTKSTP_DBG_T *stp_dbg, INT32 dbg_type, + INT32 type, INT32 ack_no, INT32 seq_no, INT32 crc, INT32 dir, INT32 len, + const PUINT8 body) +{ + STP_DBG_HDR_T hdr; + + osal_bug_on(!stp_dbg); + + if (!stp_dbg) + return -1; + + if (stp_dbg->is_enable == 0) { + /*dbg is disable,and not to log */ + } else { + hdr.no = 0; + hdr.chs = 0; + stp_dbg_fill_hdr(&hdr, + (INT32) type, + (INT32) ack_no, + (INT32) seq_no, (INT32) crc, (INT32) dir, (INT32) len, + (INT32) dbg_type); + + stp_dbg_add_pkt(stp_dbg, &hdr, body); + } + + return 0; +} + +INT32 stp_dbg_log_ctrl(UINT32 on) +{ + if (on != 0) { + gStpDbgLogOut = 1; + pr_warn("STP-DBG: enable pkt log dump out.\n"); + } else { + gStpDbgLogOut = 0; + pr_warn("STP-DBG: disable pkt log dump out.\n"); + } + + return 0; +} + +VOID stp_dbg_nl_init(VOID) +{ +#if 0 + if (genl_register_family(&stp_dbg_gnl_family) != 0) { + STP_DBG_PR_ERR("%s(): GE_NELINK family registration fail\n", __func__); + } else { + if (genl_register_ops(&stp_dbg_gnl_family, &stp_dbg_gnl_ops_bind) != 0) + STP_DBG_PR_ERR("%s(): BIND operation registration fail\n", __func__); + + if (genl_register_ops(&stp_dbg_gnl_family, &stp_dbg_gnl_ops_reset) != 0) + STP_DBG_PR_ERR("%s(): RESET operation registration fail\n", __func__); + + } +#endif + osal_sleepable_lock_init(&g_dbg_nl_lock); + if (genl_register_family(&stp_dbg_gnl_family) != 0) + STP_DBG_PR_ERR("%s(): GE_NELINK family registration fail\n", __func__); +} + +VOID stp_dbg_nl_deinit(VOID) +{ + int i; + + num_bind_process = 0; + for (i = 0; i < MAX_BIND_PROCESS; i++) + bind_pid[i] = 0; + genl_unregister_family(&stp_dbg_gnl_family); + osal_sleepable_lock_deinit(&g_dbg_nl_lock); +} + +static INT32 stp_dbg_nl_bind(struct sk_buff *skb, struct genl_info *info) +{ + struct nlattr *na = NULL; + PINT8 mydata; + INT32 i; + + if (info == NULL) + goto out; + + STP_DBG_PR_INFO("%s():->\n", __func__); + + na = info->attrs[STP_DBG_ATTR_MSG]; + + if (na) + mydata = (PINT8) nla_data(na); + + if (osal_lock_sleepable_lock(&g_dbg_nl_lock)) + return -1; + + for (i = 0; i < MAX_BIND_PROCESS; i++) { + if (bind_pid[i] == 0) { + bind_pid[i] = info->snd_portid; + num_bind_process++; + STP_DBG_PR_INFO("%s():-> pid = %d\n", __func__, info->snd_portid); + break; + } + } + + if (i == MAX_BIND_PROCESS) { + STP_DBG_PR_ERR("%s(): exceeding binding limit %d\n", __func__, MAX_BIND_PROCESS); + bind_pid[0] = info->snd_portid; + } + + osal_unlock_sleepable_lock(&g_dbg_nl_lock); + +out: + return 0; +} + +static INT32 stp_dbg_nl_reset(struct sk_buff *skb, struct genl_info *info) +{ + STP_DBG_PR_ERR("%s(): should not be invoked\n", __func__); + + return 0; +} + +INT32 stp_dbg_nl_send(PINT8 aucMsg, UINT8 cmd, INT32 len) +{ + struct sk_buff *skb = NULL; + PVOID msg_head = NULL; + INT32 rc = -1; + INT32 i, j; + INT32 ret = 0; + INT32 killed_num = 0; + + if (num_bind_process == 0) { + /* no listening process */ + STP_DBG_PR_ERR("%s(): the process is not invoked\n", __func__); + return 0; + } + + ret = stp_dbg_core_dump_nl(g_core_dump, aucMsg, len); + if (ret < 0) + return ret; + if (ret == 32) + return ret; + + ret = -1; + for (i = 0; i < num_bind_process; i++) { + if (bind_pid[i] == 0) { + killed_num++; + continue; + } + + skb = genlmsg_new(2048, GFP_KERNEL); + if (skb) { + msg_head = genlmsg_put(skb, 0, stp_dbg_seqnum++, &stp_dbg_gnl_family, 0, cmd); + if (msg_head == NULL) { + nlmsg_free(skb); + STP_DBG_PR_ERR("%s(): genlmsg_put fail...\n", __func__); + return -1; + } + + rc = nla_put(skb, STP_DBG_ATTR_MSG, len, aucMsg); + if (rc != 0) { + nlmsg_free(skb); + STP_DBG_PR_ERR("%s(): nla_put_string fail...: %d\n", __func__, rc); + return rc; + } + + /* finalize the message */ + genlmsg_end(skb, msg_head); + + /* sending message */ + rc = genlmsg_unicast(&init_net, skb, bind_pid[i]); + if (rc != 0) { + STP_DBG_PR_INFO("%s(): genlmsg_unicast fail...: %d pid: %d\n", + __func__, rc, bind_pid[i]); + if (rc == -ECONNREFUSED) { + bind_pid[i] = 0; + killed_num++; + } + } else { + /* don't retry as long as at least one process receives data */ + ret = 0; + } + } else { + STP_DBG_PR_ERR("%s(): genlmsg_new fail...\n", __func__); + } + } + + if (killed_num > 0) { + if (osal_lock_sleepable_lock(&g_dbg_nl_lock)) { + /* if fail to get lock, it is fine to update bind_pid[] later */ + return ret; + } + + for (i = 0; i < num_bind_process - killed_num; i++) { + if (bind_pid[i] == 0) { + for (j = num_bind_process - 1; j > i; j--) { + if (bind_pid[j] > 0) { + bind_pid[i] = bind_pid[j]; + bind_pid[j] = 0; + } + } + } + } + num_bind_process -= killed_num; + osal_unlock_sleepable_lock(&g_dbg_nl_lock); + } + + return ret; +} + +INT32 stp_dbg_dump_send_retry_handler(PINT8 tmp, INT32 len) +{ + INT32 ret = 0; + INT32 nl_retry = 0; + + if (tmp == NULL) + return -1; + + ret = stp_dbg_nl_send(tmp, 2, len+5); + while (ret) { + nl_retry++; + if (ret == 32) { + STP_DBG_PR_ERR("**dump send timeout : %d**\n", ret); + ret = 1; + break; + } + if (nl_retry > 1000) { + STP_DBG_PR_ERR("**dump send fails, and retry more than 1000: %d.**\n", ret); + ret = 2; + break; + } + STP_DBG_PR_WARN("**dump send fails, and retry again.**\n"); + osal_sleep_ms(3); + ret = stp_dbg_nl_send(tmp, 2, len+5); + if (!ret) + STP_DBG_PR_DBG("****retry again ok!**\n"); + } + + return ret; +} + +INT32 stp_dbg_aee_send(PUINT8 aucMsg, INT32 len, INT32 cmd) +{ +#define KBYTES (1024*sizeof(char)) +#ifndef LOG_STP_DEBUG_DISABLE +#define L1_BUF_SIZE (32*KBYTES) +#define PKT_MULTIPLIER 18 +#else +#define L1_BUF_SIZE (4*KBYTES) +#define PKT_MULTIPLIER 1 +#endif + INT32 ret = 0; + + if (g_core_dump->count == 0) { + g_core_dump->compressor = stp_dbg_compressor_init("core_dump_compressor", + L1_BUF_SIZE, + PKT_MULTIPLIER*g_core_dump->dmp_num*KBYTES); + g_core_dump->count++; + if (!g_core_dump->compressor) { + STP_DBG_PR_ERR("create compressor failed!\n"); + stp_dbg_compressor_deinit(g_core_dump->compressor); + return -1; + } + } + /* buffered to compressor */ + ret = stp_dbg_core_dump_in(g_core_dump, aucMsg, len); + if (ret == 1 && wmt_detect_get_chip_type() == WMT_CHIP_TYPE_COMBO) + stp_dbg_core_dump_flush(0, MTK_WCN_BOOL_FALSE); + + return ret; +} + +INT32 stp_dbg_dump_num(LONG dmp_num) +{ + g_core_dump->dmp_num = dmp_num; + return 0; +} + +static _osal_inline_ INT32 stp_dbg_parser_assert_str(PINT8 str, ENUM_ASSERT_INFO_PARSER_TYPE type) +{ +#define WDT_INFO_HEAD "Watch Dog Timeout" + PINT8 pStr = NULL; + PINT8 pDtr = NULL; + PINT8 pTemp = NULL; + PINT8 pTemp2 = NULL; + INT8 tempBuf[STP_ASSERT_TYPE_SIZE] = { 0 }; + UINT32 len = 0; + LONG res; + INT32 ret; + INT32 remain_array_len = 0; + + PUINT8 parser_sub_string[] = { + "{ASSERT} ", + "id=", + "isr=", + "irq=", + "rc=" + }; + + if (!str) { + STP_DBG_PR_ERR("NULL string source\n"); + return -1; + } + + if (!g_stp_dbg_cpupcr) { + STP_DBG_PR_ERR("NULL pointer\n"); + return -2; + } + + pStr = str; + STP_DBG_PR_DBG("source infor:%s\n", pStr); + switch (type) { + case STP_DBG_ASSERT_INFO: + + + pDtr = osal_strstr(pStr, parser_sub_string[type]); + if (pDtr != NULL) { + pDtr += osal_strlen(parser_sub_string[type]); + pTemp = osal_strchr(pDtr, ' '); + } else { + STP_DBG_PR_ERR("parser str is NULL,substring(%s)\n", parser_sub_string[type]); + return -3; + } + + if (pTemp == NULL) { + STP_DBG_PR_ERR("delimiter( ) is not found,substring(%s)\n", + parser_sub_string[type]); + return -4; + } + + len = pTemp - pDtr; + osal_memcpy(&g_stp_dbg_cpupcr->assert_info[0], "assert@", osal_strlen("assert@")); + osal_memcpy(&g_stp_dbg_cpupcr->assert_info[osal_strlen("assert@")], pDtr, len); + g_stp_dbg_cpupcr->assert_info[osal_strlen("assert@") + len] = '_'; + + pTemp = osal_strchr(pDtr, '#'); + if (pTemp == NULL) { + STP_DBG_PR_ERR("parser '#' is not find\n"); + return -5; + } + pTemp += 1; + + pTemp2 = osal_strchr(pTemp, ' '); + if (pTemp2 == NULL) { + STP_DBG_PR_ERR("parser ' ' is not find\n"); + pTemp2 = pTemp + 1; + } + remain_array_len = osal_array_size(g_stp_dbg_cpupcr->assert_info) - (osal_strlen("assert@") + len + 1); + if (remain_array_len - 1 > pTemp2 - pTemp) { + osal_memcpy(&g_stp_dbg_cpupcr->assert_info[osal_strlen("assert@") + len + 1], pTemp, + pTemp2 - pTemp); + g_stp_dbg_cpupcr->assert_info[osal_strlen("assert@") + len + 1 + pTemp2 - pTemp] = '\0'; + } else { + osal_memcpy(&g_stp_dbg_cpupcr->assert_info[osal_strlen("assert@") + len + 1], pTemp, + remain_array_len - 1); + g_stp_dbg_cpupcr->assert_info[STP_ASSERT_INFO_SIZE - 1] = '\0'; + } + STP_DBG_PR_INFO("assert info:%s\n", &g_stp_dbg_cpupcr->assert_info[0]); + break; + case STP_DBG_FW_TASK_ID: + pDtr = osal_strstr(pStr, parser_sub_string[type]); + if (pDtr != NULL) { + pDtr += osal_strlen(parser_sub_string[type]); + pTemp = osal_strchr(pDtr, ' '); + } else { + STP_DBG_PR_ERR("parser str is NULL,substring(%s)\n", parser_sub_string[type]); + return -3; + } + + if (pTemp == NULL) { + STP_DBG_PR_ERR("delimiter( ) is not found,substring(%s)\n", + parser_sub_string[type]); + return -4; + } + + len = pTemp - pDtr; + len = (len >= STP_ASSERT_TYPE_SIZE) ? STP_ASSERT_TYPE_SIZE - 1 : len; + osal_memcpy(&tempBuf[0], pDtr, len); + tempBuf[len] = '\0'; + ret = osal_strtol(tempBuf, 16, &res); + if (ret) { + STP_DBG_PR_ERR("get fw task id fail(%d)\n", ret); + return -4; + } + g_stp_dbg_cpupcr->fwTaskId = (UINT32)res; + + STP_DBG_PR_INFO("fw task id :%x\n", (UINT32)res); + break; + case STP_DBG_FW_ISR: + pDtr = osal_strstr(pStr, parser_sub_string[type]); + + if (pDtr != NULL) { + pDtr += osal_strlen(parser_sub_string[type]); + pTemp = osal_strchr(pDtr, ','); + } else { + STP_DBG_PR_ERR("parser str is NULL,substring(%s)\n", + parser_sub_string[type]); + return -3; + } + + if (pTemp == NULL) { + STP_DBG_PR_ERR("delimiter(,) is not found,substring(%s)\n", + parser_sub_string[type]); + return -4; + } + + len = pTemp - pDtr; + len = (len >= STP_ASSERT_TYPE_SIZE) ? STP_ASSERT_TYPE_SIZE - 1 : len; + osal_memcpy(&tempBuf[0], pDtr, len); + tempBuf[len] = '\0'; + ret = osal_strtol(tempBuf, 16, &res); + if (ret) { + STP_DBG_PR_ERR("get fw isr id fail(%d)\n", ret); + return -4; + } + g_stp_dbg_cpupcr->fwIsr = (UINT32)res; + + STP_DBG_PR_INFO("fw isr str:%x\n", (UINT32)res); + break; + case STP_DBG_FW_IRQ: + pDtr = osal_strstr(pStr, parser_sub_string[type]); + if (pDtr != NULL) { + pDtr += osal_strlen(parser_sub_string[type]); + pTemp = osal_strchr(pDtr, ','); + } else { + STP_DBG_PR_ERR("parser str is NULL,substring(%s)\n", parser_sub_string[type]); + return -3; + } + + if (pTemp == NULL) { + STP_DBG_PR_ERR("delimiter(,) is not found,substring(%s)\n", + parser_sub_string[type]); + return -4; + } + + len = pTemp - pDtr; + len = (len >= STP_ASSERT_TYPE_SIZE) ? STP_ASSERT_TYPE_SIZE - 1 : len; + osal_memcpy(&tempBuf[0], pDtr, len); + tempBuf[len] = '\0'; + ret = osal_strtol(tempBuf, 16, &res); + if (ret) { + STP_DBG_PR_ERR("get fw irq id fail(%d)\n", ret); + return -4; + } + g_stp_dbg_cpupcr->fwRrq = (UINT32)res; + + STP_DBG_PR_INFO("fw irq value:%x\n", (UINT32)res); + break; + case STP_DBG_ASSERT_TYPE: + pDtr = osal_strstr(pStr, parser_sub_string[type]); + if (pDtr != NULL) { + pDtr += osal_strlen(parser_sub_string[type]); + pTemp = osal_strchr(pDtr, ','); + } else { + STP_DBG_PR_ERR("parser str is NULL,substring(%s)\n", parser_sub_string[type]); + return -3; + } + + if (pTemp == NULL) { + STP_DBG_PR_ERR("delimiter(,) is not found,substring(%s)\n", + parser_sub_string[type]); + return -4; + } + + len = pTemp - pDtr; + len = (len >= STP_ASSERT_TYPE_SIZE) ? STP_ASSERT_TYPE_SIZE - 1 : len; + osal_memcpy(&tempBuf[0], pDtr, len); + tempBuf[len] = '\0'; + + if (osal_memcmp(tempBuf, "*", osal_strlen("*")) == 0) + osal_memcpy(&g_stp_dbg_cpupcr->assert_type[0], "general assert", + osal_strlen("general assert")); + if (osal_memcmp(tempBuf, WDT_INFO_HEAD, osal_strlen(WDT_INFO_HEAD)) == 0) + osal_memcpy(&g_stp_dbg_cpupcr->assert_type[0], "wdt", osal_strlen("wdt")); + if (osal_memcmp(tempBuf, "RB_FULL", osal_strlen("RB_FULL")) == 0) { + osal_memcpy(&g_stp_dbg_cpupcr->assert_type[0], tempBuf, len); + + pDtr = osal_strstr(&g_stp_dbg_cpupcr->assert_type[0], "RB_FULL("); + if (pDtr != NULL) { + pDtr += osal_strlen("RB_FULL("); + pTemp = osal_strchr(pDtr, ')'); + } else { + STP_DBG_PR_ERR("parser str is NULL,substring(RB_FULL()\n"); + return -5; + } + len = pTemp - pDtr; + len = (len >= STP_ASSERT_TYPE_SIZE) ? STP_ASSERT_TYPE_SIZE - 1 : len; + osal_memcpy(&tempBuf[0], pDtr, len); + tempBuf[len] = '\0'; + ret = osal_strtol(tempBuf, 16, &res); + if (ret) { + STP_DBG_PR_ERR("get fw task id fail(%d)\n", ret); + return -5; + } + g_stp_dbg_cpupcr->fwTaskId = (UINT32)res; + + STP_DBG_PR_INFO("update fw task id :%x\n", (UINT32)res); + } + + STP_DBG_PR_INFO("fw asert type:%s\n", g_stp_dbg_cpupcr->assert_type); + break; + default: + STP_DBG_PR_ERR("unknown parser type\n"); + break; + } + + return 0; +} + +static _osal_inline_ P_STP_DBG_CPUPCR_T stp_dbg_cpupcr_init(VOID) +{ + P_STP_DBG_CPUPCR_T pSdCpupcr = NULL; + + pSdCpupcr = (P_STP_DBG_CPUPCR_T) osal_malloc(osal_sizeof(STP_DBG_CPUPCR_T)); + if (!pSdCpupcr) { + STP_DBG_PR_ERR("stp dbg cpupcr allocate memory fail!\n"); + return NULL; + } + + osal_memset(pSdCpupcr, 0, osal_sizeof(STP_DBG_CPUPCR_T)); + + osal_sleepable_lock_init(&pSdCpupcr->lock); + + return pSdCpupcr; +} + +static _osal_inline_ VOID stp_dbg_cpupcr_deinit(P_STP_DBG_CPUPCR_T pCpupcr) +{ + if (pCpupcr) { + osal_sleepable_lock_deinit(&pCpupcr->lock); + osal_free(pCpupcr); + pCpupcr = NULL; + } +} + +static _osal_inline_ P_STP_DBG_DMAREGS_T stp_dbg_dmaregs_init(VOID) +{ + P_STP_DBG_DMAREGS_T pDmaRegs = NULL; + + pDmaRegs = (P_STP_DBG_DMAREGS_T) osal_malloc(osal_sizeof(STP_DBG_DMAREGS_T)); + if (!pDmaRegs) { + STP_DBG_PR_ERR("stp dbg dmareg allocate memory fail!\n"); + return NULL; + } + + osal_memset(pDmaRegs, 0, osal_sizeof(STP_DBG_DMAREGS_T)); + + osal_sleepable_lock_init(&pDmaRegs->lock); + + return pDmaRegs; +} + +static VOID stp_dbg_dmaregs_deinit(P_STP_DBG_DMAREGS_T pDmaRegs) +{ + if (pDmaRegs) { + osal_sleepable_lock_deinit(&pDmaRegs->lock); + osal_free(pDmaRegs); + pDmaRegs = NULL; + } +} + +/* + * who call this ? + * - stp_dbg_soc_paged_dump + * generate coredump and coredump timeout + * - wmt_dbg_poll_cpupcr + * dump cpupcr through command + * - mtk_stp_dbg_poll_cpupcr (should remove this) + * export to other drivers + * - _stp_btm_handler + * coredump timeout + * - wmt_ctrl_rx + * rx timeout + * - stp_do_tx_timeout + * tx timeout + * + */ +INT32 stp_dbg_poll_cpupcr(UINT32 times, UINT32 sleep, UINT32 cmd) +{ + INT32 i = 0; + UINT32 value = 0x0; + ENUM_WMT_CHIP_TYPE chip_type; + UINT8 cccr_value = 0x0; + INT32 chip_id = -1; + INT32 i_ret = 0; + INT32 count = 0; + + if (!g_stp_dbg_cpupcr) { + STP_DBG_PR_ERR("NULL reference pointer\n"); + return -1; + } + + chip_type = wmt_detect_get_chip_type(); + + if (times > STP_DBG_CPUPCR_NUM) + times = STP_DBG_CPUPCR_NUM; + + switch (chip_type) { + case WMT_CHIP_TYPE_COMBO: + osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); + for (i = 0; i < times; i++) { + stp_sdio_rw_retry(HIF_TYPE_READL, STP_SDIO_RETRY_LIMIT, + g_stp_sdio_host_info.sdio_cltctx, SWPCDBGR, &value, 0); + g_stp_dbg_cpupcr->buffer[g_stp_dbg_cpupcr->count] = value; + osal_get_local_time(&(g_stp_dbg_cpupcr->sec_buffer[g_stp_dbg_cpupcr->count]), + &(g_stp_dbg_cpupcr->nsec_buffer[g_stp_dbg_cpupcr->count])); + if (sleep > 0) + osal_sleep_ms(sleep); + g_stp_dbg_cpupcr->count++; + if (g_stp_dbg_cpupcr->count >= STP_DBG_CPUPCR_NUM) + g_stp_dbg_cpupcr->count = 0; + } + osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); + break; + case WMT_CHIP_TYPE_SOC: + if (times > WMT_CORE_DMP_CPUPCR_NUM) + times = WMT_CORE_DMP_CPUPCR_NUM; + if (wmt_lib_dmp_consys_state(&g_dmp_info, times, sleep) == MTK_WCN_BOOL_TRUE) { + osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); + for (i = 0; i < times; i++) { + g_stp_dbg_cpupcr->buffer[g_stp_dbg_cpupcr->count] = g_dmp_info.cpu_pcr[i]; + osal_get_local_time(&(g_stp_dbg_cpupcr->sec_buffer[g_stp_dbg_cpupcr->count]), + &(g_stp_dbg_cpupcr->nsec_buffer[g_stp_dbg_cpupcr->count])); + g_stp_dbg_cpupcr->count++; + if (g_stp_dbg_cpupcr->count >= STP_DBG_CPUPCR_NUM) + g_stp_dbg_cpupcr->count = 0; + } + osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); + } + break; + default: + STP_DBG_PR_INFO("error chip type(%d)\n", chip_type); + } + + if (cmd) { + UINT8 str[DBG_LOG_STR_SIZE] = {""}; + PUINT8 p = str; + INT32 str_len = 0; + + for (i = 0; i < STP_DBG_CPUPCR_NUM; i++) { + if (g_stp_dbg_cpupcr->sec_buffer[i] == 0 && + g_stp_dbg_cpupcr->nsec_buffer[i] == 0) + continue; + + count++; + if (count % 4 != 0) { + str_len = osal_sprintf(p, "%llu.%06lu/0x%08x;", + g_stp_dbg_cpupcr->sec_buffer[i], + g_stp_dbg_cpupcr->nsec_buffer[i], + g_stp_dbg_cpupcr->buffer[i]); + p += str_len; + } else { + str_len = osal_sprintf(p, "%llu.%06lu/0x%08x;", + g_stp_dbg_cpupcr->sec_buffer[i], + g_stp_dbg_cpupcr->nsec_buffer[i], + g_stp_dbg_cpupcr->buffer[i]); + STP_DBG_PR_INFO("TIME/CPUPCR: %s\n", str); + p = str; + } + } + if (count % 4 != 0) + STP_DBG_PR_INFO("TIME/CPUPCR: %s\n", str); + + if (wmt_lib_power_lock_trylock()) { + if (chip_type == WMT_CHIP_TYPE_SOC && wmt_lib_reg_readable()) { + STP_DBG_PR_INFO("CONNSYS cpu:0x%x/bus:0x%x/dbg_cr1:0x%x/dbg_cr2:0x%x/EMIaddr:0x%x\n", + stp_dbg_soc_read_debug_crs(CONNSYS_CPU_CLK), + stp_dbg_soc_read_debug_crs(CONNSYS_BUS_CLK), + stp_dbg_soc_read_debug_crs(CONNSYS_DEBUG_CR1), + stp_dbg_soc_read_debug_crs(CONNSYS_DEBUG_CR2), + stp_dbg_soc_read_debug_crs(CONNSYS_EMI_REMAP)); + } + wmt_lib_power_lock_release(); + } + + chip_id = mtk_wcn_wmt_chipid_query(); + if (chip_id == 0x6632) { + for (i = 0; i < 8; i++) { + i_ret = mtk_wcn_hif_sdio_f0_readb(g_stp_sdio_host_info.sdio_cltctx, + CCCR_F8 + i, &cccr_value); + if (i_ret) + STP_DBG_PR_ERR("read CCCR fail(%d), address(0x%x)\n", + i_ret, CCCR_F8 + i); + else + STP_DBG_PR_INFO("read CCCR value(0x%x), address(0x%x)\n", + cccr_value, CCCR_F8 + i); + cccr_value = 0x0; + } + } + /* Need in platform code - mtxxxx.c to provide function implementation */ + mtk_wcn_consys_hang_debug(); + } + if (chip_type == WMT_CHIP_TYPE_COMBO) { + STP_DBG_PR_INFO("dump sdio register for debug\n"); + mtk_stp_dump_sdio_register(); + } + return 0; +} + +INT32 stp_dbg_dump_cpupcr_reg_info(PUINT8 buf, UINT32 consys_lp_reg) +{ + INT32 i = 0; + INT32 count = 0; + UINT32 len = 0; + + /* never retrun negative value */ + if (!g_stp_dbg_cpupcr || !buf) { + STP_DBG_PR_DBG("NULL pointer, g_stp_dbg_cpupcr:%p, buf:%p\n", + g_stp_dbg_cpupcr, buf); + return 0; + } + + for (i = 0; i < STP_DBG_CPUPCR_NUM; i++) { + if (g_stp_dbg_cpupcr->sec_buffer[i] == 0 && + g_stp_dbg_cpupcr->nsec_buffer[i] == 0) + continue; + count++; + if (count == 1) + len += osal_sprintf(buf + len, "0x%08x", g_stp_dbg_cpupcr->buffer[i]); + else + len += osal_sprintf(buf + len, ";0x%08x", g_stp_dbg_cpupcr->buffer[i]); + } + + if (count == 0) + len += osal_sprintf(buf + len, "0x%08x\n", consys_lp_reg); + else + len += osal_sprintf(buf + len, ";0x%08x\n", consys_lp_reg); + + stp_dbg_clear_cpupcr_reg_info(); + + return len; +} + +VOID stp_dbg_clear_cpupcr_reg_info(VOID) +{ + if (osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock)) { + STP_DBG_PR_DBG("lock failed\n"); + return; + } + + osal_memset(&g_stp_dbg_cpupcr->buffer[0], 0, STP_DBG_CPUPCR_NUM); + g_stp_dbg_cpupcr->count = 0; + g_stp_dbg_cpupcr->host_assert_info.reason = 0; + g_stp_dbg_cpupcr->host_assert_info.drv_type = 0; + g_stp_dbg_cpupcr->issue_type = STP_FW_ISSUE_TYPE_INVALID; + g_stp_dbg_cpupcr->keyword[0] = '\0'; + osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); +} + +INT32 stp_dbg_poll_dmaregs(UINT32 times, UINT32 sleep) +{ +#if 0 + INT32 i = 0; + + if (!g_stp_dbg_dmaregs) { + STP_DBG_PR_ERR("NULL reference pointer\n"); + return -1; + } + + osal_lock_sleepable_lock(&g_stp_dbg_dmaregs->lock); + + if (g_stp_dbg_dmaregs->count + times > STP_DBG_DMAREGS_NUM) { + if (g_stp_dbg_dmaregs->count > STP_DBG_DMAREGS_NUM) { + STP_DBG_PR_ERR("g_stp_dbg_dmaregs->count:%d must less than STP_DBG_DMAREGS_NUM:%d\n", + g_stp_dbg_dmaregs->count, STP_DBG_DMAREGS_NUM); + g_stp_dbg_dmaregs->count = 0; + STP_DBG_PR_ERR("g_stp_dbg_dmaregs->count be set default value 0\n"); + } + times = STP_DBG_DMAREGS_NUM - g_stp_dbg_dmaregs->count; + } + if (times > STP_DBG_DMAREGS_NUM) { + STP_DBG_PR_ERR("times overflow, set default value:0\n"); + times = 0; + } + + for (i = 0; i < times; i++) { + INT32 k = 0; + + for (; k < DMA_REGS_MAX; k++) { + STP_DBG_PR_INFO("times:%d,i:%d reg: %s, regs:%08x\n", times, i, dmaRegsStr[k], + wmt_plat_read_dmaregs(k)); + /* g_stp_dbg_dmaregs->dmaIssue[k][g_stp_dbg_dmaregs->count + i] = + * wmt_plat_read_dmaregs(k); + */ + } + osal_sleep_ms(sleep); + } + + g_stp_dbg_dmaregs->count += times; + + osal_unlock_sleepable_lock(&g_stp_dbg_dmaregs->lock); +#else + return 0; +#endif +} + +INT32 stp_dbg_poll_cpupcr_ctrl(UINT32 en) +{ + STP_DBG_PR_INFO("%s polling cpupcr\n", en == 0 ? "start" : "stop"); + + osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); + g_stp_dbg_cpupcr->stop_flag = en; + osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); + + return 0; +} + +INT32 stp_dbg_set_version_info(UINT32 chipid, PUINT8 pRomVer, PUINT8 pPatchVer, PUINT8 pPatchBrh) +{ + if (g_stp_dbg_cpupcr) { + osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); + g_stp_dbg_cpupcr->chipId = chipid; + + if (pRomVer) + osal_memcpy(g_stp_dbg_cpupcr->romVer, pRomVer, 2); + if (pPatchVer) + osal_memcpy(g_stp_dbg_cpupcr->patchVer, pPatchVer, 8); + if (pPatchBrh) + osal_memcpy(g_stp_dbg_cpupcr->branchVer, pPatchBrh, 4); + + osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); + } else { + STP_DBG_PR_ERR("NULL pointer\n"); + return -1; + } + + STP_DBG_PR_DBG("chipid(0x%x),romver(%s),patchver(%s),branchver(%s)\n", + g_stp_dbg_cpupcr->chipId, + &g_stp_dbg_cpupcr->romVer[0], + &g_stp_dbg_cpupcr->patchVer[0], + &g_stp_dbg_cpupcr->branchVer[0]); + + return 0; +} + +INT32 stp_dbg_set_wifiver(UINT32 wifiver) +{ + if (!g_stp_dbg_cpupcr) { + STP_DBG_PR_ERR("NULL pointer\n"); + return -1; + } + + osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); + g_stp_dbg_cpupcr->wifiVer = wifiver; + osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); + + STP_DBG_PR_INFO("wifiver(%x)\n", g_stp_dbg_cpupcr->wifiVer); + + return 0; +} + +INT32 stp_dbg_set_host_assert_info(UINT32 drv_type, UINT32 reason, UINT32 en) +{ + osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); + + g_stp_dbg_cpupcr->host_assert_info.assert_from_host = en; + g_stp_dbg_cpupcr->host_assert_info.drv_type = drv_type; + g_stp_dbg_cpupcr->host_assert_info.reason = reason; + + osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); + + return 0; +} + +VOID stp_dbg_set_keyword(PINT8 keyword) +{ + osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); + if (keyword != NULL) { + if (osal_strlen(keyword) >= STP_DBG_KEYWORD_SIZE) + STP_DBG_PR_INFO("Keyword over max size(%d)\n", STP_DBG_KEYWORD_SIZE); + else if (osal_strchr(keyword, '<') != NULL || osal_strchr(keyword, '>') != NULL) + STP_DBG_PR_INFO("Keyword has < or >, keywrod: %s\n", keyword); + else + osal_strncat(&g_stp_dbg_cpupcr->keyword[0], keyword, osal_strlen(keyword)); + } else { + g_stp_dbg_cpupcr->keyword[0] = '\0'; + } + osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); +} + +UINT32 stp_dbg_get_host_trigger_assert(VOID) +{ + return g_stp_dbg_cpupcr->host_assert_info.assert_from_host; +} + +VOID stp_dbg_set_coredump_timer_state(CORE_DUMP_STA state) +{ + if (g_core_dump) + g_core_dump->sm = state; +} + +INT32 stp_dbg_get_coredump_timer_state(VOID) +{ + if (g_core_dump) + return g_core_dump->sm; + return -1; +} + +INT32 stp_dbg_set_fw_info(PUINT8 issue_info, UINT32 len, ENUM_STP_FW_ISSUE_TYPE issue_type) +{ + ENUM_ASSERT_INFO_PARSER_TYPE type_index; + PUINT8 tempbuf = NULL; + UINT32 i = 0; + INT32 iRet = 0; + + if (issue_info == NULL) { + STP_DBG_PR_ERR("null issue infor\n"); + return -1; + } + + if (g_stp_dbg_cpupcr->issue_type && + g_stp_dbg_cpupcr->issue_type != STP_HOST_TRIGGER_COLLECT_FTRACE) { + STP_DBG_PR_ERR("assert information has been set up\n"); + return -1; + } + + STP_DBG_PR_INFO("issue type(%d)\n", issue_type); + g_stp_dbg_cpupcr->issue_type = issue_type; + osal_memset(&g_stp_dbg_cpupcr->assert_info[0], 0, STP_ASSERT_INFO_SIZE); + + /*print patch version when assert happened */ + STP_DBG_PR_INFO("[consys patch]patch version:%s\n", g_stp_dbg_cpupcr->patchVer); + STP_DBG_PR_INFO("[consys patch]ALPS branch:%s\n", g_stp_dbg_cpupcr->branchVer); + + if ((issue_type == STP_FW_ASSERT_ISSUE) || + (issue_type == STP_HOST_TRIGGER_FW_ASSERT) || + (issue_type == STP_HOST_TRIGGER_ASSERT_TIMEOUT) || + (issue_type == STP_HOST_TRIGGER_COLLECT_FTRACE) || + (issue_type == STP_FW_ABT)) { + if ((issue_type == STP_FW_ASSERT_ISSUE) || (issue_type == STP_HOST_TRIGGER_FW_ASSERT) + || (issue_type == STP_FW_ABT)) { + tempbuf = osal_malloc(len + 1); + if (!tempbuf) + return -2; + + osal_memcpy(&tempbuf[0], issue_info, len); + + for (i = 0; i < len; i++) { + if (tempbuf[i] == '\0') + tempbuf[i] = '?'; + else if (tempbuf[i] == '<') + tempbuf[i] = '{'; + else if (tempbuf[i] == '>') + tempbuf[i] = '}'; + } + + tempbuf[len] = '\0'; + + for (type_index = STP_DBG_ASSERT_INFO; type_index < STP_DBG_PARSER_TYPE_MAX; + type_index++) { + iRet = stp_dbg_parser_assert_str(&tempbuf[0], type_index); + if (iRet) + STP_DBG_PR_INFO("fail to parse assert str %s, type = %d, ret = %d\n", + &tempbuf[0], type_index, iRet); + } + + } + if ((issue_type == STP_HOST_TRIGGER_FW_ASSERT) || + (issue_type == STP_HOST_TRIGGER_ASSERT_TIMEOUT) || + (issue_type == STP_HOST_TRIGGER_COLLECT_FTRACE)) { + g_stp_dbg_cpupcr->fwIsr = 0; + g_stp_dbg_cpupcr->fwRrq = 0; + + osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); + switch (g_stp_dbg_cpupcr->host_assert_info.drv_type) { + case WMTDRV_TYPE_BT: + STP_DBG_PR_INFO("BT trigger assert\n"); + if (g_stp_dbg_cpupcr->host_assert_info.reason != 31) + g_stp_dbg_cpupcr->fwTaskId = STP_DBG_TASK_BT; /*BT firmware trigger assert */ + else { + /*BT stack trigger assert */ + g_stp_dbg_cpupcr->fwTaskId = STP_DBG_TASK_NATBT; + } + break; + case WMTDRV_TYPE_FM: + STP_DBG_PR_INFO("FM trigger assert\n"); + g_stp_dbg_cpupcr->fwTaskId = STP_DBG_TASK_FM; + break; + case WMTDRV_TYPE_GPS: + STP_DBG_PR_INFO("GPS trigger assert\n"); + g_stp_dbg_cpupcr->fwTaskId = STP_DBG_TASK_DRVGPS; + break; + case WMTDRV_TYPE_GPSL5: + STP_DBG_PR_INFO("GPSL5 trigger assert\n"); + g_stp_dbg_cpupcr->fwTaskId = STP_DBG_TASK_DRVGPS; + break; + case WMTDRV_TYPE_WIFI: + STP_DBG_PR_INFO("WIFI trigger assert\n"); + g_stp_dbg_cpupcr->fwTaskId = STP_DBG_TASK_DRVWIFI; + break; + case WMTDRV_TYPE_WMT: + STP_DBG_PR_INFO("WMT trigger assert\n"); + if (issue_type == STP_HOST_TRIGGER_ASSERT_TIMEOUT) + osal_memcpy(&g_stp_dbg_cpupcr->assert_info[0], issue_info, len); + /* 30: adb trigger assert */ + /* 43: process packet fail count > 10 */ + /* 44: rx timeout with pending data */ + /* 45: tx timeout with pending data */ + if (g_stp_dbg_cpupcr->host_assert_info.reason == 30 || + g_stp_dbg_cpupcr->host_assert_info.reason == 43 || + g_stp_dbg_cpupcr->host_assert_info.reason == 44 || + g_stp_dbg_cpupcr->host_assert_info.reason == 45) + g_stp_dbg_cpupcr->fwTaskId = STP_DBG_TASK_DRVSTP; + else + g_stp_dbg_cpupcr->fwTaskId = STP_DBG_TASK_WMT; + break; + default: + break; + } + g_stp_dbg_cpupcr->host_assert_info.assert_from_host = 0; + osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); + + } else if (issue_type == STP_FW_ABT) { + INT32 copyLen = (len < STP_ASSERT_INFO_SIZE ? len : STP_ASSERT_INFO_SIZE - 1); + + osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); + osal_memcpy(&g_stp_dbg_cpupcr->assert_info[0], tempbuf, copyLen); + g_stp_dbg_cpupcr->assert_info[copyLen] = '\0'; + osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); + } + + if (tempbuf) + osal_free(tempbuf); + } else if (issue_type == STP_FW_NOACK_ISSUE) { + osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); + osal_memcpy(&g_stp_dbg_cpupcr->assert_info[0], issue_info, len); + g_stp_dbg_cpupcr->fwTaskId = STP_DBG_TASK_DRVSTP; + g_stp_dbg_cpupcr->fwRrq = 0; + g_stp_dbg_cpupcr->fwIsr = 0; + osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); + } else if (issue_type == STP_DBG_PROC_TEST) { + osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); + osal_memcpy(&g_stp_dbg_cpupcr->assert_info[0], issue_info, len); + g_stp_dbg_cpupcr->fwTaskId = STP_DBG_TASK_WMT; + g_stp_dbg_cpupcr->fwRrq = 0; + g_stp_dbg_cpupcr->fwIsr = 0; + osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); + } else if (issue_type == STP_FW_WARM_RST_ISSUE) { + osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); + osal_memcpy(&g_stp_dbg_cpupcr->assert_info[0], issue_info, len); + g_stp_dbg_cpupcr->fwTaskId = STP_DBG_TASK_WMT; + g_stp_dbg_cpupcr->fwRrq = 0; + g_stp_dbg_cpupcr->fwIsr = 0; + osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); + } else { + STP_DBG_PR_ERR("invalid issue type(%d)\n", issue_type); + return -3; + } + + return 0; +} + +INT32 stp_dbg_cpupcr_infor_format(PUINT8 buf, UINT32 max_len) +{ + UINT32 len = 0; + UINT32 i = 0; + + /* never retrun negative value */ + if (!g_stp_dbg_cpupcr || !buf) { + STP_DBG_PR_ERR("NULL pointer, g_stp_dbg_cpupcr:%p, buf:%p\n", + g_stp_dbg_cpupcr, buf); + return 0; + } + + /* format common information about issue */ + /* max_len can guarantee there's enough buffer for
section */ + len = osal_sprintf(buf, "
\n\t"); + len += osal_sprintf(buf + len, "\n\t\tMT%x\n\t\n\t", + g_stp_dbg_cpupcr->chipId); + len += osal_sprintf(buf + len, "\n\t\t"); + len += osal_sprintf(buf + len, "%s\n\t\t", g_stp_dbg_cpupcr->romVer); + if (!(osal_memcmp(g_stp_dbg_cpupcr->branchVer, "ALPS", strlen("ALPS")))) + len += osal_sprintf(buf + len, "Internal Dev\n\t\t", + g_stp_dbg_cpupcr->branchVer); + else + len += osal_sprintf(buf + len, "W%sMP\n\t\t", + g_stp_dbg_cpupcr->branchVer); + + len += osal_sprintf(buf + len, "%s\n\t\t", g_stp_dbg_cpupcr->patchVer); + + if (g_stp_dbg_cpupcr->wifiVer == 0) + len += osal_sprintf(buf + len, "NULL\n\t"); + else + len += osal_sprintf(buf + len, "0x%X.%X\n\t", + (UINT8)((g_stp_dbg_cpupcr->wifiVer & 0xFF00)>>8), + (UINT8)(g_stp_dbg_cpupcr->wifiVer & 0xFF)); + + len += osal_sprintf(buf + len, "\n\t"); + + /*format issue information: no ack, assert */ + len += osal_sprintf(buf + len, "\n\t\t\n\t\t\t"); + if ((g_stp_dbg_cpupcr->issue_type == STP_FW_NOACK_ISSUE) || + (g_stp_dbg_cpupcr->issue_type == STP_DBG_PROC_TEST) || + (g_stp_dbg_cpupcr->issue_type == STP_FW_WARM_RST_ISSUE) || + (g_stp_dbg_cpupcr->issue_type == STP_FW_ABT)) { + len += osal_sprintf(buf + len, "%s\n\t\t\n\t\t\n\t\t\t", + g_stp_dbg_cpupcr->assert_info); + len += osal_sprintf(buf + len, "NULL\n\t\t\n\t\n\t"); + len += osal_sprintf(buf + len, "\n\t\tNULL\n\t\t"); + len += osal_sprintf(buf + len, "NULL\n\t\t"); + len += osal_sprintf(buf + len, "\n\t\t\t%s\n\t\t\t", + stp_dbg_id_to_task(g_stp_dbg_cpupcr->fwTaskId)); + len += osal_sprintf(buf + len, "IRQ_0x%x\n\t\t\t", g_stp_dbg_cpupcr->fwRrq); + len += osal_sprintf(buf + len, "0x%x\n\t\t\t", g_stp_dbg_cpupcr->fwIsr); + len += osal_sprintf(buf + len, "NULL\n\t\t\t"); + len += osal_sprintf(buf + len, "NULL\n\t\t\t"); + len += osal_sprintf(buf + len, "%s\n\t\t\t", + g_stp_dbg_cpupcr->keyword); + } else if ((g_stp_dbg_cpupcr->issue_type == STP_FW_ASSERT_ISSUE) || + (g_stp_dbg_cpupcr->issue_type == STP_HOST_TRIGGER_FW_ASSERT) || + (g_stp_dbg_cpupcr->issue_type == STP_HOST_TRIGGER_ASSERT_TIMEOUT)) { + len += osal_sprintf(buf + len, "%s\n\t\t\n\t\t\n\t\t\t", + g_stp_dbg_cpupcr->assert_info); + len += osal_sprintf(buf + len, "%s\n\t\t\n\t\n\t", + g_stp_dbg_cpupcr->assert_type); + len += osal_sprintf(buf + len, "\n\t\tNULL\n\t\t"); + len += osal_sprintf(buf + len, "NULL\n\t\t"); + len += osal_sprintf(buf + len, "\n\t\t\t%s\n\t\t\t", + stp_dbg_id_to_task(g_stp_dbg_cpupcr->fwTaskId)); + if (g_stp_dbg_cpupcr->host_assert_info.reason == 32 || + g_stp_dbg_cpupcr->host_assert_info.reason == 33 || + g_stp_dbg_cpupcr->host_assert_info.reason == 34 || + g_stp_dbg_cpupcr->host_assert_info.reason == 35 || + g_stp_dbg_cpupcr->host_assert_info.reason == 36 || + g_stp_dbg_cpupcr->host_assert_info.reason == 37 || + g_stp_dbg_cpupcr->host_assert_info.reason == 38 || + g_stp_dbg_cpupcr->host_assert_info.reason == 39 || + g_stp_dbg_cpupcr->host_assert_info.reason == 40) { + /*handling wmt turn on/off bt cmd has ack but no evt issue */ + /*one of both the irqx and irs is nULL, then use task to find MOF */ + len += osal_sprintf(buf + len, "NULL\n\t\t\t"); + } else + len += osal_sprintf(buf + len, "IRQ_0x%x\n\t\t\t", + g_stp_dbg_cpupcr->fwRrq); + len += osal_sprintf(buf + len, "0x%x\n\t\t\t", g_stp_dbg_cpupcr->fwIsr); + + if (g_stp_dbg_cpupcr->issue_type == STP_FW_ASSERT_ISSUE) { + len += osal_sprintf(buf + len, "NULL\n\t\t\t"); + len += osal_sprintf(buf + len, "NULL\n\t\t\t"); + } + + if ((g_stp_dbg_cpupcr->issue_type == STP_HOST_TRIGGER_FW_ASSERT) || + (g_stp_dbg_cpupcr->issue_type == STP_HOST_TRIGGER_ASSERT_TIMEOUT)) { + len += osal_sprintf(buf + len, "%d\n\t\t\t", + g_stp_dbg_cpupcr->host_assert_info.drv_type); + len += osal_sprintf(buf + len, "%d\n\t\t\t", + g_stp_dbg_cpupcr->host_assert_info.reason); + } + + len += osal_sprintf(buf + len, "%s\n\t\t\t", + g_stp_dbg_cpupcr->keyword); + } else { + len += osal_sprintf(buf + len, "NULL\n\t\t\n\t\t\n\t\t\t"); + len += osal_sprintf(buf + len, "NULL\n\t\t\n\t\n\t"); + len += osal_sprintf(buf + len, "\n\t\tNULL\n\t\t"); + len += osal_sprintf(buf + len, "NULL\n\t\t"); + len += osal_sprintf(buf + len, "\n\t\t\t%s\n\t\t\t", + stp_dbg_id_to_task(g_stp_dbg_cpupcr->fwTaskId)); + len += osal_sprintf(buf + len, "NULL\n\t\t\t"); + len += osal_sprintf(buf + len, "NULL\n\t\t\t"); + len += osal_sprintf(buf + len, "NULL\n\t\t\t"); + len += osal_sprintf(buf + len, "NULL\n\t\t\t"); + len += osal_sprintf(buf + len, "%s\n\t\t\t", + g_stp_dbg_cpupcr->keyword); + } + + len += osal_sprintf(buf + len, ""); + STP_DBG_PR_INFO("stp-dbg:sub len1 for debug(%d)\n", len); + + if (!g_stp_dbg_cpupcr->count) + len += osal_sprintf(buf + len, "NULL"); + else { + for (i = 0; i < g_stp_dbg_cpupcr->count; i++) + len += osal_sprintf(buf + len, "%08x,", g_stp_dbg_cpupcr->buffer[i]); + } + STP_DBG_PR_INFO("stp-dbg:sub len2 for debug(%d)\n", len); + len += osal_sprintf(buf + len, "\n\t\t\t"); + len += osal_sprintf(buf + len, + "NULL\n\t\t\n\t\n
\n"); + + STP_DBG_PR_INFO("buffer len[%d]\n", len); + /* STP_DBG_PR_INFO("Format infor:\n%s\n",buf); */ + + osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); + osal_memset(&g_stp_dbg_cpupcr->buffer[0], 0, STP_DBG_CPUPCR_NUM); + g_stp_dbg_cpupcr->count = 0; + g_stp_dbg_cpupcr->host_assert_info.reason = 0; + g_stp_dbg_cpupcr->host_assert_info.drv_type = 0; + g_stp_dbg_cpupcr->issue_type = STP_FW_ISSUE_TYPE_INVALID; + g_stp_dbg_cpupcr->keyword[0] = '\0'; + g_stp_dbg_cpupcr->fwRrq = 0; + g_stp_dbg_cpupcr->fwIsr = 0; + osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); + + return len; +} + +PUINT8 stp_dbg_id_to_task(UINT32 id) +{ + ENUM_WMT_CHIP_TYPE chip_type; + PUINT8 task_id = NULL; + + chip_type = wmt_detect_get_chip_type(); + switch (chip_type) { + case WMT_CHIP_TYPE_COMBO: + task_id = stp_dbg_combo_id_to_task(id); + break; + case WMT_CHIP_TYPE_SOC: + task_id = stp_dbg_soc_id_to_task(id); + break; + default: + STP_DBG_PR_ERR("error chip type(%d)\n", chip_type); + } + + return task_id; +} + +VOID stp_dbg_reset(VOID) +{ + if (g_stp_dbg_cpupcr) { + osal_memset(g_stp_dbg_cpupcr->buffer, 0, osal_sizeof(g_stp_dbg_cpupcr->buffer)); + osal_memset(g_stp_dbg_cpupcr->sec_buffer, 0, osal_sizeof(g_stp_dbg_cpupcr->sec_buffer)); + osal_memset(g_stp_dbg_cpupcr->nsec_buffer, 0, osal_sizeof(g_stp_dbg_cpupcr->nsec_buffer)); + } + + if (g_stp_dbg_dmaregs) { + g_stp_dbg_dmaregs->count = 0; + osal_memset(g_stp_dbg_dmaregs->dmaIssue, 0, osal_sizeof(g_stp_dbg_dmaregs->dmaIssue)); + } +} + +MTKSTP_DBG_T *stp_dbg_init(PVOID btm_half) +{ + MTKSTP_DBG_T *stp_dbg = NULL; + + stp_dbg = kzalloc(sizeof(MTKSTP_DBG_T), GFP_KERNEL); + if (stp_dbg == NULL) + goto ERR_EXIT1; + if (IS_ERR(stp_dbg)) { + STP_DBG_PR_ERR("-ENOMEM\n"); + goto ERR_EXIT1; + } + + stp_dbg->logsys = vmalloc(sizeof(MTKSTP_LOG_SYS_T)); + if (stp_dbg->logsys == NULL) + goto ERR_EXIT2; + if (IS_ERR(stp_dbg->logsys)) { + STP_DBG_PR_ERR("-ENOMEM stp_gdb->logsys\n"); + goto ERR_EXIT2; + } + memset(stp_dbg->logsys, 0, sizeof(MTKSTP_LOG_SYS_T)); + spin_lock_init(&(stp_dbg->logsys->lock)); + INIT_WORK(&(stp_dbg->logsys->dump_work), stp_dbg_dmp_print_work); + stp_dbg->pkt_trace_no = 0; + stp_dbg->is_enable = 0; + g_stp_dbg = stp_dbg; + + if (btm_half != NULL) + stp_dbg->btm = btm_half; + else + stp_dbg->btm = NULL; + + g_core_dump = stp_dbg_core_dump_init(STP_CORE_DUMP_TIMEOUT); + if (!g_core_dump) { + STP_DBG_PR_ERR("-ENOMEM wcn_coer_dump_init fail!"); + goto ERR_EXIT2; + } + g_stp_dbg_cpupcr = stp_dbg_cpupcr_init(); + if (!g_stp_dbg_cpupcr) { + STP_DBG_PR_ERR("-ENOMEM stp_dbg_cpupcr_init fail!"); + goto ERR_EXIT2; + } + g_stp_dbg_dmaregs = stp_dbg_dmaregs_init(); + if (!g_stp_dbg_dmaregs) { + STP_DBG_PR_ERR("-ENOMEM stp_dbg_dmaregs_init fail!"); + goto ERR_EXIT2; + } + return stp_dbg; + +ERR_EXIT2: + stp_dbg_deinit(stp_dbg); + return NULL; + +ERR_EXIT1: + kfree(stp_dbg); + return NULL; +} + +INT32 stp_dbg_deinit(MTKSTP_DBG_T *stp_dbg) +{ + stp_dbg_core_dump_deinit(g_core_dump); + + stp_dbg_cpupcr_deinit(g_stp_dbg_cpupcr); + stp_dbg_dmaregs_deinit(g_stp_dbg_dmaregs); + /* unbind with netlink */ + stp_dbg_nl_deinit(); + + if (stp_dbg->logsys) + vfree(stp_dbg->logsys); + + kfree(stp_dbg); + + return 0; +} + +INT32 stp_dbg_start_coredump_timer(VOID) +{ + if (!g_core_dump) { + STP_DBG_PR_ERR("invalid pointer!\n"); + return -1; + } + + return osal_timer_modify(&g_core_dump->dmp_timer, STP_CORE_DUMP_TIMEOUT); +} + +INT32 stp_dbg_start_emi_dump(VOID) +{ + INT32 ret = 0; + + if (!g_core_dump) { + STP_DBG_PR_ERR("invalid pointer!\n"); + return -1; + } + + if (mtk_wcn_wlan_emi_mpu_set_protection) + (*mtk_wcn_wlan_emi_mpu_set_protection)(false); + /* Disable MCIF EMI protection */ + mtk_wcn_wmt_set_mcif_mpu_protection(false); + stp_dbg_set_coredump_timer_state(CORE_DUMP_DOING); + osal_timer_modify(&g_core_dump->dmp_emi_timer, STP_EMI_DUMP_TIMEOUT); + ret = stp_dbg_nl_send_data(EMICOREDUMP_CMD, sizeof(EMICOREDUMP_CMD)); + if (ret) + stp_dbg_stop_emi_dump(); + + return ret ? -1 : 0; +} + +INT32 stp_dbg_stop_emi_dump(VOID) +{ + if (!g_core_dump) { + STP_DBG_PR_ERR("invalid pointer!\n"); + return -1; + } + + if (mtk_wcn_stp_emi_dump_flag_get() == 1) { + STP_DBG_PR_ERR("stopping emi dump!\n"); + return -2; + } + + mtk_wcn_stp_emi_dump_flag_ctrl(1); + /* Enable MCIF EMI protection */ + mtk_wcn_wmt_set_mcif_mpu_protection(true); + if (mtk_wcn_wlan_emi_mpu_set_protection) + (*mtk_wcn_wlan_emi_mpu_set_protection)(true); + osal_timer_stop(&g_core_dump->dmp_emi_timer); + return 0; +} + +INT32 stp_dbg_nl_send_data(const PINT8 buf, INT32 len) +{ + PINT8 pdata = NULL; + INT32 ret = 0; + + pdata = kmalloc(len+5, GFP_KERNEL); + if (!pdata) + return -1; + pdata[0] = '['; + pdata[1] = 'M'; + pdata[2] = ']'; + osal_memcpy(&pdata[3], &len, 2); + osal_memcpy(&pdata[5], buf, len); + ret = stp_dbg_dump_send_retry_handler(pdata, len); + kfree(pdata); + return ret; +} diff --git a/drivers/misc/mediatek/connectivity/common/common_main/linux/stp_dbg_combo.c b/drivers/misc/mediatek/connectivity/common/common_main/linux/stp_dbg_combo.c new file mode 100644 index 0000000000000000000000000000000000000000..796c98fce8d6f7309fbea9060733ec074ba4d473 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/linux/stp_dbg_combo.c @@ -0,0 +1,196 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +#include "stp_dbg.h" +#include "stp_dbg_combo.h" + +static _osal_inline_ INT32 stp_dbg_combo_put_dump_to_aee(VOID); +static _osal_inline_ INT32 stp_dbg_combo_put_dump_to_nl(VOID); + +static PUINT8 combo_task_str[STP_DBG_TASK_ID_MAX] = { + "Task_WMT", + "Task_BT", + "Task_Wifi", + "Task_Tst", + "Task_FM", + "Task_GPS", + "Task_FLP", + "Task_BAL", + "Task_Idle", + "Task_DrvStp", + "Task_DrvSdio", + "Task_NatBt", + "Task_DrvWifi", + "Task_GPS" +}; + +INT32 const combo_legacy_task_id_adapter[STP_DBG_TASK_ID_MAX] = { + STP_DBG_TASK_WMT, + STP_DBG_TASK_BT, + STP_DBG_TASK_WIFI, + STP_DBG_TASK_TST, + STP_DBG_TASK_FM, + STP_DBG_TASK_IDLE, + STP_DBG_TASK_WMT, + STP_DBG_TASK_WMT, + STP_DBG_TASK_WMT, + STP_DBG_TASK_DRVSTP, + STP_DBG_TASK_BUS, + STP_DBG_TASK_NATBT, + STP_DBG_TASK_DRVWIFI, + STP_DBG_TASK_DRVGPS +}; + +static _osal_inline_ INT32 stp_dbg_combo_put_dump_to_aee(VOID) +{ + static UINT8 buf[2048]; + static UINT8 tmp[2048]; + + UINT32 buf_len; + STP_PACKET_T *pkt = NULL; + STP_DBG_HDR_T *hdr = NULL; + INT32 remain = 0; + INT32 retry = 0; + INT32 ret = 0; + + do { + remain = stp_dbg_dmp_out_ex(&buf[0], &buf_len); + if (buf_len > 0) { + pkt = (STP_PACKET_T *) buf; + hdr = &pkt->hdr; + if (hdr->dbg_type == STP_DBG_FW_DMP) { + if (pkt->hdr.len <= 1500) { + tmp[pkt->hdr.len] = '\n'; + tmp[pkt->hdr.len + 1] = '\0'; + if (pkt->hdr.len < STP_DMP_SZ) + osal_memcpy(&tmp[0], pkt->raw, pkt->hdr.len); + else + osal_memcpy(&tmp[0], pkt->raw, STP_DMP_SZ); + ret = stp_dbg_aee_send(tmp, pkt->hdr.len, 0); + } else { + STP_DBG_PR_INFO("dump entry length is over long\n"); + osal_bug_on(0); + } + retry = 0; + } + retry = 0; + } else { + retry++; + osal_sleep_ms(20); + } + } while ((remain > 0) || (retry < 10)); + + return ret; +} + +static _osal_inline_ INT32 stp_dbg_combo_put_dump_to_nl(VOID) +{ +#define NUM_FETCH_ENTRY 8 + + static UINT8 buf[2048]; + static UINT8 tmp[2048]; + + UINT32 buf_len; + STP_PACKET_T *pkt = NULL; + STP_DBG_HDR_T *hdr = NULL; + INT32 remain = 0; + INT32 index = 0; + INT32 retry = 0; + INT32 ret = 0; + INT32 len; + + index = 0; + tmp[index++] = '['; + tmp[index++] = 'M'; + tmp[index++] = ']'; + + do { + index = 3; + remain = stp_dbg_dmp_out_ex(&buf[0], &buf_len); + if (buf_len > 0) { + pkt = (STP_PACKET_T *) buf; + hdr = &pkt->hdr; + len = pkt->hdr.len; + osal_memcpy(&tmp[index], &len, 2); + index += 2; + if (hdr->dbg_type == STP_DBG_FW_DMP) { + osal_memcpy(&tmp[index], pkt->raw, pkt->hdr.len); + + if (pkt->hdr.len <= 1500) { + tmp[index + pkt->hdr.len] = '\n'; + tmp[index + pkt->hdr.len + 1] = '\0'; + + /* pr_warn("\n%s\n+++\n", tmp); */ + ret = stp_dbg_dump_send_retry_handler((PINT8)&tmp, len); + if (ret) + break; + + /* schedule(); */ + } else { + STP_DBG_PR_INFO("dump entry length is over long\n"); + osal_bug_on(0); + } + retry = 0; + } + } else { + retry++; + osal_sleep_ms(100); + } + } while ((remain > 0) || (retry < 2)); + + return ret; +} + +INT32 stp_dbg_combo_core_dump(INT32 dump_sink) +{ + INT32 ret = 0; + + switch (dump_sink) { + case 0: + STP_DBG_PR_INFO("coredump is disabled!\n"); + break; + case 1: + ret = stp_dbg_combo_put_dump_to_aee(); + break; + case 2: + ret = stp_dbg_combo_put_dump_to_nl(); + break; + default: + ret = -1; + STP_DBG_PR_ERR("unknown sink %d\n", dump_sink); + } + + return ret; +} + +PUINT8 stp_dbg_combo_id_to_task(UINT32 id) +{ + UINT32 chip_id = mtk_wcn_wmt_chipid_query(); + UINT32 temp_id; + + if (id >= STP_DBG_TASK_ID_MAX) { + STP_DBG_PR_ERR("task id(%d) overflow(%d)\n", id, STP_DBG_TASK_ID_MAX); + return NULL; + } + + switch (chip_id) { + case 0x6632: + temp_id = id; + break; + default: + temp_id = combo_legacy_task_id_adapter[id]; + break; + } + + return combo_task_str[temp_id]; +} diff --git a/drivers/misc/mediatek/connectivity/common/common_main/linux/stp_dbg_soc.c b/drivers/misc/mediatek/connectivity/common/common_main/linux/stp_dbg_soc.c new file mode 100644 index 0000000000000000000000000000000000000000..15ebea85608f700e09e9eb9ca4945158b36b0831 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/linux/stp_dbg_soc.c @@ -0,0 +1,578 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +#include "stp_dbg.h" +#include "stp_dbg_soc.h" +#include "btm_core.h" +#include "stp_core.h" +#include "mtk_wcn_consys_hw.h" +#include "wmt_step.h" +#include "wmt_lib.h" +#include + +#define STP_DBG_PAGED_TRACE_SIZE (2048*sizeof(char)) +#define SUB_PKT_SIZE 1024 +#define EMI_SYNC_TIMEOUT 100 /* FW guarantee that MCU copy data time is ~20ms. We set 100ms for safety */ +#define IS_VISIBLE_CHAR(c) ((c) >= 32 && (c) <= 126) +#define DUMP_LOG_BYTES_PER_LINE (128) + +#define ROM_V2_PATCH "ROMv2" +#define ROM_V3_PATCH "ROMv3" +#define ROM_V4_PATCH "ROMv4" + +ENUM_STP_FW_ISSUE_TYPE issue_type; +UINT8 g_paged_trace_buffer[STP_DBG_PAGED_TRACE_SIZE] = { 0 }; +UINT32 g_paged_trace_len; +UINT8 g_paged_dump_buffer[STP_DBG_PAGED_DUMP_BUFFER_SIZE] = { 0 }; +UINT32 g_paged_dump_len; + +static PUINT8 soc_task_str[STP_DBG_TASK_ID_MAX] = { + "Task_WMT", + "Task_BT", + "Task_Wifi", + "Task_Tst", + "Task_FM", + "Task_GPS", + "Task_FLP", + "Task_BT2", + "Task_Idle", + "Task_DrvStp", + "Task_DrvBtif", + "Task_NatBt", + "Task_DrvWifi", + "Task_GPS" +}; + +INT32 const soc_gen_two_task_id_adapter[STP_DBG_TASK_ID_MAX] = { + STP_DBG_TASK_WMT, + STP_DBG_TASK_BT, + STP_DBG_TASK_WIFI, + STP_DBG_TASK_TST, + STP_DBG_TASK_FM, + STP_DBG_TASK_IDLE, + STP_DBG_TASK_WMT, + STP_DBG_TASK_WMT, + STP_DBG_TASK_WMT, + STP_DBG_TASK_DRVSTP, + STP_DBG_TASK_BUS, + STP_DBG_TASK_NATBT, + STP_DBG_TASK_DRVWIFI, + STP_DBG_TASK_DRVGPS +}; + +INT32 const soc_gen_three_task_id_adapter[STP_DBG_TASK_ID_MAX] = { + STP_DBG_TASK_WMT, + STP_DBG_TASK_BT, + STP_DBG_TASK_WIFI, + STP_DBG_TASK_TST, + STP_DBG_TASK_FM, + STP_DBG_TASK_GPS, + STP_DBG_TASK_FLP, + STP_DBG_TASK_IDLE, + STP_DBG_TASK_WMT, + STP_DBG_TASK_DRVSTP, + STP_DBG_TASK_BUS, + STP_DBG_TASK_NATBT, + STP_DBG_TASK_DRVWIFI, + STP_DBG_TASK_DRVGPS +}; + +static _osal_inline_ INT32 stp_dbg_soc_paged_dump(INT32 dump_sink); +static _osal_inline_ INT32 stp_dbg_soc_paged_trace(VOID); +static _osal_inline_ INT32 stp_dbg_soc_put_emi_dump_to_nl(PUINT8 data_buf, INT32 dump_len); +static _osal_inline_ VOID stp_dbg_soc_emi_dump_buffer(UINT8 *buffer, UINT32 len); + +static VOID stp_dbg_dump_log(PUINT8 buf, INT32 size) +{ + INT32 i = 0; + UINT8 line[DUMP_LOG_BYTES_PER_LINE + 1]; + + while (size--) { + if (IS_VISIBLE_CHAR(*buf)) + line[i] = *buf; + else + line[i] = '.'; + i++; + buf++; + + if (i >= DUMP_LOG_BYTES_PER_LINE || !size) { + line[i] = 0; + pr_info("page_trace: %s\n", line); + i = 0; + } + } +} + +static _osal_inline_ VOID stp_dbg_soc_emi_dump_buffer(UINT8 *buffer, UINT32 len) +{ + UINT32 i = 0; + + if (len > 16) + len = 16; + for (i = 0; i < len; i++) { + if (i % 16 == 0 && i != 0) + pr_cont("\n "); + + if (buffer[i] == ']' || buffer[i] == '[' || buffer[i] == ',') + pr_cont("%c", buffer[i]); + else + pr_cont("0x%02x ", buffer[i]); + } +} + +static _osal_inline_ INT32 stp_dbg_soc_put_emi_dump_to_nl(PUINT8 data_buf, INT32 dump_len) +{ + static UINT8 tmp[SUB_PKT_SIZE + NL_PKT_HEADER_LEN]; + INT32 remain = dump_len, index = 0; + INT32 ret = 0; + INT32 len; + INT32 offset = 0; + + if (dump_len > 0) { + index = 0; + tmp[index++] = '['; + tmp[index++] = 'M'; + tmp[index++] = ']'; + + do { + index = 3; + if (remain >= SUB_PKT_SIZE) + len = SUB_PKT_SIZE; + else + len = remain; + remain -= len; + + osal_memcpy(&tmp[index], &len, 2); + index += 2; + osal_memcpy(&tmp[index], data_buf + offset, len); + offset += len; + STP_DBG_PR_DBG("send %d remain %d\n", len, remain); + + ret = stp_dbg_dump_send_retry_handler((PINT8)&tmp, len); + if (ret) + break; + + /* schedule(); */ + } while (remain > 0); + } else + STP_DBG_PR_INFO("dump entry length is 0\n"); + + return ret; +} + +static _osal_inline_ UINT64 stp_dbg_soc_elapsed_time(UINT64 ts, ULONG nsec) +{ + UINT64 current_ts = 0; + ULONG current_nsec = 0; + + osal_get_local_time(¤t_ts, ¤t_nsec); + return (current_ts*1000 + current_nsec/1000) - (ts*1000 + nsec/1000); +} + +static _osal_inline_ INT32 stp_dbg_soc_paged_dump(INT32 dump_sink) +{ + INT32 ret = 0; + UINT32 counter = 0; + UINT32 dump_num = 0; + UINT32 packet_num = STP_PAGED_DUMP_TIME_LIMIT/100; + UINT32 page_counter = 0; + ENUM_CHIP_DUMP_STATE chip_state; + UINT32 dump_phy_addr = 0; + PUINT8 dump_vir_addr = NULL; + INT32 dump_len = 0; + P_CONSYS_EMI_ADDR_INFO p_ecsi; + UINT64 start_ts = 0; + ULONG start_nsec = 0; + UINT64 elapsed_time = 0; + INT32 abort = 0; +#if WMT_DBG_SUPPORT + static DEFINE_RATELIMIT_STATE(_rs, 10 * HZ, 1); +#endif + + g_paged_dump_len = 0; + p_ecsi = wmt_plat_get_emi_phy_add(); + osal_assert(p_ecsi); + if (p_ecsi == NULL) + return -1; + + issue_type = STP_FW_ASSERT_ISSUE; + if (chip_reset_only) { + STP_DBG_PR_WARN("is chip reset only\n"); + ret = -3; + return ret; + } + + if (dump_sink == 0) + return 0; + + /* handshake error handle: notify FW assert in abnormal case */ + if (p_ecsi->p_ecso->emi_apmem_ctrl_state == 0x0) { + mtk_wcn_force_trigger_assert_debug_pin(); + osal_sleep_ms(100); + } + + /*packet number depend on dump_num get from register:0xf0080044 ,support jade*/ + dump_num = wmt_plat_get_dump_info(p_ecsi->p_ecso->emi_apmem_ctrl_chip_page_dump_num); + if (dump_num != 0) { + packet_num = dump_num; + STP_DBG_PR_INFO("get consys dump num packet_num(%d)\n", packet_num); + } else { + dump_num = CORE_DUMP_NUM; + STP_DBG_PR_ERR("can not get consys dump num and default num is %d\n", CORE_DUMP_NUM); + } + + stp_dbg_dump_num(dump_num); + stp_dbg_start_coredump_timer(); + wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START); + page_counter = 0; + if (mtk_wcn_stp_get_wmt_trg_assert() == 0) + WMT_STEP_DO_ACTIONS_FUNC(STEP_TRIGGER_POINT_FIRMWARE_TRIGGER_ASSERT); + + while (1) { + /* assert flag 2 means mcu is ready to start coredump */ + if (wmt_plat_get_dump_info(p_ecsi->p_ecso->emi_apmem_ctrl_assert_flag) == 2) { + STP_DBG_PR_INFO("coredump handshake start\n"); + break; + } else if (stp_dbg_get_coredump_timer_state() == CORE_DUMP_TIMEOUT) + goto paged_dump_end; + osal_sleep_ms(1); + } + + do { + dump_phy_addr = 0; + dump_vir_addr = NULL; + dump_len = 0; + + counter++; + osal_get_local_time(&start_ts, &start_nsec); + while (1) { + elapsed_time = stp_dbg_soc_elapsed_time(start_ts, start_nsec); + chip_state = (ENUM_CHIP_DUMP_STATE)wmt_plat_get_dump_info( + p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_state); + if (chip_state == STP_CHIP_DUMP_PUT_DONE) { + STP_DBG_PR_DBG("chip put done\n"); + break; + } + STP_DBG_PR_DBG("waiting chip put done, chip_state: %d\n", chip_state); +#if WMT_DBG_SUPPORT + if (chip_state == 0 && __ratelimit(&_rs)) + stp_dbg_poll_cpupcr(5, 1, 1); +#endif + + if (elapsed_time > EMI_SYNC_TIMEOUT) { +#if !WMT_DBG_SUPPORT + STP_DBG_PR_ERR("Wait Timeout: %llu > %d\n", elapsed_time, EMI_SYNC_TIMEOUT); + /* Since customer's user/userdebug load get coredump via netlink(dump_sink==2). */ + /* For UX, if get coredump timeout, skip it and do chip reset ASAP. */ + if (dump_sink == 2) + abort = 1; +#endif + goto paged_dump_end; + } + osal_sleep_ms(1); + } + + dump_phy_addr = wmt_plat_get_dump_info( + p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_addr); + + if (!dump_phy_addr) { + STP_DBG_PR_ERR("get paged dump phy address fail\n"); + ret = -1; + break; + } + + dump_vir_addr = wmt_plat_get_emi_virt_add(dump_phy_addr - p_ecsi->emi_phy_addr); + if (!dump_vir_addr) { + STP_DBG_PR_ERR("get paged dump phy address fail\n"); + ret = -2; + break; + } + dump_len = wmt_plat_get_dump_info(p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_len); + STP_DBG_PR_DBG("dump_phy_ddr(%08x),dump_vir_add(0x%p),dump_len(%d)\n", + dump_phy_addr, dump_vir_addr, dump_len); + + /* dump_len should not be negative */ + if (dump_len < 0) + dump_len = 0; + + /*move dump info according to dump_addr & dump_len */ + osal_memcpy_fromio(&g_paged_dump_buffer[0], dump_vir_addr, dump_len); + + if (dump_len <= 32 * 1024) { + STP_DBG_PR_DBG("coredump mode: %d!\n", dump_sink); + switch (dump_sink) { + case 1: + ret = stp_dbg_aee_send(&g_paged_dump_buffer[0], dump_len, 0); + if (ret == 0) + STP_DBG_PR_DBG("aee send ok!\n"); + else if (ret == 1) + STP_DBG_PR_DBG("aee send fisish!\n"); + else if (ret == -1) { + STP_DBG_PR_ERR("aee send timeout!\n"); + abort = 1; + goto paged_dump_end; + } else + STP_DBG_PR_ERR("aee send error!\n"); + break; + case 2: + ret = stp_dbg_soc_put_emi_dump_to_nl(&g_paged_dump_buffer[0], dump_len); + if (ret == 0) + STP_DBG_PR_DBG("dump send ok!\n"); + else if (ret == 1) { + STP_DBG_PR_ERR("dump send timeout!\n"); + abort = 1; + goto paged_dump_end; + } else + STP_DBG_PR_ERR("dump send error!\n"); + break; + default: + STP_DBG_PR_ERR("unknown sink %d\n", dump_sink); + return -1; + } + } else + STP_DBG_PR_ERR("dump len is over than 32K(%d)\n", dump_len); + + g_paged_dump_len += dump_len; + wmt_plat_update_host_sync_num(); + wmt_plat_set_host_dump_state(STP_HOST_DUMP_GET_DONE); + + STP_DBG_PR_DBG("host sync num(%d),chip sync num(%d)\n", + wmt_plat_get_dump_info(p_ecsi->p_ecso->emi_apmem_ctrl_host_sync_num), + wmt_plat_get_dump_info(p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_num)); + page_counter++; + STP_DBG_PR_DBG("++ paged dump counter(%d) ++\n", page_counter); + /* dump 1st 512 bytes data to kernel log for fw requirement */ + if (page_counter == 1) + stp_dbg_dump_log(&g_paged_dump_buffer[0], dump_len < 512 ? dump_len : 512); + + osal_get_local_time(&start_ts, &start_nsec); + while (1) { + elapsed_time = stp_dbg_soc_elapsed_time(start_ts, start_nsec); + chip_state = (ENUM_CHIP_DUMP_STATE)wmt_plat_get_dump_info( + p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_state); + if (chip_state == STP_CHIP_DUMP_END) { + STP_DBG_PR_DBG("chip put end\n"); + break; + } + STP_DBG_PR_DBG("waiting chip put end, chip_state: %d\n", chip_state); + if (elapsed_time > EMI_SYNC_TIMEOUT) { +#if !WMT_DBG_SUPPORT + STP_DBG_PR_ERR("Wait Timeout: %llu > %d\n", elapsed_time, EMI_SYNC_TIMEOUT); + /* Since customer's user/userdebug load get coredump via netlink(dump_sink==2). */ + /* For UX, if wait sync state timeout, skip it and do chip reset ASAP. */ + if (dump_sink == 2) + abort = 1; +#endif + goto paged_dump_end; + } + osal_sleep_ms(1); + } + +paged_dump_end: + wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START); + STP_DBG_PR_INFO("++ counter(%d) packet_num(%d) page_counter(%d) g_paged_dump_len(%d) fw_state(%d)++\n", + counter, packet_num, page_counter, g_paged_dump_len, + wmt_plat_get_dump_info(p_ecsi->p_ecso->emi_apmem_ctrl_state)); + if (wmt_plat_get_dump_info(p_ecsi->p_ecso->emi_apmem_ctrl_chip_paded_dump_end) || + (wmt_plat_get_dump_info(p_ecsi->p_ecso->emi_apmem_ctrl_state) == 0x8)) { + if (stp_dbg_get_coredump_timer_state() == CORE_DUMP_DOING) { + STP_DBG_PR_INFO("paged dump end by emi flag\n"); + if (dump_sink == 1) + stp_dbg_aee_send(FAKECOREDUMPEND, osal_sizeof(FAKECOREDUMPEND), 0); + else if (dump_sink == 2) + stp_dbg_nl_send_data(FAKECOREDUMPEND, osal_sizeof(FAKECOREDUMPEND)); + } else + STP_DBG_PR_INFO("paged dump end\n"); + ret = 0; + break; + } else if (abort || stp_dbg_get_coredump_timer_state() == CORE_DUMP_TIMEOUT) { + STP_DBG_PR_ERR("paged dump fail, generate fake coredump message\n"); + stp_dbg_set_coredump_timer_state(CORE_DUMP_DOING); + if (dump_sink == 1) + stp_dbg_aee_send(FAKECOREDUMPEND, osal_sizeof(FAKECOREDUMPEND), 0); + else if (dump_sink == 2) + stp_dbg_nl_send_data(FAKECOREDUMPEND, osal_sizeof(FAKECOREDUMPEND)); + stp_dbg_set_coredump_timer_state(CORE_DUMP_TIMEOUT); + stp_dbg_poll_cpupcr(5, 5, 0); + stp_dbg_poll_dmaregs(5, 1); + ret = -1; + break; + } + } while (1); + + return ret; +} + +static _osal_inline_ INT32 stp_dbg_soc_paged_trace(VOID) +{ + INT32 ret = 0; + UINT32 ctrl_val = 0; + UINT32 loop_cnt1 = 0; + UINT32 buffer_start = 0; + UINT32 buffer_idx = 0; + PUINT8 dump_vir_addr = NULL; + P_CONSYS_EMI_ADDR_INFO p_ecsi; + INT32 dump_len = 0; + + p_ecsi = wmt_plat_get_emi_phy_add(); + if (p_ecsi == NULL) { + STP_DBG_PR_ERR("get EMI info failed.\n"); + return -1; + } + + do { + ctrl_val = 0; + loop_cnt1 = 0; + buffer_start = 0; + buffer_idx = 0; + dump_vir_addr = NULL; + + while (loop_cnt1 < 10) { + ctrl_val = wmt_plat_get_dump_info(p_ecsi->p_ecso->emi_apmem_ctrl_state); + if (ctrl_val == 0x8) + break; + osal_sleep_ms(10); + loop_cnt1++; + } + if (loop_cnt1 >= 10) { + STP_DBG_PR_ERR("polling CTRL STATE fail\n"); + ret = -1; + break; + } + + buffer_start = wmt_plat_get_dump_info(p_ecsi->p_ecso->emi_apmem_ctrl_chip_print_buff_start); + buffer_idx = wmt_plat_get_dump_info(p_ecsi->p_ecso->emi_apmem_ctrl_chip_print_buff_idx); + g_paged_trace_len = buffer_idx; + STP_DBG_PR_INFO("paged trace buffer addr(%08x),buffer_len(%d)\n", buffer_start, + buffer_idx); + dump_vir_addr = wmt_plat_get_emi_virt_add(buffer_start - p_ecsi->emi_phy_addr); + if (!dump_vir_addr) { + STP_DBG_PR_ERR("get vir dump address fail\n"); + ret = -2; + break; + } + osal_memcpy_fromio(&g_paged_trace_buffer[0], dump_vir_addr, + buffer_idx < STP_DBG_PAGED_TRACE_SIZE ? buffer_idx : STP_DBG_PAGED_TRACE_SIZE); + /*moving paged trace according to buffer_start & buffer_len */ + + dump_len = + buffer_idx < STP_DBG_PAGED_TRACE_SIZE ? buffer_idx : STP_DBG_PAGED_TRACE_SIZE; + pr_info("-- paged trace ascii output --"); + stp_dbg_dump_log(&g_paged_trace_buffer[0], dump_len); + ret = 0; + } while (0); + + return ret; +} + +INT32 stp_dbg_soc_core_dump(INT32 dump_sink) +{ + INT32 ret = 0; + + if (dump_sink == 0 || chip_reset_only == 1) { + if (chip_reset_only) { + STP_DBG_PR_INFO("Chip reset only\n"); + chip_reset_only = 0; + } + mtk_wcn_stp_ctx_restore(); + } else if (dump_sink == 1 || dump_sink == 2) { + stp_dbg_soc_paged_dump(dump_sink); + ret = stp_dbg_soc_paged_trace(); + if (ret) + STP_DBG_PR_ERR("stp_dbg_soc_paged_trace fail: %d!\n", ret); + if (stp_dbg_start_emi_dump() < 0) + mtk_wcn_stp_ctx_restore(); + } + + return ret; +} + +PUINT8 stp_dbg_soc_id_to_task(UINT32 id) +{ + P_WMT_PATCH_INFO p_patch_info; + PUINT8 patch_name = NULL; + UINT32 temp_id; + + if (id >= STP_DBG_TASK_ID_MAX) { + STP_DBG_PR_ERR("task id(%d) overflow(%d)\n", id, STP_DBG_TASK_ID_MAX); + return NULL; + } + + p_patch_info = wmt_lib_get_patch_info(); + if (p_patch_info) + patch_name = p_patch_info->patchName; + + if (patch_name == NULL) { + STP_DBG_PR_INFO("patch_name is null\n"); + /* For projects without patch download */ + return soc_task_str[id]; + } + + if (osal_strncmp(patch_name, ROM_V2_PATCH, strlen(ROM_V2_PATCH)) == 0) { + temp_id = soc_gen_two_task_id_adapter[id]; + STP_DBG_PR_INFO("id = %d, gen two task_id = %d\n", id, temp_id); + } else if (osal_strncmp(patch_name, ROM_V3_PATCH, strlen(ROM_V3_PATCH)) == 0) { + temp_id = soc_gen_three_task_id_adapter[id]; + STP_DBG_PR_INFO("id = %d, gen three task_id = %d\n", id, temp_id); + } else if (osal_strncmp(patch_name, ROM_V4_PATCH, strlen(ROM_V4_PATCH)) == 0) { + temp_id = soc_gen_three_task_id_adapter[id]; + STP_DBG_PR_INFO("id = %d, gen three (ROMv4) task_id = %d\n", id, temp_id); + } else { + temp_id = id; + STP_DBG_PR_INFO("id = %d, CONNAC project task_id = %d\n", id, temp_id); + } + + return soc_task_str[temp_id]; +} + +UINT32 stp_dbg_soc_read_debug_crs(ENUM_CONNSYS_DEBUG_CR cr) +{ +#define CONSYS_REG_READ(addr) (*((volatile UINT32 *)(addr))) +#ifdef CONFIG_OF /*use DT */ + P_CONSYS_EMI_ADDR_INFO emi_phy_addr; + UINT32 chip_id = 0; + + chip_id = wmt_plat_get_soc_chipid(); + emi_phy_addr = mtk_wcn_consys_soc_get_emi_phy_add(); + + if (cr == CONNSYS_EMI_REMAP) { + if (emi_phy_addr != NULL && emi_phy_addr->emi_remap_offset) + return CONSYS_REG_READ(conn_reg.topckgen_base + + emi_phy_addr->emi_remap_offset); + else + STP_DBG_PR_INFO("EMI remap has no value\n"); + } + + if (chip_id == 0x6765 || chip_id == 0x3967 || chip_id == 0x6761 + || chip_id == 0x6779 || chip_id == 0x6768 || chip_id == 0x6785 + || chip_id == 0x6873 || chip_id == 0x8168 || chip_id == 0x6853 + || chip_id == 0x6833) + return 0; + + if (conn_reg.mcu_base) { + switch (cr) { + case CONNSYS_CPU_CLK: + return CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_CPU_CLK_STATUS_OFFSET); + case CONNSYS_BUS_CLK: + return CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_BUS_CLK_STATUS_OFFSET); + case CONNSYS_DEBUG_CR1: + return CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_DBG_CR1_OFFSET); + case CONNSYS_DEBUG_CR2: + return CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_DBG_CR2_OFFSET); + default: + return 0; + } + } +#endif + return -1; +} diff --git a/drivers/misc/mediatek/connectivity/common/common_main/linux/stp_sdio.c b/drivers/misc/mediatek/connectivity/common/common_main/linux/stp_sdio.c new file mode 100644 index 0000000000000000000000000000000000000000..6c663ed5cb374a7385a53759ec3075a6c8c463b0 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/linux/stp_sdio.c @@ -0,0 +1,3584 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +/*! \file "stp_sdio.c" + * \brief + * + * detailed description +*/ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +#define STP_SDIO_TXPERFDBG 1 /* depends on STP_SDIO_DBG_SUPPORT */ +#define STP_SDIO_OWNBACKDBG 1 /* depends on STP_SDIO_DBG_SUPPORT */ +#define STP_SDIO_NEW_IRQ_HANDLER 1 + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "osal.h" +#include "stp_exp.h" +#include "hif_sdio.h" +#include "stp_sdio.h" +#include "stp_dbg.h" +#include "wmt_lib.h" +#include "wmt_exp.h" + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +#ifdef DFT_TAG +#undef DFT_TAG +#endif +#define DFT_TAG "[STP SDIO]" + +#define STPSDIO_LOG_LOUD 5 +#define STPSDIO_LOG_DBG 4 +#define STPSDIO_LOG_HINT 3 +#define STPSDIO_LOG_INFO 2 +#define STPSDIO_LOG_WARN 1 +#define STPSDIO_LOG_ERR 0 + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ +#if STP_SDIO_DBG_SUPPORT && STP_SDIO_RXDBG +#define STP_SDIO_RXDBG_COUNT (0x10UL) +#define STP_SDIO_RXDBG_COUNT_MASK (STP_SDIO_RXDBG_COUNT - 1) +struct stp_sdio_rxdbg { + UINT32 ts; + UINT32 bus_rxlen; + UINT32 chisr_rxlen; + UINT8 rx_pkt_buf[STP_SDIO_RX_BUF_SIZE]; +}; +#endif + +#if STP_SDIO_DBG_SUPPORT && STP_SDIO_TXDBG +#define STP_SDIO_TXDBG_COUNT (0x10UL) +#define STP_SDIO_TXDBG_COUNT_MASK (STP_SDIO_TXDBG_COUNT - 1) +struct stp_sdio_txdbg { + UINT32 ts; + UINT32 bus_txlen; + UINT64 l_sec; + ULONG l_nsec; + UINT32 four_byte_align_len; + UINT8 tx_pkt_buf[STP_SDIO_TX_ENTRY_SIZE]; +}; +#define STP_SDIO_TXDBG_MAX_SIZE (0x20) +#endif +OSAL_SLEEPABLE_LOCK fake_coredump_lock; +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +static INT32 stp_sdio_func0_reg_rw(INT32 direction, UINT32 offset, UINT32 value); +static INT32 stp_sdio_func_reg_rw(INT32 direction, UINT32 offset, UINT32 value); + +static INT32 stp_sdio_irq(const MTK_WCN_HIF_SDIO_CLTCTX clt_ctx); +static INT32 stp_sdio_probe(const MTK_WCN_HIF_SDIO_CLTCTX clt_ctx, + const MTK_WCN_HIF_SDIO_FUNCINFO *sdio_func_infop); +static INT32 stp_sdio_remove(const MTK_WCN_HIF_SDIO_CLTCTX clt_ctx); + +static VOID stp_sdio_rx_wkr(struct work_struct *work); +static VOID stp_sdio_tx_wkr(struct work_struct *work); +#if STP_SDIO_OWN_THREAD +static INT32 stp_sdio_wait_for_msg(PVOID pvData); +static VOID stp_sdio_tx_rx_handling(PVOID pData); +#endif +static _osal_inline_ INT32 stp_sdio_host_info_deinit(PPUINT8 ppTxBuf, PPUINT8 ppRxBuf); +static _osal_inline_ INT32 stp_sdio_host_info_init(PPUINT8 ppTxBuf, PPUINT8 ppRxBuf); +static _osal_inline_ INT32 stp_sdio_host_info_op(INT32 opId); +static _osal_inline_ SDIO_PS_OP stp_sdio_get_own_state(VOID); +static _osal_inline_ INT32 stp_sdio_do_own_set(MTK_WCN_STP_SDIO_HIF_INFO *p_info); +static _osal_inline_ INT32 stp_sdio_do_own_clr(INT32 wait); +static _osal_inline_ VOID stp_sdio_check_tx_sanity(const MTK_WCN_STP_SDIO_HIF_INFO *p_info, const UINT32 id); +static _osal_inline_ VOID stp_sdio_tx_wkr_comp(MTK_WCN_STP_SDIO_HIF_INFO * const p_info); +static _osal_inline_ INT32 stp_sdio_ownback_poll(const MTK_WCN_HIF_SDIO_CLTCTX clt_ctx, UINT32 retry, + UINT32 delay_us); +static _osal_inline_ VOID stp_sdio_txperf_dump(VOID); +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/* Supported SDIO device table */ +static const MTK_WCN_HIF_SDIO_FUNCINFO mtk_stp_sdio_id_tbl[] = { + /* MT6618 *//* Not an SDIO standard class device */ + {MTK_WCN_HIF_SDIO_FUNC(0x037A, 0x018B, 1, STP_SDIO_BLK_SIZE)}, + {MTK_WCN_HIF_SDIO_FUNC(0x037A, 0x018C, 1, STP_SDIO_BLK_SIZE)}, /* 2-function */ + + /* MT6619 *//* Not an SDIO standard class device */ + {MTK_WCN_HIF_SDIO_FUNC(0x037A, 0x6619, 1, STP_SDIO_BLK_SIZE)}, + + /* MT6620 *//* Not an SDIO standard class device */ + {MTK_WCN_HIF_SDIO_FUNC(0x037A, 0x020B, 1, STP_SDIO_BLK_SIZE)}, + {MTK_WCN_HIF_SDIO_FUNC(0x037A, 0x020C, 1, STP_SDIO_BLK_SIZE)}, /* 2-function */ + + /* MT6628 *//* Not an SDIO standard class device */ + {MTK_WCN_HIF_SDIO_FUNC(0x037A, 0x6628, 2, STP_SDIO_BLK_SIZE)}, /* 2-function */ + + /* MT6630 *//* Not an SDIO standard class device */ + {MTK_WCN_HIF_SDIO_FUNC(0x037A, 0x6630, 2, STP_SDIO_BLK_SIZE)}, /* 2-function */ + + /* MT6632 *//* Not an SDIO standard class device */ + {MTK_WCN_HIF_SDIO_FUNC(0x037A, 0x6632, 2, STP_SDIO_BLK_SIZE)}, /* 2-function */ + { /* end: all zeroes */ }, +}; + +wait_queue_head_t g_ownback_done; +INT32 is_wait_ownback; +/* static void (*cmb_bgf_eirq_cb)(void) = NULL; */ + +/* STP SDIO client information for hif sdio driver registration */ +const MTK_WCN_HIF_SDIO_CLTINFO g_stp_sdio_cltinfo = { + .func_tbl = mtk_stp_sdio_id_tbl, + .func_tbl_size = (sizeof(mtk_stp_sdio_id_tbl) / sizeof(MTK_WCN_HIF_SDIO_FUNCINFO) - 1), + .hif_clt_irq = stp_sdio_irq, + .hif_clt_probe = stp_sdio_probe, + .hif_clt_remove = stp_sdio_remove, +}; + +/* STP SDIO host array for multiple hosts maintenance */ +MTK_WCN_STP_SDIO_HIF_INFO g_stp_sdio_host_info; /*[STP_SDIO_HOST_COUNT]; */ +/* STP SDIO host information pointer (for stp if_tx() function) */ +MTK_WCN_STP_SDIO_HIF_INFO *const gp_info = &g_stp_sdio_host_info; + +/* STP-SDIO probe count (not support multiple probe and hosts) */ +UINT32 g_stp_sdio_host_count; + +#if STP_SDIO_DBG_SUPPORT && STP_SDIO_RXDBG +#define STP_SDIO_RXDBG_PROCNAME "driver/stp_sdio_rxdbg" +static struct proc_dir_entry *gStpSdioRxDbgEntry; +static INT32 stp_sdio_rxdbg_cnt; +static struct stp_sdio_rxdbg stp_sdio_rxdbg_buffer[STP_SDIO_RXDBG_COUNT]; +static struct timeval old = {0}; +#define TX_NO_ACK_TIMEOUT_ASSERT 5 /* tx no ack timeout assert, unit:second*/ + +static ssize_t stp_sdio_rxdbg_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos); +static ssize_t stp_sdio_rxdbg_write(struct file *filp, const char __user *buf, size_t count, + loff_t *f_pos); +static const struct file_operations stp_sdio_rxdbg_fops = { + .read = stp_sdio_rxdbg_read, + .write = stp_sdio_rxdbg_write, +}; + +#endif + +#if STP_SDIO_DBG_SUPPORT && STP_SDIO_OWNBACKDBG +#define STP_SDIO_OWNDBG_PROCNAME "driver/stp_sdio_own" +static struct proc_dir_entry *gStpSdioOwnEntry; +static ssize_t stp_sdio_own_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos); +static ssize_t stp_sdio_own_write(struct file *filp, const char __user *buf, size_t count, + loff_t *f_pos); +static const struct file_operations stp_sdio_own_fops = { + .read = stp_sdio_own_read, + .write = stp_sdio_own_write, +}; + +#endif + +#if STP_SDIO_DBG_SUPPORT && (STP_SDIO_TXDBG || STP_SDIO_TXPERFDBG) +#define STP_SDIO_TXDBG_PROCNAME "driver/stp_sdio_txdbg" +static struct proc_dir_entry *gStpSdioTxDbgEntry; + +static ssize_t stp_sdio_txdbg_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos); +static ssize_t stp_sdio_txdbg_write(struct file *filp, const char __user *buf, size_t count, + loff_t *f_pos); +static const struct file_operations stp_sdio_txdbg_fops = { + .read = stp_sdio_txdbg_read, + .write = stp_sdio_txdbg_write, +}; + +#if STP_SDIO_TXDBG +static INT32 stp_sdio_txdbg_cnt; +static struct stp_sdio_txdbg stp_sdio_txdbg_buffer[STP_SDIO_TXDBG_COUNT]; +#endif + +#if STP_SDIO_TXPERFDBG +/* a record for tx worker loop counter */ +static UINT32 stp_sdio_txperf_worker_cnt; + +/* a record for left fifo size in hw when tx wait */ +static UINT32 stp_sdio_txperf_fifo_left; +/* a record for data length when tx wait */ +static UINT32 stp_sdio_txperf_to_send; +/* a record for tx wait fifo limit counter */ +static UINT32 stp_sdio_txperf_fifo_lmt_cnt; + +/* a record for left txed pkt number in tx worker */ +static UINT32 stp_sdio_txperf_txed_pkt_num; +/* a record for tx wait pkt_num limit counter */ +static UINT32 stp_sdio_txperf_pkt_num_lmt_cnt; +#endif +#endif + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("MediaTek Inc WCN_SE_CS3"); +MODULE_DESCRIPTION("Read-Copy Update tracing for hierarchical implementation"); + +INT32 gStpSdioDbgLvl = STPSDIO_LOG_INFO; +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +#define STPSDIO_PR_LOUD(fmt, arg...) \ +do { \ + if (gStpSdioDbgLvl >= STPSDIO_LOG_LOUD) \ + pr_info(DFT_TAG "[L]%s:" fmt, __func__, ##arg); \ +} while (0) + +#define STPSDIO_PR_DBG(fmt, arg...) \ +do { \ + if (gStpSdioDbgLvl >= STPSDIO_LOG_DBG) \ + pr_info(DFT_TAG "[D]%s:" fmt, __func__, ##arg); \ +} while (0) + +#define STPSDIO_PR_HINT(fmt, arg...) \ +do { \ + if (gStpSdioDbgLvl >= STPSDIO_LOG_HINT) \ + pr_info(DFT_TAG "[I]%s:" fmt, __func__, ##arg); \ +} while (0) + +#define STPSDIO_PR_INFO(fmt, arg...) \ +do { \ + if (gStpSdioDbgLvl >= STPSDIO_LOG_INFO) \ + pr_info(DFT_TAG "[I]%s:" fmt, __func__, ##arg); \ +} while (0) + +#define STPSDIO_PR_WARN(fmt, arg...) \ +do { \ + if (gStpSdioDbgLvl >= STPSDIO_LOG_WARN) \ + pr_warn(DFT_TAG "[W]%s:" fmt, __func__, ##arg); \ +} while (0) + +#define STPSDIO_PR_ERR(fmt, arg...) \ +do { \ + if (gStpSdioDbgLvl >= STPSDIO_LOG_ERR) \ + pr_err(DFT_TAG "[E]%s(%d):" fmt, __func__, __LINE__, ##arg); \ +} while (0) + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +#ifdef CONFIG_MTK_COMBO_CHIP_DEEP_SLEEP_SUPPORT +INT32 stp_sdio_deep_sleep_flag_set(MTK_WCN_BOOL flag) +{ + return mtk_wcn_hif_sdio_deep_sleep_flag_set(flag); +} +#endif + +VOID stp_sdio_retry_flag_ctrl(INT32 flag) +{ + gp_info->retry_enable_flag = flag == 0 ? 0 : 1; +} + +INT32 stp_sdio_retry_flag_get(VOID) +{ + return gp_info->retry_enable_flag; +} + +static _osal_inline_ INT32 stp_sdio_host_info_op(INT32 opId) +{ + INT32 iRet = 0; +#if KMALLOC_UPDATE + static PUINT8 p_tx_buffer; + static PUINT8 p_rx_buffer; + + if (p_tx_buffer == NULL) { + p_tx_buffer = kmalloc(STP_SDIO_TX_BUF_CNT * STP_SDIO_TX_ENTRY_SIZE, GFP_ATOMIC); + if (p_tx_buffer == NULL) { + STPSDIO_PR_ERR + ("memory allocate for g_stp_sdio_host_info.pkt_buf.tx_buf fail!\n"); + iRet = -1; + } else { + STPSDIO_PR_DBG + ("memory allocate for g_stp_sdio_host_info.pkt_buf.tx_buf succeed!\n"); + iRet = 0; + } + } else { + STPSDIO_PR_DBG + ("memory already allocated for g_stp_sdio_host_info.pkt_buf.tx_buf!\n"); + iRet = 0; + } + if (p_rx_buffer == NULL) { + p_rx_buffer = kmalloc(STP_SDIO_RX_BUF_SIZE, GFP_ATOMIC); + if (p_rx_buffer == NULL) { + STPSDIO_PR_ERR + ("memory allocate for g_stp_sdio_host_info.pkt_buf.rx_buf fail!\n"); + iRet = -1; + } else { + STPSDIO_PR_DBG + ("memory allocate for g_stp_sdio_host_info.pkt_buf.rx_buf succeed!\n"); + iRet = 0; + } + } else { + STPSDIO_PR_DBG + ("memory already allocated for g_stp_sdio_host_info.pkt_buf.rx_buf!\n"); + iRet = 0; + } +#endif /* KMALLOC_UPDATE */ + + if (iRet == 0 && opId == 0) + iRet = stp_sdio_host_info_deinit(&p_tx_buffer, &p_rx_buffer); + else if (iRet == 0) + iRet = stp_sdio_host_info_init(&p_tx_buffer, &p_rx_buffer); + else + STPSDIO_PR_ERR("iRet (%d)!\n", iRet); + + return iRet; +} + +static _osal_inline_ INT32 stp_sdio_host_info_init(PPUINT8 ppTxBuf, PPUINT8 ppRxBuf) +{ + /* Init host count */ + memset(&g_stp_sdio_host_info, 0, sizeof(g_stp_sdio_host_info)); + +#if KMALLOC_UPDATE + g_stp_sdio_host_info.pkt_buf.tx_buf = *ppTxBuf; + g_stp_sdio_host_info.pkt_buf.rx_buf = *ppRxBuf; +#endif + + return 0; +} + +static _osal_inline_ INT32 stp_sdio_host_info_deinit(PPUINT8 ppTxBuf, PPUINT8 ppRxBuf) +{ +#if KMALLOC_UPDATE + if (*ppTxBuf != NULL) { + kfree(*ppTxBuf); + *ppTxBuf = NULL; + } + if (*ppRxBuf != NULL) { + kfree(*ppRxBuf); + *ppRxBuf = NULL; + } +#endif + + return 0; +} + +INT32 stp_sdio_issue_fake_coredump(UINT8 *str) +{ +#define MAX_STRING_LENGTH 140 + UINT8 AssertStr[4 + MAX_STRING_LENGTH + 1 + 2] = { 0 }; + UINT32 length = strlen(str) >= MAX_STRING_LENGTH ? MAX_STRING_LENGTH : strlen(str); + /*pack str into STP SDIO packet format */ + osal_lock_sleepable_lock(&fake_coredump_lock); + /*STP header */ + AssertStr[0] = 0x80; + AssertStr[1] = 0x50; + AssertStr[2] = (length + 1) & 0xff; + AssertStr[3] = 0x0; + /*STP content */ + memcpy(&AssertStr[4], str, length); + /*string end character */ + AssertStr[4 + length] = '\n'; + /*STP CRC */ + AssertStr[4 + length + 1] = 0x0; + AssertStr[4 + length + 2] = 0x0; + /*send to STP layer coredump content */ + mtk_wcn_stp_parser_data(&AssertStr[0], 4 + length + 1 + 2); + + /*send coredump end content */ + length = strlen("coredump end"); + AssertStr[0] = 0x80; + AssertStr[1] = 0x50; + AssertStr[2] = (length + 2) & 0xff; + AssertStr[3] = 0x0; + memcpy(&AssertStr[4], "coredump end", length); + /*string end character */ + AssertStr[4 + length] = '\r'; + AssertStr[4 + length + 1] = '\n'; + /*STP CRC */ + AssertStr[4 + length + 2] = 0x0; + AssertStr[4 + length + 3] = 0x0; + mtk_wcn_stp_parser_data(&AssertStr[0], 4 + length + 2 + 2); + osal_unlock_sleepable_lock(&fake_coredump_lock); + + STPSDIO_PR_ERR("trigger fake coredump with str:[%s] finished\n", str); + + return 0; +} + +/*! + * \brief + * + * \details + * + * \retval 0 success + * \retval !=0 fail + */ +static _osal_inline_ SDIO_PS_OP stp_sdio_get_own_state(VOID) +{ + SDIO_PS_OP ret = OWN_SET; + INT32 i_ret = 0; + UINT32 chlcpr_value = 0x0; + MTK_WCN_HIF_SDIO_CLTCTX clt_ctx; + + clt_ctx = gp_info->sdio_cltctx; + i_ret = stp_sdio_rw_retry(HIF_TYPE_READL, STP_SDIO_RETRY_LIMIT, clt_ctx, CHLPCR, &chlcpr_value, + 0); + if (i_ret) { + ret = OWN_SET; + STPSDIO_PR_ERR("read CHLPCR fail(%d), return\n", ret); + return ret; + } + if ((chlcpr_value & C_FW_COM_DRV_OWN) == C_FW_COM_DRV_OWN) + ret = OWN_CLR; + else + ret = OWN_SET; + + return ret; +} + +static _osal_inline_ INT32 stp_sdio_do_own_set(MTK_WCN_STP_SDIO_HIF_INFO *p_info) +{ + UINT32 value = 0; + UINT32 iRet = 0; + + /* [COHEC_00006052] SW work-around solution: + * using CMD52 write instead of CMD53 write for CCIR, CHLPCR, CSDIOCSR + */ +#if COHEC_00006052 + value = (C_FW_OWN_REQ_SET >> 8); + iRet = stp_sdio_rw_retry(HIF_TYPE_WRITEB, STP_SDIO_RETRY_LIMIT, p_info->sdio_cltctx, + (UINT32)(CHLPCR + 0x01), &value, 0); +#else + value = C_FW_OWN_REQ_SET; + iRet = stp_sdio_rw_retry(HIF_TYPE_WRITEL, STP_SDIO_RETRY_LIMIT, p_info->sdio_cltctx, CHLPCR, &value, + 0); +#endif /* COHEC_00006052 */ + if (iRet) { + STPSDIO_PR_ERR("write CHLPCR, set firmware own! (sleeping) fail\n"); + } else { + iRet = stp_sdio_rw_retry(HIF_TYPE_READL, STP_SDIO_RETRY_LIMIT, p_info->sdio_cltctx, CHLPCR, + &value, 0); + if (iRet) + STPSDIO_PR_ERR("get firmware own! (sleeping) fail iRet:%d\n", iRet); + else { + if (!(value & C_FW_COM_DRV_OWN)) { + STPSDIO_PR_DBG("set firmware own! (sleeping) ok\n"); + osal_ftrace_print("set F own okay, sleep_flag(%d), wakeup_flag(%d), awake_falg(%d)", + p_info->sleep_flag, p_info->wakeup_flag, p_info->awake_flag); + p_info->awake_flag = 0; + p_info->sleep_flag = 0; + osal_raise_signal(&p_info->isr_check_complete); + osal_ftrace_print("set F own okay and raise signal done"); + } else { + STPSDIO_PR_WARN("set firmware own fail!, set CLR BACK\n"); + osal_ftrace_print("set F own fail, set CLR BACK\n"); + /* if set firmware own not successful(possibly pending interrupts), + * indicate an own clear event + */ + /* [COHEC_00006052] SW work-around solution: + * using CMD52 write instead of CMD53 write for CCIR, CHLPCR, CSDIOCSR + */ +#if COHEC_00006052 + value = (C_FW_OWN_REQ_CLR >> 8); + iRet = stp_sdio_rw_retry(HIF_TYPE_WRITEB, STP_SDIO_RETRY_LIMIT, + p_info->sdio_cltctx, (UINT32)(CHLPCR + 0x01), &value, 0); +#else + value = C_FW_OWN_REQ_CLR; + iRet = stp_sdio_rw_retry(HIF_TYPE_WRITEL, STP_SDIO_RETRY_LIMIT, + p_info->sdio_cltctx, CHLPCR, &value, 0); +#endif /* COHEC_00006052 */ + } + } + } + + return 0; +} + +/*! + * \brief + * + * \details + * + * \retval 0 success + * \retval !=0 fail + */ +static _osal_inline_ INT32 stp_sdio_do_own_clr(INT32 wait) +{ +#define CLR_OWN_RETRY 50 + INT32 ret = -1; + UINT32 time_out; + INT32 retry; + UINT32 chlcpr_value = 0x0; + UINT32 write_value = 0x0; + UINT32 delay_us = 500; + MTK_WCN_HIF_SDIO_CLTCTX clt_ctx; + + clt_ctx = gp_info->sdio_cltctx; + retry = 40; + + /* <1> request firmware-own back */ + STPSDIO_PR_DBG("Do FW-Own back!(Wakeup)\n"); + if (wait) { + /* TODO:[FixMe][George] why use both polling & interrupt methods here??? */ + init_waitqueue_head(&g_ownback_done); + + is_wait_ownback = 1; + } +/* need to wait for the ownback completion */ +/* [COHEC_00006052] SW work-around solution: + * using CMD52 write instead of CMD53 write for CCIR, CHLPCR, CSDIOCSR + */ + while (retry-- > 0) { +#if COHEC_00006052 + write_value = (C_FW_OWN_REQ_CLR>>8); + ret = stp_sdio_rw_retry(HIF_TYPE_WRITEB, STP_SDIO_RETRY_LIMIT, clt_ctx, + (UINT32)(CHLPCR+0x1), &write_value, 0); +#else + write_value = C_FW_OWN_REQ_CLR; + ret = stp_sdio_rw_retry(HIF_TYPE_WRITEL, STP_SDIO_RETRY_LIMIT, clt_ctx, CHLPCR, + &write_value, 0); +#endif /* COHEC_00006052 */ + if (ret) { + STPSDIO_PR_ERR("request firmware own back fail(%d)\n", ret); + osal_dbg_assert_aee(" sdio_write ERROR", + "write CHLPCR by SDIO report error"); + if (retry == 0) + goto out; + } else + break; + } + retry = 1200;/*wait for 1200*500 = 600 000 us*/ + do { + ret = stp_sdio_rw_retry(HIF_TYPE_READL, STP_SDIO_RETRY_LIMIT, clt_ctx, CHLPCR, + &chlcpr_value, 0); + if (ret) { + /* 4 <1.1> get CHISR Rx error handling */ + STPSDIO_PR_ERR("get CHLPCR information rx error!(%d)\n", ret); + goto out; + } + + if ((chlcpr_value & C_FW_COM_DRV_OWN) == C_FW_COM_DRV_OWN) { + /* 4 <2> handle ownership back interrupt */ + STPSDIO_PR_DBG("firmware ownback is polled!(%d)\n", + CLR_OWN_RETRY - retry); + /*osal_usleep_range(2000, 2000);*/ + break; + } + STPSDIO_PR_DBG("firmware ownback is no polled, wait for (%d us) and retry\n", delay_us); + osal_usleep_range(delay_us, 2*delay_us); + if (0 == (retry - 1)%40) + STPSDIO_PR_ERR("own back failed in %d us, something might goes wrong\n", + 40*delay_us); + + if (0 == (retry - 1)%200) { +#if COHEC_00006052 + write_value = (C_FW_OWN_REQ_CLR>>8); + ret = stp_sdio_rw_retry(HIF_TYPE_WRITEB, STP_SDIO_RETRY_LIMIT, clt_ctx, + (UINT32)(CHLPCR+0x1), &write_value, 0); +#else + write_value = C_FW_OWN_REQ_CLR; + ret = stp_sdio_rw_retry(HIF_TYPE_WRITEL, STP_SDIO_RETRY_LIMIT, clt_ctx, CHLPCR, + &write_value, 0); +#endif /* COHEC_00006052 */ + if (ret) + STPSDIO_PR_ERR("request firmware own back fail(%d)\n", ret); + STPSDIO_PR_ERR("own back failed in %d us, write again\n", 200*delay_us); + stp_dbg_poll_cpupcr(5, 1, 1); + } + } while (retry-- > 0); + if (wait) { + /* <2> wait own_back bit is set. */ + time_out = wait_event_timeout(g_ownback_done, + is_wait_ownback == 0, (1000 / (1000 / HZ))); + + if (time_out != 0) { + STPSDIO_PR_INFO("Do FW-Own back!(Wakeup) succeed\n"); + ret = 0; + } else { + STPSDIO_PR_ERR("Do FW-Own back!(Wakeup) fail\n"); + ret = -1; + } + } else + ret = retry > 0 ? 0 : -1; + +out: + return ret; +} + +/*! + * \brief + * + * \details + * + * \param[IN] op code for SDIO PS and OWN control + * + * \retval 0 success + * \retval !=0 fail + */ +INT32 stp_sdio_own_ctrl(SDIO_PS_OP op) +{ + INT32 ret = -1; + P_OSAL_SIGNAL pOsalSignal = NULL; + + if (g_stp_sdio_host_count == 0) { + STPSDIO_PR_WARN("g_stp_sdio_host_count is 0, do nothing!\n"); + return 0; + } + pOsalSignal = &gp_info->isr_check_complete; + switch (op) { + case OWN_SET: + gp_info->wakeup_flag = 0; + gp_info->sleep_flag = 1; + osal_trigger_event(&gp_info->tx_rx_event); + STPSDIO_PR_LOUD("before op(%d)\n", op); + osal_ftrace_print("own set start, wakeup_flag(%d), sleep_flag(%d), wait signal", + gp_info->wakeup_flag, gp_info->sleep_flag); + ret = osal_wait_for_signal_timeout(pOsalSignal, NULL); + if (!ret) + STPSDIO_PR_ERR("OWN_SET fail, done(%d), sleep(%d), wakeup(%d)\n", + pOsalSignal->comp.done, gp_info->sleep_flag, gp_info->wakeup_flag); + STPSDIO_PR_LOUD("after op(%d)\n", op); + ret = 0; + break; + + case OWN_CLR: + /* ret = stp_sdio_do_own_clr(1); */ + gp_info->sleep_flag = 0; + gp_info->wakeup_flag = 1; + osal_trigger_event(&gp_info->tx_rx_event); + osal_ftrace_print("own clear start, wakeup_flag(%d), sleep_flag(%d), wait signal", + gp_info->wakeup_flag, gp_info->sleep_flag); + STPSDIO_PR_LOUD("before op(%d)\n", op); + ret = osal_wait_for_signal_timeout(pOsalSignal, NULL); + if (!ret) + STPSDIO_PR_ERR("OWN_CLER fail, done(%d), sleep(%d), wakeup(%d)\n", + pOsalSignal->comp.done, gp_info->sleep_flag, gp_info->wakeup_flag); + STPSDIO_PR_LOUD("after op(%d)\n", op); + ret = 0; + break; + case OWN_STATE: + /* ret = stp_sdio_get_own_state(); */ + STPSDIO_PR_INFO("omit op(%d)\n", op); + ret = 0; + break; + default: + STPSDIO_PR_WARN("omit op(%d)\n", op); + ret = -1; + break; + } + osal_ftrace_print("own control end, wakeup_flag(%d), sleep_flag(%d), signal done", + gp_info->wakeup_flag, gp_info->sleep_flag); + return ret; +} + +#if STP_SDIO_OWN_THREAD + +static INT32 stp_sdio_wait_for_msg(PVOID pvData) +{ + MTK_WCN_STP_SDIO_HIF_INFO *pInfo = (MTK_WCN_STP_SDIO_HIF_INFO *) pvData; +#if STP_SDIO_NEW_TXRING + STPSDIO_PR_LOUD + ("len(%u), wr_cnt(%u), rd_cnt(%u), irq_pending(%u), sleep(%u), wakeup(%u)\n", + pInfo->rx_pkt_len, atomic_read(&pInfo->pkt_buf.wr_cnt), atomic_read(&pInfo->pkt_buf.rd_cnt), + pInfo->irq_pending, pInfo->sleep_flag, pInfo->wakeup_flag); + osal_ftrace_print("len(%u), txwkr(%u), irq(%u), sleep(%u), wakeup(%u), tx_pkt_num(%u))\n", + pInfo->rx_pkt_len, pInfo->txwkr_flag, pInfo->irq_pending, pInfo->sleep_flag, pInfo->wakeup_flag, + pInfo->firmware_info.tx_packet_num); + return (pInfo->rx_pkt_len != 0) + || (pInfo->txwkr_flag != 0) + || (pInfo->irq_pending != 0) + || (pInfo->sleep_flag != 0) + || (pInfo->wakeup_flag != 0) + || (osal_thread_should_stop(&pInfo->tx_rx_thread)); +#else + STPSDIO_PR_LOUD + ("len(%u), rd_idx(%u), wr_idx(%u), irq_pending(%u), sleep(%u), wakeup(%u)\n", + pInfo->rx_pkt_len, atomic_read(&pInfo->pkt_buf.rd_idx), atomic_read(&pInfo->pkt_buf.wr_idx), + pInfo->irq_pending, pInfo->sleep_flag, pInfo->wakeup_flag); + osal_ftrace_print("len(%u), txwkr(%u), irq(%u), sleep(%u), wakeup(%u), tx_pkt_num(%u)\n", + pInfo->rx_pkt_len, pInfo->txwkr_flag, pInfo->irq_pending, pInfo->sleep_flag, pInfo->wakeup_flag, + pInfo->firmware_info.tx_packet_num); + return (pInfo->rx_pkt_len != 0) + || (pInfo->txwkr_flag != 0) + || (pInfo->irq_pending != 0) + || (pInfo->sleep_flag != 0) + || (pInfo->wakeup_flag != 0) + || (osal_thread_should_stop(&pInfo->tx_rx_thread)); +#endif /* STP_SDIO_NEW_TXRING */ +} + +static VOID stp_sdio_tx_rx_handling(PVOID pData) +{ + MTK_WCN_STP_SDIO_HIF_INFO *pInfo = (MTK_WCN_STP_SDIO_HIF_INFO *) pData; + UINT32 iRet = 0; + UINT32 chisr = 0; + UINT32 chlcpr_value = 0; + UINT32 write_value = 0; + UINT32 tx_comp = 0; + MTK_WCN_HIF_SDIO_CLTCTX clt_ctx; + UINT32 while_loop_counter = 0; + UINT32 own_fail_counter = 0; + UINT32 val = 0; + UINT32 delay_us = 10000; + UINT32 chisr_error_count = 3; + + STPSDIO_PR_INFO("stp_tx_rx_thread start running...\n"); + if (pInfo == NULL) { + STPSDIO_PR_WARN("sanity check fail, (pInfo == NULL)\n"); + return; + } + clt_ctx = pInfo->sdio_cltctx; + + while (!osal_thread_should_stop(&pInfo->tx_rx_thread)) { + while_loop_counter++; + osal_ftrace_print("loop_count:%d\n", while_loop_counter); + /* <0> get CHLPCR information */ + if (pInfo->awake_flag == 0) { + if (CLTCTX_CID(clt_ctx) == 0x6632) + stp_sdio_wake_up_ctrl(clt_ctx); + if (stp_sdio_do_own_clr(0) == 0) { + STPSDIO_PR_DBG("set OWN to driver side ok!\n"); + pInfo->awake_flag = 1; + osal_ftrace_print("set OWN D ok!, sleep_flag(%d), wakeup_flag(%d), awake_falg(%d)", + pInfo->sleep_flag, pInfo->wakeup_flag, pInfo->awake_flag); + own_fail_counter = 0; + } else { + if ((pInfo->sleep_flag != 0) || (pInfo->wakeup_flag != 0)) { + pInfo->wakeup_flag = 0; + pInfo->sleep_flag = 0; + STPSDIO_PR_WARN("clr fw own fail,signal for sleep/wakeup to return\n"); + osal_raise_signal(&pInfo->isr_check_complete); + } + if ((own_fail_counter % 50) == 0) { + STPSDIO_PR_ERR("set OWN to driver side error!\n"); + /*trigger whole chip reset by send fake coredump content */ + if (own_fail_counter == 0) + stp_sdio_issue_fake_coredump + ("ABT: STP-SDIO clear f/w own failed"); + } + own_fail_counter++; + } + } else { + STPSDIO_PR_DBG("OWN on driver side!\n"); + osal_ftrace_print("OWN D , sleep_flag(%d), wakeup_flag(%d), awake_falg(%d)", + pInfo->sleep_flag, pInfo->wakeup_flag, pInfo->awake_flag); + } + + if ((pInfo->wakeup_flag != 0) && (pInfo->awake_flag != 0)) { + while_loop_counter = 0; + STPSDIO_PR_DBG("clr firmware own! (wakeup) ok\n"); + pInfo->wakeup_flag = 0; + osal_raise_signal(&pInfo->isr_check_complete); + osal_ftrace_print("wakeup done\n"); + } + + if ((pInfo->irq_pending != 0) && (pInfo->awake_flag == 1)) { + while_loop_counter = 0; + + /* <1> get CHISR information */ + iRet = mtk_wcn_hif_sdio_readl(clt_ctx, CHISR, &chisr); + if (iRet) { + /* 4 <1.1> get CHISR Rx error handling */ + /* TODO: error handling! */ + STPSDIO_PR_ERR("get CHISR information rx error, ret:%d\n", iRet); + if (-5 == iRet) { + iRet = stp_sdio_rw_retry(HIF_TYPE_READL, STP_SDIO_MAX_RETRY_NUM, + clt_ctx, CSR, &chisr, 0); + pInfo->irq_pending = 0; + } + } else { + pInfo->irq_pending = 0; + osal_ftrace_print("CHISR(0x%08x)\n", chisr); + } + + if (pInfo->dump_flag != 0) + STPSDIO_PR_ERR("CHISR(0x%08x)\n", chisr); + else + STPSDIO_PR_DBG("CHISR(0x%08x)\n", chisr); + + + if (chisr == 0x0) { + STPSDIO_PR_ERR("******CHISR == 0*****\n"); + while (chisr_error_count) { + stp_sdio_rw_retry(HIF_TYPE_READL, STP_SDIO_RETRY_LIMIT, + clt_ctx, CCIR, &val, 0); + STPSDIO_PR_ERR("******CCIR == 0x%x*****\n", val); + stp_sdio_rw_retry(HIF_TYPE_READL, STP_SDIO_RETRY_LIMIT, + clt_ctx, CHLPCR, &val, 0); + STPSDIO_PR_ERR("******CHLPCR == 0x%x*****\n", val); + stp_sdio_rw_retry(HIF_TYPE_READL, STP_SDIO_RETRY_LIMIT, + clt_ctx, CSDIOCSR, &val, 0); + STPSDIO_PR_ERR("******CSDIOCSR == 0x%x*****\n", val); + stp_sdio_rw_retry(HIF_TYPE_READL, STP_SDIO_RETRY_LIMIT, + clt_ctx, CHCR, &val, 0); + STPSDIO_PR_ERR("******CHCR == 0x%x*****\n", val); + stp_sdio_rw_retry(HIF_TYPE_READL, STP_SDIO_RETRY_LIMIT, + clt_ctx, CHISR, &chisr, 0); + STPSDIO_PR_ERR("******CHISR == 0x%x*****\n", chisr); + if (chisr) + break; + stp_sdio_rw_retry(HIF_TYPE_READL, STP_SDIO_RETRY_LIMIT, + clt_ctx, CHIER, &val, 0); + STPSDIO_PR_ERR("******CHIER == 0x%x*****\n", val); + stp_sdio_rw_retry(HIF_TYPE_READL, STP_SDIO_RETRY_LIMIT, + clt_ctx, CTFSR, &val, 0); + STPSDIO_PR_ERR("******CTFSR == 0x%x*****\n", val); + stp_sdio_rw_retry(HIF_TYPE_READL, STP_SDIO_RETRY_LIMIT, + clt_ctx, CRPLR, &val, 0); + STPSDIO_PR_ERR("******CRPLR == 0x%x*****\n", val); + chisr_error_count--; + osal_usleep_range(delay_us, 2 * delay_us); + } + } + + if (chisr & FW_OWN_BACK_INT) + STPSDIO_PR_HINT("FW_OWN_BACK_INT\n"); + + /* <4> handle Tx interrupt */ + if ((chisr & TX_EMPTY) || (chisr & TX_UNDER_THOLD) || (chisr & TX_RETRY)) { + while_loop_counter = 0; + STPSDIO_PR_DBG("Tx interrupt\n"); + /* get complete count */ + tx_comp = (chisr & TX_COMPLETE_COUNT) >> 4; + + tx_comp = + atomic_add_return(tx_comp, &pInfo->firmware_info.tx_comp_num); + if (tx_comp > STP_SDIO_TX_PKT_MAX_CNT) + STPSDIO_PR_ERR + ("Abnormal accumulated comp count(%d) chisr(0x%x)\n", + tx_comp, chisr); + if (chisr & TX_RETRY) + pInfo->tx_retry_flag = STP_SDIO_RETRY_INT; + } + if (pInfo->awake_flag == 1 && pInfo->tx_retry_flag != STP_SDIO_RETRY_CRC_ERROR) + stp_sdio_tx_wkr(&pInfo->tx_work); + + if (chisr & RX_DONE) { + /* STPSDIO_PR_INFO("RX_DONE_INT\n"); */ + if (pInfo->rx_pkt_len) + STPSDIO_PR_ERR("rx worker is not finished yet!\n"); + + /* get Rx packet length */ + pInfo->rx_pkt_len = (chisr & RX_PKT_LEN) >> 16; + STPSDIO_PR_HINT("rx_pkt_len(%d)\n", pInfo->rx_pkt_len); + /* sanity check */ + if ((pInfo->rx_pkt_len == 0) || + (pInfo->rx_pkt_len > STP_SDIO_RX_FIFO_SIZE)) { + STPSDIO_PR_ERR + ("abnormal rx_pkt_len(%d) in CHISR(0x%08x) skip rx_worker\n", + pInfo->rx_pkt_len, chisr); + pInfo->rx_pkt_len = 0; + } else { + /* Before host driver read all rx data, chip/fw will not send more + * data to host. No need to mask rx interrupt. schedule rx worker to + * get data back and handle it. + */ + if (pInfo->rx_pkt_len & 0x3) + STPSDIO_PR_WARN("rx len not 4 bytes, CHISR(0x%08x), rx len (%d).\n", + chisr, pInfo->rx_pkt_len); + } + /*Rx job */ + stp_sdio_rx_wkr(&pInfo->rx_work); + mtk_wcn_stp_wmt_sdio_host_awake(); + } + + } + + /* We schedule Tx job here without condition */ + /*Tx job */ + if (pInfo->awake_flag == 1 && pInfo->tx_retry_flag != STP_SDIO_RETRY_CRC_ERROR) + stp_sdio_tx_wkr(&pInfo->tx_work); + + /*Enable IRQ */ + /*Disable Common interrupt output in CHLPCR */ + STPSDIO_PR_DBG("enable COM IRQ\n"); + osal_ftrace_print("enable COM IRQ\n"); +/* need to wait for the ownback completion */ +/* [COHEC_00006052] SW work-around solution: + * using CMD52 write instead of CMD53 write for CCIR, CHLPCR, CSDIOCSR + */ +#if COHEC_00006052 + write_value = C_FW_INT_EN_SET; + iRet = stp_sdio_rw_retry(HIF_TYPE_WRITEB, STP_SDIO_RETRY_LIMIT, clt_ctx, CHLPCR, + &write_value, 0); +#else + write_value = C_FW_INT_EN_SET; + iRet = stp_sdio_rw_retry(HIF_TYPE_WRITEL, STP_SDIO_RETRY_LIMIT, clt_ctx, CHLPCR, + &write_value, 0); +#endif /* COHEC_00006052 */ + if (iRet) { + STPSDIO_PR_ERR("enable IRQ fail. iRet:%d\n", iRet); + osal_ftrace_print("enable COM IRQ fail, iRet:%d\n", iRet); + } else { + STPSDIO_PR_HINT("enable COM IRQ\n"); + iRet = stp_sdio_rw_retry(HIF_TYPE_READL, STP_SDIO_RETRY_LIMIT, clt_ctx, CHLPCR, + &chlcpr_value, 0); + if (iRet) { + STPSDIO_PR_ERR("read CHLPCR fail. iRet:%d\n", iRet); + } else { + if (chlcpr_value & C_FW_INT_EN_SET) { + STPSDIO_PR_HINT("enable COM IRQ okay (0x%x)\n", + chlcpr_value); + osal_ftrace_print("enable COM IRQ done\n"); + + /* INTR_STATUS CHECK */ +#if 0 + write_value = 0x00000002; + iRet = stp_sdio_rw_retry(HIF_TYPE_WRITEL, STP_SDIO_RETRY_LIMIT, + clt_ctx, CHCR, &write_value, 0); + + iRet = stp_sdio_rw_retry(HIF_TYPE_READL, STP_SDIO_RETRY_LIMIT, + clt_ctx, CHISR, &chisr, 0); + STPSDIO_PR_INFO("Query CHISR(0x%08x)\n", chisr); + + write_value = 0x00000000; + iRet = stp_sdio_rw_retry(HIF_TYPE_WRITEL, STP_SDIO_RETRY_LIMIT, + clt_ctx, CHCR, &write_value, 0); +#endif + } + } + + } + + if ((pInfo->sleep_flag != 0) + && (pInfo->wakeup_flag == 0) + && (pInfo->irq_pending == 0) + && (pInfo->rx_pkt_len == 0) + && mtk_wcn_stp_is_ready() + && !mtk_wcn_stp_coredump_start_get() /* f/w assert disable sdio sleep */ + ) { + if (pInfo->firmware_info.tx_packet_num == 0) { + /* pInfo->awake_flag = 0; */ + /* STPSDIO_PR_INFO("set firmware own! (sleeping)\n"); */ + while_loop_counter = 0; + osal_ftrace_print("|S|set F own\n"); + stp_sdio_do_own_set(pInfo); + osal_ftrace_print("|E|set F own, sleep_flag(%d), wakeup_flag(%d), awake_falg(%d)", + pInfo->sleep_flag, pInfo->wakeup_flag, pInfo->awake_flag); + } else { +#if 0 + /* debug code */ + if (while_loop_counter > 150) { + osal_ftrace_print("assert, w_l_c > %u\n", while_loop_counter); + stp_sdio_rw_retry(HIF_TYPE_READL, STP_SDIO_RETRY_LIMIT, clt_ctx, + CHLPCR, &val, 0); + osal_ftrace_print("CHLPCR(0x%x)\n", val); + stp_sdio_rw_retry(HIF_TYPE_READL, STP_SDIO_RETRY_LIMIT, clt_ctx, + CHISR, &val, 0); + osal_ftrace_print("CHISR(0x%x)\n", val); + iRet = wmt_core_trigger_stp_assert(); + if (!iRet) + STPSDIO_PR_INFO("trigger assert fail\n"); + } +#endif + /*Avoid competition for SDIO operations with ksdioirqd/mmc2 thread*/ + osal_usleep_range(300, 500); + } + } + if (while_loop_counter > 1000) { + while_loop_counter = 0; + pInfo->dump_flag = 1; + STPSDIO_PR_ERR("stp_sdio_tx_rx thread while_loop_counter over1000\n"); + stp_sdio_dump_info(pInfo); + osal_ftrace_print("stp(%d)irq(%d)tx_pkt_num(%d)rx_pkt_len(%d)", + mtk_wcn_stp_is_ready(), pInfo->irq_pending, + pInfo->firmware_info.tx_packet_num, pInfo->rx_pkt_len); + /*make fake irq flag to dump CHISR information */ + pInfo->irq_pending = 1; + + if ((pInfo->sleep_flag != 0) || (pInfo->wakeup_flag != 0)) { + osal_ftrace_print("loop_count > 1000, sleep_flag(%d), wakeup_flag(%d), awake_flag(%d)", + pInfo->sleep_flag, pInfo->wakeup_flag, pInfo->awake_flag); + /*clear wakeup/sleep pending flag, wakeup wmtd thread */ + pInfo->wakeup_flag = 0; + pInfo->sleep_flag = 0; + osal_raise_signal(&pInfo->isr_check_complete); + if (pInfo->firmware_info.tx_packet_num == STP_SDIO_TX_PKT_MAX_CNT) { + STPSDIO_PR_ERR("STP-SDIO can't handle tx request. tx_packet_num:%d\n", + pInfo->firmware_info.tx_packet_num); + osal_sleep_ms(200); + } + } + } else { + pInfo->dump_flag = 0; + } + osal_wait_for_event(&pInfo->tx_rx_event, stp_sdio_wait_for_msg, (PVOID) pInfo); + /* Read Packet from Firmware until firmware rx packet empty */ + STPSDIO_PR_DBG("stp_tx_rx_thread receive signal\n"); + } + /*make sure thread who is waiting for STP-SDIO's sleep/wakeup completion event */ + if ((pInfo->sleep_flag != 0) || (pInfo->wakeup_flag != 0)) { + osal_ftrace_print("wait for sleep/wakeup event, sleep_flag(%d), wakeup_flag(%d), awake_falg(%d)", + pInfo->sleep_flag, pInfo->wakeup_flag, pInfo->awake_flag); + pInfo->wakeup_flag = 0; + pInfo->sleep_flag = 0; + STPSDIO_PR_WARN("someone is wait for sleep/wakeup event, signal it to return\n"); + osal_raise_signal(&pInfo->isr_check_complete); + } + STPSDIO_PR_INFO("stp_tx_rx_thread exit\n"); +} +#endif /* STP_SDIO_OWN_THREAD */ + +/*! + * \brief Tx callback function for STP-CORE module + * + * \details A function registered to STP-CORE to provide STP-SDIO tx method. + * Multiple STP packet may be aggregated when available. + * + * \param[IN] data STP packet buffer to be sent through STP-SDIO + * \param[IN] size STP packet length to be sent + * \param[OUT] written_size Accepted buffer length by STP-SDIO. Shall be $size + * if success. + * + *\note Tx may do aggregation to previous entry with lock protection. If no + * aggregation is done, protection is NOT required. + * + * \retval 0 success + * \retval -1 invalid input parameters + * \todo return !0 when fail case (TBD) + */ +#if STP_SDIO_NEW_TXRING +INT32 stp_sdio_tx(const PUINT8 data, const UINT32 size, PUINT32 written_size) +{ + PUINT8 pkt_bufp; + UINT32 prev_wr_idx; + UINT32 prev_size; + MTK_WCN_STP_SDIO_PKT_BUF *pb = NULL; + UINT32 idx; + + osal_ftrace_print("%s|S|L|%d\n", __func__, size); + if (written_size) + *written_size = 0; + + /* do sanity check */ + if ((size > STP_SDIO_TX_FIFO_SIZE) + || (!data)) { + STPSDIO_PR_LOUD("invalid size(%ld) > fifo(%d) or data(0x%p)\n", + size, STP_SDIO_TX_FIFO_SIZE, data); + return -1; + } + + pb = &gp_info->pkt_buf; + /* 4 <1> enqueue the stp Tx packet */ + + spin_lock_irqsave(&pb->rd_cnt_lock, pb->rd_irq_flag); + /* Case 1: buffer is empty (No aggregation). Full flag is useless in this + * condition. + */ + if (atomic_read(&pb->rd_cnt) == atomic_read(&pb->wr_cnt)) { + spin_unlock_irqrestore(&pb->rd_cnt_lock, pb->rd_irq_flag); + /* Set the size in SDIO packet header later in tx_worker, not here */ + idx = atomic_read(&pb->wr_cnt) & STP_SDIO_TX_BUF_CNT_MASK; + pb->tx_buf_ts[idx] = jiffies; + pb->tx_buf_sz[idx] = size + STP_SDIO_HDR_SIZE; +#if KMALLOC_UPDATE + pkt_bufp = pb->tx_buf + idx * STP_SDIO_TX_ENTRY_SIZE + STP_SDIO_HDR_SIZE; +#else + pkt_bufp = &pb->tx_buf[idx][STP_SDIO_HDR_SIZE]; +#endif + memcpy(pkt_bufp, data, size); + gp_info->txwkr_flag = 1; + atomic_inc(&pb->wr_cnt); + + if (written_size) + *written_size = size; + STPSDIO_PR_DBG("(Empty) Enqueue done\n"); + } + /* Case 2: buffer is neither empty(w != r) nor full (w-r < s) */ + else if ((atomic_read(&pb->wr_cnt) - atomic_read(&pb->rd_cnt)) < STP_SDIO_TX_BUF_CNT) { + prev_wr_idx = (atomic_read(&pb->wr_cnt) - 1) & STP_SDIO_TX_BUF_CNT_MASK; + prev_size = pb->tx_buf_sz[prev_wr_idx]; + + /* Case 2.1 Aggregate if rd_cnt+1 != wr_cnt */ + /* George: do length check using add instead of sub operation. Compare + * to FIFO size instead of sw entry size. + */ + if (((atomic_read(&pb->rd_cnt) + 1) != atomic_read(&pb->wr_cnt)) + && ((size + prev_size) <= STP_SDIO_TX_FIFO_SIZE)) { +#if KMALLOC_UPDATE + pkt_bufp = pb->tx_buf + prev_wr_idx * STP_SDIO_TX_ENTRY_SIZE + prev_size; +#else + pkt_bufp = &pb->tx_buf[prev_wr_idx][prev_size]; +#endif + pb->tx_buf_sz[prev_wr_idx] += size; + + memcpy(pkt_bufp, data, size); + spin_unlock_irqrestore(&pb->rd_cnt_lock, pb->rd_irq_flag); + + STPSDIO_PR_DBG("(Not empty-aggre) Enqueue done\n"); + + if (written_size) + *written_size = size; + } + /* Case 2.2 Use next entry w/o aggregation */ + else { + /* Check the ring buf is full or not */ + if ((atomic_read(&pb->wr_cnt) - atomic_read(&pb->rd_cnt)) == 1) + pb->full_flag = MTK_WCN_BOOL_TRUE; + spin_unlock_irqrestore(&pb->rd_cnt_lock, pb->rd_irq_flag); + + /* George: if tx_wkr preempts here and pop out all buffered entries, + * ie increase rd_idx utill wr_idx, tx_wkr will encounter buffer + * empty condition and stop, then being scheduled before end of this + * function. It's safe! + */ + idx = atomic_read(&pb->wr_cnt) & STP_SDIO_TX_BUF_CNT_MASK; + pb->tx_buf_ts[idx] = jiffies; + pb->tx_buf_sz[idx] = size + STP_SDIO_HDR_SIZE; +#if KMALLOC_UPDATE + pkt_bufp = pb->tx_buf + idx * STP_SDIO_TX_ENTRY_SIZE + STP_SDIO_HDR_SIZE; +#else + pkt_bufp = &pb->tx_buf[idx][STP_SDIO_HDR_SIZE]; +#endif + memcpy(pkt_bufp, data, size); + gp_info->txwkr_flag = 1; + atomic_inc(&pb->wr_cnt); + + STPSDIO_PR_DBG("(Not empty-no aggre) Enqueue done\n"); + if (written_size) + *written_size = size; + } + } + /* Case 3: buffer is full (w-r >= s), (try aggregation) */ + else { + if (!((atomic_read(&pb->wr_cnt) - atomic_read(&pb->rd_cnt)) >= STP_SDIO_TX_BUF_CNT)) { + STPSDIO_PR_ERR + ("abnormal condition and flow, wr_cnt(0x%x), rd_cnt(0x%x)\n", + atomic_read(&pb->wr_cnt), atomic_read(&pb->rd_cnt)); + } + prev_wr_idx = (atomic_read(&pb->wr_cnt) - 1) & STP_SDIO_TX_BUF_CNT_MASK; + prev_size = pb->tx_buf_sz[prev_wr_idx]; + + /* George: do length check using add instead of sub operation. Compare + * to FIFO size instead of sw entry size. (buf_allocation != 0) shall be + * an assert true condition, not a if () condition...... + */ + /* Case 3.1 Aggregation */ + if ((size + prev_size) <= STP_SDIO_TX_FIFO_SIZE) { + if (prev_size != 0) + STPSDIO_PR_ERR("abnormal, wr_cnt(0x%x), rd_cnt(0x%x), prev(%d), prev_size(%d)\n", + atomic_read(&pb->wr_cnt), atomic_read(&pb->rd_cnt), + prev_wr_idx, prev_size); +#if KMALLOC_UPDATE + pkt_bufp = pb->tx_buf + prev_wr_idx * STP_SDIO_TX_ENTRY_SIZE + prev_size; +#else + pkt_bufp = &pb->tx_buf[prev_wr_idx][prev_size]; +#endif + pb->tx_buf_sz[prev_wr_idx] += size; + + /* unlock after copying data to ring buffer done so that rd_cnt can + * move forward and may overlap to prev_wr_idx. + */ + memcpy(pkt_bufp, data, size); + spin_unlock_irqrestore(&pb->rd_cnt_lock, pb->rd_irq_flag); + + STPSDIO_PR_DBG("(full-aggre) Enqueue done\n"); + + if (written_size) + *written_size = size; + } + /* Case 3.2 Buffer is full */ + else { + spin_unlock_irqrestore(&pb->rd_cnt_lock, pb->rd_irq_flag); + STPSDIO_PR_WARN("Local Tx buffer is full !\n"); + + /* Wait for tx ring buffer is not full */ + /* TODO:[FixMe][George] This wait() call IS a problem if caller runs + * in interrupt context (sw or hw) !! + */ + /* TODO:[FixMe][George] should use timeout version, + * not interruptible version. Return error when timeout! + */ + wait_event_interruptible(pb->fullwait_q, + (pb->full_flag == MTK_WCN_BOOL_FALSE)); + STPSDIO_PR_INFO("wait event return\n"); + + spin_lock_irqsave(&pb->rd_cnt_lock, pb->rd_irq_flag); + /* Check if the local buf is free enough */ + if ((atomic_read(&pb->wr_cnt) - atomic_read(&pb->rd_cnt)) == 1) + pb->full_flag = MTK_WCN_BOOL_TRUE; + spin_unlock_irqrestore(&pb->rd_cnt_lock, pb->rd_irq_flag); + + /* George: use this new entry w/o protection */ + idx = atomic(&pb->wr_cnt) & STP_SDIO_TX_BUF_CNT_MASK; + pb->tx_buf_ts[idx] = jiffies; + pb->tx_buf_sz[idx] = size + STP_SDIO_HDR_SIZE; +#if KMALLOC_UPDATE + pkt_bufp = pb->tx_buf + idx * STP_SDIO_TX_ENTRY_SIZE + STP_SDIO_HDR_SIZE; +#else + pkt_bufp = &pb->tx_buf[idx][STP_SDIO_HDR_SIZE]; +#endif + /* Copy data to ring buffer */ + memcpy(pkt_bufp, data, size); + gp_info->txwkr_flag = 1; + atomic_inc(&pb->wr_cnt); + + if (written_size) + *written_size = size; + } + } + + /* <2> schedule for Tx worker tasklet */ + osal_ftrace_print("%s|E|signal stp_sdio_tx_rx\n", __func__); +#if STP_SDIO_OWN_THREAD + /* tasklet_schedule(&gp_info->tx_rx_job); */ + STPSDIO_PR_DBG("osal_trigger_event gp_info->tx_rx_event\n"); + osal_trigger_event(&gp_info->tx_rx_event); +#else + schedule_work(&gp_info->tx_work); +#endif + osal_ftrace_print("%s|E|L|%d\n", __func__, size); + + return 0; +} + +#else +INT32 stp_sdio_tx(const PUINT8 data, const UINT32 size, PUINT32 written_size) +{ + PUINT8 pkt_bufp; + UINT32 prev_wr_idx; + UINT32 buf_allocation; + UINT32 room; + UINT64 ts; + ULONG nsec; + + osal_ftrace_print("%s|S|L|%d\n", __func__, size); + + /* 4 <1> enqueue the stp Tx packet */ + *written_size = 0; + + spin_lock_irqsave(&gp_info->pkt_buf.rd_idx_lock, gp_info->pkt_buf.rd_irq_flag); + /* Case 1: buffer is empty (Not aggregation) */ + if ((atomic_read(&gp_info->pkt_buf.rd_idx) == atomic_read(&gp_info->pkt_buf.wr_idx)) + && (gp_info->pkt_buf.full_flag == MTK_WCN_BOOL_FALSE)) { + spin_unlock_irqrestore(&gp_info->pkt_buf.rd_idx_lock, gp_info->pkt_buf.rd_irq_flag); + /* set the size in SDIO packet header */ +#if KMALLOC_UPDATE + *(gp_info->pkt_buf.tx_buf + atomic_read(&gp_info->pkt_buf.wr_idx) * + STP_SDIO_TX_ENTRY_SIZE + 0) = (UINT8)((size + STP_SDIO_HDR_SIZE) & 0xff); + *(gp_info->pkt_buf.tx_buf + atomic_read(&gp_info->pkt_buf.wr_idx) * + STP_SDIO_TX_ENTRY_SIZE + 1) = (UINT8)((size + STP_SDIO_HDR_SIZE) >> 8); +#else + gp_info->pkt_buf.tx_buf[atomic_read(&gp_info->pkt_buf.wr_idx)][0] = + (UINT8) ((size + STP_SDIO_HDR_SIZE) & 0xff); + gp_info->pkt_buf.tx_buf[atomic_read(&gp_info->pkt_buf.wr_idx)][1] = + (UINT8) ((size + STP_SDIO_HDR_SIZE) >> 8); +#endif + gp_info->pkt_buf.tx_buf_ts[atomic_read(&gp_info->pkt_buf.wr_idx)] = jiffies; + osal_get_local_time(&ts, &nsec); + gp_info->pkt_buf.tx_buf_local_ts[atomic_read(&gp_info->pkt_buf.wr_idx)] = ts; + gp_info->pkt_buf.tx_buf_local_nsec[atomic_read(&gp_info->pkt_buf.wr_idx)] = nsec; + + STPSDIO_PR_DBG("(Empty) Enqueue done\n"); +#if KMALLOC_UPDATE + pkt_bufp = gp_info->pkt_buf.tx_buf + atomic_read(&gp_info->pkt_buf.wr_idx) * + STP_SDIO_TX_ENTRY_SIZE + STP_SDIO_HDR_SIZE; +#else + pkt_bufp = &gp_info->pkt_buf.tx_buf[atomic_read(&gp_info->pkt_buf.wr_idx)][STP_SDIO_HDR_SIZE]; +#endif + memcpy(pkt_bufp, data, size); + *written_size = size; + gp_info->txwkr_flag = 1; + atomic_set(&gp_info->pkt_buf.wr_idx, + (atomic_read(&gp_info->pkt_buf.wr_idx) + 1) % STP_SDIO_TX_BUF_CNT); + } + /* Case 2: buffer is not empty */ + else if (atomic_read(&gp_info->pkt_buf.rd_idx) != atomic_read(&gp_info->pkt_buf.wr_idx)) { + prev_wr_idx = (atomic_read(&gp_info->pkt_buf.wr_idx) - 1 + STP_SDIO_TX_BUF_CNT) % + STP_SDIO_TX_BUF_CNT; + /* set the packet size form previous SDIO packet header */ +#if KMALLOC_UPDATE + buf_allocation = + *(gp_info->pkt_buf.tx_buf + prev_wr_idx * STP_SDIO_TX_ENTRY_SIZE + 1); + buf_allocation = + (buf_allocation << 8) | *(gp_info->pkt_buf.tx_buf + + prev_wr_idx * STP_SDIO_TX_ENTRY_SIZE + 0); +#else + buf_allocation = gp_info->pkt_buf.tx_buf[prev_wr_idx][1]; + buf_allocation = (buf_allocation << 8) | gp_info->pkt_buf.tx_buf[prev_wr_idx][0]; +#endif + /* Case 2.1 Aggregation */ + /* George: do length check using add instead of sub operation. Compare + * to FIFO size instead of sw entry size. + */ + if ((prev_wr_idx != atomic_read(&gp_info->pkt_buf.rd_idx)) + && ((size + buf_allocation) <= STP_SDIO_TX_FIFO_SIZE)) { +#if KMALLOC_UPDATE + pkt_bufp = + gp_info->pkt_buf.tx_buf + prev_wr_idx * STP_SDIO_TX_ENTRY_SIZE + + buf_allocation; + + buf_allocation += size; + *(gp_info->pkt_buf.tx_buf + prev_wr_idx * STP_SDIO_TX_ENTRY_SIZE + 0) = + (UINT8) (buf_allocation & 0xff); + *(gp_info->pkt_buf.tx_buf + prev_wr_idx * STP_SDIO_TX_ENTRY_SIZE + 1) = + (UINT8) (buf_allocation >> 8); +#else + pkt_bufp = &gp_info->pkt_buf.tx_buf[prev_wr_idx][buf_allocation]; + + buf_allocation += size; + gp_info->pkt_buf.tx_buf[prev_wr_idx][0] = (UINT8) (buf_allocation & 0xff); + gp_info->pkt_buf.tx_buf[prev_wr_idx][1] = (UINT8) (buf_allocation >> 8); +#endif + memcpy(pkt_bufp, data, size); + spin_unlock_irqrestore(&gp_info->pkt_buf.rd_idx_lock, + gp_info->pkt_buf.rd_irq_flag); + + STPSDIO_PR_DBG("(Not empty-aggre) Enqueue done\n"); + + *written_size = size; + } + /* Case 2.2 Not aggregation */ + else { + /* Check the ring buf is full or not */ + room = (atomic_read(&gp_info->pkt_buf.wr_idx) >= + atomic_read(&gp_info->pkt_buf.rd_idx)) ? (STP_SDIO_TX_BUF_CNT - + (atomic_read(&gp_info->pkt_buf.wr_idx) - + atomic_read(&gp_info->pkt_buf.rd_idx))) : + (atomic_read(&gp_info->pkt_buf.rd_idx) - + atomic_read(&gp_info->pkt_buf.wr_idx)); + if (room == 1) + gp_info->pkt_buf.full_flag = MTK_WCN_BOOL_TRUE; + spin_unlock_irqrestore(&gp_info->pkt_buf.rd_idx_lock, + gp_info->pkt_buf.rd_irq_flag); + + /* George: if tx_wkr preempts here and pop out all buffered entries, + * ie increase rd_idx utill wr_idx, tx_wkr will encounter buffer + * empty condition and stop, then being scheduled before end of this + * function. It's safe! + */ + + /* set the size in SDIO packet header */ +#if KMALLOC_UPDATE + *(gp_info->pkt_buf.tx_buf + + atomic_read(&gp_info->pkt_buf.wr_idx) * STP_SDIO_TX_ENTRY_SIZE + 0) = + (UINT8) ((size + STP_SDIO_HDR_SIZE) & 0xff); + *(gp_info->pkt_buf.tx_buf + + atomic_read(&gp_info->pkt_buf.wr_idx) * STP_SDIO_TX_ENTRY_SIZE + 1) = + (UINT8) ((size + STP_SDIO_HDR_SIZE) >> 8); + gp_info->pkt_buf.tx_buf_ts[atomic_read(&gp_info->pkt_buf.wr_idx)] = jiffies; + osal_get_local_time(&ts, &nsec); + gp_info->pkt_buf.tx_buf_local_ts[atomic_read(&gp_info->pkt_buf.wr_idx)] = ts; + gp_info->pkt_buf.tx_buf_local_nsec[atomic_read(&gp_info->pkt_buf.wr_idx)] = nsec; + + pkt_bufp = + gp_info->pkt_buf.tx_buf + + atomic_read(&gp_info->pkt_buf.wr_idx) * STP_SDIO_TX_ENTRY_SIZE + STP_SDIO_HDR_SIZE; +#else + gp_info->pkt_buf.tx_buf[atomic_read(&gp_info->pkt_buf.wr_idx)][0] = + (UINT8) ((size + STP_SDIO_HDR_SIZE) & 0xff); + gp_info->pkt_buf.tx_buf[atomic_read(&gp_info->pkt_buf.wr_idx)][1] = + (UINT8) ((size + STP_SDIO_HDR_SIZE) >> 8); + gp_info->pkt_buf.tx_buf_ts[atomic_read(&gp_info->pkt_buf.wr_idx)] = jiffies; + + pkt_bufp = &gp_info->pkt_buf. + tx_buf[atomic_read(&gp_info->pkt_buf.wr_idx)][STP_SDIO_HDR_SIZE]; +#endif + memcpy(pkt_bufp, data, size); + + STPSDIO_PR_DBG("(Not empty-no aggre) Enqueue done\n"); + + *written_size = size; + gp_info->txwkr_flag = 1; + atomic_set(&gp_info->pkt_buf.wr_idx, + (atomic_read(&gp_info->pkt_buf.wr_idx) + 1) % STP_SDIO_TX_BUF_CNT); + } + } + /* Case 3: buffer is full (Aggregation) */ + else if (gp_info->pkt_buf.full_flag != MTK_WCN_BOOL_FALSE) { + prev_wr_idx = (atomic_read(&gp_info->pkt_buf.wr_idx) - 1 + STP_SDIO_TX_BUF_CNT) % + STP_SDIO_TX_BUF_CNT; +#if KMALLOC_UPDATE + buf_allocation = + *(gp_info->pkt_buf.tx_buf + prev_wr_idx * STP_SDIO_TX_ENTRY_SIZE + 1); + buf_allocation = + (buf_allocation << 8) | *(gp_info->pkt_buf.tx_buf + + prev_wr_idx * STP_SDIO_TX_ENTRY_SIZE + 0); +#else + buf_allocation = gp_info->pkt_buf.tx_buf[prev_wr_idx][1]; + buf_allocation = (buf_allocation << 8) | gp_info->pkt_buf.tx_buf[prev_wr_idx][0]; +#endif + /* Case 3.1 Aggregation */ + /* George: do length check using add instead of sub operation. Compare + * to FIFO size instead of sw entry size. (buf_allocation != 0) shall be + * an assert true condition, not a if () condition...... + */ + if ((buf_allocation != 0) + && ((size + buf_allocation) <= STP_SDIO_TX_FIFO_SIZE)) { +#if KMALLOC_UPDATE + pkt_bufp = + gp_info->pkt_buf.tx_buf + prev_wr_idx * STP_SDIO_TX_ENTRY_SIZE + + buf_allocation; +#else + pkt_bufp = &gp_info->pkt_buf.tx_buf[prev_wr_idx][buf_allocation]; +#endif + buf_allocation += size; +#if KMALLOC_UPDATE + *(gp_info->pkt_buf.tx_buf + prev_wr_idx * STP_SDIO_TX_ENTRY_SIZE + 0) = + (UINT8) (buf_allocation & 0xff); + *(gp_info->pkt_buf.tx_buf + prev_wr_idx * STP_SDIO_TX_ENTRY_SIZE + 1) = + (UINT8) (buf_allocation >> 8); +#else + gp_info->pkt_buf.tx_buf[prev_wr_idx][0] = (UINT8) (buf_allocation & 0xff); + gp_info->pkt_buf.tx_buf[prev_wr_idx][1] = (UINT8) (buf_allocation >> 8); +#endif + /* Copy data to ring buffer */ + memcpy(pkt_bufp, data, size); + spin_unlock_irqrestore(&gp_info->pkt_buf.rd_idx_lock, + gp_info->pkt_buf.rd_irq_flag); + + STPSDIO_PR_DBG("(full-aggre) Enqueue done\n"); + + *written_size = size; + } + /* Case 3.2 Buffer is full */ + else { + spin_unlock_irqrestore(&gp_info->pkt_buf.rd_idx_lock, + gp_info->pkt_buf.rd_irq_flag); + STPSDIO_PR_WARN("Local Tx buffer is full !!!!!\n"); + + /* Wait for tx ring buffer is not full + * TODO:[FixMe][George] This wait() call IS a problem + * if caller runs in interrupt context (sw or hw) !! + * TODO:[FixMe][George] should use timeout version, + * not interruptible version. Return error when timeout! + */ + wait_event_interruptible(gp_info->pkt_buf.fullwait_q, + (!gp_info->pkt_buf.full_flag)); + STPSDIO_PR_INFO("wait event return\n"); + + spin_lock_irqsave(&gp_info->pkt_buf.rd_idx_lock, + gp_info->pkt_buf.rd_irq_flag); + /* Check if the local buf is free enough */ + room = (atomic_read(&gp_info->pkt_buf.wr_idx) >= + atomic_read(&gp_info->pkt_buf.rd_idx)) ? + (STP_SDIO_TX_BUF_CNT - (atomic_read(&gp_info->pkt_buf.wr_idx) - + atomic_read(&gp_info->pkt_buf.rd_idx))) : + (atomic_read(&gp_info->pkt_buf.rd_idx) - + atomic_read(&gp_info->pkt_buf.wr_idx)); + if (room == 1) + gp_info->pkt_buf.full_flag = MTK_WCN_BOOL_TRUE; + spin_unlock_irqrestore(&gp_info->pkt_buf.rd_idx_lock, + gp_info->pkt_buf.rd_irq_flag); + + /* George: use this new entry w/o protection */ +#if KMALLOC_UPDATE + *(gp_info->pkt_buf.tx_buf + atomic_read(&gp_info->pkt_buf.wr_idx) * + STP_SDIO_TX_ENTRY_SIZE + 0) = + (UINT8) ((size + STP_SDIO_HDR_SIZE) & 0xff); + *(gp_info->pkt_buf.tx_buf + atomic_read(&gp_info->pkt_buf.wr_idx) * + STP_SDIO_TX_ENTRY_SIZE + 1) = + (UINT8) ((size + STP_SDIO_HDR_SIZE) >> 8); + gp_info->pkt_buf.tx_buf_ts[atomic_read(&gp_info->pkt_buf.wr_idx)] = jiffies; + osal_get_local_time(&ts, &nsec); + gp_info->pkt_buf.tx_buf_local_ts[atomic_read(&gp_info->pkt_buf.wr_idx)] = ts; + gp_info->pkt_buf.tx_buf_local_nsec[atomic_read(&gp_info->pkt_buf.wr_idx)] = nsec; + + pkt_bufp = gp_info->pkt_buf.tx_buf + atomic_read(&gp_info->pkt_buf.wr_idx) + * STP_SDIO_TX_ENTRY_SIZE + STP_SDIO_HDR_SIZE; +#else + gp_info->pkt_buf.tx_buf[atomic_read(&gp_info->pkt_buf.wr_idx)][0] = + (UINT8) ((size + STP_SDIO_HDR_SIZE) & 0xff); + gp_info->pkt_buf.tx_buf[atomic_read(&gp_info->pkt_buf.wr_idx)][1] = + (UINT8) ((size + STP_SDIO_HDR_SIZE) >> 8); + gp_info->pkt_buf.tx_buf_ts[atomic_read(&gp_info->pkt_buf.wr_idx)] = jiffies; + + pkt_bufp = &gp_info->pkt_buf. + tx_buf[atomic_read(&gp_info->pkt_buf.wr_idx)][STP_SDIO_HDR_SIZE]; +#endif + /* Copy data to ring buffer */ + memcpy(pkt_bufp, data, size); + *written_size = size; + gp_info->txwkr_flag = 1; + atomic_set(&gp_info->pkt_buf.wr_idx, + (atomic_read(&gp_info->pkt_buf.wr_idx) + 1) % STP_SDIO_TX_BUF_CNT); + } + } + /* <2> schedule for Tx worker tasklet */ + osal_ftrace_print("%s|E|signal stp_sdio_tx_rx\n", __func__); +#if STP_SDIO_OWN_THREAD + /* tasklet_schedule(&gp_info->tx_rx_job); */ + STPSDIO_PR_DBG("osal_trigger_event gp_info->tx_rx_event\n"); + osal_trigger_event(&gp_info->tx_rx_event); +#else + schedule_work(&gp_info->tx_work); +#endif + osal_ftrace_print("%s|E|L|%d\n", __func__, size); + + return 0; +} +#endif /* end of !STP_SDIO_NEW_TXRING */ + +/*! + * \brief Do STP-SDIO tx status, counters, debug information sanity check + * + * \details A function doing sanity checks on STP-SDIO Tx-related status, + * counters, debugging information. Used in tx_worker before and after bus + * write to check if any abnormal status happened. + * + * \param[IN] p_info The STP-SDIO HIF information structure pointer + * \param[IN] id The sanity check location ID, assigned by caller + * + * \retval none. + */ +static _osal_inline_ VOID stp_sdio_check_tx_sanity(const MTK_WCN_STP_SDIO_HIF_INFO *p_info, const UINT32 id) +{ +#if STP_SDIO_DBG_SUPPORT && STP_SDIO_TXDBG + if ((p_info) && (p_info->firmware_info.tx_packet_num == 0)) { + if (!(p_info->tx_pkt_list.pkt_rd_cnt == p_info->tx_pkt_list.pkt_wr_cnt)) { + STPSDIO_PR_ERR + ("abnormal fifo_size(%d) pkt_num(%d) pkt_rd(0x%x, %ld) pkt_wr(0x%x, %ld)!(%d)\n", + p_info->firmware_info.tx_fifo_size, + p_info->firmware_info.tx_packet_num, p_info->tx_pkt_list.pkt_rd_cnt, + STP_SDIO_GET_PKT_AR_IDX(p_info->tx_pkt_list.pkt_rd_cnt), + p_info->tx_pkt_list.pkt_wr_cnt, + STP_SDIO_GET_PKT_AR_IDX(p_info->tx_pkt_list.pkt_wr_cnt), id); + /* stp_sdio_dump_txdbg(); */ + } + if (p_info->firmware_info.tx_fifo_size != STP_SDIO_TX_FIFO_SIZE) { + STPSDIO_PR_ERR + ("abnormal fifo_size(%d) pkt_num(%d) pkt_rd(0x%x, %ld) pkt_wr(0x%x, %ld)!(%d)\n", + p_info->firmware_info.tx_fifo_size, + p_info->firmware_info.tx_packet_num, p_info->tx_pkt_list.pkt_rd_cnt, + STP_SDIO_GET_PKT_AR_IDX(p_info->tx_pkt_list.pkt_rd_cnt), + p_info->tx_pkt_list.pkt_wr_cnt, + STP_SDIO_GET_PKT_AR_IDX(p_info->tx_pkt_list.pkt_wr_cnt), id); + /* stp_sdio_dump_txdbg(); */ + } + } else { + if ((p_info) && (p_info->tx_pkt_list.pkt_rd_cnt == p_info->tx_pkt_list.pkt_wr_cnt)) { + STPSDIO_PR_ERR + ("abnormal fifo_size(%d) pkt_num(%d) pkt_rd(0x%x, %ld) pkt_wr(0x%x, %ld)!(%d)\n", + p_info->firmware_info.tx_fifo_size, + p_info->firmware_info.tx_packet_num, p_info->tx_pkt_list.pkt_rd_cnt, + STP_SDIO_GET_PKT_AR_IDX(p_info->tx_pkt_list.pkt_rd_cnt), + p_info->tx_pkt_list.pkt_wr_cnt, + STP_SDIO_GET_PKT_AR_IDX(p_info->tx_pkt_list.pkt_wr_cnt), id); + /* stp_sdio_dump_txdbg(); */ + } + } +#endif +} + +/*! + * \brief Handle STP-SDIO TX IRQ BH part and complete count + * + * \details Handle STP-SDIO TX IRQ bottom half part and reported tx complete + * coount. This function is used in tx_worker ONLY to avoid race condition. + * + * \note tx_comp_num in firmware_info structure shall be handled atomically. + * It is added in STP-SDIO Tx IRQ top half handler with the number reported + * in CHISR. It is deducted in this function. + * + * \note tx_fifo_size is deducted in tx_worker when writing data to bus and + * added back in this function when tx complete. + * + * \param[IN] p_info The STP-SDIO HIF information structure pointer + * + * \retval none. + */ +static VOID stp_sdio_tx_wkr_comp(MTK_WCN_STP_SDIO_HIF_INFO * const p_info) +{ + INT32 comp_count; + UINT32 idx; + INT32 i; + INT32 max; + INT32 ret; + UINT32 value = 0; + + comp_count = atomic_read(&p_info->firmware_info.tx_comp_num); + atomic_sub(comp_count, &p_info->firmware_info.tx_comp_num); + + /* update tx to firemware information */ + if (p_info->firmware_info.tx_packet_num >= comp_count) { + STPSDIO_PR_DBG("tx_pack_num(%d), comp_count(%d),tx_comp_num(%d), retry flag(%d)\n", + p_info->firmware_info.tx_packet_num, comp_count, + atomic_read(&p_info->firmware_info.tx_comp_num), + p_info->tx_retry_flag); + p_info->firmware_info.tx_packet_num -= comp_count; + } else { + STPSDIO_PR_INFO("abnormal complete count(%d), tx_packet_num(%d), retry flag(%d)!\n", + comp_count, p_info->firmware_info.tx_packet_num, p_info->tx_retry_flag); + /* TODO: [FixMe][George] Add error handling or bug report!! */ + STPSDIO_PR_INFO("tx_fifo_size(%d), tx_packet_num(%d)\n", + p_info->firmware_info.tx_fifo_size, + p_info->firmware_info.tx_packet_num); + } + + while (comp_count > 0) { + if (p_info->tx_pkt_list.pkt_rd_cnt == p_info->tx_pkt_list.pkt_wr_cnt) { + STPSDIO_PR_ERR("tx complete count(%d) but tx_pkt_list empty\n", + comp_count); + STPSDIO_PR_ERR("rd_cnt(%u, idx:%lx), wr_cnt(%u, idx:%lx)!\n", + p_info->tx_pkt_list.pkt_rd_cnt, + p_info->tx_pkt_list.pkt_rd_cnt & STP_SDIO_TX_PKT_LIST_SIZE_MASK, + p_info->tx_pkt_list.pkt_wr_cnt, + p_info->tx_pkt_list.pkt_wr_cnt & STP_SDIO_TX_PKT_LIST_SIZE_MASK); + break; + } + + idx = p_info->tx_pkt_list.pkt_rd_cnt++ & STP_SDIO_TX_PKT_LIST_SIZE_MASK; + p_info->firmware_info.tx_fifo_size += p_info->tx_pkt_list.pkt_size_list[idx]; + p_info->tx_pkt_list.out_ts[idx] = jiffies; + --comp_count; + } + if (p_info->retry_enable_flag) { + if (p_info->tx_retry_flag == STP_SDIO_RETRY_INT) { + for (i = 0; i < 100; i++) { + ret = stp_sdio_rw_retry(HIF_TYPE_READL, STP_SDIO_RETRY_LIMIT, p_info->sdio_cltctx, + CTMDPCR0, &value, 0); + if (value & 1) + break; + osal_sleep_ms(10); + } + if (!(value & 1)) { + stp_sdio_rw_retry(HIF_TYPE_READL, STP_SDIO_RETRY_LIMIT, p_info->sdio_cltctx, + CTMDPCR0, &value, 0); + STPSDIO_PR_ERR("tx retry: firmware rx buffer is disable CTMDPCR0 value(%x)!\n", + value); + stp_sdio_rw_retry(HIF_TYPE_READL, STP_SDIO_RETRY_LIMIT, p_info->sdio_cltctx, + CTMDPCR1, &value, 0); + STPSDIO_PR_ERR("tx retry: firmware rx buffer is disable CTMDPCR1 value(%x)!\n", + value); + stp_sdio_issue_fake_coredump + ("ABT: tx retry ERROR: firmware rx buffer is disable"); + } + idx = p_info->tx_pkt_list.pkt_rd_cnt & STP_SDIO_TX_PKT_LIST_SIZE_MASK; + max = p_info->firmware_info.tx_packet_num; + STPSDIO_PR_ERR("tx retry idx(%d) tx retry max(%d)\n", idx, max); + for (i = 0; i < max; i++) { + /* sdio crc error tx retry */ + ret = stp_sdio_rw_retry(HIF_TYPE_WRITE_BUF, STP_SDIO_RETRY_LIMIT, + p_info->sdio_cltctx, CTDR, + (PUINT32)(p_info->pkt_buf.tx_buf + idx * STP_SDIO_TX_ENTRY_SIZE + 0), + p_info->tx_pkt_list.pkt_size_list[idx]); + if (ret) { + STPSDIO_PR_ERR("sdio tx retry get CTDR information Tx error(%d)!\n", + ret); + /* TODO: error handling! */ + p_info->tx_retry_count++; + if (p_info->tx_retry_count > STP_SDIO_RETRY_LIMIT) { + STPSDIO_PR_INFO("sdio tx retry fail complete count(%d)\n", + comp_count); + STPSDIO_PR_INFO("tx_packet_num(%d), tx_fifo_size(%d)\n", + p_info->firmware_info.tx_packet_num, + p_info->firmware_info.tx_fifo_size); + STPSDIO_PR_INFO("retry flag(%d)!\n", p_info->tx_retry_flag); + /* TODO: error handling! */ +#if STP_SDIO_DBG_SUPPORT && STP_SDIO_TXDBG + stp_sdio_txdbg_dump(); +#endif + p_info->tx_retry_count = 0; + stp_sdio_issue_fake_coredump + ("ABT: write_readsb retry ERROR"); + } + } else + p_info->tx_retry_count = 0; + idx++; + idx = idx & STP_SDIO_TX_PKT_LIST_SIZE_MASK; + } + p_info->tx_retry_flag = STP_SDIO_RETRY_NONE; + } + } +} + +/*! + * \brief Handle STP-SDIO Tx buffer and send to bus + * + * \details Handle STP-SDIO Tx buffer and send SDIO packet to bus if everything + * is checked ok. + * + * \note Tx count to FIFO is counted on a 4-byte aligned base. 1~3 bytes padding + * are also sent into HW FIFO and SHALL be trimmed off by firmware. + * tx_fifo_size is deducted in this bus when writing data to bus and added + * back in handle_tx_comp() function. + * + * \note Data length written to bus shall be 4-byte aligned AND block_size + * aligned if length > block_size. Padding bytes added for block_size is + * removed by HW. + * + * \note Max accumulated Tx size to FIFO is limited by STP_SDIO_TX_FIFO_SIZE and + * it is (2080) for MT6620. It is NOT limited to 256*5=1280 bytes. + * + * \note Max outstanding Tx packet count is limited by STP_SDIO_TX_PKT_MAX_CNT + * and it is (7) for MT6620. + * + * \param[IN] work Tx work struct work_struct pointer used by STP-SDIO + * + * \retval none. + */ +#if STP_SDIO_NEW_TXRING +static VOID stp_sdio_tx_wkr(struct work_struct *work) +{ + MTK_WCN_STP_SDIO_HIF_INFO *p_info; + UINT32 bus_txlen; + UINT32 four_byte_align_len; + PUINT8 buf_tx; + INT32 ret; + UINT32 idx; + MTK_WCN_STP_SDIO_PKT_BUF *pb; + struct timeval now; + UINT64 ts; + ULONG nsec; + + p_info = container_of(work, MTK_WCN_STP_SDIO_HIF_INFO, tx_work); + ret = HIF_SDIO_ERR_SUCCESS; + pb = &p_info->pkt_buf; + + /* 4 <0> Tx worker has been scheduled to send data */ + do { + /* handle tx complete count if any */ + stp_sdio_tx_wkr_comp(p_info); + /* check sanity of local tx information */ + stp_sdio_check_tx_sanity(p_info, 1); + + /* check if Tx ring buffer is empty */ + if (atomic_read(&p_info->pkt_buf.wr_cnt) == atomic_read(&p_info->pkt_buf.rd_cnt)) { + /* full flag is use less in this condition */ + STPSDIO_PR_DBG("Tx entry ring buffer empty\n"); + break; + } + p_info->txwkr_flag = 0; +#if STP_SDIO_DBG_SUPPORT && STP_SDIO_TXPERFDBG + ++stp_sdio_txperf_worker_cnt; +#endif + + /* George: check txed packet number < limit(7) + * tx_packet_num is maintained only in tw_worker, no protection. + */ + if (p_info->firmware_info.tx_packet_num >= STP_SDIO_TX_PKT_MAX_CNT) { + STPSDIO_PR_DBG + ("tx_packet_num(%ld) limit, tx_fifo_size(%ld), four_byte_align_len(%ld)\n", + p_info->firmware_info.tx_packet_num, + p_info->firmware_info.tx_fifo_size, four_byte_align_len); +#if STP_SDIO_DBG_SUPPORT && STP_SDIO_TXPERFDBG + ++stp_sdio_txperf_pkt_num_lmt_cnt; +#endif + break; + } +#if STP_SDIO_DBG_SUPPORT && STP_SDIO_TXPERFDBG + stp_sdio_txperf_txed_pkt_num += p_info->firmware_info.tx_packet_num; +#endif + + /* Access content in rd_cnt is safe because it will not be aggregated + * anymore in sdio_tx(). Check current tx condition with info in rd_cnt. + */ + idx = atomic(&pb->rd_cnt) & STP_SDIO_TX_BUF_CNT_MASK; + + /* Get Tx packet size from Tx size ring buf */ + bus_txlen = pb->tx_buf_sz[idx]; + /* Update packet length in Tx entry */ +#if KMALLOC_UPDATE + buf_tx = gp_info->pkt_buf.tx_buf + idx * STP_SDIO_TX_ENTRY_SIZE + 0; +#else + buf_tx = &pb->tx_buf[idx][0]; +#endif + buf_tx[0] = (UINT8) (bus_txlen & 0xff); + buf_tx[1] = (UINT8) ((bus_txlen >> 8) & 0xff); + + /* George: hw always count fifo in 4-byte aligned length */ + bus_txlen += 0x3; + bus_txlen &= ~(0x3UL); + four_byte_align_len = bus_txlen; + + /* Sanity check: 4-byte aligned length shall not exceed HW FIFO Size */ + if (four_byte_align_len > STP_SDIO_TX_FIFO_SIZE) { + STPSDIO_PR_ERR("abnormal four_byte_align_len(%d) > TX_FIFO_SIZE(%ld)!!\n", + four_byte_align_len, STP_SDIO_TX_FIFO_SIZE); + } + + /* George: check if tx FIFO space is enough for 4-byte aligned length. + * If enough, tx this entry and increase rd_cnt. + */ + if (p_info->firmware_info.tx_fifo_size >= four_byte_align_len) { + /* George: refine block_size alignment with the assumption: block_size is 2^*x */ + if (bus_txlen > STP_SDIO_BLK_SIZE) { + bus_txlen += (STP_SDIO_BLK_SIZE - 1); + bus_txlen &= ~((UINT32) STP_SDIO_BLK_SIZE - 1); + } + + /* Sanity check: bus_txlen shall not exceed SW entry size */ + if (bus_txlen > STP_SDIO_TX_ENTRY_SIZE) { + STPSDIO_PR_ERR + ("abnormal bus_txlen(%d) > STP_SDIO_TX_ENTRY_SIZE(%ld)!!\n", + bus_txlen, STP_SDIO_TX_ENTRY_SIZE); + } + + ++(p_info->firmware_info.tx_packet_num); + /* decrease Tx FIFO size: using 4-byte aligned length! */ + p_info->firmware_info.tx_fifo_size -= four_byte_align_len; + /* record the SDIO packet size in packet size list: using 4-byte aligned length! */ + idx = p_info->tx_pkt_list.pkt_wr_cnt++ & STP_SDIO_TX_PKT_LIST_SIZE_MASK; + p_info->tx_pkt_list.pkt_size_list[idx] = four_byte_align_len; + p_info->tx_pkt_list.in_ts[idx] = jiffies; + p_info->tx_pkt_list.out_ts[idx] = 0; + + STPSDIO_PR_DBG("wr(0x%x, %ld) rd(0x%x, %ld), tx fifo(size:%d), pkt_num(%d)done\n", + p_info->tx_pkt_list.pkt_wr_cnt, + STP_SDIO_GET_PKT_AR_IDX(p_info->tx_pkt_list.pkt_wr_cnt), + p_info->tx_pkt_list.pkt_rd_cnt, + STP_SDIO_GET_PKT_AR_IDX(p_info->tx_pkt_list.pkt_rd_cnt), + p_info->firmware_info.tx_fifo_size, + p_info->firmware_info.tx_packet_num); + + /* port write the packet to CTDR */ + ret = stp_sdio_rw_retry(HIF_TYPE_WRITE_BUF, STP_SDIO_RETRY_LIMIT, p_info->sdio_cltctx, + CTDR, (PUINT32) buf_tx, bus_txlen); + STPSDIO_PR_DBG("write to CTDR done\n"); + +#if STP_SDIO_DBG_SUPPORT && STP_SDIO_TXDBG + do { + osal_get_local_time(&ts, &nsec); + idx = stp_sdio_txdbg_cnt++ & STP_SDIO_TXDBG_COUNT_MASK; + /* skip clear buf */ + stp_sdio_txdbg_buffer[idx].ts = jiffies; + stp_sdio_txdbg_buffer[idx].l_sec = ts; + stp_sdio_txdbg_buffer[idx].l_nsec = nsec; + stp_sdio_txdbg_buffer[idx].bus_txlen = bus_txlen; + stp_sdio_txdbg_buffer[idx].four_byte_align_len = + four_byte_align_len; + /* store content */ + if (bus_txlen <= STP_SDIO_TX_ENTRY_SIZE) { + memcpy(&stp_sdio_txdbg_buffer[idx].tx_pkt_buf[0], buf_tx, + bus_txlen); + } else { + memcpy(&stp_sdio_txdbg_buffer[idx].tx_pkt_buf[0], buf_tx, + STP_SDIO_TX_ENTRY_SIZE); + STPSDIO_PR_ERR("abnormal bus_txlen (%d)!\n", bus_txlen); + } + } while (0); +#endif + if (ret) { + STPSDIO_PR_ERR("get CTDR information Tx error(%d)!\n", ret); + if (p_info->retry_enable_flag) { + if (ret == -EIO || ret == -EILSEQ || ret == -EBUSY) + p_info->tx_retry_flag = STP_SDIO_RETRY_CRC_ERROR; + else { + p_info->tx_retry_count = 0; + p_info->tx_retry_flag = STP_SDIO_RETRY_NONE; + stp_sdio_issue_fake_coredump + ("ABT: write_readsb retry ERROR"); + } + } else + stp_sdio_issue_fake_coredump("ABT: write_readsb retry ERROR"); + } + + /* clear rd index entry of Tx ring buffer */ + /*memset(buf_tx, 0, STP_SDIO_TX_ENTRY_SIZE); */ + /* George: clear STP-SDIO header only for debugging. */ + /*memset(buf_tx, 0, 4); */ + /* need clear??? skip it for debugging */ + + spin_lock_irqsave(&pb->rd_cnt_lock, pb->rd_irq_flag); + atomic_inc(&pb->rd_cnt); + /* TODO: [FixMe][George] check if full_flag needed? */ + if (pb->full_flag != MTK_WCN_BOOL_FALSE) { + pb->full_flag = MTK_WCN_BOOL_FALSE; + wake_up_interruptible(&pb->fullwait_q); + } + spin_unlock_irqrestore(&pb->rd_cnt_lock, pb->rd_irq_flag); + osal_do_gettimeofday(&old); + } else { + /* tx FIFO free space < packet size, wait next time */ +#if STP_SDIO_DBG_SUPPORT && STP_SDIO_TXPERFDBG + stp_sdio_txperf_fifo_left += p_info->firmware_info.tx_fifo_size; + stp_sdio_txperf_to_send += four_byte_align_len; + ++stp_sdio_txperf_fifo_lmt_cnt; +#endif + + osal_do_gettimeofday(&now); + if ((now.tv_sec - old.tv_sec) > TX_NO_ACK_TIMEOUT_ASSERT) { + STPSDIO_PR_INFO("tx_fifo_size(%d), four_byte_align_len(%d), tx_packet_num(%d)\n", + p_info->firmware_info.tx_fifo_size, four_byte_align_len, + p_info->firmware_info.tx_packet_num); + STPSDIO_PR_INFO("No ack trigger assert, tx %d seconds later\n", + TX_NO_ACK_TIMEOUT_ASSERT); + stp_dbg_poll_cpupcr(5, 1, 1); + p_info->firmware_info.tx_fifo_size = STP_SDIO_TX_FIFO_SIZE; + p_info->firmware_info.tx_packet_num = 0; + if (pb->full_flag != MTK_WCN_BOOL_FALSE) { + pb->full_flag = MTK_WCN_BOOL_FALSE; + wake_up_interruptible(&pb->fullwait_q); + } + ret = mtk_wcn_wmt_assert_timeout(WMTDRV_TYPE_STP, 33, 0); + if (!ret) + STPSDIO_PR_INFO("trigger assert fail\n"); + } + break; + } + + stp_sdio_check_tx_sanity(p_info, 2); + } while (1); +} + +#else +static VOID stp_sdio_tx_wkr(struct work_struct *work) +{ + MTK_WCN_STP_SDIO_HIF_INFO *p_info; + UINT32 bus_txlen; + UINT32 four_byte_align_len; + PUINT8 buf_tx; + INT32 ret; + UINT32 idx; + MTK_WCN_STP_SDIO_PKT_BUF *pb; + struct timeval now; + UINT64 ts; + ULONG nsec; + + p_info = container_of(work, MTK_WCN_STP_SDIO_HIF_INFO, tx_work); + ret = HIF_SDIO_ERR_SUCCESS; + pb = &p_info->pkt_buf; + + /* 4 <0> Tx worker has been scheduled to send data */ + do { + /* handle tx complete count if any */ + stp_sdio_tx_wkr_comp(p_info); + stp_sdio_check_tx_sanity(p_info, 1); + + /* check if Tx ring buffer is empty */ + if ((atomic_read(&p_info->pkt_buf.wr_idx) == atomic_read(&p_info->pkt_buf.rd_idx)) + && (p_info->pkt_buf.full_flag == MTK_WCN_BOOL_FALSE)) { + STPSDIO_PR_DBG("Tx ring buffer is empty\n"); + break; + } + p_info->txwkr_flag = 0; + + /* George: no race condition here! Updating rd_idx content will not be + * put into more data by stp_sdio_tx + */ + /* Get Tx packet size from Tx ring buf */ +#if KMALLOC_UPDATE + buf_tx = gp_info->pkt_buf.tx_buf + + atomic_read(&p_info->pkt_buf.rd_idx) * STP_SDIO_TX_ENTRY_SIZE + 0; +#else + buf_tx = &p_info->pkt_buf.tx_buf[atomic_read(&p_info->pkt_buf.rd_idx)][0]; +#endif + bus_txlen = buf_tx[1]; + bus_txlen = (bus_txlen << 8) | buf_tx[0]; + + /* George: hw always count fifo in 4-byte aligned length */ + bus_txlen += 0x3; + bus_txlen &= ~(0x3UL); + four_byte_align_len = bus_txlen; + /* Sanity check: 4-byte aligned length shall not exceed HW FIFO Size */ + if (four_byte_align_len > STP_SDIO_TX_FIFO_SIZE) { + STPSDIO_PR_ERR("abnormal four_byte_align_len(%d) > TX_FIFO_SIZE(%ld)!!\n", + four_byte_align_len, STP_SDIO_TX_FIFO_SIZE); + } + + osal_ftrace_print("%s|S|bus_txlen(%d)\n", __func__, four_byte_align_len); + /* George: check if + * 1. tx FIFO free space is enough using 4-byte aligned length + * 2. tx max pkt count is not reached + */ + if ((p_info->firmware_info.tx_fifo_size >= four_byte_align_len) + && (p_info->firmware_info.tx_packet_num < STP_SDIO_TX_PKT_MAX_CNT)) { + /* George: refine block_size alignment with the assumption: block_size is 2^*x */ + if (bus_txlen > STP_SDIO_BLK_SIZE) { + bus_txlen += (STP_SDIO_BLK_SIZE - 1); + bus_txlen &= ~((UINT32) STP_SDIO_BLK_SIZE - 1); + } + + /* Sanity check: bus_txlen shall not exceed SW entry size */ + if (bus_txlen > STP_SDIO_TX_ENTRY_SIZE) { + STPSDIO_PR_ERR + ("abnormal bus_txlen(%d) > STP_SDIO_TX_ENTRY_SIZE(%ld)!!\n", + bus_txlen, STP_SDIO_TX_ENTRY_SIZE); + } + + ++(p_info->firmware_info.tx_packet_num); + /* decrease Tx FIFO size: using 4-byte aligned length! */ + p_info->firmware_info.tx_fifo_size -= four_byte_align_len; + /* record the SDIO packet size in packet size list: using 4-byte aligned length! */ + idx = p_info->tx_pkt_list.pkt_wr_cnt++ & STP_SDIO_TX_PKT_LIST_SIZE_MASK; + p_info->tx_pkt_list.pkt_size_list[idx] = four_byte_align_len; + p_info->tx_pkt_list.in_ts[idx] = jiffies; + p_info->tx_pkt_list.out_ts[idx] = 0; + + STPSDIO_PR_DBG("wr(0x%x, %ld) rd(0x%x, %ld), tx fifo(size:%d), pkt_num(%d)done\n", + p_info->tx_pkt_list.pkt_wr_cnt, + STP_SDIO_GET_PKT_AR_IDX(p_info->tx_pkt_list.pkt_wr_cnt), + p_info->tx_pkt_list.pkt_rd_cnt, + STP_SDIO_GET_PKT_AR_IDX(p_info->tx_pkt_list.pkt_rd_cnt), + p_info->firmware_info.tx_fifo_size, + p_info->firmware_info.tx_packet_num); + + /* port write the packet to CTDR */ + ret = stp_sdio_rw_retry(HIF_TYPE_WRITE_BUF, STP_SDIO_RETRY_LIMIT, p_info->sdio_cltctx, + CTDR, (PUINT32) buf_tx, bus_txlen); + STPSDIO_PR_DBG("write to CTDR done\n"); + +#if STP_SDIO_DBG_SUPPORT && STP_SDIO_TXDBG + do { + osal_get_local_time(&ts, &nsec); + idx = stp_sdio_txdbg_cnt++ & STP_SDIO_TXDBG_COUNT_MASK; + /* skip clear buf */ + stp_sdio_txdbg_buffer[idx].ts = jiffies; + stp_sdio_txdbg_buffer[idx].l_sec = ts; + stp_sdio_txdbg_buffer[idx].l_nsec = nsec; + stp_sdio_txdbg_buffer[idx].bus_txlen = bus_txlen; + stp_sdio_txdbg_buffer[idx].four_byte_align_len = + four_byte_align_len; + /* store content */ + if (bus_txlen <= STP_SDIO_TX_ENTRY_SIZE) { + memcpy(&stp_sdio_txdbg_buffer[idx].tx_pkt_buf[0], buf_tx, + bus_txlen); + } else { + memcpy(&stp_sdio_txdbg_buffer[idx].tx_pkt_buf[0], buf_tx, + STP_SDIO_TX_ENTRY_SIZE); + STPSDIO_PR_ERR("abnormal bus_txlen(%d)!\n", bus_txlen); + } + } while (0); +#endif + + if (ret) { + STPSDIO_PR_ERR("get CTDR information Tx error(%d)!\n", ret); + if (p_info->retry_enable_flag) { + if (ret == -EIO || ret == -EILSEQ || ret == -EBUSY) + p_info->tx_retry_flag = STP_SDIO_RETRY_CRC_ERROR; + else { + p_info->tx_retry_count = 0; + p_info->tx_retry_flag = STP_SDIO_RETRY_NONE; + stp_sdio_issue_fake_coredump + ("ABT: write_readsb retry ERROR"); + } + } else + stp_sdio_issue_fake_coredump("ABT: write_readsb retry ERROR"); + } + + /* clear rd index entry of Tx ring buffer */ + /*memset(buf_tx, 0, STP_SDIO_TX_ENTRY_SIZE); */ + /* George: clear STP-SDIO header only for debugging. */ + /*memset(buf_tx, 0, 4); */ + /* need clear??? skip it for debugging */ + + spin_lock_irqsave(&p_info->pkt_buf.rd_idx_lock, + p_info->pkt_buf.rd_irq_flag); + /* release tx ring buffer */ + atomic_set(&p_info->pkt_buf.rd_idx, + (atomic_read(&p_info->pkt_buf.rd_idx) + 1) % STP_SDIO_TX_BUF_CNT); + /* Set Tx ring buffer is not full */ + if (p_info->pkt_buf.full_flag != MTK_WCN_BOOL_FALSE) { + p_info->pkt_buf.full_flag = MTK_WCN_BOOL_FALSE; + wake_up_interruptible(&p_info->pkt_buf.fullwait_q); + } + spin_unlock_irqrestore(&p_info->pkt_buf.rd_idx_lock, + p_info->pkt_buf.rd_irq_flag); + osal_do_gettimeofday(&old); + } else { +#if STP_SDIO_DBG_SUPPORT && STP_SDIO_TXPERFDBG + stp_sdio_txperf_fifo_left += p_info->firmware_info.tx_fifo_size; + stp_sdio_txperf_to_send += four_byte_align_len; + ++stp_sdio_txperf_fifo_lmt_cnt; +#endif + /* (tx FIFO free space < packet size) or (the number of tx packets >= 7) */ + osal_do_gettimeofday(&now); + if ((now.tv_sec - old.tv_sec) > TX_NO_ACK_TIMEOUT_ASSERT) { + STPSDIO_PR_INFO("tx_fifo_size(%d), four_byte_align_len(%d), tx_packet_num(%d)\n", + p_info->firmware_info.tx_fifo_size, four_byte_align_len, + p_info->firmware_info.tx_packet_num); + STPSDIO_PR_INFO("No ack trigger assert, tx %d seconds later\n", + TX_NO_ACK_TIMEOUT_ASSERT); + stp_dbg_poll_cpupcr(5, 1, 1); + osal_ftrace_print("tx_fifo_size:%d, four_byte_align_len:%d, tx_packet_num(%d)\n", + p_info->firmware_info.tx_fifo_size, four_byte_align_len, + p_info->firmware_info.tx_packet_num); + p_info->firmware_info.tx_fifo_size = STP_SDIO_TX_FIFO_SIZE; + p_info->firmware_info.tx_packet_num = 0; + if (pb->full_flag != MTK_WCN_BOOL_FALSE) { + pb->full_flag = MTK_WCN_BOOL_FALSE; + wake_up_interruptible(&pb->fullwait_q); + } + ret = mtk_wcn_wmt_assert_timeout(WMTDRV_TYPE_STP, 33, 0); + if (!ret) + STPSDIO_PR_INFO("trigger assert fail\n"); + } + break; + } + + stp_sdio_check_tx_sanity(p_info, 2); + } while (1); + + osal_ftrace_print("%s|E|\n", __func__); +} +#endif /* end of stp_sdio_tx_wkr and STP_SDIO_NEW_TXRING */ + +/*! + * \brief Handle STP-SDIO Rx IRQ BH and read data from bus + * + * \details Handle STP-SDIO Rx IRQ buttom half and read data from bus according + * to the length read in Rx IRQ top half (stp_sdio_irq()) from CHISR + * + * \note rx_pkt_len read in stp_sdio_irq() from CHISR. No Rx IRQ would be + * triggered by FW before all Rx FIFO data is read by host driver. Do + * sanity check for this condition. + * + * \note HW Rx FIFO size is (2304 = 256*9) for MT6620 + * + * \param[IN] work Rx work struct work_struct pointer used by STP-SDIO + * + * \retval none. + */ +static VOID stp_sdio_rx_wkr(struct work_struct *work) +{ + PUINT8 bufp; + UINT32 bus_rxlen; + UINT32 chisr_rxlen; + INT32 ret; + INT32 ret_1; + UINT8 cccr_value = 0; + MTK_WCN_STP_SDIO_HIF_INFO *p_info; + + p_info = container_of(work, MTK_WCN_STP_SDIO_HIF_INFO, rx_work); + + /* 4 <0> receive data from CRDR */ + /* George: refine 4-byte alignment */ + chisr_rxlen = p_info->rx_pkt_len; + + + if (chisr_rxlen > STP_SDIO_RX_FIFO_SIZE) { + /* TODO: error handling! */ + STPSDIO_PR_ERR("abnormal chisr_rxlen(%d) rx_worker stop\n", chisr_rxlen); + return; + } + + bus_rxlen = chisr_rxlen; + bus_rxlen += 0x3; + bus_rxlen &= ~(0x3UL); + + /* George: refine block_size alignment with the assumption: BLK_SIZE is 2^x. */ + if (bus_rxlen > STP_SDIO_BLK_SIZE) { + bus_rxlen += (STP_SDIO_BLK_SIZE - 1); + bus_rxlen &= ~((UINT32) STP_SDIO_BLK_SIZE - 1); + } + + ret = stp_sdio_rw_retry(HIF_TYPE_READ_BUF, STP_SDIO_RETRY_LIMIT, p_info->sdio_cltctx, CRDR, + (PUINT32)(&(p_info->pkt_buf.rx_buf[0])), bus_rxlen); + if (p_info->retry_enable_flag) { + if (ret) { + if (ret == -EIO || ret == -EILSEQ || ret == -EBUSY) { + cccr_value = 0; + ret_1 = mtk_wcn_hif_sdio_f0_readb(p_info->sdio_cltctx, CCCR_F0, &cccr_value); + if (ret_1) + STPSDIO_PR_ERR("read CCCR_F0 fail(%d)\n", ret_1); + STPSDIO_PR_ERR("read CCCR_F0: (0x%x)\n", cccr_value); + cccr_value |= CCCR_F0_RX_CRC; + cccr_value |= CCCR_F0_RX_INT; + ret_1 = mtk_wcn_hif_sdio_f0_writeb(p_info->sdio_cltctx, CCCR_F0, cccr_value); + if (ret_1) + STPSDIO_PR_ERR("write CCCR_F0 fail(%d)\n", ret_1); + STPSDIO_PR_ERR("write CCCR_F0: (0x%x)\n", cccr_value); + cccr_value = 0; + ret_1 = mtk_wcn_hif_sdio_f0_readb(p_info->sdio_cltctx, CCCR_F0, &cccr_value); + if (ret_1) + STPSDIO_PR_ERR("read CCCR_F0 fail(%d)\n", ret_1); + STPSDIO_PR_ERR("read CCCR_F0: (0x%x)\n", cccr_value); + STPSDIO_PR_ERR("sdio read buffer happen crc error will be retry(%d)\n", ret); + p_info->rx_retry_count++; + if (p_info->rx_retry_count > STP_SDIO_RETRY_LIMIT) { + p_info->rx_retry_count = 0; + stp_sdio_issue_fake_coredump("ABT: sdio_readsb retry ERROR"); + } + } else { + p_info->rx_retry_count = 0; + stp_sdio_issue_fake_coredump("ABT: sdio_readsb retry ERROR"); + } + } else { + cccr_value = 0; + ret_1 = mtk_wcn_hif_sdio_f0_readb(p_info->sdio_cltctx, CCCR_F0, &cccr_value); + if (ret_1) + STPSDIO_PR_ERR("read CCCR_F0 fail(%d)\n", ret_1); + STPSDIO_PR_DBG("read CCCR_F0: (0x%x)\n", cccr_value); + cccr_value &= ~CCCR_F0_RX_CRC; + cccr_value |= CCCR_F0_RX_INT; + ret_1 = mtk_wcn_hif_sdio_f0_writeb(p_info->sdio_cltctx, CCCR_F0, cccr_value); + if (ret_1) + STPSDIO_PR_ERR("write CCCR_F0 fail(%d)\n", ret_1); + STPSDIO_PR_DBG("write CCCR_F0: (0x%x)\n", cccr_value); + cccr_value = 0; + ret_1 = mtk_wcn_hif_sdio_f0_readb(p_info->sdio_cltctx, CCCR_F0, &cccr_value); + if (ret_1) + STPSDIO_PR_ERR("read CCCR_F0 fail(%d)\n", ret_1); + STPSDIO_PR_DBG("read CCCR_F0: (0x%x)\n", cccr_value); + STPSDIO_PR_DBG("sdio read buffer success(%d)\n", ret); + + p_info->rx_retry_count = 0; + } + } else { + if (ret) { + STPSDIO_PR_HINT("set to p_info->rx_pkt_len 0\n"); + stp_sdio_issue_fake_coredump("ABT: sdio_readsb retry ERROR"); + } + } + if (ret) { + /* TODO: error handling! */ + STPSDIO_PR_ERR("read CRDR len(%d) rx error!(%d)\n", bus_rxlen, ret); + p_info->rx_pkt_len = 0; + return; + } + p_info->rx_pkt_len = 0; + STPSDIO_PR_HINT("set to p_info->rx_pkt_len 0\n"); +#if STP_SDIO_DBG_SUPPORT && STP_SDIO_RXDBG + do { + UINT32 idx = stp_sdio_rxdbg_cnt++ & (STP_SDIO_RXDBG_COUNT - 1); + /* skip clear buf */ + stp_sdio_rxdbg_buffer[idx].ts = jiffies; + stp_sdio_rxdbg_buffer[idx].chisr_rxlen = chisr_rxlen; + stp_sdio_rxdbg_buffer[idx].bus_rxlen = bus_rxlen; + /* store content */ + memcpy(&stp_sdio_rxdbg_buffer[idx].rx_pkt_buf[0], &p_info->pkt_buf.rx_buf[0], + bus_rxlen); + } while (0); +#endif + + bufp = &p_info->pkt_buf.rx_buf[4]; + + /* Notice: len = SDIO_HDR(4) + (STP Packet + padding)*N */ + /* George: refine sanity check */ + bus_rxlen = p_info->pkt_buf.rx_buf[1]; + bus_rxlen = (bus_rxlen << 8) | p_info->pkt_buf.rx_buf[0]; + STPSDIO_PR_DBG("bus_rxlen(%d) rx_len in chisr(%d)\n", bus_rxlen, chisr_rxlen); + if (bus_rxlen != chisr_rxlen) { + STPSDIO_PR_ERR("abnormal bus_rxlen(%d) in SDIO packet header!in chisr(%d)\n", + bus_rxlen, chisr_rxlen); + return; + } + if (p_info->pkt_buf.rx_buf[2] || p_info->pkt_buf.rx_buf[3]) { + STPSDIO_PR_ERR("abnormal p_info->pkt_buf.rx_buf[2](0x%02x) [3](0x%02x)\n", + p_info->pkt_buf.rx_buf[2], p_info->pkt_buf.rx_buf[3]); + return; + } + + if (bus_rxlen > STP_SDIO_HDR_SIZE) { + bus_rxlen -= STP_SDIO_HDR_SIZE; + /* transmit data to stp core driver */ + osal_ftrace_print("%s|B|parser|L|%d\n", __func__, bus_rxlen); + ret = mtk_wcn_stp_parser_data(bufp, bus_rxlen); + osal_ftrace_print("%s|A|parser|L|%d\n", __func__, bus_rxlen); +#if STP_SDIO_DBG_SUPPORT && (STP_SDIO_TXDBG || STP_SDIO_TXPERFDBG) + if (ret && (p_info->tx_dbg_dump_flag == 0)) { + p_info->tx_dbg_dump_flag = 1; + stp_sdio_txdbg_dump(); + } +#endif + } else { + STPSDIO_PR_ERR("abnormal rx length(%d, %d)\n", bus_rxlen, chisr_rxlen); + } + + /* [George]: no need to mask/unmask rx interrupt. chip/fw assert next rx int + * if and only if host reads all rx data. + */ +} + +#if STP_SDIO_NEW_IRQ_HANDLER +static INT32 stp_sdio_irq(const MTK_WCN_HIF_SDIO_CLTCTX clt_ctx) +{ + INT32 iRet = 0; + UINT32 chlcpr_value = 0; + UINT32 write_value = 0; + MTK_WCN_STP_SDIO_HIF_INFO *p_info = gp_info; + + STPSDIO_PR_HINT("disable IRQ\n"); + /*Disable Common interrupt output in CHLPCR */ +/* [COHEC_00006052] SW work-around solution: + * using CMD52 write instead of CMD53 write for CCIR, CHLPCR, CSDIOCSR + */ +#if COHEC_00006052 + write_value = C_FW_INT_EN_CLR; + iRet = stp_sdio_rw_retry(HIF_TYPE_WRITEB, STP_SDIO_RETRY_LIMIT, clt_ctx, CHLPCR, + &write_value, 0); +#else + write_value = C_FW_INT_EN_CLR; + iRet = stp_sdio_rw_retry(HIF_TYPE_WRITEL, STP_SDIO_RETRY_LIMIT, clt_ctx, CHLPCR, + &write_value, 0); +#endif /* COHEC_00006052 */ + if (iRet) + STPSDIO_PR_ERR("disalbe IRQ fail\n"); + else { + iRet = stp_sdio_rw_retry(HIF_TYPE_READL, STP_SDIO_RETRY_LIMIT, clt_ctx, CHLPCR, + &chlcpr_value, 0); + if (iRet) + STPSDIO_PR_ERR("read CHLPCR fail. iRet(%d)\n", iRet); + else { + if (!(chlcpr_value & C_FW_INT_EN_SET)) { + STPSDIO_PR_DBG("disable COM IRQ okay (0x%x)\n", chlcpr_value); + p_info->irq_pending = 1; + + /*inform stp_sdio thread to to rx/tx job */ + STPSDIO_PR_DBG("signal stp_tx_rx\n"); + osal_trigger_event(&gp_info->tx_rx_event); + osal_ftrace_print("%s|stp_tx_rx\n", __func__); + } else + STPSDIO_PR_ERR + ("**********disable COM IRQ fail, don't signal stp-sdio thread******\n"); + } + + } + return 0; + +} + +#else +/*! + * \brief Handle STP-SDIO interrupt + * + * \details Top half interrupt handler of STP-SDIO. Most of Tx/Rx jobs are put + * to bottom half workers respectively. + * + * \note Rx ok interrupt shall be asserted by hw ONLY after last data are all + * read by driver. Do sanity check on rx_pkt_len and should be 0: rx BH + * finished. + * + * \note Tx complete count shall be handled atomically TH here and BH in + * tx_worker. + * + * \param[IN] clt_ctx A HIF-SDIO client context + * + * \retval 0 success + * \retval !=0 fail + */ +static INT32 stp_sdio_irq(const MTK_WCN_HIF_SDIO_CLTCTX clt_ctx) +{ + /*MTK_WCN_STP_SDIO_PRIVATE_INFO *p_priv; */ + MTK_WCN_STP_SDIO_HIF_INFO *p_info = NULL; + UINT32 chisr = 0; + UINT32 tx_comp; + INT32 ret; + +#if 0 + p_priv = mtk_wcn_hif_sdio_get_drvdata(clt_ctx); +TODO:[FixMe][George] do sanity check ! + p_info = &g_stp_sdio_host_info[p_priv->stp_sdio_host_idx]; +#endif + p_info = gp_info; + ret = HIF_SDIO_ERR_SUCCESS; + /* 4 <0> get CHLPCR information */ + if (stp_sdio_get_own_state() == OWN_CLR) + STPSDIO_PR_DBG("OWN on driver side!\n"); + else { + STPSDIO_PR_DBG("OWN on fw side!\n"); + if (stp_sdio_do_own_clr(0) == 0) + STPSDIO_PR_DBG("set OWN to driver side ok!\n"); + else { + STPSDIO_PR_ERR("set OWN to driver side error!\n"); + return -1; + } + + } +retry: + /* 4 <1> get CHISR information */ + ret = mtk_wcn_hif_sdio_readl(clt_ctx, CHISR, &chisr); + if (ret) { + /* 4 <1.1> get CHISR Rx error handling */ + /* TODO: error handling! */ + STPSDIO_PR_ERR("get CHISR information rx error,ret:%d\n", ret); + if (ret == -5) { + STPSDIO_PR_ERR("get CHISR DAT CRC error, retry.\n"); + ret = stp_sdio_rw_retry(HIF_TYPE_READL, STP_SDIO_MAX_RETRY_NUM, clt_ctx, CSR, &chisr, + 0); + } else + goto retry; + } + STPSDIO_PR_HINT("CHISR(0x%08x)\n", chisr); + if (chisr == 0x0) { + STPSDIO_PR_ERR("******CHISR == 0*****\n"); + return 0; + } + /* 4 <2> handle ownership back interrupt */ + if (chisr & FW_OWN_BACK_INT) { + STPSDIO_PR_INFO("FW_OWN_BACK_INT\n"); + + if (is_wait_ownback) { + is_wait_ownback = 0; + wake_up(&g_ownback_done); + } else { + mtk_wcn_stp_wmt_sdio_host_awake(); + /* if (cmb_bgf_eirq_cb) { */ + /* (*cmb_bgf_eirq_cb)(); */ + /* } */ + } + } + /* 4 <3> handle Rx interrupt */ + if (chisr & RX_DONE) { + /* STPSDIO_PR_INFO("RX_DONE_INT\n"); */ + + /* TODO: [FixMe][George] testing... */ + if (p_info->rx_pkt_len) + STPSDIO_PR_ERR("rx worker is not finished yet!!!(%d)\n", + p_info->rx_pkt_len); + + /* get Rx packet length */ + p_info->rx_pkt_len = (chisr & RX_PKT_LEN) >> 16; + STPSDIO_PR_HINT("rx_pkt_len(%d)\n", p_info->rx_pkt_len); + /* sanity check */ + if ((p_info->rx_pkt_len == 0) + || (p_info->rx_pkt_len > STP_SDIO_RX_FIFO_SIZE)) { + STPSDIO_PR_ERR + ("abnormal rx_pkt_len(%d) in CHISR(0x%08x) skip rx_worker\n", + p_info->rx_pkt_len, chisr); + p_info->rx_pkt_len = 0; + } else { + /* Before host driver read all rx data, chip/fw will not send more data + * to host. No need to mask rx interrupt. schedule rx worker to get data + * back and handle it. + */ + if (p_info->rx_pkt_len & 0x3) { + STPSDIO_PR_WARN + ("rx data len is not 4 bytes allignment, CHISR(0x%08x), rx len (%d).\n", + chisr, p_info->rx_pkt_len); + } +#if STP_SDIO_OWN_THREAD + /* tasklet_schedule(&p_info->tx_rx_job); */ + STPSDIO_PR_DBG("osal_trigger_event gp_info->tx_rx_event\n"); + osal_trigger_event(&gp_info->tx_rx_event); +#else + schedule_work(&p_info->rx_work); +#endif + } + } + /* 4 <4> handle Tx interrupt */ + if ((chisr & TX_EMPTY) || (chisr & TX_UNDER_THOLD)) { + STPSDIO_PR_DBG("Tx interrupt\n"); + /* get complete count */ + tx_comp = (chisr & TX_COMPLETE_COUNT) >> 4; +#if 0 + atomic_add(tx_comp, &p_info->firmware_info.tx_comp_num); + /* TODO:[FixMe][George]: debug and to be removed... */ + tx_comp = atomic_read(&p_info->firmware_info.tx_comp_num); +#else + tx_comp = atomic_add_return(tx_comp, &p_info->firmware_info.tx_comp_num); +#endif + if (tx_comp > STP_SDIO_TX_PKT_MAX_CNT) { + STPSDIO_PR_ERR("Abnormal accumulated comp count(%d) chisr(0x%x)\n", + tx_comp, chisr); + } + + /* move most of tx jobs to tx_worker */ + /* schedule tx worker for tx complete count and following tx data */ +#if STP_SDIO_OWN_THREAD + /* tasklet_schedule(&p_info->tx_rx_job); */ + STPSDIO_PR_DBG("osal_trigger_event gp_info->tx_rx_event\n"); + osal_trigger_event(&gp_info->tx_rx_event); +#else + schedule_work(&p_info->tx_work); +#endif + } + + return ret; +} +#endif /* STP_SDIO_NEW_IRQ_HANDLER */ + +#if STP_SDIO_POLL_OWNBACK_INTR +/***************************************************************************** + * FUNCTION + * stp_sdio_ownback_poll + * DESCRIPTION + * Poll ownback interrupt + * PARAMETERS + * 1. *func [IN] sdio driver function pointer + * 2. retryp [IN] polling retry times + * 3. delay_us [IN] polling delay (unit: us) + * RETURNS + * ret: Probe result + *****************************************************************************/ +static INT32 stp_sdio_ownback_poll(const MTK_WCN_HIF_SDIO_CLTCTX clt_ctx, UINT32 retry, UINT32 delay_us) +{ + INT32 ret; + UINT32 chlpcr = 0; + + do { +#if 0 + ret = stp_sdio_rw_retry(HIF_TYPE_READL, STP_SDIO_RETRY_LIMIT, clt_ctx, CHISR, &chisr_value, + 0); +#endif + /* 20111020: change to poll CHLPCR instead of read-cleared CHISR */ + ret = stp_sdio_rw_retry(HIF_TYPE_READL, STP_SDIO_RETRY_LIMIT, clt_ctx, CHLPCR, &chlpcr, 0); + if (ret) { + /* 4 <1.1> get CHISR Rx error handling */ + STPSDIO_PR_ERR("get CHLPCR information rx error!(%d)\n", ret); + return ret; + } + + /*if (chisr_value & FW_OWN_BACK_INT) { */ + if (chlpcr & C_FW_COM_DRV_OWN) { + /* 4 <2> handle ownership back interrupt */ + STPSDIO_PR_DBG("Driver own is polled!(%d)\n", retry); + gp_info->awake_flag = 1; + break; + } + osal_usleep_range(delay_us, delay_us); + } while (retry-- > 0); + + /*return (chisr_value & FW_OWN_BACK_INT) ? 0 : -HIF_SDIO_ERR_FAIL; */ + return (chlpcr & C_FW_COM_DRV_OWN) ? 0 : -HIF_SDIO_ERR_FAIL; +} +#endif /* STP_SDIO_POLL_OWNBACK_INTR */ + +/***************************************************************************** + * FUNCTION + * stp_sdio_probe + * DESCRIPTION + * Probe function of SDIO driver + * PARAMETERS + * 1. *func [IN] sdio driver function pointer + * 2. *id [IN] sdio function id + * RETURNS + * ret: Probe result + *****************************************************************************/ +/* typedef INT32 (*MTK_WCN_HIF_SDIO_PROBE)(MTK_WCN_HIF_SDIO_CLTCTX, const MTK_WCN_HIF_SDIO_FUNCINFO *); */ +static INT32 stp_sdio_probe(const MTK_WCN_HIF_SDIO_CLTCTX clt_ctx, + const MTK_WCN_HIF_SDIO_FUNCINFO *sdio_func_infop) +{ + INT32 ret = HIF_SDIO_ERR_SUCCESS; + UINT32 i = 0, chlcpr_value = 0; + UINT32 write_value = 0; + + STPSDIO_PR_DBG("sdio_cltctx: 0x%08x\n", clt_ctx); + + if (g_stp_sdio_host_count) { + STPSDIO_PR_ERR("g_stp_sdio_host_count(%d) probed already!\n", + g_stp_sdio_host_count); + return -1; + } + /* 4 <1> check if input pointer is valid */ + if (g_stp_sdio_host_info.sdio_cltctx == clt_ctx) { + STPSDIO_PR_WARN("sdio_cltctx(%d) already probed!\n", clt_ctx); + return 0; + } + /* 4 <2> allocate host inform structure and initialize private variables */ + /* init host info private variables */ + g_stp_sdio_host_info.sdio_cltctx = clt_ctx; + + /* init Tx packet ring buffer */ + for (i = 0; i < STP_SDIO_TX_BUF_CNT; ++i) { +#if KMALLOC_UPDATE + UINT8 *pData = g_stp_sdio_host_info.pkt_buf.tx_buf + i * STP_SDIO_TX_ENTRY_SIZE + 0; + + memset(pData, 0, STP_SDIO_TX_ENTRY_SIZE); +#else + memset(&g_stp_sdio_host_info.pkt_buf.tx_buf[i][0], 0, + sizeof(g_stp_sdio_host_info.pkt_buf.tx_buf[i])); +#endif + } + osal_sleepable_lock_init(&fake_coredump_lock); + +#if STP_SDIO_NEW_TXRING + spin_lock_init(&g_stp_sdio_host_info.pkt_buf.rd_cnt_lock); + atomic_set(&g_stp_sdio_host_info.pkt_buf.wr_cnt, 0); + atomic_set(&g_stp_sdio_host_info.pkt_buf.rd_cnt, 0); +#else + /*g_stp_sdio_host_info.pkt_buf.rd_idx_lock = SPIN_LOCK_UNLOCKED; */ + spin_lock_init(&g_stp_sdio_host_info.pkt_buf.rd_idx_lock); + atomic_set(&g_stp_sdio_host_info.pkt_buf.wr_idx, 0); + atomic_set(&g_stp_sdio_host_info.pkt_buf.rd_idx, 0); +#endif + g_stp_sdio_host_info.pkt_buf.full_flag = MTK_WCN_BOOL_FALSE; + + /* init wait queue head for Tx ring buf full */ + init_waitqueue_head(&g_stp_sdio_host_info.pkt_buf.fullwait_q); + + /* init Tx packet size list information */ + memset(&g_stp_sdio_host_info.tx_pkt_list.pkt_size_list[0], 0, + sizeof(g_stp_sdio_host_info.tx_pkt_list.pkt_size_list)); + g_stp_sdio_host_info.tx_pkt_list.pkt_rd_cnt = 0; + g_stp_sdio_host_info.tx_pkt_list.pkt_wr_cnt = 0; + + /* init Rx interrupt mask */ + /* g_stp_sdio_host_info.rx_intr_mask = MTK_WCN_BOOL_FALSE; */ + + /* init firmware related information */ + g_stp_sdio_host_info.firmware_info.tx_fifo_size = STP_SDIO_TX_FIFO_SIZE; + g_stp_sdio_host_info.firmware_info.tx_packet_num = 0; + atomic_set(&g_stp_sdio_host_info.firmware_info.tx_comp_num, 0); + + /* init SDIO data path retry flag */ + g_stp_sdio_host_info.retry_enable_flag = 0; + g_stp_sdio_host_info.tx_retry_flag = STP_SDIO_RETRY_NONE; + + g_stp_sdio_host_info.isr_check_complete.timeoutValue = 1000; + osal_signal_init(&g_stp_sdio_host_info.isr_check_complete); + +#if STP_SDIO_OWN_THREAD + /* tasklet_init(&g_stp_sdio_host_info.tx_rx_job, stp_sdio_tx_rx_handling, */ + /* (unsigned long) &g_stp_sdio_host_info); */ + /* Create stp_sdio_tx_rx_thread, in suspend state */ + g_stp_sdio_host_info.irq_pending = 0; + g_stp_sdio_host_info.sleep_flag = 0; + g_stp_sdio_host_info.wakeup_flag = 0; + osal_event_init(&g_stp_sdio_host_info.tx_rx_event); + g_stp_sdio_host_info.tx_rx_thread.pThreadFunc = stp_sdio_tx_rx_handling; + g_stp_sdio_host_info.tx_rx_thread.pThreadData = (PVOID) &g_stp_sdio_host_info; + g_stp_sdio_host_info.tx_dbg_dump_flag = 0; + osal_strncpy((PINT8)&g_stp_sdio_host_info.tx_rx_thread.threadName, + "stp_sdio_tx_rx", osal_sizeof(g_stp_sdio_host_info.tx_rx_thread.threadName)); + ret = osal_thread_create(&g_stp_sdio_host_info.tx_rx_thread); + if (ret < 0) { + STPSDIO_PR_ERR("osal_thread_create fail...: %p\n", + g_stp_sdio_host_info.tx_rx_thread.pThread); + return ret; + } +#else + /* init tx_tasklet and rx work_queue */ + INIT_WORK(&g_stp_sdio_host_info.tx_work, stp_sdio_tx_wkr); + INIT_WORK(&g_stp_sdio_host_info.rx_work, stp_sdio_rx_wkr); +#endif + /* init stp sdio host private information *//* TODO: [FixMe][George] Still need this? */ + g_stp_sdio_host_info.private_info.stp_sdio_host_idx = g_stp_sdio_host_count; + mtk_wcn_hif_sdio_set_drvdata(clt_ctx, &g_stp_sdio_host_info.private_info); + + ++g_stp_sdio_host_count; + + /* 4 <3> request firmware-own back */ +/* [COHEC_00006052] SW work-around solution: */ +/* using CMD52 write instead of CMD53 write for CCIR, CHLPCR, CSDIOCSR */ +#if COHEC_00006052 + write_value = (C_FW_OWN_REQ_CLR >> 8); + ret = stp_sdio_rw_retry(HIF_TYPE_WRITEB, STP_SDIO_RETRY_LIMIT, clt_ctx, (UINT32)(CHLPCR + 0x1), + &write_value, 0); +#else + write_value = C_FW_OWN_REQ_CLR; + ret = stp_sdio_rw_retry(HIF_TYPE_WRITEL, STP_SDIO_RETRY_LIMIT, clt_ctx, CHLPCR, + &write_value, 0); +#endif /* COHEC_00006052 */ + if (ret) { + STPSDIO_PR_ERR("request FW-Own back fail!(%d)\n", ret); + goto out; + } + STPSDIO_PR_DBG("request FW-Own back done\n"); + +#if STP_SDIO_POLL_OWNBACK_INTR + /* 4 <3.1> polling own back bit */ + ret = stp_sdio_ownback_poll(clt_ctx, 10, 100); + if (ret) { + STPSDIO_PR_ERR("poll FW-Own back fail!(%d)\n", ret); + goto out; + } +#endif + /* 4 <4.0> enable irq flag in HIF-SDIO */ + mtk_wcn_hif_sdio_enable_irq(clt_ctx, MTK_WCN_BOOL_TRUE); + /* 4 <4> enabling all host interrupt except abnormal ones */ + /*write_value = (CHISR_EN_15_7 | CHISR_EN_3_0);*/ /* enable CHISR interrupt output */ + /*ret = stp_sdio_rw_retry(HIF_TYPE_WRITEL, STP_SDIO_RETRY_LIMIT, clt_ctx, CHIER, &write_value, 0);*/ + write_value = (FIRMWARE_INT | TX_FIFO_OVERFLOW | FW_INT_IND_INDICATOR | TX_COMPLETE_COUNT + | TX_UNDER_THOLD | TX_EMPTY | RX_DONE); + ret = stp_sdio_rw_retry(HIF_TYPE_WRITEL, STP_SDIO_RETRY_LIMIT, clt_ctx, CHIER, + &write_value, 0); + if (ret) { + STPSDIO_PR_ERR("set interrupt output fail!(%d)\n", ret); + goto out; + } + STPSDIO_PR_DBG("set interrupt output done\n"); +/* [COHEC_00006052] SW work-around solution: */ +/* using CMD52 write instead of CMD53 write for CCIR, CHLPCR, CSDIOCSR */ +#if COHEC_00006052 + write_value = C_FW_INT_EN_SET; + ret = stp_sdio_rw_retry(HIF_TYPE_WRITEB, STP_SDIO_RETRY_LIMIT, clt_ctx, CHLPCR, &write_value, + 0); /* enable interrupt */ +#else + write_value = C_FW_INT_EN_SET; + ret = stp_sdio_rw_retry(HIF_TYPE_WRITEL, STP_SDIO_RETRY_LIMIT, clt_ctx, CHLPCR, &write_value, + 0); /* enable interrupt */ +#endif /* COHEC_00006052 */ + if (ret) { + STPSDIO_PR_ERR("enable interrupt fail!(%d)\n", ret); + goto out; + } + ret = stp_sdio_rw_retry(HIF_TYPE_READL, STP_SDIO_RETRY_LIMIT, clt_ctx, CHLPCR, &chlcpr_value, + 0); + if (ret) { + STPSDIO_PR_ERR("Read CHLPCR fail!(%d)\n", ret); + goto out; + } else { + if (chlcpr_value & C_FW_INT_EN_SET) + STPSDIO_PR_DBG("enable interrupt okay (0x%x)\n", chlcpr_value); + } + + STPSDIO_PR_DBG("enable interrupt done\n"); + +#ifdef CONFIG_MTK_COMBO_CHIP_DEEP_SLEEP_SUPPORT + stp_sdio_deep_sleep_flag_set(MTK_WCN_BOOL_FALSE); +#endif + +#if STP_SDIO_OWN_THREAD + ret = osal_thread_run(&g_stp_sdio_host_info.tx_rx_thread); + if (ret < 0) { + STPSDIO_PR_ERR("osal_thread_run fail...\n"); + goto out; + } +#endif + + /* 4 <5> register mtk_wcn_stp_if_tx() to stp driver */ + mtk_wcn_stp_register_if_tx(STP_SDIO_IF_TX, (MTK_WCN_STP_IF_TX) stp_sdio_tx); + +#if 0 /* controlled by 6620_launcher & WMT */ + /*set STP sdio mode */ + pr_warn(DFT_TAG "%s: set stp sdio mode\n", __func__); + mtk_wcn_stp_set_sdio_mode(1); + + /*indicate the stp the sdio ready */ + pr_warn(DFT_TAG "%s: stp enable\n", __func__); + mtk_wcn_stp_enable(1); +#endif + +out: + /* 4 <6> error handling */ + /* TODO: error handling */ + if (ret) { +#if STP_SDIO_OWN_THREAD + osal_thread_destroy(&g_stp_sdio_host_info.tx_rx_thread); +#endif + if (g_stp_sdio_host_count > 0) + --g_stp_sdio_host_count; + } + + return ret; +} + +/***************************************************************************** + * FUNCTION + * stp_sdio_probe + * DESCRIPTION + * SDIO hardware remove function. + * PARAMETERS + * *func [IN] SDIO driver handler pointer. + * RETURNS + * none. + *****************************************************************************/ +static INT32 stp_sdio_remove(const MTK_WCN_HIF_SDIO_CLTCTX clt_ctx) +{ +#if 0 + MTK_WCN_STP_SDIO_PRIVATE_INFO *p_priv; + + p_priv = mtk_wcn_hif_sdio_get_drvdata(clt_ctx); +#endif + + if (g_stp_sdio_host_info.sdio_cltctx == clt_ctx) + STPSDIO_PR_DBG("sdio_cltctx(%d) found\n", clt_ctx); + else { + STPSDIO_PR_ERR("sdio_cltctx(%d) not found\n", clt_ctx); + return -1; + } + osal_sleepable_lock_deinit(&fake_coredump_lock); + if (g_stp_sdio_host_count > 0) + --g_stp_sdio_host_count; + /* 4 <0> disable irq flag in HIF-SDIO */ + mtk_wcn_hif_sdio_enable_irq(clt_ctx, MTK_WCN_BOOL_FALSE); + /* 4 <1> unregister if_tx() function */ + mtk_wcn_stp_register_if_tx(STP_SDIO_IF_TX, NULL); + + /* <2> stop Tx tasklet/Rx work queue of the host */ +#if STP_SDIO_OWN_THREAD + /* tasklet_kill(&g_stp_sdio_host_info.tx_rx_job); */ + /* STPSDIO_PR_INFO("kill tasklet finished\n"); */ + osal_thread_destroy(&g_stp_sdio_host_info.tx_rx_thread); + osal_event_deinit(&g_stp_sdio_host_info.tx_rx_event); + osal_signal_deinit(&g_stp_sdio_host_info.isr_check_complete); + STPSDIO_PR_DBG("destroy STP-SDIO tx_rx_thread\n"); +#else + flush_scheduled_work(); + STPSDIO_PR_INFO("flush scheduled work end\n"); +#endif + + /* 4 <3> return ownership to firmware of the host */ + /* TODO: check set which register ! */ + + /* 4 <4> clear the host struct list */ + stp_sdio_host_info_op(1); + + + STPSDIO_PR_DBG("clear g_stp_sdio_host_info[p_priv->stp_sdio_host_idx] done\n"); + + return 0; +} + +INT32 stp_sdio_rw_retry(ENUM_STP_SDIO_HIF_TYPE_T type, UINT32 retry_limit, + MTK_WCN_HIF_SDIO_CLTCTX clt_ctx, UINT32 offset, PUINT32 pData, UINT32 len) +{ + INT32 ret = -1; + INT32 ret_1 = -1; + UINT32 value = 0; + INT32 retry_flag = 0; + + UINT32 card_id = CLTCTX_CID(clt_ctx); + + if (card_id != 0x6630 && card_id != 0x6632) { + STPSDIO_PR_LOUD("card_id is :0x%x, does not support CSR (Common Snapshot Register)\n", + card_id); + retry_limit = 1; + } + STPSDIO_PR_LOUD("clt_ctx:0x%x, offset:0x%x, retry_limit:%d\n", clt_ctx, offset, retry_limit); + + retry_limit = retry_limit == 0 ? 1 : retry_limit; + retry_limit = retry_limit > STP_SDIO_MAX_RETRY_NUM ? STP_SDIO_MAX_RETRY_NUM : retry_limit; + + while (retry_limit > 0) { + switch (type) { + case HIF_TYPE_READB: + if (retry_flag) + ret = mtk_wcn_hif_sdio_readb(clt_ctx, CSR, (PUINT8)pData); + else + ret = mtk_wcn_hif_sdio_readb(clt_ctx, offset, (PUINT8)pData); + break; + case HIF_TYPE_READL: + if (retry_flag) + ret = mtk_wcn_hif_sdio_readl(clt_ctx, CSR, pData); + else + ret = mtk_wcn_hif_sdio_readl(clt_ctx, offset, pData); + break; + case HIF_TYPE_READ_BUF: + ret = mtk_wcn_hif_sdio_read_buf(clt_ctx, offset, pData, len); + break; + case HIF_TYPE_WRITEB: + ret = mtk_wcn_hif_sdio_writeb(clt_ctx, offset, (UINT8)(*pData)); + break; + case HIF_TYPE_WRITEL: + ret = mtk_wcn_hif_sdio_writel(clt_ctx, offset, *pData); + break; + case HIF_TYPE_WRITE_BUF: + ret = mtk_wcn_hif_sdio_write_buf(clt_ctx, offset, pData, len); + break; + default: + STPSDIO_PR_ERR("unknown hif sdio type!\n"); + goto exit; + } + + if (ret) { + STPSDIO_PR_ERR("sdio read or write failed, ret:%d\n", ret); + if (ret == -ETIMEDOUT) { + ret_1 = mtk_wcn_hif_sdio_readl(clt_ctx, CCIR, &value); + STPSDIO_PR_ERR("sdio read or write timeout, ret:%d ret_1:%d, read chip id:%x\n", + ret, ret_1, value); + stp_sdio_dump_register(); + } + /* sdio CRC error read CSR */ + if (type == HIF_TYPE_READ_BUF || type == HIF_TYPE_WRITE_BUF) { + if (ret == -EIO || ret == -EILSEQ || ret == -EBUSY) { + ret_1 = mtk_wcn_hif_sdio_abort(clt_ctx); + if (ret_1) + STPSDIO_PR_ERR("sdio crc error send abort fail, ret_1:%d\n", + ret_1); + else + STPSDIO_PR_ERR("sdio crc error send abort success, ret_1:%d\n", + ret_1); + goto exit; + } + } else + retry_flag = 1; + } else { + STPSDIO_PR_LOUD("CR:0x:%x value:0x%x\n", offset, *pData); + break; + } + retry_limit--; + } + +exit: + return ret; +} + + +#if STP_SDIO_DBG_SUPPORT && STP_SDIO_RXDBG + +/*! + * \brief /proc debug read interface and dump rx dbg information + * + * \details Dump all rx debug information to console. + * + * \retval 0 success + */ +ssize_t stp_sdio_rxdbg_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) +{ + UINT32 idx; + UINT32 i; + UINT32 j; + PUINT8 pbuf; + UINT32 len; + + if (*f_pos > 0) + return 0; + + for (i = 0; i < STP_SDIO_RXDBG_COUNT; ++i) { + idx = (stp_sdio_rxdbg_cnt - 1 - i) & STP_SDIO_TXDBG_COUNT_MASK; + len = stp_sdio_rxdbg_buffer[idx].bus_rxlen; + if (len == 0) { + pr_warn(DFT_TAG "idx(0x%x) 0 == len dump skip\n", + stp_sdio_rxdbg_cnt); + } + pr_warn(DFT_TAG "idx(0x%x) chisr_rxlen(%d) bus_rxlen(%d) ts(%d)\n", + stp_sdio_rxdbg_cnt, stp_sdio_rxdbg_buffer[idx].chisr_rxlen, len, + stp_sdio_rxdbg_buffer[idx].ts); + for (j = 0; j < STP_SDIO_RX_BUF_SIZE && j < len; j += 16) { + pbuf = &stp_sdio_rxdbg_buffer[idx].rx_pkt_buf[j]; + pr_warn(DFT_TAG "[0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x ", + pbuf[0], pbuf[1], pbuf[2], pbuf[3], pbuf[4], pbuf[5], pbuf[6], + pbuf[7]); + pr_warn(DFT_TAG "0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x]\n", + pbuf[8], pbuf[9], pbuf[10], pbuf[11], pbuf[12], pbuf[13], + pbuf[14], pbuf[15]); + msleep(20); + } + pr_warn(DFT_TAG "dump ok\n"); + } + + return 0; +} + +/*! + * \brief /proc debug write interface. do nothing. + * + * \details + * + * \retval 0 success + */ +ssize_t stp_sdio_rxdbg_write(struct file *filp, const char __user *buf, size_t count, + loff_t *f_pos) +{ + ULONG len = count; + + pr_warn(DFT_TAG "write parameter len = %lu\n\r", len); + + return len; +} + +/*! + * \brief /proc initial procedures. Initialize global debugging information. + * + * \details Setup entry for /proc debugging for rx + * + * \retval 0 success + */ +INT32 stp_sdio_rxdbg_setup(VOID) +{ + stp_sdio_rxdbg_cnt = 0; + + gStpSdioRxDbgEntry = proc_create(STP_SDIO_RXDBG_PROCNAME, 0644, NULL, &stp_sdio_rxdbg_fops); + if (gStpSdioRxDbgEntry == NULL) { + pr_warn(DFT_TAG "Unable to create /proc entry\n\r"); + return -1; + } + + return 0; +} + +/*! + * \brief /proc de-init procedures. + * + * \details remove entry for /proc debugging for rx + * + * \retval 0 success + */ +INT32 stp_sdio_rxdbg_remove(VOID) +{ + if (gStpSdioRxDbgEntry != NULL) + proc_remove(gStpSdioRxDbgEntry); + + return 0; +} +#endif + +#if STP_SDIO_DBG_SUPPORT && (STP_SDIO_TXDBG || STP_SDIO_TXPERFDBG) + +static VOID stp_sdio_txperf_dump(VOID) +{ +#if STP_SDIO_DBG_SUPPORT && STP_SDIO_TXPERFDBG + UINT32 cnt; + UINT32 fifo; + UINT32 data; + UINT32 wkr; + UINT32 pkt_num; + UINT32 lmt_cnt; + + /* get debug counter snapshot */ + cnt = stp_sdio_txperf_fifo_lmt_cnt; + fifo = stp_sdio_txperf_fifo_left; + data = stp_sdio_txperf_to_send; + + wkr = stp_sdio_txperf_worker_cnt; + pkt_num = stp_sdio_txperf_txed_pkt_num; + lmt_cnt = stp_sdio_txperf_pkt_num_lmt_cnt; + + pr_warn(DFT_TAG "txwait_fifo_left(%d), txwait_to_send(%d), txwait_count(%d)\n", + fifo, data, cnt); + if (cnt) + pr_warn(DFT_TAG "avg left(%d), to_send(%d)\n", (fifo / cnt), (data / cnt)); + pr_warn(DFT_TAG "tx_worker_cnt(%d), pkt_num(%d), pkt_num_lmt_cnt(%d)\n", + wkr, pkt_num, lmt_cnt); + +#endif +} + +VOID stp_sdio_dump_info(MTK_WCN_STP_SDIO_HIF_INFO *p_info) +{ + STPSDIO_PR_INFO("stp_is_ready(%d) irq_pending(%d) tx_packet_num(%d) rx_pkt_len(%d)\n", + mtk_wcn_stp_is_ready(), p_info->irq_pending, + p_info->firmware_info.tx_packet_num, p_info->rx_pkt_len); + STPSDIO_PR_INFO("sleep_flag(%d) wakeup_flag(%d) awake_flag(%d) txwkr_flag(%d)\n", + p_info->sleep_flag, p_info->wakeup_flag, p_info->awake_flag, p_info->txwkr_flag); + STPSDIO_PR_INFO("wr_idx(%d), rd_idx(%d), full_flag(%d), tx_fifo_size(%d)\n", + atomic_read(&p_info->pkt_buf.wr_idx), atomic_read(&p_info->pkt_buf.rd_idx), + p_info->pkt_buf.full_flag, p_info->firmware_info.tx_fifo_size); +} + +VOID stp_sdio_txdbg_dump(VOID) +{ +#if STP_SDIO_TXDBG + UINT32 idx; + UINT32 i; + UINT32 j; + PUINT8 pbuf; + UINT32 len; + + for (i = 0; i < STP_SDIO_TXDBG_COUNT; ++i) { + idx = (stp_sdio_txdbg_cnt - 1 - i) & STP_SDIO_TXDBG_COUNT_MASK; + len = stp_sdio_txdbg_buffer[idx].bus_txlen; + if (len == 0) { + STPSDIO_PR_INFO("idx(%x) 0 == len dump skip\n", idx); + continue; + } + + len = len > STP_SDIO_TXDBG_MAX_SIZE ? STP_SDIO_TXDBG_MAX_SIZE : len; + STPSDIO_PR_INFO( + "stp_sdio_txdbg_buffer idx(%x) bus_txlen(0x%x, %d), time[%llu.%06lu]\n", + idx, len, len, stp_sdio_txdbg_buffer[idx].l_sec, stp_sdio_txdbg_buffer[idx].l_nsec); + for (j = 0; j < STP_SDIO_TX_ENTRY_SIZE && j < len; j += 16) { + pbuf = &stp_sdio_txdbg_buffer[idx].tx_pkt_buf[j]; + STPSDIO_PR_INFO("[0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x]\n", + pbuf[0], pbuf[1], pbuf[2], pbuf[3], pbuf[4], pbuf[5], pbuf[6], pbuf[7]); + STPSDIO_PR_INFO("[0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x]\n", + pbuf[8], pbuf[9], pbuf[10], pbuf[11], pbuf[12], pbuf[13], pbuf[14], + pbuf[15]); + msleep(20); + } + STPSDIO_PR_INFO("stp_sdio_txdbg_buffer dump ok\n"); + } +#if STP_TXDBG + for (i = 0; i < STP_SDIO_TXDBG_COUNT; ++i) { + idx = (stp_sdio_txdbg_cnt - 1 - i) & STP_SDIO_TXDBG_COUNT_MASK; + len = stp_sdio_txdbg_buffer[idx].bus_txlen; + STPSDIO_PR_INFO( + "stp_sdio_txdbg_buffer idx(%x) bus_txlen(0x%x, %d) ts(%d)\n", idx, len, len, + stp_sdio_txdbg_buffer[idx].ts); + } + STPSDIO_PR_INFO( + "Dump tx info: pkt_num(%d) fifo(%d) pkt_list.rd(0x%x, %ld) pkt_list.wr(0x%x, %ld)\n", + gp_info->firmware_info.tx_packet_num, gp_info->firmware_info.tx_fifo_size, + gp_info->tx_pkt_list.pkt_rd_cnt, + STP_SDIO_GET_PKT_AR_IDX(gp_info->tx_pkt_list.pkt_rd_cnt), + gp_info->tx_pkt_list.pkt_wr_cnt, + STP_SDIO_GET_PKT_AR_IDX(gp_info->tx_pkt_list.pkt_wr_cnt)); + + for (i = 0; i < STP_SDIO_TX_PKT_LIST_SIZE; ++i) { + idx = STP_SDIO_GET_PKT_AR_IDX(gp_info->tx_pkt_list.pkt_wr_cnt - 1 - i); + STPSDIO_PR_INFO( + "tx_pkt_list idx(0x%x, %d) size(0x%x, %d), in_ts(%d), out_ts(%d)\n", + (gp_info->tx_pkt_list.pkt_wr_cnt - 1 - i), idx, + gp_info->tx_pkt_list.pkt_size_list[idx], + gp_info->tx_pkt_list.pkt_size_list[idx], gp_info->tx_pkt_list.in_ts[idx], + gp_info->tx_pkt_list.out_ts[idx]); + } + +#if STP_SDIO_NEW_TXRING + STPSDIO_PR_INFO("\n\ndump pkt_buf.tx_buf: rd(%d) wr(%d) full(%d)\n", + atomic_read(&gp_info->pkt_buf.rd_cnt), atomic_read(&gp_info->pkt_buf.wr_cnt), + gp_info->pkt_buf.full_flag); +#else + STPSDIO_PR_INFO("\n\ndump pkt_buf.tx_buf: rdi(%d) wri(%d) full(%d)\n", + atomic_read(&gp_info->pkt_buf.rd_idx), atomic_read(&gp_info->pkt_buf.wr_idx), + gp_info->pkt_buf.full_flag); +#endif + + for (i = 0; i < STP_SDIO_TX_BUF_CNT; ++i) { +#if STP_SDIO_NEW_TXRING + idx = (atomic_read(&gp_info->pkt_buf.wr_cnt) - 1 - i) & STP_SDIO_TX_BUF_CNT_MASK; + len = gp_info->pkt_buf.tx_buf_sz[idx]; +#else + idx = (atomic_read(&gp_info->pkt_buf.wr_idx) - 1 - i + STP_SDIO_TX_BUF_CNT) % + STP_SDIO_TX_BUF_CNT; +#if KMALLOC_UPDATE + len = *(gp_info->pkt_buf.tx_buf + idx * STP_SDIO_TX_ENTRY_SIZE + 1); + len = (len << 8) | *(gp_info->pkt_buf.tx_buf + idx * STP_SDIO_TX_ENTRY_SIZE + 0); +#else + len = gp_info->pkt_buf.tx_buf[idx][1]; + len = (len << 8) | gp_info->pkt_buf.tx_buf[idx][0]; +#endif + +#endif + STPSDIO_PR_INFO("pkt_buf.tx_buf idx(%x) ts(%d) len(%d), time[%llu.%06lu]\n", + idx, gp_info->pkt_buf.tx_buf_ts[idx], len, + gp_info->pkt_buf.tx_buf_local_ts[idx], gp_info->pkt_buf.tx_buf_local_nsec[idx]); + if (len == 0) { + STPSDIO_PR_INFO("idx(%x) 0 == len dump skip\n", idx); + continue; + } + len = len > STP_SDIO_TXDBG_MAX_SIZE ? STP_SDIO_TXDBG_MAX_SIZE : len; + for (j = 0; j < STP_SDIO_TX_ENTRY_SIZE && j < len; j += 16) { +#if KMALLOC_UPDATE + pbuf = gp_info->pkt_buf.tx_buf + idx * STP_SDIO_TX_ENTRY_SIZE + j; +#else + pbuf = &gp_info->pkt_buf.tx_buf[idx][j]; +#endif + STPSDIO_PR_INFO("[0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x]\n", + pbuf[0], pbuf[1], pbuf[2], pbuf[3], pbuf[4], pbuf[5], pbuf[6], + pbuf[7]); + STPSDIO_PR_INFO("[0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x]\n", + pbuf[8], pbuf[9], pbuf[10], pbuf[11], pbuf[12], pbuf[13], pbuf[14], + pbuf[15]); + msleep(20); + } + STPSDIO_PR_INFO("pkt_buf.tx_buf dump ok\n"); + } +#endif /*end of STP_TXDBG*/ +#endif /* end of STP_SDIO_TXDBG */ +} + +/*! + * \brief /proc debug read interface and dump tx dbg information + * + * \details Dump all tx debug information to console. + * + * \retval 0 success + */ +ssize_t stp_sdio_txdbg_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) +{ + if (*f_pos > 0) + return 0; + + stp_sdio_txdbg_dump(); + stp_sdio_txperf_dump(); + + return 0; +} + +/*! + * \brief /proc debug write interface. do nothing. + * + * \details + * + * \retval 0 success + */ +ssize_t stp_sdio_txdbg_write(struct file *filp, const char __user *buf, size_t count, + loff_t *f_pos) +{ + ULONG len = count; + + pr_warn(DFT_TAG "write parameter len = %lu\n\r", len); + + return len; +} + +/*! + * \brief /proc debug read interface and dump tx dbg information + * + * \details Dump all tx debug information to console. + * + * \retval 0 success + */ +ssize_t stp_sdio_own_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) +{ + if (*f_pos > 0) + return 0; + + return 0; +} + +/*! + * \brief /proc debug write interface. do nothing. + * + * \details + * + * \retval 0 success + */ +ssize_t stp_sdio_own_write(struct file *filp, const char __user *buffer, size_t count, + loff_t *f_pos) +{ + ULONG len = count; + PINT8 pBuf = NULL; + PINT8 pToken = NULL; + PINT8 pDelimiter = " \t"; + INT32 x = 0; + INT8 buf[128] = { 0 }; + LONG res = 0; + + if (len >= osal_sizeof(buf)) { + STPSDIO_PR_ERR("input handling fail!\n"); + len = osal_sizeof(buf) - 1; + return -1; + } + + if (copy_from_user(buf, buffer, len)) { + STPSDIO_PR_ERR("copy_from_user error.\n"); + return -EFAULT; + } + + buf[len] = '\0'; + pBuf = buf; + pToken = osal_strsep(&pBuf, pDelimiter); + if (pToken != NULL) { + osal_strtol(pToken, 16, &res); + x = (INT32)res; + } else { + x = 0; + } + + if (x == 0) { + STPSDIO_PR_INFO("stp_sdio_own_ctrl(OWN_CLR)\n\r"); + stp_sdio_own_ctrl(OWN_CLR); + } else if (x == 2) { + STPSDIO_PR_INFO("stp_sdio_own_ctrl(OWN_SET) -->Sleep\n\r"); + stp_sdio_own_ctrl(OWN_SET); + } else if (x == 3) { + gStpSdioDbgLvl = STPSDIO_LOG_WARN; + STPSDIO_PR_WARN("set STP-SDIO LogLevel to STPSDIO_LOG_WARN\n\r"); + } else if (x == 4) { + gStpSdioDbgLvl = STPSDIO_LOG_INFO; + STPSDIO_PR_INFO("set STP-SDIO LogLevel to STPSDIO_LOG_INFO\n\r"); + } else if (x == 5) { + gStpSdioDbgLvl = STPSDIO_LOG_HINT; + STPSDIO_PR_INFO("set STP-SDIO LogLevel to STPSDIO_LOG_HINT\n\r"); + } else if (x == 6) { + gStpSdioDbgLvl = STPSDIO_LOG_DBG; + STPSDIO_PR_INFO("set STP-SDIO LogLevel to STPSDIO_LOG_DBG\n\r"); + } else if (x == 7) { + gStpSdioDbgLvl = STPSDIO_LOG_LOUD; + STPSDIO_PR_INFO("set STP-SDIO LogLevel to STPSDIO_LOG_LOUD\n\r"); + } + + return len; +} + + +/*! + * \brief /proc initial procedures. Initialize global debugging information. + * + * \details Setup entry for /proc debugging for tx + * + * \retval 0 success + */ +INT32 stp_sdio_txdbg_setup(VOID) +{ + gStpSdioTxDbgEntry = proc_create(STP_SDIO_TXDBG_PROCNAME, 0644, NULL, &stp_sdio_txdbg_fops); + if (gStpSdioTxDbgEntry == NULL) { + pr_warn(DFT_TAG "Unable to create /proc entry\n\r"); + return -1; + } + +#if STP_SDIO_TXPERFDBG + stp_sdio_txperf_worker_cnt = 0; + + stp_sdio_txperf_fifo_left = 0; + stp_sdio_txperf_to_send = 0; + stp_sdio_txperf_fifo_lmt_cnt = 0; + + stp_sdio_txperf_txed_pkt_num = 0; + stp_sdio_txperf_pkt_num_lmt_cnt = 0; +#endif + +#if STP_SDIO_TXDBG + stp_sdio_txdbg_cnt = 0; +#endif + + return 0; +} + +/*! + * \brief /proc de-init procedures. + * + * \details remove entry for /proc debugging for tx + * + * \retval 0 success + */ +INT32 stp_sdio_txdbg_remove(VOID) +{ + if (gStpSdioTxDbgEntry != NULL) + proc_remove(gStpSdioTxDbgEntry); + + return 0; +} + +#endif /* end of STP_SDIO_DBG_SUPPORT && (STP_SDIO_TXDBG || STP_SDIO_TXPERFDBG) */ + +#if STP_SDIO_DBG_SUPPORT && STP_SDIO_OWNBACKDBG + +/*! + * \brief /proc initial procedures. Initialize global debugging information. + * + * \details Setup entry for /proc debugging for tx + * + * \retval 0 success + */ +INT32 stp_sdio_owndbg_setup(VOID) +{ + gStpSdioOwnEntry = proc_create(STP_SDIO_OWNDBG_PROCNAME, 0644, NULL, &stp_sdio_own_fops); + if (gStpSdioOwnEntry == NULL) { + pr_warn(DFT_TAG "Unable to create /proc entry\n\r"); + return -1; + } + + return 0; +} + + + +/*! + * \brief /proc de-init procedures. + * + * \details remove entry for /proc debugging for tx + * + * \retval 0 success + */ +INT32 stp_sdio_owndbg_remove(VOID) +{ + if (gStpSdioOwnEntry != NULL) + proc_remove(gStpSdioOwnEntry); + + return 0; +} +#endif + +/*! + * \brief hif_sdio init function + * + * detailed descriptions + * + * \retval + */ +static INT32 stp_sdio_init(VOID) +{ + INT32 ret; + INT32 i; + + /* 4 <1> initialize all private variables */ + stp_sdio_host_info_op(1); + g_stp_sdio_host_count = 0; + /* Init stp sdio client info */ +#if 0 /* George: chage to be a constant struct */ + g_stp_sdio_cltinfo.func_tbl = mtk_stp_sdio_id_tbl; + g_stp_sdio_cltinfo.func_tbl_size = + sizeof(mtk_stp_sdio_id_tbl) / sizeof(MTK_WCN_HIF_SDIO_FUNCINFO) - 1; + g_stp_sdio_cltinfo.hif_clt_irq = stp_sdio_irq; + g_stp_sdio_cltinfo.hif_clt_probe = stp_sdio_probe; + g_stp_sdio_cltinfo.hif_clt_remove = stp_sdio_remove; +#endif + + STPSDIO_PR_DBG("cltinfo func table size:%d\n", g_stp_sdio_cltinfo.func_tbl_size); + for (i = 0; i < g_stp_sdio_cltinfo.func_tbl_size; i++) { + STPSDIO_PR_DBG("manf_id:0x%x, card_id:0x%x, func_num:%d, blk_size:%d\n", + mtk_stp_sdio_id_tbl[i].manf_id, mtk_stp_sdio_id_tbl[i].card_id, + mtk_stp_sdio_id_tbl[i].func_num, mtk_stp_sdio_id_tbl[i].blk_sz); + } + + /* 4 <2> register supported functions from sdio id table to hif sdio driver */ + ret = mtk_wcn_hif_sdio_client_reg(&g_stp_sdio_cltinfo); + if (ret) + STPSDIO_PR_ERR("mtk_wcn_hif_sdio_client_reg fail(%d)!\n", ret); + + ret = mtk_wcn_stp_wmt_sdio_op_reg(stp_sdio_own_ctrl); + if (ret) + STPSDIO_PR_ERR + ("mtk_wcn_stp_wmt_sdio_op_reg(mtk_wcn_stp_sdio_own_ctrl) fail(%d)!\n", ret); +#ifdef CONFIG_MTK_COMBO_CHIP_DEEP_SLEEP_SUPPORT + mtk_wcn_wmt_sdio_deep_sleep_flag_cb_reg(stp_sdio_deep_sleep_flag_set); +#endif + mtk_wcn_wmt_sdio_rw_cb_reg(stp_sdio_reg_rw); + +#if STP_SDIO_DBG_SUPPORT && STP_SDIO_RXDBG + stp_sdio_rxdbg_setup(); +#endif + +#if STP_SDIO_DBG_SUPPORT && STP_SDIO_TXDBG + stp_sdio_txdbg_setup(); +#endif + +#if STP_SDIO_DBG_SUPPORT && STP_SDIO_OWNBACKDBG + stp_sdio_owndbg_setup(); +#endif + + STPSDIO_PR_DBG + ("blk_size(%ld), tx_buf_cnt(%ld), fifo tx(%ld) rx(%ld), buf tx(%ld) rx(%ld)\n", + STP_SDIO_BLK_SIZE, STP_SDIO_TX_BUF_CNT, STP_SDIO_TX_FIFO_SIZE, STP_SDIO_RX_FIFO_SIZE, + STP_SDIO_TX_ENTRY_SIZE, STP_SDIO_TX_ENTRY_SIZE); + + return ret; +} + +INT32 stp_sdio_reg_rw(INT32 func_num, INT32 direction, UINT32 offset, UINT32 value) +{ + + if (func_num == 0) + return stp_sdio_func0_reg_rw(direction, offset, value); + else if (func_num == 2) + return stp_sdio_func_reg_rw(direction, offset, value); + + STPSDIO_PR_ERR("func_num(%d) is not support!\n", func_num); + return -1; +} + +INT32 stp_sdio_func0_reg_rw(INT32 direction, UINT32 offset, UINT32 value) +{ + INT32 ret = -1; + UINT8 val = 0x00; + + val = (UINT8) value; + switch (direction) { + case 0: + ret = mtk_wcn_hif_sdio_f0_readb(g_stp_sdio_host_info.sdio_cltctx, offset, &val); + STPSDIO_PR_INFO("read func0 CR(0x%x), value(0x%x)\n", offset, val); + break; + case 1: + ret = mtk_wcn_hif_sdio_f0_writeb(g_stp_sdio_host_info.sdio_cltctx, offset, val); + STPSDIO_PR_INFO("write func0 CR(0x%x), value(0x%x)\n", offset, val); + break; + default: + break; + } + return ret; + +} + +INT32 stp_sdio_func_reg_rw(INT32 direction, UINT32 offset, UINT32 value) +{ + INT32 ret = -1; + UINT32 val = 0x00; + + val = (UINT32) value; + switch (direction) { + case 0: + ret = mtk_wcn_hif_sdio_readl(g_stp_sdio_host_info.sdio_cltctx, offset, &val); + STPSDIO_PR_INFO("read sdio CR(0x%x), value(0x%x)\n", offset, val); + break; + case 1: + ret = mtk_wcn_hif_sdio_writel(g_stp_sdio_host_info.sdio_cltctx, offset, val); + STPSDIO_PR_INFO("write sdio CR(0x%x), value(0x%x)\n", offset, val); + break; + default: + break; + } + return ret; +} + +INT32 stp_sdio_wake_up_ctrl(MTK_WCN_HIF_SDIO_CLTCTX ctx) +{ + INT32 ret; + + ret = hif_sdio_wake_up_ctrl(ctx); + if (ret == -11) { + STPSDIO_PR_ERR("wake up fail, polling [GPIO_CHIP_DEEP_SLEEP_PIN] low over 30ms\n"); + ret = stp_sdio_issue_fake_coredump + (" wake up fail, polling [GPIO_CHIP_DEEP_SLEEP_PIN] low over 30ms # -"); + } else if (ret == -2 || ret == -3) + STPSDIO_PR_ERR("get wake up, sleep pin error\n"); + + return ret; +} + +VOID stp_sdio_dump_register(VOID) +{ + UINT32 count = 3; + MTK_WCN_HIF_SDIO_CLTCTX clt_ctx; + UINT32 val = 0; + UINT32 delay_us = 10000; + + clt_ctx = gp_info->sdio_cltctx; + while (count) { + stp_sdio_rw_retry(HIF_TYPE_READL, STP_SDIO_RETRY_LIMIT, clt_ctx, CCIR, &val, 0); + STPSDIO_PR_ERR("******CCIR == 0x%x*****\n", val); + stp_sdio_rw_retry(HIF_TYPE_READL, STP_SDIO_RETRY_LIMIT, clt_ctx, CHLPCR, &val, 0); + STPSDIO_PR_ERR("******CHLPCR == 0x%x*****\n", val); + stp_sdio_rw_retry(HIF_TYPE_READL, STP_SDIO_RETRY_LIMIT, clt_ctx, CSDIOCSR, &val, 0); + STPSDIO_PR_ERR("******CSDIOCSR == 0x%x*****\n", val); + stp_sdio_rw_retry(HIF_TYPE_READL, STP_SDIO_RETRY_LIMIT, clt_ctx, CHCR, &val, 0); + STPSDIO_PR_ERR("******CHCR == 0x%x*****\n", val); + stp_sdio_rw_retry(HIF_TYPE_READL, STP_SDIO_RETRY_LIMIT, clt_ctx, CHISR, &val, 0); + STPSDIO_PR_ERR("******CHISR == 0x%x*****\n", val); + stp_sdio_rw_retry(HIF_TYPE_READL, STP_SDIO_RETRY_LIMIT, clt_ctx, CHIER, &val, 0); + STPSDIO_PR_ERR("******CHIER == 0x%x*****\n", val); + stp_sdio_rw_retry(HIF_TYPE_READL, STP_SDIO_RETRY_LIMIT, clt_ctx, CTFSR, &val, 0); + STPSDIO_PR_ERR("******CTFSR == 0x%x*****\n", val); + stp_sdio_rw_retry(HIF_TYPE_READL, STP_SDIO_RETRY_LIMIT, clt_ctx, CRPLR, &val, 0); + STPSDIO_PR_ERR("******CRPLR == 0x%x*****\n", val); + count--; + osal_usleep_range(delay_us, 2 * delay_us); + } + +} + +/*! + * \brief hif_sdio init function + * + * detailed descriptions + * + * \retval + */ +static VOID stp_sdio_exit(VOID) +{ +#if STP_SDIO_DBG_SUPPORT && STP_SDIO_TXDBG + stp_sdio_txdbg_remove(); +#endif + +#if STP_SDIO_DBG_SUPPORT && STP_SDIO_RXDBG + stp_sdio_rxdbg_remove(); +#endif + +#if STP_SDIO_DBG_SUPPORT && STP_SDIO_OWNBACKDBG + stp_sdio_owndbg_remove(); +#endif + + /* 4 <0> unregister if_tx() function */ + mtk_wcn_stp_register_if_tx(STP_SDIO_IF_TX, 0x0); + + /* 4 <1> for all functions that have not been unregistered */ + /* 4 <1.1> unregister stp sdio func of the host */ + mtk_wcn_hif_sdio_client_unreg(&g_stp_sdio_cltinfo); + + /* 4 <1.2> stop Tx tasklet/Rx work queue of the host */ + flush_scheduled_work(); + STPSDIO_PR_DBG("flush scheduled work end\n"); + + /* 4 <1.3> return ownership to firmware of the host */ + /* TODO: check set which register ! */ + + /* 4 <1.4> clear the host struct list and free the memory allocation of the host */ + g_stp_sdio_host_count = 0; + stp_sdio_host_info_op(0); + /* 4 <1.5> Notice: while rmmod client driver, the stp_sdio_remove() */ + /* will not be called after stp_sdio_exit() ! */ +} + +INT32 mtk_wcn_stp_sdio_drv_init(VOID) +{ + return stp_sdio_init(); + +} +EXPORT_SYMBOL(mtk_wcn_stp_sdio_drv_init); + +VOID mtk_wcn_stp_sdio_drv_exit(VOID) +{ + return stp_sdio_exit(); +} +EXPORT_SYMBOL(mtk_wcn_stp_sdio_drv_exit); diff --git a/drivers/misc/mediatek/connectivity/common/common_main/linux/stp_uart.c b/drivers/misc/mediatek/connectivity/common/common_main/linux/stp_uart.c new file mode 100644 index 0000000000000000000000000000000000000000..8803c2375b25ca728210701bea8b3ab1fb8ab9fb --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/linux/stp_uart.c @@ -0,0 +1,843 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + + +#include "stp_exp.h" + +#define N_MTKSTP (15 + 1) /* refer to linux tty.h use N_HCI. */ + +#define HCIUARTSETPROTO _IOW('U', 200, int) + +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) + +#define PFX "[UART] " +#define UART_LOG_LOUD 4 +#define UART_LOG_DBG 3 +#define UART_LOG_INFO 2 +#define UART_LOG_WARN 1 +#define UART_LOG_ERR 0 + +#define MAX_PACKET_ALLOWED 2000 + + +static INT32 gDbgLevel = UART_LOG_INFO; + +#define UART_PR_DBG(fmt, arg...) \ +do { if (gDbgLevel >= UART_LOG_DBG) \ + pr_info(PFX "%s: " fmt, __func__, ##arg); \ +} while (0) +#define UART_PR_INFO(fmt, arg...) \ +do { if (gDbgLevel >= UART_LOG_INFO) \ + pr_info(PFX "%s: " fmt, __func__, ##arg); \ +} while (0) +#define UART_PR_WARN(fmt, arg...) \ +do { if (gDbgLevel >= UART_LOG_WARN) \ + pr_warn(PFX "%s: " fmt, __func__, ##arg); \ +} while (0) +#define UART_PR_ERR(fmt, arg...) \ +do { if (gDbgLevel >= UART_LOG_ERR) \ + pr_err(PFX "%s: " fmt, __func__, ##arg); \ +} while (0) + + +#include +#define LDISC_RX_TASKLET 0 +#define LDISC_RX_WORK 1 + +#if WMT_UART_RX_MODE_WORK +#define LDISC_RX LDISC_RX_WORK +#else +#define LDISC_RX LDISC_RX_TASKLET +#endif + +#if (LDISC_RX == LDISC_RX_TASKLET) +#define LDISC_RX_FIFO_SIZE (0x20000) /*8192 bytes */ +struct kfifo *g_stp_uart_rx_fifo; +spinlock_t g_stp_uart_rx_fifo_spinlock; +struct tasklet_struct g_stp_uart_rx_fifo_tasklet; +#define RX_BUFFER_LEN 1024 +UINT8 g_rx_data[RX_BUFFER_LEN]; + +/* static DEFINE_RWLOCK(g_stp_uart_rx_handling_lock); */ +#elif (LDISC_RX == LDISC_RX_WORK) + +#define LDISC_RX_FIFO_SIZE (0x4000) /* 16K bytes shall be enough...... */ +#define LDISC_RX_BUF_SIZE (2048) /* 2K bytes in one shot is enough */ + +PUINT8 g_stp_uart_rx_buf; /* for stp rx data parsing */ +struct kfifo *g_stp_uart_rx_fifo; /* for uart tty data receiving */ +spinlock_t g_stp_uart_rx_fifo_spinlock; /* fifo spinlock */ +struct workqueue_struct *g_stp_uart_rx_wq; /* rx work queue (do not use system_wq) */ +struct work_struct *g_stp_uart_rx_work; /* rx work */ + +#endif + +struct tty_struct *stp_tty; + +UINT8 tx_buf[MTKSTP_BUFFER_SIZE] = { 0x0 }; + +INT32 rd_idx; +INT32 wr_idx; +/* struct semaphore buf_mtx; */ +spinlock_t buf_lock; +static INT32 mtk_wcn_uart_tx(const PUINT8 data, const UINT32 size, PUINT32 written_size); + + +static _osal_inline_ INT32 stp_uart_tx_wakeup(struct tty_struct *tty) +{ + INT32 len = 0; + INT32 written = 0; + INT32 written_count = 0; + static INT32 i; + /* UINT32 flags; */ + /* get data from ring buffer */ +/* down(&buf_mtx); */ +/* // spin_lock_irqsave(&buf_lock, flags); */ + +#if 0 + if ((i > 1000) && (i % 5) == 0) { + UART_PR_INFO("i=(%d), ****** drop data from uart******\n", i); + i++; + return 0; + } + UART_PR_INFO("i=(%d)at stp uart **\n", i); +#endif + + len = (wr_idx >= rd_idx) ? (wr_idx - rd_idx) : (MTKSTP_BUFFER_SIZE - rd_idx); + if (len > 0 && len < MAX_PACKET_ALLOWED) { + i++; + /* + * ops->write is called by the kernel to write a series of + * characters to the tty device. The characters may come from + * user space or kernel space. This routine will return the + * number of characters actually accepted for writing. + */ + set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); + written = tty->ops->write(tty, &tx_buf[rd_idx], len); + if (written != len) { + UART_PR_ERR + ("Error(i-%d):[pid(%d)(%s)]tty-ops->write FAIL!len(%d)wr(%d)wr_i(%d)rd_i(%d)\n\r", + i, current->pid, current->comm, len, written, wr_idx, rd_idx); + return -1; + } + written_count = written; + /* pr_debug("len = %d, written = %d\n", len, written); */ + rd_idx = ((rd_idx + written) % MTKSTP_BUFFER_SIZE); + /* all data is accepted by UART driver, check again in case roll over */ + len = (wr_idx >= rd_idx) ? (wr_idx - rd_idx) : (MTKSTP_BUFFER_SIZE - rd_idx); + if (len > 0 && len < MAX_PACKET_ALLOWED) { + set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); + written = tty->ops->write(tty, &tx_buf[rd_idx], len); + if (written != len) { + UART_PR_ERR("Error(i-%d):[pid(%d)(%s)]len(%d)wr(%d)wr_i(%d)rd_i(%d)\n\r", + i, current->pid, current->comm, len, written, wr_idx, rd_idx); + return -1; + } + rd_idx = ((rd_idx + written) % MTKSTP_BUFFER_SIZE); + written_count += written; + } else if (len < 0 || len >= MAX_PACKET_ALLOWED) { + UART_PR_ERR("Warnning(i-%d):[pid(%d)(%s)]length verfication(external)\n", + i, current->pid, current->comm); + UART_PR_ERR("warnning,len(%d), wr_idx(%d), rd_idx(%d)!\n\r", len, wr_idx, rd_idx); + return -1; + } + } else { + UART_PR_ERR("Warnning(i-%d):[pid(%d)(%s)]length verfication(external)\n", + i, current->pid, current->comm); + UART_PR_ERR("warnning,len(%d), wr_idx(%d), rd_idx(%d)!\n\r", len, wr_idx, rd_idx); + return -1; + } + /* up(&buf_mtx); */ +/* // spin_unlock_irqrestore(&buf_lock, flags); */ + return written_count; +} + +/* ------ LDISC part ------ */ +/* stp_uart_tty_open + * + * Called when line discipline changed to HCI_UART. + * + * Arguments: + * tty pointer to tty info structure + * Return Value: + * 0 if success, otherwise error code + */ +static INT32 stp_uart_tty_open(struct tty_struct *tty) +{ + UART_PR_DBG("stp_uart_tty_opentty: %p\n", tty); + + tty->receive_room = 65536; + tty->port->low_latency = 1; + + /* Flush any pending characters in the driver and line discipline. */ + + /* FIXME: why is this needed. Note don't use ldisc_ref here as the */ + /* open path is before the ldisc is referencable */ + + /* definition changed!! */ + if (tty->ldisc->ops->flush_buffer) + tty->ldisc->ops->flush_buffer(tty); + + tty_driver_flush_buffer(tty); + +/* init_MUTEX(&buf_mtx); */ +/* // spin_lock_init(&buf_lock); */ + + rd_idx = wr_idx = 0; + stp_tty = tty; + mtk_wcn_stp_register_if_tx(STP_UART_IF_TX, (MTK_WCN_STP_IF_TX) mtk_wcn_uart_tx); + + return 0; +} + +/* stp_uart_tty_close() + * + * Called when the line discipline is changed to something + * else, the tty is closed, or the tty detects a hangup. + */ +static VOID stp_uart_tty_close(struct tty_struct *tty) +{ + UART_PR_DBG("stp_uart_tty_close(): tty %p\n", tty); + mtk_wcn_stp_register_if_tx(STP_UART_IF_TX, NULL); +} + +/* stp_uart_tty_wakeup() + * + * Callback for transmit wakeup. Called when low level + * device driver can accept more send data. + * + * Arguments: tty pointer to associated tty instance data + * Return Value: None + */ +static VOID stp_uart_tty_wakeup(struct tty_struct *tty) +{ + /* pr_debug("%s: start !!\n", __FUNCTION__); */ + + /* clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); */ + + /* stp_uart_tx_wakeup(tty); */ +} + +/* stp_uart_tty_receive() + * + * Called by tty low level driver when receive data is + * available. + * + * Arguments: tty pointer to tty isntance data + * data pointer to received data + * flags pointer to flags for data + * count count of received data in bytes + * + * Return Value: None + */ +#if (LDISC_RX == LDISC_RX_TASKLET) + +static INT32 stp_uart_fifo_init(VOID) +{ + INT32 err = 0; + /*add rx fifo */ + g_stp_uart_rx_fifo = kzalloc(sizeof(struct kfifo), GFP_ATOMIC); + if (g_stp_uart_rx_fifo == NULL) { + err = -2; + UART_PR_ERR("kzalloc for g_stp_uart_rx_fifo failed (kernel version > 2.6.35)\n"); + return err; + } + err = kfifo_alloc(g_stp_uart_rx_fifo, LDISC_RX_FIFO_SIZE, GFP_ATOMIC); + if (err != 0) { + UART_PR_ERR("kfifo_alloc failed, errno(%d)(kernel version > 2.6.35)\n", err); + kfree(g_stp_uart_rx_fifo); + g_stp_uart_rx_fifo = NULL; + err = -3; + return err; + } + if (err == 0) { + if (g_stp_uart_rx_fifo != NULL) { + kfifo_reset(g_stp_uart_rx_fifo); + UART_PR_DBG("stp_uart_fifo_init() success.\n"); + } else { + err = -4; + UART_PR_ERR + ("abnormal case, err = 0 but g_stp_uart_rx_fifo = NULL, set err to %d\n", + err); + } + } else + UART_PR_ERR("stp_uart_fifo_init() failed.\n"); + + return err; +} + +static INT32 stp_uart_fifo_deinit(VOID) +{ + if (g_stp_uart_rx_fifo != NULL) { + kfifo_free(g_stp_uart_rx_fifo); + kfree(g_stp_uart_rx_fifo); + g_stp_uart_rx_fifo = NULL; + } + return 0; +} + +static VOID stp_uart_rx_handling(ULONG func_data) +{ + UINT32 how_much_get = 0; + UINT32 how_much_to_get = 0; + UINT32 flag = 0; + +/* read_lock(&g_stp_uart_rx_handling_lock); */ + how_much_to_get = kfifo_len(g_stp_uart_rx_fifo); + + if (how_much_to_get >= RX_BUFFER_LEN) { + flag = 1; + UART_PR_INFO("fifolen(%d)\n", how_much_to_get); + } + + do { + how_much_get = kfifo_out(g_stp_uart_rx_fifo, g_rx_data, RX_BUFFER_LEN); + /* UART_PR_INFO ("fifoget(%d)\n", how_much_get); */ + mtk_wcn_stp_parser_data((UINT8 *) g_rx_data, how_much_get); + how_much_to_get = kfifo_len(g_stp_uart_rx_fifo); + } while (how_much_to_get > 0); + +/* read_unlock(&g_stp_uart_rx_handling_lock); */ + if (flag == 1) + UART_PR_INFO("finish, fifolen(%d)\n", kfifo_len(g_stp_uart_rx_fifo)); +} + +static VOID stp_uart_tty_receive(struct tty_struct *tty, const unsigned char *data, PINT8 flags, INT32 count) +{ + UINT32 fifo_avail_len = LDISC_RX_FIFO_SIZE - kfifo_len(g_stp_uart_rx_fifo); + UINT32 how_much_put = 0; +#if 0 + { + struct timeval now; + + osal_do_gettimeofday(&now); + pr_warn("[+STP][ ][R] %4d --> sec = %lu, --> usec --> %lu\n", + count, now.tv_sec, now.tv_usec); + } +#endif +/* write_lock(&g_stp_uart_rx_handling_lock); */ + if (count > 2000) { + /*this is abnormal */ + UART_PR_ERR("abnormal: buffer count = %d\n", count); + } + /*How much empty seat? */ + if (fifo_avail_len > 0) { + /* UART_PR_INFO ("fifo left(%d), count(%d)\n", fifo_avail_len, count); */ + how_much_put = kfifo_in(g_stp_uart_rx_fifo, (PUINT8) data, count); + + /*schedule it! */ + tasklet_schedule(&g_stp_uart_rx_fifo_tasklet); + } else { + UART_PR_ERR("stp_uart_tty_receive rxfifo is full!!\n"); + } + +#if 0 + { + struct timeval now; + + osal_do_gettimeofday(&now); + pr_warn("[-STP][ ][R] %4d --> sec = %lu, --> usec --> %lu\n", + count, now.tv_sec, now.tv_usec); + } +#endif + +/* write_unlock(&g_stp_uart_rx_handling_lock); */ + +} +#elif (LDISC_RX == LDISC_RX_WORK) +static INT32 stp_uart_fifo_init(VOID) +{ + INT32 err = 0; + + g_stp_uart_rx_buf = vzalloc(LDISC_RX_BUF_SIZE); + if (!g_stp_uart_rx_buf) { + UART_PR_ERR("kfifo_alloc failed (kernel version >= 2.6.37)\n"); + err = -4; + goto fifo_init_end; + } + + UART_PR_INFO("g_stp_uart_rx_buf alloc ok(0x%p, %d)\n", + g_stp_uart_rx_buf, LDISC_RX_BUF_SIZE); + + /*add rx fifo */ + /* allocate struct kfifo first */ + g_stp_uart_rx_fifo = kzalloc(sizeof(struct kfifo), GFP_KERNEL); + if (g_stp_uart_rx_fifo == NULL) { + err = -2; + UART_PR_ERR("kzalloc struct kfifo failed (kernel version > 2.6.33)\n"); + goto fifo_init_end; + } + + /* allocate kfifo data buffer then */ + err = kfifo_alloc(g_stp_uart_rx_fifo, LDISC_RX_FIFO_SIZE, GFP_KERNEL); + if (err != 0) { + UART_PR_ERR("kfifo_alloc failed, err(%d)(kernel version > 2.6.33)\n", err); + kfree(g_stp_uart_rx_fifo); + g_stp_uart_rx_fifo = NULL; + err = -3; + goto fifo_init_end; + } + UART_PR_INFO("g_stp_uart_rx_fifo alloc ok\n"); + +fifo_init_end: + + if (err == 0) { + /* kfifo init ok */ + kfifo_reset(g_stp_uart_rx_fifo); + UART_PR_DBG("g_stp_uart_rx_fifo init success\n"); + } else { + UART_PR_ERR("stp_uart_fifo_init() fail(%d)\n", err); + if (g_stp_uart_rx_buf) { + UART_PR_DBG("free g_stp_uart_rx_buf\n"); + vfree(g_stp_uart_rx_buf); + g_stp_uart_rx_buf = NULL; + } + } + + return err; +} + +static INT32 stp_uart_fifo_deinit(VOID) +{ + if (g_stp_uart_rx_buf) { + vfree(g_stp_uart_rx_buf); + g_stp_uart_rx_buf = NULL; + } + + if (g_stp_uart_rx_fifo != NULL) { + kfifo_free(g_stp_uart_rx_fifo); + kfree(g_stp_uart_rx_fifo); + g_stp_uart_rx_fifo = NULL; + } + return 0; +} + +static VOID stp_uart_rx_worker(struct work_struct *work) +{ + UINT32 read; + + if (unlikely(!g_stp_uart_rx_fifo)) { + UART_PR_ERR("NULL rx fifo!\n"); + return; + } + if (unlikely(!g_stp_uart_rx_buf)) { + UART_PR_ERR("NULL rx buf!\n"); + return; + } + + + /* run until fifo becomes empty */ + while (!kfifo_is_empty(g_stp_uart_rx_fifo)) { + read = kfifo_out(g_stp_uart_rx_fifo, g_stp_uart_rx_buf, LDISC_RX_BUF_SIZE); + /* pr_debug("rx_work:%d\n\r",read); */ + if (likely(read)) { + /* UART_LOUD_FUNC("->%d\n", read); */ + mtk_wcn_stp_parser_data((UINT8 *) g_stp_uart_rx_buf, read); + /* UART_LOUD_FUNC("<-\n", read); */ + } + } +} + +/* stp_uart_tty_receive() + * + * Called by tty low level driver when receive data is + * available. + * + * Arguments: tty pointer to tty isntance data + * data pointer to received data + * flags pointer to flags for data + * count count of received data in bytes + * + * Return Value: None + */ +static VOID stp_uart_tty_receive(struct tty_struct *tty, const PUINT8 data, PINT8 flags, INT32 count) +{ + UINT32 written; + + /* UART_LOUD_FUNC("URX:%d\n", count); */ + if (unlikely(count > 2000)) + UART_PR_WARN("abnormal: buffer count = %d\n", count); + + if (unlikely(!g_stp_uart_rx_fifo || !g_stp_uart_rx_work || !g_stp_uart_rx_wq)) { + UART_PR_ERR + ("abnormal g_stp_uart_rx_fifo(0x%p),g_stp_uart_rx_work(0x%p),g_stp_uart_rx_wq(0x%p)\n", + g_stp_uart_rx_fifo, g_stp_uart_rx_work, g_stp_uart_rx_wq); + return; + } + + /* need to check available buffer size? skip! */ + + /* need to lock fifo? skip for single writer single reader! */ + + written = kfifo_in(g_stp_uart_rx_fifo, (PUINT8) data, count); + /* pr_debug("uart_rx:%d,wr:%d\n\r",count,written); */ + + queue_work(g_stp_uart_rx_wq, g_stp_uart_rx_work); + + if (unlikely(written != count)) + UART_PR_ERR("c(%d),w(%d) bytes dropped\n", count, written); +} + +#else + +static VOID stp_uart_tty_receive(struct tty_struct *tty, const PUINT8 data, PINT8 flags, INT32 count) +{ + +#if 0 + mtk_wcn_stp_debug_gpio_assert(IDX_STP_RX_PROC, DBG_TIE_LOW); +#endif + + if (count > 2000) { + /*this is abnormal */ + UART_PR_ERR("stp_uart_tty_receive buffer count = %d\n", count); + } +#if 0 + { + struct timeval now; + + osal_do_gettimeofday(&now); + } +#endif + + + /*There are multi-context to access here? Need to spinlock? */ + /*Only one context: flush_to_ldisc in tty_buffer.c */ + mtk_wcn_stp_parser_data((UINT8 *) data, (UINT32) count); + +#if 0 + mtk_wcn_stp_debug_gpio_assert(IDX_STP_RX_PROC, DBG_TIE_HIGH); +#endif + + tty_unthrottle(tty); + +#if 0 + { + struct timeval now; + + osal_do_gettimeofday(&now); + } +#endif +} +#endif + +/* stp_uart_tty_ioctl() + * + * Process IOCTL system call for the tty device. + * + * Arguments: + * + * tty pointer to tty instance data + * file pointer to open file object for device + * cmd IOCTL command code + * arg argument for IOCTL call (cmd dependent) + * + * Return Value: Command dependent + */ +static INT32 stp_uart_tty_ioctl(struct tty_struct *tty, struct file *file, UINT32 cmd, ULONG arg) +{ + INT32 err = 0; + + switch (cmd) { + case HCIUARTSETPROTO: + UART_PR_DBG(" Set low_latency to TRUE \n"); + tty->port->low_latency = 1; + + break; + default: + UART_PR_DBG(" n_tty_ioctl_helper \n"); + err = n_tty_ioctl_helper(tty, file, cmd, arg); + break; + }; + + return err; +} + +/* + * We don't provide read/write/poll interface for user space. + */ +static ssize_t stp_uart_tty_read(struct tty_struct *tty, struct file *file, + unsigned char __user *buf, size_t nr) +{ + return 0; +} + +static ssize_t stp_uart_tty_write(struct tty_struct *tty, struct file *file, + const unsigned char *data, size_t count) +{ + return 0; +} + +static UINT32 stp_uart_tty_poll(struct tty_struct *tty, struct file *filp, poll_table *wait) +{ + return 0; +} + +INT32 mtk_wcn_uart_tx(const PUINT8 data, const UINT32 size, PUINT32 written_size) +{ + INT32 room; + /* int idx = 0; */ + /* unsigned long flags; */ + INT32 ret = 0; + UINT32 len; + /* static int tmp=0; */ + static INT32 i; + + if (stp_tty == NULL) + return -1; + + (*written_size) = 0; + /* put data into ring buffer */ + /* down(&buf_mtx); */ + + + /* + * [PatchNeed] + * spin_lock_irqsave is redundant + */ + /* spin_lock_irqsave(&buf_lock, flags); */ + + room = + (wr_idx >= + rd_idx) ? (MTKSTP_BUFFER_SIZE - (wr_idx - rd_idx) - 1) : (rd_idx - wr_idx - 1); + UART_PR_DBG("r(%d)s(%d)wr_i(%d)rd_i(%d)\n\r", room, size, wr_idx, rd_idx); + /* + * [PatchNeed] + * Block copy instead of byte copying + */ + if (data == NULL) { + UART_PR_ERR("pid(%d)(%s): data is NULL\n", current->pid, current->comm); + (*written_size) = 0; + return -2; + } +#if 1 + if (unlikely(size > room)) { + UART_PR_ERR + ("pid(%d)(%s)room is not available, size needed(%d), wr_idx(%d), rd_idx(%d), room left(%d)\n", + current->pid, current->comm, size, wr_idx, rd_idx, room); + (*written_size) = 0; + return -3; + } + /* wr_idx : the position next to write */ + /* rd_idx : the position next to read */ + len = min(size, MTKSTP_BUFFER_SIZE - (UINT32) wr_idx); + memcpy(&tx_buf[wr_idx], &data[0], len); + memcpy(&tx_buf[0], &data[len], size - len); + wr_idx = (wr_idx + size) % MTKSTP_BUFFER_SIZE; + UART_PR_DBG("r(%d)s(%d)wr_i(%d)rd_i(%d)\n\r", room, size, wr_idx, rd_idx); + i++; + if (size == 0) { + (*written_size) = 0; + } else if (size < MAX_PACKET_ALLOWED) { + /* only size ~(0, 2000) is allowed */ + ret = stp_uart_tx_wakeup(stp_tty); + if (ret < 0) { + /* reset read and write index of tx_buffer, is there any risk? */ + wr_idx = rd_idx = 0; + *written_size = 0; + } else + *written_size = ret; + } else { + /* we filter all packet with size > 2000 */ + UART_PR_ERR("Warnning(i-%d):[pid(%d)(%s)]len(%d)size(%d)wr_i(%d)rd_i(%d)\n\r", + i, current->pid, current->comm, len, size, wr_idx, rd_idx); + (*written_size) = 0; + } +#endif + + +#if 0 + while ((room > 0) && (size > 0)) { + tx_buf[wr_idx] = data[idx]; + wr_idx = ((wr_idx + 1) % MTKSTP_BUFFER_SIZE); + idx++; + room--; + size--; + (*written_size)++; + } +#endif + /* up(&buf_mtx); */ + /* + * [PatchNeed] + * spin_lock_irqsave is redundant + */ + /* spin_lock_irqsave(&buf_lock, flags); */ + + /*[PatchNeed]To add a tasklet to shedule Uart Tx */ + + return 0; +} + +static INT32 mtk_wcn_stp_uart_init(VOID) +{ + static struct tty_ldisc_ops stp_uart_ldisc; + INT32 err; + INT32 fifo_init_done = 0; + + UART_PR_DBG("mtk_wcn_stp_uart_init(): MTK STP UART driver\n"); + +#if (LDISC_RX == LDISC_RX_TASKLET) + err = stp_uart_fifo_init(); + if (err != 0) + goto init_err; + + fifo_init_done = 1; + /*init rx tasklet */ + tasklet_init(&g_stp_uart_rx_fifo_tasklet, stp_uart_rx_handling, (ULONG)0); + +#elif (LDISC_RX == LDISC_RX_WORK) + err = stp_uart_fifo_init(); + if (err != 0) { + UART_PR_ERR("stp_uart_fifo_init(WORK) error(%d)\n", err); + err = -EFAULT; + goto init_err; + } + fifo_init_done = 1; + + g_stp_uart_rx_work = vmalloc(sizeof(struct work_struct)); + if (!g_stp_uart_rx_work) { + UART_PR_ERR("vmalloc work_struct(%d) fail\n", sizeof(struct work_struct)); + err = -ENOMEM; + goto init_err; + } + + g_stp_uart_rx_wq = create_singlethread_workqueue("mtk_urxd"); + if (!g_stp_uart_rx_wq) { + UART_PR_ERR("create_singlethread_workqueue fail\n"); + err = -ENOMEM; + goto init_err; + } + + /* init rx work */ + INIT_WORK(g_stp_uart_rx_work, stp_uart_rx_worker); + +#endif + + /* Register the tty discipline */ + memset(&stp_uart_ldisc, 0, sizeof(stp_uart_ldisc)); + stp_uart_ldisc.magic = TTY_LDISC_MAGIC; + stp_uart_ldisc.name = "n_mtkstp"; + stp_uart_ldisc.open = stp_uart_tty_open; + stp_uart_ldisc.close = stp_uart_tty_close; + stp_uart_ldisc.read = stp_uart_tty_read; + stp_uart_ldisc.write = stp_uart_tty_write; + stp_uart_ldisc.ioctl = stp_uart_tty_ioctl; + stp_uart_ldisc.poll = stp_uart_tty_poll; + stp_uart_ldisc.receive_buf = stp_uart_tty_receive; + stp_uart_ldisc.write_wakeup = stp_uart_tty_wakeup; + stp_uart_ldisc.owner = THIS_MODULE; + + err = tty_register_ldisc(N_MTKSTP, &stp_uart_ldisc); + if (err) { + UART_PR_ERR("MTK STP line discipline registration failed. (%d)\n", err); + goto init_err; + } + + /* + * mtk_wcn_stp_register_if_tx( mtk_wcn_uart_tx); + */ + + return 0; + +init_err: + +#if (LDISC_RX == LDISC_RX_TASKLET) + /* nothing */ + if (fifo_init_done) + stp_uart_fifo_deinit(); +#elif (LDISC_RX == LDISC_RX_WORK) + if (g_stp_uart_rx_wq) { + destroy_workqueue(g_stp_uart_rx_wq); + g_stp_uart_rx_wq = NULL; + } + if (g_stp_uart_rx_work) + vfree(g_stp_uart_rx_work); + + if (fifo_init_done) + stp_uart_fifo_deinit(); +#endif + UART_PR_ERR("init fail, return(%d)\n", err); + + return err; + +} + +static VOID mtk_wcn_stp_uart_exit(VOID) +{ + INT32 err; + + mtk_wcn_stp_register_if_tx(STP_UART_IF_TX, NULL); /* unregister if_tx function */ + + /* Release tty registration of line discipline */ + err = tty_unregister_ldisc(N_MTKSTP); + if (err) + UART_PR_ERR("Can't unregister MTK STP line discipline (%d)\n", err); + +#if (LDISC_RX == LDISC_RX_TASKLET) + tasklet_kill(&g_stp_uart_rx_fifo_tasklet); + stp_uart_fifo_deinit(); +#elif (LDISC_RX == LDISC_RX_WORK) + if (g_stp_uart_rx_work) + cancel_work_sync(g_stp_uart_rx_work); + + if (g_stp_uart_rx_wq) { + destroy_workqueue(g_stp_uart_rx_wq); + g_stp_uart_rx_wq = NULL; + } + if (g_stp_uart_rx_work) { + vfree(g_stp_uart_rx_work); + g_stp_uart_rx_work = NULL; + } + stp_uart_fifo_deinit(); + +#endif +} + +INT32 mtk_wcn_stp_uart_drv_init(VOID) +{ + return mtk_wcn_stp_uart_init(); + +} +EXPORT_SYMBOL(mtk_wcn_stp_uart_drv_init); + +VOID mtk_wcn_stp_uart_drv_exit(VOID) +{ + return mtk_wcn_stp_uart_exit(); +} +EXPORT_SYMBOL(mtk_wcn_stp_uart_drv_exit); diff --git a/drivers/misc/mediatek/connectivity/common/common_main/linux/wmt_alarm.c b/drivers/misc/mediatek/connectivity/common/common_main/linux/wmt_alarm.c new file mode 100644 index 0000000000000000000000000000000000000000..1ad1c263156bd0b237ec28802d79b0b412cf0a2e --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/linux/wmt_alarm.c @@ -0,0 +1,150 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include +#include +#include "osal.h" +#include "wmt_alarm.h" +#include "wmt_lib.h" + +#define WMT_ALARM_STATE_UNINIT 0x0 +#define WMT_ALARM_STATE_DISABLE 0x01 +#define WMT_ALARM_STATE_ENABLE 0x03 + +struct wmt_alarm { + struct alarm alarm_timer; + unsigned int alarm_state; + unsigned int alarm_sec; + spinlock_t alarm_lock; + struct work_struct dmp_info_worker; + unsigned long flags; +}; + +struct wmt_alarm g_wmt_alarm; +static CONSYS_STATE_DMP_INFO g_dmp_info; + + +static void wmt_alarm_dmp_info_handler(struct work_struct *work) +{ + UINT8 dmp_info_buf[DBG_LOG_STR_SIZE]; + int len = 0, i, dmp_cnt = 5; + + if (wmt_lib_dmp_consys_state(&g_dmp_info, dmp_cnt, 0) == MTK_WCN_BOOL_TRUE) { + + len += snprintf(dmp_info_buf + len, + DBG_LOG_STR_SIZE - len, "0x%08x", g_dmp_info.cpu_pcr[0]); + for (i = 1; i < dmp_cnt; i++) + len += snprintf(dmp_info_buf + len, + DBG_LOG_STR_SIZE - len, ";0x%08x", g_dmp_info.cpu_pcr[i]); + + len += snprintf(dmp_info_buf + len, + DBG_LOG_STR_SIZE - len, ";<0x%08x>", g_dmp_info.state.lp[1]); + + len += snprintf(dmp_info_buf + len, + DBG_LOG_STR_SIZE - len, ";<0x%08x>", g_dmp_info.state.gating[1]); + + len += snprintf(dmp_info_buf + len, DBG_LOG_STR_SIZE - len, + ";[0x%08x", g_dmp_info.state.sw_state.info_time); + len += snprintf(dmp_info_buf + len, DBG_LOG_STR_SIZE - len, + ";0x%08x", g_dmp_info.state.sw_state.is_gating); + len += snprintf(dmp_info_buf + len, DBG_LOG_STR_SIZE - len, + ";0x%08x", g_dmp_info.state.sw_state.resource_disable_sleep); + len += snprintf(dmp_info_buf + len, DBG_LOG_STR_SIZE - len, + ";0x%08x", g_dmp_info.state.sw_state.clock_hif_ctrl); + len += snprintf(dmp_info_buf + len, DBG_LOG_STR_SIZE - len, + ";0x%08x", g_dmp_info.state.sw_state.clock_umac_ctrl); + len += snprintf(dmp_info_buf + len, DBG_LOG_STR_SIZE - len, + ";0x%08x", g_dmp_info.state.sw_state.clock_mcu); + len += snprintf(dmp_info_buf + len, DBG_LOG_STR_SIZE - len, + ";0x%08x]", g_dmp_info.state.sw_state.sub_system); + + WMT_INFO_FUNC("%s", dmp_info_buf); + } +} + +static enum alarmtimer_restart alarm_timer_handler(struct alarm *alarm, + ktime_t now) +{ + ktime_t kt; + + spin_lock_irqsave(&g_wmt_alarm.alarm_lock, g_wmt_alarm.flags); + + schedule_work(&g_wmt_alarm.dmp_info_worker); + kt = ktime_set(g_wmt_alarm.alarm_sec, 0); + alarm_start_relative(&g_wmt_alarm.alarm_timer, kt); + + spin_unlock_irqrestore(&g_wmt_alarm.alarm_lock, g_wmt_alarm.flags); + + return ALARMTIMER_NORESTART; +} + +static int _wmt_alarm_start_timer_nolock(unsigned int sec) +{ + ktime_t kt; + + g_wmt_alarm.alarm_sec = sec; + kt = ktime_set(g_wmt_alarm.alarm_sec, 0); + alarm_start_relative(&g_wmt_alarm.alarm_timer, kt); + g_wmt_alarm.alarm_state = WMT_ALARM_STATE_ENABLE; + + pr_info("[wmt_alarm] alarm timer enabled timeout=[%d]", g_wmt_alarm.alarm_sec); + return 0; +} + +int wmt_alarm_init(void) +{ + spin_lock_init(&g_wmt_alarm.alarm_lock); + + spin_lock_irqsave(&g_wmt_alarm.alarm_lock, g_wmt_alarm.flags); + alarm_init(&g_wmt_alarm.alarm_timer, ALARM_REALTIME, alarm_timer_handler); + INIT_WORK(&g_wmt_alarm.dmp_info_worker, wmt_alarm_dmp_info_handler); + g_wmt_alarm.alarm_state = WMT_ALARM_STATE_DISABLE; + + spin_unlock_irqrestore(&g_wmt_alarm.alarm_lock, g_wmt_alarm.flags); + + return 0; +} + +int wmt_alarm_deinit(void) +{ + wmt_alarm_cancel(); + return 0; +} + + +int _wmt_alarm_cancel_nolock(void) +{ + if (g_wmt_alarm.alarm_state == WMT_ALARM_STATE_ENABLE) { + pr_info("disable wmt_alarm"); + alarm_cancel(&g_wmt_alarm.alarm_timer); + g_wmt_alarm.alarm_state = WMT_ALARM_STATE_DISABLE; + } + return 0; +} + +int wmt_alarm_start(unsigned int sec) +{ + spin_lock_irqsave(&g_wmt_alarm.alarm_lock, g_wmt_alarm.flags); + if (g_wmt_alarm.alarm_state == WMT_ALARM_STATE_UNINIT) { + spin_unlock_irqrestore(&g_wmt_alarm.alarm_lock, g_wmt_alarm.flags); + return -1; + } + + if (g_wmt_alarm.alarm_state == WMT_ALARM_STATE_ENABLE) + _wmt_alarm_cancel_nolock(); + _wmt_alarm_start_timer_nolock(sec); + spin_unlock_irqrestore(&g_wmt_alarm.alarm_lock, g_wmt_alarm.flags); + return 0; +} + +int wmt_alarm_cancel(void) +{ + int ret; + + spin_lock_irqsave(&g_wmt_alarm.alarm_lock, g_wmt_alarm.flags); + ret = _wmt_alarm_cancel_nolock(); + spin_unlock_irqrestore(&g_wmt_alarm.alarm_lock, g_wmt_alarm.flags); + return ret; +} diff --git a/drivers/misc/mediatek/connectivity/common/common_main/linux/wmt_dbg.c b/drivers/misc/mediatek/connectivity/common/common_main/linux/wmt_dbg.c new file mode 100644 index 0000000000000000000000000000000000000000..5736dfcd3ed6e3387d07046bcf784792d39cc47d --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/linux/wmt_dbg.c @@ -0,0 +1,1627 @@ +/* +* Copyright (C) 2016 MediaTek Inc. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. +*/ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +#include "osal_typedef.h" +#include "wmt_dbg.h" +#include "wmt_dev.h" +#include "wmt_core.h" +#include "wmt_lib.h" +#include "wmt_conf.h" +#include "psm_core.h" +#include "stp_core.h" +#include "stp_dbg.h" +#include "connsys_debug_utility.h" +#include "wmt_step.h" +#include "wmt_alarm.h" +#ifdef CONFIG_MTK_ENG_BUILD +#include "wmt_step_test.h" +#endif + +#ifdef DFT_TAG +#undef DFT_TAG +#define DFT_TAG "[WMT-DEV]" +#endif + +#define WMT_DBG_PROCNAME "driver/wmt_dbg" + +#define BUF_LEN_MAX 384 + +#if (defined(CONFIG_MTK_GMO_RAM_OPTIMIZE) && !defined(CONFIG_MTK_ENG_BUILD)) +#define WMT_EMI_DEBUG_BUF_SIZE (8*1024) +#else +#define WMT_EMI_DEBUG_BUF_SIZE (32*1024) +#endif + +struct wmt_dbg_work { + struct work_struct work; + INT32 x; + INT32 y; + INT32 z; +}; + +static struct proc_dir_entry *gWmtDbgEntry; +COEX_BUF gCoexBuf; +static UINT8 gEmiBuf[WMT_EMI_DEBUG_BUF_SIZE]; +PUINT8 buf_emi; +static OSAL_SLEEPABLE_LOCK g_dbg_emi_lock; + +static ssize_t wmt_dbg_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos); +static ssize_t wmt_dbg_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos); + + +static INT32 wmt_dbg_psm_ctrl(INT32 par1, INT32 par2, INT32 par3); +static INT32 wmt_dbg_quick_sleep_ctrl(INT32 par1, INT32 par2, INT32 par3); +static INT32 wmt_dbg_dsns_ctrl(INT32 par1, INT32 par2, INT32 par3); +static INT32 wmt_dbg_hwver_get(INT32 par1, INT32 par2, INT32 par3); +static INT32 wmt_dbg_inband_rst(INT32 par1, INT32 par2, INT32 par3); +static INT32 wmt_dbg_chip_rst(INT32 par1, INT32 par2, INT32 par3); +static INT32 wmt_dbg_func_ctrl(INT32 par1, INT32 par2, INT32 par3); +static INT32 wmt_dbg_raed_chipid(INT32 par1, INT32 par2, INT32 par3); +static INT32 wmt_dbg_wmt_dbg_level(INT32 par1, INT32 par2, INT32 par3); +static INT32 wmt_dbg_stp_dbg_level(INT32 par1, INT32 par2, INT32 par3); +static INT32 wmt_dbg_reg_read(INT32 par1, INT32 par2, INT32 par3); +static INT32 wmt_dbg_reg_write(INT32 par1, INT32 par2, INT32 par3); +static INT32 wmt_dbg_coex_test(INT32 par1, INT32 par2, INT32 par3); +static INT32 wmt_dbg_assert_test(INT32 par1, INT32 par2, INT32 par3); +static INT32 wmt_dbg_cmd_test_api(ENUM_WMTDRV_CMD_T cmd); +static INT32 wmt_dbg_rst_ctrl(INT32 par1, INT32 par2, INT32 par3); +static INT32 wmt_dbg_ut_test(INT32 par1, INT32 par2, INT32 par3); +static INT32 wmt_dbg_efuse_read(INT32 par1, INT32 par2, INT32 par3); +static INT32 wmt_dbg_efuse_write(INT32 par1, INT32 par2, INT32 par3); +static INT32 wmt_dbg_sdio_ctrl(INT32 par1, INT32 par2, INT32 par3); +static INT32 wmt_dbg_stp_dbg_ctrl(INT32 par1, INT32 par2, INT32 par3); +static INT32 wmt_dbg_stp_dbg_log_ctrl(INT32 par1, INT32 par2, INT32 par3); +static INT32 wmt_dbg_wmt_assert_ctrl(INT32 par1, INT32 par2, INT32 par3); +#if CFG_CORE_INTERNAL_TXRX +static INT32 wmt_dbg_internal_lpbk_test(INT32 par1, INT32 par2, INT32 par3); +#endif +static INT32 wmt_dbg_stp_trigger_assert(INT32 par1, INT32 par2, INT32 par3); +static INT32 wmt_dbg_ap_reg_read(INT32 par1, INT32 par2, INT32 par3); +static INT32 wmt_dbg_ap_reg_write(INT32 par1, INT32 par2, INT32 par3); +static INT32 wmt_dbg_set_mcu_clock(INT32 par1, INT32 par2, INT32 par3); +static INT32 wmt_dbg_poll_cpupcr(INT32 par1, INT32 par2, INT32 par3); +#if CONSYS_ENALBE_SET_JTAG +static INT32 wmt_dbg_jtag_flag_ctrl(INT32 par1, INT32 par2, INT32 par3); +#endif +#if CFG_WMT_LTE_COEX_HANDLING +static INT32 wmt_dbg_lte_coex_test(INT32 par1, INT32 par2, INT32 par3); +#endif +#ifdef CONFIG_TRACING +static INT32 wmt_dbg_ftrace_dbg_log_ctrl(INT32 par1, INT32 par2, INT32 par3); +#endif +#ifdef CONFIG_MTK_COMBO_CHIP_DEEP_SLEEP_SUPPORT +static INT32 wmt_dbg_deep_sleep_ctrl(INT32 par1, INT32 par2, INT32 par3); +#endif +static INT32 wmt_dbg_sdio_retry_ctrl(INT32 par1, INT32 par2, INT32 par3); + +static INT32 wmt_dbg_func0_reg_read(INT32 par1, INT32 address, INT32 value); +static INT32 wmt_dbg_func0_reg_write(INT32 par1, INT32 address, INT32 value); +static INT32 wmt_dbg_stp_sdio_reg_read(INT32 par1, INT32 address, INT32 value); +static INT32 wmt_dbg_stp_sdio_reg_write(INT32 par1, INT32 address, INT32 value); +static INT32 wmt_dbg_show_thread_debug_info(INT32 par1, INT32 address, INT32 value); +static INT32 wmt_dbg_met_ctrl(INT32 par1, INT32 met_ctrl, INT32 log_ctrl); +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH +static INT32 wmt_dbg_set_fw_log_mode(INT32 par1, INT32 par2, INT32 par3); +static INT32 wmt_dbg_emi_dump(INT32 par1, INT32 offset, INT32 size); +#endif +static INT32 wmt_dbg_suspend_debug(INT32 par1, INT32 offset, INT32 size); +static INT32 wmt_dbg_fw_log_ctrl(INT32 par1, INT32 onoff, INT32 level); +static INT32 wmt_dbg_pre_pwr_on_ctrl(INT32 par1, INT32 enable, INT32 par3); +#ifdef CONFIG_MTK_ENG_BUILD +static INT32 wmt_dbg_step_test(INT32 par1, INT32 address, INT32 value); +#endif + +static INT32 wmt_dbg_alarm_ctrl(INT32 par1, INT32 offset, INT32 size); + +static INT32 wmt_dbg_thermal_query(INT32 par1, INT32 count, INT32 interval); +static INT32 wmt_dbg_thermal_ctrl(INT32 par1, INT32 par2, INT32 par3); +static INT32 wmt_dbg_step_ctrl(INT32 par1, INT32 par2, INT32 par3); + +static INT32 wmt_dbg_gps_suspend(INT32 par1, INT32 par2, INT32 par3); +static INT32 wmt_dbg_set_bt_link_status(INT32 par1, INT32 par2, INT32 par3); + +static const WMT_DEV_DBG_FUNC wmt_dev_dbg_func[] = { + [0x0] = wmt_dbg_psm_ctrl, + [0x1] = wmt_dbg_quick_sleep_ctrl, + [0x2] = wmt_dbg_dsns_ctrl, + [0x3] = wmt_dbg_hwver_get, + [0x4] = wmt_dbg_assert_test, + [0x5] = wmt_dbg_inband_rst, + [0x6] = wmt_dbg_chip_rst, + [0x7] = wmt_dbg_func_ctrl, + [0x8] = wmt_dbg_raed_chipid, + [0x9] = wmt_dbg_wmt_dbg_level, + [0xa] = wmt_dbg_stp_dbg_level, + [0xb] = wmt_dbg_reg_read, + [0xc] = wmt_dbg_reg_write, + [0xd] = wmt_dbg_coex_test, + [0xe] = wmt_dbg_rst_ctrl, + [0xf] = wmt_dbg_ut_test, + [0x10] = wmt_dbg_efuse_read, + [0x11] = wmt_dbg_efuse_write, + [0x12] = wmt_dbg_sdio_ctrl, + [0x13] = wmt_dbg_stp_dbg_ctrl, + [0x14] = wmt_dbg_stp_dbg_log_ctrl, + [0x15] = wmt_dbg_wmt_assert_ctrl, + [0x16] = wmt_dbg_stp_trigger_assert, + [0x17] = wmt_dbg_ap_reg_read, + [0x18] = wmt_dbg_ap_reg_write, + [0x19] = wmt_dbg_fwinfor_from_emi, + [0x1a] = wmt_dbg_set_mcu_clock, + [0x1b] = wmt_dbg_poll_cpupcr, + [0x1c] = wmt_dbg_jtag_flag_ctrl, + +#if CFG_WMT_LTE_COEX_HANDLING + [0x1d] = wmt_dbg_lte_coex_test, +#endif +#ifdef CONFIG_TRACING + [0x1e] = wmt_dbg_ftrace_dbg_log_ctrl, +#endif +#ifdef CONFIG_MTK_COMBO_CHIP_DEEP_SLEEP_SUPPORT + [0x1f] = wmt_dbg_deep_sleep_ctrl, +#endif + [0x20] = wmt_dbg_sdio_retry_ctrl, + [0x22] = wmt_dbg_func0_reg_read, + [0x23] = wmt_dbg_func0_reg_write, + [0x24] = wmt_dbg_stp_sdio_reg_read, + [0x25] = wmt_dbg_stp_sdio_reg_write, + [0x26] = wmt_dbg_met_ctrl, + [0x27] = wmt_dbg_fw_log_ctrl, + [0x28] = wmt_dbg_pre_pwr_on_ctrl, + [0x29] = wmt_dbg_thermal_query, + [0x2a] = wmt_dbg_thermal_ctrl, + [0x2b] = wmt_dbg_step_ctrl, +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH + [0x2c] = wmt_dbg_set_fw_log_mode, + [0x2d] = wmt_dbg_emi_dump, +#endif + [0x2e] = wmt_dbg_suspend_debug, + [0x2f] = wmt_dbg_set_bt_link_status, + [0x30] = wmt_dbg_show_thread_debug_info, + [0x31] = wmt_dbg_gps_suspend, + [0x32] = wmt_dbg_alarm_ctrl, +#ifdef CONFIG_MTK_ENG_BUILD + [0xa0] = wmt_dbg_step_test, +#endif +}; + +static VOID wmt_dbg_fwinfor_print_buff(UINT32 len) +{ + UINT32 i = 0; + UINT32 idx = 0; + + for (i = 0; i < len; i++) { + buf_emi[idx] = gEmiBuf[i]; + if (gEmiBuf[i] == '\n') { + WMT_INFO_FUNC("%s", buf_emi); + osal_memset(buf_emi, 0, BUF_LEN_MAX); + idx = 0; + } else { + idx++; + if (idx == BUF_LEN_MAX-1) { + buf_emi[idx] = '\0'; + WMT_INFO_FUNC("%s", buf_emi); + osal_memset(buf_emi, 0, BUF_LEN_MAX); + idx = 0; + } + } + } + if ((idx != 0) && (idx < BUF_LEN_MAX)) { + buf_emi[idx] = '\0'; + WMT_INFO_FUNC("%s", buf_emi); + osal_memset(buf_emi, 0, BUF_LEN_MAX); + idx = 0; + } +} + +INT32 wmt_dbg_psm_ctrl(INT32 par1, INT32 par2, INT32 par3) +{ +#if CFG_WMT_PS_SUPPORT + if (par2 == 0) { + wmt_lib_ps_ctrl(0); + WMT_INFO_FUNC("disable PSM\n"); + } else { + par2 = (par2 < 1 || par2 > 2000) ? STP_PSM_IDLE_TIME_SLEEP : par2; + wmt_lib_ps_set_idle_time(par2); + wmt_lib_ps_ctrl(1); + WMT_WARN_FUNC("enable PSM, idle to sleep time = %d ms\n", par2); + } +#else + WMT_INFO_FUNC("WMT PS not supported\n"); +#endif + return 0; +} + +INT32 wmt_dbg_quick_sleep_ctrl(INT32 par1, INT32 par2, INT32 par3) +{ +#if CFG_WMT_PS_SUPPORT + UINT32 en_flag = par2; + + wmt_lib_quick_sleep_ctrl(en_flag); +#else + WMT_WARN_FUNC("WMT PS not supported\n"); +#endif + return 0; +} + +INT32 wmt_dbg_dsns_ctrl(INT32 par1, INT32 par2, INT32 par3) +{ + if (WMTDSNS_FM_DISABLE <= par2 && WMTDSNS_MAX > par2) { + WMT_INFO_FUNC("DSNS type (%d)\n", par2); + mtk_wcn_wmt_dsns_ctrl(par2); + } else { + WMT_WARN_FUNC("invalid DSNS type\n"); + } + return 0; +} + +INT32 wmt_dbg_hwver_get(INT32 par1, INT32 par2, INT32 par3) +{ + WMT_INFO_FUNC("query chip version\n"); + wmt_lib_get_icinfo(WMTCHIN_HWVER); + return 0; +} + +INT32 wmt_dbg_assert_test(INT32 par1, INT32 par2, INT32 par3) +{ + INT32 sec = 8; + INT32 times = 0; + + if (par3 == 0) { + /* par2 = 0: send assert command */ + /* par2 != 0: send exception command */ + return wmt_dbg_cmd_test_api(par2 == 0 ? 0 : 1); + } else if (par3 == 1) { + /* send noack command */ + return wmt_dbg_cmd_test_api(WMTDRV_CMD_NOACK_TEST); + } else if (par3 == 2) { + /* warn reset test */ + return wmt_dbg_cmd_test_api(WMTDRV_CMD_WARNRST_TEST); + } else if (par3 == 3) { + /* firmware trace test - for soc usage, not used in combo chip */ + return wmt_dbg_cmd_test_api(WMTDRV_CMD_FWTRACE_TEST); + } else if (par3 == 4) { + if (DISABLE_PSM_MONITOR()) { + WMT_ERR_FUNC("wake up failed\n"); + return -1; + } + /* driver type */ + wmt_lib_trigger_assert(par2, 30); + ENABLE_PSM_MONITOR(); + return 0; + } else if (par3 == 5) { + if (DISABLE_PSM_MONITOR()) { + WMT_ERR_FUNC("wake up failed\n"); + return -1; + } + /* assert reason */ + wmt_lib_trigger_assert(4, par2); + ENABLE_PSM_MONITOR(); + return 0; + } + + times = par3; + do { + WMT_INFO_FUNC("Send Assert Command per 8 secs!!\n"); + wmt_dbg_cmd_test_api(0); + osal_sleep_ms(sec * 1000); + } while (--times); + + return 0; +} + +INT32 wmt_dbg_cmd_test_api(ENUM_WMTDRV_CMD_T cmd) +{ + P_OSAL_OP pOp = NULL; + MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; + P_OSAL_SIGNAL pSignal; + + pOp = wmt_lib_get_free_op(); + if (!pOp) { + WMT_DBG_FUNC("get_free_lxop fail\n"); + return MTK_WCN_BOOL_FALSE; + } + + pSignal = &pOp->signal; + + pOp->op.opId = WMT_OPID_CMD_TEST; + + pSignal->timeoutValue = MAX_EACH_WMT_CMD; + /*this test command should be run with usb cable connected, so no host awake is needed */ + /* wmt_lib_host_awake_get(); */ + + switch (cmd) { + case WMTDRV_CMD_ASSERT: + pOp->op.au4OpData[0] = 0; + break; + case WMTDRV_CMD_EXCEPTION: + pOp->op.au4OpData[0] = 1; + break; + case WMTDRV_CMD_NOACK_TEST: + pOp->op.au4OpData[0] = 3; + break; + case WMTDRV_CMD_WARNRST_TEST: + pOp->op.au4OpData[0] = 4; + break; + case WMTDRV_CMD_FWTRACE_TEST: + pOp->op.au4OpData[0] = 5; + break; + default: + if (WMTDRV_CMD_COEXDBG_00 <= cmd && WMTDRV_CMD_COEXDBG_15 >= cmd) { + pOp->op.au4OpData[0] = 2; + pOp->op.au4OpData[1] = cmd - 2; + } else { + pOp->op.au4OpData[0] = 0xff; + pOp->op.au4OpData[1] = 0xff; + } + pOp->op.au4OpData[2] = (ULONG) gCoexBuf.buffer; + pOp->op.au4OpData[3] = osal_sizeof(gCoexBuf.buffer); + break; + } + WMT_INFO_FUNC("CMD_TEST, opid(%d), par(%zu, %zu)\n", pOp->op.opId, pOp->op.au4OpData[0], + pOp->op.au4OpData[1]); + /*wake up chip first */ + if (DISABLE_PSM_MONITOR()) { + WMT_ERR_FUNC("wake up failed\n"); + wmt_lib_put_op_to_free_queue(pOp); + return -1; + } + bRet = wmt_lib_put_act_op(pOp); + ENABLE_PSM_MONITOR(); + if ((cmd != WMTDRV_CMD_ASSERT) && + (cmd != WMTDRV_CMD_EXCEPTION) && + (cmd != WMTDRV_CMD_NOACK_TEST) && + (cmd != WMTDRV_CMD_WARNRST_TEST) && + (cmd != WMTDRV_CMD_FWTRACE_TEST)) { + if (bRet == MTK_WCN_BOOL_FALSE) { + gCoexBuf.availSize = 0; + } else { + gCoexBuf.availSize = pOp->op.au4OpData[3]; + WMT_INFO_FUNC("gCoexBuf.availSize = %d\n", gCoexBuf.availSize); + } + } + /* wmt_lib_host_awake_put(); */ + WMT_INFO_FUNC("CMD_TEST, opid (%d), par(%zu, %zu), ret(%d), result(%s)\n", + pOp->op.opId, + pOp->op.au4OpData[0], + pOp->op.au4OpData[1], + bRet, MTK_WCN_BOOL_FALSE == bRet ? "failed" : "succeed"); + + if (bRet == MTK_WCN_BOOL_TRUE) + wmt_lib_set_host_assert_info(WMTDRV_TYPE_WMT, 0, 1); + + return 0; +} + +INT32 wmt_dbg_inband_rst(INT32 par1, INT32 par2, INT32 par3) +{ + if (par2 == 0) { + WMT_INFO_FUNC("inband reset test!!\n"); + mtk_wcn_stp_inband_reset(); + } else { + WMT_INFO_FUNC("STP context reset in host side!!\n"); + mtk_wcn_stp_flush_context(); + } + + return 0; +} + +INT32 wmt_dbg_chip_rst(INT32 par1, INT32 par2, INT32 par3) +{ + if (par2 == 0) { + if (mtk_wcn_stp_is_ready()) { + WMT_INFO_FUNC("whole chip reset test\n"); + wmt_lib_cmb_rst(WMTRSTSRC_RESET_TEST); + } else { + WMT_INFO_FUNC("STP not ready , not to launch whole chip reset test\n"); + } + } else if (par2 == 1) { + WMT_INFO_FUNC("chip hardware reset test\n"); + wmt_lib_hw_rst(); + } else { + WMT_INFO_FUNC("chip software reset test\n"); + wmt_lib_sw_rst(1); + } + + return 0; +} + +INT32 wmt_dbg_func_ctrl(INT32 par1, INT32 par2, INT32 par3) +{ + MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE; + + if (par2 < WMTDRV_TYPE_WMT || par2 == WMTDRV_TYPE_LPBK || par2 == WMTDRV_TYPE_GPSL5) { + if (par3 == 0) { + WMT_INFO_FUNC("function off test, type(%d)\n", par2); + ret = mtk_wcn_wmt_func_off(par2); + } else { + WMT_INFO_FUNC("function on test, type(%d)\n", par2); + ret = mtk_wcn_wmt_func_on(par2); + } + WMT_INFO_FUNC("function test return %d\n", ret); + } else + WMT_INFO_FUNC("function ctrl test, invalid type(%d)\n", par2); + + return 0; +} + +INT32 wmt_dbg_raed_chipid(INT32 par1, INT32 par2, INT32 par3) +{ + WMT_INFO_FUNC("chip id = %d\n", wmt_lib_get_icinfo(WMTCHIN_CHIPID)); + + return 0; +} + +INT32 wmt_dbg_wmt_dbg_level(INT32 par1, INT32 par2, INT32 par3) +{ + par2 = (WMT_LOG_ERR <= par2 && WMT_LOG_LOUD >= par2) ? par2 : WMT_LOG_INFO; + wmt_lib_dbg_level_set(par2); + WMT_INFO_FUNC("set wmt log level to %d\n", par2); + + return 0; +} + +INT32 wmt_dbg_stp_dbg_level(INT32 par1, INT32 par2, INT32 par3) +{ + par2 = (0 <= par2 && 4 >= par2) ? par2 : 2; + mtk_wcn_stp_dbg_level(par2); + WMT_INFO_FUNC("set stp log level to %d\n", par2); + + return 0; +} + +INT32 wmt_dbg_reg_read(INT32 par1, INT32 par2, INT32 par3) +{ + /* par2-->register address */ + /* par3-->register mask */ + UINT32 value = 0x0; + UINT32 iRet = -1; +#if 0 + DISABLE_PSM_MONITOR(); + iRet = wmt_core_reg_rw_raw(0, par2, &value, par3); + ENABLE_PSM_MONITOR(); +#endif + iRet = wmt_lib_reg_rw(0, par2, &value, par3); + WMT_INFO_FUNC("read combo chip register (0x%08x) with mask (0x%08x) %s, value = 0x%08x\n", + par2, par3, iRet != 0 ? "failed" : "succeed", iRet != 0 ? -1 : value); + + return 0; +} + +INT32 wmt_dbg_reg_write(INT32 par1, INT32 par2, INT32 par3) +{ + /* par2-->register address */ + /* par3-->value to set */ + UINT32 iRet = -1; +#if 0 + DISABLE_PSM_MONITOR(); + iRet = wmt_core_reg_rw_raw(1, par2, &par3, 0xffffffff); + ENABLE_PSM_MONITOR(); +#endif + iRet = wmt_lib_reg_rw(1, par2, &par3, 0xffffffff); + WMT_INFO_FUNC("write combo chip register (0x%08x) with value (0x%08x) %s\n", + par2, par3, iRet != 0 ? "failed" : "succeed"); + + return 0; +} + +INT32 wmt_dbg_efuse_read(INT32 par1, INT32 par2, INT32 par3) +{ + /* par2-->efuse address */ + /* par3-->register mask */ + UINT32 value = 0x0; + UINT32 iRet = -1; + + iRet = wmt_lib_efuse_rw(0, par2, &value, par3); + WMT_INFO_FUNC("read combo chip efuse (0x%08x) with mask (0x%08x) %s, value = 0x%08x\n", + par2, par3, iRet != 0 ? "failed" : "succeed", iRet != 0 ? -1 : value); + + return 0; +} + +INT32 wmt_dbg_efuse_write(INT32 par1, INT32 par2, INT32 par3) +{ + /* par2-->efuse address */ + /* par3-->value to set */ + UINT32 iRet = -1; + + iRet = wmt_lib_efuse_rw(1, par2, &par3, 0xffffffff); + WMT_INFO_FUNC("write combo chip efuse (0x%08x) with value (0x%08x) %s\n", + par2, par3, iRet != 0 ? "failed" : "succeed"); + + return 0; +} + +INT32 wmt_dbg_sdio_ctrl(INT32 par1, INT32 par2, INT32 par3) +{ +/*remove sdio card detect/remove control because of btif is used*/ +#if 0 + INT32 iRet = -1; + + iRet = wmt_lib_sdio_ctrl(par2 != 0 ? 1 : 0); + WMT_INFO_FUNC("ctrl SDIO function %s\n", 0 == iRet ? "succeed" : "failed"); +#endif + return 0; +} + +INT32 wmt_dbg_stp_dbg_ctrl(INT32 par1, INT32 par2, INT32 par3) +{ + if (par2 > 1) { + mtk_wcn_stp_dbg_dump_package(); + return 0; + } + + WMT_INFO_FUNC("%s stp debug function\n", par2 == 0 ? "disable" : "enable"); + + if (par2 == 0) + mtk_wcn_stp_dbg_disable(); + else if (par2 == 1) + mtk_wcn_stp_dbg_enable(); + + return 0; +} + +INT32 wmt_dbg_stp_dbg_log_ctrl(INT32 par1, INT32 par2, INT32 par3) +{ + mtk_wcn_stp_dbg_log_ctrl(par2 != 0 ? 1 : 0); + + return 0; +} + +INT32 wmt_dbg_wmt_assert_ctrl(INT32 par1, INT32 par2, INT32 par3) +{ + if (par2 > 2 || par2 < 0) + return -1; + + mtk_wcn_stp_coredump_flag_ctrl(par2); + + return 0; +} + +INT32 wmt_dbg_fwinfor_from_emi(INT32 par1, INT32 par2, INT32 par3) +{ + UINT32 offset = 0; + UINT32 len = 0; + UINT32 *pAddr = NULL; + UINT32 cur_idx_pagedtrace; + static UINT32 prev_idx_pagedtrace; + MTK_WCN_BOOL isBreak = MTK_WCN_BOOL_TRUE; + + offset = par2; + len = par3; + + if (osal_lock_sleepable_lock(&g_dbg_emi_lock)) { + WMT_ERR_FUNC("lock failed\n"); + return -1; + } + + buf_emi = kmalloc(sizeof(UINT8) * BUF_LEN_MAX, GFP_KERNEL); + if (!buf_emi) { + WMT_ERR_FUNC("buf kmalloc memory fail\n"); + return 0; + } + osal_memset(buf_emi, 0, BUF_LEN_MAX); + osal_memset(&gEmiBuf[0], 0, WMT_EMI_DEBUG_BUF_SIZE); + wmt_lib_get_fwinfor_from_emi(0, offset, &gEmiBuf[0], 0x100); + + if (offset == 1) { + do { + pAddr = (PUINT32) wmt_plat_get_emi_virt_add(0x24); + if (pAddr == NULL) { + WMT_ERR_FUNC("get virtual emi address 0x24 fail!\n"); + return -1; + } + cur_idx_pagedtrace = *pAddr; + + if (cur_idx_pagedtrace > prev_idx_pagedtrace) { + len = cur_idx_pagedtrace - prev_idx_pagedtrace; + wmt_lib_get_fwinfor_from_emi(1, prev_idx_pagedtrace, &gEmiBuf[0], len); + wmt_dbg_fwinfor_print_buff(len); + prev_idx_pagedtrace = cur_idx_pagedtrace; + } + + if (cur_idx_pagedtrace < prev_idx_pagedtrace) { + if (prev_idx_pagedtrace >= 0x8000) { + WMT_INFO_FUNC("++ prev_idx_pagedtrace invalid ...++\n\\n"); + prev_idx_pagedtrace = 0x8000 - 1; + continue; + } + + len = 0x8000 - prev_idx_pagedtrace - 1; + wmt_lib_get_fwinfor_from_emi(1, prev_idx_pagedtrace, &gEmiBuf[0], len); + WMT_INFO_FUNC("\n\n -- CONNSYS paged trace ascii output (cont...) --\n\n"); + wmt_dbg_fwinfor_print_buff(len); + + len = cur_idx_pagedtrace; + wmt_lib_get_fwinfor_from_emi(1, 0x0, &gEmiBuf[0], len); + WMT_INFO_FUNC("\n\n -- CONNSYS paged trace ascii output (end) --\n\n"); + wmt_dbg_fwinfor_print_buff(len); + prev_idx_pagedtrace = cur_idx_pagedtrace; + } + msleep(100); + } while (isBreak); + } + + WMT_INFO_FUNC("\n\n -- control word --\n\n"); + wmt_dbg_fwinfor_print_buff(256); + if (len > 1024 * 4) + len = 1024 * 4; + + WMT_WARN_FUNC("get fw infor from emi at offset(0x%x),len(0x%x)\n", offset, len); + osal_memset(&gEmiBuf[0], 0, WMT_EMI_DEBUG_BUF_SIZE); + wmt_lib_get_fwinfor_from_emi(1, offset, &gEmiBuf[0], len); + + WMT_INFO_FUNC("\n\n -- paged trace hex output --\n\n"); + wmt_dbg_fwinfor_print_buff(len); + WMT_INFO_FUNC("\n\n -- paged trace ascii output --\n\n"); + wmt_dbg_fwinfor_print_buff(len); + kfree(buf_emi); + osal_unlock_sleepable_lock(&g_dbg_emi_lock); + + return 0; +} + +INT32 wmt_dbg_stp_trigger_assert(INT32 par1, INT32 par2, INT32 par3) +{ + wmt_lib_btm_cb(BTM_TRIGGER_STP_ASSERT_OP); + + return 0; +} + +static INT32 wmt_dbg_ap_reg_read(INT32 par1, INT32 par2, INT32 par3) +{ + INT32 value = 0x0; + PUINT8 ap_reg_base = NULL; + + WMT_INFO_FUNC("AP register read, reg address:0x%x\n", par2); + ap_reg_base = ioremap_nocache(par2, 0x4); + if (ap_reg_base) { + value = readl(ap_reg_base); + WMT_INFO_FUNC("AP register read, reg address:0x%x, value:0x%x\n", par2, value); + iounmap(ap_reg_base); + } else + WMT_ERR_FUNC("AP register ioremap fail!\n"); + + return 0; +} + +static INT32 wmt_dbg_ap_reg_write(INT32 par1, INT32 par2, INT32 par3) +{ + INT32 value = 0x0; + PUINT8 ap_reg_base = NULL; + + WMT_INFO_FUNC("AP register write, reg address:0x%x, value:0x%x\n", par2, par3); + + ap_reg_base = ioremap_nocache(par2, 0x4); + if (ap_reg_base) { + writel(par3, ap_reg_base); + value = readl(ap_reg_base); + WMT_INFO_FUNC("AP register write done, value after write:0x%x\n", value); + iounmap(ap_reg_base); + } else + WMT_ERR_FUNC("AP register ioremap fail!\n"); + + return 0; +} + +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH +static INT32 wmt_dbg_set_fw_log_mode(INT32 par1, INT32 par2, INT32 par3) +{ + connsys_dedicated_log_set_log_mode(par2); + return 0; +} + +static INT32 wmt_dbg_emi_dump(INT32 par1, INT32 offset, INT32 size) +{ + connsys_dedicated_log_dump_emi(offset, size); + return 0; +} +#endif + +/********************************************************/ +/* par2: */ +/* 0: Off */ +/* others: alarm time (seconds) */ +/********************************************************/ +static INT32 wmt_dbg_suspend_debug(INT32 par1, INT32 par2, INT32 par3) +{ + if (par2 > 0) + connsys_log_alarm_enable(par2); + else + connsys_log_alarm_disable(); + return 0; +} + +static INT32 wmt_dbg_alarm_ctrl(INT32 par1, INT32 par2, INT32 par3) +{ + if (par2 > 0) + wmt_alarm_start(par2); + else + wmt_alarm_cancel(); + return 0; +} + +static INT32 wmt_dbg_set_bt_link_status(INT32 par1, INT32 par2, INT32 par3) +{ + if (par2 != 0 && par2 != 1) + return 0; + + wmt_lib_set_bt_link_status(par2, par3); + return 0; +} + +#ifdef CONFIG_TRACING +static INT32 wmt_dbg_ftrace_dbg_log_ctrl(INT32 par1, INT32 par2, INT32 par3) +{ + WMT_INFO_FUNC("%s ftrace print!!\n", par2 == 0 ? "disable" : "enable"); + + return osal_ftrace_print_ctrl(par2 == 0 ? 0 : 1); +} +#endif + +#ifdef CONFIG_MTK_COMBO_CHIP_DEEP_SLEEP_SUPPORT +static INT32 wmt_dbg_deep_sleep_ctrl(INT32 par1, INT32 par2, INT32 par3) +{ + WMT_INFO_FUNC("%s deep_sleep !!\n", par2 == 0 ? "disable" : "enable"); + return wmt_lib_deep_sleep_ctrl(par2); +} +#endif + +static INT32 wmt_dbg_sdio_retry_ctrl(INT32 par1, INT32 par2, INT32 par3) +{ + WMT_INFO_FUNC("%s sdio retry!!\n", par2 == 0 ? "disable" : "enable"); + + mtk_stp_dbg_sdio_retry_flag_ctrl(par2 == 0 ? 0 : 1); + + return 0; +} + +INT32 wmt_dbg_coex_test(INT32 par1, INT32 par2, INT32 par3) +{ + WMT_INFO_FUNC("coexistance test cmd!!\n"); + + return wmt_dbg_cmd_test_api(par2 + WMTDRV_CMD_COEXDBG_00); +} + +INT32 wmt_dbg_rst_ctrl(INT32 par1, INT32 par2, INT32 par3) +{ + WMT_INFO_FUNC("%s audo rst\n", par2 == 0 ? "disable" : "enable"); + mtk_wcn_stp_set_auto_rst(par2 == 0 ? 0 : 1); + + return 0; +} + +INT32 wmt_dbg_func0_reg_read(INT32 par1, INT32 address, INT32 value) +{ + INT32 ret = -1; + + ret = wmt_lib_sdio_reg_rw(0, 0, (UINT32)address, (UINT32)value); + if (ret) { + WMT_ERR_FUNC("read fucn0 SDIO register fail"); + return ret; + } + return ret; +} + +INT32 wmt_dbg_func0_reg_write(INT32 par1, INT32 address, INT32 value) +{ + INT32 ret = -1; + + ret = wmt_lib_sdio_reg_rw(0, 1, (UINT32)address, (UINT32)value); + if (ret) { + WMT_ERR_FUNC("write func0 SDIO register fail"); + return ret; + } + + return ret; +} + +INT32 wmt_dbg_stp_sdio_reg_read(INT32 par1, INT32 address, INT32 value) +{ + INT32 ret = -1; + + ret = wmt_lib_sdio_reg_rw(2, 0, (UINT32)address, (UINT32)value); + if (ret) { + WMT_ERR_FUNC("read SDIO register fail"); + return ret; + } + + return ret; +} + +INT32 wmt_dbg_stp_sdio_reg_write(INT32 par1, INT32 address, INT32 value) +{ + INT32 ret = -1; + + ret = wmt_lib_sdio_reg_rw(2, 1, (UINT32)address, (UINT32)value); + if (ret) { + WMT_ERR_FUNC("write SDIO register fail"); + return ret; + } + + return ret; +} + +static INT32 wmt_dbg_show_thread_debug_info(INT32 par1, INT32 address, INT32 value) +{ + + osal_dump_thread_state("btif_rxd"); + osal_dump_thread_state("mtk_wmtd"); + osal_dump_thread_state("mtk_stp_psm"); + osal_dump_thread_state("mtk_stp_btm"); + + return 0; +} + +INT32 wmt_dbg_met_ctrl(INT32 par1, INT32 met_ctrl, INT32 log_ctrl) +{ + UINT32 ret = -1; + + ret = wmt_lib_met_ctrl(met_ctrl, log_ctrl); + WMT_INFO_FUNC("met ctrl(0x%08x) met log print to %s, %s\n", + met_ctrl, + log_ctrl == 0 ? "kernel log" : "ftrace log", + ret != 0 ? "failed" : "succeed"); + + return ret; +} + +static INT32 wmt_dbg_fw_log_ctrl(INT32 par1, INT32 onoff, INT32 level) +{ + /* Parameter format + * onoff: + * - bit 24~31: unused + * - bit 16~23: subsys type + * - bit 8~15 : unused + * - bit 0~7 : on/off setting + * level: only lowest 8 bites will be used. + * - bit 8~31 : unused + * - bit 0~7 : log level setting + * Example: + * 1. To turn on MCU log + * onoff = 0x0001 + * 2. To turn on Subsys Z log + * onoff = 0x0z01 (z = subsys) + * 3. To turn off Subsys Z log + * onoff = 0x0z00 (z = subsys) + */ + UINT8 type = (unsigned char)(onoff >> 16); + + WMT_INFO_FUNC("Configuring firmware log: type:%d, on/off:%d, level:%d\n", + type, (unsigned char)onoff, (unsigned char)level); + wmt_lib_fw_log_ctrl(type, (unsigned char)onoff, (unsigned char)level); + + return 0; +} + +INT32 wmt_dbg_pre_pwr_on_ctrl(INT32 par1, INT32 enable, INT32 par3) +{ + MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE; + + WMT_INFO_FUNC("%s pre power on function\n", enable ? "enable" : "disable"); + + if (enable) { + /* Turn LPBK off and set always power on flag to 1 */ + ret = mtk_wcn_wmt_func_off(WMTDRV_TYPE_LPBK); + if (!ret) + WMT_WARN_FUNC("mtk_wcn_wmt_func_off(WMTDRV_TYPE_LPBK) return %d\n", ret); + wmt_dev_apo_ctrl(1); + } else { + /* Just set always power on flag to 0 */ + wmt_dev_apo_ctrl(0); + } + + return 0; +} + +#ifdef CONFIG_MTK_ENG_BUILD +INT32 wmt_dbg_step_test(INT32 par1, INT32 par2, INT32 par3) +{ + wmt_step_test_all(); + + return 0; +} +#endif + +INT32 wmt_dbg_thermal_query(INT32 par1, INT32 count, INT32 interval) +{ + LONG tm; + + if (count < 0) + count = 0; + if (interval < 0) + interval = 0; + + WMT_INFO_FUNC("Performing thermal query for %d times with %dms interval\n", count, interval); + while (count--) { + mtk_wcn_wmt_therm_ctrl(WMTTHERM_ENABLE); + tm = mtk_wcn_wmt_therm_ctrl(WMTTHERM_READ); + mtk_wcn_wmt_therm_ctrl(WMTTHERM_DISABLE); + + WMT_INFO_FUNC("Temperature: %ld\n", tm); + if (count > 0) + osal_sleep_ms(interval); + } + return 0; +} + +INT32 wmt_dbg_thermal_ctrl(INT32 par1, INT32 par2, INT32 par3) +{ + if (par2 == 0) { + if (par3 >= 99) { + WMT_INFO_FUNC("Can`t set temp threshold greater or queal 99\n"); + return -1; + } + wmt_dev_set_temp_threshold(par3); + } + + return 0; +} + +static INT32 wmt_dbg_step_ctrl(INT32 par1, INT32 par2, INT32 par3) +{ + if (par2 == 0) + wmt_step_print_version(); + else if (par2 == 1) { + WMT_INFO_FUNC("STEP show: Start to change config\n"); + wmt_step_deinit(); + wmt_step_init(); + WMT_INFO_FUNC("STEP show: End to change config\n"); + } + + return 0; +} + +INT32 wmt_dbg_ut_test(INT32 par1, INT32 par2, INT32 par3) +{ + INT32 i = 0; + INT32 j = 0; + INT32 iRet = 0; + + i = 20; + while ((i--) > 0) { + WMT_INFO_FUNC("#### UT WMT and STP Function On/Off .... %d\n", i); + j = 10; + while ((j--) > 0) { + WMT_INFO_FUNC("#### BT On .... (%d, %d)\n", i, j); + iRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_BT); + if (iRet == MTK_WCN_BOOL_FALSE) + break; + WMT_INFO_FUNC("#### GPS On .... (%d, %d)\n", i, j); + iRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_GPS); + if (iRet == MTK_WCN_BOOL_FALSE) + break; + WMT_INFO_FUNC("#### GPSL5 On .... (%d, %d)\n", i, j); + iRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_GPSL5); + if (iRet == MTK_WCN_BOOL_FALSE) + break; + WMT_INFO_FUNC("#### FM On .... (%d, %d)\n", i, j); + iRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_FM); + if (iRet == MTK_WCN_BOOL_FALSE) + break; + WMT_INFO_FUNC("#### WIFI On .... (%d, %d)\n", i, j); + iRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI); + if (iRet == MTK_WCN_BOOL_FALSE) + break; + WMT_INFO_FUNC("#### ANT On .... (%d, %d)\n", i, j); + iRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_ANT); + if (iRet == MTK_WCN_BOOL_FALSE) + break; + + WMT_INFO_FUNC("#### BT Off .... (%d, %d)\n", i, j); + iRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_BT); + if (iRet == MTK_WCN_BOOL_FALSE) + break; + + WMT_INFO_FUNC("#### GPS Off ....(%d, %d)\n", i, j); + iRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_GPS); + if (iRet == MTK_WCN_BOOL_FALSE) + break; + + WMT_INFO_FUNC("#### GPSL5 Off ....(%d, %d)\n", i, j); + iRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_GPSL5); + if (iRet == MTK_WCN_BOOL_FALSE) + break; + + WMT_INFO_FUNC("#### FM Off .... (%d, %d)\n", i, j); + iRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_FM); + if (iRet == MTK_WCN_BOOL_FALSE) + break; + WMT_INFO_FUNC("#### WIFI Off ....(%d, %d)\n", i, j); + iRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_WIFI); + if (iRet == MTK_WCN_BOOL_FALSE) + break; + WMT_INFO_FUNC("#### ANT Off ....(%d, %d)\n", i, j); + iRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_ANT); + if (iRet == MTK_WCN_BOOL_FALSE) + break; + } + + if (iRet == MTK_WCN_BOOL_FALSE) + break; + } + if (iRet == MTK_WCN_BOOL_FALSE) + WMT_INFO_FUNC("#### UT FAIL!!\n"); + else + WMT_INFO_FUNC("#### UT PASS!!\n"); + + return iRet; +} + +#if CFG_CORE_INTERNAL_TXRX +struct lpbk_package { + UINT32 payload_length; + UINT8 out_payload[2048]; + UINT8 in_payload[2048]; +}; + +static INT32 wmt_internal_loopback(INT32 count, INT32 max) +{ + INT32 ret = 0; + INT32 loop; + INT32 offset; + struct lpbk_package lpbk_buffer; + P_OSAL_OP pOp; + P_OSAL_SIGNAL pSignal = NULL; + + for (loop = 0; loop < count; loop++) { + /* <1> init buffer */ + osal_memset((PVOID)&lpbk_buffer, 0, sizeof(struct lpbk_package)); + lpbk_buffer.payload_length = max; + for (offset = 0; offset < max; offset++) + lpbk_buffer.out_payload[offset] = (offset + 1) & 0xFF;/*for test use: begin from 1 */ + + memcpy(&gLpbkBuf[0], &lpbk_buffer.out_payload[0], max); + + pOp = wmt_lib_get_free_op(); + if (!pOp) { + WMT_WARN_FUNC("get_free_lxop fail\n"); + ret = -1; + break; + } + pSignal = &pOp->signal; + pOp->op.opId = WMT_OPID_LPBK; + pOp->op.au4OpData[0] = lpbk_buffer.payload_length; /* packet length */ + pOp->op.au4OpData[1] = (UINT32) &gLpbkBuf[0]; + pSignal->timeoutValue = MAX_EACH_WMT_CMD; + WMT_INFO_FUNC("OPID(%d) type(%zu) start\n", pOp->op.opId, pOp->op.au4OpData[0]); + if (DISABLE_PSM_MONITOR()) { + WMT_ERR_FUNC("wake up failed,OPID(%d) type(%zu) abort\n", pOp->op.opId, + pOp->op.au4OpData[0]); + wmt_lib_put_op_to_free_queue(pOp); + ret = -2; + } + + ret = wmt_lib_put_act_op(pOp); + ENABLE_PSM_MONITOR(); + if (ret == MTK_WCN_BOOL_FALSE) { + WMT_WARN_FUNC("OPID(%d) type(%zu)fail\n", + pOp->op.opId, pOp->op.au4OpData[0]); + ret = -3; + break; + } + WMT_INFO_FUNC("OPID(%d) length(%zu) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); + + memcpy(&lpbk_buffer.in_payload[0], &gLpbkBuf[0], max); + + ret = pOp->op.au4OpData[0]; + /*<3> compare result */ + if (memcmp(lpbk_buffer.in_payload, lpbk_buffer.out_payload, lpbk_buffer.payload_length)) { + WMT_INFO_FUNC("[%s] WMT_TEST_LPBK_CMD payload compare error\n", __func__); + ret = -4; + break; + } + WMT_ERR_FUNC("[%s] exec WMT_TEST_LPBK_CMD succeed(loop = %d, size = %ld)\n", __func__, loop, + lpbk_buffer.payload_length); + } + + if (loop != count) + WMT_ERR_FUNC("fail at loop(%d) buf_length(%d)\n", loop, max); + + return ret; +} + +INT32 wmt_dbg_internal_lpbk_test(INT32 par1, INT32 par2, INT32 par3) +{ + UINT32 count; + UINT32 length; + + count = par1; + length = par2; + + WMT_INFO_FUNC("count[%d],length[%d]\n", count, length); + + wmt_core_lpbk_do_stp_init(); + + wmt_internal_loopback(count, length); + + wmt_core_lpbk_do_stp_deinit(); + return 0; +} +#endif /* CFG_CORE_INTERNAL_TXRX */ + +static INT32 wmt_dbg_set_mcu_clock(INT32 par1, INT32 par2, INT32 par3) +{ + INT32 ret = 0; + P_OSAL_OP pOp; + P_OSAL_SIGNAL pSignal = NULL; + UINT32 kind = 0; + UINT32 version = 0; + + version = par2; + kind = par3; + pOp = wmt_lib_get_free_op(); + if (!pOp) { + WMT_WARN_FUNC("get_free_lxop fail\n"); + return -1; + } + pSignal = &pOp->signal; + pOp->op.opId = WMT_OPID_SET_MCU_CLK; + pOp->op.au4OpData[0] = kind; + pOp->op.au4OpData[1] = version; + pSignal->timeoutValue = MAX_EACH_WMT_CMD; + + WMT_INFO_FUNC("OPID(%d) kind(%zu) start\n", pOp->op.opId, pOp->op.au4OpData[0]); + if (DISABLE_PSM_MONITOR()) { + WMT_ERR_FUNC("wake up failed,OPID(%d) kind(%zu) abort\n", + pOp->op.opId, pOp->op.au4OpData[0]); + wmt_lib_put_op_to_free_queue(pOp); + return -2; + } + + ret = wmt_lib_put_act_op(pOp); + ENABLE_PSM_MONITOR(); + if (ret == MTK_WCN_BOOL_FALSE) { + WMT_WARN_FUNC("OPID(%d) kind(%zu)fail(%d)\n", + pOp->op.opId, pOp->op.au4OpData[0], ret); + return -3; + } + WMT_INFO_FUNC("OPID(%d) kind(%zu) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); + + return ret; +} + +static INT32 wmt_dbg_poll_cpupcr(INT32 par1, INT32 par2, INT32 par3) +{ + UINT32 count = 0; + UINT16 sleep = 0; + UINT16 toAee = 0; + + count = par2; + sleep = (par3 & 0xF0) >> 4; + toAee = (par3 & 0x0F); + + WMT_INFO_FUNC("polling count[%d],polling sleep[%d],toaee[%d]\n", count, sleep, toAee); + stp_dbg_poll_cpupcr(count, sleep, toAee); + + return 0; +} + +#if CONSYS_ENALBE_SET_JTAG +static INT32 wmt_dbg_jtag_flag_ctrl(INT32 par1, INT32 par2, INT32 par3) +{ + UINT32 en_flag = par2; + + switch (en_flag) { + case 1: + case 2: + /* gen2 consys does not support 2-wire jtag*/ + wmt_lib_jtag_flag_set(en_flag); + WMT_INFO_FUNC("enable %s mcu jtag pinmux setting\n", en_flag == 1 ? "7-wire" : "2-wire"); + break; + default: + WMT_INFO_FUNC("enable mcu jtag does not support %d options\n", en_flag); + } + + return 0; +} +#endif + +#if CFG_WMT_LTE_COEX_HANDLING +static INT32 wmt_dbg_lte_to_wmt_test(UINT32 opcode, UINT32 msg_len) +{ + conn_md_ipc_ilm_t ilm; + struct local_para *p_buf_str = NULL; + INT32 i = 0; + INT32 iRet = -1; + + WMT_INFO_FUNC("opcode(0x%02x),msg_len(%d)\n", opcode, msg_len); + p_buf_str = osal_malloc(osal_sizeof(struct local_para) + msg_len); + if (p_buf_str == NULL) { + WMT_ERR_FUNC("kmalloc for local para ptr structure failed.\n"); + return -1; + } + p_buf_str->msg_len = msg_len; + for (i = 0; i < msg_len; i++) + p_buf_str->data[i] = i; + + ilm.local_para_ptr = p_buf_str; + ilm.msg_id = opcode; + + iRet = wmt_lib_handle_idc_msg(&ilm); + osal_free(p_buf_str); + return iRet; + +} + +static INT32 wmt_dbg_lte_coex_test(INT32 par1, INT32 par2, INT32 par3) +{ + PUINT8 local_buffer = NULL; + UINT32 handle_len; + INT32 iRet = -1; + + static UINT8 wmt_to_lte_test_evt1[] = { 0x02, 0x16, 0x0d, 0x00, + 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, + 0xa, 0xb + }; + static UINT8 wmt_to_lte_test_evt2[] = { 0x02, 0x16, 0x09, 0x00, + 0x01, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }; + static UINT8 wmt_to_lte_test_evt3[] = { 0x02, 0x16, 0x02, 0x00, + 0x02, 0xff + }; + static UINT8 wmt_to_lte_test_evt4[] = { 0x02, 0x16, 0x0d, 0x00, + 0x03, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, + 0xa, 0xb + }; + + local_buffer = kmalloc(512, GFP_KERNEL); + if (!local_buffer) { + WMT_ERR_FUNC("local_buffer kmalloc memory fail\n"); + return 0; + } + + if (par2 == 1) { + handle_len = wmt_idc_msg_to_lte_handing_for_test(&wmt_to_lte_test_evt1[0], + osal_sizeof(wmt_to_lte_test_evt1)); + if (handle_len != osal_sizeof(wmt_to_lte_test_evt1)) { + WMT_ERR_FUNC("par2=1,wmt send to lte msg fail:handle_len(%d),buff_len(%zu)\n", + handle_len, osal_sizeof(wmt_to_lte_test_evt1)); + } else + WMT_INFO_FUNC("par2=1,wmt send to lte msg OK! send_len(%d)\n", handle_len); + } + if (par2 == 2) { + osal_memcpy(&local_buffer[0], &wmt_to_lte_test_evt1[0], osal_sizeof(wmt_to_lte_test_evt1)); + osal_memcpy(&local_buffer[osal_sizeof(wmt_to_lte_test_evt1)], &wmt_to_lte_test_evt2[0], + osal_sizeof(wmt_to_lte_test_evt2)); + + handle_len = wmt_idc_msg_to_lte_handing_for_test(&local_buffer[0], + osal_sizeof(wmt_to_lte_test_evt1) + osal_sizeof(wmt_to_lte_test_evt2)); + if (handle_len != osal_sizeof(wmt_to_lte_test_evt1) + osal_sizeof(wmt_to_lte_test_evt2)) { + WMT_ERR_FUNC("par2=2,wmt send to lte msg fail:handle_len(%d),buff_len(%zu)\n", + handle_len, + osal_sizeof(wmt_to_lte_test_evt1) + + osal_sizeof(wmt_to_lte_test_evt2)); + } else + WMT_INFO_FUNC("par2=1,wmt send to lte msg OK! send_len(%d)\n", handle_len); + } + if (par2 == 3) { + osal_memcpy(&local_buffer[0], &wmt_to_lte_test_evt1[0], osal_sizeof(wmt_to_lte_test_evt1)); + osal_memcpy(&local_buffer[osal_sizeof(wmt_to_lte_test_evt1)], &wmt_to_lte_test_evt2[0], + osal_sizeof(wmt_to_lte_test_evt2)); + osal_memcpy(&local_buffer[osal_sizeof(wmt_to_lte_test_evt1) + + osal_sizeof(wmt_to_lte_test_evt2)], + &wmt_to_lte_test_evt3[0], osal_sizeof(wmt_to_lte_test_evt3)); + + handle_len = wmt_idc_msg_to_lte_handing_for_test(&local_buffer[0], + osal_sizeof(wmt_to_lte_test_evt1) + + osal_sizeof(wmt_to_lte_test_evt2) + + osal_sizeof(wmt_to_lte_test_evt3)); + if (handle_len != osal_sizeof(wmt_to_lte_test_evt1) + + osal_sizeof(wmt_to_lte_test_evt2) + + osal_sizeof(wmt_to_lte_test_evt3)) { + WMT_ERR_FUNC("par2=3,wmt send to lte msg fail:handle_len(%d),buff_len(%zu)\n", + handle_len, + osal_sizeof(wmt_to_lte_test_evt1) + + osal_sizeof(wmt_to_lte_test_evt2) + + osal_sizeof(wmt_to_lte_test_evt3)); + } else + WMT_INFO_FUNC("par3=1,wmt send to lte msg OK! send_len(%d)\n", handle_len); + } + if (par2 == 4) { + handle_len = wmt_idc_msg_to_lte_handing_for_test(&wmt_to_lte_test_evt4[0], + osal_sizeof(wmt_to_lte_test_evt4)); + if (handle_len != osal_sizeof(wmt_to_lte_test_evt4)) { + WMT_ERR_FUNC("par2=1,wmt send to lte msg fail:handle_len(%d),buff_len(%zu)\n", + handle_len, osal_sizeof(wmt_to_lte_test_evt4)); + } else + WMT_INFO_FUNC("par2=1,wmt send to lte msg OK! send_len(%d)\n", handle_len); + } + if (par2 == 5) { + if (par3 >= 1024) + par3 = 1024; + iRet = wmt_dbg_lte_to_wmt_test(IPC_MSG_ID_EL1_LTE_DEFAULT_PARAM_IND, par3); + WMT_INFO_FUNC("IPC_MSG_ID_EL1_LTE_DEFAULT_PARAM_IND test result(%d)\n", iRet); + } + if (par2 == 6) { + if (par3 >= 1024) + par3 = 1024; + iRet = wmt_dbg_lte_to_wmt_test(IPC_MSG_ID_EL1_LTE_OPER_FREQ_PARAM_IND, par3); + WMT_INFO_FUNC("IPC_MSG_ID_EL1_LTE_OPER_FREQ_PARAM_IND test result(%d)\n", iRet); + } + if (par2 == 7) { + if (par3 >= 1024) + par3 = 1024; + iRet = wmt_dbg_lte_to_wmt_test(IPC_MSG_ID_EL1_WIFI_MAX_PWR_IND, par3); + WMT_INFO_FUNC("IPC_MSG_ID_EL1_WIFI_MAX_PWR_IND test result(%d)\n", iRet); + } + if (par2 == 8) { + if (par3 >= 1024) + par3 = 1024; + iRet = wmt_dbg_lte_to_wmt_test(IPC_MSG_ID_EL1_LTE_TX_IND, par3); + WMT_INFO_FUNC("IPC_MSG_ID_EL1_LTE_TX_IND test result(%d)\n", iRet); + } + if (par2 == 9) { + if (par3 > 0) + wmt_core_set_flag_for_test(1); + else + wmt_core_set_flag_for_test(0); + } + + kfree(local_buffer); + + return 0; +} +#endif /* CFG_WMT_LTE_COEX_HANDLING */ + +ssize_t wmt_dbg_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) +{ + INT32 retval = 0; + INT32 i_ret = 0; + PINT8 warn_msg = "no data available, please run echo 15 xx > /proc/driver/wmt_psm first\n"; + + if (*f_pos > 0) + retval = 0; + else { + /*len = sprintf(page, "%d\n", g_psm_enable); */ + if (gCoexBuf.availSize <= 0) { + WMT_INFO_FUNC + ("no data available, please run echo 15 xx > /proc/driver/wmt_psm first\n"); + retval = osal_strlen(warn_msg) + 1; + if (count < retval) + retval = count; + i_ret = copy_to_user(buf, warn_msg, retval); + if (i_ret) { + WMT_ERR_FUNC("copy to buffer failed, ret:%d\n", retval); + retval = -EFAULT; + goto err_exit; + } + *f_pos += retval; + } else { + INT32 i = 0; + INT32 len = 0; + INT8 msg_info[512]; + INT32 max_num = 0; + + /*we do not check page buffer, because there are only 100 bytes in g_coex_buf, */ + /* no reason page buffer is not enough, */ + /* a bomb is placed here on unexpected condition */ + WMT_INFO_FUNC("%d bytes available\n", gCoexBuf.availSize); + max_num = + ((osal_sizeof(msg_info) > + count ? osal_sizeof(msg_info) : count) - 1) / 5; + + if (max_num > gCoexBuf.availSize) { + max_num = gCoexBuf.availSize; + } else { + WMT_INFO_FUNC + ("round to %d bytes due to local buffer size limitation\n", + max_num); + } + + for (i = 0; i < max_num; i++) + len += osal_sprintf(msg_info + len, "0x%02x ", gCoexBuf.buffer[i]); + + len += osal_sprintf(msg_info + len, "\n"); + retval = len; + + i_ret = copy_to_user(buf, msg_info, retval); + if (i_ret) { + WMT_ERR_FUNC("copy to buffer failed, ret:%d\n", retval); + retval = -EFAULT; + goto err_exit; + } + *f_pos += retval; + } + } + gCoexBuf.availSize = 0; + +err_exit: + return retval; +} + +static VOID delay_work_func(struct work_struct *work) +{ + struct wmt_dbg_work *dbgWork = container_of(work, struct wmt_dbg_work, work); + + if (!dbgWork) { + WMT_ERR_FUNC("fail to get dbgWork"); + return; + } + + if ((dbgWork->x >= 0) && (dbgWork->x < 0x33)) + (*wmt_dev_dbg_func[dbgWork->x]) (dbgWork->x, dbgWork->y, dbgWork->z); + + kvfree(dbgWork); +} + +static VOID wmt_dbg_delay_work(INT32 x, INT32 y, INT32 z) +{ + struct wmt_dbg_work *dbgWork; + + dbgWork = kmalloc(sizeof(struct wmt_dbg_work), GFP_KERNEL); + if (!dbgWork) { + WMT_ERR_FUNC("fail to allocate memory"); + return; + } + + dbgWork->x = x; + dbgWork->y = y; + dbgWork->z = z; + + INIT_WORK(&dbgWork->work, delay_work_func); + schedule_work(&dbgWork->work); +} + +ssize_t wmt_dbg_write(struct file *filp, const char __user *buffer, size_t count, loff_t *f_pos) +{ + ULONG len = count; + INT8 buf[256]; + PINT8 pBuf; + INT32 x = 0, y = 0, z = 0; + PINT8 pToken = NULL; + PINT8 pDelimiter = " \t"; + LONG res = 0; + static INT8 dbgEnabled; + + WMT_INFO_FUNC("write parameter len = %d\n\r", (INT32) len); + if (len >= osal_sizeof(buf)) { + WMT_ERR_FUNC("input handling fail!\n"); + len = osal_sizeof(buf) - 1; + return -1; + } + + if (copy_from_user(buf, buffer, len)) + return -EFAULT; + + buf[len] = '\0'; + WMT_INFO_FUNC("write parameter data = %s\n\r", buf); + + pBuf = buf; + pToken = osal_strsep(&pBuf, pDelimiter); + if (pToken != NULL) { + osal_strtol(pToken, 16, &res); + x = (INT32)res; + } else { + x = 0; + } + + pToken = osal_strsep(&pBuf, "\t\n "); + if (pToken != NULL) { + osal_strtol(pToken, 16, &res); + y = (INT32)res; + WMT_INFO_FUNC("y = 0x%08x\n\r", y); + } else { + y = 3000; + /*efuse, register read write default value */ + if (0x11 == x || 0x12 == x || 0x13 == x) + y = 0x80000000; + } + + pToken = osal_strsep(&pBuf, "\t\n "); + if (pToken != NULL) { + if (0x2f == x) + z = osal_strcmp(pToken, "true") ? 0 : 1; + else { + osal_strtol(pToken, 16, &res); + z = (INT32)res; + } + } else { + z = 10; + /*efuse, register read write default value */ + if (0x11 == x || 0x12 == x || 0x13 == x) + z = 0xffffffff; + } + + WMT_INFO_FUNC("x(0x%08x), y(0x%08x), z(0x%08x)\n\r", x, y, z); + + /* For eng and userdebug load, have to enable wmt_dbg by writing 0xDB9DB9 to + * "/proc/driver/wmt_dbg" to avoid some malicious use + */ +#if (WMT_DBG_SUPPORT) + if (0xDB9DB9 == x) { + dbgEnabled = 1; + return len; + } +#endif + /* Commands allowed to execute in user load + * 0x15: assert control + * 0x2e: enable catch connsys log + * 0x2f: set bt link status + * 0x32: alarm dump control + */ + if (0 == dbgEnabled && 0x15 != x && 0x2e != x && 0x2f != x && + 0x7 != x && x != 0x32) { + WMT_INFO_FUNC("please enable WMT debug first\n\r"); + return len; + } + + if (osal_array_size(wmt_dev_dbg_func) > x && NULL != wmt_dev_dbg_func[x]) + if (x == 0x7) + wmt_dbg_delay_work(x, y, z); + else + (*wmt_dev_dbg_func[x]) (x, y, z); + else + WMT_WARN_FUNC("no handler defined for command id(0x%08x)\n\r", x); + + return len; +} + +INT32 wmt_dev_dbg_setup(VOID) +{ + static const struct file_operations wmt_dbg_fops = { + .owner = THIS_MODULE, + .read = wmt_dbg_read, + .write = wmt_dbg_write, + }; + INT32 i_ret = 0; + + gWmtDbgEntry = proc_create(WMT_DBG_PROCNAME, 0664, NULL, &wmt_dbg_fops); + if (gWmtDbgEntry == NULL) { + WMT_ERR_FUNC("Unable to create / wmt_aee proc entry\n\r"); + i_ret = -1; + } + osal_sleepable_lock_init(&g_dbg_emi_lock); + + return i_ret; +} + +INT32 wmt_dev_dbg_remove(VOID) +{ + if (gWmtDbgEntry != NULL) + proc_remove(gWmtDbgEntry); + + osal_sleepable_lock_deinit(&g_dbg_emi_lock); + +#if CFG_WMT_PS_SUPPORT + wmt_lib_ps_deinit(); +#endif + return 0; +} + +INT32 wmt_dbg_gps_suspend(INT32 par1, INT32 par2, INT32 par3) +{ + MTK_WCN_BOOL suspend = (par2 != 0) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE; + + WMT_INFO_FUNC("GPS %s mode test, type(%d, %s)\n", + (par2 != 0) ? "suspend" : "resume", + par3, (par3 == 0) ? "L1+L5" : ((par3 == 1) ? "L1" : "L5")); + + if (par3 == 0) + mtk_wmt_gps_suspend_ctrl(suspend); + else if (par3 == 1) + mtk_wmt_gps_l1_suspend_ctrl(suspend); + else + mtk_wmt_gps_l5_suspend_ctrl(suspend); + + return 0; +} diff --git a/drivers/misc/mediatek/connectivity/common/common_main/linux/wmt_dev.c b/drivers/misc/mediatek/connectivity/common/common_main/linux/wmt_dev.c new file mode 100644 index 0000000000000000000000000000000000000000..8759d79a5638e49a6418602e7d6fbd25996889c5 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/linux/wmt_dev.c @@ -0,0 +1,1786 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +/*! \file + * \brief brief description + * + * Detailed descriptions here. + * + */ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +#ifdef DFT_TAG +#undef DFT_TAG +#endif +#define DFT_TAG "[WMT-DEV]" + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +#ifdef CONFIG_COMPAT +#include +#endif +#include +#if WMT_CREATE_NODE_DYNAMIC +#include +#endif +#ifdef CONFIG_EARLYSUSPEND +#include +#else +#include +#endif +#include +#include +#include "osal_typedef.h" +#include "osal.h" +#include "wmt_dev.h" +#include "wmt_core.h" +#include "wmt_exp.h" +#include "wmt_lib.h" +#include "wmt_conf.h" +#include "wmt_dbg.h" +#include "wmt_user_proc.h" +#include "psm_core.h" +#include "stp_core.h" +#include "stp_exp.h" +#include "bgw_desense.h" +#include "wmt_idc.h" +#include "wmt_detect.h" +#include "hif_sdio.h" +#include "wmt_step.h" +#include "wmt_proc_dbg.h" +#include "wmt_alarm.h" + +#include "connsys_debug_utility.h" + +#ifdef CONFIG_COMPAT +#define COMPAT_WMT_IOCTL_SET_PATCH_NAME _IOW(WMT_IOC_MAGIC, 4, compat_uptr_t) +#define COMPAT_WMT_IOCTL_LPBK_TEST _IOWR(WMT_IOC_MAGIC, 8, compat_uptr_t) +#define COMPAT_WMT_IOCTL_SET_PATCH_INFO _IOW(WMT_IOC_MAGIC, 15, compat_uptr_t) +#define COMPAT_WMT_IOCTL_PORT_NAME _IOWR(WMT_IOC_MAGIC, 20, compat_uptr_t) +#define COMPAT_WMT_IOCTL_WMT_CFG_NAME _IOWR(WMT_IOC_MAGIC, 21, compat_uptr_t) +#define COMPAT_WMT_IOCTL_SEND_BGW_DS_CMD _IOW(WMT_IOC_MAGIC, 25, compat_uptr_t) +#define COMPAT_WMT_IOCTL_ADIE_LPBK_TEST _IOWR(WMT_IOC_MAGIC, 26, compat_uptr_t) +#define COMPAT_WMT_IOCTL_DYNAMIC_DUMP_CTRL _IOR(WMT_IOC_MAGIC, 30, compat_uptr_t) +#define COMPAT_WMT_IOCTL_SET_ROM_PATCH_INFO _IOW(WMT_IOC_MAGIC, 31, compat_uptr_t) +#define COMPAT_WMT_IOCTL_GET_VENDOR_PATCH_VERSION _IOR(WMT_IOC_MAGIC, 36, compat_uptr_t) +#define COMPAT_WMT_IOCTL_SET_VENDOR_PATCH_VERSION _IOW(WMT_IOC_MAGIC, 37, compat_uptr_t) +#define COMPAT_WMT_IOCTL_SET_ACTIVE_PATCH_VERSION _IOR(WMT_IOC_MAGIC, 40, compat_uptr_t) +#define COMPAT_WMT_IOCTL_GET_ACTIVE_PATCH_VERSION _IOR(WMT_IOC_MAGIC, 41, compat_uptr_t) +#endif + +#define WMT_IOC_MAGIC 0xa0 +#define WMT_IOCTL_SET_PATCH_NAME _IOW(WMT_IOC_MAGIC, 4, char*) +#define WMT_IOCTL_SET_STP_MODE _IOW(WMT_IOC_MAGIC, 5, int) +#define WMT_IOCTL_FUNC_ONOFF_CTRL _IOW(WMT_IOC_MAGIC, 6, int) +#define WMT_IOCTL_LPBK_POWER_CTRL _IOW(WMT_IOC_MAGIC, 7, int) +#define WMT_IOCTL_LPBK_TEST _IOWR(WMT_IOC_MAGIC, 8, char*) +#define WMT_IOCTL_GET_CHIP_INFO _IOR(WMT_IOC_MAGIC, 12, int) +#define WMT_IOCTL_SET_LAUNCHER_KILL _IOW(WMT_IOC_MAGIC, 13, int) +#define WMT_IOCTL_SET_PATCH_NUM _IOW(WMT_IOC_MAGIC, 14, int) +#define WMT_IOCTL_SET_PATCH_INFO _IOW(WMT_IOC_MAGIC, 15, char*) +#define WMT_IOCTL_PORT_NAME _IOWR(WMT_IOC_MAGIC, 20, char*) +#define WMT_IOCTL_WMT_CFG_NAME _IOWR(WMT_IOC_MAGIC, 21, char*) +#define WMT_IOCTL_WMT_QUERY_CHIPID _IOR(WMT_IOC_MAGIC, 22, int) +#define WMT_IOCTL_WMT_TELL_CHIPID _IOW(WMT_IOC_MAGIC, 23, int) +#define WMT_IOCTL_WMT_COREDUMP_CTRL _IOW(WMT_IOC_MAGIC, 24, int) +#define WMT_IOCTL_SEND_BGW_DS_CMD _IOW(WMT_IOC_MAGIC, 25, char*) +#define WMT_IOCTL_ADIE_LPBK_TEST _IOWR(WMT_IOC_MAGIC, 26, char*) +#define WMT_IOCTL_WMT_STP_ASSERT_CTRL _IOW(WMT_IOC_MAGIC, 27, int) +#define WMT_IOCTL_FW_DBGLOG_CTRL _IOR(WMT_IOC_MAGIC, 29, int) +#define WMT_IOCTL_DYNAMIC_DUMP_CTRL _IOR(WMT_IOC_MAGIC, 30, char*) +#define WMT_IOCTL_SET_ROM_PATCH_INFO _IOW(WMT_IOC_MAGIC, 31, char*) +#define WMT_IOCTL_GET_EMI_PHY_SIZE _IOR(WMT_IOC_MAGIC, 33, unsigned int) +#define WMT_IOCTL_FW_PATCH_UPDATE_RST _IOR(WMT_IOC_MAGIC, 34, int) +#define WMT_IOCTL_GET_VENDOR_PATCH_NUM _IOW(WMT_IOC_MAGIC, 35, int) +#define WMT_IOCTL_GET_VENDOR_PATCH_VERSION _IOR(WMT_IOC_MAGIC, 36, char*) +#define WMT_IOCTL_SET_VENDOR_PATCH_VERSION _IOW(WMT_IOC_MAGIC, 37, char*) +#define WMT_IOCTL_GET_CHECK_PATCH_STATUS _IOR(WMT_IOC_MAGIC, 38, int) +#define WMT_IOCTL_SET_CHECK_PATCH_STATUS _IOW(WMT_IOC_MAGIC, 39, int) +#define WMT_IOCTL_SET_ACTIVE_PATCH_VERSION _IOR(WMT_IOC_MAGIC, 40, char*) +#define WMT_IOCTL_GET_ACTIVE_PATCH_VERSION _IOR(WMT_IOC_MAGIC, 41, char*) +#define WMT_IOCTL_GET_DIRECT_PATH_EMI_SIZE _IOR(WMT_IOC_MAGIC, 42, unsigned int) + +#define MTK_WMT_VERSION "Consys WMT Driver - v1.0" +#define MTK_WMT_DATE "2013/01/20" +#define WMT_DEV_MAJOR 190 /* never used number */ +#define WMT_DEV_NUM 1 +#define WMT_DEV_INIT_TO_MS (2 * 1000) +#define DYNAMIC_DUMP_BUF 109 + +#define WMT_DRIVER_NAME "mtk_stp_wmt" + +P_OSAL_EVENT gpRxEvent; + +UINT32 u4RxFlag; +static atomic_t gRxCount = ATOMIC_INIT(0); + +/* Linux UINT8 device */ +static INT32 gWmtMajor = WMT_DEV_MAJOR; +static struct cdev gWmtCdev; +static atomic_t gWmtRefCnt = ATOMIC_INIT(0); +/* WMT driver information */ +static UINT8 gLpbkBuf[WMT_LPBK_BUF_LEN] = { 0 }; + +static UINT32 gLpbkBufLog; /* George LPBK debug */ + +enum wmt_init_status { + WMT_INIT_NOT_START, + WMT_INIT_START, + WMT_INIT_DONE, +}; +static INT32 gWmtInitStatus = WMT_INIT_NOT_START; +static wait_queue_head_t gWmtInitWq; +#ifdef CONFIG_MTK_COMBO_COMM_APO +UINT32 always_pwr_on_flag = 1; +#else +UINT32 always_pwr_on_flag; +#endif +P_WMT_PATCH_INFO pPatchInfo; +UINT32 pAtchNum; +UINT32 currentLpbkStatus; +#define TEMP_THRESHOLD 60 +static INT32 gTemperatureThreshold = TEMP_THRESHOLD; + +#if WMT_CREATE_NODE_DYNAMIC +struct class *wmt_class; +struct device *wmt_dev; +#endif + + +/*LCM on/off ctrl for wmt varabile*/ +UINT32 hif_info; +UINT8 gWmtClose; +static struct work_struct gPwrOnOffWork; +static atomic_t g_es_lr_flag_for_quick_sleep = ATOMIC_INIT(1); /* for ctrl quick sleep flag */ +static atomic_t g_es_lr_flag_for_lpbk_onoff = ATOMIC_INIT(0); /* for ctrl lpbk on off */ + +/*BLANK on/off ctrl for wmt varabile*/ +static atomic_t g_es_lr_flag_for_blank = ATOMIC_INIT(0); /* for ctrl blank flag */ +static atomic_t g_late_pwr_on_for_blank = ATOMIC_INIT(0); /* PwrOnOff Late flag */ + +/* Prevent race condition when wmt_dev_tm_temp_query is called concurrently */ +static OSAL_UNSLEEPABLE_LOCK g_temp_query_spinlock; + +#ifdef CONFIG_EARLYSUSPEND +static VOID wmt_dev_early_suspend(struct early_suspend *h) +{ + atomic_set(&g_es_lr_flag_for_quick_sleep, 1); + atomic_set(&g_es_lr_flag_for_lpbk_onoff, 0); + atomic_set(&g_es_lr_flag_for_blank, 0); + + WMT_WARN_FUNC("@@@@@@@@@@wmt enter early suspend@@@@@@@@@@@@@@\n"); + + schedule_work(&gPwrOnOffWork); +} + +static VOID wmt_dev_late_resume(struct early_suspend *h) +{ + atomic_set(&g_es_lr_flag_for_quick_sleep, 0); + atomic_set(&g_es_lr_flag_for_lpbk_onoff, 1); + atomic_set(&g_es_lr_flag_for_blank, 1); + + WMT_WARN_FUNC("@@@@@@@@@@wmt enter late resume@@@@@@@@@@@@@@\n"); + + schedule_work(&gPwrOnOffWork); + +} + +struct early_suspend wmt_early_suspend_handler = { + .suspend = wmt_dev_early_suspend, + .resume = wmt_dev_late_resume, +}; + +#else + +static struct notifier_block wmt_fb_notifier; +static INT32 wmt_fb_notifier_callback(struct notifier_block *self, ULONG event, PVOID data) +{ + struct fb_event *evdata = data; + INT32 blank; + + WMT_DBG_FUNC("wmt_fb_notifier_callback\n"); + + /* If we aren't interested in this event, skip it immediately ... */ + if (event != FB_EVENT_BLANK) + return 0; + + blank = *(INT32 *)evdata->data; + WMT_DBG_FUNC("fb_notify(blank=%d)\n", blank); + + switch (blank) { + case FB_BLANK_UNBLANK: + atomic_set(&g_es_lr_flag_for_quick_sleep, 0); + atomic_set(&g_es_lr_flag_for_lpbk_onoff, 1); + atomic_set(&g_es_lr_flag_for_blank, 1); + WMT_WARN_FUNC("@@@@@@@@@@wmt enter UNBLANK @@@@@@@@@@@@@@\n"); + if (hif_info == 0) { + atomic_set(&g_late_pwr_on_for_blank, 1); + break; + } + schedule_work(&gPwrOnOffWork); + break; + case FB_BLANK_POWERDOWN: + atomic_set(&g_es_lr_flag_for_quick_sleep, 1); + atomic_set(&g_es_lr_flag_for_lpbk_onoff, 0); + atomic_set(&g_es_lr_flag_for_blank, 0); + WMT_WARN_FUNC("@@@@@@@@@@wmt enter early POWERDOWN @@@@@@@@@@@@@@\n"); + schedule_work(&gPwrOnOffWork); + break; + default: + break; + } + return 0; +} +#endif /* CONFIG_EARLYSUSPEND */ +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +INT32 wmt_dev_apo_ctrl(UINT32 enable) +{ + always_pwr_on_flag = enable ? 1 : 0; + if (!always_pwr_on_flag) + schedule_work(&gPwrOnOffWork); + WMT_INFO_FUNC("always_pwr_on_flag: %d\n", always_pwr_on_flag); + + return 0; +} + +static VOID wmt_pwr_on_off_handler(struct work_struct *work) +{ + INT32 retry = 5; + INT32 desync = 0; + + WMT_DBG_FUNC("wmt_pwr_on_off_handler start to run\n"); + + /* Update blank off status before wmt power off */ + if (wmt_dev_get_blank_state() == 0) { + wmt_dev_blank_handler(); + connsys_log_blank_state_changed(0); + } + + if (always_pwr_on_flag == 0) { + while ((wmt_lib_get_drv_status(WMTDRV_TYPE_LPBK) == DRV_STS_FUNC_ON) != + atomic_read(&g_es_lr_flag_for_lpbk_onoff)) { + if (++desync > 1) + WMT_WARN_FUNC("suspend/resume not sync count:%d\n", desync); + if (wmt_lpbk_handler(atomic_read(&g_es_lr_flag_for_lpbk_onoff), retry) < 0) + break; + } + } + + /* Update blank on status after wmt power on */ + if (wmt_dev_get_blank_state() == 1) { + wmt_dev_blank_handler(); + connsys_log_blank_state_changed(1); + } +} + +INT32 wmt_lpbk_handler(UINT32 on_off_flag, UINT32 retry) +{ + UINT32 retry_count; + + retry_count = retry; + do { + if (on_off_flag) { + if (mtk_wcn_wmt_func_on(WMTDRV_TYPE_LPBK) == MTK_WCN_BOOL_FALSE) { + WMT_WARN_FUNC("WMT turn on LPBK fail, retrying, retryCounter left:%d!\n", + retry_count); + retry_count--; + osal_sleep_ms(1000); + } else { + WMT_DBG_FUNC("WMT turn on LPBK suceed\n"); + break; + } + } else { + if (mtk_wcn_wmt_func_off(WMTDRV_TYPE_LPBK) == MTK_WCN_BOOL_FALSE) { + WMT_WARN_FUNC("WMT turn off LPBK fail, retrying, retryCounter left:%d!\n", + retry_count); + retry_count--; + osal_sleep_ms(1000); + } else { + WMT_DBG_FUNC("WMT turn off LPBK suceed\n"); + break; + } + } + } while (retry_count > 0); + return ((wmt_lib_get_drv_status(WMTDRV_TYPE_LPBK) == DRV_STS_FUNC_ON) == on_off_flag) - 1; +} + +VOID wmt_dev_blank_handler(VOID) +{ + WMT_DBG_FUNC("wmt_dev_blank_handler start to run\n"); + + if (wmt_lib_get_blank_status() != wmt_dev_get_blank_state()) + if (wmt_lib_blank_status_ctrl(wmt_dev_get_blank_state())) + WMT_WARN_FUNC("mtk_lib_blank_status_ctrl failed\n"); +} + +UINT32 wmt_dev_get_blank_state(VOID) +{ + return atomic_read(&g_es_lr_flag_for_blank); +} + +MTK_WCN_BOOL wmt_dev_get_early_suspend_state(VOID) +{ + MTK_WCN_BOOL bRet = + (atomic_read(&g_es_lr_flag_for_quick_sleep) == 0) ? MTK_WCN_BOOL_FALSE : MTK_WCN_BOOL_TRUE; + /* WMT_INFO_FUNC("bRet:%d\n", bRet); */ + return bRet; +} + +VOID wmt_dev_rx_event_cb(VOID) +{ + u4RxFlag = 1; + atomic_inc(&gRxCount); + if (gpRxEvent != NULL) { + /* u4RxFlag = 1; */ + /* atomic_inc(&gRxCount); */ + wake_up_interruptible(&gpRxEvent->waitQueue); + } else { + /* WMT_ERR_FUNC("null gpRxEvent, flush rx!\n"); */ + /* wmt_lib_flush_rx(); */ + } +} + +INT32 wmt_dev_rx_timeout(P_OSAL_EVENT pEvent) +{ + UINT32 ms = pEvent->timeoutValue; + LONG lRet = 0; + + gpRxEvent = pEvent; + if (ms != 0) + lRet = wait_event_interruptible_timeout(gpRxEvent->waitQueue, 0 != u4RxFlag, + msecs_to_jiffies(ms)); + else + lRet = wait_event_interruptible(gpRxEvent->waitQueue, u4RxFlag != 0); + + u4RxFlag = 0; +/* gpRxEvent = NULL; */ + if (atomic_dec_return(&gRxCount)) { + WMT_ERR_FUNC("gRxCount != 0 (%d), reset it!\n", atomic_read(&gRxCount)); + atomic_set(&gRxCount, 0); + } + + return lRet; +} + +/* TODO: [ChangeFeature][George] refine this function name for general filesystem read operation, not patch only. */ +INT32 wmt_dev_patch_get(PUINT8 pPatchName, osal_firmware **ppPatch) +{ + INT32 iRet = -1; + osal_firmware *fw = NULL; + + if (!ppPatch) { + WMT_ERR_FUNC("invalid ppBufptr!\n"); + return -1; + } + *ppPatch = NULL; + do { + iRet = request_firmware((const struct firmware **)&fw, pPatchName, NULL); + if (iRet == -EAGAIN) { + WMT_ERR_FUNC("failed to open or read!(%s), retry again!\n", pPatchName); + osal_sleep_ms(100); + } + } while (iRet == -EAGAIN); + if (iRet != 0) { + WMT_ERR_FUNC("failed to open or read!(%s)\n", pPatchName); + release_firmware(fw); + return -1; + } + WMT_DBG_FUNC("loader firmware %s ok!!\n", pPatchName); + iRet = 0; + *ppPatch = fw; + + return iRet; +} +EXPORT_SYMBOL(wmt_dev_patch_get); + +INT32 wmt_dev_patch_put(osal_firmware **ppPatch) +{ + if (*ppPatch != NULL) { + release_firmware((const struct firmware *)*ppPatch); + *ppPatch = NULL; + } + return 0; +} + +VOID wmt_dev_patch_info_free(VOID) +{ + kfree(pPatchInfo); + pPatchInfo = NULL; + wmt_lib_set_patch_info(NULL); +} + +MTK_WCN_BOOL wmt_dev_is_file_exist(PUINT8 pFileName) +{ + INT32 iRet = 0; + osal_firmware *fw = NULL; + + if (pFileName == NULL) { + WMT_ERR_FUNC("invalid file name pointer(%p)\n", pFileName); + return MTK_WCN_BOOL_FALSE; + } + + if (osal_strlen(pFileName) < osal_strlen(defaultPatchName)) { + WMT_ERR_FUNC("invalid file name(%s)\n", pFileName); + return MTK_WCN_BOOL_FALSE; + } + + iRet = request_firmware((const struct firmware **)&fw, pFileName, NULL); + if (iRet != 0) { + WMT_ERR_FUNC("failed to open or read!(%s)\n", pFileName); + release_firmware(fw); + return MTK_WCN_BOOL_FALSE; + } + release_firmware(fw); + return true; +} + +static ULONG count_last_access_sdio; +static ULONG count_last_access_btif; +static ULONG count_last_access_uart; +static ULONG jiffies_last_poll; + +static INT32 wmt_dev_tra_sdio_update(VOID) +{ + count_last_access_sdio += 1; + /* WMT_INFO_FUNC("jiffies_last_access_sdio: jiffies = %ul\n", jiffies); */ + + return 0; +} + +extern INT32 wmt_dev_tra_bitf_update(VOID) +{ + count_last_access_btif += 1; + /* WMT_INFO_FUNC("jiffies_last_access_btif: jiffies = %ul\n", jiffies); */ + + return 0; +} + +extern INT32 wmt_dev_tra_uart_update(VOID) +{ + count_last_access_uart += 1; + /* WMT_INFO_FUNC("jiffies_last_access_btif: jiffies = %ul\n", jiffies); */ + + return 0; +} + +static UINT32 wmt_dev_tra_poll(VOID) +{ +#define TIME_THRESHOLD_TO_TEMP_QUERY 3000 +#define COUNT_THRESHOLD_TO_TEMP_QUERY 200 + + ULONG during_count = 0; + ULONG poll_during_time = 0; + ENUM_WMT_CHIP_TYPE chip_type; + + chip_type = wmt_detect_get_chip_type(); + /* if (jiffies > jiffies_last_poll) */ + if (time_after(jiffies, jiffies_last_poll)) + poll_during_time = jiffies - jiffies_last_poll; + else + poll_during_time = 0xffffffff; + + WMT_DBG_FUNC("**jiffies_to_mesecs(0xffffffff) = %d\n", jiffies_to_msecs(0xffffffff)); + + if (jiffies_to_msecs(poll_during_time) < TIME_THRESHOLD_TO_TEMP_QUERY) { + WMT_DBG_FUNC("**poll_during_time = %d < %d, not to query\n", + jiffies_to_msecs(poll_during_time), TIME_THRESHOLD_TO_TEMP_QUERY); + return -1; + } + + switch (chip_type) { + case WMT_CHIP_TYPE_COMBO: + during_count = count_last_access_sdio; + break; + case WMT_CHIP_TYPE_SOC: + if (mtk_wcn_wlan_bus_tx_cnt == NULL) { + WMT_ERR_FUNC("WMT-DEV:mtk_wcn_wlan_bus_tx_cnt null pointer\n"); + return -1; + } + if (mtk_wcn_wlan_bus_tx_cnt_clr == NULL) { + WMT_ERR_FUNC("WMT-DEV:mtk_wcn_wlan_bus_tx_cnt_clr null pointer\n"); + return -3; + } + during_count = (*mtk_wcn_wlan_bus_tx_cnt)(); + break; + default: + WMT_ERR_FUNC("WMT-DEV:error chip type(%d)\n", chip_type); + } + + if (during_count < COUNT_THRESHOLD_TO_TEMP_QUERY) { + WMT_DBG_FUNC("**during_count = %lu < %d, not to query\n", during_count, + COUNT_THRESHOLD_TO_TEMP_QUERY); + return -2; + } + + jiffies_last_poll = jiffies; + if (chip_type == WMT_CHIP_TYPE_COMBO) + count_last_access_sdio = 0; + else if (chip_type == WMT_CHIP_TYPE_SOC) + (*mtk_wcn_wlan_bus_tx_cnt_clr)(); + else + WMT_ERR_FUNC("WMT-DEV:error chip type(%d)\n", chip_type); + WMT_INFO_FUNC("**poll_during_time = %d > %d, during_count = %d > %d, query\n", + jiffies_to_msecs(poll_during_time), TIME_THRESHOLD_TO_TEMP_QUERY, + jiffies_to_msecs(during_count), COUNT_THRESHOLD_TO_TEMP_QUERY); + + return 0; +} + +VOID wmt_dev_set_temp_threshold(INT32 val) +{ + gTemperatureThreshold = val; + WMT_INFO_FUNC("Set temperature threashold to %d\n", val); +} + +LONG wmt_dev_tm_temp_query(VOID) +{ +#define HISTORY_NUM 3 +#define REFRESH_TIME 300 /* sec */ +#define ONE_DAY_LONG 86400 /* sec */ +#define MAX_TEMP 0x54 /* Max temperature for Connsys chip */ + + static INT32 s_temp_table[HISTORY_NUM] = { 99 }; /* not query yet. */ + static INT32 s_idx_temp_table; + static struct timeval s_query_time; + static struct timeval sync_log_last_time = {0, 0}; + + INT32 temp_table[HISTORY_NUM]; + INT32 idx_temp_table; + struct timeval query_time; + + struct timeval now_time; + INT32 current_temp = 0; + INT32 index = 0; + LONG return_temp = 0; + INT8 query_cond = 0; + + /* Let us work on the copied version of function static variables */ + osal_lock_unsleepable_lock(&g_temp_query_spinlock); + osal_memcpy(temp_table, s_temp_table, sizeof(s_temp_table)); + osal_memcpy(&query_time, &s_query_time, sizeof(struct timeval)); + idx_temp_table = s_idx_temp_table; + osal_unlock_unsleepable_lock(&g_temp_query_spinlock); + + /* Query condition 1: */ + /* If we have the high temperature records on the past, we continue to query/monitor */ + /* the real temperature until cooling */ + for (index = 0; index < HISTORY_NUM; index++) { + if (temp_table[index] >= gTemperatureThreshold) { + query_cond = 1; + WMT_DBG_FUNC + ("temperature table is still initial value, we should query temp temperature..\n"); + } + } + + osal_do_gettimeofday(&now_time); +#if 1 + /* Query condition 2: */ + /* Moniter the bus activity to decide if we have the need to query temperature. */ + if (!query_cond) { + if (wmt_dev_tra_poll() == 0) { + query_cond = 1; + WMT_DBG_FUNC("traffic , we must query temperature..\n"); + } else if (temp_table[idx_temp_table] >= gTemperatureThreshold) { + WMT_INFO_FUNC("temperature maybe greater than %d, query temperature\n", gTemperatureThreshold); + query_cond = 1; + } else + WMT_DBG_FUNC("idle traffic ....\n"); + + /* only WIFI tx power might make temperature varies largely */ +#if 0 + if (!query_cond) { + last_access_time = wmt_dev_tra_uart_poll(); + if (jiffies_to_msecs(last_access_time) < TIME_THRESHOLD_TO_TEMP_QUERY) { + query_cond = 1; + WMT_DBG_FUNC("uart busy traffic , we must query temperature..\n"); + } else { + WMT_DBG_FUNC("uart still idle traffic , we don't query temp temperature..\n"); + } + } +#endif + } +#endif + /* Query condition 3: */ + /* If the query time exceeds the a certain of period, refresh temp table. */ + /* */ + if (!query_cond) { + /* time overflow, we refresh temp table again for simplicity! */ + if ((now_time.tv_sec < query_time.tv_sec) || + ((now_time.tv_sec > query_time.tv_sec) && + (now_time.tv_sec - query_time.tv_sec) > REFRESH_TIME)) { + query_cond = 1; + + WMT_INFO_FUNC + ("It is long time (prev(%lu), now(%lu), > %d sec) not to query, query temp again..\n", + query_time.tv_sec, now_time.tv_sec, REFRESH_TIME); + for (index = 0; index < HISTORY_NUM; index++) + temp_table[index] = 99; + + } + } + + /* update utc time for fw once a day */ + if ((now_time.tv_sec < sync_log_last_time.tv_sec) || + ((now_time.tv_sec - sync_log_last_time.tv_sec) > ONE_DAY_LONG)) { + sync_log_last_time.tv_sec = now_time.tv_sec; + wmt_lib_utc_time_sync(); + } + + if (query_cond) { + /* update the temperature record */ + mtk_wcn_wmt_therm_ctrl(WMTTHERM_ENABLE); + current_temp = mtk_wcn_wmt_therm_ctrl(WMTTHERM_READ); + mtk_wcn_wmt_therm_ctrl(WMTTHERM_DISABLE); + + /* Only update temperature if our index hasn't been modified by the concurrent thread */ + osal_lock_unsleepable_lock(&g_temp_query_spinlock); + if (idx_temp_table == s_idx_temp_table) { + osal_memcpy(s_temp_table, temp_table, sizeof(s_temp_table)); + s_idx_temp_table = (s_idx_temp_table + 1) % HISTORY_NUM; + s_temp_table[s_idx_temp_table] = current_temp; + osal_do_gettimeofday(&s_query_time); + index = -1; + } else { + index = s_idx_temp_table; + } + osal_unlock_unsleepable_lock(&g_temp_query_spinlock); + + if (index == -1) { + WMT_INFO_FUNC("[Thermal] current_temp = 0x%x\n", (current_temp & 0xFF)); + } else { + WMT_ERR_FUNC("Temperature(0x%x) update failed due to modified idx_temp_table(%d, %d)", + (current_temp & 0xFF), idx_temp_table, index); + } + } else { + /* Only update temperature if our index hasn't been modified by the concurrent thread */ + osal_lock_unsleepable_lock(&g_temp_query_spinlock); + if (idx_temp_table == s_idx_temp_table) { + current_temp = s_temp_table[s_idx_temp_table]; + s_idx_temp_table = (s_idx_temp_table + 1) % HISTORY_NUM; + s_temp_table[s_idx_temp_table] = current_temp; + index = -1; + } else { + /* Return the last valid temperature which has just been modified by the concurrent thread */ + current_temp = s_temp_table[s_idx_temp_table]; + index = s_idx_temp_table; + } + osal_unlock_unsleepable_lock(&g_temp_query_spinlock); + if (index != -1) { + WMT_DBG_FUNC("Use last valid temperature (0x%x) due to modified idx_temp_table(%d, %d)", + (current_temp & 0xFF), idx_temp_table, index); + } + } + + return_temp = ((current_temp & 0x80) == 0x0) ? current_temp : (-1) * (current_temp & 0x7f); + + /* */ + /* Dump information */ + /* */ + if ((gWmtDbgLvl >= WMT_LOG_DBG) || (return_temp > MAX_TEMP)) { + osal_lock_unsleepable_lock(&g_temp_query_spinlock); + WMT_INFO_FUNC("[Thermal] s_idx_temp_table = %d, idx_temp_table = %d\n", + s_idx_temp_table, idx_temp_table); + WMT_INFO_FUNC("[Thermal] now.time = %lu, s_query.time = %lu, query.time = %lu, REFRESH_TIME = %d\n", + now_time.tv_sec, s_query_time.tv_sec, query_time.tv_sec, REFRESH_TIME); + + WMT_INFO_FUNC("[0] = %d, [1] = %d, [2] = %d\n----\n", + s_temp_table[0], s_temp_table[1], s_temp_table[2]); + osal_unlock_unsleepable_lock(&g_temp_query_spinlock); + } + + if (return_temp > MAX_TEMP) { + return_temp = MAX_TEMP; + wmt_lib_trigger_assert_keyword(WMTDRV_TYPE_WMT, 36, "Temperature too high"); + } + + return return_temp; +} + +ssize_t WMT_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) +{ + INT32 iRet = 0; + UINT8 wrBuf[NAME_MAX + 1] = { 0 }; + INT32 copySize = (count < NAME_MAX) ? count : NAME_MAX; + + WMT_LOUD_FUNC("count:%zu copySize:%d\n", count, copySize); + + if (copySize > 0) { + if (copy_from_user(wrBuf, buf, copySize)) { + iRet = -EFAULT; + goto write_done; + } + iRet = copySize; + wrBuf[NAME_MAX] = '\0'; + + if (!strncasecmp(wrBuf, "ok", NAME_MAX)) { + WMT_DBG_FUNC("resp str ok\n"); + /* pWmtDevCtx->cmd_result = 0; */ + wmt_lib_trigger_cmd_signal(0); + } else { + WMT_WARN_FUNC("warning resp str (%s)\n", wrBuf); + /* pWmtDevCtx->cmd_result = -1; */ + wmt_lib_trigger_cmd_signal(-1); + } + /* complete(&pWmtDevCtx->cmd_comp); */ + } + +write_done: + return iRet; +} + +ssize_t WMT_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) +{ + INT32 iRet = 0; + PUINT8 pCmd = NULL; + UINT32 cmdLen = 0; + + pCmd = wmt_lib_get_cmd(); + + if (pCmd != NULL) { + cmdLen = osal_strlen(pCmd) < NAME_MAX ? osal_strlen(pCmd) : NAME_MAX; + if (cmdLen > count) + cmdLen = count; + WMT_DBG_FUNC("cmd str(%s)\n", pCmd); + if (copy_to_user(buf, pCmd, cmdLen)) + iRet = -EFAULT; + else + iRet = cmdLen; + } +#if 0 + if (test_and_clear_bit(WMT_STAT_CMD, &pWmtDevCtx->state)) { + iRet = osal_strlen(localBuf) < NAME_MAX ? osal_strlen(localBuf) : NAME_MAX; + /* we got something from STP driver */ + WMT_DBG_FUNC("copy cmd to user by read:%s\n", localBuf); + if (copy_to_user(buf, localBuf, iRet)) { + iRet = -EFAULT; + goto read_done; + } + } +#endif + + return iRet; +} + +UINT32 WMT_poll(struct file *filp, poll_table *wait) +{ + UINT32 mask = 0; + P_OSAL_EVENT pEvent = wmt_lib_get_cmd_event(); + + poll_wait(filp, &pEvent->waitQueue, wait); + /* empty let select sleep */ + if (wmt_lib_get_cmd_status() == MTK_WCN_BOOL_TRUE) + mask |= POLLIN | POLLRDNORM; /* readable */ +#if 0 + if (test_bit(WMT_STAT_CMD, &pWmtDevCtx->state)) + mask |= POLLIN | POLLRDNORM; /* readable */ +#endif + mask |= POLLOUT | POLLWRNORM; /* writable */ + + return mask; +} + +/* INT32 WMT_ioctl(struct inode *inode, struct file *filp, UINT32 cmd, unsigned long arg) */ +LONG WMT_unlocked_ioctl(struct file *filp, UINT32 cmd, ULONG arg) +{ + INT32 iRet = 0; + UINT8 *pBuffer = NULL; + + WMT_DBG_FUNC("cmd (%u), arg (0x%lx)\n", cmd, arg); + switch (cmd) { + case WMT_IOCTL_SET_PATCH_NAME: /* patch location */ + { + pBuffer = kmalloc(NAME_MAX + 1, GFP_KERNEL); + if (!pBuffer) { + WMT_ERR_FUNC("pBuffer kmalloc memory fail\n"); + return 0; + } + if (copy_from_user(pBuffer, (PVOID)arg, NAME_MAX)) { + iRet = -EFAULT; + kfree(pBuffer); + break; + } + pBuffer[NAME_MAX] = '\0'; + wmt_lib_set_patch_name(pBuffer); + kfree(pBuffer); + } + break; + case WMT_IOCTL_SET_STP_MODE: /* stp/hif/fm mode */ + /* set hif conf */ + do { + P_OSAL_OP pOp; + MTK_WCN_BOOL bRet; + P_OSAL_SIGNAL pSignal = NULL; + P_WMT_HIF_CONF pHif = NULL; + + if (hif_info == 1) { + WMT_INFO_FUNC("hif_info had been set!\n"); + break; + } + + iRet = wmt_lib_set_hif(arg); + if (iRet != 0) { + WMT_INFO_FUNC("wmt_lib_set_hif fail (%lu)\n", arg); + break; + } + + pOp = wmt_lib_get_free_op(); + if (!pOp) { + WMT_INFO_FUNC("get_free_lxop fail\n"); + break; + } + pSignal = &pOp->signal; + pOp->op.opId = WMT_OPID_HIF_CONF; + + pHif = wmt_lib_get_hif(); + + osal_memcpy(&pOp->op.au4OpData[0], pHif, sizeof(WMT_HIF_CONF)); + pOp->op.u4InfoBit = WMT_OP_HIF_BIT; + pSignal->timeoutValue = 0; + + bRet = wmt_lib_put_act_op(pOp); + WMT_DBG_FUNC("WMT_OPID_HIF_CONF result(%d)\n", bRet); + iRet = (bRet == MTK_WCN_BOOL_FALSE) ? -EFAULT : 0; + if (iRet == 0) { + WMT_INFO_FUNC("luncher set STP mode success!\n"); + hif_info = 1; + + if (atomic_read(&g_late_pwr_on_for_blank) && + atomic_read(&g_es_lr_flag_for_blank)) { + atomic_set(&g_late_pwr_on_for_blank, 0); + schedule_work(&gPwrOnOffWork); + } + } + } while (0); + break; + case WMT_IOCTL_FUNC_ONOFF_CTRL: /* test turn on/off func */ +#if WMT_DBG_SUPPORT + do { + MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; + + if (arg >> 4 == 0xBEEF000) + bRet = mtk_wcn_wmt_func_on(arg & 0xF); + else if (arg >> 4 == 0xDEAD000) + bRet = mtk_wcn_wmt_func_off(arg & 0xF); + + iRet = (bRet == MTK_WCN_BOOL_FALSE) ? -EFAULT : 0; + } while (0); +#endif + break; + case WMT_IOCTL_LPBK_POWER_CTRL: + do { + MTK_WCN_BOOL bRet = MTK_WCN_BOOL_TRUE; + + switch (arg) { + case 0: + if (always_pwr_on_flag) + bRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_LPBK); + break; + case 1: + if (always_pwr_on_flag) + bRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_LPBK); + break; + case 2: + bRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_LPBK); + break; + case 3: + bRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_LPBK); + break; + } + iRet = (bRet == MTK_WCN_BOOL_TRUE) ? 0 : -EFAULT; + } while (0); + break; + case WMT_IOCTL_LPBK_TEST: + do { + P_OSAL_OP pOp; + MTK_WCN_BOOL bRet; + UINT32 u4Wait; + /* UINT8 lpbk_buf[1024] = {0}; */ + UINT32 effectiveLen = 0; + P_OSAL_SIGNAL pSignal = NULL; + + if (copy_from_user(&effectiveLen, (PVOID)arg, sizeof(effectiveLen))) { + iRet = -EFAULT; + WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__); + break; + } + if (effectiveLen > sizeof(gLpbkBuf)) { + iRet = -EFAULT; + WMT_ERR_FUNC("length is too long\n"); + break; + } + WMT_DBG_FUNC("len = %d\n", effectiveLen); + + u4Wait = 2000; + if (copy_from_user(&gLpbkBuf[0], (PVOID)arg + sizeof(effectiveLen), effectiveLen)) { + WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__); + iRet = -EFAULT; + break; + } + pOp = wmt_lib_get_free_op(); + if (!pOp) { + WMT_WARN_FUNC("get_free_lxop fail\n"); + iRet = -EFAULT; + break; + } + pSignal = &pOp->signal; + pOp->op.opId = WMT_OPID_LPBK; + pOp->op.au4OpData[0] = effectiveLen; /* packet length */ + pOp->op.au4OpData[1] = (SIZE_T)&gLpbkBuf[0]; /* packet buffer pointer */ + memcpy(&gLpbkBufLog, &gLpbkBuf[((effectiveLen >= 4) ? effectiveLen - 4 : 0)], 4); + pSignal->timeoutValue = MAX_EACH_WMT_CMD; + WMT_INFO_FUNC("OPID(%d) type(%zu) start\n", pOp->op.opId, pOp->op.au4OpData[0]); + if (DISABLE_PSM_MONITOR()) { + WMT_ERR_FUNC("wake up failed,OPID(%d) type(%d) abort\n", + pOp->op.opId, pOp->op.au4OpData[0]); + wmt_lib_put_op_to_free_queue(pOp); + iRet = -1; + break; + } + + bRet = wmt_lib_put_act_op(pOp); + ENABLE_PSM_MONITOR(); + if (bRet == MTK_WCN_BOOL_FALSE) { + WMT_WARN_FUNC("OPID(%d) type(%d) buf tail(0x%08x) fail\n", + pOp->op.opId, pOp->op.au4OpData[0], gLpbkBufLog); + iRet = -1; + break; + } + WMT_INFO_FUNC("OPID(%d) length(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); + iRet = pOp->op.au4OpData[0]; + if ((iRet > sizeof(gLpbkBuf)) || (iRet < 0)) { + iRet = -EFAULT; + WMT_ERR_FUNC("length is too long\n"); + break; + } + if (copy_to_user((PVOID)arg + sizeof(effectiveLen) + sizeof(UINT8[2048]), gLpbkBuf, iRet)) { + iRet = -EFAULT; + break; + } + + } while (0); + break; + case WMT_IOCTL_ADIE_LPBK_TEST: + do { + P_OSAL_OP pOp; + MTK_WCN_BOOL bRet; + P_OSAL_SIGNAL pSignal = NULL; + + pOp = wmt_lib_get_free_op(); + if (!pOp) { + WMT_WARN_FUNC("get_free_lxop fail\n"); + iRet = -EFAULT; + break; + } + + pSignal = &pOp->signal; + pOp->op.opId = WMT_OPID_ADIE_LPBK_TEST; + pOp->op.au4OpData[0] = 0; + pOp->op.au4OpData[1] = (SIZE_T)&gLpbkBuf[0]; + pSignal->timeoutValue = MAX_EACH_WMT_CMD; + WMT_INFO_FUNC("OPID(%d) start\n", pOp->op.opId); + if (DISABLE_PSM_MONITOR()) { + WMT_ERR_FUNC("wake up failed,OPID(%d)abort\n", pOp->op.opId); + wmt_lib_put_op_to_free_queue(pOp); + return -1; + } + + bRet = wmt_lib_put_act_op(pOp); + ENABLE_PSM_MONITOR(); + if (bRet == MTK_WCN_BOOL_FALSE) { + WMT_WARN_FUNC("OPID(%d) fail\n", pOp->op.opId); + iRet = -1; + break; + } + WMT_INFO_FUNC("OPID(%d) length(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); + iRet = pOp->op.au4OpData[0]; + if ((iRet > sizeof(gLpbkBuf)) || (iRet < 0)) { + iRet = -EFAULT; + WMT_ERR_FUNC("length is too long\n"); + break; + } + if (copy_to_user((PVOID)arg + sizeof(SIZE_T), gLpbkBuf, iRet)) { + iRet = -EFAULT; + break; + } + } while (0); + break; + case 10: + if (mtk_wcn_stp_coredump_start_get()) { + wmt_lib_host_awake_get(); + if (wmt_detect_get_chip_type() == WMT_CHIP_TYPE_SOC) + WMT_INFO_FUNC("stp dump start.\n"); + else { + WMT_INFO_FUNC("Trigger kernel api dump.\n"); + if (wmt_detect_get_chip_type() == WMT_CHIP_TYPE_COMBO || + mtk_wcn_stp_coredump_flag_get() == 2) { + pBuffer = kmalloc(NAME_MAX + 1, GFP_KERNEL); + if (!pBuffer) { + WMT_ERR_FUNC("pBuffer kmalloc memory fail\n"); + return 0; + } + + osal_strcpy(pBuffer, "MT662x f/w coredump start-"); + if (copy_from_user(pBuffer + osal_strlen(pBuffer), (PVOID)arg, + NAME_MAX - osal_strlen(pBuffer))) { + /* osal_strcpy(pBuffer, "MT662x f/w assert core dump start"); */ + WMT_ERR_FUNC("copy assert string failed\n"); + } + pBuffer[NAME_MAX] = '\0'; + osal_dbg_assert_aee(pBuffer, "%s", pBuffer); + kfree(pBuffer); + } + } + } + break; + case 11: + if (mtk_wcn_stp_coredump_start_get()) { + if (wmt_detect_get_chip_type() == WMT_CHIP_TYPE_SOC) { + WMT_INFO_FUNC("Dump connsys EMI done.\n"); + mtk_stp_notify_emi_dump_end(); + } + wmt_lib_host_awake_put(); + } + break; + case WMT_IOCTL_GET_CHIP_INFO: + if (arg == 0) + return wmt_lib_get_icinfo(WMTCHIN_CHIPID); + else if (arg == 1) + return wmt_lib_get_icinfo(WMTCHIN_HWVER); + else if (arg == 2) + return wmt_lib_get_icinfo(WMTCHIN_FWVER); + else if (arg == 3) + return wmt_lib_get_icinfo(WMTCHIN_IPVER); + else if (arg == 4) + return wmt_detect_get_chip_type(); + break; + case WMT_IOCTL_WMT_CFG_NAME: + { + INT8 cWmtCfgName[NAME_MAX + 1]; + + if (copy_from_user(cWmtCfgName, (void *)arg, NAME_MAX)) { + iRet = -EFAULT; + break; + } + cWmtCfgName[NAME_MAX] = '\0'; + wmt_conf_set_cfg_file(cWmtCfgName); + } + break; + case WMT_IOCTL_SET_LAUNCHER_KILL: + if (arg == 1) { + WMT_INFO_FUNC("launcher may be killed,block abnormal stp tx.\n"); + wmt_lib_set_stp_wmt_last_close(1); + } else + wmt_lib_set_stp_wmt_last_close(0); + break; + case WMT_IOCTL_SET_PATCH_NUM: + if (arg == 0 || arg > MAX_PATCH_NUM || pAtchNum > 0) { + WMT_ERR_FUNC("patch num(%lu) == 0 or > %d or has set!\n", arg, MAX_PATCH_NUM); + iRet = -1; + break; + } + + pAtchNum = arg; + + if (pPatchInfo == NULL) + pPatchInfo = kcalloc(pAtchNum, sizeof(WMT_PATCH_INFO), GFP_ATOMIC); + if (!pPatchInfo) { + WMT_ERR_FUNC("allocate memory fail!\n"); + iRet = -EFAULT; + break; + } + + WMT_DBG_FUNC(" get patch num from launcher = %d\n", pAtchNum); + wmt_lib_set_patch_num(pAtchNum); + break; + case WMT_IOCTL_SET_PATCH_INFO: + do { + WMT_PATCH_INFO wMtPatchInfo; + P_WMT_PATCH_INFO pTemp = NULL; + UINT32 dWloadSeq; + static UINT32 counter; + + if (!pPatchInfo) { + WMT_ERR_FUNC("NULL patch info pointer\n"); + break; + } + + if (copy_from_user(&wMtPatchInfo, (PVOID)arg, sizeof(WMT_PATCH_INFO))) { + WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__); + iRet = -EFAULT; + break; + } + if (wMtPatchInfo.dowloadSeq > pAtchNum || wMtPatchInfo.dowloadSeq == 0) { + WMT_ERR_FUNC("dowloadSeq num(%u) > %u or == 0!\n", wMtPatchInfo.dowloadSeq, pAtchNum); + iRet = -EFAULT; + counter = 0; + break; + } + + dWloadSeq = wMtPatchInfo.dowloadSeq; + WMT_DBG_FUNC( + "patch dl seq %d,name %s,address info 0x%02x,0x%02x,0x%02x,0x%02x\n", + dWloadSeq, wMtPatchInfo.patchName, + wMtPatchInfo.addRess[0], + wMtPatchInfo.addRess[1], + wMtPatchInfo.addRess[2], + wMtPatchInfo.addRess[3]); + osal_memcpy(pPatchInfo + dWloadSeq - 1, &wMtPatchInfo, sizeof(WMT_PATCH_INFO)); + pTemp = pPatchInfo + dWloadSeq - 1; + if (++counter == pAtchNum) { + wmt_lib_set_patch_info(pPatchInfo); + counter = 0; + } + } while (0); + break; + case WMT_IOCTL_WMT_COREDUMP_CTRL: + mtk_wcn_stp_coredump_flag_ctrl(arg); + break; + case WMT_IOCTL_WMT_STP_ASSERT_CTRL: + if (wmt_lib_btm_cb(BTM_TRIGGER_STP_ASSERT_OP) == MTK_WCN_BOOL_TRUE) { + WMT_INFO_FUNC("trigger stp assert succeed\n"); + iRet = 0; + } else { + WMT_INFO_FUNC("trigger stp assert failed\n"); + iRet = -1; + } + break; + case WMT_IOCTL_WMT_QUERY_CHIPID: + iRet = mtk_wcn_wmt_chipid_query(); + WMT_WARN_FUNC("chipid = 0x%x\n", iRet); + break; + case WMT_IOCTL_WMT_TELL_CHIPID: + { +#if !(DELETE_HIF_SDIO_CHRDEV) + iRet = mtk_wcn_hif_sdio_tell_chipid(arg); +#endif + if (0x6628 == arg || 0x6630 == arg || 0x6632 == arg) + wmt_lib_merge_if_flag_ctrl(1); + else + wmt_lib_merge_if_flag_ctrl(0); + } + break; + case WMT_IOCTL_SEND_BGW_DS_CMD: + do { + P_OSAL_OP pOp; + MTK_WCN_BOOL bRet; + UINT8 desense_buf[14] = { 0 }; + UINT32 effectiveLen = 14; + P_OSAL_SIGNAL pSignal = NULL; + + if (!mtk_wcn_stp_is_ready()) { + iRet = -EFAULT; + break; + } + + if (copy_from_user(&desense_buf[0], (PVOID)arg, effectiveLen)) { + WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__); + iRet = -EFAULT; + break; + } + + pOp = wmt_lib_get_free_op(); + if (!pOp) { + WMT_WARN_FUNC("get_free_lxop fail\n"); + iRet = -EFAULT; + break; + } + pSignal = &pOp->signal; + pOp->op.opId = WMT_OPID_BGW_DS; + pOp->op.au4OpData[0] = effectiveLen; /* packet length */ + pOp->op.au4OpData[1] = (SIZE_T)&desense_buf[0]; /* packet buffer pointer */ + pSignal->timeoutValue = MAX_WMT_OP_TIMEOUT; + WMT_INFO_FUNC("OPID(%d) start\n", pOp->op.opId); + if (DISABLE_PSM_MONITOR()) { + WMT_ERR_FUNC("wake up failed,opid(%d) abort\n", pOp->op.opId); + wmt_lib_put_op_to_free_queue(pOp); + return -1; + } + + bRet = wmt_lib_put_act_op(pOp); + ENABLE_PSM_MONITOR(); + if (bRet == MTK_WCN_BOOL_FALSE) { + WMT_WARN_FUNC("OPID(%d) fail\n", pOp->op.opId); + iRet = -1; + break; + } + WMT_INFO_FUNC("OPID(%d) length(%zu) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); + iRet = pOp->op.au4OpData[0]; + + } while (0); + break; + case WMT_IOCTL_FW_DBGLOG_CTRL: + iRet = wmt_plat_set_dbg_mode(arg); + if (iRet == 0) + wmt_dbg_fwinfor_from_emi(0, 1, 0); + break; + case WMT_IOCTL_DYNAMIC_DUMP_CTRL: + do { + UINT32 i = 0, j = 0, k = 0; + PUINT8 pBuf = NULL; + UINT32 int_buf[10] = {0}; + INT8 Buffer[10][11]; + + pBuf = kmalloc(DYNAMIC_DUMP_BUF + 1, GFP_KERNEL); + if (!pBuf) { + WMT_ERR_FUNC("pBuf kmalloc memory fail\n"); + return 0; + } + if (copy_from_user(pBuf, (PVOID)arg, DYNAMIC_DUMP_BUF)) { + iRet = -EFAULT; + kfree(pBuf); + break; + } + pBuf[DYNAMIC_DUMP_BUF] = '\0'; + WMT_INFO_FUNC("get dynamic dump data from property(%s)\n", pBuf); + memset(Buffer, 0, 10*11); + for (i = 0; i < DYNAMIC_DUMP_BUF && j <= 9; i++) { + if (pBuf[i] == '/') { + k = 0; + j++; + } else if (isascii(pBuf[i]) && k <= 10) { + Buffer[j][k] = pBuf[i]; + k++; + } + } + for (i = 0; i < (j > 10 ? 10 : j); i++) { + iRet = kstrtou32(Buffer[i], 0, &int_buf[i]); + if (iRet) { + WMT_ERR_FUNC("string convert fail(%d)\n", iRet); + break; + } + WMT_INFO_FUNC("dynamic dump data buf[%d]:(0x%x)\n", i, int_buf[i]); + } + wmt_plat_set_dynamic_dumpmem(int_buf); + kfree(pBuf); + } while (0); + break; + case WMT_IOCTL_SET_ROM_PATCH_INFO: + do { + struct wmt_rom_patch_info wmtRomPatchInfo; + + if (copy_from_user(&wmtRomPatchInfo, (PVOID)arg, sizeof(struct wmt_rom_patch_info))) { + WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__); + iRet = -EFAULT; + break; + } + + if (wmtRomPatchInfo.type >= WMTDRV_TYPE_ANT) { + WMT_ERR_FUNC("rom patch type(%d) >= %d!\n", + wmtRomPatchInfo.type, WMTDRV_TYPE_WMT); + iRet = -EFAULT; + break; + } + + WMT_DBG_FUNC("rom patch type %d,name %s,address info 0x%02x,0x%02x,0x%02x,0x%02x\n", + wmtRomPatchInfo.type, wmtRomPatchInfo.patchName, + wmtRomPatchInfo.addRess[0], + wmtRomPatchInfo.addRess[1], + wmtRomPatchInfo.addRess[2], + wmtRomPatchInfo.addRess[3]); + wmt_lib_set_rom_patch_info(&wmtRomPatchInfo, wmtRomPatchInfo.type); + } while (0); + break; + case WMT_IOCTL_GET_EMI_PHY_SIZE: + do { + WMT_INFO_FUNC("gConEmiSize %llu\n", gConEmiSize); + return (UINT32)gConEmiSize; + } while (0); + break; + case WMT_IOCTL_FW_PATCH_UPDATE_RST: + wmt_lib_fw_patch_update_rst_ctrl(arg); + break; + case WMT_IOCTL_GET_DIRECT_PATH_EMI_SIZE: + do { + P_CONSYS_EMI_ADDR_INFO emiInfo = mtk_wcn_consys_soc_get_emi_phy_add(); + + if (emiInfo == NULL) { + WMT_INFO_FUNC("Get emi info fail. Return 0.\n"); + return 0; + } + WMT_INFO_FUNC("Direct path emi size=%d\n", emiInfo->emi_direct_path_size); + return (UINT32)emiInfo->emi_direct_path_size; + } while (0); + break; + case WMT_IOCTL_GET_VENDOR_PATCH_NUM: + iRet = wmt_lib_get_vendor_patch_num(); + break; + case WMT_IOCTL_SET_VENDOR_PATCH_VERSION: + do { + struct wmt_vendor_patch patch; + + if (copy_from_user(&patch, (PVOID)arg, + sizeof(struct wmt_vendor_patch))) { + WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__); + iRet = -EFAULT; + break; + } + + iRet = wmt_lib_set_vendor_patch_version(&patch); + if (iRet) { + iRet = -EFAULT; + break; + } + } while (0); + break; + case WMT_IOCTL_GET_VENDOR_PATCH_VERSION: + do { + struct wmt_vendor_patch patch; + + if (copy_from_user(&patch, (PVOID)arg, sizeof(struct wmt_vendor_patch))) { + WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__); + iRet = -EFAULT; + break; + } + + iRet = wmt_lib_get_vendor_patch_version(&patch); + if (iRet) { + iRet = -EFAULT; + break; + } + + if (copy_to_user((PVOID)arg, &patch, sizeof(struct wmt_vendor_patch))) + iRet = -EFAULT; + } while (0); + break; + case WMT_IOCTL_SET_ACTIVE_PATCH_VERSION: + do { + struct wmt_vendor_patch patch; + + if (copy_from_user(&patch, (PVOID)arg, + sizeof(struct wmt_vendor_patch))) { + WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__); + iRet = -EFAULT; + break; + } + + iRet = wmt_lib_set_active_patch_version(&patch); + WMT_ERR_FUNC("wmt_lib_set_active_patch_version ret = %d\n", iRet); + if (iRet) { + iRet = -EFAULT; + break; + } + } while (0); + break; + case WMT_IOCTL_GET_ACTIVE_PATCH_VERSION: + do { + struct wmt_vendor_patch patch; + + if (copy_from_user(&patch, (PVOID)arg, sizeof(struct wmt_vendor_patch))) { + WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__); + iRet = -EFAULT; + break; + } + + iRet = wmt_lib_get_active_patch_version(&patch); + if (iRet) { + iRet = -EFAULT; + break; + } + + if (copy_to_user((PVOID)arg, &patch, sizeof(struct wmt_vendor_patch))) + iRet = -EFAULT; + } while (0); + break; + case WMT_IOCTL_SET_CHECK_PATCH_STATUS: + iRet = wmt_lib_set_check_patch_status(arg); + break; + case WMT_IOCTL_GET_CHECK_PATCH_STATUS: + iRet = wmt_lib_get_check_patch_status(); + break; + default: + iRet = -EINVAL; + WMT_WARN_FUNC("unknown cmd (0x%x)\n", cmd); + break; + } + + return iRet; +} + +#ifdef CONFIG_COMPAT +LONG WMT_compat_ioctl(struct file *filp, UINT32 cmd, ULONG arg) +{ + LONG ret; + + WMT_INFO_FUNC("cmd[0x%x]\n", cmd); + switch (cmd) { + case COMPAT_WMT_IOCTL_SET_PATCH_NAME: + ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_SET_PATCH_NAME, (ULONG)compat_ptr(arg)); + break; + case COMPAT_WMT_IOCTL_LPBK_TEST: + ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_LPBK_TEST, (ULONG)compat_ptr(arg)); + break; + case COMPAT_WMT_IOCTL_SET_PATCH_INFO: + ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_SET_PATCH_INFO, (ULONG)compat_ptr(arg)); + break; + case COMPAT_WMT_IOCTL_PORT_NAME: + ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_PORT_NAME, (ULONG)compat_ptr(arg)); + break; + case COMPAT_WMT_IOCTL_WMT_CFG_NAME: + ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_WMT_CFG_NAME, (ULONG)compat_ptr(arg)); + break; + case COMPAT_WMT_IOCTL_SEND_BGW_DS_CMD: + ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_SEND_BGW_DS_CMD, (ULONG)compat_ptr(arg)); + break; + case COMPAT_WMT_IOCTL_ADIE_LPBK_TEST: + ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_ADIE_LPBK_TEST, (ULONG)compat_ptr(arg)); + break; + case COMPAT_WMT_IOCTL_DYNAMIC_DUMP_CTRL: + ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_DYNAMIC_DUMP_CTRL, (ULONG)compat_ptr(arg)); + break; + case COMPAT_WMT_IOCTL_SET_ROM_PATCH_INFO: + ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_SET_ROM_PATCH_INFO, (ULONG)compat_ptr(arg)); + break; + default: { + ret = WMT_unlocked_ioctl(filp, cmd, arg); + break; + } + } + return ret; +} +#endif /* CONFIG_COMPAT */ + +static INT32 WMT_open(struct inode *inode, struct file *file) +{ + LONG ret; + + WMT_INFO_FUNC("major %d minor %d (pid %d)\n", imajor(inode), iminor(inode), current->pid); + ret = wait_event_timeout(gWmtInitWq, gWmtInitStatus == WMT_INIT_DONE, msecs_to_jiffies(WMT_DEV_INIT_TO_MS)); + if (!ret) { + WMT_WARN_FUNC("wait_event_timeout (%d)ms,(%lu)jiffies,return -EIO\n", + WMT_DEV_INIT_TO_MS, msecs_to_jiffies(WMT_DEV_INIT_TO_MS)); + return -EIO; + } + + if (atomic_inc_return(&gWmtRefCnt) == 1) { + WMT_INFO_FUNC("1st call\n"); + gWmtClose = 0; + } + + return 0; +} + +static INT32 WMT_close(struct inode *inode, struct file *file) +{ + WMT_INFO_FUNC("major %d minor %d (pid %d)\n", imajor(inode), iminor(inode), current->pid); + + if (atomic_dec_return(&gWmtRefCnt) == 0) { + WMT_INFO_FUNC("last call\n"); + gWmtClose = 1; + } + + return 0; +} + +static INT32 WMT_mmap(struct file *pFile, struct vm_area_struct *pVma) +{ + unsigned long bufId = pVma->vm_pgoff; + P_CONSYS_EMI_ADDR_INFO emiInfo = mtk_wcn_consys_soc_get_emi_phy_add(); + + pVma->vm_flags &= ~(VM_WRITE | VM_MAYWRITE); + WMT_INFO_FUNC("WMT_mmap start:%lu end:%lu size: %lu buffer id=%lu\n", + pVma->vm_start, pVma->vm_end, + pVma->vm_end - pVma->vm_start, bufId); + + if (bufId == 0) { + if (pVma->vm_end - pVma->vm_start > gConEmiSize) + return -EINVAL; + WMT_INFO_FUNC("WMT_mmap size: %lu\n", pVma->vm_end - pVma->vm_start); + if (remap_pfn_range(pVma, pVma->vm_start, gConEmiPhyBase >> PAGE_SHIFT, + pVma->vm_end - pVma->vm_start, pVma->vm_page_prot)) + return -EAGAIN; + return 0; + } else if (bufId == 1) { + if (emiInfo == NULL) + return -EINVAL; + if (emiInfo->emi_direct_path_size == 0 || + pVma->vm_end - pVma->vm_start > emiInfo->emi_direct_path_size) + return -EINVAL; + WMT_INFO_FUNC("MD direct path size=%d map size=%lu\n", + emiInfo->emi_direct_path_size, + pVma->vm_end - pVma->vm_start); + if (remap_pfn_range(pVma, pVma->vm_start, + emiInfo->emi_direct_path_ap_phy_addr >> PAGE_SHIFT, + pVma->vm_end - pVma->vm_start, pVma->vm_page_prot)) + return -EAGAIN; + return 0; + } + /* Invalid buff id */ + return -EINVAL; +} + +const struct file_operations gWmtFops = { + .open = WMT_open, + .release = WMT_close, + .read = WMT_read, + .write = WMT_write, +/* .ioctl = WMT_ioctl, */ + .unlocked_ioctl = WMT_unlocked_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = WMT_compat_ioctl, +#endif + .poll = WMT_poll, + .mmap = WMT_mmap, +}; + +VOID wmt_dev_bgw_desense_init(VOID) +{ + bgw_init_socket(); +} + +VOID wmt_dev_bgw_desense_deinit(VOID) +{ + bgw_destroy_netlink_kernel(); +} + +VOID wmt_dev_send_cmd_to_daemon(UINT32 cmd) +{ + send_command_to_daemon(cmd); +} + +UINT8 wmt_dev_is_close(VOID) +{ + return gWmtClose; +} + +static INT32 WMT_init(VOID) +{ + dev_t devID = MKDEV(gWmtMajor, 0); + INT32 cdevErr = -1; + INT32 ret = -1; + ENUM_WMT_CHIP_TYPE chip_type; + + WMT_DBG_FUNC("WMT Version= %s DATE=%s\n", MTK_WMT_VERSION, MTK_WMT_DATE); + if (gWmtInitStatus != WMT_INIT_NOT_START) + return 0; + /* Prepare a UINT8 device */ + /*static allocate chrdev */ + gWmtInitStatus = WMT_INIT_START; + init_waitqueue_head((wait_queue_head_t *) &gWmtInitWq); + + osal_unsleepable_lock_init(&g_temp_query_spinlock); + +#if (MTK_WCN_REMOVE_KO) + /* called in do_common_drv_init() */ +#else + mtk_wcn_hif_sdio_drv_init(); +#endif + stp_drv_init(); + + ret = register_chrdev_region(devID, WMT_DEV_NUM, WMT_DRIVER_NAME); + if (ret) { + WMT_ERR_FUNC("fail to register chrdev\n"); + gWmtInitStatus = WMT_INIT_NOT_START; + return ret; + } + + cdev_init(&gWmtCdev, &gWmtFops); + gWmtCdev.owner = THIS_MODULE; + + cdevErr = cdev_add(&gWmtCdev, devID, WMT_DEV_NUM); + if (cdevErr) { + WMT_ERR_FUNC("cdev_add() fails (%d)\n", cdevErr); + goto error; + } + WMT_INFO_FUNC("driver(major %d) installed\n", gWmtMajor); + +#if WMT_CREATE_NODE_DYNAMIC + wmt_class = class_create(THIS_MODULE, "stpwmt"); + if (IS_ERR(wmt_class)) + goto error; + wmt_dev = device_create(wmt_class, NULL, devID, NULL, "stpwmt"); + if (IS_ERR(wmt_dev)) + goto error; +#endif + +#if 0 + pWmtDevCtx = wmt_drv_create(); + if (!pWmtDevCtx) { + WMT_ERR_FUNC("wmt_drv_create() fails\n"); + goto error; + } + + ret = wmt_drv_init(pWmtDevCtx); + if (ret) { + WMT_ERR_FUNC("wmt_drv_init() fails (%d)\n", ret); + goto error; + } + + WMT_INFO_FUNC("stp_btmcb_reg\n"); + wmt_cdev_btmcb_reg(); + + ret = wmt_drv_start(pWmtDevCtx); + if (ret) { + WMT_ERR_FUNC("wmt_drv_start() fails (%d)\n", ret); + goto error; + } +#endif + ret = wmt_lib_init(); + if (ret) { + WMT_ERR_FUNC("wmt_lib_init() fails (%d)\n", ret); + goto error; + } +#if CFG_WMT_DBG_SUPPORT + wmt_dev_dbg_setup(); +#endif + wmt_dev_user_proc_setup(); + + wmt_dev_proc_init(); + wmt_alarm_init(); + + WMT_STEP_INIT_FUNC(); + + chip_type = wmt_detect_get_chip_type(); + if (chip_type == WMT_CHIP_TYPE_COMBO) + mtk_wcn_hif_sdio_update_cb_reg(wmt_dev_tra_sdio_update); + + wmt_lib_register_thermal_ctrl_cb(wmt_dev_tm_temp_query); + wmt_lib_register_trigger_assert_cb(wmt_lib_trigger_assert); + + if (chip_type == WMT_CHIP_TYPE_SOC) + wmt_dev_bgw_desense_init(); + + gWmtInitStatus = WMT_INIT_DONE; + wake_up(&gWmtInitWq); + + INIT_WORK(&gPwrOnOffWork, wmt_pwr_on_off_handler); +#ifdef CONFIG_EARLYSUSPEND + register_early_suspend(&wmt_early_suspend_handler); + WMT_INFO_FUNC("register_early_suspend finished\n"); +#else + wmt_fb_notifier.notifier_call = wmt_fb_notifier_callback; + ret = fb_register_client(&wmt_fb_notifier); + if (ret) + WMT_ERR_FUNC("wmt register fb_notifier failed! ret(%d)\n", ret); + else + WMT_DBG_FUNC("wmt register fb_notifier OK!\n"); +#endif /* CONFIG_EARLYSUSPEND */ + WMT_DBG_FUNC("success\n"); + +#if (MTK_WCN_REMOVE_KO) + /* called in do_common_drv_init() */ +#else + mtk_wcn_stp_uart_drv_init(); + mtk_wcn_stp_sdio_drv_init(); +#endif + + return 0; + +error: + wmt_lib_deinit(); +#if CFG_WMT_DBG_SUPPORT + wmt_dev_dbg_remove(); +#endif + wmt_dev_user_proc_remove(); +#if WMT_CREATE_NODE_DYNAMIC + if (!(IS_ERR(wmt_dev))) + device_destroy(wmt_class, devID); + if (!(IS_ERR(wmt_class))) { + class_destroy(wmt_class); + wmt_class = NULL; + } +#endif + + if (cdevErr == 0) + cdev_del(&gWmtCdev); + + if (ret == 0) { + unregister_chrdev_region(devID, WMT_DEV_NUM); + gWmtMajor = -1; + } + + gWmtInitStatus = WMT_INIT_NOT_START; + WMT_ERR_FUNC("fail\n"); + + return -1; +} + +static VOID WMT_exit(VOID) +{ + dev_t dev = MKDEV(gWmtMajor, 0); + + if (gWmtInitStatus != WMT_INIT_DONE) + return; + + osal_unsleepable_lock_deinit(&g_temp_query_spinlock); +#ifdef CONFIG_EARLYSUSPEND + unregister_early_suspend(&wmt_early_suspend_handler); + WMT_INFO_FUNC("unregister_early_suspend finished\n"); +#else + fb_unregister_client(&wmt_fb_notifier); +#endif /* CONFIG_EARLYSUSPEND */ + + wmt_dev_patch_info_free(); + mtk_wcn_stp_uart_drv_exit(); + mtk_wcn_stp_sdio_drv_exit(); + + wmt_dev_bgw_desense_deinit(); + + wmt_lib_register_thermal_ctrl_cb(NULL); + + wmt_lib_deinit(); + +#if CFG_WMT_DBG_SUPPORT + wmt_dev_dbg_remove(); +#endif + wmt_dev_user_proc_remove(); + + wmt_dev_proc_deinit(); + wmt_alarm_deinit(); + +#if WMT_CREATE_NODE_DYNAMIC + if (wmt_dev) { + device_destroy(wmt_class, dev); + wmt_dev = NULL; + } + if (wmt_class) { + class_destroy(wmt_class); + wmt_class = NULL; + } +#endif + cdev_del(&gWmtCdev); + unregister_chrdev_region(dev, WMT_DEV_NUM); + gWmtMajor = -1; + + stp_drv_exit(); + mtk_wcn_hif_sdio_driver_exit(); + gWmtInitStatus = WMT_INIT_NOT_START; + WMT_INFO_FUNC("done\n"); +} + +INT32 mtk_wcn_common_drv_init(VOID) +{ + return WMT_init(); +} +EXPORT_SYMBOL(mtk_wcn_common_drv_init); + +VOID mtk_wcn_common_drv_exit(VOID) +{ + WMT_exit(); +} +EXPORT_SYMBOL(mtk_wcn_common_drv_exit); + diff --git a/drivers/misc/mediatek/connectivity/common/common_main/linux/wmt_idc.c b/drivers/misc/mediatek/connectivity/common/common_main/linux/wmt_idc.c new file mode 100644 index 0000000000000000000000000000000000000000..864b2ac18eb6559fda93243b66eebd3865445399 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/linux/wmt_idc.c @@ -0,0 +1,318 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +#include "osal.h" +#include "wmt_idc.h" +#include "wmt_lib.h" + +#if CFG_WMT_LTE_COEX_HANDLING + +MTK_WCN_WMT_IDC_INFO gWmtIdcInfo; + +INT32 wmt_idc_init(VOID) +{ + INT32 iRet; + + osal_memset(&gWmtIdcInfo, 0, osal_sizeof(gWmtIdcInfo)); + gWmtIdcInfo.iit.src_mod_id = AP_MOD_WMT; + gWmtIdcInfo.iit.dest_mod_id = MD_MOD_EL1; + gWmtIdcInfo.iit.sap_id = 0; + gWmtIdcInfo.ops.rx_cb = wmt_idc_msg_from_lte_handing; + + iRet = mtk_conn_md_bridge_reg(gWmtIdcInfo.iit.src_mod_id, &gWmtIdcInfo.ops); + if (iRet) { + WMT_ERR_FUNC("mtk_conn_md_bridge_reg fail(%d)\n", iRet); + return -1; + } + /* mtk_wcn_stp_flush_rx_queue(COEX_TASK_INDX); */ + return 0; +} + +INT32 wmt_idc_deinit(VOID) +{ + INT32 iRet; + + iRet = mtk_conn_md_bridge_unreg(gWmtIdcInfo.iit.src_mod_id); + if (iRet) + WMT_ERR_FUNC("mtk_conn_md_bridge_unreg fail(%d)\n", iRet); + + osal_memset(&gWmtIdcInfo, 0, osal_sizeof(gWmtIdcInfo)); + + return 0; +} + +INT32 wmt_idc_msg_from_lte_handing(conn_md_ipc_ilm_t *ilm) +{ + MTK_WCN_BOOL bRet; + + if (ilm == NULL) { + WMT_ERR_FUNC("NULL pointer\n"); + return -1; + } + if (mtk_wcn_stp_is_ready()) { + bRet = wmt_lib_handle_idc_msg(ilm); + if (bRet == MTK_WCN_BOOL_FALSE) { + WMT_ERR_FUNC("wmt handing idc msg fail\n"); + return -2; + } + } else + WMT_INFO_FUNC("Received LTE msg,but STP is not ready,drop it!\n"); + + return 0; +} + +VOID wmt_idc_dump_debug_msg(PUINT8 str, PUINT8 p_buf, UINT32 buf_len) +{ + UINT32 idx = 0; + + WMT_DBG_FUNC("%s:, length:%d\n", str, buf_len); + + WMT_DBG_FUNC("ASCII output:\n"); + + for (idx = 0; idx < buf_len;) { + WMT_DBG_FUNC("%c", p_buf[idx]); + idx++; + if (idx % 16 == 0) + WMT_DBG_FUNC("\n"); + } + + WMT_DBG_FUNC("HEX output:\n"); + + for (idx = 0; idx < buf_len;) { + WMT_DBG_FUNC("%02x ", p_buf[idx]); + idx++; + if (idx % 16 == 0) + WMT_DBG_FUNC("\n"); + } +} + +INT32 wmt_idc_msg_to_lte_handing(VOID) +{ + UINT32 readlen = 0; + struct local_para *p_lps = NULL; + PUINT8 p_data = NULL; + UINT8 opcode = 0; + UINT16 msg_len = 0; +#if CFG_WMT_LTE_ENABLE_MSGID_MAPPING + MTK_WCN_BOOL unknown_msgid = MTK_WCN_BOOL_FALSE; +#endif + + readlen = mtk_wcn_stp_receive_data(&gWmtIdcInfo.buffer[0], 4, COEX_TASK_INDX); + if (readlen == 0) { + osal_sleep_ms(5); + readlen = mtk_wcn_stp_receive_data(&gWmtIdcInfo.buffer[0], 4, COEX_TASK_INDX); + } + + if (readlen > 0) { + WMT_DBG_FUNC("read data len from fw(%d)\n", readlen); + wmt_idc_dump_debug_msg("WMT->LTE from STP buffer", &gWmtIdcInfo.buffer[0], readlen); + + while (readlen) { + p_data = &gWmtIdcInfo.buffer[0]; + p_data += 2; /*omit direction & opcode 2 bytes */ + osal_memcpy(&msg_len, p_data, 2); + WMT_DBG_FUNC("current raw data len(%d) from connsys firmware\n", msg_len); + + msg_len = msg_len > LTE_IDC_BUFFER_MAX_SIZE ? LTE_IDC_BUFFER_MAX_SIZE : msg_len; + osal_memset(&gWmtIdcInfo.buffer[0], 0, LTE_IDC_BUFFER_MAX_SIZE); + readlen = mtk_wcn_stp_receive_data(&gWmtIdcInfo.buffer[0], msg_len, COEX_TASK_INDX); + p_data = &gWmtIdcInfo.buffer[0]; + + if (msg_len > 0) + msg_len -= 1; /*flag byte */ + else + WMT_ERR_FUNC("msg_len is ERROR!"); + + /*how to handle flag(msg type) need to Scott comment */ + /************************************************/ + + if (*p_data == WMT_IDC_RX_OPCODE_DEBUG_MONITOR) + /*do not need transfer to LTE */ + { + p_data += 1; /*flag : 1 byte */ + /*need to handle these debug message */ + wmt_idc_dump_debug_msg("WIFI DEBUG MONITOR", p_data, msg_len); + } else + /*need to transfer to LTE */ + { + p_lps = + (struct local_para *) osal_malloc(osal_sizeof(struct local_para) + + osal_sizeof(UINT8) * msg_len); + if (p_lps == NULL) { + WMT_ERR_FUNC("allocate struct local_para memory fail\n"); + return -1; + } + + p_lps->msg_len = msg_len + osal_sizeof(struct local_para); + + opcode = *p_data; + WMT_DBG_FUNC("current opcode(%d) to LTE\n", opcode); + + p_data += 1; /*flag : 1 byte */ + osal_memcpy(p_lps->data, p_data, msg_len); + + gWmtIdcInfo.iit.local_para_ptr = p_lps; + +#if CFG_WMT_LTE_ENABLE_MSGID_MAPPING + switch (opcode) { + case WMT_IDC_RX_OPCODE_BTWF_DEF_PARA: + gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_DEFAULT_PARAM_IND; + break; + case WMT_IDC_RX_OPCODE_BTWF_CHAN_RAN: + gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_FREQ_IND; + break; + case WMT_IDC_RX_OPCODE_LTE_FREQ_IDX_TABLE: + gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_FREQ_IDX_TABLE_IND; + break; + case WMT_IDC_RX_OPCODE_BTWF_PROFILE_IND: + gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_PROFILE_IND; + break; + case WMT_IDC_RX_OPCODE_UART_PIN_SEL: + gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_PIN_TYPE_IND; + break; + /* case WMT_IDC_RX_OPCODE_TDM_REQ: */ + /* gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_FREQ_IND; */ + /* break; */ + default: + unknown_msgid = MTK_WCN_BOOL_TRUE; + WMT_ERR_FUNC("unknown opcode(%d) from connsys firmware\n", opcode); + break; + } + if (unknown_msgid == MTK_WCN_BOOL_FALSE) { + /*handling flag value in wmt cmd */ + mtk_conn_md_bridge_send_msg(&gWmtIdcInfo.iit); + } +#else + if (opcode >= LTE_MSG_ID_OFFSET) { + gWmtIdcInfo.iit.msg_id = + opcode + IPC_EL1_MSG_ID_BEGIN - LTE_MSG_ID_OFFSET + 1; + /*handling flag value in wmt cmd */ + if (gWmtIdcInfo.iit.msg_id == IPC_MSG_ID_MD_CONSYS_VERIFICATION_REQ) + gWmtIdcInfo.iit.dest_mod_id = MD_MOD_GMMGR; + else + gWmtIdcInfo.iit.dest_mod_id = MD_MOD_EL1; + + mtk_conn_md_bridge_send_msg(&gWmtIdcInfo.iit); + WMT_DBG_FUNC("CONN->LTE: (0x%x->0x%x)\n", opcode, + gWmtIdcInfo.iit.msg_id); + } else + WMT_ERR_FUNC("opcode(%d)from connsys fw is out of range,drop it!\n", + opcode); +#endif + osal_free(p_lps); + } + + osal_memset(&gWmtIdcInfo.buffer[0], 0, LTE_IDC_BUFFER_MAX_SIZE); + readlen = mtk_wcn_stp_receive_data(&gWmtIdcInfo.buffer[0], 4, COEX_TASK_INDX); + WMT_DBG_FUNC("read data len from fw(%d)\n", readlen); + } + + } else + WMT_ERR_FUNC("there is no coex data in stp buffer\n"); + + osal_memset(&gWmtIdcInfo.buffer[0], 0, LTE_IDC_BUFFER_MAX_SIZE); + + return 0; +} + +UINT32 wmt_idc_msg_to_lte_handing_for_test(PUINT8 p_buf, UINT32 len) +{ + UINT32 readlen = len; + struct local_para *p_lps = NULL; + PUINT8 p_data = NULL; + UINT8 opcode = 0; + UINT16 msg_len = 0; + MTK_WCN_BOOL unknown_msgid = MTK_WCN_BOOL_FALSE; + + osal_memcpy(&gWmtIdcInfo.buffer[0], p_buf, len); + + if (readlen > 0) { + WMT_DBG_FUNC("read data len from fw(%d)\n", readlen); + + while (readlen) { + p_data = &gWmtIdcInfo.buffer[0]; + p_data += 2; /*omit direction & opcode 2 bytes */ + osal_memcpy(&msg_len, p_data, 2); + + msg_len = msg_len > LTE_IDC_BUFFER_MAX_SIZE ? LTE_IDC_BUFFER_MAX_SIZE : msg_len; + osal_memset(&gWmtIdcInfo.buffer[0], 0, LTE_IDC_BUFFER_MAX_SIZE); + readlen = mtk_wcn_stp_receive_data(&gWmtIdcInfo.buffer[0], msg_len, COEX_TASK_INDX); + p_data = &gWmtIdcInfo.buffer[0]; + + if (msg_len > 0) + msg_len -= 1; /*flag byte */ + else + WMT_ERR_FUNC("msg_len is ERROR!"); + WMT_DBG_FUNC("current raw data len(%d) from connsys firmware\n", msg_len); + + /*how to handle flag(msg type) need to Scott comment */ + /************************************************/ + + if (*p_data == WMT_IDC_RX_OPCODE_DEBUG_MONITOR) + /*do not need transfer to LTE */ + { + p_data += 1; /*flag : 1 byte */ + /*need to handle these debug message */ + wmt_idc_dump_debug_msg("WIFI DEBUG MONITOR", p_data, msg_len); + } else { + /*need to transfer to LTE */ + p_lps = (struct local_para *) osal_malloc(osal_sizeof(struct local_para) + + osal_sizeof(UINT8) * msg_len); + if (p_lps == NULL) { + WMT_ERR_FUNC("allocate struct local_para memory fail\n"); + return -1; + } + + p_lps->msg_len = msg_len + osal_sizeof(struct local_para); + + opcode = *p_data; + WMT_DBG_FUNC("current opcode(%d) to LTE\n", opcode); + + p_data += 1; /*flag : 1 byte */ + osal_memcpy(p_lps->data, p_data, msg_len); + + gWmtIdcInfo.iit.local_para_ptr = p_lps; + + switch (opcode) { + case WMT_IDC_RX_OPCODE_BTWF_DEF_PARA: + gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_DEFAULT_PARAM_IND; + break; + case WMT_IDC_RX_OPCODE_BTWF_CHAN_RAN: + gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_FREQ_IND; + break; + /* case WMT_IDC_RX_OPCODE_TDM_REQ: */ + /* gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_FREQ_IND; */ + /* break; */ + default: + unknown_msgid = MTK_WCN_BOOL_TRUE; + WMT_ERR_FUNC("unknown opcode(%d) from connsys firmware\n", opcode); + } + if (unknown_msgid == MTK_WCN_BOOL_FALSE) { + /*handling flag value in wmt cmd */ + mtk_conn_md_bridge_send_msg(&gWmtIdcInfo.iit); + } + osal_free(p_lps); + } + + osal_memset(&gWmtIdcInfo.buffer[0], 0, LTE_IDC_BUFFER_MAX_SIZE); + readlen = mtk_wcn_stp_receive_data(&gWmtIdcInfo.buffer[0], 4, COEX_TASK_INDX); + } + + } else + WMT_ERR_FUNC("there is no coex data in stp buffer\n"); + + osal_memset(&gWmtIdcInfo.buffer[0], 0, LTE_IDC_BUFFER_MAX_SIZE); + + return 0; +} +#endif /* CFG_WMT_LTE_COEX_HANDLING */ diff --git a/drivers/misc/mediatek/connectivity/common/common_main/linux/wmt_proc_dbg.c b/drivers/misc/mediatek/connectivity/common/common_main/linux/wmt_proc_dbg.c new file mode 100644 index 0000000000000000000000000000000000000000..bb26f2dd0ec13298271c448cb6e38f48d33ed491 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/linux/wmt_proc_dbg.c @@ -0,0 +1,299 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include +#include "osal.h" +#include "wmt_core.h" +#include "wmt_lib.h" +#include "wmt_proc_dbg.h" + +#if CFG_WMT_PROC_FOR_AEE +static struct proc_dir_entry *gWmtAeeEntry; +#define WMT_AEE_PROCNAME "driver/wmt_aee" +#define WMT_PROC_AEE_SIZE 3072 +static UINT32 g_buf_len; +static PUINT8 pBuf; + +static OSAL_SLEEPABLE_LOCK g_aee_read_lock; +#endif + + +#if CFG_WMT_PROC_FOR_DUMP_INFO + +static struct proc_dir_entry *gWmtdumpinfoEntry; +#define WMT_DUMP_INFO_PROCNAME "driver/wmt_dump_info" +static CONSYS_STATE_DMP_INFO g_dmp_info; +static UINT32 g_dump_info_buf_len; +static UINT8 dmp_info_buf[DBG_LOG_STR_SIZE]; +static PUINT8 dmp_info_buf_ptr; + +static OSAL_SLEEPABLE_LOCK g_dump_info_read_lock; + +static ssize_t wmt_dev_proc_for_dump_info_read(struct file *filp, char __user *buf, size_t count, + loff_t *f_pos) +{ + INT32 retval = 0; + UINT32 len = 0; + INT32 i, dmp_cnt = 5; + + WMT_INFO_FUNC("%s: count %lu pos %lld\n", __func__, count, *f_pos); + + if (osal_lock_sleepable_lock(&g_dump_info_read_lock)) { + WMT_ERR_FUNC("lock failed\n"); + return 0; + } + + if (*f_pos == 0) { + g_dump_info_buf_len = 0; + if (wmt_lib_dmp_consys_state(&g_dmp_info, dmp_cnt, 0) == MTK_WCN_BOOL_TRUE) { + g_dump_info_buf_len = len; + memset(dmp_info_buf, '\0', DBG_LOG_STR_SIZE); + g_dump_info_buf_len = 0; + g_dump_info_buf_len += snprintf(dmp_info_buf + g_dump_info_buf_len, + DBG_LOG_STR_SIZE - g_dump_info_buf_len, + "0x%08x", g_dmp_info.cpu_pcr[0]); + + for (i = 1; i < dmp_cnt; i++) + g_dump_info_buf_len += snprintf(dmp_info_buf + g_dump_info_buf_len, + DBG_LOG_STR_SIZE - g_dump_info_buf_len, + ";0x%08x", g_dmp_info.cpu_pcr[i]); + + g_dump_info_buf_len += snprintf(dmp_info_buf + g_dump_info_buf_len, + DBG_LOG_STR_SIZE - g_dump_info_buf_len, ";0x%08x", g_dmp_info.state.lp[1]); + + g_dump_info_buf_len += snprintf(dmp_info_buf + g_dump_info_buf_len, + DBG_LOG_STR_SIZE - g_dump_info_buf_len, ";0x%08x", g_dmp_info.state.gating[1]); + + g_dump_info_buf_len += snprintf(dmp_info_buf + g_dump_info_buf_len, + DBG_LOG_STR_SIZE - len, + ";[0x%08x", g_dmp_info.state.sw_state.info_time); + + g_dump_info_buf_len += snprintf(dmp_info_buf + g_dump_info_buf_len, + DBG_LOG_STR_SIZE - len, + ";0x%08x", g_dmp_info.state.sw_state.is_gating); + g_dump_info_buf_len += snprintf(dmp_info_buf + g_dump_info_buf_len, + DBG_LOG_STR_SIZE - len, + ";0x%08x", g_dmp_info.state.sw_state.resource_disable_sleep); + g_dump_info_buf_len += snprintf(dmp_info_buf + g_dump_info_buf_len, + DBG_LOG_STR_SIZE - len, + ";0x%08x", g_dmp_info.state.sw_state.clock_hif_ctrl); + g_dump_info_buf_len += snprintf(dmp_info_buf + g_dump_info_buf_len, + DBG_LOG_STR_SIZE - len, + ";0x%08x", g_dmp_info.state.sw_state.clock_umac_ctrl); + g_dump_info_buf_len += snprintf(dmp_info_buf + g_dump_info_buf_len, + DBG_LOG_STR_SIZE - len, + ";0x%08x", g_dmp_info.state.sw_state.clock_mcu); + g_dump_info_buf_len += snprintf(dmp_info_buf + g_dump_info_buf_len, + DBG_LOG_STR_SIZE - len, + ";0x%08x]", g_dmp_info.state.sw_state.sub_system); + + + dmp_info_buf_ptr = dmp_info_buf; + } + + WMT_INFO_FUNC("wmt_dev:wmt for dump info buffer len(%d)\n", g_dump_info_buf_len); + } + + if (g_dump_info_buf_len >= count) { + retval = copy_to_user(buf, dmp_info_buf_ptr, count); + if (retval) { + WMT_ERR_FUNC("copy to dump info buffer failed, ret:%d\n", retval); + retval = -EFAULT; + goto dump_info_err_exit; + } + + *f_pos += count; + g_dump_info_buf_len -= count; + dmp_info_buf_ptr += count; + WMT_INFO_FUNC("wmt_dev:after read,wmt for dump info buffer len(%d)\n", g_dump_info_buf_len); + + retval = count; + } else if (g_dump_info_buf_len != 0) { + retval = copy_to_user(buf, dmp_info_buf_ptr, g_dump_info_buf_len); + if (retval) { + WMT_ERR_FUNC("copy to dump info buffer failed, ret:%d\n", retval); + retval = -EFAULT; + goto dump_info_err_exit; + } + + *f_pos += g_dump_info_buf_len; + len = g_dump_info_buf_len; + g_dump_info_buf_len = 0; + dmp_info_buf_ptr += len; + retval = len; + WMT_INFO_FUNC("wmt_dev:after read,wmt for dump info buffer len(%d)\n", g_dump_info_buf_len); + } else { + WMT_INFO_FUNC("wmt_dev: no data available for dump info\n"); + retval = 0; + } + +dump_info_err_exit: + osal_unlock_sleepable_lock(&g_dump_info_read_lock); + + return retval; +} + +static ssize_t wmt_dev_proc_for_dump_info_write(struct file *filp, const char __user *buf, size_t count, + loff_t *f_pos) +{ + WMT_TRC_FUNC(); + return 0; +} + +INT32 wmt_dev_proc_for_dump_info_setup(VOID) +{ + static const struct file_operations wmt_dump_info_fops = { + .owner = THIS_MODULE, + .read = wmt_dev_proc_for_dump_info_read, + .write = wmt_dev_proc_for_dump_info_write, + }; + + osal_sleepable_lock_init(&g_dump_info_read_lock); + + gWmtdumpinfoEntry = proc_create(WMT_DUMP_INFO_PROCNAME, 0664, NULL, &wmt_dump_info_fops); + if (gWmtdumpinfoEntry == NULL) { + WMT_ERR_FUNC("Unable to create /proc entry\n\r"); + return -1; + } + + return 0; +} + +INT32 wmt_dev_proc_for_dump_info_remove(VOID) +{ + if (gWmtdumpinfoEntry != NULL) + remove_proc_entry(WMT_DUMP_INFO_PROCNAME, NULL); + osal_sleepable_lock_deinit(&g_dump_info_read_lock); + + return 0; +} +#endif /* CFG_WMT_PROC_FOR_DUMP_INFO */ + +#if CFG_WMT_PROC_FOR_AEE +static ssize_t wmt_dev_proc_for_aee_read(struct file *filp, char __user *buf, size_t count, + loff_t *f_pos) +{ + INT32 retval = 0; + UINT32 len = 0; + + WMT_INFO_FUNC("%s: count %lu pos %lld\n", __func__, count, *f_pos); + + if (osal_lock_sleepable_lock(&g_aee_read_lock)) { + WMT_ERR_FUNC("lock failed\n"); + return 0; + } + + if (*f_pos == 0) { + pBuf = wmt_lib_get_cpupcr_xml_format(&len); + g_buf_len = len; + WMT_INFO_FUNC("wmt_dev:wmt for aee buffer len(%d)\n", g_buf_len); + } + + if (g_buf_len >= count) { + retval = copy_to_user(buf, pBuf, count); + if (retval) { + WMT_ERR_FUNC("copy to aee buffer failed, ret:%d\n", retval); + retval = -EFAULT; + goto err_exit; + } + + *f_pos += count; + g_buf_len -= count; + pBuf += count; + WMT_INFO_FUNC("wmt_dev:after read,wmt for aee buffer len(%d)\n", g_buf_len); + + retval = count; + } else if (g_buf_len != 0) { + retval = copy_to_user(buf, pBuf, g_buf_len); + if (retval) { + WMT_ERR_FUNC("copy to aee buffer failed, ret:%d\n", retval); + retval = -EFAULT; + goto err_exit; + } + + *f_pos += g_buf_len; + len = g_buf_len; + g_buf_len = 0; + pBuf += len; + retval = len; + WMT_INFO_FUNC("wmt_dev:after read,wmt for aee buffer len(%d)\n", g_buf_len); + } else { + WMT_INFO_FUNC("wmt_dev: no data available for aee\n"); + retval = 0; + } + +err_exit: + osal_unlock_sleepable_lock(&g_aee_read_lock); + + return retval; +} + +static ssize_t wmt_dev_proc_for_aee_write(struct file *filp, const char __user *buf, size_t count, + loff_t *f_pos) +{ + WMT_TRC_FUNC(); + return 0; +} + +INT32 wmt_dev_proc_for_aee_setup(VOID) +{ + static const struct file_operations wmt_aee_fops = { + .owner = THIS_MODULE, + .read = wmt_dev_proc_for_aee_read, + .write = wmt_dev_proc_for_aee_write, + }; + + osal_sleepable_lock_init(&g_aee_read_lock); + gWmtAeeEntry = proc_create(WMT_AEE_PROCNAME, 0664, NULL, &wmt_aee_fops); + if (gWmtAeeEntry == NULL) { + WMT_ERR_FUNC("Unable to create /proc entry\n\r"); + return -1; + } + + return 0; +} + +INT32 wmt_dev_proc_for_aee_remove(VOID) +{ + if (gWmtAeeEntry != NULL) + remove_proc_entry(WMT_AEE_PROCNAME, NULL); + osal_sleepable_lock_deinit(&g_aee_read_lock); + + return 0; +} +#endif /* CFG_WMT_PROC_FOR_AEE */ + + + +INT32 wmt_dev_proc_init(VOID) +{ + int ret = 0; +#if CFG_WMT_PROC_FOR_DUMP_INFO + ret = wmt_dev_proc_for_dump_info_setup(); + if (ret) + return ret; +#endif + +#if CFG_WMT_PROC_FOR_AEE + ret = wmt_dev_proc_for_aee_setup(); +#endif + return ret; +} +INT32 wmt_dev_proc_deinit(VOID) +{ + int ret = 0; + +#if CFG_WMT_PROC_FOR_DUMP_INFO + ret = wmt_dev_proc_for_dump_info_remove(); + if (ret) + return ret; +#endif +#if CFG_WMT_PROC_FOR_AEE + ret = wmt_dev_proc_for_aee_remove(); +#endif + return ret; +} + + diff --git a/drivers/misc/mediatek/connectivity/common/common_main/linux/wmt_step.c b/drivers/misc/mediatek/connectivity/common/common_main/linux/wmt_step.c new file mode 100644 index 0000000000000000000000000000000000000000..b76414ff212ae176d443d0f7f831120462f4326a --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/linux/wmt_step.c @@ -0,0 +1,2433 @@ +/* + * Copyright (C) 2016 MediaTek Inc. * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +#include +#include + +#include "osal.h" +#include "wmt_step.h" +#include "wmt_dev.h" +#include "wmt_plat.h" +#include "mtk_wcn_consys_hw.h" +#include "stp_core.h" +#include "wmt_lib.h" + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S +********************************************************************************/ +static struct step_action *wmt_step_create_emi_action(int param_num, char *params[]); +static struct step_action *wmt_step_create_register_action(int param_num, char *params[]); +static struct step_action *wmt_step_create_gpio_action(int param_num, char *params[]); +static struct step_action *wmt_step_create_disable_reset_action(int param_num, char *params[]); +static struct step_action *wmt_step_create_chip_reset_action(int param_num, char *params[]); +static struct step_action *wmt_step_create_keep_wakeup_action(int param_num, char *params[]); +static struct step_action *wmt_step_create_cancel_wakeup_action(int param_num, char *params[]); +static struct step_action *wmt_step_create_periodic_dump_action(int param_num, char *params[]); +static struct step_action *wmt_step_create_show_string_action(int param_num, char *params[]); +static struct step_action *wmt_step_create_sleep_action(int param_num, char *params[]); +static struct step_action *wmt_step_create_condition_action(int param_num, char *params[]); +static struct step_action *wmt_step_create_value_action(int param_num, char *params[]); +static struct step_action *wmt_step_create_condition_emi_action(int param_num, char *params[]); +static struct step_action *wmt_step_create_condition_register_action(int param_num, char *params[]); + +static void wmt_step_remove_emi_action(struct step_action *p_act); +static void wmt_step_remove_register_action(struct step_action *p_act); +static void wmt_step_remove_gpio_action(struct step_action *p_act); +static void wmt_step_remove_disable_reset_action(struct step_action *p_act); +static void wmt_step_remove_chip_reset_action(struct step_action *p_act); +static void wmt_step_remove_keep_wakeup_action(struct step_action *p_act); +static void wmt_step_remove_cancel_wakeup_action(struct step_action *p_act); +static void wmt_step_remove_periodic_dump_action(struct step_action *p_act); +static void wmt_step_remove_show_string_action(struct step_action *p_act); +static void wmt_step_remove_sleep_action(struct step_action *p_act); +static void wmt_step_remove_condition_action(struct step_action *p_act); +static void wmt_step_remove_value_action(struct step_action *p_act); +static void wmt_step_remove_condition_emi_action(struct step_action *p_act); +static void wmt_step_remove_condition_register_action(struct step_action *p_act); + +static int wmt_step_access_line_state_init(char *tok, + struct step_target_act_list_info *p_parse_info, + struct step_parse_line_data_param_info *p_parse_line_info); +static int wmt_step_access_line_state_tp(char *tok, + struct step_target_act_list_info *p_parse_info, + struct step_parse_line_data_param_info *p_parse_line_info); +static int wmt_step_access_line_state_at(char *tok, + struct step_target_act_list_info *p_parse_info, + struct step_parse_line_data_param_info *p_parse_line_info); +static int wmt_step_access_line_state_at_op(char *tok, + struct step_target_act_list_info *p_parse_info, + struct step_parse_line_data_param_info *p_parse_line_info); +static int wmt_step_access_line_state_pd(char *tok, + struct step_target_act_list_info *p_parse_info, + struct step_parse_line_data_param_info *p_parse_line_info); + +static int wmt_step_operator_result_greater(int l_val, int r_val); +static int wmt_step_operator_result_greater_equal(int l_val, int r_val); +static int wmt_step_operator_result_less(int l_val, int r_val); +static int wmt_step_operator_result_less_equal(int l_val, int r_val); +static int wmt_step_operator_result_equal(int l_val, int r_val); +static int wmt_step_operator_result_not_equal(int l_val, int r_val); +static int wmt_step_operator_result_and(int l_val, int r_val); +static int wmt_step_operator_result_or(int l_val, int r_val); + +/******************************************************************************* + * D E F I N E +********************************************************************************/ +#define STEP_EMI_ACT_INT (int)(*(int *)STEP_ACTION_NAME_EMI) +#define STEP_REG_ACT_INT (int)(*(int *)STEP_ACTION_NAME_REGISTER) +#define STEP_GPIO_ACT_INT (int)(*(int *)STEP_ACTION_NAME_GPIO) +#define STEP_DISABLE_RESET_ACT_INT (int)(*(int *)STEP_ACTION_NAME_DISABLE_RESET) +#define STEP_CHIP_RESET_ACT_INT (int)(*(int *)STEP_ACTION_NAME_CHIP_RESET) +#define STEP_KEEP_WAKEUP_ACT_INT (int)(*(int *)STEP_ACTION_NAME_KEEP_WAKEUP) +#define STEP_CANCEL_KEEP_WAKEUP_ACT_INT (int)(*(int *)STEP_ACTION_NAME_CANCEL_WAKEUP) +#define STEP_SHOW_STRING_ACT_INT (int)(*(int *)STEP_ACTION_NAME_SHOW_STRING) +#define STEP_SLEEP_ACT_INT (int)(*(int *)STEP_ACTION_NAME_SLEEP) +#define STEP_CONDITION_ACT_INT (int)(*(int *)STEP_ACTION_NAME_CONDITION) +#define STEP_VALUE_ACT_INT (int)(*(int *)STEP_ACTION_NAME_VALUE) +#define STEP_CONDITION_EMI_ACT_INT (int)(*(int *)STEP_ACTION_NAME_CONDITION_EMI) +#define STEP_CONDITION_REG_ACT_INT (int)(*(int *)STEP_ACTION_NAME_CONDITION_REGISTER) + +#define STEP_PARSE_LINE_STATE_INIT 0 +#define STEP_PARSE_LINE_STATE_TP 1 +#define STEP_PARSE_LINE_STATE_AT 2 +#define STEP_PARSE_LINE_STATE_AT_OP 3 +#define STEP_PARSE_LINE_STATE_PD_START 4 +#define STEP_PARSE_LINE_STATE_PD_END 5 +/******************************************************************************* + * P R I V A T E D A T A +********************************************************************************/ +struct step_env_struct g_step_env; + +static const struct step_action_contrl wmt_step_action_map[] = { + [STEP_ACTION_INDEX_EMI] = { + wmt_step_create_emi_action, + wmt_step_do_emi_action, + wmt_step_remove_emi_action + }, + [STEP_ACTION_INDEX_REGISTER] = { + wmt_step_create_register_action, + wmt_step_do_register_action, + wmt_step_remove_register_action + }, + [STEP_ACTION_INDEX_GPIO] = { + wmt_step_create_gpio_action, + wmt_step_do_gpio_action, + wmt_step_remove_gpio_action + }, + [STEP_ACTION_INDEX_DISABLE_RESET] = { + wmt_step_create_disable_reset_action, + wmt_step_do_disable_reset_action, + wmt_step_remove_disable_reset_action + }, + [STEP_ACTION_INDEX_CHIP_RESET] = { + wmt_step_create_chip_reset_action, + wmt_step_do_chip_reset_action, + wmt_step_remove_chip_reset_action + }, + [STEP_ACTION_INDEX_KEEP_WAKEUP] = { + wmt_step_create_keep_wakeup_action, + wmt_step_do_keep_wakeup_action, + wmt_step_remove_keep_wakeup_action + }, + [STEP_ACTION_INDEX_CANCEL_WAKEUP] = { + wmt_step_create_cancel_wakeup_action, + wmt_step_do_cancel_wakeup_action, + wmt_step_remove_cancel_wakeup_action + }, + [STEP_ACTION_INDEX_PERIODIC_DUMP] = { + wmt_step_create_periodic_dump_action, + wmt_step_do_periodic_dump_action, + wmt_step_remove_periodic_dump_action, + }, + [STEP_ACTION_INDEX_SHOW_STRING] = { + wmt_step_create_show_string_action, + wmt_step_do_show_string_action, + wmt_step_remove_show_string_action + }, + [STEP_ACTION_INDEX_SLEEP] = { + wmt_step_create_sleep_action, + wmt_step_do_sleep_action, + wmt_step_remove_sleep_action + }, + [STEP_ACTION_INDEX_CONDITION] = { + wmt_step_create_condition_action, + wmt_step_do_condition_action, + wmt_step_remove_condition_action + }, + [STEP_ACTION_INDEX_VALUE] = { + wmt_step_create_value_action, + wmt_step_do_value_action, + wmt_step_remove_value_action + }, + [STEP_ACTION_INDEX_CONDITION_EMI] = { + wmt_step_create_condition_emi_action, + wmt_step_do_condition_emi_action, + wmt_step_remove_condition_emi_action + }, + [STEP_ACTION_INDEX_CONDITION_REGISTER] = { + wmt_step_create_condition_register_action, + wmt_step_do_condition_register_action, + wmt_step_remove_condition_register_action + }, +}; + +static const char * const STEP_TRIGGER_TIME_NAME[] = { + [STEP_TRIGGER_POINT_COMMAND_TIMEOUT] = + "[TP 1] When Command timeout", + [STEP_TRIGGER_POINT_FIRMWARE_TRIGGER_ASSERT] = + "[TP 2] When Firmware trigger assert", + [STEP_TRIGGER_POINT_BEFORE_CHIP_RESET] = + "[TP 3] Before Chip reset", + [STEP_TRIGGER_POINT_AFTER_CHIP_RESET] = + "[TP 4] After Chip reset", + [STEP_TRIGGER_POINT_BEFORE_WIFI_FUNC_ON] = + "[TP 5] Before Wifi function on", + [STEP_TRIGGER_POINT_BEFORE_WIFI_FUNC_OFF] = + "[TP 6] Before Wifi function off", + [STEP_TRIGGER_POINT_BEFORE_BT_FUNC_ON] = + "[TP 7] Before BT function on", + [STEP_TRIGGER_POINT_BEFORE_BT_FUNC_OFF] = + "[TP 8] Before BT function off", + [STEP_TRIGGER_POINT_BEFORE_FM_FUNC_ON] = + "[TP 9] Before FM function on", + [STEP_TRIGGER_POINT_BEFORE_FM_FUNC_OFF] = + "[TP 10] Before FM function off", + [STEP_TRIGGER_POINT_BEFORE_GPS_FUNC_ON] = + "[TP 11] Before GPS function on", + [STEP_TRIGGER_POINT_BEFORE_GPS_FUNC_OFF] = + "[TP 12] Before GPS function off", + [STEP_TRIGGER_POINT_BEFORE_READ_THERMAL] = + "[TP 13] Before read consys thermal", + [STEP_TRIGGER_POINT_POWER_ON_START] = + "[TP 14] Power on sequence(0): Start power on", + [STEP_TRIGGER_POINT_POWER_ON_BEFORE_GET_CONNSYS_ID] = + "[TP 15] Power on sequence(1): Before can get connsys id", + [STEP_TRIGGER_POINT_POWER_ON_BEFORE_SEND_DOWNLOAD_PATCH] = + "[TP 16] Power on sequence(2): Before send download patch", + [STEP_TRIGGER_POINT_POWER_ON_BEFORE_CONNSYS_RESET] = + "[TP 17] Power on sequence(3): Before connsys reset (donwload patch)", + [STEP_TRIGGER_POINT_POWER_ON_BEFORE_SET_WIFI_LTE_COEX] = + "[TP 18] Power on sequence(4): Before set wifi and lte coex", + [STEP_TRIGGER_POINT_POWER_ON_BEFORE_BT_WIFI_CALIBRATION] = + "[TP 19] Power on sequence(5): Before set BT and Wifi calibration", + [STEP_TRIGGER_POINT_POWER_ON_END] = + "[TP 20] Power on sequence(6): End power on", + [STEP_TRIGGER_POINT_BEFORE_POWER_OFF] = + "[TP 21] Before WMT power off", + [STEP_TRIGGER_POINT_WHEN_AP_SUSPEND] = + "[TP 22] When AP suspend", + [STEP_TRIGGER_POINT_WHEN_AP_RESUME] = + "[TP 23] When AP resume", + [STEP_TRIGGER_POINT_POWER_OFF_HANDSHAKE] = + "[TP 24] When power off handshake", + [STEP_TRIGGER_POINT_BEFORE_RESTORE_CAL_RESULT] = + "[TP 25] Before restore calibration result", + [STEP_TRIGGER_POINT_AFTER_RESTORE_CAL_RESULT] = + "[TP 26] After restore calibration result", + [STEP_TRIGGER_POINT_POWER_ON_AFTER_BT_WIFI_CALIBRATION] = + "[TP 27] Power on sequence(5): After BT and Wi-Fi calibration", + [STEP_TRIGGER_POINT_AFTER_RESTORE_CAL_CMD] = + "[TP 28] After send calibration restore command", + [STEP_TRIGGER_POINT_WHEN_CLOCK_FAIL] = + "[TP 29] When clock fail", + [STEP_TRIGGER_POINT_BEFORE_GPSL5_FUNC_ON] = + "[TP 30] Before GPSL5 function on", + [STEP_TRIGGER_POINT_BEFORE_GPSL5_FUNC_OFF] = + "[TP 31] Before GPSL5 function off", +}; + +static const int wmt_step_func_ctrl_id[WMTDRV_TYPE_MAX][2] = { + [WMTDRV_TYPE_BT] = { + STEP_TRIGGER_POINT_BEFORE_BT_FUNC_OFF, + STEP_TRIGGER_POINT_BEFORE_BT_FUNC_ON + }, + [WMTDRV_TYPE_FM] = { + STEP_TRIGGER_POINT_BEFORE_FM_FUNC_OFF, + STEP_TRIGGER_POINT_BEFORE_FM_FUNC_ON + }, + [WMTDRV_TYPE_GPS] = { + STEP_TRIGGER_POINT_BEFORE_GPS_FUNC_OFF, + STEP_TRIGGER_POINT_BEFORE_GPS_FUNC_ON + }, + [WMTDRV_TYPE_WIFI] = { + STEP_TRIGGER_POINT_BEFORE_WIFI_FUNC_OFF, + STEP_TRIGGER_POINT_BEFORE_WIFI_FUNC_ON + }, + [WMTDRV_TYPE_GPSL5] = { + STEP_TRIGGER_POINT_BEFORE_GPSL5_FUNC_OFF, + STEP_TRIGGER_POINT_BEFORE_GPSL5_FUNC_ON + }, +}; + +typedef int (*STEP_LINE_STATE) (char *, + struct step_target_act_list_info *, struct step_parse_line_data_param_info *); +static const STEP_LINE_STATE wmt_step_line_state_action_map[] = { + [STEP_PARSE_LINE_STATE_INIT] = wmt_step_access_line_state_init, + [STEP_PARSE_LINE_STATE_TP] = wmt_step_access_line_state_tp, + [STEP_PARSE_LINE_STATE_AT] = wmt_step_access_line_state_at, + [STEP_PARSE_LINE_STATE_AT_OP] = wmt_step_access_line_state_at_op, + [STEP_PARSE_LINE_STATE_PD_START] = wmt_step_access_line_state_pd, +}; + +typedef int (*STEP_OPERATOR_RESULT) (int, int); +static const STEP_OPERATOR_RESULT wmt_step_operator_result_map[] = { + [STEP_OPERATOR_GREATER] = wmt_step_operator_result_greater, + [STEP_OPERATOR_GREATER_EQUAL] = wmt_step_operator_result_greater_equal, + [STEP_OPERATOR_LESS] = wmt_step_operator_result_less, + [STEP_OPERATOR_LESS_EQUAL] = wmt_step_operator_result_less_equal, + [STEP_OPERATOR_EQUAL] = wmt_step_operator_result_equal, + [STEP_OPERATOR_NOT_EQUAL] = wmt_step_operator_result_not_equal, + [STEP_OPERATOR_AND] = wmt_step_operator_result_and, + [STEP_OPERATOR_OR] = wmt_step_operator_result_or, +}; + +/******************************************************************************* + * I N T E R N A L F U N C T I O N S +********************************************************************************/ +#ifdef CFG_WMT_STEP +static void wmt_step_init_list(void) +{ + unsigned int i = 0; + + for (i = 0; i < STEP_TRIGGER_POINT_MAX; i++) + INIT_LIST_HEAD(&(g_step_env.actions[i].list)); +} +#endif + +static unsigned char __iomem *wmt_step_get_emi_base_address(void) +{ + if (g_step_env.emi_base_addr == NULL) { + if (gConEmiPhyBase) + g_step_env.emi_base_addr = ioremap_nocache(gConEmiPhyBase, gConEmiSize); + } + + return g_step_env.emi_base_addr; +} + +static void _wmt_step_init_register_base_size(struct device_node *node, int index, int step_index, unsigned long addr) +{ + int flag; + + if (step_index < 0) + return; + + g_step_env.reg_base[step_index].vir_addr = addr; + if (addr != 0) + of_get_address(node, index, &(g_step_env.reg_base[step_index].size), &flag); +} + +static void wmt_step_init_register_base_size(void) +{ + struct device_node *node = NULL; + + /* If you need to change the register index, address. Please update STEP Config comment */ + if (g_pdev != NULL) { + node = g_pdev->dev.of_node; + _wmt_step_init_register_base_size(node, STEP_MCU_BASE_INDEX, + STEP_REGISTER_CONN_MCU_CONFIG_BASE, conn_reg.mcu_base); + _wmt_step_init_register_base_size(node, STEP_TOP_RGU_BASE_INDEX, + STEP_REGISTER_AP_RGU_BASE, conn_reg.ap_rgu_base); + _wmt_step_init_register_base_size(node, STEP_INFRACFG_AO_BASE_INDEX, + STEP_REGISTER_TOPCKGEN_BASE, conn_reg.topckgen_base); + _wmt_step_init_register_base_size(node, STEP_SPM_BASE_INDEX, + STEP_REGISTER_SPM_BASE, conn_reg.spm_base); + _wmt_step_init_register_base_size(node, STEP_MCU_CONN_HIF_ON_BASE_INDEX, + STEP_REGISTER_HIF_ON_BASE, conn_reg.mcu_conn_hif_on_base); + _wmt_step_init_register_base_size(node, STEP_MCU_TOP_MISC_OFF_BASE_INDEX, + STEP_REGISTER_MISC_OFF_BASE, conn_reg.mcu_top_misc_off_base); + _wmt_step_init_register_base_size(node, STEP_MCU_CFG_ON_BASE_INDEX, + STEP_REGISTER_CFG_ON_BASE, conn_reg.mcu_cfg_on_base); + _wmt_step_init_register_base_size(node, STEP_MCU_CIRQ_BASE_INDEX, + STEP_CIRQ_BASE, conn_reg.mcu_cirq_base); + _wmt_step_init_register_base_size(node, STEP_MCU_TOP_MISC_ON_BASE_INDEX, + STEP_MCU_TOP_MISC_ON_BASE, conn_reg.mcu_top_misc_on_base); + } +} + +static void wmt_step_clear_action_list(struct step_action_list *action_list) +{ + struct step_action *p_act = NULL, *p_act_next = NULL; + + list_for_each_entry_safe(p_act, p_act_next, &(action_list->list), list) { + list_del_init(&p_act->list); + wmt_step_remove_action(p_act); + } +} + +static void wmt_step_clear_list(void) +{ + unsigned int i = 0; + + for (i = 0; i < STEP_TRIGGER_POINT_MAX; i++) + wmt_step_clear_action_list(&g_step_env.actions[i]); +} + +static void wmt_step_unioremap_emi(void) +{ + if (g_step_env.emi_base_addr != NULL) { + iounmap(g_step_env.emi_base_addr); + g_step_env.emi_base_addr = NULL; + } +} + +static unsigned char *mtk_step_get_emi_virt_addr(unsigned char *emi_base_addr, unsigned int offset) +{ + unsigned char *p_virtual_addr = NULL; + + if (offset > gConEmiSize) { + WMT_ERR_FUNC("STEP failed: offset size %d over MAX size(%llu)\n", offset, + gConEmiSize); + return NULL; + } + p_virtual_addr = emi_base_addr + offset; + + return p_virtual_addr; +} + +static int wmt_step_get_cfg(const char *p_patch_name, osal_firmware **pp_patch) +{ + osal_firmware *fw = NULL; + + *pp_patch = NULL; + if (request_firmware((const struct firmware **)&fw, p_patch_name, NULL) != 0) { + release_firmware(fw); + return -1; + } + + WMT_DBG_FUNC("Load step cfg %s ok!!\n", p_patch_name); + *pp_patch = fw; + + return 0; +} + +static void wmt_step_sleep_or_delay(int ms) +{ + /* msleep < 20ms can sleep for up to 20ms */ + if (ms < 20) + udelay(ms * 1000); + else + osal_sleep_ms(ms); +} + +static unsigned char wmt_step_to_upper(char str) +{ + if ((str >= 'a') && (str <= 'z')) + return str + ('A' - 'a'); + else + return str; +} + +static void wmt_step_string_to_upper(char *tok) +{ + for (; *tok != '\0'; tok++) + *tok = wmt_step_to_upper(*tok); +} + +static int wmt_step_get_int_from_four_char(char *str) +{ + unsigned char char_array[4]; + int i; + + for (i = 0; i < 4; i++) { + if (*(str + i) == '\0') + return -1; + + char_array[i] = wmt_step_to_upper(*(str + i)); + } + + return *(int *)char_array; +} + +static enum step_trigger_point_id wmt_step_parse_tp_id(char *str) +{ + long tp_id = STEP_TRIGGER_POINT_NO_DEFINE; + + if (osal_strtol(str, 10, &tp_id)) { + WMT_ERR_FUNC("STEP failed: str to value %s\n", str); + return STEP_TRIGGER_POINT_NO_DEFINE; + } + if (tp_id <= STEP_TRIGGER_POINT_NO_DEFINE || tp_id >= STEP_TRIGGER_POINT_MAX) + return STEP_TRIGGER_POINT_NO_DEFINE; + + return (enum step_trigger_point_id)tp_id; +} + +static int wmt_step_parse_pd_expires(PINT8 ptr) +{ + long expires_ms; + + if (osal_strtol(ptr, 0, &expires_ms)) + return -1; + + return (int)expires_ms; +} + +static int wmt_step_parse_act_id(char *str) +{ + int str_to_int = STEP_ACTION_INDEX_NO_DEFINE; + + if (str == NULL) + return STEP_ACTION_INDEX_NO_DEFINE; + + str_to_int = wmt_step_get_int_from_four_char(str); + if (str_to_int == STEP_EMI_ACT_INT) + return STEP_ACTION_INDEX_EMI; + else if (str_to_int == STEP_REG_ACT_INT) + return STEP_ACTION_INDEX_REGISTER; + else if (str_to_int == STEP_GPIO_ACT_INT) + return STEP_ACTION_INDEX_GPIO; + else if (str_to_int == STEP_DISABLE_RESET_ACT_INT) + return STEP_ACTION_INDEX_DISABLE_RESET; + else if (str_to_int == STEP_CHIP_RESET_ACT_INT) + return STEP_ACTION_INDEX_CHIP_RESET; + else if (str_to_int == STEP_KEEP_WAKEUP_ACT_INT) + return STEP_ACTION_INDEX_KEEP_WAKEUP; + else if (str_to_int == STEP_CANCEL_KEEP_WAKEUP_ACT_INT) + return STEP_ACTION_INDEX_CANCEL_WAKEUP; + else if (str_to_int == STEP_SHOW_STRING_ACT_INT) + return STEP_ACTION_INDEX_SHOW_STRING; + else if (str_to_int == STEP_SLEEP_ACT_INT) + return STEP_ACTION_INDEX_SLEEP; + else if (str_to_int == STEP_CONDITION_ACT_INT) + return STEP_ACTION_INDEX_CONDITION; + else if (str_to_int == STEP_VALUE_ACT_INT) + return STEP_ACTION_INDEX_VALUE; + else if (str_to_int == STEP_CONDITION_EMI_ACT_INT) + return STEP_ACTION_INDEX_CONDITION_EMI; + else if (str_to_int == STEP_CONDITION_REG_ACT_INT) + return STEP_ACTION_INDEX_CONDITION_REGISTER; + else + return STEP_ACTION_INDEX_NO_DEFINE; + +} + +static struct step_action_list *wmt_step_get_tp_list(int tp_id) +{ + if (tp_id <= STEP_TRIGGER_POINT_NO_DEFINE || tp_id >= STEP_TRIGGER_POINT_MAX) { + WMT_ERR_FUNC("STEP failed: Write action to tp_id: %d\n", tp_id); + return NULL; + } + + return &g_step_env.actions[tp_id]; +} + +#define STEP_PARSE_LINE_RET_CONTINUE 0 +#define STEP_PARSE_LINE_RET_BREAK 1 + +static void wmt_step_set_line_state(int *p_state, int value) +{ + *p_state = value; +} + +static int wmt_step_access_line_state_init(char *tok, + struct step_target_act_list_info *p_parse_info, + struct step_parse_line_data_param_info *p_parse_line_info) +{ + wmt_step_string_to_upper(tok); + if (osal_strcmp(tok, "[TP") == 0) { + wmt_step_set_line_state(&p_parse_line_info->state, STEP_PARSE_LINE_STATE_TP); + return STEP_PARSE_LINE_RET_CONTINUE; + } + + if (p_parse_info->tp_id == STEP_TRIGGER_POINT_NO_DEFINE) { + WMT_ERR_FUNC("STEP failed: Set trigger point first: %s\n", tok); + return STEP_PARSE_LINE_RET_BREAK; + } + + if (osal_strcmp(tok, "[PD+]") == 0) { + wmt_step_set_line_state(&p_parse_line_info->state, STEP_PARSE_LINE_STATE_PD_START); + return STEP_PARSE_LINE_RET_CONTINUE; + } + + if (osal_strcmp(tok, "[PD-]") == 0) { + wmt_step_set_line_state(&p_parse_line_info->state, STEP_PARSE_LINE_STATE_PD_END); + return STEP_PARSE_LINE_RET_BREAK; + } + + if (osal_strcmp(tok, "[AT]") == 0) { + wmt_step_set_line_state(&p_parse_line_info->state, STEP_PARSE_LINE_STATE_AT); + return STEP_PARSE_LINE_RET_CONTINUE; + } + + return STEP_PARSE_LINE_RET_BREAK; +} + +static int wmt_step_access_line_state_tp(char *tok, + struct step_target_act_list_info *p_parse_info, + struct step_parse_line_data_param_info *p_parse_line_info) +{ + char *pch = NULL; + + if (p_parse_info->p_pd_entry != NULL) { + WMT_ERR_FUNC("STEP failed: Please add [PD-] after [PD+], tok = %s\n", tok); + p_parse_info->p_pd_entry = NULL; + } + + pch = osal_strchr(tok, ']'); + if (pch == NULL) { + WMT_ERR_FUNC("STEP failed: Trigger point format is wrong: %s\n", tok); + } else { + *pch = '\0'; + p_parse_info->tp_id = wmt_step_parse_tp_id(tok); + p_parse_info->p_target_list = wmt_step_get_tp_list(p_parse_info->tp_id); + + if (p_parse_info->tp_id == STEP_TRIGGER_POINT_NO_DEFINE) + WMT_ERR_FUNC("STEP failed: Trigger point no define: %s\n", tok); + } + + return STEP_PARSE_LINE_RET_BREAK; +} + +static int wmt_step_access_line_state_at(char *tok, + struct step_target_act_list_info *p_parse_info, + struct step_parse_line_data_param_info *p_parse_line_info) +{ + p_parse_line_info->act_id = wmt_step_parse_act_id(tok); + if (p_parse_line_info->act_id == STEP_ACTION_INDEX_NO_DEFINE) { + WMT_ERR_FUNC("STEP failed: Action no define: %s\n", tok); + return STEP_PARSE_LINE_RET_BREAK; + } + wmt_step_set_line_state(&p_parse_line_info->state, STEP_PARSE_LINE_STATE_AT_OP); + + return STEP_PARSE_LINE_RET_CONTINUE; +} + +static int wmt_step_access_line_state_at_op(char *tok, + struct step_target_act_list_info *p_parse_info, + struct step_parse_line_data_param_info *p_parse_line_info) +{ + if (p_parse_line_info->param_index >= 0) + p_parse_line_info->act_params[p_parse_line_info->param_index] = tok; + (p_parse_line_info->param_index)++; + + if (p_parse_line_info->param_index >= STEP_PARAMETER_SIZE) { + WMT_ERR_FUNC("STEP failed: Param too much"); + return STEP_PARSE_LINE_RET_BREAK; + } + + return STEP_PARSE_LINE_RET_CONTINUE; +} + +static int wmt_step_access_line_state_pd(char *tok, + struct step_target_act_list_info *p_parse_info, + struct step_parse_line_data_param_info *p_parse_line_info) +{ + int pd_ms = -1; + + pd_ms = wmt_step_parse_pd_expires(tok); + if (pd_ms == -1) + WMT_ERR_FUNC("STEP failed: PD ms failed %s\n", tok); + + if (p_parse_info->p_pd_entry != NULL) + WMT_ERR_FUNC("STEP failed: Please add [PD-] after [PD+], tok = %s\n", tok); + + p_parse_info->p_pd_entry = wmt_step_get_periodic_dump_entry(pd_ms); + if (p_parse_info->p_pd_entry == NULL) + WMT_ERR_FUNC("STEP failed: p_pd_entry create fail\n"); + else + p_parse_info->p_target_list = &(p_parse_info->p_pd_entry->action_list); + + return STEP_PARSE_LINE_RET_BREAK; +} + +static void wmt_step_parse_line_data(char *line, struct step_target_act_list_info *p_parse_info, + STEP_WRITE_ACT_TO_LIST func_act_to_list) +{ + char *tok; + int line_ret = STEP_PARSE_LINE_RET_BREAK; + struct step_parse_line_data_param_info parse_line_info; + + parse_line_info.param_index = 0; + parse_line_info.act_id = STEP_ACTION_INDEX_NO_DEFINE; + parse_line_info.state = STEP_PARSE_LINE_STATE_INIT; + + while ((tok = osal_strsep(&line, " \t")) != NULL) { + if (*tok == '\0') + continue; + if (osal_strcmp(tok, "//") == 0) + break; + + if (wmt_step_line_state_action_map[parse_line_info.state] != NULL) { + line_ret = wmt_step_line_state_action_map[parse_line_info.state] (tok, + p_parse_info, &parse_line_info); + } + + if (line_ret == STEP_PARSE_LINE_RET_CONTINUE) + continue; + else + break; + } + + if (parse_line_info.state == STEP_PARSE_LINE_STATE_AT_OP) { + func_act_to_list(p_parse_info->p_target_list, + parse_line_info.act_id, parse_line_info.param_index, parse_line_info.act_params); + } else if (parse_line_info.state == STEP_PARSE_LINE_STATE_PD_END) { + p_parse_info->p_target_list = wmt_step_get_tp_list(p_parse_info->tp_id); + if (p_parse_info->p_pd_entry != NULL) { + parse_line_info.act_params[0] = (PINT8)p_parse_info->p_pd_entry; + func_act_to_list(p_parse_info->p_target_list, + STEP_ACTION_INDEX_PERIODIC_DUMP, parse_line_info.param_index, + parse_line_info.act_params); + p_parse_info->p_pd_entry = NULL; + } + } +} + +static void _wmt_step_do_actions(struct step_action_list *action_list) +{ + struct step_action *p_act = NULL, *p_act_next = NULL; + + list_for_each_entry_safe(p_act, p_act_next, &action_list->list, list) { + if (p_act->action_id <= STEP_ACTION_INDEX_NO_DEFINE || p_act->action_id >= STEP_ACTION_INDEX_MAX) { + WMT_ERR_FUNC("STEP failed: Wrong action id %d\n", (int)p_act->action_id); + continue; + } + + if (wmt_step_action_map[p_act->action_id].func_do_action != NULL) + wmt_step_action_map[p_act->action_id].func_do_action(p_act, NULL); + else + WMT_ERR_FUNC("STEP failed: Action is NULL\n"); + } +} + +static void wmt_step_start_work(struct step_pd_entry *p_entry) +{ + unsigned int timeout; + int result = 0; + + if (!g_step_env.pd_struct.step_pd_wq) { + WMT_ERR_FUNC("STEP failed: step wq doesn't run\n"); + result = -1; + } + + if (p_entry == NULL) { + WMT_ERR_FUNC("STEP failed: entry is null\n"); + result = -1; + } + + if (result == 0) { + timeout = p_entry->expires_ms; + queue_delayed_work(g_step_env.pd_struct.step_pd_wq, &p_entry->pd_work, timeout); + } +} + +static void wmt_step_pd_work(struct work_struct *work) +{ + struct step_pd_entry *p_entry = NULL; + struct delayed_work *delayed_work = NULL; + int result = 0; + + if (down_read_trylock(&g_step_env.init_rwsem)) { + if (!g_step_env.is_enable) { + WMT_ERR_FUNC("STEP failed: step doesn`t enable\n"); + result = -1; + } + + delayed_work = to_delayed_work(work); + if (delayed_work == NULL) { + WMT_ERR_FUNC("STEP failed: work is NULL\n"); + result = -1; + } + + if (result == 0) { + p_entry = container_of(delayed_work, struct step_pd_entry, pd_work); + + WMT_INFO_FUNC("STEP show: Periodic dump: %d ms\n", p_entry->expires_ms); + _wmt_step_do_actions(&p_entry->action_list); + wmt_step_start_work(p_entry); + } + + up_read(&g_step_env.init_rwsem); + } +} + +static struct step_pd_entry *wmt_step_create_periodic_dump_entry(unsigned int expires) +{ + struct step_pd_entry *p_pd_entry = NULL; + + p_pd_entry = kzalloc(sizeof(struct step_pd_entry), GFP_KERNEL); + if (p_pd_entry == NULL) { + WMT_ERR_FUNC("STEP failed: kzalloc fail\n"); + return NULL; + } + p_pd_entry->expires_ms = expires; + + INIT_DELAYED_WORK(&p_pd_entry->pd_work, wmt_step_pd_work); + INIT_LIST_HEAD(&(p_pd_entry->action_list.list)); + + return p_pd_entry; +} + +static void wmt_step_print_trigger_time(enum step_trigger_point_id tp_id, char *reason) +{ + const char *p_trigger_name = NULL; + + if (tp_id < 0) + return; + + p_trigger_name = STEP_TRIGGER_TIME_NAME[tp_id]; + if (reason != NULL) + WMT_INFO_FUNC("STEP show: Trigger point: %s reason: %s\n", p_trigger_name, reason); + else + WMT_INFO_FUNC("STEP show: Trigger point: %s\n", p_trigger_name); +} + +static VOID wmt_step_do_actions_from_tp(enum step_trigger_point_id tp_id, char *reason) +{ + int result = 0; + + if (down_read_trylock(&g_step_env.init_rwsem)) { + if (g_step_env.is_enable == 0) + result = -1; + + if (tp_id <= STEP_TRIGGER_POINT_NO_DEFINE || tp_id >= STEP_TRIGGER_POINT_MAX) { + WMT_ERR_FUNC("STEP failed: Do actions from tp_id: %d\n", tp_id); + result = -1; + } else if (list_empty(&g_step_env.actions[tp_id].list)) { + result = -1; + } + + if (result == 0) { + wmt_step_print_trigger_time(tp_id, reason); + _wmt_step_do_actions(&g_step_env.actions[tp_id]); + } + + up_read(&g_step_env.init_rwsem); + } +} + +static int wmt_step_write_action(struct step_action_list *p_list, enum step_action_id act_id, + int param_num, char *params[]) +{ + struct step_action *p_action = NULL; + + if (p_list == NULL) { + WMT_ERR_FUNC("STEP failed: p_list is null\n"); + return -1; + } + + p_action = wmt_step_create_action(act_id, param_num, params); + if (p_action != NULL) { + list_add_tail(&(p_action->list), &(p_list->list)); + return 0; + } + + return -1; +} + +static int wmt_step_parse_number_with_symbol(char *ptr, long *value) +{ + int ret = STEP_VALUE_INFO_UNKNOWN; + + if (*ptr == '#') { + if (osal_strtol(ptr + 1, 10, value)) { + WMT_ERR_FUNC("STEP failed: str to value %s\n", ptr); + ret = STEP_VALUE_INFO_UNKNOWN; + } else { + ret = STEP_VALUE_INFO_SYMBOL_REG_BASE; + } + } else if (*ptr == '$') { + if (osal_strtol(ptr + 1, 10, value)) { + WMT_ERR_FUNC("STEP failed: str to value %s\n", ptr); + ret = STEP_VALUE_INFO_UNKNOWN; + } else { + ret = STEP_VALUE_INFO_SYMBOL_TEMP_REG; + } + } else { + if (osal_strtol(ptr, 0, value)) { + WMT_ERR_FUNC("STEP failed: str to value %s\n", ptr); + ret = STEP_VALUE_INFO_UNKNOWN; + } else { + ret = STEP_VALUE_INFO_NUMBER; + } + } + + return ret; +} + +static int wmt_step_parse_register_address(struct step_reg_addr_info *p_reg_addr, char *ptr, long offset) +{ + unsigned long res; + unsigned int symbol; + int num_sym; + + num_sym = wmt_step_parse_number_with_symbol(ptr, &res); + if (num_sym == STEP_VALUE_INFO_SYMBOL_REG_BASE) { + symbol = (unsigned int) res; + if (symbol <= STEP_REGISTER_PHYSICAL_ADDRESS || symbol >= STEP_REGISTER_MAX) { + WMT_ERR_FUNC("STEP failed: No support the base %s\n", ptr); + return -1; + } + res = g_step_env.reg_base[symbol].vir_addr; + + if (res == 0) { + WMT_ERR_FUNC("STEP failed: No support the base %s is 0\n", ptr); + return -1; + } + + if (offset >= g_step_env.reg_base[symbol].size) { + WMT_ERR_FUNC("STEP failed: symbol(%d), offset(%d) over max size(%llu)\n", + symbol, (int) offset, g_step_env.reg_base[symbol].size); + return -1; + } + + p_reg_addr->address = res; + p_reg_addr->address_type = symbol; + } else if (num_sym == STEP_VALUE_INFO_NUMBER) { + p_reg_addr->address = res; + p_reg_addr->address_type = STEP_REGISTER_PHYSICAL_ADDRESS; + } else { + WMT_ERR_FUNC("STEP failed: number with symbol parse fail %s\n", ptr); + return -1; + } + + return 0; +} + +static unsigned int wmt_step_parse_temp_register_id(char *ptr) +{ + unsigned long res; + int num_sym; + + num_sym = wmt_step_parse_number_with_symbol(ptr, &res); + + if (num_sym == STEP_VALUE_INFO_SYMBOL_TEMP_REG) + return res; + else + return STEP_TEMP_REGISTER_SIZE; +} + +static enum step_condition_operator_id wmt_step_parse_operator_id(char *ptr) +{ + if (osal_strcmp(ptr, ">") == 0) + return STEP_OPERATOR_GREATER; + else if (osal_strcmp(ptr, ">=") == 0) + return STEP_OPERATOR_GREATER_EQUAL; + else if (osal_strcmp(ptr, "<") == 0) + return STEP_OPERATOR_LESS; + else if (osal_strcmp(ptr, "<=") == 0) + return STEP_OPERATOR_LESS_EQUAL; + else if (osal_strcmp(ptr, "==") == 0) + return STEP_OPERATOR_EQUAL; + else if (osal_strcmp(ptr, "!=") == 0) + return STEP_OPERATOR_NOT_EQUAL; + else if (osal_strcmp(ptr, "&&") == 0) + return STEP_OPERATOR_AND; + else if (osal_strcmp(ptr, "||") == 0) + return STEP_OPERATOR_OR; + + return STEP_OPERATOR_MAX; +} + +static int wmt_step_operator_result_greater(int l_val, int r_val) +{ + return (l_val > r_val); +} + +static int wmt_step_operator_result_greater_equal(int l_val, int r_val) +{ + return (l_val >= r_val); +} + +static int wmt_step_operator_result_less(int l_val, int r_val) +{ + return (l_val < r_val); +} + +static int wmt_step_operator_result_less_equal(int l_val, int r_val) +{ + return (l_val <= r_val); +} + +static int wmt_step_operator_result_equal(int l_val, int r_val) +{ + return (l_val == r_val); +} + +static int wmt_step_operator_result_not_equal(int l_val, int r_val) +{ + return (l_val != r_val); +} + +static int wmt_step_operator_result_and(int l_val, int r_val) +{ + return (l_val && r_val); +} + +static int wmt_step_operator_result_or(int l_val, int r_val) +{ + return (l_val || r_val); +} + +static char *wmt_step_save_params_msg(int num, char *params[], char *buf, int buf_size) +{ + int i, len, temp; + + for (i = 0, len = 0; i < num; i++) { + if (params[i] == NULL) + break; + + temp = osal_strlen(params[i]) + 1; + + if ((len + temp) >= (buf_size - 1)) + break; + + len += temp; + osal_strncat(buf, params[i], temp); + osal_strncat(buf, " ", 1); + } + osal_strncat(buf, "\0", 1); + + return buf; +} + +static void wmt_step_create_emi_output_log(struct step_emi_info *p_emi_info, int write, + unsigned int begin, unsigned int end) +{ + p_emi_info->is_write = write; + p_emi_info->begin_offset = begin; + p_emi_info->end_offset = end; + p_emi_info->output_mode = STEP_OUTPUT_LOG; +} + +static void wmt_step_create_emi_output_register(struct step_emi_info *p_emi_info, int write, + unsigned int begin, unsigned int mask, unsigned int reg_id) +{ + p_emi_info->is_write = write; + p_emi_info->begin_offset = begin; + p_emi_info->end_offset = begin + 0x4; + p_emi_info->mask = mask; + p_emi_info->temp_reg_id = reg_id; + p_emi_info->output_mode = STEP_OUTPUT_REGISTER; +} + +static int _wmt_step_create_emi_action(struct step_emi_info *p_emi_info, int param_num, char *params[]) +{ + long write, begin, end; + unsigned int reg_id; + char buf[128] = ""; + long mask = 0xFFFFFFFF; + + if (param_num < 3) { + WMT_ERR_FUNC("STEP failed: Init EMI to log param(%d): %s\n", param_num, + wmt_step_save_params_msg(param_num, params, buf, 128)); + return -1; + } + + if (osal_strtol(params[0], 0, &write) || + osal_strtol(params[1], 0, &begin)) { + WMT_ERR_FUNC("STEP failed: str to value %s\n", + wmt_step_save_params_msg(param_num, params, buf, 128)); + return -1; + } + + if (*params[(param_num - 1)] == STEP_TEMP_REGISTER_SYMBOL) { + reg_id = wmt_step_parse_temp_register_id(params[(param_num - 1)]); + if (reg_id >= STEP_PARAMETER_SIZE) { + WMT_ERR_FUNC("STEP failed: register id failed: %s\n", + wmt_step_save_params_msg(param_num, params, buf, 128)); + return -1; + } + + if (param_num > 3) { + if (osal_strtol(params[2], 0, &mask)) { + WMT_ERR_FUNC("STEP failed: str to value %s\n", + wmt_step_save_params_msg(param_num, params, buf, 128)); + return -1; + } + } + + wmt_step_create_emi_output_register(p_emi_info, write, begin, mask, reg_id); + } else { + if (osal_strtol(params[2], 0, &end)) { + WMT_ERR_FUNC("STEP failed: str to value %s\n", + wmt_step_save_params_msg(param_num, params, buf, 128)); + return -1; + } + wmt_step_create_emi_output_log(p_emi_info, write, begin, end); + } + + return 0; +} + +/* + * Support: + * _EMI | R(0) | Begin offset | End offset + * _EMI | R(0) | Begin offset | mask | Output temp register ID ($) + * _EMI | R(0) | Begin offset | Output temp register ID ($) + */ +static struct step_action *wmt_step_create_emi_action(int param_num, char *params[]) +{ + struct step_emi_action *p_emi_act = NULL; + struct step_emi_info *p_emi_info = NULL; + int ret; + + p_emi_act = kzalloc(sizeof(struct step_emi_action), GFP_KERNEL); + if (p_emi_act == NULL) { + WMT_ERR_FUNC("STEP failed: kzalloc emi fail\n"); + return NULL; + } + + p_emi_info = &p_emi_act->info; + ret = _wmt_step_create_emi_action(p_emi_info, param_num, params); + + if (ret != 0) { + kfree(p_emi_act); + return NULL; + } + + return &(p_emi_act->base); +} + +/* + * Support: + * CEMI | Check temp register ID (#) | R(0) | Begin offset | End offset + * CEMI | Check temp register ID (#) | R(0) | Begin offset | mask | Output temp register ID ($) + * CEMI | Check temp register ID (#) | R(0) | Begin offset | Output temp register ID ($) + */ +static struct step_action *wmt_step_create_condition_emi_action(int param_num, char *params[]) +{ + struct step_condition_emi_action *p_cond_emi_act = NULL; + struct step_emi_info *p_emi_info = NULL; + unsigned int reg_id; + char buf[128] = ""; + int ret; + + if (param_num < 1) { + WMT_ERR_FUNC("STEP failed: EMI no params\n"); + return NULL; + } + + reg_id = wmt_step_parse_temp_register_id(params[0]); + if (reg_id >= STEP_PARAMETER_SIZE) { + WMT_ERR_FUNC("STEP failed: condition register id failed: %s\n", + wmt_step_save_params_msg(param_num, params, buf, 128)); + return NULL; + } + + p_cond_emi_act = kzalloc(sizeof(struct step_condition_emi_action), GFP_KERNEL); + if (p_cond_emi_act == NULL) { + WMT_ERR_FUNC("STEP failed: kzalloc condition emi fail\n"); + return NULL; + } + + p_emi_info = &p_cond_emi_act->info; + p_cond_emi_act->cond_reg_id = reg_id; + ret = _wmt_step_create_emi_action(p_emi_info, param_num - 1, ¶ms[1]); + + if (ret != 0) { + kfree(p_cond_emi_act); + return NULL; + } + + return &(p_cond_emi_act->base); +} + +static void wmt_step_create_read_register_output_register(struct step_reigster_info *p_reg_info, + struct step_reg_addr_info reg_addr_info, unsigned int offset, int mask, unsigned int reg_id) +{ + p_reg_info->is_write = 0; + p_reg_info->address_type = reg_addr_info.address_type; + p_reg_info->address = reg_addr_info.address; + p_reg_info->offset = offset; + p_reg_info->times = 1; + p_reg_info->delay_time = 0; + p_reg_info->mask = mask; + p_reg_info->temp_reg_id = reg_id; + p_reg_info->output_mode = STEP_OUTPUT_REGISTER; +} + +static void wmt_step_create_read_register_output_log(struct step_reigster_info *p_reg_info, + struct step_reg_addr_info reg_addr_info, unsigned int offset, unsigned int times, unsigned int delay_time) +{ + p_reg_info->is_write = 0; + p_reg_info->address_type = reg_addr_info.address_type; + p_reg_info->address = reg_addr_info.address; + p_reg_info->offset = offset; + p_reg_info->times = times; + p_reg_info->delay_time = delay_time; + p_reg_info->output_mode = STEP_OUTPUT_LOG; +} + +static void wmt_step_create_write_register_action(struct step_reigster_info *p_reg_info, + struct step_reg_addr_info reg_addr_info, unsigned int offset, int value, int mask) +{ + p_reg_info->is_write = 1; + p_reg_info->address_type = reg_addr_info.address_type; + p_reg_info->address = reg_addr_info.address; + p_reg_info->offset = offset; + p_reg_info->value = value; + p_reg_info->mask = mask; +} + +static int _wmt_step_create_register_action(struct step_reigster_info *p_reg_info, + int param_num, char *params[]) +{ + long write; + struct step_reg_addr_info reg_addr_info; + long offset, value; + unsigned int reg_id = 0; + char buf[128] = ""; + long mask = 0xFFFFFFFF; + long times = 1; + long delay_time = 0; + + if (param_num < 4) { + WMT_ERR_FUNC("STEP failed: Register no params\n"); + return -1; + } + + if (osal_strtol(params[0], 0, &write)) { + WMT_ERR_FUNC("STEP failed: str to value %s\n", + params[0]); + return -1; + } + + if (osal_strtol(params[2], 0, &offset)) { + WMT_ERR_FUNC("STEP failed: str to value %s\n", + wmt_step_save_params_msg(param_num, params, buf, 128)); + return -1; + } + + if (wmt_step_parse_register_address(®_addr_info, params[1], offset) == -1) { + WMT_ERR_FUNC("STEP failed: init write register symbol: %s\n", + wmt_step_save_params_msg(param_num, params, buf, 128)); + return -1; + } + + if (write == 0) { + if (*params[(param_num - 1)] == STEP_TEMP_REGISTER_SYMBOL) { + reg_id = wmt_step_parse_temp_register_id(params[(param_num - 1)]); + if (reg_id >= STEP_PARAMETER_SIZE) { + WMT_ERR_FUNC("STEP failed: register id failed: %s\n", + wmt_step_save_params_msg(param_num, params, buf, 128)); + return -1; + } + + if (param_num > 4) { + if (osal_strtol(params[3], 0, &mask)) { + WMT_ERR_FUNC("STEP failed: str to value %s\n", + wmt_step_save_params_msg(param_num, params, buf, 128)); + return -1; + } + } + + wmt_step_create_read_register_output_register(p_reg_info, reg_addr_info, offset, mask, reg_id); + } else { + if (param_num < 5 || + osal_strtol(params[3], 0, ×) || + osal_strtol(params[4], 0, &delay_time)) { + WMT_ERR_FUNC("STEP failed: str to value %s\n", + wmt_step_save_params_msg(param_num, params, buf, 128)); + return -1; + } + + wmt_step_create_read_register_output_log(p_reg_info, reg_addr_info, offset, times, delay_time); + } + } else { + if (osal_strtol(params[3], 0, &value)) { + WMT_ERR_FUNC("STEP failed: str to value %s\n", + wmt_step_save_params_msg(param_num, params, buf, 128)); + return -1; + } + + if (param_num > 4) { + if (osal_strtol(params[4], 0, &mask)) { + WMT_ERR_FUNC("STEP failed: str to value %s\n", + wmt_step_save_params_msg(param_num, params, buf, 128)); + return -1; + } + } + + wmt_step_create_write_register_action(p_reg_info, reg_addr_info, offset, value, mask); + } + + return 0; +} + +/* + * Support: + * _REG | R(0) | Pre-define base address ID | offset | times | delay time(ms) + * _REG | R(0) | AP Physical address | offset | times | delay time(ms) + * _REG | R(0) | Pre-define base address ID | offset | mask | Output temp register ID ($) + * _REG | R(0) | AP Physical address | offset | mask | Output temp register ID ($) + * _REG | R(0) | Pre-define base address ID | offset | Output temp register ID ($) + * _REG | R(0) | AP Physical address | offset | Output temp register ID ($) + * _REG | W(1) | AP Physical address | offset | value + * _REG | W(1) | AP Physical address | offset | value + * _REG | W(1) | AP Physical address | offset | value | mask + * _REG | W(1) | AP Physical address | offset | value | mask + */ +static struct step_action *wmt_step_create_register_action(int param_num, char *params[]) +{ + struct step_register_action *p_reg_act = NULL; + struct step_reigster_info *p_reg_info = NULL; + int ret; + + p_reg_act = kzalloc(sizeof(struct step_register_action), GFP_KERNEL); + if (p_reg_act == NULL) { + WMT_ERR_FUNC("STEP failed: kzalloc register fail\n"); + return NULL; + } + + p_reg_info = &p_reg_act->info; + ret = _wmt_step_create_register_action(p_reg_info, param_num, params); + + if (ret != 0) { + kfree(p_reg_act); + return NULL; + } + + return &(p_reg_act->base); +} + +/* + * Support: + * CREG | Check temp register ID (#) | R(0) | Pre-define base address ID | offset | times | delay time(ms) + * CREG | Check temp register ID (#) | R(0) | AP Physical address | offset | times | delay time(ms) + * CREG | Check temp register ID (#) | R(0) | Pre-define base address ID | offset | mask | Output temp register ID ($) + * CREG | Check temp register ID (#) | R(0) | AP Physical address | offset | mask | Output temp register ID ($) + * CREG | Check temp register ID (#) | R(0) | Pre-define base address ID | offset | Output temp register ID ($) + * CREG | Check temp register ID (#) | R(0) | AP Physical address | offset | Output temp register ID ($) + * CREG | Check temp register ID (#) | W(1) | AP Physical address | offset | value + * CREG | Check temp register ID (#) | W(1) | AP Physical address | offset | value + * CREG | Check temp register ID (#) | W(1) | AP Physical address | offset | value | mask + * CREG | Check temp register ID (#) | W(1) | AP Physical address | offset | value | mask + */ +static struct step_action *wmt_step_create_condition_register_action(int param_num, char *params[]) +{ + struct step_condition_register_action *p_cond_reg_act = NULL; + struct step_reigster_info *p_reg_info = NULL; + unsigned int reg_id; + char buf[128] = ""; + int ret; + + if (param_num < 0) { + WMT_ERR_FUNC("STEP failed: Init EMI param(%d): %s\n", param_num, + wmt_step_save_params_msg(param_num, params, buf, 128)); + return NULL; + } + + reg_id = wmt_step_parse_temp_register_id(params[0]); + if (reg_id >= STEP_PARAMETER_SIZE) { + WMT_ERR_FUNC("STEP failed: condition register id failed: %s\n", + wmt_step_save_params_msg(param_num, params, buf, 128)); + return NULL; + } + + p_cond_reg_act = kzalloc(sizeof(struct step_condition_register_action), GFP_KERNEL); + if (p_cond_reg_act == NULL) { + WMT_ERR_FUNC("STEP failed: kzalloc condition register fail\n"); + return NULL; + } + + p_reg_info = &p_cond_reg_act->info; + p_cond_reg_act->cond_reg_id = reg_id; + ret = _wmt_step_create_register_action(p_reg_info, param_num - 1, ¶ms[1]); + + if (ret != 0) { + kfree(p_cond_reg_act); + return NULL; + } + + return &(p_cond_reg_act->base); +} + +/* + * Support: + * GPIO | R(0) | Pin number + */ +static struct step_action *wmt_step_create_gpio_action(int param_num, char *params[]) +{ + struct step_gpio_action *p_gpio_act = NULL; + long write, symbol; + char buf[128] = ""; + + if (param_num != 2) { + WMT_ERR_FUNC("STEP failed: init gpio param(%d): %s\n", param_num, + wmt_step_save_params_msg(param_num, params, buf, 128)); + return NULL; + } + + if (osal_strtol(params[0], 0, &write) || + osal_strtol(params[1], 0, &symbol)) { + WMT_ERR_FUNC("STEP failed: str to value %s\n", + wmt_step_save_params_msg(param_num, params, buf, 128)); + return NULL; + } + + p_gpio_act = kzalloc(sizeof(struct step_gpio_action), GFP_KERNEL); + if (p_gpio_act == NULL) { + WMT_ERR_FUNC("STEP failed: kzalloc gpio fail\n"); + return NULL; + } + p_gpio_act->is_write = write; + p_gpio_act->pin_symbol = symbol; + + return &(p_gpio_act->base); +} + +/* + * Support: + * DRST + */ +static struct step_action *wmt_step_create_disable_reset_action(int param_num, char *params[]) +{ + struct step_disable_reset_action *p_drst_act = NULL; + + p_drst_act = kzalloc(sizeof(struct step_disable_reset_action), GFP_KERNEL); + if (p_drst_act == NULL) { + WMT_ERR_FUNC("STEP failed: kzalloc disalbe reset fail\n"); + return NULL; + } + + return &(p_drst_act->base); +} + +/* + * Support: + * _RST + */ +static struct step_action *wmt_step_create_chip_reset_action(int param_num, char *params[]) +{ + struct step_chip_reset_action *p_crst_act = NULL; + + p_crst_act = kzalloc(sizeof(struct step_chip_reset_action), GFP_KERNEL); + if (p_crst_act == NULL) { + WMT_ERR_FUNC("STEP failed: kzalloc chip reset fail\n"); + return NULL; + } + + return &(p_crst_act->base); +} + +/* + * Support: + * WAK+ + */ +static struct step_action *wmt_step_create_keep_wakeup_action(int param_num, char *params[]) +{ + struct step_keep_wakeup_action *p_kwak_act = NULL; + + p_kwak_act = kzalloc(sizeof(struct step_keep_wakeup_action), GFP_KERNEL); + if (p_kwak_act == NULL) { + WMT_ERR_FUNC("STEP failed: kzalloc keep wakeup fail\n"); + return NULL; + } + + return &(p_kwak_act->base); +} + +/* + * Support: + * WAK- + */ +static struct step_action *wmt_step_create_cancel_wakeup_action(int param_num, char *params[]) +{ + struct step_cancel_wakeup_action *p_cwak_act = NULL; + + p_cwak_act = kzalloc(sizeof(struct step_cancel_wakeup_action), GFP_KERNEL); + if (p_cwak_act == NULL) { + WMT_ERR_FUNC("STEP failed: kzalloc cancel wakeup fail\n"); + return NULL; + } + + return &(p_cwak_act->base); +} + +/* + * Support: + * [PD+] | ms + */ +static struct step_action *wmt_step_create_periodic_dump_action(int param_num, char *params[]) +{ + struct step_periodic_dump_action *p_pd_act = NULL; + + if (params[0] == NULL) { + WMT_ERR_FUNC("STEP failed: param null\n"); + return NULL; + } + + p_pd_act = kzalloc(sizeof(struct step_periodic_dump_action), GFP_KERNEL); + if (p_pd_act == NULL) { + WMT_ERR_FUNC("STEP failed: kzalloc fail\n"); + return NULL; + } + + p_pd_act->pd_entry = (struct step_pd_entry *)params[0]; + return &(p_pd_act->base); +} + +/* + * Support: + * SHOW | Message (no space) + */ +static struct step_action *wmt_step_create_show_string_action(int param_num, char *params[]) +{ + struct step_show_string_action *p_show_act = NULL; + char buf[128] = ""; + + if (param_num != 1) { + WMT_ERR_FUNC("STEP failed: init show param(%d): %s\n", param_num, + wmt_step_save_params_msg(param_num, params, buf, 128)); + return NULL; + } + + p_show_act = kzalloc(sizeof(struct step_show_string_action), GFP_KERNEL); + if (p_show_act == NULL) { + WMT_ERR_FUNC("STEP failed: kzalloc show string fail\n"); + return NULL; + } + + p_show_act->content = kzalloc((osal_strlen(params[0]) + 1), GFP_KERNEL); + if (p_show_act->content == NULL) { + WMT_ERR_FUNC("STEP failed: kzalloc show string content fail\n"); + kfree(p_show_act); + return NULL; + } + osal_memcpy(p_show_act->content, params[0], osal_strlen(params[0])); + return &(p_show_act->base); +} + +/* + * Support: + * _SLP | time (ms) + */ +static struct step_action *wmt_step_create_sleep_action(int param_num, char *params[]) +{ + struct step_sleep_action *p_sleep_act = NULL; + long ms; + char buf[128] = ""; + + if (param_num != 1) { + WMT_ERR_FUNC("STEP failed: init sleep param(%d): %s\n", param_num, + wmt_step_save_params_msg(param_num, params, buf, 128)); + return NULL; + } + + if (osal_strtol(params[0], 0, &ms)) { + WMT_ERR_FUNC("STEP failed: str to value %s\n", + params[0]); + return NULL; + } + + p_sleep_act = kzalloc(sizeof(struct step_sleep_action), GFP_KERNEL); + if (p_sleep_act == NULL) { + WMT_ERR_FUNC("STEP failed: kzalloc sleep fail\n"); + return NULL; + } + p_sleep_act->ms = ms; + + return &(p_sleep_act->base); +} + +/* + * Support: + * COND | Check temp register ID ($) | Left temp register ID ($) | Operator | Right temp register ID ($) + * COND | Check temp register ID ($) | Left temp register ID ($) | Operator | value + */ +static struct step_action *wmt_step_create_condition_action(int param_num, char *params[]) +{ + struct step_condition_action *p_cond_act = NULL; + unsigned int res_reg_id, l_reg_id, r_reg_id = 0; + long value = 0; + int mode; + enum step_condition_operator_id op_id; + char buf[128] = ""; + + if (param_num != 4) { + WMT_ERR_FUNC("STEP failed: init sleep param(%d): %s\n", param_num, + wmt_step_save_params_msg(param_num, params, buf, 128)); + return NULL; + } + + res_reg_id = wmt_step_parse_temp_register_id(params[0]); + l_reg_id = wmt_step_parse_temp_register_id(params[1]); + if (res_reg_id >= STEP_PARAMETER_SIZE || l_reg_id >= STEP_PARAMETER_SIZE) { + WMT_ERR_FUNC("STEP failed: register id failed: %s\n", + wmt_step_save_params_msg(param_num, params, buf, 128)); + return NULL; + } + + op_id = wmt_step_parse_operator_id(params[2]); + if (op_id >= STEP_OPERATOR_MAX) { + WMT_ERR_FUNC("STEP failed: operator id failed: %s\n", + wmt_step_save_params_msg(param_num, params, buf, 128)); + return NULL; + } + + if (*params[(param_num - 1)] == STEP_TEMP_REGISTER_SYMBOL) { + r_reg_id = wmt_step_parse_temp_register_id(params[3]); + mode = STEP_CONDITION_RIGHT_REGISTER; + if (r_reg_id >= STEP_PARAMETER_SIZE) { + WMT_ERR_FUNC("STEP failed: register id failed: %s\n", + wmt_step_save_params_msg(param_num, params, buf, 128)); + return NULL; + } + } else { + if (osal_strtol(params[3], 0, &value)) { + WMT_ERR_FUNC("STEP failed: str to value %s\n", + wmt_step_save_params_msg(param_num, params, buf, 128)); + return NULL; + } + mode = STEP_CONDITION_RIGHT_VALUE; + } + + p_cond_act = kzalloc(sizeof(struct step_condition_action), GFP_KERNEL); + if (p_cond_act == NULL) { + WMT_ERR_FUNC("STEP failed: kzalloc condition fail\n"); + return NULL; + } + + p_cond_act->result_temp_reg_id = res_reg_id; + p_cond_act->l_temp_reg_id = l_reg_id; + p_cond_act->operator_id = op_id; + p_cond_act->r_temp_reg_id = r_reg_id; + p_cond_act->value = value; + p_cond_act->mode = mode; + + return &(p_cond_act->base); +} + +/* + * Support: + * _VAL | Save temp register ID ($) | Value + */ +static struct step_action *wmt_step_create_value_action(int param_num, char *params[]) +{ + struct step_value_action *p_val_act = NULL; + unsigned int reg_id; + long value; + char buf[128] = ""; + + if (param_num != 2) { + WMT_ERR_FUNC("STEP failed: init sleep param(%d): %s\n", param_num, + wmt_step_save_params_msg(param_num, params, buf, 128)); + return NULL; + } + + reg_id = wmt_step_parse_temp_register_id(params[0]); + if (reg_id >= STEP_PARAMETER_SIZE) { + WMT_ERR_FUNC("STEP failed: register id failed: %s\n", + wmt_step_save_params_msg(param_num, params, buf, 128)); + return NULL; + } + + if (osal_strtol(params[1], 0, &value)) { + WMT_ERR_FUNC("STEP failed: str to value %s\n", + wmt_step_save_params_msg(param_num, params, buf, 128)); + return NULL; + } + + p_val_act = kzalloc(sizeof(struct step_value_action), GFP_KERNEL); + if (p_val_act == NULL) { + WMT_ERR_FUNC("STEP failed: kzalloc value fail\n"); + return NULL; + } + + p_val_act->temp_reg_id = reg_id; + p_val_act->value = value; + + return &(p_val_act->base); +} + +static int wmt_step_do_write_register_action(struct step_reigster_info *p_reg_info, + STEP_DO_EXTRA func_do_extra) +{ + phys_addr_t phy_addr; + void __iomem *p_addr = NULL; + SIZE_T vir_addr; + + if (p_reg_info->address_type == STEP_REGISTER_PHYSICAL_ADDRESS) { + phy_addr = p_reg_info->address + p_reg_info->offset; + if (phy_addr & 0x3) { + WMT_ERR_FUNC("STEP failed: phy_addr(0x%08x) page failed\n", + (unsigned int)phy_addr); + return -1; + } + + p_addr = ioremap_nocache(phy_addr, 0x4); + if (p_addr) { + CONSYS_REG_WRITE_MASK((unsigned int *)p_addr, p_reg_info->value, p_reg_info->mask); + WMT_INFO_FUNC( + "STEP show: reg write Phy addr(0x%08x): 0x%08x\n", + (unsigned int)phy_addr, CONSYS_REG_READ(p_addr)); + if (func_do_extra != NULL) + func_do_extra(1, CONSYS_REG_READ(p_addr)); + iounmap(p_addr); + } else { + WMT_ERR_FUNC("STEP failed: ioremap(0x%08x) is NULL\n", + (unsigned int)phy_addr); + return -1; + } + } else { + vir_addr = p_reg_info->address + p_reg_info->offset; + if (vir_addr & 0x3) { + WMT_ERR_FUNC("STEP failed: vir_addr(0x%08x) page failed\n", + (unsigned int)vir_addr); + return -1; + } + + CONSYS_REG_WRITE_MASK((unsigned int *)vir_addr, p_reg_info->value, p_reg_info->mask); + WMT_INFO_FUNC( + "STEP show: reg write (symbol, offset)(%d, 0x%08x): 0x%08x\n", + p_reg_info->address_type, p_reg_info->offset, + CONSYS_REG_READ(vir_addr)); + if (func_do_extra != NULL) + func_do_extra(1, CONSYS_REG_READ(vir_addr)); + } + + return 0; +} + +static void _wmt_step_do_read_register_action(struct step_reigster_info *p_reg_info, + STEP_DO_EXTRA func_do_extra, char *info, int value) +{ + int i; + + for (i = 0; i < p_reg_info->times; i++) { + if (i > 0) + wmt_step_sleep_or_delay(p_reg_info->delay_time); + + if (p_reg_info->output_mode == STEP_OUTPUT_REGISTER) + g_step_env.temp_register[p_reg_info->temp_reg_id] = value & p_reg_info->mask; + else + WMT_INFO_FUNC("%s", info); + + if (func_do_extra != NULL) + func_do_extra(1, value); + } +} + +static int wmt_step_do_read_register_action(struct step_reigster_info *p_reg_info, + STEP_DO_EXTRA func_do_extra) +{ +#define WMT_STEP_REGISTER_ACTION_BUF_LEN 128 + phys_addr_t phy_addr; + void __iomem *p_addr = NULL; + SIZE_T vir_addr; + char buf[WMT_STEP_REGISTER_ACTION_BUF_LEN]; + + if (p_reg_info->address_type == STEP_REGISTER_PHYSICAL_ADDRESS) { + phy_addr = p_reg_info->address + p_reg_info->offset; + if (phy_addr & 0x3) { + WMT_ERR_FUNC("STEP failed: phy_addr(0x%08x) page failed\n", + (unsigned int)phy_addr); + return -1; + } + + p_addr = ioremap_nocache(phy_addr, 0x4); + if (p_addr) { + if (snprintf(buf, WMT_STEP_REGISTER_ACTION_BUF_LEN, + "STEP show: reg read Phy addr(0x%08x): 0x%08x\n", + (unsigned int)phy_addr, CONSYS_REG_READ(p_addr)) < 0) + WMT_INFO_FUNC("snprintf buf fail\n"); + else + _wmt_step_do_read_register_action(p_reg_info, func_do_extra, buf, + CONSYS_REG_READ(p_addr)); + iounmap(p_addr); + } else { + WMT_ERR_FUNC("STEP failed: ioremap(0x%08x) is NULL\n", + (unsigned int)phy_addr); + return -1; + } + } else { + vir_addr = p_reg_info->address + p_reg_info->offset; + if (vir_addr & 0x3) { + WMT_ERR_FUNC("STEP failed: vir_addr(0x%08x) page failed\n", + (unsigned int)vir_addr); + return -1; + } + + if (snprintf(buf, WMT_STEP_REGISTER_ACTION_BUF_LEN, + "STEP show: reg read (symbol, offset)(%d, 0x%08x): 0x%08x\n", + p_reg_info->address_type, p_reg_info->offset, + CONSYS_REG_READ(vir_addr)) < 0) + WMT_INFO_FUNC("snprintf buf fail\n"); + else + _wmt_step_do_read_register_action(p_reg_info, func_do_extra, buf, + CONSYS_REG_READ(vir_addr)); + } + + return 0; +} + +static void wmt_step_remove_emi_action(struct step_action *p_act) +{ + struct step_emi_action *p_emi_act = NULL; + + p_emi_act = list_entry_action(emi, p_act); + kfree(p_emi_act); +} + +static void wmt_step_remove_register_action(struct step_action *p_act) +{ + struct step_register_action *p_reg_act = NULL; + + p_reg_act = list_entry_action(register, p_act); + kfree(p_reg_act); +} + +static void wmt_step_remove_gpio_action(struct step_action *p_act) +{ + struct step_gpio_action *p_gpio_act = NULL; + + p_gpio_act = list_entry_action(gpio, p_act); + kfree(p_gpio_act); +} + +static void wmt_step_remove_disable_reset_action(struct step_action *p_act) +{ + struct step_disable_reset_action *p_drst = NULL; + + p_drst = list_entry_action(disable_reset, p_act); + kfree(p_drst); +} + +static void wmt_step_remove_chip_reset_action(struct step_action *p_act) +{ + struct step_chip_reset_action *p_crst = NULL; + + p_crst = list_entry_action(chip_reset, p_act); + kfree(p_crst); +} + +static void wmt_step_remove_keep_wakeup_action(struct step_action *p_act) +{ + struct step_keep_wakeup_action *p_kwak = NULL; + + p_kwak = list_entry_action(keep_wakeup, p_act); + kfree(p_kwak); +} + +static void wmt_step_remove_cancel_wakeup_action(struct step_action *p_act) +{ + struct step_cancel_wakeup_action *p_cwak = NULL; + + p_cwak = list_entry_action(cancel_wakeup, p_act); + kfree(p_cwak); +} + +static void wmt_step_remove_periodic_dump_action(struct step_action *p_act) +{ + struct step_periodic_dump_action *p_pd = NULL; + + p_pd = list_entry_action(periodic_dump, p_act); + kfree(p_pd); +} + +static void wmt_step_remove_show_string_action(struct step_action *p_act) +{ + struct step_show_string_action *p_show = NULL; + + p_show = list_entry_action(show_string, p_act); + if (p_show->content != NULL) + kfree(p_show->content); + + kfree(p_show); +} + +static void wmt_step_remove_sleep_action(struct step_action *p_act) +{ + struct step_sleep_action *p_sleep = NULL; + + p_sleep = list_entry_action(sleep, p_act); + kfree(p_sleep); +} + +static void wmt_step_remove_condition_action(struct step_action *p_act) +{ + struct step_condition_action *p_cond = NULL; + + p_cond = list_entry_action(condition, p_act); + kfree(p_cond); +} + +static void wmt_step_remove_value_action(struct step_action *p_act) +{ + struct step_value_action *p_val = NULL; + + p_val = list_entry_action(value, p_act); + kfree(p_val); +} + +static void wmt_step_remove_condition_emi_action(struct step_action *p_act) +{ + struct step_condition_emi_action *p_cond_emi_act = NULL; + + p_cond_emi_act = list_entry_action(condition_emi, p_act); + kfree(p_cond_emi_act); +} + +static void wmt_step_remove_condition_register_action(struct step_action *p_act) +{ + struct step_condition_register_action *p_cond_reg_act = NULL; + + p_cond_reg_act = list_entry_action(condition_register, p_act); + kfree(p_cond_reg_act); +} + +static int _wmt_step_do_emi_action(struct step_emi_info *p_emi_info, STEP_DO_EXTRA func_do_extra) +{ + unsigned char *p_emi_begin_addr = NULL, *p_emi_end_addr = NULL; + unsigned char __iomem *emi_base_addr = NULL; + unsigned int dis = 0, temp = 0, i = 0; + + if (p_emi_info->is_write != 0) { + WMT_ERR_FUNC("STEP failed: Only support dump EMI region\n"); + return -1; + } + + if (p_emi_info->begin_offset > p_emi_info->end_offset) { + temp = p_emi_info->begin_offset; + p_emi_info->begin_offset = p_emi_info->end_offset; + p_emi_info->end_offset = temp; + } + dis = p_emi_info->end_offset - p_emi_info->begin_offset; + + emi_base_addr = wmt_step_get_emi_base_address(); + if (emi_base_addr == NULL) { + WMT_ERR_FUNC("STEP failed: EMI base address is NULL\n"); + return -1; + } + + if (p_emi_info->begin_offset & 0x3) { + WMT_ERR_FUNC("STEP failed: begin offset(0x%08x) page failed\n", + p_emi_info->begin_offset); + return -1; + } + + p_emi_begin_addr = mtk_step_get_emi_virt_addr(emi_base_addr, p_emi_info->begin_offset); + p_emi_end_addr = mtk_step_get_emi_virt_addr(emi_base_addr, p_emi_info->end_offset); + if (!p_emi_begin_addr) { + WMT_ERR_FUNC("STEP failed: Get NULL begin virtual address 0x%08x\n", + p_emi_info->begin_offset); + return -1; + } + + if (!p_emi_end_addr) { + WMT_ERR_FUNC("STEP failed: Get NULL end virtual address 0x%08x\n", + p_emi_info->end_offset); + return -1; + } + + for (i = 0; i < dis; i += 0x4) { + if (p_emi_info->output_mode == STEP_OUTPUT_REGISTER) { + g_step_env.temp_register[p_emi_info->temp_reg_id] = + (CONSYS_REG_READ(p_emi_begin_addr + i) & p_emi_info->mask); + } else { + WMT_INFO_FUNC("STEP show: EMI action, Phy address(0x%08x): 0x%08x\n", + (unsigned int) (gConEmiPhyBase + p_emi_info->begin_offset + i), + CONSYS_REG_READ(p_emi_begin_addr + i)); + } + + if (func_do_extra != NULL) + func_do_extra(1, CONSYS_REG_READ(p_emi_begin_addr + i)); + } + + return 0; +} + +static bool wmt_step_reg_readable(struct step_reigster_info *p_reg_info) +{ + phys_addr_t phy_addr; + SIZE_T vir_addr; + + if (p_reg_info->address_type == STEP_REGISTER_PHYSICAL_ADDRESS) { + phy_addr = p_reg_info->address + p_reg_info->offset; + if (mtk_consys_is_connsys_reg(phy_addr)) + return wmt_lib_reg_readable(); + else + return 1; + + } else { + if (p_reg_info->address_type == STEP_REGISTER_CONN_MCU_CONFIG_BASE || + p_reg_info->address_type == STEP_REGISTER_MISC_OFF_BASE || + p_reg_info->address_type == STEP_REGISTER_CFG_ON_BASE || + p_reg_info->address_type == STEP_REGISTER_HIF_ON_BASE || + p_reg_info->address_type == STEP_MCU_TOP_MISC_ON_BASE || + p_reg_info->address_type == STEP_CIRQ_BASE) { + vir_addr = p_reg_info->address + p_reg_info->offset; + return wmt_lib_reg_readable_by_addr(vir_addr); + } + } + + return 1; +} + +int _wmt_step_do_register_action(struct step_reigster_info *p_reg_info, STEP_DO_EXTRA func_do_extra) +{ + int ret = 0; + bool is_wakeup = g_step_env.is_keep_wakeup; + + if (is_wakeup == 1) { + if (DISABLE_PSM_MONITOR()) + WMT_ERR_FUNC("STEP failed: Wake up, continue to show register\n"); + } + + if (wmt_lib_power_lock_trylock() == 0) { + WMT_INFO_FUNC("STEP failed: can't get lock\n"); + if (is_wakeup == 1) + ENABLE_PSM_MONITOR(); + return -1; + } + + if (!wmt_step_reg_readable(p_reg_info)) { + wmt_lib_power_lock_release(); + WMT_ERR_FUNC("STEP failed: register cant read (No clock)\n"); + if (is_wakeup == 1) + ENABLE_PSM_MONITOR(); + + return -2; + } + + if (p_reg_info->is_write == 1) + ret = wmt_step_do_write_register_action(p_reg_info, func_do_extra); + else + ret = wmt_step_do_read_register_action(p_reg_info, func_do_extra); + wmt_lib_power_lock_release(); + + if (is_wakeup == 1) + ENABLE_PSM_MONITOR(); + + return ret; +} + +void wmt_step_setup(void) +{ + if (!g_step_env.is_setup) { + g_step_env.is_setup = true; + init_rwsem(&g_step_env.init_rwsem); + wmt_step_init_register_base_size(); + } +} + +/******************************************************************************* + * I N T E R N A L F U N C T I O N S W I T H U T +********************************************************************************/ +int wmt_step_do_emi_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra) +{ + struct step_emi_action *p_emi_act = NULL; + struct step_emi_info *p_emi_info = NULL; + + p_emi_act = list_entry_action(emi, p_act); + p_emi_info = &p_emi_act->info; + return _wmt_step_do_emi_action(p_emi_info, func_do_extra); +} + +int wmt_step_do_condition_emi_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra) +{ + struct step_condition_emi_action *p_cond_emi_act = NULL; + struct step_emi_info *p_emi_info = NULL; + + p_cond_emi_act = list_entry_action(condition_emi, p_act); + p_emi_info = &p_cond_emi_act->info; + + if (g_step_env.temp_register[p_cond_emi_act->cond_reg_id] == 0) { + WMT_INFO_FUNC("STEP show: Dont do emi, condition %c%d is %d\n", + STEP_TEMP_REGISTER_SYMBOL, p_emi_info->temp_reg_id, + g_step_env.temp_register[p_cond_emi_act->cond_reg_id]); + return -1; + } + + return _wmt_step_do_emi_action(p_emi_info, func_do_extra); +} + +int wmt_step_do_register_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra) +{ + struct step_register_action *p_reg_act = NULL; + struct step_reigster_info *p_reg_info = NULL; + + p_reg_act = list_entry_action(register, p_act); + p_reg_info = &p_reg_act->info; + + return _wmt_step_do_register_action(p_reg_info, func_do_extra); +} + +int wmt_step_do_condition_register_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra) +{ + struct step_condition_register_action *p_cond_reg_act = NULL; + struct step_reigster_info *p_reg_info = NULL; + + p_cond_reg_act = list_entry_action(condition_register, p_act); + p_reg_info = &p_cond_reg_act->info; + + if (g_step_env.temp_register[p_cond_reg_act->cond_reg_id] == 0) { + WMT_INFO_FUNC("STEP show: Dont do register, condition %c%d is %d\n", + STEP_TEMP_REGISTER_SYMBOL, p_reg_info->temp_reg_id, + g_step_env.temp_register[p_cond_reg_act->cond_reg_id]); + return -1; + } + + return _wmt_step_do_register_action(p_reg_info, func_do_extra); +} + +int wmt_step_do_gpio_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra) +{ + struct step_gpio_action *p_gpio_act = NULL; + + p_gpio_act = list_entry_action(gpio, p_act); + if (p_gpio_act->is_write == 1) { + WMT_ERR_FUNC("STEP failed: Only support dump GPIO\n"); + return -1; + } + +#ifdef KERNEL_gpio_dump_regs_range + KERNEL_gpio_dump_regs_range(p_gpio_act->pin_symbol, p_gpio_act->pin_symbol); +#else + WMT_INFO_FUNC("STEP show: No support gpio dump\n"); +#endif + if (func_do_extra != NULL) + func_do_extra(0); + + return 0; +} + +int wmt_step_do_disable_reset_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra) +{ + WMT_INFO_FUNC("STEP show: Do disable reset\n"); + mtk_wcn_stp_set_auto_rst(0); + if (func_do_extra != NULL) + func_do_extra(0); + + return 0; +} + +int wmt_step_do_chip_reset_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra) +{ + WMT_INFO_FUNC("STEP show: Do chip reset\n"); + mtk_wcn_wmt_do_reset(WMTDRV_TYPE_WMT); + if (func_do_extra != NULL) + func_do_extra(0); + + return 0; +} + +int wmt_step_do_keep_wakeup_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra) +{ + WMT_INFO_FUNC("STEP show: Do keep wake up\n"); + g_step_env.is_keep_wakeup = 1; + if (func_do_extra != NULL) + func_do_extra(0); + + return 0; +} + +int wmt_step_do_cancel_wakeup_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra) +{ + WMT_INFO_FUNC("STEP show: Do cancel keep wake up\n"); + g_step_env.is_keep_wakeup = 0; + if (func_do_extra != NULL) + func_do_extra(0); + + return 0; +} + +int wmt_step_do_periodic_dump_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra) +{ + struct step_periodic_dump_action *p_pd_act = NULL; + + p_pd_act = list_entry_action(periodic_dump, p_act); + if (p_pd_act->pd_entry->is_enable == 0) { + WMT_INFO_FUNC("STEP show: Start periodic dump(%d ms)\n", + p_pd_act->pd_entry->expires_ms); + wmt_step_start_work(p_pd_act->pd_entry); + p_pd_act->pd_entry->is_enable = 1; + } + + if (func_do_extra != NULL) + func_do_extra(0); + + return 0; +} + +int wmt_step_do_show_string_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra) +{ + struct step_show_string_action *p_show_act = NULL; + + p_show_act = list_entry_action(show_string, p_act); + + WMT_INFO_FUNC("STEP show: %s\n", p_show_act->content); + + if (func_do_extra != NULL) + func_do_extra(1, p_show_act->content); + + return 0; +} + +int wmt_step_do_sleep_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra) +{ + struct step_sleep_action *p_sleep_act = NULL; + + p_sleep_act = list_entry_action(sleep, p_act); + + wmt_step_sleep_or_delay(p_sleep_act->ms); + + if (func_do_extra != NULL) + func_do_extra(0); + + return 0; +} + +int wmt_step_do_condition_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra) +{ + struct step_condition_action *p_cond_act = NULL; + int result, l_val, r_val; + + p_cond_act = list_entry_action(condition, p_act); + + l_val = g_step_env.temp_register[p_cond_act->l_temp_reg_id]; + + if (p_cond_act->mode == STEP_CONDITION_RIGHT_REGISTER) + r_val = g_step_env.temp_register[p_cond_act->r_temp_reg_id]; + else + r_val = p_cond_act->value; + + if ((p_cond_act->operator_id >= 0) && wmt_step_operator_result_map[p_cond_act->operator_id]) { + result = wmt_step_operator_result_map[p_cond_act->operator_id] (l_val, r_val); + g_step_env.temp_register[p_cond_act->result_temp_reg_id] = result; + + WMT_INFO_FUNC("STEP show: Condition %d(%c%d) op %d(%c%d) => %d(%c%d)\n", + l_val, STEP_TEMP_REGISTER_SYMBOL, p_cond_act->l_temp_reg_id, + r_val, STEP_TEMP_REGISTER_SYMBOL, p_cond_act->r_temp_reg_id, + result, STEP_TEMP_REGISTER_SYMBOL, p_cond_act->result_temp_reg_id); + } else { + WMT_ERR_FUNC("STEP failed: operator no define id: %d\n", p_cond_act->operator_id); + } + + if (func_do_extra != NULL) + func_do_extra(1, g_step_env.temp_register[p_cond_act->result_temp_reg_id]); + + return 0; +} + +int wmt_step_do_value_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra) +{ + struct step_value_action *p_val_act = NULL; + + p_val_act = list_entry_action(value, p_act); + + g_step_env.temp_register[p_val_act->temp_reg_id] = p_val_act->value; + + if (func_do_extra != NULL) + func_do_extra(1, g_step_env.temp_register[p_val_act->temp_reg_id]); + + return 0; +} + +struct step_action *wmt_step_create_action(enum step_action_id act_id, int param_num, char *params[]) +{ + struct step_action *p_act = NULL; + + if (act_id <= STEP_ACTION_INDEX_NO_DEFINE || act_id >= STEP_ACTION_INDEX_MAX) { + WMT_ERR_FUNC("STEP failed: Create action id: %d\n", act_id); + return NULL; + } + + if (wmt_step_action_map[act_id].func_create_action != NULL) + p_act = wmt_step_action_map[act_id].func_create_action(param_num, params); + else + WMT_ERR_FUNC("STEP failed: Create no define id: %d\n", act_id); + + if (p_act != NULL) + p_act->action_id = act_id; + + return p_act; +} + +int wmt_step_init_pd_env(void) +{ + g_step_env.pd_struct.step_pd_wq = create_workqueue(STEP_PERIODIC_DUMP_WORK_QUEUE); + if (!g_step_env.pd_struct.step_pd_wq) { + WMT_ERR_FUNC("create_workqueue fail\n"); + return -1; + } + INIT_LIST_HEAD(&g_step_env.pd_struct.pd_list); + + return 0; +} + +int wmt_step_deinit_pd_env(void) +{ + struct step_pd_entry *p_current = NULL; + struct step_pd_entry *p_next = NULL; + + if (!g_step_env.pd_struct.step_pd_wq) + return -1; + + list_for_each_entry_safe(p_current, p_next, &g_step_env.pd_struct.pd_list, list) { + cancel_delayed_work(&p_current->pd_work); + wmt_step_clear_action_list(&p_current->action_list); + } + destroy_workqueue(g_step_env.pd_struct.step_pd_wq); + + return 0; +} + +struct step_pd_entry *wmt_step_get_periodic_dump_entry(unsigned int expires) +{ + struct step_pd_entry *p_current = NULL; + + if (expires <= 0) + return NULL; + + if (!g_step_env.pd_struct.step_pd_wq) { + if (wmt_step_init_pd_env() != 0) + return NULL; + } + + p_current = wmt_step_create_periodic_dump_entry(expires); + if (p_current == NULL) + return NULL; + list_add_tail(&(p_current->list), &(g_step_env.pd_struct.pd_list)); + + return p_current; +} + +int wmt_step_parse_data(const char *in_buf, unsigned int size, + STEP_WRITE_ACT_TO_LIST func_act_to_list) +{ + struct step_target_act_list_info parse_info; + char *buf = NULL, *tmp_buf = NULL; + char *line = NULL; + + buf = osal_malloc(size + 1); + if (!buf) { + WMT_ERR_FUNC("STEP failed: Buf malloc\n"); + return -1; + } + + osal_memcpy(buf, (char *)in_buf, size); + buf[size] = '\0'; + + parse_info.tp_id = STEP_TRIGGER_POINT_NO_DEFINE; + parse_info.p_target_list = NULL; + parse_info.p_pd_entry = NULL; + + tmp_buf = buf; + while ((line = osal_strsep(&tmp_buf, "\r\n")) != NULL) + wmt_step_parse_line_data(line, &parse_info, func_act_to_list); + + osal_free(buf); + + return 0; +} + + +int wmt_step_read_file(const char *file_name) +{ + int ret = -1; + const osal_firmware *p_step_cfg = NULL; + + if (g_step_env.is_enable == 1) + return 0; + + if (0 == wmt_step_get_cfg(file_name, (osal_firmware **) &p_step_cfg)) { + if (0 == wmt_step_parse_data((const char *)p_step_cfg->data, p_step_cfg->size, + wmt_step_write_action)) { + ret = 0; + } else { + ret = -1; + } + + wmt_dev_patch_put((osal_firmware **) &p_step_cfg); + return ret; + } + + WMT_INFO_FUNC("STEP read file, %s is not exist\n", file_name); + + return ret; +} + +void wmt_step_remove_action(struct step_action *p_act) +{ + if (p_act != NULL) { + if (p_act->action_id <= STEP_ACTION_INDEX_NO_DEFINE || p_act->action_id >= STEP_ACTION_INDEX_MAX) { + WMT_ERR_FUNC("STEP failed: Wrong action id %d\n", (int)p_act->action_id); + return; + } + + if (wmt_step_action_map[p_act->action_id].func_remove_action != NULL) + wmt_step_action_map[p_act->action_id].func_remove_action(p_act); + } else { + WMT_ERR_FUNC("STEP failed: Action is NULL\n"); + } +} + +void wmt_step_print_version(void) +{ + WMT_INFO_FUNC("STEP version: %d\n", STEP_VERSION); +} + +/******************************************************************************* + * E X T E R N A L F U N C T I O N S +********************************************************************************/ +void wmt_step_init(void) +{ +#ifdef CFG_WMT_STEP + wmt_step_setup(); + wmt_step_init_list(); + if (wmt_step_read_file(STEP_CONFIG_NAME) == 0) { + wmt_step_print_version(); + down_write(&g_step_env.init_rwsem); + g_step_env.is_enable = 1; + up_write(&g_step_env.init_rwsem); + } +#endif +} + +void wmt_step_deinit(void) +{ + down_write(&g_step_env.init_rwsem); + g_step_env.is_enable = 0; + up_write(&g_step_env.init_rwsem); + wmt_step_clear_list(); + wmt_step_unioremap_emi(); + wmt_step_deinit_pd_env(); +} + +void wmt_step_do_actions(enum step_trigger_point_id tp_id) +{ + wmt_step_do_actions_from_tp(tp_id, NULL); +} + +void wmt_step_func_crtl_do_actions(ENUM_WMTDRV_TYPE_T type, ENUM_WMT_OPID_T opId) +{ + enum step_trigger_point_id tp_id = STEP_TRIGGER_POINT_NO_DEFINE; + + if (type < WMTDRV_TYPE_BT || type >= WMTDRV_TYPE_MAX) { + WMT_ERR_FUNC("STEP failed: Do actions from type: %d\n", type); + return; + } + + switch (opId) { + case WMT_OPID_FUNC_OFF: + tp_id = wmt_step_func_ctrl_id[type][0]; + break; + case WMT_OPID_FUNC_ON: + tp_id = wmt_step_func_ctrl_id[type][1]; + break; + default: + break; + } + + if (tp_id != STEP_TRIGGER_POINT_NO_DEFINE) { + /* default value is 0*/ + wmt_step_do_actions(tp_id); + } +} + +void wmt_step_command_timeout_do_actions(char *reason) +{ + wmt_step_do_actions_from_tp(STEP_TRIGGER_POINT_COMMAND_TIMEOUT, reason); +} + diff --git a/drivers/misc/mediatek/connectivity/common/common_main/linux/wmt_user_proc.c b/drivers/misc/mediatek/connectivity/common/common_main/linux/wmt_user_proc.c new file mode 100644 index 0000000000000000000000000000000000000000..b03e20a4792cd2f4fb544e4bb84bbad48eb66e0e --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/linux/wmt_user_proc.c @@ -0,0 +1,194 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +#include "osal_typedef.h" +#include "wmt_user_proc.h" +#include "wmt_lib.h" +#include "stp_core.h" +#include "connsys_debug_utility.h" +#include "wmt_alarm.h" + +#ifdef DFT_TAG +#undef DFT_TAG +#define DFT_TAG "[WMT-DEV]" +#endif + +#define WMT_USER_PROCNAME "driver/wmt_user_proc" +static struct proc_dir_entry *gWmtUserProcEntry; + +static ssize_t wmt_user_proc_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos); + +static INT32 wmt_user_proc_func_ctrl(INT32 par1, INT32 par2, INT32 par3); +static INT32 wmt_user_proc_wmt_assert_ctrl(INT32 par1, INT32 par2, INT32 par3); +static INT32 wmt_user_proc_suspend_debug(INT32 par1, INT32 offset, INT32 size); +static INT32 wmt_user_proc_alarm_ctrl(INT32 par1, INT32 offset, INT32 size); +static INT32 wmt_user_proc_set_bt_link_status(INT32 par1, INT32 par2, INT32 par3); + +static const WMT_DEV_USER_PROC_FUNC wmt_dev_user_proc_func[] = { + [0x0] = wmt_user_proc_func_ctrl, + [0x1] = wmt_user_proc_wmt_assert_ctrl, + [0x2] = wmt_user_proc_suspend_debug, + [0x3] = wmt_user_proc_set_bt_link_status, + [0x4] = wmt_user_proc_alarm_ctrl, +}; + +INT32 wmt_user_proc_func_ctrl(INT32 par1, INT32 par2, INT32 par3) +{ + MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE; + + if (par2 < WMTDRV_TYPE_WMT || par2 == WMTDRV_TYPE_LPBK) { + if (par3 == 0) { + WMT_INFO_FUNC("function off test, type(%d)\n", par2); + ret = mtk_wcn_wmt_func_off(par2); + } else { + WMT_INFO_FUNC("function on test, type(%d)\n", par2); + ret = mtk_wcn_wmt_func_on(par2); + } + WMT_INFO_FUNC("function test return %d\n", ret); + } else + WMT_INFO_FUNC("function ctrl test, invalid type(%d)\n", par2); + + return 0; +} + +INT32 wmt_user_proc_wmt_assert_ctrl(INT32 par1, INT32 par2, INT32 par3) +{ + if (par2 > 2 || par2 < 0) + return -1; + + mtk_wcn_stp_coredump_flag_ctrl(par2); + + return 0; +} + +/********************************************************/ +/* par2: */ +/* 0: Off */ +/* others: alarm time (seconds) */ +/********************************************************/ +static INT32 wmt_user_proc_suspend_debug(INT32 par1, INT32 par2, INT32 par3) +{ + if (par2 > 0) + connsys_log_alarm_enable(par2); + else + connsys_log_alarm_disable(); + return 0; +} + +static INT32 wmt_user_proc_alarm_ctrl(INT32 par1, INT32 par2, INT32 par3) +{ + if (par2 > 0) + wmt_alarm_start(par2); + else + wmt_alarm_cancel(); + return 0; +} + +static INT32 wmt_user_proc_set_bt_link_status(INT32 par1, INT32 par2, INT32 par3) +{ + if (par2 != 0 && par2 != 1) + return 0; + + wmt_lib_set_bt_link_status(par2, par3); + return 0; +} + +ssize_t wmt_user_proc_write(struct file *filp, const char __user *buffer, size_t count, loff_t *f_pos) +{ + ULONG len = count; + INT8 buf[256]; + PINT8 pBuf; + INT32 x = 0, y = 0, z = 0; + PINT8 pToken = NULL; + PINT8 pDelimiter = " \t"; + LONG res = 0; + + WMT_INFO_FUNC("write parameter len = %d\n\r", (INT32) len); + if (len >= osal_sizeof(buf)) { + WMT_ERR_FUNC("input handling fail!\n"); + len = osal_sizeof(buf) - 1; + return -1; + } + + if (copy_from_user(buf, buffer, len)) + return -EFAULT; + + buf[len] = '\0'; + WMT_INFO_FUNC("write parameter data = %s\n\r", buf); + + pBuf = buf; + pToken = osal_strsep(&pBuf, pDelimiter); + if (pToken != NULL) { + osal_strtol(pToken, 16, &res); + x = (INT32)res; + } else { + x = 0; + } + + pToken = osal_strsep(&pBuf, "\t\n "); + if (pToken != NULL) { + osal_strtol(pToken, 16, &res); + y = (INT32)res; + WMT_INFO_FUNC("y = 0x%08x\n\r", y); + } else { + y = 3000; + } + + pToken = osal_strsep(&pBuf, "\t\n "); + if (pToken != NULL) { + if (0x3 == x) + z = osal_strcmp(pToken, "true") ? 0 : 1; + else { + osal_strtol(pToken, 16, &res); + z = (INT32)res; + } + } else { + z = 10; + } + + WMT_INFO_FUNC("x(0x%08x), y(0x%08x), z(0x%08x)\n\r", x, y, z); + + if (osal_array_size(wmt_dev_user_proc_func) > x && NULL != wmt_dev_user_proc_func[x]) + (*wmt_dev_user_proc_func[x]) (x, y, z); + else + WMT_WARN_FUNC("no handler defined for command id(0x%08x)\n\r", x); + + return len; +} + +INT32 wmt_dev_user_proc_setup(VOID) +{ + static const struct file_operations wmt_user_proc_fops = { + .owner = THIS_MODULE, + .write = wmt_user_proc_write, + }; + INT32 i_ret = 0; + + gWmtUserProcEntry = proc_create(WMT_USER_PROCNAME, 0664, NULL, &wmt_user_proc_fops); + if (gWmtUserProcEntry == NULL) { + WMT_ERR_FUNC("Unable to create / wmt_user_proc proc entry\n\r"); + i_ret = -1; + } + + return i_ret; +} + +INT32 wmt_dev_user_proc_remove(VOID) +{ + if (gWmtUserProcEntry != NULL) + proc_remove(gWmtUserProcEntry); + gWmtUserProcEntry = NULL; + + return 0; +} diff --git a/drivers/misc/mediatek/connectivity/common/common_main/platform/include/mt6580.h b/drivers/misc/mediatek/connectivity/common/common_main/platform/include/mt6580.h new file mode 100644 index 0000000000000000000000000000000000000000..9ceee3b3942020769eddd33bdc24faacd2aeb9e6 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/platform/include/mt6580.h @@ -0,0 +1,220 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#ifndef _MTK_MT6580_H_ +#define _MTK_MT6580_H_ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ +#define MT6580_WORKAROUND 1 +#if MT6580_WORKAROUND +#define CONSYS_BT_WIFI_SHARE_V33 1 +#else +#define CONSYS_BT_WIFI_SHARE_V33 0 +#endif +#define CONSYS_PMIC_CTRL_ENABLE 1 +#define CONSYS_EMI_MPU_SETTING 1 +#define CONSYS_AHB_CLK_MAGEMENT 0 +#define CONSYS_USE_PLATFORM_WRITE 1 +#define CONSYS_PWR_ON_OFF_API_AVAILABLE 1 +#define CONSYS_CLOCK_BUF_CTRL 1 +#if defined(CONFIG_MTK_LEGACY) +#define CONFIG_MTK_PMIC_LEGACY 1 +#endif +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/*tag start:new platform need to make sure these define */ +#define PLATFORM_SOC_CHIP 0x6580 +/*tag end*/ + +#ifdef CONFIG_OF +/*TOPCKGEN_BASE*/ +#define CONSYS_TOP_CLKCG_CLR_OFFSET 0x00000084 +#define CONSYS_TOP_CLKCG_SET_OFFSET 0x00000054 +#define CONSYS_WD_SYS_RST_OFFSET 0x00000018 +#define CONSYS_AP2CONN_OSC_EN_OFFSET 0x00001880 +#define CONSYS_EMI_MAPPING_OFFSET 0x00001320 +#define CONSYS_DA_XOBUF_OFFSET 0x0000013C +#define CONSYS_TOPAXI_PROT_EN_OFFSET 0x00001220 +#define CONSYS_TOPAXI_PROT_STA1_OFFSET 0x00001228 +#define CONSYS_PROT_MASK ((0x1<<9) | (0x1<<8))/*bit 9, 8*/ +/*AP_RGU_BASE*/ +#define CONSYS_CPU_SW_RST_OFFSET 0x00000018 +/*SPM_BASE*/ +#define CONSYS_PWRON_CONFG_EN_OFFSET 0x00000000 +#define CONSYS_TOP1_PWR_CTRL_OFFSET 0x00000280 +#define CONSYS_PWR_CONN_ACK_OFFSET 0x0000060c +#define CONSYS_PWR_CONN_ACK_S_OFFSET 0x00000610 +/*CONN_MCU_CONFIG_BASE*/ +#define CONSYS_CHIP_ID_OFFSET 0x00000008 +#define CONSYS_ROM_RAM_DELSEL_OFFSET 0x00000114 +#define CONSYS_MCU_CFG_ACR_OFFSET 0x00000110 +#define CONSYS_CPUPCR_OFFSET 0x00000160 +#endif /*END CONFIG_OF*/ + +/*tag start: connsys register base address (hard code, no use) */ +#define AP_RGU_BASE 0xF0007000 +#define TOPCKGEN_BASE 0xF0000000 +#define SPM_BASE 0xF0006000 +#define CONN_MCU_CONFIG_BASE 0xF8070000 +/*GIC Interrupt ID*/ +#define MT_CONN2AP_BTIF_WAKEUP_IRQ_ID 270 +/*tag end*/ + + +/*connsys register offset define(hard code mode)*/ +#if 1 +/*top clock gating control register*/ +#define CONSYS_TOP_CLKCG_CLR_REG (TOPCKGEN_BASE + 0x00000084) +#define CONSYS_TOP_CLKCG_SET_REG (TOPCKGEN_BASE + 0x00000054) +#define CONSYS_TOP_CLKCG_BIT (0x1 << 26) + +/*SPM clock gating control register*/ +#define CONSYS_PWRON_CONFG_EN_REG (SPM_BASE + 0x00000000) +#define CONSYS_PWRON_CONFG_EN_VALUE (0x0b160001) +#define CONSYS_PWRON_CONFG_DIS_VALUE (0x0b160000) +#endif + +#define CONSYS_CPU_SW_RST_REG (AP_RGU_BASE + 0x00000018) +#define CONSYS_TOP1_PWR_CTRL_REG (SPM_BASE + 0x00000280) +#define CONSYS_PWR_CONN_ACK_REG (SPM_BASE + 0x0000060c) +#define CONSYS_PWR_CONN_ACK_S_REG (SPM_BASE + 0x00000610) + +#define CONSYS_WD_SYS_RST_REG (TOPCKGEN_BASE + 0x00000018) +#define CONSYS_CHIP_ID_REG (CONN_MCU_CONFIG_BASE + 0x00000008) +#define CONSYS_ROM_RAM_DELSEL_REG (CONN_MCU_CONFIG_BASE + 0x00000114) +#define CONSYS_MCU_CFG_ACR_REG (CONN_MCU_CONFIG_BASE + 0x00000110) +#define CONSYS_AFE_REG (CONN_TOP_CR_BASE + 0x00002000) +#define CONSYS_AFE_REG_DIG_RCK_01 (CONSYS_AFE_REG + 0x00000010) +#define CONSYS_AFE_REG_WBG_PLL_02 (CONSYS_AFE_REG + 0x00000028) +#define CONSYS_AFE_REG_WBG_WB_TX_01 (CONSYS_AFE_REG + 0x0000003c) +#define CONSYS_AFE_REG_DIG_RCK_01_VALUE (0x174b0160) +#define CONSYS_AFE_REG_WBG_PLL_02_VALUE (0x844083fe) +#define CONSYS_AFE_REG_WBG_WB_TX_01_VALUE (0x7fc39a20) + + +/*CONSYS_CPU_SW_RST_REG*/ +#define CONSYS_CPU_SW_RST_BIT (0x1 << 12) +#define CONSYS_CPU_SW_RST_CTRL_KEY (0x88 << 24) + +/*CONSYS_TOP1_PWR_CTRL_REG*/ +#define CONSYS_SPM_PWR_RST_BIT (0x1 << 0) +#define CONSYS_SPM_PWR_ISO_S_BIT (0x1 << 1) +#define CONSYS_SPM_PWR_ON_BIT (0x1 << 2) +#define CONSYS_SPM_PWR_ON_S_BIT (0x1 << 3) +#define CONSYS_CLK_CTRL_BIT (0x1 << 4) +#define CONSYS_SRAM_CONN_PD_BIT (0x1 << 8) + +/*CONSYS_PWR_CONN_ACK_REG*/ +#define CONSYS_PWR_ON_ACK_BIT (0x1 << 1) + +/*CONSYS_PWR_CONN_ACK_S_REG*/ +#define CONSYS_PWR_CONN_ACK_S_BIT (0x1 << 1) + +/*CONSYS_WD_SYS_RST_REG*/ +#define CONSYS_WD_SYS_RST_CTRL_KEY (0x88 << 24) +#define CONSYS_WD_SYS_RST_BIT (0x1 << 9) + +/*CONSYS_MCU_CFG_ACR_REG*/ +#define CONSYS_MCU_CFG_ACR_MBIST_BIT (0x1 << 18) + +/* EMI part mapping & ctrl*/ +#define CONSYS_EMI_COREDUMP_OFFSET (0x80000) +#define CONSYS_EMI_AP_PHY_BASE (0x80080000) +#define CONSYS_EMI_FW_PHY_BASE (0xf0080000) +#define CONSYS_EMI_PAGED_TRACE_OFFSET (0x400) +#define CONSYS_EMI_PAGED_DUMP_OFFSET (0x8400) +#define CONSYS_EMI_FULL_DUMP_OFFSET (0x10400) + +/*cpupcr*/ +#define CONSYS_CPUPCR_REG (CONN_MCU_CONFIG_BASE + 0x00000160) +/*emi mapping*/ +#define CONSYS_EMI_MAPPING (TOPCKGEN_BASE + CONSYS_EMI_MAPPING_OFFSET) + +/*control app2cnn_osc_en*/ +#define CONSYS_AP2CONN_OSC_EN_REG (TOPCKGEN_BASE + 0x00001800) +#define CONSYS_AP2CONN_OSC_EN_BIT (0x1 << 16) +#define CONSYS_AP2CONN_WAKEUP_BIT (0x1 << 17) + +/*paged dump address start*/ +#define CONSYS_PAGED_DUMP_START_ADDR (0xf0088400) + +/*full dump address start*/ +#define CONSYS_FULL_DUMP_START_ADDR (0xf0090400) +#define CONSYS_FULL_DUMP_DLM_LEN (0x1f000) +#define CONSYS_FULL_DUMP_SYSB2_START (CONSYS_FULL_DUMP_START_ADDR + CONSYS_FULL_DUMP_DLM_LEN) +#define CONSYS_FULL_DUMP_SYSB2_LEN (0x6800) +#define CONSYS_FULL_DUMP_SYSB3_START (CONSYS_FULL_DUMP_SYSB2_START + CONSYS_FULL_DUMP_SYSB2_LEN) +#define CONSYS_FULL_DUMP_SYSB3_LEN (0x16800) + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + + + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + + + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +#if CONSYS_BT_WIFI_SHARE_V33 +struct bt_wifi_v33_status { + UINT32 counter; + UINT32 flags; + spinlock_t lock; +}; + +extern struct bt_wifi_v33_status gBtWifiV33; +#endif + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _MTK_MT6580_H_ */ diff --git a/drivers/misc/mediatek/connectivity/common/common_main/platform/include/mt6735.h b/drivers/misc/mediatek/connectivity/common/common_main/platform/include/mt6735.h new file mode 100644 index 0000000000000000000000000000000000000000..a3b6463c402dff23c98a510ecee20aa3b289f0cc --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/platform/include/mt6735.h @@ -0,0 +1,215 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + + +#ifndef _MTK_MT6735_H_ +#define _MTK_MT6735_H_ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ +#define CONSYS_BT_WIFI_SHARE_V33 0 +#define CONSYS_PMIC_CTRL_ENABLE 1 +#define CONSYS_EMI_MPU_SETTING 1 +#define CONSYS_AHB_CLK_MAGEMENT 1 +#define CONSYS_USE_PLATFORM_WRITE 1 +#define CONSYS_PWR_ON_OFF_API_AVAILABLE 1 +#define CONSYS_CLOCK_BUF_CTRL 1 +#if defined(CONFIG_MTK_LEGACY) +#define CONFIG_MTK_PMIC_LEGACY 1 +#endif +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/*tag start:new platform need to make sure these define */ +#if defined(CONFIG_ARCH_MT6735) || defined(CONFIG_MACH_MT6735) +#define PLATFORM_SOC_CHIP 0x0321 +#elif defined(CONFIG_ARCH_MT6735M) || defined(CONFIG_MACH_MT6735M) +#define PLATFORM_SOC_CHIP 0x0335 +#elif defined(CONFIG_ARCH_MT6753) || defined(CONFIG_MACH_MT6753) +#define PLATFORM_SOC_CHIP 0x0337 +#else +#define PLATFORM_SOC_CHIP 0x6735 +#endif +/*tag end*/ + +#ifdef CONFIG_OF +/*TOPCKGEN_BASE*/ +#define CONSYS_TOP_CLKCG_CLR_OFFSET 0x00000084 +#define CONSYS_TOP_CLKCG_SET_OFFSET 0x00000054 +#define CONSYS_WD_SYS_RST_OFFSET 0x00000018 +#define CONSYS_AP2CONN_OSC_EN_OFFSET 0x00000700 +#define CONSYS_EMI_MAPPING_OFFSET 0x00000320 +/*AP_RGU_BASE*/ +#define CONSYS_CPU_SW_RST_OFFSET 0x00000018 +/*SPM_BASE*/ +#define CONSYS_PWRON_CONFG_EN_OFFSET 0x00000000 +#define CONSYS_TOP1_PWR_CTRL_OFFSET 0x00000280 +#define CONSYS_PWR_CONN_ACK_OFFSET 0x0000060c +#define CONSYS_PWR_CONN_ACK_S_OFFSET 0x00000610 +/*CONN_MCU_CONFIG_BASE*/ +#define CONSYS_CHIP_ID_OFFSET 0x00000008 +#define CONSYS_ROM_RAM_DELSEL_OFFSET 0x00000114 +#define CONSYS_MCU_CFG_ACR_OFFSET 0x00000110 +#define CONSYS_CPUPCR_OFFSET 0x00000160 +/*AXI bus*/ +#define CONSYS_TOPAXI_PROT_EN_OFFSET 0x0220 +#define CONSYS_TOPAXI_PROT_STA1_OFFSET 0x0228 +#endif /* END CONFIG_OF*/ + +/*tag start: connsys register base address (hard code, no use) */ +#define AP_RGU_BASE 0xF0007000 +#define TOPCKGEN_BASE 0xF0000000 +#define SPM_BASE 0xF0006000 +#define CONN_MCU_CONFIG_BASE 0xF8070000 +/*GIC Interrupt ID*/ +#define MT_CONN2AP_BTIF_WAKEUP_IRQ_ID 259 +/*tag end*/ + +/*connsys register offset define(hard code mode)*/ +#if 1 + /*top clock gating control register */ +#define CONSYS_TOP_CLKCG_CLR_REG (TOPCKGEN_BASE + 0x00000084) +#define CONSYS_TOP_CLKCG_SET_REG (TOPCKGEN_BASE + 0x00000054) +#define CONSYS_TOP_CLKCG_BIT (0x1 << 26) + + /*SPM clock gating control register */ +#define CONSYS_PWRON_CONFG_EN_REG (SPM_BASE + 0x00000000) +#define CONSYS_PWRON_CONFG_EN_VALUE (0x0b160001) +#define CONSYS_PWRON_CONFG_DIS_VALUE (0x0b160000) +#endif + +#define CONSYS_CPU_SW_RST_REG (AP_RGU_BASE + 0x00000018) +#define CONSYS_TOP1_PWR_CTRL_REG (SPM_BASE + 0x00000280) +#define CONSYS_PWR_CONN_ACK_REG (SPM_BASE + 0x0000060c) +#define CONSYS_PWR_CONN_ACK_S_REG (SPM_BASE + 0x00000610) + +#define CONSYS_WD_SYS_RST_REG (TOPCKGEN_BASE + 0x00000018) +#define CONSYS_CHIP_ID_REG (CONN_MCU_CONFIG_BASE + 0x00000008) +#define CONSYS_ROM_RAM_DELSEL_REG (CONN_MCU_CONFIG_BASE + 0x00000114) +#define CONSYS_MCU_CFG_ACR_REG (CONN_MCU_CONFIG_BASE + 0x00000110) +#define CONSYS_AFE_REG (CONN_TOP_CR_BASE + 0x00002000) +#define CONSYS_AFE_REG_DIG_RCK_01 (CONSYS_AFE_REG + 0x00000010) +#define CONSYS_AFE_REG_WBG_PLL_02 (CONSYS_AFE_REG + 0x00000028) +#define CONSYS_AFE_REG_WBG_WB_TX_01 (CONSYS_AFE_REG + 0x0000003c) +#define CONSYS_AFE_REG_DIG_RCK_01_VALUE (0x174b0160) +#define CONSYS_AFE_REG_WBG_PLL_02_VALUE (0x844083fe) +#define CONSYS_AFE_REG_WBG_WB_TX_01_VALUE (0x7fc39a20) + +#define CONSYS_TOPAXI_PROT_EN (TOPCKGEN_BASE + 0x0220) +#define CONSYS_TOPAXI_PROT_STA1 (TOPCKGEN_BASE + 0x0228) +#define CONSYS_PROT_MASK ((0x1<<2) | (0x1<<8)) /* bit 2, 8 */ +/*CONSYS_CPU_SW_RST_REG*/ +#define CONSYS_CPU_SW_RST_BIT (0x1 << 12) +#define CONSYS_CPU_SW_RST_CTRL_KEY (0x88 << 24) + +/*CONSYS_TOP1_PWR_CTRL_REG*/ +#define CONSYS_SPM_PWR_RST_BIT (0x1 << 0) +#define CONSYS_SPM_PWR_ISO_S_BIT (0x1 << 1) +#define CONSYS_SPM_PWR_ON_BIT (0x1 << 2) +#define CONSYS_SPM_PWR_ON_S_BIT (0x1 << 3) +#define CONSYS_CLK_CTRL_BIT (0x1 << 4) +#define CONSYS_SRAM_CONN_PD_BIT (0x1 << 8) + +/*CONSYS_PWR_CONN_ACK_REG*/ +#define CONSYS_PWR_ON_ACK_BIT (0x1 << 1) + +/*CONSYS_PWR_CONN_ACK_S_REG*/ +#define CONSYS_PWR_CONN_ACK_S_BIT (0x1 << 1) + +/*CONSYS_WD_SYS_RST_REG*/ +#define CONSYS_WD_SYS_RST_CTRL_KEY (0x88 << 24) +#define CONSYS_WD_SYS_RST_BIT (0x1 << 9) + +/*CONSYS_MCU_CFG_ACR_REG*/ +#define CONSYS_MCU_CFG_ACR_MBIST_BIT (0x1 << 18) + +/* EMI part mapping & ctrl*/ +#define CONSYS_EMI_COREDUMP_OFFSET (0x80000) +#define CONSYS_EMI_AP_PHY_BASE (0x80080000) +#define CONSYS_EMI_FW_PHY_BASE (0xf0080000) +#define CONSYS_EMI_PAGED_TRACE_OFFSET (0x400) +#define CONSYS_EMI_PAGED_DUMP_OFFSET (0x8400) +#define CONSYS_EMI_FULL_DUMP_OFFSET (0x10400) + +/*cpupcr*/ +#define CONSYS_CPUPCR_REG (CONN_MCU_CONFIG_BASE + 0x00000160) +/*emi mapping*/ +#define CONSYS_EMI_MAPPING (TOPCKGEN_BASE + CONSYS_EMI_MAPPING_OFFSET) + +/*control app2cnn_osc_en*/ +#define CONSYS_AP2CONN_OSC_EN_REG (TOPCKGEN_BASE + 0x00001800) +#define CONSYS_AP2CONN_OSC_EN_BIT (0x1 << 10) +#define CONSYS_AP2CONN_WAKEUP_BIT (0x1 << 9) + +/*paged dump address start*/ +#define CONSYS_PAGED_DUMP_START_ADDR (0xf0088400) + +/*full dump address start*/ +#define CONSYS_FULL_DUMP_START_ADDR (0xf0090400) +#define CONSYS_FULL_DUMP_DLM_LEN (0x1f000) +#define CONSYS_FULL_DUMP_SYSB2_START (CONSYS_FULL_DUMP_START_ADDR + CONSYS_FULL_DUMP_DLM_LEN) +#define CONSYS_FULL_DUMP_SYSB2_LEN (0x6800) +#define CONSYS_FULL_DUMP_SYSB3_START (CONSYS_FULL_DUMP_SYSB2_START + CONSYS_FULL_DUMP_SYSB2_LEN) +#define CONSYS_FULL_DUMP_SYSB3_LEN (0x16800) + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +#if CONSYS_BT_WIFI_SHARE_V33 +struct bt_wifi_v33_status { + UINT32 counter; + UINT32 flags; + spinlock_t lock; +}; + +extern struct bt_wifi_v33_status gBtWifiV33; +#endif + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _MTK_MT6735_H_ */ diff --git a/drivers/misc/mediatek/connectivity/common/common_main/platform/include/mt6739.h b/drivers/misc/mediatek/connectivity/common/common_main/platform/include/mt6739.h new file mode 100644 index 0000000000000000000000000000000000000000..684e2afdcce0d8da93dc4aac4226375eaec5359a --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/platform/include/mt6739.h @@ -0,0 +1,236 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +/*! \file + * \brief Declaration of library functions + * + * Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#ifndef _MTK_MT6739_H_ +#define _MTK_MT6739_H_ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +#define CONSYS_BT_WIFI_SHARE_V33 0 +#define CONSYS_PMIC_CTRL_ENABLE 1 +#define CONSYS_EMI_MPU_SETTING 1 +#define CONSYS_AHB_CLK_MAGEMENT 1 +#define CONSYS_USE_PLATFORM_WRITE 1 +#define CONSYS_PWR_ON_OFF_API_AVAILABLE 1 +#define CONSYS_CLOCK_BUF_CTRL 1 +#define CONSYS_AFE_REG_SETTING 0 + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/*tag start:new platform need to make sure these define */ +#define PLATFORM_SOC_CHIP 0x6739 +/*tag end*/ + +/*device tree mode*/ +#if CONFIG_OF +/*TOPCKGEN_BASE*/ +#define CONSYS_TOP_CLKCG_CLR_OFFSET 0x00000084 +#define CONSYS_TOP_CLKCG_SET_OFFSET 0x00000054 +#define CONSYS_WD_SYS_RST_OFFSET 0x00000018 +#define CONSYS_AP2CONN_OSC_EN_OFFSET 0x00001f00 +#define CONSYS_EMI_MAPPING_OFFSET 0x00001380 +/*AP_RGU_BASE*/ +#define CONSYS_CPU_SW_RST_OFFSET 0x00000018 +/*SPM_BASE*/ +#define CONSYS_PWRON_CONFG_EN_OFFSET 0x00000000 +#define CONSYS_TOP1_PWR_CTRL_OFFSET 0x0000032c +#define CONSYS_PWR_CONN_ACK_OFFSET 0x00000180 +#define CONSYS_PWR_CONN_ACK_S_OFFSET 0x00000184 +/*CONN_MCU_CONFIG_BASE*/ +#define CONSYS_CHIP_ID_OFFSET 0x00000008 +#define CONSYS_ROM_RAM_DELSEL_OFFSET 0x00000114 +#define CONSYS_MCU_CFG_ACR_OFFSET 0x00000110 +#define CONSYS_CPUPCR_OFFSET 0x00000160 +#endif +/*AXI bus*/ +#define CONSYS_TOPAXI_PROT_EN_OFFSET 0x1220 +#define CONSYS_TOPAXI_PROT_STA1_OFFSET 0x1228 + +/*tag start: connsys register base address (hard code, no use) */ +#define AP_RGU_BASE 0xF0007000 +#define TOPCKGEN_BASE 0xF0000000 +#define SPM_BASE 0xF0006000 +#define CONN_MCU_CONFIG_BASE 0xF8070000 +/*GIC Interrupt ID*/ +#define MT_CONN2AP_BTIF_WAKEUP_IRQ_ID 270 +/*tag end*/ + +/*connsys register offset define(hard code mode)*/ +#if 1 + /*top clock gating control register */ +#define CONSYS_TOP_CLKCG_CLR_REG (TOPCKGEN_BASE + 0x00000084) +#define CONSYS_TOP_CLKCG_SET_REG (TOPCKGEN_BASE + 0x00000054) +#define CONSYS_TOP_CLKCG_BIT (0x1 << 26) + + /*SPM clock gating control register */ +#define CONSYS_PWRON_CONFG_EN_REG (SPM_BASE + 0x00000000) +#define CONSYS_PWRON_CONFG_EN_VALUE (0x0b160001) +#define CONSYS_PWRON_CONFG_DIS_VALUE (0x0b160000) +#endif + +#define CONSYS_CPU_SW_RST_REG (AP_RGU_BASE + 0x00000018) +#define CONSYS_TOP1_PWR_CTRL_REG (SPM_BASE + 0x0000032c) +#define CONSYS_PWR_CONN_ACK_REG (SPM_BASE + 0x00000180) +#define CONSYS_PWR_CONN_ACK_S_REG (SPM_BASE + 0x00000184) + +#define CONSYS_WD_SYS_RST_REG (TOPCKGEN_BASE + 0x00000018) +#define CONSYS_CHIP_ID_REG (CONN_MCU_CONFIG_BASE + 0x00000008) +#define CONSYS_ROM_RAM_DELSEL_REG (CONN_MCU_CONFIG_BASE + 0x00000114) +#define CONSYS_MCU_CFG_ACR_REG (CONN_MCU_CONFIG_BASE + 0x00000110) + +#if CONSYS_AFE_REG_SETTING +#define CONSYS_AFE_REG_BASE (0x180B2000) +#define CONSYS_AFE_REG_WBG_AFE_01_OFFSET (0x00000010) +#define CONSYS_AFE_REG_WBG_AFE_01_VALUE (0x00000000) +#define CONSYS_AFE_REG_WBG_PLL_03_OFFSET (0x00000038) +#define CONSYS_AFE_REG_WBG_PLL_03_VALUE (0x000C15F0) +#define CONSYS_AFE_REG_WBG_PLL_05_OFFSET (0x00000040) +#define CONSYS_AFE_REG_WBG_PLL_05_VALUE (0x07900020) +#define CONSYS_AFE_REG_WBG_WB_TX_01_OFFSET (0x00000088) +#define CONSYS_AFE_REG_WBG_WB_TX_01_VALUE (0x08440000) +#endif + +#define CONSYS_TOPAXI_PROT_EN (TOPCKGEN_BASE + 0x1220) +#define CONSYS_TOPAXI_PROT_STA1 (TOPCKGEN_BASE + 0x1228) +#define CONSYS_PROT_MASK ((0x1<<13) | (0x1<<14)) /* bit 13, 14 */ +/*CONSYS_CPU_SW_RST_REG*/ +#define CONSYS_CPU_SW_RST_BIT (0x1 << 12) +#define CONSYS_CPU_SW_RST_CTRL_KEY (0x88 << 24) + +/*CONSYS_TOP1_PWR_CTRL_REG*/ +#define CONSYS_SPM_PWR_RST_BIT (0x1 << 0) +#define CONSYS_SPM_PWR_ISO_S_BIT (0x1 << 1) +#define CONSYS_SPM_PWR_ON_BIT (0x1 << 2) +#define CONSYS_SPM_PWR_ON_S_BIT (0x1 << 3) +#define CONSYS_CLK_CTRL_BIT (0x1 << 4) +#define CONSYS_SRAM_CONN_PD_BIT (0x1 << 8) + +/*CONSYS_PWR_CONN_ACK_REG*/ +#define CONSYS_PWR_ON_ACK_BIT (0x1 << 1) + +/*CONSYS_PWR_CONN_ACK_S_REG*/ +#define CONSYS_PWR_CONN_ACK_S_BIT (0x1 << 1) + +/*CONSYS_WD_SYS_RST_REG*/ +#define CONSYS_WD_SYS_RST_CTRL_KEY (0x88 << 24) +#define CONSYS_WD_SYS_RST_BIT (0x1 << 9) + +/*CONSYS_MCU_CFG_ACR_REG*/ +#define CONSYS_MCU_CFG_ACR_MBIST_BIT (0x1 << 18) + +/* EMI part mapping & ctrl*/ +#define CONSYS_EMI_COREDUMP_OFFSET (0x80000) +#define CONSYS_EMI_AP_PHY_BASE (0x80080000) +#define CONSYS_EMI_FW_PHY_BASE (0xf0080000) +#define CONSYS_EMI_PAGED_TRACE_OFFSET (0x400) +#define CONSYS_EMI_PAGED_DUMP_OFFSET (0x8400) +#define CONSYS_EMI_FULL_DUMP_OFFSET (0x10400) + +/*cpupcr*/ +#define CONSYS_CPUPCR_REG (CONN_MCU_CONFIG_BASE + 0x00000160) +/*emi mapping*/ +#define CONSYS_EMI_MAPPING (TOPCKGEN_BASE + CONSYS_EMI_MAPPING_OFFSET) + +/*control app2cnn_osc_en*/ +#define CONSYS_AP2CONN_OSC_EN_REG (TOPCKGEN_BASE + 0x00001800) +#define CONSYS_AP2CONN_OSC_EN_BIT (0x1 << 10) +#define CONSYS_AP2CONN_WAKEUP_BIT (0x1 << 9) + +/*paged dump address start*/ +#define CONSYS_PAGED_DUMP_START_ADDR (0xf0088400) + +/*full dump address start*/ +#define CONSYS_FULL_DUMP_START_ADDR (0xf0090400) +#define CONSYS_FULL_DUMP_DLM_LEN (0x1f000) +#define CONSYS_FULL_DUMP_SYSB2_START (CONSYS_FULL_DUMP_START_ADDR + CONSYS_FULL_DUMP_DLM_LEN) +#define CONSYS_FULL_DUMP_SYSB2_LEN (0x6800) +#define CONSYS_FULL_DUMP_SYSB3_START (CONSYS_FULL_DUMP_SYSB2_START + CONSYS_FULL_DUMP_SYSB2_LEN) +#define CONSYS_FULL_DUMP_SYSB3_LEN (0x16800) + +#if defined(CONFIG_MTK_PMIC_CHIP_MT6353) +#define PMIC_DCXO_CW15 (0x0D46) +#define PMIC_DCXO_CW16 (0x0D48) +#define PMIC_DCXO_CW15_VAL (0x18) +#define AP_CONSYS_NOCO_CLOCK_BITA (0x1 << 11) +#define AP_CONSYS_NOCO_CLOCK_BITB (0x1 << 13) +#define AP_CONSYS_CO_CLOCK_BITA (0x1 << 10) +#define AP_CONSYS_CO_CLOCK_BITB (0x1 << 12) +#else +#define PMIC_DCXO_CW15 (0x701E) +#define PMIC_DCXO_CW16 (0x7000) +#define PMIC_DCXO_CW15_VAL (0x7) +#define AP_CONSYS_NOCO_CLOCK_BITA (0x1 << 7) +#define AP_CONSYS_NOCO_CLOCK_BITB (0x1 << 9) +#define AP_CONSYS_CO_CLOCK_BITA (0x1 << 6) +#define AP_CONSYS_CO_CLOCK_BITB (0x1 << 8) +#endif + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +#if CONSYS_BT_WIFI_SHARE_V33 +struct bt_wifi_v33_status { + UINT32 counter; + UINT32 flags; + spinlock_t lock; +}; + +extern struct bt_wifi_v33_status gBtWifiV33; +#endif + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************* +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _MTK_MT6739_H_ */ diff --git a/drivers/misc/mediatek/connectivity/common/common_main/platform/include/mt6761.h b/drivers/misc/mediatek/connectivity/common/common_main/platform/include/mt6761.h new file mode 100644 index 0000000000000000000000000000000000000000..1dc10c54b80a1c7efb92dc09f5e8a53d70748d59 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/platform/include/mt6761.h @@ -0,0 +1,261 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +/*! \file + * \brief Declaration of library functions + * + * Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#ifndef _MTK_MT6761_H_ +#define _MTK_MT6761_H_ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +#define CONSYS_BT_WIFI_SHARE_V33 0 +#define CONSYS_PMIC_CTRL_ENABLE 1 +#define CONSYS_AHB_CLK_MAGEMENT 1 +#define CONSYS_USE_PLATFORM_WRITE 1 +#define CONSYS_PWR_ON_OFF_API_AVAILABLE 1 +#define CONSYS_AFE_REG_SETTING 1 + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/*tag start:new platform need to make sure these define */ +#define PLATFORM_SOC_CHIP 0x6761 +/*tag end*/ + +/*device tree mode*/ +/* A-Die interface pinmux base */ +#define CONSYS_IF_PINMUX_REG_BASE 0x10005000 +#define CONSYS_IF_PINMUX_01_OFFSET 0x000003F0 +#define CONSYS_IF_PINMUX_01_MASK 0xFFFFFF88 +#define CONSYS_IF_PINMUX_01_VALUE 0x00000011 +#define CONSYS_IF_PINMUX_02_OFFSET 0x000003E0 +#define CONSYS_IF_PINMUX_02_MASK 0x8888888F +#define CONSYS_IF_PINMUX_02_VALUE 0x11111110 +#define CONSYS_IF_DRV_PINMUX_REG_BASE 0x10420000 +#define CONSYS_IF_DRV_PINMUX_MASK 0xF8FFFFFF + +/*TOPCKGEN_BASE*/ +#define CONSYS_AP2CONN_OSC_EN_OFFSET 0x00000f00 +#define CONSYS_EMI_MAPPING_OFFSET 0x00000380 +#define CONSYS_EMI_PERI_MAPPING_OFFSET 0x00000388 +/*AP_RGU_BASE*/ +#define CONSYS_CPU_SW_RST_OFFSET 0x00000018 +/*SPM_BASE*/ +#define CONSYS_PWRON_CONFG_EN_OFFSET 0x00000000 +#define CONSYS_TOP1_PWR_CTRL_OFFSET 0x0000032C +#define CONSYS_PWR_CONN_ACK_OFFSET 0x00000180 +#define CONSYS_PWR_CONN_ACK_S_OFFSET 0x00000184 +#define CONSYS_SPM_APSRC_OFFSET 0x000006f8 +#define CONSYS_SPM_APSRC_VALUE 0x00000005 +#define CONSYS_SPM_DDR_EN_OFFSET 0x000006fc +#define CONSYS_SPM_DDR_EN_VALUE 0x00050505 +/*CONN_MCU_CONFIG_BASE*/ +#define CONSYS_IP_VER_OFFSET 0x00000010 +#define CONSYS_CONF_ID_OFFSET 0x0000001c +#define CONSYS_HW_ID_OFFSET 0x00000000 +#define CONSYS_FW_ID_OFFSET 0x00000004 +#define CONSYS_MCU_CFG_ACR_OFFSET 0x00000140 +#define CONSYS_CPUPCR_OFFSET 0x00000104 +#define CONSYS_SW_IRQ_OFFSET 0x00000150 +#define CONSYS_CLOCK_CONTROL 0x00000100 +#define CONSYS_BUS_CONTROL 0x00000110 +#define CONSYS_DEBUG_SELECT 0x00000400 +#define CONSYS_DEBUG_STATUS 0x0000040c +#define CONSYS_EMI_CTRL_VALUE (1 << 0 | 1 << 15 | 1 << 21) +/*CONN_HIF_TOP*/ +#define CONSYS_HIF_TOP_MISC 0x00000104 +#define CONSYS_HIF_DBG_IDX 0x0000012C +#define CONSYS_HIF_DBG_PROBE 0x00000130 +#define CONSYS_HIF_BUSY_STATUS 0x00000138 +#define CONSYS_HIF_PDMA_AXI_RREADY 0x00000154 +#define CONSYS_HIF_PDMA_BUSY_STATUS 0x00000168 + +/*CONN_HIF_ON_BASE*/ +#define CONN_HIF_ON_BASE_ADDR (0x18007000) +#define CONSYS_BUSY_OFFSET 0x110 +#define CONSYS_BUSY_BIT (0x1 << 27) +#define CONSYS_CLOCK_CHECK_VALUE 0x30000 +#define CONSYS_HCLK_CHECK_BIT (0x1 << 16) +#define CONSYS_OSCCLK_CHECK_BIT (0x1 << 17) +#define CONSYS_SLEEP_CHECK_BIT (0x1 << 18) + +/*CONN_TOP_MISC_ON_BASE*/ +#define CONN_ON_HOST_CSR_MISC 0x14c +#define CONN_ON_IRQ_CTL 0x170 +#define CONN_ON_IRQ_STATUS 0x174 + + +/*AXI bus*/ +#define CONSYS_AHBAXI_PROT_EN_OFFSET 0x220 +#define CONSYS_AHBAXI_PROT_STA_OFFSET 0x228 +#define CONSYS_AXI_TX_PROT_EN_OFFSET 0x250 +#define CONSYS_AXI_TX_PROT_STA_OFFSET 0x258 +#define CONSYS_PROT_MASK ((0x1<<13) | (0x1<<14)) /* bit 13, 14 */ +#define CONSYS_TX_PROT_MASK (0x1<<18) /* bit 18 */ +#define CONSYS_PDMA_AXI_RREADY_MASK (0x1 << 1) /* bit 1 */ + +/*SPM clock gating control register */ +#define CONSYS_PWRON_CONFG_EN_VALUE (0x0b160001) +#define CONSYS_PWRON_CONFG_DIS_VALUE (0x0b160000) + +#if CONSYS_AFE_REG_SETTING +#define CONSYS_AFE_REG_BASE (0x180B3000) +#define CONSYS_AFE_RG_WBG_01_OFFSET (0x00000010) +#define CONSYS_AFE_RG_WBG_01_VALUE (0x00000004) +#define CONSYS_AFE_RG_WBG_GPS_01_OFFSET (0x00000040) +#define CONSYS_AFE_RG_WBG_GPS_01_VALUE (0xEF904400) +#define CONSYS_AFE_RG_WBG_BT_RX_01_OFFSET (0x00000048) +#define CONSYS_AFE_RG_WBG_BT_RX_01_VALUE (0xEFC82200) +#define CONSYS_AFE_RG_WBG_WF0_RX_01_OFFSET (0x00000068) +#define CONSYS_AFE_RG_WBG_WF0_RX_01_VALUE (0xFBF21102) +#endif + +#define CONSYS_COCLOCK_STABLE_TIME_BASE (0x180C1200) +#define CONSYS_COCLOCK_ACK_ENABLE_OFFSET (0x4) +#define CONSYS_COCLOCK_ACK_ENABLE_BIT (1 << 0) +#define CONSYS_COCLOCK_STABLE_TIME (0x2223) +#define CONSYS_COCLOCK_STABLE_TIME_MASK (0xffff0000) + +/*CONSYS_CPU_SW_RST_REG*/ +#define CONSYS_CPU_SW_RST_BIT (0x1 << 12) +#define CONSYS_CPU_SW_RST_CTRL_KEY (0x88 << 24) +#define CONSYS_SW_RST_BIT (0x1 << 9) + +/*CONSYS_TOP1_PWR_CTRL_REG*/ +#define CONSYS_SPM_PWR_RST_BIT (0x1 << 0) +#define CONSYS_SPM_PWR_ISO_S_BIT (0x1 << 1) +#define CONSYS_SPM_PWR_ON_BIT (0x1 << 2) +#define CONSYS_SPM_PWR_ON_S_BIT (0x1 << 3) +#define CONSYS_CLK_CTRL_BIT (0x1 << 4) +#define CONSYS_SRAM_CONN_PD_BIT (0x1 << 8) + +/*CONSYS_PWR_CONN_ACK_REG*/ +#define CONSYS_PWR_ON_ACK_BIT (0x1 << 1) + +/*CONSYS_PWR_CONN_ACK_S_REG*/ +#define CONSYS_PWR_ON_ACK_S_BIT (0x1 << 1) + +/*CONSYS_PWR_CONN_TOP2_ACK_REG*/ +#define CONSYS_TOP2_PWR_ON_ACK_BIT (0x1 << 30) + +/*CONSYS_PWR_CONN_TOP2_ACK_S_REG*/ +#define CONSYS_TOP2_PWR_ON_ACK_S_BIT (0x1 << 30) + +/*CONSYS_WD_SYS_RST_REG*/ +#define CONSYS_WD_SYS_RST_CTRL_KEY (0x88 << 24) +#define CONSYS_WD_SYS_RST_BIT (0x1 << 9) + +/*CONSYS_MCU_CFG_ACR_REG*/ +#define CONSYS_MCU_CFG_ACR_MBIST_BIT (0x1 << 0 | 0x1 << 1) + +/*control app2cnn_osc_en*/ +#define CONSYS_AP2CONN_OSC_EN_BIT (0x1 << 10) +#define CONSYS_AP2CONN_WAKEUP_BIT (0x1 << 9) + +/* EMI part mapping & ctrl*/ +#define CONSYS_EMI_COREDUMP_OFFSET (0x68000) +#define CONSYS_EMI_AP_PHY_OFFSET (0x00000) +#define CONSYS_EMI_AP_PHY_BASE (0x80068000) +#define CONSYS_EMI_FW_PHY_BASE (0xf0068000) +#define CONSYS_EMI_PAGED_TRACE_OFFSET (0x400) +#define CONSYS_EMI_PAGED_DUMP_OFFSET (0x8400) +#define CONSYS_EMI_FULL_DUMP_OFFSET (0x10400) +#define CONSYS_EMI_MET_DATA_OFFSET (0x0) + +#define CONSYS_EMI_RAM_BT_BUILDTIME_OFFSET (0x68300) +#define CONSYS_EMI_RAM_WIFI_BUILDTIME_OFFSET (0x68310) +#define CONSYS_EMI_RAM_MCU_BUILDTIME_OFFSET (0x68320) +#define CONSYS_EMI_PATCH_MCU_BUILDTIME_OFFSET (0x68330) + +/*CONSYS_MCU_CFG_DBG_LP_INFO*/ +#define CONN_CFG_ON_CONN_ON_HOST_MAILBOX_MCU_ADDR (conn_reg.mcu_cfg_on_base + 0x104) +#define CONN_CFG_ON_CONN_ON_MON_CTL_ADDR (conn_reg.mcu_top_misc_on_base + 0x320) +#define CONN_CFG_ON_CONN_ON_DBGSEL_ADDR (conn_reg.mcu_top_misc_on_base + 0x310) +#define CONN_CFG_ON_CONN_ON_MON_FLAG_RECORD_ADDR (conn_reg.mcu_top_misc_on_base + 0x340) +#define CONN_CFG_ON_CONN_ON_MON_FLAG_RECORD_MAPPING_AP_ADDR (0x180c1340) + +/* default coex wmt ant_sel cr address */ +#define DEFAULT_COEX_WMT_ANTSEL_0_POLARITY_CR 0x80025310 +#define DEFAULT_COEX_WMT_ANTSEL_1_POLARITY_CR 0x80025310 +#define DEFAULT_COEX_WMT_ANTSEL_2_POLARITY_CR 0x80025314 +#define DEFAULT_COEX_WMT_ANTSEL_3_POLARITY_CR 0x80025314 +#define DEFAULT_COEX_WMT_ANTSEL_4_POLARITY_CR 0x80025318 +#define DEFAULT_COEX_WMT_ANTSEL_5_POLARITY_CR 0x80025318 +#define DEFAULT_COEX_WMT_ANTSEL_6_POLARITY_CR 0x8002531C +#define DEFAULT_COEX_WMT_ANTSEL_7_POLARITY_CR 0x8002531C + +/* default coex wmt ant_sel cr bit */ +#define DEFAULT_COEX_WMT_ANTSEL_0_POLARITY_BIT 8 +#define DEFAULT_COEX_WMT_ANTSEL_1_POLARITY_BIT 24 +#define DEFAULT_COEX_WMT_ANTSEL_2_POLARITY_BIT 8 +#define DEFAULT_COEX_WMT_ANTSEL_3_POLARITY_BIT 24 +#define DEFAULT_COEX_WMT_ANTSEL_4_POLARITY_BIT 8 +#define DEFAULT_COEX_WMT_ANTSEL_5_POLARITY_BIT 24 +#define DEFAULT_COEX_WMT_ANTSEL_6_POLARITY_BIT 8 +#define DEFAULT_COEX_WMT_ANTSEL_7_POLARITY_BIT 24 + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +#ifdef CONSYS_BT_WIFI_SHARE_V33 +struct bt_wifi_v33_status { + UINT32 counter; + UINT32 flags; + spinlock_t lock; +}; + +extern struct bt_wifi_v33_status gBtWifiV33; +#endif + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************* +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _MTK_MT6761_H_ */ diff --git a/drivers/misc/mediatek/connectivity/common/common_main/platform/include/mt6765.h b/drivers/misc/mediatek/connectivity/common/common_main/platform/include/mt6765.h new file mode 100644 index 0000000000000000000000000000000000000000..a8e9fce1bad06f8466b11a9fa311c939ac84a92c --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/platform/include/mt6765.h @@ -0,0 +1,248 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +/*! \file + * \brief Declaration of library functions + * + * Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#ifndef _MTK_MT6765_H_ +#define _MTK_MT6765_H_ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +#define CONSYS_BT_WIFI_SHARE_V33 0 +#define CONSYS_PMIC_CTRL_ENABLE 1 +#define CONSYS_AHB_CLK_MAGEMENT 1 +#define CONSYS_USE_PLATFORM_WRITE 1 +#define CONSYS_PWR_ON_OFF_API_AVAILABLE 1 +#define CONSYS_AFE_REG_SETTING 0 + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/*tag start:new platform need to make sure these define */ +#define PLATFORM_SOC_CHIP 0x6765 +/*tag end*/ + +/*device tree mode*/ +/* A-Die interface pinmux base */ +#define CONSYS_IF_PINMUX_REG_BASE 0x10005000 +#define CONSYS_IF_PINMUX_01_OFFSET 0x000003F0 +#define CONSYS_IF_PINMUX_01_MASK 0xFFFFFF88 +#define CONSYS_IF_PINMUX_01_VALUE 0x00000011 +#define CONSYS_IF_PINMUX_02_OFFSET 0x000003E0 +#define CONSYS_IF_PINMUX_02_MASK 0x8888888F +#define CONSYS_IF_PINMUX_02_VALUE 0x11111110 +#define CONSYS_IF_DRV_PINMUX_REG_BASE 0x10420000 +#define CONSYS_IF_DRV_PINMUX_MASK 0xF8FFFFFF + +/*TOPCKGEN_BASE*/ +#define CONSYS_AP2CONN_OSC_EN_OFFSET 0x00000f00 +#define CONSYS_EMI_MAPPING_OFFSET 0x00000380 +#define CONSYS_EMI_PERI_MAPPING_OFFSET 0x00000388 +/*AP_RGU_BASE*/ +#define CONSYS_CPU_SW_RST_OFFSET 0x00000018 +/*SPM_BASE*/ +#define CONSYS_PWRON_CONFG_EN_OFFSET 0x00000000 +#define CONSYS_TOP1_PWR_CTRL_OFFSET 0x0000032C +#define CONSYS_PWR_CONN_ACK_OFFSET 0x00000180 +#define CONSYS_PWR_CONN_ACK_S_OFFSET 0x00000184 +#define CONSYS_SPM_APSRC_OFFSET 0x000006f8 +#define CONSYS_SPM_APSRC_VALUE 0x00000005 +#define CONSYS_SPM_DDR_EN_OFFSET 0x000006fc +#define CONSYS_SPM_DDR_EN_VALUE 0x00050505 +/*CONN_MCU_CONFIG_BASE*/ +#define CONSYS_IP_VER_OFFSET 0x00000010 +#define CONSYS_CONF_ID_OFFSET 0x0000001c +#define CONSYS_HW_ID_OFFSET 0x00000000 +#define CONSYS_FW_ID_OFFSET 0x00000004 +#define CONSYS_MCU_CFG_ACR_OFFSET 0x00000140 +#define CONSYS_CPUPCR_OFFSET 0x00000104 +#define CONSYS_SW_IRQ_OFFSET 0x00000150 +#define CONSYS_MCU_ROM_DELSEL_OFFSET 0x00000114 +#define CONSYS_MCU_ROM_DELSEL_VALUE 0x00000017 +#define CONSYS_EMI_CTRL_VALUE (1 << 0 | 1 << 15 | 1 << 21) +/*CONN_HIF_TOP*/ +#define CONSYS_HIF_PDMA_AXI_RREADY 0x00000154 + +/*CONN_HIF_ON_BASE*/ +#define CONN_HIF_ON_BASE_ADDR (0x18007000) +#define CONSYS_BUSY_OFFSET 0x110 +#define CONSYS_BUSY_BIT (0x1 << 27) +#define CONSYS_CLOCK_CHECK_VALUE 0x30000 +#define CONSYS_HCLK_CHECK_BIT (0x1 << 16) +#define CONSYS_OSCCLK_CHECK_BIT (0x1 << 17) +#define CONSYS_SLEEP_CHECK_BIT (0x1 << 18) + +/*AXI bus*/ +#define CONSYS_AHBAXI_PROT_EN_OFFSET 0x220 +#define CONSYS_AHBAXI_PROT_STA0_OFFSET 0x224 +#define CONSYS_AHBAXI_PROT_STA1_OFFSET 0x228 +#define CONSYS_AXI_TX_PROT_EN_OFFSET 0x250 +#define CONSYS_AXI_TX_PROT_STA_OFFSET 0x258 +#define CONSYS_PROT_MASK ((0x1<<13) | (0x1<<14)) /* bit 13, 14 */ +#define CONSYS_TX_PROT_MASK (0x1<<18) /* bit 18 */ +#define CONSYS_PDMA_AXI_RREADY_MASK (0x1 << 1) /* bit 1 */ + +/* INFRACFG_REG_BASE */ +#define INFRAGCFG_REG_TOPAXI_SI3_STA_OFFSET 0x02C +#define INFRAGCFG_REG_TOPAXI_MI_STA_OFFSET 0x008 + +/*SPM clock gating control register */ +#define CONSYS_PWRON_CONFG_EN_VALUE (0x0b160001) +#define CONSYS_PWRON_CONFG_DIS_VALUE (0x0b160000) + +#if CONSYS_AFE_REG_SETTING +#define CONSYS_AFE_REG_BASE (0x180B6000) +#define CONSYS_AFE_RG_WBG_PLL_03_OFFSET (0x00000038) +#define CONSYS_AFE_RG_WBG_PLL_03_VALUE (0x000C1DF0) +#define CONSYS_AFE_RG_WBG_GPS_02_OFFSET (0x00000054) +#define CONSYS_AFE_RG_WBG_GPS_02_VALUE (0x110A2000) +#endif + +#define CONSYS_COCLOCK_STABLE_TIME_BASE (0x180C1200) +#define CONSYS_COCLOCK_ACK_ENABLE_OFFSET (0x4) +#define CONSYS_COCLOCK_ACK_ENABLE_BIT (1 << 0) +#define CONSYS_COCLOCK_STABLE_TIME (0x2223) +#define CONSYS_COCLOCK_STABLE_TIME_MASK (0xffff0000) + +/*CONSYS_CPU_SW_RST_REG*/ +#define CONSYS_CPU_SW_RST_BIT (0x1 << 12) +#define CONSYS_CPU_SW_RST_CTRL_KEY (0x88 << 24) +#define CONSYS_SW_RST_BIT (0x1 << 9) + +/*CONSYS_TOP1_PWR_CTRL_REG*/ +#define CONSYS_SPM_PWR_RST_BIT (0x1 << 0) +#define CONSYS_SPM_PWR_ISO_S_BIT (0x1 << 1) +#define CONSYS_SPM_PWR_ON_BIT (0x1 << 2) +#define CONSYS_SPM_PWR_ON_S_BIT (0x1 << 3) +#define CONSYS_CLK_CTRL_BIT (0x1 << 4) +#define CONSYS_SRAM_CONN_PD_BIT (0x1 << 8) + +/*CONSYS_PWR_CONN_ACK_REG*/ +#define CONSYS_PWR_ON_ACK_BIT (0x1 << 1) + +/*CONSYS_PWR_CONN_ACK_S_REG*/ +#define CONSYS_PWR_ON_ACK_S_BIT (0x1 << 1) + +/*CONSYS_PWR_CONN_TOP2_ACK_REG*/ +#define CONSYS_TOP2_PWR_ON_ACK_BIT (0x1 << 30) + +/*CONSYS_PWR_CONN_TOP2_ACK_S_REG*/ +#define CONSYS_TOP2_PWR_ON_ACK_S_BIT (0x1 << 30) + +/*CONSYS_WD_SYS_RST_REG*/ +#define CONSYS_WD_SYS_RST_CTRL_KEY (0x88 << 24) +#define CONSYS_WD_SYS_RST_BIT (0x1 << 9) + +/*CONSYS_MCU_CFG_ACR_REG*/ +#define CONSYS_MCU_CFG_ACR_MBIST_BIT (0x1 << 0 | 0x1 << 1) + +/*control app2cnn_osc_en*/ +#define CONSYS_AP2CONN_OSC_EN_BIT (0x1 << 10) +#define CONSYS_AP2CONN_WAKEUP_BIT (0x1 << 9) + +/* EMI part mapping & ctrl*/ +#define CONSYS_EMI_COREDUMP_OFFSET (0x68000) +#define CONSYS_EMI_AP_PHY_BASE (0x80068000) +#define CONSYS_EMI_FW_PHY_BASE (0xf0068000) +#define CONSYS_EMI_PAGED_TRACE_OFFSET (0x400) +#define CONSYS_EMI_PAGED_DUMP_OFFSET (0x8400) +#define CONSYS_EMI_FULL_DUMP_OFFSET (0x10400) +#define CONSYS_EMI_MET_DATA_OFFSET (0x2e500) + +#define CONSYS_EMI_RAM_BT_BUILDTIME_OFFSET (0x68300) +#define CONSYS_EMI_RAM_WIFI_BUILDTIME_OFFSET (0x68310) +#define CONSYS_EMI_RAM_MCU_BUILDTIME_OFFSET (0x68320) +#define CONSYS_EMI_PATCH_MCU_BUILDTIME_OFFSET (0x68330) + +/*CONSYS_MCU_CFG_DBG_LP_INFO*/ +#define CONN_CFG_ON_CONN_ON_HOST_MAILBOX_MCU_ADDR (conn_reg.mcu_cfg_on_base + 0x104) +#define CONN_CFG_ON_CONN_ON_MON_CTL_ADDR (conn_reg.mcu_top_misc_on_base + 0x320) +#define CONN_CFG_ON_CONN_ON_DBGSEL_ADDR (conn_reg.mcu_top_misc_on_base + 0x310) +#define CONN_CFG_ON_CONN_ON_MON_FLAG_RECORD_ADDR (conn_reg.mcu_top_misc_on_base + 0x340) +#define CONN_CFG_ON_CONN_ON_MON_FLAG_RECORD_MAPPING_AP_ADDR (0x180c1340) + +/* default coex wmt ant_sel cr address */ +#define DEFAULT_COEX_WMT_ANTSEL_0_POLARITY_CR 0x80025310 +#define DEFAULT_COEX_WMT_ANTSEL_1_POLARITY_CR 0x80025310 +#define DEFAULT_COEX_WMT_ANTSEL_2_POLARITY_CR 0x80025314 +#define DEFAULT_COEX_WMT_ANTSEL_3_POLARITY_CR 0x80025314 +#define DEFAULT_COEX_WMT_ANTSEL_4_POLARITY_CR 0x80025318 +#define DEFAULT_COEX_WMT_ANTSEL_5_POLARITY_CR 0x80025318 +#define DEFAULT_COEX_WMT_ANTSEL_6_POLARITY_CR 0x8002531C +#define DEFAULT_COEX_WMT_ANTSEL_7_POLARITY_CR 0x8002531C + +/* default coex wmt ant_sel cr bit */ +#define DEFAULT_COEX_WMT_ANTSEL_0_POLARITY_BIT 8 +#define DEFAULT_COEX_WMT_ANTSEL_1_POLARITY_BIT 24 +#define DEFAULT_COEX_WMT_ANTSEL_2_POLARITY_BIT 8 +#define DEFAULT_COEX_WMT_ANTSEL_3_POLARITY_BIT 24 +#define DEFAULT_COEX_WMT_ANTSEL_4_POLARITY_BIT 8 +#define DEFAULT_COEX_WMT_ANTSEL_5_POLARITY_BIT 24 +#define DEFAULT_COEX_WMT_ANTSEL_6_POLARITY_BIT 8 +#define DEFAULT_COEX_WMT_ANTSEL_7_POLARITY_BIT 24 + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +#ifdef CONSYS_BT_WIFI_SHARE_V33 +struct bt_wifi_v33_status { + UINT32 counter; + UINT32 flags; + spinlock_t lock; +}; + +extern struct bt_wifi_v33_status gBtWifiV33; +#endif + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************* +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _MTK_MT6765_H_ */ diff --git a/drivers/misc/mediatek/connectivity/common/common_main/platform/include/mt6768.h b/drivers/misc/mediatek/connectivity/common/common_main/platform/include/mt6768.h new file mode 100644 index 0000000000000000000000000000000000000000..b8544ce45c1e792b70277173b3fdc15de2351750 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/platform/include/mt6768.h @@ -0,0 +1,242 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +/*! \file + * \brief Declaration of library functions + * + * Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#ifndef _MTK_MT6768_H_ +#define _MTK_MT6768_H_ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +#define CONSYS_BT_WIFI_SHARE_V33 0 +#define CONSYS_PMIC_CTRL_ENABLE 1 +#define CONSYS_AHB_CLK_MAGEMENT 1 +#define CONSYS_USE_PLATFORM_WRITE 1 +#define CONSYS_PWR_ON_OFF_API_AVAILABLE 1 +#define CONSYS_AFE_REG_SETTING 1 + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/*tag start:new platform need to make sure these define */ +#define PLATFORM_SOC_CHIP 0x6768 +/*tag end*/ + +/*device tree mode*/ +/* A-Die interface pinmux base */ +#define CONSYS_IF_PINMUX_REG_BASE 0x10005000 +#define CONSYS_IF_PINMUX_01_OFFSET 0x000003F0 +#define CONSYS_IF_PINMUX_01_MASK 0xFFFFFF88 +#define CONSYS_IF_PINMUX_01_VALUE 0x00000011 +#define CONSYS_IF_PINMUX_02_OFFSET 0x000003E0 +#define CONSYS_IF_PINMUX_02_MASK 0x8888888F +#define CONSYS_IF_PINMUX_02_VALUE 0x11111110 +#define CONSYS_IF_DRV_PINMUX_REG_BASE 0x10420000 +#define CONSYS_IF_DRV_PINMUX_MASK 0xF8FFFFFF + +/*TOPCKGEN_BASE*/ +#define CONSYS_AP2CONN_OSC_EN_OFFSET 0x00000f00 +#define CONSYS_EMI_MAPPING_OFFSET 0x00000380 +#define CONSYS_EMI_PERI_MAPPING_OFFSET 0x00000388 +/*AP_RGU_BASE*/ +#define CONSYS_CPU_SW_RST_OFFSET 0x00000018 +/*SPM_BASE*/ +#define CONSYS_PWRON_CONFG_EN_OFFSET 0x00000000 +#define CONSYS_TOP1_PWR_CTRL_OFFSET 0x0000032C +#define CONSYS_PWR_CONN_ACK_OFFSET 0x00000180 +#define CONSYS_PWR_CONN_ACK_S_OFFSET 0x00000184 +#define CONSYS_SPM_APSRC_OFFSET 0x000006f8 +#define CONSYS_SPM_APSRC_VALUE 0x00000005 +#define CONSYS_SPM_DDR_EN_OFFSET 0x000006fc +#define CONSYS_SPM_DDR_EN_VALUE 0x00050505 +/*CONN_MCU_CONFIG_BASE*/ +#define CONSYS_IP_VER_OFFSET 0x00000010 +#define CONSYS_CONF_ID_OFFSET 0x0000001c +#define CONSYS_HW_ID_OFFSET 0x00000000 +#define CONSYS_FW_ID_OFFSET 0x00000004 +#define CONSYS_IP_VER_ID 0x10020501 +#define CONSYS_MCU_CFG_ACR_OFFSET 0x00000140 +#define CONSYS_CPUPCR_OFFSET 0x00000104 +#define EMI_CONTROL_DBG_PROBE 0x00000144 +#define CONSYS_SW_IRQ_OFFSET 0x00000150 +#define CONSYS_MCU_ROM_DELSEL_OFFSET 0x00000114 +#define CONSYS_MCU_ROM_DELSEL_VALUE 0x00000017 +#define CONSYS_EMI_CTRL_VALUE (1 << 21) +/*CONN_HIF_TOP*/ +#define CONSYS_HIF_PDMA_AXI_RREADY 0x00000154 + +#define CONSYS_HIF_TOP_MISC 0x00000104 +#define CONSYS_HIF_DBG_IDX 0x0000012C +#define CONSYS_HIF_DBG_PROBE 0x00000130 +#define CONSYS_HIF_BUSY_STATUS 0x00000138 +#define CONSYS_HIF_PDMA_AXI_RREADY 0x00000154 +#define CONSYS_HIF_PDMA_BUSY_STATUS 0x00000168 + +/*CONN_HIF_ON_BASE*/ +#define CONN_HIF_ON_BASE_ADDR (0x18007000) +#define CONSYS_CLOCK_CONTROL 0x00000100 +#define CONSYS_BUS_CONTROL 0x00000110 +#define CONSYS_DEBUG_SELECT 0x00000400 +#define CONSYS_DEBUG_STATUS 0x0000040c + +#define CONSYS_BUSY_OFFSET 0x110 +#define CONSYS_BUSY_BIT (0x1 << 27) +#define CONSYS_CLOCK_CHECK_VALUE 0x30000 +#define CONSYS_HCLK_CHECK_BIT (0x1 << 16) +#define CONSYS_OSCCLK_CHECK_BIT (0x1 << 17) +#define CONSYS_SLEEP_CHECK_BIT (0x1 << 18) + +/*AXI bus*/ +#define CONSYS_AHBAXI_PROT_EN_OFFSET 0x220 +#define CONSYS_AHBAXI_PROT_STA_OFFSET 0x228 +#define CONSYS_AXI_TX_PROT_EN_OFFSET 0x250 +#define CONSYS_AXI_TX_PROT_STA_OFFSET 0x258 +#define CONSYS_PROT_MASK ((0x1<<13) | (0x1<<14)) /* bit 13, 14 */ +#define CONSYS_TX_PROT_MASK (0x1<<18) /* bit 18 */ +#define CONSYS_PDMA_AXI_RREADY_MASK (0x1 << 1) /* bit 1 */ + +/* toppose_restore_done rollback CR */ +#define CONSYS_TOPPOSE_RESTORE_OFFSET 0x600 +#define CONSYS_TOPPOSE_RESTORE_MASK 0xFF7FFFFF /* bit 23 */ +#define CONSYS_TOPPOSE_RESTORE_VALUE (0x1 << 23) + +/*SPM clock gating control register */ +#define CONSYS_PWRON_CONFG_EN_VALUE (0x0b160001) +#define CONSYS_PWRON_CONFG_DIS_VALUE (0x0b160000) + +#if CONSYS_AFE_REG_SETTING +#define CONSYS_AFE_REG_BASE (0x180B3000) +#define CONSYS_AFE_RG_WBG_PLL_03_OFFSET (0x00000034) +#define CONSYS_AFE_RG_WBG_PLL_03_VALUE (0x000C1DF0) +#define CONSYS_AFE_RG_WBG_GPS_02_OFFSET (0x00000054) +#define CONSYS_AFE_RG_WBG_GPS_02_VALUE (0x110A2000) +#endif + +#define CONSYS_COCLOCK_STABLE_TIME_BASE (0x180C1200) +#define CONSYS_COCLOCK_ACK_ENABLE_OFFSET (0x4) +#define CONSYS_COCLOCK_ACK_ENABLE_BIT (1 << 0) +#define CONSYS_COCLOCK_STABLE_TIME (0x708) +#define CONSYS_COCLOCK_STABLE_TIME_MASK (0xffff0000) + +/*CONSYS_CPU_SW_RST_REG*/ +#define CONSYS_CPU_SW_RST_BIT (0x1 << 12) +#define CONSYS_CPU_SW_RST_CTRL_KEY (0x88 << 24) +#define CONSYS_SW_RST_BIT (0x1 << 9) + +/*CONSYS_TOP1_PWR_CTRL_REG*/ +#define CONSYS_SPM_PWR_RST_BIT (0x1 << 0) +#define CONSYS_SPM_PWR_ISO_S_BIT (0x1 << 1) +#define CONSYS_SPM_PWR_ON_BIT (0x1 << 2) +#define CONSYS_SPM_PWR_ON_S_BIT (0x1 << 3) +#define CONSYS_CLK_CTRL_BIT (0x1 << 4) +#define CONSYS_SRAM_CONN_PD_BIT (0x1 << 8) + +/*CONSYS_PWR_CONN_ACK_REG*/ +#define CONSYS_PWR_ON_ACK_BIT (0x1 << 1) + +/*CONSYS_PWR_CONN_ACK_S_REG*/ +#define CONSYS_PWR_ON_ACK_S_BIT (0x1 << 1) + +/*CONSYS_PWR_CONN_TOP2_ACK_REG*/ +#define CONSYS_TOP2_PWR_ON_ACK_BIT (0x1 << 30) + +/*CONSYS_PWR_CONN_TOP2_ACK_S_REG*/ +#define CONSYS_TOP2_PWR_ON_ACK_S_BIT (0x1 << 30) + +/*CONSYS_WD_SYS_RST_REG*/ +#define CONSYS_WD_SYS_RST_CTRL_KEY (0x88 << 24) +#define CONSYS_WD_SYS_RST_BIT (0x1 << 9) + +/*CONSYS_MCU_CFG_ACR_REG*/ +#define CONSYS_MCU_CFG_ACR_MBIST_BIT (0x1 << 0 | 0x1 << 1) + +/*control app2cnn_osc_en*/ +#define CONSYS_AP2CONN_OSC_EN_BIT (0x1 << 10) +#define CONSYS_AP2CONN_WAKEUP_BIT (0x1 << 9) + +/* EMI part mapping & ctrl*/ +#define CONSYS_EMI_COREDUMP_OFFSET (0x68000) +#define CONSYS_EMI_AP_PHY_BASE (0x80068000) +#define CONSYS_EMI_FW_PHY_BASE (0xf0068000) +#define CONSYS_EMI_PAGED_TRACE_OFFSET (0x400) +#define CONSYS_EMI_PAGED_DUMP_OFFSET (0x8400) +#define CONSYS_EMI_FULL_DUMP_OFFSET (0x10400) +#define CONSYS_EMI_MET_DATA_OFFSET (0x2e500) + +#define CONSYS_EMI_RAM_BT_BUILDTIME_OFFSET (0x68300) +#define CONSYS_EMI_RAM_WIFI_BUILDTIME_OFFSET (0x68310) +#define CONSYS_EMI_RAM_MCU_BUILDTIME_OFFSET (0x68320) +#define CONSYS_EMI_PATCH_MCU_BUILDTIME_OFFSET (0x68330) + +/*CONSYS_MCU_CFG_DBG_LP_INFO*/ +#define CONN_CFG_ON_CONN_ON_HOST_MAILBOX_MCU_ADDR (conn_reg.mcu_cfg_on_base + 0x104) +#define CONN_CFG_ON_CONN_ON_MON_CTL_ADDR (conn_reg.mcu_top_misc_on_base + 0x320) +#define CONN_CFG_ON_CONN_ON_DBGSEL_ADDR (conn_reg.mcu_top_misc_on_base + 0x310) +#define CONN_CFG_ON_CONN_ON_MON_FLAG_RECORD_ADDR (conn_reg.mcu_top_misc_on_base + 0x340) +#define CONN_CFG_ON_CONN_ON_MON_FLAG_RECORD_MAPPING_AP_ADDR (0x180c1340) + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +#ifdef CONSYS_BT_WIFI_SHARE_V33 +struct bt_wifi_v33_status { + UINT32 counter; + UINT32 flags; + spinlock_t lock; +}; + +extern struct bt_wifi_v33_status gBtWifiV33; +#endif + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************* +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _MTK_MT6768_H_ */ diff --git a/drivers/misc/mediatek/connectivity/common/common_main/platform/include/mt6771.h b/drivers/misc/mediatek/connectivity/common/common_main/platform/include/mt6771.h new file mode 100644 index 0000000000000000000000000000000000000000..33d983cd6e6ee4f251bf2f8142f1c379e9b81e2a --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/platform/include/mt6771.h @@ -0,0 +1,186 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +/*! \file + * \brief Declaration of library functions + * + * Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#ifndef _MTK_MT6771_H_ +#define _MTK_MT6771_H_ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +#define CONSYS_BT_WIFI_SHARE_V33 0 +#define CONSYS_PMIC_CTRL_ENABLE 1 +#define CONSYS_AHB_CLK_MAGEMENT 1 +#define CONSYS_USE_PLATFORM_WRITE 1 +#define CONSYS_PWR_ON_OFF_API_AVAILABLE 1 +#define CONSYS_AFE_REG_SETTING 1 + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/*tag start:new platform need to make sure these define */ +#define PLATFORM_SOC_CHIP 0x6771 +/*tag end*/ + +/*device tree mode*/ +/* A-Die interface pinmux base */ +#define CONSYS_IF_PINMUX_REG_BASE 0x10005000 +#define CONSYS_IF_PINMUX_01_OFFSET 0x000003F0 +#define CONSYS_IF_PINMUX_01_MASK 0xFFFFFF00 +#define CONSYS_IF_PINMUX_01_VALUE 0x00000011 +#define CONSYS_IF_PINMUX_02_OFFSET 0x000003E0 +#define CONSYS_IF_PINMUX_02_MASK 0x0000000F +#define CONSYS_IF_PINMUX_02_VALUE 0x11111110 +#define CONSYS_IF_DRV_PINMUX_REG_BASE 0x10420000 +#define CONSYS_IF_DRV_PINMUX_MASK 0xF8FFFFFF + +/*TOPCKGEN_BASE*/ +#define CONSYS_AP2CONN_OSC_EN_OFFSET 0x00000f00 +#define CONSYS_EMI_MAPPING_OFFSET 0x00000380 +/*AP_RGU_BASE*/ +#define CONSYS_CPU_SW_RST_OFFSET 0x00000018 +/*SPM_BASE*/ +#define CONSYS_PWRON_CONFG_EN_OFFSET 0x00000000 +#define CONSYS_TOP1_PWR_CTRL_OFFSET 0x0000032C +#define CONSYS_PWR_CONN_ACK_OFFSET 0x00000180 +#define CONSYS_PWR_CONN_ACK_S_OFFSET 0x00000184 +/*CONN_MCU_CONFIG_BASE*/ +#define CONSYS_CHIP_ID_OFFSET 0x00000008 +#define CONSYS_ROM_DESEL_OFFSET 0x00000600 +#define CONSYS_HANG_DBG_OFFSET_1 0x00000400 +#define CONSYS_HANG_DBG_OFFSET_2 0x00000404 +#define CONSYS_HANG_DBG_OFFSET_3 0x0000040C +#define CONSYS_MCU_CFG_ACR_OFFSET 0x00000140 +#define CONSYS_CPUPCR_OFFSET 0x00000160 + +/*AXI bus*/ +#define CONSYS_TOPAXI_PROT_EN_OFFSET 0x2a4 +#define CONSYS_TOPAXI_PROT_STA1_OFFSET 0x228 + +/*SPM clock gating control register */ +#define CONSYS_PWRON_CONFG_EN_VALUE (0x0b160001) +#define CONSYS_PWRON_CONFG_DIS_VALUE (0x0b160000) + +#if CONSYS_AFE_REG_SETTING +#define CONSYS_AFE_REG_BASE (0x180B6000) +#define CONSYS_AFE_RG_WBG_PLL_03_OFFSET (0x00000038) +#define CONSYS_AFE_RG_WBG_PLL_03_VALUE (0x000C1DF0) +#define CONSYS_AFE_RG_WBG_GPS_02_OFFSET (0x00000054) +#define CONSYS_AFE_RG_WBG_GPS_02_VALUE (0x110A2000) +#endif + +#define CONSYS_PROT_MASK ((0x1<<13) | (0x1<<14)) /* bit 13, 14 */ +/*CONSYS_CPU_SW_RST_REG*/ +#define CONSYS_CPU_SW_RST_BIT (0x1 << 12) +#define CONSYS_CPU_SW_RST_CTRL_KEY (0x88 << 24) + +/*CONSYS_TOP1_PWR_CTRL_REG*/ +#define CONSYS_SPM_PWR_RST_BIT (0x1 << 0) +#define CONSYS_SPM_PWR_ISO_S_BIT (0x1 << 1) +#define CONSYS_SPM_PWR_ON_BIT (0x1 << 2) +#define CONSYS_SPM_PWR_ON_S_BIT (0x1 << 3) +#define CONSYS_CLK_CTRL_BIT (0x1 << 4) +#define CONSYS_SRAM_CONN_PD_BIT (0x1 << 8) + +/*CONSYS_PWR_CONN_ACK_REG*/ +#define CONSYS_PWR_ON_ACK_BIT (0x1 << 1) + +/*CONSYS_PWR_CONN_ACK_S_REG*/ +#define CONSYS_PWR_ON_ACK_S_BIT (0x1 << 1) + +/*CONSYS_PWR_CONN_TOP2_ACK_REG*/ +#define CONSYS_TOP2_PWR_ON_ACK_BIT (0x1 << 30) + +/*CONSYS_PWR_CONN_TOP2_ACK_S_REG*/ +#define CONSYS_TOP2_PWR_ON_ACK_S_BIT (0x1 << 30) + +/*CONSYS_WD_SYS_RST_REG*/ +#define CONSYS_WD_SYS_RST_CTRL_KEY (0x88 << 24) +#define CONSYS_WD_SYS_RST_BIT (0x1 << 9) + +/*CONSYS_MCU_CFG_ACR_REG*/ +#define CONSYS_MCU_CFG_ACR_MBIST_BIT (0x1 << 0 | 0x1 << 1) + +/*control app2cnn_osc_en*/ +#define CONSYS_AP2CONN_OSC_EN_BIT (0x1 << 10) +#define CONSYS_AP2CONN_WAKEUP_BIT (0x1 << 9) +#define CONSYS_ROM_DESEL_MASK ((0x17 << 16) | 0x2a4) + +/* EMI part mapping & ctrl*/ +#define CONSYS_EMI_COREDUMP_OFFSET (0x80000) +#define CONSYS_EMI_AP_PHY_BASE (0x80080000) +#define CONSYS_EMI_FW_PHY_BASE (0xf0080000) +#define CONSYS_EMI_PAGED_TRACE_OFFSET (0x400) +#define CONSYS_EMI_PAGED_DUMP_OFFSET (0x8400) +#define CONSYS_EMI_FULL_DUMP_OFFSET (0x10400) + +/*CONSYS_MCU_CFG_DBG_LP_INFO*/ +#define MCU_TOP_MISC_ON_BASE_ADDR (0x180c1000) +#define CONN_CFG_ON_CONN_ON_MON_FLAG_RECORD_ADDR (0x134) +#define CONN_CFG_ON_CONN_ON_MON_FLAG_RECORD_MAPPING_AP_ADDR (0x180c1134) + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +#ifdef CONSYS_BT_WIFI_SHARE_V33 +struct bt_wifi_v33_status { + UINT32 counter; + UINT32 flags; + spinlock_t lock; +}; + +extern struct bt_wifi_v33_status gBtWifiV33; +#endif + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************* +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _MTK_MT6771_H_ */ diff --git a/drivers/misc/mediatek/connectivity/common/common_main/platform/include/mt6779.h b/drivers/misc/mediatek/connectivity/common/common_main/platform/include/mt6779.h new file mode 100644 index 0000000000000000000000000000000000000000..0df7e62a202056644a682b89f69d6acc07fb5d37 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/platform/include/mt6779.h @@ -0,0 +1,305 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +/*! \file + * \brief Declaration of library functions + * + * Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#ifndef _MTK_MT6779_H_ +#define _MTK_MT6779_H_ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +#define CONSYS_BT_WIFI_SHARE_V33 0 +#define CONSYS_PMIC_CTRL_ENABLE 1 +#define CONSYS_PWR_ON_OFF_API_AVAILABLE 1 +#define CONSYS_AFE_REG_SETTING 0 + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) +#define COMMON_KERNEL_EMI_MPU_SUPPORT 1 +#define COMMON_KERNEL_PMIC_SUPPORT 1 +#else +#define COMMON_KERNEL_EMI_MPU_SUPPORT 0 +#define COMMON_KERNEL_PMIC_SUPPORT 0 +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) +#define COMMON_KERNEL_CLK_SUPPORT 1 +#else +#define COMMON_KERNEL_CLK_SUPPORT 0 +#endif + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/*tag start:new platform need to make sure these define */ +#define PLATFORM_SOC_CHIP 0x6779 +/*tag end*/ + +/*device tree mode*/ +/* A-Die interface pinmux base */ +#define CONSYS_IF_PINMUX_REG_BASE 0x10005000 +#define CONSYS_IF_PINMUX_01_OFFSET 0x00000430 +#define CONSYS_IF_PINMUX_01_MASK 0x0000FFFF +#define CONSYS_IF_PINMUX_01_VALUE 0x11110000 +#define CONSYS_IF_PINMUX_02_OFFSET 0x00000440 +#define CONSYS_IF_PINMUX_02_MASK 0xF0000000 +#define CONSYS_IF_PINMUX_02_VALUE 0x01111111 + +/* A-Die interface pinmux driving base */ +#define CONSYS_IF_PINMUX_DRIVING_BASE 0x11EA0000 +#define CONSYS_IF_PINMUX_DRIVING_OFFSET 0x0 +#define CONSYS_IF_PINMUX_DRIVING_MASK 0xC00001FF +#define CONSYS_IF_PINMUX_DRIVING_VALUE 0x0 + +/* CONN_WF_CTRL2 */ +#define CONSYS_WF_CTRL2_01_OFFSET 0x00000050 +#define CONSYS_WF_CTRL2_01_MASK 0xFFFFFFEF +#define CONSYS_WF_CTRL2_01_VALUE 0x00000010 +#define CONSYS_WF_CTRL2_02_OFFSET 0x00000150 +#define CONSYS_WF_CTRL2_02_MASK 0xFFFFFFEF +#define CONSYS_WF_CTRL2_02_VALUE 0x00000010 +#define CONSYS_WF_CTRL2_03_OFFSET 0x00000440 +#define CONSYS_WF_CTRL2_03_MASK 0xFFF8FFFF +#define CONSYS_WF_CTRL2_GPIO_MODE 0x00000000 +#define CONSYS_WF_CTRL2_CONN_MODE 0x00010000 + +/*TOPCKGEN_BASE*/ +#define CONSYS_AP2CONN_OSC_EN_OFFSET 0x00000f00 +#define CONSYS_EMI_MAPPING_OFFSET 0x00000380 +#define CONSYS_EMI_PERI_MAPPING_OFFSET 0x00000388 +#define CONSYS_EMI_AP_MD_OFFSET 0x0000039C +/*AP_RGU_BASE*/ +#define CONSYS_CPU_SW_RST_OFFSET 0x00000018 +/*SPM_BASE*/ +#define CONSYS_PWRON_CONFG_EN_OFFSET 0x00000000 +#define CONSYS_TOP1_PWR_CTRL_OFFSET 0x00000320 +#define CONSYS_PWR_CONN_ACK_OFFSET 0x00000160 +#define CONSYS_PWR_CONN_ACK_S_OFFSET 0x00000164 +#define CONSYS_SPM_APSRC_OFFSET 0x000006f8 +#define CONSYS_SPM_APSRC_VALUE 0x00000005 +#define CONSYS_SPM_DDR_EN_OFFSET 0x000006fc +#define CONSYS_SPM_DDR_EN_VALUE 0x00050505 +/*CONN_MCU_CONFIG_BASE*/ +#define CONSYS_IP_VER_OFFSET 0x00000010 +#define CONSYS_CONF_ID_OFFSET 0x0000001c +#define CONSYS_HW_ID_OFFSET 0x00000000 +#define CONSYS_FW_ID_OFFSET 0x00000004 +#define CONSYS_MCU_CFG_ACR_OFFSET 0x00000140 +#define CONSYS_CPUPCR_OFFSET 0x00000104 +#define EMI_CONTROL_DBG_PROBE 0x00000144 +#define CONSYS_SW_IRQ_OFFSET 0x00000148 +#define CONN_MCU_EMI_CONTROL 0x00000150 + +#define CONSYS_IP_VER_ID 0x10050000 + +#define CONSYS_HIF_TOP_MISC 0x00002104 +#define CONSYS_HIF_DBG_IDX 0x0000212C +#define CONSYS_HIF_DBG_PROBE 0x00002130 +#define CONSYS_HIF_BUSY_STATUS 0x00002138 +#define CONSYS_HIF_PDMA_BUSY_STATUS 0x00002168 +#define CONSYS_HIF_PDMA_AXI_RREADY 0x18004154 +#define CONSYS_HIF_PDMA_AXI_RREADY_MASK (0x1 << 1) /* bit 1 */ +#define CONSYS_CLOCK_CONTROL 0x00000100 +#define CONSYS_BUS_CONTROL 0x00000110 +#define CONSYS_DEBUG_SELECT 0x00000400 +#define CONSYS_DEBUG_STATUS 0x0000040c +#define CONSYS_EMI_CTRL_VALUE (1 << 21) + +/*CONN_HIF_ON_BASE*/ +#define CONN_HIF_ON_BASE_ADDR (0x18007000) +#define CONSYS_CLOCK_CHECK_VALUE 0x30000 +#define CONSYS_HCLK_CHECK_BIT (0x1 << 16) +#define CONSYS_OSCCLK_CHECK_BIT (0x1 << 17) +#define CONSYS_SLEEP_CHECK_BIT (0x1 << 18) + +/*AXI bus*/ +#define CONSYS_AHB_RX_PROT_EN_OFFSET 0x2AC +#define CONSYS_AHB_RX_PROT_STA_OFFSET 0x258 +#define CONSYS_AXI_RX_PROT_EN_OFFSET 0x2A4 +#define CONSYS_AXI_RX_PROT_STA_OFFSET 0x228 +#define CONSYS_AHB_RX_PROT_MASK (0x1<<10) /* bit 10 */ +#define CONSYS_AXI_RX_PROT_MASK (0x1<<14) /* bit 14 */ +#define CONSYS_AXI_TX_PROT_MASK (0x1<<18) /* bit 18 */ +#define CONSYS_AHB_TX_PROT_MASK (0x1<<13) /* bit 13 */ +#define CONSYS_AHB_TIMEOUT_EN_ADDRESS 0x18002440 +#define CONSYS_AHB_TIMEOUT_EN_VALUE 0x80000101 + +/*WPLL SETTING*/ +#define CONSYS_WPLL_SETTING_ADDRESS 0x180b3034 +#define CONSYS_WPLL_SETTING_MASK 0xFFE7FFFF /* bit 19, bit 20 */ +#define CONSYS_WPLL_SETTING_VALUE 0x00080000 /* bit 19, bit 20 */ + +/* toppose_restore_done rollback CR */ +#define CONSYS_TOPPOSE_RESTORE_ADDRESS 0x180c1130 +#define CONSYS_TOPPOSE_RESTORE_MASK 0xFBFFFFFF /* bit 26 */ +#define CONSYS_TOPPOSE_RESTORE_VALUE (0x1 << 26) + +/*SPM clock gating control register */ +#define CONSYS_PWRON_CONFG_EN_VALUE (0x0b160001) +#define CONSYS_PWRON_CONFG_DIS_VALUE (0x0b160000) + +#if CONSYS_AFE_REG_SETTING +#define CONSYS_AFE_REG_BASE (0x180B6000) +#define CONSYS_AFE_RG_WBG_PLL_03_OFFSET (0x00000038) +#define CONSYS_AFE_RG_WBG_PLL_03_VALUE (0x000C1DF0) +#define CONSYS_AFE_RG_WBG_GPS_02_OFFSET (0x00000054) +#define CONSYS_AFE_RG_WBG_GPS_02_VALUE (0x110A2000) +#endif + +#define CONSYS_COCLOCK_STABLE_TIME_BASE (0x180C1200) +#define CONSYS_COCLOCK_ACK_ENABLE_OFFSET (0x4) +#define CONSYS_COCLOCK_ACK_ENABLE_BIT (1 << 0) +#define CONSYS_COCLOCK_ACK_ENABLE_MAST (0xffff00ff) +#define CONSYS_COCLOCK_ACK_ENABLE_VALUE (0x600) +#define CONSYS_COCLOCK_STABLE_TIME (0x708) +#define CONSYS_COCLOCK_STABLE_TIME_MASK (0xffff0000) + +#define CONSYS_IDENTIFY_ADIE_CR_ADDRESS (0x180C1130) +#define CONSYS_IDENTIFY_ADIE_ENABLE_BIT (1 << 8) + +/*CONSYS_CPU_SW_RST_REG*/ +#define CONSYS_CPU_SW_RST_BIT (0x1 << 12) +#define CONSYS_CPU_SW_RST_CTRL_KEY (0x88 << 24) +#define CONSYS_SW_RST_BIT (0x1 << 9) + +/*CONSYS_TOP1_PWR_CTRL_REG*/ +#define CONSYS_SPM_PWR_RST_BIT (0x1 << 0) +#define CONSYS_SPM_PWR_ISO_S_BIT (0x1 << 1) +#define CONSYS_SPM_PWR_ON_BIT (0x1 << 2) +#define CONSYS_SPM_PWR_ON_S_BIT (0x1 << 3) +#define CONSYS_CLK_CTRL_BIT (0x1 << 4) +#define CONSYS_SRAM_CONN_PD_BIT (0x1 << 8) + +/*CONSYS_PWR_CONN_ACK_REG*/ +#define CONSYS_PWR_ON_ACK_BIT (0x1 << 1) + +/*CONSYS_PWR_CONN_ACK_S_REG*/ +#define CONSYS_PWR_ON_ACK_S_BIT (0x1 << 1) + +/*CONSYS_PWR_CONN_TOP2_ACK_REG*/ +#define CONSYS_TOP2_PWR_ON_ACK_BIT (0x1 << 30) + +/*CONSYS_PWR_CONN_TOP2_ACK_S_REG*/ +#define CONSYS_TOP2_PWR_ON_ACK_S_BIT (0x1 << 30) + +/*CONSYS_WD_SYS_RST_REG*/ +#define CONSYS_WD_SYS_RST_CTRL_KEY (0x88 << 24) +#define CONSYS_WD_SYS_RST_BIT (0x1 << 9) + +/*CONSYS_MCU_CFG_ACR_REG*/ +#define CONSYS_MCU_CFG_ACR_MBIST_BIT (0x1 << 0 | 0x1 << 1) + +/*control app2cnn_osc_en*/ +#define CONSYS_AP2CONN_OSC_EN_BIT (0x1 << 10) +#define CONSYS_AP2CONN_WAKEUP_BIT (0x1 << 9) + +/* EMI part mapping & ctrl*/ +#define CONSYS_EMI_COREDUMP_OFFSET (0x68000) +#define CONSYS_EMI_COREDUMP_MEM_SIZE (0xa0000) +#define CONSYS_EMI_AP_PHY_OFFSET (0x00000) +#define CONSYS_EMI_AP_PHY_BASE (0x80068000) +#define CONSYS_EMI_FW_PHY_BASE (0xf0068000) +#define CONSYS_EMI_PAGED_TRACE_OFFSET (0x400) +#define CONSYS_EMI_PAGED_DUMP_OFFSET (0x8400) +#define CONSYS_EMI_FULL_DUMP_OFFSET (0x10400) +#define CONSYS_EMI_MET_DATA_OFFSET (0x0) + +#define CONSYS_EMI_RAM_BT_BUILDTIME_OFFSET (0x68300) +#define CONSYS_EMI_RAM_WIFI_BUILDTIME_OFFSET (0x68310) +#define CONSYS_EMI_RAM_MCU_BUILDTIME_OFFSET (0x68320) +#define CONSYS_EMI_PATCH_MCU_BUILDTIME_OFFSET (0x68330) + +/* AP_PCCIF4_BASE Register */ +#define INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG (0x438) +#define INFRASYS_COMMON_AP2MD_PCCIF4_AP_PCCIF_ACK_OFFSET (0x14) +#define INFRASYS_COMMON_AP2MD_CON_PWR_ON_CON_SW_READY_MASK (0x3 << 0) + +/* MCU Sleep handshake */ +#define MCU_GOTO_SLEEP 0x5aa5 +#define MCU_SLEEP_DONE 0x7788 + +/*CONSYS_MCU_CFG_DBG_LP_INFO*/ +#define CONN_CFG_ON_CONN_ON_HOST_MAILBOX_MCU_ADDR (conn_reg.mcu_cfg_on_base + 0x104) +#define CONN_CFG_ON_CONN_ON_MON_CTL_ADDR (conn_reg.mcu_top_misc_on_base + 0x320) +#define CONN_CFG_ON_CONN_ON_MON_SEL0_ADDR (conn_reg.mcu_top_misc_on_base + 0x328) +#define CONN_CFG_ON_CONN_ON_MON_SEL1_ADDR (conn_reg.mcu_top_misc_on_base + 0x32C) +#define CONN_CFG_ON_CONN_ON_MON_SEL2_ADDR (conn_reg.mcu_top_misc_on_base + 0x330) +#define CONN_CFG_ON_CONN_ON_MON_SEL3_ADDR (conn_reg.mcu_top_misc_on_base + 0x334) +#define CONN_CFG_ON_CONN_ON_DBGSEL_ADDR (conn_reg.mcu_top_misc_on_base + 0x310) +#define CONN_CFG_ON_CONN_ON_MON_FLAG_RECORD_ADDR (conn_reg.mcu_top_misc_on_base + 0x340) +#define CONN_CFG_ON_CONN_ON_MON_FLAG_RECORD_MAPPING_AP_ADDR (0x180c1340) + +#define CONN_ON_ADIE_CTL_OFFSET (0x500) + +/**********************************************************************/ +/* Base: conn_rf_spi_base (0x180c_6000) */ +/**********************************************************************/ +#define CONN_RF_SPI_BASE 0x180c6000 +#define SPI_TOP_ADDR 0x50 +#define SPI_TOP_WDAT 0x54 +#define SPI_TOP_RDAT 0x58 + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +#ifdef CONSYS_BT_WIFI_SHARE_V33 +struct bt_wifi_v33_status { + UINT32 counter; + UINT32 flags; + spinlock_t lock; +}; + +extern struct bt_wifi_v33_status gBtWifiV33; +#endif + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************* +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _MTK_MT6779_H_ */ diff --git a/drivers/misc/mediatek/connectivity/common/common_main/platform/include/mt6785.h b/drivers/misc/mediatek/connectivity/common/common_main/platform/include/mt6785.h new file mode 100644 index 0000000000000000000000000000000000000000..8b82e06521037d5bd8814a231875a889dfb99e62 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/platform/include/mt6785.h @@ -0,0 +1,267 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +/*! \file + * \brief Declaration of library functions + * + * Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#ifndef _MTK_MT6785_H_ +#define _MTK_MT6785_H_ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +#define CONSYS_BT_WIFI_SHARE_V33 0 +#define CONSYS_PMIC_CTRL_ENABLE 1 +#define CONSYS_AHB_CLK_MAGEMENT 1 +#define CONSYS_USE_PLATFORM_WRITE 1 +#define CONSYS_PWR_ON_OFF_API_AVAILABLE 1 +#define CONSYS_AFE_REG_SETTING 1 + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/*tag start:new platform need to make sure these define */ +#define PLATFORM_SOC_CHIP 0x6785 +/*tag end*/ + +/*device tree mode*/ +/* A-Die interface pinmux base */ +#define CONSYS_IF_PINMUX_REG_BASE 0x10005000 +#define CONSYS_IF_PINMUX_01_OFFSET 0x00000430 +#define CONSYS_IF_PINMUX_01_MASK 0x0000ffff +#define CONSYS_IF_PINMUX_01_VALUE 0x11110000 +#define CONSYS_IF_PINMUX_02_OFFSET 0x00000440 +#define CONSYS_IF_PINMUX_02_MASK 0xfff00000 +#define CONSYS_IF_PINMUX_02_VALUE 0x11111 + +/* A-Die interface pinmux driving base */ +#define CONSYS_IF_PINMUX_DRIVING_BASE 0x11EA0000 +#define CONSYS_IF_PINMUX_DRIVING_OFFSET 0x0 +#define CONSYS_IF_PINMUX_DRIVING_MASK 0xff000007 +#define CONSYS_IF_PINMUX_DRIVING_VALUE 0x0 + +/*TOPCKGEN_BASE*/ +#define CONSYS_AP2CONN_OSC_EN_OFFSET 0x00000f00 +#define CONSYS_EMI_MAPPING_OFFSET 0x00000380 +#define CONSYS_EMI_PERI_MAPPING_OFFSET 0x00000388 +#define CONSYS_EMI_AP_MD_OFFSET 0x0000039C +/*AP_RGU_BASE*/ +#define CONSYS_CPU_SW_RST_OFFSET 0x00000018 +/*SPM_BASE*/ +#define CONSYS_PWRON_CONFG_EN_OFFSET 0x00000000 +#define CONSYS_TOP1_PWR_CTRL_OFFSET 0x00000320 +#define CONSYS_PWR_CONN_ACK_OFFSET 0x00000160 +#define CONSYS_PWR_CONN_ACK_S_OFFSET 0x00000164 +#define CONSYS_SPM_APSRC_OFFSET 0x000006f8 +#define CONSYS_SPM_APSRC_VALUE 0x00000005 +#define CONSYS_SPM_DDR_EN_OFFSET 0x000006fc +#define CONSYS_SPM_DDR_EN_VALUE 0x00050505 +/*CONN_MCU_CONFIG_BASE*/ +#define CONSYS_IP_VER_OFFSET 0x00000010 +#define CONSYS_CONF_ID_OFFSET 0x0000001c +#define CONSYS_HW_ID_OFFSET 0x00000000 +#define CONSYS_FW_ID_OFFSET 0x00000004 +#define CONSYS_IP_VER_ID 0x10020600 +#define CONSYS_MCU_CFG_ACR_OFFSET 0x00000140 +#define CONSYS_CPUPCR_OFFSET 0x00000104 +#define EMI_CONTROL_DBG_PROBE 0x00000144 +#define CONN_MCU_EMI_CONTROL 0x00000150 +#define CONSYS_MCU_ROM_DELSEL_OFFSET 0x00000114 +#define CONSYS_MCU_ROM_DELSEL_VALUE 0x00000017 +#define CONSYS_EMI_CTRL_VALUE (1 << 21) +/*CONN_HIF_TOP*/ +#define CONSYS_HIF_PDMA_AXI_RREADY 0x00000154 + +#define CONSYS_HIF_TOP_MISC 0x00000104 +#define CONSYS_HIF_DBG_IDX 0x0000012C +#define CONSYS_HIF_DBG_PROBE 0x00000130 +#define CONSYS_HIF_BUSY_STATUS 0x00000138 +#define CONSYS_HIF_PDMA_AXI_RREADY 0x00000154 +#define CONSYS_HIF_PDMA_BUSY_STATUS 0x00000168 + +/*CONN_HIF_ON_BASE*/ +#define CONN_HIF_ON_BASE_ADDR (0x18007000) +#define CONSYS_CLOCK_CONTROL 0x00000100 +#define CONSYS_BUS_CONTROL 0x00000110 +#define CONSYS_DEBUG_SELECT 0x00000400 +#define CONSYS_DEBUG_STATUS 0x0000040c + +#define CONSYS_BUSY_OFFSET 0x110 +#define CONSYS_BUSY_BIT (0x1 << 27) +#define CONSYS_CLOCK_CHECK_VALUE 0x30000 +#define CONSYS_HCLK_CHECK_BIT (0x1 << 16) +#define CONSYS_OSCCLK_CHECK_BIT (0x1 << 17) +#define CONSYS_SLEEP_CHECK_BIT (0x1 << 18) + +/*AXI bus*/ +#define CONSYS_AHB_RX_PROT_EN_OFFSET 0x2AC +#define CONSYS_AHB_RX_PROT_STA_OFFSET 0x258 +#define CONSYS_AXI_RX_PROT_EN_OFFSET 0x2A4 +#define CONSYS_AXI_RX_PROT_STA_OFFSET 0x228 +#define CONSYS_AHB_RX_PROT_MASK (0x1<<10) /* bit 10 */ +#define CONSYS_AXI_RX_PROT_MASK (0x1<<14) /* bit 14 */ +#define CONSYS_AXI_TX_PROT_MASK (0x1<<18) /* bit 18 */ +#define CONSYS_AHB_TX_PROT_MASK (0x1<<13) /* bit 13 */ +#define CONSYS_AHB_TIMEOUT_EN_ADDRESS 0x18002440 +#define CONSYS_AHB_TIMEOUT_EN_VALUE 0x80000101 +#define CONSYS_PDMA_AXI_RREADY_MASK (0x1 << 1) /* bit 1 */ + +/* CONN2EMI HW slpprot control enable */ +#define CONSYS_SLPPROT_CONTROL_OFFSET 0x160 +#define CONSYS_SLPPROT_CONTROL_MASK 0xFFFFFFEF /* bit 4 */ +#define CONSYS_SLPPROT_CONTROL_VALUE (0x1 << 4) + +/* toppose_restore_done rollback CR */ +#define CONSYS_TOPPOSE_RESTORE_ADDRESS 0x180c1600 +#define CONSYS_TOPPOSE_RESTORE_MASK 0xFF7FFFFF /* bit 23 */ +#define CONSYS_TOPPOSE_RESTORE_VALUE (0x1 << 23) + +/* WPLL SETTING */ +#define CONSYS_WPLL_SETTING_ADDRESS 0x180b3034 +#define CONSYS_WPLL_SETTING_MASK 0xFFE7FFFF /* bit 19, bit 20 */ +#define CONSYS_WPLL_SETTING_VALUE 0x00080000 /* bit 19, bit 20 */ + +/*SPM clock gating control register */ +#define CONSYS_PWRON_CONFG_EN_VALUE (0x0b160001) +#define CONSYS_PWRON_CONFG_DIS_VALUE (0x0b160000) + +#if CONSYS_AFE_REG_SETTING +#define CONSYS_AFE_REG_BASE (0x180B3000) +#define CONSYS_AFE_RG_WBG_PLL_03_OFFSET (0x00000034) +#endif + +#define CONSYS_COCLOCK_STABLE_TIME_BASE (0x180C1200) +#define CONSYS_COCLOCK_ACK_ENABLE_OFFSET (0x4) +#define CONSYS_COCLOCK_ACK_ENABLE_BIT (1 << 0) +#define CONSYS_COCLOCK_STABLE_TIME (0x708) +#define CONSYS_COCLOCK_STABLE_TIME_MASK (0xffff0000) + +/*CONSYS_CPU_SW_RST_REG*/ +#define CONSYS_CPU_SW_RST_BIT (0x1 << 12) +#define CONSYS_CPU_SW_RST_CTRL_KEY (0x88 << 24) +#define CONSYS_SW_RST_BIT (0x1 << 9) + +/*CONSYS_TOP1_PWR_CTRL_REG*/ +#define CONSYS_SPM_PWR_RST_BIT (0x1 << 0) +#define CONSYS_SPM_PWR_ISO_S_BIT (0x1 << 1) +#define CONSYS_SPM_PWR_ON_BIT (0x1 << 2) +#define CONSYS_SPM_PWR_ON_S_BIT (0x1 << 3) +#define CONSYS_CLK_CTRL_BIT (0x1 << 4) +#define CONSYS_SRAM_CONN_PD_BIT (0x1 << 8) + +/*CONSYS_PWR_CONN_ACK_REG*/ +#define CONSYS_PWR_ON_ACK_BIT (0x1 << 1) + +/*CONSYS_PWR_CONN_ACK_S_REG*/ +#define CONSYS_PWR_ON_ACK_S_BIT (0x1 << 1) + +/*CONSYS_PWR_CONN_TOP2_ACK_REG*/ +#define CONSYS_TOP2_PWR_ON_ACK_BIT (0x1 << 30) + +/*CONSYS_PWR_CONN_TOP2_ACK_S_REG*/ +#define CONSYS_TOP2_PWR_ON_ACK_S_BIT (0x1 << 30) + +/*CONSYS_WD_SYS_RST_REG*/ +#define CONSYS_WD_SYS_RST_CTRL_KEY (0x88 << 24) +#define CONSYS_WD_SYS_RST_BIT (0x1 << 9) + +/*CONSYS_MCU_CFG_ACR_REG*/ +#define CONSYS_MCU_CFG_ACR_MBIST_BIT (0x1 << 0 | 0x1 << 1) + +/*control app2cnn_osc_en*/ +#define CONSYS_AP2CONN_OSC_EN_BIT (0x1 << 10) +#define CONSYS_AP2CONN_WAKEUP_BIT (0x1 << 9) + +/* EMI part mapping & ctrl*/ +#define CONSYS_EMI_COREDUMP_OFFSET (0x68000) +#define CONSYS_EMI_AP_PHY_BASE (0x80068000) +#define CONSYS_EMI_FW_PHY_BASE (0xf0068000) +#define CONSYS_EMI_PAGED_TRACE_OFFSET (0x400) +#define CONSYS_EMI_PAGED_DUMP_OFFSET (0x8400) +#define CONSYS_EMI_FULL_DUMP_OFFSET (0x10400) +#define CONSYS_EMI_MET_DATA_OFFSET (0x2e500) + +#define CONSYS_EMI_RAM_BT_BUILDTIME_OFFSET (0x68300) +#define CONSYS_EMI_RAM_WIFI_BUILDTIME_OFFSET (0x68310) +#define CONSYS_EMI_RAM_MCU_BUILDTIME_OFFSET (0x68320) +#define CONSYS_EMI_PATCH_MCU_BUILDTIME_OFFSET (0x68330) + +/* AP_PCCIF4_BASE Register */ +#define INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG (0x438) +#define INFRASYS_COMMON_AP2MD_PCCIF4_AP_PCCIF_ACK_OFFSET (0x14) +#define INFRASYS_COMMON_AP2MD_CON_PWR_ON_CON_SW_READY_MASK (0x3 << 0) + +/*CONSYS_MCU_CFG_DBG_LP_INFO*/ +#define CONN_CFG_ON_CONN_ON_HOST_MAILBOX_MCU_ADDR (conn_reg.mcu_cfg_on_base + 0x104) +#define CONN_CFG_ON_CONN_ON_MON_CTL_ADDR (conn_reg.mcu_top_misc_on_base + 0x320) +#define CONN_CFG_ON_CONN_ON_MON_SEL0_ADDR (conn_reg.mcu_top_misc_on_base + 0x328) +#define CONN_CFG_ON_CONN_ON_MON_SEL1_ADDR (conn_reg.mcu_top_misc_on_base + 0x32C) +#define CONN_CFG_ON_CONN_ON_MON_SEL2_ADDR (conn_reg.mcu_top_misc_on_base + 0x330) +#define CONN_CFG_ON_CONN_ON_MON_SEL3_ADDR (conn_reg.mcu_top_misc_on_base + 0x334) +#define CONN_CFG_ON_CONN_ON_DBGSEL_ADDR (conn_reg.mcu_top_misc_on_base + 0x310) +#define CONN_CFG_ON_CONN_ON_MON_FLAG_RECORD_ADDR (conn_reg.mcu_top_misc_on_base + 0x340) +#define CONN_CFG_ON_CONN_ON_MON_FLAG_RECORD_MAPPING_AP_ADDR (0x180c1340) + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +#ifdef CONSYS_BT_WIFI_SHARE_V33 +struct bt_wifi_v33_status { + UINT32 counter; + UINT32 flags; + spinlock_t lock; +}; + +extern struct bt_wifi_v33_status gBtWifiV33; +#endif + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************* +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _MTK_MT6785_H_ */ diff --git a/drivers/misc/mediatek/connectivity/common/common_main/platform/include/mt6853.h b/drivers/misc/mediatek/connectivity/common/common_main/platform/include/mt6853.h new file mode 100644 index 0000000000000000000000000000000000000000..73a605f24e5a3119e1808ceaa77db91e953a62a6 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/platform/include/mt6853.h @@ -0,0 +1,326 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef _MTK_MT6853_H_ +#define _MTK_MT6853_H_ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +#define CONSYS_BT_WIFI_SHARE_V33 0 +#define CONSYS_PMIC_CTRL_ENABLE 1 +#define CONSYS_PWR_ON_OFF_API_AVAILABLE 1 +#define CONSYS_RC_MODE_ENABLE 1 + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/*tag start:new platform need to make sure these define */ +#define PLATFORM_SOC_CHIP 0x6853 +/*tag end*/ + +/*device tree mode*/ +/* A-Die interface pinmux base */ +#define CONSYS_IF_PINMUX_REG_BASE 0x10005000 +#define CONSYS_IF_PINMUX_01_OFFSET 0x00000480 +#define CONSYS_IF_PINMUX_01_MASK 0x00000000 +#define CONSYS_IF_PINMUX_01_VALUE 0x11111111 +#define CONSYS_IF_PINMUX_02_OFFSET 0x00000490 +#define CONSYS_IF_PINMUX_02_MASK 0xFFFFF000 +#define CONSYS_IF_PINMUX_02_VALUE 0x00000111 +#define CONSYS_CLOCK_TCXO_MODE_OFFSET 0x410 +#define CONSYS_CLOCK_TCXO_MODE_MASK 0xFFFFFF8F +#define CONSYS_CLOCK_TCXO_MODE_VALUE 0x50 + +/* A-Die interface pinmux driving base */ +#define CONSYS_IF_PINMUX_DRIVING_BASE 0x11EA0000 +#define CONSYS_IF_PINMUX_DRIVING_OFFSET_1 0x0 +#define CONSYS_IF_PINMUX_DRIVING_MASK_1 0xC003FFFF +#define CONSYS_IF_PINMUX_DRIVING_VALUE_1 0x8240000 +#define CONSYS_IF_PINMUX_DRIVING_OFFSET_2 0x10 +#define CONSYS_IF_PINMUX_DRIVING_MASK_2 0xFFE00000 +#define CONSYS_IF_PINMUX_DRIVING_VALUE_2 0x1 + +/* CONN_WF_CTRL2 */ +#define CONSYS_WF_CTRL2_01_OFFSET 0x60 +#define CONSYS_WF_CTRL2_01_MASK 0xfffffeff +#define CONSYS_WF_CTRL2_01_VALUE 0x100 +#define CONSYS_WF_CTRL2_02_OFFSET 0x160 +#define CONSYS_WF_CTRL2_02_MASK 0xfffffeff +#define CONSYS_WF_CTRL2_02_VALUE 0x100 +#define CONSYS_WF_CTRL2_03_OFFSET 0x490 +#define CONSYS_WF_CTRL2_03_MASK 0xfffffff8 +#define CONSYS_WF_CTRL2_GPIO_MODE 0x0 +#define CONSYS_WF_CTRL2_CONN_MODE 0x1 + +/*TOPCKGEN_BASE*/ +#define CONSYS_AP2CONN_OSC_EN_OFFSET 0x00000f00 +#define CONSYS_EMI_MAPPING_OFFSET 0x00000380 +#define CONSYS_EMI_PERI_MAPPING_OFFSET 0x00000388 +#define CONSYS_EMI_AP_MD_OFFSET 0x0000039C +/*AP_RGU_BASE*/ +#define CONSYS_CPU_SW_RST_OFFSET 0x00000018 +/*SPM_BASE*/ +#define CONSYS_PWRON_CONFG_EN_OFFSET 0x00000000 +#define CONSYS_TOP1_PWR_CTRL_OFFSET 0x00000304 +#define CONSYS_PWR_CONN_ACK_OFFSET 0x0000016C +#define CONSYS_PWR_CONN_ACK_S_OFFSET 0x00000170 +#define CONSYS_SPM_CON_TOP_OFF_CHECK_OFFSET 0x00000178 +#define CONSYS_SPM_CON_TOP_OFF_CHECK_BIT (0x1 << 1) +/*CONN_MCU_CONFIG_BASE*/ +#define CONSYS_IP_VER_OFFSET 0x00000010 +#define CONSYS_CONF_ID_OFFSET 0x0000001c +#define CONSYS_HW_ID_OFFSET 0x00000000 +#define CONSYS_FW_ID_OFFSET 0x00000004 +#define EMI_CONTROL_DBG_PROBE 0x00000144 +#define CONN_MCU_EMI_CONTROL 0x00000150 + +#define CONSYS_IP_VER_ID 0x10090000 + +/*CONN_HIF_ON_BASE*/ +#define CONSYS_CLOCK_CHECK_VALUE 0x30000 +#define CONSYS_HCLK_CHECK_BIT (0x1 << 16) +#define CONSYS_OSCCLK_CHECK_BIT (0x1 << 17) +#define CONSYS_SLEEP_CHECK_BIT (0x1 << 18) + +/*AXI bus*/ +#define CONSYS_AHB_RX_PROT_EN_OFFSET 0x2AC +#define CONSYS_AHB_RX_PROT_STA_OFFSET 0x258 +#define CONSYS_AXI_RX_PROT_EN_OFFSET 0x2A4 +#define CONSYS_AXI_RX_PROT_STA_OFFSET 0x228 +#define CONSYS_AHB_RX_PROT_MASK (0x1<<10) /* bit 10 */ +#define CONSYS_AXI_RX_PROT_MASK (0x1<<14) /* bit 14 */ +#define CONSYS_AXI_TX_PROT_MASK (0x1<<18) /* bit 18 */ +#define CONSYS_AHB_TX_PROT_MASK (0x1<<13) /* bit 13 */ +#define CONSYS_AHB_TIMEOUT_EN_ADDRESS 0x18002440 +#define CONSYS_AHB_TIMEOUT_EN_VALUE 0x90000002 + +#define CONSYS_AFE_WBG_REG_BASE (0x180B3000) +#define CONSYS_AFE_WBG_REG_AFE_01_OFFSET (0x10) +#define CONSYS_AFE_WBG_REG_RCK_01_OFFSET (0x18) +#define CONSYS_AFE_WBG_REG_GL1_01_OFFSET (0x40) +#define CONSYS_AFE_WBG_REG_BT_TX_03_OFFSET (0x58) +#define CONSYS_AFE_WBG_REG_WF0_TX_03_OFFSET (0x78) +#define CONSYS_AFE_WBG_REG_WF1_TX_03_OFFSET (0x94) +#define CONSYS_AFE_WBG_REG_GL5_01_OFFSET (0x100) +#define CONSYS_AFE_WBG_REG_AFE_01_VALUE (0x00000000) +#define CONSYS_AFE_WBG_REG_RCK_01_VALUE (0x144B0160) +#define CONSYS_AFE_WBG_REG_GL1_01_VALUE (0x10990C13) +#define CONSYS_AFE_WBG_REG_BT_TX_03_VALUE (0xCD258051) +#define CONSYS_AFE_WBG_REG_WF0_TX_03_VALUE (0xC5258251) +#define CONSYS_AFE_WBG_REG_WF1_TX_03_VALUE (0xC5258251) +#define CONSYS_AFE_WBG_REG_GL5_01_VALUE (0x10990C13) + +#define CONSYS_COCLOCK_STABLE_TIME_BASE (0x180C1200) +#define CONSYS_COCLOCK_ACK_ENABLE_OFFSET (0x4) +#define CONSYS_COCLOCK_ACK_ENABLE_BIT (1 << 0) +#define CONSYS_COCLOCK_ACK_ENABLE_MAST (0xffff00ff) +#define CONSYS_COCLOCK_ACK_ENABLE_VALUE (0x600) +#define CONSYS_COCLOCK_STABLE_TIME (0x708) +#define CONSYS_COCLOCK_STABLE_TIME_MASK (0xffff0000) + +#define CONSYS_COCLOCK_RC_CTL_0_TOP_OSC_RC_EN_OFFSET (0x40) +#define CONSYS_COCLOCK_RC_CTL_0_TOP_OSC_RC_EN_BIT (0x1 << 7) +#define CONSYS_COCLOCK_RC_CTL_1_GPS_XO_OFFSET (0x44) +#define CONSYS_COCLOCK_RC_CTL_0_GPS_ACK_OFFSET (0x48) +#define CONSYS_COCLOCK_RC_CTL_1_BT_XO_OFFSET (0x4C) +#define CONSYS_COCLOCK_RC_CTL_0_BT_ACK_OFFSET (0x50) +#define CONSYS_COCLOCK_RC_CTL_1_WF_XO_OFFSET (0x54) +#define CONSYS_COCLOCK_RC_CTL_0_WF_ACK_OFFSET (0x58) +#define CONSYS_COCLOCK_RC_CTL_1_TOP_XO_OFFSET (0x5C) +#define CONSYS_COCLOCK_RC_CTL_0_TOP_ACK_OFFSET (0x60) +#define CONSYS_COCLOCK_RC_CTL_1_XO_VALUE (0x02080706) +#define CONSYS_COCLOCK_RC_CTL_1_XO_TCXO_VALUE (0x02434241) +#define CONSYS_COCLOCK_RC_CTL_0_ACK_BIT (0x1 << 16) +#define CONSYS_COCLOCK_RC_CTL_0_GPS_OSC_RC_EN_BIT (0x1 << 4 | 0x1 << 12) +#define CONSYS_COCLOCK_RC_CTL_0_BT_OSC_RC_EN_BIT (0x1 << 5 | 0x1 << 13) +#define CONSYS_COCLOCK_RC_CTL_0_WF_OSC_RC_EN_BIT (0x1 << 6 | 0x1 << 14) +#define CONSYS_COCLOCK_RC_CTL_0_TOP_OSC_RC_EN_BIT_2 (0x1 << 7 | 0x1 << 15) +#define CONSYS_COCLOCK_RC_CTL_0_OSC_LEGACY_EN_BIT (0x1 << 8) + +#define CONSYS_IDENTIFY_ADIE_CR_ADDRESS (0x180C1130) +#define CONSYS_IDENTIFY_ADIE_ENABLE_BIT (0x1 << 8) + +/*CONSYS_CPU_SW_RST_REG*/ +#define CONSYS_CPU_SW_RST_BIT (0x1 << 12) +#define CONSYS_CPU_SW_RST_CTRL_KEY (0x88 << 24) +#define CONSYS_SW_RST_BIT (0x1 << 9) + +/*CONSYS_TOP1_PWR_CTRL_REG*/ +#define CONSYS_SPM_PWR_RST_BIT (0x1 << 0) +#define CONSYS_SPM_PWR_ISO_S_BIT (0x1 << 1) +#define CONSYS_SPM_PWR_ON_BIT (0x1 << 2) +#define CONSYS_SPM_PWR_ON_S_BIT (0x1 << 3) +#define CONSYS_CLK_CTRL_BIT (0x1 << 4) +#define CONSYS_SRAM_CONN_PD_BIT (0x1 << 8) +#define CONSYS_SPM_PWR_ON_CLK_BIT (0x1 << 0) +#define CONSYS_SPM_PWR_ON_CLK_CTRL_KEY (0x0B16 << 16) +#define SRCLKEN_RC_BASE (0x1000F800) +#define SRCLKEN_RC_CENTRAL_CFG1_BIT (0x1 << 0) +#define SRCLKEN_RC_CENTRAL_CFG1 (0x4) + + +/*CONSYS_PWR_CONN_ACK_REG*/ +#define CONSYS_PWR_ON_ACK_BIT (0x1 << 1) + +/*CONSYS_PWR_CONN_ACK_S_REG*/ +#define CONSYS_PWR_ON_ACK_S_BIT (0x1 << 1) + +/*CONSYS_PWR_CONN_TOP2_ACK_REG*/ +#define CONSYS_TOP2_PWR_ON_ACK_BIT (0x1 << 30) + +/*CONSYS_PWR_CONN_TOP2_ACK_S_REG*/ +#define CONSYS_TOP2_PWR_ON_ACK_S_BIT (0x1 << 30) + +/*CONSYS_WD_SYS_RST_REG*/ +#define CONSYS_WD_SYS_RST_CTRL_KEY (0x88 << 24) +#define CONSYS_WD_SYS_RST_BIT (0x1 << 9) + +/*CONSYS_MCU_CFG_ACR_REG*/ +#define CONSYS_MCU_CFG_ACR_MBIST_BIT (0x1 << 0 | 0x1 << 1) + +/*control app2cnn_osc_en*/ +#define CONSYS_AP2CONN_OSC_EN_BIT (0x1 << 10) +#define CONSYS_AP2CONN_WAKEUP_BIT (0x1 << 9) + +/* EMI part mapping & ctrl*/ +#define CONSYS_EMI_COREDUMP_OFFSET (0x68000) +#define CONSYS_EMI_COREDUMP_MEM_SIZE (0xa0000) +#define CONSYS_EMI_AP_PHY_OFFSET (0x00000) +#define CONSYS_EMI_AP_PHY_BASE (0x80068000) +#define CONSYS_EMI_FW_PHY_BASE (0xf0068000) +#define CONSYS_EMI_PAGED_TRACE_OFFSET (0x400) +#define CONSYS_EMI_PAGED_DUMP_OFFSET (0x8400) +#define CONSYS_EMI_FULL_DUMP_OFFSET (0x10400) +#define CONSYS_EMI_MET_DATA_OFFSET (0x2e500) + +#define CONSYS_EMI_RAM_BT_BUILDTIME_OFFSET (0x68300) +#define CONSYS_EMI_RAM_WIFI_BUILDTIME_OFFSET (0x68310) +#define CONSYS_EMI_RAM_MCU_BUILDTIME_OFFSET (0x68320) +#define CONSYS_EMI_PATCH_MCU_BUILDTIME_OFFSET (0x68330) + +#define CONSYS_EMI_BT_ENTRY_ADDRESS (0xF0110000) +#define CONSYS_EMI_WIFI_ENTRY_ADDRESS (0xF01D0000) + +/* AP_PCCIF4_BASE Register */ +#define INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG (0x314) +#define INFRASYS_COMMON_AP2MD_PCCIF4_AP_PCCIF_ACK_OFFSET (0x14) +#define INFRASYS_COMMON_AP2MD_CON_PWR_ON_CON_SW_READY_MASK (0x3 << 0) + +/**********************************************************************/ +/* Base: mcu_base (0x1800_2000) */ +/**********************************************************************/ +#define CONSYS_HW_ID_OFFSET 0x00000000 +#define CONSYS_FW_ID_OFFSET 0x00000004 +#define CONSYS_CLOCK_CONTROL 0x00000100 +#define CONSYS_BUS_CONTROL 0x00000110 +#define EMI_CONTROL_DBG_PROBE 0x00000144 +#define CONN2AP_SW_IRQ_CLR_OFFSET 0x0000014c +#define CONN2AP_SW_IRQ_OFFSET 0x00000150 +#define CONN_MCU_EMI_CONTROL 0x00000150 +#define CONSYS_SW_DBG_CTL (0x16c) +#define CONSYS_DEBUG_SELECT 0x00000400 +#define CONSYS_DEBUG_STATUS 0x0000040c +#define CONSYS_EMI_BT_ENTRY_OFFSET (0x504) +#define CONSYS_EMI_WIFI_ENTRY_OFFSET (0x508) +#define CONSYS_COM_REG0 (0x600) + +/**********************************************************************/ +/* Base: conn_hif_pdma_base (0x1800_4000) */ +/**********************************************************************/ +#define CONSYS_HIF_TOP_MISC 0x00000104 +#define CONSYS_HIF_DBG_IDX 0x0000012C +#define CONSYS_HIF_DBG_PROBE 0x00000130 +#define CONSYS_HIF_BUSY_STATUS 0x00000138 +#define CONSYS_HIF_PDMA_BUSY_STATUS 0x00000168 +#define CONSYS_HIF_PDMA_AXI_RREADY 0x00000154 +#define CONSYS_HIF_PDMA_AXI_RREADY_MASK (0x1 << 1) /* bit 1 */ + +/**********************************************************************/ +/* Base: conn_hif_on_base (0x1800_7000) */ +/**********************************************************************/ +#define CONN_HIF_ON_BASE_ADDR (0x18007000) +#define CONN_HOST_CR_SLEEP_CNT_OFFSET (0x58) +#define CONN_SLEEP_INFO_CTRL_OFFSET (0x5c) +#define CONN_SLEEP_INFO_READ_CTRL_TIMER_OFFSET (0x60) +#define CONN_SLEEP_INFO_READ_CTRL_COUNT_OFFSET (0x64) +#define CONSYS_CPUPCR_OFFSET (0x00000104) +#define CONN_MCU_MAILBOX_DBG (0x0120) + +/**********************************************************************/ +/* Base: conn_top_misc_on_base (0x180c_1000) */ +/**********************************************************************/ +#define CONSYS_ACCESS_EMI_HW_MODE_OFFSET (0x168) +#define CONN_CFG_ON_DBGSEL_ADDR_OFFSET (0x310) +#define CONN_CFG_ON_MON_CTL_ADDR_OFFSET (0x320) +#define CONN_CFG_ON_MON_SEL0_ADDR_OFFSET (0x328) +#define CONN_CFG_ON_MON_SEL1_ADDR_OFFSET (0x32C) +#define CONN_CFG_ON_MON_SEL2_ADDR_OFFSET (0x330) +#define CONN_CFG_ON_MON_SEL3_ADDR_OFFSET (0x334) +#define CONN_CFG_ON_MON_FLAG_RECORD_ADDR_OFFSET (0x340) +#define CONN_ON_ADIE_CTL_OFFSET (0x500) + +/**********************************************************************/ +/* Base: conn_rf_spi_base (0x180c_6000) */ +/**********************************************************************/ +#define CONN_RF_SPI_BASE 0x180c6000 +#define SPI_TOP_ADDR 0x50 +#define SPI_TOP_WDAT 0x54 +#define SPI_TOP_RDAT 0x58 + +/**********************************************************************/ +/* Base: conn_mcu_cfg_on_base (0x180a_3000) */ +/**********************************************************************/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +#ifdef CONSYS_BT_WIFI_SHARE_V33 +struct bt_wifi_v33_status { + UINT32 counter; + UINT32 flags; + spinlock_t lock; +}; + +extern struct bt_wifi_v33_status gBtWifiV33; +#endif + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************* +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _MTK_MT6853_H_ */ diff --git a/drivers/misc/mediatek/connectivity/common/common_main/platform/include/mt6873.h b/drivers/misc/mediatek/connectivity/common/common_main/platform/include/mt6873.h new file mode 100644 index 0000000000000000000000000000000000000000..21049666b567459e66db837609e620ad8e0bd124 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/platform/include/mt6873.h @@ -0,0 +1,432 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef _MTK_MT6873_H_ +#define _MTK_MT6873_H_ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +#define CONSYS_BT_WIFI_SHARE_V33 0 +#define CONSYS_PMIC_CTRL_ENABLE 1 +#define CONSYS_PWR_ON_OFF_API_AVAILABLE 1 +#define CONSYS_AFE_REG_SETTING 0 +#define CONSYS_RC_MODE_ENABLE 1 + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) +#define COMMON_KERNEL_EMI_MPU_SUPPORT 1 +#define COMMON_KERNEL_PMIC_SUPPORT 1 +#else +#define COMMON_KERNEL_EMI_MPU_SUPPORT 0 +#define COMMON_KERNEL_PMIC_SUPPORT 0 +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) +#define COMMON_KERNEL_CLK_SUPPORT 1 +#else +#define COMMON_KERNEL_CLK_SUPPORT 0 +#endif + +#if CONSYS_PMIC_CTRL_ENABLE +#if COMMON_KERNEL_PMIC_SUPPORT +#include +#endif +#endif + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/*tag start:new platform need to make sure these define */ +#define PLATFORM_SOC_CHIP 0x6873 +/*tag end*/ + +/*device tree mode*/ +/* A-Die interface pinmux base */ +#define CONSYS_IF_PINMUX_REG_BASE 0x10005000 +#define CONSYS_IF_PINMUX_01_OFFSET 0x00000450 +#define CONSYS_IF_PINMUX_01_MASK 0x0000FFFF +#define CONSYS_IF_PINMUX_01_VALUE 0x11110000 +#define CONSYS_IF_PINMUX_02_OFFSET 0x00000460 +#define CONSYS_IF_PINMUX_02_MASK 0xF0000000 +#define CONSYS_IF_PINMUX_02_VALUE 0x01111111 +#define CONSYS_CLOCK_TCXO_MODE_OFFSET 0x400 +#define CONSYS_CLOCK_TCXO_MODE_MASK 0x8FFFFFFF +#define CONSYS_CLOCK_TCXO_MODE_VALUE 0x50000000 + +/* A-Die interface pinmux driving base */ +#define CONSYS_IF_PINMUX_DRIVING_BASE 0x11EA0000 +#define CONSYS_IF_PINMUX_DRIVING_OFFSET_1 0x0 +#define CONSYS_IF_PINMUX_DRIVING_MASK_1 0xC0000FFF +#define CONSYS_IF_PINMUX_DRIVING_VALUE_1 0x01209000 /* --00 0001 0010 0000 1001 ---- */ +#define CONSYS_IF_PINMUX_DRIVING_OFFSET_2 0x10 +#define CONSYS_IF_PINMUX_DRIVING_MASK_2 0xFFFF8000 +#define CONSYS_IF_PINMUX_DRIVING_VALUE_2 0x0 + +/* CONN_WF_CTRL2 */ +#define CONSYS_WF_CTRL2_01_OFFSET 0x00000050 +#define CONSYS_WF_CTRL2_01_MASK 0xFFEFFFFF +#define CONSYS_WF_CTRL2_01_VALUE 0x00100000 +#define CONSYS_WF_CTRL2_02_OFFSET 0x00000150 +#define CONSYS_WF_CTRL2_02_MASK 0xFFEFFFFF +#define CONSYS_WF_CTRL2_02_VALUE 0x00100000 +#define CONSYS_WF_CTRL2_03_OFFSET 0x00000460 +#define CONSYS_WF_CTRL2_03_MASK 0xFFF8FFFF +#define CONSYS_WF_CTRL2_GPIO_MODE 0x00000000 +#define CONSYS_WF_CTRL2_CONN_MODE 0x00010000 + +/*TOPCKGEN_BASE*/ +#define CONSYS_AP2CONN_OSC_EN_OFFSET 0x00000f00 +#define CONSYS_EMI_MAPPING_OFFSET 0x00000380 +#define CONSYS_EMI_PERI_MAPPING_OFFSET 0x00000388 +#define CONSYS_EMI_AP_MD_OFFSET 0x0000039C +/*AP_RGU_BASE*/ +#define CONSYS_CPU_SW_RST_OFFSET 0x00000018 +/*SPM_BASE*/ +#define CONSYS_PWRON_CONFG_EN_OFFSET 0x00000000 +#define CONSYS_TOP1_PWR_CTRL_OFFSET 0x00000304 +#define CONSYS_PWR_CONN_ACK_OFFSET 0x0000016C +#define CONSYS_PWR_CONN_ACK_S_OFFSET 0x00000170 +#define CONSYS_SPM_APSRC_OFFSET 0x000006f8 +#define CONSYS_SPM_APSRC_VALUE 0x00000005 +#define CONSYS_SPM_DDR_EN_OFFSET 0x000006fc +#define CONSYS_SPM_DDR_EN_VALUE 0x00050505 +#define CONSYS_SPM_CON_TOP_OFF_CHECK_OFFSET 0x00000178 +#define CONSYS_SPM_CON_TOP_OFF_CHECK_BIT (0x1 << 1) +/*CONN_MCU_CONFIG_BASE*/ +#define CONSYS_IP_VER_OFFSET 0x00000010 +#define CONSYS_CONF_ID_OFFSET 0x0000001c +#define CONSYS_HW_ID_OFFSET 0x00000000 +#define CONSYS_FW_ID_OFFSET 0x00000004 +#define CONSYS_MCU_CFG_ACR_OFFSET 0x00000140 +#define EMI_CONTROL_DBG_PROBE 0x00000144 +#define CONSYS_SW_IRQ_OFFSET 0x00000148 +#define CONN2AP_SW_IRQ_CLR_OFFSET 0x0000014c +#define CONN2AP_SW_IRQ_OFFSET 0x00000150 +#define CONN_MCU_EMI_CONTROL 0x00000150 + +#define CONSYS_IP_VER_ID 0x10070000 + +#define CONSYS_HIF_TOP_MISC 0x00002104 +#define CONSYS_HIF_DBG_IDX 0x0000212C +#define CONSYS_HIF_DBG_PROBE 0x00002130 +#define CONSYS_HIF_BUSY_STATUS 0x00002138 +#define CONSYS_HIF_PDMA_BUSY_STATUS 0x00002168 +#define CONSYS_HIF_PDMA_AXI_RREADY 0x00000154 +#define CONSYS_HIF_PDMA_AXI_RREADY_MASK (0x1 << 1) /* bit 1 */ +#define CONSYS_CLOCK_CONTROL 0x00000100 +#define CONSYS_BUS_CONTROL 0x00000110 +#define CONSYS_DEBUG_SELECT 0x00000400 +#define CONSYS_DEBUG_STATUS 0x0000040c +#define CONSYS_EMI_CTRL_VALUE (1 << 21) + +/*CONN_HIF_ON_BASE*/ +#define CONSYS_CLOCK_CHECK_VALUE 0x30000 +#define CONSYS_HCLK_CHECK_BIT (0x1 << 16) +#define CONSYS_OSCCLK_CHECK_BIT (0x1 << 17) +#define CONSYS_SLEEP_CHECK_BIT (0x1 << 18) + +/*AXI bus*/ +#define CONSYS_AHB_RX_PROT_EN_OFFSET 0x2AC +#define CONSYS_AHB_RX_PROT_STA_OFFSET 0x258 +#define CONSYS_AXI_RX_PROT_EN_OFFSET 0x2A4 +#define CONSYS_AXI_RX_PROT_STA_OFFSET 0x228 +#define CONSYS_AHB_RX_PROT_MASK (0x1<<10) /* bit 10 */ +#define CONSYS_AXI_RX_PROT_MASK (0x1<<14) /* bit 14 */ +#define CONSYS_AXI_TX_PROT_MASK (0x1<<18) /* bit 18 */ +#define CONSYS_AHB_TX_PROT_MASK (0x1<<13) /* bit 13 */ +#define CONSYS_AHB_TIMEOUT_EN_ADDRESS 0x18002440 +#define CONSYS_AHB_TIMEOUT_EN_VALUE 0x90000002 + +/*WPLL SETTING*/ +#define CONSYS_WPLL_SETTING_ADDRESS 0x180b3034 +#define CONSYS_WPLL_SETTING_MASK 0xFFE7FFFF /* bit 19, bit 20 */ +#define CONSYS_WPLL_SETTING_VALUE 0x00080000 /* bit 19, bit 20 */ + +/* toppose_restore_done rollback CR */ +#define CONSYS_TOPPOSE_RESTORE_ADDRESS 0x180c1130 +#define CONSYS_TOPPOSE_RESTORE_MASK 0xFBFFFFFF /* bit 26 */ +#define CONSYS_TOPPOSE_RESTORE_VALUE (0x1 << 26) + +/*SPM clock gating control register */ +#define CONSYS_PWRON_CONFG_EN_VALUE (0x0b160001) +#define CONSYS_PWRON_CONFG_DIS_VALUE (0x0b160000) + +#if CONSYS_AFE_REG_SETTING +#define CONSYS_AFE_REG_BASE (0x180B6000) +#define CONSYS_AFE_RG_WBG_PLL_03_OFFSET (0x00000038) +#define CONSYS_AFE_RG_WBG_PLL_03_VALUE (0x000C1DF0) +#define CONSYS_AFE_RG_WBG_GPS_02_OFFSET (0x00000054) +#define CONSYS_AFE_RG_WBG_GPS_02_VALUE (0x110A2000) +#endif + +#define CONSYS_AFE_WBG_REG_BASE (0x180B3000) +#define CONSYS_AFE_WBG_REG_AFE_01_OFFSET (0x10) +#define CONSYS_AFE_WBG_REG_RCK_01_OFFSET (0x18) +#define CONSYS_AFE_WBG_REG_GL1_01_OFFSET (0x40) +#define CONSYS_AFE_WBG_REG_BT_TX_03_OFFSET (0x58) +#define CONSYS_AFE_WBG_REG_WF0_TX_03_OFFSET (0x78) +#define CONSYS_AFE_WBG_REG_WF1_TX_03_OFFSET (0x94) +#define CONSYS_AFE_WBG_REG_GL5_01_OFFSET (0x100) +#define CONSYS_AFE_WBG_REG_AFE_01_VALUE (0x00000000) +#define CONSYS_AFE_WBG_REG_RCK_01_VALUE (0x144B0160) +#define CONSYS_AFE_WBG_REG_GL1_01_VALUE (0x10990C13) +#define CONSYS_AFE_WBG_REG_BT_TX_03_VALUE (0xCD258051) +#define CONSYS_AFE_WBG_REG_WF0_TX_03_VALUE (0xC5258251) +#define CONSYS_AFE_WBG_REG_WF1_TX_03_VALUE (0xC5258251) +#define CONSYS_AFE_WBG_REG_GL5_01_VALUE (0x10990C13) + +#define CONSYS_COCLOCK_STABLE_TIME_BASE (0x180C1200) +#define CONSYS_COCLOCK_ACK_ENABLE_OFFSET (0x4) +#define CONSYS_COCLOCK_ACK_ENABLE_BIT (1 << 0) +#define CONSYS_COCLOCK_ACK_ENABLE_MAST (0xffff00ff) +#define CONSYS_COCLOCK_ACK_ENABLE_VALUE (0x600) +#define CONSYS_COCLOCK_STABLE_TIME (0x708) +#define CONSYS_COCLOCK_STABLE_TIME_MASK (0xffff0000) + +#define CONSYS_COCLOCK_RC_CTL_0_TOP_OSC_RC_EN_OFFSET (0x40) +#define CONSYS_COCLOCK_RC_CTL_0_TOP_OSC_RC_EN_BIT (0x1 << 7) +#define CONSYS_COCLOCK_RC_CTL_1_GPS_XO_OFFSET (0x44) +#define CONSYS_COCLOCK_RC_CTL_0_GPS_ACK_OFFSET (0x48) +#define CONSYS_COCLOCK_RC_CTL_1_BT_XO_OFFSET (0x4C) +#define CONSYS_COCLOCK_RC_CTL_0_BT_ACK_OFFSET (0x50) +#define CONSYS_COCLOCK_RC_CTL_1_WF_XO_OFFSET (0x54) +#define CONSYS_COCLOCK_RC_CTL_0_WF_ACK_OFFSET (0x58) +#define CONSYS_COCLOCK_RC_CTL_1_TOP_XO_OFFSET (0x5C) +#define CONSYS_COCLOCK_RC_CTL_0_TOP_ACK_OFFSET (0x60) +#define CONSYS_COCLOCK_RC_CTL_1_XO_VALUE (0x02080706) +#define CONSYS_COCLOCK_RC_CTL_0_ACK_BIT (0x1 << 16) +#define CONSYS_COCLOCK_RC_CTL_0_GPS_OSC_RC_EN_BIT (0x1 << 4 | 0x1 << 12) +#define CONSYS_COCLOCK_RC_CTL_0_BT_OSC_RC_EN_BIT (0x1 << 5 | 0x1 << 13) +#define CONSYS_COCLOCK_RC_CTL_0_WF_OSC_RC_EN_BIT (0x1 << 6 | 0x1 << 14) +#define CONSYS_COCLOCK_RC_CTL_0_TOP_OSC_RC_EN_BIT_2 (0x1 << 7 | 0x1 << 15) +#define CONSYS_COCLOCK_RC_CTL_0_OSC_LEGACY_EN_BIT (0x1 << 8) + +#define CONSYS_IDENTIFY_ADIE_CR_ADDRESS (0x180C1130) +#define CONSYS_IDENTIFY_ADIE_ENABLE_BIT (0x1 << 8) + +/*CONSYS_CPU_SW_RST_REG*/ +#define CONSYS_CPU_SW_RST_BIT (0x1 << 12) +#define CONSYS_CPU_SW_RST_CTRL_KEY (0x88 << 24) +#define CONSYS_SW_RST_BIT (0x1 << 9) + +/*CONSYS_TOP1_PWR_CTRL_REG*/ +#define CONSYS_SPM_PWR_RST_BIT (0x1 << 0) +#define CONSYS_SPM_PWR_ISO_S_BIT (0x1 << 1) +#define CONSYS_SPM_PWR_ON_BIT (0x1 << 2) +#define CONSYS_SPM_PWR_ON_S_BIT (0x1 << 3) +#define CONSYS_CLK_CTRL_BIT (0x1 << 4) +#define CONSYS_SRAM_CONN_PD_BIT (0x1 << 8) +#define CONSYS_SPM_PWR_ON_CLK_BIT (0x1 << 0) +#define CONSYS_SPM_PWR_ON_CLK_CTRL_KEY (0x0B16 << 16) +#define SPM_RC_CENTRAL_CFG1 (0x0504) +#define SPM_RC_CENTRAL_CFG1_BIT (0x1) + +/*CONSYS_PWR_CONN_ACK_REG*/ +#define CONSYS_PWR_ON_ACK_BIT (0x1 << 1) + +/*CONSYS_PWR_CONN_ACK_S_REG*/ +#define CONSYS_PWR_ON_ACK_S_BIT (0x1 << 1) + +/*CONSYS_PWR_CONN_TOP2_ACK_REG*/ +#define CONSYS_TOP2_PWR_ON_ACK_BIT (0x1 << 30) + +/*CONSYS_PWR_CONN_TOP2_ACK_S_REG*/ +#define CONSYS_TOP2_PWR_ON_ACK_S_BIT (0x1 << 30) + +/*CONSYS_WD_SYS_RST_REG*/ +#define CONSYS_WD_SYS_RST_CTRL_KEY (0x88 << 24) +#define CONSYS_WD_SYS_RST_BIT (0x1 << 9) + +/*CONSYS_MCU_CFG_ACR_REG*/ +#define CONSYS_MCU_CFG_ACR_MBIST_BIT (0x1 << 0 | 0x1 << 1) + +/*control app2cnn_osc_en*/ +#define CONSYS_AP2CONN_OSC_EN_BIT (0x1 << 10) +#define CONSYS_AP2CONN_WAKEUP_BIT (0x1 << 9) + +/* EMI part mapping & ctrl*/ +#define CONSYS_EMI_COREDUMP_OFFSET (0x68000) +#define CONSYS_EMI_COREDUMP_MEM_SIZE (0xa0000) +#define CONSYS_EMI_AP_PHY_OFFSET (0x00000) +#define CONSYS_EMI_AP_PHY_BASE (0x80068000) +#define CONSYS_EMI_FW_PHY_BASE (0xf0068000) +#define CONSYS_EMI_PAGED_TRACE_OFFSET (0x400) +#define CONSYS_EMI_PAGED_DUMP_OFFSET (0x8400) +#define CONSYS_EMI_FULL_DUMP_OFFSET (0x10400) +#define CONSYS_EMI_MET_DATA_OFFSET (0x0) + +#define CONSYS_EMI_RAM_BT_BUILDTIME_OFFSET (0x68300) +#define CONSYS_EMI_RAM_WIFI_BUILDTIME_OFFSET (0x68310) +#define CONSYS_EMI_RAM_MCU_BUILDTIME_OFFSET (0x68320) +#define CONSYS_EMI_PATCH_MCU_BUILDTIME_OFFSET (0x68330) + +#define CONSYS_EMI_BT_ENTRY_OFFSET (0x504) +#define CONSYS_EMI_BT_ENTRY_ADDRESS (0xF0110000) +#define CONSYS_EMI_WIFI_ENTRY_OFFSET (0x508) +#define CONSYS_EMI_WIFI_ENTRY_ADDRESS (0xF01D0000) + +/* AP_PCCIF4_BASE Register */ +#define INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG (0x314) +#define INFRASYS_COMMON_AP2MD_PCCIF4_AP_PCCIF_ACK_OFFSET (0x14) +#define INFRASYS_COMMON_AP2MD_CON_PWR_ON_CON_SW_READY_MASK (0x3 << 0) + +/**********************************************************************/ +/* Base: conn_hif_on_base (0x1800_7000) */ +/**********************************************************************/ +#define CONN_HIF_ON_BASE_ADDR (0x18007000) +#define CONN_HOST_CR_SLEEP_CNT_OFFSET (0x58) +#define CONN_SLEEP_INFO_CTRL_OFFSET (0x5c) +#define CONN_SLEEP_INFO_READ_CTRL_TIMER_OFFSET (0x60) +#define CONN_SLEEP_INFO_READ_CTRL_COUNT_OFFSET (0x64) +#define CONSYS_CPUPCR_OFFSET (0x00000104) +#define CONN_MCU_MAILBOX_DBG (0x0120) + +/**********************************************************************/ +/* Base: conn_top_misc_on_base (0x180c_1000) */ +/**********************************************************************/ +#define CONSYS_ACCESS_EMI_HW_MODE_OFFSET (0x168) +#define CONN_CFG_ON_DBGSEL_ADDR_OFFSET (0x310) +#define CONN_CFG_ON_MON_CTL_ADDR_OFFSET (0x320) +#define CONN_CFG_ON_MON_SEL0_ADDR_OFFSET (0x328) +#define CONN_CFG_ON_MON_SEL1_ADDR_OFFSET (0x32C) +#define CONN_CFG_ON_MON_SEL2_ADDR_OFFSET (0x330) +#define CONN_CFG_ON_MON_SEL3_ADDR_OFFSET (0x334) +#define CONN_CFG_ON_MON_FLAG_RECORD_ADDR_OFFSET (0x340) + +/**********************************************************************/ +/* Base: conn_mcu_cfg_on_base (0x180a_3000) */ +/**********************************************************************/ + + +/**********************************************************************/ +/* PMIC mt6359P define for Quark project only*/ +/**********************************************************************/ +#ifndef MT6359_PMIC_REG_BASE + +#define MT6359_PMIC_REG_BASE ((unsigned int)(0x0)) + +#define MT6359_BUCK_VS2_CON1 (MT6359_PMIC_REG_BASE+0x188e) +#define MT6359_BUCK_VS2_VOTER_SET (MT6359_PMIC_REG_BASE+0x18ac) +#define MT6359_BUCK_VS2_VOTER_CLR (MT6359_PMIC_REG_BASE+0x18ae) +#define MT6359_BUCK_VS2_ELR0 (MT6359_PMIC_REG_BASE+0x18b4) +#define MT6359_LDO_VCN33_1_CON0 (MT6359_PMIC_REG_BASE+0x1be2) +#define MT6359_LDO_VCN33_1_OP_EN_SET (MT6359_PMIC_REG_BASE+0x1bea) +#define MT6359_LDO_VCN33_1_OP_CFG_SET (MT6359_PMIC_REG_BASE+0x1bf0) +#define MT6359_LDO_VCN33_2_CON0 (MT6359_PMIC_REG_BASE+0x1c08) +#define MT6359_LDO_VCN33_2_OP_EN_SET (MT6359_PMIC_REG_BASE+0x1c10) +#define MT6359_LDO_VCN33_2_OP_CFG_SET (MT6359_PMIC_REG_BASE+0x1c16) +#define MT6359_LDO_VCN13_CON0 (MT6359_PMIC_REG_BASE+0x1c1c) +#define MT6359_LDO_VCN13_OP_EN_SET (MT6359_PMIC_REG_BASE+0x1c24) +#define MT6359_LDO_VCN13_OP_CFG_SET (MT6359_PMIC_REG_BASE+0x1c2a) +#define MT6359_LDO_VCN18_CON0 (MT6359_PMIC_REG_BASE+0x1c2e) +#define MT6359_LDO_VCN18_OP_EN_SET (MT6359_PMIC_REG_BASE+0x1c36) +#define MT6359_LDO_VCN18_OP_CFG_SET (MT6359_PMIC_REG_BASE+0x1c3c) +#define MT6359_VCN13_ANA_CON0 (MT6359_PMIC_REG_BASE+0x202e) + +#define PMIC_RG_BUCK_VS2_VOTER_EN_SET_ADDR \ + MT6359_BUCK_VS2_VOTER_SET +#define PMIC_RG_BUCK_VS2_VOTER_EN_SET_MASK 0xFFF +#define PMIC_RG_BUCK_VS2_VOTER_EN_SET_SHIFT 0 +#define PMIC_RG_BUCK_VS2_VOTER_EN_CLR_ADDR \ + MT6359_BUCK_VS2_VOTER_CLR +#define PMIC_RG_BUCK_VS2_VOTER_EN_CLR_MASK 0xFFF +#define PMIC_RG_BUCK_VS2_VOTER_EN_CLR_SHIFT 0 +#define PMIC_RG_BUCK_VS2_VOSEL_ADDR \ + MT6359_BUCK_VS2_ELR0 +#define PMIC_RG_BUCK_VS2_VOSEL_MASK 0x7F +#define PMIC_RG_BUCK_VS2_VOSEL_SHIFT 0 +#define PMIC_RG_BUCK_VS2_VOSEL_SLEEP_ADDR \ + MT6359_BUCK_VS2_CON1 +#define PMIC_RG_BUCK_VS2_VOSEL_SLEEP_MASK 0x7F +#define PMIC_RG_BUCK_VS2_VOSEL_SLEEP_SHIFT 0 +#define PMIC_RG_LDO_VCN33_1_LP_ADDR \ + MT6359_LDO_VCN33_1_CON0 +#define PMIC_RG_LDO_VCN33_1_LP_MASK 0x1 +#define PMIC_RG_LDO_VCN33_1_LP_SHIFT 1 +#define PMIC_RG_LDO_VCN33_1_OP_EN_SET_ADDR \ + MT6359_LDO_VCN33_1_OP_EN_SET +#define PMIC_RG_LDO_VCN33_1_OP_CFG_SET_ADDR \ + MT6359_LDO_VCN33_1_OP_CFG_SET +#define PMIC_RG_LDO_VCN33_2_LP_ADDR \ + MT6359_LDO_VCN33_2_CON0 +#define PMIC_RG_LDO_VCN33_2_LP_MASK 0x1 +#define PMIC_RG_LDO_VCN33_2_LP_SHIFT 1 +#define PMIC_RG_LDO_VCN33_2_OP_EN_SET_ADDR \ + MT6359_LDO_VCN33_2_OP_EN_SET +#define PMIC_RG_LDO_VCN33_2_OP_CFG_SET_ADDR \ + MT6359_LDO_VCN33_2_OP_CFG_SET +#define PMIC_RG_LDO_VCN13_LP_ADDR \ + MT6359_LDO_VCN13_CON0 +#define PMIC_RG_LDO_VCN13_LP_MASK 0x1 +#define PMIC_RG_LDO_VCN13_LP_SHIFT 1 +#define PMIC_RG_LDO_VCN13_OP_EN_SET_ADDR \ + MT6359_LDO_VCN13_OP_EN_SET +#define PMIC_RG_LDO_VCN13_OP_CFG_SET_ADDR \ + MT6359_LDO_VCN13_OP_CFG_SET +#define PMIC_RG_LDO_VCN18_LP_ADDR \ + MT6359_LDO_VCN18_CON0 +#define PMIC_RG_LDO_VCN18_LP_MASK 0x1 +#define PMIC_RG_LDO_VCN18_LP_SHIFT 1 +#define PMIC_RG_LDO_VCN18_OP_EN_SET_ADDR \ + MT6359_LDO_VCN18_OP_EN_SET +#define PMIC_RG_LDO_VCN18_OP_CFG_SET_ADDR \ + MT6359_LDO_VCN18_OP_CFG_SET +#define PMIC_RG_VCN13_VOCAL_ADDR \ + MT6359_VCN13_ANA_CON0 +#define PMIC_RG_VCN13_VOCAL_MASK 0xF +#define PMIC_RG_VCN13_VOCAL_SHIFT 0 + +#endif + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +#ifdef CONSYS_BT_WIFI_SHARE_V33 +struct bt_wifi_v33_status { + UINT32 counter; + UINT32 flags; + spinlock_t lock; +}; + +extern struct bt_wifi_v33_status gBtWifiV33; +#endif + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************* +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _MTK_MT6873_H_ */ diff --git a/drivers/misc/mediatek/connectivity/common/common_main/platform/include/mtk_wcn_consys_hw.h b/drivers/misc/mediatek/connectivity/common/common_main/platform/include/mtk_wcn_consys_hw.h new file mode 100644 index 0000000000000000000000000000000000000000..1776804c012fb4c6881c9f3d9b1a79bf9656cdd8 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/platform/include/mtk_wcn_consys_hw.h @@ -0,0 +1,422 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +/*! \file + * \brief Declaration of library functions + * + * Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#ifndef _MTK_WCN_CONSYS_HW_H_ +#define _MTK_WCN_CONSYS_HW_H_ + +/*#include */ +#include "wmt_plat.h" + +/*device tree mode*/ +#ifdef CONFIG_OF +#include +#include +#include +#include +#endif +#include +#include + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) +#include +#endif + +#define ENABLE MTK_WCN_BOOL_TRUE +#define DISABLE MTK_WCN_BOOL_FALSE + +#define KBYTE (1024*sizeof(char)) +#define CONSYS_PAGED_DUMP_SIZE (32*KBYTE) +#define CONSYS_EMI_MEM_SIZE (96*KBYTE) /*coredump space , 96K is enough */ + +#define CONSYS_SET_BIT(REG, BITVAL) (*((volatile UINT32 *)(REG)) |= ((UINT32)(BITVAL))) +#define CONSYS_CLR_BIT(REG, BITVAL) ((*(volatile UINT32 *)(REG)) &= ~((UINT32)(BITVAL))) +#define CONSYS_CLR_BIT_WITH_KEY(REG, BITVAL, KEY) {\ + UINT32 val = (*(volatile UINT32 *)(REG)); \ + val &= ~((UINT32)(BITVAL)); \ + val |= ((UINT32)(KEY)); \ + (*(volatile UINT32 *)(REG)) = val;\ +} +#define CONSYS_REG_READ(addr) (*((volatile UINT32 *)(addr))) +#define CONSYS_REG_WRITE(addr, data) do {\ + writel(data, (volatile void *)addr); \ + mb(); \ +} while (0) +#define CONSYS_REG_WRITE_RANGE(reg, data, end, begin) {\ + UINT32 val = CONSYS_REG_READ(reg); \ + SET_BIT_RANGE(&val, data, end, begin); \ + CONSYS_REG_WRITE(reg, val); \ +} +#define CONSYS_REG_WRITE_MASK(reg, data, mask) {\ + UINT32 val = CONSYS_REG_READ(reg); \ + SET_BIT_MASK(&val, data, mask); \ + CONSYS_REG_WRITE(reg, val); \ +} + +/* + * Write value with value_offset bits of right shift and size bits, + * to the reg_offset-th bit of address reg + * value -----------XXXXXXXXXXXX------------------- + * |<--size-->|<--value_offset-->| + * reg -------------OOOOOOOOOOOO----------------- + * |<--size-->|<--reg_offset-->| + * result -------------XXXXXXXXXXXX----------------- + */ +#define CONSYS_REG_WRITE_OFFSET_RANGE(reg, value, reg_offset, value_offset, size) ({\ + UINT32 data = (value) >> (value_offset); \ + data = GET_BIT_RANGE(data, size, 0); \ + data = data << (reg_offset); \ + CONSYS_REG_WRITE_RANGE(reg, data, ((reg_offset) + ((size) - 1)), reg_offset); \ +}) + +#define CONSYS_REG_WRITE_BIT(reg, offset, val) CONSYS_REG_WRITE_OFFSET_RANGE(reg, ((val) & 1), offset, 0, 1) + +/*force fw assert pattern*/ +#define EXP_APMEM_HOST_OUTBAND_ASSERT_MAGIC_W1 (0x19b30bb1) + +#define DYNAMIC_DUMP_GROUP_NUM 5 + + +#define OPT_POWER_ON_DLM_TABLE (0x1) +#define OPT_SET_MCUCLK_TABLE_1_2 (0x1 << 1) +#define OPT_SET_MCUCLK_TABLE_3_4 (0x1 << 2) +#define OPT_QUERY_ADIE (0x1 << 3) +#define OPT_SET_WIFI_EXT_COMPONENT (0x1 << 4) +#define OPT_WIFI_LTE_COEX (0x1 << 5) +#define OPT_COEX_TDM_REQ_ANTSEL_NUM (0x1 << 6) +#define OPT_BT_TSSI_FROM_WIFI_CONFIG_NEW_OPID (0x1 << 7) +#define OPT_INIT_COEX_BEFORE_RF_CALIBRATION (0x1 << 8) +#define OPT_INIT_COEX_AFTER_RF_CALIBRATION (0x1 << 9) +#define OPT_COEX_CONFIG_ADJUST (0x1 << 10) +#define OPT_COEX_CONFIG_ADJUST_NEW_FLAG (0x1 << 11) +#define OPT_SET_OSC_TYPE (0x1 << 12) +#define OPT_SET_COREDUMP_LEVEL (0x1 << 13) +#define OPT_WIFI_5G_PALDO (0x1 << 14) +#define OPT_GPS_SYNC (0x1 << 15) +#define OPT_WIFI_LTE_COEX_TABLE_0 (0x1 << 16) +#define OPT_WIFI_LTE_COEX_TABLE_1 (0x1 << 17) +#define OPT_WIFI_LTE_COEX_TABLE_2 (0x1 << 18) +#define OPT_WIFI_LTE_COEX_TABLE_3 (0x1 << 19) +#define OPT_COEX_EXT_ELNA_GAIN_P1_SUPPORT (0x1 << 20) +#define OPT_NORMAL_PATCH_DWN_0 (0x1 << 21) +#define OPT_NORMAL_PATCH_DWN_1 (0x1 << 22) +#define OPT_NORMAL_PATCH_DWN_2 (0x1 << 23) +#define OPT_NORMAL_PATCH_DWN_3 (0x1 << 24) +#define OPT_PATCH_CHECKSUM (0x1 << 25) +#define OPT_DISABLE_ROM_PATCH_DWN (0x1 << 26) + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +struct CONSYS_BASE_ADDRESS { + SIZE_T mcu_base; + SIZE_T ap_rgu_base; + SIZE_T topckgen_base; + SIZE_T spm_base; + SIZE_T mcu_conn_hif_on_base; + SIZE_T mcu_top_misc_off_base; + SIZE_T mcu_cfg_on_base; + SIZE_T mcu_cirq_base; + SIZE_T da_xobuf_base; + SIZE_T mcu_top_misc_on_base; + SIZE_T mcu_conn_hif_pdma_base; + SIZE_T ap_pccif4_base; + SIZE_T infra_ao_pericfg_base; + SIZE_T infracfg_reg_base; +}; + +enum CONSYS_BASE_ADDRESS_INDEX { + MCU_BASE_INDEX = 0, + TOP_RGU_BASE_INDEX, + INFRACFG_AO_BASE_INDEX, + SPM_BASE_INDEX, + MCU_CONN_HIF_ON_BASE_INDEX, + MCU_TOP_MISC_OFF_BASE_INDEX, + MCU_CFG_ON_BASE_INDEX, + MCU_CIRQ_BASE_INDEX, + MCU_TOP_MISC_ON_BASE_INDEX, + MCU_CONN_HIF_PDMA_BASE_INDEX, + AP_PCCIF4_BASE_INDEX, + INFRA_AO_PERICFG_BASE_INDEX, + INFRACFG_REG_BASE_INDEX, +}; + +typedef enum _ENUM_EMI_CTRL_STATE_OFFSET_ { + EXP_APMEM_CTRL_STATE = 0x0, + EXP_APMEM_CTRL_HOST_SYNC_STATE = 0x4, + EXP_APMEM_CTRL_HOST_SYNC_NUM = 0x8, + EXP_APMEM_CTRL_CHIP_SYNC_STATE = 0xc, + EXP_APMEM_CTRL_CHIP_SYNC_NUM = 0x10, + EXP_APMEM_CTRL_CHIP_SYNC_ADDR = 0x14, + EXP_APMEM_CTRL_CHIP_SYNC_LEN = 0x18, + EXP_APMEM_CTRL_CHIP_PRINT_BUFF_START = 0x1c, + EXP_APMEM_CTRL_CHIP_PRINT_BUFF_LEN = 0x20, + EXP_APMEM_CTRL_CHIP_PRINT_BUFF_IDX = 0x24, + EXP_APMEM_CTRL_CHIP_INT_STATUS = 0x28, + EXP_APMEM_CTRL_CHIP_PAGED_DUMP_END = 0x2c, + EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1 = 0x30, + EXP_APMEM_CTRL_CHIP_PAGE_DUMP_NUM = 0x44, + EXP_APMEM_CTRL_CHIP_FW_DBGLOG_MODE = 0x40, + EXP_APMEM_CTRL_CHIP_DYNAMIC_DUMP = 0x48, + EXP_APMEM_CTRL_CHIP_CHECK_SLEEP = 0x4c, + EXP_APMEM_CTRL_ASSERT_FLAG = 0x100, + EXP_APMEM_CTRL_MAX +} ENUM_EMI_CTRL_STATE_OFFSET, *P_ENUM_EMI_CTRL_STATE_OFFSET; + +typedef enum _CONSYS_GPS_CO_CLOCK_TYPE_ { + GPS_TCXO_TYPE = 0, + GPS_CO_TSX_TYPE = 1, + GPS_CO_DCXO_TYPE = 2, + GPS_CO_VCTCXO_TYPE = 3, + GPS_CO_CLOCK_TYPE_MAX +} CONSYS_GPS_CO_CLOCK_TYPE, *P_CONSYS_GPS_CO_CLOCK_TYPE; + +typedef INT32(*CONSYS_IC_CLOCK_BUFFER_CTRL) (MTK_WCN_BOOL enable); +typedef VOID(*CONSYS_IC_HW_RESET_BIT_SET) (MTK_WCN_BOOL enable); +typedef VOID(*CONSYS_IC_HW_SPM_CLK_GATING_ENABLE) (VOID); +typedef INT32(*CONSYS_IC_HW_POWER_CTRL) (MTK_WCN_BOOL enable); +typedef INT32(*CONSYS_IC_AHB_CLOCK_CTRL) (MTK_WCN_BOOL enable); +typedef INT32(*POLLING_CONSYS_IC_CHIPID) (VOID); +typedef VOID(*UPDATE_CONSYS_ROM_DESEL_VALUE) (VOID); +typedef VOID(*CONSYS_HANG_DEBUG)(VOID); +typedef VOID(*CONSYS_IC_ARC_REG_SETTING) (VOID); +typedef VOID(*CONSYS_IC_AFE_REG_SETTING) (VOID); +typedef INT32(*CONSYS_IC_HW_VCN18_CTRL) (MTK_WCN_BOOL enable); +typedef VOID(*CONSYS_IC_VCN28_HW_MODE_CTRL) (UINT32 enable); +typedef INT32(*CONSYS_IC_HW_VCN28_CTRL) (UINT32 enable); +typedef INT32(*CONSYS_IC_HW_WIFI_VCN33_CTRL) (UINT32 enable); +typedef INT32(*CONSYS_IC_HW_BT_VCN33_CTRL) (UINT32 enable); +typedef INT32(*CONSYS_IC_HW_VCN_CTRL_AFTER_IDLE) (VOID); +typedef UINT32(*CONSYS_IC_SOC_CHIPID_GET) (VOID); +typedef INT32(*CONSYS_IC_ADIE_CHIPID_DETECT) (VOID); +typedef INT32(*CONSYS_IC_EMI_MPU_SET_REGION_PROTECTION) (VOID); +typedef UINT32(*CONSYS_IC_EMI_SET_REMAPPING_REG) (VOID); +typedef INT32(*IC_BT_WIFI_SHARE_V33_SPIN_LOCK_INIT) (VOID); +typedef INT32(*CONSYS_IC_CLK_GET_FROM_DTS) (struct platform_device *pdev); +typedef INT32(*CONSYS_IC_PMIC_GET_FROM_DTS) (struct platform_device *pdev); +typedef INT32(*CONSYS_IC_READ_IRQ_INFO_FROM_DTS) (struct platform_device *pdev, PINT32 irq_num, PUINT32 irq_flag); +typedef INT32(*CONSYS_IC_READ_REG_FROM_DTS) (struct platform_device *pdev); +typedef UINT32(*CONSYS_IC_READ_CPUPCR) (VOID); +typedef VOID(*IC_FORCE_TRIGGER_ASSERT_DEBUG_PIN) (VOID); +typedef INT32(*CONSYS_IC_CO_CLOCK_TYPE) (VOID); +typedef P_CONSYS_EMI_ADDR_INFO(*CONSYS_IC_SOC_GET_EMI_PHY_ADD) (VOID); +typedef MTK_WCN_BOOL(*CONSYS_IC_NEED_STORE_PDEV) (VOID); +typedef UINT32(*CONSYS_IC_STORE_PDEV) (struct platform_device *pdev); +typedef UINT32(*CONSYS_IC_STORE_RESET_CONTROL) (struct platform_device *pdev); +typedef MTK_WCN_BOOL(*CONSYS_IC_NEED_GPS) (VOID); +typedef VOID(*CONSYS_IC_SET_IF_PINMUX) (MTK_WCN_BOOL enable); +typedef VOID(*CONSYS_IC_SET_DL_ROM_PATCH_FLAG) (INT32 flag); +typedef INT32(*CONSYS_IC_DEDICATED_LOG_PATH_INIT) (struct platform_device *pdev); +typedef VOID(*CONSYS_IC_DEDICATED_LOG_PATH_DEINIT) (VOID); +typedef INT32(*CONSYS_IC_CHECK_REG_READABLE) (VOID); +typedef INT32(*CONSYS_IC_EMI_COREDUMP_REMAPPING) (UINT8 __iomem **addr, UINT32 enable); +typedef INT32(*CONSYS_IC_RESET_EMI_COREDUMP) (UINT8 __iomem *addr); +typedef VOID(*CONSYS_IC_CLOCK_FAIL_DUMP) (VOID); +typedef INT32(*CONSYS_IC_IS_CONNSYS_REG) (UINT32 addr); +typedef INT32(*CONSYS_IC_IS_HOST_CSR) (SIZE_T addr); +typedef INT32(*CONSYS_IC_DUMP_OSC_STATE) (P_CONSYS_STATE state); +typedef VOID(*CONSYS_IC_SET_PDMA_AXI_RREADY_FORCE_HIGH) (UINT32 enable); +typedef VOID(*CONSYS_IC_SET_MCIF_EMI_MPU_PROTECTION)(MTK_WCN_BOOL enable); +typedef INT32(*CONSYS_IC_CALIBRATION_BACKUP_RESTORE) (VOID); +typedef VOID(*CONSYS_IC_REGISTER_DEVAPC_CB) (VOID); +typedef VOID(*CONSYS_IC_INFRA_REG_DUMP)(VOID); +typedef INT32(*CONSYS_IC_IS_ANT_SWAP_ENABLE_BY_HWID) (INT32 pin_num); +typedef VOID(*CONSYS_IC_GET_ANT_SEL_CR_ADDR) (PUINT32 default_invert_cr, PUINT32 default_invert_bit); +typedef VOID(*CONSYS_IC_EMI_ENTRY_ADDRESS) (VOID); +typedef VOID(*CONSYS_IC_SET_XO_OSC_CTRL) (VOID); +typedef VOID(*CONSYS_IC_IDENTIFY_ADIE) (VOID); +typedef VOID(*CONSYS_IC_WIFI_CTRL_SETTING) (VOID); +typedef VOID(*CONSYS_IC_WIFI_CTRL_SWITCH_CONN_MODE) (VOID); +typedef VOID(*CONSYS_IC_BUS_TIMEOUT_CONFIG) (VOID); +typedef VOID(*CONSYS_IC_SET_ACCESS_EMI_HW_MODE) (VOID); +typedef INT32(*CONSYS_IC_DUMP_GATING_STATE) (P_CONSYS_STATE state); +typedef INT32(*CONSYS_IC_SLEEP_INFO_ENABLE_CTRL) (UINT32 enable); +typedef INT32(*CONSYS_IC_SLEEP_INFO_READ_CTRL) (WMT_SLEEP_COUNT_TYPE type, PUINT64 sleep_counter, PUINT64 sleep_timer); +typedef INT32(*CONSYS_IC_SLEEP_INFO_CLEAR) (VOID); +typedef UINT64(*CONSYS_IC_GET_OPTIONS) (VOID); +typedef INT32(*CONSYS_IC_POLLING_GOTO_IDLE) (VOID); + +typedef struct _WMT_CONSYS_IC_OPS_ { + CONSYS_IC_CLOCK_BUFFER_CTRL consys_ic_clock_buffer_ctrl; + CONSYS_IC_HW_RESET_BIT_SET consys_ic_hw_reset_bit_set; + CONSYS_IC_HW_SPM_CLK_GATING_ENABLE consys_ic_hw_spm_clk_gating_enable; + CONSYS_IC_HW_POWER_CTRL consys_ic_hw_power_ctrl; + CONSYS_IC_AHB_CLOCK_CTRL consys_ic_ahb_clock_ctrl; + POLLING_CONSYS_IC_CHIPID polling_consys_ic_chipid; + UPDATE_CONSYS_ROM_DESEL_VALUE update_consys_rom_desel_value; + CONSYS_HANG_DEBUG consys_hang_debug; + CONSYS_IC_ARC_REG_SETTING consys_ic_acr_reg_setting; + CONSYS_IC_AFE_REG_SETTING consys_ic_afe_reg_setting; + CONSYS_IC_HW_VCN18_CTRL consys_ic_hw_vcn18_ctrl; + CONSYS_IC_VCN28_HW_MODE_CTRL consys_ic_vcn28_hw_mode_ctrl; + CONSYS_IC_HW_VCN28_CTRL consys_ic_hw_vcn28_ctrl; + CONSYS_IC_HW_WIFI_VCN33_CTRL consys_ic_hw_wifi_vcn33_ctrl; + CONSYS_IC_HW_BT_VCN33_CTRL consys_ic_hw_bt_vcn33_ctrl; + CONSYS_IC_HW_VCN_CTRL_AFTER_IDLE consys_ic_hw_vcn_ctrl_after_idle; + CONSYS_IC_SOC_CHIPID_GET consys_ic_soc_chipid_get; + CONSYS_IC_ADIE_CHIPID_DETECT consys_ic_adie_chipid_detect; + CONSYS_IC_EMI_MPU_SET_REGION_PROTECTION consys_ic_emi_mpu_set_region_protection; + CONSYS_IC_EMI_SET_REMAPPING_REG consys_ic_emi_set_remapping_reg; + IC_BT_WIFI_SHARE_V33_SPIN_LOCK_INIT ic_bt_wifi_share_v33_spin_lock_init; + CONSYS_IC_CLK_GET_FROM_DTS consys_ic_clk_get_from_dts; + CONSYS_IC_PMIC_GET_FROM_DTS consys_ic_pmic_get_from_dts; + CONSYS_IC_READ_IRQ_INFO_FROM_DTS consys_ic_read_irq_info_from_dts; + CONSYS_IC_READ_REG_FROM_DTS consys_ic_read_reg_from_dts; + CONSYS_IC_READ_CPUPCR consys_ic_read_cpupcr; + IC_FORCE_TRIGGER_ASSERT_DEBUG_PIN ic_force_trigger_assert_debug_pin; + CONSYS_IC_CO_CLOCK_TYPE consys_ic_co_clock_type; + CONSYS_IC_SOC_GET_EMI_PHY_ADD consys_ic_soc_get_emi_phy_add; + CONSYS_IC_NEED_STORE_PDEV consys_ic_need_store_pdev; + CONSYS_IC_STORE_PDEV consys_ic_store_pdev; + CONSYS_IC_STORE_RESET_CONTROL consys_ic_store_reset_control; + CONSYS_IC_NEED_GPS consys_ic_need_gps; + CONSYS_IC_SET_IF_PINMUX consys_ic_set_if_pinmux; + CONSYS_IC_SET_DL_ROM_PATCH_FLAG consys_ic_set_dl_rom_patch_flag; + CONSYS_IC_DEDICATED_LOG_PATH_INIT consys_ic_dedicated_log_path_init; + CONSYS_IC_DEDICATED_LOG_PATH_DEINIT consys_ic_dedicated_log_path_deinit; + CONSYS_IC_CHECK_REG_READABLE consys_ic_check_reg_readable; + CONSYS_IC_EMI_COREDUMP_REMAPPING consys_ic_emi_coredump_remapping; + CONSYS_IC_RESET_EMI_COREDUMP consys_ic_reset_emi_coredump; + CONSYS_IC_CLOCK_FAIL_DUMP consys_ic_clock_fail_dump; + CONSYS_IC_IS_CONNSYS_REG consys_ic_is_connsys_reg; + CONSYS_IC_IS_HOST_CSR consys_ic_is_host_csr; + CONSYS_IC_DUMP_OSC_STATE consys_ic_dump_osc_state; + CONSYS_IC_SET_PDMA_AXI_RREADY_FORCE_HIGH consys_ic_set_pdma_axi_rready_force_high; + CONSYS_IC_SET_MCIF_EMI_MPU_PROTECTION consys_ic_set_mcif_emi_mpu_protection; + CONSYS_IC_CALIBRATION_BACKUP_RESTORE consys_ic_calibration_backup_restore; + CONSYS_IC_REGISTER_DEVAPC_CB consys_ic_register_devapc_cb; + CONSYS_IC_INFRA_REG_DUMP consys_ic_infra_reg_dump; + CONSYS_IC_IS_ANT_SWAP_ENABLE_BY_HWID consys_ic_is_ant_swap_enable_by_hwid; + CONSYS_IC_GET_ANT_SEL_CR_ADDR consys_ic_get_ant_sel_cr_addr; + CONSYS_IC_EMI_ENTRY_ADDRESS consys_ic_emi_entry_address; + CONSYS_IC_SET_XO_OSC_CTRL consys_ic_set_xo_osc_ctrl; + CONSYS_IC_IDENTIFY_ADIE consys_ic_identify_adie; + CONSYS_IC_WIFI_CTRL_SETTING consys_ic_wifi_ctrl_setting; + CONSYS_IC_WIFI_CTRL_SWITCH_CONN_MODE consys_ic_wifi_ctrl_switch_conn_mode; + CONSYS_IC_BUS_TIMEOUT_CONFIG consys_ic_bus_timeout_config; + CONSYS_IC_SET_ACCESS_EMI_HW_MODE consys_ic_set_access_emi_hw_mode; + CONSYS_IC_DUMP_GATING_STATE consys_ic_dump_gating_state; + CONSYS_IC_SLEEP_INFO_ENABLE_CTRL consys_ic_sleep_info_enable_ctrl; + CONSYS_IC_SLEEP_INFO_READ_CTRL consys_ic_sleep_info_read_ctrl; + CONSYS_IC_SLEEP_INFO_CLEAR consys_ic_sleep_info_clear; + CONSYS_IC_GET_OPTIONS consys_ic_get_options; + CONSYS_IC_POLLING_GOTO_IDLE consys_ic_polling_goto_idle; +} WMT_CONSYS_IC_OPS, *P_WMT_CONSYS_IC_OPS; +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ +#if CFG_WMT_DUMP_INT_STATUS +extern void mt_irq_dump_status(int irq); +#endif +extern struct CONSYS_BASE_ADDRESS conn_reg; +extern UINT32 gCoClockFlag; +extern EMI_CTRL_STATE_OFFSET mtk_wcn_emi_state_off; +extern CONSYS_EMI_ADDR_INFO mtk_wcn_emi_addr_info; + +extern UINT64 gConEmiSize; +extern phys_addr_t gConEmiPhyBase; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) +extern struct regmap *g_regmap; +#endif + + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +INT32 mtk_wcn_consys_hw_init(VOID); +INT32 mtk_wcn_consys_hw_deinit(VOID); +INT32 mtk_wcn_consys_hw_pwr_off(UINT32 co_clock_type); +INT32 mtk_wcn_consys_hw_pwr_on(UINT32 co_clock_type); +INT32 mtk_wcn_consys_hw_rst(UINT32 co_clock_type); +INT32 mtk_wcn_consys_hw_bt_paldo_ctrl(UINT32 enable); +INT32 mtk_wcn_consys_hw_wifi_paldo_ctrl(UINT32 enable); +INT32 mtk_wcn_consys_hw_efuse_paldo_ctrl(UINT32 enable, UINT32 co_clock_type); +INT32 mtk_wcn_consys_hw_vcn28_ctrl(UINT32 enable); +INT32 mtk_wcn_consys_hw_state_show(VOID); +PUINT8 mtk_wcn_consys_emi_virt_addr_get(UINT32 ctrl_state_offset); +P_CONSYS_EMI_ADDR_INFO mtk_wcn_consys_soc_get_emi_phy_add(VOID); +UINT32 mtk_wcn_consys_read_cpupcr(VOID); + +VOID mtk_wcn_force_trigger_assert_debug_pin(VOID); +INT32 mtk_wcn_consys_read_irq_info_from_dts(PINT32 irq_num, PUINT32 irq_flag); +INT32 mtk_wcn_consys_reg_ctrl(UINT32 is_write, enum CONSYS_BASE_ADDRESS_INDEX index, UINT32 offset, + PUINT32 value); + +P_WMT_CONSYS_IC_OPS mtk_wcn_get_consys_ic_ops(VOID); +INT32 mtk_wcn_consys_jtag_set_for_mcu(VOID); +#if CONSYS_ENALBE_SET_JTAG +UINT32 mtk_wcn_consys_jtag_flag_ctrl(UINT32 en); +#endif +#ifdef CONSYS_WMT_REG_SUSPEND_CB_ENABLE +UINT32 mtk_wcn_consys_hw_osc_en_ctrl(UINT32 en); +#endif +UINT32 mtk_wcn_consys_soc_chipid(VOID); +UINT32 mtk_wcn_consys_get_adie_chipid(VOID); +INT32 mtk_wcn_consys_detect_adie_chipid(UINT32 co_clock_type); +#if !defined(CONFIG_MTK_GPIO_LEGACY) +struct pinctrl *mtk_wcn_consys_get_pinctrl(VOID); +#endif +INT32 mtk_wcn_consys_co_clock_type(VOID); +INT32 mtk_wcn_consys_set_dbg_mode(UINT32 flag); +INT32 mtk_wcn_consys_set_dynamic_dump(PUINT32 buf); +INT32 mtk_wdt_swsysret_config(INT32 bit, INT32 set_value); +VOID mtk_wcn_consys_hang_debug(VOID); +UINT32 mtk_consys_get_gps_lna_pin_num(VOID); +INT32 mtk_consys_check_reg_readable(VOID); +INT32 mtk_consys_check_reg_readable_by_addr(SIZE_T addr); +VOID mtk_wcn_consys_clock_fail_dump(VOID); +INT32 mtk_consys_is_connsys_reg(UINT32 addr); +VOID mtk_consys_set_mcif_mpu_protection(MTK_WCN_BOOL enable); +INT32 mtk_consys_is_calibration_backup_restore_support(VOID); +VOID mtk_consys_set_chip_reset_status(INT32 status); +INT32 mtk_consys_chip_reset_status(VOID); +INT32 mtk_consys_is_ant_swap_enable_by_hwid(VOID); +INT32 mtk_consys_dump_osc_state(P_CONSYS_STATE state); +VOID mtk_wcn_consys_ic_get_ant_sel_cr_addr(PUINT32 default_invert_cr, PUINT32 default_invert_bit); +INT32 mtk_wcn_consys_dump_gating_state(P_CONSYS_STATE state); +INT32 mtk_wcn_consys_sleep_info_read_all_ctrl(P_CONSYS_STATE state); +INT32 mtk_wcn_consys_sleep_info_clear(VOID); +INT32 mtk_wcn_consys_sleep_info_restore(VOID); +UINT64 mtk_wcn_consys_get_options(VOID); +#endif /* _MTK_WCN_CONSYS_HW_H_ */ + diff --git a/drivers/misc/mediatek/connectivity/common/common_main/platform/mt6580.c b/drivers/misc/mediatek/connectivity/common/common_main/platform/mt6580.c new file mode 100644 index 0000000000000000000000000000000000000000..0c53eea3d4a82d687adc07500042c5fa54a1bd83 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/platform/mt6580.c @@ -0,0 +1,1158 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +#ifdef DFT_TAG +#undef DFT_TAG +#endif +#define DFT_TAG "[WMT-CONSYS-HW]" + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include + +#if defined(CONFIG_MTK_CLKMGR) +#include +#else +#include +#endif /* defined(CONFIG_MTK_CLKMGR) */ +#include +#include +#include "osal_typedef.h" +#include "mt6580.h" +#include "mtk_wcn_consys_hw.h" +#include + +#if CONSYS_EMI_MPU_SETTING +#include +#endif + +#if CONSYS_PMIC_CTRL_ENABLE +#include +#include +#endif + +#ifdef CONFIG_MTK_HIBERNATION +#include +#endif + +#include + +#if CONSYS_CLOCK_BUF_CTRL +#include +#endif + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +static INT32 consys_clock_buffer_ctrl(MTK_WCN_BOOL enable); +static VOID consys_hw_reset_bit_set(MTK_WCN_BOOL enable); +static VOID consys_hw_spm_clk_gating_enable(VOID); +static INT32 consys_hw_power_ctrl(MTK_WCN_BOOL enable); +static INT32 consys_ahb_clock_ctrl(MTK_WCN_BOOL enable); +static INT32 polling_consys_chipid(VOID); +static VOID consys_acr_reg_setting(VOID); +static VOID consys_afe_reg_setting(VOID); +static INT32 consys_hw_vcn18_ctrl(MTK_WCN_BOOL enable); +static VOID consys_vcn28_hw_mode_ctrl(UINT32 enable); +static INT32 consys_hw_vcn28_ctrl(UINT32 enable); +static INT32 consys_hw_wifi_vcn33_ctrl(UINT32 enable); +static INT32 consys_hw_bt_vcn33_ctrl(UINT32 enable); +static UINT32 consys_soc_chipid_get(VOID); +static INT32 consys_emi_mpu_set_region_protection(VOID); +static UINT32 consys_emi_set_remapping_reg(VOID); +static INT32 bt_wifi_share_v33_spin_lock_init(VOID); +static INT32 consys_clk_get_from_dts(struct platform_device *pdev); +static INT32 consys_pmic_get_from_dts(struct platform_device *pdev); +static INT32 consys_read_irq_info_from_dts(struct platform_device *pdev, INT32 *irq_num, UINT32 *irq_flag); +static INT32 consys_read_reg_from_dts(struct platform_device *pdev); +static UINT32 consys_read_cpupcr(VOID); +static VOID force_trigger_assert_debug_pin(VOID); +static P_CONSYS_EMI_ADDR_INFO consys_soc_get_emi_phy_add(VOID); +static INT32 consys_emi_coredump_remapping(UINT8 __iomem **addr, UINT32 enable); +static INT32 consys_reset_emi_coredump(UINT8 __iomem *addr); +static UINT64 consys_get_options(VOID); + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ +#if CONSYS_BT_WIFI_SHARE_V33 +struct bt_wifi_v33_status gBtWifiV33; +#endif + +/* PMIC part */ +#if CONSYS_PMIC_CTRL_ENABLE +#if !defined(CONFIG_MTK_PMIC_LEGACY) +struct regulator *reg_VCN18; +struct regulator *reg_VCN28; +struct regulator *reg_VCN33_BT; +struct regulator *reg_VCN33_WIFI; +#endif +#endif + +/* CCF part */ +#if !defined(CONFIG_MTK_CLKMGR) +struct clk *clk_scp_conn_main; /*ctrl conn_power_on/off */ +struct clk *clk_infra_conn_main; /*ctrl infra_connmcu_bus clk */ +#endif /* !defined(CONFIG_MTK_CLKMGR) */ + + +EMI_CTRL_STATE_OFFSET mtk_wcn_emi_state_off = { + .emi_apmem_ctrl_state = EXP_APMEM_CTRL_STATE, + .emi_apmem_ctrl_host_sync_state = EXP_APMEM_CTRL_HOST_SYNC_STATE, + .emi_apmem_ctrl_host_sync_num = EXP_APMEM_CTRL_HOST_SYNC_NUM, + .emi_apmem_ctrl_chip_sync_state = EXP_APMEM_CTRL_CHIP_SYNC_STATE, + .emi_apmem_ctrl_chip_sync_num = EXP_APMEM_CTRL_CHIP_SYNC_NUM, + .emi_apmem_ctrl_chip_sync_addr = EXP_APMEM_CTRL_CHIP_SYNC_ADDR, + .emi_apmem_ctrl_chip_sync_len = EXP_APMEM_CTRL_CHIP_SYNC_LEN, + .emi_apmem_ctrl_chip_print_buff_start = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_START, + .emi_apmem_ctrl_chip_print_buff_len = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_LEN, + .emi_apmem_ctrl_chip_print_buff_idx = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_IDX, + .emi_apmem_ctrl_chip_int_status = EXP_APMEM_CTRL_CHIP_INT_STATUS, + .emi_apmem_ctrl_chip_paded_dump_end = EXP_APMEM_CTRL_CHIP_PAGED_DUMP_END, + .emi_apmem_ctrl_host_outband_assert_w1 = EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1, + .emi_apmem_ctrl_chip_page_dump_num = EXP_APMEM_CTRL_CHIP_PAGE_DUMP_NUM, + .emi_apmem_ctrl_assert_flag = EXP_APMEM_CTRL_ASSERT_FLAG, +}; + +CONSYS_EMI_ADDR_INFO mtk_wcn_emi_addr_info = { + .emi_phy_addr = CONSYS_EMI_FW_PHY_BASE, + .paged_trace_off = CONSYS_EMI_PAGED_TRACE_OFFSET, + .paged_dump_off = CONSYS_EMI_PAGED_DUMP_OFFSET, + .full_dump_off = CONSYS_EMI_FULL_DUMP_OFFSET, + .p_ecso = &mtk_wcn_emi_state_off, + .emi_core_dump_offset = CONSYS_EMI_COREDUMP_OFFSET, +}; + +WMT_CONSYS_IC_OPS consys_ic_ops = { + .consys_ic_clock_buffer_ctrl = consys_clock_buffer_ctrl, + .consys_ic_hw_reset_bit_set = consys_hw_reset_bit_set, + .consys_ic_hw_spm_clk_gating_enable = consys_hw_spm_clk_gating_enable, + .consys_ic_hw_power_ctrl = consys_hw_power_ctrl, + .consys_ic_ahb_clock_ctrl = consys_ahb_clock_ctrl, + .polling_consys_ic_chipid = polling_consys_chipid, + .consys_ic_acr_reg_setting = consys_acr_reg_setting, + .consys_ic_afe_reg_setting = consys_afe_reg_setting, + .consys_ic_hw_vcn18_ctrl = consys_hw_vcn18_ctrl, + .consys_ic_vcn28_hw_mode_ctrl = consys_vcn28_hw_mode_ctrl, + .consys_ic_hw_vcn28_ctrl = consys_hw_vcn28_ctrl, + .consys_ic_hw_wifi_vcn33_ctrl = consys_hw_wifi_vcn33_ctrl, + .consys_ic_hw_bt_vcn33_ctrl = consys_hw_bt_vcn33_ctrl, + .consys_ic_soc_chipid_get = consys_soc_chipid_get, + .consys_ic_emi_mpu_set_region_protection = consys_emi_mpu_set_region_protection, + .consys_ic_emi_set_remapping_reg = consys_emi_set_remapping_reg, + .ic_bt_wifi_share_v33_spin_lock_init = bt_wifi_share_v33_spin_lock_init, + .consys_ic_clk_get_from_dts = consys_clk_get_from_dts, + .consys_ic_pmic_get_from_dts = consys_pmic_get_from_dts, + .consys_ic_read_irq_info_from_dts = consys_read_irq_info_from_dts, + .consys_ic_read_reg_from_dts = consys_read_reg_from_dts, + .consys_ic_read_cpupcr = consys_read_cpupcr, + .ic_force_trigger_assert_debug_pin = force_trigger_assert_debug_pin, + .consys_ic_soc_get_emi_phy_add = consys_soc_get_emi_phy_add, + .consys_ic_emi_coredump_remapping = consys_emi_coredump_remapping, + .consys_ic_reset_emi_coredump = consys_reset_emi_coredump, + .consys_ic_get_options = consys_get_options, +}; + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +UINT32 gJtagCtrl; +#if CONSYS_ENALBE_SET_JTAG +#define JTAG_ADDR1_BASE 0x10002000 +PINT8 jtag_addr1 = (PINT8)JTAG_ADDR1_BASE; +#define JTAG1_REG_WRITE(addr, value) \ + writel(value, ((PUINT32)(jtag_addr1+(addr-JTAG_ADDR1_BASE)))) +#define JTAG1_REG_READ(addr) \ + readl(((PUINT32)(jtag_addr1+(addr-JTAG_ADDR1_BASE)))) +#endif + +INT32 mtk_wcn_consys_jtag_set_for_mcu(VOID) +{ +#if CONSYS_ENALBE_SET_JTAG + + if (gJtagCtrl) { +#if 0 + INT32 iRet = -1; + + WMT_PLAT_PR_INFO("WCN jtag_set_for_mcu start...\n"); + jtag_addr1 = ioremap(JTAG_ADDR1_BASE, 0x5000); + if (jtag_addr1 == 0) { + WMT_PLAT_PR_ERR("remap jtag_addr1 fail!\n"); + return iRet; + } + WMT_PLAT_PR_INFO("jtag_addr1 = 0x%p\n", jtag_addr1); + + JTAG1_REG_WRITE(0x100053c4, 0x11111100); + JTAG1_REG_WRITE(0x100053d4, 0x00111111); + + /*Enable IES of all pins */ + JTAG1_REG_WRITE(0x10002014, 0x00000003); + JTAG1_REG_WRITE(0x10005334, 0x55000000); + JTAG1_REG_WRITE(0x10005344, 0x00555555); + JTAG1_REG_WRITE(0x10005008, 0xc0000000); + JTAG1_REG_WRITE(0x10005018, 0x0000000d); + JTAG1_REG_WRITE(0x10005014, 0x00000032); + JTAG1_REG_WRITE(0x100020a4, 0x000000ff); + JTAG1_REG_WRITE(0x100020d4, 0x000000b4); + JTAG1_REG_WRITE(0x100020d8, 0x0000004b); + + WMT_PLAT_PR_INFO("WCN jtag set for mcu start...\n"); + kal_uint32 tmp = 0; + kal_int32 addr = 0; + kal_int32 remap_addr1 = 0; + kal_int32 remap_addr2 = 0; + + remap_addr1 = ioremap(JTAG_ADDR1_BASE, 0x1000); + if (remap_addr1 == 0) { + WMT_PLAT_PR_ERR("remap jtag_addr1 fail!\n"); + return -1; + } + + remap_addr2 = ioremap(JTAG_ADDR2_BASE, 0x100); + if (remap_addr2 == 0) { + WMT_PLAT_PR_ERR("remap jtag_addr2 fail!\n"); + return -1; + } + + /*Pinmux setting for MT6625 I/F */ + addr = remap_addr1 + 0x03C0; + tmp = DRV_Reg32(addr); + tmp = tmp & 0xff; + tmp = tmp | 0x11111100; + DRV_WriteReg32(addr, tmp); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%08x, 0x%08x)", addr, DRV_Reg32(addr)); + + addr = remap_addr1 + 0x03D0; + tmp = DRV_Reg32(addr); + tmp = tmp & 0xff000000; + tmp = tmp | 0x00111111; + DRV_WriteReg32(addr, tmp); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%08x, 0x%08x)", addr, DRV_Reg32(addr)); + + /*AP GPIO Setting 1 */ + /*Enable IES */ + /* addr = 0x10002014; */ + addr = remap_addr2 + 0x0014; + tmp = 0x00000003; + DRV_WriteReg32(addr, tmp); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%08x, 0x%08x)", addr, DRV_Reg32(addr)); + /*GPIO mode setting */ + /* addr = 0x10005334; */ + addr = remap_addr1 + 0x0334; + tmp = 0x55000000; + DRV_WriteReg32(addr, tmp); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%08x, 0x%08x)", addr, DRV_Reg32(addr)); + + /* addr = 0x10005344; */ + addr = remap_addr1 + 0x0344; + tmp = 0x00555555; + DRV_WriteReg32(addr, tmp); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%08x, 0x%08x)", addr, DRV_Reg32(addr)); + /*GPIO direction control */ + /* addr = 0x10005008; */ + addr = remap_addr1 + 0x0008; + tmp = 0xc0000000; + DRV_WriteReg32(addr, tmp); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%08x, 0x%08x)", addr, DRV_Reg32(addr)); + + /* addr = 0x10005018; */ + addr = remap_addr1 + 0x0018; + tmp = 0x0000000d; + DRV_WriteReg32(addr, tmp); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%08x, 0x%08x)", addr, DRV_Reg32(addr)); + + /* addr = 0x10005014; */ + addr = remap_addr1 + 0x0014; + tmp = 0x00000032; + DRV_WriteReg32(addr, tmp); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%08x, 0x%08x)", addr, DRV_Reg32(addr)); + + /*PULL Enable */ + /* addr = 0x100020a4; */ + addr = remap_addr2 + 0x00a4; + tmp = 0x000000ff; + DRV_WriteReg32(addr, tmp); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%08x, 0x%08x)", addr, DRV_Reg32(addr)); + + /*PULL select enable */ + /* addr = 0x100020d4; */ + addr = remap_addr2 + 0x00d4; + tmp = 0x000000b4; + DRV_WriteReg32(addr, tmp); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%08x, 0x%08x)", addr, DRV_Reg32(addr)); + + /* addr = 0x100020d8; */ + addr = remap_addr2 + 0x00d8; + tmp = 0x0000004b; + DRV_WriteReg32(addr, tmp); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%08x, 0x%08x)", addr, DRV_Reg32(addr)); +#endif + } +#endif + return 0; +} + +UINT32 mtk_wcn_consys_jtag_flag_ctrl(UINT32 en) +{ + WMT_PLAT_PR_INFO("%s jtag set for MCU\n", en ? "enable" : "disable"); + gJtagCtrl = en; + return 0; +} + +#if CONSYS_PMIC_CTRL_ENABLE +#ifdef CFG_WMT_READ_EFUSE_VCN33 +INT32 wmt_set_pmic_voltage(UINT32 level) +{ + INT32 iRet = -1; + + switch (level) { + case 0: + regulator_set_voltage(reg_VCN33_BT, 3300000, 3300000); + regulator_set_voltage(reg_VCN33_WIFI, 3300000, 3300000); + WMT_PLAT_PR_INFO("WMT set BT/WIFI regulator voltage:3.3V!\n"); + iRet = 0; + break; + case 1: + regulator_set_voltage(reg_VCN33_BT, 3400000, 3400000); + regulator_set_voltage(reg_VCN33_WIFI, 3400000, 3400000); + WMT_PLAT_PR_INFO("WMT set BT/WIFI regulator voltage:3.4V!\n"); + iRet = 0; + break; + case 2: + regulator_set_voltage(reg_VCN33_BT, 3500000, 3500000); + regulator_set_voltage(reg_VCN33_WIFI, 3500000, 3500000); + WMT_PLAT_PR_INFO("WMT set BT/WIFI regulator voltage:3.5V!\n"); + iRet = 0; + break; + case 3: + regulator_set_voltage(reg_VCN33_BT, 3600000, 3600000); + regulator_set_voltage(reg_VCN33_WIFI, 3600000, 3600000); + WMT_PLAT_PR_INFO("WMT set BT/WIFI regulator voltage:3.6V!\n"); + iRet = 0; + break; + default: + regulator_set_voltage(reg_VCN33_BT, 3500000, 3500000); + regulator_set_voltage(reg_VCN33_WIFI, 3500000, 3500000); + WMT_PLAT_PR_INFO("WMT set BT/WIFI regulator voltage default:3.5V!\n"); + iRet = 0; + break; + } + return iRet; +} +#endif /*CFG_WMT_READ_EFUSE_VCN33 defined*/ +#endif + +static INT32 consys_clock_buffer_ctrl(MTK_WCN_BOOL enable) +{ +#if CONSYS_CLOCK_BUF_CTRL + KERNEL_clk_buf_ctrl(CLK_BUF_CONNSRC, enable); +#endif + return 0; +} + +static VOID consys_hw_reset_bit_set(MTK_WCN_BOOL enable) +{ +#ifdef CONFIG_OF /*use DT */ + if (enable) { + /*3.assert CONNSYS CPU SW reset 0x10007018 "[12]=1'b1 [31:24]=8'h88 (key)" */ + CONSYS_REG_WRITE((conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET), + CONSYS_REG_READ(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET) | + CONSYS_CPU_SW_RST_BIT | CONSYS_CPU_SW_RST_CTRL_KEY); + } else { + /*16.deassert CONNSYS CPU SW reset 0x10007018 "[12]=1'b0 [31:24] =8'h88 (key)" */ + CONSYS_REG_WRITE(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET, + (CONSYS_REG_READ(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET) & + ~CONSYS_CPU_SW_RST_BIT) | CONSYS_CPU_SW_RST_CTRL_KEY); + } +#else + if (enable) { + /*3.assert CONNSYS CPU SW reset 0x10007018 "[12]=1'b1 [31:24]=8'h88 (key)" */ + CONSYS_REG_WRITE(CONSYS_CPU_SW_RST_REG, + (CONSYS_REG_READ(CONSYS_CPU_SW_RST_REG) | CONSYS_CPU_SW_RST_BIT | + CONSYS_CPU_SW_RST_CTRL_KEY)); + } else { + /*16.deassert CONNSYS CPU SW reset 0x10007018 "[12]=1'b0 [31:24] =8'h88(key)" */ + CONSYS_REG_WRITE(CONSYS_CPU_SW_RST_REG, + (CONSYS_REG_READ(CONSYS_CPU_SW_RST_REG) & ~CONSYS_CPU_SW_RST_BIT) | + CONSYS_CPU_SW_RST_CTRL_KEY); + } +#endif +} + +static VOID consys_hw_spm_clk_gating_enable(VOID) +{ +#ifdef CONFIG_OF /*use DT */ + /*turn on SPM clock gating enable PWRON_CONFG_EN 0x10006000 32'h0b160001 */ + CONSYS_REG_WRITE((conn_reg.spm_base + CONSYS_PWRON_CONFG_EN_OFFSET), CONSYS_PWRON_CONFG_EN_VALUE); +#else + /*turn on SPM clock gating enable PWRON_CONFG_EN 0x10006000 32'h0b160001 */ + CONSYS_REG_WRITE(CONSYS_PWRON_CONFG_EN_REG, CONSYS_PWRON_CONFG_EN_VALUE); +#endif +} + +static INT32 consys_hw_power_ctrl(MTK_WCN_BOOL enable) +{ +#if CONSYS_PWR_ON_OFF_API_AVAILABLE + INT32 iRet = -1; +#endif + + if (enable) { +#if CONSYS_PWR_ON_OFF_API_AVAILABLE +#if defined(CONFIG_MTK_CLKMGR) + iRet = conn_power_on(); /* consult clkmgr owner. */ + if (iRet) + WMT_PLAT_PR_ERR("conn_power_on fail(%d)\n", iRet); + WMT_PLAT_PR_DBG("conn_power_on ok\n"); +#else + iRet = clk_prepare_enable(clk_scp_conn_main); + if (iRet) + WMT_PLAT_PR_ERR("clk_prepare_enable(clk_scp_conn_main) fail(%d)\n", iRet); + WMT_PLAT_PR_DBG("clk_prepare_enable(clk_scp_conn_main) ok\n"); +#endif /* defined(CONFIG_MTK_CLKMGR) */ + +#else + +#ifdef CONFIG_OF /*use DT */ + /*2.write conn_top1_pwr_on=1, power on conn_top1 0x10006280 [2] 1'b1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_SPM_PWR_ON_BIT); + /*3.read conn_top1_pwr_on_ack =1, power on ack ready 0x1000660C [1] */ + while (0 == (CONSYS_PWR_ON_ACK_BIT & CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_OFFSET))) + NULL; + /*5.write conn_top1_pwr_on_s=1, power on conn_top1 0x10006280 [3] 1'b1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_SPM_PWR_ON_S_BIT); + /*6.write conn_clk_dis=0, enable connsys clock 0x10006280 [4] 1'b0 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) & + ~CONSYS_CLK_CTRL_BIT); + /*7.wait 1us */ + udelay(1); + /*8.read conn_top1_pwr_on_ack_s =1, power on ack ready 0x10006610 [1] */ + while (0 == (CONSYS_PWR_CONN_ACK_S_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_S_OFFSET))) + NULL; + /*9.release connsys ISO, conn_top1_iso_en=0 0x10006280 [1] 1'b0 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) & + ~CONSYS_SPM_PWR_ISO_S_BIT); + /*10.release SW reset of connsys, conn_ap_sw_rst_b=1 0x10006280[0] 1'b1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_SPM_PWR_RST_BIT); + /*disable AXI BUS protect */ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_TOPAXI_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_TOPAXI_PROT_EN_OFFSET) & + ~CONSYS_PROT_MASK); + while (CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_TOPAXI_PROT_STA1_OFFSET) & CONSYS_PROT_MASK) + NULL; +#else /*use HADRCODE, maybe no use.. */ + /*2.write conn_top1_pwr_on=1, power on conn_top1 0x10006280 [2] 1'b1 */ + CONSYS_REG_WRITE(CONSYS_TOP1_PWR_CTRL_REG, + CONSYS_REG_READ(CONSYS_TOP1_PWR_CTRL_REG) | CONSYS_SPM_PWR_ON_BIT); + /*3.read conn_top1_pwr_on_ack =1, power on ack ready 0x1000660C [1] */ + while (0 == (CONSYS_PWR_ON_ACK_BIT & CONSYS_REG_READ(CONSYS_PWR_CONN_ACK_REG))) + NULL; + /*5.write conn_top1_pwr_on_s=1, power on conn_top1 0x10006280 [3] 1'b1 */ + CONSYS_REG_WRITE(CONSYS_TOP1_PWR_CTRL_REG, + CONSYS_REG_READ(CONSYS_TOP1_PWR_CTRL_REG) | CONSYS_SPM_PWR_ON_S_BIT); + /*6.write conn_clk_dis=0, enable connsys clock 0x10006280 [4] 1'b0 */ + CONSYS_REG_WRITE(CONSYS_TOP1_PWR_CTRL_REG, + CONSYS_REG_READ(CONSYS_TOP1_PWR_CTRL_REG) & ~CONSYS_CLK_CTRL_BIT); + /*7.wait 1us */ + udelay(1); + /*8.read conn_top1_pwr_on_ack_s =1, power on ack ready 0x10006610 [1] */ + while (0 == (CONSYS_PWR_CONN_ACK_S_BIT & CONSYS_REG_READ(CONSYS_PWR_CONN_ACK_S_REG))) + NULL; + /*9.release connsys ISO, conn_top1_iso_en=0 0x10006280 [1] 1'b0 */ + CONSYS_REG_WRITE(CONSYS_TOP1_PWR_CTRL_REG, + CONSYS_REG_READ(CONSYS_TOP1_PWR_CTRL_REG) & ~CONSYS_SPM_PWR_ISO_S_BIT); + /*10.release SW reset of connsys, conn_ap_sw_rst_b=1 0x10006280[0] 1'b1 */ + CONSYS_REG_WRITE(CONSYS_TOP1_PWR_CTRL_REG, + CONSYS_REG_READ(CONSYS_TOP1_PWR_CTRL_REG) | CONSYS_SPM_PWR_RST_BIT); + /*disable AXI BUS protect */ + CONSYS_REG_WRITE(CONSYS_TOPAXI_PROT_EN, CONSYS_REG_READ(CONSYS_TOPAXI_PROT_EN) & ~CONSYS_PROT_MASK); + while (CONSYS_REG_READ(CONSYS_TOPAXI_PROT_STA1) & CONSYS_PROT_MASK) + NULL; +#endif +#endif + } else { +#if CONSYS_PWR_ON_OFF_API_AVAILABLE +#if defined(CONFIG_MTK_CLKMGR) + /*power off connsys by API (MT6582, MT6572 are different) API: conn_power_off() */ + iRet = conn_power_off(); /* consult clkmgr owner */ + if (iRet) + WMT_PLAT_PR_ERR("conn_power_off fail(%d)\n", iRet); + WMT_PLAT_PR_DBG("conn_power_off ok\n"); +#else + clk_disable_unprepare(clk_scp_conn_main); + WMT_PLAT_PR_DBG("clk_disable_unprepare(clk_scp_conn_main) calling\n"); +#endif /* defined(CONFIG_MTK_CLKMGR) */ + +#else + +#ifdef CONFIG_OF /*use DT */ + { + INT32 count = 0; + + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_TOPAXI_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_TOPAXI_PROT_EN_OFFSET) | + CONSYS_PROT_MASK); + while ((CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_TOPAXI_PROT_STA1_OFFSET) & + CONSYS_PROT_MASK) != CONSYS_PROT_MASK) { + count++; + if (count > 1000) + break; + } + } + /*release connsys ISO, conn_top1_iso_en=1 0x10006280 [1] 1'b1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_SPM_PWR_ISO_S_BIT); + /*assert SW reset of connsys, conn_ap_sw_rst_b=0 0x10006280[0] 1'b0 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) & + ~CONSYS_SPM_PWR_RST_BIT); + /*write conn_clk_dis=1, disable connsys clock 0x10006280 [4] 1'b1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_CLK_CTRL_BIT); + /*wait 1us */ + udelay(1); + /*write conn_top1_pwr_on=0, power off conn_top1 0x10006280 [3:2] 2'b00 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) & + ~(CONSYS_SPM_PWR_ON_BIT | CONSYS_SPM_PWR_ON_S_BIT)); +#else + { + INT32 count = 0; + + CONSYS_REG_WRITE(CONSYS_TOPAXI_PROT_EN, + CONSYS_REG_READ(CONSYS_TOPAXI_PROT_EN) | CONSYS_PROT_MASK); + while ((CONSYS_REG_READ(CONSYS_TOPAXI_PROT_STA1) & CONSYS_PROT_MASK) != CONSYS_PROT_MASK) { + count++; + if (count > 1000) + break; + } + + } + /*release connsys ISO, conn_top1_iso_en=1 0x10006280 [1] 1'b1 */ + CONSYS_REG_WRITE(CONSYS_TOP1_PWR_CTRL_REG, + CONSYS_REG_READ(CONSYS_TOP1_PWR_CTRL_REG) | CONSYS_SPM_PWR_ISO_S_BIT); + /*assert SW reset of connsys, conn_ap_sw_rst_b=0 0x10006280[0] 1'b0 */ + CONSYS_REG_WRITE(CONSYS_TOP1_PWR_CTRL_REG, + CONSYS_REG_READ(CONSYS_TOP1_PWR_CTRL_REG) & ~CONSYS_SPM_PWR_RST_BIT); + /*write conn_clk_dis=1, disable connsys clock 0x10006280 [4] 1'b1 */ + CONSYS_REG_WRITE(CONSYS_TOP1_PWR_CTRL_REG, + CONSYS_REG_READ(CONSYS_TOP1_PWR_CTRL_REG) | CONSYS_CLK_CTRL_BIT); + /*wait 1us */ + udelay(1); + /*write conn_top1_pwr_on=0, power off conn_top1 0x10006280 [3:2] 2'b00 */ + CONSYS_REG_WRITE(CONSYS_TOP1_PWR_CTRL_REG, CONSYS_REG_READ(CONSYS_TOP1_PWR_CTRL_REG) & + ~(CONSYS_SPM_PWR_ON_BIT | CONSYS_SPM_PWR_ON_S_BIT)); +#endif /* CONFIG_OF */ +#endif /* CONSYS_PWR_ON_OFF_API_AVAILABLE */ + } + +#if CONSYS_PWR_ON_OFF_API_AVAILABLE + return iRet; +#else + return 0; +#endif +} + +static INT32 consys_ahb_clock_ctrl(MTK_WCN_BOOL enable) +{ +#if CONSYS_AHB_CLK_MAGEMENT + if (enable) { +#if defined(CONFIG_MTK_CLKMGR) + enable_clock(MT_CG_INFRA_CONNMCU_BUS, "WCN_MOD"); + WMT_PLAT_PR_DBG("enable MT_CG_INFRA_CONNMCU_BUS CLK\n"); +#else + INT32 iRet = -1; + + iRet = clk_prepare_enable(clk_infra_conn_main); + if (iRet) + WMT_PLAT_PR_ERR("clk_prepare_enable(clk_infra_conn_main) fail(%d)\n", iRet); + WMT_PLAT_PR_DBG("[CCF]enable clk_infra_conn_main\n"); +#endif /* defined(CONFIG_MTK_CLKMGR) */ + } else { +#if defined(CONFIG_MTK_CLKMGR) + disable_clock(MT_CG_INFRA_CONNMCU_BUS, "WMT_MOD"); +#else + clk_disable_unprepare(clk_infra_conn_main); + WMT_PLAT_PR_DBG("[CCF] clk_disable_unprepare(clk_infra_conn_main) calling\n"); +#endif /* defined(CONFIG_MTK_CLKMGR) */ + } +#endif + return 0; +} + +static INT32 polling_consys_chipid(VOID) +{ + UINT32 retry = 10; + UINT32 consysHwChipId = 0; + +#ifdef CONFIG_OF /*use DT */ + /*12.poll CONNSYS CHIP ID until chipid is returned 0x18070008 */ + while (retry-- > 0) { + consysHwChipId = CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_CHIP_ID_OFFSET); + if (consysHwChipId == 0x6580) { + WMT_PLAT_PR_INFO("retry(%d)consys chipId(0x%08x)\n", retry, consysHwChipId); + break; + } + msleep(20); + } + + if ((0 == retry) || (0 == consysHwChipId)) { + WMT_PLAT_PR_ERR("Maybe has a consys power on issue,(0x%08x)\n", consysHwChipId); + WMT_PLAT_PR_INFO("reg dump:CONSYS_CPU_SW_RST_REG(0x%x)\n", + CONSYS_REG_READ(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET)); + WMT_PLAT_PR_INFO("reg dump:CONSYS_PWR_CONN_ACK_REG(0x%x)\n", + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_OFFSET)); + WMT_PLAT_PR_INFO("reg dump:CONSYS_PWR_CONN_ACK_S_REG(0x%x)\n", + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_S_OFFSET)); + WMT_PLAT_PR_INFO("reg dump:CONSYS_TOP1_PWR_CTRL_REG(0x%x)\n", + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET)); + } +#else + /*12.poll CONNSYS CHIP ID until 6752 is returned 0x18070008 32'h6752 */ + while (retry-- > 0) { + WMT_PLAT_PR_DBG("CONSYS_CHIP_ID_REG(0x%08x)", CONSYS_REG_READ(CONSYS_CHIP_ID_REG)); + consysHwChipId = CONSYS_REG_READ(CONSYS_CHIP_ID_REG); + if ((consysHwChipId == 0x0321) || (consysHwChipId == 0x0335) || (consysHwChipId == 0x0337)) { + WMT_PLAT_PR_INFO("retry(%d)consys chipId(0x%08x)\n", retry, consysHwChipId); + break; + } + msleep(20); + } + + if ((0 == retry) || (0 == consysHwChipId)) { + WMT_PLAT_PR_ERR("Maybe has a consys power on issue,(0x%08x)\n", consysHwChipId); + WMT_PLAT_PR_INFO("reg dump:CONSYS_CPU_SW_RST_REG(0x%x)\n", + CONSYS_REG_READ(CONSYS_CPU_SW_RST_REG)); + WMT_PLAT_PR_INFO("reg dump:CONSYS_PWR_CONN_ACK_REG(0x%x)\n", + CONSYS_REG_READ(CONSYS_PWR_CONN_ACK_REG)); + WMT_PLAT_PR_INFO("reg dump:CONSYS_PWR_CONN_ACK_S_REG(0x%x)\n", + CONSYS_REG_READ(CONSYS_PWR_CONN_ACK_S_REG)); + WMT_PLAT_PR_INFO("reg dump:CONSYS_TOP1_PWR_CTRL_REG(0x%x)\n", + CONSYS_REG_READ(CONSYS_TOP1_PWR_CTRL_REG)); + } +#endif + return 0; +} + +static VOID consys_acr_reg_setting(VOID) +{ + /* + *14.write 1 to conn_mcu_confg ACR[1] if real speed MBIST + *(default write "1") ACR 0x18070110[18] 1'b1 + *if this bit is 0, HW will do memory auto test under low CPU frequence (26M Hz) + *if this bit is 0, HW will do memory auto test under high CPU frequence(138M Hz) + *inclulding low CPU frequence + */ +#ifdef CONFIG_OF /*use DT */ + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_MCU_CFG_ACR_OFFSET, + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_MCU_CFG_ACR_OFFSET) | + CONSYS_MCU_CFG_ACR_MBIST_BIT); +#else + CONSYS_REG_WRITE(CONSYS_MCU_CFG_ACR_REG, + CONSYS_REG_READ(CONSYS_MCU_CFG_ACR_REG) | CONSYS_MCU_CFG_ACR_MBIST_BIT); +#endif +} + +static VOID consys_afe_reg_setting(VOID) +{ +#if 0 + /*15.default no need,update ANA_WBG(AFE) CR if needed, CONSYS_AFE_REG */ + CONSYS_REG_WRITE(CONSYS_AFE_REG_DIG_RCK_01, CONSYS_AFE_REG_DIG_RCK_01_VALUE); + CONSYS_REG_WRITE(CONSYS_AFE_REG_WBG_PLL_02, CONSYS_AFE_REG_WBG_PLL_02_VALUE); + CONSYS_REG_WRITE(CONSYS_AFE_REG_WBG_WB_TX_01, CONSYS_AFE_REG_WBG_WB_TX_01_VALUE); +#endif +} + +static INT32 consys_hw_vcn18_ctrl(MTK_WCN_BOOL enable) +{ +#if CONSYS_PMIC_CTRL_ENABLE + if (enable) { + /*need PMIC driver provide new API protocol */ + /*1.AP power on VCN_1V8 LDO (with PMIC_WRAP API) VCN_1V8 */ +#if MT6580_WORKAROUND + KERNEL_pmic_set_register_value(MT6350_VCN_1V8_CON1, 0); +#else +#if !defined(CONFIG_MTK_PMIC_LEGACY) + KERNEL_pmic_set_register_value(PMIC_VCN_1V8_ON_CTRL, 0); + if (reg_VCN18) { + if (regulator_enable(reg_VCN18)) + WMT_PLAT_PR_INFO("wmt_dev enable VCN_1V8 fail!\n"); + else + WMT_PLAT_PR_DBG("wmt_dev enable VCN_1V8\n"); + } +#endif +#endif + } else { + /*AP power off MT6323 VCN_1V8 LDO (with PMIC_WRAP API) RG_VCN18_ON_CTRL "0x0510[1] + *"1'b0 RG_VCN18_EN" 0x0512[14]" 1'b0" + */ +#if MT6580_WORKAROUND + KERNEL_pmic_set_register_value(MT6350_VCN_1V8_CON1, 1); +#else +#if !defined(CONFIG_MTK_PMIC_LEGACY) + KERNEL_pmic_set_register_value(PMIC_VCN_1V8_ON_CTRL, 0); + if (reg_VCN18) { + regulator_disable(reg_VCN18); + WMT_PLAT_PR_INFO("wmt_dev disable VCN_1V8\n"); + } +#endif +#endif + } +#endif + return 0; +} + +static VOID consys_vcn28_hw_mode_ctrl(UINT32 enable) +{ +#if CONSYS_PMIC_CTRL_ENABLE + if (enable) { + KERNEL_pmic_set_register_value(PMIC_VCN28_ON_CTRL, 1); + /*2.2 turn on VCN28 LDO (with PMIC_WRAP API) DA_XOBUF_SEL 0x1000513C[7:6]" " 2'b11"*/ + CONSYS_REG_WRITE((conn_reg.da_xobuf_base + CONSYS_DA_XOBUF_OFFSET), + CONSYS_REG_READ(conn_reg.da_xobuf_base + CONSYS_DA_XOBUF_OFFSET) | + ((0x1 << 7) | (0x1 << 6))); + WMT_PLAT_PR_INFO("NOT co_clock mode reg dump:XO BUFFER(0x%08x)\n", + CONSYS_REG_READ(conn_reg.da_xobuf_base + CONSYS_DA_XOBUF_OFFSET)); + } else { + KERNEL_pmic_set_register_value(PMIC_VCN28_ON_CTRL, 0); + /*2.set RF XO BUF source from CellularRF DA_XOBUF_SEL 0x1000513C[7:6] 2'b10*/ + CONSYS_REG_WRITE((conn_reg.da_xobuf_base + CONSYS_DA_XOBUF_OFFSET), + CONSYS_REG_READ(conn_reg.da_xobuf_base + CONSYS_DA_XOBUF_OFFSET) & + ~(0x1 << 6)); + CONSYS_REG_WRITE((conn_reg.da_xobuf_base + CONSYS_DA_XOBUF_OFFSET), + CONSYS_REG_READ(conn_reg.da_xobuf_base + CONSYS_DA_XOBUF_OFFSET) | + (0x1 << 7)); + WMT_PLAT_PR_INFO("co_clock mode reg dump:XO BUFFER(0x%08x)\n", + CONSYS_REG_READ(conn_reg.da_xobuf_base + CONSYS_DA_XOBUF_OFFSET)); + } +#endif +} + +static INT32 consys_hw_vcn28_ctrl(UINT32 enable) +{ +#if CONSYS_PMIC_CTRL_ENABLE + if (enable) { +#if defined(CONFIG_MTK_PMIC_LEGACY) + hwPowerOn(MT6328_POWER_LDO_VCN28, VOL_2800, "wcn_drv"); +#else + if (reg_VCN28) { + regulator_set_voltage(reg_VCN28, VOL_2800, VOL_2800); + if (regulator_enable(reg_VCN28)) + WMT_PLAT_PR_ERR("enable VCN_2V8 fail!\n"); + else + WMT_PLAT_PR_DBG("enable VCN_2V8 ok\n"); + } +#endif + } else { +#if defined(CONFIG_MTK_LEGACY) + hwPowerDown(MT6328_POWER_LDO_VCN28, "wcn_drv"); +#else + if (reg_VCN28) + regulator_disable(reg_VCN28); +#endif + } +#endif + return 0; +} + +static INT32 consys_hw_bt_vcn33_ctrl(UINT32 enable) +{ +#if CONSYS_BT_WIFI_SHARE_V33 + /* spin_lock_irqsave(&gBtWifiV33.lock,gBtWifiV33.flags); */ + if (enable) { + if (1 == gBtWifiV33.counter) { + gBtWifiV33.counter++; + WMT_PLAT_PR_DBG("V33 has been enabled,counter(%d)\n", gBtWifiV33.counter); + } else if (2 == gBtWifiV33.counter) { + WMT_PLAT_PR_DBG("V33 has been enabled,counter(%d)\n", gBtWifiV33.counter); + } else { +#if CONSYS_PMIC_CTRL_ENABLE + /*do BT PMIC on,depenency PMIC API ready */ + /*switch BT PALDO control from SW mode to HW mode:0x416[5]-->0x1 */ + /* VOL_DEFAULT, VOL_3300, VOL_3400, VOL_3500, VOL_3600 */ + KERNEL_pmic_set_register_value(PMIC_VCN33_LP_SET, 0); +#endif + WMT_PLAT_PR_INFO("WMT do BT/WIFI v3.3 on\n"); + gBtWifiV33.counter++; + } + + } else { + if (1 == gBtWifiV33.counter) { + /*do BT PMIC off */ + /*switch BT PALDO control from HW mode to SW mode:0x416[5]-->0x0 */ +#if CONSYS_PMIC_CTRL_ENABLE + KERNEL_pmic_set_register_value(PMIC_VCN33_LP_SET, 1); +#endif + WMT_PLAT_PR_INFO("WMT do BT/WIFI v3.3 off\n"); + gBtWifiV33.counter--; + } else if (2 == gBtWifiV33.counter) { + gBtWifiV33.counter--; + WMT_PLAT_PR_DBG("V33 no need disabled,counter(%d)\n", gBtWifiV33.counter); + } else { + WMT_PLAT_PR_DBG("V33 has been disabled,counter(%d)\n", gBtWifiV33.counter); + } + + } + /* spin_unlock_irqrestore(&gBtWifiV33.lock,gBtWifiV33.flags); */ +#else + if (enable) { + /*do BT PMIC on,depenency PMIC API ready */ + /*switch BT PALDO control from SW mode to HW mode:0x416[5]-->0x1 */ +#if CONSYS_PMIC_CTRL_ENABLE + /* VOL_DEFAULT, VOL_3300, VOL_3400, VOL_3500, VOL_3600 */ + if (reg_VCN33_BT) { + regulator_set_voltage(reg_VCN33_BT, VOL_3300, VOL_3300); + if (regulator_enable(reg_VCN33_BT)) + WMT_PLAT_PR_ERR("WMT do BT PMIC on fail!\n"); + } +#endif + WMT_PLAT_PR_INFO("WMT do BT PMIC on\n"); + } else { + /*do BT PMIC off */ + /*switch BT PALDO control from HW mode to SW mode:0x416[5]-->0x0 */ +#if CONSYS_PMIC_CTRL_ENABLE + if (reg_VCN33_BT) + regulator_disable(reg_VCN33_BT); +#endif + WMT_PLAT_PR_INFO("WMT do BT PMIC off\n"); + } +#endif + return 0; +} + +static INT32 consys_hw_wifi_vcn33_ctrl(UINT32 enable) +{ +#if CONSYS_BT_WIFI_SHARE_V33 + consys_hw_bt_vcn33_ctrl(enable); +#else + if (enable) { + /*do WIFI PMIC on,depenency PMIC API ready */ + /*switch WIFI PALDO control from SW mode to HW mode:0x418[14]-->0x1 */ +#if CONSYS_PMIC_CTRL_ENABLE + + if (reg_VCN33_WIFI) { + regulator_set_voltage(reg_VCN33_WIFI, VOL_3300, VOL_3300); + if (regulator_enable(reg_VCN33_WIFI)) + WMT_PLAT_PR_ERR("WMT do WIFI PMIC on fail!\n"); + } +#endif + WMT_PLAT_PR_INFO("WMT do WIFI PMIC on\n"); + } else { + /*do WIFI PMIC off */ + /*switch WIFI PALDO control from HW mode to SW mode:0x418[14]-->0x0 */ +#if CONSYS_PMIC_CTRL_ENABLE + + if (reg_VCN33_WIFI) + regulator_disable(reg_VCN33_WIFI); +#endif + WMT_PLAT_PR_INFO("WMT do WIFI PMIC off\n"); + } +#endif + return 0; +} + +#if CONSYS_WMT_REG_SUSPEND_CB_ENABLE +UINT32 mtk_wcn_consys_hw_osc_en_ctrl(UINT32 en) +{ + if (en) { + WMT_PLAT_PR_INFO("enable consys sleep mode(turn off 26M)\n"); + CONSYS_REG_WRITE(CONSYS_AP2CONN_OSC_EN_REG, CONSYS_REG_READ(CONSYS_AP2CONN_OSC_EN_REG) & + ~CONSYS_AP2CONN_OSC_EN_BIT); + } else { + WMT_PLAT_PR_INFO("disable consys sleep mode\n"); + CONSYS_REG_WRITE(CONSYS_AP2CONN_OSC_EN_REG, CONSYS_REG_READ(CONSYS_AP2CONN_OSC_EN_REG) | + CONSYS_AP2CONN_OSC_EN_BIT); + } + + WMT_PLAT_PR_INFO("dump CONSYS_AP2CONN_OSC_EN_REG(0x%x)\n", CONSYS_REG_READ(CONSYS_AP2CONN_OSC_EN_REG)); + + return 0; +} +#endif + +static INT32 consys_emi_mpu_set_region_protection(VOID) +{ +#if CONSYS_EMI_MPU_SETTING + /*set MPU for EMI share Memory */ + WMT_PLAT_PR_INFO("setting MPU for EMI share memory\n"); + emi_mpu_set_region_protection(gConEmiPhyBase + SZ_1M/2, + gConEmiPhyBase + gConEmiSize - 1, + 6, + SET_ACCESS_PERMISSON(FORBIDDEN, NO_PROTECTION, FORBIDDEN, NO_PROTECTION)); +#endif + return 0; +} + +static UINT32 consys_emi_set_remapping_reg(VOID) +{ +#ifdef CONFIG_OF /*use DT */ + UINT32 addrPhy = 0; + + /*consys to ap emi remapping register:10000320, cal remapping address */ + addrPhy = (gConEmiPhyBase & 0xFFF00000) >> 20; + + /*enable consys to ap emi remapping bit12 */ + addrPhy = addrPhy | 0x1000; + + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET) | addrPhy); + + WMT_PLAT_PR_INFO("CONSYS_EMI_MAPPING dump in restore cb(0x%08x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET)); +#endif + return 0; +} + +static INT32 bt_wifi_share_v33_spin_lock_init(VOID) +{ +#if CONSYS_BT_WIFI_SHARE_V33 + gBtWifiV33.counter = 0; + spin_lock_init(&gBtWifiV33.lock); +#endif + return 0; +} + +static INT32 consys_clk_get_from_dts(struct platform_device *pdev) +{ +#ifdef CONFIG_OF /*use DT */ +#if !defined(CONFIG_MTK_CLKMGR) + clk_scp_conn_main = devm_clk_get(&pdev->dev, "conn"); + if (IS_ERR(clk_scp_conn_main)) { + WMT_PLAT_PR_ERR("[CCF]cannot get clk_scp_conn_main clock.\n"); + return PTR_ERR(clk_scp_conn_main); + } + WMT_PLAT_PR_DBG("[CCF]clk_scp_conn_main=%p\n", clk_scp_conn_main); + + clk_infra_conn_main = devm_clk_get(&pdev->dev, "bus"); + if (IS_ERR(clk_infra_conn_main)) { + WMT_PLAT_PR_ERR("[CCF]cannot get clk_infra_conn_main clock.\n"); + return PTR_ERR(clk_infra_conn_main); + } + WMT_PLAT_PR_DBG("[CCF]clk_infra_conn_main=%p\n", clk_infra_conn_main); +#endif /* !defined(CONFIG_MTK_CLKMGR) */ +#endif + return 0; +} + +static INT32 consys_pmic_get_from_dts(struct platform_device *pdev) +{ +#ifdef CONFIG_OF /*use DT */ +#if CONSYS_PMIC_CTRL_ENABLE +#if !defined(CONFIG_MTK_PMIC_LEGACY) + reg_VCN18 = regulator_get(&pdev->dev, "vcn18"); + if (!reg_VCN18) + WMT_PLAT_PR_ERR("Regulator_get VCN_1V8 fail\n"); + reg_VCN28 = regulator_get(&pdev->dev, "vcn28"); + if (!reg_VCN28) + WMT_PLAT_PR_ERR("Regulator_get VCN_2V8 fail\n"); + reg_VCN33_BT = regulator_get(&pdev->dev, "vcn33_bt"); + if (!reg_VCN33_BT) + WMT_PLAT_PR_ERR("Regulator_get VCN33_BT fail\n"); + reg_VCN33_WIFI = regulator_get(&pdev->dev, "vcn33_wifi"); + if (!reg_VCN33_WIFI) + WMT_PLAT_PR_ERR("Regulator_get VCN33_WIFI fail\n"); +#endif +#endif +#endif + return 0; +} + +static INT32 consys_read_irq_info_from_dts(struct platform_device *pdev, INT32 *irq_num, UINT32 *irq_flag) +{ +#ifdef CONFIG_OF /*use DT */ + struct device_node *node; + UINT32 irq_info[3] = { 0, 0, 0 }; + + INT32 iret = -1; + + node = pdev->dev.of_node; + if (node) { + *irq_num = irq_of_parse_and_map(node, 0); + /* get the interrupt line behaviour */ + if (of_property_read_u32_array(node, "interrupts", irq_info, ARRAY_SIZE(irq_info))) { + WMT_PLAT_PR_ERR("get irq flags from DTS fail!!\n"); + return iret; + } + *irq_flag = irq_info[2]; + WMT_PLAT_PR_INFO("get irq id(%d) and irq trigger flag(%d) from DT\n", *irq_num, + *irq_flag); + } else { + WMT_PLAT_PR_ERR("[%s] can't find CONSYS compatible node\n", __func__); + return iret; + } +#endif + return 0; +} + +static INT32 consys_read_reg_from_dts(struct platform_device *pdev) +{ +#ifdef CONFIG_OF /*use DT */ + INT32 iRet = -1; + struct device_node *node = NULL; + + node = pdev->dev.of_node; + if (node) { + /* registers base address */ + conn_reg.mcu_base = (SIZE_T) of_iomap(node, 0); + WMT_PLAT_PR_DBG("Get mcu register base(0x%zx)\n", conn_reg.mcu_base); + conn_reg.ap_rgu_base = (SIZE_T) of_iomap(node, 1); + WMT_PLAT_PR_DBG("Get ap_rgu register base(0x%zx)\n", conn_reg.ap_rgu_base); + conn_reg.topckgen_base = (SIZE_T) of_iomap(node, 2); + WMT_PLAT_PR_DBG("Get topckgen register base(0x%zx)\n", conn_reg.topckgen_base); + conn_reg.spm_base = (SIZE_T) of_iomap(node, 3); + WMT_PLAT_PR_DBG("Get spm register base(0x%zx)\n", conn_reg.spm_base); + conn_reg.da_xobuf_base = (SIZE_T)of_iomap(node, 4); + WMT_PLAT_PR_INFO("Get xo_buf register base(0x%zx)\n", conn_reg.da_xobuf_base); + } else { + WMT_PLAT_PR_ERR("[%s] can't find CONSYS compatible node\n", __func__); + return iRet; + } +#endif + return 0; +} + +static VOID force_trigger_assert_debug_pin(VOID) +{ +#ifdef CONFIG_OF /*use DT */ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AP2CONN_OSC_EN_OFFSET) & ~CONSYS_AP2CONN_WAKEUP_BIT); + WMT_PLAT_PR_INFO("enable:dump CONSYS_AP2CONN_OSC_EN_REG(0x%x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET)); + usleep_range(64, 96); + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AP2CONN_OSC_EN_OFFSET) | CONSYS_AP2CONN_WAKEUP_BIT); + WMT_PLAT_PR_INFO("disable:dump CONSYS_AP2CONN_OSC_EN_REG(0x%x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET)); +#endif +} + +static UINT32 consys_read_cpupcr(VOID) +{ +#ifdef CONFIG_OF /*use DT */ + if (conn_reg.mcu_base == 0) + return 0; + + if (mtk_consys_check_reg_readable_by_addr(conn_reg.mcu_base + CONSYS_CPUPCR_OFFSET) == 0) + return 0; + + return CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_CPUPCR_OFFSET); +#endif +} + +static UINT32 consys_soc_chipid_get(VOID) +{ + return PLATFORM_SOC_CHIP; +} + +static P_CONSYS_EMI_ADDR_INFO consys_soc_get_emi_phy_add(VOID) +{ + return &mtk_wcn_emi_addr_info; +} + +P_WMT_CONSYS_IC_OPS mtk_wcn_get_consys_ic_ops(VOID) +{ + return &consys_ic_ops; +} + +static INT32 consys_emi_coredump_remapping(UINT8 __iomem **addr, UINT32 enable) +{ + if (enable) { + *addr = ioremap_nocache(gConEmiPhyBase + CONSYS_EMI_COREDUMP_OFFSET, CONSYS_EMI_MEM_SIZE); + if (*addr) { + WMT_PLAT_PR_INFO("COREDUMP EMI mapping OK virtual(0x%p) physical(0x%x)\n", + *addr, (UINT32) gConEmiPhyBase + CONSYS_EMI_COREDUMP_OFFSET); + memset_io(*addr, 0, CONSYS_EMI_MEM_SIZE); + } else { + WMT_PLAT_PR_ERR("EMI mapping fail\n"); + return -1; + } + } else { + if (*addr) { + iounmap(*addr); + *addr = NULL; + } + } + return 0; +} + +static INT32 consys_reset_emi_coredump(UINT8 __iomem *addr) +{ + if (!addr) { + WMT_PLAT_PR_ERR("get virtual address fail\n"); + return -1; + } + WMT_PLAT_PR_INFO("Reset EMI(0xF0080000 ~ 0xF0080400) and (0xF0088400 ~ 0xF0090400)\n"); + /* reset 0xF0080000 ~ 0xF0080400 (1K) */ + memset_io(addr, 0, 0x400); + /* reset 0xF0088400 ~ 0xF0090400 (32K) */ + memset_io(addr + CONSYS_EMI_PAGED_DUMP_OFFSET, 0, 0x8000); + return 0; +} + +static UINT64 consys_get_options(VOID) +{ + UINT64 options = OPT_POWER_ON_DLM_TABLE | + OPT_SET_MCUCLK_TABLE_1_2 | + OPT_WIFI_LTE_COEX | + OPT_INIT_COEX_AFTER_RF_CALIBRATION | + OPT_SET_OSC_TYPE | + OPT_SET_COREDUMP_LEVEL | + OPT_GPS_SYNC | + OPT_WIFI_LTE_COEX_TABLE_1 | + OPT_NORMAL_PATCH_DWN_0; + return options; +} + diff --git a/drivers/misc/mediatek/connectivity/common/common_main/platform/mt6735.c b/drivers/misc/mediatek/connectivity/common/common_main/platform/mt6735.c new file mode 100644 index 0000000000000000000000000000000000000000..6d095e62c9223e4552d3a965bf638178316098fd --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/platform/mt6735.c @@ -0,0 +1,1132 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +#ifdef DFT_TAG +#undef DFT_TAG +#endif +#define DFT_TAG "[WMT-CONSYS-HW]" + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include + +#if defined(CONFIG_MTK_CLKMGR) +#include +#else +#include +#endif /* defined(CONFIG_MTK_CLKMGR) */ +#include +#include +#include "osal_typedef.h" +#include "mt6735.h" +#include "mtk_wcn_consys_hw.h" +#include + +#if CONSYS_EMI_MPU_SETTING +#include +#endif + +#if CONSYS_PMIC_CTRL_ENABLE +#include +#include +#endif + +#ifdef CONFIG_MTK_HIBERNATION +#include +#endif + +#include + +#if CONSYS_CLOCK_BUF_CTRL +#include +#endif + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +static INT32 consys_clock_buffer_ctrl(MTK_WCN_BOOL enable); +static VOID consys_hw_reset_bit_set(MTK_WCN_BOOL enable); +static VOID consys_hw_spm_clk_gating_enable(VOID); +static INT32 consys_hw_power_ctrl(MTK_WCN_BOOL enable); +static INT32 consys_ahb_clock_ctrl(MTK_WCN_BOOL enable); +static INT32 polling_consys_chipid(VOID); +static VOID consys_acr_reg_setting(VOID); +static VOID consys_afe_reg_setting(VOID); +static INT32 consys_hw_vcn18_ctrl(MTK_WCN_BOOL enable); +static VOID consys_vcn28_hw_mode_ctrl(UINT32 enable); +static INT32 consys_hw_vcn28_ctrl(UINT32 enable); +static INT32 consys_hw_wifi_vcn33_ctrl(UINT32 enable); +static INT32 consys_hw_bt_vcn33_ctrl(UINT32 enable); +static UINT32 consys_soc_chipid_get(VOID); +static INT32 consys_emi_mpu_set_region_protection(VOID); +static UINT32 consys_emi_set_remapping_reg(VOID); +static INT32 bt_wifi_share_v33_spin_lock_init(VOID); +static INT32 consys_clk_get_from_dts(struct platform_device *pdev); +static INT32 consys_pmic_get_from_dts(struct platform_device *pdev); +static INT32 consys_read_irq_info_from_dts(struct platform_device *pdev, INT32 *irq_num, UINT32 *irq_flag); +static INT32 consys_read_reg_from_dts(struct platform_device *pdev); +static UINT32 consys_read_cpupcr(VOID); +static VOID force_trigger_assert_debug_pin(VOID); +static P_CONSYS_EMI_ADDR_INFO consys_soc_get_emi_phy_add(VOID); +static INT32 consys_emi_coredump_remapping(UINT8 __iomem **addr, UINT32 enable); +static INT32 consys_reset_emi_coredump(UINT8 __iomem *addr); +static UINT64 consys_get_options(VOID); + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ +#if CONSYS_BT_WIFI_SHARE_V33 +struct bt_wifi_v33_status gBtWifiV33; +#endif + +/* CCF part */ +#if !defined(CONFIG_MTK_CLKMGR) +struct clk *clk_scp_conn_main; /*ctrl conn_power_on/off */ +struct clk *clk_infra_conn_main; /*ctrl infra_connmcu_bus clk */ +#endif /* !defined(CONFIG_MTK_CLKMGR) */ + + +/* PMIC part */ +#if CONSYS_PMIC_CTRL_ENABLE +#if !defined(CONFIG_MTK_PMIC_LEGACY) +struct regulator *reg_VCN18; +struct regulator *reg_VCN28; +struct regulator *reg_VCN33_BT; +struct regulator *reg_VCN33_WIFI; +#endif +#endif + +EMI_CTRL_STATE_OFFSET mtk_wcn_emi_state_off = { + .emi_apmem_ctrl_state = EXP_APMEM_CTRL_STATE, + .emi_apmem_ctrl_host_sync_state = EXP_APMEM_CTRL_HOST_SYNC_STATE, + .emi_apmem_ctrl_host_sync_num = EXP_APMEM_CTRL_HOST_SYNC_NUM, + .emi_apmem_ctrl_chip_sync_state = EXP_APMEM_CTRL_CHIP_SYNC_STATE, + .emi_apmem_ctrl_chip_sync_num = EXP_APMEM_CTRL_CHIP_SYNC_NUM, + .emi_apmem_ctrl_chip_sync_addr = EXP_APMEM_CTRL_CHIP_SYNC_ADDR, + .emi_apmem_ctrl_chip_sync_len = EXP_APMEM_CTRL_CHIP_SYNC_LEN, + .emi_apmem_ctrl_chip_print_buff_start = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_START, + .emi_apmem_ctrl_chip_print_buff_len = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_LEN, + .emi_apmem_ctrl_chip_print_buff_idx = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_IDX, + .emi_apmem_ctrl_chip_int_status = EXP_APMEM_CTRL_CHIP_INT_STATUS, + .emi_apmem_ctrl_chip_paded_dump_end = EXP_APMEM_CTRL_CHIP_PAGED_DUMP_END, + .emi_apmem_ctrl_host_outband_assert_w1 = EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1, + .emi_apmem_ctrl_chip_page_dump_num = EXP_APMEM_CTRL_CHIP_PAGE_DUMP_NUM, + .emi_apmem_ctrl_assert_flag = EXP_APMEM_CTRL_ASSERT_FLAG, +}; + +CONSYS_EMI_ADDR_INFO mtk_wcn_emi_addr_info = { + .emi_phy_addr = CONSYS_EMI_FW_PHY_BASE, + .paged_trace_off = CONSYS_EMI_PAGED_TRACE_OFFSET, + .paged_dump_off = CONSYS_EMI_PAGED_DUMP_OFFSET, + .full_dump_off = CONSYS_EMI_FULL_DUMP_OFFSET, + .p_ecso = &mtk_wcn_emi_state_off, + .emi_core_dump_offset = CONSYS_EMI_COREDUMP_OFFSET, +}; + +WMT_CONSYS_IC_OPS consys_ic_ops = { + .consys_ic_clock_buffer_ctrl = consys_clock_buffer_ctrl, + .consys_ic_hw_reset_bit_set = consys_hw_reset_bit_set, + .consys_ic_hw_spm_clk_gating_enable = consys_hw_spm_clk_gating_enable, + .consys_ic_hw_power_ctrl = consys_hw_power_ctrl, + .consys_ic_ahb_clock_ctrl = consys_ahb_clock_ctrl, + .polling_consys_ic_chipid = polling_consys_chipid, + .consys_ic_acr_reg_setting = consys_acr_reg_setting, + .consys_ic_afe_reg_setting = consys_afe_reg_setting, + .consys_ic_hw_vcn18_ctrl = consys_hw_vcn18_ctrl, + .consys_ic_vcn28_hw_mode_ctrl = consys_vcn28_hw_mode_ctrl, + .consys_ic_hw_vcn28_ctrl = consys_hw_vcn28_ctrl, + .consys_ic_hw_wifi_vcn33_ctrl = consys_hw_wifi_vcn33_ctrl, + .consys_ic_hw_bt_vcn33_ctrl = consys_hw_bt_vcn33_ctrl, + .consys_ic_soc_chipid_get = consys_soc_chipid_get, + .consys_ic_emi_mpu_set_region_protection = consys_emi_mpu_set_region_protection, + .consys_ic_emi_set_remapping_reg = consys_emi_set_remapping_reg, + .ic_bt_wifi_share_v33_spin_lock_init = bt_wifi_share_v33_spin_lock_init, + .consys_ic_clk_get_from_dts = consys_clk_get_from_dts, + .consys_ic_pmic_get_from_dts = consys_pmic_get_from_dts, + .consys_ic_read_irq_info_from_dts = consys_read_irq_info_from_dts, + .consys_ic_read_reg_from_dts = consys_read_reg_from_dts, + .consys_ic_read_cpupcr = consys_read_cpupcr, + .ic_force_trigger_assert_debug_pin = force_trigger_assert_debug_pin, + .consys_ic_soc_get_emi_phy_add = consys_soc_get_emi_phy_add, + .consys_ic_emi_coredump_remapping = consys_emi_coredump_remapping, + .consys_ic_reset_emi_coredump = consys_reset_emi_coredump, + .consys_ic_get_options = consys_get_options, +}; + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +UINT32 gJtagCtrl; +#if CONSYS_ENALBE_SET_JTAG +#define JTAG_ADDR1_BASE 0x10002000 +PINT8 jtag_addr1 = (PINT8)JTAG_ADDR1_BASE; +#define JTAG1_REG_WRITE(addr, value) \ + writel(value, ((PUINT32)(jtag_addr1+(addr-JTAG_ADDR1_BASE)))) +#define JTAG1_REG_READ(addr) \ + readl(((PUINT32)(jtag_addr1+(addr-JTAG_ADDR1_BASE)))) +#endif + +INT32 mtk_wcn_consys_jtag_set_for_mcu(VOID) +{ +#if CONSYS_ENALBE_SET_JTAG + + if (gJtagCtrl) { +#if 0 + INT32 iRet = -1; + + WMT_PLAT_PR_INFO("WCN jtag_set_for_mcu start...\n"); + jtag_addr1 = ioremap(JTAG_ADDR1_BASE, 0x5000); + if (jtag_addr1 == 0) { + WMT_PLAT_PR_ERR("remap jtag_addr1 fail!\n"); + return iRet; + } + WMT_PLAT_PR_INFO("jtag_addr1 = 0x%p\n", jtag_addr1); + + JTAG1_REG_WRITE(0x100053c4, 0x11111100); + JTAG1_REG_WRITE(0x100053d4, 0x00111111); + + /*Enable IES of all pins */ + JTAG1_REG_WRITE(0x10002014, 0x00000003); + JTAG1_REG_WRITE(0x10005334, 0x55000000); + JTAG1_REG_WRITE(0x10005344, 0x00555555); + JTAG1_REG_WRITE(0x10005008, 0xc0000000); + JTAG1_REG_WRITE(0x10005018, 0x0000000d); + JTAG1_REG_WRITE(0x10005014, 0x00000032); + JTAG1_REG_WRITE(0x100020a4, 0x000000ff); + JTAG1_REG_WRITE(0x100020d4, 0x000000b4); + JTAG1_REG_WRITE(0x100020d8, 0x0000004b); + + WMT_PLAT_PR_INFO("WCN jtag set for mcu start...\n"); + kal_int32 iRet = 0; + kal_uint32 tmp = 0; + kal_int32 addr = 0; + kal_int32 remap_addr1 = 0; + kal_int32 remap_addr2 = 0; + + remap_addr1 = ioremap(JTAG_ADDR1_BASE, 0x1000); + if (remap_addr1 == 0) { + WMT_PLAT_PR_ERR("remap jtag_addr1 fail!\n"); + return -1; + } + + remap_addr2 = ioremap(JTAG_ADDR2_BASE, 0x100); + if (remap_addr2 == 0) { + WMT_PLAT_PR_ERR("remap jtag_addr2 fail!\n"); + return -1; + } + + /*Pinmux setting for MT6625 I/F */ + addr = remap_addr1 + 0x03C0; + tmp = DRV_Reg32(addr); + tmp = tmp & 0xff; + tmp = tmp | 0x11111100; + DRV_WriteReg32(addr, tmp); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%08x, 0x%08x)", addr, DRV_Reg32(addr)); + + addr = remap_addr1 + 0x03D0; + tmp = DRV_Reg32(addr); + tmp = tmp & 0xff000000; + tmp = tmp | 0x00111111; + DRV_WriteReg32(addr, tmp); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%08x, 0x%08x)", addr, DRV_Reg32(addr)); + + /*AP GPIO Setting 1 */ + /*Enable IES */ + /* addr = 0x10002014; */ + addr = remap_addr2 + 0x0014; + tmp = 0x00000003; + DRV_WriteReg32(addr, tmp); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%08x, 0x%08x)", addr, DRV_Reg32(addr)); + /*GPIO mode setting */ + /* addr = 0x10005334; */ + addr = remap_addr1 + 0x0334; + tmp = 0x55000000; + DRV_WriteReg32(addr, tmp); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%08x, 0x%08x)", addr, DRV_Reg32(addr)); + + /* addr = 0x10005344; */ + addr = remap_addr1 + 0x0344; + tmp = 0x00555555; + DRV_WriteReg32(addr, tmp); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%08x, 0x%08x)", addr, DRV_Reg32(addr)); + /*GPIO direction control */ + /* addr = 0x10005008; */ + addr = remap_addr1 + 0x0008; + tmp = 0xc0000000; + DRV_WriteReg32(addr, tmp); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%08x, 0x%08x)", addr, DRV_Reg32(addr)); + + /* addr = 0x10005018; */ + addr = remap_addr1 + 0x0018; + tmp = 0x0000000d; + DRV_WriteReg32(addr, tmp); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%08x, 0x%08x)", addr, DRV_Reg32(addr)); + + /* addr = 0x10005014; */ + addr = remap_addr1 + 0x0014; + tmp = 0x00000032; + DRV_WriteReg32(addr, tmp); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%08x, 0x%08x)", addr, DRV_Reg32(addr)); + + /*PULL Enable */ + /* addr = 0x100020a4; */ + addr = remap_addr2 + 0x00a4; + tmp = 0x000000ff; + DRV_WriteReg32(addr, tmp); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%08x, 0x%08x)", addr, DRV_Reg32(addr)); + + /*PULL select enable */ + /* addr = 0x100020d4; */ + addr = remap_addr2 + 0x00d4; + tmp = 0x000000b4; + DRV_WriteReg32(addr, tmp); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%08x, 0x%08x)", addr, DRV_Reg32(addr)); + + /* addr = 0x100020d8; */ + addr = remap_addr2 + 0x00d8; + tmp = 0x0000004b; + DRV_WriteReg32(addr, tmp); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%08x, 0x%08x)", addr, DRV_Reg32(addr)); +#endif + } +#endif + return 0; +} + +UINT32 mtk_wcn_consys_jtag_flag_ctrl(UINT32 en) +{ + WMT_PLAT_PR_INFO("%s jtag set for MCU\n", en ? "enable" : "disable"); + gJtagCtrl = en; + return 0; +} + +static INT32 consys_clock_buffer_ctrl(MTK_WCN_BOOL enable) +{ +#if CONSYS_CLOCK_BUF_CTRL + KERNEL_clk_buf_ctrl(CLK_BUF_CONN, enable); +#endif + return 0; +} + +static VOID consys_hw_reset_bit_set(MTK_WCN_BOOL enable) +{ +#ifdef CONFIG_OF /*use DT */ + if (enable) { + /*3.assert CONNSYS CPU SW reset 0x10007018 "[12]=1'b1 [31:24]=8'h88 (key)" */ + CONSYS_REG_WRITE((conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET), + CONSYS_REG_READ(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET) | + CONSYS_CPU_SW_RST_BIT | CONSYS_CPU_SW_RST_CTRL_KEY); + } else { + /*16.deassert CONNSYS CPU SW reset 0x10007018 "[12]=1'b0 [31:24] =8'h88 (key)" */ + CONSYS_REG_WRITE(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET, + (CONSYS_REG_READ(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET) & + ~CONSYS_CPU_SW_RST_BIT) | CONSYS_CPU_SW_RST_CTRL_KEY); + } +#else + if (enable) { + /*3.assert CONNSYS CPU SW reset 0x10007018 "[12]=1'b1 [31:24]=8'h88 (key)" */ + CONSYS_REG_WRITE(CONSYS_CPU_SW_RST_REG, + (CONSYS_REG_READ(CONSYS_CPU_SW_RST_REG) | CONSYS_CPU_SW_RST_BIT | + CONSYS_CPU_SW_RST_CTRL_KEY)); + } else { + /*16.deassert CONNSYS CPU SW reset 0x10007018 "[12]=1'b0 [31:24] =8'h88(key)" */ + CONSYS_REG_WRITE(CONSYS_CPU_SW_RST_REG, + (CONSYS_REG_READ(CONSYS_CPU_SW_RST_REG) & ~CONSYS_CPU_SW_RST_BIT) | + CONSYS_CPU_SW_RST_CTRL_KEY); + } +#endif +} + +static VOID consys_hw_spm_clk_gating_enable(VOID) +{ +#ifdef CONFIG_OF /*use DT */ + /*turn on SPM clock gating enable PWRON_CONFG_EN 0x10006000 32'h0b160001 */ + CONSYS_REG_WRITE((conn_reg.spm_base + CONSYS_PWRON_CONFG_EN_OFFSET), CONSYS_PWRON_CONFG_EN_VALUE); +#else + /*turn on SPM clock gating enable PWRON_CONFG_EN 0x10006000 32'h0b160001 */ + CONSYS_REG_WRITE(CONSYS_PWRON_CONFG_EN_REG, CONSYS_PWRON_CONFG_EN_VALUE); +#endif +} + +static INT32 consys_hw_power_ctrl(MTK_WCN_BOOL enable) +{ +#if CONSYS_PWR_ON_OFF_API_AVAILABLE + INT32 iRet = -1; +#endif + + if (enable) { +#if CONSYS_PWR_ON_OFF_API_AVAILABLE +#if defined(CONFIG_MTK_CLKMGR) + iRet = conn_power_on(); /* consult clkmgr owner. */ + if (iRet) + WMT_PLAT_PR_ERR("conn_power_on fail(%d)\n", iRet); + WMT_PLAT_PR_DBG("conn_power_on ok\n"); +#else + iRet = clk_prepare_enable(clk_scp_conn_main); + if (iRet) + WMT_PLAT_PR_ERR("clk_prepare_enable(clk_scp_conn_main) fail(%d)\n", iRet); + WMT_PLAT_PR_DBG("clk_prepare_enable(clk_scp_conn_main) ok\n"); +#endif /* defined(CONFIG_MTK_CLKMGR) */ + +#else + +#ifdef CONFIG_OF /*use DT */ + /*2.write conn_top1_pwr_on=1, power on conn_top1 0x10006280 [2] 1'b1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_SPM_PWR_ON_BIT); + /*3.read conn_top1_pwr_on_ack =1, power on ack ready 0x1000660C [1] */ + while (0 == (CONSYS_PWR_ON_ACK_BIT & CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_OFFSET))) + NULL; + /*5.write conn_top1_pwr_on_s=1, power on conn_top1 0x10006280 [3] 1'b1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_SPM_PWR_ON_S_BIT); + /*6.write conn_clk_dis=0, enable connsys clock 0x10006280 [4] 1'b0 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) & + ~CONSYS_CLK_CTRL_BIT); + /*7.wait 1us */ + udelay(1); + /*8.read conn_top1_pwr_on_ack_s =1, power on ack ready 0x10006610 [1] */ + while (0 == (CONSYS_PWR_CONN_ACK_S_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_S_OFFSET))) + NULL; + /*9.release connsys ISO, conn_top1_iso_en=0 0x10006280 [1] 1'b0 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) & + ~CONSYS_SPM_PWR_ISO_S_BIT); + /*10.release SW reset of connsys, conn_ap_sw_rst_b=1 0x10006280[0] 1'b1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_SPM_PWR_RST_BIT); + /*disable AXI BUS protect */ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_TOPAXI_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_TOPAXI_PROT_EN_OFFSET) & + ~CONSYS_PROT_MASK); + while (CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_TOPAXI_PROT_STA1_OFFSET) & CONSYS_PROT_MASK) + NULL; +#else + /*2.write conn_top1_pwr_on=1, power on conn_top1 0x10006280 [2] 1'b1 */ + CONSYS_REG_WRITE(CONSYS_TOP1_PWR_CTRL_REG, + CONSYS_REG_READ(CONSYS_TOP1_PWR_CTRL_REG) | CONSYS_SPM_PWR_ON_BIT); + /*3.read conn_top1_pwr_on_ack =1, power on ack ready 0x1000660C [1] */ + while (0 == (CONSYS_PWR_ON_ACK_BIT & CONSYS_REG_READ(CONSYS_PWR_CONN_ACK_REG))) + NULL; + /*5.write conn_top1_pwr_on_s=1, power on conn_top1 0x10006280 [3] 1'b1 */ + CONSYS_REG_WRITE(CONSYS_TOP1_PWR_CTRL_REG, + CONSYS_REG_READ(CONSYS_TOP1_PWR_CTRL_REG) | CONSYS_SPM_PWR_ON_S_BIT); + /*6.write conn_clk_dis=0, enable connsys clock 0x10006280 [4] 1'b0 */ + CONSYS_REG_WRITE(CONSYS_TOP1_PWR_CTRL_REG, + CONSYS_REG_READ(CONSYS_TOP1_PWR_CTRL_REG) & ~CONSYS_CLK_CTRL_BIT); + /*7.wait 1us */ + udelay(1); + /*8.read conn_top1_pwr_on_ack_s =1, power on ack ready 0x10006610 [1] */ + while (0 == (CONSYS_PWR_CONN_ACK_S_BIT & CONSYS_REG_READ(CONSYS_PWR_CONN_ACK_S_REG))) + NULL; + /*9.release connsys ISO, conn_top1_iso_en=0 0x10006280 [1] 1'b0 */ + CONSYS_REG_WRITE(CONSYS_TOP1_PWR_CTRL_REG, + CONSYS_REG_READ(CONSYS_TOP1_PWR_CTRL_REG) & ~CONSYS_SPM_PWR_ISO_S_BIT); + /*10.release SW reset of connsys, conn_ap_sw_rst_b=1 0x10006280[0] 1'b1 */ + CONSYS_REG_WRITE(CONSYS_TOP1_PWR_CTRL_REG, + CONSYS_REG_READ(CONSYS_TOP1_PWR_CTRL_REG) | CONSYS_SPM_PWR_RST_BIT); + /*disable AXI BUS protect */ + CONSYS_REG_WRITE(CONSYS_TOPAXI_PROT_EN, CONSYS_REG_READ(CONSYS_TOPAXI_PROT_EN) & ~CONSYS_PROT_MASK); + while (CONSYS_REG_READ(CONSYS_TOPAXI_PROT_STA1) & CONSYS_PROT_MASK) + NULL; +#endif /* CONFIG_OF */ +#endif /* CONSYS_PWR_ON_OFF_API_AVAILABLE */ + } else { +#if CONSYS_PWR_ON_OFF_API_AVAILABLE +#if defined(CONFIG_MTK_CLKMGR) + /*power off connsys by API (MT6582, MT6572 are different) API: conn_power_off() */ + iRet = conn_power_off(); /* consult clkmgr owner */ + if (iRet) + WMT_PLAT_PR_ERR("conn_power_off fail(%d)\n", iRet); + WMT_PLAT_PR_DBG("conn_power_off ok\n"); +#else + clk_disable_unprepare(clk_scp_conn_main); + WMT_PLAT_PR_DBG("clk_disable_unprepare(clk_scp_conn_main) calling\n"); +#endif /* defined(CONFIG_MTK_CLKMGR) */ + +#else + +#ifdef CONFIG_OF /*use DT */ + { + INT32 count = 0; + + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_TOPAXI_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_TOPAXI_PROT_EN_OFFSET) | + CONSYS_PROT_MASK); + while ((CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_TOPAXI_PROT_STA1_OFFSET) & + CONSYS_PROT_MASK) != CONSYS_PROT_MASK) { + count++; + if (count > 1000) + break; + } + } + /*release connsys ISO, conn_top1_iso_en=1 0x10006280 [1] 1'b1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_SPM_PWR_ISO_S_BIT); + /*assert SW reset of connsys, conn_ap_sw_rst_b=0 0x10006280[0] 1'b0 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) & + ~CONSYS_SPM_PWR_RST_BIT); + /*write conn_clk_dis=1, disable connsys clock 0x10006280 [4] 1'b1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_CLK_CTRL_BIT); + /*wait 1us */ + udelay(1); + /*write conn_top1_pwr_on=0, power off conn_top1 0x10006280 [3:2] 2'b00 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) & + ~(CONSYS_SPM_PWR_ON_BIT | CONSYS_SPM_PWR_ON_S_BIT)); +#else + { + INT32 count = 0; + + CONSYS_REG_WRITE(CONSYS_TOPAXI_PROT_EN, + CONSYS_REG_READ(CONSYS_TOPAXI_PROT_EN) | CONSYS_PROT_MASK); + while ((CONSYS_REG_READ(CONSYS_TOPAXI_PROT_STA1) & CONSYS_PROT_MASK) != CONSYS_PROT_MASK) { + count++; + if (count > 1000) + break; + } + + } + /*release connsys ISO, conn_top1_iso_en=1 0x10006280 [1] 1'b1 */ + CONSYS_REG_WRITE(CONSYS_TOP1_PWR_CTRL_REG, + CONSYS_REG_READ(CONSYS_TOP1_PWR_CTRL_REG) | CONSYS_SPM_PWR_ISO_S_BIT); + /*assert SW reset of connsys, conn_ap_sw_rst_b=0 0x10006280[0] 1'b0 */ + CONSYS_REG_WRITE(CONSYS_TOP1_PWR_CTRL_REG, + CONSYS_REG_READ(CONSYS_TOP1_PWR_CTRL_REG) & ~CONSYS_SPM_PWR_RST_BIT); + /*write conn_clk_dis=1, disable connsys clock 0x10006280 [4] 1'b1 */ + CONSYS_REG_WRITE(CONSYS_TOP1_PWR_CTRL_REG, + CONSYS_REG_READ(CONSYS_TOP1_PWR_CTRL_REG) | CONSYS_CLK_CTRL_BIT); + /*wait 1us */ + udelay(1); + /*write conn_top1_pwr_on=0, power off conn_top1 0x10006280 [3:2] 2'b00 */ + CONSYS_REG_WRITE(CONSYS_TOP1_PWR_CTRL_REG, CONSYS_REG_READ(CONSYS_TOP1_PWR_CTRL_REG) & + ~(CONSYS_SPM_PWR_ON_BIT | CONSYS_SPM_PWR_ON_S_BIT)); +#endif /* CONFIG_OF */ +#endif /* CONSYS_PWR_ON_OFF_API_AVAILABLE */ + } + +#if CONSYS_PWR_ON_OFF_API_AVAILABLE + return iRet; +#else + return 0; +#endif +} + +static INT32 consys_ahb_clock_ctrl(MTK_WCN_BOOL enable) +{ +#if CONSYS_AHB_CLK_MAGEMENT + + if (enable) { +#if defined(CONFIG_MTK_CLKMGR) + enable_clock(MT_CG_INFRA_CONNMCU_BUS, "WCN_MOD"); + WMT_PLAT_PR_DBG("enable MT_CG_INFRA_CONNMCU_BUS CLK\n"); +#else + INT32 iRet = -1; + + iRet = clk_prepare_enable(clk_infra_conn_main); + if (iRet) + WMT_PLAT_PR_ERR("clk_prepare_enable(clk_infra_conn_main) fail(%d)\n", iRet); + WMT_PLAT_PR_DBG("[CCF]enable clk_infra_conn_main\n"); +#endif /* defined(CONFIG_MTK_CLKMGR) */ + } else { +#if defined(CONFIG_MTK_CLKMGR) + disable_clock(MT_CG_INFRA_CONNMCU_BUS, "WMT_MOD"); +#else + clk_disable_unprepare(clk_infra_conn_main); + WMT_PLAT_PR_DBG("[CCF] clk_disable_unprepare(clk_infra_conn_main) calling\n"); +#endif /* defined(CONFIG_MTK_CLKMGR) */ + } +#endif + return 0; +} + +static INT32 polling_consys_chipid(VOID) +{ + UINT32 retry = 10; + UINT32 consysHwChipId = 0; + +#ifdef CONFIG_OF /*use DT */ + /*12.poll CONNSYS CHIP ID until chipid is returned 0x18070008 */ + while (retry-- > 0) { + consysHwChipId = CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_CHIP_ID_OFFSET); + if ((consysHwChipId == 0x0321) || (consysHwChipId == 0x0335) || (consysHwChipId == 0x0337)) { + WMT_PLAT_PR_INFO("retry(%d)consys chipId(0x%08x)\n", retry, consysHwChipId); + break; + } + msleep(20); + } + + if ((0 == retry) || (0 == consysHwChipId)) { + WMT_PLAT_PR_ERR("Maybe has a consys power on issue,(0x%08x)\n", consysHwChipId); + WMT_PLAT_PR_INFO("reg dump:CONSYS_CPU_SW_RST_REG(0x%x)\n", + CONSYS_REG_READ(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET)); + WMT_PLAT_PR_INFO("reg dump:CONSYS_PWR_CONN_ACK_REG(0x%x)\n", + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_OFFSET)); + WMT_PLAT_PR_INFO("reg dump:CONSYS_PWR_CONN_ACK_S_REG(0x%x)\n", + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_S_OFFSET)); + WMT_PLAT_PR_INFO("reg dump:CONSYS_TOP1_PWR_CTRL_REG(0x%x)\n", + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET)); + } +#else + /*12.poll CONNSYS CHIP ID until 6752 is returned 0x18070008 32'h6752 */ + while (retry-- > 0) { + WMT_PLAT_PR_DBG("CONSYS_CHIP_ID_REG(0x%08x)", CONSYS_REG_READ(CONSYS_CHIP_ID_REG)); + consysHwChipId = CONSYS_REG_READ(CONSYS_CHIP_ID_REG); + if ((consysHwChipId == 0x0321) || (consysHwChipId == 0x0335) || (consysHwChipId == 0x0337)) { + WMT_PLAT_PR_INFO("retry(%d)consys chipId(0x%08x)\n", retry, consysHwChipId); + break; + } + msleep(20); + } + + if ((0 == retry) || (0 == consysHwChipId)) { + WMT_PLAT_PR_ERR("Maybe has a consys power on issue,(0x%08x)\n", consysHwChipId); + WMT_PLAT_PR_INFO("reg dump:CONSYS_CPU_SW_RST_REG(0x%x)\n", + CONSYS_REG_READ(CONSYS_CPU_SW_RST_REG)); + WMT_PLAT_PR_INFO("reg dump:CONSYS_PWR_CONN_ACK_REG(0x%x)\n", + CONSYS_REG_READ(CONSYS_PWR_CONN_ACK_REG)); + WMT_PLAT_PR_INFO("reg dump:CONSYS_PWR_CONN_ACK_S_REG(0x%x)\n", + CONSYS_REG_READ(CONSYS_PWR_CONN_ACK_S_REG)); + WMT_PLAT_PR_INFO("reg dump:CONSYS_TOP1_PWR_CTRL_REG(0x%x)\n", + CONSYS_REG_READ(CONSYS_TOP1_PWR_CTRL_REG)); + } +#endif + return 0; +} + +static VOID consys_acr_reg_setting(VOID) +{ + /* + *14.write 1 to conn_mcu_confg ACR[1] if real speed MBIST + *(default write "1") ACR 0x18070110[18] 1'b1 + *if this bit is 0, HW will do memory auto test under low CPU frequence (26M Hz) + *if this bit is 0, HW will do memory auto test under high CPU frequence(138M Hz) + *inclulding low CPU frequence + */ +#ifdef CONFIG_OF /*use DT */ + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_MCU_CFG_ACR_OFFSET, + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_MCU_CFG_ACR_OFFSET) | + CONSYS_MCU_CFG_ACR_MBIST_BIT); +#else + CONSYS_REG_WRITE(CONSYS_MCU_CFG_ACR_REG, + CONSYS_REG_READ(CONSYS_MCU_CFG_ACR_REG) | CONSYS_MCU_CFG_ACR_MBIST_BIT); +#endif +} + +static VOID consys_afe_reg_setting(VOID) +{ +#if 0 + /*15.default no need,update ANA_WBG(AFE) CR if needed, CONSYS_AFE_REG */ + CONSYS_REG_WRITE(CONSYS_AFE_REG_DIG_RCK_01, CONSYS_AFE_REG_DIG_RCK_01_VALUE); + CONSYS_REG_WRITE(CONSYS_AFE_REG_WBG_PLL_02, CONSYS_AFE_REG_WBG_PLL_02_VALUE); + CONSYS_REG_WRITE(CONSYS_AFE_REG_WBG_WB_TX_01, CONSYS_AFE_REG_WBG_WB_TX_01_VALUE); +#endif +} + +static INT32 consys_hw_vcn18_ctrl(MTK_WCN_BOOL enable) +{ +#if CONSYS_PMIC_CTRL_ENABLE + if (enable) { + /*need PMIC driver provide new API protocol */ + /*1.AP power on VCN_1V8 LDO (with PMIC_WRAP API) VCN_1V8 */ + KERNEL_pmic_set_register_value(PMIC_RG_VCN18_ON_CTRL, 0); + /* VOL_DEFAULT, VOL_1200, VOL_1300, VOL_1500, VOL_1800... */ +#if defined(CONFIG_MTK_PMIC_LEGACY) + hwPowerOn(MT6328_POWER_LDO_VCN18, VOL_1800, "wcn_drv"); +#else + if (reg_VCN18) { + regulator_set_voltage(reg_VCN18, VOL_1800, VOL_1800); + if (regulator_enable(reg_VCN18)) + WMT_PLAT_PR_ERR("enable VCN18 fail\n"); + else + WMT_PLAT_PR_DBG("enable VCN18 ok\n"); + } +#endif + } else { + /*AP power off MT6625L VCN_1V8 LDO */ + KERNEL_pmic_set_register_value(PMIC_RG_VCN18_ON_CTRL, 0); +#if defined(CONFIG_MTK_PMIC_LEGACY) + hwPowerDown(MT6328_POWER_LDO_VCN18, "wcn_drv"); +#else + if (reg_VCN18) { + if (regulator_disable(reg_VCN18)) + WMT_PLAT_PR_ERR("disable VCN_1V8 fail!\n"); + else + WMT_PLAT_PR_DBG("disable VCN_1V8 ok\n"); + } +#endif + } +#endif + return 0; +} + +static VOID consys_vcn28_hw_mode_ctrl(UINT32 enable) +{ +#if CONSYS_PMIC_CTRL_ENABLE + if (enable) { + /*2.1.switch VCN28 to HW control mode (with PMIC_WRAP API) */ + KERNEL_pmic_set_register_value(PMIC_RG_VCN28_ON_CTRL, 1); + } else + KERNEL_pmic_set_register_value(PMIC_RG_VCN28_ON_CTRL, 0); +#endif +} + +static INT32 consys_hw_vcn28_ctrl(UINT32 enable) +{ +#if CONSYS_PMIC_CTRL_ENABLE + if (enable) { + /*in co-clock mode,need to turn on vcn28 when fm on */ +#if defined(CONFIG_MTK_PMIC_LEGACY) + hwPowerOn(MT6328_POWER_LDO_VCN28, VOL_2800, "wcn_drv"); +#else + if (reg_VCN28) { + regulator_set_voltage(reg_VCN28, VOL_2800, VOL_2800); + if (regulator_enable(reg_VCN28)) + WMT_PLAT_PR_ERR("enable VCN_2V8 fail!\n"); + else + WMT_PLAT_PR_DBG("enable VCN_2V8 ok\n"); + } +#endif + WMT_PLAT_PR_INFO("turn on vcn28 for fm/gps usage in co-clock mode\n"); + } else { + /*in co-clock mode,need to turn off vcn28 when fm off */ +#if defined(CONFIG_MTK_PMIC_LEGACY) + hwPowerDown(MT6328_POWER_LDO_VCN28, "wcn_drv"); +#else + if (reg_VCN28) { + if (regulator_disable(reg_VCN28)) + WMT_PLAT_PR_ERR("disable VCN_2V8 fail!\n"); + else + WMT_PLAT_PR_DBG("disable VCN_2V8 ok\n"); + } +#endif + WMT_PLAT_PR_INFO("turn off vcn28 for fm/gps usage in co-clock mode\n"); + } +#endif + return 0; +} + +static INT32 consys_hw_bt_vcn33_ctrl(UINT32 enable) +{ +#if CONSYS_BT_WIFI_SHARE_V33 + /* spin_lock_irqsave(&gBtWifiV33.lock,gBtWifiV33.flags); */ + if (enable) { + if (1 == gBtWifiV33.counter) { + gBtWifiV33.counter++; + WMT_PLAT_PR_DBG("V33 has been enabled,counter(%d)\n", gBtWifiV33.counter); + } else if (2 == gBtWifiV33.counter) { + WMT_PLAT_PR_DBG("V33 has been enabled,counter(%d)\n", gBtWifiV33.counter); + } else { +#if CONSYS_PMIC_CTRL_ENABLE + /*do BT PMIC on,depenency PMIC API ready */ + /*switch BT PALDO control from SW mode to HW mode:0x416[5]-->0x1 */ + /* VOL_DEFAULT, VOL_3300, VOL_3400, VOL_3500, VOL_3600 */ + hwPowerOn(MT6325_POWER_LDO_VCN33, VOL_3300, "wcn_drv"); + mt6325_upmu_set_rg_vcn33_on_ctrl(1); +#endif + WMT_PLAT_PR_INFO("WMT do BT/WIFI v3.3 on\n"); + gBtWifiV33.counter++; + } + + } else { + if (1 == gBtWifiV33.counter) { + /*do BT PMIC off */ + /*switch BT PALDO control from HW mode to SW mode:0x416[5]-->0x0 */ +#if CONSYS_PMIC_CTRL_ENABLE + mt6325_upmu_set_rg_vcn33_on_ctrl(0); + hwPowerDown(MT6325_POWER_LDO_VCN33, "wcn_drv"); +#endif + WMT_PLAT_PR_INFO("WMT do BT/WIFI v3.3 off\n"); + gBtWifiV33.counter--; + } else if (2 == gBtWifiV33.counter) { + gBtWifiV33.counter--; + WMT_PLAT_PR_DBG("V33 no need disabled,counter(%d)\n", gBtWifiV33.counter); + } else { + WMT_PLAT_PR_DBG("V33 has been disabled,counter(%d)\n", gBtWifiV33.counter); + } + + } + /* spin_unlock_irqrestore(&gBtWifiV33.lock,gBtWifiV33.flags); */ +#else + if (enable) { + /*do BT PMIC on,depenency PMIC API ready */ + /*switch BT PALDO control from SW mode to HW mode:0x416[5]-->0x1 */ +#if CONSYS_PMIC_CTRL_ENABLE + /* VOL_DEFAULT, VOL_3300, VOL_3400, VOL_3500, VOL_3600 */ +#if defined(CONFIG_MTK_PMIC_LEGACY) + hwPowerOn(MT6328_POWER_LDO_VCN33_BT, VOL_3300, "wcn_drv"); +#else + if (reg_VCN33_BT) { + regulator_set_voltage(reg_VCN33_BT, VOL_3300, VOL_3300); + if (regulator_enable(reg_VCN33_BT)) + WMT_PLAT_PR_ERR("WMT do BT PMIC on fail!\n"); + } +#endif + KERNEL_pmic_set_register_value(PMIC_RG_VCN33_ON_CTRL_BT, 1); + +#endif + WMT_PLAT_PR_INFO("WMT do BT PMIC on\n"); + } else { + /*do BT PMIC off */ + /*switch BT PALDO control from HW mode to SW mode:0x416[5]-->0x0 */ +#if CONSYS_PMIC_CTRL_ENABLE + KERNEL_pmic_set_register_value(PMIC_RG_VCN33_ON_CTRL_BT, 0); +#if defined(CONFIG_MTK_PMIC_LEGACY) + hwPowerDown(MT6328_POWER_LDO_VCN33_BT, "wcn_drv"); +#else + if (reg_VCN33_BT) + regulator_disable(reg_VCN33_BT); +#endif +#endif + WMT_PLAT_PR_INFO("WMT do BT PMIC off\n"); + } +#endif + return 0; +} + +static INT32 consys_hw_wifi_vcn33_ctrl(UINT32 enable) +{ +#if CONSYS_BT_WIFI_SHARE_V33 + mtk_wcn_consys_hw_bt_paldo_ctrl(enable); +#else + if (enable) { + /*do WIFI PMIC on,depenency PMIC API ready */ + /*switch WIFI PALDO control from SW mode to HW mode:0x418[14]-->0x1 */ +#if CONSYS_PMIC_CTRL_ENABLE +#if defined(CONFIG_MTK_PMIC_LEGACY) + hwPowerOn(MT6328_POWER_LDO_VCN33_WIFI, VOL_3300, "wcn_drv"); +#else + if (reg_VCN33_WIFI) { + regulator_set_voltage(reg_VCN33_WIFI, VOL_3300, VOL_3300); + if (regulator_enable(reg_VCN33_WIFI)) + WMT_PLAT_PR_ERR("WMT do WIFI PMIC on fail!\n"); + } +#endif + KERNEL_pmic_set_register_value(PMIC_RG_VCN33_ON_CTRL_WIFI, 1); +#endif + WMT_PLAT_PR_INFO("WMT do WIFI PMIC on\n"); + } else { + /*do WIFI PMIC off */ + /*switch WIFI PALDO control from HW mode to SW mode:0x418[14]-->0x0 */ +#if CONSYS_PMIC_CTRL_ENABLE + KERNEL_pmic_set_register_value(PMIC_RG_VCN33_ON_CTRL_WIFI, 0); +#if defined(CONFIG_MTK_PMIC_LEGACY) + hwPowerDown(MT6328_POWER_LDO_VCN33_WIFI, "wcn_drv"); +#else + if (reg_VCN33_WIFI) + regulator_disable(reg_VCN33_WIFI); +#endif + +#endif + WMT_PLAT_PR_INFO("WMT do WIFI PMIC off\n"); + } + +#endif + return 0; +} + +static INT32 consys_emi_mpu_set_region_protection(VOID) +{ +#if CONSYS_EMI_MPU_SETTING + /*set MPU for EMI share Memory */ + WMT_PLAT_PR_INFO("setting MPU for EMI share memory\n"); +#if defined(CONFIG_ARCH_MT6735) + emi_mpu_set_region_protection(gConEmiPhyBase + SZ_1M / 2, + gConEmiPhyBase + gConEmiSize - 1, + 13, + SET_ACCESS_PERMISSON(FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, + FORBIDDEN, NO_PROTECTION, FORBIDDEN, NO_PROTECTION)); +#elif defined(CONFIG_ARCH_MT6735M) + emi_mpu_set_region_protection(gConEmiPhyBase, + gConEmiPhyBase + SZ_1M - 1, + 6, + SET_ACCESS_PERMISSON(FORBIDDEN, NO_PROTECTION, FORBIDDEN, + NO_PROTECTION)); +#elif defined(CONFIG_ARCH_MT6753) + emi_mpu_set_region_protection(gConEmiPhyBase + SZ_1M / 2, + gConEmiPhyBase + SZ_1M - 1, + 13, + SET_ACCESS_PERMISSON(FORBIDDEN, FORBIDDEN, FORBIDDEN, + FORBIDDEN, FORBIDDEN, NO_PROTECTION, FORBIDDEN, NO_PROTECTION)); + +#else + WMT_PLAT_PR_WARN("not define platform config\n"); +#endif +#endif + return 0; +} + +static UINT32 consys_emi_set_remapping_reg(VOID) +{ +#ifdef CONFIG_OF /*use DT */ + UINT32 addrPhy = 0; + + /*consys to ap emi remapping register:10000320, cal remapping address */ + addrPhy = (gConEmiPhyBase & 0xFFF00000) >> 20; + + /*enable consys to ap emi remapping bit12 */ + addrPhy = addrPhy | 0x1000; + + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET) | addrPhy); + + WMT_PLAT_PR_INFO("CONSYS_EMI_MAPPING dump in restore cb(0x%08x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET)); +#endif + return 0; +} + +static INT32 bt_wifi_share_v33_spin_lock_init(VOID) +{ +#if CONSYS_BT_WIFI_SHARE_V33 + gBtWifiV33.counter = 0; + spin_lock_init(&gBtWifiV33.lock); +#endif + return 0; +} + +static INT32 consys_clk_get_from_dts(struct platform_device *pdev) +{ +#ifdef CONFIG_OF /*use DT */ +#if !defined(CONFIG_MTK_CLKMGR) + clk_scp_conn_main = devm_clk_get(&pdev->dev, "conn"); + if (IS_ERR(clk_scp_conn_main)) { + WMT_PLAT_PR_ERR("[CCF]cannot get clk_scp_conn_main clock.\n"); + return PTR_ERR(clk_scp_conn_main); + } + WMT_PLAT_PR_DBG("[CCF]clk_scp_conn_main=%p\n", clk_scp_conn_main); + + clk_infra_conn_main = devm_clk_get(&pdev->dev, "bus"); + if (IS_ERR(clk_infra_conn_main)) { + WMT_PLAT_PR_ERR("[CCF]cannot get clk_infra_conn_main clock.\n"); + return PTR_ERR(clk_infra_conn_main); + } + WMT_PLAT_PR_DBG("[CCF]clk_infra_conn_main=%p\n", clk_infra_conn_main); +#endif /* !defined(CONFIG_MTK_CLKMGR) */ +#endif + return 0; +} + +static INT32 consys_pmic_get_from_dts(struct platform_device *pdev) +{ +#ifdef CONFIG_OF /*use DT */ +#if CONSYS_PMIC_CTRL_ENABLE +#if !defined(CONFIG_MTK_PMIC_LEGACY) + reg_VCN18 = regulator_get(&pdev->dev, "vcn18"); + if (!reg_VCN18) + WMT_PLAT_PR_ERR("Regulator_get VCN_1V8 fail\n"); + reg_VCN28 = regulator_get(&pdev->dev, "vcn28"); + if (!reg_VCN28) + WMT_PLAT_PR_ERR("Regulator_get VCN_2V8 fail\n"); + reg_VCN33_BT = regulator_get(&pdev->dev, "vcn33_bt"); + if (!reg_VCN33_BT) + WMT_PLAT_PR_ERR("Regulator_get VCN33_BT fail\n"); + reg_VCN33_WIFI = regulator_get(&pdev->dev, "vcn33_wifi"); + if (!reg_VCN33_WIFI) + WMT_PLAT_PR_ERR("Regulator_get VCN33_WIFI fail\n"); +#endif +#endif +#endif + return 0; +} + +static INT32 consys_read_irq_info_from_dts(struct platform_device *pdev, INT32 *irq_num, UINT32 *irq_flag) +{ +#ifdef CONFIG_OF /*use DT */ + struct device_node *node; + UINT32 irq_info[3] = { 0, 0, 0 }; + + INT32 iret = -1; + + node = pdev->dev.of_node; + if (node) { + *irq_num = irq_of_parse_and_map(node, 0); + /* get the interrupt line behaviour */ + if (of_property_read_u32_array(node, "interrupts", irq_info, ARRAY_SIZE(irq_info))) { + WMT_PLAT_PR_ERR("get irq flags from DTS fail!!\n"); + return iret; + } + *irq_flag = irq_info[2]; + WMT_PLAT_PR_INFO("get irq id(%d) and irq trigger flag(%d) from DT\n", *irq_num, + *irq_flag); + } else { + WMT_PLAT_PR_ERR("[%s] can't find CONSYS compatible node\n", __func__); + return iret; + } +#endif + return 0; +} + +static INT32 consys_read_reg_from_dts(struct platform_device *pdev) +{ +#ifdef CONFIG_OF /*use DT */ + INT32 iRet = -1; + struct device_node *node = NULL; + + node = pdev->dev.of_node; + if (node) { + /* registers base address */ + conn_reg.mcu_base = (SIZE_T) of_iomap(node, 0); + WMT_PLAT_PR_DBG("Get mcu register base(0x%zx)\n", conn_reg.mcu_base); + conn_reg.ap_rgu_base = (SIZE_T) of_iomap(node, 1); + WMT_PLAT_PR_DBG("Get ap_rgu register base(0x%zx)\n", conn_reg.ap_rgu_base); + conn_reg.topckgen_base = (SIZE_T) of_iomap(node, 2); + WMT_PLAT_PR_DBG("Get topckgen register base(0x%zx)\n", conn_reg.topckgen_base); + conn_reg.spm_base = (SIZE_T) of_iomap(node, 3); + WMT_PLAT_PR_DBG("Get spm register base(0x%zx)\n", conn_reg.spm_base); + } else { + WMT_PLAT_PR_ERR("[%s] can't find CONSYS compatible node\n", __func__); + return iRet; + } +#endif + return 0; +} + +static VOID force_trigger_assert_debug_pin(VOID) +{ +#ifdef CONFIG_OF /*use DT */ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AP2CONN_OSC_EN_OFFSET) & ~CONSYS_AP2CONN_WAKEUP_BIT); + WMT_PLAT_PR_INFO("enable:dump CONSYS_AP2CONN_OSC_EN_REG(0x%x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET)); + usleep_range(64, 96); + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AP2CONN_OSC_EN_OFFSET) | CONSYS_AP2CONN_WAKEUP_BIT); + WMT_PLAT_PR_INFO("disable:dump CONSYS_AP2CONN_OSC_EN_REG(0x%x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET)); +#endif +} + +static UINT32 consys_read_cpupcr(VOID) +{ +#ifdef CONFIG_OF /*use DT */ + if (conn_reg.mcu_base == 0) + return 0; + + if (mtk_consys_check_reg_readable_by_addr(conn_reg.mcu_base + CONSYS_CPUPCR_OFFSET) == 0) + return 0; + + return CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_CPUPCR_OFFSET); +#endif +} + +static UINT32 consys_soc_chipid_get(VOID) +{ + return PLATFORM_SOC_CHIP; +} + +static P_CONSYS_EMI_ADDR_INFO consys_soc_get_emi_phy_add(VOID) +{ + return &mtk_wcn_emi_addr_info; +} + +P_WMT_CONSYS_IC_OPS mtk_wcn_get_consys_ic_ops(VOID) +{ + return &consys_ic_ops; +} + +static INT32 consys_emi_coredump_remapping(UINT8 __iomem **addr, UINT32 enable) +{ + if (enable) { + *addr = ioremap_nocache(gConEmiPhyBase + CONSYS_EMI_COREDUMP_OFFSET, CONSYS_EMI_MEM_SIZE); + if (*addr) { + WMT_PLAT_PR_INFO("COREDUMP EMI mapping OK virtual(0x%p) physical(0x%x)\n", + *addr, (UINT32) gConEmiPhyBase + CONSYS_EMI_COREDUMP_OFFSET); + memset_io(*addr, 0, CONSYS_EMI_MEM_SIZE); + } else { + WMT_PLAT_PR_ERR("EMI mapping fail\n"); + return -1; + } + } else { + if (*addr) { + iounmap(*addr); + *addr = NULL; + } + } + return 0; +} + +static INT32 consys_reset_emi_coredump(UINT8 __iomem *addr) +{ + if (!addr) { + WMT_PLAT_PR_ERR("get virtual address fail\n"); + return -1; + } + WMT_PLAT_PR_INFO("Reset EMI(0xF0080000 ~ 0xF0080400) and (0xF0088400 ~ 0xF0090400)\n"); + /* reset 0xF0080000 ~ 0xF0080400 (1K) */ + memset_io(addr, 0, 0x400); + /* reset 0xF0088400 ~ 0xF0090400 (32K) */ + memset_io(addr + CONSYS_EMI_PAGED_DUMP_OFFSET, 0, 0x8000); + return 0; +} + +static UINT64 consys_get_options(VOID) +{ + UINT64 options = OPT_POWER_ON_DLM_TABLE | + OPT_SET_MCUCLK_TABLE_1_2 | + OPT_WIFI_LTE_COEX | + OPT_INIT_COEX_AFTER_RF_CALIBRATION | + OPT_SET_OSC_TYPE | + OPT_SET_COREDUMP_LEVEL | + OPT_GPS_SYNC | + OPT_WIFI_LTE_COEX_TABLE_1 | + OPT_NORMAL_PATCH_DWN_0; + return options; +} diff --git a/drivers/misc/mediatek/connectivity/common/common_main/platform/mt6739.c b/drivers/misc/mediatek/connectivity/common/common_main/platform/mt6739.c new file mode 100644 index 0000000000000000000000000000000000000000..cbceddfe1731a0f0c102fdfa7bda4b6d401d3626 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/platform/mt6739.c @@ -0,0 +1,1195 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +#ifdef DFT_TAG +#undef DFT_TAG +#endif +#define DFT_TAG "[WMT-CONSYS-HW]" + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include + +#if defined(CONFIG_MTK_CLKMGR) +#include +#else +#include +#endif /* defined(CONFIG_MTK_LEGACY) */ +#include +#include +#include +#include "osal_typedef.h" +#include "mt6739.h" +#include "mtk_wcn_consys_hw.h" + +#if CONSYS_EMI_MPU_SETTING +#include +#endif + +#if CONSYS_PMIC_CTRL_ENABLE +#include +#include +#endif + +#ifdef CONFIG_MTK_HIBERNATION +#include +#endif + +#include + +#if CONSYS_CLOCK_BUF_CTRL +#include +#endif + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +static INT32 consys_clock_buffer_ctrl(MTK_WCN_BOOL enable); +static VOID consys_hw_reset_bit_set(MTK_WCN_BOOL enable); +static VOID consys_hw_spm_clk_gating_enable(VOID); +static INT32 consys_hw_power_ctrl(MTK_WCN_BOOL enable); +static INT32 consys_ahb_clock_ctrl(MTK_WCN_BOOL enable); +static INT32 polling_consys_chipid(VOID); +static VOID consys_acr_reg_setting(VOID); +static VOID consys_afe_reg_setting(VOID); +static INT32 consys_hw_vcn18_ctrl(MTK_WCN_BOOL enable); +static VOID consys_vcn28_hw_mode_ctrl(UINT32 enable); +static INT32 consys_hw_vcn28_ctrl(UINT32 enable); +static INT32 consys_hw_wifi_vcn33_ctrl(UINT32 enable); +static INT32 consys_hw_bt_vcn33_ctrl(UINT32 enable); +static UINT32 consys_soc_chipid_get(VOID); +static INT32 consys_emi_mpu_set_region_protection(VOID); +static UINT32 consys_emi_set_remapping_reg(VOID); +static INT32 bt_wifi_share_v33_spin_lock_init(VOID); +static INT32 consys_clk_get_from_dts(struct platform_device *pdev); +static INT32 consys_pmic_get_from_dts(struct platform_device *pdev); +static INT32 consys_read_irq_info_from_dts(struct platform_device *pdev, PINT32 irq_num, PUINT32 irq_flag); +static INT32 consys_read_reg_from_dts(struct platform_device *pdev); +static UINT32 consys_read_cpupcr(VOID); +static VOID force_trigger_assert_debug_pin(VOID); +static INT32 consys_co_clock_type(VOID); +static P_CONSYS_EMI_ADDR_INFO consys_soc_get_emi_phy_add(VOID); +static INT32 consys_emi_coredump_remapping(UINT8 __iomem **addr, UINT32 enable); +static INT32 consys_reset_emi_coredump(UINT8 __iomem *addr); +static UINT64 consys_get_options(VOID); + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ +#if CONSYS_BT_WIFI_SHARE_V33 +struct bt_wifi_v33_status gBtWifiV33; +#endif + +/* CCF part */ +#if !defined(CONFIG_MTK_CLKMGR) +struct clk *clk_scp_conn_main; /*ctrl conn_power_on/off */ +/* struct clk *clk_infra_conn_main; */ /*ctrl infra_connmcu_bus clk */ +#endif /* !defined(CONFIG_MTK_LEGACY) */ + + +/* PMIC part */ +#if CONSYS_PMIC_CTRL_ENABLE +#if !defined(CONFIG_MTK_LEGACY) +struct regulator *reg_VCN18; +struct regulator *reg_VCN28; +struct regulator *reg_VCN33_BT; +struct regulator *reg_VCN33_WIFI; +#endif +#endif + +EMI_CTRL_STATE_OFFSET mtk_wcn_emi_state_off = { + .emi_apmem_ctrl_state = EXP_APMEM_CTRL_STATE, + .emi_apmem_ctrl_host_sync_state = EXP_APMEM_CTRL_HOST_SYNC_STATE, + .emi_apmem_ctrl_host_sync_num = EXP_APMEM_CTRL_HOST_SYNC_NUM, + .emi_apmem_ctrl_chip_sync_state = EXP_APMEM_CTRL_CHIP_SYNC_STATE, + .emi_apmem_ctrl_chip_sync_num = EXP_APMEM_CTRL_CHIP_SYNC_NUM, + .emi_apmem_ctrl_chip_sync_addr = EXP_APMEM_CTRL_CHIP_SYNC_ADDR, + .emi_apmem_ctrl_chip_sync_len = EXP_APMEM_CTRL_CHIP_SYNC_LEN, + .emi_apmem_ctrl_chip_print_buff_start = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_START, + .emi_apmem_ctrl_chip_print_buff_len = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_LEN, + .emi_apmem_ctrl_chip_print_buff_idx = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_IDX, + .emi_apmem_ctrl_chip_int_status = EXP_APMEM_CTRL_CHIP_INT_STATUS, + .emi_apmem_ctrl_chip_paded_dump_end = EXP_APMEM_CTRL_CHIP_PAGED_DUMP_END, + .emi_apmem_ctrl_host_outband_assert_w1 = EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1, + .emi_apmem_ctrl_chip_page_dump_num = EXP_APMEM_CTRL_CHIP_PAGE_DUMP_NUM, + .emi_apmem_ctrl_assert_flag = EXP_APMEM_CTRL_ASSERT_FLAG, +}; + +CONSYS_EMI_ADDR_INFO mtk_wcn_emi_addr_info = { + .emi_phy_addr = CONSYS_EMI_FW_PHY_BASE, + .paged_trace_off = CONSYS_EMI_PAGED_TRACE_OFFSET, + .paged_dump_off = CONSYS_EMI_PAGED_DUMP_OFFSET, + .full_dump_off = CONSYS_EMI_FULL_DUMP_OFFSET, + .p_ecso = &mtk_wcn_emi_state_off, + .emi_core_dump_offset = CONSYS_EMI_COREDUMP_OFFSET, +}; + +WMT_CONSYS_IC_OPS consys_ic_ops = { + .consys_ic_clock_buffer_ctrl = consys_clock_buffer_ctrl, + .consys_ic_hw_reset_bit_set = consys_hw_reset_bit_set, + .consys_ic_hw_spm_clk_gating_enable = consys_hw_spm_clk_gating_enable, + .consys_ic_hw_power_ctrl = consys_hw_power_ctrl, + .consys_ic_ahb_clock_ctrl = consys_ahb_clock_ctrl, + .polling_consys_ic_chipid = polling_consys_chipid, + .consys_ic_acr_reg_setting = consys_acr_reg_setting, + .consys_ic_afe_reg_setting = consys_afe_reg_setting, + .consys_ic_hw_vcn18_ctrl = consys_hw_vcn18_ctrl, + .consys_ic_vcn28_hw_mode_ctrl = consys_vcn28_hw_mode_ctrl, + .consys_ic_hw_vcn28_ctrl = consys_hw_vcn28_ctrl, + .consys_ic_hw_wifi_vcn33_ctrl = consys_hw_wifi_vcn33_ctrl, + .consys_ic_hw_bt_vcn33_ctrl = consys_hw_bt_vcn33_ctrl, + .consys_ic_soc_chipid_get = consys_soc_chipid_get, + .consys_ic_emi_mpu_set_region_protection = consys_emi_mpu_set_region_protection, + .consys_ic_emi_set_remapping_reg = consys_emi_set_remapping_reg, + .ic_bt_wifi_share_v33_spin_lock_init = bt_wifi_share_v33_spin_lock_init, + .consys_ic_clk_get_from_dts = consys_clk_get_from_dts, + .consys_ic_pmic_get_from_dts = consys_pmic_get_from_dts, + .consys_ic_read_irq_info_from_dts = consys_read_irq_info_from_dts, + .consys_ic_read_reg_from_dts = consys_read_reg_from_dts, + .consys_ic_read_cpupcr = consys_read_cpupcr, + .ic_force_trigger_assert_debug_pin = force_trigger_assert_debug_pin, + .consys_ic_co_clock_type = consys_co_clock_type, + .consys_ic_soc_get_emi_phy_add = consys_soc_get_emi_phy_add, + .consys_ic_emi_coredump_remapping = consys_emi_coredump_remapping, + .consys_ic_reset_emi_coredump = consys_reset_emi_coredump, + .consys_ic_get_options = consys_get_options, +}; + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +UINT32 gJtagCtrl; +#if CONSYS_ENALBE_SET_JTAG +#define JTAG_ADDR1_BASE 0x10002000 +PINT8 jtag_addr1 = (PINT8)JTAG_ADDR1_BASE; +#define JTAG1_REG_WRITE(addr, value) \ + writel(value, ((PUINT32)(jtag_addr1+(addr-JTAG_ADDR1_BASE)))) +#define JTAG1_REG_READ(addr) \ + readl(((PUINT32)(jtag_addr1+(addr-JTAG_ADDR1_BASE)))) +#endif + +INT32 mtk_wcn_consys_jtag_set_for_mcu(VOID) +{ +#if CONSYS_ENALBE_SET_JTAG + + if (gJtagCtrl) { +#if 0 + INT32 iRet = -1; + + WMT_PLAT_PR_INFO("WCN jtag_set_for_mcu start...\n"); + jtag_addr1 = ioremap(JTAG_ADDR1_BASE, 0x5000); + if (jtag_addr1 == 0) { + WMT_PLAT_PR_ERR("remap jtag_addr1 fail!\n"); + return iRet; + } + WMT_PLAT_PR_INFO("jtag_addr1 = 0x%p\n", jtag_addr1); + + JTAG1_REG_WRITE(0x100053c4, 0x11111100); + JTAG1_REG_WRITE(0x100053d4, 0x00111111); + + /*Enable IES of all pins */ + JTAG1_REG_WRITE(0x10002014, 0x00000003); + JTAG1_REG_WRITE(0x10005334, 0x55000000); + JTAG1_REG_WRITE(0x10005344, 0x00555555); + JTAG1_REG_WRITE(0x10005008, 0xc0000000); + JTAG1_REG_WRITE(0x10005018, 0x0000000d); + JTAG1_REG_WRITE(0x10005014, 0x00000032); + JTAG1_REG_WRITE(0x100020a4, 0x000000ff); + JTAG1_REG_WRITE(0x100020d4, 0x000000b4); + + JTAG1_REG_WRITE(0x100020d8, 0x0000004b); + + WMT_PLAT_PR_INFO("WCN jtag set for mcu start...\n"); + kal_uint32 tmp = 0; + kal_int32 addr = 0; + kal_int32 remap_addr1 = 0; + kal_int32 remap_addr2 = 0; + + remap_addr1 = ioremap(JTAG_ADDR1_BASE, 0x1000); + if (remap_addr1 == 0) { + WMT_PLAT_PR_ERR("remap jtag_addr1 fail!\n"); + return -1; + } + + remap_addr2 = ioremap(JTAG_ADDR2_BASE, 0x100); + if (remap_addr2 == 0) { + WMT_PLAT_PR_ERR("remap jtag_addr2 fail!\n"); + return -1; + } + + /*Pinmux setting for MT6625 I/F */ + addr = remap_addr1 + 0x03C0; + tmp = DRV_Reg32(addr); + tmp = tmp & 0xff; + tmp = tmp | 0x11111100; + DRV_WriteReg32(addr, tmp); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%08x, 0x%08x)", addr, DRV_Reg32(addr)); + + addr = remap_addr1 + 0x03D0; + tmp = DRV_Reg32(addr); + tmp = tmp & 0xff000000; + tmp = tmp | 0x00111111; + DRV_WriteReg32(addr, tmp); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%08x, 0x%08x)", addr, DRV_Reg32(addr)); + + /*AP GPIO Setting 1 */ + /*Enable IES */ + /* addr = 0x10002014; */ + addr = remap_addr2 + 0x0014; + tmp = 0x00000003; + DRV_WriteReg32(addr, tmp); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%08x, 0x%08x)", addr, DRV_Reg32(addr)); + /*GPIO mode setting */ + /* addr = 0x10005334; */ + addr = remap_addr1 + 0x0334; + tmp = 0x55000000; + DRV_WriteReg32(addr, tmp); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%08x, 0x%08x)", addr, DRV_Reg32(addr)); + + /* addr = 0x10005344; */ + addr = remap_addr1 + 0x0344; + tmp = 0x00555555; + DRV_WriteReg32(addr, tmp); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%08x, 0x%08x)", addr, DRV_Reg32(addr)); + /*GPIO direction control */ + /* addr = 0x10005008; */ + addr = remap_addr1 + 0x0008; + tmp = 0xc0000000; + DRV_WriteReg32(addr, tmp); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%08x, 0x%08x)", addr, DRV_Reg32(addr)); + + /* addr = 0x10005018; */ + addr = remap_addr1 + 0x0018; + tmp = 0x0000000d; + DRV_WriteReg32(addr, tmp); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%08x, 0x%08x)", addr, DRV_Reg32(addr)); + + /* addr = 0x10005014; */ + addr = remap_addr1 + 0x0014; + tmp = 0x00000032; + DRV_WriteReg32(addr, tmp); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%08x, 0x%08x)", addr, DRV_Reg32(addr)); + + /*PULL Enable */ + /* addr = 0x100020a4; */ + addr = remap_addr2 + 0x00a4; + tmp = 0x000000ff; + DRV_WriteReg32(addr, tmp); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%08x, 0x%08x)", addr, DRV_Reg32(addr)); + + /*PULL select enable */ + /* addr = 0x100020d4; */ + addr = remap_addr2 + 0x00d4; + tmp = 0x000000b4; + DRV_WriteReg32(addr, tmp); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%08x, 0x%08x)", addr, DRV_Reg32(addr)); + + /* addr = 0x100020d8; */ + addr = remap_addr2 + 0x00d8; + tmp = 0x0000004b; + DRV_WriteReg32(addr, tmp); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%08x, 0x%08x)", addr, DRV_Reg32(addr)); +#endif + } +#endif + return 0; +} + +UINT32 mtk_wcn_consys_jtag_flag_ctrl(UINT32 en) +{ + WMT_PLAT_PR_INFO("%s jtag set for MCU\n", en ? "enable" : "disable"); + gJtagCtrl = en; + return 0; +} + +static INT32 consys_clk_get_from_dts(struct platform_device *pdev) +{ +#ifdef CONFIG_OF /*use DT */ +#if !defined(CONFIG_MTK_CLKMGR) + clk_scp_conn_main = devm_clk_get(&pdev->dev, "conn"); + if (IS_ERR(clk_scp_conn_main)) { + WMT_PLAT_PR_ERR("[CCF]cannot get clk_scp_conn_main clock.\n"); + return PTR_ERR(clk_scp_conn_main); + } + WMT_PLAT_PR_DBG("[CCF]clk_scp_conn_main=%p\n", clk_scp_conn_main); +#if 0 + clk_infra_conn_main = devm_clk_get(&pdev->dev, "infra-sys-conn-main"); + if (IS_ERR(clk_infra_conn_main)) { + WMT_PLAT_PR_ERR("[CCF]cannot get clk_infra_conn_main clock.\n"); + return PTR_ERR(clk_infra_conn_main); + } + WMT_PLAT_PR_DBG("[CCF]clk_infra_conn_main=%p\n", clk_infra_conn_main); +#endif + +#endif /* !defined(CONFIG_MTK_LEGACY) */ +#endif + return 0; +} + +static INT32 consys_pmic_get_from_dts(struct platform_device *pdev) +{ +#ifdef CONFIG_OF /*use DT */ +#if CONSYS_PMIC_CTRL_ENABLE +#if !defined(CONFIG_MTK_LEGACY) + reg_VCN18 = regulator_get(&pdev->dev, "vcn18"); + if (!reg_VCN18) + WMT_PLAT_PR_ERR("Regulator_get VCN_1V8 fail\n"); + reg_VCN28 = regulator_get(&pdev->dev, "vcn28"); + if (!reg_VCN28) + WMT_PLAT_PR_ERR("Regulator_get VCN_2V8 fail\n"); + reg_VCN33_BT = regulator_get(&pdev->dev, "vcn33_bt"); + if (!reg_VCN33_BT) + WMT_PLAT_PR_ERR("Regulator_get VCN33_BT fail\n"); + reg_VCN33_WIFI = regulator_get(&pdev->dev, "vcn33_wifi"); + if (!reg_VCN33_WIFI) + WMT_PLAT_PR_ERR("Regulator_get VCN33_WIFI fail\n"); +#endif +#endif +#endif + return 0; +} + +static INT32 consys_co_clock_type(VOID) +{ + UINT32 retval = 0; + UINT32 back_up = 0; + UINT32 co_clock_type = 0; + + /* co-clock auto detection:backup cw15,write cw15,read cw16,restore cw15, */ + KERNEL_pmic_read_interface(PMIC_DCXO_CW15, &retval, 0xFFFF, 0); + back_up = retval; + KERNEL_pmic_config_interface(PMIC_DCXO_CW15, PMIC_DCXO_CW15_VAL, 0xFFFF, 0); + KERNEL_pmic_read_interface(PMIC_DCXO_CW16, &retval, 0xFFFF, 0); + KERNEL_pmic_config_interface(PMIC_DCXO_CW15, back_up, 0xFFFF, 0); + if ((retval & AP_CONSYS_NOCO_CLOCK_BITA) || (retval & AP_CONSYS_NOCO_CLOCK_BITB)) { + co_clock_type = 0; + WMT_PLAT_PR_INFO("pmic_register_val = 0x%x, co_clock_type = %d,TCXO mode\n", retval, co_clock_type); + } else if ((retval & AP_CONSYS_CO_CLOCK_BITA) || (retval & AP_CONSYS_CO_CLOCK_BITB)) { + co_clock_type = 1; + WMT_PLAT_PR_INFO("pmic_register_val = 0x%x, co_clock_type = %d,co-TSX mode\n", retval, co_clock_type); + } + return co_clock_type; +} + +static INT32 consys_clock_buffer_ctrl(MTK_WCN_BOOL enable) +{ +#if CONSYS_CLOCK_BUF_CTRL + if (enable == MTK_WCN_BOOL_TRUE) + KERNEL_clk_buf_ctrl(CLK_BUF_CONN, 1); + else if (enable == MTK_WCN_BOOL_FALSE) + KERNEL_clk_buf_ctrl(CLK_BUF_CONN, 0); +#endif + return 0; +} + +static VOID consys_hw_reset_bit_set(MTK_WCN_BOOL enable) +{ +#ifdef CONFIG_OF /*use DT */ + if (enable) { + /*3.assert CONNSYS CPU SW reset 0x10007018 "[12]=1'b1 [31:24]=8'h88 (key)" */ + CONSYS_REG_WRITE((conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET), + CONSYS_REG_READ(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET) | + CONSYS_CPU_SW_RST_BIT | CONSYS_CPU_SW_RST_CTRL_KEY); + } else { + /*16.deassert CONNSYS CPU SW reset 0x10007018 "[12]=1'b0 [31:24] =8'h88 (key)" */ + CONSYS_REG_WRITE(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET, + (CONSYS_REG_READ(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET) & + ~CONSYS_CPU_SW_RST_BIT) | CONSYS_CPU_SW_RST_CTRL_KEY); + } +#else + if (enable) { + /*3.assert CONNSYS CPU SW reset 0x10007018 "[12]=1'b1 [31:24]=8'h88 (key)" */ + CONSYS_REG_WRITE(CONSYS_CPU_SW_RST_REG, + (CONSYS_REG_READ(CONSYS_CPU_SW_RST_REG) | CONSYS_CPU_SW_RST_BIT | + CONSYS_CPU_SW_RST_CTRL_KEY)); + } else { + /*16.deassert CONNSYS CPU SW reset 0x10007018 "[12]=1'b0 [31:24] =8'h88(key)" */ + CONSYS_REG_WRITE(CONSYS_CPU_SW_RST_REG, + (CONSYS_REG_READ(CONSYS_CPU_SW_RST_REG) & ~CONSYS_CPU_SW_RST_BIT) | + CONSYS_CPU_SW_RST_CTRL_KEY); + } +#endif +} + +static VOID consys_hw_spm_clk_gating_enable(VOID) +{ +#ifdef CONFIG_OF /*use DT */ + /*turn on SPM clock gating enable PWRON_CONFG_EN 0x10006000 32'h0b160001 */ + /*CONSYS_REG_WRITE((conn_reg.spm_base + CONSYS_PWRON_CONFG_EN_OFFSET), CONSYS_PWRON_CONFG_EN_VALUE);*/ +#else + /*turn on SPM clock gating enable PWRON_CONFG_EN 0x10006000 32'h0b160001 */ + CONSYS_REG_WRITE(CONSYS_PWRON_CONFG_EN_REG, CONSYS_PWRON_CONFG_EN_VALUE); +#endif +} + +static INT32 consys_hw_power_ctrl(MTK_WCN_BOOL enable) +{ +#if CONSYS_PWR_ON_OFF_API_AVAILABLE + INT32 iRet = -1; +#endif + + if (enable) { +#if CONSYS_PWR_ON_OFF_API_AVAILABLE +#if defined(CONFIG_MTK_CLKMGR) + iRet = conn_power_on(); /* consult clkmgr owner. */ + if (iRet) + WMT_PLAT_PR_ERR("conn_power_on fail(%d)\n", iRet); + WMT_PLAT_PR_DBG("conn_power_on ok\n"); +#else + iRet = clk_prepare_enable(clk_scp_conn_main); + if (iRet) + WMT_PLAT_PR_ERR("clk_prepare_enable(clk_scp_conn_main) fail(%d)\n", iRet); + WMT_PLAT_PR_DBG("clk_prepare_enable(clk_scp_conn_main) ok\n"); +#endif /* defined(CONFIG_MTK_LEGACY) */ + +#else + +#ifdef CONFIG_OF /*use DT */ + /*2.write conn_top1_pwr_on=1, power on conn_top1 0x1000632c [2] 1'b1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_SPM_PWR_ON_BIT); + /*3.read conn_top1_pwr_on_ack =1, power on ack ready 0x10006180 [1] */ + while (0 == (CONSYS_PWR_ON_ACK_BIT & CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_OFFSET))) + NULL; + /*5.write conn_top1_pwr_on_s=1, power on conn_top1 0x1000632c [3] 1'b1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_SPM_PWR_ON_S_BIT); + /*6.write conn_clk_dis=0, enable connsys clock 0x1000632c [4] 1'b0 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) & + ~CONSYS_CLK_CTRL_BIT); + /*7.wait 1us */ + udelay(1); + /*8.read conn_top1_pwr_on_ack_s =1, power on ack ready 0x10006184 [1] */ + while (0 == (CONSYS_PWR_CONN_ACK_S_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_S_OFFSET))) + NULL; + /*9.release connsys ISO, conn_top1_iso_en=0 0x1000632c [1] 1'b0 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) & + ~CONSYS_SPM_PWR_ISO_S_BIT); + /*10.release SW reset of connsys, conn_ap_sw_rst_b=1 0x1000632c[0] 1'b1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_SPM_PWR_RST_BIT); + /*disable AXI BUS protect 0x10001220[13] [14] */ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_TOPAXI_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_TOPAXI_PROT_EN_OFFSET) & + ~CONSYS_PROT_MASK); + while (CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_TOPAXI_PROT_STA1_OFFSET) & CONSYS_PROT_MASK) + NULL; +#else + /*2.write conn_top1_pwr_on=1, power on conn_top1 0x10006280 [2] 1'b1 */ + CONSYS_REG_WRITE(CONSYS_TOP1_PWR_CTRL_REG, + CONSYS_REG_READ(CONSYS_TOP1_PWR_CTRL_REG) | CONSYS_SPM_PWR_ON_BIT); + /*3.read conn_top1_pwr_on_ack =1, power on ack ready 0x1000660C [1] */ + while (0 == (CONSYS_PWR_ON_ACK_BIT & CONSYS_REG_READ(CONSYS_PWR_CONN_ACK_REG))) + NULL; + /*5.write conn_top1_pwr_on_s=1, power on conn_top1 0x10006280 [3] 1'b1 */ + CONSYS_REG_WRITE(CONSYS_TOP1_PWR_CTRL_REG, + CONSYS_REG_READ(CONSYS_TOP1_PWR_CTRL_REG) | CONSYS_SPM_PWR_ON_S_BIT); + /*6.write conn_clk_dis=0, enable connsys clock 0x10006280 [4] 1'b0 */ + CONSYS_REG_WRITE(CONSYS_TOP1_PWR_CTRL_REG, + CONSYS_REG_READ(CONSYS_TOP1_PWR_CTRL_REG) & ~CONSYS_CLK_CTRL_BIT); + /*7.wait 1us */ + udelay(1); + /*8.read conn_top1_pwr_on_ack_s =1, power on ack ready 0x10006610 [1] */ + while (0 == (CONSYS_PWR_CONN_ACK_S_BIT & CONSYS_REG_READ(CONSYS_PWR_CONN_ACK_S_REG))) + NULL; + /*9.release connsys ISO, conn_top1_iso_en=0 0x10006280 [1] 1'b0 */ + CONSYS_REG_WRITE(CONSYS_TOP1_PWR_CTRL_REG, + CONSYS_REG_READ(CONSYS_TOP1_PWR_CTRL_REG) & ~CONSYS_SPM_PWR_ISO_S_BIT); + /*10.release SW reset of connsys, conn_ap_sw_rst_b=1 0x10006280[0] 1'b1 */ + CONSYS_REG_WRITE(CONSYS_TOP1_PWR_CTRL_REG, + CONSYS_REG_READ(CONSYS_TOP1_PWR_CTRL_REG) | CONSYS_SPM_PWR_RST_BIT); + /*disable AXI BUS protect */ + CONSYS_REG_WRITE(CONSYS_TOPAXI_PROT_EN, CONSYS_REG_READ(CONSYS_TOPAXI_PROT_EN) & ~CONSYS_PROT_MASK); + while (CONSYS_REG_READ(CONSYS_TOPAXI_PROT_STA1) & CONSYS_PROT_MASK) + NULL; +#endif /* CONFIG_OF */ +#endif /* CONSYS_PWR_ON_OFF_API_AVAILABLE */ + } else { +#if CONSYS_PWR_ON_OFF_API_AVAILABLE +#if defined(CONFIG_MTK_CLKMGR) + /*power off connsys by API (MT6582, MT6572 are different) API: conn_power_off() */ + iRet = conn_power_off(); /* consult clkmgr owner */ + if (iRet) + WMT_PLAT_PR_ERR("conn_power_off fail(%d)\n", iRet); + WMT_PLAT_PR_DBG("conn_power_off ok\n"); +#else + clk_disable_unprepare(clk_scp_conn_main); + WMT_PLAT_PR_DBG("clk_disable_unprepare(clk_scp_conn_main) calling\n"); +#endif /* defined(CONFIG_MTK_LEGACY) */ + +#else + +#ifdef CONFIG_OF /*use DT */ + { + INT32 count = 0; + + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_TOPAXI_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_TOPAXI_PROT_EN_OFFSET) | + CONSYS_PROT_MASK); + while ((CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_TOPAXI_PROT_STA1_OFFSET) & + CONSYS_PROT_MASK) != CONSYS_PROT_MASK) { + count++; + if (count > 1000) + break; + } + } + /*release connsys ISO, conn_top1_iso_en=1 0x1000632c [1] 1'b1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_SPM_PWR_ISO_S_BIT); + /*assert SW reset of connsys, conn_ap_sw_rst_b=0 0x1000632c[0] 1'b0 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) & + ~CONSYS_SPM_PWR_RST_BIT); + /*write conn_clk_dis=1, disable connsys clock 0x1000632c [4] 1'b1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_CLK_CTRL_BIT); + /*wait 1us */ + udelay(1); + /*write conn_top1_pwr_on=0, power off conn_top1 0x1000632c [3:2] 2'b00 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) & + ~(CONSYS_SPM_PWR_ON_BIT | CONSYS_SPM_PWR_ON_S_BIT)); +#else + { + INT32 count = 0; + + CONSYS_REG_WRITE(CONSYS_TOPAXI_PROT_EN, + CONSYS_REG_READ(CONSYS_TOPAXI_PROT_EN) | CONSYS_PROT_MASK); + while ((CONSYS_REG_READ(CONSYS_TOPAXI_PROT_STA1) & CONSYS_PROT_MASK) != CONSYS_PROT_MASK) { + count++; + if (count > 1000) + break; + } + + } + /*release connsys ISO, conn_top1_iso_en=1 0x1000632c [1] 1'b1 */ + CONSYS_REG_WRITE(CONSYS_TOP1_PWR_CTRL_REG, + CONSYS_REG_READ(CONSYS_TOP1_PWR_CTRL_REG) | CONSYS_SPM_PWR_ISO_S_BIT); + /*assert SW reset of connsys, conn_ap_sw_rst_b=0 0x1000632c[0] 1'b0 */ + CONSYS_REG_WRITE(CONSYS_TOP1_PWR_CTRL_REG, + CONSYS_REG_READ(CONSYS_TOP1_PWR_CTRL_REG) & ~CONSYS_SPM_PWR_RST_BIT); + /*write conn_clk_dis=1, disable connsys clock 0x1000632c [4] 1'b1 */ + CONSYS_REG_WRITE(CONSYS_TOP1_PWR_CTRL_REG, + CONSYS_REG_READ(CONSYS_TOP1_PWR_CTRL_REG) | CONSYS_CLK_CTRL_BIT); + /*wait 1us */ + udelay(1); + /*write conn_top1_pwr_on=0, power off conn_top1 0x1000632c [3:2] 2'b00 */ + CONSYS_REG_WRITE(CONSYS_TOP1_PWR_CTRL_REG, CONSYS_REG_READ(CONSYS_TOP1_PWR_CTRL_REG) & + ~(CONSYS_SPM_PWR_ON_BIT | CONSYS_SPM_PWR_ON_S_BIT)); +#endif /* CONFIG_OF */ +#endif /* CONSYS_PWR_ON_OFF_API_AVAILABLE */ + } + +#if CONSYS_PWR_ON_OFF_API_AVAILABLE + return iRet; +#else + return 0; +#endif +} + +static INT32 consys_ahb_clock_ctrl(MTK_WCN_BOOL enable) +{ + return 0; +} + +static INT32 polling_consys_chipid(VOID) +{ + UINT32 retry = 10; + UINT32 consysHwChipId = 0; + +#ifdef CONFIG_OF /*use DT */ + /*12.poll CONNSYS CHIP ID until chipid is returned 0x18070008 */ + while (retry-- > 0) { + consysHwChipId = CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_CHIP_ID_OFFSET); + if (consysHwChipId == 0x0699) { + WMT_PLAT_PR_INFO("retry(%d)consys chipId(0x%08x)\n", retry, consysHwChipId); + break; + } + msleep(20); + } + + if ((retry == 0) || (consysHwChipId == 0)) { + WMT_PLAT_PR_ERR("Maybe has a consys power on issue,(0x%08x)\n", consysHwChipId); + WMT_PLAT_PR_INFO("reg dump:CONSYS_CPU_SW_RST_REG(0x%x)\n", + CONSYS_REG_READ(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET)); + WMT_PLAT_PR_INFO("reg dump:CONSYS_PWR_CONN_ACK_REG(0x%x)\n", + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_OFFSET)); + WMT_PLAT_PR_INFO("reg dump:CONSYS_PWR_CONN_ACK_S_REG(0x%x)\n", + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_S_OFFSET)); + WMT_PLAT_PR_INFO("reg dump:CONSYS_TOP1_PWR_CTRL_REG(0x%x)\n", + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET)); + } +#else + /*12.poll CONNSYS CHIP ID until 6739 is returned 0x18070008 32'h6739 */ + while (retry-- > 0) { + WMT_PLAT_PR_DBG("CONSYS_CHIP_ID_REG(0x%08x)", CONSYS_REG_READ(CONSYS_CHIP_ID_REG)); + consysHwChipId = CONSYS_REG_READ(CONSYS_CHIP_ID_REG); + if (consysHwChipId == 0x0699) { + WMT_PLAT_PR_INFO("retry(%d)consys chipId(0x%08x)\n", retry, consysHwChipId); + break; + } + msleep(20); + } + + if ((retry == 0) || (consysHwChipId == 0)) { + WMT_PLAT_PR_ERR("Maybe has a consys power on issue,(0x%08x)\n", consysHwChipId); + WMT_PLAT_PR_INFO("reg dump:CONSYS_CPU_SW_RST_REG(0x%x)\n", + CONSYS_REG_READ(CONSYS_CPU_SW_RST_REG)); + WMT_PLAT_PR_INFO("reg dump:CONSYS_PWR_CONN_ACK_REG(0x%x)\n", + CONSYS_REG_READ(CONSYS_PWR_CONN_ACK_REG)); + WMT_PLAT_PR_INFO("reg dump:CONSYS_PWR_CONN_ACK_S_REG(0x%x)\n", + CONSYS_REG_READ(CONSYS_PWR_CONN_ACK_S_REG)); + WMT_PLAT_PR_INFO("reg dump:CONSYS_TOP1_PWR_CTRL_REG(0x%x)\n", + CONSYS_REG_READ(CONSYS_TOP1_PWR_CTRL_REG)); + } +#endif + return 0; +} + +static VOID consys_acr_reg_setting(VOID) +{ + /* + *14.write 1 to conn_mcu_confg ACR[1] if real speed MBIST + *(default write "1") ACR 0x18070110[18] 1'b1 + *if this bit is 0, HW will do memory auto test under low CPU frequence (26M Hz) + *if this bit is 0, HW will do memory auto test under high CPU frequence(138M Hz) + *inclulding low CPU frequence + */ +#ifdef CONFIG_OF /*use DT */ + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_MCU_CFG_ACR_OFFSET, + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_MCU_CFG_ACR_OFFSET) | + CONSYS_MCU_CFG_ACR_MBIST_BIT); +#else + CONSYS_REG_WRITE(CONSYS_MCU_CFG_ACR_REG, + CONSYS_REG_READ(CONSYS_MCU_CFG_ACR_REG) | CONSYS_MCU_CFG_ACR_MBIST_BIT); +#endif +} + +static VOID consys_afe_reg_setting(VOID) +{ +#if CONSYS_AFE_REG_SETTING + UINT8 *consys_afe_reg_base = NULL; + UINT8 i = 0; + + /*15.default no need,update ANA_WBG(AFE) CR if needed, CONSYS_AFE_REG */ + consys_afe_reg_base = ioremap_nocache(CONSYS_AFE_REG_BASE, 0x100); + if (consys_afe_reg_base) { + CONSYS_REG_WRITE(consys_afe_reg_base + CONSYS_AFE_REG_WBG_AFE_01_OFFSET, + CONSYS_AFE_REG_WBG_AFE_01_VALUE); + CONSYS_REG_WRITE(consys_afe_reg_base + CONSYS_AFE_REG_WBG_PLL_03_OFFSET, + CONSYS_AFE_REG_WBG_PLL_03_VALUE); + CONSYS_REG_WRITE(consys_afe_reg_base + CONSYS_AFE_REG_WBG_PLL_05_OFFSET, + CONSYS_AFE_REG_WBG_PLL_05_VALUE); + CONSYS_REG_WRITE(consys_afe_reg_base + CONSYS_AFE_REG_WBG_WB_TX_01_OFFSET, + CONSYS_AFE_REG_WBG_WB_TX_01_VALUE); + + WMT_PLAT_PR_DBG("Dump AFE register\n"); + for (i = 0; i < 64; i++) { + WMT_PLAT_PR_DBG("reg:0x%08x|val:0x%08x\n", CONSYS_AFE_REG_BASE + 4*i, + CONSYS_REG_READ(consys_afe_reg_base + 4*i)); + } + iounmap(consys_afe_reg_base); + } else + WMT_PLAT_PR_ERR("AFE base(0x%x) ioremap fail!\n", CONSYS_AFE_REG_BASE); +#endif +} + +/* Wayne Chen - This function was copied from mt6759.c */ +static INT32 consys_hw_vcn18_ctrl(MTK_WCN_BOOL enable) +{ +#if CONSYS_PMIC_CTRL_ENABLE + if (enable) { + /*need PMIC driver provide new API protocol */ + /*1.AP power on VCN_1V8 LDO (with PMIC_WRAP API) VCN_1V8 */ +#if defined(CONFIG_MTK_PMIC_CHIP_MT6357) + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN18_EN, 1); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN18_SW_OP_EN, 1); +#else + KERNEL_pmic_set_register_value(MT6351_PMIC_RG_VCN18_ON_CTRL, 0); +#endif + /* VOL_DEFAULT, VOL_1200, VOL_1300, VOL_1500, VOL_1800... */ +#if defined(CONFIG_MTK_LEGACY) + hwPowerOn(MT6351_POWER_LDO_VCN18, VOL_1800 * 1000, "wcn_drv"); +#else + if (reg_VCN18) { + regulator_set_voltage(reg_VCN18, 1800000, 1800000); + if (regulator_enable(reg_VCN18)) + WMT_PLAT_PR_ERR("enable VCN18 fail\n"); + else + WMT_PLAT_PR_DBG("enable VCN18 ok\n"); + } +#endif + + if (reg_VCN33_BT) { + regulator_set_voltage(reg_VCN33_BT, 3300000, 3300000); + if (regulator_enable(reg_VCN33_BT)) + WMT_PLAT_PR_ERR("WMT do BT PMIC on fail!\n"); + } + +#if defined(CONFIG_MTK_PMIC_CHIP_MT6357) + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_HW0_OP_EN, 0); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_HW0_OP_CFG, 0); +#else + KERNEL_pmic_set_register_value(MT6351_PMIC_RG_VCN33_ON_CTRL_BT, 1); +#endif + } else { +#if defined(CONFIG_MTK_PMIC_CHIP_MT6357) + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN18_EN, 1); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN18_SW_OP_EN, 1); +#else + KERNEL_pmic_set_register_value(MT6351_PMIC_RG_VCN33_ON_CTRL_BT, 0); +#endif + if (reg_VCN33_BT) + regulator_disable(reg_VCN33_BT); + + /*AP power off MT6351L VCN_1V8 LDO */ +#if defined(CONFIG_MTK_PMIC_CHIP_MT6357) + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN18_EN, 1); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN18_SW_OP_EN, 1); +#else + KERNEL_pmic_set_register_value(MT6351_PMIC_RG_VCN18_ON_CTRL, 0); +#endif +#if defined(CONFIG_MTK_LEGACY) + hwPowerDown(MT6351_POWER_LDO_VCN18, "wcn_drv"); +#else + if (reg_VCN18) { + if (regulator_disable(reg_VCN18)) + WMT_PLAT_PR_ERR("disable VCN_1V8 fail!\n"); + else + WMT_PLAT_PR_DBG("disable VCN_1V8 ok\n"); + } +#endif + } +#endif + return 0; +} + +/* Wayne Chen - This function was copied from mt6759.c */ +static VOID consys_vcn28_hw_mode_ctrl(UINT32 enable) +{ +#if CONSYS_PMIC_CTRL_ENABLE + if (enable) { +#if defined(CONFIG_MTK_PMIC_CHIP_MT6357) + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN28_HW0_OP_EN, 1); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN28_HW0_OP_CFG, 0); +#else + KERNEL_pmic_set_register_value(MT6351_PMIC_RG_VCN28_ON_CTRL, 1); +#endif + } else { +#if defined(CONFIG_MTK_PMIC_CHIP_MT6357) + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN28_HW0_OP_EN, 0); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN28_HW0_OP_CFG, 0); +#else + KERNEL_pmic_set_register_value(MT6351_PMIC_RG_VCN28_ON_CTRL, 0); +#endif + } +#endif +} + +/* Wayne Chen - This function was copied from mt6759.c */ +static INT32 consys_hw_vcn28_ctrl(UINT32 enable) +{ +#if CONSYS_PMIC_CTRL_ENABLE + if (enable) { + /*in co-clock mode,need to turn on vcn28 when fm on */ + if (reg_VCN28) { + regulator_set_voltage(reg_VCN28, 2800000, 2800000); + if (regulator_enable(reg_VCN28)) + WMT_PLAT_PR_ERR("WMT do VCN28 PMIC on fail!\n"); + } + WMT_PLAT_PR_INFO("turn on vcn28 for fm/gps usage in co-clock mode\n"); + } else { + /*in co-clock mode,need to turn off vcn28 when fm off */ + if (reg_VCN28) + regulator_disable(reg_VCN28); + WMT_PLAT_PR_INFO("turn off vcn28 for fm/gps usage in co-clock mode\n"); + } +#endif + return 0; +} + +static INT32 consys_hw_bt_vcn33_ctrl(UINT32 enable) +{ +#if CONSYS_BT_WIFI_SHARE_V33 + /* spin_lock_irqsave(&gBtWifiV33.lock,gBtWifiV33.flags); */ + if (enable) { + if (gBtWifiV33.counter == 1) { + gBtWifiV33.counter++; + WMT_PLAT_PR_DBG("V33 has been enabled,counter(%d)\n", gBtWifiV33.counter); + } else if (gBtWifiV33.counter == 2) { + WMT_PLAT_PR_DBG("V33 has been enabled,counter(%d)\n", gBtWifiV33.counter); + } else { +#if CONSYS_PMIC_CTRL_ENABLE + /*do BT PMIC on,depenency PMIC API ready */ + /*switch BT PALDO control from SW mode to HW mode:0x416[5]-->0x1 */ + /* VOL_DEFAULT, VOL_3300, VOL_3400, VOL_3500, VOL_3600 */ + hwPowerOn(MT6351_POWER_LDO_VCN33_BT, VOL_3300 * 1000, "wcn_drv"); + mt6351_upmu_set_rg_vcn33_on_ctrl(1); +#endif + WMT_PLAT_PR_INFO("WMT do BT/WIFI v3.3 on\n"); + gBtWifiV33.counter++; + } + + } else { + if (gBtWifiV33.counter == 1) { + /*do BT PMIC off */ + /*switch BT PALDO control from HW mode to SW mode:0x416[5]-->0x0 */ +#if CONSYS_PMIC_CTRL_ENABLE + mt6351_upmu_set_rg_vcn33_on_ctrl(0); + hwPowerDown(MT6351_POWER_LDO_VCN33_BT, "wcn_drv"); +#endif + WMT_PLAT_PR_INFO("WMT do BT/WIFI v3.3 off\n"); + gBtWifiV33.counter--; + } else if (gBtWifiV33.counter == 2) { + gBtWifiV33.counter--; + WMT_PLAT_PR_DBG("V33 no need disabled,counter(%d)\n", gBtWifiV33.counter); + } else { + WMT_PLAT_PR_DBG("V33 has been disabled,counter(%d)\n", gBtWifiV33.counter); + } + + } + /* spin_unlock_irqrestore(&gBtWifiV33.lock,gBtWifiV33.flags); */ +#else + if (enable) { + /*do BT PMIC on,depenency PMIC API ready */ + /*switch BT PALDO control from SW mode to HW mode:0x416[5]-->0x1 */ +#if CONSYS_PMIC_CTRL_ENABLE + /* VOL_DEFAULT, VOL_3300, VOL_3400, VOL_3500, VOL_3600 */ +#if defined(CONFIG_MTK_LEGACY) + hwPowerOn(MT6351_POWER_LDO_VCN33_BT, VOL_3300 * 1000, "wcn_drv"); +#else + if (reg_VCN33_BT) { + regulator_set_voltage(reg_VCN33_BT, 3300000, 3300000); + if (regulator_enable(reg_VCN33_BT)) + WMT_PLAT_PR_ERR("WMT do BT PMIC on fail!\n"); + } +#endif + +#if defined(CONFIG_MTK_PMIC_CHIP_MT6357) + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_HW0_OP_EN, 1); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_HW0_OP_CFG, 0); +#else + KERNEL_pmic_set_register_value(MT6351_PMIC_RG_VCN33_ON_CTRL_BT, 1); +#endif + +#endif + WMT_PLAT_PR_DBG("WMT do BT PMIC on\n"); + } else { + /*do BT PMIC off */ + /*switch BT PALDO control from HW mode to SW mode:0x416[5]-->0x0 */ +#if CONSYS_PMIC_CTRL_ENABLE +#if defined(CONFIG_MTK_PMIC_CHIP_MT6357) + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_HW0_OP_EN, 0); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_HW0_OP_CFG, 0); +#else + KERNEL_pmic_set_register_value(MT6351_PMIC_RG_VCN33_ON_CTRL_BT, 0); +#endif +#if defined(CONFIG_MTK_LEGACY) + hwPowerDown(MT6351_POWER_LDO_VCN33_BT, "wcn_drv"); +#else + if (reg_VCN33_BT) + regulator_disable(reg_VCN33_BT); +#endif +#endif + WMT_PLAT_PR_DBG("WMT do BT PMIC off\n"); + } +#endif + + return 0; +} + +static INT32 consys_hw_wifi_vcn33_ctrl(UINT32 enable) +{ +#if CONSYS_BT_WIFI_SHARE_V33 + mtk_wcn_consys_hw_bt_paldo_ctrl(enable); +#else + if (enable) { + /*do WIFI PMIC on,depenency PMIC API ready */ + /*switch WIFI PALDO control from SW mode to HW mode:0x418[14]-->0x1 */ +#if CONSYS_PMIC_CTRL_ENABLE +#if defined(CONFIG_MTK_LEGACY) + hwPowerOn(MT6351_POWER_LDO_VCN33_WIFI, VOL_3300 * 1000, "wcn_drv"); +#else + if (reg_VCN33_WIFI) { + regulator_set_voltage(reg_VCN33_WIFI, 3300000, 3300000); + if (regulator_enable(reg_VCN33_WIFI)) + WMT_PLAT_PR_ERR("WMT do WIFI PMIC on fail!\n"); + } +#endif +#if defined(CONFIG_MTK_PMIC_CHIP_MT6357) + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_HW0_OP_EN, 1); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_HW0_OP_CFG, 0); +#else + KERNEL_pmic_set_register_value(MT6351_PMIC_RG_VCN33_ON_CTRL_WIFI, 1); +#endif +#endif + WMT_PLAT_PR_DBG("WMT do WIFI PMIC on\n"); + } else { + /*do WIFI PMIC off */ + /*switch WIFI PALDO control from HW mode to SW mode:0x418[14]-->0x0 */ +#if CONSYS_PMIC_CTRL_ENABLE +#if defined(CONFIG_MTK_PMIC_CHIP_MT6357) + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_HW0_OP_EN, 0); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_HW0_OP_CFG, 0); +#else + KERNEL_pmic_set_register_value(MT6351_PMIC_RG_VCN33_ON_CTRL_WIFI, 0); +#endif +#if defined(CONFIG_MTK_LEGACY) + hwPowerDown(MT6351_POWER_LDO_VCN33_WIFI, "wcn_drv"); +#else + if (reg_VCN33_WIFI) + regulator_disable(reg_VCN33_WIFI); +#endif + +#endif + WMT_PLAT_PR_DBG("WMT do WIFI PMIC off\n"); + } + +#endif + + return 0; +} + +static INT32 consys_emi_mpu_set_region_protection(VOID) +{ +#if CONSYS_EMI_MPU_SETTING + /*set MPU for EMI share Memory */ + WMT_PLAT_PR_INFO("setting MPU for EMI share memory\n"); + + /* 5 = Forbidden, 0 = No_protect */ + emi_mpu_set_region_protection(gConEmiPhyBase + SZ_1M / 2, + gConEmiPhyBase + gConEmiSize - 1, + 22, + SET_ACCESS_PERMISSON(LOCK, FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, + FORBIDDEN, NO_PROTECTION, FORBIDDEN, NO_PROTECTION)); +#endif + return 0; +} + +static UINT32 consys_emi_set_remapping_reg(VOID) +{ +#ifdef CONFIG_OF /*use DT */ + UINT32 addrPhy = 0; + + /*consys to ap emi remapping register:10001380, cal remapping address */ + addrPhy = (gConEmiPhyBase >> 21) & 0x1FFF; + + /*enable consys to ap emi remapping bit13 */ + addrPhy = addrPhy | 0x2000; + + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET) | addrPhy); + + WMT_PLAT_PR_INFO("CONSYS_EMI_MAPPING dump in restore cb(0x%08x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET)); +#endif + return 0; +} + +static INT32 bt_wifi_share_v33_spin_lock_init(VOID) +{ +#if CONSYS_BT_WIFI_SHARE_V33 + gBtWifiV33.counter = 0; + spin_lock_init(&gBtWifiV33.lock); +#endif + return 0; +} + +static INT32 consys_read_irq_info_from_dts(struct platform_device *pdev, PINT32 irq_num, PUINT32 irq_flag) +{ +#ifdef CONFIG_OF /*use DT */ + struct device_node *node; + UINT32 irq_info[3] = { 0, 0, 0 }; + + INT32 iret = -1; + + node = pdev->dev.of_node; + if (node) { + *irq_num = irq_of_parse_and_map(node, 0); + /* get the interrupt line behaviour */ + if (of_property_read_u32_array(node, "interrupts", irq_info, ARRAY_SIZE(irq_info))) { + WMT_PLAT_PR_ERR("get irq flags from DTS fail!!\n"); + return iret; + } + *irq_flag = irq_info[2]; + WMT_PLAT_PR_INFO("get irq id(%d) and irq trigger flag(%d) from DT\n", *irq_num, + *irq_flag); + } else { + WMT_PLAT_PR_ERR("[%s] can't find CONSYS compatible node\n", __func__); + return iret; + } +#endif + return 0; +} + +static INT32 consys_read_reg_from_dts(struct platform_device *pdev) +{ +#ifdef CONFIG_OF /*use DT */ + INT32 iRet = -1; + struct device_node *node = NULL; + + node = pdev->dev.of_node; + if (node) { + /* registers base address */ + conn_reg.mcu_base = (SIZE_T) of_iomap(node, 0); + WMT_PLAT_PR_DBG("Get mcu register base(0x%zx)\n", conn_reg.mcu_base); + conn_reg.ap_rgu_base = (SIZE_T) of_iomap(node, 1); + WMT_PLAT_PR_DBG("Get ap_rgu register base(0x%zx)\n", conn_reg.ap_rgu_base); + conn_reg.topckgen_base = (SIZE_T) of_iomap(node, 2); + WMT_PLAT_PR_DBG("Get topckgen register base(0x%zx)\n", conn_reg.topckgen_base); + conn_reg.spm_base = (SIZE_T) of_iomap(node, 3); + WMT_PLAT_PR_DBG("Get spm register base(0x%zx)\n", conn_reg.spm_base); + } else { + WMT_PLAT_PR_ERR("[%s] can't find CONSYS compatible node\n", __func__); + return iRet; + } +#endif + return 0; +} + +static VOID force_trigger_assert_debug_pin(VOID) +{ +#ifdef CONFIG_OF /*use DT */ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AP2CONN_OSC_EN_OFFSET) & ~CONSYS_AP2CONN_WAKEUP_BIT); + WMT_PLAT_PR_INFO("enable:dump CONSYS_AP2CONN_OSC_EN_REG(0x%x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET)); + usleep_range(64, 96); + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AP2CONN_OSC_EN_OFFSET) | CONSYS_AP2CONN_WAKEUP_BIT); + WMT_PLAT_PR_INFO("disable:dump CONSYS_AP2CONN_OSC_EN_REG(0x%x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET)); +#endif +} + +static UINT32 consys_read_cpupcr(VOID) +{ +#ifdef CONFIG_OF /*use DT */ + if (conn_reg.mcu_base == 0) + return 0; + + if (mtk_consys_check_reg_readable_by_addr(conn_reg.mcu_base + CONSYS_CPUPCR_OFFSET) == 0) + return 0; + + return CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_CPUPCR_OFFSET); +#endif +} + +static UINT32 consys_soc_chipid_get(VOID) +{ + return PLATFORM_SOC_CHIP; +} + +static P_CONSYS_EMI_ADDR_INFO consys_soc_get_emi_phy_add(VOID) +{ + return &mtk_wcn_emi_addr_info; +} + +P_WMT_CONSYS_IC_OPS mtk_wcn_get_consys_ic_ops(VOID) +{ + return &consys_ic_ops; +} + +static INT32 consys_emi_coredump_remapping(UINT8 __iomem **addr, UINT32 enable) +{ + if (enable) { + *addr = ioremap_nocache(gConEmiPhyBase + CONSYS_EMI_COREDUMP_OFFSET, CONSYS_EMI_MEM_SIZE); + if (*addr) { + WMT_PLAT_PR_INFO("COREDUMP EMI mapping OK virtual(0x%p) physical(0x%x)\n", + *addr, (UINT32) gConEmiPhyBase + CONSYS_EMI_COREDUMP_OFFSET); + memset_io(*addr, 0, CONSYS_EMI_MEM_SIZE); + } else { + WMT_PLAT_PR_ERR("EMI mapping fail\n"); + return -1; + } + } else { + if (*addr) { + iounmap(*addr); + *addr = NULL; + } + } + return 0; +} + +static INT32 consys_reset_emi_coredump(UINT8 __iomem *addr) +{ + if (!addr) { + WMT_PLAT_PR_ERR("get virtual address fail\n"); + return -1; + } + WMT_PLAT_PR_INFO("Reset EMI(0xF0080000 ~ 0xF0080400) and (0xF0088400 ~ 0xF0090400)\n"); + /* reset 0xF0080000 ~ 0xF0080400 (1K) */ + memset_io(addr, 0, 0x400); + /* reset 0xF0088400 ~ 0xF0090400 (32K) */ + memset_io(addr + CONSYS_EMI_PAGED_DUMP_OFFSET, 0, 0x8000); + return 0; +} + +static UINT64 consys_get_options(VOID) +{ + UINT64 options = OPT_POWER_ON_DLM_TABLE | + OPT_SET_MCUCLK_TABLE_1_2 | + OPT_WIFI_LTE_COEX | + OPT_INIT_COEX_AFTER_RF_CALIBRATION | + OPT_SET_OSC_TYPE | + OPT_SET_COREDUMP_LEVEL | + OPT_GPS_SYNC | + OPT_WIFI_LTE_COEX_TABLE_1 | + OPT_NORMAL_PATCH_DWN_0; + return options; +} + diff --git a/drivers/misc/mediatek/connectivity/common/common_main/platform/mt6761.c b/drivers/misc/mediatek/connectivity/common/common_main/platform/mt6761.c new file mode 100644 index 0000000000000000000000000000000000000000..f185e32a914c92d2221807998d91404cc60b4337 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/platform/mt6761.c @@ -0,0 +1,1431 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +#ifdef DFT_TAG +#undef DFT_TAG +#endif +#define DFT_TAG "[WMT-CONSYS-HW]" + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include +#include +#include +#include +#include +#include "connsys_debug_utility.h" +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH +#include "fw_log_wmt.h" +#endif +#include "osal_typedef.h" +#include "mt6761.h" +#include "mtk_wcn_consys_hw.h" +#include "wmt_ic.h" +#include "wmt_lib.h" +#include "stp_dbg.h" + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) +#include +#else +#include +#endif + +#ifdef CONFIG_MTK_EMI +#include +#endif + +#if CONSYS_PMIC_CTRL_ENABLE +#include +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) +#include +#include +#include +#else +#include +#endif +#endif + +#ifdef CONFIG_MTK_HIBERNATION +#include +#endif + +#include + +#define CONSYS_ENABLE_EMI_MPU 1 +#define REGION_CONN 25 +#define DOMAIN_AP 0 +#define DOMAIN_CONN 2 + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +static INT32 consys_clock_buffer_ctrl(MTK_WCN_BOOL enable); +static VOID consys_hw_reset_bit_set(MTK_WCN_BOOL enable); +static VOID consys_hw_spm_clk_gating_enable(VOID); +static INT32 consys_hw_power_ctrl(MTK_WCN_BOOL enable); +static INT32 consys_ahb_clock_ctrl(MTK_WCN_BOOL enable); +static INT32 polling_consys_chipid(VOID); +static VOID consys_acr_reg_setting(VOID); +static VOID consys_afe_reg_setting(VOID); +static INT32 consys_hw_vcn18_ctrl(MTK_WCN_BOOL enable); +static VOID consys_vcn28_hw_mode_ctrl(UINT32 enable); +static INT32 consys_hw_vcn28_ctrl(UINT32 enable); +static INT32 consys_hw_wifi_vcn33_ctrl(UINT32 enable); +static INT32 consys_hw_bt_vcn33_ctrl(UINT32 enable); +static UINT32 consys_soc_chipid_get(VOID); +static INT32 consys_emi_mpu_set_region_protection(VOID); +static UINT32 consys_emi_set_remapping_reg(VOID); +static INT32 bt_wifi_share_v33_spin_lock_init(VOID); +static INT32 consys_clk_get_from_dts(struct platform_device *pdev); +static INT32 consys_pmic_get_from_dts(struct platform_device *pdev); +static INT32 consys_read_irq_info_from_dts(struct platform_device *pdev, PINT32 irq_num, PUINT32 irq_flag); +static INT32 consys_read_reg_from_dts(struct platform_device *pdev); +static UINT32 consys_read_cpupcr(VOID); +static VOID force_trigger_assert_debug_pin(VOID); +static INT32 consys_co_clock_type(VOID); +static P_CONSYS_EMI_ADDR_INFO consys_soc_get_emi_phy_add(VOID); +static VOID consys_set_if_pinmux(MTK_WCN_BOOL enable); +static INT32 consys_dl_rom_patch(UINT32 ip_ver, UINT32 fw_ver); +static VOID consys_set_dl_rom_patch_flag(INT32 flag); +static INT32 consys_dedicated_log_path_init(struct platform_device *pdev); +static VOID consys_dedicated_log_path_deinit(VOID); +static INT32 consys_emi_coredump_remapping(UINT8 __iomem **addr, UINT32 enable); +static INT32 consys_reset_emi_coredump(UINT8 __iomem *addr); +static INT32 consys_check_reg_readable(VOID); +static INT32 consys_dump_osc_state(P_CONSYS_STATE state); +static VOID consys_clock_fail_dump(VOID); +static VOID consys_set_pdma_axi_rready_force_high(UINT32 enable); +static VOID consys_get_ant_sel_cr_addr(PUINT32 default_invert_cr, PUINT32 default_invert_bit); +static INT32 consys_is_host_csr(SIZE_T addr); +static INT32 consys_calibration_backup_restore_support(VOID); +static UINT64 consys_get_options(VOID); + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ +#if CONSYS_BT_WIFI_SHARE_V33 +struct bt_wifi_v33_status gBtWifiV33; +#endif + +/* CCF part */ +struct clk *clk_scp_conn_main; /*ctrl conn_power_on/off */ + +/* PMIC part */ +#if CONSYS_PMIC_CTRL_ENABLE +static struct regulator *reg_VCN18; +static struct regulator *reg_VCN28; +static struct regulator *reg_VCN33_BT; +static struct regulator *reg_VCN33_WIFI; +#endif + +EMI_CTRL_STATE_OFFSET mtk_wcn_emi_state_off = { + .emi_apmem_ctrl_state = EXP_APMEM_CTRL_STATE, + .emi_apmem_ctrl_host_sync_state = EXP_APMEM_CTRL_HOST_SYNC_STATE, + .emi_apmem_ctrl_host_sync_num = EXP_APMEM_CTRL_HOST_SYNC_NUM, + .emi_apmem_ctrl_chip_sync_state = EXP_APMEM_CTRL_CHIP_SYNC_STATE, + .emi_apmem_ctrl_chip_sync_num = EXP_APMEM_CTRL_CHIP_SYNC_NUM, + .emi_apmem_ctrl_chip_sync_addr = EXP_APMEM_CTRL_CHIP_SYNC_ADDR, + .emi_apmem_ctrl_chip_sync_len = EXP_APMEM_CTRL_CHIP_SYNC_LEN, + .emi_apmem_ctrl_chip_print_buff_start = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_START, + .emi_apmem_ctrl_chip_print_buff_len = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_LEN, + .emi_apmem_ctrl_chip_print_buff_idx = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_IDX, + .emi_apmem_ctrl_chip_int_status = EXP_APMEM_CTRL_CHIP_INT_STATUS, + .emi_apmem_ctrl_chip_paded_dump_end = EXP_APMEM_CTRL_CHIP_PAGED_DUMP_END, + .emi_apmem_ctrl_host_outband_assert_w1 = EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1, + .emi_apmem_ctrl_chip_page_dump_num = EXP_APMEM_CTRL_CHIP_PAGE_DUMP_NUM, + .emi_apmem_ctrl_assert_flag = EXP_APMEM_CTRL_ASSERT_FLAG, +}; + +CONSYS_EMI_ADDR_INFO mtk_wcn_emi_addr_info = { + .emi_phy_addr = CONSYS_EMI_FW_PHY_BASE, + .paged_trace_off = CONSYS_EMI_PAGED_TRACE_OFFSET, + .paged_dump_off = CONSYS_EMI_PAGED_DUMP_OFFSET, + .full_dump_off = CONSYS_EMI_FULL_DUMP_OFFSET, + .emi_remap_offset = CONSYS_EMI_MAPPING_OFFSET, + .emi_core_dump_offset = CONSYS_EMI_COREDUMP_OFFSET, + .p_ecso = &mtk_wcn_emi_state_off, + .pda_dl_patch_flag = 1, + .emi_met_size = 0x50000, + .emi_met_data_offset = CONSYS_EMI_MET_DATA_OFFSET, +}; + +WMT_CONSYS_IC_OPS consys_ic_ops = { + .consys_ic_clock_buffer_ctrl = consys_clock_buffer_ctrl, + .consys_ic_hw_reset_bit_set = consys_hw_reset_bit_set, + .consys_ic_hw_spm_clk_gating_enable = consys_hw_spm_clk_gating_enable, + .consys_ic_hw_power_ctrl = consys_hw_power_ctrl, + .consys_ic_ahb_clock_ctrl = consys_ahb_clock_ctrl, + .polling_consys_ic_chipid = polling_consys_chipid, + .consys_ic_acr_reg_setting = consys_acr_reg_setting, + .consys_ic_afe_reg_setting = consys_afe_reg_setting, + .consys_ic_hw_vcn18_ctrl = consys_hw_vcn18_ctrl, + .consys_ic_vcn28_hw_mode_ctrl = consys_vcn28_hw_mode_ctrl, + .consys_ic_hw_vcn28_ctrl = consys_hw_vcn28_ctrl, + .consys_ic_hw_wifi_vcn33_ctrl = consys_hw_wifi_vcn33_ctrl, + .consys_ic_hw_bt_vcn33_ctrl = consys_hw_bt_vcn33_ctrl, + .consys_ic_soc_chipid_get = consys_soc_chipid_get, + .consys_ic_emi_mpu_set_region_protection = consys_emi_mpu_set_region_protection, + .consys_ic_emi_set_remapping_reg = consys_emi_set_remapping_reg, + .ic_bt_wifi_share_v33_spin_lock_init = bt_wifi_share_v33_spin_lock_init, + .consys_ic_clk_get_from_dts = consys_clk_get_from_dts, + .consys_ic_pmic_get_from_dts = consys_pmic_get_from_dts, + .consys_ic_read_irq_info_from_dts = consys_read_irq_info_from_dts, + .consys_ic_read_reg_from_dts = consys_read_reg_from_dts, + .consys_ic_read_cpupcr = consys_read_cpupcr, + .ic_force_trigger_assert_debug_pin = force_trigger_assert_debug_pin, + .consys_ic_co_clock_type = consys_co_clock_type, + .consys_ic_soc_get_emi_phy_add = consys_soc_get_emi_phy_add, + .consys_ic_set_if_pinmux = consys_set_if_pinmux, + .consys_ic_set_dl_rom_patch_flag = consys_set_dl_rom_patch_flag, + .consys_ic_dedicated_log_path_init = consys_dedicated_log_path_init, + .consys_ic_dedicated_log_path_deinit = consys_dedicated_log_path_deinit, + .consys_ic_emi_coredump_remapping = consys_emi_coredump_remapping, + .consys_ic_reset_emi_coredump = consys_reset_emi_coredump, + .consys_ic_check_reg_readable = consys_check_reg_readable, + .consys_ic_dump_osc_state = consys_dump_osc_state, + .consys_ic_clock_fail_dump = consys_clock_fail_dump, + .consys_ic_set_pdma_axi_rready_force_high = consys_set_pdma_axi_rready_force_high, + .consys_ic_get_ant_sel_cr_addr = consys_get_ant_sel_cr_addr, + .consys_ic_is_host_csr = consys_is_host_csr, + .consys_ic_calibration_backup_restore = consys_calibration_backup_restore_support, + .consys_ic_get_options = consys_get_options, +}; + +static const struct connlog_emi_config connsys_fw_log_parameter = { + .emi_offset = 0x36500, + .emi_size_total = (192*1024),/* 192KB */ + .emi_size_mcu = (16*1024), + .emi_size_wifi = (64*1024), + .emi_size_bt = (64*1024), + .emi_size_gps = (32*1024), +}; + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +INT32 rom_patch_dl_flag = 1; +UINT32 gJtagCtrl; +UINT32 g_connsys_lp_dump_info[2]; + +#if CONSYS_ENALBE_SET_JTAG +#define JTAG_ADDR1_BASE 0x10005000 +#define JTAG_ADDR2_BASE 0x11E80000 +#define JTAG_ADDR3_BASE 0x11D20000 +#define AP2CONN_JTAG_2WIRE_OFFSET 0xF00 +#endif + +INT32 mtk_wcn_consys_jtag_set_for_mcu(VOID) +{ +#if CONSYS_ENALBE_SET_JTAG + INT32 ret = 0; + UINT32 tmp = 0; + PVOID addr = 0; + PVOID remap_addr1 = 0; + PVOID remap_addr2 = 0; + PVOID remap_addr3 = 0; + + if (gJtagCtrl) { + + remap_addr1 = ioremap(JTAG_ADDR1_BASE, 0x1000); + if (remap_addr1 == 0) { + WMT_PLAT_PR_ERR("remap jtag_addr1 fail!\n"); + ret = -1; + goto error; + } + + remap_addr2 = ioremap(JTAG_ADDR2_BASE, 0x100); + if (remap_addr2 == 0) { + WMT_PLAT_PR_ERR("remap jtag_addr2 fail!\n"); + ret = -1; + goto error; + } + + remap_addr3 = ioremap(JTAG_ADDR3_BASE, 0x100); + if (remap_addr3 == 0) { + WMT_PLAT_PR_ERR("remap jtag_addr3 fail!\n"); + ret = -1; + goto error; + } + + WMT_PLAT_PR_INFO("WCN jtag set for mcu start...\n"); + switch (gJtagCtrl) { + case 1: + /* 7-wire jtag pinmux setting*/ +#if 1 + /* PAD AUX Function Selection */ + addr = remap_addr1 + 0x320; + tmp = readl(addr); + tmp = tmp & 0x0000000f; + tmp = tmp | 0x33333330; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + /* PAD Driving Selection */ + addr = remap_addr2 + 0xA0; + tmp = readl(addr); + tmp = tmp & 0xfff00fff; + tmp = tmp | 0x00077000; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + /* PAD PULL Selection */ + addr = remap_addr2 + 0x60; + tmp = readl(addr); + tmp = tmp & 0xfffe03ff; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + addr = remap_addr2 + 0x60; + tmp = readl(addr); + tmp = tmp & 0xfff80fff; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + +#else + /* backup */ + /* PAD AUX Function Selection */ + addr = remap_addr1 + 0x310; + tmp = readl(addr); + tmp = tmp & 0xfffff000; + tmp = tmp | 0x00000444; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + addr = remap_addr1 + 0x3C0; + tmp = readl(addr); + tmp = tmp & 0xf00ff00f; + tmp = tmp | 0x04400440; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + /* PAD Driving Selection */ + addr = remap_addr3 + 0xA0; + tmp = readl(addr); + tmp = tmp & 0x0ffffff0; + tmp = tmp | 0x70000007; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + addr = remap_addr3 + 0xB0; + tmp = readl(addr); + tmp = tmp & 0xfff0f0ff; + tmp = tmp | 0x0007070f; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + /* PAD PULL Selection */ + addr = remap_addr3 + 0x60; + tmp = readl(addr); + tmp = tmp & 0xf333fffe; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); +#endif + break; + case 2: + /* 2-wire jtag pinmux setting*/ +#if 0 + CONSYS_SET_BIT(conn_reg.topckgen_base + AP2CONN_JTAG_2WIRE_OFFSET, 1 << 8); + addr = remap_addr1 + 0x340; + tmp = readl(addr); + tmp = tmp & 0xfff88fff; + tmp = tmp | 0x00034000; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); +#endif + break; + default: + WMT_PLAT_PR_INFO("unsupported options!\n"); + } + + } +#endif + +error: + + if (remap_addr1) + iounmap(remap_addr1); + if (remap_addr2) + iounmap(remap_addr2); + if (remap_addr3) + iounmap(remap_addr3); + + return ret; +} + +UINT32 mtk_wcn_consys_jtag_flag_ctrl(UINT32 en) +{ + WMT_PLAT_PR_INFO("%s jtag set for MCU\n", en ? "enable" : "disable"); + gJtagCtrl = en; + return 0; +} + +static INT32 consys_clk_get_from_dts(struct platform_device *pdev) +{ + clk_scp_conn_main = devm_clk_get(&pdev->dev, "conn"); + if (IS_ERR(clk_scp_conn_main)) { + WMT_PLAT_PR_ERR("[CCF]cannot get clk_scp_conn_main clock.\n"); + return PTR_ERR(clk_scp_conn_main); + } + WMT_PLAT_PR_DBG("[CCF]clk_scp_conn_main=%p\n", clk_scp_conn_main); + + return 0; +} + +static INT32 consys_pmic_get_from_dts(struct platform_device *pdev) +{ +#if CONSYS_PMIC_CTRL_ENABLE + reg_VCN18 = regulator_get(&pdev->dev, "vcn18"); + if (!reg_VCN18) + WMT_PLAT_PR_ERR("Regulator_get VCN_1V8 fail\n"); + reg_VCN28 = regulator_get(&pdev->dev, "vcn28"); + if (!reg_VCN28) + WMT_PLAT_PR_ERR("Regulator_get VCN_2V8 fail\n"); + reg_VCN33_BT = regulator_get(&pdev->dev, "vcn33_bt"); + if (!reg_VCN33_BT) + WMT_PLAT_PR_ERR("Regulator_get VCN33_BT fail\n"); + reg_VCN33_WIFI = regulator_get(&pdev->dev, "vcn33_wifi"); + if (!reg_VCN33_WIFI) + WMT_PLAT_PR_ERR("Regulator_get VCN33_WIFI fail\n"); +#endif + return 0; +} + +static INT32 consys_co_clock_type(VOID) +{ + return 0; +} + +static INT32 consys_clock_buffer_ctrl(MTK_WCN_BOOL enable) +{ + if (enable) + KERNEL_clk_buf_ctrl(CLK_BUF_CONN, true); /*open XO_WCN*/ + else + KERNEL_clk_buf_ctrl(CLK_BUF_CONN, false); /*close XO_WCN*/ + + return 0; +} + +static VOID consys_set_if_pinmux(MTK_WCN_BOOL enable) +{ + UINT8 *consys_if_pinmux_reg_base = NULL; + + /* Switch D die pinmux for connecting A die */ + consys_if_pinmux_reg_base = ioremap_nocache(CONSYS_IF_PINMUX_REG_BASE, 0x1000); + if (!consys_if_pinmux_reg_base) { + WMT_PLAT_PR_ERR("consys_if_pinmux_reg_base(%x) ioremap fail\n", CONSYS_IF_PINMUX_REG_BASE); + return; + } + + if (enable) { + CONSYS_REG_WRITE(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_01_OFFSET, + (CONSYS_REG_READ(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_01_OFFSET) & + CONSYS_IF_PINMUX_01_MASK) | CONSYS_IF_PINMUX_01_VALUE); + CONSYS_REG_WRITE(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_02_OFFSET, + (CONSYS_REG_READ(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_02_OFFSET) & + CONSYS_IF_PINMUX_02_MASK) | CONSYS_IF_PINMUX_02_VALUE); + } else { + CONSYS_REG_WRITE(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_01_OFFSET, + CONSYS_REG_READ(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_01_OFFSET) & + CONSYS_IF_PINMUX_01_MASK); + CONSYS_REG_WRITE(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_02_OFFSET, + CONSYS_REG_READ(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_02_OFFSET) & + CONSYS_IF_PINMUX_02_MASK); + } + + if (consys_if_pinmux_reg_base) + iounmap(consys_if_pinmux_reg_base); +} + +static VOID consys_hw_reset_bit_set(MTK_WCN_BOOL enable) +{ + UINT32 consys_ver_id = 0; + UINT32 cnt = 0; + UINT32 pre_ver_id = 0xFFFFFFFF; + + if (enable) { + /*3.assert CONNSYS CPU SW reset 0x10007018 "[12]=1'b1 [31:24]=8'h88 (key)" */ + CONSYS_REG_WRITE((conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET), + CONSYS_REG_READ(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET) | + CONSYS_CPU_SW_RST_BIT | CONSYS_CPU_SW_RST_CTRL_KEY); + } else { + /*16.deassert CONNSYS CPU SW reset 0x10007018 "[12]=1'b0 [31:24] =8'h88 (key)" */ + CONSYS_REG_WRITE(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET, + (CONSYS_REG_READ(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET) & + ~CONSYS_CPU_SW_RST_BIT) | CONSYS_CPU_SW_RST_CTRL_KEY); + + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_base + 0x600); + while (consys_ver_id != 0x1D1E) { + if (cnt > 10) + break; + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_base + 0x600); + if (pre_ver_id != consys_ver_id) { + pre_ver_id = consys_ver_id; + WMT_PLAT_PR_INFO("0x18002600(0x%x), 0x1800216c(0x%x), 0x18007104(0x%x)\n", + consys_ver_id, CONSYS_REG_READ(conn_reg.mcu_base + 0x16c), + CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + CONSYS_CPUPCR_OFFSET)); + } + msleep(20); + cnt++; + } + } +} + +static VOID consys_hw_spm_clk_gating_enable(VOID) +{ +} + +static INT32 consys_hw_power_ctrl(MTK_WCN_BOOL enable) +{ +#if CONSYS_PWR_ON_OFF_API_AVAILABLE + INT32 iRet = 0; +#else + INT32 value = 0; + INT32 i = 0; +#endif + + if (enable) { +#if CONSYS_PWR_ON_OFF_API_AVAILABLE + iRet = clk_prepare_enable(clk_scp_conn_main); + if (iRet) + WMT_PLAT_PR_ERR("clk_prepare_enable(clk_scp_conn_main) fail(%d)\n", iRet); + WMT_PLAT_PR_DBG("clk_prepare_enable(clk_scp_conn_main) ok\n"); +#else + /* turn on SPM clock gating enable PWRON_CONFG_EN 0x10006000 32'h0b160001 */ + CONSYS_REG_WRITE((conn_reg.spm_base + CONSYS_PWRON_CONFG_EN_OFFSET), + (CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWRON_CONFG_EN_OFFSET) & + 0x0000FFFF) | CONSYS_PWRON_CONFG_EN_VALUE); + + /*write assert "conn_top_on" primary part power on, set "connsys_on_domain_pwr_on"=1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_SPM_PWR_ON_BIT); + /*read check "conn_top_on" primary part power status, check "connsys_on_domain_pwr_ack"=1 */ + value = CONSYS_PWR_ON_ACK_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_OFFSET); + while (value == 0) + value = CONSYS_PWR_ON_ACK_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_OFFSET); + /*write assert "conn_top_on" secondary part power on, set "connsys_on_domain_pwr_on_s"=1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_SPM_PWR_ON_S_BIT); + /*read check "conn_top_on" secondary part power status, check "connsys_on_domain_pwr_ack_s"=1 */ + value = CONSYS_PWR_ON_ACK_S_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_S_OFFSET); + while (value == 0) + value = CONSYS_PWR_ON_ACK_S_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_S_OFFSET); + /*write turn on AP-to-CONNSYS bus clock, set "conn_clk_dis"=0 (apply this for bus + *clock toggling) + */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) & + ~CONSYS_CLK_CTRL_BIT); + /*wait 1us*/ + udelay(1); + /*de-assert "conn_top_on" isolation, set "connsys_iso_en"=0 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) & + ~CONSYS_SPM_PWR_ISO_S_BIT); + /*read check "conn_top_off" primary part power status, check + *"connsys_off_domain_pwr_ack"=1 + */ + value = CONSYS_TOP2_PWR_ON_ACK_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_OFFSET); + while (value == 0) + value = CONSYS_TOP2_PWR_ON_ACK_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_OFFSET); + /*read check "conn_top_off" secondary part power status, check + *"connsys_off_domain_pwr_ack_s"=1 + */ + value = CONSYS_TOP2_PWR_ON_ACK_S_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_S_OFFSET); + while (value == 0) + value = CONSYS_TOP2_PWR_ON_ACK_S_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_S_OFFSET); + + /*de-assert CONNSYS S/W reset, set "ap_sw_rst_b"=1 */ + CONSYS_REG_WRITE(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET, + (CONSYS_REG_READ(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET) & + ~CONSYS_SW_RST_BIT) | CONSYS_CPU_SW_RST_CTRL_KEY); + + /*Turn off AHB bus sleep protect (AP2CONN AHB Bus protect) (apply this for INFRA AHB + *bus accessing when CONNSYS had been turned on) + */ + /*disable AHBAXI BUS protect 10001220 [13][14] */ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_EN_OFFSET) & + ~CONSYS_PROT_MASK); + value = ~CONSYS_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_STA_OFFSET); + i = 0; + while (value == 0 || i > 10) { + value = ~CONSYS_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_STA_OFFSET); + i++; + } + /*Disable AXI TX bus sleep protect (CONN2AP AXI Tx Bus protect) (disable sleep + * protection when CONNSYS had been turned on) + * Note : Should turn off AXI Tx sleep protection after AXI Rx sleep protection has + * been turn off. + */ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AXI_TX_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AXI_TX_PROT_EN_OFFSET) & + ~CONSYS_TX_PROT_MASK); + value = ~CONSYS_TX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AXI_TX_PROT_STA_OFFSET); + i = 0; + while (value == 0 || i > 10) { + value = ~CONSYS_TX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AXI_TX_PROT_STA_OFFSET); + i++; + } + /*SPM apsrc/ddr_en hardware mask disable & wait cycle setting*/ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_SPM_APSRC_OFFSET, CONSYS_SPM_APSRC_VALUE); + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_SPM_DDR_EN_OFFSET, CONSYS_SPM_DDR_EN_VALUE); +#endif /* CONSYS_PWR_ON_OFF_API_AVAILABLE */ + } else { +#if CONSYS_PWR_ON_OFF_API_AVAILABLE + clk_disable_unprepare(clk_scp_conn_main); + WMT_PLAT_PR_DBG("clk_disable_unprepare(clk_scp_conn_main) calling\n"); +#else + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_EN_OFFSET) & + CONSYS_PROT_MASK); + value = CONSYS_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_STA_OFFSET); + i = 0; + while (value == CONSYS_PROT_MASK || i > 10) { + value = CONSYS_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_STA_OFFSET); + i++; + } + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AXI_TX_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AXI_TX_PROT_EN_OFFSET) & + CONSYS_TX_PROT_MASK); + value = CONSYS_TX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AXI_TX_PROT_STA_OFFSET); + i = 0; + while (value == CONSYS_TX_PROT_MASK || i > 10) { + value = CONSYS_TX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AXI_TX_PROT_STA_OFFSET); + i++; + } + + /*release connsys ISO, conn_top1_iso_en=1 0x1000632C [1] 1'b1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_SPM_PWR_ISO_S_BIT); + /*de-assert CONNSYS S/W reset, set "ap_sw_rst_b"=1 */ + CONSYS_REG_WRITE(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET, + (CONSYS_REG_READ(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET) & + CONSYS_SW_RST_BIT) | CONSYS_CPU_SW_RST_CTRL_KEY); + /*write conn_clk_dis=1, disable connsys clock 0x1000632C [4] 1'b1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_CLK_CTRL_BIT); + /*wait 1us */ + udelay(1); + /*write conn_top1_pwr_on=0, power off conn_top1 0x1000632C [3:2] 2'b00 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) & + ~(CONSYS_SPM_PWR_ON_BIT | CONSYS_SPM_PWR_ON_S_BIT)); +#endif /* CONSYS_PWR_ON_OFF_API_AVAILABLE */ + } + +#if CONSYS_PWR_ON_OFF_API_AVAILABLE + return iRet; +#else + return 0; +#endif +} + +static INT32 consys_ahb_clock_ctrl(MTK_WCN_BOOL enable) +{ + return 0; +} + +static INT32 polling_consys_chipid(VOID) +{ + INT32 retry = 10; + UINT32 consys_ver_id = 0; + UINT32 consys_hw_ver = 0; + UINT32 consys_fw_ver = 0; + UINT8 *consys_reg_base = NULL; + UINT32 value = 0; + UINT32 pre_ver_id = 0xFFFFFFFF; + + /*12.poll CONNSYS CHIP ID until chipid is returned 0x18070008 */ + while (retry-- > 0) { + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_top_misc_off_base + CONSYS_IP_VER_OFFSET); + if (consys_ver_id == 0x10020300) { + WMT_PLAT_PR_INFO("retry(%d)consys version id(0x%08x)\n", retry, consys_ver_id); + consys_hw_ver = CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HW_ID_OFFSET); + WMT_PLAT_PR_INFO("consys HW version id(0x%x)\n", consys_hw_ver & 0xFFFF); + consys_fw_ver = CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_FW_ID_OFFSET); + WMT_PLAT_PR_INFO("consys FW version id(0x%x)\n", consys_fw_ver & 0xFFFF); + + if (consys_dl_rom_patch(consys_ver_id, consys_fw_ver) == 0) + break; + } else if (pre_ver_id != consys_ver_id) { + pre_ver_id = consys_ver_id; + WMT_PLAT_PR_ERR("Read CONSYS version id(0x%08x)", consys_ver_id); + } + msleep(20); + } + + if (retry <= 0) + return -1; + + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_top_misc_off_base + CONSYS_CONF_ID_OFFSET); + WMT_PLAT_PR_INFO("consys configuration id(0x%x)\n", consys_ver_id & 0xF); + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HW_ID_OFFSET); + WMT_PLAT_PR_INFO("consys HW version id(0x%x)\n", consys_ver_id & 0xFFFF); + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_FW_ID_OFFSET); + WMT_PLAT_PR_INFO("consys FW version id(0x%x)\n", consys_ver_id & 0xFFFF); + if (wmt_plat_soc_co_clock_flag_get()) { + consys_reg_base = ioremap_nocache(CONSYS_COCLOCK_STABLE_TIME_BASE, 0x100); + if (consys_reg_base) { + value = CONSYS_REG_READ(consys_reg_base); + value = (value & CONSYS_COCLOCK_STABLE_TIME_MASK) | CONSYS_COCLOCK_STABLE_TIME; + CONSYS_REG_WRITE(consys_reg_base, value); + value = CONSYS_REG_READ(consys_reg_base + CONSYS_COCLOCK_ACK_ENABLE_OFFSET); + value = value & (~CONSYS_COCLOCK_ACK_ENABLE_BIT); + CONSYS_REG_WRITE(consys_reg_base + CONSYS_COCLOCK_ACK_ENABLE_OFFSET, value); + iounmap(consys_reg_base); + } else + WMT_PLAT_PR_ERR("connsys co_clock stable time base(0x%x) ioremap fail!\n", + CONSYS_COCLOCK_STABLE_TIME_BASE); + } + /* EMI control CR setting(sw mode) */ + CONSYS_SET_BIT(conn_reg.mcu_base + CONSYS_SW_IRQ_OFFSET, CONSYS_EMI_CTRL_VALUE); + return 0; +} + +static VOID consys_acr_reg_setting(VOID) +{ +} + +static VOID consys_afe_reg_setting(VOID) +{ +#if CONSYS_AFE_REG_SETTING + UINT8 *consys_afe_reg_base = NULL; + + /*15.default no need,update ANA_WBG(AFE) CR if needed, CONSYS_AFE_REG */ + consys_afe_reg_base = ioremap_nocache(CONSYS_AFE_REG_BASE, 0x100); + if (consys_afe_reg_base) { + CONSYS_REG_WRITE(consys_afe_reg_base + CONSYS_AFE_RG_WBG_01_OFFSET, + CONSYS_AFE_RG_WBG_01_VALUE); + CONSYS_REG_WRITE(consys_afe_reg_base + CONSYS_AFE_RG_WBG_GPS_01_OFFSET, + CONSYS_AFE_RG_WBG_GPS_01_VALUE); + CONSYS_REG_WRITE(consys_afe_reg_base + CONSYS_AFE_RG_WBG_BT_RX_01_OFFSET, + CONSYS_AFE_RG_WBG_BT_RX_01_VALUE); + CONSYS_REG_WRITE(consys_afe_reg_base + CONSYS_AFE_RG_WBG_WF0_RX_01_OFFSET, + CONSYS_AFE_RG_WBG_WF0_RX_01_VALUE); + + iounmap(consys_afe_reg_base); + } else + WMT_PLAT_PR_ERR("AFE base(0x%x) ioremap fail!\n", CONSYS_AFE_REG_BASE); +#endif +} + +static INT32 consys_hw_vcn18_ctrl(MTK_WCN_BOOL enable) +{ +#if CONSYS_PMIC_CTRL_ENABLE + if (enable) { + /*need PMIC driver provide new API protocol */ + /*1.AP power on VCN_1V8 LDO (with PMIC_WRAP API) VCN_1V8 */ + /*set vcn18 SW mode*/ + if (reg_VCN18) { + regulator_set_voltage(reg_VCN18, 1800000, 1800000); + if (regulator_enable(reg_VCN18)) + WMT_PLAT_PR_ERR("enable VCN18 fail\n"); + else + WMT_PLAT_PR_DBG("enable VCN18 ok\n"); + } + if (reg_VCN33_BT) { + regulator_set_voltage(reg_VCN33_BT, 3300000, 3300000); + if (regulator_enable(reg_VCN33_BT)) + WMT_PLAT_PR_ERR("WMT do BT PMIC on fail!\n"); + } + + } else { + if (reg_VCN33_BT) + regulator_disable(reg_VCN33_BT); + + /*AP power off MT6351L VCN_1V8 LDO */ + if (reg_VCN18) { + if (regulator_disable(reg_VCN18)) + WMT_PLAT_PR_ERR("disable VCN_1V8 fail!\n"); + else + WMT_PLAT_PR_DBG("disable VCN_1V8 ok\n"); + } + } +#endif + return 0; +} + +static VOID consys_vcn28_hw_mode_ctrl(UINT32 enable) +{ +#if CONSYS_PMIC_CTRL_ENABLE +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) + if (!g_regmap) + return; + + if (enable) { + regmap_write(g_regmap, MT6357_LDO_VCN28_OP_EN_SET, 2); + regmap_write(g_regmap, MT6357_LDO_VCN28_OP_CFG_CLR, 2); + } else { + regmap_write(g_regmap, MT6357_LDO_VCN28_OP_EN_CLR, 2); + regmap_write(g_regmap, MT6357_LDO_VCN28_OP_CFG_CLR, 2); + } +#else + if (enable) { + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN28_HW0_OP_EN, 1); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN28_HW0_OP_CFG, 0); + } else { + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN28_HW0_OP_EN, 0); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN28_HW0_OP_CFG, 0); + } +#endif +#endif +} + +static INT32 consys_hw_vcn28_ctrl(UINT32 enable) +{ +#if CONSYS_PMIC_CTRL_ENABLE + if (enable) { + /*in co-clock mode,need to turn on vcn28 when fm on */ + if (reg_VCN28) { + regulator_set_voltage(reg_VCN28, 2800000, 2800000); + if (regulator_enable(reg_VCN28)) + WMT_PLAT_PR_ERR("WMT do VCN28 PMIC on fail!\n"); + } + WMT_PLAT_PR_INFO("turn on vcn28 for fm/gps usage in co-clock mode\n"); + } else { + /*in co-clock mode,need to turn off vcn28 when fm off */ + if (reg_VCN28) + regulator_disable(reg_VCN28); + WMT_PLAT_PR_INFO("turn off vcn28 for fm/gps usage in co-clock mode\n"); + } +#endif + return 0; +} + +static INT32 consys_hw_bt_vcn33_ctrl(UINT32 enable) +{ +#if 0 +#if CONSYS_BT_WIFI_SHARE_V33 + /* spin_lock_irqsave(&gBtWifiV33.lock,gBtWifiV33.flags); */ + if (enable) { + if (gBtWifiV33.counter == 1) { + gBtWifiV33.counter++; + WMT_PLAT_PR_DBG("V33 has been enabled,counter(%d)\n", gBtWifiV33.counter); + } else if (gBtWifiV33.counter == 2) { + WMT_PLAT_PR_DBG("V33 has been enabled,counter(%d)\n", gBtWifiV33.counter); + } else { +#if CONSYS_PMIC_CTRL_ENABLE + /*do BT PMIC on,depenency PMIC API ready */ + /*switch BT PALDO control from SW mode to HW mode:0x416[5]-->0x1 */ + /* VOL_DEFAULT, VOL_3300, VOL_3400, VOL_3500, VOL_3600 */ + hwPowerOn(MT6351_POWER_LDO_VCN33_BT, VOL_3300 * 1000, "wcn_drv"); + mt6351_upmu_set_rg_vcn33_on_ctrl(1); +#endif + WMT_PLAT_PR_INFO("WMT do BT/WIFI v3.3 on\n"); + gBtWifiV33.counter++; + } + + } else { + if (gBtWifiV33.counter == 1) { + /*do BT PMIC off */ + /*switch BT PALDO control from HW mode to SW mode:0x416[5]-->0x0 */ +#if CONSYS_PMIC_CTRL_ENABLE + mt6351_upmu_set_rg_vcn33_on_ctrl(0); + hwPowerDown(MT6351_POWER_LDO_VCN33_BT, "wcn_drv"); +#endif + WMT_PLAT_PR_INFO("WMT do BT/WIFI v3.3 off\n"); + gBtWifiV33.counter--; + } else if (gBtWifiV33.counter == 2) { + gBtWifiV33.counter--; + WMT_PLAT_PR_DBG("V33 no need disabled,counter(%d)\n", gBtWifiV33.counter); + } else { + WMT_PLAT_PR_DBG("V33 has been disabled,counter(%d)\n", gBtWifiV33.counter); + } + + } + /* spin_unlock_irqrestore(&gBtWifiV33.lock,gBtWifiV33.flags); */ +#else + if (enable) { + /*do BT PMIC on,depenency PMIC API ready */ + /*switch BT PALDO control from SW mode to HW mode:0x416[5]-->0x1 */ +#if CONSYS_PMIC_CTRL_ENABLE + /* VOL_DEFAULT, VOL_3300, VOL_3400, VOL_3500, VOL_3600 */ + if (reg_VCN33_BT) { + regulator_set_voltage(reg_VCN33_BT, 3300000, 3300000); + if (regulator_enable(reg_VCN33_BT)) + WMT_PLAT_PR_ERR("WMT do BT PMIC on fail!\n"); + } + + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_HW0_OP_EN, 1); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_HW0_OP_CFG, 0); +#endif + WMT_PLAT_PR_DBG("WMT do BT PMIC on\n"); + } else { + /*do BT PMIC off */ + /*switch BT PALDO control from HW mode to SW mode:0x416[5]-->0x0 */ +#if CONSYS_PMIC_CTRL_ENABLE + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_HW0_OP_EN, 0); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_HW0_OP_CFG, 0); + if (reg_VCN33_BT) + regulator_disable(reg_VCN33_BT); +#endif + WMT_PLAT_PR_DBG("WMT do BT PMIC off\n"); + } +#endif + +#endif + return 0; +} + +static INT32 consys_hw_wifi_vcn33_ctrl(UINT32 enable) +{ +#if 0 +#if CONSYS_BT_WIFI_SHARE_V33 + mtk_wcn_consys_hw_bt_paldo_ctrl(enable); +#else + if (enable) { + /*do WIFI PMIC on,depenency PMIC API ready */ + /*switch WIFI PALDO control from SW mode to HW mode:0x418[14]-->0x1 */ +#if CONSYS_PMIC_CTRL_ENABLE + if (reg_VCN33_WIFI) { + regulator_set_voltage(reg_VCN33_WIFI, 3300000, 3300000); + if (regulator_enable(reg_VCN33_WIFI)) + WMT_PLAT_PR_ERR("WMT do WIFI PMIC on fail!\n"); + } + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_HW0_OP_EN, 1); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_HW0_OP_CFG, 0); +#endif + WMT_PLAT_PR_DBG("WMT do WIFI PMIC on\n"); + } else { + /*do WIFI PMIC off */ + /*switch WIFI PALDO control from HW mode to SW mode:0x418[14]-->0x0 */ +#if CONSYS_PMIC_CTRL_ENABLE + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_HW0_OP_EN, 0); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_HW0_OP_CFG, 0); + if (reg_VCN33_WIFI) + regulator_disable(reg_VCN33_WIFI); +#endif + WMT_PLAT_PR_DBG("WMT do WIFI PMIC off\n"); + } + +#endif + +#endif + return 0; +} + +static INT32 consys_emi_mpu_set_region_protection(VOID) +{ +#if CONSYS_ENABLE_EMI_MPU + struct emi_region_info_t region_info; + + /*set MPU for EMI share Memory */ + WMT_PLAT_PR_INFO("setting MPU for EMI share memory\n"); + + region_info.start = gConEmiPhyBase; + region_info.end = gConEmiPhyBase + gConEmiSize - 1; + region_info.region = REGION_CONN; + SET_ACCESS_PERMISSION(region_info.apc, LOCK, + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, + NO_PROTECTION, FORBIDDEN, NO_PROTECTION); + emi_mpu_set_protection(®ion_info); +#endif + return 0; +} + +static UINT32 consys_emi_set_remapping_reg(VOID) +{ + UINT32 addrPhy = 0; + UINT32 value = 0; + + mtk_wcn_emi_addr_info.emi_ap_phy_addr = gConEmiPhyBase; + mtk_wcn_emi_addr_info.emi_size = gConEmiSize; + + /*consys to ap emi remapping register:10001380, cal remapping address */ + addrPhy = (gConEmiPhyBase >> 24) & 0xFFF; + value = CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET); + WMT_PLAT_PR_INFO("before CONSYS_EMI_MAPPING read:0x%zx, value:0x%x\n", + conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET, value); + + value = value & 0xFFFFF000; + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET, value | addrPhy); + WMT_PLAT_PR_INFO("CONSYS_EMI_MAPPING dump in restore cb(0x%08x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET)); + + /*Perisys Configuration Registers remapping*/ + addrPhy = ((0x10003000 >> 24) & 0xFFF) << 16; + value = CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_PERI_MAPPING_OFFSET); + value = value & 0xF000FFFF; + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_EMI_PERI_MAPPING_OFFSET, value | addrPhy); + + WMT_PLAT_PR_INFO("CONSYS_EMI_MAPPING dump in restore cb(0x%08x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_PERI_MAPPING_OFFSET)); + + mtk_wcn_emi_addr_info.emi_ram_bt_buildtime_offset = + CONSYS_EMI_RAM_BT_BUILDTIME_OFFSET; + mtk_wcn_emi_addr_info.emi_ram_wifi_buildtime_offset = + CONSYS_EMI_RAM_WIFI_BUILDTIME_OFFSET; + mtk_wcn_emi_addr_info.emi_ram_mcu_buildtime_offset = + CONSYS_EMI_RAM_MCU_BUILDTIME_OFFSET; + mtk_wcn_emi_addr_info.emi_patch_mcu_buildtime_offset = + CONSYS_EMI_PATCH_MCU_BUILDTIME_OFFSET; + + return 0; +} + +static INT32 bt_wifi_share_v33_spin_lock_init(VOID) +{ +#if CONSYS_BT_WIFI_SHARE_V33 + gBtWifiV33.counter = 0; + spin_lock_init(&gBtWifiV33.lock); +#endif + return 0; +} + +static INT32 consys_read_irq_info_from_dts(struct platform_device *pdev, PINT32 irq_num, PUINT32 irq_flag) +{ + struct device_node *node; + + node = pdev->dev.of_node; + if (node) { + *irq_num = irq_of_parse_and_map(node, 0); + *irq_flag = irq_get_trigger_type(*irq_num); + WMT_PLAT_PR_INFO("get irq id(%d) and irq trigger flag(%d) from DT\n", *irq_num, + *irq_flag); + } else { + WMT_PLAT_PR_ERR("[%s] can't find CONSYS compatible node\n", __func__); + return -1; + } + + return 0; +} + +static INT32 consys_read_reg_from_dts(struct platform_device *pdev) +{ + INT32 iRet = -1; + struct device_node *node = NULL; + + node = pdev->dev.of_node; + if (node) { + /* registers base address */ + conn_reg.mcu_base = (SIZE_T) of_iomap(node, MCU_BASE_INDEX); + conn_reg.ap_rgu_base = (SIZE_T) of_iomap(node, TOP_RGU_BASE_INDEX); + conn_reg.topckgen_base = (SIZE_T) of_iomap(node, INFRACFG_AO_BASE_INDEX); + conn_reg.spm_base = (SIZE_T) of_iomap(node, SPM_BASE_INDEX); + conn_reg.mcu_top_misc_off_base = (SIZE_T) of_iomap(node, MCU_TOP_MISC_OFF_BASE_INDEX); + conn_reg.mcu_conn_hif_on_base = (SIZE_T) of_iomap(node, MCU_CONN_HIF_ON_BASE_INDEX); + conn_reg.mcu_cfg_on_base = (SIZE_T) of_iomap(node, MCU_CFG_ON_BASE_INDEX); + conn_reg.mcu_cirq_base = (SIZE_T) of_iomap(node, MCU_CIRQ_BASE_INDEX); + conn_reg.mcu_top_misc_on_base = (SIZE_T) of_iomap(node, MCU_TOP_MISC_ON_BASE_INDEX); + conn_reg.mcu_conn_hif_pdma_base = (SIZE_T) of_iomap(node, MCU_CONN_HIF_PDMA_BASE_INDEX); + + WMT_PLAT_PR_DBG("Get base mcu(0x%zx), rgu(0x%zx), topckgen(0x%zx), spm(0x%zx)\n", + conn_reg.mcu_base, conn_reg.ap_rgu_base, + conn_reg.topckgen_base, conn_reg.spm_base); + WMT_PLAT_PR_DBG("Get base misc_off(0x%zx), hif_on(0x%zx), cfg_on(0x%zx), misc_on(0x%zx)\n", + conn_reg.mcu_top_misc_off_base, + conn_reg.mcu_conn_hif_on_base, + conn_reg.mcu_cfg_on_base, + conn_reg.mcu_top_misc_on_base); + WMT_PLAT_PR_DBG("Get hif_pdma(0x%zx)\n", + conn_reg.mcu_conn_hif_pdma_base); + } else { + WMT_PLAT_PR_ERR("[%s] can't find CONSYS compatible node\n", __func__); + return iRet; + } + + return 0; +} + +static VOID force_trigger_assert_debug_pin(VOID) +{ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AP2CONN_OSC_EN_OFFSET) & ~CONSYS_AP2CONN_WAKEUP_BIT); + WMT_PLAT_PR_INFO("enable:dump CONSYS_AP2CONN_OSC_EN_REG(0x%x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET)); + usleep_range(64, 96); + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AP2CONN_OSC_EN_OFFSET) | CONSYS_AP2CONN_WAKEUP_BIT); + WMT_PLAT_PR_INFO("disable:dump CONSYS_AP2CONN_OSC_EN_REG(0x%x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET)); +} + +static UINT32 consys_read_cpupcr(VOID) +{ + if (conn_reg.mcu_conn_hif_on_base == 0) + return 0; + + return CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + CONSYS_CPUPCR_OFFSET); +} + +static INT32 consys_is_host_csr(SIZE_T addr) +{ + SIZE_T start_offset = 0x000; + SIZE_T end_offset = 0xFFF; + + if (addr >= (CONN_HIF_ON_BASE_ADDR + start_offset) && + addr <= (CONN_HIF_ON_BASE_ADDR + end_offset)) + return 1; + + if (conn_reg.mcu_conn_hif_on_base != 0 && + addr >= (conn_reg.mcu_conn_hif_on_base + start_offset) && + addr <= (conn_reg.mcu_conn_hif_on_base + end_offset)) + return 1; + + return 0; +} + +static UINT32 consys_soc_chipid_get(VOID) +{ + return PLATFORM_SOC_CHIP; +} + +static P_CONSYS_EMI_ADDR_INFO consys_soc_get_emi_phy_add(VOID) +{ + return &mtk_wcn_emi_addr_info; +} + +P_WMT_CONSYS_IC_OPS mtk_wcn_get_consys_ic_ops(VOID) +{ + return &consys_ic_ops; +} + +static INT32 consys_dl_rom_patch(UINT32 ip_ver, UINT32 fw_ver) +{ + if (rom_patch_dl_flag) { + if (mtk_wcn_soc_rom_patch_dwn(ip_ver, fw_ver) == 0) + rom_patch_dl_flag = 1; + else + return -1; + } + + return 0; +} + +static VOID consys_set_dl_rom_patch_flag(INT32 flag) +{ + rom_patch_dl_flag = flag; +} + +static INT32 consys_dedicated_log_path_init(struct platform_device *pdev) +{ + struct device_node *node; + UINT32 irq_num; + UINT32 irq_flag; + INT32 iret = -1; + struct connlog_irq_config irq_config; + + memset(&irq_config, 0, sizeof(struct connlog_irq_config)); + node = pdev->dev.of_node; + if (node) { + irq_num = irq_of_parse_and_map(node, 2); + irq_flag = irq_get_trigger_type(irq_num); + WMT_PLAT_PR_INFO("get conn2ap_sw_irq id(%d) and irq trigger flag(%d) from DT\n", irq_num, + irq_flag); + } else { + WMT_PLAT_PR_ERR("[%s] can't find CONSYS compatible node\n", __func__); + return iret; + } + + irq_config.irq_num = irq_num; + irq_config.irq_flag = irq_flag; + irq_config.irq_callback = NULL; + + connsys_dedicated_log_path_apsoc_init( + gConEmiPhyBase, &connsys_fw_log_parameter, &irq_config); +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH + fw_log_wmt_init(); +#endif + return 0; +} + +static VOID consys_dedicated_log_path_deinit(VOID) +{ +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH + fw_log_wmt_deinit(); +#endif + connsys_dedicated_log_path_apsoc_deinit(); +} + +static INT32 consys_emi_coredump_remapping(UINT8 __iomem **addr, UINT32 enable) +{ + if (enable) { + *addr = ioremap_nocache(gConEmiPhyBase + CONSYS_EMI_COREDUMP_OFFSET, CONSYS_EMI_MEM_SIZE); + if (*addr) { + WMT_PLAT_PR_INFO("COREDUMP EMI mapping OK virtual(0x%p) physical(0x%x)\n", + *addr, (UINT32) gConEmiPhyBase + CONSYS_EMI_COREDUMP_OFFSET); + memset_io(*addr, 0, CONSYS_EMI_MEM_SIZE); + } else { + WMT_PLAT_PR_ERR("EMI mapping fail\n"); + return -1; + } + } else { + if (*addr) { + iounmap(*addr); + *addr = NULL; + } + } + return 0; +} + +static INT32 consys_reset_emi_coredump(UINT8 __iomem *addr) +{ + if (!addr) { + WMT_PLAT_PR_ERR("get virtual address fail\n"); + return -1; + } + WMT_PLAT_PR_INFO("Reset EMI(0xF0068000 ~ 0xF0068400) and (0xF0070400 ~ 0xF0078400)\n"); + /* reset 0xF0068000 ~ 0xF0068400 (1K) */ + memset_io(addr, 0, 0x400); + /* reset 0xF0070400 ~ 0xF0078400 (32K) */ + memset_io(addr + CONSYS_EMI_PAGED_DUMP_OFFSET, 0, 0x8000); + return 0; +} + +static INT32 consys_check_reg_readable(VOID) +{ + INT32 can_read = 0; + UINT32 value = 0; + + if (conn_reg.mcu_cfg_on_base != 0 && + conn_reg.mcu_top_misc_on_base != 0) { + /*check connsys clock and sleep status*/ + CONSYS_REG_WRITE(conn_reg.mcu_conn_hif_on_base, CONSYS_CLOCK_CHECK_VALUE); + udelay(1000); + value = CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base); + if ((value & CONSYS_HCLK_CHECK_BIT) && + (value & CONSYS_OSCCLK_CHECK_BIT) && + ((value & CONSYS_SLEEP_CHECK_BIT) == 0)) + can_read = 1; + } + + if (!can_read) + WMT_PLAT_PR_ERR("connsys clock check fail 0x18007000(0x%x)\n", value); + + return can_read; +} + +static VOID consys_clock_fail_dump(VOID) +{ + WMT_PLAT_PR_ERR("CONN_HIF_TOP_MISC=0x%08x CONN_HIF_BUSY_STATUS=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_TOP_MISC), + CONSYS_REG_READ(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_BUSY_STATUS)); + + CONSYS_REG_WRITE(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_DBG_IDX, 0x3333); + WMT_PLAT_PR_ERR("Write CONSYS_HIF_DBG_IDX to 0x3333\n"); + + WMT_PLAT_PR_ERR("CONSYS_HIF_DBG_PROBE=0x%08x CONN_HIF_TOP_MISC=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_DBG_PROBE), + CONSYS_REG_READ(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_TOP_MISC)); + WMT_PLAT_PR_ERR("CONN_HIF_BUSY_STATUS=0x%08x CONN_HIF_PDMA_BUSY_STATUS=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_BUSY_STATUS), + CONSYS_REG_READ(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_PDMA_BUSY_STATUS)); + + CONSYS_REG_WRITE(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_DBG_IDX, 0x2222); + WMT_PLAT_PR_ERR("Write CONSYS_HIF_DBG_IDX to 0x2222\n"); + + WMT_PLAT_PR_ERR("CONSYS_HIF_DBG_PROBE=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_DBG_PROBE)); + + CONSYS_REG_WRITE(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_DBG_IDX, 0x3333); + WMT_PLAT_PR_ERR("Write CONSYS_HIF_DBG_IDX to 0x3333\n"); + + WMT_PLAT_PR_ERR("CONSYS_HIF_DBG_PROBE=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_DBG_PROBE)); + + CONSYS_REG_WRITE(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_DBG_IDX, 0x4444); + WMT_PLAT_PR_ERR("Write CONSYS_HIF_DBG_IDX to 0x4444\n"); + + WMT_PLAT_PR_ERR("CONSYS_HIF_DBG_PROBE=0x%08x CONN_MCU_EMI_CONTROL=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_DBG_PROBE), + CONSYS_REG_READ(conn_reg.mcu_conn_hif_pdma_base + CONSYS_SW_IRQ_OFFSET)); + WMT_PLAT_PR_ERR("CONN_MCU_CLOCK_CONTROL=0x%08x CONN_MCU_BUS_CONTROL=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_CLOCK_CONTROL), + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_BUS_CONTROL)); + + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_DEBUG_SELECT, 0x003e3d00); + WMT_PLAT_PR_ERR("Write CONSYS_DEBUG_SELECT to 0x003e3d00\n"); + + WMT_PLAT_PR_ERR("CONN_MCU_DEBUG_STATUS=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_DEBUG_STATUS)); + + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_DEBUG_SELECT, 0x00403f00); + WMT_PLAT_PR_ERR("Write CONSYS_DEBUG_SELECT to 0x00403f00\n"); + + WMT_PLAT_PR_ERR("CONN_MCU_DEBUG_STATUS=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_DEBUG_STATUS)); + + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_DEBUG_SELECT, 0x00424100); + WMT_PLAT_PR_ERR("Write CONSYS_DEBUG_SELECT to 0x00424100\n"); + + WMT_PLAT_PR_ERR("CONN_MCU_DEBUG_STATUS=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_DEBUG_STATUS)); + + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_DEBUG_SELECT, 0x00444300); + WMT_PLAT_PR_ERR("Write CONSYS_DEBUG_SELECT to 0x00444300\n"); + + WMT_PLAT_PR_ERR("CONN_MCU_DEBUG_STATUS=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_DEBUG_STATUS)); + + WMT_PLAT_PR_ERR("CONN_ON_HOST_CSR_MISC=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_top_misc_on_base + CONN_ON_HOST_CSR_MISC)); + + WMT_PLAT_PR_ERR("CONN_ON_IRQ_CTL=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_top_misc_on_base + CONN_ON_IRQ_CTL)); + + WMT_PLAT_PR_ERR("CONN_ON_IRQ_STATUS=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_top_misc_on_base + CONN_ON_IRQ_STATUS)); +} + +/* + * Before calling this function, should check consys state + * ex: consys power on already and reg_readable + */ + +static INT32 consys_dump_osc_state(P_CONSYS_STATE state) +{ +#if 0 + UINT8 __iomem *addr; +#endif + + CONSYS_REG_WRITE(CONN_CFG_ON_CONN_ON_HOST_MAILBOX_MCU_ADDR, 0x1); + CONSYS_REG_WRITE(CONN_CFG_ON_CONN_ON_MON_CTL_ADDR, 0x80000001); + CONSYS_REG_WRITE(CONN_CFG_ON_CONN_ON_DBGSEL_ADDR, 0x3); + state->lp[0] = (UINT32)CONN_CFG_ON_CONN_ON_MON_FLAG_RECORD_MAPPING_AP_ADDR; + state->lp[1] = CONSYS_REG_READ(CONN_CFG_ON_CONN_ON_MON_FLAG_RECORD_ADDR); + WMT_PLAT_PR_INFO("0x%08x: 0x%x\n", state->lp[0], state->lp[1]); + CONSYS_REG_WRITE(CONN_CFG_ON_CONN_ON_HOST_MAILBOX_MCU_ADDR, 0x0); + + CONSYS_REG_WRITE(CONN_CFG_ON_CONN_ON_HOST_MAILBOX_MCU_ADDR, 0x0); + +#if 0 + addr = ioremap_nocache(gConEmiPhyBase + 0x66500, sizeof(struct consys_sw_state)); + if (addr) + memcpy_fromio(&state->sw_state, addr, sizeof(struct consys_sw_state)); + else + WMT_PLAT_PR_ERR("ioremap fail\n"); + iounmap(addr); +#endif + return MTK_WCN_BOOL_TRUE; +} + +static VOID consys_set_pdma_axi_rready_force_high(UINT32 enable) +{ + if (enable) + CONSYS_SET_BIT(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_PDMA_AXI_RREADY, + CONSYS_PDMA_AXI_RREADY_MASK); + else if ((CONSYS_REG_READ(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_PDMA_AXI_RREADY) & + CONSYS_PDMA_AXI_RREADY_MASK) != 0) + CONSYS_CLR_BIT(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_PDMA_AXI_RREADY, + CONSYS_PDMA_AXI_RREADY_MASK); +} + +static VOID consys_get_ant_sel_cr_addr(PUINT32 default_invert_cr, PUINT32 default_invert_bit) +{ + if (default_invert_cr) { + default_invert_cr[0] = DEFAULT_COEX_WMT_ANTSEL_0_POLARITY_CR; + default_invert_cr[1] = DEFAULT_COEX_WMT_ANTSEL_1_POLARITY_CR; + default_invert_cr[2] = DEFAULT_COEX_WMT_ANTSEL_2_POLARITY_CR; + default_invert_cr[3] = DEFAULT_COEX_WMT_ANTSEL_3_POLARITY_CR; + default_invert_cr[4] = DEFAULT_COEX_WMT_ANTSEL_4_POLARITY_CR; + default_invert_cr[5] = DEFAULT_COEX_WMT_ANTSEL_5_POLARITY_CR; + default_invert_cr[6] = DEFAULT_COEX_WMT_ANTSEL_6_POLARITY_CR; + default_invert_cr[7] = DEFAULT_COEX_WMT_ANTSEL_7_POLARITY_CR; + } + + if (default_invert_bit) { + default_invert_bit[0] = DEFAULT_COEX_WMT_ANTSEL_0_POLARITY_BIT; + default_invert_bit[1] = DEFAULT_COEX_WMT_ANTSEL_1_POLARITY_BIT; + default_invert_bit[2] = DEFAULT_COEX_WMT_ANTSEL_2_POLARITY_BIT; + default_invert_bit[3] = DEFAULT_COEX_WMT_ANTSEL_3_POLARITY_BIT; + default_invert_bit[4] = DEFAULT_COEX_WMT_ANTSEL_4_POLARITY_BIT; + default_invert_bit[5] = DEFAULT_COEX_WMT_ANTSEL_5_POLARITY_BIT; + default_invert_bit[6] = DEFAULT_COEX_WMT_ANTSEL_6_POLARITY_BIT; + default_invert_bit[7] = DEFAULT_COEX_WMT_ANTSEL_7_POLARITY_BIT; + } +} + +static INT32 consys_calibration_backup_restore_support(VOID) +{ + return 1; +} + +static UINT64 consys_get_options(VOID) +{ + UINT64 options = OPT_WIFI_LTE_COEX | + OPT_BT_TSSI_FROM_WIFI_CONFIG_NEW_OPID | + OPT_INIT_COEX_BEFORE_RF_CALIBRATION | + OPT_WIFI_LTE_COEX_TABLE_3 | + OPT_COEX_EXT_ELNA_GAIN_P1_SUPPORT | + OPT_NORMAL_PATCH_DWN_3 | + OPT_PATCH_CHECKSUM; + return options; +} + diff --git a/drivers/misc/mediatek/connectivity/common/common_main/platform/mt6765.c b/drivers/misc/mediatek/connectivity/common/common_main/platform/mt6765.c new file mode 100644 index 0000000000000000000000000000000000000000..fd7179658ee86e084f5a655e993233fa0113e16c --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/platform/mt6765.c @@ -0,0 +1,1425 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +#ifdef DFT_TAG +#undef DFT_TAG +#endif +#define DFT_TAG "[WMT-CONSYS-HW]" + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include +#include +#include +#include +#include +#include "connsys_debug_utility.h" +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH +#include "fw_log_wmt.h" +#endif +#include "osal_typedef.h" +#include "mt6765.h" +#include "mtk_wcn_consys_hw.h" +#include "wmt_ic.h" +#include "wmt_lib.h" +#include "wmt_plat.h" +#include "stp_dbg.h" + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) +#include +#else +#include +#endif + +#ifdef CONFIG_MTK_EMI +#include +#endif + +#if CONSYS_PMIC_CTRL_ENABLE +#include +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) +#include +#include +#include +#else +#include +#endif +#endif + +#ifdef CONFIG_MTK_HIBERNATION +#include +#endif + +#include + + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +static INT32 consys_clock_buffer_ctrl(MTK_WCN_BOOL enable); +static VOID consys_hw_reset_bit_set(MTK_WCN_BOOL enable); +static VOID consys_hw_spm_clk_gating_enable(VOID); +static INT32 consys_hw_power_ctrl(MTK_WCN_BOOL enable); +static INT32 consys_ahb_clock_ctrl(MTK_WCN_BOOL enable); +static INT32 polling_consys_chipid(VOID); +static VOID consys_acr_reg_setting(VOID); +static VOID consys_afe_reg_setting(VOID); +static INT32 consys_hw_vcn18_ctrl(MTK_WCN_BOOL enable); +static VOID consys_vcn28_hw_mode_ctrl(UINT32 enable); +static INT32 consys_hw_vcn28_ctrl(UINT32 enable); +static INT32 consys_hw_wifi_vcn33_ctrl(UINT32 enable); +static INT32 consys_hw_bt_vcn33_ctrl(UINT32 enable); +static UINT32 consys_soc_chipid_get(VOID); +static INT32 consys_emi_mpu_set_region_protection(VOID); +static UINT32 consys_emi_set_remapping_reg(VOID); +static INT32 bt_wifi_share_v33_spin_lock_init(VOID); +static INT32 consys_clk_get_from_dts(struct platform_device *pdev); +static INT32 consys_pmic_get_from_dts(struct platform_device *pdev); +static INT32 consys_read_irq_info_from_dts(struct platform_device *pdev, PINT32 irq_num, PUINT32 irq_flag); +static INT32 consys_read_reg_from_dts(struct platform_device *pdev); +static UINT32 consys_read_cpupcr(VOID); +static VOID force_trigger_assert_debug_pin(VOID); +static INT32 consys_co_clock_type(VOID); +static P_CONSYS_EMI_ADDR_INFO consys_soc_get_emi_phy_add(VOID); +static VOID consys_set_if_pinmux(MTK_WCN_BOOL enable); +static INT32 consys_dl_rom_patch(UINT32 ip_ver, UINT32 fw_ver); +static VOID consys_set_dl_rom_patch_flag(INT32 flag); +static INT32 consys_dedicated_log_path_init(struct platform_device *pdev); +static VOID consys_dedicated_log_path_deinit(VOID); +static INT32 consys_check_reg_readable(VOID); +static INT32 consys_emi_coredump_remapping(UINT8 __iomem **addr, UINT32 enable); +static INT32 consys_reset_emi_coredump(UINT8 __iomem *addr); +static INT32 consys_is_connsys_reg(UINT32 addr); +static INT32 consys_is_host_csr(SIZE_T addr); +static INT32 consys_dump_osc_state(P_CONSYS_STATE state); +static VOID consys_set_pdma_axi_rready_force_high(UINT32 enable); +static VOID consys_infra_reg_dump(VOID); +static VOID consys_get_ant_sel_cr_addr(PUINT32 default_invert_cr, PUINT32 default_invert_bit); +static INT32 consys_calibration_backup_restore_support(VOID); +static UINT64 consys_get_options(VOID); + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ +#if CONSYS_BT_WIFI_SHARE_V33 +struct bt_wifi_v33_status gBtWifiV33; +#endif + +/* CCF part */ +struct clk *clk_scp_conn_main; /*ctrl conn_power_on/off */ + +/* PMIC part */ +#if CONSYS_PMIC_CTRL_ENABLE +static struct regulator *reg_VCN18; +static struct regulator *reg_VCN28; +static struct regulator *reg_VCN33_BT; +static struct regulator *reg_VCN33_WIFI; +#endif + +EMI_CTRL_STATE_OFFSET mtk_wcn_emi_state_off = { + .emi_apmem_ctrl_state = EXP_APMEM_CTRL_STATE, + .emi_apmem_ctrl_host_sync_state = EXP_APMEM_CTRL_HOST_SYNC_STATE, + .emi_apmem_ctrl_host_sync_num = EXP_APMEM_CTRL_HOST_SYNC_NUM, + .emi_apmem_ctrl_chip_sync_state = EXP_APMEM_CTRL_CHIP_SYNC_STATE, + .emi_apmem_ctrl_chip_sync_num = EXP_APMEM_CTRL_CHIP_SYNC_NUM, + .emi_apmem_ctrl_chip_sync_addr = EXP_APMEM_CTRL_CHIP_SYNC_ADDR, + .emi_apmem_ctrl_chip_sync_len = EXP_APMEM_CTRL_CHIP_SYNC_LEN, + .emi_apmem_ctrl_chip_print_buff_start = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_START, + .emi_apmem_ctrl_chip_print_buff_len = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_LEN, + .emi_apmem_ctrl_chip_print_buff_idx = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_IDX, + .emi_apmem_ctrl_chip_int_status = EXP_APMEM_CTRL_CHIP_INT_STATUS, + .emi_apmem_ctrl_chip_paded_dump_end = EXP_APMEM_CTRL_CHIP_PAGED_DUMP_END, + .emi_apmem_ctrl_host_outband_assert_w1 = EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1, + .emi_apmem_ctrl_chip_page_dump_num = EXP_APMEM_CTRL_CHIP_PAGE_DUMP_NUM, + .emi_apmem_ctrl_assert_flag = EXP_APMEM_CTRL_ASSERT_FLAG, +}; + +CONSYS_EMI_ADDR_INFO mtk_wcn_emi_addr_info = { + .emi_phy_addr = CONSYS_EMI_FW_PHY_BASE, + .paged_trace_off = CONSYS_EMI_PAGED_TRACE_OFFSET, + .paged_dump_off = CONSYS_EMI_PAGED_DUMP_OFFSET, + .full_dump_off = CONSYS_EMI_FULL_DUMP_OFFSET, + .emi_remap_offset = CONSYS_EMI_MAPPING_OFFSET, + .p_ecso = &mtk_wcn_emi_state_off, + .emi_core_dump_offset = CONSYS_EMI_COREDUMP_OFFSET, + .pda_dl_patch_flag = 1, + .emi_met_size = (32*KBYTE), + .emi_met_data_offset = CONSYS_EMI_MET_DATA_OFFSET, +}; + +WMT_CONSYS_IC_OPS consys_ic_ops = { + .consys_ic_clock_buffer_ctrl = consys_clock_buffer_ctrl, + .consys_ic_hw_reset_bit_set = consys_hw_reset_bit_set, + .consys_ic_hw_spm_clk_gating_enable = consys_hw_spm_clk_gating_enable, + .consys_ic_hw_power_ctrl = consys_hw_power_ctrl, + .consys_ic_ahb_clock_ctrl = consys_ahb_clock_ctrl, + .polling_consys_ic_chipid = polling_consys_chipid, + .consys_ic_acr_reg_setting = consys_acr_reg_setting, + .consys_ic_afe_reg_setting = consys_afe_reg_setting, + .consys_ic_hw_vcn18_ctrl = consys_hw_vcn18_ctrl, + .consys_ic_vcn28_hw_mode_ctrl = consys_vcn28_hw_mode_ctrl, + .consys_ic_hw_vcn28_ctrl = consys_hw_vcn28_ctrl, + .consys_ic_hw_wifi_vcn33_ctrl = consys_hw_wifi_vcn33_ctrl, + .consys_ic_hw_bt_vcn33_ctrl = consys_hw_bt_vcn33_ctrl, + .consys_ic_soc_chipid_get = consys_soc_chipid_get, + .consys_ic_emi_mpu_set_region_protection = consys_emi_mpu_set_region_protection, + .consys_ic_emi_set_remapping_reg = consys_emi_set_remapping_reg, + .ic_bt_wifi_share_v33_spin_lock_init = bt_wifi_share_v33_spin_lock_init, + .consys_ic_clk_get_from_dts = consys_clk_get_from_dts, + .consys_ic_pmic_get_from_dts = consys_pmic_get_from_dts, + .consys_ic_read_irq_info_from_dts = consys_read_irq_info_from_dts, + .consys_ic_read_reg_from_dts = consys_read_reg_from_dts, + .consys_ic_read_cpupcr = consys_read_cpupcr, + .ic_force_trigger_assert_debug_pin = force_trigger_assert_debug_pin, + .consys_ic_co_clock_type = consys_co_clock_type, + .consys_ic_soc_get_emi_phy_add = consys_soc_get_emi_phy_add, + .consys_ic_set_if_pinmux = consys_set_if_pinmux, + .consys_ic_set_dl_rom_patch_flag = consys_set_dl_rom_patch_flag, + .consys_ic_dedicated_log_path_init = consys_dedicated_log_path_init, + .consys_ic_dedicated_log_path_deinit = consys_dedicated_log_path_deinit, + .consys_ic_check_reg_readable = consys_check_reg_readable, + .consys_ic_emi_coredump_remapping = consys_emi_coredump_remapping, + .consys_ic_reset_emi_coredump = consys_reset_emi_coredump, + .consys_ic_is_connsys_reg = consys_is_connsys_reg, + .consys_ic_is_host_csr = consys_is_host_csr, + .consys_ic_dump_osc_state = consys_dump_osc_state, + .consys_ic_set_pdma_axi_rready_force_high = consys_set_pdma_axi_rready_force_high, + .consys_ic_infra_reg_dump = consys_infra_reg_dump, + .consys_ic_get_ant_sel_cr_addr = consys_get_ant_sel_cr_addr, + .consys_ic_calibration_backup_restore = consys_calibration_backup_restore_support, + .consys_ic_get_options = consys_get_options, +}; + +static const struct connlog_emi_config connsys_fw_log_parameter = { + .emi_offset = 0x36500, + .emi_size_total = (192*1024),/* 192KB */ + .emi_size_mcu = (16*1024), + .emi_size_wifi = (64*1024), + .emi_size_bt = (64*1024), + .emi_size_gps = (32*1024), +}; + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +INT32 rom_patch_dl_flag = 1; +UINT32 gJtagCtrl; +UINT32 g_connsys_lp_dump_info[2]; + +#if CONSYS_ENALBE_SET_JTAG +#define JTAG_ADDR1_BASE 0x10005000 +#define JTAG_ADDR2_BASE 0x11E80000 +#define JTAG_ADDR3_BASE 0x11D20000 +#define AP2CONN_JTAG_2WIRE_OFFSET 0xF00 +#endif + +INT32 mtk_wcn_consys_jtag_set_for_mcu(VOID) +{ +#if CONSYS_ENALBE_SET_JTAG + INT32 ret = 0; + UINT32 tmp = 0; + PVOID addr = 0; + PVOID remap_addr1 = 0; + PVOID remap_addr2 = 0; + PVOID remap_addr3 = 0; + + if (gJtagCtrl) { + + remap_addr1 = ioremap(JTAG_ADDR1_BASE, 0x1000); + if (remap_addr1 == 0) { + WMT_PLAT_PR_ERR("remap jtag_addr1 fail!\n"); + ret = -1; + goto error; + } + + remap_addr2 = ioremap(JTAG_ADDR2_BASE, 0x100); + if (remap_addr2 == 0) { + WMT_PLAT_PR_ERR("remap jtag_addr2 fail!\n"); + ret = -1; + goto error; + } + + remap_addr3 = ioremap(JTAG_ADDR3_BASE, 0x100); + if (remap_addr3 == 0) { + WMT_PLAT_PR_ERR("remap jtag_addr3 fail!\n"); + ret = -1; + goto error; + } + + WMT_PLAT_PR_INFO("WCN jtag set for mcu start...\n"); + switch (gJtagCtrl) { + case 1: + /* 7-wire jtag pinmux setting*/ +#if 1 + /* PAD AUX Function Selection */ + addr = remap_addr1 + 0x320; + tmp = readl(addr); + tmp = tmp & 0x0000000f; + tmp = tmp | 0x33333330; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + /* PAD Driving Selection */ + addr = remap_addr2 + 0xA0; + tmp = readl(addr); + tmp = tmp & 0xfff00fff; + tmp = tmp | 0x00077000; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + /* PAD PULL Selection */ + addr = remap_addr2 + 0x60; + tmp = readl(addr); + tmp = tmp & 0xfffe03ff; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + addr = remap_addr2 + 0x60; + tmp = readl(addr); + tmp = tmp & 0xfff80fff; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + +#else + /* backup */ + /* PAD AUX Function Selection */ + addr = remap_addr1 + 0x310; + tmp = readl(addr); + tmp = tmp & 0xfffff000; + tmp = tmp | 0x00000444; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + addr = remap_addr1 + 0x3C0; + tmp = readl(addr); + tmp = tmp & 0xf00ff00f; + tmp = tmp | 0x04400440; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + /* PAD Driving Selection */ + addr = remap_addr3 + 0xA0; + tmp = readl(addr); + tmp = tmp & 0x0ffffff0; + tmp = tmp | 0x70000007; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + addr = remap_addr3 + 0xB0; + tmp = readl(addr); + tmp = tmp & 0xfff0f0ff; + tmp = tmp | 0x0007070f; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + /* PAD PULL Selection */ + addr = remap_addr3 + 0x60; + tmp = readl(addr); + tmp = tmp & 0xf333fffe; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); +#endif + break; + case 2: + /* 2-wire jtag pinmux setting*/ +#if 0 + CONSYS_SET_BIT(conn_reg.topckgen_base + AP2CONN_JTAG_2WIRE_OFFSET, 1 << 8); + addr = remap_addr1 + 0x340; + tmp = readl(addr); + tmp = tmp & 0xfff88fff; + tmp = tmp | 0x00034000; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); +#endif + break; + default: + WMT_PLAT_PR_INFO("unsupported options!\n"); + } + + } +#endif + +error: + + if (remap_addr1) + iounmap(remap_addr1); + if (remap_addr2) + iounmap(remap_addr2); + if (remap_addr3) + iounmap(remap_addr3); + + return ret; +} + +UINT32 mtk_wcn_consys_jtag_flag_ctrl(UINT32 en) +{ + WMT_PLAT_PR_INFO("%s jtag set for MCU\n", en ? "enable" : "disable"); + gJtagCtrl = en; + return 0; +} + +static INT32 consys_clk_get_from_dts(struct platform_device *pdev) +{ + clk_scp_conn_main = devm_clk_get(&pdev->dev, "conn"); + if (IS_ERR(clk_scp_conn_main)) { + WMT_PLAT_PR_ERR("[CCF]cannot get clk_scp_conn_main clock.\n"); + return PTR_ERR(clk_scp_conn_main); + } + WMT_PLAT_PR_DBG("[CCF]clk_scp_conn_main=%p\n", clk_scp_conn_main); + + return 0; +} + +static INT32 consys_pmic_get_from_dts(struct platform_device *pdev) +{ +#if CONSYS_PMIC_CTRL_ENABLE + reg_VCN18 = regulator_get(&pdev->dev, "vcn18"); + if (!reg_VCN18) + WMT_PLAT_PR_ERR("Regulator_get VCN_1V8 fail\n"); + reg_VCN28 = regulator_get(&pdev->dev, "vcn28"); + if (!reg_VCN28) + WMT_PLAT_PR_ERR("Regulator_get VCN_2V8 fail\n"); + reg_VCN33_BT = regulator_get(&pdev->dev, "vcn33_bt"); + if (!reg_VCN33_BT) + WMT_PLAT_PR_ERR("Regulator_get VCN33_BT fail\n"); + reg_VCN33_WIFI = regulator_get(&pdev->dev, "vcn33_wifi"); + if (!reg_VCN33_WIFI) + WMT_PLAT_PR_ERR("Regulator_get VCN33_WIFI fail\n"); +#endif + return 0; +} + +static INT32 consys_co_clock_type(VOID) +{ + return 0; +} + +static INT32 consys_clock_buffer_ctrl(MTK_WCN_BOOL enable) +{ + if (enable) + KERNEL_clk_buf_ctrl(CLK_BUF_CONN, true); /*open XO_WCN*/ + else + KERNEL_clk_buf_ctrl(CLK_BUF_CONN, false); /*close XO_WCN*/ + + return 0; +} + +static VOID consys_set_if_pinmux(MTK_WCN_BOOL enable) +{ + UINT8 *consys_if_pinmux_reg_base = NULL; + + /* Switch D die pinmux for connecting A die */ + consys_if_pinmux_reg_base = ioremap_nocache(CONSYS_IF_PINMUX_REG_BASE, 0x1000); + if (!consys_if_pinmux_reg_base) { + WMT_PLAT_PR_ERR("consys_if_pinmux_reg_base(%x) ioremap fail\n", CONSYS_IF_PINMUX_REG_BASE); + return; + } + + if (enable) { + CONSYS_REG_WRITE(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_01_OFFSET, + (CONSYS_REG_READ(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_01_OFFSET) & + CONSYS_IF_PINMUX_01_MASK) | CONSYS_IF_PINMUX_01_VALUE); + CONSYS_REG_WRITE(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_02_OFFSET, + (CONSYS_REG_READ(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_02_OFFSET) & + CONSYS_IF_PINMUX_02_MASK) | CONSYS_IF_PINMUX_02_VALUE); + } else { + CONSYS_REG_WRITE(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_01_OFFSET, + CONSYS_REG_READ(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_01_OFFSET) & + CONSYS_IF_PINMUX_01_MASK); + CONSYS_REG_WRITE(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_02_OFFSET, + CONSYS_REG_READ(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_02_OFFSET) & + CONSYS_IF_PINMUX_02_MASK); + } + + if (consys_if_pinmux_reg_base) + iounmap(consys_if_pinmux_reg_base); +} + +static VOID consys_hw_reset_bit_set(MTK_WCN_BOOL enable) +{ + UINT32 consys_ver_id = 0; + UINT32 cnt = 0; + + if (enable) { + /*3.assert CONNSYS CPU SW reset 0x10007018 "[12]=1'b1 [31:24]=8'h88 (key)" */ + CONSYS_REG_WRITE((conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET), + CONSYS_REG_READ(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET) | + CONSYS_CPU_SW_RST_BIT | CONSYS_CPU_SW_RST_CTRL_KEY); + } else { + /*16.deassert CONNSYS CPU SW reset 0x10007018 "[12]=1'b0 [31:24] =8'h88 (key)" */ + CONSYS_REG_WRITE(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET, + (CONSYS_REG_READ(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET) & + ~CONSYS_CPU_SW_RST_BIT) | CONSYS_CPU_SW_RST_CTRL_KEY); + + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_base + 0x600); + while (consys_ver_id != 0x1D1E) { + if (cnt > 10) + break; + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_base + 0x600); + WMT_PLAT_PR_INFO("0x18002600(0x%x)\n", consys_ver_id); + WMT_PLAT_PR_INFO("0x1800216c(0x%x)\n", + CONSYS_REG_READ(conn_reg.mcu_base + 0x16c)); + WMT_PLAT_PR_INFO("0x18007104(0x%x)\n", + CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + CONSYS_CPUPCR_OFFSET)); + msleep(20); + cnt++; + } + } +} + +static VOID consys_hw_spm_clk_gating_enable(VOID) +{ +} + +static INT32 consys_hw_power_ctrl(MTK_WCN_BOOL enable) +{ +#if CONSYS_PWR_ON_OFF_API_AVAILABLE + INT32 iRet = 0; +#else + INT32 value = 0; + INT32 i = 0; +#endif + + if (enable) { +#if CONSYS_PWR_ON_OFF_API_AVAILABLE + iRet = clk_prepare_enable(clk_scp_conn_main); + if (iRet) + WMT_PLAT_PR_ERR("clk_prepare_enable(clk_scp_conn_main) fail(%d)\n", iRet); + WMT_PLAT_PR_DBG("clk_prepare_enable(clk_scp_conn_main) ok\n"); +#else + /* turn on SPM clock gating enable PWRON_CONFG_EN 0x10006000 32'h0b160001 */ + CONSYS_REG_WRITE((conn_reg.spm_base + CONSYS_PWRON_CONFG_EN_OFFSET), + (CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWRON_CONFG_EN_OFFSET) & + 0x0000FFFF) | CONSYS_PWRON_CONFG_EN_VALUE); + + /*write assert "conn_top_on" primary part power on, set "connsys_on_domain_pwr_on"=1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_SPM_PWR_ON_BIT); + /*read check "conn_top_on" primary part power status, check "connsys_on_domain_pwr_ack"=1 */ + value = CONSYS_PWR_ON_ACK_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_OFFSET); + while (value == 0) + value = CONSYS_PWR_ON_ACK_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_OFFSET); + /*write assert "conn_top_on" secondary part power on, set "connsys_on_domain_pwr_on_s"=1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_SPM_PWR_ON_S_BIT); + /*read check "conn_top_on" secondary part power status, check "connsys_on_domain_pwr_ack_s"=1 */ + value = CONSYS_PWR_ON_ACK_S_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_S_OFFSET); + while (value == 0) + value = CONSYS_PWR_ON_ACK_S_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_S_OFFSET); + /*write turn on AP-to-CONNSYS bus clock, set "conn_clk_dis"=0 (apply this for bus + *clock toggling) + */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) & + ~CONSYS_CLK_CTRL_BIT); + /*wait 1us*/ + udelay(1); + /*de-assert "conn_top_on" isolation, set "connsys_iso_en"=0 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) & + ~CONSYS_SPM_PWR_ISO_S_BIT); + /*read check "conn_top_off" primary part power status, check + *"connsys_off_domain_pwr_ack"=1 + */ + value = CONSYS_TOP2_PWR_ON_ACK_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_OFFSET); + while (value == 0) + value = CONSYS_TOP2_PWR_ON_ACK_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_OFFSET); + /*read check "conn_top_off" secondary part power status, check + *"connsys_off_domain_pwr_ack_s"=1 + */ + value = CONSYS_TOP2_PWR_ON_ACK_S_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_S_OFFSET); + while (value == 0) + value = CONSYS_TOP2_PWR_ON_ACK_S_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_S_OFFSET); + + /*de-assert CONNSYS S/W reset, set "ap_sw_rst_b"=1 */ + CONSYS_REG_WRITE(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET, + (CONSYS_REG_READ(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET) & + ~CONSYS_SW_RST_BIT) | CONSYS_CPU_SW_RST_CTRL_KEY); + + /*Turn off AHB bus sleep protect (AP2CONN AHB Bus protect) (apply this for INFRA AHB + *bus accessing when CONNSYS had been turned on) + */ + /*disable AHBAXI BUS protect 10001220 [13][14] */ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_EN_OFFSET) & + ~CONSYS_PROT_MASK); + value = ~CONSYS_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_STA1_OFFSET); + i = 0; + while (value == 0 || i > 10) { + value = ~CONSYS_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_STA1_OFFSET); + i++; + } + /*Disable AXI TX bus sleep protect (CONN2AP AXI Tx Bus protect) (disable sleep + * protection when CONNSYS had been turned on) + * Note : Should turn off AXI Tx sleep protection after AXI Rx sleep protection has + * been turn off. + */ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AXI_TX_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AXI_TX_PROT_EN_OFFSET) & + ~CONSYS_TX_PROT_MASK); + value = ~CONSYS_TX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AXI_TX_PROT_STA_OFFSET); + i = 0; + while (value == 0 || i > 10) { + value = ~CONSYS_TX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AXI_TX_PROT_STA_OFFSET); + i++; + } + /*SPM apsrc/ddr_en hardware mask disable & wait cycle setting*/ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_SPM_APSRC_OFFSET, CONSYS_SPM_APSRC_VALUE); + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_SPM_DDR_EN_OFFSET, CONSYS_SPM_DDR_EN_VALUE); +#endif /* CONSYS_PWR_ON_OFF_API_AVAILABLE */ + } else { +#if CONSYS_PWR_ON_OFF_API_AVAILABLE + clk_disable_unprepare(clk_scp_conn_main); + WMT_PLAT_PR_DBG("clk_disable_unprepare(clk_scp_conn_main) calling\n"); +#else + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_EN_OFFSET) & + CONSYS_PROT_MASK); + value = CONSYS_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_STA1_OFFSET); + i = 0; + while (value == CONSYS_PROT_MASK || i > 10) { + value = CONSYS_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_STA1_OFFSET); + i++; + } + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AXI_TX_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AXI_TX_PROT_EN_OFFSET) & + CONSYS_TX_PROT_MASK); + value = CONSYS_TX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AXI_TX_PROT_STA_OFFSET); + i = 0; + while (value == CONSYS_TX_PROT_MASK || i > 10) { + value = CONSYS_TX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AXI_TX_PROT_STA_OFFSET); + i++; + } + + /*release connsys ISO, conn_top1_iso_en=1 0x1000632C [1] 1'b1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_SPM_PWR_ISO_S_BIT); + /*de-assert CONNSYS S/W reset, set "ap_sw_rst_b"=1 */ + CONSYS_REG_WRITE(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET, + (CONSYS_REG_READ(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET) & + CONSYS_SW_RST_BIT) | CONSYS_CPU_SW_RST_CTRL_KEY); + /*write conn_clk_dis=1, disable connsys clock 0x1000632C [4] 1'b1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_CLK_CTRL_BIT); + /*wait 1us */ + udelay(1); + /*write conn_top1_pwr_on=0, power off conn_top1 0x1000632C [3:2] 2'b00 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) & + ~(CONSYS_SPM_PWR_ON_BIT | CONSYS_SPM_PWR_ON_S_BIT)); +#endif /* CONSYS_PWR_ON_OFF_API_AVAILABLE */ + } + +#if CONSYS_PWR_ON_OFF_API_AVAILABLE + return iRet; +#else + return 0; +#endif +} + +static INT32 consys_ahb_clock_ctrl(MTK_WCN_BOOL enable) +{ + return 0; +} + +static INT32 polling_consys_chipid(VOID) +{ + INT32 retry = 10; + UINT32 consys_ver_id = 0; + UINT32 consys_hw_ver = 0; + UINT32 consys_fw_ver = 0; + UINT8 *consys_reg_base = NULL; + UINT32 value = 0; + + /*12.poll CONNSYS CHIP ID until chipid is returned 0x18070008 */ + while (retry-- > 0) { + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_top_misc_off_base + CONSYS_IP_VER_OFFSET); + if (consys_ver_id == 0x10020300) { + WMT_PLAT_PR_INFO("retry(%d)consys version id(0x%08x)\n", retry, consys_ver_id); + consys_hw_ver = CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HW_ID_OFFSET); + WMT_PLAT_PR_INFO("consys HW version id(0x%x)\n", consys_hw_ver & 0xFFFF); + consys_fw_ver = CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_FW_ID_OFFSET); + WMT_PLAT_PR_INFO("consys FW version id(0x%x)\n", consys_fw_ver & 0xFFFF); + + if (consys_dl_rom_patch(consys_ver_id, consys_fw_ver) == 0) + break; + } + WMT_PLAT_PR_ERR("Read CONSYS version id(0x%08x)", consys_ver_id); + msleep(20); + } + + if (retry <= 0) + return -1; + + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_top_misc_off_base + CONSYS_CONF_ID_OFFSET); + WMT_PLAT_PR_INFO("consys configuration id(0x%x)\n", consys_ver_id & 0xF); + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HW_ID_OFFSET); + WMT_PLAT_PR_INFO("consys HW version id(0x%x)\n", consys_ver_id & 0xFFFF); + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_FW_ID_OFFSET); + WMT_PLAT_PR_INFO("consys FW version id(0x%x)\n", consys_ver_id & 0xFFFF); + + /* CONNSYS mcu rom delsel setting */ + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_MCU_ROM_DELSEL_OFFSET); + consys_ver_id &= 0xFFFF0000; + consys_ver_id |= CONSYS_MCU_ROM_DELSEL_VALUE; + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_MCU_ROM_DELSEL_OFFSET, consys_ver_id); + + if (wmt_plat_soc_co_clock_flag_get()) { + consys_reg_base = ioremap_nocache(CONSYS_COCLOCK_STABLE_TIME_BASE, 0x100); + if (consys_reg_base) { +#if 0 + /* disable XO stable time setting */ + value = CONSYS_REG_READ(consys_reg_base); + value = (value & CONSYS_COCLOCK_STABLE_TIME_MASK) | CONSYS_COCLOCK_STABLE_TIME; + CONSYS_REG_WRITE(consys_reg_base, value); +#endif + value = CONSYS_REG_READ(consys_reg_base + CONSYS_COCLOCK_ACK_ENABLE_OFFSET); + value = value & (~CONSYS_COCLOCK_ACK_ENABLE_BIT); + CONSYS_REG_WRITE(consys_reg_base + CONSYS_COCLOCK_ACK_ENABLE_OFFSET, value); + iounmap(consys_reg_base); + } else + WMT_PLAT_PR_ERR("connsys co_clock stable time base(0x%x) ioremap fail!\n", + CONSYS_COCLOCK_STABLE_TIME_BASE); + } + + CONSYS_SET_BIT(conn_reg.mcu_base + CONSYS_SW_IRQ_OFFSET, CONSYS_EMI_CTRL_VALUE); + + return 0; +} + +static VOID consys_acr_reg_setting(VOID) +{ +} + +static VOID consys_afe_reg_setting(VOID) +{ +#if CONSYS_AFE_REG_SETTING + UINT8 i = 0; + UINT8 *consys_afe_reg_base = NULL; + + /*15.default no need,update ANA_WBG(AFE) CR if needed, CONSYS_AFE_REG */ + consys_afe_reg_base = ioremap_nocache(CONSYS_AFE_REG_BASE, 0x100); + if (consys_afe_reg_base) { + CONSYS_REG_WRITE(consys_afe_reg_base + CONSYS_AFE_RG_WBG_PLL_03_OFFSET, + CONSYS_AFE_RG_WBG_PLL_03_VALUE); + CONSYS_REG_WRITE(consys_afe_reg_base + CONSYS_AFE_RG_WBG_GPS_02_OFFSET, + CONSYS_AFE_RG_WBG_GPS_02_VALUE); + + WMT_PLAT_PR_DBG("Dump AFE register\n"); + for (i = 0; i < 64; i++) { + WMT_PLAT_PR_DBG("reg:0x%08x|val:0x%08x\n", + CONSYS_AFE_REG_BASE + 4*i, + CONSYS_REG_READ(consys_afe_reg_base + 4*i)); + } + iounmap(consys_afe_reg_base); + } else + WMT_PLAT_PR_ERR("AFE base(0x%x) ioremap fail!\n", CONSYS_AFE_REG_BASE); +#endif +} + +static INT32 consys_hw_vcn18_ctrl(MTK_WCN_BOOL enable) +{ +#if CONSYS_PMIC_CTRL_ENABLE + if (enable) { + /*need PMIC driver provide new API protocol */ + /*1.AP power on VCN_1V8 LDO (with PMIC_WRAP API) VCN_1V8 */ + /*set vcn18 SW mode*/ + if (reg_VCN18) { + regulator_set_voltage(reg_VCN18, 1800000, 1800000); + if (regulator_enable(reg_VCN18)) + WMT_PLAT_PR_ERR("enable VCN18 fail\n"); + else + WMT_PLAT_PR_DBG("enable VCN18 ok\n"); + } + + if (!(wmt_lib_get_ext_ldo())) { + if (reg_VCN33_BT) { + regulator_set_voltage(reg_VCN33_BT, 3300000, 3300000); + if (regulator_enable(reg_VCN33_BT)) + WMT_PLAT_PR_ERR("WMT do BT PMIC on fail!\n"); + } + } else + WMT_PLAT_PR_INFO("VCN33 uses external LDO!\n"); + } else { + if (!(wmt_lib_get_ext_ldo())) { + if (reg_VCN33_BT) + regulator_disable(reg_VCN33_BT); + } + + /*AP power off MT6351L VCN_1V8 LDO */ + if (reg_VCN18) { + if (regulator_disable(reg_VCN18)) + WMT_PLAT_PR_ERR("disable VCN_1V8 fail!\n"); + else + WMT_PLAT_PR_DBG("disable VCN_1V8 ok\n"); + } + } +#endif + return 0; +} + +static VOID consys_vcn28_hw_mode_ctrl(UINT32 enable) +{ +#if CONSYS_PMIC_CTRL_ENABLE +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) + if (!g_regmap) + return; + + if (enable) { + regmap_write(g_regmap, MT6357_LDO_VCN28_OP_EN_SET, 2); + regmap_write(g_regmap, MT6357_LDO_VCN28_OP_CFG_CLR, 2); + } else { + regmap_write(g_regmap, MT6357_LDO_VCN28_OP_EN_CLR, 2); + regmap_write(g_regmap, MT6357_LDO_VCN28_OP_CFG_CLR, 2); + } +#else + if (enable) { + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN28_HW0_OP_EN, 1); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN28_HW0_OP_CFG, 0); + } else { + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN28_HW0_OP_EN, 0); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN28_HW0_OP_CFG, 0); + } +#endif +#endif +} + +static INT32 consys_hw_vcn28_ctrl(UINT32 enable) +{ +#if CONSYS_PMIC_CTRL_ENABLE + if (enable) { + /*in co-clock mode,need to turn on vcn28 when fm on */ + if (reg_VCN28) { + regulator_set_voltage(reg_VCN28, 2800000, 2800000); + if (regulator_enable(reg_VCN28)) + WMT_PLAT_PR_ERR("WMT do VCN28 PMIC on fail!\n"); + } + WMT_PLAT_PR_INFO("turn on vcn28 for fm/gps usage in co-clock mode\n"); + } else { + /*in co-clock mode,need to turn off vcn28 when fm off */ + if (reg_VCN28) + regulator_disable(reg_VCN28); + WMT_PLAT_PR_INFO("turn off vcn28 for fm/gps usage in co-clock mode\n"); + } +#endif + return 0; +} + +static INT32 consys_hw_bt_vcn33_ctrl(UINT32 enable) +{ +#if 0 +#if CONSYS_BT_WIFI_SHARE_V33 + /* spin_lock_irqsave(&gBtWifiV33.lock,gBtWifiV33.flags); */ + if (enable) { + if (gBtWifiV33.counter == 1) { + gBtWifiV33.counter++; + WMT_PLAT_PR_DBG("V33 has been enabled,counter(%d)\n", gBtWifiV33.counter); + } else if (gBtWifiV33.counter == 2) { + WMT_PLAT_PR_DBG("V33 has been enabled,counter(%d)\n", gBtWifiV33.counter); + } else { +#if CONSYS_PMIC_CTRL_ENABLE + /*do BT PMIC on,depenency PMIC API ready */ + /*switch BT PALDO control from SW mode to HW mode:0x416[5]-->0x1 */ + /* VOL_DEFAULT, VOL_3300, VOL_3400, VOL_3500, VOL_3600 */ + hwPowerOn(MT6351_POWER_LDO_VCN33_BT, VOL_3300 * 1000, "wcn_drv"); + mt6351_upmu_set_rg_vcn33_on_ctrl(1); +#endif + WMT_PLAT_PR_INFO("WMT do BT/WIFI v3.3 on\n"); + gBtWifiV33.counter++; + } + + } else { + if (gBtWifiV33.counter == 1) { + /*do BT PMIC off */ + /*switch BT PALDO control from HW mode to SW mode:0x416[5]-->0x0 */ +#if CONSYS_PMIC_CTRL_ENABLE + mt6351_upmu_set_rg_vcn33_on_ctrl(0); + hwPowerDown(MT6351_POWER_LDO_VCN33_BT, "wcn_drv"); +#endif + WMT_PLAT_PR_INFO("WMT do BT/WIFI v3.3 off\n"); + gBtWifiV33.counter--; + } else if (gBtWifiV33.counter == 2) { + gBtWifiV33.counter--; + WMT_PLAT_PR_DBG("V33 no need disabled,counter(%d)\n", gBtWifiV33.counter); + } else { + WMT_PLAT_PR_DBG("V33 has been disabled,counter(%d)\n", gBtWifiV33.counter); + } + + } + /* spin_unlock_irqrestore(&gBtWifiV33.lock,gBtWifiV33.flags); */ +#else + if (enable) { + /*do BT PMIC on,depenency PMIC API ready */ + /*switch BT PALDO control from SW mode to HW mode:0x416[5]-->0x1 */ +#if CONSYS_PMIC_CTRL_ENABLE + /* VOL_DEFAULT, VOL_3300, VOL_3400, VOL_3500, VOL_3600 */ + if (reg_VCN33_BT) { + regulator_set_voltage(reg_VCN33_BT, 3300000, 3300000); + if (regulator_enable(reg_VCN33_BT)) + WMT_PLAT_PR_ERR("WMT do BT PMIC on fail!\n"); + } + + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_HW0_OP_EN, 1); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_HW0_OP_CFG, 0); +#endif + WMT_PLAT_PR_DBG("WMT do BT PMIC on\n"); + } else { + /*do BT PMIC off */ + /*switch BT PALDO control from HW mode to SW mode:0x416[5]-->0x0 */ +#if CONSYS_PMIC_CTRL_ENABLE + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_HW0_OP_EN, 0); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_HW0_OP_CFG, 0); + if (reg_VCN33_BT) + regulator_disable(reg_VCN33_BT); +#endif + WMT_PLAT_PR_DBG("WMT do BT PMIC off\n"); + } +#endif + +#endif + return 0; +} + +static INT32 consys_hw_wifi_vcn33_ctrl(UINT32 enable) +{ +#if 0 +#if CONSYS_BT_WIFI_SHARE_V33 + mtk_wcn_consys_hw_bt_paldo_ctrl(enable); +#else + if (enable) { + /*do WIFI PMIC on,depenency PMIC API ready */ + /*switch WIFI PALDO control from SW mode to HW mode:0x418[14]-->0x1 */ +#if CONSYS_PMIC_CTRL_ENABLE + if (reg_VCN33_WIFI) { + regulator_set_voltage(reg_VCN33_WIFI, 3300000, 3300000); + if (regulator_enable(reg_VCN33_WIFI)) + WMT_PLAT_PR_ERR("WMT do WIFI PMIC on fail!\n"); + } + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_HW0_OP_EN, 1); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_HW0_OP_CFG, 0); +#endif + WMT_PLAT_PR_DBG("WMT do WIFI PMIC on\n"); + } else { + /*do WIFI PMIC off */ + /*switch WIFI PALDO control from HW mode to SW mode:0x418[14]-->0x0 */ +#if CONSYS_PMIC_CTRL_ENABLE + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_HW0_OP_EN, 0); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_HW0_OP_CFG, 0); + if (reg_VCN33_WIFI) + regulator_disable(reg_VCN33_WIFI); +#endif + WMT_PLAT_PR_DBG("WMT do WIFI PMIC off\n"); + } + +#endif + +#endif + return 0; +} + +static INT32 consys_emi_mpu_set_region_protection(VOID) +{ +#ifdef CONFIG_MTK_EMI + struct emi_region_info_t region_info; + + /*set MPU for EMI share Memory */ + WMT_PLAT_PR_INFO("setting MPU for EMI share memory\n"); + + region_info.start = gConEmiPhyBase; + region_info.end = gConEmiPhyBase + gConEmiSize - 1; + region_info.region = 25; + SET_ACCESS_PERMISSION(region_info.apc, LOCK, + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, + NO_PROTECTION, FORBIDDEN, NO_PROTECTION); + emi_mpu_set_protection(®ion_info); +#endif + return 0; +} + +static UINT32 consys_emi_set_remapping_reg(VOID) +{ + UINT32 addrPhy = 0; + UINT32 value = 0; + + mtk_wcn_emi_addr_info.emi_ap_phy_addr = gConEmiPhyBase; + mtk_wcn_emi_addr_info.emi_size = gConEmiSize; + + /*consys to ap emi remapping register:10001380, cal remapping address */ + addrPhy = (gConEmiPhyBase >> 24) & 0xFFF; + value = CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET); + WMT_PLAT_PR_INFO("before CONSYS_EMI_MAPPING read:0x%zx, value:0x%x\n", + conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET, value); + + value = value & 0xFFFFF000; + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET, value | addrPhy); + WMT_PLAT_PR_INFO("CONSYS_EMI_MAPPING dump in restore cb(0x%08x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET)); + + /*Perisys Configuration Registers remapping*/ + addrPhy = ((0x10003000 >> 24) & 0xFFF) << 16; + value = CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_PERI_MAPPING_OFFSET); + value = value & 0xF000FFFF; + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_EMI_PERI_MAPPING_OFFSET, value | addrPhy); + + WMT_PLAT_PR_INFO("CONSYS_EMI_MAPPING dump in restore cb(0x%08x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_PERI_MAPPING_OFFSET)); + + mtk_wcn_emi_addr_info.emi_ram_bt_buildtime_offset = + CONSYS_EMI_RAM_BT_BUILDTIME_OFFSET; + mtk_wcn_emi_addr_info.emi_ram_wifi_buildtime_offset = + CONSYS_EMI_RAM_WIFI_BUILDTIME_OFFSET; + mtk_wcn_emi_addr_info.emi_ram_mcu_buildtime_offset = + CONSYS_EMI_RAM_MCU_BUILDTIME_OFFSET; + mtk_wcn_emi_addr_info.emi_patch_mcu_buildtime_offset = + CONSYS_EMI_PATCH_MCU_BUILDTIME_OFFSET; + + return 0; +} + +static INT32 bt_wifi_share_v33_spin_lock_init(VOID) +{ +#if CONSYS_BT_WIFI_SHARE_V33 + gBtWifiV33.counter = 0; + spin_lock_init(&gBtWifiV33.lock); +#endif + return 0; +} + +static INT32 consys_read_irq_info_from_dts(struct platform_device *pdev, PINT32 irq_num, PUINT32 irq_flag) +{ + struct device_node *node; + + node = pdev->dev.of_node; + if (node) { + *irq_num = irq_of_parse_and_map(node, 0); + *irq_flag = irq_get_trigger_type(*irq_num); + WMT_PLAT_PR_INFO("get irq id(%d) and irq trigger flag(%d) from DT\n", *irq_num, + *irq_flag); + } else { + WMT_PLAT_PR_ERR("[%s] can't find CONSYS compatible node\n", __func__); + return -1; + } + + return 0; +} + +static INT32 consys_read_reg_from_dts(struct platform_device *pdev) +{ + INT32 iRet = -1; + struct device_node *node = NULL; + + node = pdev->dev.of_node; + if (node) { + /* registers base address */ + conn_reg.mcu_base = (SIZE_T) of_iomap(node, MCU_BASE_INDEX); + conn_reg.ap_rgu_base = (SIZE_T) of_iomap(node, TOP_RGU_BASE_INDEX); + conn_reg.topckgen_base = (SIZE_T) of_iomap(node, INFRACFG_AO_BASE_INDEX); + conn_reg.spm_base = (SIZE_T) of_iomap(node, SPM_BASE_INDEX); + conn_reg.mcu_top_misc_off_base = (SIZE_T) of_iomap(node, MCU_TOP_MISC_OFF_BASE_INDEX); + conn_reg.mcu_conn_hif_on_base = (SIZE_T) of_iomap(node, MCU_CONN_HIF_ON_BASE_INDEX); + conn_reg.mcu_cfg_on_base = (SIZE_T) of_iomap(node, MCU_CFG_ON_BASE_INDEX); + conn_reg.mcu_cirq_base = (SIZE_T) of_iomap(node, MCU_CIRQ_BASE_INDEX); + conn_reg.mcu_top_misc_on_base = (SIZE_T) of_iomap(node, MCU_TOP_MISC_ON_BASE_INDEX); + conn_reg.mcu_conn_hif_pdma_base = (SIZE_T) of_iomap(node, MCU_CONN_HIF_PDMA_BASE_INDEX); + conn_reg.infracfg_reg_base = (SIZE_T) of_iomap(node, INFRACFG_REG_BASE_INDEX); + + WMT_PLAT_PR_DBG("Get base mcu(0x%zx), rgu(0x%zx), topckgen(0x%zx), spm(0x%zx)\n", + conn_reg.mcu_base, conn_reg.ap_rgu_base, + conn_reg.topckgen_base, conn_reg.spm_base); + WMT_PLAT_PR_DBG("Get base misc_off(0x%zx), hif_on(0x%zx), cfg_on(0x%zx), misc_on(0x%zx)\n", + conn_reg.mcu_top_misc_off_base, + conn_reg.mcu_conn_hif_on_base, + conn_reg.mcu_cfg_on_base, + conn_reg.mcu_top_misc_on_base); + WMT_PLAT_PR_DBG("Get hif_pdma(0x%zx)\n", + conn_reg.mcu_conn_hif_pdma_base); + WMT_PLAT_PR_DBG("Get infracfg_reg(0x%zx)\n", + conn_reg.infracfg_reg_base); + } else { + WMT_PLAT_PR_ERR("[%s] can't find CONSYS compatible node\n", __func__); + return iRet; + } + + return 0; +} + +static VOID force_trigger_assert_debug_pin(VOID) +{ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AP2CONN_OSC_EN_OFFSET) & ~CONSYS_AP2CONN_WAKEUP_BIT); + WMT_PLAT_PR_INFO("enable:dump CONSYS_AP2CONN_OSC_EN_REG(0x%x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET)); + usleep_range(64, 96); + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AP2CONN_OSC_EN_OFFSET) | CONSYS_AP2CONN_WAKEUP_BIT); + WMT_PLAT_PR_INFO("disable:dump CONSYS_AP2CONN_OSC_EN_REG(0x%x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET)); +} + +static UINT32 consys_soc_chipid_get(VOID) +{ + return PLATFORM_SOC_CHIP; +} + +static P_CONSYS_EMI_ADDR_INFO consys_soc_get_emi_phy_add(VOID) +{ + return &mtk_wcn_emi_addr_info; +} + +P_WMT_CONSYS_IC_OPS mtk_wcn_get_consys_ic_ops(VOID) +{ + return &consys_ic_ops; +} + +static INT32 consys_dl_rom_patch(UINT32 ip_ver, UINT32 fw_ver) +{ + if (rom_patch_dl_flag) { + if (mtk_wcn_soc_rom_patch_dwn(ip_ver, fw_ver) == 0) + rom_patch_dl_flag = 1; + else + return -1; + } + + return 0; +} + +static VOID consys_set_dl_rom_patch_flag(INT32 flag) +{ + rom_patch_dl_flag = flag; +} + +static INT32 consys_dedicated_log_path_init(struct platform_device *pdev) +{ + struct device_node *node; + UINT32 irq_num; + UINT32 irq_flag; + INT32 iret = -1; + struct connlog_irq_config irq_config; + + memset(&irq_config, 0, sizeof(struct connlog_irq_config)); + node = pdev->dev.of_node; + if (node) { + irq_num = irq_of_parse_and_map(node, 2); + irq_flag = irq_get_trigger_type(irq_num); + WMT_PLAT_PR_INFO("get conn2ap_sw_irq id(%d) and irq trigger flag(%d) from DT\n", irq_num, + irq_flag); + } else { + WMT_PLAT_PR_ERR("[%s] can't find CONSYS compatible node\n", __func__); + return iret; + } + + irq_config.irq_num = irq_num; + irq_config.irq_flag = irq_flag; + irq_config.irq_callback = NULL; + + connsys_dedicated_log_path_apsoc_init( + gConEmiPhyBase, &connsys_fw_log_parameter, &irq_config); +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH + fw_log_wmt_init(); +#endif + return 0; +} + +static VOID consys_dedicated_log_path_deinit(VOID) +{ +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH + fw_log_wmt_deinit(); +#endif + connsys_dedicated_log_path_apsoc_deinit(); +} + +static UINT32 consys_read_cpupcr(VOID) +{ + if (conn_reg.mcu_conn_hif_on_base == 0) + return 0; + + return CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + CONSYS_CPUPCR_OFFSET); +} + +static INT32 consys_check_reg_readable(VOID) +{ + INT32 can_read = 0; + UINT32 value = 0; + + if (conn_reg.mcu_cfg_on_base != 0 && + conn_reg.mcu_top_misc_on_base != 0) { + /*check connsys clock and sleep status*/ + CONSYS_REG_WRITE(conn_reg.mcu_conn_hif_on_base, CONSYS_CLOCK_CHECK_VALUE); + udelay(1000); + value = CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base); + + if ((value & CONSYS_HCLK_CHECK_BIT) && + (value & CONSYS_OSCCLK_CHECK_BIT) && + ((value & CONSYS_SLEEP_CHECK_BIT) == 0)) + can_read = 1; + } + + if (!can_read) + WMT_PLAT_PR_ERR("connsys clock check fail 0x18007000(0x%x)\n", value); + + return can_read; +} + +static INT32 consys_emi_coredump_remapping(UINT8 __iomem **addr, UINT32 enable) +{ + if (enable) { + *addr = ioremap_nocache(gConEmiPhyBase + CONSYS_EMI_COREDUMP_OFFSET, CONSYS_EMI_MEM_SIZE); + if (*addr) { + WMT_PLAT_PR_INFO("COREDUMP EMI mapping OK virtual(0x%p) physical(0x%x)\n", + *addr, (UINT32) gConEmiPhyBase + CONSYS_EMI_COREDUMP_OFFSET); + memset_io(*addr, 0, CONSYS_EMI_MEM_SIZE); + } else { + WMT_PLAT_PR_ERR("EMI mapping fail\n"); + return -1; + } + } else { + if (*addr) { + iounmap(*addr); + *addr = NULL; + } + } + return 0; +} + +static INT32 consys_reset_emi_coredump(UINT8 __iomem *addr) +{ + if (!addr) { + WMT_PLAT_PR_ERR("get virtual address fail\n"); + return -1; + } + WMT_PLAT_PR_INFO("Reset EMI(0xF0068000 ~ 0xF0068400) and (0xF0070400 ~ 0xF0078400)\n"); + /* reset 0xF0068000 ~ 0xF0068400 (1K) */ + memset_io(addr, 0, 0x400); + /* reset 0xF0070400 ~ 0xF0078400 (32K) */ + memset_io(addr + CONSYS_EMI_PAGED_DUMP_OFFSET, 0, 0x8000); + return 0; +} + +static INT32 consys_is_connsys_reg(UINT32 addr) +{ + if (addr > 0x18000000 && addr < 0x180FFFFF) { + if (addr >= 0x18007000 && addr <= 0x18007FFF) + return 0; + + return 1; + } + + return 0; +} + +static INT32 consys_is_host_csr(SIZE_T addr) +{ + SIZE_T start_offset = 0x000; + SIZE_T end_offset = 0xFFF; + + if (addr >= (CONN_HIF_ON_BASE_ADDR + start_offset) && + addr <= (CONN_HIF_ON_BASE_ADDR + end_offset)) + return 1; + + if (conn_reg.mcu_conn_hif_on_base != 0 && + addr >= (conn_reg.mcu_conn_hif_on_base + start_offset) && + addr <= (conn_reg.mcu_conn_hif_on_base + end_offset)) + return 1; + + return 0; +} + +/* + * Before calling this function, should check consys state + * ex: consys power on already and reg_readable + */ +static INT32 consys_dump_osc_state(P_CONSYS_STATE state) +{ +#if 0 + UINT8 __iomem *addr; +#endif + + CONSYS_REG_WRITE(CONN_CFG_ON_CONN_ON_HOST_MAILBOX_MCU_ADDR, 0x1); + CONSYS_REG_WRITE(CONN_CFG_ON_CONN_ON_MON_CTL_ADDR, 0x80000001); + CONSYS_REG_WRITE(CONN_CFG_ON_CONN_ON_DBGSEL_ADDR, 0x3); + state->lp[0] = (UINT32)CONN_CFG_ON_CONN_ON_MON_FLAG_RECORD_MAPPING_AP_ADDR; + state->lp[1] = CONSYS_REG_READ(CONN_CFG_ON_CONN_ON_MON_FLAG_RECORD_ADDR); + + WMT_PLAT_PR_INFO("0x%08x: 0x%x\n", state->lp[0], state->lp[1]); + + CONSYS_REG_WRITE(CONN_CFG_ON_CONN_ON_HOST_MAILBOX_MCU_ADDR, 0x0); + +#if 0 + addr = ioremap_nocache(gConEmiPhyBase + 0x66500, sizeof(struct consys_sw_state)); + if (addr) { + memcpy_fromio(&state->sw_state, addr, sizeof(struct consys_sw_state)); + WMT_PLAT_PR_INFO("[%s] [%x][%x] [%x][%x] [%x] [%x][%x]", __func__, + state->sw_state.clock_hif_ctrl, + state->sw_state.clock_umac_ctrl, + state->sw_state.resource_disable_sleep, + state->sw_state.clock_mcu, + state->sw_state.info_time, state->sw_state.is_gating, + state->sw_state.sub_system); + + + } else { + WMT_PLAT_PR_WARN("ioremap fail\n"); + } + iounmap(addr); +#endif + return MTK_WCN_BOOL_TRUE; +} + +static VOID consys_set_pdma_axi_rready_force_high(UINT32 enable) +{ + if (enable) + CONSYS_SET_BIT(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_PDMA_AXI_RREADY, + CONSYS_PDMA_AXI_RREADY_MASK); + else if ((CONSYS_REG_READ(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_PDMA_AXI_RREADY) & + CONSYS_PDMA_AXI_RREADY_MASK) != 0) + CONSYS_CLR_BIT(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_PDMA_AXI_RREADY, + CONSYS_PDMA_AXI_RREADY_MASK); +} + +static VOID consys_infra_reg_dump(VOID) +{ + UINT32 infra_topaxi_si3_sta = + CONSYS_REG_READ(conn_reg.infracfg_reg_base + INFRAGCFG_REG_TOPAXI_SI3_STA_OFFSET); + UINT32 infra_topaxi_mi_sta = + CONSYS_REG_READ(conn_reg.infracfg_reg_base + INFRAGCFG_REG_TOPAXI_MI_STA_OFFSET); + UINT32 infra_topaxi_prot_sta0 = + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_STA0_OFFSET); + UINT32 infra_topaxi_prot_sta1 = + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_STA1_OFFSET); + + + WMT_PLAT_PR_INFO("INFRA_TOPAXI_SI3_STA(0x%zx): 0x%x\n", + conn_reg.infracfg_reg_base + INFRAGCFG_REG_TOPAXI_SI3_STA_OFFSET, + infra_topaxi_si3_sta); + WMT_PLAT_PR_INFO("INFRA_TOPAXI_MI_STA(0x%zx): 0x%x\n", + conn_reg.infracfg_reg_base + INFRAGCFG_REG_TOPAXI_MI_STA_OFFSET, + infra_topaxi_mi_sta); + WMT_PLAT_PR_INFO("INFRA_TOPAXI_PROTECTEN_STA0(0x%zx): 0x%x\n", + conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_STA0_OFFSET, + infra_topaxi_prot_sta0); + WMT_PLAT_PR_INFO("INFRA_TOPAXI_PROTECTEN_STA1(0x%zx): 0x%x\n", + conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_STA1_OFFSET, + infra_topaxi_prot_sta1); +} + +static VOID consys_get_ant_sel_cr_addr(PUINT32 default_invert_cr, PUINT32 default_invert_bit) +{ + if (default_invert_cr) { + default_invert_cr[0] = DEFAULT_COEX_WMT_ANTSEL_0_POLARITY_CR; + default_invert_cr[1] = DEFAULT_COEX_WMT_ANTSEL_1_POLARITY_CR; + default_invert_cr[2] = DEFAULT_COEX_WMT_ANTSEL_2_POLARITY_CR; + default_invert_cr[3] = DEFAULT_COEX_WMT_ANTSEL_3_POLARITY_CR; + default_invert_cr[4] = DEFAULT_COEX_WMT_ANTSEL_4_POLARITY_CR; + default_invert_cr[5] = DEFAULT_COEX_WMT_ANTSEL_5_POLARITY_CR; + default_invert_cr[6] = DEFAULT_COEX_WMT_ANTSEL_6_POLARITY_CR; + default_invert_cr[7] = DEFAULT_COEX_WMT_ANTSEL_7_POLARITY_CR; + } + + if (default_invert_bit) { + default_invert_bit[0] = DEFAULT_COEX_WMT_ANTSEL_0_POLARITY_BIT; + default_invert_bit[1] = DEFAULT_COEX_WMT_ANTSEL_1_POLARITY_BIT; + default_invert_bit[2] = DEFAULT_COEX_WMT_ANTSEL_2_POLARITY_BIT; + default_invert_bit[3] = DEFAULT_COEX_WMT_ANTSEL_3_POLARITY_BIT; + default_invert_bit[4] = DEFAULT_COEX_WMT_ANTSEL_4_POLARITY_BIT; + default_invert_bit[5] = DEFAULT_COEX_WMT_ANTSEL_5_POLARITY_BIT; + default_invert_bit[6] = DEFAULT_COEX_WMT_ANTSEL_6_POLARITY_BIT; + default_invert_bit[7] = DEFAULT_COEX_WMT_ANTSEL_7_POLARITY_BIT; + } +} + +static INT32 consys_calibration_backup_restore_support(VOID) +{ + return 1; +} + +static UINT64 consys_get_options(VOID) +{ + ULONG options = OPT_QUERY_ADIE | + OPT_WIFI_LTE_COEX | + OPT_BT_TSSI_FROM_WIFI_CONFIG_NEW_OPID | + OPT_INIT_COEX_BEFORE_RF_CALIBRATION | + OPT_COEX_CONFIG_ADJUST | + OPT_COEX_CONFIG_ADJUST_NEW_FLAG | + OPT_WIFI_LTE_COEX_TABLE_3 | + OPT_COEX_EXT_ELNA_GAIN_P1_SUPPORT | + OPT_NORMAL_PATCH_DWN_3 | + OPT_PATCH_CHECKSUM; + return options; +} diff --git a/drivers/misc/mediatek/connectivity/common/common_main/platform/mt6768.c b/drivers/misc/mediatek/connectivity/common/common_main/platform/mt6768.c new file mode 100644 index 0000000000000000000000000000000000000000..971108bf932de20fef2fe96b7871fb6577be639d --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/platform/mt6768.c @@ -0,0 +1,1481 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +#ifdef DFT_TAG +#undef DFT_TAG +#endif +#define DFT_TAG "[WMT-CONSYS-HW]" + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include +#include +#include +#include +#include +#include "connsys_debug_utility.h" +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH +#include "fw_log_wmt.h" +#endif +#include "osal_typedef.h" +#include "mt6768.h" +#include "mtk_wcn_consys_hw.h" +#include "wmt_ic.h" +#include "wmt_lib.h" +#include "wmt_plat.h" +#include "stp_dbg.h" + +#ifdef CONFIG_MTK_EMI +#include +#endif + +#if CONSYS_PMIC_CTRL_ENABLE +#include +#include +#endif + +#ifdef CONFIG_MTK_HIBERNATION +#include +#endif + +#include + +#include + +#ifdef CONFIG_MTK_DEVAPC_DRIVER +#include +#define WMT_DEVAPC_CALLBACK +#endif + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +static INT32 consys_clock_buffer_ctrl(MTK_WCN_BOOL enable); +static VOID consys_hw_reset_bit_set(MTK_WCN_BOOL enable); +static VOID consys_hw_spm_clk_gating_enable(VOID); +static INT32 consys_hw_power_ctrl(MTK_WCN_BOOL enable); +static INT32 consys_ahb_clock_ctrl(MTK_WCN_BOOL enable); +static INT32 polling_consys_chipid(VOID); +static VOID consys_acr_reg_setting(VOID); +static VOID consys_afe_reg_setting(VOID); +static INT32 consys_hw_vcn18_ctrl(MTK_WCN_BOOL enable); +static VOID consys_vcn28_hw_mode_ctrl(UINT32 enable); +static INT32 consys_hw_vcn28_ctrl(UINT32 enable); +static INT32 consys_hw_wifi_vcn33_ctrl(UINT32 enable); +static INT32 consys_hw_bt_vcn33_ctrl(UINT32 enable); +static UINT32 consys_soc_chipid_get(VOID); +static INT32 consys_emi_mpu_set_region_protection(VOID); +static UINT32 consys_emi_set_remapping_reg(VOID); +static INT32 bt_wifi_share_v33_spin_lock_init(VOID); +static INT32 consys_clk_get_from_dts(struct platform_device *pdev); +static INT32 consys_pmic_get_from_dts(struct platform_device *pdev); +static INT32 consys_read_irq_info_from_dts(struct platform_device *pdev, PINT32 irq_num, PUINT32 irq_flag); +static INT32 consys_read_reg_from_dts(struct platform_device *pdev); +static UINT32 consys_read_cpupcr(VOID); +static VOID force_trigger_assert_debug_pin(VOID); +static INT32 consys_co_clock_type(VOID); +static P_CONSYS_EMI_ADDR_INFO consys_soc_get_emi_phy_add(VOID); +static VOID consys_set_if_pinmux(MTK_WCN_BOOL enable); +static INT32 consys_dl_rom_patch(UINT32 ip_ver, UINT32 fw_ver); +static VOID consys_set_dl_rom_patch_flag(INT32 flag); +static INT32 consys_dedicated_log_path_init(struct platform_device *pdev); +static VOID consys_dedicated_log_path_deinit(VOID); +static INT32 consys_check_reg_readable(VOID); +static INT32 consys_emi_coredump_remapping(UINT8 __iomem **addr, UINT32 enable); +static INT32 consys_reset_emi_coredump(UINT8 __iomem *addr); +static VOID consys_ic_clock_fail_dump(VOID); +static INT32 consys_is_connsys_reg(UINT32 addr); +static INT32 consys_is_host_csr(SIZE_T addr); +static INT32 consys_dump_osc_state(P_CONSYS_STATE state); +static VOID consys_set_pdma_axi_rready_force_high(UINT32 enable); +static INT32 consys_calibration_backup_restore_support(VOID); +#ifdef WMT_DEVAPC_CALLBACK +static VOID consys_devapc_violation_cb(VOID); +static VOID consyc_register_devapc_cb(VOID); +#endif +static INT32 consys_is_ant_swap_enable_by_hwid(INT32 pin_num); +static UINT64 consys_get_options(VOID); + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ +#if CONSYS_BT_WIFI_SHARE_V33 +struct bt_wifi_v33_status gBtWifiV33; +#endif + +/* CCF part */ +struct clk *clk_scp_conn_main; /*ctrl conn_power_on/off */ + +/* PMIC part */ +#if CONSYS_PMIC_CTRL_ENABLE +struct regulator *reg_VCN18; +struct regulator *reg_VCN28; +struct regulator *reg_VCN33_BT; +struct regulator *reg_VCN33_WIFI; +#endif + +EMI_CTRL_STATE_OFFSET mtk_wcn_emi_state_off = { + .emi_apmem_ctrl_state = EXP_APMEM_CTRL_STATE, + .emi_apmem_ctrl_host_sync_state = EXP_APMEM_CTRL_HOST_SYNC_STATE, + .emi_apmem_ctrl_host_sync_num = EXP_APMEM_CTRL_HOST_SYNC_NUM, + .emi_apmem_ctrl_chip_sync_state = EXP_APMEM_CTRL_CHIP_SYNC_STATE, + .emi_apmem_ctrl_chip_sync_num = EXP_APMEM_CTRL_CHIP_SYNC_NUM, + .emi_apmem_ctrl_chip_sync_addr = EXP_APMEM_CTRL_CHIP_SYNC_ADDR, + .emi_apmem_ctrl_chip_sync_len = EXP_APMEM_CTRL_CHIP_SYNC_LEN, + .emi_apmem_ctrl_chip_print_buff_start = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_START, + .emi_apmem_ctrl_chip_print_buff_len = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_LEN, + .emi_apmem_ctrl_chip_print_buff_idx = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_IDX, + .emi_apmem_ctrl_chip_int_status = EXP_APMEM_CTRL_CHIP_INT_STATUS, + .emi_apmem_ctrl_chip_paded_dump_end = EXP_APMEM_CTRL_CHIP_PAGED_DUMP_END, + .emi_apmem_ctrl_host_outband_assert_w1 = EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1, + .emi_apmem_ctrl_chip_page_dump_num = EXP_APMEM_CTRL_CHIP_PAGE_DUMP_NUM, + .emi_apmem_ctrl_assert_flag = EXP_APMEM_CTRL_ASSERT_FLAG, +}; + +CONSYS_EMI_ADDR_INFO mtk_wcn_emi_addr_info = { + .emi_phy_addr = CONSYS_EMI_FW_PHY_BASE, + .paged_trace_off = CONSYS_EMI_PAGED_TRACE_OFFSET, + .paged_dump_off = CONSYS_EMI_PAGED_DUMP_OFFSET, + .full_dump_off = CONSYS_EMI_FULL_DUMP_OFFSET, + .emi_remap_offset = CONSYS_EMI_MAPPING_OFFSET, + .p_ecso = &mtk_wcn_emi_state_off, + .emi_core_dump_offset = CONSYS_EMI_COREDUMP_OFFSET, + .pda_dl_patch_flag = 1, + .emi_met_size = (32*KBYTE), + .emi_met_data_offset = CONSYS_EMI_MET_DATA_OFFSET, +}; + +WMT_CONSYS_IC_OPS consys_ic_ops = { + .consys_ic_clock_buffer_ctrl = consys_clock_buffer_ctrl, + .consys_ic_hw_reset_bit_set = consys_hw_reset_bit_set, + .consys_ic_hw_spm_clk_gating_enable = consys_hw_spm_clk_gating_enable, + .consys_ic_hw_power_ctrl = consys_hw_power_ctrl, + .consys_ic_ahb_clock_ctrl = consys_ahb_clock_ctrl, + .polling_consys_ic_chipid = polling_consys_chipid, + .consys_ic_acr_reg_setting = consys_acr_reg_setting, + .consys_ic_afe_reg_setting = consys_afe_reg_setting, + .consys_ic_hw_vcn18_ctrl = consys_hw_vcn18_ctrl, + .consys_ic_vcn28_hw_mode_ctrl = consys_vcn28_hw_mode_ctrl, + .consys_ic_hw_vcn28_ctrl = consys_hw_vcn28_ctrl, + .consys_ic_hw_wifi_vcn33_ctrl = consys_hw_wifi_vcn33_ctrl, + .consys_ic_hw_bt_vcn33_ctrl = consys_hw_bt_vcn33_ctrl, + .consys_ic_soc_chipid_get = consys_soc_chipid_get, + .consys_ic_emi_mpu_set_region_protection = consys_emi_mpu_set_region_protection, + .consys_ic_emi_set_remapping_reg = consys_emi_set_remapping_reg, + .ic_bt_wifi_share_v33_spin_lock_init = bt_wifi_share_v33_spin_lock_init, + .consys_ic_clk_get_from_dts = consys_clk_get_from_dts, + .consys_ic_pmic_get_from_dts = consys_pmic_get_from_dts, + .consys_ic_read_irq_info_from_dts = consys_read_irq_info_from_dts, + .consys_ic_read_reg_from_dts = consys_read_reg_from_dts, + .consys_ic_read_cpupcr = consys_read_cpupcr, + .ic_force_trigger_assert_debug_pin = force_trigger_assert_debug_pin, + .consys_ic_co_clock_type = consys_co_clock_type, + .consys_ic_soc_get_emi_phy_add = consys_soc_get_emi_phy_add, + .consys_ic_set_if_pinmux = consys_set_if_pinmux, + .consys_ic_set_dl_rom_patch_flag = consys_set_dl_rom_patch_flag, + .consys_ic_dedicated_log_path_init = consys_dedicated_log_path_init, + .consys_ic_dedicated_log_path_deinit = consys_dedicated_log_path_deinit, + .consys_ic_check_reg_readable = consys_check_reg_readable, + .consys_ic_emi_coredump_remapping = consys_emi_coredump_remapping, + .consys_ic_reset_emi_coredump = consys_reset_emi_coredump, + .consys_ic_clock_fail_dump = consys_ic_clock_fail_dump, + .consys_ic_is_connsys_reg = consys_is_connsys_reg, + .consys_ic_is_host_csr = consys_is_host_csr, + .consys_ic_dump_osc_state = consys_dump_osc_state, + .consys_ic_set_pdma_axi_rready_force_high = consys_set_pdma_axi_rready_force_high, + .consys_ic_calibration_backup_restore = consys_calibration_backup_restore_support, +#ifdef WMT_DEVAPC_CALLBACK + .consys_ic_register_devapc_cb = consyc_register_devapc_cb, +#endif + .consys_ic_is_ant_swap_enable_by_hwid = consys_is_ant_swap_enable_by_hwid, + .consys_ic_get_options = consys_get_options, +}; + +static const struct connlog_emi_config connsys_fw_log_parameter = { + .emi_offset = 0x36500, + .emi_size_total = (192*1024),/* 192KB */ + .emi_size_mcu = (16*1024), + .emi_size_wifi = (64*1024), + .emi_size_bt = (64*1024), + .emi_size_gps = (32*1024), +}; + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +INT32 rom_patch_dl_flag = 1; +UINT32 gJtagCtrl; +UINT32 g_connsys_lp_dump_info[2]; + +#ifdef WMT_DEVAPC_CALLBACK +static struct devapc_vio_callbacks devapc_handle = { + .id = INFRA_SUBSYS_CONN, + .debug_dump = consys_devapc_violation_cb, +}; +#endif + +#if CONSYS_ENALBE_SET_JTAG +#define JTAG_ADDR1_BASE 0x10005000 +#define JTAG_ADDR2_BASE 0x10002800 +#define JTAG_ADDR3_BASE 0x10002600 +#define AP2CONN_JTAG_2WIRE_OFFSET 0xF00 +#endif + +INT32 mtk_wcn_consys_jtag_set_for_mcu(VOID) +{ + INT32 ret = 0; +#if CONSYS_ENALBE_SET_JTAG + UINT32 tmp = 0; + PVOID addr = 0; + PVOID remap_addr1 = 0; + PVOID remap_addr2 = 0; + PVOID remap_addr3 = 0; + + if (gJtagCtrl) { + WMT_PLAT_PR_INFO("WCN jtag set for mcu start...\n"); + + switch (gJtagCtrl) { + case 1: + remap_addr1 = ioremap(JTAG_ADDR1_BASE, 0x1000); + if (remap_addr1 == 0) { + WMT_PLAT_PR_ERR("remap jtag_addr1 fail!\n"); + ret = -1; + goto error; + } + + remap_addr2 = ioremap(JTAG_ADDR2_BASE, 0x100); + if (remap_addr2 == 0) { + WMT_PLAT_PR_ERR("remap jtag_addr2 fail!\n"); + ret = -1; + goto error; + } + + remap_addr3 = ioremap(JTAG_ADDR3_BASE, 0x100); + if (remap_addr3 == 0) { + WMT_PLAT_PR_ERR("remap jtag_addr3 fail!\n"); + ret = -1; + goto error; + } + /* 7-wire jtag pinmux setting*/ + /* PAD AUX Function Selection */ + addr = remap_addr1 + 0x310; + tmp = readl(addr); + tmp = tmp & 0xfffff00f; + tmp = tmp | 0x440; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + addr = remap_addr1 + 0x3c0; + tmp = readl(addr); + tmp = tmp & 0xf00ff00f; + tmp = tmp | 0x4400440; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + addr = remap_addr1 + 0x370; + tmp = readl(addr); + tmp = tmp & 0xfffff0ff; + tmp = tmp | 0x400; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + /* PAD Driving Selection */ + addr = remap_addr2; + tmp = readl(addr); + tmp = tmp & 0xffe381ff; + tmp = tmp | 0x1c7e00; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + addr = remap_addr2 + 0x10; + tmp = readl(addr); + tmp = tmp & 0xfffc7fff; + tmp = tmp | 0x38000; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + addr = remap_addr3 + 0x10; + tmp = readl(addr); + tmp = tmp & 0xf8ffffff; + tmp = tmp | 0x7000000; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + /* PAD PULL Selection */ + addr = remap_addr2 + 0x60; + tmp = readl(addr); + tmp = tmp & 0xfffdfd87; + tmp = tmp | 0x20278; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + addr = remap_addr3 + 0x40; + tmp = readl(addr); + tmp = tmp & 0xffbfffff; + tmp = tmp | 0x400000; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + break; + case 2: + remap_addr1 = ioremap(JTAG_ADDR1_BASE, 0x1000); + if (remap_addr1 == 0) { + WMT_PLAT_PR_ERR("remap jtag_addr1 fail!\n"); + ret = -1; + goto error; + } + + remap_addr2 = ioremap(0x10002400, 0x100); + if (remap_addr2 == 0) { + WMT_PLAT_PR_ERR("remap jtag_addr2 fail!\n"); + ret = -1; + goto error; + } + + /* 2-wire jtag pinmux setting*/ + addr = remap_addr1 + 0x450; + tmp = readl(addr); + tmp = tmp & 0xff0fffff; + tmp = tmp | 0x400000; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + addr = remap_addr1 + 0x430; + tmp = readl(addr); + tmp = tmp & 0xfff0ffff; + tmp = tmp | 0x40000; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + /* Driving Selection */ + + addr = remap_addr2; + tmp = readl(addr); + tmp = tmp & 0xffff99ff; + tmp = tmp | 0x6600; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + /* PULL Selection */ + addr = remap_addr2 + 0x10; + tmp = readl(addr); + tmp = tmp & 0xfffff6ff; + tmp = tmp | 0x900; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + break; + default: + WMT_PLAT_PR_INFO("unsupported options!\n"); + } + + } + +error: + if (remap_addr1) + iounmap(remap_addr1); + if (remap_addr2) + iounmap(remap_addr2); + if (remap_addr3) + iounmap(remap_addr3); +#endif + return ret; +} + +UINT32 mtk_wcn_consys_jtag_flag_ctrl(UINT32 en) +{ + WMT_PLAT_PR_INFO("%s jtag set for MCU\n", en ? "enable" : "disable"); + gJtagCtrl = en; + return 0; +} + +static INT32 consys_clk_get_from_dts(struct platform_device *pdev) +{ + clk_scp_conn_main = devm_clk_get(&pdev->dev, "conn"); + if (IS_ERR(clk_scp_conn_main)) { + WMT_PLAT_PR_ERR("[CCF]cannot get clk_scp_conn_main clock.\n"); + return PTR_ERR(clk_scp_conn_main); + } + WMT_PLAT_PR_DBG("[CCF]clk_scp_conn_main=%p\n", clk_scp_conn_main); + + return 0; +} + +static INT32 consys_pmic_get_from_dts(struct platform_device *pdev) +{ +#if CONSYS_PMIC_CTRL_ENABLE + reg_VCN18 = regulator_get(&pdev->dev, "vcn18"); + if (!reg_VCN18) + WMT_PLAT_PR_ERR("Regulator_get VCN_1V8 fail\n"); + reg_VCN28 = regulator_get(&pdev->dev, "vcn28"); + if (!reg_VCN28) + WMT_PLAT_PR_ERR("Regulator_get VCN_2V8 fail\n"); + reg_VCN33_BT = regulator_get(&pdev->dev, "vcn33_bt"); + if (!reg_VCN33_BT) + WMT_PLAT_PR_ERR("Regulator_get VCN33_BT fail\n"); + reg_VCN33_WIFI = regulator_get(&pdev->dev, "vcn33_wifi"); + if (!reg_VCN33_WIFI) + WMT_PLAT_PR_ERR("Regulator_get VCN33_WIFI fail\n"); +#endif + return 0; +} + +static INT32 consys_co_clock_type(VOID) +{ + return 0; +} + +static INT32 consys_clock_buffer_ctrl(MTK_WCN_BOOL enable) +{ + if (enable) + KERNEL_clk_buf_ctrl(CLK_BUF_CONN, true); /*open XO_WCN*/ + else + KERNEL_clk_buf_ctrl(CLK_BUF_CONN, false); /*close XO_WCN*/ + + return 0; +} + +static VOID consys_set_if_pinmux(MTK_WCN_BOOL enable) +{ + UINT8 *consys_if_pinmux_reg_base = NULL; + + /* Switch D die pinmux for connecting A die */ + consys_if_pinmux_reg_base = ioremap_nocache(CONSYS_IF_PINMUX_REG_BASE, 0x1000); + if (!consys_if_pinmux_reg_base) { + WMT_PLAT_PR_ERR("consys_if_pinmux_reg_base(%x) ioremap fail\n", CONSYS_IF_PINMUX_REG_BASE); + return; + } + + if (enable) { + CONSYS_REG_WRITE(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_01_OFFSET, + (CONSYS_REG_READ(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_01_OFFSET) & + CONSYS_IF_PINMUX_01_MASK) | CONSYS_IF_PINMUX_01_VALUE); + CONSYS_REG_WRITE(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_02_OFFSET, + (CONSYS_REG_READ(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_02_OFFSET) & + CONSYS_IF_PINMUX_02_MASK) | CONSYS_IF_PINMUX_02_VALUE); + } else { + CONSYS_REG_WRITE(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_01_OFFSET, + CONSYS_REG_READ(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_01_OFFSET) & + CONSYS_IF_PINMUX_01_MASK); + CONSYS_REG_WRITE(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_02_OFFSET, + CONSYS_REG_READ(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_02_OFFSET) & + CONSYS_IF_PINMUX_02_MASK); + } + + if (consys_if_pinmux_reg_base) + iounmap(consys_if_pinmux_reg_base); +} + +static VOID consys_hw_reset_bit_set(MTK_WCN_BOOL enable) +{ + UINT32 consys_ver_id = 0; + UINT32 cnt = 0; + + if (enable) { + /*3.assert CONNSYS CPU SW reset 0x10007018 "[12]=1'b1 [31:24]=8'h88 (key)" */ + CONSYS_REG_WRITE((conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET), + CONSYS_REG_READ(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET) | + CONSYS_CPU_SW_RST_BIT | CONSYS_CPU_SW_RST_CTRL_KEY); + } else { + /*16.deassert CONNSYS CPU SW reset 0x10007018 "[12]=1'b0 [31:24] =8'h88 (key)" */ + CONSYS_REG_WRITE(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET, + (CONSYS_REG_READ(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET) & + ~CONSYS_CPU_SW_RST_BIT) | CONSYS_CPU_SW_RST_CTRL_KEY); + + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_base + 0x600); + while (consys_ver_id != 0x1D1E) { + if (cnt > 10) + break; + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_base + 0x600); + WMT_PLAT_PR_INFO("0x18002600(0x%x)\n", consys_ver_id); + WMT_PLAT_PR_INFO("0x1800216c(0x%x)\n", + CONSYS_REG_READ(conn_reg.mcu_base + 0x16c)); + WMT_PLAT_PR_INFO("0x18007104(0x%x)\n", + CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + CONSYS_CPUPCR_OFFSET)); + msleep(20); + cnt++; + } + } +} + +static VOID consys_hw_spm_clk_gating_enable(VOID) +{ +} + +static INT32 consys_hw_power_ctrl(MTK_WCN_BOOL enable) +{ +#if CONSYS_PWR_ON_OFF_API_AVAILABLE + INT32 iRet = 0; +#else + INT32 value = 0; + INT32 i = 0; +#endif + + if (enable) { +#if CONSYS_PWR_ON_OFF_API_AVAILABLE + iRet = clk_prepare_enable(clk_scp_conn_main); + if (iRet) + WMT_PLAT_PR_ERR("clk_prepare_enable(clk_scp_conn_main) fail(%d)\n", iRet); + WMT_PLAT_PR_DBG("clk_prepare_enable(clk_scp_conn_main) ok\n"); +#else + /* turn on SPM clock gating enable PWRON_CONFG_EN 0x10006000 32'h0b160001 */ + CONSYS_REG_WRITE((conn_reg.spm_base + CONSYS_PWRON_CONFG_EN_OFFSET), + (CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWRON_CONFG_EN_OFFSET) & + 0x0000FFFF) | CONSYS_PWRON_CONFG_EN_VALUE); + + /*write assert "conn_top_on" primary part power on, set "connsys_on_domain_pwr_on"=1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_SPM_PWR_ON_BIT); + /*read check "conn_top_on" primary part power status, check "connsys_on_domain_pwr_ack"=1 */ + value = CONSYS_PWR_ON_ACK_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_OFFSET); + while (value == 0) + value = CONSYS_PWR_ON_ACK_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_OFFSET); + /*write assert "conn_top_on" secondary part power on, set "connsys_on_domain_pwr_on_s"=1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_SPM_PWR_ON_S_BIT); + /*read check "conn_top_on" secondary part power status, check "connsys_on_domain_pwr_ack_s"=1 */ + value = CONSYS_PWR_ON_ACK_S_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_S_OFFSET); + while (value == 0) + value = CONSYS_PWR_ON_ACK_S_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_S_OFFSET); + /*write turn on AP-to-CONNSYS bus clock, set "conn_clk_dis"=0 (apply this for bus + *clock toggling) + */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) & + ~CONSYS_CLK_CTRL_BIT); + /*wait 1us*/ + udelay(1); + /*de-assert "conn_top_on" isolation, set "connsys_iso_en"=0 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) & + ~CONSYS_SPM_PWR_ISO_S_BIT); + /*read check "conn_top_off" primary part power status, check + *"connsys_off_domain_pwr_ack"=1 + */ + value = CONSYS_TOP2_PWR_ON_ACK_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_OFFSET); + while (value == 0) + value = CONSYS_TOP2_PWR_ON_ACK_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_OFFSET); + /*read check "conn_top_off" secondary part power status, check + *"connsys_off_domain_pwr_ack_s"=1 + */ + value = CONSYS_TOP2_PWR_ON_ACK_S_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_S_OFFSET); + while (value == 0) + value = CONSYS_TOP2_PWR_ON_ACK_S_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_S_OFFSET); + + /*de-assert CONNSYS S/W reset, set "ap_sw_rst_b"=1 */ + CONSYS_REG_WRITE(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET, + (CONSYS_REG_READ(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET) & + ~CONSYS_SW_RST_BIT) | CONSYS_CPU_SW_RST_CTRL_KEY); + + /*Turn off AHB bus sleep protect (AP2CONN AHB Bus protect) (apply this for INFRA AHB + *bus accessing when CONNSYS had been turned on) + */ + /*disable AHBAXI BUS protect 10001220 [13][14] */ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_EN_OFFSET) & + ~CONSYS_PROT_MASK); + value = ~CONSYS_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_STA_OFFSET); + i = 0; + while (value == 0 || i > 10) { + value = ~CONSYS_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_STA_OFFSET); + i++; + } + /*Disable AXI TX bus sleep protect (CONN2AP AXI Tx Bus protect) (disable sleep + * protection when CONNSYS had been turned on) + * Note : Should turn off AXI Tx sleep protection after AXI Rx sleep protection has + * been turn off. + */ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AXI_TX_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AXI_TX_PROT_EN_OFFSET) & + ~CONSYS_TX_PROT_MASK); + value = ~CONSYS_TX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AXI_TX_PROT_STA_OFFSET); + i = 0; + while (value == 0 || i > 10) { + value = ~CONSYS_TX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AXI_TX_PROT_STA_OFFSET); + i++; + } + /*SPM apsrc/ddr_en hardware mask disable & wait cycle setting*/ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_SPM_APSRC_OFFSET, CONSYS_SPM_APSRC_VALUE); + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_SPM_DDR_EN_OFFSET, CONSYS_SPM_DDR_EN_VALUE); +#endif /* CONSYS_PWR_ON_OFF_API_AVAILABLE */ + } else { +#if CONSYS_PWR_ON_OFF_API_AVAILABLE + clk_disable_unprepare(clk_scp_conn_main); + WMT_PLAT_PR_DBG("clk_disable_unprepare(clk_scp_conn_main) calling\n"); +#else + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_EN_OFFSET) & + CONSYS_PROT_MASK); + value = CONSYS_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_STA_OFFSET); + i = 0; + while (value == CONSYS_PROT_MASK || i > 10) { + value = CONSYS_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_STA_OFFSET); + i++; + } + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AXI_TX_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AXI_TX_PROT_EN_OFFSET) & + CONSYS_TX_PROT_MASK); + value = CONSYS_TX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AXI_TX_PROT_STA_OFFSET); + i = 0; + while (value == CONSYS_TX_PROT_MASK || i > 10) { + value = CONSYS_TX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AXI_TX_PROT_STA_OFFSET); + i++; + } + + /*release connsys ISO, conn_top1_iso_en=1 0x1000632C [1] 1'b1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_SPM_PWR_ISO_S_BIT); + /*de-assert CONNSYS S/W reset, set "ap_sw_rst_b"=1 */ + CONSYS_REG_WRITE(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET, + (CONSYS_REG_READ(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET) & + CONSYS_SW_RST_BIT) | CONSYS_CPU_SW_RST_CTRL_KEY); + /*write conn_clk_dis=1, disable connsys clock 0x1000632C [4] 1'b1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_CLK_CTRL_BIT); + /*wait 1us */ + udelay(1); + /*write conn_top1_pwr_on=0, power off conn_top1 0x1000632C [3:2] 2'b00 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) & + ~(CONSYS_SPM_PWR_ON_BIT | CONSYS_SPM_PWR_ON_S_BIT)); +#endif /* CONSYS_PWR_ON_OFF_API_AVAILABLE */ + } + +#if CONSYS_PWR_ON_OFF_API_AVAILABLE + return iRet; +#else + return 0; +#endif +} + +static INT32 consys_ahb_clock_ctrl(MTK_WCN_BOOL enable) +{ + return 0; +} + +static INT32 polling_consys_chipid(VOID) +{ + INT32 retry = 10; + UINT32 consys_ver_id = 0; + UINT32 consys_hw_ver = 0; + UINT32 consys_fw_ver = 0; + UINT8 *consys_reg_base = NULL; + UINT32 value = 0; + + /*12.poll CONNSYS CHIP ID until chipid is returned 0x18070008 */ + while (retry-- > 0) { + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_top_misc_off_base + CONSYS_IP_VER_OFFSET); + if (consys_ver_id == CONSYS_IP_VER_ID) { + WMT_PLAT_PR_INFO("retry(%d)consys version id(0x%08x)\n", retry, consys_ver_id); + consys_hw_ver = CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HW_ID_OFFSET); + WMT_PLAT_PR_INFO("consys HW version id(0x%x)\n", consys_hw_ver & 0xFFFF); + consys_fw_ver = CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_FW_ID_OFFSET); + WMT_PLAT_PR_INFO("consys FW version id(0x%x)\n", consys_fw_ver & 0xFFFF); + + if (consys_dl_rom_patch(consys_ver_id, consys_fw_ver) == 0) + break; + } + WMT_PLAT_PR_ERR("Read CONSYS version id(0x%08x)", consys_ver_id); + msleep(20); + } + + if (retry <= 0) + return -1; + + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_top_misc_off_base + CONSYS_CONF_ID_OFFSET); + WMT_PLAT_PR_INFO("consys configuration id(0x%x)\n", consys_ver_id & 0xF); + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HW_ID_OFFSET); + WMT_PLAT_PR_INFO("consys HW version id(0x%x)\n", consys_ver_id & 0xFFFF); + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_FW_ID_OFFSET); + WMT_PLAT_PR_INFO("consys FW version id(0x%x)\n", consys_ver_id & 0xFFFF); + + if (wmt_plat_soc_co_clock_flag_get()) { + consys_reg_base = ioremap_nocache(CONSYS_COCLOCK_STABLE_TIME_BASE, 0x100); + if (consys_reg_base) { + /** + * 1. set CR "vcore ready stable time" "XO initial stable time" and + * "XO bg stable time" to optimize the wakeup time after sleep + * 2. clear "source clock enable ack to XO state" mask + */ + value = CONSYS_REG_READ(consys_reg_base); + value = (value & CONSYS_COCLOCK_STABLE_TIME_MASK) | CONSYS_COCLOCK_STABLE_TIME; + CONSYS_REG_WRITE(consys_reg_base, value); + + value = CONSYS_REG_READ(consys_reg_base + CONSYS_COCLOCK_ACK_ENABLE_OFFSET); + value = (value & 0xffff00fe) | 0x600; + CONSYS_REG_WRITE(consys_reg_base + CONSYS_COCLOCK_ACK_ENABLE_OFFSET, value); + iounmap(consys_reg_base); + } else + WMT_PLAT_PR_ERR("connsys co_clock stable time base(0x%x) ioremap fail!\n", + CONSYS_COCLOCK_STABLE_TIME_BASE); + } + + /* EMI control CR setting(hw mode) */ + CONSYS_CLR_BIT(conn_reg.mcu_base + CONSYS_SW_IRQ_OFFSET, CONSYS_EMI_CTRL_VALUE); + + /* toppose_restore_done rollabck */ + CONSYS_REG_WRITE(conn_reg.mcu_top_misc_on_base + CONSYS_TOPPOSE_RESTORE_OFFSET, + (CONSYS_REG_READ(conn_reg.mcu_top_misc_on_base + CONSYS_TOPPOSE_RESTORE_OFFSET) & + CONSYS_TOPPOSE_RESTORE_MASK) | CONSYS_TOPPOSE_RESTORE_VALUE); + + return 0; +} + +static VOID consys_acr_reg_setting(VOID) +{ +} + +static VOID consys_afe_reg_setting(VOID) +{ +#if CONSYS_AFE_REG_SETTING + UINT8 *consys_afe_reg_base = NULL; + + /* update WPLL setting for WPLL issue@LT */ + consys_afe_reg_base = ioremap_nocache(CONSYS_AFE_REG_BASE, 0x100); + if (consys_afe_reg_base) { + + UINT32 value = CONSYS_REG_READ(consys_afe_reg_base + CONSYS_AFE_RG_WBG_PLL_03_OFFSET); + + value = (value & 0xffe7ffff) | 0x80000; + CONSYS_REG_WRITE(consys_afe_reg_base + CONSYS_AFE_RG_WBG_PLL_03_OFFSET, value); + iounmap(consys_afe_reg_base); + } else + WMT_PLAT_PR_ERR("AFE base(0x%x) ioremap fail!\n", CONSYS_AFE_REG_BASE); +#endif +} + +static INT32 consys_hw_vcn18_ctrl(MTK_WCN_BOOL enable) +{ +#if CONSYS_PMIC_CTRL_ENABLE + if (enable) { + /*need PMIC driver provide new API protocol */ + /*1.AP power on VCN_1V8 LDO (with PMIC_WRAP API) VCN_1V8 */ + /*set vcn18 SW mode*/ + KERNEL_upmu_set_reg_value(MT6358_LDO_VCN18_OP_EN, 0x1); + if (reg_VCN18) { + regulator_set_voltage(reg_VCN18, 1800000, 1800000); + if (regulator_enable(reg_VCN18)) + WMT_PLAT_PR_ERR("enable VCN18 fail\n"); + else + WMT_PLAT_PR_DBG("enable VCN18 ok\n"); + } + + if (!(wmt_lib_get_ext_ldo())) { + KERNEL_upmu_set_reg_value(MT6358_LDO_VCN33_OP_EN, 0x1); + if (reg_VCN33_BT) { + regulator_set_voltage(reg_VCN33_BT, 3300000, 3300000); + if (regulator_enable(reg_VCN33_BT)) + WMT_PLAT_PR_ERR("WMT do BT PMIC on fail!\n"); + } + } else + WMT_PLAT_PR_INFO("VCN33 uses external LDO!\n"); + } else { + if (!(wmt_lib_get_ext_ldo())) { + if (reg_VCN33_BT) + regulator_disable(reg_VCN33_BT); + } + + /*AP power off MT6358 VCN_1V8 LDO */ + if (reg_VCN18) { + if (regulator_disable(reg_VCN18)) + WMT_PLAT_PR_ERR("disable VCN_1V8 fail!\n"); + else + WMT_PLAT_PR_DBG("disable VCN_1V8 ok\n"); + } + } +#endif + return 0; +} + +static VOID consys_vcn28_hw_mode_ctrl(UINT32 enable) +{ +#if CONSYS_PMIC_CTRL_ENABLE + if (enable) { + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN28_HW0_OP_EN, 1); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN28_HW0_OP_CFG, 0); + } else { + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN28_HW0_OP_EN, 0); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN28_HW0_OP_CFG, 0); + } +#endif +} + +static INT32 consys_hw_vcn28_ctrl(UINT32 enable) +{ +#if CONSYS_PMIC_CTRL_ENABLE + if (enable) { + /*in co-clock mode,need to turn on vcn28 when fm on */ + if (reg_VCN28) { + regulator_set_voltage(reg_VCN28, 2800000, 2800000); + if (regulator_enable(reg_VCN28)) + WMT_PLAT_PR_ERR("WMT do VCN28 PMIC on fail!\n"); + } + WMT_PLAT_PR_INFO("turn on vcn28 for fm/gps usage in co-clock mode\n"); + } else { + /*in co-clock mode,need to turn off vcn28 when fm off */ + if (reg_VCN28) + regulator_disable(reg_VCN28); + WMT_PLAT_PR_INFO("turn off vcn28 for fm/gps usage in co-clock mode\n"); + } +#endif + return 0; +} + +static INT32 consys_hw_bt_vcn33_ctrl(UINT32 enable) +{ +#if 0 +#if CONSYS_BT_WIFI_SHARE_V33 + /* spin_lock_irqsave(&gBtWifiV33.lock,gBtWifiV33.flags); */ + if (enable) { + if (gBtWifiV33.counter == 1) { + gBtWifiV33.counter++; + WMT_PLAT_PR_DBG("V33 has been enabled,counter(%d)\n", gBtWifiV33.counter); + } else if (gBtWifiV33.counter == 2) { + WMT_PLAT_PR_DBG("V33 has been enabled,counter(%d)\n", gBtWifiV33.counter); + } else { +#if CONSYS_PMIC_CTRL_ENABLE + /*do BT PMIC on,depenency PMIC API ready */ + /*switch BT PALDO control from SW mode to HW mode:0x416[5]-->0x1 */ + /* VOL_DEFAULT, VOL_3300, VOL_3400, VOL_3500, VOL_3600 */ + hwPowerOn(MT6351_POWER_LDO_VCN33_BT, VOL_3300 * 1000, "wcn_drv"); + mt6351_upmu_set_rg_vcn33_on_ctrl(1); +#endif + WMT_PLAT_PR_INFO("WMT do BT/WIFI v3.3 on\n"); + gBtWifiV33.counter++; + } + + } else { + if (gBtWifiV33.counter == 1) { + /*do BT PMIC off */ + /*switch BT PALDO control from HW mode to SW mode:0x416[5]-->0x0 */ +#if CONSYS_PMIC_CTRL_ENABLE + mt6351_upmu_set_rg_vcn33_on_ctrl(0); + hwPowerDown(MT6351_POWER_LDO_VCN33_BT, "wcn_drv"); +#endif + WMT_PLAT_PR_INFO("WMT do BT/WIFI v3.3 off\n"); + gBtWifiV33.counter--; + } else if (gBtWifiV33.counter == 2) { + gBtWifiV33.counter--; + WMT_PLAT_PR_DBG("V33 no need disabled,counter(%d)\n", gBtWifiV33.counter); + } else { + WMT_PLAT_PR_DBG("V33 has been disabled,counter(%d)\n", gBtWifiV33.counter); + } + + } + /* spin_unlock_irqrestore(&gBtWifiV33.lock,gBtWifiV33.flags); */ +#else + if (enable) { + /*do BT PMIC on,depenency PMIC API ready */ + /*switch BT PALDO control from SW mode to HW mode:0x416[5]-->0x1 */ +#if CONSYS_PMIC_CTRL_ENABLE + /* VOL_DEFAULT, VOL_3300, VOL_3400, VOL_3500, VOL_3600 */ + if (reg_VCN33_BT) { + regulator_set_voltage(reg_VCN33_BT, 3300000, 3300000); + if (regulator_enable(reg_VCN33_BT)) + WMT_PLAT_PR_ERR("WMT do BT PMIC on fail!\n"); + } + + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_HW0_OP_EN, 1); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_HW0_OP_CFG, 0); +#endif + WMT_PLAT_PR_DBG("WMT do BT PMIC on\n"); + } else { + /*do BT PMIC off */ + /*switch BT PALDO control from HW mode to SW mode:0x416[5]-->0x0 */ +#if CONSYS_PMIC_CTRL_ENABLE + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_HW0_OP_EN, 0); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_HW0_OP_CFG, 0); + if (reg_VCN33_BT) + regulator_disable(reg_VCN33_BT); +#endif + WMT_PLAT_PR_DBG("WMT do BT PMIC off\n"); + } +#endif + +#endif + return 0; +} + +static INT32 consys_hw_wifi_vcn33_ctrl(UINT32 enable) +{ +#if 0 +#if CONSYS_BT_WIFI_SHARE_V33 + mtk_wcn_consys_hw_bt_paldo_ctrl(enable); +#else + if (enable) { + /*do WIFI PMIC on,depenency PMIC API ready */ + /*switch WIFI PALDO control from SW mode to HW mode:0x418[14]-->0x1 */ +#if CONSYS_PMIC_CTRL_ENABLE + if (reg_VCN33_WIFI) { + regulator_set_voltage(reg_VCN33_WIFI, 3300000, 3300000); + if (regulator_enable(reg_VCN33_WIFI)) + WMT_PLAT_PR_ERR("WMT do WIFI PMIC on fail!\n"); + } + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_HW0_OP_EN, 1); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_HW0_OP_CFG, 0); +#endif + WMT_PLAT_PR_DBG("WMT do WIFI PMIC on\n"); + } else { + /*do WIFI PMIC off */ + /*switch WIFI PALDO control from HW mode to SW mode:0x418[14]-->0x0 */ +#if CONSYS_PMIC_CTRL_ENABLE + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_HW0_OP_EN, 0); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_HW0_OP_CFG, 0); + if (reg_VCN33_WIFI) + regulator_disable(reg_VCN33_WIFI); +#endif + WMT_PLAT_PR_DBG("WMT do WIFI PMIC off\n"); + } + +#endif + +#endif + return 0; +} + +static INT32 consys_emi_mpu_set_region_protection(VOID) +{ +#ifdef CONFIG_MTK_EMI + struct emi_region_info_t region_info; + + /*set MPU for EMI share Memory */ + WMT_PLAT_PR_INFO("setting MPU for EMI share memory\n"); + + region_info.start = gConEmiPhyBase; + region_info.end = gConEmiPhyBase + gConEmiSize - 1; + region_info.region = 26; + SET_ACCESS_PERMISSION(region_info.apc, LOCK, + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, + NO_PROTECTION, FORBIDDEN, NO_PROTECTION); + emi_mpu_set_protection(®ion_info); +#endif + return 0; +} + +static UINT32 consys_emi_set_remapping_reg(VOID) +{ + UINT32 addrPhy = 0; + UINT32 value = 0; + + mtk_wcn_emi_addr_info.emi_ap_phy_addr = gConEmiPhyBase; + mtk_wcn_emi_addr_info.emi_size = gConEmiSize; + + /*consys to ap emi remapping register:10001380, cal remapping address */ + addrPhy = (gConEmiPhyBase >> 24) & 0xFFF; + value = CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET); + WMT_PLAT_PR_INFO("before CONSYS_EMI_MAPPING read:0x%zx, value:0x%x\n", + conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET, value); + + value = value & 0xFFFFF000; + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET, value | addrPhy); + WMT_PLAT_PR_INFO("CONSYS_EMI_MAPPING dump in restore cb(0x%08x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET)); + + /*Perisys Configuration Registers remapping*/ + addrPhy = ((0x10003000 >> 24) & 0xFFF) << 16; + value = CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_PERI_MAPPING_OFFSET); + value = value & 0xF000FFFF; + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_EMI_PERI_MAPPING_OFFSET, value | addrPhy); + + WMT_PLAT_PR_INFO("CONSYS_EMI_MAPPING dump in restore cb(0x%08x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_PERI_MAPPING_OFFSET)); + + mtk_wcn_emi_addr_info.emi_ram_bt_buildtime_offset = + CONSYS_EMI_RAM_BT_BUILDTIME_OFFSET; + mtk_wcn_emi_addr_info.emi_ram_wifi_buildtime_offset = + CONSYS_EMI_RAM_WIFI_BUILDTIME_OFFSET; + mtk_wcn_emi_addr_info.emi_ram_mcu_buildtime_offset = + CONSYS_EMI_RAM_MCU_BUILDTIME_OFFSET; + mtk_wcn_emi_addr_info.emi_patch_mcu_buildtime_offset = + CONSYS_EMI_PATCH_MCU_BUILDTIME_OFFSET; + + return 0; +} + +static INT32 bt_wifi_share_v33_spin_lock_init(VOID) +{ +#if CONSYS_BT_WIFI_SHARE_V33 + gBtWifiV33.counter = 0; + spin_lock_init(&gBtWifiV33.lock); +#endif + return 0; +} + +static INT32 consys_read_irq_info_from_dts(struct platform_device *pdev, PINT32 irq_num, PUINT32 irq_flag) +{ + struct device_node *node; + + node = pdev->dev.of_node; + if (node) { + *irq_num = irq_of_parse_and_map(node, 0); + *irq_flag = irq_get_trigger_type(*irq_num); + WMT_PLAT_PR_INFO("get irq id(%d) and irq trigger flag(%d) from DT\n", *irq_num, + *irq_flag); + } else { + WMT_PLAT_PR_ERR("[%s] can't find CONSYS compatible node\n", __func__); + return -1; + } + + return 0; +} + +static INT32 consys_read_reg_from_dts(struct platform_device *pdev) +{ + INT32 iRet = -1; + struct device_node *node = NULL; + + node = pdev->dev.of_node; + if (node) { + /* registers base address */ + conn_reg.mcu_base = (SIZE_T) of_iomap(node, MCU_BASE_INDEX); + conn_reg.ap_rgu_base = (SIZE_T) of_iomap(node, TOP_RGU_BASE_INDEX); + conn_reg.topckgen_base = (SIZE_T) of_iomap(node, INFRACFG_AO_BASE_INDEX); + conn_reg.spm_base = (SIZE_T) of_iomap(node, SPM_BASE_INDEX); + conn_reg.mcu_top_misc_off_base = (SIZE_T) of_iomap(node, MCU_TOP_MISC_OFF_BASE_INDEX); + conn_reg.mcu_conn_hif_on_base = (SIZE_T) of_iomap(node, MCU_CONN_HIF_ON_BASE_INDEX); + conn_reg.mcu_cfg_on_base = (SIZE_T) of_iomap(node, MCU_CFG_ON_BASE_INDEX); + conn_reg.mcu_cirq_base = (SIZE_T) of_iomap(node, MCU_CIRQ_BASE_INDEX); + conn_reg.mcu_top_misc_on_base = (SIZE_T) of_iomap(node, MCU_TOP_MISC_ON_BASE_INDEX); + conn_reg.mcu_conn_hif_pdma_base = (SIZE_T) of_iomap(node, MCU_CONN_HIF_PDMA_BASE_INDEX); + + WMT_PLAT_PR_DBG("Get base mcu(0x%zx), rgu(0x%zx), topckgen(0x%zx), spm(0x%zx)\n", + conn_reg.mcu_base, conn_reg.ap_rgu_base, + conn_reg.topckgen_base, conn_reg.spm_base); + WMT_PLAT_PR_DBG("Get base misc_off(0x%zx), hif_on(0x%zx), cfg_on(0x%zx), misc_on(0x%zx)\n", + conn_reg.mcu_top_misc_off_base, + conn_reg.mcu_conn_hif_on_base, + conn_reg.mcu_cfg_on_base, + conn_reg.mcu_top_misc_on_base); + WMT_PLAT_PR_DBG("Get hif_pdma(0x%zx)\n", + conn_reg.mcu_conn_hif_pdma_base); + } else { + WMT_PLAT_PR_ERR("[%s] can't find CONSYS compatible node\n", __func__); + return iRet; + } + + return 0; +} + +static VOID force_trigger_assert_debug_pin(VOID) +{ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AP2CONN_OSC_EN_OFFSET) & ~CONSYS_AP2CONN_WAKEUP_BIT); + WMT_PLAT_PR_INFO("enable:dump CONSYS_AP2CONN_OSC_EN_REG(0x%x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET)); + usleep_range(64, 96); + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AP2CONN_OSC_EN_OFFSET) | CONSYS_AP2CONN_WAKEUP_BIT); + WMT_PLAT_PR_INFO("disable:dump CONSYS_AP2CONN_OSC_EN_REG(0x%x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET)); +} + +static UINT32 consys_read_cpupcr(VOID) +{ + if (conn_reg.mcu_conn_hif_on_base == 0) + return 0; + + return CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + CONSYS_CPUPCR_OFFSET); +} + +static UINT32 consys_soc_chipid_get(VOID) +{ + return PLATFORM_SOC_CHIP; +} + +static P_CONSYS_EMI_ADDR_INFO consys_soc_get_emi_phy_add(VOID) +{ + return &mtk_wcn_emi_addr_info; +} + +P_WMT_CONSYS_IC_OPS mtk_wcn_get_consys_ic_ops(VOID) +{ + return &consys_ic_ops; +} + +static INT32 consys_dl_rom_patch(UINT32 ip_ver, UINT32 fw_ver) +{ + if (rom_patch_dl_flag) { + if (mtk_wcn_soc_rom_patch_dwn(ip_ver, fw_ver) == 0) + rom_patch_dl_flag = 1; + else + return -1; + } + + return 0; +} + +static VOID consys_set_dl_rom_patch_flag(INT32 flag) +{ + rom_patch_dl_flag = flag; +} + +static INT32 consys_dedicated_log_path_init(struct platform_device *pdev) +{ + struct device_node *node; + UINT32 irq_num; + UINT32 irq_flag; + INT32 iret = -1; + struct connlog_irq_config irq_config; + + memset(&irq_config, 0, sizeof(struct connlog_irq_config)); + node = pdev->dev.of_node; + if (node) { + irq_num = irq_of_parse_and_map(node, 2); + irq_flag = irq_get_trigger_type(irq_num); + WMT_PLAT_PR_INFO("get conn2ap_sw_irq id(%d) and irq trigger flag(%d) from DT\n", irq_num, + irq_flag); + } else { + WMT_PLAT_PR_ERR("[%s] can't find CONSYS compatible node\n", __func__); + return iret; + } + + irq_config.irq_num = irq_num; + irq_config.irq_flag = irq_flag; + irq_config.irq_callback = NULL; + + connsys_dedicated_log_path_apsoc_init(gConEmiPhyBase, &connsys_fw_log_parameter, &irq_config); +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH + fw_log_wmt_init(); +#endif + return 0; +} + +static VOID consys_dedicated_log_path_deinit(VOID) +{ +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH + fw_log_wmt_deinit(); +#endif + connsys_dedicated_log_path_apsoc_deinit(); +} + +static INT32 consys_check_reg_readable(VOID) +{ + INT32 can_read = 0; + UINT32 value = 0; + + if (conn_reg.mcu_cfg_on_base != 0 && + conn_reg.mcu_top_misc_on_base != 0) { + /*check connsys clock and sleep status*/ + CONSYS_REG_WRITE(conn_reg.mcu_conn_hif_on_base, CONSYS_CLOCK_CHECK_VALUE); + udelay(1000); + value = CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base); + if ((value & CONSYS_HCLK_CHECK_BIT) && + (value & CONSYS_OSCCLK_CHECK_BIT) && + ((value & CONSYS_SLEEP_CHECK_BIT) == 0)) + can_read = 1; + } + + if (!can_read) + WMT_PLAT_PR_ERR("connsys clock check fail 0x18007000(0x%x)\n", value); + + return can_read; +} + +static INT32 consys_emi_coredump_remapping(UINT8 __iomem **addr, UINT32 enable) +{ + if (enable) { + *addr = ioremap_nocache(gConEmiPhyBase + CONSYS_EMI_COREDUMP_OFFSET, CONSYS_EMI_MEM_SIZE); + if (*addr) { + WMT_PLAT_PR_INFO("COREDUMP EMI mapping OK virtual(0x%p) physical(0x%x)\n", + *addr, (UINT32) gConEmiPhyBase + CONSYS_EMI_COREDUMP_OFFSET); + memset_io(*addr, 0, CONSYS_EMI_MEM_SIZE); + } else { + WMT_PLAT_PR_ERR("EMI mapping fail\n"); + return -1; + } + } else { + if (*addr) { + iounmap(*addr); + *addr = NULL; + } + } + return 0; +} + +static INT32 consys_reset_emi_coredump(UINT8 __iomem *addr) +{ + if (!addr) { + WMT_PLAT_PR_ERR("get virtual address fail\n"); + return -1; + } + WMT_PLAT_PR_INFO("Reset EMI(0xF0068000 ~ 0xF0068400) and (0xF0070400 ~ 0xF0078400)\n"); + /* reset 0xF0068000 ~ 0xF0068400 (1K) */ + memset_io(addr, 0, 0x400); + /* reset 0xF0070400 ~ 0xF0078400 (32K) */ + memset_io(addr + CONSYS_EMI_PAGED_DUMP_OFFSET, 0, 0x8000); + return 0; +} + +static INT32 consys_is_connsys_reg(UINT32 addr) +{ + if (addr > 0x18000000 && addr < 0x180FFFFF) { + if (addr >= 0x18007000 && addr <= 0x18007FFF) + return 0; + + return 1; + } + + return 0; +} + +static INT32 consys_is_host_csr(SIZE_T addr) +{ + SIZE_T start_offset = 0x000; + SIZE_T end_offset = 0xFFF; + + if (addr >= (CONN_HIF_ON_BASE_ADDR + start_offset) && + addr <= (CONN_HIF_ON_BASE_ADDR + end_offset)) + return 1; + + if (conn_reg.mcu_conn_hif_on_base != 0 && + addr >= (conn_reg.mcu_conn_hif_on_base + start_offset) && + addr <= (conn_reg.mcu_conn_hif_on_base + end_offset)) + return 1; + + return 0; +} + +static VOID consys_ic_clock_fail_dump(VOID) +{ + INT8 *addr; + char *buffer, *temp; + INT32 size = 1024; + + /* make sure buffer size is big enough */ + buffer = osal_malloc(size); + if (!buffer) + return; + + temp = buffer; + temp += sprintf(temp, "CONN_HIF_TOP_MISC=0x%08x CONN_HIF_BUSY_STATUS=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HIF_TOP_MISC), + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HIF_BUSY_STATUS)); + + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_HIF_DBG_IDX, 0x3333); + temp += sprintf(temp, "Write CONSYS_HIF_DBG_IDX to 0x3333\n"); + + temp += sprintf(temp, "CONSYS_HIF_DBG_PROBE=0x%08x CONN_HIF_TOP_MISC=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HIF_DBG_PROBE), + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HIF_TOP_MISC)); + + temp += sprintf(temp, "CONN_HIF_BUSY_STATUS=0x%08x CONN_HIF_PDMA_BUSY_STATUS=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HIF_BUSY_STATUS), + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HIF_PDMA_BUSY_STATUS)); + + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_HIF_DBG_IDX, 0x2222); + temp += sprintf(temp, "Write CONSYS_HIF_DBG_IDX to 0x2222\n"); + + temp += sprintf(temp, "CONSYS_HIF_DBG_PROBE=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HIF_DBG_PROBE)); + + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_HIF_DBG_IDX, 0x3333); + temp += sprintf(temp, "Write CONSYS_HIF_DBG_IDX to 0x3333\n"); + + temp += sprintf(temp, "CONSYS_HIF_DBG_PROBE=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HIF_DBG_PROBE)); + + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_HIF_DBG_IDX, 0x4444); + temp += sprintf(temp, "Write CONSYS_HIF_DBG_IDX to 0x4444\n"); + + temp += sprintf(temp, "CONSYS_HIF_DBG_PROBE=0x%08x CONN_MCU_EMI_CONTROL=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HIF_DBG_PROBE), + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_SW_IRQ_OFFSET)); + temp += sprintf(temp, "EMI_CONTROL_DBG_PROBE=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + EMI_CONTROL_DBG_PROBE)); + temp += sprintf(temp, "CONN_MCU_CLOCK_CONTROL=0x%08x CONN_MCU_BUS_CONTROL=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_CLOCK_CONTROL), + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_BUS_CONTROL)); + + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_DEBUG_SELECT, 0x003e3d00); + temp += sprintf(temp, "Write CONSYS_DEBUG_SELECT to 0x003e3d00\n"); + + temp += sprintf(temp, "CONN_MCU_DEBUG_STATUS=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_DEBUG_STATUS)); + + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_DEBUG_SELECT, 0x00403f00); + temp += sprintf(temp, "Write CONSYS_DEBUG_SELECT to 0x00403f00\n"); + + temp += sprintf(temp, "CONN_MCU_DEBUG_STATUS=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_DEBUG_STATUS)); + + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_DEBUG_SELECT, 0x00424100); + temp += sprintf(temp, "Write CONSYS_DEBUG_SELECT to 0x00424100\n"); + + temp += sprintf(temp, "CONN_MCU_DEBUG_STATUS=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_DEBUG_STATUS)); + + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_DEBUG_SELECT, 0x00444300); + temp += sprintf(temp, "Write CONSYS_DEBUG_SELECT to 0x00444300\n"); + + temp += sprintf(temp, "CONN_MCU_DEBUG_STATUS=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_DEBUG_STATUS)); + + addr = ioremap_nocache(0x10001B20, 0x100); + /* 0x1020E804 */ + temp += sprintf(temp, "0x10001B20=0x%08x\n", CONSYS_REG_READ(addr)); + iounmap(addr); + + WMT_PLAT_PR_ERR("%s length = %d", buffer, osal_strlen(buffer)); + osal_free(buffer); +} + +/* + * Before calling this function, should check consys state + * ex: consys power on already and reg_readable + */ + +static INT32 consys_dump_osc_state(P_CONSYS_STATE state) +{ +#if 0 + UINT8 __iomem *addr; +#endif + + CONSYS_REG_WRITE(CONN_CFG_ON_CONN_ON_HOST_MAILBOX_MCU_ADDR, 0x1); + CONSYS_REG_WRITE(CONN_CFG_ON_CONN_ON_MON_CTL_ADDR, 0x80000001); + CONSYS_REG_WRITE(CONN_CFG_ON_CONN_ON_DBGSEL_ADDR, 0x3); + state->lp[0] = (UINT32)CONN_CFG_ON_CONN_ON_MON_FLAG_RECORD_MAPPING_AP_ADDR; + state->lp[1] = CONSYS_REG_READ(CONN_CFG_ON_CONN_ON_MON_FLAG_RECORD_ADDR); + WMT_PLAT_PR_INFO("0x%08x: 0x%x\n", state->lp[0], state->lp[1]); + CONSYS_REG_WRITE(CONN_CFG_ON_CONN_ON_HOST_MAILBOX_MCU_ADDR, 0x0); + +#if 0 + addr = ioremap_nocache(gConEmiPhyBase + 0x66500, sizeof(struct consys_sw_state)); + if (addr) + memcpy_fromio(&state->sw_state, addr, sizeof(struct consys_sw_state)); + else + WMT_PLAT_PR_WARN("ioremap fail\n"); + iounmap(addr); +#endif + + return MTK_WCN_BOOL_TRUE; +} + +static VOID consys_set_pdma_axi_rready_force_high(UINT32 enable) +{ + if (enable) + CONSYS_SET_BIT(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_PDMA_AXI_RREADY, + CONSYS_PDMA_AXI_RREADY_MASK); + else if ((CONSYS_REG_READ(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_PDMA_AXI_RREADY) & + CONSYS_PDMA_AXI_RREADY_MASK) != 0) + CONSYS_CLR_BIT(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_PDMA_AXI_RREADY, + CONSYS_PDMA_AXI_RREADY_MASK); +} + +static INT32 consys_calibration_backup_restore_support(VOID) +{ + return 1; +} + +#ifdef WMT_DEVAPC_CALLBACK +static VOID consys_devapc_violation_cb(VOID) +{ + /** + * Don't use wmt_lib_trigger_assert() because it will invoke vmalloc and then cause KE since + * this callback is supposed to be invoked in DEVAPC exception hanlder. + */ + wmt_lib_trigger_assert_keyword_delay(WMTDRV_TYPE_WMT, 46, "DEVAPC Violation"); +} + +static VOID consyc_register_devapc_cb(VOID) +{ + register_devapc_vio_callback(&devapc_handle); +} +#endif + +static INT32 consys_is_ant_swap_enable_by_hwid(INT32 pin_num) +{ + return !connectivity_export_gpio_get_tristate_input(pin_num); +} + +static UINT64 consys_get_options(VOID) +{ + UINT64 options = OPT_QUERY_ADIE | + OPT_WIFI_LTE_COEX | + OPT_BT_TSSI_FROM_WIFI_CONFIG_NEW_OPID | + OPT_INIT_COEX_BEFORE_RF_CALIBRATION | + OPT_COEX_CONFIG_ADJUST | + OPT_COEX_CONFIG_ADJUST_NEW_FLAG | + OPT_WIFI_LTE_COEX_TABLE_3 | + OPT_COEX_EXT_ELNA_GAIN_P1_SUPPORT | + OPT_NORMAL_PATCH_DWN_3 | + OPT_PATCH_CHECKSUM; + return options; +} + diff --git a/drivers/misc/mediatek/connectivity/common/common_main/platform/mt6771.c b/drivers/misc/mediatek/connectivity/common/common_main/platform/mt6771.c new file mode 100644 index 0000000000000000000000000000000000000000..5609b214a79bd562923b8ce444e130453e2ee1c5 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/platform/mt6771.c @@ -0,0 +1,1130 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +#ifdef DFT_TAG +#undef DFT_TAG +#endif +#define DFT_TAG "[WMT-CONSYS-HW]" + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include +#include +#include +#include +#include +#include "osal_typedef.h" +#include "mt6771.h" +#include "mtk_wcn_consys_hw.h" + +#ifdef CONFIG_MTK_EMI +#include +#endif + +#if CONSYS_PMIC_CTRL_ENABLE +#include +#include +#endif + +#ifdef CONFIG_MTK_HIBERNATION +#include +#endif + +#include +#include + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +static INT32 consys_clock_buffer_ctrl(MTK_WCN_BOOL enable); +static VOID consys_hw_reset_bit_set(MTK_WCN_BOOL enable); +static VOID consys_hw_spm_clk_gating_enable(VOID); +static INT32 consys_hw_power_ctrl(MTK_WCN_BOOL enable); +static INT32 consys_ahb_clock_ctrl(MTK_WCN_BOOL enable); +static INT32 polling_consys_chipid(VOID); +static VOID update_consys_rom_desel(VOID); +static VOID consys_hang_debug_info(VOID); +static VOID consys_acr_reg_setting(VOID); +static VOID consys_afe_reg_setting(VOID); +static INT32 consys_hw_vcn18_ctrl(MTK_WCN_BOOL enable); +static VOID consys_vcn28_hw_mode_ctrl(UINT32 enable); +static INT32 consys_hw_vcn28_ctrl(UINT32 enable); +static INT32 consys_hw_wifi_vcn33_ctrl(UINT32 enable); +static INT32 consys_hw_bt_vcn33_ctrl(UINT32 enable); +static UINT32 consys_soc_chipid_get(VOID); +static INT32 consys_emi_mpu_set_region_protection(VOID); +static UINT32 consys_emi_set_remapping_reg(VOID); +static INT32 bt_wifi_share_v33_spin_lock_init(VOID); +static INT32 consys_clk_get_from_dts(struct platform_device *pdev); +static INT32 consys_pmic_get_from_dts(struct platform_device *pdev); +static INT32 consys_read_irq_info_from_dts(struct platform_device *pdev, PINT32 irq_num, PUINT32 irq_flag); +static INT32 consys_read_reg_from_dts(struct platform_device *pdev); +static UINT32 consys_read_cpupcr(VOID); +static VOID force_trigger_assert_debug_pin(VOID); +static INT32 consys_co_clock_type(VOID); +static P_CONSYS_EMI_ADDR_INFO consys_soc_get_emi_phy_add(VOID); +static VOID consys_set_if_pinmux(MTK_WCN_BOOL enable); +static INT32 consys_emi_coredump_remapping(UINT8 __iomem **addr, UINT32 enable); +static INT32 consys_reset_emi_coredump(UINT8 __iomem *addr); +static INT32 consys_dump_osc_state(P_CONSYS_STATE state); +static UINT64 consys_get_options(VOID); + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ +#if CONSYS_BT_WIFI_SHARE_V33 +struct bt_wifi_v33_status gBtWifiV33; +#endif + +/* CCF part */ +struct clk *clk_scp_conn_main; /*ctrl conn_power_on/off */ + +/* PMIC part */ +#if CONSYS_PMIC_CTRL_ENABLE +struct regulator *reg_VCN18; +struct regulator *reg_VCN28; +struct regulator *reg_VCN33_BT; +struct regulator *reg_VCN33_WIFI; +#endif + +EMI_CTRL_STATE_OFFSET mtk_wcn_emi_state_off = { + .emi_apmem_ctrl_state = EXP_APMEM_CTRL_STATE, + .emi_apmem_ctrl_host_sync_state = EXP_APMEM_CTRL_HOST_SYNC_STATE, + .emi_apmem_ctrl_host_sync_num = EXP_APMEM_CTRL_HOST_SYNC_NUM, + .emi_apmem_ctrl_chip_sync_state = EXP_APMEM_CTRL_CHIP_SYNC_STATE, + .emi_apmem_ctrl_chip_sync_num = EXP_APMEM_CTRL_CHIP_SYNC_NUM, + .emi_apmem_ctrl_chip_sync_addr = EXP_APMEM_CTRL_CHIP_SYNC_ADDR, + .emi_apmem_ctrl_chip_sync_len = EXP_APMEM_CTRL_CHIP_SYNC_LEN, + .emi_apmem_ctrl_chip_print_buff_start = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_START, + .emi_apmem_ctrl_chip_print_buff_len = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_LEN, + .emi_apmem_ctrl_chip_print_buff_idx = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_IDX, + .emi_apmem_ctrl_chip_int_status = EXP_APMEM_CTRL_CHIP_INT_STATUS, + .emi_apmem_ctrl_chip_paded_dump_end = EXP_APMEM_CTRL_CHIP_PAGED_DUMP_END, + .emi_apmem_ctrl_host_outband_assert_w1 = EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1, + .emi_apmem_ctrl_chip_page_dump_num = EXP_APMEM_CTRL_CHIP_PAGE_DUMP_NUM, + .emi_apmem_ctrl_assert_flag = EXP_APMEM_CTRL_ASSERT_FLAG, +}; + +CONSYS_EMI_ADDR_INFO mtk_wcn_emi_addr_info = { + .emi_phy_addr = CONSYS_EMI_FW_PHY_BASE, + .paged_trace_off = CONSYS_EMI_PAGED_TRACE_OFFSET, + .paged_dump_off = CONSYS_EMI_PAGED_DUMP_OFFSET, + .full_dump_off = CONSYS_EMI_FULL_DUMP_OFFSET, + .emi_remap_offset = CONSYS_EMI_MAPPING_OFFSET, + .p_ecso = &mtk_wcn_emi_state_off, + .emi_core_dump_offset = CONSYS_EMI_COREDUMP_OFFSET, +}; + +WMT_CONSYS_IC_OPS consys_ic_ops = { + .consys_ic_clock_buffer_ctrl = consys_clock_buffer_ctrl, + .consys_ic_hw_reset_bit_set = consys_hw_reset_bit_set, + .consys_ic_hw_spm_clk_gating_enable = consys_hw_spm_clk_gating_enable, + .consys_ic_hw_power_ctrl = consys_hw_power_ctrl, + .consys_ic_ahb_clock_ctrl = consys_ahb_clock_ctrl, + .polling_consys_ic_chipid = polling_consys_chipid, + .update_consys_rom_desel_value = update_consys_rom_desel, + .consys_hang_debug = consys_hang_debug_info, + .consys_ic_acr_reg_setting = consys_acr_reg_setting, + .consys_ic_afe_reg_setting = consys_afe_reg_setting, + .consys_ic_hw_vcn18_ctrl = consys_hw_vcn18_ctrl, + .consys_ic_vcn28_hw_mode_ctrl = consys_vcn28_hw_mode_ctrl, + .consys_ic_hw_vcn28_ctrl = consys_hw_vcn28_ctrl, + .consys_ic_hw_wifi_vcn33_ctrl = consys_hw_wifi_vcn33_ctrl, + .consys_ic_hw_bt_vcn33_ctrl = consys_hw_bt_vcn33_ctrl, + .consys_ic_soc_chipid_get = consys_soc_chipid_get, + .consys_ic_emi_mpu_set_region_protection = consys_emi_mpu_set_region_protection, + .consys_ic_emi_set_remapping_reg = consys_emi_set_remapping_reg, + .ic_bt_wifi_share_v33_spin_lock_init = bt_wifi_share_v33_spin_lock_init, + .consys_ic_clk_get_from_dts = consys_clk_get_from_dts, + .consys_ic_pmic_get_from_dts = consys_pmic_get_from_dts, + .consys_ic_read_irq_info_from_dts = consys_read_irq_info_from_dts, + .consys_ic_read_reg_from_dts = consys_read_reg_from_dts, + .consys_ic_read_cpupcr = consys_read_cpupcr, + .ic_force_trigger_assert_debug_pin = force_trigger_assert_debug_pin, + .consys_ic_co_clock_type = consys_co_clock_type, + .consys_ic_soc_get_emi_phy_add = consys_soc_get_emi_phy_add, + .consys_ic_set_if_pinmux = consys_set_if_pinmux, + .consys_ic_emi_coredump_remapping = consys_emi_coredump_remapping, + .consys_ic_reset_emi_coredump = consys_reset_emi_coredump, + .consys_ic_dump_osc_state = consys_dump_osc_state, + .consys_ic_get_options = consys_get_options, +}; + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +UINT32 gJtagCtrl; + +#if CONSYS_ENALBE_SET_JTAG +#define JTAG_ADDR1_BASE 0x10005000 +#define JTAG_ADDR2_BASE 0x11E80000 +#define JTAG_ADDR3_BASE 0x11D20000 +#define AP2CONN_JTAG_2WIRE_OFFSET 0xF00 +#endif + +INT32 mtk_wcn_consys_jtag_set_for_mcu(VOID) +{ +#if CONSYS_ENALBE_SET_JTAG + INT32 ret = 0; + UINT32 tmp = 0; + PVOID addr = 0; + PVOID remap_addr1 = 0; + PVOID remap_addr2 = 0; + PVOID remap_addr3 = 0; + + if (gJtagCtrl) { + + remap_addr1 = ioremap(JTAG_ADDR1_BASE, 0x1000); + if (remap_addr1 == 0) { + WMT_PLAT_PR_ERR("remap jtag_addr1 fail!\n"); + ret = -1; + goto error; + } + + remap_addr2 = ioremap(JTAG_ADDR2_BASE, 0x100); + if (remap_addr2 == 0) { + WMT_PLAT_PR_ERR("remap jtag_addr2 fail!\n"); + ret = -1; + goto error; + } + + remap_addr3 = ioremap(JTAG_ADDR3_BASE, 0x100); + if (remap_addr3 == 0) { + WMT_PLAT_PR_ERR("remap jtag_addr3 fail!\n"); + ret = -1; + goto error; + } + + WMT_PLAT_PR_INFO("WCN jtag set for mcu start...\n"); + switch (gJtagCtrl) { + case 1: + /* 7-wire jtag pinmux setting*/ +#if 1 + /* PAD AUX Function Selection */ + addr = remap_addr1 + 0x320; + tmp = readl(addr); + tmp = tmp & 0x0000000f; + tmp = tmp | 0x33333330; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + /* PAD Driving Selection */ + addr = remap_addr2 + 0xA0; + tmp = readl(addr); + tmp = tmp & 0xfff00fff; + tmp = tmp | 0x00077000; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + /* PAD PULL Selection */ + addr = remap_addr2 + 0x60; + tmp = readl(addr); + tmp = tmp & 0xfffe03ff; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + addr = remap_addr2 + 0x60; + tmp = readl(addr); + tmp = tmp & 0xfff80fff; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + +#else + /* backup */ + /* PAD AUX Function Selection */ + addr = remap_addr1 + 0x310; + tmp = readl(addr); + tmp = tmp & 0xfffff000; + tmp = tmp | 0x00000444; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + addr = remap_addr1 + 0x3C0; + tmp = readl(addr); + tmp = tmp & 0xf00ff00f; + tmp = tmp | 0x04400440; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + /* PAD Driving Selection */ + addr = remap_addr3 + 0xA0; + tmp = readl(addr); + tmp = tmp & 0x0ffffff0; + tmp = tmp | 0x70000007; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + addr = remap_addr3 + 0xB0; + tmp = readl(addr); + tmp = tmp & 0xfff0f0ff; + tmp = tmp | 0x0007070f; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + /* PAD PULL Selection */ + addr = remap_addr3 + 0x60; + tmp = readl(addr); + tmp = tmp & 0xf333fffe; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); +#endif + break; + case 2: + /* 2-wire jtag pinmux setting*/ +#if 0 + CONSYS_SET_BIT(conn_reg.topckgen_base + AP2CONN_JTAG_2WIRE_OFFSET, 1 << 8); + addr = remap_addr1 + 0x340; + tmp = readl(addr); + tmp = tmp & 0xfff88fff; + tmp = tmp | 0x00034000; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); +#endif + break; + default: + WMT_PLAT_PR_INFO("unsupported options!\n"); + } + + } +#endif + +error: + + if (remap_addr1) + iounmap(remap_addr1); + if (remap_addr2) + iounmap(remap_addr2); + if (remap_addr3) + iounmap(remap_addr3); + + return ret; +} + +UINT32 mtk_wcn_consys_jtag_flag_ctrl(UINT32 en) +{ + WMT_PLAT_PR_INFO("%s jtag set for MCU\n", en ? "enable" : "disable"); + gJtagCtrl = en; + return 0; +} + +static INT32 consys_clk_get_from_dts(struct platform_device *pdev) +{ + clk_scp_conn_main = devm_clk_get(&pdev->dev, "conn"); + if (IS_ERR(clk_scp_conn_main)) { + WMT_PLAT_PR_ERR("[CCF]cannot get clk_scp_conn_main clock.\n"); + return PTR_ERR(clk_scp_conn_main); + } + WMT_PLAT_PR_DBG("[CCF]clk_scp_conn_main=%p\n", clk_scp_conn_main); + + return 0; +} + +static INT32 consys_pmic_get_from_dts(struct platform_device *pdev) +{ +#if CONSYS_PMIC_CTRL_ENABLE + reg_VCN18 = regulator_get(&pdev->dev, "vcn18"); + if (!reg_VCN18) + WMT_PLAT_PR_ERR("Regulator_get VCN_1V8 fail\n"); + reg_VCN28 = regulator_get(&pdev->dev, "vcn28"); + if (!reg_VCN28) + WMT_PLAT_PR_ERR("Regulator_get VCN_2V8 fail\n"); + reg_VCN33_BT = regulator_get(&pdev->dev, "vcn33_bt"); + if (!reg_VCN33_BT) + WMT_PLAT_PR_ERR("Regulator_get VCN33_BT fail\n"); + reg_VCN33_WIFI = regulator_get(&pdev->dev, "vcn33_wifi"); + if (!reg_VCN33_WIFI) + WMT_PLAT_PR_ERR("Regulator_get VCN33_WIFI fail\n"); +#endif + return 0; +} + +static INT32 consys_co_clock_type(VOID) +{ + return 0; +} + +static INT32 consys_clock_buffer_ctrl(MTK_WCN_BOOL enable) +{ + if (enable) + KERNEL_clk_buf_ctrl(CLK_BUF_CONN, true); /*open XO_WCN*/ + else + KERNEL_clk_buf_ctrl(CLK_BUF_CONN, false); /*close XO_WCN*/ + + return 0; +} + +static VOID consys_set_if_pinmux(MTK_WCN_BOOL enable) +{ + UINT8 *consys_if_pinmux_reg_base = NULL; + + /* Switch D die pinmux for connecting A die */ + consys_if_pinmux_reg_base = ioremap_nocache(CONSYS_IF_PINMUX_REG_BASE, 0x1000); + if (!consys_if_pinmux_reg_base) { + WMT_PLAT_PR_ERR("consys_if_pinmux_reg_base(%x) ioremap fail\n", CONSYS_IF_PINMUX_REG_BASE); + return; + } + + if (enable) { + CONSYS_REG_WRITE(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_01_OFFSET, + (CONSYS_REG_READ(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_01_OFFSET) & + CONSYS_IF_PINMUX_01_MASK) | CONSYS_IF_PINMUX_01_VALUE); + CONSYS_REG_WRITE(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_02_OFFSET, + (CONSYS_REG_READ(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_02_OFFSET) & + CONSYS_IF_PINMUX_02_MASK) | CONSYS_IF_PINMUX_02_VALUE); + } else { + CONSYS_REG_WRITE(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_01_OFFSET, + CONSYS_REG_READ(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_01_OFFSET) & + CONSYS_IF_PINMUX_01_MASK); + CONSYS_REG_WRITE(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_02_OFFSET, + CONSYS_REG_READ(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_02_OFFSET) & + CONSYS_IF_PINMUX_02_MASK); + } + + if (consys_if_pinmux_reg_base) + iounmap(consys_if_pinmux_reg_base); +} + +static VOID consys_hw_reset_bit_set(MTK_WCN_BOOL enable) +{ + if (enable) { + /*3.assert CONNSYS CPU SW reset 0x10007018 "[12]=1'b1 [31:24]=8'h88 (key)" */ + CONSYS_REG_WRITE((conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET), + CONSYS_REG_READ(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET) | + CONSYS_CPU_SW_RST_BIT | CONSYS_CPU_SW_RST_CTRL_KEY); + } else { + /*16.deassert CONNSYS CPU SW reset 0x10007018 "[12]=1'b0 [31:24] =8'h88 (key)" */ + CONSYS_REG_WRITE(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET, + (CONSYS_REG_READ(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET) & + ~CONSYS_CPU_SW_RST_BIT) | CONSYS_CPU_SW_RST_CTRL_KEY); + } +} + +static VOID consys_hw_spm_clk_gating_enable(VOID) +{ + /*turn on SPM clock gating enable PWRON_CONFG_EN 0x10006000 32'h0b160001 */ +} + +static INT32 consys_hw_power_ctrl(MTK_WCN_BOOL enable) +{ +#if CONSYS_PWR_ON_OFF_API_AVAILABLE + INT32 iRet = -1; +#else + INT32 value = 0; +#endif + + if (enable) { +#if CONSYS_PWR_ON_OFF_API_AVAILABLE + iRet = clk_prepare_enable(clk_scp_conn_main); + if (iRet) + WMT_PLAT_PR_ERR("clk_prepare_enable(clk_scp_conn_main) fail(%d)\n", iRet); + WMT_PLAT_PR_DBG("clk_prepare_enable(clk_scp_conn_main) ok\n"); +#else + /*2.write conn_top1_pwr_on=1, power on conn_top1 0x1000632C [2] 1'b1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_SPM_PWR_ON_BIT); + /*2.write conn_top1_pwr_on_s=1, power on conn_top1 0x1000632C [3] 1'b1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_SPM_PWR_ON_S_BIT); + /*3.read conn_top1_pwr_on_ack =1, power on ack ready 0x10006180 [1] */ + value = CONSYS_PWR_ON_ACK_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_OFFSET); + while (value == 0) + value = CONSYS_PWR_ON_ACK_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_OFFSET); + /*3.read conn_top1_pwr_on_ack_s =1, power on ack ready 0x10006184 [1] */ + value = CONSYS_PWR_ON_ACK_S_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_S_OFFSET); + while (value == 0) + value = CONSYS_PWR_ON_ACK_S_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_S_OFFSET); + /*6.write conn_clk_dis=0, enable connsys clock 0x1000632C [4] 1'b0 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) & + ~CONSYS_CLK_CTRL_BIT); + /*7.wait 1us */ + udelay(1); + /*9.release connsys ISO, conn_top1_iso_en=0 0x1000632C [1] 1'b0 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) & + ~CONSYS_SPM_PWR_ISO_S_BIT); + /*10.release SW reset of connsys, conn_ap_sw_rst_b=1 0x1000632C[0] 1'b1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_SPM_PWR_RST_BIT); + /*disable AXI BUS protect 100012a4 [13][14] */ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_TOPAXI_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_TOPAXI_PROT_EN_OFFSET) & + ~CONSYS_PROT_MASK); + /*read conn_top2_pwr_on_ack =1, power on ack ready 0x10006180 [30] */ + value = CONSYS_TOP2_PWR_ON_ACK_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET); + while (value == 0) + value = CONSYS_TOP2_PWR_ON_ACK_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET); + /*read conn_top2_pwr_on_ack_s =1, power on ack ready 0x10006180 [30] */ + value = CONSYS_TOP2_PWR_ON_ACK_S_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET); + while (value == 0) + value = CONSYS_TOP2_PWR_ON_ACK_S_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET); +#endif /* CONSYS_PWR_ON_OFF_API_AVAILABLE */ + } else { +#if CONSYS_PWR_ON_OFF_API_AVAILABLE + clk_disable_unprepare(clk_scp_conn_main); + WMT_PLAT_PR_DBG("clk_disable_unprepare(clk_scp_conn_main) calling\n"); +#else + /*disable AXI BUS protect 0x100012a0 [13][14] */ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_TOPAXI_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_TOPAXI_PROT_EN_OFFSET) | + CONSYS_PROT_MASK); + /*assert SW reset of connsys, conn_ap_sw_rst_b=0 0x1000632C [0] 1'b0 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) & + ~CONSYS_SPM_PWR_RST_BIT); + /*release connsys ISO, conn_top1_iso_en=1 0x1000632C [1] 1'b1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_SPM_PWR_ISO_S_BIT); + /*write conn_clk_dis=1, disable connsys clock 0x1000632C [4] 1'b1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_CLK_CTRL_BIT); + /*wait 1us */ + udelay(1); + /*write conn_top1_pwr_on=0, power off conn_top1 0x1000632C [3:2] 2'b00 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) & + ~(CONSYS_SPM_PWR_ON_BIT | CONSYS_SPM_PWR_ON_S_BIT)); +#endif /* CONSYS_PWR_ON_OFF_API_AVAILABLE */ + } + +#if CONSYS_PWR_ON_OFF_API_AVAILABLE + return iRet; +#else + return 0; +#endif +} + +static INT32 consys_ahb_clock_ctrl(MTK_WCN_BOOL enable) +{ + return 0; +} + +static INT32 polling_consys_chipid(VOID) +{ + UINT32 retry = 10; + UINT32 consysHwChipId = 0; + + /*12.poll CONNSYS CHIP ID until chipid is returned 0x18070008 */ + while (retry-- > 0) { + consysHwChipId = CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_CHIP_ID_OFFSET); + if (consysHwChipId == 0x0788) { + WMT_PLAT_PR_INFO("retry(%d)consys chipId(0x%08x)\n", retry, consysHwChipId); + break; + } + msleep(20); + } + + if ((retry == 0) || (consysHwChipId == 0)) { + WMT_PLAT_PR_ERR("Maybe has a consys power on issue,(0x%08x)\n", consysHwChipId); + WMT_PLAT_PR_INFO("reg dump:CONSYS_CPU_SW_RST_REG(0x%x)\n", + CONSYS_REG_READ(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET)); + WMT_PLAT_PR_INFO("reg dump:CONSYS_PWR_CONN_ACK_REG(0x%x)\n", + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_OFFSET)); + WMT_PLAT_PR_INFO("reg dump:CONSYS_PWR_CONN_ACK_S_REG(0x%x)\n", + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_S_OFFSET)); + WMT_PLAT_PR_INFO("reg dump:CONSYS_TOP1_PWR_CTRL_REG(0x%x)\n", + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET)); + } + + return 0; +} + +static VOID update_consys_rom_desel(VOID) +{ + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_ROM_DESEL_OFFSET, CONSYS_ROM_DESEL_MASK); + WMT_PLAT_PR_INFO("Update consys rom desel value(0x%x)\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_ROM_DESEL_OFFSET)); +} + +static VOID consys_hang_debug_info(VOID) +{ + SIZE_T addr_1; + SIZE_T addr_2; + SIZE_T addr_3; + + UINT32 rv1, wv1[2], rv2[2], rv3, wv3 = 0; + UINT32 i = 0; + + addr_1 = conn_reg.mcu_base + CONSYS_HANG_DBG_OFFSET_1; + addr_2 = conn_reg.mcu_base + CONSYS_HANG_DBG_OFFSET_2; + addr_3 = conn_reg.mcu_base + CONSYS_HANG_DBG_OFFSET_3; + rv1 = CONSYS_REG_READ(addr_1); + rv3 = CONSYS_REG_READ(addr_3); + WMT_PLAT_PR_INFO("addr1:%zx:0x%x/addr2:%zx/addr3:%zx:0x%x\n", + addr_1, rv1, addr_2, addr_3, rv3); + + wv1[0] = (rv1 & 0xFF0000FF) | (0x0201 << 8); + CONSYS_REG_WRITE(addr_1, wv1[0]); + rv2[0] = CONSYS_REG_READ(addr_2); + + wv1[1] = (rv1 & 0xFF0000FF) | (0x0403 << 8); + CONSYS_REG_WRITE(addr_1, wv1[1]); + rv2[1] = CONSYS_REG_READ(addr_2); + WMT_PLAT_PR_INFO("0x%x->addr1, addr2:0x%x/0x%x->addr1, addr2:0x%x\n", + wv1[0], rv2[0], wv1[1], rv2[1]); + + for (i = 0; i < 9; i++) { + wv3 = (rv3 & 0xFFFFFF0F) | (i << 4); + CONSYS_REG_WRITE(addr_3, wv3); + + wv1[0] = (rv1 & 0xFF0000FF) | (0x5251 << 8); + CONSYS_REG_WRITE(addr_1, wv1[0]); + rv2[0] = CONSYS_REG_READ(addr_2); + + wv1[1] = (rv1 & 0xFF0000FF) | (0x5453 << 8); + CONSYS_REG_WRITE(addr_1, wv1[1]); + rv2[1] = CONSYS_REG_READ(addr_2); + WMT_PLAT_PR_INFO("0x%x->addr3,0x%x->addr1,addr2:0x%x/0x%x->addr1,addr2:0x%x\n", + wv3, wv1[0], rv2[0], wv1[1], rv2[1]); + } + + WMT_PLAT_PR_INFO("apb0_dbg_prob\n"); + for (i = 0; i < 10; i++) { + wv3 = (rv3 & 0xFFFF0FFF) | (i << 12); + CONSYS_REG_WRITE(addr_3, wv3); + + wv1[0] = (rv1 & 0xFF0000FF) | (0x5655 << 8); + CONSYS_REG_WRITE(addr_1, wv1[0]); + rv2[0] = CONSYS_REG_READ(addr_2); + + wv1[1] = (rv1 & 0xFF0000FF) | (0x5857 << 8); + CONSYS_REG_WRITE(addr_1, wv1[1]); + rv2[1] = CONSYS_REG_READ(addr_2); + WMT_PLAT_PR_INFO("0x%x->addr3,0x%x->addr1,addr2:0x%x/0x%x->addr1,addr2:0x%x\n", + wv3, wv1[0], rv2[0], wv1[1], rv2[1]); + } + + WMT_PLAT_PR_INFO("apb1_dbg_prob\n"); + for (i = 0; i < 10; i++) { + wv3 = (rv3 & 0xFF0FFFFF) | (i << 20); + CONSYS_REG_WRITE(addr_3, wv3); + + wv1[0] = (rv1 & 0xFF0000FF) | (0x5A59 << 8); + CONSYS_REG_WRITE(addr_1, wv1[0]); + rv2[0] = CONSYS_REG_READ(addr_2); + + wv1[1] = (rv1 & 0xFF0000FF) | (0x5C5B << 8); + CONSYS_REG_WRITE(addr_1, wv1[1]); + rv2[1] = CONSYS_REG_READ(addr_2); + WMT_PLAT_PR_INFO("0x%x->addr3,0x%x->addr1,addr2:0x%x/0x%x->addr1,addr2:0x%x\n", + wv3, wv1[0], rv2[0], wv1[1], rv2[1]); + } +} + +static VOID consys_acr_reg_setting(VOID) +{ + /* + * if bypass at-speed MBIST (default is at-speed) 0x18070140[1:0] 2'b11 + */ + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_MCU_CFG_ACR_OFFSET, + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_MCU_CFG_ACR_OFFSET) | + CONSYS_MCU_CFG_ACR_MBIST_BIT); +} + +static VOID consys_afe_reg_setting(VOID) +{ +#if CONSYS_AFE_REG_SETTING + UINT8 i = 0; + UINT8 *consys_afe_reg_base = NULL; + + /*15.default no need,update ANA_WBG(AFE) CR if needed, CONSYS_AFE_REG */ + consys_afe_reg_base = ioremap_nocache(CONSYS_AFE_REG_BASE, 0x100); + if (consys_afe_reg_base) { + CONSYS_REG_WRITE(consys_afe_reg_base + CONSYS_AFE_RG_WBG_PLL_03_OFFSET, + CONSYS_AFE_RG_WBG_PLL_03_VALUE); + CONSYS_REG_WRITE(consys_afe_reg_base + CONSYS_AFE_RG_WBG_GPS_02_OFFSET, + CONSYS_AFE_RG_WBG_GPS_02_VALUE); + + WMT_PLAT_PR_DBG("Dump AFE register\n"); + for (i = 0; i < 64; i++) { + WMT_PLAT_PR_DBG("reg:0x%08x|val:0x%08x\n", + CONSYS_AFE_REG_BASE + 4*i, + CONSYS_REG_READ(consys_afe_reg_base + 4*i)); + } + iounmap(consys_afe_reg_base); + } else + WMT_PLAT_PR_ERR("AFE base(0x%x) ioremap fail!\n", CONSYS_AFE_REG_BASE); +#endif +} + +static INT32 consys_hw_vcn18_ctrl(MTK_WCN_BOOL enable) +{ +#if CONSYS_PMIC_CTRL_ENABLE + if (enable) { + /*need PMIC driver provide new API protocol */ + /*1.AP power on VCN_1V8 LDO (with PMIC_WRAP API) VCN_1V8 */ + /*set vcn18 SW mode*/ + KERNEL_upmu_set_reg_value(MT6358_LDO_VCN18_OP_EN, 0x1); + + if (reg_VCN18) { + regulator_set_voltage(reg_VCN18, 1800000, 1800000); + if (regulator_enable(reg_VCN18)) + WMT_PLAT_PR_ERR("enable VCN18 fail\n"); + else + WMT_PLAT_PR_DBG("enable VCN18 ok\n"); + } + + /*set vcn33 SW mode*/ + KERNEL_upmu_set_reg_value(MT6358_LDO_VCN33_OP_EN, 0x1); + + if (reg_VCN33_BT) { + regulator_set_voltage(reg_VCN33_BT, 3500000, 3500000); + if (regulator_enable(reg_VCN33_BT)) + WMT_PLAT_PR_ERR("WMT do BT PMIC on fail!\n"); + } + + } else { + if (reg_VCN33_BT) + regulator_disable(reg_VCN33_BT); + + /*AP power off MT6351L VCN_1V8 LDO */ + if (reg_VCN18) { + if (regulator_disable(reg_VCN18)) + WMT_PLAT_PR_ERR("disable VCN_1V8 fail!\n"); + else + WMT_PLAT_PR_DBG("disable VCN_1V8 ok\n"); + } + } +#endif + return 0; +} + +static VOID consys_vcn28_hw_mode_ctrl(UINT32 enable) +{ +#if CONSYS_PMIC_CTRL_ENABLE + if (enable) { + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN28_HW0_OP_EN, 1); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN28_HW0_OP_CFG, 0); + } else { + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN28_HW0_OP_EN, 0); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN28_HW0_OP_CFG, 0); + } +#endif +} + +static INT32 consys_hw_vcn28_ctrl(UINT32 enable) +{ +#if CONSYS_PMIC_CTRL_ENABLE + if (enable) { + /*in co-clock mode,need to turn on vcn28 when fm on */ + if (reg_VCN28) { + regulator_set_voltage(reg_VCN28, 2800000, 2800000); + if (regulator_enable(reg_VCN28)) + WMT_PLAT_PR_ERR("WMT do VCN28 PMIC on fail!\n"); + } + WMT_PLAT_PR_INFO("turn on vcn28 for fm/gps usage in co-clock mode\n"); + } else { + /*in co-clock mode,need to turn off vcn28 when fm off */ + if (reg_VCN28) + regulator_disable(reg_VCN28); + WMT_PLAT_PR_INFO("turn off vcn28 for fm/gps usage in co-clock mode\n"); + } +#endif + return 0; +} + +static INT32 consys_hw_bt_vcn33_ctrl(UINT32 enable) +{ +#if 0 +#if CONSYS_BT_WIFI_SHARE_V33 + /* spin_lock_irqsave(&gBtWifiV33.lock,gBtWifiV33.flags); */ + if (enable) { + if (gBtWifiV33.counter == 1) { + gBtWifiV33.counter++; + WMT_PLAT_PR_DBG("V33 has been enabled,counter(%d)\n", gBtWifiV33.counter); + } else if (gBtWifiV33.counter == 2) { + WMT_PLAT_PR_DBG("V33 has been enabled,counter(%d)\n", gBtWifiV33.counter); + } else { +#if CONSYS_PMIC_CTRL_ENABLE + /*do BT PMIC on,depenency PMIC API ready */ + /*switch BT PALDO control from SW mode to HW mode:0x416[5]-->0x1 */ + /* VOL_DEFAULT, VOL_3300, VOL_3400, VOL_3500, VOL_3600 */ + hwPowerOn(MT6351_POWER_LDO_VCN33_BT, VOL_3300 * 1000, "wcn_drv"); + mt6351_upmu_set_rg_vcn33_on_ctrl(1); +#endif + WMT_PLAT_PR_INFO("WMT do BT/WIFI v3.3 on\n"); + gBtWifiV33.counter++; + } + + } else { + if (gBtWifiV33.counter == 1) { + /*do BT PMIC off */ + /*switch BT PALDO control from HW mode to SW mode:0x416[5]-->0x0 */ +#if CONSYS_PMIC_CTRL_ENABLE + mt6351_upmu_set_rg_vcn33_on_ctrl(0); + hwPowerDown(MT6351_POWER_LDO_VCN33_BT, "wcn_drv"); +#endif + WMT_PLAT_PR_INFO("WMT do BT/WIFI v3.3 off\n"); + gBtWifiV33.counter--; + } else if (gBtWifiV33.counter == 2) { + gBtWifiV33.counter--; + WMT_PLAT_PR_DBG("V33 no need disabled,counter(%d)\n", gBtWifiV33.counter); + } else { + WMT_PLAT_PR_DBG("V33 has been disabled,counter(%d)\n", gBtWifiV33.counter); + } + + } + /* spin_unlock_irqrestore(&gBtWifiV33.lock,gBtWifiV33.flags); */ +#else + if (enable) { + /*do BT PMIC on,depenency PMIC API ready */ + /*switch BT PALDO control from SW mode to HW mode:0x416[5]-->0x1 */ +#if CONSYS_PMIC_CTRL_ENABLE + /* VOL_DEFAULT, VOL_3300, VOL_3400, VOL_3500, VOL_3600 */ + if (reg_VCN33_BT) { + regulator_set_voltage(reg_VCN33_BT, 3300000, 3300000); + if (regulator_enable(reg_VCN33_BT)) + WMT_PLAT_PR_ERR("WMT do BT PMIC on fail!\n"); + } + + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_HW0_OP_EN, 1); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_HW0_OP_CFG, 0); +#endif + WMT_PLAT_PR_DBG("WMT do BT PMIC on\n"); + } else { + /*do BT PMIC off */ + /*switch BT PALDO control from HW mode to SW mode:0x416[5]-->0x0 */ +#if CONSYS_PMIC_CTRL_ENABLE + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_HW0_OP_EN, 0); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_HW0_OP_CFG, 0); + if (reg_VCN33_BT) + regulator_disable(reg_VCN33_BT); +#endif + WMT_PLAT_PR_DBG("WMT do BT PMIC off\n"); + } +#endif + +#endif + return 0; +} + +static INT32 consys_hw_wifi_vcn33_ctrl(UINT32 enable) +{ +#if 0 +#if CONSYS_BT_WIFI_SHARE_V33 + mtk_wcn_consys_hw_bt_paldo_ctrl(enable); +#else + if (enable) { + /*do WIFI PMIC on,depenency PMIC API ready */ + /*switch WIFI PALDO control from SW mode to HW mode:0x418[14]-->0x1 */ +#if CONSYS_PMIC_CTRL_ENABLE + if (reg_VCN33_WIFI) { + regulator_set_voltage(reg_VCN33_WIFI, 3300000, 3300000); + if (regulator_enable(reg_VCN33_WIFI)) + WMT_PLAT_PR_ERR("WMT do WIFI PMIC on fail!\n"); + } + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_HW0_OP_EN, 1); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_HW0_OP_CFG, 0); +#endif + WMT_PLAT_PR_DBG("WMT do WIFI PMIC on\n"); + } else { + /*do WIFI PMIC off */ + /*switch WIFI PALDO control from HW mode to SW mode:0x418[14]-->0x0 */ +#if CONSYS_PMIC_CTRL_ENABLE + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_HW0_OP_EN, 0); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_HW0_OP_CFG, 0); + if (reg_VCN33_WIFI) + regulator_disable(reg_VCN33_WIFI); +#endif + WMT_PLAT_PR_DBG("WMT do WIFI PMIC off\n"); + } + +#endif + +#endif + return 0; +} + +static INT32 consys_emi_mpu_set_region_protection(VOID) +{ +#ifdef CONFIG_MTK_EMI + struct emi_region_info_t region_info; + + /*set MPU for EMI share Memory */ + WMT_PLAT_PR_INFO("setting MPU for EMI share memory\n"); + + region_info.start = gConEmiPhyBase + SZ_1M / 2 - SZ_64K; + region_info.end = gConEmiPhyBase + gConEmiSize - 1; + region_info.region = 26; + SET_ACCESS_PERMISSION(region_info.apc, LOCK, + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, + NO_PROTECTION, FORBIDDEN, NO_PROTECTION); + emi_mpu_set_protection(®ion_info); +#endif + return 0; +} + +static UINT32 consys_emi_set_remapping_reg(VOID) +{ + UINT32 addrPhy = 0; + + /*consys to ap emi remapping register:10000380, cal remapping address */ + addrPhy = (gConEmiPhyBase >> 21) & 0x1FFF; + + /*enable consys to ap emi remapping bit13 */ + addrPhy = addrPhy | 0x2000; + + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET) | addrPhy); + + WMT_PLAT_PR_INFO("CONSYS_EMI_MAPPING dump in restore cb(0x%08x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET)); + + return 0; +} + +static INT32 bt_wifi_share_v33_spin_lock_init(VOID) +{ +#if CONSYS_BT_WIFI_SHARE_V33 + gBtWifiV33.counter = 0; + spin_lock_init(&gBtWifiV33.lock); +#endif + return 0; +} + +static INT32 consys_read_irq_info_from_dts(struct platform_device *pdev, PINT32 irq_num, PUINT32 irq_flag) +{ + struct device_node *node; + UINT32 irq_info[3] = { 0, 0, 0 }; + + INT32 iret = -1; + + node = pdev->dev.of_node; + if (node) { + *irq_num = irq_of_parse_and_map(node, 0); + /* get the interrupt line behaviour */ + if (of_property_read_u32_array(node, "interrupts", irq_info, ARRAY_SIZE(irq_info))) { + WMT_PLAT_PR_ERR("get irq flags from DTS fail!!\n"); + return iret; + } + *irq_flag = irq_info[2]; + WMT_PLAT_PR_INFO("get irq id(%d) and irq trigger flag(%d) from DT\n", *irq_num, + *irq_flag); + } else { + WMT_PLAT_PR_ERR("[%s] can't find CONSYS compatible node\n", __func__); + return iret; + } + + return 0; +} + +static INT32 consys_read_reg_from_dts(struct platform_device *pdev) +{ + INT32 iRet = -1; + struct device_node *node = NULL; + + node = pdev->dev.of_node; + if (node) { + /* registers base address */ + conn_reg.mcu_base = (SIZE_T) of_iomap(node, 0); + WMT_PLAT_PR_DBG("Get mcu register base(0x%zx)\n", conn_reg.mcu_base); + conn_reg.ap_rgu_base = (SIZE_T) of_iomap(node, 1); + WMT_PLAT_PR_DBG("Get ap_rgu register base(0x%zx)\n", conn_reg.ap_rgu_base); + conn_reg.topckgen_base = (SIZE_T) of_iomap(node, 2); + WMT_PLAT_PR_DBG("Get topckgen register base(0x%zx)\n", conn_reg.topckgen_base); + conn_reg.spm_base = (SIZE_T) of_iomap(node, 3); + WMT_PLAT_PR_DBG("Get spm register base(0x%zx)\n", conn_reg.spm_base); + } else { + WMT_PLAT_PR_ERR("[%s] can't find CONSYS compatible node\n", __func__); + return iRet; + } + + return 0; +} + +static VOID force_trigger_assert_debug_pin(VOID) +{ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AP2CONN_OSC_EN_OFFSET) & ~CONSYS_AP2CONN_WAKEUP_BIT); + WMT_PLAT_PR_INFO("enable:dump CONSYS_AP2CONN_OSC_EN_REG(0x%x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET)); + usleep_range(64, 96); + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AP2CONN_OSC_EN_OFFSET) | CONSYS_AP2CONN_WAKEUP_BIT); + WMT_PLAT_PR_INFO("disable:dump CONSYS_AP2CONN_OSC_EN_REG(0x%x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET)); +} + +static UINT32 consys_read_cpupcr(VOID) +{ + if (conn_reg.mcu_base == 0) + return 0; + + if (mtk_consys_check_reg_readable_by_addr(conn_reg.mcu_base + CONSYS_CPUPCR_OFFSET) == 0) + return 0; + + return CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_CPUPCR_OFFSET); +} + +static UINT32 consys_soc_chipid_get(VOID) +{ + return PLATFORM_SOC_CHIP; +} + +static P_CONSYS_EMI_ADDR_INFO consys_soc_get_emi_phy_add(VOID) +{ + return &mtk_wcn_emi_addr_info; +} + +P_WMT_CONSYS_IC_OPS mtk_wcn_get_consys_ic_ops(VOID) +{ + return &consys_ic_ops; +} + +static INT32 consys_emi_coredump_remapping(UINT8 __iomem **addr, UINT32 enable) +{ + if (enable) { + *addr = ioremap_nocache(gConEmiPhyBase + CONSYS_EMI_COREDUMP_OFFSET, CONSYS_EMI_MEM_SIZE); + if (*addr) { + WMT_PLAT_PR_INFO("COREDUMP EMI mapping OK virtual(0x%p) physical(0x%x)\n", + *addr, (UINT32) gConEmiPhyBase + CONSYS_EMI_COREDUMP_OFFSET); + memset_io(*addr, 0, CONSYS_EMI_MEM_SIZE); + } else { + WMT_PLAT_PR_ERR("EMI mapping fail\n"); + return -1; + } + } else { + if (*addr) { + iounmap(*addr); + *addr = NULL; + } + } + return 0; +} + +static INT32 consys_reset_emi_coredump(UINT8 __iomem *addr) +{ + if (!addr) { + WMT_PLAT_PR_ERR("get virtual address fail\n"); + return -1; + } + WMT_PLAT_PR_INFO("Reset EMI(0xF0080000 ~ 0xF0080400) and (0xF0088400 ~ 0xF0090400)\n"); + /* reset 0xF0080000 ~ 0xF0080400 (1K) */ + memset_io(addr, 0, 0x400); + /* reset 0xF0088400 ~ 0xF0090400 (32K) */ + memset_io(addr + CONSYS_EMI_PAGED_DUMP_OFFSET, 0, 0x8000); + return 0; +} + +/* + * Before calling this function, should check consys state + * ex: consys power on already and reg_readable + */ +static INT32 consys_dump_osc_state(P_CONSYS_STATE state) +{ + INT32 ret = MTK_WCN_BOOL_TRUE; + /* marked for 6771 first, util it can work find */ +#if 0 + UINT8 __iomem *addr; + UINT8 *mcu_top_misc_on_base = NULL; + + mcu_top_misc_on_base = ioremap_nocache(MCU_TOP_MISC_ON_BASE_ADDR, 0x200); + + /* 6771 doesn't have reg_readable function, should check osc state from PMIC */ + if (mcu_top_misc_on_base != 0) { + state->lp[0] = (UINT32)CONN_CFG_ON_CONN_ON_MON_FLAG_RECORD_MAPPING_AP_ADDR; + state->lp_buf[1] = CONSYS_REG_READ(mcu_top_misc_on_base + CONN_CFG_ON_CONN_ON_MON_FLAG_RECORD_ADDR); + WMT_PLAT_PR_INFO("0x%08x: 0x%x\n", state->lp_buf[0], state->lp[1]); + + } else { + ret = MTK_WCN_BOOL_FALSE; + } + iounmap(mcu_top_misc_on_base); + + addr = ioremap_nocache(gConEmiPhyBase + 0x66500, sizeof(struct consys_sw_state)); + if (addr) + memcpy_fromio(&state->sw_state, addr, sizeof(struct consys_sw_state)); + else + WMT_PLAT_PR_WARN("ioremap fail\n"); + iounmap(addr); + +#endif + + return ret; +} + +static UINT64 consys_get_options(VOID) +{ + UINT64 options = OPT_POWER_ON_DLM_TABLE | + OPT_SET_MCUCLK_TABLE_3_4 | + OPT_SET_WIFI_EXT_COMPONENT | + OPT_WIFI_LTE_COEX | + OPT_BT_TSSI_FROM_WIFI_CONFIG_NEW_OPID | + OPT_INIT_COEX_AFTER_RF_CALIBRATION | + OPT_COEX_CONFIG_ADJUST | + OPT_SET_OSC_TYPE | + OPT_SET_COREDUMP_LEVEL | + OPT_WIFI_LTE_COEX_TABLE_2 | + OPT_NORMAL_PATCH_DWN_2; + return options; +} diff --git a/drivers/misc/mediatek/connectivity/common/common_main/platform/mt6779.c b/drivers/misc/mediatek/connectivity/common/common_main/platform/mt6779.c new file mode 100644 index 0000000000000000000000000000000000000000..452965effe368d5481941f2fb24b11be55446c4e --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/platform/mt6779.c @@ -0,0 +1,2092 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +#ifdef DFT_TAG +#undef DFT_TAG +#endif +#define DFT_TAG "[WMT-CONSYS-HW]" + +#define PRIMARY_ADIE 0x6635 +#define SECONDARY_ADIE 0x6631 + +#define REGION_CONN 27 + +#define DOMAIN_AP 0 +#define DOMAIN_CONN 2 + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include +#include +#include +#include +#include +#include "connsys_debug_utility.h" +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH +#include "fw_log_wmt.h" +#endif +#include "osal_typedef.h" +#include "mt6779.h" +#include "mtk_wcn_consys_hw.h" +#include "wmt_ic.h" +#include "wmt_lib.h" +#include "wmt_step.h" +#include "stp_dbg.h" + +#if (COMMON_KERNEL_EMI_MPU_SUPPORT) +#ifdef CONFIG_MTK_EMI_LEGACY +#define CONSYS_ENABLE_EMI_MPU +#include +#endif +#else +#ifdef CONFIG_MTK_EMI +#define CONSYS_ENABLE_EMI_MPU +#include +#endif +#endif +#include + +#if CONSYS_PMIC_CTRL_ENABLE +#include +#if (COMMON_KERNEL_PMIC_SUPPORT) +#include +#include +#include +#else +#include +#include +#endif +#endif + +#ifdef CONFIG_MTK_HIBERNATION +#include +#endif + +#include + +#include + +/* Direct path */ +#include +#include +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +static INT32 consys_clock_buffer_ctrl(MTK_WCN_BOOL enable); +static VOID consys_hw_reset_bit_set(MTK_WCN_BOOL enable); +static VOID consys_hw_spm_clk_gating_enable(VOID); +static INT32 consys_hw_power_ctrl(MTK_WCN_BOOL enable); +static INT32 consys_ahb_clock_ctrl(MTK_WCN_BOOL enable); +static INT32 polling_consys_chipid(VOID); +static VOID consys_acr_reg_setting(VOID); +static VOID consys_afe_reg_setting(VOID); +static INT32 consys_hw_vcn18_ctrl(MTK_WCN_BOOL enable); +static VOID consys_vcn28_hw_mode_ctrl(UINT32 enable); +static INT32 consys_hw_vcn28_ctrl(UINT32 enable); +static INT32 consys_hw_wifi_vcn33_ctrl(UINT32 enable); +static INT32 consys_hw_bt_vcn33_ctrl(UINT32 enable); +static UINT32 consys_soc_chipid_get(VOID); +static INT32 consys_adie_chipid_detect(VOID); +static INT32 consys_emi_mpu_set_region_protection(VOID); +static UINT32 consys_emi_set_remapping_reg(VOID); +static INT32 bt_wifi_share_v33_spin_lock_init(VOID); +static INT32 consys_clk_get_from_dts(struct platform_device *pdev); +static INT32 consys_pmic_get_from_dts(struct platform_device *pdev); +static INT32 consys_read_irq_info_from_dts(struct platform_device *pdev, + PINT32 irq_num, PUINT32 irq_flag); +static INT32 consys_read_reg_from_dts(struct platform_device *pdev); +static UINT32 consys_read_cpupcr(VOID); +static VOID force_trigger_assert_debug_pin(VOID); +static INT32 consys_co_clock_type(VOID); +static P_CONSYS_EMI_ADDR_INFO consys_soc_get_emi_phy_add(VOID); +static VOID consys_set_if_pinmux(MTK_WCN_BOOL enable); +static INT32 consys_dl_rom_patch(UINT32 ip_ver, UINT32 fw_ver); +static VOID consys_set_dl_rom_patch_flag(INT32 flag); +static INT32 consys_dedicated_log_path_init(struct platform_device *pdev); +static VOID consys_dedicated_log_path_deinit(VOID); +static INT32 consys_emi_coredump_remapping(UINT8 __iomem **addr, UINT32 enable); +static INT32 consys_reset_emi_coredump(UINT8 __iomem *addr); +static INT32 consys_check_reg_readable(VOID); +static VOID consys_ic_clock_fail_dump(VOID); +static INT32 consys_is_connsys_reg(UINT32 addr); +static INT32 consys_is_host_csr(SIZE_T addr); +static INT32 consys_dump_osc_state(P_CONSYS_STATE state); +static VOID consys_set_pdma_axi_rready_force_high(UINT32 enable); +static VOID consys_set_mcif_emi_mpu_protection(MTK_WCN_BOOL enable); +#if (COMMON_KERNEL_CLK_SUPPORT) +static MTK_WCN_BOOL consys_need_store_pdev(VOID); +static UINT32 consys_store_pdev(struct platform_device *pdev); +#endif +/* + * If 1: this platform supports calibration backup/restore. + * otherwise: 0 + */ +static INT32 consys_calibration_backup_restore_support(VOID); +static INT32 consys_is_ant_swap_enable_by_hwid(INT32 pin_num); +static UINT64 consys_get_options(VOID); + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ +/* CCF part */ +#if (!COMMON_KERNEL_CLK_SUPPORT) +struct clk *clk_scp_conn_main; /*ctrl conn_power_on/off */ +#endif +static struct clk *clk_infracfg_ao_ccif4_ap_cg; /* For direct path */ + +#if (COMMON_KERNEL_CLK_SUPPORT) +static struct platform_device *connsys_pdev; +#endif + +/* PMIC part */ +#if CONSYS_PMIC_CTRL_ENABLE +struct regulator *reg_VCN13; +struct regulator *reg_VCN18; +struct regulator *reg_VCN33_1_BT; +struct regulator *reg_VCN33_1_WIFI; +struct regulator *reg_VCN33_2_WIFI; +#endif + +EMI_CTRL_STATE_OFFSET mtk_wcn_emi_state_off = { + .emi_apmem_ctrl_state = EXP_APMEM_CTRL_STATE, + .emi_apmem_ctrl_host_sync_state = EXP_APMEM_CTRL_HOST_SYNC_STATE, + .emi_apmem_ctrl_host_sync_num = EXP_APMEM_CTRL_HOST_SYNC_NUM, + .emi_apmem_ctrl_chip_sync_state = EXP_APMEM_CTRL_CHIP_SYNC_STATE, + .emi_apmem_ctrl_chip_sync_num = EXP_APMEM_CTRL_CHIP_SYNC_NUM, + .emi_apmem_ctrl_chip_sync_addr = EXP_APMEM_CTRL_CHIP_SYNC_ADDR, + .emi_apmem_ctrl_chip_sync_len = EXP_APMEM_CTRL_CHIP_SYNC_LEN, + .emi_apmem_ctrl_chip_print_buff_start = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_START, + .emi_apmem_ctrl_chip_print_buff_len = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_LEN, + .emi_apmem_ctrl_chip_print_buff_idx = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_IDX, + .emi_apmem_ctrl_chip_int_status = EXP_APMEM_CTRL_CHIP_INT_STATUS, + .emi_apmem_ctrl_chip_paded_dump_end = EXP_APMEM_CTRL_CHIP_PAGED_DUMP_END, + .emi_apmem_ctrl_host_outband_assert_w1 = EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1, + .emi_apmem_ctrl_chip_page_dump_num = EXP_APMEM_CTRL_CHIP_PAGE_DUMP_NUM, + .emi_apmem_ctrl_assert_flag = EXP_APMEM_CTRL_ASSERT_FLAG, + .emi_apmem_ctrl_chip_check_sleep = EXP_APMEM_CTRL_CHIP_CHECK_SLEEP, +}; + +CONSYS_EMI_ADDR_INFO mtk_wcn_emi_addr_info = { + .emi_phy_addr = CONSYS_EMI_FW_PHY_BASE, + .paged_trace_off = CONSYS_EMI_PAGED_TRACE_OFFSET, + .paged_dump_off = CONSYS_EMI_PAGED_DUMP_OFFSET, + .full_dump_off = CONSYS_EMI_FULL_DUMP_OFFSET, + .emi_remap_offset = CONSYS_EMI_MAPPING_OFFSET, + .p_ecso = &mtk_wcn_emi_state_off, + .pda_dl_patch_flag = 1, + .emi_met_size = (32*KBYTE), + .emi_met_data_offset = CONSYS_EMI_MET_DATA_OFFSET, + .emi_core_dump_offset = CONSYS_EMI_COREDUMP_OFFSET, +}; + +WMT_CONSYS_IC_OPS consys_ic_ops = { + .consys_ic_clock_buffer_ctrl = consys_clock_buffer_ctrl, + .consys_ic_hw_reset_bit_set = consys_hw_reset_bit_set, + .consys_ic_hw_spm_clk_gating_enable = consys_hw_spm_clk_gating_enable, + .consys_ic_hw_power_ctrl = consys_hw_power_ctrl, + .consys_ic_ahb_clock_ctrl = consys_ahb_clock_ctrl, + .polling_consys_ic_chipid = polling_consys_chipid, + .consys_ic_acr_reg_setting = consys_acr_reg_setting, + .consys_ic_afe_reg_setting = consys_afe_reg_setting, + .consys_ic_hw_vcn18_ctrl = consys_hw_vcn18_ctrl, + .consys_ic_vcn28_hw_mode_ctrl = consys_vcn28_hw_mode_ctrl, + .consys_ic_hw_vcn28_ctrl = consys_hw_vcn28_ctrl, + .consys_ic_hw_wifi_vcn33_ctrl = consys_hw_wifi_vcn33_ctrl, + .consys_ic_hw_bt_vcn33_ctrl = consys_hw_bt_vcn33_ctrl, + .consys_ic_soc_chipid_get = consys_soc_chipid_get, + .consys_ic_adie_chipid_detect = consys_adie_chipid_detect, + .consys_ic_emi_mpu_set_region_protection = consys_emi_mpu_set_region_protection, + .consys_ic_emi_set_remapping_reg = consys_emi_set_remapping_reg, + .ic_bt_wifi_share_v33_spin_lock_init = bt_wifi_share_v33_spin_lock_init, + .consys_ic_clk_get_from_dts = consys_clk_get_from_dts, + .consys_ic_pmic_get_from_dts = consys_pmic_get_from_dts, + .consys_ic_read_irq_info_from_dts = consys_read_irq_info_from_dts, + .consys_ic_read_reg_from_dts = consys_read_reg_from_dts, + .consys_ic_read_cpupcr = consys_read_cpupcr, + .ic_force_trigger_assert_debug_pin = force_trigger_assert_debug_pin, + .consys_ic_co_clock_type = consys_co_clock_type, + .consys_ic_soc_get_emi_phy_add = consys_soc_get_emi_phy_add, + .consys_ic_set_if_pinmux = consys_set_if_pinmux, + .consys_ic_set_dl_rom_patch_flag = consys_set_dl_rom_patch_flag, + .consys_ic_dedicated_log_path_init = consys_dedicated_log_path_init, + .consys_ic_dedicated_log_path_deinit = consys_dedicated_log_path_deinit, + .consys_ic_emi_coredump_remapping = consys_emi_coredump_remapping, + .consys_ic_reset_emi_coredump = consys_reset_emi_coredump, + .consys_ic_check_reg_readable = consys_check_reg_readable, + .consys_ic_clock_fail_dump = consys_ic_clock_fail_dump, + .consys_ic_is_connsys_reg = consys_is_connsys_reg, + .consys_ic_is_host_csr = consys_is_host_csr, + .consys_ic_dump_osc_state = consys_dump_osc_state, + .consys_ic_set_pdma_axi_rready_force_high = consys_set_pdma_axi_rready_force_high, + .consys_ic_set_mcif_emi_mpu_protection = consys_set_mcif_emi_mpu_protection, + .consys_ic_calibration_backup_restore = consys_calibration_backup_restore_support, + .consys_ic_is_ant_swap_enable_by_hwid = consys_is_ant_swap_enable_by_hwid, +#if (COMMON_KERNEL_CLK_SUPPORT) + .consys_ic_need_store_pdev = consys_need_store_pdev, + .consys_ic_store_pdev = consys_store_pdev, +#endif + .consys_ic_get_options = consys_get_options, +}; + +static const struct connlog_emi_config connsys_fw_log_parameter = { + .emi_offset = 0x36500, + .emi_size_total = (192*1024),/* 192KB */ + .emi_size_mcu = (16*1024), + .emi_size_wifi = (64*1024), + .emi_size_bt = (64*1024), + .emi_size_gps = (32*1024), +}; + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +INT32 rom_patch_dl_flag = 1; +UINT32 gJtagCtrl; +UINT32 g_connsys_lp_dump_info[2]; + +#if CONSYS_ENALBE_SET_JTAG +#define JTAG_ADDR1_BASE 0x10005000 +#define JTAG_ADDR2_BASE 0x11E80000 +#define JTAG_ADDR3_BASE 0x11D20000 +#define AP2CONN_JTAG_2WIRE_OFFSET 0xF00 +#endif + +INT32 mtk_wcn_consys_jtag_set_for_mcu(VOID) +{ +#if 0 +#if CONSYS_ENALBE_SET_JTAG + INT32 ret = 0; + UINT32 tmp = 0; + PVOID addr = 0; + PVOID remap_addr1 = 0; + PVOID remap_addr2 = 0; + PVOID remap_addr3 = 0; + + if (gJtagCtrl) { + + remap_addr1 = ioremap(JTAG_ADDR1_BASE, 0x1000); + if (remap_addr1 == 0) { + WMT_PLAT_PR_ERR("remap jtag_addr1 fail!\n"); + ret = -1; + goto error; + } + + remap_addr2 = ioremap(JTAG_ADDR2_BASE, 0x100); + if (remap_addr2 == 0) { + WMT_PLAT_PR_ERR("remap jtag_addr2 fail!\n"); + ret = -1; + goto error; + } + + remap_addr3 = ioremap(JTAG_ADDR3_BASE, 0x100); + if (remap_addr3 == 0) { + WMT_PLAT_PR_ERR("remap jtag_addr3 fail!\n"); + ret = -1; + goto error; + } + + WMT_PLAT_PR_INFO("WCN jtag set for mcu start...\n"); + switch (gJtagCtrl) { + case 1: + /* 7-wire jtag pinmux setting*/ +#if 1 + /* PAD AUX Function Selection */ + addr = remap_addr1 + 0x320; + tmp = readl(addr); + tmp = tmp & 0x0000000f; + tmp = tmp | 0x33333330; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + /* PAD Driving Selection */ + addr = remap_addr2 + 0xA0; + tmp = readl(addr); + tmp = tmp & 0xfff00fff; + tmp = tmp | 0x00077000; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + /* PAD PULL Selection */ + addr = remap_addr2 + 0x60; + tmp = readl(addr); + tmp = tmp & 0xfffe03ff; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + addr = remap_addr2 + 0x60; + tmp = readl(addr); + tmp = tmp & 0xfff80fff; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + +#else + /* backup */ + /* PAD AUX Function Selection */ + addr = remap_addr1 + 0x310; + tmp = readl(addr); + tmp = tmp & 0xfffff000; + tmp = tmp | 0x00000444; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + addr = remap_addr1 + 0x3C0; + tmp = readl(addr); + tmp = tmp & 0xf00ff00f; + tmp = tmp | 0x04400440; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + /* PAD Driving Selection */ + addr = remap_addr3 + 0xA0; + tmp = readl(addr); + tmp = tmp & 0x0ffffff0; + tmp = tmp | 0x70000007; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + addr = remap_addr3 + 0xB0; + tmp = readl(addr); + tmp = tmp & 0xfff0f0ff; + tmp = tmp | 0x0007070f; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + /* PAD PULL Selection */ + addr = remap_addr3 + 0x60; + tmp = readl(addr); + tmp = tmp & 0xf333fffe; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); +#endif + break; + case 2: + /* 2-wire jtag pinmux setting*/ +#if 0 + CONSYS_SET_BIT(conn_reg.topckgen_base + AP2CONN_JTAG_2WIRE_OFFSET, 1 << 8); + addr = remap_addr1 + 0x340; + tmp = readl(addr); + tmp = tmp & 0xfff88fff; + tmp = tmp | 0x00034000; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); +#endif + break; + default: + WMT_PLAT_PR_INFO("unsupported options!\n"); + } + + } +#endif + +error: + + if (remap_addr1) + iounmap(remap_addr1); + if (remap_addr2) + iounmap(remap_addr2); + if (remap_addr3) + iounmap(remap_addr3); + + return ret; +#else + WMT_PLAT_PR_INFO("No support switch to JTAG!\n"); + + return 0; +#endif +} + +UINT32 mtk_wcn_consys_jtag_flag_ctrl(UINT32 en) +{ + WMT_PLAT_PR_INFO("%s jtag set for MCU\n", en ? "enable" : "disable"); + gJtagCtrl = en; + + return 0; +} + +static INT32 consys_clk_get_from_dts(struct platform_device *pdev) +{ +#if (!COMMON_KERNEL_CLK_SUPPORT) + clk_scp_conn_main = devm_clk_get(&pdev->dev, "conn"); + if (IS_ERR(clk_scp_conn_main)) { + WMT_PLAT_PR_ERR("[CCF]cannot get clk_scp_conn_main clock.\n"); + return PTR_ERR(clk_scp_conn_main); + } + WMT_PLAT_PR_DBG("[CCF]clk_scp_conn_main=%p\n", clk_scp_conn_main); +#endif + clk_infracfg_ao_ccif4_ap_cg = devm_clk_get(&pdev->dev, "ccif"); + if (IS_ERR(clk_infracfg_ao_ccif4_ap_cg)) { + WMT_PLAT_PR_ERR("[CCF]cannot get clk_infracfg_ao_ccif4_ap_cg clock.\n"); + return PTR_ERR(clk_infracfg_ao_ccif4_ap_cg); + } + WMT_PLAT_PR_DBG("[CCF]clk_infracfg_ao_ccif4_ap_cg=%p\n", clk_infracfg_ao_ccif4_ap_cg); + + return 0; +} + +static INT32 consys_pmic_get_from_dts(struct platform_device *pdev) +{ +#if CONSYS_PMIC_CTRL_ENABLE + reg_VCN18 = regulator_get(&pdev->dev, "vcn18"); + if (!reg_VCN18) + WMT_PLAT_PR_ERR("Regulator_get VCN_1V8 fail\n"); + reg_VCN13 = regulator_get(&pdev->dev, "vcn13"); + if (!reg_VCN13) + WMT_PLAT_PR_ERR("Regulator_get VCN_1V3 fail\n"); + reg_VCN33_1_BT = regulator_get(&pdev->dev, "vcn33_1_bt"); + if (!reg_VCN33_1_BT) + WMT_PLAT_PR_ERR("Regulator_get VCN33_1_BT fail\n"); + reg_VCN33_1_WIFI = regulator_get(&pdev->dev, "vcn33_1_wifi"); + if (!reg_VCN33_1_WIFI) + WMT_PLAT_PR_ERR("Regulator_get VCN33_1_WIFI fail\n"); + reg_VCN33_2_WIFI = regulator_get(&pdev->dev, "vcn33_2_wifi"); + if (!reg_VCN33_2_WIFI) + WMT_PLAT_PR_ERR("Regulator_get VCN33_2_WIFI fail\n"); +#endif + + return 0; +} + +static INT32 consys_co_clock_type(VOID) +{ + return 0; +} + +static INT32 consys_clock_buffer_ctrl(MTK_WCN_BOOL enable) +{ + if (enable) + clk_buf_ctrl(CLK_BUF_CONN, true); /*open XO_WCN*/ + else + clk_buf_ctrl(CLK_BUF_CONN, false); /*close XO_WCN*/ + + return 0; +} + +static VOID consys_set_if_pinmux(MTK_WCN_BOOL enable) +{ + UINT8 *consys_if_pinmux_reg_base = NULL; + UINT8 *consys_if_pinmux_driving_base = NULL; + + /* Switch D die pinmux for connecting A die */ + consys_if_pinmux_reg_base = ioremap_nocache(CONSYS_IF_PINMUX_REG_BASE, 0x1000); + if (!consys_if_pinmux_reg_base) { + WMT_PLAT_PR_ERR("consys_if_pinmux_reg_base(%x) ioremap fail\n", + CONSYS_IF_PINMUX_REG_BASE); + return; + } + + consys_if_pinmux_driving_base = ioremap_nocache(CONSYS_IF_PINMUX_DRIVING_BASE, 0x100); + if (!consys_if_pinmux_driving_base) { + WMT_PLAT_PR_ERR("consys_if_pinmux_driving_base(%x) ioremap fail\n", + CONSYS_IF_PINMUX_DRIVING_BASE); + if (consys_if_pinmux_reg_base) + iounmap(consys_if_pinmux_reg_base); + return; + } + + if (enable) { + CONSYS_REG_WRITE(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_01_OFFSET, + (CONSYS_REG_READ(consys_if_pinmux_reg_base + + CONSYS_IF_PINMUX_01_OFFSET) & + CONSYS_IF_PINMUX_01_MASK) | CONSYS_IF_PINMUX_01_VALUE); + CONSYS_REG_WRITE(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_02_OFFSET, + (CONSYS_REG_READ(consys_if_pinmux_reg_base + + CONSYS_IF_PINMUX_02_OFFSET) & + CONSYS_IF_PINMUX_02_MASK) | CONSYS_IF_PINMUX_02_VALUE); + /* set pinmux driving to 2mA */ + CONSYS_REG_WRITE(consys_if_pinmux_driving_base + CONSYS_IF_PINMUX_DRIVING_OFFSET, + (CONSYS_REG_READ(consys_if_pinmux_driving_base + + CONSYS_IF_PINMUX_DRIVING_OFFSET) & + CONSYS_IF_PINMUX_DRIVING_MASK) | CONSYS_IF_PINMUX_DRIVING_VALUE); + } else { + CONSYS_REG_WRITE(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_01_OFFSET, + CONSYS_REG_READ(consys_if_pinmux_reg_base + + CONSYS_IF_PINMUX_01_OFFSET) & CONSYS_IF_PINMUX_01_MASK); + CONSYS_REG_WRITE(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_02_OFFSET, + CONSYS_REG_READ(consys_if_pinmux_reg_base + + CONSYS_IF_PINMUX_02_OFFSET) & CONSYS_IF_PINMUX_02_MASK); + } + + if (consys_if_pinmux_reg_base) + iounmap(consys_if_pinmux_reg_base); + if (consys_if_pinmux_driving_base) + iounmap(consys_if_pinmux_driving_base); +} + +static VOID consys_hw_reset_bit_set(MTK_WCN_BOOL enable) +{ + UINT32 consys_ver_id = 0; + UINT32 cnt = 0; + UINT8 *consys_reg_base = NULL; + + if (enable) { + /*3.assert CONNSYS CPU SW reset 0x10007018 "[12]=1'b1 [31:24]=8'h88 (key)" */ + CONSYS_REG_WRITE((conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET), + CONSYS_REG_READ(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET) | + CONSYS_CPU_SW_RST_BIT | CONSYS_CPU_SW_RST_CTRL_KEY); + } else { + /*16.deassert CONNSYS CPU SW reset 0x10007018 "[12]=1'b0 [31:24] =8'h88 (key)" */ + CONSYS_REG_WRITE(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET, + (CONSYS_REG_READ(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET) & + ~CONSYS_CPU_SW_RST_BIT) | CONSYS_CPU_SW_RST_CTRL_KEY); + /* check CONNSYS power-on completion + * (polling "0x8000_0600[31:0]" == 0x1D1E and each polling interval is "1ms") + * (apply this for guarantee that CONNSYS CPU goes to "cos_idle_loop") + */ + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_base + 0x600); + while (consys_ver_id != 0x1D1E) { + if (cnt > 10) + break; + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_base + 0x600); + WMT_PLAT_PR_INFO("0x18002600(0x%x)\n", consys_ver_id); + WMT_PLAT_PR_INFO("0x1800216c(0x%x)\n", + CONSYS_REG_READ(conn_reg.mcu_base + 0x16c)); + WMT_PLAT_PR_INFO("0x18007104(0x%x)\n", + CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + + CONSYS_CPUPCR_OFFSET)); + msleep(20); + cnt++; + } + + if (mtk_wcn_consys_get_adie_chipid() != SECONDARY_ADIE) { + /* if(MT6635) CONN_WF_CTRL2 swtich to CONN mode */ + consys_reg_base = ioremap_nocache(CONSYS_IF_PINMUX_REG_BASE, 0x1000); + if (!consys_reg_base) { + WMT_PLAT_PR_INFO("consys_if_pinmux_reg_base(%x) ioremap fail\n", + CONSYS_IF_PINMUX_REG_BASE); + return; + } + CONSYS_REG_WRITE(consys_reg_base + CONSYS_WF_CTRL2_03_OFFSET, + (CONSYS_REG_READ(consys_reg_base + + CONSYS_WF_CTRL2_03_OFFSET) & + CONSYS_WF_CTRL2_03_MASK) | CONSYS_WF_CTRL2_CONN_MODE); + iounmap(consys_reg_base); + } + } +} + +static VOID consys_hw_spm_clk_gating_enable(VOID) +{ +} + +static INT32 consys_hw_power_ctrl(MTK_WCN_BOOL enable) +{ +#if CONSYS_PWR_ON_OFF_API_AVAILABLE + INT32 iRet = 0; + UINT8 *check_coredump_reg = NULL; + UINT8 *check_sleep_reg = NULL; + UINT32 check_sleep = 0; + UINT32 retry = 100; + P_CONSYS_EMI_ADDR_INFO p_ecsi; +#else + INT32 value = 0; + INT32 i = 0; +#endif + + if (enable) { +#if CONSYS_PWR_ON_OFF_API_AVAILABLE + iRet = clk_prepare_enable(clk_infracfg_ao_ccif4_ap_cg); + if (iRet) { + WMT_PLAT_PR_ERR("clk_prepare_enable(clk_infracfg_ao_ccif4_ap_cg) fail(%d)\n", iRet); + return iRet; + } + WMT_PLAT_PR_DBG("clk_prepare_enable(clk_infracfg_ao_ccif4_ap_cg) ok\n"); +#if (COMMON_KERNEL_CLK_SUPPORT) + iRet = pm_runtime_get_sync(&connsys_pdev->dev); + if (iRet) + WMT_PLAT_PR_INFO("pm_runtime_get_sync() fail(%d)\n", iRet); + else + WMT_PLAT_PR_INFO("pm_runtime_get_sync() CONSYS ok\n"); + + iRet = device_init_wakeup(&connsys_pdev->dev, true); + if (iRet) + WMT_PLAT_PR_INFO("device_init_wakeup(true) fail.\n"); + else + WMT_PLAT_PR_INFO("device_init_wakeup(true) CONSYS ok\n"); +#else + iRet = clk_prepare_enable(clk_scp_conn_main); + if (iRet) { + WMT_PLAT_PR_ERR("clk_prepare_enable(clk_scp_conn_main) fail(%d)\n", iRet); + return iRet; + } + WMT_PLAT_PR_DBG("clk_prepare_enable(clk_scp_conn_main) ok\n"); +#endif + if (conn_reg.infra_ao_pericfg_base != 0) { + WMT_PLAT_PR_DBG("CON_STA_REG = %x\n", + CONSYS_REG_READ( + conn_reg.infra_ao_pericfg_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG)); + + /* Set CON_PWR_ON bit (CON_STA_REG[0]) */ + CONSYS_REG_WRITE_RANGE((conn_reg.infra_ao_pericfg_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG), + 1, 1, 0); + + WMT_PLAT_PR_DBG("CON_STA_REG = %x\n", + CONSYS_REG_READ( + conn_reg.infra_ao_pericfg_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG)); + } +#else + /* turn on SPM clock gating enable PWRON_CONFG_EN 0x10006000 32'h0b160001 */ + CONSYS_REG_WRITE((conn_reg.spm_base + CONSYS_PWRON_CONFG_EN_OFFSET), + (CONSYS_REG_READ(conn_reg.spm_base + + CONSYS_PWRON_CONFG_EN_OFFSET) & + 0x0000FFFF) | CONSYS_PWRON_CONFG_EN_VALUE); + + /*write assert "conn_top_on" primary part power on, + *set "connsys_on_domain_pwr_on"=1 + */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_SPM_PWR_ON_BIT); + /*read check "conn_top_on" primary part power status, + *check "connsys_on_domain_pwr_ack"=1 + */ + value = CONSYS_PWR_ON_ACK_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_OFFSET); + while (value == 0) + value = CONSYS_PWR_ON_ACK_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_OFFSET); + /*write assert "conn_top_on" secondary part power on, + *set "connsys_on_domain_pwr_on_s"=1 + */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_SPM_PWR_ON_S_BIT); + /*read check "conn_top_on" secondary part power status, + *check "connsys_on_domain_pwr_ack_s"=1 + */ + value = CONSYS_PWR_ON_ACK_S_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_S_OFFSET); + while (value == 0) + value = CONSYS_PWR_ON_ACK_S_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_S_OFFSET); + /*write turn on AP-to-CONNSYS bus clock, set "conn_clk_dis"=0 (apply this for bus + *clock toggling) + */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) & + ~CONSYS_CLK_CTRL_BIT); + /*wait 1us*/ + udelay(1); + /*de-assert "conn_top_on" isolation, set "connsys_iso_en"=0 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) & + ~CONSYS_SPM_PWR_ISO_S_BIT); + + /*de-assert CONNSYS S/W reset (TOP RGU CR), set "ap_sw_rst_b"=1 */ + CONSYS_REG_WRITE(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET, + (CONSYS_REG_READ(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET) & + ~CONSYS_SW_RST_BIT) | CONSYS_CPU_SW_RST_CTRL_KEY); + + /*de-assert CONNSYS S/W reset (SPM CR), set "ap_sw_rst_b"=1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) & + CONSYS_SPM_PWR_RST_BIT); +#if 0 + /*read check "conn_top_off" primary part power status, check + *"connsys_off_domain_pwr_ack"=1 + */ + value = CONSYS_TOP2_PWR_ON_ACK_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_OFFSET); + while (value == 0) + value = CONSYS_TOP2_PWR_ON_ACK_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_OFFSET); + /*read check "conn_top_off" secondary part power status, check + *"connsys_off_domain_pwr_ack_s"=1 + */ + value = CONSYS_TOP2_PWR_ON_ACK_S_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_S_OFFSET); + while (value == 0) + value = CONSYS_TOP2_PWR_ON_ACK_S_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_S_OFFSET); +#endif + /*wait 0.5ms*/ + udelay(500); + /*Turn off AHB RX bus sleep protect (AP2CONN AHB Bus protect) + *(apply this for INFRA AHB bus accessing when CONNSYS had been turned on) + */ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AHB_RX_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AHB_RX_PROT_EN_OFFSET) & ~CONSYS_AHB_RX_PROT_MASK); + value = ~CONSYS_AHB_RX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AHB_RX_PROT_STA_OFFSET); + i = 0; + while (value == 0 || i > 10) { + value = ~CONSYS_AP2CONN_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AHB_RX_PROT_STA_OFFSET); + i++; + } + + /*Turn off AXI Rx bus sleep protect (CONN2AP AXI Rx Bus protect) + *(disable sleep protection when CONNSYS had been turned on) + */ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AXI_RX_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AXI_RX_PROT_EN_OFFSET) & ~CONSYS_AXI_RX_PROT_MASK); + value = ~CONSYS_AXI_RX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AXI_RX_PROT_STA_OFFSET); + i = 0; + while (value == 0 || i > 10) { + value = ~CONSYS_AXI_RX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AXI_RX_PROT_STA_OFFSET); + i++; + } + + /*Turn off AXI TX bus sleep protect (CONN2AP AXI Tx Bus protect) + *(disable sleep protection when CONNSYS had been turned on) + */ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AXI_RX_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AXI_RX_PROT_EN_OFFSET) & ~CONSYS_AXI_TX_PROT_MASK); + value = ~CONSYS_AXI_TX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AXI_RX_PROT_STA_OFFSET); + i = 0; + while (value == 0 || i > 10) { + value = ~CONSYS_AXI_TX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AXI_RX_PROT_STA_OFFSET); + i++; + } + + /*Turn off AHB TX bus sleep protect (AP2CONN AHB Bus protect) + *(apply this for INFRA AHB bus accessing when CONNSYS had been turned on) + */ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AXI_RX_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AXI_RX_PROT_EN_OFFSET) & ~CONSYS_AHB_TX_PROT_MASK); + value = ~CONSYS_AHB_TX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AXI_RX_PROT_STA_OFFSET); + i = 0; + while (value == 0 || i > 10) { + value = ~CONSYS_AHB_TX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AXI_RX_PROT_STA_OFFSET); + i++; + } +#if 0 + /*SPM apsrc/ddr_en hardware mask disable & wait cycle setting*/ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_SPM_APSRC_OFFSET, + CONSYS_SPM_APSRC_VALUE); + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_SPM_DDR_EN_OFFSET, + CONSYS_SPM_DDR_EN_VALUE); +#endif + /*wait 5ms*/ + mdelay(5); +#endif /* CONSYS_PWR_ON_OFF_API_AVAILABLE */ + } else { +#if CONSYS_PWR_ON_OFF_API_AVAILABLE + p_ecsi = wmt_plat_get_emi_phy_add(); + if (!p_ecsi) + return iRet; + check_sleep_reg = wmt_plat_get_emi_virt_add + (p_ecsi->p_ecso->emi_apmem_ctrl_chip_check_sleep); + check_coredump_reg = wmt_plat_get_emi_virt_add + (p_ecsi->p_ecso->emi_apmem_ctrl_state); + + /* Handshake flow: Notify MCU goto sleep before connsys power off */ + if ((check_sleep_reg) && (check_coredump_reg) + && mtk_wcn_consys_get_adie_chipid()) { + /* check if chip reset flow */ + if ((CONSYS_REG_READ(check_coredump_reg) == 0) + && (mtk_consys_chip_reset_status() != 1)) { + /* 1. write pattern EMI CR: F006804C = 0x5aa5 */ + CONSYS_REG_WRITE(check_sleep_reg, MCU_GOTO_SLEEP); + + /* 2. trigger EINT */ + mtk_wcn_force_trigger_assert_debug_pin(); + + /* 3. Polling EMI CR: F006804C == 0x7788 */ + while (retry-- > 0) { + check_sleep = CONSYS_REG_READ(check_sleep_reg); + if (check_sleep == MCU_SLEEP_DONE) { + WMT_PLAT_PR_INFO("consys is ready to sleep\n"); + break; + } + WMT_STEP_DO_ACTIONS_FUNC + (STEP_TRIGGER_POINT_POWER_OFF_HANDSHAKE); + WMT_PLAT_PR_INFO("check_sleep_reg=(0x%x)\n", check_sleep); + msleep(20); + } + /* 4. Clear EMI CR: F006804C = 0 */ + CONSYS_REG_WRITE(check_sleep_reg, 0x0); + } + } + + if (conn_reg.infra_ao_pericfg_base != 0) { + WMT_PLAT_PR_DBG("CON_STA_REG = %x\n", + CONSYS_REG_READ( + conn_reg.infra_ao_pericfg_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG)); + + /* Clean CON_STA_REG + * when power off or reset connsys + */ + CONSYS_REG_WRITE((conn_reg.infra_ao_pericfg_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG), 0); + + WMT_PLAT_PR_DBG("CON_STA_REG = %x\n", + CONSYS_REG_READ( + conn_reg.infra_ao_pericfg_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG)); + } +#if (COMMON_KERNEL_CLK_SUPPORT) + iRet = device_init_wakeup(&connsys_pdev->dev, false); + if (iRet) + WMT_PLAT_PR_INFO("device_init_wakeup(false) fail.\n"); + else + WMT_PLAT_PR_INFO("device_init_wakeup(false) CONSYS ok\n"); + + iRet = pm_runtime_put_sync(&connsys_pdev->dev); + if (iRet) + WMT_PLAT_PR_INFO("pm_runtime_put_sync() fail.\n"); + else + WMT_PLAT_PR_INFO("pm_runtime_put_sync() CONSYS ok\n"); +#else + clk_disable_unprepare(clk_scp_conn_main); + WMT_PLAT_PR_DBG("clk_disable_unprepare(clk_scp_conn_main) calling\n"); +#endif + + /* Clean CCIF4 ACK status */ + /* Wait 100us to make sure all ongoing tx interrupt could be + * reset. + * According to profiling result, the time between read + * register and send tx interrupt is less than 20 us. + */ + udelay(100); + CONSYS_REG_WRITE((conn_reg.ap_pccif4_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PCCIF_ACK_OFFSET), + 0xFF); + WMT_PLAT_PR_DBG("AP_PCCIF_ACK = %x\n", + CONSYS_REG_READ( + conn_reg.ap_pccif4_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PCCIF_ACK_OFFSET)); + + clk_disable_unprepare(clk_infracfg_ao_ccif4_ap_cg); + WMT_PLAT_PR_DBG("clk_disable_unprepare(clk_infracfg_ao_ccif4_ap_cg) calling\n"); + +#else + /* Turn on AHB bus sleep protect (AP2CONN AHB Bus protect) + * (apply this for INFRA AXI bus protection to prevent bus hang + * when CONNSYS had been turned off) + */ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AHBAXI_PROT_EN_OFFSET) & + CONSYS_AP2CONN_PROT_MASK); + value = CONSYS_AP2CONN_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_STA_OFFSET); + i = 0; + while (value == CONSYS_AP2CONN_PROT_MASK || i > 10) { + value = CONSYS_AP2CONN_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AHBAXI_PROT_STA_OFFSET); + i++; + } + /* Turn on AXI Tx bus sleep protect (CONN2AP AXI Tx Bus protect) + * (apply this for INFRA AXI bus protection to prevent bus hang + * when CONNSYS had been turned off) + * Note : Should turn on AXI Tx sleep protection first. + */ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AHBAXI_PROT_EN_OFFSET) & + CONSYS_TX_PROT_MASK); + value = CONSYS_TX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_STA_OFFSET); + i = 0; + while (value == CONSYS_TX_PROT_MASK || i > 10) { + value = CONSYS_TX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AHBAXI_PROT_STA_OFFSET); + i++; + } + /* Turn on AXI Rx bus sleep protect (CONN2AP AXI RX Bus protect) + * (apply this for INFRA AXI bus protection to prevent bus hang + * when CONNSYS had been turned off) + * Note : Should turn on AXI Rx sleep protection + * after AXI Tx sleep protection has been turn on. + */ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AHBAXI_PROT_EN_OFFSET) & + CONSYS_RX_PROT_MASK); + value = CONSYS_RX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_STA_OFFSET); + i = 0; + while (value == CONSYS_RX_PROT_MASK || i > 10) { + value = CONSYS_RX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AHBAXI_PROT_STA_OFFSET); + i++; + } + + /*assert "conn_top_on" isolation, set "connsys_iso_en"=1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_SPM_PWR_ISO_S_BIT); + /*assert CONNSYS S/W reset (TOP RGU CR), set "ap_sw_rst_b"=0 */ + CONSYS_REG_WRITE(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET, + (CONSYS_REG_READ(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET) & + CONSYS_SW_RST_BIT) | CONSYS_CPU_SW_RST_CTRL_KEY); + /*assert CONNSYS S/W reset (SPM CR), set "ap_sw_rst_b"=0 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + ~CONSYS_SPM_PWR_RST_BIT); + /*write conn_clk_dis=1, disable connsys clock 0x1000632C [4] 1'b1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_CLK_CTRL_BIT); + /*wait 1us */ + udelay(1); + /*write conn_top1_pwr_on=0, power off conn_top1 0x1000632C [3:2] 2'b00 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) & + ~(CONSYS_SPM_PWR_ON_BIT | CONSYS_SPM_PWR_ON_S_BIT)); +#endif /* CONSYS_PWR_ON_OFF_API_AVAILABLE */ + } + +#if CONSYS_PWR_ON_OFF_API_AVAILABLE + return iRet; +#else + return 0; +#endif +} + +static INT32 consys_ahb_clock_ctrl(MTK_WCN_BOOL enable) +{ + return 0; +} + +static INT32 polling_consys_chipid(VOID) +{ + INT32 retry = 10; + UINT32 consys_ver_id = 0; + UINT32 consys_hw_ver = 0; + UINT32 consys_fw_ver = 0; + UINT8 *consys_reg_base = NULL; + UINT32 value = 0; + + /*12.poll CONNSYS CHIP ID until chipid is returned 0x18070008 */ + while (retry-- > 0) { + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_top_misc_off_base + + CONSYS_IP_VER_OFFSET); + if (consys_ver_id == CONSYS_IP_VER_ID) { + WMT_PLAT_PR_INFO("retry(%d)consys version id(0x%08x)\n", + retry, consys_ver_id); + consys_hw_ver = CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HW_ID_OFFSET); + WMT_PLAT_PR_INFO("consys HW version id(0x%x)\n", consys_hw_ver & 0xFFFF); + consys_fw_ver = CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_FW_ID_OFFSET); + WMT_PLAT_PR_INFO("consys FW version id(0x%x)\n", consys_fw_ver & 0xFFFF); + + if (mtk_wcn_consys_get_adie_chipid()) + consys_dl_rom_patch(consys_ver_id, consys_fw_ver); + break; + } + WMT_PLAT_PR_ERR("Read CONSYS version id(0x%08x)", consys_ver_id); + msleep(20); + } + + if (retry <= 0) + return -1; + + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_top_misc_off_base + CONSYS_CONF_ID_OFFSET); + WMT_PLAT_PR_INFO("consys configuration id(0x%x)\n", consys_ver_id & 0xF); + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HW_ID_OFFSET); + WMT_PLAT_PR_INFO("consys HW version id(0x%x)\n", consys_ver_id & 0xFFFF); + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_FW_ID_OFFSET); + WMT_PLAT_PR_INFO("consys FW version id(0x%x)\n", consys_ver_id & 0xFFFF); + + /* set CR "XO initial stable time" and "XO bg stable time" + * to optimize the wakeup time after sleep + * clear "source clock enable ack to XO state" mask + */ + if (wmt_plat_soc_co_clock_flag_get()) { + consys_reg_base = ioremap_nocache(CONSYS_COCLOCK_STABLE_TIME_BASE, 0x100); + if (consys_reg_base) { + value = CONSYS_REG_READ(consys_reg_base); + value = (value & CONSYS_COCLOCK_STABLE_TIME_MASK) | + CONSYS_COCLOCK_STABLE_TIME; + CONSYS_REG_WRITE(consys_reg_base, value); + value = CONSYS_REG_READ(consys_reg_base + CONSYS_COCLOCK_ACK_ENABLE_OFFSET); + value = (value & CONSYS_COCLOCK_ACK_ENABLE_MAST) | + CONSYS_COCLOCK_ACK_ENABLE_VALUE; + value = value & (~CONSYS_COCLOCK_ACK_ENABLE_BIT); + CONSYS_REG_WRITE(consys_reg_base + CONSYS_COCLOCK_ACK_ENABLE_OFFSET, value); + iounmap(consys_reg_base); + } else + WMT_PLAT_PR_ERR("connsys co_clock stable time base(0x%x) ioremap fail!\n", + CONSYS_COCLOCK_STABLE_TIME_BASE); + } + + /* write reserverd cr for identify adie is 6635 or 6631 */ + consys_reg_base = ioremap_nocache(CONSYS_IDENTIFY_ADIE_CR_ADDRESS, 0x8); + if (consys_reg_base) { + value = CONSYS_REG_READ(consys_reg_base); + if (mtk_wcn_consys_get_adie_chipid() == PRIMARY_ADIE) + value = value & (~CONSYS_IDENTIFY_ADIE_ENABLE_BIT); + else + value = value | (CONSYS_IDENTIFY_ADIE_ENABLE_BIT); + CONSYS_REG_WRITE(consys_reg_base, value); + iounmap(consys_reg_base); + } else + WMT_PLAT_PR_ERR("connsys identify adie cr address(0x%x) ioremap fail!\n", + CONSYS_IDENTIFY_ADIE_CR_ADDRESS); + + /* if(MT6635) + * CONN_WF_CTRL2 swtich to GPIO mode, GPIO output value + * before patch download swtich back to CONN mode. + */ + if (mtk_wcn_consys_get_adie_chipid() == PRIMARY_ADIE) { + consys_reg_base = ioremap_nocache(CONSYS_IF_PINMUX_REG_BASE, 0x1000); + if (!consys_reg_base) { + WMT_PLAT_PR_INFO("consys_if_pinmux_reg_base(%x) ioremap fail\n", + CONSYS_IF_PINMUX_REG_BASE); + return 0; + } + + CONSYS_REG_WRITE(consys_reg_base + CONSYS_WF_CTRL2_01_OFFSET, + (CONSYS_REG_READ(consys_reg_base + CONSYS_WF_CTRL2_01_OFFSET) & + CONSYS_WF_CTRL2_01_MASK) | CONSYS_WF_CTRL2_01_VALUE); + CONSYS_REG_WRITE(consys_reg_base + CONSYS_WF_CTRL2_02_OFFSET, + (CONSYS_REG_READ(consys_reg_base + CONSYS_WF_CTRL2_02_OFFSET) & + CONSYS_WF_CTRL2_02_MASK) | CONSYS_WF_CTRL2_02_VALUE); + CONSYS_REG_WRITE(consys_reg_base + CONSYS_WF_CTRL2_03_OFFSET, + (CONSYS_REG_READ(consys_reg_base + CONSYS_WF_CTRL2_03_OFFSET) & + CONSYS_WF_CTRL2_03_MASK) | CONSYS_WF_CTRL2_GPIO_MODE); + iounmap(consys_reg_base); + } + + /* connsys bus time out configure, enable AHB bus timeout */ + consys_reg_base = ioremap_nocache(CONSYS_AHB_TIMEOUT_EN_ADDRESS, 0x100); + if (consys_reg_base) { + CONSYS_REG_WRITE(consys_reg_base, CONSYS_AHB_TIMEOUT_EN_VALUE); + iounmap(consys_reg_base); + } else + WMT_PLAT_PR_ERR("CONSYS_AHB_TIMEOUT_EN_ADDRESS(0x%x) ioremap fail!\n", + CONSYS_AHB_TIMEOUT_EN_ADDRESS); + + /* update WPLL setting for WPLL issue@LT */ + consys_reg_base = ioremap_nocache(CONSYS_WPLL_SETTING_ADDRESS, 0x100); + if (consys_reg_base) { + CONSYS_REG_WRITE(consys_reg_base, + (CONSYS_REG_READ(consys_reg_base) & + CONSYS_WPLL_SETTING_MASK) | CONSYS_WPLL_SETTING_VALUE); + iounmap(consys_reg_base); + } + + /* toppose_restore_done rollabck */ + consys_reg_base = ioremap_nocache(CONSYS_TOPPOSE_RESTORE_ADDRESS, 0x100); + if (consys_reg_base) { + CONSYS_REG_WRITE(consys_reg_base, + (CONSYS_REG_READ(consys_reg_base) & + CONSYS_TOPPOSE_RESTORE_MASK) | CONSYS_TOPPOSE_RESTORE_VALUE); + iounmap(consys_reg_base); + } + + return 0; +} + +static VOID consys_acr_reg_setting(VOID) +{ + WMT_PLAT_PR_INFO("No need to do acr"); +} + +static VOID consys_afe_reg_setting(VOID) +{ + WMT_PLAT_PR_INFO("No need to do afe"); +} + +static INT32 consys_hw_vcn18_ctrl(MTK_WCN_BOOL enable) +{ +#if CONSYS_PMIC_CTRL_ENABLE + if (enable) { +#if (!COMMON_KERNEL_PMIC_SUPPORT) + /*Set VCN18_SW_OP_EN as 1*/ + KERNEL_pmic_ldo_vcn18_lp(SW, 1, 1, SW_OFF); +#endif + /*Set VCN18_SW_EN as 1 and set votage as 1V8*/ + if (reg_VCN18) { + regulator_set_voltage(reg_VCN18, 1800000, 1800000); + if (regulator_enable(reg_VCN18)) + WMT_PLAT_PR_ERR("enable VCN18 fail\n"); + else + WMT_PLAT_PR_DBG("enable VCN18 ok\n"); + } +#if (COMMON_KERNEL_PMIC_SUPPORT) + /* Set VCN18 as low-power mode(1), HW0_OP_EN as 1, + * HW0_OP_CFG as HW_LP(1) + */ + if (g_regmap) { + regmap_write(g_regmap, MT6359_LDO_VCN18_OP_CFG_SET, 1); + regmap_write(g_regmap, MT6359_LDO_VCN18_OP_EN_SET, 1); + } +#else + /*Set VCN18 SW_LP as 0*/ + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN18_LP, 0); + /*Set VCN18 as low-power mode(1), HW0_OP_EN as 1, HW0_OP_CFG as HW_LP(1)*/ + KERNEL_pmic_ldo_vcn18_lp(SRCLKEN0, 1, 1, HW_LP); +#endif + if (mtk_wcn_consys_get_adie_chipid() == PRIMARY_ADIE) { + /* delay 300us (VCN18 stable time) */ + udelay(300); +#if (!COMMON_KERNEL_PMIC_SUPPORT) + /*Set VCN13_SW_OP_EN as 1*/ + KERNEL_pmic_ldo_vcn13_lp(SW, 1, 1, SW_OFF); +#endif + /*Set VCN13_SW_EN as 1 and set votage as 1V3*/ + if (reg_VCN13) { + regulator_set_voltage(reg_VCN13, 1300000, 1300000); + if (regulator_enable(reg_VCN13)) + WMT_PLAT_PR_INFO("enable VCN13 fail\n"); + else + WMT_PLAT_PR_DBG("enable VCN13 ok\n"); + } +#if (!COMMON_KERNEL_PMIC_SUPPORT) + /*Set VCN13 SW_LP as 0*/ + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN13_LP, 0); + /*Set VCN13 as low-power mode(1), HW0_OP_EN as 1, HW0_OP_CFG as HW_LP(1)*/ + KERNEL_pmic_ldo_vcn13_lp(SRCLKEN0, 1, 1, HW_LP); +#else + /* Set VCN13 as low-power mode(1), HW0_OP_EN as 1, + * HW0_OP_CFG as HW_LP(1) + */ + if (g_regmap) { + regmap_write(g_regmap, MT6359_LDO_VCN13_OP_CFG_SET, 1); + regmap_write(g_regmap, MT6359_LDO_VCN13_OP_EN_SET, 1); + } +#endif + } else { + /*1.AP power on VCN_3V3 LDO (with PMIC_WRAP API) VCN_3V3 */ + /*default vcn33_1 SW mode*/ + if (reg_VCN33_1_BT) { + regulator_set_voltage(reg_VCN33_1_BT, 3500000, 3500000); + if (regulator_enable(reg_VCN33_1_BT)) + WMT_PLAT_PR_ERR("WMT do BT PMIC on fail!\n"); + } + } + } else { + if (mtk_wcn_consys_get_adie_chipid() == PRIMARY_ADIE) { + if (reg_VCN13) + regulator_disable(reg_VCN13); + } else { + if (reg_VCN33_1_BT) + regulator_disable(reg_VCN33_1_BT); + } + /* delay 300us */ + udelay(300); + /*AP power off MT6351L VCN_1V8 LDO */ + if (reg_VCN18) { + if (regulator_disable(reg_VCN18)) + WMT_PLAT_PR_ERR("disable VCN_1V8 fail!\n"); + else + WMT_PLAT_PR_DBG("disable VCN_1V8 ok\n"); + } + } +#endif + return 0; +} + +static VOID consys_vcn28_hw_mode_ctrl(UINT32 enable) +{ +#if CONSYS_PMIC_CTRL_ENABLE + if (mtk_wcn_consys_get_adie_chipid() == SECONDARY_ADIE) { +#if (!COMMON_KERNEL_PMIC_SUPPORT) + if (enable) + /*Set VCN33_2_SW_OP_EN as 1*/ + KERNEL_pmic_ldo_vcn33_2_lp(SW, 1, 1, SW_OFF); + else + /*Set VCN33_2 as low-power mode(1), HW0_OP_EN as 0, HW0_OP_CFG as HW_OFF(0)*/ + KERNEL_pmic_ldo_vcn33_2_lp(SRCLKEN0, 1, 0, HW_OFF); +#else + if (!enable && g_regmap) + regmap_write(g_regmap, MT6359_LDO_VCN33_2_OP_EN_CLR, 1); +#endif + } +#endif +} + +static INT32 consys_hw_vcn28_ctrl(UINT32 enable) +{ +#if CONSYS_PMIC_CTRL_ENABLE + if (mtk_wcn_consys_get_adie_chipid() == SECONDARY_ADIE) { + if (enable) { + /*in co-clock mode,need to turn on vcn33_2 when fm on */ +#if (!COMMON_KERNEL_PMIC_SUPPORT) + /*Set VCN33_2_SW_OP_EN as 1*/ + KERNEL_pmic_ldo_vcn33_2_lp(SW, 1, 1, SW_OFF); +#endif + /*Set VCN33_1_SW_EN as 1 and set votage as 2V8*/ + if (reg_VCN33_2_WIFI) { + regulator_set_voltage(reg_VCN33_2_WIFI, 2800000, 2800000); + if (regulator_enable(reg_VCN33_2_WIFI)) + WMT_PLAT_PR_INFO("[%s::%d] WMT do VCN33_2 PMIC on fail!\n", __func__, __LINE__); + } +#if (!COMMON_KERNEL_PMIC_SUPPORT) + /*Set VCN33_2 SW_LP as 0*/ + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_2_LP, 0); + /*Set VCN33_2 as low-power mode(1), HW0_OP_EN as 1, HW0_OP_CFG as HW_OFF(0)*/ + KERNEL_pmic_ldo_vcn33_2_lp(SRCLKEN0, 1, 1, HW_OFF); +#else + /* Set HW0_OP_EN as 1 */ + if (g_regmap) + regmap_write(g_regmap, MT6359_LDO_VCN33_2_OP_EN_SET, 1); +#endif + WMT_PLAT_PR_INFO("turn on vcn33_2 for fm/gps usage in co-clock mode\n"); + } else { + /*in co-clock mode,need to turn off vcn33_2 when fm off */ +#if (!COMMON_KERNEL_PMIC_SUPPORT) + /*Set VCN33_2 as low-power mode(1), HW0_OP_EN as 0, HW0_OP_CFG as HW_OFF(0)*/ + KERNEL_pmic_ldo_vcn33_2_lp(SRCLKEN0, 1, 0, HW_OFF); +#else + /* Set HW0_OP_EN as 0 */ + if (g_regmap) + regmap_write(g_regmap, MT6359_LDO_VCN33_2_OP_EN_CLR, 1); +#endif + if (reg_VCN33_2_WIFI) + regulator_disable(reg_VCN33_2_WIFI); + WMT_PLAT_PR_INFO("turn off vcn33_2 for fm/gps usage in co-clock mode\n"); + } + } +#endif + + return 0; +} + +static INT32 consys_hw_bt_vcn33_ctrl(UINT32 enable) +{ + if (mtk_wcn_consys_get_adie_chipid() == SECONDARY_ADIE) + return 0; + + if (enable) { +#if CONSYS_PMIC_CTRL_ENABLE +#if (!COMMON_KERNEL_PMIC_SUPPORT) + /*Set VCN33_1_SW_OP_EN as 1*/ + KERNEL_pmic_ldo_vcn33_1_lp(SW, 1, 1, SW_OFF); +#endif + /*Set VCN33_1_SW_EN as 1 and set votage as 3V3*/ + if (reg_VCN33_1_BT) { + regulator_set_voltage(reg_VCN33_1_BT, 3300000, 3300000); + if (regulator_enable(reg_VCN33_1_BT)) + WMT_PLAT_PR_ERR("WMT do BT PMIC on fail!\n"); + } +#if (!COMMON_KERNEL_PMIC_SUPPORT) + /*Set VCN33_1 SW_LP as 0*/ + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_1_LP, 0); + /*Set VCN33_1 as low-power mode(1), HW0_OP_EN as 1, HW0_OP_CFG as HW_OFF(0)*/ + KERNEL_pmic_ldo_vcn33_1_lp(SRCLKEN0, 1, 1, HW_OFF); + /* request VS2 to 1.4V by VS2 VOTER (use bit 4) */ + KERNEL_pmic_set_register_value(PMIC_RG_BUCK_VS2_VOTER_EN_SET, 0x10); + /* Set VCN13 to 1.32V */ + KERNEL_pmic_set_register_value(PMIC_RG_VCN13_VOCAL, 0x2); +#else + if (g_regmap) { + /* Set HW0_OP_EN as 1 */ + regmap_write(g_regmap, MT6359_LDO_VCN33_1_OP_EN_SET, 1); + /* request VS2 to 1.4V by VS2 VOTER (use bit 4) */ + regmap_write(g_regmap, MT6359_BUCK_VS2_VOTER_SET, 0x10); + /* Set VCN13 to 1.32V */ + regmap_update_bits(g_regmap, MT6359_RG_VCN13_VOCAL_ADDR, + MT6359_RG_VCN13_VOCAL_MASK << MT6359_RG_VCN13_VOCAL_SHIFT, 0x2); + } +#endif +#endif + WMT_PLAT_PR_DBG("WMT do BT PMIC on\n"); + } else { + /*do BT PMIC off */ + /*switch BT PALDO control from HW mode to SW mode:0x416[5]-->0x0 */ +#if CONSYS_PMIC_CTRL_ENABLE +#if (!COMMON_KERNEL_PMIC_SUPPORT) + /*Set VCN33_1 as low-power mode(1), HW0_OP_EN as 0, HW0_OP_CFG as HW_OFF(0)*/ + KERNEL_pmic_ldo_vcn33_1_lp(SRCLKEN0, 1, 0, HW_OFF); + /* restore VCN13 to 1.3V */ + KERNEL_pmic_set_register_value(PMIC_RG_VCN13_VOCAL, 0); + /* clear bit 4 of VS2 VOTER then VS2 can restore to 1.35V */ + KERNEL_pmic_set_register_value(PMIC_RG_BUCK_VS2_VOTER_EN_CLR, 0x10); +#else + if (g_regmap) { + /* Set VCN33_1 as low-power mode(1), HW0_OP_EN as 0 */ + regmap_write(g_regmap, MT6359_LDO_VCN33_1_OP_EN_CLR, 1); + /* restore VCN13 to 1.3V */ + regmap_update_bits(g_regmap, MT6359_RG_VCN13_VOCAL_ADDR, + MT6359_RG_VCN13_VOCAL_MASK << MT6359_RG_VCN13_VOCAL_SHIFT, 0); + /* clear bit 4 of VS2 VOTER then VS2 can restore to 1.35V */ + regmap_write(g_regmap, MT6359_BUCK_VS2_VOTER_CLR, 0x10); + } +#endif + if (reg_VCN33_1_BT) + regulator_disable(reg_VCN33_1_BT); +#endif + WMT_PLAT_PR_DBG("WMT do BT PMIC off\n"); + } + + return 0; +} + +static INT32 consys_hw_wifi_vcn33_ctrl(UINT32 enable) +{ + if (mtk_wcn_consys_get_adie_chipid() == SECONDARY_ADIE) + return 0; + + if (enable) { +#if CONSYS_PMIC_CTRL_ENABLE +#if (!COMMON_KERNEL_PMIC_SUPPORT) + /*Set VCN33_1_SW_OP_EN as 1*/ + KERNEL_pmic_ldo_vcn33_1_lp(SW, 1, 1, SW_OFF); +#endif + /*Set VCN33_1_SW_EN as 1 and set votage as 3V3*/ + if (reg_VCN33_1_WIFI) { + regulator_set_voltage(reg_VCN33_1_WIFI, 3300000, 3300000); + if (regulator_enable(reg_VCN33_1_WIFI)) + WMT_PLAT_PR_ERR("WMT do WIFI PMIC on fail!\n"); + } +#if (!COMMON_KERNEL_PMIC_SUPPORT) + /*Set VCN33_1 SW_LP as 0*/ + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_1_LP, 0); + /*Set VCN33_1 as low-power mode(1), HW0_OP_EN as 1, HW0_OP_CFG as HW_OFF(0)*/ + KERNEL_pmic_ldo_vcn33_1_lp(SRCLKEN0, 1, 1, HW_OFF); + + /*Set VCN33_2_SW_OP_EN as 1*/ + KERNEL_pmic_ldo_vcn33_2_lp(SW, 1, 1, SW_OFF); +#else + /* Set HW0_OP_EN as 1 */ + if (g_regmap) + regmap_write(g_regmap, MT6359_LDO_VCN33_1_OP_EN_SET, 1); +#endif + /*Set VCN33_1_SW_EN as 1 and set votage as 3V3*/ + if (reg_VCN33_2_WIFI) { + regulator_set_voltage(reg_VCN33_2_WIFI, 3300000, 3300000); + if (regulator_enable(reg_VCN33_2_WIFI)) + WMT_PLAT_PR_ERR("WMT do WIFI PMIC on fail!\n"); + } +#if (!COMMON_KERNEL_PMIC_SUPPORT) + /*Set VCN33_2 SW_LP as 0*/ + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_2_LP, 0); + /*Set VCN33_2 as low-power mode(1), HW0_OP_EN as 1, HW0_OP_CFG as HW_OFF(0)*/ + KERNEL_pmic_ldo_vcn33_2_lp(SRCLKEN0, 1, 1, HW_OFF); +#else + /* Set HW0_OP_EN as 1 */ + if (g_regmap) + regmap_write(g_regmap, MT6359_LDO_VCN33_2_OP_EN_SET, 1); +#endif +#endif + WMT_PLAT_PR_DBG("WMT do WIFI PMIC on\n"); + } else { + /*do WIFI PMIC off */ + /*switch WIFI PALDO control from HW mode to SW mode:0x418[14]-->0x0 */ +#if CONSYS_PMIC_CTRL_ENABLE +#if (!COMMON_KERNEL_PMIC_SUPPORT) + /*Set VCN33_1 as low-power mode(1), HW0_OP_EN as 0, HW0_OP_CFG as HW_OFF(0)*/ + KERNEL_pmic_ldo_vcn33_1_lp(SRCLKEN0, 1, 0, HW_OFF); +#else + if (g_regmap) + regmap_write(g_regmap, MT6359_LDO_VCN33_1_OP_EN_CLR, 1); +#endif + if (reg_VCN33_1_WIFI) + regulator_disable(reg_VCN33_1_WIFI); +#if (!COMMON_KERNEL_PMIC_SUPPORT) + /*Set VCN33_2 as low-power mode(1), HW0_OP_EN as 0, HW0_OP_CFG as HW_OFF(0)*/ + KERNEL_pmic_ldo_vcn33_2_lp(SRCLKEN0, 1, 0, HW_OFF); +#else + if (g_regmap) + regmap_write(g_regmap, MT6359_LDO_VCN33_2_OP_EN_CLR, 1); +#endif + if (reg_VCN33_2_WIFI) + regulator_disable(reg_VCN33_2_WIFI); +#endif + WMT_PLAT_PR_DBG("WMT do WIFI PMIC off\n"); + } + + return 0; +} + +static INT32 consys_emi_mpu_set_region_protection(VOID) +{ + struct emimpu_region_t region; + unsigned long long start = gConEmiPhyBase; + unsigned long long end = gConEmiPhyBase + gConEmiSize - 1; + + mtk_emimpu_init_region(®ion, REGION_CONN); + mtk_emimpu_set_addr(®ion, start, end); + mtk_emimpu_set_apc(®ion, DOMAIN_AP, MTK_EMIMPU_NO_PROTECTION); + mtk_emimpu_set_apc(®ion, DOMAIN_CONN, MTK_EMIMPU_NO_PROTECTION); + mtk_emimpu_set_protection(®ion); + mtk_emimpu_free_region(®ion); + + WMT_PLAT_PR_INFO("setting MPU for EMI share memory\n"); + + return 0; +} + +static UINT32 consys_emi_set_remapping_reg(VOID) +{ + /* For direct path */ + phys_addr_t mdPhy = 0; + INT32 size = 0; + + mtk_wcn_emi_addr_info.emi_ap_phy_addr = gConEmiPhyBase; + mtk_wcn_emi_addr_info.emi_size = gConEmiSize; + + /*EMI Registers remapping*/ + CONSYS_REG_WRITE_OFFSET_RANGE(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET, + gConEmiPhyBase, 0, 16, 20); + WMT_PLAT_PR_INFO("CONSYS_EMI_MAPPING dump in restore cb(0x%08x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET)); + + /*Perisys Configuration Registers remapping*/ + CONSYS_REG_WRITE_OFFSET_RANGE(conn_reg.topckgen_base + CONSYS_EMI_PERI_MAPPING_OFFSET, + 0x10003000, 0, 16, 20); + WMT_PLAT_PR_INFO("PERISYS_MAPPING dump in restore cb(0x%08x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_PERI_MAPPING_OFFSET)); + + /*Modem Configuration Registers remapping*/ + mdPhy = get_smem_phy_start_addr(MD_SYS1, SMEM_USER_RAW_MD_CONSYS, &size); + if (size == 0) + WMT_PLAT_PR_INFO("MD direct path is not supported\n"); + else { + CONSYS_REG_WRITE_OFFSET_RANGE( + conn_reg.topckgen_base + CONSYS_EMI_AP_MD_OFFSET, + mdPhy, 0, 16, 20); + WMT_PLAT_PR_INFO("MD_MAPPING dump in restore cb(0x%08x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_AP_MD_OFFSET)); + } + mtk_wcn_emi_addr_info.emi_direct_path_ap_phy_addr = mdPhy; + mtk_wcn_emi_addr_info.emi_direct_path_size = size; + + mtk_wcn_emi_addr_info.emi_ram_bt_buildtime_offset = + CONSYS_EMI_RAM_BT_BUILDTIME_OFFSET; + mtk_wcn_emi_addr_info.emi_ram_wifi_buildtime_offset = + CONSYS_EMI_RAM_WIFI_BUILDTIME_OFFSET; + mtk_wcn_emi_addr_info.emi_ram_mcu_buildtime_offset = + CONSYS_EMI_RAM_MCU_BUILDTIME_OFFSET; + mtk_wcn_emi_addr_info.emi_patch_mcu_buildtime_offset = + CONSYS_EMI_PATCH_MCU_BUILDTIME_OFFSET; + + return 0; +} + +static INT32 bt_wifi_share_v33_spin_lock_init(VOID) +{ + return 0; +} + +static INT32 consys_read_irq_info_from_dts(struct platform_device *pdev, PINT32 irq_num, + PUINT32 irq_flag) +{ + struct device_node *node; + + node = pdev->dev.of_node; + if (node) { + *irq_num = irq_of_parse_and_map(node, 0); + *irq_flag = irq_get_trigger_type(*irq_num); + WMT_PLAT_PR_INFO("get irq id(%d) and irq trigger flag(%d) from DT\n", *irq_num, + *irq_flag); + } else { + WMT_PLAT_PR_ERR("[%s] can't find CONSYS compatible node\n", __func__); + return -1; + } + + return 0; +} + +static INT32 consys_read_reg_from_dts(struct platform_device *pdev) +{ + INT32 iRet = -1; + struct device_node *node = NULL; + + node = pdev->dev.of_node; + if (node) { + /* registers base address */ + conn_reg.mcu_base = (SIZE_T) of_iomap(node, MCU_BASE_INDEX); + WMT_PLAT_PR_DBG("Get mcu register base(0x%zx)\n", conn_reg.mcu_base); + conn_reg.ap_rgu_base = (SIZE_T) of_iomap(node, TOP_RGU_BASE_INDEX); + WMT_PLAT_PR_DBG("Get ap_rgu register base(0x%zx)\n", conn_reg.ap_rgu_base); + conn_reg.topckgen_base = (SIZE_T) of_iomap(node, INFRACFG_AO_BASE_INDEX); + WMT_PLAT_PR_DBG("Get topckgen register base(0x%zx)\n", conn_reg.topckgen_base); + conn_reg.spm_base = (SIZE_T) of_iomap(node, SPM_BASE_INDEX); + WMT_PLAT_PR_DBG("Get spm register base(0x%zx)\n", conn_reg.spm_base); + conn_reg.mcu_conn_hif_on_base = (SIZE_T) of_iomap(node, MCU_CONN_HIF_ON_BASE_INDEX); + WMT_PLAT_PR_DBG("Get mcu_conn_hif_on register base(0x%zx)\n", + conn_reg.mcu_conn_hif_on_base); + conn_reg.mcu_top_misc_off_base = (SIZE_T) of_iomap(node, + MCU_TOP_MISC_OFF_BASE_INDEX); + WMT_PLAT_PR_DBG("Get mcu_top_misc_off register base(0x%zx)\n", + conn_reg.mcu_top_misc_off_base); + conn_reg.mcu_cfg_on_base = (SIZE_T) of_iomap(node, MCU_CFG_ON_BASE_INDEX); + WMT_PLAT_PR_DBG("Get mcu_cfg_on register base(0x%zx)\n", conn_reg.mcu_cfg_on_base); + conn_reg.mcu_cirq_base = (SIZE_T) of_iomap(node, MCU_CIRQ_BASE_INDEX); + WMT_PLAT_PR_DBG("Get mcu cirq register base(0x%zx)\n", conn_reg.mcu_cirq_base); + conn_reg.mcu_top_misc_on_base = (SIZE_T) of_iomap(node, MCU_TOP_MISC_ON_BASE_INDEX); + WMT_PLAT_PR_DBG("Get mcu_top_misc_off register base(0x%zx)\n", + conn_reg.mcu_top_misc_on_base); + conn_reg.ap_pccif4_base = (SIZE_T) of_iomap(node, AP_PCCIF4_BASE_INDEX); + WMT_PLAT_PR_DBG("Get ap_pccif4 register base(0x%zx)\n", + conn_reg.ap_pccif4_base); + conn_reg.infra_ao_pericfg_base = (SIZE_T) of_iomap(node, INFRA_AO_PERICFG_BASE_INDEX); + WMT_PLAT_PR_DBG("Get infra_ao_pericfg register base(0x%zx)\n", + conn_reg.infra_ao_pericfg_base); + } else { + WMT_PLAT_PR_ERR("[%s] can't find CONSYS compatible node\n", __func__); + return iRet; + } + + return 0; +} + +static VOID force_trigger_assert_debug_pin(VOID) +{ + UINT32 value = 0; + + if (conn_reg.infra_ao_pericfg_base != 0) { + WMT_PLAT_PR_DBG("CON_STA_REG = %x\n", + CONSYS_REG_READ( + conn_reg.infra_ao_pericfg_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG)); + + /* clear CON_PWR_ON & CON_SW_READY bit (CON_STA_REG[0], CON_STA_REG[1]) */ + value = CONSYS_REG_READ(conn_reg.infra_ao_pericfg_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG); + value = value & (~INFRASYS_COMMON_AP2MD_CON_PWR_ON_CON_SW_READY_MASK); + CONSYS_REG_WRITE(conn_reg.infra_ao_pericfg_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG, + value); + + WMT_PLAT_PR_DBG("CON_STA_REG = %x\n", + CONSYS_REG_READ( + conn_reg.infra_ao_pericfg_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG)); + } + + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AP2CONN_OSC_EN_OFFSET) & ~CONSYS_AP2CONN_WAKEUP_BIT); + WMT_PLAT_PR_INFO("enable:dump CONSYS_AP2CONN_OSC_EN_REG(0x%x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET)); + usleep_range(64, 96); + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AP2CONN_OSC_EN_OFFSET) | CONSYS_AP2CONN_WAKEUP_BIT); + WMT_PLAT_PR_INFO("disable:dump CONSYS_AP2CONN_OSC_EN_REG(0x%x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET)); +} + +static UINT32 consys_read_cpupcr(VOID) +{ + if (conn_reg.mcu_conn_hif_on_base == 0) + return 0; + + return CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + CONSYS_CPUPCR_OFFSET); +} + +static UINT32 consys_soc_chipid_get(VOID) +{ + return PLATFORM_SOC_CHIP; +} + +static UINT32 consys_adie_chipid_checking_flow(UINT32 adie) +{ + UINT8 *conn_rf_spi_base = NULL; + UINT32 chipid = 0; + UINT32 retry = 10; + + conn_rf_spi_base = ioremap_nocache(CONN_RF_SPI_BASE, 0x100); + if (!conn_rf_spi_base) { + WMT_PLAT_PR_INFO("ioumap 0x180c6000 fail"); + return 0; + } + + if (reg_VCN18) { + regulator_set_voltage(reg_VCN18, 1800000, 1800000); + if (regulator_enable(reg_VCN18)) + WMT_PLAT_PR_INFO("enable VCN18 fail\n"); + else + WMT_PLAT_PR_DBG("enable VCN18 ok\n"); + } + udelay(300); + if ((reg_VCN13) && (adie == PRIMARY_ADIE)) { + regulator_set_voltage(reg_VCN13, 1300000, 1300000); + if (regulator_enable(reg_VCN13)) + WMT_PLAT_PR_INFO("enable VCN13 fail\n"); + else + WMT_PLAT_PR_DBG("enable VCN13 ok\n"); + } + consys_set_if_pinmux(ENABLE); + udelay(150); + consys_hw_reset_bit_set(ENABLE); + consys_hw_spm_clk_gating_enable(); + consys_hw_power_ctrl(ENABLE); + udelay(10); + polling_consys_chipid(); + + CONSYS_REG_WRITE(conn_reg.mcu_top_misc_on_base + CONN_ON_ADIE_CTL_OFFSET, + CONSYS_REG_READ(conn_reg.mcu_top_misc_on_base + CONN_ON_ADIE_CTL_OFFSET) + | 0x1); + + while (retry-- > 0) { + if ((CONSYS_REG_READ(conn_rf_spi_base) & 0x1) == 0) + break; + udelay(500); + } + + if (adie == PRIMARY_ADIE) + CONSYS_REG_WRITE(conn_rf_spi_base + SPI_TOP_ADDR, 0x0000b02C); + else if (adie == SECONDARY_ADIE) + CONSYS_REG_WRITE(conn_rf_spi_base + SPI_TOP_ADDR, 0x0000b024); + CONSYS_REG_WRITE(conn_rf_spi_base + SPI_TOP_WDAT, 0); + + retry = 10; + while (retry-- > 0) { + if ((CONSYS_REG_READ(conn_rf_spi_base) & 0x20) == 0) + break; + udelay(500); + } + + chipid = CONSYS_REG_READ(conn_rf_spi_base + SPI_TOP_RDAT) >> 16; + + CONSYS_REG_WRITE(conn_reg.mcu_top_misc_on_base + CONN_ON_ADIE_CTL_OFFSET, + CONSYS_REG_READ(conn_reg.mcu_top_misc_on_base + CONN_ON_ADIE_CTL_OFFSET) + & 0x0); + + iounmap(conn_rf_spi_base); + + consys_hw_power_ctrl(DISABLE); + consys_set_if_pinmux(DISABLE); + if ((reg_VCN13) && (adie == PRIMARY_ADIE)) { + if (regulator_disable(reg_VCN13)) + WMT_PLAT_PR_INFO("disable VCN13 fail!\n"); + } + udelay(300); + if (reg_VCN18) { + if (regulator_disable(reg_VCN18)) + WMT_PLAT_PR_INFO("disable VCN18 fail!\n"); + } + + if ((reg_VCN13) && (chipid == SECONDARY_ADIE)) { + /* release VCN13 resource if never used to prevent customerized issue */ + regulator_put(reg_VCN13); + reg_VCN13 = NULL; + } + + return chipid; +} + +static INT32 consys_adie_chipid_detect(VOID) +{ + INT32 chipid = -1; + UINT32 retry = 3; + + while ((retry-- > 0) && (chipid == -1)) { + if (consys_adie_chipid_checking_flow(PRIMARY_ADIE) == PRIMARY_ADIE) + chipid = PRIMARY_ADIE; + else if (consys_adie_chipid_checking_flow(SECONDARY_ADIE) == SECONDARY_ADIE) + chipid = SECONDARY_ADIE; + } + WMT_PLAT_PR_INFO("A-die chip id = %x\n", chipid); + + return chipid; +} + +static P_CONSYS_EMI_ADDR_INFO consys_soc_get_emi_phy_add(VOID) +{ + return &mtk_wcn_emi_addr_info; +} + +P_WMT_CONSYS_IC_OPS mtk_wcn_get_consys_ic_ops(VOID) +{ + return &consys_ic_ops; +} + +static INT32 consys_dl_rom_patch(UINT32 ip_ver, UINT32 fw_ver) +{ + if (rom_patch_dl_flag) { + if (mtk_wcn_soc_rom_patch_dwn(ip_ver, fw_ver) == 0) + rom_patch_dl_flag = 1; + else + return -1; + } + + return 0; +} + +static VOID consys_set_dl_rom_patch_flag(INT32 flag) +{ + rom_patch_dl_flag = flag; +} + +static INT32 consys_dedicated_log_path_init(struct platform_device *pdev) +{ + struct device_node *node; + UINT32 irq_num; + UINT32 irq_flag; + INT32 iret = -1; + struct connlog_irq_config irq_config; + + memset(&irq_config, 0, sizeof(struct connlog_irq_config)); + node = pdev->dev.of_node; + if (node) { + irq_num = irq_of_parse_and_map(node, 2); + irq_flag = irq_get_trigger_type(irq_num); + WMT_PLAT_PR_INFO("get conn2ap_sw_irq id(%d) and irq trigger flag(%d) from DT\n", + irq_num, irq_flag); + } else { + WMT_PLAT_PR_ERR("[%s] can't find CONSYS compatible node\n", __func__); + return iret; + } + + irq_config.irq_num = irq_num; + irq_config.irq_flag = irq_flag; + irq_config.irq_callback = NULL; + + connsys_dedicated_log_path_apsoc_init( + gConEmiPhyBase, &connsys_fw_log_parameter, &irq_config); +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH + fw_log_wmt_init(); +#endif + return 0; +} + +static VOID consys_dedicated_log_path_deinit(VOID) +{ +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH + fw_log_wmt_deinit(); +#endif + connsys_dedicated_log_path_apsoc_deinit(); +} + +static INT32 consys_emi_coredump_remapping(UINT8 __iomem **addr, UINT32 enable) +{ + if (enable) { + *addr = ioremap_nocache(gConEmiPhyBase + CONSYS_EMI_COREDUMP_OFFSET, + CONSYS_EMI_COREDUMP_MEM_SIZE); + if (*addr) { + WMT_PLAT_PR_INFO("COREDUMP EMI mapping OK virtual(0x%p) physical(0x%x)\n", + *addr, (UINT32) gConEmiPhyBase + + CONSYS_EMI_COREDUMP_OFFSET); + memset_io(*addr, 0, CONSYS_EMI_COREDUMP_MEM_SIZE); + } else { + WMT_PLAT_PR_ERR("EMI mapping fail\n"); + return -1; + } + } else { + if (*addr) { + iounmap(*addr); + *addr = NULL; + } + } + return 0; +} + +static INT32 consys_reset_emi_coredump(UINT8 __iomem *addr) +{ + if (!addr) { + WMT_PLAT_PR_ERR("get virtual address fail\n"); + return -1; + } + WMT_PLAT_PR_INFO("Reset EMI(0xF0068000 ~ 0xF0107FFF)\n"); + memset_io(addr, 0, CONSYS_EMI_COREDUMP_MEM_SIZE); + return 0; +} + +static INT32 consys_check_reg_readable(VOID) +{ + INT32 can_read = 0; + UINT32 value = 0; + + if (conn_reg.mcu_cfg_on_base != 0 && + conn_reg.mcu_top_misc_on_base != 0) { + /*check connsys clock and sleep status*/ + CONSYS_REG_WRITE(conn_reg.mcu_conn_hif_on_base, CONSYS_CLOCK_CHECK_VALUE); + udelay(1000); + value = CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base); + if ((value & CONSYS_HCLK_CHECK_BIT) && + (value & CONSYS_OSCCLK_CHECK_BIT)) + can_read = 1; + } + + if (!can_read) + WMT_PLAT_PR_ERR("connsys clock check fail 0x18007000(0x%x)\n", value); + + return can_read; +} + +static VOID consys_ic_clock_fail_dump(VOID) +{ + UINT8 *addr; + char *buffer, *temp; + INT32 size = 1024; + + /* make sure buffer size is big enough */ + buffer = osal_malloc(size); + if (!buffer) + return; + + temp = buffer; + temp += sprintf(temp, "CONN_HIF_TOP_MISC=0x%08x CONN_HIF_BUSY_STATUS=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HIF_TOP_MISC), + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HIF_BUSY_STATUS)); + + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_HIF_DBG_IDX, 0x3333); + temp += sprintf(temp, "Write CONSYS_HIF_DBG_IDX to 0x3333\n"); + + temp += sprintf(temp, "CONSYS_HIF_DBG_PROBE=0x%08x CONN_HIF_TOP_MISC=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HIF_DBG_PROBE), + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HIF_TOP_MISC)); + + temp += sprintf(temp, "CONN_HIF_BUSY_STATUS=0x%08x CONN_HIF_PDMA_BUSY_STATUS=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HIF_BUSY_STATUS), + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HIF_PDMA_BUSY_STATUS)); + + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_HIF_DBG_IDX, 0x2222); + temp += sprintf(temp, "Write CONSYS_HIF_DBG_IDX to 0x2222\n"); + + temp += sprintf(temp, "CONSYS_HIF_DBG_PROBE=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HIF_DBG_PROBE)); + + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_HIF_DBG_IDX, 0x3333); + temp += sprintf(temp, "Write CONSYS_HIF_DBG_IDX to 0x3333\n"); + + temp += sprintf(temp, "CONSYS_HIF_DBG_PROBE=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HIF_DBG_PROBE)); + + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_HIF_DBG_IDX, 0x4444); + temp += sprintf(temp, "Write CONSYS_HIF_DBG_IDX to 0x4444\n"); + + temp += sprintf(temp, "CONSYS_HIF_DBG_PROBE=0x%08x CONN_MCU_EMI_CONTROL=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HIF_DBG_PROBE), + CONSYS_REG_READ(conn_reg.mcu_base + CONN_MCU_EMI_CONTROL)); + temp += sprintf(temp, "EMI_CONTROL_DBG_PROBE=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + EMI_CONTROL_DBG_PROBE)); + temp += sprintf(temp, "CONN_MCU_CLOCK_CONTROL=0x%08x CONN_MCU_BUS_CONTROL=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_CLOCK_CONTROL), + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_BUS_CONTROL)); + + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_DEBUG_SELECT, 0x003e3d00); + temp += sprintf(temp, "Write CONSYS_DEBUG_SELECT to 0x003e3d00\n"); + + temp += sprintf(temp, "CONN_MCU_DEBUG_STATUS=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_DEBUG_STATUS)); + + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_DEBUG_SELECT, 0x00403f00); + temp += sprintf(temp, "Write CONSYS_DEBUG_SELECT to 0x00403f00\n"); + + temp += sprintf(temp, "CONN_MCU_DEBUG_STATUS=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_DEBUG_STATUS)); + + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_DEBUG_SELECT, 0x00424100); + temp += sprintf(temp, "Write CONSYS_DEBUG_SELECT to 0x00424100\n"); + + temp += sprintf(temp, "CONN_MCU_DEBUG_STATUS=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_DEBUG_STATUS)); + + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_DEBUG_SELECT, 0x00444300); + temp += sprintf(temp, "Write CONSYS_DEBUG_SELECT to 0x00444300\n"); + + temp += sprintf(temp, "CONN_MCU_DEBUG_STATUS=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_DEBUG_STATUS)); + WMT_PLAT_PR_ERR("%s length = %d", buffer, osal_strlen(buffer)); + + temp = buffer; + addr = ioremap_nocache(0x180bc000, 0x100); + /* conn2ap axi master sleep prot info */ + temp += sprintf(temp, "0x180bc010=0x%08x\n", CONSYS_REG_READ(addr + 0x10)); + /* conn_mcu2ap axi master sleep prot info */ + temp += sprintf(temp, "0x180bc014=0x%08x\n", CONSYS_REG_READ(addr + 0x14)); + /* conn2ap axi gals bus info */ + temp += sprintf(temp, "0x180bc018=0x%08x\n", CONSYS_REG_READ(addr + 0x18)); + /* conn2ap mux4to1 debug info */ + temp += sprintf(temp, "0x180bc01c=0x%08x\n", CONSYS_REG_READ(addr + 0x1c)); + /* conn_hif_off bus busy info */ + temp += sprintf(temp, "0x180bc020=0x%08x\n", CONSYS_REG_READ(addr + 0x20)); + iounmap(addr); + + addr = ioremap_nocache(0x1800713c, 0x100); + /* conn_hif_on misc info */ + temp += sprintf(temp, "0x1800713c=0x%08x\n", CONSYS_REG_READ(addr)); + iounmap(addr); + + addr = ioremap_nocache(0x180c1144, 0x100); + /* conn_on_host debug flag */ + temp += sprintf(temp, "0x180c1144=0x%08x\n", CONSYS_REG_READ(addr)); + iounmap(addr); + + addr = ioremap_nocache(0x1020E804, 0x100); + /* 0x1020E804 */ + temp += sprintf(temp, "0x1020E804=0x%08x\n", CONSYS_REG_READ(addr)); + iounmap(addr); + + WMT_PLAT_PR_ERR("%s length = %d", buffer, osal_strlen(buffer)); + osal_free(buffer); +} + +static INT32 consys_is_connsys_reg(UINT32 addr) +{ + if (addr > 0x18000000 && addr < 0x180FFFFF) { + if (addr >= 0x18007000 && addr <= 0x18007FFF) + return 0; + + return 1; + } + + return 0; +} + +static INT32 consys_is_host_csr(SIZE_T addr) +{ + SIZE_T start_offset = 0x000; + SIZE_T end_offset = 0xFFF; + + if (addr >= (CONN_HIF_ON_BASE_ADDR + start_offset) && + addr <= (CONN_HIF_ON_BASE_ADDR + end_offset)) + return 1; + + if (conn_reg.mcu_conn_hif_on_base != 0 && + addr >= (conn_reg.mcu_conn_hif_on_base + start_offset) && + addr <= (conn_reg.mcu_conn_hif_on_base + end_offset)) + return 1; + + return 0; +} + +static INT32 consys_dump_osc_state(P_CONSYS_STATE state) +{ +#if 0 + UINT8 __iomem *addr; +#endif + + CONSYS_REG_WRITE(CONN_CFG_ON_CONN_ON_HOST_MAILBOX_MCU_ADDR, 0x1); + CONSYS_REG_WRITE(CONN_CFG_ON_CONN_ON_MON_CTL_ADDR, 0x80000001); + CONSYS_REG_WRITE(CONN_CFG_ON_CONN_ON_MON_SEL0_ADDR, 0x03020100); + CONSYS_REG_WRITE(CONN_CFG_ON_CONN_ON_MON_SEL1_ADDR, 0x07060504); + CONSYS_REG_WRITE(CONN_CFG_ON_CONN_ON_MON_SEL2_ADDR, 0x0b0a0908); + CONSYS_REG_WRITE(CONN_CFG_ON_CONN_ON_MON_SEL3_ADDR, 0x0f0e0d0c); + CONSYS_REG_WRITE(CONN_CFG_ON_CONN_ON_DBGSEL_ADDR, 0x3); + state->lp[0] = (UINT32)CONN_CFG_ON_CONN_ON_MON_FLAG_RECORD_MAPPING_AP_ADDR; + state->lp[1] = CONSYS_REG_READ(CONN_CFG_ON_CONN_ON_MON_FLAG_RECORD_ADDR); + WMT_PLAT_PR_INFO("0x%08x: 0x%x\n", state->lp[0], state->lp[1]); + CONSYS_REG_WRITE(CONN_CFG_ON_CONN_ON_HOST_MAILBOX_MCU_ADDR, 0x0); + +#if 0 + addr = ioremap_nocache(gConEmiPhyBase + 0x66500, sizeof(struct consys_sw_state)); + if (addr) + memcpy_fromio(&state->sw_state, addr, sizeof(struct consys_sw_state)); + else + WMT_PLAT_PR_ERR("ioremap fail\n"); + iounmap(addr); +#endif + return MTK_WCN_BOOL_TRUE; +} + +static VOID consys_set_pdma_axi_rready_force_high(UINT32 enable) +{ + UINT8 *consys_hif_pdma_axi_rready; + + consys_hif_pdma_axi_rready = ioremap_nocache(CONSYS_HIF_PDMA_AXI_RREADY, 0x100); + + if (consys_hif_pdma_axi_rready) { + if (enable) + CONSYS_SET_BIT(consys_hif_pdma_axi_rready, CONSYS_HIF_PDMA_AXI_RREADY_MASK); + else if ((CONSYS_REG_READ(consys_hif_pdma_axi_rready) & + CONSYS_HIF_PDMA_AXI_RREADY_MASK) != 0) + CONSYS_CLR_BIT(consys_hif_pdma_axi_rready, CONSYS_HIF_PDMA_AXI_RREADY_MASK); + iounmap(consys_hif_pdma_axi_rready); + } +} + +static VOID consys_set_mcif_emi_mpu_protection(MTK_WCN_BOOL enable) +{ + WMT_PLAT_PR_INFO("Setup region 23 for domain 0 as %s\n", enable ? "FORBIDDEN" : "SEC_R_NSEC_R"); +#ifdef CONFIG_MTK_EMI_LEGACY + emi_mpu_set_single_permission(23, 0, enable ? FORBIDDEN : SEC_R_NSEC_R); +#endif +} + +static INT32 consys_calibration_backup_restore_support(VOID) +{ + return 1; +} + +static INT32 consys_is_ant_swap_enable_by_hwid(INT32 pin_num) +{ + return !gpio_get_value(pin_num); +} + +#if (COMMON_KERNEL_CLK_SUPPORT) +static MTK_WCN_BOOL consys_need_store_pdev(VOID) +{ + return MTK_WCN_BOOL_TRUE; +} + +static UINT32 consys_store_pdev(struct platform_device *pdev) +{ + connsys_pdev = pdev; + return 0; +} +#endif + +static UINT64 consys_get_options(VOID) +{ + UINT64 options = OPT_WIFI_LTE_COEX | + OPT_BT_TSSI_FROM_WIFI_CONFIG_NEW_OPID | + OPT_COEX_CONFIG_ADJUST | + OPT_COEX_CONFIG_ADJUST_NEW_FLAG | + OPT_WIFI_LTE_COEX_TABLE_3 | + OPT_NORMAL_PATCH_DWN_3 | + OPT_PATCH_CHECKSUM; + return options; +} diff --git a/drivers/misc/mediatek/connectivity/common/common_main/platform/mt6785.c b/drivers/misc/mediatek/connectivity/common/common_main/platform/mt6785.c new file mode 100644 index 0000000000000000000000000000000000000000..b640f73ec57c01fa07731da6b18542a41cc141f9 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/platform/mt6785.c @@ -0,0 +1,1585 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +#ifdef DFT_TAG +#undef DFT_TAG +#endif +#define DFT_TAG "[WMT-CONSYS-HW]" + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include +#include +#include +#include +#include +#include "connsys_debug_utility.h" +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH +#include "fw_log_wmt.h" +#endif +#include "osal_typedef.h" +#include "mt6785.h" +#include "mtk_wcn_consys_hw.h" +#include "wmt_ic.h" +#include "wmt_lib.h" +#include "wmt_plat.h" +#include "stp_dbg.h" + +#ifdef CONFIG_MTK_EMI +#include +#endif + +#if CONSYS_PMIC_CTRL_ENABLE +#include +#include +#include +#endif + +#ifdef CONFIG_MTK_HIBERNATION +#include +#endif + +#include + +#include + +/* Direct path */ +#include +#if WMT_DEVAPC_DBG_SUPPORT +#include +#endif +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +static INT32 consys_clock_buffer_ctrl(MTK_WCN_BOOL enable); +static VOID consys_hw_reset_bit_set(MTK_WCN_BOOL enable); +static VOID consys_hw_spm_clk_gating_enable(VOID); +static INT32 consys_hw_power_ctrl(MTK_WCN_BOOL enable); +static INT32 consys_ahb_clock_ctrl(MTK_WCN_BOOL enable); +static INT32 polling_consys_chipid(VOID); +static VOID consys_acr_reg_setting(VOID); +static VOID consys_afe_reg_setting(VOID); +static INT32 consys_hw_vcn18_ctrl(MTK_WCN_BOOL enable); +static VOID consys_vcn28_hw_mode_ctrl(UINT32 enable); +static INT32 consys_hw_vcn28_ctrl(UINT32 enable); +static INT32 consys_hw_wifi_vcn33_ctrl(UINT32 enable); +static INT32 consys_hw_bt_vcn33_ctrl(UINT32 enable); +static UINT32 consys_soc_chipid_get(VOID); +static INT32 consys_emi_mpu_set_region_protection(VOID); +static UINT32 consys_emi_set_remapping_reg(VOID); +static INT32 bt_wifi_share_v33_spin_lock_init(VOID); +static INT32 consys_clk_get_from_dts(struct platform_device *pdev); +static INT32 consys_pmic_get_from_dts(struct platform_device *pdev); +static INT32 consys_read_irq_info_from_dts(struct platform_device *pdev, + PINT32 irq_num, PUINT32 irq_flag); +static INT32 consys_read_reg_from_dts(struct platform_device *pdev); +static UINT32 consys_read_cpupcr(VOID); +static VOID force_trigger_assert_debug_pin(VOID); +static INT32 consys_co_clock_type(VOID); +static P_CONSYS_EMI_ADDR_INFO consys_soc_get_emi_phy_add(VOID); +static VOID consys_set_if_pinmux(MTK_WCN_BOOL enable); +static INT32 consys_dl_rom_patch(UINT32 ip_ver, UINT32 fw_ver); +static VOID consys_set_dl_rom_patch_flag(INT32 flag); +static INT32 consys_dedicated_log_path_init(struct platform_device *pdev); +static VOID consys_dedicated_log_path_deinit(VOID); +static INT32 consys_check_reg_readable(VOID); +static INT32 consys_emi_coredump_remapping(UINT8 __iomem **addr, UINT32 enable); +static INT32 consys_reset_emi_coredump(UINT8 __iomem *addr); +static VOID consys_ic_clock_fail_dump(VOID); +static INT32 consys_is_connsys_reg(UINT32 addr); +static INT32 consys_is_host_csr(SIZE_T addr); +static INT32 consys_dump_osc_state(P_CONSYS_STATE state); +static VOID consys_set_pdma_axi_rready_force_high(UINT32 enable); +static VOID consys_set_mcif_emi_mpu_protection(MTK_WCN_BOOL enable); +/* + * If 1: this platform supports calibration backup/restore. + * otherwise: 0 + */ +static INT32 consys_calibration_backup_restore_support(VOID); +#if WMT_DEVAPC_DBG_SUPPORT +static VOID consys_devapc_violation_cb(VOID); +#endif +static VOID consyc_register_devapc_cb(VOID); +static UINT64 consys_get_options(VOID); + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ +/* CCF part */ +struct clk *clk_scp_conn_main; /*ctrl conn_power_on/off */ +struct clk *clk_infracfg_ao_ccif4_ap_cg; /* For direct path */ + +/* PMIC part */ +#if CONSYS_PMIC_CTRL_ENABLE +struct regulator *reg_VCN18; +struct regulator *reg_VCN33_1; +struct regulator *reg_VCN33_2; +#endif + +EMI_CTRL_STATE_OFFSET mtk_wcn_emi_state_off = { + .emi_apmem_ctrl_state = EXP_APMEM_CTRL_STATE, + .emi_apmem_ctrl_host_sync_state = EXP_APMEM_CTRL_HOST_SYNC_STATE, + .emi_apmem_ctrl_host_sync_num = EXP_APMEM_CTRL_HOST_SYNC_NUM, + .emi_apmem_ctrl_chip_sync_state = EXP_APMEM_CTRL_CHIP_SYNC_STATE, + .emi_apmem_ctrl_chip_sync_num = EXP_APMEM_CTRL_CHIP_SYNC_NUM, + .emi_apmem_ctrl_chip_sync_addr = EXP_APMEM_CTRL_CHIP_SYNC_ADDR, + .emi_apmem_ctrl_chip_sync_len = EXP_APMEM_CTRL_CHIP_SYNC_LEN, + .emi_apmem_ctrl_chip_print_buff_start = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_START, + .emi_apmem_ctrl_chip_print_buff_len = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_LEN, + .emi_apmem_ctrl_chip_print_buff_idx = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_IDX, + .emi_apmem_ctrl_chip_int_status = EXP_APMEM_CTRL_CHIP_INT_STATUS, + .emi_apmem_ctrl_chip_paded_dump_end = EXP_APMEM_CTRL_CHIP_PAGED_DUMP_END, + .emi_apmem_ctrl_host_outband_assert_w1 = EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1, + .emi_apmem_ctrl_chip_page_dump_num = EXP_APMEM_CTRL_CHIP_PAGE_DUMP_NUM, + .emi_apmem_ctrl_assert_flag = EXP_APMEM_CTRL_ASSERT_FLAG, +}; + +CONSYS_EMI_ADDR_INFO mtk_wcn_emi_addr_info = { + .emi_phy_addr = CONSYS_EMI_FW_PHY_BASE, + .paged_trace_off = CONSYS_EMI_PAGED_TRACE_OFFSET, + .paged_dump_off = CONSYS_EMI_PAGED_DUMP_OFFSET, + .full_dump_off = CONSYS_EMI_FULL_DUMP_OFFSET, + .emi_remap_offset = CONSYS_EMI_MAPPING_OFFSET, + .p_ecso = &mtk_wcn_emi_state_off, + .emi_core_dump_offset = CONSYS_EMI_COREDUMP_OFFSET, + .pda_dl_patch_flag = 1, + .emi_met_size = (32*KBYTE), + .emi_met_data_offset = CONSYS_EMI_MET_DATA_OFFSET, +}; + +WMT_CONSYS_IC_OPS consys_ic_ops = { + .consys_ic_clock_buffer_ctrl = consys_clock_buffer_ctrl, + .consys_ic_hw_reset_bit_set = consys_hw_reset_bit_set, + .consys_ic_hw_spm_clk_gating_enable = consys_hw_spm_clk_gating_enable, + .consys_ic_hw_power_ctrl = consys_hw_power_ctrl, + .consys_ic_ahb_clock_ctrl = consys_ahb_clock_ctrl, + .polling_consys_ic_chipid = polling_consys_chipid, + .consys_ic_acr_reg_setting = consys_acr_reg_setting, + .consys_ic_afe_reg_setting = consys_afe_reg_setting, + .consys_ic_hw_vcn18_ctrl = consys_hw_vcn18_ctrl, + .consys_ic_vcn28_hw_mode_ctrl = consys_vcn28_hw_mode_ctrl, + .consys_ic_hw_vcn28_ctrl = consys_hw_vcn28_ctrl, + .consys_ic_hw_wifi_vcn33_ctrl = consys_hw_wifi_vcn33_ctrl, + .consys_ic_hw_bt_vcn33_ctrl = consys_hw_bt_vcn33_ctrl, + .consys_ic_soc_chipid_get = consys_soc_chipid_get, + .consys_ic_emi_mpu_set_region_protection = consys_emi_mpu_set_region_protection, + .consys_ic_emi_set_remapping_reg = consys_emi_set_remapping_reg, + .ic_bt_wifi_share_v33_spin_lock_init = bt_wifi_share_v33_spin_lock_init, + .consys_ic_clk_get_from_dts = consys_clk_get_from_dts, + .consys_ic_pmic_get_from_dts = consys_pmic_get_from_dts, + .consys_ic_read_irq_info_from_dts = consys_read_irq_info_from_dts, + .consys_ic_read_reg_from_dts = consys_read_reg_from_dts, + .consys_ic_read_cpupcr = consys_read_cpupcr, + .ic_force_trigger_assert_debug_pin = force_trigger_assert_debug_pin, + .consys_ic_co_clock_type = consys_co_clock_type, + .consys_ic_soc_get_emi_phy_add = consys_soc_get_emi_phy_add, + .consys_ic_set_if_pinmux = consys_set_if_pinmux, + .consys_ic_set_dl_rom_patch_flag = consys_set_dl_rom_patch_flag, + .consys_ic_dedicated_log_path_init = consys_dedicated_log_path_init, + .consys_ic_dedicated_log_path_deinit = consys_dedicated_log_path_deinit, + .consys_ic_check_reg_readable = consys_check_reg_readable, + .consys_ic_emi_coredump_remapping = consys_emi_coredump_remapping, + .consys_ic_reset_emi_coredump = consys_reset_emi_coredump, + .consys_ic_clock_fail_dump = consys_ic_clock_fail_dump, + .consys_ic_is_connsys_reg = consys_is_connsys_reg, + .consys_ic_is_host_csr = consys_is_host_csr, + .consys_ic_dump_osc_state = consys_dump_osc_state, + .consys_ic_set_pdma_axi_rready_force_high = consys_set_pdma_axi_rready_force_high, + .consys_ic_set_mcif_emi_mpu_protection = consys_set_mcif_emi_mpu_protection, + .consys_ic_calibration_backup_restore = consys_calibration_backup_restore_support, + .consys_ic_register_devapc_cb = consyc_register_devapc_cb, + .consys_ic_get_options = consys_get_options, +}; + +static const struct connlog_emi_config connsys_fw_log_parameter = { + .emi_offset = 0x36500, + .emi_size_total = (192*1024),/* 192KB */ + .emi_size_mcu = (16*1024), + .emi_size_wifi = (64*1024), + .emi_size_bt = (64*1024), + .emi_size_gps = (32*1024), +}; + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +INT32 rom_patch_dl_flag = 1; +UINT32 gJtagCtrl; +UINT32 g_connsys_lp_dump_info[2]; + +#if WMT_DEVAPC_DBG_SUPPORT +static struct devapc_vio_callbacks devapc_handle = { + .id = INFRA_SUBSYS_CONN, + .debug_dump = consys_devapc_violation_cb, +}; +#endif + +#if CONSYS_ENALBE_SET_JTAG +#define JTAG_ADDR1_BASE 0x10005000 +#define JTAG_ADDR2_BASE 0x11F20000 +#define AP2CONN_JTAG_2WIRE_OFFSET 0xF00 +#endif + +INT32 mtk_wcn_consys_jtag_set_for_mcu(VOID) +{ + INT32 ret = 0; +#if CONSYS_ENALBE_SET_JTAG + UINT32 tmp = 0; + PVOID addr = 0; + PVOID remap_addr1 = 0; + PVOID remap_addr2 = 0; + + if (gJtagCtrl) { + WMT_PLAT_PR_INFO("WCN jtag set for mcu start...\n"); + + switch (gJtagCtrl) { + case 1: + remap_addr1 = ioremap(JTAG_ADDR1_BASE, 0x1000); + if (remap_addr1 == 0) { + WMT_PLAT_PR_ERR("remap jtag_addr1 fail!\n"); + ret = -1; + goto error; + } + + remap_addr2 = ioremap(JTAG_ADDR2_BASE, 0x100); + if (remap_addr2 == 0) { + WMT_PLAT_PR_ERR("remap jtag_addr2 fail!\n"); + ret = -1; + goto error; + } + + /* 7-wire jtag pinmux setting*/ + /* PAD AUX Function Selection */ + addr = remap_addr1 + 0x310; + tmp = readl(addr); + tmp = tmp & 0xffffff00; + tmp = tmp | 0x66; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + addr = remap_addr1 + 0x330; + tmp = readl(addr); + tmp = tmp & 0x00ffffff; + tmp = tmp | 0x66000000; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + addr = remap_addr1 + 0x340; + tmp = readl(addr); + tmp = tmp & 0xfffff000; + tmp = tmp | 0x666; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + /* PAD Driving Selection */ + addr = remap_addr2; + tmp = readl(addr); + tmp = tmp & 0xfffc01ff; + tmp = tmp | 0x3fe00; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + /* PAD PULL Selection */ + addr = remap_addr2 + 0x40; + tmp = readl(addr); + tmp = tmp & 0xfffc07ff; + tmp = tmp | 0x3f800; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + break; + case 2: + remap_addr1 = ioremap(JTAG_ADDR1_BASE, 0x1000); + if (remap_addr1 == 0) { + WMT_PLAT_PR_ERR("remap jtag_addr1 fail!\n"); + ret = -1; + goto error; + } + + remap_addr2 = ioremap(0x11C20000, 0x100); + if (remap_addr2 == 0) { + WMT_PLAT_PR_ERR("remap jtag_addr2 fail!\n"); + ret = -1; + goto error; + } + + /* 2-wire jtag pinmux setting*/ + addr = remap_addr1 + 0x3F0; + tmp = readl(addr); + tmp = tmp & 0x0fffffff; + tmp = tmp | 0x60000000; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + addr = remap_addr1 + 0x400; + tmp = readl(addr); + tmp = tmp & 0xfffffff0; + tmp = tmp | 0x6; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + /* Driving Selection */ + + addr = remap_addr2; + tmp = readl(addr); + tmp = tmp & 0xfffff1ff; + tmp = tmp | 0x600; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + /* PULL Selection */ + addr = remap_addr2 + 0x30; + tmp = readl(addr); + tmp = tmp & 0xffffff3f; + tmp = tmp | 0xc0; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + break; + default: + WMT_PLAT_PR_INFO("unsupported options!\n"); + } + + } + +error: + if (remap_addr1) + iounmap(remap_addr1); + if (remap_addr2) + iounmap(remap_addr2); +#endif + return ret; +} + +UINT32 mtk_wcn_consys_jtag_flag_ctrl(UINT32 en) +{ + WMT_PLAT_PR_INFO("%s jtag set for MCU\n", en ? "enable" : "disable"); + gJtagCtrl = en; + return 0; +} + +static INT32 consys_clk_get_from_dts(struct platform_device *pdev) +{ + clk_scp_conn_main = devm_clk_get(&pdev->dev, "conn"); + if (IS_ERR(clk_scp_conn_main)) { + WMT_PLAT_PR_ERR("[CCF]cannot get clk_scp_conn_main clock.\n"); + return PTR_ERR(clk_scp_conn_main); + } + WMT_PLAT_PR_DBG("[CCF]clk_scp_conn_main=%p\n", clk_scp_conn_main); + + clk_infracfg_ao_ccif4_ap_cg = devm_clk_get(&pdev->dev, "ccif"); + if (IS_ERR(clk_infracfg_ao_ccif4_ap_cg)) { + WMT_PLAT_PR_ERR("[CCF]cannot get clk_infracfg_ao_ccif4_ap_cg clock.\n"); + return PTR_ERR(clk_infracfg_ao_ccif4_ap_cg); + } + WMT_PLAT_PR_DBG("[CCF]clk_infracfg_ao_ccif4_ap_cg=%p\n", clk_infracfg_ao_ccif4_ap_cg); + + return 0; +} + +static INT32 consys_pmic_get_from_dts(struct platform_device *pdev) +{ +#if CONSYS_PMIC_CTRL_ENABLE + reg_VCN18 = regulator_get(&pdev->dev, "vcn18"); + if (!reg_VCN18) + WMT_PLAT_PR_ERR("Regulator_get VCN_1V8 fail\n"); + reg_VCN33_1 = regulator_get(&pdev->dev, "vcn33_1_wifi"); + if (!reg_VCN33_1) + WMT_PLAT_PR_ERR("Regulator_get VCN33_1 fail\n"); + reg_VCN33_2 = regulator_get(&pdev->dev, "vcn33_2_wifi"); + if (!reg_VCN33_2) + WMT_PLAT_PR_ERR("Regulator_get VCN33_2 fail\n"); +#endif + return 0; +} + +static INT32 consys_co_clock_type(VOID) +{ + return 0; +} + +static INT32 consys_clock_buffer_ctrl(MTK_WCN_BOOL enable) +{ + if (enable) + KERNEL_clk_buf_ctrl(CLK_BUF_CONN, true); /*open XO_WCN*/ + else + KERNEL_clk_buf_ctrl(CLK_BUF_CONN, false); /*close XO_WCN*/ + + return 0; +} + +static VOID consys_set_if_pinmux(MTK_WCN_BOOL enable) +{ + UINT8 *consys_if_pinmux_reg_base = NULL; + UINT8 *consys_if_pinmux_driving_base = NULL; + + /* Switch D die pinmux for connecting A die */ + consys_if_pinmux_reg_base = ioremap_nocache(CONSYS_IF_PINMUX_REG_BASE, 0x1000); + if (!consys_if_pinmux_reg_base) { + WMT_PLAT_PR_ERR("consys_if_pinmux_reg_base(%x) ioremap fail\n", + CONSYS_IF_PINMUX_REG_BASE); + return; + } + + consys_if_pinmux_driving_base = ioremap_nocache(CONSYS_IF_PINMUX_DRIVING_BASE, 0x100); + if (!consys_if_pinmux_driving_base) { + WMT_PLAT_PR_ERR("consys_if_pinmux_driving_base(%x) ioremap fail\n", + CONSYS_IF_PINMUX_DRIVING_BASE); + if (consys_if_pinmux_reg_base) + iounmap(consys_if_pinmux_reg_base); + return; + } + + if (enable) { + CONSYS_REG_WRITE(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_01_OFFSET, + (CONSYS_REG_READ(consys_if_pinmux_reg_base + + CONSYS_IF_PINMUX_01_OFFSET) & + CONSYS_IF_PINMUX_01_MASK) | CONSYS_IF_PINMUX_01_VALUE); + CONSYS_REG_WRITE(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_02_OFFSET, + (CONSYS_REG_READ(consys_if_pinmux_reg_base + + CONSYS_IF_PINMUX_02_OFFSET) & + CONSYS_IF_PINMUX_02_MASK) | CONSYS_IF_PINMUX_02_VALUE); + /* set pinmux driving to 2mA */ + CONSYS_REG_WRITE(consys_if_pinmux_driving_base + CONSYS_IF_PINMUX_DRIVING_OFFSET, + (CONSYS_REG_READ(consys_if_pinmux_driving_base + + CONSYS_IF_PINMUX_DRIVING_OFFSET) & + CONSYS_IF_PINMUX_DRIVING_MASK) | CONSYS_IF_PINMUX_DRIVING_VALUE); + } else { + CONSYS_REG_WRITE(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_01_OFFSET, + CONSYS_REG_READ(consys_if_pinmux_reg_base + + CONSYS_IF_PINMUX_01_OFFSET) & CONSYS_IF_PINMUX_01_MASK); + CONSYS_REG_WRITE(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_02_OFFSET, + CONSYS_REG_READ(consys_if_pinmux_reg_base + + CONSYS_IF_PINMUX_02_OFFSET) & CONSYS_IF_PINMUX_02_MASK); + } + + if (consys_if_pinmux_reg_base) + iounmap(consys_if_pinmux_reg_base); + if (consys_if_pinmux_driving_base) + iounmap(consys_if_pinmux_driving_base); +} + +static VOID consys_hw_reset_bit_set(MTK_WCN_BOOL enable) +{ + UINT32 consys_ver_id = 0; + UINT32 cnt = 0; + + if ((conn_reg.ap_rgu_base == 0) || (conn_reg.mcu_base == 0) || + (conn_reg.mcu_conn_hif_on_base == 0)) + return; + + if (enable) { + /*3.assert CONNSYS CPU SW reset 0x10007018 "[12]=1'b1 [31:24]=8'h88 (key)" */ + CONSYS_REG_WRITE((conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET), + CONSYS_REG_READ(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET) | + CONSYS_CPU_SW_RST_BIT | CONSYS_CPU_SW_RST_CTRL_KEY); + } else { + /*16.deassert CONNSYS CPU SW reset 0x10007018 "[12]=1'b0 [31:24] =8'h88 (key)" */ + CONSYS_REG_WRITE(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET, + (CONSYS_REG_READ(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET) & + ~CONSYS_CPU_SW_RST_BIT) | CONSYS_CPU_SW_RST_CTRL_KEY); + + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_base + 0x600); + while (consys_ver_id != 0x1D1E) { + if (cnt > 10) + break; + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_base + 0x600); + WMT_PLAT_PR_INFO("0x18002600(0x%x)\n", consys_ver_id); + WMT_PLAT_PR_INFO("0x1800216c(0x%x)\n", + CONSYS_REG_READ(conn_reg.mcu_base + 0x16c)); + WMT_PLAT_PR_INFO("0x18007104(0x%x)\n", + CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + + CONSYS_CPUPCR_OFFSET)); + msleep(20); + cnt++; + } + } +} + +static VOID consys_hw_spm_clk_gating_enable(VOID) +{ +} + +static INT32 consys_hw_power_ctrl(MTK_WCN_BOOL enable) +{ +#if CONSYS_PWR_ON_OFF_API_AVAILABLE + INT32 iRet = 0; +#else + INT32 value = 0; + INT32 i = 0; +#endif + + if (enable) { +#if CONSYS_PWR_ON_OFF_API_AVAILABLE + iRet = clk_prepare_enable(clk_infracfg_ao_ccif4_ap_cg); + if (iRet) { + WMT_PLAT_PR_ERR("clk_prepare_enable(clk_infracfg_ao_ccif4_ap_cg) fail(%d)\n", iRet); + return iRet; + } + WMT_PLAT_PR_DBG("clk_prepare_enable(clk_infracfg_ao_ccif4_ap_cg) ok\n"); + + iRet = clk_prepare_enable(clk_scp_conn_main); + if (iRet) { + WMT_PLAT_PR_ERR("clk_prepare_enable(clk_scp_conn_main) fail(%d)\n", iRet); + return iRet; + } + WMT_PLAT_PR_DBG("clk_prepare_enable(clk_scp_conn_main) ok\n"); + + if (conn_reg.infra_ao_pericfg_base != 0) { + WMT_PLAT_PR_DBG("CON_STA_REG = %x\n", + CONSYS_REG_READ( + conn_reg.infra_ao_pericfg_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG)); + + /* Set CON_PWR_ON bit (CON_STA_REG[0]) */ + CONSYS_REG_WRITE_RANGE((conn_reg.infra_ao_pericfg_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG), + 1, 1, 0); + + WMT_PLAT_PR_DBG("CON_STA_REG = %x\n", + CONSYS_REG_READ( + conn_reg.infra_ao_pericfg_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG)); + } +#else + /* turn on SPM clock gating enable PWRON_CONFG_EN 0x10006000 32'h0b160001 */ + CONSYS_REG_WRITE((conn_reg.spm_base + CONSYS_PWRON_CONFG_EN_OFFSET), + (CONSYS_REG_READ(conn_reg.spm_base + + CONSYS_PWRON_CONFG_EN_OFFSET) & + 0x0000FFFF) | CONSYS_PWRON_CONFG_EN_VALUE); + + /*write assert "conn_top_on" primary part power on, + *set "connsys_on_domain_pwr_on"=1 + */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_SPM_PWR_ON_BIT); + /*read check "conn_top_on" primary part power status, + *check "connsys_on_domain_pwr_ack"=1 + */ + value = CONSYS_PWR_ON_ACK_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_OFFSET); + while (value == 0) + value = CONSYS_PWR_ON_ACK_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_OFFSET); + /*write assert "conn_top_on" secondary part power on, + *set "connsys_on_domain_pwr_on_s"=1 + */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_SPM_PWR_ON_S_BIT); + /*read check "conn_top_on" secondary part power status, + *check "connsys_on_domain_pwr_ack_s"=1 + */ + value = CONSYS_PWR_ON_ACK_S_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_S_OFFSET); + while (value == 0) + value = CONSYS_PWR_ON_ACK_S_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_S_OFFSET); + /*write turn on AP-to-CONNSYS bus clock, set "conn_clk_dis"=0 (apply this for bus + *clock toggling) + */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) & + ~CONSYS_CLK_CTRL_BIT); + /*wait 1us*/ + udelay(1); + /*de-assert "conn_top_on" isolation, set "connsys_iso_en"=0 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) & + ~CONSYS_SPM_PWR_ISO_S_BIT); + + /*de-assert CONNSYS S/W reset (TOP RGU CR), set "ap_sw_rst_b"=1 */ + CONSYS_REG_WRITE(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET, + (CONSYS_REG_READ(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET) & + ~CONSYS_SW_RST_BIT) | CONSYS_CPU_SW_RST_CTRL_KEY); + + /*de-assert CONNSYS S/W reset (SPM CR), set "ap_sw_rst_b"=1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) & + CONSYS_SPM_PWR_RST_BIT); + + /*wait 0.5ms*/ + udelay(500); + /*Turn off AHB RX bus sleep protect (AP2CONN AHB Bus protect) + *(apply this for INFRA AHB bus accessing when CONNSYS had been turned on) + */ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AHB_RX_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AHB_RX_PROT_EN_OFFSET) & ~CONSYS_AHB_RX_PROT_MASK); + value = ~CONSYS_AHB_RX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AHB_RX_PROT_STA_OFFSET); + i = 0; + while (value == 0 || i > 10) { + value = ~CONSYS_AP2CONN_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AHB_RX_PROT_STA_OFFSET); + i++; + } + + /*Turn off AXI Rx bus sleep protect (CONN2AP AXI Rx Bus protect) + *(disable sleep protection when CONNSYS had been turned on) + */ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AXI_RX_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AXI_RX_PROT_EN_OFFSET) & ~CONSYS_AXI_RX_PROT_MASK); + value = ~CONSYS_AXI_RX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AXI_RX_PROT_STA_OFFSET); + i = 0; + while (value == 0 || i > 10) { + value = ~CONSYS_AXI_RX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AXI_RX_PROT_STA_OFFSET); + i++; + } + + /*Turn off AXI TX bus sleep protect (CONN2AP AXI Tx Bus protect) + *(disable sleep protection when CONNSYS had been turned on) + */ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AXI_RX_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AXI_RX_PROT_EN_OFFSET) & ~CONSYS_AXI_TX_PROT_MASK); + value = ~CONSYS_AXI_TX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AXI_RX_PROT_STA_OFFSET); + i = 0; + while (value == 0 || i > 10) { + value = ~CONSYS_AXI_TX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AXI_RX_PROT_STA_OFFSET); + i++; + } + + /*Turn off AHB TX bus sleep protect (AP2CONN AHB Bus protect) + *(apply this for INFRA AHB bus accessing when CONNSYS had been turned on) + */ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AXI_RX_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AXI_RX_PROT_EN_OFFSET) & ~CONSYS_AHB_TX_PROT_MASK); + value = ~CONSYS_AHB_TX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AXI_RX_PROT_STA_OFFSET); + i = 0; + while (value == 0 || i > 10) { + value = ~CONSYS_AHB_TX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AXI_RX_PROT_STA_OFFSET); + i++; + } + /*wait 5ms*/ + mdelay(5); +#endif /* CONSYS_PWR_ON_OFF_API_AVAILABLE */ + } else { +#if CONSYS_PWR_ON_OFF_API_AVAILABLE + if (conn_reg.infra_ao_pericfg_base != 0) { + WMT_PLAT_PR_DBG("CON_STA_REG = %x\n", + CONSYS_REG_READ( + conn_reg.infra_ao_pericfg_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG)); + + /* Clean CON_STA_REG + * when power off or reset connsys + */ + CONSYS_REG_WRITE((conn_reg.infra_ao_pericfg_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG), 0); + + WMT_PLAT_PR_DBG("CON_STA_REG = %x\n", + CONSYS_REG_READ( + conn_reg.infra_ao_pericfg_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG)); + } + + clk_disable_unprepare(clk_scp_conn_main); + WMT_PLAT_PR_DBG("clk_disable_unprepare(clk_scp_conn_main) calling\n"); + + /* Clean CCIF4 ACK status */ + /* Wait 100us to make sure all ongoing tx interrupt could be + * reset. + * According to profiling result, the time between read + * register and send tx interrupt is less than 20 us. + */ + udelay(100); + if (conn_reg.ap_pccif4_base != 0) { + CONSYS_REG_WRITE((conn_reg.ap_pccif4_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PCCIF_ACK_OFFSET), + 0xFF); + WMT_PLAT_PR_DBG("AP_PCCIF_ACK = %x\n", + CONSYS_REG_READ( + conn_reg.ap_pccif4_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PCCIF_ACK_OFFSET)); + } + + clk_disable_unprepare(clk_infracfg_ao_ccif4_ap_cg); + WMT_PLAT_PR_DBG("clk_disable_unprepare(clk_infracfg_ao_ccif4_ap_cg) calling\n"); + +#else + /* Turn on AHB bus sleep protect (AP2CONN AHB Bus protect) + * (apply this for INFRA AXI bus protection to prevent bus hang + * when CONNSYS had been turned off) + */ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AHBAXI_PROT_EN_OFFSET) & + CONSYS_AP2CONN_PROT_MASK); + value = CONSYS_AP2CONN_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_STA_OFFSET); + i = 0; + while (value == CONSYS_AP2CONN_PROT_MASK || i > 10) { + value = CONSYS_AP2CONN_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AHBAXI_PROT_STA_OFFSET); + i++; + } + /* Turn on AXI Tx bus sleep protect (CONN2AP AXI Tx Bus protect) + * (apply this for INFRA AXI bus protection to prevent bus hang + * when CONNSYS had been turned off) + * Note : Should turn on AXI Tx sleep protection first. + */ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AHBAXI_PROT_EN_OFFSET) & + CONSYS_TX_PROT_MASK); + value = CONSYS_TX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_STA_OFFSET); + i = 0; + while (value == CONSYS_TX_PROT_MASK || i > 10) { + value = CONSYS_TX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AHBAXI_PROT_STA_OFFSET); + i++; + } + /* Turn on AXI Rx bus sleep protect (CONN2AP AXI RX Bus protect) + * (apply this for INFRA AXI bus protection to prevent bus hang + * when CONNSYS had been turned off) + * Note : Should turn on AXI Rx sleep protection + * after AXI Tx sleep protection has been turn on. + */ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AHBAXI_PROT_EN_OFFSET) & + CONSYS_RX_PROT_MASK); + value = CONSYS_RX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_STA_OFFSET); + i = 0; + while (value == CONSYS_RX_PROT_MASK || i > 10) { + value = CONSYS_RX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AHBAXI_PROT_STA_OFFSET); + i++; + } + + /*assert "conn_top_on" isolation, set "connsys_iso_en"=1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_SPM_PWR_ISO_S_BIT); + /*assert CONNSYS S/W reset (TOP RGU CR), set "ap_sw_rst_b"=0 */ + CONSYS_REG_WRITE(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET, + (CONSYS_REG_READ(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET) & + CONSYS_SW_RST_BIT) | CONSYS_CPU_SW_RST_CTRL_KEY); + /*assert CONNSYS S/W reset (SPM CR), set "ap_sw_rst_b"=0 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + ~CONSYS_SPM_PWR_RST_BIT); + /*write conn_clk_dis=1, disable connsys clock 0x1000632C [4] 1'b1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_CLK_CTRL_BIT); + /*wait 1us */ + udelay(1); + /*write conn_top1_pwr_on=0, power off conn_top1 0x1000632C [3:2] 2'b00 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) & + ~(CONSYS_SPM_PWR_ON_BIT | CONSYS_SPM_PWR_ON_S_BIT)); +#endif /* CONSYS_PWR_ON_OFF_API_AVAILABLE */ + } + +#if CONSYS_PWR_ON_OFF_API_AVAILABLE + return iRet; +#else + return 0; +#endif +} + +static INT32 consys_ahb_clock_ctrl(MTK_WCN_BOOL enable) +{ + return 0; +} + +static INT32 polling_consys_chipid(VOID) +{ + UINT32 retry = 10; + UINT32 consys_ver_id = 0; + UINT32 consys_hw_ver = 0; + UINT32 consys_fw_ver = 0; + UINT8 *consys_reg_base = NULL; + UINT32 value = 0; + + if ((conn_reg.mcu_top_misc_off_base == 0) || (conn_reg.mcu_base == 0) || + (conn_reg.mcu_conn_hif_pdma_base == 0)) + return 0; + + /*12.poll CONNSYS CHIP ID until chipid is returned */ + while (retry-- > 0) { + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_top_misc_off_base + + CONSYS_IP_VER_OFFSET); + if (consys_ver_id == CONSYS_IP_VER_ID) { + WMT_PLAT_PR_INFO("retry(%d)consys version id(0x%08x)\n", + retry, consys_ver_id); + consys_hw_ver = CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HW_ID_OFFSET); + WMT_PLAT_PR_INFO("consys HW version id(0x%x)\n", consys_hw_ver & 0xFFFF); + consys_fw_ver = CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_FW_ID_OFFSET); + WMT_PLAT_PR_INFO("consys FW version id(0x%x)\n", consys_fw_ver & 0xFFFF); + + consys_dl_rom_patch(consys_ver_id, consys_fw_ver); + break; + } + WMT_PLAT_PR_ERR("Read CONSYS version id(0x%08x)", consys_ver_id); + msleep(20); + } + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_top_misc_off_base + CONSYS_CONF_ID_OFFSET); + WMT_PLAT_PR_INFO("consys configuration id(0x%x)\n", consys_ver_id & 0xF); + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HW_ID_OFFSET); + WMT_PLAT_PR_INFO("consys HW version id(0x%x)\n", consys_ver_id & 0xFFFF); + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_FW_ID_OFFSET); + WMT_PLAT_PR_INFO("consys FW version id(0x%x)\n", consys_ver_id & 0xFFFF); + + if (wmt_plat_soc_co_clock_flag_get()) { + consys_reg_base = ioremap_nocache(CONSYS_COCLOCK_STABLE_TIME_BASE, 0x100); + if (consys_reg_base) { + /** + * 1. set CR "vcore ready stable time" "XO initial stable time" and + * "XO bg stable time" to optimize the wakeup time after sleep + * 2. clear "source clock enable ack to XO state" mask + */ + value = CONSYS_REG_READ(consys_reg_base); + value = (value & CONSYS_COCLOCK_STABLE_TIME_MASK) | + CONSYS_COCLOCK_STABLE_TIME; + CONSYS_REG_WRITE(consys_reg_base, value); + value = CONSYS_REG_READ(consys_reg_base + CONSYS_COCLOCK_ACK_ENABLE_OFFSET); + value = (value & 0xffff00fe) | 0x600; + CONSYS_REG_WRITE(consys_reg_base + CONSYS_COCLOCK_ACK_ENABLE_OFFSET, value); + iounmap(consys_reg_base); + } else + WMT_PLAT_PR_ERR("connsys co_clock stable time base(0x%x) ioremap fail!\n", + CONSYS_COCLOCK_STABLE_TIME_BASE); + } + + /* CONN2EMI HW slpprot control enable: 0x18004160[4] 1'b1 */ + CONSYS_REG_WRITE(conn_reg.mcu_conn_hif_pdma_base + CONSYS_SLPPROT_CONTROL_OFFSET, + (CONSYS_REG_READ(conn_reg.mcu_conn_hif_pdma_base + + CONSYS_SLPPROT_CONTROL_OFFSET) & + CONSYS_SLPPROT_CONTROL_MASK) | CONSYS_SLPPROT_CONTROL_VALUE); + + /* toppose_restore_done rollback */ + consys_reg_base = ioremap_nocache(CONSYS_TOPPOSE_RESTORE_ADDRESS, 0x100); + if (consys_reg_base) { + CONSYS_REG_WRITE(consys_reg_base, + (CONSYS_REG_READ(consys_reg_base) & + CONSYS_TOPPOSE_RESTORE_MASK) | CONSYS_TOPPOSE_RESTORE_VALUE); + iounmap(consys_reg_base); + } + + /* update WPLL setting for WPLL issue@LT */ + consys_reg_base = ioremap_nocache(CONSYS_WPLL_SETTING_ADDRESS, 0x100); + if (consys_reg_base) { + CONSYS_REG_WRITE(consys_reg_base, + (CONSYS_REG_READ(consys_reg_base) & + CONSYS_WPLL_SETTING_MASK) | CONSYS_WPLL_SETTING_VALUE); + iounmap(consys_reg_base); + } + + return 0; +} + +static VOID consys_acr_reg_setting(VOID) +{ + WMT_PLAT_PR_INFO("No need to do acr"); +} + +static VOID consys_afe_reg_setting(VOID) +{ + WMT_PLAT_PR_INFO("No need to do afe"); +} + +static INT32 consys_hw_vcn18_ctrl(MTK_WCN_BOOL enable) +{ +#if CONSYS_PMIC_CTRL_ENABLE + if (enable) { + /*Set VCN18_SW_OP_EN as 1*/ + KERNEL_pmic_ldo_vcn18_lp(SW, 1, 1, SW_OFF); + /*Set VCN18_SW_EN as 1 and set votage as 1V8*/ + if (reg_VCN18) { + regulator_set_voltage(reg_VCN18, 1800000, 1800000); + if (regulator_enable(reg_VCN18)) + WMT_PLAT_PR_ERR("enable VCN18 fail\n"); + else + WMT_PLAT_PR_DBG("enable VCN18 ok\n"); + } + /*Set VCN18 SW_LP as 0*/ + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN18_LP, 0); + /*Set VCN18 as low-power mode(1), HW0_OP_EN as 1, HW0_OP_CFG as HW_LP(1)*/ + KERNEL_pmic_ldo_vcn18_lp(SRCLKEN0, 1, 1, HW_LP); + + /*1.AP power on VCN_3V3 LDO (with PMIC_WRAP API) VCN_3V3 */ + /*default vcn33_1 SW mode*/ + if (reg_VCN33_1) { + regulator_set_voltage(reg_VCN33_1, 3300000, 3300000); + if (regulator_enable(reg_VCN33_1)) + WMT_PLAT_PR_ERR("WMT do VCN33_1 PMIC on fail!\n"); + } + + } else { + if (reg_VCN33_1) + regulator_disable(reg_VCN33_1); + /* delay 300us */ + udelay(300); + /*AP power off MT6359 VCN_1V8 LDO */ + if (reg_VCN18) { + if (regulator_disable(reg_VCN18)) + WMT_PLAT_PR_ERR("disable VCN_1V8 fail!\n"); + else + WMT_PLAT_PR_DBG("disable VCN_1V8 ok\n"); + } + } +#endif + return 0; +} + +static VOID consys_vcn28_hw_mode_ctrl(UINT32 enable) +{ +#if CONSYS_PMIC_CTRL_ENABLE + if (enable) + /*Set VCN33_2_SW_OP_EN as 1*/ + KERNEL_pmic_ldo_vcn33_2_lp(SW, 1, 1, SW_OFF); + else + /*Set VCN33_2 as low-power mode(1), HW0_OP_EN as 0, HW0_OP_CFG as HW_OFF(0)*/ + KERNEL_pmic_ldo_vcn33_2_lp(SRCLKEN0, 1, 0, HW_OFF); +#endif +} + +static INT32 consys_hw_vcn28_ctrl(UINT32 enable) +{ +#if CONSYS_PMIC_CTRL_ENABLE + INT32 result; + + if (enable) { + /*in co-clock mode,need to turn on vcn33_2 when fm on */ + /*Set VCN33_2_SW_OP_EN as 1*/ + KERNEL_pmic_ldo_vcn33_2_lp(SW, 1, 1, SW_OFF); + /*Set VCN33_2_SW_EN as 1 and set votage as 2V8*/ + if (reg_VCN33_2) { + regulator_set_voltage(reg_VCN33_2, 2800000, 2800000); + result = regulator_enable(reg_VCN33_2); + } + /*Set VCN33_2 SW_LP as 0*/ + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_2_LP, 0); + /*Set VCN33_2 as low-power mode(1), HW0_OP_EN as 1, HW0_OP_CFG as HW_OFF(0)*/ + KERNEL_pmic_ldo_vcn33_2_lp(SRCLKEN0, 1, 1, HW_OFF); + WMT_PLAT_PR_INFO("turn on vcn33_2 for fm/gps usage in co-clock mode\n"); + } else { + /*in co-clock mode,need to turn off vcn33_2 when fm off */ + /*Set VCN33_2 as low-power mode(1), HW0_OP_EN as 0, HW0_OP_CFG as HW_OFF(0)*/ + KERNEL_pmic_ldo_vcn33_2_lp(SRCLKEN0, 1, 0, HW_OFF); + if (reg_VCN33_2) + regulator_disable(reg_VCN33_2); + WMT_PLAT_PR_INFO("turn off vcn33_2 for fm/gps usage in co-clock mode\n"); + } +#endif + return 0; +} + +static INT32 consys_hw_bt_vcn33_ctrl(UINT32 enable) +{ + return 0; +} + +static INT32 consys_hw_wifi_vcn33_ctrl(UINT32 enable) +{ + return 0; +} + +static INT32 consys_emi_mpu_set_region_protection(VOID) +{ +#ifdef CONFIG_MTK_EMI + struct emi_region_info_t region_info; + + /*set MPU for EMI share Memory */ + WMT_PLAT_PR_INFO("setting MPU for EMI share memory\n"); + + region_info.start = gConEmiPhyBase; + region_info.end = gConEmiPhyBase + gConEmiSize - 1; + region_info.region = 27; + SET_ACCESS_PERMISSION(region_info.apc, LOCK, + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, + NO_PROTECTION, FORBIDDEN, NO_PROTECTION); + emi_mpu_set_protection(®ion_info); +#endif + return 0; +} + +static UINT32 consys_emi_set_remapping_reg(VOID) +{ + /* For direct path */ + phys_addr_t mdPhy = 0; + INT32 size = 0; + + mtk_wcn_emi_addr_info.emi_ap_phy_addr = gConEmiPhyBase; + mtk_wcn_emi_addr_info.emi_size = gConEmiSize; + + if (conn_reg.topckgen_base == 0) + return 0; + + /*EMI Registers remapping*/ + CONSYS_REG_WRITE_OFFSET_RANGE(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET, + gConEmiPhyBase, 0, 16, 20); + WMT_PLAT_PR_INFO("CONSYS_EMI_MAPPING dump in restore cb(0x%08x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET)); + + /*Perisys Configuration Registers remapping*/ + CONSYS_REG_WRITE_OFFSET_RANGE(conn_reg.topckgen_base + CONSYS_EMI_PERI_MAPPING_OFFSET, + 0x10003000, 0, 16, 20); + WMT_PLAT_PR_INFO("PERISYS_MAPPING dump in restore cb(0x%08x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_PERI_MAPPING_OFFSET)); + + /*Modem Configuration Registers remapping*/ +#ifdef CONFIG_MTK_ECCCI_DRIVER + mdPhy = get_smem_phy_start_addr(MD_SYS1, SMEM_USER_RAW_MD_CONSYS, &size); +#endif + if (size == 0) + WMT_PLAT_PR_INFO("MD direct path is not supported\n"); + else { + CONSYS_REG_WRITE_OFFSET_RANGE( + conn_reg.topckgen_base + CONSYS_EMI_AP_MD_OFFSET, + mdPhy, 0, 16, 20); + WMT_PLAT_PR_INFO("MD_MAPPING dump in restore cb(0x%08x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_AP_MD_OFFSET)); + } + mtk_wcn_emi_addr_info.emi_direct_path_ap_phy_addr = mdPhy; + mtk_wcn_emi_addr_info.emi_direct_path_size = size; + + mtk_wcn_emi_addr_info.emi_ram_bt_buildtime_offset = + CONSYS_EMI_RAM_BT_BUILDTIME_OFFSET; + mtk_wcn_emi_addr_info.emi_ram_wifi_buildtime_offset = + CONSYS_EMI_RAM_WIFI_BUILDTIME_OFFSET; + mtk_wcn_emi_addr_info.emi_ram_mcu_buildtime_offset = + CONSYS_EMI_RAM_MCU_BUILDTIME_OFFSET; + mtk_wcn_emi_addr_info.emi_patch_mcu_buildtime_offset = + CONSYS_EMI_PATCH_MCU_BUILDTIME_OFFSET; + + return 0; +} + +static INT32 bt_wifi_share_v33_spin_lock_init(VOID) +{ + return 0; +} + +static INT32 consys_read_irq_info_from_dts(struct platform_device *pdev, PINT32 irq_num, + PUINT32 irq_flag) +{ + struct device_node *node; + + node = pdev->dev.of_node; + if (node) { + *irq_num = irq_of_parse_and_map(node, 0); + *irq_flag = irq_get_trigger_type(*irq_num); + WMT_PLAT_PR_INFO("get irq id(%d) and irq trigger flag(%d) from DT\n", *irq_num, + *irq_flag); + } else { + WMT_PLAT_PR_ERR("[%s] can't find CONSYS compatible node\n", __func__); + return -1; + } + + return 0; +} + +static INT32 consys_read_reg_from_dts(struct platform_device *pdev) +{ + INT32 iRet = -1; + struct device_node *node = NULL; + + node = pdev->dev.of_node; + if (node) { + /* registers base address */ + conn_reg.mcu_base = (SIZE_T) of_iomap(node, MCU_BASE_INDEX); + conn_reg.ap_rgu_base = (SIZE_T) of_iomap(node, TOP_RGU_BASE_INDEX); + conn_reg.topckgen_base = (SIZE_T) of_iomap(node, INFRACFG_AO_BASE_INDEX); + conn_reg.spm_base = (SIZE_T) of_iomap(node, SPM_BASE_INDEX); + conn_reg.mcu_conn_hif_on_base = (SIZE_T) of_iomap(node, MCU_CONN_HIF_ON_BASE_INDEX); + conn_reg.mcu_top_misc_off_base = (SIZE_T) of_iomap(node, + MCU_TOP_MISC_OFF_BASE_INDEX); + conn_reg.mcu_cfg_on_base = (SIZE_T) of_iomap(node, MCU_CFG_ON_BASE_INDEX); + conn_reg.mcu_cirq_base = (SIZE_T) of_iomap(node, MCU_CIRQ_BASE_INDEX); + conn_reg.mcu_top_misc_on_base = (SIZE_T) of_iomap(node, MCU_TOP_MISC_ON_BASE_INDEX); + conn_reg.mcu_conn_hif_pdma_base = (SIZE_T) of_iomap(node, + MCU_CONN_HIF_PDMA_BASE_INDEX); + conn_reg.ap_pccif4_base = (SIZE_T) of_iomap(node, AP_PCCIF4_BASE_INDEX); + conn_reg.infra_ao_pericfg_base = (SIZE_T) of_iomap(node, + INFRA_AO_PERICFG_BASE_INDEX); + + WMT_PLAT_PR_DBG("Get base mcu(0x%zx), rgu(0x%zx), topckgen(0x%zx), spm(0x%zx)\n", + conn_reg.mcu_base, conn_reg.ap_rgu_base, + conn_reg.topckgen_base, conn_reg.spm_base); + WMT_PLAT_PR_DBG("Get base hif_on(0x%zx), misc_off(0x%zx), cfg_on(0x%zx)\n", + conn_reg.mcu_top_misc_off_base, + conn_reg.mcu_conn_hif_on_base, + conn_reg.mcu_cfg_on_base); + WMT_PLAT_PR_DBG("Get base cirq(0x%zx), top_misc_on(0x%zx), hif_pdma(0x%zx)\n", + conn_reg.mcu_top_misc_on_base, + conn_reg.mcu_cirq_base, + conn_reg.mcu_conn_hif_pdma_base); + WMT_PLAT_PR_DBG("Get base ap_pccif4(0x%zx), infra_ao_pericfg(0x%zx)\n", + conn_reg.ap_pccif4_base, + conn_reg.infra_ao_pericfg_base); + } else { + WMT_PLAT_PR_ERR("[%s] can't find CONSYS compatible node\n", __func__); + return iRet; + } + + return 0; +} + +static VOID force_trigger_assert_debug_pin(VOID) +{ + UINT32 value = 0; + + if (conn_reg.infra_ao_pericfg_base != 0) { + WMT_PLAT_PR_DBG("CON_STA_REG = %x\n", + CONSYS_REG_READ( + conn_reg.infra_ao_pericfg_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG)); + + /* clear CON_PWR_ON & CON_SW_READY bit (CON_STA_REG[0], CON_STA_REG[1]) */ + value = CONSYS_REG_READ(conn_reg.infra_ao_pericfg_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG); + value = value & (~INFRASYS_COMMON_AP2MD_CON_PWR_ON_CON_SW_READY_MASK); + CONSYS_REG_WRITE(conn_reg.infra_ao_pericfg_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG, + value); + + WMT_PLAT_PR_DBG("CON_STA_REG = %x\n", + CONSYS_REG_READ( + conn_reg.infra_ao_pericfg_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG)); + } + + if (conn_reg.topckgen_base == 0) + return; + + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AP2CONN_OSC_EN_OFFSET) & ~CONSYS_AP2CONN_WAKEUP_BIT); + WMT_PLAT_PR_INFO("enable:dump CONSYS_AP2CONN_OSC_EN_REG(0x%x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET)); + usleep_range(64, 96); + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AP2CONN_OSC_EN_OFFSET) | CONSYS_AP2CONN_WAKEUP_BIT); + WMT_PLAT_PR_INFO("disable:dump CONSYS_AP2CONN_OSC_EN_REG(0x%x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET)); +} + +static UINT32 consys_read_cpupcr(VOID) +{ + if (conn_reg.mcu_conn_hif_on_base == 0) + return 0; + + return CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + CONSYS_CPUPCR_OFFSET); +} + +static UINT32 consys_soc_chipid_get(VOID) +{ + return PLATFORM_SOC_CHIP; +} + +static P_CONSYS_EMI_ADDR_INFO consys_soc_get_emi_phy_add(VOID) +{ + return &mtk_wcn_emi_addr_info; +} + +P_WMT_CONSYS_IC_OPS mtk_wcn_get_consys_ic_ops(VOID) +{ + return &consys_ic_ops; +} + +static INT32 consys_dl_rom_patch(UINT32 ip_ver, UINT32 fw_ver) +{ + if (rom_patch_dl_flag) { + if (mtk_wcn_soc_rom_patch_dwn(ip_ver, fw_ver) == 0) + rom_patch_dl_flag = 1; + } + + return 0; +} + +static VOID consys_set_dl_rom_patch_flag(INT32 flag) +{ + rom_patch_dl_flag = flag; +} + +static INT32 consys_dedicated_log_path_init(struct platform_device *pdev) +{ + struct device_node *node; + UINT32 irq_num; + UINT32 irq_flag; + INT32 iret = -1; + struct connlog_irq_config irq_config; + + memset(&irq_config, 0, sizeof(struct connlog_irq_config)); + node = pdev->dev.of_node; + if (node) { + irq_num = irq_of_parse_and_map(node, 2); + irq_flag = irq_get_trigger_type(irq_num); + WMT_PLAT_PR_INFO("get conn2ap_sw_irq id(%d) and irq trigger flag(%d) from DT\n", + irq_num, irq_flag); + } else { + WMT_PLAT_PR_ERR("[%s] can't find CONSYS compatible node\n", __func__); + return iret; + } + + irq_config.irq_num = irq_num; + irq_config.irq_flag = irq_flag; + irq_config.irq_callback = NULL; + + connsys_dedicated_log_path_apsoc_init( + gConEmiPhyBase, &connsys_fw_log_parameter, &irq_config); +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH + fw_log_wmt_init(); +#endif + return 0; +} + +static VOID consys_dedicated_log_path_deinit(VOID) +{ +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH + fw_log_wmt_deinit(); +#endif + connsys_dedicated_log_path_apsoc_deinit(); +} + +static INT32 consys_check_reg_readable(VOID) +{ + INT32 can_read = 0; + UINT32 value = 0; + + if (conn_reg.mcu_cfg_on_base != 0 && + conn_reg.mcu_top_misc_on_base != 0) { + /*check connsys clock and sleep status*/ + CONSYS_REG_WRITE(conn_reg.mcu_conn_hif_on_base, CONSYS_CLOCK_CHECK_VALUE); + udelay(1000); + value = CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base); + if ((value & CONSYS_HCLK_CHECK_BIT) && + (value & CONSYS_OSCCLK_CHECK_BIT)) + can_read = 1; + } + + if (!can_read) + WMT_PLAT_PR_ERR("connsys clock check fail 0x18007000(0x%x)\n", value); + + return can_read; +} + +static INT32 consys_emi_coredump_remapping(UINT8 __iomem **addr, UINT32 enable) +{ + if (enable) { + *addr = ioremap_nocache(gConEmiPhyBase + CONSYS_EMI_COREDUMP_OFFSET, + CONSYS_EMI_MEM_SIZE); + if (*addr) { + WMT_PLAT_PR_INFO("COREDUMP EMI mapping OK virtual(0x%p) physical(0x%x)\n", + *addr, (UINT32) gConEmiPhyBase + + CONSYS_EMI_COREDUMP_OFFSET); + memset_io(*addr, 0, CONSYS_EMI_MEM_SIZE); + } else { + WMT_PLAT_PR_ERR("EMI mapping fail\n"); + return -1; + } + } else { + if (*addr) { + iounmap(*addr); + *addr = NULL; + } + } + return 0; +} + +static INT32 consys_reset_emi_coredump(UINT8 __iomem *addr) +{ + if (!addr) { + WMT_PLAT_PR_ERR("get virtual address fail\n"); + return -1; + } + WMT_PLAT_PR_INFO("Reset EMI(0xF0068000 ~ 0xF0068400) and (0xF0070400 ~ 0xF0078400)\n"); + /* reset 0xF0068000 ~ 0xF0068400 (1K) */ + memset_io(addr, 0, 0x400); + /* reset 0xF0070400 ~ 0xF0078400 (32K) */ + memset_io(addr + CONSYS_EMI_PAGED_DUMP_OFFSET, 0, 0x8000); + return 0; +} + +static INT32 consys_is_connsys_reg(UINT32 addr) +{ + if (addr > 0x18000000 && addr < 0x180FFFFF) { + if (addr >= 0x18007000 && addr <= 0x18007FFF) + return 0; + + return 1; + } + + return 0; +} + +static INT32 consys_is_host_csr(SIZE_T addr) +{ + SIZE_T start_offset = 0x000; + SIZE_T end_offset = 0xFFF; + + if (addr >= (CONN_HIF_ON_BASE_ADDR + start_offset) && + addr <= (CONN_HIF_ON_BASE_ADDR + end_offset)) + return 1; + + if (conn_reg.mcu_conn_hif_on_base != 0 && + addr >= (conn_reg.mcu_conn_hif_on_base + start_offset) && + addr <= (conn_reg.mcu_conn_hif_on_base + end_offset)) + return 1; + + return 0; +} + +static VOID consys_ic_clock_fail_dump(VOID) +{ + UINT8 *addr; + char *buffer, *temp; + INT32 size = 1024; + + if (conn_reg.mcu_base == 0) + return; + + /* make sure buffer size is big enough */ + buffer = osal_malloc(size); + if (!buffer) + return; + + temp = buffer; + temp += sprintf(temp, "CONN_HIF_TOP_MISC=0x%08x CONN_HIF_BUSY_STATUS=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HIF_TOP_MISC), + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HIF_BUSY_STATUS)); + + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_HIF_DBG_IDX, 0x3333); + temp += sprintf(temp, "Write CONSYS_HIF_DBG_IDX to 0x3333\n"); + + temp += sprintf(temp, "CONSYS_HIF_DBG_PROBE=0x%08x CONN_HIF_TOP_MISC=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HIF_DBG_PROBE), + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HIF_TOP_MISC)); + + temp += sprintf(temp, "CONN_HIF_BUSY_STATUS=0x%08x CONN_HIF_PDMA_BUSY_STATUS=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HIF_BUSY_STATUS), + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HIF_PDMA_BUSY_STATUS)); + + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_HIF_DBG_IDX, 0x2222); + temp += sprintf(temp, "Write CONSYS_HIF_DBG_IDX to 0x2222\n"); + + temp += sprintf(temp, "CONSYS_HIF_DBG_PROBE=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HIF_DBG_PROBE)); + + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_HIF_DBG_IDX, 0x3333); + temp += sprintf(temp, "Write CONSYS_HIF_DBG_IDX to 0x3333\n"); + + temp += sprintf(temp, "CONSYS_HIF_DBG_PROBE=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HIF_DBG_PROBE)); + + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_HIF_DBG_IDX, 0x4444); + temp += sprintf(temp, "Write CONSYS_HIF_DBG_IDX to 0x4444\n"); + + temp += sprintf(temp, "CONSYS_HIF_DBG_PROBE=0x%08x CONN_MCU_EMI_CONTROL=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HIF_DBG_PROBE), + CONSYS_REG_READ(conn_reg.mcu_base + CONN_MCU_EMI_CONTROL)); + temp += sprintf(temp, "EMI_CONTROL_DBG_PROBE=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + EMI_CONTROL_DBG_PROBE)); + temp += sprintf(temp, "CONN_MCU_CLOCK_CONTROL=0x%08x CONN_MCU_BUS_CONTROL=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_CLOCK_CONTROL), + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_BUS_CONTROL)); + + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_DEBUG_SELECT, 0x003e3d00); + temp += sprintf(temp, "Write CONSYS_DEBUG_SELECT to 0x003e3d00\n"); + + temp += sprintf(temp, "CONN_MCU_DEBUG_STATUS=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_DEBUG_STATUS)); + + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_DEBUG_SELECT, 0x00403f00); + temp += sprintf(temp, "Write CONSYS_DEBUG_SELECT to 0x00403f00\n"); + + temp += sprintf(temp, "CONN_MCU_DEBUG_STATUS=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_DEBUG_STATUS)); + + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_DEBUG_SELECT, 0x00424100); + temp += sprintf(temp, "Write CONSYS_DEBUG_SELECT to 0x00424100\n"); + + temp += sprintf(temp, "CONN_MCU_DEBUG_STATUS=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_DEBUG_STATUS)); + + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_DEBUG_SELECT, 0x00444300); + temp += sprintf(temp, "Write CONSYS_DEBUG_SELECT to 0x00444300\n"); + + temp += sprintf(temp, "CONN_MCU_DEBUG_STATUS=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_DEBUG_STATUS)); + WMT_PLAT_PR_ERR("%s length = %d", buffer, osal_strlen(buffer)); + + temp = buffer; + addr = ioremap_nocache(0x180bc000, 0x100); + /* conn2ap axi master sleep prot info */ + temp += sprintf(temp, "0x180bc010=0x%08x\n", CONSYS_REG_READ(addr + 0x10)); + /* conn_mcu2ap axi master sleep prot info */ + temp += sprintf(temp, "0x180bc014=0x%08x\n", CONSYS_REG_READ(addr + 0x14)); + /* conn2ap axi gals bus info */ + temp += sprintf(temp, "0x180bc018=0x%08x\n", CONSYS_REG_READ(addr + 0x18)); + /* conn2ap mux4to1 debug info */ + temp += sprintf(temp, "0x180bc01c=0x%08x\n", CONSYS_REG_READ(addr + 0x1c)); + /* conn_hif_off bus busy info */ + temp += sprintf(temp, "0x180bc020=0x%08x\n", CONSYS_REG_READ(addr + 0x20)); + iounmap(addr); + + addr = ioremap_nocache(0x10001B20, 0x100); + /* 0x1020E804 */ + temp += sprintf(temp, "0x10001B20=0x%08x\n", CONSYS_REG_READ(addr)); + + addr = ioremap_nocache(0x1800713c, 0x100); + /* conn_hif_on misc info */ + temp += sprintf(temp, "0x1800713c=0x%08x\n", CONSYS_REG_READ(addr)); + iounmap(addr); + + addr = ioremap_nocache(0x180c1144, 0x100); + /* conn_on_host debug flag */ + temp += sprintf(temp, "0x180c1144=0x%08x\n", CONSYS_REG_READ(addr)); + iounmap(addr); + + addr = ioremap_nocache(0x1020E804, 0x100); + /* 0x1020E804 */ + temp += sprintf(temp, "0x1020E804=0x%08x\n", CONSYS_REG_READ(addr)); + iounmap(addr); + + WMT_PLAT_PR_ERR("%s length = %d", buffer, osal_strlen(buffer)); + osal_free(buffer); +} + +static INT32 consys_dump_osc_state(P_CONSYS_STATE state) +{ + CONSYS_REG_WRITE(CONN_CFG_ON_CONN_ON_HOST_MAILBOX_MCU_ADDR, 0x1); + CONSYS_REG_WRITE(CONN_CFG_ON_CONN_ON_MON_CTL_ADDR, 0x80000001); + CONSYS_REG_WRITE(CONN_CFG_ON_CONN_ON_MON_SEL0_ADDR, 0x03020100); + CONSYS_REG_WRITE(CONN_CFG_ON_CONN_ON_MON_SEL1_ADDR, 0x07060504); + CONSYS_REG_WRITE(CONN_CFG_ON_CONN_ON_MON_SEL2_ADDR, 0x0b0a0908); + CONSYS_REG_WRITE(CONN_CFG_ON_CONN_ON_MON_SEL3_ADDR, 0x0f0e0d0c); + CONSYS_REG_WRITE(CONN_CFG_ON_CONN_ON_DBGSEL_ADDR, 0x3); + state->lp[0] = (UINT32)CONN_CFG_ON_CONN_ON_MON_FLAG_RECORD_MAPPING_AP_ADDR; + state->lp[1] = CONSYS_REG_READ(CONN_CFG_ON_CONN_ON_MON_FLAG_RECORD_ADDR); + WMT_PLAT_PR_INFO("0x%08x: 0x%x\n", state->lp[0], state->lp[1]); + CONSYS_REG_WRITE(CONN_CFG_ON_CONN_ON_HOST_MAILBOX_MCU_ADDR, 0x0); + + return MTK_WCN_BOOL_TRUE; +} + +static VOID consys_set_pdma_axi_rready_force_high(UINT32 enable) +{ + if (conn_reg.mcu_conn_hif_pdma_base == 0) + return; + + if (enable) + CONSYS_SET_BIT(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_PDMA_AXI_RREADY, + CONSYS_PDMA_AXI_RREADY_MASK); + else if ((CONSYS_REG_READ(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_PDMA_AXI_RREADY) & + CONSYS_PDMA_AXI_RREADY_MASK) != 0) + CONSYS_CLR_BIT(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_PDMA_AXI_RREADY, + CONSYS_PDMA_AXI_RREADY_MASK); +} + +static VOID consys_set_mcif_emi_mpu_protection(MTK_WCN_BOOL enable) +{ + WMT_PLAT_PR_INFO("No need setup region 23 for this project.\n"); +} + +static INT32 consys_calibration_backup_restore_support(VOID) +{ + return 1; +} + +#if WMT_DEVAPC_DBG_SUPPORT +static VOID consys_devapc_violation_cb(VOID) +{ + /** + * Don't use wmt_lib_trigger_assert() because it will invoke vmalloc and then cause KE since + * this callback is supposed to be invoked in DEVAPC exception hanlder. + */ + wmt_lib_trigger_assert_keyword_delay(WMTDRV_TYPE_WMT, 46, "DEVAPC Violation"); +} +#endif + +static VOID consyc_register_devapc_cb(VOID) +{ +#if WMT_DEVAPC_DBG_SUPPORT + register_devapc_vio_callback(&devapc_handle); +#endif +} + +static UINT64 consys_get_options(VOID) +{ + UINT64 options = OPT_WIFI_LTE_COEX | + OPT_BT_TSSI_FROM_WIFI_CONFIG_NEW_OPID | + OPT_COEX_CONFIG_ADJUST | + OPT_COEX_CONFIG_ADJUST_NEW_FLAG | + OPT_WIFI_LTE_COEX_TABLE_3 | + OPT_NORMAL_PATCH_DWN_3 | + OPT_PATCH_CHECKSUM; + return options; +} + diff --git a/drivers/misc/mediatek/connectivity/common/common_main/platform/mt6853.c b/drivers/misc/mediatek/connectivity/common/common_main/platform/mt6853.c new file mode 100644 index 0000000000000000000000000000000000000000..ded34113aa570a2df5f853cb017414ed6ab24c47 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/platform/mt6853.c @@ -0,0 +1,2554 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +#ifdef DFT_TAG +#undef DFT_TAG +#endif +#define DFT_TAG "[WMT-CONSYS-HW]" + +#define CONSYS_ENABLE_EMI_MPU 1 +#define REGION_CONN 27 + +#define DOMAIN_AP 0 +#define DOMAIN_CONN 2 + +#define PRIMARY_ADIE 0x6631 +#define SECONDARY_ADIE 0x6635 + +/* if clock of TCXO is controlled by GPIO, CLK_CTRL_TCXOENA_REQ should be 1. */ +#define CLK_CTRL_TCXOENA_REQ 0 + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include +#include +#include +#include +#include +#include "connsys_debug_utility.h" +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH +#include "fw_log_wmt.h" +#endif +#include "osal_typedef.h" +#include "mt6853.h" +#include "mtk_wcn_consys_hw.h" +#include "wmt_ic.h" +#include "wmt_lib.h" +#include "wmt_step.h" +#include "wmt_plat.h" +#include "stp_dbg.h" + +#include + +#if CONSYS_PMIC_CTRL_ENABLE +#include +#include +#include +#endif + +#ifdef CONFIG_MTK_HIBERNATION +#include +#endif + +#include + +/* Direct path */ +#include +#include +#if WMT_DEVAPC_DBG_SUPPORT +#include +#endif +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +static INT32 consys_clock_buffer_ctrl(MTK_WCN_BOOL enable); +static VOID consys_hw_reset_bit_set(MTK_WCN_BOOL enable); +static VOID consys_hw_spm_clk_gating_enable(VOID); +static INT32 consys_hw_power_ctrl(MTK_WCN_BOOL enable); +static INT32 consys_ahb_clock_ctrl(MTK_WCN_BOOL enable); +static INT32 polling_consys_chipid(VOID); +static VOID consys_acr_reg_setting(VOID); +static VOID consys_afe_reg_setting(VOID); +static INT32 consys_hw_vcn18_ctrl(MTK_WCN_BOOL enable); +static VOID consys_vcn28_hw_mode_ctrl(UINT32 enable); +static INT32 consys_hw_vcn28_ctrl(UINT32 enable); +static INT32 consys_hw_wifi_vcn33_ctrl(UINT32 enable); +static INT32 consys_hw_bt_vcn33_ctrl(UINT32 enable); +static INT32 consys_hw_vcn_ctrl_after_idle(VOID); +static UINT32 consys_soc_chipid_get(VOID); +static INT32 consys_adie_chipid_detect(VOID); +static INT32 consys_emi_mpu_set_region_protection(VOID); +static UINT32 consys_emi_set_remapping_reg(VOID); +static INT32 bt_wifi_share_v33_spin_lock_init(VOID); +static INT32 consys_clk_get_from_dts(struct platform_device *pdev); +static INT32 consys_pmic_get_from_dts(struct platform_device *pdev); +static INT32 consys_read_irq_info_from_dts(struct platform_device *pdev, + PINT32 irq_num, PUINT32 irq_flag); +static INT32 consys_read_reg_from_dts(struct platform_device *pdev); +static UINT32 consys_read_cpupcr(VOID); +static VOID force_trigger_assert_debug_pin(VOID); +static INT32 consys_co_clock_type(VOID); +static P_CONSYS_EMI_ADDR_INFO consys_soc_get_emi_phy_add(VOID); +static VOID consys_set_if_pinmux(MTK_WCN_BOOL enable); +static INT32 consys_dl_rom_patch(UINT32 ip_ver, UINT32 fw_ver); +static VOID consys_set_dl_rom_patch_flag(INT32 flag); +static INT32 consys_dedicated_log_path_init(struct platform_device *pdev); +static VOID consys_dedicated_log_path_deinit(VOID); +static INT32 consys_emi_coredump_remapping(UINT8 __iomem **addr, UINT32 enable); +static INT32 consys_reset_emi_coredump(UINT8 __iomem *addr); +static INT32 consys_check_reg_readable(VOID); +static VOID consys_ic_clock_fail_dump(VOID); +static INT32 consys_is_connsys_reg(UINT32 addr); +static INT32 consys_is_host_csr(SIZE_T addr); +static INT32 consys_dump_osc_state(P_CONSYS_STATE state); +static VOID consys_set_pdma_axi_rready_force_high(UINT32 enable); +static VOID consys_set_mcif_emi_mpu_protection(MTK_WCN_BOOL enable); +/* + * If 1: this platform supports calibration backup/restore. + * otherwise: 0 + */ +static INT32 consys_calibration_backup_restore_support(VOID); +#if WMT_DEVAPC_DBG_SUPPORT +static VOID consys_devapc_violation_cb(VOID); +#endif +static VOID consyc_register_devapc_cb(VOID); +static INT32 consys_is_rc_mode_enable(VOID); +static VOID consys_emi_entry_address(VOID); +static VOID consys_set_xo_osc_ctrl(VOID); +static VOID consys_identify_adie(VOID); +static VOID consys_wifi_ctrl_setting(VOID); +static VOID consys_bus_timeout_config(VOID); +static VOID consys_set_access_emi_hw_mode(VOID); +static INT32 consys_dump_gating_state(P_CONSYS_STATE state); +static INT32 consys_sleep_info_enable_ctrl(UINT32 enable); +static INT32 consys_sleep_info_read_ctrl(WMT_SLEEP_COUNT_TYPE type, PUINT64 sleep_counter, PUINT64 sleep_timer); +static INT32 consys_sleep_info_clear(VOID); +static VOID consys_conn2ap_sw_irq_clear(VOID); +static UINT64 consys_get_options(VOID); + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ +/* CCF part */ +struct clk *clk_scp_conn_main; /*ctrl conn_power_on/off */ +struct clk *clk_infracfg_ao_ccif4_ap_cg; /* For direct path */ + +/* PMIC part */ +#if CONSYS_PMIC_CTRL_ENABLE +struct regulator *reg_VCN13; +struct regulator *reg_VCN18; +struct regulator *reg_VCN33_1_BT; +struct regulator *reg_VCN33_1_WIFI; +struct regulator *reg_VCN33_2_WIFI; +#endif + +EMI_CTRL_STATE_OFFSET mtk_wcn_emi_state_off = { + .emi_apmem_ctrl_state = EXP_APMEM_CTRL_STATE, + .emi_apmem_ctrl_host_sync_state = EXP_APMEM_CTRL_HOST_SYNC_STATE, + .emi_apmem_ctrl_host_sync_num = EXP_APMEM_CTRL_HOST_SYNC_NUM, + .emi_apmem_ctrl_chip_sync_state = EXP_APMEM_CTRL_CHIP_SYNC_STATE, + .emi_apmem_ctrl_chip_sync_num = EXP_APMEM_CTRL_CHIP_SYNC_NUM, + .emi_apmem_ctrl_chip_sync_addr = EXP_APMEM_CTRL_CHIP_SYNC_ADDR, + .emi_apmem_ctrl_chip_sync_len = EXP_APMEM_CTRL_CHIP_SYNC_LEN, + .emi_apmem_ctrl_chip_print_buff_start = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_START, + .emi_apmem_ctrl_chip_print_buff_len = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_LEN, + .emi_apmem_ctrl_chip_print_buff_idx = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_IDX, + .emi_apmem_ctrl_chip_int_status = EXP_APMEM_CTRL_CHIP_INT_STATUS, + .emi_apmem_ctrl_chip_paded_dump_end = EXP_APMEM_CTRL_CHIP_PAGED_DUMP_END, + .emi_apmem_ctrl_host_outband_assert_w1 = EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1, + .emi_apmem_ctrl_chip_page_dump_num = EXP_APMEM_CTRL_CHIP_PAGE_DUMP_NUM, + .emi_apmem_ctrl_assert_flag = EXP_APMEM_CTRL_ASSERT_FLAG, + .emi_apmem_ctrl_chip_check_sleep = EXP_APMEM_CTRL_CHIP_CHECK_SLEEP, +}; + +CONSYS_EMI_ADDR_INFO mtk_wcn_emi_addr_info = { + .emi_phy_addr = CONSYS_EMI_FW_PHY_BASE, + .paged_trace_off = CONSYS_EMI_PAGED_TRACE_OFFSET, + .paged_dump_off = CONSYS_EMI_PAGED_DUMP_OFFSET, + .full_dump_off = CONSYS_EMI_FULL_DUMP_OFFSET, + .emi_remap_offset = CONSYS_EMI_MAPPING_OFFSET, + .p_ecso = &mtk_wcn_emi_state_off, + .pda_dl_patch_flag = 1, + .emi_met_size = (32*KBYTE), + .emi_met_data_offset = CONSYS_EMI_MET_DATA_OFFSET, + .emi_core_dump_offset = CONSYS_EMI_COREDUMP_OFFSET, +}; + +WMT_CONSYS_IC_OPS consys_ic_ops = { + .consys_ic_clock_buffer_ctrl = consys_clock_buffer_ctrl, + .consys_ic_hw_reset_bit_set = consys_hw_reset_bit_set, + .consys_ic_hw_spm_clk_gating_enable = consys_hw_spm_clk_gating_enable, + .consys_ic_hw_power_ctrl = consys_hw_power_ctrl, + .consys_ic_ahb_clock_ctrl = consys_ahb_clock_ctrl, + .polling_consys_ic_chipid = polling_consys_chipid, + .consys_ic_acr_reg_setting = consys_acr_reg_setting, + .consys_ic_afe_reg_setting = consys_afe_reg_setting, + .consys_ic_hw_vcn18_ctrl = consys_hw_vcn18_ctrl, + .consys_ic_vcn28_hw_mode_ctrl = consys_vcn28_hw_mode_ctrl, + .consys_ic_hw_vcn28_ctrl = consys_hw_vcn28_ctrl, + .consys_ic_hw_wifi_vcn33_ctrl = consys_hw_wifi_vcn33_ctrl, + .consys_ic_hw_bt_vcn33_ctrl = consys_hw_bt_vcn33_ctrl, + .consys_ic_hw_vcn_ctrl_after_idle = consys_hw_vcn_ctrl_after_idle, + .consys_ic_soc_chipid_get = consys_soc_chipid_get, + .consys_ic_adie_chipid_detect = consys_adie_chipid_detect, + .consys_ic_emi_mpu_set_region_protection = consys_emi_mpu_set_region_protection, + .consys_ic_emi_set_remapping_reg = consys_emi_set_remapping_reg, + .ic_bt_wifi_share_v33_spin_lock_init = bt_wifi_share_v33_spin_lock_init, + .consys_ic_clk_get_from_dts = consys_clk_get_from_dts, + .consys_ic_pmic_get_from_dts = consys_pmic_get_from_dts, + .consys_ic_read_irq_info_from_dts = consys_read_irq_info_from_dts, + .consys_ic_read_reg_from_dts = consys_read_reg_from_dts, + .consys_ic_read_cpupcr = consys_read_cpupcr, + .ic_force_trigger_assert_debug_pin = force_trigger_assert_debug_pin, + .consys_ic_co_clock_type = consys_co_clock_type, + .consys_ic_soc_get_emi_phy_add = consys_soc_get_emi_phy_add, + .consys_ic_set_if_pinmux = consys_set_if_pinmux, + .consys_ic_set_dl_rom_patch_flag = consys_set_dl_rom_patch_flag, + .consys_ic_dedicated_log_path_init = consys_dedicated_log_path_init, + .consys_ic_dedicated_log_path_deinit = consys_dedicated_log_path_deinit, + .consys_ic_emi_coredump_remapping = consys_emi_coredump_remapping, + .consys_ic_reset_emi_coredump = consys_reset_emi_coredump, + .consys_ic_check_reg_readable = consys_check_reg_readable, + .consys_ic_clock_fail_dump = consys_ic_clock_fail_dump, + .consys_ic_is_connsys_reg = consys_is_connsys_reg, + .consys_ic_is_host_csr = consys_is_host_csr, + .consys_ic_dump_osc_state = consys_dump_osc_state, + .consys_ic_set_pdma_axi_rready_force_high = consys_set_pdma_axi_rready_force_high, + .consys_ic_set_mcif_emi_mpu_protection = consys_set_mcif_emi_mpu_protection, + .consys_ic_calibration_backup_restore = consys_calibration_backup_restore_support, + .consys_ic_register_devapc_cb = consyc_register_devapc_cb, + .consys_ic_emi_entry_address = consys_emi_entry_address, + .consys_ic_set_xo_osc_ctrl = consys_set_xo_osc_ctrl, + .consys_ic_identify_adie = consys_identify_adie, + .consys_ic_wifi_ctrl_setting = consys_wifi_ctrl_setting, + .consys_ic_bus_timeout_config = consys_bus_timeout_config, + .consys_ic_set_access_emi_hw_mode = consys_set_access_emi_hw_mode, + .consys_ic_dump_gating_state = consys_dump_gating_state, + .consys_ic_sleep_info_enable_ctrl = consys_sleep_info_enable_ctrl, + .consys_ic_sleep_info_read_ctrl = consys_sleep_info_read_ctrl, + .consys_ic_sleep_info_clear = consys_sleep_info_clear, + .consys_ic_get_options = consys_get_options, +}; + +static const struct connlog_emi_config connsys_fw_log_parameter = { + .emi_offset = 0x36500, + .emi_size_total = (192*1024),/* 192KB */ + .emi_size_mcu = (16*1024), + .emi_size_wifi = (64*1024), + .emi_size_bt = (64*1024), + .emi_size_gps = (32*1024), +}; + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ +static OSAL_UNSLEEPABLE_LOCK g_pwr_off_lock; +static atomic_t g_power_on = ATOMIC_INIT(0); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +INT32 rom_patch_dl_flag = 1; +UINT32 gJtagCtrl; +UINT32 g_connsys_lp_dump_info[2]; + +#if WMT_DEVAPC_DBG_SUPPORT +static struct devapc_vio_callbacks devapc_handle = { + .id = INFRA_SUBSYS_CONN, + .debug_dump = consys_devapc_violation_cb, +}; +#endif + +#if CONSYS_ENALBE_SET_JTAG +#define JTAG_ADDR1_BASE 0x10005000 +#define JTAG_ADDR2_BASE 0x11c00000 +#endif + +INT32 mtk_wcn_consys_jtag_set_for_mcu(VOID) +{ +#if 0 +#if CONSYS_ENALBE_SET_JTAG + INT32 ret = 0; + UINT32 tmp = 0; + PVOID addr = 0; + PVOID remap_addr1 = 0; + PVOID remap_addr2 = 0; + + if (gJtagCtrl) { + remap_addr1 = ioremap(JTAG_ADDR1_BASE, 0x1000); + if (remap_addr1 == 0) { + WMT_PLAT_PR_INFO("remap jtag_addr1 fail!\n"); + ret = -1; + goto error; + } + + remap_addr2 = ioremap(JTAG_ADDR2_BASE, 0x100); + if (remap_addr2 == 0) { + WMT_PLAT_PR_INFO("remap jtag_addr2 fail!\n"); + ret = -1; + goto error; + } + + WMT_PLAT_PR_INFO("WCN jtag set for mcu start...\n"); + switch (gJtagCtrl) { + case 1: + /* 7-wire jtag pinmux setting*/ + /* PAD AUX Function Selection */ + addr = remap_addr1 + 0x360; + tmp = readl(addr); + tmp = tmp & 0xfff0f; + tmp = tmp | 0x66600060; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + addr = remap_addr1 + 0x370; + tmp = readl(addr); + tmp = tmp & 0xfffff000; + tmp = tmp | 0x666; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + /* PAD Driving Selection */ + addr = remap_addr2 + 0x0; + tmp = readl(addr); + tmp = tmp & 0xf80001f8; + tmp = tmp | 0x36db603; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + /* PAD IES */ + addr = remap_addr2 + 0x10; + tmp = readl(addr); + tmp = tmp & 0xfffffe06; + tmp = tmp | 0xf1; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + break; + case 2: + /* 2-wire jtag pinmux setting*/ + addr = remap_addr1 + 0x400; + tmp = readl(addr); + tmp = tmp & 0xfffff00f; + tmp = tmp | 0x430; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + break; + default: + WMT_PLAT_PR_INFO("unsupported options!\n"); + } + + } +#endif + +error: + if (remap_addr1) + iounmap(remap_addr1); + if (remap_addr2) + iounmap(remap_addr2); + return ret; +#else + WMT_PLAT_PR_INFO("No support switch to JTAG!\n"); + + return 0; +#endif +} + +UINT32 mtk_wcn_consys_jtag_flag_ctrl(UINT32 en) +{ + WMT_PLAT_PR_INFO("%s jtag set for MCU\n", en ? "enable" : "disable"); + gJtagCtrl = en; + + return 0; +} + +static INT32 consys_clk_get_from_dts(struct platform_device *pdev) +{ + clk_scp_conn_main = devm_clk_get(&pdev->dev, "conn"); + if (IS_ERR(clk_scp_conn_main)) { + WMT_PLAT_PR_INFO("[CCF]cannot get clk_scp_conn_main clock.\n"); + return PTR_ERR(clk_scp_conn_main); + } + WMT_PLAT_PR_DBG("[CCF]clk_scp_conn_main=%p\n", clk_scp_conn_main); + + clk_infracfg_ao_ccif4_ap_cg = devm_clk_get(&pdev->dev, "ccif"); + if (IS_ERR(clk_infracfg_ao_ccif4_ap_cg)) { + WMT_PLAT_PR_INFO("[CCF]cannot get clk_infracfg_ao_ccif4_ap_cg clock.\n"); + return PTR_ERR(clk_infracfg_ao_ccif4_ap_cg); + } + WMT_PLAT_PR_DBG("[CCF]clk_infracfg_ao_ccif4_ap_cg=%p\n", clk_infracfg_ao_ccif4_ap_cg); + + return 0; +} + +static INT32 consys_pmic_get_from_dts(struct platform_device *pdev) +{ +#if CONSYS_PMIC_CTRL_ENABLE + reg_VCN18 = regulator_get(&pdev->dev, "vcn18"); + if (!reg_VCN18) + WMT_PLAT_PR_INFO("Regulator_get VCN_1V8 fail\n"); + reg_VCN13 = regulator_get(&pdev->dev, "vcn13"); + if (!reg_VCN13) + WMT_PLAT_PR_INFO("Regulator_get VCN_1V3 fail\n"); + reg_VCN33_1_BT = regulator_get(&pdev->dev, "vcn33_1_bt"); + if (!reg_VCN33_1_BT) + WMT_PLAT_PR_INFO("Regulator_get VCN33_1_BT fail\n"); + reg_VCN33_1_WIFI = regulator_get(&pdev->dev, "vcn33_1_wifi"); + if (!reg_VCN33_1_WIFI) + WMT_PLAT_PR_INFO("Regulator_get VCN33_1_WIFI fail\n"); + reg_VCN33_2_WIFI = regulator_get(&pdev->dev, "vcn33_2_wifi"); + if (!reg_VCN33_2_WIFI) + WMT_PLAT_PR_INFO("Regulator_get VCN33_2_WIFI fail\n"); +#endif + + return 0; +} + +static INT32 consys_co_clock_type(VOID) +{ + return 0; +} + +static INT32 consys_clock_buffer_ctrl(MTK_WCN_BOOL enable) +{ +#if 0 + if (enable) + KERNEL_clk_buf_ctrl(CLK_BUF_CONN, true); /*open XO_WCN*/ + else + KERNEL_clk_buf_ctrl(CLK_BUF_CONN, false); /*close XO_WCN*/ +#endif + return 0; +} + +static VOID consys_set_if_pinmux(MTK_WCN_BOOL enable) +{ + UINT8 *consys_if_pinmux_reg_base = NULL; + UINT8 *consys_if_pinmux_driving_base = NULL; + + /* Switch D die pinmux for connecting A die */ + consys_if_pinmux_reg_base = ioremap_nocache(CONSYS_IF_PINMUX_REG_BASE, 0x1000); + if (!consys_if_pinmux_reg_base) { + WMT_PLAT_PR_INFO("consys_if_pinmux_reg_base(%x) ioremap fail\n", + CONSYS_IF_PINMUX_REG_BASE); + return; + } + + consys_if_pinmux_driving_base = ioremap_nocache(CONSYS_IF_PINMUX_DRIVING_BASE, 0x100); + if (!consys_if_pinmux_driving_base) { + WMT_PLAT_PR_INFO("consys_if_pinmux_driving_base(%x) ioremap fail\n", + CONSYS_IF_PINMUX_DRIVING_BASE); + iounmap(consys_if_pinmux_reg_base); + return; + } + + if (enable) { + CONSYS_REG_WRITE(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_01_OFFSET, + (CONSYS_REG_READ(consys_if_pinmux_reg_base + + CONSYS_IF_PINMUX_01_OFFSET) & + CONSYS_IF_PINMUX_01_MASK) | CONSYS_IF_PINMUX_01_VALUE); + CONSYS_REG_WRITE(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_02_OFFSET, + (CONSYS_REG_READ(consys_if_pinmux_reg_base + + CONSYS_IF_PINMUX_02_OFFSET) & + CONSYS_IF_PINMUX_02_MASK) | CONSYS_IF_PINMUX_02_VALUE); + /* set pinmux driving to 2mA */ + CONSYS_REG_WRITE(consys_if_pinmux_driving_base + CONSYS_IF_PINMUX_DRIVING_OFFSET_1, + (CONSYS_REG_READ(consys_if_pinmux_driving_base + + CONSYS_IF_PINMUX_DRIVING_OFFSET_1) & + CONSYS_IF_PINMUX_DRIVING_MASK_1) | CONSYS_IF_PINMUX_DRIVING_VALUE_1); + CONSYS_REG_WRITE(consys_if_pinmux_driving_base + CONSYS_IF_PINMUX_DRIVING_OFFSET_2, + (CONSYS_REG_READ(consys_if_pinmux_driving_base + + CONSYS_IF_PINMUX_DRIVING_OFFSET_2) & + CONSYS_IF_PINMUX_DRIVING_MASK_2) | CONSYS_IF_PINMUX_DRIVING_VALUE_2); +#if CLK_CTRL_TCXOENA_REQ + if (wmt_plat_soc_co_clock_flag_get() == 0) { + CONSYS_REG_WRITE(consys_if_pinmux_reg_base + CONSYS_CLOCK_TCXO_MODE_OFFSET, + (CONSYS_REG_READ(consys_if_pinmux_reg_base + CONSYS_CLOCK_TCXO_MODE_OFFSET) & + CONSYS_CLOCK_TCXO_MODE_MASK) | CONSYS_CLOCK_TCXO_MODE_VALUE); + WMT_PLAT_PR_INFO("set GPIO137 pinmux for TCXO mode (Aux5)\n"); + } +#endif + } else { + CONSYS_REG_WRITE(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_01_OFFSET, + CONSYS_REG_READ(consys_if_pinmux_reg_base + + CONSYS_IF_PINMUX_01_OFFSET) & CONSYS_IF_PINMUX_01_MASK); + CONSYS_REG_WRITE(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_02_OFFSET, + CONSYS_REG_READ(consys_if_pinmux_reg_base + + CONSYS_IF_PINMUX_02_OFFSET) & CONSYS_IF_PINMUX_02_MASK); +#if CLK_CTRL_TCXOENA_REQ + if (wmt_plat_soc_co_clock_flag_get() == 0) { + CONSYS_REG_WRITE(consys_if_pinmux_reg_base + CONSYS_CLOCK_TCXO_MODE_OFFSET, + CONSYS_REG_READ(consys_if_pinmux_reg_base + CONSYS_CLOCK_TCXO_MODE_OFFSET) & + CONSYS_CLOCK_TCXO_MODE_MASK); + } +#endif + } + + iounmap(consys_if_pinmux_reg_base); + iounmap(consys_if_pinmux_driving_base); +} + +static VOID consys_hw_reset_bit_set(MTK_WCN_BOOL enable) +{ + UINT32 consys_ver_id = 0; + UINT32 cnt = 0; + UINT8 *consys_reg_base = NULL; + + if (enable) { + /*3.assert CONNSYS CPU SW reset 0x10007018 "[12]=1'b1 [31:24]=8'h88 (key)" */ + CONSYS_REG_WRITE((conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET), + CONSYS_REG_READ(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET) | + CONSYS_CPU_SW_RST_BIT | CONSYS_CPU_SW_RST_CTRL_KEY); + } else { + /*16.deassert CONNSYS CPU SW reset 0x10007018 "[12]=1'b0 [31:24] =8'h88 (key)" */ + CONSYS_REG_WRITE(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET, + (CONSYS_REG_READ(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET) & + ~CONSYS_CPU_SW_RST_BIT) | CONSYS_CPU_SW_RST_CTRL_KEY); + /* check CONNSYS power-on completion + * (polling "0x8000_0600[31:0]" == 0x1D1E and each polling interval is "1ms") + * (apply this for guarantee that CONNSYS CPU goes to "cos_idle_loop") + */ + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_COM_REG0); + while (consys_ver_id != 0x1D1E) { + if (cnt > 10) + break; + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_COM_REG0); + WMT_PLAT_PR_INFO("0x18002600(0x%x)\n", consys_ver_id); + WMT_PLAT_PR_INFO("0x1800216c(0x%x)\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_SW_DBG_CTL)); + WMT_PLAT_PR_INFO("0x18007104(0x%x)\n", + CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + + CONSYS_CPUPCR_OFFSET)); + msleep(20); + cnt++; + } + + if (mtk_wcn_consys_get_adie_chipid() == SECONDARY_ADIE) { + /* if(MT6635) CONN_WF_CTRL2 swtich to CONN mode */ + consys_reg_base = ioremap_nocache(CONSYS_IF_PINMUX_REG_BASE, 0x1000); + if (!consys_reg_base) { + WMT_PLAT_PR_INFO("consys_if_pinmux_reg_base(%x) ioremap fail\n", + CONSYS_IF_PINMUX_REG_BASE); + return; + } + CONSYS_REG_WRITE(consys_reg_base + CONSYS_WF_CTRL2_03_OFFSET, + (CONSYS_REG_READ(consys_reg_base + CONSYS_WF_CTRL2_03_OFFSET) & + CONSYS_WF_CTRL2_03_MASK) | CONSYS_WF_CTRL2_CONN_MODE); + iounmap(consys_reg_base); + } + } +} + +static VOID consys_hw_spm_clk_gating_enable(VOID) +{ + /* turn on SPM clock (apply this for SPM's CONNSYS power control related CR accessing) */ + CONSYS_REG_WRITE((conn_reg.spm_base + CONSYS_PWRON_CONFG_EN_OFFSET), + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWRON_CONFG_EN_OFFSET) | + CONSYS_SPM_PWR_ON_CLK_BIT | CONSYS_SPM_PWR_ON_CLK_CTRL_KEY); +} + +static INT32 consys_hw_power_ctrl(MTK_WCN_BOOL enable) +{ +#if CONSYS_PWR_ON_OFF_API_AVAILABLE + INT32 iRet = 0; +#else + INT32 value = 0; + INT32 i = 0; +#endif + + if (enable) { +#if CONSYS_PWR_ON_OFF_API_AVAILABLE + iRet = clk_prepare_enable(clk_infracfg_ao_ccif4_ap_cg); + if (iRet) { + WMT_PLAT_PR_INFO("clk_prepare_enable(clk_infracfg_ao_ccif4_ap_cg) fail(%d)\n", iRet); + return iRet; + } + WMT_PLAT_PR_DBG("clk_prepare_enable(clk_infracfg_ao_ccif4_ap_cg) ok\n"); + + iRet = clk_prepare_enable(clk_scp_conn_main); + if (iRet) { + WMT_PLAT_PR_INFO("clk_prepare_enable(clk_scp_conn_main) fail(%d)\n", iRet); + return iRet; + } + WMT_PLAT_PR_DBG("clk_prepare_enable(clk_scp_conn_main) ok\n"); + + if (conn_reg.infra_ao_pericfg_base != 0) { + WMT_PLAT_PR_DBG("CON_STA_REG = %x\n", + CONSYS_REG_READ( + conn_reg.infra_ao_pericfg_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG)); + + /* Set CON_PWR_ON bit (CON_STA_REG[0]) */ + CONSYS_REG_WRITE(conn_reg.infra_ao_pericfg_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG, + 0x00000001); + + WMT_PLAT_PR_DBG("CON_STA_REG = %x\n", + CONSYS_REG_READ( + conn_reg.infra_ao_pericfg_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG)); + } +#else + /*write assert "conn_top_on" primary part power on, + *set "connsys_on_domain_pwr_on"=1 + */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_SPM_PWR_ON_BIT); + + /*read check "conn_top_on" primary part power status, + *check "connsys_on_domain_pwr_ack"=1 + */ + value = CONSYS_PWR_ON_ACK_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_OFFSET); + i = 0; + while (value == 0 && i < 10) { + value = CONSYS_PWR_ON_ACK_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_OFFSET); + udelay(500); + i++; + } + if (value == 0) + WMT_PLAT_PR_INFO("[POS polling info] >> check connsys_on_domain_pwr_ack status fail\n"); + + /*write assert "conn_top_on" secondary part power on, + *set "connsys_on_domain_pwr_on_s"=1 + */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_SPM_PWR_ON_S_BIT); + + /*read check "conn_top_on" secondary part power status, + *check "connsys_on_domain_pwr_ack_s"=1 + */ + value = CONSYS_PWR_ON_ACK_S_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_S_OFFSET); + i = 0; + while (value == 0 && i < 10) { + value = CONSYS_PWR_ON_ACK_S_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_S_OFFSET); + udelay(500); + i++; + } + if (value == 0) + WMT_PLAT_PR_INFO("[POS polling info] >> check connsys_on_domain_pwr_ack_s status fail\n"); + + /*write turn on AP-to-CONNSYS bus clock, set "conn_clk_dis"=0 (apply this for bus + *clock toggling) + */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) & + ~CONSYS_CLK_CTRL_BIT); + + /*wait 1us*/ + udelay(1); + + /*de-assert "conn_top_on" isolation, set "connsys_iso_en"=0 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) & + ~CONSYS_SPM_PWR_ISO_S_BIT); + + + /*de-assert CONNSYS S/W reset (TOP RGU CR), set "ap_sw_rst_b"=1 */ + CONSYS_REG_WRITE(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET, + (CONSYS_REG_READ(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET) & + ~CONSYS_SW_RST_BIT) | CONSYS_CPU_SW_RST_CTRL_KEY); + + /*de-assert CONNSYS S/W reset (SPM CR), set "ap_sw_rst_b"=1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) & + CONSYS_SPM_PWR_RST_BIT); + + /* check "conn_top_off" primary part power status, + * check "connsys_off_domain_pwr_ack"=1 + * (polling "10 times" and each polling interval is "0.5ms") + */ + value = CONSYS_SPM_CON_TOP_OFF_CHECK_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_SPM_CON_TOP_OFF_CHECK_OFFSET); + i = 0; + while (value == 0 && i < 10) { + value = CONSYS_SPM_CON_TOP_OFF_CHECK_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_SPM_CON_TOP_OFF_CHECK_OFFSET); + udelay(500); + i++; + } + if (value == 0) + WMT_PLAT_PR_INFO("[POS polling info] >> check connsys_off_domain_pwr_ack status fail\n"); + + /*wait 0.5ms*/ + udelay(500); + + /*Turn off AHB RX bus sleep protect (AP2CONN AHB Bus protect) + *(apply this for INFRA AHB bus accessing when CONNSYS had been turned on) + */ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AHB_RX_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AHB_RX_PROT_EN_OFFSET) & + CONSYS_AHB_RX_PROT_MASK); + + value = ~CONSYS_AHB_RX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AHB_RX_PROT_STA_OFFSET); + i = 0; + while (value == 0 && i < 10) { + value = ~CONSYS_AHB_RX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AHB_RX_PROT_STA_OFFSET); + i++; + } + if (value == 0) + WMT_PLAT_PR_INFO("[POS polling info] >> check AHB RX bus sleep protect turn off fail\n"); + + /*Turn off AXI Rx bus sleep protect (CONN2AP AXI Rx Bus protect) + *(disable sleep protection when CONNSYS had been turned on) + */ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AXI_RX_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AXI_RX_PROT_EN_OFFSET) & + CONSYS_AXI_RX_PROT_MASK); + + value = ~CONSYS_AXI_RX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AXI_RX_PROT_STA_OFFSET); + i = 0; + while (value == 0 && i < 10) { + value = ~CONSYS_AXI_RX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AXI_RX_PROT_STA_OFFSET); + i++; + } + if (value == 0) + WMT_PLAT_PR_INFO("[POS polling info] >> check AXI Rx bus sleep protect turn off fail\n"); + + /*Turn off AXI TX bus sleep protect (CONN2AP AXI Tx Bus protect) + *(disable sleep protection when CONNSYS had been turned on) + */ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AXI_RX_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AXI_RX_PROT_EN_OFFSET) & + CONSYS_AXI_TX_PROT_MASK); + + value = ~CONSYS_AXI_TX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AXI_RX_PROT_STA_OFFSET); + i = 0; + while (value == 0 && i < 10) { + value = ~CONSYS_AXI_TX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AXI_RX_PROT_STA_OFFSET); + i++; + } + if (value == 0) + WMT_PLAT_PR_INFO("[POS polling info] >> check AXI Tx bus sleep protect turn off fail\n"); + + /*Turn off AHB TX bus sleep protect (AP2CONN AHB Bus protect) + *(apply this for INFRA AHB bus accessing when CONNSYS had been turned on) + */ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AXI_RX_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AXI_RX_PROT_EN_OFFSET) & + CONSYS_AHB_TX_PROT_MASK); + + value = ~CONSYS_AHB_TX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AXI_RX_PROT_STA_OFFSET); + i = 0; + while (value == 0 && i < 10) { + value = ~CONSYS_AHB_TX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AXI_RX_PROT_STA_OFFSET); + i++; + } + if (value == 0) + WMT_PLAT_PR_INFO("[POS polling info] >> check AHB TX bus sleep protect turn off fail\n"); +#endif /* CONSYS_PWR_ON_OFF_API_AVAILABLE */ + + atomic_set(&g_power_on, 1); + /*wait 5ms*/ + mdelay(5); + } else { + osal_lock_unsleepable_lock(&g_pwr_off_lock); + atomic_set(&g_power_on, 0); + osal_unlock_unsleepable_lock(&g_pwr_off_lock); + +#if CONSYS_PWR_ON_OFF_API_AVAILABLE + if (conn_reg.infra_ao_pericfg_base != 0) { + WMT_PLAT_PR_DBG("CON_STA_REG = %x\n", + CONSYS_REG_READ( + conn_reg.infra_ao_pericfg_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG)); + + /* Clean CON_STA_REG + * when power off or reset connsys + */ + CONSYS_REG_WRITE((conn_reg.infra_ao_pericfg_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG), 0); + + WMT_PLAT_PR_DBG("CON_STA_REG = %x\n", + CONSYS_REG_READ( + conn_reg.infra_ao_pericfg_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG)); + } + + clk_disable_unprepare(clk_scp_conn_main); + WMT_PLAT_PR_DBG("clk_disable_unprepare(clk_scp_conn_main) calling\n"); + + /* Clean CCIF4 ACK status */ + /* Wait 100us to make sure all ongoing tx interrupt could be + * reset. + * According to profiling result, the time between read + * register and send tx interrupt is less than 20 us. + */ + udelay(100); + if (conn_reg.ap_pccif4_base != 0) { + CONSYS_REG_WRITE((conn_reg.ap_pccif4_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PCCIF_ACK_OFFSET), + 0xFF); + WMT_PLAT_PR_DBG("AP_PCCIF_ACK = %x\n", + CONSYS_REG_READ( + conn_reg.ap_pccif4_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PCCIF_ACK_OFFSET)); + } + + clk_disable_unprepare(clk_infracfg_ao_ccif4_ap_cg); + WMT_PLAT_PR_DBG("clk_disable_unprepare(clk_infracfg_ao_ccif4_ap_cg) calling\n"); + +#else + /* Turn on AHB bus sleep protect (AP2CONN AHB Bus protect) + * (apply this for INFRA AXI bus protection to prevent bus hang + * when CONNSYS had been turned off) + */ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AHBAXI_PROT_EN_OFFSET) & + CONSYS_AP2CONN_PROT_MASK); + value = CONSYS_AP2CONN_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_STA_OFFSET); + i = 0; + while (value == CONSYS_AP2CONN_PROT_MASK || i > 10) { + value = CONSYS_AP2CONN_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AHBAXI_PROT_STA_OFFSET); + i++; + } + /* Turn on AXI Tx bus sleep protect (CONN2AP AXI Tx Bus protect) + * (apply this for INFRA AXI bus protection to prevent bus hang + * when CONNSYS had been turned off) + * Note : Should turn on AXI Tx sleep protection first. + */ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AHBAXI_PROT_EN_OFFSET) & + CONSYS_TX_PROT_MASK); + value = CONSYS_TX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_STA_OFFSET); + i = 0; + while (value == CONSYS_TX_PROT_MASK || i > 10) { + value = CONSYS_TX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AHBAXI_PROT_STA_OFFSET); + i++; + } + /* Turn on AXI Rx bus sleep protect (CONN2AP AXI RX Bus protect) + * (apply this for INFRA AXI bus protection to prevent bus hang + * when CONNSYS had been turned off) + * Note : Should turn on AXI Rx sleep protection + * after AXI Tx sleep protection has been turn on. + */ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AHBAXI_PROT_EN_OFFSET) & + CONSYS_RX_PROT_MASK); + value = CONSYS_RX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_STA_OFFSET); + i = 0; + while (value == CONSYS_RX_PROT_MASK || i > 10) { + value = CONSYS_RX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AHBAXI_PROT_STA_OFFSET); + i++; + } + + /*assert "conn_top_on" isolation, set "connsys_iso_en"=1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_SPM_PWR_ISO_S_BIT); + /*assert CONNSYS S/W reset (TOP RGU CR), set "ap_sw_rst_b"=0 */ + CONSYS_REG_WRITE(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET, + (CONSYS_REG_READ(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET) & + CONSYS_SW_RST_BIT) | CONSYS_CPU_SW_RST_CTRL_KEY); + /*assert CONNSYS S/W reset (SPM CR), set "ap_sw_rst_b"=0 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + ~CONSYS_SPM_PWR_RST_BIT); + /*write conn_clk_dis=1, disable connsys clock 0x1000632C [4] 1'b1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_CLK_CTRL_BIT); + /*wait 1us */ + udelay(1); + /*write conn_top1_pwr_on=0, power off conn_top1 0x1000632C [3:2] 2'b00 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) & + ~(CONSYS_SPM_PWR_ON_BIT | CONSYS_SPM_PWR_ON_S_BIT)); +#endif /* CONSYS_PWR_ON_OFF_API_AVAILABLE */ + } + +#if CONSYS_PWR_ON_OFF_API_AVAILABLE + return iRet; +#else + return 0; +#endif +} + +static INT32 consys_ahb_clock_ctrl(MTK_WCN_BOOL enable) +{ + return 0; +} + +static INT32 polling_consys_chipid(VOID) +{ + UINT32 retry = 10; + UINT32 consys_ver_id = 0; + UINT32 consys_hw_ver = 0; + UINT32 consys_fw_ver = 0; + + if ((conn_reg.mcu_top_misc_off_base == 0) || (conn_reg.mcu_base == 0)) + return 0; + + /*12.poll CONNSYS CHIP ID until chipid is returned 0x10070000 */ + while (retry-- > 0) { + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_top_misc_off_base + + CONSYS_IP_VER_OFFSET); + if (consys_ver_id == CONSYS_IP_VER_ID) { + WMT_PLAT_PR_INFO("retry(%d)consys version id(0x%08x)\n", + retry, consys_ver_id); + consys_hw_ver = CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HW_ID_OFFSET); + WMT_PLAT_PR_INFO("consys HW version id(0x%x)\n", consys_hw_ver & 0xFFFF); + consys_fw_ver = CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_FW_ID_OFFSET); + WMT_PLAT_PR_INFO("consys FW version id(0x%x)\n", consys_fw_ver & 0xFFFF); + + /* TODO: NEW API for ROM patch download */ + if (mtk_wcn_consys_get_adie_chipid()) + consys_dl_rom_patch(consys_ver_id, consys_fw_ver); + break; + } + WMT_PLAT_PR_INFO("Read CONSYS version id(0x%08x)", consys_ver_id); + msleep(20); + } + + if (retry <= 0) { +#if defined(KERNEL_clk_buf_show_status_info) + KERNEL_clk_buf_show_status_info(); /* dump clock buffer */ +#endif + return -1; + } + + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_top_misc_off_base + CONSYS_CONF_ID_OFFSET); + WMT_PLAT_PR_INFO("consys configuration id(0x%x)\n", consys_ver_id & 0xF); + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HW_ID_OFFSET); + WMT_PLAT_PR_INFO("consys HW version id(0x%x)\n", consys_ver_id & 0xFFFF); + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_FW_ID_OFFSET); + WMT_PLAT_PR_INFO("consys FW version id(0x%x)\n", consys_ver_id & 0xFFFF); + + return 0; +} + +static VOID consys_set_access_emi_hw_mode(VOID) +{ + if (conn_reg.mcu_top_misc_on_base == 0) + return; + + /* conn2ap access EMI hw mode with slpprotect ctrl */ + CONSYS_REG_WRITE(conn_reg.mcu_top_misc_on_base + CONSYS_ACCESS_EMI_HW_MODE_OFFSET, + CONSYS_REG_READ(conn_reg.mcu_top_misc_on_base + CONSYS_ACCESS_EMI_HW_MODE_OFFSET) | + (0x1 << 0)); +} + +static VOID consys_acr_reg_setting(VOID) +{ + WMT_PLAT_PR_INFO("No need to do acr"); +} + +static VOID consys_afe_reg_setting(VOID) +{ + UINT8 *consys_afe_wbg_reg_base = NULL; + /* AFE WBG CR (if needed), + * note that this CR must be backuped and restored by command batch engine + * 0x180B_3010[31:0] 0x00000000 + * 0x180B_3018[31:0] 0x144B0160 + * 0x180B_3040[31:0] 0x10990C13 + * 0x180B_3058[31:0] 0xCD258051 + * 0x180B_3078[31:0] 0xC5258251 + * 0x180B_3094[31:0] 0xC5258251 + * 0x180B_3100[31:0] 0x10990C13 + */ + consys_afe_wbg_reg_base = ioremap_nocache(CONSYS_AFE_WBG_REG_BASE, 0x200); + if (consys_afe_wbg_reg_base) { + CONSYS_REG_WRITE(consys_afe_wbg_reg_base + CONSYS_AFE_WBG_REG_AFE_01_OFFSET, + CONSYS_AFE_WBG_REG_AFE_01_VALUE); + CONSYS_REG_WRITE(consys_afe_wbg_reg_base + CONSYS_AFE_WBG_REG_RCK_01_OFFSET, + CONSYS_AFE_WBG_REG_RCK_01_VALUE); + CONSYS_REG_WRITE(consys_afe_wbg_reg_base + CONSYS_AFE_WBG_REG_GL1_01_OFFSET, + CONSYS_AFE_WBG_REG_GL1_01_VALUE); + CONSYS_REG_WRITE(consys_afe_wbg_reg_base + CONSYS_AFE_WBG_REG_BT_TX_03_OFFSET, + CONSYS_AFE_WBG_REG_BT_TX_03_VALUE); + CONSYS_REG_WRITE(consys_afe_wbg_reg_base + CONSYS_AFE_WBG_REG_WF0_TX_03_OFFSET, + CONSYS_AFE_WBG_REG_WF0_TX_03_VALUE); + CONSYS_REG_WRITE(consys_afe_wbg_reg_base + CONSYS_AFE_WBG_REG_WF1_TX_03_OFFSET, + CONSYS_AFE_WBG_REG_WF1_TX_03_VALUE); + CONSYS_REG_WRITE(consys_afe_wbg_reg_base + CONSYS_AFE_WBG_REG_GL5_01_OFFSET, + CONSYS_AFE_WBG_REG_GL5_01_VALUE); + iounmap(consys_afe_wbg_reg_base); + } else { + WMT_PLAT_PR_INFO("CONSYS_AFE_WBG_REG_BASE(0x%x) ioremap fail!\n", + CONSYS_AFE_WBG_REG_BASE); + } +} + +static VOID consys_emi_entry_address(VOID) +{ + /* EMI entry address (define by CONNSYS MCU SE) + * 0x1800_2504[31:0] 0xF011_0000 + * 0x1800_2508[31:0] 0xF01D_0000 + */ + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_EMI_BT_ENTRY_OFFSET, + CONSYS_EMI_BT_ENTRY_ADDRESS); + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_EMI_WIFI_ENTRY_OFFSET, + CONSYS_EMI_WIFI_ENTRY_ADDRESS); +} + +static VOID consys_set_xo_osc_ctrl(VOID) +{ + UINT8 *consys_reg_base = NULL; + UINT32 value = 0; + UINT32 xo_value; + + consys_reg_base = ioremap_nocache(CONSYS_COCLOCK_STABLE_TIME_BASE, 0x100); + if (consys_reg_base) { + if (!consys_is_rc_mode_enable()) { + /* set CR "XO initial stable time" and "XO bg stable time" + * to optimize the wakeup time after sleep + * clear "source clock enable ack to XO state" mask + */ + CONSYS_REG_WRITE(consys_reg_base + CONSYS_COCLOCK_RC_CTL_0_TOP_OSC_RC_EN_OFFSET, + CONSYS_REG_READ(consys_reg_base + CONSYS_COCLOCK_RC_CTL_0_TOP_OSC_RC_EN_OFFSET) & + ~CONSYS_COCLOCK_RC_CTL_0_TOP_OSC_RC_EN_BIT); + + if (wmt_plat_soc_co_clock_flag_get()) { + value = CONSYS_REG_READ(consys_reg_base); + value = (value & CONSYS_COCLOCK_STABLE_TIME_MASK) | CONSYS_COCLOCK_STABLE_TIME; + CONSYS_REG_WRITE(consys_reg_base, value); + + value = CONSYS_REG_READ(consys_reg_base + CONSYS_COCLOCK_ACK_ENABLE_OFFSET); + value = (value & CONSYS_COCLOCK_ACK_ENABLE_MAST) | CONSYS_COCLOCK_ACK_ENABLE_VALUE; + value = value & (~CONSYS_COCLOCK_ACK_ENABLE_BIT); + CONSYS_REG_WRITE(consys_reg_base + CONSYS_COCLOCK_ACK_ENABLE_OFFSET, value); + } + } else { + if (wmt_plat_soc_co_clock_flag_get()) + xo_value = CONSYS_COCLOCK_RC_CTL_1_XO_VALUE; + else + xo_value = CONSYS_COCLOCK_RC_CTL_1_XO_TCXO_VALUE; + + CONSYS_REG_WRITE(consys_reg_base + CONSYS_COCLOCK_RC_CTL_1_GPS_XO_OFFSET, + xo_value); + + CONSYS_REG_WRITE(consys_reg_base + CONSYS_COCLOCK_RC_CTL_0_GPS_ACK_OFFSET, + CONSYS_REG_READ(consys_reg_base + CONSYS_COCLOCK_RC_CTL_0_GPS_ACK_OFFSET) & + ~CONSYS_COCLOCK_RC_CTL_0_ACK_BIT); + + CONSYS_REG_WRITE(consys_reg_base + CONSYS_COCLOCK_RC_CTL_1_BT_XO_OFFSET, + xo_value); + + CONSYS_REG_WRITE(consys_reg_base + CONSYS_COCLOCK_RC_CTL_0_BT_ACK_OFFSET, + CONSYS_REG_READ(consys_reg_base + CONSYS_COCLOCK_RC_CTL_0_BT_ACK_OFFSET) & + ~CONSYS_COCLOCK_RC_CTL_0_ACK_BIT); + + CONSYS_REG_WRITE(consys_reg_base + CONSYS_COCLOCK_RC_CTL_1_WF_XO_OFFSET, + xo_value); + + CONSYS_REG_WRITE(consys_reg_base + CONSYS_COCLOCK_RC_CTL_0_WF_ACK_OFFSET, + CONSYS_REG_READ(consys_reg_base + CONSYS_COCLOCK_RC_CTL_0_WF_ACK_OFFSET) & + ~CONSYS_COCLOCK_RC_CTL_0_ACK_BIT); + + CONSYS_REG_WRITE(consys_reg_base + CONSYS_COCLOCK_RC_CTL_1_TOP_XO_OFFSET, + xo_value); + + CONSYS_REG_WRITE(consys_reg_base + CONSYS_COCLOCK_RC_CTL_0_TOP_ACK_OFFSET, + CONSYS_REG_READ(consys_reg_base + CONSYS_COCLOCK_RC_CTL_0_TOP_ACK_OFFSET) & + ~CONSYS_COCLOCK_RC_CTL_0_ACK_BIT); + + CONSYS_REG_WRITE(consys_reg_base + CONSYS_COCLOCK_RC_CTL_0_TOP_OSC_RC_EN_OFFSET, + CONSYS_REG_READ(consys_reg_base + CONSYS_COCLOCK_RC_CTL_0_TOP_OSC_RC_EN_OFFSET) | + CONSYS_COCLOCK_RC_CTL_0_GPS_OSC_RC_EN_BIT); + + CONSYS_REG_WRITE(consys_reg_base + CONSYS_COCLOCK_RC_CTL_0_TOP_OSC_RC_EN_OFFSET, + CONSYS_REG_READ(consys_reg_base + CONSYS_COCLOCK_RC_CTL_0_TOP_OSC_RC_EN_OFFSET) | + CONSYS_COCLOCK_RC_CTL_0_BT_OSC_RC_EN_BIT); + + CONSYS_REG_WRITE(consys_reg_base + CONSYS_COCLOCK_RC_CTL_0_TOP_OSC_RC_EN_OFFSET, + CONSYS_REG_READ(consys_reg_base + CONSYS_COCLOCK_RC_CTL_0_TOP_OSC_RC_EN_OFFSET) | + CONSYS_COCLOCK_RC_CTL_0_WF_OSC_RC_EN_BIT); + + CONSYS_REG_WRITE(consys_reg_base + CONSYS_COCLOCK_RC_CTL_0_TOP_OSC_RC_EN_OFFSET, + CONSYS_REG_READ(consys_reg_base + CONSYS_COCLOCK_RC_CTL_0_TOP_OSC_RC_EN_OFFSET) | + CONSYS_COCLOCK_RC_CTL_0_TOP_OSC_RC_EN_BIT_2); + + CONSYS_REG_WRITE(consys_reg_base + CONSYS_COCLOCK_RC_CTL_0_TOP_OSC_RC_EN_OFFSET, + CONSYS_REG_READ(consys_reg_base + CONSYS_COCLOCK_RC_CTL_0_TOP_OSC_RC_EN_OFFSET) & + ~CONSYS_COCLOCK_RC_CTL_0_OSC_LEGACY_EN_BIT); + } + iounmap(consys_reg_base); + } else { + WMT_PLAT_PR_INFO("connsys co_clock stable time base(0x%x) ioremap fail!\n", + CONSYS_COCLOCK_STABLE_TIME_BASE); + } +} + +static VOID consys_identify_adie(VOID) +{ + UINT8 *consys_reg_base = NULL; + + consys_reg_base = ioremap_nocache(CONSYS_IDENTIFY_ADIE_CR_ADDRESS, 0x100); + if (consys_reg_base) { + if (mtk_wcn_consys_get_adie_chipid() == SECONDARY_ADIE) + CONSYS_REG_WRITE(consys_reg_base, + CONSYS_REG_READ(consys_reg_base) & + ~CONSYS_IDENTIFY_ADIE_ENABLE_BIT); + else + CONSYS_REG_WRITE(consys_reg_base, + CONSYS_REG_READ(consys_reg_base) | + CONSYS_IDENTIFY_ADIE_ENABLE_BIT); + iounmap(consys_reg_base); + } else { + WMT_PLAT_PR_INFO("CONSYS_IDENTIFY_ADIE_CR_ADDRESS(0x%x) ioremap fail!\n", + CONSYS_IDENTIFY_ADIE_CR_ADDRESS); + } +} + +static VOID consys_wifi_ctrl_setting(VOID) +{ + UINT8 *reg_base = NULL; + + if (mtk_wcn_consys_get_adie_chipid() != SECONDARY_ADIE) + return; + + /* if(MT6635) + * CONN_WF_CTRL2 swtich to GPIO mode, GPIO output value + * before patch download swtich back to CONN mode. + */ + reg_base = ioremap_nocache(CONSYS_IF_PINMUX_REG_BASE, 0x1000); + if (reg_base) { + CONSYS_REG_WRITE(reg_base + CONSYS_WF_CTRL2_01_OFFSET, + (CONSYS_REG_READ(reg_base + CONSYS_WF_CTRL2_01_OFFSET) & + CONSYS_WF_CTRL2_01_MASK) | CONSYS_WF_CTRL2_01_VALUE); + CONSYS_REG_WRITE(reg_base + CONSYS_WF_CTRL2_02_OFFSET, + (CONSYS_REG_READ(reg_base + CONSYS_WF_CTRL2_02_OFFSET) & + CONSYS_WF_CTRL2_02_MASK) | CONSYS_WF_CTRL2_02_VALUE); + CONSYS_REG_WRITE(reg_base + CONSYS_WF_CTRL2_03_OFFSET, + (CONSYS_REG_READ(reg_base + CONSYS_WF_CTRL2_03_OFFSET) & + CONSYS_WF_CTRL2_03_MASK) | CONSYS_WF_CTRL2_GPIO_MODE); + iounmap(reg_base); + } else { + WMT_PLAT_PR_INFO("consys_if_pinmux_reg_base(0x%x) ioremap fail!\n", + CONSYS_IF_PINMUX_REG_BASE); + } +} + +static VOID consys_bus_timeout_config(VOID) +{ + UINT8 *consys_reg_base = NULL; + + /* connsys bus time out configure, enable AHB bus timeout */ + consys_reg_base = ioremap_nocache(CONSYS_AHB_TIMEOUT_EN_ADDRESS, 0x100); + if (consys_reg_base) { + CONSYS_REG_WRITE(consys_reg_base, CONSYS_AHB_TIMEOUT_EN_VALUE); + iounmap(consys_reg_base); + } else { + WMT_PLAT_PR_INFO("CONSYS_AHB_TIMEOUT_EN_ADDRESS(0x%x) ioremap fail!\n", + CONSYS_AHB_TIMEOUT_EN_ADDRESS); + } +} + + +static VOID consys_hw_vcn33_primary_rc_mode_enable(VOID) +{ + WMT_PLAT_PR_INFO("Turn on reg_VCN33_1_BT in RC mode\n"); + /* PMRC_EN[7][6][5][4] HW_OP_EN = 1, HW_OP_CFG = 0 */ + KERNEL_pmic_ldo_vcn33_1_lp(SRCLKEN7, 0, 1, HW_OFF); + KERNEL_pmic_ldo_vcn33_1_lp(SRCLKEN4, 0, 1, HW_OFF); + KERNEL_pmic_ldo_vcn33_1_lp(SRCLKEN6, 0, 1, HW_OFF); + KERNEL_pmic_ldo_vcn33_1_lp(SRCLKEN5, 0, 1, HW_OFF); + /* SW_LP =0 */ + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_1_LP, 0); + if (reg_VCN33_1_BT) { + regulator_set_voltage(reg_VCN33_1_BT, 3300000, 3300000); + if (regulator_enable(reg_VCN33_1_BT)) + WMT_PLAT_PR_INFO("WMT do WIFI PMIC on fail!\n"); + } +} + +static VOID consys_hw_vcn33_primary_legacy_mode_enable(VOID) +{ + WMT_PLAT_PR_INFO("Turn on reg_VCN33_1_BT in legacy mode\n"); + /* HW_OP_EN = 0, HW_OP_CFG = 0 */ + KERNEL_pmic_ldo_vcn33_1_lp(SRCLKEN0, 1, 1, HW_LP); + /* SW_LP =0 */ + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_1_LP, 0); + + /*Set VCN33_1_SW_EN as 1 and set votage as 3V3*/ + if (reg_VCN33_1_BT) { + regulator_set_voltage(reg_VCN33_1_BT, 3300000, 3300000); + if (regulator_enable(reg_VCN33_1_BT)) + WMT_PLAT_PR_INFO("WMT do WIFI PMIC on fail!\n"); + } +} +static VOID consys_hw_vcn13_secondary_rc_mode_enable(VOID) +{ + /* VCN13 */ + /* PMRC_EN[7][6][5][4] HW_OP_EN = 1, HW_OP_CFG = 0 */ + KERNEL_pmic_ldo_vcn13_lp(SRCLKEN7, 0, 1, HW_OFF); + KERNEL_pmic_ldo_vcn13_lp(SRCLKEN6, 0, 1, HW_OFF); + KERNEL_pmic_ldo_vcn13_lp(SRCLKEN5, 0, 1, HW_OFF); + KERNEL_pmic_ldo_vcn13_lp(SRCLKEN4, 0, 1, HW_OFF); + /* SW_LP =1 */ + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN13_LP, 0); + if (reg_VCN13) { + regulator_set_voltage(reg_VCN13, 1300000, 1300000); + if (regulator_enable(reg_VCN13)) + WMT_PLAT_PR_INFO("enable VCN13 fail\n"); + else + WMT_PLAT_PR_DBG("enable VCN13 ok\n"); + } +} +static VOID consys_hw_vcn13_secondary_legacy_mode_enable(VOID) +{ + /* HW_OP_EN = 1, HW_OP_CFG = 1 */ + KERNEL_pmic_ldo_vcn13_lp(SRCLKEN0, 1, 1, HW_LP); + /* SW_LP=0 */ + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN13_LP, 0); + + if (reg_VCN13) { + regulator_set_voltage(reg_VCN13, 1300000, 1300000); + if (regulator_enable(reg_VCN13)) + WMT_PLAT_PR_INFO("enable VCN13 fail\n"); + else + WMT_PLAT_PR_DBG("enable VCN13 ok\n"); + } +} + +static INT32 consys_hw_vcn18_ctrl(MTK_WCN_BOOL enable) +{ +#if CONSYS_PMIC_CTRL_ENABLE + if (enable) { + if (consys_is_rc_mode_enable()) { + /* RC mode */ + WMT_PLAT_PR_INFO("Turn on VCN18 in RC mode\n"); + /* VCN18 op_mode = 0 */ + /* PMRC_EN[7][6][5][4] HW_OP_EN = 1, HW_OP_CFG = 0 */ + KERNEL_pmic_ldo_vcn18_lp(SRCLKEN7, 0, 1, HW_OFF); + KERNEL_pmic_ldo_vcn18_lp(SRCLKEN6, 0, 1, HW_OFF); + KERNEL_pmic_ldo_vcn18_lp(SRCLKEN5, 0, 1, HW_OFF); + KERNEL_pmic_ldo_vcn18_lp(SRCLKEN4, 0, 1, HW_OFF); + + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN18_LP, 0); + /*Set VCN18_SW_EN as 1 and set votage as 1V8*/ + if (reg_VCN18) { + regulator_set_voltage(reg_VCN18, 1800000, 1800000); + if (regulator_enable(reg_VCN18)) + WMT_PLAT_PR_INFO("enable VCN18 fail\n"); + else + WMT_PLAT_PR_DBG("enable VCN18 ok\n"); + } + if (mtk_wcn_consys_get_adie_chipid() == PRIMARY_ADIE) + consys_hw_vcn33_primary_rc_mode_enable(); + else if (mtk_wcn_consys_get_adie_chipid() == SECONDARY_ADIE) + consys_hw_vcn13_secondary_rc_mode_enable(); + } else { + if (mtk_wcn_consys_get_adie_chipid() == PRIMARY_ADIE) { + WMT_PLAT_PR_INFO("Turn on VCN18 in legacy mode\n"); + /* HW_OP_EN = 1, HW_OP_CFG = 0 */ + KERNEL_pmic_ldo_vcn18_lp(SRCLKEN0, 1, 1, HW_LP); + /* SW_LP=0 */ + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN18_LP, 0); + } else if (mtk_wcn_consys_get_adie_chipid() == SECONDARY_ADIE) { + WMT_PLAT_PR_INFO("Turn on VCN18, VCN13 in legacy mode\n"); + /* HW_OP_EN = 1, HW_OP_CFG = 1 */ + KERNEL_pmic_ldo_vcn18_lp(SRCLKEN0, 1, 1, HW_LP); + /* SW_LP=0 */ + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN18_LP, 0); + } + /*Set VCN18_SW_EN as 1 and set votage as 1V8*/ + if (reg_VCN18) { + regulator_set_voltage(reg_VCN18, 1800000, 1800000); + if (regulator_enable(reg_VCN18)) + WMT_PLAT_PR_INFO("enable VCN18 fail\n"); + else + WMT_PLAT_PR_DBG("enable VCN18 ok\n"); + } + /* Legacy mode */ + if (mtk_wcn_consys_get_adie_chipid() == PRIMARY_ADIE) + consys_hw_vcn33_primary_legacy_mode_enable(); + else if (mtk_wcn_consys_get_adie_chipid() == SECONDARY_ADIE) + consys_hw_vcn13_secondary_legacy_mode_enable(); + } + } else { + if (mtk_wcn_consys_get_adie_chipid() == PRIMARY_ADIE) { + WMT_PLAT_PR_INFO("Turn off VCN33\n"); + if (reg_VCN33_1_BT) { + if (regulator_disable(reg_VCN33_1_BT)) + WMT_PLAT_PR_INFO("disable VCN33 fail!\n"); + } + } else if (mtk_wcn_consys_get_adie_chipid() == SECONDARY_ADIE) { + WMT_PLAT_PR_INFO("Turn off VCN13\n"); + if (reg_VCN13) { + if (regulator_disable(reg_VCN13)) + WMT_PLAT_PR_INFO("disable VCN13 fail!\n"); + } + } + /* delay 300us */ + udelay(300); + + WMT_PLAT_PR_INFO("Turn off VCN18\n"); + if (reg_VCN18) { + if (regulator_disable(reg_VCN18)) + WMT_PLAT_PR_INFO("disable VCN18 fail!\n"); + } + } +#endif + return 0; +} + +static VOID consys_vcn28_hw_mode_ctrl(UINT32 enable) +{ + /* 6635 not supported */ +} + +static INT32 consys_hw_vcn28_ctrl(UINT32 enable) +{ +#if CONSYS_PMIC_CTRL_ENABLE + if (mtk_wcn_consys_get_adie_chipid() == SECONDARY_ADIE) + /* 6635 not supported */ + return 0; + + if (consys_is_rc_mode_enable()) { + WMT_PLAT_PR_INFO("Configure reg_VCN33_2 in RC mode\n"); + /* HW_OP_EN = 1, HW_OP_CFG = 0 */ + KERNEL_pmic_ldo_vcn33_2_lp(SRCLKEN7, 0, enable, HW_OFF); + KERNEL_pmic_ldo_vcn33_2_lp(SRCLKEN4, 0, enable, HW_OFF); + if (wmt_plat_soc_co_clock_flag_get() == 0) { + KERNEL_pmic_ldo_vcn33_2_lp(SRCLKEN6, 0, enable, HW_OFF); + KERNEL_pmic_ldo_vcn33_2_lp(SRCLKEN5, 0, enable, HW_OFF); + } + /* SW_LP =0 */ + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_2_LP, 0); + if (reg_VCN33_2_WIFI) + regulator_set_voltage(reg_VCN33_2_WIFI, 2800000, 2800000); + } else { + if (enable) { + WMT_PLAT_PR_INFO("Turn on reg_VCN33_2_WIFI in legacy mode\n"); + /* HW_OP_EN = 1, HW_OP_CFG = 0 */ + KERNEL_pmic_ldo_vcn33_2_lp(SRCLKEN0, 1, 1, HW_OFF); + /* SW_LP =0 */ + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_2_LP, 0); + + /*Set VCN33_1_SW_EN as 1 and set votage as 2.8V*/ + if (reg_VCN33_2_WIFI) { + regulator_set_voltage(reg_VCN33_2_WIFI, 2800000, 2800000); + if (regulator_enable(reg_VCN33_2_WIFI)) + WMT_PLAT_PR_INFO("WMT do WIFI PMIC on fail!\n"); + } + } else { + if (reg_VCN33_2_WIFI) { + regulator_disable(reg_VCN33_2_WIFI); + WMT_PLAT_PR_INFO("turn off vcn33_2_WIFI\n"); + } + } + } +#endif + return 0; +} + +static INT32 consys_hw_bt_vcn33_ctrl(UINT32 enable) +{ +#if CONSYS_PMIC_CTRL_ENABLE + if (mtk_wcn_consys_get_adie_chipid() != SECONDARY_ADIE) + /* 6631 not supported */ + return 0; + if (enable) { + if (consys_is_rc_mode_enable()) { + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN18_LP, 0); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN13_LP, 0); + udelay(50); + } + + /* Set VS2 to 1.4625V */ + KERNEL_pmic_set_register_value(PMIC_RG_BUCK_VS2_VOSEL, 0x35); + + /* request VS2 to 1.4625V by VS2 VOTER (use bit 4) */ + KERNEL_pmic_set_register_value(PMIC_RG_BUCK_VS2_VOTER_EN_SET, 0x10); + + /* Set VS2 sleep voltage to 1.375V */ + KERNEL_pmic_set_register_value(PMIC_RG_BUCK_VS2_VOSEL_SLEEP, 0x2E); + + /* Set VCN13 to 1.37V */ + KERNEL_pmic_set_register_value(PMIC_RG_VCN13_VOCAL, 0x7); + + if (consys_is_rc_mode_enable()) { + WMT_PLAT_PR_INFO("Turn on reg_VCN33_1_BT in RC mode\n"); + /* PMRC_EN[6][5] HW_OP_EN = 1, HW_OP_CFG = 0 */ + KERNEL_pmic_ldo_vcn33_1_lp(SRCLKEN6, 0, 1, HW_OFF); + KERNEL_pmic_ldo_vcn33_1_lp(SRCLKEN5, 0, 1, HW_OFF); + /* SW_LP =0 */ + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_1_LP, 0); + if (reg_VCN33_1_BT) + regulator_set_voltage(reg_VCN33_1_BT, 3300000, 3300000); + + udelay(50); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN18_LP, 1); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN13_LP, 1); + + /* SW_EN=0 */ + /* For RC mode, we don't have to control VCN33_1 & VCN33_2 */ + /* regulator_disable(reg_VCN33_1_BT); */ + } else { + WMT_PLAT_PR_INFO("Turn on reg_VCN33_1_BT in legacy mode\n"); + /* HW_OP_EN = 1, HW_OP_CFG = 0 */ + KERNEL_pmic_ldo_vcn33_1_lp(SRCLKEN0, 1, 1, HW_OFF); + /* SW_LP =0 */ + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_1_LP, 0); + + /*Set VCN33_1_SW_EN as 1 and set votage as 3V3*/ + if (reg_VCN33_1_BT) { + regulator_set_voltage(reg_VCN33_1_BT, 3300000, 3300000); + if (regulator_enable(reg_VCN33_1_BT)) + WMT_PLAT_PR_INFO("WMT do WIFI PMIC on fail!\n"); + } + } + WMT_PLAT_PR_DBG("WMT do BT PMIC on\n"); + } else { + /*do BT PMIC off */ + if (consys_is_rc_mode_enable()) { + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN18_LP, 0); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN13_LP, 0); + udelay(50); + } + + /* restore VCN13 to 1.3V */ + KERNEL_pmic_set_register_value(PMIC_RG_VCN13_VOCAL, 0); + /* clear bit 4 of VS2 VOTER then VS2 can restore to 1.35V */ + KERNEL_pmic_set_register_value(PMIC_RG_BUCK_VS2_VOTER_EN_CLR, 0x10); + + /* Restore VS2 sleep voltage to 1.35V */ + KERNEL_pmic_set_register_value(PMIC_RG_BUCK_VS2_VOSEL_SLEEP, 0x2C); + + if (consys_is_rc_mode_enable()) { + udelay(50); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN18_LP, 1); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN13_LP, 1); + } else { + if (reg_VCN33_1_BT) + regulator_disable(reg_VCN33_1_BT); + } + WMT_PLAT_PR_DBG("WMT do BT PMIC off\n"); + } +#endif + return 0; +} + +static INT32 consys_hw_wifi_vcn33_ctrl(UINT32 enable) +{ +#if CONSYS_PMIC_CTRL_ENABLE + if (mtk_wcn_consys_get_adie_chipid() != SECONDARY_ADIE) + /* 6631 not supported */ + return 0; + if (enable) { + if (consys_is_rc_mode_enable()) { + WMT_PLAT_PR_INFO("Turn on reg_VCN33_1_WIFI in RC mode\n"); + /* PMRC_EN[6][5] HW_OP_EN = 1, HW_OP_CFG = 0 */ + KERNEL_pmic_ldo_vcn33_1_lp(SRCLKEN6, 0, 1, HW_OFF); + KERNEL_pmic_ldo_vcn33_1_lp(SRCLKEN5, 0, 1, HW_OFF); + + /* SW_LP =0 */ + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_1_LP, 0); + if (reg_VCN33_1_WIFI) + regulator_set_voltage(reg_VCN33_1_WIFI, 3300000, 3300000); + /* SW_EN=0 */ + /* For RC mode, we don't have to control VCN33_1 & VCN33_2 */ + /* regulator_disable(reg_VCN33_1_WIFI); */ + + WMT_PLAT_PR_INFO("Turn on reg_VCN33_2_WIFI in RC mode\n"); + + /* PMRC_EN[6] HW_OP_EN = 1, HW_OP_CFG = 0 */ + KERNEL_pmic_ldo_vcn33_2_lp(SRCLKEN6, 0, 1, HW_OFF); + + /* SW_LP =0 */ + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_2_LP, 0); + if (reg_VCN33_2_WIFI) + regulator_set_voltage(reg_VCN33_2_WIFI, 3300000, 3300000); + /* SW_EN=0 */ + /* For RC mode, we don't have to control VCN33_1 & VCN33_2 */ + /* regulator_disable(reg_VCN33_2_WIFI); */ + } else { + WMT_PLAT_PR_INFO("Turn on reg_VCN33_1_WIFI in legacy mode\n"); + /* HW_OP_EN = 1, HW_OP_CFG = 0 */ + KERNEL_pmic_ldo_vcn33_1_lp(SRCLKEN0, 1, 1, HW_OFF); + /* SW_LP =0 */ + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_1_LP, 0); + + /*Set VCN33_1_SW_EN as 1 and set votage as 3V3*/ + if (reg_VCN33_1_WIFI) { + regulator_set_voltage(reg_VCN33_1_WIFI, 3300000, 3300000); + if (regulator_enable(reg_VCN33_1_WIFI)) + WMT_PLAT_PR_INFO("WMT do WIFI PMIC on fail!\n"); + } + + WMT_PLAT_PR_INFO("Turn on reg_VCN33_2_WIFI in legacy mode\n"); + /* HW_OP_EN = 1, HW_OP_CFG = 0 */ + KERNEL_pmic_ldo_vcn33_2_lp(SRCLKEN0, 1, 1, HW_OFF); + /* SW_LP =0 */ + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_2_LP, 0); + + /*Set VCN33_2_SW_EN as 1 and set votage as 3V3*/ + if (reg_VCN33_2_WIFI) { + regulator_set_voltage(reg_VCN33_2_WIFI, 3300000, 3300000); + if (regulator_enable(reg_VCN33_2_WIFI)) + WMT_PLAT_PR_INFO("WMT do WIFI PMIC on fail!\n"); + } + } + WMT_PLAT_PR_DBG("WMT do WIFI PMIC on\n"); + } else { + /*do WIFI PMIC off */ + /*switch WIFI PALDO control from HW mode to SW mode:0x418[14]-->0x0 */ + if (consys_is_rc_mode_enable()) { + WMT_PLAT_PR_INFO("Do nothing for VCN33_1 under RC mode when disable\n"); + } else { + if (reg_VCN33_1_WIFI) + regulator_disable(reg_VCN33_1_WIFI); + + if (reg_VCN33_2_WIFI) + regulator_disable(reg_VCN33_2_WIFI); + } + WMT_PLAT_PR_DBG("WMT do WIFI PMIC off\n"); + } +#endif + return 0; +} + +static INT32 consys_hw_vcn_ctrl_after_idle(VOID) +{ + if (consys_is_rc_mode_enable()) { + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN18_LP, 1); + if (mtk_wcn_consys_get_adie_chipid() == PRIMARY_ADIE) + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_1_LP, 1); + else if (mtk_wcn_consys_get_adie_chipid() == SECONDARY_ADIE) + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN13_LP, 1); + } + return 0; +} + +static INT32 consys_emi_mpu_set_region_protection(VOID) +{ +#if CONSYS_ENABLE_EMI_MPU + struct emimpu_region_t region; + unsigned long long start = gConEmiPhyBase; + unsigned long long end = gConEmiPhyBase + gConEmiSize - 1; + + mtk_emimpu_init_region(®ion, REGION_CONN); + mtk_emimpu_set_addr(®ion, start, end); + mtk_emimpu_set_apc(®ion, DOMAIN_AP, MTK_EMIMPU_NO_PROTECTION); + mtk_emimpu_set_apc(®ion, DOMAIN_CONN, MTK_EMIMPU_NO_PROTECTION); + mtk_emimpu_set_protection(®ion); + mtk_emimpu_free_region(®ion); + + WMT_PLAT_PR_INFO("setting MPU for EMI share memory\n"); +#endif + return 0; +} + +static UINT32 consys_emi_set_remapping_reg(VOID) +{ + /* For direct path */ + phys_addr_t mdPhy = 0; + INT32 size = 0; + + mtk_wcn_emi_addr_info.emi_ap_phy_addr = gConEmiPhyBase; + mtk_wcn_emi_addr_info.emi_size = gConEmiSize; + + if (conn_reg.topckgen_base == 0) + return 0; + + /*EMI Registers remapping*/ + CONSYS_REG_WRITE_OFFSET_RANGE(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET, + gConEmiPhyBase, 0, 16, 20); + WMT_PLAT_PR_INFO("CONSYS_EMI_MAPPING dump in restore cb(0x%08x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET)); + + /*Perisys Configuration Registers remapping*/ + CONSYS_REG_WRITE_OFFSET_RANGE(conn_reg.topckgen_base + CONSYS_EMI_PERI_MAPPING_OFFSET, + 0x10003000, 0, 16, 20); + WMT_PLAT_PR_INFO("PERISYS_MAPPING dump in restore cb(0x%08x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_PERI_MAPPING_OFFSET)); + + /*Modem Configuration Registers remapping*/ +#ifdef CONFIG_MTK_ECCCI_DRIVER + mdPhy = get_smem_phy_start_addr(MD_SYS1, SMEM_USER_RAW_MD_CONSYS, &size); +#endif + if (size == 0) + WMT_PLAT_PR_INFO("MD direct path is not supported\n"); + else { + CONSYS_REG_WRITE_OFFSET_RANGE( + conn_reg.topckgen_base + CONSYS_EMI_AP_MD_OFFSET, + mdPhy, 0, 16, 20); + WMT_PLAT_PR_INFO("MD_MAPPING dump in restore cb(0x%08x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_AP_MD_OFFSET)); + } + mtk_wcn_emi_addr_info.emi_direct_path_ap_phy_addr = mdPhy; + mtk_wcn_emi_addr_info.emi_direct_path_size = size; + + mtk_wcn_emi_addr_info.emi_ram_bt_buildtime_offset = + CONSYS_EMI_RAM_BT_BUILDTIME_OFFSET; + mtk_wcn_emi_addr_info.emi_ram_wifi_buildtime_offset = + CONSYS_EMI_RAM_WIFI_BUILDTIME_OFFSET; + mtk_wcn_emi_addr_info.emi_ram_mcu_buildtime_offset = + CONSYS_EMI_RAM_MCU_BUILDTIME_OFFSET; + mtk_wcn_emi_addr_info.emi_patch_mcu_buildtime_offset = + CONSYS_EMI_PATCH_MCU_BUILDTIME_OFFSET; + + return 0; +} + +static INT32 bt_wifi_share_v33_spin_lock_init(VOID) +{ + return 0; +} + +static INT32 consys_read_irq_info_from_dts(struct platform_device *pdev, PINT32 irq_num, + PUINT32 irq_flag) +{ + struct device_node *node; + + node = pdev->dev.of_node; + if (node) { + *irq_num = irq_of_parse_and_map(node, 0); + *irq_flag = irq_get_trigger_type(*irq_num); + WMT_PLAT_PR_INFO("get irq id(%d) and irq trigger flag(%d) from DT\n", *irq_num, + *irq_flag); + } else { + WMT_PLAT_PR_INFO("[%s] can't find CONSYS compatible node\n", __func__); + return -1; + } + + return 0; +} + +static INT32 consys_read_reg_from_dts(struct platform_device *pdev) +{ + INT32 iRet = -1; + struct device_node *node = NULL; + + node = pdev->dev.of_node; + if (node) { + /* registers base address */ + conn_reg.mcu_base = (SIZE_T) of_iomap(node, MCU_BASE_INDEX); + WMT_PLAT_PR_DBG("Get mcu register base(0x%zx)\n", conn_reg.mcu_base); + conn_reg.ap_rgu_base = (SIZE_T) of_iomap(node, TOP_RGU_BASE_INDEX); + WMT_PLAT_PR_DBG("Get ap_rgu register base(0x%zx)\n", conn_reg.ap_rgu_base); + conn_reg.topckgen_base = (SIZE_T) of_iomap(node, INFRACFG_AO_BASE_INDEX); + WMT_PLAT_PR_DBG("Get topckgen register base(0x%zx)\n", conn_reg.topckgen_base); + conn_reg.spm_base = (SIZE_T) of_iomap(node, SPM_BASE_INDEX); + WMT_PLAT_PR_DBG("Get spm register base(0x%zx)\n", conn_reg.spm_base); + conn_reg.mcu_conn_hif_on_base = (SIZE_T) of_iomap(node, MCU_CONN_HIF_ON_BASE_INDEX); + WMT_PLAT_PR_DBG("Get mcu_conn_hif_on register base(0x%zx)\n", + conn_reg.mcu_conn_hif_on_base); + conn_reg.mcu_top_misc_off_base = (SIZE_T) of_iomap(node, + MCU_TOP_MISC_OFF_BASE_INDEX); + WMT_PLAT_PR_DBG("Get mcu_top_misc_off register base(0x%zx)\n", + conn_reg.mcu_top_misc_off_base); + conn_reg.mcu_cfg_on_base = (SIZE_T) of_iomap(node, MCU_CFG_ON_BASE_INDEX); + WMT_PLAT_PR_DBG("Get mcu_cfg_on register base(0x%zx)\n", conn_reg.mcu_cfg_on_base); + conn_reg.mcu_cirq_base = (SIZE_T) of_iomap(node, MCU_CIRQ_BASE_INDEX); + WMT_PLAT_PR_DBG("Get mcu cirq register base(0x%zx)\n", conn_reg.mcu_cirq_base); + conn_reg.mcu_top_misc_on_base = (SIZE_T) of_iomap(node, MCU_TOP_MISC_ON_BASE_INDEX); + WMT_PLAT_PR_DBG("Get mcu_top_misc_on register base(0x%zx)\n", + conn_reg.mcu_top_misc_on_base); + conn_reg.mcu_conn_hif_pdma_base = (SIZE_T) of_iomap(node, MCU_CONN_HIF_PDMA_BASE_INDEX); + WMT_PLAT_PR_DBG("Get mcu_conn_hif_pdma register base(0x%zx)\n", + conn_reg.mcu_conn_hif_pdma_base); + conn_reg.ap_pccif4_base = (SIZE_T) of_iomap(node, AP_PCCIF4_BASE_INDEX); + WMT_PLAT_PR_DBG("Get ap_pccif4 register base(0x%zx)\n", + conn_reg.ap_pccif4_base); + conn_reg.infra_ao_pericfg_base = (SIZE_T) of_iomap(node, INFRA_AO_PERICFG_BASE_INDEX); + WMT_PLAT_PR_DBG("Get infra_ao_pericfg register base(0x%zx)\n", + conn_reg.infra_ao_pericfg_base); + } else { + WMT_PLAT_PR_INFO("[%s] can't find CONSYS compatible node\n", __func__); + return iRet; + } + + return 0; +} + +static VOID force_trigger_assert_debug_pin(VOID) +{ + UINT32 value = 0; + + if (conn_reg.infra_ao_pericfg_base != 0) { + WMT_PLAT_PR_DBG("CON_STA_REG = %x\n", + CONSYS_REG_READ( + conn_reg.infra_ao_pericfg_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG)); + + /* clear CON_PWR_ON & CON_SW_READY bit (CON_STA_REG[0], CON_STA_REG[1]) */ + value = CONSYS_REG_READ(conn_reg.infra_ao_pericfg_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG); + value = value & (~INFRASYS_COMMON_AP2MD_CON_PWR_ON_CON_SW_READY_MASK); + CONSYS_REG_WRITE(conn_reg.infra_ao_pericfg_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG, + value); + + WMT_PLAT_PR_DBG("CON_STA_REG = %x\n", + CONSYS_REG_READ( + conn_reg.infra_ao_pericfg_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG)); + } + + if (conn_reg.topckgen_base == 0) + return; + + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AP2CONN_OSC_EN_OFFSET) & ~CONSYS_AP2CONN_WAKEUP_BIT); + WMT_PLAT_PR_INFO("enable:dump CONSYS_AP2CONN_OSC_EN_REG(0x%x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET)); + usleep_range(64, 96); + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AP2CONN_OSC_EN_OFFSET) | CONSYS_AP2CONN_WAKEUP_BIT); + WMT_PLAT_PR_INFO("disable:dump CONSYS_AP2CONN_OSC_EN_REG(0x%x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET)); +} + +static UINT32 consys_read_cpupcr(VOID) +{ + if (conn_reg.mcu_conn_hif_on_base == 0) + return 0; + + if (mtk_consys_check_reg_readable_by_addr(conn_reg.mcu_conn_hif_on_base + CONSYS_CPUPCR_OFFSET) == 0) + return 0; + + return CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + CONSYS_CPUPCR_OFFSET); +} + +static UINT32 consys_soc_chipid_get(VOID) +{ + return PLATFORM_SOC_CHIP; +} + +static UINT32 consys_adie_chipid_checking_flow(UINT32 adie) +{ + UINT8 *conn_rf_spi_base = NULL; + UINT32 chipid = 0; + UINT32 retry = 10; + + conn_rf_spi_base = ioremap_nocache(CONN_RF_SPI_BASE, 0x100); + if (!conn_rf_spi_base) { + WMT_PLAT_PR_INFO("ioumap 0x180c6000 fail"); + return 0; + } + + if (reg_VCN18) { + regulator_set_voltage(reg_VCN18, 1800000, 1800000); + if (regulator_enable(reg_VCN18)) + WMT_PLAT_PR_INFO("enable VCN18 fail\n"); + else + WMT_PLAT_PR_DBG("enable VCN18 ok\n"); + } + udelay(300); + if ((reg_VCN13) && (adie == SECONDARY_ADIE)) { + regulator_set_voltage(reg_VCN13, 1300000, 1300000); + if (regulator_enable(reg_VCN13)) + WMT_PLAT_PR_INFO("enable VCN13 fail\n"); + else + WMT_PLAT_PR_DBG("enable VCN13 ok\n"); + } + if (wmt_plat_soc_co_clock_flag_get() == 0) + consys_hw_vcn28_ctrl(ENABLE); + consys_set_if_pinmux(ENABLE); + udelay(150); + consys_hw_reset_bit_set(ENABLE); + consys_hw_spm_clk_gating_enable(); + consys_hw_power_ctrl(ENABLE); + udelay(10); + polling_consys_chipid(); + consys_set_access_emi_hw_mode(); + consys_afe_reg_setting(); + consys_set_xo_osc_ctrl(); + + CONSYS_REG_WRITE(conn_reg.mcu_top_misc_on_base + CONN_ON_ADIE_CTL_OFFSET, + CONSYS_REG_READ(conn_reg.mcu_top_misc_on_base + CONN_ON_ADIE_CTL_OFFSET) + | 0x1); + + while (retry-- > 0) { + if ((CONSYS_REG_READ(conn_rf_spi_base) & 0x1) == 0) + break; + udelay(500); + } + + if (adie == PRIMARY_ADIE) + CONSYS_REG_WRITE(conn_rf_spi_base + SPI_TOP_ADDR, 0x0000b024); + else if (adie == SECONDARY_ADIE) + CONSYS_REG_WRITE(conn_rf_spi_base + SPI_TOP_ADDR, 0x0000b02C); + CONSYS_REG_WRITE(conn_rf_spi_base + SPI_TOP_WDAT, 0); + + retry = 10; + while (retry-- > 0) { + if ((CONSYS_REG_READ(conn_rf_spi_base) & 0x20) == 0) + break; + udelay(500); + } + + chipid = CONSYS_REG_READ(conn_rf_spi_base + SPI_TOP_RDAT) >> 16; + + CONSYS_REG_WRITE(conn_reg.mcu_top_misc_on_base + CONN_ON_ADIE_CTL_OFFSET, + CONSYS_REG_READ(conn_reg.mcu_top_misc_on_base + CONN_ON_ADIE_CTL_OFFSET) + & 0x0); + + iounmap(conn_rf_spi_base); + + consys_hw_power_ctrl(DISABLE); + consys_set_if_pinmux(DISABLE); + if (wmt_plat_soc_co_clock_flag_get() == 0) + consys_hw_vcn28_ctrl(DISABLE); + + if ((reg_VCN13) && (adie == SECONDARY_ADIE)) { + if (regulator_disable(reg_VCN13)) + WMT_PLAT_PR_INFO("disable VCN13 fail!\n"); + } + udelay(300); + if (reg_VCN18) { + if (regulator_disable(reg_VCN18)) + WMT_PLAT_PR_INFO("disable VCN18 fail!\n"); + } + + if ((reg_VCN13) && (chipid == PRIMARY_ADIE)) { + /* release VCN13 resource if never used to prevent customerized issue */ + regulator_put(reg_VCN13); + reg_VCN13 = NULL; + } + + return chipid; +} + +static INT32 consys_adie_chipid_detect(VOID) +{ + INT32 chipid = -1; + UINT32 retry = 3; + + while ((retry-- > 0) && (chipid == -1)) { + if (consys_adie_chipid_checking_flow(PRIMARY_ADIE) == PRIMARY_ADIE) + chipid = PRIMARY_ADIE; + else if (consys_adie_chipid_checking_flow(SECONDARY_ADIE) == SECONDARY_ADIE) + chipid = SECONDARY_ADIE; + } + WMT_PLAT_PR_INFO("A-die chip id = %x\n", chipid); + + return chipid; +} + +static P_CONSYS_EMI_ADDR_INFO consys_soc_get_emi_phy_add(VOID) +{ + return &mtk_wcn_emi_addr_info; +} + +P_WMT_CONSYS_IC_OPS mtk_wcn_get_consys_ic_ops(VOID) +{ + return &consys_ic_ops; +} + +static INT32 consys_dl_rom_patch(UINT32 ip_ver, UINT32 fw_ver) +{ + if (rom_patch_dl_flag) { + if (mtk_wcn_soc_rom_patch_dwn(ip_ver, fw_ver) == 0) + rom_patch_dl_flag = 1; + else + return -1; + } + + return 0; +} + +static VOID consys_set_dl_rom_patch_flag(INT32 flag) +{ + rom_patch_dl_flag = flag; +} + +static VOID consys_conn2ap_sw_irq_clear(VOID) +{ + UINT32 ret; + + if (!conn_reg.mcu_base) + return; + + if (osal_trylock_unsleepable_lock(&g_pwr_off_lock) == 0) { + WMT_PLAT_PR_INFO("fail to get pwr off lock\n"); + return; + } + + if (atomic_read(&g_power_on) == 1) { + /* clear 0x1800214c[27:24] */ + CONSYS_REG_WRITE(conn_reg.mcu_base + CONN2AP_SW_IRQ_CLR_OFFSET, + CONSYS_REG_READ(conn_reg.mcu_base + CONN2AP_SW_IRQ_CLR_OFFSET) + | (0xf << 24)); + + ret = CONSYS_REG_READ(conn_reg.mcu_base + CONN2AP_SW_IRQ_OFFSET) & (0xf << 24); + if (ret > 0) + WMT_PLAT_PR_INFO("CONN2AP_SW_IRQ[27:24] = 0x%x\n", ret); + } + + osal_unlock_unsleepable_lock(&g_pwr_off_lock); +} + +static INT32 consys_dedicated_log_path_init(struct platform_device *pdev) +{ + struct device_node *node; + UINT32 irq_num; + UINT32 irq_flag; + INT32 iret = -1; + struct connlog_irq_config irq_config; + + memset(&irq_config, 0, sizeof(struct connlog_irq_config)); + node = pdev->dev.of_node; + if (node) { + irq_num = irq_of_parse_and_map(node, 2); + irq_flag = irq_get_trigger_type(irq_num); + WMT_PLAT_PR_INFO("get conn2ap_sw_irq id(%d) and irq trigger flag(%d) from DT\n", + irq_num, irq_flag); + } else { + WMT_PLAT_PR_INFO("[%s] can't find CONSYS compatible node\n", __func__); + return iret; + } + osal_unsleepable_lock_init(&g_pwr_off_lock); + + irq_config.irq_num = irq_num; + irq_config.irq_flag = irq_flag; + irq_config.irq_callback = consys_conn2ap_sw_irq_clear; + + connsys_dedicated_log_path_apsoc_init( + gConEmiPhyBase, &connsys_fw_log_parameter, &irq_config); + +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH + fw_log_wmt_init(); +#endif + return 0; +} + +static VOID consys_dedicated_log_path_deinit(VOID) +{ +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH + fw_log_wmt_deinit(); +#endif + connsys_dedicated_log_path_apsoc_deinit(); + osal_unsleepable_lock_deinit(&g_pwr_off_lock); +} + +static INT32 consys_emi_coredump_remapping(UINT8 __iomem **addr, UINT32 enable) +{ + if (enable) { + *addr = ioremap_nocache(gConEmiPhyBase + CONSYS_EMI_COREDUMP_OFFSET, + CONSYS_EMI_COREDUMP_MEM_SIZE); + if (*addr) { + WMT_PLAT_PR_INFO("COREDUMP EMI mapping OK virtual(0x%p) physical(0x%x)\n", + *addr, (UINT32) gConEmiPhyBase + + CONSYS_EMI_COREDUMP_OFFSET); + memset_io(*addr, 0, CONSYS_EMI_COREDUMP_MEM_SIZE); + } else { + WMT_PLAT_PR_INFO("EMI mapping fail\n"); + return -1; + } + } else { + if (*addr) { + iounmap(*addr); + *addr = NULL; + } + } + return 0; +} + +static INT32 consys_reset_emi_coredump(UINT8 __iomem *addr) +{ + if (!addr) { + WMT_PLAT_PR_INFO("get virtual address fail\n"); + return -1; + } + WMT_PLAT_PR_INFO("Reset EMI(0xF0068000 ~ 0xF0107FFF)\n"); + memset_io(addr, 0, CONSYS_EMI_COREDUMP_MEM_SIZE); + return 0; +} + +static INT32 consys_check_reg_readable(VOID) +{ + INT32 can_read = 0; + UINT32 value = 0; + + if (conn_reg.mcu_cfg_on_base != 0 && + conn_reg.mcu_top_misc_on_base != 0) { + /*check connsys clock and sleep status*/ + CONSYS_REG_WRITE(conn_reg.mcu_conn_hif_on_base, CONSYS_CLOCK_CHECK_VALUE); + udelay(200); + value = CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base); + if ((value & CONSYS_HCLK_CHECK_BIT) && + (value & CONSYS_OSCCLK_CHECK_BIT)) + can_read = 1; + } + + if (!can_read) + WMT_PLAT_PR_INFO("connsys clock check fail 0x18007000(0x%x)\n", value); + + return can_read; +} + +static VOID consys_ic_clock_fail_dump(VOID) +{ +#if 0 + UINT8 *addr; +#endif + char *temp; + char buffer[1024] = {""}; + + if (conn_reg.mcu_base == 0 || + conn_reg.mcu_conn_hif_pdma_base == 0 || + conn_reg.mcu_conn_hif_on_base == 0) + return; + + temp = buffer; + temp += sprintf(temp, "CONN_HIF_TOP_MISC=0x%08x CONN_HIF_BUSY_STATUS=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_TOP_MISC), + CONSYS_REG_READ(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_BUSY_STATUS)); + + CONSYS_REG_WRITE(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_DBG_IDX, 0x3333); + temp += sprintf(temp, "Write CONSYS_HIF_DBG_IDX to 0x3333\n"); + + temp += sprintf(temp, "CONSYS_HIF_DBG_PROBE=0x%08x CONN_HIF_TOP_MISC=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_DBG_PROBE), + CONSYS_REG_READ(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_TOP_MISC)); + + temp += sprintf(temp, "CONN_HIF_BUSY_STATUS=0x%08x CONN_HIF_PDMA_BUSY_STATUS=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_BUSY_STATUS), + CONSYS_REG_READ(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_PDMA_BUSY_STATUS)); + + CONSYS_REG_WRITE(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_DBG_IDX, 0x2222); + temp += sprintf(temp, "Write CONSYS_HIF_DBG_IDX to 0x2222\n"); + + temp += sprintf(temp, "CONSYS_HIF_DBG_PROBE=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_DBG_PROBE)); + + CONSYS_REG_WRITE(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_DBG_IDX, 0x3333); + temp += sprintf(temp, "Write CONSYS_HIF_DBG_IDX to 0x3333\n"); + + temp += sprintf(temp, "CONSYS_HIF_DBG_PROBE=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_DBG_PROBE)); + + CONSYS_REG_WRITE(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_DBG_IDX, 0x4444); + temp += sprintf(temp, "Write CONSYS_HIF_DBG_IDX to 0x4444\n"); + + temp += sprintf(temp, "CONSYS_HIF_DBG_PROBE=0x%08x CONN_MCU_EMI_CONTROL=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_DBG_PROBE), + CONSYS_REG_READ(conn_reg.mcu_base + CONN_MCU_EMI_CONTROL)); + temp += sprintf(temp, "EMI_CONTROL_DBG_PROBE=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + EMI_CONTROL_DBG_PROBE)); + temp += sprintf(temp, "CONN_MCU_CLOCK_CONTROL=0x%08x CONN_MCU_BUS_CONTROL=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_CLOCK_CONTROL), + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_BUS_CONTROL)); +#if 0 + temp = buffer; + addr = ioremap_nocache(0x180bc000, 0x100); + if (addr) { + /* conn2ap axi master sleep prot info */ + temp += sprintf(temp, "0x180bc010=0x%08x\n", CONSYS_REG_READ(addr + 0x10)); + /* conn_mcu2ap axi master sleep prot info */ + temp += sprintf(temp, "0x180bc014=0x%08x\n", CONSYS_REG_READ(addr + 0x14)); + /* conn2ap axi gals bus info */ + temp += sprintf(temp, "0x180bc018=0x%08x\n", CONSYS_REG_READ(addr + 0x18)); + /* conn2ap mux4to1 debug info */ + temp += sprintf(temp, "0x180bc01c=0x%08x\n", CONSYS_REG_READ(addr + 0x1c)); + /* conn_hif_off bus busy info */ + temp += sprintf(temp, "0x180bc020=0x%08x\n", CONSYS_REG_READ(addr + 0x20)); + iounmap(addr); + } else { + WMT_PLAT_PR_INFO("0x180bc000 ioremap fail!\n"); + } + + addr = ioremap_nocache(0x10001B20, 0x100); + if (addr) { + /* 0x10001B20 */ + temp += sprintf(temp, "0x10001B20=0x%08x\n", CONSYS_REG_READ(addr)); + iounmap(addr); + } else { + WMT_PLAT_PR_INFO("0x10001B20 ioremap fail!\n"); + } + + /* conn_hif_on misc info */ + temp += sprintf(temp, "0x1800713c=0x%08x\n", CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + 0x13c)); + + addr = ioremap_nocache(0x180c1144, 0x100); + if (addr) { + /* conn_on_host debug flag */ + temp += sprintf(temp, "0x180c1144=0x%08x\n", CONSYS_REG_READ(addr)); + iounmap(addr); + } else { + WMT_PLAT_PR_INFO("0x180c1144 ioremap fail!\n"); + } + + addr = ioremap_nocache(0x1020E804, 0x100); + if (addr) { + /* 0x1020E804 */ + temp += sprintf(temp, "0x1020E804=0x%08x\n", CONSYS_REG_READ(addr)); + iounmap(addr); + } else { + WMT_PLAT_PR_INFO("0x1020E804 ioremap fail!\n"); + } +#endif + WMT_PLAT_PR_INFO("%s length = %d", buffer, osal_strlen(buffer)); +} + +static INT32 consys_is_connsys_reg(UINT32 addr) +{ + if (addr > 0x18000000 && addr < 0x180FFFFF) { + if (addr >= 0x18007000 && addr <= 0x18007FFF) + return 0; + + return 1; + } + + return 0; +} + +static INT32 consys_is_host_csr(SIZE_T addr) +{ + SIZE_T start_offset = 0x000; + SIZE_T end_offset = 0xFFF; + + if (addr >= (CONN_HIF_ON_BASE_ADDR + start_offset) && + addr <= (CONN_HIF_ON_BASE_ADDR + end_offset)) + return 1; + + if (conn_reg.mcu_conn_hif_on_base != 0 && + addr >= (conn_reg.mcu_conn_hif_on_base + start_offset) && + addr <= (conn_reg.mcu_conn_hif_on_base + end_offset)) + return 1; + + return 0; +} + +static INT32 consys_dump_osc_state(P_CONSYS_STATE state) +{ +#define MCU_OSC_EN_BIT 6 +#define BT_OSC_EN_BIT 8 +#define GPS_OSC_EN_BIT 9 +#define WIFI_OSC_EN_BIT 12 +#define FM_OSC_EN_BIT 7 +#define AP2CONN_OSC_EN_BIT 5 + + UINT32 value = 0; + UINT8 strbuf[DBG_LOG_STR_SIZE] = {""}; + UINT32 len = 0; + + UINT32 mcu_osc_en = 0; + UINT32 bt_osc_en = 0; + UINT32 gps_osc_en = 0; + UINT32 wifi_osc_en = 0; + UINT32 fm_osc_en = 0; + UINT32 ap2conn_osc_en = 0; + + if (conn_reg.mcu_cfg_on_base != 0 && + conn_reg.mcu_top_misc_on_base != 0) { + + CONSYS_REG_WRITE(conn_reg.mcu_top_misc_on_base + CONN_CFG_ON_MON_CTL_ADDR_OFFSET, 0x80000001); + CONSYS_REG_WRITE(conn_reg.mcu_top_misc_on_base + CONN_CFG_ON_MON_SEL0_ADDR_OFFSET, 0x03020100); + CONSYS_REG_WRITE(conn_reg.mcu_top_misc_on_base + CONN_CFG_ON_MON_SEL1_ADDR_OFFSET, 0x07060504); + CONSYS_REG_WRITE(conn_reg.mcu_top_misc_on_base + CONN_CFG_ON_MON_SEL2_ADDR_OFFSET, 0x0b0a0908); + CONSYS_REG_WRITE(conn_reg.mcu_top_misc_on_base + CONN_CFG_ON_MON_SEL3_ADDR_OFFSET, 0x0f0e0d0c); + CONSYS_REG_WRITE(conn_reg.mcu_top_misc_on_base + CONN_CFG_ON_DBGSEL_ADDR_OFFSET, 0x3); + value = CONSYS_REG_READ(conn_reg.mcu_top_misc_on_base + CONN_CFG_ON_MON_FLAG_RECORD_ADDR_OFFSET); + + state->lp[0] = (UINT32)0x180c1340; + state->lp[1] = value; + + if (value != 0 && value != 0xdeadfeed) { + mcu_osc_en = (value >> MCU_OSC_EN_BIT) & 0x1; + bt_osc_en = (value >> BT_OSC_EN_BIT) & 0x1; + gps_osc_en = (value >> GPS_OSC_EN_BIT) & 0x1; + wifi_osc_en = (value >> WIFI_OSC_EN_BIT) & 0x1; + fm_osc_en = (value >> FM_OSC_EN_BIT) & 0x1; + ap2conn_osc_en = (value >> AP2CONN_OSC_EN_BIT) & 0x1; + } + + len += osal_sprintf(strbuf + len, "0x%08x: 0x%x", state->lp[0], state->lp[1]); + if ((mcu_osc_en + bt_osc_en + gps_osc_en + wifi_osc_en + fm_osc_en + ap2conn_osc_en) >= 1) { + len += osal_sprintf(strbuf + len, " (%s%s%s%s%s%s", + ((mcu_osc_en == 1) ? "MCU," : ""), ((bt_osc_en == 1) ? "BT," : ""), + ((gps_osc_en == 1) ? "GPS," : ""), ((wifi_osc_en == 1) ? "WIFI," : ""), + ((fm_osc_en == 1) ? "FM," : ""), ((ap2conn_osc_en == 1) ? "AP2CONN," : "")); + len += osal_sprintf(strbuf + len - 1, ")"); + } + WMT_PLAT_PR_INFO("%s\n", strbuf); + } + return MTK_WCN_BOOL_TRUE; +} + +static INT32 consys_dump_gating_state(P_CONSYS_STATE state) +{ + UINT32 value = 0; + UINT8 strbuf[DBG_LOG_STR_SIZE] = {""}; + UINT32 len = 0; + + UINT32 magic_number = 0; + UINT32 clock_hif_ctrl = 0; + UINT32 clock_umac_ctrl = 0; + UINT32 sleep_disable_mode = 0; + UINT32 subsys_clk_req_stutus = 0; + UINT32 clk_rate = 0; + + if (conn_reg.mcu_conn_hif_on_base == 0) + return MTK_WCN_BOOL_FALSE; + + value = CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + CONN_MCU_MAILBOX_DBG); + + if (state) { + state->gating[0] = (UINT32)0x18007120; + state->gating[1] = value; + osal_memset(&(state->sw_state), 0, sizeof(state->sw_state)); + } + + magic_number = (value >> 0) & 0xF; + if (magic_number == 0x7) { + clock_hif_ctrl = (value >> 4) & 0x1; + clock_umac_ctrl = (value >> 5) & 0x1; + sleep_disable_mode = (value >> 8) & 0xFF; + subsys_clk_req_stutus = (value >> 16) & 0xFF; + clk_rate = (value >> 24) & 0xFF; + } + + len += osal_sprintf(strbuf + len, "0x%08x: 0x%x", 0x18007120, value); + if (magic_number == 0x7) { + if (clock_hif_ctrl == 0x0 && clock_umac_ctrl == 0x0 && sleep_disable_mode == 0x0 && + subsys_clk_req_stutus == 0x0 && clk_rate <= 0x1a) { + len += osal_sprintf(strbuf + len, " (sleep)"); + if (state) { + state->sw_state.is_gating = 0; + state->sw_state.clock_mcu = clk_rate; + } + } else { + len += osal_sprintf(strbuf + len, + " (gating, hif_clk:0x%01x, umac_clk:0x%01x, slp_dis:0x%02x, subsys_clk:0x%02x, clk_rate:0x%02x)", + clock_hif_ctrl, clock_umac_ctrl, sleep_disable_mode, subsys_clk_req_stutus, clk_rate); + if (state) { + state->sw_state.is_gating = 1; + state->sw_state.clock_hif_ctrl = clock_hif_ctrl; + state->sw_state.clock_umac_ctrl = clock_umac_ctrl; + state->sw_state.resource_disable_sleep = sleep_disable_mode; + state->sw_state.sub_system = subsys_clk_req_stutus; + state->sw_state.clock_mcu = clk_rate; + } + } + } else { + len += osal_sprintf(strbuf + len, " (no gating info found)"); + } + WMT_PLAT_PR_INFO("%s\n", strbuf); + + return MTK_WCN_BOOL_TRUE; +} + +static VOID consys_set_pdma_axi_rready_force_high(UINT32 enable) +{ + if (conn_reg.mcu_conn_hif_pdma_base == 0) + return; + + if (enable) + CONSYS_SET_BIT(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_PDMA_AXI_RREADY, + CONSYS_HIF_PDMA_AXI_RREADY_MASK); + else if ((CONSYS_REG_READ(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_PDMA_AXI_RREADY) & + CONSYS_HIF_PDMA_AXI_RREADY_MASK) != 0) + CONSYS_CLR_BIT(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_PDMA_AXI_RREADY, + CONSYS_HIF_PDMA_AXI_RREADY_MASK); +} + +static VOID consys_set_mcif_emi_mpu_protection(MTK_WCN_BOOL enable) +{ + WMT_PLAT_PR_INFO("Setup region 23 for domain 0 as %s\n", enable ? "FORBIDDEN" : "SEC_R_NSEC_R"); + /* emi_mpu_set_single_permission(23, 0, enable ? FORBIDDEN : SEC_R_NSEC_R); */ +} + +static INT32 consys_calibration_backup_restore_support(VOID) +{ + return 1; +} + +#if WMT_DEVAPC_DBG_SUPPORT +static VOID consys_devapc_violation_cb(VOID) +{ + /** + * Don't use wmt_lib_trigger_assert() because it will invoke vmalloc and then cause KE since + * this callback is supposed to be invoked in DEVAPC exception hanlder. + */ + wmt_lib_trigger_assert_keyword_delay(WMTDRV_TYPE_WMT, 46, "DEVAPC Violation"); +} +#endif + +static VOID consyc_register_devapc_cb(VOID) +{ +#if WMT_DEVAPC_DBG_SUPPORT + register_devapc_vio_callback(&devapc_handle); +#endif +} + +static INT32 consys_is_rc_mode_enable(VOID) +{ +#if CONSYS_RC_MODE_ENABLE + INT32 value; + UINT8 *reg_base; + + reg_base = ioremap_nocache(SRCLKEN_RC_BASE, 0x10); + /* Since RC mode is default on, return 1 if ioremap is failed */ + if (!reg_base) + return 1; + + value = SRCLKEN_RC_CENTRAL_CFG1_BIT & + CONSYS_REG_READ(reg_base + SRCLKEN_RC_CENTRAL_CFG1); + + iounmap(reg_base); + return value; +#else + return 0; +#endif +} + +UINT32 consys_sleep_info_is_enable(VOID) +{ + UINT32 ctrl_enable = 0; + UINT32 host_ctrl_enable = 0; + + if (conn_reg.mcu_conn_hif_on_base == 0) + return 0; + + ctrl_enable = (CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + + CONN_HOST_CR_SLEEP_CNT_OFFSET) >> 0) & 0x1; + + if (ctrl_enable == 0) + return 0; + + host_ctrl_enable = (CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + + CONN_HOST_CR_SLEEP_CNT_OFFSET) >> 5) & 0x1; + + if (host_ctrl_enable == 0) + return 0; + + return 1; +} + +INT32 consys_sleep_info_clear(VOID) +{ + if (conn_reg.mcu_conn_hif_on_base == 0) + return -1; + + /* set xx_in_sleep_clr = 1 */ + CONSYS_REG_WRITE(conn_reg.mcu_conn_hif_on_base + CONN_SLEEP_INFO_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + CONN_SLEEP_INFO_CTRL_OFFSET) | + (0x1F << 5)); + + /* wait 100us */ + udelay(100); + + /* set xx_in_sleep_clr = 0 */ + CONSYS_REG_WRITE(conn_reg.mcu_conn_hif_on_base + CONN_SLEEP_INFO_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + CONN_SLEEP_INFO_CTRL_OFFSET) & + ~(0x1F << 5)); + + return 0; +} + +INT32 consys_sleep_info_enable_ctrl(UINT32 enable) +{ + if (conn_reg.mcu_conn_hif_on_base == 0) + return -1; + + WMT_PLAT_PR_DBG("consys_sleep_info_enable_ctrl, enable=[%d]\n", enable); + + if (enable == 1) { + /* set sleep_cnt_en = 1 (function enable) */ + CONSYS_REG_WRITE(conn_reg.mcu_conn_hif_on_base + CONN_HOST_CR_SLEEP_CNT_OFFSET, + CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + CONN_HOST_CR_SLEEP_CNT_OFFSET) | + (0x1 << 0)); + + /* wait 100us */ + udelay(100); + + /* set cr_host_slp_cnt_host_ctl_en = 1 (driver only) */ + CONSYS_REG_WRITE(conn_reg.mcu_conn_hif_on_base + CONN_HOST_CR_SLEEP_CNT_OFFSET, + CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + CONN_HOST_CR_SLEEP_CNT_OFFSET) | + (0x1 << 5)); + + /* set xx_in_sleep_clr = 1 */ + CONSYS_REG_WRITE(conn_reg.mcu_conn_hif_on_base + CONN_SLEEP_INFO_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + CONN_SLEEP_INFO_CTRL_OFFSET) | + (0x1F << 5)); + + /* set xx_in_sleep_stop = 0 */ + CONSYS_REG_WRITE(conn_reg.mcu_conn_hif_on_base + CONN_SLEEP_INFO_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + CONN_SLEEP_INFO_CTRL_OFFSET) & + ~(0x1F << 0)); + + /* wait 100us */ + udelay(100); + + /* set xx_in_sleep_clr = 0 */ + CONSYS_REG_WRITE(conn_reg.mcu_conn_hif_on_base + CONN_SLEEP_INFO_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + CONN_SLEEP_INFO_CTRL_OFFSET) & + ~(0x1F << 5)); + } else { + /* set xx_in_sleep_stop = 1 */ + CONSYS_REG_WRITE(conn_reg.mcu_conn_hif_on_base + CONN_SLEEP_INFO_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + CONN_SLEEP_INFO_CTRL_OFFSET) | + (0x1F << 0)); + + /* set cr_host_slp_cnt_host_ctl_en = 0 (driver only) */ + CONSYS_REG_WRITE(conn_reg.mcu_conn_hif_on_base + CONN_HOST_CR_SLEEP_CNT_OFFSET, + CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + CONN_HOST_CR_SLEEP_CNT_OFFSET) & + ~(0x1 << 5)); + + /* wait 100us */ + udelay(100); + + /* set sleep_cnt_en = 0 (function disable) */ + CONSYS_REG_WRITE(conn_reg.mcu_conn_hif_on_base + CONN_HOST_CR_SLEEP_CNT_OFFSET, + CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + CONN_HOST_CR_SLEEP_CNT_OFFSET) & + ~(0x1 << 0)); + } + + return 0; +} + +INT32 consys_sleep_info_read_ctrl(WMT_SLEEP_COUNT_TYPE type, PUINT64 sleep_counter, PUINT64 sleep_timer) +{ + /* + * type = 0 --> WMT_SLEEP_COUNT_TOP + * type = 1 --> WMT_SLEEP_COUNT_MCU + * type = 2 --> WMT_SLEEP_COUNT_BT + * type = 3 --> WMT_SLEEP_COUNT_WF + * type = 4 --> WMT_SLEEP_COUNT_GPS + */ + + UINT32 in_sleep_state = 0; + UINT32 value_sleep_timer_rd = 0; + UINT32 value_sleep_counter_rd = 0; + UINT32 value_final_counter = 0; + + if (conn_reg.mcu_conn_hif_on_base == 0) + return -1; + + if (type >= WMT_SLEEP_COUNT_MAX) + return -2; + + if (sleep_counter == NULL && sleep_timer == NULL) + return -3; + + if (!consys_sleep_info_is_enable()) + return -4; + + WMT_PLAT_PR_DBG("type=[%d]\n", type); + + /* set sleep_cnt_sel = top/mcu/bt/wf/gps */ + CONSYS_REG_WRITE(conn_reg.mcu_conn_hif_on_base + CONN_HOST_CR_SLEEP_CNT_OFFSET, + (CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + CONN_HOST_CR_SLEEP_CNT_OFFSET) & + 0xFFFFFFF1) | (type * 2)); + + /* set sleep_cnt_rd_trig = 1 */ + CONSYS_REG_WRITE(conn_reg.mcu_conn_hif_on_base + CONN_HOST_CR_SLEEP_CNT_OFFSET, + CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + CONN_HOST_CR_SLEEP_CNT_OFFSET) | + (0x1 << 4)); + + /* wait 40us */ + udelay(40); + + /* set sleep_cnt_rd_trig = 0 */ + CONSYS_REG_WRITE(conn_reg.mcu_conn_hif_on_base + CONN_HOST_CR_SLEEP_CNT_OFFSET, + CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + CONN_HOST_CR_SLEEP_CNT_OFFSET) & + ~(0x1 << 4)); + + /* wait 100us */ + udelay(100); + + if (sleep_counter) { + /* read sleep_cnt_counter */ + value_sleep_counter_rd = CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + + CONN_SLEEP_INFO_READ_CTRL_COUNT_OFFSET); + in_sleep_state = (CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + + CONN_SLEEP_INFO_CTRL_OFFSET) >> (14 - type)) & 0x1; + + if (value_sleep_counter_rd == 0) { + value_final_counter = 0; + } else { + if ((type == WMT_SLEEP_COUNT_BT || type == WMT_SLEEP_COUNT_WF) && in_sleep_state == 1) + value_final_counter = value_sleep_counter_rd + 1; + else + value_final_counter = value_sleep_counter_rd; + } + + if (value_final_counter > 0) + value_final_counter--; + + *sleep_counter = value_final_counter; + WMT_PLAT_PR_DBG("sleep_counter_rd=[%d], in_sleep_state=[%d], final_counter=[%d]\n", + value_sleep_counter_rd, in_sleep_state, value_final_counter); + } + + if (sleep_timer) { + /* read sleep_cnt_timer */ + value_sleep_timer_rd = CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + + CONN_SLEEP_INFO_READ_CTRL_TIMER_OFFSET); + *sleep_timer = value_sleep_timer_rd; + WMT_PLAT_PR_DBG("sleep_timer_rd=[%d]\n", value_sleep_timer_rd); + } + + return 0; +} + +static UINT64 consys_get_options(VOID) +{ + UINT64 options = OPT_QUERY_ADIE | + OPT_WIFI_LTE_COEX | + OPT_BT_TSSI_FROM_WIFI_CONFIG_NEW_OPID | + OPT_COEX_CONFIG_ADJUST | + OPT_COEX_CONFIG_ADJUST_NEW_FLAG | + OPT_WIFI_LTE_COEX_TABLE_3 | + OPT_NORMAL_PATCH_DWN_3 | + OPT_PATCH_CHECKSUM; + return options; +} + diff --git a/drivers/misc/mediatek/connectivity/common/common_main/platform/mt6873.c b/drivers/misc/mediatek/connectivity/common/common_main/platform/mt6873.c new file mode 100644 index 0000000000000000000000000000000000000000..20d05dd54326a7cced383e09146ca5577124d62a --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/platform/mt6873.c @@ -0,0 +1,2640 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +#ifdef DFT_TAG +#undef DFT_TAG +#endif +#define DFT_TAG "[WMT-CONSYS-HW]" + +#define REGION_CONN 27 + +#define DOMAIN_AP 0 +#define DOMAIN_CONN 2 + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include +#include +#include +#include +#include +#include "connsys_debug_utility.h" +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH +#include "fw_log_wmt.h" +#endif +#include "osal_typedef.h" +#include "mt6873.h" +#include "mtk_wcn_consys_hw.h" +#include "wmt_ic.h" +#include "wmt_lib.h" +#include "wmt_step.h" +#include "wmt_plat.h" +#include "stp_dbg.h" + +#if (COMMON_KERNEL_CLK_SUPPORT) +#include +#else +#include +#endif + +#if CONSYS_PMIC_CTRL_ENABLE +#include +#if (COMMON_KERNEL_PMIC_SUPPORT) +#include +#include +#else +#include +#include +#endif +#endif + +#ifdef CONFIG_MTK_HIBERNATION +#include +#endif + +#include + +#if (!COMMON_KERNEL_CLK_SUPPORT) +#include +#endif + +/* Direct path */ +#include +#include +#if WMT_DEVAPC_DBG_SUPPORT +#include +#endif +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +static INT32 consys_clock_buffer_ctrl(MTK_WCN_BOOL enable); +static VOID consys_hw_reset_bit_set(MTK_WCN_BOOL enable); +static VOID consys_hw_spm_clk_gating_enable(VOID); +static INT32 consys_hw_power_ctrl(MTK_WCN_BOOL enable); +static INT32 consys_ahb_clock_ctrl(MTK_WCN_BOOL enable); +static INT32 polling_consys_chipid(VOID); +static VOID consys_acr_reg_setting(VOID); +static VOID consys_afe_reg_setting(VOID); +static INT32 consys_hw_vcn18_ctrl(MTK_WCN_BOOL enable); +static VOID consys_vcn28_hw_mode_ctrl(UINT32 enable); +static INT32 consys_hw_vcn28_ctrl(UINT32 enable); +static INT32 consys_hw_wifi_vcn33_ctrl(UINT32 enable); +static INT32 consys_hw_bt_vcn33_ctrl(UINT32 enable); +static INT32 consys_hw_vcn_ctrl_after_idle(VOID); +static UINT32 consys_soc_chipid_get(VOID); +static INT32 consys_emi_mpu_set_region_protection(VOID); +static UINT32 consys_emi_set_remapping_reg(VOID); +static INT32 bt_wifi_share_v33_spin_lock_init(VOID); +static INT32 consys_clk_get_from_dts(struct platform_device *pdev); +static INT32 consys_pmic_get_from_dts(struct platform_device *pdev); +static INT32 consys_read_irq_info_from_dts(struct platform_device *pdev, + PINT32 irq_num, PUINT32 irq_flag); +static INT32 consys_read_reg_from_dts(struct platform_device *pdev); +static UINT32 consys_read_cpupcr(VOID); +static VOID force_trigger_assert_debug_pin(VOID); +static INT32 consys_co_clock_type(VOID); +static P_CONSYS_EMI_ADDR_INFO consys_soc_get_emi_phy_add(VOID); +static VOID consys_set_if_pinmux(MTK_WCN_BOOL enable); +static INT32 consys_dl_rom_patch(UINT32 ip_ver, UINT32 fw_ver); +static VOID consys_set_dl_rom_patch_flag(INT32 flag); +static INT32 consys_dedicated_log_path_init(struct platform_device *pdev); +static VOID consys_dedicated_log_path_deinit(VOID); +static INT32 consys_emi_coredump_remapping(UINT8 __iomem **addr, UINT32 enable); +static INT32 consys_reset_emi_coredump(UINT8 __iomem *addr); +static INT32 consys_check_reg_readable(VOID); +static VOID consys_ic_clock_fail_dump(VOID); +static INT32 consys_is_connsys_reg(UINT32 addr); +static INT32 consys_is_host_csr(SIZE_T addr); +static INT32 consys_dump_osc_state(P_CONSYS_STATE state); +static VOID consys_set_pdma_axi_rready_force_high(UINT32 enable); +static VOID consys_set_mcif_emi_mpu_protection(MTK_WCN_BOOL enable); +#if (COMMON_KERNEL_CLK_SUPPORT) +static MTK_WCN_BOOL consys_need_store_pdev(VOID); +static UINT32 consys_store_pdev(struct platform_device *pdev); +#endif +/* + * If 1: this platform supports calibration backup/restore. + * otherwise: 0 + */ +static INT32 consys_calibration_backup_restore_support(VOID); +static INT32 consys_is_ant_swap_enable_by_hwid(INT32 pin_num); +#if WMT_DEVAPC_DBG_SUPPORT +static VOID consys_devapc_violation_cb(VOID); +#endif +static VOID consyc_register_devapc_cb(VOID); +static INT32 consys_is_rc_mode_enable(VOID); +static VOID consys_emi_entry_address(VOID); +static VOID consys_set_xo_osc_ctrl(VOID); +static VOID consys_identify_adie(VOID); +static VOID consys_wifi_ctrl_setting(VOID); +static VOID consys_bus_timeout_config(VOID); +static VOID consys_set_access_emi_hw_mode(VOID); +static INT32 consys_dump_gating_state(P_CONSYS_STATE state); +static INT32 consys_sleep_info_enable_ctrl(UINT32 enable); +static INT32 consys_sleep_info_read_ctrl(WMT_SLEEP_COUNT_TYPE type, PUINT64 sleep_counter, PUINT64 sleep_timer); +static INT32 consys_sleep_info_clear(VOID); +static UINT64 consys_get_options(VOID); + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ +/* CCF part */ +#if (!COMMON_KERNEL_CLK_SUPPORT) +struct clk *clk_scp_conn_main; /*ctrl conn_power_on/off */ +#endif +static struct clk *clk_infracfg_ao_ccif4_ap_cg; /* For direct path */ + +#if (COMMON_KERNEL_CLK_SUPPORT) +static struct platform_device *connsys_pdev; +#endif + +/* PMIC part */ +#if CONSYS_PMIC_CTRL_ENABLE +struct regulator *reg_VCN13; +struct regulator *reg_VCN18; +struct regulator *reg_VCN33_1_BT; +struct regulator *reg_VCN33_1_WIFI; +struct regulator *reg_VCN33_2_WIFI; +#endif + +EMI_CTRL_STATE_OFFSET mtk_wcn_emi_state_off = { + .emi_apmem_ctrl_state = EXP_APMEM_CTRL_STATE, + .emi_apmem_ctrl_host_sync_state = EXP_APMEM_CTRL_HOST_SYNC_STATE, + .emi_apmem_ctrl_host_sync_num = EXP_APMEM_CTRL_HOST_SYNC_NUM, + .emi_apmem_ctrl_chip_sync_state = EXP_APMEM_CTRL_CHIP_SYNC_STATE, + .emi_apmem_ctrl_chip_sync_num = EXP_APMEM_CTRL_CHIP_SYNC_NUM, + .emi_apmem_ctrl_chip_sync_addr = EXP_APMEM_CTRL_CHIP_SYNC_ADDR, + .emi_apmem_ctrl_chip_sync_len = EXP_APMEM_CTRL_CHIP_SYNC_LEN, + .emi_apmem_ctrl_chip_print_buff_start = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_START, + .emi_apmem_ctrl_chip_print_buff_len = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_LEN, + .emi_apmem_ctrl_chip_print_buff_idx = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_IDX, + .emi_apmem_ctrl_chip_int_status = EXP_APMEM_CTRL_CHIP_INT_STATUS, + .emi_apmem_ctrl_chip_paded_dump_end = EXP_APMEM_CTRL_CHIP_PAGED_DUMP_END, + .emi_apmem_ctrl_host_outband_assert_w1 = EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1, + .emi_apmem_ctrl_chip_page_dump_num = EXP_APMEM_CTRL_CHIP_PAGE_DUMP_NUM, + .emi_apmem_ctrl_assert_flag = EXP_APMEM_CTRL_ASSERT_FLAG, + .emi_apmem_ctrl_chip_check_sleep = EXP_APMEM_CTRL_CHIP_CHECK_SLEEP, +}; + +CONSYS_EMI_ADDR_INFO mtk_wcn_emi_addr_info = { + .emi_phy_addr = CONSYS_EMI_FW_PHY_BASE, + .paged_trace_off = CONSYS_EMI_PAGED_TRACE_OFFSET, + .paged_dump_off = CONSYS_EMI_PAGED_DUMP_OFFSET, + .full_dump_off = CONSYS_EMI_FULL_DUMP_OFFSET, + .emi_remap_offset = CONSYS_EMI_MAPPING_OFFSET, + .p_ecso = &mtk_wcn_emi_state_off, + .pda_dl_patch_flag = 1, + .emi_met_size = (32*KBYTE), + .emi_met_data_offset = CONSYS_EMI_MET_DATA_OFFSET, + .emi_core_dump_offset = CONSYS_EMI_COREDUMP_OFFSET, +}; + +WMT_CONSYS_IC_OPS consys_ic_ops = { + .consys_ic_clock_buffer_ctrl = consys_clock_buffer_ctrl, + .consys_ic_hw_reset_bit_set = consys_hw_reset_bit_set, + .consys_ic_hw_spm_clk_gating_enable = consys_hw_spm_clk_gating_enable, + .consys_ic_hw_power_ctrl = consys_hw_power_ctrl, + .consys_ic_ahb_clock_ctrl = consys_ahb_clock_ctrl, + .polling_consys_ic_chipid = polling_consys_chipid, + .consys_ic_acr_reg_setting = consys_acr_reg_setting, + .consys_ic_afe_reg_setting = consys_afe_reg_setting, + .consys_ic_hw_vcn18_ctrl = consys_hw_vcn18_ctrl, + .consys_ic_vcn28_hw_mode_ctrl = consys_vcn28_hw_mode_ctrl, + .consys_ic_hw_vcn28_ctrl = consys_hw_vcn28_ctrl, + .consys_ic_hw_wifi_vcn33_ctrl = consys_hw_wifi_vcn33_ctrl, + .consys_ic_hw_bt_vcn33_ctrl = consys_hw_bt_vcn33_ctrl, + .consys_ic_hw_vcn_ctrl_after_idle = consys_hw_vcn_ctrl_after_idle, + .consys_ic_soc_chipid_get = consys_soc_chipid_get, + .consys_ic_emi_mpu_set_region_protection = consys_emi_mpu_set_region_protection, + .consys_ic_emi_set_remapping_reg = consys_emi_set_remapping_reg, + .ic_bt_wifi_share_v33_spin_lock_init = bt_wifi_share_v33_spin_lock_init, + .consys_ic_clk_get_from_dts = consys_clk_get_from_dts, + .consys_ic_pmic_get_from_dts = consys_pmic_get_from_dts, + .consys_ic_read_irq_info_from_dts = consys_read_irq_info_from_dts, + .consys_ic_read_reg_from_dts = consys_read_reg_from_dts, + .consys_ic_read_cpupcr = consys_read_cpupcr, + .ic_force_trigger_assert_debug_pin = force_trigger_assert_debug_pin, + .consys_ic_co_clock_type = consys_co_clock_type, + .consys_ic_soc_get_emi_phy_add = consys_soc_get_emi_phy_add, + .consys_ic_set_if_pinmux = consys_set_if_pinmux, + .consys_ic_set_dl_rom_patch_flag = consys_set_dl_rom_patch_flag, + .consys_ic_dedicated_log_path_init = consys_dedicated_log_path_init, + .consys_ic_dedicated_log_path_deinit = consys_dedicated_log_path_deinit, + .consys_ic_emi_coredump_remapping = consys_emi_coredump_remapping, + .consys_ic_reset_emi_coredump = consys_reset_emi_coredump, + .consys_ic_check_reg_readable = consys_check_reg_readable, + .consys_ic_clock_fail_dump = consys_ic_clock_fail_dump, + .consys_ic_is_connsys_reg = consys_is_connsys_reg, + .consys_ic_is_host_csr = consys_is_host_csr, + .consys_ic_dump_osc_state = consys_dump_osc_state, + .consys_ic_set_pdma_axi_rready_force_high = consys_set_pdma_axi_rready_force_high, + .consys_ic_set_mcif_emi_mpu_protection = consys_set_mcif_emi_mpu_protection, + .consys_ic_calibration_backup_restore = consys_calibration_backup_restore_support, + .consys_ic_is_ant_swap_enable_by_hwid = consys_is_ant_swap_enable_by_hwid, + .consys_ic_register_devapc_cb = consyc_register_devapc_cb, + .consys_ic_emi_entry_address = consys_emi_entry_address, + .consys_ic_set_xo_osc_ctrl = consys_set_xo_osc_ctrl, + .consys_ic_identify_adie = consys_identify_adie, + .consys_ic_wifi_ctrl_setting = consys_wifi_ctrl_setting, + .consys_ic_bus_timeout_config = consys_bus_timeout_config, + .consys_ic_set_access_emi_hw_mode = consys_set_access_emi_hw_mode, + .consys_ic_dump_gating_state = consys_dump_gating_state, + .consys_ic_sleep_info_enable_ctrl = consys_sleep_info_enable_ctrl, + .consys_ic_sleep_info_read_ctrl = consys_sleep_info_read_ctrl, + .consys_ic_sleep_info_clear = consys_sleep_info_clear, + .consys_ic_get_options = consys_get_options, +#if (COMMON_KERNEL_CLK_SUPPORT) + .consys_ic_need_store_pdev = consys_need_store_pdev, + .consys_ic_store_pdev = consys_store_pdev, +#endif +}; + +static const struct connlog_emi_config connsys_fw_log_parameter = { + .emi_offset = 0x36500, + .emi_size_total = (192*1024),/* 192KB */ + .emi_size_mcu = (16*1024), + .emi_size_wifi = (64*1024), + .emi_size_bt = (64*1024), + .emi_size_gps = (32*1024), +}; + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ +static OSAL_UNSLEEPABLE_LOCK g_pwr_off_lock; +static atomic_t g_power_on = ATOMIC_INIT(0); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +INT32 rom_patch_dl_flag = 1; +UINT32 gJtagCtrl; +UINT32 g_connsys_lp_dump_info[2]; + +#if WMT_DEVAPC_DBG_SUPPORT +static struct devapc_vio_callbacks devapc_handle = { + .id = INFRA_SUBSYS_CONN, + .debug_dump = consys_devapc_violation_cb, +}; +#endif + +#if CONSYS_ENALBE_SET_JTAG +#define JTAG_ADDR1_BASE 0x10005000 +#define JTAG_ADDR2_BASE 0x11E80000 +#define JTAG_ADDR3_BASE 0x11D20000 +#define AP2CONN_JTAG_2WIRE_OFFSET 0xF00 +#endif + +INT32 mtk_wcn_consys_jtag_set_for_mcu(VOID) +{ +#if 0 +#if CONSYS_ENALBE_SET_JTAG + INT32 ret = 0; + UINT32 tmp = 0; + PVOID addr = 0; + PVOID remap_addr1 = 0; + PVOID remap_addr2 = 0; + PVOID remap_addr3 = 0; + + if (gJtagCtrl) { + + remap_addr1 = ioremap(JTAG_ADDR1_BASE, 0x1000); + if (remap_addr1 == 0) { + WMT_PLAT_PR_ERR("remap jtag_addr1 fail!\n"); + ret = -1; + goto error; + } + + remap_addr2 = ioremap(JTAG_ADDR2_BASE, 0x100); + if (remap_addr2 == 0) { + WMT_PLAT_PR_ERR("remap jtag_addr2 fail!\n"); + ret = -1; + goto error; + } + + remap_addr3 = ioremap(JTAG_ADDR3_BASE, 0x100); + if (remap_addr3 == 0) { + WMT_PLAT_PR_ERR("remap jtag_addr3 fail!\n"); + ret = -1; + goto error; + } + + WMT_PLAT_PR_INFO("WCN jtag set for mcu start...\n"); + switch (gJtagCtrl) { + case 1: + /* 7-wire jtag pinmux setting*/ +#if 1 + /* PAD AUX Function Selection */ + addr = remap_addr1 + 0x320; + tmp = readl(addr); + tmp = tmp & 0x0000000f; + tmp = tmp | 0x33333330; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + /* PAD Driving Selection */ + addr = remap_addr2 + 0xA0; + tmp = readl(addr); + tmp = tmp & 0xfff00fff; + tmp = tmp | 0x00077000; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + /* PAD PULL Selection */ + addr = remap_addr2 + 0x60; + tmp = readl(addr); + tmp = tmp & 0xfffe03ff; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + addr = remap_addr2 + 0x60; + tmp = readl(addr); + tmp = tmp & 0xfff80fff; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + +#else + /* backup */ + /* PAD AUX Function Selection */ + addr = remap_addr1 + 0x310; + tmp = readl(addr); + tmp = tmp & 0xfffff000; + tmp = tmp | 0x00000444; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + addr = remap_addr1 + 0x3C0; + tmp = readl(addr); + tmp = tmp & 0xf00ff00f; + tmp = tmp | 0x04400440; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + /* PAD Driving Selection */ + addr = remap_addr3 + 0xA0; + tmp = readl(addr); + tmp = tmp & 0x0ffffff0; + tmp = tmp | 0x70000007; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + addr = remap_addr3 + 0xB0; + tmp = readl(addr); + tmp = tmp & 0xfff0f0ff; + tmp = tmp | 0x0007070f; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); + + /* PAD PULL Selection */ + addr = remap_addr3 + 0x60; + tmp = readl(addr); + tmp = tmp & 0xf333fffe; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); +#endif + break; + case 2: + /* 2-wire jtag pinmux setting*/ +#if 0 + CONSYS_SET_BIT(conn_reg.topckgen_base + AP2CONN_JTAG_2WIRE_OFFSET, 1 << 8); + addr = remap_addr1 + 0x340; + tmp = readl(addr); + tmp = tmp & 0xfff88fff; + tmp = tmp | 0x00034000; + writel(tmp, addr); + tmp = readl(addr); + WMT_PLAT_PR_INFO("(RegAddr, RegVal):(0x%p, 0x%x)\n", addr, tmp); +#endif + break; + default: + WMT_PLAT_PR_INFO("unsupported options!\n"); + } + + } +#endif + +error: + + if (remap_addr1) + iounmap(remap_addr1); + if (remap_addr2) + iounmap(remap_addr2); + if (remap_addr3) + iounmap(remap_addr3); + + return ret; +#else + WMT_PLAT_PR_INFO("No support switch to JTAG!\n"); + + return 0; +#endif +} + +UINT32 mtk_wcn_consys_jtag_flag_ctrl(UINT32 en) +{ + WMT_PLAT_PR_INFO("%s jtag set for MCU\n", en ? "enable" : "disable"); + gJtagCtrl = en; + + return 0; +} + +static INT32 consys_clk_get_from_dts(struct platform_device *pdev) +{ +#if (!COMMON_KERNEL_CLK_SUPPORT) + clk_scp_conn_main = devm_clk_get(&pdev->dev, "conn"); + if (IS_ERR(clk_scp_conn_main)) { + WMT_PLAT_PR_ERR("[CCF]cannot get clk_scp_conn_main clock.\n"); + return PTR_ERR(clk_scp_conn_main); + } + WMT_PLAT_PR_DBG("[CCF]clk_scp_conn_main=%p\n", clk_scp_conn_main); +#endif + clk_infracfg_ao_ccif4_ap_cg = devm_clk_get(&pdev->dev, "ccif"); + if (IS_ERR(clk_infracfg_ao_ccif4_ap_cg)) { + WMT_PLAT_PR_ERR("[CCF]cannot get clk_infracfg_ao_ccif4_ap_cg clock.\n"); + return PTR_ERR(clk_infracfg_ao_ccif4_ap_cg); + } + WMT_PLAT_PR_DBG("[CCF]clk_infracfg_ao_ccif4_ap_cg=%p\n", clk_infracfg_ao_ccif4_ap_cg); + + return 0; +} + +static INT32 consys_pmic_get_from_dts(struct platform_device *pdev) +{ +#if CONSYS_PMIC_CTRL_ENABLE + reg_VCN18 = regulator_get(&pdev->dev, "vcn18"); + if (!reg_VCN18) + WMT_PLAT_PR_ERR("Regulator_get VCN_1V8 fail\n"); + reg_VCN13 = regulator_get(&pdev->dev, "vcn13"); + if (!reg_VCN13) + WMT_PLAT_PR_ERR("Regulator_get VCN_1V3 fail\n"); + reg_VCN33_1_BT = regulator_get(&pdev->dev, "vcn33_1_bt"); + if (!reg_VCN33_1_BT) + WMT_PLAT_PR_ERR("Regulator_get VCN33_1_BT fail\n"); + reg_VCN33_1_WIFI = regulator_get(&pdev->dev, "vcn33_1_wifi"); + if (!reg_VCN33_1_WIFI) + WMT_PLAT_PR_ERR("Regulator_get VCN33_1_WIFI fail\n"); + reg_VCN33_2_WIFI = regulator_get(&pdev->dev, "vcn33_2_wifi"); + if (!reg_VCN33_2_WIFI) + WMT_PLAT_PR_ERR("Regulator_get VCN33_2_WIFI fail\n"); +#endif + + return 0; +} + +static INT32 consys_co_clock_type(VOID) +{ + return 0; +} + +static INT32 consys_clock_buffer_ctrl(MTK_WCN_BOOL enable) +{ +#if (!COMMON_KERNEL_CLK_SUPPORT) + if (enable) + clk_buf_ctrl(CLK_BUF_CONN, true); /*open XO_WCN*/ + else + clk_buf_ctrl(CLK_BUF_CONN, false); /*close XO_WCN*/ +#endif + return 0; +} + +static VOID consys_set_if_pinmux(MTK_WCN_BOOL enable) +{ + UINT8 *consys_if_pinmux_reg_base = NULL; + UINT8 *consys_if_pinmux_driving_base = NULL; + + /* Switch D die pinmux for connecting A die */ + consys_if_pinmux_reg_base = ioremap_nocache(CONSYS_IF_PINMUX_REG_BASE, 0x1000); + if (!consys_if_pinmux_reg_base) { + WMT_PLAT_PR_ERR("consys_if_pinmux_reg_base(%x) ioremap fail\n", + CONSYS_IF_PINMUX_REG_BASE); + return; + } + + consys_if_pinmux_driving_base = ioremap_nocache(CONSYS_IF_PINMUX_DRIVING_BASE, 0x100); + if (!consys_if_pinmux_driving_base) { + WMT_PLAT_PR_ERR("consys_if_pinmux_driving_base(%x) ioremap fail\n", + CONSYS_IF_PINMUX_DRIVING_BASE); + if (consys_if_pinmux_reg_base) + iounmap(consys_if_pinmux_reg_base); + return; + } + + if (enable) { + CONSYS_REG_WRITE(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_01_OFFSET, + (CONSYS_REG_READ(consys_if_pinmux_reg_base + + CONSYS_IF_PINMUX_01_OFFSET) & + CONSYS_IF_PINMUX_01_MASK) | CONSYS_IF_PINMUX_01_VALUE); + CONSYS_REG_WRITE(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_02_OFFSET, + (CONSYS_REG_READ(consys_if_pinmux_reg_base + + CONSYS_IF_PINMUX_02_OFFSET) & + CONSYS_IF_PINMUX_02_MASK) | CONSYS_IF_PINMUX_02_VALUE); + /* set pinmux driving to 2mA */ + CONSYS_REG_WRITE(consys_if_pinmux_driving_base + CONSYS_IF_PINMUX_DRIVING_OFFSET_1, + (CONSYS_REG_READ(consys_if_pinmux_driving_base + + CONSYS_IF_PINMUX_DRIVING_OFFSET_1) & + CONSYS_IF_PINMUX_DRIVING_MASK_1) | CONSYS_IF_PINMUX_DRIVING_VALUE_1); + CONSYS_REG_WRITE(consys_if_pinmux_driving_base + CONSYS_IF_PINMUX_DRIVING_OFFSET_2, + (CONSYS_REG_READ(consys_if_pinmux_driving_base + + CONSYS_IF_PINMUX_DRIVING_OFFSET_2) & + CONSYS_IF_PINMUX_DRIVING_MASK_2) | CONSYS_IF_PINMUX_DRIVING_VALUE_2); + if (wmt_plat_soc_co_clock_flag_get() == 0) { + CONSYS_REG_WRITE(consys_if_pinmux_reg_base + CONSYS_CLOCK_TCXO_MODE_OFFSET, + (CONSYS_REG_READ(consys_if_pinmux_reg_base + CONSYS_CLOCK_TCXO_MODE_OFFSET) & + CONSYS_CLOCK_TCXO_MODE_MASK) | CONSYS_CLOCK_TCXO_MODE_VALUE); + } + } else { + CONSYS_REG_WRITE(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_01_OFFSET, + CONSYS_REG_READ(consys_if_pinmux_reg_base + + CONSYS_IF_PINMUX_01_OFFSET) & CONSYS_IF_PINMUX_01_MASK); + CONSYS_REG_WRITE(consys_if_pinmux_reg_base + CONSYS_IF_PINMUX_02_OFFSET, + CONSYS_REG_READ(consys_if_pinmux_reg_base + + CONSYS_IF_PINMUX_02_OFFSET) & CONSYS_IF_PINMUX_02_MASK); + } + + if (consys_if_pinmux_reg_base) + iounmap(consys_if_pinmux_reg_base); + if (consys_if_pinmux_driving_base) + iounmap(consys_if_pinmux_driving_base); +} + +static VOID consys_hw_reset_bit_set(MTK_WCN_BOOL enable) +{ + UINT32 consys_ver_id = 0; + UINT32 cnt = 0; +#if CONSYS_PMIC_CTRL_6635 + UINT8 *consys_reg_base = NULL; +#endif + + if (enable) { + /*3.assert CONNSYS CPU SW reset 0x10007018 "[12]=1'b1 [31:24]=8'h88 (key)" */ + CONSYS_REG_WRITE((conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET), + CONSYS_REG_READ(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET) | + CONSYS_CPU_SW_RST_BIT | CONSYS_CPU_SW_RST_CTRL_KEY); + } else { + /*16.deassert CONNSYS CPU SW reset 0x10007018 "[12]=1'b0 [31:24] =8'h88 (key)" */ + CONSYS_REG_WRITE(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET, + (CONSYS_REG_READ(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET) & + ~CONSYS_CPU_SW_RST_BIT) | CONSYS_CPU_SW_RST_CTRL_KEY); + /* check CONNSYS power-on completion + * (polling "0x8000_0600[31:0]" == 0x1D1E and each polling interval is "1ms") + * (apply this for guarantee that CONNSYS CPU goes to "cos_idle_loop") + */ + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_base + 0x600); + while (consys_ver_id != 0x1D1E) { + if (cnt > 10) + break; + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_base + 0x600); + WMT_PLAT_PR_INFO("0x18002600(0x%x)\n", consys_ver_id); + WMT_PLAT_PR_INFO("0x1800216c(0x%x)\n", + CONSYS_REG_READ(conn_reg.mcu_base + 0x16c)); + WMT_PLAT_PR_INFO("0x18007104(0x%x)\n", + CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + + CONSYS_CPUPCR_OFFSET)); + msleep(20); + cnt++; + } + +#if CONSYS_PMIC_CTRL_6635 + /* if(MT6635) CONN_WF_CTRL2 swtich to CONN mode */ + consys_reg_base = ioremap_nocache(CONSYS_IF_PINMUX_REG_BASE, 0x1000); + if (!consys_reg_base) { + WMT_PLAT_PR_ERR("consys_if_pinmux_reg_base(%x) ioremap fail\n", + CONSYS_IF_PINMUX_REG_BASE); + return; + } + CONSYS_REG_WRITE(consys_reg_base + CONSYS_WF_CTRL2_03_OFFSET, + (CONSYS_REG_READ(consys_reg_base + CONSYS_WF_CTRL2_03_OFFSET) & + CONSYS_WF_CTRL2_03_MASK) | CONSYS_WF_CTRL2_CONN_MODE); + if (consys_reg_base) + iounmap(consys_reg_base); + else + WMT_PLAT_PR_ERR("consys_if_pinmux_reg_base(0x%x) ioremap fail!\n", + CONSYS_IF_PINMUX_REG_BASE); +#endif + } +} + +static VOID consys_hw_spm_clk_gating_enable(VOID) +{ + /* turn on SPM clock (apply this for SPM's CONNSYS power control related CR accessing) */ + CONSYS_REG_WRITE((conn_reg.spm_base + CONSYS_PWRON_CONFG_EN_OFFSET), + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWRON_CONFG_EN_OFFSET) | + CONSYS_SPM_PWR_ON_CLK_BIT | CONSYS_SPM_PWR_ON_CLK_CTRL_KEY); +} + +static INT32 consys_hw_power_ctrl(MTK_WCN_BOOL enable) +{ +#if CONSYS_PWR_ON_OFF_API_AVAILABLE + INT32 iRet = 0; +#else + INT32 value = 0; + INT32 i = 0; +#endif + + if (enable) { +#if CONSYS_PWR_ON_OFF_API_AVAILABLE + iRet = clk_prepare_enable(clk_infracfg_ao_ccif4_ap_cg); + if (iRet) { + WMT_PLAT_PR_ERR("clk_prepare_enable(clk_infracfg_ao_ccif4_ap_cg) fail(%d)\n", iRet); + return iRet; + } + WMT_PLAT_PR_DBG("clk_prepare_enable(clk_infracfg_ao_ccif4_ap_cg) ok\n"); +#if (COMMON_KERNEL_CLK_SUPPORT) + iRet = pm_runtime_get_sync(&connsys_pdev->dev); + if (iRet) + WMT_PLAT_PR_INFO("pm_runtime_get_sync() fail(%d)\n", iRet); + else + WMT_PLAT_PR_INFO("pm_runtime_get_sync() CONSYS ok\n"); + + iRet = device_init_wakeup(&connsys_pdev->dev, true); + if (iRet) + WMT_PLAT_PR_INFO("device_init_wakeup(true) fail.\n"); + else + WMT_PLAT_PR_INFO("device_init_wakeup(true) CONSYS ok\n"); +#else + iRet = clk_prepare_enable(clk_scp_conn_main); + if (iRet) { + WMT_PLAT_PR_ERR("clk_prepare_enable(clk_scp_conn_main) fail(%d)\n", iRet); + return iRet; + } + WMT_PLAT_PR_DBG("clk_prepare_enable(clk_scp_conn_main) ok\n"); +#endif + if (conn_reg.infra_ao_pericfg_base != 0) { + WMT_PLAT_PR_DBG("CON_STA_REG = %x\n", + CONSYS_REG_READ( + conn_reg.infra_ao_pericfg_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG)); + + /* Set CON_PWR_ON bit (CON_STA_REG[0]) */ + CONSYS_REG_WRITE(conn_reg.infra_ao_pericfg_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG, + 0x00000001); + + WMT_PLAT_PR_DBG("CON_STA_REG = %x\n", + CONSYS_REG_READ( + conn_reg.infra_ao_pericfg_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG)); + } +#else + /*write assert "conn_top_on" primary part power on, + *set "connsys_on_domain_pwr_on"=1 + */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_SPM_PWR_ON_BIT); + + /*read check "conn_top_on" primary part power status, + *check "connsys_on_domain_pwr_ack"=1 + */ + value = CONSYS_PWR_ON_ACK_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_OFFSET); + i = 0; + while (value == 0 && i < 10) { + value = CONSYS_PWR_ON_ACK_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_OFFSET); + udelay(500); + i++; + } + if (value == 0) + WMT_PLAT_PR_INFO("[POS polling info] >> check connsys_on_domain_pwr_ack status fail\n"); + + /*write assert "conn_top_on" secondary part power on, + *set "connsys_on_domain_pwr_on_s"=1 + */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_SPM_PWR_ON_S_BIT); + + /*read check "conn_top_on" secondary part power status, + *check "connsys_on_domain_pwr_ack_s"=1 + */ + value = CONSYS_PWR_ON_ACK_S_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_S_OFFSET); + i = 0; + while (value == 0 && i < 10) { + value = CONSYS_PWR_ON_ACK_S_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_PWR_CONN_ACK_S_OFFSET); + udelay(500); + i++; + } + if (value == 0) + WMT_PLAT_PR_INFO("[POS polling info] >> check connsys_on_domain_pwr_ack_s status fail\n"); + + /*write turn on AP-to-CONNSYS bus clock, set "conn_clk_dis"=0 (apply this for bus + *clock toggling) + */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) & + ~CONSYS_CLK_CTRL_BIT); + + /*wait 1us*/ + udelay(1); + + /*de-assert "conn_top_on" isolation, set "connsys_iso_en"=0 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) & + ~CONSYS_SPM_PWR_ISO_S_BIT); + + + /*de-assert CONNSYS S/W reset (TOP RGU CR), set "ap_sw_rst_b"=1 */ + CONSYS_REG_WRITE(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET, + (CONSYS_REG_READ(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET) & + ~CONSYS_SW_RST_BIT) | CONSYS_CPU_SW_RST_CTRL_KEY); + + /*de-assert CONNSYS S/W reset (SPM CR), set "ap_sw_rst_b"=1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) & + CONSYS_SPM_PWR_RST_BIT); + + /* check "conn_top_off" primary part power status, + * check "connsys_off_domain_pwr_ack"=1 + * (polling "10 times" and each polling interval is "0.5ms") + */ + value = CONSYS_SPM_CON_TOP_OFF_CHECK_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_SPM_CON_TOP_OFF_CHECK_OFFSET); + i = 0; + while (value == 0 && i < 10) { + value = CONSYS_SPM_CON_TOP_OFF_CHECK_BIT & + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_SPM_CON_TOP_OFF_CHECK_OFFSET); + udelay(500); + i++; + } + if (value == 0) + WMT_PLAT_PR_INFO("[POS polling info] >> check connsys_off_domain_pwr_ack status fail\n"); + + /*wait 0.5ms*/ + udelay(500); + + /*Turn off AHB RX bus sleep protect (AP2CONN AHB Bus protect) + *(apply this for INFRA AHB bus accessing when CONNSYS had been turned on) + */ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AHB_RX_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AHB_RX_PROT_EN_OFFSET) & + CONSYS_AHB_RX_PROT_MASK); + + value = ~CONSYS_AHB_RX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AHB_RX_PROT_STA_OFFSET); + i = 0; + while (value == 0 && i < 10) { + value = ~CONSYS_AHB_RX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AHB_RX_PROT_STA_OFFSET); + i++; + } + if (value == 0) + WMT_PLAT_PR_INFO("[POS polling info] >> check AHB RX bus sleep protect turn off fail\n"); + + /*Turn off AXI Rx bus sleep protect (CONN2AP AXI Rx Bus protect) + *(disable sleep protection when CONNSYS had been turned on) + */ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AXI_RX_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AXI_RX_PROT_EN_OFFSET) & + CONSYS_AXI_RX_PROT_MASK); + + value = ~CONSYS_AXI_RX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AXI_RX_PROT_STA_OFFSET); + i = 0; + while (value == 0 && i < 10) { + value = ~CONSYS_AXI_RX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AXI_RX_PROT_STA_OFFSET); + i++; + } + if (value == 0) + WMT_PLAT_PR_INFO("[POS polling info] >> check AXI Rx bus sleep protect turn off fail\n"); + + /*Turn off AXI TX bus sleep protect (CONN2AP AXI Tx Bus protect) + *(disable sleep protection when CONNSYS had been turned on) + */ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AXI_RX_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AXI_RX_PROT_EN_OFFSET) & + CONSYS_AXI_TX_PROT_MASK); + + value = ~CONSYS_AXI_TX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AXI_RX_PROT_STA_OFFSET); + i = 0; + while (value == 0 && i < 10) { + value = ~CONSYS_AXI_TX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AXI_RX_PROT_STA_OFFSET); + i++; + } + if (value == 0) + WMT_PLAT_PR_INFO("[POS polling info] >> check AXI Tx bus sleep protect turn off fail\n"); + + /*Turn off AHB TX bus sleep protect (AP2CONN AHB Bus protect) + *(apply this for INFRA AHB bus accessing when CONNSYS had been turned on) + */ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AXI_RX_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AXI_RX_PROT_EN_OFFSET) & + CONSYS_AHB_TX_PROT_MASK); + + value = ~CONSYS_AHB_TX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AXI_RX_PROT_STA_OFFSET); + i = 0; + while (value == 0 && i < 10) { + value = ~CONSYS_AHB_TX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AXI_RX_PROT_STA_OFFSET); + i++; + } + if (value == 0) + WMT_PLAT_PR_INFO("[POS polling info] >> check AHB TX bus sleep protect turn off fail\n"); +#endif /* CONSYS_PWR_ON_OFF_API_AVAILABLE */ + + /*wait 5ms*/ + atomic_set(&g_power_on, 1); + mdelay(5); + } else { + osal_lock_unsleepable_lock(&g_pwr_off_lock); + atomic_set(&g_power_on, 0); + osal_unlock_unsleepable_lock(&g_pwr_off_lock); + +#if CONSYS_PWR_ON_OFF_API_AVAILABLE + if (conn_reg.infra_ao_pericfg_base != 0) { + WMT_PLAT_PR_DBG("CON_STA_REG = %x\n", + CONSYS_REG_READ( + conn_reg.infra_ao_pericfg_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG)); + + /* Clean CON_STA_REG + * when power off or reset connsys + */ + CONSYS_REG_WRITE((conn_reg.infra_ao_pericfg_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG), 0); + + WMT_PLAT_PR_DBG("CON_STA_REG = %x\n", + CONSYS_REG_READ( + conn_reg.infra_ao_pericfg_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG)); + } +#if (COMMON_KERNEL_CLK_SUPPORT) + iRet = device_init_wakeup(&connsys_pdev->dev, false); + if (iRet) + WMT_PLAT_PR_INFO("device_init_wakeup(false) fail.\n"); + else + WMT_PLAT_PR_INFO("device_init_wakeup(false) CONSYS ok\n"); + + iRet = pm_runtime_put_sync(&connsys_pdev->dev); + if (iRet) + WMT_PLAT_PR_INFO("pm_runtime_put_sync() fail.\n"); + else + WMT_PLAT_PR_INFO("pm_runtime_put_sync() CONSYS ok\n"); +#else + clk_disable_unprepare(clk_scp_conn_main); + WMT_PLAT_PR_DBG("clk_disable_unprepare(clk_scp_conn_main) calling\n"); +#endif + /* Clean CCIF4 ACK status */ + /* Wait 100us to make sure all ongoing tx interrupt could be + * reset. + * According to profiling result, the time between read + * register and send tx interrupt is less than 20 us. + */ + udelay(100); + if (conn_reg.ap_pccif4_base != 0) { + CONSYS_REG_WRITE((conn_reg.ap_pccif4_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PCCIF_ACK_OFFSET), + 0xFF); + WMT_PLAT_PR_DBG("AP_PCCIF_ACK = %x\n", + CONSYS_REG_READ( + conn_reg.ap_pccif4_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PCCIF_ACK_OFFSET)); + } + + clk_disable_unprepare(clk_infracfg_ao_ccif4_ap_cg); + WMT_PLAT_PR_DBG("clk_disable_unprepare(clk_infracfg_ao_ccif4_ap_cg) calling\n"); + +#else + /* Turn on AHB bus sleep protect (AP2CONN AHB Bus protect) + * (apply this for INFRA AXI bus protection to prevent bus hang + * when CONNSYS had been turned off) + */ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AHBAXI_PROT_EN_OFFSET) & + CONSYS_AP2CONN_PROT_MASK); + value = CONSYS_AP2CONN_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_STA_OFFSET); + i = 0; + while (value == CONSYS_AP2CONN_PROT_MASK || i > 10) { + value = CONSYS_AP2CONN_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AHBAXI_PROT_STA_OFFSET); + i++; + } + /* Turn on AXI Tx bus sleep protect (CONN2AP AXI Tx Bus protect) + * (apply this for INFRA AXI bus protection to prevent bus hang + * when CONNSYS had been turned off) + * Note : Should turn on AXI Tx sleep protection first. + */ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AHBAXI_PROT_EN_OFFSET) & + CONSYS_TX_PROT_MASK); + value = CONSYS_TX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_STA_OFFSET); + i = 0; + while (value == CONSYS_TX_PROT_MASK || i > 10) { + value = CONSYS_TX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AHBAXI_PROT_STA_OFFSET); + i++; + } + /* Turn on AXI Rx bus sleep protect (CONN2AP AXI RX Bus protect) + * (apply this for INFRA AXI bus protection to prevent bus hang + * when CONNSYS had been turned off) + * Note : Should turn on AXI Rx sleep protection + * after AXI Tx sleep protection has been turn on. + */ + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AHBAXI_PROT_EN_OFFSET) & + CONSYS_RX_PROT_MASK); + value = CONSYS_RX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AHBAXI_PROT_STA_OFFSET); + i = 0; + while (value == CONSYS_RX_PROT_MASK || i > 10) { + value = CONSYS_RX_PROT_MASK & + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AHBAXI_PROT_STA_OFFSET); + i++; + } + + /*assert "conn_top_on" isolation, set "connsys_iso_en"=1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_SPM_PWR_ISO_S_BIT); + /*assert CONNSYS S/W reset (TOP RGU CR), set "ap_sw_rst_b"=0 */ + CONSYS_REG_WRITE(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET, + (CONSYS_REG_READ(conn_reg.ap_rgu_base + CONSYS_CPU_SW_RST_OFFSET) & + CONSYS_SW_RST_BIT) | CONSYS_CPU_SW_RST_CTRL_KEY); + /*assert CONNSYS S/W reset (SPM CR), set "ap_sw_rst_b"=0 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + ~CONSYS_SPM_PWR_RST_BIT); + /*write conn_clk_dis=1, disable connsys clock 0x1000632C [4] 1'b1 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) | + CONSYS_CLK_CTRL_BIT); + /*wait 1us */ + udelay(1); + /*write conn_top1_pwr_on=0, power off conn_top1 0x1000632C [3:2] 2'b00 */ + CONSYS_REG_WRITE(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.spm_base + CONSYS_TOP1_PWR_CTRL_OFFSET) & + ~(CONSYS_SPM_PWR_ON_BIT | CONSYS_SPM_PWR_ON_S_BIT)); +#endif /* CONSYS_PWR_ON_OFF_API_AVAILABLE */ + } + +#if CONSYS_PWR_ON_OFF_API_AVAILABLE + return iRet; +#else + return 0; +#endif +} + +static INT32 consys_ahb_clock_ctrl(MTK_WCN_BOOL enable) +{ + return 0; +} + +static INT32 polling_consys_chipid(VOID) +{ + UINT32 retry = 10; + UINT32 consys_ver_id = 0; + UINT32 consys_hw_ver = 0; + UINT32 consys_fw_ver = 0; + + if ((conn_reg.mcu_top_misc_off_base == 0) || (conn_reg.mcu_base == 0)) + return 0; + + /*12.poll CONNSYS CHIP ID until chipid is returned 0x10070000 */ + while (retry-- > 0) { + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_top_misc_off_base + + CONSYS_IP_VER_OFFSET); + if (consys_ver_id == CONSYS_IP_VER_ID) { + WMT_PLAT_PR_INFO("retry(%d)consys version id(0x%08x)\n", + retry, consys_ver_id); + consys_hw_ver = CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HW_ID_OFFSET); + WMT_PLAT_PR_INFO("consys HW version id(0x%x)\n", consys_hw_ver & 0xFFFF); + consys_fw_ver = CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_FW_ID_OFFSET); + WMT_PLAT_PR_INFO("consys FW version id(0x%x)\n", consys_fw_ver & 0xFFFF); + + consys_dl_rom_patch(consys_ver_id, consys_fw_ver); + break; + } + WMT_PLAT_PR_ERR("Read CONSYS version id(0x%08x)", consys_ver_id); + msleep(20); + } + + if (retry <= 0) { +#if defined(KERNEL_clk_buf_show_status_info) + KERNEL_clk_buf_show_status_info(); /* dump clock buffer */ +#endif + return -1; + } + + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_top_misc_off_base + CONSYS_CONF_ID_OFFSET); + WMT_PLAT_PR_INFO("consys configuration id(0x%x)\n", consys_ver_id & 0xF); + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HW_ID_OFFSET); + WMT_PLAT_PR_INFO("consys HW version id(0x%x)\n", consys_ver_id & 0xFFFF); + consys_ver_id = CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_FW_ID_OFFSET); + WMT_PLAT_PR_INFO("consys FW version id(0x%x)\n", consys_ver_id & 0xFFFF); + + return 0; +} + +static VOID consys_set_access_emi_hw_mode(VOID) +{ + if (conn_reg.mcu_top_misc_on_base == 0) + return; + + /* conn2ap access EMI hw mode with slpprotect ctrl */ + CONSYS_REG_WRITE(conn_reg.mcu_top_misc_on_base + CONSYS_ACCESS_EMI_HW_MODE_OFFSET, + CONSYS_REG_READ(conn_reg.mcu_top_misc_on_base + CONSYS_ACCESS_EMI_HW_MODE_OFFSET) | + (0x1 << 0)); +} + +static VOID consys_acr_reg_setting(VOID) +{ + WMT_PLAT_PR_INFO("No need to do acr"); +} + +static VOID consys_afe_reg_setting(VOID) +{ + UINT8 *consys_afe_wbg_reg_base = NULL; + /* AFE WBG CR (if needed), + * note that this CR must be backuped and restored by command batch engine + * 0x180B_3010[31:0] 0x00000000 + * 0x180B_3018[31:0] 0x144B0160 + * 0x180B_3040[31:0] 0x10990C13 + * 0x180B_3058[31:0] 0xCD258051 + * 0x180B_3078[31:0] 0xC5258251 + * 0x180B_3094[31:0] 0xC5258251 + * 0x180B_3100[31:0] 0x10990C13 + */ + consys_afe_wbg_reg_base = ioremap_nocache(CONSYS_AFE_WBG_REG_BASE, 0x200); + if (consys_afe_wbg_reg_base) { + CONSYS_REG_WRITE(consys_afe_wbg_reg_base + CONSYS_AFE_WBG_REG_AFE_01_OFFSET, + CONSYS_AFE_WBG_REG_AFE_01_VALUE); + CONSYS_REG_WRITE(consys_afe_wbg_reg_base + CONSYS_AFE_WBG_REG_RCK_01_OFFSET, + CONSYS_AFE_WBG_REG_RCK_01_VALUE); + CONSYS_REG_WRITE(consys_afe_wbg_reg_base + CONSYS_AFE_WBG_REG_GL1_01_OFFSET, + CONSYS_AFE_WBG_REG_GL1_01_VALUE); + CONSYS_REG_WRITE(consys_afe_wbg_reg_base + CONSYS_AFE_WBG_REG_BT_TX_03_OFFSET, + CONSYS_AFE_WBG_REG_BT_TX_03_VALUE); + CONSYS_REG_WRITE(consys_afe_wbg_reg_base + CONSYS_AFE_WBG_REG_WF0_TX_03_OFFSET, + CONSYS_AFE_WBG_REG_WF0_TX_03_VALUE); + CONSYS_REG_WRITE(consys_afe_wbg_reg_base + CONSYS_AFE_WBG_REG_WF1_TX_03_OFFSET, + CONSYS_AFE_WBG_REG_WF1_TX_03_VALUE); + CONSYS_REG_WRITE(consys_afe_wbg_reg_base + CONSYS_AFE_WBG_REG_GL5_01_OFFSET, + CONSYS_AFE_WBG_REG_GL5_01_VALUE); + iounmap(consys_afe_wbg_reg_base); + } else { + WMT_PLAT_PR_ERR("CONSYS_AFE_WBG_REG_BASE(0x%x) ioremap fail!\n", + CONSYS_AFE_WBG_REG_BASE); + } +} + +static VOID consys_emi_entry_address(VOID) +{ + /* EMI entry address (define by CONNSYS MCU SE) + * 0x1800_2504[31:0] 0xF011_0000 + * 0x1800_2508[31:0] 0xF01D_0000 + */ + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_EMI_BT_ENTRY_OFFSET, + CONSYS_EMI_BT_ENTRY_ADDRESS); + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_EMI_WIFI_ENTRY_OFFSET, + CONSYS_EMI_WIFI_ENTRY_ADDRESS); +} + +static VOID consys_set_xo_osc_ctrl(VOID) +{ + UINT8 *consys_reg_base = NULL; + UINT32 value = 0; + + consys_reg_base = ioremap_nocache(CONSYS_COCLOCK_STABLE_TIME_BASE, 0x100); + if (consys_reg_base) { + if (!consys_is_rc_mode_enable()) { + /* set CR "XO initial stable time" and "XO bg stable time" + * to optimize the wakeup time after sleep + * clear "source clock enable ack to XO state" mask + */ + CONSYS_REG_WRITE(consys_reg_base + CONSYS_COCLOCK_RC_CTL_0_TOP_OSC_RC_EN_OFFSET, + CONSYS_REG_READ(consys_reg_base + CONSYS_COCLOCK_RC_CTL_0_TOP_OSC_RC_EN_OFFSET) & + ~CONSYS_COCLOCK_RC_CTL_0_TOP_OSC_RC_EN_BIT); + + if (wmt_plat_soc_co_clock_flag_get()) { + value = CONSYS_REG_READ(consys_reg_base); + value = (value & CONSYS_COCLOCK_STABLE_TIME_MASK) | CONSYS_COCLOCK_STABLE_TIME; + CONSYS_REG_WRITE(consys_reg_base, value); + + value = CONSYS_REG_READ(consys_reg_base + CONSYS_COCLOCK_ACK_ENABLE_OFFSET); + value = (value & CONSYS_COCLOCK_ACK_ENABLE_MAST) | CONSYS_COCLOCK_ACK_ENABLE_VALUE; + value = value & (~CONSYS_COCLOCK_ACK_ENABLE_BIT); + CONSYS_REG_WRITE(consys_reg_base + CONSYS_COCLOCK_ACK_ENABLE_OFFSET, value); + } + } else { + CONSYS_REG_WRITE(consys_reg_base + CONSYS_COCLOCK_RC_CTL_1_GPS_XO_OFFSET, + CONSYS_COCLOCK_RC_CTL_1_XO_VALUE); + + CONSYS_REG_WRITE(consys_reg_base + CONSYS_COCLOCK_RC_CTL_0_GPS_ACK_OFFSET, + CONSYS_REG_READ(consys_reg_base + CONSYS_COCLOCK_RC_CTL_0_GPS_ACK_OFFSET) & + ~CONSYS_COCLOCK_RC_CTL_0_ACK_BIT); + + CONSYS_REG_WRITE(consys_reg_base + CONSYS_COCLOCK_RC_CTL_1_BT_XO_OFFSET, + CONSYS_COCLOCK_RC_CTL_1_XO_VALUE); + + CONSYS_REG_WRITE(consys_reg_base + CONSYS_COCLOCK_RC_CTL_0_BT_ACK_OFFSET, + CONSYS_REG_READ(consys_reg_base + CONSYS_COCLOCK_RC_CTL_0_BT_ACK_OFFSET) & + ~CONSYS_COCLOCK_RC_CTL_0_ACK_BIT); + + CONSYS_REG_WRITE(consys_reg_base + CONSYS_COCLOCK_RC_CTL_1_WF_XO_OFFSET, + CONSYS_COCLOCK_RC_CTL_1_XO_VALUE); + + CONSYS_REG_WRITE(consys_reg_base + CONSYS_COCLOCK_RC_CTL_0_WF_ACK_OFFSET, + CONSYS_REG_READ(consys_reg_base + CONSYS_COCLOCK_RC_CTL_0_WF_ACK_OFFSET) & + ~CONSYS_COCLOCK_RC_CTL_0_ACK_BIT); + + CONSYS_REG_WRITE(consys_reg_base + CONSYS_COCLOCK_RC_CTL_1_TOP_XO_OFFSET, + CONSYS_COCLOCK_RC_CTL_1_XO_VALUE); + + CONSYS_REG_WRITE(consys_reg_base + CONSYS_COCLOCK_RC_CTL_0_TOP_ACK_OFFSET, + CONSYS_REG_READ(consys_reg_base + CONSYS_COCLOCK_RC_CTL_0_TOP_ACK_OFFSET) & + ~CONSYS_COCLOCK_RC_CTL_0_ACK_BIT); + + CONSYS_REG_WRITE(consys_reg_base + CONSYS_COCLOCK_RC_CTL_0_TOP_OSC_RC_EN_OFFSET, + CONSYS_REG_READ(consys_reg_base + CONSYS_COCLOCK_RC_CTL_0_TOP_OSC_RC_EN_OFFSET) | + CONSYS_COCLOCK_RC_CTL_0_GPS_OSC_RC_EN_BIT); + + CONSYS_REG_WRITE(consys_reg_base + CONSYS_COCLOCK_RC_CTL_0_TOP_OSC_RC_EN_OFFSET, + CONSYS_REG_READ(consys_reg_base + CONSYS_COCLOCK_RC_CTL_0_TOP_OSC_RC_EN_OFFSET) | + CONSYS_COCLOCK_RC_CTL_0_BT_OSC_RC_EN_BIT); + + CONSYS_REG_WRITE(consys_reg_base + CONSYS_COCLOCK_RC_CTL_0_TOP_OSC_RC_EN_OFFSET, + CONSYS_REG_READ(consys_reg_base + CONSYS_COCLOCK_RC_CTL_0_TOP_OSC_RC_EN_OFFSET) | + CONSYS_COCLOCK_RC_CTL_0_WF_OSC_RC_EN_BIT); + + CONSYS_REG_WRITE(consys_reg_base + CONSYS_COCLOCK_RC_CTL_0_TOP_OSC_RC_EN_OFFSET, + CONSYS_REG_READ(consys_reg_base + CONSYS_COCLOCK_RC_CTL_0_TOP_OSC_RC_EN_OFFSET) | + CONSYS_COCLOCK_RC_CTL_0_TOP_OSC_RC_EN_BIT_2); + + CONSYS_REG_WRITE(consys_reg_base + CONSYS_COCLOCK_RC_CTL_0_TOP_OSC_RC_EN_OFFSET, + CONSYS_REG_READ(consys_reg_base + CONSYS_COCLOCK_RC_CTL_0_TOP_OSC_RC_EN_OFFSET) & + ~CONSYS_COCLOCK_RC_CTL_0_OSC_LEGACY_EN_BIT); + } + iounmap(consys_reg_base); + } else { + WMT_PLAT_PR_ERR("connsys co_clock stable time base(0x%x) ioremap fail!\n", + CONSYS_COCLOCK_STABLE_TIME_BASE); + } +} + +static VOID consys_identify_adie(VOID) +{ + UINT8 *consys_reg_base = NULL; + + consys_reg_base = ioremap_nocache(CONSYS_IDENTIFY_ADIE_CR_ADDRESS, 0x100); + if (consys_reg_base) { +#if CONSYS_PMIC_CTRL_6635 + CONSYS_REG_WRITE(consys_reg_base, + CONSYS_REG_READ(consys_reg_base) & + ~CONSYS_IDENTIFY_ADIE_ENABLE_BIT); +#else + CONSYS_REG_WRITE(consys_reg_base, + CONSYS_REG_READ(consys_reg_base) | + CONSYS_IDENTIFY_ADIE_ENABLE_BIT); +#endif + iounmap(consys_reg_base); + } else { + WMT_PLAT_PR_ERR("CONSYS_IDENTIFY_ADIE_CR_ADDRESS(0x%x) ioremap fail!\n", + CONSYS_IDENTIFY_ADIE_CR_ADDRESS); + } +} + +static VOID consys_wifi_ctrl_setting(VOID) +{ +#if CONSYS_PMIC_CTRL_6635 + UINT8 *consys_reg_base = NULL; + + /* if(MT6635) + * CONN_WF_CTRL2 swtich to GPIO mode, GPIO output value + * before patch download swtich back to CONN mode. + */ + consys_reg_base = ioremap_nocache(CONSYS_IF_PINMUX_REG_BASE, 0x1000); + if (consys_reg_base) { + CONSYS_REG_WRITE(consys_reg_base + CONSYS_WF_CTRL2_01_OFFSET, + (CONSYS_REG_READ(consys_reg_base + CONSYS_WF_CTRL2_01_OFFSET) & + CONSYS_WF_CTRL2_01_MASK) | CONSYS_WF_CTRL2_01_VALUE); + CONSYS_REG_WRITE(consys_reg_base + CONSYS_WF_CTRL2_02_OFFSET, + (CONSYS_REG_READ(consys_reg_base + CONSYS_WF_CTRL2_02_OFFSET) & + CONSYS_WF_CTRL2_02_MASK) | CONSYS_WF_CTRL2_02_VALUE); + CONSYS_REG_WRITE(consys_reg_base + CONSYS_WF_CTRL2_03_OFFSET, + (CONSYS_REG_READ(consys_reg_base + CONSYS_WF_CTRL2_03_OFFSET) & + CONSYS_WF_CTRL2_03_MASK) | CONSYS_WF_CTRL2_GPIO_MODE); + iounmap(consys_reg_base); + } else { + WMT_PLAT_PR_ERR("consys_if_pinmux_reg_base(0x%x) ioremap fail!\n", + CONSYS_IF_PINMUX_REG_BASE); + } +#endif +} + +static VOID consys_bus_timeout_config(VOID) +{ + UINT8 *consys_reg_base = NULL; + + /* connsys bus time out configure, enable AHB bus timeout */ + consys_reg_base = ioremap_nocache(CONSYS_AHB_TIMEOUT_EN_ADDRESS, 0x100); + if (consys_reg_base) { + CONSYS_REG_WRITE(consys_reg_base, CONSYS_AHB_TIMEOUT_EN_VALUE); + iounmap(consys_reg_base); + } else { + WMT_PLAT_PR_ERR("CONSYS_AHB_TIMEOUT_EN_ADDRESS(0x%x) ioremap fail!\n", + CONSYS_AHB_TIMEOUT_EN_ADDRESS); + } +} + +static INT32 consys_hw_vcn18_ctrl(MTK_WCN_BOOL enable) +{ +#if CONSYS_PMIC_CTRL_ENABLE + if (enable) { + if (consys_is_rc_mode_enable()) { + /* RC mode */ + WMT_PLAT_PR_INFO("Turn on VCN18, VCN13 in RC mode\n"); + /* VCN18 */ +#if (!COMMON_KERNEL_PMIC_SUPPORT) + /* PMRC_EN[7][6][5][4] HW_OP_EN = 1, HW_OP_CFG = 0 */ + KERNEL_pmic_ldo_vcn18_lp(SRCLKEN7, 0, 1, HW_OFF); + KERNEL_pmic_ldo_vcn18_lp(SRCLKEN6, 0, 1, HW_OFF); + KERNEL_pmic_ldo_vcn18_lp(SRCLKEN5, 0, 1, HW_OFF); + KERNEL_pmic_ldo_vcn18_lp(SRCLKEN4, 0, 1, HW_OFF); + /* SW_LP =1 */ + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN18_LP, 0); +#else + if (g_regmap) { + regmap_write(g_regmap, PMIC_RG_LDO_VCN18_OP_EN_SET_ADDR, 1 << 7); + regmap_write(g_regmap, PMIC_RG_LDO_VCN18_OP_CFG_SET_ADDR, 0 << 7); + regmap_write(g_regmap, PMIC_RG_LDO_VCN18_OP_EN_SET_ADDR, 1 << 6); + regmap_write(g_regmap, PMIC_RG_LDO_VCN18_OP_CFG_SET_ADDR, 0 << 6); + regmap_write(g_regmap, PMIC_RG_LDO_VCN18_OP_EN_SET_ADDR, 1 << 5); + regmap_write(g_regmap, PMIC_RG_LDO_VCN18_OP_CFG_SET_ADDR, 0 << 5); + regmap_write(g_regmap, PMIC_RG_LDO_VCN18_OP_EN_SET_ADDR, 1 << 4); + regmap_write(g_regmap, PMIC_RG_LDO_VCN18_OP_CFG_SET_ADDR, 0 << 4); + regmap_update_bits(g_regmap, + PMIC_RG_LDO_VCN18_LP_ADDR, + PMIC_RG_LDO_VCN18_LP_MASK << PMIC_RG_LDO_VCN18_LP_SHIFT, + 0 << PMIC_RG_LDO_VCN18_LP_SHIFT); + } +#endif + + /*Set VCN18_SW_EN as 1 and set votage as 1V8*/ + if (reg_VCN18) { + regulator_set_voltage(reg_VCN18, 1800000, 1800000); + if (regulator_enable(reg_VCN18)) + WMT_PLAT_PR_ERR("enable VCN18 fail\n"); + else + WMT_PLAT_PR_DBG("enable VCN18 ok\n"); + } + + /* VCN13 */ +#if (!COMMON_KERNEL_PMIC_SUPPORT) + /* PMRC_EN[7][6][5][4] HW_OP_EN = 1, HW_OP_CFG = 0 */ + KERNEL_pmic_ldo_vcn13_lp(SRCLKEN7, 0, 1, HW_OFF); + KERNEL_pmic_ldo_vcn13_lp(SRCLKEN6, 0, 1, HW_OFF); + KERNEL_pmic_ldo_vcn13_lp(SRCLKEN5, 0, 1, HW_OFF); + KERNEL_pmic_ldo_vcn13_lp(SRCLKEN4, 0, 1, HW_OFF); + /* SW_LP =0 */ + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN13_LP, 0); +#else + if (g_regmap) { + regmap_write(g_regmap, PMIC_RG_LDO_VCN13_OP_EN_SET_ADDR, 1 << 7); + regmap_write(g_regmap, PMIC_RG_LDO_VCN13_OP_CFG_SET_ADDR, 0 << 7); + regmap_write(g_regmap, PMIC_RG_LDO_VCN13_OP_EN_SET_ADDR, 1 << 6); + regmap_write(g_regmap, PMIC_RG_LDO_VCN13_OP_CFG_SET_ADDR, 0 << 6); + regmap_write(g_regmap, PMIC_RG_LDO_VCN13_OP_EN_SET_ADDR, 1 << 5); + regmap_write(g_regmap, PMIC_RG_LDO_VCN13_OP_CFG_SET_ADDR, 0 << 5); + regmap_write(g_regmap, PMIC_RG_LDO_VCN13_OP_EN_SET_ADDR, 1 << 4); + regmap_write(g_regmap, PMIC_RG_LDO_VCN13_OP_CFG_SET_ADDR, 0 << 4); + regmap_update_bits(g_regmap, + PMIC_RG_LDO_VCN13_LP_ADDR, + PMIC_RG_LDO_VCN13_LP_MASK << PMIC_RG_LDO_VCN13_LP_SHIFT, + 0 << PMIC_RG_LDO_VCN13_LP_SHIFT); + } +#endif + if (reg_VCN13) { + regulator_set_voltage(reg_VCN13, 1300000, 1300000); + if (regulator_enable(reg_VCN13)) + WMT_PLAT_PR_ERR("enable VCN13 fail\n"); + else + WMT_PLAT_PR_DBG("enable VCN13 ok\n"); + } + } else { + /* Legacy mode */ + WMT_PLAT_PR_INFO("Turn on VCN18, VCN13 in legacy mode\n"); +#if (!COMMON_KERNEL_PMIC_SUPPORT) + /* HW_OP_EN = 1, HW_OP_CFG = 1 */ + KERNEL_pmic_ldo_vcn18_lp(SRCLKEN0, 1, 1, HW_LP); + /* SW_LP=0 */ + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN18_LP, 0); +#else + if (g_regmap) { + regmap_write(g_regmap, PMIC_RG_LDO_VCN18_OP_EN_SET_ADDR, 1 << 0); + regmap_write(g_regmap, PMIC_RG_LDO_VCN18_OP_CFG_SET_ADDR, 1 << 0); + regmap_update_bits(g_regmap, + PMIC_RG_LDO_VCN18_LP_ADDR, + PMIC_RG_LDO_VCN18_LP_MASK << PMIC_RG_LDO_VCN18_LP_SHIFT, + 0 << PMIC_RG_LDO_VCN18_LP_SHIFT); + } +#endif + /*Set VCN18_SW_EN as 1 and set votage as 1V8*/ + if (reg_VCN18) { + regulator_set_voltage(reg_VCN18, 1800000, 1800000); + if (regulator_enable(reg_VCN18)) + WMT_PLAT_PR_ERR("enable VCN18 fail\n"); + else + WMT_PLAT_PR_DBG("enable VCN18 ok\n"); + } +#if (!COMMON_KERNEL_PMIC_SUPPORT) + /* HW_OP_EN = 1, HW_OP_CFG = 1 */ + KERNEL_pmic_ldo_vcn13_lp(SRCLKEN0, 1, 1, HW_LP); + /* SW_LP=0 */ + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN13_LP, 0); +#else + if (g_regmap) { + regmap_write(g_regmap, PMIC_RG_LDO_VCN13_OP_EN_SET_ADDR, 1 << 0); + regmap_write(g_regmap, PMIC_RG_LDO_VCN13_OP_CFG_SET_ADDR, 1 << 0); + regmap_update_bits(g_regmap, + PMIC_RG_LDO_VCN13_LP_ADDR, + PMIC_RG_LDO_VCN13_LP_MASK << PMIC_RG_LDO_VCN13_LP_SHIFT, + 0 << PMIC_RG_LDO_VCN13_LP_SHIFT); + } +#endif + if (reg_VCN13) { + regulator_set_voltage(reg_VCN13, 1300000, 1300000); + if (regulator_enable(reg_VCN13)) + WMT_PLAT_PR_ERR("enable VCN13 fail\n"); + else + WMT_PLAT_PR_DBG("enable VCN13 ok\n"); + } + } + } else { + WMT_PLAT_PR_INFO("Turn off VCN13, VCN18\n"); + if (reg_VCN13) + regulator_disable(reg_VCN13); + /* delay 300us */ + udelay(300); + /*AP power off MT6351L VCN_1V8 LDO */ + if (reg_VCN18) { + if (regulator_disable(reg_VCN18)) + WMT_PLAT_PR_ERR("disable VCN_1V8 fail!\n"); + else + WMT_PLAT_PR_DBG("disable VCN_1V8 ok\n"); + } + } +#endif + return 0; +} + +static VOID consys_vcn28_hw_mode_ctrl(UINT32 enable) +{ + /* 6635 not supported */ +} + +static INT32 consys_hw_vcn28_ctrl(UINT32 enable) +{ + /* 6635 not supported */ + + return 0; +} + +static INT32 consys_hw_set_vcn13_vcn18_lp_mode(INT8 lp_mode) +{ + if (consys_is_rc_mode_enable()) { + if (lp_mode == 1) + udelay(50); +#if (!COMMON_KERNEL_PMIC_SUPPORT) + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN18_LP, lp_mode); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN13_LP, lp_mode); +#else + if (g_regmap) { + regmap_update_bits(g_regmap, + PMIC_RG_LDO_VCN18_LP_ADDR, + PMIC_RG_LDO_VCN18_LP_MASK << PMIC_RG_LDO_VCN18_LP_SHIFT, + lp_mode << PMIC_RG_LDO_VCN18_LP_SHIFT); + regmap_update_bits(g_regmap, + PMIC_RG_LDO_VCN13_LP_ADDR, + PMIC_RG_LDO_VCN13_LP_MASK << PMIC_RG_LDO_VCN13_LP_SHIFT, + lp_mode << PMIC_RG_LDO_VCN13_LP_SHIFT); + } +#endif + if (lp_mode == 0) + udelay(50); + } + return 0; +} + +static INT32 consys_hw_bt_vcn33_ctrl(UINT32 enable) +{ + if (enable) { +#if CONSYS_PMIC_CTRL_ENABLE + /* Switch to ON mode to avoid OC */ + consys_hw_set_vcn13_vcn18_lp_mode(0); +#if (!COMMON_KERNEL_PMIC_SUPPORT) + /* Set VS2 to 1.4625V */ + KERNEL_pmic_set_register_value(PMIC_RG_BUCK_VS2_VOSEL, 0x35); + /* request VS2 to 1.4625V by VS2 VOTER (use bit 4) */ + KERNEL_pmic_set_register_value(PMIC_RG_BUCK_VS2_VOTER_EN_SET, 0x10); + /* Set VS2 sleep voltage to 1.375V */ + KERNEL_pmic_set_register_value(PMIC_RG_BUCK_VS2_VOSEL_SLEEP, 0x2e); + /* Set VCN13 to 1.37V */ + KERNEL_pmic_set_register_value(PMIC_RG_VCN13_VOCAL, 0x7); +#else + if (g_regmap) { + /* Set VS2 to 1.4625V */ + regmap_update_bits(g_regmap, + PMIC_RG_BUCK_VS2_VOSEL_ADDR, + PMIC_RG_BUCK_VS2_VOSEL_MASK << PMIC_RG_BUCK_VS2_VOSEL_SHIFT, + 0x35 << PMIC_RG_BUCK_VS2_VOSEL_SHIFT); + /* request VS2 to 1.4625V by VS2 VOTER (use bit 4) */ + regmap_update_bits(g_regmap, + PMIC_RG_BUCK_VS2_VOTER_EN_SET_ADDR, + PMIC_RG_BUCK_VS2_VOTER_EN_SET_MASK << PMIC_RG_BUCK_VS2_VOTER_EN_SET_SHIFT, + 0x10 << PMIC_RG_BUCK_VS2_VOTER_EN_SET_SHIFT); + /* Set VS2 sleep voltage to 1.375V */ + regmap_update_bits(g_regmap, + PMIC_RG_BUCK_VS2_VOSEL_SLEEP_ADDR, + PMIC_RG_BUCK_VS2_VOSEL_SLEEP_MASK << PMIC_RG_BUCK_VS2_VOSEL_SLEEP_SHIFT, + 0x2e << PMIC_RG_BUCK_VS2_VOSEL_SLEEP_SHIFT); + /* Set VCN13 to 1.37V */ + regmap_update_bits(g_regmap, + PMIC_RG_VCN13_VOCAL_ADDR, + PMIC_RG_VCN13_VOCAL_MASK << PMIC_RG_VCN13_VOCAL_SHIFT, + 0x7 << PMIC_RG_VCN13_VOCAL_SHIFT); + } +#endif + consys_hw_set_vcn13_vcn18_lp_mode(1); + + if (consys_is_rc_mode_enable()) { + WMT_PLAT_PR_INFO("Turn on reg_VCN33_1_BT in RC mode\n"); +#if (!COMMON_KERNEL_PMIC_SUPPORT) + /* PMRC_EN[6][5] HW_OP_EN = 1, HW_OP_CFG = 0 */ + KERNEL_pmic_ldo_vcn33_1_lp(SRCLKEN6, 0, 1, HW_OFF); + KERNEL_pmic_ldo_vcn33_1_lp(SRCLKEN5, 0, 1, HW_OFF); + /* SW_LP =0 */ + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_1_LP, 0); +#else + if (g_regmap) { + regmap_write(g_regmap, PMIC_RG_LDO_VCN33_1_OP_EN_SET_ADDR, 1 << 6); + regmap_write(g_regmap, PMIC_RG_LDO_VCN33_1_OP_CFG_SET_ADDR, 0 << 6); + regmap_write(g_regmap, PMIC_RG_LDO_VCN33_1_OP_EN_SET_ADDR, 1 << 5); + regmap_write(g_regmap, PMIC_RG_LDO_VCN33_1_OP_CFG_SET_ADDR, 0 << 5); + regmap_update_bits(g_regmap, + PMIC_RG_LDO_VCN33_1_LP_ADDR, + PMIC_RG_LDO_VCN33_1_LP_MASK << PMIC_RG_LDO_VCN33_1_LP_SHIFT, + 0 << PMIC_RG_LDO_VCN33_1_LP_SHIFT); + } +#endif + regulator_set_voltage(reg_VCN33_1_BT, 3300000, 3300000); + /* SW_EN=0 */ + /* For RC mode, we don't have to control VCN33_1 & VCN33_2 */ + /* regulator_disable(reg_VCN33_1_BT); */ + } else { + WMT_PLAT_PR_INFO("Turn on reg_VCN33_1_BT in legacy mode\n"); +#if (!COMMON_KERNEL_PMIC_SUPPORT) + /* HW_OP_EN = 1, HW_OP_CFG = 0 */ + KERNEL_pmic_ldo_vcn33_1_lp(SRCLKEN0, 1, 1, HW_OFF); + /* SW_LP =0 */ + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_1_LP, 0); +#else + if (g_regmap) { + regmap_write(g_regmap, PMIC_RG_LDO_VCN33_1_OP_EN_SET_ADDR, 1 << 0); + regmap_write(g_regmap, PMIC_RG_LDO_VCN33_1_OP_CFG_SET_ADDR, 0 << 0); + regmap_update_bits(g_regmap, + PMIC_RG_LDO_VCN33_1_LP_ADDR, + PMIC_RG_LDO_VCN33_1_LP_MASK << PMIC_RG_LDO_VCN33_1_LP_SHIFT, + 0 << PMIC_RG_LDO_VCN33_1_LP_SHIFT); + } +#endif + /*Set VCN33_1_SW_EN as 1 and set votage as 3V3*/ + if (reg_VCN33_1_WIFI) { + regulator_set_voltage(reg_VCN33_1_BT, 3300000, 3300000); + if (regulator_enable(reg_VCN33_1_BT)) + WMT_PLAT_PR_ERR("WMT do WIFI PMIC on fail!\n"); + } + } +#endif + WMT_PLAT_PR_DBG("WMT do BT PMIC on\n"); + } else { + /*do BT PMIC off */ +#if CONSYS_PMIC_CTRL_ENABLE + consys_hw_set_vcn13_vcn18_lp_mode(0); +#if (!COMMON_KERNEL_PMIC_SUPPORT) + /* restore VCN13 to 1.3V */ + KERNEL_pmic_set_register_value(PMIC_RG_VCN13_VOCAL, 0); + /* clear bit 4 of VS2 VOTER then VS2 can restore to 1.35V */ + KERNEL_pmic_set_register_value(PMIC_RG_BUCK_VS2_VOTER_EN_CLR, 0x10); + /* restore VS2 sleep voltage to 1.35V */ + KERNEL_pmic_set_register_value(PMIC_RG_BUCK_VS2_VOSEL_SLEEP, 0x2c); +#else + if (g_regmap) { + /* restore VCN13 to 1.3V */ + regmap_update_bits(g_regmap, + PMIC_RG_VCN13_VOCAL_ADDR, + PMIC_RG_VCN13_VOCAL_MASK << PMIC_RG_VCN13_VOCAL_SHIFT, + 0 << PMIC_RG_VCN13_VOCAL_SHIFT); + /* clear bit 4 of VS2 VOTER then VS2 can restore to 1.35V */ + regmap_update_bits(g_regmap, + PMIC_RG_BUCK_VS2_VOTER_EN_CLR_ADDR, + PMIC_RG_BUCK_VS2_VOTER_EN_CLR_MASK << PMIC_RG_BUCK_VS2_VOTER_EN_CLR_SHIFT, + 0x10 << PMIC_RG_BUCK_VS2_VOTER_EN_CLR_SHIFT); + /* restore VS2 sleep voltage to 1.35V */ + regmap_update_bits(g_regmap, + PMIC_RG_BUCK_VS2_VOSEL_SLEEP_ADDR, + PMIC_RG_BUCK_VS2_VOSEL_SLEEP_MASK << PMIC_RG_BUCK_VS2_VOSEL_SLEEP_SHIFT, + 0x2c << PMIC_RG_BUCK_VS2_VOSEL_SLEEP_SHIFT); + } +#endif + consys_hw_set_vcn13_vcn18_lp_mode(1); + + if (consys_is_rc_mode_enable()) { + WMT_PLAT_PR_INFO("Do nothing for reg_VCN33_1_BT under RC mode when disable\n"); + } else { +#if (!COMMON_KERNEL_PMIC_SUPPORT) + /*Set VCN33_1 as low-power mode(1), HW0_OP_EN as 0, HW0_OP_CFG as HW_OFF(0)*/ + KERNEL_pmic_ldo_vcn33_1_lp(SRCLKEN0, 1, 0, HW_OFF); +#else + if (g_regmap) { + regmap_write(g_regmap, PMIC_RG_LDO_VCN33_1_OP_EN_SET_ADDR, 0 << 0); + regmap_write(g_regmap, PMIC_RG_LDO_VCN33_1_OP_CFG_SET_ADDR, 0 << 0); + } +#endif + if (reg_VCN33_1_BT) + regulator_disable(reg_VCN33_1_BT); + } +#endif + WMT_PLAT_PR_DBG("WMT do BT PMIC off\n"); + } + + return 0; +} + +static INT32 consys_hw_wifi_vcn33_ctrl(UINT32 enable) +{ + if (enable) { +#if CONSYS_PMIC_CTRL_ENABLE + if (consys_is_rc_mode_enable()) { + WMT_PLAT_PR_INFO("Turn on reg_VCN33_1_WIFI in RC mode\n"); +#if (!COMMON_KERNEL_PMIC_SUPPORT) + /* PMRC_EN[6][5] HW_OP_EN = 1, HW_OP_CFG = 0 */ + KERNEL_pmic_ldo_vcn33_1_lp(SRCLKEN6, 0, 1, HW_OFF); + KERNEL_pmic_ldo_vcn33_1_lp(SRCLKEN5, 0, 1, HW_OFF); + /* SW_LP =0 */ + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_1_LP, 0); +#else + if (g_regmap) { + regmap_write(g_regmap, PMIC_RG_LDO_VCN33_1_OP_EN_SET_ADDR, 1 << 6); + regmap_write(g_regmap, PMIC_RG_LDO_VCN33_1_OP_CFG_SET_ADDR, 0 << 6); + regmap_write(g_regmap, PMIC_RG_LDO_VCN33_1_OP_EN_SET_ADDR, 1 << 5); + regmap_write(g_regmap, PMIC_RG_LDO_VCN33_1_OP_CFG_SET_ADDR, 0 << 5); + regmap_update_bits(g_regmap, + PMIC_RG_LDO_VCN33_1_LP_ADDR, + PMIC_RG_LDO_VCN33_1_LP_MASK << PMIC_RG_LDO_VCN33_1_LP_SHIFT, + 0 << PMIC_RG_LDO_VCN33_1_LP_SHIFT); + } +#endif + regulator_set_voltage(reg_VCN33_1_WIFI, 3300000, 3300000); + /* SW_EN=0 */ + /* For RC mode, we don't have to control VCN33_1 & VCN33_2 */ + /* regulator_disable(reg_VCN33_1_WIFI); */ + + WMT_PLAT_PR_INFO("Turn on reg_VCN33_2_WIFI in RC mode\n"); +#if (!COMMON_KERNEL_PMIC_SUPPORT) + /* PMRC_EN[6] HW_OP_EN = 1, HW_OP_CFG = 0 */ + KERNEL_pmic_ldo_vcn33_2_lp(SRCLKEN6, 0, 1, HW_OFF); + /* SW_LP =0 */ + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_2_LP, 0); +#else + if (g_regmap) { + regmap_write(g_regmap, PMIC_RG_LDO_VCN33_2_OP_EN_SET_ADDR, 1 << 6); + regmap_write(g_regmap, PMIC_RG_LDO_VCN33_2_OP_CFG_SET_ADDR, 0 << 6); + regmap_update_bits(g_regmap, + PMIC_RG_LDO_VCN33_2_LP_ADDR, + PMIC_RG_LDO_VCN33_2_LP_MASK << PMIC_RG_LDO_VCN33_2_LP_SHIFT, + 0 << PMIC_RG_LDO_VCN33_2_LP_SHIFT); + } +#endif + regulator_set_voltage(reg_VCN33_2_WIFI, 3300000, 3300000); + /* SW_EN=0 */ + /* For RC mode, we don't have to control VCN33_1 & VCN33_2 */ + /* regulator_disable(reg_VCN33_2_WIFI); */ + } else { + WMT_PLAT_PR_INFO("Turn on reg_VCN33_1_WIFI in legacy mode\n"); +#if (!COMMON_KERNEL_PMIC_SUPPORT) + /* HW_OP_EN = 1, HW_OP_CFG = 0 */ + KERNEL_pmic_ldo_vcn33_1_lp(SRCLKEN0, 1, 1, HW_OFF); + /* SW_LP =0 */ + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_1_LP, 0); +#else + if (g_regmap) { + regmap_write(g_regmap, PMIC_RG_LDO_VCN33_1_OP_EN_SET_ADDR, 1 << 0); + regmap_write(g_regmap, PMIC_RG_LDO_VCN33_1_OP_CFG_SET_ADDR, 0 << 0); + regmap_update_bits(g_regmap, + PMIC_RG_LDO_VCN33_1_LP_ADDR, + PMIC_RG_LDO_VCN33_1_LP_MASK << PMIC_RG_LDO_VCN33_1_LP_SHIFT, + 0 << PMIC_RG_LDO_VCN33_1_LP_SHIFT); + } +#endif + /*Set VCN33_1_SW_EN as 1 and set votage as 3V3*/ + if (reg_VCN33_1_WIFI) { + regulator_set_voltage(reg_VCN33_1_WIFI, 3300000, 3300000); + if (regulator_enable(reg_VCN33_1_WIFI)) + WMT_PLAT_PR_ERR("WMT do WIFI PMIC on fail!\n"); + } + + WMT_PLAT_PR_INFO("Turn on reg_VCN33_2_WIFI in legacy mode\n"); +#if (!COMMON_KERNEL_PMIC_SUPPORT) + /* HW_OP_EN = 1, HW_OP_CFG = 0 */ + KERNEL_pmic_ldo_vcn33_2_lp(SRCLKEN0, 1, 1, HW_OFF); + /* SW_LP =0 */ + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_2_LP, 0); +#else + if (g_regmap) { + regmap_write(g_regmap, PMIC_RG_LDO_VCN33_2_OP_EN_SET_ADDR, 1 << 0); + regmap_write(g_regmap, PMIC_RG_LDO_VCN33_2_OP_CFG_SET_ADDR, 0 << 0); + regmap_update_bits(g_regmap, + PMIC_RG_LDO_VCN33_2_LP_ADDR, + PMIC_RG_LDO_VCN33_2_LP_MASK << PMIC_RG_LDO_VCN33_2_LP_SHIFT, + 0 << PMIC_RG_LDO_VCN33_2_LP_SHIFT); + } +#endif + /*Set VCN33_1_SW_EN as 1 and set votage as 3V3*/ + if (reg_VCN33_2_WIFI) { + regulator_set_voltage(reg_VCN33_2_WIFI, 3300000, 3300000); + if (regulator_enable(reg_VCN33_2_WIFI)) + WMT_PLAT_PR_ERR("WMT do WIFI PMIC on fail!\n"); + } + } +#endif + WMT_PLAT_PR_DBG("WMT do WIFI PMIC on\n"); + } else { + /*do WIFI PMIC off */ + /*switch WIFI PALDO control from HW mode to SW mode:0x418[14]-->0x0 */ +#if CONSYS_PMIC_CTRL_ENABLE + if (consys_is_rc_mode_enable()) { + WMT_PLAT_PR_INFO("Do nothing for VCN33_1 under RC mode when disable\n"); + } else { +#if (!COMMON_KERNEL_PMIC_SUPPORT) + /*Set VCN33_1 as low-power mode(1), HW0_OP_EN as 0, HW0_OP_CFG as HW_OFF(0)*/ + KERNEL_pmic_ldo_vcn33_1_lp(SRCLKEN0, 1, 0, HW_OFF); +#else + if (g_regmap) { + regmap_write(g_regmap, PMIC_RG_LDO_VCN33_1_OP_EN_SET_ADDR, 0 << 0); + regmap_write(g_regmap, PMIC_RG_LDO_VCN33_1_OP_CFG_SET_ADDR, 0 << 0); + } +#endif + if (reg_VCN33_1_WIFI) + regulator_disable(reg_VCN33_1_WIFI); +#if (!COMMON_KERNEL_PMIC_SUPPORT) + /*Set VCN33_2 as low-power mode(1), HW0_OP_EN as 0, HW0_OP_CFG as HW_OFF(0)*/ + KERNEL_pmic_ldo_vcn33_2_lp(SRCLKEN0, 1, 0, HW_OFF); +#else + if (g_regmap) { + regmap_write(g_regmap, PMIC_RG_LDO_VCN33_2_OP_EN_SET_ADDR, 0 << 0); + regmap_write(g_regmap, PMIC_RG_LDO_VCN33_2_OP_CFG_SET_ADDR, 0 << 0); + } +#endif + if (reg_VCN33_2_WIFI) + regulator_disable(reg_VCN33_2_WIFI); + } +#endif + WMT_PLAT_PR_DBG("WMT do WIFI PMIC off\n"); + } + + return 0; +} + +static INT32 consys_hw_vcn_ctrl_after_idle(VOID) +{ + consys_hw_set_vcn13_vcn18_lp_mode(1); + return 0; +} + +static INT32 consys_emi_mpu_set_region_protection(VOID) +{ + struct emimpu_region_t region; + unsigned long long start = gConEmiPhyBase; + unsigned long long end = gConEmiPhyBase + gConEmiSize - 1; + + mtk_emimpu_init_region(®ion, REGION_CONN); + mtk_emimpu_set_addr(®ion, start, end); + mtk_emimpu_set_apc(®ion, DOMAIN_AP, MTK_EMIMPU_NO_PROTECTION); + mtk_emimpu_set_apc(®ion, DOMAIN_CONN, MTK_EMIMPU_NO_PROTECTION); + mtk_emimpu_set_protection(®ion); + mtk_emimpu_free_region(®ion); + + WMT_PLAT_PR_INFO("setting MPU for EMI share memory\n"); + return 0; +} + +static UINT32 consys_emi_set_remapping_reg(VOID) +{ + /* For direct path */ + phys_addr_t mdPhy = 0; + INT32 size = 0; + + mtk_wcn_emi_addr_info.emi_ap_phy_addr = gConEmiPhyBase; + mtk_wcn_emi_addr_info.emi_size = gConEmiSize; + + if (conn_reg.topckgen_base == 0) + return 0; + + /*EMI Registers remapping*/ + CONSYS_REG_WRITE_OFFSET_RANGE(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET, + gConEmiPhyBase, 0, 16, 20); + WMT_PLAT_PR_INFO("CONSYS_EMI_MAPPING dump in restore cb(0x%08x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET)); + + /*Perisys Configuration Registers remapping*/ + CONSYS_REG_WRITE_OFFSET_RANGE(conn_reg.topckgen_base + CONSYS_EMI_PERI_MAPPING_OFFSET, + 0x10003000, 0, 16, 20); + WMT_PLAT_PR_INFO("PERISYS_MAPPING dump in restore cb(0x%08x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_PERI_MAPPING_OFFSET)); + + /*Modem Configuration Registers remapping*/ +#if IS_ENABLED(CONFIG_MTK_ECCCI_DRIVER) + mdPhy = get_smem_phy_start_addr(MD_SYS1, SMEM_USER_RAW_MD_CONSYS, &size); +#endif + if (size == 0) + WMT_PLAT_PR_INFO("MD direct path is not supported\n"); + else { + CONSYS_REG_WRITE_OFFSET_RANGE( + conn_reg.topckgen_base + CONSYS_EMI_AP_MD_OFFSET, + mdPhy, 0, 16, 20); + WMT_PLAT_PR_INFO("MD_MAPPING dump in restore cb(0x%08x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_AP_MD_OFFSET)); + } + mtk_wcn_emi_addr_info.emi_direct_path_ap_phy_addr = mdPhy; + mtk_wcn_emi_addr_info.emi_direct_path_size = size; + + mtk_wcn_emi_addr_info.emi_ram_bt_buildtime_offset = + CONSYS_EMI_RAM_BT_BUILDTIME_OFFSET; + mtk_wcn_emi_addr_info.emi_ram_wifi_buildtime_offset = + CONSYS_EMI_RAM_WIFI_BUILDTIME_OFFSET; + mtk_wcn_emi_addr_info.emi_ram_mcu_buildtime_offset = + CONSYS_EMI_RAM_MCU_BUILDTIME_OFFSET; + mtk_wcn_emi_addr_info.emi_patch_mcu_buildtime_offset = + CONSYS_EMI_PATCH_MCU_BUILDTIME_OFFSET; + + return 0; +} + +static INT32 bt_wifi_share_v33_spin_lock_init(VOID) +{ + return 0; +} + +static INT32 consys_read_irq_info_from_dts(struct platform_device *pdev, PINT32 irq_num, + PUINT32 irq_flag) +{ + struct device_node *node; + + node = pdev->dev.of_node; + if (node) { + *irq_num = irq_of_parse_and_map(node, 0); + *irq_flag = irq_get_trigger_type(*irq_num); + WMT_PLAT_PR_INFO("get irq id(%d) and irq trigger flag(%d) from DT\n", *irq_num, + *irq_flag); + } else { + WMT_PLAT_PR_ERR("[%s] can't find CONSYS compatible node\n", __func__); + return -1; + } + + return 0; +} + +static INT32 consys_read_reg_from_dts(struct platform_device *pdev) +{ + INT32 iRet = -1; + struct device_node *node = NULL; + + node = pdev->dev.of_node; + if (node) { + /* registers base address */ + conn_reg.mcu_base = (SIZE_T) of_iomap(node, MCU_BASE_INDEX); + WMT_PLAT_PR_DBG("Get mcu register base(0x%zx)\n", conn_reg.mcu_base); + conn_reg.ap_rgu_base = (SIZE_T) of_iomap(node, TOP_RGU_BASE_INDEX); + WMT_PLAT_PR_DBG("Get ap_rgu register base(0x%zx)\n", conn_reg.ap_rgu_base); + conn_reg.topckgen_base = (SIZE_T) of_iomap(node, INFRACFG_AO_BASE_INDEX); + WMT_PLAT_PR_DBG("Get topckgen register base(0x%zx)\n", conn_reg.topckgen_base); + conn_reg.spm_base = (SIZE_T) of_iomap(node, SPM_BASE_INDEX); + WMT_PLAT_PR_DBG("Get spm register base(0x%zx)\n", conn_reg.spm_base); + conn_reg.mcu_conn_hif_on_base = (SIZE_T) of_iomap(node, MCU_CONN_HIF_ON_BASE_INDEX); + WMT_PLAT_PR_DBG("Get mcu_conn_hif_on register base(0x%zx)\n", + conn_reg.mcu_conn_hif_on_base); + conn_reg.mcu_top_misc_off_base = (SIZE_T) of_iomap(node, + MCU_TOP_MISC_OFF_BASE_INDEX); + WMT_PLAT_PR_DBG("Get mcu_top_misc_off register base(0x%zx)\n", + conn_reg.mcu_top_misc_off_base); + conn_reg.mcu_cfg_on_base = (SIZE_T) of_iomap(node, MCU_CFG_ON_BASE_INDEX); + WMT_PLAT_PR_DBG("Get mcu_cfg_on register base(0x%zx)\n", conn_reg.mcu_cfg_on_base); + conn_reg.mcu_cirq_base = (SIZE_T) of_iomap(node, MCU_CIRQ_BASE_INDEX); + WMT_PLAT_PR_DBG("Get mcu cirq register base(0x%zx)\n", conn_reg.mcu_cirq_base); + conn_reg.mcu_top_misc_on_base = (SIZE_T) of_iomap(node, MCU_TOP_MISC_ON_BASE_INDEX); + WMT_PLAT_PR_DBG("Get mcu_top_misc_off register base(0x%zx)\n", + conn_reg.mcu_top_misc_on_base); + conn_reg.ap_pccif4_base = (SIZE_T) of_iomap(node, AP_PCCIF4_BASE_INDEX); + WMT_PLAT_PR_DBG("Get ap_pccif4 register base(0x%zx)\n", + conn_reg.ap_pccif4_base); + conn_reg.infra_ao_pericfg_base = (SIZE_T) of_iomap(node, INFRA_AO_PERICFG_BASE_INDEX); + WMT_PLAT_PR_DBG("Get infra_ao_pericfg register base(0x%zx)\n", + conn_reg.infra_ao_pericfg_base); + } else { + WMT_PLAT_PR_ERR("[%s] can't find CONSYS compatible node\n", __func__); + return iRet; + } + + return 0; +} + +static VOID force_trigger_assert_debug_pin(VOID) +{ + UINT32 value = 0; + + if (conn_reg.infra_ao_pericfg_base != 0) { + WMT_PLAT_PR_DBG("CON_STA_REG = %x\n", + CONSYS_REG_READ( + conn_reg.infra_ao_pericfg_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG)); + + /* clear CON_PWR_ON & CON_SW_READY bit (CON_STA_REG[0], CON_STA_REG[1]) */ + value = CONSYS_REG_READ(conn_reg.infra_ao_pericfg_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG); + value = value & (~INFRASYS_COMMON_AP2MD_CON_PWR_ON_CON_SW_READY_MASK); + CONSYS_REG_WRITE(conn_reg.infra_ao_pericfg_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG, + value); + + WMT_PLAT_PR_DBG("CON_STA_REG = %x\n", + CONSYS_REG_READ( + conn_reg.infra_ao_pericfg_base + + INFRASYS_COMMON_AP2MD_PCCIF4_AP_PERI_AP_CCU_CONFIG)); + } + + if (conn_reg.topckgen_base == 0) + return; + + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AP2CONN_OSC_EN_OFFSET) & ~CONSYS_AP2CONN_WAKEUP_BIT); + WMT_PLAT_PR_INFO("enable:dump CONSYS_AP2CONN_OSC_EN_REG(0x%x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET)); + usleep_range(64, 96); + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + + CONSYS_AP2CONN_OSC_EN_OFFSET) | CONSYS_AP2CONN_WAKEUP_BIT); + WMT_PLAT_PR_INFO("disable:dump CONSYS_AP2CONN_OSC_EN_REG(0x%x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET)); +} + +static UINT32 consys_read_cpupcr(VOID) +{ + if (conn_reg.mcu_conn_hif_on_base == 0) + return 0; + + return CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + CONSYS_CPUPCR_OFFSET); +} + +static UINT32 consys_soc_chipid_get(VOID) +{ + return PLATFORM_SOC_CHIP; +} + +static P_CONSYS_EMI_ADDR_INFO consys_soc_get_emi_phy_add(VOID) +{ + return &mtk_wcn_emi_addr_info; +} + +P_WMT_CONSYS_IC_OPS mtk_wcn_get_consys_ic_ops(VOID) +{ + return &consys_ic_ops; +} + +static INT32 consys_dl_rom_patch(UINT32 ip_ver, UINT32 fw_ver) +{ + if (rom_patch_dl_flag) { + if (mtk_wcn_soc_rom_patch_dwn(ip_ver, fw_ver) == 0) + rom_patch_dl_flag = 1; + else + return -1; + } + + return 0; +} + +static VOID consys_set_dl_rom_patch_flag(INT32 flag) +{ + rom_patch_dl_flag = flag; +} + +static VOID consys_conn2ap_sw_irq_clear(VOID) +{ + UINT32 ret; + + if (!conn_reg.mcu_base) + return; + + if (osal_trylock_unsleepable_lock(&g_pwr_off_lock) == 0) { + WMT_PLAT_PR_INFO("fail to get pwr off lock\n"); + return; + } + + if (atomic_read(&g_power_on) == 1) { + /* clear 0x1800214c[27:24] */ + CONSYS_REG_WRITE(conn_reg.mcu_base + CONN2AP_SW_IRQ_CLR_OFFSET, + CONSYS_REG_READ(conn_reg.mcu_base + CONN2AP_SW_IRQ_CLR_OFFSET) + | (0xf << 24)); + + ret = CONSYS_REG_READ(conn_reg.mcu_base + CONN2AP_SW_IRQ_OFFSET) & (0xf << 24); + if (ret > 0) + WMT_PLAT_PR_INFO("CONN2AP_SW_IRQ[27:24] = 0x%x\n", ret); + } + + osal_unlock_unsleepable_lock(&g_pwr_off_lock); +} + +static INT32 consys_dedicated_log_path_init(struct platform_device *pdev) +{ + struct device_node *node; + UINT32 irq_num; + UINT32 irq_flag; + INT32 iret = -1; + struct connlog_irq_config irq_config; + + memset(&irq_config, 0, sizeof(struct connlog_irq_config)); + node = pdev->dev.of_node; + if (node) { + irq_num = irq_of_parse_and_map(node, 2); + irq_flag = irq_get_trigger_type(irq_num); + WMT_PLAT_PR_INFO("get conn2ap_sw_irq id(%d) and irq trigger flag(%d) from DT\n", + irq_num, irq_flag); + } else { + WMT_PLAT_PR_ERR("[%s] can't find CONSYS compatible node\n", __func__); + return iret; + } + + osal_unsleepable_lock_init(&g_pwr_off_lock); + + irq_config.irq_num = irq_num; + irq_config.irq_flag = irq_flag; + irq_config.irq_callback = consys_conn2ap_sw_irq_clear; + + connsys_dedicated_log_path_apsoc_init( + gConEmiPhyBase, &connsys_fw_log_parameter, &irq_config); +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH + fw_log_wmt_init(); +#endif + return 0; +} + +static VOID consys_dedicated_log_path_deinit(VOID) +{ +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH + fw_log_wmt_deinit(); +#endif + connsys_dedicated_log_path_apsoc_deinit(); + osal_unsleepable_lock_deinit(&g_pwr_off_lock); +} + +static INT32 consys_emi_coredump_remapping(UINT8 __iomem **addr, UINT32 enable) +{ + if (enable) { + *addr = ioremap_nocache(gConEmiPhyBase + CONSYS_EMI_COREDUMP_OFFSET, + CONSYS_EMI_COREDUMP_MEM_SIZE); + if (*addr) { + WMT_PLAT_PR_INFO("COREDUMP EMI mapping OK virtual(0x%p) physical(0x%x)\n", + *addr, (UINT32) gConEmiPhyBase + + CONSYS_EMI_COREDUMP_OFFSET); + memset_io(*addr, 0, CONSYS_EMI_COREDUMP_MEM_SIZE); + } else { + WMT_PLAT_PR_ERR("EMI mapping fail\n"); + return -1; + } + } else { + if (*addr) { + iounmap(*addr); + *addr = NULL; + } + } + return 0; +} + +static INT32 consys_reset_emi_coredump(UINT8 __iomem *addr) +{ + if (!addr) { + WMT_PLAT_PR_ERR("get virtual address fail\n"); + return -1; + } + WMT_PLAT_PR_INFO("Reset EMI(0xF0068000 ~ 0xF0107FFF)\n"); + memset_io(addr, 0, CONSYS_EMI_COREDUMP_MEM_SIZE); + return 0; +} + +static INT32 consys_check_reg_readable(VOID) +{ + INT32 can_read = 0; + UINT32 value = 0; + + if (conn_reg.mcu_cfg_on_base != 0 && + conn_reg.mcu_top_misc_on_base != 0) { + /*check connsys clock and sleep status*/ + CONSYS_REG_WRITE(conn_reg.mcu_conn_hif_on_base, CONSYS_CLOCK_CHECK_VALUE); + udelay(200); + value = CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base); + if ((value & CONSYS_HCLK_CHECK_BIT) && + (value & CONSYS_OSCCLK_CHECK_BIT)) + can_read = 1; + } + + if (!can_read) + WMT_PLAT_PR_ERR("connsys clock check fail 0x18007000(0x%x)\n", value); + + return can_read; +} + +static VOID consys_ic_clock_fail_dump(VOID) +{ + UINT8 *addr = NULL; + char *buffer = NULL, *temp = NULL; + INT32 size = 1024; + + if (conn_reg.mcu_base == 0) + return; + + /* make sure buffer size is big enough */ + buffer = osal_malloc(size); + if (!buffer) + return; + + temp = buffer; + temp += sprintf(temp, "CONN_HIF_TOP_MISC=0x%08x CONN_HIF_BUSY_STATUS=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HIF_TOP_MISC), + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HIF_BUSY_STATUS)); + + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_HIF_DBG_IDX, 0x3333); + temp += sprintf(temp, "Write CONSYS_HIF_DBG_IDX to 0x3333\n"); + + temp += sprintf(temp, "CONSYS_HIF_DBG_PROBE=0x%08x CONN_HIF_TOP_MISC=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HIF_DBG_PROBE), + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HIF_TOP_MISC)); + + temp += sprintf(temp, "CONN_HIF_BUSY_STATUS=0x%08x CONN_HIF_PDMA_BUSY_STATUS=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HIF_BUSY_STATUS), + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HIF_PDMA_BUSY_STATUS)); + + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_HIF_DBG_IDX, 0x2222); + temp += sprintf(temp, "Write CONSYS_HIF_DBG_IDX to 0x2222\n"); + + temp += sprintf(temp, "CONSYS_HIF_DBG_PROBE=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HIF_DBG_PROBE)); + + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_HIF_DBG_IDX, 0x3333); + temp += sprintf(temp, "Write CONSYS_HIF_DBG_IDX to 0x3333\n"); + + temp += sprintf(temp, "CONSYS_HIF_DBG_PROBE=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HIF_DBG_PROBE)); + + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_HIF_DBG_IDX, 0x4444); + temp += sprintf(temp, "Write CONSYS_HIF_DBG_IDX to 0x4444\n"); + + temp += sprintf(temp, "CONSYS_HIF_DBG_PROBE=0x%08x CONN_MCU_EMI_CONTROL=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_HIF_DBG_PROBE), + CONSYS_REG_READ(conn_reg.mcu_base + CONN_MCU_EMI_CONTROL)); + temp += sprintf(temp, "EMI_CONTROL_DBG_PROBE=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + EMI_CONTROL_DBG_PROBE)); + temp += sprintf(temp, "CONN_MCU_CLOCK_CONTROL=0x%08x CONN_MCU_BUS_CONTROL=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_CLOCK_CONTROL), + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_BUS_CONTROL)); + + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_DEBUG_SELECT, 0x003e3d00); + temp += sprintf(temp, "Write CONSYS_DEBUG_SELECT to 0x003e3d00\n"); + + temp += sprintf(temp, "CONN_MCU_DEBUG_STATUS=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_DEBUG_STATUS)); + + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_DEBUG_SELECT, 0x00403f00); + temp += sprintf(temp, "Write CONSYS_DEBUG_SELECT to 0x00403f00\n"); + + temp += sprintf(temp, "CONN_MCU_DEBUG_STATUS=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_DEBUG_STATUS)); + + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_DEBUG_SELECT, 0x00424100); + temp += sprintf(temp, "Write CONSYS_DEBUG_SELECT to 0x00424100\n"); + + temp += sprintf(temp, "CONN_MCU_DEBUG_STATUS=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_DEBUG_STATUS)); + + CONSYS_REG_WRITE(conn_reg.mcu_base + CONSYS_DEBUG_SELECT, 0x00444300); + temp += sprintf(temp, "Write CONSYS_DEBUG_SELECT to 0x00444300\n"); + + temp += sprintf(temp, "CONN_MCU_DEBUG_STATUS=0x%08x\n", + CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_DEBUG_STATUS)); + WMT_PLAT_PR_ERR("%s length = %d", buffer, osal_strlen(buffer)); + + temp = buffer; + addr = ioremap_nocache(0x180bc000, 0x100); + /* conn2ap axi master sleep prot info */ + temp += sprintf(temp, "0x180bc010=0x%08x\n", CONSYS_REG_READ(addr + 0x10)); + /* conn_mcu2ap axi master sleep prot info */ + temp += sprintf(temp, "0x180bc014=0x%08x\n", CONSYS_REG_READ(addr + 0x14)); + /* conn2ap axi gals bus info */ + temp += sprintf(temp, "0x180bc018=0x%08x\n", CONSYS_REG_READ(addr + 0x18)); + /* conn2ap mux4to1 debug info */ + temp += sprintf(temp, "0x180bc01c=0x%08x\n", CONSYS_REG_READ(addr + 0x1c)); + /* conn_hif_off bus busy info */ + temp += sprintf(temp, "0x180bc020=0x%08x\n", CONSYS_REG_READ(addr + 0x20)); + iounmap(addr); + + addr = ioremap_nocache(0x10001B20, 0x100); + /* 0x1020E804 */ + temp += sprintf(temp, "0x10001B20=0x%08x\n", CONSYS_REG_READ(addr)); + + addr = ioremap_nocache(0x1800713c, 0x100); + /* conn_hif_on misc info */ + temp += sprintf(temp, "0x1800713c=0x%08x\n", CONSYS_REG_READ(addr)); + iounmap(addr); + + addr = ioremap_nocache(0x180c1144, 0x100); + /* conn_on_host debug flag */ + temp += sprintf(temp, "0x180c1144=0x%08x\n", CONSYS_REG_READ(addr)); + iounmap(addr); + + addr = ioremap_nocache(0x1020E804, 0x100); + /* 0x1020E804 */ + temp += sprintf(temp, "0x1020E804=0x%08x\n", CONSYS_REG_READ(addr)); + iounmap(addr); + + WMT_PLAT_PR_ERR("%s length = %d", buffer, osal_strlen(buffer)); + osal_free(buffer); +} + +static INT32 consys_is_connsys_reg(UINT32 addr) +{ + if (addr > 0x18000000 && addr < 0x180FFFFF) { + if (addr >= 0x18007000 && addr <= 0x18007FFF) + return 0; + + return 1; + } + + return 0; +} + +static INT32 consys_is_host_csr(SIZE_T addr) +{ + SIZE_T start_offset = 0x000; + SIZE_T end_offset = 0xFFF; + + if (addr >= (CONN_HIF_ON_BASE_ADDR + start_offset) && + addr <= (CONN_HIF_ON_BASE_ADDR + end_offset)) + return 1; + + if (conn_reg.mcu_conn_hif_on_base != 0 && + addr >= (conn_reg.mcu_conn_hif_on_base + start_offset) && + addr <= (conn_reg.mcu_conn_hif_on_base + end_offset)) + return 1; + + return 0; +} + +static INT32 consys_dump_osc_state(P_CONSYS_STATE state) +{ +#define MCU_OSC_EN_BIT 6 +#define BT_OSC_EN_BIT 8 +#define GPS_OSC_EN_BIT 9 +#define WIFI_OSC_EN_BIT 12 +#define FM_OSC_EN_BIT 7 +#define AP2CONN_OSC_EN_BIT 5 + + UINT32 value = 0; + UINT8 strbuf[DBG_LOG_STR_SIZE] = {""}; + UINT32 len = 0; + + UINT32 mcu_osc_en = 0; + UINT32 bt_osc_en = 0; + UINT32 gps_osc_en = 0; + UINT32 wifi_osc_en = 0; + UINT32 fm_osc_en = 0; + UINT32 ap2conn_osc_en = 0; + + if (conn_reg.mcu_cfg_on_base != 0 && + conn_reg.mcu_top_misc_on_base != 0) { + + CONSYS_REG_WRITE(conn_reg.mcu_top_misc_on_base + CONN_CFG_ON_MON_CTL_ADDR_OFFSET, 0x80000001); + CONSYS_REG_WRITE(conn_reg.mcu_top_misc_on_base + CONN_CFG_ON_MON_SEL0_ADDR_OFFSET, 0x03020100); + CONSYS_REG_WRITE(conn_reg.mcu_top_misc_on_base + CONN_CFG_ON_MON_SEL1_ADDR_OFFSET, 0x07060504); + CONSYS_REG_WRITE(conn_reg.mcu_top_misc_on_base + CONN_CFG_ON_MON_SEL2_ADDR_OFFSET, 0x0b0a0908); + CONSYS_REG_WRITE(conn_reg.mcu_top_misc_on_base + CONN_CFG_ON_MON_SEL3_ADDR_OFFSET, 0x0f0e0d0c); + CONSYS_REG_WRITE(conn_reg.mcu_top_misc_on_base + CONN_CFG_ON_DBGSEL_ADDR_OFFSET, 0x3); + value = CONSYS_REG_READ(conn_reg.mcu_top_misc_on_base + CONN_CFG_ON_MON_FLAG_RECORD_ADDR_OFFSET); + + state->lp[0] = (UINT32)0x180c1340; + state->lp[1] = value; + + if (value != 0 && value != 0xdeadfeed) { + mcu_osc_en = (value >> MCU_OSC_EN_BIT) & 0x1; + bt_osc_en = (value >> BT_OSC_EN_BIT) & 0x1; + gps_osc_en = (value >> GPS_OSC_EN_BIT) & 0x1; + wifi_osc_en = (value >> WIFI_OSC_EN_BIT) & 0x1; + fm_osc_en = (value >> FM_OSC_EN_BIT) & 0x1; + ap2conn_osc_en = (value >> AP2CONN_OSC_EN_BIT) & 0x1; + } + + len += osal_sprintf(strbuf + len, "0x%08x: 0x%x", state->lp[0], state->lp[1]); + if ((mcu_osc_en + bt_osc_en + gps_osc_en + wifi_osc_en + fm_osc_en + ap2conn_osc_en) >= 1) { + len += osal_sprintf(strbuf + len, " (%s%s%s%s%s%s", + ((mcu_osc_en == 1) ? "MCU," : ""), ((bt_osc_en == 1) ? "BT," : ""), + ((gps_osc_en == 1) ? "GPS," : ""), ((wifi_osc_en == 1) ? "WIFI," : ""), + ((fm_osc_en == 1) ? "FM," : ""), ((ap2conn_osc_en == 1) ? "AP2CONN," : "")); + len += osal_sprintf(strbuf + len - 1, ")"); + } + WMT_PLAT_PR_INFO("%s\n", strbuf); + } + return MTK_WCN_BOOL_TRUE; +} + +static INT32 consys_dump_gating_state(P_CONSYS_STATE state) +{ + UINT32 value = 0; + UINT8 strbuf[DBG_LOG_STR_SIZE] = {""}; + UINT32 len = 0; + + UINT32 magic_number = 0; + UINT32 clock_hif_ctrl = 0; + UINT32 clock_umac_ctrl = 0; + UINT32 sleep_disable_mode = 0; + UINT32 subsys_clk_req_stutus = 0; + UINT32 clk_rate = 0; + + if (conn_reg.mcu_conn_hif_on_base == 0) + return MTK_WCN_BOOL_FALSE; + + value = CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + CONN_MCU_MAILBOX_DBG); + + if (state) { + state->gating[0] = (UINT32)0x18007120; + state->gating[1] = value; + osal_memset(&(state->sw_state), 0, sizeof(state->sw_state)); + } + + magic_number = (value >> 0) & 0xF; + if (magic_number == 0x7) { + clock_hif_ctrl = (value >> 4) & 0x1; + clock_umac_ctrl = (value >> 5) & 0x1; + sleep_disable_mode = (value >> 8) & 0xFF; + subsys_clk_req_stutus = (value >> 16) & 0xFF; + clk_rate = (value >> 24) & 0xFF; + } + + len += osal_sprintf(strbuf + len, "0x%08x: 0x%x", 0x18007120, value); + if (magic_number == 0x7) { + if (clock_hif_ctrl == 0x0 && clock_umac_ctrl == 0x0 && sleep_disable_mode == 0x0 && + subsys_clk_req_stutus == 0x0 && clk_rate <= 0x1a) { + len += osal_sprintf(strbuf + len, " (sleep)"); + if (state) { + state->sw_state.is_gating = 0; + state->sw_state.clock_mcu = clk_rate; + } + } else { + len += osal_sprintf(strbuf + len, + " (gating, hif_clk:0x%01x, umac_clk:0x%01x, slp_dis:0x%02x, subsys_clk:0x%02x, clk_rate:0x%02x)", + clock_hif_ctrl, clock_umac_ctrl, sleep_disable_mode, subsys_clk_req_stutus, clk_rate); + if (state) { + state->sw_state.is_gating = 1; + state->sw_state.clock_hif_ctrl = clock_hif_ctrl; + state->sw_state.clock_umac_ctrl = clock_umac_ctrl; + state->sw_state.resource_disable_sleep = sleep_disable_mode; + state->sw_state.sub_system = subsys_clk_req_stutus; + state->sw_state.clock_mcu = clk_rate; + } + } + } else { + len += osal_sprintf(strbuf + len, " (no gating info found)"); + } + WMT_PLAT_PR_INFO("%s\n", strbuf); + + return MTK_WCN_BOOL_TRUE; +} + +static VOID consys_set_pdma_axi_rready_force_high(UINT32 enable) +{ + if (conn_reg.mcu_conn_hif_pdma_base == 0) + return; + + if (enable) + CONSYS_SET_BIT(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_PDMA_AXI_RREADY, + CONSYS_HIF_PDMA_AXI_RREADY_MASK); + else if ((CONSYS_REG_READ(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_PDMA_AXI_RREADY) & + CONSYS_HIF_PDMA_AXI_RREADY_MASK) != 0) + CONSYS_CLR_BIT(conn_reg.mcu_conn_hif_pdma_base + CONSYS_HIF_PDMA_AXI_RREADY, + CONSYS_HIF_PDMA_AXI_RREADY_MASK); +} + +static VOID consys_set_mcif_emi_mpu_protection(MTK_WCN_BOOL enable) +{ + WMT_PLAT_PR_INFO("Setup region 23 for domain 0 as %s\n", enable ? "FORBIDDEN" : "SEC_R_NSEC_R"); + /* emi_mpu_set_single_permission(23, 0, enable ? FORBIDDEN : SEC_R_NSEC_R); */ +} + +static INT32 consys_calibration_backup_restore_support(VOID) +{ + return 1; +} + +static INT32 consys_is_ant_swap_enable_by_hwid(INT32 pin_num) +{ + return !gpio_get_value(pin_num); +} + +#if WMT_DEVAPC_DBG_SUPPORT +static VOID consys_devapc_violation_cb(VOID) +{ + /** + * Don't use wmt_lib_trigger_assert() because it will invoke vmalloc and then cause KE since + * this callback is supposed to be invoked in DEVAPC exception hanlder. + */ + wmt_lib_trigger_assert_keyword_delay(WMTDRV_TYPE_WMT, 46, "DEVAPC Violation"); +} +#endif + +static VOID consyc_register_devapc_cb(VOID) +{ +#if WMT_DEVAPC_DBG_SUPPORT + register_devapc_vio_callback(&devapc_handle); +#endif +} + +static INT32 consys_is_rc_mode_enable(VOID) +{ +#if CONSYS_RC_MODE_ENABLE + INT32 value; + + value = SPM_RC_CENTRAL_CFG1_BIT & + CONSYS_REG_READ(conn_reg.spm_base + SPM_RC_CENTRAL_CFG1); + return value; +#else + return 0; +#endif +} + +UINT32 consys_sleep_info_is_enable(VOID) +{ + UINT32 ctrl_enable = 0; + UINT32 host_ctrl_enable = 0; + + if (conn_reg.mcu_conn_hif_on_base == 0) + return 0; + + ctrl_enable = (CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + + CONN_HOST_CR_SLEEP_CNT_OFFSET) >> 0) & 0x1; + + if (ctrl_enable == 0) + return 0; + + host_ctrl_enable = (CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + + CONN_HOST_CR_SLEEP_CNT_OFFSET) >> 5) & 0x1; + + if (host_ctrl_enable == 0) + return 0; + + return 1; +} + +INT32 consys_sleep_info_clear(VOID) +{ + if (conn_reg.mcu_conn_hif_on_base == 0) + return -1; + + /* set xx_in_sleep_clr = 1 */ + CONSYS_REG_WRITE(conn_reg.mcu_conn_hif_on_base + CONN_SLEEP_INFO_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + CONN_SLEEP_INFO_CTRL_OFFSET) | + (0x1F << 5)); + + /* wait 100us */ + udelay(100); + + /* set xx_in_sleep_clr = 0 */ + CONSYS_REG_WRITE(conn_reg.mcu_conn_hif_on_base + CONN_SLEEP_INFO_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + CONN_SLEEP_INFO_CTRL_OFFSET) & + ~(0x1F << 5)); + + return 0; +} + +INT32 consys_sleep_info_enable_ctrl(UINT32 enable) +{ + if (conn_reg.mcu_conn_hif_on_base == 0) + return -1; + + WMT_PLAT_PR_DBG("consys_sleep_info_enable_ctrl, enable=[%d]\n", enable); + + if (enable == 1) { + /* set sleep_cnt_en = 1 (function enable) */ + CONSYS_REG_WRITE(conn_reg.mcu_conn_hif_on_base + CONN_HOST_CR_SLEEP_CNT_OFFSET, + CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + CONN_HOST_CR_SLEEP_CNT_OFFSET) | + (0x1 << 0)); + + /* wait 100us */ + udelay(100); + + /* set cr_host_slp_cnt_host_ctl_en = 1 (driver only) */ + CONSYS_REG_WRITE(conn_reg.mcu_conn_hif_on_base + CONN_HOST_CR_SLEEP_CNT_OFFSET, + CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + CONN_HOST_CR_SLEEP_CNT_OFFSET) | + (0x1 << 5)); + + /* set xx_in_sleep_clr = 1 */ + CONSYS_REG_WRITE(conn_reg.mcu_conn_hif_on_base + CONN_SLEEP_INFO_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + CONN_SLEEP_INFO_CTRL_OFFSET) | + (0x1F << 5)); + + /* set xx_in_sleep_stop = 0 */ + CONSYS_REG_WRITE(conn_reg.mcu_conn_hif_on_base + CONN_SLEEP_INFO_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + CONN_SLEEP_INFO_CTRL_OFFSET) & + ~(0x1F << 0)); + + /* wait 100us */ + udelay(100); + + /* set xx_in_sleep_clr = 0 */ + CONSYS_REG_WRITE(conn_reg.mcu_conn_hif_on_base + CONN_SLEEP_INFO_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + CONN_SLEEP_INFO_CTRL_OFFSET) & + ~(0x1F << 5)); + } else { + /* set xx_in_sleep_stop = 1 */ + CONSYS_REG_WRITE(conn_reg.mcu_conn_hif_on_base + CONN_SLEEP_INFO_CTRL_OFFSET, + CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + CONN_SLEEP_INFO_CTRL_OFFSET) | + (0x1F << 0)); + + /* set cr_host_slp_cnt_host_ctl_en = 0 (driver only) */ + CONSYS_REG_WRITE(conn_reg.mcu_conn_hif_on_base + CONN_HOST_CR_SLEEP_CNT_OFFSET, + CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + CONN_HOST_CR_SLEEP_CNT_OFFSET) & + ~(0x1 << 5)); + + /* wait 100us */ + udelay(100); + + /* set sleep_cnt_en = 0 (function disable) */ + CONSYS_REG_WRITE(conn_reg.mcu_conn_hif_on_base + CONN_HOST_CR_SLEEP_CNT_OFFSET, + CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + CONN_HOST_CR_SLEEP_CNT_OFFSET) & + ~(0x1 << 0)); + } + + return 0; +} + +INT32 consys_sleep_info_read_ctrl(WMT_SLEEP_COUNT_TYPE type, PUINT64 sleep_counter, PUINT64 sleep_timer) +{ + /* + * type = 0 --> WMT_SLEEP_COUNT_TOP + * type = 1 --> WMT_SLEEP_COUNT_MCU + * type = 2 --> WMT_SLEEP_COUNT_BT + * type = 3 --> WMT_SLEEP_COUNT_WF + * type = 4 --> WMT_SLEEP_COUNT_GPS + */ + + UINT32 in_sleep_state = 0; + UINT32 value_sleep_timer_rd = 0; + UINT32 value_sleep_counter_rd = 0; + UINT32 value_final_counter = 0; + + if (conn_reg.mcu_conn_hif_on_base == 0) + return -1; + + if (type >= WMT_SLEEP_COUNT_MAX) + return -2; + + if (sleep_counter == NULL && sleep_timer == NULL) + return -3; + + if (!consys_sleep_info_is_enable()) + return -4; + + WMT_PLAT_PR_DBG("type=[%d]\n", type); + + /* set sleep_cnt_sel = top/mcu/bt/wf/gps */ + CONSYS_REG_WRITE(conn_reg.mcu_conn_hif_on_base + CONN_HOST_CR_SLEEP_CNT_OFFSET, + (CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + CONN_HOST_CR_SLEEP_CNT_OFFSET) & + 0xFFFFFFF1) | (type * 2)); + + /* set sleep_cnt_rd_trig = 1 */ + CONSYS_REG_WRITE(conn_reg.mcu_conn_hif_on_base + CONN_HOST_CR_SLEEP_CNT_OFFSET, + CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + CONN_HOST_CR_SLEEP_CNT_OFFSET) | + (0x1 << 4)); + + /* wait 40us */ + udelay(40); + + /* set sleep_cnt_rd_trig = 0 */ + CONSYS_REG_WRITE(conn_reg.mcu_conn_hif_on_base + CONN_HOST_CR_SLEEP_CNT_OFFSET, + CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + CONN_HOST_CR_SLEEP_CNT_OFFSET) & + ~(0x1 << 4)); + + /* wait 100us */ + udelay(100); + + if (sleep_counter) { + /* read sleep_cnt_counter */ + value_sleep_counter_rd = CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + + CONN_SLEEP_INFO_READ_CTRL_COUNT_OFFSET); + in_sleep_state = (CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + + CONN_SLEEP_INFO_CTRL_OFFSET) >> (14 - type)) & 0x1; + + if (value_sleep_counter_rd == 0) { + value_final_counter = 0; + } else { + if ((type == WMT_SLEEP_COUNT_BT || type == WMT_SLEEP_COUNT_WF) && in_sleep_state == 1) + value_final_counter = value_sleep_counter_rd + 1; + else + value_final_counter = value_sleep_counter_rd; + } + + if (value_final_counter > 0) + value_final_counter--; + + *sleep_counter = value_final_counter; + WMT_PLAT_PR_DBG("sleep_counter_rd=[%d], in_sleep_state=[%d], final_counter=[%d]\n", + value_sleep_counter_rd, in_sleep_state, value_final_counter); + } + + if (sleep_timer) { + /* read sleep_cnt_timer */ + value_sleep_timer_rd = CONSYS_REG_READ(conn_reg.mcu_conn_hif_on_base + + CONN_SLEEP_INFO_READ_CTRL_TIMER_OFFSET); + *sleep_timer = value_sleep_timer_rd; + WMT_PLAT_PR_DBG("sleep_timer_rd=[%d]\n", value_sleep_timer_rd); + } + + return 0; +} + +#if (COMMON_KERNEL_CLK_SUPPORT) +static MTK_WCN_BOOL consys_need_store_pdev(VOID) +{ + return MTK_WCN_BOOL_TRUE; +} + +static UINT32 consys_store_pdev(struct platform_device *pdev) +{ + connsys_pdev = pdev; + return 0; +} +#endif + +static UINT64 consys_get_options(VOID) +{ + UINT64 options = OPT_QUERY_ADIE | + OPT_WIFI_LTE_COEX | + OPT_BT_TSSI_FROM_WIFI_CONFIG_NEW_OPID | + OPT_COEX_CONFIG_ADJUST | + OPT_COEX_CONFIG_ADJUST_NEW_FLAG | + OPT_WIFI_LTE_COEX_TABLE_3 | + OPT_NORMAL_PATCH_DWN_3 | + OPT_PATCH_CHECKSUM; + return options; +} diff --git a/drivers/misc/mediatek/connectivity/common/common_main/platform/mtk_wcn_cmb_hw.c b/drivers/misc/mediatek/connectivity/common/common_main/platform/mtk_wcn_cmb_hw.c new file mode 100644 index 0000000000000000000000000000000000000000..b2fd526e632f1d03010756deb4cbfbe42801b3f1 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/platform/mtk_wcn_cmb_hw.c @@ -0,0 +1,340 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + + + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +#ifdef DFT_TAG +#undef DFT_TAG +#endif +#define DFT_TAG "[WMT-CMB-HW]" + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +#include "wmt_plat.h" +#include "wmt_lib.h" +#include "mtk_wcn_cmb_hw.h" +#include "osal_typedef.h" + + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ +#define DFT_RTC_STABLE_TIME 100 +#define DFT_LDO_STABLE_TIME 100 +#define DFT_RST_STABLE_TIME 30 +#define DFT_OFF_STABLE_TIME 10 +#define DFT_ON_STABLE_TIME 30 + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + + + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +PWR_SEQ_TIME gPwrSeqTime; + + + + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + + + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +INT32 mtk_wcn_cmb_hw_pwr_off(VOID) +{ + INT32 iRet = 0; + UINT32 chip_id = 0x0; + + WMT_DBG_FUNC("CMB-HW, hw_pwr_off start\n"); + + /*1. disable irq --> should be done when do wmt-ic swDeinit period */ + /* TODO:[FixMe][GeorgeKuo] clarify this */ + + /*2. set bgf eint/all eint to deinit state, namely input low state */ + chip_id = mtk_wcn_wmt_chipid_query(); + if (!((chip_id == 0x6630 || chip_id == 0x6632) + && (wmt_plat_get_comm_if_type() == STP_SDIO_IF_TX))) { + iRet += wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS); + WMT_INFO_FUNC("CMB-HW, BGF_EINT IRQ unregistered and disabled\n"); + iRet += wmt_plat_gpio_ctrl(PIN_BGF_EINT, PIN_STA_DEINIT); + } + /* 2.1 set ALL_EINT pin to correct state even it is not used currently */ + iRet += wmt_plat_eirq_ctrl(PIN_ALL_EINT, PIN_STA_DEINIT); + WMT_DBG_FUNC("CMB-HW, ALL_EINT IRQ unregistered and disabled\n"); + iRet += wmt_plat_gpio_ctrl(PIN_ALL_EINT, PIN_STA_DEINIT); + /* 2.2 deinit gps sync */ + iRet += wmt_plat_gpio_ctrl(PIN_GPS_SYNC, PIN_STA_DEINIT); + + /*3. set audio interface to CMB_STUB_AIF_0, BT PCM OFF, I2S OFF */ + iRet += wmt_plat_audio_ctrl(CMB_STUB_AIF_0, CMB_STUB_AIF_CTRL_DIS); + + /*4. set control gpio into deinit state, namely input low state */ + iRet += wmt_plat_gpio_ctrl(PIN_SDIO_GRP, PIN_STA_DEINIT); + if (chip_id != 0x6632) + iRet += wmt_plat_gpio_ctrl(PIN_RST, PIN_STA_OUT_L); + iRet += wmt_plat_gpio_ctrl(PIN_PMU, PIN_STA_OUT_L); + + /*5. set uart tx/rx into deinit state, namely input low state */ + iRet += wmt_plat_gpio_ctrl(PIN_UART_GRP, PIN_STA_DEINIT); + + /* 6. Last, LDO output low */ + iRet += wmt_plat_gpio_ctrl(PIN_LDO, PIN_STA_OUT_L); + + /*7. deinit gps_lna */ + iRet += wmt_plat_gpio_ctrl(PIN_GPS_LNA, PIN_STA_DEINIT); + + WMT_DBG_FUNC("CMB-HW, hw_pwr_off finish\n"); + return iRet; +} + +INT32 mtk_wcn_cmb_hw_pwr_on(VOID) +{ + static UINT32 _pwr_first_time = 1; + INT32 iRet = 0; + UINT32 chip_id = 0x0; + + WMT_DBG_FUNC("CMB-HW, hw_pwr_on start\n"); + + /* disable interrupt firstly */ + chip_id = mtk_wcn_wmt_chipid_query(); + if (!((chip_id == 0x6630 || chip_id == 0x6632) + && (wmt_plat_get_comm_if_type() == STP_SDIO_IF_TX))) + iRet += wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS); + iRet += wmt_plat_eirq_ctrl(PIN_ALL_EINT, PIN_STA_EINT_DIS); + + /*set all control and eint gpio to init state, namely input low mode */ + iRet += wmt_plat_gpio_ctrl(PIN_LDO, PIN_STA_INIT); + iRet += wmt_plat_gpio_ctrl(PIN_PMU, PIN_STA_INIT); + if (chip_id != 0x6632) + iRet += wmt_plat_gpio_ctrl(PIN_RST, PIN_STA_INIT); + iRet += wmt_plat_gpio_ctrl(PIN_SDIO_GRP, PIN_STA_INIT); + if (!((chip_id == 0X6630 || chip_id == 0X6632) + && (wmt_plat_get_comm_if_type() == STP_SDIO_IF_TX))) + iRet += wmt_plat_gpio_ctrl(PIN_BGF_EINT, PIN_STA_INIT); + iRet += wmt_plat_gpio_ctrl(PIN_ALL_EINT, PIN_STA_INIT); + iRet += wmt_plat_gpio_ctrl(PIN_GPS_SYNC, PIN_STA_INIT); + iRet += wmt_plat_gpio_ctrl(PIN_GPS_LNA, PIN_STA_INIT); + /* wmt_plat_gpio_ctrl(PIN_WIFI_EINT, PIN_STA_INIT); *//* WIFI_EINT is controlled by SDIO host driver */ + /* TODO: [FixMe][George]:WIFI_EINT is used in common SDIO */ + + /*1. pull high LDO to supply power to chip */ + iRet += wmt_plat_gpio_ctrl(PIN_LDO, PIN_STA_OUT_H); + osal_sleep_ms(gPwrSeqTime.ldoStableTime); + + /* 2. export RTC clock to chip */ + if (_pwr_first_time) { + /* rtc clock should be output all the time, so no need to enable output again */ + iRet += wmt_plat_gpio_ctrl(PIN_RTC, PIN_STA_INIT); + osal_sleep_ms(gPwrSeqTime.rtcStableTime); + WMT_INFO_FUNC("CMB-HW, rtc clock exported\n"); + } + + /*3. set UART Tx/Rx to UART mode */ + iRet += wmt_plat_gpio_ctrl(PIN_UART_GRP, PIN_STA_INIT); + + if (0x6630 == chip_id || 0x6632 == chip_id) { + switch (wmt_plat_get_comm_if_type()) { + case STP_UART_IF_TX: + iRet += wmt_plat_gpio_ctrl(PIN_UART_RX, PIN_STA_OUT_H); + break; + case STP_SDIO_IF_TX: + iRet += wmt_plat_gpio_ctrl(PIN_UART_RX, PIN_STA_OUT_L); + break; + default: + WMT_ERR_FUNC("not supported common interface\n"); + break; + } + } + /*4. PMU->output low, RST->output low, sleep off stable time */ + iRet += wmt_plat_gpio_ctrl(PIN_PMU, PIN_STA_OUT_L); + if (chip_id != 0x6632) + iRet += wmt_plat_gpio_ctrl(PIN_RST, PIN_STA_OUT_L); + osal_sleep_ms(gPwrSeqTime.offStableTime); + + /*5. PMU->output high, sleep rst stable time */ + iRet += wmt_plat_gpio_ctrl(PIN_PMU, PIN_STA_OUT_H); + osal_sleep_ms(gPwrSeqTime.rstStableTime); + + /*6. RST->output high, sleep on stable time */ + if (chip_id != 0x6632) + iRet += wmt_plat_gpio_ctrl(PIN_RST, PIN_STA_OUT_H); + osal_sleep_ms(gPwrSeqTime.onStableTime); + + /*set UART Tx/Rx to UART mode */ + if (0x6630 == chip_id || 0x6632 == chip_id) + iRet += wmt_plat_gpio_ctrl(PIN_UART_RX, PIN_STA_IN_NP); + + + /*7. set audio interface to CMB_STUB_AIF_1, BT PCM ON, I2S OFF */ + /* BT PCM bus default mode. Real control is done by audio */ + iRet += wmt_plat_audio_ctrl(CMB_STUB_AIF_1, CMB_STUB_AIF_CTRL_DIS); + + /*8. set EINT< -ommited-> move this to WMT-IC module, + * where common sdio interface will be identified and do proper operation + */ + /* TODO: [FixMe][GeorgeKuo] double check if BGF_INT is implemented ok */ + if (!((chip_id == 0x6630 || chip_id == 0x6632) + && (wmt_plat_get_comm_if_type() == STP_SDIO_IF_TX))) { + iRet += wmt_plat_gpio_ctrl(PIN_BGF_EINT, PIN_STA_MUX); + iRet += wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_INIT); + WMT_INFO_FUNC("CMB-HW, BGF_EINT IRQ registered and disabled\n"); + } else { + WMT_DBG_FUNC("CMB-HW, no need to register BGF_EINT for MT6630 & MT6632 SDIO mode\n"); + } + + /* 8.1 set ALL_EINT pin to correct state even it is not used currently */ + iRet += wmt_plat_gpio_ctrl(PIN_ALL_EINT, PIN_STA_MUX); + iRet += wmt_plat_eirq_ctrl(PIN_ALL_EINT, PIN_STA_INIT); + WMT_DBG_FUNC("CMB-HW, hw_pwr_on finish (%d)\n", iRet); + + _pwr_first_time = 0; + return iRet; + +} + +INT32 mtk_wcn_cmb_hw_rst(VOID) +{ + INT32 iRet = 0; + UINT32 chip_id = 0x0; + + WMT_INFO_FUNC("CMB-HW, hw_rst start, eirq should be disabled before this step\n"); + chip_id = mtk_wcn_wmt_chipid_query(); + iRet += wmt_plat_gpio_ctrl(PIN_UART_GRP, PIN_STA_INIT); + if (0x6630 == chip_id || 0x6632 == chip_id) { + switch (wmt_plat_get_comm_if_type()) { + case STP_UART_IF_TX: + iRet += wmt_plat_gpio_ctrl(PIN_UART_RX, PIN_STA_OUT_H); + break; + case STP_SDIO_IF_TX: + iRet += wmt_plat_gpio_ctrl(PIN_UART_RX, PIN_STA_OUT_L); + break; + default: + WMT_ERR_FUNC("not supported common interface\n"); + break; + } + } + + /*1. PMU->output low, RST->output low, sleep off stable time */ + iRet += wmt_plat_gpio_ctrl(PIN_PMU, PIN_STA_OUT_L); + if (chip_id != 0x6632) + iRet += wmt_plat_gpio_ctrl(PIN_RST, PIN_STA_OUT_L); + osal_sleep_ms(gPwrSeqTime.offStableTime); + + /*2. PMU->output high, sleep rst stable time */ + iRet += wmt_plat_gpio_ctrl(PIN_PMU, PIN_STA_OUT_H); + osal_sleep_ms(gPwrSeqTime.rstStableTime); + + /*3. RST->output high, sleep on stable time */ + if (chip_id != 0x6632) + iRet += wmt_plat_gpio_ctrl(PIN_RST, PIN_STA_OUT_H); + osal_sleep_ms(gPwrSeqTime.onStableTime); + + /*set UART Tx/Rx to UART mode */ + if (0x6630 == chip_id || 0x6632 == chip_id) + iRet += wmt_plat_gpio_ctrl(PIN_UART_RX, PIN_STA_IN_NP); + + WMT_INFO_FUNC("CMB-HW, hw_rst finish, eirq should be enabled after this step\n"); + return 0; +} + +static VOID mtk_wcn_cmb_hw_dmp_seq(VOID) +{ + PUINT32 pTimeSlot = (PUINT32) &gPwrSeqTime; + + WMT_INFO_FUNC + ("combo chip power on sequence time, RTC (%d), LDO (%d), RST(%d), OFF(%d), ON(%d)\n", + pTimeSlot[0], + /**pTimeSlot++,*/ + pTimeSlot[1], pTimeSlot[2], pTimeSlot[3], pTimeSlot[4] + ); +} + +INT32 mtk_wcn_cmb_hw_state_show(VOID) +{ + wmt_plat_gpio_ctrl(PIN_PMU, PIN_STA_SHOW); + wmt_plat_gpio_ctrl(PIN_RST, PIN_STA_SHOW); + wmt_plat_gpio_ctrl(PIN_RTC, PIN_STA_SHOW); + return 0; +} + + + +INT32 mtk_wcn_cmb_hw_init(P_PWR_SEQ_TIME pPwrSeqTime) +{ + if (pPwrSeqTime != NULL && + pPwrSeqTime->ldoStableTime > 0 && + pPwrSeqTime->rtcStableTime > 0 && + pPwrSeqTime->offStableTime > DFT_OFF_STABLE_TIME && + pPwrSeqTime->onStableTime > DFT_ON_STABLE_TIME && + pPwrSeqTime->rstStableTime > DFT_RST_STABLE_TIME) { + /*memcpy may be more performance */ + WMT_DBG_FUNC("setting hw init sequence parameters\n"); + osal_memcpy(&gPwrSeqTime, pPwrSeqTime, osal_sizeof(gPwrSeqTime)); + } else { + WMT_DBG_FUNC + ("invalid pPwrSeqTime parameter, use default hw init sequence parameters\n"); + gPwrSeqTime.ldoStableTime = DFT_LDO_STABLE_TIME; + gPwrSeqTime.offStableTime = DFT_OFF_STABLE_TIME; + gPwrSeqTime.onStableTime = DFT_ON_STABLE_TIME; + gPwrSeqTime.rstStableTime = DFT_RST_STABLE_TIME; + gPwrSeqTime.rtcStableTime = DFT_RTC_STABLE_TIME; + } + mtk_wcn_cmb_hw_dmp_seq(); + return 0; +} + +INT32 mtk_wcn_cmb_hw_deinit(VOID) +{ + + WMT_WARN_FUNC("mtk_wcn_cmb_hw_deinit start, set to default hw init sequence parameters\n"); + gPwrSeqTime.ldoStableTime = DFT_LDO_STABLE_TIME; + gPwrSeqTime.offStableTime = DFT_OFF_STABLE_TIME; + gPwrSeqTime.onStableTime = DFT_ON_STABLE_TIME; + gPwrSeqTime.rstStableTime = DFT_RST_STABLE_TIME; + gPwrSeqTime.rtcStableTime = DFT_RTC_STABLE_TIME; + WMT_WARN_FUNC("mtk_wcn_cmb_hw_deinit finish\n"); + return 0; +} diff --git a/drivers/misc/mediatek/connectivity/common/common_main/platform/mtk_wcn_consys_hw.c b/drivers/misc/mediatek/connectivity/common/common_main/platform/mtk_wcn_consys_hw.c new file mode 100644 index 0000000000000000000000000000000000000000..87c347e95f24295ce1835685365576faf9a29f10 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/platform/mtk_wcn_consys_hw.c @@ -0,0 +1,1251 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +/*! \file + * \brief Declaration of library functions + * + * Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +#ifdef DFT_TAG +#undef DFT_TAG +#endif +#define DFT_TAG "[WMT-CONSYS-HW]" + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include "osal_typedef.h" +#include "mtk_wcn_consys_hw.h" +#include "wmt_step.h" +#include "wmt_ic.h" +#include +#include +#include +#include +#include "wmt_lib.h" + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) +#include +#include +#include +#include +#include +#define ALLOCATE_CONNSYS_EMI_FROM_KO 1 +#endif + +#include + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +static INT32 mtk_wmt_probe(struct platform_device *pdev); +static INT32 mtk_wmt_remove(struct platform_device *pdev); +static INT32 mtk_wmt_suspend(struct device *dev); +static INT32 mtk_wmt_resume(struct device *dev); + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ +UINT8 __iomem *pEmibaseaddr; + +P_WMT_CONSYS_IC_OPS wmt_consys_ic_ops; + +struct platform_device *g_pdev; + +#ifdef ALLOCATE_CONNSYS_EMI_FROM_KO +phys_addr_t gConEmiPhyBase; +EXPORT_SYMBOL(gConEmiPhyBase); +unsigned long long gConEmiSize; +EXPORT_SYMBOL(gConEmiSize); +#endif + +UINT32 gps_lna_pin_num = 0xffffffff; + +INT32 chip_reset_status = -1; +static INT32 wifi_ant_swap_gpio_pin_num; + +static UINT32 g_adie_chipid; +static OSAL_SLEEPABLE_LOCK g_adie_chipid_lock; + +static atomic64_t g_sleep_counter_enable = ATOMIC64_INIT(1); +static OSAL_UNSLEEPABLE_LOCK g_sleep_counter_spinlock; + +static atomic_t g_probe_called = ATOMIC_INIT(0); + +#ifdef CONFIG_OF +const struct of_device_id apwmt_of_ids[] = { + {.compatible = "mediatek,mt3967-consys",}, + {.compatible = "mediatek,mt6570-consys",}, + {.compatible = "mediatek,mt6580-consys",}, + {.compatible = "mediatek,mt6735-consys",}, + {.compatible = "mediatek,mt6739-consys",}, + {.compatible = "mediatek,mt6755-consys",}, + {.compatible = "mediatek,mt6757-consys",}, + {.compatible = "mediatek,mt6758-consys",}, + {.compatible = "mediatek,mt6759-consys",}, + {.compatible = "mediatek,mt6763-consys",}, + {.compatible = "mediatek,mt6797-consys",}, + {.compatible = "mediatek,mt8127-consys",}, + {.compatible = "mediatek,mt8163-consys",}, + {.compatible = "mediatek,mt8167-consys",}, + {.compatible = "mediatek,mt6775-consys",}, + {.compatible = "mediatek,mt6771-consys",}, + {.compatible = "mediatek,mt6765-consys",}, + {.compatible = "mediatek,mt6761-consys",}, + {.compatible = "mediatek,mt6779-consys",}, + {.compatible = "mediatek,mt6768-consys",}, + {.compatible = "mediatek,mt6785-consys",}, + {.compatible = "mediatek,mt6833-consys",}, + {.compatible = "mediatek,mt6853-consys",}, + {.compatible = "mediatek,mt6873-consys",}, + {.compatible = "mediatek,mt8168-consys",}, + {} +}; +struct CONSYS_BASE_ADDRESS conn_reg; +#endif + +static const struct dev_pm_ops wmt_drv_pm_ops = { + .suspend_noirq = mtk_wmt_suspend, + .resume_noirq = mtk_wmt_resume, +}; + +static struct platform_driver mtk_wmt_dev_drv = { + .probe = mtk_wmt_probe, + .remove = mtk_wmt_remove, + .driver = { + .name = "mtk_wmt", + .owner = THIS_MODULE, +#ifdef CONFIG_OF + .of_match_table = apwmt_of_ids, +#endif + .pm = &wmt_drv_pm_ops, + }, +}; + +/* GPIO part */ +struct pinctrl *consys_pinctrl; + +struct work_struct plt_resume_worker; +static void plat_resume_handler(struct work_struct *work); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) +struct regmap *g_regmap; +#endif + +static int wmt_thermal_get_temp_cb(void *data, int *temp); +static const struct thermal_zone_of_device_ops tz_wmt_thermal_ops = { + .get_temp = wmt_thermal_get_temp_cb, +}; + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +INT32 __weak mtk_wcn_consys_jtag_set_for_mcu(VOID) +{ + WMT_PLAT_PR_WARN("Does not support on combo\n"); + return 0; +} + +#if CONSYS_ENALBE_SET_JTAG +UINT32 __weak mtk_wcn_consys_jtag_flag_ctrl(UINT32 en) +{ + WMT_PLAT_PR_WARN("Does not support on combo\n"); + return 0; +} +#endif + +#ifdef CONSYS_WMT_REG_SUSPEND_CB_ENABLE +UINT32 __weak mtk_wcn_consys_hw_osc_en_ctrl(UINT32 en) +{ + WMT_PLAT_PR_WARN("Does not support on combo\n"); + return 0; +} +#endif + +P_WMT_CONSYS_IC_OPS __weak mtk_wcn_get_consys_ic_ops(VOID) +{ + WMT_PLAT_PR_WARN("Does not support on combo\n"); + return NULL; +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) +static VOID mtk_wcn_get_regmap(struct platform_device *pdev) +{ + struct device_node *pmic_node; + struct platform_device *pmic_pdev; + struct mt6397_chip *chip; + + pmic_node = of_parse_phandle(pdev->dev.of_node, "pmic", 0); + if (!pmic_node) { + WMT_PLAT_PR_INFO("get pmic_node fail\n"); + return; + } + + pmic_pdev = of_find_device_by_node(pmic_node); + if (!pmic_pdev) { + WMT_PLAT_PR_INFO("get pmic_pdev fail\n"); + return; + } + + chip = dev_get_drvdata(&(pmic_pdev->dev)); + if (!chip) { + WMT_PLAT_PR_INFO("get chip fail\n"); + return; + } + + g_regmap = chip->regmap; + if (IS_ERR_VALUE(g_regmap)) { + g_regmap = NULL; + WMT_PLAT_PR_INFO("get regmap fail\n"); + } +} +#endif + +static INT32 wmt_allocate_connsys_emi(struct platform_device *pdev) +{ +#ifdef ALLOCATE_CONNSYS_EMI_FROM_KO + struct device_node *np; + struct reserved_mem *rmem; + + np = of_parse_phandle(pdev->dev.of_node, "memory-region", 0); + if (!np) { + WMT_PLAT_PR_INFO("no memory-region, np is NULL\n"); + return -1; + } + + rmem = of_reserved_mem_lookup(np); + of_node_put(np); + + if (!rmem) { + WMT_PLAT_PR_INFO("no memory-region\n"); + return -1; + } + + gConEmiPhyBase = rmem->base; + gConEmiSize = rmem->size; +#endif + return 0; +} + +static int wmt_thermal_get_temp_cb(void *data, int *temp) +{ + if (temp) { + *temp = wmt_lib_tm_temp_query() * 1000; + WMT_PLAT_PR_INFO("thermal = %d\n", *temp); + } + return 0; +} + +static INT32 wmt_thermal_register(struct platform_device *pdev) +{ + struct thermal_zone_device *tz; + int ret; + + /* register thermal zone */ + tz = devm_thermal_zone_of_sensor_register( + &pdev->dev, 0, NULL, &tz_wmt_thermal_ops); + + if (IS_ERR(tz)) { + ret = PTR_ERR(tz); + WMT_PLAT_PR_INFO("Failed to register thermal zone device %d\n", ret); + return -1; + } + WMT_PLAT_PR_INFO("Register thermal zone device.\n"); + return 0; +} + +static INT32 mtk_wmt_probe(struct platform_device *pdev) +{ + INT32 iRet = -1; + INT32 pin_ret = 0; + UINT32 pinmux = 0; + struct device_node *pinctl_node = NULL, *pins_node = NULL; + UINT8 __iomem *pConnsysEmiStart = NULL; + + if (pdev) + g_pdev = pdev; + else { + WMT_PLAT_PR_ERR("pdev is NULL\n"); + return -1; + } + + wmt_allocate_connsys_emi(pdev); + wmt_thermal_register(pdev); + + if (wmt_consys_ic_ops->consys_ic_need_store_pdev) { + if (wmt_consys_ic_ops->consys_ic_need_store_pdev() == MTK_WCN_BOOL_TRUE) { + if (wmt_consys_ic_ops->consys_ic_store_pdev) + wmt_consys_ic_ops->consys_ic_store_pdev(pdev); + pm_runtime_enable(&pdev->dev); + dev_pm_syscore_device(&pdev->dev, true); + } + } + + if (wmt_consys_ic_ops->consys_ic_read_reg_from_dts) + iRet = wmt_consys_ic_ops->consys_ic_read_reg_from_dts(pdev); + else + iRet = -1; + + if (iRet) + return iRet; + + if (wmt_consys_ic_ops->consys_ic_clk_get_from_dts) + iRet = wmt_consys_ic_ops->consys_ic_clk_get_from_dts(pdev); + else + iRet = -1; + + if (iRet) + return iRet; + + if (gConEmiPhyBase) { + pConnsysEmiStart = ioremap_nocache(gConEmiPhyBase, gConEmiSize); + WMT_PLAT_PR_INFO("Clearing Connsys EMI (virtual(0x%p) physical(0x%pa)) %llu bytes\n", + pConnsysEmiStart, &gConEmiPhyBase, gConEmiSize); + memset_io(pConnsysEmiStart, 0, gConEmiSize); + iounmap(pConnsysEmiStart); + pConnsysEmiStart = NULL; + + if (wmt_consys_ic_ops->consys_ic_emi_mpu_set_region_protection) + wmt_consys_ic_ops->consys_ic_emi_mpu_set_region_protection(); + if (wmt_consys_ic_ops->consys_ic_emi_set_remapping_reg) + wmt_consys_ic_ops->consys_ic_emi_set_remapping_reg(); + if (wmt_consys_ic_ops->consys_ic_emi_coredump_remapping) + wmt_consys_ic_ops->consys_ic_emi_coredump_remapping(&pEmibaseaddr, 1); +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH + if (wmt_consys_ic_ops->consys_ic_dedicated_log_path_init) + wmt_consys_ic_ops->consys_ic_dedicated_log_path_init(pdev); +#endif + } else { + WMT_PLAT_PR_ERR("consys emi memory address gConEmiPhyBase invalid\n"); + } + +#ifdef CONFIG_MTK_HIBERNATION + WMT_PLAT_PR_INFO("register connsys restore cb for complying with IPOH function\n"); + register_swsusp_restore_noirq_func(ID_M_CONNSYS, mtk_wcn_consys_hw_restore, NULL); +#endif + + if (wmt_consys_ic_ops->ic_bt_wifi_share_v33_spin_lock_init) + wmt_consys_ic_ops->ic_bt_wifi_share_v33_spin_lock_init(); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) + mtk_wcn_get_regmap(pdev); +#endif + if (wmt_consys_ic_ops->consys_ic_pmic_get_from_dts) + wmt_consys_ic_ops->consys_ic_pmic_get_from_dts(pdev); + + consys_pinctrl = devm_pinctrl_get(&pdev->dev); + if (IS_ERR(consys_pinctrl)) { + WMT_PLAT_PR_ERR("cannot find consys pinctrl.\n"); + consys_pinctrl = NULL; + } + + /* find gps lna gpio number */ + if (consys_pinctrl) { + pinctl_node = of_parse_phandle(pdev->dev.of_node, "pinctrl-1", 0); + if (pinctl_node) { + pins_node = of_get_child_by_name(pinctl_node, "pins_cmd_dat"); + if (pins_node) { + pin_ret = of_property_read_u32(pins_node, "pinmux", &pinmux); + if (pin_ret) + pin_ret = of_property_read_u32(pins_node, "pins", &pinmux); + gps_lna_pin_num = (pinmux >> 8) & 0xff; + WMT_PLAT_PR_INFO("GPS LNA gpio pin number:%d, pinmux:0x%08x.\n", + gps_lna_pin_num, pinmux); + } + } + } + + wifi_ant_swap_gpio_pin_num = of_get_named_gpio(pdev->dev.of_node, "wifi_ant_swap_gpio", 0); + WMT_PLAT_PR_INFO("ant swap pin number:%d\n", wifi_ant_swap_gpio_pin_num); + + if (wmt_consys_ic_ops->consys_ic_store_reset_control) + wmt_consys_ic_ops->consys_ic_store_reset_control(pdev); + + if (wmt_consys_ic_ops->consys_ic_register_devapc_cb) + wmt_consys_ic_ops->consys_ic_register_devapc_cb(); + + osal_unsleepable_lock_init(&g_sleep_counter_spinlock); + osal_sleepable_lock_init(&g_adie_chipid_lock); + + INIT_WORK(&plt_resume_worker, plat_resume_handler); + + atomic_set(&g_probe_called, 1); + + return 0; +} + +static INT32 mtk_wmt_remove(struct platform_device *pdev) +{ + if (wmt_consys_ic_ops->consys_ic_need_store_pdev) { + if (wmt_consys_ic_ops->consys_ic_need_store_pdev() == MTK_WCN_BOOL_TRUE) + pm_runtime_disable(&pdev->dev); + } + +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH + if (wmt_consys_ic_ops->consys_ic_dedicated_log_path_deinit) + wmt_consys_ic_ops->consys_ic_dedicated_log_path_deinit(); +#endif + if (wmt_consys_ic_ops->consys_ic_emi_coredump_remapping) + wmt_consys_ic_ops->consys_ic_emi_coredump_remapping(&pEmibaseaddr, 0); + + if (g_pdev) + g_pdev = NULL; + + osal_unsleepable_lock_deinit(&g_sleep_counter_spinlock); + osal_sleepable_lock_deinit(&g_adie_chipid_lock); + + atomic_set(&g_probe_called, 0); + return 0; +} + +static INT32 mtk_wmt_suspend(struct device *dev) +{ + WMT_PLAT_PR_INFO(" mtk_wmt_suspend !!"); + WMT_STEP_DO_ACTIONS_FUNC(STEP_TRIGGER_POINT_WHEN_AP_SUSPEND); + + mtk_wcn_consys_sleep_info_clear(); + return 0; +} + + +static void plat_resume_handler(struct work_struct *work) +{ + CONSYS_STATE_DMP_INFO dmp_info; + UINT8 dmp_info_buf[DBG_LOG_STR_SIZE]; + int len = 0, i, dmp_cnt = 5; + P_DEV_WMT pDev = &gDevWmt; + + if (wmt_lib_dmp_consys_state(&dmp_info, dmp_cnt, 0) == MTK_WCN_BOOL_TRUE) { + len += snprintf(dmp_info_buf + len, + DBG_LOG_STR_SIZE - len, "0x%08x", dmp_info.cpu_pcr[0]); + + for (i = 1; i < dmp_cnt; i++) + len += snprintf(dmp_info_buf + len, + DBG_LOG_STR_SIZE - len, ";0x%08x", dmp_info.cpu_pcr[i]); + + len += snprintf(dmp_info_buf + len, + DBG_LOG_STR_SIZE - len, ";0x%08x", dmp_info.state.lp[1]); + + len += snprintf(dmp_info_buf + len, + DBG_LOG_STR_SIZE - len, ";0x%08x", dmp_info.state.gating[1]); + + len += snprintf(dmp_info_buf + len, + DBG_LOG_STR_SIZE - len, ";%llu", dmp_info.state.sleep_counter[0]); + for (i = 1; i < WMT_SLEEP_COUNT_MAX; i++) { + len += snprintf(dmp_info_buf + len, + DBG_LOG_STR_SIZE - len, ",%llu", dmp_info.state.sleep_counter[i]); + } + + len += snprintf(dmp_info_buf + len, + DBG_LOG_STR_SIZE - len, ";%llu", dmp_info.state.sleep_timer[0]); + for (i = 1; i < WMT_SLEEP_COUNT_MAX; i++) { + len += snprintf(dmp_info_buf + len, + DBG_LOG_STR_SIZE - len, ",%llu", dmp_info.state.sleep_timer[i]); + } + + WMT_PLAT_PR_INFO("%s\n", dmp_info_buf); + } else { + if ((wmt_lib_get_drv_status(WMTDRV_TYPE_WMT) != DRV_STS_FUNC_ON) + || (osal_test_bit(WMT_STAT_PWR, &pDev->state)) == 0) { + WMT_PLAT_PR_INFO("TOP:0,0;MCU:0,0;BT:0,0;WIFI:0,0;GPS:0,0\n"); + } + } +} + +static INT32 mtk_wmt_resume(struct device *dev) +{ + WMT_PLAT_PR_INFO(" mtk_wmt_resume !!"); + schedule_work(&plt_resume_worker); + + return 0; +} + +INT32 mtk_wcn_consys_sleep_info_read_all_ctrl(P_CONSYS_STATE state) +{ + INT32 ret = 0; + INT32 i = 0; + UINT64 sleep_counter = 0, sleep_timer = 0; + UINT8 strbuf[DBG_LOG_STR_SIZE] = {""}; + UINT32 len = 0; + + WMT_PLAT_PR_DBG("sleep count info read all ctrl start\n"); + + if (wmt_consys_ic_ops->consys_ic_sleep_info_enable_ctrl && + wmt_consys_ic_ops->consys_ic_sleep_info_read_ctrl && + wmt_consys_ic_ops->consys_ic_sleep_info_clear) { + osal_lock_unsleepable_lock(&g_sleep_counter_spinlock); + if (atomic64_read(&g_sleep_counter_enable) == 1) { + for (i = 0; i < WMT_SLEEP_COUNT_MAX; i++) { + sleep_counter = 0; + sleep_timer = 0; + wmt_consys_ic_ops->consys_ic_sleep_info_read_ctrl(i, &sleep_counter, &sleep_timer); + if (state) { + state->sleep_counter[i] = sleep_counter; + state->sleep_timer[i] = sleep_timer; + } + len += osal_sprintf(strbuf + len, "%s%s%s%s%s:%llu,%llu;", + ((i == WMT_SLEEP_COUNT_TOP) ? "TOP" : ""), + ((i == WMT_SLEEP_COUNT_MCU) ? "MCU" : ""), + ((i == WMT_SLEEP_COUNT_BT) ? "BT" : ""), + ((i == WMT_SLEEP_COUNT_WF) ? "WIFI" : ""), + ((i == WMT_SLEEP_COUNT_GPS) ? "GPS" : ""), + sleep_counter, sleep_timer); + } + len += osal_sprintf(strbuf + len - 1, ""); + WMT_PLAT_PR_INFO("%s\n", strbuf); + } else { + ret = -21; + } + osal_unlock_unsleepable_lock(&g_sleep_counter_spinlock); + } + + return ret; +} + +INT32 mtk_wcn_consys_sleep_info_clear(VOID) +{ + INT32 ret = 0; + P_DEV_WMT pDev = &gDevWmt; + + WMT_PLAT_PR_DBG("sleep count info clear start\n"); + + if (wmt_consys_ic_ops->consys_ic_sleep_info_enable_ctrl && + wmt_consys_ic_ops->consys_ic_sleep_info_read_ctrl && + wmt_consys_ic_ops->consys_ic_sleep_info_clear) { + + osal_lock_unsleepable_lock(&g_sleep_counter_spinlock); + + if ((wmt_lib_get_drv_status(WMTDRV_TYPE_WMT) == DRV_STS_FUNC_ON) + && (osal_test_bit(WMT_STAT_PWR, &pDev->state))) + ret = wmt_consys_ic_ops->consys_ic_sleep_info_clear(); + osal_unlock_unsleepable_lock(&g_sleep_counter_spinlock); + } + + return ret; +} + +INT32 mtk_wcn_consys_sleep_info_restore(VOID) +{ + P_DEV_WMT pDev = &gDevWmt; + + WMT_PLAT_PR_DBG("sleep count info restore start\n"); + + if (NULL != wmt_consys_ic_ops && + wmt_consys_ic_ops->consys_ic_sleep_info_enable_ctrl && + wmt_consys_ic_ops->consys_ic_sleep_info_read_ctrl && + wmt_consys_ic_ops->consys_ic_sleep_info_clear) { + if ((wmt_lib_get_drv_status(WMTDRV_TYPE_WMT) == DRV_STS_FUNC_ON) + && (osal_test_bit(WMT_STAT_PWR, &pDev->state))) { + osal_lock_unsleepable_lock(&g_sleep_counter_spinlock); + if (atomic64_read(&g_sleep_counter_enable) == 1) + wmt_consys_ic_ops->consys_ic_sleep_info_enable_ctrl(1); + osal_unlock_unsleepable_lock(&g_sleep_counter_spinlock); + } + } + + return 0; +} + +INT32 mtk_wcn_consys_hw_reg_ctrl(UINT32 on, UINT32 co_clock_type) +{ + INT32 iRet = 0; + + WMT_PLAT_PR_INFO("CONSYS-HW-REG-CTRL(0x%08x),start\n", on); + + if (on) { + WMT_PLAT_PR_DBG("++\n"); + if (wmt_consys_ic_ops->consys_ic_reset_emi_coredump) + wmt_consys_ic_ops->consys_ic_reset_emi_coredump(pEmibaseaddr); + + if (wmt_consys_ic_ops->consys_ic_hw_vcn18_ctrl) + wmt_consys_ic_ops->consys_ic_hw_vcn18_ctrl(ENABLE); + + if (wmt_consys_ic_ops->consys_ic_set_if_pinmux) + wmt_consys_ic_ops->consys_ic_set_if_pinmux(ENABLE); + + udelay(150); + + if (co_clock_type) { + WMT_PLAT_PR_INFO("co clock type(%d),turn on clk buf\n", co_clock_type); + if (wmt_consys_ic_ops->consys_ic_clock_buffer_ctrl) + wmt_consys_ic_ops->consys_ic_clock_buffer_ctrl(ENABLE); + } + + if (co_clock_type) { + /*if co-clock mode: */ + /*1.set VCN28 to SW control mode (with PMIC_WRAP API) */ + if (wmt_consys_ic_ops->consys_ic_vcn28_hw_mode_ctrl) + wmt_consys_ic_ops->consys_ic_vcn28_hw_mode_ctrl(DISABLE); + } else { + /*if NOT co-clock: */ + /*1.set VCN28 to HW control mode (with PMIC_WRAP API) */ + /*2.turn on VCN28 LDO (with PMIC_WRAP API)" */ + if (wmt_consys_ic_ops->consys_ic_vcn28_hw_mode_ctrl) + wmt_consys_ic_ops->consys_ic_vcn28_hw_mode_ctrl(ENABLE); + if (wmt_consys_ic_ops->consys_ic_hw_vcn28_ctrl) + wmt_consys_ic_ops->consys_ic_hw_vcn28_ctrl(ENABLE); + } + + /* turn on VCN28 LDO for reading efuse usage */ + mtk_wcn_consys_hw_efuse_paldo_ctrl(ENABLE, co_clock_type); + + if (wmt_consys_ic_ops->consys_ic_hw_reset_bit_set) + wmt_consys_ic_ops->consys_ic_hw_reset_bit_set(ENABLE); + if (wmt_consys_ic_ops->consys_ic_hw_spm_clk_gating_enable) + wmt_consys_ic_ops->consys_ic_hw_spm_clk_gating_enable(); + if (wmt_consys_ic_ops->consys_ic_hw_power_ctrl) + wmt_consys_ic_ops->consys_ic_hw_power_ctrl(ENABLE); + + udelay(10); + + if (wmt_consys_ic_ops->consys_ic_ahb_clock_ctrl) + wmt_consys_ic_ops->consys_ic_ahb_clock_ctrl(ENABLE); + + WMT_STEP_DO_ACTIONS_FUNC(STEP_TRIGGER_POINT_POWER_ON_BEFORE_GET_CONNSYS_ID); + + if (wmt_consys_ic_ops->polling_consys_ic_chipid && + wmt_consys_ic_ops->polling_consys_ic_chipid() < 0) + return -WMT_ERRCODE_POLL_CHIPID_FAIL; + + if (wmt_consys_ic_ops->consys_ic_set_access_emi_hw_mode) + wmt_consys_ic_ops->consys_ic_set_access_emi_hw_mode(); + if (wmt_consys_ic_ops->update_consys_rom_desel_value) + wmt_consys_ic_ops->update_consys_rom_desel_value(); + if (wmt_consys_ic_ops->consys_ic_acr_reg_setting) + wmt_consys_ic_ops->consys_ic_acr_reg_setting(); + if (wmt_consys_ic_ops->consys_ic_afe_reg_setting) + wmt_consys_ic_ops->consys_ic_afe_reg_setting(); + if (wmt_consys_ic_ops->consys_ic_emi_entry_address) + wmt_consys_ic_ops->consys_ic_emi_entry_address(); + if (wmt_consys_ic_ops->consys_ic_set_xo_osc_ctrl) + wmt_consys_ic_ops->consys_ic_set_xo_osc_ctrl(); + if (wmt_consys_ic_ops->consys_ic_identify_adie) + wmt_consys_ic_ops->consys_ic_identify_adie(); + if (wmt_consys_ic_ops->consys_ic_wifi_ctrl_setting) + wmt_consys_ic_ops->consys_ic_wifi_ctrl_setting(); + if (wmt_consys_ic_ops->consys_ic_bus_timeout_config) + wmt_consys_ic_ops->consys_ic_bus_timeout_config(); + if (wmt_consys_ic_ops->consys_ic_hw_reset_bit_set) + wmt_consys_ic_ops->consys_ic_hw_reset_bit_set(DISABLE); + + if (wmt_consys_ic_ops->consys_ic_polling_goto_idle && + wmt_consys_ic_ops->consys_ic_polling_goto_idle()) + return -WMT_ERRCODE_POLL_NOT_GOTO_IDLE; + + if (wmt_consys_ic_ops->consys_ic_wifi_ctrl_switch_conn_mode) + wmt_consys_ic_ops->consys_ic_wifi_ctrl_switch_conn_mode(); + if (wmt_consys_ic_ops->consys_ic_hw_vcn_ctrl_after_idle) + wmt_consys_ic_ops->consys_ic_hw_vcn_ctrl_after_idle(); + msleep(20); + + } else { + if (wmt_consys_ic_ops->consys_ic_ahb_clock_ctrl) + wmt_consys_ic_ops->consys_ic_ahb_clock_ctrl(DISABLE); + if (wmt_consys_ic_ops->consys_ic_hw_power_ctrl) + wmt_consys_ic_ops->consys_ic_hw_power_ctrl(DISABLE); + if (co_clock_type) { + if (wmt_consys_ic_ops->consys_ic_clock_buffer_ctrl) + wmt_consys_ic_ops->consys_ic_clock_buffer_ctrl(DISABLE); + } + + if (co_clock_type == 0) { + if (wmt_consys_ic_ops->consys_ic_vcn28_hw_mode_ctrl) + wmt_consys_ic_ops->consys_ic_vcn28_hw_mode_ctrl(DISABLE); + /*turn off VCN28 LDO (with PMIC_WRAP API)" */ + if (wmt_consys_ic_ops->consys_ic_hw_vcn28_ctrl) + wmt_consys_ic_ops->consys_ic_hw_vcn28_ctrl(DISABLE); + } + + if (wmt_consys_ic_ops->consys_ic_set_if_pinmux) + wmt_consys_ic_ops->consys_ic_set_if_pinmux(DISABLE); + + if (wmt_consys_ic_ops->consys_ic_hw_vcn18_ctrl) + wmt_consys_ic_ops->consys_ic_hw_vcn18_ctrl(DISABLE); + } + WMT_PLAT_PR_INFO("CONSYS-HW-REG-CTRL(0x%08x),finish\n", on); + return iRet; +} +/*tag4 wujun api big difference end*/ + +INT32 mtk_wcn_consys_hw_bt_paldo_ctrl(UINT32 enable) +{ + if (wmt_consys_ic_ops->consys_ic_hw_bt_vcn33_ctrl) + wmt_consys_ic_ops->consys_ic_hw_bt_vcn33_ctrl(enable); + return 0; +} + +INT32 mtk_wcn_consys_hw_wifi_paldo_ctrl(UINT32 enable) +{ + if (wmt_consys_ic_ops->consys_ic_hw_wifi_vcn33_ctrl) + wmt_consys_ic_ops->consys_ic_hw_wifi_vcn33_ctrl(enable); + return 0; +} +EXPORT_SYMBOL(mtk_wcn_consys_hw_wifi_paldo_ctrl); + +INT32 mtk_wcn_consys_hw_efuse_paldo_ctrl(UINT32 enable, UINT32 co_clock_type) +{ + if (co_clock_type) { + if (wmt_consys_ic_ops->consys_ic_hw_vcn28_ctrl) + wmt_consys_ic_ops->consys_ic_hw_vcn28_ctrl(enable); + if (enable) + WMT_PLAT_PR_INFO("turn on vcn28 for efuse usage in co-clock mode\n"); + else + WMT_PLAT_PR_INFO("turn off vcn28 for efuse usage in co-clock mode\n"); + } + return 0; +} +EXPORT_SYMBOL(mtk_wcn_consys_hw_efuse_paldo_ctrl); + +INT32 mtk_wcn_consys_hw_vcn28_ctrl(UINT32 enable) +{ + if (wmt_consys_ic_ops->consys_ic_hw_vcn28_ctrl) + wmt_consys_ic_ops->consys_ic_hw_vcn28_ctrl(enable); + if (enable) + WMT_PLAT_PR_INFO("turn on vcn28 for fm/gps usage in co-clock mode\n"); + else + WMT_PLAT_PR_INFO("turn off vcn28 for fm/gps usage in co-clock mode\n"); + return 0; +} + +UINT32 mtk_wcn_consys_soc_chipid(VOID) +{ + if (wmt_consys_ic_ops == NULL) + wmt_consys_ic_ops = mtk_wcn_get_consys_ic_ops(); + + if (wmt_consys_ic_ops && wmt_consys_ic_ops->consys_ic_soc_chipid_get) + return wmt_consys_ic_ops->consys_ic_soc_chipid_get(); + else + return 0; +} + +UINT32 mtk_wcn_consys_get_adie_chipid(VOID) +{ + return g_adie_chipid; +} + +INT32 mtk_wcn_consys_detect_adie_chipid(UINT32 co_clock_type) +{ + INT32 chipid = 0; + + if (osal_lock_sleepable_lock(&g_adie_chipid_lock)) + return 0; + + /* detect a-die only once */ + if (g_adie_chipid) { + osal_unlock_sleepable_lock(&g_adie_chipid_lock); + return g_adie_chipid; + } + + if (wmt_consys_ic_ops == NULL) + wmt_consys_ic_ops = mtk_wcn_get_consys_ic_ops(); + + if (wmt_consys_ic_ops && wmt_consys_ic_ops->consys_ic_adie_chipid_detect) { + WMT_PLAT_PR_INFO("CONSYS A-DIE DETECT start\n"); + chipid = wmt_consys_ic_ops->consys_ic_adie_chipid_detect(); + if (chipid > 0) { + g_adie_chipid = chipid; + WMT_PLAT_PR_INFO("Set a-die chipid = %x\n", chipid); + } else + WMT_PLAT_PR_INFO("Detect a-die chipid = %x failed!\n", chipid); + WMT_PLAT_PR_INFO("CONSYS A-DIE DETECT finish\n"); + } + + osal_unlock_sleepable_lock(&g_adie_chipid_lock); + + return chipid; +} + +struct pinctrl *mtk_wcn_consys_get_pinctrl() +{ + return consys_pinctrl; +} + +INT32 mtk_wcn_consys_hw_gpio_ctrl(UINT32 on) +{ + INT32 iRet = 0; + + WMT_PLAT_PR_DBG("CONSYS-HW-GPIO-CTRL(0x%08x), start\n", on); + + if (on) { + if (wmt_consys_ic_ops->consys_ic_need_gps) { + if (wmt_consys_ic_ops->consys_ic_need_gps() == MTK_WCN_BOOL_TRUE) { + /*if external modem used,GPS_SYNC still needed to control */ + iRet += wmt_plat_gpio_ctrl(PIN_GPS_SYNC, PIN_STA_INIT); + iRet += wmt_plat_gpio_ctrl(PIN_GPS_LNA, PIN_STA_INIT); + + iRet += wmt_plat_gpio_ctrl(PIN_I2S_GRP, PIN_STA_INIT); + } + } else { + iRet += wmt_plat_gpio_ctrl(PIN_GPS_SYNC, PIN_STA_INIT); + iRet += wmt_plat_gpio_ctrl(PIN_GPS_LNA, PIN_STA_INIT); + + iRet += wmt_plat_gpio_ctrl(PIN_I2S_GRP, PIN_STA_INIT); + } + /* TODO: [FixMe][GeorgeKuo] double check if BGF_INT is implemented ok */ + /* iRet += wmt_plat_gpio_ctrl(PIN_BGF_EINT, PIN_STA_MUX); */ + iRet += wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_INIT); + iRet += wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS); + WMT_PLAT_PR_DBG("CONSYS-HW, BGF IRQ registered and disabled\n"); + } else { + /* set bgf eint/all eint to deinit state, namely input low state */ + iRet += wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS); + iRet += wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_DEINIT); + WMT_PLAT_PR_DBG("CONSYS-HW, BGF IRQ unregistered and disabled\n"); + /* iRet += wmt_plat_gpio_ctrl(PIN_BGF_EINT, PIN_STA_DEINIT); */ + if (wmt_consys_ic_ops->consys_ic_need_gps) { + if (wmt_consys_ic_ops->consys_ic_need_gps() == MTK_WCN_BOOL_TRUE) { + /*if external modem used,GPS_SYNC still needed to control */ + iRet += wmt_plat_gpio_ctrl(PIN_GPS_SYNC, PIN_STA_DEINIT); + iRet += wmt_plat_gpio_ctrl(PIN_I2S_GRP, PIN_STA_DEINIT); + /* deinit gps_lna */ + iRet += wmt_plat_gpio_ctrl(PIN_GPS_LNA, PIN_STA_DEINIT); + } + } else { + iRet += wmt_plat_gpio_ctrl(PIN_GPS_SYNC, PIN_STA_DEINIT); + iRet += wmt_plat_gpio_ctrl(PIN_I2S_GRP, PIN_STA_DEINIT); + iRet += wmt_plat_gpio_ctrl(PIN_GPS_LNA, PIN_STA_DEINIT); + } + } + WMT_PLAT_PR_DBG("CONSYS-HW-GPIO-CTRL(0x%08x),iRet(%d) finish\n", on, iRet); + + return (iRet) ? -WMT_ERRCODE_GPIO_CTRL_FAIL : 0; + +} + +INT32 mtk_wcn_consys_hw_pwr_on(UINT32 co_clock_type) +{ + INT32 iRet = 0; + + WMT_PLAT_PR_INFO("CONSYS-HW-PWR-ON, start\n"); + WMT_STEP_DO_ACTIONS_FUNC(STEP_TRIGGER_POINT_POWER_ON_START); + if (!gConEmiPhyBase) { + WMT_PLAT_PR_ERR("EMI base address is invalid, CONNSYS can not be powered on!"); + return -WMT_ERRCODE_EMI_NOT_READY; + } + iRet = mtk_wcn_consys_hw_reg_ctrl(1, co_clock_type); + if (iRet) { + WMT_PLAT_PR_ERR("CONSYS-HW-PWR-ON, failed!(%d)\n", iRet); + return iRet; + } + iRet = mtk_wcn_consys_hw_gpio_ctrl(1); + mtk_wcn_consys_jtag_set_for_mcu(); + + WMT_PLAT_PR_INFO("CONSYS-HW-PWR-ON, finish(%d)\n", iRet); + + return iRet; +} + +INT32 mtk_wcn_consys_hw_pwr_off(UINT32 co_clock_type) +{ + INT32 iRet = 0; + + WMT_PLAT_PR_INFO("CONSYS-HW-PWR-OFF, start\n"); + WMT_STEP_DO_ACTIONS_FUNC(STEP_TRIGGER_POINT_BEFORE_POWER_OFF); + + iRet = mtk_wcn_consys_hw_reg_ctrl(0, co_clock_type); + if (iRet) { + WMT_PLAT_PR_ERR("CONSYS-HW-PWR-OFF, failed!(%d)\n", iRet); + return iRet; + } + iRet = mtk_wcn_consys_hw_gpio_ctrl(0); + + WMT_PLAT_PR_INFO("CONSYS-HW-PWR-OFF, finish(%d)\n", iRet); + return iRet; +} + +INT32 mtk_wcn_consys_hw_rst(UINT32 co_clock_type) +{ + INT32 iRet = 0; + + WMT_PLAT_PR_INFO("CONSYS-HW, hw_rst start, eirq should be disabled before this step\n"); + + mtk_consys_set_chip_reset_status(1); + + if (wmt_consys_ic_ops->consys_ic_set_dl_rom_patch_flag) + wmt_consys_ic_ops->consys_ic_set_dl_rom_patch_flag(1); + + /* Dump infra register for debug purpose */ + if (wmt_consys_ic_ops->consys_ic_infra_reg_dump) + wmt_consys_ic_ops->consys_ic_infra_reg_dump(); + + /* write 0x5000_0154.Bit[1] = 1 (pdma_axi_rready_force_high) to prevent pdma block slpprot */ + if (wmt_consys_ic_ops->consys_ic_set_pdma_axi_rready_force_high) + wmt_consys_ic_ops->consys_ic_set_pdma_axi_rready_force_high(1); + + /*1. do whole hw power off flow */ + iRet += mtk_wcn_consys_hw_reg_ctrl(0, co_clock_type); + + /* Write Wi-Fi calibration data back to EMI */ + mtk_wcn_soc_restore_wifi_cal_result(); + + /*2. do whole hw power on flow */ + iRet += mtk_wcn_consys_hw_reg_ctrl(1, co_clock_type); + + /* Make sure pdma_axi_rready_force_high set to 0 after reset */ + if (wmt_consys_ic_ops->consys_ic_set_pdma_axi_rready_force_high) + wmt_consys_ic_ops->consys_ic_set_pdma_axi_rready_force_high(0); + + mtk_consys_set_chip_reset_status(0); + + WMT_PLAT_PR_INFO("CONSYS-HW, hw_rst finish, eirq should be enabled after this step\n"); + return iRet; +} + +INT32 mtk_wcn_consys_hw_state_show(VOID) +{ + return 0; +} + +INT32 mtk_wcn_consys_hw_restore(struct device *device) +{ + if (gConEmiPhyBase) { + if (wmt_consys_ic_ops->consys_ic_emi_mpu_set_region_protection) + wmt_consys_ic_ops->consys_ic_emi_mpu_set_region_protection(); + if (wmt_consys_ic_ops->consys_ic_emi_set_remapping_reg) + wmt_consys_ic_ops->consys_ic_emi_set_remapping_reg(); + if (wmt_consys_ic_ops->consys_ic_emi_coredump_remapping) + wmt_consys_ic_ops->consys_ic_emi_coredump_remapping(&pEmibaseaddr, 1); + } else { + WMT_PLAT_PR_ERR("consys emi memory address gConEmiPhyBase invalid\n"); + } + + return 0; +} + +INT32 mtk_wcn_consys_hw_init(VOID) +{ + INT32 iRet = -1, retry = 0; + + if (wmt_consys_ic_ops == NULL) + wmt_consys_ic_ops = mtk_wcn_get_consys_ic_ops(); + + iRet = platform_driver_register(&mtk_wmt_dev_drv); + if (iRet) + WMT_PLAT_PR_ERR("WMT platform driver registered failed(%d)\n", iRet); + else { + while (atomic_read(&g_probe_called) == 0 && retry < 100) { + osal_sleep_ms(50); + retry++; + WMT_PLAT_PR_INFO("g_probe_called = 0, retry = %d\n", retry); + } + } + + return iRet; + +} + +INT32 mtk_wcn_consys_hw_deinit(VOID) +{ + + if (pEmibaseaddr) { + if (wmt_consys_ic_ops->consys_ic_emi_coredump_remapping) + wmt_consys_ic_ops->consys_ic_emi_coredump_remapping(&pEmibaseaddr, 0); + } +#ifdef CONFIG_MTK_HIBERNATION + unregister_swsusp_restore_noirq_func(ID_M_CONNSYS); +#endif + + platform_driver_unregister(&mtk_wmt_dev_drv); + + if (wmt_consys_ic_ops) + wmt_consys_ic_ops = NULL; + + return 0; +} + +PUINT8 mtk_wcn_consys_emi_virt_addr_get(UINT32 ctrl_state_offset) +{ + UINT8 *p_virtual_addr = NULL; + + if (!pEmibaseaddr) { + WMT_PLAT_PR_ERR("EMI base address is NULL\n"); + return NULL; + } + WMT_PLAT_PR_DBG("ctrl_state_offset(%08x)\n", ctrl_state_offset); + p_virtual_addr = pEmibaseaddr + ctrl_state_offset; + + return p_virtual_addr; +} + +INT32 mtk_wcn_consys_set_dbg_mode(UINT32 flag) +{ + INT32 ret = -1; + PUINT8 vir_addr = NULL; + + vir_addr = mtk_wcn_consys_emi_virt_addr_get(EXP_APMEM_CTRL_CHIP_FW_DBGLOG_MODE); + if (!vir_addr) { + WMT_PLAT_PR_ERR("get vir address fail\n"); + return -2; + } + if (flag) { + ret = 0; + CONSYS_REG_WRITE(vir_addr, 0x1); + } else { + CONSYS_REG_WRITE(vir_addr, 0x0); + } + WMT_PLAT_PR_INFO("fw dbg mode register value(0x%08x)\n", CONSYS_REG_READ(vir_addr)); + return ret; +} + +INT32 mtk_wcn_consys_set_dynamic_dump(PUINT32 str_buf) +{ + PUINT8 vir_addr = NULL; + + vir_addr = mtk_wcn_consys_emi_virt_addr_get(EXP_APMEM_CTRL_CHIP_DYNAMIC_DUMP); + if (!vir_addr) { + WMT_PLAT_PR_ERR("get vir address fail\n"); + return -2; + } + memcpy(vir_addr, str_buf, DYNAMIC_DUMP_GROUP_NUM*8); + WMT_PLAT_PR_INFO("dynamic dump register value(0x%08x)\n", CONSYS_REG_READ(vir_addr)); + return 0; +} + +INT32 mtk_wcn_consys_co_clock_type(VOID) +{ + if (wmt_consys_ic_ops == NULL) + wmt_consys_ic_ops = mtk_wcn_get_consys_ic_ops(); + + if (wmt_consys_ic_ops && wmt_consys_ic_ops->consys_ic_co_clock_type) + return wmt_consys_ic_ops->consys_ic_co_clock_type(); + else + return -1; +} + +P_CONSYS_EMI_ADDR_INFO mtk_wcn_consys_soc_get_emi_phy_add(VOID) +{ + if (wmt_consys_ic_ops->consys_ic_soc_get_emi_phy_add) + return wmt_consys_ic_ops->consys_ic_soc_get_emi_phy_add(); + else + return NULL; +} + +UINT32 mtk_wcn_consys_read_cpupcr(VOID) +{ + if (wmt_consys_ic_ops->consys_ic_read_cpupcr) + return wmt_consys_ic_ops->consys_ic_read_cpupcr(); + else + return 0; +} + +VOID mtk_wcn_force_trigger_assert_debug_pin(VOID) +{ + if (wmt_consys_ic_ops->ic_force_trigger_assert_debug_pin) + wmt_consys_ic_ops->ic_force_trigger_assert_debug_pin(); +} + +INT32 mtk_wcn_consys_read_irq_info_from_dts(PINT32 irq_num, PUINT32 irq_flag) +{ + if (wmt_consys_ic_ops->consys_ic_read_irq_info_from_dts) + return wmt_consys_ic_ops->consys_ic_read_irq_info_from_dts(g_pdev, irq_num, irq_flag); + else + return 0; +} + +VOID mtk_wcn_consys_hang_debug(VOID) +{ + if (wmt_consys_ic_ops && wmt_consys_ic_ops->consys_hang_debug) + wmt_consys_ic_ops->consys_hang_debug(); +} + +UINT32 mtk_consys_get_gps_lna_pin_num(VOID) +{ + return gps_lna_pin_num; +} + +INT32 mtk_wcn_consys_reg_ctrl(UINT32 is_write, enum CONSYS_BASE_ADDRESS_INDEX index, UINT32 offset, + PUINT32 value) +{ + INT32 iRet = -1; + PUINT32 reg_info = NULL; + UINT32 reg_info_size = index * 4 + 4; + struct device_node *node; + PVOID remap_addr = NULL; + + reg_info = osal_malloc(reg_info_size * sizeof(UINT32)); + if (!reg_info) { + WMT_PLAT_PR_ERR("reg_info osal_malloc fail\n"); + goto fail; + } + + node = g_pdev->dev.of_node; + if (node) { + if (of_property_read_u32_array(node, "reg", reg_info, reg_info_size)) { + WMT_PLAT_PR_ERR("get reg from DTS fail!!\n"); + goto fail; + } + } else { + WMT_PLAT_PR_ERR("[%s] can't find CONSYS compatible node\n", __func__); + goto fail; + } + + if (reg_info[index*4 + 3] < offset) { + WMT_PLAT_PR_ERR("Access overflow of address(0x%x), offset(0x%x)!\n", + reg_info[index*4 + 1], reg_info[index*4 + 3]); + goto fail; + } + + remap_addr = ioremap(reg_info[index*4 + 1] + offset, 0x4); + if (remap_addr == NULL) { + WMT_PLAT_PR_ERR("ioremap fail!\n"); + goto fail; + } + + if (is_write) + CONSYS_REG_WRITE(remap_addr, *value); + else + *value = CONSYS_REG_READ(remap_addr); + + if (remap_addr) + iounmap(remap_addr); + + iRet = 0; + +fail: + if (reg_info) + osal_free(reg_info); + return iRet; +} + +/* Who call this? + * - wmt_step + * - stp_dbg.c stp_dbg_poll_cpupcr + * - wmt_core + */ +INT32 mtk_consys_check_reg_readable(VOID) +{ + return mtk_consys_check_reg_readable_by_addr(0); +} + +INT32 mtk_consys_check_reg_readable_by_addr(SIZE_T addr) +{ + INT32 is_host_csr = 0; + + if (wmt_consys_ic_ops->consys_ic_is_host_csr) + is_host_csr = wmt_consys_ic_ops->consys_ic_is_host_csr(addr); + + if (wmt_consys_ic_ops->consys_ic_check_reg_readable && is_host_csr == 0) + return wmt_consys_ic_ops->consys_ic_check_reg_readable(); + else + return 1; +} + +VOID mtk_wcn_consys_clock_fail_dump(VOID) +{ + if (wmt_consys_ic_ops->consys_ic_clock_fail_dump) + wmt_consys_ic_ops->consys_ic_clock_fail_dump(); + WMT_STEP_DO_ACTIONS_FUNC(STEP_TRIGGER_POINT_WHEN_CLOCK_FAIL); +} + +INT32 mtk_consys_is_connsys_reg(UINT32 addr) +{ + if (wmt_consys_ic_ops->consys_ic_is_connsys_reg) + return wmt_consys_ic_ops->consys_ic_is_connsys_reg(addr); + else + return 0; +} + +VOID mtk_consys_set_mcif_mpu_protection(MTK_WCN_BOOL enable) +{ + if (wmt_consys_ic_ops->consys_ic_set_mcif_emi_mpu_protection) + wmt_consys_ic_ops->consys_ic_set_mcif_emi_mpu_protection(enable); +} + +INT32 mtk_consys_is_calibration_backup_restore_support(VOID) +{ + if (wmt_consys_ic_ops->consys_ic_calibration_backup_restore) + return wmt_consys_ic_ops->consys_ic_calibration_backup_restore(); + else + return 0; + +} + +VOID mtk_consys_set_chip_reset_status(INT32 status) +{ + chip_reset_status = status; +} + +INT32 mtk_consys_chip_reset_status(VOID) +{ + return chip_reset_status; +} + +INT32 mtk_consys_is_ant_swap_enable_by_hwid(VOID) +{ + if (wmt_consys_ic_ops->consys_ic_is_ant_swap_enable_by_hwid) + return wmt_consys_ic_ops->consys_ic_is_ant_swap_enable_by_hwid(wifi_ant_swap_gpio_pin_num); + else + return 0; +} + +INT32 mtk_consys_dump_osc_state(P_CONSYS_STATE state) +{ + if (wmt_consys_ic_ops->consys_ic_dump_osc_state) + return wmt_consys_ic_ops->consys_ic_dump_osc_state(state); + + return MTK_WCN_BOOL_FALSE; +} + +VOID mtk_wcn_consys_ic_get_ant_sel_cr_addr(PUINT32 default_invert_cr, PUINT32 default_invert_bit) +{ + if (wmt_consys_ic_ops->consys_ic_get_ant_sel_cr_addr) + wmt_consys_ic_ops->consys_ic_get_ant_sel_cr_addr(default_invert_cr, default_invert_bit); +} + +INT32 mtk_wcn_consys_dump_gating_state(P_CONSYS_STATE state) +{ + if (wmt_consys_ic_ops->consys_ic_dump_gating_state) + return wmt_consys_ic_ops->consys_ic_dump_gating_state(state); + + return MTK_WCN_BOOL_FALSE; +} + +UINT64 mtk_wcn_consys_get_options(VOID) +{ + if (wmt_consys_ic_ops->consys_ic_get_options) + return wmt_consys_ic_ops->consys_ic_get_options(); + + WMT_PLAT_PR_INFO("Please implement consys_ic_get_options!"); + wmt_lib_trigger_assert(WMTDRV_TYPE_WMT, 45); + return 0; +} diff --git a/drivers/misc/mediatek/connectivity/common/common_main/platform/wmt_plat_alps.c b/drivers/misc/mediatek/connectivity/common/common_main/platform/wmt_plat_alps.c new file mode 100644 index 0000000000000000000000000000000000000000..2ec5808b5ed75d4e7010f59e664d78a161727b5d --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/platform/wmt_plat_alps.c @@ -0,0 +1,1851 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + + + + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + + +#ifdef DFT_TAG +#undef DFT_TAG +#endif +#define DFT_TAG "[WMT-PLAT]" + +#include + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include + +/* ALPS header files */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0)) +#ifndef CONFIG_RTC_DRV_MT6397 +#include +#else +#include +#endif +#endif + +#ifdef CONFIG_MTK_MT6306_GPIO_SUPPORT +#include +#endif +/* ALPS and COMBO header files */ +#include +/* MTK_WCN_COMBO header files */ +#include "wmt_plat.h" +#include "wmt_dev.h" +#include "wmt_lib.h" +#include "mtk_wcn_cmb_hw.h" +#include "mtk_wcn_consys_hw.h" +#include "stp_dbg.h" +#include "osal.h" +#include "wmt_gpio.h" +#include "wmt_detect.h" +#include + +#include +#include +#include + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +#if CFG_WMT_PS_SUPPORT +static VOID wmt_plat_bgf_eirq_cb(VOID); +#endif +static INT32 wmt_plat_ldo_ctrl(ENUM_PIN_STATE state); +static INT32 wmt_plat_pmu_ctrl(ENUM_PIN_STATE state); +static INT32 wmt_plat_rtc_ctrl(ENUM_PIN_STATE state); +static INT32 wmt_plat_rst_ctrl(ENUM_PIN_STATE state); +static INT32 wmt_plat_bgf_eint_ctrl(ENUM_PIN_STATE state); +static INT32 wmt_plat_wifi_eint_ctrl(ENUM_PIN_STATE state); +static INT32 wmt_plat_all_eint_ctrl(ENUM_PIN_STATE state); +static INT32 wmt_plat_uart_ctrl(ENUM_PIN_STATE state); +static INT32 wmt_plat_pcm_ctrl(ENUM_PIN_STATE state); +static INT32 wmt_plat_i2s_ctrl(ENUM_PIN_STATE state); +static INT32 wmt_plat_sdio_pin_ctrl(ENUM_PIN_STATE state); +static INT32 wmt_plat_gps_sync_ctrl(ENUM_PIN_STATE state); +static INT32 wmt_plat_gps_lna_ctrl(ENUM_PIN_STATE state); +static INT32 wmt_plat_uart_rx_ctrl(ENUM_PIN_STATE state); +#if CFG_WMT_LTE_COEX_HANDLING +static INT32 wmt_plat_tdm_req_ctrl(ENUM_PIN_STATE state); +#endif +static INT32 wmt_plat_dump_pin_conf(VOID); + + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +INT32 gWmtMergeIfSupport; +UINT32 gCoClockFlag; +BGF_IRQ_BALANCE g_bgf_irq_lock; +INT32 wmtPlatLogLvl = WMT_PLAT_LOG_INFO; + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +static ENUM_STP_TX_IF_TYPE gCommIfType = STP_MAX_IF_TX; +static OSAL_SLEEPABLE_LOCK gOsSLock; +static OSAL_WAKE_LOCK wmt_wake_lock; + +irq_cb wmt_plat_bgf_irq_cb; +device_audio_if_cb wmt_plat_audio_if_cb; +func_ctrl_cb wmt_plat_func_ctrl_cb; +thermal_query_ctrl_cb wmt_plat_thermal_query_ctrl_cb; +trigger_assert_cb wmt_plat_trigger_assert_cb; +deep_idle_ctrl_cb wmt_plat_deep_idle_ctrl_cb; + +static const fp_set_pin gfp_set_pin_table[] = { + [PIN_LDO] = wmt_plat_ldo_ctrl, + [PIN_PMU] = wmt_plat_pmu_ctrl, + [PIN_RTC] = wmt_plat_rtc_ctrl, + [PIN_RST] = wmt_plat_rst_ctrl, + [PIN_BGF_EINT] = wmt_plat_bgf_eint_ctrl, + [PIN_WIFI_EINT] = wmt_plat_wifi_eint_ctrl, + [PIN_ALL_EINT] = wmt_plat_all_eint_ctrl, + [PIN_UART_GRP] = wmt_plat_uart_ctrl, + [PIN_PCM_GRP] = wmt_plat_pcm_ctrl, + [PIN_I2S_GRP] = wmt_plat_i2s_ctrl, + [PIN_SDIO_GRP] = wmt_plat_sdio_pin_ctrl, + [PIN_GPS_SYNC] = wmt_plat_gps_sync_ctrl, + [PIN_GPS_LNA] = wmt_plat_gps_lna_ctrl, + [PIN_UART_RX] = wmt_plat_uart_rx_ctrl, +#if CFG_WMT_LTE_COEX_HANDLING + [PIN_TDM_REQ] = wmt_plat_tdm_req_ctrl, +#endif +}; + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +/*! + * \brief audio control callback function for CMB_STUB on ALPS + * + * A platform function required for dynamic binding with CMB_STUB on ALPS. + * + * \param state desired audio interface state to use + * \param flag audio interface control options + * + * \retval 0 operation success + * \retval -1 invalid parameters + * \retval < 0 error for operation fail + */ +INT32 wmt_plat_audio_ctrl(enum CMB_STUB_AIF_X state, enum CMB_STUB_AIF_CTRL ctrl) +{ + INT32 iRet = 0; + UINT32 mergeIfSupport = 0; + + /* input sanity check */ + if ((state >= CMB_STUB_AIF_MAX) || (ctrl >= CMB_STUB_AIF_CTRL_MAX)) + return -1; + + iRet = 0; + + /* set host side first */ + switch (state) { + case CMB_STUB_AIF_0: + /* BT_PCM_OFF & FM line in/out */ + iRet += wmt_plat_gpio_ctrl(PIN_PCM_GRP, PIN_STA_DEINIT); + iRet += wmt_plat_gpio_ctrl(PIN_I2S_GRP, PIN_STA_DEINIT); + break; + + case CMB_STUB_AIF_1: + iRet += wmt_plat_gpio_ctrl(PIN_I2S_GRP, PIN_STA_DEINIT); + iRet += wmt_plat_gpio_ctrl(PIN_PCM_GRP, PIN_STA_INIT); + break; + + case CMB_STUB_AIF_2: + iRet += wmt_plat_gpio_ctrl(PIN_PCM_GRP, PIN_STA_DEINIT); + iRet += wmt_plat_gpio_ctrl(PIN_I2S_GRP, PIN_STA_INIT); + break; + + case CMB_STUB_AIF_3: + iRet += wmt_plat_gpio_ctrl(PIN_PCM_GRP, PIN_STA_INIT); + iRet += wmt_plat_gpio_ctrl(PIN_I2S_GRP, PIN_STA_INIT); + break; + + default: + /* FIXME: move to cust folder? */ + WMT_ERR_FUNC("invalid state [%d]\n", state); + return -1; + } + + if (wmt_plat_merge_if_flag_get() != 0) { +#if (MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT) + WMT_DBG_FUNC("[MT6628] no need to ctrl combo chip side GPIO\n"); +#else + mergeIfSupport = 1; +#endif + } else + mergeIfSupport = 1; + + if (mergeIfSupport != 0) { + if (ctrl == CMB_STUB_AIF_CTRL_EN) { + WMT_INFO_FUNC("call chip aif setting\n"); + /* need to control chip side GPIO */ + if (wmt_plat_audio_if_cb != NULL) + iRet += (*wmt_plat_audio_if_cb)(state, MTK_WCN_BOOL_FALSE); + else { + WMT_WARN_FUNC("wmt_plat_audio_if_cb is not registered\n"); + iRet -= 1; + } + + + } else + WMT_INFO_FUNC("skip chip aif setting\n"); + } + + return iRet; +} + +static VOID wmt_plat_func_ctrl(UINT32 type, UINT32 on) +{ + if (wmt_plat_func_ctrl_cb) + (*wmt_plat_func_ctrl_cb)(on, type); +} + +static long wmt_plat_thermal_ctrl(VOID) +{ + long temp = 0; + + if (wmt_plat_thermal_query_ctrl_cb) + temp = (*wmt_plat_thermal_query_ctrl_cb)(); + + return temp; +} + +static INT32 wmt_plat_assert_ctrl(VOID) +{ + INT32 ret = 0; + + if (wmt_plat_trigger_assert_cb) + ret = (*wmt_plat_trigger_assert_cb)(WMTDRV_TYPE_WMT, 45); + + return ret; +} + +static INT32 wmt_plat_deep_idle_ctrl(UINT32 dpilde_ctrl) +{ + INT32 iRet = -1; + + if (wmt_plat_deep_idle_ctrl_cb) + iRet = (*wmt_plat_deep_idle_ctrl_cb)(dpilde_ctrl); + + return iRet; +} + +static VOID wmt_plat_clock_fail_dump(VOID) +{ + mtk_wcn_consys_clock_fail_dump(); +} + +#if CFG_WMT_PS_SUPPORT +static VOID wmt_plat_bgf_eirq_cb(VOID) +{ +/* #error "need to disable EINT here" */ + /* wmt_lib_ps_irq_cb(); */ + if (wmt_plat_bgf_irq_cb != NULL) + (*(wmt_plat_bgf_irq_cb))(); + else + WMT_PLAT_PR_WARN("WMT-PLAT: wmt_plat_bgf_irq_cb not registered\n"); +} +#endif + +irqreturn_t wmt_plat_bgf_irq_isr(INT32 irq, PVOID arg) +{ +#if CFG_WMT_PS_SUPPORT + wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS); + wmt_plat_bgf_eirq_cb(); +#else + WMT_PLAT_PR_INFO("skip irq handing because psm is disable"); +#endif + + return IRQ_HANDLED; +} + +VOID wmt_plat_irq_cb_reg(irq_cb bgf_irq_cb) +{ + wmt_plat_bgf_irq_cb = bgf_irq_cb; +} + +VOID wmt_plat_aif_cb_reg(device_audio_if_cb aif_ctrl_cb) +{ + wmt_plat_audio_if_cb = aif_ctrl_cb; +} + +VOID wmt_plat_func_ctrl_cb_reg(func_ctrl_cb subsys_func_ctrl) +{ + wmt_plat_func_ctrl_cb = subsys_func_ctrl; +} + +VOID wmt_plat_thermal_ctrl_cb_reg(thermal_query_ctrl_cb thermal_query_ctrl) +{ + wmt_plat_thermal_query_ctrl_cb = thermal_query_ctrl; +} + +VOID wmt_plat_trigger_assert_cb_reg(trigger_assert_cb trigger_assert) +{ + wmt_plat_trigger_assert_cb = trigger_assert; +} + +VOID wmt_plat_deep_idle_ctrl_cb_reg(deep_idle_ctrl_cb deep_idle_ctrl) +{ + wmt_plat_deep_idle_ctrl_cb = deep_idle_ctrl; +} + +UINT32 wmt_plat_soc_co_clock_flag_get(VOID) +{ + return gCoClockFlag; +} + +static UINT32 wmt_plat_soc_co_clock_flag_set(UINT32 flag) +{ + gCoClockFlag = flag; + return 0; +} + +INT32 wmt_plat_init(P_PWR_SEQ_TIME pPwrSeqTime, UINT32 co_clock_type) +{ + struct _CMB_STUB_CB_ stub_cb; + INT32 iret = -1; + + if (wmt_detect_get_chip_type() == WMT_CHIP_TYPE_SOC) { + iret = mtk_wcn_consys_co_clock_type(); + if ((co_clock_type == 0) && (iret >= 0)) + co_clock_type = iret; + wmt_plat_soc_co_clock_flag_set(co_clock_type); + } + + stub_cb.aif_ctrl_cb = wmt_plat_audio_ctrl; + stub_cb.func_ctrl_cb = wmt_plat_func_ctrl; + stub_cb.thermal_query_cb = wmt_plat_thermal_ctrl; + stub_cb.trigger_assert_cb = wmt_plat_assert_ctrl; + stub_cb.deep_idle_ctrl_cb = wmt_plat_deep_idle_ctrl; + stub_cb.wmt_do_reset_cb = NULL; + stub_cb.clock_fail_dump_cb = wmt_plat_clock_fail_dump; + stub_cb.size = sizeof(stub_cb); + + /* register to cmb_stub */ + iret = mtk_wcn_cmb_stub_reg(&stub_cb); + + /*init wmt function ctrl wakelock if wake lock is supported by host platform */ + osal_strcpy(wmt_wake_lock.name, "wmtFuncCtrl"); + wmt_wake_lock.init_flag = 0; + osal_wake_lock_init(&wmt_wake_lock); + osal_sleepable_lock_init(&gOsSLock); + + /* init hw */ + if (wmt_detect_get_chip_type() == WMT_CHIP_TYPE_SOC) + iret += mtk_wcn_consys_hw_init(); + else + iret += mtk_wcn_cmb_hw_init(pPwrSeqTime); + + spin_lock_init(&g_bgf_irq_lock.lock); + + mtk_wcn_consys_detect_adie_chipid(co_clock_type); + + WMT_DBG_FUNC("WMT-PLAT: ALPS platform init (%d)\n", iret); + + return 0; +} + +INT32 wmt_plat_deinit(VOID) +{ + INT32 iret = 0; + + /* 1. de-init hw */ + if (wmt_detect_get_chip_type() == WMT_CHIP_TYPE_SOC) + iret += mtk_wcn_consys_hw_deinit(); + else + iret = mtk_wcn_cmb_hw_deinit(); + /* 2. unreg to cmb_stub */ + iret += mtk_wcn_cmb_stub_unreg(); + /*3. wmt wakelock deinit */ + osal_wake_lock_deinit(&wmt_wake_lock); + osal_sleepable_lock_deinit(&gOsSLock); + WMT_DBG_FUNC("destroy wmt_wake_lock\n"); + WMT_DBG_FUNC("WMT-PLAT: ALPS platform init (%d)\n", iret); + + return 0; +} + +INT32 wmt_plat_sdio_ctrl(WMT_SDIO_SLOT_NUM sdioPortType, ENUM_FUNC_STATE on) +{ + return board_sdio_ctrl(sdioPortType, (on == FUNC_OFF) ? 0 : 1); +} + +INT32 wmt_plat_irq_ctrl(ENUM_FUNC_STATE state) +{ + return -1; +} + +static INT32 wmt_plat_dump_pin_conf(VOID) +{ + WMT_DBG_FUNC("[WMT-PLAT]=>dump wmt pin configuration start<=\n"); + + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num != DEFAULT_PIN_ID) { + WMT_DBG_FUNC("LDO(GPIO%d)\n", + gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num); + } else + WMT_DBG_FUNC("LDO(not defined)\n"); + + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num != DEFAULT_PIN_ID) { + WMT_DBG_FUNC("PMU(GPIO%d)\n", + gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num); + } else + WMT_DBG_FUNC("PMU(not defined)\n"); + + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMUV28_EN_PIN].gpio_num != DEFAULT_PIN_ID) { + WMT_DBG_FUNC("PMUV28(GPIO%d)\n", + gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMUV28_EN_PIN].gpio_num); + } else + WMT_DBG_FUNC("PMUV28(not defined)\n"); + + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num != DEFAULT_PIN_ID) { + WMT_DBG_FUNC("RST(GPIO%d)\n", + gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num); + } else + WMT_DBG_FUNC("RST(not defined)\n"); + + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_BGF_EINT_PIN].gpio_num != DEFAULT_PIN_ID) { + WMT_DBG_FUNC("BGF_EINT(GPIO%d)\n", + gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_BGF_EINT_PIN].gpio_num); + } else + WMT_DBG_FUNC("BGF_EINT(not defined)\n"); + + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_BGF_EINT_PIN].gpio_num != DEFAULT_PIN_ID) { + WMT_DBG_FUNC("BGF_EINT_NUM(%d)\n", + gpio_to_irq(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_BGF_EINT_PIN].gpio_num)); + } else + WMT_DBG_FUNC("BGF_EINT_NUM(not defined)\n"); + + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num != DEFAULT_PIN_ID) { + WMT_DBG_FUNC("WIFI_EINT(GPIO%d)\n", + gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num); + } else + WMT_DBG_FUNC("WIFI_EINT(not defined)\n"); + + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num != DEFAULT_PIN_ID) { + WMT_DBG_FUNC("WIFI_EINT_NUM(%d)\n", + gpio_to_irq(gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num)); + } else + WMT_DBG_FUNC("WIFI_EINT_NUM(not defined)\n"); + + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_URXD_PIN].gpio_num != DEFAULT_PIN_ID) { + WMT_DBG_FUNC("UART_RX(GPIO%d)\n", + gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_URXD_PIN].gpio_num); + } else + WMT_DBG_FUNC("UART_RX(not defined)\n"); + + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_UTXD_PIN].gpio_num != DEFAULT_PIN_ID) { + WMT_DBG_FUNC("UART_TX(GPIO%d)\n", + gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_UTXD_PIN].gpio_num); + } else + WMT_DBG_FUNC("UART_TX(not defined)\n"); + + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAICLK_PIN].gpio_num != DEFAULT_PIN_ID) { + WMT_DBG_FUNC("DAICLK(GPIO%d)\n", + gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAICLK_PIN].gpio_num); + } else + WMT_DBG_FUNC("DAICLK(not defined)\n"); + + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAIPCMOUT_PIN].gpio_num != DEFAULT_PIN_ID) { + WMT_DBG_FUNC("PCMOUT(GPIO%d)\n", + gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAIPCMOUT_PIN].gpio_num); + } else + WMT_DBG_FUNC("PCMOUT(not defined)\n"); + + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAIPCMIN_PIN].gpio_num != DEFAULT_PIN_ID) { + WMT_DBG_FUNC("PCMIN(GPIO%d)\n", + gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAIPCMIN_PIN].gpio_num); + } else + WMT_DBG_FUNC("PCMIN(not defined)\n"); + + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAISYNC_PIN].gpio_num != DEFAULT_PIN_ID) { + WMT_DBG_FUNC("PCMSYNC(GPIO%d)\n", + gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAISYNC_PIN].gpio_num); + } else + WMT_DBG_FUNC("PCMSYNC(not defined)\n"); +#if defined(FM_DIGITAL_INPUT) || defined(FM_DIGITAL_OUTPUT) + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_I2S_CK_PIN].gpio_num != DEFAULT_PIN_ID) { + WMT_DBG_FUNC("I2S_CK(GPIO%d)\n", + gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_I2S_CK_PIN].gpio_num); + } else + WMT_DBG_FUNC("I2S_CK(not defined)\n"); + + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_I2S_WS_PIN].gpio_num != DEFAULT_PIN_ID) { + WMT_DBG_FUNC("I2S_WS(GPIO%d)\n", + gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_I2S_WS_PIN].gpio_num); + } else + WMT_DBG_FUNC("I2S_WS(not defined)\n"); + + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_I2S_DAT_PIN].gpio_num != DEFAULT_PIN_ID) { + WMT_DBG_FUNC("I2S_DAT(GPIO%d)\n", + gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_I2S_DAT_PIN].gpio_num); + } else + WMT_DBG_FUNC("I2S_DAT(not defined)\n"); + +#else /* FM_ANALOG_INPUT || FM_ANALOG_OUTPUT */ + WMT_DBG_FUNC("FM digital mode is not set, no need for I2S GPIOs\n"); +#endif + + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_GPS_SYNC_PIN].gpio_num != DEFAULT_PIN_ID) { + WMT_DBG_FUNC("GPS_SYNC(GPIO%d)\n", + gpio_ctrl_info.gpio_ctrl_state[GPIO_GPS_SYNC_PIN].gpio_num); + } else + WMT_DBG_FUNC("GPS_SYNC(not defined)\n"); + + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_GPS_LNA_PIN].gpio_num != DEFAULT_PIN_ID) { + WMT_DBG_FUNC("GPS_LNA(GPIO%d)\n", + gpio_ctrl_info.gpio_ctrl_state[GPIO_GPS_LNA_PIN].gpio_num); + } else + WMT_DBG_FUNC("GPS_LNA(not defined)\n"); + + WMT_DBG_FUNC("[WMT-PLAT]=>dump wmt pin configuration emds<=\n"); + + return 0; +} + +INT32 wmt_plat_pwr_ctrl(ENUM_FUNC_STATE state) +{ + INT32 ret = -1; + + switch (state) { + case FUNC_ON: + /* TODO:[ChangeFeature][George] always output this or by request throuth /proc or sysfs? */ + if (wmt_detect_get_chip_type() == WMT_CHIP_TYPE_SOC) + ret = mtk_wcn_consys_hw_pwr_on(gCoClockFlag); + else { + wmt_plat_dump_pin_conf(); + ret = mtk_wcn_cmb_hw_pwr_on(); + } + break; + + case FUNC_OFF: + if (wmt_detect_get_chip_type() == WMT_CHIP_TYPE_SOC) + ret = mtk_wcn_consys_hw_pwr_off(gCoClockFlag); + else + ret = mtk_wcn_cmb_hw_pwr_off(); + break; + + case FUNC_RST: + if (wmt_detect_get_chip_type() == WMT_CHIP_TYPE_SOC) + ret = mtk_wcn_consys_hw_rst(gCoClockFlag); + else + ret = mtk_wcn_cmb_hw_rst(); + break; + case FUNC_STAT: + if (wmt_detect_get_chip_type() == WMT_CHIP_TYPE_SOC) + ret = mtk_wcn_consys_hw_state_show(); + else + ret = mtk_wcn_cmb_hw_state_show(); + break; + default: + WMT_WARN_FUNC("WMT-PLAT:Warnning, invalid state(%d) in pwr_ctrl\n", state); + break; + } + + return ret; +} + +INT32 wmt_plat_ps_ctrl(ENUM_FUNC_STATE state) +{ + return -1; +} + +INT32 wmt_plat_eirq_ctrl(ENUM_PIN_ID id, ENUM_PIN_STATE state) +{ + INT32 iret; + static UINT32 bgf_irq_num = -1; + static UINT32 bgf_irq_flag; + + /* TODO: [ChangeFeature][GeorgeKuo]: use another function to handle this, as done in gpio_ctrls */ + + if ((state != PIN_STA_INIT) && (state != PIN_STA_DEINIT) && (state != PIN_STA_EINT_EN) + && (state != PIN_STA_EINT_DIS)) { + WMT_WARN_FUNC("WMT-PLAT:invalid PIN_STATE(%d) in eirq_ctrl for PIN(%d)\n", state, id); + return -1; + } + + iret = -2; + switch (id) { + case PIN_BGF_EINT: + if (state == PIN_STA_INIT) { + if (wmt_detect_get_chip_type() == WMT_CHIP_TYPE_SOC) { +#ifdef CONFIG_OF + iret = mtk_wcn_consys_read_irq_info_from_dts(&bgf_irq_num, &bgf_irq_flag); + if (iret) + return iret; +#else + bgf_irq_num = MT_CONN2AP_BTIF_WAKEUP_IRQ_ID; + bgf_irq_flag = IRQF_TRIGGER_LOW; +#endif + iret = request_irq(bgf_irq_num, wmt_plat_bgf_irq_isr, bgf_irq_flag, + "BTIF_WAKEUP_IRQ", NULL); + if (iret) { + WMT_PLAT_PR_ERR("request_irq fail,irq_no(%d),iret(%d)\n", + bgf_irq_num, iret); + return iret; + } else { + iret = enable_irq_wake(bgf_irq_num); + if (iret) + WMT_PLAT_PR_ERR("enable irq wake fail,irq_no(%d),iret(%d)\n", + bgf_irq_num, iret); + iret = 0; + } + } else { + struct device_node *node; + INT32 ret = -EINVAL; + + node = of_find_compatible_node(NULL, NULL, "mediatek,connectivity-combo"); + if (node) { + /*BGF-eint name maybe wrong*/ + bgf_irq_num = irq_of_parse_and_map(node, 1); + ret = request_irq(bgf_irq_num, wmt_plat_bgf_irq_isr, + IRQF_TRIGGER_LOW, "BGF-eint", NULL); + if (ret) + WMT_ERR_FUNC("BGF EINT IRQ LINE NOT AVAILABLE!!\n"); + else + WMT_INFO_FUNC("BGF EINT request_irq success!!\n"); + } else + WMT_ERR_FUNC("[%s] can't find BGF eint compatible node\n", + __func__); + } + g_bgf_irq_lock.counter = 1; + } else if (state == PIN_STA_EINT_EN) { + spin_lock_irqsave(&g_bgf_irq_lock.lock, g_bgf_irq_lock.flags); + if (g_bgf_irq_lock.counter) { + WMT_PLAT_PR_DBG("BGF INT has been enabled,counter(%d)\n", + g_bgf_irq_lock.counter); + } else { + enable_irq(bgf_irq_num); + g_bgf_irq_lock.counter++; + WMT_DBG_FUNC("WMT-PLAT:BGFInt (en)\n"); + } + spin_unlock_irqrestore(&g_bgf_irq_lock.lock, g_bgf_irq_lock.flags); + } else if (state == PIN_STA_EINT_DIS) { + spin_lock_irqsave(&g_bgf_irq_lock.lock, g_bgf_irq_lock.flags); + if (!g_bgf_irq_lock.counter) { + WMT_PLAT_PR_DBG("BGF INT has been disabled,counter(%d)\n", + g_bgf_irq_lock.counter); + } else { + disable_irq_nosync(bgf_irq_num); + g_bgf_irq_lock.counter--; + WMT_DBG_FUNC("WMT-PLAT:BGFInt (dis)\n"); + } + spin_unlock_irqrestore(&g_bgf_irq_lock.lock, g_bgf_irq_lock.flags); + } else { + free_irq(bgf_irq_num, NULL); + WMT_DBG_FUNC("WMT-PLAT:BGFInt (free)\n"); + /* de-init: nothing to do in ALPS, such as un-registration... */ + } + + iret = 0; + break; + case PIN_ALL_EINT: + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_ALL_EINT_PIN].gpio_num != DEFAULT_PIN_ID) { + if (state == PIN_STA_INIT) { + disable_irq_nosync(gpio_to_irq(gpio_ctrl_info. + gpio_ctrl_state[GPIO_COMBO_ALL_EINT_PIN].gpio_num)); + WMT_DBG_FUNC("WMT-PLAT:ALLInt (INIT but not used yet)\n"); + } else if (state == PIN_STA_EINT_EN) { + enable_irq(gpio_to_irq(gpio_ctrl_info. + gpio_ctrl_state[GPIO_COMBO_ALL_EINT_PIN].gpio_num)); + WMT_DBG_FUNC("WMT-PLAT:ALLInt (EN but not used yet)\n"); + } else if (state == PIN_STA_EINT_DIS) { + disable_irq_nosync(gpio_to_irq(gpio_ctrl_info. + gpio_ctrl_state[GPIO_COMBO_ALL_EINT_PIN].gpio_num)); + WMT_DBG_FUNC("WMT-PLAT:ALLInt (DIS but not used yet)\n"); + } else { + disable_irq_nosync(gpio_to_irq(gpio_ctrl_info. + gpio_ctrl_state[GPIO_COMBO_ALL_EINT_PIN].gpio_num)); + WMT_DBG_FUNC("WMT-PLAT:ALLInt (DEINIT but not used yet)\n"); + /* de-init: nothing to do in ALPS, such as un-registration... */ + } + } else + WMT_DBG_FUNC("WMT-PLAT:ALL EINT not defined\n"); + + iret = 0; + break; + + default: + WMT_WARN_FUNC("WMT-PLAT:unsupported EIRQ(PIN_ID:%d) in eirq_ctrl\n", id); + iret = -1; + break; + } + + return iret; +} + +INT32 wmt_plat_gpio_ctrl(ENUM_PIN_ID id, ENUM_PIN_STATE state) +{ + INT32 iret = -1; + + if ((id >= 0) && (id < PIN_ID_MAX) && (state < PIN_STA_MAX)) { + /* TODO: [FixMe][GeorgeKuo] do sanity check to const function table when init and skip checking here */ + if (gfp_set_pin_table[id]) + iret = (*(gfp_set_pin_table[id]))(state); /* .handler */ + else { + WMT_WARN_FUNC("WMT-PLAT: null fp for gpio_ctrl(%d)\n", id); + iret = -2; + } + } + + return iret; +} + +static INT32 wmt_plat_ldo_ctrl(ENUM_PIN_STATE state) +{ + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num == DEFAULT_PIN_ID) { + WMT_DBG_FUNC("WMT-PLAT:LDO is not used\n"); + return 0; + } + + switch (state) { + case PIN_STA_INIT: + /*set to gpio output low, disable pull */ + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, gpio_ctrl_info. + gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_state[GPIO_PULL_DIS]); + gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num, 0); + WMT_DBG_FUNC("WMT-PLAT:LDO init (out 0)\n"); + break; + case PIN_STA_OUT_H: + gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num, 1); + WMT_DBG_FUNC("WMT-PLAT:LDO (out 1)\n"); + break; + case PIN_STA_OUT_L: + gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num, 0); + WMT_DBG_FUNC("WMT-PLAT:LDO (out 0)\n"); + break; + case PIN_STA_IN_L: + case PIN_STA_DEINIT: + /*set to gpio input low, pull down enable */ + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, gpio_ctrl_info. + gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_state[GPIO_IN_PULLDOWN]); + WMT_DBG_FUNC("WMT-PLAT:LDO deinit (in pd)\n"); + break; + default: + WMT_WARN_FUNC("WMT-PLAT:Warnning, invalid state(%d) on LDO\n", state); + break; + } + + return 0; +} + +static INT32 wmt_plat_pmu_ctrl(ENUM_PIN_STATE state) +{ + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num == DEFAULT_PIN_ID) { + WMT_ERR_FUNC("WMT-PLAT:PMU not define\n"); + return -1; + } + + switch (state) { + case PIN_STA_INIT: + /*set to gpio output low, disable pull */ + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, + gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_state[GPIO_PULL_DIS]); + gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num, 0); + WMT_DBG_FUNC("WMT-PLAT:PMU init (out %d)\n", + gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num)); + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMUV28_EN_PIN].gpio_num != DEFAULT_PIN_ID) { + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, gpio_ctrl_info. + gpio_ctrl_state[GPIO_COMBO_PMUV28_EN_PIN].gpio_state[GPIO_PULL_DIS]); + gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMUV28_EN_PIN].gpio_num, + 0); + } + WMT_DBG_FUNC("WMT-PLAT:PMU init (out 0)\n"); + break; + + case PIN_STA_OUT_H: + gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num, 1); + WMT_DBG_FUNC("WMT-PLAT:PMU (out 1): %d\n", + gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num)); + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMUV28_EN_PIN].gpio_num != DEFAULT_PIN_ID) + gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMUV28_EN_PIN].gpio_num, + 1); + WMT_DBG_FUNC("WMT-PLAT:PMU (out 1)\n"); + break; + + case PIN_STA_OUT_L: + gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num, 0); + WMT_DBG_FUNC("WMT-PLAT:PMU (out 0): %d\n", + gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num)); + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMUV28_EN_PIN].gpio_num != DEFAULT_PIN_ID) + gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMUV28_EN_PIN].gpio_num, + 0); + WMT_DBG_FUNC("WMT-PLAT:PMU (out 0)\n"); + break; + + case PIN_STA_IN_L: + case PIN_STA_DEINIT: + /*set to gpio input low, pull down enable */ + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, gpio_ctrl_info. + gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_state[GPIO_IN_PULLDOWN]); + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMUV28_EN_PIN].gpio_num != DEFAULT_PIN_ID) + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, gpio_ctrl_info. + gpio_ctrl_state[GPIO_COMBO_PMUV28_EN_PIN].gpio_state[GPIO_IN_PULLDOWN]); + WMT_DBG_FUNC("WMT-PLAT:PMU deinit (in pd)\n"); + break; + case PIN_STA_SHOW: + WMT_INFO_FUNC("WMT-PLAT:PMU PIN_STA_SHOW start\n"); + WMT_INFO_FUNC("WMT-PLAT:PMU out(%d)\n", + gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMUV28_EN_PIN].gpio_num)); + WMT_INFO_FUNC("WMT-PLAT:PMU PIN_STA_SHOW end\n"); + break; + default: + WMT_WARN_FUNC("WMT-PLAT:Warnning, invalid state(%d) on PMU\n", state); + break; + } + + return 0; +} + +static INT32 wmt_plat_rtc_ctrl(ENUM_PIN_STATE state) +{ + switch (state) { + case PIN_STA_INIT: +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)) + rtc_gpio_enable_32k(RTC_GPIO_USER_GPS); + WMT_DBG_FUNC("WMT-PLAT:RTC init\n"); +#endif + break; + case PIN_STA_SHOW: + WMT_INFO_FUNC("WMT-PLAT:RTC PIN_STA_SHOW start\n"); + /* WMT_INFO_FUNC("WMT-PLAT:RTC Status(%d)\n", rtc_gpio_32k_status()); */ + WMT_INFO_FUNC("WMT-PLAT:RTC PIN_STA_SHOW end\n"); + break; + default: + WMT_WARN_FUNC("WMT-PLAT:Warnning, invalid state(%d) on RTC\n", state); + break; + } + + return 0; +} + +static INT32 wmt_plat_rst_ctrl(ENUM_PIN_STATE state) +{ + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num == DEFAULT_PIN_ID) { + WMT_ERR_FUNC("WMT-PLAT:RST not define\n"); + return -1; + } + + switch (state) { + case PIN_STA_INIT: + /*set to gpio output low, disable pull */ + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, + gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_state[GPIO_PULL_DIS]); + gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num, 0); + WMT_DBG_FUNC("WMT-PLAT:RST init (out 0)\n"); + break; + + case PIN_STA_OUT_H: + gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num, 1); + WMT_DBG_FUNC("WMT-PLAT:RST (out 1): %d\n", + gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num)); + break; + + case PIN_STA_OUT_L: + gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num, 0); + WMT_DBG_FUNC("WMT-PLAT:RST (out 0): %d\n", + gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num)); + break; + + case PIN_STA_IN_L: + case PIN_STA_DEINIT: + /*set to gpio input low, pull down enable */ + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, + gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_state[GPIO_IN_PULLDOWN]); + WMT_DBG_FUNC("WMT-PLAT:RST deinit (in pd)\n"); + break; + case PIN_STA_SHOW: + WMT_INFO_FUNC("WMT-PLAT:RST PIN_STA_SHOW start\n"); + WMT_INFO_FUNC("WMT-PLAT:RST out(%d)\n", + gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num)); + WMT_INFO_FUNC("WMT-PLAT:RST PIN_STA_SHOW end\n"); + break; + + default: + WMT_WARN_FUNC("WMT-PLAT:Warnning, invalid state(%d) on RST\n", state); + break; + } + + return 0; +} + +static INT32 wmt_plat_bgf_eint_ctrl(ENUM_PIN_STATE state) +{ + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_BGF_EINT_PIN].gpio_num == DEFAULT_PIN_ID) { + WMT_INFO_FUNC("WMT-PLAT:BGF EINT not defined\n"); + return 0; + } + + switch (state) { + case PIN_STA_INIT: + /*set to gpio input low, pull down enable */ + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, gpio_ctrl_info. + gpio_ctrl_state[GPIO_COMBO_BGF_EINT_PIN].gpio_state[GPIO_IN_PULLDOWN]); + WMT_DBG_FUNC("WMT-PLAT:BGFInt init(in pd)\n"); + break; + case PIN_STA_MUX: + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, gpio_ctrl_info. + gpio_ctrl_state[GPIO_COMBO_BGF_EINT_PIN].gpio_state[GPIO_IN_PULLUP]); + WMT_DBG_FUNC("WMT-PLAT:BGFInt mux (eint)\n"); + break; + case PIN_STA_IN_L: + case PIN_STA_DEINIT: + /*set to gpio input low, pull down enable */ + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, gpio_ctrl_info. + gpio_ctrl_state[GPIO_COMBO_BGF_EINT_PIN].gpio_state[GPIO_IN_PULLDOWN]); + WMT_DBG_FUNC("WMT-PLAT:BGFInt deinit(in pd)\n"); + break; + default: + WMT_WARN_FUNC("WMT-PLAT:Warnning, invalid state(%d) on BGF EINT\n", state); + break; + } + + return 0; +} + + +static INT32 wmt_plat_wifi_eint_ctrl(ENUM_PIN_STATE state) +{ +#if 0 /*def GPIO_WIFI_EINT_PIN */ + switch (state) { + case PIN_STA_INIT: + mt_set_gpio_pull_enable(GPIO_WIFI_EINT_PIN, GPIO_PULL_DISABLE); + mt_set_gpio_dir(GPIO_WIFI_EINT_PIN, GPIO_DIR_OUT); + mt_set_gpio_mode(GPIO_WIFI_EINT_PIN, GPIO_MODE_GPIO); + mt_set_gpio_out(GPIO_WIFI_EINT_PIN, GPIO_OUT_ONE); + break; + case PIN_STA_MUX: + mt_set_gpio_mode(GPIO_WIFI_EINT_PIN, GPIO_WIFI_EINT_PIN_M_GPIO); + mt_set_gpio_pull_enable(GPIO_WIFI_EINT_PIN, GPIO_PULL_ENABLE); + mt_set_gpio_pull_select(GPIO_WIFI_EINT_PIN, GPIO_PULL_UP); + mt_set_gpio_mode(GPIO_WIFI_EINT_PIN, GPIO_WIFI_EINT_PIN_M_EINT); + + break; + case PIN_STA_EINT_EN: + mt_eint_unmask(CUST_EINT_WIFI_NUM); + break; + case PIN_STA_EINT_DIS: + mt_eint_mask(CUST_EINT_WIFI_NUM); + break; + case PIN_STA_IN_L: + case PIN_STA_DEINIT: + /*set to gpio input low, pull down enable */ + mt_set_gpio_mode(GPIO_WIFI_EINT_PIN, GPIO_COMBO_BGF_EINT_PIN_M_GPIO); + mt_set_gpio_dir(GPIO_WIFI_EINT_PIN, GPIO_DIR_IN); + mt_set_gpio_pull_select(GPIO_WIFI_EINT_PIN, GPIO_PULL_DOWN); + mt_set_gpio_pull_enable(GPIO_WIFI_EINT_PIN, GPIO_PULL_ENABLE); + break; + default: + WMT_WARN_FUNC("WMT-PLAT:Warnning, invalid state(%d) on WIFI EINT\n", state); + break; + } +#else + WMT_INFO_FUNC("WMT-PLAT:WIFI EINT is controlled by MSDC driver\n"); +#endif + return 0; +} + + +static INT32 wmt_plat_all_eint_ctrl(ENUM_PIN_STATE state) +{ + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_ALL_EINT_PIN].gpio_num == DEFAULT_PIN_ID) { + WMT_DBG_FUNC("WMT-PLAT:ALL EINT not defined\n"); + return 0; + } + + switch (state) { + case PIN_STA_INIT: + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, gpio_ctrl_info. + gpio_ctrl_state[GPIO_COMBO_ALL_EINT_PIN].gpio_state[GPIO_IN_PULLDOWN]); + WMT_DBG_FUNC("WMT-PLAT:ALLInt init(in pd)\n"); + break; + case PIN_STA_MUX: + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, gpio_ctrl_info. + gpio_ctrl_state[GPIO_COMBO_ALL_EINT_PIN].gpio_state[GPIO_IN_PULLUP]); + break; + case PIN_STA_IN_L: + case PIN_STA_DEINIT: + /*set to gpio input low, pull down enable */ + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, gpio_ctrl_info. + gpio_ctrl_state[GPIO_COMBO_ALL_EINT_PIN].gpio_state[GPIO_IN_PULLDOWN]); + break; + default: + WMT_WARN_FUNC("WMT-PLAT:Warnning, invalid state(%d) on ALL EINT\n", state); + break; + } + + return 0; +} + +static INT32 wmt_plat_uart_ctrl(ENUM_PIN_STATE state) +{ + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_UTXD_PIN].gpio_num == DEFAULT_PIN_ID) { + WMT_DBG_FUNC("WMT-PLAT:UART TX not defined\n"); + return 0; + } + + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_URXD_PIN].gpio_num == DEFAULT_PIN_ID) { + WMT_DBG_FUNC("WMT-PLAT:UART RX not defined\n"); + return 0; + } + + switch (state) { + case PIN_STA_MUX: + case PIN_STA_INIT: + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, gpio_ctrl_info. + gpio_ctrl_state[GPIO_COMBO_URXD_PIN].gpio_state[GPIO_PULL_DIS]); + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, gpio_ctrl_info. + gpio_ctrl_state[GPIO_COMBO_UTXD_PIN].gpio_state[GPIO_PULL_DIS]); + WMT_DBG_FUNC("WMT-PLAT:UART init (mode_01, uart)\n"); + break; + case PIN_STA_IN_L: + case PIN_STA_DEINIT: + gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_URXD_PIN].gpio_num, 0); + gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_UTXD_PIN].gpio_num, 0); + WMT_DBG_FUNC("WMT-PLAT:UART deinit (out 0)\n"); + break; + case PIN_STA_IN_PU: + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, gpio_ctrl_info. + gpio_ctrl_state[GPIO_COMBO_URXD_PIN].gpio_state[GPIO_IN_PULLUP]); + break; + default: + WMT_WARN_FUNC("WMT-PLAT:Warnning, invalid state(%d) on UART Group\n", state); + break; + } + + return 0; +} + +static INT32 wmt_plat_pcm_ctrl(ENUM_PIN_STATE state) +{ + UINT32 normalPCMFlag = 0; + + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAICLK_PIN].gpio_num == DEFAULT_PIN_ID) { + WMT_INFO_FUNC("WMT-PLAT:PCM DAICLK not defined\n"); + return 0; + } + + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAIPCMOUT_PIN].gpio_num == DEFAULT_PIN_ID) { + WMT_INFO_FUNC("WMT-PLAT:PCM DAIPCMOUT not defined\n"); + return 0; + } + + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAIPCMIN_PIN].gpio_num == DEFAULT_PIN_ID) { + WMT_INFO_FUNC("WMT-PLAT:PCM DAIPCMIN not defined\n"); + return 0; + } + + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAISYNC_PIN].gpio_num == DEFAULT_PIN_ID) { + WMT_INFO_FUNC("WMT-PLAT:PCM DAISYNC not defined\n"); + return 0; + } + /*check if combo chip support merge if or not */ + if (wmt_plat_merge_if_flag_get() != 0) { +#if (MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT) + /* Hardware support Merge IF function */ + WMT_DBG_FUNC("WMT-PLAT:set to Merge PCM function\n"); + /*merge PCM function define */ + switch (state) { + case PIN_STA_MUX: + case PIN_STA_INIT: + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, gpio_ctrl_info. + gpio_ctrl_state[GPIO_PCM_DAICLK_PIN].gpio_state[GPIO_PULL_DIS]); + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, gpio_ctrl_info. + gpio_ctrl_state[GPIO_PCM_DAIPCMOUT_PIN].gpio_state[GPIO_PULL_DIS]); + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, gpio_ctrl_info. + gpio_ctrl_state[GPIO_PCM_DAIPCMIN_PIN].gpio_state[GPIO_PULL_DIS]); + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, gpio_ctrl_info. + gpio_ctrl_state[GPIO_PCM_DAISYNC_PIN].gpio_state[GPIO_PULL_DIS]); + WMT_DBG_FUNC("WMT-PLAT:PCM init (pcm)\n"); + break; + + case PIN_STA_IN_L: + case PIN_STA_DEINIT: + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, + gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAICLK_PIN].gpio_state[GPIO_PULL_DIS]); + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, gpio_ctrl_info. + gpio_ctrl_state[GPIO_PCM_DAIPCMOUT_PIN].gpio_state[GPIO_PULL_DIS]); + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, gpio_ctrl_info. + gpio_ctrl_state[GPIO_PCM_DAIPCMIN_PIN].gpio_state[GPIO_PULL_DIS]); + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, gpio_ctrl_info. + gpio_ctrl_state[GPIO_PCM_DAISYNC_PIN].gpio_state[GPIO_PULL_DIS]); + WMT_DBG_FUNC("WMT-PLAT:PCM deinit (out 0)\n"); + break; + + default: + WMT_WARN_FUNC + ("WMT-PLAT:Warnning, invalid state(%d) on PCM Group\n", + state); + break; + } + +#else + /* Hardware does not support Merge IF function */ + normalPCMFlag = 1; + WMT_DBG_FUNC("WMT-PLAT:set to normal PCM function\n"); +#endif + + } else { + normalPCMFlag = 1; + } + + if (normalPCMFlag != 0) { + /*normal PCM function define */ + switch (state) { + case PIN_STA_MUX: + case PIN_STA_INIT: + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, + gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAICLK_PIN].gpio_state[GPIO_PULL_DIS]); + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, gpio_ctrl_info. + gpio_ctrl_state[GPIO_PCM_DAIPCMOUT_PIN].gpio_state[GPIO_PULL_DIS]); + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, gpio_ctrl_info. + gpio_ctrl_state[GPIO_PCM_DAIPCMIN_PIN].gpio_state[GPIO_PULL_DIS]); + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, gpio_ctrl_info. + gpio_ctrl_state[GPIO_PCM_DAISYNC_PIN].gpio_state[GPIO_PULL_DIS]); + WMT_DBG_FUNC("WMT-PLAT:MT6589 PCM init (pcm)\n"); + break; + + case PIN_STA_IN_L: + case PIN_STA_DEINIT: + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, + gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAICLK_PIN].gpio_state[GPIO_PULL_DIS]); + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, gpio_ctrl_info. + gpio_ctrl_state[GPIO_PCM_DAIPCMOUT_PIN].gpio_state[GPIO_PULL_DIS]); + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, gpio_ctrl_info. + gpio_ctrl_state[GPIO_PCM_DAIPCMIN_PIN].gpio_state[GPIO_PULL_DIS]); + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, gpio_ctrl_info. + gpio_ctrl_state[GPIO_PCM_DAISYNC_PIN].gpio_state[GPIO_PULL_DIS]); + WMT_DBG_FUNC("WMT-PLAT:MT6589 PCM deinit (out 0)\n"); + break; + + default: + WMT_WARN_FUNC("WMT-PLAT:MT6589 Warnning, invalid state(%d) on PCM Group\n", + state); + break; + } + } + + return 0; +} + +static INT32 wmt_plat_cmb_i2s_ctrl(ENUM_PIN_STATE state) +{ + UINT32 normalI2SFlag = 0; + + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_I2S_CK_PIN].gpio_num == DEFAULT_PIN_ID) { + WMT_DBG_FUNC("WMT-PLAT:I2S CK not defined\n"); + return 0; + } + + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_I2S_WS_PIN].gpio_num == DEFAULT_PIN_ID) { + WMT_DBG_FUNC("WMT-PLAT:I2S WS not defined\n"); + return 0; + } + + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_I2S_DAT_PIN].gpio_num == DEFAULT_PIN_ID) { + WMT_DBG_FUNC("WMT-PLAT:DAT CK not defined\n"); + return 0; + } + /*check if combo chip support merge if or not */ + if (wmt_plat_merge_if_flag_get() != 0) { +#if (MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT) + /* Hardware support Merge IF function */ +#if defined(FM_DIGITAL_INPUT) || defined(FM_DIGITAL_OUTPUT) + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_I2S_CK_PIN].gpio_num != DEFAULT_PIN_ID) { + switch (state) { + case PIN_STA_INIT: + case PIN_STA_MUX: + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, gpio_ctrl_info. + gpio_ctrl_state[GPIO_COMBO_I2S_CK_PIN].gpio_state[GPIO_PULL_DIS]); + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, gpio_ctrl_info. + gpio_ctrl_state[GPIO_COMBO_I2S_WS_PIN].gpio_state[GPIO_PULL_DIS]); + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, gpio_ctrl_info. + gpio_ctrl_state[GPIO_COMBO_I2S_DAT_PIN].gpio_state[GPIO_PULL_DIS]); + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, gpio_ctrl_info. + gpio_ctrl_state[GPIO_COMBO_PCM_DAIPMCOUT_PIN]. + gpio_state[GPIO_PULL_DIS]); + WMT_DBG_FUNC("WMT-PLAT:I2S init (I2S0 system)\n"); + break; + case PIN_STA_IN_L: + case PIN_STA_DEINIT: + gpio_direction_output(gpio_ctrl_info. + gpio_ctrl_state[GPIO_COMBO_I2S_CK_PIN].gpio_num, 0); + gpio_direction_output(gpio_ctrl_info. + gpio_ctrl_state[GPIO_COMBO_I2S_WS_PIN].gpio_num, 0); + gpio_direction_output(gpio_ctrl_info. + gpio_ctrl_state[GPIO_COMBO_I2S_DAT_PIN].gpio_num, 0); + WMT_DBG_FUNC("WMT-PLAT:I2S deinit (out 0)\n"); + break; + default: + WMT_WARN_FUNC("WMT-PLAT:Warnning, invalid state(%d) on I2S Group\n", + state); + break; + } + } else + WMT_ERR_FUNC("[MT662x]Error:FM digital mode set, no I2S GPIOs defined\n"); +#else + WMT_INFO_FUNC("[MT662x]warnning:FM digital mode is not set\n"); + WMT_INFO_FUNC("no I2S GPIO settings should be modified by combo driver\n"); +#endif +#else + /* Hardware does support Merge IF function */ + normalI2SFlag = 1; +#endif + } else + normalI2SFlag = 1; + + if (normalI2SFlag != 0) { +#if defined(FM_DIGITAL_INPUT) || defined(FM_DIGITAL_OUTPUT) + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_I2S_CK_PIN].gpio_num != DEFAULT_PIN_ID) { + switch (state) { + case PIN_STA_INIT: + case PIN_STA_MUX: + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, gpio_ctrl_info. + gpio_ctrl_state[GPIO_COMBO_I2S_CK_PIN].gpio_state[GPIO_PULL_DIS]); + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, gpio_ctrl_info. + gpio_ctrl_state[GPIO_COMBO_I2S_WS_PIN].gpio_state[GPIO_PULL_DIS]); + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, gpio_ctrl_info. + gpio_ctrl_state[GPIO_COMBO_I2S_DAT_PIN].gpio_state[GPIO_PULL_DIS]); + WMT_DBG_FUNC("WMT-PLAT:I2S init (I2S0 system)\n"); + break; + case PIN_STA_IN_L: + case PIN_STA_DEINIT: + gpio_direction_output(gpio_ctrl_info. + gpio_ctrl_state[GPIO_COMBO_I2S_CK_PIN].gpio_num, 0); + gpio_direction_output(gpio_ctrl_info. + gpio_ctrl_state[GPIO_COMBO_I2S_WS_PIN].gpio_num, 0); + gpio_direction_output(gpio_ctrl_info. + gpio_ctrl_state[GPIO_COMBO_I2S_DAT_PIN].gpio_num, 0); + WMT_DBG_FUNC("WMT-PLAT:I2S deinit (out 0)\n"); + break; + default: + WMT_WARN_FUNC("WMT-PLAT:Warnning, invalid state(%d) on I2S Group\n", + state); + break; + } + } else + WMT_ERR_FUNC("[MT662x]Error:FM digital mode set, but no I2S GPIOs defined\n"); +#else + WMT_INFO_FUNC("[MT662x]warnning:FM digital mode is not set\n"); + WMT_INFO_FUNC("no I2S GPIO settings should be modified by combo driver\n"); +#endif + } + + return 0; +} + +static INT32 wmt_plat_soc_i2s_ctrl(ENUM_PIN_STATE state) +{ + WMT_PLAT_PR_WARN("host i2s pin not defined!!!\n"); + + return 0; +} + +static INT32 wmt_plat_i2s_ctrl(ENUM_PIN_STATE state) +{ + INT32 ret = -1; + + if (wmt_detect_get_chip_type() == WMT_CHIP_TYPE_SOC) + ret = wmt_plat_soc_i2s_ctrl(state); + else + ret = wmt_plat_cmb_i2s_ctrl(state); + + return ret; +} + +static INT32 wmt_plat_sdio_pin_ctrl(ENUM_PIN_STATE state) +{ + return 0; +} + +static INT32 wmt_plat_cmb_gps_sync_ctrl(ENUM_PIN_STATE state) +{ + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_GPS_SYNC_PIN].gpio_num == DEFAULT_PIN_ID) { + WMT_INFO_FUNC("WMT-PLAT:GPS SYNC not defined\n"); + return 0; + } + + switch (state) { + case PIN_STA_INIT: + case PIN_STA_DEINIT: + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, + gpio_ctrl_info.gpio_ctrl_state[GPIO_GPS_SYNC_PIN].gpio_state[GPIO_PULL_DIS]); + gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[GPIO_GPS_SYNC_PIN].gpio_num, 0); + break; + case PIN_STA_MUX: + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, + gpio_ctrl_info.gpio_ctrl_state[GPIO_GPS_SYNC_PIN].gpio_state[GPIO_PULL_DIS]); + break; + default: + break; + } + + return 0; +} + +static INT32 wmt_plat_soc_gps_sync_ctrl(ENUM_PIN_STATE state) +{ + WMT_PLAT_PR_WARN("host gps sync pin not defined!!!\n"); + + return 0; +} + +static INT32 wmt_plat_gps_sync_ctrl(ENUM_PIN_STATE state) +{ + INT32 ret = -1; + + if (wmt_detect_get_chip_type() == WMT_CHIP_TYPE_SOC) + ret = wmt_plat_soc_gps_sync_ctrl(state); + else + ret = wmt_plat_cmb_gps_sync_ctrl(state); + + return ret; +} + +static INT32 wmt_plat_soc_gps_lna_ctrl(ENUM_PIN_STATE state) +{ +#ifdef CONFIG_MTK_MT6306_GPIO_SUPPORT + switch (state) { + case PIN_STA_INIT: + case PIN_STA_DEINIT: + KERNEL_mt6306_set_gpio_dir(MT6306_GPIO_01, MT6306_GPIO_DIR_OUT); + KERNEL_mt6306_set_gpio_out(MT6306_GPIO_01, MT6306_GPIO_OUT_LOW); + WMT_PLAT_PR_DBG("set gps lna to init\n"); + break; + case PIN_STA_OUT_H: + KERNEL_mt6306_set_gpio_out(MT6306_GPIO_01, MT6306_GPIO_OUT_HIGH); + WMT_PLAT_PR_DBG("set gps lna to oh\n"); + break; + case PIN_STA_OUT_L: + KERNEL_mt6306_set_gpio_out(MT6306_GPIO_01, MT6306_GPIO_OUT_LOW); + WMT_PLAT_PR_DBG("set gps lna to ol\n"); + break; + default: + WMT_PLAT_PR_WARN("%d mode not defined for gps lna pin !!!\n", state); + break; + } +#else + struct pinctrl_state *gps_lna_init = NULL; + struct pinctrl_state *gps_lna_oh = NULL; + struct pinctrl_state *gps_lna_ol = NULL; + struct pinctrl *consys_pinctrl = NULL; + + WMT_PLAT_PR_DBG("ENTER++\n"); + consys_pinctrl = mtk_wcn_consys_get_pinctrl(); + if (!consys_pinctrl) { + WMT_PLAT_PR_ERR("get consys pinctrl fail\n"); + return 0; + } + + gps_lna_init = pinctrl_lookup_state(consys_pinctrl, "gps_lna_state_init"); + if (IS_ERR(gps_lna_init)) { + WMT_PLAT_PR_ERR("Cannot find gps lna pin init state!\n"); + return 0; + } + + gps_lna_oh = pinctrl_lookup_state(consys_pinctrl, "gps_lna_state_oh"); + if (IS_ERR(gps_lna_oh)) { + WMT_PLAT_PR_ERR("Cannot find gps lna pin oh state!\n"); + return 0; + } + + gps_lna_ol = pinctrl_lookup_state(consys_pinctrl, "gps_lna_state_ol"); + if (IS_ERR(gps_lna_ol)) { + WMT_PLAT_PR_ERR("Cannot find gps lna pin ol state!\n"); + return 0; + } + + switch (state) { + case PIN_STA_INIT: + case PIN_STA_DEINIT: + pinctrl_select_state(consys_pinctrl, gps_lna_init); + WMT_PLAT_PR_DBG("set gps lna to init\n"); + break; + case PIN_STA_OUT_H: + pinctrl_select_state(consys_pinctrl, gps_lna_oh); + WMT_PLAT_PR_DBG("set gps lna to oh\n"); + break; + case PIN_STA_OUT_L: + pinctrl_select_state(consys_pinctrl, gps_lna_ol); + WMT_PLAT_PR_DBG("set gps lna to ol\n"); + break; + default: + WMT_PLAT_PR_WARN("%d mode not defined for gps lna pin !!!\n", state); + break; + } +#endif + + return 0; +} + +static INT32 wmt_plat_cmb_gps_lna_ctrl(ENUM_PIN_STATE state) +{ + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_GPS_LNA_PIN].gpio_num != DEFAULT_PIN_ID) { + switch (state) { + case PIN_STA_INIT: + case PIN_STA_DEINIT: + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, + gpio_ctrl_info.gpio_ctrl_state[GPIO_GPS_LNA_PIN].gpio_state[GPIO_PULL_DIS]); + gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[GPIO_GPS_LNA_PIN].gpio_num, 0); + break; + case PIN_STA_OUT_H: + gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[GPIO_GPS_LNA_PIN].gpio_num, 1); + break; + case PIN_STA_OUT_L: + gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[GPIO_GPS_LNA_PIN].gpio_num, 0); + break; + default: + WMT_WARN_FUNC("%d mode not defined for gps lna pin !!!\n", state); + break; + } + } else { +#ifdef CONFIG_MTK_MT6306_GPIO_SUPPORT + WMT_WARN_FUNC("/******************************************************************/\n"); + WMT_WARN_FUNC("use MT6306 GPIO7 for gps lna pin.\n this HARD CODE may hurt other\n"); + WMT_WARN_FUNC("system module, if GPIO7 of MT6306 is not defined as GPS_LNA function\n"); + WMT_WARN_FUNC("/******************************************************************/\n"); + + switch (state) { + case PIN_STA_INIT: + case PIN_STA_DEINIT: + /* KERNEL_mt6306_set_gpio_dir(GPIO7, GPIO_DIR_OUT); */ + /* KERNEL_mt6306_set_gpio_out(GPIO7, GPIO_OUT_ZERO); */ + break; + case PIN_STA_OUT_H: + /* KERNEL_mt6306_set_gpio_out(GPIO7, GPIO_OUT_ONE); */ + break; + case PIN_STA_OUT_L: + /* KERNEL_mt6306_set_gpio_out(GPIO7, GPIO_OUT_ZERO); */ + break; + default: + WMT_WARN_FUNC("%d mode not defined for gps lna pin !!!\n", state); + break; + } +#else + WMT_WARN_FUNC("host gps lna pin not defined!!!\n"); + WMT_WARN_FUNC("if you donot use eighter AP or MT6306's pin as GPS_LNA\n"); + WMT_WARN_FUNC("please customize your own GPS_LNA related code here\n"); +#endif + } + + return 0; +} + +static INT32 wmt_plat_gps_lna_ctrl(ENUM_PIN_STATE state) +{ + INT32 ret = -1; + + if (wmt_detect_get_chip_type() == WMT_CHIP_TYPE_SOC) + ret = wmt_plat_soc_gps_lna_ctrl(state); + else + ret = wmt_plat_cmb_gps_lna_ctrl(state); + + return ret; +} + +static INT32 wmt_plat_uart_rx_ctrl(ENUM_PIN_STATE state) +{ + if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_URXD_PIN].gpio_num == DEFAULT_PIN_ID) { + WMT_DBG_FUNC("WMT-PLAT:UART RX not defined\n"); + return 0; + } + + switch (state) { + case PIN_STA_MUX: + case PIN_STA_INIT: + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, + gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_URXD_PIN].gpio_state[GPIO_PULL_DIS]); + WMT_DBG_FUNC("WMT-PLAT:UART Rx init\n"); + break; + case PIN_STA_IN_L: + case PIN_STA_DEINIT: + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, + gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_URXD_PIN].gpio_state[GPIO_PULL_DIS]); + gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_URXD_PIN].gpio_num, 0); + WMT_DBG_FUNC("WMT-PLAT:UART Rx deinit (out 0)\n"); + break; + case PIN_STA_IN_NP: + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, + gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_URXD_PIN].gpio_state[GPIO_IN_PULL_DIS]); + WMT_DBG_FUNC("WMT-PLAT:UART Rx input pull none\n"); + break; + case PIN_STA_IN_H: + pinctrl_select_state(gpio_ctrl_info.pinctrl_info, + gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_URXD_PIN].gpio_state[GPIO_IN_PULLUP]); + WMT_DBG_FUNC("WMT-PLAT:UART Rx input pull high\n"); + break; + case PIN_STA_OUT_H: + gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_URXD_PIN].gpio_num, 1); + WMT_DBG_FUNC("WMT-PLAT:UART Rx output high\n"); + break; + case PIN_STA_OUT_L: + gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_URXD_PIN].gpio_num, 0); + WMT_DBG_FUNC("WMT-PLAT:UART Rx deinit (out 0)\n"); + break; + default: + WMT_WARN_FUNC("WMT-PLAT:Warnning, invalid state(%d) on UART Rx\n", state); + break; + } + + return 0; +} + +#if CFG_WMT_LTE_COEX_HANDLING +static INT32 wmt_plat_tdm_req_ctrl(ENUM_PIN_STATE state) +{ + return 0; +} +#endif + +INT32 wmt_plat_wake_lock_ctrl(ENUM_WL_OP opId) +{ + static INT32 counter; + INT32 ret = 0; + + ret = osal_lock_sleepable_lock(&gOsSLock); + if (ret) { + WMT_ERR_FUNC("--->lock gOsSLock failed, ret=%d\n", ret); + return ret; + } + + if (opId == WL_OP_GET) + ++counter; + else if (opId == WL_OP_PUT) + --counter; + + osal_unlock_sleepable_lock(&gOsSLock); + if (opId == WL_OP_GET && counter == 1) { + osal_wake_lock(&wmt_wake_lock); + WMT_DBG_FUNC("WMT-PLAT: after wake_lock(%d), counter(%d)\n", + osal_wake_lock_count(&wmt_wake_lock), counter); + + } else if (opId == WL_OP_PUT && counter == 0) { + osal_wake_unlock(&wmt_wake_lock); + WMT_DBG_FUNC("WMT-PLAT: after wake_unlock(%d), counter(%d)\n", + osal_wake_lock_count(&wmt_wake_lock), counter); + } else { + WMT_WARN_FUNC("WMT-PLAT: wakelock status(%d), counter(%d)\n", + osal_wake_lock_count(&wmt_wake_lock), counter); + } + + return 0; +} + + +INT32 wmt_plat_merge_if_flag_ctrl(UINT32 enable) +{ + if (enable) { +#if (MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT) + gWmtMergeIfSupport = 1; +#else + gWmtMergeIfSupport = 0; + WMT_WARN_FUNC("neither MT6589, MTK_MERGE_INTERFACE_SUPPORT nor MT6628 is not set to 1\n"); + WMT_WARN_FUNC("so set gWmtMergeIfSupport to %d\n", gWmtMergeIfSupport); +#endif + } else + gWmtMergeIfSupport = 0; + + WMT_INFO_FUNC("set gWmtMergeIfSupport to %d\n", gWmtMergeIfSupport); + + return gWmtMergeIfSupport; +} + +INT32 wmt_plat_merge_if_flag_get(VOID) +{ + return gWmtMergeIfSupport; +} + +INT32 wmt_plat_set_comm_if_type(ENUM_STP_TX_IF_TYPE type) +{ + gCommIfType = type; + + return 0; +} + +ENUM_STP_TX_IF_TYPE wmt_plat_get_comm_if_type(VOID) +{ + return gCommIfType; +} + +INT32 wmt_plat_soc_paldo_ctrl(ENUM_PALDO_TYPE ePt, ENUM_PALDO_OP ePo) +{ + INT32 iRet = 0; + + switch (ePt) { + case BT_PALDO: + iRet = mtk_wcn_consys_hw_bt_paldo_ctrl(ePo); + break; + case WIFI_PALDO: + iRet = mtk_wcn_consys_hw_wifi_paldo_ctrl(ePo); + break; + case FM_PALDO: + case GPS_PALDO: + iRet = mtk_wcn_consys_hw_vcn28_ctrl(ePo); + break; + case EFUSE_PALDO: + iRet = mtk_wcn_consys_hw_efuse_paldo_ctrl(ePo, wmt_plat_soc_co_clock_flag_get()); + break; + default: + WMT_PLAT_PR_WARN("WMT-PLAT:Warnning, invalid type(%d) in palod_ctrl\n", ePt); + break; + } + + return iRet; +} + +#if CONSYS_WMT_REG_SUSPEND_CB_ENABLE +UINT32 wmt_plat_soc_osc_en_ctrl(UINT32 en) +{ + return mtk_wcn_consys_hw_osc_en_ctrl(en); +} +#endif + +UINT8 *wmt_plat_get_emi_virt_add(UINT32 offset) +{ + return mtk_wcn_consys_emi_virt_addr_get(offset); +} + +P_CONSYS_EMI_ADDR_INFO wmt_plat_get_emi_phy_add(VOID) +{ + return mtk_wcn_consys_soc_get_emi_phy_add(); +} + +#if CONSYS_ENALBE_SET_JTAG +UINT32 wmt_plat_jtag_flag_ctrl(UINT32 en) +{ + return mtk_wcn_consys_jtag_flag_ctrl(en); +} +#endif + +#if CFG_WMT_DUMP_INT_STATUS +VOID wmt_plat_BGF_irq_dump_status(VOID) +{ + mt_irq_dump_status(269);/*tag3 wujun rainier is enabled */ + + WMT_PLAT_PR_INFO("this function is null in MT6735\n"); +} + +MTK_WCN_BOOL wmt_plat_dump_BGF_irq_status(VOID) +{ + return MTK_WCN_BOOL_FALSE;/*tag4 wujun rainier is enabled */ +} +#endif + +UINT32 wmt_plat_read_cpupcr(VOID) +{ + return mtk_wcn_consys_read_cpupcr(); +} +EXPORT_SYMBOL(wmt_plat_read_cpupcr); + +UINT32 wmt_plat_read_dmaregs(UINT32 type) +{ + return 0; +#if 0 + switch (type) { + case CONNSYS_CLK_GATE_STATUS: + return CONSYS_REG_READ(CONNSYS_CLK_GATE_STATUS_REG); + case CONSYS_EMI_STATUS: + return CONSYS_REG_READ(CONSYS_EMI_STATUS_REG); + case SYSRAM1: + return CONSYS_REG_READ(SYSRAM1_REG); + case SYSRAM2: + return CONSYS_REG_READ(SYSRAM2_REG); + case SYSRAM3: + return CONSYS_REG_READ(SYSRAM3_REG); + default: + return 0; + } +#endif +} + +INT32 wmt_plat_set_host_dump_state(ENUM_HOST_DUMP_STATE state) +{ + PUINT8 p_virtual_addr = NULL; + + p_virtual_addr = wmt_plat_get_emi_virt_add(EXP_APMEM_CTRL_HOST_SYNC_STATE); + if (!p_virtual_addr) { + WMT_PLAT_PR_ERR("get virtual address fail\n"); + return -1; + } + + CONSYS_REG_WRITE(p_virtual_addr, state); + + return 0; +} + +UINT32 wmt_plat_force_trigger_assert(ENUM_FORCE_TRG_ASSERT_T type) +{ + PUINT8 p_virtual_addr = NULL; + + switch (type) { + case STP_FORCE_TRG_ASSERT_EMI: + + WMT_PLAT_PR_INFO("[Force Assert] stp_trigger_firmware_assert_via_emi -->\n"); + p_virtual_addr = wmt_plat_get_emi_virt_add(EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1); + if (!p_virtual_addr) { + WMT_PLAT_PR_ERR("get virtual address fail\n"); + return -1; + } + + CONSYS_REG_WRITE(p_virtual_addr, EXP_APMEM_HOST_OUTBAND_ASSERT_MAGIC_W1); + WMT_PLAT_PR_INFO("[Force Assert] stp_trigger_firmware_assert_via_emi <--\n"); + break; + case STP_FORCE_TRG_ASSERT_DEBUG_PIN: + mtk_wcn_force_trigger_assert_debug_pin(); + break; + default: + WMT_PLAT_PR_ERR("unknown force trigger assert type\n"); + break; + } + + return 0; +} + +INT32 wmt_plat_update_host_sync_num(VOID) +{ + PUINT8 p_virtual_addr = NULL; + UINT32 sync_num = 0; + + p_virtual_addr = wmt_plat_get_emi_virt_add(EXP_APMEM_CTRL_HOST_SYNC_NUM); + if (!p_virtual_addr) { + WMT_PLAT_PR_ERR("get virtual address fail\n"); + return -1; + } + + sync_num = CONSYS_REG_READ(p_virtual_addr); + CONSYS_REG_WRITE(p_virtual_addr, sync_num + 1); + + return 0; +} + +INT32 wmt_plat_get_dump_info(UINT32 offset) +{ + PUINT8 p_virtual_addr = NULL; + + p_virtual_addr = wmt_plat_get_emi_virt_add(offset); + if (!p_virtual_addr) { + WMT_PLAT_PR_ERR("get virtual address fail\n"); + return -1; + } + WMT_PLAT_PR_DBG("connsys_reg_read (0x%x), (0x%p), (0x%x)\n", CONSYS_REG_READ(p_virtual_addr), p_virtual_addr, + offset); + return CONSYS_REG_READ(p_virtual_addr); +} + +INT32 wmt_plat_write_emi_l(UINT32 offset, UINT32 value) +{ + PUINT8 p_virtual_addr = NULL; + + p_virtual_addr = wmt_plat_get_emi_virt_add(offset); + if (!p_virtual_addr) { + WMT_PLAT_PR_ERR("get virtual address fail\n"); + return -1; + } + + CONSYS_REG_WRITE(p_virtual_addr, value); + return 0; +} + +UINT32 wmt_plat_get_soc_chipid(VOID) +{ + UINT32 chipId = mtk_wcn_consys_soc_chipid(); + + return chipId; +} +EXPORT_SYMBOL(wmt_plat_get_soc_chipid); + +INT32 wmt_plat_get_adie_chipid(VOID) +{ + return mtk_wcn_consys_detect_adie_chipid(gCoClockFlag); +} + +#if CFG_WMT_LTE_COEX_HANDLING +INT32 wmt_plat_get_tdm_antsel_index(VOID) +{ + WMT_PLAT_PR_INFO("not support LTE in this platform\n"); + return 0; +} +#endif + +INT32 wmt_plat_set_dbg_mode(UINT32 flag) +{ + INT32 ret = -1; + PUINT8 vir_addr = NULL; + + vir_addr = mtk_wcn_consys_emi_virt_addr_get(EXP_APMEM_CTRL_CHIP_FW_DBGLOG_MODE); + if (!vir_addr) { + WMT_PLAT_PR_ERR("get vir address fail\n"); + return ret; + } + if (flag) { + CONSYS_REG_WRITE(vir_addr, 0x1); + ret = 0; + } else { + CONSYS_REG_WRITE(vir_addr, 0x0); + ret = 1; + } + WMT_PLAT_PR_INFO("fw dbg mode register value(0x%08x)\n", CONSYS_REG_READ(vir_addr)); + + return ret; +} + +INT32 wmt_plat_set_dynamic_dumpmem(PUINT32 str_buf) +{ + PUINT8 vir_addr = NULL; + + vir_addr = mtk_wcn_consys_emi_virt_addr_get(EXP_APMEM_CTRL_CHIP_DYNAMIC_DUMP); + if (!vir_addr) { + WMT_PLAT_PR_ERR("get vir address fail\n"); + return -1; + } + memcpy(vir_addr, str_buf, DYNAMIC_DUMP_GROUP_NUM*8); + WMT_PLAT_PR_INFO("dynamic dump register value(0x%08x)\n", CONSYS_REG_READ(vir_addr)); + + return 0; +} diff --git a/drivers/misc/mediatek/connectivity/common/common_main/platform/wmt_plat_stub.c b/drivers/misc/mediatek/connectivity/common/common_main/platform/wmt_plat_stub.c new file mode 100644 index 0000000000000000000000000000000000000000..09547b390b78c1c76b62c75463a9f65b9699fe2c --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/common_main/platform/wmt_plat_stub.c @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + + + + + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + + +#ifdef DFT_TAG +#undef DFT_TAG +#endif +#define DFT_TAG "[WMT-PLAT]" + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/* ALPS and COMBO header files */ +#include + +/* MTK_WCN_COMBO header files */ +#include "wmt_plat.h" +#include "wmt_plat_stub.h" +#include "wmt_exp.h" +#include "wmt_lib.h" +#include "osal.h" + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + + + + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +static VOID wmt_plat_func_ctrl(UINT32 type, UINT32 on); + + + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +static void wmt_plat_func_ctrl(unsigned int type, unsigned int on) +{ + if (on) + mtk_wcn_wmt_func_on((ENUM_WMTDRV_TYPE_T) type); + else + mtk_wcn_wmt_func_off((ENUM_WMTDRV_TYPE_T) type); +} + +static signed long wmt_plat_thremal_query(void) +{ + return wmt_lib_tm_temp_query(); +} + +INT32 wmt_plat_stub_init(VOID) +{ + INT32 iRet = -1; + struct _CMB_STUB_CB_ stub_cb = {0}; + + stub_cb.aif_ctrl_cb = wmt_plat_audio_ctrl; + stub_cb.func_ctrl_cb = wmt_plat_func_ctrl; + stub_cb.thermal_query_cb = wmt_plat_thremal_query; + stub_cb.size = sizeof(stub_cb); + + /* register to cmb_stub */ + iRet = mtk_wcn_cmb_stub_reg(&stub_cb); + return iRet; +} diff --git a/drivers/misc/mediatek/connectivity/common/debug_utility/connsys_debug_utility.c b/drivers/misc/mediatek/connectivity/common/debug_utility/connsys_debug_utility.c new file mode 100644 index 0000000000000000000000000000000000000000..4c9baf0c0902bb9ed7d3e5474b4f749350861fe5 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/debug_utility/connsys_debug_utility.c @@ -0,0 +1,1349 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include +#include +#include +#include +#include +#include +#include "connsys_debug_utility.h" +#include "ring_emi.h" +#include "ring.h" +#include "wmt_exp.h" +#include +#include +#include +#include + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ +enum FW_LOG_MODE { + PRINT_TO_KERNEL_LOG = 0, + LOG_TO_FILE = 1, +}; + +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH +static atomic_t log_mode = ATOMIC_INIT(LOG_TO_FILE); +#else +static atomic_t log_mode = ATOMIC_INIT(PRINT_TO_KERNEL_LOG); +#endif + +#define CONNLOG_ALARM_STATE_DISABLE 0x0 +#define CONNLOG_ALARM_STATE_ENABLE 0x01 +#define CONNLOG_ALARM_STATE_RUNNING 0x03 + +#define CONNLOG_LOG_BUFFER_SIZE (64*1024) + +struct connlog_alarm { + struct alarm alarm_timer; + unsigned int alarm_state; + unsigned int blank_state; + unsigned int alarm_sec; + spinlock_t alarm_lock; + unsigned long flags; +}; + +struct connlog_dev { + phys_addr_t phyAddrEmiBase; + void __iomem *virAddrEmiLogBase; + struct connlog_emi_config emi_config; + int conn2ApIrqId; + bool eirqOn; + spinlock_t irq_lock; + unsigned long flags; + unsigned int irq_counter; + CONNLOG_IRQ_CB irq_callback; + struct timer_list workTimer; + struct work_struct logDataWorker; + /* alarm timer for suspend */ + struct connlog_alarm log_alarm; + void *log_data; +}; +static struct connlog_dev gDev = { 0 }; + +static CONNLOG_EVENT_CB event_callback_table[CONNLOG_TYPE_END] = { 0x0 }; + +struct connlog_buffer { + struct ring_emi ring_emi; + struct ring ring_cache; + void *cache_base; +}; +static struct connlog_buffer connlog_buffer_table[CONNLOG_TYPE_END]; + +struct connlog_offset { + unsigned int emi_base_offset; + unsigned int emi_size; + unsigned int emi_read; + unsigned int emi_write; + unsigned int emi_buf; +}; + +static struct connlog_offset emi_offset_table[CONNLOG_TYPE_END]; + +static char *type_to_title[CONNLOG_TYPE_END] = { + "wifi_fw", "bt_fw", "gps_fw", "mcu_fw" +}; + +static size_t cache_size_table[CONNLOG_TYPE_END]; + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +static int connlog_eirq_init(const struct connlog_irq_config *irq_config); +static void connlog_eirq_deinit(void); +static int connlog_emi_init(phys_addr_t emi_base, const struct connlog_emi_config *emi_config); +static void connlog_emi_deinit(void); +static int connlog_ring_buffer_init(void); +static void connlog_ring_buffer_deinit(void); +static int connlog_set_ring_buffer_base_addr(void); +static irqreturn_t connlog_eirq_isr(int irq, void *arg); +static void connlog_set_ring_ready(void); +static void connlog_buffer_init(int conn_type); +static void connlog_ring_emi_to_cache(int conn_type); +static void connlog_dump_buf(const char *title, const char *buf, ssize_t sz); +static void connlog_ring_print(int conn_type); +static void connlog_event_set(int conn_type); +static void connlog_log_data_handler(struct work_struct *work); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) +static void work_timer_handler(struct timer_list *t); +#else +static void work_timer_handler(unsigned long data); +#endif +static void connlog_do_schedule_work(bool count); +static void connlog_emi_status_dump(void); + +/* connlog when suspend */ +static int connlog_alarm_init(void); +static enum alarmtimer_restart alarm_timer_handler(struct alarm *alarm, ktime_t); +static inline bool connlog_is_alarm_enable(void); +static int connlog_set_alarm_timer(void); +static int connlog_cancel_alarm_timer(void); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +static void connlog_set_ring_ready(void); + + +/***************************************************************************** +* FUNCTION +* connlog_emi_status_dump +* DESCRIPTION +* Dump emi control block . +*****************************************************************************/ +void connlog_emi_status_dump(void) +{ + /* Dump header (0x40) and MCU read/write pointer */ + connsys_dedicated_log_dump_emi(0x0, 0x60); + /* 32 byte wifi read/write pointer */ + connsys_dedicated_log_dump_emi(emi_offset_table[CONNLOG_TYPE_WIFI].emi_base_offset, 0x20); + /* 32 byte bt read/write pointer */ + connsys_dedicated_log_dump_emi(emi_offset_table[CONNLOG_TYPE_BT].emi_base_offset, 0x20); + /* 32 byte gps read/write pointer */ + connsys_dedicated_log_dump_emi(emi_offset_table[CONNLOG_TYPE_GPS].emi_base_offset, 0x20); +} + + +/***************************************************************************** +* FUNCTION +* connlog_cache_allocate +* DESCRIPTION +* Allocate memroy for cache . +* PARAMETERS +* size [IN] data buffer length +* RETURNS +* void* buffer pointer +*****************************************************************************/ +void *connlog_cache_allocate(size_t size) +{ + void *pBuffer = NULL; + + pBuffer = vmalloc(size); + if (!pBuffer) + return NULL; + return pBuffer; +} + +/* */ +/***************************************************************************** +* FUNCTION +* connlog_set_ring_ready +* DESCRIPTION +* set reserved bit be EMIFWLOG to indicate that init is ready. +* PARAMETERS +* void +* RETURNS +* void +*****************************************************************************/ +static void connlog_set_ring_ready(void) +{ + const char ready_str[] = "EMIFWLOG"; + + memcpy_toio(gDev.virAddrEmiLogBase + CONNLOG_READY_PATTERN_BASE, + ready_str, CONNLOG_READY_PATTERN_BASE_SIZE); +} + +/***************************************************************************** +* FUNCTION +* connlog_buffer_init +* DESCRIPTION +* Initialize ring and cache buffer +* PARAMETERS +* conn_type [IN] subsys type +* RETURNS +* void +*****************************************************************************/ +static void connlog_buffer_init(int conn_type) +{ + if (conn_type < 0 || conn_type >= CONNLOG_TYPE_END) + return; + + /* init ring emi */ + ring_emi_init( + gDev.virAddrEmiLogBase + emi_offset_table[conn_type].emi_buf, + emi_offset_table[conn_type].emi_size, + gDev.virAddrEmiLogBase + emi_offset_table[conn_type].emi_read, + gDev.virAddrEmiLogBase + emi_offset_table[conn_type].emi_write, + &connlog_buffer_table[conn_type].ring_emi + ); + + /* init ring cache */ + connlog_buffer_table[conn_type].cache_base = connlog_cache_allocate(cache_size_table[conn_type]); + memset(connlog_buffer_table[conn_type].cache_base, 0, cache_size_table[conn_type]); + ring_init( + connlog_buffer_table[conn_type].cache_base, + cache_size_table[conn_type], + 0, + 0, + &connlog_buffer_table[conn_type].ring_cache + ); +} + +/***************************************************************************** +* FUNCTION +* connlog_ring_emi_to_cache +* DESCRIPTION +* copy data from emi ring buffer to cache +* PARAMETERS +* conn_type [IN] subsys type +* RETURNS +* int 0=failed, others=buffer length +*****************************************************************************/ +static void connlog_ring_emi_to_cache(int conn_type) +{ + struct ring_emi_segment ring_emi_seg; + struct ring_emi *ring_emi; + struct ring *ring_cache; + int total_size = 0; + int count = 0; + unsigned int cache_max_size = 0; + static DEFINE_RATELIMIT_STATE(_rs, 10 * HZ, 1); + static DEFINE_RATELIMIT_STATE(_rs2, HZ, 1); + + if (conn_type < 0 || conn_type >= CONNLOG_TYPE_END) + return; + + ring_emi = &connlog_buffer_table[conn_type].ring_emi; + ring_cache = &connlog_buffer_table[conn_type].ring_cache; + + if (RING_FULL(ring_cache)) { + if (__ratelimit(&_rs)) + pr_warn("%s cache is full.\n", type_to_title[conn_type]); + return; + } + + cache_max_size = RING_WRITE_REMAIN_SIZE(ring_cache); + if (RING_EMI_EMPTY(ring_emi) || !ring_emi_read_prepare(cache_max_size, &ring_emi_seg, ring_emi)) { + if (__ratelimit(&_rs)) + pr_err("%s no data, possibly taken by concurrent reader.\n", type_to_title[conn_type]); + return; + } + + /* Check ring_emi buffer memory. Dump EMI data if it's corruption. */ + if (EMI_READ32(ring_emi->read) > emi_offset_table[conn_type].emi_size || + EMI_READ32(ring_emi->write) > emi_offset_table[conn_type].emi_size) { + if (__ratelimit(&_rs)) + pr_err("%s read/write pointer out-of-bounds.\n", type_to_title[conn_type]); + connlog_emi_status_dump(); + /* Trigger Connsys Assert */ + mtk_wcn_wmt_assert(WMTDRV_TYPE_WMT, 46); + return; + } + + RING_EMI_READ_ALL_FOR_EACH(ring_emi_seg, ring_emi) { + struct ring_segment ring_cache_seg; + unsigned int emi_buf_size = ring_emi_seg.sz; + unsigned int written = 0; + +#ifdef DEBUG_RING + ring_emi_dump(__func__, ring_emi); + ring_emi_dump_segment(__func__, &ring_emi_seg); +#endif + RING_WRITE_FOR_EACH(ring_emi_seg.sz, ring_cache_seg, &connlog_buffer_table[conn_type].ring_cache) { +#ifdef DEBUG_RING + ring_dump(__func__, &connlog_buffer_table[conn_type].ring_cache); + ring_dump_segment(__func__, &ring_cache_seg); +#endif + if (__ratelimit(&_rs2)) + pr_info("%s: ring_emi_seg.sz=%d, ring_cache_pt=%p, ring_cache_seg.sz=%d\n", + type_to_title[conn_type], ring_emi_seg.sz, ring_cache_seg.ring_pt, + ring_cache_seg.sz); + memcpy_fromio(ring_cache_seg.ring_pt, ring_emi_seg.ring_emi_pt + ring_cache_seg.data_pos, + ring_cache_seg.sz); + emi_buf_size -= ring_cache_seg.sz; + written += ring_cache_seg.sz; + } + + total_size += ring_emi_seg.sz; + count++; + } +} + +/* output format + * xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx ................ + * 3 digits hex * 16 + 16 single char + 1 NULL terminate = 64+1 bytes + */ +#define BYETES_PER_LINE 16 +#define LOG_LINE_SIZE (3*BYETES_PER_LINE + BYETES_PER_LINE + 1) +#define IS_VISIBLE_CHAR(c) ((c) >= 32 && (c) <= 126) +static void connlog_dump_buf(const char *title, const char *buf, ssize_t sz) +{ + int i; + char line[LOG_LINE_SIZE]; + + i = 0; + line[LOG_LINE_SIZE-1] = 0; + while (sz--) { + if (snprintf(line + i*3, 3, "%02x", *buf) < 0) + return; + line[i*3 + 2] = ' '; + + if (IS_VISIBLE_CHAR(*buf)) + line[3*BYETES_PER_LINE + i] = *buf; + else + line[3*BYETES_PER_LINE + i] = '`'; + + i++; + buf++; + + if (i >= BYETES_PER_LINE || !sz) { + if (i < BYETES_PER_LINE) { + memset(line+i*3, ' ', (BYETES_PER_LINE-i)*3); + memset(line+3*BYETES_PER_LINE+i, '.', BYETES_PER_LINE-i); + } + pr_info("%s: %s\n", title, line); + i = 0; + } + } +} + +#define LOG_MAX_LEN 1024 +#define LOG_HEAD_LENG 16 +#define TIMESYNC_LENG 40 +const char log_head[] = {0x55, 0x00, 0x00, 0x62}; +const char timesync_head[] = {0x55, 0x00, 0x25, 0x62}; +static char log_line[LOG_MAX_LEN]; +static void connlog_fw_log_parser(int conn_type, const char *buf, ssize_t sz) +{ + unsigned int systime = 0; + unsigned int utc_s = 0; + unsigned int utc_us = 0; + unsigned int buf_len = 0; + unsigned int print_len = 0; + + if (conn_type < 0 || conn_type >= CONNLOG_TYPE_END) + return; + + while (sz > LOG_HEAD_LENG) { + if (*buf == log_head[0]) { + if (!memcmp(buf, log_head, sizeof(log_head))) { + buf_len = buf[14] + (buf[15] << 8); + print_len = buf_len >= LOG_MAX_LEN ? LOG_MAX_LEN - 1 : buf_len; + memcpy(log_line, buf + LOG_HEAD_LENG, print_len); + log_line[print_len] = 0; + pr_info("%s: %s\n", type_to_title[conn_type], log_line); + sz -= (LOG_HEAD_LENG + buf_len); + buf += (LOG_HEAD_LENG + buf_len); + continue; + } else if (sz >= TIMESYNC_LENG && + !memcmp(buf, timesync_head, sizeof(timesync_head))) { + memcpy(&systime, buf + 28, sizeof(systime)); + memcpy(&utc_s, buf + 32, sizeof(utc_s)); + memcpy(&utc_us, buf + 36, sizeof(utc_us)); + pr_info("%s: timesync : (%u) %u.%06u\n", + type_to_title[conn_type], systime, utc_s, utc_us); + sz -= TIMESYNC_LENG; + buf += TIMESYNC_LENG; + continue; + } + } + sz--; + buf++; + } +} +/***************************************************************************** +* FUNCTION +* connlog_ring_print +* DESCRIPTION +* print log data on kernel log +* PARAMETERS +* conn_type [IN] subsys type +* RETURNS +* void +*****************************************************************************/ +static void connlog_ring_print(int conn_type) +{ + unsigned int written = 0; + unsigned int buf_size; + struct ring_emi_segment ring_emi_seg; + struct ring_emi *ring_emi; + + if (conn_type < 0 || conn_type >= CONNLOG_TYPE_END) + return; + + ring_emi = &connlog_buffer_table[conn_type].ring_emi; + if (RING_EMI_EMPTY(ring_emi) || !ring_emi_read_all_prepare(&ring_emi_seg, ring_emi)) { + pr_err("type(%s) no data, possibly taken by concurrent reader.\n", type_to_title[conn_type]); + return; + } + buf_size = ring_emi_seg.remain; + memset(gDev.log_data, 0, CONNLOG_LOG_BUFFER_SIZE); + + /* Check ring_emi buffer memory. Dump EMI data if it's corruption. */ + if (EMI_READ32(ring_emi->read) > emi_offset_table[conn_type].emi_size || + EMI_READ32(ring_emi->write) > emi_offset_table[conn_type].emi_size) { + pr_err("%s read/write pointer out-of-bounds.\n", type_to_title[conn_type]); + connlog_emi_status_dump(); + /* Trigger Connsys Assert */ + mtk_wcn_wmt_assert(WMTDRV_TYPE_WMT, 46); + return; + } + + RING_EMI_READ_ALL_FOR_EACH(ring_emi_seg, ring_emi) { + memcpy_fromio(gDev.log_data + written, ring_emi_seg.ring_emi_pt, ring_emi_seg.sz); + /* connlog_dump_buf("fw_log", gDev.log_data + written, ring_emi_seg.sz); */ + buf_size -= ring_emi_seg.sz; + written += ring_emi_seg.sz; + } + if (conn_type != CONNLOG_TYPE_BT) + connlog_fw_log_parser(conn_type, gDev.log_data, written); +} + +/***************************************************************************** +* FUNCTION +* connlog_event_set +* DESCRIPTION +* Trigger event call back to wakeup waitqueue +* PARAMETERS +* conn_type [IN] subsys type +* RETURNS +* void +*****************************************************************************/ +static void connlog_event_set(int conn_type) +{ + if ((conn_type >= 0) && (conn_type < CONNLOG_TYPE_END) && + (event_callback_table[conn_type] != 0x0)) + (*event_callback_table[conn_type])(); +} + +/***************************************************************************** +* FUNCTION +* connlog_do_schedule_work +* DESCRIPTION +* schedule work to read emi log data +* PARAMETERS +* count [IN] write irq counter to EMI +* RETURNS +* void +*****************************************************************************/ +static void connlog_do_schedule_work(bool count) +{ + spin_lock_irqsave(&gDev.irq_lock, gDev.flags); + if (count) { + gDev.irq_counter++; + EMI_WRITE32(gDev.virAddrEmiLogBase + CONNLOG_IRQ_COUNTER_BASE, gDev.irq_counter); + } + gDev.eirqOn = !schedule_work(&gDev.logDataWorker); + spin_unlock_irqrestore(&gDev.irq_lock, gDev.flags); +} + +/***************************************************************************** +* FUNCTION +* work_timer_handler +* DESCRIPTION +* IRQ is still on, do schedule_work again +* PARAMETERS +* data [IN] input data +* RETURNS +* void +*****************************************************************************/ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) +static void work_timer_handler(struct timer_list *t) +#else +static void work_timer_handler(unsigned long data) +#endif +{ + connlog_do_schedule_work(false); +} + +/***************************************************************************** +* FUNCTION +* connlog_alarm_init +* DESCRIPTION +* init alarm timer +* PARAMETERS +* void +* RETURNS +* void +*****************************************************************************/ +static int connlog_alarm_init(void) +{ + alarm_init(&gDev.log_alarm.alarm_timer, ALARM_REALTIME, alarm_timer_handler); + gDev.log_alarm.alarm_state = CONNLOG_ALARM_STATE_DISABLE; + spin_lock_init(&gDev.log_alarm.alarm_lock); + return 0; +} + +/***************************************************************************** +* FUNCTION +* connlog_is_alarm_enable +* DESCRIPTION +* is alarm timer enable +* PARAMETERS +* void +* RETURNS +* void +*****************************************************************************/ +static inline bool connlog_is_alarm_enable(void) +{ + if ((gDev.log_alarm.alarm_state & CONNLOG_ALARM_STATE_ENABLE) > 0) + return true; + return false; +} + +/***************************************************************************** +* FUNCTION +* connlog_set_alarm_timer +* DESCRIPTION +* setup alarm timer +* PARAMETERS +* void +* RETURNS +* void +*****************************************************************************/ +static int connlog_set_alarm_timer(void) +{ + ktime_t kt; + + kt = ktime_set(gDev.log_alarm.alarm_sec, 0); + alarm_start_relative(&gDev.log_alarm.alarm_timer, kt); + + pr_info("[connsys_log_alarm] alarm timer enabled timeout=[%d]", gDev.log_alarm.alarm_sec); + return 0; +} + +/***************************************************************************** +* FUNCTION +* connlog_cancel_alarm_timer +* DESCRIPTION +* cancel alarm timer +* PARAMETERS +* void +* RETURNS +* void +*****************************************************************************/ +static int connlog_cancel_alarm_timer(void) +{ + pr_info("[connsys_log_alarm] alarm timer cancel"); + return alarm_cancel(&gDev.log_alarm.alarm_timer); +} + +/***************************************************************************** +* FUNCTION +* connsys_log_alarm_enable +* DESCRIPTION +* enable screen off alarm timer mechanism +* PARAMETERS +* sec [IN] alarm timeout in seconds +* RETURNS +* void +*****************************************************************************/ +int connsys_log_alarm_enable(unsigned int sec) +{ + if (!gDev.virAddrEmiLogBase) + return -1; + + spin_lock_irqsave(&gDev.log_alarm.alarm_lock, gDev.log_alarm.flags); + + gDev.log_alarm.alarm_sec = sec; + if (!connlog_is_alarm_enable()) { + gDev.log_alarm.alarm_state = CONNLOG_ALARM_STATE_ENABLE; + pr_info("[connsys_log_alarm] alarm timer enabled timeout=[%d]", sec); + } + if (gDev.log_alarm.blank_state == 0) + connlog_set_alarm_timer(); + + spin_unlock_irqrestore(&gDev.log_alarm.alarm_lock, gDev.log_alarm.flags); + return 0; +} +EXPORT_SYMBOL(connsys_log_alarm_enable); + +/***************************************************************************** +* FUNCTION +* connsys_log_alarm_disable +* DESCRIPTION +* disable screen off alarm timer mechanism +* PARAMETERS +* void +* RETURNS +* void +*****************************************************************************/ +int connsys_log_alarm_disable(void) +{ + int ret = 0; + + if (!gDev.virAddrEmiLogBase) + return -1; + + spin_lock_irqsave(&gDev.log_alarm.alarm_lock, gDev.log_alarm.flags); + if (connlog_is_alarm_enable()) { + ret = connlog_cancel_alarm_timer(); + gDev.log_alarm.alarm_state = CONNLOG_ALARM_STATE_DISABLE; + pr_info("[connsys_log_alarm] alarm timer disable"); + } + + spin_unlock_irqrestore(&gDev.log_alarm.alarm_lock, gDev.log_alarm.flags); + return ret; +} +EXPORT_SYMBOL(connsys_log_alarm_disable); + +/***************************************************************************** +* FUNCTION +* connsys_log_blank_state_changed +* DESCRIPTION +* listen blank on/off to suspend/reusme alarm timer +* PARAMETERS +* int [IN] blank state +* RETURNS +* void +*****************************************************************************/ +int connsys_log_blank_state_changed(int blank_state) +{ + int ret = 0; + + if (!gDev.virAddrEmiLogBase) + return -1; + + spin_lock_irqsave(&gDev.log_alarm.alarm_lock, gDev.log_alarm.flags); + gDev.log_alarm.blank_state = blank_state; + if (connlog_is_alarm_enable()) { + if (blank_state == 0) + ret = connlog_set_alarm_timer(); + else + ret = connlog_cancel_alarm_timer(); + } + spin_unlock_irqrestore(&gDev.log_alarm.alarm_lock, gDev.log_alarm.flags); + + return ret; +} +EXPORT_SYMBOL(connsys_log_blank_state_changed); + +/***************************************************************************** +* FUNCTION +* alarm_timer_handler +* DESCRIPTION +* handler for alarm timer +* PARAMETERS +* int [IN] blank state +* RETURNS +* void +*****************************************************************************/ +static enum alarmtimer_restart alarm_timer_handler(struct alarm *alarm, + ktime_t now) +{ + ktime_t kt; + struct rtc_time tm; + unsigned int tsec, tusec; + + connsys_dedicated_log_get_utc_time(&tsec, &tusec); + rtc_time_to_tm(tsec, &tm); + pr_info("[connsys_log_alarm] alarm_timer triggered [%d-%02d-%02d %02d:%02d:%02d.%09u]" + , tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday + , tm.tm_hour, tm.tm_min, tm.tm_sec, tusec); + + connlog_do_schedule_work(false); + + spin_lock_irqsave(&gDev.log_alarm.alarm_lock, gDev.log_alarm.flags); + kt = ktime_set(gDev.log_alarm.alarm_sec, 0); + alarm_start_relative(&gDev.log_alarm.alarm_timer, kt); + spin_unlock_irqrestore(&gDev.log_alarm.alarm_lock, gDev.log_alarm.flags); + + return ALARMTIMER_NORESTART; +} + +/***************************************************************************** +* FUNCTION +* connlog_print_log +* DESCRIPTION +* Print FW log to kernel log +* PARAMETERS +* conn_type [IN] subsys type +* RETURNS +* void +*****************************************************************************/ +static void connlog_log_data_handler(struct work_struct *work) +{ + int ret = 0; + int i; + int module = 0; + static DEFINE_RATELIMIT_STATE(_rs, 10 * HZ, 1); + static DEFINE_RATELIMIT_STATE(_rs2, 2 * HZ, 1); + + do { + ret = 0; + for (i = 0; i < CONNLOG_TYPE_END; i++) { + if (!RING_EMI_EMPTY(&connlog_buffer_table[i].ring_emi)) { + if (atomic_read(&log_mode) == LOG_TO_FILE) + connlog_ring_emi_to_cache(i); + else + connlog_ring_print(i); + + connlog_event_set(i); + /* Set module bit */ + module |= (1 << i); + /* ret++; */ + } else { + if (__ratelimit(&_rs)) + pr_info("[connlog] %s emi ring is empty!!\n", type_to_title[i]); + } + } + } while (ret); + + if (__ratelimit(&_rs2)) + pr_info("[connlog] irq counter=%d module=0x%04x\n", + EMI_READ32(gDev.virAddrEmiLogBase + CONNLOG_IRQ_COUNTER_BASE), module); + spin_lock_irqsave(&gDev.irq_lock, gDev.flags); + if (gDev.eirqOn) + mod_timer(&gDev.workTimer, jiffies + 1); + spin_unlock_irqrestore(&gDev.irq_lock, gDev.flags); +} + +/***************************************************************************** +* FUNCTION +* connlog_eirq_isr +* DESCRIPTION +* IRQ handler to notify subsys that EMI has logs. +* PARAMETERS +* irq [IN] irq number +* art [IN] other argument +* RETURNS +* irqreturn_t irq status +* @IRQ_HANDLED interrupt was handled by this device +*****************************************************************************/ +static irqreturn_t connlog_eirq_isr(int irq, void *arg) +{ + connlog_do_schedule_work(true); + + if (gDev.irq_callback) + (*gDev.irq_callback)(); + + return IRQ_HANDLED; +} + +/***************************************************************************** +* FUNCTION +* connlog_eirq_init +* DESCRIPTION +* To register IRQ +* PARAMETERS +* irq_id [IN] irq number +* irq_flag [IN] irq type +* RETURNS +* int 0=success, others=error +*****************************************************************************/ +static int connlog_eirq_init(const struct connlog_irq_config *irq_config) +{ + int iret = 0; + + if (irq_config == NULL) { + pr_info("irq_config is NULL\n"); + return -1; + } + + if (gDev.conn2ApIrqId == 0) + gDev.conn2ApIrqId = irq_config->irq_num; + else { + pr_warn("IRQ has been initialized\n"); + return -1; + } + + gDev.irq_callback = irq_config->irq_callback; + + pr_info("EINT CONN_LOG_IRQ(%d, %d)\n", irq_config->irq_num, irq_config->irq_flag); + + iret = request_irq(gDev.conn2ApIrqId, connlog_eirq_isr, irq_config->irq_flag, "CONN_LOG_IRQ", NULL); + if (iret) { + pr_err("EINT IRQ(%d) NOT AVAILABLE!!\n", gDev.conn2ApIrqId); + } else { + iret = enable_irq_wake(gDev.conn2ApIrqId); + if (iret) + pr_err("enable irq wake fail,irq_no(%d),iret(%d)\n", gDev.conn2ApIrqId, iret); + iret = 0; + } + + return iret; +} + +/***************************************************************************** +* FUNCTION +* connlog_eirq_deinit +* DESCRIPTION +* unrigester irq +* PARAMETERS +* void +* RETURNS +* void +*****************************************************************************/ +static void connlog_eirq_deinit(void) +{ + free_irq(gDev.conn2ApIrqId, NULL); +} + +/***************************************************************************** +* FUNCTION +* connlog_set_ring_buffer_base_addr +* DESCRIPTION +* Set subsys log base address on EMI for FW +* PARAMETERS +* void +* RETURNS +* void +*****************************************************************************/ +static int connlog_set_ring_buffer_base_addr(void) +{ + if (!gDev.virAddrEmiLogBase) + return -1; + + /* set up subsys base address */ + EMI_WRITE32(gDev.virAddrEmiLogBase + 0, emi_offset_table[CONNLOG_TYPE_MCU].emi_base_offset); + EMI_WRITE32(gDev.virAddrEmiLogBase + 4, emi_offset_table[CONNLOG_TYPE_MCU].emi_size); + EMI_WRITE32(gDev.virAddrEmiLogBase + 8, emi_offset_table[CONNLOG_TYPE_WIFI].emi_base_offset); + EMI_WRITE32(gDev.virAddrEmiLogBase + 12, emi_offset_table[CONNLOG_TYPE_WIFI].emi_size); + EMI_WRITE32(gDev.virAddrEmiLogBase + 16, emi_offset_table[CONNLOG_TYPE_BT].emi_base_offset); + EMI_WRITE32(gDev.virAddrEmiLogBase + 20, emi_offset_table[CONNLOG_TYPE_BT].emi_size); + EMI_WRITE32(gDev.virAddrEmiLogBase + 24, emi_offset_table[CONNLOG_TYPE_GPS].emi_base_offset); + EMI_WRITE32(gDev.virAddrEmiLogBase + 28, emi_offset_table[CONNLOG_TYPE_GPS].emi_size); + return 0; +} + +/***************************************************************************** +* FUNCTION +* connlog_emi_init +* DESCRIPTION +* Do ioremap for log buffer on EMI +* PARAMETERS +* emiaddr [IN] physical EMI base address +* RETURNS +* void +*****************************************************************************/ +static int connlog_emi_init(phys_addr_t emi_base, const struct connlog_emi_config *emi_config) +{ + unsigned int mcu_base, wifi_base, bt_base, gps_base; + + if (emi_config == 0) { + pr_err("consys emi memory address gPhyAddrEmiBase invalid\n"); + return -1; + } + + if (gDev.phyAddrEmiBase) { + pr_warn("emi base address has been initialized\n"); + return -2; + } + + gDev.phyAddrEmiBase = emi_base; + gDev.virAddrEmiLogBase = ioremap_nocache(gDev.phyAddrEmiBase + + emi_config->emi_offset, emi_config->emi_size_total); + if (gDev.virAddrEmiLogBase) { + pr_info("EMI mapping OK virtual(0x%p) physical(0x%x)\n", + gDev.virAddrEmiLogBase, + (unsigned int)(gDev.phyAddrEmiBase + emi_config->emi_offset)); + memset_io(gDev.virAddrEmiLogBase, 0, emi_config->emi_size_total); + } else + pr_err("EMI mapping fail\n"); + + memcpy(&gDev.emi_config, emi_config, sizeof(struct connlog_emi_config)); + + mcu_base = CONNLOG_CONTROL_RING_BUFFER_BASE_SIZE; + wifi_base = + mcu_base + gDev.emi_config.emi_size_mcu + CONNLOG_CONTROL_RING_BUFFER_RESERVE_SIZE + + CONNLOG_EMI_32_BYTE_ALIGNED; + bt_base = + wifi_base + gDev.emi_config.emi_size_wifi + CONNLOG_CONTROL_RING_BUFFER_RESERVE_SIZE + + CONNLOG_EMI_32_BYTE_ALIGNED; + gps_base = + bt_base + gDev.emi_config.emi_size_bt + CONNLOG_CONTROL_RING_BUFFER_RESERVE_SIZE + + CONNLOG_EMI_32_BYTE_ALIGNED; + +#define INIT_EMI_OFFSET_TABLE(index, base, size, read_offset, write_offset, buf_offset) \ + emi_offset_table[index].emi_base_offset = base; \ + emi_offset_table[index].emi_size = size; \ + emi_offset_table[index].emi_read = read_offset; \ + emi_offset_table[index].emi_write = write_offset; \ + emi_offset_table[index].emi_buf = buf_offset + + INIT_EMI_OFFSET_TABLE( + CONNLOG_TYPE_MCU, + mcu_base, gDev.emi_config.emi_size_mcu, + mcu_base + 0, mcu_base + 4, + mcu_base + CONNLOG_EMI_32_BYTE_ALIGNED); + INIT_EMI_OFFSET_TABLE( + CONNLOG_TYPE_WIFI, + wifi_base, gDev.emi_config.emi_size_wifi, + wifi_base + 0, wifi_base + 4, + wifi_base + CONNLOG_EMI_32_BYTE_ALIGNED); + INIT_EMI_OFFSET_TABLE( + CONNLOG_TYPE_BT, + bt_base, gDev.emi_config.emi_size_bt, + bt_base + 0, bt_base + 4, + bt_base + CONNLOG_EMI_32_BYTE_ALIGNED); + INIT_EMI_OFFSET_TABLE( + CONNLOG_TYPE_GPS, + gps_base, gDev.emi_config.emi_size_gps, + gps_base + 0, gps_base + 4, + gps_base + CONNLOG_EMI_32_BYTE_ALIGNED); + + return 0; +} + +/***************************************************************************** +* FUNCTION +* connlog_emi_deinit +* DESCRIPTION +* Do iounmap for log buffer on EMI +* PARAMETERS +* void +* RETURNS +* void +*****************************************************************************/ +static void connlog_emi_deinit(void) +{ + iounmap(gDev.virAddrEmiLogBase); +} + +/***************************************************************************** +* FUNCTION +* connlog_ring_buffer_init +* DESCRIPTION +* Initialize ring buffer setting for subsys +* PARAMETERS +* void +* RETURNS +* void +*****************************************************************************/ +static int connlog_ring_buffer_init(void) +{ + if (!gDev.virAddrEmiLogBase) { + pr_err("consys emi memory address phyAddrEmiBase invalid\n"); + return -1; + } + + connlog_set_ring_buffer_base_addr(); + /* cache table size init */ + cache_size_table[CONNLOG_TYPE_WIFI] = (emi_offset_table[CONNLOG_TYPE_WIFI].emi_size * 2); + cache_size_table[CONNLOG_TYPE_BT] = (emi_offset_table[CONNLOG_TYPE_BT].emi_size * 2); + cache_size_table[CONNLOG_TYPE_GPS] = emi_offset_table[CONNLOG_TYPE_GPS].emi_size; + cache_size_table[CONNLOG_TYPE_MCU] = emi_offset_table[CONNLOG_TYPE_MCU].emi_size; + + connlog_buffer_init(CONNLOG_TYPE_WIFI); + connlog_buffer_init(CONNLOG_TYPE_BT); + connlog_buffer_init(CONNLOG_TYPE_GPS); + connlog_buffer_init(CONNLOG_TYPE_MCU); + gDev.log_data = connlog_cache_allocate(CONNLOG_LOG_BUFFER_SIZE); + connlog_set_ring_ready(); + + return 0; +} + +/***************************************************************************** +* FUNCTION +* connlog_ring_buffer_deinit +* DESCRIPTION +* Initialize ring buffer setting for subsys +* PARAMETERS +* void +* RETURNS +* void +*****************************************************************************/ +static void connlog_ring_buffer_deinit(void) +{ + int i = 0; + + for (i = 0; i < CONNLOG_TYPE_END; i++) { + kvfree(connlog_buffer_table[i].cache_base); + connlog_buffer_table[i].cache_base = NULL; + } + kvfree(gDev.log_data); + gDev.log_data = NULL; +} + +/***************************************************************************** +* FUNCTION +* connsys_dedicated_log_path_apsoc_init +* DESCRIPTION +* Initialize API for common driver to initialize connsys dedicated log +* for APSOC platform +* PARAMETERS +* emiaddr [IN] EMI physical base address +* irq_num [IN] IRQ id from device tree +* irq_flag [IN] IRQ flag from device tree +* RETURNS +* void +*****************************************************************************/ +int connsys_dedicated_log_path_apsoc_init( + phys_addr_t emi_base, + const struct connlog_emi_config *emi_config, + const struct connlog_irq_config *irq_config) +{ + gDev.phyAddrEmiBase = 0; + gDev.virAddrEmiLogBase = 0; + gDev.conn2ApIrqId = 0; + gDev.eirqOn = false; + gDev.irq_counter = 0; + gDev.irq_callback = NULL; + memset(&gDev.emi_config, 0, sizeof(struct connlog_emi_config)); + + if (connlog_emi_init(emi_base, emi_config)) { + pr_err("EMI init failed\n"); + return -1; + } + + if (connlog_ring_buffer_init()) { + pr_err("Ring buffer init failed\n"); + return -2; + } + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) + timer_setup(&gDev.workTimer, work_timer_handler, 0); +#else + init_timer(&gDev.workTimer); +#endif + gDev.workTimer.function = work_timer_handler; + spin_lock_init(&gDev.irq_lock); + INIT_WORK(&gDev.logDataWorker, connlog_log_data_handler); + if (connlog_eirq_init(irq_config)) { + pr_err("EIRQ init failed\n"); + return -3; + } + + /* alarm_timer */ + connlog_alarm_init(); + return 0; +} +EXPORT_SYMBOL(connsys_dedicated_log_path_apsoc_init); + +/***************************************************************************** +* FUNCTION +* connsys_dedicated_log_path_apsoc_deinit +* DESCRIPTION +* De-Initialize API for common driver to release cache, un-remap emi and free +* irq for APSOC platform +* PARAMETERS +* void +* RETURNS +* void +*****************************************************************************/ +void connsys_dedicated_log_path_apsoc_deinit(void) +{ + connlog_emi_deinit(); + connlog_eirq_deinit(); + connlog_ring_buffer_deinit(); +} +EXPORT_SYMBOL(connsys_dedicated_log_path_apsoc_deinit); + +/***************************************************************************** +* FUNCTION +* connsys_log_init +* DESCRIPTION +* Init API for subsys driver. +* PARAMETERS +* conn_type [IN] subsys type +* RETURNS +* int 0=success, others=error +*****************************************************************************/ +int connsys_log_init(int conn_type) +{ + return 0; +} +EXPORT_SYMBOL(connsys_log_init); + +/***************************************************************************** +* FUNCTION +* connsys_log_deinit +* DESCRIPTION +* De-init API for subsys driver. +* PARAMETERS +* conn_type [IN] subsys type +* RETURNS +* int 0=success, others=error +*****************************************************************************/ +int connsys_log_deinit(int conn_type) +{ + if (conn_type >= CONNLOG_TYPE_END || conn_type < 0) + return -1; + event_callback_table[conn_type] = 0x0; + return 0; +} +EXPORT_SYMBOL(connsys_log_deinit); + +/***************************************************************************** +* FUNCTION +* connsys_log_get_buf_size +* DESCRIPTION +* Get ring buffer unread size on EMI. +* PARAMETERS +* conn_type [IN] subsys type +* RETURNS +* unsigned int Ring buffer unread size +*****************************************************************************/ +unsigned int connsys_log_get_buf_size(int conn_type) +{ + if (conn_type >= CONNLOG_TYPE_END || conn_type < 0) + return -1; + return RING_SIZE(&connlog_buffer_table[conn_type].ring_cache); +} +EXPORT_SYMBOL(connsys_log_get_buf_size); + +/***************************************************************************** +* FUNCTION +* connsys_log_register_event_cb +* DESCRIPTION +* Register callback function. It'll be trigger while receive conn2ap IRQ. +* PARAMETERS +* conn_type [IN] subsys type +* func [IN] callback function pointer +* RETURNS +* int 0=success, others=error +*****************************************************************************/ +int connsys_log_register_event_cb(int conn_type, CONNLOG_EVENT_CB func) +{ + if (conn_type >= CONNLOG_TYPE_END || conn_type < 0) + return -1; + event_callback_table[conn_type] = func; + return 0; +} +EXPORT_SYMBOL(connsys_log_register_event_cb); + +/***************************************************************************** +* FUNCTION +* connsys_log_read +* DESCRIPTION +* Copy EMI ring buffer data to the buffer that provided by sub-module. +* PARAMETERS +* conn_type [IN] subsys type +* buf [IN] buffer from driver +* count [IN] buffer length +* RETURNS +* ssize_t read buffer size +*****************************************************************************/ +ssize_t connsys_log_read(int conn_type, char *buf, size_t count) +{ + unsigned int written = 0; + unsigned int cache_buf_size; + struct ring_segment ring_seg; + struct ring *ring; + unsigned int size = 0; + + if (conn_type < 0 || conn_type >= CONNLOG_TYPE_END) + return 0; + + ring = &connlog_buffer_table[conn_type].ring_cache; + + if (atomic_read(&log_mode) != LOG_TO_FILE) + goto done; + + size = count < RING_SIZE(ring) ? count : RING_SIZE(ring); + if (RING_EMPTY(ring) || !ring_read_prepare(size, &ring_seg, ring)) { + pr_err("type(%d) no data, possibly taken by concurrent reader.\n", conn_type); + goto done; + } + cache_buf_size = ring_seg.remain; + + RING_READ_FOR_EACH(size, ring_seg, ring) { + memcpy(buf + written, ring_seg.ring_pt, ring_seg.sz); + cache_buf_size -= ring_seg.sz; + written += ring_seg.sz; + } +done: + return written; +} +EXPORT_SYMBOL(connsys_log_read); + +/***************************************************************************** +* FUNCTION +* connsys_log_read_to_user +* DESCRIPTION +* Copy EMI ring buffer data to the user buffer. +* PARAMETERS +* conn_type [IN] subsys type +* buf [IN] user buffer +* count [IN] buffer length +* RETURNS +* ssize_t read buffer size +*****************************************************************************/ +ssize_t connsys_log_read_to_user(int conn_type, char __user *buf, size_t count) +{ + int retval; + unsigned int written = 0; + static DEFINE_RATELIMIT_STATE(_rs, 10 * HZ, 1); + unsigned int cache_buf_size; + struct ring_segment ring_seg; + struct ring *ring; + unsigned int size = 0; + + if (conn_type < 0 || conn_type >= CONNLOG_TYPE_END) + return 0; + + ring = &connlog_buffer_table[conn_type].ring_cache; + + if (atomic_read(&log_mode) != LOG_TO_FILE) + goto done; + + size = count < RING_SIZE(ring) ? count : RING_SIZE(ring); + if (RING_EMPTY(ring) || !ring_read_prepare(size, &ring_seg, ring)) { + pr_err("type(%d) no data, possibly taken by concurrent reader.\n", conn_type); + goto done; + } + cache_buf_size = ring_seg.remain; + + RING_READ_FOR_EACH(size, ring_seg, ring) { + retval = copy_to_user(buf + written, ring_seg.ring_pt, ring_seg.sz); + if (retval) { + if (__ratelimit(&_rs)) + pr_err("copy to user buffer failed, ret:%d\n", retval); + goto done; + } + cache_buf_size -= ring_seg.sz; + written += ring_seg.sz; + } +done: + return written; +} +EXPORT_SYMBOL(connsys_log_read_to_user); + +/***************************************************************************** +* FUNCTION +* connsys_log_get_emi_log_base_vir_addr +* DESCRIPTION +* return EMI log base address whitch has done ioremap. +* PARAMETERS +* void +* RETURNS +* void __iomem * ioremap EMI log base address +*****************************************************************************/ +void __iomem *connsys_log_get_emi_log_base_vir_addr(void) +{ + return gDev.virAddrEmiLogBase; +} +EXPORT_SYMBOL(connsys_log_get_emi_log_base_vir_addr); + +/***************************************************************************** +* FUNCTION +* connsys_dedicated_log_get_utc_time +* DESCRIPTION +* return EMI log base address whitch has done ioremap. +* PARAMETERS +* second [IN] UTC seconds +* usecond [IN] UTC usecons +* RETURNS +* void +*****************************************************************************/ +void connsys_dedicated_log_get_utc_time(unsigned int *second, + unsigned int *usecond) +{ + struct timespec64 time; + + ktime_get_real_ts64(&time); + *second = (unsigned int)time.tv_sec; /* UTC time second unit */ + *usecond = (unsigned int)(time.tv_nsec / NSEC_PER_USEC); /* UTC time microsecond unit */ +} +EXPORT_SYMBOL(connsys_dedicated_log_get_utc_time); + +/***************************************************************************** +* FUNCTION +* connsys_dedicated_log_flush_emi +* DESCRIPTION +* flush EMI buffer to log cache. +* PARAMETERS +* void +* RETURNS +* void +*****************************************************************************/ +void connsys_dedicated_log_flush_emi(void) +{ + connlog_do_schedule_work(false); +} + +/***************************************************************************** +* FUNCTION +* connsys_dedicated_log_dump_emi +* DESCRIPTION +* dump EMI buffer for debug. +* PARAMETERS +* offset [IN] buffer offset +* size [IN] dump buffer size +* RETURNS +* void +*****************************************************************************/ +void connsys_dedicated_log_dump_emi(int offset, int size) +{ + connlog_dump_buf("emi", gDev.virAddrEmiLogBase + offset, size); +} + +/***************************************************************************** +* FUNCTION +* connsys_dedicated_log_set_log_to_file +* DESCRIPTION +* set log mode. +* PARAMETERS +* mode [IN] log mode +* RETURNS +* void +*****************************************************************************/ +void connsys_dedicated_log_set_log_mode(int mode) +{ + atomic_set(&log_mode, (mode > 0 ? LOG_TO_FILE : PRINT_TO_KERNEL_LOG)); +} + +/***************************************************************************** +* FUNCTION +* connsys_dedicated_log_get_log_mode +* DESCRIPTION +* get log mode. +* PARAMETERS +* void +* RETURNS +* int log mode +*****************************************************************************/ +int connsys_dedicated_log_get_log_mode(void) +{ + return atomic_read(&log_mode); +} diff --git a/drivers/misc/mediatek/connectivity/common/debug_utility/connsys_debug_utility.h b/drivers/misc/mediatek/connectivity/common/debug_utility/connsys_debug_utility.h new file mode 100644 index 0000000000000000000000000000000000000000..14d8c2a06ea52acae4197b9c9abcee3a58d2debe --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/debug_utility/connsys_debug_utility.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +#ifndef _CONNSYS_DEBUG_UTILITY_H_ +#define _CONNSYS_DEBUG_UTILITY_H_ + +#include "connsys_debug_utility_emi.h" +#include +#include + + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ +enum CONNLOG_TYPE { + CONNLOG_TYPE_WIFI = 0, + CONNLOG_TYPE_BT = 1, + CONNLOG_TYPE_GPS = 2, + CONNLOG_TYPE_MCU = 3, + CONNLOG_TYPE_END, +}; + +typedef void (*CONNLOG_EVENT_CB) (void); +typedef void (*CONNLOG_IRQ_CB) (void); + +struct connlog_emi_config { + /* basic information */ + phys_addr_t emi_offset; + unsigned int emi_size_total; + /* for individual radio */ + unsigned int emi_size_mcu; + unsigned int emi_size_wifi; + unsigned int emi_size_bt; + unsigned int emi_size_gps; +}; + +struct connlog_irq_config { + unsigned int irq_num; + unsigned int irq_flag; + CONNLOG_IRQ_CB irq_callback; +}; + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/* Common Driver API */ +int connsys_dedicated_log_path_apsoc_init( + phys_addr_t emi_base, + const struct connlog_emi_config *emi_config, + const struct connlog_irq_config *irq_config); +void connsys_dedicated_log_path_apsoc_deinit(void); +void __iomem *connsys_log_get_emi_log_base_vir_addr(void); +void connsys_dedicated_log_get_utc_time(unsigned int *second, unsigned int *usecond); +void connsys_dedicated_log_flush_emi(void); +void connsys_dedicated_log_set_log_mode(int mode); +int connsys_dedicated_log_get_log_mode(void); +void connsys_dedicated_log_dump_emi(int offset, int size); + +/* Debug Utility API */ +int connsys_log_init(int conn_type); +int connsys_log_deinit(int conn_type); +unsigned int connsys_log_get_buf_size(int conn_type); +int connsys_log_register_event_cb(int conn_type, CONNLOG_EVENT_CB func); +ssize_t connsys_log_read_to_user(int conn_type, char __user *buf, size_t count); +ssize_t connsys_log_read(int conn_type, char *buf, size_t count); + +int connsys_log_alarm_enable(unsigned int sec); +int connsys_log_alarm_disable(void); +int connsys_log_blank_state_changed(int blank_state); + +#endif /*_CONNSYS_DEBUG_UTILITY_H_*/ diff --git a/drivers/misc/mediatek/connectivity/common/debug_utility/connsys_debug_utility_emi.h b/drivers/misc/mediatek/connectivity/common/debug_utility/connsys_debug_utility_emi.h new file mode 100644 index 0000000000000000000000000000000000000000..485c8119aa108e16ce7b4339d90761ddd5f9f018 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/debug_utility/connsys_debug_utility_emi.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#ifndef _CONN_DEDICATED_LOG_EMI_H_ +#define _CONN_DEDICATED_LOG_EMI_H_ + +#define CONNLOG_EMI_32_BYTE_ALIGNED 32 /* connsys EMI cache is 32-byte aligned */ +#define CONNLOG_CONTROL_RING_BUFFER_BASE_SIZE 64 /* Reserve for setup ring buffer base address */ +#define CONNLOG_CONTROL_RING_BUFFER_RESERVE_SIZE 32 +#define CONNLOG_IRQ_COUNTER_BASE 48 +#define CONNLOG_READY_PATTERN_BASE 56 +#define CONNLOG_READY_PATTERN_BASE_SIZE 8 + +/* Init emi_offset_table */ +/* EMI structure + * +-+-+ +----------------------+ Offset + * | | Header | + * | | size: 0x40 | + * | +----------------------+ +0x40 //CONNLOG_CONTROL_RING_BUFFER_BASE_SIZE + * | | | +0x00: read + * | | MCU | +0x04: write + * | | | +0x20: buf start //CONNLOG_CONTROL_RING_BUFFER_RESERVE_SIZE + * | +----------------------+ + * | | | //reserved, CONNLOG_EMI_32_BYTE_ALIGNED + * | +----------------------+ +(0x40 + 0x20 + MCU_SIZE + 0x20) + * | | | +0x00: read + * | | WIFI | +0x04: write + * v | | +0x20: buf + * | | + * +----------------------+ + * Size | | //reserved, CONNLOG_EMI_32_BYTE_ALIGNED + * +----------------------+ +(0x40 + 0x20 + MCU_SIZE + 0x20) + + * | | (WIFI_SIZE + 0x20 + 0x20) + * | BT | +0x00: read + * ^ | | +0x04: write + * | | | +0x20: buf + * | +----------------------+ + * | | | //reserved, CONNLOG_EMI_32_BYTE_ALIGNED + * | +----------------------+ +(0x40 + 0x20 + MCU_SIZE + 0x20) + + * | | | (WIFI_SIZE + 0x20 + 0x20) + + * | | GPS | (BT_SIZE + 0x20 + 0x20) + * | | | +0x00: read + * | +----------------------+ +0x04: write + * | | padding | +0x20: buf + * +-+-+ +----------------------+ + * + * Header detail: + * +---------------+--------------+---------------+--------------+ Offset + * | MCU base | MCU size | WIFI base | WIFI size | + * +---------------+--------------+---------------+--------------+ +0x10 + * | BT base | BT size | GPS base | GPS size | + * +---------------+--------------+---------------+--------------+ +0x20 + * | Reserved 16 byte | + * +---------------+--------------+---------------+--------------+ +0x30 + * | IRQ count | IRQ submit | | + * | received by | by MCU | "EMIFWLOG" | + * | driver | | | + * +---------------+--------------+---------------+--------------+ +0x40 + * +0 +4 +8 +C +F + */ + +#endif diff --git a/drivers/misc/mediatek/connectivity/common/debug_utility/ring.c b/drivers/misc/mediatek/connectivity/common/debug_utility/ring.c new file mode 100644 index 0000000000000000000000000000000000000000..51fbf82160621a5a83e333efca3f0882b8e33af3 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/debug_utility/ring.c @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#include "ring.h" +#include +#include +#include + + + +void ring_init(void *base, unsigned int max_size, unsigned int read, + unsigned int write, struct ring *ring) +{ + WARN_ON(!base); + + /* making sure max_size is power of 2 */ + WARN_ON(!max_size || (max_size & (max_size - 1))); + + /* making sure write largger than read */ + WARN_ON(read > write); + + ring->base = base; + ring->read = read; + ring->write = write; + ring->max_size = max_size; +} + +void ring_dump(const char *title, struct ring *ring) +{ + pr_info("[%s] ring:{write=%d, read=%d, max_size=%d}\n", + title, ring->write, ring->read, ring->max_size); +} + +void ring_dump_segment(const char *title, struct ring_segment *seg) +{ + pr_info("[%s] seg:{ring_pt=0x%p, data_pos=%d, sz=%d, remain=%d}\n", + title, seg->ring_pt, seg->data_pos, seg->sz, seg->remain); +} + +/* + * Function prepares the ring_segment and returns the number of valid bytes for read. + */ +unsigned int ring_read_prepare(unsigned int sz, struct ring_segment *seg, struct ring *ring) +{ + unsigned int wt = ring->write; + unsigned int rd = ring->read; + + memset(seg, 0, sizeof(struct ring_segment)); + if (sz > wt - rd) + sz = wt - rd; + seg->remain = sz; + /* ring_dump(__func__, ring); */ + /* ring_dump_segment(__func__, seg); */ + return seg->remain; +} + +/* + * Function prepares the ring_segment and returns the number of bytes available for write. + */ +unsigned int ring_write_prepare(unsigned int sz, struct ring_segment *seg, struct ring *ring) +{ + unsigned int wt = ring->write; + unsigned int rd = ring->read; + + memset(seg, 0, sizeof(struct ring_segment)); + if (sz > ring->max_size - (wt - rd)) + sz = ring->max_size - (wt - rd); + seg->remain = sz; + /* ring_dump(__func__, ring); */ + /* ring_dump_segment(__func__, seg); */ + return seg->remain; +} + +unsigned int ring_overwrite_prepare(unsigned int sz, struct ring_segment *seg, + struct ring *ring) +{ + unsigned int wt = ring->write; + unsigned int rd = ring->read; + + memset(seg, 0, sizeof(struct ring_segment)); + if (sz > ring->max_size - (wt - rd)) + ring->read += sz - (ring->max_size - (wt - rd)); + seg->remain = sz; + /* ring_dump(__func__, ring); */ + /* ring_dump_segment(__func__, seg); */ + return seg->remain; +} + +void __ring_segment_prepare(unsigned int from, unsigned int sz, struct ring_segment *seg, + struct ring *ring) +{ + unsigned int ring_pos = from & (ring->max_size - 1); + + seg->ring_pt = ring->base + ring_pos; + seg->data_pos = (seg->sz ? seg->data_pos + seg->sz : 0); + if (ring_pos + sz <= ring->max_size) + seg->sz = sz; + else + seg->sz = ring->max_size - ring_pos; + seg->remain -= seg->sz; + /* ring_dump(__func__, ring); */ + /* ring_dump_segment(__func__, seg); */ +} + +void _ring_segment_prepare(unsigned int from, struct ring_segment *seg, struct ring *ring) +{ + __ring_segment_prepare(from, seg->remain, seg, ring); +} + +void _ring_segment_prepare_item(unsigned int from, struct ring_segment *seg, struct ring *ring) +{ + unsigned int size; + + size = (seg->remain ? 1 : 0); + __ring_segment_prepare(from, size, seg, ring); +} + +void _ring_read_commit(struct ring_segment *seg, struct ring *ring) +{ + ring->read += seg->sz; + /* ring_dump(__func__, ring); */ + /* ring_dump_segment(__func__, seg); */ +} +void _ring_write_commit(struct ring_segment *seg, struct ring *ring) +{ + ring->write += seg->sz; + /* ring_dump(__func__, ring); */ + /* ring_dump_segment(__func__, seg); */ +} + diff --git a/drivers/misc/mediatek/connectivity/common/debug_utility/ring.h b/drivers/misc/mediatek/connectivity/common/debug_utility/ring.h new file mode 100644 index 0000000000000000000000000000000000000000..81168ce86615152d0999befe251fa5e69e292f1f --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/debug_utility/ring.h @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#ifndef _RING_H_ +#define _RING_H_ + +struct ring { + /* addr where ring buffer starts */ + void *base; + /* addr storing the next writable pos, guaranteed to be >= read except when write overflow, but it's ok. */ + unsigned int write; + /* addr storing the next readable pos, except when read == write as buffer empty */ + unsigned int read; + /* must be power of 2 */ + unsigned int max_size; +}; + +struct ring_segment { + /* addr points into ring buffer for read/write */ + void *ring_pt; + /* size to read/write */ + unsigned int sz; + /* pos in external data buffer to read/write */ + unsigned int data_pos; + /* the size to be read/write after this segment completed */ + unsigned int remain; +}; + +void ring_init(void *base, unsigned int max_size, unsigned int read, + unsigned int write, struct ring *ring); +unsigned int ring_read_prepare(unsigned int sz, struct ring_segment *seg, struct ring *ring); +#define ring_read_all_prepare(seg, ring) ring_read_prepare((ring)->max_size, seg, ring) +unsigned int ring_write_prepare(unsigned int sz, struct ring_segment *seg, struct ring *ring); +unsigned int ring_overwrite_prepare(unsigned int sz, + struct ring_segment *seg, struct ring *ring); + +/* making sure max_size is power of 2 */ +#define RING_VALIDATE_SIZE(max_size) WARN_ON(!max_size || (max_size & (max_size - 1))) + +#define RING_EMPTY(ring) ((ring)->read == (ring)->write) +/* equation works even when write overflow */ +#define RING_SIZE(ring) ((ring)->write - (ring)->read) +#define RING_FULL(ring) (RING_SIZE(ring) == (ring)->max_size) +#define RING_WRITE_REMAIN_SIZE(ring) ((ring)->max_size - RING_SIZE(ring)) + +#define RING_READ_FOR_EACH(_sz, _seg, _ring) \ + for (ring_read_prepare(_sz, &(_seg), _ring), \ + _ring_segment_prepare((_ring)->read, &(_seg), (_ring)); \ + (_seg).sz > 0; \ + _ring_read_commit(&(_seg), (_ring)), _ring_segment_prepare((_ring)->read, \ + &(_seg), (_ring))) + +#define RING_READ_ALL_FOR_EACH(seg, ring) RING_READ_FOR_EACH((ring)->max_size, seg, ring) + +#define RING_READ_FOR_EACH_ITEM(_sz, _seg, _ring) \ + for (ring_read_prepare(_sz, &(_seg), _ring), \ + _ring_segment_prepare_item((_ring)->read, &(_seg), (_ring)); \ + (_seg).sz > 0; \ + _ring_read_commit(&(_seg), (_ring)), _ring_segment_prepare_item((_ring)->read, \ + &(_seg), (_ring))) + +#define RING_WRITE_FOR_EACH(_sz, _seg, _ring) \ + for (ring_write_prepare(_sz, &(_seg), _ring),\ + _ring_segment_prepare((_ring)->write, &(_seg), (_ring)); \ + (_seg).sz > 0; \ + _ring_write_commit(&(_seg), (_ring)), _ring_segment_prepare((_ring)->write, \ + &(_seg), (_ring))) + +#define RING_OVERWRITE_FOR_EACH(_sz, _seg, _ring) \ + for (ring_overwrite_prepare(_sz, &(_seg), _ring), \ + _ring_segment_prepare((_ring)->write, &(_seg), (_ring)); \ + (_seg).sz > 0; \ + _ring_write_commit(&(_seg), (_ring)), _ring_segment_prepare((_ring)->write, \ + &(_seg), (_ring))) + +void ring_dump(const char *title, struct ring *ring); +void ring_dump_segment(const char *title, struct ring_segment *seg); + + +/* ring Buffer Internal API */ +void _ring_segment_prepare(unsigned int from, struct ring_segment *seg, struct ring *ring); +void _ring_segment_prepare_item(unsigned int from, struct ring_segment *seg, struct ring *ring); +void _ring_read_commit(struct ring_segment *seg, struct ring *ring); +void _ring_write_commit(struct ring_segment *seg, struct ring *ring); + +#endif diff --git a/drivers/misc/mediatek/connectivity/common/debug_utility/ring_emi.c b/drivers/misc/mediatek/connectivity/common/debug_utility/ring_emi.c new file mode 100644 index 0000000000000000000000000000000000000000..3d0d111dfd4c9b3dba85757e3d76cd86c38f5125 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/debug_utility/ring_emi.c @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#include "ring_emi.h" +#include +#include +#include + +void ring_emi_init(void *base, unsigned int max_size, void *read, void *write, struct ring_emi *ring_emi) +{ + WARN_ON(!base || !read || !write); + + /* making sure max_size is power of 2 */ + WARN_ON(!max_size || (max_size & (max_size - 1))); + + /* making sure read & write pointers are 4 bytes aligned */ + WARN_ON(((long)read & 0x3) != 0 || ((long)write & 0x3) != 0); + + ring_emi->base = base; + ring_emi->read = read; + ring_emi->write = write; + if (ring_emi->write) + EMI_WRITE32(ring_emi->write, 0); + if (ring_emi->read) + EMI_WRITE32(ring_emi->read, 0); + ring_emi->max_size = max_size; + pr_info("base: %p, read: %p, write: %p, max_size: %d\n", base, read, write, max_size); +} + +void ring_emi_dump(const char *title, struct ring_emi *ring_emi) +{ + pr_info("[%s] ring_emi:{base=0x%p, write=%d, read=%d, max_size=%d}\n", + title, ring_emi->base, EMI_READ32(ring_emi->write), + EMI_READ32(ring_emi->read), ring_emi->max_size); +} + +void ring_emi_dump_segment(const char *title, struct ring_emi_segment *seg) +{ + pr_info("[%s] seg:{ring_emi_pt=0x%p, data_pos=%d, sz=%d, remain=%d}\n", + title, seg->ring_emi_pt, seg->data_pos, seg->sz, seg->remain); +} + +/* + * Function prepares the ring_emi_segment and returns the number of valid bytes for read. + */ +unsigned int ring_emi_read_prepare(unsigned int sz, struct ring_emi_segment *seg, struct ring_emi *ring_emi) +{ + unsigned int wt = EMI_READ32(ring_emi->write); + unsigned int rd = EMI_READ32(ring_emi->read); + + memset(seg, 0, sizeof(struct ring_emi_segment)); +#ifdef ROUND_REPEAT + if (wt >= rd) { + if (sz > wt - rd) + sz = wt - rd; + seg->remain = sz; + } else { + if (sz > ring_emi->max_size - (rd - wt)) + sz = ring_emi->max_size - (rd - wt); + seg->remain = sz; + } +#else + if (sz > wt - rd) + sz = wt - rd; + seg->remain = sz; +#endif + /* ring_emi_dump(__func__, ring_emi); */ + /* ring_emi_dump_segment(__func__, seg); */ + return seg->remain; +} + +/* + * Function prepares the ring_emi_segment and returns the number of bytes available for write. + */ +unsigned int ring_emi_write_prepare(unsigned int sz, struct ring_emi_segment *seg, struct ring_emi *ring_emi) +{ + unsigned int wt = EMI_READ32(ring_emi->write); + unsigned int rd = EMI_READ32(ring_emi->read); + + memset(seg, 0, sizeof(struct ring_emi_segment)); +#ifdef ROUND_REPEAT + if (wt >= rd) + seg->remain = ring_emi->max_size - (wt - rd + 1); + else + seg->remain = ring_emi->max_size - (rd - wt + 1); + + if (sz <= seg->remain) + seg->remain = sz; +#else + if (sz > ring_emi->max_size - (wt - rd)) + sz = ring_emi->max_size - (wt - rd); + seg->remain = sz; +#endif + /* ring_emi_dump(__func__, ring_emi); */ + /* ring_emi_dump_segment(__func__, seg); */ + return seg->remain; +} + +void _ring_emi_segment_prepare(unsigned int from, struct ring_emi_segment *seg, struct ring_emi *ring_emi) +{ +#ifndef ROUND_REPEAT + unsigned int ring_emi_pos = from & (ring_emi->max_size - 1); + + seg->ring_emi_pt = ring_emi->base + ring_emi_pos; +#else + seg->ring_emi_pt = ring_emi->base + from; +#endif + seg->data_pos = (seg->sz ? seg->data_pos + seg->sz : 0); + if (from + seg->remain <= ring_emi->max_size) + seg->sz = seg->remain; + else + seg->sz = ring_emi->max_size - from; + seg->remain -= seg->sz; + /* ring_emi_dump(__func__, ring_emi); */ + /* ring_emi_dump_segment(__func__, seg); */ +} + +void _ring_emi_read_commit(struct ring_emi_segment *seg, struct ring_emi *ring_emi) +{ +#ifdef ROUND_REPEAT + EMI_WRITE32(ring_emi->read, (EMI_READ32(ring_emi->read) + seg->sz) & (ring_emi->max_size - 1)); +#else + EMI_WRITE32(ring_emi->read, EMI_READ32(ring_emi->read) + seg->sz); +#endif + /* *(ring_emi->read) += seg->sz; */ + /* ring_emi_dump(__func__, ring_emi); */ + /* ring_emi_dump_segment(__func__, seg); */ +} +void _ring_emi_write_commit(struct ring_emi_segment *seg, struct ring_emi *ring_emi) +{ +#ifdef ROUND_REPEAT + EMI_WRITE32(ring_emi->write, (EMI_READ32(ring_emi->write) + seg->sz) & (ring_emi->max_size - 1)); +#else + EMI_WRITE32(ring_emi->write, EMI_READ32(ring_emi->write) + seg->sz); +#endif + /* ring_emi_dump(__func__, ring_emi); */ + /* ring_emi_dump_segment(__func__, seg); */ +} + diff --git a/drivers/misc/mediatek/connectivity/common/debug_utility/ring_emi.h b/drivers/misc/mediatek/connectivity/common/debug_utility/ring_emi.h new file mode 100644 index 0000000000000000000000000000000000000000..30e9e475e7c0f8500049d73aecaede752b6070a2 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/debug_utility/ring_emi.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#ifndef _RING_EMI_H_ +#define _RING_EMI_H_ + +#include +#define ROUND_REPEAT +#define EMI_READ32(addr) (readl(addr)) +#define EMI_WRITE32(addr, data) (writel(data, addr)) + +struct ring_emi { + /* addr where ring buffer starts */ + void *base; + /* addr storing the next writable pos, guaranteed to be >= read except when write overflow, but it's ok. */ + void *write; + /* addr storing the next readable pos, except when read == write as buffer empty */ + void *read; + /* must be power of 2 */ + unsigned int max_size; +}; + +struct ring_emi_segment { + /* addr points into ring buffer for read/write */ + void *ring_emi_pt; + /* size to read/write */ + unsigned int sz; + /* pos in external data buffer to read/write */ + unsigned int data_pos; + /* the size to be read/write after this segment completed */ + unsigned int remain; +}; + +void ring_emi_init(void *base, unsigned int max_size, void *read, void *write, struct ring_emi *ring_emi); +unsigned int ring_emi_read_prepare(unsigned int sz, struct ring_emi_segment *seg, struct ring_emi *ring_emi); +#define ring_emi_read_all_prepare(seg, ring_emi) ring_emi_read_prepare((ring_emi)->max_size, seg, ring_emi) +unsigned int ring_emi_write_prepare(unsigned int sz, struct ring_emi_segment *seg, struct ring_emi *ring_emi); + +/* making sure max_size is power of 2 */ +#define RING_EMI_VALIDATE_SIZE(max_size) WARN_ON(!max_size || (max_size & (max_size - 1))) + +#define RING_EMI_EMPTY(ring_emi) (EMI_READ32((ring_emi)->read) == EMI_READ32((ring_emi)->write)) +/* equation works even when write overflow */ +#define RING_EMI_SIZE(ring_emi) (EMI_READ32((ring_emi)->write) - EMI_READ32((ring_emi)->read)) +#ifdef ROUND_REPEAT +#define RING_EMI_FULL(ring_emi) (((EMI_READ32((ring_emi)->write) + 1) & ((ring_emi)->max_size - 1)) \ + == EMI_READ32((ring_emi)->read)) +#else +#define RING_EMI_FULL(ring_emi) (RING_EMI_SIZE(ring_emi) == (ring_emi)->max_size) +#endif + +#define RING_EMI_READ_FOR_EACH(_sz, _seg, _ring_emi) \ + for (_ring_emi_segment_prepare(EMI_READ32((_ring_emi)->read), &(_seg), (_ring_emi)); \ + (_seg).sz > 0; \ + _ring_emi_read_commit(&(_seg), (_ring_emi)), \ + _ring_emi_segment_prepare(EMI_READ32((_ring_emi)->read), &(_seg), (_ring_emi))) + +#define RING_EMI_READ_ALL_FOR_EACH(seg, ring_emi) RING_EMI_READ_FOR_EACH((ring_emi)->max_size, seg, ring_emi) + +#define RING_EMI_WRITE_FOR_EACH(_sz, _seg, _ring_emi) \ + for (_ring_emi_segment_prepare(EMI_READ32((_ring_emi)->write), &(_seg), (_ring_emi)); \ + (_seg).sz > 0; \ + _ring_emi_write_commit(&(_seg), (_ring_emi)), \ + _ring_emi_segment_prepare(EMI_READ32((_ring_emi)->write), &(_seg), (_ring_emi))) + +void ring_emi_dump(const char *title, struct ring_emi *ring_emi); +void ring_emi_dump_segment(const char *title, struct ring_emi_segment *seg); + + +/* Ring Buffer Internal API */ +void _ring_emi_segment_prepare(unsigned int from, struct ring_emi_segment *seg, struct ring_emi *ring_emi); +void _ring_emi_read_commit(struct ring_emi_segment *seg, struct ring_emi *ring_emi); +void _ring_emi_write_commit(struct ring_emi_segment *seg, struct ring_emi *ring_emi); + +#endif diff --git a/drivers/misc/mediatek/connectivity/common/debug_utility/tool/connsys_log_AT/connsys_debut_utility_tester.bat b/drivers/misc/mediatek/connectivity/common/debug_utility/tool/connsys_log_AT/connsys_debut_utility_tester.bat new file mode 100644 index 0000000000000000000000000000000000000000..ad6610c04477f0569d276f4270b56fb3824195f5 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/debug_utility/tool/connsys_log_AT/connsys_debut_utility_tester.bat @@ -0,0 +1,5 @@ +SET log_path=output + +python dedicated_log_path_test.py %log_path% + +PAUSE \ No newline at end of file diff --git a/drivers/misc/mediatek/connectivity/common/debug_utility/tool/connsys_log_AT/dedicated_log_path_test.py b/drivers/misc/mediatek/connectivity/common/debug_utility/tool/connsys_log_AT/dedicated_log_path_test.py new file mode 100644 index 0000000000000000000000000000000000000000..7ce453428120e97a2acf37ff560c6922e018be89 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/debug_utility/tool/connsys_log_AT/dedicated_log_path_test.py @@ -0,0 +1,134 @@ +# +# Copyright (C) 2016 MediaTek Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. +# + +import sys, os, time +import subprocess +import re +import optparse + +emi_log = 'emi.log' +out_path = '' +MCU_INDEX = 0 +WIFI_INDEX = 1 +BT_INDEX =2 +GPS_INDEX = 3 +WMTDRV_TYPE_BT = 0 +WMTDRV_TYPE_GPS = 2 +WMTDRV_TYPE_WIFI = 3 + +def get_last_emi_log(log_fd, num_line): + log_list = [] + for line in log_fd: + if line.find('emi:') > 0: + log_list.append(line) + num_line *= -1 + return log_list[num_line:] + +def dump_emi(offset, size): + global out_path + dump_emi_init_cmd = "adb shell \"echo 0x2d " + hex(offset) + " " + hex(size) + " " + "> /proc/driver/wmt_dbg\"" + get_emi_log_cmd = "adb shell \"dmesg | grep emi\" > " + os.path.join(out_path, emi_log) + subprocess.call(dump_emi_init_cmd, shell=True) + subprocess.call(get_emi_log_cmd, shell=True) + log_fd = open(os.path.join(out_path, emi_log), 'rb') + log_list = get_last_emi_log(log_fd, 4) + log_fd.close + return log_list + +def find_base_addr(line_list): + base_addr_list = [] + count = 0 + for line in line_list: + # print line + base_addr = '' + pos = line.find('emi:') + digit_list = line[pos+4:].split(' ') + for no, dig in enumerate(digit_list, start=1): + if len(dig) == 2: + base_addr = dig + base_addr + if no % 4 == 1: + count+=1 + if count % 2 == 1: + base_addr_list.append(int(base_addr, 16)) + base_addr = '' + if count >= 8: + break + return base_addr_list + +def subsys_test(line_list, subsys_name): + for line in line_list: + base_addr = '' + count = 0 + pos = line.find('emi:') + digit_list = line[pos+4:].split(' ') + for no, dig in enumerate(digit_list, start=1): + if len(dig) == 2: + base_addr = dig + base_addr + if no % 4 == 1: + if int(base_addr, 16) > 0: + count += 1 + if count == 2: + print '------------------->' + subsys_name + ' connsys log Test PASS!' + return; + base_addr = '' + print '------------------->' + subsys_name + ' connsys log Test FAIL!' + +def subsys_fucn_ctrl(wmtdrv_type, on): + func_ctrl_cmd = "adb shell \"echo 0x07 " + hex(wmtdrv_type) + " " + hex(on) + " " + "> /proc/driver/wmt_dbg\"" + subprocess.call(func_ctrl_cmd, shell=True) + if on == 1: + time.sleep(5) + else: + time.sleep(1) + +def main(): + global out_path + out_folder = sys.argv[1] + out_path = os.path.join(os.getcwd(), out_folder) + print out_path + if(not os.path.exists(out_path)): + os.makedirs(out_path) + + line_list = dump_emi(0, 64) + base_addr_list = [] + + # TEST CASE1 INIT + if line_list[-1].find('EMIFWLOG'): + print '------------------->' + 'Connsys Debug Utility init Test PASS!' + else: + print 'EMIFWLOG not found.' + print '------------------->' + 'Connsys Debug Utility init Test FAIL!' + return + + base_addr_list = find_base_addr(line_list) + print 'subsys base address offset:' + print base_addr_list + + subsys_fucn_ctrl(WMTDRV_TYPE_WIFI, 1) + line_list = dump_emi(base_addr_list[WIFI_INDEX], 64) + subsys_test(line_list, 'WIFI') + + subsys_fucn_ctrl(WMTDRV_TYPE_BT, 1) + line_list = dump_emi(base_addr_list[BT_INDEX], 64) + subsys_test(line_list, 'BT') + + ygps_cmd = "adb shell \"am start -n com.mediatek.ygps/.YgpsActivity\"" + subprocess.call(ygps_cmd, shell=True) + time.sleep(30) + line_list = dump_emi(base_addr_list[GPS_INDEX], 64) + subsys_test(line_list, 'GPS') + ygps_cmd = "adb shell \"am force-stop com.mediatek.ygps\"" + time.sleep(1) + +if __name__ == '__main__': + main() diff --git a/drivers/misc/mediatek/connectivity/common/debug_utility/tool/connsys_log_tool/connsys_log_converter.py b/drivers/misc/mediatek/connectivity/common/debug_utility/tool/connsys_log_tool/connsys_log_converter.py new file mode 100644 index 0000000000000000000000000000000000000000..56db892dc4228e0f7a6de493de50e7fcf268b1d2 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/debug_utility/tool/connsys_log_tool/connsys_log_converter.py @@ -0,0 +1,174 @@ + +# +# Copyright (C) 2016 MediaTek Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. +# + +import sys +import re +import time +import os +import datetime +import codecs +import struct + +LogHeader = b'\x00\x00\x62' +InfoHeader = b'\x00\x25\x62' +TimeSyncLog = b'\x74\x69\x6D\x65' +LostLog = b'\x6C\x6F\x73\x74' +UTC_DIFF = 0 +UtcTime = 0 +systemTime = 0 + +# write time log +# ex: 01-01 08:34:46.372470 ( 79.231659) +def write_time_title(fh_out, utc_time, system_time): + utcTimeInt = int(utc_time) + utcTimeFrac = utc_time - utcTimeInt + systemTimeInt = int(system_time) + systemTimeFrac = system_time - systemTimeInt + fh_out.write(time.strftime("%m-%d %H:%M:%S", time.gmtime(utcTimeInt)) + ("%.6f " % utcTimeFrac)[1:] + "(%5d" % systemTimeInt + ("%.6f) " % systemTimeFrac)[1:]) + +# check time sync log +# update UTC_DIFF if utc log is chaged +def update_time_sync(fh, fh_out): + global UTC_DIFF + global UtcTime + global systemTime + fh.read(8) # skip 24 byte in header + systemTime = struct.unpack("] ... android time + +such as: +<4>[12175.130847] (0)[62:wdtk-0][cpu-0:thread:62] 2012-08-02 03:41:18.94083 UTC; android time 2012-08-02 11:41:18.94083 +<5>[25676.236787] (0)[313:InputReader][request_suspend_state]: wakeup (0->0) at 25665623103493 (2012-11-19 08:03:43.654473155 UTC) +<6>[ 344.427890] (0)[41:binder_watchdog]binder: 54296 exec 1354:1380 to 110:333 over 4.011 sec () dex_code 4 start_at 581.260 2012-01-02 00:06:18.728 +<6>[ 160.699284] (0)[44:binder_watchdog]binder: 15889 read 563:1223 to 1076:0 over 2.257 sec () dex_code 44 start_at 158.372 android 2013-04-26 21:57:28.624 +<6>[26064.469194].(4)[6320:kworker/u:1]PM: suspend exit 2013-10-12 06:18:48.551577654 UTC +[ 5.219499] .(2)[1:swapper/0]mt-rtc mt-rtc: setting system clock to 2018-01-25 01:24:36 UTC (1516843476) +[ 67.101501] .(1)[249:wdtk-1][name:wd_common_drv&][thread:249][RT:67101493390] 2018-01-25 01:25:38.382875 UTC;android time 2018-01-25 01:25:38.382875 + +''' + +import sys +import re +import time +import os +import datetime +from bisect import bisect_right + +def kernel_to_utc(klog, llog): + # if llog == '-', output to stdout + line = 0 + line_timestamp = [] + diff_timestamp = [] + debug_enable = False + _stdout = True if llog == '-' else False + + # first pass + try: + fh = open(klog, "rb") + if _stdout: + fhout = sys.stdout + else: + fhout = open(llog, "w") + except IOError as err: + print err + sys.exit() + + _re_utc_time = re.compile(r"[^\[]*?\[[ ]*(\d+?\.\d+)\].*?(\d+-\d+-\d+ \d+:\d+:\d+)(\.\d+) UTC") + + for linebuf in fh: + line = line + 1 + + if "UTC" not in linebuf: + continue + + m = _re_utc_time.match(linebuf) + if m: + (ktime, atime, usec) = m.group(1,2,3) + time_sec_int = time.mktime(time.strptime(atime, "%Y-%m-%d %H:%M:%S")) + time_sec = time_sec_int + float(usec) - float(ktime) + + if (debug_enable): + print "*" + print linebuf + print ktime, atime, usec + + line_timestamp.append(line) + diff_timestamp.append(time_sec) + + + # second pass + fh.seek(0, os.SEEK_SET) + + if debug_enable: + print len(line_timestamp),",",len(diff_timestamp) + print line_timestamp + print diff_timestamp + + line_ts_ref = -1 + diff_ts_ref = 0 + + # in case no timestamp exist + if line_timestamp: + line_ts_ref = line_timestamp[0] + diff_ts_ref = diff_timestamp[0] + + # _re_ktime = re.compile(r"^[ ]*?<[^>]+>\[[ ]*?(\d+?\.\d+?)\]") + _re_ktime = re.compile(r"^[^\[]*?\[[ ]*?(\d+?\.\d+?)\]") + + line = 0 + for linebuf in fh: + diff_ts = -1 + line = line + 1 + + m = _re_ktime.match(linebuf) + if m: + diff_ts = float(m.group(1)) + + if line == line_ts_ref: + line_timestamp.pop(0) + line_ts_ref = line_timestamp[0] if line_timestamp else sys.maxint + diff_ts_ref = diff_timestamp.pop(0) + + if debug_enable: print "diff_ts_ref: ", diff_ts_ref + + if diff_ts != -1: + if line_ts_ref != -1: + android_time = diff_ts + diff_ts_ref + android_time_int = int(android_time) + android_time_frac = android_time - android_time_int + + ts = time.localtime(android_time_int) + + fhout.write(time.strftime("%m-%d %H:%M:%S", ts) + ("%.6f " % android_time_frac)[1:]) + else: + fhout.write("??-?? ??:??:??.?????? ") + + fhout.write(linebuf) + + # for debug + # print linebuf, + + try: + fhout.close() + if not _stdout: + fh.close() + except IOError as err: + print err + sys.exit() + + +if __name__ == "__main__": + if (len(sys.argv) not in [2, 3]): + print "Usage: ", sys.argv[0], " [-]" + sys.exit() + + _stdout = False + if len(sys.argv) == 3 and sys.argv[2] == '-': + _stdout = True + + if _stdout: + kernel_to_utc(sys.argv[1],'-') + else: + kernel_to_utc(sys.argv[1],sys.argv[1]+".utc") + sys.exit() diff --git a/drivers/misc/mediatek/connectivity/common/init.wmt_drv.rc b/drivers/misc/mediatek/connectivity/common/init.wmt_drv.rc new file mode 100644 index 0000000000000000000000000000000000000000..732a4cd8c3b27f0280f83b6c15cd09ab49b07650 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/init.wmt_drv.rc @@ -0,0 +1,2 @@ +on boot + insmod /vendor/lib/modules/wmt_drv.ko diff --git a/drivers/misc/mediatek/connectivity/common/test/include/wmt_step_test.h b/drivers/misc/mediatek/connectivity/common/test/include/wmt_step_test.h new file mode 100644 index 0000000000000000000000000000000000000000..c8de0418cac7766d84d5b3dc5210cbf577157ff7 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/test/include/wmt_step_test.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2016 MediaTek Inc. * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +#ifndef _WMT_STEP_TEST_H_ +#define _WMT_STEP_TEST_H_ + +#include "osal.h" +#include "wmt_step.h" + +#define STEP_TEST_CONSYS_EMI_WMT_OFFSET 0x68000 + +#define TEST_FAIL -1 +#define TEST_PASS 0 +#define TEST_CHECK 1 +#define STEP_TEST_ACTION_NUMBER 30 + +extern struct step_env_struct g_step_env; +extern struct platform_device *g_pdev; + +struct step_test_report { + unsigned int pass; + unsigned int fail; + unsigned int check; +}; + +struct step_test_check { + unsigned int step_check_total; + int step_check_test_tp_id[STEP_TEST_ACTION_NUMBER]; + int step_check_test_act_id[STEP_TEST_ACTION_NUMBER]; + char *step_check_params[STEP_TEST_ACTION_NUMBER][STEP_PARAMETER_SIZE]; + int step_check_params_num[STEP_TEST_ACTION_NUMBER]; + unsigned int step_check_index; + int step_check_result; + char *step_check_result_string; + int step_check_result_value; + unsigned int step_check_emi_offset[STEP_TEST_ACTION_NUMBER]; + SIZE_T step_check_register_addr; + SIZE_T step_check_write_value; + unsigned int step_test_mask; + unsigned int step_recovery_value; + int step_check_temp_register_id; +}; + +void wmt_step_test_all(void); +void wmt_step_test_read_file(struct step_test_report *p_report); +void wmt_step_test_parse_data(struct step_test_report *p_report); +void wmt_step_test_create_emi_action(struct step_test_report *p_report); +void wmt_step_test_create_cond_emi_action(struct step_test_report *p_report); +void wmt_step_test_create_register_action(struct step_test_report *p_report); +void wmt_step_test_create_cond_register_action(struct step_test_report *p_report); +void wmt_step_test_check_register_symbol(struct step_test_report *p_report); +void wmt_step_test_create_other_action(struct step_test_report *p_report); +void wmt_step_test_do_emi_action(struct step_test_report *p_report); +void wmt_step_test_do_cond_emi_action(struct step_test_report *p_report); +void wmt_step_test_do_register_action(struct step_test_report *p_report); +void wmt_step_test_do_cond_register_action(struct step_test_report *p_report); +void wmt_step_test_do_gpio_action(struct step_test_report *p_report); +void wmt_step_test_do_disable_reset_action(struct step_test_report *p_report); +void wmt_step_test_do_chip_reset_action(struct step_test_report *p_report); +void wmt_step_test_do_wakeup_action(struct step_test_report *p_report); +void wmt_step_test_create_periodic_dump(struct step_test_report *p_report); +void wmt_step_test_do_show_action(struct step_test_report *p_report); +void wmt_step_test_do_sleep_action(struct step_test_report *p_report); +void wmt_step_test_do_condition_action(struct step_test_report *p_report); +void wmt_step_test_do_value_action(struct step_test_report *p_report); + +#endif /* end of _WMT_STEP_TEST_H_ */ + diff --git a/drivers/misc/mediatek/connectivity/common/test/wmt_step_test.c b/drivers/misc/mediatek/connectivity/common/test/wmt_step_test.c new file mode 100644 index 0000000000000000000000000000000000000000..f28a2b1a40c335b1f197de1b8cabfa483b46f9c1 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/common/test/wmt_step_test.c @@ -0,0 +1,4966 @@ +/* + * Copyright (C) 2016 MediaTek Inc. * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +#include +#include "osal.h" +#include "wmt_step_test.h" +#include "wmt_step.h" +#include "wmt_exp.h" +#include "wmt_lib.h" +#include "mtk_wcn_consys_hw.h" +#include "stp_core.h" +#include "wmt_dbg.h" + +struct step_test_check g_step_test_check; + +void wmt_step_test_clear_parameter(char *params[]) +{ + int i = 0; + + for (i = 0; i < STEP_PARAMETER_SIZE; i++) + params[i] = NULL; +} + +#define index_of_array(current_addr, base_addr, type) \ + (((unsigned long)current_addr - (unsigned long)base_addr) / sizeof(type)) + +int wmt_step_test_check_write_tp(struct step_action_list *p_act_list, enum step_action_id act_id, + int param_num, char *params[]) +{ + int index = g_step_test_check.step_check_index; + int i; + int tp_id; + + if (g_step_test_check.step_check_result == TEST_FAIL) + return 0; + + if (index < 0) + return 0; + + g_step_test_check.step_check_index++; + + if (g_step_test_check.step_check_test_tp_id[index] != -1) { + tp_id = index_of_array(p_act_list, &g_step_env.actions, struct step_action_list); + if (tp_id != g_step_test_check.step_check_test_tp_id[index]) { + g_step_test_check.step_check_result = TEST_FAIL; + WMT_ERR_FUNC("STEP test failed: tp_id %d: expect %d(%d)\n", tp_id, + g_step_test_check.step_check_test_tp_id[index], index); + return 0; + } + } + + if (act_id != g_step_test_check.step_check_test_act_id[index]) { + g_step_test_check.step_check_result = TEST_FAIL; + WMT_ERR_FUNC("STEP test failed: act_id %d: expect %d(%d)\n", act_id, + g_step_test_check.step_check_test_tp_id[index], index); + return 0; + } + + if (param_num != g_step_test_check.step_check_params_num[index]) { + g_step_test_check.step_check_result = TEST_FAIL; + WMT_ERR_FUNC("STEP test failed: param num %d: expect %d(%d)\n", param_num, + g_step_test_check.step_check_params_num[index], index); + return 0; + } + + for (i = 0; i < STEP_PARAMETER_SIZE; i++) { + if (osal_strcmp(g_step_test_check.step_check_params[index][0], "") == 0) + break; + + if (params[0] == NULL || osal_strcmp(params[0], g_step_test_check.step_check_params[index][0]) != 0) { + g_step_test_check.step_check_result = TEST_FAIL; + WMT_ERR_FUNC("STEP test failed: params[%d] %s: expect %s(%d)\n", i, params[0], + g_step_test_check.step_check_params[index][0], index); + return 0; + } + } + + g_step_test_check.step_check_result = TEST_PASS; + + return 0; +} + +int wmt_step_test_check_create_emi(struct step_emi_action *p_emi_act, int check_params[], + char *err_result) +{ + struct step_emi_info *p_emi_info = NULL; + int result = TEST_FAIL; + + p_emi_info = &p_emi_act->info; + if (p_emi_act->base.action_id != STEP_ACTION_INDEX_EMI) { + WMT_ERR_FUNC("%s, id wrong: %d\n", err_result, p_emi_act->base.action_id); + result = TEST_FAIL; + } else if (p_emi_info->output_mode == STEP_OUTPUT_LOG) { + if (p_emi_info->is_write != check_params[0] || + p_emi_info->begin_offset != check_params[1] || + p_emi_info->end_offset != check_params[2]) { + WMT_ERR_FUNC("%s, C1 emi log params: %d, %d, %d\n", + err_result, p_emi_info->is_write, p_emi_info->begin_offset, + p_emi_info->end_offset); + result = TEST_FAIL; + } else { + result = TEST_PASS; + } + } else if (p_emi_info->output_mode == STEP_OUTPUT_REGISTER) { + if (p_emi_info->is_write != check_params[0] || + p_emi_info->begin_offset != check_params[1] || + p_emi_info->mask != check_params[2] || + p_emi_info->temp_reg_id != check_params[3]) { + WMT_ERR_FUNC("%s, C2 emi reg params: %d, %d, %d, %d\n", + err_result, p_emi_info->is_write, p_emi_info->begin_offset, + p_emi_info->mask, p_emi_info->temp_reg_id); + result = TEST_FAIL; + } else { + result = TEST_PASS; + } + } else { + result = TEST_FAIL; + } + + return result; +} + +int wmt_step_test_check_create_condition_emi(struct step_condition_emi_action *p_cond_emi_act, int check_params[], + char *err_result) +{ + struct step_emi_info *p_emi_info = NULL; + int result = TEST_FAIL; + + p_emi_info = &p_cond_emi_act->info; + if (p_cond_emi_act->base.action_id != STEP_ACTION_INDEX_CONDITION_EMI) { + WMT_ERR_FUNC("%s, id wrong: %d\n", err_result, p_cond_emi_act->base.action_id); + result = TEST_FAIL; + } else if (p_emi_info->output_mode == STEP_OUTPUT_LOG) { + if (p_cond_emi_act->cond_reg_id != check_params[0] || + p_emi_info->is_write != check_params[1] || + p_emi_info->begin_offset != check_params[2] || + p_emi_info->end_offset != check_params[3]) { + WMT_ERR_FUNC("%s, C1 emi log params: %d, %d, %d, %d\n", + err_result, p_cond_emi_act->cond_reg_id, p_emi_info->is_write, + p_emi_info->begin_offset, p_emi_info->end_offset); + result = TEST_FAIL; + } else { + result = TEST_PASS; + } + } else if (p_emi_info->output_mode == STEP_OUTPUT_REGISTER) { + if (p_cond_emi_act->cond_reg_id != check_params[0] || + p_emi_info->is_write != check_params[1] || + p_emi_info->begin_offset != check_params[2] || + p_emi_info->mask != check_params[3] || + p_emi_info->temp_reg_id != check_params[4]) { + WMT_ERR_FUNC("%s, C2 emi reg params: %d, %d, %d, %d, %d\n", + err_result, p_cond_emi_act->cond_reg_id, p_emi_info->is_write, + p_emi_info->begin_offset, p_emi_info->mask, p_emi_info->temp_reg_id); + result = TEST_FAIL; + } else { + result = TEST_PASS; + } + } else { + result = TEST_FAIL; + } + + return result; +} + +int wmt_step_test_check_create_read_reg(struct step_reigster_info *p_reg_info, + int check_params[], char *err_result, int check_index) +{ + int result = TEST_FAIL; + + if (p_reg_info->address_type == STEP_REGISTER_PHYSICAL_ADDRESS) { + if (p_reg_info->address != check_params[check_index + 1] || + p_reg_info->offset != check_params[check_index + 2]) { + WMT_ERR_FUNC( + "%s, C1 reg params: %d, 0x%08x, %d\n", + err_result, p_reg_info->is_write, (unsigned int)p_reg_info->address, + p_reg_info->offset); + return TEST_FAIL; + } + } else { + if (p_reg_info->address_type != check_params[check_index + 1] || + p_reg_info->offset != check_params[check_index + 2]) { + WMT_ERR_FUNC( + "%s, C2 reg params: %d, 0x%08x, %d\n", + err_result, p_reg_info->is_write, (unsigned int)p_reg_info->address, + p_reg_info->offset); + return TEST_FAIL; + } + } + + if (p_reg_info->output_mode == STEP_OUTPUT_LOG) { + if (p_reg_info->times != check_params[check_index + 3] || + p_reg_info->delay_time != check_params[check_index + 4]) { + WMT_ERR_FUNC( + "%s, C3 reg params: %d, 0x%08x, %d, %d, %d\n", + err_result, p_reg_info->is_write, (unsigned int)p_reg_info->address, + p_reg_info->offset, p_reg_info->times, p_reg_info->delay_time); + result = TEST_FAIL; + } else { + result = TEST_PASS; + } + } else if (p_reg_info->output_mode == STEP_OUTPUT_REGISTER) { + if (p_reg_info->mask != check_params[check_index + 3] || + p_reg_info->temp_reg_id != check_params[check_index + 4]) { + WMT_ERR_FUNC( + "%s, C4 reg params: %d, 0x%08x, %d, %d, %d\n", + err_result, p_reg_info->is_write, (unsigned int)p_reg_info->address, + p_reg_info->offset, p_reg_info->mask, p_reg_info->temp_reg_id); + result = TEST_FAIL; + } else { + result = TEST_PASS; + } + } else { + result = TEST_FAIL; + } + + return result; +} + +int wmt_step_test_check_create_write_reg(struct step_reigster_info *p_reg_info, + int check_params[], char *err_result, int check_index) +{ + int result = TEST_FAIL; + + if (p_reg_info->address_type == STEP_REGISTER_PHYSICAL_ADDRESS) { + if (p_reg_info->address != check_params[check_index + 1] || + p_reg_info->offset != check_params[check_index + 2] || + p_reg_info->value != check_params[check_index + 3]) { + WMT_ERR_FUNC( + "%s, C1 reg params: %d, 0x%08x, %d, %d\n", + err_result, p_reg_info->is_write, (unsigned int)p_reg_info->address, + p_reg_info->offset, p_reg_info->value); + result = TEST_FAIL; + } else { + result = TEST_PASS; + } + } else { + if (p_reg_info->address_type != check_params[check_index + 1] || + p_reg_info->offset != check_params[check_index + 2] || + p_reg_info->value != check_params[check_index + 3]) { + WMT_ERR_FUNC( + "%s, C2 reg params: %d, %d, %d, %d\n", + err_result, p_reg_info->is_write, p_reg_info->address_type, + p_reg_info->offset, p_reg_info->value); + result = TEST_FAIL; + } else { + result = TEST_PASS; + } + } + + return result; +} + +int wmt_step_test_check_create_reg(struct step_register_action *p_reg_act, int check_params[], + char *err_result) +{ + struct step_reigster_info *p_reg_info = NULL; + int result = TEST_FAIL; + + p_reg_info = &p_reg_act->info; + if (p_reg_act->base.action_id != STEP_ACTION_INDEX_REGISTER) { + WMT_ERR_FUNC("%s, id wrong: %d\n", err_result, p_reg_act->base.action_id); + result = TEST_FAIL; + } else if (p_reg_info->is_write != check_params[0]) { + WMT_ERR_FUNC("%s, write failed: %d expect(%d)", err_result, p_reg_info->is_write, check_params[0]); + result = TEST_FAIL; + } else { + if (p_reg_info->is_write == 0) + result = wmt_step_test_check_create_read_reg(p_reg_info, check_params, err_result, 0); + else + result = wmt_step_test_check_create_write_reg(p_reg_info, check_params, err_result, 0); + } + + return result; +} + +int wmt_step_test_check_create_condition_reg(struct step_condition_register_action *p_cond_reg_act, int check_params[], + char *err_result) +{ + struct step_reigster_info *p_reg_info = NULL; + int result = TEST_FAIL; + + p_reg_info = &p_cond_reg_act->info; + if (p_cond_reg_act->base.action_id != STEP_ACTION_INDEX_CONDITION_REGISTER) { + WMT_ERR_FUNC("%s, id wrong: %d\n", err_result, p_cond_reg_act->base.action_id); + result = TEST_FAIL; + } else if (p_cond_reg_act->cond_reg_id != check_params[0]) { + WMT_ERR_FUNC("%s, reg id failed: %d expect(%d)", err_result, + p_cond_reg_act->cond_reg_id, check_params[0]); + result = TEST_FAIL; + } else if (p_reg_info->is_write != check_params[1]) { + WMT_ERR_FUNC("%s, write failed: %d expect(%d)", err_result, + p_reg_info->is_write, check_params[1]); + result = TEST_FAIL; + } else { + if (p_reg_info->is_write == 0) + result = wmt_step_test_check_create_read_reg(p_reg_info, check_params, err_result, 1); + else + result = wmt_step_test_check_create_write_reg(p_reg_info, check_params, err_result, 1); + } + + return result; +} + +int wmt_step_test_check_create_gpio(struct step_gpio_action *p_gpio_act, int check_params[], + char *err_result) +{ + int result = TEST_FAIL; + + if (p_gpio_act->base.action_id != STEP_ACTION_INDEX_GPIO) { + WMT_ERR_FUNC("%s, id wrong: %d\n", err_result, p_gpio_act->base.action_id); + result = TEST_FAIL; + } else if (p_gpio_act->is_write != check_params[0]) { + WMT_ERR_FUNC("%s, write failed: %d", err_result, p_gpio_act->is_write); + result = TEST_FAIL; + } else { + if (p_gpio_act->pin_symbol != check_params[1]) { + WMT_ERR_FUNC("%s, gpio params: %d, %d\n", + err_result, p_gpio_act->is_write, p_gpio_act->pin_symbol); + result = TEST_FAIL; + } else { + result = TEST_PASS; + } + } + + return result; +} + +int wmt_step_test_check_create_drst(struct step_disable_reset_action *p_drst_act, int check_params[], + char *err_result) +{ + int result = TEST_FAIL; + + if (p_drst_act->base.action_id != STEP_ACTION_INDEX_DISABLE_RESET) { + WMT_ERR_FUNC("%s, id wrong: %d\n", err_result, p_drst_act->base.action_id); + result = TEST_FAIL; + } else { + result = TEST_PASS; + } + + return result; +} + +int wmt_step_test_check_create_crst(struct step_chip_reset_action *p_crst_act, int check_params[], + char *err_result) +{ + int result = TEST_FAIL; + + if (p_crst_act->base.action_id != STEP_ACTION_INDEX_CHIP_RESET) { + WMT_ERR_FUNC("%s, id wrong: %d\n", err_result, p_crst_act->base.action_id); + result = TEST_FAIL; + } else { + result = TEST_PASS; + } + + return result; +} + +int wmt_step_test_check_create_keep_wakeup(struct step_keep_wakeup_action *p_kwak_act, + int check_params[], char *err_result) +{ + int result = TEST_FAIL; + + if (p_kwak_act->base.action_id != STEP_ACTION_INDEX_KEEP_WAKEUP) { + WMT_ERR_FUNC("%s, id wrong: %d\n", err_result, p_kwak_act->base.action_id); + result = TEST_FAIL; + } else { + result = TEST_PASS; + } + + return result; +} + +int wmt_step_test_check_create_cancel_wakeup(struct step_cancel_wakeup_action *p_cwak_act, + int check_params[], char *err_result) +{ + int result = TEST_FAIL; + + if (p_cwak_act->base.action_id != STEP_ACTION_INDEX_CANCEL_WAKEUP) { + WMT_ERR_FUNC("%s, id wrong: %d\n", err_result, p_cwak_act->base.action_id); + result = TEST_FAIL; + } else { + result = TEST_PASS; + } + + return result; +} + +int wmt_step_test_check_create_periodic_dump(struct step_periodic_dump_action *p_pd_act, + int check_params[], char *err_result) +{ + int result = TEST_FAIL; + + if (p_pd_act->base.action_id != STEP_ACTION_INDEX_PERIODIC_DUMP) { + WMT_ERR_FUNC("%s, id wrong: %d\n", err_result, p_pd_act->base.action_id); + result = TEST_FAIL; + } else { + result = TEST_PASS; + } + + return result; +} + +int wmt_step_test_check_create_show_string(struct step_show_string_action *p_show_act, + int check_params[], char *err_result) +{ + int result = TEST_FAIL; + + if (p_show_act->base.action_id != STEP_ACTION_INDEX_SHOW_STRING) { + WMT_ERR_FUNC("%s, id wrong: %d\n", err_result, p_show_act->base.action_id); + result = TEST_FAIL; + } else { + result = TEST_PASS; + } + + return result; +} + +int wmt_step_test_check_create_sleep(struct step_sleep_action *p_sleep_act, + int check_params[], char *err_result) +{ + int result = TEST_FAIL; + + if (p_sleep_act->base.action_id != STEP_ACTION_INDEX_SLEEP) { + WMT_ERR_FUNC("%s, id wrong: %d\n", err_result, p_sleep_act->base.action_id); + result = TEST_FAIL; + } else if (p_sleep_act->ms != check_params[0]) { + WMT_ERR_FUNC("%s, param failed: %d expect(%d)", err_result, p_sleep_act->ms, check_params[0]); + result = TEST_FAIL; + } else { + result = TEST_PASS; + } + + return result; +} + +int wmt_step_test_check_create_condition(struct step_condition_action *p_cond_act, + int check_params[], char *err_result) +{ + int result = TEST_FAIL; + + if (p_cond_act->base.action_id != STEP_ACTION_INDEX_CONDITION) { + WMT_ERR_FUNC("%s, id wrong: %d\n", err_result, p_cond_act->base.action_id); + result = TEST_FAIL; + } else if (p_cond_act->result_temp_reg_id != check_params[0] || + p_cond_act->l_temp_reg_id != check_params[1] || + p_cond_act->operator_id != check_params[2]) { + WMT_ERR_FUNC("%s, C1 param failed: %d %d %d %d expect(%d %d %d %d)", + err_result, p_cond_act->result_temp_reg_id, p_cond_act->l_temp_reg_id, + p_cond_act->operator_id, p_cond_act->r_temp_reg_id, + check_params[0], check_params[1], check_params[2], check_params[3]); + result = TEST_FAIL; + } else { + if (p_cond_act->mode == STEP_CONDITION_RIGHT_REGISTER && p_cond_act->r_temp_reg_id != check_params[3]) { + WMT_ERR_FUNC("%s, C2 param failed: %d %d %d %d expect(%d %d %d %d)", + err_result, p_cond_act->result_temp_reg_id, p_cond_act->l_temp_reg_id, + p_cond_act->operator_id, p_cond_act->r_temp_reg_id, + check_params[0], check_params[1], check_params[2], check_params[3]); + result = TEST_FAIL; + } else if (p_cond_act->mode == STEP_CONDITION_RIGHT_VALUE && p_cond_act->value != check_params[3]) { + WMT_ERR_FUNC("%s, C3 param failed: %d %d %d %d expect(%d %d %d %d)", + err_result, p_cond_act->result_temp_reg_id, p_cond_act->l_temp_reg_id, + p_cond_act->operator_id, p_cond_act->value, + check_params[0], check_params[1], check_params[2], check_params[3]); + result = TEST_FAIL; + } else { + result = TEST_PASS; + } + } + + return result; +} + +int wmt_step_test_check_create_value(struct step_value_action *p_val_act, + int check_params[], char *err_result) +{ + int result = TEST_FAIL; + + if (p_val_act->base.action_id != STEP_ACTION_INDEX_VALUE) { + WMT_ERR_FUNC("%s, id wrong: %d\n", err_result, p_val_act->base.action_id); + result = TEST_FAIL; + } else if (p_val_act->temp_reg_id != check_params[0] || + p_val_act->value != check_params[1]) { + WMT_ERR_FUNC("%s, param failed: %d %d expect(%d %d)", + err_result, p_val_act->temp_reg_id, p_val_act->value, + check_params[0], check_params[1]); + result = TEST_FAIL; + } else { + result = TEST_PASS; + } + + return result; +} + +void wmt_step_test_check_emi_act(unsigned int len, ...) +{ + unsigned int offset; + unsigned int check_result; + unsigned int value; + PUINT8 p_virtual_addr = NULL; + va_list args; + + if (g_step_test_check.step_check_result == TEST_FAIL) + return; + + offset = g_step_test_check.step_check_emi_offset[g_step_test_check.step_check_index]; + p_virtual_addr = wmt_plat_get_emi_virt_add(offset); + if (!p_virtual_addr) { + g_step_test_check.step_check_result = TEST_FAIL; + WMT_ERR_FUNC("STEP test failed: p_virtual_addr offset(%d) is null", offset); + return; + } + check_result = CONSYS_REG_READ(p_virtual_addr); + + va_start(args, len); + value = va_arg(args, unsigned int); + va_end(args); + + if (check_result == value) { + g_step_test_check.step_check_result = TEST_PASS; + } else { + WMT_ERR_FUNC("STEP test failed: Value is %d, expect %d", value, check_result); + g_step_test_check.step_check_result = TEST_FAIL; + return; + } + + if (g_step_test_check.step_check_temp_register_id != -1) { + if (g_step_env.temp_register[g_step_test_check.step_check_temp_register_id] != + (check_result & g_step_test_check.step_test_mask)) { + WMT_ERR_FUNC("STEP test failed: Register id(%d) value is %d, expect %d mask 0x%08x", + g_step_test_check.step_check_temp_register_id, + g_step_env.temp_register[g_step_test_check.step_check_temp_register_id], + check_result, g_step_test_check.step_test_mask); + g_step_test_check.step_check_result = TEST_FAIL; + } + } + + g_step_test_check.step_check_index++; +} + +void wmt_step_test_check_reg_read_act(unsigned int len, ...) +{ + unsigned int check_result; + unsigned int value; + va_list args; + + if (g_step_test_check.step_check_result == TEST_FAIL) + return; + + va_start(args, len); + value = va_arg(args, unsigned int); + check_result = CONSYS_REG_READ(g_step_test_check.step_check_register_addr); + + if (check_result == value) { + g_step_test_check.step_check_result = TEST_PASS; + } else { + WMT_ERR_FUNC("STEP test failed: Value is %d, expect %d(0x%08x)", value, check_result, + (unsigned int)g_step_test_check.step_check_register_addr); + g_step_test_check.step_check_result = TEST_FAIL; + } + + if (g_step_test_check.step_check_temp_register_id != -1) { + if (g_step_env.temp_register[g_step_test_check.step_check_temp_register_id] != + (check_result & g_step_test_check.step_test_mask)) { + WMT_ERR_FUNC("STEP test failed: Register id(%d) value is %d, expect %d", + g_step_test_check.step_check_temp_register_id, + g_step_env.temp_register[g_step_test_check.step_check_temp_register_id], + check_result); + g_step_test_check.step_check_result = TEST_FAIL; + } + } + + va_end(args); +} + +void wmt_step_test_check_reg_write_act(unsigned int len, ...) +{ + unsigned int value; + va_list args; + unsigned int mask = g_step_test_check.step_test_mask; + + va_start(args, len); + value = va_arg(args, unsigned int); + + if (value == 0xdeadfeed) { + g_step_test_check.step_check_result = TEST_PASS; + } else if (mask == 0xFFFFFFFF) { + if (g_step_test_check.step_check_write_value == value) { + g_step_test_check.step_check_result = TEST_PASS; + } else { + WMT_ERR_FUNC("STEP test failed: Value is %d, expect %zu", value, + g_step_test_check.step_check_write_value); + g_step_test_check.step_check_result = TEST_FAIL; + } + } else { + if ((mask & value) != (mask & g_step_test_check.step_check_write_value)) { + WMT_ERR_FUNC("STEP test failed: Overrite:%d, expect:%zu origin %d mask %d", + value, + g_step_test_check.step_check_write_value, + g_step_test_check.step_recovery_value, + mask); + g_step_test_check.step_check_result = TEST_FAIL; + } else if ((~mask & value) != (~mask & g_step_test_check.step_recovery_value)) { + WMT_ERR_FUNC("STEP test failed: No change:%d, expect:%zu origin %d mask %d", + value, + g_step_test_check.step_check_write_value, + g_step_test_check.step_recovery_value, + mask); + g_step_test_check.step_check_result = TEST_FAIL; + } else { + g_step_test_check.step_check_result = TEST_PASS; + } + } + + va_end(args); +} + +void wmt_step_test_check_show_act(unsigned int len, ...) +{ + char *content = NULL; + va_list args; + + va_start(args, len); + content = va_arg(args, char*); + if (content == NULL || g_step_test_check.step_check_result_string == NULL) { + WMT_ERR_FUNC("STEP test failed: content is NULL"); + g_step_test_check.step_check_result = TEST_FAIL; + } else if (osal_strcmp(content, g_step_test_check.step_check_result_string) == 0) { + g_step_test_check.step_check_result = TEST_PASS; + } else { + WMT_ERR_FUNC("STEP test failed: content(%s), expect(%s)", + content, g_step_test_check.step_check_result_string); + g_step_test_check.step_check_result = TEST_FAIL; + } + va_end(args); +} + +void wmt_step_test_check_condition_act(unsigned int len, ...) +{ + int value; + va_list args; + + va_start(args, len); + value = va_arg(args, int); + if (value == g_step_test_check.step_check_result_value) { + g_step_test_check.step_check_result = TEST_PASS; + } else { + WMT_ERR_FUNC("STEP test failed: value(%d), expect(%d)", + value, g_step_test_check.step_check_result_value); + g_step_test_check.step_check_result = TEST_FAIL; + } + va_end(args); +} + +void wmt_step_test_check_value_act(unsigned int len, ...) +{ + int value; + va_list args; + + va_start(args, len); + value = va_arg(args, int); + if (value == g_step_test_check.step_check_result_value) { + g_step_test_check.step_check_result = TEST_PASS; + } else { + WMT_ERR_FUNC("STEP test failed: value(%d), expect(%d)", + value, g_step_test_check.step_check_result_value); + g_step_test_check.step_check_result = TEST_FAIL; + } + va_end(args); +} + +void wmt_step_test_clear_check_data(void) +{ + unsigned int i = 0, j = 0; + + for (i = 0; i < STEP_TEST_ACTION_NUMBER; i++) { + g_step_test_check.step_check_test_tp_id[i] = 0; + g_step_test_check.step_check_test_act_id[i] = 0; + g_step_test_check.step_check_params_num[i] = 0; + g_step_test_check.step_check_emi_offset[i] = 0; + for (j = 0; j < STEP_PARAMETER_SIZE; j++) + g_step_test_check.step_check_params[i][j] = ""; + } + + g_step_test_check.step_check_total = 0; + g_step_test_check.step_check_index = 0; + g_step_test_check.step_check_result = TEST_PASS; + g_step_test_check.step_check_register_addr = 0; + g_step_test_check.step_test_mask = 0xFFFFFFFF; + g_step_test_check.step_recovery_value = 0; + g_step_test_check.step_check_result_value = 0; + g_step_test_check.step_check_temp_register_id = -1; +} + +void wmt_step_test_clear_temp_register(void) +{ + int i; + + for (i = 0; i < STEP_TEMP_REGISTER_SIZE; i++) + g_step_env.temp_register[i] = 0; +} + +#define STEP_CAN_WRITE_UNKNOWN 0 +#define STEP_CAN_WRITE_YES 1 +#define STEP_CAN_WRITE_NO 2 +int wmt_step_test_is_can_write(SIZE_T addr, unsigned int mask) +{ + unsigned int before, after; + int ret = STEP_CAN_WRITE_UNKNOWN; + + before = CONSYS_REG_READ(addr); + CONSYS_REG_WRITE_MASK(addr, 0xFFFFFFFF, mask); + after = CONSYS_REG_READ(addr); + if ((after & mask) != (0xFFFFFFFF & mask)) + ret = STEP_CAN_WRITE_NO; + + CONSYS_REG_WRITE_MASK(addr, 0x0, mask); + after = CONSYS_REG_READ(addr); + if ((after & mask) != (0x0 & mask)) + ret = STEP_CAN_WRITE_NO; + + CONSYS_REG_WRITE_MASK(addr, before, mask); + if (ret != STEP_CAN_WRITE_NO) + ret = STEP_CAN_WRITE_YES; + + return ret; +} + +int wmt_step_test_find_can_write_register(SIZE_T addr, int max, unsigned int mask) +{ + int i; + int write_able; + + if (DISABLE_PSM_MONITOR()) { + WMT_ERR_FUNC("wake up failed\n"); + return -1; + } + + for (i = 0x0; i < max; i += 0x4) { + write_able = wmt_step_test_is_can_write(addr + i, mask); + if (write_able == STEP_CAN_WRITE_YES) { + ENABLE_PSM_MONITOR(); + return i; + } + } + ENABLE_PSM_MONITOR(); + + return -1; +} + +void wmt_step_test_update_result(int result, struct step_test_report *p_report, char *err_result) +{ + if (result != TEST_FAIL) { + p_report->pass++; + } else { + WMT_ERR_FUNC("%s", err_result); + p_report->fail++; + } +} + +void wmt_step_test_update_result_report(struct step_test_report *p_dest_report, + struct step_test_report *p_src_report) +{ + p_dest_report->pass += p_src_report->pass; + p_dest_report->fail += p_src_report->fail; + p_dest_report->check += p_src_report->check; +} + +void wmt_step_test_show_result_report(char *test_name, struct step_test_report *p_report, int sec_begin, int usec_begin, + int sec_end, int usec_end) +{ + unsigned int total = 0; + unsigned int pass = 0; + unsigned int fail = 0; + unsigned int check = 0; + int sec = 0; + int usec = 0; + + pass = p_report->pass; + fail = p_report->fail; + check = p_report->check; + + if (usec_end >= usec_begin) { + sec = sec_end - sec_begin; + usec = usec_end - usec_begin; + } else { + sec = sec_end - sec_begin - 1; + usec = usec_end - usec_begin + 1000000; + } + + total = pass + fail + check; + WMT_INFO_FUNC("%s Total: %d, PASS: %d, FAIL: %d, CHECK: %d, Spend Time: %d.%.6d\n", + test_name, total, pass, fail, check, sec, usec); +} + +void __wmt_step_test_parse_data(const char *buf, struct step_test_report *p_report, char *err_result) +{ + wmt_step_parse_data(buf, osal_strlen((char *)buf), wmt_step_test_check_write_tp); + if (g_step_test_check.step_check_total != g_step_test_check.step_check_index) { + WMT_ERR_FUNC("STEP test failed: index %d: expect total %d\n", g_step_test_check.step_check_index, + g_step_test_check.step_check_total); + g_step_test_check.step_check_result = TEST_FAIL; + } + wmt_step_test_update_result(g_step_test_check.step_check_result, p_report, err_result); +} + +void __wmt_step_test_create_action(enum step_action_id act_id, int param_num, char *params[], int result_of_action, + int check_params[], struct step_test_report *p_report, char *err_result) +{ + struct step_action *p_act = NULL; + int result = TEST_FAIL; + + p_act = wmt_step_create_action(act_id, param_num, params); + if (p_act != NULL) { + switch (p_act->action_id) { + case STEP_ACTION_INDEX_EMI: + { + struct step_emi_action *p_emi_act = NULL; + + p_emi_act = list_entry_action(emi, p_act); + result = wmt_step_test_check_create_emi(p_emi_act, check_params, + err_result); + } + break; + case STEP_ACTION_INDEX_REGISTER: + { + struct step_register_action *p_reg_act = NULL; + + p_reg_act = list_entry_action(register, p_act); + result = wmt_step_test_check_create_reg(p_reg_act, check_params, + err_result); + } + break; + case STEP_ACTION_INDEX_GPIO: + { + struct step_gpio_action *p_gpio_act = NULL; + + p_gpio_act = list_entry_action(gpio, p_act); + result = wmt_step_test_check_create_gpio(p_gpio_act, check_params, + err_result); + } + break; + case STEP_ACTION_INDEX_DISABLE_RESET: + { + struct step_disable_reset_action *p_drst_act = NULL; + + p_drst_act = list_entry_action(disable_reset, p_act); + result = wmt_step_test_check_create_drst(p_drst_act, + check_params, err_result); + } + break; + case STEP_ACTION_INDEX_CHIP_RESET: + { + struct step_chip_reset_action *p_crst_act = NULL; + + p_crst_act = list_entry_action(chip_reset, p_act); + result = wmt_step_test_check_create_crst(p_crst_act, + check_params, err_result); + } + break; + case STEP_ACTION_INDEX_KEEP_WAKEUP: + { + struct step_keep_wakeup_action *p_kwak_act = NULL; + + p_kwak_act = list_entry_action(keep_wakeup, p_act); + result = wmt_step_test_check_create_keep_wakeup(p_kwak_act, + check_params, err_result); + } + break; + case STEP_ACTION_INDEX_CANCEL_WAKEUP: + { + struct step_cancel_wakeup_action *p_cwak_act = NULL; + + p_cwak_act = list_entry_action(cancel_wakeup, p_act); + result = wmt_step_test_check_create_cancel_wakeup(p_cwak_act, + check_params, err_result); + } + break; + case STEP_ACTION_INDEX_PERIODIC_DUMP: + { + struct step_periodic_dump_action *p_pd_act = NULL; + + p_pd_act = list_entry_action(periodic_dump, p_act); + result = wmt_step_test_check_create_periodic_dump(p_pd_act, + check_params, err_result); + } + break; + case STEP_ACTION_INDEX_SHOW_STRING: + { + struct step_show_string_action *p_show_act = NULL; + + p_show_act = list_entry_action(show_string, p_act); + result = wmt_step_test_check_create_show_string(p_show_act, + check_params, err_result); + } + break; + case STEP_ACTION_INDEX_SLEEP: + { + struct step_sleep_action *p_sleep_act = NULL; + + p_sleep_act = list_entry_action(sleep, p_act); + result = wmt_step_test_check_create_sleep(p_sleep_act, + check_params, err_result); + } + break; + case STEP_ACTION_INDEX_CONDITION: + { + struct step_condition_action *p_cond_act = NULL; + + p_cond_act = list_entry_action(condition, p_act); + result = wmt_step_test_check_create_condition(p_cond_act, + check_params, err_result); + } + break; + case STEP_ACTION_INDEX_VALUE: + { + struct step_value_action *p_val_act = NULL; + + p_val_act = list_entry_action(value, p_act); + result = wmt_step_test_check_create_value(p_val_act, + check_params, err_result); + } + break; + case STEP_ACTION_INDEX_CONDITION_EMI: + { + struct step_condition_emi_action *p_cond_emi_act = NULL; + + p_cond_emi_act = list_entry_action(condition_emi, p_act); + result = wmt_step_test_check_create_condition_emi(p_cond_emi_act, check_params, + err_result); + } + break; + case STEP_ACTION_INDEX_CONDITION_REGISTER: + { + struct step_condition_register_action *p_cond_reg_act = NULL; + + p_cond_reg_act = list_entry_action(condition_register, p_act); + result = wmt_step_test_check_create_condition_reg(p_cond_reg_act, check_params, + err_result); + } + break; + default: + result = TEST_FAIL; + break; + } + + if (result_of_action == -1) + result = TEST_FAIL; + + wmt_step_remove_action(p_act); + } else { + if (result_of_action == -1) + result = TEST_PASS; + else + result = TEST_FAIL; + } + wmt_step_test_update_result(result, p_report, err_result); +} + +void __wmt_step_test_do_emi_action(enum step_action_id act_id, int param_num, char *params[], int result_of_action, + struct step_test_report *p_report, char *err_result) +{ + struct step_action *p_act = NULL; + + p_act = wmt_step_create_action(act_id, param_num, params); + if (p_act != NULL) { + if (wmt_step_do_emi_action(p_act, wmt_step_test_check_emi_act) == + result_of_action) { + if (g_step_test_check.step_check_total != g_step_test_check.step_check_index) { + p_report->fail++; + WMT_ERR_FUNC("%s, index %d: expect total %d\n", err_result, + g_step_test_check.step_check_index, g_step_test_check.step_check_total); + } else if (g_step_test_check.step_check_result == TEST_PASS) { + p_report->pass++; + } else { + p_report->fail++; + WMT_ERR_FUNC("%s\n", err_result); + } + } else { + WMT_ERR_FUNC("%s, expect result is %d\n", err_result, result_of_action); + p_report->fail++; + } + wmt_step_remove_action(p_act); + } else { + if (result_of_action == -1) { + p_report->pass++; + } else { + p_report->fail++; + WMT_ERR_FUNC("%s, Create failed\n", err_result); + } + } +} + +void __wmt_step_test_do_cond_emi_action(enum step_action_id act_id, int param_num, char *params[], int result_of_action, + struct step_test_report *p_report, char *err_result) +{ + struct step_action *p_act = NULL; + + p_act = wmt_step_create_action(act_id, param_num, params); + if (p_act != NULL) { + if (wmt_step_do_condition_emi_action(p_act, wmt_step_test_check_emi_act) == + result_of_action) { + if (g_step_test_check.step_check_total != g_step_test_check.step_check_index) { + p_report->fail++; + WMT_ERR_FUNC("%s, index %d: expect total %d\n", err_result, + g_step_test_check.step_check_index, g_step_test_check.step_check_total); + } else if (g_step_test_check.step_check_result == TEST_PASS) { + p_report->pass++; + } else { + p_report->fail++; + WMT_ERR_FUNC("%s\n", err_result); + } + } else { + WMT_ERR_FUNC("%s, expect result is %d\n", err_result, result_of_action); + p_report->fail++; + } + wmt_step_remove_action(p_act); + } else { + if (result_of_action == -1) { + p_report->pass++; + } else { + p_report->fail++; + WMT_ERR_FUNC("%s, Create failed\n", err_result); + } + } +} + + +void __wmt_step_test_do_register_action(enum step_action_id act_id, int param_num, char *params[], int result_of_action, + struct step_test_report *p_report, char *err_result) +{ + struct step_action *p_act = NULL; + int result; + + p_act = wmt_step_create_action(act_id, param_num, params); + if (p_act != NULL) { + if (osal_strcmp(params[0], "1") == 0) { + /* Write register test */ + if (g_step_test_check.step_check_register_addr != 0) { + g_step_test_check.step_recovery_value = + CONSYS_REG_READ(g_step_test_check.step_check_register_addr); + } + result = wmt_step_do_register_action(p_act, wmt_step_test_check_reg_write_act); + if (result == result_of_action) { + if (g_step_test_check.step_check_result == TEST_PASS) { + p_report->pass++; + } else { + p_report->fail++; + WMT_ERR_FUNC("%s\n", err_result); + } + } else if (result == -2) { + p_report->check++; + WMT_INFO_FUNC("STEP check: %s, no clock is ok?\n", err_result); + } else { + WMT_ERR_FUNC("%s, expect result is %d\n", err_result, + result_of_action); + p_report->fail++; + } + if (g_step_test_check.step_check_register_addr != 0) { + CONSYS_REG_WRITE(g_step_test_check.step_check_register_addr, + g_step_test_check.step_recovery_value); + } + } else { + /* Read register test */ + g_step_test_check.step_check_result = TEST_PASS; + result = wmt_step_do_register_action(p_act, wmt_step_test_check_reg_read_act); + if (result == result_of_action) { + if (g_step_test_check.step_check_result == TEST_PASS) { + p_report->pass++; + } else { + p_report->fail++; + WMT_ERR_FUNC("%s\n", err_result); + } + } else if (result == -2) { + p_report->check++; + WMT_INFO_FUNC("STEP check: %s, no clock is ok?\n", err_result); + } else { + WMT_ERR_FUNC("%s, expect result is %d\n", err_result, + result_of_action); + p_report->fail++; + } + } + wmt_step_remove_action(p_act); + } else { + if (result_of_action == -1) { + p_report->pass++; + } else { + p_report->fail++; + WMT_ERR_FUNC("%s, Create failed\n", err_result); + } + } +} + +void __wmt_step_test_do_cond_register_action(enum step_action_id act_id, int param_num, + char *params[], int result_of_action, + struct step_test_report *p_report, char *err_result) +{ + struct step_action *p_act = NULL; + int result; + + p_act = wmt_step_create_action(act_id, param_num, params); + if (p_act != NULL) { + if (osal_strcmp(params[1], "1") == 0) { + /* Write register test */ + if (g_step_test_check.step_check_register_addr != 0) { + g_step_test_check.step_recovery_value = + CONSYS_REG_READ(g_step_test_check.step_check_register_addr); + } + + result = wmt_step_do_condition_register_action(p_act, wmt_step_test_check_reg_write_act); + if (result == result_of_action) { + if (g_step_test_check.step_check_result == TEST_PASS) { + p_report->pass++; + } else { + p_report->fail++; + WMT_ERR_FUNC("%s\n", err_result); + } + } else if (result == -2) { + p_report->check++; + WMT_INFO_FUNC("STEP check: %s, no clock is ok?\n", err_result); + } else { + WMT_ERR_FUNC("%s, expect result is %d\n", err_result, result_of_action); + p_report->fail++; + } + if (g_step_test_check.step_check_register_addr != 0) { + CONSYS_REG_WRITE(g_step_test_check.step_check_register_addr, + g_step_test_check.step_recovery_value); + } + } else { + /* Read register test */ + g_step_test_check.step_check_result = TEST_PASS; + result = wmt_step_do_condition_register_action(p_act, wmt_step_test_check_reg_read_act); + if (result == result_of_action) { + if (g_step_test_check.step_check_result == TEST_PASS) { + p_report->pass++; + } else { + p_report->fail++; + WMT_ERR_FUNC("%s\n", err_result); + } + } else if (result == -2) { + p_report->check++; + WMT_INFO_FUNC("STEP check: %s, no clock is ok?\n", err_result); + } else { + WMT_ERR_FUNC("%s, expect result is %d\n", err_result, result_of_action); + p_report->fail++; + } + } + wmt_step_remove_action(p_act); + } else { + if (result_of_action == -1) { + p_report->pass++; + } else { + p_report->fail++; + WMT_ERR_FUNC("%s, Create failed\n", err_result); + } + } +} + +void wmt_step_test_all(void) +{ + struct step_test_report report = {0, 0, 0}; + bool is_enable_step = g_step_env.is_enable; + int sec_begin = 0; + int usec_begin = 0; + int sec_end = 0; + int usec_end = 0; + + report.pass = 0; + report.fail = 0; + report.check = 0; + + WMT_INFO_FUNC("STEP test: All start\n"); + osal_gettimeofday(&sec_begin, &usec_begin); + g_step_env.is_enable = 0; + wmt_step_test_read_file(&report); + g_step_env.is_enable = 1; + wmt_step_test_create_emi_action(&report); + wmt_step_test_create_cond_emi_action(&report); + wmt_step_test_create_register_action(&report); + wmt_step_test_create_cond_register_action(&report); + wmt_step_test_check_register_symbol(&report); + wmt_step_test_create_other_action(&report); + wmt_step_test_parse_data(&report); + wmt_step_test_do_emi_action(&report); + wmt_step_test_do_cond_emi_action(&report); + wmt_step_test_do_register_action(&report); + wmt_step_test_do_cond_register_action(&report); + wmt_step_test_do_gpio_action(&report); + wmt_step_test_do_wakeup_action(&report); + wmt_step_test_create_periodic_dump(&report); + wmt_step_test_do_show_action(&report); + wmt_step_test_do_sleep_action(&report); + wmt_step_test_do_condition_action(&report); + wmt_step_test_do_value_action(&report); + + wmt_step_test_do_chip_reset_action(&report); + g_step_env.is_enable = is_enable_step; + + osal_gettimeofday(&sec_end, &usec_end); + wmt_step_test_show_result_report("STEP result: All result", + &report, sec_begin, usec_begin, sec_end, usec_end); +} + +void wmt_step_test_read_file(struct step_test_report *p_report) +{ + struct step_test_report temp_report = {0, 0, 0}; + int sec_begin = 0; + int usec_begin = 0; + int sec_end = 0; + int usec_end = 0; + + WMT_INFO_FUNC("STEP test: Read file start\n"); + osal_gettimeofday(&sec_begin, &usec_begin); + /******************************** + ******** Test case 1 *********** + ******* Wrong file name ******** + ********************************/ + if (-1 == wmt_step_read_file("wmt_failed.cfg")) { + temp_report.pass++; + } else { + WMT_ERR_FUNC("STEP test failed: (Read file TC-1) expect no file\n"); + temp_report.fail++; + } + + osal_gettimeofday(&sec_end, &usec_end); + wmt_step_test_show_result_report("STEP result: Read file result", + &temp_report, sec_begin, usec_begin, sec_end, usec_end); + wmt_step_test_update_result_report(p_report, &temp_report); +} + +void wmt_step_test_parse_data(struct step_test_report *p_report) +{ + char *buf = NULL; + struct step_test_report temp_report = {0, 0, 0}; + int sec_begin = 0; + int usec_begin = 0; + int sec_end = 0; + int usec_end = 0; + + WMT_INFO_FUNC("STEP test: Parse data start\n"); + osal_gettimeofday(&sec_begin, &usec_begin); + /******************************** + ******** Test case 1 *********** + ******** Normal case *********** + ********************************/ + WMT_INFO_FUNC("STEP test: TC 1\n"); + wmt_step_test_clear_check_data(); + + buf = + "// TEST NOW\r\n" + "\r\n" + "[TP 1] When Command timeout\r\n" + "[AT] _EMI 0 0x50 0x9c\r\n" + "[AT] _REG 0 0x08 5 2\r\n" + "[AT] DRST\r\n" + "[AT] _RST\r\n" + "[TP 2] When Firmware trigger assert\r\n" + "[AT] _REG 1 0x08 30\r\n" + "[AT] GPIO 0 8\r\n" + "[AT] GPIO 1 6 3\r\n" + "[AT] WAK+\r\n" + "[AT] WAK-\r\n" + "[AT] _REG 1 0x08 30 0xFF00FF00\r\n" + "[TP 3] Before Chip reset\r\n" + "[AT] SHOW Hello_World\r\n" + "[AT] _SLP 1000\r\n" + "[AT] COND $1 $2 == $3\r\n" + "[AT] COND $1 $2 == 16\r\n" + "[AT] _VAL $0 0x66\r\n" + "[TP 4] After Chip reset\r\n" + "[AT] _EMI 0 0x50 0xFFFFFFFF $1\r\n" + "[AT] _REG 0 0x08 0xFFFFFFFF $1\r\n" + "[AT] CEMI $2 0 0x50 0xFFFFFFFF $1\r\n" + "[AT] CREG $2 0 0x08 0xFFFFFFFF $1\r\n" + "\r\n"; + + g_step_test_check.step_check_total = 19; + g_step_test_check.step_check_test_tp_id[0] = STEP_TRIGGER_POINT_COMMAND_TIMEOUT; + g_step_test_check.step_check_test_act_id[0] = STEP_ACTION_INDEX_EMI; + g_step_test_check.step_check_test_tp_id[1] = STEP_TRIGGER_POINT_COMMAND_TIMEOUT; + g_step_test_check.step_check_test_act_id[1] = STEP_ACTION_INDEX_REGISTER; + g_step_test_check.step_check_test_tp_id[2] = STEP_TRIGGER_POINT_COMMAND_TIMEOUT; + g_step_test_check.step_check_test_act_id[2] = STEP_ACTION_INDEX_DISABLE_RESET; + g_step_test_check.step_check_test_tp_id[3] = STEP_TRIGGER_POINT_COMMAND_TIMEOUT; + g_step_test_check.step_check_test_act_id[3] = STEP_ACTION_INDEX_CHIP_RESET; + g_step_test_check.step_check_test_tp_id[4] = STEP_TRIGGER_POINT_FIRMWARE_TRIGGER_ASSERT; + g_step_test_check.step_check_test_act_id[4] = STEP_ACTION_INDEX_REGISTER; + g_step_test_check.step_check_test_tp_id[5] = STEP_TRIGGER_POINT_FIRMWARE_TRIGGER_ASSERT; + g_step_test_check.step_check_test_act_id[5] = STEP_ACTION_INDEX_GPIO; + g_step_test_check.step_check_test_tp_id[6] = STEP_TRIGGER_POINT_FIRMWARE_TRIGGER_ASSERT; + g_step_test_check.step_check_test_act_id[6] = STEP_ACTION_INDEX_GPIO; + g_step_test_check.step_check_test_tp_id[7] = STEP_TRIGGER_POINT_FIRMWARE_TRIGGER_ASSERT; + g_step_test_check.step_check_test_act_id[7] = STEP_ACTION_INDEX_KEEP_WAKEUP; + g_step_test_check.step_check_test_tp_id[8] = STEP_TRIGGER_POINT_FIRMWARE_TRIGGER_ASSERT; + g_step_test_check.step_check_test_act_id[8] = STEP_ACTION_INDEX_CANCEL_WAKEUP; + g_step_test_check.step_check_test_tp_id[9] = STEP_TRIGGER_POINT_FIRMWARE_TRIGGER_ASSERT; + g_step_test_check.step_check_test_act_id[9] = STEP_ACTION_INDEX_REGISTER; + g_step_test_check.step_check_test_tp_id[10] = STEP_TRIGGER_POINT_BEFORE_CHIP_RESET; + g_step_test_check.step_check_test_act_id[10] = STEP_ACTION_INDEX_SHOW_STRING; + g_step_test_check.step_check_test_tp_id[11] = STEP_TRIGGER_POINT_BEFORE_CHIP_RESET; + g_step_test_check.step_check_test_act_id[11] = STEP_ACTION_INDEX_SLEEP; + g_step_test_check.step_check_test_tp_id[12] = STEP_TRIGGER_POINT_BEFORE_CHIP_RESET; + g_step_test_check.step_check_test_act_id[12] = STEP_ACTION_INDEX_CONDITION; + g_step_test_check.step_check_test_tp_id[13] = STEP_TRIGGER_POINT_BEFORE_CHIP_RESET; + g_step_test_check.step_check_test_act_id[13] = STEP_ACTION_INDEX_CONDITION; + g_step_test_check.step_check_test_tp_id[14] = STEP_TRIGGER_POINT_BEFORE_CHIP_RESET; + g_step_test_check.step_check_test_act_id[14] = STEP_ACTION_INDEX_VALUE; + g_step_test_check.step_check_test_tp_id[15] = STEP_TRIGGER_POINT_AFTER_CHIP_RESET; + g_step_test_check.step_check_test_act_id[15] = STEP_ACTION_INDEX_EMI; + g_step_test_check.step_check_test_tp_id[16] = STEP_TRIGGER_POINT_AFTER_CHIP_RESET; + g_step_test_check.step_check_test_act_id[16] = STEP_ACTION_INDEX_REGISTER; + g_step_test_check.step_check_test_tp_id[17] = STEP_TRIGGER_POINT_AFTER_CHIP_RESET; + g_step_test_check.step_check_test_act_id[17] = STEP_ACTION_INDEX_CONDITION_EMI; + g_step_test_check.step_check_test_tp_id[18] = STEP_TRIGGER_POINT_AFTER_CHIP_RESET; + g_step_test_check.step_check_test_act_id[18] = STEP_ACTION_INDEX_CONDITION_REGISTER; + + g_step_test_check.step_check_params[0][0] = "0"; + g_step_test_check.step_check_params[0][1] = "0x50"; + g_step_test_check.step_check_params[0][2] = "0x9c"; + g_step_test_check.step_check_params_num[0] = 3; + g_step_test_check.step_check_params[1][0] = "0"; + g_step_test_check.step_check_params[1][1] = "0x08"; + g_step_test_check.step_check_params[1][2] = "5"; + g_step_test_check.step_check_params[1][3] = "2"; + g_step_test_check.step_check_params_num[1] = 4; + g_step_test_check.step_check_params[4][0] = "1"; + g_step_test_check.step_check_params[4][1] = "0x08"; + g_step_test_check.step_check_params[4][2] = "30"; + g_step_test_check.step_check_params_num[4] = 3; + g_step_test_check.step_check_params[5][0] = "0"; + g_step_test_check.step_check_params[5][1] = "8"; + g_step_test_check.step_check_params_num[5] = 2; + g_step_test_check.step_check_params[6][0] = "1"; + g_step_test_check.step_check_params[6][1] = "6"; + g_step_test_check.step_check_params[6][2] = "3"; + g_step_test_check.step_check_params_num[6] = 3; + g_step_test_check.step_check_params[9][0] = "1"; + g_step_test_check.step_check_params[9][1] = "0x08"; + g_step_test_check.step_check_params[9][2] = "30"; + g_step_test_check.step_check_params[9][3] = "0xFF00FF00"; + g_step_test_check.step_check_params_num[9] = 4; + g_step_test_check.step_check_params[10][0] = "Hello_World"; + g_step_test_check.step_check_params_num[10] = 1; + g_step_test_check.step_check_params[11][0] = "1000"; + g_step_test_check.step_check_params_num[11] = 1; + g_step_test_check.step_check_params[12][0] = "$1"; + g_step_test_check.step_check_params[12][1] = "$2"; + g_step_test_check.step_check_params[12][2] = "=="; + g_step_test_check.step_check_params[12][3] = "$3"; + g_step_test_check.step_check_params_num[12] = 4; + g_step_test_check.step_check_params[13][0] = "$1"; + g_step_test_check.step_check_params[13][1] = "$2"; + g_step_test_check.step_check_params[13][2] = "=="; + g_step_test_check.step_check_params[13][3] = "16"; + g_step_test_check.step_check_params_num[13] = 4; + g_step_test_check.step_check_params[14][0] = "$0"; + g_step_test_check.step_check_params[14][1] = "0x66"; + g_step_test_check.step_check_params_num[14] = 2; + g_step_test_check.step_check_params[15][0] = "0"; + g_step_test_check.step_check_params[15][1] = "0x50"; + g_step_test_check.step_check_params[15][2] = "0xFFFFFFFF"; + g_step_test_check.step_check_params[15][3] = "$1"; + g_step_test_check.step_check_params_num[15] = 4; + g_step_test_check.step_check_params[16][0] = "0"; + g_step_test_check.step_check_params[16][1] = "0x08"; + g_step_test_check.step_check_params[16][2] = "0xFFFFFFFF"; + g_step_test_check.step_check_params[16][3] = "$1"; + g_step_test_check.step_check_params_num[16] = 4; + g_step_test_check.step_check_params[17][0] = "$2"; + g_step_test_check.step_check_params[17][1] = "0"; + g_step_test_check.step_check_params[17][2] = "0x50"; + g_step_test_check.step_check_params[17][3] = "0xFFFFFFFF"; + g_step_test_check.step_check_params[17][4] = "$1"; + g_step_test_check.step_check_params_num[17] = 5; + g_step_test_check.step_check_params[18][0] = "$2"; + g_step_test_check.step_check_params[18][1] = "0"; + g_step_test_check.step_check_params[18][2] = "0x08"; + g_step_test_check.step_check_params[18][3] = "0xFFFFFFFF"; + g_step_test_check.step_check_params[18][4] = "$1"; + g_step_test_check.step_check_params_num[18] = 5; + __wmt_step_test_parse_data(buf, &temp_report, + "STEP test case failed: (Parse data TC-1) Normal case\n"); + + /********************************* + ******** Test case 2 ************ + ** Normal case with some space ** + *********************************/ + WMT_INFO_FUNC("STEP test: TC 2\n"); + wmt_step_test_clear_check_data(); + buf = + "// TEST NOW\r\n" + "\r\n" + "[TP 1] When Command timeout\r\n" + "[AT] _EMI 0 0x50 0x9c \r\n" + "[AT] _REG 0 0x08 5 2\r\n" + "[AT] DRST\r\n" + "[AT] _RST\r\n" + " [PD+] 2\r\n" + " [AT] _EMI 0 0x50 0x9c\r\n" + " [PD-] \r\n" + " [TP 2] When Firmware trigger assert\r\n" + "[AT] _REG 1 0x08 30\r\n" + "[AT] GPIO 0 8\r\n" + " [AT] GPIO 1 6 3\r\n" + " [AT] WAK+\r\n" + " [AT] WAK-\r\n" + " [PD+] 5\r\n" + " [AT] _EMI 0 0x50 0x9c\r\n" + " [PD-] \r\n" + "[TP 3] Before Chip reset\r\n" + " [AT] SHOW Hello\r\n" + "[AT] _SLP 1000\r\n" + " [AT] COND $1 $2 == $3\r\n" + " [AT] _VAL $0 0x66\r\n" + "[TP 4] After Chip reset\r\n" + "[AT] CEMI $2 0 0x50 0xFFFFFFFF $1\r\n" + " [AT] CREG $2 0 0x08 0xFFFFFFFF $1\r\n" + "\r\n"; + + g_step_test_check.step_check_total = 19; + g_step_test_check.step_check_test_tp_id[0] = STEP_TRIGGER_POINT_COMMAND_TIMEOUT; + g_step_test_check.step_check_test_act_id[0] = STEP_ACTION_INDEX_EMI; + g_step_test_check.step_check_test_tp_id[1] = STEP_TRIGGER_POINT_COMMAND_TIMEOUT; + g_step_test_check.step_check_test_act_id[1] = STEP_ACTION_INDEX_REGISTER; + g_step_test_check.step_check_test_tp_id[2] = STEP_TRIGGER_POINT_COMMAND_TIMEOUT; + g_step_test_check.step_check_test_act_id[2] = STEP_ACTION_INDEX_DISABLE_RESET; + g_step_test_check.step_check_test_tp_id[3] = STEP_TRIGGER_POINT_COMMAND_TIMEOUT; + g_step_test_check.step_check_test_act_id[3] = STEP_ACTION_INDEX_CHIP_RESET; + g_step_test_check.step_check_test_tp_id[4] = -1; + g_step_test_check.step_check_test_act_id[4] = STEP_ACTION_INDEX_EMI; + g_step_test_check.step_check_test_tp_id[5] = STEP_TRIGGER_POINT_COMMAND_TIMEOUT; + g_step_test_check.step_check_test_act_id[5] = STEP_ACTION_INDEX_PERIODIC_DUMP; + g_step_test_check.step_check_test_tp_id[6] = STEP_TRIGGER_POINT_FIRMWARE_TRIGGER_ASSERT; + g_step_test_check.step_check_test_act_id[6] = STEP_ACTION_INDEX_REGISTER; + g_step_test_check.step_check_test_tp_id[7] = STEP_TRIGGER_POINT_FIRMWARE_TRIGGER_ASSERT; + g_step_test_check.step_check_test_act_id[7] = STEP_ACTION_INDEX_GPIO; + g_step_test_check.step_check_test_tp_id[8] = STEP_TRIGGER_POINT_FIRMWARE_TRIGGER_ASSERT; + g_step_test_check.step_check_test_act_id[8] = STEP_ACTION_INDEX_GPIO; + g_step_test_check.step_check_test_tp_id[9] = STEP_TRIGGER_POINT_FIRMWARE_TRIGGER_ASSERT; + g_step_test_check.step_check_test_act_id[9] = STEP_ACTION_INDEX_KEEP_WAKEUP; + g_step_test_check.step_check_test_tp_id[10] = STEP_TRIGGER_POINT_FIRMWARE_TRIGGER_ASSERT; + g_step_test_check.step_check_test_act_id[10] = STEP_ACTION_INDEX_CANCEL_WAKEUP; + g_step_test_check.step_check_test_tp_id[11] = -1; + g_step_test_check.step_check_test_act_id[11] = STEP_ACTION_INDEX_EMI; + g_step_test_check.step_check_test_tp_id[12] = STEP_TRIGGER_POINT_FIRMWARE_TRIGGER_ASSERT; + g_step_test_check.step_check_test_act_id[12] = STEP_ACTION_INDEX_PERIODIC_DUMP; + g_step_test_check.step_check_test_tp_id[13] = STEP_TRIGGER_POINT_BEFORE_CHIP_RESET; + g_step_test_check.step_check_test_act_id[13] = STEP_ACTION_INDEX_SHOW_STRING; + g_step_test_check.step_check_test_tp_id[14] = STEP_TRIGGER_POINT_BEFORE_CHIP_RESET; + g_step_test_check.step_check_test_act_id[14] = STEP_ACTION_INDEX_SLEEP; + g_step_test_check.step_check_test_tp_id[15] = STEP_TRIGGER_POINT_BEFORE_CHIP_RESET; + g_step_test_check.step_check_test_act_id[15] = STEP_ACTION_INDEX_CONDITION; + g_step_test_check.step_check_test_tp_id[16] = STEP_TRIGGER_POINT_BEFORE_CHIP_RESET; + g_step_test_check.step_check_test_act_id[16] = STEP_ACTION_INDEX_VALUE; + g_step_test_check.step_check_test_tp_id[17] = STEP_TRIGGER_POINT_AFTER_CHIP_RESET; + g_step_test_check.step_check_test_act_id[17] = STEP_ACTION_INDEX_CONDITION_EMI; + g_step_test_check.step_check_test_tp_id[18] = STEP_TRIGGER_POINT_AFTER_CHIP_RESET; + g_step_test_check.step_check_test_act_id[18] = STEP_ACTION_INDEX_CONDITION_REGISTER; + g_step_test_check.step_check_params[0][0] = "0"; + g_step_test_check.step_check_params[0][1] = "0x50"; + g_step_test_check.step_check_params[0][2] = "0x9c"; + g_step_test_check.step_check_params_num[0] = 3; + g_step_test_check.step_check_params[1][0] = "0"; + g_step_test_check.step_check_params[1][1] = "0x08"; + g_step_test_check.step_check_params[1][2] = "5"; + g_step_test_check.step_check_params[1][3] = "2"; + g_step_test_check.step_check_params_num[1] = 4; + g_step_test_check.step_check_params[4][0] = "0"; + g_step_test_check.step_check_params[4][1] = "0x50"; + g_step_test_check.step_check_params[4][2] = "0x9c"; + g_step_test_check.step_check_params_num[4] = 3; + g_step_test_check.step_check_params[6][0] = "1"; + g_step_test_check.step_check_params[6][1] = "0x08"; + g_step_test_check.step_check_params[6][2] = "30"; + g_step_test_check.step_check_params_num[6] = 3; + g_step_test_check.step_check_params[7][0] = "0"; + g_step_test_check.step_check_params[7][1] = "8"; + g_step_test_check.step_check_params_num[7] = 2; + g_step_test_check.step_check_params[8][0] = "1"; + g_step_test_check.step_check_params[8][1] = "6"; + g_step_test_check.step_check_params[8][2] = "3"; + g_step_test_check.step_check_params_num[8] = 3; + g_step_test_check.step_check_params[11][0] = "0"; + g_step_test_check.step_check_params[11][1] = "0x50"; + g_step_test_check.step_check_params[11][2] = "0x9c"; + g_step_test_check.step_check_params_num[11] = 3; + g_step_test_check.step_check_params[13][0] = "Hello"; + g_step_test_check.step_check_params_num[13] = 1; + g_step_test_check.step_check_params[14][0] = "1000"; + g_step_test_check.step_check_params_num[14] = 1; + g_step_test_check.step_check_params[15][0] = "$1"; + g_step_test_check.step_check_params[15][1] = "$2"; + g_step_test_check.step_check_params[15][2] = "=="; + g_step_test_check.step_check_params[15][3] = "$3"; + g_step_test_check.step_check_params_num[15] = 4; + g_step_test_check.step_check_params[16][0] = "$0"; + g_step_test_check.step_check_params[16][1] = "0x66"; + g_step_test_check.step_check_params_num[16] = 2; + g_step_test_check.step_check_params[17][0] = "$2"; + g_step_test_check.step_check_params[17][1] = "0"; + g_step_test_check.step_check_params[17][2] = "0x50"; + g_step_test_check.step_check_params[17][3] = "0xFFFFFFFF"; + g_step_test_check.step_check_params[17][4] = "$1"; + g_step_test_check.step_check_params_num[17] = 5; + g_step_test_check.step_check_params[18][0] = "$2"; + g_step_test_check.step_check_params[18][1] = "0"; + g_step_test_check.step_check_params[18][2] = "0x08"; + g_step_test_check.step_check_params[18][3] = "0xFFFFFFFF"; + g_step_test_check.step_check_params[18][4] = "$1"; + g_step_test_check.step_check_params_num[18] = 5; + __wmt_step_test_parse_data(buf, &temp_report, + "STEP test case failed: (Parse data TC-2) Normal case with some space\n"); + + /*************************************************** + ****************** Test case 3 ******************** + ** Failed case not enough parameter (Can parser) ** + ***************************************************/ + WMT_INFO_FUNC("STEP test: TC 3\n"); + wmt_step_test_clear_check_data(); + buf = + "// TEST NOW\r\n" + "\r\n" + "[TP 1] When Command timeout\r\n" + "[AT] _EMI 0x50 0x9c\r\n" + "[AT] _REG 0 5 2\r\n" + "[AT] DRST\r\n" + "[AT] _RST\r\n" + "[TP 2] When Firmware trigger assert\r\n" + "[AT] _REG 1 0x08\r\n" + "[AT] GPIO 0\r\n" + "[AT] GPIO 6 3\r\n" + "[TP 3] Before Chip reset\r\n" + "[AT] SHOW\r\n" + "[AT] _SLP\r\n" + "[AT] COND $1 $2 >\r\n" + "[AT] _VAL 0x66\r\n" + "\r\n"; + + g_step_test_check.step_check_total = 11; + g_step_test_check.step_check_test_tp_id[0] = STEP_TRIGGER_POINT_COMMAND_TIMEOUT; + g_step_test_check.step_check_test_act_id[0] = STEP_ACTION_INDEX_EMI; + g_step_test_check.step_check_test_tp_id[1] = STEP_TRIGGER_POINT_COMMAND_TIMEOUT; + g_step_test_check.step_check_test_act_id[1] = STEP_ACTION_INDEX_REGISTER; + g_step_test_check.step_check_test_tp_id[2] = STEP_TRIGGER_POINT_COMMAND_TIMEOUT; + g_step_test_check.step_check_test_act_id[2] = STEP_ACTION_INDEX_DISABLE_RESET; + g_step_test_check.step_check_test_tp_id[3] = STEP_TRIGGER_POINT_COMMAND_TIMEOUT; + g_step_test_check.step_check_test_act_id[3] = STEP_ACTION_INDEX_CHIP_RESET; + g_step_test_check.step_check_test_tp_id[4] = STEP_TRIGGER_POINT_FIRMWARE_TRIGGER_ASSERT; + g_step_test_check.step_check_test_act_id[4] = STEP_ACTION_INDEX_REGISTER; + g_step_test_check.step_check_test_tp_id[5] = STEP_TRIGGER_POINT_FIRMWARE_TRIGGER_ASSERT; + g_step_test_check.step_check_test_act_id[5] = STEP_ACTION_INDEX_GPIO; + g_step_test_check.step_check_test_tp_id[6] = STEP_TRIGGER_POINT_FIRMWARE_TRIGGER_ASSERT; + g_step_test_check.step_check_test_act_id[6] = STEP_ACTION_INDEX_GPIO; + g_step_test_check.step_check_test_tp_id[7] = STEP_TRIGGER_POINT_BEFORE_CHIP_RESET; + g_step_test_check.step_check_test_act_id[7] = STEP_ACTION_INDEX_SHOW_STRING; + g_step_test_check.step_check_test_tp_id[8] = STEP_TRIGGER_POINT_BEFORE_CHIP_RESET; + g_step_test_check.step_check_test_act_id[8] = STEP_ACTION_INDEX_SLEEP; + g_step_test_check.step_check_test_tp_id[9] = STEP_TRIGGER_POINT_BEFORE_CHIP_RESET; + g_step_test_check.step_check_test_act_id[9] = STEP_ACTION_INDEX_CONDITION; + g_step_test_check.step_check_test_tp_id[10] = STEP_TRIGGER_POINT_BEFORE_CHIP_RESET; + g_step_test_check.step_check_test_act_id[10] = STEP_ACTION_INDEX_VALUE; + + g_step_test_check.step_check_params[0][0] = "0x50"; + g_step_test_check.step_check_params[0][1] = "0x9c"; + g_step_test_check.step_check_params_num[0] = 2; + g_step_test_check.step_check_params[1][0] = "0"; + g_step_test_check.step_check_params[1][1] = "5"; + g_step_test_check.step_check_params[1][2] = "2"; + g_step_test_check.step_check_params_num[1] = 3; + g_step_test_check.step_check_params[4][0] = "1"; + g_step_test_check.step_check_params[4][1] = "0x08"; + g_step_test_check.step_check_params_num[4] = 2; + g_step_test_check.step_check_params[5][0] = "0"; + g_step_test_check.step_check_params_num[5] = 1; + g_step_test_check.step_check_params[6][0] = "6"; + g_step_test_check.step_check_params[6][1] = "3"; + g_step_test_check.step_check_params_num[6] = 2; + g_step_test_check.step_check_params[9][0] = "$1"; + g_step_test_check.step_check_params[9][1] = "$2"; + g_step_test_check.step_check_params[9][2] = ">"; + g_step_test_check.step_check_params_num[9] = 3; + g_step_test_check.step_check_params[10][0] = "0x66"; + g_step_test_check.step_check_params_num[10] = 1; + + __wmt_step_test_parse_data(buf, &temp_report, + "STEP test case failed: (Parse data TC-3) Not enough parameter\n"); + + /*************************************************** + ****************** Test case 4 ******************** + ************** Upcase and lowercase *************** + ***************************************************/ + WMT_INFO_FUNC("STEP test: TC 4\n"); + wmt_step_test_clear_check_data(); + buf = + "// TEST NOW\r\n" + "\r\n" + "[Tp 1] When Command timeout\r\n" + "[aT] _emi 0 0x50 0x9c\r\n" + "[At] _reg 0 0x08 5 2\r\n" + "[AT] drst\r\n" + "[at] _rst\r\n" + "[tP 2] When Firmware trigger assert\r\n" + "[at] _reg 1 0x08 30\r\n" + "[at] gpio 0 8\r\n" + "[AT] gpio 1 6 3\r\n" + "[AT] wak+\r\n" + "[AT] wak--\r\n" + "[AT] _reg 1 0x08 30 0xFF00FF00\r\n" + "[pd+] 5\r\n" + "[At] gpio 0 8\r\n" + "[pd-]\r\n" + "[tp 3] Before Chip reset\r\n" + "[AT] show Hello_World\r\n" + "[AT] _slp 1000\r\n" + "[AT] cond $1 $2 == $3\r\n" + "[AT] _val $0 0x66\r\n" + "[TP 4] After Chip reset\r\n" + "[AT] cemi $2 0 0x50 0xFFFFFFFF $1\r\n" + "[at] creg $2 0 0x08 0xffffffff $1\r\n" + "\r\n"; + + g_step_test_check.step_check_total = 18; + g_step_test_check.step_check_test_tp_id[0] = STEP_TRIGGER_POINT_COMMAND_TIMEOUT; + g_step_test_check.step_check_test_act_id[0] = STEP_ACTION_INDEX_EMI; + g_step_test_check.step_check_test_tp_id[1] = STEP_TRIGGER_POINT_COMMAND_TIMEOUT; + g_step_test_check.step_check_test_act_id[1] = STEP_ACTION_INDEX_REGISTER; + g_step_test_check.step_check_test_tp_id[2] = STEP_TRIGGER_POINT_COMMAND_TIMEOUT; + g_step_test_check.step_check_test_act_id[2] = STEP_ACTION_INDEX_DISABLE_RESET; + g_step_test_check.step_check_test_tp_id[3] = STEP_TRIGGER_POINT_COMMAND_TIMEOUT; + g_step_test_check.step_check_test_act_id[3] = STEP_ACTION_INDEX_CHIP_RESET; + g_step_test_check.step_check_test_tp_id[4] = STEP_TRIGGER_POINT_FIRMWARE_TRIGGER_ASSERT; + g_step_test_check.step_check_test_act_id[4] = STEP_ACTION_INDEX_REGISTER; + g_step_test_check.step_check_test_tp_id[5] = STEP_TRIGGER_POINT_FIRMWARE_TRIGGER_ASSERT; + g_step_test_check.step_check_test_act_id[5] = STEP_ACTION_INDEX_GPIO; + g_step_test_check.step_check_test_tp_id[6] = STEP_TRIGGER_POINT_FIRMWARE_TRIGGER_ASSERT; + g_step_test_check.step_check_test_act_id[6] = STEP_ACTION_INDEX_GPIO; + g_step_test_check.step_check_test_tp_id[7] = STEP_TRIGGER_POINT_FIRMWARE_TRIGGER_ASSERT; + g_step_test_check.step_check_test_act_id[7] = STEP_ACTION_INDEX_KEEP_WAKEUP; + g_step_test_check.step_check_test_tp_id[8] = STEP_TRIGGER_POINT_FIRMWARE_TRIGGER_ASSERT; + g_step_test_check.step_check_test_act_id[8] = STEP_ACTION_INDEX_CANCEL_WAKEUP; + g_step_test_check.step_check_test_tp_id[9] = STEP_TRIGGER_POINT_FIRMWARE_TRIGGER_ASSERT; + g_step_test_check.step_check_test_act_id[9] = STEP_ACTION_INDEX_REGISTER; + g_step_test_check.step_check_test_tp_id[10] = -1; + g_step_test_check.step_check_test_act_id[10] = STEP_ACTION_INDEX_GPIO; + g_step_test_check.step_check_test_tp_id[11] = STEP_TRIGGER_POINT_FIRMWARE_TRIGGER_ASSERT; + g_step_test_check.step_check_test_act_id[11] = STEP_ACTION_INDEX_PERIODIC_DUMP; + g_step_test_check.step_check_test_tp_id[12] = STEP_TRIGGER_POINT_BEFORE_CHIP_RESET; + g_step_test_check.step_check_test_act_id[12] = STEP_ACTION_INDEX_SHOW_STRING; + g_step_test_check.step_check_test_tp_id[13] = STEP_TRIGGER_POINT_BEFORE_CHIP_RESET; + g_step_test_check.step_check_test_act_id[13] = STEP_ACTION_INDEX_SLEEP; + g_step_test_check.step_check_test_tp_id[14] = STEP_TRIGGER_POINT_BEFORE_CHIP_RESET; + g_step_test_check.step_check_test_act_id[14] = STEP_ACTION_INDEX_CONDITION; + g_step_test_check.step_check_test_tp_id[15] = STEP_TRIGGER_POINT_BEFORE_CHIP_RESET; + g_step_test_check.step_check_test_act_id[15] = STEP_ACTION_INDEX_VALUE; + g_step_test_check.step_check_test_tp_id[16] = STEP_TRIGGER_POINT_AFTER_CHIP_RESET; + g_step_test_check.step_check_test_act_id[16] = STEP_ACTION_INDEX_CONDITION_EMI; + g_step_test_check.step_check_test_tp_id[17] = STEP_TRIGGER_POINT_AFTER_CHIP_RESET; + g_step_test_check.step_check_test_act_id[17] = STEP_ACTION_INDEX_CONDITION_REGISTER; + + g_step_test_check.step_check_params[0][0] = "0"; + g_step_test_check.step_check_params[0][1] = "0x50"; + g_step_test_check.step_check_params[0][2] = "0x9c"; + g_step_test_check.step_check_params_num[0] = 3; + g_step_test_check.step_check_params[1][0] = "0"; + g_step_test_check.step_check_params[1][1] = "0x08"; + g_step_test_check.step_check_params[1][2] = "5"; + g_step_test_check.step_check_params[1][3] = "2"; + g_step_test_check.step_check_params_num[1] = 4; + g_step_test_check.step_check_params[4][0] = "1"; + g_step_test_check.step_check_params[4][1] = "0x08"; + g_step_test_check.step_check_params[4][2] = "30"; + g_step_test_check.step_check_params_num[4] = 3; + g_step_test_check.step_check_params[5][0] = "0"; + g_step_test_check.step_check_params[5][1] = "8"; + g_step_test_check.step_check_params_num[5] = 2; + g_step_test_check.step_check_params[6][0] = "1"; + g_step_test_check.step_check_params[6][1] = "6"; + g_step_test_check.step_check_params[6][2] = "3"; + g_step_test_check.step_check_params_num[6] = 3; + g_step_test_check.step_check_params[9][0] = "1"; + g_step_test_check.step_check_params[9][1] = "0x08"; + g_step_test_check.step_check_params[9][2] = "30"; + g_step_test_check.step_check_params[9][3] = "0xFF00FF00"; + g_step_test_check.step_check_params_num[9] = 4; + g_step_test_check.step_check_params[10][0] = "0"; + g_step_test_check.step_check_params[10][1] = "8"; + g_step_test_check.step_check_params_num[10] = 2; + g_step_test_check.step_check_params[12][0] = "Hello_World"; + g_step_test_check.step_check_params_num[12] = 1; + g_step_test_check.step_check_params[13][0] = "1000"; + g_step_test_check.step_check_params_num[13] = 1; + g_step_test_check.step_check_params[14][0] = "$1"; + g_step_test_check.step_check_params[14][1] = "$2"; + g_step_test_check.step_check_params[14][2] = "=="; + g_step_test_check.step_check_params[14][3] = "$3"; + g_step_test_check.step_check_params_num[14] = 4; + g_step_test_check.step_check_params[15][0] = "$0"; + g_step_test_check.step_check_params[15][1] = "0x66"; + g_step_test_check.step_check_params_num[15] = 2; + g_step_test_check.step_check_params[16][0] = "$2"; + g_step_test_check.step_check_params[16][1] = "0"; + g_step_test_check.step_check_params[16][2] = "0x50"; + g_step_test_check.step_check_params[16][3] = "0xFFFFFFFF"; + g_step_test_check.step_check_params[16][4] = "$1"; + g_step_test_check.step_check_params_num[16] = 5; + g_step_test_check.step_check_params[17][0] = "$2"; + g_step_test_check.step_check_params[17][1] = "0"; + g_step_test_check.step_check_params[17][2] = "0x08"; + g_step_test_check.step_check_params[17][3] = "0xFFFFFFFF"; + g_step_test_check.step_check_params[17][4] = "$1"; + g_step_test_check.step_check_params_num[17] = 5; + + __wmt_step_test_parse_data(buf, &temp_report, + "STEP test case failed: (Parse data TC-4) Upcase and lowercase\n"); + + /************************************************* + ****************** Test case 5 ****************** + ************** TP sequence switch *************** + *************************************************/ + WMT_INFO_FUNC("STEP test: TC 5\n"); + wmt_step_test_clear_check_data(); + buf = + "// TEST NOW\r\n" + "\r\n" + "[TP 2] When Firmware trigger assert\r\n" + "[AT] _REG 1 0x08 30\r\n" + "[AT] GPIO 0 8\r\n" + "[AT] GPIO 1 6 3\r\n" + "[tp 3] Before Chip reset\r\n" + "[AT] DRST\r\n" + "[AT] _RST\r\n" + "[TP 1] When Command timeout\r\n" + "[AT] _EMI 0 0x50 0x9c\r\n" + "[AT] _REG 0 0x08 5 2\r\n" + "\r\n"; + + g_step_test_check.step_check_total = 7; + g_step_test_check.step_check_test_tp_id[0] = STEP_TRIGGER_POINT_FIRMWARE_TRIGGER_ASSERT; + g_step_test_check.step_check_test_act_id[0] = STEP_ACTION_INDEX_REGISTER; + g_step_test_check.step_check_test_tp_id[1] = STEP_TRIGGER_POINT_FIRMWARE_TRIGGER_ASSERT; + g_step_test_check.step_check_test_act_id[1] = STEP_ACTION_INDEX_GPIO; + g_step_test_check.step_check_test_tp_id[2] = STEP_TRIGGER_POINT_FIRMWARE_TRIGGER_ASSERT; + g_step_test_check.step_check_test_act_id[2] = STEP_ACTION_INDEX_GPIO; + g_step_test_check.step_check_test_tp_id[3] = STEP_TRIGGER_POINT_BEFORE_CHIP_RESET; + g_step_test_check.step_check_test_act_id[3] = STEP_ACTION_INDEX_DISABLE_RESET; + g_step_test_check.step_check_test_tp_id[4] = STEP_TRIGGER_POINT_BEFORE_CHIP_RESET; + g_step_test_check.step_check_test_act_id[4] = STEP_ACTION_INDEX_CHIP_RESET; + g_step_test_check.step_check_test_tp_id[5] = STEP_TRIGGER_POINT_COMMAND_TIMEOUT; + g_step_test_check.step_check_test_act_id[5] = STEP_ACTION_INDEX_EMI; + g_step_test_check.step_check_test_tp_id[6] = STEP_TRIGGER_POINT_COMMAND_TIMEOUT; + g_step_test_check.step_check_test_act_id[6] = STEP_ACTION_INDEX_REGISTER; + g_step_test_check.step_check_params[0][0] = "1"; + g_step_test_check.step_check_params[0][1] = "0x08"; + g_step_test_check.step_check_params[0][2] = "30"; + g_step_test_check.step_check_params_num[0] = 3; + g_step_test_check.step_check_params[1][0] = "0"; + g_step_test_check.step_check_params[1][1] = "8"; + g_step_test_check.step_check_params_num[1] = 2; + g_step_test_check.step_check_params[2][0] = "1"; + g_step_test_check.step_check_params[2][1] = "6"; + g_step_test_check.step_check_params[2][2] = "3"; + g_step_test_check.step_check_params_num[2] = 3; + g_step_test_check.step_check_params[5][0] = "0"; + g_step_test_check.step_check_params[5][1] = "0x50"; + g_step_test_check.step_check_params[5][2] = "0x9c"; + g_step_test_check.step_check_params_num[5] = 3; + g_step_test_check.step_check_params[6][0] = "0"; + g_step_test_check.step_check_params[6][1] = "0x08"; + g_step_test_check.step_check_params[6][2] = "5"; + g_step_test_check.step_check_params[6][3] = "2"; + g_step_test_check.step_check_params_num[6] = 4; + __wmt_step_test_parse_data(buf, &temp_report, + "STEP test case failed: (Parse data TC-5) TP sequence switch\n"); + + /********************************* + ********* Test case 6 *********** + ********* More comment ********** + *********************************/ + WMT_INFO_FUNC("STEP test: TC 6\n"); + wmt_step_test_clear_check_data(); + + buf = + "// TEST NOW\r\n" + "\r\n" + "[TP 1] When Command timeout\r\n" + "[AT] _EMI 0 0x50 0x9c // show emi 0x50~0x9c\r\n" + "// show cregister\r\n" + "[AT] _REG 0 0x08 5 2\r\n" + "// Do some action\r\n" + "[AT] DRST // just do it\r\n" + "[AT] _RST // is ok?\r\n" + "[TP 2] When Firmware trigger assert\r\n" + "[AT] _REG 1 0x08 30\r\n" + "[AT] GPIO 0 8\r\n" + "[AT] GPIO 1 6 3\r\n" + "[PD+] 5 // pd start\r\n" + "[AT] GPIO 0 8 // just do it\r\n" + "// Do some action\r\n" + "[PD-] // pd ned\r\n" + "\r\n"; + + g_step_test_check.step_check_total = 9; + g_step_test_check.step_check_test_tp_id[0] = STEP_TRIGGER_POINT_COMMAND_TIMEOUT; + g_step_test_check.step_check_test_act_id[0] = STEP_ACTION_INDEX_EMI; + g_step_test_check.step_check_test_tp_id[1] = STEP_TRIGGER_POINT_COMMAND_TIMEOUT; + g_step_test_check.step_check_test_act_id[1] = STEP_ACTION_INDEX_REGISTER; + g_step_test_check.step_check_test_tp_id[2] = STEP_TRIGGER_POINT_COMMAND_TIMEOUT; + g_step_test_check.step_check_test_act_id[2] = STEP_ACTION_INDEX_DISABLE_RESET; + g_step_test_check.step_check_test_tp_id[3] = STEP_TRIGGER_POINT_COMMAND_TIMEOUT; + g_step_test_check.step_check_test_act_id[3] = STEP_ACTION_INDEX_CHIP_RESET; + g_step_test_check.step_check_test_tp_id[4] = STEP_TRIGGER_POINT_FIRMWARE_TRIGGER_ASSERT; + g_step_test_check.step_check_test_act_id[4] = STEP_ACTION_INDEX_REGISTER; + g_step_test_check.step_check_test_tp_id[5] = STEP_TRIGGER_POINT_FIRMWARE_TRIGGER_ASSERT; + g_step_test_check.step_check_test_act_id[5] = STEP_ACTION_INDEX_GPIO; + g_step_test_check.step_check_test_tp_id[6] = STEP_TRIGGER_POINT_FIRMWARE_TRIGGER_ASSERT; + g_step_test_check.step_check_test_act_id[6] = STEP_ACTION_INDEX_GPIO; + g_step_test_check.step_check_test_tp_id[7] = -1; + g_step_test_check.step_check_test_act_id[7] = STEP_ACTION_INDEX_GPIO; + g_step_test_check.step_check_test_tp_id[8] = STEP_TRIGGER_POINT_FIRMWARE_TRIGGER_ASSERT; + g_step_test_check.step_check_test_act_id[8] = STEP_ACTION_INDEX_PERIODIC_DUMP; + g_step_test_check.step_check_params[0][0] = "0"; + g_step_test_check.step_check_params[0][1] = "0x50"; + g_step_test_check.step_check_params[0][2] = "0x9c"; + g_step_test_check.step_check_params_num[0] = 3; + g_step_test_check.step_check_params[1][0] = "0"; + g_step_test_check.step_check_params[1][1] = "0x08"; + g_step_test_check.step_check_params[1][2] = "5"; + g_step_test_check.step_check_params[1][3] = "2"; + g_step_test_check.step_check_params_num[1] = 4; + g_step_test_check.step_check_params[4][0] = "1"; + g_step_test_check.step_check_params[4][1] = "0x08"; + g_step_test_check.step_check_params[4][2] = "30"; + g_step_test_check.step_check_params_num[4] = 3; + g_step_test_check.step_check_params[5][0] = "0"; + g_step_test_check.step_check_params[5][1] = "8"; + g_step_test_check.step_check_params_num[5] = 2; + g_step_test_check.step_check_params[6][0] = "1"; + g_step_test_check.step_check_params[6][1] = "6"; + g_step_test_check.step_check_params[6][2] = "3"; + g_step_test_check.step_check_params_num[6] = 3; + g_step_test_check.step_check_params[7][0] = "0"; + g_step_test_check.step_check_params[7][1] = "8"; + g_step_test_check.step_check_params_num[7] = 2; + __wmt_step_test_parse_data(buf, &temp_report, + "STEP test case failed: (Parse data TC-6) More comment\n"); + + /********************************* + ********* Test case 7 *********** + ********* Wrong format ********** + *********************************/ + WMT_INFO_FUNC("STEP test: TC 7\n"); + wmt_step_test_clear_check_data(); + + buf = + "// TEST NOW\r\n" + "\r\n" + "[TP adfacdadf]When Command timeout\r\n" + "[AT] _EMI 0 0x50 0x9c\r\n" + "[TP1]When Command timeout\r\n" + "[AT] DRST\r\n" + "[TP-1]When Command timeout\r\n" + "[AT] _RST\r\n" + "[T P 2] When Firmware trigger assert\r\n" + "[AT] WAK+\r\n" + "[TP 2 When Firmware trigger assert\r\n" + "[AT] WAK+\r\n" + "[PD+]\r\n" + "[PD-]\r\n" + "[TP 2] When Firmware trigger assert\r\n" + "[AT]_REG 1 0x08 30\r\n" + "[A T] GPIO 0 8\r\n" + "[ AT ] GPIO 1 6 3\r\n" + "AT GPIO 0 8\r\n" + "[AT WAK+\r\n" + "\r\n"; + + g_step_test_check.step_check_total = 0; + __wmt_step_test_parse_data(buf, &temp_report, + "STEP test case failed: (Parse data TC-7) Wrong format\n"); + + /******************************** + ******** Test case 8 *********** + ******* Periodic dump ********** + ********************************/ + WMT_INFO_FUNC("STEP test: TC 8\n"); + wmt_step_test_clear_check_data(); + + buf = + "// TEST NOW\r\n" + "\r\n" + "[TP 1] When Command timeout\r\n" + "[PD+] 5\r\n" + "[AT] _EMI 0 0x50 0x9c\r\n" + "[AT] _REG 0 0x08 5 2\r\n" + "[PD-]\r\n" + "[AT] DRST\r\n" + "[AT] _RST\r\n" + "[TP 2] When Firmware trigger assert\r\n" + "[AT] _REG 1 0x08 30\r\n" + "[PD+] 3\r\n" + "[AT] GPIO 0 8\r\n" + "[PD-]\r\n" + "[AT] GPIO 1 6 3\r\n" + "[AT] WAK+\r\n" + "[AT] WAK-\r\n" + "\r\n"; + + g_step_test_check.step_check_total = 11; + g_step_test_check.step_check_test_tp_id[0] = -1; + g_step_test_check.step_check_test_act_id[0] = STEP_ACTION_INDEX_EMI; + g_step_test_check.step_check_test_tp_id[1] = -1; + g_step_test_check.step_check_test_act_id[1] = STEP_ACTION_INDEX_REGISTER; + g_step_test_check.step_check_test_tp_id[2] = STEP_TRIGGER_POINT_COMMAND_TIMEOUT; + g_step_test_check.step_check_test_act_id[2] = STEP_ACTION_INDEX_PERIODIC_DUMP; + g_step_test_check.step_check_test_tp_id[3] = STEP_TRIGGER_POINT_COMMAND_TIMEOUT; + g_step_test_check.step_check_test_act_id[3] = STEP_ACTION_INDEX_DISABLE_RESET; + g_step_test_check.step_check_test_tp_id[4] = STEP_TRIGGER_POINT_COMMAND_TIMEOUT; + g_step_test_check.step_check_test_act_id[4] = STEP_ACTION_INDEX_CHIP_RESET; + g_step_test_check.step_check_test_tp_id[5] = STEP_TRIGGER_POINT_FIRMWARE_TRIGGER_ASSERT; + g_step_test_check.step_check_test_act_id[5] = STEP_ACTION_INDEX_REGISTER; + g_step_test_check.step_check_test_tp_id[6] = -1; + g_step_test_check.step_check_test_act_id[6] = STEP_ACTION_INDEX_GPIO; + g_step_test_check.step_check_test_tp_id[7] = STEP_TRIGGER_POINT_FIRMWARE_TRIGGER_ASSERT; + g_step_test_check.step_check_test_act_id[7] = STEP_ACTION_INDEX_PERIODIC_DUMP; + g_step_test_check.step_check_test_tp_id[8] = STEP_TRIGGER_POINT_FIRMWARE_TRIGGER_ASSERT; + g_step_test_check.step_check_test_act_id[8] = STEP_ACTION_INDEX_GPIO; + g_step_test_check.step_check_test_tp_id[9] = STEP_TRIGGER_POINT_FIRMWARE_TRIGGER_ASSERT; + g_step_test_check.step_check_test_act_id[9] = STEP_ACTION_INDEX_KEEP_WAKEUP; + g_step_test_check.step_check_test_tp_id[10] = STEP_TRIGGER_POINT_FIRMWARE_TRIGGER_ASSERT; + g_step_test_check.step_check_test_act_id[10] = STEP_ACTION_INDEX_CANCEL_WAKEUP; + g_step_test_check.step_check_params[0][0] = "0"; + g_step_test_check.step_check_params[0][1] = "0x50"; + g_step_test_check.step_check_params[0][2] = "0x9c"; + g_step_test_check.step_check_params_num[0] = 3; + g_step_test_check.step_check_params[1][0] = "0"; + g_step_test_check.step_check_params[1][1] = "0x08"; + g_step_test_check.step_check_params[1][2] = "5"; + g_step_test_check.step_check_params[1][3] = "2"; + g_step_test_check.step_check_params_num[1] = 4; + g_step_test_check.step_check_params[5][0] = "1"; + g_step_test_check.step_check_params[5][1] = "0x08"; + g_step_test_check.step_check_params[5][2] = "30"; + g_step_test_check.step_check_params_num[5] = 3; + g_step_test_check.step_check_params[6][0] = "0"; + g_step_test_check.step_check_params[6][1] = "8"; + g_step_test_check.step_check_params_num[6] = 2; + g_step_test_check.step_check_params[8][0] = "1"; + g_step_test_check.step_check_params[8][1] = "6"; + g_step_test_check.step_check_params[8][2] = "3"; + g_step_test_check.step_check_params_num[8] = 3; + __wmt_step_test_parse_data(buf, &temp_report, + "STEP test case failed: (Parse data TC-8) Periodic dump\n"); + + /********************************* + ******** Test case 9 ************ + *** Boundary: Much parameter **** + *********************************/ + WMT_INFO_FUNC("STEP test: TC 9\n"); + wmt_step_test_clear_check_data(); + buf = + "// TEST NOW\r\n" + "\r\n" + "[TP 1] When Command timeout\r\n" + "[AT] _EMI 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0x10 0x11 0x12 0x13\r\n" + "\r\n"; + + g_step_test_check.step_check_total = 1; + g_step_test_check.step_check_test_tp_id[0] = STEP_TRIGGER_POINT_COMMAND_TIMEOUT; + g_step_test_check.step_check_test_act_id[0] = STEP_ACTION_INDEX_EMI; + g_step_test_check.step_check_params[0][0] = "0x1"; + g_step_test_check.step_check_params[0][1] = "0x2"; + g_step_test_check.step_check_params[0][2] = "0x3"; + g_step_test_check.step_check_params[0][3] = "0x4"; + g_step_test_check.step_check_params[0][4] = "0x5"; + g_step_test_check.step_check_params[0][5] = "0x6"; + g_step_test_check.step_check_params[0][6] = "0x7"; + g_step_test_check.step_check_params[0][7] = "0x8"; + g_step_test_check.step_check_params[0][8] = "0x9"; + g_step_test_check.step_check_params[0][9] = "0x10"; + g_step_test_check.step_check_params_num[0] = 10; + + __wmt_step_test_parse_data(buf, &temp_report, + "STEP test case failed: (Parse data TC-9) Boundary: Much parameter\n"); + + osal_gettimeofday(&sec_end, &usec_end); + wmt_step_test_show_result_report("STEP result: Parse data result", + &temp_report, sec_begin, usec_begin, sec_end, usec_end); + wmt_step_test_update_result_report(p_report, &temp_report); +} + +void wmt_step_test_create_emi_action(struct step_test_report *p_report) +{ + enum step_action_id act_id; + char *params[STEP_PARAMETER_SIZE]; + int check_params[STEP_PARAMETER_SIZE]; + struct step_test_report temp_report = {0, 0, 0}; + int sec_begin = 0; + int usec_begin = 0; + int sec_end = 0; + int usec_end = 0; + int param_num = 0; + + WMT_INFO_FUNC("STEP test: Create EMI action start\n"); + osal_gettimeofday(&sec_begin, &usec_begin); + act_id = STEP_ACTION_INDEX_EMI; + + /***************************** + ******** Test case 1 ******** + **** EMI create for read **** + *****************************/ + WMT_INFO_FUNC("STEP test: TC 1\n"); + wmt_step_test_clear_parameter(params); + params[0] = "0"; + params[1] = "0x50"; + params[2] = "0x9c"; + param_num = 3; + check_params[0] = 0; + check_params[1] = 0x50; + check_params[2] = 0x9c; + __wmt_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report, + "STEP test case failed: (Create action TC-1) EMI create"); + + /************************************ + ********** Test case 2 ************ + **** EMI create fail less param **** + ************************************/ + WMT_INFO_FUNC("STEP test: TC 2\n"); + wmt_step_test_clear_parameter(params); + params[0] = "0"; + params[1] = "0x50"; + param_num = 2; + __wmt_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report, + "STEP test case failed: (Create action TC-2) EMI create fail"); + + /************************************************* + **************** Test case 3 ******************* + ********** Save emi to temp register ************ + *************************************************/ + WMT_INFO_FUNC("STEP test: TC 3\n"); + wmt_step_test_clear_parameter(params); + params[0] = "0"; + params[1] = "0x50"; + params[2] = "0x00000030"; + params[3] = "$3"; + param_num = 4; + check_params[0] = 0; + check_params[1] = 0x50; + check_params[2] = 0x00000030; + check_params[3] = 3; + __wmt_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report, + "STEP test case failed: (Create action TC-3) Save emi to temp register"); + + /************************************************* + **************** Test case 4 ******************* + ** Boundary: Save emi to wrong temp register **** + *************************************************/ + WMT_INFO_FUNC("STEP test: TC 4\n"); + wmt_step_test_clear_parameter(params); + params[0] = "0"; + params[1] = "0x50"; + params[2] = "0x00000030"; + params[3] = "$30"; + param_num = 4; + __wmt_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report, + "STEP test case failed: (Create action TC-4) Boundary: Save emi to wrong temp register"); + + osal_gettimeofday(&sec_end, &usec_end); + wmt_step_test_show_result_report("STEP result: Create EMI action result", + &temp_report, sec_begin, usec_begin, sec_end, usec_end); + wmt_step_test_update_result_report(p_report, &temp_report); +} + +void wmt_step_test_create_cond_emi_action(struct step_test_report *p_report) +{ + enum step_action_id act_id; + char *params[STEP_PARAMETER_SIZE]; + int check_params[STEP_PARAMETER_SIZE]; + struct step_test_report temp_report = {0, 0, 0}; + int sec_begin = 0; + int usec_begin = 0; + int sec_end = 0; + int usec_end = 0; + int param_num = 0; + + WMT_INFO_FUNC("STEP test: Create condition EMI action start\n"); + osal_gettimeofday(&sec_begin, &usec_begin); + act_id = STEP_ACTION_INDEX_CONDITION_EMI; + + /************************************************* + **************** Test case 1 ******************* + ************ Condition emi create *************** + *************************************************/ + WMT_INFO_FUNC("STEP test: TC 1\n"); + wmt_step_test_clear_parameter(params); + params[0] = "$1"; + params[1] = "0"; + params[2] = "0x50"; + params[3] = "0x70"; + param_num = 4; + check_params[0] = 1; + check_params[1] = 0; + check_params[2] = 0x50; + check_params[3] = 0x70; + __wmt_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report, + "STEP test case failed: (Create action TC-1) Condition emi create"); + + /************************************************* + **************** Test case 2 ******************* + ****** Save condition emi to temp register ****** + *************************************************/ + WMT_INFO_FUNC("STEP test: TC 2\n"); + wmt_step_test_clear_parameter(params); + params[0] = "$2"; + params[1] = "0"; + params[2] = "0x50"; + params[3] = "0x00000030"; + params[4] = "$3"; + param_num = 5; + check_params[0] = 2; + check_params[1] = 0; + check_params[2] = 0x50; + check_params[3] = 0x00000030; + check_params[4] = 3; + __wmt_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report, + "STEP test case failed: (Create action TC-2) Save condition emi to temp register"); + + /*********************************************************** + ******************** Test case 3 ************************* + ** Boundary: Save condition emi to wrong temp register **** + ***********************************************************/ + WMT_INFO_FUNC("STEP test: TC 3\n"); + wmt_step_test_clear_parameter(params); + params[0] = "$1"; + params[1] = "0"; + params[2] = "0x50"; + params[3] = "0x00000030"; + params[4] = "$30"; + param_num = 5; + __wmt_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report, + "STEP test case failed: (Create action TC-3) Boundary: Boundary: Save condition emi to wrong temp register"); + + /*********************************************************** + ******************** Test case 4 ************************* + ** Boundary: Save condition emi is wrong temp register **** + ***********************************************************/ + WMT_INFO_FUNC("STEP test: TC 4\n"); + wmt_step_test_clear_parameter(params); + params[0] = "$30"; + params[1] = "0"; + params[2] = "0x50"; + params[3] = "0x00000030"; + params[4] = "$1"; + param_num = 5; + __wmt_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report, + "STEP test case failed: (Create action TC-4) Boundary: Boundary: Save condition emi is wrong temp register"); + + /************************************************* + **************** Test case 5 ******************* + ******* Condition emi create less params ******** + *************************************************/ + WMT_INFO_FUNC("STEP test: TC 5\n"); + wmt_step_test_clear_parameter(params); + params[0] = "$1"; + params[1] = "0"; + params[2] = "0x50"; + param_num = 3; + __wmt_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report, + "STEP test case failed: (Create action TC-5) Condition emi create less params"); + + /************************************************* + **************** Test case 6 ******************* + ******* Condition emi create wrong symbol ******* + *************************************************/ + WMT_INFO_FUNC("STEP test: TC 6\n"); + wmt_step_test_clear_parameter(params); + params[0] = "1"; + params[1] = "0"; + params[2] = "0x50"; + params[3] = "0x00000030"; + params[4] = "$1"; + param_num = 5; + __wmt_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report, + "STEP test case failed: (Create action TC-6) Condition emi create wrong symbol"); + + osal_gettimeofday(&sec_end, &usec_end); + wmt_step_test_show_result_report("STEP result: Create condition EMI action result", + &temp_report, sec_begin, usec_begin, sec_end, usec_end); + wmt_step_test_update_result_report(p_report, &temp_report); +} + +void wmt_step_test_create_register_action(struct step_test_report *p_report) +{ + enum step_action_id act_id; + char *params[STEP_PARAMETER_SIZE]; + int check_params[STEP_PARAMETER_SIZE]; + struct step_test_report temp_report = {0, 0, 0}; + int sec_begin = 0; + int usec_begin = 0; + int sec_end = 0; + int usec_end = 0; + int param_num = 0; + + WMT_INFO_FUNC("STEP test: Create Register action start\n"); + osal_gettimeofday(&sec_begin, &usec_begin); + act_id = STEP_ACTION_INDEX_REGISTER; + + /**************************************** + ************ Test case 1 *************** + **** REGISTER(Addr) create for read **** + ****************************************/ + WMT_INFO_FUNC("STEP test: TC 1\n"); + wmt_step_test_clear_parameter(params); + params[0] = "0"; + params[1] = "0x124dfad"; + params[2] = "0x9c"; + params[3] = "2"; + params[4] = "10"; + param_num = 5; + check_params[0] = 0; + check_params[1] = 0x124dfad; + check_params[2] = 0x9c; + check_params[3] = 2; + check_params[4] = 10; + __wmt_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report, + "STEP test case failed: (Create action TC-1) REG create read"); + + /***************************************** + ************ Test case 2 **************** + **** REGISTER(Addr) create for write **** + *****************************************/ + WMT_INFO_FUNC("STEP test: TC 2\n"); + wmt_step_test_clear_parameter(params); + params[0] = "1"; + params[1] = "0x124dfad"; + params[2] = "0x9c"; + params[3] = "15"; + param_num = 4; + check_params[0] = 1; + check_params[1] = 0x124dfad; + check_params[2] = 0x9c; + check_params[3] = 15; + __wmt_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report, + "STEP test case failed: (Create action TC-2) REG create write"); + + /****************************************** + ************** Test case 3 *************** + ******* Boundary: read wrong symbol ****** + ******************************************/ + WMT_INFO_FUNC("STEP test: TC 3\n"); + wmt_step_test_clear_parameter(params); + params[0] = "0"; + params[1] = "#10000"; + params[2] = "0x204"; + params[3] = "1"; + params[4] = "0"; + param_num = 5; + check_params[0] = 0; + check_params[1] = 0x124dfad; + check_params[2] = 0x9c; + check_params[3] = 2; + check_params[4] = 10; + __wmt_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report, + "STEP test case failed: (Create action TC-3) Boundary: read wrong symbol"); + + /**************************************************** + **************** Test case 4 ********************** + **** REGISTER(Addr) create read fail less param **** + ****************************************************/ + WMT_INFO_FUNC("STEP test: TC 4\n"); + wmt_step_test_clear_parameter(params); + params[0] = "0"; + params[1] = "0x124dfad"; + params[2] = "0x9c"; + param_num = 3; + __wmt_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report, + "STEP test case failed: (Create action TC-4) REG create read fail"); + + /***************************************************** + ************ Test case 5 *************************** + **** REGISTER(Addr) create write fail less param **** + *****************************************************/ + WMT_INFO_FUNC("STEP test: TC 5\n"); + wmt_step_test_clear_parameter(params); + params[0] = "1"; + params[1] = "0x124dfad"; + params[2] = "0x9c"; + param_num = 3; + __wmt_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report, + "STEP test case failed: (Create action TC-5) REG create write fail"); + + /***************************************** + ************ Test case 6 **************** + ** REGISTER(Addr) create for write bit *** + *****************************************/ + WMT_INFO_FUNC("STEP test: TC 6\n"); + wmt_step_test_clear_parameter(params); + params[0] = "1"; + params[1] = "0x124dfad"; + params[2] = "0x9c"; + params[3] = "15"; + params[4] = "0xFF00FF00"; + param_num = 5; + check_params[0] = 1; + check_params[1] = 0x124dfad; + check_params[2] = 0x9c; + check_params[3] = 15; + check_params[4] = 0xFF00FF00; + __wmt_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report, + "STEP test case failed: (Create action TC-6) REG create write"); + + /********************************************************* + ******************** Test case 7 *********************** + **** REGISTER(Addr) create for read to temp register **** + *********************************************************/ + WMT_INFO_FUNC("STEP test: TC 7\n"); + wmt_step_test_clear_parameter(params); + params[0] = "0"; + params[1] = "0x124dfad"; + params[2] = "0x9c"; + params[3] = "0x00000030"; + params[4] = "$5"; + param_num = 5; + check_params[0] = 0; + check_params[1] = 0x124dfad; + check_params[2] = 0x9c; + check_params[3] = 0x00000030; + check_params[4] = 5; + __wmt_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report, + "STEP test case failed: (Create action TC-7) REGISTER(Addr) create for read to temp register"); + + /********************************************************* + ******************** Test case 8 *********************** + *** REGISTER(Symbol) create for read to temp register *** + *********************************************************/ + WMT_INFO_FUNC("STEP test: TC 8\n"); + wmt_step_test_clear_parameter(params); + params[0] = "0"; + params[1] = "#1"; + params[2] = "0x9c"; + params[3] = "0x00000030"; + params[4] = "$7"; + param_num = 5; + check_params[0] = 0; + check_params[1] = 1; + check_params[2] = 0x9c; + check_params[3] = 0x00000030; + check_params[4] = 7; + __wmt_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report, + "STEP test case failed: (Create action TC-8) REGISTER(Symbol) create for read to temp register"); + + /********************************************************* + ******************** Test case 9 *********************** + ********** REGISTER(Symbol) create for read ************* + *********************************************************/ + WMT_INFO_FUNC("STEP test: TC 9\n"); + wmt_step_test_clear_parameter(params); + params[0] = "0"; + params[1] = "#1"; + params[2] = "0x9c"; + params[3] = "1"; + params[4] = "10"; + param_num = 5; + check_params[0] = 0; + check_params[1] = 1; + check_params[2] = 0x9c; + check_params[3] = 1; + check_params[4] = 10; + __wmt_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report, + "STEP test case failed: (Create action TC-9) REGISTER(Symbol) create for read"); + + /********************************************************* + ******************** Test case 10 *********************** + ************ REGISTER(Addr) less parameter ************** + *********************************************************/ + WMT_INFO_FUNC("STEP test: TC 10\n"); + wmt_step_test_clear_parameter(params); + params[0] = "0"; + params[1] = "0x124dfad"; + params[2] = "0x9c"; + params[3] = "0x555"; + param_num = 4; + __wmt_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report, + "STEP test case failed: (Create action TC-10) REGISTER(Addr) less parameter"); + + /********************************************************* + ******************** Test case 11 *********************** + ************ REGISTER(Symbol) less parameter ************** + *********************************************************/ + WMT_INFO_FUNC("STEP test: TC 11\n"); + wmt_step_test_clear_parameter(params); + params[0] = "0"; + params[1] = "#1"; + params[2] = "0x9c"; + params[3] = "0x555"; + param_num = 4; + __wmt_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report, + "STEP test case failed: (Create action TC-11) REGISTER(Symbol) less parameter"); + + /********************************************************** + *********************** Test case 12 ********************* + ** Boundary: REGISTER(Addr) read to worng temp register ** + **********************************************************/ + WMT_INFO_FUNC("STEP test: TC 12\n"); + wmt_step_test_clear_parameter(params); + params[0] = "0"; + params[1] = "0x124dfad"; + params[2] = "0x9c"; + params[3] = "0x00000030"; + params[4] = "$35"; + param_num = 5; + __wmt_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report, + "STEP test case failed: (Create action TC-12) Boundary: REGISTER(Addr) read to worng temp registe"); + + /************************************************************ + *********************** Test case 13 *********************** + ** Boundary: REGISTER(Symbol) read to worng temp register ** + ************************************************************/ + WMT_INFO_FUNC("STEP test: TC 13\n"); + wmt_step_test_clear_parameter(params); + params[0] = "0"; + params[1] = "#1"; + params[2] = "0x9c"; + params[3] = "0x00000030"; + params[4] = "$35"; + param_num = 5; + __wmt_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report, + "STEP test case failed: (Create action TC-13) Boundary: REGISTER(Symbol) read to worng temp registe"); + + osal_gettimeofday(&sec_end, &usec_end); + wmt_step_test_show_result_report("STEP result: Create register action result", + &temp_report, sec_begin, usec_begin, sec_end, usec_end); + wmt_step_test_update_result_report(p_report, &temp_report); +} + +void wmt_step_test_create_cond_register_action(struct step_test_report *p_report) +{ + enum step_action_id act_id; + char *params[STEP_PARAMETER_SIZE]; + int check_params[STEP_PARAMETER_SIZE]; + struct step_test_report temp_report = {0, 0, 0}; + int sec_begin = 0; + int usec_begin = 0; + int sec_end = 0; + int usec_end = 0; + int param_num = 0; + + WMT_INFO_FUNC("STEP test: Create condition Register action start\n"); + osal_gettimeofday(&sec_begin, &usec_begin); + act_id = STEP_ACTION_INDEX_CONDITION_REGISTER; + + /**************************************** + ************ Test case 1 *************** + **** COND_REG(Addr) create for read **** + ****************************************/ + WMT_INFO_FUNC("STEP test: TC 1\n"); + wmt_step_test_clear_parameter(params); + params[0] = "$5"; + params[1] = "0"; + params[2] = "0x124dfad"; + params[3] = "0x9c"; + params[4] = "2"; + params[5] = "10"; + param_num = 6; + check_params[0] = 5; + check_params[1] = 0; + check_params[2] = 0x124dfad; + check_params[3] = 0x9c; + check_params[4] = 2; + check_params[5] = 10; + __wmt_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report, + "STEP test case failed: (Create action TC-1) COND_REG(Addr) create for read"); + + /***************************************** + ************ Test case 2 **************** + **** COND_REG(Addr) create for write **** + *****************************************/ + WMT_INFO_FUNC("STEP test: TC 2\n"); + wmt_step_test_clear_parameter(params); + params[0] = "$7"; + params[1] = "1"; + params[2] = "0x124dfad"; + params[3] = "0x9c"; + params[4] = "15"; + param_num = 5; + check_params[0] = 7; + check_params[1] = 1; + check_params[2] = 0x124dfad; + check_params[3] = 0x9c; + check_params[4] = 15; + __wmt_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report, + "STEP test case failed: (Create action TC-2) COND_REG(Addr) create write"); + + /****************************************** + ************** Test case 3 *************** + ******* Boundary: read wrong symbol ****** + ******************************************/ + WMT_INFO_FUNC("STEP test: TC 3\n"); + wmt_step_test_clear_parameter(params); + params[0] = "$2"; + params[1] = "0"; + params[2] = "#10000"; + params[3] = "0x204"; + params[4] = "1"; + params[5] = "0"; + param_num = 6; + check_params[0] = 2; + check_params[1] = 0; + check_params[2] = 0x124dfad; + check_params[3] = 0x9c; + check_params[4] = 2; + check_params[5] = 10; + __wmt_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report, + "STEP test case failed: (Create action TC-3) Boundary: read wrong symbol"); + + /**************************************************** + **************** Test case 4 ********************** + **** COND_REG(Addr) create read fail less param **** + ****************************************************/ + WMT_INFO_FUNC("STEP test: TC 4\n"); + wmt_step_test_clear_parameter(params); + params[0] = "$3"; + params[1] = "0"; + params[2] = "0x124dfad"; + params[3] = "0x9c"; + param_num = 4; + __wmt_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report, + "STEP test case failed: (Create action TC-4) COND_REG create read fail"); + + /***************************************************** + ************ Test case 5 *************************** + **** COND_REG(Addr) create write fail less param **** + *****************************************************/ + WMT_INFO_FUNC("STEP test: TC 5\n"); + wmt_step_test_clear_parameter(params); + params[0] = "$4"; + params[1] = "1"; + params[2] = "0x124dfad"; + params[3] = "0x9c"; + param_num = 4; + __wmt_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report, + "STEP test case failed: (Create action TC-5) COND_REG create write fail"); + + /***************************************** + ************ Test case 6 **************** + ** COND_REG(Addr) create for write bit *** + *****************************************/ + WMT_INFO_FUNC("STEP test: TC 6\n"); + wmt_step_test_clear_parameter(params); + params[0] = "$9"; + params[1] = "1"; + params[2] = "0x124dfad"; + params[3] = "0x9c"; + params[4] = "15"; + params[5] = "0xFF00FF00"; + param_num = 6; + check_params[0] = 9; + check_params[1] = 1; + check_params[2] = 0x124dfad; + check_params[3] = 0x9c; + check_params[4] = 15; + check_params[5] = 0xFF00FF00; + __wmt_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report, + "STEP test case failed: (Create action TC-6) COND_REG create write"); + + /********************************************************* + ******************** Test case 7 *********************** + **** COND_REG(Addr) create for read to temp register **** + *********************************************************/ + WMT_INFO_FUNC("STEP test: TC 7\n"); + wmt_step_test_clear_parameter(params); + params[0] = "$9"; + params[1] = "0"; + params[2] = "0x124dfad"; + params[3] = "0x9c"; + params[4] = "0x00000030"; + params[5] = "$5"; + param_num = 6; + check_params[0] = 9; + check_params[1] = 0; + check_params[2] = 0x124dfad; + check_params[3] = 0x9c; + check_params[4] = 0x00000030; + check_params[5] = 5; + __wmt_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report, + "STEP test case failed: (Create action TC-7) COND_REG(Addr) create for read to temp register"); + + /********************************************************* + ******************** Test case 8 *********************** + *** COND_REG(Symbol) create for read to temp register *** + *********************************************************/ + WMT_INFO_FUNC("STEP test: TC 8\n"); + wmt_step_test_clear_parameter(params); + params[0] = "$1"; + params[1] = "0"; + params[2] = "#1"; + params[3] = "0x9c"; + params[4] = "0x00000030"; + params[5] = "$7"; + param_num = 6; + check_params[0] = 1; + check_params[1] = 0; + check_params[2] = 1; + check_params[3] = 0x9c; + check_params[4] = 0x00000030; + check_params[5] = 7; + __wmt_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report, + "STEP test case failed: (Create action TC-8) COND_REG(Symbol) create for read to temp register"); + + /********************************************************* + ******************** Test case 9 *********************** + ********** COND_REG(Symbol) create for read ************* + *********************************************************/ + WMT_INFO_FUNC("STEP test: TC 9\n"); + wmt_step_test_clear_parameter(params); + params[0] = "$2"; + params[1] = "0"; + params[2] = "#1"; + params[3] = "0x9c"; + params[4] = "1"; + params[5] = "10"; + param_num = 6; + check_params[0] = 2; + check_params[1] = 0; + check_params[2] = 1; + check_params[3] = 0x9c; + check_params[4] = 1; + check_params[5] = 10; + __wmt_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report, + "STEP test case failed: (Create action TC-9) COND_REG(Symbol) create for read"); + + /********************************************************* + ******************** Test case 10 *********************** + ************ COND_REG(Addr) less parameter ************** + *********************************************************/ + WMT_INFO_FUNC("STEP test: TC 10\n"); + wmt_step_test_clear_parameter(params); + params[0] = "$3"; + params[1] = "0"; + params[2] = "0x124dfad"; + params[3] = "0x9c"; + params[4] = "0x555"; + param_num = 5; + __wmt_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report, + "STEP test case failed: (Create action TC-10) COND_REG(Addr) less parameter"); + + /********************************************************* + ******************** Test case 11 *********************** + ************ COND_REG(Symbol) less parameter ************** + *********************************************************/ + WMT_INFO_FUNC("STEP test: TC 11\n"); + wmt_step_test_clear_parameter(params); + params[0] = "$4"; + params[1] = "0"; + params[2] = "#1"; + params[3] = "0x9c"; + params[4] = "0x555"; + param_num = 5; + __wmt_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report, + "STEP test case failed: (Create action TC-11) COND_REG(Symbol) less parameter"); + + /********************************************************** + *********************** Test case 12 ********************* + ** Boundary: COND_REG(Addr) read to worng temp register ** + **********************************************************/ + WMT_INFO_FUNC("STEP test: TC 12\n"); + wmt_step_test_clear_parameter(params); + params[0] = "$5"; + params[1] = "0"; + params[2] = "0x124dfad"; + params[3] = "0x9c"; + params[4] = "0x00000030"; + params[5] = "$35"; + param_num = 6; + __wmt_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report, + "STEP test case failed: (Create action TC-12) Boundary: COND_REG(Addr) read to worng temp registe"); + + /************************************************************ + *********************** Test case 13 *********************** + ** Boundary: COND_REG(Symbol) read to worng temp register ** + ************************************************************/ + WMT_INFO_FUNC("STEP test: TC 13\n"); + wmt_step_test_clear_parameter(params); + params[0] = "$6"; + params[1] = "0"; + params[2] = "#1"; + params[3] = "0x9c"; + params[4] = "0x00000030"; + params[5] = "$35"; + param_num = 6; + __wmt_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report, + "STEP test case failed: (Create action TC-13) Boundary: COND_REG(Symbol) read to worng temp registe"); + + /********************************************************* + ******************** Test case 14 *********************** + ************* COND_REG(Symbol) worng symbol ************* + *********************************************************/ + WMT_INFO_FUNC("STEP test: TC 14\n"); + wmt_step_test_clear_parameter(params); + params[0] = "8"; + params[1] = "0"; + params[2] = "#1"; + params[3] = "0x9c"; + params[4] = "1"; + params[5] = "10"; + param_num = 6; + __wmt_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report, + "STEP test case failed: (Create action TC-14) Boundary: COND_REG(Symbol) worng symbol"); + + /********************************************************* + ******************** Test case 15 *********************** + ********* COND_REG(Symbol) worng temp register id ******* + *********************************************************/ + WMT_INFO_FUNC("STEP test: TC 15\n"); + wmt_step_test_clear_parameter(params); + params[0] = "$88"; + params[1] = "0"; + params[2] = "#1"; + params[3] = "0x9c"; + params[4] = "1"; + params[5] = "10"; + param_num = 6; + __wmt_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report, + "STEP test case failed: (Create action TC-15) Boundary: COND_REG(Symbol) read to worng temp registe"); + + + osal_gettimeofday(&sec_end, &usec_end); + wmt_step_test_show_result_report("STEP result: Create condition register action result", + &temp_report, sec_begin, usec_begin, sec_end, usec_end); + wmt_step_test_update_result_report(p_report, &temp_report); +} + +int wmt_step_test_get_symbol_num(void) +{ + int len = 0; + struct device_node *node = NULL; + + if (g_pdev != NULL) { + node = g_pdev->dev.of_node; + if (node) { + of_get_property(node, "reg", &len); + len /= (of_n_addr_cells(node) + of_n_size_cells(node)); + len /= (sizeof(int)); + } else { + WMT_ERR_FUNC("STEP test failed: node null"); + return -1; + } + } else { + WMT_ERR_FUNC("STEP test failed: gdev null"); + return -1; + } + + return len; +} + +void wmt_step_test_check_register_symbol(struct step_test_report *p_report) +{ + enum step_action_id act_id; + char *params[STEP_PARAMETER_SIZE]; + int check_params[STEP_PARAMETER_SIZE]; + struct step_test_report temp_report = {0, 0, 0}; + int sec_begin = 0; + int usec_begin = 0; + int sec_end = 0; + int usec_end = 0; + int param_num = 0; + int i = 0; + int symbol_num = wmt_step_test_get_symbol_num(); + unsigned char buf[4]; + + WMT_INFO_FUNC("STEP test: Check Register symbol start\n"); + osal_gettimeofday(&sec_begin, &usec_begin); + act_id = STEP_ACTION_INDEX_REGISTER; + /********************************************************* + ******************** Test case 1 *********************** + ********** REGISTER(Symbol) create for read ************* + *********************************************************/ + WMT_INFO_FUNC("STEP test: TC 1\n"); + if (symbol_num < 0) { + temp_report.fail++; + } else { + if (symbol_num >= STEP_REGISTER_MAX) { + symbol_num = STEP_REGISTER_MAX - 1; + } + + for (i = 1; i <= symbol_num; i++) { + wmt_step_test_clear_parameter(params); + params[0] = "0"; + if (snprintf(buf, 4, "#%d", i) < 0) + WMT_INFO_FUNC("[%s::%d] snprintf buf fail\n", __func__, __LINE__); + else + params[1] = buf; + params[2] = "0x9c"; + params[3] = "1"; + params[4] = "10"; + param_num = 5; + check_params[0] = 0; + check_params[1] = i; + check_params[2] = 0x9c; + check_params[3] = 1; + check_params[4] = 10; + __wmt_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report, + "STEP test case failed: (Check Register symbol TC-1) REGISTER(Symbol) create for read"); + } + } + + osal_gettimeofday(&sec_end, &usec_end); + wmt_step_test_show_result_report("STEP result: Check Register symbol result", + &temp_report, sec_begin, usec_begin, sec_end, usec_end); + wmt_step_test_update_result_report(p_report, &temp_report); +} + +void wmt_step_test_create_other_action(struct step_test_report *p_report) +{ + enum step_action_id act_id; + char *params[STEP_PARAMETER_SIZE]; + int check_params[STEP_PARAMETER_SIZE]; + struct step_test_report temp_report = {0, 0, 0}; + int sec_begin = 0; + int usec_begin = 0; + int sec_end = 0; + int usec_end = 0; + struct step_pd_entry fack_pd_entry; + int param_num = 0; + + WMT_INFO_FUNC("STEP test: Create other action start\n"); + osal_gettimeofday(&sec_begin, &usec_begin); + /****************************************** + ************ Test case 1 ***************** + ********** GPIO create for read ********** + ******************************************/ + WMT_INFO_FUNC("STEP test: TC 1\n"); + wmt_step_test_clear_parameter(params); + act_id = STEP_ACTION_INDEX_GPIO; + params[0] = "0"; + params[1] = "8"; + param_num = 2; + check_params[0] = 0; + check_params[1] = 8; + __wmt_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report, + "STEP test case failed: (Create action TC-1) GPIO create read"); + + /***************************************** + ************ Test case 2 **************** + ********* DISABLE REST create *********** + *****************************************/ + WMT_INFO_FUNC("STEP test: TC 2\n"); + wmt_step_test_clear_parameter(params); + act_id = STEP_ACTION_INDEX_DISABLE_RESET; + param_num = 0; + __wmt_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report, + "STEP test case failed: (Create action TC-2) DISABLE REST"); + + /***************************************** + ************ Test case 3 **************** + ********** CHIP REST create ************* + *****************************************/ + WMT_INFO_FUNC("STEP test: TC 3\n"); + wmt_step_test_clear_parameter(params); + act_id = STEP_ACTION_INDEX_CHIP_RESET; + param_num = 0; + __wmt_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report, + "STEP test case failed: (Create action TC-3) CHIP REST"); + + /***************************************** + ************ Test case 4 **************** + ******** Keep Wakeup create ************* + *****************************************/ + WMT_INFO_FUNC("STEP test: TC 4\n"); + wmt_step_test_clear_parameter(params); + act_id = STEP_ACTION_INDEX_KEEP_WAKEUP; + param_num = 0; + __wmt_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report, + "STEP test case failed: (Create action TC-4) Keep wakeup"); + + /***************************************** + ************ Test case 5 **************** + ***** Cancel keep wakeup create ********* + *****************************************/ + WMT_INFO_FUNC("STEP test: TC 5\n"); + wmt_step_test_clear_parameter(params); + act_id = STEP_ACTION_INDEX_CANCEL_WAKEUP; + param_num = 0; + __wmt_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report, + "STEP test case failed: (Create action TC-5) Cancel keep wakeup"); + + /************************************************* + **************** Test case 6 ******************* + ********** GPIO create fail less param ********** + *************************************************/ + WMT_INFO_FUNC("STEP test: TC 6\n"); + wmt_step_test_clear_parameter(params); + act_id = STEP_ACTION_INDEX_GPIO; + params[0] = "0"; + param_num = 1; + __wmt_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report, + "STEP test case failed: (Create action TC-6) GPIO create fail"); + + /************************************************* + **************** Test case 7 ******************* + ************** Periodic dump create ************* + *************************************************/ + WMT_INFO_FUNC("STEP test: TC 7\n"); + wmt_step_test_clear_parameter(params); + act_id = STEP_ACTION_INDEX_PERIODIC_DUMP; + params[0] = (PINT8)&fack_pd_entry; + param_num = 1; + __wmt_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report, + "STEP test case failed: (Create action TC-7) Periodic dump create fail"); + + /************************************************* + **************** Test case 8 ******************* + ****** Periodic dump create fail no param ******* + *************************************************/ + WMT_INFO_FUNC("STEP test: TC 8\n"); + wmt_step_test_clear_parameter(params); + act_id = STEP_ACTION_INDEX_PERIODIC_DUMP; + param_num = 0; + __wmt_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report, + "STEP test case failed: (Create action TC-8) Periodic dump create fail"); + + /************************************************* + **************** Test case 9 ******************* + **************** Show create ******************** + *************************************************/ + WMT_INFO_FUNC("STEP test: TC 9\n"); + wmt_step_test_clear_parameter(params); + act_id = STEP_ACTION_INDEX_SHOW_STRING; + params[0] = "Hello"; + param_num = 1; + __wmt_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report, + "STEP test case failed: (Create action TC-9) Show create"); + + /************************************************* + **************** Test case 10 ******************* + ******** Show create failed no param ************ + *************************************************/ + WMT_INFO_FUNC("STEP test: TC 10\n"); + wmt_step_test_clear_parameter(params); + act_id = STEP_ACTION_INDEX_SHOW_STRING; + param_num = 0; + __wmt_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report, + "STEP test case failed: (Create action TC-10) Show create failed no param"); + + /************************************************* + **************** Test case 11 ******************* + **************** Sleep create ******************* + *************************************************/ + WMT_INFO_FUNC("STEP test: TC 11\n"); + wmt_step_test_clear_parameter(params); + act_id = STEP_ACTION_INDEX_SLEEP; + params[0] = "1000"; + param_num = 1; + check_params[0] = 1000; + __wmt_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report, + "STEP test case failed: (Create action TC-11) Sleep create"); + + /************************************************* + **************** Test case 12 ******************* + ********* Sleep create failed no param ********** + *************************************************/ + WMT_INFO_FUNC("STEP test: TC 12\n"); + wmt_step_test_clear_parameter(params); + act_id = STEP_ACTION_INDEX_SLEEP; + param_num = 0; + __wmt_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report, + "STEP test case failed: (Create action TC-12) Sleep create failed no param"); + + /************************************************* + **************** Test case 13 ******************* + ************** Condition create ***************** + *************************************************/ + WMT_INFO_FUNC("STEP test: TC 13\n"); + wmt_step_test_clear_parameter(params); + act_id = STEP_ACTION_INDEX_CONDITION; + params[0] = "$0"; + params[1] = "$1"; + params[2] = "=="; + params[3] = "$2"; + param_num = 4; + check_params[0] = 0; + check_params[1] = 1; + check_params[2] = STEP_OPERATOR_EQUAL; + check_params[3] = 2; + __wmt_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report, + "STEP test case failed: (Create action TC-13) Condition create"); + + /************************************************* + **************** Test case 14 ******************* + *********** Condition create value ************** + *************************************************/ + WMT_INFO_FUNC("STEP test: TC 14\n"); + wmt_step_test_clear_parameter(params); + act_id = STEP_ACTION_INDEX_CONDITION; + params[0] = "$0"; + params[1] = "$1"; + params[2] = "=="; + params[3] = "16"; + param_num = 4; + check_params[0] = 0; + check_params[1] = 1; + check_params[2] = STEP_OPERATOR_EQUAL; + check_params[3] = 16; + __wmt_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report, + "STEP test case failed: (Create action TC-14) Condition create"); + + /************************************************* + **************** Test case 15 ******************* + ****** Condition create failed less param ******* + *************************************************/ + WMT_INFO_FUNC("STEP test: TC 15\n"); + wmt_step_test_clear_parameter(params); + act_id = STEP_ACTION_INDEX_CONDITION; + params[0] = "$0"; + params[1] = "$1"; + params[2] = "$2"; + param_num = 3; + __wmt_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report, + "STEP test case failed: (Create action TC-15) Condition create failed less param"); + + /************************************************* + **************** Test case 16 ******************* + ******** Condition create failed no value******** + *************************************************/ + WMT_INFO_FUNC("STEP test: TC 16\n"); + wmt_step_test_clear_parameter(params); + act_id = STEP_ACTION_INDEX_CONDITION; + params[0] = "=="; + param_num = 1; + __wmt_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report, + "STEP test case failed: (Create action TC-16) Condition create failed no value"); + + /************************************************* + **************** Test case 17 ******************* + * Boundary: Condition create failed over reg id * + *************************************************/ + WMT_INFO_FUNC("STEP test: TC 17\n"); + wmt_step_test_clear_parameter(params); + act_id = STEP_ACTION_INDEX_CONDITION; + params[0] = "$25"; + params[1] = "$1"; + params[2] = "=="; + params[3] = "$2"; + param_num = 4; + __wmt_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report, + "STEP test case failed: (Create action TC-17) Boundary: Condition create failed over reg id"); + + /************************************************* + **************** Test case 18 ******************* + * Boundary: Condition create failed over reg id * + *************************************************/ + WMT_INFO_FUNC("STEP test: TC 18\n"); + wmt_step_test_clear_parameter(params); + act_id = STEP_ACTION_INDEX_CONDITION; + params[0] = "$0"; + params[1] = "$1"; + params[2] = "=="; + params[3] = "$20"; + param_num = 4; + __wmt_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report, + "STEP test case failed: (Create action TC-18) Boundary: Condition create failed over reg id"); + + /************************************************* + **************** Test case 19 ******************* + ******** Condition create failed operator******** + *************************************************/ + WMT_INFO_FUNC("STEP test: TC 19\n"); + wmt_step_test_clear_parameter(params); + act_id = STEP_ACTION_INDEX_CONDITION; + params[0] = "$0"; + params[1] = "$1"; + params[2] = "&"; + params[3] = "$2"; + param_num = 4; + __wmt_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report, + "STEP test case failed: (Create action TC-19) Condition create failed operator"); + + /************************************************* + **************** Test case 20 ******************* + **************** Value create ******************* + *************************************************/ + WMT_INFO_FUNC("STEP test: TC 20\n"); + wmt_step_test_clear_parameter(params); + act_id = STEP_ACTION_INDEX_VALUE; + params[0] = "$0"; + params[1] = "0x123"; + param_num = 2; + check_params[0] = 0; + check_params[1] = 0x123; + __wmt_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report, + "STEP test case failed: (Create action TC-20) Condition create"); + + /************************************************* + **************** Test case 21 ******************* + ******* Value create failed wrong order ********* + *************************************************/ + WMT_INFO_FUNC("STEP test: TC 21\n"); + wmt_step_test_clear_parameter(params); + act_id = STEP_ACTION_INDEX_VALUE; + params[0] = "0x123"; + params[1] = "$1"; + param_num = 2; + __wmt_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report, + "STEP test case failed: (Create action TC-21) Value create failed wrong order"); + + /************************************************* + **************** Test case 22 ******************* + ********* Value create failed no value ********** + *************************************************/ + WMT_INFO_FUNC("STEP test: TC 22\n"); + wmt_step_test_clear_parameter(params); + act_id = STEP_ACTION_INDEX_VALUE; + params[0] = "$1"; + param_num = 1; + __wmt_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report, + "STEP test case failed: (Create action TC-22) Value create failed no value"); + + /************************************************* + **************** Test case 23 ******************* + *** Boundary: Value create failed over reg id *** + *************************************************/ + WMT_INFO_FUNC("STEP test: TC 23\n"); + wmt_step_test_clear_parameter(params); + act_id = STEP_ACTION_INDEX_VALUE; + params[0] = "$25"; + params[1] = "0x123"; + param_num = 2; + __wmt_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report, + "STEP test case failed: (Create action TC-23) Boundary: Value create failed over reg id"); + + osal_gettimeofday(&sec_end, &usec_end); + wmt_step_test_show_result_report("STEP result: Create other action result", + &temp_report, sec_begin, usec_begin, sec_end, usec_end); + wmt_step_test_update_result_report(p_report, &temp_report); +} + +int wmt_step_test_get_emi_wmt_offset(unsigned char buf[], int offset) +{ + P_CONSYS_EMI_ADDR_INFO emi_phy_addr; + + emi_phy_addr = mtk_wcn_consys_soc_get_emi_phy_add(); + if (emi_phy_addr != NULL) { + if (snprintf(buf, 11, "0x%08x", ((unsigned int)emi_phy_addr->emi_core_dump_offset + offset)) < 0) { + WMT_INFO_FUNC("[%s::%d] snprintf buf fail\n", __func__, __LINE__); + return -1; + } + } else { + WMT_ERR_FUNC("STEP test failed: emi_phy_addr is NULL\n"); + return -1; + } + + return 0; +} + +void wmt_step_test_do_emi_action(struct step_test_report *p_report) +{ + enum step_action_id act_id; + char *params[STEP_PARAMETER_SIZE]; + struct step_test_report temp_report = {0, 0, 0}; + int sec_begin = 0; + int usec_begin = 0; + int sec_end = 0; + int usec_end = 0; + unsigned char buf_begin[11]; + unsigned char buf_end[11]; + int param_num; + + WMT_INFO_FUNC("STEP test: Do EMI action start\n"); + osal_gettimeofday(&sec_begin, &usec_begin); + act_id = STEP_ACTION_INDEX_EMI; + + if (wmt_step_test_get_emi_wmt_offset(buf_begin, 0x0) != 0) { + temp_report.fail++; + osal_gettimeofday(&sec_end, &usec_end); + wmt_step_test_show_result_report("STEP result: Do EMI action result", + &temp_report, sec_begin, usec_begin, sec_end, usec_end); + wmt_step_test_update_result_report(p_report, &temp_report); + return; + } + + /***************************************** + ************ Test case 1 **************** + ********** EMI dump 32 bit ************** + *****************************************/ + WMT_INFO_FUNC("STEP test: TC 1\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + params[0] = "0"; + wmt_step_test_get_emi_wmt_offset(buf_begin, 0x44); + params[1] = buf_begin; + wmt_step_test_get_emi_wmt_offset(buf_end, 0x48); + params[2] = buf_end; + param_num = 3; + g_step_test_check.step_check_total = 1; + g_step_test_check.step_check_emi_offset[0] = 0x44; + __wmt_step_test_do_emi_action(act_id, param_num, params, 0, &temp_report, + "STEP test case failed: (Do EMI action TC-1) dump 32bit"); + + /***************************************** + ************ Test case 2 **************** + ****** EMI dump check for address ******* + *****************************************/ + WMT_INFO_FUNC("STEP test: TC 2\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + params[0] = "0"; + wmt_step_test_get_emi_wmt_offset(buf_begin, 0x24); + params[1] = buf_begin; + wmt_step_test_get_emi_wmt_offset(buf_end, 0x44); + params[2] = buf_end; + param_num = 3; + g_step_test_check.step_check_total = 8; + g_step_test_check.step_check_emi_offset[0] = 0x24; + g_step_test_check.step_check_emi_offset[1] = 0x28; + g_step_test_check.step_check_emi_offset[2] = 0x2c; + g_step_test_check.step_check_emi_offset[3] = 0x30; + g_step_test_check.step_check_emi_offset[4] = 0x34; + g_step_test_check.step_check_emi_offset[5] = 0x38; + g_step_test_check.step_check_emi_offset[6] = 0x3c; + g_step_test_check.step_check_emi_offset[7] = 0x40; + __wmt_step_test_do_emi_action(act_id, param_num, params, 0, &temp_report, + "STEP test case failed: (Do EMI action TC-2) more address"); + + /***************************************** + ************ Test case 3 **************** + **** EMI dump begin larger than end ***** + *****************************************/ + WMT_INFO_FUNC("STEP test: TC 3\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + params[0] = "0"; + wmt_step_test_get_emi_wmt_offset(buf_begin, 0x20); + params[1] = buf_begin; + wmt_step_test_get_emi_wmt_offset(buf_end, 0x08); + params[2] = buf_end; + param_num = 3; + g_step_test_check.step_check_total = 6; + g_step_test_check.step_check_emi_offset[0] = 0x08; + g_step_test_check.step_check_emi_offset[1] = 0x0c; + g_step_test_check.step_check_emi_offset[2] = 0x10; + g_step_test_check.step_check_emi_offset[3] = 0x14; + g_step_test_check.step_check_emi_offset[4] = 0x18; + g_step_test_check.step_check_emi_offset[5] = 0x1c; + __wmt_step_test_do_emi_action(act_id, param_num, params, 0, &temp_report, + "STEP test case failed: (Do EMI action TC-3) begin larger than end"); + + /**************************************** + ************ Test case 4 *************** + ******** EMI only support read ********* + ****************************************/ + WMT_INFO_FUNC("STEP test: TC 4\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + params[0] = "1"; + wmt_step_test_get_emi_wmt_offset(buf_begin, 0x08); + params[1] = buf_begin; + wmt_step_test_get_emi_wmt_offset(buf_end, 0x20); + params[2] = buf_end; + param_num = 3; + __wmt_step_test_do_emi_action(act_id, param_num, params, -1, &temp_report, + "STEP test case failed: (Do EMI action TC-4) only support read"); + + /**************************************** + ************ Test case 5 *************** + ********* EMI dump not 32bit *********** + ****************************************/ + WMT_INFO_FUNC("STEP test: TC 5\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + params[0] = "0"; + wmt_step_test_get_emi_wmt_offset(buf_begin, 0x08); + params[1] = buf_begin; + wmt_step_test_get_emi_wmt_offset(buf_end, 0x0e); + params[2] = buf_end; + param_num = 3; + g_step_test_check.step_check_total = 2; + g_step_test_check.step_check_emi_offset[0] = 0x08; + g_step_test_check.step_check_emi_offset[1] = 0x0c; + __wmt_step_test_do_emi_action(act_id, param_num, params, 0, &temp_report, + "STEP test case failed: (Do EMI action TC-5) not 32bit"); + + /***************************************** + ************ Test case 6 **************** + ***** EMI dump over emi max size ******** + *****************************************/ + WMT_INFO_FUNC("STEP test: TC 6\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + params[0] = "0"; + wmt_step_test_get_emi_wmt_offset(buf_begin, (gConEmiSize + 0x08)); + params[1] = buf_begin; + wmt_step_test_get_emi_wmt_offset(buf_end, (gConEmiSize + 0x0e)); + params[2] = buf_end; + param_num = 3; + __wmt_step_test_do_emi_action(act_id, param_num, params, -1, &temp_report, + "STEP test case failed: (Do EMI action TC-6) over emi max size"); + + /***************************************** + ************ Test case 7 **************** + ************* page fault **************** + *****************************************/ + WMT_INFO_FUNC("STEP test: TC 7\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + params[0] = "0"; + wmt_step_test_get_emi_wmt_offset(buf_begin, 0x02); + params[1] = buf_begin; + wmt_step_test_get_emi_wmt_offset(buf_end, 0x08); + params[2] = buf_end; + param_num = 3; + __wmt_step_test_do_emi_action(act_id, param_num, params, -1, &temp_report, + "STEP test case failed: (Do EMI action TC-7) page fault"); + + /***************************************** + ************ Test case 8 **************** + ********** save to temp reg ************* + *****************************************/ + WMT_INFO_FUNC("STEP test: TC 8\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + wmt_step_test_clear_temp_register(); + params[0] = "0"; + wmt_step_test_get_emi_wmt_offset(buf_begin, 0x08); + params[1] = buf_begin; + params[2] = "0x0F0F0F0F"; + params[3] = "$1"; + param_num = 4; + g_step_test_check.step_check_total = 1; + g_step_test_check.step_check_emi_offset[0] = 0x08; + g_step_test_check.step_test_mask = 0x0F0F0F0F; + g_step_test_check.step_check_temp_register_id = 1; + __wmt_step_test_do_emi_action(act_id, param_num, params, 0, &temp_report, + "STEP test case failed: (Do EMI action TC-8) save to temp reg"); + + osal_gettimeofday(&sec_end, &usec_end); + wmt_step_test_show_result_report("STEP result: Do EMI action result", + &temp_report, sec_begin, usec_begin, sec_end, usec_end); + wmt_step_test_update_result_report(p_report, &temp_report); +} + +void wmt_step_test_do_cond_emi_action(struct step_test_report *p_report) +{ + enum step_action_id act_id; + char *params[STEP_PARAMETER_SIZE]; + struct step_test_report temp_report = {0, 0, 0}; + int sec_begin = 0; + int usec_begin = 0; + int sec_end = 0; + int usec_end = 0; + unsigned char buf_begin[11]; + unsigned char buf_end[11]; + int param_num; + + WMT_INFO_FUNC("STEP test: Do condition EMI action start\n"); + osal_gettimeofday(&sec_begin, &usec_begin); + act_id = STEP_ACTION_INDEX_CONDITION_EMI; + /***************************************** + ************ Test case 1 **************** + ********** EMI dump 32 bit ************** + *****************************************/ + WMT_INFO_FUNC("STEP test: TC 1\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + wmt_step_test_clear_temp_register(); + params[0] = "$0"; + params[1] = "0"; + wmt_step_test_get_emi_wmt_offset(buf_begin, 0x44); + params[2] = buf_begin; + wmt_step_test_get_emi_wmt_offset(buf_end, 0x48); + params[3] = buf_end; + param_num = 4; + g_step_env.temp_register[0] = 1; + + g_step_test_check.step_check_total = 1; + g_step_test_check.step_check_emi_offset[0] = 0x44; + __wmt_step_test_do_cond_emi_action(act_id, param_num, params, 0, &temp_report, + "STEP test case failed: (Do COND EMI action TC-1) dump 32bit"); + + /***************************************** + ************ Test case 2 **************** + ****** EMI dump check for address ******* + *****************************************/ + WMT_INFO_FUNC("STEP test: TC 2\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + wmt_step_test_clear_temp_register(); + params[0] = "$1"; + params[1] = "0"; + wmt_step_test_get_emi_wmt_offset(buf_begin, 0x24); + params[2] = buf_begin; + wmt_step_test_get_emi_wmt_offset(buf_end, 0x44); + params[3] = buf_end; + param_num = 4; + g_step_env.temp_register[1] = 1; + + g_step_test_check.step_check_total = 8; + g_step_test_check.step_check_emi_offset[0] = 0x24; + g_step_test_check.step_check_emi_offset[1] = 0x28; + g_step_test_check.step_check_emi_offset[2] = 0x2c; + g_step_test_check.step_check_emi_offset[3] = 0x30; + g_step_test_check.step_check_emi_offset[4] = 0x34; + g_step_test_check.step_check_emi_offset[5] = 0x38; + g_step_test_check.step_check_emi_offset[6] = 0x3c; + g_step_test_check.step_check_emi_offset[7] = 0x40; + __wmt_step_test_do_cond_emi_action(act_id, param_num, params, 0, &temp_report, + "STEP test case failed: (Do COND EMI action TC-2) more address"); + + /***************************************** + ************ Test case 3 **************** + **** EMI dump begin larger than end ***** + *****************************************/ + WMT_INFO_FUNC("STEP test: TC 3\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + wmt_step_test_clear_temp_register(); + params[0] = "$0"; + params[1] = "0"; + wmt_step_test_get_emi_wmt_offset(buf_begin, 0x20); + params[2] = buf_begin; + wmt_step_test_get_emi_wmt_offset(buf_end, 0x08); + params[3] = buf_end; + param_num = 4; + g_step_env.temp_register[0] = 15; + + g_step_test_check.step_check_total = 6; + g_step_test_check.step_check_emi_offset[0] = 0x08; + g_step_test_check.step_check_emi_offset[1] = 0x0c; + g_step_test_check.step_check_emi_offset[2] = 0x10; + g_step_test_check.step_check_emi_offset[3] = 0x14; + g_step_test_check.step_check_emi_offset[4] = 0x18; + g_step_test_check.step_check_emi_offset[5] = 0x1c; + __wmt_step_test_do_cond_emi_action(act_id, param_num, params, 0, &temp_report, + "STEP test case failed: (Do COND EMI action TC-3) begin larger than end"); + + /**************************************** + ************ Test case 4 *************** + ******** EMI only support read ********* + ****************************************/ + WMT_INFO_FUNC("STEP test: TC 4\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + wmt_step_test_clear_temp_register(); + params[0] = "$1"; + params[1] = "1"; + wmt_step_test_get_emi_wmt_offset(buf_begin, 0x08); + params[2] = buf_begin; + wmt_step_test_get_emi_wmt_offset(buf_end, 0x20); + params[3] = buf_end; + param_num = 4; + g_step_env.temp_register[1] = 1; + + __wmt_step_test_do_cond_emi_action(act_id, param_num, params, -1, &temp_report, + "STEP test case failed: (Do COND EMI action TC-4) only support read"); + + /**************************************** + ************ Test case 5 *************** + ********* EMI dump not 32bit *********** + ****************************************/ + WMT_INFO_FUNC("STEP test: TC 5\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + wmt_step_test_clear_temp_register(); + params[0] = "$0"; + params[1] = "0"; + wmt_step_test_get_emi_wmt_offset(buf_begin, 0x08); + params[2] = buf_begin; + wmt_step_test_get_emi_wmt_offset(buf_end, 0x0e); + params[3] = buf_end; + param_num = 4; + g_step_env.temp_register[0] = 1; + + g_step_test_check.step_check_total = 2; + g_step_test_check.step_check_emi_offset[0] = 0x08; + g_step_test_check.step_check_emi_offset[1] = 0x0c; + __wmt_step_test_do_cond_emi_action(act_id, param_num, params, 0, &temp_report, + "STEP test case failed: (Do COND EMI action TC-5) not 32bit"); + + /***************************************** + ************ Test case 6 **************** + ***** EMI dump over emi max size ******** + *****************************************/ + WMT_INFO_FUNC("STEP test: TC 6\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + wmt_step_test_clear_temp_register(); + params[0] = "$9"; + params[1] = "0"; + wmt_step_test_get_emi_wmt_offset(buf_begin, (gConEmiSize + 0x08)); + params[2] = buf_begin; + wmt_step_test_get_emi_wmt_offset(buf_end, (gConEmiSize + 0x0e)); + params[3] = buf_end; + param_num = 4; + g_step_env.temp_register[9] = 1; + + __wmt_step_test_do_cond_emi_action(act_id, param_num, params, -1, &temp_report, + "STEP test case failed: (Do COND EMI action TC-6) over emi max size"); + + /***************************************** + ************ Test case 7 **************** + ************* page fault **************** + *****************************************/ + WMT_INFO_FUNC("STEP test: TC 7\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + wmt_step_test_clear_temp_register(); + params[0] = "$0"; + params[1] = "0"; + wmt_step_test_get_emi_wmt_offset(buf_begin, 0x02); + params[2] = buf_begin; + wmt_step_test_get_emi_wmt_offset(buf_end, 0x08); + params[3] = buf_end; + param_num = 4; + g_step_env.temp_register[0] = 1; + + __wmt_step_test_do_cond_emi_action(act_id, param_num, params, -1, &temp_report, + "STEP test case failed: (Do COND EMI action TC-7) page fault"); + + /***************************************** + ************ Test case 8 **************** + ********** save to temp reg ************* + *****************************************/ + WMT_INFO_FUNC("STEP test: TC 8\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + wmt_step_test_clear_temp_register(); + params[0] = "$0"; + params[1] = "0"; + wmt_step_test_get_emi_wmt_offset(buf_begin, 0x08); + params[2] = buf_begin; + params[3] = "0x0F0F0F0F"; + params[4] = "$1"; + param_num = 5; + g_step_test_check.step_check_total = 1; + g_step_test_check.step_check_emi_offset[0] = 0x08; + g_step_test_check.step_test_mask = 0x0F0F0F0F; + g_step_test_check.step_check_temp_register_id = 1; + g_step_env.temp_register[0] = 1; + __wmt_step_test_do_cond_emi_action(act_id, param_num, params, 0, &temp_report, + "STEP test case failed: (Do EMI action TC-8) save to temp reg"); + + + /***************************************** + ************ Test case 9 **************** + ******** condition invalid ************** + *****************************************/ + WMT_INFO_FUNC("STEP test: TC 9\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + wmt_step_test_clear_temp_register(); + params[0] = "$0"; + params[1] = "0"; + wmt_step_test_get_emi_wmt_offset(buf_begin, 0x08); + params[2] = buf_begin; + wmt_step_test_get_emi_wmt_offset(buf_end, 0x0e); + params[3] = buf_end; + param_num = 4; + g_step_env.temp_register[0] = 0; + + __wmt_step_test_do_cond_emi_action(act_id, param_num, params, -1, &temp_report, + "STEP test case failed: (Do COND EMI action TC-9) condition invalid"); + + osal_gettimeofday(&sec_end, &usec_end); + wmt_step_test_show_result_report("STEP result: Do condition EMI action result", + &temp_report, sec_begin, usec_begin, sec_end, usec_end); + wmt_step_test_update_result_report(p_report, &temp_report); +} + +int wmt_step_test_get_reg_base_phy_addr(unsigned char buf[], unsigned int index) +{ + struct device_node *node = NULL; + struct resource res; + int ret; + + if (g_pdev != NULL) { + node = g_pdev->dev.of_node; + if (node) { + ret = of_address_to_resource(node, index, &res); + if (ret) { + WMT_ERR_FUNC("STEP test failed: of_address_to_resource null"); + return ret; + } + } else { + WMT_ERR_FUNC("STEP test failed: node null"); + return -1; + } + } else { + WMT_ERR_FUNC("STEP test failed: gdev null"); + return -1; + } + snprintf(buf, 11, "0x%08x", ((unsigned int)res.start)); + + return 0; +} + +void wmt_step_test_do_register_action(struct step_test_report *p_report) +{ + enum step_action_id act_id; + char *params[STEP_PARAMETER_SIZE]; + struct step_test_report temp_report = {0, 0, 0}; + int sec_begin = 0; + int usec_begin = 0; + int sec_end = 0; + int usec_end = 0; + unsigned char buf[11]; + int param_num; + int can_write_offset = 0; + unsigned char can_write_offset_char[11]; + + WMT_INFO_FUNC("STEP test: Do register action start\n"); + + can_write_offset = + wmt_step_test_find_can_write_register(conn_reg.mcu_base, 0x200, 0x0000000F); + if (can_write_offset == -1) { + p_report->fail++; + WMT_ERR_FUNC("STEP test: Do register action init can_write_offset failed\n"); + return; + } + if (snprintf(can_write_offset_char, 11, "0x%08x", can_write_offset) < 0) + WMT_INFO_FUNC("[%s::%d] snprintf can_write_offset_char fail\n", __func__, __LINE__); + + osal_gettimeofday(&sec_begin, &usec_begin); + act_id = STEP_ACTION_INDEX_REGISTER; + /**************************************** + ************ Test case 1 *************** + ******** REG read MCU chip id ********** + ****************************************/ + WMT_INFO_FUNC("STEP test: TC 1\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + params[0] = "0"; + params[1] = "#1"; + params[2] = "0x08"; + params[3] = "1"; + params[4] = "0"; + param_num = 5; + g_step_test_check.step_check_register_addr = (conn_reg.mcu_base + 0x08); + __wmt_step_test_do_register_action(act_id, param_num, params, 0, &temp_report, + "STEP test case failed: (Do register action TC-1) MCU chip id"); + + /**************************************** + ************ Test case 2 *************** + *** REG read cpucpr 5 times / 3ms **** + ****************************************/ + WMT_INFO_FUNC("STEP test: TC 2\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + params[0] = "0"; + params[1] = "#1"; + params[2] = "0x160"; + params[3] = "5"; + params[4] = "3"; + param_num = 5; + g_step_test_check.step_check_register_addr = (conn_reg.mcu_base + 0x160); + __wmt_step_test_do_register_action(act_id, param_num, params, 0, &temp_report, + "STEP test case failed: (Do register action TC-2) cpucpr 5 times / 3ms"); + + /********************************************** + *************** Test case 3 ****************** + ** REG read MCU chip id by physical address ** + **********************************************/ + WMT_INFO_FUNC("STEP test: TC 3\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + params[0] = "0"; + if (wmt_step_test_get_reg_base_phy_addr(buf, 0) == 0) { + params[1] = buf; + params[2] = "0x08"; + params[3] = "1"; + params[4] = "0"; + param_num = 5; + g_step_test_check.step_check_register_addr = (conn_reg.mcu_base + 0x08); + __wmt_step_test_do_register_action(act_id, param_num, params, 0, &temp_report, + "STEP test case failed: (Do register action TC-3) MCU chip id by phy"); + } else { + p_report->fail++; + WMT_ERR_FUNC("STEP test case failed: get physical address failed\n"); + } + + /********************************************************* + ********************* Test case 4 *********************** + ** REG read cpucpr 5 times / 3ms by physical address ** + *********************************************************/ + WMT_INFO_FUNC("STEP test: TC 4\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + params[0] = "0"; + if (wmt_step_test_get_reg_base_phy_addr(buf, 0) == 0) { + params[1] = buf; + params[2] = "0x160"; + params[3] = "5"; + params[4] = "3"; + param_num = 5; + g_step_test_check.step_check_register_addr = (conn_reg.mcu_base + 0x160); + __wmt_step_test_do_register_action(act_id, param_num, params, 0, &temp_report, + "STEP test case failed: (Do register action TC-4) cpucpr 5 times / 3ms by phy"); + } else { + p_report->fail++; + WMT_ERR_FUNC("STEP test case failed: get physical address failed\n"); + } + + /***************************************** + ************* Test case 5 *************** + ******** REG read over base size ******** + *****************************************/ + WMT_INFO_FUNC("STEP test: TC 5\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + params[0] = "0"; + params[1] = "#1"; + params[2] = "0x11204"; + params[3] = "1"; + params[4] = "0"; + param_num = 5; + __wmt_step_test_do_register_action(act_id, param_num, params, -1, &temp_report, + "STEP test case failed: (Do register action TC-5) Over size"); + + /****************************************** + ************** Test case 6 *************** + ***** REG read over base size by phy ***** + ******************************************/ + WMT_INFO_FUNC("STEP test: TC 6\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + params[0] = "0"; + if (wmt_step_test_get_reg_base_phy_addr(buf, 0) == 0) { + params[1] = buf; + params[2] = "0x204"; + params[3] = "1"; + params[4] = "0"; + param_num = 5; + g_step_test_check.step_check_register_addr = (conn_reg.mcu_base + 0x204); + __wmt_step_test_do_register_action(act_id, param_num, params, 0, &temp_report, + "STEP test case failed: (Do register action TC-6) Over size by phy"); + } else { + p_report->fail++; + WMT_ERR_FUNC("STEP test case failed: get physical address failed\n"); + } + + /****************************************** + ************** Test case 7 *************** + *************** REG write **************** + ******************************************/ + WMT_INFO_FUNC("STEP test: TC 7\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + params[0] = "1"; + params[1] = "#1"; + params[2] = can_write_offset_char; + params[3] = "0x2"; + param_num = 4; + g_step_test_check.step_check_register_addr = (conn_reg.mcu_base + can_write_offset); + g_step_test_check.step_check_write_value = 0x2; + __wmt_step_test_do_register_action(act_id, param_num, params, 0, &temp_report, + "STEP test case failed: (Do register action TC-7) REG write"); + + /****************************************** + ************** Test case 8 *************** + *********** REG write by phy ************* + ******************************************/ + WMT_INFO_FUNC("STEP test: TC 8\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + params[0] = "1"; + if (wmt_step_test_get_reg_base_phy_addr(buf, 0) == 0) { + params[1] = buf; + params[2] = can_write_offset_char; + params[3] = "0x7"; + param_num = 4; + g_step_test_check.step_check_register_addr = (conn_reg.mcu_base + can_write_offset); + g_step_test_check.step_check_write_value = 0x7; + __wmt_step_test_do_register_action(act_id, param_num, params, 0, &temp_report, + "STEP test case failed: (Do register action TC-8) REG write by phy"); + } else { + p_report->fail++; + WMT_ERR_FUNC("STEP test case failed: get physical address failed\n"); + } + + /****************************************** + ************** Test case 9 *************** + ************* REG write bit ************** + ******************************************/ + WMT_INFO_FUNC("STEP test: TC 9\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + params[0] = "1"; + params[1] = "#1"; + params[2] = can_write_offset_char; + params[3] = "0x321"; + params[4] = "0x00F"; + param_num = 5; + g_step_test_check.step_check_register_addr = (conn_reg.mcu_base + can_write_offset); + g_step_test_check.step_check_write_value = 0x001; + g_step_test_check.step_test_mask = 0x00F; + __wmt_step_test_do_register_action(act_id, param_num, params, 0, &temp_report, + "STEP test case failed: (Do register action TC-9) REG write bit"); + + /****************************************** + ************** Test case 10 ************** + ********* REG write bit by phy *********** + ******************************************/ + WMT_INFO_FUNC("STEP test: TC 10\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + params[0] = "1"; + if (wmt_step_test_get_reg_base_phy_addr(buf, 0) == 0) { + params[1] = buf; + params[2] = can_write_offset_char; + params[3] = "0x32f"; + params[4] = "0x002"; + param_num = 5; + g_step_test_check.step_check_register_addr = (conn_reg.mcu_base + can_write_offset); + g_step_test_check.step_check_write_value = 0x002; + g_step_test_check.step_test_mask = 0x002; + __wmt_step_test_do_register_action(act_id, param_num, params, 0, &temp_report, + "STEP test case failed: (Do register action TC-10) REG write bit by phy"); + } else { + p_report->fail++; + WMT_ERR_FUNC("STEP test case failed: get physical address failed\n"); + } + + /****************************************** + ************** Test case 11 ************** + ********* REG read to temp reg *********** + ******************************************/ + WMT_INFO_FUNC("STEP test: TC 11\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + wmt_step_test_clear_temp_register(); + params[0] = "0"; + params[1] = "#1"; + params[2] = "0x08"; + params[3] = "0x0F0F0F0F"; + params[4] = "$2"; + param_num = 5; + g_step_test_check.step_check_register_addr = (conn_reg.mcu_base + 0x08); + g_step_test_check.step_test_mask = 0x0F0F0F0F; + g_step_test_check.step_check_temp_register_id = 2; + __wmt_step_test_do_register_action(act_id, param_num, params, 0, &temp_report, + "STEP test case failed: (Do register action TC-11) REG read to temp reg"); + + /****************************************** + ************** Test case 12 ************** + ******* REG read phy to temp reg ********* + ******************************************/ + WMT_INFO_FUNC("STEP test: TC 12\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + wmt_step_test_clear_temp_register(); + params[0] = "0"; + if (wmt_step_test_get_reg_base_phy_addr(buf, 0) == 0) { + params[1] = buf; + params[2] = "0x08"; + params[3] = "0x0F0F0F0F"; + params[4] = "$3"; + param_num = 5; + g_step_test_check.step_check_register_addr = (conn_reg.mcu_base + 0x08); + g_step_test_check.step_test_mask = 0x0F0F0F0F; + g_step_test_check.step_check_temp_register_id = 3; + __wmt_step_test_do_register_action(act_id, param_num, params, 0, &temp_report, + "STEP test case failed: (Do register action TC-12) REG read phy to temp reg"); + } else { + p_report->fail++; + WMT_ERR_FUNC("STEP test case failed: get physical address failed\n"); + } + + osal_gettimeofday(&sec_end, &usec_end); + wmt_step_test_show_result_report("STEP result: Do register action result", + &temp_report, sec_begin, usec_begin, sec_end, usec_end); + wmt_step_test_update_result_report(p_report, &temp_report); +} + +void wmt_step_test_do_cond_register_action(struct step_test_report *p_report) +{ + enum step_action_id act_id; + char *params[STEP_PARAMETER_SIZE]; + struct step_test_report temp_report = {0, 0, 0}; + int sec_begin = 0; + int usec_begin = 0; + int sec_end = 0; + int usec_end = 0; + unsigned char buf[11]; + int param_num; + int can_write_offset = 0; + unsigned char can_write_offset_char[11]; + + WMT_INFO_FUNC("STEP test: Do condition register action start\n"); + + can_write_offset = + wmt_step_test_find_can_write_register(conn_reg.mcu_base, 0x200, 0x0000000F); + if (can_write_offset == -1) { + p_report->fail++; + WMT_ERR_FUNC("STEP test: Do register action init can_write_offset failed\n"); + return; + } + if (snprintf(can_write_offset_char, 11, "0x%08x", can_write_offset) < 0) + WMT_INFO_FUNC("[%s::%d] snprintf can_write_offset_char fail\n", __func__, __LINE__); + + osal_gettimeofday(&sec_begin, &usec_begin); + act_id = STEP_ACTION_INDEX_CONDITION_REGISTER; + /**************************************** + ************ Test case 1 *************** + ******** REG read MCU chip id ********** + ****************************************/ + WMT_INFO_FUNC("STEP test: TC 1\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + wmt_step_test_clear_temp_register(); + params[0] = "$0"; + params[1] = "0"; + params[2] = "#1"; + params[3] = "0x08"; + params[4] = "1"; + params[5] = "0"; + param_num = 6; + g_step_env.temp_register[0] = 1; + + g_step_test_check.step_check_register_addr = (conn_reg.mcu_base + 0x08); + __wmt_step_test_do_cond_register_action(act_id, param_num, params, 0, &temp_report, + "STEP test case failed: (Do cond register action TC-1) MCU chip id"); + + /**************************************** + ************ Test case 2 *************** + *** REG read cpucpr 5 times / 3ms **** + ****************************************/ + WMT_INFO_FUNC("STEP test: TC 2\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + wmt_step_test_clear_temp_register(); + params[0] = "$1"; + params[1] = "0"; + params[2] = "#1"; + params[3] = "0x160"; + params[4] = "5"; + params[5] = "3"; + param_num = 6; + g_step_env.temp_register[1] = 1; + + g_step_test_check.step_check_register_addr = (conn_reg.mcu_base + 0x160); + __wmt_step_test_do_cond_register_action(act_id, param_num, params, 0, &temp_report, + "STEP test case failed: (Do cond register action TC-2) cpucpr 5 times / 3ms"); + + /********************************************** + *************** Test case 3 ****************** + ** REG read MCU chip id by physical address ** + **********************************************/ + WMT_INFO_FUNC("STEP test: TC 3\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + wmt_step_test_clear_temp_register(); + params[0] = "$2"; + params[1] = "0"; + if (wmt_step_test_get_reg_base_phy_addr(buf, 0) == 0) { + params[2] = buf; + params[3] = "0x08"; + params[4] = "1"; + params[5] = "0"; + param_num = 6; + g_step_env.temp_register[2] = 1; + + g_step_test_check.step_check_register_addr = (conn_reg.mcu_base + 0x08); + __wmt_step_test_do_cond_register_action(act_id, param_num, params, 0, &temp_report, + "STEP test case failed: (Do cond register action TC-3) MCU chip id by phy"); + } else { + p_report->fail++; + WMT_ERR_FUNC("STEP test case failed: get physical address failed\n"); + } + + /********************************************************* + ********************* Test case 4 *********************** + ** REG read cpucpr 5 times / 3ms by physical address ** + *********************************************************/ + WMT_INFO_FUNC("STEP test: TC 4\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + wmt_step_test_clear_temp_register(); + params[0] = "$3"; + params[1] = "0"; + if (wmt_step_test_get_reg_base_phy_addr(buf, 0) == 0) { + params[2] = buf; + params[3] = "0x160"; + params[4] = "5"; + params[5] = "3"; + param_num = 6; + g_step_env.temp_register[3] = 11; + + g_step_test_check.step_check_register_addr = (conn_reg.mcu_base + 0x160); + __wmt_step_test_do_cond_register_action(act_id, param_num, params, 0, &temp_report, + "STEP test case failed: (Do cond register action TC-4) cpucpr 5 times / 3ms by phy"); + } else { + p_report->fail++; + WMT_ERR_FUNC("STEP test case failed: get physical address failed\n"); + } + + /***************************************** + ************* Test case 5 *************** + ******** REG read over base size ******** + *****************************************/ + WMT_INFO_FUNC("STEP test: TC 5\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + wmt_step_test_clear_temp_register(); + params[0] = "$4"; + params[1] = "0"; + params[2] = "#1"; + params[3] = "0x11204"; + params[4] = "1"; + params[5] = "0"; + param_num = 6; + g_step_env.temp_register[4] = 10; + + __wmt_step_test_do_cond_register_action(act_id, param_num, params, -1, &temp_report, + "STEP test case failed: (Do cond register action TC-5) Over size"); + + /****************************************** + ************** Test case 6 *************** + ***** REG read over base size by phy ***** + ******************************************/ + WMT_INFO_FUNC("STEP test: TC 6\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + wmt_step_test_clear_temp_register(); + params[0] = "$5"; + params[1] = "0"; + if (wmt_step_test_get_reg_base_phy_addr(buf, 0) == 0) { + params[2] = buf; + params[3] = "0x204"; + params[4] = "1"; + params[5] = "0"; + param_num = 6; + g_step_env.temp_register[5] = 1; + + g_step_test_check.step_check_register_addr = (conn_reg.mcu_base + 0x204); + __wmt_step_test_do_cond_register_action(act_id, param_num, params, 0, &temp_report, + "STEP test case failed: (Do cond register action TC-6) Over size by phy"); + } else { + p_report->fail++; + WMT_ERR_FUNC("STEP test case failed: get physical address failed\n"); + } + + /****************************************** + ************** Test case 7 *************** + *************** REG write **************** + ******************************************/ + WMT_INFO_FUNC("STEP test: TC 7\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + wmt_step_test_clear_temp_register(); + params[0] = "$6"; + params[1] = "1"; + params[2] = "#1"; + params[3] = can_write_offset_char; + params[4] = "0x2"; + param_num = 5; + g_step_env.temp_register[6] = 1; + + g_step_test_check.step_check_register_addr = (conn_reg.mcu_base + can_write_offset); + g_step_test_check.step_check_write_value = 0x2; + __wmt_step_test_do_cond_register_action(act_id, param_num, params, 0, &temp_report, + "STEP test case failed: (Do cond register action TC-7) REG write"); + + /****************************************** + ************** Test case 8 *************** + *********** REG write by phy ************* + ******************************************/ + WMT_INFO_FUNC("STEP test: TC 8\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + wmt_step_test_clear_temp_register(); + params[0] = "$7"; + params[1] = "1"; + if (wmt_step_test_get_reg_base_phy_addr(buf, 0) == 0) { + params[2] = buf; + params[3] = can_write_offset_char; + params[4] = "0x7"; + param_num = 5; + g_step_env.temp_register[7] = 1; + + g_step_test_check.step_check_register_addr = (conn_reg.mcu_base + can_write_offset); + g_step_test_check.step_check_write_value = 0x7; + __wmt_step_test_do_cond_register_action(act_id, param_num, params, 0, &temp_report, + "STEP test case failed: (Do cond register action TC-8) REG write by phy"); + } else { + p_report->fail++; + WMT_ERR_FUNC("STEP test case failed: get physical address failed\n"); + } + + /****************************************** + ************** Test case 9 *************** + ************* REG write bit ************** + ******************************************/ + WMT_INFO_FUNC("STEP test: TC 9\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + wmt_step_test_clear_temp_register(); + params[0] = "$8"; + params[1] = "1"; + params[2] = "#1"; + params[3] = can_write_offset_char; + params[4] = "0x321"; + params[5] = "0x00F"; + param_num = 6; + g_step_env.temp_register[8] = 1; + + g_step_test_check.step_check_register_addr = (conn_reg.mcu_base + can_write_offset); + g_step_test_check.step_check_write_value = 0x001; + g_step_test_check.step_test_mask = 0x00F; + __wmt_step_test_do_cond_register_action(act_id, param_num, params, 0, &temp_report, + "STEP test case failed: (Do cond register action TC-9) REG write bit"); + + /****************************************** + ************** Test case 10 ************** + ********* REG write bit by phy *********** + ******************************************/ + WMT_INFO_FUNC("STEP test: TC 10\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + wmt_step_test_clear_temp_register(); + params[0] = "$9"; + params[1] = "1"; + if (wmt_step_test_get_reg_base_phy_addr(buf, 0) == 0) { + params[2] = buf; + params[3] = can_write_offset_char; + params[4] = "0x32f"; + params[5] = "0x002"; + param_num = 6; + g_step_env.temp_register[9] = 1; + + g_step_test_check.step_check_register_addr = (conn_reg.mcu_base + can_write_offset); + g_step_test_check.step_check_write_value = 0x002; + g_step_test_check.step_test_mask = 0x002; + __wmt_step_test_do_cond_register_action(act_id, param_num, params, 0, &temp_report, + "STEP test case failed: (Do cond register action TC-10) REG write bit by phy"); + } else { + p_report->fail++; + WMT_ERR_FUNC("STEP test case failed: get physical address failed\n"); + } + + /****************************************** + ************** Test case 11 ************** + ********* REG read to temp reg *********** + ******************************************/ + WMT_INFO_FUNC("STEP test: TC 11\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + wmt_step_test_clear_temp_register(); + params[0] = "$8"; + params[1] = "0"; + params[2] = "#1"; + params[3] = "0x08"; + params[4] = "0x0F0F0F0F"; + params[5] = "$2"; + param_num = 6; + g_step_test_check.step_check_register_addr = (conn_reg.mcu_base + 0x08); + g_step_test_check.step_test_mask = 0x0F0F0F0F; + g_step_test_check.step_check_temp_register_id = 2; + g_step_env.temp_register[8] = 1; + __wmt_step_test_do_register_action(act_id, param_num, params, 0, &temp_report, + "STEP test case failed: (Do register action TC-11) REG read to temp reg"); + + /****************************************** + ************** Test case 12 ************** + ******* REG read phy to temp reg ********* + ******************************************/ + WMT_INFO_FUNC("STEP test: TC 12\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + wmt_step_test_clear_temp_register(); + params[0] = "$8"; + params[1] = "0"; + if (wmt_step_test_get_reg_base_phy_addr(buf, 0) == 0) { + params[2] = buf; + params[3] = "0x08"; + params[4] = "0x0F0F0F0F"; + params[5] = "$3"; + param_num = 6; + g_step_test_check.step_check_register_addr = (conn_reg.mcu_base + 0x08); + g_step_test_check.step_test_mask = 0x0F0F0F0F; + g_step_test_check.step_check_temp_register_id = 3; + g_step_env.temp_register[8] = 1; + __wmt_step_test_do_register_action(act_id, param_num, params, 0, &temp_report, + "STEP test case failed: (Do register action TC-12) REG read phy to temp reg"); + } else { + p_report->fail++; + WMT_ERR_FUNC("STEP test case failed: get physical address failed\n"); + } + + /****************************************** + ************** Test case 13 ************** + ************* condition invalid ********** + ******************************************/ + WMT_INFO_FUNC("STEP test: TC 13\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + wmt_step_test_clear_temp_register(); + params[0] = "$8"; + params[1] = "1"; + params[2] = "#1"; + params[3] = "0x160"; + params[4] = "0x123"; + params[5] = "0xF00"; + param_num = 6; + g_step_env.temp_register[8] = 0; + + __wmt_step_test_do_cond_register_action(act_id, param_num, params, -1, &temp_report, + "STEP test case failed: (Do cond register action TC-13) condition invalid"); + + /****************************************** + ************** Test case 14 ************** + ********** condition invalid write ******* + ******************************************/ + WMT_INFO_FUNC("STEP test: TC 14\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + wmt_step_test_clear_temp_register(); + params[0] = "$6"; + params[1] = "1"; + params[2] = "#1"; + params[3] = "0x110"; + params[4] = "0x200"; + param_num = 5; + g_step_env.temp_register[6] = 0; + + __wmt_step_test_do_cond_register_action(act_id, param_num, params, -1, &temp_report, + "STEP test case failed: (Do cond register action TC-14) condition invalid write"); + + /****************************************** + ************** Test case 15 ************** + ********** condition invalid read ******* + ******************************************/ + WMT_INFO_FUNC("STEP test: TC 15\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + wmt_step_test_clear_temp_register(); + params[0] = "$0"; + params[1] = "0"; + params[2] = "#1"; + params[3] = "0x08"; + params[4] = "1"; + params[5] = "0"; + param_num = 6; + g_step_env.temp_register[0] = 0; + + __wmt_step_test_do_cond_register_action(act_id, param_num, params, -1, &temp_report, + "STEP test case failed: (Do cond register action TC-15) REG write"); + + + osal_gettimeofday(&sec_end, &usec_end); + wmt_step_test_show_result_report("STEP result: Do condition register action result", + &temp_report, sec_begin, usec_begin, sec_end, usec_end); + wmt_step_test_update_result_report(p_report, &temp_report); +} + + +void wmt_step_test_do_gpio_action(struct step_test_report *p_report) +{ + enum step_action_id act_id; + char *params[STEP_PARAMETER_SIZE]; + struct step_action *p_act = NULL; + struct step_test_report temp_report = {0, 0, 0}; + int sec_begin = 0; + int usec_begin = 0; + int sec_end = 0; + int usec_end = 0; + int param_num; + + WMT_INFO_FUNC("STEP test: Do GPIO action start\n"); + osal_gettimeofday(&sec_begin, &usec_begin); + act_id = STEP_ACTION_INDEX_GPIO; + /**************************************** + ************* Test case 1 ************** + ************* GPIO read #8 ************* + ****************************************/ + WMT_INFO_FUNC("STEP test: TC 1\n"); + wmt_step_test_clear_parameter(params); + params[0] = "0"; + params[1] = "8"; + param_num = 2; + + p_act = wmt_step_create_action(act_id, param_num, params); + if (p_act != NULL) { + if (wmt_step_do_gpio_action(p_act, NULL) == 0) { + WMT_INFO_FUNC("STEP check: Do gpio action TC-1(Read #8): search(8: )"); + temp_report.check++; + } else { + WMT_ERR_FUNC("STEP test case failed: (Do gpio action TC-1) Read #8\n"); + temp_report.fail++; + } + wmt_step_remove_action(p_act); + } else { + temp_report.fail++; + WMT_ERR_FUNC("STEP test case failed: (Do gpio action TC-1) Create failed\n"); + } + + osal_gettimeofday(&sec_end, &usec_end); + wmt_step_test_show_result_report("STEP result: Do GPIO action result", + &temp_report, sec_begin, usec_begin, sec_end, usec_end); + wmt_step_test_update_result_report(p_report, &temp_report); +} + +void wmt_step_test_do_chip_reset_action(struct step_test_report *p_report) +{ + enum step_action_id act_id; + char *params[STEP_PARAMETER_SIZE]; + struct step_action *p_act = NULL; + struct step_test_report temp_report = {0, 0, 0}; + int sec_begin = 0; + int usec_begin = 0; + int sec_end = 0; + int usec_end = 0; + int param_num; + + WMT_INFO_FUNC("STEP test: Do chip reset action start\n"); + osal_gettimeofday(&sec_begin, &usec_begin); + act_id = STEP_ACTION_INDEX_CHIP_RESET; + /**************************************** + ************* Test case 1 ************** + ************* chip reset *************** + ****************************************/ + WMT_INFO_FUNC("STEP test: TC 1\n"); + param_num = 0; + + p_act = wmt_step_create_action(act_id, param_num, params); + if (p_act != NULL) { + if (wmt_step_do_chip_reset_action(p_act, NULL) == 0) { + WMT_INFO_FUNC("STEP check: Do chip reset TC-1(chip reset): Trigger AEE"); + temp_report.check++; + } else { + WMT_ERR_FUNC("STEP test case failed: (Do chip reset action TC-1) chip reset\n"); + temp_report.fail++; + } + wmt_step_remove_action(p_act); + } else { + temp_report.fail++; + WMT_ERR_FUNC("STEP test case failed: (Do chip reset action TC-1) Create failed\n"); + } + + osal_gettimeofday(&sec_end, &usec_end); + wmt_step_test_show_result_report("STEP result: Do chip reset action result", + &temp_report, sec_begin, usec_begin, sec_end, usec_end); + wmt_step_test_update_result_report(p_report, &temp_report); +} + +void wmt_step_test_do_wakeup_action(struct step_test_report *p_report) +{ + enum step_action_id act_id; + char *params[STEP_PARAMETER_SIZE]; + struct step_action *p_act = NULL; + struct step_test_report temp_report = {0, 0, 0}; + int sec_begin = 0; + int usec_begin = 0; + int sec_end = 0; + int usec_end = 0; + int param_num; + + WMT_INFO_FUNC("STEP test: Do wakeup action start\n"); + osal_gettimeofday(&sec_begin, &usec_begin); + /**************************************** + ************* Test case 1 ************** + ***** Wakeup then read/write reg ******* + ****************************************/ + WMT_INFO_FUNC("STEP test: TC 1\n"); + act_id = STEP_ACTION_INDEX_KEEP_WAKEUP; + param_num = 0; + + p_act = wmt_step_create_action(act_id, param_num, params); + if (p_act != NULL) { + wmt_step_do_keep_wakeup_action(p_act, NULL); + wmt_step_test_do_register_action(&temp_report); + wmt_step_remove_action(p_act); + } else { + temp_report.fail++; + WMT_ERR_FUNC("STEP test case failed: (Do wakeup) Create failed\n"); + } + + act_id = STEP_ACTION_INDEX_CANCEL_WAKEUP; + param_num = 0; + + p_act = wmt_step_create_action(act_id, param_num, params); + if (p_act != NULL) { + wmt_step_do_cancel_wakeup_action(p_act, NULL); + wmt_step_remove_action(p_act); + } else { + temp_report.fail++; + WMT_ERR_FUNC("STEP test case failed: (Do cancel wakeup) Create failed\n"); + } + + osal_gettimeofday(&sec_end, &usec_end); + wmt_step_test_show_result_report("STEP result: Do wakeup action result", + &temp_report, sec_begin, usec_begin, sec_end, usec_end); + wmt_step_test_update_result_report(p_report, &temp_report); +} + +void wmt_step_test_do_show_action(struct step_test_report *p_report) +{ + enum step_action_id act_id; + char *params[STEP_PARAMETER_SIZE]; + struct step_action *p_act = NULL; + struct step_test_report temp_report = {0, 0, 0}; + int sec_begin = 0; + int usec_begin = 0; + int sec_end = 0; + int usec_end = 0; + int param_num; + + WMT_INFO_FUNC("STEP test: Do show action start\n"); + osal_gettimeofday(&sec_begin, &usec_begin); + act_id = STEP_ACTION_INDEX_SHOW_STRING; + /**************************************** + ************* Test case 1 ************** + ********** Show Hello world ************ + ****************************************/ + WMT_INFO_FUNC("STEP test: TC 1\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_parameter(params); + params[0] = "Hello_World"; + param_num = 1; + + g_step_test_check.step_check_result_string = "Hello_World"; + p_act = wmt_step_create_action(act_id, param_num, params); + if (p_act != NULL) { + wmt_step_do_show_string_action(p_act, wmt_step_test_check_show_act); + if (g_step_test_check.step_check_result == TEST_PASS) { + temp_report.pass++; + } else { + WMT_ERR_FUNC("STEP test case failed: Do show TC-1(Show Hello world)\n"); + temp_report.fail++; + } + wmt_step_remove_action(p_act); + } else { + temp_report.fail++; + WMT_ERR_FUNC("STEP test case failed: Do show TC-1(Show Hello world) Create failed\n"); + } + + osal_gettimeofday(&sec_end, &usec_end); + wmt_step_test_show_result_report("STEP result: Do show action result", + &temp_report, sec_begin, usec_begin, sec_end, usec_end); + wmt_step_test_update_result_report(p_report, &temp_report); +} + +void wmt_step_test_do_sleep_action(struct step_test_report *p_report) +{ + enum step_action_id act_id; + char *params[STEP_PARAMETER_SIZE]; + struct step_action *p_act = NULL; + struct step_test_report temp_report = {0, 0, 0}; + int sec_begin = 0; + int usec_begin = 0; + int sec_end = 0; + int usec_end = 0; + int check_sec_b, check_sec_e; + int check_usec_b, check_usec_e; + int param_num; + + WMT_INFO_FUNC("STEP test: Do sleep action start\n"); + osal_gettimeofday(&sec_begin, &usec_begin); + act_id = STEP_ACTION_INDEX_SLEEP; + /**************************************** + ************* Test case 1 ************** + *************** Sleep 1s *************** + ****************************************/ + WMT_INFO_FUNC("STEP test: TC 1\n"); + wmt_step_test_clear_parameter(params); + params[0] = "1000"; + param_num = 1; + + p_act = wmt_step_create_action(act_id, param_num, params); + if (p_act != NULL) { + osal_gettimeofday(&check_sec_b, &check_usec_b); + wmt_step_do_sleep_action(p_act, NULL); + osal_gettimeofday(&check_sec_e, &check_usec_e); + if (check_sec_e > check_sec_b) { + temp_report.pass++; + } else { + WMT_ERR_FUNC("STEP test case failed: Do show TC-1(Sleep 1s), begin(%d.%d) end(%d.%d)\n", + check_sec_b, check_usec_b, check_sec_e, check_usec_e); + temp_report.fail++; + } + wmt_step_remove_action(p_act); + } else { + temp_report.fail++; + WMT_ERR_FUNC("STEP test case failed: Do show TC-1(Sleep 1s) Create failed\n"); + } + + osal_gettimeofday(&sec_end, &usec_end); + wmt_step_test_show_result_report("STEP result: Do sleep action result", + &temp_report, sec_begin, usec_begin, sec_end, usec_end); + wmt_step_test_update_result_report(p_report, &temp_report); +} + +void wmt_step_test_do_condition_action(struct step_test_report *p_report) +{ + enum step_action_id act_id; + char *params[STEP_PARAMETER_SIZE]; + struct step_action *p_act = NULL; + struct step_test_report temp_report = {0, 0, 0}; + int sec_begin = 0; + int usec_begin = 0; + int sec_end = 0; + int usec_end = 0; + int param_num; + + WMT_INFO_FUNC("STEP test: Do condition action start\n"); + osal_gettimeofday(&sec_begin, &usec_begin); + act_id = STEP_ACTION_INDEX_CONDITION; + /**************************************** + ************* Test case 1 ************** + *********** Condition equal ************ + ****************************************/ + WMT_INFO_FUNC("STEP test: TC 1\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_temp_register(); + wmt_step_test_clear_parameter(params); + params[0] = "$0"; + params[1] = "$1"; + params[2] = "=="; + params[3] = "$2"; + param_num = 4; + + g_step_test_check.step_check_result_value = 1; + p_act = wmt_step_create_action(act_id, param_num, params); + if (p_act != NULL) { + wmt_step_do_condition_action(p_act, wmt_step_test_check_condition_act); + if (g_step_test_check.step_check_result == TEST_PASS) { + temp_report.pass++; + } else { + WMT_ERR_FUNC("STEP test case failed: Do condition TC-1(equal)\n"); + temp_report.fail++; + } + wmt_step_remove_action(p_act); + } else { + temp_report.fail++; + WMT_ERR_FUNC("STEP test case failed: Do condition TC-1(equal) Create failed\n"); + } + + /**************************************** + ************* Test case 2 ************** + ********** Condition greater *********** + ****************************************/ + WMT_INFO_FUNC("STEP test: TC 2\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_temp_register(); + wmt_step_test_clear_parameter(params); + params[0] = "$0"; + params[1] = "$1"; + params[2] = ">"; + params[3] = "$2"; + param_num = 4; + g_step_env.temp_register[1] = 0; + g_step_env.temp_register[2] = 1; + + g_step_test_check.step_check_result_value = 0; + p_act = wmt_step_create_action(act_id, param_num, params); + if (p_act != NULL) { + wmt_step_do_condition_action(p_act, wmt_step_test_check_condition_act); + if (g_step_test_check.step_check_result == TEST_PASS) { + temp_report.pass++; + } else { + WMT_ERR_FUNC("STEP test case failed: Do condition TC-2(greater)\n"); + temp_report.fail++; + } + wmt_step_remove_action(p_act); + } else { + temp_report.fail++; + WMT_ERR_FUNC("STEP test case failed: Do condition TC-2(greater) Create failed\n"); + } + + /**************************************** + ************* Test case 3 ************** + ******* Condition greater equal ******** + ****************************************/ + WMT_INFO_FUNC("STEP test: TC 3\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_temp_register(); + wmt_step_test_clear_parameter(params); + params[0] = "$0"; + params[1] = "$1"; + params[2] = ">="; + params[3] = "$2"; + param_num = 4; + g_step_env.temp_register[1] = 2; + g_step_env.temp_register[2] = 2; + + g_step_test_check.step_check_result_value = 1; + p_act = wmt_step_create_action(act_id, param_num, params); + if (p_act != NULL) { + wmt_step_do_condition_action(p_act, wmt_step_test_check_condition_act); + if (g_step_test_check.step_check_result == TEST_PASS) { + temp_report.pass++; + } else { + WMT_ERR_FUNC("STEP test case failed: Do condition TC-3(greater equal)\n"); + temp_report.fail++; + } + wmt_step_remove_action(p_act); + } else { + temp_report.fail++; + WMT_ERR_FUNC("STEP test case failed: Do condition TC-3(greater equal) Create failed\n"); + } + + /**************************************** + ************* Test case 4 ************** + ************ Condition less ************ + ****************************************/ + WMT_INFO_FUNC("STEP test: TC 4\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_temp_register(); + wmt_step_test_clear_parameter(params); + params[0] = "$0"; + params[1] = "$1"; + params[2] = "<"; + params[3] = "$2"; + param_num = 4; + g_step_env.temp_register[1] = 10; + g_step_env.temp_register[2] = 0; + + g_step_test_check.step_check_result_value = 0; + p_act = wmt_step_create_action(act_id, param_num, params); + if (p_act != NULL) { + wmt_step_do_condition_action(p_act, wmt_step_test_check_condition_act); + if (g_step_test_check.step_check_result == TEST_PASS) { + temp_report.pass++; + } else { + WMT_ERR_FUNC("STEP test case failed: Do condition TC-4(less)\n"); + temp_report.fail++; + } + wmt_step_remove_action(p_act); + } else { + temp_report.fail++; + WMT_ERR_FUNC("STEP test case failed: Do condition TC-4(less) Create failed\n"); + } + + /**************************************** + ************* Test case 5 ************** + ********* Condition less equal ********* + ****************************************/ + WMT_INFO_FUNC("STEP test: TC 5\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_temp_register(); + wmt_step_test_clear_parameter(params); + params[0] = "$0"; + params[1] = "$1"; + params[2] = "<="; + params[3] = "$2"; + param_num = 4; + g_step_env.temp_register[1] = 0; + g_step_env.temp_register[2] = 10; + + g_step_test_check.step_check_result_value = 1; + p_act = wmt_step_create_action(act_id, param_num, params); + if (p_act != NULL) { + wmt_step_do_condition_action(p_act, wmt_step_test_check_condition_act); + if (g_step_test_check.step_check_result == TEST_PASS) { + temp_report.pass++; + } else { + WMT_ERR_FUNC("STEP test case failed: Do condition TC-5(less equal)\n"); + temp_report.fail++; + } + wmt_step_remove_action(p_act); + } else { + temp_report.fail++; + WMT_ERR_FUNC("STEP test case failed: Do condition TC-5(less equal) Create failed\n"); + } + + /**************************************** + ************* Test case 6 ************** + ********* Condition not equal ********** + ****************************************/ + WMT_INFO_FUNC("STEP test: TC 6\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_temp_register(); + wmt_step_test_clear_parameter(params); + params[0] = "$1"; + params[1] = "$2"; + params[2] = "!="; + params[3] = "$3"; + param_num = 4; + g_step_env.temp_register[2] = 3; + g_step_env.temp_register[3] = 3; + + g_step_test_check.step_check_result_value = 0; + p_act = wmt_step_create_action(act_id, param_num, params); + if (p_act != NULL) { + wmt_step_do_condition_action(p_act, wmt_step_test_check_condition_act); + if (g_step_test_check.step_check_result == TEST_PASS) { + temp_report.pass++; + } else { + WMT_ERR_FUNC("STEP test case failed: Do condition TC-6(not equal)\n"); + temp_report.fail++; + } + wmt_step_remove_action(p_act); + } else { + temp_report.fail++; + WMT_ERR_FUNC("STEP test case failed: Do condition TC-6(not equal) Create failed\n"); + } + + /**************************************** + ************* Test case 7 ************** + ************ Condition and ************* + ****************************************/ + WMT_INFO_FUNC("STEP test: TC 7\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_temp_register(); + wmt_step_test_clear_parameter(params); + params[0] = "$1"; + params[1] = "$2"; + params[2] = "&&"; + params[3] = "$3"; + param_num = 4; + g_step_env.temp_register[2] = 0x10; + g_step_env.temp_register[3] = 0x00; + + g_step_test_check.step_check_result_value = 0; + p_act = wmt_step_create_action(act_id, param_num, params); + if (p_act != NULL) { + wmt_step_do_condition_action(p_act, wmt_step_test_check_condition_act); + if (g_step_test_check.step_check_result == TEST_PASS) { + temp_report.pass++; + } else { + WMT_ERR_FUNC("STEP test case failed: Do condition TC-7(and)\n"); + temp_report.fail++; + } + wmt_step_remove_action(p_act); + } else { + temp_report.fail++; + WMT_ERR_FUNC("STEP test case failed: Do condition TC-7(and) Create failed\n"); + } + + /**************************************** + ************* Test case 8 ************** + ************* Condition or ************* + ****************************************/ + WMT_INFO_FUNC("STEP test: TC 8\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_temp_register(); + wmt_step_test_clear_parameter(params); + params[0] = "$1"; + params[1] = "$2"; + params[2] = "||"; + params[3] = "$3"; + param_num = 4; + g_step_env.temp_register[2] = 0x10; + g_step_env.temp_register[3] = 0x00; + + g_step_test_check.step_check_result_value = 1; + p_act = wmt_step_create_action(act_id, param_num, params); + if (p_act != NULL) { + wmt_step_do_condition_action(p_act, wmt_step_test_check_condition_act); + if (g_step_test_check.step_check_result == TEST_PASS) { + temp_report.pass++; + } else { + WMT_ERR_FUNC("STEP test case failed: Do condition TC-8(or)\n"); + temp_report.fail++; + } + wmt_step_remove_action(p_act); + } else { + temp_report.fail++; + WMT_ERR_FUNC("STEP test case failed: Do condition TC-8(or) Create failed\n"); + } + + /**************************************** + ************* Test case 9 ************** + ****** Condition not equal value ******* + ****************************************/ + WMT_INFO_FUNC("STEP test: TC 9\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_temp_register(); + wmt_step_test_clear_parameter(params); + params[0] = "$1"; + params[1] = "$2"; + params[2] = "!="; + params[3] = "99"; + param_num = 4; + g_step_env.temp_register[2] = 99; + + g_step_test_check.step_check_result_value = 0; + p_act = wmt_step_create_action(act_id, param_num, params); + if (p_act != NULL) { + wmt_step_do_condition_action(p_act, wmt_step_test_check_condition_act); + if (g_step_test_check.step_check_result == TEST_PASS) { + temp_report.pass++; + } else { + WMT_ERR_FUNC("STEP test case failed: Do condition TC-9(not equal value)\n"); + temp_report.fail++; + } + wmt_step_remove_action(p_act); + } else { + temp_report.fail++; + WMT_ERR_FUNC("STEP test case failed: Do condition TC-9(not equal value) Create failed\n"); + } + + /**************************************** + ************* Test case 10 ************* + ********* Condition equal value ******** + ****************************************/ + WMT_INFO_FUNC("STEP test: TC 10\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_temp_register(); + wmt_step_test_clear_parameter(params); + params[0] = "$1"; + params[1] = "$2"; + params[2] = "=="; + params[3] = "18"; + param_num = 4; + g_step_env.temp_register[2] = 18; + + g_step_test_check.step_check_result_value = 1; + p_act = wmt_step_create_action(act_id, param_num, params); + if (p_act != NULL) { + wmt_step_do_condition_action(p_act, wmt_step_test_check_condition_act); + if (g_step_test_check.step_check_result == TEST_PASS) { + temp_report.pass++; + } else { + WMT_ERR_FUNC("STEP test case failed: Do condition TC-10(equal value)\n"); + temp_report.fail++; + } + wmt_step_remove_action(p_act); + } else { + temp_report.fail++; + WMT_ERR_FUNC("STEP test case failed: Do condition TC-10(equal value) Create failed\n"); + } + + /**************************************** + ************* Test case 11 ************* + ****** Condition equal value (HEX) ***** + ****************************************/ + WMT_INFO_FUNC("STEP test: TC 10\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_temp_register(); + wmt_step_test_clear_parameter(params); + params[0] = "$1"; + params[1] = "$2"; + params[2] = "=="; + params[3] = "0x18"; + param_num = 4; + g_step_env.temp_register[2] = 24; + + g_step_test_check.step_check_result_value = 1; + p_act = wmt_step_create_action(act_id, param_num, params); + if (p_act != NULL) { + wmt_step_do_condition_action(p_act, wmt_step_test_check_condition_act); + if (g_step_test_check.step_check_result == TEST_PASS) { + temp_report.pass++; + } else { + WMT_ERR_FUNC("STEP test case failed: Do condition TC-11(equal value HEX)\n"); + temp_report.fail++; + } + wmt_step_remove_action(p_act); + } else { + temp_report.fail++; + WMT_ERR_FUNC("STEP test case failed: Do condition TC-11(equal value HEX) Create failed\n"); + } + + osal_gettimeofday(&sec_end, &usec_end); + wmt_step_test_show_result_report("STEP result: Do condition action result", + &temp_report, sec_begin, usec_begin, sec_end, usec_end); + wmt_step_test_update_result_report(p_report, &temp_report); +} + +void wmt_step_test_do_value_action(struct step_test_report *p_report) +{ + enum step_action_id act_id; + char *params[STEP_PARAMETER_SIZE]; + struct step_action *p_act = NULL; + struct step_test_report temp_report = {0, 0, 0}; + int sec_begin = 0; + int usec_begin = 0; + int sec_end = 0; + int usec_end = 0; + int param_num; + + WMT_INFO_FUNC("STEP test: Do value action start\n"); + osal_gettimeofday(&sec_begin, &usec_begin); + act_id = STEP_ACTION_INDEX_VALUE; + /**************************************** + ************* Test case 1 ************** + ******* Save value to register ********* + ****************************************/ + WMT_INFO_FUNC("STEP test: TC 1\n"); + wmt_step_test_clear_check_data(); + wmt_step_test_clear_temp_register(); + wmt_step_test_clear_parameter(params); + params[0] = "$2"; + params[1] = "0x66"; + param_num = 2; + + g_step_test_check.step_check_result_value = 0x66; + p_act = wmt_step_create_action(act_id, param_num, params); + if (p_act != NULL) { + wmt_step_do_value_action(p_act, wmt_step_test_check_value_act); + if (g_step_test_check.step_check_result == TEST_PASS) { + temp_report.pass++; + } else { + WMT_ERR_FUNC("STEP test case failed: Do show TC-1(Save value to register)"); + temp_report.fail++; + } + wmt_step_remove_action(p_act); + } else { + temp_report.fail++; + WMT_ERR_FUNC("STEP test case failed: Do show TC-1(Save value to register) Create failed\n"); + } + + osal_gettimeofday(&sec_end, &usec_end); + wmt_step_test_show_result_report("STEP result: Do value action result", + &temp_report, sec_begin, usec_begin, sec_end, usec_end); + wmt_step_test_update_result_report(p_report, &temp_report); +} + +void wmt_step_test_create_periodic_dump(struct step_test_report *p_report) +{ + int expires_ms; + struct step_test_report temp_report = {0, 0, 0}; + int sec_begin = 0; + int usec_begin = 0; + int sec_end = 0; + int usec_end = 0; + struct step_pd_entry *p_current = NULL; + bool is_thread_run_for_test = 0; + + WMT_INFO_FUNC("STEP test: Create periodic dump start\n"); + osal_gettimeofday(&sec_begin, &usec_begin); + + if (g_step_env.pd_struct.step_pd_wq == NULL) { + if (wmt_step_init_pd_env() != 0) { + WMT_ERR_FUNC("STEP test case failed: Start thread failed\n"); + return; + } + is_thread_run_for_test = 1; + } + + /**************************************** + ************* Test case 1 ************** + *************** Normal ***************** + ****************************************/ + WMT_INFO_FUNC("STEP test: TC 1\n"); + expires_ms = 5; + p_current = wmt_step_get_periodic_dump_entry(expires_ms); + if (p_current == NULL) { + WMT_ERR_FUNC("STEP test case failed: (Create periodic dump TC-1) No entry\n"); + temp_report.fail++; + } else { + if (p_current->expires_ms == expires_ms) { + temp_report.pass++; + } else { + WMT_ERR_FUNC("STEP test case failed: (Create periodic dump TC-1) Currect %d not %d\n", + p_current->expires_ms, expires_ms); + temp_report.fail++; + } + list_del_init(&p_current->list); + kfree(p_current); + } + + if (is_thread_run_for_test == 1) + wmt_step_deinit_pd_env(); + + osal_gettimeofday(&sec_end, &usec_end); + wmt_step_test_show_result_report("STEP result: Create periodic dump result", + &temp_report, sec_begin, usec_begin, sec_end, usec_end); + wmt_step_test_update_result_report(p_report, &temp_report); +} + diff --git a/drivers/misc/mediatek/connectivity/conninfra/Makefile b/drivers/misc/mediatek/connectivity/conninfra/Makefile new file mode 100755 index 0000000000000000000000000000000000000000..4411d2bafd3bb2315d7d364a4fcf5cba743eced4 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/Makefile @@ -0,0 +1,158 @@ +MTK_PLATFORM := $(subst ",,$(CONFIG_MTK_PLATFORM)) +# Force build fail on modpost warning +KBUILD_MODPOST_FAIL_ON_WARNINGS := y +############################################################################### + + +CONNSYS_PLATFORM := $(TARGET_BOARD_PLATFORM_CONNINFRA) + +ifeq ($(CONNSYS_PLATFORM),) +$(info $$CONFIG_MTK_COMBO_CHIP is [${CONFIG_MTK_COMBO_CHIP}]) +ifneq ($(CONFIG_MTK_COMBO_CHIP),) +# replace CONSYS_XXXX to mtXXXX +CONNINFRA_PLATFORM_ID := $(patsubst CONSYS_%,mt%,$(subst ",,$(CONFIG_MTK_COMBO_CHIP))) +$(info CONNINFRA_PLATFORM_ID is [${CONNINFRA_PLATFORM_ID}]) +CONNSYS_PLATFORM := $(CONNINFRA_PLATFORM_ID) +else +CONNSYS_PLATFORM := $(MTK_PLATFORM) +endif +endif +$(info $$CONNSYS_PLATFORM is [${CONNSYS_PLATFORM}]) + +#ccflags-y += -D MTK_WCN_REMOVE_KERNEL_MODULE +ifeq ($(CONFIG_ARM64), y) + ccflags-y += -D CONFIG_MTK_WCN_ARM64 +endif + +# Option for some ALPS specific feature, ex: AEE. +ccflags-y += -D CONNINFRA_PLAT_ALPS=1 + +ccflags-y += -D MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT +ccflags-y += -D MTK_CONNINFRA_CLOCK_BUFFER_API_AVAILABLE=1 + +ccflags-y += -I$(srctree)/drivers/misc/mediatek/include +ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(CONNSYS_PLATFORM)/include +ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(CONNSYS_PLATFORM)/include/mach +ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat +ccflags-y += -I$(srctree)/drivers/misc/mediatek/base/power/$(CONNSYS_PLATFORM) +ccflags-y += -I$(srctree)/drivers/misc/mediatek/base/power/include +ccflags-y += -I$(srctree)/drivers/misc/mediatek/base/power/include/clkbuf_v1 +ccflags-y += -I$(srctree)/drivers/misc/mediatek/base/power/include/clkbuf_v1/$(CONNSYS_PLATFORM) +ccflags-y += -I$(srctree)/drivers/misc/mediatek/eccci +ccflags-y += -I$(srctree)/drivers/misc/mediatek/eccci/$(CONNSYS_PLATFORM) +ccflags-y += -I$(srctree)/drivers/misc/mediatek/eemcs +ccflags-y += -I$(srctree)/drivers/misc/mediatek/mach/$(CONNSYS_PLATFORM)/include/mach +ccflags-y += -I$(srctree)/drivers/misc/mediatek/emi/submodule +ccflags-y += -I$(srctree)/drivers/misc/mediatek/emi/$(CONNSYS_PLATFORM) +ccflags-y += -I$(srctree)/drivers/mmc/core +ccflags-y += -I$(srctree)/drivers/misc/mediatek/connectivity/common +ccflags-y += -I$(srctree)/drivers/misc/mediatek/pmic/include/ +############################################################################### + + +ccflags-y += -Werror +ccflags-y += -Wno-error=format +ccflags-y += -Wno-error=format-extra-args + +############################################################################### +MODULE_NAME := conninfra +ifeq ($(CONFIG_WLAN_DRV_BUILD_IN),y) +$(warning $(MODULE_NAME) build-in boot.img) +obj-y += $(MODULE_NAME).o +else +$(warning $(MODULE_NAME) is kernel module) +obj-m += $(MODULE_NAME).o +endif + +############################################################################### +# common_main +############################################################################### +ccflags-y += -I$(src)/include +ccflags-y += -I$(src)/base/include +ccflags-y += -I$(src)/core/include +ccflags-y += -I$(src)/conf/include +ccflags-y += -I$(src)/drv_init/include +ccflags-y += -I$(src)/platform/include +ccflags-y += -I$(src)/debug_utility +ccflags-y += -I$(src)/debug_utility/include +ccflags-y += -I$(src)/debug_utility/connsyslog +ccflags-y += -I$(src)/debug_utility/connsyslog/platform/include +ccflags-y += -I$(src)/debug_utility/coredump +ccflags-y += -I$(src)/debug_utility/coredump/platform/include + +# By Plaftfrom +ccflags-y += -I$(src)/platform/$(CONNSYS_PLATFORM)/include + +ifneq ($(TARGET_BUILD_VARIANT), user) + ccflags-y += -D CONNINFRA_DBG_SUPPORT=1 +else + ccflags-y += -D CONNINFRA_DBG_SUPPORT=0 +endif + +#ifeq ($(findstring evb, $(MTK_PROJECT)), evb) +#ccflags-y += -D CFG_WMT_EVB +#endif + +#ifneq ($(filter "CONSYS_%",$(CONFIG_MTK_COMBO_CHIP)),) +#$(MODULE_NAME)-objs += common_main/platform/$(CONNSYS_PLATFORM).o +#endif + +$(MODULE_NAME)-objs += base/ring.o +$(MODULE_NAME)-objs += base/osal.o +#$(MODULE_NAME)-objs += base/log.o +$(MODULE_NAME)-objs += base/msg_thread.o +$(MODULE_NAME)-objs += core/conninfra_core.o +$(MODULE_NAME)-objs += src/conninfra_dev.o +$(MODULE_NAME)-objs += src/conninfra.o +$(MODULE_NAME)-objs += conf/conninfra_conf.o +$(MODULE_NAME)-objs += platform/consys_hw.o +$(MODULE_NAME)-objs += platform/clock_mng.o +$(MODULE_NAME)-objs += platform/pmic_mng.o +$(MODULE_NAME)-objs += platform/emi_mng.o +$(MODULE_NAME)-objs += platform/consys_reg_mng.o + +$(MODULE_NAME)-objs += debug_utility/conninfra_dbg.o + +# By Plaftfrom +$(MODULE_NAME)-objs += platform/$(CONNSYS_PLATFORM)/$(CONNSYS_PLATFORM).o +$(MODULE_NAME)-objs += platform/$(CONNSYS_PLATFORM)/$(CONNSYS_PLATFORM)_pmic.o +$(MODULE_NAME)-objs += platform/$(CONNSYS_PLATFORM)/$(CONNSYS_PLATFORM)_emi.o +$(MODULE_NAME)-objs += platform/$(CONNSYS_PLATFORM)/$(CONNSYS_PLATFORM)_consys_reg.o +$(MODULE_NAME)-objs += platform/$(CONNSYS_PLATFORM)/$(CONNSYS_PLATFORM)_pos.o +#$(MODULE_NAME)-objs += platform/$(CONNSYS_PLATFORM)/$(CONNSYS_PLATFORM).o +#$(MODULE_NAME)-objs += platform/$(CONNSYS_PLATFORM)/$(CONNSYS_PLATFORM)_pmic.o +#$(MODULE_NAME)-objs += platform/$(CONNSYS_PLATFORM)/$(CONNSYS_PLATFORM)_clock.o + +# Debug utility +$(MODULE_NAME)-objs += debug_utility/connsyslog/ring_emi.o +$(MODULE_NAME)-objs += debug_utility/connsyslog/connsyslog.o +$(MODULE_NAME)-objs += debug_utility/connsyslog/platform/$(CONNSYS_PLATFORM)/$(CONNSYS_PLATFORM).o +$(MODULE_NAME)-objs += debug_utility/coredump/connsys_coredump.o +$(MODULE_NAME)-objs += debug_utility/coredump/conndump_netlink.o +$(MODULE_NAME)-objs += debug_utility/coredump/platform/$(CONNSYS_PLATFORM)/$(CONNSYS_PLATFORM).o + +# Drv init +$(MODULE_NAME)-objs += drv_init/bluetooth_drv_init.o +$(MODULE_NAME)-objs += drv_init/conn_drv_init.o +$(MODULE_NAME)-objs += drv_init/fm_drv_init.o +$(MODULE_NAME)-objs += drv_init/gps_drv_init.o +$(MODULE_NAME)-objs += drv_init/wlan_drv_init.o + +############################################################################### +# test +############################################################################### +ifneq ($(TARGET_BUILD_VARIANT), user) +ccflags-y += -D CFG_CONNINFRA_UT_SUPPORT + +ccflags-y += -I$(src)/test/include +$(MODULE_NAME)-objs += test/conninfra_core_test.o +$(MODULE_NAME)-objs += test/conf_test.o +$(MODULE_NAME)-objs += test/cal_test.o +$(MODULE_NAME)-objs += test/msg_evt_test.o +$(MODULE_NAME)-objs += test/chip_rst_test.o +$(MODULE_NAME)-objs += test/conninfra_test.o +$(MODULE_NAME)-objs += test/mailbox_test.o +$(MODULE_NAME)-objs += test/connsyslog_test.o +$(MODULE_NAME)-objs += test/dump_test.o +endif + diff --git a/drivers/misc/mediatek/connectivity/conninfra/NOTICE b/drivers/misc/mediatek/connectivity/conninfra/NOTICE new file mode 100644 index 0000000000000000000000000000000000000000..52c1cace2c1ddf53b083ad9692a5986a22a5aab6 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/NOTICE @@ -0,0 +1,202 @@ +The GNU General Public License (GPL) + +Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. +59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. + +Preamble + +The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU +General Public License is intended to guarantee your freedom to share and change free software--to make sure the +software is free for all its users. This General Public License applies to most of the Free Software Foundation's +software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is +covered by the GNU Library General Public License instead.) You can apply it to your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make +sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you +receive source code or can get it if you want it, that you can change the software or use pieces of it in new free +programs; and that you know you can do these things. + +To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to +surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the +software, or if you modify it. + +For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all +the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them +these terms so they know their rights. + +We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the software. + +Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty +for this free software. If the software is modified by someone else and passed on, we want its recipients to know that +what they have is not the original, so that any problems introduced by others will not reflect on the original authors' +reputations. + +Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors +of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, +we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. + +The precise terms and conditions for copying, distribution and modification follow. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it +may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or +work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to +say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into +another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is +addressed as "you". + +Activities other than copying, distribution and modification are not covered by this License; they are outside its +scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents +constitute a work based on the Program (independent of having been made by running the Program). Whether that is true +depends on what the Program does. + +1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided +that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of +warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other +recipients of the Program a copy of this License along with the Program. + +You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection +in exchange for a fee. + +2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and +copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of +these conditions: + +a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any +change. + +b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the +Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this +License. + +c) If the modified program normally reads commands interactively when run, you must cause it, when started running for +such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright +notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may +redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if +the Program itself is interactive but does not normally print such an announcement, your work based on the Program is +not required to print an announcement.) + +These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the +Program, and can be reasonably considered independent and separate works in themselves, then this License, and its +terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same +sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part +regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; +rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the +Program. + +In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the +Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. + +3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you also do one of the following: + +a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms +of Sections 1 and 2 above on a medium customarily used for software interchange; or, + +b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than +your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source +code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; +or, + +c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This +alternative is allowed only for noncommercial distribution and only if you received the program in object code or +executable form with such an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for making modifications to it. For an executable work, +complete source code means all the source code for all modules it contains, plus any associated interface definition +files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, +the source code distributed need not include anything that is normally distributed (in either source or binary form) +with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless +that component itself accompanies the executable. + +If distribution of executable or object code is made by offering access to copy from a designated place, then offering +equivalent access to copy the source code from the same place counts as distribution of the source code, even though +third parties are not compelled to copy the source along with the object code. + +4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your +rights under this License. However, parties who have received copies, or rights, from you under this License will not +have their licenses terminated so long as such parties remain in full compliance. + +5. You are not required to accept this License, since you have not signed it. However, nothing else grants you +permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do +not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you +indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or +modifying the Program or works based on it. + +6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a +license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You +may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not +responsible for enforcing compliance by third parties to this License. + +7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to +patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the +conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as +to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence +you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution +of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy +both it and this License would be to refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the +section is intended to apply and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest +validity of any such claims; this section has the sole purpose of protecting the integrity of the free software +distribution system, which is implemented by public license practices. Many people have made generous contributions to +the wide range of software distributed through that system in reliance on consistent application of that system; it is +up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee +cannot impose that choice. + +This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. + +8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted +interfaces, the original copyright holder who places the Program under this License may add an explicit geographical +distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if written in the body of this License. + +9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. +Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or +concerns. + +Each version is given a distinguishing version number. If the Program specifies a version number of this License which +applies to it and "any later version", you have the option of following the terms and conditions either of that version +or of any later version published by the Free Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software Foundation. + +10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are +different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, +write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two +goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of +software generally. + +NO WARRANTY + +11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM +"AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR +CORRECTION. + +12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY +WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, +SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT +LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF +THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY +OF SUCH DAMAGES. + +END OF TERMS AND CONDITIONS + + + + diff --git a/drivers/misc/mediatek/connectivity/conninfra/base/include/msg_thread.h b/drivers/misc/mediatek/connectivity/conninfra/base/include/msg_thread.h new file mode 100755 index 0000000000000000000000000000000000000000..127272436f0c1f7af06a46404b167fc39ad5788c --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/base/include/msg_thread.h @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#ifndef _BASE_MSG_THREAD_H_ +#define _BASE_MSG_THREAD_H_ + +#include "osal.h" + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + + +#define MSG_THREAD_OP_DATA_SIZE 8 +#define MSG_THREAD_OP_BUF_SIZE 64 + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +struct msg_op_data { + unsigned int op_id; /* Event ID */ + unsigned int info_bit; /* Reserved */ + size_t op_data[MSG_THREAD_OP_DATA_SIZE]; /* OP Data */ +}; + +struct msg_op { + struct msg_op_data op; + OSAL_SIGNAL signal; + int result; + atomic_t ref_count; +}; + + +struct msg_op_q { + OSAL_SLEEPABLE_LOCK lock; + unsigned int write; + unsigned int read; + unsigned int size; + struct msg_op *queue[MSG_THREAD_OP_BUF_SIZE]; +}; + +typedef OSAL_OP_DAT msg_evt_op; +typedef int(*msg_opid_func) (struct msg_op_data *); + +struct msg_thread_ctx { + OSAL_THREAD thread; /* core thread */ + OSAL_EVENT evt; + + struct msg_op_q free_op_q; /* free op queue */ + struct msg_op_q active_op_q; /* active op queue */ + struct msg_op op_q_inst[MSG_THREAD_OP_BUF_SIZE]; /* real op instances */ + struct msg_op *cur_op; /* current op */ + + int op_func_size; + const msg_opid_func *op_func; + + struct osal_op_history op_history; +}; + + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +#define MSG_OP_TIMEOUT 20000 + +int msg_thread_init(struct msg_thread_ctx *ctx, const char *name, + const msg_opid_func *func, int op_size); +int msg_thread_deinit(struct msg_thread_ctx *ctx); + +/* timeout: + * 0: default value (by MSG_OP_TIMEOUT define) + * >0: cutom timeout (ms) + */ +int msg_thread_send(struct msg_thread_ctx *ctx, int opid); +int msg_thread_send_1(struct msg_thread_ctx *ctx, int opid, + size_t param1); +int msg_thread_send_2(struct msg_thread_ctx *ctx, int opid, + size_t param1, size_t param2); + +int msg_thread_send_wait(struct msg_thread_ctx *ctx, int opid, + int timeout); +int msg_thread_send_wait_1(struct msg_thread_ctx *ctx, int opid, + int timeout, size_t param1); +int msg_thread_send_wait_2(struct msg_thread_ctx *ctx, int opid, + int timeout, size_t param1, size_t param2); +int msg_thread_send_wait_3(struct msg_thread_ctx *ctx, int opid, int timeout, size_t param1, + size_t param2,size_t param3); + + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _BASE_MSG_THREAD_H_ */ diff --git a/drivers/misc/mediatek/connectivity/conninfra/base/include/osal.h b/drivers/misc/mediatek/connectivity/conninfra/base/include/osal.h new file mode 100755 index 0000000000000000000000000000000000000000..3493dd6fb61ff79b9a2249b9c388cfcb09b81fbb --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/base/include/osal.h @@ -0,0 +1,419 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + + +/*! \file + * \brief Declaration of library functions + * Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. + */ + +#ifndef _OSAL_H_ +#define _OSAL_H_ + +#include +#include +#include +#include +#include "ring.h" +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +#define OS_BIT_OPS_SUPPORT 1 + +#ifndef MTK_CONN_BOOL_TRUE +#define MTK_CONN_BOOL_FALSE ((MTK_CONN_BOOL) 0) +#define MTK_CONN_BOOL_TRUE ((MTK_CONN_BOOL) 1) +#endif + +#define _osal_inline_ inline + +#define MAX_THREAD_NAME_LEN 16 +#define MAX_HISTORY_NAME_LEN 16 +#define OSAL_OP_BUF_SIZE 64 + + +#if (defined(CONFIG_MTK_GMO_RAM_OPTIMIZE) && !defined(CONFIG_MTK_ENG_BUILD)) +#define OSAL_OP_DATA_SIZE 8 +#else +#define OSAL_OP_DATA_SIZE 32 +#endif + +#define DBG_LOG_STR_SIZE 256 + +#define osal_sizeof(x) sizeof(x) + +#define osal_array_size(x) ARRAY_SIZE(x) + +#ifndef NAME_MAX +#define NAME_MAX 256 +#endif + +#define WMT_OP_BIT(x) (0x1UL << x) +#define WMT_OP_HIF_BIT WMT_OP_BIT(0) + +#define GET_BIT_MASK(value, mask) ((value) & (mask)) +#define SET_BIT_MASK(pdest, value, mask) (*(pdest) = (GET_BIT_MASK(*(pdest), ~(mask)) | GET_BIT_MASK(value, mask))) +#define GET_BIT_RANGE(data, end, begin) ((data) & GENMASK(end, begin)) +#define SET_BIT_RANGE(pdest, data, end, begin) (SET_BIT_MASK(pdest, data, GENMASK(end, begin))) + +#define RB_LATEST(prb) ((prb)->write - 1) +#define RB_SIZE(prb) ((prb)->size) +#define RB_MASK(prb) (RB_SIZE(prb) - 1) +#define RB_COUNT(prb) ((prb)->write - (prb)->read) +#define RB_FULL(prb) (RB_COUNT(prb) >= RB_SIZE(prb)) +#define RB_EMPTY(prb) ((prb)->write == (prb)->read) + +#define RB_INIT(prb, qsize) \ +do { \ + (prb)->read = (prb)->write = 0; \ + (prb)->size = (qsize); \ +} while (0) + +#define RB_PUT(prb, value) \ +do { \ + if (!RB_FULL(prb)) { \ + (prb)->queue[(prb)->write & RB_MASK(prb)] = value; \ + ++((prb)->write); \ + } \ + else { \ + pr_warn("RB is full!"); \ + } \ +} while (0) + +#define RB_GET(prb, value) \ +do { \ + if (!RB_EMPTY(prb)) { \ + value = (prb)->queue[(prb)->read & RB_MASK(prb)]; \ + ++((prb)->read); \ + if (RB_EMPTY(prb)) { \ + (prb)->read = (prb)->write = 0; \ + } \ + } \ + else { \ + value = NULL; \ + pr_warn("RB is empty!"); \ + } \ +} while (0) + +#define RB_GET_LATEST(prb, value) \ +do { \ + if (!RB_EMPTY(prb)) { \ + value = (prb)->queue[RB_LATEST(prb) & RB_MASK(prb)]; \ + if (RB_EMPTY(prb)) { \ + (prb)->read = (prb)->write = 0; \ + } \ + } \ + else { \ + value = NULL; \ + } \ +} while (0) + + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +typedef int MTK_CONN_BOOL; + +typedef void(*P_TIMEOUT_HANDLER) (unsigned long); +typedef int(*P_COND) (void *); + +typedef struct _OSAL_TIMER_ { + struct timer_list timer; + P_TIMEOUT_HANDLER timeoutHandler; + unsigned long timeroutHandlerData; +} OSAL_TIMER, *P_OSAL_TIMER; + +typedef struct _OSAL_UNSLEEPABLE_LOCK_ { + spinlock_t lock; + unsigned long flag; +} OSAL_UNSLEEPABLE_LOCK, *P_OSAL_UNSLEEPABLE_LOCK; + +typedef struct _OSAL_SLEEPABLE_LOCK_ { + struct mutex lock; +} OSAL_SLEEPABLE_LOCK, *P_OSAL_SLEEPABLE_LOCK; + +typedef struct _OSAL_SIGNAL_ { + struct completion comp; + unsigned int timeoutValue; + unsigned int timeoutExtension; /* max number of timeout caused by thread not able to acquire CPU */ +} OSAL_SIGNAL, *P_OSAL_SIGNAL; + +typedef struct _OSAL_EVENT_ { + wait_queue_head_t waitQueue; + unsigned int timeoutValue; + int waitFlag; + +} OSAL_EVENT, *P_OSAL_EVENT; + +/* Data collected from sched_entity and sched_statistics */ +typedef struct _OSAL_THREAD_SCHEDSTATS_ { + unsigned long long time; /* when marked: the profiling start time(ms), when unmarked: total duration(ms) */ + unsigned long long exec; /* time spent in exec (sum_exec_runtime) */ + unsigned long long runnable; /* time spent in run-queue while not being scheduled (wait_sum) */ + unsigned long long iowait; /* time spent waiting for I/O (iowait_sum) */ +} OSAL_THREAD_SCHEDSTATS, *P_OSAL_THREAD_SCHEDSTATS; + +typedef struct _OSAL_THREAD_ { + struct task_struct *pThread; + void *pThreadFunc; + void *pThreadData; + char threadName[MAX_THREAD_NAME_LEN]; +} OSAL_THREAD, *P_OSAL_THREAD; + + +typedef struct _OSAL_FIFO_ { + /*fifo definition */ + void *pFifoBody; + spinlock_t fifoSpinlock; + /*fifo operations */ + int (*FifoInit)(struct _OSAL_FIFO_ *pFifo, unsigned char *buf, unsigned int); + int (*FifoDeInit)(struct _OSAL_FIFO_ *pFifo); + int (*FifoReset)(struct _OSAL_FIFO_ *pFifo); + int (*FifoSz)(struct _OSAL_FIFO_ *pFifo); + int (*FifoAvailSz)(struct _OSAL_FIFO_ *pFifo); + int (*FifoLen)(struct _OSAL_FIFO_ *pFifo); + int (*FifoIsEmpty)(struct _OSAL_FIFO_ *pFifo); + int (*FifoIsFull)(struct _OSAL_FIFO_ *pFifo); + int (*FifoDataIn)(struct _OSAL_FIFO_ *pFifo, const void *buf, unsigned int len); + int (*FifoDataOut)(struct _OSAL_FIFO_ *pFifo, void *buf, unsigned int len); +} OSAL_FIFO, *P_OSAL_FIFO; + +typedef struct firmware osal_firmware; + +typedef struct _OSAL_OP_DAT { + unsigned int opId; /* Event ID */ + unsigned int u4InfoBit; /* Reserved */ + size_t au4OpData[OSAL_OP_DATA_SIZE]; /* OP Data */ +} OSAL_OP_DAT, *P_OSAL_OP_DAT; + +typedef struct _OSAL_LXOP_ { + OSAL_OP_DAT op; + OSAL_SIGNAL signal; + int result; + atomic_t ref_count; +} OSAL_OP, *P_OSAL_OP; + +typedef struct _OSAL_LXOP_Q { + OSAL_SLEEPABLE_LOCK sLock; + unsigned int write; + unsigned int read; + unsigned int size; + P_OSAL_OP queue[OSAL_OP_BUF_SIZE]; +} OSAL_OP_Q, *P_OSAL_OP_Q; + +typedef struct _OSAL_BIT_OP_VAR_ { + unsigned long data; + OSAL_UNSLEEPABLE_LOCK opLock; +} OSAL_BIT_OP_VAR, *P_OSAL_BIT_OP_VAR; + +typedef unsigned int (*P_OSAL_EVENT_CHECKER) (P_OSAL_THREAD pThread); + +struct osal_op_history_entry { + void *opbuf_address; + unsigned int op_id; + unsigned int opbuf_ref_count; + unsigned int op_info_bit; + size_t param_0; + size_t param_1; + size_t param_2; + size_t param_3; + unsigned long long ts; + unsigned long usec; +}; + +struct osal_op_history { + struct ring ring_buffer; + struct osal_op_history_entry *queue; + spinlock_t lock; + struct ring dump_ring_buffer; + struct work_struct dump_work; + unsigned char name[MAX_HISTORY_NAME_LEN]; +}; + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +unsigned int osal_strlen(const char *str); +int osal_strcmp(const char *dst, const char *src); +int osal_strncmp(const char *dst, const char *src, unsigned int len); +char *osal_strcpy(char *dst, const char *src); +char *osal_strncpy(char *dst, const char *src, unsigned int len); +char *osal_strcat(char *dst, const char *src); +char *osal_strncat(char *dst, const char *src, unsigned int len); +char *osal_strchr(const char *str, unsigned char c); +char *osal_strsep(char **str, const char *c); +int osal_strtol(const char *str, unsigned int adecimal, long *res); +char *osal_strstr(char *str1, const char *str2); +char *osal_strnstr(char *str1, const char *str2, int n); + +void osal_bug_on(unsigned int val); + +int osal_snprintf(char *buf, unsigned int len, const char *fmt, ...); + +int osal_sprintf(char *str, const char *format, ...); +void *osal_malloc(unsigned int size); +void osal_free(const void *dst); +void *osal_memset(void *buf, int i, unsigned int len); +void *osal_memcpy(void *dst, const void *src, unsigned int len); +void osal_memcpy_fromio(void *dst, const void *src, unsigned int len); +void osal_memcpy_toio(void *dst, const void *src, unsigned int len); +int osal_memcmp(const void *buf1, const void *buf2, unsigned int len); + +unsigned short osal_crc16(const unsigned char *buffer, const unsigned int length); +void osal_thread_show_stack(P_OSAL_THREAD pThread); + +int osal_sleep_ms(unsigned int ms); +int osal_udelay(unsigned int us); +int osal_usleep_range(unsigned long min, unsigned long max); +int osal_timer_create(P_OSAL_TIMER); +int osal_timer_start(P_OSAL_TIMER, unsigned int); +int osal_timer_stop(P_OSAL_TIMER); +int osal_timer_stop_sync(P_OSAL_TIMER pTimer); +int osal_timer_modify(P_OSAL_TIMER, unsigned int); +int osal_timer_delete(P_OSAL_TIMER); + +int osal_fifo_init(P_OSAL_FIFO pFifo, unsigned char *buffer, unsigned int size); +void osal_fifo_deinit(P_OSAL_FIFO pFifo); +int osal_fifo_reset(P_OSAL_FIFO pFifo); +unsigned int osal_fifo_in(P_OSAL_FIFO pFifo, unsigned char *buffer, + unsigned int size); +unsigned int osal_fifo_out(P_OSAL_FIFO pFifo, unsigned char *buffer, + unsigned int size); +unsigned int osal_fifo_len(P_OSAL_FIFO pFifo); +unsigned int osal_fifo_sz(P_OSAL_FIFO pFifo); +unsigned int osal_fifo_avail(P_OSAL_FIFO pFifo); +unsigned int osal_fifo_is_empty(P_OSAL_FIFO pFifo); +unsigned int osal_fifo_is_full(P_OSAL_FIFO pFifo); + +#if defined(CONFIG_PROVE_LOCKING) +#define osal_unsleepable_lock_init(l) { spin_lock_init(&((l)->lock)); } +#else +int osal_unsleepable_lock_init(P_OSAL_UNSLEEPABLE_LOCK); +#endif +int osal_lock_unsleepable_lock(P_OSAL_UNSLEEPABLE_LOCK); +int osal_unlock_unsleepable_lock(P_OSAL_UNSLEEPABLE_LOCK); +int osal_unsleepable_lock_deinit(P_OSAL_UNSLEEPABLE_LOCK); + +#if defined(CONFIG_PROVE_LOCKING) +#define osal_sleepable_lock_init(l) { mutex_init(&((l)->lock)); } +#else +int osal_sleepable_lock_init(P_OSAL_SLEEPABLE_LOCK); +#endif +int osal_lock_sleepable_lock(P_OSAL_SLEEPABLE_LOCK); +int osal_unlock_sleepable_lock(P_OSAL_SLEEPABLE_LOCK); +int osal_trylock_sleepable_lock(P_OSAL_SLEEPABLE_LOCK); +int osal_sleepable_lock_deinit(P_OSAL_SLEEPABLE_LOCK); + +int osal_signal_init(P_OSAL_SIGNAL); +int osal_wait_for_signal(P_OSAL_SIGNAL); +int osal_wait_for_signal_timeout(P_OSAL_SIGNAL, P_OSAL_THREAD); +int osal_raise_signal(P_OSAL_SIGNAL); +int osal_signal_active_state(P_OSAL_SIGNAL pSignal); +int osal_signal_deinit(P_OSAL_SIGNAL); + +int osal_event_init(P_OSAL_EVENT); +int osal_wait_for_event(P_OSAL_EVENT, P_COND, void*); +int osal_wait_for_event_timeout(P_OSAL_EVENT, P_COND, void*); +extern int osal_trigger_event(P_OSAL_EVENT); + +int osal_event_deinit(P_OSAL_EVENT); +long osal_wait_for_event_bit_set(P_OSAL_EVENT pEvent, unsigned long *pState, unsigned int bitOffset); +long osal_wait_for_event_bit_clr(P_OSAL_EVENT pEvent, unsigned long *pState, unsigned int bitOffset); + +int osal_thread_create(P_OSAL_THREAD); +int osal_thread_run(P_OSAL_THREAD); +int osal_thread_should_stop(P_OSAL_THREAD); +int osal_thread_stop(P_OSAL_THREAD); +/*int osal_thread_wait_for_event(P_OSAL_THREAD, P_OSAL_EVENT);*/ +int osal_thread_wait_for_event(P_OSAL_THREAD, P_OSAL_EVENT, P_OSAL_EVENT_CHECKER); +/*check pOsalLxOp and OSAL_THREAD_SHOULD_STOP*/ +int osal_thread_destroy(P_OSAL_THREAD); +int osal_thread_sched_mark(P_OSAL_THREAD, P_OSAL_THREAD_SCHEDSTATS schedstats); +int osal_thread_sched_unmark(P_OSAL_THREAD pThread, P_OSAL_THREAD_SCHEDSTATS schedstats); + +int osal_clear_bit(unsigned int bitOffset, P_OSAL_BIT_OP_VAR pData); +int osal_set_bit(unsigned int bitOffset, P_OSAL_BIT_OP_VAR pData); +int osal_test_bit(unsigned int bitOffset, P_OSAL_BIT_OP_VAR pData); +int osal_test_and_clear_bit(unsigned int bitOffset, P_OSAL_BIT_OP_VAR pData); +int osal_test_and_set_bit(unsigned int bitOffset, P_OSAL_BIT_OP_VAR pData); + +int osal_gettimeofday(int *sec, int *usec); +//int osal_printtimeofday(const unsigned char *prefix); +void osal_get_local_time(unsigned long long *sec, unsigned long *nsec); +unsigned long long osal_elapsed_us(unsigned long long ts, unsigned long usec); + +void osal_buffer_dump(const unsigned char *buf, const unsigned char *title, unsigned int len, unsigned int limit); +void osal_buffer_dump_data(const unsigned int *buf, const unsigned char *title, const unsigned int len, const unsigned int limit, + const int flag); + +unsigned int osal_op_get_id(P_OSAL_OP pOp); +MTK_CONN_BOOL osal_op_is_wait_for_signal(P_OSAL_OP pOp); +void osal_op_raise_signal(P_OSAL_OP pOp, int result); +void osal_set_op_result(P_OSAL_OP pOp, int result); +void osal_opq_dump(const char *qName, P_OSAL_OP_Q pOpQ); +void osal_opq_dump_locked(const char *qName, P_OSAL_OP_Q pOpQ); +MTK_CONN_BOOL osal_opq_has_op(P_OSAL_OP_Q pOpQ, P_OSAL_OP pOp); + +int osal_ftrace_print(const char *str, ...); +int osal_ftrace_print_ctrl(int flag); + +void osal_dump_thread_state(const unsigned char *name); +void osal_op_history_init(struct osal_op_history *log_history, int queue_size); +void osal_op_history_save(struct osal_op_history *log_history, P_OSAL_OP pOp); +void osal_op_history_print(struct osal_op_history *log_history, char *name); + +void osal_systrace_major_b(const char *name, ...); +void osal_systrace_major_e(void); + +void osal_systrace_minor_b(const char *name, ...); +void osal_systrace_minor_e(void); +void osal_systrace_minor_c(int val, const char *name, ...); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _OSAL_H_ */ diff --git a/drivers/misc/mediatek/connectivity/conninfra/base/include/ring.h b/drivers/misc/mediatek/connectivity/conninfra/base/include/ring.h new file mode 100755 index 0000000000000000000000000000000000000000..81168ce86615152d0999befe251fa5e69e292f1f --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/base/include/ring.h @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#ifndef _RING_H_ +#define _RING_H_ + +struct ring { + /* addr where ring buffer starts */ + void *base; + /* addr storing the next writable pos, guaranteed to be >= read except when write overflow, but it's ok. */ + unsigned int write; + /* addr storing the next readable pos, except when read == write as buffer empty */ + unsigned int read; + /* must be power of 2 */ + unsigned int max_size; +}; + +struct ring_segment { + /* addr points into ring buffer for read/write */ + void *ring_pt; + /* size to read/write */ + unsigned int sz; + /* pos in external data buffer to read/write */ + unsigned int data_pos; + /* the size to be read/write after this segment completed */ + unsigned int remain; +}; + +void ring_init(void *base, unsigned int max_size, unsigned int read, + unsigned int write, struct ring *ring); +unsigned int ring_read_prepare(unsigned int sz, struct ring_segment *seg, struct ring *ring); +#define ring_read_all_prepare(seg, ring) ring_read_prepare((ring)->max_size, seg, ring) +unsigned int ring_write_prepare(unsigned int sz, struct ring_segment *seg, struct ring *ring); +unsigned int ring_overwrite_prepare(unsigned int sz, + struct ring_segment *seg, struct ring *ring); + +/* making sure max_size is power of 2 */ +#define RING_VALIDATE_SIZE(max_size) WARN_ON(!max_size || (max_size & (max_size - 1))) + +#define RING_EMPTY(ring) ((ring)->read == (ring)->write) +/* equation works even when write overflow */ +#define RING_SIZE(ring) ((ring)->write - (ring)->read) +#define RING_FULL(ring) (RING_SIZE(ring) == (ring)->max_size) +#define RING_WRITE_REMAIN_SIZE(ring) ((ring)->max_size - RING_SIZE(ring)) + +#define RING_READ_FOR_EACH(_sz, _seg, _ring) \ + for (ring_read_prepare(_sz, &(_seg), _ring), \ + _ring_segment_prepare((_ring)->read, &(_seg), (_ring)); \ + (_seg).sz > 0; \ + _ring_read_commit(&(_seg), (_ring)), _ring_segment_prepare((_ring)->read, \ + &(_seg), (_ring))) + +#define RING_READ_ALL_FOR_EACH(seg, ring) RING_READ_FOR_EACH((ring)->max_size, seg, ring) + +#define RING_READ_FOR_EACH_ITEM(_sz, _seg, _ring) \ + for (ring_read_prepare(_sz, &(_seg), _ring), \ + _ring_segment_prepare_item((_ring)->read, &(_seg), (_ring)); \ + (_seg).sz > 0; \ + _ring_read_commit(&(_seg), (_ring)), _ring_segment_prepare_item((_ring)->read, \ + &(_seg), (_ring))) + +#define RING_WRITE_FOR_EACH(_sz, _seg, _ring) \ + for (ring_write_prepare(_sz, &(_seg), _ring),\ + _ring_segment_prepare((_ring)->write, &(_seg), (_ring)); \ + (_seg).sz > 0; \ + _ring_write_commit(&(_seg), (_ring)), _ring_segment_prepare((_ring)->write, \ + &(_seg), (_ring))) + +#define RING_OVERWRITE_FOR_EACH(_sz, _seg, _ring) \ + for (ring_overwrite_prepare(_sz, &(_seg), _ring), \ + _ring_segment_prepare((_ring)->write, &(_seg), (_ring)); \ + (_seg).sz > 0; \ + _ring_write_commit(&(_seg), (_ring)), _ring_segment_prepare((_ring)->write, \ + &(_seg), (_ring))) + +void ring_dump(const char *title, struct ring *ring); +void ring_dump_segment(const char *title, struct ring_segment *seg); + + +/* ring Buffer Internal API */ +void _ring_segment_prepare(unsigned int from, struct ring_segment *seg, struct ring *ring); +void _ring_segment_prepare_item(unsigned int from, struct ring_segment *seg, struct ring *ring); +void _ring_read_commit(struct ring_segment *seg, struct ring *ring); +void _ring_write_commit(struct ring_segment *seg, struct ring *ring); + +#endif diff --git a/drivers/misc/mediatek/connectivity/conninfra/base/msg_thread.c b/drivers/misc/mediatek/connectivity/conninfra/base/msg_thread.c new file mode 100755 index 0000000000000000000000000000000000000000..980dee6a8e5dccf537e9dba2ccde4b9691f97ad3 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/base/msg_thread.c @@ -0,0 +1,605 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#define pr_fmt(fmt) KBUILD_MODNAME "@(%s:%d) " fmt, __func__, __LINE__ +#include +#include "msg_thread.h" + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#define MSG_OP_SIZE(prb) ((prb)->size) +#define MSG_OP_MASK(prb) (MSG_OP_SIZE(prb) - 1) +#define MSG_OP_COUNT(prb) ((prb)->write - (prb)->read) +#define MSG_OP_FULL(prb) (MSG_OP_COUNT(prb) >= MSG_OP_SIZE(prb)) +#define MSG_OP_EMPTY(prb) ((prb)->write == (prb)->read) + +#define MSG_OP_INIT(prb, qsize) \ +do { \ + (prb)->read = (prb)->write = 0; \ + (prb)->size = (qsize); \ +} while (0) + +#define MSG_OP_PUT(prb, value) \ +do { \ + if (!MSG_OP_FULL(prb)) { \ + (prb)->queue[(prb)->write & MSG_OP_MASK(prb)] = value; \ + ++((prb)->write); \ + } \ + else { \ + pr_warn("Message queue is full."); \ + } \ +} while (0) + +#define MSG_OP_GET(prb, value) \ +do { \ + if (!MSG_OP_EMPTY(prb)) { \ + value = (prb)->queue[(prb)->read & MSG_OP_MASK(prb)]; \ + ++((prb)->read); \ + if (MSG_OP_EMPTY(prb)) { \ + (prb)->read = (prb)->write = 0; \ + } \ + } \ + else { \ + value = NULL; \ + pr_warn("Message queue is empty."); \ + } \ +} while (0) + + + +#if defined(CONFIG_MTK_ENG_BUILD) || defined(CONFIG_MT_ENG_BUILD) +static bool msg_evt_opq_has_op(struct msg_op_q *op_q, struct msg_op *op) +{ + unsigned int rd; + unsigned int wt; + struct msg_op *tmp_op; + + rd = op_q->read; + wt = op_q->write; + + while (rd != wt) { + tmp_op = op_q->queue[rd & MSG_OP_MASK(op_q)]; + if (op == tmp_op) + return true; + rd++; + } + return false; +} +#endif + +/* + * Utility functions + */ +static int msg_evt_put_op_to_q(struct msg_op_q *op_q, struct msg_op *op) +{ + int ret; + + if (!op_q || !op) { + pr_err("invalid input param: pOpQ(0x%p), pLxOp(0x%p)\n", op_q, op); + return -1; + } + + ret = osal_lock_sleepable_lock(&op_q->lock); + if (ret) { + pr_warn("osal_lock_sleepable_lock iRet(%d)\n", ret); + return -2; + } + +#if defined(CONFIG_MTK_ENG_BUILD) || defined(CONFIG_MT_ENG_BUILD) + if (msg_evt_opq_has_op(op_q, op)) { + pr_err("Op(%p) already exists in queue(%p)\n", op, op_q); + ret = -3; + } +#endif + + /* acquire lock success */ + if (!MSG_OP_FULL(op_q)) + MSG_OP_PUT(op_q, op); + else { + pr_warn("MSG_OP_FULL(%p -> %p)\n", op, op_q); + ret = -4; + } + + osal_unlock_sleepable_lock(&op_q->lock); + + if (ret) { + //osal_opq_dump("FreeOpQ", &g_conninfra_ctx.rFreeOpQ); + //osal_opq_dump("ActiveOpQ", &g_conninfra_ctx.rActiveOpQ); + return ret; + } + return 0; +} + + +/* + * Utility functions + */ +static struct msg_op *msg_evt_get_op_from_q(struct msg_op_q *op_q) +{ + struct msg_op *op; + int ret; + + if (op_q == NULL) { + pr_err("pOpQ = NULL\n"); + return NULL; + } + + ret = osal_lock_sleepable_lock(&op_q->lock); + if (ret) { + pr_err("osal_lock_sleepable_lock iRet(%d)\n", ret); + return NULL; + } + + /* acquire lock success */ + MSG_OP_GET(op_q, op); + osal_unlock_sleepable_lock(&op_q->lock); + + if (op == NULL) { + pr_warn("MSG_OP_GET(%p) return NULL\n", op_q); + //osal_opq_dump("FreeOpQ", &g_conninfra_ctx.rFreeOpQ); + //osal_opq_dump("ActiveOpQ", &g_conninfra_ctx.rActiveOpQ); + } + + return op; +} + +/* + * msg_evt_thread API + */ + +int msg_evt_put_op_to_free_queue(struct msg_thread_ctx *ctx, struct msg_op *op) +{ + if (msg_evt_put_op_to_q(&ctx->free_op_q, op)) + return -1; + return 0; +} + + +struct msg_op *msg_evt_get_free_op(struct msg_thread_ctx *ctx) +{ + struct msg_op *op = NULL; + + if (ctx == NULL) { + pr_warn("ctx is null."); + return op; + } + op = msg_evt_get_op_from_q(&ctx->free_op_q); + if (op) + osal_memset(op, 0, osal_sizeof(struct msg_op)); + return op; +} + +int msg_evt_put_op_to_active(struct msg_thread_ctx *ctx, struct msg_op *op) +{ + P_OSAL_SIGNAL signal = NULL; + int wait_ret = -1; + int ret = 0; + + do { + if (!ctx || !op) { + pr_err("msg_thread_ctx(0x%p), op(0x%p)\n", ctx, op); + break; + } + + signal = &op->signal; + if (signal->timeoutValue) { + op->result = -9; + osal_signal_init(signal); + atomic_set(&op->ref_count, 1); + } else + atomic_set(&op->ref_count, 0); + + /* Increment ref_count by 1 as wmtd thread will hold a reference also, + * this must be done here instead of on target thread, because + * target thread might not be scheduled until a much later time, + * allowing current thread to decrement ref_count at the end of function, + * putting op back to free queue before target thread has a chance to process. + */ + atomic_inc(&op->ref_count); + + /* put to active Q */ + ret = msg_evt_put_op_to_q(&ctx->active_op_q, op); + if (ret) { + pr_warn("put to active queue fail\n"); + atomic_dec(&op->ref_count); + break; + } + + /* wake up conninfra_cored */ + osal_trigger_event(&ctx->evt); + + if (signal->timeoutValue == 0) { + //ret = -1; + /* Not set timeout, don't wait */ + /* pr_info("[%s] timeout is zero", __func__);*/ + break; + } + + /* check result */ + wait_ret = osal_wait_for_signal_timeout(signal, &ctx->thread); + /*pr_info("osal_wait_for_signal_timeout:%d result=[%d]\n", + wait_ret, op->result);*/ + + if (wait_ret == 0) + pr_warn("opId(%d) completion timeout\n", op->op.op_id); + else if (op->result) + pr_info("opId(%d) result:%d\n", + op->op.op_id, op->result); + + /* op completes, check result */ + ret = op->result; + } while (0); + + if (op != NULL && signal != NULL && signal->timeoutValue && + atomic_dec_and_test(&op->ref_count)) { + /* put Op back to freeQ */ + msg_evt_put_op_to_free_queue(ctx, op); + } + + return ret; +} + + +int msg_thread_send(struct msg_thread_ctx *ctx, int opid) +{ + return msg_thread_send_2(ctx, opid, 0, 0); +} + +int msg_thread_send_1(struct msg_thread_ctx *ctx, int opid, + size_t param1) +{ + return msg_thread_send_2(ctx, opid, param1, 0); +} + +int msg_thread_send_2(struct msg_thread_ctx *ctx, int opid, + size_t param1, size_t param2) +{ + struct msg_op *op = NULL; + P_OSAL_SIGNAL signal; + int ret; + + op = msg_evt_get_free_op(ctx); + if (!op) { + pr_err("[%s] can't get free op\n", __func__); + return -1; + } + op->op.op_id = opid; + op->op.op_data[0] = param1; + op->op.op_data[1] = param2; + + signal = &op->signal; + //signal->timeoutValue = timeout > 0 ? timeout : MSG_OP_TIMEOUT; + signal->timeoutValue = 0; + ret = msg_evt_put_op_to_active(ctx, op); + + return ret; +} + +int msg_thread_send_wait(struct msg_thread_ctx *ctx, int opid, + int timeout) +{ + return msg_thread_send_wait_3(ctx, opid, timeout, 0, 0, 0); +} + +int msg_thread_send_wait_1(struct msg_thread_ctx *ctx, + int opid, int timeout, + size_t param1) +{ + return msg_thread_send_wait_3(ctx, opid, timeout, param1, 0, 0); +} + + +int msg_thread_send_wait_2(struct msg_thread_ctx *ctx, + int opid, int timeout, + size_t param1, + size_t param2) +{ + return msg_thread_send_wait_3(ctx, opid, timeout, param1, param2, 0); +} + +int msg_thread_send_wait_3(struct msg_thread_ctx *ctx, + int opid, int timeout, + size_t param1, + size_t param2, + size_t param3) +{ + struct msg_op *op = NULL; + P_OSAL_SIGNAL signal; + int ret; + + op = msg_evt_get_free_op(ctx); + if (!op) { + pr_err("[%s] can't get free op\n", __func__); + return -1; + } + op->op.op_id = opid; + op->op.op_data[0] = param1; + op->op.op_data[1] = param2; + op->op.op_data[2] = param3; + + signal = &op->signal; + signal->timeoutValue = timeout > 0 ? timeout : MSG_OP_TIMEOUT; + ret = msg_evt_put_op_to_active(ctx, op); + return ret; + +} + +void msg_op_history_save(struct osal_op_history *log_history, struct msg_op *op) +{ + struct osal_op_history_entry *entry = NULL; + struct ring_segment seg; + int index; + unsigned long long sec = 0; + unsigned long usec = 0; + unsigned long flags; + + if (log_history->queue == NULL) + return; + + osal_get_local_time(&sec, &usec); + + spin_lock_irqsave(&(log_history->lock), flags); + RING_OVERWRITE_FOR_EACH(1, seg, &log_history->ring_buffer) { + index = seg.ring_pt - log_history->ring_buffer.base; + entry = &log_history->queue[index]; + } + + if (entry == NULL) { + pr_info("Entry is null, size %d\n", + RING_SIZE(&log_history->ring_buffer)); + spin_unlock_irqrestore(&(log_history->lock), flags); + return; + } + + entry->opbuf_address = op; + entry->op_id = op->op.op_id; + entry->opbuf_ref_count = atomic_read(&op->ref_count); + entry->op_info_bit = op->op.info_bit; + entry->param_0 = op->op.op_data[0]; + entry->param_1 = op->op.op_data[1]; + entry->param_2 = op->op.op_data[2]; + entry->param_3 = op->op.op_data[3]; + entry->ts = sec; + entry->usec = usec; + spin_unlock_irqrestore(&(log_history->lock), flags); +} + +unsigned int msg_evt_wait_event_checker(P_OSAL_THREAD thread) +{ + struct msg_thread_ctx *ctx = NULL; + + if (thread) { + ctx = (struct msg_thread_ctx *) (thread->pThreadData); + return !MSG_OP_EMPTY(&ctx->active_op_q); + } + return 0; +} + +int msg_evt_set_current_op(struct msg_thread_ctx *ctx, struct msg_op *op) +{ + ctx->cur_op = op; + return 0; +} + +int msg_evt_opid_handler(struct msg_thread_ctx *ctx, struct msg_op_data *op) +{ + int opid, ret; + + /*sanity check */ + if (op == NULL) { + pr_warn("null op\n"); + return -1; + } + if (ctx == NULL) { + pr_warn("null evt thread ctx\n"); + return -2; + } + + opid = op->op_id; + + if (opid >= ctx->op_func_size) { + pr_err("msg_evt_thread invalid OPID(%d)\n", opid); + return -3; + } + + if (ctx->op_func[opid] == NULL) { + pr_err("null handler (%d)\n", opid); + return -4; + } + ret = (*(ctx->op_func[opid])) (op); + return ret; +} + +static int msg_evt_thread(void *pvData) +{ + struct msg_thread_ctx *ctx = (struct msg_thread_ctx *)pvData; + P_OSAL_EVENT evt = NULL; + struct msg_op *op; + int ret; + + if (ctx == NULL) { + pr_err("msg_evt_thread (NULL)\n"); + return -1; + } + + evt = &(ctx->evt); + + for (;;) { + op = NULL; + evt->timeoutValue = 0; + + osal_thread_wait_for_event(&ctx->thread, evt, msg_evt_wait_event_checker); + + if (osal_thread_should_stop(&ctx->thread)) { + pr_info("msg_evt_thread thread should stop now...\n"); + /* TODO: clean up active opQ */ + break; + } + /* get Op from activeQ */ + op = msg_evt_get_op_from_q(&ctx->active_op_q); + if (!op) { + pr_warn("get op from activeQ fail\n"); + continue; + } + + /* TODO: save op history */ + msg_op_history_save(&ctx->op_history, op); + msg_evt_set_current_op(ctx, op); + ret = msg_evt_opid_handler(ctx, &op->op); + msg_evt_set_current_op(ctx, NULL); + + if (ret) + pr_warn("opid (0x%x) failed, ret(%d)\n", + op->op.op_id, ret); + + if (atomic_dec_and_test(&op->ref_count)) { + /* msg_evt_free_op(ctx) */ + msg_evt_put_op_to_free_queue(ctx, op); + } else if (op->signal.timeoutValue) { + op->result = ret; + osal_raise_signal(&op->signal); + } + } + + pr_debug("msg evt thread exists\n"); + return 0; +} + +int msg_thread_init(struct msg_thread_ctx *ctx, + const char *thread_name, const msg_opid_func *funcs, + int op_size) +{ + int r = 0, i; + P_OSAL_THREAD p_thread; + + osal_memset(ctx, 0, sizeof(struct msg_thread_ctx)); + + ctx->op_func = funcs; + ctx->op_func_size = op_size; + + /* init thread inst */ + p_thread = &ctx->thread; + + osal_strncpy(p_thread->threadName, thread_name, + sizeof(p_thread->threadName)); + + p_thread->pThreadData = (void *) ctx; + p_thread->pThreadFunc = (void *) msg_evt_thread; + r = osal_thread_create(p_thread); + + if (r) { + pr_err("osal_thread_create(0x%p) fail(%d)\n", p_thread, r); + return -1; + } + + osal_event_init(&ctx->evt); + osal_sleepable_lock_init(&ctx->active_op_q.lock); + osal_sleepable_lock_init(&ctx->free_op_q.lock); + + /* Initialize op queue */ + MSG_OP_INIT(&ctx->free_op_q, MSG_THREAD_OP_BUF_SIZE); + MSG_OP_INIT(&ctx->active_op_q, MSG_THREAD_OP_BUF_SIZE); + + /* Put all to free Q */ + for (i = 0; i < MSG_THREAD_OP_BUF_SIZE; i++) { + osal_signal_init(&(ctx->op_q_inst[i].signal)); + msg_evt_put_op_to_free_queue(ctx, &(ctx->op_q_inst[i])); + } + + osal_op_history_init(&ctx->op_history, 16); + + r = osal_thread_run(p_thread); + if (r) { + pr_err("osal_thread_run(evt_thread 0x%p) fail(%d)\n", + p_thread, r); + return -2; + } + return r; +} + +int msg_thread_deinit(struct msg_thread_ctx *ctx) +{ + int r, i; + P_OSAL_THREAD p_thraed = &ctx->thread; + + r = osal_thread_stop(p_thraed); + if (r) { + pr_err("osal_thread_stop(0x%p) fail(%d)\n", p_thraed, r); + return -1; + } + + for (i = 0; i < MSG_THREAD_OP_BUF_SIZE; i++) + osal_signal_deinit(&(ctx->op_q_inst[i].signal)); + + osal_sleepable_lock_deinit(&ctx->free_op_q.lock); + osal_sleepable_lock_deinit(&ctx->active_op_q.lock); + + r = osal_thread_destroy(p_thraed); + if (r) { + pr_err("osal_thread_stop(0x%p) fail(%d)\n", p_thraed, r); + return -2; + } + + osal_memset(ctx, 0, sizeof(struct msg_thread_ctx)); + + pr_debug("[%s] DONE\n", __func__); + return 0; +} diff --git a/drivers/misc/mediatek/connectivity/conninfra/base/osal.c b/drivers/misc/mediatek/connectivity/conninfra/base/osal.c new file mode 100755 index 0000000000000000000000000000000000000000..36b6e18df626c9ea747402777f02c1a79ecc538b --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/base/osal.c @@ -0,0 +1,1644 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +/*! \file + * \brief Declaration of library functions + * Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. + */ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ +#define pr_fmt(fmt) KBUILD_MODNAME "@(%s:%d) " fmt, __func__, __LINE__ +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "connectivity_build_in_adapter.h" +#include "osal.h" + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +#define GPIO_ASSERT 70 +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/* CRC table for the CRC-16. The poly is 0x8005 (x^16 + x^15 + x^2 + 1) */ +static unsigned short const crc16_table[256] = { + 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, + 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, + 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, + 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, + 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, + 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, + 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, + 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, + 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, + 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, + 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, + 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, + 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, + 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, + 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, + 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, + 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, + 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, + 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, + 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, + 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, + 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, + 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, + 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, + 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, + 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, + 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, + 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, + 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, + 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, + 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, + 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040 +}; + +int ftrace_flag = 1; + +static unsigned long __read_mostly mark_addr; +static unsigned int g_pid; +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +/*string operations*/ +unsigned int osal_strlen(const char *str) +{ + return strlen(str); +} + +int osal_strcmp(const char *dst, const char *src) +{ + return strcmp(dst, src); +} + +int osal_strncmp(const char *dst, const char *src, unsigned int len) +{ + return strncmp(dst, src, len); +} + +char *osal_strcpy(char *dst, const char *src) +{ + return strncpy(dst, src, strlen(src)+1); +} + +char *osal_strncpy(char *dst, const char *src, unsigned int len) +{ + return strncpy(dst, src, len); +} + +char *osal_strcat(char *dst, const char *src) +{ + return strncat(dst, src, strlen(src)); +} + +char *osal_strncat(char *dst, const char *src, unsigned int len) +{ + return strncat(dst, src, len); +} + +char *osal_strchr(const char *str, unsigned char c) +{ + return strchr(str, c); +} + +char *osal_strsep(char **str, const char *c) +{ + return strsep(str, c); +} + +int osal_strtol(const char *str, unsigned int adecimal, long *res) +{ + if (sizeof(long) == 4) + return kstrtou32(str, adecimal, (unsigned int *) res); + else + return kstrtol(str, adecimal, res); +} + +char *osal_strstr(char *str1, const char *str2) +{ + return strstr(str1, str2); +} + +char *osal_strnstr(char *str1, const char *str2, int n) +{ + return strnstr(str1, str2, n); +} + +void osal_bug_on(unsigned int val) +{ + WARN_ON(val); +} + +int osal_snprintf(char *buf, unsigned int len, const char *fmt, ...) +{ + int iRet = 0; + va_list args; + + /*va_start(args, fmt); */ + va_start(args, fmt); + /*iRet = snprintf(buf, len, fmt, args); */ + iRet = vsnprintf(buf, len, fmt, args); + va_end(args); + + return iRet; +} + +int osal_sprintf(char *str, const char *format, ...) +{ + int iRet = 0; + va_list args; + + va_start(args, format); + iRet = vsnprintf(str, DBG_LOG_STR_SIZE, format, args); + va_end(args); + + return iRet; +} + +void *osal_malloc(unsigned int size) +{ + return vmalloc(size); +} + +void osal_free(const void *dst) +{ + vfree(dst); +} + +void *osal_memset(void *buf, int i, unsigned int len) +{ + return memset(buf, i, len); +} + +void *osal_memcpy(void *dst, const void *src, unsigned int len) +{ + return memcpy(dst, src, len); +} + +void osal_memcpy_fromio(void *dst, const void *src, unsigned int len) +{ + return memcpy_fromio(dst, src, len); +} + +void osal_memcpy_toio(void *dst, const void *src, unsigned int len) +{ + return memcpy_toio(dst, src, len); +} + +int osal_memcmp(const void *buf1, const void *buf2, unsigned int len) +{ + return memcmp(buf1, buf2, len); +} + +unsigned short osal_crc16(const unsigned char *buffer, + const unsigned int length) +{ + unsigned short crc = 0; + unsigned int i = 0; + const unsigned char *temp = buffer; + + /* FIXME: Add STP checksum feature */ + crc = 0; + for (i = 0; i < length; i++, temp++) + crc = (crc >> 8) ^ crc16_table[(crc ^ (*temp)) & 0xff]; + return crc; +} + +void osal_dump_thread_state(const unsigned char *name) +{ + //return connectivity_export_dump_thread_state(name); +} + +static inline bool __osal_is_valid_thread(P_OSAL_THREAD pThread) +{ + if ((pThread) && !IS_ERR_OR_NULL(pThread->pThread)) + return true; + else + return false; +} + +void osal_thread_show_stack(P_OSAL_THREAD pThread) +{ + if (__osal_is_valid_thread(pThread)) + KERNEL_show_stack(pThread->pThread, NULL); +} + +/* + * OSAL layer Thread Opeartion related APIs + * + */ +int osal_thread_create(P_OSAL_THREAD pThread) +{ + struct task_struct *task; + + if (!pThread) + return -1; + + task = kthread_create(pThread->pThreadFunc, + pThread->pThreadData, pThread->threadName); + if (IS_ERR(task)) { + pr_err("[%s] create %s thread fail", __func__, pThread->threadName); + return -1; + } + + pThread->pThread = task; + return 0; +} + +int osal_thread_run(P_OSAL_THREAD pThread) +{ + if (__osal_is_valid_thread(pThread)) { + wake_up_process(pThread->pThread); + return 0; + } else { + return -1; + } +} + +int osal_thread_stop(P_OSAL_THREAD pThread) +{ + int iRet; + + if (__osal_is_valid_thread(pThread)) { + iRet = kthread_stop(pThread->pThread); + pThread->pThread = NULL; + return iRet; + } + return -1; +} + +int osal_thread_should_stop(P_OSAL_THREAD pThread) +{ + if (__osal_is_valid_thread(pThread)) + return kthread_should_stop(); + else + return 1; + +} + +int osal_thread_wait_for_event(P_OSAL_THREAD pThread, + P_OSAL_EVENT pEvent, P_OSAL_EVENT_CHECKER pChecker) +{ + /* P_DEV_WMT pDevWmt;*/ + + if (__osal_is_valid_thread(pThread) && (pEvent) && (pChecker)) { + return wait_event_interruptible(pEvent->waitQueue, ( + osal_thread_should_stop(pThread) + || (*pChecker) (pThread))); + } + return -1; +} + +int osal_thread_destroy(P_OSAL_THREAD pThread) +{ + if (__osal_is_valid_thread(pThread)) { + kthread_stop(pThread->pThread); + pThread->pThread = NULL; + } + return 0; +} + +/* + * osal_thread_sched_retrieve + * Retrieve thread's current scheduling statistics and stored in output "sched". + * Return value: + * 0 : Schedstats successfully retrieved + * -1 : Kernel's schedstats feature not enabled + * -2 : pThread not yet initialized or sched is a NULL pointer + */ +static int osal_thread_sched_retrieve(P_OSAL_THREAD pThread, + P_OSAL_THREAD_SCHEDSTATS sched) +{ +#ifdef CONFIG_SCHEDSTATS + struct sched_entity se; + unsigned long long sec; + unsigned long usec; + + if (!sched) + return -2; + + /* always clear sched to simplify error handling at caller side */ + memset(sched, 0, sizeof(OSAL_THREAD_SCHEDSTATS)); + + if (!__osal_is_valid_thread(pThread)) + return -2; + + memcpy(&se, &pThread->pThread->se, sizeof(struct sched_entity)); + osal_get_local_time(&sec, &usec); + + sched->time = sec*1000 + usec/1000; + sched->exec = se.sum_exec_runtime; + sched->runnable = se.statistics.wait_sum; + sched->iowait = se.statistics.iowait_sum; + + return 0; +#else + /* always clear sched to simplify error handling at caller side */ + if (sched) + memset(sched, 0, sizeof(OSAL_THREAD_SCHEDSTATS)); + return -1; +#endif +} + +/* + * osal_thread_sched_mark + * Record the thread's current schedstats and stored + * in output "schedstats" parameter for profiling at + * later time. + * Return value: + * 0 : Schedstats successfully recorded + * -1 : Kernel's schedstats feature not enabled + * -2 : pThread not yet initialized or invalid parameters + */ +int osal_thread_sched_mark(P_OSAL_THREAD pThread, + P_OSAL_THREAD_SCHEDSTATS schedstats) +{ + return osal_thread_sched_retrieve(pThread, schedstats); +} + +/* + * osal_thread_sched_unmark + * Calculate scheduling statistics against the previously marked point. + * The result will be filled back into the schedstats output parameter. + * Return value: + * 0 : Schedstats successfully calculated + * -1 : Kernel's schedstats feature not enabled + * -2 : pThread not yet initialized or invalid parameters + */ +int osal_thread_sched_unmark(P_OSAL_THREAD pThread, + P_OSAL_THREAD_SCHEDSTATS schedstats) +{ + int ret; + OSAL_THREAD_SCHEDSTATS sched_now; + + if (unlikely(!schedstats)) { + ret = -2; + } else { + ret = osal_thread_sched_retrieve(pThread, &sched_now); + if (ret == 0) { + schedstats->time = sched_now.time - schedstats->time; + schedstats->exec = sched_now.exec - schedstats->exec; + schedstats->runnable = + sched_now.runnable - schedstats->runnable; + schedstats->iowait = + sched_now.iowait - schedstats->iowait; + } + } + return ret; +} + +/* + * OSAL layer Signal Opeartion related APIs + * initialization + * wait for signal + * wait for signal timerout + * raise signal + * destroy a signal + * + */ + +int osal_signal_init(P_OSAL_SIGNAL pSignal) +{ + if (pSignal) { + init_completion(&pSignal->comp); + return 0; + } else { + return -1; + } +} + +int osal_wait_for_signal(P_OSAL_SIGNAL pSignal) +{ + if (pSignal) { + wait_for_completion_interruptible(&pSignal->comp); + return 0; + } else { + return -1; + } +} + +/* + * osal_wait_for_signal_timeout + * + * Wait for a signal to be triggered by the corresponding thread, within the + * expected timeout specified by the signal's timeoutValue. + * When the pThread parameter is specified, the thread's scheduling ability is + * considered, the timeout will be extended when thread cannot acquire CPU + * resource, and will only extend for a number of times specified by the + * signal's timeoutExtension should the situation continues. + * + * Return value: + * 0 : timeout + * >0 : signal triggered + */ +int osal_wait_for_signal_timeout(P_OSAL_SIGNAL pSignal, P_OSAL_THREAD pThread) +{ + OSAL_THREAD_SCHEDSTATS schedstats; + int waitRet; + + /* [ChangeFeature][George] gps driver may be closed by -ERESTARTSYS. + * Avoid using *interruptible" version in order to complete our jobs, + * such as function off gracefully. + */ + if (!pThread || !pThread->pThread) + return wait_for_completion_timeout(&pSignal->comp, + msecs_to_jiffies(pSignal->timeoutValue)); + + do { + osal_thread_sched_mark(pThread, &schedstats); + waitRet = wait_for_completion_timeout(&pSignal->comp, + msecs_to_jiffies(pSignal->timeoutValue)); + osal_thread_sched_unmark(pThread, &schedstats); + + if (waitRet > 0) + break; + + if (schedstats.runnable > schedstats.exec) { + pr_err( + "[E]%s:wait completion timeout, %s cannot get CPU, extension(%d), show backtrace:\n", + __func__, + pThread->threadName, + pSignal->timeoutExtension); + } else { + pr_err( + "[E]%s:wait completion timeout, show %s backtrace:\n", + __func__, + pThread->threadName); + pSignal->timeoutExtension = 0; + } + pr_err( + "[E]%s:\tduration:%llums, sched(x%llu/r%llu/i%llu)\n", + __func__, + schedstats.time, + schedstats.exec, + schedstats.runnable, + schedstats.iowait); + /* + * no need to disginguish combo or A/D die projects + * osal_dump_thread_state will just return if target + * thread does not exist + */ + osal_dump_thread_state("mtk_wmtd"); + osal_dump_thread_state("mtk_wmtd_worker"); + osal_dump_thread_state("btif_rxd"); + osal_dump_thread_state("mtk_stp_psm"); + osal_dump_thread_state("mtk_stp_btm"); + osal_dump_thread_state("stp_sdio_tx_rx"); + } while (pSignal->timeoutExtension--); + return waitRet; +} + +int osal_raise_signal(P_OSAL_SIGNAL pSignal) +{ + if (pSignal) { + complete(&pSignal->comp); + return 0; + } else + return -1; +} + +int osal_signal_active_state(P_OSAL_SIGNAL pSignal) +{ + if (pSignal) + return pSignal->timeoutValue; + else + return -1; +} + +int osal_signal_deinit(P_OSAL_SIGNAL pSignal) +{ + if (pSignal) { + pSignal->timeoutValue = 0; + return 0; + } else + return -1; +} + +/* + * OSAL layer Event Opeartion related APIs + * initialization + * wait for signal + * wait for signal timerout + * raise signal + * destroy a signal + * + */ + +int osal_event_init(P_OSAL_EVENT pEvent) +{ + if (pEvent) { + init_waitqueue_head(&pEvent->waitQueue); + return 0; + } + return -1; +} + +int osal_trigger_event(P_OSAL_EVENT pEvent) +{ + int ret = 0; + + if (pEvent) { + wake_up_interruptible(&pEvent->waitQueue); + return ret; + } + return -1; +} + +int osal_wait_for_event(P_OSAL_EVENT pEvent, + int (*condition)(void *), void *cond_pa) +{ + if (pEvent) + return wait_event_interruptible(pEvent->waitQueue, + condition(cond_pa)); + else + return -1; +} + +int osal_wait_for_event_timeout(P_OSAL_EVENT pEvent, + int (*condition)(void *), void *cond_pa) +{ + if (pEvent) + return wait_event_interruptible_timeout(pEvent->waitQueue, + condition(cond_pa), + msecs_to_jiffies(pEvent->timeoutValue)); + return -1; +} + + +int osal_event_deinit(P_OSAL_EVENT pEvent) +{ + return 0; +} + +long osal_wait_for_event_bit_set(P_OSAL_EVENT pEvent, + unsigned long *pState, unsigned int bitOffset) +{ + unsigned int ms = 0; + + if (pEvent) { + ms = pEvent->timeoutValue; + if (ms != 0) + return wait_event_interruptible_timeout( + pEvent->waitQueue, + test_bit(bitOffset, pState), + msecs_to_jiffies(ms)); + else + return wait_event_interruptible(pEvent->waitQueue, + test_bit(bitOffset, pState)); + } else + return -1; + +} + +long osal_wait_for_event_bit_clr(P_OSAL_EVENT pEvent, + unsigned long *pState, unsigned int bitOffset) +{ + unsigned int ms = 0; + + if (pEvent) { + ms = pEvent->timeoutValue; + if (ms != 0) + return wait_event_interruptible_timeout( + pEvent->waitQueue, + !test_bit(bitOffset, pState), + msecs_to_jiffies(ms)); + else + return wait_event_interruptible(pEvent->waitQueue, + !test_bit(bitOffset, pState)); + } else + return -1; +} + +/* + * bit test and set/clear operations APIs + */ +#if OS_BIT_OPS_SUPPORT +#define osal_bit_op_lock(x) +#define osal_bit_op_unlock(x) +#else + +int osal_bit_op_lock(P_OSAL_UNSLEEPABLE_LOCK pLock) +{ + + return 0; +} + +int osal_bit_op_unlock(P_OSAL_UNSLEEPABLE_LOCK pLock) +{ + + return 0; +} +#endif +int osal_clear_bit(unsigned int bitOffset, P_OSAL_BIT_OP_VAR pData) +{ + osal_bit_op_lock(&(pData->opLock)); + clear_bit(bitOffset, &pData->data); + osal_bit_op_unlock(&(pData->opLock)); + return 0; +} + +int osal_set_bit(unsigned int bitOffset, P_OSAL_BIT_OP_VAR pData) +{ + osal_bit_op_lock(&(pData->opLock)); + set_bit(bitOffset, &pData->data); + osal_bit_op_unlock(&(pData->opLock)); + return 0; +} + +int osal_test_bit(unsigned int bitOffset, P_OSAL_BIT_OP_VAR pData) +{ + unsigned int iRet = 0; + + osal_bit_op_lock(&(pData->opLock)); + iRet = test_bit(bitOffset, &pData->data); + osal_bit_op_unlock(&(pData->opLock)); + return iRet; +} + +int osal_test_and_clear_bit(unsigned int bitOffset, P_OSAL_BIT_OP_VAR pData) +{ + unsigned int iRet = 0; + + osal_bit_op_lock(&(pData->opLock)); + iRet = test_and_clear_bit(bitOffset, &pData->data); + osal_bit_op_unlock(&(pData->opLock)); + return iRet; + +} + +int osal_test_and_set_bit(unsigned int bitOffset, P_OSAL_BIT_OP_VAR pData) +{ + unsigned int iRet = 0; + + osal_bit_op_lock(&(pData->opLock)); + iRet = test_and_set_bit(bitOffset, &pData->data); + osal_bit_op_unlock(&(pData->opLock)); + return iRet; +} + +/* + * tiemr operations APIs + * create + * stop + * modify + * create + * delete + * + */ + +int osal_timer_create(P_OSAL_TIMER pTimer) +{ + struct timer_list *timer = &pTimer->timer; + + init_timer(timer); + timer->function = pTimer->timeoutHandler; + timer->data = (unsigned long)pTimer->timeroutHandlerData; + return 0; +} + +int osal_timer_start(P_OSAL_TIMER pTimer, unsigned int ms) +{ + + struct timer_list *timer = &pTimer->timer; + + timer->expires = jiffies + (ms / (1000 / HZ)); + add_timer(timer); + return 0; +} + +int osal_timer_stop(P_OSAL_TIMER pTimer) +{ + struct timer_list *timer = &pTimer->timer; + + del_timer(timer); + return 0; +} + +int osal_timer_stop_sync(P_OSAL_TIMER pTimer) +{ + struct timer_list *timer = &pTimer->timer; + + del_timer_sync(timer); + return 0; +} + +int osal_timer_modify(P_OSAL_TIMER pTimer, unsigned int ms) +{ + + mod_timer(&pTimer->timer, jiffies + (ms) / (1000 / HZ)); + return 0; +} + +int _osal_fifo_init(OSAL_FIFO *pFifo, unsigned char *buf, unsigned int size) +{ + struct kfifo *fifo = NULL; + int ret = -1; + + if (!pFifo) { + pr_err("pFifo must be !NULL\n"); + return -1; + } + if (pFifo->pFifoBody) { + pr_err("pFifo->pFifoBody must be NULL\n"); + pr_err("pFifo(0x%p), pFifo->pFifoBody(0x%p)\n", + pFifo, pFifo->pFifoBody); + return -1; + } + fifo = kzalloc(sizeof(struct kfifo), GFP_ATOMIC); + if (!buf) { + /*fifo's buffer is not ready, we allocate automatically */ + ret = kfifo_alloc(fifo, size, /*GFP_KERNEL */ GFP_ATOMIC); + } else { + if (is_power_of_2(size)) { + kfifo_init(fifo, buf, size); + ret = 0; + } else { + kfifo_free(fifo); + fifo = NULL; + ret = -1; + } + } + + pFifo->pFifoBody = fifo; + return (ret < 0) ? (-1) : (0); +} + +int _osal_fifo_deinit(OSAL_FIFO *pFifo) +{ + struct kfifo *fifo = NULL; + + if (!pFifo || !pFifo->pFifoBody) { + pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", + __func__); + return -1; + } + + fifo = (struct kfifo *)pFifo->pFifoBody; + + if (fifo) + kfifo_free(fifo); + + return 0; +} + +int _osal_fifo_size(OSAL_FIFO *pFifo) +{ + struct kfifo *fifo = NULL; + int ret = 0; + + if (!pFifo || !pFifo->pFifoBody) { + pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", + __func__); + return -1; + } + + fifo = (struct kfifo *)pFifo->pFifoBody; + + if (fifo) + ret = kfifo_size(fifo); + + return ret; +} + +/*returns unused bytes in fifo*/ +int _osal_fifo_avail_size(OSAL_FIFO *pFifo) +{ + struct kfifo *fifo = NULL; + int ret = 0; + + if (!pFifo || !pFifo->pFifoBody) { + pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", + __func__); + return -1; + } + + fifo = (struct kfifo *)pFifo->pFifoBody; + + if (fifo) + ret = kfifo_avail(fifo); + + return ret; +} + +/*returns used bytes in fifo*/ +int _osal_fifo_len(OSAL_FIFO *pFifo) +{ + struct kfifo *fifo = NULL; + int ret = 0; + + if (!pFifo || !pFifo->pFifoBody) { + pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", + __func__); + return -1; + } + + fifo = (struct kfifo *)pFifo->pFifoBody; + + if (fifo) + ret = kfifo_len(fifo); + + return ret; +} + +int _osal_fifo_is_empty(OSAL_FIFO *pFifo) +{ + struct kfifo *fifo = NULL; + int ret = 0; + + if (!pFifo || !pFifo->pFifoBody) { + pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", + __func__); + return -1; + } + + fifo = (struct kfifo *)pFifo->pFifoBody; + + if (fifo) + ret = kfifo_is_empty(fifo); + + return ret; +} + +int _osal_fifo_is_full(OSAL_FIFO *pFifo) +{ + struct kfifo *fifo = NULL; + int ret = 0; + + if (!pFifo || !pFifo->pFifoBody) { + pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", + __func__); + return -1; + } + + fifo = (struct kfifo *)pFifo->pFifoBody; + + if (fifo) + ret = kfifo_is_full(fifo); + + return ret; +} + +int _osal_fifo_data_in(OSAL_FIFO *pFifo, const void *buf, unsigned int len) +{ + struct kfifo *fifo = NULL; + int ret = 0; + + if (!pFifo || !pFifo->pFifoBody) { + pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", + __func__); + return -1; + } + + fifo = (struct kfifo *)pFifo->pFifoBody; + + if (fifo && buf && (len <= _osal_fifo_avail_size(pFifo))) { + ret = kfifo_in(fifo, buf, len); + } else { + pr_err("%s: kfifo_in, error, len = %d, _osal_fifo_avail_size = %d, buf=%p\n", + __func__, len, _osal_fifo_avail_size(pFifo), buf); + + ret = 0; + } + + return ret; +} + +int _osal_fifo_data_out(OSAL_FIFO *pFifo, void *buf, unsigned int len) +{ + struct kfifo *fifo = NULL; + int ret = 0; + + if (!pFifo || !pFifo->pFifoBody) { + pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n" + , __func__); + return -1; + } + + fifo = (struct kfifo *)pFifo->pFifoBody; + + if (fifo && buf && (len <= _osal_fifo_len(pFifo))) { + ret = kfifo_out(fifo, buf, len); + } else { + pr_err("%s: kfifo_out, error, len = %d, osal_fifo_len = %d, buf=%p\n", + __func__, len, _osal_fifo_len(pFifo), buf); + + ret = 0; + } + + return ret; +} + +int _osal_fifo_reset(OSAL_FIFO *pFifo) +{ + struct kfifo *fifo = NULL; + + if (!pFifo || !pFifo->pFifoBody) { + pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", + __func__); + return -1; + } + + fifo = (struct kfifo *)pFifo->pFifoBody; + + if (fifo) + kfifo_reset(fifo); + + return 0; +} + +int osal_fifo_init(P_OSAL_FIFO pFifo, unsigned char *buffer, unsigned int size) +{ + if (!pFifo) { + pr_err("%s:pFifo = NULL, error\n", __func__); + return -1; + } + + pFifo->FifoInit = _osal_fifo_init; + pFifo->FifoDeInit = _osal_fifo_deinit; + pFifo->FifoSz = _osal_fifo_size; + pFifo->FifoAvailSz = _osal_fifo_avail_size; + pFifo->FifoLen = _osal_fifo_len; + pFifo->FifoIsEmpty = _osal_fifo_is_empty; + pFifo->FifoIsFull = _osal_fifo_is_full; + pFifo->FifoDataIn = _osal_fifo_data_in; + pFifo->FifoDataOut = _osal_fifo_data_out; + pFifo->FifoReset = _osal_fifo_reset; + + if (pFifo->pFifoBody != NULL) { + pr_err("%s:Because pFifo room is avialable, we clear the room and allocate them again.\n", __func__); + pFifo->FifoDeInit(pFifo->pFifoBody); + pFifo->pFifoBody = NULL; + } + + pFifo->FifoInit(pFifo, buffer, size); + + return 0; +} + +void osal_fifo_deinit(P_OSAL_FIFO pFifo) +{ + if (pFifo) + pFifo->FifoDeInit(pFifo); + else { + pr_err("%s:pFifo = NULL, error\n", __func__); + return; + } + kfree(pFifo->pFifoBody); +} + +int osal_fifo_reset(P_OSAL_FIFO pFifo) +{ + int ret = -1; + + if (pFifo) { + ret = pFifo->FifoReset(pFifo); + } else { + pr_err("%s:pFifo = NULL, error\n", __func__); + ret = -1; + } + return ret; +} + +unsigned int osal_fifo_in(P_OSAL_FIFO pFifo, + unsigned char *buffer, unsigned int size) +{ + unsigned int ret = 0; + + if (pFifo) { + ret = pFifo->FifoDataIn(pFifo, buffer, size); + } else { + pr_err("%s:pFifo = NULL, error\n", __func__); + ret = 0; + } + + return ret; +} + +unsigned int osal_fifo_out(P_OSAL_FIFO pFifo, + unsigned char *buffer, unsigned int size) +{ + unsigned int ret = 0; + + if (pFifo) { + ret = pFifo->FifoDataOut(pFifo, buffer, size); + } else { + pr_err("%s:pFifo = NULL, error\n", __func__); + ret = 0; + } + + return ret; +} + +unsigned int osal_fifo_len(P_OSAL_FIFO pFifo) +{ + unsigned int ret = 0; + + if (pFifo) { + ret = pFifo->FifoLen(pFifo); + } else { + pr_err("%s:pFifo = NULL, error\n", __func__); + ret = 0; + } + + return ret; +} + +unsigned int osal_fifo_sz(P_OSAL_FIFO pFifo) +{ + unsigned int ret = 0; + + if (pFifo) { + ret = pFifo->FifoSz(pFifo); + } else { + pr_err("%s:pFifo = NULL, error\n", __func__); + ret = 0; + } + + return ret; +} + +unsigned int osal_fifo_avail(P_OSAL_FIFO pFifo) +{ + unsigned int ret = 0; + + if (pFifo) { + ret = pFifo->FifoAvailSz(pFifo); + } else { + pr_err("%s:pFifo = NULL, error\n", __func__); + ret = 0; + } + + return ret; +} + +unsigned int osal_fifo_is_empty(P_OSAL_FIFO pFifo) +{ + unsigned int ret = 0; + + if (pFifo) { + ret = pFifo->FifoIsEmpty(pFifo); + } else { + pr_err("%s:pFifo = NULL, error\n", __func__); + ret = 0; + } + + return ret; +} + +unsigned int osal_fifo_is_full(P_OSAL_FIFO pFifo) +{ + unsigned int ret = 0; + + if (pFifo) { + ret = pFifo->FifoIsFull(pFifo); + } else { + pr_err("%s:pFifo = NULL, error\n", __func__); + ret = 0; + } + return ret; +} + +/* + * sleepable lock operations APIs + * init + * lock + * unlock + * destroy + * + */ +#if !defined(CONFIG_PROVE_LOCKING) +int osal_unsleepable_lock_init(P_OSAL_UNSLEEPABLE_LOCK pUSL) +{ + spin_lock_init(&(pUSL->lock)); + return 0; +} +#endif + +int osal_lock_unsleepable_lock(P_OSAL_UNSLEEPABLE_LOCK pUSL) +{ + spin_lock_irqsave(&(pUSL->lock), pUSL->flag); + return 0; +} + +int osal_unlock_unsleepable_lock(P_OSAL_UNSLEEPABLE_LOCK pUSL) +{ + spin_unlock_irqrestore(&(pUSL->lock), pUSL->flag); + return 0; +} + +int osal_unsleepable_lock_deinit(P_OSAL_UNSLEEPABLE_LOCK pUSL) +{ + return 0; +} + +/* + * unsleepable operations APIs + * init + * lock + * unlock + * destroy + * + */ + +#if !defined(CONFIG_PROVE_LOCKING) +int osal_sleepable_lock_init(P_OSAL_SLEEPABLE_LOCK pSL) +{ + mutex_init(&pSL->lock); + return 0; +} +#endif + +int osal_lock_sleepable_lock(P_OSAL_SLEEPABLE_LOCK pSL) +{ + return mutex_lock_killable(&pSL->lock); +} + +int osal_unlock_sleepable_lock(P_OSAL_SLEEPABLE_LOCK pSL) +{ + mutex_unlock(&pSL->lock); + return 0; +} + +int osal_trylock_sleepable_lock(P_OSAL_SLEEPABLE_LOCK pSL) +{ + return mutex_trylock(&pSL->lock); +} + +int osal_sleepable_lock_deinit(P_OSAL_SLEEPABLE_LOCK pSL) +{ + mutex_destroy(&pSL->lock); + return 0; +} + +int osal_sleep_ms(unsigned int ms) +{ + msleep(ms); + return 0; +} + +int osal_udelay(unsigned int us) +{ + udelay(us); + return 0; +} + +int osal_usleep_range(unsigned long min, unsigned long max) +{ + usleep_range(min, max); + return 0; +} + +int osal_gettimeofday(int *sec, int *usec) +{ + int ret = 0; + struct timeval now; + + do_gettimeofday(&now); + + if (sec != NULL) + *sec = now.tv_sec; + else + ret = -1; + + if (usec != NULL) + *usec = now.tv_usec; + else + ret = -1; + + return ret; +} + +void osal_get_local_time(unsigned long long *sec, unsigned long *nsec) +{ + if (sec != NULL && nsec != NULL) { + *sec = local_clock(); + *nsec = do_div(*sec, 1000000000)/1000; + } else + pr_err("The input parameters error when get local time\n"); +} + +unsigned long long osal_elapsed_us(unsigned long long ts, unsigned long usec) +{ + unsigned long long current_ts = 0; + unsigned long current_usec = 0; + + osal_get_local_time(¤t_ts, ¤t_usec); + return (current_ts*1000000 + current_usec) - (ts*1000000 + usec); +} + +void osal_buffer_dump(const unsigned char *buf, + const unsigned char *title, const unsigned int len, + const unsigned int limit) +{ + int k; + unsigned int dump_len; + char str[DBG_LOG_STR_SIZE] = {""}; + int strlen = 0; + + pr_info("[%s] len=%d, limit=%d, start dump\n", title, len, limit); + + dump_len = ((limit != 0) && (len > limit)) ? limit : len; + for (k = 0; k < dump_len; k++) { + if ((k+1) % 16 != 0) { + strlen += osal_snprintf(str + strlen, DBG_LOG_STR_SIZE - strlen, + "%02x ", buf[k]); + } else { + strlen += osal_snprintf(str + strlen, DBG_LOG_STR_SIZE - strlen, + "%02x ", buf[k]); + + pr_info("%s", str); + strlen = 0; + } + } + if (k % 16 != 0) + pr_info("%s\n", str); + + pr_info("end of dump\n"); +} + +void osal_buffer_dump_data(const unsigned int *buf, + const unsigned char *title, const unsigned int len, + const unsigned int limit, + const int flag) +{ + int k; + unsigned int dump_len; + char str[DBG_LOG_STR_SIZE] = {""}; + int strlen = 0; + + dump_len = ((limit != 0) && (len > limit)) ? limit : len; + for (k = 0; k < dump_len; k++) { + if (((k+1) % 8 != 0) && (k < (dump_len - 1))) { + strlen += osal_snprintf(str + strlen, DBG_LOG_STR_SIZE - strlen, + "0x%08x,", buf[k]); + } else { + strlen += osal_snprintf(str + strlen, DBG_LOG_STR_SIZE - strlen, + "0x%08x,", buf[k]); + if (flag) + osal_ftrace_print("%s%s", title, str); + else + pr_info("%s%s", title, str); + strlen = 0; + } + } + if (k % 8 != 0) { + if (flag) + osal_ftrace_print("%s%s", title, str); + else + pr_info("%s%s", title, str); + } +} + +unsigned int osal_op_get_id(P_OSAL_OP pOp) +{ + return (pOp) ? pOp->op.opId : 0xFFFFFFFF; +} + +MTK_CONN_BOOL osal_op_is_wait_for_signal(P_OSAL_OP pOp) +{ + return (pOp && pOp->signal.timeoutValue) + ? MTK_CONN_BOOL_TRUE : MTK_CONN_BOOL_FALSE; +} + +void osal_op_raise_signal(P_OSAL_OP pOp, int result) +{ + if (pOp) { + pOp->result = result; + osal_raise_signal(&pOp->signal); + } +} + +int osal_ftrace_print(const char *str, ...) +{ +#ifdef CONFIG_TRACING + va_list args; + char tempString[DBG_LOG_STR_SIZE]; + + if (ftrace_flag) { + va_start(args, str); + vsnprintf(tempString, DBG_LOG_STR_SIZE, str, args); + va_end(args); + + trace_printk("%s\n", tempString); + } +#endif + return 0; +} + +int osal_ftrace_print_ctrl(int flag) +{ +#ifdef CONFIG_TRACING + if (flag) + ftrace_flag = 1; + else + ftrace_flag = 0; +#endif + return 0; +} + +void osal_set_op_result(P_OSAL_OP pOp, int result) +{ + if (pOp) + pOp->result = result; + +} + +MTK_CONN_BOOL osal_opq_has_op(P_OSAL_OP_Q pOpQ, P_OSAL_OP pOp) +{ + unsigned int rd; + unsigned int wt; + P_OSAL_OP op; + + rd = pOpQ->read; + wt = pOpQ->write; + + while (rd != wt) { + op = pOpQ->queue[rd & RB_MASK(pOpQ)]; + if (op == pOp) + return MTK_CONN_BOOL_TRUE; + rd++; + } + return MTK_CONN_BOOL_FALSE; +} + +static void osal_op_history_print_work(struct work_struct *work) +{ + struct osal_op_history *log_history + = container_of(work, struct osal_op_history, dump_work); + struct ring *ring_buffer = &log_history->dump_ring_buffer; + struct ring_segment seg; + struct osal_op_history_entry *queue = ring_buffer->base; + struct osal_op_history_entry *entry; + int index = 0; + + if (queue == NULL) { + pr_info("queue shouldn't be NULL, %s", log_history->name); + return; + } + + RING_READ_FOR_EACH_ITEM(RING_SIZE(ring_buffer), seg, ring_buffer) { + index = seg.ring_pt - ring_buffer->base; + entry = &queue[index]; + pr_info("(%llu.%06lu) %s: pOp(%p):%u(%d)-%x-%zx,%zx,%zx,%zx\n", + entry->ts, + entry->usec, + log_history->name, + entry->opbuf_address, + entry->op_id, + entry->opbuf_ref_count, + entry->op_info_bit, + entry->param_0, + entry->param_1, + entry->param_2, + entry->param_3); + } + kfree(queue); + ring_buffer->base = NULL; +} + +void osal_op_history_init(struct osal_op_history *log_history, int queue_size) +{ + int size = queue_size * sizeof(struct osal_op_history_entry); + + spin_lock_init(&(log_history->lock)); + + log_history->queue = kzalloc(size, GFP_ATOMIC); + if (log_history->queue == NULL) + return; + + /* queue_size must be power of 2 */ + ring_init( + &log_history->queue, + queue_size, + 0, + 0, + &log_history->ring_buffer); + + INIT_WORK(&log_history->dump_work, osal_op_history_print_work); +} + +void osal_op_history_print(struct osal_op_history *log_history, char *name) +{ + struct osal_op_history_entry *queue; + struct ring *ring_buffer, *dump_ring_buffer; + int queue_size; + unsigned long flags; + struct work_struct *work = &log_history->dump_work; + spinlock_t *lock = &(log_history->lock); + + if (log_history->queue == NULL) { + pr_info("Queue is NULL, name: %s\n", name); + return; + } + + ring_buffer = &log_history->ring_buffer; + queue_size = sizeof(struct osal_op_history_entry) + * RING_SIZE(ring_buffer); + + /* Allocate memory before getting lock to save time of holding lock */ + queue = kmalloc(queue_size, GFP_KERNEL); + if (queue == NULL) + return; + + dump_ring_buffer = &log_history->dump_ring_buffer; + + spin_lock_irqsave(lock, flags); + if (dump_ring_buffer->base != NULL) { + spin_unlock_irqrestore(lock, flags); + kfree(queue); + pr_info("print is ongoing: %s\n", name); + return; + } + + osal_snprintf(log_history->name, sizeof(log_history->name), "%s", name); + osal_memcpy(queue, log_history->queue, queue_size); + osal_memcpy(dump_ring_buffer, ring_buffer, sizeof(struct ring)); + /* assign value to base after memory copy */ + dump_ring_buffer->base = queue; + spin_unlock_irqrestore(lock, flags); + schedule_work(work); +} + +void osal_op_history_save(struct osal_op_history *log_history, P_OSAL_OP pOp) +{ + struct osal_op_history_entry *entry = NULL; + struct ring_segment seg; + int index; + unsigned long long sec = 0; + unsigned long usec = 0; + unsigned long flags; + + if (log_history->queue == NULL) + return; + + osal_get_local_time(&sec, &usec); + + spin_lock_irqsave(&(log_history->lock), flags); + RING_OVERWRITE_FOR_EACH(1, seg, &log_history->ring_buffer) { + index = seg.ring_pt - log_history->ring_buffer.base; + entry = &log_history->queue[index]; + } + + if (entry == NULL) { + pr_info("Entry is null, size %d\n", + RING_SIZE(&log_history->ring_buffer)); + spin_unlock_irqrestore(&(log_history->lock), flags); + return; + } + + entry->opbuf_address = pOp; + entry->op_id = pOp->op.opId; + entry->opbuf_ref_count = atomic_read(&pOp->ref_count); + entry->op_info_bit = pOp->op.u4InfoBit; + entry->param_0 = pOp->op.au4OpData[0]; + entry->param_1 = pOp->op.au4OpData[1]; + entry->param_2 = pOp->op.au4OpData[2]; + entry->param_3 = pOp->op.au4OpData[3]; + entry->ts = sec; + entry->usec = usec; + spin_unlock_irqrestore(&(log_history->lock), flags); +} + +static inline void osal_systrace_prepare(void) +{ + if (unlikely(mark_addr == 0)) + mark_addr = kallsyms_lookup_name("tracing_mark_write"); + if (unlikely(g_pid == 0)) + g_pid = task_pid_nr(current); +} + +static void osal_systrace_b(const char *log) +{ + osal_systrace_prepare(); + preempt_disable(); + KERNEL_event_trace_printk(mark_addr, "B|%d|%s\n", g_pid, log); + preempt_enable(); +} + + +static void osal_systrace_e(void) +{ + preempt_disable(); + KERNEL_event_trace_printk(mark_addr, "E\n"); + preempt_enable(); +} + +static void osal_systrace_c(int val, const char *log) +{ + osal_systrace_prepare(); + preempt_disable(); + KERNEL_event_trace_printk(mark_addr, "C|%d|%s|%d\n", g_pid, log, val); + preempt_enable(); +} + +void osal_systrace_major_b(const char *fmt, ...) +{ + char log[DBG_LOG_STR_SIZE]; + va_list args; + + memset(log, ' ', sizeof(log)); + va_start(args, fmt); + if (vsnprintf(log, sizeof(log), fmt, args) < 0) + pr_err("[%s:%d] vsnprintf error", __func__, __LINE__); + va_end(args); + osal_systrace_b(log); +} + +void osal_systrace_major_e(void) +{ + osal_systrace_e(); +} + +void osal_systrace_minor_b(const char *fmt, ...) +{ + char log[DBG_LOG_STR_SIZE]; + va_list args; + + if (!ftrace_flag) + return; + + memset(log, ' ', sizeof(log)); + va_start(args, fmt); + if (vsnprintf(log, sizeof(log), fmt, args) < 0) + pr_err("[%s:%d] vsnprintf error", __func__, __LINE__); + va_end(args); + osal_systrace_b(log); + +} + +void osal_systrace_minor_e(void) +{ + if (!ftrace_flag) + return; + osal_systrace_e(); +} + +void osal_systrace_minor_c(int val, const char *fmt, ...) +{ + char log[DBG_LOG_STR_SIZE]; + va_list args; + + if (!ftrace_flag) + return; + + memset(log, ' ', sizeof(log)); + va_start(args, fmt); + if (vsnprintf(log, sizeof(log), fmt, args) < 0) + pr_err("[%s:%d] vsnprintf error", __func__, __LINE__); + va_end(args); + osal_systrace_c(val, log); +} + diff --git a/drivers/misc/mediatek/connectivity/conninfra/base/ring.c b/drivers/misc/mediatek/connectivity/conninfra/base/ring.c new file mode 100755 index 0000000000000000000000000000000000000000..e563760afecae6cc9bab7c5e8ef523a10df64e71 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/base/ring.c @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#include "ring.h" +#include +#include +#include + + + +void ring_init(void *base, unsigned int max_size, unsigned int read, + unsigned int write, struct ring *ring) +{ + WARN_ON(!base); + + /* making sure max_size is power of 2 */ + WARN_ON(!max_size || (max_size & (max_size - 1))); + + /* making sure write largger than read */ + WARN_ON(read > write); + + ring->base = base; + ring->read = read; + ring->write = write; + ring->max_size = max_size; +} + +void ring_dump(const char *title, struct ring *ring) +{ + pr_info("[%s] ring:{write=%d, read=%d, max_size=%d}\n", + title, ring->write, ring->read, ring->max_size); +} + +void ring_dump_segment(const char *title, struct ring_segment *seg) +{ + pr_info("[%s] seg:{ring_pt=0x%p, data_pos=%d, sz=%d, remain=%d}\n", + title, seg->ring_pt, seg->data_pos, + seg->sz, seg->remain); +} + +/* + * Function prepares the ring_segment and + * returns the number of valid bytes for read. + */ +unsigned int ring_read_prepare(unsigned int sz, + struct ring_segment *seg, + struct ring *ring) +{ + unsigned int wt = ring->write; + unsigned int rd = ring->read; + + memset(seg, 0, sizeof(struct ring_segment)); + if (sz > wt - rd) + sz = wt - rd; + seg->remain = sz; + /* ring_dump(__func__, ring); */ + /* ring_dump_segment(__func__, seg); */ + return seg->remain; +} + +/* + * Function prepares the ring_segment and + * returns the number of bytes available for write. + */ +unsigned int ring_write_prepare(unsigned int sz, + struct ring_segment *seg, + struct ring *ring) +{ + unsigned int wt = ring->write; + unsigned int rd = ring->read; + + memset(seg, 0, sizeof(struct ring_segment)); + if (sz > ring->max_size - (wt - rd)) + sz = ring->max_size - (wt - rd); + seg->remain = sz; + /* ring_dump(__func__, ring); */ + /* ring_dump_segment(__func__, seg); */ + return seg->remain; +} + +unsigned int ring_overwrite_prepare(unsigned int sz, struct ring_segment *seg, + struct ring *ring) +{ + unsigned int wt = ring->write; + unsigned int rd = ring->read; + + memset(seg, 0, sizeof(struct ring_segment)); + if (sz > ring->max_size - (wt - rd)) + ring->read += sz - (ring->max_size - (wt - rd)); + seg->remain = sz; + /* ring_dump(__func__, ring); */ + /* ring_dump_segment(__func__, seg); */ + return seg->remain; +} + +void __ring_segment_prepare(unsigned int from, unsigned int sz, + struct ring_segment *seg, + struct ring *ring) +{ + unsigned int ring_pos = from & (ring->max_size - 1); + + seg->ring_pt = ring->base + ring_pos; + seg->data_pos = (seg->sz ? seg->data_pos + seg->sz : 0); + if (ring_pos + sz <= ring->max_size) + seg->sz = sz; + else + seg->sz = ring->max_size - ring_pos; + seg->remain -= seg->sz; + /* ring_dump(__func__, ring); */ + /* ring_dump_segment(__func__, seg); */ +} + +void _ring_segment_prepare(unsigned int from, + struct ring_segment *seg, + struct ring *ring) +{ + __ring_segment_prepare(from, seg->remain, seg, ring); +} + +void _ring_segment_prepare_item(unsigned int from, + struct ring_segment *seg, + struct ring *ring) +{ + unsigned int size; + + size = (seg->remain ? 1 : 0); + __ring_segment_prepare(from, size, seg, ring); +} + +void _ring_read_commit(struct ring_segment *seg, struct ring *ring) +{ + ring->read += seg->sz; + /* ring_dump(__func__, ring); */ + /* ring_dump_segment(__func__, seg); */ +} +void _ring_write_commit(struct ring_segment *seg, struct ring *ring) +{ + ring->write += seg->sz; + /* ring_dump(__func__, ring); */ + /* ring_dump_segment(__func__, seg); */ +} + diff --git a/drivers/misc/mediatek/connectivity/conninfra/conf/conninfra_conf.c b/drivers/misc/mediatek/connectivity/conninfra/conf/conninfra_conf.c new file mode 100755 index 0000000000000000000000000000000000000000..d330cb54fe8a3bd5cc6eb4ed25e26dcd21da8bb0 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/conf/conninfra_conf.c @@ -0,0 +1,635 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME "@(%s:%d) " fmt, __func__, __LINE__ + +#include +#include "conninfra_conf.h" + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ +struct parse_data { + char *name; + int (*parser)(const struct parse_data *data, const char *value); + char *(*writer)(const struct parse_data *data); + void (*relase_mem)(const struct parse_data *data); + /*PCHAR param1, *param2, *param3; */ + /* TODO:[FixMe][George] CLARIFY WHAT SHOULD BE USED HERE!!! */ + char *param1; + char *param2; + char *param3; +}; + + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +struct conninfra_conf g_conninfra_conf; + +/****************************************************************************** +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************* +*/ +static int conf_parse_char(const struct parse_data *data, const char *pos); + +static char *conf_write_char(const struct parse_data *data); + +static int conf_parse_short(const struct parse_data *data, const char *pos); + +static char *conf_write_short(const struct parse_data *data); + +static int conf_parse_int(const struct parse_data *data, const char *pos); + +static char *conf_write_int(const struct parse_data *data); + +static int conf_parse_byte_array(const struct parse_data *data, + const char *pos); + +static char *conf_write_byte_array(const struct parse_data *data); + +static void conf_release_byte_array(const struct parse_data *data); + +static int conf_parse_pair(const char *key, const char *pVal); + +static int conf_parse(const char *pInBuf, unsigned int size); + +//#define OFFSET(v) ((void *) &((struct conninfra_conf*) 0)->v) + +#define CHAR(f) {#f, conf_parse_char, conf_write_char, NULL, (char *)&g_conninfra_conf.f, NULL, NULL} + +#define SHORT(f) {#f, conf_parse_short, conf_write_short, NULL, (char *)&g_conninfra_conf.f, NULL, NULL} + +#define INT(f) {#f, conf_parse_int, conf_write_int, NULL, (char *)&g_conninfra_conf.f, NULL, NULL} + +#define BYTE_ARRAY(f) {#f, conf_parse_byte_array, conf_write_byte_array, conf_release_byte_array,\ + (char *)&g_conninfra_conf.f, NULL, NULL} + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +static const struct parse_data cfg_fields[] = { + CHAR(coex_wmt_ant_mode), + CHAR(coex_wmt_ant_mode_ex), + CHAR(coex_wmt_ext_component), + CHAR(coex_wmt_wifi_time_ctl), + CHAR(coex_wmt_ext_pta_dev_on), + CHAR(coex_wmt_filter_mode), + + CHAR(coex_bt_rssi_upper_limit), + CHAR(coex_bt_rssi_mid_limit), + CHAR(coex_bt_rssi_lower_limit), + CHAR(coex_bt_pwr_high), + CHAR(coex_bt_pwr_mid), + CHAR(coex_bt_pwr_low), + + CHAR(coex_wifi_rssi_upper_limit), + CHAR(coex_wifi_rssi_mid_limit), + CHAR(coex_wifi_rssi_lower_limit), + CHAR(coex_wifi_pwr_high), + CHAR(coex_wifi_pwr_mid), + CHAR(coex_wifi_pwr_low), + + CHAR(coex_ext_pta_hi_tx_tag), + CHAR(coex_ext_pta_hi_rx_tag), + CHAR(coex_ext_pta_lo_tx_tag), + CHAR(coex_ext_pta_lo_rx_tag), + SHORT(coex_ext_pta_sample_t1), + SHORT(coex_ext_pta_sample_t2), + CHAR(coex_ext_pta_wifi_bt_con_trx), + + INT(coex_misc_ext_pta_on), + INT(coex_misc_ext_feature_set), + + CHAR(wmt_gps_lna_pin), + CHAR(wmt_gps_lna_enable), + + CHAR(pwr_on_rtc_slot), + CHAR(pwr_on_ldo_slot), + CHAR(pwr_on_rst_slot), + CHAR(pwr_on_off_slot), + CHAR(pwr_on_on_slot), + CHAR(co_clock_flag), + + CHAR(disable_deep_sleep_cfg), + + INT(sdio_driving_cfg), + + SHORT(coex_wmt_wifi_path), + + CHAR(coex_wmt_ext_elna_gain_p1_support), + INT(coex_wmt_ext_elna_gain_p1_D0), + INT(coex_wmt_ext_elna_gain_p1_D1), + INT(coex_wmt_ext_elna_gain_p1_D2), + INT(coex_wmt_ext_elna_gain_p1_D3), + + BYTE_ARRAY(coex_wmt_epa_elna), + + CHAR(bt_tssi_from_wifi), + SHORT(bt_tssi_target), + + CHAR(coex_config_bt_ctrl), + CHAR(coex_config_bt_ctrl_mode), + CHAR(coex_config_bt_ctrl_rw), + + CHAR(coex_config_addjust_opp_time_ratio), + CHAR(coex_config_addjust_opp_time_ratio_bt_slot), + CHAR(coex_config_addjust_opp_time_ratio_wifi_slot), + + CHAR(coex_config_addjust_ble_scan_time_ratio), + CHAR(coex_config_addjust_ble_scan_time_ratio_bt_slot), + CHAR(coex_config_addjust_ble_scan_time_ratio_wifi_slot), + CHAR(tcxo_gpio), + CHAR(pre_cal_mode), +}; + +#define NUM_CFG_FIELDS (osal_sizeof(cfg_fields) / osal_sizeof(cfg_fields[0])) + +static int conf_parse_char(const struct parse_data *data, const char *pos) +{ + char *dst; + long res = 0; + + dst = (char *)(data->param1); + + if ((osal_strlen(pos) > 2) && ((*pos) == '0') && (*(pos + 1) == 'x')) { + osal_strtol(pos + 2, 16, &res); + *dst = (char)res; + pr_debug("cfg==> %s=0x%x\n", data->name, *dst); + } else { + osal_strtol(pos, 10, &res); + *dst = (char)res; + pr_debug("cfg==> %s=%d\n", data->name, *dst); + } + return 0; +} + +static char *conf_write_char(const struct parse_data *data) +{ + char *src; + int res; + char *value; + + src = data->param1; + + value = osal_malloc(20); + if (value == NULL) + return NULL; + res = osal_snprintf(value, 20, "0x%x", *src); + if (res < 0 || res >= 20) { + osal_free(value); + return NULL; + } + value[20 - 1] = '\0'; + return value; +} + +static int conf_parse_short(const struct parse_data *data, const char *pos) +{ + unsigned short *dst; + long res = 0; + + dst = (unsigned short *)data->param1; + + if ((osal_strlen(pos) > 2) && ((*pos) == '0') && (*(pos + 1) == 'x')) { + osal_strtol(pos + 2, 16, &res); + *dst = (unsigned short)res; + pr_debug("cfg==> %s=0x%x\n", data->name, *dst); + } else { + osal_strtol(pos, 10, &res); + *dst = (unsigned short)res; + pr_debug("cfg==> %s=%d\n", data->name, *dst); + } + + return 0; +} + +static char *conf_write_short(const struct parse_data *data) +{ + short *src; + int res; + char *value; + + /* TODO: [FixMe][George] FIX COMPILE WARNING HERE! */ + src = (short *)data->param1; + + value = osal_malloc(20); + if (value == NULL) + return NULL; + res = osal_snprintf(value, 20, "0x%x", *src); + if (res < 0 || res >= 20) { + osal_free(value); + return NULL; + } + value[20 - 1] = '\0'; + return value; +} + +static int conf_parse_int(const struct parse_data *data, const char *pos) +{ + int *dst; + long res = 0; + + dst = (int *)data->param1; + + if ((osal_strlen(pos) > 2) && ((*pos) == '0') && (*(pos + 1) == 'x')) { + osal_strtol(pos + 2, 16, &res); + *dst = (unsigned int)res; + pr_debug("cfg==> %s=0x%x\n", data->name, *dst); + } else { + osal_strtol(pos, 10, &res); + *dst = (unsigned int)res; + pr_debug("cfg==> %s=%d\n", data->name, *dst); + } + + return 0; +} + +static char *conf_write_int(const struct parse_data *data) +{ + int *src; + int res; + char *value; + + src = (unsigned int *) data->param1; + + value = osal_malloc(20); + if (value == NULL) + return NULL; + res = osal_snprintf(value, 20, "0x%x", *src); + if (res < 0 || res >= 20) { + osal_free(value); + return NULL; + } + value[20 - 1] = '\0'; + return value; +} + +static int conf_parse_byte_array(const struct parse_data *data, + const char *pos) +{ + unsigned char **dst; + struct conf_byte_ary *ba; + unsigned char *buffer; + int size = osal_strlen(pos) / 2; + unsigned char temp[3]; + int i; + long value; + + if (size <= 1) { + pr_err("cfg==> %s has no value assigned\n", + data->name); + return -1; + } else if (size & 0x1) { + pr_debug("cfg==> %s, length should be even\n", data->name); + return -1; + } + + ba = (struct conf_byte_ary *)osal_malloc(sizeof(struct conf_byte_ary)); + if (ba == NULL) { + pr_err("cfg==> %s malloc fail\n", data->name); + return -1; + } + + buffer = osal_malloc(size); + if (buffer == NULL) { + osal_free(ba); + pr_err("cfg==> %s malloc fail, size %d\n", data->name, size); + return -1; + } + + temp[2] = '\0'; + for (i = 0; i < size; i++) { + osal_memcpy(temp, &pos[i * 2], 2); + if (osal_strtol(temp, 16, &value) < 0) { + pr_err("cfg==> %s should be hexadecimal format\n", + data->name); + osal_free(ba); + osal_free(buffer); + return -1; + } + buffer[i] = (char)value; + } + ba->data = buffer; + ba->size = size; + + dst = (unsigned char **) data->param1; + *dst = (unsigned char *)ba; + + return 0; +} + +static char *conf_write_byte_array(const struct parse_data *data) +{ + unsigned char **src; + char *value; + struct conf_byte_ary *ba; + int i; + + src = (unsigned char **) data->param1; + if (*src == NULL) + return NULL; + + ba = (struct conf_byte_ary *)*src; + + value = osal_malloc(ba->size * 2 + 1); + if (value == NULL) + return NULL; + + for (i = 0; i < ba->size; i++) + osal_snprintf(&value[i * 2], 3, "%x", ba->data[i]); + + return value; +} + + +static void conf_release_byte_array(const struct parse_data *data) +{ + //unsigned char *buffer; + struct conf_byte_ary *ba; + unsigned char **src; + + if (data->param1 != NULL) { + src = (unsigned char **) data->param1; + ba = (struct conf_byte_ary *) *src; + if (ba->data != NULL) { + osal_free(ba->data); + ba->data = NULL; + } + osal_free(ba); + //data->param1 = NULL; + *src = NULL; + } +} + +static int conf_parse_pair(const char *pKey, const char *pVal) +{ + int i = 0; + int ret = 0; + + + for (i = 0; i < NUM_CFG_FIELDS; i++) { + const struct parse_data *field = &cfg_fields[i]; + + if (osal_strcmp(pKey, field->name) != 0) + continue; + if (field->parser(field, pVal)) { + pr_err("failed to parse %s '%s'.\n", pKey, pVal); + ret = -1; + } + break; + } + if (i == NUM_CFG_FIELDS) { + pr_err("unknown field '%s'.\n", pKey); + ret = -1; + } + + return ret; +} + +static int conf_parse(const char *pInBuf, unsigned int size) +{ + char *pch; + char *pBuf; + char *pLine; + char *pKey; + char *pVal; + char *pPos; + int ret = 0; + int i = 0; + char *pa = NULL; + + pBuf = osal_malloc(size+1); + if (!pBuf) + return -1; + + osal_memcpy(pBuf, pInBuf, size); + pBuf[size] = '\0'; + + pch = pBuf; + /* pch is to be updated by strsep(). Keep pBuf unchanged!! */ + + while ((pLine = osal_strsep(&pch, "\r\n")) != NULL) { + /* pch is updated to the end of pLine by + * strsep() and updated to '\0' + */ + /* parse each line */ + + if (!*pLine) + continue; + + pVal = osal_strchr(pLine, '='); + if (!pVal) { + pr_warn("mal-format cfg string(%s)\n", pLine); + continue; + } + + /* |<-pLine->|'='<-pVal->|'\n' ('\0')| */ + *pVal = '\0'; /* replace '=' with '\0' to get key */ + /* |<-pKey->|'\0'|<-pVal->|'\n' ('\0')| */ + pKey = pLine; + + if ((pVal - pBuf) < size) + pVal++; + + /*key handling */ + pPos = pKey; + /*skip space characeter */ + while (((*pPos) == ' ') || + ((*pPos) == '\t') || ((*pPos) == '\n')) { + if ((pPos - pBuf) >= size) + break; + pPos++; + } + /*key head */ + pKey = pPos; + while (((*pPos) != ' ') && + ((*pPos) != '\t') && ((*pPos) != '\0') + && ((*pPos) != '\n')) { + if ((pPos - pBuf) >= size) + break; + pPos++; + } + /*key tail */ + (*pPos) = '\0'; + + /*value handling */ + pPos = pVal; + /*skip space characeter */ + while (((*pPos) == ' ') || + ((*pPos) == '\t') || ((*pPos) == '\n')) { + if ((pPos - pBuf) >= size) + break; + pPos++; + } + /*value head */ + pVal = pPos; + while (((*pPos) != ' ') && + ((*pPos) != '\t') && ((*pPos) != '\0') + && ((*pPos) != '\n')) { + if ((pPos - pBuf) >= size) + break; + pPos++; + } + /*value tail */ + (*pPos) = '\0'; + + ret = conf_parse_pair(pKey, pVal); + pr_debug("parse (%s, %s, %d)\n", pKey, pVal, ret); + if (ret) + pr_debug("parse fail (%s, %s, %d)\n", pKey, pVal, ret); + } + + for (i = 0; i < NUM_CFG_FIELDS; i++) { + const struct parse_data *field = &cfg_fields[i]; + + pa = field->writer(field); + if (pa) { + pr_debug("#%d(%s)=>%s\n", i, field->name, pa); + osal_free(pa); + } else + pr_err("failed to parse '%s'.\n", field->name); + } + osal_free(pBuf); + return 0; +} + +static int platform_request_firmware(char *patch_name, osal_firmware **ppPatch) +{ + int ret; + osal_firmware *fw = NULL; + + if (!ppPatch) { + pr_err("invalid ppBufptr!\n"); + return -1; + } + + *ppPatch = NULL; + do { + ret = request_firmware((const struct firmware **)&fw, + patch_name, NULL); + if (ret == -EAGAIN) { + pr_err("failed to open or read!(%s), retry again!\n", + patch_name); + osal_sleep_ms(100); + } + } while (ret == -EAGAIN); + if (ret != 0) { + pr_err("failed to open or read!(%s)\n", patch_name); + release_firmware(fw); + return -1; + } + pr_debug("loader firmware %s ok!!\n", patch_name); + ret = 0; + *ppPatch = fw; + + return ret; +} + +static int platform_release_firmware(osal_firmware **ppPatch) +{ + if (*ppPatch != NULL) { + release_firmware((const struct firmware *)*ppPatch); + *ppPatch = NULL; + } + return 0; +} + +int conninfra_conf_init(void) +{ + int ret = -1; + const osal_firmware *conf_inst; + + osal_memset(&g_conninfra_conf, 0, osal_sizeof(struct conninfra_conf)); + osal_strcpy(&(g_conninfra_conf.conf_name[0]), "conninfra.cfg"); + + pr_debug("config file:%s\n", &(g_conninfra_conf.conf_name[0])); + if (0 == + platform_request_firmware(&g_conninfra_conf.conf_name[0], + (osal_firmware **) &conf_inst)) { + /*get full name patch success */ + pr_debug("get full file name(%s) buf(0x%p) size(%zu)\n", + &g_conninfra_conf.conf_name[0], conf_inst->data, + conf_inst->size); + if (0 == + conf_parse((const char *)conf_inst->data, + conf_inst->size)) { + /*config file exists */ + g_conninfra_conf.cfg_exist = 1; + ret = 0; + } else { + pr_err("conf parsing fail\n"); + ret = -1; + } + platform_release_firmware((osal_firmware **) &conf_inst); + return ret; + } + pr_err("read %s file fails\n", &(g_conninfra_conf.conf_name[0])); + g_conninfra_conf.cfg_exist = 0; + return ret; +} + +int conninfra_conf_set_cfg_file(const char *name) +{ + if (name == NULL) { + pr_err("name is NULL\n"); + return -1; + } + if (osal_strlen(name) >= osal_sizeof(g_conninfra_conf.conf_name)) { + pr_err("name is too long, length=%d, expect to < %zu\n", + osal_strlen(name), + osal_sizeof(g_conninfra_conf.conf_name)); + return -2; + } + osal_memset(&g_conninfra_conf.conf_name[0], 0, + osal_sizeof(g_conninfra_conf.conf_name)); + osal_strcpy(&(g_conninfra_conf.conf_name[0]), name); + pr_err("WMT config file is set to (%s)\n", + &(g_conninfra_conf.conf_name[0])); + + return 0; +} + +const struct conninfra_conf *conninfra_conf_get_cfg(void) +{ + if (g_conninfra_conf.cfg_exist == 0) + return NULL; + + return &g_conninfra_conf; +} + +int conninfra_conf_deinit(void) +{ + int i; + + if (g_conninfra_conf.cfg_exist == 0) + return -1; + + for (i = 0; i < NUM_CFG_FIELDS; i++) { + const struct parse_data *field = &cfg_fields[i]; + field->relase_mem(field); + } + g_conninfra_conf.cfg_exist = 0; + return 0; +} + diff --git a/drivers/misc/mediatek/connectivity/conninfra/conf/include/conninfra_conf.h b/drivers/misc/mediatek/connectivity/conninfra/conf/include/conninfra_conf.h new file mode 100755 index 0000000000000000000000000000000000000000..8aa9169dd117f1303d1e841c4920e40018b612d2 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/conf/include/conninfra_conf.h @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + + + +#ifndef _CONNINFRA_CONF_H_ +#define _CONNINFRA_CONF_H_ + +#include "osal.h" + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +#define CUST_CFG_INFRA "WMT.cfg" +#define CUST_CFG_INFRA_SOC "WMT_SOC.cfg" + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + + + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + + + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ +struct conf_byte_ary { + unsigned int size; + char *data; +}; + +struct conninfra_conf { + + char conf_name[NAME_MAX + 1]; + //const osal_firmware *conf_inst; + unsigned char cfg_exist; + + unsigned char coex_wmt_ant_mode; + unsigned char coex_wmt_ant_mode_ex; + unsigned char coex_wmt_ext_component; + unsigned char coex_wmt_wifi_time_ctl; + unsigned char coex_wmt_ext_pta_dev_on; + /*combo chip and LTE coex filter mode setting */ + unsigned char coex_wmt_filter_mode; + + unsigned char coex_bt_rssi_upper_limit; + unsigned char coex_bt_rssi_mid_limit; + unsigned char coex_bt_rssi_lower_limit; + unsigned char coex_bt_pwr_high; + unsigned char coex_bt_pwr_mid; + unsigned char coex_bt_pwr_low; + + unsigned char coex_wifi_rssi_upper_limit; + unsigned char coex_wifi_rssi_mid_limit; + unsigned char coex_wifi_rssi_lower_limit; + unsigned char coex_wifi_pwr_high; + unsigned char coex_wifi_pwr_mid; + unsigned char coex_wifi_pwr_low; + + unsigned char coex_ext_pta_hi_tx_tag; + unsigned char coex_ext_pta_hi_rx_tag; + unsigned char coex_ext_pta_lo_tx_tag; + unsigned char coex_ext_pta_lo_rx_tag; + unsigned short coex_ext_pta_sample_t1; + unsigned short coex_ext_pta_sample_t2; + unsigned char coex_ext_pta_wifi_bt_con_trx; + + unsigned int coex_misc_ext_pta_on; + unsigned int coex_misc_ext_feature_set; + /*GPS LNA setting */ + unsigned char wmt_gps_lna_pin; + unsigned char wmt_gps_lna_enable; + /*Power on sequence */ + unsigned char pwr_on_rtc_slot; + unsigned char pwr_on_ldo_slot; + unsigned char pwr_on_rst_slot; + unsigned char pwr_on_off_slot; + unsigned char pwr_on_on_slot; + unsigned char co_clock_flag; + + /*deep sleep feature flag*/ + unsigned char disable_deep_sleep_cfg; + + /* Combo chip side SDIO driving setting */ + unsigned int sdio_driving_cfg; + + /* Combo chip WiFi path setting */ + unsigned short coex_wmt_wifi_path; + /* Combo chip WiFi eLAN gain setting */ + unsigned char coex_wmt_ext_elna_gain_p1_support; + unsigned int coex_wmt_ext_elna_gain_p1_D0; + unsigned int coex_wmt_ext_elna_gain_p1_D1; + unsigned int coex_wmt_ext_elna_gain_p1_D2; + unsigned int coex_wmt_ext_elna_gain_p1_D3; + + struct conf_byte_ary *coex_wmt_epa_elna; + + unsigned char bt_tssi_from_wifi; + unsigned short bt_tssi_target; + + unsigned char coex_config_bt_ctrl; + unsigned char coex_config_bt_ctrl_mode; + unsigned char coex_config_bt_ctrl_rw; + + unsigned char coex_config_addjust_opp_time_ratio; + unsigned char coex_config_addjust_opp_time_ratio_bt_slot; + unsigned char coex_config_addjust_opp_time_ratio_wifi_slot; + + unsigned char coex_config_addjust_ble_scan_time_ratio; + unsigned char coex_config_addjust_ble_scan_time_ratio_bt_slot; + unsigned char coex_config_addjust_ble_scan_time_ratio_wifi_slot; + + /* POS. If set, means using ext TCXO */ + unsigned char tcxo_gpio; + + unsigned char pre_cal_mode; +}; + + + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + + + + + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +const struct conninfra_conf *conninfra_conf_get_cfg(void); +int conninfra_conf_set_cfg_file(const char *name); + +int conninfra_conf_init(void); +int conninfra_conf_deinit(void); + +#endif /* _CONNINFRA_CONF_H_ */ diff --git a/drivers/misc/mediatek/connectivity/conninfra/core/conninfra_core.c b/drivers/misc/mediatek/connectivity/conninfra/core/conninfra_core.c new file mode 100755 index 0000000000000000000000000000000000000000..b9c204f6acd79dba4dd5aaa8b35b67fd9608770a --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/core/conninfra_core.c @@ -0,0 +1,1806 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#define pr_fmt(fmt) KBUILD_MODNAME "@(%s:%d) " fmt, __func__, __LINE__ + +#include "consys_hw.h" +#include "conninfra_core.h" +#include "msg_thread.h" +#include "consys_reg_mng.h" +#include "conninfra_conf.h" + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +#define CONNINFRA_EVENT_TIMEOUT 3000 +#define CONNINFRA_RESET_TIMEOUT 500 +#define CONNINFRA_PRE_CAL_TIMEOUT 500 + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +static int opfunc_power_on(struct msg_op_data *op); +static int opfunc_power_off(struct msg_op_data *op); +static int opfunc_chip_rst(struct msg_op_data *op); +static int opfunc_pre_cal(struct msg_op_data *op); +static int opfunc_therm_ctrl(struct msg_op_data *op); +static int opfunc_rfspi_read(struct msg_op_data *op); +static int opfunc_rfspi_write(struct msg_op_data *op); +static int opfunc_adie_top_ck_en_on(struct msg_op_data *op); +static int opfunc_adie_top_ck_en_off(struct msg_op_data *op); +static int opfunc_spi_clock_switch(struct msg_op_data *op); +static int opfunc_clock_fail_dump(struct msg_op_data *op); +static int opfunc_pre_cal_prepare(struct msg_op_data *op); +static int opfunc_pre_cal_check(struct msg_op_data *op); + +static int opfunc_force_conninfra_wakeup(struct msg_op_data *op); +static int opfunc_force_conninfra_sleep(struct msg_op_data *op); + +static int opfunc_dump_power_state(struct msg_op_data *op); + +static int opfunc_subdrv_pre_reset(struct msg_op_data *op); +static int opfunc_subdrv_post_reset(struct msg_op_data *op); +static int opfunc_subdrv_cal_pwr_on(struct msg_op_data *op); +static int opfunc_subdrv_cal_do_cal(struct msg_op_data *op); +static int opfunc_subdrv_therm_ctrl(struct msg_op_data *op); + +static void _conninfra_core_update_rst_status(enum chip_rst_status status); + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +struct conninfra_ctx g_conninfra_ctx; + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ +static const msg_opid_func conninfra_core_opfunc[] = { + [CONNINFRA_OPID_PWR_ON] = opfunc_power_on, + [CONNINFRA_OPID_PWR_OFF] = opfunc_power_off, + [CONNINFRA_OPID_THERM_CTRL] = opfunc_therm_ctrl, + [CONNINFRA_OPID_RFSPI_READ] = opfunc_rfspi_read, + [CONNINFRA_OPID_RFSPI_WRITE] = opfunc_rfspi_write, + [CONNINFRA_OPID_ADIE_TOP_CK_EN_ON] = opfunc_adie_top_ck_en_on, + [CONNINFRA_OPID_ADIE_TOP_CK_EN_OFF] = opfunc_adie_top_ck_en_off, + [CONNINFRA_OPID_SPI_CLOCK_SWITCH] = opfunc_spi_clock_switch, + [CONNINFRA_OPID_CLOCK_FAIL_DUMP] = opfunc_clock_fail_dump, + [CONNINFRA_OPID_PRE_CAL_PREPARE] = opfunc_pre_cal_prepare, + [CONNINFRA_OPID_PRE_CAL_CHECK] = opfunc_pre_cal_check, + + [CONNINFRA_OPID_FORCE_CONNINFRA_WAKUP] = opfunc_force_conninfra_wakeup, + [CONNINFRA_OPID_FORCE_CONNINFRA_SLEEP] = opfunc_force_conninfra_sleep, + + [CONNINFRA_OPID_DUMP_POWER_STATE] = opfunc_dump_power_state, +}; + +static const msg_opid_func conninfra_core_cb_opfunc[] = { + [CONNINFRA_CB_OPID_CHIP_RST] = opfunc_chip_rst, + [CONNINFRA_CB_OPID_PRE_CAL] = opfunc_pre_cal, +}; + + +/* subsys ops */ +static char *drv_thread_name[] = { + [CONNDRV_TYPE_BT] = "sub_bt_thrd", + [CONNDRV_TYPE_FM] = "sub_fm_thrd", + [CONNDRV_TYPE_GPS] = "sub_gps_thrd", + [CONNDRV_TYPE_WIFI] = "sub_wifi_thrd", + [CONNDRV_TYPE_CONNINFRA] = "sub_conninfra_thrd", +}; + +static char *drv_name[] = { + [CONNDRV_TYPE_BT] = "BT", + [CONNDRV_TYPE_FM] = "FM", + [CONNDRV_TYPE_GPS] = "GPS", + [CONNDRV_TYPE_WIFI] = "WIFI", + [CONNDRV_TYPE_CONNINFRA] = "CONNINFRA", +}; + +typedef enum { + INFRA_SUBDRV_OPID_PRE_RESET = 0, + INFRA_SUBDRV_OPID_POST_RESET = 1, + INFRA_SUBDRV_OPID_CAL_PWR_ON = 2, + INFRA_SUBDRV_OPID_CAL_DO_CAL = 3, + INFRA_SUBDRV_OPID_THERM_CTRL = 4, + + INFRA_SUBDRV_OPID_MAX +} infra_subdrv_op; + + +static const msg_opid_func infra_subdrv_opfunc[] = { + [INFRA_SUBDRV_OPID_PRE_RESET] = opfunc_subdrv_pre_reset, + [INFRA_SUBDRV_OPID_POST_RESET] = opfunc_subdrv_post_reset, + [INFRA_SUBDRV_OPID_CAL_PWR_ON] = opfunc_subdrv_cal_pwr_on, + [INFRA_SUBDRV_OPID_CAL_DO_CAL] = opfunc_subdrv_cal_do_cal, + [INFRA_SUBDRV_OPID_THERM_CTRL] = opfunc_subdrv_therm_ctrl, +}; + +enum pre_cal_type { + PRE_CAL_ALL_ENABLED = 0, + PRE_CAL_ALL_DISABLED = 1, + PRE_CAL_PWR_ON_DISABLED = 2, + PRE_CAL_SCREEN_ON_DISABLED = 3 +}; + +static unsigned int g_pre_cal_mode = 0; + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +static void reset_chip_rst_trg_data(void) +{ + g_conninfra_ctx.trg_drv = CONNDRV_TYPE_MAX; + memset(g_conninfra_ctx.trg_reason, '\0', CHIP_RST_REASON_MAX_LEN); +} + +static unsigned long timeval_to_ms(struct timeval *begin, struct timeval *end) +{ + unsigned long time_diff; + + time_diff = (end->tv_sec - begin->tv_sec) * 1000; + time_diff += (end->tv_usec - begin->tv_usec) / 1000; + + return time_diff; +} + +static unsigned int opfunc_get_current_status(void) +{ + unsigned int ret = 0; + unsigned int i; + + for (i = 0; i < CONNDRV_TYPE_MAX; i++) { + ret |= (g_conninfra_ctx.drv_inst[i].drv_status << i); + } + + return ret; +} + +static void opfunc_vcn_control_internal(unsigned int drv_type, bool on) +{ + /* VCNx enable */ + switch (drv_type) { + case CONNDRV_TYPE_BT: + consys_hw_bt_power_ctl(on); + break; + case CONNDRV_TYPE_FM: + consys_hw_fm_power_ctl(on); + break; + case CONNDRV_TYPE_GPS: + consys_hw_gps_power_ctl(on); + break; + case CONNDRV_TYPE_WIFI: + consys_hw_wifi_power_ctl(on); + break; + default: + pr_err("Wrong parameter: drv_type(%d)\n", drv_type); + break; + } +} + +static int opfunc_power_on_internal(unsigned int drv_type) +{ + int ret; + struct conninfra_ctx *infra_ctx = &g_conninfra_ctx; + + /* Check abnormal type */ + if (drv_type >= CONNDRV_TYPE_MAX) { + pr_err("abnormal Fun(%d)\n", drv_type); + return -EINVAL; + } + + /* Check abnormal state */ + if ((g_conninfra_ctx.drv_inst[drv_type].drv_status < DRV_STS_POWER_OFF) + || (g_conninfra_ctx.drv_inst[drv_type].drv_status >= DRV_STS_MAX)) { + pr_err("func(%d) status[0x%x] abnormal\n", drv_type, + g_conninfra_ctx.drv_inst[drv_type].drv_status); + return -EINVAL; + } + + ret = osal_lock_sleepable_lock(&infra_ctx->core_lock); + if (ret) { + pr_err("core_lock fail!!"); + return ret; + } + + /* check if func already on */ + if (g_conninfra_ctx.drv_inst[drv_type].drv_status == DRV_STS_POWER_ON) { + pr_warn("func(%d) already on\n", drv_type); + osal_unlock_sleepable_lock(&infra_ctx->core_lock); + return 0; + } + + ret = consys_hw_pwr_on(opfunc_get_current_status(), drv_type); + if (ret) { + pr_err("Conninfra power on fail. drv(%d) ret=(%d)\n", + drv_type, ret); + osal_unlock_sleepable_lock(&infra_ctx->core_lock); + return -3; + } + /* POWER ON SEQUENCE */ + g_conninfra_ctx.infra_drv_status = DRV_STS_POWER_ON; + + g_conninfra_ctx.drv_inst[drv_type].drv_status = DRV_STS_POWER_ON; + + /* VCNx enable */ + opfunc_vcn_control_internal(drv_type, true); + + pr_info("[Conninfra Pwr On] BT=[%d] FM=[%d] GPS=[%d] WF=[%d]", + infra_ctx->drv_inst[CONNDRV_TYPE_BT].drv_status, + infra_ctx->drv_inst[CONNDRV_TYPE_FM].drv_status, + infra_ctx->drv_inst[CONNDRV_TYPE_GPS].drv_status, + infra_ctx->drv_inst[CONNDRV_TYPE_WIFI].drv_status); + osal_unlock_sleepable_lock(&infra_ctx->core_lock); + + return 0; +} + +static int opfunc_power_on(struct msg_op_data *op) +{ + unsigned int drv_type = op->op_data[0]; + + return opfunc_power_on_internal(drv_type); +} + +static int opfunc_power_off_internal(unsigned int drv_type) +{ + int i, ret; + bool try_power_off = true; + struct conninfra_ctx *infra_ctx = &g_conninfra_ctx; + unsigned int curr_status = opfunc_get_current_status(); + + /* Check abnormal type */ + if (drv_type >= CONNDRV_TYPE_MAX) { + pr_err("abnormal Fun(%d)\n", drv_type); + return -EINVAL; + } + + ret = osal_lock_sleepable_lock(&infra_ctx->core_lock); + if (ret) { + pr_err("core_lock fail!!"); + return ret; + } + + /* Check abnormal state */ + if ((g_conninfra_ctx.drv_inst[drv_type].drv_status < DRV_STS_POWER_OFF) + || (g_conninfra_ctx.drv_inst[drv_type].drv_status >= DRV_STS_MAX)) { + pr_err("func(%d) status[0x%x] abnormal\n", drv_type, + g_conninfra_ctx.drv_inst[drv_type].drv_status); + osal_unlock_sleepable_lock(&infra_ctx->core_lock); + return -2; + } + + /* Special case for force power off */ + if (drv_type == CONNDRV_TYPE_CONNINFRA) { + if (g_conninfra_ctx.infra_drv_status == DRV_STS_POWER_OFF) { + pr_warn("Connsys already off, do nothing for force off\n"); + return 0; + } + /* Turn off subsys VCN and update record */ + for (i = 0; i < CONNDRV_TYPE_MAX; i++) { + if (g_conninfra_ctx.drv_inst[i].drv_status == DRV_STS_POWER_ON) { + opfunc_vcn_control_internal(i, false); + g_conninfra_ctx.drv_inst[i].drv_status = DRV_STS_POWER_OFF; + } + } + /* POWER OFF SEQUENCE */ + ret = consys_hw_pwr_off(0, drv_type); + /* For force power off operation, ignore err code */ + if (ret) + pr_err("Force power off fail. ret=%d\n", ret); + try_power_off = true; + } else { + /* check if func already off */ + if (g_conninfra_ctx.drv_inst[drv_type].drv_status + == DRV_STS_POWER_OFF) { + pr_warn("func(%d) already off\n", drv_type); + osal_unlock_sleepable_lock(&infra_ctx->core_lock); + return 0; + } + /* VCNx disable */ + opfunc_vcn_control_internal(drv_type, false); + g_conninfra_ctx.drv_inst[drv_type].drv_status = DRV_STS_POWER_OFF; + /* is there subsys on ? */ + for (i = 0; i < CONNDRV_TYPE_MAX; i++) + if (g_conninfra_ctx.drv_inst[i].drv_status == DRV_STS_POWER_ON) + try_power_off = false; + + /* POWER OFF SEQUENCE */ + ret = consys_hw_pwr_off(curr_status, drv_type); + if (ret) { + pr_err("Conninfra power on fail. drv(%d) ret=(%d)\n", + drv_type, ret); + osal_unlock_sleepable_lock(&infra_ctx->core_lock); + return -3; + } + } + + if (try_power_off) + g_conninfra_ctx.infra_drv_status = DRV_STS_POWER_OFF; + + pr_info("[Conninfra Pwr Off] Conninfra=[%d] BT=[%d] FM=[%d] GPS=[%d] WF=[%d]", + infra_ctx->infra_drv_status, + infra_ctx->drv_inst[CONNDRV_TYPE_BT].drv_status, + infra_ctx->drv_inst[CONNDRV_TYPE_FM].drv_status, + infra_ctx->drv_inst[CONNDRV_TYPE_GPS].drv_status, + infra_ctx->drv_inst[CONNDRV_TYPE_WIFI].drv_status); + + osal_unlock_sleepable_lock(&infra_ctx->core_lock); + return 0; +} + +static int opfunc_power_off(struct msg_op_data *op) +{ + unsigned int drv_type = op->op_data[0]; + + return opfunc_power_off_internal(drv_type); +} + +static int opfunc_chip_rst(struct msg_op_data *op) +{ + int i, ret, cur_rst_state; + struct subsys_drv_inst *drv_inst; + unsigned int drv_pwr_state[CONNDRV_TYPE_MAX]; + const unsigned int subdrv_all_done = (0x1 << CONNDRV_TYPE_MAX) - 1; + struct timeval pre_begin, pre_end, reset_end, done_end; + + if (g_conninfra_ctx.infra_drv_status == DRV_STS_POWER_OFF) { + pr_info("No subsys on, just return"); + _conninfra_core_update_rst_status(CHIP_RST_NONE); + return 0; + } + + do_gettimeofday(&pre_begin); + + atomic_set(&g_conninfra_ctx.rst_state, 0); + sema_init(&g_conninfra_ctx.rst_sema, 1); + + _conninfra_core_update_rst_status(CHIP_RST_PRE_CB); + + /* pre */ + for (i = 0; i < CONNDRV_TYPE_MAX; i++) { + drv_inst = &g_conninfra_ctx.drv_inst[i]; + drv_pwr_state[i] = drv_inst->drv_status; + pr_info("subsys %d is %d", i, drv_inst->drv_status); + ret = msg_thread_send_1(&drv_inst->msg_ctx, + INFRA_SUBDRV_OPID_PRE_RESET, i); + } + + pr_info("[chip_rst] pre vvvvvvvvvvvvv"); + while (atomic_read(&g_conninfra_ctx.rst_state) != subdrv_all_done) { + ret = down_timeout(&g_conninfra_ctx.rst_sema, msecs_to_jiffies(CONNINFRA_RESET_TIMEOUT)); + pr_info("sema ret=[%d]", ret); + if (ret == 0) + continue; + cur_rst_state = atomic_read(&g_conninfra_ctx.rst_state); + pr_info("cur_rst state =[%d]", cur_rst_state); + for (i = 0; i < CONNDRV_TYPE_MAX; i++) { + if ((cur_rst_state & (0x1 << i)) == 0) { + pr_info("[chip_rst] [%s] pre-callback is not back", drv_thread_name[i]); + drv_inst = &g_conninfra_ctx.drv_inst[i]; + osal_thread_show_stack(&drv_inst->msg_ctx.thread); + } + } + } + + _conninfra_core_update_rst_status(CHIP_RST_RESET); + + do_gettimeofday(&pre_end); + + pr_info("[chip_rst] reset ++++++++++++"); + /*******************************************************/ + /* reset */ + /* call consys_hw */ + /*******************************************************/ + /* Special power-off function, turn off connsys directly */ + ret = opfunc_power_off_internal(CONNDRV_TYPE_CONNINFRA); + pr_info("Force conninfra power off, ret=%d\n", ret); + pr_info("conninfra status should be power off. Status=%d", g_conninfra_ctx.infra_drv_status); + + /* Turn on subsys */ + for (i = 0; i < CONNDRV_TYPE_MAX; i++) { + if (drv_pwr_state[i]) { + ret = opfunc_power_on_internal(i); + pr_info("Call subsys(%d) power on ret=%d", i, ret); + } + } + pr_info("conninfra status should be power on. Status=%d", g_conninfra_ctx.infra_drv_status); + + pr_info("[chip_rst] reset --------------"); + + _conninfra_core_update_rst_status(CHIP_RST_POST_CB); + + do_gettimeofday(&reset_end); + + /* post */ + atomic_set(&g_conninfra_ctx.rst_state, 0); + sema_init(&g_conninfra_ctx.rst_sema, 1); + for (i = 0; i < CONNDRV_TYPE_MAX; i++) { + drv_inst = &g_conninfra_ctx.drv_inst[i]; + ret = msg_thread_send_1(&drv_inst->msg_ctx, + INFRA_SUBDRV_OPID_POST_RESET, i); + } + + while (atomic_read(&g_conninfra_ctx.rst_state) != subdrv_all_done) { + ret = down_timeout(&g_conninfra_ctx.rst_sema, msecs_to_jiffies(CONNINFRA_RESET_TIMEOUT)); + if (ret == 0) + continue; + cur_rst_state = atomic_read(&g_conninfra_ctx.rst_state); + for (i = 0; i < CONNDRV_TYPE_MAX; i++) { + if ((cur_rst_state & (0x1 << i)) == 0) { + pr_info("[chip_rst] [%s] post-callback is not back", drv_thread_name[i]); + drv_inst = &g_conninfra_ctx.drv_inst[i]; + osal_thread_show_stack(&drv_inst->msg_ctx.thread); + } + } + } + pr_info("[chip_rst] post ^^^^^^^^^^^^^^"); + + reset_chip_rst_trg_data(); + //_conninfra_core_update_rst_status(CHIP_RST_DONE); + _conninfra_core_update_rst_status(CHIP_RST_NONE); + do_gettimeofday(&done_end); + + pr_info("[chip_rst] summary pre=[%lu] reset=[%lu] post=[%lu]", + timeval_to_ms(&pre_begin, &pre_end), + timeval_to_ms(&pre_end, &reset_end), + timeval_to_ms(&reset_end, &done_end)); + + return 0; +} + +static int opfunc_pre_cal(struct msg_op_data *op) +{ +#define CAL_DRV_COUNT 2 + int cal_drvs[CAL_DRV_COUNT] = {CONNDRV_TYPE_BT, CONNDRV_TYPE_WIFI}; + int i, ret, cur_state; + int bt_cal_ret, wf_cal_ret; + struct subsys_drv_inst *drv_inst; + int pre_cal_done_state = (0x1 << CONNDRV_TYPE_BT) | (0x1 << CONNDRV_TYPE_WIFI); + struct timeval begin, bt_cal_begin, wf_cal_begin, end; + + /* Check BT/WIFI status again */ + ret = osal_lock_sleepable_lock(&g_conninfra_ctx.core_lock); + if (ret) { + pr_err("[%s] core_lock fail!!", __func__); + return ret; + } + /* check if func already on */ + for (i = 0; i < CAL_DRV_COUNT; i++) { + if (g_conninfra_ctx.drv_inst[cal_drvs[i]].drv_status == DRV_STS_POWER_ON) { + pr_warn("[%s] %s already on\n", __func__, drv_name[cal_drvs[i]]); + osal_unlock_sleepable_lock(&g_conninfra_ctx.core_lock); + return 0; + } + } + osal_unlock_sleepable_lock(&g_conninfra_ctx.core_lock); + + ret = conninfra_core_power_on(CONNDRV_TYPE_BT); + if (ret) { + pr_err("BT power on fail during pre_cal"); + return -1; + } + ret = conninfra_core_power_on(CONNDRV_TYPE_WIFI); + if (ret) { + pr_err("WIFI power on fail during pre_cal"); + conninfra_core_power_off(CONNDRV_TYPE_BT); + return -2; + } + + do_gettimeofday(&begin); + + /* power on subsys */ + atomic_set(&g_conninfra_ctx.pre_cal_state, 0); + sema_init(&g_conninfra_ctx.pre_cal_sema, 1); + + for (i = 0; i < CAL_DRV_COUNT; i++) { + drv_inst = &g_conninfra_ctx.drv_inst[cal_drvs[i]]; + ret = msg_thread_send_1(&drv_inst->msg_ctx, + INFRA_SUBDRV_OPID_CAL_PWR_ON, cal_drvs[i]); + if (ret) + pr_warn("driver [%d] power on fail\n", cal_drvs[i]); + } + + while (atomic_read(&g_conninfra_ctx.pre_cal_state) != pre_cal_done_state) { + ret = down_timeout(&g_conninfra_ctx.pre_cal_sema, msecs_to_jiffies(CONNINFRA_PRE_CAL_TIMEOUT)); + if (ret == 0) + continue; + cur_state = atomic_read(&g_conninfra_ctx.pre_cal_state); + pr_info("[pre_cal] cur state =[%d]", cur_state); + if ((cur_state & (0x1 << CONNDRV_TYPE_BT)) == 0) { + pr_info("[pre_cal] BT pwr_on callback is not back"); + drv_inst = &g_conninfra_ctx.drv_inst[CONNDRV_TYPE_BT]; + osal_thread_show_stack(&drv_inst->msg_ctx.thread); + } + if ((cur_state & (0x1 << CONNDRV_TYPE_WIFI)) == 0) { + pr_info("[pre_cal] WIFI pwr_on callback is not back"); + drv_inst = &g_conninfra_ctx.drv_inst[CONNDRV_TYPE_WIFI]; + osal_thread_show_stack(&drv_inst->msg_ctx.thread); + } + } + pr_info("[pre_cal] >>>>>>> power on DONE!!"); + + do_gettimeofday(&bt_cal_begin); + + /* Do Calibration */ + drv_inst = &g_conninfra_ctx.drv_inst[CONNDRV_TYPE_BT]; + bt_cal_ret = msg_thread_send_wait_1(&drv_inst->msg_ctx, + INFRA_SUBDRV_OPID_CAL_DO_CAL, 0, CONNDRV_TYPE_BT); + + pr_info("[pre_cal] driver [%s] calibration %s, ret=[%d]\n", drv_name[CONNDRV_TYPE_BT], + (bt_cal_ret == CONNINFRA_CB_RET_CAL_FAIL_POWER_OFF || + bt_cal_ret == CONNINFRA_CB_RET_CAL_FAIL_POWER_ON) ? "fail" : "success", + bt_cal_ret); + + if (bt_cal_ret == CONNINFRA_CB_RET_CAL_PASS_POWER_OFF || + bt_cal_ret == CONNINFRA_CB_RET_CAL_FAIL_POWER_OFF) + conninfra_core_power_off(CONNDRV_TYPE_BT); + + pr_info("[pre_cal] >>>>>>>> BT do cal done"); + + do_gettimeofday(&wf_cal_begin); + + drv_inst = &g_conninfra_ctx.drv_inst[CONNDRV_TYPE_WIFI]; + wf_cal_ret = msg_thread_send_wait_1(&drv_inst->msg_ctx, + INFRA_SUBDRV_OPID_CAL_DO_CAL, 0, CONNDRV_TYPE_WIFI); + + pr_info("[pre_cal] driver [%s] calibration %s, ret=[%d]\n", drv_name[CONNDRV_TYPE_WIFI], + (wf_cal_ret == CONNINFRA_CB_RET_CAL_FAIL_POWER_OFF || + wf_cal_ret == CONNINFRA_CB_RET_CAL_FAIL_POWER_ON) ? "fail" : "success", + wf_cal_ret); + + if (wf_cal_ret == CONNINFRA_CB_RET_CAL_PASS_POWER_OFF || + wf_cal_ret == CONNINFRA_CB_RET_CAL_FAIL_POWER_OFF) + conninfra_core_power_off(CONNDRV_TYPE_WIFI); + + pr_info(">>>>>>>> WF do cal done"); + + do_gettimeofday(&end); + + pr_info("[pre_cal] summary pwr=[%lu] bt_cal=[%d][%lu] wf_cal=[%d][%lu]", + timeval_to_ms(&begin, &bt_cal_begin), + bt_cal_ret, timeval_to_ms(&bt_cal_begin, &wf_cal_begin), + wf_cal_ret, timeval_to_ms(&wf_cal_begin, &end)); + + return 0; +} + + +static int opfunc_therm_ctrl(struct msg_op_data *op) +{ + int ret = -1; + int *data_ptr = (int*)op->op_data[0]; + + if (g_conninfra_ctx.infra_drv_status != DRV_STS_POWER_ON) { + *data_ptr = 0; + return 0; + } + + if (data_ptr) + ret = consys_hw_therm_query(data_ptr); + return ret; +} + + +static int opfunc_rfspi_read(struct msg_op_data *op) +{ + int ret = 0; + unsigned int data = 0; + unsigned int* data_pt = (unsigned int*)op->op_data[2]; + + ret = osal_lock_sleepable_lock(&g_conninfra_ctx.core_lock); + if (ret) { + pr_err("core_lock fail!!\n"); + return CONNINFRA_SPI_OP_FAIL; + } + + if (g_conninfra_ctx.infra_drv_status != DRV_STS_POWER_ON) { + pr_err("Connsys didn't power on\n"); + ret = CONNINFRA_SPI_OP_FAIL; + goto err; + } + if (consys_hw_reg_readable() == 0) { + pr_err("connsys reg not readable\n"); + ret = CONNINFRA_SPI_OP_FAIL; + goto err; + } + /* DO read spi */ + ret = consys_hw_spi_read(op->op_data[0], op->op_data[1], &data); + if (data_pt) + *(data_pt) = data; +err: + osal_unlock_sleepable_lock(&g_conninfra_ctx.core_lock); + return ret; +} + +static int opfunc_rfspi_write(struct msg_op_data *op) +{ + int ret = 0; + + ret = osal_lock_sleepable_lock(&g_conninfra_ctx.core_lock); + if (ret) { + pr_err("core_lock fail!!\n"); + return CONNINFRA_SPI_OP_FAIL; + } + + if (g_conninfra_ctx.infra_drv_status != DRV_STS_POWER_ON) { + pr_err("Connsys didn't power on\n"); + ret = CONNINFRA_SPI_OP_FAIL; + goto err; + } + if (consys_hw_reg_readable() == 0) { + pr_err("connsys reg not readable\n"); + ret = CONNINFRA_SPI_OP_FAIL; + goto err; + } + /* DO spi write */ + ret = consys_hw_spi_write(op->op_data[0], op->op_data[1], op->op_data[2]); +err: + osal_unlock_sleepable_lock(&g_conninfra_ctx.core_lock); + return ret; +} + +static int opfunc_adie_top_ck_en_on(struct msg_op_data *op) +{ + int ret = 0; + unsigned int type = op->op_data[0]; + + if (type >= CONNSYS_ADIE_CTL_MAX) { + pr_err("wrong parameter %d\n", type); + return -EINVAL; + } + + ret = osal_lock_sleepable_lock(&g_conninfra_ctx.core_lock); + if (ret) { + pr_err("core_lock fail!!\n"); + ret = -1; + goto err; + } + + if (g_conninfra_ctx.infra_drv_status != DRV_STS_POWER_ON) { + pr_err("Connsys didn't power on\n"); + ret = -2; + goto err; + } + + ret = consys_hw_adie_top_ck_en_on(type); + +err: + osal_unlock_sleepable_lock(&g_conninfra_ctx.core_lock); + return ret; +} + + +static int opfunc_adie_top_ck_en_off(struct msg_op_data *op) +{ + int ret = 0; + unsigned int type = op->op_data[0]; + + if (type >= CONNSYS_ADIE_CTL_MAX) { + pr_err("wrong parameter %d\n", type); + return -EINVAL; + } + + ret = osal_lock_sleepable_lock(&g_conninfra_ctx.core_lock); + if (ret) { + pr_err("core_lock fail!!\n"); + ret = -1; + goto err; + } + if (g_conninfra_ctx.infra_drv_status != DRV_STS_POWER_ON) { + pr_err("Connsys didn't power on\n"); + ret = -2; + goto err; + } + + ret = consys_hw_adie_top_ck_en_off(type); +err: + osal_unlock_sleepable_lock(&g_conninfra_ctx.core_lock); + return ret; +} + +static int opfunc_spi_clock_switch(struct msg_op_data *op) +{ + int ret = 0; + unsigned int type = op->op_data[0]; + + if (type >= CONNSYS_SPI_SPEED_MAX) { + pr_err("wrong parameter %d\n", type); + return -EINVAL; + } + + ret = osal_lock_sleepable_lock(&g_conninfra_ctx.core_lock); + if (ret) { + pr_err("core_lock fail!!\n"); + ret = -2; + goto err; + } + if (g_conninfra_ctx.infra_drv_status != DRV_STS_POWER_ON) { + pr_err("Connsys didn't power on\n"); + ret = -2; + goto err; + } + + ret = consys_hw_spi_clock_switch(type); +err: + osal_unlock_sleepable_lock(&g_conninfra_ctx.core_lock); + return ret; +} + + +static int opfunc_clock_fail_dump(struct msg_op_data *op) +{ + consys_hw_clock_fail_dump(); + return 0; +} + + +static int opfunc_pre_cal_prepare(struct msg_op_data *op) +{ + int ret, rst_status; + unsigned long flag; + struct pre_cal_info *cal_info = &g_conninfra_ctx.cal_info; + struct subsys_drv_inst *bt_drv = &g_conninfra_ctx.drv_inst[CONNDRV_TYPE_BT]; + struct subsys_drv_inst *wifi_drv = &g_conninfra_ctx.drv_inst[CONNDRV_TYPE_WIFI]; + enum pre_cal_status cur_status; + + spin_lock_irqsave(&g_conninfra_ctx.infra_lock, flag); + + if (bt_drv->ops_cb.pre_cal_cb.do_cal_cb == NULL || + wifi_drv->ops_cb.pre_cal_cb.do_cal_cb == NULL) { + pr_info("[%s] [pre_cal] [%p][%p]", __func__, + bt_drv->ops_cb.pre_cal_cb.do_cal_cb, + wifi_drv->ops_cb.pre_cal_cb.do_cal_cb); + spin_unlock_irqrestore(&g_conninfra_ctx.infra_lock, flag); + return 0; + } + spin_unlock_irqrestore(&g_conninfra_ctx.infra_lock, flag); + + spin_lock_irqsave(&g_conninfra_ctx.rst_lock, flag); + rst_status = g_conninfra_ctx.rst_status; + spin_unlock_irqrestore(&g_conninfra_ctx.rst_lock, flag); + + if (rst_status > CHIP_RST_NONE) { + pr_info("rst is ongoing, skip pre_cal"); + return 0; + } + + /* non-zero means lock got, zero means not */ + ret = osal_trylock_sleepable_lock(&cal_info->pre_cal_lock); + + if (ret) { + cur_status = cal_info->status; + + if ((cur_status == PRE_CAL_NOT_INIT || cur_status == PRE_CAL_NEED_RESCHEDULE) && + bt_drv->drv_status == DRV_STS_POWER_OFF && + wifi_drv->drv_status == DRV_STS_POWER_OFF) { + cal_info->status = PRE_CAL_SCHEDULED; + cal_info->caller = op->op_data[0]; + pr_info("[pre_cal] BT&WIFI is off, schedule pre-cal from status=[%d] to new status[%d]\n", + cur_status, cal_info->status); + schedule_work(&cal_info->pre_cal_work); + } else { + pr_info("[%s] [pre_cal] bt=[%d] wf=[%d] status=[%d]", __func__, + bt_drv->drv_status, wifi_drv->drv_status, cur_status); + } + osal_unlock_sleepable_lock(&cal_info->pre_cal_lock); + } + + return 0; +} + +static int opfunc_pre_cal_check(struct msg_op_data *op) +{ + int ret; + struct pre_cal_info *cal_info = &g_conninfra_ctx.cal_info; + struct subsys_drv_inst *bt_drv = &g_conninfra_ctx.drv_inst[CONNDRV_TYPE_BT]; + struct subsys_drv_inst *wifi_drv = &g_conninfra_ctx.drv_inst[CONNDRV_TYPE_WIFI]; + enum pre_cal_status cur_status; + + /* non-zero means lock got, zero means not */ + ret = osal_trylock_sleepable_lock(&cal_info->pre_cal_lock); + if (ret) { + cur_status = cal_info->status; + + pr_info("[%s] [pre_cal] bt=[%d] wf=[%d] status=[%d]", __func__, + bt_drv->drv_status, wifi_drv->drv_status, + cur_status); + if (cur_status == PRE_CAL_DONE && + bt_drv->drv_status == DRV_STS_POWER_OFF && + wifi_drv->drv_status == DRV_STS_POWER_OFF) { + pr_info("[pre_cal] reset pre-cal"); + cal_info->status = PRE_CAL_NEED_RESCHEDULE; + } + osal_unlock_sleepable_lock(&cal_info->pre_cal_lock); + } + return 0; +} + + +static int opfunc_force_conninfra_wakeup(struct msg_op_data *op) +{ + int ret; + struct conninfra_ctx *infra_ctx = &g_conninfra_ctx; + + ret = osal_lock_sleepable_lock(&infra_ctx->core_lock); + if (ret) { + pr_err("core_lock fail!!"); + return ret; + } + + /* check if conninfra already on */ + if (g_conninfra_ctx.infra_drv_status != DRV_STS_POWER_ON) { + ret = -1; + goto err; + } + + ret = consys_hw_force_conninfra_wakeup(); + if (ret) + pr_err("force conninfra wakeup fail"); + +err: + osal_unlock_sleepable_lock(&infra_ctx->core_lock); + return ret; +} + +static int opfunc_force_conninfra_sleep(struct msg_op_data *op) +{ + int ret; + struct conninfra_ctx *infra_ctx = &g_conninfra_ctx; + + ret = osal_lock_sleepable_lock(&infra_ctx->core_lock); + if (ret) { + pr_err("core_lock fail!!"); + return ret; + } + + /* check if conninfra already on */ + if (g_conninfra_ctx.infra_drv_status != DRV_STS_POWER_ON) { + ret = -1; + goto err; + } + + ret = consys_hw_force_conninfra_sleep(); + if (ret) + pr_err("force conninfra sleep fail"); + +err: + osal_unlock_sleepable_lock(&infra_ctx->core_lock); + return ret; +} + + +static int opfunc_dump_power_state(struct msg_op_data *op) +{ + int ret; + struct conninfra_ctx *infra_ctx = &g_conninfra_ctx; + + ret = osal_lock_sleepable_lock(&infra_ctx->core_lock); + if (ret) { + pr_err("core_lock fail!!"); + return ret; + } + + /* check if conninfra already on */ + if (g_conninfra_ctx.infra_drv_status != DRV_STS_POWER_ON) { + ret = -1; + goto err; + } + + ret = consys_hw_dump_power_state(); + if (ret) + pr_err("dump power state fail"); + +err: + osal_unlock_sleepable_lock(&infra_ctx->core_lock); + return ret; + +} + +static int opfunc_subdrv_pre_reset(struct msg_op_data *op) +{ + int ret, cur_rst_state; + unsigned int drv_type = op->op_data[0]; + struct subsys_drv_inst *drv_inst; + + + /* TODO: should be locked, to avoid cb was reset */ + drv_inst = &g_conninfra_ctx.drv_inst[drv_type]; + if (/*drv_inst->drv_status == DRV_ST_POWER_ON &&*/ + drv_inst->ops_cb.rst_cb.pre_whole_chip_rst) { + + ret = drv_inst->ops_cb.rst_cb.pre_whole_chip_rst(g_conninfra_ctx.trg_drv, + g_conninfra_ctx.trg_reason); + if (ret) + pr_err("[%s] fail [%d]", __func__, ret); + } + + atomic_add(0x1 << drv_type, &g_conninfra_ctx.rst_state); + cur_rst_state = atomic_read(&g_conninfra_ctx.rst_state); + + pr_info("[%s] rst_state=[%d]", drv_thread_name[drv_type], cur_rst_state); + + up(&g_conninfra_ctx.rst_sema); + return 0; +} + +static int opfunc_subdrv_post_reset(struct msg_op_data *op) +{ + int ret; + unsigned int drv_type = op->op_data[0]; + struct subsys_drv_inst *drv_inst; + + /* TODO: should be locked, to avoid cb was reset */ + drv_inst = &g_conninfra_ctx.drv_inst[drv_type]; + if (/*drv_inst->drv_status == DRV_ST_POWER_ON &&*/ + drv_inst->ops_cb.rst_cb.post_whole_chip_rst) { + ret = drv_inst->ops_cb.rst_cb.post_whole_chip_rst(); + if (ret) + pr_warn("[%s] fail [%d]", __func__, ret); + } + + atomic_add(0x1 << drv_type, &g_conninfra_ctx.rst_state); + up(&g_conninfra_ctx.rst_sema); + return 0; +} + +static int opfunc_subdrv_cal_pwr_on(struct msg_op_data *op) +{ + int ret; + unsigned int drv_type = op->op_data[0]; + struct subsys_drv_inst *drv_inst; + + pr_info("[%s] drv=[%s]", __func__, drv_thread_name[drv_type]); + + /* TODO: should be locked, to avoid cb was reset */ + drv_inst = &g_conninfra_ctx.drv_inst[drv_type]; + if (/*drv_inst->drv_status == DRV_ST_POWER_ON &&*/ + drv_inst->ops_cb.pre_cal_cb.pwr_on_cb) { + ret = drv_inst->ops_cb.pre_cal_cb.pwr_on_cb(); + if (ret) + pr_warn("[%s] fail [%d]", __func__, ret); + } + + atomic_add(0x1 << drv_type, &g_conninfra_ctx.pre_cal_state); + up(&g_conninfra_ctx.pre_cal_sema); + + pr_info("[pre_cal][%s] [%s] DONE", __func__, drv_thread_name[drv_type]); + return 0; +} + +static int opfunc_subdrv_cal_do_cal(struct msg_op_data *op) +{ + int ret = 0; + unsigned int drv_type = op->op_data[0]; + struct subsys_drv_inst *drv_inst; + + pr_info("[%s] drv=[%s]", __func__, drv_thread_name[drv_type]); + + drv_inst = &g_conninfra_ctx.drv_inst[drv_type]; + if (/*drv_inst->drv_status == DRV_ST_POWER_ON &&*/ + drv_inst->ops_cb.pre_cal_cb.do_cal_cb) { + ret = drv_inst->ops_cb.pre_cal_cb.do_cal_cb(); + if (ret) + pr_warn("[%s] fail [%d]", __func__, ret); + } + + pr_info("[pre_cal][%s] [%s] DONE", __func__, drv_thread_name[drv_type]); + return ret; +} + +static int opfunc_subdrv_therm_ctrl(struct msg_op_data *op) +{ + return 0; +} + + +/* + * CONNINFRA API + */ +int conninfra_core_power_on(enum consys_drv_type type) +{ + int ret = 0; + struct conninfra_ctx *infra_ctx = &g_conninfra_ctx; + + ret = msg_thread_send_wait_1(&infra_ctx->msg_ctx, + CONNINFRA_OPID_PWR_ON, 0, type); + if (ret) { + pr_err("[%s] fail, ret = %d\n", __func__, ret); + return -1; + } + return 0; +} + +int conninfra_core_power_off(enum consys_drv_type type) +{ + int ret = 0; + struct conninfra_ctx *infra_ctx = &g_conninfra_ctx; + + ret = msg_thread_send_wait_1(&infra_ctx->msg_ctx, + CONNINFRA_OPID_PWR_OFF, 0, type); + if (ret) { + pr_err("[%s] send msg fail, ret = %d\n", __func__, ret); + return -1; + } + return 0; +} + +int conninfra_core_pre_cal_start(void) +{ + int ret = 0; + bool skip = false; + enum pre_cal_caller caller; + struct conninfra_ctx *infra_ctx = &g_conninfra_ctx; + struct pre_cal_info *cal_info = &infra_ctx->cal_info; + + ret = osal_lock_sleepable_lock(&cal_info->pre_cal_lock); + if (ret) { + pr_err("[%s] get lock fail, ret = %d\n", + __func__, ret); + return -1; + } + + caller = cal_info->caller; + pr_info("[%s] [pre_cal] Caller = %u", __func__, caller); + + /* Handle different pre_cal_mode */ + switch (g_pre_cal_mode) { + case PRE_CAL_ALL_DISABLED: + pr_info("[%s] [pre_cal] Skip all pre-cal", __func__); + skip = true; + cal_info->status = PRE_CAL_DONE; + break; + case PRE_CAL_PWR_ON_DISABLED: + if (caller == PRE_CAL_BY_SUBDRV_REGISTER) { + pr_info("[%s] [pre_cal] Skip pre-cal triggered by subdrv register", __func__); + skip = true; + cal_info->status = PRE_CAL_NOT_INIT; + } + break; + case PRE_CAL_SCREEN_ON_DISABLED: + if (caller == PRE_CAL_BY_SCREEN_ON) { + pr_info("[%s] [pre_cal] Skip pre-cal triggered by screen on", __func__); + skip = true; + cal_info->status = PRE_CAL_DONE; + } + break; + default: + pr_info("[%s] [pre_cal] Begin pre-cal, g_pre_cal_mode: %u", + __func__, g_pre_cal_mode); + break; + } + + if (skip) { + pr_info("[%s] [pre_cal] Reset status to %d", __func__, cal_info->status); + osal_unlock_sleepable_lock(&cal_info->pre_cal_lock); + return -2; + } + + cal_info->status = PRE_CAL_EXECUTING; + ret = msg_thread_send_wait(&infra_ctx->cb_ctx, + CONNINFRA_CB_OPID_PRE_CAL, 0); + if (ret) { + pr_err("[%s] send msg fail, ret = %d\n", __func__, ret); + } + + cal_info->status = PRE_CAL_DONE; + osal_unlock_sleepable_lock(&cal_info->pre_cal_lock); + return 0; +} + +int conninfra_core_screen_on(void) +{ + int ret = 0, rst_status; + unsigned long flag; + struct conninfra_ctx *infra_ctx = &g_conninfra_ctx; + + spin_lock_irqsave(&infra_ctx->rst_lock, flag); + rst_status = g_conninfra_ctx.rst_status; + spin_unlock_irqrestore(&infra_ctx->rst_lock, flag); + + if (rst_status > CHIP_RST_NONE) { + pr_info("rst is ongoing, skip pre_cal"); + return 0; + } + + ret = msg_thread_send_1(&infra_ctx->msg_ctx, + CONNINFRA_OPID_PRE_CAL_PREPARE, PRE_CAL_BY_SCREEN_ON); + if (ret) { + pr_err("[%s] send msg fail, ret = %d\n", __func__, ret); + return -1; + } + return 0; +} + +int conninfra_core_screen_off(void) +{ + int ret = 0; + struct conninfra_ctx *infra_ctx = &g_conninfra_ctx; + + ret = msg_thread_send(&infra_ctx->msg_ctx, + CONNINFRA_OPID_PRE_CAL_CHECK); + if (ret) { + pr_err("[%s] send msg fail, ret = %d\n", __func__, ret); + return -1; + } + + return 0; +} + +int conninfra_core_reg_readable(void) +{ + int ret = 0, rst_status; + unsigned long flag; + struct conninfra_ctx *infra_ctx = &g_conninfra_ctx; + + + /* check if in reseting, can not read */ + spin_lock_irqsave(&g_conninfra_ctx.rst_lock, flag); + rst_status = g_conninfra_ctx.rst_status; + spin_unlock_irqrestore(&g_conninfra_ctx.rst_lock, flag); + + if (rst_status >= CHIP_RST_RESET && + rst_status < CHIP_RST_POST_CB) + return 0; + + ret = osal_lock_sleepable_lock(&infra_ctx->core_lock); + if (ret) { + pr_err("core_lock fail!!"); + return 0; + } + + if (infra_ctx->infra_drv_status == DRV_STS_POWER_ON) + ret = consys_hw_reg_readable(); + osal_unlock_sleepable_lock(&infra_ctx->core_lock); + + return ret; +} + +int conninfra_core_reg_readable_no_lock(void) +{ + int rst_status; + unsigned long flag; + + /* check if in reseting, can not read */ + spin_lock_irqsave(&g_conninfra_ctx.rst_lock, flag); + rst_status = g_conninfra_ctx.rst_status; + spin_unlock_irqrestore(&g_conninfra_ctx.rst_lock, flag); + + if (rst_status >= CHIP_RST_RESET && + rst_status < CHIP_RST_POST_CB) + return 0; + + return consys_hw_reg_readable(); +} + +int conninfra_core_is_bus_hang(void) +{ + int ret = 0; + struct conninfra_ctx *infra_ctx = &g_conninfra_ctx; + + ret = osal_lock_sleepable_lock(&infra_ctx->core_lock); + if (ret) { + pr_err("core_lock fail!!"); + return 0; + } + + if (infra_ctx->infra_drv_status == DRV_STS_POWER_ON) + ret = consys_hw_is_bus_hang(); + osal_unlock_sleepable_lock(&infra_ctx->core_lock); + + return ret; + +} + +int conninfra_core_is_consys_reg(phys_addr_t addr) +{ + return consys_hw_is_connsys_reg(addr); +} + +int conninfra_core_reg_read(unsigned long address, unsigned int *value, unsigned int mask) +{ + int ret = 0; + struct conninfra_ctx *infra_ctx = &g_conninfra_ctx; + + ret = osal_lock_sleepable_lock(&infra_ctx->core_lock); + if (ret) { + pr_err("core_lock fail!!"); + return 0; + } + + if (infra_ctx->infra_drv_status == DRV_STS_POWER_ON) { + if (consys_reg_mng_is_host_csr(address)) + ret = consys_reg_mng_reg_read(address, value, mask); + else if (consys_hw_reg_readable()) + ret = consys_reg_mng_reg_read(address, value, mask); + else + pr_info("CR (%lx) is not readable\n", address); + } else + pr_info("CR (%lx) cannot read. conninfra is off\n", address); + + osal_unlock_sleepable_lock(&infra_ctx->core_lock); + return ret; +} + +int conninfra_core_reg_write(unsigned long address, unsigned int value, unsigned int mask) +{ + int ret = 0; + struct conninfra_ctx *infra_ctx = &g_conninfra_ctx; + + ret = osal_lock_sleepable_lock(&infra_ctx->core_lock); + if (ret) { + pr_err("core_lock fail!!"); + return 0; + } + + if (infra_ctx->infra_drv_status == DRV_STS_POWER_ON) { + if (consys_reg_mng_is_host_csr(address)) + ret = consys_reg_mng_reg_write(address, value, mask); + else if (consys_hw_reg_readable()) + ret = consys_reg_mng_reg_write(address, value, mask); + else + pr_info("CR (%p) is not readable\n", (void*)address); + } else + pr_info("CR (%p) cannot read. conninfra is off\n", (void*)address); + + osal_unlock_sleepable_lock(&infra_ctx->core_lock); + return ret; + +} + +int conninfra_core_lock_rst(void) +{ + struct conninfra_ctx *infra_ctx = &g_conninfra_ctx; + int ret = 0; + unsigned long flag; + + spin_lock_irqsave(&infra_ctx->rst_lock, flag); + + ret = infra_ctx->rst_status; + if (infra_ctx->rst_status > CHIP_RST_NONE && + infra_ctx->rst_status < CHIP_RST_DONE) { + /* do nothing */ + } else { + infra_ctx->rst_status = CHIP_RST_START; + } + spin_unlock_irqrestore(&infra_ctx->rst_lock, flag); + + pr_info("[%s] ret=[%d]", __func__, ret); + return ret; +} + +int conninfra_core_unlock_rst(void) +{ + unsigned long flag; + struct conninfra_ctx *infra_ctx = &g_conninfra_ctx; + + spin_lock_irqsave(&infra_ctx->rst_lock, flag); + infra_ctx->rst_status = CHIP_RST_NONE; + spin_unlock_irqrestore(&infra_ctx->rst_lock, flag); + return 0; +} + +int conninfra_core_trg_chip_rst(enum consys_drv_type drv, char *reason) +{ + int ret = 0; + struct conninfra_ctx *infra_ctx = &g_conninfra_ctx; + + infra_ctx->trg_drv = drv; + if (snprintf(infra_ctx->trg_reason, CHIP_RST_REASON_MAX_LEN, "%s", reason) < 0) + pr_warn("[%s::%d] snprintf error\n", __func__, __LINE__); + ret = msg_thread_send_1(&infra_ctx->cb_ctx, + CONNINFRA_CB_OPID_CHIP_RST, drv); + if (ret) { + pr_err("[%s] send msg fail, ret = %d", __func__, ret); + return -1; + } + pr_info("trg_reset DONE!"); + return 0; +} + +int conninfra_core_thermal_query(int *temp_val) +{ + int ret = 0; + struct conninfra_ctx *infra_ctx = &g_conninfra_ctx; + + ret = msg_thread_send_wait_1(&infra_ctx->msg_ctx, + CONNINFRA_OPID_THERM_CTRL, 0, + (size_t) temp_val); + if (ret) { + pr_err("send msg fail ret=%d\n", ret); + return ret; + } + pr_info("ret=[%d] temp=[%d]\n", ret, *temp_val); + return ret; +} + +void conninfra_core_clock_fail_dump_cb(void) +{ + int ret = 0; + struct conninfra_ctx *infra_ctx = &g_conninfra_ctx; + + ret = msg_thread_send(&infra_ctx->msg_ctx, + CONNINFRA_OPID_CLOCK_FAIL_DUMP); + if (ret) + pr_err("failed (ret = %d)", ret); +} + +static inline char* conninfra_core_spi_subsys_string(enum sys_spi_subsystem subsystem) +{ + static char* subsys_name[] = { + "SYS_SPI_WF1", + "SYS_SPI_WF", + "SYS_SPI_BT", + "SYS_SPI_FM", + "SYS_SPI_GPS", + "SYS_SPI_TOP", + "SYS_SPI_WF2", + "SYS_SPI_WF3", + "SYS_SPI_MAX" + }; + + if (subsystem < 0 || subsystem > SYS_SPI_MAX) + return "UNKNOWN"; + + return subsys_name[subsystem]; +} + +int conninfra_core_spi_read(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int *data) +{ + int ret = 0; + struct conninfra_ctx *infra_ctx = &g_conninfra_ctx; + size_t data_ptr = (size_t)data; + + ret = msg_thread_send_wait_3(&infra_ctx->msg_ctx, + CONNINFRA_OPID_RFSPI_READ, 0, + subsystem, addr, data_ptr); + if (ret) { + pr_err("[%s] failed (ret = %d). subsystem=%s addr=%x\n", + __func__, ret, conninfra_core_spi_subsys_string(subsystem), addr); + return CONNINFRA_SPI_OP_FAIL; + } + return 0; +} + +int conninfra_core_spi_write(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int data) +{ + int ret; + ret = msg_thread_send_wait_3(&(g_conninfra_ctx.msg_ctx), CONNINFRA_OPID_RFSPI_WRITE, 0, + subsystem, addr, data); + if (ret) { + pr_err("[%s] failed (ret = %d). subsystem=%s addr=0x%x data=%d\n", + __func__, ret, conninfra_core_spi_subsys_string(subsystem), addr, data); + return CONNINFRA_SPI_OP_FAIL; + } + return 0; +} + +int conninfra_core_adie_top_ck_en_on(enum consys_adie_ctl_type type) +{ + int ret = 0; + struct conninfra_ctx *infra_ctx = &g_conninfra_ctx; + + ret = msg_thread_send_wait_1(&infra_ctx->msg_ctx, + CONNINFRA_OPID_ADIE_TOP_CK_EN_ON, 0, type); + if (ret) { + pr_err("[%s] fail, ret = %d\n", __func__, ret); + return -1; + } + return 0; +} + +int conninfra_core_adie_top_ck_en_off(enum consys_adie_ctl_type type) +{ + int ret = 0; + struct conninfra_ctx *infra_ctx = &g_conninfra_ctx; + + ret = msg_thread_send_wait_1(&infra_ctx->msg_ctx, + CONNINFRA_OPID_ADIE_TOP_CK_EN_OFF, 0, type); + if (ret) { + pr_err("[%s] fail, ret = %d\n", __func__, ret); + return -1; + } + return 0; +} + +int conninfra_core_force_conninfra_wakeup(void) +{ + int ret = 0; + struct conninfra_ctx *infra_ctx = &g_conninfra_ctx; + + /* if in conninfra_cored thread */ + if (current == infra_ctx->msg_ctx.thread.pThread) + return opfunc_force_conninfra_wakeup(NULL); + + ret = msg_thread_send_wait(&infra_ctx->msg_ctx, + CONNINFRA_OPID_FORCE_CONNINFRA_WAKUP, 0); + if (ret) { + pr_err("[%s] fail, ret = %d\n", __func__, ret); + return -1; + } + return 0; +} + +int conninfra_core_force_conninfra_sleep(void) +{ + int ret = 0; + struct conninfra_ctx *infra_ctx = &g_conninfra_ctx; + + /* if in conninfra_cored thread */ + if (current == infra_ctx->msg_ctx.thread.pThread) + return opfunc_force_conninfra_sleep(NULL); + + ret = msg_thread_send_wait(&infra_ctx->msg_ctx, + CONNINFRA_OPID_FORCE_CONNINFRA_SLEEP, 0); + if (ret) { + pr_err("[%s] fail, ret = %d\n", __func__, ret); + return -1; + } + return 0; +} + +int conninfra_core_spi_clock_switch(enum connsys_spi_speed_type type) +{ + int ret = 0; + struct conninfra_ctx *infra_ctx = &g_conninfra_ctx; + + ret = msg_thread_send_wait_1(&infra_ctx->msg_ctx, + CONNINFRA_OPID_SPI_CLOCK_SWITCH, 0, type); + if (ret) { + pr_err("[%s] fail, ret = %d\n", __func__, ret); + return -1; + } + return 0; +} + +int conninfra_core_subsys_ops_reg(enum consys_drv_type type, + struct sub_drv_ops_cb *cb) +{ + unsigned long flag; + struct subsys_drv_inst *drv_inst; + struct conninfra_ctx *infra_ctx = &g_conninfra_ctx; + int ret, trigger_pre_cal = 0; + + if (type < CONNDRV_TYPE_BT || type >= CONNDRV_TYPE_MAX) + return -1; + + spin_lock_irqsave(&g_conninfra_ctx.infra_lock, flag); + drv_inst = &g_conninfra_ctx.drv_inst[type]; + memcpy(&g_conninfra_ctx.drv_inst[type].ops_cb, cb, + sizeof(struct sub_drv_ops_cb)); + + pr_info("[%s] [pre_cal] type=[%s] cb rst=[%p][%p] pre_cal=[%p][%p], therm=[%p]", + __func__, drv_name[type], + cb->rst_cb.pre_whole_chip_rst, cb->rst_cb.post_whole_chip_rst, + cb->pre_cal_cb.pwr_on_cb, cb->pre_cal_cb.do_cal_cb, cb->thermal_qry); + + pr_info("[%s] [pre_cal] type=[%d] bt=[%p] wf=[%p]", __func__, type, + infra_ctx->drv_inst[CONNDRV_TYPE_BT].ops_cb.pre_cal_cb.pwr_on_cb, + infra_ctx->drv_inst[CONNDRV_TYPE_WIFI].ops_cb.pre_cal_cb.pwr_on_cb); + + /* trigger pre-cal if BT and WIFI are registered */ + if (infra_ctx->drv_inst[CONNDRV_TYPE_BT].ops_cb.pre_cal_cb.do_cal_cb != NULL && + infra_ctx->drv_inst[CONNDRV_TYPE_WIFI].ops_cb.pre_cal_cb.do_cal_cb != NULL) + trigger_pre_cal = 1; + + spin_unlock_irqrestore(&g_conninfra_ctx.infra_lock, flag); + + if (trigger_pre_cal) { + pr_info("[%s] [pre_cal] trigger pre-cal BT/WF are registered", __func__); + ret = msg_thread_send_1(&infra_ctx->msg_ctx, + CONNINFRA_OPID_PRE_CAL_PREPARE, PRE_CAL_BY_SUBDRV_REGISTER); + if (ret) + pr_err("send pre_cal_prepare msg fail, ret = %d\n", ret); + } + + return 0; +} + +int conninfra_core_subsys_ops_unreg(enum consys_drv_type type) +{ + unsigned long flag; + + if (type < CONNDRV_TYPE_BT || type >= CONNDRV_TYPE_MAX) + return -1; + spin_lock_irqsave(&g_conninfra_ctx.infra_lock, flag); + memset(&g_conninfra_ctx.drv_inst[type].ops_cb, 0, + sizeof(struct sub_drv_ops_cb)); + spin_unlock_irqrestore(&g_conninfra_ctx.infra_lock, flag); + + return 0; +} + +#if ENABLE_PRE_CAL_BLOCKING_CHECK +void conninfra_core_pre_cal_blocking(void) +{ +#define BLOCKING_CHECK_MONITOR_THREAD 100 + int ret; + struct pre_cal_info *cal_info = &g_conninfra_ctx.cal_info; + struct timeval start, end; + unsigned long diff; + static bool ever_pre_cal = false; + + do_gettimeofday(&start); + + /* non-zero means lock got, zero means not */ + while (true) { + // Handle PRE_CAL_PWR_ON_DISABLED case: + // 1. Do pre-cal "only once" after bootup if BT or WIFI is default on + // 2. Use ever_pre_cal to check if the "first" pre-cal is already + // triggered. If yes, skip pre-cal + if (g_pre_cal_mode == PRE_CAL_PWR_ON_DISABLED && !ever_pre_cal) { + struct conninfra_ctx *infra_ctx = &g_conninfra_ctx; + + ret = msg_thread_send_1(&infra_ctx->msg_ctx, + CONNINFRA_OPID_PRE_CAL_PREPARE, PRE_CAL_BY_SUBDRV_PWR_ON); + ever_pre_cal = true; + pr_info("[%s] [pre_cal] Triggered by subdrv power on and set ever_pre_cal to true, result: %d", __func__, ret); + } + + ret = osal_trylock_sleepable_lock(&cal_info->pre_cal_lock); + if (ret) { + if (cal_info->status == PRE_CAL_NOT_INIT || + cal_info->status == PRE_CAL_SCHEDULED) { + pr_info("[%s] [pre_cal] ret=[%d] status=[%d]", __func__, ret, cal_info->status); + osal_unlock_sleepable_lock(&cal_info->pre_cal_lock); + osal_sleep_ms(100); + continue; + } + osal_unlock_sleepable_lock(&cal_info->pre_cal_lock); + break; + } else { + pr_info("[%s] [pre_cal] ret=[%d] status=[%d]", __func__, ret, cal_info->status); + osal_sleep_ms(100); + } + } + do_gettimeofday(&end); + + diff = timeval_to_ms(&start, &end); + if (diff > BLOCKING_CHECK_MONITOR_THREAD) + pr_info("blocking spent [%lu]", diff); +} +#endif + + +static void _conninfra_core_update_rst_status(enum chip_rst_status status) +{ + unsigned long flag; + + spin_lock_irqsave(&g_conninfra_ctx.rst_lock, flag); + g_conninfra_ctx.rst_status = status; + spin_unlock_irqrestore(&g_conninfra_ctx.rst_lock, flag); +} + + +int conninfra_core_is_rst_locking(void) +{ + unsigned long flag; + int ret = 0; + + spin_lock_irqsave(&g_conninfra_ctx.rst_lock, flag); + + if (g_conninfra_ctx.rst_status > CHIP_RST_NONE && + g_conninfra_ctx.rst_status < CHIP_RST_POST_CB) + ret = 1; + spin_unlock_irqrestore(&g_conninfra_ctx.rst_lock, flag); + return ret; +} + +static void conninfra_core_pre_cal_work_handler(struct work_struct *work) +{ + int ret; + + /* if fail, do we need re-try? */ + ret = conninfra_core_pre_cal_start(); + pr_info("[%s] [pre_cal][ret=%d] -----------", __func__, ret); +} + + +int conninfra_core_dump_power_state(void) +{ + int ret = 0; + struct conninfra_ctx *infra_ctx = &g_conninfra_ctx; + + ret = msg_thread_send(&infra_ctx->msg_ctx, + CONNINFRA_OPID_DUMP_POWER_STATE); + if (ret) { + pr_err("[%s] fail, ret = %d\n", __func__, ret); + return -1; + } + return 0; + +} + +void conninfra_core_config_setup(void) +{ + struct conninfra_ctx *infra_ctx = &g_conninfra_ctx; + int ret; + + ret = osal_lock_sleepable_lock(&infra_ctx->core_lock); + if (ret) { + pr_err("[%s] core_lock fail!!\n", __func__); + return; + } + + if (infra_ctx->infra_drv_status == DRV_STS_POWER_ON) + consys_hw_config_setup(); + + osal_unlock_sleepable_lock(&infra_ctx->core_lock); +} + +int conninfra_core_pmic_event_cb(unsigned int id, unsigned int event) +{ + struct conninfra_ctx *infra_ctx = &g_conninfra_ctx; + int ret; + + if (conninfra_core_is_rst_locking()) { + return 0; + } + + ret = osal_lock_sleepable_lock(&infra_ctx->core_lock); + if (ret) { + pr_err("[%s] core_lock fail!!\n", __func__); + return 0; + } + + if (infra_ctx->infra_drv_status == DRV_STS_POWER_ON) + consys_hw_pmic_event_cb(id, event); + + osal_unlock_sleepable_lock(&infra_ctx->core_lock); + + return 0; +} + +int conninfra_core_bus_clock_ctrl(enum consys_drv_type drv_type, unsigned int bus_clock, int status) +{ + int ret = -1, rst_status; + unsigned long flag; + struct conninfra_ctx *infra_ctx = &g_conninfra_ctx; + + /* check if in reseting, can not read */ + spin_lock_irqsave(&g_conninfra_ctx.rst_lock, flag); + rst_status = g_conninfra_ctx.rst_status; + spin_unlock_irqrestore(&g_conninfra_ctx.rst_lock, flag); + + if (rst_status >= CHIP_RST_RESET && + rst_status < CHIP_RST_POST_CB) + return -1; + + ret = osal_lock_sleepable_lock(&infra_ctx->core_lock); + if (ret) { + pr_err("[%s] core_lock fail!!", __func__); + return -1; + } + + if (infra_ctx->infra_drv_status == DRV_STS_POWER_ON) + ret = consys_hw_bus_clock_ctrl(drv_type, bus_clock, status); + osal_unlock_sleepable_lock(&infra_ctx->core_lock); + + return ret; +} + +int conninfra_core_init(void) +{ + int ret = 0, i; + struct conninfra_ctx *infra_ctx = &g_conninfra_ctx; + + // Get pre-cal mode + const struct conninfra_conf *conf = NULL; + conf = conninfra_conf_get_cfg(); + if (conf != NULL) { + g_pre_cal_mode = conf->pre_cal_mode; + } + pr_info("[%s] [pre_cal] Init g_pre_cal_mode = %u", __func__, g_pre_cal_mode); + + osal_memset(&g_conninfra_ctx, 0, sizeof(g_conninfra_ctx)); + + reset_chip_rst_trg_data(); + + spin_lock_init(&infra_ctx->infra_lock); + osal_sleepable_lock_init(&infra_ctx->core_lock); + spin_lock_init(&infra_ctx->rst_lock); + + + ret = msg_thread_init(&infra_ctx->msg_ctx, "conninfra_cored", + conninfra_core_opfunc, CONNINFRA_OPID_MAX); + if (ret) { + pr_err("msg_thread init fail(%d)\n", ret); + return -1; + } + + ret = msg_thread_init(&infra_ctx->cb_ctx, "conninfra_cb", + conninfra_core_cb_opfunc, CONNINFRA_CB_OPID_MAX); + if (ret) { + pr_err("callback msg thread init fail(%d)\n", ret); + return -1; + } + /* init subsys drv state */ + for (i = 0; i < CONNDRV_TYPE_MAX; i++) { + ret += msg_thread_init(&infra_ctx->drv_inst[i].msg_ctx, + drv_thread_name[i], infra_subdrv_opfunc, + INFRA_SUBDRV_OPID_MAX); + } + + if (ret) { + pr_err("subsys callback thread init fail.\n"); + return -1; + } + + INIT_WORK(&infra_ctx->cal_info.pre_cal_work, conninfra_core_pre_cal_work_handler); + osal_sleepable_lock_init(&infra_ctx->cal_info.pre_cal_lock); + + return ret; +} + + +int conninfra_core_deinit(void) +{ + int ret, i; + struct conninfra_ctx *infra_ctx = &g_conninfra_ctx; + + osal_sleepable_lock_deinit(&infra_ctx->cal_info.pre_cal_lock); + + for (i = 0; i < CONNDRV_TYPE_MAX; i++) { + ret = msg_thread_deinit(&infra_ctx->drv_inst[i].msg_ctx); + if (ret) + pr_warn("subdrv [%d] msg_thread deinit fail (%d)\n", + i, ret); + } + + ret = msg_thread_deinit(&infra_ctx->msg_ctx); + if (ret) { + pr_err("msg_thread_deinit fail(%d)\n", ret); + return -1; + } + + osal_sleepable_lock_deinit(&infra_ctx->core_lock); + //osal_sleepable_lock_deinit(&infra_ctx->rst_lock); + + return 0; +} + + + diff --git a/drivers/misc/mediatek/connectivity/conninfra/core/include/conninfra_core.h b/drivers/misc/mediatek/connectivity/conninfra/core/include/conninfra_core.h new file mode 100755 index 0000000000000000000000000000000000000000..82dc62bb05b97fe644bddc63c0ba03cba2ce7dce --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/core/include/conninfra_core.h @@ -0,0 +1,249 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#ifndef _CONNINFRA_CORE_H_ +#define _CONNINFRA_CORE_H_ + +#include +#include +#include +#include + +#include "osal.h" +#include "msg_thread.h" +#include "conninfra.h" + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +#define ENABLE_PRE_CAL_BLOCKING_CHECK 1 +#define CHIP_RST_REASON_MAX_LEN 128 + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ +typedef enum _ENUM_DRV_STS_ { + DRV_STS_POWER_OFF = 0, /* initial state */ + DRV_STS_POWER_ON = 1, /* powered on */ + DRV_STS_RESET = 2, + DRV_STS_MAX +} ENUM_DRV_STS, *P_ENUM_DRV_STS; + +enum pre_cal_status { + PRE_CAL_NOT_INIT = 0, + PRE_CAL_NEED_RESCHEDULE = 1, + PRE_CAL_SCHEDULED = 2, + PRE_CAL_EXECUTING = 3, + PRE_CAL_DONE = 4 +}; + +enum pre_cal_caller { + PRE_CAL_BY_NONE = 0, + PRE_CAL_BY_SUBDRV_REGISTER = 1, + PRE_CAL_BY_SUBDRV_PWR_ON = 2, + PRE_CAL_BY_SCREEN_ON = 3 +}; + +enum chip_rst_status { + CHIP_RST_NONE = 0, + CHIP_RST_START = 1, + CHIP_RST_PRE_CB = 2, + CHIP_RST_RESET = 3, + CHIP_RST_POST_CB = 4, + CHIP_RST_DONE = 5 +}; + +struct subsys_drv_inst { + ENUM_DRV_STS drv_status; /* Controlled driver status */ + unsigned int rst_state; + struct sub_drv_ops_cb ops_cb; + struct msg_thread_ctx msg_ctx; +}; + +struct pre_cal_info { + enum pre_cal_status status; + enum pre_cal_caller caller; + struct work_struct pre_cal_work; + OSAL_SLEEPABLE_LOCK pre_cal_lock; +}; + + +/* + * state of conninfra + * + */ +struct conninfra_ctx { + ENUM_DRV_STS infra_drv_status; + + struct subsys_drv_inst drv_inst[CONNDRV_TYPE_MAX]; + /*struct spinlock infra_lock;*/ + spinlock_t infra_lock; + + OSAL_SLEEPABLE_LOCK core_lock; + + /* chip reset */ + enum chip_rst_status rst_status; + spinlock_t rst_lock; + + struct semaphore rst_sema; + atomic_t rst_state; + enum consys_drv_type trg_drv; + char trg_reason[CHIP_RST_REASON_MAX_LEN]; + + /* pre_cal */ + struct semaphore pre_cal_sema; + atomic_t pre_cal_state; + + struct msg_thread_ctx msg_ctx; + struct msg_thread_ctx cb_ctx; + + unsigned int hw_ver; + unsigned int fw_ver; + unsigned int ip_ver; + + struct osal_op_history cored_op_history; + + struct pre_cal_info cal_info; + +}; + +//typedef enum _ENUM_CONNINFRA_CORE_OPID_T { +typedef enum { + CONNINFRA_OPID_PWR_ON = 0, + CONNINFRA_OPID_PWR_OFF = 1, + CONNINFRA_OPID_THERM_CTRL = 2, + CONNINFRA_OPID_RFSPI_READ = 5, + CONNINFRA_OPID_RFSPI_WRITE = 6, + CONNINFRA_OPID_ADIE_TOP_CK_EN_ON = 7, + CONNINFRA_OPID_ADIE_TOP_CK_EN_OFF = 8, + CONNINFRA_OPID_SPI_CLOCK_SWITCH = 9, + CONNINFRA_OPID_CLOCK_FAIL_DUMP = 10, + CONNINFRA_OPID_PRE_CAL_PREPARE = 11, + CONNINFRA_OPID_PRE_CAL_CHECK = 12, + CONNINFRA_OPID_FORCE_CONNINFRA_WAKUP = 13, + CONNINFRA_OPID_FORCE_CONNINFRA_SLEEP = 14, + CONNINFRA_OPID_DUMP_POWER_STATE = 15, + CONNINFRA_OPID_MAX +} conninfra_core_opid; + +/* For the operation which may callback subsys driver */ +typedef enum { + CONNINFRA_CB_OPID_CHIP_RST = 0, + CONNINFRA_CB_OPID_PRE_CAL = 1, + CONNINFRA_CB_OPID_MAX +} conninfra_core_cb_opid; + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +extern int conninfra_core_init(void); +extern int conninfra_core_deinit(void); + +int conninfra_core_power_on(enum consys_drv_type type); +int conninfra_core_power_off(enum consys_drv_type type); + +int conninfra_core_lock_rst(void); +int conninfra_core_unlock_rst(void); +int conninfra_core_trg_chip_rst(enum consys_drv_type drv, char *reason); + +int conninfra_core_subsys_ops_reg(enum consys_drv_type type, + struct sub_drv_ops_cb *cb); +int conninfra_core_subsys_ops_unreg(enum consys_drv_type type); + + +int conninfra_core_screen_on(void); +int conninfra_core_screen_off(void); + +/* pre_cal */ +int conninfra_core_pre_cal_start(void); +#if ENABLE_PRE_CAL_BLOCKING_CHECK +void conninfra_core_pre_cal_blocking(void); +#endif + +/* reg control */ +/* NOTE: NOT thread-safe + * return value + * 1 : Yes, 0: NO + */ +int conninfra_core_reg_readable(void); +int conninfra_core_reg_readable_no_lock(void); +int conninfra_core_is_bus_hang(void); + +int conninfra_core_is_consys_reg(phys_addr_t addr); +int conninfra_core_reg_read(unsigned long address, unsigned int *value, unsigned int mask); +int conninfra_core_reg_write(unsigned long address, unsigned int value, unsigned int mask); + +int conninfra_core_is_rst_locking(void); + +int conninfra_core_thermal_query(int *temp_val); +void conninfra_core_clock_fail_dump_cb(void); + +int conninfra_core_spi_read(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int *data); +int conninfra_core_spi_write(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int data); + +int conninfra_core_adie_top_ck_en_on(enum consys_adie_ctl_type type); +int conninfra_core_adie_top_ck_en_off(enum consys_adie_ctl_type type); + +int conninfra_core_force_conninfra_wakeup(void); +int conninfra_core_force_conninfra_sleep(void); + +int conninfra_core_spi_clock_switch(enum connsys_spi_speed_type type); + +int conninfra_core_dump_power_state(void); +int conninfra_core_pmic_event_cb(unsigned int, unsigned int); + +void conninfra_core_config_setup(void); + +int conninfra_core_bus_clock_ctrl(enum consys_drv_type drv_type, unsigned int bus_clock, int status); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _CONNINFRA_CORE_H_ */ diff --git a/drivers/misc/mediatek/connectivity/conninfra/debug_utility/conninfra_dbg.c b/drivers/misc/mediatek/connectivity/conninfra/debug_utility/conninfra_dbg.c new file mode 100644 index 0000000000000000000000000000000000000000..356569d930c10dfb26ee3ef34afa74690b3f45aa --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/debug_utility/conninfra_dbg.c @@ -0,0 +1,581 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +#include +#include +#include +#include "osal.h" +#include "conninfra_dbg.h" +#include "conninfra.h" +#include "conninfra_core.h" +#include "emi_mng.h" +#include "connsys_debug_utility.h" + +#define CONNINFRA_DBG_PROCNAME "driver/conninfra_dbg" + +#define BUF_LEN_MAX 384 + +#if (defined(CONFIG_MTK_GMO_RAM_OPTIMIZE) && !defined(CONFIG_MTK_ENG_BUILD)) +#define WMT_EMI_DEBUG_BUF_SIZE (8*1024) +#else +#define WMT_EMI_DEBUG_BUF_SIZE (32*1024) +#endif + +static struct proc_dir_entry *g_conninfra_dbg_entry; + +#if CONNINFRA_DBG_SUPPORT +static ssize_t conninfra_dbg_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos); +static ssize_t conninfra_dbg_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos); + +static int conninfra_dbg_hwver_get(int par1, int par2, int par3); + +static int conninfra_dbg_chip_rst(int par1, int par2, int par3); + +static int conninfra_dbg_read_chipid(int par1, int par2, int par3); + +static int conninfra_dbg_force_conninfra_wakeup(int par1, int par2, int par3); +static int conninfra_dbg_force_conninfra_sleep(int par1, int par2, int par3); + +static int conninfra_dbg_reg_read(int par1, int par2, int par3); +static int conninfra_dbg_reg_write(int par1, int par2, int par3); + +static int conninfra_dbg_efuse_read(int par1, int par2, int par3); +static int conninfra_dbg_efuse_write(int par1, int par2, int par3); + +static int conninfra_dbg_ap_reg_read(int par1, int par2, int par3); +static int conninfra_dbg_ap_reg_write(int par1, int par2, int par3); + + +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH +/* consys log, need this ?? */ +static int conninfra_dbg_set_fw_log_mode(int par1, int par2, int par3); +static int conninfra_dbg_fw_log_dump_emi(int par1, int offset, int size); +#endif + +static int conninfra_dbg_suspend_debug(int par1, int offset, int size); +static int conninfra_dbg_fw_log_ctrl(int par1, int onoff, int level); + +static int conninfra_dbg_thermal_query(int par1, int count, int interval); +static int conninfra_dbg_thermal_ctrl(int par1, int par2, int par3); + +static int conninfra_dbg_connsys_emi_dump(int par1, int par2, int par3); +#endif /* CONNINFRA_DBG_SUPPORT */ + +static int conninfra_dbg_connsys_coredump_ctrl(int par1, int par2, int par3); +static int conninfra_dbg_connsys_coredump_mode_query(int par1, int par2, int par3); + +static const CONNINFRA_DEV_DBG_FUNC conninfra_dev_dbg_func[] = { +#if CONNINFRA_DBG_SUPPORT + [0x0] = conninfra_dbg_hwver_get, + [0x1] = conninfra_dbg_chip_rst, + [0x2] = conninfra_dbg_read_chipid, + + [0x3] = conninfra_dbg_force_conninfra_wakeup, + [0x4] = conninfra_dbg_force_conninfra_sleep, + [0x5] = conninfra_dbg_reg_read, + [0x6] = conninfra_dbg_reg_write, + + [0x7] = conninfra_dbg_efuse_read, + [0x8] = conninfra_dbg_efuse_write, + [0x9] = conninfra_dbg_ap_reg_read, + [0xa] = conninfra_dbg_ap_reg_write, + + [0xb] = conninfra_dbg_fw_log_ctrl, + [0xc] = conninfra_dbg_thermal_query, + [0xd] = conninfra_dbg_thermal_ctrl, + + [0xf] = conninfra_dbg_suspend_debug, +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH + [0x10] = conninfra_dbg_set_fw_log_mode, + [0x11] = conninfra_dbg_fw_log_dump_emi, +#endif + [0x12] = conninfra_dbg_connsys_emi_dump, +#endif /* CONNINFRA_DBG_SUPPORT */ + [0x13] = conninfra_dbg_connsys_coredump_ctrl, + [0x14] = conninfra_dbg_connsys_coredump_mode_query, +}; + +#define CONNINFRA_DBG_DUMP_BUF_SIZE 1024 +char g_dump_buf[CONNINFRA_DBG_DUMP_BUF_SIZE]; +char *g_dump_buf_ptr; +int g_dump_buf_len; +static OSAL_SLEEPABLE_LOCK g_dump_lock; + +#if CONNINFRA_DBG_SUPPORT +int conninfra_dbg_hwver_get(int par1, int par2, int par3) +{ + pr_info("query chip version\n"); + /* TODO: */ + return 0; +} + +int conninfra_dbg_chip_rst(int par1, int par2, int par3) +{ + /* TODO: */ + conninfra_trigger_whole_chip_rst(CONNDRV_TYPE_BT, "Conninfra_dbg"); + return 0; +} + + +int conninfra_dbg_read_chipid(int par1, int par2, int par3) +{ + //pr_info("chip id = %d\n", wmt_lib_get_icinfo(WMTCHIN_CHIPID)); + + return 0; +} + +int conninfra_dbg_reg_read(int par1, int par2, int par3) +{ + int ret = 0, sz; + char buf[CONNINFRA_DBG_DUMP_BUF_SIZE]; + + /* par2-->register address */ + /* par3-->register mask */ + unsigned int value = 0x0; + int iRet; + + iRet = conninfra_core_reg_read(par2, &value, par3); + ret = snprintf(buf, CONNINFRA_DBG_DUMP_BUF_SIZE, + "read chip register (0x%08x) with mask (0x%08x) %s, value = 0x%08x\n", + par2, par3, iRet != 0 ? "failed" : "succeed", iRet != 0 ? -1 : value); + if (ret < 0) { + pr_info("read chip register (0x%08x) with mask (0x%08x) error(%d)\n", + par2, par3, ret); + } else + pr_info("%s", buf); + + + ret = osal_lock_sleepable_lock(&g_dump_lock); + if (ret) { + pr_err("dump_lock fail!!"); + return ret; + } + + if (g_dump_buf_len < CONNINFRA_DBG_DUMP_BUF_SIZE) { + sz = strlen(buf); + sz = (sz < CONNINFRA_DBG_DUMP_BUF_SIZE - g_dump_buf_len) ? + sz : CONNINFRA_DBG_DUMP_BUF_SIZE - g_dump_buf_len; + strncpy(g_dump_buf + g_dump_buf_len, buf, sz); + g_dump_buf_len += sz; + } + + osal_unlock_sleepable_lock(&g_dump_lock); + + return 0; +} + +int conninfra_dbg_reg_write(int par1, int par2, int par3) +{ + /* par2-->register address */ + /* par3-->value to set */ + int ret; + + ret = conninfra_core_reg_write(par2, par3, 0xffffffff); + pr_info("write chip register (0x%08x) with value (0x%08x) %s\n", + par2, par3, ret != 0 ? "failed" : "succeed"); + return 0; +} + + +int conninfra_dbg_force_conninfra_wakeup(int par1, int par2, int par3) +{ + int ret; + + ret = conninfra_core_force_conninfra_wakeup(); + if (ret) + pr_info("conninfra wakup fail\n"); + else + pr_info("conninfra wakup success\n"); + + return 0; +} + +int conninfra_dbg_force_conninfra_sleep(int par1, int par2, int par3) +{ + int ret; + + ret = conninfra_core_force_conninfra_sleep(); + if (ret) + pr_info("conninfra sleep fail\n"); + else + pr_info("conninfra sleep success\n"); + + return 0; +} + +int conninfra_dbg_efuse_read(int par1, int par2, int par3) +{ +#if 0 + /* par2-->efuse address */ + /* par3-->register mask */ + Uint value = 0x0; + Uint iRet = -1; + + iRet = wmt_lib_efuse_rw(0, par2, &value, par3); + pr_info("read combo chip efuse (0x%08x) with mask (0x%08x) %s, value = 0x%08x\n", + par2, par3, iRet != 0 ? "failed" : "succeed", iRet != 0 ? -1 : value); +#endif + return 0; +} + +int conninfra_dbg_efuse_write(int par1, int par2, int par3) +{ +#if 0 + /* par2-->efuse address */ + /* par3-->value to set */ + Uint iRet = -1; + + iRet = wmt_lib_efuse_rw(1, par2, &par3, 0xffffffff); + pr_info("write combo chip efuse (0x%08x) with value (0x%08x) %s\n", + par2, par3, iRet != 0 ? "failed" : "succeed"); +#endif + return 0; +} + + +static int conninfra_dbg_ap_reg_read(int par1, int par2, int par3) +{ + int value = 0x0; + unsigned char *ap_reg_base = NULL; + + pr_info("AP register read, reg address:0x%x\n", par2); + ap_reg_base = ioremap_nocache(par2, 0x4); + if (ap_reg_base) { + value = readl(ap_reg_base); + pr_info("AP register read, reg address:0x%x, value:0x%x\n", par2, value); + iounmap(ap_reg_base); + } else + pr_err("AP register ioremap fail!\n"); + + return 0; +} + +static int conninfra_dbg_ap_reg_write(int par1, int par2, int par3) +{ + int value = 0x0; + unsigned char *ap_reg_base = NULL; + + pr_info("AP register write, reg address:0x%x, value:0x%x\n", par2, par3); + + ap_reg_base = ioremap_nocache(par2, 0x4); + if (ap_reg_base) { + writel(par3, ap_reg_base); + value = readl(ap_reg_base); + pr_info("AP register write done, value after write:0x%x\n", value); + iounmap(ap_reg_base); + } else + pr_err("AP register ioremap fail!\n"); + + return 0; +} + +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH +static int conninfra_dbg_set_fw_log_mode(int par1, int par2, int par3) +{ + connsys_dedicated_log_set_log_mode(par2); + return 0; +} + +static int conninfra_dbg_fw_log_dump_emi(int par1, int offset, int size) +{ + //connsys_dedicated_log_dump_emi(offset, size); + return 0; +} +#endif + +/********************************************************/ +/* par2: */ +/* 0: Off */ +/* others: alarm time (seconds) */ +/********************************************************/ +static int conninfra_dbg_suspend_debug(int par1, int par2, int par3) +{ +#if 0 + if (par2 > 0) + connsys_log_alarm_enable(par2); + else + connsys_log_alarm_disable(); +#endif + return 0; +} + + +static int conninfra_dbg_fw_log_ctrl(int par1, int onoff, int level) +{ + /* Parameter format + * onoff: + * - bit 24~31: unused + * - bit 16~23: subsys type + * - bit 8~15 : unused + * - bit 0~7 : on/off setting + * level: only lowest 8 bites will be used. + * - bit 8~31 : unused + * - bit 0~7 : log level setting + * Example: + * 1. To turn on MCU log + * onoff = 0x0001 + * 2. To turn on Subsys Z log + * onoff = 0x0z01 (z = subsys) + * 3. To turn off Subsys Z log + * onoff = 0x0z00 (z = subsys) + */ +#if 0 + UINT8 type = (unsigned char)(onoff >> 16); + + pr_info("Configuring firmware log: type:%d, on/off:%d, level:%d\n", + type, (unsigned char)onoff, (unsigned char)level); + //wmt_lib_fw_log_ctrl(type, (unsigned char)onoff, (unsigned char)level); +#endif + return 0; +} + +int conninfra_dbg_thermal_query(int par1, int count, int interval) +{ + int temp, ret; + + ret = conninfra_core_thermal_query(&temp); + + pr_info("[Conninfra_Thermal_Query] ret=[%d] temp=[%d]", ret, temp); + + return 0; +} + +int conninfra_dbg_thermal_ctrl(int par1, int par2, int par3) +{ +#if 0 + if (par2 == 0) { + if (par3 >= 99) { + pr_info("Can`t set temp threshold greater or queal 99\n"); + return -1; + } + wmt_dev_set_temp_threshold(par3); + } +#endif + return 0; +} + +static int conninfra_dbg_connsys_emi_dump(int par1, int par2, int par3) +{ + unsigned int start; + // make size 16-byte alignment + int size = (((par3 + 15) >> 4) << 4); + void __iomem *vir_addr = NULL; + char* buf = NULL; + struct consys_emi_addr_info* addr_info = emi_mng_get_phy_addr(); + int i; + + if (par2 & 0xf) { + pr_err("EMI dump fail: wrong offset(0x%x), should be 16-byte alignment\n", par2); + return -1; + } + + start = (unsigned int)(par2 + addr_info->emi_ap_phy_addr); + + buf = (char*)osal_malloc(sizeof(char)*size); + if (buf == NULL) { + pr_err("[%s] allocate buffer fail\n", __func__); + return -1; + } + + pr_info("EMI dump, offset=0x%x(physical addr=0x%x), size=0x%x\n", par2, start, size); + vir_addr = ioremap_nocache(start, size); + if (!vir_addr) { + pr_err("ioremap fail"); + osal_free(buf); + return -1; + } + memcpy_fromio(buf, vir_addr, size); + for (i = 0; i < size; i+= 16) { + pr_info( + "EMI[0x%x]: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", + par2 + i, + buf[i + 0], buf[i + 1], buf[i + 2], buf[i + 3], + buf[i + 4], buf[i + 5], buf[i + 6], buf[i + 7], + buf[i + 8], buf[i + 9], buf[i + 0xa], buf[i + 0xb], + buf[i + 0xc], buf[i + 0xd], buf[i + 0xe], buf[i + 0xf]); + } + + iounmap(vir_addr); + osal_free(buf); + return 0; +} +#endif /* CONNINFRA_DBG_SUPPORT */ + +static int conninfra_dbg_connsys_coredump_ctrl(int par1, int par2, int par3) +{ + unsigned int orig_mode = connsys_coredump_get_mode(); + + pr_info("Setup coredump mode from %d to %d\n", orig_mode, par2); + connsys_coredump_set_dump_mode(par2); + return 0; +} + +static int conninfra_dbg_connsys_coredump_mode_query(int par1, int par2, int par3) +{ + unsigned int orig_mode = connsys_coredump_get_mode(); + + pr_info("Connsys coredump mode is [%d]\n", orig_mode); + return orig_mode; +} + +ssize_t conninfra_dbg_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) +{ + int ret = 0; + int dump_len; + + ret = osal_lock_sleepable_lock(&g_dump_lock); + if (ret) { + pr_err("dump_lock fail!!"); + return ret; + } + + if (g_dump_buf_len == 0) + goto exit; + + if (*f_pos == 0) + g_dump_buf_ptr = g_dump_buf; + + dump_len = g_dump_buf_len >= count ? count : g_dump_buf_len; + ret = copy_to_user(buf, g_dump_buf_ptr, dump_len); + if (ret) { + pr_err("copy to dump info buffer failed, ret:%d\n", ret); + ret = -EFAULT; + goto exit; + } + + *f_pos += dump_len; + g_dump_buf_len -= dump_len; + g_dump_buf_ptr += dump_len; + pr_info("conninfra_dbg:after read,wmt for dump info buffer len(%d)\n", g_dump_buf_len); + + ret = dump_len; +exit: + + osal_unlock_sleepable_lock(&g_dump_lock); + return ret; +} + +ssize_t conninfra_dbg_write(struct file *filp, const char __user *buffer, size_t count, loff_t *f_pos) +{ + size_t len = count; + char buf[256]; + char* pBuf; + int x = 0, y = 0, z = 0; + char* pToken = NULL; + char* pDelimiter = " \t"; + long res = 0; + static char dbg_enabled; + + pr_info("write parameter len = %d\n\r", (int) len); + if (len >= osal_sizeof(buf)) { + pr_err("input handling fail!\n"); + len = osal_sizeof(buf) - 1; + return -1; + } + + if (copy_from_user(buf, buffer, len)) + return -EFAULT; + + buf[len] = '\0'; + pr_info("write parameter data = %s\n\r", buf); + + pBuf = buf; + pToken = osal_strsep(&pBuf, pDelimiter); + if (pToken != NULL) { + osal_strtol(pToken, 16, &res); + x = (int)res; + } else { + x = 0; + } + + pToken = osal_strsep(&pBuf, "\t\n "); + if (pToken != NULL) { + osal_strtol(pToken, 16, &res); + y = (int)res; + pr_info("y = 0x%08x\n\r", y); + } else { + y = 3000; + /*efuse, register read write default value */ + if (0x5 == x || 0x6 == x) + y = 0x80000000; + } + + pToken = osal_strsep(&pBuf, "\t\n "); + if (pToken != NULL) { + osal_strtol(pToken, 16, &res); + z = (int)res; + } else { + z = 10; + /*efuse, register read write default value */ + if (0x5 == x || 0x6 == x) + z = 0xffffffff; + } + + pr_info("x(0x%08x), y(0x%08x), z(0x%08x)\n\r", x, y, z); + + /* For eng and userdebug load, have to enable wmt_dbg by writing 0xDB9DB9 to + * "/proc/driver/wmt_dbg" to avoid some malicious use + */ +#if CONNINFRA_DBG_SUPPORT + if (0xDB9DB9 == x) { + dbg_enabled = 1; + return len; + } +#endif + /* For user load, only 0x13 is allowed to execute */ + /* allow command 0x2e to enable catch connsys log on userload */ + if (0 == dbg_enabled && (x != 0x13) && (x != 0x14)) { + pr_info("please enable conninfra debug first\n\r"); + return len; + } + + if (osal_array_size(conninfra_dev_dbg_func) > x && NULL != conninfra_dev_dbg_func[x]) + (*conninfra_dev_dbg_func[x]) (x, y, z); + else + pr_warn("no handler defined for command id(0x%08x)\n\r", x); + + return len; +} + +int conninfra_dev_dbg_init(void) +{ + static const struct file_operations conninfra_dbg_fops = { + .owner = THIS_MODULE, + .read = conninfra_dbg_read, + .write = conninfra_dbg_write, + }; + int i_ret = 0; + + g_conninfra_dbg_entry = proc_create(CONNINFRA_DBG_PROCNAME, 0664, NULL, &conninfra_dbg_fops); + if (g_conninfra_dbg_entry == NULL) { + pr_err("Unable to create / wmt_aee proc entry\n\r"); + i_ret = -1; + } + + osal_sleepable_lock_init(&g_dump_lock); + + return i_ret; +} + +int conninfra_dev_dbg_deinit(void) +{ + osal_sleepable_lock_deinit(&g_dump_lock); + + if (g_conninfra_dbg_entry != NULL) { + proc_remove(g_conninfra_dbg_entry); + g_conninfra_dbg_entry = NULL; + } + + return 0; +} diff --git a/drivers/misc/mediatek/connectivity/conninfra/debug_utility/conninfra_dbg.h b/drivers/misc/mediatek/connectivity/conninfra/debug_utility/conninfra_dbg.h new file mode 100644 index 0000000000000000000000000000000000000000..c06b8c6092243d0e8f2396fd2210e1c24ae1d3e0 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/debug_utility/conninfra_dbg.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef _CONNINFRA_DBG_H_ +#define _CONNINFRA_DBG_H_ +#include "osal.h" + +typedef int(*CONNINFRA_DEV_DBG_FUNC) (int par1, int par2, int par3); +int conninfra_dev_dbg_init(void); +int conninfra_dev_dbg_deinit(void); + +#endif /* _CONNINFRA_DBG_H_ */ diff --git a/drivers/misc/mediatek/connectivity/conninfra/debug_utility/connsyslog/connsyslog.c b/drivers/misc/mediatek/connectivity/conninfra/debug_utility/connsyslog/connsyslog.c new file mode 100644 index 0000000000000000000000000000000000000000..eac87ed21ac0f87fb06a19d24e79c503bc26b996 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/debug_utility/connsyslog/connsyslog.c @@ -0,0 +1,1302 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include +#include +#include +#include +#include +#include +#include + +#include "connsyslog.h" +#include "connsyslog_emi.h" +#include "connsyslog_hw_config.h" +#include "ring.h" +#include "ring_emi.h" + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/* Close debug log */ +//#define DEBUG_RING 1 + +#define CONNLOG_ALARM_STATE_DISABLE 0x0 +#define CONNLOG_ALARM_STATE_ENABLE 0x01 +#define CONNLOG_ALARM_STATE_RUNNING 0x03 + +#define BYETES_PER_LINE 16 +#define LOG_LINE_SIZE (3*BYETES_PER_LINE + BYETES_PER_LINE + 1) +#define IS_VISIBLE_CHAR(c) ((c) >= 32 && (c) <= 126) + +#define LOG_MAX_LEN 1024 +#define LOG_HEAD_LENG 16 +#define TIMESYNC_LENG 40 + +static const char log_head[] = {0x55, 0x00, 0x00, 0x62}; +static const char timesync_head[] = {0x55, 0x00, 0x25, 0x62}; + +struct connlog_alarm { + struct alarm alarm_timer; + unsigned int alarm_state; + unsigned int blank_state; + unsigned int alarm_sec; + spinlock_t alarm_lock; + unsigned long flags; +}; + +struct connlog_offset { + unsigned int emi_base_offset; + unsigned int emi_size; + unsigned int emi_read; + unsigned int emi_write; + unsigned int emi_buf; + unsigned int emi_guard_pattern_offset; +}; + +struct connlog_buffer { + struct ring_emi ring_emi; + struct ring ring_cache; + void *cache_base; +}; + +struct connlog_event_cb { + CONNLOG_EVENT_CB log_data_handler; +}; + +struct connlog_dev { + int conn_type; + phys_addr_t phyAddrEmiBase; + unsigned int emi_size; + void __iomem *virAddrEmiLogBase; + struct connlog_offset log_offset; + struct connlog_buffer log_buffer; + bool eirqOn; + spinlock_t irq_lock; + unsigned long flags; + unsigned int irq_counter; + struct timer_list workTimer; + struct work_struct logDataWorker; + void *log_data; + char log_line[LOG_MAX_LEN]; + struct connlog_event_cb callback; +}; + +static char *type_to_title[CONN_DEBUG_TYPE_END] = { + "wifi_fw", "bt_fw" +}; + +static struct connlog_dev* gLogDev[CONN_DEBUG_TYPE_END]; + +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH +static atomic_t g_log_mode = ATOMIC_INIT(LOG_TO_FILE); +#else +static atomic_t g_log_mode = ATOMIC_INIT(PRINT_TO_KERNEL_LOG); +#endif + +static phys_addr_t gPhyEmiBase; + +/* alarm timer for suspend */ +struct connlog_alarm gLogAlarm; + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +static void connlog_do_schedule_work(struct connlog_dev* handler, bool count); +static void work_timer_handler(unsigned long data); +static void connlog_event_set(struct connlog_dev* handler); +static struct connlog_dev* connlog_subsys_init( + int conn_type, + phys_addr_t emiaddr, + unsigned int emi_size); +static void connlog_subsys_deinit(struct connlog_dev* handler); +static ssize_t connlog_read_internal( + struct connlog_dev* handler, int conn_type, + char *buf, char __user *userbuf, size_t count, bool to_user); +static void connlog_dump_emi(struct connlog_dev* handler, int offset, int size); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +struct connlog_emi_config* __weak get_connsyslog_platform_config(int conn_type) +{ + pr_err("Miss platform ops !!\n"); + return NULL; +} + +void *connlog_cache_allocate(size_t size) +{ + void *pBuffer = NULL; + + if (size > (PAGE_SIZE << 1)) + pBuffer = vmalloc(size); + else + pBuffer = kmalloc(size, GFP_KERNEL); + + /* If there is fragment, kmalloc may not get memory when size > one page. + * For this case, use vmalloc instead. + */ + if (pBuffer == NULL && size > PAGE_SIZE) + pBuffer = vmalloc(size); + + return pBuffer; +} + +void connlog_cache_free(const void *dst) +{ + kvfree(dst); +} + +/***************************************************************************** + * FUNCTION + * connlog_event_set + * DESCRIPTION + * Trigger event call back to wakeup waitqueue + * PARAMETERS + * conn_type [IN] subsys type + * RETURNS + * void + *****************************************************************************/ +static void connlog_event_set(struct connlog_dev* handler) +{ + if (handler->callback.log_data_handler) + handler->callback.log_data_handler(); +} + + +/***************************************************************************** +* FUNCTION +* connlog_set_ring_ready +* DESCRIPTION +* set reserved bit be EMIFWLOG to indicate that init is ready. +* PARAMETERS +* void +* RETURNS +* void +*****************************************************************************/ +static void connlog_set_ring_ready(struct connlog_dev* handler) +{ + const char ready_str[] = "EMIFWLOG"; + + memcpy_toio(handler->virAddrEmiLogBase + CONNLOG_READY_PATTERN_BASE, + ready_str, CONNLOG_READY_PATTERN_BASE_SIZE); +} + +static unsigned int connlog_cal_log_size(unsigned int emi_size) +{ + int position; + int i; + + if (emi_size > 0) { + for (i = (emi_size >> 1), position = 0; i != 0; ++position) + i >>= 1; + } else { + return 0; + } + + return (1UL << position); +} + +static int connlog_emi_init(struct connlog_dev* handler, phys_addr_t emiaddr, unsigned int emi_size) +{ + int conn_type = handler->conn_type; + unsigned int cal_log_size = connlog_cal_log_size( + emi_size - CONNLOG_EMI_BASE_OFFSET - CONNLOG_EMI_END_PATTERN_SIZE); + + if (emiaddr == 0 || cal_log_size == 0) { + pr_err("[%s] consys emi memory address invalid emi_addr=%p emi_size=%d\n", + type_to_title[conn_type], emiaddr, emi_size); + return -1; + } + pr_info("input size = %d cal_size = %d\n", emi_size, cal_log_size); + + handler->phyAddrEmiBase = emiaddr; + handler->emi_size = emi_size; + handler->virAddrEmiLogBase = ioremap_nocache(handler->phyAddrEmiBase, emi_size); + handler->log_offset.emi_base_offset = CONNLOG_EMI_BASE_OFFSET; + handler->log_offset.emi_size = cal_log_size; + handler->log_offset.emi_read = CONNLOG_EMI_READ; + handler->log_offset.emi_write = CONNLOG_EMI_WRITE; + handler->log_offset.emi_buf = CONNLOG_EMI_BUF; + handler->log_offset.emi_guard_pattern_offset = handler->log_offset.emi_buf + handler->log_offset.emi_size; + + if (handler->virAddrEmiLogBase) { + pr_info("[%s] EMI mapping OK virtual(0x%p) physical(0x%x) size=%d\n", + type_to_title[conn_type], + handler->virAddrEmiLogBase, + (unsigned int)handler->phyAddrEmiBase, + handler->emi_size); + /* Clean it */ + memset_io(handler->virAddrEmiLogBase, 0xff, handler->emi_size); + /* Clean control block as 0 */ + memset_io(handler->virAddrEmiLogBase + CONNLOG_EMI_BASE_OFFSET, 0x0, CONNLOG_EMI_32_BYTE_ALIGNED); + /* Setup henader */ + EMI_WRITE32(handler->virAddrEmiLogBase + 0, handler->log_offset.emi_base_offset); + EMI_WRITE32(handler->virAddrEmiLogBase + 4, handler->log_offset.emi_size); + /* Setup end pattern */ + memcpy_toio( + handler->virAddrEmiLogBase + handler->log_offset.emi_guard_pattern_offset, + CONNLOG_EMI_END_PATTERN, CONNLOG_EMI_END_PATTERN_SIZE); + } else { + pr_err("[%s] EMI mapping fail\n", type_to_title[conn_type]); + return -1; + } + + return 0; +} + +/***************************************************************************** +* FUNCTION +* connlog_emi_deinit +* DESCRIPTION +* Do iounmap for log buffer on EMI +* PARAMETERS +* void +* RETURNS +* void +*****************************************************************************/ +static void connlog_emi_deinit(struct connlog_dev* handler) +{ + iounmap(handler->virAddrEmiLogBase); +} + +static int connlog_buffer_init(struct connlog_dev* handler) +{ + void *pBuffer = NULL; + + /* Init ring emi */ + ring_emi_init( + handler->virAddrEmiLogBase + handler->log_offset.emi_buf, + handler->log_offset.emi_size, + handler->virAddrEmiLogBase + handler->log_offset.emi_read, + handler->virAddrEmiLogBase + handler->log_offset.emi_write, + &handler->log_buffer.ring_emi); + + /* init ring cache */ + /* TODO: use emi size. Need confirm */ + pBuffer = connlog_cache_allocate(handler->emi_size); + if (pBuffer == NULL) { + pr_info("[%s] allocate cache fail.", __func__); + return -ENOMEM; + } + + handler->log_buffer.cache_base = pBuffer; + memset(handler->log_buffer.cache_base, 0, handler->emi_size); + ring_init( + handler->log_buffer.cache_base, + handler->log_offset.emi_size, + 0, + 0, + &handler->log_buffer.ring_cache); + + return 0; +} + +static int connlog_ring_buffer_init(struct connlog_dev* handler) +{ + void *pBuffer = NULL; + if (!handler->virAddrEmiLogBase) { + pr_err("[%s] consys emi memory address phyAddrEmiBase invalid\n", + type_to_title[handler->conn_type]); + return -1; + } + connlog_buffer_init(handler); + /* TODO: use emi size. Need confirm */ + pBuffer = connlog_cache_allocate(handler->emi_size); + if (pBuffer == NULL) { + pr_info("[%s] allocate ring buffer fail.", __func__); + return -ENOMEM; + } + handler->log_data = pBuffer; + connlog_set_ring_ready(handler); + return 0; +} + +/***************************************************************************** +* FUNCTION +* connlog_ring_buffer_deinit +* DESCRIPTION +* Initialize ring buffer setting for subsys +* PARAMETERS +* void +* RETURNS +* void +*****************************************************************************/ +static void connlog_ring_buffer_deinit(struct connlog_dev* handler) +{ + if (handler->log_buffer.cache_base) { + connlog_cache_free(handler->log_buffer.cache_base); + handler->log_buffer.cache_base = NULL; + } + + if (handler->log_data) { + connlog_cache_free(handler->log_data); + handler->log_data = NULL; + } +} + +/***************************************************************************** +* FUNCTION +* work_timer_handler +* DESCRIPTION +* IRQ is still on, do schedule_work again +* PARAMETERS +* data [IN] input data +* RETURNS +* void +*****************************************************************************/ +static void work_timer_handler(unsigned long data) +{ + struct connlog_dev* handler = (struct connlog_dev*)data; + connlog_do_schedule_work(handler, false); +} + +/***************************************************************************** +* FUNCTION +* connlog_dump_buf +* DESCRIPTION +* Dump EMI content. Output format: +* xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx ................ +* 3 digits hex * 16 + 16 single char + 1 NULL terminate = 64+1 bytes +* PARAMETERS +* +* RETURNS +* void +*****************************************************************************/ +void connsys_log_dump_buf(const char *title, const char *buf, ssize_t sz) +{ + int i; + char line[LOG_LINE_SIZE]; + + i = 0; + line[LOG_LINE_SIZE-1] = 0; + while (sz--) { + snprintf(line + i*3, 3, "%02x", *buf); + line[i*3 + 2] = ' '; + + if (IS_VISIBLE_CHAR(*buf)) + line[3*BYETES_PER_LINE + i] = *buf; + else + line[3*BYETES_PER_LINE + i] = '`'; + + i++; + buf++; + + if (i >= BYETES_PER_LINE || !sz) { + if (i < BYETES_PER_LINE) { + memset(line+i*3, ' ', (BYETES_PER_LINE-i)*3); + memset(line+3*BYETES_PER_LINE+i, '.', BYETES_PER_LINE-i); + } + pr_info("%s: %s\n", title, line); + i = 0; + } + } +} +EXPORT_SYMBOL(connsys_log_dump_buf); + +/***************************************************************************** +* FUNCTION +* connlog_dump_emi +* DESCRIPTION +* dump EMI buffer for debug. +* PARAMETERS +* offset [IN] buffer offset +* size [IN] dump buffer size +* RETURNS +* void +*****************************************************************************/ +void connlog_dump_emi(struct connlog_dev* handler, int offset, int size) +{ + char title[100]; + memset(title, 0, 100); + sprintf(title, "%s(%p)", "emi", handler->virAddrEmiLogBase + offset); + connsys_log_dump_buf(title, handler->virAddrEmiLogBase + offset, size); +} + +/***************************************************************************** +* FUNCTION +* connlog_ring_emi_check +* DESCRIPTION +* +* PARAMETERS +* +* RETURNS +* void +*****************************************************************************/ +static bool connlog_ring_emi_check(struct connlog_dev* handler) +{ + struct ring_emi *ring_emi = &handler->log_buffer.ring_emi; + char line[CONNLOG_EMI_END_PATTERN_SIZE + 1]; + + memcpy_fromio( + line, + handler->virAddrEmiLogBase + handler->log_offset.emi_guard_pattern_offset, + CONNLOG_EMI_END_PATTERN_SIZE); + line[CONNLOG_EMI_END_PATTERN_SIZE] = '\0'; + + /* Check ring_emi buffer memory. Dump EMI data if it is corruption. */ + if (EMI_READ32(ring_emi->read) > handler->log_offset.emi_size || + EMI_READ32(ring_emi->write) > handler->log_offset.emi_size || + strncmp(line, CONNLOG_EMI_END_PATTERN, CONNLOG_EMI_END_PATTERN_SIZE) != 0) { + pr_err("[connlog] %s out of bound or guard pattern overwrited. Read(pos=%p)=[0x%x] write(pos=%p)=[0x%x] size=[0x%x]\n", + type_to_title[handler->conn_type], + ring_emi->read, EMI_READ32(ring_emi->read), + ring_emi->write, EMI_READ32(ring_emi->write), + handler->log_offset.emi_size); + connlog_dump_emi(handler, 0x0, 0x60); + connlog_dump_emi(handler, CONNLOG_EMI_BASE_OFFSET, 0x20); + connlog_dump_emi( + handler, + handler->log_offset.emi_guard_pattern_offset, + CONNLOG_EMI_END_PATTERN_SIZE); + return false; + } + + return true; +} + +/***************************************************************************** +* FUNCTION +* connlog_ring_emi_to_cache +* DESCRIPTION +* +* PARAMETERS +* +* RETURNS +* void +*****************************************************************************/ +static void connlog_ring_emi_to_cache(struct connlog_dev* handler) +{ + struct ring_emi_segment ring_emi_seg; + struct ring_emi *ring_emi = &handler->log_buffer.ring_emi; + struct ring *ring_cache = &handler->log_buffer.ring_cache; + int total_size = 0; + int count = 0; + unsigned int cache_max_size = 0; +#ifndef DEBUG_LOG_ON + static DEFINE_RATELIMIT_STATE(_rs, 10 * HZ, 1); + static DEFINE_RATELIMIT_STATE(_rs2, HZ, 1); +#endif + + if (RING_FULL(ring_cache)) { + #ifndef DEBUG_LOG_ON + if (__ratelimit(&_rs)) + #endif + pr_warn("[connlog] %s cache is full.\n", type_to_title[handler->conn_type]); + return; + } + + cache_max_size = RING_WRITE_REMAIN_SIZE(ring_cache); + if (RING_EMI_EMPTY(ring_emi) || !ring_emi_read_prepare(cache_max_size, &ring_emi_seg, ring_emi)) { + #ifndef DEBUG_LOG_ON + if(__ratelimit(&_rs)) + #endif + pr_err("[connlog] %s no data.\n", type_to_title[handler->conn_type]); + return; + } + + /* Check ring_emi buffer memory. Dump EMI data if it is corruption. */ + if (connlog_ring_emi_check(handler) == false) { + pr_err("[connlog] %s emi check fail\n", type_to_title[handler->conn_type]); + /* TODO: trigger assert by callback? */ + return; + } + + RING_EMI_READ_ALL_FOR_EACH(ring_emi_seg, ring_emi) { + struct ring_segment ring_cache_seg; + unsigned int emi_buf_size = ring_emi_seg.sz; + unsigned int written = 0; + +#ifdef DEBUG_RING + ring_emi_dump(__func__, ring_emi); + ring_emi_dump_segment(__func__, &ring_emi_seg); +#endif + RING_WRITE_FOR_EACH(ring_emi_seg.sz, ring_cache_seg, &handler->log_buffer.ring_cache) { +#ifdef DEBUG_RING + ring_dump(__func__, &handler->log_buffer.ring_cache); + ring_dump_segment(__func__, &ring_cache_seg); +#endif + #ifndef DEBUG_LOG_ON + if (__ratelimit(&_rs2)) + #endif + pr_info("%s: ring_emi_seg.sz=%d, ring_cache_pt=%p, ring_cache_seg.sz=%d\n", + type_to_title[handler->conn_type], ring_emi_seg.sz, ring_cache_seg.ring_pt, + ring_cache_seg.sz); + memcpy_fromio(ring_cache_seg.ring_pt, ring_emi_seg.ring_emi_pt + ring_cache_seg.data_pos, + ring_cache_seg.sz); + emi_buf_size -= ring_cache_seg.sz; + written += ring_cache_seg.sz; + } + + total_size += ring_emi_seg.sz; + count++; + } +} + + +/***************************************************************************** + * FUNCTION + * connlog_fw_log_parser + * DESCRIPTION + * Parse fw log and print to kernel + * PARAMETERS + * conn_type [IN] log type + * buf [IN] buffer to prase + * sz [IN] buffer size + * RETURNS + * void + *****************************************************************************/ +static void connlog_fw_log_parser(struct connlog_dev* handler, ssize_t sz) +{ + unsigned int systime = 0; + unsigned int utc_s = 0; + unsigned int utc_us = 0; + unsigned int buf_len = 0; + unsigned int print_len = 0; + char* log_line = handler->log_line; + const char* buf = handler->log_data; + int conn_type = handler->conn_type; + + while (sz > LOG_HEAD_LENG) { + if (*buf == log_head[0]) { + if (!memcmp(buf, log_head, sizeof(log_head))) { + buf_len = buf[14] + (buf[15] << 8); + print_len = buf_len >= LOG_MAX_LEN ? LOG_MAX_LEN - 1 : buf_len; + memcpy(log_line, buf + LOG_HEAD_LENG, print_len); + log_line[print_len] = 0; + pr_info("%s: %s\n", type_to_title[conn_type], log_line); + sz -= (LOG_HEAD_LENG + buf_len); + buf += (LOG_HEAD_LENG + buf_len); + continue; + } else if (sz >= TIMESYNC_LENG && + !memcmp(buf, timesync_head, sizeof(timesync_head))) { + memcpy(&systime, buf + 28, sizeof(systime)); + memcpy(&utc_s, buf + 32, sizeof(utc_s)); + memcpy(&utc_us, buf + 36, sizeof(utc_us)); + pr_info("%s: timesync : (%u) %u.%06u\n", + type_to_title[conn_type], systime, utc_s, utc_us); + sz -= TIMESYNC_LENG; + buf += TIMESYNC_LENG; + continue; + } + } + sz--; + buf++; + } +} + +/***************************************************************************** + * FUNCTION + * connlog_ring_print + * DESCRIPTION + * print log data on kernel log + * PARAMETERS + * handler [IN] log handler + * RETURNS + * void + *****************************************************************************/ +static void connlog_ring_print(struct connlog_dev* handler) +{ + unsigned int written = 0; + unsigned int buf_size; + struct ring_emi_segment ring_emi_seg; + struct ring_emi *ring_emi = &handler->log_buffer.ring_emi; + int conn_type = handler->conn_type; + + if (RING_EMI_EMPTY(ring_emi) || !ring_emi_read_all_prepare(&ring_emi_seg, ring_emi)) { + pr_err("type(%s) no data, possibly taken by concurrent reader.\n", type_to_title[conn_type]); + return; + } + buf_size = ring_emi_seg.remain; + memset(handler->log_data, 0, handler->emi_size); + + /* Check ring_emi buffer memory. Dump EMI data if it is corruption. */ + if (connlog_ring_emi_check(handler) == false) { + pr_err("[connlog] %s emi check fail\n", type_to_title[handler->conn_type]); + /* TODO: trigger assert by callback? */ + return; + } + + RING_EMI_READ_ALL_FOR_EACH(ring_emi_seg, ring_emi) { + memcpy_fromio(handler->log_data + written, ring_emi_seg.ring_emi_pt, ring_emi_seg.sz); + buf_size -= ring_emi_seg.sz; + written += ring_emi_seg.sz; + } + + if (conn_type != CONN_DEBUG_TYPE_BT) + connlog_fw_log_parser(handler, written); +} + +/***************************************************************************** +* FUNCTION +* connlog_log_data_handler +* DESCRIPTION +* +* PARAMETERS +* +* RETURNS +* void +*****************************************************************************/ +static void connlog_log_data_handler(struct work_struct *work) +{ + struct connlog_dev* handler = + container_of(work, struct connlog_dev, logDataWorker); +#ifndef DEBUG_LOG_ON + static DEFINE_RATELIMIT_STATE(_rs, 10 * HZ, 1); + static DEFINE_RATELIMIT_STATE(_rs2, 2 * HZ, 1); +#endif + + if (!RING_EMI_EMPTY(&handler->log_buffer.ring_emi)) { + if (atomic_read(&g_log_mode) == LOG_TO_FILE) + connlog_ring_emi_to_cache(handler); + else + connlog_ring_print(handler); + connlog_event_set(handler); + } else { +#ifndef DEBUG_LOG_ON + if (__ratelimit(&_rs)) +#endif + pr_info("[connlog] %s emi ring is empty!\n", + type_to_title[handler->conn_type]); + } + +#ifndef DEBUG_LOG_ON + if (__ratelimit(&_rs2)) +#endif + pr_info("[connlog] %s irq counter = %d\n", + type_to_title[handler->conn_type], + EMI_READ32(handler->virAddrEmiLogBase + CONNLOG_IRQ_COUNTER_BASE)); + + spin_lock_irqsave(&handler->irq_lock, handler->flags); + if (handler->eirqOn) + mod_timer(&handler->workTimer, jiffies + 1); + spin_unlock_irqrestore(&handler->irq_lock, handler->flags); +} + +static void connlog_do_schedule_work(struct connlog_dev* handler, bool count) +{ + spin_lock_irqsave(&handler->irq_lock, handler->flags); + if (count) { + handler->irq_counter++; + EMI_WRITE32( + handler->virAddrEmiLogBase + CONNLOG_IRQ_COUNTER_BASE, + handler->irq_counter); + } + handler->eirqOn = !schedule_work(&handler->logDataWorker); + spin_unlock_irqrestore(&handler->irq_lock, handler->flags); +} + +/***************************************************************************** +* FUNCTION +* connsys_log_get_buf_size +* DESCRIPTION +* Get ring buffer unread size on EMI. +* PARAMETERS +* conn_type [IN] subsys type +* RETURNS +* unsigned int Ring buffer unread size +*****************************************************************************/ +unsigned int connsys_log_get_buf_size(int conn_type) +{ + struct connlog_dev* handler; + if (conn_type < CONN_DEBUG_TYPE_WIFI || conn_type >= CONN_DEBUG_TYPE_END) + return 0; + + handler = gLogDev[conn_type]; + if (handler == NULL) { + pr_err("[%s][%s] didn't init\n", __func__, type_to_title[conn_type]); + return 0; + } + + return RING_SIZE(&handler->log_buffer.ring_cache); +} +EXPORT_SYMBOL(connsys_log_get_buf_size); + +/***************************************************************************** + * FUNCTION + * connsys_log_read_internal + * DESCRIPTION + * Read log in ring_cache to buf + * PARAMETERS + * + * RETURNS + * + *****************************************************************************/ +static ssize_t connlog_read_internal( + struct connlog_dev* handler, int conn_type, + char *buf, char __user *userbuf, size_t count, bool to_user) +{ + unsigned int written = 0; + unsigned int cache_buf_size; + struct ring_segment ring_seg; + struct ring *ring = &handler->log_buffer.ring_cache; + unsigned int size = 0; + int retval; + static DEFINE_RATELIMIT_STATE(_rs, 10 * HZ, 1); + static DEFINE_RATELIMIT_STATE(_rs2, 1 * HZ, 1); + + size = count < RING_SIZE(ring) ? count : RING_SIZE(ring); + if (RING_EMPTY(ring) || !ring_read_prepare(size, &ring_seg, ring)) { + pr_err("type(%d) no data, possibly taken by concurrent reader.\n", conn_type); + goto done; + } + cache_buf_size = ring_seg.remain; + + RING_READ_FOR_EACH(size, ring_seg, ring) { + if (to_user) { + retval = copy_to_user(userbuf + written, ring_seg.ring_pt, ring_seg.sz); + if (retval) { + if (__ratelimit(&_rs)) + pr_err("copy to user buffer failed, ret:%d\n", retval); + goto done; + } + } else { + memcpy(buf + written, ring_seg.ring_pt, ring_seg.sz); + } + cache_buf_size -= ring_seg.sz; + written += ring_seg.sz; + if (__ratelimit(&_rs2)) + pr_info("[%s] copy %d to %s\n", + type_to_title[conn_type], + ring_seg.sz, + (to_user? "user space" : "buffer")); + } +done: + return written; +} + +/***************************************************************************** + * FUNCTION + * connsys_log_read_to_user + * DESCRIPTION + * Read log in ring_cache to user space buf + * PARAMETERS + * + * RETURNS + * + *****************************************************************************/ +ssize_t connsys_log_read_to_user(int conn_type, char __user *buf, size_t count) +{ + struct connlog_dev* handler; + unsigned int written = 0; + + if (conn_type < CONN_DEBUG_TYPE_WIFI || conn_type >= CONN_DEBUG_TYPE_END) + goto done; + if (atomic_read(&g_log_mode) != LOG_TO_FILE) + goto done; + + handler = gLogDev[conn_type]; + if (handler == NULL) { + pr_err("[%s][%s] not init\n", __func__, type_to_title[conn_type]); + goto done; + } + written = connlog_read_internal(handler, conn_type, NULL, buf, count, true); +done: + return written; +} +EXPORT_SYMBOL(connsys_log_read_to_user); + +/***************************************************************************** + * FUNCTION + * connsys_log_read + * DESCRIPTION + * Read log in ring_cache to buf + * PARAMETERS + * + * RETURNS + * + *****************************************************************************/ +ssize_t connsys_log_read(int conn_type, char *buf, size_t count) +{ + unsigned int ret = 0; + struct connlog_dev* handler; + + if (conn_type < CONN_DEBUG_TYPE_WIFI || conn_type >= CONN_DEBUG_TYPE_END) + goto done; + if (atomic_read(&g_log_mode) != LOG_TO_FILE) + goto done; + + handler = gLogDev[conn_type]; + ret = connlog_read_internal(handler, conn_type, buf, NULL, count, false); +done: + return ret; +} +EXPORT_SYMBOL(connsys_log_read); + + +/***************************************************************************** + * FUNCTION + * connsys_dedicated_log_set_log_mode + * DESCRIPTION + * set log mode. + * PARAMETERS + * mode [IN] log mode + * RETURNS + * void + *****************************************************************************/ +void connsys_dedicated_log_set_log_mode(int mode) +{ + atomic_set(&g_log_mode, (mode > 0 ? LOG_TO_FILE : PRINT_TO_KERNEL_LOG)); +} +EXPORT_SYMBOL(connsys_dedicated_log_set_log_mode); + +/***************************************************************************** +* FUNCTION +* connsys_dedicated_log_get_log_mode +* DESCRIPTION +* get log mode. +* PARAMETERS +* void +* RETURNS +* int log mode +*****************************************************************************/ +int connsys_dedicated_log_get_log_mode(void) +{ + return atomic_read(&g_log_mode); +} +EXPORT_SYMBOL(connsys_dedicated_log_get_log_mode); + +/***************************************************************************** +* FUNCTION +* connsys_log_irq_handler +* DESCRIPTION +* +* PARAMETERS +* void +* RETURNS +* int +*****************************************************************************/ +int connsys_log_irq_handler(int conn_type) +{ + struct connlog_dev* handler; + if (conn_type < CONN_DEBUG_TYPE_WIFI || conn_type >= CONN_DEBUG_TYPE_END) + return -1; + + handler = gLogDev[conn_type]; + if (handler == NULL) { + pr_err("[%s][%s] didn't init\n", __func__, type_to_title[conn_type]); + return -1; + } + + connlog_do_schedule_work(handler, true); + return 0; +} +EXPORT_SYMBOL(connsys_log_irq_handler); + +/***************************************************************************** +* FUNCTION +* connsys_log_register_event_cb +* DESCRIPTION +*· +* PARAMETERS +* void +* RETURNS +* +*****************************************************************************/ +int connsys_log_register_event_cb(int conn_type, CONNLOG_EVENT_CB func) +{ + struct connlog_dev* handler; + if (conn_type < CONN_DEBUG_TYPE_WIFI || conn_type >= CONN_DEBUG_TYPE_END) + return -1; + + handler = gLogDev[conn_type]; + if (handler == NULL) { + pr_err("[%s][%s] didn't init\n", __func__, type_to_title[conn_type]); + return -1; + } + + handler->callback.log_data_handler = func; + return 0; +} +EXPORT_SYMBOL(connsys_log_register_event_cb); + +/***************************************************************************** +* FUNCTION +* connlog_subsys_init +* DESCRIPTION +* +* PARAMETERS +* conn_type [IN] subsys type +* emi_addr [IN] physical emi +* emi_size [IN] emi size +* RETURNS +* struct connlog_dev* the handler +*****************************************************************************/ +static struct connlog_dev* connlog_subsys_init( + int conn_type, + phys_addr_t emi_addr, + unsigned int emi_size) +{ + struct connlog_dev* handler = 0; + + if (conn_type < CONN_DEBUG_TYPE_WIFI || conn_type >= CONN_DEBUG_TYPE_END) + return 0; + + handler = (struct connlog_dev*)kzalloc(sizeof(struct connlog_dev), GFP_KERNEL); + if (!handler) + return 0; + + handler->conn_type = conn_type; + if (connlog_emi_init(handler, emi_addr, emi_size)) { + pr_err("[%s] EMI init failed\n", type_to_title[conn_type]); + goto error_exit; + } + + if (connlog_ring_buffer_init(handler)) { + pr_err("[%s] Ring buffer init failed\n", type_to_title[conn_type]); + goto error_exit; + } + + init_timer(&handler->workTimer); + handler->workTimer.data = (unsigned long)handler; + handler->workTimer.function = work_timer_handler; + handler->irq_counter = 0; + spin_lock_init(&handler->irq_lock); + INIT_WORK(&handler->logDataWorker, connlog_log_data_handler); + + /* alarm timer */ + return handler; + +error_exit: + if (handler) + connlog_subsys_deinit(handler); + return 0; + +} + +/***************************************************************************** +* FUNCTION +* connsys_log_init +* DESCRIPTION +* +* PARAMETERS +* void +* RETURNS +* int +*****************************************************************************/ +int connsys_log_init(int conn_type) +{ + struct connlog_dev* handler; + phys_addr_t log_start_addr; + unsigned int log_size; + struct connlog_emi_config* emi_config; + + if (conn_type < CONN_DEBUG_TYPE_WIFI || conn_type >= CONN_DEBUG_TYPE_END) { + pr_err("[%s] invalid type:%d\n", __func__, conn_type); + return -1; + } + if (gLogDev[conn_type] != NULL) { + pr_err("[%s][%s] double init.\n", __func__, type_to_title[conn_type]); + return 0; + } + + emi_config = get_connsyslog_platform_config(conn_type); + if (!emi_config) { + pr_err("[%s] get emi config fail.\n", __func__); + return -1; + } + + log_start_addr = emi_config->log_offset + gPhyEmiBase; + log_size = emi_config->log_size; + pr_info("%s init. Base=%p size=%d\n", + type_to_title[conn_type], log_start_addr, log_size); + + handler = connlog_subsys_init(conn_type, log_start_addr, log_size); + if (handler == NULL) { + pr_err("[%s][%s] failed.\n", __func__, type_to_title[conn_type]); + return -1; + } + + gLogDev[conn_type] = handler; + return 0; +} +EXPORT_SYMBOL(connsys_log_init); + +/***************************************************************************** +* Function +* connlog_subsys_deinit +* DESCRIPTION +* +* PARAMETERS +* +* RETURNS +* +*****************************************************************************/ +static void connlog_subsys_deinit(struct connlog_dev* handler) +{ + if (handler == NULL) + return; + + connlog_emi_deinit(handler); + connlog_ring_buffer_deinit(handler); + kfree(handler); +} + +/***************************************************************************** +* Function +* connsys_log_deinit +* DESCRIPTION +* +* PARAMETERS +* +* RETURNS +* +*****************************************************************************/ +int connsys_log_deinit(int conn_type) +{ + struct connlog_dev* handler; + if (conn_type < CONN_DEBUG_TYPE_WIFI || conn_type >= CONN_DEBUG_TYPE_END) + return -1; + + handler = gLogDev[conn_type]; + if (handler == NULL) { + pr_err("[%s][%s] didn't init\n", __func__, type_to_title[conn_type]); + return -1; + } + + connlog_subsys_deinit(gLogDev[conn_type]); + gLogDev[conn_type] = NULL; + return 0; +} +EXPORT_SYMBOL(connsys_log_deinit); + +/***************************************************************************** +* FUNCTION +* connsys_log_get_utc_time +* DESCRIPTION +* Return UTC time +* PARAMETERS +* second [IN] UTC seconds +* usecond [IN] UTC usecons +* RETURNS +* void +*****************************************************************************/ +void connsys_log_get_utc_time( + unsigned int *second, unsigned int *usecond) +{ + struct timeval time; + + do_gettimeofday(&time); + *second = (unsigned int)time.tv_sec; /* UTC time second unit */ + *usecond = (unsigned int)time.tv_usec; /* UTC time microsecond unit */ +} +EXPORT_SYMBOL(connsys_log_get_utc_time); + +static inline bool connlog_is_alarm_enable(void) +{ + if ((gLogAlarm.alarm_state & CONNLOG_ALARM_STATE_ENABLE) > 0) + return true; + return false; +} + +static int connlog_set_alarm_timer(void) +{ + ktime_t kt; + + kt = ktime_set(gLogAlarm.alarm_sec, 0); + alarm_start_relative(&gLogAlarm.alarm_timer, kt); + + pr_info("[connsys_log_alarm] alarm timer enabled timeout=[%d]", gLogAlarm.alarm_sec); + return 0; +} + +static int connlog_cancel_alarm_timer(void) +{ + pr_info("[connsys_log_alarm] alarm timer cancel"); + return alarm_cancel(&gLogAlarm.alarm_timer); +} + + +static enum alarmtimer_restart connlog_alarm_timer_handler(struct alarm *alarm, + ktime_t now) +{ + ktime_t kt; + struct rtc_time tm; + unsigned int tsec, tusec; + int i; + + connsys_log_get_utc_time(&tsec, &tusec); + rtc_time_to_tm(tsec, &tm); + pr_info("[connsys_log_alarm] alarm_timer triggered [%d-%02d-%02d %02d:%02d:%02d.%09u]" + , tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday + , tm.tm_hour, tm.tm_min, tm.tm_sec, tusec); + + for (i = 0; i < CONN_DEBUG_TYPE_END; i++) { + if (gLogDev[i]) { + connlog_do_schedule_work(gLogDev[i], false); + } + } + + spin_lock_irqsave(&gLogAlarm.alarm_lock, gLogAlarm.flags); + kt = ktime_set(gLogAlarm.alarm_sec, 0); + alarm_start_relative(&gLogAlarm.alarm_timer, kt); + spin_unlock_irqrestore(&gLogAlarm.alarm_lock, gLogAlarm.flags); + + return ALARMTIMER_NORESTART; +} + +static int connlog_alarm_init(void) +{ + alarm_init(&gLogAlarm.alarm_timer, ALARM_REALTIME, connlog_alarm_timer_handler); + gLogAlarm.alarm_state = CONNLOG_ALARM_STATE_DISABLE; + spin_lock_init(&gLogAlarm.alarm_lock); + + return 0; +} + +/***************************************************************************** +* FUNCTION +* connsys_dedicated_log_path_alarm_enable +* DESCRIPTION +* Enable log timer. +* When log timer is enable, it starts every sec seconds to fetch log from EMI +* to file. +* Usually enable log timer for debug. +* PARAMETERS +* sec [IN] timer config +* RETURNS +* int +*****************************************************************************/ +int connsys_dedicated_log_path_alarm_enable(unsigned int sec) +{ + if (!gPhyEmiBase) + return -1; + + spin_lock_irqsave(&gLogAlarm.alarm_lock, gLogAlarm.flags); + + gLogAlarm.alarm_sec = sec; + if (!connlog_is_alarm_enable()) { + gLogAlarm.alarm_state = CONNLOG_ALARM_STATE_ENABLE; + pr_info("[connsys_log_alarm] alarm timer enabled timeout=[%d]", sec); + } + if (gLogAlarm.blank_state == 0) + connlog_set_alarm_timer(); + + spin_unlock_irqrestore(&gLogAlarm.alarm_lock, gLogAlarm.flags); + return 0; +} +EXPORT_SYMBOL(connsys_dedicated_log_path_alarm_enable); + +/***************************************************************************** +* FUNCTION +* connsys_dedicated_log_path_alarm_disable +* DESCRIPTION +* Disable log timer +* PARAMETERS +* +* RETURNS +* int +*****************************************************************************/ +int connsys_dedicated_log_path_alarm_disable(void) +{ + int ret; + + if (!gPhyEmiBase) + return -1; + + spin_lock_irqsave(&gLogAlarm.alarm_lock, gLogAlarm.flags); + + if (connlog_is_alarm_enable()) { + ret = connlog_cancel_alarm_timer(); + gLogAlarm.alarm_state = CONNLOG_ALARM_STATE_ENABLE; + pr_info("[connsys_log_alarm] alarm timer disable ret=%d", ret); + } + spin_unlock_irqrestore(&gLogAlarm.alarm_lock, gLogAlarm.flags); + return 0; +} +EXPORT_SYMBOL(connsys_dedicated_log_path_alarm_disable); + +/**************************************************************************** +* FUNCTION +* connsys_dedicated_log_path_blank_state_changed +* DESCRIPTION +* +* PARAMETERS +* +* RETURNS +* int +*****************************************************************************/ +int connsys_dedicated_log_path_blank_state_changed(int blank_state) +{ + int ret = 0; + + if (!gPhyEmiBase) + return -1; + spin_lock_irqsave(&gLogAlarm.alarm_lock, gLogAlarm.flags); + gLogAlarm.blank_state = blank_state; + if (connlog_is_alarm_enable()) { + if (blank_state == 0) + ret = connlog_set_alarm_timer(); + else + ret = connlog_cancel_alarm_timer(); + } + + spin_unlock_irqrestore(&gLogAlarm.alarm_lock, gLogAlarm.flags); + + return ret; +} +EXPORT_SYMBOL(connsys_dedicated_log_path_blank_state_changed); + +/***************************************************************************** +* FUNCTION +* connsys_dedicated_log_path_apsoc_init +* DESCRIPTION +* Initialize API for common driver to initialize connsys dedicated log +* for APSOC platform +* PARAMETERS +* emiaddr [IN] EMI physical base address +* RETURNS +* void +****************************************************************************/ +int connsys_dedicated_log_path_apsoc_init(phys_addr_t emiaddr) +{ + if (gPhyEmiBase != 0 || emiaddr == 0) { + pr_err("Connsys log double init or invalid parameter(emiaddr=%p)\n", emiaddr); + return -1; + } + + gPhyEmiBase = emiaddr; + + connlog_alarm_init(); + return 0; +} +EXPORT_SYMBOL(connsys_dedicated_log_path_apsoc_init); + +/***************************************************************************** +* FUNCTION +* connsys_dedicated_log_path_apsoc_deinit +* DESCRIPTION +* De-Initialize API for common driver to release cache, un-remap emi and free +* irq for APSOC platform +* PARAMETERS +* void +* RETURNS +* void +*****************************************************************************/ +int connsys_dedicated_log_path_apsoc_deinit(void) +{ + int i; + + /* Check subsys */ + for (i = 0; i < CONN_DEBUG_TYPE_END; i++) { + if (gLogDev[i] != NULL) { + pr_err("[%s] subsys %s should be deinit first.\n", + __func__, type_to_title[i]); + return -1; + } + } + + gPhyEmiBase = 0; + return 0; +} +EXPORT_SYMBOL(connsys_dedicated_log_path_apsoc_deinit); diff --git a/drivers/misc/mediatek/connectivity/conninfra/debug_utility/connsyslog/connsyslog.h b/drivers/misc/mediatek/connectivity/conninfra/debug_utility/connsyslog/connsyslog.h new file mode 100644 index 0000000000000000000000000000000000000000..6e410ec615b4ed650e0977fa7620d82857a912c6 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/debug_utility/connsyslog/connsyslog.h @@ -0,0 +1,60 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef _CONNSYSLOG_H_ +#define _CONNSYSLOG_H_ + +#include +#include + +#include "connsys_debug_utility.h" + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +/* Close debug log */ +//#define DEBUG_LOG_ON 1 + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ +enum FW_LOG_MODE { + PRINT_TO_KERNEL_LOG = 0, + LOG_TO_FILE = 1, +}; + +typedef void (*CONNLOG_EVENT_CB) (void); + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/* utility */ +void connsys_log_dump_buf(const char *title, const char *buf, ssize_t sz); +void connsys_log_get_utc_time( + unsigned int *second, unsigned int *usecond); + +/* Global config */ +int connsys_dedicated_log_path_apsoc_init(phys_addr_t emiaddr); +int connsys_dedicated_log_path_apsoc_deinit(void); +void connsys_dedicated_log_set_log_mode(int mode); +int connsys_dedicated_log_get_log_mode(void); +int connsys_dedicated_log_path_alarm_enable(unsigned int sec); +int connsys_dedicated_log_path_alarm_disable(void); +int connsys_dedicated_log_path_blank_state_changed(int blank_state); + +/* For subsys */ +int connsys_log_init(int conn_type); +int connsys_log_deinit(int conn_type); +unsigned int connsys_log_get_buf_size(int conn_type); +int connsys_log_register_event_cb(int conn_type, CONNLOG_EVENT_CB func); +ssize_t connsys_log_read_to_user(int conn_type, char __user *buf, size_t count); +ssize_t connsys_log_read(int conn_type, char *buf, size_t count); +int connsys_log_irq_handler(int conn_type); + +#endif /*_CONNSYSLOG_H_*/ diff --git a/drivers/misc/mediatek/connectivity/conninfra/debug_utility/connsyslog/connsyslog_emi.h b/drivers/misc/mediatek/connectivity/conninfra/debug_utility/connsyslog/connsyslog_emi.h new file mode 100644 index 0000000000000000000000000000000000000000..d2d823bd2d7d1f640e0aa150b8b0e48f07fc73ca --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/debug_utility/connsyslog/connsyslog_emi.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#ifndef _CONNSYSLOG_EMI_H_ +#define _CONNSYSLOG_EMI_H_ + +#define CONNLOG_EMI_32_BYTE_ALIGNED 32 /* connsys EMI cache is 32-byte aligned */ +#define CONNLOG_CONTROL_RING_BUFFER_BASE_SIZE 64 /* Reserve for setup ring buffer base address */ +#define CONNLOG_CONTROL_RING_BUFFER_RESERVE_SIZE 32 +#define CONNLOG_IRQ_COUNTER_BASE 48 +#define CONNLOG_READY_PATTERN_BASE 56 +#define CONNLOG_READY_PATTERN_BASE_SIZE 8 +#define CONNLOG_EMI_END_PATTERN_SIZE CONNLOG_EMI_32_BYTE_ALIGNED +#define CONNLOG_EMI_END_PATTERN "FWLOGENDFWLOGENDFWLOGENDFWLOGEND" + +#define CONNLOG_EMI_BASE_OFFSET CONNLOG_CONTROL_RING_BUFFER_BASE_SIZE +#define CONNLOG_EMI_READ (CONNLOG_EMI_BASE_OFFSET + 0) +#define CONNLOG_EMI_WRITE (CONNLOG_EMI_BASE_OFFSET + 4) +#define CONNLOG_EMI_BUF (CONNLOG_EMI_BASE_OFFSET + \ + CONNLOG_EMI_32_BYTE_ALIGNED) + +#endif /* _CONNSYSLOG_EMI_H_ */ diff --git a/drivers/misc/mediatek/connectivity/conninfra/debug_utility/connsyslog/log_ring.c b/drivers/misc/mediatek/connectivity/conninfra/debug_utility/connsyslog/log_ring.c new file mode 100644 index 0000000000000000000000000000000000000000..c1cfb3b2a6a2dba40adbb9a93068e54b5c274945 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/debug_utility/connsyslog/log_ring.c @@ -0,0 +1,141 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include "log_ring.h" +#include +#include +#include + + + +void log_ring_init(void *base, unsigned int max_size, unsigned int read, + unsigned int write, struct ring *ring) +{ + pr_info("base=0x%lx max_size=%x read=%x write=%x", base, max_size, read, write); + + WARN_ON(!base); + pr_info("xxxx-1"); + LOG_RING_VALIDATE_SIZE(max_size); + pr_info("xxx-2"); + /* making sure write largger than read */ + WARN_ON(read > write); + pr_info("xxx-3"); + ring->base = base; + ring->read = read; + ring->write = write; + ring->max_size = max_size; +} + +void log_ring_dump(const char *title, struct ring *ring) +{ + pr_info("[%s] ring:{write=%d, read=%d, max_size=%d}\n", + title, ring->write, ring->read, ring->max_size); +} + +void log_ring_dump_segment(const char *title, struct ring_segment *seg) +{ + pr_info("[%s] seg:{ring_pt=0x%p, data_pos=%d, sz=%d, remain=%d}\n", + title, seg->ring_pt, seg->data_pos, seg->sz, seg->remain); +} + +/* + * Function prepares the ring_segment and returns the number of valid bytes for read. + */ +unsigned int log_ring_read_prepare(unsigned int sz, struct ring_segment *seg, struct ring *ring) +{ + unsigned int wt = ring->write; + unsigned int rd = ring->read; + + memset(seg, 0, sizeof(struct ring_segment)); + if (sz > wt - rd) + sz = wt - rd; + seg->remain = sz; + /* log_ring_dump(__func__, ring); */ + /* log_ring_dump_segment(__func__, seg); */ + return seg->remain; +} + +/* + * Function prepares the ring_segment and returns the number of bytes available for write. + */ +unsigned int log_ring_write_prepare(unsigned int sz, struct ring_segment *seg, struct ring *ring) +{ + unsigned int wt = ring->write; + unsigned int rd = ring->read; + + memset(seg, 0, sizeof(struct ring_segment)); + if (sz > ring->max_size - (wt - rd)) + sz = ring->max_size - (wt - rd); + seg->remain = sz; + /* log_ring_dump(__func__, ring); */ + /* log_ring_dump_segment(__func__, seg); */ + return seg->remain; +} + +unsigned int log_ring_overwrite_prepare(unsigned int sz, struct ring_segment *seg, + struct ring *ring) +{ + unsigned int wt = ring->write; + unsigned int rd = ring->read; + + memset(seg, 0, sizeof(struct ring_segment)); + if (sz > ring->max_size - (wt - rd)) + ring->read += sz - (ring->max_size - (wt - rd)); + seg->remain = sz; + /* log_ring_dump(__func__, ring); */ + /* log_ring_dump_segment(__func__, seg); */ + return seg->remain; +} + +void __log_ring_segment_prepare(unsigned int from, unsigned int sz, struct ring_segment *seg, + struct ring *ring) +{ + unsigned int ring_pos = from; + + if (ring_pos >= ring->max_size) + ring_pos -= ring->max_size; + + seg->ring_pt = ring->base + ring_pos; + seg->data_pos = (seg->sz ? seg->data_pos + seg->sz : 0); + if (ring_pos + sz <= ring->max_size) + seg->sz = sz; + else + seg->sz = ring->max_size - ring_pos; + seg->remain -= seg->sz; + /* log_ring_dump(__func__, ring); */ + /* log_ring_dump_segment(__func__, seg); */ +} + +void _log_ring_segment_prepare(unsigned int from, struct ring_segment *seg, struct ring *ring) +{ + __log_ring_segment_prepare(from, seg->remain, seg, ring); +} + +void _log_ring_segment_prepare_item(unsigned int from, struct ring_segment *seg, struct ring *ring) +{ + unsigned int size; + + size = (seg->remain ? 1 : 0); + __log_ring_segment_prepare(from, size, seg, ring); +} + +void _log_ring_read_commit(struct ring_segment *seg, struct ring *ring) +{ + ring->read += seg->sz; + if (ring->read >= ring->max_size) + ring->read -= ring->max_size; + /* log_ring_dump(__func__, ring); */ + /* log_ring_dump_segment(__func__, seg); */ +} +void _log_ring_write_commit(struct ring_segment *seg, struct ring *ring) +{ + ring->write += seg->sz; + if (ring->write >= ring->max_size) + ring->write -= ring->max_size; + + /* log_ring_dump(__func__, ring); */ + /* log_ring_dump_segment(__func__, seg); */ +} + diff --git a/drivers/misc/mediatek/connectivity/conninfra/debug_utility/connsyslog/log_ring.h b/drivers/misc/mediatek/connectivity/conninfra/debug_utility/connsyslog/log_ring.h new file mode 100644 index 0000000000000000000000000000000000000000..49cc9f91fc22901205aad9336910acd4290353b5 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/debug_utility/connsyslog/log_ring.h @@ -0,0 +1,88 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef _LOG_RING_H_ +#define _LOG_RING_H_ + +struct ring { + /* addr where ring buffer starts */ + void *base; + /* addr storing the next writable pos, guaranteed to be >= read except when write overflow, but it's ok. */ + unsigned int write; + /* addr storing the next readable pos, except when read == write as buffer empty */ + unsigned int read; + /* must be power of 2 */ + unsigned int max_size; +}; + +struct ring_segment { + /* addr points into ring buffer for read/write */ + void *ring_pt; + /* size to read/write */ + unsigned int sz; + /* pos in external data buffer to read/write */ + unsigned int data_pos; + /* the size to be read/write after this segment completed */ + unsigned int remain; +}; + +void log_ring_init(void *base, unsigned int max_size, unsigned int read, + unsigned int write, struct ring *ring); +unsigned int log_ring_read_prepare(unsigned int sz, struct ring_segment *seg, struct ring *ring); +#define log_ring_read_all_prepare(seg, ring) log_ring_read_prepare((ring)->max_size, seg, ring) +unsigned int log_ring_write_prepare(unsigned int sz, struct ring_segment *seg, struct ring *ring); +unsigned int log_ring_overwrite_prepare(unsigned int sz, + struct ring_segment *seg, struct ring *ring); + +/* making sure max_size is power of 2 */ +#define LOG_RING_VALIDATE_SIZE(max_size) WARN_ON(!max_size) + +#define LOG_RING_EMPTY(ring) ((ring)->read == (ring)->write) +/* equation works even when write overflow */ +#define LOG_RING_SIZE(ring) ((ring)->write - (ring)->read) +#define LOG_RING_FULL(ring) (LOG_RING_SIZE(ring) == (ring)->max_size) +#define LOG_RING_WRITE_REMAIN_SIZE(ring) ((ring)->max_size - LOG_RING_SIZE(ring)) + +#define LOG_RING_READ_FOR_EACH(_sz, _seg, _ring) \ + for (log_ring_read_prepare(_sz, &(_seg), _ring), \ + _log_ring_segment_prepare((_ring)->read, &(_seg), (_ring)); \ + (_seg).sz > 0; \ + _log_ring_read_commit(&(_seg), (_ring)), _log_ring_segment_prepare((_ring)->read, \ + &(_seg), (_ring))) + +#define LOG_RING_READ_ALL_FOR_EACH(seg, ring) LOG_RING_READ_FOR_EACH((ring)->max_size, seg, ring) + +#define LOG_RING_READ_FOR_EACH_ITEM(_sz, _seg, _ring) \ + for (log_ring_read_prepare(_sz, &(_seg), _ring), \ + _log_ring_segment_prepare_item((_ring)->read, &(_seg), (_ring)); \ + (_seg).sz > 0; \ + _log_ring_read_commit(&(_seg), (_ring)), _log_ring_segment_prepare_item((_ring)->read, \ + &(_seg), (_ring))) + +#define LOG_RING_WRITE_FOR_EACH(_sz, _seg, _ring) \ + for (log_ring_write_prepare(_sz, &(_seg), _ring),\ + _log_ring_segment_prepare((_ring)->write, &(_seg), (_ring)); \ + (_seg).sz > 0; \ + _log_ring_write_commit(&(_seg), (_ring)), _log_ring_segment_prepare((_ring)->write, \ + &(_seg), (_ring))) + +#define LOG_RING_OVERWRITE_FOR_EACH(_sz, _seg, _ring) \ + for (log_ring_overwrite_prepare(_sz, &(_seg), _ring), \ + _log_ring_segment_prepare((_ring)->write, &(_seg), (_ring)); \ + (_seg).sz > 0; \ + _log_ring_write_commit(&(_seg), (_ring)), _log_ring_segment_prepare((_ring)->write, \ + &(_seg), (_ring))) + +void log_ring_dump(const char *title, struct ring *ring); +void log_ring_dump_segment(const char *title, struct ring_segment *seg); + + +/* ring Buffer Internal API */ +void _log_ring_segment_prepare(unsigned int from, struct ring_segment *seg, struct ring *ring); +void _log_ring_segment_prepare_item(unsigned int from, struct ring_segment *seg, struct ring *ring); +void _log_ring_read_commit(struct ring_segment *seg, struct ring *ring); +void _log_ring_write_commit(struct ring_segment *seg, struct ring *ring); + +#endif diff --git a/drivers/misc/mediatek/connectivity/conninfra/debug_utility/connsyslog/platform/include/connsyslog_hw_config.h b/drivers/misc/mediatek/connectivity/conninfra/debug_utility/connsyslog/platform/include/connsyslog_hw_config.h new file mode 100644 index 0000000000000000000000000000000000000000..df226ec93bc3cd96fa4228bdb86359ed5e9dec61 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/debug_utility/connsyslog/platform/include/connsyslog_hw_config.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef __CONNSYSLOG_HW_CONFIG_H__ +#define __CONNSYSLOG_HW_CONFIG_H__ + +struct connlog_emi_config { + phys_addr_t log_offset; + unsigned int log_size; +}; + +#endif /* __CONNSYSLOG_HW_CONFIG_H__ */ diff --git a/drivers/misc/mediatek/connectivity/conninfra/debug_utility/connsyslog/platform/mt6885/mt6885.c b/drivers/misc/mediatek/connectivity/conninfra/debug_utility/connsyslog/platform/mt6885/mt6885.c new file mode 100644 index 0000000000000000000000000000000000000000..e58b5b60efaa47e70b091f6500f709c3d76e93a4 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/debug_utility/connsyslog/platform/mt6885/mt6885.c @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#include + +#include "connsys_debug_utility.h" +#include "connsyslog_hw_config.h" + +#ifdef CONFIG_FPGA_EARLY_PORTING +#define CONNLOG_EMI_OFFSET_WIFI 0x0001F000 +#define CONNLOG_EMI_OFFSET_BT 0x0002F000 +#else +#define CONNLOG_EMI_OFFSET_WIFI 0x0024F000 +#define CONNLOG_EMI_OFFSET_BT 0x0004b000 +#endif + +#define CONNLOG_EMI_SIZE_WIFI (192*1024) +#define CONNLOG_EMI_SIZE_BT (64*1024) + +struct connlog_emi_config g_connsyslog_config[CONN_DEBUG_TYPE_END] = { + /* Wi-Fi config */ + {CONNLOG_EMI_OFFSET_WIFI, CONNLOG_EMI_SIZE_WIFI}, + {CONNLOG_EMI_OFFSET_BT, CONNLOG_EMI_SIZE_BT}, +}; + +struct connlog_emi_config* get_connsyslog_platform_config(int conn_type) +{ + if (conn_type < 0 || conn_type >= CONN_DEBUG_TYPE_END) { + pr_err("Incorrect type: %d\n", conn_type); + return NULL; + } + return &g_connsyslog_config[conn_type]; +} + diff --git a/drivers/misc/mediatek/connectivity/conninfra/debug_utility/connsyslog/ring_emi.c b/drivers/misc/mediatek/connectivity/conninfra/debug_utility/connsyslog/ring_emi.c new file mode 100644 index 0000000000000000000000000000000000000000..03115ad0f261350f474f259f2fa1796b887d670a --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/debug_utility/connsyslog/ring_emi.c @@ -0,0 +1,151 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#include "ring_emi.h" +#include +#include +#include + +void ring_emi_init(void *base, unsigned int max_size, void *read, void *write, struct ring_emi *ring_emi) +{ + WARN_ON(!base || !read || !write); + + /* making sure max_size is power of 2 */ + WARN_ON(!max_size || (max_size & (max_size - 1))); + + /* making sure read & write pointers are 4 bytes aligned */ + WARN_ON(((long)read & 0x3) != 0 || ((long)write & 0x3) != 0); + + ring_emi->base = base; + ring_emi->read = read; + ring_emi->write = write; + EMI_WRITE32(ring_emi->write, 0); + EMI_WRITE32(ring_emi->read, 0); + ring_emi->max_size = max_size; + pr_info("write(%p) as 0, read(%p) as 0\n", ring_emi->write, ring_emi->read); + pr_info("base: %p, read: %p, write: %p, max_size: %d\n", base, read, write, max_size); +} + +void ring_emi_dump(const char *title, struct ring_emi *ring_emi) +{ + pr_info("[%s] ring_emi:{base=0x%p, write=%d, read=%d, max_size=%d}\n", + title, ring_emi->base, EMI_READ32(ring_emi->write), + EMI_READ32(ring_emi->read), ring_emi->max_size); +} + +void ring_emi_dump_segment(const char *title, struct ring_emi_segment *seg) +{ + pr_info("[%s] seg:{ring_emi_pt=0x%p, data_pos=%d, sz=%d, remain=%d}\n", + title, seg->ring_emi_pt, seg->data_pos, seg->sz, seg->remain); +} + +/* + * Function prepares the ring_emi_segment and returns the number of valid bytes for read. + */ +unsigned int ring_emi_read_prepare(unsigned int sz, struct ring_emi_segment *seg, struct ring_emi *ring_emi) +{ + unsigned int wt = EMI_READ32(ring_emi->write); + unsigned int rd = EMI_READ32(ring_emi->read); + + memset(seg, 0, sizeof(struct ring_emi_segment)); +#ifdef ROUND_REPEAT + if (wt >= rd) { + if (sz > wt - rd) + sz = wt - rd; + seg->remain = sz; + } else { + if (sz > ring_emi->max_size - (rd - wt)) + sz = ring_emi->max_size - (rd - wt); + seg->remain = sz; + } +#else + if (sz > wt - rd) + sz = wt - rd; + seg->remain = sz; +#endif + /* ring_emi_dump(__func__, ring_emi); */ + /* ring_emi_dump_segment(__func__, seg); */ + return seg->remain; +} + +/* + * Function prepares the ring_emi_segment and returns the number of bytes available for write. + */ +unsigned int ring_emi_write_prepare(unsigned int sz, struct ring_emi_segment *seg, struct ring_emi *ring_emi) +{ + unsigned int wt = EMI_READ32(ring_emi->write); + unsigned int rd = EMI_READ32(ring_emi->read); + + memset(seg, 0, sizeof(struct ring_emi_segment)); +#ifdef ROUND_REPEAT + if (wt >= rd) + seg->remain = ring_emi->max_size - (wt - rd + 1); + else + seg->remain = ring_emi->max_size - (rd - wt + 1); + + if (sz <= seg->remain) + seg->remain = sz; +#else + if (sz > ring_emi->max_size - (wt - rd)) + sz = ring_emi->max_size - (wt - rd); + seg->remain = sz; +#endif + /* ring_emi_dump(__func__, ring_emi); */ + /* ring_emi_dump_segment(__func__, seg); */ + return seg->remain; +} + +void _ring_emi_segment_prepare(unsigned int from, struct ring_emi_segment *seg, struct ring_emi *ring_emi) +{ +#ifndef ROUND_REPEAT + unsigned int ring_emi_pos = from & (ring_emi->max_size - 1); + + seg->ring_emi_pt = ring_emi->base + ring_emi_pos; +#else + seg->ring_emi_pt = ring_emi->base + from; +#endif + seg->data_pos = (seg->sz ? seg->data_pos + seg->sz : 0); + if (from + seg->remain <= ring_emi->max_size) + seg->sz = seg->remain; + else + seg->sz = ring_emi->max_size - from; + seg->remain -= seg->sz; + /* ring_emi_dump(__func__, ring_emi); */ + /* ring_emi_dump_segment(__func__, seg); */ +} + +void _ring_emi_read_commit(struct ring_emi_segment *seg, struct ring_emi *ring_emi) +{ +#ifdef ROUND_REPEAT +#ifdef DEBUG_LOG_ON + pr_info("[%s] write %p as %d\n", __func__, ring_emi->read, (EMI_READ32(ring_emi->read) + seg->sz) & (ring_emi->max_size - 1)); +#endif + EMI_WRITE32(ring_emi->read, (EMI_READ32(ring_emi->read) + seg->sz) & (ring_emi->max_size - 1)); +#else +#ifdef DEBUG_LOG_ON + pr_info("[%s] write %p as %d\n", __func__, ring_emi->read, EMI_READ32(ring_emi->read) + seg->sz); +#endif + EMI_WRITE32(ring_emi->read, EMI_READ32(ring_emi->read) + seg->sz); +#endif + /* *(ring_emi->read) += seg->sz; */ + /* ring_emi_dump(__func__, ring_emi); */ + /* ring_emi_dump_segment(__func__, seg); */ +} +void _ring_emi_write_commit(struct ring_emi_segment *seg, struct ring_emi *ring_emi) +{ +#ifdef ROUND_REPEAT +#ifdef DEBUG_LOG_ON + pr_info("[%s] write %p as %d\n", __func__, (EMI_READ32(ring_emi->write) + seg->sz) & (ring_emi->max_size - 1)); +#endif + EMI_WRITE32(ring_emi->write, (EMI_READ32(ring_emi->write) + seg->sz) & (ring_emi->max_size - 1)); +#else +#ifdef DEBUG_LOG_ON + pr_info("[%s] write %p as %d\n", __func__, ring_emi->write, EMI_READ32(ring_emi->write) + seg->sz); +#endif + EMI_WRITE32(ring_emi->write, EMI_READ32(ring_emi->write) + seg->sz); +#endif + /* ring_emi_dump(__func__, ring_emi); */ + /* ring_emi_dump_segment(__func__, seg); */ +} + diff --git a/drivers/misc/mediatek/connectivity/conninfra/debug_utility/connsyslog/ring_emi.h b/drivers/misc/mediatek/connectivity/conninfra/debug_utility/connsyslog/ring_emi.h new file mode 100644 index 0000000000000000000000000000000000000000..5969fd90f5bed24750525c0ddf4c7dc3e4f191fe --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/debug_utility/connsyslog/ring_emi.h @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#ifndef _RING_EMI_H_ +#define _RING_EMI_H_ + +#include +#define ROUND_REPEAT +#define EMI_READ32(addr) (readl(addr)) +#define EMI_WRITE32(addr, data) (writel(data, addr)) + +struct ring_emi { + /* addr where ring buffer starts */ + void *base; + /* addr storing the next writable pos, guaranteed to be >= read except when write overflow, but it's ok. */ + void *write; + /* addr storing the next readable pos, except when read == write as buffer empty */ + void *read; + /* must be power of 2 */ + unsigned int max_size; +}; + +struct ring_emi_segment { + /* addr points into ring buffer for read/write */ + void *ring_emi_pt; + /* size to read/write */ + unsigned int sz; + /* pos in external data buffer to read/write */ + unsigned int data_pos; + /* the size to be read/write after this segment completed */ + unsigned int remain; +}; + +void ring_emi_init(void *base, unsigned int max_size, void *read, void *write, struct ring_emi *ring_emi); +unsigned int ring_emi_read_prepare(unsigned int sz, struct ring_emi_segment *seg, struct ring_emi *ring_emi); +#define ring_emi_read_all_prepare(seg, ring_emi) ring_emi_read_prepare((ring_emi)->max_size, seg, ring_emi) +unsigned int ring_emi_write_prepare(unsigned int sz, struct ring_emi_segment *seg, struct ring_emi *ring_emi); + +/* making sure max_size is power of 2 */ +#define RING_EMI_VALIDATE_SIZE(max_size) WARN_ON(!max_size || (max_size & (max_size - 1))) + +#define RING_EMI_EMPTY(ring_emi) (EMI_READ32((ring_emi)->read) == EMI_READ32((ring_emi)->write)) +/* equation works even when write overflow */ +#define RING_EMI_SIZE(ring_emi) (EMI_READ32((ring_emi)->write) - EMI_READ32((ring_emi)->read)) +#ifdef ROUND_REPEAT +#define RING_EMI_FULL(ring_emi) (((EMI_READ32((ring_emi)->write) + 1) & ((ring_emi)->max_size - 1)) \ + == EMI_READ32((ring_emi)->read)) +#else +#define RING_EMI_FULL(ring_emi) (RING_EMI_SIZE(ring_emi) == (ring_emi)->max_size) +#endif + +#define RING_EMI_READ_FOR_EACH(_sz, _seg, _ring_emi) \ + for (_ring_emi_segment_prepare(EMI_READ32((_ring_emi)->read), &(_seg), (_ring_emi)); \ + (_seg).sz > 0; \ + _ring_emi_read_commit(&(_seg), (_ring_emi)), \ + _ring_emi_segment_prepare(EMI_READ32((_ring_emi)->read), &(_seg), (_ring_emi))) + +#define RING_EMI_READ_ALL_FOR_EACH(seg, ring_emi) RING_EMI_READ_FOR_EACH((ring_emi)->max_size, seg, ring_emi) + +#define RING_EMI_WRITE_FOR_EACH(_sz, _seg, _ring_emi) \ + for (_ring_emi_segment_prepare(EMI_READ32((_ring_emi)->write), &(_seg), (_ring_emi)); \ + (_seg).sz > 0; \ + _ring_emi_write_commit(&(_seg), (_ring_emi)), \ + _ring_emi_segment_prepare(EMI_READ32((_ring_emi)->write), &(_seg), (_ring_emi))) + +void ring_emi_dump(const char *title, struct ring_emi *ring_emi); +void ring_emi_dump_segment(const char *title, struct ring_emi_segment *seg); + + +/* Ring Buffer Internal API */ +void _ring_emi_segment_prepare(unsigned int from, struct ring_emi_segment *seg, struct ring_emi *ring_emi); +void _ring_emi_read_commit(struct ring_emi_segment *seg, struct ring_emi *ring_emi); +void _ring_emi_write_commit(struct ring_emi_segment *seg, struct ring_emi *ring_emi); + +#endif diff --git a/drivers/misc/mediatek/connectivity/conninfra/debug_utility/coredump/conndump_netlink.c b/drivers/misc/mediatek/connectivity/conninfra/debug_utility/coredump/conndump_netlink.c new file mode 100755 index 0000000000000000000000000000000000000000..7c965643a92c28fafea1f28b9bee820e6d89eba9 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/debug_utility/coredump/conndump_netlink.c @@ -0,0 +1,535 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "connsys_debug_utility.h" +#include "conndump_netlink.h" + + +/******************************************************************************* +* MACROS +******************************************************************************** +*/ +#define MAX_BIND_PROCESS (4) + +#define CONNSYS_DUMP_NETLINK_FAMILY_NAME_WIFI "CONNDUMP_WIFI" +#define CONNSYS_DUMP_NETLINK_FAMILY_NAME_BT "CONNDUMP_BT" + +#ifndef GENL_ID_GENERATE +#define GENL_ID_GENERATE 0 +#endif + +#define CONNSYS_DUMP_PKT_SIZE NLMSG_DEFAULT_SIZE + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +enum { + __CONNDUMP_ATTR_INVALID, + CONNDUMP_ATTR_MSG, + CONNDUMP_ATTR_PORT, + CONNDUMP_ATTR_HEADER, + CONNDUMP_ATTR_MSG_SIZE, + CONNDUMP_ATTR_LAST, + __CONNDUMP_ATTR_MAX, +}; +#define CONNDUMP_ATTR_MAX (__CONNDUMP_ATTR_MAX - 1) + +enum { + __CONNDUMP_COMMAND_INVALID, + CONNDUMP_COMMAND_BIND, + CONNDUMP_COMMAND_DUMP, + CONNDUMP_COMMAND_END, + CONNDUMP_COMMAND_RESET, + __CONNDUMP_COMMAND_MAX, +}; + +enum LINK_STATUS { + LINK_STATUS_INIT, + LINK_STATUS_INIT_DONE, + LINK_STATUS_MAX, +}; + +struct dump_netlink_ctx { + int conn_type; + pid_t bind_pid[MAX_BIND_PROCESS]; + unsigned int num_bind_process; + struct genl_family gnl_family; + unsigned int seqnum; + struct mutex nl_lock; + enum LINK_STATUS status; + void* coredump_ctx; + struct netlink_event_cb cb; +}; + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +static int conndump_nl_bind_wifi(struct sk_buff *skb, struct genl_info *info); +static int conndump_nl_dump_wifi(struct sk_buff *skb, struct genl_info *info); +static int conndump_nl_dump_end_wifi(struct sk_buff *skb, struct genl_info *info); +static int conndump_nl_reset_wifi(struct sk_buff *skb, struct genl_info *info); +static int conndump_nl_bind_bt(struct sk_buff *skb, struct genl_info *info); +static int conndump_nl_dump_bt(struct sk_buff *skb, struct genl_info *info); +static int conndump_nl_dump_end_bt(struct sk_buff *skb, struct genl_info *info); +static int conndump_nl_reset_bt(struct sk_buff *skb, struct genl_info *info); + +/******************************************************************************* +* G L O B A L V A R I A B L E +******************************************************************************** +*/ + +/* attribute policy */ +static struct nla_policy conndump_genl_policy[CONNDUMP_ATTR_MAX + 1] = { + [CONNDUMP_ATTR_MSG] = {.type = NLA_NUL_STRING}, + [CONNDUMP_ATTR_PORT] = {.type = NLA_U32}, + [CONNDUMP_ATTR_HEADER] = {.type = NLA_NUL_STRING}, + [CONNDUMP_ATTR_MSG_SIZE] = {.type = NLA_U32}, + [CONNDUMP_ATTR_LAST] = {.type = NLA_U32}, +}; + + +/* operation definition */ +static struct genl_ops conndump_gnl_ops_array_wifi[] = { + { + .cmd = CONNDUMP_COMMAND_BIND, + .flags = 0, + .policy = conndump_genl_policy, + .doit = conndump_nl_bind_wifi, + .dumpit = NULL, + }, + { + .cmd = CONNDUMP_COMMAND_DUMP, + .flags = 0, + .policy = conndump_genl_policy, + .doit = conndump_nl_dump_wifi, + .dumpit = NULL, + }, + { + .cmd = CONNDUMP_COMMAND_END, + .flags = 0, + .policy = conndump_genl_policy, + .doit = conndump_nl_dump_end_wifi, + .dumpit = NULL, + }, + { + .cmd = CONNDUMP_COMMAND_RESET, + .flags = 0, + .policy = conndump_genl_policy, + .doit = conndump_nl_reset_wifi, + .dumpit = NULL, + }, +}; + +static struct genl_ops conndump_gnl_ops_array_bt[] = { + { + .cmd = CONNDUMP_COMMAND_BIND, + .flags = 0, + .policy = conndump_genl_policy, + .doit = conndump_nl_bind_bt, + .dumpit = NULL, + }, + { + .cmd = CONNDUMP_COMMAND_DUMP, + .flags = 0, + .policy = conndump_genl_policy, + .doit = conndump_nl_dump_bt, + .dumpit = NULL, + }, + { + .cmd = CONNDUMP_COMMAND_END, + .flags = 0, + .policy = conndump_genl_policy, + .doit = conndump_nl_dump_end_bt, + .dumpit = NULL, + }, + { + .cmd = CONNDUMP_COMMAND_RESET, + .flags = 0, + .policy = conndump_genl_policy, + .doit = conndump_nl_reset_bt, + .dumpit = NULL, + }, +}; + +struct dump_netlink_ctx g_netlink_ctx[2] = { + /* WIFI */ + { + .conn_type = CONN_DEBUG_TYPE_WIFI, + .gnl_family = { + .id = GENL_ID_GENERATE, + .hdrsize = 0, + .name = CONNSYS_DUMP_NETLINK_FAMILY_NAME_WIFI, + .version = 1, + .maxattr = CONNDUMP_ATTR_MAX, + .ops = conndump_gnl_ops_array_wifi, + .n_ops = ARRAY_SIZE(conndump_gnl_ops_array_wifi), + }, + .status = LINK_STATUS_INIT, + .num_bind_process = 0, + .seqnum = 0, + }, + /* BT */ + { + .conn_type = CONN_DEBUG_TYPE_BT, + .gnl_family = { + .id = GENL_ID_GENERATE, + .hdrsize = 0, + .name = CONNSYS_DUMP_NETLINK_FAMILY_NAME_BT, + .version = 1, + .maxattr = CONNDUMP_ATTR_MAX, + .ops = conndump_gnl_ops_array_bt, + .n_ops = ARRAY_SIZE(conndump_gnl_ops_array_bt), + }, + .status = LINK_STATUS_INIT, + .num_bind_process = 0, + .seqnum = 0, + }, +}; + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +static int conndump_nl_bind_internal(struct dump_netlink_ctx* ctx, struct sk_buff *skb, struct genl_info *info) +{ + int i; + struct nlattr *port_na; + unsigned int port; + + if (info == NULL) + goto out; + + if (mutex_lock_killable(&ctx->nl_lock)) + return -1; + + port_na = info->attrs[CONNDUMP_ATTR_PORT]; + if (port_na) { + port = (unsigned int)nla_get_u32(port_na); + } else { + pr_err("%s:-> no port_na found\n"); + return -1; + } + + for (i = 0; i < MAX_BIND_PROCESS; i ++) { + if (ctx->bind_pid[i] == 0) { + ctx->bind_pid[i] = port; + ctx->num_bind_process++; + pr_info("%s():-> pid = %d\n", __func__, port); + break; + } + } + if (i == MAX_BIND_PROCESS) { + pr_err("%s(): exceeding binding limit %d\n", __func__, MAX_BIND_PROCESS); + } + mutex_unlock(&ctx->nl_lock); + +out: + return 0; +} + +static int conndump_nl_dump_end_internal(struct dump_netlink_ctx* ctx, struct sk_buff *skb, struct genl_info *info) +{ + if (ctx && ctx->cb.coredump_end) { + pr_info("Get coredump end command, type=%d", ctx->conn_type); + ctx->cb.coredump_end(ctx->coredump_ctx); + } + return 0; +} + +static int conndump_nl_bind_wifi(struct sk_buff *skb, struct genl_info *info) +{ + int ret = 0; + + ret = conndump_nl_bind_internal(&g_netlink_ctx[CONN_DEBUG_TYPE_WIFI], skb, info); + return ret; +} + +static int conndump_nl_dump_wifi(struct sk_buff *skb, struct genl_info *info) +{ + pr_err("%s(): should not be invoked\n", __func__); + + return 0; +} + +static int conndump_nl_dump_end_wifi(struct sk_buff *skb, struct genl_info *info) +{ + int ret = 0; + + ret = conndump_nl_dump_end_internal(&g_netlink_ctx[CONN_DEBUG_TYPE_WIFI], skb, info); + + return ret; +} + +static int conndump_nl_reset_wifi(struct sk_buff *skb, struct genl_info *info) +{ + pr_err("%s(): should not be invoked\n", __func__); + + return 0; +} + +static int conndump_nl_bind_bt(struct sk_buff *skb, struct genl_info *info) +{ + int ret = 0; + + ret = conndump_nl_bind_internal(&g_netlink_ctx[CONN_DEBUG_TYPE_BT], skb, info); + return ret; +} + +static int conndump_nl_dump_bt(struct sk_buff *skb, struct genl_info *info) +{ + pr_err("%s(): should not be invoked\n", __func__); + + return 0; +} + +static int conndump_nl_dump_end_bt(struct sk_buff *skb, struct genl_info *info) +{ + int ret = 0; + + ret = conndump_nl_dump_end_internal(&g_netlink_ctx[CONN_DEBUG_TYPE_BT], skb, info); + + return ret; + +} + +static int conndump_nl_reset_bt(struct sk_buff *skb, struct genl_info *info) +{ + pr_err("%s(): should not be invoked\n", __func__); + + return 0; +} + +/***************************************************************************** + * FUNCTION + * conndump_netlink_init + * DESCRIPTION + * + * PARAMETERS + * + * RETURNS + * + *****************************************************************************/ +int conndump_netlink_init(int conn_type, void* dump_ctx, struct netlink_event_cb* cb) +{ + int ret = 0; + struct dump_netlink_ctx* ctx; + + if (conn_type < CONN_DEBUG_TYPE_WIFI || conn_type > CONN_DEBUG_TYPE_BT) { + pr_err("Incorrect type (%d)\n", conn_type); + return -1; + } + + ctx = &g_netlink_ctx[conn_type]; + mutex_init(&ctx->nl_lock); + ret = genl_register_family(&ctx->gnl_family); + if (ret != 0) { + pr_err("%s(): GE_NELINK family registration fail (ret=%d)\n", __func__, ret); + return -2; + } + ctx->status = LINK_STATUS_INIT_DONE; + memset(ctx->bind_pid, 0, sizeof(ctx->bind_pid)); + ctx->coredump_ctx = dump_ctx; + memcpy(&(ctx->cb), cb, sizeof(struct netlink_event_cb)); + + return ret; +} + +int conndump_netlink_msg_send(struct dump_netlink_ctx* ctx, char* tag, char* buf, unsigned int length, pid_t pid, unsigned int seq) +{ + struct sk_buff *skb; + void* msg_head = NULL; + int ret = 0; + int conn_type = ctx->conn_type; + + /* Allocating a Generic Netlink message buffer */ + skb = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); + if (skb != NULL) { + /* Create message header */ + msg_head = genlmsg_put(skb, 0, seq, &ctx->gnl_family, 0, CONNDUMP_COMMAND_DUMP); + if (msg_head == NULL) { + pr_err("%s(): genlmsg_put fail(conn_type=%d).\n", __func__, conn_type); + nlmsg_free(skb); + return -EMSGSIZE; + } + /* Add message attribute and content */ + ret = nla_put_string(skb, CONNDUMP_ATTR_HEADER, tag); + if (ret != 0) { + pr_err("%s(): nla_put_string header fail(conn_type=%d): %d\n", __func__, conn_type, ret); + genlmsg_cancel(skb, msg_head); + nlmsg_free(skb); + return ret; + } + if (length) { + ret = nla_put(skb, CONNDUMP_ATTR_MSG, length, buf); + if (ret != 0) { + pr_err("%s(): nla_put fail(conn_type=%d): %d\n", __func__, conn_type, ret); + genlmsg_cancel(skb, msg_head); + nlmsg_free(skb); + return ret; + } + ret = nla_put_u32(skb, CONNDUMP_ATTR_MSG_SIZE, length); + if (ret != 0) { + pr_err("%s(): nal_put_u32 fail(conn_type=%d): %d\n", __func__, conn_type, ret); + genlmsg_cancel(skb, msg_head); + nlmsg_free(skb); + return ret; + } + } + /* finalize the message */ + genlmsg_end(skb, msg_head); + + /* sending message */ + ret = genlmsg_unicast(&init_net, skb, pid); + } else { + pr_err("Allocate message error\n"); + ret = -ENOMEM; + } + + return ret; +} + +/***************************************************************************** + * FUNCTION + * conndump_send_to_native + * DESCRIPTION + * Send dump content to native layer (AEE or dump service) + * PARAMETERS + * conn_type [IN] subsys type + * tag [IN] the tag for the content (null end string) + * [M] for coredump + * buf [IN] the content to dump (a buffer may not have end character) + * length [IN] dump length + * RETURNS + * + *****************************************************************************/ +int conndump_netlink_send_to_native_internal(struct dump_netlink_ctx* ctx, char* tag, char* buf, unsigned int length) +{ + int killed_num = 0; + int i, j, ret = 0; + unsigned int retry; + + for (i = 0; i < ctx->num_bind_process; i++) { + ret =conndump_netlink_msg_send(ctx, tag, buf, length, ctx->bind_pid[i], ctx->seqnum); + if (ret != 0) { + pr_err("%s(): genlmsg_unicast fail (ret=%d): pid = %d seq=%d tag=%s\n", + __func__, ret, ctx->bind_pid[i], ctx->seqnum, tag); + if (ret == -EAGAIN) { + retry = 0; + while (retry < 100 && ret == -EAGAIN) { + msleep(10); + ret =conndump_netlink_msg_send(ctx, tag, buf, length, ctx->bind_pid[i], ctx->seqnum); + retry ++; + pr_err("%s(): genlmsg_unicast retry (%d)...: ret = %d pid = %d seq=%d tag=%s\n", + __func__, retry, ret, ctx->bind_pid[i], ctx->seqnum, tag); + } + if (ret) { + pr_err("%s(): genlmsg_unicast fail (ret=%d) after retry %d times: pid = %d seq=%d tag=%s\n", + __func__, ret, retry, ctx->bind_pid[i], ctx->seqnum, tag); + } + } + if (ret == -ECONNREFUSED) { + ctx->bind_pid[i] = 0; + killed_num++; + } + } + } + + ctx->seqnum ++; + + /* Clean up invalid bind_pid */ + if (killed_num > 0) { + if (mutex_lock_killable(&ctx->nl_lock)) { + /* if fail to get lock, it is fine to update bind_pid[] later */ + return ret; + } + for (i = 0; i < ctx->num_bind_process - killed_num; i++) { + if (ctx->bind_pid[i] == 0) { + for (j = ctx->num_bind_process - 1; j > i; j--) { + if (ctx->bind_pid[j] > 0) { + ctx->bind_pid[i] = ctx->bind_pid[j]; + ctx->bind_pid[j] = 0; + } + } + } + } + ctx->num_bind_process -= killed_num; + mutex_unlock(&ctx->nl_lock); + } + + return ret; +} + + +/***************************************************************************** + * FUNCTION + * conndump_send_to_native + * DESCRIPTION + * Send dump content to native layer (AEE or dump service) + * PARAMETERS + * conn_type [IN] subsys type + * tag [IN] the tag for the content (null end string) + * [M] for coredump + * buf [IN] the content to dump (a buffer may not have end character) + * length [IN] dump length + * RETURNS + * + *****************************************************************************/ +int conndump_netlink_send_to_native(int conn_type, char* tag, char* buf, unsigned int length) +{ + struct dump_netlink_ctx* ctx; + int idx = 0; + unsigned int send_len; + unsigned int remain_len = length; + int ret; + + pr_info("[%s] conn_type=%d tag=%s buf=0x%x length=%d\n", + __func__, conn_type, tag, buf, length); + if ((conn_type < CONN_DEBUG_TYPE_WIFI || conn_type > CONN_DEBUG_TYPE_BT) || tag == NULL) { + pr_err("Incorrect type (%d), tag = %s\n", conn_type, tag); + return -1; + } + + ctx = &g_netlink_ctx[conn_type]; + if (ctx->status != LINK_STATUS_INIT_DONE) { + pr_err("%s(): netlink should be init (type=%d).\n", __func__, conn_type); + return -2; + } + + if (ctx->num_bind_process == 0) { + pr_err("No bind service\n"); + return -3; + } + + while (remain_len) { + send_len = (remain_len > CONNSYS_DUMP_PKT_SIZE? CONNSYS_DUMP_PKT_SIZE : remain_len); + ret = conndump_netlink_send_to_native_internal(ctx, tag, &buf[idx], send_len); + if (ret) { + pr_err("[%s] from %d with len=%d fail, ret=%d\n", __func__, idx, send_len, ret); + break; + } + remain_len -= send_len; + idx += send_len; + } + return idx; +} + diff --git a/drivers/misc/mediatek/connectivity/conninfra/debug_utility/coredump/conndump_netlink.h b/drivers/misc/mediatek/connectivity/conninfra/debug_utility/coredump/conndump_netlink.h new file mode 100755 index 0000000000000000000000000000000000000000..70f351759318be53a26d4e5613732cb2d441c4cf --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/debug_utility/coredump/conndump_netlink.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#ifndef _CONNDUMP_NETLINK_H_ +#define _CONNDUMP_NETLINK_H_ + +#include +#include + +#include "coredump/connsys_coredump.h" + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +struct netlink_event_cb { + void (*coredump_end)(void*); +}; + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +int conndump_netlink_init(int conn_type, void* dump_ctx, struct netlink_event_cb* cb); +int conndump_netlink_send_to_native(int conn_type, char* tag, char* buf, unsigned int length); + + +#endif /*_CONNDUMP_NETLINK_H_ */ diff --git a/drivers/misc/mediatek/connectivity/conninfra/debug_utility/coredump/connsys_coredump.c b/drivers/misc/mediatek/connectivity/conninfra/debug_utility/coredump/connsys_coredump.c new file mode 100755 index 0000000000000000000000000000000000000000..c06a5a5ddda3dadb5015b6726c227b9c13f8834e --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/debug_utility/coredump/connsys_coredump.c @@ -0,0 +1,1704 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#if defined(CONNINFRA_PLAT_ALPS) && CONNINFRA_PLAT_ALPS +#include +#endif +#include "conninfra.h" +#include "connsys_debug_utility.h" +#include "connsys_coredump.h" +#include "connsys_coredump_emi.h" +#include "connsys_coredump_hw_config.h" +#include "conndump_netlink.h" + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +#define DEBUG_MODE 1 + +#define CONNSYS_DUMP_INFO_SIZE 180 +#define CONNSYS_ASSERT_INFO_SIZE 164 +#define CONNSYS_ASSERT_TYPE_SIZE 64 +#define CONNSYS_ASSERT_KEYWORD_SIZE 64 +#define CONNSYS_ASSERT_REASON_SIZE 128 +#define CONNSYS_AEE_INFO_SIZE 240 + +#define INFO_HEAD ";CONSYS FW CORE," +#define WDT_INFO_HEAD "Watch Dog Timeout" + +enum fw_coredump_status { + FW_DUMP_STATE_NOT_START = 0, + FW_DUMP_STATE_PUTTING = 1, + FW_DUMP_STATE_PUT_DONE = 2, + FW_DUMP_STATE_END, +}; + +enum core_dump_state { + CORE_DUMP_INIT = 0, + CORE_DUMP_START, + CORE_DUMP_DOING, + CORE_DUMP_TIMEOUT, /* Coredump timeout */ + CORE_DUMP_EMI_TIMEOUT, /* EMI dump timeout */ + CORE_DUMP_EMI, /* start for EMI dump */ + CORE_DUMP_DONE, + CORE_DUMP_INVALID, + CORE_DUMP_MAX, +}; + +enum connsys_issue_type { + CONNSYS_ISSUE_FW_ASSERT = 0, + CONNSYS_ISSUE_FW_EXCEPTION, + CONNSYS_ISSUE_DRIVER_ASSERT, + CONNSYS_ISSUE_MAX, +}; + +struct connsys_dump_info { + enum connsys_issue_type issue_type; + char dump_info[CONNSYS_DUMP_INFO_SIZE]; + char assert_info[CONNSYS_ASSERT_INFO_SIZE]; + unsigned int fw_task_id; + unsigned int fw_isr; + unsigned int fw_irq; + unsigned int exp_ipc; + unsigned int exp_eva; + char etype[CONNSYS_ASSERT_INFO_SIZE]; + char assert_type[CONNSYS_ASSERT_TYPE_SIZE]; + char exception_log[CONNSYS_AEE_INFO_SIZE]; + int drv_type; + char reason[CONNSYS_ASSERT_REASON_SIZE]; + char keyword[CONNSYS_ASSERT_KEYWORD_SIZE]; +}; + +struct connsys_dump_ctx { + int conn_type; + phys_addr_t emi_phy_addr_base; + void __iomem *emi_virt_addr_base; + unsigned int emi_size; + unsigned int mcif_emi_size; + struct coredump_event_cb callback; + struct timer_list dmp_timer; + struct completion emi_dump; + enum core_dump_state sm; + char* page_dump_buf; + struct dump_region* dump_regions; + int dump_regions_num; + unsigned int dynamic_map_cr; + struct coredump_hw_config hw_config; + struct connsys_dump_info info; + unsigned int full_emi_size; +}; + +#define DUMP_REGION_NAME_LENGTH 10 +/* TODO: Need check */ +#define DUMP_REGION_DEFAULT_NUM 50 + +enum dump_region_type { + DUMP_TYPE_CR = 0, + DUMP_TYPE_ROM, + DUMP_TYPE_ILM, + DUMP_TYPE_DLM, + DUMP_TYPE_SRAM, + DUMP_TYPE_SYS1, + DUMP_TYPE_SYS2, + DUMP_TYPE_MAX, +}; + +struct dump_region { + int dump_type; + char name[DUMP_REGION_NAME_LENGTH]; + unsigned int base; + unsigned int length; +}; + +static atomic_t g_dump_mode = ATOMIC_INIT(DUMP_MODE_DAEMON); + +static const char* g_type_name[] = { + "Wi-Fi", + "BT", +}; + +/******************************************************************************* +* MACROS +******************************************************************************** +*/ + +#if DEBUG_MODE +#if defined(CONFIG_FPGA_EARLY_PORTING) +/* For FPGA shorten the timer */ +#define CONNSYS_COREDUMP_TIMEOUT (1*10*1000) +#define CONNSYS_EMIDUMP_TIMEOUT (10*1000) +#else +#define CONNSYS_COREDUMP_TIMEOUT (1*10*1000) +#define CONNSYS_EMIDUMP_TIMEOUT (60*1000) +#endif +#else +#define CONNSYS_COREDUMP_TIMEOUT (10*1000) +#define CONNSYS_EMIDUMP_TIMEOUT (60*1000) +#endif + +#define CONNSYS_DUMP_BUFF_SIZE (32*1024*sizeof(char)) + +#define EMI_READ32(addr) (readl(addr)) +#define EMI_READ8(addr) (readb(addr)) +#define DUMP_LOG_BYTES_PER_LINE (128) +#define IS_VISIBLE_CHAR(c) ((c) >= 32 && (c) <= 126) + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +static void conndump_set_dump_state(struct connsys_dump_ctx* ctx, enum core_dump_state state); +static enum core_dump_state conndump_get_dump_state(struct connsys_dump_ctx* ctx); +static void conndump_timeout_handler(unsigned long data); +static inline int conndump_get_dmp_info(struct connsys_dump_ctx* ctx, unsigned int offset, bool log); +/* Dynamic remap relative function */ +static unsigned int conndump_setup_dynamic_remap(struct connsys_dump_ctx* ctx, unsigned int base, unsigned int length); +static void __iomem* conndump_remap(struct connsys_dump_ctx* ctx, unsigned int base, unsigned int length); +static void conndump_unmap(struct connsys_dump_ctx* ctx, void __iomem* vir_addr); +/* To dump different partition */ +static void conndump_dump_log(char* buf, int size); +static int conndump_dump_print_buff(struct connsys_dump_ctx* ctx); +static int conndump_dump_dump_buff(struct connsys_dump_ctx* ctx); +static int conndump_dump_cr_regions(struct connsys_dump_ctx* ctx); +static int conndump_dump_mem_regions(struct connsys_dump_ctx* ctx); +static int conndump_dump_emi(struct connsys_dump_ctx* ctx); +static int conndump_send_fake_coredump(struct connsys_dump_ctx* ctx); +/* Utility */ +static bool conndump_check_cr_readable(struct connsys_dump_ctx* ctx); +static int conndump_info_format( + struct connsys_dump_ctx* ctx, + char* buf, unsigned int max_len, + bool full_dump); +static void conndump_exception_show(struct connsys_dump_ctx* ctx, bool full_dump); +/* memory allocate/free */ +static void* conndump_malloc(unsigned int size); +static void conndump_free(const void* dst); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +/* Platform relative function */ +/* ------------------------------------------------------------------------------*/ +struct coredump_hw_config* __weak get_coredump_platform_config(int conn_type) +{ + pr_err("[%s] Miss platform ops!\n", __func__); + return NULL; +} + +unsigned int __weak get_coredump_platform_chipid(void) +{ + pr_err("[%s] Miss platform ops!\n", __func__); + return 0; +} + +char* __weak get_task_string(int conn_type, int task_id) +{ + pr_err("[%s] Miss platform ops!\n", __func__); + return "ERROR"; +} + +char* __weak get_sys_name(int conn_type) +{ + pr_err("[%s] Miss platform ops!\n", __func__); + return "ERROR"; +} + +bool __weak is_host_view_cr(unsigned int addr, unsigned int* host_view) +{ + pr_err("[%s] Miss platform ops!\n", __func__); + return false; +} + +/*----------------------------------------------------------------------------*/ + + +static unsigned long timeval_to_ms(struct timeval *begin, struct timeval *end) +{ + unsigned long time_diff; + + time_diff = (end->tv_sec - begin->tv_sec) * 1000; + time_diff += (end->tv_usec - begin->tv_usec) / 1000; + + return time_diff; +} + +static void* conndump_malloc(unsigned int size) +{ + void* p = NULL; + + if (size > (PAGE_SIZE << 1)) + p = vmalloc(size); + else + p = kmalloc(size, GFP_KERNEL); + + /* If there is fragment, kmalloc may not get memory when size > one page. + * For this case, use vmalloc instead. + */ + if (p == NULL && size > PAGE_SIZE) + p = vmalloc(size); + return p; +} + +static void conndump_free(const void* dst) +{ + kvfree(dst); +} + + +static bool conndump_check_cr_readable(struct connsys_dump_ctx* ctx) +{ + int cb_ret = 0; + + /* Check reg readable */ + if (ctx->callback.reg_readable) { + cb_ret = ctx->callback.reg_readable(); + if (cb_ret == 1) { + return true; + } + pr_err("[%s] reg_readable callback ret = %d\n", + g_type_name[ctx->conn_type], cb_ret); + return false; + } + + pr_err("[%s] reg_readable callback is not implement! Return false\n", g_type_name[ctx->conn_type]); + return false; +} + +static void conndump_set_dump_state( + struct connsys_dump_ctx* ctx, enum core_dump_state state) +{ + if (ctx) + ctx->sm = state; +} + +static enum core_dump_state conndump_get_dump_state(struct connsys_dump_ctx* ctx) +{ + if (ctx) + return ctx->sm; + pr_err("%s ctx is null\n", __func__); + return CORE_DUMP_INVALID; +} + +static void conndump_timeout_handler(unsigned long data) +{ + struct connsys_dump_ctx* ctx = (struct connsys_dump_ctx*)data; + + pr_info("[%s] coredump timeout\n", ctx->conn_type); + conndump_set_dump_state(ctx, CORE_DUMP_TIMEOUT); +} + +static inline void conndump_get_dmp_char(struct connsys_dump_ctx* ctx, unsigned int offset, unsigned int byte_num, char* dest) +{ + int i; + char ret; + + if (!dest) + return; + + for (i = 0; i < byte_num; i++) { + ret = EMI_READ8(ctx->emi_virt_addr_base + offset + i); + dest[i] = ret; + } +} + +static inline int conndump_get_dmp_info(struct connsys_dump_ctx* ctx, unsigned int offset, bool log) +{ + int ret; + + ret = EMI_READ32(ctx->emi_virt_addr_base + offset); + if (log) + pr_info("EMI[0x%x] = 0x%08x\n", offset, ret); + + return ret; +} + +static void conndump_dump_log(char* buf, int size) +{ + int i = 0; + char line[DUMP_LOG_BYTES_PER_LINE + 1]; + + while (size--) { + if (IS_VISIBLE_CHAR(*buf)) + line[i] = *buf; + else + line[i] = '.'; + i++; + buf++; + + if (i >= DUMP_LOG_BYTES_PER_LINE || !size) { + line[i] = 0; + pr_info("page_trace: %s\n", line); + i = 0; + } + } +} + +static int conndump_info_format( + struct connsys_dump_ctx* ctx, + char* buf, + unsigned int max_len, + bool full_dump) +{ +#define FORMAT_STRING(buf, len, max_len, sec_len, fmt, arg...) \ +do { \ + sec_len = snprintf(buf + len, max_len, fmt, ##arg); \ + max_len -= sec_len; \ + len += sec_len; \ + if (max_len <= 0) \ + goto format_finish; \ +} while (0) + + int len = 0; + int ret; + int idx; + int sec_len; + char* drv_name[CONNDRV_TYPE_MAX] = { + "DRV_BT", + "DRV_FM", + "DRV_GPS", + "DRV_WIFI", + "DRV_CONNINFRA", + }; + /* Align with connac1.x and previous version */ + char* task_drv_name[CONNDRV_TYPE_MAX] = { + "Task_DrvBT", + "Task_DrvFM", + "Task_DrvGPS", + "Task_DrvWifi", + "Task_DrvConninfra", + }; + char* task_drv_name2[CONN_DEBUG_TYPE_END] = { + "Task_DrvWifi", + "Task_DrvBT", + }; + + if (!buf) { + pr_err("Invalid input, buf = %p", buf); + return 0; + } + + /* Init buffer */ + memset(buf, '\0', max_len); + FORMAT_STRING(buf, len, max_len, sec_len, "
\n"); + FORMAT_STRING(buf, len, max_len, sec_len, "\tMT%x\n", get_coredump_platform_chipid()); + + /* section */ + FORMAT_STRING(buf, len, max_len, sec_len, + "\t\n\t\t\n\t\t\t%s\n\t\t\n", + ctx->info.assert_info); + if (ctx->info.issue_type == CONNSYS_ISSUE_FW_EXCEPTION) { + FORMAT_STRING(buf, len, max_len, sec_len, + "\t\t\n\t\t\tFW Exception: %s\n\t\t\n", ctx->info.etype); + } else if (ctx->info.issue_type == CONNSYS_ISSUE_FW_ASSERT) { + FORMAT_STRING(buf, len, max_len, sec_len, + "\t\t\n\t\t\t%s\n\t\t\n", ctx->info.assert_type); + } else if (ctx->info.issue_type == CONNSYS_ISSUE_DRIVER_ASSERT) { + FORMAT_STRING(buf, len, max_len, sec_len, + "\t\t\n\t\t\t%s trigger assert\n\t\t\n", drv_name[ctx->info.drv_type]); + } else { + FORMAT_STRING(buf, len, max_len, sec_len, + "\t\t\n\t\t\tUnknown\n\t\t\n"); + } + /* section @{*/ + FORMAT_STRING(buf, len, max_len, sec_len, + "\t\n\t\n\t\t\n"); + + FORMAT_STRING(buf, len, max_len, sec_len, + "\t\t\t%s\n", ctx->hw_config.name); + if (ctx->info.issue_type == CONNSYS_ISSUE_DRIVER_ASSERT) { + /* Driver trigger assert */ + FORMAT_STRING(buf, len, max_len, sec_len, + "\t\t\t%s\n", + task_drv_name[ctx->info.drv_type]); + FORMAT_STRING(buf, len, max_len, sec_len, + "\t\t\tNULL\n"); + FORMAT_STRING(buf, len, max_len, sec_len, + "\t\t\tNULL\n"); + FORMAT_STRING(buf, len, max_len, sec_len, + "\t\t\t%s\n", + drv_name[ctx->info.drv_type]); + FORMAT_STRING(buf, len, max_len, sec_len, + "\t\t\t%s\n", + ctx->info.reason); + } else { + /* FW assert */ + if (full_dump) { + FORMAT_STRING(buf, len, max_len, sec_len, + "\t\t\t%s\n", + get_task_string(ctx->conn_type, ctx->info.fw_task_id)); + FORMAT_STRING(buf, len, max_len, sec_len, + "\t\t\tIRQ_0x%x_%s\n", + ctx->info.fw_irq, + get_sys_name(ctx->conn_type)); + FORMAT_STRING(buf, len, max_len, sec_len, + "\t\t\t0x%x\n", + ctx->info.fw_isr); + } else { + FORMAT_STRING(buf, len, max_len, sec_len, + "\t\t\t%s\n", + task_drv_name2[ctx->conn_type]); + FORMAT_STRING(buf, len, max_len, sec_len, + "\t\t\tNULL\n"); + FORMAT_STRING(buf, len, max_len, sec_len, + "\t\t\tNULL\n"); + } + FORMAT_STRING(buf, len, max_len, sec_len, + "\t\t\t%s\n", + "NULL"); + FORMAT_STRING(buf, len, max_len, sec_len, + "\t\t\t%s\n", + "NULL"); + } + if (strlen(ctx->info.keyword) != 0) { + FORMAT_STRING(buf, len, max_len, sec_len, + "\t\t\t%s\n", + ctx->info.keyword); + } else { + FORMAT_STRING(buf, len, max_len, sec_len, + "\t\t\tNULL\n"); + + } + FORMAT_STRING(buf, len, max_len, sec_len, + "\t\t\n\t\n"); + /* section @}*/ + /* section start @{ */ + FORMAT_STRING(buf, len, max_len, sec_len, "\t\n"); + for (idx = 0; idx < ctx->dump_regions_num; idx++) { + /* Non-empty name means memory regions */ + if (ctx->dump_regions[idx].name[0] != 0) { + FORMAT_STRING(buf, len, max_len, sec_len, + "\t\t<%s>\n\t\t\t0x%x\n\t\t\t0x%x\n\t\t\n", + ctx->dump_regions[idx].name, + ctx->dump_regions[idx].base, + ctx->dump_regions[idx].length, + ctx->dump_regions[idx].name); + } + } + FORMAT_STRING(buf, len, max_len, sec_len, "\t\n"); + /* section end @} */ + FORMAT_STRING(buf, len, max_len, sec_len, "
\n"); + +format_finish: + pr_info("== Issue info ==\n", buf); + pr_info("%s\n", buf); + pr_info("===== END =====\n"); + ret = conndump_netlink_send_to_native(ctx->conn_type, "INFO", buf, len); + if (ret < 0) + pr_err("Send issue info to native fail, ret=%d\n", ret); + return len; +} + +static void conndump_info_analysis( + struct connsys_dump_ctx* ctx, + unsigned int buf_len) +{ + const char* parser_sub_string[] = { + " ", + "id=", + "isr=", + "irq=", + "rc=", + }; + const char* exception_sub_string[] = { + " ", + "ipc=", + "eva=", + "etype:", + }; + char* pStr = ctx->page_dump_buf; + char* pDtr = NULL; + char* pTemp = NULL; + char* pTemp2 = NULL; + unsigned int len; + int remain_array_len = 0, sec_len = 0, idx = 0; + char tempBuf[CONNSYS_ASSERT_TYPE_SIZE] = { 0 }; + int ret, res; + char* type_str; + + /* Check */ + memset(&ctx->info.assert_info[0], '\0', CONNSYS_ASSERT_INFO_SIZE); + type_str = (char*)parser_sub_string[0]; + pDtr = strstr(pStr, type_str); + if (pDtr != NULL) { + if (ctx->info.issue_type != CONNSYS_ISSUE_DRIVER_ASSERT) + ctx->info.issue_type = CONNSYS_ISSUE_FW_ASSERT; + pDtr += strlen(type_str); + pTemp = strchr(pDtr, ' '); + + if (pTemp != NULL) { + idx = 0; + remain_array_len = CONNSYS_ASSERT_INFO_SIZE -1; + sec_len = strlen("assert@"); + memcpy(&ctx->info.assert_info[0], "assert@", sec_len); + idx += sec_len; + remain_array_len -= sec_len; + + len = pTemp - pDtr; + sec_len = (len < remain_array_len ? len : remain_array_len); + if (sec_len > remain_array_len) + goto check_task_id; + memcpy(&ctx->info.assert_info[idx], pDtr, sec_len); + remain_array_len -= sec_len; + idx += sec_len; + + sec_len = strlen("_"); + if (sec_len > remain_array_len) + goto check_task_id; + ctx->info.assert_info[idx] = '_'; + remain_array_len -= sec_len; + idx += sec_len; + + pTemp = strchr(pDtr, '#'); + if (pTemp != NULL) { + pTemp += 1; + pTemp2 = strchr(pTemp, ' '); + if (pTemp2 == NULL) { + pr_err("parser ' ' is not find\n"); + pTemp2 = pTemp + 1; + } + pr_info("(pTemp2 - pTemp)=%d\n", (pTemp2 - pTemp)); + if ((remain_array_len) > (pTemp2 - pTemp)) { + pr_info("Copy %d\n", pTemp2 - pTemp); + memcpy( + &ctx->info.assert_info[idx], + pTemp, + pTemp2 - pTemp); + } else { + pr_info("copy %d\n", (remain_array_len - 1)); + memcpy( + &ctx->info.assert_info[idx], + pTemp, + remain_array_len); + } + } + pr_info("assert info:%s\n", ctx->info.assert_info); + } + } else { + /* FW exception */ + type_str = (char*)exception_sub_string[0]; + pDtr = strstr(pStr, type_str); + if (pDtr == NULL) + goto check_task_id; + + if (ctx->info.issue_type != CONNSYS_ISSUE_DRIVER_ASSERT) + ctx->info.issue_type = CONNSYS_ISSUE_FW_EXCEPTION; + idx = 0; + remain_array_len = CONNSYS_ASSERT_INFO_SIZE; + sec_len = snprintf(&ctx->info.assert_info[idx], remain_array_len, + "%s", "Exception:"); + remain_array_len -= sec_len; + idx += sec_len; + + /* Check ipc */ + type_str = (char*)exception_sub_string[1]; + pDtr = strstr(pDtr, type_str); + if (pDtr == NULL) { + pr_err("Exception substring (%s) not found\n", type_str); + goto check_task_id; + } + pDtr += strlen(type_str); + pTemp = strchr(pDtr, ','); + if (pTemp != NULL) { + len = pTemp - pDtr; + len = (len >= CONNSYS_ASSERT_TYPE_SIZE) ? CONNSYS_ASSERT_TYPE_SIZE - 1 : len; + memcpy(&tempBuf[0], pDtr, len); + tempBuf[len] = '\0'; + ret = kstrtouint(tempBuf, 16, &res); + if (ret) { + pr_err("Convert to uint fail, ret=%d, buf=%s\n", + ret, tempBuf); + } else { + ctx->info.exp_ipc = res; + pr_info("exp_ipc=0x%x\n", ctx->info.exp_ipc); + } + if (remain_array_len > 0) { + sec_len = snprintf(&ctx->info.assert_info[idx], remain_array_len, + " ipc=0x%x", ctx->info.exp_ipc); + remain_array_len -= sec_len; + idx += sec_len; + } + } + + /* Check eva */ + type_str = (char*)exception_sub_string[2]; + pDtr = strstr(pDtr, type_str); + if (pDtr == NULL) { + pr_err("substring (%s) not found\n", type_str); + goto check_task_id; + } + pDtr += strlen(type_str); + pTemp = strchr(pDtr, ','); + if (pTemp != NULL) { + len = pTemp - pDtr; + len = (len >= CONNSYS_ASSERT_TYPE_SIZE) ? CONNSYS_ASSERT_TYPE_SIZE - 1 : len; + memcpy(&tempBuf[0], pDtr, len); + tempBuf[len] = '\0'; + ret = kstrtouint(tempBuf, 16, &res); + if (ret) { + pr_err("Convert to uint fail, ret=%d, buf=%s\n", + ret, tempBuf); + } else { + ctx->info.exp_eva = res; + pr_info("eva addr=0x%x\n", ctx->info.exp_eva); + } + if (remain_array_len > 0) { + sec_len = snprintf( + &ctx->info.assert_info[idx], remain_array_len, + " eva=0x%x", ctx->info.exp_eva); + remain_array_len -= sec_len; + idx += sec_len; + } + } + + /* Check etype */ + type_str = (char*)exception_sub_string[3]; + pDtr = strstr(pDtr, type_str); + if (pDtr == NULL) { + pr_err("Substring(%s) not found\n", type_str); + goto check_task_id; + } + pDtr += strlen(type_str); + pTemp = strchr(pDtr, ','); + if (pTemp != NULL) { + len = pTemp - pDtr; + len = (len >= CONNSYS_ASSERT_TYPE_SIZE) ? CONNSYS_ASSERT_TYPE_SIZE - 1 : len; + memcpy(ctx->info.etype, pDtr, len); + ctx->info.etype[len] = '\0'; + pr_info("etype=%s\n", ctx->info.etype); + if (remain_array_len > 0) { + sec_len = snprintf( + &ctx->info.assert_info[idx], remain_array_len, + " etype=%s", ctx->info.etype); + remain_array_len -= sec_len; + idx += sec_len; + } + } + } + +check_task_id: + /* Check id */ + ctx->info.fw_task_id = 0; + type_str = (char*)parser_sub_string[1]; + pDtr = strstr(pStr, type_str); + if (pDtr == NULL) { + pr_err("parser str is NULL,substring(%s)\n", type_str); + + } else { + pDtr += strlen(type_str); + pTemp = strchr(pDtr, ' '); + + if (pTemp == NULL) { + pr_err("delimiter( ) is not found,substring(%s)\n", + type_str); + } else { + len = pTemp - pDtr; + len = (len >= CONNSYS_ASSERT_TYPE_SIZE) ? CONNSYS_ASSERT_TYPE_SIZE - 1 : len; + memcpy(&tempBuf[0], pDtr, len); + tempBuf[len] = '\0'; + ret = kstrtouint(tempBuf, 16, &res); + if (ret) { + pr_err("Convert to uint fail, ret=%d\n, buf=%s\n", + ret, tempBuf); + } else { + ctx->info.fw_task_id = res; + pr_info("fw task id: %x\n", ctx->info.fw_task_id); + } + } + } + + /* Check ISR */ + ctx->info.fw_isr = 0; + type_str = (char*)parser_sub_string[2]; + pDtr = strstr(pStr, type_str); + if (pDtr == NULL) { + pr_err("parser str is NULL,substring(%s)\n", type_str); + } else { + pDtr += strlen(type_str); + pTemp = strchr(pDtr, ','); + + if (pTemp == NULL) { + pr_err("delimiter(,) is not found,substring(%s)\n", type_str); + } else { + len = pTemp - pDtr; + len = (len >= CONNSYS_ASSERT_TYPE_SIZE) ? CONNSYS_ASSERT_TYPE_SIZE - 1 : len; + memcpy(&tempBuf[0], pDtr, len); + tempBuf[len] = '\0'; + + ret = kstrtouint(tempBuf, 16, &res); + if (ret) { + pr_err("Get fw isr id fail, ret=%d, buf=%s\n", ret, tempBuf); + } else { + ctx->info.fw_isr = res; + pr_info("fw isr str:%x\n", ctx->info.fw_isr); + } + } + } + + /* Check IRQ */ + ctx->info.fw_irq = 0; + type_str = (char*)parser_sub_string[3]; + pDtr = strstr(pStr, type_str); + if (pDtr == NULL) { + pr_err("parser str is NULL,substring(%s)\n", type_str); + } else { + pDtr += strlen(type_str); + pTemp = strchr(pDtr, ','); + if (pTemp == NULL) { + pr_err("delimiter(,) is not found,substring(%s)\n", type_str); + } else { + len = pTemp - pDtr; + len = (len >= CONNSYS_ASSERT_TYPE_SIZE) ? CONNSYS_ASSERT_TYPE_SIZE - 1 : len; + memcpy(&tempBuf[0], pDtr, len); + tempBuf[len] = '\0'; + ret = kstrtouint(tempBuf, 16, &res); + if (ret) { + pr_err("get fw irq id fail ret=%d, buf=%s\n", ret, tempBuf); + } else { + ctx->info.fw_irq = res; + pr_info("fw irq value:%x\n", ctx->info.fw_irq); + } + } + } + + /* Check assert type */ + memset(&ctx->info.assert_type[0], '\0', CONNSYS_ASSERT_TYPE_SIZE); + type_str = (char*)parser_sub_string[4]; + pDtr = strstr(pStr, type_str); + if (pDtr == NULL) { + pr_err("parser str is NULL,substring(%s)\n", type_str); + } else { + pDtr += strlen(type_str); + pTemp = strchr(pDtr, ','); + + if (pTemp == NULL) { + pr_err("delimiter(,) is not found,substring(%s)\n", type_str); + } else { + len = pTemp - pDtr; + len = (len >= CONNSYS_ASSERT_TYPE_SIZE) ? CONNSYS_ASSERT_TYPE_SIZE - 1 : len; + memcpy(&tempBuf[0], pDtr, len); + tempBuf[len] = '\0'; + + if (memcmp(tempBuf, "*", strlen("*")) == 0) + memcpy( + &ctx->info.assert_type[0], + "general assert", + strlen("general assert")); + if (memcmp(tempBuf, WDT_INFO_HEAD, strlen(WDT_INFO_HEAD)) == 0) + memcpy( + &ctx->info.assert_type[0], "wdt", strlen("wdt")); + if (memcmp(tempBuf, "RB_FULL", strlen("RB_FULL")) == 0) { + memcpy(&ctx->info.assert_type[0], tempBuf, len); + pDtr = strstr(&ctx->info.assert_type[0], "RB_FULL("); + if (pDtr == NULL) { + pr_err("parser str is NULL,substring(RB_FULL()\n"); + } else { + pDtr += strlen("RB_FULL("); + pTemp = strchr(pDtr, ')'); + len = pTemp - pDtr; + len = (len >= CONNSYS_ASSERT_TYPE_SIZE) ? CONNSYS_ASSERT_TYPE_SIZE - 1 : len; + memcpy(&tempBuf[0], pDtr, len); + tempBuf[len] = '\0'; + ret = kstrtouint(tempBuf, 16, &res); + if (ret) { + pr_err("get fw task id fail(%d)\n", ret); + } else { + snprintf( + ctx->info.keyword, + CONNSYS_ASSERT_KEYWORD_SIZE, + "RB_FULL_%d_%s", res, + ctx->hw_config.name); + } + } + } + } + pr_info("fw asert type:%s\n", ctx->info.assert_type); + } + + /* Store first several characters */ + len = strlen(ctx->page_dump_buf); + len = (len >= CONNSYS_DUMP_INFO_SIZE) ? CONNSYS_DUMP_INFO_SIZE - 1 : len; + strncpy(ctx->info.dump_info, ctx->page_dump_buf, CONNSYS_DUMP_INFO_SIZE); + ctx->info.dump_info[len] = '\0'; +} + +/***************************************************************************** + * FUNCTION + * conndump_dump_print_buff + * DESCRIPTION + * + * PARAMETERS + * + * RETURNS + * + *****************************************************************************/ +static int conndump_dump_print_buff(struct connsys_dump_ctx* ctx) +{ + int ret = 0; + unsigned int buff_start, buff_len; + int section_len; + + buff_start = CONNSYS_DUMP_PRINT_BUFF_OFFSET; + buff_len = conndump_get_dmp_info(ctx, CONNSYS_DUMP_CTRL_BLOCK_OFFSET + EXP_CTRL_PRINT_BUFF_IDX, true); + + if (buff_len > CONNSYS_DUMP_PRINT_BUFF_SIZE) { + pr_err("Get print buff idx = %d, but the length is %d\n", buff_len, CONNSYS_DUMP_PRINT_BUFF_SIZE); + buff_len = CONNSYS_DUMP_PRINT_BUFF_SIZE; + } + + pr_info("-- paged trace ascii output start --\n"); + while (buff_len > 0) { + memset(ctx->page_dump_buf, '\0', CONNSYS_DUMP_BUFF_SIZE); + section_len = (buff_len > (CONNSYS_DUMP_BUFF_SIZE - 1)) ? (CONNSYS_DUMP_BUFF_SIZE - 1) : buff_len; + memcpy_fromio(ctx->page_dump_buf, ctx->emi_virt_addr_base + buff_start, section_len); + + pr_info("-- paged trace ascii output --\n"); + conndump_dump_log(ctx->page_dump_buf, section_len); + + buff_len -= section_len; + buff_start += section_len; + } + pr_info("-- paged trace ascii output end --\n"); + return ret; +} + +/***************************************************************************** + * FUNCTION + * conndump_dump_dump_buff + * DESCRIPTION + * + * PARAMETERS + * + * RETURNS + * + *****************************************************************************/ +static int conndump_dump_dump_buff(struct connsys_dump_ctx* ctx) +{ + int ret = 0; + unsigned int buff_start, buff_len; + int section_len; + bool first = true; + + buff_start = CONNSYS_DUMP_DUMP_BUFF_OFFSET; + buff_len = conndump_get_dmp_info(ctx, CONNSYS_DUMP_CTRL_BLOCK_OFFSET + EXP_CTRL_DUMP_BUFF_IDX, true); + + if (buff_len > CONNSYS_DUMP_DUMP_BUFF_SIZE) { + pr_err("Get dump buff idx = %d, but the size is %d\n", buff_len, CONNSYS_DUMP_DUMP_BUFF_SIZE); + buff_len = CONNSYS_DUMP_DUMP_BUFF_SIZE; + } + + if (buff_len == 0) { + ret = conndump_send_fake_coredump(ctx); + return ret; + } + + while (buff_len > 0) { + memset(ctx->page_dump_buf, '\0', CONNSYS_DUMP_BUFF_SIZE); + section_len = (buff_len > (CONNSYS_DUMP_BUFF_SIZE - 1)) ? (CONNSYS_DUMP_BUFF_SIZE - 1): buff_len; + memcpy_fromio(ctx->page_dump_buf, ctx->emi_virt_addr_base + buff_start, section_len); + + /* pack it */ + ret = conndump_netlink_send_to_native(ctx->conn_type, "[M]", ctx->page_dump_buf, section_len); + /* For 1st package, analysis it */ + if (first) { + conndump_info_analysis(ctx, section_len); + first = false; + } + + buff_len -= section_len; + buff_start += section_len; + } + return ret; +} + +/***************************************************************************** + * FUNCTION + * conndump_setup_dynamic_remap + * DESCRIPTION + * Setup dynamic remap region + * PARAMETERS + * + * RETURNS + * + *****************************************************************************/ +static unsigned int conndump_setup_dynamic_remap(struct connsys_dump_ctx* ctx, unsigned int base, unsigned int length) +{ + +#define DYNAMIC_MAP_MAX_SIZE 0x300000 + unsigned int map_len = (length > DYNAMIC_MAP_MAX_SIZE? DYNAMIC_MAP_MAX_SIZE : length); + void __iomem* vir_addr = 0; + + if (is_host_view_cr(base, NULL)) { + pr_info("Host view CR: 0x%x, skip dynamic remap\n", base); + return length; + } + + /* Expand to request size */ + vir_addr = ioremap_nocache(ctx->hw_config.seg1_cr, 4); + if (vir_addr) { + iowrite32(ctx->hw_config.seg1_phy_addr + map_len, vir_addr); + iounmap(vir_addr); + } else { + return 0; + } + /* Setup map base */ + vir_addr = ioremap_nocache(ctx->hw_config.seg1_start_addr, 4); + if (vir_addr) { + iowrite32(base, vir_addr); + iounmap(vir_addr); + } else { + return 0; + } + return map_len; +} + +/***************************************************************************** + * FUNCTION + * conndump_remap + * DESCRIPTION + * Map dynamic remap CR region to virtual address + * PARAMETERS + * + * RETURNS + * + *****************************************************************************/ +static void __iomem* conndump_remap(struct connsys_dump_ctx* ctx, unsigned int base, unsigned int length) +{ + void __iomem* vir_addr = 0; + unsigned int host_cr; + + if (is_host_view_cr(base, &host_cr)) { + pr_info("Map 0x%x to 0x%x\n", base, host_cr); + vir_addr = ioremap_nocache(host_cr, length); + } else { + vir_addr = ioremap_nocache(ctx->hw_config.seg1_phy_addr, length); + } + return vir_addr; +} + +/***************************************************************************** + * FUNCTION + * conndump_unmap + * DESCRIPTION + * Unmap virtual address + * PARAMETERS + * + * RETURNS + * + *****************************************************************************/ +static void conndump_unmap(struct connsys_dump_ctx* ctx, void __iomem* vir_addr) +{ + iounmap(vir_addr); +} + + +/***************************************************************************** + * FUNCTION + * conndump_dump_cr_regions + * DESCRIPTION + * + * PARAMETERS + * + * RETURNS + * + *****************************************************************************/ +static int conndump_dump_cr_regions(struct connsys_dump_ctx* ctx) +{ +#define CR_PER_LINE 11 + int ret = 0; + int idx; + unsigned int map_length; + void __iomem *map_base; + unsigned int buff_size = CONNSYS_DUMP_BUFF_SIZE; + /* format is [addr,valu] */ + char per_cr[CR_PER_LINE]; + int i; + int addr, value; + unsigned int buff_idx = 0; + + if (!conndump_check_cr_readable(ctx)) { + pr_err("CR not readable, skip cr dump\n"); + return -1; + } + + for (idx = 0; idx < ctx->dump_regions_num; idx++) { + /* empty name means cr regions */ + if (ctx->dump_regions[idx].name[0] == 0 && + (ctx->dump_regions[idx].base > 0) && + (ctx->dump_regions[idx].base & 0x3) == 0 && + (ctx->dump_regions[idx].length & 0x3) == 0) { + pr_info("[%s][Region %d] base=0x%x size=0x%x\n", __func__, idx, ctx->dump_regions[idx].base, ctx->dump_regions[idx].length); + map_length = conndump_setup_dynamic_remap( + ctx, ctx->dump_regions[idx].base, ctx->dump_regions[idx].length); + /* For CR region, we assume region size should < dynamic remap region. */ + if (map_length != ctx->dump_regions[idx].length) { + pr_err("Expect_size=0x%x map_length=0x%x\n", ctx->dump_regions[idx].length, map_length); + } else { + map_base = conndump_remap(ctx, ctx->dump_regions[idx].base, map_length); + if (!map_base) { + pr_err("[%s][Region %d] remap fail, break\n", __func__, idx); + break; + } + for (i = 0, addr = ctx->dump_regions[idx].base; i < map_length; i+=4, addr+=4) { + value = (*((volatile unsigned int *)(map_base + i))); + per_cr[0] = '['; + memcpy(&per_cr[1], &addr, 4); + per_cr[5] = ','; + memcpy(&per_cr[6], &value, 4); + per_cr[10] = ']'; + if (buff_size < CR_PER_LINE) { + pr_info("[%s] Dump buffer full (%d-th cr), flush to native space.\n", __func__, i); + /* pack it! */ + conndump_netlink_send_to_native(ctx->conn_type, "[M]", ctx->page_dump_buf, buff_idx); + + /* start from buffer start */ + buff_size = CONNSYS_DUMP_BUFF_SIZE; + buff_idx = 0; + memset(ctx->page_dump_buf, 0, CONNSYS_DUMP_BUFF_SIZE); + } + memcpy(&ctx->page_dump_buf[buff_idx], per_cr, CR_PER_LINE); + buff_size -= CR_PER_LINE; + buff_idx += CR_PER_LINE; + } + conndump_unmap(ctx, map_base); + } + } + } + + /* pack remaining item */ + if (buff_idx) { + pr_info("[%s] send remain %d bytes\n", __func__, buff_idx); + conndump_netlink_send_to_native(ctx->conn_type, "[M]", ctx->page_dump_buf, buff_idx); + } + + return ret; +} + +/***************************************************************************** + * FUNCTION + * conndump_nfra_get_phy_addr(&emi_addr, &emi_size); + * DESCRIPTION + * + * PARAMETERS + * + * RETURNS + * + *****************************************************************************/ +static int conndump_dump_mem_regions(struct connsys_dump_ctx* ctx) +{ +#define MEM_REGION_TAG_LENGTH 32 +#define MEM_REGION_MAX_COPY_LENGTH (CONNSYS_DUMP_BUFF_SIZE - MEM_REGION_TAG_LENGTH) + int ret = 0; + int idx; + unsigned int map_length; + void __iomem *map_base; + unsigned int* dump_buff = NULL; + + pr_info("[%s] dump_regions_num=%d\n", __func__, ctx->dump_regions_num); + /* Check reg readable */ + if (!conndump_check_cr_readable(ctx)) { + pr_err("CR not readable, skip memory region dump\n"); + return -1; + } + for (idx = 0; idx < ctx->dump_regions_num; idx++) { + /* Non-empty name means memory regions */ + if (ctx->dump_regions[idx].name[0] != 0 && + (ctx->dump_regions[idx].length > 0) && + (ctx->dump_regions[idx].length & 0x3) == 0 && + (ctx->dump_regions[idx].base & 0x3) == 0) { + pr_info("[%s][Region %d][%s] base=0x%x size=0x%x\n", + __func__, idx, ctx->dump_regions[idx].name, + ctx->dump_regions[idx].base, ctx->dump_regions[idx].length); + /* variable init */ + ret = 0; + dump_buff = (unsigned int*)conndump_malloc(ctx->dump_regions[idx].length); + if (!dump_buff) { + pr_err("Allocate buffer for %s fail.\n", + ctx->dump_regions[idx].name); + goto next_mem_region; + } + /* Change dynamic window */ + map_length = conndump_setup_dynamic_remap( + ctx, ctx->dump_regions[idx].base, ctx->dump_regions[idx].length); + if (map_length != ctx->dump_regions[idx].length) { + pr_err("Setup dynamic remap for %s fail. Expect 0x%x but 0x%x", + ctx->dump_regions[idx].name, + ctx->dump_regions[idx].length, + map_length); + goto next_mem_region; + } + map_base = conndump_remap(ctx, ctx->dump_regions[idx].base, map_length); + if (!map_base) { + pr_err("Remap %s fail.\n", ctx->dump_regions[idx].name); + goto next_mem_region; + } + memcpy_fromio(dump_buff, map_base, map_length); + conndump_unmap(ctx, map_base); + ret = conndump_netlink_send_to_native( + ctx->conn_type, + ctx->dump_regions[idx].name, + (char*)dump_buff, + ctx->dump_regions[idx].length); + if (ret != ctx->dump_regions[idx].length) { + pr_err("[%s][%s] Send fail, length = 0x%x but only 0x%x send\n", + __func__, ctx->dump_regions[idx].name, + ctx->dump_regions[idx].length, ret); + } + } +next_mem_region: + if (dump_buff) { + conndump_free((void*)dump_buff); + dump_buff = NULL; + } + } + return ret; +} + +/***************************************************************************** + * FUNCTION + * conndump_dump_emi + * DESCRIPTION + * + * PARAMETERS + * + * RETURNS + * + *****************************************************************************/ +static int conndump_dump_emi(struct connsys_dump_ctx* ctx) +{ +#define EMI_COMMAND_LENGTH 64 + int ret; + unsigned long comp_ret; + // format: emi_size=aaaaaaaa, mcif_emi_size=bbbbbbbb + char emi_dump_command[EMI_COMMAND_LENGTH]; + + snprintf(emi_dump_command, EMI_COMMAND_LENGTH, "emi_size=%d,mcif_emi_size=%d", ctx->full_emi_size, ctx->mcif_emi_size); + pr_info("[%s] dump command: %s\n", __func__, emi_dump_command); + conndump_set_dump_state(ctx, CORE_DUMP_EMI); + ret = conndump_netlink_send_to_native(ctx->conn_type, "[EMI]", emi_dump_command, strlen(emi_dump_command)); + + if (ret < 0) { + pr_err("Start EMI dump fail, ret = %d\n", ret); + return -1; + } + + comp_ret = wait_for_completion_timeout( + &ctx->emi_dump, + msecs_to_jiffies(CONNSYS_EMIDUMP_TIMEOUT)); + + if (comp_ret == 0) { + pr_err("EMI dump timeout\n"); + conndump_set_dump_state(ctx, CORE_DUMP_EMI_TIMEOUT); + } else { + pr_info("EMI dump end"); + conndump_set_dump_state(ctx, CORE_DUMP_DONE); + } + + return 0; +} + +static int connsys_coredump_init_dump_regions(struct connsys_dump_ctx* ctx, int num) +{ + int size = sizeof(struct dump_region)*num; + + ctx->dump_regions = (struct dump_region*)conndump_malloc(size); + if (!ctx->dump_regions) { + ctx->dump_regions_num = 0; + pr_err("ctx->dump_regions create fail!\n"); + return 0; + } + memset(ctx->dump_regions, 0, size); + ctx->dump_regions_num = num; + return num; +} + +static void connsys_coredump_deinit_dump_regions(struct connsys_dump_ctx* ctx) +{ + conndump_free(ctx->dump_regions); + ctx->dump_regions = 0; + ctx->dump_regions_num = 0; +} + +static void conndump_coredump_end(void* handler) +{ + struct connsys_dump_ctx* ctx = (struct connsys_dump_ctx*)handler; + + if (conndump_get_dump_state(ctx) == CORE_DUMP_EMI) { + pr_info("Wake up emi_dump\n"); + complete(&ctx->emi_dump); + } +} + +static int conndump_send_fake_coredump(struct connsys_dump_ctx* ctx) +{ + pr_info("Send fake coredump\n"); + return conndump_netlink_send_to_native(ctx->conn_type, "[M]", "FORCE_COREDUMP", 13); +} + +static void conndump_exception_show(struct connsys_dump_ctx* ctx, bool full_dump) +{ + if (full_dump) { + snprintf( + ctx->info.exception_log, CONNSYS_AEE_INFO_SIZE, + "%s %s %s %s", + INFO_HEAD, ctx->hw_config.name, + ctx->info.assert_type, ctx->info.dump_info); + } else { + snprintf( + ctx->info.exception_log, CONNSYS_AEE_INFO_SIZE, + "%s %s", + INFO_HEAD, ctx->hw_config.name); + } + +#if defined(CONNINFRA_PLAT_ALPS) && CONNINFRA_PLAT_ALPS + pr_info("par1: [%s] pars: [%s] par3: [%d]\n", + ctx->hw_config.exception_tag_name, + ctx->info.exception_log, + strlen(ctx->info.exception_log)); + /* Call AEE API */ + aed_common_exception_api( + ctx->hw_config.exception_tag_name, + NULL, 0, + (const int*)ctx->info.exception_log, strlen(ctx->info.exception_log), + ctx->info.exception_log, 0); +#endif +} + +/***************************************************************************** + * FUNCTION + * connsys_coredump_clean + * DESCRIPTION + * To clean coredump EMI region + * PARAMETERS + * + * RETURNS + * + *****************************************************************************/ +void connsys_coredump_clean(void* handler) +{ + struct connsys_dump_ctx* ctx = (struct connsys_dump_ctx*)handler; + + if (ctx == NULL) + return; + + pr_info("[%s] Clear %p size=%d as zero\n", __func__, ctx->emi_virt_addr_base, ctx->emi_size); + memset_io(ctx->emi_virt_addr_base, 0, ctx->emi_size); + + conndump_set_dump_state(ctx, CORE_DUMP_INIT); +} +EXPORT_SYMBOL(connsys_coredump_clean); + + +/***************************************************************************** + * FUNCTION + * connsys_coredump_setup_dump_region + * DESCRIPTION + * Parse dump region in EMI (including CR regions, IDLM, SYSRAM, ...) + * The number would be record in ctx->dump_regions_num + * The data would be stored in ctx->dump_regions + * PARAMETERS + * + * RETURNS + * + *****************************************************************************/ +int connsys_coredump_setup_dump_region(void* handler) +{ + int ret = 0; + int cr_regions_idx = 0; + int total_mem_region; + int total_count; + int i, idx = 0, offset; + struct connsys_dump_ctx* ctx = (struct connsys_dump_ctx*)handler; + struct dump_region* curr_region = 0; + + total_mem_region = conndump_get_dmp_info( + ctx, CONNSYS_DUMP_CTRL_BLOCK_OFFSET + EXP_CTRL_TOTAL_MEM_REGION, false); + + /* Get idx first. The number is idx/8 */ + cr_regions_idx = conndump_get_dmp_info( + ctx, CONNSYS_DUMP_CTRL_BLOCK_OFFSET + EXP_CTRL_CR_REGION_IDX, false); + if (cr_regions_idx & 0x7) { + pr_err("cr_regions_idx should be multiple of 8. But it is %d.\n", cr_regions_idx); + } + cr_regions_idx = (cr_regions_idx >> 3); + total_count = total_mem_region + cr_regions_idx; + pr_info("CR region=%d. Memory region=%d total dump regions is %d.\n", + cr_regions_idx, total_mem_region, total_count); + + if (ctx->dump_regions) { + connsys_coredump_deinit_dump_regions(ctx); + } + if (total_count == 0) { + pr_info("Total dump regions is %d.\n", total_count); + return 0; + } + + ret = connsys_coredump_init_dump_regions(ctx, total_count); + if (ret != total_count) { + pr_err("[%s] allocate %d dump regions failed\n", __func__, total_count); + return 0; + } + + /* Setup memory region */ + offset = CONNSYS_DUMP_CTRL_BLOCK_OFFSET + EXP_CTRL_MEM_REGION_NAME_1; + for (i = 0, curr_region = ctx->dump_regions; i < total_mem_region && idx < total_count; i++, idx++, offset += 12, curr_region++) { + conndump_get_dmp_char(ctx, offset, 4, curr_region->name); + curr_region->base = conndump_get_dmp_info(ctx, offset + 4, false); + curr_region->length = conndump_get_dmp_info(ctx, offset + 8, false); + pr_info("[%d][Memory region] name: %s, base: %x, length: %x\n", + idx, + curr_region->name, + curr_region->base, + curr_region->length); + } + + offset = CONNSYS_DUMP_CR_REGION_OFFSET; + for (i = 0; i < cr_regions_idx && idx < total_count; i++, idx++, offset+=8) { + ctx->dump_regions[idx].base = conndump_get_dmp_info(ctx, offset, false); + ctx->dump_regions[idx].length = conndump_get_dmp_info(ctx, offset + 4, false); + pr_info("[%d][CR region] base: 0x%x, length: %d\n", + idx, ctx->dump_regions[idx].base, ctx->dump_regions[idx].length); + } + return ctx->dump_regions_num; +} +EXPORT_SYMBOL(connsys_coredump_setup_dump_region); + +/***************************************************************************** + * FUNCTION + * connsys_coredump_start + * DESCRIPTION + * + * PARAMETERS + * + * RETURNS + * + *****************************************************************************/ +int connsys_coredump_start( + void* handler, + unsigned int dump_property, + int drv, + char* reason) +{ + struct connsys_dump_ctx* ctx = (struct connsys_dump_ctx*)handler; + int ret = 0; + bool full_dump = false; + struct timeval begin, end, put_done; + struct timeval mem_start, mem_end, cr_start, cr_end, emi_dump_start, emi_dump_end; + + static DEFINE_RATELIMIT_STATE(_rs, HZ, 1); + + if (ctx == NULL) + return 0; + + /* TODO: Check coredump mode */ + if (connsys_coredump_get_mode() == DUMP_MODE_RESET_ONLY) { + pr_info("Chip reset only, skip coredump\n"); + return 0; + } + + pr_info("[COREDUMP] dump_property=[0x%x] drv=[%d] reason=[%s]\n", dump_property, drv, reason); + do_gettimeofday(&begin); + conndump_set_dump_state(ctx, CORE_DUMP_START); + /* Reset assert info */ + memset(&ctx->info, 0, sizeof(struct connsys_dump_info)); + if (drv >= CONNDRV_TYPE_BT && drv < CONNDRV_TYPE_MAX) { + ctx->info.issue_type = CONNSYS_ISSUE_DRIVER_ASSERT; + ctx->info.drv_type = drv; + snprintf(ctx->info.reason, CONNSYS_ASSERT_REASON_SIZE, "%s", reason); + } + + /* Start coredump timer */ + mod_timer(&ctx->dmp_timer, jiffies + (CONNSYS_COREDUMP_TIMEOUT) / (1000 / HZ)); + + /* Check coredump status */ + while (1) { + if (conndump_get_dmp_info(ctx, CONNSYS_DUMP_CTRL_BLOCK_OFFSET + EXP_CTRL_DUMP_STATE, false) == FW_DUMP_STATE_PUT_DONE) { + pr_info("coredump put done\n"); + del_timer(&ctx->dmp_timer); + full_dump = true; + break; + } else if (conndump_get_dump_state(ctx) == CORE_DUMP_TIMEOUT) { + pr_err("Coredump timeout\n"); + if (ctx->callback.poll_cpupcr) { + pr_info("Debug dump:\n"); + ctx->callback.poll_cpupcr(5, 1); + } + conndump_send_fake_coredump(ctx); + goto partial_dump; + } + if (__ratelimit(&_rs)) { + pr_info("Wait coredump state, EMI[0]=0x%x EMI[4]=0x%x\n", + conndump_get_dmp_info(ctx, 0, false), + conndump_get_dmp_info(ctx, 4, false)); + } + if (dump_property & CONNSYS_DUMP_PROPERTY_NO_WAIT) { + pr_info("Don't wait dump status, go to partial dump\n"); + if (ctx->callback.poll_cpupcr) { + pr_info("Debug dump:\n"); + ctx->callback.poll_cpupcr(5, 1); + } + conndump_send_fake_coredump(ctx); + goto partial_dump; + } + msleep(1); + } + do_gettimeofday(&put_done); + conndump_set_dump_state(ctx, CORE_DUMP_DOING); + + /* Get print_buff */ + conndump_dump_print_buff(ctx); + + /* Get dump_buff and send to pack it */ + conndump_dump_dump_buff(ctx); + +partial_dump: + /* TODO: move to init or other suitable place */ + ret = connsys_coredump_setup_dump_region(ctx); + if (!ret) + pr_err("No dump region found\n"); + + conndump_set_dump_state(ctx, CORE_DUMP_DOING); + /* Memory region and CR region should be setup when MCU init */ + /* Parse CR region and send to pack it */ + do_gettimeofday(&cr_start); + conndump_dump_cr_regions(ctx); + do_gettimeofday(&cr_end); + + /* Construct assert info and send to native */ + conndump_info_format(ctx, ctx->page_dump_buf, CONNSYS_DUMP_BUFF_SIZE, full_dump); + + /* Read memory region on ctrl block */ + do_gettimeofday(&mem_start); + conndump_dump_mem_regions(ctx); + do_gettimeofday(&mem_end); + + + /* Start EMI dump */ + do_gettimeofday(&emi_dump_start); + conndump_dump_emi(ctx); + do_gettimeofday(&emi_dump_end); + + /* All process finished, set to init status */ + conndump_set_dump_state(ctx, CORE_DUMP_INIT); + + conndump_exception_show(ctx, full_dump); + do_gettimeofday(&end); + pr_info("Coredump end\n"); + if (full_dump) { + pr_info("%s coredump summary: full dump total=[%lu] put_done=[%lu] cr=[%lu] mem=[%lu] emi=[%lu]\n", + g_type_name[ctx->conn_type], + timeval_to_ms(&begin, &end), + timeval_to_ms(&begin, &put_done), + timeval_to_ms(&cr_start, &cr_end), + timeval_to_ms(&mem_start, &mem_end), + timeval_to_ms(&emi_dump_start, &emi_dump_end)); + } else { + pr_info("%s coredump summary: partial dump total=[%lu] cr=[%lu] mem=[%lu] emi=[%lu]\n", + g_type_name[ctx->conn_type], + timeval_to_ms(&begin, &end), + timeval_to_ms(&cr_start, &cr_end), + timeval_to_ms(&mem_start, &mem_end), + timeval_to_ms(&emi_dump_start, &emi_dump_end)); + } + return 0; +} +EXPORT_SYMBOL(connsys_coredump_start); + +/***************************************************************************** + * FUNCTION + * connsys_coredump_get_start_offset + * DESCRIPTION + * + * PARAMETERS + * + * RETURNS + * + *****************************************************************************/ +phys_addr_t connsys_coredump_get_start_offset(int conn_type) +{ + struct coredump_hw_config *config = get_coredump_platform_config(conn_type); + + if (config) + return config->start_offset; + return 0; +} +EXPORT_SYMBOL(connsys_coredump_get_start_offset); + +/***************************************************************************** + * FUNCTION + * connsys_coredump_init + * DESCRIPTION + * + * PARAMETERS + * + * RETURNS + * + *****************************************************************************/ +void* connsys_coredump_init( + int conn_type, + struct coredump_event_cb* cb) +{ + struct connsys_dump_ctx* ctx = 0; + struct netlink_event_cb nl_cb; + struct coredump_hw_config *config = get_coredump_platform_config(conn_type); + phys_addr_t emi_base; + unsigned int emi_size, mcif_emi_size; + + /* Get EMI config */ + if (config == NULL) { + pr_err("Get coredump EMI config fail\n"); + goto error_exit; + } + + ctx = (struct connsys_dump_ctx*)conndump_malloc(sizeof(struct connsys_dump_ctx)); + if (!ctx) { + pr_err("Allocate connsys_dump_ctx fail"); + goto error_exit; + } + + /* clean it */ + memset(ctx, 0, sizeof(struct connsys_dump_ctx)); + memcpy(&ctx->hw_config, config, sizeof(struct coredump_hw_config)); + + ctx->page_dump_buf = (char*)conndump_malloc(CONNSYS_DUMP_BUFF_SIZE); + if (!ctx->page_dump_buf) { + pr_err("Create dump buffer fail.\n"); + goto error_exit; + } + + ctx->conn_type = conn_type; + if (cb) + memcpy(&ctx->callback, cb, sizeof(struct coredump_event_cb)); + else + pr_info("[%s][%d] callback is null\n", __func__, conn_type); + + /* EMI init */ + conninfra_get_emi_phy_addr(CONNSYS_EMI_FW, &emi_base, &emi_size); + conninfra_get_emi_phy_addr(CONNSYS_EMI_MCIF, NULL, &mcif_emi_size); + pr_info("Get emi_base=0x%x emi_size=%d\n", emi_base, emi_size); + ctx->full_emi_size = emi_size; + ctx->emi_phy_addr_base = config->start_offset + emi_base; + ctx->emi_size = config->size; + ctx->mcif_emi_size = mcif_emi_size; + + ctx->emi_virt_addr_base = + ioremap_nocache(ctx->emi_phy_addr_base, ctx->emi_size); + if (ctx->emi_virt_addr_base == 0) { + pr_err("Remap emi fail (0x%08x) size=%d", + ctx->emi_phy_addr_base, ctx->emi_size); + goto error_exit; + } + + pr_info("Clear %p size=%d as zero\n", ctx->emi_virt_addr_base, ctx->emi_size); + memset_io(ctx->emi_virt_addr_base, 0, ctx->emi_size); + + /* Setup timer */ + init_timer(&ctx->dmp_timer); + ctx->dmp_timer.function = conndump_timeout_handler; + ctx->dmp_timer.data = (unsigned long)ctx; + init_completion(&ctx->emi_dump); + + conndump_set_dump_state(ctx, CORE_DUMP_INIT); + + /* Init netlink */ + nl_cb.coredump_end = conndump_coredump_end; + conndump_netlink_init(ctx->conn_type, ctx, &nl_cb); + return ctx; + +error_exit: + if (ctx) + connsys_coredump_deinit(ctx); + + return 0; +} +EXPORT_SYMBOL(connsys_coredump_init); + +/***************************************************************************** + * FUNCTION + * connsys_coredump_deinit + * DESCRIPTION + * + * PARAMETERS + * + * RETURNS + * + *****************************************************************************/ +void connsys_coredump_deinit(void* handler) +{ + struct connsys_dump_ctx* ctx = (struct connsys_dump_ctx*)handler; + + if (handler == NULL) + return; + + if (ctx->emi_virt_addr_base) { + iounmap(ctx->emi_virt_addr_base); + ctx->emi_virt_addr_base = NULL; + } + + if (ctx->page_dump_buf) { + conndump_free(ctx->page_dump_buf); + ctx->page_dump_buf = NULL; + } + + if (ctx->dump_regions) { + connsys_coredump_deinit_dump_regions(ctx); + ctx->dump_regions = NULL; + } + + conndump_free(ctx); +} +EXPORT_SYMBOL(connsys_coredump_deinit); + + +/***************************************************************************** + * FUNCTION + * connsys_coredump_get_mode + * DESCRIPTION + * + * PARAMETERS + * + * RETURNS + * + *****************************************************************************/ +enum connsys_coredump_mode connsys_coredump_get_mode(void) +{ + return atomic_read(&g_dump_mode); +} +EXPORT_SYMBOL(connsys_coredump_get_mode); + +/***************************************************************************** + * FUNCTION + * connsys_coredump_set_dump_mode + * DESCRIPTION + * + * PARAMETERS + * + * RETURNS + * + *****************************************************************************/ +void connsys_coredump_set_dump_mode(enum connsys_coredump_mode mode) +{ + if (mode < DUMP_MODE_MAX) + atomic_set(&g_dump_mode, mode); +} +EXPORT_SYMBOL(connsys_coredump_set_dump_mode); + + diff --git a/drivers/misc/mediatek/connectivity/conninfra/debug_utility/coredump/connsys_coredump.h b/drivers/misc/mediatek/connectivity/conninfra/debug_utility/coredump/connsys_coredump.h new file mode 100755 index 0000000000000000000000000000000000000000..609f60b7008d291a46d1d3359b644b96e4714ec8 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/debug_utility/coredump/connsys_coredump.h @@ -0,0 +1,63 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#ifndef _CONNSYS_COREDUMP_H_ +#define _CONNSYS_COREDUMP_H_ + +#include +#include + + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/* Coredump property */ +#define CONNSYS_DUMP_PROPERTY_NO_WAIT 0x1 + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +enum connsys_coredump_mode { + DUMP_MODE_RESET_ONLY = 0, + DUMP_MODE_AEE = 1, + DUMP_MODE_DAEMON = 2, + DUMP_MODE_MAX, +}; + +struct coredump_event_cb { + int (*reg_readable)(void); + void (*poll_cpupcr)(unsigned int times, unsigned int sleep); +}; + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/* subsys usage */ +void* connsys_coredump_init( + int conn_type, + struct coredump_event_cb* cb); +void connsys_coredump_deinit(void* handler); + +phys_addr_t connsys_coredump_get_start_offset(int conn_type); + +int connsys_coredump_setup_dump_region(void* handler); +int connsys_coredump_start( + void* handler, + unsigned int dump_property, + int drv, + char *reason); +void connsys_coredump_clean(void* handler); + + +/* config relative */ +enum connsys_coredump_mode connsys_coredump_get_mode(void); +void connsys_coredump_set_dump_mode(enum connsys_coredump_mode mode); + +#endif diff --git a/drivers/misc/mediatek/connectivity/conninfra/debug_utility/coredump/connsys_coredump_emi.h b/drivers/misc/mediatek/connectivity/conninfra/debug_utility/coredump/connsys_coredump_emi.h new file mode 100755 index 0000000000000000000000000000000000000000..b52140429305ee929ff79b5ca7ed56f52bcc411c --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/debug_utility/coredump/connsys_coredump_emi.h @@ -0,0 +1,69 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef _CONNSYS_COREDUMP_EMI_H_ +#define _CONNSYS_COREDUMP_EMI_H_ + +#include +#include + + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + + +/* Block and size definition */ +#define CONNSYS_DUMP_CTRL_BLOCK_SIZE 0x80 +#define CONNSYS_DUMP_DEBUG_BLOCK_SIZE 0x80 +#define CONNSYS_DUMP_PRINT_BUFF_SIZE 0x7f00 +#define CONNSYS_DUMP_DUMP_BUFF_SIZE 0x8000 +#define CONNSYS_DUMP_CR_REGION_SIZE 0x8000 + +#define CONNSYS_DUMP_CTRL_BLOCK_OFFSET 0x0 +#define CONNSYS_DUMP_DEBUG_BLOCK_OFFSET (CONNSYS_DUMP_CTRL_BLOCK_OFFSET + CONNSYS_DUMP_CTRL_BLOCK_SIZE) +#define CONNSYS_DUMP_PRINT_BUFF_OFFSET (CONNSYS_DUMP_DEBUG_BLOCK_OFFSET + CONNSYS_DUMP_DEBUG_BLOCK_SIZE) +#define CONNSYS_DUMP_DUMP_BUFF_OFFSET (CONNSYS_DUMP_PRINT_BUFF_OFFSET + CONNSYS_DUMP_PRINT_BUFF_SIZE) +#define CONNSYS_DUMP_CR_REGION_OFFSET (CONNSYS_DUMP_DUMP_BUFF_OFFSET + CONNSYS_DUMP_DUMP_BUFF_SIZE) + +/* Control block definition */ +enum connsys_dump_ctrl_block_offset { + EXP_CTRL_DUMP_STATE = 0x4, + EXP_CTRL_OUTBAND_ASSERT_W1 = 0x8, + EXP_CTRL_PRINT_BUFF_IDX = 0xC, + EXP_CTRL_DUMP_BUFF_IDX = 0x10, + EXP_CTRL_CR_REGION_IDX = 0x14, + EXP_CTRL_TOTAL_MEM_REGION = 0x18, + EXP_CTRL_MEM_REGION_NAME_1 = 0x1C, + EXP_CTRL_MEM_REGION_START_1 = 0x20, + EXP_CTRL_MEM_REGION_LEN_1 = 0x24, + EXP_CTRL_MEM_REGION_NAME_2 = 0x28, + EXP_CTRL_MEM_REGION_START_2 = 0x2c, + EXP_CTRL_MEM_REGION_LEN_2 = 0x30, + EXP_CTRL_MEM_REGION_NAME_3 = 0x34, + EXP_CTRL_MEM_REGION_START_3 = 0x38, + EXP_CTRL_MEM_REGION_LEN_3 = 0x3c, + EXP_CTRL_MEM_REGION_NAME_4 = 0x40, + EXP_CTRL_MEM_REGION_START_4 = 0x44, + EXP_CTRL_MEM_REGION_LEN_4 = 0x48, + EXP_CTRL_MEM_REGION_NAME_5 = 0x4C, + EXP_CTRL_MEM_REGION_START_5 = 0x50, + EXP_CTRL_MEM_REGION_LEN_5 = 0x54, +}; + + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + + +#endif /*_CONNSYS_COREDUMP_EMI_H_*/ diff --git a/drivers/misc/mediatek/connectivity/conninfra/debug_utility/coredump/platform/include/connsys_coredump_hw_config.h b/drivers/misc/mediatek/connectivity/conninfra/debug_utility/coredump/platform/include/connsys_coredump_hw_config.h new file mode 100755 index 0000000000000000000000000000000000000000..d150804e7d9290eb9e5fc284cdeb9fe80b7be01d --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/debug_utility/coredump/platform/include/connsys_coredump_hw_config.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef _CONNSYS_COREDUMP_HW_CONFIG_H_ +#define _CONNSYS_COREDUMP_HW_CONFIG_H_ + + +struct coredump_hw_config { + char* name; + phys_addr_t start_offset; + unsigned int size; + unsigned int seg1_cr; + unsigned int seg1_value_end; + unsigned int seg1_start_addr; + unsigned int seg1_phy_addr; + unsigned int task_table_size; + char** task_map_table; + char* exception_tag_name; +}; + +#endif + diff --git a/drivers/misc/mediatek/connectivity/conninfra/debug_utility/coredump/platform/mt6885/mt6885.c b/drivers/misc/mediatek/connectivity/conninfra/debug_utility/coredump/platform/mt6885/mt6885.c new file mode 100755 index 0000000000000000000000000000000000000000..3ebcf97c432f14e5f5c3b6416769588ef33cdfa8 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/debug_utility/coredump/platform/mt6885/mt6885.c @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include + +#include "connsys_debug_utility.h" +#include "connsys_coredump_hw_config.h" + +static char* wifi_task_str[] = { + "Task_WIFI", + "Task_TST_WFSYS", + "Task_Idle_WFSYS", +}; + +static char* bt_task_str[] = { + "Task_WMT", + "Task_BT", + "Task_TST_BTSYS", + "Task_BT2", + "Task_Idle_BTSYS", +}; + +struct coredump_hw_config g_coredump_config[CONN_DEBUG_TYPE_END] = { + /* Wi-Fi config */ + { + .name = "WFSYS", +#ifdef CONFIG_FPGA_EARLY_PORTING + .start_offset = 0x0004f000, +#else + .start_offset = 0x027f000, +#endif + .size = 0x18000, + .seg1_cr = 0x1800112c, + .seg1_value_end = 0x187fffff, + .seg1_start_addr = 0x18001120, + .seg1_phy_addr = 0x18500000, + .task_table_size = sizeof(wifi_task_str)/sizeof(char*), + .task_map_table = wifi_task_str, + .exception_tag_name = "combo_wifi", + }, + /* BT config */ + { + .name = "BTSYS", + .start_offset = 0x33000, + .size = 0x18000, + .seg1_cr = 0x18001110, + .seg1_value_end = 0x18bfffff, + .seg1_start_addr = 0x18001104, + .seg1_phy_addr = 0x18900000, + .task_table_size = sizeof(bt_task_str)/sizeof(char*), + .task_map_table = bt_task_str, + .exception_tag_name = "combo_bt", + }, +}; + +struct coredump_hw_config* get_coredump_platform_config(int conn_type) +{ + if (conn_type < 0 || conn_type >= CONN_DEBUG_TYPE_END) { + pr_err("Incorrect type: %d\n", conn_type); + return NULL; + } + return &g_coredump_config[conn_type]; +} + +unsigned int get_coredump_platform_chipid(void) +{ + return 0x6885; +} + +char* get_task_string(int conn_type, unsigned int task_id) +{ + if (conn_type < 0 || conn_type >= CONN_DEBUG_TYPE_END) { + pr_err("Incorrect type: %d\n", conn_type); + return NULL; + } + + if (task_id > g_coredump_config[conn_type].task_table_size) { + pr_err("[%s] Incorrect task: %d\n", + g_coredump_config[conn_type].name, task_id); + return NULL; + } + + return g_coredump_config[conn_type].task_map_table[task_id]; +} + +char* get_sys_name(int conn_type) +{ + if (conn_type < 0 || conn_type >= CONN_DEBUG_TYPE_END) { + pr_err("Incorrect type: %d\n", conn_type); + return NULL; + } + return g_coredump_config[conn_type].name; +} + +bool is_host_view_cr(unsigned int addr, unsigned int* host_view) +{ + if (addr >= 0x7C000000 && addr <= 0x7Cffffff) { + if (host_view) { + *host_view = ((addr - 0x7c000000) + 0x18000000); + } + return true; + } else if (addr >= 0x18000000 && addr <= 0x18ffffff) { + if (host_view) { + *host_view = addr; + } + return true; + } + return false; +} diff --git a/drivers/misc/mediatek/connectivity/conninfra/debug_utility/include/connsys_debug_utility.h b/drivers/misc/mediatek/connectivity/conninfra/debug_utility/include/connsys_debug_utility.h new file mode 100644 index 0000000000000000000000000000000000000000..897bda5009825976dc9f6b11a9ce048946c216b3 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/debug_utility/include/connsys_debug_utility.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#ifndef _CONNSYS_DEBUG_UTILITY_H_ +#define _CONNSYS_DEBUG_UTILITY_H_ + +#include +#include + +#include "coredump/connsys_coredump.h" +#include "connsyslog/connsyslog.h" + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +enum CONN_DEBUG_TYPE { + CONN_DEBUG_TYPE_WIFI = 0, + CONN_DEBUG_TYPE_BT = 1, + CONN_DEBUG_TYPE_END, +}; + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + + +#endif /*_CONNSYS_DEBUG_UTILITY_H_*/ diff --git a/drivers/misc/mediatek/connectivity/conninfra/drv_init/bluetooth_drv_init.c b/drivers/misc/mediatek/connectivity/conninfra/drv_init/bluetooth_drv_init.c new file mode 100644 index 0000000000000000000000000000000000000000..ec4b05641c21403b47e77fd9a8da59f4f90f5b35 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/drv_init/bluetooth_drv_init.c @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include +#include "bluetooth_drv_init.h" + +#ifdef CONFIG_MTK_COMBO_BT +int __attribute__((weak)) mtk_wcn_stpbt_drv_init() +{ + pr_info("Not implement mtk_wcn_stpbt_drv_init\n"); + return 0; +} +#endif + +int do_bluetooth_drv_init(int chip_id) +{ + int i_ret = -1; + +#ifdef CONFIG_MTK_COMBO_BT + pr_info("Start to do bluetooth driver init\n"); + i_ret = mtk_wcn_stpbt_drv_init(); + pr_info("Finish bluetooth driver init, i_ret:%d\n", i_ret); +#else + pr_info("CONFIG_MTK_COMBO_BT is not defined\n"); +#endif + return i_ret; +} diff --git a/drivers/misc/mediatek/connectivity/conninfra/drv_init/conn_drv_init.c b/drivers/misc/mediatek/connectivity/conninfra/drv_init/conn_drv_init.c new file mode 100644 index 0000000000000000000000000000000000000000..06a0c3056d1437166b719fab520184c223b9a188 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/drv_init/conn_drv_init.c @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include + +#include "conn_drv_init.h" +#include "fm_drv_init.h" +#include "wlan_drv_init.h" +#include "bluetooth_drv_init.h" +#include "gps_drv_init.h" + +#ifdef MTK_WCN_REMOVE_KERNEL_MODULE +int do_connectivity_driver_init(int chip_id) +{ + int i_ret = 0; + int tmp_ret = 0; + static int init_before = 0; + + /* To avoid invoking more than once.*/ + if (init_before) + return 0; + init_before = 1; + + tmp_ret = do_bluetooth_drv_init(chip_id); + i_ret += tmp_ret; + if (tmp_ret) + pr_err("Do BT driver init failed, ret:%d\n", tmp_ret); + + tmp_ret = do_gps_drv_init(chip_id); + i_ret += tmp_ret; + if (tmp_ret) + pr_err("Do GPS driver init failed, ret:%d\n", tmp_ret); + + tmp_ret = do_fm_drv_init(chip_id); + i_ret += tmp_ret; + if (tmp_ret) + pr_err("Do FM module init failed, ret:%d\n", tmp_ret); + + tmp_ret = do_wlan_drv_init(chip_id); + i_ret += tmp_ret; + if (tmp_ret) + pr_err("Do wlan module init failed, ret:%d\n", tmp_ret); + + return i_ret; +} +#endif + diff --git a/drivers/misc/mediatek/connectivity/conninfra/drv_init/fm_drv_init.c b/drivers/misc/mediatek/connectivity/conninfra/drv_init/fm_drv_init.c new file mode 100644 index 0000000000000000000000000000000000000000..35d512408c435889418ef94d7b82c272d23e3f84 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/drv_init/fm_drv_init.c @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include + +#include "fm_drv_init.h" + +#ifdef CONFIG_MTK_FMRADIO +int __attribute__((weak)) mtk_wcn_fm_init() +{ + pr_err("no impl. mtk_wcn_fm_init\n"); + return 0; +} +#endif + +int do_fm_drv_init(int chip_id) +{ + pr_info("Start to do fm module init\n"); + +#ifdef CONFIG_MTK_FMRADIO + mtk_wcn_fm_init(); +#endif + + pr_info("Finish fm module init\n"); + return 0; +} diff --git a/drivers/misc/mediatek/connectivity/conninfra/drv_init/gps_drv_init.c b/drivers/misc/mediatek/connectivity/conninfra/drv_init/gps_drv_init.c new file mode 100644 index 0000000000000000000000000000000000000000..f3e7dc7169d3831f5af531dc36227d0f8763713c --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/drv_init/gps_drv_init.c @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include + +#include "gps_drv_init.h" + +#ifdef CONFIG_MTK_GPS_SUPPORT +int __attribute__((weak)) mtk_wcn_gpsdl_drv_init() +{ + pr_info("No impl. %s\n", __func__); + return 0; +} +#endif + +int do_gps_drv_init(int chip_id) +{ + int i_ret = -1; +#ifdef CONFIG_MTK_GPS_SUPPORT + pr_info("Start to do gps driver init\n"); + i_ret = mtk_wcn_gpsdl_drv_init(); + pr_info("finish gps driver init, i_ret:%d\n", i_ret); +#else + pr_info("CONFIG_MTK_GPS_SUPPORT is not defined\n"); +#endif + return i_ret; + +} diff --git a/drivers/misc/mediatek/connectivity/conninfra/drv_init/include/bluetooth_drv_init.h b/drivers/misc/mediatek/connectivity/conninfra/drv_init/include/bluetooth_drv_init.h new file mode 100644 index 0000000000000000000000000000000000000000..a47881f0baf2b0b139b5d1cad6830bfafb7da9c4 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/drv_init/include/bluetooth_drv_init.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef _BLUETOOTH_DRIVER_INIT_H_ +#define _BLUETOOTH_DRIVER_INIT_H_ + +extern int do_bluetooth_drv_init(int chip_id); +extern int mtk_wcn_stpbt_drv_init(void); +#endif diff --git a/drivers/misc/mediatek/connectivity/conninfra/drv_init/include/conn_drv_init.h b/drivers/misc/mediatek/connectivity/conninfra/drv_init/include/conn_drv_init.h new file mode 100644 index 0000000000000000000000000000000000000000..697b420ae1c7b5f1e6f9f66713382aebca5d8ff8 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/drv_init/include/conn_drv_init.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef _CONNECTIVITY_DRV_INIT_H_ +#define _CONNECTIVITY_DRV_INIT_H_ +extern int do_connectivity_driver_init(int chip_id); +#endif diff --git a/drivers/misc/mediatek/connectivity/conninfra/drv_init/include/fm_drv_init.h b/drivers/misc/mediatek/connectivity/conninfra/drv_init/include/fm_drv_init.h new file mode 100644 index 0000000000000000000000000000000000000000..e4d749297b23c7241a9f72e1a2e27d514059e855 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/drv_init/include/fm_drv_init.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef _FM_DRV_INIT_H_ +#define _FM_DRV_INIT_H_ +extern int do_fm_drv_init(int chip_id); +extern int mtk_wcn_fm_init(void); +extern void mtk_wcn_fm_exit(void); +#endif diff --git a/drivers/misc/mediatek/connectivity/conninfra/drv_init/include/gps_drv_init.h b/drivers/misc/mediatek/connectivity/conninfra/drv_init/include/gps_drv_init.h new file mode 100644 index 0000000000000000000000000000000000000000..c274b3ad2cbe51172c9462ea33166161e889ea3a --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/drv_init/include/gps_drv_init.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef _GPS_DRIVER_INIT_H_ +#define _GPS_DRIVER_INIT_H_ +extern int do_gps_drv_init(int chip_id); +extern int mtk_wcn_stpgps_drv_init(void); +#endif diff --git a/drivers/misc/mediatek/connectivity/conninfra/drv_init/include/wlan_drv_init.h b/drivers/misc/mediatek/connectivity/conninfra/drv_init/include/wlan_drv_init.h new file mode 100644 index 0000000000000000000000000000000000000000..12d74827afe44677b858920e30aa20634a3b5488 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/drv_init/include/wlan_drv_init.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef _WLAN_DRV_INIT_H_ +#define _WLAN_DRV_INIT_H_ + + +extern int do_wlan_drv_init(int chip_id); + +extern int mtk_wcn_wmt_wifi_init(void); + +extern int mtk_wcn_wlan_gen4_init(void); + +#endif diff --git a/drivers/misc/mediatek/connectivity/conninfra/drv_init/wlan_drv_init.c b/drivers/misc/mediatek/connectivity/conninfra/drv_init/wlan_drv_init.c new file mode 100644 index 0000000000000000000000000000000000000000..d62c7fc9be62019df97af5d119dd297abffc122d --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/drv_init/wlan_drv_init.c @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include + +#include "wlan_drv_init.h" + +int __attribute__((weak)) mtk_wcn_wlan_gen4_init() +{ + pr_info("no impl. mtk_wcn_wlan_gen4_init\n"); + return 0; +} + +int __attribute__((weak)) mtk_wcn_wmt_wifi_init() +{ + pr_info("no impl. mtk_wcn_wmt_wifi_init"); + return 0; +} + +int do_wlan_drv_init(int chip_id) +{ + int i_ret = 0; + int ret = 0; + + pr_info("Start to do wlan module init 0x%x\n", chip_id); + + /* WMT-WIFI char dev init */ + ret = mtk_wcn_wmt_wifi_init(); + pr_info("WMT-WIFI char dev init, ret:%d\n", ret); + i_ret += ret; + + /* WLAN driver init */ + ret = mtk_wcn_wlan_gen4_init(); + pr_info("WLAN-GEN4 driver init, ret:%d\n", ret); + + i_ret += ret; + + pr_info("Finish wlan module init\n"); + + return i_ret; +} diff --git a/drivers/misc/mediatek/connectivity/conninfra/include/conninfra.h b/drivers/misc/mediatek/connectivity/conninfra/include/conninfra.h new file mode 100755 index 0000000000000000000000000000000000000000..9162e983f1ec050213c93f24ed97db679fe578f5 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/include/conninfra.h @@ -0,0 +1,259 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#ifndef _CONNINFRA_H_ +#define _CONNINFRA_H_ + + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ +enum consys_drv_type { + CONNDRV_TYPE_BT = 0, + CONNDRV_TYPE_FM = 1, + CONNDRV_TYPE_GPS = 2, + CONNDRV_TYPE_WIFI = 3, + CONNDRV_TYPE_CONNINFRA = 4, + CONNDRV_TYPE_MAX +}; + +enum consys_adie_ctl_type { + CONNSYS_ADIE_CTL_HOST_BT, + CONNSYS_ADIE_CTL_HOST_FM, + CONNSYS_ADIE_CTL_HOST_GPS, + CONNSYS_ADIE_CTL_HOST_WIFI, + CONNSYS_ADIE_CTL_HOST_CONNINFRA, + CONNSYS_ADIE_CTL_FW_BT, + CONNSYS_ADIE_CTL_FW_WIFI, + CONNSYS_ADIE_CTL_MAX +}; + +/* HW-specific, need sync with FW. DO NOT MODIFY */ +enum sys_spi_subsystem +{ + SYS_SPI_WF1 = 0x00, + SYS_SPI_WF = 0x01, + SYS_SPI_BT = 0x02, + SYS_SPI_FM = 0x03, + SYS_SPI_GPS = 0x04, + SYS_SPI_TOP = 0x05, + SYS_SPI_WF2 = 0x06, + SYS_SPI_WF3 = 0x07, + SYS_SPI_MAX +}; + +enum connsys_spi_speed_type { + CONNSYS_SPI_SPEED_26M, + CONNSYS_SPI_SPEED_64M, + CONNSYS_SPI_SPEED_MAX +}; + +enum connsys_clock_schematic +{ + CONNSYS_CLOCK_SCHEMATIC_26M_COTMS = 0, + CONNSYS_CLOCK_SCHEMATIC_52M_COTMS, + CONNSYS_CLOCK_SCHEMATIC_26M_EXTCXO, + + CONNSYS_CLOCK_SCHEMATIC_MAX, +}; + +/* Conninfra driver allocate EMI for FW + * (FW includes: BT, WIFI and their MCU) + * +-----------+ + * | | + * | FW | + * | | + * +-----------+ + * + * MCIF region is provided by MD + * +-----------+ + * | | + * | | + * | MCIF | + * | | + * +-----------+ + */ +enum connsys_emi_type +{ + CONNSYS_EMI_FW, + CONNSYS_EMI_MCIF, + + CONNSYS_EMI_MAX, +}; + +#define CONNINFRA_SPI_OP_FAIL 0x1 + +#define CONNINFRA_CB_RET_CAL_PASS_POWER_OFF 0x0 +#define CONNINFRA_CB_RET_CAL_PASS_POWER_ON 0x2 +#define CONNINFRA_CB_RET_CAL_FAIL_POWER_OFF 0x1 +#define CONNINFRA_CB_RET_CAL_FAIL_POWER_ON 0x3 + +#define CONNINFRA_BUS_CLOCK_WPLL 0x1 +#define CONNINFRA_BUS_CLOCK_BPLL 0x2 +#define CONNINFRA_BUS_CLOCK_ALL 0x3 + +/* bus hang error define */ +#define CONNINFRA_INFRA_BUS_HANG 0x1 +#define CONNINFRA_AP2CONN_RX_SLP_PROT_ERR 0x2 +#define CONNINFRA_AP2CONN_TX_SLP_PROT_ERR 0x4 +#define CONNINFRA_AP2CONN_CLK_ERR 0x8 +#define CONNINFRA_INFRA_BUS_HANG_IRQ 0x10 + +#define CONNINFRA_ERR_RST_ONGOING -0x7788 +#define CONNINFRA_ERR_WAKEUP_FAIL -0x5566 +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +/* Conninfra bus clock control */ +int conninfra_bus_clock_ctrl(enum consys_drv_type drv_type, unsigned int bus_clock, int status); +/* Clock schematic query */ +int conninfra_get_clock_schematic(void); + +/* SPI clock switch */ +int conninfra_spi_clock_switch(enum connsys_spi_speed_type type); + +/* A-die top_ck_en control */ +int conninfra_adie_top_ck_en_on(enum consys_adie_ctl_type type); +int conninfra_adie_top_ck_en_off(enum consys_adie_ctl_type type); + +/* RFSPI */ +int conninfra_spi_read(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int *data); +int conninfra_spi_write(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int data); + +/* EMI */ +void conninfra_get_phy_addr(unsigned int *addr, unsigned int *size); +void conninfra_get_emi_phy_addr(enum connsys_emi_type type, phys_addr_t* base, unsigned int *size); + +/* power on/off */ +int conninfra_pwr_on(enum consys_drv_type drv_type); +int conninfra_pwr_off(enum consys_drv_type drv_type); + +/* To setup config relative data, ex: debug flag */ +void conninfra_config_setup(void); + +/* reg */ +/* + * 1 : can read + * 0 : can't read + */ +int conninfra_reg_readable(void); +/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ +/* reg readable */ +/* THIS API SHOULD NOT USED IN NORMAL CASE */ +/* IF YOU NEED THIS, PLEASE DISCUSS WITH OWNER */ +/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ +int conninfra_reg_readable_no_lock(void); +/* + * 0 : NO hang + * > 0 : HANG!! + * CONNINFRA_ERR_RST_ONGOING: whole chip reset is ongoing + */ +int conninfra_is_bus_hang(void); + +/* chip reset + * return: + * <0: error + * =0: triggered + * =1: ongoing + */ +int conninfra_trigger_whole_chip_rst(enum consys_drv_type drv, char *reason); + +/* whole chip reset callback + * return: + * =0: success + * !0: fail + */ +struct whole_chip_rst_cb { + int (*pre_whole_chip_rst)(enum consys_drv_type drv, char *reason); + int (*post_whole_chip_rst)(void); +}; + +/* driver state query */ + +/* VCN control */ + +/* Thermal */ + +/* Config */ + +/* semaphore */ + +/* calibration */ + + + +/* subsys callback register */ +struct pre_calibration_cb { + int (*pwr_on_cb)(void); + int (*do_cal_cb)(void); +}; + +struct sub_drv_ops_cb { + /* chip reset */ + struct whole_chip_rst_cb rst_cb; + + /* calibration */ + struct pre_calibration_cb pre_cal_cb; + + /* thermal query */ + int (*thermal_qry)(void); + +}; + +int conninfra_sub_drv_ops_register(enum consys_drv_type drv_type, struct sub_drv_ops_cb *cb); +int conninfra_sub_drv_ops_unregister(enum consys_drv_type drv_type); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _CONNINFRA_H_ */ diff --git a/drivers/misc/mediatek/connectivity/conninfra/init.conninfra.rc b/drivers/misc/mediatek/connectivity/conninfra/init.conninfra.rc new file mode 100755 index 0000000000000000000000000000000000000000..cca37bfcffcaf8bef41fbb869b525cee2286fc89 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/init.conninfra.rc @@ -0,0 +1,2 @@ +on boot + insmod /vendor/lib/modules/conninfra.ko diff --git a/drivers/misc/mediatek/connectivity/conninfra/platform/clock_mng.c b/drivers/misc/mediatek/connectivity/conninfra/platform/clock_mng.c new file mode 100755 index 0000000000000000000000000000000000000000..9c2fd55d28ad3929dd31523e8d66e6a7037c192c --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/platform/clock_mng.c @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#include "osal.h" + +#include "clock_mng.h" + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + + diff --git a/drivers/misc/mediatek/connectivity/conninfra/platform/consys_hw.c b/drivers/misc/mediatek/connectivity/conninfra/platform/consys_hw.c new file mode 100755 index 0000000000000000000000000000000000000000..7e44816eba22b619bcbcad02c0a9fe885c576a13 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/platform/consys_hw.c @@ -0,0 +1,525 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#include +#include +#include "osal.h" + +#include "consys_hw.h" +#include "emi_mng.h" +#include "pmic_mng.h" +#include "consys_reg_mng.h" +#include "connsys_debug_utility.h" + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +static int mtk_conninfra_probe(struct platform_device *pdev); +static int mtk_conninfra_remove(struct platform_device *pdev); +static int mtk_conninfra_suspend(struct platform_device *pdev, pm_message_t state); +static int mtk_conninfra_resume(struct platform_device *pdev); + +static int _consys_hw_conninfra_wakeup(void); +static void _consys_hw_conninfra_sleep(void); + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +#ifdef CONFIG_OF +const struct of_device_id apconninfra_of_ids[] = { + {.compatible = "mediatek,mt6885-consys",}, + {.compatible = "mediatek,mt6893-consys",}, + {} +}; +#endif + +static struct platform_driver mtk_conninfra_dev_drv = { + .probe = mtk_conninfra_probe, + .remove = mtk_conninfra_remove, + .suspend = mtk_conninfra_suspend, + .resume = mtk_conninfra_resume, + .driver = { + .name = "mtk_conninfra", + .owner = THIS_MODULE, +#ifdef CONFIG_OF + .of_match_table = apconninfra_of_ids, +#endif + }, +}; + + +struct consys_hw_env conn_hw_env; + +struct consys_hw_ops_struct *consys_hw_ops; +struct platform_device *g_pdev; + +int g_conninfra_wakeup_ref_cnt; + +struct work_struct ap_resume_work; + +struct conninfra_dev_cb *g_conninfra_dev_cb; + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +struct consys_hw_ops_struct* __weak get_consys_platform_ops(void) +{ + pr_err("Miss platform ops !!\n"); + return NULL; +} + + +struct platform_device *get_consys_device(void) +{ + return g_pdev; +} + +int consys_hw_get_clock_schematic(void) +{ + if (consys_hw_ops->consys_plt_co_clock_type) + return consys_hw_ops->consys_plt_co_clock_type(); + else + pr_err("consys_hw_ops->consys_co_clock_type not supported\n"); + + return -1; +} + +unsigned int consys_hw_chipid_get(void) +{ + if (consys_hw_ops->consys_plt_soc_chipid_get) + return consys_hw_ops->consys_plt_soc_chipid_get(); + else + pr_err("consys_plt_soc_chipid_get not supported\n"); + + return 0; +} + +unsigned int consys_hw_get_hw_ver(void) +{ + if (consys_hw_ops->consys_plt_get_hw_ver) + return consys_hw_ops->consys_plt_get_hw_ver(); + return 0; +} + + +int consys_hw_reg_readable(void) +{ + return consys_reg_mng_reg_readable(); +} + +int consys_hw_is_connsys_reg(phys_addr_t addr) +{ + return consys_reg_mng_is_connsys_reg(addr); +} + +int consys_hw_is_bus_hang(void) +{ + return consys_reg_mng_is_bus_hang(); +} + +int consys_hw_dump_bus_status(void) +{ + return consys_reg_mng_dump_bus_status(); +} + +int consys_hw_dump_cpupcr(enum conn_dump_cpupcr_type dump_type, int times, unsigned long interval_us) +{ + return consys_reg_mng_dump_cpupcr(dump_type, times, interval_us); +} + +int consys_hw_pwr_off(unsigned int curr_status, unsigned int off_radio) +{ + unsigned int next_status = curr_status & ~(0x1 << off_radio); + int ret = 0; + + if (next_status == 0) { + pr_info("Last pwoer off: %d\n", off_radio); + pr_info("Power off CONNSYS PART 1\n"); + if (consys_hw_ops->consys_plt_conninfra_on_power_ctrl) + consys_hw_ops->consys_plt_conninfra_on_power_ctrl(0); + pr_info("Power off CONNSYS PART 2\n"); + if (consys_hw_ops->consys_plt_set_if_pinmux) + consys_hw_ops->consys_plt_set_if_pinmux(0); + if (consys_hw_ops->consys_plt_clock_buffer_ctrl) + consys_hw_ops->consys_plt_clock_buffer_ctrl(0); + ret = pmic_mng_common_power_ctrl(0); + pr_info("Power off a-die power, ret=%d\n", ret); + } else { + pr_info("[%s] Part 0: only subsys (%d) off (curr_status=0x%x, next_status = 0x%x)\n", + __func__, off_radio, curr_status, next_status); + ret = _consys_hw_conninfra_wakeup(); + if (consys_hw_ops->consys_plt_subsys_status_update) + consys_hw_ops->consys_plt_subsys_status_update(false, off_radio); + if (consys_hw_ops->consys_plt_spi_master_cfg) + consys_hw_ops->consys_plt_spi_master_cfg(next_status); + if (consys_hw_ops->consys_plt_low_power_setting) + consys_hw_ops->consys_plt_low_power_setting(curr_status, next_status); + if (ret == 0) + _consys_hw_conninfra_sleep(); + } + + return 0; +} + +int consys_hw_pwr_on(unsigned int curr_status, unsigned int on_radio) +{ + int ret; + unsigned int next_status = (curr_status | (0x1 << on_radio)); + + /* first power on */ + if (curr_status == 0) { + /* POS PART 1: + * Set PMIC to turn on the power that AFE WBG circuit in D-die, + * OSC or crystal component, and A-die need. + */ + ret = pmic_mng_common_power_ctrl(1); + if (consys_hw_ops->consys_plt_clock_buffer_ctrl) + consys_hw_ops->consys_plt_clock_buffer_ctrl(1); + + /* POS PART 2: + * 1. Pinmux setting + * 2. Turn on MTCMOS + * 3. Enable AXI bus (AP2CONN slpprot) + */ + if (consys_hw_ops->consys_plt_set_if_pinmux) + consys_hw_ops->consys_plt_set_if_pinmux(1); + + if (consys_hw_ops->consys_plt_conninfra_on_power_ctrl) + consys_hw_ops->consys_plt_conninfra_on_power_ctrl(1); + + if (consys_hw_ops->consys_plt_polling_consys_chipid) + ret = consys_hw_ops->consys_plt_polling_consys_chipid(); + + /* POS PART 3: + * 1. Set connsys EMI mapping + * 2. d_die_cfg + * 3. spi_master_cfg + * 4. a_die_cfg + * 5. afe_wbg_cal + * 6. patch default value + * 7. CONN_INFRA low power setting (srcclken wait time, mtcmos HW ctl...) + */ + emi_mng_set_remapping_reg(); + if (consys_hw_ops->consys_plt_d_die_cfg) + consys_hw_ops->consys_plt_d_die_cfg(); + if (consys_hw_ops->consys_plt_spi_master_cfg) + consys_hw_ops->consys_plt_spi_master_cfg(next_status); + if (consys_hw_ops->consys_plt_a_die_cfg) + consys_hw_ops->consys_plt_a_die_cfg(); + if (consys_hw_ops->consys_plt_afe_wbg_cal) + consys_hw_ops->consys_plt_afe_wbg_cal(); + if (consys_hw_ops->consys_plt_subsys_pll_initial) + consys_hw_ops->consys_plt_subsys_pll_initial(); + /* Record SW status on shared sysram */ + if (consys_hw_ops->consys_plt_subsys_status_update) + consys_hw_ops->consys_plt_subsys_status_update(true, on_radio); + if (consys_hw_ops->consys_plt_low_power_setting) + consys_hw_ops->consys_plt_low_power_setting(curr_status, next_status); + } else { + ret = _consys_hw_conninfra_wakeup(); + /* Record SW status on shared sysram */ + if (consys_hw_ops->consys_plt_subsys_status_update) + consys_hw_ops->consys_plt_subsys_status_update(true, on_radio); + if (consys_hw_ops->consys_plt_spi_master_cfg) + consys_hw_ops->consys_plt_spi_master_cfg(next_status); + if (consys_hw_ops->consys_plt_low_power_setting) + consys_hw_ops->consys_plt_low_power_setting(curr_status, next_status); + + if (ret == 0) + _consys_hw_conninfra_sleep(); + } + return 0; +} + +int consys_hw_wifi_power_ctl(unsigned int enable) +{ + return pmic_mng_wifi_power_ctrl(enable); +} + +int consys_hw_bt_power_ctl(unsigned int enable) +{ + return pmic_mng_bt_power_ctrl(enable); +} + +int consys_hw_gps_power_ctl(unsigned int enable) +{ + return pmic_mng_gps_power_ctrl(enable); +} + +int consys_hw_fm_power_ctl(unsigned int enable) +{ + return pmic_mng_fm_power_ctrl(enable); +} + + +int consys_hw_therm_query(int *temp_ptr) +{ + int ret = 0; + + /* wake/sleep conninfra */ + if (consys_hw_ops && consys_hw_ops->consys_plt_thermal_query) { + ret = _consys_hw_conninfra_wakeup(); + if (ret) + return CONNINFRA_ERR_WAKEUP_FAIL; + *temp_ptr = consys_hw_ops->consys_plt_thermal_query(); + _consys_hw_conninfra_sleep(); + } else + ret = -1; + + return ret; +} + +void consys_hw_clock_fail_dump(void) +{ + if (consys_hw_ops && consys_hw_ops->consys_plt_clock_fail_dump) + consys_hw_ops->consys_plt_clock_fail_dump(); +} + + +int consys_hw_dump_power_state(void) +{ + if (consys_hw_ops && consys_hw_ops->consys_plt_power_state) + consys_hw_ops->consys_plt_power_state(); + return 0; +} + +int consys_hw_spi_read(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int *data) +{ + if (consys_hw_ops->consys_plt_spi_read) + return consys_hw_ops->consys_plt_spi_read(subsystem, addr, data); + return -1; +} + +int consys_hw_spi_write(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int data) +{ + if (consys_hw_ops->consys_plt_spi_write) + return consys_hw_ops->consys_plt_spi_write(subsystem, addr, data); + return -1; +} + +int consys_hw_adie_top_ck_en_on(enum consys_adie_ctl_type type) +{ + if (consys_hw_ops->consys_plt_adie_top_ck_en_on) + return consys_hw_ops->consys_plt_adie_top_ck_en_on(type); + return -1; +} + +int consys_hw_adie_top_ck_en_off(enum consys_adie_ctl_type type) +{ + if (consys_hw_ops->consys_plt_adie_top_ck_en_off) + return consys_hw_ops->consys_plt_adie_top_ck_en_off(type); + return -1; +} + + +static int _consys_hw_conninfra_wakeup(void) +{ + int ref = g_conninfra_wakeup_ref_cnt; + bool wakeup = false, ret; + + if (consys_hw_ops->consys_plt_conninfra_wakeup) { + if (g_conninfra_wakeup_ref_cnt == 0) { + ret = consys_hw_ops->consys_plt_conninfra_wakeup(); + if (ret) { + pr_err("wakeup fail!! ret=[%d]", ret); + return ret; + } + wakeup = true; + } + g_conninfra_wakeup_ref_cnt++; + } + + pr_info("conninfra_wakeup refcnt=[%d]->[%d] %s", + ref, g_conninfra_wakeup_ref_cnt, (wakeup ? "wakeup!!" : "")); + return 0; +} + +static void _consys_hw_conninfra_sleep(void) +{ + int ref = g_conninfra_wakeup_ref_cnt; + bool sleep = false; + + if (consys_hw_ops->consys_plt_conninfra_sleep && + --g_conninfra_wakeup_ref_cnt == 0) { + sleep = true; + consys_hw_ops->consys_plt_conninfra_sleep(); + } + pr_info("conninfra_sleep refcnt=[%d]->[%d] %s", + ref, g_conninfra_wakeup_ref_cnt, (sleep ? "sleep!!" : "")); +} + +int consys_hw_force_conninfra_wakeup(void) +{ + return _consys_hw_conninfra_wakeup(); +} + +int consys_hw_force_conninfra_sleep(void) +{ + _consys_hw_conninfra_sleep(); + return 0; +} + +int consys_hw_spi_clock_switch(enum connsys_spi_speed_type type) +{ + if (consys_hw_ops->consys_plt_spi_clock_switch) + return consys_hw_ops->consys_plt_spi_clock_switch(type); + return -1; +} + +void consys_hw_config_setup(void) +{ + if (consys_hw_ops->consys_plt_config_setup) + consys_hw_ops->consys_plt_config_setup(); +} + +int consys_hw_pmic_event_cb(unsigned int id, unsigned int event) +{ + pmic_mng_event_cb(id, event); + return 0; +} + +int consys_hw_bus_clock_ctrl(enum consys_drv_type drv_type, unsigned int bus_clock, int status) +{ + if (consys_hw_ops->consys_plt_bus_clock_ctrl) + return consys_hw_ops->consys_plt_bus_clock_ctrl(drv_type, bus_clock, status); + else + return -1; +} + +int mtk_conninfra_probe(struct platform_device *pdev) +{ + int ret = -1; + struct consys_emi_addr_info* emi_info = NULL; + + /* Read device node */ + if (consys_reg_mng_init(pdev) != 0) { + pr_err("consys_plt_read_reg_from_dts fail"); + return -1; + } + + if (consys_hw_ops->consys_plt_clk_get_from_dts) + consys_hw_ops->consys_plt_clk_get_from_dts(pdev); + else { + pr_err("consys_plt_clk_get_from_dtsfail"); + return -2; + } + + /* emi mng init */ + ret = emi_mng_init(); + if (ret) { + pr_err("emi_mng init fail, %d\n", ret); + return -3; + } + + ret = pmic_mng_init(pdev, g_conninfra_dev_cb); + if (ret) { + pr_err("pmic_mng init fail, %d\n", ret); + return -4; + } + + /* Setup connsys log emi base */ + emi_info = emi_mng_get_phy_addr(); + if (emi_info) { + connsys_dedicated_log_path_apsoc_init((phys_addr_t)emi_info->emi_ap_phy_addr); + } else { + pr_err("Connsys log didn't init because EMI is invalid\n"); + } + + if (pdev) + g_pdev = pdev; + + return 0; +} + +int mtk_conninfra_remove(struct platform_device *pdev) +{ + if (g_pdev) + g_pdev = NULL; + + return 0; +} + +int mtk_conninfra_suspend(struct platform_device *pdev, pm_message_t state) +{ + /* suspend callback is in atomic context */ + return 0; +} + +int mtk_conninfra_resume(struct platform_device *pdev) +{ + /* suspend callback is in atomic context */ + schedule_work(&ap_resume_work); + return 0; +} + + +static void consys_hw_ap_resume_handler(struct work_struct *work) +{ + if (g_conninfra_dev_cb && g_conninfra_dev_cb->conninfra_resume_cb) + (*g_conninfra_dev_cb->conninfra_resume_cb)(); +} + + +int consys_hw_init(struct conninfra_dev_cb *dev_cb) +{ + int iRet = 0; + + if (consys_hw_ops == NULL) + consys_hw_ops = get_consys_platform_ops(); + + g_conninfra_dev_cb = dev_cb; + + iRet = platform_driver_register(&mtk_conninfra_dev_drv); + if (iRet) + pr_err("Conninfra platform driver registered failed(%d)\n", iRet); + + INIT_WORK(&ap_resume_work, consys_hw_ap_resume_handler); + pr_info("[consys_hw_init] result [%d]\n", iRet); + + return iRet; +} + +int consys_hw_deinit(void) +{ + platform_driver_unregister(&mtk_conninfra_dev_drv); + g_conninfra_dev_cb = NULL; + return 0; +} diff --git a/drivers/misc/mediatek/connectivity/conninfra/platform/consys_reg_mng.c b/drivers/misc/mediatek/connectivity/conninfra/platform/consys_reg_mng.c new file mode 100755 index 0000000000000000000000000000000000000000..a17ca4a001d64b1cef916e4f6c680212aea58b83 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/platform/consys_reg_mng.c @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#define pr_fmt(fmt) KBUILD_MODNAME "@(%s:%d) " fmt, __func__, __LINE__ + +#include "consys_reg_mng.h" +#include "consys_reg_util.h" + +struct consys_reg_mng_ops* g_consys_reg_ops = NULL; + +struct consys_reg_mng_ops* __weak get_consys_reg_mng_ops(void) +{ + pr_warn("No specify project\n"); + return NULL; +} + +int consys_reg_mng_reg_readable(void) +{ + if (g_consys_reg_ops && + g_consys_reg_ops->consys_reg_mng_check_reable) + return g_consys_reg_ops->consys_reg_mng_check_reable(); + pr_err("%s not implement", __func__); + return -1; +} + +int consys_reg_mng_is_connsys_reg(phys_addr_t addr) +{ + if (g_consys_reg_ops && + g_consys_reg_ops->consys_reg_mng_is_consys_reg) + return g_consys_reg_ops->consys_reg_mng_is_consys_reg(addr); + return -1; +} + + +int consys_reg_mng_is_bus_hang(void) +{ + if (g_consys_reg_ops && + g_consys_reg_ops->consys_reg_mng_is_bus_hang) + return g_consys_reg_ops->consys_reg_mng_is_bus_hang(); + return -1; +} + +int consys_reg_mng_dump_bus_status(void) +{ + if (g_consys_reg_ops && + g_consys_reg_ops->consys_reg_mng_dump_bus_status) + return g_consys_reg_ops->consys_reg_mng_dump_bus_status(); + return -1; +} + +int consys_reg_mng_dump_conninfra_status(void) +{ + if (g_consys_reg_ops && + g_consys_reg_ops->consys_reg_mng_dump_conninfra_status) + return g_consys_reg_ops->consys_reg_mng_dump_conninfra_status(); + return -1; +} + +int consys_reg_mng_dump_cpupcr(enum conn_dump_cpupcr_type dump_type, int times, unsigned long interval_us) +{ + if (g_consys_reg_ops && + g_consys_reg_ops->consys_reg_mng_dump_cpupcr) + return g_consys_reg_ops->consys_reg_mng_dump_cpupcr(dump_type, times, interval_us); + return -1; +} + +int consys_reg_mng_init(struct platform_device *pdev) +{ + int ret = 0; + if (g_consys_reg_ops == NULL) + g_consys_reg_ops = get_consys_reg_mng_ops(); + + if (g_consys_reg_ops && + g_consys_reg_ops->consys_reg_mng_init) + ret = g_consys_reg_ops->consys_reg_mng_init(pdev); + else + ret = EFAULT; + + return ret; +} + +int consys_reg_mng_deinit(void) +{ + if (g_consys_reg_ops&& + g_consys_reg_ops->consys_reg_mng_deinit) + g_consys_reg_ops->consys_reg_mng_deinit(); + + return 0; +} + +int consys_reg_mng_reg_read(unsigned long addr, unsigned int *value, unsigned int mask) +{ + void __iomem *vir_addr = NULL; + + vir_addr = ioremap_nocache(addr, 0x100); + if (!vir_addr) { + pr_err("ioremap fail"); + return -1; + } + + *value = (unsigned int)CONSYS_REG_READ(vir_addr) & mask; + + pr_info("[%x] mask=[%x]", *value, mask); + + iounmap(vir_addr); + return 0; +} + +int consys_reg_mng_reg_write(unsigned long addr, unsigned int value, unsigned int mask) +{ + void __iomem *vir_addr = NULL; + + vir_addr = ioremap_nocache(addr, 0x100); + if (!vir_addr) { + pr_err("ioremap fail"); + return -1; + } + + CONSYS_REG_WRITE_MASK(vir_addr, value, mask); + + iounmap(vir_addr); + return 0; +} + + +int consys_reg_mng_is_host_csr(unsigned long addr) +{ + if (g_consys_reg_ops && + g_consys_reg_ops->consys_reg_mng_is_host_csr) + return g_consys_reg_ops->consys_reg_mng_is_host_csr(addr); + return -1; +} diff --git a/drivers/misc/mediatek/connectivity/conninfra/platform/emi_mng.c b/drivers/misc/mediatek/connectivity/conninfra/platform/emi_mng.c new file mode 100755 index 0000000000000000000000000000000000000000..ed953cc6de89f82694c7c7599ca25f2f28a94718 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/platform/emi_mng.c @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#include +#include +#include +#include "osal.h" + +#include "emi_mng.h" + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + + +extern unsigned long long gConEmiSize; +extern phys_addr_t gConEmiPhyBase; + +struct consys_platform_emi_ops* consys_platform_emi_ops = NULL; + +struct consys_emi_addr_info connsys_emi_addr_info = { + .emi_ap_phy_addr = 0, + .emi_size = 0, + .md_emi_phy_addr = 0, + .md_emi_size = 0, +}; + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + + +int emi_mng_set_region_protection(void) +{ + if (consys_platform_emi_ops && + consys_platform_emi_ops->consys_ic_emi_mpu_set_region_protection) + return consys_platform_emi_ops->consys_ic_emi_mpu_set_region_protection(); + return -1; +} + +int emi_mng_set_remapping_reg(void) +{ + if (consys_platform_emi_ops && + consys_platform_emi_ops->consys_ic_emi_set_remapping_reg) + return consys_platform_emi_ops->consys_ic_emi_set_remapping_reg( + connsys_emi_addr_info.emi_ap_phy_addr, + connsys_emi_addr_info.md_emi_phy_addr); + return -1; +} + +struct consys_emi_addr_info* emi_mng_get_phy_addr(void) +{ + return &connsys_emi_addr_info; +} + + +struct consys_platform_emi_ops* __weak get_consys_platform_emi_ops(void) +{ + pr_warn("No specify project\n"); + return NULL; +} + +int emi_mng_init(void) +{ + if (consys_platform_emi_ops == NULL) + consys_platform_emi_ops = get_consys_platform_emi_ops(); + + pr_info("[emi_mng_init] gConEmiPhyBase = [0x%llx] size = [%llx] ops=[%p]", + gConEmiPhyBase, gConEmiSize, consys_platform_emi_ops); + + if (gConEmiPhyBase) { + connsys_emi_addr_info.emi_ap_phy_addr = gConEmiPhyBase; + connsys_emi_addr_info.emi_size = gConEmiSize; + } else { + pr_err("consys emi memory address gConEmiPhyBase invalid\n"); + } + + if (consys_platform_emi_ops && + consys_platform_emi_ops->consys_ic_emi_get_md_shared_emi) + consys_platform_emi_ops->consys_ic_emi_get_md_shared_emi( + &connsys_emi_addr_info.md_emi_phy_addr, + &connsys_emi_addr_info.md_emi_size); + + if (consys_platform_emi_ops && + consys_platform_emi_ops->consys_ic_emi_mpu_set_region_protection) + consys_platform_emi_ops->consys_ic_emi_mpu_set_region_protection(); + + return 0; +} + +int emi_mng_deinit(void) +{ + return 0; +} diff --git a/drivers/misc/mediatek/connectivity/conninfra/platform/include/clock_mng.h b/drivers/misc/mediatek/connectivity/conninfra/platform/include/clock_mng.h new file mode 100755 index 0000000000000000000000000000000000000000..ff628306c800bfeae4fd0a8fe7acb1d52d3553be --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/platform/include/clock_mng.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#ifndef _PLATFORM_CLOCK_MNG_H_ +#define _PLATFORM_CLOCK_MNG_H_ + +#include "osal.h" +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _PLATFORM_CLOCK_MNG_H_ */ diff --git a/drivers/misc/mediatek/connectivity/conninfra/platform/include/consys_hw.h b/drivers/misc/mediatek/connectivity/conninfra/platform/include/consys_hw.h new file mode 100755 index 0000000000000000000000000000000000000000..bce4e91a64b662823ab2c2448c2d7996b62cf154 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/platform/include/consys_hw.h @@ -0,0 +1,244 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#ifndef _PLATFORM_CONSYS_HW_H_ +#define _PLATFORM_CONSYS_HW_H_ + +#include + +#include "conninfra.h" + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +#define CONN_SEMA_GET_SUCCESS 0 +#define CONN_SEMA_GET_FAIL 1 + +#define CONN_SEMA_TIMEOUT (1*1000) /* 1ms */ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +typedef int(*CONSYS_PLT_CLK_GET_FROM_DTS) (struct platform_device *pdev); +typedef int(*CONSYS_PLT_READ_REG_FROM_DTS) (struct platform_device *pdev); + +typedef int(*CONSYS_PLT_CLOCK_BUFFER_CTRL) (unsigned int enable); +typedef int(*CONSYS_PLT_CONNINFRA_ON_POWER_CTRL) (unsigned int enable); +typedef void(*CONSYS_PLT_SET_IF_PINMUX) (unsigned int enable); + +typedef int(*CONSYS_PLT_POLLING_CONSYS_CHIPID) (void); +typedef int(*CONSYS_PLT_D_DIE_CFG) (void); +typedef int(*CONSYS_PLT_SPI_MASTER_CFG) (unsigned int next_status); +typedef int(*CONSYS_PLT_A_DIE_CFG) (void); +typedef int(*CONSYS_PLT_AFE_WBG_CAL) (void); +typedef int(*CONSYS_PLT_SUBSYS_PLL_INITIAL) (void); +typedef int(*CONSYS_PLT_LOW_POWER_SETTING) (unsigned int curr_status, unsigned int next_status); +typedef int(*CONSYS_PLT_CONNINFRA_WAKEUP) (void); +typedef int(*CONSYS_PLT_CONNINFRA_SLEEP) (void); + +typedef void(*CONSYS_PLT_AFE_REG_SETTING) (void); +typedef unsigned int(*CONSYS_PLT_SOC_CHIPID_GET) (void); + +typedef void(*CONSYS_PLT_FORCE_TRIGGER_ASSERT_DEBUG_PIN) (void); +typedef int(*CONSYS_PLT_CO_CLOCK_TYPE) (void); + +typedef int(*CONSYS_PLT_CHECK_REG_READABLE) (void); +typedef void(*CONSYS_PLT_CLOCK_FAIL_DUMP) (void); +typedef int(*CONSYS_PLT_IS_CONNSYS_REG) (unsigned int addr); + + +typedef int(*CONSYS_PLT_SPI_READ)(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int *data); +typedef int(*CONSYS_PLT_SPI_WRITE)(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int data); + +typedef int(*CONSYS_PLT_ADIE_TOP_CK_EN_ON)(enum consys_adie_ctl_type type); +typedef int(*CONSYS_PLT_ADIE_TOP_CK_EN_OFF)(enum consys_adie_ctl_type type); + +typedef int(*CONSYS_PLT_SPI_CLOCK_SWITCH)(enum connsys_spi_speed_type type); + +typedef bool(*CONSYS_PLT_IS_RC_MODE_ENABLE)(void); +typedef int(*CONSYS_PLT_SUBSYS_STATUS_UPDATE)(bool on, int radio); + +typedef unsigned int(*CONSYS_PLT_GET_HW_VER)(void); +typedef int(*CONSYS_PLT_THERMAL_QUERY)(void); +typedef int(*CONSYS_PLT_POWER_STATE)(void); + +typedef void(*CONSYS_PLT_CONFIG_SETUP)(void); + +typedef int(*CONSYS_PLT_BUS_CLOCK_CTRL)(enum consys_drv_type drv_type, unsigned int, int); + +struct consys_hw_ops_struct { + /* load from dts */ + CONSYS_PLT_CLK_GET_FROM_DTS consys_plt_clk_get_from_dts; + + /* clock */ + CONSYS_PLT_CLOCK_BUFFER_CTRL consys_plt_clock_buffer_ctrl; + CONSYS_PLT_CO_CLOCK_TYPE consys_plt_co_clock_type; + + /* POS */ + CONSYS_PLT_CONNINFRA_ON_POWER_CTRL consys_plt_conninfra_on_power_ctrl; + CONSYS_PLT_SET_IF_PINMUX consys_plt_set_if_pinmux; + + CONSYS_PLT_POLLING_CONSYS_CHIPID consys_plt_polling_consys_chipid; + CONSYS_PLT_D_DIE_CFG consys_plt_d_die_cfg; + CONSYS_PLT_SPI_MASTER_CFG consys_plt_spi_master_cfg; + CONSYS_PLT_A_DIE_CFG consys_plt_a_die_cfg; + CONSYS_PLT_AFE_WBG_CAL consys_plt_afe_wbg_cal; + CONSYS_PLT_SUBSYS_PLL_INITIAL consys_plt_subsys_pll_initial; + CONSYS_PLT_LOW_POWER_SETTING consys_plt_low_power_setting; + + CONSYS_PLT_AFE_REG_SETTING consys_plt_afe_reg_setting; + + CONSYS_PLT_SOC_CHIPID_GET consys_plt_soc_chipid_get; + CONSYS_PLT_CONNINFRA_WAKEUP consys_plt_conninfra_wakeup; + CONSYS_PLT_CONNINFRA_SLEEP consys_plt_conninfra_sleep; + CONSYS_PLT_IS_RC_MODE_ENABLE consys_plt_is_rc_mode_enable; + + CONSYS_PLT_CHECK_REG_READABLE consys_plt_check_reg_readable; + /* debug */ + CONSYS_PLT_CLOCK_FAIL_DUMP consys_plt_clock_fail_dump; + CONSYS_PLT_GET_HW_VER consys_plt_get_hw_ver; + + /* For SPI operation */ + CONSYS_PLT_SPI_READ consys_plt_spi_read; + CONSYS_PLT_SPI_WRITE consys_plt_spi_write; + + /* For a-die top_ck_en control */ + CONSYS_PLT_ADIE_TOP_CK_EN_ON consys_plt_adie_top_ck_en_on; + CONSYS_PLT_ADIE_TOP_CK_EN_OFF consys_plt_adie_top_ck_en_off; + + /* For SPI clock switch */ + CONSYS_PLT_SPI_CLOCK_SWITCH consys_plt_spi_clock_switch; + CONSYS_PLT_SUBSYS_STATUS_UPDATE consys_plt_subsys_status_update; + + /* thermal */ + CONSYS_PLT_THERMAL_QUERY consys_plt_thermal_query; + + /* power state */ + CONSYS_PLT_POWER_STATE consys_plt_power_state; + + CONSYS_PLT_CONFIG_SETUP consys_plt_config_setup; + + CONSYS_PLT_BUS_CLOCK_CTRL consys_plt_bus_clock_ctrl; +}; + +struct conninfra_dev_cb { + int (*conninfra_suspend_cb) (void); + int (*conninfra_resume_cb) (void); + int (*conninfra_pmic_event_notifier) (unsigned int, unsigned int); +}; + +struct consys_hw_env { + unsigned int adie_hw_version; + int is_rc_mode; +}; + +extern struct consys_hw_env conn_hw_env; +extern struct consys_base_addr conn_reg; +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +int consys_hw_init(struct conninfra_dev_cb *dev_cb); +int consys_hw_deinit(void); + +int consys_hw_pwr_off(unsigned int curr_status, unsigned int off_radio); +int consys_hw_pwr_on(unsigned int curr_status, unsigned int on_radio); + +int consys_hw_wifi_power_ctl(unsigned int enable); +int consys_hw_bt_power_ctl(unsigned int enable); +int consys_hw_gps_power_ctl(unsigned int enable); +int consys_hw_fm_power_ctl(unsigned int enable); +int consys_hw_pmic_event_cb(unsigned int id, unsigned int event); + +unsigned int consys_hw_chipid_get(void); + +int consys_hw_get_clock_schematic(void); +unsigned int consys_hw_get_hw_ver(void); + +/* + * return + * 1 : can read + * 0 : can't read + * -1: not consys register + */ +int consys_hw_reg_readable(void); +int consys_hw_is_connsys_reg(phys_addr_t addr); +/* + * 0 means NO hang + * > 0 means hang!! + */ +int consys_hw_is_bus_hang(void); +int consys_hw_dump_bus_status(void); + +int consys_hw_spi_read(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int *data); +int consys_hw_spi_write(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int data); + +int consys_hw_adie_top_ck_en_on(enum consys_adie_ctl_type type); +int consys_hw_adie_top_ck_en_off(enum consys_adie_ctl_type type); + +/* NOTE: debug only*/ +int consys_hw_force_conninfra_wakeup(void); +int consys_hw_force_conninfra_sleep(void); + +int consys_hw_spi_clock_switch(enum connsys_spi_speed_type type); + +struct platform_device *get_consys_device(void); +struct consys_base_addr *get_conn_reg_base_addr(void); + +int consys_hw_therm_query(int *temp_ptr); +void consys_hw_clock_fail_dump(void); + +int consys_hw_dump_power_state(void); +void consys_hw_config_setup(void); +int consys_hw_bus_clock_ctrl(enum consys_drv_type drv_type, unsigned int bus_clock, int status); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _PLATFORM_CONSYS_HW_H_ */ diff --git a/drivers/misc/mediatek/connectivity/conninfra/platform/include/consys_reg_base.h b/drivers/misc/mediatek/connectivity/conninfra/platform/include/consys_reg_base.h new file mode 100755 index 0000000000000000000000000000000000000000..563fd198d0a60227719283e5903e8415d246e6ec --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/platform/include/consys_reg_base.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#ifndef _PLATFORM_CONSYS_REG_BASE_H_ +#define _PLATFORM_CONSYS_REG_BASE_H_ + +struct consys_reg_base_addr { + unsigned long vir_addr; + unsigned long phy_addr; + unsigned long long size; +}; + +#endif /* _PLATFORM_CONSYS_REG_BASE_H_ */ diff --git a/drivers/misc/mediatek/connectivity/conninfra/platform/include/consys_reg_mng.h b/drivers/misc/mediatek/connectivity/conninfra/platform/include/consys_reg_mng.h new file mode 100755 index 0000000000000000000000000000000000000000..81ddc27eb9e3989c364c6eb0707b5752ace5d7a8 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/platform/include/consys_reg_mng.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#ifndef _PLATFORM_CONSYS_REG_MNG_H_ +#define _PLATFORM_CONSYS_REG_MNG_H_ + +#include + +enum conn_dump_cpupcr_type +{ + CONN_DUMP_CPUPCR_TYPE_BT = 1, + CONN_DUMP_CPUPCR_TYPE_WF = 2, + CONN_DUMP_CPUPCR_TYPE_ALL = 3, +}; + +struct consys_reg_mng_ops { + + int(*consys_reg_mng_init) (struct platform_device *pdev); + int(*consys_reg_mng_deinit) (void); + int(*consys_reg_mng_check_reable) (void); + int(*consys_reg_mng_is_consys_reg) (unsigned int addr); + + int(*consys_reg_mng_is_bus_hang) (void); + int(*consys_reg_mng_dump_bus_status) (void); + int(*consys_reg_mng_dump_conninfra_status) (void); + int(*consys_reg_mng_dump_cpupcr) (enum conn_dump_cpupcr_type, int times, unsigned long interval_us); + + int(*consys_reg_mng_is_host_csr) (unsigned long addr); +}; + +int consys_reg_mng_init(struct platform_device *pdev); +int consys_reg_mng_deinit(void); + +int consys_reg_mng_reg_readable(void); +int consys_reg_mng_is_connsys_reg(phys_addr_t addr); +int consys_reg_mng_reg_read(unsigned long addr, unsigned int *value, unsigned int mask); +int consys_reg_mng_reg_write(unsigned long addr, unsigned int value, unsigned int mask); +int consys_reg_mng_is_bus_hang(void); +int consys_reg_mng_dump_bus_status(void); +int consys_reg_mng_dump_conninfra_status(void); +int consys_reg_mng_dump_cpupcr(enum conn_dump_cpupcr_type dump_type, int times, unsigned long interval_us); + +int consys_reg_mng_is_host_csr(unsigned long addr); + +#endif /* _PLATFORM_CONSYS_REG_MNG_H_ */ diff --git a/drivers/misc/mediatek/connectivity/conninfra/platform/include/consys_reg_util.h b/drivers/misc/mediatek/connectivity/conninfra/platform/include/consys_reg_util.h new file mode 100755 index 0000000000000000000000000000000000000000..e5d06ec4d76bf88996065d8548ed16b66da89e64 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/platform/include/consys_reg_util.h @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#ifndef _PLATFORM_CONSYS_REG_UTIL_H_ +#define _PLATFORM_CONSYS_REG_UTIL_H_ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +/* platform dependent */ +#include "plat_def.h" + +#define KBYTE (1024*sizeof(char)) + +#define GENMASK(h, l) \ + (((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h)))) + +#define GET_BIT_MASK(value, mask) ((value) & (mask)) +#define SET_BIT_MASK(pdest, value, mask) (*(pdest) = (GET_BIT_MASK(*(pdest), ~(mask)) | GET_BIT_MASK(value, mask))) +#define GET_BIT_RANGE(data, end, begin) ((data) & GENMASK(end, begin)) +#define SET_BIT_RANGE(pdest, data, end, begin) (SET_BIT_MASK(pdest, data, GENMASK(end, begin))) + +#define CONSYS_SET_BIT(REG, BITVAL) (*((volatile unsigned int *)(REG)) |= ((unsigned int)(BITVAL))) +#define CONSYS_CLR_BIT(REG, BITVAL) ((*(volatile unsigned int *)(REG)) &= ~((unsigned int)(BITVAL))) +#define CONSYS_CLR_BIT_WITH_KEY(REG, BITVAL, KEY) {\ + unsigned int val = (*(volatile unsigned int *)(REG)); \ + val &= ~((unsigned int)(BITVAL)); \ + val |= ((unsigned int)(KEY)); \ + (*(volatile unsigned int *)(REG)) = val;\ +} +#define CONSYS_REG_READ(addr) (*((volatile unsigned int *)(addr))) +#define CONSYS_REG_READ_BIT(addr, BITVAL) (*((volatile unsigned int *)(addr)) & ((unsigned int)(BITVAL))) +#define CONSYS_REG_WRITE(addr, data) mt_reg_sync_writel(data, addr) +#define CONSYS_REG_WRITE_RANGE(reg, data, end, begin) {\ + unsigned int val = CONSYS_REG_READ(reg); \ + SET_BIT_RANGE(&val, data, end, begin); \ + CONSYS_REG_WRITE(reg, val); \ +} +#define CONSYS_REG_WRITE_MASK(reg, data, mask) {\ + unsigned int val = CONSYS_REG_READ(reg); \ + SET_BIT_MASK(&val, data, mask); \ + CONSYS_REG_WRITE(reg, val); \ +} + +/* + * Write value with value_offset bits of right shift and size bits, + * to the reg_offset-th bit of address reg + * value -----------XXXXXXXXXXXX------------------- + * |<--size-->|<--value_offset-->| + * reg -------------OOOOOOOOOOOO----------------- + * |<--size-->|<--reg_offset-->| + * result -------------XXXXXXXXXXXX----------------- + */ +#define CONSYS_REG_WRITE_OFFSET_RANGE(reg, value, reg_offset, value_offset, size) ({\ + unsigned int data = (value) >> (value_offset); \ + data = GET_BIT_RANGE(data, size, 0); \ + data = data << (reg_offset); \ + CONSYS_REG_WRITE_RANGE(reg, data, ((reg_offset) + ((size) - 1)), reg_offset); \ +}) + +#define CONSYS_REG_WRITE_BIT(reg, offset, val) CONSYS_REG_WRITE_OFFSET_RANGE(reg, ((val) & 1), offset, 0, 1) + +#define CONSYS_REG_BIT_POLLING(addr, bit_index, exp_val, loop, delay, success) {\ + unsigned int polling_count = 0; \ + unsigned int reg_value = 0; \ + success = 0; \ + reg_value = (CONSYS_REG_READ_BIT(addr, (0x1 << bit_index)) >> bit_index); \ + while (reg_value != exp_val) { \ + if (polling_count > loop) { \ + success = -1; \ + break; \ + } \ + reg_value = (CONSYS_REG_READ_BIT(addr, (0x1 << bit_index)) >> bit_index); \ + udelay(delay); \ + polling_count++; \ + } \ +} + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _PLATFORM_CONSYS_REG_UTIL_H_ */ diff --git a/drivers/misc/mediatek/connectivity/conninfra/platform/include/emi_mng.h b/drivers/misc/mediatek/connectivity/conninfra/platform/include/emi_mng.h new file mode 100755 index 0000000000000000000000000000000000000000..b017993877a92877aa0ead3d178ec89eaf861364 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/platform/include/emi_mng.h @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#ifndef _PLATFORM_EMI_MNG_H_ +#define _PLATFORM_EMI_MNG_H_ + +#include +#include "osal.h" +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +struct consys_emi_addr_info { + /* This include BT/WF FW and WFDMA */ + phys_addr_t emi_ap_phy_addr; + unsigned int emi_size; + /* MCIF EMI get from MD */ + phys_addr_t md_emi_phy_addr; + unsigned int md_emi_size; +}; + +typedef int(*CONSYS_IC_EMI_MPU_SET_REGION_PROTECTION) (void); +typedef unsigned int(*CONSYS_IC_EMI_SET_REMAPPING_REG) (phys_addr_t, phys_addr_t); +typedef void(*CONSYS_IC_EMI_GET_MD_SHARED_EMI) (phys_addr_t* phy_addr, unsigned int *size); + +struct consys_platform_emi_ops { + CONSYS_IC_EMI_MPU_SET_REGION_PROTECTION consys_ic_emi_mpu_set_region_protection; + CONSYS_IC_EMI_SET_REMAPPING_REG consys_ic_emi_set_remapping_reg; + CONSYS_IC_EMI_GET_MD_SHARED_EMI consys_ic_emi_get_md_shared_emi; +}; + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +int emi_mng_init(void); +int emi_mng_deinit(void); + +int emi_mng_set_region_protection(void); +int emi_mng_set_remapping_reg(void); +struct consys_emi_addr_info* emi_mng_get_phy_addr(void); + + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _PLATFORM_EMI_MNG_H_ */ + diff --git a/drivers/misc/mediatek/connectivity/conninfra/platform/include/plat_def.h b/drivers/misc/mediatek/connectivity/conninfra/platform/include/plat_def.h new file mode 100755 index 0000000000000000000000000000000000000000..0d3903bd99df92ed7a0d92b29d812aae8f180551 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/platform/include/plat_def.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#ifndef _PLATFORM_DEF_H_ +#define _PLATFORM_DEF_H_ + +#include +#include + +#endif /* _PLATFORM_DEF_H_ */ diff --git a/drivers/misc/mediatek/connectivity/conninfra/platform/include/pmic_mng.h b/drivers/misc/mediatek/connectivity/conninfra/platform/include/pmic_mng.h new file mode 100755 index 0000000000000000000000000000000000000000..75d68ca59409eba326a56062da6a2580fae1f416 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/platform/include/pmic_mng.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#ifndef _PLATFORM_PMIC_MNG_H_ +#define _PLATFORM_PMIC_MNG_H_ + +#include + +#include "consys_hw.h" + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +typedef int(*CONSYS_PMIC_GET_FROM_DTS) ( + struct platform_device *pdev, + struct conninfra_dev_cb* dev_cb); + +typedef int(*CONSYS_PMIC_COMMON_POWER_CTRL) (unsigned int enable); + +typedef int(*CONSYS_PMIC_WIFI_POWER_CTRL) (unsigned int enable); +typedef int(*CONSYS_PMIC_BT_POWER_CTRL) (unsigned int enable); +typedef int(*CONSYS_PMIC_GPS_POWER_CTRL) (unsigned int enable); +typedef int(*CONSYS_PMIC_FM_POWER_CTRL) (unsigned int enable); +typedef int(*CONSYS_PMIC_EVENT_NOTIFIER) (unsigned int id, unsigned int event); + +typedef struct _CONSYS_PLATFORM_PMIC_OPS_ { + CONSYS_PMIC_GET_FROM_DTS consys_pmic_get_from_dts; + /* vcn 18 */ + CONSYS_PMIC_COMMON_POWER_CTRL consys_pmic_common_power_ctrl; + CONSYS_PMIC_WIFI_POWER_CTRL consys_pmic_wifi_power_ctrl; + CONSYS_PMIC_BT_POWER_CTRL consys_pmic_bt_power_ctrl; + CONSYS_PMIC_GPS_POWER_CTRL consys_pmic_gps_power_ctrl; + CONSYS_PMIC_FM_POWER_CTRL consys_pmic_fm_power_ctrl; + CONSYS_PMIC_EVENT_NOTIFIER consys_pmic_event_notifier; +} CONSYS_PLATFORM_PMIC_OPS, *P_CONSYS_PLATFORM_PMIC_OPS; + + + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +int pmic_mng_init(struct platform_device *pdev, struct conninfra_dev_cb* dev_cb); +int pmic_mng_deinit(void); + +int pmic_mng_common_power_ctrl(unsigned int enable); +int pmic_mng_wifi_power_ctrl(unsigned int enable); +int pmic_mng_bt_power_ctrl(unsigned int enable); +int pmic_mng_gps_power_ctrl(unsigned int enable); +int pmic_mng_fm_power_ctrl(unsigned int enable); +int pmic_mng_event_cb(unsigned int id, unsigned int event); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _PLATFORM_PMIC_MNG_H_ */ diff --git a/drivers/misc/mediatek/connectivity/conninfra/platform/mt6885/include/mt6885.h b/drivers/misc/mediatek/connectivity/conninfra/platform/mt6885/include/mt6885.h new file mode 100755 index 0000000000000000000000000000000000000000..6b067003c09e69e154e0b8da57f20163542222c5 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/platform/mt6885/include/mt6885.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#ifndef _PLATFORM_MT6885_H_ +#define _PLATFORM_MT6885_H_ + +enum conn_semaphore_type +{ + CONN_SEMA_CHIP_POWER_ON_INDEX = 0, + CONN_SEMA_CALIBRATION_INDEX = 1, + CONN_SEMA_FW_DL_INDEX = 2, + CONN_SEMA_CLOCK_SWITCH_INDEX = 3, + CONN_SEMA_CCIF_INDEX = 4, + CONN_SEMA_COEX_INDEX = 5, + CONN_SEMA_USB_EP0_INDEX = 6, + CONN_SEMA_USB_SHARED_INFO_INDEX = 7, + CONN_SEMA_USB_SUSPEND_INDEX = 8, + CONN_SEMA_USB_RESUME_INDEX = 9, + CONN_SEMA_PCIE_INDEX = 10, + CONN_SEMA_RFSPI_INDEX = 11, + CONN_SEMA_EFUSE_INDEX = 12, + CONN_SEMA_THERMAL_INDEX = 13, + CONN_SEMA_FLASH_INDEX = 14, + CONN_SEMA_DEBUG_INDEX = 15, + CONN_SEMA_WIFI_LP_INDEX = 16, + CONN_SEMA_PATCH_DL_INDEX = 17, + CONN_SEMA_SHARED_VAR_INDEX = 18, + CONN_SEMA_CONN_INFRA_COMMON_SYSRAM_INDEX = 19, + CONN_SEMA_NUM_MAX = 32 /* can't be omitted */ +}; + +int consys_platform_spm_conn_ctrl(unsigned int enable); +int consys_co_clock_type(void); + +struct consys_plat_thermal_data { + int thermal_b; + int slop_molecule; + int offset; +}; + +void update_thermal_data(struct consys_plat_thermal_data* input); +#endif /* _PLATFORM_MT6885_H_ */ diff --git a/drivers/misc/mediatek/connectivity/conninfra/platform/mt6885/include/mt6885_consys_reg.h b/drivers/misc/mediatek/connectivity/conninfra/platform/mt6885/include/mt6885_consys_reg.h new file mode 100755 index 0000000000000000000000000000000000000000..70fc7cddd91fc3b0dd28aeac590190598a9cd7f1 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/platform/mt6885/include/mt6885_consys_reg.h @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#ifndef _PLATFORM_MT6885_CONSYS_REG_H_ +#define _PLATFORM_MT6885_CONSYS_REG_H_ + +#include "consys_reg_base.h" +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +enum consys_base_addr_index { + CONN_INFRA_RGU_BASE_INDEX = 0, + CONN_INFRA_CFG_BASE_INDEX = 1, + CONN_HOST_CSR_TOP_BASE_INDEX = 2, + INFRACFG_AO_BASE_INDEX = 3, + TOPRGU_BASE_INDEX= 4, + SPM_BASE_INDEX = 5, + INFRACFG_BASE_INDEX = 6, + CONN_WT_SLP_CTL_REG_INDEX = 7, + CONN_AFE_CTL_INDEX = 8, + CONN_INFRA_SYSRAM_INDEX = 9, + GPIO_INDEX = 10, + CONN_RF_SPI_MST_REG_INDEX = 11, + CONN_SEMAPHORE_INDEX = 12, + CONN_TOP_THERM_CTL_INDEX = 13, + IOCFG_RT_INDEX = 14, /* Base: 0x11EA_0000 */ + CONN_DEBUG_CTRL = 15, /* Base: 0x1800_f000 */ + + CONSYS_BASE_ADDR_MAX +}; + + +struct consys_base_addr { + struct consys_reg_base_addr reg_base_addr[CONSYS_BASE_ADDR_MAX]; +}; + +extern struct consys_base_addr conn_reg; + +#define CON_REG_INFRA_RGU_ADDR conn_reg.reg_base_addr[CONN_INFRA_RGU_BASE_INDEX].vir_addr +#define CON_REG_INFRA_CFG_ADDR conn_reg.reg_base_addr[CONN_INFRA_CFG_BASE_INDEX].vir_addr +#define CON_REG_HOST_CSR_ADDR conn_reg.reg_base_addr[CONN_HOST_CSR_TOP_BASE_INDEX].vir_addr +#define CON_REG_INFRACFG_AO_ADDR conn_reg.reg_base_addr[INFRACFG_AO_BASE_INDEX].vir_addr + +#define CON_REG_TOP_RGU_ADDR conn_reg.reg_base_addr[TOPRGU_BASE_INDEX].vir_addr +#define CON_REG_SPM_BASE_ADDR conn_reg.reg_base_addr[SPM_BASE_INDEX].vir_addr +#define CON_REG_INFRACFG_BASE_ADDR conn_reg.reg_base_addr[INFRACFG_BASE_INDEX].vir_addr +#define CON_REG_WT_SPL_CTL_ADDR conn_reg.reg_base_addr[CONN_WT_SLP_CTL_REG_INDEX].vir_addr + +#define CONN_AFE_CTL_BASE_ADDR conn_reg.reg_base_addr[CONN_AFE_CTL_INDEX].vir_addr +#define CONN_INFRA_SYSRAM_BASE_ADDR conn_reg.reg_base_addr[CONN_INFRA_SYSRAM_INDEX].vir_addr +#define GPIO_BASE_ADDR conn_reg.reg_base_addr[GPIO_INDEX].vir_addr +#define CONN_REG_RFSPI_ADDR conn_reg.reg_base_addr[CONN_RF_SPI_MST_REG_INDEX].vir_addr + +#define CONN_REG_SEMAPHORE_ADDR conn_reg.reg_base_addr[CONN_SEMAPHORE_INDEX].vir_addr +#define CONN_TOP_THERM_CTL_ADDR conn_reg.reg_base_addr[CONN_TOP_THERM_CTL_INDEX].vir_addr +#define IOCFG_RT_ADDR conn_reg.reg_base_addr[IOCFG_RT_INDEX].vir_addr +#define CONN_DEBUG_CTRL_ADDR conn_reg.reg_base_addr[CONN_DEBUG_CTRL].vir_addr + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +struct consys_base_addr* get_conn_reg_base_addr(void); + +#endif /* _PLATFORM_MT6885_CONSYS_REG_H_ */ diff --git a/drivers/misc/mediatek/connectivity/conninfra/platform/mt6885/include/mt6885_consys_reg_offset.h b/drivers/misc/mediatek/connectivity/conninfra/platform/mt6885/include/mt6885_consys_reg_offset.h new file mode 100755 index 0000000000000000000000000000000000000000..552679e607619e86fe64b61d843ed864a83ddd8e --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/platform/mt6885/include/mt6885_consys_reg_offset.h @@ -0,0 +1,319 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#ifndef _PLATFORM_MT6885_CONSYS_REG_OFFSET_H_ +#define _PLATFORM_MT6885_CONSYS_REG_OFFSET_H_ + + +/**********************************************************************/ +/* Base: infracfg_ao (0x1000_1000) */ +/**********************************************************************/ +#define INFRA_TOPAXI_PROTECTEN_STA1_OFFSET 0x0228 +#define INFRA_TOPAXI_PROTECTEN_SET_OFFSET 0x02a0 +#define INFRA_TOPAXI_PROTECTEN_CLR_OFFSET 0x02a4 +#define INFRA_TOPAXI_PROTECTEN2_CLR_OFFSET 0x0718 +#define INFRA_TOPAXI_PROTECTEN2_SET_OFFSET 0x0714 +#define INFRA_TOPAXI_PROTECTEN2_STA1_OFFSET 0x0724 + +/**********************************************************************/ +/* Base: GPIO (0x1000_5000) */ +/**********************************************************************/ +#define GPIO_DIR5_SET 0x0054 + +#define GPIO_DOUT5_SET 0x0154 + +#define GPIO_MODE19 0x0430 +#define GPIO_MODE21 0x0450 +#define GPIO_MODE22 0x0460 + +/**********************************************************************/ +/* Base: SPM (0x1000_6000) */ +/**********************************************************************/ +#define SPM_POWERON_CONFIG_EN 0x0000 +#define SPM_PCM_REG13_DATA 0x0110 +#define SPM_PCM_REG7_DATA 0x0100 +#define SPM_SRC_REQ_STA_0 0x0114 +#define SPM_BUS_PROTECT_RDY 0x0150 +#define SPM_BUS_PROTECT2_RDY 0x0158 +#define SPM_PWR_STATUS 0x016c +#define SPM_PWR_STATUS_2ND 0x0170 +#define SPM_CONN_PWR_CON 0x0304 +#define SPM_PLL_CON 0x044C +#define SPM_RC_CENTRAL_CFG1 0x0504 +#define SPM_PCM_WDT_LATCH_SPARE_0 0x084C + +#define SPM_RC_RC_M04_REQ_STA_0 0xE28 +#define SPM_RC_RC_M05_REQ_STA_0 0xE2C +#define SPM_RC_RC_M06_REQ_STA_0 0xE30 +#define SPM_RC_RC_M07_REQ_STA_0 0xE34 + +/**********************************************************************/ +/* Base: TOP RGU (0x1000_7000) */ +/**********************************************************************/ +#define TOP_RGU_WDT_SWSYSRST 0x0018 + + +/**********************************************************************/ +/* Base: INFRACFG (0x1020_e000) */ +/**********************************************************************/ +#define INFRA_AP2MD_GALS_CTL 0x0504 +#define INFRA_CONN2AP_GLAS_RC_ST 0x0804 + +/**********************************************************************/ +/* Base: IOCFG_RT (0x11EA_0000) */ +/**********************************************************************/ +#define IOCFG_RT_DRV_CFG0 0x0000 +#define IOCFG_RT_PD_CFG0_SET 0x0054 +#define IOCFG_RT_PD_CFG0_CLR 0x0058 +#define IOCFG_RT_PU_CFG0_SET 0x0074 +#define IOCFG_RT_PU_CFG0_CLR 0x0078 + +/**********************************************************************/ +/* Base: conn_infra_rgu (0x1800_0000) */ +/**********************************************************************/ +#define CONN_INFRA_RGU_BGFSYS_ON_TOP_PWR_CTL 0x0008 +#define CONN_INFRA_RGU_SYSRAM_HWCTL_PDN 0x0038 +#define CONN_INFRA_RGU_SYSRAM_HWCTL_SLP 0x003c +#define CONN_INFRA_RGU_CO_EXT_MEM_HWCTL_PDN 0x0050 +#define CONN_INFRA_RGU_CO_EXT_MEM_HWCTL_SLP 0x0054 +#define CONN_INFRA_RGU_DEBUG_SEL 0x0090 + +/**********************************************************************/ +/* Base: conn_infra_cfg (0x1800_1000) */ +/**********************************************************************/ +#define CONN_HW_VER_OFFSET 0x0000 +#define CONN_CFG_ID_OFFSET 0x0004 +#define CONN_INFRA_CFG_LIGHT_SECURITY_CTRL 0x00f0 + +#define CONN_INFRA_CFG_GALS_AP2CONN_GALS_DBG 0x0160 +#define CONN_INFRA_CFG_GALS_CONN2AP_TX_SLP_CTRL 0x0630 +#define CONN_INFRA_CFG_GALS_CONN2AP_RX_SLP_CTRL 0x0634 +#define CONN_INFRA_CFG_GALS_GPS2CONN_SLP_CTRL 0x061C +#define CONN_INFRA_CFG_GALS_CONN2GPS_SLP_CTRL 0x0618 +#define CONN_INFRA_CFG_GALS_BT2CONN_SLP_CTRL 0x0614 +#define CONN_INFRA_CFG_GALS_CONN2BT_SLP_CTRL 0x0610 + +#define CONN_INFRA_CFG_WF_SLP_CTRL 0x0620 +#define CONN_INFRA_CFG_ON_BUS_SLP_CTRL 0x0628 +#define CONN_INFRA_CFG_OFF_BUS_SLP_CTRL 0x062C + + +#define CONN_INFRA_CFG_OSC_CTL_0 0x0800 +#define CONN_INFRA_CFG_OSC_CTL_1 0x0804 +#define CONN_INFRA_CFG_OSC_STATUS 0x080C +#define CONN_INFRA_CFG_PLL_STATUS 0x0810 + +#define AP2CONN_EFUSE_DATA 0x0818 +#define CONN_INFRA_CFG_RC_CTL_0 0x0834 +#define CONN_INFRA_CFG_RC_CTL_0_GPS 0x0838 +#define CONN_INFRA_CFG_RC_CTL_1_GPS 0x083C +#define CONN_INFRA_CFG_RC_CTL_0_BT 0x0840 +#define CONN_INFRA_CFG_RC_CTL_1_BT 0x0844 +#define CONN_INFRA_CFG_RC_CTL_0_WF 0x0848 +#define CONN_INFRA_CFG_RC_CTL_1_WF 0x084c +#define CONN_INFRA_CFG_RC_CTL_1_TOP 0x0854 +#define CONN_INFRA_CFG_RC_CTL_0_TOP 0x0850 +#define CONN_INFRA_CFG_PWRCTRL0 0x0860 +#define CONN_INFRA_CFG_ADIE_CTL 0x0900 +#define CONN_INFRA_CFG_CKGEN_BUS 0x0a00 +#define CONN_INFRA_CFG_DBG_MUX_SEL 0x0b00 +#define CONN_INFRA_CFG_EMI_CTL_0 0x0c00 + +#define CONN_HW_VER 0x20010000 +#define CONN_CFG_ID 0x3 + +/**********************************************************************/ +/* Base: conn_top_therm_ctl (0x1800_2000) */ +/**********************************************************************/ +#define CONN_TOP_THERM_CTL_THERMCR1 0x0004 +#define CONN_TOP_THERM_CTL_THERM_AADDR 0x0018 +#define CONN_TOP_THERM_CTL_THERM_CAL_EN 0x0024 + +/**********************************************************************/ +/* Base: conn_afe_ctl(0x1800_3000) */ +/**********************************************************************/ +#define CONN_AFE_CTL_RG_DIG_EN_01 0x0000 +#define CONN_AFE_CTL_RG_DIG_EN_02 0x0004 +#define CONN_AFE_CTL_RG_DIG_EN_03 0x0008 +#define CONN_AFE_CTL_RG_WBG_AFE_01 0x0010 +#define CONN_AFE_CTL_RG_WBG_RCK_01 0x0018 +#define CONN_AFE_CTL_RG_WBG_GL1_01 0x0040 +#define CONN_AFE_CTL_RG_WBG_BT_TX_03 0x0058 +#define CONN_AFE_CTL_RG_WBG_WF0_TX_03 0x0078 +#define CONN_AFE_CTL_RG_WBG_WF1_TX_03 0x0094 +#define CONN_AFE_CTL_RG_PLL_STB_TIME 0x00f4 +#define CONN_AFE_CTL_RG_WBG_GL5_01 0x0100 + + +/**********************************************************************/ +/* Base: conn_rf_spi_mst_reg(0x1800_4000) */ +/**********************************************************************/ +#define CONN_RF_SPI_MST_REG_SPI_STA 0x0000 +#define CONN_RF_SPI_MST_REG_SPI_CRTL 0x0004 +#define CONN_RF_SPI_MST_REG_FM_CTRL 0x000c +#define CONN_RF_SPI_MST_REG_SPI_WF_ADDR 0x0010 +#define CONN_RF_SPI_MST_REG_SPI_WF_WDAT 0x0014 +#define CONN_RF_SPI_MST_REG_SPI_WF_RDAT 0x0018 +#define CONN_RF_SPI_MST_REG_SPI_BT_ADDR 0x0020 +#define CONN_RF_SPI_MST_REG_SPI_BT_WDAT 0x0024 +#define CONN_RF_SPI_MST_REG_SPI_BT_RDAT 0x0028 +#define CONN_RF_SPI_MST_REG_SPI_FM_ADDR 0x0030 +#define CONN_RF_SPI_MST_REG_SPI_FM_WDAT 0x0034 +#define CONN_RF_SPI_MST_REG_SPI_FM_RDAT 0x0038 +#define CONN_RF_SPI_MST_REG_SPI_TOP_ADDR 0x0050 +#define CONN_RF_SPI_MST_REG_SPI_TOP_WDAT 0x0054 +#define CONN_RF_SPI_MST_REG_SPI_TOP_RDAT 0x0058 +#define CONN_RF_SPI_MST_REG_SPI_GPS_GPS_ADDR 0x0210 +#define CONN_RF_SPI_MST_REG_SPI_GPS_GPS_WDAT 0x0214 +#define CONN_RF_SPI_MST_REG_SPI_GPS_GPS_RDAT 0x0218 + + +/**********************************************************************/ +/* Base: conn_wt_slp_ctl_reg(0x1800_5000) */ +/**********************************************************************/ +#define CONN_WTSLP_CTL_REG_WB_STA 0x0008 +#define CONN_WT_SLP_CTL_REG_WB_SLP_CTL 0x0004 +#define CONN_WT_SLP_CTL_REG_WB_BG_ADDR1 0x0010 +#define CONN_WT_SLP_CTL_REG_WB_BG_ADDR2 0x0014 +#define CONN_WT_SLP_CTL_REG_WB_BG_ADDR3 0x0018 +#define CONN_WT_SLP_CTL_REG_WB_BG_ADDR4 0x001c +#define CONN_WT_SLP_CTL_REG_WB_BG_ADDR5 0x0020 +#define CONN_WT_SLP_CTL_REG_WB_BG_ADDR6 0x0024 +#define CONN_WT_SLP_CTL_REG_WB_BG_ADDR7 0x0028 +#define CONN_WT_SLP_CTL_REG_WB_BG_ADDR8 0x002c +#define CONN_WT_SLP_CTL_REG_WB_BG_ON1 0x0030 +#define CONN_WT_SLP_CTL_REG_WB_BG_ON2 0x0034 +#define CONN_WT_SLP_CTL_REG_WB_BG_ON3 0x0038 +#define CONN_WT_SLP_CTL_REG_WB_BG_ON4 0x003c +#define CONN_WT_SLP_CTL_REG_WB_BG_ON5 0x0040 +#define CONN_WT_SLP_CTL_REG_WB_BG_ON6 0x0044 +#define CONN_WT_SLP_CTL_REG_WB_BG_ON7 0x0048 +#define CONN_WT_SLP_CTL_REG_WB_BG_ON8 0x004c +#define CONN_WT_SLP_CTL_REG_WB_BG_OFF1 0x0050 +#define CONN_WT_SLP_CTL_REG_WB_BG_OFF2 0x0054 +#define CONN_WT_SLP_CTL_REG_WB_BG_OFF3 0x0058 +#define CONN_WT_SLP_CTL_REG_WB_BG_OFF4 0x005c +#define CONN_WT_SLP_CTL_REG_WB_BG_OFF5 0x0060 +#define CONN_WT_SLP_CTL_REG_WB_BG_OFF6 0x0064 +#define CONN_WT_SLP_CTL_REG_WB_BG_OFF7 0x0068 +#define CONN_WT_SLP_CTL_REG_WB_BG_OFF8 0x006c +#define CONN_WT_SLP_CTL_REG_WB_WF_CK_ADDR 0x0070 +#define CONN_WT_SLP_CTL_REG_WB_WF_WAKE_ADDR 0x0074 +#define CONN_WT_SLP_CTL_REG_WB_WF_ZPS_ADDR 0x0078 +#define CONN_WT_SLP_CTL_REG_WB_BT_CK_ADDR 0x007c +#define CONN_WT_SLP_CTL_REG_WB_BT_WAKE_ADDR 0x0080 +#define CONN_WT_SLP_CTL_REG_WB_TOP_CK_ADDR 0x0084 +#define CONN_WT_SLP_CTL_REG_WB_GPS_CK_ADDR 0x0088 +#define CONN_WT_SLP_CTL_REG_WB_WF_B0_CMD_ADDR 0x008c +#define CONN_WT_SLP_CTL_REG_WB_WF_B1_CMD_ADDR 0x0090 +#define CONN_WT_SLP_CTL_REG_WB_GPS_RFBUF_ADDR 0x0094 +#define CONN_WT_SLP_CTL_REG_WB_GPS_L5_EN_ADDR 0x0098 + +/**********************************************************************/ +/* Base: GPT2 timer (0x1800_7000) */ +/**********************************************************************/ +#define CONN_GPT2_CTRL_BASE 0x18007000 +#define CONN_GPT2_CTRL_THERMAL_EN 0x38 + +/**********************************************************************/ +/* Base: debug_ctrl (0x1800_f000) */ +/**********************************************************************/ +#define CONN_DEBUG_CTRL_REG_OFFSET 0x0000 + + +/**********************************************************************/ +/* Base: conn_infra_sysram(0x1805_0000) */ +/**********************************************************************/ +#define CONN_INFRA_SYSRAM_SW_CR_A_DIE_CHIP_ID 0x2800 +#define CONN_INFRA_SYSRAM_SW_CR_A_DIE_EFUSE_DATA_0 0x2804 +#define CONN_INFRA_SYSRAM_SW_CR_A_DIE_EFUSE_DATA_1 0x2808 +#define CONN_INFRA_SYSRAM_SW_CR_A_DIE_EFUSE_DATA_2 0x280C +#define CONN_INFRA_SYSRAM_SW_CR_A_DIE_EFUSE_DATA_3 0x2810 + +#define CONN_INFRA_SYSRAM_SW_CR_D_DIE_EFUSE 0x2820 + +#define CONN_INFRA_SYSRAM_SW_CR_A_DIE_TOP_CK_EN_CTRL 0x2830 +#define CONN_INFRA_SYSRAM_SW_CR_RADIO_STATUS 0x2834 + +#define CONN_INFRA_SYSRAM_SW_CR_OFFSET 0x2800 +#define CONN_INFRA_SYSRAM_SW_CR_SIZE (4 * 1024) + + +/**********************************************************************/ +/* Base: conn_host_csr_top (0x1806_0000) */ +/**********************************************************************/ +#define CONN_HOST_CSR_TOP_CSR_DEADFEED_EN_CR 0x0124 +#define CONN_HOST_CSR_TOP_CONN_INFRA_DEBUG_AO_DEBUGSYS 0x0128 +#define CONN_HOST_CSR_TOP_CONN_INFRA_DEBUG_CTRL_AO2SYS_OUT 0x0148 +#define CONN_HOST_CSR_TOP_CONN_SLP_PROT_CTRL 0x0184 +#define CONN_HOST_CSR_TOP_CONN_INFRA_WAKEPU_TOP_CONN_INFRA_WAKEPU_TOP 0x01a0 +/* remap */ +#define CONN2AP_REMAP_MCU_EMI_BASE_ADDR_OFFSET 0x01c4 +#define CONN2AP_REMAP_MD_SHARE_EMI_BASE_ADDR_OFFSET 0x01cc +#define CONN2AP_REMAP_GPS_EMI_BASE_ADDR_OFFSET 0x01d0 +#define CONN2AP_REMAP_WF_PERI_BASE_ADDR_OFFSET 0x01d4 +#define CONN2AP_REMAP_BT_PERI_BASE_ADDR_OFFSET 0x01d8 +#define CONN2AP_REMAP_GPS_PERI_BASE_ADDR_OFFSET 0x01dc + +#define CONN_HOST_CSR_WM_MCU_PC_DBG 0x0204 +#define CONN_HOST_CSR_WM_MCU_GPR_DBG 0x0208 +#define CONN_HOST_CSR_BGF_MCU_PC_DBG 0x022C + +#define CONN_HOST_CSR_DBG_DUMMY_0 0x02C0 +#define CONN_HOST_CSR_DBG_DUMMY_2 0x02C8 +#define CONN_HOST_CSR_DBG_DUMMY_3 0x02CC +#define CONN_HOST_CSR_DBG_DUMMY_4 0x02D0 +#define CONN_HOST_CSR_TOP_BUS_TIMEOUT_IRQ 0x02d4 + +#define TOP_BUS_MUC_STAT_HCLK_FR_CK_DETECT_BIT (0x1 << 1) +#define TOP_BUS_MUC_STAT_OSC_CLK_DETECT_BIT (0x1 << 2) +#define TOP_SLP_PROT_CTRL_CONN_INFRA_ON2OFF_SLP_PROT_ACK_BIT (0x1 << 5) + +/**********************************************************************/ +/* Base: conn_semaphore(0x1807_0000) */ +/**********************************************************************/ +#define CONN_SEMA_OWN_BY_M0_STA_REP 0x0400 +#define CONN_SEMA_OWN_BY_M1_STA_REP 0x1400 +#define CONN_SEMAPHORE_M2_OWN_STA 0x2000 +#define CONN_SEMAPHORE_M2_OWN_REL 0x2200 +#define CONN_SEMA_OWN_BY_M2_STA_REP 0x2400 +#define CONN_SEMA_OWN_BY_M3_STA_REP 0x3400 + +/**********************************************************************/ +/* A-die CR */ +/**********************************************************************/ +#define ATOP_CHIP_ID 0x02c +#define ATOP_RG_TOP_THADC_BG 0x034 +#define ATOP_RG_TOP_THADC 0x038 +#define ATOP_WRI_CTR2 0x064 +#define ATOP_RG_ENCAL_WBTAC_IF_SW 0x070 +#define ATOP_SMCTK11 0x0BC +#define ATOP_EFUSE_CTRL 0x108 +#define ATOP_EFUSE_RDATA0 0x130 +#define ATOP_EFUSE_RDATA1 0x134 +#define ATOP_EFUSE_RDATA2 0x138 +#define ATOP_EFUSE_RDATA3 0x13c +#define ATOP_RG_WF0_TOP_01 0x380 +#define ATOP_RG_WF0_BG 0x384 +#define ATOP_RG_WF1_BG 0x394 +#define ATOP_RG_WF1_TOP_01 0x390 +#define ATOP_RG_TOP_XTAL_01 0xA18 +#define ATOP_RG_TOP_XTAL_02 0xA1C + + +#endif /* _PLATFORM_MT6885_CONSSY_REG_OFFSET_H_ */ diff --git a/drivers/misc/mediatek/connectivity/conninfra/platform/mt6885/include/mt6885_emi.h b/drivers/misc/mediatek/connectivity/conninfra/platform/mt6885/include/mt6885_emi.h new file mode 100755 index 0000000000000000000000000000000000000000..f941a155a9c1fc5cdcd50e9a32ef164de120946d --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/platform/mt6885/include/mt6885_emi.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#ifndef _PLATFORM_MT6885_EMI_H_ +#define _PLATFORM_MT6885_EMI_H_ + +#include "osal.h" +#include "emi_mng.h" +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +struct consys_platform_emi_ops* get_consys_platform_emi_ops(void); + +struct consys_emi_addr_info* consys_emi_get_phy_addr(void); +int consys_emi_mpu_set_region_protection(void); +void consys_emi_get_md_shared_emi(phys_addr_t*, unsigned int*); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _PLATFORM_MT6885_EMI_H_ */ diff --git a/drivers/misc/mediatek/connectivity/conninfra/platform/mt6885/include/mt6885_pmic.h b/drivers/misc/mediatek/connectivity/conninfra/platform/mt6885/include/mt6885_pmic.h new file mode 100755 index 0000000000000000000000000000000000000000..313fdeb4de6b372c3cc21b2b13626b77e9510985 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/platform/mt6885/include/mt6885_pmic.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#ifndef _PLATFORM_MT6885_PMIC_H_ +#define _PLATFORM_MT6885_PMIC_H_ + +#include "osal.h" +#include "pmic_mng.h" +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +P_CONSYS_PLATFORM_PMIC_OPS get_consys_platform_pmic_ops(void); +int consys_plt_pmic_ctrl_dump(const char* tag); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _PLATFORM_MT6885_PMIC_H_ */ diff --git a/drivers/misc/mediatek/connectivity/conninfra/platform/mt6885/include/mt6885_pos.h b/drivers/misc/mediatek/connectivity/conninfra/platform/mt6885/include/mt6885_pos.h new file mode 100755 index 0000000000000000000000000000000000000000..8c1255a5bfb69424468514dc64f0dca9fdd84e47 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/platform/mt6885/include/mt6885_pos.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#ifndef _PLATFORM_MT6885_POS_H_ +#define _PLATFORM_MT6885_POS_H_ + + +unsigned int consys_emi_set_remapping_reg(phys_addr_t, phys_addr_t); + +int consys_conninfra_on_power_ctrl(unsigned int enable); +int consys_conninfra_wakeup(void); +int consys_conninfra_sleep(void); +void consys_set_if_pinmux(unsigned int enable); +int consys_polling_chipid(void); + +int connsys_d_die_cfg(void); +int connsys_spi_master_cfg(unsigned int); +int connsys_a_die_cfg(void); +int connsys_afe_wbg_cal(void); +int connsys_subsys_pll_initial(void); +int connsys_low_power_setting(unsigned int, unsigned int); + +int consys_sema_acquire_timeout(unsigned int index, unsigned int usec); +void consys_sema_release(unsigned int index); + +int consys_spi_read(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int *data); +int consys_spi_write(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int data); +int consys_spi_write_offset_range( + enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int value, + unsigned int reg_offset, unsigned int value_offset, unsigned int size); + +int consys_adie_top_ck_en_on(enum consys_adie_ctl_type type); +int consys_adie_top_ck_en_off(enum consys_adie_ctl_type type); + +int consys_spi_clock_switch(enum connsys_spi_speed_type type); +int consys_subsys_status_update(bool, int); +bool consys_is_rc_mode_enable(void); + +void consys_config_setup(void); + +#endif /* _PLATFORM_MT6885_POS_H_ */ diff --git a/drivers/misc/mediatek/connectivity/conninfra/platform/mt6885/mt6885.c b/drivers/misc/mediatek/connectivity/conninfra/platform/mt6885/mt6885.c new file mode 100755 index 0000000000000000000000000000000000000000..eeb5034d6afa564d3d267ad1c259f8f0a7d1314b --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/platform/mt6885/mt6885.c @@ -0,0 +1,435 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#define pr_fmt(fmt) KBUILD_MODNAME "@(%s:%d) " fmt, __func__, __LINE__ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "osal.h" +#include "conninfra.h" +#include "conninfra_conf.h" +#include "consys_hw.h" +#include "consys_reg_mng.h" +#include "consys_reg_util.h" +#include "mt6885.h" +#include "emi_mng.h" +#include "mt6885_emi.h" +#include "mt6885_consys_reg.h" +#include "mt6885_consys_reg_offset.h" +#include "mt6885_pos.h" + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +#define CONSYS_PWR_SPM_CTRL 1 +#define PLATFORM_SOC_CHIP 0x6885 + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +static int consys_clk_get_from_dts(struct platform_device *pdev); +static int consys_clock_buffer_ctrl(unsigned int enable); +static unsigned int consys_soc_chipid_get(void); +static unsigned int consys_get_hw_ver(void); +static void consys_clock_fail_dump(void); +static int consys_thermal_query(void); +static int consys_power_state(void); +static int consys_bus_clock_ctrl(enum consys_drv_type, unsigned int, int); + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ +struct consys_hw_ops_struct g_consys_hw_ops = { + /* load from dts */ + /* TODO: mtcmos should move to a independent module */ + .consys_plt_clk_get_from_dts = consys_clk_get_from_dts, + + /* clock */ + .consys_plt_clock_buffer_ctrl = consys_clock_buffer_ctrl, + .consys_plt_co_clock_type = consys_co_clock_type, + + /* POS */ + .consys_plt_conninfra_on_power_ctrl = consys_conninfra_on_power_ctrl, + .consys_plt_set_if_pinmux = consys_set_if_pinmux, + + .consys_plt_polling_consys_chipid = consys_polling_chipid, + .consys_plt_d_die_cfg = connsys_d_die_cfg, + .consys_plt_spi_master_cfg = connsys_spi_master_cfg, + .consys_plt_a_die_cfg = connsys_a_die_cfg, + .consys_plt_afe_wbg_cal = connsys_afe_wbg_cal, + .consys_plt_subsys_pll_initial = connsys_subsys_pll_initial, + .consys_plt_low_power_setting = connsys_low_power_setting, + .consys_plt_soc_chipid_get = consys_soc_chipid_get, + .consys_plt_conninfra_wakeup = consys_conninfra_wakeup, + .consys_plt_conninfra_sleep = consys_conninfra_sleep, + .consys_plt_is_rc_mode_enable = consys_is_rc_mode_enable, + + /* debug */ + .consys_plt_clock_fail_dump = consys_clock_fail_dump, + .consys_plt_get_hw_ver = consys_get_hw_ver, + + .consys_plt_spi_read = consys_spi_read, + .consys_plt_spi_write = consys_spi_write, + .consys_plt_adie_top_ck_en_on = consys_adie_top_ck_en_on, + .consys_plt_adie_top_ck_en_off = consys_adie_top_ck_en_off, + .consys_plt_spi_clock_switch = consys_spi_clock_switch, + .consys_plt_subsys_status_update = consys_subsys_status_update, + + .consys_plt_thermal_query = consys_thermal_query, + .consys_plt_power_state = consys_power_state, + .consys_plt_config_setup = consys_config_setup, + .consys_plt_bus_clock_ctrl = consys_bus_clock_ctrl, +}; + + +struct clk *clk_scp_conn_main; /*ctrl conn_power_on/off */ +struct consys_plat_thermal_data g_consys_plat_therm_data; + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +struct consys_hw_ops_struct* get_consys_platform_ops(void) +{ + return &g_consys_hw_ops; +} + +/* mtcmos contorl */ +int consys_clk_get_from_dts(struct platform_device *pdev) +{ + clk_scp_conn_main = devm_clk_get(&pdev->dev, "conn"); + if (IS_ERR(clk_scp_conn_main)) { + pr_err("[CCF]cannot get clk_scp_conn_main clock.\n"); + return PTR_ERR(clk_scp_conn_main); + } + pr_debug("[CCF]clk_scp_conn_main=%p\n", clk_scp_conn_main); + + return 0; +} + +int consys_platform_spm_conn_ctrl(unsigned int enable) +{ + int ret = 0; + + if (enable) { + ret = clk_prepare_enable(clk_scp_conn_main); + if (ret) { + pr_err("Turn on oonn_infra power fail. Ret=%d\n", ret); + return -1; + } + } else { + clk_disable_unprepare(clk_scp_conn_main); + + } + + return ret; +} + +int consys_clock_buffer_ctrl(unsigned int enable) +{ + /* This function call didn't work now. + * clock buffer is HW controlled, not SW controlled. + * Keep this function call to update status. + */ + if (enable) + KERNEL_clk_buf_ctrl(CLK_BUF_CONN, true); /*open XO_WCN*/ + else + KERNEL_clk_buf_ctrl(CLK_BUF_CONN, false); /*close XO_WCN*/ + return 0; +} + +int consys_co_clock_type(void) +{ + const struct conninfra_conf *conf; + + /* Default solution */ + conf = conninfra_conf_get_cfg(); + if (NULL == conf) { + pr_err("[%s] Get conf fail", __func__); + return -1; + } + /* TODO: for co-clock mode, there are two case: 26M and 52M. Need something to distinguish it. */ + if (conf->tcxo_gpio != 0) + return CONNSYS_CLOCK_SCHEMATIC_26M_EXTCXO; + else + return CONNSYS_CLOCK_SCHEMATIC_26M_COTMS; +} + +unsigned int consys_soc_chipid_get(void) +{ + return PLATFORM_SOC_CHIP; +} + +unsigned int consys_get_hw_ver(void) +{ + return CONN_HW_VER; +} + +void consys_clock_fail_dump(void) +{ + pr_info("[%s]", __func__); +} + + +void update_thermal_data(struct consys_plat_thermal_data* input) +{ + memcpy(&g_consys_plat_therm_data, input, sizeof(struct consys_plat_thermal_data)); + /* Special factor, not in POS */ + /* THERMCR1 [16:17]*/ + CONSYS_REG_WRITE(CONN_TOP_THERM_CTL_ADDR + CONN_TOP_THERM_CTL_THERMCR1, + (CONSYS_REG_READ(CONN_TOP_THERM_CTL_ADDR + CONN_TOP_THERM_CTL_THERMCR1) | + (0x3 << 16))); + +} + +int calculate_thermal_temperature(int y) +{ + struct consys_plat_thermal_data *data = &g_consys_plat_therm_data; + int t; + int const_offset = 25; + + /* + * MT6635 E1 : read 0x02C = 0x66358A00 + * MT6635 E2 : read 0x02C = 0x66358A10 + * MT6635 E3 : read 0x02C = 0x66358A11 + */ + if (conn_hw_env.adie_hw_version == 0x66358A10 || + conn_hw_env.adie_hw_version == 0x66358A11) + const_offset = 28; + + /* temperature = (y-b)*slope + (offset) */ + /* TODO: offset + 25 : this is only for E1, E2 is 28 */ + t = (y - (data->thermal_b == 0 ? 0x36 : data->thermal_b)) * + ((data->slop_molecule + 209) / 100) + (data->offset + const_offset); + + pr_info("y=[%d] b=[%d] constOffset=[%d] [%d] [%d] => t=[%d]\n", + y, data->thermal_b, const_offset, data->slop_molecule, data->offset, + t); + + return t; +} + +int consys_thermal_query(void) +{ +#define THERMAL_DUMP_NUM 11 +#define LOG_TMP_BUF_SZ 256 +#define TEMP_SIZE 13 + void __iomem *addr = NULL; + int cal_val, res = 0; + /* Base: 0x1800_2000, CONN_TOP_THERM_CTL */ + const unsigned int thermal_dump_crs[THERMAL_DUMP_NUM] = { + 0x00, 0x04, 0x08, 0x0c, + 0x10, 0x14, 0x18, 0x1c, + 0x20, 0x24, 0x28, + }; + char tmp[TEMP_SIZE] = {'\0'}; + char tmp_buf[LOG_TMP_BUF_SZ] = {'\0'}; + unsigned int i; + unsigned int efuse0, efuse1, efuse2, efuse3; + + addr = ioremap_nocache(CONN_GPT2_CTRL_BASE, 0x100); + if (addr == NULL) { + pr_err("GPT2_CTRL_BASE remap fail"); + return -1; + } + + consys_adie_top_ck_en_on(CONNSYS_ADIE_CTL_HOST_CONNINFRA); + + /* Hold Semaphore, TODO: may not need this, because + thermal cr seperate for different */ + if (consys_sema_acquire_timeout(CONN_SEMA_THERMAL_INDEX, CONN_SEMA_TIMEOUT) == CONN_SEMA_GET_FAIL) { + pr_err("[THERM QRY] Require semaphore fail\n"); + consys_adie_top_ck_en_off(CONNSYS_ADIE_CTL_HOST_CONNINFRA); + iounmap(addr); + return -1; + } + + /* therm cal en */ + CONSYS_REG_WRITE(CONN_TOP_THERM_CTL_ADDR + CONN_TOP_THERM_CTL_THERM_CAL_EN, + (CONSYS_REG_READ(CONN_TOP_THERM_CTL_ADDR + CONN_TOP_THERM_CTL_THERM_CAL_EN) | + (0x1 << 19))); + /* GPT2 En */ + CONSYS_REG_WRITE(addr + CONN_GPT2_CTRL_THERMAL_EN, + (CONSYS_REG_READ(addr + CONN_GPT2_CTRL_THERMAL_EN) | + 0x1)); + + /* thermal trigger */ + CONSYS_REG_WRITE(CONN_TOP_THERM_CTL_ADDR + CONN_TOP_THERM_CTL_THERM_CAL_EN, + (CONSYS_REG_READ(CONN_TOP_THERM_CTL_ADDR + CONN_TOP_THERM_CTL_THERM_CAL_EN) | + (0x1 << 18))); + udelay(500); + /* get thermal value */ + cal_val = CONSYS_REG_READ(CONN_TOP_THERM_CTL_ADDR + CONN_TOP_THERM_CTL_THERM_CAL_EN); + cal_val = (cal_val >> 8) & 0x7f; + + /* thermal debug dump */ + efuse0 = CONSYS_REG_READ(CONN_INFRA_SYSRAM_BASE_ADDR + CONN_INFRA_SYSRAM_SW_CR_A_DIE_EFUSE_DATA_0); + efuse1 = CONSYS_REG_READ(CONN_INFRA_SYSRAM_BASE_ADDR + CONN_INFRA_SYSRAM_SW_CR_A_DIE_EFUSE_DATA_1); + efuse2 = CONSYS_REG_READ(CONN_INFRA_SYSRAM_BASE_ADDR + CONN_INFRA_SYSRAM_SW_CR_A_DIE_EFUSE_DATA_2); + efuse3 = CONSYS_REG_READ(CONN_INFRA_SYSRAM_BASE_ADDR + CONN_INFRA_SYSRAM_SW_CR_A_DIE_EFUSE_DATA_3); + for (i = 0; i < THERMAL_DUMP_NUM; i++) { + if (snprintf( + tmp, TEMP_SIZE, "[0x%08x]", + CONSYS_REG_READ(CONN_TOP_THERM_CTL_ADDR + thermal_dump_crs[i])) >= 0) + strncat(tmp_buf, tmp, strlen(tmp)); + } + pr_info("[%s] efuse:[0x%08x][0x%08x][0x%08x][0x%08x] thermal dump: %s", + __func__, efuse0, efuse1, efuse2, efuse3, tmp_buf); + + res = calculate_thermal_temperature(cal_val); + + /* GPT2 disable, no effect on 6885 */ + CONSYS_REG_WRITE(addr + CONN_GPT2_CTRL_THERMAL_EN, + (CONSYS_REG_READ(addr + CONN_GPT2_CTRL_THERMAL_EN) & + ~(0x1))); + + /* disable */ + CONSYS_REG_WRITE(CONN_TOP_THERM_CTL_ADDR + CONN_TOP_THERM_CTL_THERM_CAL_EN, + (CONSYS_REG_READ(CONN_TOP_THERM_CTL_ADDR + CONN_TOP_THERM_CTL_THERM_CAL_EN) & + ~(0x1 << 19))); + + consys_sema_release(CONN_SEMA_THERMAL_INDEX); + consys_adie_top_ck_en_off(CONNSYS_ADIE_CTL_HOST_CONNINFRA); + + iounmap(addr); + + return res; +} + + +int consys_power_state(void) +{ + const char* osc_str[] = { + "fm ", "gps ", "bgf ", "wf ", "ap2conn ", "conn_thm ", "conn_pta ", "conn_infra_bus " + }; + char buf[256] = {'\0'}; + unsigned int r = CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_DBG_DUMMY_2); + unsigned int i, buf_len = 0, str_len; + + for (i = 0; i < 8; i++) { + str_len = strlen(osc_str[i]); + if ((r & (0x1 << (18 + i))) > 0 && (buf_len + str_len < 256)) { + strncat(buf, osc_str[i], str_len); + buf_len += str_len; + } + } + pr_info("[%s] [0x%x] %s", __func__, r, buf); + return 0; +} + +int consys_bus_clock_ctrl(enum consys_drv_type drv_type, unsigned int bus_clock, int status) +{ + static unsigned int conninfra_bus_clock_wpll_state = 0; + static unsigned int conninfra_bus_clock_bpll_state = 0; + unsigned int wpll_state = conninfra_bus_clock_wpll_state; + unsigned int bpll_state = conninfra_bus_clock_bpll_state; + bool wpll_switch = false, bpll_switch = false; + int check; + + if (status) { + /* Turn on */ + /* Enable BPLL */ + if (bus_clock & CONNINFRA_BUS_CLOCK_BPLL) { + + if (conninfra_bus_clock_bpll_state == 0) { + CONSYS_SET_BIT(CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_03, (0x1 << 21)); + udelay(30); + bpll_switch = true; + } + conninfra_bus_clock_bpll_state |= (0x1 << drv_type); + } + /* Enable WPLL */ + if (bus_clock & CONNINFRA_BUS_CLOCK_WPLL) { + if (conninfra_bus_clock_wpll_state == 0) { + CONSYS_SET_BIT(CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_03, (0x1 << 20)); + udelay(50); + wpll_switch = true; + } + conninfra_bus_clock_wpll_state |= (0x1 << drv_type); + } + pr_info("drv=[%d] conninfra_bus_clock_wpll=[%u]->[%u] %s conninfra_bus_clock_bpll=[%u]->[%u] %s", + drv_type, + wpll_state, conninfra_bus_clock_wpll_state, (wpll_switch ? "enable" : ""), + bpll_state, conninfra_bus_clock_bpll_state, (bpll_switch ? "enable" : "")); + } else { + /* Turn off */ + /* Turn off WPLL */ + if (bus_clock & CONNINFRA_BUS_CLOCK_WPLL) { + conninfra_bus_clock_wpll_state &= ~(0x1<[%u] %s conninfra_bus_clock_bpll=[%u]->[%u] %s", + drv_type, + wpll_state, conninfra_bus_clock_wpll_state, (wpll_switch ? "disable" : ""), + bpll_state, conninfra_bus_clock_bpll_state, (bpll_switch ? "disable" : "")); + if (consys_reg_mng_reg_readable() == 0) { + check = consys_reg_mng_is_bus_hang(); + pr_info("[%s] not readable, bus hang check=[%d]", __func__, check); + } + } + return 0; +} diff --git a/drivers/misc/mediatek/connectivity/conninfra/platform/mt6885/mt6885_consys_reg.c b/drivers/misc/mediatek/connectivity/conninfra/platform/mt6885/mt6885_consys_reg.c new file mode 100755 index 0000000000000000000000000000000000000000..573b9d6853cbf949e5b19ac868d3d3512feef5a1 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/platform/mt6885/mt6885_consys_reg.c @@ -0,0 +1,799 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#include +#include +#include +#include +#include +#include + +#include + +#include "consys_reg_mng.h" +#include "mt6885_consys_reg.h" +#include "mt6885_consys_reg_offset.h" +#include "consys_hw.h" +#include "consys_reg_util.h" + +#define LOG_TMP_BUF_SZ 256 +#define CONSYS_POWER_MODE_LEGACY "Legacy" +#define CONSYS_POWER_MODE_RC "RC" + +static int consys_reg_init(struct platform_device *pdev); +static int consys_reg_deinit(void); +static int consys_check_reg_readable(void); +static int consys_is_consys_reg(unsigned int addr); +static int consys_is_bus_hang(void); +static int consys_dump_bus_status(void); +static int consys_dump_conninfra_status(void); +static int consys_dump_cpupcr(enum conn_dump_cpupcr_type, int times, unsigned long interval_us); +static int consys_is_host_csr(unsigned long addr); + +struct consys_reg_mng_ops g_dev_consys_reg_ops = { + .consys_reg_mng_init = consys_reg_init, + .consys_reg_mng_deinit = consys_reg_deinit, + + .consys_reg_mng_check_reable = consys_check_reg_readable, + .consys_reg_mng_is_consys_reg = consys_is_consys_reg, + .consys_reg_mng_is_bus_hang = consys_is_bus_hang, + .consys_reg_mng_dump_bus_status = consys_dump_bus_status, + .consys_reg_mng_dump_conninfra_status = consys_dump_conninfra_status, + .consys_reg_mng_dump_cpupcr = consys_dump_cpupcr, + .consys_reg_mng_is_host_csr = consys_is_host_csr +}; + + +const char* consys_base_addr_index_to_str[CONSYS_BASE_ADDR_MAX] = { + "CONN_INFRA_RGU_BASE", + "CONN_INFRA_CFG_BASE", + "CONN_HOST_CSR_TOP_BASE", + "INFRACFG_AO_BASE", + "TOPRGU_BASE", + "SPM_BASE", + "INFRACFG_BASE", + "CONN_WT_SLP_CTL_REG", + "CONN_AFE_CTL_REG", + "CONN_INFRA_SYSRAM", + "GPIO", + "CONN_RF_SPI_MST_REG", + "CONN_SEMAPHORE", + "CONN_TOP_THERM_CTL", + "IOCFG_RT", +}; + +struct consys_base_addr conn_reg; + +struct consys_reg_mng_ops* get_consys_reg_mng_ops(void) +{ + return &g_dev_consys_reg_ops; +} + +struct consys_base_addr* get_conn_reg_base_addr() +{ + return &conn_reg; +} + +static void consys_bus_hang_dump_c(void) +{ + unsigned long debug_addr, out_addr; + unsigned long value; + int i; + unsigned long debug_setting[] = { + 0xf0001, 0xe0001, 0xd0001, 0xc0001, 0xb0001, 0xa0001, + 0x90001, 0x80001, 0x70001, 0x60001, 0x50001, 0x40001, + 0x30001, 0x20001, 0x10001, 0x30002, 0x20002, 0x10002, + 0x40003, 0x30003, 0x20003, 0x10003 + }; + + /* CONN2AP GALS RX status + * 0x1020_E804 + * + * CONNINFRA sleep protect + * 0x1000_6158[2] ap2conn gals rx slp prot + * 0x1000_6150[13] ap2conn gals tx slp prot + * + * conninfra on2off off2on slp prot + * 0x1806_0184[5] conn_infra on2off slp prot + * 0x1806_0184[3] conn_infra off2on slp prot + */ + pr_info("[CONN_BUS_C] [%x][%x][%x] [%x]", + CONSYS_REG_READ(CON_REG_INFRACFG_BASE_ADDR + INFRA_CONN2AP_GLAS_RC_ST), + CONSYS_REG_READ(CON_REG_SPM_BASE_ADDR + SPM_BUS_PROTECT2_RDY), + CONSYS_REG_READ(CON_REG_SPM_BASE_ADDR + SPM_BUS_PROTECT_RDY), + CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CONN_SLP_PROT_CTRL) + ); + + debug_addr = CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CONN_INFRA_DEBUG_AO_DEBUGSYS; + out_addr = CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CONN_INFRA_DEBUG_CTRL_AO2SYS_OUT; + + for (i = 0; i < ARRAY_SIZE(debug_setting); i++) { + CONSYS_REG_WRITE(debug_addr, debug_setting[i]); + value = CONSYS_REG_READ(out_addr); + pr_info("[CONN_BUS_C] addr=0x%x value=0x%08x", debug_setting[i], value); + } +} + +static void consys_bus_hang_dump_a_rc(void) +{ + unsigned int i; + char tmp[LOG_TMP_BUF_SZ] = {'\0'}; + char tmp_buf[LOG_TMP_BUF_SZ] = {'\0'}; + + for (i = 0xE50; i <= 0xE94; i += 4) { + if (snprintf(tmp, LOG_TMP_BUF_SZ, "[%x]", + CONSYS_REG_READ(CON_REG_SPM_BASE_ADDR + i)) >= 0) + strncat(tmp_buf, tmp, strlen(tmp)); + } + pr_info("[rc_trace] %s", tmp_buf); + + memset(tmp_buf, '\0', LOG_TMP_BUF_SZ); + for (i = 0xE98; i <= 0xED4; i += 4) { + if (snprintf(tmp, LOG_TMP_BUF_SZ, "[%x]", + CONSYS_REG_READ(CON_REG_SPM_BASE_ADDR + i)) >= 0) + strncat(tmp_buf, tmp, strlen(tmp)); + } + pr_info("[rc_timer] %s", tmp_buf); +} + +static void consys_bus_hang_dump_a(void) +{ + void __iomem *addr = NULL; + unsigned int r1, r2, r3, r4, r5, r6, r7 = 0, r8 = 0, r9 = 0, r10, r11; + char tmp_buf[LOG_TMP_BUF_SZ] = {'\0'}; + char rc_buf[LOG_TMP_BUF_SZ] = {'\0'}; + + /* + * r1 : 0x1000_6110 + * r2 : 0x1000_6114 + */ + if (snprintf(tmp_buf, LOG_TMP_BUF_SZ, "[%s] [0x%x][0x%x]", + (conn_hw_env.is_rc_mode ? CONSYS_POWER_MODE_RC : CONSYS_POWER_MODE_LEGACY), + CONSYS_REG_READ(CON_REG_SPM_BASE_ADDR + SPM_PCM_REG13_DATA), + CONSYS_REG_READ(CON_REG_SPM_BASE_ADDR + SPM_SRC_REQ_STA_0)) < 0) + pr_warn("[%s] sprintf error\n", __func__); + + /* RC REQ STA + * r3 : 0x1000_6E28 + * r4 : 0x1000_6E2C + * r5 : 0x1000_6E30 + * r6 : 0x1000_6E34 + */ + if (snprintf(rc_buf, LOG_TMP_BUF_SZ, "[%x][%x][%x][%x]", + CONSYS_REG_READ(CON_REG_SPM_BASE_ADDR + SPM_RC_RC_M04_REQ_STA_0), + CONSYS_REG_READ(CON_REG_SPM_BASE_ADDR + SPM_RC_RC_M05_REQ_STA_0), + CONSYS_REG_READ(CON_REG_SPM_BASE_ADDR + SPM_RC_RC_M06_REQ_STA_0), + CONSYS_REG_READ(CON_REG_SPM_BASE_ADDR + SPM_RC_RC_M07_REQ_STA_0)) < 0) + pr_warn("[%s] sprintf error\n", __func__); + + /* + * 0x1000684C [28] DEBUG_IDX_VTCXO_STATE + * 0x1000684C [29] DEBUG_IDX_INFRA_STATE + * 0x1000684C [30] DEBUG_IDX_VRF18_STATE + * 0x1000684C [31] DEBUG_IDX_APSRC_STATE + * r7: 0x1000684C + */ + r1 = CONSYS_REG_READ(CON_REG_SPM_BASE_ADDR + SPM_PCM_WDT_LATCH_SPARE_0); + + /* + * 0x10006100[0] sc_26m_ck_off 1'b0: 26M on; 1'b1 + * 0x10006100[3] sc_axi_ck_off 1'b0: bus ck on; 1'b1 bus ck off + * 0x10006100[5] sc_md26m_ck_off 1'b0: MD 26M on; 1'b1 MD 26M off + * 0x10006100[20] sc_cksq0_off 1'b0: clock square0 on; 1'b1 clock square off + * r8:0x10006100 + */ + r2 = CONSYS_REG_READ(CON_REG_SPM_BASE_ADDR + SPM_PCM_REG7_DATA); + + /* + * 0x1000_6304[2] : pwr_on + * 0x1000_616c[1] : pwr_ack + * 0x1000_6304[3] : pwr_on_s + * 0x1000_6170[1] : pwr_ack_s + * 0x1000_6304[1] : iso_en + * 0x1000_6304[0] : ap_sw_rst + * r9 : 0x1000_616C + * r10 : 0x1000_6170 + * r11 : 0x1000_6304 + */ + r3 = CONSYS_REG_READ(CON_REG_SPM_BASE_ADDR + SPM_PWR_STATUS); + r4 = CONSYS_REG_READ(CON_REG_SPM_BASE_ADDR + SPM_PWR_STATUS_2ND); + r5 = CONSYS_REG_READ(CON_REG_SPM_BASE_ADDR + SPM_CONN_PWR_CON); + + /* + * sc_md_32k_ck_off + * r12 : 0x1000_644C + */ + r6 = CONSYS_REG_READ(CON_REG_SPM_BASE_ADDR + SPM_PLL_CON); + + /* + * infra bus clock + * r13 : 0x1000_0000 pdn_conn_32k + * r14 : 0x1000_0010[2:0] + * 0: tck_26m_mx9_ck => 26M + * 1: mainpll_d4_d4 => 136.5M + * 2: mainpll_d7_d2 => 156M + * 3: mainpll_d4_d2 => 273M + * 4: mainpll_d5_d2 => 218.4M + * 5: mainpll_d6_d2 => 182M + * 6: osc_d4 => 65M + */ + addr = ioremap_nocache(0x10000000, 0x20); + if (addr != NULL) { + r7 = CONSYS_REG_READ(addr); + r8 = CONSYS_REG_READ(addr + 0x10); + iounmap(addr); + } + + /* + * r15 : 0x1000_0200 sc_md2_32k_off_en + */ + addr = ioremap_nocache(0x10000200, 0x20); + if (addr != NULL) { + r9 = CONSYS_REG_READ(addr); + iounmap(addr); + } + + /* ap2conn gals sleep protect status + * - 0x1000_1724 [2] / 0x1000_1228 [13] (infracfg_ao)(rx/tx) (sleep protect enable ready) + * r16 : 0x1000_1724 + * r17 : 0x1000_1228 + */ + r10 = CONSYS_REG_READ(CON_REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN2_STA1_OFFSET); + r11 = CONSYS_REG_READ(CON_REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN_STA1_OFFSET); + + pr_info("[CONN_BUS_A] %s %s [%x][%x][%x][%x][%x][%x] [%x][%x] [%x][%x][%x]", tmp_buf, + rc_buf, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11); + + consys_bus_hang_dump_a_rc(); +} + +static void consys_bus_hang_dump_b(void) +{ + char tmp_buf[LOG_TMP_BUF_SZ] = {'\0'}; + unsigned int r1, r2, r3, r4, r5, r6, r7; + + /* Legacy Mode */ + /* + * 0x180602c0 + * [4]: conn_srcclkena_ack + * [5]: conn_ap_bus_ack + * [6]: conn_apsrc_ack + * [7]: conn_ddr_en_ack + * cr1 : 0x1806_02c0 + */ + if (snprintf(tmp_buf, LOG_TMP_BUF_SZ, "[%s] [%x]", + (conn_hw_env.is_rc_mode ? CONSYS_POWER_MODE_RC : CONSYS_POWER_MODE_LEGACY), + CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_DBG_DUMMY_0)) < 0) + pr_warn("[%s] sprintf error\n", __func__); + + /* RC Mode */ + /* + * debug sel 0x18001B00[2:0] 3'b010 + * 0x1806_02C8 + * [12] conn_srcclkena_0_bblpm_ack + * [13] conn_srcclkena_0_fpm_ack + * [28] conn_srcclkena_1_bblpm_ack + * [29] conn_srcclkena_1_fpm_ack + * cr2 : 0x1806_02c8 + */ + r1 = CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_DBG_DUMMY_2); + + /* + * Consys status check + * debug sel 0x18001B00[2:0] 3'b010 + * 0x1806_02C8 + * [25] conninfra_bus_osc_en + * [24] conn_pta_osc_en + * [23] conn_thm_osc_en + * [22] ap2conn_osc_en + * [21] wfsys_osc_en + * [20] bgfsys_osc_en + * [19] gpssys_osc_en + * [18] fmsys_osc_en + */ + /*CONSYS_REG_WRITE_MASK(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_DBG_MUX_SEL, + 0x2, 0x7);*/ + /*r1 = CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_DBG_DUMMY_2);*/ + + /* Conninfra Off power state + * 0x1806_02CC + * [15] power_enable + * [14] power_on + * [13] pwer_ack + * [12] pwr_on_s + * [11] pwr_ack_s + * [10] iso_en + * [9] conn_infra_off_xreset_b + * [8] conn_infra_off_hreset_b + * + * cr3 : 0x1806_02CC + */ + r2 = CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_DBG_DUMMY_3); + + + /* conn_infra_on clock 0x1020E504[0] = 1’b1 + * + * cr4 : 0x1020_E504 + */ + r3 = CONSYS_REG_READ(CON_REG_INFRACFG_BASE_ADDR + + INFRA_AP2MD_GALS_CTL); + + /* Check conn_infra off bus clock + * - write 0x1 to 0x1806_0000[0], reset clock detect + * - 0x1806_0000[2] conn_infra off bus clock (should be 1'b1 if clock exist) + * - 0x1806_0000[1] osc clock (should be 1'b1 if clock exist) + * + * cr5 : 0x1806_0000 + */ + CONSYS_SET_BIT(CON_REG_HOST_CSR_ADDR, 0x1); + udelay(200); + r4 = CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR); + + /* conn_infra on2off sleep protect status + * - 0x1806_0184[5] (sleep protect enable ready), should be 1'b0 + * cr6 : 0x1806_0184 + */ + r5 = CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CONN_SLP_PROT_CTRL); + + /* CONN_HOST_CSR_DBG_DUMMY_4 + * cr7 : 0x1806_02D0 + */ + r6 = CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_DBG_DUMMY_4); + + /* 0x1806_02D4: dump bus timeout irq status + * cr8 : 0x1806_02D4 + */ + r7 = CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_BUS_TIMEOUT_IRQ); + + pr_info("[CONN_BUS_B] infra_off %s [%x][%x] [%x][%x][%x] [%x] [%x]" + , tmp_buf, r1, r2, r3, r4, r5, r6, r7); + pr_info("[CONN_BUS_B] 0x1806_0294:[0x%08x] 0x1806_0220:[0x%08x]\n", + CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + 0x0294), + CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + 0x0220)); +} + +#if 0 +static void consys_bus_hang_dump_d(void) +{ + int r1; + + /* check if consys off on + * 0x1806_02cc[8] 1'b1 ==> pwr on, 1'b0 ==> pwr off + */ + r1 = CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_DBG_DUMMY_3); + if (((r1 >> 8) & 0x01) == 0) { + pr_info("[CONN_BUS_D] conninfra off is not on"); + return; + } + + /* PLL & OSC status + * 0x18001810[1] bpll_rdy + * 0x18001810[0] wpll_rdy + * + * OSC + * 0x1800_180C + * [3] : bus_bpll_sw_rdy, 1'b1 conninfra bus clock=166.4M + * [2] : bus_bpll_sw_rdy, 1'b1 conninfra bus clock=83.2M + * [1] : bus_bpll_sw_rdy, 1'b1 conninfra bus clock=32M + * [0] : bus_bpll_sw_rdy, 1'b1 conninfra bus clock=osc + * + * 0x1800_1160[22] ap2conn gals rx slp prot + * 0x1800_1630[3] conn2ap gals tx slp prot + * 0x1800_1634[3] conn2ap gals rx slp prot + * + * 0x1800_1628[3] conn_infra on2off slp pro + * 0x1800_162c[3] conn_infra off2on slp pro + * + * 0x1800_161C[3] gps2conn gals tx slp prot + * 0x1800_161C[7] gps2conn gals rx slp prot + * 0x1800_1618[7] conn2gps gals rx slp prot + * 0x1800_1618[3] conn2gps gals tx slp prot + * + * 0x1800_1614[3] bt2conn gals tx slp prot + * 0x1800_1614[7] bt2conn gals rx slp prot + * 0x1800_1610[3] conn2bt gals tx slp prot + * 0x1800_1610[7] conn2bt gals rx slp prot + * + * 0x1800_1620[3] wf2conn slp prot + */ + pr_info("[CONN_BUS_D] [%x][%x] [%x][%x][%x] [%x][%x] [%x][%x] [%x][%x] [%x]", + CONSYS_REG_READ(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_PLL_STATUS), /* PLL */ + CONSYS_REG_READ(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_OSC_STATUS), /* OSC */ + + CONSYS_REG_READ(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_GALS_AP2CONN_GALS_DBG), + CONSYS_REG_READ(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_GALS_CONN2AP_TX_SLP_CTRL), + CONSYS_REG_READ(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_GALS_CONN2AP_RX_SLP_CTRL), + + CONSYS_REG_READ(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_ON_BUS_SLP_CTRL), /* on2off */ + CONSYS_REG_READ(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_OFF_BUS_SLP_CTRL),/* off2on */ + + CONSYS_REG_READ(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_GALS_GPS2CONN_SLP_CTRL), /* gps2conn */ + CONSYS_REG_READ(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_GALS_CONN2GPS_SLP_CTRL), /* conn2gps */ + + CONSYS_REG_READ(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_GALS_BT2CONN_SLP_CTRL), /* bt2conn */ + CONSYS_REG_READ(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_GALS_CONN2BT_SLP_CTRL), /* conn2bt */ + + CONSYS_REG_READ(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_WF_SLP_CTRL) /* w2conn */ + ); +} +#endif + +static int consys_dump_bus_status(void) +{ + consys_bus_hang_dump_c(); + return 0; +} + +static int consys_dump_conninfra_status(void) +{ + consys_bus_hang_dump_a(); + consys_bus_hang_dump_b(); + return 0; +} + +int consys_dump_cpupcr(enum conn_dump_cpupcr_type type, int times, unsigned long interval_us) +{ + int i; + + for (i = 0; i < times; i++) { + pr_info("%s: wm pc=0x%x, wm lp=0x%x, bt pc=0x%x", + __func__, + CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_WM_MCU_PC_DBG), + CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_WM_MCU_GPR_DBG), + CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_BGF_MCU_PC_DBG)); + if (interval_us > 1000) + usleep_range(interval_us - 100, interval_us + 100); + else + udelay(interval_us); + } + + return 0; +} + +static int consys_is_bus_hang(void) +{ + int r; + + /* dump SPM register */ + consys_bus_hang_dump_a(); + + /* STEP - 1 */ + /* + * check kernel API lastbus_timeout_dump + * if return > 0 -> return 0x1 + */ + + /* 1. Check ap2conn gals sleep protect status + * - 0x1000_1724 [2] / 0x1000_1228 [13] (infracfg_ao)(rx/tx) (sleep protect enable ready) + * both of them should be 1'b0 (CR at ap side) + */ + r = CONSYS_REG_READ_BIT(CON_REG_INFRACFG_AO_ADDR + + INFRA_TOPAXI_PROTECTEN2_STA1_OFFSET, (0x1 << 2)); + if (r != 0) + return CONNINFRA_AP2CONN_RX_SLP_PROT_ERR; + + r = CONSYS_REG_READ_BIT(CON_REG_INFRACFG_AO_ADDR + + INFRA_TOPAXI_PROTECTEN_STA1_OFFSET, (0x1 << 13)); + if (r != 0) + return CONNINFRA_AP2CONN_TX_SLP_PROT_ERR; + + /* 2. Check conn_infra_on clock 0x1020E504[0] = 1’b1 */ + r = CONSYS_REG_READ_BIT(CON_REG_INFRACFG_BASE_ADDR + + INFRA_AP2MD_GALS_CTL, 0x1); + if (r != 1) + return CONNINFRA_AP2CONN_CLK_ERR; + + /* STEP - 2 */ + consys_bus_hang_dump_b(); + +#if 0 + /* 3. Check conn_infra off bus clock + * - write 0x1 to 0x1806_0000[0], reset clock detect + * - 0x1806_0000[2] conn_infra off bus clock (should be 1'b1 if clock exist) + * - 0x1806_0000[1] osc clock (should be 1'b1 if clock exist) + */ + CONSYS_SET_BIT(CON_REG_HOST_CSR_ADDR, 0x1); + udelay(500); + r = CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR); + if ((r & TOP_BUS_MUC_STAT_HCLK_FR_CK_DETECT_BIT) == 0 || + (r & TOP_BUS_MUC_STAT_OSC_CLK_DETECT_BIT) == 0) + ret |= CONNINFRA_INFRA_BUS_CLK_ERR; +#endif + + /* 4. Check conn_infra off domain bus hang irq status + * - 0x1806_02d4[0], should be 1'b1, or means conn_infra off bus might hang + */ + r = CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_BUS_TIMEOUT_IRQ); + + if ((r & 0x1) != 0x1) { + pr_err("conninfra off bus might hang cirq=[0x%08x]", r); + consys_bus_hang_dump_c(); + return CONNINFRA_INFRA_BUS_HANG_IRQ; + } + consys_bus_hang_dump_c(); + +#if 0 + /* 5. Check conn_infra on2off sleep protect status + * - 0x1806_0184[5] (sleep protect enable ready), should be 1'b0 + */ + r = CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CONN_SLP_PROT_CTRL); + if (r & TOP_SLP_PROT_CTRL_CONN_INFRA_ON2OFF_SLP_PROT_ACK_BIT) + ret |= CONNINFRA_ON2OFF_SLP_PROT_ERR; + if (ret) { + pr_info("[%s] ret=[%x]", __func__, ret); + consys_bus_hang_dump_c(); + return ret; + } +#endif + /*consys_bus_hang_dump_d();*/ + + return 0; + +} + +int consys_check_reg_readable(void) +{ + int r; + unsigned int rnd; + int delay_time = 1, spent = delay_time, max_wait = 16000; // 1.6 ms + int retry = max_wait / 10; + + /* STEP - 1 */ + /* + * check kernel API lastbus_timeout_dump + * if return > 0 -> return 0x1 + */ + + + /* 1. Check ap2conn gals sleep protect status + * - 0x1000_1724 [2] / 0x1000_1228 [13] (infracfg_ao)(rx/tx) (sleep protect enable ready) + * both of them should be 1'b0 (CR at ap side) + */ + r = CONSYS_REG_READ_BIT(CON_REG_INFRACFG_AO_ADDR + + INFRA_TOPAXI_PROTECTEN2_STA1_OFFSET, (0x1 << 2)); + if (r != 0) + return 0; + + r = CONSYS_REG_READ_BIT(CON_REG_INFRACFG_AO_ADDR + + INFRA_TOPAXI_PROTECTEN_STA1_OFFSET, (0x1 << 13)); + if (r != 0) + return 0; + + /* STEP - 2 */ + + /* 2. Check conn_infra_on clock 0x1020E504[0] = 1’b1 */ + r = CONSYS_REG_READ_BIT(CON_REG_INFRACFG_BASE_ADDR + + INFRA_AP2MD_GALS_CTL, 0x1); + if (r != 1) + return 0; + + /* 3. Check conn_infra off bus clock + * - write 0x1 to 0x1806_0000[0], reset clock detect + * - 0x1806_0000[1] conn_infra off bus clock (should be 1'b1 if clock exist) + * - 0x1806_0000[2] osc clock (should be 1'b1 if clock exist) + */ + + while (retry > 0 && spent < max_wait) { + CONSYS_SET_BIT(CON_REG_HOST_CSR_ADDR, 0x1); + udelay(delay_time); + r = CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR); + if ((r & TOP_BUS_MUC_STAT_HCLK_FR_CK_DETECT_BIT) == 0 || + (r & TOP_BUS_MUC_STAT_OSC_CLK_DETECT_BIT) == 0) { + spent += delay_time; + retry--; + if (retry == 0) + pr_info("[%s] retry=0 r=[%x]", __func__, r); + else + delay_time = 10; + rnd = get_random_int() % 10; + spent += rnd; + udelay(rnd); + continue; + } + break; + } + if (retry == 0 || spent >= max_wait) { + pr_info("[%s] readable fail = bus clock retry=[%d] spent=[%d]", __func__, + retry, spent); + return 0; + } + + /* 4. Check conn_infra off domain bus hang irq status + * - 0x1806_02d4[0], should be 1'b1, or means conn_infra off bus might hang + */ + r = CONSYS_REG_READ_BIT(CON_REG_HOST_CSR_ADDR + + CONN_HOST_CSR_TOP_BUS_TIMEOUT_IRQ, 0x1); + if (r != 0x1) + return 0; + + /* 5. Check conn_infra on2off sleep protect status + * - 0x1806_0184[5] (sleep protect enable ready), should be 1'b0 + */ + r = CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CONN_SLP_PROT_CTRL); + if (r & TOP_SLP_PROT_CTRL_CONN_INFRA_ON2OFF_SLP_PROT_ACK_BIT) + return 0; + + return 1; +} + + +int consys_is_consys_reg(unsigned int addr) +{ + return 0; +} + + +static int consys_is_host_csr(unsigned long addr) +{ + struct consys_reg_base_addr *host_csr_addr = + &conn_reg.reg_base_addr[CONN_HOST_CSR_TOP_BASE_INDEX]; + + if (addr >= host_csr_addr->phy_addr && + addr < host_csr_addr->phy_addr + host_csr_addr->size) + return 1; + return 0; +} + +unsigned long consys_reg_validate_idx_n_offset(unsigned int idx, unsigned long offset) +{ + unsigned long res; + + if (idx < 0 || idx >= CONSYS_BASE_ADDR_MAX) { + pr_warn("ConsysReg failed: No support the base %d\n", idx); + return 0; + } + + res = conn_reg.reg_base_addr[idx].phy_addr; + + if (res == 0) { + pr_warn("ConsysReg failed: No support the base idx is 0 index=[%d]\n", idx); + return 0; + } + + if (offset >= conn_reg.reg_base_addr[idx].size) { + pr_warn("ConnReg failed: index(%d), offset(%d) over max size(%llu) %s\n", + idx, (int) offset, conn_reg.reg_base_addr[idx].size); + return 0; + } + return res; +} + +int consys_find_can_write_reg(unsigned int *idx, unsigned long *offset) +{ + int i; + size_t addr = 0, addr_offset; + int max, mask = 0x0000000F; + int before, after, ret; + + addr = conn_reg.reg_base_addr[CONN_INFRA_RGU_BASE_INDEX].vir_addr; + max = conn_reg.reg_base_addr[CONN_INFRA_RGU_BASE_INDEX].size; + + pr_info("[%s] addr=[%p]\n", __func__, addr); + + for (i = 0x0; i < max; i += 0x4) { + ret = 0; + addr_offset = addr + i; + before = CONSYS_REG_READ(addr_offset); + CONSYS_REG_WRITE_MASK(addr_offset, 0xFFFFFFFF, mask); + after = CONSYS_REG_READ(addr_offset); + if ((after & mask) != (0xFFFFFFFF & mask)) + ret = -1; + + CONSYS_REG_WRITE_MASK(addr_offset, 0x0, mask); + after = CONSYS_REG_READ(addr_offset); + if ((after & mask) != (0x0 & mask)) + ret = -1; + + CONSYS_REG_WRITE_MASK(addr_offset, before, mask); + + pr_info("[%s] addr=[%p] [%d]\n", __func__, addr_offset, ret); + if (ret == 0) { + *idx = CONN_INFRA_RGU_BASE_INDEX; + *offset = i; + return 0; + } + } + return -1; + +} + + +unsigned long consys_reg_get_phy_addr_by_idx(unsigned int idx) +{ + if (idx >= CONSYS_BASE_ADDR_MAX) + return 0; + return conn_reg.reg_base_addr[idx].phy_addr; +} + +unsigned long consys_reg_get_virt_addr_by_idx(unsigned int idx) +{ + if (idx >= CONSYS_BASE_ADDR_MAX) + return 0; + return conn_reg.reg_base_addr[idx].vir_addr; +} + + +int consys_reg_get_chip_id_idx_offset(unsigned int *idx, unsigned long *offset) +{ + *idx = CONN_INFRA_CFG_BASE_INDEX; + *offset = CONN_CFG_ID_OFFSET; + return 0; +} + +int consys_reg_get_reg_symbol_num(void) +{ + return CONSYS_BASE_ADDR_MAX; +} + + +int consys_reg_init(struct platform_device *pdev) +{ + int ret = -1; + struct device_node *node = NULL; + struct consys_reg_base_addr *base_addr = NULL; + struct resource res; + int flag, i = 0; + + node = pdev->dev.of_node; + pr_info("[%s] node=[%p]\n", __func__, node); + if (node) { + for (i = 0; i < CONSYS_BASE_ADDR_MAX; i++) { + base_addr = &conn_reg.reg_base_addr[i]; + + ret = of_address_to_resource(node, i, &res); + if (ret) { + pr_err("Get Reg Index(%d-%s) failed", + i, consys_base_addr_index_to_str[i]); + continue; + } + + base_addr->phy_addr = res.start; + base_addr->vir_addr = + (unsigned long) of_iomap(node, i); + of_get_address(node, i, &(base_addr->size), &flag); + + pr_info("Get Index(%d-%s) phy(0x%zx) baseAddr=(0x%zx) size=(0x%zx)", + i, consys_base_addr_index_to_str[i], base_addr->phy_addr, + base_addr->vir_addr, base_addr->size); + } + + } else { + pr_err("[%s] can't find CONSYS compatible node\n", __func__); + return ret; + } + return 0; + +} + +static int consys_reg_deinit(void) +{ + int i = 0; + + for (i = 0; i < CONSYS_BASE_ADDR_MAX; i++) { + if (conn_reg.reg_base_addr[i].vir_addr) { + pr_info("[%d] Unmap %s (0x%zx)", + i, consys_base_addr_index_to_str[i], + conn_reg.reg_base_addr[i].vir_addr); + iounmap((void __iomem*)conn_reg.reg_base_addr[i].vir_addr); + conn_reg.reg_base_addr[i].vir_addr = 0; + } + } + + return 0; +} + diff --git a/drivers/misc/mediatek/connectivity/conninfra/platform/mt6885/mt6885_emi.c b/drivers/misc/mediatek/connectivity/conninfra/platform/mt6885/mt6885_emi.c new file mode 100755 index 0000000000000000000000000000000000000000..057ecec2c26b123beb97964e87ce2b7a4823fcbf --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/platform/mt6885/mt6885_emi.c @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#define pr_fmt(fmt) KBUILD_MODNAME "@(%s:%d) " fmt, __func__, __LINE__ + +#include +#include +#ifdef CONFIG_MTK_EMI +#include +#endif +#include + +#include +#include "mt6885_emi.h" +#include "mt6885.h" +#include "mt6885_consys_reg.h" +#include "consys_hw.h" +#include "consys_reg_util.h" +#include "mt6885_pos.h" + +/* For MCIF */ +#include + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +#define REGION_CONN 27 + +#define DOMAIN_AP 0 +#define DOMAIN_CONN 2 + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +extern unsigned long long gConEmiSize; +extern phys_addr_t gConEmiPhyBase; + +struct consys_platform_emi_ops g_consys_platform_emi_ops = { + .consys_ic_emi_mpu_set_region_protection = consys_emi_mpu_set_region_protection, + .consys_ic_emi_set_remapping_reg = consys_emi_set_remapping_reg, + .consys_ic_emi_get_md_shared_emi = consys_emi_get_md_shared_emi, +}; + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +struct consys_platform_emi_ops* get_consys_platform_emi_ops(void) +{ + return &g_consys_platform_emi_ops; +} + +int consys_emi_mpu_set_region_protection(void) +{ + struct emimpu_region_t region; + unsigned long long start = gConEmiPhyBase; + unsigned long long end = gConEmiPhyBase + gConEmiSize - 1; + + mtk_emimpu_init_region(®ion, REGION_CONN); + mtk_emimpu_set_addr(®ion, start, end); + mtk_emimpu_set_apc(®ion, DOMAIN_AP, MTK_EMIMPU_NO_PROTECTION); + mtk_emimpu_set_apc(®ion, DOMAIN_CONN, MTK_EMIMPU_NO_PROTECTION); + mtk_emimpu_set_protection(®ion); + mtk_emimpu_free_region(®ion); + + pr_info("setting MPU for EMI share memory\n"); + return 0; +} + +void consys_emi_get_md_shared_emi(phys_addr_t* base, unsigned int* size) +{ + phys_addr_t mdPhy = 0; + int ret = 0; + +#ifdef CONFIG_MTK_ECCCI_DRIVER + mdPhy = get_smem_phy_start_addr(MD_SYS1, SMEM_USER_RAW_MD_CONSYS, &ret); +#else + pr_info("[%s] ECCCI Driver is not supported.\n", __func__); +#endif + if (ret && mdPhy) { + pr_info("MCIF base=0x%llx size=0x%x", mdPhy, ret); + if (base) + *base = mdPhy; + if (size) + *size = ret; + } else { + pr_info("MCIF is not supported"); + if (base) + *base = 0; + if (size) + *size = 0; + } +} + diff --git a/drivers/misc/mediatek/connectivity/conninfra/platform/mt6885/mt6885_pmic.c b/drivers/misc/mediatek/connectivity/conninfra/platform/mt6885/mt6885_pmic.c new file mode 100755 index 0000000000000000000000000000000000000000..36e3e21ff17a591560deafa5e5edcdb8332d783d --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/platform/mt6885/mt6885_pmic.c @@ -0,0 +1,448 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#define pr_fmt(fmt) KBUILD_MODNAME "@(%s:%d) " fmt, __func__, __LINE__ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "consys_hw.h" +#include "consys_reg_util.h" +#include "osal.h" +#include "mt6885.h" +#include "mt6885_pmic.h" +#include "mt6885_pos.h" +#include "mt6885_consys_reg.h" +#include "mt6885_consys_reg_offset.h" + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +static int consys_plt_pmic_get_from_dts(struct platform_device *pdev, struct conninfra_dev_cb* dev_cb); + +static int consys_plt_pmic_common_power_ctrl(unsigned int enable); +static int consys_plt_pmic_wifi_power_ctrl(unsigned int enable); +static int consys_plt_pmic_bt_power_ctrl(unsigned int enable); +static int consys_plt_pmic_gps_power_ctrl(unsigned int enable); +static int consys_plt_pmic_fm_power_ctrl(unsigned int enable); +/* VCN33_1 is enable when BT or Wi-Fi is on */ +static int consys_pmic_vcn33_1_power_ctl(bool enable, struct regulator* reg_VCN33_1); +/* VCN33_2 is enable when Wi-Fi is on */ +static int consys_pmic_vcn33_2_power_ctl(bool enable); + +static int consys_plt_pmic_event_notifier(unsigned int id, unsigned int event); + +static int consys_plt_pmic_exit_idle_power_ctrl(void); +static int consys_plt_pmic_enter_idle_power_ctrl(void); + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +CONSYS_PLATFORM_PMIC_OPS g_consys_platform_pmic_ops = { + .consys_pmic_get_from_dts = consys_plt_pmic_get_from_dts, + /* vcn 18 */ + .consys_pmic_common_power_ctrl = consys_plt_pmic_common_power_ctrl, + .consys_pmic_wifi_power_ctrl = consys_plt_pmic_wifi_power_ctrl, + .consys_pmic_bt_power_ctrl = consys_plt_pmic_bt_power_ctrl, + .consys_pmic_gps_power_ctrl = consys_plt_pmic_gps_power_ctrl, + .consys_pmic_fm_power_ctrl = consys_plt_pmic_fm_power_ctrl, + .consys_pmic_event_notifier = consys_plt_pmic_event_notifier, +}; + +struct regulator *reg_VCN13; +struct regulator *reg_VCN18; +struct regulator *reg_VCN33_1_BT; +struct regulator *reg_VCN33_1_WIFI; +struct regulator *reg_VCN33_2_WIFI; +struct notifier_block vcn13_nb; + +static struct conninfra_dev_cb* g_dev_cb; +static int g_first_power_on = 0; + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +P_CONSYS_PLATFORM_PMIC_OPS get_consys_platform_pmic_ops(void) +{ + return &g_consys_platform_pmic_ops; +} + + +static int consys_vcn13_oc_notify(struct notifier_block *nb, unsigned long event, + void *unused) +{ + if (event != REGULATOR_EVENT_OVER_CURRENT) + return NOTIFY_OK; + + if (g_dev_cb != NULL && g_dev_cb->conninfra_pmic_event_notifier != NULL) + g_dev_cb->conninfra_pmic_event_notifier(0, 0); + return NOTIFY_OK; +} + +static int consys_plt_pmic_event_notifier(unsigned int id, unsigned int event) +{ + static int oc_counter = 0; + + oc_counter++; + pr_info("[%s] VCN13 OC times: %d\n", __func__, oc_counter); + + consys_plt_pmic_ctrl_dump("VCN13 OC"); + return NOTIFY_OK; +} + +int consys_plt_pmic_ctrl_dump(const char* tag) +{ +#define ATOP_DUMP_NUM 10 +#define LOG_TMP_BUF_SZ 256 + int ret; + unsigned int adie_value = 0; + unsigned int value1 = 0, value2 = 0, value3 = 0; + const unsigned int adie_cr_list[ATOP_DUMP_NUM] = { + 0xa10, 0x90, 0x94, 0xa0, + 0xa18, 0xa1c, 0xc8, 0x3c, + 0x0b4, 0x34c + }; + int index; + char tmp[LOG_TMP_BUF_SZ] = {'\0'}; + char tmp_buf[LOG_TMP_BUF_SZ] = {'\0'}; + + consys_hw_is_bus_hang(); + ret = consys_hw_force_conninfra_wakeup(); + if (ret) { + pr_info("[%s] force conninfra wakeup fail\n", __func__); + return 0; + } + + value1 = CONSYS_REG_READ(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_ADIE_CTL); + value2 = CONSYS_REG_READ(CON_REG_WT_SPL_CTL_ADDR + 0xa8); + if (consys_sema_acquire_timeout(CONN_SEMA_CONN_INFRA_COMMON_SYSRAM_INDEX, CONN_SEMA_TIMEOUT) == CONN_SEMA_GET_SUCCESS) { + value3 = CONSYS_REG_READ(CONN_INFRA_SYSRAM_BASE_ADDR + CONN_INFRA_SYSRAM_SW_CR_A_DIE_TOP_CK_EN_CTRL); + consys_sema_release(CONN_SEMA_CONN_INFRA_COMMON_SYSRAM_INDEX); + pr_info("[%s] D-die: 0x1800_1900:0x%08x 0x1800_50A8:0x%08x 0x1805_2830:0x%08x\n", + (tag == NULL?__func__:tag), value1, value2, value3); + } else { + pr_info("[%s] D-die: 0x1800_1900:0x%08x 0x1800_50A8:0x%08x\n", + (tag == NULL?__func__:tag), value1, value2); + } + + for (index = 0; index < ATOP_DUMP_NUM; index++) { + consys_spi_read(SYS_SPI_TOP, adie_cr_list[index], &adie_value); + if (snprintf(tmp, LOG_TMP_BUF_SZ, " [0x%04x: 0x%08x]", adie_cr_list[index], adie_value) >= 0) + strncat(tmp_buf, tmp, strlen(tmp)); + } + pr_info("[%s] ATOP:%s\n", (tag == NULL?__func__:tag), tmp_buf); + consys_hw_force_conninfra_sleep(); + + return 0; +} + +int consys_plt_pmic_get_from_dts(struct platform_device *pdev, struct conninfra_dev_cb* dev_cb) +{ + int ret; + + g_dev_cb = dev_cb; +//#if CONSYS_PMIC_CTRL_ENABLE + reg_VCN13 = devm_regulator_get_optional(&pdev->dev, "vcn13"); + if (!reg_VCN13) + pr_err("Regulator_get VCN_13 fail\n"); + else { + vcn13_nb.notifier_call = consys_vcn13_oc_notify; + ret = devm_regulator_register_notifier(reg_VCN13, &vcn13_nb); + if (ret) { + pr_info("VCN13 regulator notifier request failed\n"); + } + /* Set VS2 to 1.4625V */ + KERNEL_pmic_set_register_value(PMIC_RG_BUCK_VS2_VOSEL, 0x35); + } + reg_VCN18 = regulator_get(&pdev->dev, "vcn18"); + if (!reg_VCN18) + pr_err("Regulator_get VCN_18 fail\n"); + reg_VCN33_1_BT = regulator_get(&pdev->dev, "vcn33_1_bt"); + if (!reg_VCN33_1_BT) + pr_err("Regulator_get VCN33_1_BT fail\n"); + reg_VCN33_1_WIFI = regulator_get(&pdev->dev, "vcn33_1_wifi"); + if (!reg_VCN33_1_WIFI) + pr_err("Regulator_get VCN33_1_WIFI fail\n"); + reg_VCN33_2_WIFI = regulator_get(&pdev->dev, "vcn33_2_wifi"); + if (!reg_VCN33_2_WIFI) + pr_err("Regulator_get VCN33_WIFI fail\n"); +//#endif + return 0; +} + +int consys_pmic_vcn33_1_power_ctl(bool enable, struct regulator *reg_VCN33_1) +{ + int ret; + if (enable) { + if (consys_is_rc_mode_enable()) { + /* PMRC_EN[6][5] HW_OP_EN = 1, HW_OP_CFG = 0 */ + KERNEL_pmic_ldo_vcn33_1_lp(SRCLKEN6, 0, 1, HW_OFF); + KERNEL_pmic_ldo_vcn33_1_lp(SRCLKEN5, 0, 1, HW_OFF); + /* SW_LP =0 */ + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_1_LP, 0); + regulator_set_voltage(reg_VCN33_1, 3300000, 3300000); + /* SW_EN=0 */ + /* For RC mode, we don't have to control VCN33_1 & VCN33_2 */ + #if 0 + /* regulator_disable(reg_VCN33_1); */ + #endif + } else { + /* HW_OP_EN = 1, HW_OP_CFG = 0 */ + KERNEL_pmic_ldo_vcn33_1_lp(SRCLKEN0, 1, 1, HW_OFF); + /* SW_LP =0 */ + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_1_LP, 0); + regulator_set_voltage(reg_VCN33_1, 3300000, 3300000); + /* SW_EN=1 */ + ret = regulator_enable(reg_VCN33_1); + if (ret) + pr_err("Enable VCN33_1 fail. ret=%d\n", ret); + } + } else { + if (consys_is_rc_mode_enable()) { + /* Do nothing */ + } else { + regulator_disable(reg_VCN33_1); + } + } + return 0; +} + +int consys_pmic_vcn33_2_power_ctl(bool enable) +{ + int ret; + + if (enable) { + if (consys_is_rc_mode_enable()) { + /* PMRC_EN[6] HW_OP_EN = 1, HW_OP_CFG = 0 */ + KERNEL_pmic_ldo_vcn33_2_lp(SRCLKEN6, 0, 1, HW_OFF); + /* SW_LP =0 */ + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_2_LP, 0); + regulator_set_voltage(reg_VCN33_2_WIFI, 3300000, 3300000); + /* SW_EN=0 */ + /* For RC mode, we don't have to control VCN33_1 & VCN33_2 */ + #if 0 + regulator_disable(reg_VCN33_2_WIFI); + #endif + } else { + /* HW_OP_EN = 1, HW_OP_CFG = 0 */ + KERNEL_pmic_ldo_vcn33_2_lp(SRCLKEN0, 1, 1, HW_OFF); + /* SW_LP =0 */ + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_2_LP, 0); + regulator_set_voltage(reg_VCN33_2_WIFI, 3300000, 3300000); + /* SW_EN=1 */ + ret = regulator_enable(reg_VCN33_2_WIFI); + if (ret) + pr_err("Enable VCN33_2 fail. ret=%d\n", ret); + } + } else { + if (consys_is_rc_mode_enable()) { + /* Do nothing */ + } else { + regulator_disable(reg_VCN33_2_WIFI); + } + } + return 0; +} + +int consys_plt_pmic_common_power_ctrl(unsigned int enable) +{ + int ret; + + if (enable) { + if (consys_is_rc_mode_enable()) { + /* RC mode */ + /* VCN18 */ + /* PMRC_EN[7][6][5][4] HW_OP_EN = 1, HW_OP_CFG = 0 */ + KERNEL_pmic_ldo_vcn18_lp(SRCLKEN7, 0, 1, HW_OFF); + KERNEL_pmic_ldo_vcn18_lp(SRCLKEN6, 0, 1, HW_OFF); + KERNEL_pmic_ldo_vcn18_lp(SRCLKEN5, 0, 1, HW_OFF); + KERNEL_pmic_ldo_vcn18_lp(SRCLKEN4, 0, 1, HW_OFF); + /* SW_LP =1 */ + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN18_LP, 0); + regulator_set_voltage(reg_VCN18, 1800000, 1800000); + ret = regulator_enable(reg_VCN18); + if (ret) + pr_err("Enable VCN18 fail. ret=%d\n", ret); + + /* VCN13 */ + /* PMRC_EN[7][6][5][4] HW_OP_EN = 1, HW_OP_CFG = 0 */ + KERNEL_pmic_ldo_vcn13_lp(SRCLKEN7, 0, 1, HW_OFF); + KERNEL_pmic_ldo_vcn13_lp(SRCLKEN6, 0, 1, HW_OFF); + KERNEL_pmic_ldo_vcn13_lp(SRCLKEN5, 0, 1, HW_OFF); + KERNEL_pmic_ldo_vcn13_lp(SRCLKEN4, 0, 1, HW_OFF); + /* SW_LP =1 */ + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN13_LP, 0); + regulator_set_voltage(reg_VCN13, 1300000, 1300000); + ret = regulator_enable(reg_VCN13); + if (ret) + pr_err("Enable VCN13 fail. ret=%d\n", ret); + + g_first_power_on = 1; + } else { + /* Legacy mode */ + /* HW_OP_EN = 1, HW_OP_CFG = 1 */ + KERNEL_pmic_ldo_vcn18_lp(SRCLKEN0, 1, 1, HW_LP); + /* SW_LP=0 */ + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN18_LP, 0); + regulator_set_voltage(reg_VCN18, 1800000, 1800000); + /* SW_EN=1 */ + ret = regulator_enable(reg_VCN18); + if (ret) + pr_err("Enable VCN18 fail. ret=%d\n", ret); + + /* HW_OP_EN = 1, HW_OP_CFG = 1 */ + KERNEL_pmic_ldo_vcn13_lp(SRCLKEN0, 1, 1, HW_LP); + regulator_set_voltage(reg_VCN13, 1300000, 1300000); + /* SW_LP=0 */ + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN13_LP, 0); + /* SW_EN=1 */ + ret = regulator_enable(reg_VCN13); + if (ret) + pr_err("Enable VCN13 fail. ret=%d\n", ret); + } + } else { + regulator_disable(reg_VCN13); + regulator_disable(reg_VCN18); + } + return 0; +} + +int consys_plt_pmic_wifi_power_ctrl(unsigned int enable) +{ + int ret; + + if (enable) + consys_plt_pmic_enter_idle_power_ctrl(); + + ret = consys_pmic_vcn33_1_power_ctl(enable, reg_VCN33_1_WIFI); + if (ret) + pr_err("%s VCN33_1 fail\n", (enable? "Enable" : "Disable")); + ret = consys_pmic_vcn33_2_power_ctl(enable); + if (ret) + pr_err("%s VCN33_2 fail\n", (enable? "Enable" : "Disable")); + return ret; +} + +int consys_plt_pmic_bt_power_ctrl(unsigned int enable) +{ + if (enable) { + consys_plt_pmic_exit_idle_power_ctrl(); + udelay(50); + + /* request VS2 to 1.4V by VS2 VOTER (use bit 4) */ + KERNEL_pmic_set_register_value(PMIC_RG_BUCK_VS2_VOTER_EN_SET, 0x10); + + /* Set VS2 sleep voltage to 1.375V */ + KERNEL_pmic_set_register_value(PMIC_RG_BUCK_VS2_VOSEL_SLEEP, 0x2E); + /* Set VCN13 to 1.37V */ + KERNEL_pmic_set_register_value(PMIC_RG_VCN13_VOCAL, 0x7); + udelay(50); + consys_plt_pmic_enter_idle_power_ctrl(); + } else { + consys_plt_pmic_exit_idle_power_ctrl(); + udelay(50); + /* restore VCN13 to 1.3V */ + KERNEL_pmic_set_register_value(PMIC_RG_VCN13_VOCAL, 0); + /* Restore VS2 sleep voltage to 1.35V */ + KERNEL_pmic_set_register_value(PMIC_RG_BUCK_VS2_VOSEL_SLEEP, 0x2C); + + /* clear bit 4 of VS2 VOTER then VS2 can restore to 1.35V */ + KERNEL_pmic_set_register_value(PMIC_RG_BUCK_VS2_VOTER_EN_CLR, 0x10); + udelay(50); + consys_plt_pmic_enter_idle_power_ctrl(); + } + return consys_pmic_vcn33_1_power_ctl(enable, reg_VCN33_1_BT); +} + +int consys_plt_pmic_gps_power_ctrl(unsigned int enable) +{ + if (enable) + consys_plt_pmic_enter_idle_power_ctrl(); + return 0; +} + +int consys_plt_pmic_fm_power_ctrl(unsigned int enable) +{ + if (enable) + consys_plt_pmic_enter_idle_power_ctrl(); + return 0; +} + +int consys_plt_pmic_exit_idle_power_ctrl(void) +{ + if (consys_is_rc_mode_enable() && g_first_power_on == 0) { + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN18_LP, 0); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN13_LP, 0); + g_first_power_on = 1; + } + return 0; +} + +int consys_plt_pmic_enter_idle_power_ctrl(void) +{ + if (consys_is_rc_mode_enable() && g_first_power_on == 1) { + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN18_LP, 1); + KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN13_LP, 1); + g_first_power_on = 0; + } + return 0; +} + diff --git a/drivers/misc/mediatek/connectivity/conninfra/platform/mt6885/mt6885_pos.c b/drivers/misc/mediatek/connectivity/conninfra/platform/mt6885/mt6885_pos.c new file mode 100755 index 0000000000000000000000000000000000000000..ba5a83d847ba00ab6fc0f745bcd6f62267f26e2e --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/platform/mt6885/mt6885_pos.c @@ -0,0 +1,2339 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include "consys_hw.h" /* for semaphore index */ +/* platform dependent */ +#include "plat_def.h" +/* macro for read/write cr */ +#include "consys_reg_util.h" +#include "consys_reg_mng.h" +/* cr base address */ +#include "mt6885_consys_reg.h" +/* cr offset */ +#include "mt6885_consys_reg_offset.h" +/* For function declaration */ +#include "mt6885_pos.h" +#include "mt6885.h" +#include "mt6885_pmic.h" + +#include + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +#define CONN_INFRA_SYSRAM__A_DIE_DIG_TOP_CK_EN_MASK 0x7f + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ +struct a_die_reg_config { + unsigned int reg; + unsigned int mask; + unsigned int config; +}; + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ +const static char* gAdieCtrlType[CONNSYS_ADIE_CTL_MAX] = +{ + "CONNSYS_ADIE_CTL_HOST_BT", + "CONNSYS_ADIE_CTL_HOST_FM", + "CONNSYS_ADIE_CTL_HOST_GPS", + "CONNSYS_ADIE_CTL_HOST_WIFI", + "CONNSYS_ADIE_CTL_HOST_CONNINFRA", + "CONNSYS_ADIE_CTL_FW_BT", + "CONNSYS_ADIE_CTL_FW_WIFI", +}; + +const static char* g_spi_system_name[SYS_SPI_MAX] = { + "SYS_SPI_WF1", + "SYS_SPI_WF", + "SYS_SPI_BT", + "SYS_SPI_FM", + "SYS_SPI_GPS", + "SYS_SPI_TOP", + "SYS_SPI_WF2", + "SYS_SPI_WF3", +}; + +const char* g_pos_unknown_str = "unknown"; + +#define ADIE_CONFIG_NUM 2 + +// E1 WF/GPS/FM on(default) +const static struct a_die_reg_config adie_e1_default[ADIE_CONFIG_NUM] = +{ + {ATOP_RG_TOP_XTAL_01, 0xc180, 0xc180}, + {ATOP_RG_TOP_XTAL_02, 0xf0ff0080, 0xd0550080}, +}; + +const static struct a_die_reg_config adie_e1_bt_only[ADIE_CONFIG_NUM] = +{ + {ATOP_RG_TOP_XTAL_01, 0xc180, 0x100}, + {ATOP_RG_TOP_XTAL_02, 0xf0ff0080, 0xf0ff0000}, +}; + +const static struct a_die_reg_config adie_e2_default[ADIE_CONFIG_NUM] = +{ + {ATOP_RG_TOP_XTAL_01, 0xc180, 0xc180}, + {ATOP_RG_TOP_XTAL_02, 0xf0ff0080, 0x50550080}, +}; + +const static struct a_die_reg_config adie_e2_bt_only[ADIE_CONFIG_NUM] = +{ + {ATOP_RG_TOP_XTAL_01, 0xc180, 0x100}, + {ATOP_RG_TOP_XTAL_02, 0xf0ff0080, 0x70ff0000}, +}; + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +static int consys_spi_read_nolock(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int *data); +static int consys_spi_write_nolock(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int data); +static void consys_spi_write_offset_range_nolock( + enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int value, + unsigned int reg_offset, unsigned int value_offset, unsigned int size); +static int connsys_a_die_thermal_cal(int efuse_valid, unsigned int efuse); + +const char* get_adie_ctrl_type_str(enum consys_adie_ctl_type type) +{ + if (type >= CONNSYS_ADIE_CTL_HOST_BT && type < CONNSYS_ADIE_CTL_MAX) + return gAdieCtrlType[type]; + return g_pos_unknown_str; +} + +const char* get_spi_sys_name(enum sys_spi_subsystem subsystem) +{ + if (subsystem >= SYS_SPI_WF1 && subsystem < SYS_SPI_MAX) + return g_spi_system_name[subsystem]; + return g_pos_unknown_str; +} + + +unsigned int consys_emi_set_remapping_reg( + phys_addr_t con_emi_base_addr, + phys_addr_t md_shared_emi_base_addr) +{ + /* EMI Registers remapping */ + CONSYS_REG_WRITE_OFFSET_RANGE(CON_REG_HOST_CSR_ADDR + CONN2AP_REMAP_MCU_EMI_BASE_ADDR_OFFSET, + con_emi_base_addr, 0, 16, 20); + + CONSYS_REG_WRITE_MASK( + CON_REG_HOST_CSR_ADDR + CONN2AP_REMAP_WF_PERI_BASE_ADDR_OFFSET, + 0x01000, 0xFFFFF); + CONSYS_REG_WRITE_MASK( + CON_REG_HOST_CSR_ADDR + CONN2AP_REMAP_BT_PERI_BASE_ADDR_OFFSET, + 0x01000, 0xFFFFF); + CONSYS_REG_WRITE_MASK( + CON_REG_HOST_CSR_ADDR + CONN2AP_REMAP_GPS_PERI_BASE_ADDR_OFFSET, + 0x01000, 0xFFFFF); + + if (md_shared_emi_base_addr) { + CONSYS_REG_WRITE_OFFSET_RANGE( + CON_REG_HOST_CSR_ADDR + CONN2AP_REMAP_MD_SHARE_EMI_BASE_ADDR_OFFSET, + md_shared_emi_base_addr, 0, 16, 20); + } + pr_info("connsys_emi_base=[0x%llx] mcif_emi_base=[0x%llx] remap cr: connsys=[0x%08x] mcif=[0x%08x]\n", + con_emi_base_addr, md_shared_emi_base_addr, + CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN2AP_REMAP_MCU_EMI_BASE_ADDR_OFFSET), + CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN2AP_REMAP_MD_SHARE_EMI_BASE_ADDR_OFFSET)); + return 0; +} + +int consys_conninfra_on_power_ctrl(unsigned int enable) +{ + int check; + if (enable) { +#ifndef CONFIG_FPGA_EARLY_PORTING + /* Turn on SPM clock (apply this for SPM's CONNSYS power control related CR accessing) + * address: 0x1000_6000[0] + * 0x1000_6000[31:16] + * Data: [0]=1'b1 + * [31:16]=16'h0b16 (key) + * Action: write + */ + CONSYS_REG_WRITE_MASK( + CON_REG_SPM_BASE_ADDR + SPM_POWERON_CONFIG_EN, 0x0b160001, 0xffff0001); +#endif + + /* Turn on ap2conn host_ck CG (ECO) + * Address: INFRA_AP2MD_GALS_CTL[0] (0x1020E504[0]) + * Value: 1'b1 + * Action: write + */ + CONSYS_SET_BIT(CON_REG_INFRACFG_BASE_ADDR + INFRA_AP2MD_GALS_CTL, 0x1); + +#if MTK_CONNINFRA_CLOCK_BUFFER_API_AVAILABLE + check = consys_platform_spm_conn_ctrl(enable); + if (check) { + pr_err("Turn on conn_infra power fail\n"); + return -1; + } +#else + pr_info("Turn on conn_infra power by POS steps\n"); + /* Assert "conn_infra_on" primary part power on, set "connsys_on_domain_pwr_on"=1 + * Address: 0x1000_6304[2] + * Data: 1'b1 + * Action: write + */ + CONSYS_SET_BIT(CON_REG_SPM_BASE_ADDR + SPM_CONN_PWR_CON, 0x4); + +#ifndef CONFIG_FPGA_EARLY_PORTING + /* Check "conn_infra_on" primary part power status, check "connsys_on_domain_pwr_ack"=1 + * (polling "10 times" and each polling interval is "0.5ms") + * Address: 0x1000_616C[1] + * Data: 1'b1 + * Action: polling + */ + check = 0; + CONSYS_REG_BIT_POLLING(CON_REG_SPM_BASE_ADDR + SPM_PWR_STATUS, 1, 1, 10, 500, check); + if (check != 0) + pr_err("Check conn_infra_on primary power fail. 0x1000_616C is 0x%08x. Expect [1] as 1.\n", + CONSYS_REG_READ(CON_REG_SPM_BASE_ADDR + SPM_PWR_STATUS)); +#endif + + /* Assert "conn_infra_on" secondary part power on, set "connsys_on_domain_pwr_on_s"=1 + * Address: 0x1000_6304[3] + * Data: 1'b1 + * Action: write + */ + CONSYS_SET_BIT(CON_REG_SPM_BASE_ADDR + SPM_CONN_PWR_CON, 0x8); + +#ifndef CONFIG_FPGA_EARLY_PORTING + /* Check "conn_infra_on" secondary part power status, + * check "connsys_on_domain_pwr_ack_s"=1 + * (polling "10 times" and each polling interval is "0.5ms") + * Address: 0x1000_6170[1] + * Data: 1'b1 + * Action: polling + */ + check = 0; + CONSYS_REG_BIT_POLLING(CON_REG_SPM_BASE_ADDR + SPM_PWR_STATUS_2ND, 1, 1, 10, 500, check); + if (check != 0) + pr_err("Check conn_infra_on secondary power fail. 0x1000_6170 is 0x%08x. Expect [1] as 1.\n", + CONSYS_REG_READ(CON_REG_SPM_BASE_ADDR + SPM_PWR_STATUS_2ND)); +#endif + + /* Turn on AP-to-CONNSYS bus clock, set "conn_clk_dis"=0 + * (apply this for bus clock toggling) + * Address: 0x1000_6304[4] + * Data: 1'b0 + * Action: write + */ + CONSYS_CLR_BIT(CON_REG_SPM_BASE_ADDR + SPM_CONN_PWR_CON, 0x10); + + /* Wait 1 us */ + udelay(1); + + /* De-assert "conn_infra_on" isolation, set "connsys_iso_en"=0 + * Address: 0x1000_6304[1] + * Data: 1'b0 + * Action: write + */ + CONSYS_CLR_BIT(CON_REG_SPM_BASE_ADDR + SPM_CONN_PWR_CON, 0x2); + + /* De-assert CONNSYS S/W reset (TOP RGU CR), + * set "ap_sw_rst_b"=1 + * Address: WDT_SWSYSRST[9] (0x1000_7018[9]) + * WDT_SWSYSRST[31:24] (0x1000_7018[31:24]) + * Data: [9]=1'b0 + * [31:24]=8'h88 (key) + * Action: Write + */ + CONSYS_REG_WRITE_MASK( + CON_REG_TOP_RGU_ADDR + TOP_RGU_WDT_SWSYSRST,0x88000000, 0xff000200); + + /* De-assert CONNSYS S/W reset (SPM CR), set "ap_sw_rst_b"=1 + * Address: CONN_PWR_CON[0] (0x1000_6304[0]) + * Data: 1'b1 + * Action: write + */ + CONSYS_SET_BIT(CON_REG_SPM_BASE_ADDR + SPM_CONN_PWR_CON, 0x1); + + /* Wait 0.5ms */ + udelay(500); + + /* Disable AXI bus sleep protect */ + /* Turn off AXI RX bus sleep protect (AP2CONN AHB Bus protect) + * (apply this for INFRA AHB bus accessing when CONNSYS had been turned on) + * Address: 0x1000_1718[31:0] (INFRA_TOPAXI_PROTECTEN2_CLR) + * Data: 0x0000_0002 + * Action: write + */ + CONSYS_REG_WRITE( + CON_REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN2_CLR_OFFSET, + 0x00000002); + +#ifndef CONFIG_FPGA_EARLY_PORTING + /* Check AHB RX bus sleep protect turn off + * (polling "100 times" and each polling interval is "0.5ms") + * Address: 0x1000_1724[2] (INFRA_TOPAXI_PROTECTEN2_STA1[2]) + * Data: 1'b0 + * Action: polling + */ + check = 0; + CONSYS_REG_BIT_POLLING( + CON_REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN2_STA1_OFFSET, + 2, 0, 100, 500, check); + if (check != 0) + pr_err("Polling AHB RX bus sleep protect turn off fail. status=0x%08x\n", + CONSYS_REG_READ(CON_REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN2_STA1_OFFSET)); +#endif + + /* Turn off AXI Rx bus sleep protect (CONN2AP AXI Rx Bus protect) + * (disable sleep protection when CONNSYS had been turned on) + * Note : Should turn off AHB Rx sleep protection first. + */ + CONSYS_REG_WRITE( + CON_REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN_CLR_OFFSET, + 0x00004000); +#if 0 /* POS update 20190819: Skip check */ +#ifndef CONFIG_FPGA_EARLY_PORTING + /* Check AXI Rx bus sleep protect turn off + * (polling "10 times" and each polling interval is "0.5ms") + * Address: 0x1000_1228[14] (INFRA_TOPAXI_PROTECTEN_STA1[14]) + * Data: 1'b0 + * Action: polling + */ + CONSYS_REG_BIT_POLLING( + CON_REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN_STA1_OFFSET, + 14, 0, 10, 50, check); + if (check != 0) + pr_err("Polling AXI bus sleep protect turn off fail. Status=0x%08x\n", + CONSYS_REG_READ(CON_REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN_STA1_OFFSET)); +#endif +#endif + /* Turn off AXI TX bus sleep protect (AP2CONN AXI Bus protect) + * (apply this for INFRA AXI bus accessing when CONNSYS had been turned on) + */ + CONSYS_REG_WRITE( + CON_REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN_CLR_OFFSET, + 0x00002000); + +#ifndef CONFIG_FPGA_EARLY_PORTING + /* Check AXI TX bus sleep protect turn off + * (polling "100 times" and each polling interval is "0.5ms") + * Address: 0x1000_1228[13] (INFRA_TOPAXI_PROTECTEN_STA1[13]) + * Data: 1'b0 + * Action: polling + */ + CONSYS_REG_BIT_POLLING( + CON_REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN_STA1_OFFSET, + 13, 0, 100, 500, check); + if (check != 0) + pr_err("polling AHB TX bus sleep protect turn off fail. Status=0x%08x\n", + CONSYS_REG_READ(CON_REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN_STA1_OFFSET)); +#endif +#endif /* MTK_CONNINFRA_CLOCK_BUFFER_API_AVAILABLE */ + /* Wait 6ms (apply this for CONNSYS XO clock ready) + * [NOTE] + * This setting could be changed at different design architecture + * and the characteristic of AFE WBG) + */ + mdelay(6); + } else { + consys_plt_pmic_ctrl_dump("CONN OFF"); + + /* Enable AXI bus sleep protect */ +#if MTK_CONNINFRA_CLOCK_BUFFER_API_AVAILABLE + pr_info("Turn off conn_infra power by SPM API\n"); + check = consys_platform_spm_conn_ctrl(enable); + if (check) { + pr_err("Turn off conn_infra power fail, ret=%d\n", check); + return -1; + } +#else + /* Turn on AXI TX bus sleep protect (AP2CONN AXI Bus protect) + * (apply this for INFRA AXI bus protection to prevent bus hang when + * CONNSYS had been turned off) + * Address: 0x1000_12a0[31:0] + * Data: 0x0000_2000 + * Action: write + */ + CONSYS_REG_WRITE( + CON_REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN_SET_OFFSET, + 0x00002000); + + /* check AHB TX bus sleep protect turn on (polling "100 times") + * Address: 0x1000_1228[13] + * Data: 1'b1 + * Action: polling + */ + CONSYS_REG_BIT_POLLING( + CON_REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN_STA1_OFFSET, + 13, 1, 100, 500, check); + if (check) + pr_err("Polling AHB TX bus sleep protect turn on fail.\n"); + + /* Turn on AXI Rx bus sleep protect (CONN2AP AXI RX Bus protect) + * (apply this for INFRA AXI bus protection to prevent bus hang when + * CONNSYS had been turned off) + * Note: + * Should turn on AXI Rx sleep protection after + * AXI Tx sleep protection has been turn on. + * Address: 0x1000_12A0[31:0] + * Data: 0x0000_4000 + * Action: write + */ + CONSYS_REG_WRITE( + CON_REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN_SET_OFFSET, + 0x00004000); + + /* check AXI Rx bus sleep protect turn on + * (polling "100 times", polling interval is 1ms) + * Address: 0x1000_1228[14] + * Data: 1'b1 + * Action: polling + */ + CONSYS_REG_BIT_POLLING( + CON_REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN_STA1_OFFSET, + 14, 1, 100, 1000, check); + if (check) + pr_err("Polling AXI Rx bus sleep protect turn on fail.\n"); + + /* Turn on AXI RX bus sleep protect (AP2CONN AXI Bus protect) + * (apply this for INFRA AXI bus protection to prevent bus hang when + * CONNSYS had been turned off) + * Address: 0x1000_1714[31:0] (INFRA_TOPAXI_PROTECTEN2_SET) + * Data: 0x0000_0002 + * Action: write + */ + CONSYS_REG_WRITE( + CON_REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN2_SET_OFFSET, + 0x00000002); + /* check AHB RX bus sleep protect turn on (polling "10 times") + * Address: 0x1000_1724[2] (INFRA_TOPAXI_PROTECTEN2_STA1[2]) + * Value: 1'b1 + * Action: polling + */ + CONSYS_REG_BIT_POLLING( + CON_REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN2_STA1_OFFSET, + 2, 1, 10, 1000, check); + if (check) + pr_err("Polling AHB RX bus sleep protect turn on fail.\n"); + + /* Assert "conn_infra_on" isolation, set "connsys_iso_en"=1 + * Address: CONN_PWR_CON[1] (0x1000_6304[1]) + * Value: 1'b1 + * Action: write + */ + CONSYS_SET_BIT(CON_REG_SPM_BASE_ADDR + SPM_CONN_PWR_CON, 0x2); + + /* Assert CONNSYS S/W reset (SPM CR), set "ap_sw_rst_b"=0 + * Address: CONN_PWR_CON[0] (0x1000_6304[0]) + * Value: 1'b0 + * Action: write + */ + CONSYS_CLR_BIT(CON_REG_SPM_BASE_ADDR + SPM_CONN_PWR_CON, 0x1); + + /* Assert CONNSYS S/W reset(TOP RGU CR), set "ap_sw_rst_b"=0 + * Address: WDT_SWSYSRST[9] (0x1000_7018[9]) + * WDT_SWSYSRST[31:24] (0x1000_7018[31:24]) + * Value: [9]=1'b1 + * [31:24]=8'h88 (key) + * Action: write + * Note: this CR value for reset control is active high (0: not reset, 1: reset) + */ + CONSYS_REG_WRITE_MASK( + CON_REG_TOP_RGU_ADDR + TOP_RGU_WDT_SWSYSRST, + 0x88000200, + 0xff000200); + + /* Turn off AP-to-CONNSYS bus clock, set "conn_clk_dis"=1 + * (apply this for bus clock gating) + * Address: CONN_PWR_CON[4] (0x1000_6304[4]) + * Value: 1'b1 + * Action: write + */ + CONSYS_SET_BIT(CON_REG_SPM_BASE_ADDR + SPM_CONN_PWR_CON, 0x10); + + /* wait 1us (?) */ + udelay(1); + + /* De-assert "conn_infra_on" primary part power on, + * set "connsys_on_domain_pwr_on"=0 + * Address: CONN_PWR_CON[2] (0x1000_6304[2]) + * Value: 1'b0 + * Action: write + */ + CONSYS_CLR_BIT(CON_REG_SPM_BASE_ADDR + SPM_CONN_PWR_CON, 0x4); + + /* De-assert "conn_infra_on" secondary part power on, + * set "connsys_on_domain_pwr_on_s"=0 + * Address: CONN_PWR_CON[3] (0x1000_6304[3]) + * Value: 1'b0 + * Action: write + */ + CONSYS_CLR_BIT(CON_REG_SPM_BASE_ADDR + SPM_CONN_PWR_CON, 0x8); +#endif /* MTK_CONNINFRA_CLOCK_BUFFER_API_AVAILABLE */ + + /* Turn off ap2conn host_ck CG (ECO) + * Address: INFRA_AP2MD_GALS_CTL[0] (0x1020E504[0]) + * Data: 1'b0 + * Action: write + */ + CONSYS_CLR_BIT(CON_REG_INFRACFG_BASE_ADDR + INFRA_AP2MD_GALS_CTL, 0x1); + } + return 0; +} + +int consys_conninfra_wakeup(void) +{ + int check, r1, r2; + unsigned int retry = 10; + unsigned int consys_hw_ver = 0; + int polling_fail_retry = 2; + unsigned long polling_fail_delay = 20000; /* 20ms */ + + /* Wake up conn_infra + * Address: CONN_HOST_CSR_TOP_CONN_INFRA_WAKEPU_TOP_CONN_INFRA_WAKEPU_TOP (0x180601a0) + * Data: 1'b1 + * Action: write + */ + CONSYS_REG_WRITE( + CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CONN_INFRA_WAKEPU_TOP_CONN_INFRA_WAKEPU_TOP, + 0x1); + + /* Check ap2conn slpprot_rdy + * (polling "10 times" for specific project code and each polling interval is "1ms") + * Address: CONN_HOST_CSR_TOP_CONN_SLP_PROT_CTRL_CONN_INFRA_ON2OFF_SLP_PROT_ACK (0x1806_0184[5]) + * Data: 1'b0 + * Action: polling + */ + while (polling_fail_retry > 0) { + check = 0; + CONSYS_REG_BIT_POLLING( + CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CONN_SLP_PROT_CTRL, 5, 0, 10, 1000, check); + + if (check) { + pr_err("[%s] Check ap2conn slpprot_rdy fail. value=0x%x WAKEUP_TOP=[0x%x]\n", + __func__, + CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CONN_SLP_PROT_CTRL), + CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CONN_INFRA_WAKEPU_TOP_CONN_INFRA_WAKEPU_TOP)); + } + + if (consys_reg_mng_reg_readable() == 0) { + check = consys_reg_mng_is_bus_hang(); + r1 = CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_DBG_DUMMY_3); + r2 = CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CONN_INFRA_WAKEPU_TOP_CONN_INFRA_WAKEPU_TOP); + pr_info("[%s] check=[%d] r1=[0x%x] r2=[0x%x]", __func__, check, r1, r2); + consys_reg_mng_dump_cpupcr(CONN_DUMP_CPUPCR_TYPE_ALL, 10, 200); + if (check > 0) { + return -1; + } + check = -1; + } + + if (check == 0) + break; + + /* delay 20 ms */ + usleep_range(polling_fail_delay - 200, polling_fail_delay + 200); + polling_fail_retry--; + } + + if (check != 0) { + pr_err("[%s] wakeup fail retry %d", __func__, polling_fail_retry); + return -1; + } + + /* Check CONNSYS version ID + * (polling "10 times" for specific project code and each polling interval is "1ms") + * Address: CONN_HW_VER (0x1800_1000[31:0]) + * Data: 32'h2001_0000 + * Action: polling + */ + check = 0; + while (retry-- > 0) { + consys_hw_ver = CONSYS_REG_READ( + CON_REG_INFRA_CFG_ADDR + + CONN_HW_VER_OFFSET); + if (consys_hw_ver == CONN_HW_VER) { + check = 0; + pr_info("[%s] Polling chip id success (0x%x)\n", __func__, consys_hw_ver); + break; + } + check = -1; + } + if (check != 0) + pr_err("[%s] Polling chip id fail (0x%x)\n", __func__, consys_hw_ver); + + return check; +} + +int consys_conninfra_sleep(void) +{ + /* Release conn_infra force on + * Address: CONN_HOST_CSR_TOP_CONN_INFRA_WAKEPU_TOP_CONN_INFRA_WAKEPU_TOP (0x180601a0) + * Data: 1'b0 + * Action: write + */ + CONSYS_REG_WRITE( + CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CONN_INFRA_WAKEPU_TOP_CONN_INFRA_WAKEPU_TOP, + 0x0); + + return 0; +} + +void consys_set_if_pinmux(unsigned int enable) +{ +#ifndef CONFIG_FPGA_EARLY_PORTING + if (enable) { + /* Set pinmux for the interface between D-die and A-die + * (CONN_HRST_B / CONN_TOP_CLK / CONN_TOP_DATA / CONN_WB_PTA / + * CONN_BT_CLK / CONN_BT_DATA / CONN_WF_CTRL0 / CONN_WF_CTRL1 / + * CONN_WF_CTRL2 / CONN_WF_CTRL3 / CONN_WF_CTRL4) + */ + /* GPIO 172: 0x1000_5450[18:16] */ + /* GPIO 173: 0x1000_5450[22:20] */ + /* GPIO 174: 0x1000_5450[26:24] */ + /* GPIO 175: 0x1000_5450[30:28] */ + CONSYS_REG_WRITE_MASK(GPIO_BASE_ADDR + GPIO_MODE21, 0x11110000, 0xffff0000); + + /* GPIO 176: 0x1000_5460[2:0] */ + /* GPIO 177: 0x1000_5460[6:4] */ + /* GPIO 178: 0x1000_5460[10:8] */ + /* GPIO 179: 0x1000_5460[14:12] */ + /* GPIO 180: 0x1000_5460[18:16] */ + /* GPIO 181: 0x1000_5460[22:20] */ + /* GPIO 182: 0x1000_5460[26:24] */ + CONSYS_REG_WRITE_MASK(GPIO_BASE_ADDR + GPIO_MODE22, 0x01111111, 0x0fffffff); + + /* Set pinmux driving to 2mA + * Address: + * 0x11EA_0000[5:3]/0x11EA_0000[8:6]/0x11EA_0000[11:9] + * 0x11EA_0000[14:12]/0x11EA_0000[17:15] + * Data: 3'b000 + * Action: write + * Note: IOCFG_RT + */ + CONSYS_REG_WRITE_MASK(IOCFG_RT_ADDR + IOCFG_RT_DRV_CFG0, 0x0, 0x3fff8); + + /* Set CONN_TOP_CLK/CONN_TOP_DATA/CONN_BT_CLK/CONN_BT_DATA driving to 4mA + * (CONN_TOP_DATA driving config is the same position with + * CONN_WF_CTRL0/CONN_WF_CTRL1/CONN_WF_CTRL2/CONN_WF_CTRL3/CONN_WF_CTRL4) + * Address: + * CONN_TOP_CLK 0x11EA_0000[17:15] = 3b'001 + * CONN_TOP_DATA 0x11EA_0000[5:3] = 3b'001 + * CONN_BT_CLK 0x11EA_0000[8:6] = 3b'001 + * CONN_BT_DATA 0x11EA_0000[11:9] = 3b'001 + * Action: write + */ + CONSYS_REG_WRITE_MASK(IOCFG_RT_ADDR + IOCFG_RT_DRV_CFG0, 0x8248, 0x38ff8); + + /* Set pinmux PUPD setting + * Clear CONN_TOP_DATA/CONN_BT_DATA PD setting + * Address: 0x11EA_0058[14][11] + * Data: 2'b11 + * Action: write + * Note: IOCFG_RT + */ + CONSYS_REG_WRITE_MASK(IOCFG_RT_ADDR + IOCFG_RT_PD_CFG0_CLR, 0x4800, 0x4800); + + /* Set pinmux PUPD + * Setting CONN_TOP_DATA/CONN_BT_DATA as PU + * Address: 0x11EA_0074[14][11] + * Data: 2'b11 + * Action: write + * Note: IOCFG_RT + */ + CONSYS_REG_WRITE_MASK(IOCFG_RT_ADDR + IOCFG_RT_PU_CFG0_SET, 0x4800, 0x4800); + + /* If TCXO mode, set GPIO155 pinmux for TCXO mode (AUX4) + * (CONN_TCXOENA_REQ) + * Address: 0x1000_5430[14:12] + * Data: 3'b100 + * Action: write + */ + if (consys_co_clock_type() == CONNSYS_CLOCK_SCHEMATIC_26M_EXTCXO) { + /* TODO: need customization for TCXO GPIO */ + CONSYS_REG_WRITE_MASK(GPIO_BASE_ADDR + GPIO_MODE19, 0x4000, 0x7000); + } + } else { + /* Set pinmux for the interface between D-die and A-die (Aux0) + * Address: + * 0x1000_5450[26:24]/0x1000_5450[18:16]/0x1000_5450[22:20] + * 0x1000_5450[30:28]/0x1000_5460[2:0]/0x1000_5460[6:4] + * 0x1000_5460[10:8]/0x1000_5460[14:12]/0x1000_5460[18:16] + * 0x1000_5460[22:20]/0x1000_5460[26:24] + * Data: 3'b000 + * Action: write + */ + CONSYS_REG_WRITE_MASK(GPIO_BASE_ADDR + GPIO_MODE21, 0x0, 0xffff0000); + CONSYS_REG_WRITE_MASK(GPIO_BASE_ADDR + GPIO_MODE22, 0x0, 0x0fffffff); + + /* Set pinmux PUPD setting + * Clear CONN_TOP_DATA/CONN_BT_DATA PU setting + * Address: 0x11EA_0078[14][11] + * Data: 2'b11 + * Action: write + */ + CONSYS_REG_WRITE_MASK(IOCFG_RT_ADDR + IOCFG_RT_PU_CFG0_CLR, 0x4800, 0x4800); + + /* Set pinmux PUPD setting + * CONN_TOP_DATA/CONN_BT_DATA as PD + * Address: 0x11EA_0054[14][11] + * Data: 2'b11 + *Action: write + */ + CONSYS_REG_WRITE_MASK(IOCFG_RT_ADDR + IOCFG_RT_PD_CFG0_SET, 0x4800, 0x4800); + + /* If TCXO mode, set GPIO155 pinmux to GPIO mode + * Address: 0x1000_5430[14:12] + * Data: 3'b000 + * Action: write + */ + if (consys_co_clock_type() == CONNSYS_CLOCK_SCHEMATIC_26M_EXTCXO) { + CONSYS_REG_WRITE_MASK(GPIO_BASE_ADDR + GPIO_MODE19, 0x0, 0x7000); + } + } +#else + pr_info("[%s] not for FPGA\n", __func__); +#endif +} + +int consys_polling_chipid(void) +{ + unsigned int retry = 11; + unsigned int consys_hw_ver = 0; + unsigned int consys_configuration_id = 0; + int ret = -1; + int check; + + /* Check ap2conn slpprot_rdy + * (polling "10 times" for specific project code and each polling interval is "1ms") + * Address: + * CONN_HOST_CSR_TOP_CONN_SLP_PROT_CTRL_CONN_INFRA_ON2OFF_SLP_PROT_ACK + * 0x1806_0184[5] + * Value: 1'b0 + * Action: polling + * Note: deadfeed CDC issue + */ + check = 0; + CONSYS_REG_BIT_POLLING( + CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CONN_SLP_PROT_CTRL, 5, 0, 10, 1000, check); + if (check) { + pr_err("[%s] Check ap2conn slpprot_rdy fail. value=0x%x WAKEUP_TOP=[0x%x]\n", + __func__, + CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CONN_SLP_PROT_CTRL), + CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CONN_INFRA_WAKEPU_TOP_CONN_INFRA_WAKEPU_TOP)); + } + + while (--retry > 0) { + consys_hw_ver = CONSYS_REG_READ( + CON_REG_INFRA_CFG_ADDR + + CONN_HW_VER_OFFSET); + if (consys_hw_ver == CONN_HW_VER) { + consys_configuration_id = CONSYS_REG_READ( + CON_REG_INFRA_CFG_ADDR + CONN_CFG_ID_OFFSET); + pr_info("Consys HW version id(0x%x) cfg_id=(0x%x)\n", + consys_hw_ver, consys_configuration_id); + ret = 0; + break; + } + msleep(20); + } + + if (retry == 0) { + pr_err("Read CONSYS version id fail. Expect 0x%x but get 0x%x\n", + CONN_HW_VER, consys_hw_ver); + return -1; + } + + /* Disable conn_infra deadfeed function(workaround) + * Address: CONN_HOST_CSR_TOP_CSR_DEADFEED_EN_CR_AP2CONN_DEADFEED_EN (0x1806_0124[0]) + * Data: 1'b0 + * Action: write + * Note: workaround for deadfeed CDC issue + */ + CONSYS_CLR_BIT(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CSR_DEADFEED_EN_CR, 0x1); + +#ifdef CONFIG_FPGA_EARLY_PORTING + /* For FPGA workaround */ + CONSYS_SET_BIT(CON_REG_INFRA_CFG_ADDR + 0x0c04, + ((0x1 << 1) | (0x1 << 9) | (0x1 << 17) | (0x1 << 25))); + pr_info("Workaround for FPGA: Check %x\n", CON_REG_INFRA_CFG_ADDR + 0x0c04); +#endif + + return ret; +} + +int connsys_d_die_cfg(void) +{ + /* Read D-die Efuse + * Address: AP2CONN_EFUSE_DATA (0x1800_1818) + * Data: + * Action: read + */ + CONSYS_REG_WRITE( + CONN_INFRA_SYSRAM_BASE_ADDR + CONN_INFRA_SYSRAM_SW_CR_D_DIE_EFUSE, + CONSYS_REG_READ(CON_REG_INFRA_CFG_ADDR + AP2CONN_EFUSE_DATA)); + + /* conn_infra sysram hw control setting -> disable hw power down + * Address: CONN_INFRA_RGU_SYSRAM_HWCTL_PDN_SYSRAM_HWCTL_PDN (0x1800_0038) + * Data: 32'h0 + * Action: write + */ + CONSYS_REG_WRITE(CON_REG_INFRA_RGU_ADDR + CONN_INFRA_RGU_SYSRAM_HWCTL_PDN, 0x0); + + /* conn_infra sysram hw control setting -> enable hw sleep + * Address: CONN_INFRA_RGU_SYSRAM_HWCTL_SLP_SYSRAM_HWCTL_SLP (0x1800_003C) + * Data: 32'h0000_00FF + * Action: write + */ + CONSYS_REG_WRITE(CON_REG_INFRA_RGU_ADDR + CONN_INFRA_RGU_SYSRAM_HWCTL_SLP, 0x000000ff); + + /* co-ext memory hw control setting -> disable hw power down + * Address: CONN_INFRA_RGU_CO_EXT_MEM_HWCTL_PDN_CO_EXT_MEM_HWCTL_PDN (0x1800_0050) + * Data: 32'h0 + * Action: write + */ + CONSYS_REG_WRITE(CON_REG_INFRA_RGU_ADDR + CONN_INFRA_RGU_CO_EXT_MEM_HWCTL_PDN, 0x0); + + /* co-ext memory hw control setting -> enable hw sleep + * Address: CONN_INFRA_RGU_CO_EXT_MEM_HWCTL_SLP_CO_EXT_MEM_HWCTL_SLP (0x1800_0054) + * Data: 32'h0000_0001 + * Action: write + */ + CONSYS_REG_WRITE(CON_REG_INFRA_RGU_ADDR + CONN_INFRA_RGU_CO_EXT_MEM_HWCTL_SLP, 0x1); + + return 0; +} + +int connsys_spi_master_cfg(unsigned int next_status) +{ + unsigned int bt_only = 0; + + if ((next_status & (~(0x1 << CONNDRV_TYPE_BT))) == 0) + bt_only = 1; + + /* CONN_WT_SLP_CTL_REG_WB_WF_CK_ADDR_ADDR(0x070) = 0x0AF40A04 + * CONN_WT_SLP_CTL_REG_WB_WF_WAKE_ADDR_ADDR(0x74) = 0x00A00090 + * CONN_WT_SLP_CTL_REG_WB_WF_ZPS_ADDR_ADDR(0x78) = 0x009c008c + * CONN_WT_SLP_CTL_REG_WB_BT_CK_ADDR_ADDR(0x7c[11:0]) = 0xa08 + * CONN_WT_SLP_CTL_REG_WB_BT_WAKE_ADDR_ADDR(0x80[11:0]) = 0x094 + * CONN_WT_SLP_CTL_REG_WB_TOP_CK_ADDR_ADDR(0x84[11:0]) = 0x02c + * CONN_WT_SLP_CTL_REG_WB_GPS_CK_ADDR_ADDR(0x88) = 0x0AFC0A0C + * CONN_WT_SLP_CTL_REG_WB_WF_B0_CMD_ADDR_ADDR(0x8c[11:0]) = 0x0F0 + * CONN_WT_SLP_CTL_REG_WB_WF_B1_CMD_ADDR_ADDR(0x90[11:0]) = 0x0F4 + * CONN_WT_SLP_CTL_REG_WB_GPS_RFBUF_ADDR(0x18005094[11:0]) = 0x0FC + * CONN_WT_SLP_CTL_REG_WB_GPS_L5_EN_ADDR(0x18005098[11:0]) = 0x0F8 + */ + CONSYS_REG_WRITE( + CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_WF_CK_ADDR, 0x0AF40A04); + CONSYS_REG_WRITE( + CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_WF_WAKE_ADDR, 0x00A00090); + CONSYS_REG_WRITE( + CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_WF_ZPS_ADDR, 0x009C008C); + CONSYS_REG_WRITE_MASK( + CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BT_CK_ADDR, + 0xa08, 0xfff); + CONSYS_REG_WRITE_MASK( + CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BT_WAKE_ADDR, + 0x094, 0xfff); + CONSYS_REG_WRITE_MASK( + CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_TOP_CK_ADDR, + 0x02c, 0xfff); + CONSYS_REG_WRITE( + CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_GPS_CK_ADDR, + 0x0AFC0A0C); + CONSYS_REG_WRITE_MASK( + CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_WF_B0_CMD_ADDR, + 0x0f0, 0xfff); + CONSYS_REG_WRITE_MASK( + CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_WF_B1_CMD_ADDR, + 0x0f4, 0xfff); + CONSYS_REG_WRITE_MASK( + CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_GPS_RFBUF_ADDR, + 0x0FC, 0xfff); + CONSYS_REG_WRITE_MASK( + CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_GPS_L5_EN_ADDR, + 0x0F8, 0xfff); + + /* CONN_WT_SLP_CTL_REG_WB_SLP_CTL_CMD_LENGTH(0x004[4:0]) = 0x8 + * CONN_WT_SLP_CTL_REG_WB_BG_ADDR1_WB_BG_ADDR1(0x10[15:0]) = 0xA03C + * CONN_WT_SLP_CTL_REG_WB_BG_ADDR2_WB_BG_ADDR2(0x14[15:0]) = 0xA03C + * CONN_WT_SLP_CTL_REG_WB_BG_ADDR3_WB_BG_ADDR3(0x18[15:0]) = 0xAA18 + * CONN_WT_SLP_CTL_REG_WB_BG_ADDR4_WB_BG_ADDR4(0x1c[15:0]) = 0xAA18 + * CONN_WT_SLP_CTL_REG_WB_BG_ADDR5_WB_BG_ADDR5(0x20[15:0]) = 0xA0C8 + * CONN_WT_SLP_CTL_REG_WB_BG_ADDR6_WB_BG_ADDR6(0x24[15:0]) = 0xAA00 + * CONN_WT_SLP_CTL_REG_WB_BG_ADDR7_WB_BG_ADDR7(0x28[15:0]) = 0xA0B4 + * CONN_WT_SLP_CTL_REG_WB_BG_ADDR8_WB_BG_ADDR8(0x2c[15:0]) = 0xA34C + * CONN_WT_SLP_CTL_REG_WB_BG_ON1_WB_BG_ON1(0x30) = 0x00000000 + * CONN_WT_SLP_CTL_REG_WB_BG_ON2_WB_BG_ON2(0x34) = 0x00000000 + * if (BT_only) { + * CONN_WT_SLP_CTL_REG_WB_BG_ON3_WB_BG_ON3(0x38) = 0x74E03F75 + * CONN_WT_SLP_CTL_REG_WB_BG_ON4_WB_BG_ON4(0x3c) = 0x76E83F75 + * } else { + * CONN_WT_SLP_CTL_REG_WB_BG_ON3_WB_BG_ON3(0x38) = 0x74E0FFF5 + * CONN_WT_SLP_CTL_REG_WB_BG_ON4_WB_BG_ON4(0x3c) = 0x76E8FFF5 + * } + * CONN_WT_SLP_CTL_REG_WB_BG_ON5_WB_BG_ON5(0x40) = 0x00000000 + * CONN_WT_SLP_CTL_REG_WB_BG_ON6_WB_BG_ON6(0x44) = 0xFFFFFFFF + * CONN_WT_SLP_CTL_REG_WB_BG_ON7_WB_BG_ON7(0x48) = 0x00000019 + * CONN_WT_SLP_CTL_REG_WB_BG_ON8_WB_BG_ON8(0x4c) = 0x00010400 + * CONN_WT_SLP_CTL_REG_WB_BG_OFF1_WB_BG_OFF1(0x50) = 0x57400000 + * CONN_WT_SLP_CTL_REG_WB_BG_OFF2_WB_BG_OFF2(0x54) = 0x57400000 + * if (BT only) { + * CONN_WT_SLP_CTL_REG_WB_BG_OFF3_WB_BG_OFF3(0x58) = 0x44E03F75 + * CONN_WT_SLP_CTL_REG_WB_BG_OFF4_WB_BG_OFF4(0x5c) = 0x44E03F75 + * } else { + * CONN_WT_SLP_CTL_REG_WB_BG_OFF3_WB_BG_OFF3(0x58) = 0x44E0FFF5 + * CONN_WT_SLP_CTL_REG_WB_BG_OFF4_WB_BG_OFF4(0x5c) = 0x44E0FFF5 + * } + * CONN_WT_SLP_CTL_REG_WB_BG_OFF5_WB_BG_OFF5(0x60) = 0x00000001 + * CONN_WT_SLP_CTL_REG_WB_BG_OFF6_WB_BG_OFF6(0x64) = 0x00000000 + * CONN_WT_SLP_CTL_REG_WB_RG_OFF7_WB_BG_OFF7(0x68) = 0x00040019 + * CONN_WT_SLP_CTL_REG_WB_RG_OFF8_WB_BG_OFF8(0x6c) = 0x00410440 + */ + CONSYS_REG_WRITE_MASK( + CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_SLP_CTL, + 0x8, 0x1f); + + CONSYS_REG_WRITE_MASK( + CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ADDR1, + 0xa03c, 0xffff); + CONSYS_REG_WRITE_MASK( + CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ADDR2, + 0xa03c, 0xffff); + CONSYS_REG_WRITE_MASK( + CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ADDR3, + 0xaa18, 0xffff); + CONSYS_REG_WRITE_MASK( + CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ADDR4, + 0xaa18, 0xffff); + CONSYS_REG_WRITE_MASK( + CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ADDR5, + 0xa0c8, 0xffff); + CONSYS_REG_WRITE_MASK( + CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ADDR6, + 0xaa00, 0xffff); + CONSYS_REG_WRITE_MASK( + CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ADDR7, + 0xa0b4, 0xffff); + CONSYS_REG_WRITE_MASK( + CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ADDR8, + 0xa34c, 0xffff); + CONSYS_REG_WRITE( + CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ON1, 0x00000000); + CONSYS_REG_WRITE( + CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ON2, 0x00000000); + if (bt_only) { + CONSYS_REG_WRITE( + CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ON3, 0x74E03F75); + CONSYS_REG_WRITE( + CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ON4, 0x76E83F75); + } else { + CONSYS_REG_WRITE( + CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ON3, 0x74E0fff5); + CONSYS_REG_WRITE( + CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ON4, 0x76E8FFF5); + } + CONSYS_REG_WRITE( + CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ON5, 0x00000000); + CONSYS_REG_WRITE( + CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ON6, 0xFFFFFFFF); + CONSYS_REG_WRITE( + CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ON7, 0x00000019); + CONSYS_REG_WRITE( + CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ON8, 0x00010400); + + CONSYS_REG_WRITE( + CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_OFF1, 0x57400000); + CONSYS_REG_WRITE( + CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_OFF2, 0x57400000); + if (bt_only) { + CONSYS_REG_WRITE( + CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_OFF3, 0x44E03F75); + CONSYS_REG_WRITE( + CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_OFF4, 0x44E03F75); + } else { + CONSYS_REG_WRITE( + CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_OFF3, 0x44e0fff5); + CONSYS_REG_WRITE( + CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_OFF4, 0x44e0fff5); + } + CONSYS_REG_WRITE( + CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_OFF5, 0x00000001); + CONSYS_REG_WRITE( + CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_OFF6, 0x00000000); + CONSYS_REG_WRITE( + CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_OFF7, 0x00040019); + CONSYS_REG_WRITE( + CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_OFF8, 0x00410440); + + return 0; +} + +//#ifndef CONFIG_FPGA_EARLY_PORTING +/***************************************************************************** +* FUNCTION +* connsys_a_die_efuse_read +* DESCRIPTION +* Read a-die efuse +* PARAMETERS +* efuse_addr: read address +* RETURNS +* int +* 0: fail, efuse is invalid +* 1: success, efuse is valid +*****************************************************************************/ +static int connsys_a_die_efuse_read(unsigned int efuse_addr) +{ + int ret = 0; + int retry = 0; + unsigned int efuse0 = 0, efuse1 = 0, efuse2 = 0, efuse3 = 0; + int ret0, ret1, ret2, ret3; + + /* Get semaphore before read */ + if (consys_sema_acquire_timeout(CONN_SEMA_RFSPI_INDEX, CONN_SEMA_TIMEOUT) == CONN_SEMA_GET_FAIL) { + pr_err("[EFUSE READ] Require semaphore fail\n"); + return 0; + } + + /* Efuse control clear, clear Status /trigger + * Address: ATOP EFUSE_CTRL_write_efsrom_kick_and_read_kick_busy_flag (0x108[30]) + * Data: 1'b0 + * Action: TOPSPI_WR + */ + consys_spi_read_nolock(SYS_SPI_TOP, ATOP_EFUSE_CTRL, &ret); + ret &= ~(0x1 << 30); + consys_spi_write_nolock(SYS_SPI_TOP, ATOP_EFUSE_CTRL, ret); + + /* Efuse Read 1st 16byte + * Address: + * ATOP EFUSE_CTRL_efsrom_mode (0x108[7:6]) = 2'b00 + * ATOP EFUSE_CTRL_efsrom_ain (0x108[25:16]) = efuse_addr (0) + * ATOP EFUSE_CTRL_write_efsrom_kick_and_read_kick_busy_flag (0x108[30]) = 1'b1 + * Action: TOPSPI_WR + */ + consys_spi_read_nolock(SYS_SPI_TOP, ATOP_EFUSE_CTRL, &ret); + ret &= ~(0x43ff00c0); + ret |= (0x1 << 30); + ret |= ((efuse_addr << 16) & 0x3ff0000); + consys_spi_write_nolock(SYS_SPI_TOP, ATOP_EFUSE_CTRL, ret); + + /* Polling EFUSE busy = low + * (each polling interval is "30us" and polling timeout is 2ms) + * Address: + * ATOP EFUSE_CTRL_write_efsrom_kick_and_read_kick_busy_flag (0x108[30]) = 1'b0 + * Action: TOPSPI_Polling + */ + consys_spi_read_nolock(SYS_SPI_TOP, ATOP_EFUSE_CTRL, &ret); + while ((ret & (0x1 << 30)) != 0 && retry < 70) { + retry++; + udelay(30); + consys_spi_read_nolock(SYS_SPI_TOP, ATOP_EFUSE_CTRL, &ret); + } + if ((ret & (0x1 << 30)) != 0) { + pr_info("[%s] EFUSE busy, retry failed(%d)\n", __func__, retry); + } + + /* Check efuse_valid & return + * Address: ATOP EFUSE_CTRL_csri_efsrom_dout_vld_sync_1_ (0x108[29]) + * Action: TOPSPI_RD + */ + /* if (efuse_valid == 1'b1) + * Read Efuse Data to global var + */ + consys_spi_read_nolock(SYS_SPI_TOP, ATOP_EFUSE_CTRL, &ret); + if (((ret & (0x1 << 29)) >> 29) == 1) { + ret0 = consys_spi_read_nolock(SYS_SPI_TOP, ATOP_EFUSE_RDATA0, &efuse0); + + CONSYS_REG_WRITE( + CONN_INFRA_SYSRAM_BASE_ADDR + CONN_INFRA_SYSRAM_SW_CR_A_DIE_EFUSE_DATA_0, + efuse0); + + ret1 = consys_spi_read_nolock(SYS_SPI_TOP, ATOP_EFUSE_RDATA1, &efuse1); + CONSYS_REG_WRITE( + CONN_INFRA_SYSRAM_BASE_ADDR + CONN_INFRA_SYSRAM_SW_CR_A_DIE_EFUSE_DATA_1, + efuse1); + /* Sub-task: thermal cal */ + connsys_a_die_thermal_cal(1, efuse1); + + ret2 = consys_spi_read_nolock(SYS_SPI_TOP, ATOP_EFUSE_RDATA2, &efuse2); + CONSYS_REG_WRITE( + CONN_INFRA_SYSRAM_BASE_ADDR + CONN_INFRA_SYSRAM_SW_CR_A_DIE_EFUSE_DATA_2, + efuse2); + + ret3 = consys_spi_read_nolock(SYS_SPI_TOP, ATOP_EFUSE_RDATA3, &efuse3); + CONSYS_REG_WRITE( + CONN_INFRA_SYSRAM_BASE_ADDR + CONN_INFRA_SYSRAM_SW_CR_A_DIE_EFUSE_DATA_3, + efuse3); + + pr_info("efuse = [0x%08x, 0x%08x, 0x%08x, 0x%08x]", efuse0, efuse1, efuse2, efuse3); + if (ret0 || ret1 || ret2 || ret3) + pr_err("efuse read error: [%d, %d, %d, %d]", ret0, ret1, ret2, ret3); + ret = 1; + } else { + connsys_a_die_thermal_cal(0, 0); + pr_err("EFUSE is invalid\n"); + ret = 0; + } + + consys_sema_release(CONN_SEMA_RFSPI_INDEX); + return ret; +} + +static int connsys_a_die_thermal_cal(int efuse_valid, unsigned int efuse) +{ + struct consys_plat_thermal_data input; + memset(&input, 0, sizeof(struct consys_plat_thermal_data)); + + if (efuse_valid) { + if (efuse & (0x1 << 7)) { + consys_spi_write_offset_range_nolock( + SYS_SPI_TOP, ATOP_RG_TOP_THADC_BG, efuse, 12, 3, 4); + consys_spi_write_offset_range_nolock( + SYS_SPI_TOP, ATOP_RG_TOP_THADC, efuse, 23, 0, 3); + } + if(efuse & (0x1 << 15)) { + consys_spi_write_offset_range_nolock( + SYS_SPI_TOP, ATOP_RG_TOP_THADC, efuse, 26, 13, 2); + input.slop_molecule = (efuse & 0x1f00) >> 8; + pr_info("slop_molecule=[%d]", input.slop_molecule); + } + if (efuse & (0x1 << 23)) { + /* [22:16] */ + input.thermal_b = (efuse & 0x7f0000) >> 16; + pr_info("thermal_b =[%d]", input.thermal_b); + } + if (efuse & (0x1 << 31)) { + input.offset = (efuse & 0x7f000000) >> 24; + pr_info("offset=[%d]", input.offset); + } + } + update_thermal_data(&input); + return 0; +} +//#endif + +int connsys_a_die_cfg(void) +{ + int efuse_valid; + bool adie_26m = true; + unsigned int adie_id = 0; + + if (consys_co_clock_type() == CONNSYS_CLOCK_SCHEMATIC_52M_COTMS) { + pr_info("A-die clock 52M\n"); + adie_26m = false; + } + /* First time to setup conninfra sysram, clean it. */ + memset_io( + (volatile void*)CONN_INFRA_SYSRAM_BASE_ADDR + CONN_INFRA_SYSRAM_SW_CR_OFFSET, + 0x0, + CONN_INFRA_SYSRAM_SW_CR_SIZE); + + + /* if(A-die XTAL = 26MHz ) { + * CONN_WF_CTRL2 swtich to GPIO mode, GPIO output value + * before patch download swtich back to CONN mode. + * } + */ + /* Address: + * 0x1000_5054 = 32'h0010_0000 + * 0x1000_5154 = 32'h0010_0000 + * 0x1000_5460[18:16] = 3'b000 + * Actin: write + * Note: MT6635 strap pinmux, set CONN_WF_CTRL2 as GPIO + */ + if (adie_26m) { + CONSYS_REG_WRITE(GPIO_BASE_ADDR + GPIO_DIR5_SET, 0x00100000); + CONSYS_REG_WRITE(GPIO_BASE_ADDR + GPIO_DOUT5_SET, 0x00100000); + CONSYS_REG_WRITE_MASK(GPIO_BASE_ADDR + GPIO_MODE22, 0x0, 0x70000); + } + /* sub-task: a-die cfg */ + /* De-assert A-die reset + * Address: CONN_INFRA_CFG_ADIE_CTL_ADIE_RSTB (0x18001900[0]) + * Data: 1'b1 + * Action: write + */ + CONSYS_SET_BIT(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_ADIE_CTL, 0x1); + + /* Read MT6635 ID + * Address: ATOP CHIP_ID + * 0x02C[31:16]: hw_code + * 0x02C[15:0]: hw_ver + * Data: + * MT6635 E1 : read 0x02C = 0x66358A00 + * MT6635 E2 : read 0x02C = 0x66358A10 + * MT6635 E3 : read 0x02C = 0x66358A11 + * Action: TOPSPI_RD + */ + consys_spi_read(SYS_SPI_TOP, ATOP_CHIP_ID, &adie_id); + conn_hw_env.adie_hw_version = adie_id; + conn_hw_env.is_rc_mode = consys_is_rc_mode_enable(); + pr_info("A-die CHIP_ID=0x%08x rc=%d\n", adie_id, conn_hw_env.is_rc_mode); + + CONSYS_REG_WRITE( + CONN_INFRA_SYSRAM_BASE_ADDR + CONN_INFRA_SYSRAM_SW_CR_A_DIE_CHIP_ID, + adie_id); + + /* Patch to FW from 7761(WF0_WRI_SX_CAL_MAP/WF1_WRI_SX_CAL_MAP) + * Address: ATOP WRI_CTR2 (0x064) + * Data: 32'h00007700 + * Action: TOPSPI_WR + */ + consys_spi_write(SYS_SPI_TOP, ATOP_WRI_CTR2, 0x00007700); + + /* Set WF low power cmd as DBDC mode & legacy interface + * Address: ATOP SMCTK11 (0x0BC) + * Data: 32'h00000021 + * Action: TOPSPI_WR + */ + consys_spi_write(SYS_SPI_TOP, ATOP_SMCTK11, 0x00000021); + + /* Update spi fm read extra bit setting + * Address: + * CONN_RF_SPI_MST_REG_FM_CTRL_FM_RD_EXT_EN (0x1800400C[15]) + * CONN_RF_SPI_MST_REG_FM_CTRL_FM_RD_EXT_CNT (0x1800400C[7:0]) + * Data: + * 0x1800400C[15] = 1'b0 + * 0x1800400C[7:0] = 8'h0 + * Action: write + */ + CONSYS_REG_WRITE_MASK( + CONN_REG_RFSPI_ADDR + CONN_RF_SPI_MST_REG_FM_CTRL, 0x0, 0x80ff); + + /* Update Thermal addr for 6635 + * Address: CONN_TOP_THERM_CTL_THERM_AADDR (0x18002018) + * Data: 32'h50305A00 + * Action: write + */ + CONSYS_REG_WRITE(CONN_TOP_THERM_CTL_ADDR + CONN_TOP_THERM_CTL_THERM_AADDR, 0x50305A00); + + /* Sub-task: read a-die efuse */ + efuse_valid = connsys_a_die_efuse_read(0); + + /* Set WF_PAD to HighZ + * Address: ATOP RG_ENCAL_WBTAC_IF_SW (0x070) + * Data: 32'h80000000 + * Action: TOPSPI_WR + */ + consys_spi_write(SYS_SPI_TOP, ATOP_RG_ENCAL_WBTAC_IF_SW, 0x80000000); + + /* Disable CAL LDO + * Address: ATOP RG_WF0_TOP_01 (0x380) + * Data: 32'h000E8002 + * Action: TOPSPI_WR + * Note: AC mode + */ + consys_spi_write(SYS_SPI_TOP, ATOP_RG_WF0_TOP_01, 0x000e8002); + + /* Disable CAL LDO + * Address: ATOP RG_WF1_TOP_01 (0x390) + * Data: 32'h000E8002 + * Action: TOPSPI_WR + * Note: AC mode + */ + consys_spi_write(SYS_SPI_TOP, ATOP_RG_WF1_TOP_01, 0x000e8002); + + /* Increase XOBUF supply-V + * Address: ATOP RG_TOP_XTAL_01 (0xA18) + * Data: 32'hF6E8FFF5 + * Action: TOPSPI_WR + */ + consys_spi_write(SYS_SPI_TOP, ATOP_RG_TOP_XTAL_01, 0xF6E8FFF5); + + /* Increase XOBUF supply-R for MT6635 E1 + * Address: ATOP RG_TOP_XTAL_02 (0xA1C) + * Data: + * if(MT6635 E1) //rf_hw_ver = 0x8a00 + * 32'hD5555FFF + * else + * 32'h0x55555FFF + * Action: TOPSPI_WR + */ + if (adie_id == 0x66358a00) { + consys_spi_write(SYS_SPI_TOP, ATOP_RG_TOP_XTAL_02, 0xD5555FFF); + } else { + consys_spi_write(SYS_SPI_TOP, ATOP_RG_TOP_XTAL_02, 0x55555FFF); + } + + /* Initial IR value for WF0 THADC + * Address: ATOP RG_WF0_BG (0x384) + * Data: 0x00002008 + * Action: TOPSPI_WR + */ + consys_spi_write(SYS_SPI_TOP, ATOP_RG_WF0_BG, 0x2008); + + /* Initial IR value for WF1 THADC + * Address: ATOP RG_WF1_BG (0x394) + * Data: 0x00002008 + * Action: TOPSPI_WR + */ + consys_spi_write(SYS_SPI_TOP, ATOP_RG_WF1_BG, 0x2008); + + /* if(A-die XTAL = 26MHz ) { + * CONN_WF_CTRL2 swtich to CONN mode + * } + */ + /* Adress: 0x1000_5460[18:16] = 3'b001 + * Action: write + * Note: MT6635 strap pinmux, set CONN_WF_CTRL2 as conn mode + */ + if (adie_26m) { + CONSYS_REG_WRITE_MASK(GPIO_BASE_ADDR + GPIO_MODE22, 0x10000, 0x70000); + } + return 0; +} + +int connsys_afe_wbg_cal(void) +{ + /* Default value update; 1: AFE WBG CR (if needed) + * note that this CR must be backuped and restored by command batch engine + * Address: + * CONN_AFE_CTL_RG_WBG_AFE_01(0x18003010) = 32'h00000000 + * CONN_AFE_CTL_RG_WBG_RCK_01(0x18003018) = 32'h144B0160 + * CONN_AFE_CTL_RG_WBG_GL1_01(0x18003040) = 32'h10990C13 + * CONN_AFE_CTL_RG_WBG_GL5_01(0x18003100) = 32'h10990C13 + * CONN_AFE_CTL_RG_WBG_BT_TX_03 (0x18003058) = 32'hCD258051 + * CONN_AFE_CTL_RG_WBG_WF0_TX_03 (0x18003078) = 32'hC5258251 + * CONN_AFE_CTL_RG_WBG_WF1_TX_03 (0x18003094) = 32'hC5258251 + */ + CONSYS_REG_WRITE( + CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_WBG_AFE_01, + 0x0); + CONSYS_REG_WRITE( + CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_WBG_RCK_01, + 0x144B0160); + CONSYS_REG_WRITE( + CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_WBG_GL1_01, + 0x10990C13); + CONSYS_REG_WRITE( + CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_WBG_GL5_01, + 0x10990C13); + CONSYS_REG_WRITE( + CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_WBG_BT_TX_03, + 0xCD258051); + CONSYS_REG_WRITE( + CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_WBG_WF0_TX_03, + 0xC5258251); + CONSYS_REG_WRITE( + CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_WBG_WF1_TX_03, + 0xC5258251); + + /* AFE WBG CAL SEQ1 (RC calibration) */ + /* AFE WBG RC calibration, set "AFE RG_WBG_EN_RCK" = 1 + * Address: CONN_AFE_CTL_RG_DIG_EN_01_RG_WBG_EN_RCK (0x18003000[0]) + * Data: 1'b1 + * Action: write + */ + CONSYS_SET_BIT(CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_01, 0x1); + udelay(60); + /* AFE WBG RC calibration */ + /* AFE WBG RC calibration, set "AFE RG_WBG_EN_RCK" = 0 + * Address: CONN_AFE_CTL_RG_DIG_EN_01_RG_WBG_EN_RCK (0x18003000[0]) + * Data: 1'b0 + * Action: write + */ + CONSYS_CLR_BIT(CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_01, 0x1); + + /* AFE WBG CAL SEQ2 (TX calibration) */ + /* AFE WBG TX calibration, set "AFE RG_WBG_EN_BPLL_UP" = 1 + * Address: CONN_AFE_CTL_RG_DIG_EN_03_RG_WBG_EN_BPLL_UP (0x18003008[21]) + * Data: 1'b1 + * Action: write + */ + CONSYS_SET_BIT(CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_03, (0x1 << 21)); + udelay(30); + /* AFE WBG TX calibration, set "AFE RG_WBG_EN_WPLL_UP" = 1 + * Address: CONN_AFE_CTL_RG_DIG_EN_03_RG_WBG_EN_WPLL_UP (0x18003008[20]) + * Data: 1'b1 + * Action: write + */ + CONSYS_SET_BIT(CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_03, (0x1 << 20)); + udelay(60); + /* AFE WBG TX calibration, set "AFE RG_WBG_EN_TXCAL_BT" = 1 + * Address: CONN_AFE_CTL_RG_DIG_EN_01_RG_WBG_EN_TXCAL_BT (0x18003000[21]) + * Data: 1'b1 + * Action: write + */ + CONSYS_SET_BIT(CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_01, (0x1 << 21)); + /* AFE WBG TX calibration, set "AFE RG_WBG_EN_TXCAL_WF0" = 1 + * Address: CONN_AFE_CTL_RG_DIG_EN_01_RG_WBG_EN_TXCAL_WF0 (0x18003000[20]) + * Data: 1'b1 + * Action: write + */ + CONSYS_SET_BIT(CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_01, (0x1 << 20)); + /* AFE WBG TX calibration, set "AFE RG_WBG_EN_TXCAL_WF1" = 1 + * Address: CONN_AFE_CTL_RG_DIG_EN_01_RG_WBG_EN_TXCAL_WF1 (0x18003000[19]) + * Data: 1'b1 + * Action: write + */ + CONSYS_SET_BIT(CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_01, (0x1 << 19)); + /* AFE WBG TX calibration, set "AFE RG_WBG_EN_TXCAL_WF2" = 1 + * Address: CONN_AFE_CTL_RG_DIG_EN_01_RG_WBG_EN_TXCAL_WF2 (0x18003000[18]) + * Data: 1'b1 + * Action: write + */ + CONSYS_SET_BIT(CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_01, (0x1 << 18)); + /* AFE WBG TX calibration, set "AFE RG_WBG_EN_TXCAL_WF3" = 1 + * Addres: CONN_AFE_CTL_RG_DIG_EN_01_RG_WBG_EN_TXCAL_WF3 (0x18003000[17]) + * Data: 1'b1 + * Action: write + */ + CONSYS_SET_BIT(CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_01, (0x1 << 17)); + udelay(800); + /* AFE WBG TX calibration, set "AFE RG_WBG_EN_TXCAL_BT" = 0 + * Address: CONN_AFE_CTL_RG_DIG_EN_01_RG_WBG_EN_TXCAL_BT (0x18003000[21]) + * Data: 1'b0 + * Action: write + */ + CONSYS_CLR_BIT(CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_01, (0x1 << 21)); + /* AFE WBG TX calibration, set "AFE RG_WBG_EN_TXCAL_WF0" = 0 + * Address: CONN_AFE_CTL_RG_DIG_EN_01_RG_WBG_EN_TXCAL_WF0 (0x18003000[20]) + * Data: 1'b0 + * Action: write + */ + CONSYS_CLR_BIT(CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_01, (0x1 << 20)); + /* AFE WBG TX calibration, set "AFE RG_WBG_EN_TXCAL_WF1" = 0 + * Address: CONN_AFE_CTL_RG_DIG_EN_01_RG_WBG_EN_TXCAL_WF1 (0x18003000[19]) + * Data: 1'b0 + * Action: write + */ + CONSYS_CLR_BIT(CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_01, (0x1 << 19)); + /* AFE WBG TX calibration, set "AFE RG_WBG_EN_TXCAL_WF2" = 0 + * Address: CONN_AFE_CTL_RG_DIG_EN_01_RG_WBG_EN_TXCAL_WF2 (0x18003000[18]) + * Data: 1'b0 + * Action: write + */ + CONSYS_CLR_BIT(CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_01, (0x1 << 18)); + /* AFE WBG TX calibration, set "AFE RG_WBG_EN_TXCAL_WF3" = 0 + * Address: CONN_AFE_CTL_RG_DIG_EN_01_RG_WBG_EN_TXCAL_WF3 (0x18003000[17]) + * Data: 1'b0 + * Action: write + */ + CONSYS_CLR_BIT(CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_01, (0x1 << 17)); + /* AFE WBG TX calibration, set "AFE RG_WBG_EN_BPLL_UP" = 0 + * Address: CONN_AFE_CTL_RG_DIG_EN_03_RG_WBG_EN_BPLL_UP (0x18003008[21]) + * Data: 1'b0 + * Action: write + */ + CONSYS_CLR_BIT(CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_03, (0x1 << 21)); + /* AFE WBG TX calibration, set "AFE RG_WBG_EN_WPLL_UP" = 0 + * Address:i CONN_AFE_CTL_RG_DIG_EN_03_RG_WBG_EN_WPLL_UP (0x18003008[20]) + * Data: 1'b0 + * Action: write + */ + CONSYS_CLR_BIT(CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_03, (0x1 << 20)); + + /* Initial BT path if WF is in cal(need set this CR after WBG cal) + * Address: ATOP RG_ENCAL_WBTAC_IF_SW (0x070) + * Data: 32'h00000005 + * Action: write + */ + consys_spi_write(SYS_SPI_TOP, ATOP_RG_ENCAL_WBTAC_IF_SW, 0x5); + return 0; +} + +int connsys_subsys_pll_initial(void) +{ + /* Check with DE, only 26M on mobile phone */ + /* Set BPLL stable time = 30us (value = 30 * 1000 *1.01 / 38.46ns) + * CONN_AFE_CTL_RG_PLL_STB_TIME_RG_WBG_BPLL_STB_TIME (0x180030F4[30:16]) = 0x314 + * Set WPLL stable time = 50us (value = 50 * 1000 *1.01 / 38.46ns) + * CONN_AFE_CTL_RG_PLL_STB_TIME_RG_WBG_WPLL_STB_TIME (0x180030F4[14:0]) = 0x521 + */ + CONSYS_REG_WRITE_MASK( + CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_PLL_STB_TIME, + 0x03140521, 0x7fff7fff); + + /* BT pll_en will turn on BPLL only (may change in different XTAL option) + * CONN_AFE_CTL_RG_DIG_EN_02_RG_WBG_EN_BT_PLL (0x18003004[7:6])=0x1 + * WF pll_en will turn on BPLL + WPLL only (may change in different XTAL option) + * CONN_AFE_CTL_RG_DIG_EN_02_RG_WBG_EN_WF_PLL (0x18003004[1:0])=0x3 + * MCU pll_en will turn on BPLL + WPLL (may change in different XTAL option) + * CONN_AFE_CTL_RG_DIG_EN_02_RG_WBG_EN_MCU_PLL (0x18003004[3:2])=0x3 + */ + CONSYS_REG_WRITE_MASK( + CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_02, + 0x4f, 0xcf); + + return 0; +} + +// Special setting for BT low power +static int connsys_bt_low_power_setting(bool bt_only) +{ + int hw_version; + const struct a_die_reg_config* config = NULL; + unsigned int ret, i; + + hw_version = CONSYS_REG_READ( + CONN_INFRA_SYSRAM_BASE_ADDR + CONN_INFRA_SYSRAM_SW_CR_A_DIE_CHIP_ID); + + if (bt_only) { + /* E1 */ + if (hw_version == 0x66358A00) { + config = adie_e1_bt_only; + } else if (hw_version == 0x66358A10 || hw_version == 0x66358A11) { + config = adie_e2_bt_only; + } else + pr_err("[%s] wrong adie version (0x%08x)\n", __func__, hw_version); + } else { + if (hw_version == 0x66358A00) { + config = adie_e1_default; + } else if (hw_version == 0x66358A10 || hw_version == 0x66358A11) { + config = adie_e2_default; + } else + pr_err("[%s] wrong adie version (0x%08x)\n", __func__, hw_version); + } + + if (config == NULL) + return -1; + + consys_adie_top_ck_en_on(CONNSYS_ADIE_CTL_HOST_CONNINFRA); + + /* Get semaphore before read */ + if (consys_sema_acquire_timeout(CONN_SEMA_RFSPI_INDEX, CONN_SEMA_TIMEOUT) == CONN_SEMA_GET_FAIL) { + pr_err("[EFUSE READ] Require semaphore fail\n"); + consys_adie_top_ck_en_off(CONNSYS_ADIE_CTL_HOST_CONNINFRA); + return -1; + } + + for (i = 0; i < ADIE_CONFIG_NUM; i++) { + consys_spi_read_nolock(SYS_SPI_TOP, config[i].reg, &ret); + ret &= (~config[i].mask); + ret |= config[i].config; + consys_spi_write_nolock(SYS_SPI_TOP, config[i].reg, ret); + } + + consys_sema_release(CONN_SEMA_RFSPI_INDEX); + + consys_adie_top_ck_en_off(CONNSYS_ADIE_CTL_HOST_CONNINFRA); + + return 0; +} + +void connsys_debug_select_config(void) +{ +#if 1 + /* select conn_infra_cfg debug_sel to low pwoer related + * Address: 0x18001B00[2:0] + * Data: 3'b000 + * Action: write + */ + CONSYS_REG_WRITE_MASK(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_DBG_MUX_SEL, + 0x0, 0x7); +#else + /* select conn_infra_cfg debug_sel to BPLL/WPLL status + * Address: 0x18001B00[2:0] + * Data: 3’b001 + * Action: write + */ + CONSYS_REG_WRITE_MASK(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_DBG_MUX_SEL, + 0x1, 0x7); + { + void __iomem *vir_addr = NULL; + vir_addr = ioremap_nocache(0x18006000, 0x1000); + if (vir_addr) { + /* wpll_rdy/bpll_rdy status dump + * 1.???Set 0x1800_604C = 0xFFFF_FFFF + * 2.???Set 0c1800_6058[1] = 0x1 + * 3.???Set 0x1800_603C = 0x0000_0100 + * 4.???Set 0x1800_601C = 0x0302_0100 + * 5.???Set 0x1800_6020 = 0x0706_0504 + * 6.???Set 0x1800_6024 = 0x0b0a_0908 + * 7.???Set 0x1800_6028 = 0x0f0e_0d0c + * 8.???Set 0x1800_602C = 0x1312_1110 + * 9.???Set 0x1800_6030 = 0x1716_1514 + * 10.??Set 0x1800_6034 = 0x1b1a_1918 + * 11.??Set 0x1800_6038 = 0x1f1e_1d1c + */ + CONSYS_REG_WRITE(vir_addr + 0x004c, 0xffffffff); + CONSYS_SET_BIT(vir_addr + 0x0058, 0x1); + CONSYS_REG_WRITE(vir_addr + 0x3c, 0x00000100); + CONSYS_REG_WRITE(vir_addr + 0x1c, 0x03020100); + CONSYS_REG_WRITE(vir_addr + 0x20, 0x07060504); + CONSYS_REG_WRITE(vir_addr + 0x24, 0x0b0a0908); + CONSYS_REG_WRITE(vir_addr + 0x28, 0x0f0e0d0c); + CONSYS_REG_WRITE(vir_addr + 0x2c, 0x13121110); + CONSYS_REG_WRITE(vir_addr + 0x30, 0x17161514); + CONSYS_REG_WRITE(vir_addr + 0x34, 0x1b1a1918); + CONSYS_REG_WRITE(vir_addr + 0x38, 0x1f1e1d1c); + iounmap(vir_addr); + } else { + pr_err("remap 0x1800_6000 fail\n"); + } + } +#endif + +} + + +int connsys_low_power_setting(unsigned int curr_status, unsigned int next_status) +{ + bool bt_only = false; + + if ((next_status & (~(0x1 << CONNDRV_TYPE_BT))) == 0) + bt_only = true; + + pr_info("[%s] current_status=%d bt_only = %d\n", __func__, curr_status, bt_only); + + /* First subsys on */ + if (curr_status == 0) { + /* Enable AP2CONN GALS Slave sleep protect en with conn_infra on2off/off2on & wfdma2conn + * sleep protect en + * Address: CONN_HOST_CSR_TOP_CONN_SLP_PROT_CTRL_WFDMA2CONN_SLP_PROT_AP2CONN_EN_ENABLE + * CONN_HOST_CSR_TOP_CONN_SLP_PROT_CTRL_CONN_INFRA_ON2OFF_SLP_PROT_AP2CONN_EN_ENABLE + * CONN_HOST_CSR_TOP_CONN_SLP_PROT_CTRL_CONN_INFRA_OFF2ON_SLP_PROT_AP2CONN_EN_ENABLE (0x1806_0184[11:9]) + * Data: 3'b111 + * Action: write + */ + CONSYS_REG_WRITE_MASK( + CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CONN_SLP_PROT_CTRL, + 0xe00, 0xe00); + + /* Unmask on2off/off2on slpprot_rdy enable checker @conn_infra off power off=> check slpprot_rdy = 1'b1 and go to sleep + * Address: CONN_INFRA_CFG_PWRCTRL0_CONN_INFRA_CFG_SLP_RDY_MASK (0x18001860[15:12]) + * Data: 4'h1 + * Action: write + */ + CONSYS_REG_WRITE_MASK( + CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_PWRCTRL0, + 0x1000, 0xf000); + + /* conn_infra low power setting */ + if (!consys_is_rc_mode_enable()) { + /* Default mode (non-RC) */ + /* Disable conn_top rc osc_ctrl_top + * Address: CONN_INFRA_CFG_RC_CTL_0_CONN_INFRA_OSC_RC_EN (0x18001834[7]) + * Data: 1'b0 + * Action: write + */ + CONSYS_CLR_BIT(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_RC_CTL_0, (0x1 << 7)); + /* Legacy OSC control stable time + * Address: + * CONN_INFRA_CFG_OSC_CTL_0_XO_VCORE_RDY_STABLE_TIME (0x18001800[7:0]) = 8'd6 + * CONN_INFRA_CFG_OSC_CTL_0_XO_INI_STABLE_TIME (0x18001800[15:8]) = 8'd7 + * CONN_INFRA_CFG_OSC_CTL_0_XO_BG_STABLE_TIME (0x18001800[23:16]) = 8'd8 + * Action: write + */ + CONSYS_REG_WRITE_MASK( + CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_OSC_CTL_0, 0x080706, 0xffffff); + /* Legacy OSC control unmask conn_srcclkena_ack + * Address: CONN_INFRA_CFG_OSC_CTL_1_ACK_FOR_XO_STATE_MASK (0x18001804[16]) + * Data: 1'b0 + * Action: write + */ + CONSYS_CLR_BIT(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_OSC_CTL_1, (0x1 << 16)); + } else { + /* RC mode */ + /* GPS RC OSC control stable time + * Address: + * CONN_INFRA_CFG_RC_CTL_1_GPS_XO_VCORE_RDY_STABLE_TIME_0 (0x1800183C[7:0]) = 8'd6 + * CONN_INFRA_CFG_RC_CTL_1_GPS_XO_INI_STABLE_TIME_0 (0x1800183C[15:8]) = 8'd7 + * CONN_INFRA_CFG_RC_CTL_1_GPS_XO_BG_STABLE_TIME_0 (0x1800183C[23:16]) = 8'd8 + * CONN_INFRA_CFG_RC_CTL_1_GPS_XO_VCORE_OFF_STABLE_TIME_0 (0x1800183C[31:24]) = 8'd2 + * Action: write + */ + CONSYS_REG_WRITE( + CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_RC_CTL_1_GPS, + 0x02080706); + + /* GPS RC OSC control unmask conn_srcclkena_ack + * Address: CONN_INFRA_CFG_RC_CTL_0_GPS_ACK_FOR_XO_STATE_MASK_0 (0x18001838[15]) + * Data: 1'b0 + * Action: write + */ + CONSYS_CLR_BIT(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_RC_CTL_0_GPS, (0x1 << 15)); + + /* BT RC OSC control stable time + * Address: + * CONN_INFRA_CFG_RC_CTL_1_BT_XO_VCORE_RDY_STABLE_TIME_1 (0x18001844[7:0]) = 8'd6 + * CONN_INFRA_CFG_RC_CTL_1_BT_XO_INI_STABLE_TIME_1 (0x18001844[15:8]) = 8'd7 + * CONN_INFRA_CFG_RC_CTL_1_BT_XO_BG_STABLE_TIME_1 (0x18001844[23:16]) = 8'd8 + * CONN_INFRA_CFG_RC_CTL_1_BT_XO_VCORE_OFF_STABLE_TIME_1 (0x18001844[31:24]) = 8'd2 + * Action: write + */ + CONSYS_REG_WRITE( + CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_RC_CTL_1_BT, + 0x02080706); + + /* BT RC OSC control unmask conn_srcclkena_ack + * Address: CONN_INFRA_CFG_RC_CTL_0_BT_ACK_FOR_XO_STATE_MASK_1 (0x18001840[15]) + * Data: 1'b0 + * Action: write + */ + CONSYS_CLR_BIT(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_RC_CTL_0_BT, (0x1 << 15)); + + /* WF RC OSC control stable time + * Address: + * CONN_INFRA_CFG_RC_CTL_1_WF_XO_VCORE_RDY_STABLE_TIME_2 (0x1800184C[7:0]) = 8'd6 + * CONN_INFRA_CFG_RC_CTL_1_WF_XO_INI_STABLE_TIME_2 (0x1800184C[15:8]) = 8'd7 + * CONN_INFRA_CFG_RC_CTL_1_WF_XO_BG_STABLE_TIME_2 (0x1800184C[23:16]) = 8'd8 + * CONN_INFRA_CFG_RC_CTL_1_WF_XO_VCORE_OFF_STABLE_TIME_2 (0x1800184C[31:24])= 8'd2 + * Action: write + */ + CONSYS_REG_WRITE( + CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_RC_CTL_1_WF, + 0x02080706); + + /* WF RC OSC control unmask conn_srcclkena_ack + * Address: CONN_INFRA_CFG_RC_CTL_0_WF_ACK_FOR_XO_STATE_MASK_2 (0x18001848[15]) + * Data: 1'b0 + * Action: write + */ + CONSYS_CLR_BIT(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_RC_CTL_0_WF, (0x1 << 15)); + + /* TOP RC OSC control stable time + * Address: + * CONN_INFRA_CFG_RC_CTL_1_TOP_XO_VCORE_RDY_STABLE_TIME_3 (0x18001854[7:0]) = 8'd6 + * CONN_INFRA_CFG_RC_CTL_1_TOP_XO_INI_STABLE_TIME_3 (0x18001854[15:8]) = 8'd7 + * CONN_INFRA_CFG_RC_CTL_1_TOP_XO_BG_STABLE_TIME_3 (0x18001854[23:16]) = 8'd8 + * CONN_INFRA_CFG_RC_CTL_1_TOP_XO_VCORE_OFF_STABLE_TIME_3 (0x18001854[31:24]) = 8'd2 + * Action: write + */ + CONSYS_REG_WRITE( + CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_RC_CTL_1_TOP, + 0x02080706); + + /* TOP RC OSC control unmask conn_srcclkena_ack + * Address: CONN_INFRA_CFG_RC_CTL_0_TOP_ACK_FOR_XO_STATE_MASK_3 (0x18001850[15]) + * Data: 1'b0 + * Action: write + */ + CONSYS_CLR_BIT( + CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_RC_CTL_0_TOP, + (0x1 << 15)); + + /* Enable conn_top rc osc_ctrl_gps + * Address: CONN_INFRA_CFG_RC_CTL_0_GPSSYS_OSC_RC_EN (0x18001834[4]) + * Data: 1'b1 + * Action: write + */ + CONSYS_SET_BIT( + CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_RC_CTL_0, + (0x1 << 4)); + + /* Enable conn_top rc osc_ctrl_bt + * Address: CONN_INFRA_CFG_RC_CTL_0_BTSYS_OSC_RC_EN (0x18001834[5]) + * Data: 1'b1 + * Action: write + */ + CONSYS_SET_BIT( + CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_RC_CTL_0, + (0x1 << 5)); + + /* Enable conn_top rc osc_ctrl_wf + * Address: CONN_INFRA_CFG_RC_CTL_0_WFSYS_OSC_RC_EN (0x18001834[6]) + * Data: 1'b1 + * Action: write + */ + CONSYS_SET_BIT( + CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_RC_CTL_0, + (0x1 << 6)); + + /* set conn_srcclkena control by conn_infra_emi_ctl + * Address: CONN_INFRA_CFG_EMI_CTL_0_CONN_EMI_RC_EN (0x18001C00[0]) + * Data: 1'b1 + * Action: write + */ + CONSYS_SET_BIT( + CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_EMI_CTL_0, 0x1); + + /* Disable legacy osc control + * Address: CONN_INFRA_CFG_RC_CTL_0_OSC_LEGACY_EN (0x18001834[0]) + * Data: 1'b0 + * Action: write + */ + CONSYS_CLR_BIT( + CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_RC_CTL_0, + 0x1); + } + /* conn2ap sleep protect release bypass ddr_en_ack check + * Address: CONN_INFRA_CFG_EMI_CTL_0_EMI_SLPPROT_BP_DDR_EN (0x18001C00[18]) + * Data: 1'b1 + * Action: write + */ + CONSYS_SET_BIT(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_EMI_CTL_0, 0x40000); + + /* Enable ddr_en timeout, timeout value = 1023 T (Bus clock) + * Address: CONN_INFRA_CFG_EMI_CTL_0_DDR_CNT_LIMIT (0x18001C00[14:4]) + * Data: 11'd1023 + * Action: write + */ + CONSYS_REG_WRITE_MASK( + CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_EMI_CTL_0, + 0x3ff0, 0x7ff0); + + /* A-die clock buffer setting for BT only and others mode */ + connsys_bt_low_power_setting(bt_only); + + /* Enable conn_infra_clkgen BPLL source (hw workaround) + * Address: CONN_INFRA_CFG_CKGEN_BUS_RFSPI_DIV_EN (0x1800_1A00[28]) + * Data: 1'b1 + * Action: write + */ + CONSYS_SET_BIT(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_CKGEN_BUS, (0x1 << 28)); + + /* Bus light security + * Address: + * CONN_INFRA_CFG_LIGHT_SECURITY_CTRL_R_CONN_INFRA_BT_PAIR1_EN + * CONN_INFRA_CFG_LIGHT_SECURITY_CTRL_R_CONN_INFRA_BT_PAIR0_EN + * CONN_INFRA_CFG_LIGHT_SECURITY_CTRL_R_CONN_INFRA_WF_PAIR1_EN + * CONN_INFRA_CFG_LIGHT_SECURITY_CTRL_R_CONN_INFRA_WF_PAIR0_EN + * 0x1800_10F0[4][3][1][0] = 6'h1B + * Action: write + */ + CONSYS_REG_WRITE_MASK( + CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_LIGHT_SECURITY_CTRL, + ((0x1 << 4) | (0x1 << 3) | (0x1 << 1) | 0x1), + ((0x1 << 4) | (0x1 << 3) | (0x1 << 1) | 0x1)); + + /* if(BT on or GPS on) + * Conn_infrapower on bgfsys on (woraround) + * Address: + * 0x18000008[31:16] = 16'h4254 (key) + * CONN_INFRA_RGU_BGFSYS_ON_TOP_PWR_CTL[7] (0x18000008[7]) = 1'b1 + * Action: write + */ + /* Check with DE, write 1 -> 1 is ok */ + if ((next_status & ((0x1 << CONNDRV_TYPE_BT) | (0x1 << CONNDRV_TYPE_GPS))) != 0) { + CONSYS_REG_WRITE_MASK( + CON_REG_INFRA_RGU_ADDR + CONN_INFRA_RGU_BGFSYS_ON_TOP_PWR_CTL, + ((0x42540000) | (0x1 << 7)), 0xffff0080); + } + + consys_config_setup(); + connsys_debug_select_config(); + /* + * set 0x1800_0090 = 4'h6 + */ + CONSYS_REG_WRITE(CON_REG_INFRA_RGU_ADDR + CONN_INFRA_RGU_DEBUG_SEL, 0x6); + + /******************************************************/ + /* power ctrl : 0x1800_1860[9] = 1'b1 */ + /******************************************************/ + CONSYS_SET_BIT(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_PWRCTRL0, 0x200); + + /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ + /* !!!!!!!!!!!!!!!!!!!!!! CANNOT add code after HERE!!!!!!!!!!!!!!!!!!!!!!!!!! */ + /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ + + /* Disable conn_infra bus clock sw control ==> conn_infra bus clock hw control + * Address: CONN_INFRA_CFG_CKGEN_BUS_HCLK_CKSEL_SWCTL (0x1800_1A00[23]) + * Data: 1'b0 + * Action: write + */ + CONSYS_CLR_BIT(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_CKGEN_BUS, (0x1 << 23)); + + /* Conn_infra HW_CONTROL => conn_infra enter dsleep mode + * Address: CONN_INFRA_CFG_PWRCTRL0_HW_CONTROL (0x1800_1860[0]) + * Data: 1'b1 + * Action: write + * Note: enable conn_infra off domain as HW control + */ + CONSYS_SET_BIT(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_PWRCTRL0, 0x1); + } else { + /* for subsys on/off, only update BT low power setting */ + connsys_bt_low_power_setting(bt_only); + + /* Workaround */ + if ((next_status & ((0x1 << CONNDRV_TYPE_BT) | (0x1 << CONNDRV_TYPE_GPS))) != 0) { + CONSYS_REG_WRITE_MASK( + CON_REG_INFRA_RGU_ADDR + CONN_INFRA_RGU_BGFSYS_ON_TOP_PWR_CTL, + ((0x42540000) | (0x1 << 7)), 0xffff0080); + } else { + CONSYS_REG_WRITE_MASK( + CON_REG_INFRA_RGU_ADDR + CONN_INFRA_RGU_BGFSYS_ON_TOP_PWR_CTL, + 0x42540000, 0xffff0080); + } + + consys_config_setup(); + connsys_debug_select_config(); + } + /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ + /* !!!!!!!!!!!!!!!!!!!!!!!!CANNOT add code HERE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ + /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ + + return 0; +} + +static int consys_sema_acquire(unsigned int index) +{ + if (CONSYS_REG_READ_BIT( + CONN_REG_SEMAPHORE_ADDR + CONN_SEMAPHORE_M2_OWN_STA + index*4, 0x1) == 0x1) { + return CONN_SEMA_GET_SUCCESS; + } else { + return CONN_SEMA_GET_FAIL; + } +} + +int consys_sema_acquire_timeout(unsigned int index, unsigned int usec) +{ + int i, check, r1, r2; + + if (index >= CONN_SEMA_NUM_MAX) { + pr_err("[%s] wrong parameter: %d", __func__, index); + return CONN_SEMA_GET_FAIL; + } + + /* debug for bus hang */ + if (consys_reg_mng_reg_readable() == 0) { + check = consys_reg_mng_is_bus_hang(); + if (check > 0) { + r1 = CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_DBG_DUMMY_3); + r2 = CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CONN_INFRA_WAKEPU_TOP_CONN_INFRA_WAKEPU_TOP); + pr_info("[%s] check=[%d] r1=[0x%x] r2=[0x%x]", __func__, check, r1, r2); + consys_reg_mng_dump_bus_status(); + consys_reg_mng_dump_cpupcr(CONN_DUMP_CPUPCR_TYPE_ALL, 10, 200); + return CONN_SEMA_GET_FAIL; + } + } + + for (i = 0; i < usec; i++) { + if (consys_sema_acquire(index) == CONN_SEMA_GET_SUCCESS) { + return CONN_SEMA_GET_SUCCESS; + } + udelay(1); + } + + pr_err("Get semaphore 0x%x timeout, dump status:\n", index); + pr_err("M0:[0x%x] M1:[0x%x] M2:[0x%x] M3:[0x%x]\n", + CONSYS_REG_READ(CONN_REG_SEMAPHORE_ADDR + CONN_SEMA_OWN_BY_M0_STA_REP), + CONSYS_REG_READ(CONN_REG_SEMAPHORE_ADDR + CONN_SEMA_OWN_BY_M1_STA_REP), + CONSYS_REG_READ(CONN_REG_SEMAPHORE_ADDR + CONN_SEMA_OWN_BY_M2_STA_REP), + CONSYS_REG_READ(CONN_REG_SEMAPHORE_ADDR + CONN_SEMA_OWN_BY_M3_STA_REP)); + consys_reg_mng_dump_cpupcr(CONN_DUMP_CPUPCR_TYPE_ALL, 10, 200); + + return CONN_SEMA_GET_FAIL; +} + +void consys_sema_release(unsigned int index) +{ + if (index >= CONN_SEMA_NUM_MAX) + return; + CONSYS_REG_WRITE( + (CONN_REG_SEMAPHORE_ADDR + CONN_SEMAPHORE_M2_OWN_REL + index*4), 0x1); +} + +struct spi_op { + unsigned int busy_cr; + unsigned int polling_bit; + unsigned int addr_cr; + unsigned int read_addr_format; + unsigned int write_addr_format; + unsigned int write_data_cr; + unsigned int read_data_cr; + unsigned int read_data_mask; +}; + +static const struct spi_op spi_op_array[SYS_SPI_MAX] = { + /* SYS_SPI_WF1 */ + { + CONN_RF_SPI_MST_REG_SPI_STA, 1, + CONN_RF_SPI_MST_REG_SPI_WF_ADDR, 0x00001000, 0x00000000, + CONN_RF_SPI_MST_REG_SPI_WF_WDAT, + CONN_RF_SPI_MST_REG_SPI_WF_RDAT, 0xffffffff + }, + /* SYS_SPI_WF */ + { + CONN_RF_SPI_MST_REG_SPI_STA, 1, + CONN_RF_SPI_MST_REG_SPI_WF_ADDR, 0x00003000, 0x00002000, + CONN_RF_SPI_MST_REG_SPI_WF_WDAT, + CONN_RF_SPI_MST_REG_SPI_WF_RDAT, 0xffffffff + }, + /* SYS_SPI_BT */ + { + CONN_RF_SPI_MST_REG_SPI_STA, 2, + CONN_RF_SPI_MST_REG_SPI_BT_ADDR, 0x00005000, 0x00004000, + CONN_RF_SPI_MST_REG_SPI_BT_WDAT, + CONN_RF_SPI_MST_REG_SPI_BT_RDAT, 0x000000ff + }, + /* SYS_SPI_FM */ + { + CONN_RF_SPI_MST_REG_SPI_STA, 3, + CONN_RF_SPI_MST_REG_SPI_FM_ADDR, 0x00007000, 0x00006000, + CONN_RF_SPI_MST_REG_SPI_FM_WDAT, + CONN_RF_SPI_MST_REG_SPI_FM_RDAT, 0x0000ffff + }, + /* SYS_SPI_GPS */ + { + CONN_RF_SPI_MST_REG_SPI_STA, 4, + CONN_RF_SPI_MST_REG_SPI_GPS_GPS_ADDR, 0x00009000, 0x00008000, + CONN_RF_SPI_MST_REG_SPI_GPS_GPS_WDAT, + CONN_RF_SPI_MST_REG_SPI_GPS_GPS_RDAT, 0x0000ffff + }, + /* SYS_SPI_TOP */ + { + CONN_RF_SPI_MST_REG_SPI_STA, 5, + CONN_RF_SPI_MST_REG_SPI_TOP_ADDR, 0x0000b000, 0x0000a000, + CONN_RF_SPI_MST_REG_SPI_TOP_WDAT, + CONN_RF_SPI_MST_REG_SPI_TOP_RDAT, 0xffffffff + }, + /* SYS_SPI_WF2 */ + { + CONN_RF_SPI_MST_REG_SPI_STA, 1, + CONN_RF_SPI_MST_REG_SPI_WF_ADDR, 0x0000d000, 0x0000c000, + CONN_RF_SPI_MST_REG_SPI_WF_WDAT, + CONN_RF_SPI_MST_REG_SPI_WF_RDAT, 0xffffffff + }, + /* SYS_SPI_WF3 */ + { + CONN_RF_SPI_MST_REG_SPI_STA, 1, + CONN_RF_SPI_MST_REG_SPI_WF_ADDR, 0x0000f000, 0x0000e000, + CONN_RF_SPI_MST_REG_SPI_WF_WDAT, + CONN_RF_SPI_MST_REG_SPI_WF_RDAT, 0xffffffff + }, +}; + +static int consys_spi_read_nolock(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int *data) +{ + /* Read action: + * 1. Polling busy_cr[polling_bit] should be 0 + * 2. Write addr_cr with data being {read_addr_format | addr[11:0]} + * 3. Trigger SPI by writing write_data_cr as 0 + * 4. Polling busy_cr[polling_bit] as 0 + * 5. Read data_cr[data_mask] + */ + int check = 0; + const struct spi_op* op = &spi_op_array[subsystem]; + + if (!data) { + pr_err("[%s] invalid data ptr\n", __func__); + return CONNINFRA_SPI_OP_FAIL; + } + + CONSYS_REG_BIT_POLLING( + CONN_REG_RFSPI_ADDR + op->busy_cr, + op->polling_bit, 0, 100, 50, check); + if (check != 0) { + pr_err("[%s][%d][STEP1] polling 0x%08x bit %d fail. Value=0x%08x\n", + __func__, subsystem, CONN_REG_RFSPI_ADDR + op->busy_cr, + op->polling_bit, + CONSYS_REG_READ(CONN_REG_RFSPI_ADDR + op->busy_cr)); + return CONNINFRA_SPI_OP_FAIL; + } + + CONSYS_REG_WRITE( + CONN_REG_RFSPI_ADDR + op->addr_cr, + (op->read_addr_format | addr)); + + CONSYS_REG_WRITE(CONN_REG_RFSPI_ADDR + op->write_data_cr, 0); + + check = 0; + CONSYS_REG_BIT_POLLING( + CONN_REG_RFSPI_ADDR + op->busy_cr, + op->polling_bit, 0, 100, 50, check); + if (check != 0) { + pr_err("[%s][%d][STEP4] polling 0x%08x bit %d fail. Value=0x%08x\n", + __func__, subsystem, CONN_REG_RFSPI_ADDR + op->busy_cr, + op->polling_bit, + CONSYS_REG_READ(CONN_REG_RFSPI_ADDR + op->busy_cr)); + return CONNINFRA_SPI_OP_FAIL; + } + + check = CONSYS_REG_READ_BIT(CONN_REG_RFSPI_ADDR + op->read_data_cr, op->read_data_mask); + *data = check; + + return 0; +} + +int consys_spi_read(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int *data) +{ + int ret; + + /* Get semaphore before read */ + if (consys_sema_acquire_timeout(CONN_SEMA_RFSPI_INDEX, CONN_SEMA_TIMEOUT) == CONN_SEMA_GET_FAIL) { + pr_err("[SPI READ] Require semaphore fail\n"); + return CONNINFRA_SPI_OP_FAIL; + } + + ret = consys_spi_read_nolock(subsystem, addr, data); + + consys_sema_release(CONN_SEMA_RFSPI_INDEX); + + return ret; +} + +static int consys_spi_write_nolock(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int data) +{ + int check = 0; + const struct spi_op* op = &spi_op_array[subsystem]; + + /* Write action: + * 1. Wait busy_cr[polling_bit] as 0 + * 2. Write addr_cr with data being {write_addr_format | addr[11:0] + * 3. Write write_data_cr ad data + * 4. Wait busy_cr[polling_bit] as 0 + */ + CONSYS_REG_BIT_POLLING( + CONN_REG_RFSPI_ADDR + op->busy_cr, + op->polling_bit, 0, 100, 50, check); + if (check != 0) { + pr_err("[%s][%d][STEP1] polling 0x%08x bit %d fail. Value=0x%08x\n", + __func__, subsystem, CONN_REG_RFSPI_ADDR + op->busy_cr, + op->polling_bit, + CONSYS_REG_READ(CONN_REG_RFSPI_ADDR + op->busy_cr)); + return CONNINFRA_SPI_OP_FAIL; + } + + CONSYS_REG_WRITE(CONN_REG_RFSPI_ADDR + op->addr_cr, (op->write_addr_format | addr)); + + CONSYS_REG_WRITE(CONN_REG_RFSPI_ADDR + op->write_data_cr, data); + + check = 0; + CONSYS_REG_BIT_POLLING( + CONN_REG_RFSPI_ADDR + op->busy_cr, + op->polling_bit, 0, 100, 50, check); + if (check != 0) { + pr_err("[%s][%d][STEP4] polling 0x%08x bit %d fail. Value=0x%08x\n", + __func__, subsystem, CONN_REG_RFSPI_ADDR + op->busy_cr, + op->polling_bit, + CONSYS_REG_READ(CONN_REG_RFSPI_ADDR + op->busy_cr)); + return CONNINFRA_SPI_OP_FAIL; + } + + return 0; +} + + +int consys_spi_write(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int data) +{ + int ret; + + /* Get semaphore before read */ + if (consys_sema_acquire_timeout(CONN_SEMA_RFSPI_INDEX, CONN_SEMA_TIMEOUT) == CONN_SEMA_GET_FAIL) { + pr_err("[SPI WRITE] Require semaphore fail\n"); + return CONNINFRA_SPI_OP_FAIL; + } + + ret = consys_spi_write_nolock(subsystem, addr, data); + + consys_sema_release(CONN_SEMA_RFSPI_INDEX); + return ret; +} + +int consys_spi_write_offset_range( + enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int value, + unsigned int reg_offset, unsigned int value_offset, unsigned int size) +{ + if (consys_sema_acquire_timeout(CONN_SEMA_RFSPI_INDEX, CONN_SEMA_TIMEOUT) == CONN_SEMA_GET_FAIL) { + pr_err("[SPI READ] Require semaphore fail\n"); + return CONNINFRA_SPI_OP_FAIL; + } + consys_spi_write_offset_range_nolock( + subsystem, addr, value, reg_offset, value_offset, size); + + consys_sema_release(CONN_SEMA_RFSPI_INDEX); + return 0; +} + +static void consys_spi_write_offset_range_nolock( + enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int value, + unsigned int reg_offset, unsigned int value_offset, unsigned int size) +{ + unsigned int data = 0, data2; + unsigned int reg_mask; + int ret; + + pr_info("[%s][%s] addr=0x%04x value=0x%08x reg_offset=%d value_offset=%d size=%d", + __func__, get_spi_sys_name(subsystem), addr, value, reg_offset, value_offset, size); + value = (value >> value_offset); + value = GET_BIT_RANGE(value, size, 0); + value = (value << reg_offset); + ret = consys_spi_read_nolock(subsystem, addr, &data); + if (ret) { + pr_err("[%s][%s] Get 0x%08x error, ret=%d", + __func__, get_spi_sys_name(subsystem), addr, ret); + return; + } + reg_mask = GENMASK(reg_offset + size - 1, reg_offset); + data2 = data & (~reg_mask); + data2 = (data2 | value); + consys_spi_write_nolock(subsystem, addr, data2); + pr_info("[%s][%s] Write CR:0x%08x from 0x%08x to 0x%08x", + __func__, get_spi_sys_name(subsystem), + addr, data, data2); +} + + +static int consys_adie_top_ck_en_ctrl(bool on) +{ + int check = 0; + + if (on) + CONSYS_SET_BIT(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_ADIE_CTL, (0x1 << 1)); + else + CONSYS_CLR_BIT(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_ADIE_CTL, (0x1 << 1)); + + CONSYS_REG_BIT_POLLING( + CON_REG_WT_SPL_CTL_ADDR + CONN_WTSLP_CTL_REG_WB_STA, + 26, 0, 100, 5, check); + if (check == -1) { + pr_err("[%s] op=%d fail\n", __func__, on); + } + return check; + +} + +int consys_adie_top_ck_en_on(enum consys_adie_ctl_type type) +{ + unsigned int status; + int ret; + + if (type >= CONNSYS_ADIE_CTL_MAX) { + pr_err("[%s] invalid parameter(%d)\n", __func__, type); + return -1; + } + + if (consys_sema_acquire_timeout(CONN_SEMA_CONN_INFRA_COMMON_SYSRAM_INDEX, CONN_SEMA_TIMEOUT) == CONN_SEMA_GET_FAIL) { + pr_err("[%s][%s] acquire semaphore (%d) timeout\n", + __func__, get_adie_ctrl_type_str(type), CONN_SEMA_CONN_INFRA_COMMON_SYSRAM_INDEX); + return -1; + } + + status = CONSYS_REG_READ( + CONN_INFRA_SYSRAM_BASE_ADDR + CONN_INFRA_SYSRAM_SW_CR_A_DIE_TOP_CK_EN_CTRL); + if ((status & CONN_INFRA_SYSRAM__A_DIE_DIG_TOP_CK_EN_MASK) == 0) { + ret = consys_adie_top_ck_en_ctrl(true); + } + CONSYS_SET_BIT( + CONN_INFRA_SYSRAM_BASE_ADDR + CONN_INFRA_SYSRAM_SW_CR_A_DIE_TOP_CK_EN_CTRL, (0x1 << type)); + + consys_sema_release(CONN_SEMA_CONN_INFRA_COMMON_SYSRAM_INDEX); + return 0; +} + +int consys_adie_top_ck_en_off(enum consys_adie_ctl_type type) +{ + unsigned int status; + int ret = 0; + + if (type >= CONNSYS_ADIE_CTL_MAX) { + pr_err("[%s] invalid parameter(%d)\n", __func__, type); + return -1; + } + + if (consys_sema_acquire_timeout(CONN_SEMA_CONN_INFRA_COMMON_SYSRAM_INDEX, CONN_SEMA_TIMEOUT) == CONN_SEMA_GET_FAIL) { + pr_err("[%s][%s] acquire semaphoreaore (%d) timeout\n", + __func__, get_adie_ctrl_type_str(type), CONN_SEMA_CONN_INFRA_COMMON_SYSRAM_INDEX); + return -1; + } + + status = CONSYS_REG_READ( + CONN_INFRA_SYSRAM_BASE_ADDR + CONN_INFRA_SYSRAM_SW_CR_A_DIE_TOP_CK_EN_CTRL); + if ((status & (0x1 << type)) == 0) { + pr_warn("[%s][%s] already off\n", __func__, get_adie_ctrl_type_str(type)); + } else { + CONSYS_CLR_BIT( + CONN_INFRA_SYSRAM_BASE_ADDR + CONN_INFRA_SYSRAM_SW_CR_A_DIE_TOP_CK_EN_CTRL, (0x1 << type)); + + status = CONSYS_REG_READ( + CONN_INFRA_SYSRAM_BASE_ADDR + CONN_INFRA_SYSRAM_SW_CR_A_DIE_TOP_CK_EN_CTRL); + if (0 == (status & CONN_INFRA_SYSRAM__A_DIE_DIG_TOP_CK_EN_MASK)) { + ret = consys_adie_top_ck_en_ctrl(false); + } + } + + consys_sema_release(CONN_SEMA_CONN_INFRA_COMMON_SYSRAM_INDEX); + return ret; +} + +int consys_spi_clock_switch(enum connsys_spi_speed_type type) +{ +#define MAX_SPI_CLOCK_SWITCH_COUNT 100 + unsigned int status; + unsigned int counter = 0; + int ret = 0; + + /* Get semaphore before read */ + if (consys_sema_acquire_timeout(CONN_SEMA_RFSPI_INDEX, CONN_SEMA_TIMEOUT) == CONN_SEMA_GET_FAIL) { + pr_err("[SPI CLOCK SWITCH] Require semaphore fail\n"); + return -1; + } + + if (type == CONNSYS_SPI_SPEED_26M) { + CONSYS_REG_WRITE_MASK( + CONN_REG_RFSPI_ADDR + CONN_RF_SPI_MST_REG_SPI_CRTL, + 0x0, 0x5); + status = CONSYS_REG_READ(CONN_REG_RFSPI_ADDR + CONN_RF_SPI_MST_REG_SPI_CRTL) & 0x18; + while (status != 0x8 && counter < MAX_SPI_CLOCK_SWITCH_COUNT) { + udelay(10); + status = CONSYS_REG_READ(CONN_REG_RFSPI_ADDR + CONN_RF_SPI_MST_REG_SPI_CRTL) & 0x18; + counter++; + } + if (counter == MAX_SPI_CLOCK_SWITCH_COUNT) { + pr_err("[%s] switch to 26M fail\n", __func__); + ret = -1; + } + } else if (type == CONNSYS_SPI_SPEED_64M) { + CONSYS_REG_WRITE_MASK( + CONN_REG_RFSPI_ADDR + CONN_RF_SPI_MST_REG_SPI_CRTL, 0x5, 0x5); + status = CONSYS_REG_READ(CONN_REG_RFSPI_ADDR + CONN_RF_SPI_MST_REG_SPI_CRTL) & 0x18; + while (status != 0x10 && counter < MAX_SPI_CLOCK_SWITCH_COUNT) { + udelay(10); + status = CONSYS_REG_READ(CONN_REG_RFSPI_ADDR + CONN_RF_SPI_MST_REG_SPI_CRTL) & 0x18; + counter++; + } + if (counter == MAX_SPI_CLOCK_SWITCH_COUNT) { + pr_err("[%s] switch to 64M fail\n", __func__); + ret = -1; + } + } else { + ret = -1; + pr_err("[%s] wrong parameter %d\n", __func__, type); + } + + consys_sema_release(CONN_SEMA_RFSPI_INDEX); + + return ret; +} + +int consys_subsys_status_update(bool on, int radio) +{ + if (radio < CONNDRV_TYPE_BT || radio > CONNDRV_TYPE_WIFI) { + pr_err("[%s] wrong parameter: %d\n", __func__, radio); + return -1; + } + + if (consys_sema_acquire_timeout(CONN_SEMA_CONN_INFRA_COMMON_SYSRAM_INDEX, CONN_SEMA_TIMEOUT) == CONN_SEMA_GET_FAIL) { + pr_err("[%s] acquire semaphore (%d) timeout\n", + __func__, CONN_SEMA_CONN_INFRA_COMMON_SYSRAM_INDEX); + return -1; + } + + if (on) { + CONSYS_SET_BIT( + CONN_INFRA_SYSRAM_BASE_ADDR + CONN_INFRA_SYSRAM_SW_CR_RADIO_STATUS, + (0x1 << radio)); + } else { + CONSYS_CLR_BIT( + CONN_INFRA_SYSRAM_BASE_ADDR + CONN_INFRA_SYSRAM_SW_CR_RADIO_STATUS, + (0x1 << radio)); + } + + consys_sema_release(CONN_SEMA_CONN_INFRA_COMMON_SYSRAM_INDEX); + return 0; +} + + +bool consys_is_rc_mode_enable(void) +{ + int ret; + + ret = CONSYS_REG_READ_BIT(CON_REG_SPM_BASE_ADDR + SPM_RC_CENTRAL_CFG1, 0x1); + + return ret; +} + +void consys_config_setup(void) +{ + /* To access CR in conninfra off domain, Conninfra should be on state */ + /* Enable conn_infra bus hang detect function + * Address: 0x1800_F000 + * Data: 32'h32C8_001C + * Action: write + */ + CONSYS_REG_WRITE(CONN_DEBUG_CTRL_ADDR + CONN_DEBUG_CTRL_REG_OFFSET, 0x32c8001c); +} diff --git a/drivers/misc/mediatek/connectivity/conninfra/platform/pmic_mng.c b/drivers/misc/mediatek/connectivity/conninfra/platform/pmic_mng.c new file mode 100755 index 0000000000000000000000000000000000000000..433f5b9995e95434808d64b90166fb22426d188d --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/platform/pmic_mng.c @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#include "pmic_mng.h" + +#include "osal.h" +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +P_CONSYS_PLATFORM_PMIC_OPS consys_platform_pmic_ops; + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +P_CONSYS_PLATFORM_PMIC_OPS __weak get_consys_platform_pmic_ops(void) +{ + pr_err("No specify project\n"); + return NULL; +} + + +int pmic_mng_init(struct platform_device *pdev, struct conninfra_dev_cb* dev_cb) +{ + if (consys_platform_pmic_ops == NULL) + consys_platform_pmic_ops = get_consys_platform_pmic_ops(); + + if (consys_platform_pmic_ops && consys_platform_pmic_ops->consys_pmic_get_from_dts) + consys_platform_pmic_ops->consys_pmic_get_from_dts(pdev, dev_cb); + + return 0; +} + +int pmic_mng_deinit(void) +{ + return 0; +} + +int pmic_mng_common_power_ctrl(unsigned int enable) +{ + int ret = 0; + if (consys_platform_pmic_ops && + consys_platform_pmic_ops->consys_pmic_common_power_ctrl) + ret = consys_platform_pmic_ops->consys_pmic_common_power_ctrl(enable); + return ret; +} + +int pmic_mng_wifi_power_ctrl(unsigned int enable) +{ + int ret = 0; + if (consys_platform_pmic_ops && + consys_platform_pmic_ops->consys_pmic_wifi_power_ctrl) + ret = consys_platform_pmic_ops->consys_pmic_wifi_power_ctrl(enable); + return ret; + +} + +int pmic_mng_bt_power_ctrl(unsigned int enable) +{ + int ret = 0; + if (consys_platform_pmic_ops && + consys_platform_pmic_ops->consys_pmic_bt_power_ctrl) + ret = consys_platform_pmic_ops->consys_pmic_bt_power_ctrl(enable); + return ret; +} + +int pmic_mng_gps_power_ctrl(unsigned int enable) +{ + int ret = 0; + if (consys_platform_pmic_ops && + consys_platform_pmic_ops->consys_pmic_gps_power_ctrl) + ret = consys_platform_pmic_ops->consys_pmic_gps_power_ctrl(enable); + return ret; +} + +int pmic_mng_fm_power_ctrl(unsigned int enable) +{ + int ret = 0; + if (consys_platform_pmic_ops && + consys_platform_pmic_ops->consys_pmic_fm_power_ctrl) + ret = consys_platform_pmic_ops->consys_pmic_fm_power_ctrl(enable); + return ret; +} + + +int pmic_mng_event_cb(unsigned int id, unsigned int event) +{ + if (consys_platform_pmic_ops && + consys_platform_pmic_ops->consys_pmic_event_notifier) + consys_platform_pmic_ops->consys_pmic_event_notifier(id, event); + return 0; +} diff --git a/drivers/misc/mediatek/connectivity/conninfra/src/conninfra.c b/drivers/misc/mediatek/connectivity/conninfra/src/conninfra.c new file mode 100755 index 0000000000000000000000000000000000000000..ec09c08ec4923c8f2cc7c0f86a07091ae90556b2 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/src/conninfra.c @@ -0,0 +1,316 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#define pr_fmt(fmt) KBUILD_MODNAME "@(%s:%d) " fmt, __func__, __LINE__ + +#include +#include +#include +#include +#include +#include +#include "conninfra.h" +#include "emi_mng.h" +#include "conninfra_core.h" +#include "consys_hw.h" + +#include + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +#define CONNINFRA_RST_RATE_LIMIT 0 + +#if CONNINFRA_RST_RATE_LIMIT +DEFINE_RATELIMIT_STATE(g_rs, HZ, 1); + +#define DUMP_LOG() if (__ratelimit(&g_rs)) \ + pr_info("rst is ongoing") + +#else +#define DUMP_LOG() +#endif + +struct conninfra_rst_data { + struct work_struct rst_worker; + enum consys_drv_type drv; + char *reason; +}; + +struct conninfra_rst_data rst_data; + +int conninfra_get_clock_schematic(void) +{ + return consys_hw_get_clock_schematic(); +} +EXPORT_SYMBOL(conninfra_get_clock_schematic); + +void conninfra_get_phy_addr(unsigned int *addr, unsigned int *size) +{ + phys_addr_t base; + + conninfra_get_emi_phy_addr(CONNSYS_EMI_FW, &base, size); + if (addr) + *addr = (unsigned int)base; + return; +} +EXPORT_SYMBOL(conninfra_get_phy_addr); + +void conninfra_get_emi_phy_addr(enum connsys_emi_type type, phys_addr_t* base, unsigned int *size) +{ + struct consys_emi_addr_info* addr_info = emi_mng_get_phy_addr(); + + switch (type) { + case CONNSYS_EMI_FW: + if (base) + *base = addr_info->emi_ap_phy_addr; + if (size) + *size = addr_info->emi_size; + break; + case CONNSYS_EMI_MCIF: + if (base) + *base = addr_info->md_emi_phy_addr; + if (size) + *size = addr_info->md_emi_size; + break; + default: + pr_err("Wrong EMI type: %d\n", type); + if (base) + *base = 0x0; + if (size) + *size = 0; + } +} +EXPORT_SYMBOL(conninfra_get_emi_phy_addr); + +int conninfra_pwr_on(enum consys_drv_type drv_type) +{ + pr_info("[%s] drv=[%d]", __func__, drv_type); + if (conninfra_core_is_rst_locking()) { + DUMP_LOG(); + return CONNINFRA_ERR_RST_ONGOING; + } + +#if ENABLE_PRE_CAL_BLOCKING_CHECK + conninfra_core_pre_cal_blocking(); +#endif + + return conninfra_core_power_on(drv_type); +} +EXPORT_SYMBOL(conninfra_pwr_on); + +int conninfra_pwr_off(enum consys_drv_type drv_type) +{ + if (conninfra_core_is_rst_locking()) { + DUMP_LOG(); + return CONNINFRA_ERR_RST_ONGOING; + } + +#if ENABLE_PRE_CAL_BLOCKING_CHECK + conninfra_core_pre_cal_blocking(); +#endif + + return conninfra_core_power_off(drv_type); +} +EXPORT_SYMBOL(conninfra_pwr_off); + + +int conninfra_reg_readable(void) +{ + return conninfra_core_reg_readable(); +} +EXPORT_SYMBOL(conninfra_reg_readable); + + +int conninfra_reg_readable_no_lock(void) +{ + return conninfra_core_reg_readable_no_lock(); +} +EXPORT_SYMBOL(conninfra_reg_readable_no_lock); + +int conninfra_is_bus_hang(void) +{ + if (conninfra_core_is_rst_locking()) { + DUMP_LOG(); + return CONNINFRA_ERR_RST_ONGOING; + } + return conninfra_core_is_bus_hang(); +} +EXPORT_SYMBOL(conninfra_is_bus_hang); + +int conninfra_trigger_whole_chip_rst(enum consys_drv_type who, char *reason) +{ + /* use schedule worker to trigger ??? */ + /* so that function can be returned immediately */ + int r; + + r = conninfra_core_lock_rst(); + if (r >= CHIP_RST_START) { + /* reset is ongoing */ + pr_warn("[%s] r=[%d] chip rst is ongoing\n", __func__, r); + return 1; + } + pr_info("[%s] rst lock [%d] [%d] reason=%s", __func__, r, who, reason); + + conninfra_core_trg_chip_rst(who, reason); + + return 0; +} +EXPORT_SYMBOL(conninfra_trigger_whole_chip_rst); + +int conninfra_sub_drv_ops_register(enum consys_drv_type type, + struct sub_drv_ops_cb *cb) +{ + /* type validation */ + if (type < 0 || type >= CONNDRV_TYPE_MAX) { + pr_err("[%s] incorrect drv type [%d]", __func__, type); + return -EINVAL; + } + pr_info("[%s] ----", __func__); + conninfra_core_subsys_ops_reg(type, cb); + return 0; +} +EXPORT_SYMBOL(conninfra_sub_drv_ops_register); + +int conninfra_sub_drv_ops_unregister(enum consys_drv_type type) +{ + /* type validation */ + if (type < 0 || type >= CONNDRV_TYPE_MAX) { + pr_err("[%s] incorrect drv type [%d]", __func__, type); + return -EINVAL; + } + pr_info("[%s] ----", __func__); + conninfra_core_subsys_ops_unreg(type); + return 0; +} +EXPORT_SYMBOL(conninfra_sub_drv_ops_unregister); + + +int conninfra_spi_read(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int *data) +{ + if (conninfra_core_is_rst_locking()) { + DUMP_LOG(); + return CONNINFRA_ERR_RST_ONGOING; + } + if (subsystem >= SYS_SPI_MAX) { + pr_err("[%s] wrong subsys %d", __func__, subsystem); + return -EINVAL; + } + conninfra_core_spi_read(subsystem, addr, data); + return 0; +} +EXPORT_SYMBOL(conninfra_spi_read); + +int conninfra_spi_write(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int data) +{ + if (conninfra_core_is_rst_locking()) { + DUMP_LOG(); + return CONNINFRA_ERR_RST_ONGOING; + } + + if (subsystem >= SYS_SPI_MAX) { + pr_err("[%s] wrong subsys %d", __func__, subsystem); + return -EINVAL; + } + conninfra_core_spi_write(subsystem, addr, data); + return 0; +} +EXPORT_SYMBOL(conninfra_spi_write); + +int conninfra_adie_top_ck_en_on(enum consys_adie_ctl_type type) +{ + if (conninfra_core_is_rst_locking()) { + DUMP_LOG(); + return CONNINFRA_ERR_RST_ONGOING; + } + + return conninfra_core_adie_top_ck_en_on(type); +} +EXPORT_SYMBOL(conninfra_adie_top_ck_en_on); + +int conninfra_adie_top_ck_en_off(enum consys_adie_ctl_type type) +{ + if (conninfra_core_is_rst_locking()) { + DUMP_LOG(); + return CONNINFRA_ERR_RST_ONGOING; + } + + return conninfra_core_adie_top_ck_en_off(type); +} +EXPORT_SYMBOL(conninfra_adie_top_ck_en_off); + +int conninfra_spi_clock_switch(enum connsys_spi_speed_type type) +{ + return conninfra_core_spi_clock_switch(type); +} +EXPORT_SYMBOL(conninfra_spi_clock_switch); + +void conninfra_config_setup(void) +{ + if (conninfra_core_is_rst_locking()) { + DUMP_LOG(); + return; + } + + conninfra_core_config_setup(); +} +EXPORT_SYMBOL(conninfra_config_setup); + +int conninfra_bus_clock_ctrl(enum consys_drv_type drv_type, unsigned int bus_clock, int status) +{ + return conninfra_core_bus_clock_ctrl(drv_type, bus_clock, status); +} +EXPORT_SYMBOL(conninfra_bus_clock_ctrl); diff --git a/drivers/misc/mediatek/connectivity/conninfra/src/conninfra_dev.c b/drivers/misc/mediatek/connectivity/conninfra/src/conninfra_dev.c new file mode 100755 index 0000000000000000000000000000000000000000..b0279174eb7f6b72a64eb402dc0d93a60cb15512 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/src/conninfra_dev.c @@ -0,0 +1,659 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#include +#include +#include +#include +#include +#include "conninfra.h" +#include "conninfra_conf.h" +#include "conninfra_core.h" +#include "conninfra_dbg.h" +#include "consys_hw.h" +#include "connsys_debug_utility.h" +#include "wmt_build_in_adapter.h" +#include "emi_mng.h" + +#ifdef MTK_WCN_REMOVE_KERNEL_MODULE +#include "conn_drv_init.h" +#endif +#ifdef CFG_CONNINFRA_UT_SUPPORT +#include "conninfra_test.h" +#endif + +#include + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +#define CONNINFRA_DEV_MAJOR 164 +//#define WMT_DETECT_MAJOR 154 +#define CONNINFRA_DEV_NUM 1 +#define CONNINFRA_DRVIER_NAME "conninfra_drv" +#define CONNINFRA_DEVICE_NAME "conninfra_dev" + +#define CONNINFRA_DEV_IOC_MAGIC 0xc2 +#define CONNINFRA_IOCTL_GET_CHIP_ID _IOR(CONNINFRA_DEV_IOC_MAGIC, 0, int) +#define CONNINFRA_IOCTL_SET_COREDUMP_MODE _IOW(CONNINFRA_DEV_IOC_MAGIC, 1, unsigned int) +#define CONNINFRA_IOCTL_DO_MODULE_INIT _IOR(CONNINFRA_DEV_IOC_MAGIC, 2, int) + +#define CONNINFRA_DEV_INIT_TO_MS (2 * 1000) + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +enum conninfra_init_status { + CONNINFRA_INIT_NOT_START, + CONNINFRA_INIT_START, + CONNINFRA_INIT_DONE, +}; +static int g_conninfra_init_status = CONNINFRA_INIT_NOT_START; +static wait_queue_head_t g_conninfra_init_wq; + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ +struct conninfra_pmic_work { + unsigned int id; + unsigned int event; + struct work_struct pmic_work; +}; + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +static int conninfra_dev_fb_notifier_callback(struct notifier_block *self, + unsigned long event, void *data); + +static int conninfra_dev_open(struct inode *inode, struct file *file); +static int conninfra_dev_close(struct inode *inode, struct file *file); +static ssize_t conninfra_dev_read(struct file *filp, char __user *buf, + size_t count, loff_t *f_pos); +static ssize_t conninfra_dev_write(struct file *filp, + const char __user *buf, size_t count, + loff_t *f_pos); +static long conninfra_dev_unlocked_ioctl( + struct file *filp, unsigned int cmd, unsigned long arg); +#ifdef CONFIG_COMPAT +static long conninfra_dev_compat_ioctl( + struct file *filp, unsigned int cmd, unsigned long arg); +#endif +static int conninfra_mmap(struct file *pFile, struct vm_area_struct *pVma); +static int conninfra_thermal_query_cb(void); +static void conninfra_clock_fail_dump_cb(void); + +static int conninfra_conn_reg_readable(void); +static int conninfra_conn_is_bus_hang(void); + +static void conninfra_devapc_violation_cb(void); +static void conninfra_register_devapc_callback(void); + +static int conninfra_dev_suspend_cb(void); +static int conninfra_dev_resume_cb(void); +static int conninfra_dev_pmic_event_cb(unsigned int, unsigned int); + +static int conninfra_dev_do_drv_init(void); +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +struct class *pConninfraClass; +struct device *pConninfraDev; +static struct cdev gConninfraCdev; + +const struct file_operations gConninfraDevFops = { + .open = conninfra_dev_open, + .release = conninfra_dev_close, + .read = conninfra_dev_read, + .write = conninfra_dev_write, + .unlocked_ioctl = conninfra_dev_unlocked_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = conninfra_dev_compat_ioctl, +#endif + .mmap = conninfra_mmap, +}; + +struct wmt_platform_bridge g_plat_bridge = { + .thermal_query_cb = conninfra_thermal_query_cb, + .clock_fail_dump_cb = conninfra_clock_fail_dump_cb, + .conninfra_reg_readable_cb = conninfra_conn_reg_readable, + .conninfra_reg_is_bus_hang_cb = conninfra_conn_is_bus_hang +}; + + +static int gConnInfraMajor = CONNINFRA_DEV_MAJOR; + +/* screen on/off notification */ +static struct notifier_block conninfra_fb_notifier; +static struct work_struct gPwrOnOffWork; +static atomic_t g_es_lr_flag_for_blank = ATOMIC_INIT(0); /* for ctrl blank flag */ +static int last_thermal_value; +static int g_temp_thermal_value; +/* For DEVAPC callback */ +static struct work_struct g_conninfra_devapc_work; +static struct devapc_vio_callbacks conninfra_devapc_handle = { + .id = INFRA_SUBSYS_CONN, + .debug_dump = conninfra_devapc_violation_cb, +}; +/* For PMIC callback */ +static struct conninfra_pmic_work g_conninfra_pmic_work; + +static struct conninfra_dev_cb g_conninfra_dev_cb = { + .conninfra_suspend_cb = conninfra_dev_suspend_cb, + .conninfra_resume_cb = conninfra_dev_resume_cb, + .conninfra_pmic_event_notifier = conninfra_dev_pmic_event_cb, +}; + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +int conninfra_dev_open(struct inode *inode, struct file *file) +{ +#ifdef MTK_WCN_REMOVE_KERNEL_MODULE + pr_info("[%s] built-in mode, allow to open", __func__); +#else + static DEFINE_RATELIMIT_STATE(_rs, HZ, 1); + + if (!wait_event_timeout( + g_conninfra_init_wq, + g_conninfra_init_status == CONNINFRA_INIT_DONE, + msecs_to_jiffies(CONNINFRA_DEV_INIT_TO_MS))) { + if (__ratelimit(&_rs)) { + pr_warn("wait_event_timeout (%d)ms,(%lu)jiffies,return -EIO\n", + CONNINFRA_DEV_INIT_TO_MS, msecs_to_jiffies(CONNINFRA_DEV_INIT_TO_MS)); + } + return -EIO; + } +#endif + pr_info("open major %d minor %d (pid %d)\n", + imajor(inode), iminor(inode), current->pid); + + return 0; +} + +int conninfra_dev_close(struct inode *inode, struct file *file) +{ + pr_info("close major %d minor %d (pid %d)\n", + imajor(inode), iminor(inode), current->pid); + + return 0; +} + +ssize_t conninfra_dev_read(struct file *filp, char __user *buf, + size_t count, loff_t *f_pos) +{ + return 0; +} + +ssize_t conninfra_dev_write(struct file *filp, + const char __user *buf, size_t count, loff_t *f_pos) +{ + return 0; +} + +static long conninfra_dev_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ +#ifdef MTK_WCN_REMOVE_KERNEL_MODULE + static DEFINE_RATELIMIT_STATE(_rs, HZ, 1); +#endif + int retval = 0; + + pr_info("[%s] cmd (%d),arg(%ld)\n", __func__, cmd, arg); + + /* Special process for module init command */ + if (cmd == CONNINFRA_IOCTL_DO_MODULE_INIT) { + #ifdef MTK_WCN_REMOVE_KERNEL_MODULE + retval = conninfra_dev_do_drv_init(); + return retval; + #else + pr_info("[%s] KO mode", __func__); + return 0; + #endif + } + +#ifdef MTK_WCN_REMOVE_KERNEL_MODULE + if (!wait_event_timeout( + g_conninfra_init_wq, + g_conninfra_init_status == CONNINFRA_INIT_DONE, + msecs_to_jiffies(CONNINFRA_DEV_INIT_TO_MS))) { + if (__ratelimit(&_rs)) { + pr_warn("wait_event_timeout (%d)ms,(%lu)jiffies,return -EIO\n", + CONNINFRA_DEV_INIT_TO_MS, msecs_to_jiffies(CONNINFRA_DEV_INIT_TO_MS)); + } + return -EIO; + } +#endif + + switch (cmd) { + case CONNINFRA_IOCTL_GET_CHIP_ID: + retval = consys_hw_chipid_get(); + break; + case CONNINFRA_IOCTL_SET_COREDUMP_MODE: + connsys_coredump_set_dump_mode(arg); + break; + } + + return retval; + +} + +#ifdef CONFIG_COMPAT +static long conninfra_dev_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + long ret; + + pr_info("[%s] cmd (%d)\n", __func__, cmd); + ret = conninfra_dev_unlocked_ioctl(filp, cmd, arg); + return ret; +} +#endif + +static int conninfra_mmap(struct file *pFile, struct vm_area_struct *pVma) +{ + unsigned long bufId = pVma->vm_pgoff; + struct consys_emi_addr_info* addr_info = emi_mng_get_phy_addr(); + + pr_info("conninfra_mmap start:%lu end:%lu size: %lu buffer id=%lu\n", + pVma->vm_start, pVma->vm_end, + pVma->vm_end - pVma->vm_start, bufId); + + if (bufId == 0) { + if (pVma->vm_end - pVma->vm_start > addr_info->emi_size) + return -EINVAL; + pr_info("conninfra_mmap size: %lu\n", pVma->vm_end - pVma->vm_start); + if (remap_pfn_range(pVma, pVma->vm_start, addr_info->emi_ap_phy_addr >> PAGE_SHIFT, + pVma->vm_end - pVma->vm_start, pVma->vm_page_prot)) + return -EAGAIN; + return 0; + } else if (bufId == 1) { + if (addr_info == NULL) + return -EINVAL; + if (addr_info->md_emi_size == 0 || + pVma->vm_end - pVma->vm_start > addr_info->md_emi_size) + return -EINVAL; + pr_info("MD direct path size=%u map size=%lu\n", + addr_info->md_emi_size, + pVma->vm_end - pVma->vm_start); + if (remap_pfn_range(pVma, pVma->vm_start, + addr_info->md_emi_phy_addr >> PAGE_SHIFT, + pVma->vm_end - pVma->vm_start, pVma->vm_page_prot)) + return -EAGAIN; + return 0; + } + /* Invalid bufId */ + return -EINVAL; +} + +static int conninfra_dev_get_blank_state(void) +{ + return atomic_read(&g_es_lr_flag_for_blank); +} + +int conninfra_dev_fb_notifier_callback(struct notifier_block *self, + unsigned long event, void *data) +{ + struct fb_event *evdata = data; + int blank; + + pr_debug("conninfra_dev_fb_notifier_callback event=[%u]\n", event); + + /* If we aren't interested in this event, skip it immediately ... */ + if (event != FB_EARLY_EVENT_BLANK) + return 0; + + blank = *(int *)evdata->data; + + switch (blank) { + case FB_BLANK_UNBLANK: + atomic_set(&g_es_lr_flag_for_blank, 1); + pr_info("@@@@@@@@@@ Conninfra enter UNBLANK @@@@@@@@@@@@@@\n"); + schedule_work(&gPwrOnOffWork); + break; + case FB_BLANK_POWERDOWN: + atomic_set(&g_es_lr_flag_for_blank, 0); + pr_info("@@@@@@@@@@ Conninfra enter early POWERDOWN @@@@@@@@@@@@@@\n"); + schedule_work(&gPwrOnOffWork); + break; + default: + break; + } + return 0; +} + +static void conninfra_dev_pwr_on_off_handler(struct work_struct *work) +{ + pr_debug("conninfra_dev_pwr_on_off_handler start to run\n"); + + /* Update blank on status after wmt power on */ + if (conninfra_dev_get_blank_state() == 1) { + conninfra_core_screen_on(); + } else { + conninfra_core_screen_off(); + } +} + +static int conninfra_thermal_query_cb(void) +{ + int ret; + + /* if rst is ongoing, return thermal val got from last time */ + if (conninfra_core_is_rst_locking()) { + pr_info("[%s] rst is locking, return last temp ", __func__); + return last_thermal_value; + } + pr_info("[%s] query thermal", __func__); + ret = conninfra_core_thermal_query(&g_temp_thermal_value); + if (ret == 0) + last_thermal_value = g_temp_thermal_value; + else if (ret == CONNINFRA_ERR_WAKEUP_FAIL) + conninfra_trigger_whole_chip_rst(CONNDRV_TYPE_CONNINFRA, "Query thermal wakeup fail"); + + return last_thermal_value; +} + +static void conninfra_clock_fail_dump_cb(void) +{ + conninfra_core_clock_fail_dump_cb(); +} + + +/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ +/* THIS FUNCTION IS ONLY FOR AUDIO DRIVER */ +/* this function go through consys_hw, skip conninfra_core */ +/* there is no lock and skip consys power on check */ +/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ +static int conninfra_conn_reg_readable(void) +{ + return consys_hw_reg_readable(); + /*return conninfra_core_reg_readable(); */ +} + +static int conninfra_conn_is_bus_hang(void) +{ + /* if rst is ongoing, don't dump */ + if (conninfra_core_is_rst_locking()) { + pr_info("[%s] rst is locking, skip dump", __func__); + return CONNINFRA_ERR_RST_ONGOING; + } + return conninfra_core_is_bus_hang(); +} + +static void conninfra_devapc_violation_cb(void) +{ + schedule_work(&g_conninfra_devapc_work); +} + +static void conninfra_devapc_handler(struct work_struct *work) +{ + conninfra_trigger_whole_chip_rst(CONNDRV_TYPE_CONNINFRA, "CONNSYS DEVAPC"); +} + +static void conninfra_register_devapc_callback(void) +{ + INIT_WORK(&g_conninfra_devapc_work, conninfra_devapc_handler); + register_devapc_vio_callback(&conninfra_devapc_handle); +} + +static int conninfra_dev_suspend_cb(void) +{ + return 0; +} + +static int conninfra_dev_resume_cb(void) +{ + conninfra_core_dump_power_state(); + return 0; +} + +static int conninfra_dev_pmic_event_cb(unsigned int id, unsigned int event) +{ + g_conninfra_pmic_work.id = id; + g_conninfra_pmic_work.event = event; + schedule_work(&g_conninfra_pmic_work.pmic_work); + + return 0; +} + +static void conninfra_dev_pmic_event_handler(struct work_struct *work) +{ + unsigned int id, event; + struct conninfra_pmic_work *pmic_work = + container_of(work, struct conninfra_pmic_work, pmic_work); + + if (pmic_work) { + id = pmic_work->id; + event = pmic_work->event; + conninfra_core_pmic_event_cb(id, event); + } else + pr_err("[%s] pmic_work is null (id, event)=(%d, %d)", __func__, id, event); + +} + +static void conninfra_register_pmic_callback(void) +{ + INIT_WORK(&g_conninfra_pmic_work.pmic_work, conninfra_dev_pmic_event_handler); +} + + +/************************************************************************/ +static int conninfra_dev_do_drv_init() +{ + static int init_done = 0; + int iret = 0; + + if (init_done) { + pr_info("%s already init, return.", __func__); + return 0; + } + init_done = 1; + + /* init power on off handler */ + INIT_WORK(&gPwrOnOffWork, conninfra_dev_pwr_on_off_handler); + conninfra_fb_notifier.notifier_call + = conninfra_dev_fb_notifier_callback; + iret = fb_register_client(&conninfra_fb_notifier); + if (iret) + pr_err("register fb_notifier fail"); + else + pr_info("register fb_notifier success"); + +#ifdef CFG_CONNINFRA_UT_SUPPORT + iret = conninfra_test_setup(); + if (iret) + pr_err("init conninfra_test fail, ret = %d\n", iret); +#endif + + iret = conninfra_conf_init(); + if (iret) + pr_warn("init conf fail\n"); + + iret = consys_hw_init(&g_conninfra_dev_cb); + if (iret) { + pr_err("init consys_hw fail, ret = %d\n", iret); + g_conninfra_init_status = CONNINFRA_INIT_NOT_START; + return -2; + } + + iret = conninfra_core_init(); + if (iret) { + pr_err("conninfra init fail"); + g_conninfra_init_status = CONNINFRA_INIT_NOT_START; + return -3; + } + + conninfra_dev_dbg_init(); + + wmt_export_platform_bridge_register(&g_plat_bridge); + + conninfra_register_devapc_callback(); + conninfra_register_pmic_callback(); + + pr_info("ConnInfra Dev: init (%d)\n", iret); + g_conninfra_init_status = CONNINFRA_INIT_DONE; + +#ifdef MTK_WCN_REMOVE_KERNEL_MODULE + iret = (int)consys_hw_chipid_get(); + iret = do_connectivity_driver_init(iret); + if (iret) + pr_err("Sub driver init fail, iret=%d", iret); +#endif + + return 0; + +} + + +static int conninfra_dev_init(void) +{ + dev_t devID = MKDEV(gConnInfraMajor, 0); + int cdevErr = -1; + int iret = 0; + + g_conninfra_init_status = CONNINFRA_INIT_START; + init_waitqueue_head((wait_queue_head_t *)&g_conninfra_init_wq); + + iret = register_chrdev_region(devID, CONNINFRA_DEV_NUM, + CONNINFRA_DRVIER_NAME); + if (iret) { + pr_err("fail to register chrdev\n"); + g_conninfra_init_status = CONNINFRA_INIT_NOT_START; + return -1; + } + + cdev_init(&gConninfraCdev, &gConninfraDevFops); + gConninfraCdev.owner = THIS_MODULE; + + cdevErr = cdev_add(&gConninfraCdev, devID, CONNINFRA_DEV_NUM); + if (cdevErr) { + pr_err("cdev_add() fails (%d)\n", cdevErr); + goto err1; + } + + pConninfraClass = class_create(THIS_MODULE, CONNINFRA_DEVICE_NAME); + if (IS_ERR(pConninfraClass)) { + pr_err("class create fail, error code(%ld)\n", + PTR_ERR(pConninfraClass)); + goto err1; + } + + pConninfraDev = device_create(pConninfraClass, NULL, devID, + NULL, CONNINFRA_DEVICE_NAME); + if (IS_ERR(pConninfraDev)) { + pr_err("device create fail, error code(%ld)\n", + PTR_ERR(pConninfraDev)); + goto err2; + } +#ifndef MTK_WCN_REMOVE_KERNEL_MODULE + iret = conninfra_dev_do_drv_init(); + if (iret) { + pr_err("conninfra_do_drv_init fail, iret = %d", iret); + return iret; + } +#endif + return 0; +err2: + + pr_err("[conninfra_dev_init] err2"); + if (pConninfraClass) { + class_destroy(pConninfraClass); + pConninfraClass = NULL; + } +err1: + pr_err("[conninfra_dev_init] err1"); + if (cdevErr == 0) + cdev_del(&gConninfraCdev); + + if (iret == 0) { + unregister_chrdev_region(devID, CONNINFRA_DEV_NUM); + gConnInfraMajor = -1; + } + + g_conninfra_init_status = CONNINFRA_INIT_NOT_START; + return -2; +} + +static void conninfra_dev_deinit(void) +{ + dev_t dev = MKDEV(gConnInfraMajor, 0); + int iret = 0; + + g_conninfra_init_status = CONNINFRA_INIT_NOT_START; + fb_unregister_client(&conninfra_fb_notifier); + + iret = conninfra_dev_dbg_deinit(); +#ifdef CFG_CONNINFRA_UT_SUPPORT + iret = conninfra_test_remove(); +#endif + + iret = conninfra_core_deinit(); + + iret = consys_hw_deinit(); + + iret = conninfra_conf_deinit(); + + if (pConninfraDev) { + device_destroy(pConninfraClass, dev); + pConninfraDev = NULL; + } + + if (pConninfraClass) { + class_destroy(pConninfraClass); + pConninfraClass = NULL; + } + + cdev_del(&gConninfraCdev); + unregister_chrdev_region(dev, CONNINFRA_DEV_NUM); + + pr_info("ConnInfra: ALPS platform init (%d)\n", iret); +} + +module_init(conninfra_dev_init); +module_exit(conninfra_dev_deinit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Willy.Yu @ CTD/SE5/CS5"); + +module_param(gConnInfraMajor, uint, 0644); + diff --git a/drivers/misc/mediatek/connectivity/conninfra/test/cal_test.c b/drivers/misc/mediatek/connectivity/conninfra/test/cal_test.c new file mode 100755 index 0000000000000000000000000000000000000000..4ba3cc880614275d543522228e0d6037104c5fc4 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/test/cal_test.c @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#include +#include +#include +#include "conninfra.h" +#include "conninfra_core.h" +#include "osal.h" + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +int pre_cal_power_on_handler(void) +{ + pr_info("[%s] ===========", __func__); + osal_sleep_ms(100); + return 0; +} + +int pre_cal_do_cal_handler(void) +{ + pr_info("[%s] ===========", __func__); + return 0; +} + + +struct sub_drv_ops_cb g_cal_drv_ops_cb; + +int calibration_test(void) +{ + int ret; + + memset(&g_cal_drv_ops_cb, 0, sizeof(struct sub_drv_ops_cb)); + + g_cal_drv_ops_cb.pre_cal_cb.pwr_on_cb = pre_cal_power_on_handler; + g_cal_drv_ops_cb.pre_cal_cb.do_cal_cb = pre_cal_do_cal_handler; + + + pr_info("[%s] cb init [%p][%p]", __func__, + g_cal_drv_ops_cb.pre_cal_cb.pwr_on_cb, + g_cal_drv_ops_cb.pre_cal_cb.do_cal_cb); + + conninfra_sub_drv_ops_register(CONNDRV_TYPE_BT, &g_cal_drv_ops_cb); + conninfra_sub_drv_ops_register(CONNDRV_TYPE_WIFI, &g_cal_drv_ops_cb); + + ret = conninfra_core_pre_cal_start(); + if (ret) + pr_warn("[%s] fail [%d]", __func__, ret); + + osal_sleep_ms(1000); + + conninfra_core_screen_on(); + + conninfra_sub_drv_ops_unregister(CONNDRV_TYPE_BT); + conninfra_sub_drv_ops_unregister(CONNDRV_TYPE_WIFI); + pr_info("[%s] finish.", __func__); + return 0; +} + + diff --git a/drivers/misc/mediatek/connectivity/conninfra/test/chip_rst_test.c b/drivers/misc/mediatek/connectivity/conninfra/test/chip_rst_test.c new file mode 100755 index 0000000000000000000000000000000000000000..bfd19b4fb5cb3572cdd6771daf7fb489b7044f8b --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/test/chip_rst_test.c @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#include +#include +#include +#include "conninfra.h" +#include "osal.h" + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +int pre_chip_rst_handler(enum consys_drv_type drv, char* reason) +{ + pr_info("[%s] ===========", __func__); + osal_sleep_ms(100); + return 0; +} + +int post_chip_rst_handler(void) +{ + pr_info("[%s] ===========", __func__); + return 0; +} + +int pre_chip_rst_timeout_handler(enum consys_drv_type drv, char* reason) +{ + pr_info("[%s] ++++++++++++", __func__); + osal_sleep_ms(800); + pr_info("[%s] ------------", __func__); + return 0; +} + +struct sub_drv_ops_cb g_drv_ops_cb; +struct sub_drv_ops_cb g_drv_timeout_ops_cb; + +int chip_rst_test(void) +{ + int ret; + + memset(&g_drv_ops_cb, 0, sizeof(struct sub_drv_ops_cb)); + memset(&g_drv_timeout_ops_cb, 0, sizeof(struct sub_drv_ops_cb)); + + g_drv_ops_cb.rst_cb.pre_whole_chip_rst = pre_chip_rst_handler; + g_drv_ops_cb.rst_cb.post_whole_chip_rst = post_chip_rst_handler; + + g_drv_timeout_ops_cb.rst_cb.pre_whole_chip_rst = pre_chip_rst_timeout_handler; + g_drv_timeout_ops_cb.rst_cb.post_whole_chip_rst = post_chip_rst_handler; + + pr_info("[%s] cb init [%p][%p]", __func__, + g_drv_ops_cb.rst_cb.pre_whole_chip_rst, + g_drv_ops_cb.rst_cb.post_whole_chip_rst); + + conninfra_sub_drv_ops_register(CONNDRV_TYPE_BT, &g_drv_ops_cb); + conninfra_sub_drv_ops_register(CONNDRV_TYPE_WIFI, &g_drv_ops_cb); + conninfra_sub_drv_ops_register(CONNDRV_TYPE_FM, &g_drv_timeout_ops_cb); + + pr_info("[%s] ++++++++++++++++++++++", __func__); + + ret = conninfra_trigger_whole_chip_rst(CONNDRV_TYPE_BT, "test reset"); + if (ret) + pr_warn("[%s] fail [%d]", __func__, ret); + else + pr_info("Trigger chip reset success. Test pass."); + osal_sleep_ms(10); + + pr_info("Try to trigger whole chip reset when reset is ongoing. It should be fail."); + ret = conninfra_trigger_whole_chip_rst(CONNDRV_TYPE_BT, "test reset"); + pr_info("Test %s. ret = %d.", ret == 1? "pass": "fail", ret); + + pr_info("Try to funcion on when reset is ongoing. It should be fail."); + ret = conninfra_pwr_on(CONNDRV_TYPE_WIFI); + pr_info("Test %s. ret = %d.", ret == CONNINFRA_ERR_RST_ONGOING ? "pass": "fail", ret); + + osal_sleep_ms(3000); + + conninfra_sub_drv_ops_unregister(CONNDRV_TYPE_BT); + conninfra_sub_drv_ops_unregister(CONNDRV_TYPE_WIFI); + pr_info("chip_rst_test finish"); + return 0; +} + + diff --git a/drivers/misc/mediatek/connectivity/conninfra/test/conf_test.c b/drivers/misc/mediatek/connectivity/conninfra/test/conf_test.c new file mode 100755 index 0000000000000000000000000000000000000000..4f3936037deccd67120d698dfd8af40b820db5f5 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/test/conf_test.c @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#include "conninfra_conf.h" +#include "conf_test.h" + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + + +int conninfra_conf_test(void) +{ + int ret; + const struct conninfra_conf *conf; + +#if 0 + ret = conninfra_conf_set_cfg_file("WMT_SOC.cfg"); + if (ret) { + pr_err("set cfg file fail [%d]", ret); + return -1; + } +#endif + + ret = conninfra_conf_init(); + if (ret) { + pr_err("int conf fail [%d]", ret); + return -1; + } + + conf = conninfra_conf_get_cfg(); + if (NULL == conf) { + pr_err("int conf fail [%d]", ret); + return -1; + } + if (conf->tcxo_gpio != 0) { + pr_err("test tcxo gpio fail [%d]. For most case, it should be 0.", + conf->tcxo_gpio); + return -1; + } + + pr_info("[%s] test PASS\n", __func__); + return 0; +} + + diff --git a/drivers/misc/mediatek/connectivity/conninfra/test/conninfra_core_test.c b/drivers/misc/mediatek/connectivity/conninfra/test/conninfra_core_test.c new file mode 100755 index 0000000000000000000000000000000000000000..3f4e039cf79e852529e1fdb470ab5f35aae039cf --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/test/conninfra_core_test.c @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#include +#include +#include +#include "conninfra_core_test.h" + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + + diff --git a/drivers/misc/mediatek/connectivity/conninfra/test/conninfra_test.c b/drivers/misc/mediatek/connectivity/conninfra/test/conninfra_test.c new file mode 100755 index 0000000000000000000000000000000000000000..df5fd1376e13942f9abfed6b7daf12a96d8f0928 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/test/conninfra_test.c @@ -0,0 +1,459 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#define pr_fmt(fmt) "conninfra_test@(%s:%d) " fmt, __func__, __LINE__ + +#include +#include +#include +#include "conninfra_test.h" +#include "osal.h" + +#include "conninfra.h" +#include "conninfra_core.h" +#include "consys_reg_mng.h" + +#include "connsyslog_test.h" +#include "conf_test.h" +#include "cal_test.h" +#include "msg_evt_test.h" +#include "chip_rst_test.h" +#include "mailbox_test.h" +#include "coredump_test.h" +#include "consys_hw.h" + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +#define CONNINFRA_TEST_PROCNAME "driver/conninfra_test" + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +static ssize_t conninfra_test_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos); +static ssize_t conninfra_test_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos); + +static int core_tc(int par1, int par2, int par3); +static int conf_tc(int par1, int par2, int par3); +static int cal_tc(int par1, int par2, int par3); +static int msg_evt_tc(int par1, int par2, int par3); +static int chip_rst_tc(int par1, int par2, int par3); +static int mailbox_tc(int par1, int par2, int par3); +static int emi_tc(int par1, int par2, int par3); +static int log_tc(int par1, int par2, int par3); +static int thermal_tc(int par1, int par2, int par3); +static int bus_hang_tc(int par1, int par2, int par3); +static int dump_tc(int par1, int par2, int par3); +static int is_bus_hang_tc(int par1, int par2, int par3); +static int ap_resume_tc(int par1, int par2, int par3); + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +static struct proc_dir_entry *gConninfraTestEntry; + +static const CONNINFRA_TEST_FUNC conninfra_test_func[] = { + [0x01] = core_tc, + [0x02] = conf_tc, + [0x03] = msg_evt_tc, + [0x04] = chip_rst_tc, + [0x05] = cal_tc, + [0x06] = mailbox_tc, + [0x07] = emi_tc, + [0x08] = log_tc, + [0x09] = thermal_tc, + [0x0a] = bus_hang_tc, + [0x0b] = dump_tc, + [0x0c] = is_bus_hang_tc, + [0x0d] = ap_resume_tc, +}; + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +int core_tc_pwr_on(void) +{ + int iret = 0; + + pr_info("Power on test start"); + iret = conninfra_core_power_on(CONNDRV_TYPE_BT); + pr_info("BT power on %s (result = %d)", iret? "fail" : "pass", iret); + osal_sleep_ms(100); + iret = conninfra_core_power_on(CONNDRV_TYPE_FM); + pr_info("FM power on %s (result = %d)", iret? "fail" : "pass", iret); + osal_sleep_ms(100); + iret = conninfra_core_power_on(CONNDRV_TYPE_GPS); + pr_info("GPS power on %s (result = %d)", iret? "fail" : "pass", iret); + osal_sleep_ms(100); + iret = conninfra_core_power_on(CONNDRV_TYPE_WIFI); + pr_info("Wi-Fi power on %s (result = %d)", iret? "fail" : "pass", iret); + osal_sleep_ms(200); + + return iret; +} + +int core_tc_pwr_off(void) +{ + int iret = 0; + + iret = conninfra_core_power_off(CONNDRV_TYPE_WIFI); + pr_info("Wi-Fi power off %s (result = %d)", iret? "fail" : "pass", iret); + osal_sleep_ms(100); + iret = conninfra_core_power_off(CONNDRV_TYPE_GPS); + pr_info("GPS power off %s (result = %d)", iret? "fail" : "pass", iret); + osal_sleep_ms(100); + iret = conninfra_core_power_off(CONNDRV_TYPE_BT); + pr_info("BT power off %s (result = %d)", iret? "fail" : "pass", iret); + osal_sleep_ms(100); + iret = conninfra_core_power_off(CONNDRV_TYPE_FM); + pr_info("FM power off %s (result = %d)", iret? "fail" : "pass", iret); + + return iret; +} + + +int core_tc(int par1, int par2, int par3) +{ + int iret = 0; + char* driver_name[CONNDRV_TYPE_MAX] = { + "BT", + "FM", + "GPS", + "Wi-Fi", + }; + + if (par2 == 0) { + iret = core_tc_pwr_on(); + iret = core_tc_pwr_off(); + } else if (par2 == 1) { + if (par3 == 15) { + iret = core_tc_pwr_on(); + } else if (par3 >= CONNDRV_TYPE_BT && par3 <= CONNDRV_TYPE_WIFI) { + pr_info("Power on %s test start\n", driver_name[par3]); + iret = conninfra_core_power_on(par3); + pr_info("Power on %s test, return = %d\n", driver_name[par3], iret); + } else { + pr_info("No support parameter\n"); + } + } else if (par2 == 2) { + if (par3 == 15) { + iret = core_tc_pwr_off(); + } else if (par3 >= CONNDRV_TYPE_BT && par3 <= CONNDRV_TYPE_WIFI) { + pr_info("Power off %s test start\n", driver_name[par3]); + iret = conninfra_core_power_off(par3); + pr_info("Power off %s test, return = %d\n", driver_name[par3], iret); + } else { + pr_info("No support parameter\n"); + } + } else if (par2 == 3) { + if (par3 == 1) { + iret = conninfra_core_adie_top_ck_en_on(CONNSYS_ADIE_CTL_FW_WIFI); + pr_info( + "Turn on adie top ck en (ret=%d), please check 0x1805_2830[6] should be 1\n", + iret); + } else if (par3 == 0) { + iret = conninfra_core_adie_top_ck_en_off(CONNSYS_ADIE_CTL_FW_WIFI); + pr_info( + "Turn off adie top ck en (ret=%d), please check 0x1805_2830[6] should be 1\n", + iret); + } + } + //pr_info("core_tc %s (result = %d)", iret? "fail" : "pass", iret); + return 0; +} + +static int conf_tc(int par1, int par2, int par3) +{ + return conninfra_conf_test(); +} + +static int msg_evt_tc(int par1, int par2, int par3) +{ + return msg_evt_test(); +} + +static int chip_rst_tc(int par1, int par2, int par3) +{ + pr_info("test start"); + return chip_rst_test(); +} + +static int cal_tc(int par1, int par2, int par3) +{ + pr_info("test start"); + return calibration_test(); +} + + +static int mailbox_tc(int par1, int par2, int par3) +{ + return mailbox_test(); +} + +static int emi_tc(int par1, int par2, int par3) +{ + unsigned int addr = 0; + unsigned int size = 0; + int ret = 0; + + pr_info("[%s] start", __func__); + conninfra_get_phy_addr(&addr, &size); + if (addr == 0 || size == 0) { + pr_err("[%s] fail! addr=[0x%x] size=[%u]", __func__, addr, size); + ret = -1; + } else + pr_info("[%s] pass. addr=[0x%x] size=[%u]", __func__, addr, size); + + pr_info("[%s] end", __func__); + + return ret; +} + +static int thermal_tc(int par1, int par2, int par3) +{ + int ret, temp; + + ret = core_tc_pwr_on(); + if (ret) { + pr_err("pwr on fail"); + return -1; + } + ret = conninfra_core_thermal_query(&temp); + pr_info("[%s] thermal res=[%d][%d]", __func__, ret, temp); + + return ret; +} + +static int log_tc(int par1, int par2, int par3) +{ + /* 0: initial state + * 1: log has been init. + */ + static int log_status = 0; + int ret = 0; + + if (par2 == 0) { + if (log_status != 0) { + pr_info("log has been init.\n"); + return 0; + } + /* init */ + ret = connlog_test_init(); + if (ret) + pr_err("FW log init fail! ret=%d\n", ret); + else { + log_status = 1; + pr_info("FW log init finish. Check result on EMI.\n"); + } + } else if (par2 == 1) { + /* add fake log */ + /* read log */ + connlog_test_read(); + } else if (par2 == 2) { + /* deinit */ + if (log_status == 0) { + pr_info("log didn't init\n"); + return 0; + } + ret = connlog_test_deinit(); + if (ret) + pr_err("FW log deinit fail! ret=%d\n", ret); + else + log_status = 0; + } + return ret; +} + + +static int bus_hang_tc(int par1, int par2, int par3) +{ + int r; + r = conninfra_core_is_bus_hang(); + + pr_info("[%s] r=[%d]\n", __func__, r); + return 0; +} + +static int dump_tc(int par1, int par2, int par3) +{ + return coredump_test(par1, par2, par3); +} + +static int is_bus_hang_tc(int par1, int par2, int par3) +{ + int r; + + r = consys_reg_mng_reg_readable(); + pr_info("[%s] r=[%d]", __func__, r); + r = consys_reg_mng_is_bus_hang(); + pr_info("[%s] r=[%d]", __func__, r); + return 0; +} + +static int ap_resume_tc(int par1, int par2, int par3) +{ + return 0; +} + +ssize_t conninfra_test_read(struct file *filp, char __user *buf, + size_t count, loff_t *f_pos) +{ + return 0; +} + +ssize_t conninfra_test_write(struct file *filp, const char __user *buffer, size_t count, loff_t *f_pos) +{ + size_t len = count; + char buf[256]; + char *pBuf; + char *pDelimiter = " \t"; + int x = 0, y = 0, z = 0; + char *pToken = NULL; + long res = 0; + static bool test_enabled = false; + + pr_info("write parameter len = %d\n\r", (int) len); + if (len >= osal_sizeof(buf)) { + pr_err("input handling fail!\n"); + len = osal_sizeof(buf) - 1; + return -1; + } + + if (copy_from_user(buf, buffer, len)) + return -EFAULT; + + buf[len] = '\0'; + pr_info("write parameter data = %s\n\r", buf); + + pBuf = buf; + pToken = osal_strsep(&pBuf, pDelimiter); + if (pToken != NULL) { + osal_strtol(pToken, 16, &res); + x = (int)res; + } else { + x = 0; + } + + pToken = osal_strsep(&pBuf, "\t\n "); + if (pToken != NULL) { + osal_strtol(pToken, 16, &res); + y = (int)res; + pr_info("y = 0x%08x\n\r", y); + } else { + y = 3000; + /*efuse, register read write default value */ + if (0x11 == x || 0x12 == x || 0x13 == x) + y = 0x80000000; + } + + pToken = osal_strsep(&pBuf, "\t\n "); + if (pToken != NULL) { + osal_strtol(pToken, 16, &res); + z = (int)res; + } else { + z = 10; + /*efuse, register read write default value */ + if (0x11 == x || 0x12 == x || 0x13 == x) + z = 0xffffffff; + } + + pr_info("x(0x%08x), y(0x%08x), z(0x%08x)\n\r", x, y, z); + + /* For eng and userdebug load, have to enable wmt_dbg by + * writing 0xDB9DB9 to * "/proc/driver/wmt_dbg" to avoid + * some malicious use + */ + if (x == 0xDB9DB9) { + test_enabled = true; + return len; + } + + if (!test_enabled) + return 0; + + if (osal_array_size(conninfra_test_func) > x && + NULL != conninfra_test_func[x]) + (*conninfra_test_func[x]) (x, y, z); + else + pr_warn("no handler defined for command id(0x%08x)\n\r", x); + + return len; + +} + + +int conninfra_test_setup(void) +{ + static const struct file_operations conninfra_test_fops = { + .owner = THIS_MODULE, + .read = conninfra_test_read, + .write = conninfra_test_write, + }; + int i_ret = 0; + + gConninfraTestEntry = proc_create(CONNINFRA_TEST_PROCNAME, + 0664, NULL, &conninfra_test_fops); + if (gConninfraTestEntry == NULL) { + pr_err("Unable to create / wmt_aee proc entry\n\r"); + i_ret = -1; + } + + return i_ret; +} + +int conninfra_test_remove(void) +{ + if (gConninfraTestEntry != NULL) + proc_remove(gConninfraTestEntry); + return 0; +} + diff --git a/drivers/misc/mediatek/connectivity/conninfra/test/connsyslog_test.c b/drivers/misc/mediatek/connectivity/conninfra/test/connsyslog_test.c new file mode 100644 index 0000000000000000000000000000000000000000..eabcdc302b31815829584c74bcc531b4256c7fff --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/test/connsyslog_test.c @@ -0,0 +1,113 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +#define pr_fmt(fmt) "connlog_test@(%s:%d) " fmt, __func__, __LINE__ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +#include + +#include "conninfra.h" +#include "connsys_debug_utility.h" + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +static void connlog_test_event_handler(void); + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +#define TEST_LOG_BUF_SIZE 1*2014 + +static char test_buf[TEST_LOG_BUF_SIZE]; + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +static void connlog_test_event_handler(void) +{ + ssize_t read = 0; + pr_info("connlog_test_event_handler\n"); + + read = connsys_log_read(CONN_DEBUG_TYPE_WIFI, test_buf, TEST_LOG_BUF_SIZE); + pr_info("Read %u:\n", read); + connsys_log_dump_buf("log_test", test_buf, read); + pr_info("============================================\n"); +} + +int connlog_test_init(void) +{ + unsigned int emi_addr = 0; + unsigned int emi_size = 0; + int ret; + + conninfra_get_phy_addr(&emi_addr, &emi_size); + if (!emi_addr || !emi_size) { + pr_err("EMI init fail.\n"); + return 1; + } + + ret = connsys_dedicated_log_path_apsoc_init(emi_addr); + if (ret) { + pr_err("connsys_dedicated_log_path_apsoc_init should fail\n"); + return 2; + } else { + pr_info("connsys_dedicated_log_path_apsoc_init return fail as expection\n"); + } + + ret = connsys_log_init(CONN_DEBUG_TYPE_WIFI); + if (ret) { + pr_err("Init connsys log failed\n"); + return 3; + } + connsys_log_register_event_cb(CONN_DEBUG_TYPE_WIFI, connlog_test_event_handler); + return 0; +} + +int connlog_test_read(void) +{ + connsys_log_irq_handler(CONN_DEBUG_TYPE_WIFI); + return 0; +} + +int connlog_test_deinit(void) +{ + connsys_log_deinit(CONN_DEBUG_TYPE_WIFI); + return 0; +} + diff --git a/drivers/misc/mediatek/connectivity/conninfra/test/dump_test.c b/drivers/misc/mediatek/connectivity/conninfra/test/dump_test.c new file mode 100755 index 0000000000000000000000000000000000000000..c1719f76d9c1f0de99a6f4e3f211b7fffea6ce87 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/test/dump_test.c @@ -0,0 +1,290 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +#define pr_fmt(fmt) "dump_test@(%s:%d) " fmt, __func__, __LINE__ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +#include +#include + +#include "conninfra.h" +#include "connsys_debug_utility.h" + +#include "coredump_test.h" +#include "coredump/conndump_netlink.h" + +#include "msg_thread.h" + + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + + +static int coredump_test_init(void); +static int coredump_test_start(void); +static int coredump_test_deinit(void); + +static int dump_test_reg_readable(void); +static void dump_test_poll_cpu_pcr(unsigned int times, unsigned int sleep); + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ +static void* g_dumpCtx = 0; +static int nl_init = 0; +struct msg_thread_ctx g_msg_ctx; + +static int init = 0; + +typedef enum { + DUMP_TEST_OPID_1 = 0, + DUMP_TEST_OPID_2 = 1, + DUMP_TEST_OPID_MAX +} test_opid; + + +static int opfunc_test_1(struct msg_op_data *op); +static int opfunc_test_2(struct msg_op_data *op); + +static const msg_opid_func test_op_func[] = { + [DUMP_TEST_OPID_1] = opfunc_test_1, + [DUMP_TEST_OPID_2] = opfunc_test_2, +}; + +struct coredump_event_cb g_cb = { + .reg_readable = dump_test_reg_readable, + .poll_cpupcr = dump_test_poll_cpu_pcr, +}; + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +static int dump_test_reg_readable(void) +{ + return 1; +} + +static void dump_test_poll_cpu_pcr(unsigned int times, unsigned int sleep) +{ + pr_info("[%s]\n", __func__); +} + +#define TEST_STRING "this is coredump test" + +static int coredump_test_start(void) +{ + + if (!g_dumpCtx) { + pr_err("coredump contxt is not init\n"); + return 1; + } +#if 0 + pr_info("[%s] tc[0] test case\n", __func__); + /* Trigger interrupt */ + connsys_coredump_setup_tc(g_dumpCtx, 0); + + /* Start to dump */ + connsys_coredump_start(g_dumpCtx, 0); + + pr_info("[%s] sleep\n", __func__); + msleep(5000); + + pr_info("[%s] tc[1] test case\n", __func__); + /* Trigger interrupt */ + connsys_coredump_setup_tc(g_dumpCtx, 1); + /* Start to dump */ + connsys_coredump_start(g_dumpCtx, 0); + + pr_info("[%s] tc[2] test case\n", __func__); + /* Trigger interrupt */ + connsys_coredump_setup_tc(g_dumpCtx, 2); + /* Start to dump */ + connsys_coredump_start(g_dumpCtx, 0); +#endif + + pr_info("[%s] end\n", __func__); + return 0; + +} + +static int coredump_nl_start(void) +{ + int ret; + + + ret = conndump_netlink_send_to_native(CONN_DEBUG_TYPE_WIFI, "[M]", TEST_STRING, osal_strlen(TEST_STRING)); + pr_info("send ret=%d", ret); + ret = conndump_netlink_send_to_native(CONN_DEBUG_TYPE_WIFI, "[EMI]", NULL, 0); + pr_info("send emi dump ret=%d", ret); + return 0; +} + +static int coredump_test_init(void) +{ + unsigned int emi_addr = 0; + unsigned int emi_size = 0; + + if (g_dumpCtx) { + pr_err("log handler has been init. Need to deinit.\n"); + return 1; + } + + conninfra_get_phy_addr(&emi_addr, &emi_size); + if (!emi_addr || !emi_size) { + pr_err("EMI init fail.\n"); + return 2; + } + + pr_info("emi_addr=0x%08x, size=%d", emi_addr, emi_size); + + g_dumpCtx = connsys_coredump_init( + CONN_DEBUG_TYPE_WIFI, &g_cb); + + if (!g_dumpCtx) { + pr_err("Coredump init fail.\n"); + return 3; + } + + return 0; + +} + +static void coredump_end_cb(void* ctx) { + pr_info("Get dump end"); +} + +static int coredump_nl_init(void) +{ + int ret; + struct netlink_event_cb nl_cb; + + if (!nl_init) { + nl_cb.coredump_end = coredump_end_cb; + ret = conndump_netlink_init(CONN_DEBUG_TYPE_WIFI, NULL, &nl_cb); + pr_info("init get %d", ret); + nl_init = 1; + } + return 0; +} + +static int coredump_test_deinit(void) +{ + if (!g_dumpCtx) { + pr_err("coredump contxt is not init\n"); + return 1; + } + + connsys_coredump_deinit(g_dumpCtx); + return 0; +} + +static int coredump_nl_deinit(void) +{ + nl_init = 0; + return 0; +} + +int opfunc_test_1(struct msg_op_data *op) +{ + int tc = op->op_data[0]; + int ret = 0; + + pr_info("[%s] param=[%d]", __func__, tc); + switch (tc) { + case 0: + ret = coredump_test_init(); + break; + case 1: + ret = coredump_test_start(); + break; + case 2: + ret = coredump_test_deinit(); + break; + } + pr_info("ret = %d", ret); + return 0; +} + +int opfunc_test_2(struct msg_op_data *op) +{ + int tc = op->op_data[0]; + int ret = 0; + + pr_info("[%s] param=[%d]", __func__, tc); + + switch (tc) { + case 0: + ret = coredump_nl_init(); + break; + case 1: + ret = coredump_nl_start(); + break; + case 2: + ret = coredump_nl_deinit(); + break; + } + pr_info("ret = %d", ret); + return 0; +} + +int coredump_test(int par1, int par2, int par3) +{ + pr_info("Disable coredump test in SQC\n"); + init = 1; + return 0; +#if 0 + int ret = 0; + + if (init == 0) { + ret = msg_thread_init( + &g_msg_ctx, "DumptestThread", test_op_func, DUMP_TEST_OPID_MAX); + init = 1; + } + if (par2 == 0xff && par3 == 0xff && init) { + pr_info("End test"); + msg_thread_deinit(&g_msg_ctx); + init = 0; + } + + msg_thread_send_1(&g_msg_ctx, par2, par3); + + return 0; +#endif +} + diff --git a/drivers/misc/mediatek/connectivity/conninfra/test/include/cal_test.h b/drivers/misc/mediatek/connectivity/conninfra/test/include/cal_test.h new file mode 100755 index 0000000000000000000000000000000000000000..da917cae2e6dbb78af36bcaa837ddb5f8cb742af --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/test/include/cal_test.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#ifndef _CAL_TEST_H_ +#define _CAL_TEST_H_ + +#include "osal.h" +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + + +int calibration_test(void); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _CAL_TEST_H_ */ diff --git a/drivers/misc/mediatek/connectivity/conninfra/test/include/chip_rst_test.h b/drivers/misc/mediatek/connectivity/conninfra/test/include/chip_rst_test.h new file mode 100755 index 0000000000000000000000000000000000000000..b9b413a568b0c41647aa53fe9b2b85ebd6b23942 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/test/include/chip_rst_test.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#ifndef _CHIP_RST_TEST_H_ +#define _CHIP_RST_TEST_H_ + +#include "osal.h" +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + + +int chip_rst_test(void); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _CHIP_RST_TEST_H_ */ diff --git a/drivers/misc/mediatek/connectivity/conninfra/test/include/conf_test.h b/drivers/misc/mediatek/connectivity/conninfra/test/include/conf_test.h new file mode 100755 index 0000000000000000000000000000000000000000..a5aa7bd4a02ff0fe403db6c7fee792a66ec65dc3 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/test/include/conf_test.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#ifndef _CONF_TEST_H_ +#define _CONF_TEST_H_ + +#include "osal.h" +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + + +int conninfra_conf_test(void); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _CONF_TEST_H_ */ diff --git a/drivers/misc/mediatek/connectivity/conninfra/test/include/conninfra_core_test.h b/drivers/misc/mediatek/connectivity/conninfra/test/include/conninfra_core_test.h new file mode 100755 index 0000000000000000000000000000000000000000..fcc964ad032b67522ff9da7cea70655cc0faec68 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/test/include/conninfra_core_test.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#ifndef _CONNINFRA_CORE_TEST_H_ +#define _CONNINFRA_CORE_TEST_H_ + +#include "osal.h" +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + + +#define WMT_FUNC_CTRL_ON (MTK_WCN_BOOL_TRUE) +#define WMT_FUNC_CTRL_OFF (MTK_WCN_BOOL_FALSE) + +#define INIT_CMD(c, e, s) {.cmd = c, .cmdSz = sizeof(c), .evt = e, .evtSz = sizeof(e), .str = s} + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _CONNINFRA_CORE_TEST_H_ */ diff --git a/drivers/misc/mediatek/connectivity/conninfra/test/include/conninfra_test.h b/drivers/misc/mediatek/connectivity/conninfra/test/include/conninfra_test.h new file mode 100755 index 0000000000000000000000000000000000000000..4710e670b82d59056f202a5b5f6acd6ec7a1c403 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/test/include/conninfra_test.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#ifndef _CONNINFRA_TEST_H_ +#define _CONNINFRA_TEST_H_ + +#include "osal.h" +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + + +#define INIT_CMD(c, e, s) {.cmd = c, .cmdSz = sizeof(c), .evt = e, .evtSz = sizeof(e), .str = s} + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +typedef int(*CONNINFRA_TEST_FUNC) (int par1, int par2, int par3); + +int conninfra_test_setup(void); +int conninfra_test_remove(void); + + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _CONNINFRA_CORE_TEST_H_ */ diff --git a/drivers/misc/mediatek/connectivity/conninfra/test/include/connsyslog_test.h b/drivers/misc/mediatek/connectivity/conninfra/test/include/connsyslog_test.h new file mode 100644 index 0000000000000000000000000000000000000000..f6e6988dd631e717e9fdf0e3f3d8dd8ce6ec5b22 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/test/include/connsyslog_test.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#ifndef _CONNLOG_TEST_H_ +#define _CONNLOG_TEST_H_ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + + +int connlog_test_init(void); +int connlog_test_read(void); +int connlog_test_deinit(void); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _CONNLOG_TEST_H_ */ + diff --git a/drivers/misc/mediatek/connectivity/conninfra/test/include/coredump_test.h b/drivers/misc/mediatek/connectivity/conninfra/test/include/coredump_test.h new file mode 100755 index 0000000000000000000000000000000000000000..3934ca7726e460a46af7c2fb0fe926162eeae33c --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/test/include/coredump_test.h @@ -0,0 +1,61 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef _COREDUMP_TEST_H_ +#define _COREDUMP_TEST_H_ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +int coredump_test(int par1, int par2, int par3); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _COREDUMP_TEST_H_ */ + + diff --git a/drivers/misc/mediatek/connectivity/conninfra/test/include/mailbox_test.h b/drivers/misc/mediatek/connectivity/conninfra/test/include/mailbox_test.h new file mode 100755 index 0000000000000000000000000000000000000000..99353524c733138401e14e2920976a06a04b1c56 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/test/include/mailbox_test.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#ifndef _MAILBOX_TEST_H_ +#define _MAILBOX_TEST_H_ + +#include "osal.h" +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +int mailbox_test(void); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _MAILBOX_TEST_H_ */ diff --git a/drivers/misc/mediatek/connectivity/conninfra/test/include/msg_evt_test.h b/drivers/misc/mediatek/connectivity/conninfra/test/include/msg_evt_test.h new file mode 100755 index 0000000000000000000000000000000000000000..617c6579790f847b0b6bedd0aeaa820606c1fd25 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/test/include/msg_evt_test.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#ifndef _MSG_EVT_TEST_H_ +#define _MSG_EVT_TEST_H_ + +#include "osal.h" +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + + +int msg_evt_test(void); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _MSG_EVT_TEST_H_ */ diff --git a/drivers/misc/mediatek/connectivity/conninfra/test/mailbox_test.c b/drivers/misc/mediatek/connectivity/conninfra/test/mailbox_test.c new file mode 100755 index 0000000000000000000000000000000000000000..49181bb12eef612a14394c7d490a08487e446e74 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/test/mailbox_test.c @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#include +#include +#include +#include +#include +#include "consys_hw.h" +#include "conninfra_core_test.h" + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +struct demo_client { + struct mbox_client cl; + struct mbox_chan *mbox; + struct completion c; + bool async; +}; + + +static void message_from_remote(struct mbox_client *cl, void *msg) +{ + struct demo_client *dc = container_of(cl, struct demo_client, cl); + if (dc->async) { + pr_info("AAAAsync"); + } else { + pr_info("SSSSSSSync"); + } +} + +static void sample_sent(struct mbox_client *cl, void *msg, int r) +{ + struct demo_client *dc = container_of(cl, struct demo_client, cl); + complete(&dc->c); +} + +int mailbox_test(void) +{ + struct demo_client *dc_sync; + struct platform_device *pdev = get_consys_device(); + + dc_sync = kzalloc(sizeof(*dc_sync), GFP_KERNEL); + dc_sync->cl.dev = &pdev->dev; + dc_sync->cl.rx_callback = message_from_remote; + dc_sync->cl.tx_done = sample_sent; + dc_sync->cl.tx_block = true; + dc_sync->cl.tx_tout = 500; + dc_sync->cl.knows_txdone = false; + dc_sync->async = false; + + dc_sync->mbox = mbox_request_channel(&dc_sync->cl, 0); + + if (IS_ERR(dc_sync->mbox)) { + pr_err("request channel fail [%d]", dc_sync->mbox); + return -1; + } + mbox_send_message(dc_sync->mbox, 0); + + wait_for_completion(&dc_sync->c); + + return 0; +} diff --git a/drivers/misc/mediatek/connectivity/conninfra/test/msg_evt_test.c b/drivers/misc/mediatek/connectivity/conninfra/test/msg_evt_test.c new file mode 100755 index 0000000000000000000000000000000000000000..6efd310a3362ec50f05d4e0137cc929ac47a241b --- /dev/null +++ b/drivers/misc/mediatek/connectivity/conninfra/test/msg_evt_test.c @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/*! \file +* \brief Declaration of library functions +* +* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#define pr_fmt(fmt) "msg_evt_test@(%s:%d) " fmt, __func__, __LINE__ + +#include +#include +#include +#include "msg_thread.h" +#include "msg_evt_test.h" + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +struct work_struct rst_worker; +struct msg_thread_ctx g_ctx; + +typedef enum { + INFRA_TEST_OPID_1 = 0, + INFRA_TEST_OPID_2 = 1, + INFRA_TEST_OPID_MAX +} test_opid; + + +static int opfunc_test_1(struct msg_op_data *op); +static int opfunc_test_2(struct msg_op_data *op); + +static const msg_opid_func test_op_func[] = { + [INFRA_TEST_OPID_1] = opfunc_test_1, + [INFRA_TEST_OPID_2] = opfunc_test_2, +}; + +int opfunc_test_1(struct msg_op_data *op) +{ + pr_info("[%s]", __func__); + return 0; +} + +int opfunc_test_2(struct msg_op_data *op) +{ + unsigned int drv_type = op->op_data[0]; + + pr_info("[%s] param=[%d]", __func__, drv_type); + return 0; +} + + +static void msg_thrd_handler(struct work_struct *work) +{ + msg_thread_send_1(&g_ctx, INFRA_TEST_OPID_2, 2011); + osal_sleep_ms(5); + msg_thread_send_wait_1(&g_ctx, INFRA_TEST_OPID_2, 0, 2022); + msg_thread_send_wait_1(&g_ctx, INFRA_TEST_OPID_2, 0, 2033); +} + +int msg_evt_test(void) +{ + int ret; + + INIT_WORK(&rst_worker, msg_thrd_handler); + + ret = msg_thread_init(&g_ctx, "TestThread", + test_op_func, INFRA_TEST_OPID_MAX); + if (ret) { + pr_err("inti msg_thread fail ret=[%d]\n", ret); + return -2; + } + + schedule_work(&rst_worker); + + msg_thread_send_wait_1(&g_ctx, INFRA_TEST_OPID_2, 0, 1011); + //osal_sleep_ms(10); + msg_thread_send_1(&g_ctx, INFRA_TEST_OPID_2, 1022); + osal_sleep_ms(10); + msg_thread_send_wait_1(&g_ctx, INFRA_TEST_OPID_2, 0, 1033); + + osal_sleep_ms(1000); + + pr_info("<<<<<>>>>>>> freeOpq=[%u][%u] ActiveQ=[%u][%u]", + g_ctx.free_op_q.write, g_ctx.free_op_q.read, + g_ctx.active_op_q.write, g_ctx.active_op_q.read); + osal_sleep_ms(500); + + ret = msg_thread_deinit(&g_ctx); + pr_info("[%s] msg_thread_deinit\n", __func__); + + pr_info("[%s] test PASS\n", __func__); + return 0; +} + + diff --git a/drivers/misc/mediatek/connectivity/fmradio/Makefile b/drivers/misc/mediatek/connectivity/fmradio/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..0b2fdb723f57edf993dfbb827dbb95b52dfc4450 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/Makefile @@ -0,0 +1,154 @@ +# +# Copyright (C) 2015 MediaTek Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 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. +# + +# Force build fail on modpost warning +KBUILD_MODPOST_FAIL_ON_WARNINGS := y +############################################################################### + +MTK_PLATFORM := $(subst ",,$(CONFIG_MTK_PLATFORM)) + +# only WMT align this design flow +#ccflags-y += -D MTK_WCN_REMOVE_KERNEL_MODULE + +ifeq ($(CONFIG_ARM64), y) + ccflags-y += -D CONFIG_MTK_WCN_ARM64 +endif + +ifeq ($(CONFIG_MTK_CONN_LTE_IDC_SUPPORT),y) + ccflags-y += -D WMT_IDC_SUPPORT=1 +else + ccflags-y += -D WMT_IDC_SUPPORT=0 +endif +ccflags-y += -D MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT + +ccflags-y += -I$(srctree)/drivers/misc/mediatek/include +ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat +ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include + +ifeq ($(CONFIG_FM_USER_LOAD),1) + ccflags-y += -D CONFIG_MTK_USER_BUILD +endif + +# Makefile generated by Mediatek +# fm support + +ifneq ($(CONFIG_MTK_FMRADIO),) + +MODULE_NAME := fmradio_drv +obj-m += $(MODULE_NAME).o + +ifeq ($(CFG_FM_CHIP),) + FM_CHIP := mt6631_6635 + + ccflags-y += -I$(src)/chips/mt6631/inc -I$(src)/chips/mt6635/inc + + $(FM_CHIP)-objs += chips/mt6631/pub/mt6631_fm_rds.o + $(FM_CHIP)-objs += chips/mt6635/pub/mt6635_fm_rds.o + $(FM_CHIP)-objs += chips/mt6631/pub/mt6631_fm_lib.o + $(FM_CHIP)-objs += chips/mt6635/pub/mt6635_fm_lib.o + +else + +ifeq ($(CONFIG_MTK_FM_CHIP),) + $(error CONFIG_MTK_FM_CHIP not defined) +endif + +ifneq ($(CFG_FM_CHIP_ID),) + ccflags-y += -D CFG_FM_CHIP_ID=0x$(CFG_FM_CHIP_ID) +endif + + FM_CHIP_MACRO := $(subst ",,$(CONFIG_MTK_FM_CHIP)) + FM_CHIP := $(subst _FM,,$(subst MT,mt,$(subst ",,$(CONFIG_MTK_FM_CHIP)))) + +ifeq ($(FM_CHIP), mt6625) + FM_CHIP := mt6627 + ccflags-y += -DMT6625_FM +endif + +ifeq ($(FM_CHIP), mt6627) + FM_CHIP := mt6627 + ccflags-y += -DMT6627_FM +endif + +ifeq ($(FM_CHIP), mt6580) + FM_CHIP := soc + ccflags-y += -Dsoc +endif + +ifeq ($(FM_CHIP), mt0633) + FM_CHIP := soc + ccflags-y += -Dsoc +endif + +ifeq ($(FM_CHIP), mt6630) + ccflags-y += -DMT6630_FM +endif + +ifeq ($(FM_CHIP), mt6632) + ccflags-y += -DMT6632_FM +endif + +ifeq ($(FM_CHIP), mt6631) + ccflags-y += -DMT6631_FM +endif + +ifeq ($(FM_CHIP), mt6635) + ccflags-y += -DMT6635_FM +endif + + FM_CHIP_PATH := $(FM_CHIP)/pub/$(FM_CHIP) + ccflags-y += -I$(src)/chips/$(FM_CHIP)/inc + + $(FM_CHIP)-objs += chips/$(FM_CHIP_PATH)_fm_rds.o +ifneq ($(CFG_BUILD_CONNAC2), true) + $(FM_CHIP)-objs += chips/$(FM_CHIP_PATH)_fm_lib.o +endif +endif + + +ccflags-y += -I$(src)/inc \ + -I$(src)/plat/inc + +$(FM_CHIP)-objs += core/fm_module.o \ + core/fm_main.o \ + core/fm_config.o \ + core/fm_rds_parser.o \ + core/fm_patch.o \ + core/fm_utils.o \ + core/fm_link.o \ + core/fm_eint.o \ + core/fm_cmd.o \ + core/fm_reg_utils.o + +ifeq ($(CFG_BUILD_CONNAC2), true) + CONNINFRA_SRC_FOLDER := $(srctree)/drivers/misc/mediatek/connectivity/conninfra + + ccflags-y += -I$(CONNINFRA_SRC_FOLDER)/include + ccflags-y += -DCFG_FM_CONNAC2=1 + $(FM_CHIP)-objs += chips/mt6635/pub/mt6635_2_fm_lib.o + $(FM_CHIP)-objs += plat/conn_infra.o +else + WMT_SRC_FOLDER := $(srctree)/drivers/misc/mediatek/connectivity/common + WMT_INCLUDE_PATH := common_main + + ccflags-y += -I$(WMT_SRC_FOLDER)/$(WMT_INCLUDE_PATH)/include \ + -I$(WMT_SRC_FOLDER)/$(WMT_INCLUDE_PATH)/linux/include + ccflags-y += -DCFG_FM_CONNAC2=0 + $(FM_CHIP)-objs += plat/legacy_wmt.o +endif + + $(MODULE_NAME)-objs += $($(FM_CHIP)-objs) + #obj-$(CONFIG_MTK_FMRADIO) += private/ +endif + +obj-y += dummy.o diff --git a/drivers/misc/mediatek/connectivity/fmradio/chips/mt6627/inc/mt6627_drv_dsp.h b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6627/inc/mt6627_drv_dsp.h new file mode 100644 index 0000000000000000000000000000000000000000..957a869719bc3b704380f6891ca4bb6b4c1fa400 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6627/inc/mt6627_drv_dsp.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2015 MediaTek Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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. + */ + + +const unsigned char channel_parameter[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0 +}; diff --git a/drivers/misc/mediatek/connectivity/fmradio/chips/mt6627/inc/mt6627_fm_lib.h b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6627/inc/mt6627_fm_lib.h new file mode 100644 index 0000000000000000000000000000000000000000..f62c130f8b1a2e85f09b62fb789b1ae3d22b2abb --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6627/inc/mt6627_fm_lib.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2015 MediaTek Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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. + */ + +#ifndef __MT6627_FM_LIB_H__ +#define __MT6627_FM_LIB_H__ + +#include "fm_typedef.h" + +enum { + DSPPATCH = 0xFFF9, + USDELAY = 0xFFFA, + MSDELAY = 0xFFFB, + HW_VER = 0xFFFD, + POLL_N = 0xFFFE, /* poling check if bit(n) is '0' */ + POLL_P = 0xFFFF, /* polling check if bit(n) is '1' */ +}; + +enum { + FM_PUS_DSPPATCH = DSPPATCH, + FM_PUS_USDELAY = USDELAY, + FM_PUS_MSDELAY = MSDELAY, + FM_PUS_HW_VER = HW_VER, + FM_PUS_POLL_N = POLL_N, /* poling check if bit(n) is '0' */ + FM_PUS_POLL_P = POLL_P, /* polling check if bit(n) is '1' */ + FM_PUS_MAX +}; + +enum { + mt6627_E1 = 0, + mt6627_E2 +}; + +struct mt6627_fm_cqi { + unsigned short ch; + unsigned short rssi; + unsigned short reserve; +}; + +struct adapt_fm_cqi { + signed int ch; + signed int rssi; + signed int reserve; +}; + +struct mt6627_full_cqi { + unsigned short ch; + unsigned short rssi; + unsigned short pamd; + unsigned short pr; + unsigned short fpamd; + unsigned short mr; + unsigned short atdc; + unsigned short prx; + unsigned short atdev; + unsigned short smg; /* soft-mute gain */ + unsigned short drssi; /* delta rssi */ +}; + +#endif diff --git a/drivers/misc/mediatek/connectivity/fmradio/chips/mt6627/inc/mt6627_fm_reg.h b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6627/inc/mt6627_fm_reg.h new file mode 100644 index 0000000000000000000000000000000000000000..ba7a71d8565bf67e79232605156149c3a23aa7f4 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6627/inc/mt6627_fm_reg.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2015 MediaTek Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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. + */ + +#ifndef __MT6627_FM_REG_H__ +#define __MT6627_FM_REG_H__ + +/* RDS_BDGRP_ABD_CTRL_REG */ +enum { + BDGRP_ABD_EN = 0x0001, + BER_RUN = 0x2000 +}; +#define FM_DAC_CON1 0x83 +#define FM_DAC_CON2 0x84 +#define FM_FT_CON0 0x86 +enum { + FT_EN = 0x0001 +}; + +#define FM_I2S_CON0 0x90 +enum { + I2S_EN = 0x0001, + FORMAT = 0x0002, + WLEN = 0x0004, + I2S_SRC = 0x0008 +}; + +/* FM_MAIN_CTRL */ +enum { + TUNE = 0x0001, + SEEK = 0x0002, + SCAN = 0x0004, + CQI_READ = 0x0008, + RDS_MASK = 0x0010, + MUTE = 0x0020, + RDS_BRST = 0x0040, + RAMP_DOWN = 0x0100, +}; + +enum { + ANTENNA_TYPE = 0x0010, /* 0x61 D4, 0:long, 1:short */ + ANALOG_I2S = 0x0080, /* 0x61 D7, 0:lineout, 1:I2S */ + DE_EMPHASIS = 0x1000, /* 0x61 D12,0:50us, 1:75 us */ +}; + +#define OSC_FREQ_BITS 0x0070 /* 0x60 bit4~6 */ +#define OSC_FREQ_MASK (~OSC_FREQ_BITS) + +#endif /* __MT6627_FM_REG_H__ */ diff --git a/drivers/misc/mediatek/connectivity/fmradio/chips/mt6627/pub/mt6627_fm_lib.c b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6627/pub/mt6627_fm_lib.c new file mode 100644 index 0000000000000000000000000000000000000000..b919fcfac956c1f928420f1cb7f93da8e104f53e --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6627/pub/mt6627_fm_lib.c @@ -0,0 +1,1841 @@ +/* + * Copyright (C) 2015 MediaTek Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 +#include + +#include "osal_typedef.h" +#include "stp_exp.h" +#include "wmt_exp.h" + +#include "fm_typedef.h" +#include "fm_dbg.h" +#include "fm_err.h" +#include "fm_interface.h" +#include "fm_stdlib.h" +#include "fm_patch.h" +#include "fm_utils.h" +#include "fm_link.h" +#include "fm_config.h" +#include "fm_cmd.h" + +#include "mt6627_fm_reg.h" +#include "mt6627_fm_lib.h" + +/* #include "mach/mt_gpio.h" */ + +/* #define MT6627_FM_PATCH_PATH "/etc/firmware/mt6627/mt6627_fm_patch.bin" */ +/* #define MT6627_FM_COEFF_PATH "/etc/firmware/mt6627/mt6627_fm_coeff.bin" */ +/* #define MT6627_FM_HWCOEFF_PATH "/etc/firmware/mt6627/mt6627_fm_hwcoeff.bin" */ +/* #define MT6627_FM_ROM_PATH "/etc/firmware/mt6627/mt6627_fm_rom.bin" */ + +static struct fm_patch_tbl mt6627_patch_tbl[5] = { + {FM_ROM_V1, "mt6627_fm_v1_patch.bin", "mt6627_fm_v1_coeff.bin", NULL, NULL}, + {FM_ROM_V2, "mt6627_fm_v2_patch.bin", "mt6627_fm_v2_coeff.bin", NULL, NULL}, + {FM_ROM_V3, "mt6627_fm_v3_patch.bin", "mt6627_fm_v3_coeff.bin", NULL, NULL}, + {FM_ROM_V4, "mt6627_fm_v4_patch.bin", "mt6627_fm_v4_coeff.bin", NULL, NULL}, + {FM_ROM_V5, "mt6627_fm_v5_patch.bin", "mt6627_fm_v5_coeff.bin", NULL, NULL} +}; + +static struct fm_hw_info mt6627_hw_info = { + .chip_id = 0x00006627, + .eco_ver = 0x00000000, + .rom_ver = 0x00000000, + .patch_ver = 0x00000000, + .reserve = 0x00000000, +}; + +static struct fm_callback *fm_cb_op; +/* static signed int Chip_Version = mt6627_E1; */ + +/* static bool rssi_th_set = false; */ + +#if 0 /* def CONFIG_MTK_FM_50KHZ_SUPPORT */ +static struct fm_fifo *cqi_fifo; +#endif +static signed int mt6627_is_dese_chan(unsigned short freq); +static bool mt6627_I2S_hopping_check(unsigned short freq); + +#if 0 +static signed int mt6627_mcu_dese(unsigned short freq, void *arg); +static signed int mt6627_gps_dese(unsigned short freq, void *arg); +static signed int mt6627_I2s_Setting(signed int onoff, signed int mode, signed int sample); +#endif +static unsigned short mt6627_chan_para_get(unsigned short freq); +static signed int mt6627_desense_check(unsigned short freq, signed int rssi); +static bool mt6627_TDD_chan_check(unsigned short freq); +static signed int mt6627_soft_mute_tune(unsigned short freq, signed int *rssi, signed int *valid); +static signed int mt6627_pwron(signed int data) +{ + if (mtk_wcn_wmt_func_on(WMTDRV_TYPE_FM) == MTK_WCN_BOOL_FALSE) { + WCN_DBG(FM_ERR | CHIP, "WMT turn on FM Fail!\n"); + return -FM_ELINK; + } + + WCN_DBG(FM_NTC | CHIP, "WMT turn on FM OK!\n"); + return 0; +} + +static signed int mt6627_pwroff(signed int data) +{ + if (mtk_wcn_wmt_func_off(WMTDRV_TYPE_FM) == MTK_WCN_BOOL_FALSE) { + WCN_DBG(FM_ERR | CHIP, "WMT turn off FM Fail!\n"); + return -FM_ELINK; + } + + WCN_DBG(FM_NTC | CHIP, "WMT turn off FM OK!\n"); + return 0; +} + +#if 0 +static signed int mt6627_top_set_bits(unsigned short addr, unsigned int bits, unsigned int mask) +{ + signed int ret = 0; + unsigned int val; + + ret = fm_top_reg_read(addr, &val); + + if (ret) + return ret; + + val = ((val & (mask)) | bits); + ret = fm_top_reg_write(addr, val); + + return ret; +} +#endif + +#if 0 +static signed int mt6627_DSP_write(unsigned short addr, unsigned short val) +{ + fm_reg_write(0xE2, addr); + fm_reg_write(0xE3, val); + fm_reg_write(0xE1, 0x0002); + return 0; +} +static signed int mt6627_DSP_read(unsigned short addr, unsigned short *val) +{ + signed int ret = -1; + + fm_reg_write(0xE2, addr); + fm_reg_write(0xE1, 0x0001); + ret = fm_reg_read(0xE4, val); + return ret; +} +#endif + +static unsigned short mt6627_get_chipid(void) +{ + return 0x6627; +} + +/* MT6627_SetAntennaType - set Antenna type + * @type - 1,Short Antenna; 0, Long Antenna + */ +static signed int mt6627_SetAntennaType(signed int type) +{ + unsigned short dataRead = 0; + + WCN_DBG(FM_DBG | CHIP, "set ana to %s\n", type ? "short" : "long"); + fm_reg_read(FM_MAIN_CG2_CTRL, &dataRead); + + if (type) + dataRead |= ANTENNA_TYPE; + else + dataRead &= (~ANTENNA_TYPE); + + fm_reg_write(FM_MAIN_CG2_CTRL, dataRead); + + return 0; +} + +static signed int mt6627_GetAntennaType(void) +{ + unsigned short dataRead = 0; + + fm_reg_read(FM_MAIN_CG2_CTRL, &dataRead); + WCN_DBG(FM_DBG | CHIP, "get ana type: %s\n", (dataRead & ANTENNA_TYPE) ? "short" : "long"); + + if (dataRead & ANTENNA_TYPE) + return FM_ANA_SHORT; /* short antenna */ + else + return FM_ANA_LONG; /* long antenna */ +} + +static signed int mt6627_Mute(bool mute) +{ + signed int ret = 0; + unsigned short dataRead = 0; + + WCN_DBG(FM_DBG | CHIP, "set %s\n", mute ? "mute" : "unmute"); + /* fm_reg_read(FM_MAIN_CTRL, &dataRead); */ + fm_reg_read(0x9C, &dataRead); + + /* fm_top_reg_write(0x0050,0x00000007); */ + if (mute == 1) + ret = fm_reg_write(0x9C, (dataRead & 0xFFFC) | 0x0003); + else + ret = fm_reg_write(0x9C, (dataRead & 0xFFFC)); + + /* fm_top_reg_write(0x0050,0x0000000F); */ + + return ret; +} + +#if 0 +static signed int mt6627_set_RSSITh(unsigned short TH_long, unsigned short TH_short) +{ + fm_reg_write(0xE2, 0x3072); + fm_reg_write(0xE3, TH_long); + fm_reg_write(0xE1, 0x0002); + + fm_delayms(1); + fm_reg_write(0xE2, 0x307A); + fm_reg_write(0xE3, TH_short); + fm_reg_write(0xE1, 0x0002); + + WCN_DBG(FM_DBG | CHIP, "RSSI TH, long:0x%04x, short:0x%04x", TH_long, TH_short); + return 0; +} + +static signed int mt6627_set_SMGTh(signed int ver, unsigned short TH_smg) +{ + if (mt6627_E1 == ver) { + fm_reg_write(0xE2, 0x321E); + fm_reg_write(0xE3, TH_smg); + fm_reg_write(0xE1, 0x0002); + } else { + fm_reg_write(0xE2, 0x3218); + fm_reg_write(0xE3, TH_smg); + fm_reg_write(0xE1, 0x0002); + } + + WCN_DBG(FM_DBG | CHIP, "Soft-mute gain TH %d\n", (int)TH_smg); + return 0; +} +#endif + +static signed int mt6627_pwrup_clock_on_reg_op(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 4; + unsigned short de_emphasis; + /* unsigned short osc_freq; */ + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + de_emphasis = fm_config.rx_cfg.deemphasis; + de_emphasis &= 0x0001; /* rang 0~1 */ + + /* 2,turn on top clock */ + pkt_size += fm_bop_top_write(0xA10, 0xFFFFFFFF, &buf[pkt_size], buf_size - pkt_size); /* wr a10 ffffffff */ + /* 3,enable MTCMOS */ + pkt_size += fm_bop_top_write(0x60, 0x00000030, &buf[pkt_size], buf_size - pkt_size); /* wr 60 30 */ + pkt_size += fm_bop_top_write(0x60, 0x00000035, &buf[pkt_size], buf_size - pkt_size); /* wr 60 35 */ + pkt_size += fm_bop_top_rd_until(0x60, 0x0000000A, 0xA, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_top_write(0x60, 0x00000015, &buf[pkt_size], buf_size - pkt_size); /* wr 60 15 */ + pkt_size += fm_bop_top_write(0x60, 0x00000005, &buf[pkt_size], buf_size - pkt_size); /* wr 60 5 */ + pkt_size += fm_bop_udelay(10, &buf[pkt_size], buf_size - pkt_size); /* delay 10us */ + pkt_size += fm_bop_top_write(0x60, 0x00000045, &buf[pkt_size], buf_size - pkt_size); /* wr 60 45 */ + /* 4,set CSPI fm slave dummy count */ + pkt_size += fm_bop_top_write(0x68, 0x0000003F, &buf[pkt_size], buf_size - pkt_size); /* wr 68 3F */ + + /* a1 enable digital OSC */ + pkt_size += fm_bop_top_write(0x50, 0x00000001, &buf[pkt_size], buf_size - pkt_size); /* wr 50 1 */ + pkt_size += fm_bop_udelay(3000, &buf[pkt_size], buf_size - pkt_size); /* delay 3ms */ + /* a3 set OSC clock output to fm */ + pkt_size += fm_bop_top_write(0x50, 0x00000003, &buf[pkt_size], buf_size - pkt_size); /* wr 50 3 */ + /* a4 release HW clock gating */ + pkt_size += fm_bop_top_write(0x50, 0x00000007, &buf[pkt_size], buf_size - pkt_size); /* wr 50 7 */ + /* set I2S current driving */ + pkt_size += fm_bop_top_write(0x000, 0x00000000, &buf[pkt_size], buf_size - pkt_size); /* wr 0 0 */ + /* a5 enable DSP auto clock gating */ + pkt_size += fm_bop_write(0x70, 0x0040, &buf[pkt_size], buf_size - pkt_size); /* wr 70 0040 */ + /* a7 deemphasis setting */ + pkt_size += fm_bop_modify(0x61, ~DE_EMPHASIS, (de_emphasis << 12), &buf[pkt_size], buf_size - pkt_size); + + /* pkt_size += fm_bop_modify(0x60, OSC_FREQ_MASK, (osc_freq << 4), &buf[pkt_size], buf_size - pkt_size); */ + + return pkt_size - 4; +} +/* + * mt6627_pwrup_clock_on - Wholechip FM Power Up: step 1, FM Digital Clock enable + * @buf - target buf + * @buf_size - buffer size + * return package size + */ +static signed int mt6627_pwrup_clock_on(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 0; + + pkt_size = mt6627_pwrup_clock_on_reg_op(buf, buf_size); + return fm_op_seq_combine_cmd(buf, FM_ENABLE_OPCODE, pkt_size); +} + +static signed int mt6627_pwrup_digital_init_reg_op(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 4; + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + /* FM RF&ADPLL divider setting */ + /* D2.1 set cell mode */ + /* wr 30 D3:D2 00:FDD(default),01:both.10: TDD, 11 FDD */ + /* pkt_size += fm_bop_modify(0x30, 0xFFF3, 0x0000, &buf[pkt_size], buf_size - pkt_size); */ + /* D2.2 set ADPLL divider */ + pkt_size += fm_bop_write(0x21, 0xE000, &buf[pkt_size], buf_size - pkt_size); /* wr 21 E000 */ + /* D2.3 set SDM coeff0_H */ + pkt_size += fm_bop_write(0xD8, 0x03F0, &buf[pkt_size], buf_size - pkt_size); /* wr D8 0x03F0 */ + /* D2.4 set SDM coeff0_L */ + pkt_size += fm_bop_write(0xD9, 0x3F04, &buf[pkt_size], buf_size - pkt_size); /* wr D9 0x3F04 */ + /* D2.5 set SDM coeff1_H */ + pkt_size += fm_bop_write(0xDA, 0x0014, &buf[pkt_size], buf_size - pkt_size); /* wr DA 0x0014 */ + /* D2.6 set SDM coeff1_L */ + pkt_size += fm_bop_write(0xDB, 0x2A38, &buf[pkt_size], buf_size - pkt_size); /* wr DB 0x2A38 */ + /* D2.7 set 26M clock */ + pkt_size += fm_bop_write(0x23, 0x4000, &buf[pkt_size], buf_size - pkt_size); /* wr 23 4000 */ + + /* FM Digital Init: fm_rgf_maincon */ + /* E4 */ + pkt_size += fm_bop_write(0x6A, 0x0021, &buf[pkt_size], buf_size - pkt_size); /* wr 6A 0021 */ + pkt_size += fm_bop_write(0x6B, 0x0021, &buf[pkt_size], buf_size - pkt_size); /* wr 6B 0021 */ + /* E5 */ + pkt_size += fm_bop_top_write(0x50, 0x0000000F, &buf[pkt_size], buf_size - pkt_size); /* wr 50 f */ + /* E6 */ + pkt_size += fm_bop_modify(0x61, 0xFFFD, 0x0002, &buf[pkt_size], buf_size - pkt_size); /* wr 61 D1=1 */ + /* E7 */ + pkt_size += fm_bop_modify(0x61, 0xFFFE, 0x0000, &buf[pkt_size], buf_size - pkt_size); /* wr 61 D0=0 */ + /* E8 */ + pkt_size += fm_bop_udelay(100000, &buf[pkt_size], buf_size - pkt_size); /* delay 100ms */ + /* E9 */ + pkt_size += fm_bop_rd_until(0x64, 0x001F, 0x0002, &buf[pkt_size], buf_size - pkt_size); /* Poll 64[0~4] = 2 */ + + return pkt_size - 4; +} + +/* + * mt6627_pwrup_digital_init - Wholechip FM Power Up: step 4, FM Digital Init: fm_rgf_maincon + * @buf - target buf + * @buf_size - buffer size + * return package size + */ +static signed int mt6627_pwrup_digital_init(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 0; + + pkt_size = mt6627_pwrup_digital_init_reg_op(buf, buf_size); + return fm_op_seq_combine_cmd(buf, FM_ENABLE_OPCODE, pkt_size); +} + +static signed int mt6627_pwrup_fine_tune_reg_op(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 4; + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + /* F1 set host control RF register */ + pkt_size += fm_bop_top_write(0x50, 0x00000007, &buf[pkt_size], buf_size - pkt_size); + /* F2 fine tune RF setting */ + pkt_size += fm_bop_write(0x01, 0xBEE8, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x03, 0xF6ED, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x15, 0x0D80, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x16, 0x0068, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x17, 0x092A, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x34, 0x807F, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x35, 0x311E, &buf[pkt_size], buf_size - pkt_size); + /* F1 set DSP control RF register */ + pkt_size += fm_bop_top_write(0x50, 0x0000000F, &buf[pkt_size], buf_size - pkt_size); + + return pkt_size - 4; +} + +/* + * mt6627_pwrup_fine_tune - Wholechip FM Power Up: step 5, FM RF fine tune setting + * @buf - target buf + * @buf_size - buffer size + * return package size + */ +static signed int mt6627_pwrup_fine_tune(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 0; + + pkt_size = mt6627_pwrup_fine_tune_reg_op(buf, buf_size); + return fm_op_seq_combine_cmd(buf, FM_ENABLE_OPCODE, pkt_size); +} + +static signed int mt6627_pwrdown_reg_op(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 4; + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + /* A1:set audio output I2S Tx mode: */ + pkt_size += fm_bop_modify(0x9B, 0xFFF8, 0x0000, &buf[pkt_size], buf_size - pkt_size); + + /* B0:Disable HW clock control */ + pkt_size += fm_bop_top_write(0x50, 0x330F, &buf[pkt_size], buf_size - pkt_size); + /* B1:Reset ASIP */ + pkt_size += fm_bop_write(0x61, 0x0001, &buf[pkt_size], buf_size - pkt_size); + /* B2:digital core + digital rgf reset */ + pkt_size += fm_bop_modify(0x6E, 0xFFF8, 0x0000, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_modify(0x6E, 0xFFF8, 0x0000, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_modify(0x6E, 0xFFF8, 0x0000, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_modify(0x6E, 0xFFF8, 0x0000, &buf[pkt_size], buf_size - pkt_size); + /* B3:Disable all clock */ + pkt_size += fm_bop_top_write(0x50, 0x0000, &buf[pkt_size], buf_size - pkt_size); + /* B4:Reset rgfrf */ + pkt_size += fm_bop_top_write(0x50, 0x4000, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_top_write(0x50, 0x0000, &buf[pkt_size], buf_size - pkt_size); + /* MTCMOS power off */ + /* C0:disable MTCMOS */ + pkt_size += fm_bop_top_write(0x60, 0x0005, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_top_write(0x60, 0x0015, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_top_write(0x60, 0x0035, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_top_write(0x60, 0x0030, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_top_rd_until(0x60, 0x0000000A, 0x0, &buf[pkt_size], buf_size - pkt_size); + + return pkt_size - 4; +} +/* + * mt6627_pwrdown - Wholechip FM Power down: Digital Modem Power Down + * @buf - target buf + * @buf_size - buffer size + * return package size + */ +static signed int mt6627_pwrdown(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 0; + + pkt_size = mt6627_pwrdown_reg_op(buf, buf_size); + return fm_op_seq_combine_cmd(buf, FM_ENABLE_OPCODE, pkt_size); +} + +static signed int mt6627_tune_reg_op(unsigned char *buf, signed int buf_size, unsigned short freq, + unsigned short chan_para) +{ + signed int pkt_size = 4; + + WCN_DBG(FM_ALT | CHIP, "%s enter mt6627_tune function\n", __func__); + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + /* Set desired channel & channel parameter */ +#ifdef FM_TUNE_USE_POLL + pkt_size += fm_bop_write(0x6A, 0x0000, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x6B, 0x0000, &buf[pkt_size], buf_size - pkt_size); +#endif + pkt_size += fm_bop_modify(FM_MAIN_CTRL, 0xFFF8, TUNE, &buf[pkt_size], buf_size - pkt_size); + /* Wait for STC_DONE interrupt */ +#ifdef FM_TUNE_USE_POLL + pkt_size += fm_bop_rd_until(FM_MAIN_INTR, FM_INTR_STC_DONE, FM_INTR_STC_DONE, &buf[pkt_size], + buf_size - pkt_size); + /* Write 1 clear the STC_DONE interrupt status flag */ + pkt_size += fm_bop_modify(FM_MAIN_INTR, 0xFFFF, FM_INTR_STC_DONE, &buf[pkt_size], buf_size - pkt_size); +#endif + + WCN_DBG(FM_ALT | CHIP, "%s leave mt6627_tune function\n", __func__); + + return pkt_size - 4; +} + +/* + * mt6627_tune - execute tune action, + * @buf - target buf + * @buf_size - buffer size + * @freq - 760 ~ 1080, 100KHz unit + * return package size + */ +static signed int mt6627_tune(unsigned char *buf, signed int buf_size, unsigned short freq, + unsigned short chan_para) +{ + signed int pkt_size = 0; + + pkt_size = mt6627_tune_reg_op(buf, buf_size, freq, chan_para); + return fm_op_seq_combine_cmd(buf, FM_TUNE_OPCODE, pkt_size); +} + +static signed int mt6627_rampdown_reg_op(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 4; + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + /* Clear DSP state */ + pkt_size += fm_bop_modify(FM_MAIN_CTRL, 0xFFF0, 0x0000, &buf[pkt_size], buf_size - pkt_size); + /* Set DSP ramp down state */ + pkt_size += fm_bop_modify(FM_MAIN_CTRL, 0xFFFF, RAMP_DOWN, &buf[pkt_size], buf_size - pkt_size); + /* @Wait for STC_DONE interrupt@ */ + pkt_size += fm_bop_rd_until(FM_MAIN_INTR, FM_INTR_STC_DONE, FM_INTR_STC_DONE, &buf[pkt_size], + buf_size - pkt_size); + /* Clear DSP ramp down state */ + pkt_size += fm_bop_modify(FM_MAIN_CTRL, (~RAMP_DOWN), 0x0000, &buf[pkt_size], buf_size - pkt_size); + /* Write 1 clear the STC_DONE interrupt status flag */ + pkt_size += fm_bop_modify(FM_MAIN_INTR, 0xFFFF, FM_INTR_STC_DONE, &buf[pkt_size], buf_size - pkt_size); + + return pkt_size - 4; +} +/* + * mt6627_rampdown - f/w will wait for STC_DONE interrupt + * @buf - target buf + * @buf_size - buffer size + * return package size + */ +static signed int mt6627_rampdown(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 0; + + pkt_size = mt6627_rampdown_reg_op(buf, buf_size); + return fm_op_seq_combine_cmd(buf, FM_RAMPDOWN_OPCODE, pkt_size); +} + +static signed int mt6627_RampDown(void) +{ + signed int ret = 0; + unsigned short pkt_size; + /* unsigned short tmp; */ + + WCN_DBG(FM_DBG | CHIP, "ramp down\n"); + /* pwer up sequence 0425 */ + ret = fm_top_reg_write(0x0050, 0x00000007); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "ramp down wr top 0x50 failed\n"); + return ret; + } + + ret = fm_set_bits(0x0F, 0x0000, 0xF800); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "ramp down wr 0x0f failed\n"); + return ret; + } + + ret = fm_top_reg_write(0x0050, 0x0000000F); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "ramp down wr top 0x50 failed\n"); + return ret; + } + + /* fm_reg_read(FM_MAIN_INTRMASK, &tmp); */ + ret = fm_reg_write(FM_MAIN_INTRMASK, 0x0000); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "ramp down wr FM_MAIN_INTRMASK failed\n"); + return ret; + } + + ret = fm_reg_write(FM_MAIN_EXTINTRMASK, 0x0000); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "ramp down wr FM_MAIN_EXTINTRMASK failed\n"); + return ret; + } + + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = mt6627_rampdown(cmd_buf, TX_BUF_SIZE); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_RAMPDOWN, SW_RETRY_CNT, RAMPDOWN_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + + if (ret) { + WCN_DBG(FM_ERR | CHIP, "ramp down failed\n"); + return ret; + } + + ret = fm_reg_write(FM_MAIN_EXTINTRMASK, 0x0021); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "ramp down wr FM_MAIN_EXTINTRMASK failed\n"); + return ret; + } + + ret = fm_reg_write(FM_MAIN_INTRMASK, 0x0021); + if (ret) + WCN_DBG(FM_ERR | CHIP, "ramp down wr FM_MAIN_INTRMASK failed\n"); + + return ret; +} + +static signed int mt6627_get_rom_version(void) +{ + unsigned short tmp = 0; + signed int ret = 0; + + /* DSP rom code version request enable --- set 0x61 b15=1 */ + fm_set_bits(0x61, 0x8000, 0x7FFF); + + /* Release ASIP reset --- set 0x61 b1=1 */ + fm_set_bits(0x61, 0x0002, 0xFFFD); + + /* Enable ASIP power --- set 0x61 b0=0 */ + fm_set_bits(0x61, 0x0000, 0xFFFE); + + /* Wait DSP code version ready --- wait 1ms */ + do { + fm_delayus(1000); + ret = fm_reg_read(0x84, &tmp); + /* ret=-4 means signal got when control FM. usually get sig 9 to kill FM process. */ + /* now cancel FM power up sequence is recommended. */ + if (ret) + return ret; + + WCN_DBG(FM_DBG | CHIP, "0x84=%x\n", tmp); + } while (tmp != 0x0001); + + /* Get FM DSP code version --- rd 0x83[15:8] */ + fm_reg_read(0x83, &tmp); + tmp = (tmp >> 8); + + /* DSP rom code version request disable --- set 0x61 b15=0 */ + fm_set_bits(0x61, 0x0000, 0x7FFF); + + /* Reset ASIP --- set 0x61[1:0] = 1 */ + fm_set_bits(0x61, 0x0001, 0xFFFC); + + /* WCN_DBG(FM_NTC | CHIP, "ROM version: v%d\n", (signed int)tmp); */ + return (signed int) tmp; +} + +/* + * mt6627_pwrup_DSP_download - execute dsp/coeff patch dl action, + * @patch_tbl - current chip patch table + * return patch dl ok or not + */ +static signed int mt6627_pwrup_DSP_download(struct fm_patch_tbl *patch_tbl) +{ +#define PATCH_BUF_SIZE (4096*6) + signed int ret = 0; + signed int patch_len = 0; + unsigned char *dsp_buf = NULL; + unsigned short tmp_reg = 0; + + mt6627_hw_info.eco_ver = (signed int) mtk_wcn_wmt_ic_info_get(1); + WCN_DBG(FM_DBG | CHIP, "ECO version:0x%08x\n", mt6627_hw_info.eco_ver); + + /* get mt6627 DSP rom version */ + ret = mt6627_get_rom_version(); + if (ret >= 0) { + mt6627_hw_info.rom_ver = ret; + WCN_DBG(FM_DBG | CHIP, "ROM version: v%d\n", mt6627_hw_info.rom_ver); + } else { + WCN_DBG(FM_ERR | CHIP, "get ROM version failed\n"); + /* ret=-4 means signal got when control FM. usually get sig 9 to kill FM process. */ + /* now cancel FM power up sequence is recommended. */ + goto out; + } + + /* Wholechip FM Power Up: step 3, download patch */ + dsp_buf = fm_vmalloc(PATCH_BUF_SIZE); + if (!dsp_buf) { + WCN_DBG(FM_ALT | CHIP, "-ENOMEM\n"); + return -ENOMEM; + } + + patch_len = fm_get_patch_path(mt6627_hw_info.rom_ver, dsp_buf, PATCH_BUF_SIZE, patch_tbl); + if (patch_len <= 0) { + WCN_DBG(FM_ALT | CHIP, " fm_get_patch_path failed\n"); + ret = patch_len; + goto out; + } + + ret = fm_download_patch((const unsigned char *)dsp_buf, patch_len, IMG_PATCH); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " DL DSPpatch failed\n"); + goto out; + } + + patch_len = fm_get_coeff_path(mt6627_hw_info.rom_ver, dsp_buf, PATCH_BUF_SIZE, patch_tbl); + if (patch_len <= 0) { + WCN_DBG(FM_ALT | CHIP, " fm_get_coeff_path failed\n"); + ret = patch_len; + goto out; + } + + mt6627_hw_info.rom_ver += 1; + + tmp_reg = dsp_buf[38] | (dsp_buf[39] << 8); /* to be confirmed */ + mt6627_hw_info.patch_ver = (signed int) tmp_reg; + WCN_DBG(FM_NTC | CHIP, "Patch version: 0x%08x\n", mt6627_hw_info.patch_ver); + + if (ret == 1) { + dsp_buf[4] = 0x00; /* if we found rom version undefined, we should disable patch */ + dsp_buf[5] = 0x00; + } + + ret = fm_download_patch((const unsigned char *)dsp_buf, patch_len, IMG_COEFFICIENT); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " DL DSPcoeff failed\n"); + goto out; + } + fm_reg_write(0x92, 0x0000); /* ? */ + fm_reg_write(0x90, 0x0040); + fm_reg_write(0x90, 0x0000); + +out: + if (dsp_buf) { + fm_vfree(dsp_buf); + dsp_buf = NULL; + } + return ret; +} + +static signed int mt6627_PowerUp(unsigned short *chip_id, unsigned short *device_id) +{ + signed int ret = 0; + unsigned short pkt_size; + unsigned short tmp_reg = 0; +#if defined(MT6625_FM) + unsigned int host_reg = 0; +#endif + + if (chip_id == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (device_id == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + WCN_DBG(FM_DBG | CHIP, "pwr on seq......\n"); + + /* Wholechip FM Power Up: step 1, set common SPI parameter */ + ret = fm_host_reg_write(0x8013000C, 0x0000801F); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup set CSPI failed\n"); + return ret; + } +#if defined(MT6625_FM) + ret = fm_host_reg_read(0x80000224, &host_reg); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup read 0x80000224 failed\n"); + return ret; + } + ret = fm_host_reg_write(0x80000224, host_reg | (1 << 0)); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup conn_srcclkena enable failed\n"); + return ret; + } + + ret = fm_host_reg_read(0x80000224, &host_reg); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup read 0x80000224 failed\n"); + return ret; + } + ret = fm_host_reg_write(0x80000224, host_reg | (1 << 16)); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup conn_srcclkena switch failed\n"); + return ret; + } + + ret = fm_host_reg_read(0x80101030, &host_reg); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup read 0x80100030 failed\n"); + return ret; + } + ret = fm_host_reg_write(0x80101030, host_reg | (1 << 1)); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup enable top_ck_en_adie failed\n"); + return ret; + } + + /* enable bgldo */ + ret = fm_top_reg_read(0x00c0, &host_reg); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "power up read top 0xc0 failed\n"); + return ret; + } + ret = fm_top_reg_write(0x00c0, host_reg | (0x3 << 27)); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "power up write top 0xc0 failed\n"); + return ret; + } +#endif + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = mt6627_pwrup_clock_on(cmd_buf, TX_BUF_SIZE); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + + if (ret) { + WCN_DBG(FM_ALT | CHIP, "mt6627_pwrup_clock_on failed\n"); + return ret; + } +/* #ifdef FM_DIGITAL_INPUT */ + /* mt6627_I2s_Setting(MT6627_I2S_ON, MT6627_I2S_MASTER, MT6627_I2S_44K); */ + /* mt_combo_audio_ctrl(COMBO_AUDIO_STATE_2); */ + /* mtk_wcn_cmb_stub_audio_ctrl((CMB_STUB_AIF_X)CMB_STUB_AIF_2); */ +/* #endif */ + + /* Wholechip FM Power Up: step 2, read HW version */ + fm_reg_read(0x62, &tmp_reg); + /* *chip_id = tmp_reg; */ + if ((tmp_reg == 0x6625) || (tmp_reg == 0x6627)) + *chip_id = 0x6627; + *device_id = tmp_reg; + mt6627_hw_info.chip_id = (signed int) tmp_reg; + WCN_DBG(FM_DBG | CHIP, "chip_id:0x%04x\n", tmp_reg); + + if ((mt6627_hw_info.chip_id != 0x6627) && (mt6627_hw_info.chip_id != 0x6625)) { + WCN_DBG(FM_NTC | CHIP, "fm sys error, reset hw\n"); + return -FM_EFW; + } + + /* Wholechip FM Power Up: step 3, patch download */ + ret = mt6627_pwrup_DSP_download(mt6627_patch_tbl); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "mt6627_pwrup_DSP_download failed\n"); + return ret; + } + + /* Wholechip FM Power Up: step 4, FM Digital Init: fm_rgf_maincon */ + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = mt6627_pwrup_digital_init(cmd_buf, TX_BUF_SIZE); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + if (ret) { + WCN_DBG(FM_ALT | CHIP, "mt6627_pwrup_digital_init failed\n"); + return ret; + } + /* Wholechip FM Power Up: step 5, FM RF fine tune setting */ + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = mt6627_pwrup_fine_tune(cmd_buf, TX_BUF_SIZE); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + if (ret) { + WCN_DBG(FM_ALT | CHIP, "mt6627_pwrup_fine_tune failed\n"); + return ret; + } + /* enable connsys FM 2 wire RX */ + fm_reg_write(0x9B, 0xF9AB); + fm_host_reg_write(0x80101054, 0x00003f35); + + WCN_DBG(FM_DBG | CHIP, "pwr on seq ok\n"); + + return ret; +} + +static signed int mt6627_PowerDown(void) +{ + signed int ret = 0; + unsigned short pkt_size; + unsigned short dataRead = 0; + unsigned int tem = 0; +#if defined(MT6625_FM) + unsigned int host_reg = 0; + + WCN_DBG(FM_DBG | CHIP, "pwr down seq, but not clear top_clk_en_adie\n"); +#endif + + WCN_DBG(FM_DBG | CHIP, "pwr down seq\n"); + /*SW work around for MCUFA issue. + *if interrupt happen before doing rampdown, DSP can't switch MCUFA back well. + * In case read interrupt, and clean if interrupt found before rampdown. + */ + fm_reg_read(FM_MAIN_INTR, &dataRead); + + if (dataRead & 0x1) + fm_reg_write(FM_MAIN_INTR, dataRead); /* clear status flag */ + + /* mt6627_RampDown(); */ + +/* #ifdef FM_DIGITAL_INPUT */ +/* mt6627_I2s_Setting(MT6627_I2S_OFF, MT6627_I2S_SLAVE, MT6627_I2S_44K); */ +/* #endif */ + /* pwer up sequence 0425 */ + /* A0:set audio output I2X Rx mode: */ + fm_host_reg_read(0x80101054, &tem); + tem = tem & 0xFFFF9FFF; + fm_host_reg_write(0x80101054, tem); + + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = mt6627_pwrdown(cmd_buf, TX_BUF_SIZE); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + + if (ret) { + WCN_DBG(FM_ALT | CHIP, "mt6627_pwrdown failed\n"); + return ret; + } + /* FIX_ME, disable ext interrupt */ + fm_reg_write(FM_MAIN_EXTINTRMASK, 0x00); + +#if defined(MT6625_FM) + /* ret = fm_host_reg_read(0x80101030, &host_reg); + * if (ret) { + * WCN_DBG(FM_ALT | CHIP, " pwroff read 0x80100030 failed\n"); + * return ret; + * } + * WCN_DBG(FM_DBG | CHIP, "read host reg 0x80101030=%x\n", host_reg); + * ret = fm_host_reg_write(0x80101030, host_reg & (~(0x1 << 1))); + * if (ret) { + * WCN_DBG(FM_ALT | CHIP, " pwroff disable top_ck_en_adie failed\n"); + * return ret; + * } + */ + + ret = fm_host_reg_read(0x80000224, &host_reg); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwroff read 0x80000224 failed\n"); + return ret; + } + WCN_DBG(FM_DBG | CHIP, "read host reg 0x80000224=%x\n", host_reg); + ret = fm_host_reg_write(0x80000224, host_reg & (~(1 << 16))); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwroff conn_srcclkena switch failed\n"); + return ret; + } +#endif + +/* rssi_th_set = false; */ + return ret; +} + +/* just for dgb */ +#if 0 +static void mt6627_bt_write(unsigned int addr, unsigned int val) +{ + unsigned int tem, i = 0; + + fm_host_reg_write(0x80103020, addr); + fm_host_reg_write(0x80103024, val); + fm_host_reg_read(0x80103000, &tem); + while ((tem == 4) && (i < 1000)) { + i++; + fm_host_reg_read(0x80103000, &tem); + } +} +#endif +static bool mt6627_SetFreq(unsigned short freq) +{ + signed int ret = 0; + unsigned short pkt_size; + unsigned short chan_para = 0; + unsigned int reg_val = 0; + unsigned short freq_reg = 0; + + fm_cb_op->cur_freq_set(freq); + +#if 0 + /* MCU clock adjust if need */ + ret = mt6627_mcu_dese(freq, NULL); + if (ret < 0) + WCN_DBG(FM_ERR | MAIN, "mt6627_mcu_dese FAIL:%d\n", ret); + + WCN_DBG(FM_INF | MAIN, "MCU %d\n", ret); + + /* GPS clock adjust if need */ + ret = mt6627_gps_dese(freq, NULL); + if (ret < 0) + WCN_DBG(FM_ERR | MAIN, "mt6627_gps_dese FAIL:%d\n", ret); + + WCN_DBG(FM_INF | MAIN, "GPS %d\n", ret); +#endif + /* pwer up sequence 0425 */ + ret = fm_top_reg_write(0x0050, 0x00000007); + if (ret) + WCN_DBG(FM_ERR | CHIP, "set freq wr top 0x50 failed\n"); + + ret = fm_set_bits(0x0F, 0x0455, 0xF800); + if (ret) + WCN_DBG(FM_ERR | CHIP, "set freq wr 0x0f failed\n"); + + if (mt6627_TDD_chan_check(freq)) { + ret = fm_set_bits(0x30, 0x0008, 0xFFF3); /* use TDD solution */ + if (ret) + WCN_DBG(FM_ERR | CHIP, "set freq wr 0x30 failed\n"); + } else { + ret = fm_set_bits(0x30, 0x0000, 0xFFF3); /* default use FDD solution */ + if (ret) + WCN_DBG(FM_ERR | CHIP, "set freq wr 0x30 failed\n"); + } + ret = fm_top_reg_write(0x0050, 0x0000000F); + if (ret) + WCN_DBG(FM_ERR | CHIP, "set freq wr top 0x50 failed\n"); + +/* if (fm_cb_op->chan_para_get) { */ + chan_para = mt6627_chan_para_get(freq); + WCN_DBG(FM_DBG | CHIP, "%d chan para = %d\n", (signed int) freq, (signed int) chan_para); +/* } */ + + freq_reg = freq; + if (fm_get_channel_space(freq_reg) == 0) + freq_reg *= 10; + + freq_reg = (freq_reg - 6400) * 2 / 10; + ret = fm_set_bits(0x65, freq_reg, 0xFC00); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "set freq wr 0x65 failed\n"); + return false; + } + + ret = fm_set_bits(0x65, (chan_para << 12), 0x0FFF); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "set freq wr 0x65 failed\n"); + return false; + } + + /* enable connsys FM 2 wire RX */ + fm_reg_write(0x9B, 0xF9AB); + fm_host_reg_write(0x80101054, 0x00003f35); + + if ((mt6627_hw_info.chip_id == 0x6625) + && ((mtk_wcn_wmt_chipid_query() == 0x6592) || (mtk_wcn_wmt_chipid_query() == 0x6752) + || (mtk_wcn_wmt_chipid_query() == 0x6755) || (mtk_wcn_wmt_chipid_query() == 0x6757) + || (mtk_wcn_wmt_chipid_query() == 0x6763) || (mtk_wcn_wmt_chipid_query() == 0x6739))) { + if (mt6627_I2S_hopping_check(freq)) { + /* set i2s TX desense mode */ + ret = fm_set_bits(0x9C, 0x80, 0xFFFF); + if (ret) + WCN_DBG(FM_ERR | CHIP, "set freq wr 0x9C failed\n"); + + /* set i2s RX desense mode */ + ret = fm_host_reg_read(0x80101054, ®_val); + if (ret) + WCN_DBG(FM_ERR | CHIP, "set freq rd 0x80101054 failed\n"); + + reg_val |= 0x8000; + ret = fm_host_reg_write(0x80101054, reg_val); + if (ret) + WCN_DBG(FM_ERR | CHIP, "set freq wr 0x80101054 failed\n"); + } else { + ret = fm_set_bits(0x9C, 0x0, 0xFF7F); + if (ret) + WCN_DBG(FM_ERR | CHIP, "set freq wr 0x9C failed\n"); + + ret = fm_host_reg_read(0x80101054, ®_val); + if (ret) + WCN_DBG(FM_ERR | CHIP, "set freq rd 0x80101054 failed\n"); + + reg_val &= 0x7FFF; + ret = fm_host_reg_write(0x80101054, reg_val); + if (ret) + WCN_DBG(FM_ERR | CHIP, "set freq wr 0x80101054 failed\n"); + } + } + + if (FM_LOCK(cmd_buf_lock)) + return false; + pkt_size = mt6627_tune(cmd_buf, TX_BUF_SIZE, freq, chan_para); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_TUNE | FLAG_TUNE_DONE, SW_RETRY_CNT, TUNE_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + + if (ret) { + WCN_DBG(FM_ALT | CHIP, "mt6627_tune failed\n"); + return false; + } + + WCN_DBG(FM_DBG | CHIP, "set freq to %d ok\n", freq); +#if 0 + /* ADPLL setting for dbg */ + fm_top_reg_write(0x0050, 0x00000007); + fm_top_reg_write(0x0A08, 0xFFFFFFFF); + mt6627_bt_write(0x82, 0x11); + mt6627_bt_write(0x83, 0x11); + mt6627_bt_write(0x84, 0x11); + fm_top_reg_write(0x0040, 0x1C1C1C1C); + fm_top_reg_write(0x0044, 0x1C1C1C1C); + fm_reg_write(0x70, 0x0010); + /*0x0806 DCO clk + *0x0802 ref clk + *0x0804 feedback clk + */ + fm_reg_write(0xE0, 0x0806); +#endif + return true; +} + +#define FM_CQI_LOG_PATH "/mnt/sdcard/fmcqilog" + +static signed int mt6627_full_cqi_get(signed int min_freq, signed int max_freq, signed int space, signed int cnt) +{ + signed int ret = 0; + unsigned short pkt_size; + unsigned short freq, orig_freq; + signed int i, j, k; + signed int space_val, max, min, num; + struct mt6627_full_cqi *p_cqi; + unsigned char *cqi_log_title = "Freq, RSSI, PAMD, PR, FPAMD, MR, ATDC, PRX, ATDEV, SMGain, DltaRSSI\n"; + unsigned char cqi_log_buf[100] = { 0 }; + signed int pos; + unsigned char cqi_log_path[100] = { 0 }; + + /* for soft-mute tune, and get cqi */ + freq = fm_cb_op->cur_freq_get(); + if (fm_get_channel_space(freq) == 0) + freq *= 10; + + /* get cqi */ + orig_freq = freq; + if (fm_get_channel_space(min_freq) == 0) + min = min_freq * 10; + else + min = min_freq; + + if (fm_get_channel_space(max_freq) == 0) + max = max_freq * 10; + else + max = max_freq; + + if (space == 0x0001) + space_val = 5; /* 50Khz */ + else if (space == 0x0002) + space_val = 10; /* 100Khz */ + else if (space == 0x0004) + space_val = 20; /* 200Khz */ + else + space_val = 10; + + num = (max - min) / space_val + 1; /* Eg, (8760 - 8750) / 10 + 1 = 2 */ + for (k = 0; (orig_freq == 10000) && (g_dbg_level == 0xffffffff) && (k < cnt); k++) { + WCN_DBG(FM_NTC | CHIP, "cqi file:%d\n", k + 1); + freq = min; + pos = 0; + fm_memcpy(cqi_log_path, FM_CQI_LOG_PATH, strlen(FM_CQI_LOG_PATH)); + if (sprintf(&cqi_log_path[strlen(FM_CQI_LOG_PATH)], "%d.txt", k + 1) < 0) + WCN_DBG(FM_NTC | CHIP, "sprintf fail\n"); + fm_file_write(cqi_log_path, cqi_log_title, strlen(cqi_log_title), &pos); + for (j = 0; j < num; j++) { + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = fm_full_cqi_req(cmd_buf, TX_BUF_SIZE, &freq, 1, 1); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_SM_TUNE, SW_RETRY_CNT, + SM_TUNE_TIMEOUT, fm_get_read_result); + FM_UNLOCK(cmd_buf_lock); + + if (!ret && fm_res) { + WCN_DBG(FM_NTC | CHIP, "smt cqi size %d\n", fm_res->cqi[0]); + p_cqi = (struct mt6627_full_cqi *)&fm_res->cqi[2]; + for (i = 0; i < fm_res->cqi[1]; i++) { + /* just for debug */ + WCN_DBG(FM_NTC | CHIP, + "freq %d, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x\n", + p_cqi[i].ch, p_cqi[i].rssi, p_cqi[i].pamd, + p_cqi[i].pr, p_cqi[i].fpamd, p_cqi[i].mr, + p_cqi[i].atdc, p_cqi[i].prx, p_cqi[i].atdev, + p_cqi[i].smg, p_cqi[i].drssi); + /* format to buffer */ + if (sprintf(cqi_log_buf, + "%04d, %04x, %04x, %04x, %04x, %04x, %04x, %04x, %04x, %04x, %04x,\n", + p_cqi[i].ch, p_cqi[i].rssi, p_cqi[i].pamd, + p_cqi[i].pr, p_cqi[i].fpamd, p_cqi[i].mr, + p_cqi[i].atdc, p_cqi[i].prx, p_cqi[i].atdev, + p_cqi[i].smg, p_cqi[i].drssi) < 0) + WCN_DBG(FM_NTC | CHIP, "sprintf fail\n"); + /* write back to log file */ + fm_file_write(cqi_log_path, cqi_log_buf, strlen(cqi_log_buf), &pos); + } + } else { + WCN_DBG(FM_ALT | CHIP, "smt get CQI failed\n"); + ret = -1; + } + freq += space_val; + } + fm_cb_op->cur_freq_set(0); /* avoid run too much times */ + } + + return ret; +} + +/* + * mt6627_GetCurRSSI - get current freq's RSSI value + * RS=RSSI + * If RS>511, then RSSI(dBm)= (RS-1024)/16*6 + * else RSSI(dBm)= RS/16*6 + */ +static signed int mt6627_GetCurRSSI(signed int *pRSSI) +{ + unsigned short tmp_reg = 0; + + fm_reg_read(FM_RSSI_IND, &tmp_reg); + tmp_reg = tmp_reg & 0x03ff; + + if (pRSSI) { + *pRSSI = (tmp_reg > 511) ? (((tmp_reg - 1024) * 6) >> 4) : ((tmp_reg * 6) >> 4); + WCN_DBG(FM_DBG | CHIP, "rssi:%d, dBm:%d\n", tmp_reg, *pRSSI); + } else { + WCN_DBG(FM_ERR | CHIP, "get rssi para error\n"); + return -FM_EPARA; + } + + return 0; +} + +static unsigned short mt6627_vol_tbl[16] = { 0x0000, 0x0519, 0x066A, 0x0814, + 0x0A2B, 0x0CCD, 0x101D, 0x1449, + 0x198A, 0x2027, 0x287A, 0x32F5, + 0x4027, 0x50C3, 0x65AD, 0x7FFF +}; + +static signed int mt6627_SetVol(unsigned char vol) +{ + signed int ret = 0; + + vol = (vol > 15) ? 15 : vol; + ret = fm_reg_write(0x7D, mt6627_vol_tbl[vol]); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "Set vol=%d Failed\n", vol); + return ret; + } + + WCN_DBG(FM_DBG | CHIP, "Set vol=%d OK\n", vol); + + if (vol == 10) { + fm_print_cmd_fifo(); /* just for debug */ + fm_print_evt_fifo(); + } + return 0; +} + +static signed int mt6627_GetVol(unsigned char *pVol) +{ + int ret = 0; + unsigned short tmp = 0; + signed int i; + + if (pVol == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + ret = fm_reg_read(0x7D, &tmp); + if (ret) { + *pVol = 0; + WCN_DBG(FM_ERR | CHIP, "Get vol Failed\n"); + return ret; + } + + for (i = 0; i < 16; i++) { + if (mt6627_vol_tbl[i] == tmp) { + *pVol = i; + break; + } + } + + WCN_DBG(FM_DBG | CHIP, "Get vol=%d OK\n", *pVol); + return 0; +} + +static signed int mt6627_dump_reg(void) +{ + signed int i; + unsigned short TmpReg = 0; + + for (i = 0; i < 0xff; i++) { + fm_reg_read(i, &TmpReg); + WCN_DBG(FM_NTC | CHIP, "0x%02x=0x%04x\n", i, TmpReg); + } + return 0; +} + +/*0:mono, 1:stereo*/ +static bool mt6627_GetMonoStereo(unsigned short *pMonoStereo) +{ +#define FM_BF_STEREO 0x1000 + unsigned short TmpReg = 0; + + if (pMonoStereo) { + fm_reg_read(FM_RSSI_IND, &TmpReg); + *pMonoStereo = (TmpReg & FM_BF_STEREO) >> 12; + } else { + WCN_DBG(FM_ERR | CHIP, "MonoStero: para err\n"); + return false; + } + + WCN_DBG(FM_NTC | CHIP, "Get MonoStero:0x%04x\n", *pMonoStereo); + return true; +} + +static signed int mt6627_SetMonoStereo(signed int MonoStereo) +{ + signed int ret = 0; + + WCN_DBG(FM_NTC | CHIP, "set to %s\n", MonoStereo ? "mono" : "auto"); + fm_top_reg_write(0x50, 0x0007); + + if (MonoStereo) /*mono */ + ret = fm_set_bits(0x75, 0x0008, ~0x0008); + else + ret = fm_set_bits(0x75, 0x0000, ~0x0008); + + fm_top_reg_write(0x50, 0x000F); + return ret; +} + +static signed int mt6627_GetCapArray(signed int *ca) +{ + unsigned short dataRead = 0; + unsigned short tmp = 0; + + if (ca == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + fm_reg_read(0x60, &tmp); + fm_reg_write(0x60, tmp & 0xFFF7); /* 0x60 D3=0 */ + + fm_reg_read(0x26, &dataRead); + *ca = dataRead; + + fm_reg_write(0x60, tmp); /* 0x60 D3=1 */ + return 0; +} + +/* + * mt6627_GetCurPamd - get current freq's PAMD value + * PA=PAMD + * If PA>511 then PAMD(dB)= (PA-1024)/16*6, + * else PAMD(dB)=PA/16*6 + */ +static bool mt6627_GetCurPamd(unsigned short *pPamdLevl) +{ + unsigned short tmp_reg = 0; + unsigned short dBvalue, valid_cnt = 0; + int i, total = 0; + + for (i = 0; i < 8; i++) { + if (fm_reg_read(FM_ADDR_PAMD, &tmp_reg)) { + *pPamdLevl = 0; + return false; + } + + tmp_reg &= 0x03FF; + dBvalue = (tmp_reg > 256) ? ((512 - tmp_reg) * 6 / 16) : 0; + if (dBvalue != 0) { + total += dBvalue; + valid_cnt++; + WCN_DBG(FM_DBG | CHIP, "[%d]PAMD=%d\n", i, dBvalue); + } + fm_delayms(3); + } + if (valid_cnt != 0) + *pPamdLevl = total / valid_cnt; + else + *pPamdLevl = 0; + + WCN_DBG(FM_NTC | CHIP, "PAMD=%d\n", *pPamdLevl); + return true; +} + +static signed int mt6627_i2s_info_get(signed int *ponoff, signed int *pmode, signed int *psample) +{ + if (ponoff == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (pmode == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (psample == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + *ponoff = fm_config.aud_cfg.i2s_info.status; + *pmode = fm_config.aud_cfg.i2s_info.mode; + *psample = fm_config.aud_cfg.i2s_info.rate; + + return 0; +} + +static signed int mt6627fm_get_audio_info(struct fm_audio_info_t *data) +{ + memcpy(data, &fm_config.aud_cfg, sizeof(struct fm_audio_info_t)); + return 0; +} + +static signed int mt6627_hw_info_get(struct fm_hw_info *req) +{ + if (req == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + req->chip_id = mt6627_hw_info.chip_id; + req->eco_ver = mt6627_hw_info.eco_ver; + req->patch_ver = mt6627_hw_info.patch_ver; + req->rom_ver = mt6627_hw_info.rom_ver; + + return 0; +} + +static signed int mt6627_pre_search(void) +{ + mt6627_RampDown(); + /* disable audio output I2S Rx mode */ + fm_host_reg_write(0x80101054, 0x00000000); + /* disable audio output I2S Tx mode */ + fm_reg_write(0x9B, 0x0000); + + return 0; +} + +static signed int mt6627_restore_search(void) +{ + mt6627_RampDown(); + /* set audio output I2S Tx mode */ + fm_reg_write(0x9B, 0xF9AB); + /* set audio output I2S Rx mode */ + fm_host_reg_write(0x80101054, 0x00003f35); + return 0; +} + +static signed int mt6627_soft_mute_tune(unsigned short freq, signed int *rssi, signed int *valid) +{ + signed int ret = 0; + unsigned short pkt_size; + /* unsigned short freq;//, orig_freq; */ + struct mt6627_full_cqi *p_cqi; + signed int RSSI = 0, PAMD = 0, MR = 0, ATDC = 0; + unsigned int PRX = 0, ATDEV = 0; + unsigned short softmuteGainLvl = 0; + + ret = mt6627_chan_para_get(freq); + if (ret == 2) + ret = fm_set_bits(FM_CHANNEL_SET, 0x2000, 0x0FFF); /* mdf HiLo */ + else + ret = fm_set_bits(FM_CHANNEL_SET, 0x0000, 0x0FFF); /* clear FA/HL/ATJ */ + + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = fm_full_cqi_req(cmd_buf, TX_BUF_SIZE, &freq, 1, 1); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_SM_TUNE, SW_RETRY_CNT, SM_TUNE_TIMEOUT, fm_get_read_result); + FM_UNLOCK(cmd_buf_lock); + + if (!ret && fm_res) { + p_cqi = (struct mt6627_full_cqi *)&fm_res->cqi[2]; + + RSSI = ((p_cqi->rssi & 0x03FF) >= 512) ? ((p_cqi->rssi & 0x03FF) - 1024) : (p_cqi->rssi & 0x03FF); + PAMD = ((p_cqi->pamd & 0x1FF) >= 256) ? ((p_cqi->pamd & 0x01FF) - 512) : (p_cqi->pamd & 0x01FF); + MR = ((p_cqi->mr & 0x01FF) >= 256) ? ((p_cqi->mr & 0x01FF) - 512) : (p_cqi->mr & 0x01FF); + ATDC = (p_cqi->atdc >= 32768) ? (65536 - p_cqi->atdc) : (p_cqi->atdc); + if (ATDC < 0) + ATDC = (~(ATDC)) - 1; /* Get abs value of ATDC */ + + PRX = (p_cqi->prx & 0x00FF); + ATDEV = p_cqi->atdev; + softmuteGainLvl = p_cqi->smg; + /* check if the channel is valid according to each CQIs */ + if ((fm_config.rx_cfg.long_ana_rssi_th <= RSSI) + && (fm_config.rx_cfg.pamd_th >= PAMD) + && (fm_config.rx_cfg.atdc_th >= ATDC) + && (fm_config.rx_cfg.mr_th <= MR) + && (fm_config.rx_cfg.prx_th <= PRX) + && (ATDEV >= ATDC) /* sync scan algorithm */ + && (fm_config.rx_cfg.smg_th <= softmuteGainLvl)) { + *valid = true; + } else { + *valid = false; + } + WCN_DBG(FM_NTC | CHIP, + "valid=%d, freq %d, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x\n", + *valid, p_cqi->ch, p_cqi->rssi, p_cqi->pamd, p_cqi->pr, p_cqi->fpamd, p_cqi->mr, + p_cqi->atdc, p_cqi->prx, p_cqi->atdev, p_cqi->smg, p_cqi->drssi); + + *rssi = RSSI; + } else { + WCN_DBG(FM_ALT | CHIP, "smt get CQI failed\n"); + return false; + } + return true; +} + +static bool mt6627_em_test(unsigned short group_idx, unsigned short item_idx, unsigned int item_value) +{ + return true; +} + +/* +*parm: +* parm.th_type: 0, RSSI. 1,desense RSSI. 2,SMG. +* parm.th_val: threshold value +*/ +static signed int mt6627_set_search_th(signed int idx, signed int val, signed int reserve) +{ + switch (idx) { + case 0: { + fm_config.rx_cfg.long_ana_rssi_th = val; + WCN_DBG(FM_NTC | CHIP, "set rssi th =%d\n", val); + break; + } + case 1: { + fm_config.rx_cfg.desene_rssi_th = val; + WCN_DBG(FM_NTC | CHIP, "set desense rssi th =%d\n", val); + break; + } + case 2: { + fm_config.rx_cfg.smg_th = val; + WCN_DBG(FM_NTC | CHIP, "set smg th =%d\n", val); + break; + } + default: + break; + } + return 0; +} + +static signed int MT6627fm_low_power_wa_default(signed int fmon) +{ + return 0; +} + +signed int fm_low_ops_register(struct fm_callback *cb, struct fm_basic_interface *bi) +{ + signed int ret = 0; + /* Basic functions. */ + + if (bi == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,bi invalid pointer\n", __func__); + return -FM_EPARA; + } + if (cb->cur_freq_get == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,cb->cur_freq_get invalid pointer\n", __func__); + return -FM_EPARA; + } + if (cb->cur_freq_set == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,cb->cur_freq_set invalid pointer\n", __func__); + return -FM_EPARA; + } + fm_cb_op = cb; + + bi->pwron = mt6627_pwron; + bi->pwroff = mt6627_pwroff; + bi->chipid_get = mt6627_get_chipid; + bi->mute = mt6627_Mute; + bi->rampdown = mt6627_RampDown; + bi->pwrupseq = mt6627_PowerUp; + bi->pwrdownseq = mt6627_PowerDown; + bi->setfreq = mt6627_SetFreq; + bi->low_pwr_wa = MT6627fm_low_power_wa_default; + bi->get_aud_info = mt6627fm_get_audio_info; + bi->rssiget = mt6627_GetCurRSSI; + bi->volset = mt6627_SetVol; + bi->volget = mt6627_GetVol; + bi->dumpreg = mt6627_dump_reg; + bi->msget = mt6627_GetMonoStereo; + bi->msset = mt6627_SetMonoStereo; + bi->pamdget = mt6627_GetCurPamd; + bi->em = mt6627_em_test; + bi->anaswitch = mt6627_SetAntennaType; + bi->anaget = mt6627_GetAntennaType; + bi->caparray_get = mt6627_GetCapArray; + bi->hwinfo_get = mt6627_hw_info_get; + bi->i2s_get = mt6627_i2s_info_get; + bi->is_dese_chan = mt6627_is_dese_chan; + bi->softmute_tune = mt6627_soft_mute_tune; + bi->desense_check = mt6627_desense_check; + bi->cqi_log = mt6627_full_cqi_get; + bi->pre_search = mt6627_pre_search; + bi->restore_search = mt6627_restore_search; + bi->set_search_th = mt6627_set_search_th; + + cmd_buf_lock = fm_lock_create("27_cmd"); + ret = fm_lock_get(cmd_buf_lock); + + cmd_buf = fm_zalloc(TX_BUF_SIZE + 1); + + if (!cmd_buf) { + WCN_DBG(FM_ALT | CHIP, "6627 fm lib alloc tx buf failed\n"); + ret = -1; + } +#if 0 /* def CONFIG_MTK_FM_50KHZ_SUPPORT */ + cqi_fifo = fm_fifo_create("6628_cqi_fifo", sizeof(struct adapt_fm_cqi), 640); + if (!cqi_fifo) { + WCN_DBG(FM_ALT | CHIP, "6627 fm lib create cqi fifo failed\n"); + ret = -1; + } +#endif + + return ret; +} + +signed int fm_low_ops_unregister(struct fm_basic_interface *bi) +{ + signed int ret = 0; + /* Basic functions. */ + if (bi == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + +#if 0 /* def CONFIG_MTK_FM_50KHZ_SUPPORT */ + fm_fifo_release(cqi_fifo); +#endif + + if (cmd_buf) { + fm_free(cmd_buf); + cmd_buf = NULL; + } + + ret = fm_lock_put(cmd_buf_lock); + fm_memset(bi, 0, sizeof(struct fm_basic_interface)); + return ret; +} + +/* static struct fm_pub pub; */ +/* static struct fm_pub_cb *pub_cb = &pub.pub_tbl; */ + +static const unsigned short mt6627_mcu_dese_list[] = { + 7630, 7800, 7940, 8320, 9260, 9600, 9710, 9920, 10400, 10410 +}; + +static const unsigned short mt6627_gps_dese_list[] = { + 7850, 7860 +}; + +static const signed char mt6627_chan_para_map[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, /* 6500~6595 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6600~6695 */ + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, /* 6700~6795 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6800~6895 */ + 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6900~6995 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7000~7095 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, /* 7100~7195 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, /* 7200~7295 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7300~7395 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7400~7495 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7500~7595 */ + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, /* 7600~7695 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7700~7795 */ + 8, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7800~7895 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, /* 7900~7995 */ + 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, /* 8000~8095 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8100~8195 */ + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8200~8295 */ + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8300~8395 */ + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8400~8495 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8500~8595 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8600~8695 */ + 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8700~8795 */ + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8800~8895 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8900~8995 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9000~9095 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9100~9195 */ + 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9200~9295 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, /* 9300~9395 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9400~9495 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9500~9595 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9600~9695 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9700~9795 */ + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9800~9895 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, /* 9900~9995 */ + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10000~10095 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10100~10195 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, /* 10200~10295 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10300~10395 */ + 8, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10400~10495 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10500~10595 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10600~10695 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, /* 10700~10795 */ + 0 /* 10800 */ +}; + +static const unsigned short mt6627_scan_dese_list[] = { + 6910, 7680, 7800, 9210, 9220, 9230, 9600, 9980, 9990, 10400, 10750, 10760 +}; + +static const unsigned short mt6627_I2S_hopping_list[] = { + 6550, 6760, 6960, 6970, 7170, 7370, 7580, 7780, 7990, 8810, 9210, 9220, 10240 +}; + +static const unsigned short mt6627_TDD_list[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 6500~6595 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 6600~6695 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 6700~6795 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 6800~6895 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 6900~6995 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7000~7095 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7100~7195 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7200~7295 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7300~7395 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7400~7495 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7500~7595 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7600~7695 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7700~7795 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7800~7895 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7900~7995 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8000~8095 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8100~8195 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8200~8295 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8300~8395 */ + 0x0101, 0x0000, 0x0000, 0x0000, 0x0000, /* 8400~8495 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8500~8595 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8600~8695 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8700~8795 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8800~8895 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8900~8995 */ + 0x0000, 0x0000, 0x0101, 0x0101, 0x0101, /* 9000~9095 */ + 0x0101, 0x0000, 0x0000, 0x0000, 0x0000, /* 9100~9195 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9200~9295 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9300~9395 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9400~9495 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9500~9595 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9600~9695 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0100, /* 9700~9795 */ + 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, /* 9800~9895 */ + 0x0101, 0x0101, 0x0001, 0x0000, 0x0000, /* 9900~9995 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10000~10095 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10100~10195 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10200~10295 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10300~10395 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10400~10495 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10500~10595 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0100, /* 10600~10695 */ + 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, /* 10700~10795 */ + 0x0001 /* 10800 */ +}; + +static const unsigned short mt6627_TDD_Mask[] = { + 0x0001, 0x0010, 0x0100, 0x1000 +}; + +/* return value: 0, not a de-sense channel; 1, this is a de-sense channel; else error no */ +static signed int mt6627_is_dese_chan(unsigned short freq) +{ + signed int size; + + /* return 0;//HQA only :skip desense channel check. */ + size = ARRAY_SIZE(mt6627_scan_dese_list); + + if (fm_get_channel_space(freq) == 0) + freq *= 10; + + while (size) { + if (mt6627_scan_dese_list[size - 1] == freq) + return 1; + + size--; + } + + return 0; +} + +/* return value: +*1, is desense channel and rssi is less than threshold; +*0, not desense channel or it is but rssi is more than threshold. +*/ +static signed int mt6627_desense_check(unsigned short freq, signed int rssi) +{ + if (mt6627_is_dese_chan(freq)) { + if (rssi < fm_config.rx_cfg.desene_rssi_th) + return 1; + + WCN_DBG(FM_DBG | CHIP, "desen_rssi %d th:%d\n", rssi, fm_config.rx_cfg.desene_rssi_th); + } + return 0; +} + +static bool mt6627_TDD_chan_check(unsigned short freq) +{ + unsigned int i = 0; + unsigned short freq_tmp = freq; + signed int ret = 0; + + ret = fm_get_channel_space(freq_tmp); + if (ret == 0) + freq_tmp *= 10; + else if (ret == -1) + return false; + + i = (freq_tmp - 6500) / 5; + if ((i / 4) >= ARRAY_SIZE(mt6627_TDD_list)) { + WCN_DBG(FM_ERR | CHIP, "Freq index out of range(%d),max(%zd)\n", + i / 4, ARRAY_SIZE(mt6627_TDD_list)); + return false; + } + + if (mt6627_TDD_list[i / 4] & mt6627_TDD_Mask[i % 4]) { + WCN_DBG(FM_NTC | CHIP, "Freq %d use TDD solution\n", freq); + return true; + } else + return false; +} + +/* get channel parameter, HL side/ FA / ATJ */ +static unsigned short mt6627_chan_para_get(unsigned short freq) +{ + signed int pos, size; + + /* return 0;//for HQA only: skip FA/HL/ATJ */ + if (fm_get_channel_space(freq) == 0) + freq *= 10; + + if (freq < 6500) + return 0; + + pos = (freq - 6500) / 5; + + size = ARRAY_SIZE(mt6627_chan_para_map); + + pos = (pos > (size - 1)) ? (size - 1) : pos; + + return mt6627_chan_para_map[pos]; +} + +static bool mt6627_I2S_hopping_check(unsigned short freq) +{ + signed int size; + + size = ARRAY_SIZE(mt6627_I2S_hopping_list); + + if (fm_get_channel_space(freq) == 0) + freq *= 10; + + while (size) { + if (mt6627_I2S_hopping_list[size - 1] == freq) + return 1; + size--; + } + + return 0; +} diff --git a/drivers/misc/mediatek/connectivity/fmradio/chips/mt6627/pub/mt6627_fm_rds.c b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6627/pub/mt6627_fm_rds.c new file mode 100644 index 0000000000000000000000000000000000000000..20bad698b319b03e0fc0a9c772c96805360e1ba5 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6627/pub/mt6627_fm_rds.c @@ -0,0 +1,334 @@ +/* + * Copyright (C) 2015 MediaTek Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 "fm_typedef.h" +#include "fm_dbg.h" +#include "fm_err.h" +#include "fm_interface.h" +#include "fm_stdlib.h" +#include "fm_rds.h" +#include "mt6627_fm_reg.h" +#include "fm_cmd.h" + +static bool bRDS_FirstIn; /* false */ +static unsigned int gBLER_CHK_INTERVAL = 500; +static unsigned short GOOD_BLK_CNT = 0, BAD_BLK_CNT; +static unsigned char BAD_BLK_RATIO; + +static struct fm_basic_interface *fm_bi; + +static bool mt6627_RDS_support(void); +static signed int mt6627_RDS_enable(void); +static signed int mt6627_RDS_disable(void); +static unsigned short mt6627_RDS_Get_GoodBlock_Counter(void); +static unsigned short mt6627_RDS_Get_BadBlock_Counter(void); +static unsigned char mt6627_RDS_Get_BadBlock_Ratio(void); +static unsigned int mt6627_RDS_Get_BlerCheck_Interval(void); +/* static void mt6627_RDS_GetData(unsigned short *data, unsigned short datalen); */ +static void mt6627_RDS_Init_Data(struct rds_t *pstRDSData); + +static bool mt6627_RDS_support(void) +{ + return true; +} + +static signed int mt6627_RDS_enable(void) +{ + signed int ret = 0; + unsigned short dataRead = 0; + + WCN_DBG(FM_DBG | RDSC, "rds enable\n"); + ret = fm_reg_read(FM_RDS_CFG0, &dataRead); + if (ret) { + WCN_DBG(FM_NTC | RDSC, "rds enable read 0x80 fail\n"); + return ret; + } + ret = fm_reg_write(FM_RDS_CFG0, 6); /* set buf_start_th */ + if (ret) { + WCN_DBG(FM_NTC | RDSC, "rds enable write 0x80 fail\n"); + return ret; + } + ret = fm_reg_read(FM_MAIN_CTRL, &dataRead); + if (ret) { + WCN_DBG(FM_NTC | RDSC, "rds enable read 0x63 fail\n"); + return ret; + } + ret = fm_reg_write(FM_MAIN_CTRL, dataRead | (RDS_MASK)); + if (ret) { + WCN_DBG(FM_NTC | RDSC, "rds enable write 0x63 fail\n"); + return ret; + } + + return ret; +} + +static signed int mt6627_RDS_disable(void) +{ + signed int ret = 0; + unsigned short dataRead = 0; + + WCN_DBG(FM_DBG | RDSC, "rds disable\n"); + ret = fm_reg_read(FM_MAIN_CTRL, &dataRead); + if (ret) { + WCN_DBG(FM_NTC | RDSC, "rds disable read 0x63 fail\n"); + return ret; + } + ret = fm_reg_write(FM_MAIN_CTRL, dataRead & (~RDS_MASK)); + if (ret) { + WCN_DBG(FM_NTC | RDSC, "rds disable write 0x63 fail\n"); + return ret; + } + + return ret; +} + +static unsigned short mt6627_RDS_Get_GoodBlock_Counter(void) +{ + unsigned short tmp_reg = 0; + + fm_reg_read(FM_RDS_GOODBK_CNT, &tmp_reg); + GOOD_BLK_CNT = tmp_reg; + WCN_DBG(FM_DBG | RDSC, "get good block cnt:%d\n", (signed int) tmp_reg); + + return tmp_reg; +} + +static unsigned short mt6627_RDS_Get_BadBlock_Counter(void) +{ + unsigned short tmp_reg = 0; + + fm_reg_read(FM_RDS_BADBK_CNT, &tmp_reg); + BAD_BLK_CNT = tmp_reg; + WCN_DBG(FM_DBG | RDSC, "get bad block cnt:%d\n", (signed int) tmp_reg); + + return tmp_reg; +} + +static unsigned char mt6627_RDS_Get_BadBlock_Ratio(void) +{ + unsigned short tmp_reg; + unsigned short gbc; + unsigned short bbc; + + gbc = mt6627_RDS_Get_GoodBlock_Counter(); + bbc = mt6627_RDS_Get_BadBlock_Counter(); + + if ((gbc + bbc) > 0) + tmp_reg = (unsigned char) (bbc * 100 / (gbc + bbc)); + else + tmp_reg = 0; + + BAD_BLK_RATIO = tmp_reg; + WCN_DBG(FM_DBG | RDSC, "get badblock ratio:%d\n", (signed int) tmp_reg); + + return tmp_reg; +} + +static signed int mt6627_RDS_BlockCounter_Reset(void) +{ + mt6627_RDS_disable(); + mt6627_RDS_enable(); + + return 0; +} + +static unsigned int mt6627_RDS_Get_BlerCheck_Interval(void) +{ + return gBLER_CHK_INTERVAL; +} + +static signed int mt6627_RDS_BlerCheck(struct rds_t *dst) +{ + return 0; +} + +#if 0 +static void RDS_Recovery_Handler(void) +{ + unsigned short tempData = 0; + + do { + fm_reg_read(FM_RDS_DATA_REG, &tempData); + fm_reg_read(FM_RDS_POINTER, &tempData); + } while (tempData & 0x3); +} +#endif + +#if 0 +static void mt6627_RDS_GetData(unsigned short *data, unsigned short datalen) +{ +#define RDS_GROUP_DIFF_OFS 0x007C +#define RDS_FIFO_DIFF 0x007F +#define RDS_CRC_BLK_ADJ 0x0020 +#define RDS_CRC_CORR_CNT 0x001E +#define RDS_CRC_INFO 0x0001 + + unsigned short CRC = 0, i = 0, RDS_adj = 0, RDSDataCount = 0, FM_WARorrCnt = 0; + unsigned short temp = 0, OutputPofm_s32 = 0; + + WCN_DBG(FM_DBG | RDSC, "get data\n"); + fm_reg_read(FM_RDS_FIFO_STATUS0, &temp); + RDSDataCount = ((RDS_GROUP_DIFF_OFS & temp) << 2); + + if ((temp & RDS_FIFO_DIFF) >= 4) { + /* block A data and info handling */ + fm_reg_read(FM_RDS_INFO, &temp); + RDS_adj |= (temp & RDS_CRC_BLK_ADJ) << 10; + CRC |= (temp & RDS_CRC_INFO) << 3; + FM_WARorrCnt |= ((temp & RDS_CRC_CORR_CNT) << 11); + fm_reg_read(FM_RDS_DATA_REG, &data[0]); + + /* block B data and info handling */ + fm_reg_read(FM_RDS_INFO, &temp); + RDS_adj |= (temp & RDS_CRC_BLK_ADJ) << 9; + CRC |= (temp & RDS_CRC_INFO) << 2; + FM_WARorrCnt |= ((temp & RDS_CRC_CORR_CNT) << 7); + fm_reg_read(FM_RDS_DATA_REG, &data[1]); + + /* block C data and info handling */ + fm_reg_read(FM_RDS_INFO, &temp); + RDS_adj |= (temp & RDS_CRC_BLK_ADJ) << 8; + CRC |= (temp & RDS_CRC_INFO) << 1; + FM_WARorrCnt |= ((temp & RDS_CRC_CORR_CNT) << 3); + fm_reg_read(FM_RDS_DATA_REG, &data[2]); + + /* block D data and info handling */ + fm_reg_read(FM_RDS_INFO, &temp); + RDS_adj |= (temp & RDS_CRC_BLK_ADJ) << 7; + CRC |= (temp & RDS_CRC_INFO); + FM_WARorrCnt |= ((temp & RDS_CRC_CORR_CNT) >> 1); + fm_reg_read(FM_RDS_DATA_REG, &data[3]); + + data[4] = (CRC | RDS_adj | RDSDataCount); + data[5] = FM_WARorrCnt; + + fm_reg_read(FM_RDS_PWDI, &data[6]); + fm_reg_read(FM_RDS_PWDQ, &data[7]); + + fm_reg_read(FM_RDS_POINTER, &OutputPofm_s32); + + /* Go fm_s32o RDS recovery handler while RDS output pofm_s32 doesn't align to 4 in numeric */ + if (OutputPofm_s32 & 0x3) + RDS_Recovery_Handler(); + + } else { + for (; i < 8; i++) + data[i] = 0; + } +} +#endif + +static void mt6627_RDS_Init_Data(struct rds_t *pstRDSData) +{ + fm_memset(pstRDSData, 0, sizeof(struct rds_t)); + bRDS_FirstIn = true; + + pstRDSData->event_status = 0x0000; + fm_memset(pstRDSData->RT_Data.TextData, 0x20, sizeof(pstRDSData->RT_Data.TextData)); + fm_memset(pstRDSData->PS_Data.PS, '\0', sizeof(pstRDSData->PS_Data.PS)); + fm_memset(pstRDSData->PS_ON, 0x20, sizeof(pstRDSData->PS_ON)); +} + +bool mt6627_RDS_OnOff(struct rds_t *dst, bool bFlag) +{ + signed int ret = 0; + + if (mt6627_RDS_support() == false) { + WCN_DBG(FM_ALT | RDSC, "mt6627_RDS_OnOff failed, RDS not support\n"); + return false; + } + + if (bFlag) { + mt6627_RDS_Init_Data(dst); + ret = mt6627_RDS_enable(); + if (ret) { + WCN_DBG(FM_NTC | RDSC, "mt6627_RDS_OnOff enable failed\n"); + return false; + } + } else { + mt6627_RDS_Init_Data(dst); + ret = mt6627_RDS_disable(); + if (ret) { + WCN_DBG(FM_NTC | RDSC, "mt6627_RDS_OnOff disable failed\n"); + return false; + } + } + + return true; +} + +DEFINE_RDSLOG(mt6627_rds_log); + +/* mt6627_RDS_Efm_s32_Handler - response FM RDS interrupt + * @fm - main data structure of FM driver + * This function first get RDS raw data, then call RDS spec parser + */ +static signed int mt6627_rds_parser(struct rds_t *rds_dst, struct rds_rx_t *rds_raw, + signed int rds_size, unsigned short(*getfreq) (void)) +{ + mt6627_rds_log.log_in(&mt6627_rds_log, rds_raw, rds_size); + return rds_parser(rds_dst, rds_raw, rds_size, getfreq); +} + +static signed int mt6627_rds_log_get(struct rds_rx_t *dst, signed int *dst_len) +{ + return mt6627_rds_log.log_out(&mt6627_rds_log, dst, dst_len); +} + +static signed int mt6627_rds_gc_get(struct rds_group_cnt_t *dst, struct rds_t *rdsp) +{ + return rds_grp_counter_get(dst, &rdsp->gc); +} + +static signed int mt6627_rds_gc_reset(struct rds_t *rdsp) +{ + return rds_grp_counter_reset(&rdsp->gc); +} + +signed int fm_rds_ops_register(struct fm_basic_interface *bi, struct fm_rds_interface *ri) +{ + signed int ret = 0; + + if (ri == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,ri invalid pointer\n", __func__); + return -FM_EPARA; + } + fm_bi = bi; + + ri->rds_blercheck = mt6627_RDS_BlerCheck; + ri->rds_onoff = mt6627_RDS_OnOff; + ri->rds_parser = mt6627_rds_parser; + ri->rds_gbc_get = mt6627_RDS_Get_GoodBlock_Counter; + ri->rds_bbc_get = mt6627_RDS_Get_BadBlock_Counter; + ri->rds_bbr_get = mt6627_RDS_Get_BadBlock_Ratio; + ri->rds_bc_reset = mt6627_RDS_BlockCounter_Reset; + ri->rds_bci_get = mt6627_RDS_Get_BlerCheck_Interval; + ri->rds_log_get = mt6627_rds_log_get; + ri->rds_gc_get = mt6627_rds_gc_get; + ri->rds_gc_reset = mt6627_rds_gc_reset; + return ret; +} + +signed int fm_rds_ops_unregister(struct fm_rds_interface *ri) +{ + signed int ret = 0; + + if (ri == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,ri invalid pointer\n", __func__); + return -FM_EPARA; + } + + fm_bi = NULL; + fm_memset(ri, 0, sizeof(struct fm_rds_interface)); + return ret; +} diff --git a/drivers/misc/mediatek/connectivity/fmradio/chips/mt6630/inc/mt6630_fm_lib.h b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6630/inc/mt6630_fm_lib.h new file mode 100644 index 0000000000000000000000000000000000000000..55fd695b2031d52d1b3126a063c98e84854c4124 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6630/inc/mt6630_fm_lib.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2015 MediaTek Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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. + */ + +#ifndef __MT6630_FM_LIB_H__ +#define __MT6630_FM_LIB_H__ + +#include "fm_typedef.h" + +enum { + DSPPATCH = 0xFFF9, + USDELAY = 0xFFFA, + MSDELAY = 0xFFFB, + HW_VER = 0xFFFD, + POLL_N = 0xFFFE, /* poling check if bit(n) is '0' */ + POLL_P = 0xFFFF, /* polling check if bit(n) is '1' */ +}; + +enum { + FM_PUS_DSPPATCH = DSPPATCH, + FM_PUS_USDELAY = USDELAY, + FM_PUS_MSDELAY = MSDELAY, + FM_PUS_HW_VER = HW_VER, + FM_PUS_POLL_N = POLL_N, /* poling check if bit(n) is '0' */ + FM_PUS_POLL_P = POLL_P, /* polling check if bit(n) is '1' */ + FM_PUS_MAX +}; + +enum { + mt6630_E1 = 0, + mt6630_E2 +}; + +struct mt6630_fm_cqi { + unsigned short ch; + unsigned short rssi; + unsigned short reserve; +}; + +struct adapt_fm_cqi { + signed int ch; + signed int rssi; + signed int reserve; +}; + +struct mt6630_full_cqi { + unsigned short ch; + unsigned short rssi; + unsigned short pamd; + unsigned short pr; + unsigned short fpamd; + unsigned short mr; + unsigned short atdc; + unsigned short prx; + unsigned short atdev; + unsigned short smg; /* soft-mute gain */ + unsigned short drssi; /* delta rssi */ +}; + +#endif diff --git a/drivers/misc/mediatek/connectivity/fmradio/chips/mt6630/inc/mt6630_fm_reg.h b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6630/inc/mt6630_fm_reg.h new file mode 100644 index 0000000000000000000000000000000000000000..cab9c814e4ca3c83856c584ed13c93451b52f594 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6630/inc/mt6630_fm_reg.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2015 MediaTek Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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. + */ + +#ifndef __MT6630_FM_REG_H__ +#define __MT6630_FM_REG_H__ + +/* RDS_BDGRP_ABD_CTRL_REG */ +enum { + BDGRP_ABD_EN = 0x0001, + BER_RUN = 0x2000 +}; +#define FM_DAC_CON1 0x83 +#define FM_DAC_CON2 0x84 +#define FM_FT_CON0 0x86 +enum { + FT_EN = 0x0001 +}; + +#define FM_I2S_CON0 0x90 +enum { + I2S_EN = 0x0001, + FORMAT = 0x0002, + WLEN = 0x0004, + I2S_SRC = 0x0008 +}; + +/* FM_MAIN_CTRL */ +enum { + TUNE = 0x0001, + SEEK = 0x0002, + SCAN = 0x0004, + CQI_READ = 0x0008, + RDS_MASK = 0x0010, + MUTE = 0x0020, + RDS_BRST = 0x0040, + RAMP_DOWN = 0x0100, +}; + +enum { + ANTENNA_TYPE = 0x0010, /* 0x61 D4, 0:long, 1:short */ + ANALOG_I2S = 0x0080, /* 0x61 D7, 0:lineout, 1:I2S */ + DE_EMPHASIS = 0x1000, /* 0x61 D12,0:50us, 1:75 us */ +}; + +#define OSC_FREQ_BITS 0x0070 /* 0x60 bit4~6 */ +#define OSC_FREQ_MASK (~OSC_FREQ_BITS) + +#endif /* __MT6630_FM_REG_H__ */ diff --git a/drivers/misc/mediatek/connectivity/fmradio/chips/mt6630/pub/mt6630_fm_lib.c b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6630/pub/mt6630_fm_lib.c new file mode 100644 index 0000000000000000000000000000000000000000..bbff7210ae252b8f0bcdb2db19edf9d77e32ca50 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6630/pub/mt6630_fm_lib.c @@ -0,0 +1,2471 @@ +/* + * Copyright (C) 2015 MediaTek Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 +#include + +#include "stp_exp.h" +#include "wmt_exp.h" + +#include "fm_typedef.h" +#include "fm_dbg.h" +#include "fm_err.h" +#include "fm_interface.h" +#include "fm_stdlib.h" +#include "fm_patch.h" +#include "fm_utils.h" +#include "fm_link.h" +#include "fm_config.h" +#include "fm_cmd.h" + +#include "mt6630_fm_reg.h" +#include "mt6630_fm_lib.h" + +static struct fm_patch_tbl mt6630_patch_tbl[5] = { + {FM_ROM_V1, "mt6630_fm_v1_patch.bin", "mt6630_fm_v1_coeff.bin", NULL, NULL}, + {FM_ROM_V2, "mt6630_fm_v2_patch.bin", "mt6630_fm_v2_coeff.bin", NULL, NULL}, + {FM_ROM_V3, "mt6630_fm_v3_patch.bin", "mt6630_fm_v3_coeff.bin", NULL, NULL}, + {FM_ROM_V4, "mt6630_fm_v4_patch.bin", "mt6630_fm_v4_coeff.bin", NULL, NULL}, + {FM_ROM_V5, "mt6630_fm_v5_patch.bin", "mt6630_fm_v5_coeff.bin", NULL, NULL}, +}; + +static struct fm_patch_tbl mt6630_patch_tbl_tx[5] = { + {FM_ROM_V1, "mt6630_fm_v1_patch_tx.bin", "mt6630_fm_v1_coeff_tx.bin", NULL, NULL}, + {FM_ROM_V2, "mt6630_fm_v2_patch_tx.bin", "mt6630_fm_v2_coeff_tx.bin", NULL, NULL}, + {FM_ROM_V3, "mt6630_fm_v3_patch_tx.bin", "mt6630_fm_v3_coeff_tx.bin", NULL, NULL}, + {FM_ROM_V4, "mt6630_fm_v4_patch_tx.bin", "mt6630_fm_v4_coeff_tx.bin", NULL, NULL}, + {FM_ROM_V5, "mt6630_fm_v5_patch_tx.bin", "mt6630_fm_v5_coeff_tx.bin", NULL, NULL}, +}; + +static struct fm_hw_info mt6630_hw_info = { + .chip_id = 0x00006630, + .eco_ver = 0x00000000, + .rom_ver = 0x00000000, + .patch_ver = 0x00000000, + .reserve = 0x00000000, +}; + +static struct fm_callback *fm_cb_op; +static unsigned char fm_packaging = 1; /*0:QFN,1:WLCSP */ +static unsigned int fm_sant_flag; /* 1,Short Antenna; 0, Long Antenna */ +static signed int mt6630_is_dese_chan(unsigned short freq); +#if 0 +static signed int mt6630_mcu_dese(unsigned short freq, void *arg); +#endif +static signed int mt6630_gps_dese(unsigned short freq, void *arg); + +static signed int mt6630_I2s_Setting(signed int onoff, signed int mode, signed int sample); +static unsigned short mt6630_chan_para_get(unsigned short freq); +static signed int mt6630_desense_check(unsigned short freq, signed int rssi); +static bool mt6630_TDD_chan_check(unsigned short freq); +static signed int mt6630_soft_mute_tune(unsigned short freq, signed int *rssi, signed int *valid); +static signed int mt6630_pwron(signed int data) +{ + if (mtk_wcn_wmt_func_on(WMTDRV_TYPE_FM) == MTK_WCN_BOOL_FALSE) { + WCN_DBG(FM_ERR | CHIP, "WMT turn on FM Fail!\n"); + return -FM_ELINK; + } + + WCN_DBG(FM_NTC | CHIP, "WMT turn on FM OK!\n"); + return 0; +} + +static signed int mt6630_pwroff(signed int data) +{ + if (mtk_wcn_wmt_func_off(WMTDRV_TYPE_FM) == MTK_WCN_BOOL_FALSE) { + WCN_DBG(FM_ERR | CHIP, "WMT turn off FM Fail!\n"); + return -FM_ELINK; + } + + WCN_DBG(FM_NTC | CHIP, "WMT turn off FM OK!\n"); + return 0; +} + +static unsigned short mt6630_get_chipid(void) +{ + return 0x6630; +} + +/* MT6630_SetAntennaType - set Antenna type + * @type - 1,Short Antenna; 0, Long Antenna + */ +static signed int mt6630_SetAntennaType(signed int type) +{ + unsigned short dataRead = 0; + + WCN_DBG(FM_NTC | CHIP, "set ana to %s\n", type ? "short" : "long"); + if (fm_packaging == 0) { + fm_sant_flag = type; + } else { + fm_reg_read(FM_MAIN_CG2_CTRL, &dataRead); + + if (type) + dataRead |= ANTENNA_TYPE; + else + dataRead &= (~ANTENNA_TYPE); + + fm_reg_write(FM_MAIN_CG2_CTRL, dataRead); + } + return 0; +} + +static signed int mt6630_GetAntennaType(void) +{ + unsigned short dataRead = 0; + + if (fm_packaging == 0) + return fm_sant_flag; + + fm_reg_read(FM_MAIN_CG2_CTRL, &dataRead); + WCN_DBG(FM_NTC | CHIP, "get ana type: %s\n", (dataRead & ANTENNA_TYPE) ? "short" : "long"); + + if (dataRead & ANTENNA_TYPE) + return FM_ANA_SHORT; /* short antenna */ + else + return FM_ANA_LONG; /* long antenna */ +} + +static signed int mt6630_Mute(bool mute) +{ + signed int ret = 0; + unsigned short dataRead = 0; + + WCN_DBG(FM_NTC | CHIP, "set %s\n", mute ? "mute" : "unmute"); + fm_reg_read(FM_MAIN_CTRL, &dataRead); + + if (mute == 1) + ret = fm_reg_write(FM_MAIN_CTRL, (dataRead & 0xFFDF) | 0x0020); + else + ret = fm_reg_write(FM_MAIN_CTRL, (dataRead & 0xFFDF)); + + return ret; +} + +signed int mt6630_rampdown_reg_op(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 4; + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + /* Clear DSP state */ + pkt_size += fm_bop_modify(FM_MAIN_CTRL, 0xFFF0, 0x0000, &buf[pkt_size], buf_size - pkt_size); + /* Set DSP ramp down state */ + pkt_size += fm_bop_modify(FM_MAIN_CTRL, 0xFFFF, RAMP_DOWN, &buf[pkt_size], buf_size - pkt_size); + /* @Wait for STC_DONE interrupt@ */ + pkt_size += fm_bop_rd_until(FM_MAIN_INTR, FM_INTR_STC_DONE, FM_INTR_STC_DONE, &buf[pkt_size], + buf_size - pkt_size); + /* Clear DSP ramp down state */ + pkt_size += fm_bop_modify(FM_MAIN_CTRL, (~RAMP_DOWN), 0x0000, &buf[pkt_size], buf_size - pkt_size); + /* Write 1 clear the STC_DONE interrupt status flag */ + pkt_size += fm_bop_modify(FM_MAIN_INTR, 0xFFFF, FM_INTR_STC_DONE, &buf[pkt_size], buf_size - pkt_size); + + return pkt_size - 4; +} + + +/* + * mt6630_rampdown - f/w will wait for STC_DONE interrupt + * @buf - target buf + * @buf_size - buffer size + * return package size + */ +static signed int mt6630_rampdown(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 0; + + pkt_size = mt6630_rampdown_reg_op(buf, buf_size); + return fm_op_seq_combine_cmd(buf, FM_RAMPDOWN_OPCODE, pkt_size); +} + +static signed int mt6630_RampDown(void) +{ + signed int ret = 0; + unsigned short pkt_size; + /* unsigned short tmp; */ + + WCN_DBG(FM_NTC | CHIP, "ramp down\n"); + + ret = fm_reg_write(FM_MAIN_EXTINTRMASK, 0x0000); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "ramp down write FM_MAIN_EXTINTRMASK failed\n"); + return ret; + } + + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = mt6630_rampdown(cmd_buf, TX_BUF_SIZE); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_RAMPDOWN, SW_RETRY_CNT, RAMPDOWN_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + + if (ret) { + WCN_DBG(FM_ERR | CHIP, "ramp down failed\n"); + return ret; + } + + ret = fm_reg_write(FM_MAIN_EXTINTRMASK, 0x0021); + if (ret) + WCN_DBG(FM_ERR | CHIP, "ramp down write FM_MAIN_EXTINTRMASK failed\n"); + + return ret; +} + +static signed int mt6630_pwrup_clock_on_reg_op(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 4; + unsigned short de_emphasis; + /* unsigned short osc_freq; */ + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + de_emphasis = fm_config.rx_cfg.deemphasis; + de_emphasis &= 0x0001; /* rang 0~1 */ + + /* B1.1 Enable digital OSC */ + pkt_size += fm_bop_write(0x60, 0x0003, &buf[pkt_size], buf_size - pkt_size); /* wr 60 3 */ + pkt_size += fm_bop_udelay(100, &buf[pkt_size], buf_size - pkt_size); /* delay 100us */ + /* B1.3 Release HW clock gating */ + pkt_size += fm_bop_write(0x60, 0x0007, &buf[pkt_size], buf_size - pkt_size); /* wr 60 7 */ + /* B1.4 Set FM long/short antenna:1: short_antenna 0: long antenna(default) */ + pkt_size += fm_bop_modify(0x61, 0xFFEF, 0x0000, &buf[pkt_size], buf_size - pkt_size); + /* B1.5 Set audio output mode (lineout/I2S) 0:lineout, 1:I2S */ + if (fm_config.aud_cfg.aud_path == FM_AUD_ANALOG) + pkt_size += fm_bop_modify(0x61, 0xFF7F, 0x0000, &buf[pkt_size], buf_size - pkt_size); + else + pkt_size += fm_bop_modify(0x61, 0xFF7F, 0x0080, &buf[pkt_size], buf_size - pkt_size); + + /* B1.6 Set deemphasis setting */ + pkt_size += fm_bop_modify(0x61, ~DE_EMPHASIS, (de_emphasis << 12), &buf[pkt_size], buf_size - pkt_size); + + /* pkt_size += fm_bop_modify(0x60, OSC_FREQ_MASK, (osc_freq << 4), &buf[pkt_size], buf_size - pkt_size); */ + + return pkt_size - 4; +} + +/* + * mt6630_pwrup_clock_on - Wholechip FM Power Up: step 1, FM Digital Clock enable + * @buf - target buf + * @buf_size - buffer size + * return package size + */ +static signed int mt6630_pwrup_clock_on(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 0; + + pkt_size = mt6630_pwrup_clock_on_reg_op(buf, buf_size); + return fm_op_seq_combine_cmd(buf, FM_ENABLE_OPCODE, pkt_size); +} + +static signed int mt6630_pwrup_digital_init_reg_op(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 4; + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + /* update FM ADPLL fast tracking mode gain */ + pkt_size += fm_bop_modify(0xF, 0xF800, 0x0455, &buf[pkt_size], buf_size - pkt_size); + /* F1.4 Set appropriate interrupt mask behavior as desired(RX) */ + /* pkt_size += fm_bop_write(0x6A, 0x0021, &buf[pkt_size], buf_size - pkt_size);//wr 6A 0021 */ + pkt_size += fm_bop_write(0x6B, 0x0021, &buf[pkt_size], buf_size - pkt_size); /* wr 6B 0021 */ + /* F1.9 Enable HW auto control */ + pkt_size += fm_bop_write(0x60, 0x000F, &buf[pkt_size], buf_size - pkt_size); /* wr 60 f */ + /* F1.10 Release ASIP reset */ + pkt_size += fm_bop_modify(0x61, 0xFFFD, 0x0002, &buf[pkt_size], buf_size - pkt_size); /* wr 61 D1=1 */ + /* F1.11 Enable ASIP power */ + pkt_size += fm_bop_modify(0x61, 0xFFFE, 0x0000, &buf[pkt_size], buf_size - pkt_size); /* wr 61 D0=0 */ + pkt_size += fm_bop_udelay(100000, &buf[pkt_size], buf_size - pkt_size); /* delay 100ms */ + /* F1.13 Check HW intitial complete */ + pkt_size += fm_bop_rd_until(0x64, 0x001F, 0x0002, &buf[pkt_size], buf_size - pkt_size); /* Poll 64[0~4] = 2 */ + + return pkt_size - 4; +} + +/* + * mt6630_pwrup_digital_init - Wholechip FM Power Up: step 4, FM Digital Init: fm_rgf_maincon + * @buf - target buf + * @buf_size - buffer size + * return package size + */ +static signed int mt6630_pwrup_digital_init(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 0; + + pkt_size = mt6630_pwrup_digital_init_reg_op(buf, buf_size); + return fm_op_seq_combine_cmd(buf, FM_ENABLE_OPCODE, pkt_size); +} + + +signed int mt6630_pwrdown_reg_op(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 4; + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + /* Disable HW clock control */ + pkt_size += fm_bop_write(0x60, 0x0107, &buf[pkt_size], buf_size - pkt_size); /* wr 60 107 */ + /* Reset ASIP */ + pkt_size += fm_bop_write(0x61, 0x0001, &buf[pkt_size], buf_size - pkt_size); /* wr 61 0001 */ + /* digital core + digital rgf reset */ + pkt_size += fm_bop_modify(0x6E, 0xFFF8, 0x0000, &buf[pkt_size], buf_size - pkt_size); /* wr 6E[0~2] 0 */ + pkt_size += fm_bop_modify(0x6E, 0xFFF8, 0x0000, &buf[pkt_size], buf_size - pkt_size); /* wr 6E[0~2] 0 */ + pkt_size += fm_bop_modify(0x6E, 0xFFF8, 0x0000, &buf[pkt_size], buf_size - pkt_size); /* wr 6E[0~2] 0 */ + pkt_size += fm_bop_modify(0x6E, 0xFFF8, 0x0000, &buf[pkt_size], buf_size - pkt_size); /* wr 6E[0~2] 0 */ + /* Disable all clock */ + pkt_size += fm_bop_write(0x60, 0x0000, &buf[pkt_size], buf_size - pkt_size); /* wr 60 0000 */ + /* Reset rgfrf */ + pkt_size += fm_bop_write(0x60, 0x4000, &buf[pkt_size], buf_size - pkt_size); /* wr 60 4000 */ + pkt_size += fm_bop_write(0x60, 0x0000, &buf[pkt_size], buf_size - pkt_size); /* wr 60 0000 */ + + return pkt_size - 4; +} + +/* + * mt6630_pwrdown - Wholechip FM Power down: Digital Modem Power Down + * @buf - target buf + * @buf_size - buffer size + * return package size + */ +static signed int mt6630_pwrdown(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 0; + + pkt_size = mt6630_pwrdown_reg_op(buf, buf_size); + return fm_op_seq_combine_cmd(buf, FM_ENABLE_OPCODE, pkt_size); +} + +signed int mt6630_tune_reg_op(unsigned char *buf, signed int buf_size, unsigned short freq, + unsigned short chan_para) +{ + signed int pkt_size = 4; + + WCN_DBG(FM_ALT | CHIP, "%s enter mt6630_tune function\n", __func__); + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + if (fm_get_channel_space(freq) == 0) + freq *= 10; + + freq = (freq - 6400) * 2 / 10; + + /* Set desired channel & channel parameter */ +#ifdef FM_TUNE_USE_POLL + pkt_size += fm_bop_write(0x6A, 0x0000, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x6B, 0x0000, &buf[pkt_size], buf_size - pkt_size); +#endif + pkt_size += fm_bop_modify(FM_CHANNEL_SET, 0xFC00, freq, &buf[pkt_size], buf_size - pkt_size); + /* channel para setting, D15~D12, D15: ATJ, D13: HL, D12: FA */ + pkt_size += fm_bop_modify(FM_CHANNEL_SET, 0x0FFF, (chan_para << 12), &buf[pkt_size], buf_size - pkt_size); + /* Enable hardware controlled tuning sequence */ + pkt_size += fm_bop_modify(FM_MAIN_CTRL, 0xFFF8, TUNE, &buf[pkt_size], buf_size - pkt_size); + /* Wait for STC_DONE interrupt */ +#ifdef FM_TUNE_USE_POLL + pkt_size += fm_bop_rd_until(FM_MAIN_INTR, FM_INTR_STC_DONE, FM_INTR_STC_DONE, &buf[pkt_size], + buf_size - pkt_size); + /* Write 1 clear the STC_DONE interrupt status flag */ + pkt_size += fm_bop_modify(FM_MAIN_INTR, 0xFFFF, FM_INTR_STC_DONE, &buf[pkt_size], buf_size - pkt_size); +#endif + + return pkt_size - 4; +} + +/* + * mt6630_tune - execute tune action, + * @buf - target buf + * @buf_size - buffer size + * @freq - 760 ~ 1080, 100KHz unit + * return package size + */ +static signed int mt6630_tune(unsigned char *buf, signed int buf_size, unsigned short freq, + unsigned short chan_para) +{ + signed int pkt_size = 0; + + pkt_size = mt6630_tune_reg_op(buf, buf_size, freq, chan_para); + return fm_op_seq_combine_cmd(buf, FM_TUNE_OPCODE, pkt_size); +} + +static signed int mt6630_get_rom_version(void) +{ + unsigned short tmp = 0; + signed int ret = 0; + + /* DSP rom code version request enable --- set 0x61 b15=1 */ + fm_set_bits(0x61, 0x8000, 0x7FFF); + + /* Release ASIP reset --- set 0x61 b1=1 */ + fm_set_bits(0x61, 0x0002, 0xFFFD); + + /* Enable ASIP power --- set 0x61 b0=0 */ + fm_set_bits(0x61, 0x0000, 0xFFFE); + + /* Wait DSP code version ready --- wait 1ms */ + do { + fm_delayus(1000); + ret = fm_reg_read(0x84, &tmp); + /* ret=-4 means signal got when control FM. usually get sig 9 to kill FM process. */ + /* now cancel FM power up sequence is recommended. */ + if (ret) + return ret; + + WCN_DBG(FM_DBG | CHIP, "0x84=%x\n", tmp); + } while (tmp != 0x0001); + + /* Get FM DSP code version --- rd 0x83[15:8] */ + fm_reg_read(0x83, &tmp); + WCN_DBG(FM_NTC | CHIP, "DSP ver=0x%x\n", tmp); + tmp = (tmp >> 8); + + /* DSP rom code version request disable --- set 0x61 b15=0 */ + fm_set_bits(0x61, 0x0000, 0x7FFF); + + /* Reset ASIP --- set 0x61[1:0] = 1 */ + fm_set_bits(0x61, 0x0001, 0xFFFC); + + return (signed int) tmp; +} + +static signed int mt6630_pwrup_top_setting(void) +{ + signed int ret = 0, value = 0; + /* A0.1 Turn on FM buffer */ + ret = fm_host_reg_read(0x8102123c, &value); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x8102123c rd failed\n"); + return ret; + } + ret = fm_host_reg_write(0x8102123c, value & 0xFFFFFFBF); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x8102123c wr failed\n"); + return ret; + } + /* A0.2 Set xtal no off when FM on */ + ret = fm_host_reg_read(0x81021134, &value); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x81021134 rd failed\n"); + return ret; + } + ret = fm_host_reg_write(0x81021134, value | 0x80); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x81021134 wr failed\n"); + return ret; + } + /* A0.3 Set top off always on when FM on */ + ret = fm_host_reg_read(0x81020010, &value); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x81020010 rd failed\n"); + return ret; + } + ret = fm_host_reg_write(0x81020010, value & 0xFFFDFFFF); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x81020010 wr failed\n"); + return ret; + } + /* A0.4 Always enable PALDO when FM on */ + ret = fm_host_reg_read(0x81021430, &value); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x81021430 rd failed\n"); + return ret; + } + ret = fm_host_reg_write(0x81021430, value | 0x80000000); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x81021430 wr failed\n"); + return ret; + } + /* A0.5 */ + fm_delayus(240); + + /* A0.6 MTCMOS Control */ + ret = fm_host_reg_read(0x81020008, &value); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x81020008 rd failed\n"); + return ret; + } + ret = fm_host_reg_write(0x81020008, value | 0x00000030); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x81020008 wr failed\n"); + return ret; + } + /* A0.7 */ + fm_delayus(20); + + /* A0.8 release power on reset */ + ret = fm_host_reg_read(0x81020008, &value); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x81020008 rd failed\n"); + return ret; + } + ret = fm_host_reg_write(0x81020008, value | 0x00000001); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x81020008 wr failed\n"); + return ret; + } + /* A0.9 enable fspi_mas_bclk_ck */ + ret = fm_host_reg_read(0x80000108, &value); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x80000108 rd failed\n"); + return ret; + } + ret = fm_host_reg_write(0x80000108, value | 0x00000100); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x80000108 wr failed\n"); + return ret; + } + return ret; +} + +static signed int mt6630_pwrdown_top_setting(void) +{ + signed int ret = 0, value = 0; + /* B0.1 disable fspi_mas_bclk_ck */ + ret = fm_host_reg_read(0x80000104, &value); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x80000104 rd failed\n"); + return ret; + } + ret = fm_host_reg_write(0x80000104, value | 0x00000100); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x80000104 wr failed\n"); + return ret; + } + /* B0.2 set power off reset */ + ret = fm_host_reg_read(0x81020008, &value); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x81020008 rd failed\n"); + return ret; + } + ret = fm_host_reg_write(0x81020008, value & 0xFFFFFFFE); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x81020008 wr failed\n"); + return ret; + } + /* B0.3 */ + fm_delayus(20); + + /* B0.4 disable MTCMOS & set Iso_en */ + ret = fm_host_reg_read(0x81020008, &value); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x81020008 rd failed\n"); + return ret; + } + ret = fm_host_reg_write(0x81020008, value & 0xFFFFFFEF); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x81020008 wr failed\n"); + return ret; + } + /* B0.5 Turn off FM buffer */ + ret = fm_host_reg_read(0x8102123c, &value); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x8102123c rd failed\n"); + return ret; + } + ret = fm_host_reg_write(0x8102123c, value | 0x40); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x8102123c wr failed\n"); + return ret; + } + /* B0.6 Clear xtal no off when FM off */ + ret = fm_host_reg_read(0x81021134, &value); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x81021134 rd failed\n"); + return ret; + } + ret = fm_host_reg_write(0x81021134, value & 0xFFFFFF7F); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x81021134 wr failed\n"); + return ret; + } + /* B0.7 Clear top off always on when FM off */ + ret = fm_host_reg_read(0x81020010, &value); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x81020010 rd failed\n"); + return ret; + } + ret = fm_host_reg_write(0x81020010, value | 0x20000); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x81020010 wr failed\n"); + return ret; + } + /* B0.9 Disable PALDO when FM off */ + ret = fm_host_reg_read(0x81021430, &value); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x81021430 rd failed\n"); + return ret; + } + ret = fm_host_reg_write(0x81021430, value & 0x7FFFFFFF); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x81021430 wr failed\n"); + return ret; + } + + return ret; +} + +static signed int mt6630_pwrup_DSP_download(struct fm_patch_tbl *patch_tbl) +{ +#define PATCH_BUF_SIZE (4096*6) + signed int ret = 0; + signed int patch_len = 0; + unsigned char *dsp_buf = NULL; + unsigned short tmp_reg = 0; + + mt6630_hw_info.eco_ver = (signed int) mtk_wcn_wmt_ic_info_get(1); + WCN_DBG(FM_NTC | CHIP, "ECO version:0x%08x\n", mt6630_hw_info.eco_ver); + + /* FM ROM code version request */ + ret = mt6630_get_rom_version(); + if (ret >= 0) { + mt6630_hw_info.rom_ver = ret; + WCN_DBG(FM_NTC | CHIP, "ROM version: v%d\n", mt6630_hw_info.rom_ver); + } else { + WCN_DBG(FM_ERR | CHIP, "get ROM version failed\n"); + /* ret=-4 means signal got when control FM. usually get sig 9 to kill FM process. */ + /* now cancel FM power up sequence is recommended. */ + return ret; + } + + /* Wholechip FM Power Up: step 3, download patch */ + dsp_buf = fm_vmalloc(PATCH_BUF_SIZE); + if (!dsp_buf) { + WCN_DBG(FM_ERR | CHIP, "-ENOMEM\n"); + return -ENOMEM; + } + + patch_len = fm_get_patch_path(mt6630_hw_info.rom_ver, dsp_buf, PATCH_BUF_SIZE, patch_tbl); + if (patch_len <= 0) { + WCN_DBG(FM_ALT | CHIP, " fm_get_patch_path failed\n"); + ret = patch_len; + goto out; + } + + ret = fm_download_patch((const unsigned char *)dsp_buf, patch_len, IMG_PATCH); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " DL DSPpatch failed\n"); + goto out; + } + + patch_len = fm_get_coeff_path(mt6630_hw_info.rom_ver, dsp_buf, PATCH_BUF_SIZE, patch_tbl); + if (patch_len <= 0) { + WCN_DBG(FM_ALT | CHIP, " fm_get_coeff_path failed\n"); + ret = patch_len; + goto out; + } + + mt6630_hw_info.rom_ver += 1; + + tmp_reg = dsp_buf[38] | (dsp_buf[39] << 8); /* to be confirmed */ + mt6630_hw_info.patch_ver = (signed int) tmp_reg; + WCN_DBG(FM_NTC | CHIP, "Patch version: 0x%08x\n", mt6630_hw_info.patch_ver); + + if (ret == 1) { + dsp_buf[4] = 0x00; /* if we found rom version undefined, we should disable patch */ + dsp_buf[5] = 0x00; + } + + ret = fm_download_patch((const unsigned char *)dsp_buf, patch_len, IMG_COEFFICIENT); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " DL DSPcoeff failed\n"); + goto out; + } + fm_reg_write(0x90, 0x0040); + fm_reg_write(0x90, 0x0000); +out: + if (dsp_buf) { + fm_vfree(dsp_buf); + dsp_buf = NULL; + } + return ret; +} + +static signed int mt6630_PowerUp(unsigned short *chip_id, unsigned short *device_id) +{ + signed int ret = 0, reg = 0; + unsigned short pkt_size; + unsigned short tmp_reg = 0; + + if (chip_id == NULL) { + WCN_DBG(CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (device_id == NULL) { + WCN_DBG(CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + WCN_DBG(FM_DBG | CHIP, "pwr on seq......\n"); + + ret = fm_host_reg_read(0x80021010, ®); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "packaging rd failed\n"); + } else { + fm_packaging = (reg & 0x00008000) >> 15; + WCN_DBG(FM_NTC | CHIP, "fm_packaging: %d\n", fm_packaging); + } + ret = mt6630_pwrup_top_setting(); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "mt6630_pwrup_top_setting failed\n"); + return ret; + } + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = mt6630_pwrup_clock_on(cmd_buf, TX_BUF_SIZE); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + + if (ret) { + WCN_DBG(FM_ERR | CHIP, "mt6630_pwrup_clock_on failed\n"); + return ret; + } + /* read HW version */ + fm_reg_read(0x62, &tmp_reg); + *chip_id = tmp_reg; + *device_id = tmp_reg; + mt6630_hw_info.chip_id = (signed int) tmp_reg; + WCN_DBG(FM_NTC | CHIP, "chip_id:0x%04x\n", tmp_reg); + + if (mt6630_hw_info.chip_id != 0x6630) { + WCN_DBG(FM_NTC | CHIP, "fm sys error!\n"); + return -FM_EPARA; + } + ret = mt6630_pwrup_DSP_download(mt6630_patch_tbl); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "mt6630_pwrup_DSP_download failed\n"); + return ret; + } + + if ((fm_config.aud_cfg.aud_path == FM_AUD_MRGIF) + || (fm_config.aud_cfg.aud_path == FM_AUD_I2S)) { + mt6630_I2s_Setting(FM_I2S_ON, fm_config.aud_cfg.i2s_info.mode, + fm_config.aud_cfg.i2s_info.rate); + /* mt_combo_audio_ctrl(COMBO_AUDIO_STATE_2); */ + mtk_wcn_cmb_stub_audio_ctrl((enum CMB_STUB_AIF_X) CMB_STUB_AIF_2); + } + /* Wholechip FM Power Up: step 4, FM Digital Init: fm_rgf_maincon */ + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = mt6630_pwrup_digital_init(cmd_buf, TX_BUF_SIZE); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "mt6630_pwrup_digital_init failed\n"); + return ret; + } + + WCN_DBG(FM_NTC | CHIP, "pwr on seq ok\n"); + + return ret; +} + +static signed int mt6630_PowerDown(void) +{ + signed int ret = 0; + unsigned short pkt_size; + unsigned short dataRead = 0; + + WCN_DBG(FM_DBG | CHIP, "pwr down seq\n"); + /*SW work around for MCUFA issue. + *if interrupt happen before doing rampdown, DSP can't switch MCUFA back well. + * In case read interrupt, and clean if interrupt found before rampdown. + */ + fm_reg_read(FM_MAIN_INTR, &dataRead); + + if (dataRead & 0x1) + fm_reg_write(FM_MAIN_INTR, dataRead); /* clear status flag */ + + /* mt6630_RampDown(); */ + + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = mt6630_pwrdown(cmd_buf, TX_BUF_SIZE); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + + if (ret) { + WCN_DBG(FM_ERR | CHIP, "mt6630_pwrdown failed\n"); + return ret; + } + + ret = mt6630_pwrdown_top_setting(); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "mt6630_pwrdown_top_setting failed\n"); + return ret; + } + + return ret; +} + +/* just for dgb */ +static bool mt6630_SetFreq(unsigned short freq) +{ + signed int ret = 0; + unsigned short pkt_size; + unsigned short chan_para = 0; + + fm_cb_op->cur_freq_set(freq); + +#if 0 + /* MCU clock adjust if need */ + ret = mt6630_mcu_dese(freq, NULL); + if (ret < 0) + WCN_DBG(FM_ERR | MAIN, "mt6630_mcu_dese FAIL:%d\n", ret); + + WCN_DBG(FM_INF | MAIN, "MCU %d\n", ret); +#endif + + /* GPS clock adjust if need */ + ret = mt6630_gps_dese(freq, NULL); + if (ret < 0) + WCN_DBG(FM_ERR | MAIN, "mt6630_gps_dese FAIL:%d\n", ret); + + WCN_DBG(FM_INF | MAIN, "GPS %d\n", ret); + + ret = fm_reg_write(0x60, 0x0007); + if (ret) + WCN_DBG(FM_ALT | MAIN, "set freq write 0x60 fail\n"); + + if (mt6630_TDD_chan_check(freq)) { + ret = fm_set_bits(0x30, 0x0004, 0xFFF9); /* use TDD solution */ + if (ret) + WCN_DBG(FM_ALT | MAIN, "set freq write 0x30 fail\n"); + } else { + ret = fm_set_bits(0x30, 0x0000, 0xFFF9); /* default use FDD solution */ + if (ret) + WCN_DBG(FM_ALT | MAIN, "set freq write 0x30 fail\n"); + } + ret = fm_reg_write(0x60, 0x000F); + if (ret) + WCN_DBG(FM_ALT | MAIN, "set freq write 0x60 fail\n"); + + chan_para = mt6630_chan_para_get(freq); + WCN_DBG(FM_DBG | CHIP, "%d chan para = %d\n", (signed int) freq, (signed int) chan_para); + + if (FM_LOCK(cmd_buf_lock)) + return false; + pkt_size = mt6630_tune(cmd_buf, TX_BUF_SIZE, freq, chan_para); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_TUNE | FLAG_TUNE_DONE, SW_RETRY_CNT, TUNE_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + + if (ret) { + WCN_DBG(FM_ERR | CHIP, "mt6630_tune failed\n"); + return false; + } + + WCN_DBG(FM_DBG | CHIP, "set freq to %d ok\n", freq); + return true; +} + +#define FM_CQI_LOG_PATH "/mnt/sdcard/fmcqilog" + +static signed int mt6630_full_cqi_get(signed int min_freq, signed int max_freq, signed int space, signed int cnt) +{ + signed int ret = 0; + unsigned short pkt_size; + unsigned short freq, orig_freq; + signed int i, j, k; + signed int space_val, max, min, num; + struct mt6630_full_cqi *p_cqi; + unsigned char *cqi_log_title = "Freq, RSSI, PAMD, PR, FPAMD, MR, ATDC, PRX, ATDEV, SMGain, DltaRSSI\n"; + unsigned char cqi_log_buf[100] = { 0 }; + signed int pos; + unsigned char cqi_log_path[100] = { 0 }; + + WCN_DBG(FM_DBG | CHIP, "6630 cqi log start\n"); + /* for soft-mute tune, and get cqi */ + freq = fm_cb_op->cur_freq_get(); + if (fm_get_channel_space(freq) == 0) + freq *= 10; + + /* get cqi */ + orig_freq = freq; + if (fm_get_channel_space(min_freq) == 0) + min = min_freq * 10; + else + min = min_freq; + + if (fm_get_channel_space(max_freq) == 0) + max = max_freq * 10; + else + max = max_freq; + + if (space == 0x0001) + space_val = 5; /* 50Khz */ + else if (space == 0x0002) + space_val = 10; /* 100Khz */ + else if (space == 0x0004) + space_val = 20; /* 200Khz */ + else + space_val = 10; + + num = (max - min) / space_val + 1; /* Eg, (8760 - 8750) / 10 + 1 = 2 */ + for (k = 0; (orig_freq == 10000) && (g_dbg_level == 0xffffffff) && (k < cnt); k++) { + WCN_DBG(FM_NTC | CHIP, "cqi file:%d\n", k + 1); + freq = min; + pos = 0; + fm_memcpy(cqi_log_path, FM_CQI_LOG_PATH, strlen(FM_CQI_LOG_PATH)); + if (sprintf(&cqi_log_path[strlen(FM_CQI_LOG_PATH)], "%d.txt", k + 1) < 0) + WCN_DBG(FM_NTC | CHIP, "sprintf fail\n"); + fm_file_write(cqi_log_path, cqi_log_title, strlen(cqi_log_title), &pos); + for (j = 0; j < num; j++) { + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = fm_full_cqi_req(cmd_buf, TX_BUF_SIZE, &freq, 1, 1); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_SM_TUNE, SW_RETRY_CNT, + SM_TUNE_TIMEOUT, fm_get_read_result); + FM_UNLOCK(cmd_buf_lock); + + if (!ret && fm_res) { + WCN_DBG(FM_NTC | CHIP, "smt cqi size %d\n", fm_res->cqi[0]); + p_cqi = (struct mt6630_full_cqi *)&fm_res->cqi[2]; + for (i = 0; i < fm_res->cqi[1]; i++) { + /* just for debug */ + WCN_DBG(FM_NTC | CHIP, + "freq %d, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x\n", + p_cqi[i].ch, p_cqi[i].rssi, p_cqi[i].pamd, + p_cqi[i].pr, p_cqi[i].fpamd, p_cqi[i].mr, + p_cqi[i].atdc, p_cqi[i].prx, p_cqi[i].atdev, + p_cqi[i].smg, p_cqi[i].drssi); + /* format to buffer */ + if (sprintf(cqi_log_buf, + "%04d, %04x, %04x, %04x, %04x, %04x, %04x, %04x, %04x, %04x, %04x,\n", + p_cqi[i].ch, p_cqi[i].rssi, p_cqi[i].pamd, + p_cqi[i].pr, p_cqi[i].fpamd, p_cqi[i].mr, + p_cqi[i].atdc, p_cqi[i].prx, p_cqi[i].atdev, + p_cqi[i].smg, p_cqi[i].drssi) < 0) + WCN_DBG(FM_NTC | CHIP, "sprintf fail\n"); + /* write back to log file */ + fm_file_write(cqi_log_path, cqi_log_buf, strlen(cqi_log_buf), &pos); + } + } else { + WCN_DBG(FM_ERR | CHIP, "smt get CQI failed\n"); + ret = -1; + } + freq += space_val; + } + fm_cb_op->cur_freq_set(0); /* avoid run too much times */ + } + WCN_DBG(FM_DBG | CHIP, "6630 cqi log done\n"); + + return ret; +} + +/* + * mt6630_GetCurRSSI - get current freq's RSSI value + * RS=RSSI + * If RS>511, then RSSI(dBm)= (RS-1024)/16*6 + * else RSSI(dBm)= RS/16*6 + */ +static signed int mt6630_GetCurRSSI(signed int *pRSSI) +{ + unsigned short tmp_reg = 0; + + /* TODO: check reg */ + fm_reg_read(FM_RSSI_IND, &tmp_reg); + tmp_reg = tmp_reg & 0x03ff; + + if (pRSSI) { + *pRSSI = (tmp_reg > 511) ? (((tmp_reg - 1024) * 6) >> 4) : ((tmp_reg * 6) >> 4); + WCN_DBG(FM_DBG | CHIP, "rssi:%d, dBm:%d\n", tmp_reg, *pRSSI); + } else { + WCN_DBG(FM_ERR | CHIP, "get rssi para error\n"); + return -FM_EPARA; + } + + return 0; +} + +static unsigned short mt6630_vol_tbl[16] = { + 0x0000, 0x0519, 0x066A, 0x0814, + 0x0A2B, 0x0CCD, 0x101D, 0x1449, + 0x198A, 0x2027, 0x287A, 0x32F5, + 0x4027, 0x50C3, 0x65AD, 0x7FFF +}; + +static signed int mt6630_SetVol(unsigned char vol) +{ + signed int ret = 0; + + /* TODO: check reg */ + vol = (vol > 15) ? 15 : vol; + ret = fm_reg_write(0x7D, mt6630_vol_tbl[vol]); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "Set vol=%d Failed\n", vol); + return ret; + } + + WCN_DBG(FM_DBG | CHIP, "Set vol=%d OK\n", vol); + + if (vol == 10) { + fm_print_cmd_fifo(); /* just for debug */ + fm_print_evt_fifo(); + } + return 0; +} + +static signed int mt6630_GetVol(unsigned char *pVol) +{ + int ret = 0; + unsigned short tmp = 0; + signed int i; + + if (pVol == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + /* TODO: check reg */ + ret = fm_reg_read(0x7D, &tmp); + if (ret) { + *pVol = 0; + WCN_DBG(FM_ERR | CHIP, "Get vol Failed\n"); + return ret; + } + + for (i = 0; i < 16; i++) { + if (mt6630_vol_tbl[i] == tmp) { + *pVol = i; + break; + } + } + + WCN_DBG(FM_DBG | CHIP, "Get vol=%d OK\n", *pVol); + return 0; +} + +static signed int mt6630_dump_reg(void) +{ + signed int i; + unsigned short TmpReg = 0; + + for (i = 0; i < 0xff; i++) { + fm_reg_read(i, &TmpReg); + WCN_DBG(FM_NTC | CHIP, "0x%02x=0x%04x\n", i, TmpReg); + } + return 0; +} + +static bool mt6630_GetMonoStereo(unsigned short *pMonoStereo) +{ +#define FM_BF_STEREO 0x1000 + unsigned short TmpReg = 0; + + /* TODO: check reg */ + if (pMonoStereo) { + fm_reg_read(FM_RSSI_IND, &TmpReg); + *pMonoStereo = (TmpReg & FM_BF_STEREO) >> 12; + } else { + WCN_DBG(FM_ERR | CHIP, "MonoStero: para err\n"); + return false; + } + + WCN_DBG(FM_DBG | CHIP, "MonoStero:0x%04x\n", *pMonoStereo); + return true; +} + +static signed int mt6630_SetMonoStereo(signed int MonoStereo) +{ + signed int ret = 0; +#define FM_FORCE_MS 0x0008 + + WCN_DBG(FM_DBG | CHIP, "set to %s\n", MonoStereo ? "mono" : "auto"); + /* TODO: check reg */ + + fm_reg_write(0x60, 0x3007); + + if (MonoStereo) + ret = fm_set_bits(0x75, FM_FORCE_MS, ~FM_FORCE_MS); + else + ret = fm_set_bits(0x75, 0x0000, ~FM_FORCE_MS); + + return ret; +} + +static signed int mt6630_GetCapArray(signed int *ca) +{ + unsigned short dataRead = 0; + unsigned short tmp = 0; + + /* TODO: check reg */ + if (ca == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + fm_reg_read(0x60, &tmp); + fm_reg_write(0x60, tmp & 0xFFF7); /* 0x60 D3=0 */ + + fm_reg_read(0x26, &dataRead); + *ca = dataRead; + + fm_reg_write(0x60, tmp); /* 0x60 D3=1 */ + return 0; +} + +/* + * mt6630_GetCurPamd - get current freq's PAMD value + * PA=PAMD + * If PA>511 then PAMD(dB)= (PA-1024)/16*6, + * else PAMD(dB)=PA/16*6 + */ +static bool mt6630_GetCurPamd(unsigned short *pPamdLevl) +{ + unsigned short tmp_reg = 0; + unsigned short dBvalue, valid_cnt = 0; + int i, total = 0; + + for (i = 0; i < 8; i++) { + /* TODO: check reg */ + if (fm_reg_read(FM_ADDR_PAMD, &tmp_reg)) { + *pPamdLevl = 0; + return false; + } + + tmp_reg &= 0x03FF; + dBvalue = (tmp_reg > 256) ? ((512 - tmp_reg) * 6 / 16) : 0; + if (dBvalue != 0) { + total += dBvalue; + valid_cnt++; + WCN_DBG(FM_DBG | CHIP, "[%d]PAMD=%d\n", i, dBvalue); + } + fm_delayms(3); + } + if (valid_cnt != 0) + *pPamdLevl = total / valid_cnt; + else + *pPamdLevl = 0; + + WCN_DBG(FM_NTC | CHIP, "PAMD=%d\n", *pPamdLevl); + return true; +} + +static signed int MT6630_FMOverBT(bool enable) +{ + signed int ret = 0; + + WCN_DBG(FM_NTC | CHIP, "+%s():\n", __func__); + + if (enable == true) { + /* change I2S to slave mode and 48K sample rate */ + if (mt6630_I2s_Setting(FM_I2S_ON, FM_I2S_SLAVE, FM_I2S_48K)) + goto out; + WCN_DBG(FM_NTC | CHIP, "set FM via BT controller\n"); + } else if (enable == false) { + /* change I2S to master mode and 44.1K sample rate */ + if (mt6630_I2s_Setting(FM_I2S_ON, FM_I2S_MASTER, FM_I2S_44K)) + goto out; + WCN_DBG(FM_NTC | CHIP, "set FM via Host\n"); + } else { + WCN_DBG(FM_ERR | CHIP, "%s()\n", __func__); + ret = -FM_EPARA; + goto out; + } +out: + WCN_DBG(FM_NTC | CHIP, "-%s():[ret=%d]\n", __func__, ret); + return ret; +} + +/* + * mt6630_I2s_Setting - set the I2S state on MT6630 + * @onoff - I2S on/off + * @mode - I2S mode: Master or Slave + * + * Return:0, if success; error code, if failed + */ +static signed int mt6630_I2s_Setting(signed int onoff, signed int mode, signed int sample) +{ + unsigned short tmp_state = 0; + unsigned short tmp_mode = 0; + unsigned short tmp_sample = 0; + signed int ret = 0; + + if (onoff == FM_I2S_ON) { + tmp_state = 0x0003; /* I2S enable and standard I2S mode, 0x9B D0,D1=1 */ + fm_config.aud_cfg.i2s_info.status = FM_I2S_ON; + } else if (onoff == FM_I2S_OFF) { + tmp_state = 0x0000; /* I2S off, 0x9B D0,D1=0 */ + fm_config.aud_cfg.i2s_info.status = FM_I2S_OFF; + } else { + WCN_DBG(FM_ERR | CHIP, "%s():[onoff=%d]\n", __func__, onoff); + ret = -FM_EPARA; + goto out; + } + + if (mode == FM_I2S_MASTER) { + tmp_mode = 0x0000; /* 6630 as I2S master, set 0x9B D3=0 */ + fm_config.aud_cfg.i2s_info.mode = FM_I2S_MASTER; + } else if (mode == FM_I2S_SLAVE) { + tmp_mode = 0x0008; /* 6630 as I2S slave, set 0x9B D3=1 */ + fm_config.aud_cfg.i2s_info.mode = FM_I2S_SLAVE; + } else { + WCN_DBG(FM_ERR | CHIP, "%s():[mode=%d]\n", __func__, mode); + ret = -FM_EPARA; + goto out; + } + + if (sample == FM_I2S_32K) { + tmp_sample = 0x0000; /* 6630 I2S 32KHz sample rate, 0x5F D11~12 */ + fm_config.aud_cfg.i2s_info.rate = FM_I2S_32K; + } else if (sample == FM_I2S_44K) { + tmp_sample = 0x0800; /* 6630 I2S 44.1KHz sample rate */ + fm_config.aud_cfg.i2s_info.rate = FM_I2S_44K; + } else if (sample == FM_I2S_48K) { + tmp_sample = 0x1000; /* 6630 I2S 48KHz sample rate */ + fm_config.aud_cfg.i2s_info.rate = FM_I2S_48K; + } else { + WCN_DBG(FM_ERR | CHIP, "%s():[sample=%d]\n", __func__, sample); + ret = -FM_EPARA; + goto out; + } + + ret = fm_reg_write(0x60, 0x7); + if (ret) + goto out; + + ret = fm_set_bits(0x5F, tmp_sample, 0xE7FF); + if (ret) + goto out; + + ret = fm_set_bits(0x9B, tmp_mode, 0xFFF7); + if (ret) + goto out; + + ret = fm_set_bits(0x9B, tmp_state, 0xFFFC); + if (ret) + goto out; + + /* F0.4 enable ft */ + ret = fm_set_bits(0x56, 0x1, 0xFFFE); + if (ret) + goto out; + + ret = fm_reg_write(0x60, 0xf); + if (ret) + goto out; + + WCN_DBG(FM_NTC | CHIP, "[onoff=%s][mode=%s][sample=%d](0)33KHz,(1)44.1KHz,(2)48KHz\n", + (onoff == FM_I2S_ON) ? "On" : "Off", (mode == FM_I2S_MASTER) ? "Master" : "Slave", sample); +out: + return ret; +} + +static signed int mt6630fm_get_audio_info(struct fm_audio_info_t *data) +{ + memcpy(data, &fm_config.aud_cfg, sizeof(struct fm_audio_info_t)); + return 0; +} + +static signed int mt6630_i2s_info_get(signed int *ponoff, signed int *pmode, signed int *psample) +{ + *ponoff = fm_config.aud_cfg.i2s_info.status; + *pmode = fm_config.aud_cfg.i2s_info.mode; + *psample = fm_config.aud_cfg.i2s_info.rate; + + return 0; +} + +static signed int mt6630_hw_info_get(struct fm_hw_info *req) +{ + if (req == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + req->chip_id = mt6630_hw_info.chip_id; + req->eco_ver = mt6630_hw_info.eco_ver; + req->patch_ver = mt6630_hw_info.patch_ver; + req->rom_ver = mt6630_hw_info.rom_ver; + + return 0; +} + +static signed int mt6630_pre_search(void) +{ + mt6630_RampDown(); + return 0; +} + +static signed int mt6630_restore_search(void) +{ + mt6630_RampDown(); + return 0; +} + +/* +*freq: 8750~10800 +*valid: true-valid channel,false-invalid channel +*return: true- smt success, false-smt fail +*/ +static signed int mt6630_soft_mute_tune(unsigned short freq, signed int *rssi, signed int *valid) +{ + signed int ret = 0; + unsigned short pkt_size; + /* unsigned short freq;//, orig_freq; */ + struct mt6630_full_cqi *p_cqi; + signed int RSSI = 0, PAMD = 0, MR = 0, ATDC = 0; + unsigned int PRX = 0, ATDEV = 0; + unsigned short softmuteGainLvl = 0; + + ret = mt6630_chan_para_get(freq); + if (ret == 2) + ret = fm_set_bits(FM_CHANNEL_SET, 0x2000, 0x0FFF); /* mdf HiLo */ + else + ret = fm_set_bits(FM_CHANNEL_SET, 0x0000, 0x0FFF); /* clear FA/HL/ATJ */ +#if 0 + fm_reg_write(0x60, 0x0007); + if (mt6630_TDD_chan_check(freq)) + fm_set_bits(0x30, 0x0004, 0xFFF9); /* use TDD solution */ + else + fm_set_bits(0x30, 0x0000, 0xFFF9); /* default use FDD solution */ + fm_reg_write(0x60, 0x000F); +#endif + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = fm_full_cqi_req(cmd_buf, TX_BUF_SIZE, &freq, 1, 1); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_SM_TUNE, SW_RETRY_CNT, SM_TUNE_TIMEOUT, fm_get_read_result); + FM_UNLOCK(cmd_buf_lock); + + if (!ret && fm_res) { + WCN_DBG(FM_DBG | CHIP, "smt cqi size %d\n", fm_res->cqi[0]); + p_cqi = (struct mt6630_full_cqi *)&fm_res->cqi[2]; + + RSSI = ((p_cqi->rssi & 0x03FF) >= 512) ? ((p_cqi->rssi & 0x03FF) - 1024) : (p_cqi->rssi & 0x03FF); + PAMD = ((p_cqi->pamd & 0x1FF) >= 256) ? ((p_cqi->pamd & 0x01FF) - 512) : (p_cqi->pamd & 0x01FF); + MR = ((p_cqi->mr & 0x01FF) >= 256) ? ((p_cqi->mr & 0x01FF) - 512) : (p_cqi->mr & 0x01FF); + ATDC = (p_cqi->atdc >= 32768) ? (65536 - p_cqi->atdc) : (p_cqi->atdc); + if (ATDC < 0) + ATDC = (~(ATDC)) - 1; /* Get abs value of ATDC */ + + PRX = (p_cqi->prx & 0x00FF); + ATDEV = p_cqi->atdev; + softmuteGainLvl = p_cqi->smg; + /* check if the channel is valid according to each CQIs */ + if ((fm_config.rx_cfg.long_ana_rssi_th <= RSSI) + && (fm_config.rx_cfg.pamd_th >= PAMD) + && (fm_config.rx_cfg.atdc_th >= ATDC) + && (fm_config.rx_cfg.mr_th <= MR) + && (fm_config.rx_cfg.prx_th <= PRX) + && (ATDEV >= ATDC) /* sync scan algorithm */ + && (fm_config.rx_cfg.smg_th <= softmuteGainLvl)) { + *valid = true; + } else { + *valid = false; + } + + WCN_DBG(FM_NTC | CHIP, + "valid = %d, freq %d, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x\n", + *valid, p_cqi->ch, p_cqi->rssi, p_cqi->pamd, p_cqi->pr, p_cqi->fpamd, p_cqi->mr, + p_cqi->atdc, p_cqi->prx, p_cqi->atdev, p_cqi->smg, p_cqi->drssi); + + *rssi = RSSI; + } else { + WCN_DBG(FM_ERR | CHIP, "smt get CQI failed\n"); + return false; + } + return true; +} + +/* +*parm: +* parm.th_type: 0, RSSI. 1,desense RSSI. 2,SMG. +* parm.th_val: threshold value +*/ +static signed int mt6630_set_search_th(signed int idx, signed int val, signed int reserve) +{ + switch (idx) { + case 0: { + fm_config.rx_cfg.long_ana_rssi_th = val; + WCN_DBG(FM_NTC | CHIP, "set rssi th =%d\n", val); + break; + } + case 1: { + fm_config.rx_cfg.desene_rssi_th = val; + WCN_DBG(FM_NTC | CHIP, "set desense rssi th =%d\n", val); + break; + } + case 2: { + fm_config.rx_cfg.smg_th = val; + WCN_DBG(FM_NTC | CHIP, "set smg th =%d\n", val); + break; + } + default: + break; + } + return 0; +} + +#if 0 +static const unsigned short mt6630_mcu_dese_list[] = { + 0 /* 7630, 7800, 7940, 8320, 9260, 9600, 9710, 9920, 10400, 10410 */ +}; + +static const unsigned short mt6630_gps_dese_list[] = { + 0 /* 7850, 7860 */ +}; +#endif + +static const signed char mt6630_chan_para_map[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6500~6595 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6600~6695 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, /* 6700~6795 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6800~6895 */ + 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6900~6995 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7000~7095 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7100~7195 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7200~7295 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7300~7395 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7400~7495 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7500~7595 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, /* 7600~7695 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7700~7795 */ + 8, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7800~7895 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7900~7995 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8000~8095 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8100~8195 */ + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8200~8295 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, /* 8300~8395 */ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8400~8495 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8500~8595 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8600~8695 */ + 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8700~8795 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8800~8895 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8900~8995 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9000~9095 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9100~9195 */ + 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9200~9295 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9300~9395 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9400~9495 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9500~9595 */ + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9600~9695 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9700~9795 */ + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9800~9895 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, /* 9900~9995 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10000~10095 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10100~10195 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, /* 10200~10295 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, /* 10300~10395 */ + 8, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10400~10495 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, /* 10500~10595 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10600~10695 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, /* 10700~10795 */ + 0 /* 10800 */ +}; + +static const unsigned short mt6630_TDD_list[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 6500~6595 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 6600~6695 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 6700~6795 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 6800~6895 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 6900~6995 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7000~7095 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7100~7195 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7200~7295 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7300~7395 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7400~7495 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7500~7595 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7600~7695 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7700~7795 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7800~7895 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7900~7995 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8000~8095 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8100~8195 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8200~8295 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8300~8395 */ + 0x0101, 0x0000, 0x0000, 0x0000, 0x0000, /* 8400~8495 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8500~8595 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8600~8695 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8700~8795 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8800~8895 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8900~8995 */ + 0x0000, 0x0000, 0x0101, 0x0101, 0x0101, /* 9000~9095 */ + 0x0101, 0x0000, 0x0000, 0x0000, 0x0000, /* 9100~9195 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9200~9295 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9300~9395 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9400~9495 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9500~9595 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9600~9695 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0100, /* 9700~9795 */ + 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, /* 9800~9895 */ + 0x0101, 0x0101, 0x0001, 0x0000, 0x0000, /* 9900~9995 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10000~10095 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10100~10195 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10200~10295 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10300~10395 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10400~10495 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10500~10595 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0100, /* 10600~10695 */ + 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, /* 10700~10795 */ + 0x0001 /* 10800 */ +}; + +static const unsigned short mt6630_TDD_Mask[] = { + 0x0001, 0x0010, 0x0100, 0x1000 +}; + +static const unsigned short mt6630_scan_dese_list[] = { + 7800, 9210, 9220, 9600, 9980, 10400, 10750, 10760 +}; + +/* return value: 0, not a de-sense channel; 1, this is a de-sense channel; else error no */ +static signed int mt6630_is_dese_chan(unsigned short freq) +{ + signed int size; + + /* return 0;//HQA only :skip desense channel check. */ + size = ARRAY_SIZE(mt6630_scan_dese_list); + + if (fm_get_channel_space(freq) == 0) + freq *= 10; + + while (size) { + if (mt6630_scan_dese_list[size - 1] == freq) + return 1; + + size--; + } + + return 0; +} + +static bool mt6630_TDD_chan_check(unsigned short freq) +{ + unsigned int i = 0; + unsigned short freq_tmp = freq; + signed int ret = 0; + + ret = fm_get_channel_space(freq_tmp); + if (ret == 0) + freq_tmp *= 10; + else if (ret == -1) + return false; + + i = (freq_tmp - 6500) / 5; + if ((i / 4) >= ARRAY_SIZE(mt6630_TDD_list)) { + WCN_DBG(FM_ERR | CHIP, "Freq index out of range(%d),max(%zd)\n", + i / 4, ARRAY_SIZE(mt6630_TDD_list)); + return false; + } + + if (mt6630_TDD_list[i / 4] & mt6630_TDD_Mask[i % 4]) { + WCN_DBG(FM_DBG | CHIP, "Freq %d use TDD solution\n", freq); + return true; + } else + return false; +} + +/* return value: +*1, is desense channel and rssi is less than threshold; +*0, not desense channel or it is but rssi is more than threshold. +*/ +static signed int mt6630_desense_check(unsigned short freq, signed int rssi) +{ + if (mt6630_is_dese_chan(freq)) { + if (rssi < fm_config.rx_cfg.desene_rssi_th) + return 1; + + WCN_DBG(FM_DBG | CHIP, "desen_rssi %d th:%d\n", rssi, fm_config.rx_cfg.desene_rssi_th); + } + return 0; +} + +/* get channel parameter, HL side/ FA / ATJ */ +static unsigned short mt6630_chan_para_get(unsigned short freq) +{ + signed int pos, size; + + /* return 0;//for HQA only: skip FA/HL/ATJ */ + if (fm_get_channel_space(freq) == 0) + freq *= 10; + + if (freq < 6500) + return 0; + + pos = (freq - 6500) / 5; + + size = ARRAY_SIZE(mt6630_chan_para_map); + + pos = (pos > (size - 1)) ? (size - 1) : pos; + + return mt6630_chan_para_map[pos]; +} + +static signed int mt6630_gps_dese(unsigned short freq, void *arg) +{ + enum fm_gps_desense_t state = FM_GPS_DESE_DISABLE; + + if (fm_get_channel_space(freq) == 0) + freq *= 10; + + WCN_DBG(FM_DBG | CHIP, "%s, [freq=%d]\n", __func__, (int)freq); + + if (state != FM_GPS_DESE_ENABLE) { + if ((freq >= 7800) && (freq <= 8000)) + state = FM_GPS_DESE_ENABLE; + } + /* request 6630 GPS change clk */ + if (state == FM_GPS_DESE_DISABLE) { + if (!mtk_wcn_wmt_dsns_ctrl(WMTDSNS_FM_GPS_DISABLE)) + return -1; + + return 0; + } + + if (!mtk_wcn_wmt_dsns_ctrl(WMTDSNS_FM_GPS_ENABLE)) + return -1; + + return 1; +} + +/******************************Tx function********************************************/ + +signed int mt6630_pwrup_clock_on_tx_reg_op(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 4; + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + /* B1.0 Enable digital OSC */ + pkt_size += fm_bop_write(0x60, 0x0003, &buf[pkt_size], buf_size - pkt_size); /* wr 60 3 */ + pkt_size += fm_bop_udelay(100, &buf[pkt_size], buf_size - pkt_size); /* delay 100us */ + /* B1.2 Release HW clock gating */ + pkt_size += fm_bop_write(0x60, 0x0007, &buf[pkt_size], buf_size - pkt_size); /* wr 60 7 */ + if (fm_config.aud_cfg.aud_path == FM_AUD_ANALOG) + pkt_size += fm_bop_modify(0x61, 0xFF7F, 0x0000, &buf[pkt_size], buf_size - pkt_size); + else + pkt_size += fm_bop_modify(0x61, 0xFF7F, 0x0080, &buf[pkt_size], buf_size - pkt_size); + + /* B1.4 set TX mode: 0909 sequence */ + pkt_size += fm_bop_write(0xC7, 0x8286, &buf[pkt_size], buf_size - pkt_size); /* wr C7 8286 */ + + return pkt_size - 4; +} + +/* + * mt6630_pwrup_clock_on_tx - FM tx Digital Clock enable + * @buf - target buf + * @buf_size - buffer size + * return package size + */ +static signed int mt6630_pwrup_clock_on_tx(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 0; + + pkt_size = mt6630_pwrup_clock_on_tx_reg_op(buf, buf_size); + return fm_op_seq_combine_cmd(buf, FM_ENABLE_OPCODE, pkt_size); +} + +signed int mt6630_pwrup_tx_deviation_reg_op(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 4; + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + /* A1 switch to host control */ + pkt_size += fm_bop_write(0x60, 0x0007, &buf[pkt_size], buf_size - pkt_size); /* wr 60 0007 */ + /* set rgf_tx_beta_sum */ + pkt_size += fm_bop_write(0xCD, 0x72D2, &buf[pkt_size], buf_size - pkt_size); /* wr CD 72D2 */ + /* set rgf_tx_beta_diff */ + pkt_size += fm_bop_write(0xCF, 0x787B, &buf[pkt_size], buf_size - pkt_size); /* wr CF 787B */ + /* set rgf_tx_beta_rds */ + pkt_size += fm_bop_write(0xCE, 0x0785, &buf[pkt_size], buf_size - pkt_size); /* wr CE 785 */ + /* set rgf_tx_beta_pilot */ + pkt_size += fm_bop_write(0xCC, 0x0000, &buf[pkt_size], buf_size - pkt_size); /* wr CC 0 */ + /* set rgf_phase_gen_rsh */ + pkt_size += fm_bop_modify(0xAD, 0xFFE8, 0x0001, &buf[pkt_size], buf_size - pkt_size); /* wr AD D4 D2:D0=1 */ + /* set rgf_phase_gen_wb */ + pkt_size += fm_bop_modify(0xA8, 0xF000, 0x0F16, &buf[pkt_size], buf_size - pkt_size); /* wr A8 D11:D0=F16 */ + /* set agc */ + pkt_size += fm_bop_modify(0xAE, 0xFC00, 0x020B, &buf[pkt_size], buf_size - pkt_size); /* wr AE D9:D0=20B */ + /* set rgf_beta_fm */ + pkt_size += fm_bop_write(0xEE, 0x623D, &buf[pkt_size], buf_size - pkt_size); /* wr EE 623D */ + /* switch to DSP control */ + pkt_size += fm_bop_write(0x60, 0x000F, &buf[pkt_size], buf_size - pkt_size); /* wr 60 000F */ + + return pkt_size - 4; +} + +/* + * mt6630_pwrup_tx_deviation - default deviation (RDS off) + * @buf - target buf + * @buf_size - buffer size + * return package size + */ +signed int mt6630_pwrup_tx_deviation(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 0; + + pkt_size = mt6630_pwrup_tx_deviation_reg_op(buf, buf_size); + return fm_op_seq_combine_cmd(buf, FM_ENABLE_OPCODE, pkt_size); +} + +signed int mt6630_tx_rdson_deviation_reg_op(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 4; + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + /* A1 switch to host control */ + pkt_size += fm_bop_write(0x60, 0x0007, &buf[pkt_size], buf_size - pkt_size); /* wr 60 0007 */ + /* set rgf_tx_beta_sum */ + pkt_size += fm_bop_write(0xCD, 0x70E3, &buf[pkt_size], buf_size - pkt_size); /* wr CD 70E3 */ + /* set rgf_tx_beta_diff */ + pkt_size += fm_bop_write(0xCF, 0x7675, &buf[pkt_size], buf_size - pkt_size); /* wr CF 7675 */ + /* set rgf_tx_beta_rds:0909 sequence */ + pkt_size += fm_bop_write(0xCC, 0x0227, &buf[pkt_size], buf_size - pkt_size); /* wr CC 227 */ + /* set rgf_tx_beta_pilot :0909 sequence */ + pkt_size += fm_bop_write(0xCE, 0x0764, &buf[pkt_size], buf_size - pkt_size); /* wr CE 764 */ + /* set rgf_phase_gen_rsh */ + pkt_size += fm_bop_modify(0xAD, 0xFFEF, 0x0000, &buf[pkt_size], buf_size - pkt_size); /* wr AD D4 =0 */ + pkt_size += fm_bop_modify(0xAD, 0xFFF8, 0x0001, &buf[pkt_size], buf_size - pkt_size); /* wr AD D2:D0=1 */ + /* set rgf_phase_gen_wb */ + pkt_size += fm_bop_modify(0xA8, 0xF000, 0x0222, &buf[pkt_size], buf_size - pkt_size); /* wr A8 D11:D0=222 */ + /* set agc */ + pkt_size += fm_bop_modify(0xAE, 0xFC00, 0x0203, &buf[pkt_size], buf_size - pkt_size); /* wr AE D9:D0=203 */ + /* set rgf_beta_fm */ + pkt_size += fm_bop_write(0xEE, 0x63EB, &buf[pkt_size], buf_size - pkt_size); /* wr EE 63EB */ + /* switch to DSP control */ + pkt_size += fm_bop_write(0x60, 0x000F, &buf[pkt_size], buf_size - pkt_size); /* wr 60 000F */ + + return pkt_size - 4; +} +/* + * mt6630_tx_rdsoff_deviation - deviation (RDS on) + * @buf - target buf + * @buf_size - buffer size + * return package size + */ +static signed int mt6630_tx_rdson_deviation(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 0; + + pkt_size = mt6630_tx_rdson_deviation_reg_op(buf, buf_size); + return fm_op_seq_combine_cmd(buf, RDS_TX_OPCODE, pkt_size); +} + +signed int mt6630_tune_tx_reg_op(unsigned char *buf, signed int buf_size, unsigned short freq, + unsigned short chan_para) +{ + signed int pkt_size = 4; + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + if (fm_get_channel_space(freq) == 0) + freq *= 10; + + freq = (freq - 6400) * 2 / 10; + /* Set desired channel & channel parameter */ +#ifdef FM_TUNE_USE_POLL + pkt_size += fm_bop_write(0x6B, 0x0000, &buf[pkt_size], buf_size - pkt_size); +#endif + /* sequence 09/16:0x65 D12=1 for iq switch */ + pkt_size += fm_bop_modify(FM_CHANNEL_SET, 0xEC00, freq | 0x1000, &buf[pkt_size], buf_size - pkt_size); + /* set 0x65[9:0] = 0x029e, => ((97.5 - 64) * 20) */ + /* set iq switch, D12 */ + /* pkt_size += fm_bop_modify(FM_CHANNEL_SET, 0x0FFF, (chan_para << 12), &buf[pkt_size], buf_size - pkt_size); */ + /* Enable hardware controlled tuning sequence */ + pkt_size += fm_bop_modify(FM_MAIN_CTRL, 0xFFF8, TUNE, &buf[pkt_size], buf_size - pkt_size); + /* Wait for STC_DONE interrupt */ +#ifdef FM_TUNE_USE_POLL + pkt_size += fm_bop_rd_until(FM_MAIN_INTR, FM_INTR_STC_DONE, FM_INTR_STC_DONE, &buf[pkt_size], + buf_size - pkt_size); + /* Write 1 clear the STC_DONE interrupt status flag */ + pkt_size += fm_bop_modify(FM_MAIN_INTR, 0xFFFF, FM_INTR_STC_DONE, &buf[pkt_size], buf_size - pkt_size); +#endif + + return pkt_size - 4; +} + + +/* + * mt6630_tune_tx - execute tx tune action, + * @buf - target buf + * @buf_size - buffer size + * @freq - 760 ~ 1080, 100KHz unit + * return package size + */ +static signed int mt6630_tune_tx(unsigned char *buf, signed int buf_size, unsigned short freq, + unsigned short chan_para) +{ + signed int pkt_size = 0; + + pkt_size = mt6630_tune_tx_reg_op(buf, buf_size, freq, chan_para); + return fm_op_seq_combine_cmd(buf, FM_TUNE_OPCODE, pkt_size); +} + +signed int mt6630_rds_tx_reg_op(unsigned char *tx_buf, signed int tx_buf_size, unsigned short pi, + unsigned short *ps, unsigned short *other_rds, unsigned char other_rds_cnt) +{ + signed int pkt_size = 4; + signed int i = 0; + + if (tx_buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (tx_buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, tx_buf_size); + return -2; + } + + /* set repeat mode */ + pkt_size += fm_bop_modify(0x88, 0xFFFE, 0x0001, &tx_buf[pkt_size], TX_BUF_SIZE - pkt_size); + /* wr 88[0] = b'1, repeat mode */ + pkt_size += fm_bop_modify(0x88, 0xFFFB, 0x0004, &tx_buf[pkt_size], TX_BUF_SIZE - pkt_size); + /* wr 88[2] = b'1, PI_reg mode */ + pkt_size += fm_bop_write(0x8A, pi, &tx_buf[pkt_size], tx_buf_size - pkt_size); + /* write PI to PI_reg */ + + pkt_size += fm_bop_modify(0x88, 0xFFFD, 0x0002, &tx_buf[pkt_size], TX_BUF_SIZE - pkt_size); + /* wr 88[1] = b'1, addr from host */ + for (i = 0; i < 12; i++) { + pkt_size += fm_bop_write(0x8B, (0x0063 + i), &tx_buf[pkt_size], tx_buf_size - pkt_size); + /* 8B = mem_addr */ + pkt_size += fm_bop_write(0x8C, ps[i], &tx_buf[pkt_size], tx_buf_size - pkt_size); + /* 8C = RDS Tx data */ + } + pkt_size += fm_bop_modify(0x88, 0xFFFD, 0x0000, &tx_buf[pkt_size], TX_BUF_SIZE - pkt_size); + /* wr 88[1] = b'0, clear mem_addr */ + pkt_size += fm_bop_modify(0x88, 0xFFEF, 0x0010, &tx_buf[pkt_size], TX_BUF_SIZE - pkt_size); + /* wr 88[4] = b'1, switch to ps buf */ + /* work around: write at leat one group to normal buffer, otherwise ps buffer can be sent out. */ + pkt_size += fm_bop_write(0x8C, 0, &tx_buf[pkt_size], tx_buf_size - pkt_size); + pkt_size += fm_bop_write(0x8C, 0, &tx_buf[pkt_size], tx_buf_size - pkt_size); + pkt_size += fm_bop_write(0x8C, 0, &tx_buf[pkt_size], tx_buf_size - pkt_size); + pkt_size += fm_bop_write(0x8C, 0, &tx_buf[pkt_size], tx_buf_size - pkt_size); + pkt_size += fm_bop_modify(0x88, 0xFFDF, 0x0020, &tx_buf[pkt_size], TX_BUF_SIZE - pkt_size); + /* wr 88[5] = b'1,clear in_ptr */ + pkt_size += fm_bop_modify(0x88, 0xFFDF, 0x0000, &tx_buf[pkt_size], TX_BUF_SIZE - pkt_size); + /* wr 88[5] = b'0,clear in_ptr */ + + return pkt_size - 4; +} + +/* +*pi: pi code +*ps: block B,C,D +*other_rds: unused +*other_rds_cnt: unused +*/ +static signed int mt6630_rds_tx(unsigned char *tx_buf, signed int tx_buf_size, unsigned short pi, + unsigned short *ps, unsigned short *other_rds, unsigned char other_rds_cnt) +{ + signed int pkt_size = 0; + + pkt_size = mt6630_rds_tx_reg_op(tx_buf, tx_buf_size, pi, ps, other_rds, other_rds_cnt); + return fm_op_seq_combine_cmd(tx_buf, RDS_TX_OPCODE, pkt_size); +} + +static signed int mt6630_Tx_Support(signed int *sup) +{ + *sup = 1; + return 0; +} + +/* +*pi: pi code, +*ps: block B,C,D +*other_rds: NULL now +*other_rds_cnt:0 now +*/ +static signed int MT6630_lib_Rds_Tx_adapter(unsigned short pi, unsigned short *ps, unsigned short *other_rds, + unsigned char other_rds_cnt) +{ + signed int ret = 0; + unsigned short pkt_size = 0; + + WCN_DBG(FM_NTC | RDSC, + "+%s():PI=0x%04x, PS=0x%04x/0x%04x/0x%04x/0x%04x, other_rds_cnt=%d\n", __func__, + pi, ps[0], ps[1], ps[2], ps[3], other_rds_cnt); + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = mt6630_rds_tx(cmd_buf, TX_BUF_SIZE, pi, ps, other_rds, other_rds_cnt); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_RDS_TX, SW_RETRY_CNT, RDS_TX_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + + return ret; +} + +/* +*freq: 8750~10800 +*valid: true-valid channel,false-invalid channel +*return: true- smt success, false-smt fail +*/ +static signed int mt6630_soft_mute_tune_Tx(unsigned short freq, signed int *rssi, bool *valid) +{ + signed int ret = 0; + unsigned short pkt_size; + struct mt6630_full_cqi *p_cqi; + signed int RSSI = 0, PAMD = 0, MR = 0, ATDC = 0; + unsigned int PRX = 0, ATDEV = 0; + unsigned short softmuteGainLvl = 0; + + ret = mt6630_chan_para_get(freq); + if (ret == 2) + ret = fm_set_bits(FM_CHANNEL_SET, 0x2000, 0x0FFF); /* mdf HiLo */ + else + ret = fm_set_bits(FM_CHANNEL_SET, 0x0000, 0x0FFF); /* clear FA/HL/ATJ */ + + fm_reg_write(0x60, 0x0007); + if (mt6630_TDD_chan_check(freq)) + fm_set_bits(0x30, 0x0004, 0xFFF9); /* use TDD solution */ + else + fm_set_bits(0x30, 0x0000, 0xFFF9); /* default use FDD solution */ + fm_reg_write(0x60, 0x000F); + + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = fm_full_cqi_req(cmd_buf, TX_BUF_SIZE, &freq, 1, 1); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_SM_TUNE, SW_RETRY_CNT, SM_TUNE_TIMEOUT, fm_get_read_result); + FM_UNLOCK(cmd_buf_lock); + + if (!ret && fm_res) { + WCN_DBG(FM_NTC | CHIP, "smt cqi size %d\n", fm_res->cqi[0]); + p_cqi = (struct mt6630_full_cqi *)&fm_res->cqi[2]; + /* just for debug */ + WCN_DBG(FM_NTC | CHIP, + "freq %d, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x\n", + p_cqi->ch, p_cqi->rssi, p_cqi->pamd, p_cqi->pr, p_cqi->fpamd, p_cqi->mr, + p_cqi->atdc, p_cqi->prx, p_cqi->atdev, p_cqi->smg, p_cqi->drssi); + RSSI = ((p_cqi->rssi & 0x03FF) >= 512) ? ((p_cqi->rssi & 0x03FF) - 1024) : (p_cqi->rssi & 0x03FF); + PAMD = ((p_cqi->pamd & 0x1FF) >= 256) ? ((p_cqi->pamd & 0x01FF) - 512) : (p_cqi->pamd & 0x01FF); + MR = ((p_cqi->mr & 0x01FF) >= 256) ? ((p_cqi->mr & 0x01FF) - 512) : (p_cqi->mr & 0x01FF); + ATDC = (p_cqi->atdc >= 32768) ? (65536 - p_cqi->atdc) : (p_cqi->atdc); + if (ATDC < 0) + ATDC = (~(ATDC)) - 1; /* Get abs value of ATDC */ + + PRX = (p_cqi->prx & 0x00FF); + ATDEV = p_cqi->atdev; + softmuteGainLvl = p_cqi->smg; + /* check if the channel is valid according to each CQIs */ + if ((fm_config.tx_cfg.pamd_th < PAMD) + && (fm_config.tx_cfg.mr_th >= MR) + && (fm_config.tx_cfg.smg_th > softmuteGainLvl)) + *valid = true; + else + *valid = false; + + *rssi = RSSI; + } else { + WCN_DBG(FM_ERR | CHIP, "smt get CQI failed\n"); + return false; + } + WCN_DBG(FM_NTC | CHIP, "valid=%d\n", *valid); + return true; +} + +#define TX_ABANDON_BAND_LOW1 7320 +#define TX_ABANDON_BAND_HIGH1 7450 +#define TX_ABANDON_BAND_LOW2 9760 +#define TX_ABANDON_BAND_HIGH2 9940 +static signed int mt6630_TxScan(unsigned short min_freq, unsigned short max_freq, unsigned short *pFreq, + unsigned short *pScanTBL, unsigned short *ScanTBLsize, unsigned short scandir, + unsigned short space) +{ + signed int i = 0, ret = 0; + unsigned short freq = *pFreq; + unsigned short scan_cnt = *ScanTBLsize; + unsigned short cnt = 0; + signed int rssi = 0; + signed int step; + bool valid = false; + signed int total_no = 0; + + WCN_DBG(FM_NTC | CHIP, "+%s():\n", __func__); + + if ((!pScanTBL) || (*ScanTBLsize < FM_TX_SCAN_MIN) || (*ScanTBLsize > FM_TX_SCAN_MAX)) { + WCN_DBG(FM_ERR | CHIP, "invalid scan table\n"); + ret = -FM_EPARA; + return 1; + } + if (fm_get_channel_space(freq) == 0) + *pFreq *= 10; + + if (fm_get_channel_space(max_freq) == 0) + max_freq *= 10; + + if (fm_get_channel_space(min_freq) == 0) + min_freq *= 10; + + WCN_DBG(FM_NTC | CHIP, + "[freq=%d], [max_freq=%d],[min_freq=%d],[scan BTL size=%d],[scandir=%d],[space=%d]\n", + *pFreq, max_freq, min_freq, *ScanTBLsize, scandir, space); + + cnt = 0; + if (space == FM_SPACE_200K) + step = 20; + else if (space == FM_SPACE_50K) + step = 5; + else + step = 10; + + total_no = (max_freq - min_freq) / step + 1; + if (scandir == FM_TX_SCAN_UP) { + for (i = ((*pFreq - min_freq) / step); i < total_no; i++) { + freq = min_freq + step * i; + + /* FM desense GPS */ + if ((freq >= TX_ABANDON_BAND_LOW1) && (freq <= TX_ABANDON_BAND_HIGH1)) { + freq = TX_ABANDON_BAND_HIGH1 + 10; + i = (freq - min_freq) / step; + } + + if ((freq >= TX_ABANDON_BAND_LOW2) && (freq <= TX_ABANDON_BAND_HIGH2)) { + freq = TX_ABANDON_BAND_HIGH2 + 10; + i = (freq - min_freq) / step; + } + + ret = mt6630_soft_mute_tune_Tx(freq, &rssi, &valid); + if (ret == false) { + WCN_DBG(FM_ERR | CHIP, "mt6630_soft_mute_tune_tx failed\n"); + return 1; + } + + if (valid == true) { + *(pScanTBL + cnt) = freq; /* strore the valid empty channel */ + cnt++; + WCN_DBG(FM_NTC | CHIP, "empty channel:[freq=%d] [cnt=%d]\n", freq, cnt); + } + if (cnt >= scan_cnt) + break; + } + + if (cnt < scan_cnt) { + for (i = 0; i < ((*pFreq - min_freq) / step); i++) { + freq = min_freq + step * i; + + /* FM desense GPS */ + if ((freq >= TX_ABANDON_BAND_LOW1) && (freq <= TX_ABANDON_BAND_HIGH1)) { + freq = TX_ABANDON_BAND_HIGH1 + 10; + i = (freq - min_freq) / step; + } + + if ((freq >= TX_ABANDON_BAND_LOW2) && (freq <= TX_ABANDON_BAND_HIGH2)) { + freq = TX_ABANDON_BAND_HIGH2 + 10; + i = (freq - min_freq) / step; + } + + if (i >= ((*pFreq - min_freq) / step)) + break; + + ret = mt6630_soft_mute_tune_Tx(freq, &rssi, &valid); + if (ret == false) { + WCN_DBG(FM_ERR | CHIP, "mt6630_soft_mute_tune failed\n"); + return 1; + } + + if (valid == true) { + *(pScanTBL + cnt) = freq; /* strore the valid empty channel */ + cnt++; + WCN_DBG(FM_NTC | CHIP, "empty channel:[freq=%d] [cnt=%d]\n", freq, cnt); + } + if (cnt >= scan_cnt) + break; + } + } + } else { + for (i = ((*pFreq - min_freq) / step - 1); i >= 0; i--) { + freq = min_freq + step * i; + + /* FM desense GPS */ + if ((freq >= TX_ABANDON_BAND_LOW1) && (freq <= TX_ABANDON_BAND_HIGH1)) { + freq = TX_ABANDON_BAND_LOW1 - 10; + i = (freq - min_freq) / step; + } + + if ((freq >= TX_ABANDON_BAND_LOW2) && (freq <= TX_ABANDON_BAND_HIGH2)) { + freq = TX_ABANDON_BAND_LOW2 - 10; + i = (freq - min_freq) / step; + } + + ret = mt6630_soft_mute_tune_Tx(freq, &rssi, &valid); + if (ret == false) { + WCN_DBG(FM_ERR | CHIP, "mt6630_soft_mute_tune failed\n"); + return 1; + } + + if (valid == true) { + *(pScanTBL + cnt) = freq; /* strore the valid empty channel */ + cnt++; + WCN_DBG(FM_NTC | CHIP, "empty channel:[freq=%d] [cnt=%d]\n", freq, cnt); + } + if (cnt >= scan_cnt) + break; + } + if (cnt < scan_cnt) { + for (i = (total_no - 1); i > ((*pFreq - min_freq) / step); i--) { + freq = min_freq + step * i; + + /* FM desense GPS */ + if ((freq >= TX_ABANDON_BAND_LOW1) && (freq <= TX_ABANDON_BAND_HIGH1)) { + freq = TX_ABANDON_BAND_LOW1 - 10; + i = (freq - min_freq) / step; + } + + if ((freq >= TX_ABANDON_BAND_LOW2) && (freq <= TX_ABANDON_BAND_HIGH2)) { + freq = TX_ABANDON_BAND_LOW2 - 10; + i = (freq - min_freq) / step; + } + + if (i <= ((*pFreq - min_freq) / step)) + break; + + ret = mt6630_soft_mute_tune_Tx(freq, &rssi, &valid); + if (ret == false) { + WCN_DBG(FM_ERR | CHIP, "mt6630_soft_mute_tune failed\n"); + return 1; + } + + if (valid == true) { + *(pScanTBL + cnt) = freq; /* strore the valid empty channel */ + cnt++; + WCN_DBG(FM_NTC | CHIP, "empty channel:[freq=%d] [cnt=%d]\n", freq, cnt); + } + if (cnt >= scan_cnt) + break; + } + } + } + + *ScanTBLsize = cnt; + WCN_DBG(FM_NTC | CHIP, "completed, [cnt=%d],[freq=%d]\n", cnt, freq); + /* return 875~1080 */ + for (i = 0; i < cnt; i++) { + if (fm_get_channel_space(*(pScanTBL + i)) == 1 && space != FM_SPACE_50K) + *(pScanTBL + i) = *(pScanTBL + i) / 10; + } + WCN_DBG(FM_NTC | CHIP, "-%s():[ret=%d]\n", __func__, ret); + return 0; +} + +static signed int mt6630_PowerUpTx(void) +{ + signed int ret = 0; + unsigned short pkt_size; + unsigned short dataRead = 0; + + WCN_DBG(FM_NTC | CHIP, "pwr on Tx seq......\n"); + + ret = mt6630_pwrup_top_setting(); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "mt6630_pwrup_top_setting failed\n"); + return ret; + } + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + + pkt_size = mt6630_pwrup_clock_on_tx(cmd_buf, TX_BUF_SIZE); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + + if (ret) { + WCN_DBG(FM_ALT | CHIP, "mt6630_pwrup_clock_on_tx failed\n"); + return ret; + } + + fm_reg_read(0x62, &dataRead); + WCN_DBG(FM_NTC | CHIP, "Tx on chipid=%x\n", dataRead); + + ret = mt6630_pwrup_DSP_download(mt6630_patch_tbl_tx); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "mt6630_pwrup_DSP_download failed\n"); + return ret; + } + + if ((fm_config.aud_cfg.aud_path == FM_AUD_MRGIF) + || (fm_config.aud_cfg.aud_path == FM_AUD_I2S)) { + mt6630_I2s_Setting(FM_I2S_ON, fm_config.aud_cfg.i2s_info.mode, + fm_config.aud_cfg.i2s_info.rate); + /* mtk_wcn_cmb_stub_audio_ctrl((CMB_STUB_AIF_X)CMB_STUB_AIF_2);//no need to do? */ + WCN_DBG(FM_NTC | CHIP, "pwron set I2S on ok\n"); + } + + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + + pkt_size = mt6630_pwrup_digital_init(cmd_buf, TX_BUF_SIZE); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + if (ret) { + WCN_DBG(FM_ALT | CHIP, "mt6630_dig_init failed\n"); + return ret; + } + + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + + pkt_size = mt6630_tx_rdson_deviation(cmd_buf, TX_BUF_SIZE); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_RDS_TX, SW_RETRY_CNT, EN_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + if (ret) { + WCN_DBG(FM_ALT | CHIP, "mt6630_tx_rdson_deviation failed\n"); + return ret; + } + + WCN_DBG(FM_DBG | CHIP, "pwr on tx seq ok\n"); + return ret; +} + +static signed int mt6630_PowerDownTx(void) +{ + signed int ret = 0; + + ret = mt6630_PowerDown(); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "mt6630_PowerDownTx failed\n"); + return ret; + } + + return ret; +} + +static unsigned short mt6630_Hside_list_Tx[] = { 7720, 8045 }; + +static bool mt6630_HiSide_chan_check_Tx(unsigned short freq) +{ + /* signed int pos, size; */ + unsigned int i = 0, count = 0; + + /* return 0;//for HQA only: skip FA/HL/ATJ */ + if (fm_get_channel_space(freq) == 0) + freq *= 10; + + if (freq < 6500) + return false; + + count = ARRAY_SIZE(mt6630_Hside_list_Tx); + for (i = 0; i < count; i++) { + if (freq == mt6630_Hside_list_Tx[i]) + return true; + } + + return false; +} + +static bool MT6630_SetFreq_Tx(unsigned short freq) +{ + signed int ret = 0; + unsigned short pkt_size; + unsigned short chan_para = 0; + unsigned short dataRead = 0; + + /* repeat tune due to audio noise workaround */ + fm_reg_read(0x63, &dataRead); + fm_reg_read(0x61, &dataRead); + fm_reg_write(0x63, 0x0); + fm_reg_write(0x61, 0x81); + fm_reg_write(0x61, 0x83); + fm_reg_write(0x61, 0x82); + /*fm_reg_write(0x69, 0x1);*/ + do { + fm_reg_read(0x64, &dataRead); + WCN_DBG(FM_DBG | CHIP, "dataRead = %d\n", dataRead); + } while (dataRead != 2); + + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + + pkt_size = mt6630_tx_rdson_deviation(cmd_buf, TX_BUF_SIZE); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_RDS_TX, SW_RETRY_CNT, EN_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + if (ret) { + WCN_DBG(FM_ALT | CHIP, "mt6630_tx_rdson_deviation failed\n"); + return ret; + } + /* repeat tune due to audio noise workaround end */ + + ret = mt6630_RampDown(); + if (ret) { + WCN_DBG(FM_ALT | CHIP, "mt6630_RampDown failed\n"); + return ret; + } + + if (true == mt6630_HiSide_chan_check_Tx(freq)) { + WCN_DBG(FM_DBG | CHIP, "%d chan para = %d\n", (signed int) freq, (signed int) chan_para); + ret = fm_set_bits(FM_CHANNEL_SET, 0x2000, 0x0FFF); /* mdf HiLo */ + } else + ret = fm_set_bits(FM_CHANNEL_SET, 0x0000, 0xEFFF); /* clear HiLo */ + + if (ret) { + WCN_DBG(FM_ALT | CHIP, "fm_set_bits failed\n"); + return ret; + } + /* fm_cb_op->cur_freq_set(freq); */ + /* start tune */ + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = mt6630_tune_tx(cmd_buf, TX_BUF_SIZE, freq, 0); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_TUNE | FLAG_TUNE_DONE, SW_RETRY_CNT, TUNE_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + + if (ret) { + WCN_DBG(FM_ALT | CHIP, "mt6630_tune_tx failed\n"); + return ret; + } + + WCN_DBG(FM_DBG | CHIP, "mt6630_tune_tx to %d ok\n", freq); + + return true; +} + +signed int fm_low_ops_register(struct fm_callback *cb, struct fm_basic_interface *bi) +{ + signed int ret = 0; + /* Basic functions. */ + + if (bi == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,bi invalid pointer\n", __func__); + return -FM_EPARA; + } + if (cb->cur_freq_get == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,cb->cur_freq_get invalid pointer\n", __func__); + return -FM_EPARA; + } + if (cb->cur_freq_set == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,cb->cur_freq_set invalid pointer\n", __func__); + return -FM_EPARA; + } + fm_cb_op = cb; + + bi->pwron = mt6630_pwron; + bi->pwroff = mt6630_pwroff; + bi->chipid_get = mt6630_get_chipid; + bi->mute = mt6630_Mute; + bi->rampdown = mt6630_RampDown; + bi->pwrupseq = mt6630_PowerUp; + bi->pwrdownseq = mt6630_PowerDown; + bi->setfreq = mt6630_SetFreq; + /* bi->low_pwr_wa = MT6630fm_low_power_wa_default; */ + bi->i2s_set = mt6630_I2s_Setting; + bi->rssiget = mt6630_GetCurRSSI; + bi->volset = mt6630_SetVol; + bi->volget = mt6630_GetVol; + bi->dumpreg = mt6630_dump_reg; + bi->msget = mt6630_GetMonoStereo; + bi->msset = mt6630_SetMonoStereo; + bi->pamdget = mt6630_GetCurPamd; + /* bi->em = mt6630_em_test; */ + bi->anaswitch = mt6630_SetAntennaType; + bi->anaget = mt6630_GetAntennaType; + bi->caparray_get = mt6630_GetCapArray; + bi->hwinfo_get = mt6630_hw_info_get; + bi->fm_via_bt = MT6630_FMOverBT; + bi->i2s_get = mt6630_i2s_info_get; + bi->is_dese_chan = mt6630_is_dese_chan; + bi->softmute_tune = mt6630_soft_mute_tune; + bi->desense_check = mt6630_desense_check; + bi->cqi_log = mt6630_full_cqi_get; + bi->pre_search = mt6630_pre_search; + bi->restore_search = mt6630_restore_search; + bi->set_search_th = mt6630_set_search_th; + bi->get_aud_info = mt6630fm_get_audio_info; + /*****tx function****/ + bi->tx_support = mt6630_Tx_Support; + bi->pwrupseq_tx = mt6630_PowerUpTx; + bi->tune_tx = MT6630_SetFreq_Tx; + bi->pwrdownseq_tx = mt6630_PowerDownTx; + bi->tx_scan = mt6630_TxScan; + /* need call fm link/cmd */ + bi->rds_tx_adapter = MT6630_lib_Rds_Tx_adapter; + /* bi->tx_pwr_ctrl = MT6630_TX_PWR_CTRL; */ + /* bi->rtc_drift_ctrl = MT6630_RTC_Drift_CTRL; */ + /* bi->tx_desense_wifi = MT6630_TX_DESENSE; */ + + cmd_buf_lock = fm_lock_create("30_cmd"); + ret = fm_lock_get(cmd_buf_lock); + + cmd_buf = fm_zalloc(TX_BUF_SIZE + 1); + + if (!cmd_buf) { + WCN_DBG(FM_ERR | CHIP, "6630 fm lib alloc tx buf failed\n"); + ret = -1; + } + + return ret; +} + +signed int fm_low_ops_unregister(struct fm_basic_interface *bi) +{ + signed int ret = 0; + /* Basic functions. */ + if (bi == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + if (cmd_buf) { + fm_free(cmd_buf); + cmd_buf = NULL; + } + + ret = fm_lock_put(cmd_buf_lock); + fm_memset(bi, 0, sizeof(struct fm_basic_interface)); + return ret; +} diff --git a/drivers/misc/mediatek/connectivity/fmradio/chips/mt6630/pub/mt6630_fm_rds.c b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6630/pub/mt6630_fm_rds.c new file mode 100644 index 0000000000000000000000000000000000000000..5f413c6a50de08ac73597785d887b50877833e2a --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6630/pub/mt6630_fm_rds.c @@ -0,0 +1,368 @@ +/* + * Copyright (C) 2015 MediaTek Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 "fm_typedef.h" +#include "fm_dbg.h" +#include "fm_err.h" +#include "fm_interface.h" +#include "fm_stdlib.h" +#include "fm_rds.h" +#include "mt6630_fm_reg.h" +#include "fm_cmd.h" + +static bool bRDS_FirstIn; /* false */ +static unsigned int gBLER_CHK_INTERVAL = 500; +static unsigned short GOOD_BLK_CNT = 0, BAD_BLK_CNT; +static unsigned char BAD_BLK_RATIO; + +static struct fm_basic_interface *fm_bi; + +static bool mt6630_RDS_support(void); +static signed int mt6630_RDS_enable(void); +static signed int mt6630_RDS_disable(void); +static unsigned short mt6630_RDS_Get_GoodBlock_Counter(void); +static unsigned short mt6630_RDS_Get_BadBlock_Counter(void); +static unsigned char mt6630_RDS_Get_BadBlock_Ratio(void); +static unsigned int mt6630_RDS_Get_BlerCheck_Interval(void); +/* static void mt6630_RDS_GetData(unsigned short *data, unsigned short datalen); */ +static void mt6630_RDS_Init_Data(struct rds_t *pstRDSData); + +static bool mt6630_RDS_support(void) +{ + return true; +} + +static signed int mt6630_RDS_enable(void) +{ + signed int ret = 0; + unsigned short dataRead = 0; + + WCN_DBG(FM_DBG | RDSC, "rds enable\n"); + /* ret = fm_reg_read(FM_RDS_CFG0, &dataRead); */ + ret = fm_reg_write(FM_RDS_CFG0, 6); /* set buf_start_th */ + if (ret) { + WCN_DBG(FM_NTC | RDSC, "rds enable write 0x80 fail\n"); + return ret; + } + ret = fm_reg_read(FM_MAIN_CTRL, &dataRead); + if (ret) { + WCN_DBG(FM_NTC | RDSC, "rds enable read 0x63 fail\n"); + return ret; + } + ret = fm_reg_write(FM_MAIN_CTRL, dataRead | (RDS_MASK)); + if (ret) { + WCN_DBG(FM_NTC | RDSC, "rds enable write 0x63 fail\n"); + return ret; + } + + return ret; +} + +static signed int mt6630_RDS_disable(void) +{ + signed int ret = 0; + unsigned short dataRead = 0; + + WCN_DBG(FM_DBG | RDSC, "rds disable\n"); + ret = fm_reg_read(FM_MAIN_CTRL, &dataRead); + if (ret) { + WCN_DBG(FM_NTC | RDSC, "rds disable read 0x63 fail\n"); + return ret; + } + ret = fm_reg_write(FM_MAIN_CTRL, dataRead & (~RDS_MASK)); + if (ret) { + WCN_DBG(FM_NTC | RDSC, "rds disable write 0x63 fail\n"); + return ret; + } + + return ret; +} + +static unsigned short mt6630_RDS_Get_GoodBlock_Counter(void) +{ + unsigned short tmp_reg = 0; + + fm_reg_read(FM_RDS_GOODBK_CNT, &tmp_reg); + GOOD_BLK_CNT = tmp_reg; + WCN_DBG(FM_DBG | RDSC, "get good block cnt:%d\n", (signed int) tmp_reg); + + return tmp_reg; +} + +static unsigned short mt6630_RDS_Get_BadBlock_Counter(void) +{ + unsigned short tmp_reg = 0; + + fm_reg_read(FM_RDS_BADBK_CNT, &tmp_reg); + BAD_BLK_CNT = tmp_reg; + WCN_DBG(FM_DBG | RDSC, "get bad block cnt:%d\n", (signed int) tmp_reg); + + return tmp_reg; +} + +static unsigned char mt6630_RDS_Get_BadBlock_Ratio(void) +{ + unsigned short tmp_reg; + unsigned short gbc; + unsigned short bbc; + + gbc = mt6630_RDS_Get_GoodBlock_Counter(); + bbc = mt6630_RDS_Get_BadBlock_Counter(); + + if ((gbc + bbc) > 0) + tmp_reg = (unsigned char) (bbc * 100 / (gbc + bbc)); + else + tmp_reg = 0; + + BAD_BLK_RATIO = tmp_reg; + WCN_DBG(FM_DBG | RDSC, "get badblock ratio:%d\n", (signed int) tmp_reg); + + return tmp_reg; +} + +static signed int mt6630_RDS_BlockCounter_Reset(void) +{ + mt6630_RDS_disable(); + mt6630_RDS_enable(); + + return 0; +} + +static unsigned int mt6630_RDS_Get_BlerCheck_Interval(void) +{ + return gBLER_CHK_INTERVAL; +} + +static signed int mt6630_RDS_BlerCheck(struct rds_t *dst) +{ + return 0; +} + +#if 0 +static void RDS_Recovery_Handler(void) +{ + unsigned short tempData = 0; + + do { + fm_reg_read(FM_RDS_DATA_REG, &tempData); + fm_reg_read(FM_RDS_POINTER, &tempData); + } while (tempData & 0x3); +} +#endif + +#if 0 +static void mt6630_RDS_GetData(unsigned short *data, unsigned short datalen) +{ +#define RDS_GROUP_DIFF_OFS 0x007C +#define RDS_FIFO_DIFF 0x007F +#define RDS_CRC_BLK_ADJ 0x0020 +#define RDS_CRC_CORR_CNT 0x001E +#define RDS_CRC_INFO 0x0001 + + unsigned short CRC = 0, i = 0, RDS_adj = 0, RDSDataCount = 0, FM_WARorrCnt = 0; + unsigned short temp = 0, OutputPofm_s32 = 0; + + WCN_DBG(FM_DBG | RDSC, "get data\n"); + fm_reg_read(FM_RDS_FIFO_STATUS0, &temp); + RDSDataCount = ((RDS_GROUP_DIFF_OFS & temp) << 2); + + if ((temp & RDS_FIFO_DIFF) >= 4) { + /* block A data and info handling */ + fm_reg_read(FM_RDS_INFO, &temp); + RDS_adj |= (temp & RDS_CRC_BLK_ADJ) << 10; + CRC |= (temp & RDS_CRC_INFO) << 3; + FM_WARorrCnt |= ((temp & RDS_CRC_CORR_CNT) << 11); + fm_reg_read(FM_RDS_DATA_REG, &data[0]); + + /* block B data and info handling */ + fm_reg_read(FM_RDS_INFO, &temp); + RDS_adj |= (temp & RDS_CRC_BLK_ADJ) << 9; + CRC |= (temp & RDS_CRC_INFO) << 2; + FM_WARorrCnt |= ((temp & RDS_CRC_CORR_CNT) << 7); + fm_reg_read(FM_RDS_DATA_REG, &data[1]); + + /* block C data and info handling */ + fm_reg_read(FM_RDS_INFO, &temp); + RDS_adj |= (temp & RDS_CRC_BLK_ADJ) << 8; + CRC |= (temp & RDS_CRC_INFO) << 1; + FM_WARorrCnt |= ((temp & RDS_CRC_CORR_CNT) << 3); + fm_reg_read(FM_RDS_DATA_REG, &data[2]); + + /* block D data and info handling */ + fm_reg_read(FM_RDS_INFO, &temp); + RDS_adj |= (temp & RDS_CRC_BLK_ADJ) << 7; + CRC |= (temp & RDS_CRC_INFO); + FM_WARorrCnt |= ((temp & RDS_CRC_CORR_CNT) >> 1); + fm_reg_read(FM_RDS_DATA_REG, &data[3]); + + data[4] = (CRC | RDS_adj | RDSDataCount); + data[5] = FM_WARorrCnt; + + fm_reg_read(FM_RDS_PWDI, &data[6]); + fm_reg_read(FM_RDS_PWDQ, &data[7]); + + fm_reg_read(FM_RDS_POINTER, &OutputPofm_s32); + + /* Go fm_s32o RDS recovery handler while RDS output pofm_s32 doesn't align to 4 in numeric */ + if (OutputPofm_s32 & 0x3) + RDS_Recovery_Handler(); + + } else { + for (; i < 8; i++) + data[i] = 0; + } +} +#endif + +static signed int mt6630_rdsTx_Support(signed int *sup) +{ + *sup = 1; + return 0; +} + +static signed int mt6630_Rds_Tx_Enable(void) +{ + fm_set_bits(0xC7, 0x0800, 0xF7FF); + return 0; +} + +static signed int mt6630_Rds_Tx_Disable(void) +{ + fm_set_bits(0xC7, 0x0000, 0xF7FF); + return 0; +} + +/* +*pi: pi code, +*ps: block B,C,D +*other_rds: NULL now +*other_rds_cnt:0 now +*/ +static signed int mt6630_Rds_Tx(unsigned short pi, unsigned short *ps, unsigned short *other_rds, + unsigned char other_rds_cnt) +{ + return fm_bi->rds_tx_adapter(pi, ps, other_rds, other_rds_cnt); +} + +static void mt6630_RDS_Init_Data(struct rds_t *pstRDSData) +{ + fm_memset(pstRDSData, 0, sizeof(struct rds_t)); + bRDS_FirstIn = true; + + fm_memset(pstRDSData->RT_Data.TextData, 0x20, sizeof(pstRDSData->RT_Data.TextData)); + fm_memset(pstRDSData->PS_Data.PS, '\0', sizeof(pstRDSData->PS_Data.PS)); + fm_memset(pstRDSData->PS_ON, 0x20, sizeof(pstRDSData->PS_ON)); +} + +bool mt6630_RDS_OnOff(struct rds_t *dst, bool bFlag) +{ + signed int ret = 0; + + if (mt6630_RDS_support() == false) { + WCN_DBG(FM_ALT | RDSC, "mt6630_RDS_OnOff failed, RDS not support\n"); + return false; + } + + if (bFlag) { + mt6630_RDS_Init_Data(dst); + ret = mt6630_RDS_enable(); + if (ret) { + WCN_DBG(FM_NTC | RDSC, "mt6630_RDS_OnOff enable failed\n"); + return false; + } + } else { + ret = mt6630_RDS_disable(); + if (ret) { + WCN_DBG(FM_NTC | RDSC, "mt6630_RDS_OnOff disable failed\n"); + return false; + } + } + + return true; +} + +DEFINE_RDSLOG(mt6630_rds_log); + +/* mt6630_RDS_Efm_s32_Handler - response FM RDS interrupt + * @fm - main data structure of FM driver + * This function first get RDS raw data, then call RDS spec parser + */ +static signed int mt6630_rds_parser(struct rds_t *rds_dst, struct rds_rx_t *rds_raw, + signed int rds_size, unsigned short(*getfreq) (void)) +{ + mt6630_rds_log.log_in(&mt6630_rds_log, rds_raw, rds_size); + return rds_parser(rds_dst, rds_raw, rds_size, getfreq); +} + +static signed int mt6630_rds_log_get(struct rds_rx_t *dst, signed int *dst_len) +{ + return mt6630_rds_log.log_out(&mt6630_rds_log, dst, dst_len); +} + +static signed int mt6630_rds_gc_get(struct rds_group_cnt_t *dst, struct rds_t *rdsp) +{ + return rds_grp_counter_get(dst, &rdsp->gc); +} + +static signed int mt6630_rds_gc_reset(struct rds_t *rdsp) +{ + return rds_grp_counter_reset(&rdsp->gc); +} + +signed int fm_rds_ops_register(struct fm_basic_interface *bi, struct fm_rds_interface *ri) +{ + signed int ret = 0; + + if (ri == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,ri invalid pointer\n", __func__); + return -FM_EPARA; + } + if (bi->rds_tx_adapter == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,bi->rds_tx_adapter invalid pointer\n", __func__); + return -FM_EPARA; + } + fm_bi = bi; + + ri->rds_blercheck = mt6630_RDS_BlerCheck; + ri->rds_onoff = mt6630_RDS_OnOff; + ri->rds_parser = mt6630_rds_parser; + ri->rds_gbc_get = mt6630_RDS_Get_GoodBlock_Counter; + ri->rds_bbc_get = mt6630_RDS_Get_BadBlock_Counter; + ri->rds_bbr_get = mt6630_RDS_Get_BadBlock_Ratio; + ri->rds_bc_reset = mt6630_RDS_BlockCounter_Reset; + ri->rds_bci_get = mt6630_RDS_Get_BlerCheck_Interval; + ri->rds_log_get = mt6630_rds_log_get; + ri->rds_gc_get = mt6630_rds_gc_get; + ri->rds_gc_reset = mt6630_rds_gc_reset; + ri->rdstx_support = mt6630_rdsTx_Support; + ri->rds_tx_enable = mt6630_Rds_Tx_Enable; + ri->rds_tx_disable = mt6630_Rds_Tx_Disable; + ri->rds_tx = mt6630_Rds_Tx; + + return ret; +} + +signed int fm_rds_ops_unregister(struct fm_rds_interface *ri) +{ + signed int ret = 0; + + if (ri == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,ri invalid pointer\n", __func__); + return -FM_EPARA; + } + + fm_bi = NULL; + fm_memset(ri, 0, sizeof(struct fm_rds_interface)); + return ret; +} + diff --git a/drivers/misc/mediatek/connectivity/fmradio/chips/mt6631/inc/mt6631_fm_lib.h b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6631/inc/mt6631_fm_lib.h new file mode 100644 index 0000000000000000000000000000000000000000..57356b4cdd5bcfa3758208659c39614e0f3871bc --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6631/inc/mt6631_fm_lib.h @@ -0,0 +1,73 @@ +/* +* Copyright (C) 2016 MediaTek Inc. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. +*/ +#ifndef __MT6631_FM_LIB_H__ +#define __MT6631_FM_LIB_H__ + +#include "fm_typedef.h" + +enum { + DSPPATCH = 0xFFF9, + USDELAY = 0xFFFA, + MSDELAY = 0xFFFB, + HW_VER = 0xFFFD, + POLL_N = 0xFFFE, /* poling check if bit(n) is '0' */ + POLL_P = 0xFFFF, /* polling check if bit(n) is '1' */ +}; + +enum { + FM_PUS_DSPPATCH = DSPPATCH, + FM_PUS_USDELAY = USDELAY, + FM_PUS_MSDELAY = MSDELAY, + FM_PUS_HW_VER = HW_VER, + FM_PUS_POLL_N = POLL_N, /* poling check if bit(n) is '0' */ + FM_PUS_POLL_P = POLL_P, /* polling check if bit(n) is '1' */ + FM_PUS_MAX +}; + +enum { + mt6631_E1 = 0, + mt6631_E2 +}; + +struct mt6631_fm_cqi { + unsigned short ch; + unsigned short rssi; + unsigned short reserve; +}; + +struct adapt_fm_cqi { + signed int ch; + signed int rssi; + signed int reserve; +}; + +struct mt6631_full_cqi { + unsigned short ch; + unsigned short rssi; + unsigned short pamd; + unsigned short pr; + unsigned short fpamd; + unsigned short mr; + unsigned short atdc; + unsigned short prx; + unsigned short atdev; + unsigned short smg; /* soft-mute gain */ + unsigned short drssi; /* delta rssi */ +}; + +signed int mt6631_fm_low_ops_register(struct fm_callback *cb, struct fm_basic_interface *bi); +signed int mt6631_fm_low_ops_unregister(struct fm_basic_interface *bi); +signed int mt6631_fm_rds_ops_register(struct fm_basic_interface *bi, struct fm_rds_interface *ri); +signed int mt6631_fm_rds_ops_unregister(struct fm_rds_interface *ri); + +#endif diff --git a/drivers/misc/mediatek/connectivity/fmradio/chips/mt6631/inc/mt6631_fm_reg.h b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6631/inc/mt6631_fm_reg.h new file mode 100644 index 0000000000000000000000000000000000000000..d4ff954759f6594309fb01b31010745201536cc1 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6631/inc/mt6631_fm_reg.h @@ -0,0 +1,57 @@ +/* +* Copyright (C) 2016 MediaTek Inc. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. +*/ +#ifndef __MT6631_FM_REG_H__ +#define __MT6631_FM_REG_H__ + +/* RDS_BDGRP_ABD_CTRL_REG */ +enum { + BDGRP_ABD_EN = 0x0001, + BER_RUN = 0x2000 +}; +#define FM_DAC_CON1 0x83 +#define FM_DAC_CON2 0x84 +#define FM_FT_CON0 0x86 +enum { + FT_EN = 0x0001 +}; + +#define FM_I2S_CON0 0x90 +enum { + I2S_EN = 0x0001, + FORMAT = 0x0002, + WLEN = 0x0004, + I2S_SRC = 0x0008 +}; + +/* FM_MAIN_CTRL */ +enum { + TUNE = 0x0001, + SEEK = 0x0002, + SCAN = 0x0004, + CQI_READ = 0x0008, + RDS_MASK = 0x0010, + MUTE = 0x0020, + RDS_BRST = 0x0040, + RAMP_DOWN = 0x0100, +}; + +enum { + ANTENNA_TYPE = 0x0010, /* 0x61 D4, 0:long, 1:short */ + ANALOG_I2S = 0x0080, /* 0x61 D7, 0:lineout, 1:I2S */ + DE_EMPHASIS = 0x1000, /* 0x61 D12,0:50us, 1:75 us */ +}; + +#define OSC_FREQ_BITS 0x0070 /* 0x60 bit4~6 */ +#define OSC_FREQ_MASK (~OSC_FREQ_BITS) + +#endif /* __MT6631_FM_REG_H__ */ diff --git a/drivers/misc/mediatek/connectivity/fmradio/chips/mt6631/pub/mt6631_fm_lib.c b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6631/pub/mt6631_fm_lib.c new file mode 100644 index 0000000000000000000000000000000000000000..ff0f1ff1e079f292ccc1267dd06f76ea1a5069bb --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6631/pub/mt6631_fm_lib.c @@ -0,0 +1,2293 @@ +/* +* Copyright (C) 2016 MediaTek Inc. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. +*/ +#include +#include + +#include "osal_typedef.h" +#include "stp_exp.h" +#include "wmt_exp.h" +#include "plat.h" + +#include "fm_typedef.h" +#include "fm_dbg.h" +#include "fm_err.h" +#include "fm_interface.h" +#include "fm_stdlib.h" +#include "fm_patch.h" +#include "fm_utils.h" +#include "fm_link.h" +#include "fm_config.h" +#include "fm_cmd.h" + +#include "mt6631_fm_reg.h" +#include "mt6631_fm_lib.h" + +#define HQA_RETURN_ZERO_MAP 0 +#define HQA_ZERO_DESENSE_MAP 0 + +/* #include "mach/mt_gpio.h" */ + +/* #define MT6631_FM_PATCH_PATH "/etc/firmware/mt6631/mt6631_fm_patch.bin" */ +/* #define MT6631_FM_COEFF_PATH "/etc/firmware/mt6631/mt6631_fm_coeff.bin" */ +/* #define MT6631_FM_HWCOEFF_PATH "/etc/firmware/mt6631/mt6631_fm_hwcoeff.bin" */ +/* #define MT6631_FM_ROM_PATH "/etc/firmware/mt6631/mt6631_fm_rom.bin" */ + +static struct fm_patch_tbl mt6631_patch_tbl[5] = { + {FM_ROM_V1, "mt6631_fm_v1_patch.bin", "mt6631_fm_v1_coeff.bin", NULL, NULL}, + {FM_ROM_V2, "mt6631_fm_v2_patch.bin", "mt6631_fm_v2_coeff.bin", NULL, NULL}, + {FM_ROM_V3, "mt6631_fm_v3_patch.bin", "mt6631_fm_v3_coeff.bin", NULL, NULL}, + {FM_ROM_V4, "mt6631_fm_v4_patch.bin", "mt6631_fm_v4_coeff.bin", NULL, NULL}, + {FM_ROM_V5, "mt6631_fm_v5_patch.bin", "mt6631_fm_v5_coeff.bin", NULL, NULL} +}; + +static struct fm_hw_info mt6631_hw_info = { + .chip_id = 0x00006631, + .eco_ver = 0x00000000, + .rom_ver = 0x00000000, + .patch_ver = 0x00000000, + .reserve = 0x00000000, +}; + + +static struct fm_callback *fm_cb_op; + +/* static signed int Chip_Version = mt6631_E1; */ + +/* static bool rssi_th_set = false; */ + +#if 0 /* def CONFIG_MTK_FM_50KHZ_SUPPORT */ +static struct fm_fifo *cqi_fifo; +#endif +static signed int mt6631_is_dese_chan(unsigned short freq); + +#if 0 +static signed int mt6631_mcu_dese(unsigned short freq, void *arg); +static signed int mt6631_gps_dese(unsigned short freq, void *arg); +static signed int mt6631_I2s_Setting(signed int onoff, signed int mode, signed int sample); +#endif +static unsigned short mt6631_chan_para_get(unsigned short freq); +static signed int mt6631_desense_check(unsigned short freq, signed int rssi); +static bool mt6631_TDD_chan_check(unsigned short freq); +static bool mt6631_SPI_hopping_check(unsigned short freq); +static signed int mt6631_soft_mute_tune(unsigned short freq, signed int *rssi, signed int *valid); + +static bool mt6631_do_SPI_hopping_26M(void) +{ + struct fm_ext_interface *ei = &fm_wcn_ops.ei; + signed int hwid = ei->get_hw_version(); + signed int ret = 0; + unsigned int tem = 0, hw_ver_id = 0; + + /* switch SPI clock to 26MHz */ + if (ei->spi_clock_switch) + ret = ei->spi_clock_switch(FM_SPI_SPEED_26M); + else { + ret = -1; + WCN_DBG(FM_ERR | CHIP, "Clock switch cb is null\n"); + } + if (ret) + WCN_DBG(FM_ERR | CHIP, "Switch SPI clock to 26MHz failed\n"); + + ret = fm_host_reg_read(0x80021010, &hw_ver_id); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: read HW ver. failed\n", __func__); + hw_ver_id = hw_ver_id >> 16; + + /* unlock 64M */ + if (hwid >= FM_CONNAC_1_2) { + if (hw_ver_id == 0x1005 || hw_ver_id == 0x1002) { + ret = fm_host_reg_read(0x80023008, &tem); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: unlock 64M reg 0x880023008 failed\n", __func__); + ret = fm_host_reg_write(0x80023008, tem & (~(0x1 << 21))); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: unlock 64M failed\n", __func__); + } else { + ret = fm_host_reg_read(0x81021128, &tem); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: unlock 64M reg 0x81021128 failed\n", __func__); + ret = fm_host_reg_write(0x81021128, tem & ~0x1); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: unlock 64M failed\n", __func__); + ret = fm_host_reg_read(0x81024040, &tem); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: unlock 64M reg 0x81024040 failed\n", __func__); + ret = fm_host_reg_write(0x81024040, tem & ~0x3); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: unlock 64M failed\n", __func__); + } + } else { + ret = fm_host_reg_read(0x80026000, &tem); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: unlock 64M reg 0x80026000 failed\n", __func__); + ret = fm_host_reg_write(0x80026000, tem & (~(0x1 << 28))); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: unlock 64M failed\n", __func__); + } + + if (hwid <= FM_CONNAC_1_2) { + /* Rlease TOP2/64M sleep */ + fm_host_reg_read(0x81021138, &tem); /* Set 0x81021138[7] = 0x0 */ + tem = tem & 0xFFFFFF7F; + ret = fm_host_reg_write(0x81021138, tem); + if (ret) { + WCN_DBG(FM_ALT | CHIP, "Rlease TOP2/64M sleep failed\n"); + return ret; + } + WCN_DBG(FM_DBG | CHIP, "Rlease TOP2/64M sleep\n"); + } + + return ret == 0; +} + +static bool mt6631_do_SPI_hopping_64M(unsigned short freq) +{ + struct fm_ext_interface *ei = &fm_wcn_ops.ei; + signed int hwid = ei->get_hw_version(); + signed int ret = 0; + signed int i = 0; + unsigned int tem = 0, hw_ver_id = 0; + bool flag_spi_hopping = false; + + if (!mt6631_SPI_hopping_check(freq)) + return true; + + /* SPI hopping setting*/ + WCN_DBG(FM_NTC | CHIP, + "%s: freq:%d is SPI hopping channel,turn on 64M PLL\n", + __func__, freq); + + ret = fm_host_reg_read(0x80021010, &hw_ver_id); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: read HW ver. failed\n", __func__); + WCN_DBG(FM_NTC | CHIP, "%s: HW ver. ID = 0x%08x\n", __func__, hw_ver_id); + hw_ver_id = hw_ver_id >> 16; + + if (hwid <= FM_CONNAC_1_2) { + /*Disable TOP2/64M sleep*/ + ret = fm_host_reg_read(0x81021138, &tem); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: read 64M reg 0x81021138 failed\n", __func__); + tem |= 0x00000080; + ret = fm_host_reg_write(0x81021138, tem); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: disable 64M sleep failed\n", __func__); + } + /* lock 64M */ + if (hwid >= FM_CONNAC_1_2) { + if (hw_ver_id == 0x1005 || hw_ver_id == 0x1002) { + ret = fm_host_reg_read(0x80023008, &tem); + if (ret) + WCN_DBG(FM_ERR | CHIP, + "%s: lock 64M reg 0x80023008 failed\n", __func__); + ret = fm_host_reg_write(0x80023008, tem | (0x1 << 21)); + if (ret) + WCN_DBG(FM_ERR | CHIP, + "%s: lock 64M failed\n", __func__); + } else { + ret = fm_host_reg_read(0x81021128, &tem); + if (ret) + WCN_DBG(FM_ERR | CHIP, + "%s: read reg 0x81021128 failed\n", __func__); + ret = fm_host_reg_write(0x81021128, tem | 0x1); + if (ret) + WCN_DBG(FM_ERR | CHIP, + "%s: enable 'rf_spi_div_en' failed\n", __func__); + ret = fm_host_reg_read(0x81024040, &tem); + if (ret) + WCN_DBG(FM_ERR | CHIP, + "%s: lock 64M reg 0x81024040 failed\n", __func__); + ret = fm_host_reg_write(0x81024040, tem | 0x3); + if (ret) + WCN_DBG(FM_ERR | CHIP, + "%s: lock 64M failed\n", __func__); + } + } else { + ret = fm_host_reg_read(0x80026000, &tem); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: lock 64M reg 0x80026000 failed\n", __func__); + ret = fm_host_reg_write(0x80026000, tem | (0x1 << 28)); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: lock 64M failed\n", __func__); + } + + for (i = 0; i < 100; i++) { /*rd 0x8002110C until D27 ==1*/ + + if (hwid >= FM_CONNAC_1_2) + fm_host_reg_read(0x80021118, &tem); + else + fm_host_reg_read(0x8002110C, &tem); + + if (tem & 0x08000000) { + WCN_DBG(FM_NTC | CHIP, "%s: POLLING PLL_RDY success !\n", __func__); + if (ei->spi_clock_switch) + flag_spi_hopping = ei->spi_clock_switch(FM_SPI_SPEED_64M) == 0; + break; + } + fm_delayus(10); + } + if (false == flag_spi_hopping) + WCN_DBG(FM_ERR | CHIP, + "%s: Polling to read rd 0x8002110C[27] ==0x1 failed !\n", + __func__); + + return flag_spi_hopping; +} + +static signed int mt6631_pwron(signed int data) +{ + if (mtk_wcn_wmt_func_on(WMTDRV_TYPE_FM) == MTK_WCN_BOOL_FALSE) { + WCN_DBG(FM_ERR | CHIP, "WMT turn on FM Fail!\n"); + return -FM_ELINK; + } + + WCN_DBG(FM_NTC | CHIP, "WMT turn on FM OK!\n"); + return 0; +} + +static signed int mt6631_pwroff(signed int data) +{ + if (mtk_wcn_wmt_func_off(WMTDRV_TYPE_FM) == MTK_WCN_BOOL_FALSE) { + WCN_DBG(FM_ERR | CHIP, "WMT turn off FM Fail!\n"); + return -FM_ELINK; + } + + WCN_DBG(FM_NTC | CHIP, "WMT turn off FM OK!\n"); + return 0; +} + +static unsigned short mt6631_get_chipid(void) +{ + return 0x6631; +} + +/* MT6631_SetAntennaType - set Antenna type + * @type - 1, Short Antenna; 0, Long Antenna + */ +static signed int mt6631_SetAntennaType(signed int type) +{ + unsigned short dataRead = 0; + + WCN_DBG(FM_DBG | CHIP, "set ana to %s\n", type ? "short" : "long"); + fm_reg_read(FM_MAIN_CG2_CTRL, &dataRead); + + if (type) + dataRead |= ANTENNA_TYPE; + else + dataRead &= (~ANTENNA_TYPE); + + fm_reg_write(FM_MAIN_CG2_CTRL, dataRead); + + return 0; +} + +static signed int mt6631_GetAntennaType(void) +{ + unsigned short dataRead = 0; + + fm_reg_read(FM_MAIN_CG2_CTRL, &dataRead); + WCN_DBG(FM_DBG | CHIP, "get ana type: %s\n", (dataRead & ANTENNA_TYPE) ? "short" : "long"); + + if (dataRead & ANTENNA_TYPE) + return FM_ANA_SHORT; /* short antenna */ + else + return FM_ANA_LONG; /* long antenna */ +} + +static signed int mt6631_Mute(bool mute) +{ + signed int ret = 0; + unsigned short dataRead = 0; + + WCN_DBG(FM_DBG | CHIP, "set %s\n", mute ? "mute" : "unmute"); + /* fm_reg_read(FM_MAIN_CTRL, &dataRead); */ + fm_reg_read(0x9C, &dataRead); + + /* fm_top_reg_write(0x0050, 0x00000007); */ + if (mute == 1) + ret = fm_reg_write(0x9C, (dataRead & 0xFFFC) | 0x0003); + else + ret = fm_reg_write(0x9C, (dataRead & 0xFFFC)); + + /* fm_top_reg_write(0x0050, 0x0000000F); */ + + return ret; +} + +static signed int mt6631_rampdown_reg_op(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 4; + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + /* Clear DSP state */ + pkt_size += fm_bop_modify(FM_MAIN_CTRL, 0xFFF0, 0x0000, &buf[pkt_size], buf_size - pkt_size); + /* Set DSP ramp down state */ + pkt_size += fm_bop_modify(FM_MAIN_CTRL, 0xFFFF, RAMP_DOWN, &buf[pkt_size], buf_size - pkt_size); + /* @Wait for STC_DONE interrupt@ */ + pkt_size += fm_bop_rd_until(FM_MAIN_INTR, FM_INTR_STC_DONE, FM_INTR_STC_DONE, &buf[pkt_size], + buf_size - pkt_size); + /* Clear DSP ramp down state */ + pkt_size += fm_bop_modify(FM_MAIN_CTRL, (~RAMP_DOWN), 0x0000, &buf[pkt_size], buf_size - pkt_size); + /* Write 1 clear the STC_DONE interrupt status flag */ + pkt_size += fm_bop_modify(FM_MAIN_INTR, 0xFFFF, FM_INTR_STC_DONE, &buf[pkt_size], buf_size - pkt_size); + + return pkt_size - 4; +} + +void mt8168_spi_hopping_clock_switch(bool clk_64M) +{ + signed int ret = 0; + unsigned int reg_val = 0; + bool flag_spi_hopping = false; + unsigned int i = 0; + + if (clk_64M == true) { + /*Disable TOP2/64M sleep*/ + ret = fm_host_reg_read(0x81021138, ®_val); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: read 64M reg 0x81021138 failed\n", __func__); + reg_val |= (0x1 << 7); + ret = fm_host_reg_write(0x81021138, reg_val); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: disable 64M sleep failed\n", __func__); + + /* lock 64M */ + ret = fm_host_reg_read(0x80023008, ®_val); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: lock 64M reg 0x80023008 failed\n", __func__); + ret = fm_host_reg_write(0x80023008, reg_val | (0x1 << 21)); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: lock 64M failed\n", __func__); + + for (i = 0; i < 100; i++) { /*rd 0x80021118 until D27 ==1*/ + + ret = fm_host_reg_read(0x80021118, ®_val); + + if (reg_val & 0x08000000) { + flag_spi_hopping = true; + WCN_DBG(FM_NTC | CHIP, "%s: POLLING PLL_RDY success !\n", __func__); + /* switch SPI clock to 64MHz */ + ret = fm_host_reg_read(0x81026004, ®_val); /* wr 0x81026004[0] 0x1 D0 */ + reg_val |= 0x00000001; + ret = fm_host_reg_write(0x81026004, reg_val); + break; + } + fm_delayus(10); + } + if (false == flag_spi_hopping) + WCN_DBG(FM_ERR | CHIP, "%s: Polling to read rd 0x80021118[27] == 0x1 failed !\n", __func__); + + flag_spi_hopping = false; + for (i = 0; i < 100; i++) { /*rd 0x8002110C until D27 ==1*/ + ret = fm_host_reg_read(0x81026004, ®_val); + if ((reg_val & 0x00000018) == 0x00000010) { + flag_spi_hopping = true; + WCN_DBG(FM_NTC | CHIP, "%s: POLLING switch command success !\n", __func__); + /* switch SPI clock to 64MHz */ + ret = fm_host_reg_read(0x81026004, ®_val); /* wr 0x81026004[0] 0x1 D0 */ + reg_val |= 0x00000004; + ret = fm_host_reg_write(0x81026004, reg_val); + break; + } + fm_delayus(10); + } + if (false == flag_spi_hopping) + WCN_DBG(FM_ERR | CHIP, "%s: Polling to read rd 0x80021118[4:3] == 0x2 failed !\n", __func__); + } else { + /*set next_cap_en*/ + ret = fm_host_reg_read(0x81026004, ®_val); /* wr 0x81026004[2] 0x0 D0 */ + reg_val &= 0xFFFFFFFB; + ret = fm_host_reg_write(0x81026004, reg_val); + + /*switch back to 26M*/ + ret = fm_host_reg_read(0x81026004, ®_val); /* wr 0x81026004[0] 0x0 D0 */ + reg_val &= 0xFFFFFFFE; + ret = fm_host_reg_write(0x81026004, reg_val); + + flag_spi_hopping = false; + for (i = 0; i < 100; i++) { + ret = fm_host_reg_read(0x81026004, ®_val); + if ((reg_val & 0x00000018) == 0x8) { + flag_spi_hopping = true; + WCN_DBG(FM_NTC | CHIP, "%s: POLLING switch command success !\n", __func__); + + /* turn off 64M PLL request */ + ret = fm_host_reg_read(0x80023008, ®_val); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: turn off 0x80023008 failed\n", __func__); + ret = fm_host_reg_write(0x80023008, reg_val & (~(0x1 << 21))); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: lock 64M failed\n", __func__); + break; + } + fm_delayus(10); + } + if (false == flag_spi_hopping) + WCN_DBG(FM_ERR | CHIP, "%s: Polling to read rd 0x80021118[4:3] == 0x2 failed !\n", __func__); + + ret = fm_host_reg_read(0x81021138, ®_val); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: read 64M reg 0x81021138 failed\n", __func__); + reg_val &= ~(0x1 << 7); + ret = fm_host_reg_write(0x81021138, reg_val); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: enable 64M sleep failed\n", __func__); + } +} + +/* + * mt6631_rampdown - f/w will wait for STC_DONE interrupt + * @buf - target buf + * @buf_size - buffer size + * return package size + */ +static signed int mt6631_rampdown(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 0; + + pkt_size = mt6631_rampdown_reg_op(buf, buf_size); + return fm_op_seq_combine_cmd(buf, FM_RAMPDOWN_OPCODE, pkt_size); +} + +/* FMSYS Ramp Down Sequence*/ +static signed int mt6631_RampDown(void) +{ + signed int ret = 0; + unsigned short pkt_size; + signed int projectid = fm_cb_op->projectid_get(); + /* unsigned short tmp; */ + + WCN_DBG(FM_DBG | CHIP, "ramp down\n"); + + /* unlock 64M */ + if (projectid == 0x8168) + mt8168_spi_hopping_clock_switch(false); + else + mt6631_do_SPI_hopping_26M(); + + /* A0.0 Host control RF register */ + ret = fm_set_bits(0x60, 0x0007, 0xFFF0); /*Set 0x60 [D3:D0] = 0x7*/ + if (ret) { + WCN_DBG(FM_ERR | CHIP, "ramp down HOST control rf: Set 0x60 [D3:D0] = 0x7 failed\n"); + return ret; + } + + /* A0.1 Update FM ADPLL fast tracking mode gain */ + ret = fm_set_bits(0x0F, 0x0000, 0xF800); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "ramp down ADPLL gainA/B: Set 0xFH [D10:D0] = 0x000 failed\n"); + return ret; + } + + /* A0.2 Host control RF register */ + ret = fm_set_bits(0x60, 0x000F, 0xFFF0); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "ramp down Host control RF registerwr top 0x60 failed\n"); + return ret; + } + /*Clear dsp state*/ + ret = fm_set_bits(0x63, 0x0000, 0xFFF0); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "ramp down Host control RF registerwr top 0x63 failed\n"); + return ret; + } + /* Set DSP ramp down state*/ + ret = fm_set_bits(0x63, 0x0010, 0xFFEF); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "ramp down Host control RF registerwr top 0x63 failed\n"); + return ret; + } + + ret = fm_reg_write(FM_MAIN_INTRMASK, 0x0000); + if (ret) + WCN_DBG(FM_ERR | CHIP, "ramp down clean FM_MAIN_INTRMASK failed\n"); + + ret = fm_reg_write(FM_MAIN_EXTINTRMASK, 0x0000); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "ramp down clean FM_MAIN_EXTINTRMASK failed\n"); + return ret; + } + + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = mt6631_rampdown(cmd_buf, TX_BUF_SIZE); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_RAMPDOWN, SW_RETRY_CNT, RAMPDOWN_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + + if (ret) { + WCN_DBG(FM_ERR | CHIP, "ramp down failed\n"); + return ret; + } + + ret = fm_reg_write(FM_MAIN_EXTINTRMASK, 0x0021); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "ramp down wr FM_MAIN_EXTINTRMASK failed\n"); + return ret; + } + + ret = fm_reg_write(FM_MAIN_INTRMASK, 0x0021); + if (ret) + WCN_DBG(FM_ERR | CHIP, "ramp down wr FM_MAIN_INTRMASK failed\n"); + +#if 0 + fm_delayms(1); + WCN_DBG(FM_DBG | CHIP, "ramp down delay 1ms\n"); + + /* A1.1. Disable aon_osc_clk_cg */ + ret = fm_host_reg_write(0x81024064, 0x00000004); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " Disable aon_osc_clk_cg failed\n"); + return ret; + } + /* A1.1. Disable FMAUD trigger */ + ret = fm_host_reg_write(0x81024058, 0x88800000); + if (ret) { + WCN_DBG(FM_ALT | CHIP, "Disable FMAUD trigger failed\n"); + return ret; + } + + /* A1.1. issue fmsys memory powr down */ + ret = fm_host_reg_write(0x81024054, 0x00000180); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " Issue fmsys memory powr down failed\n"); + return ret; + } +#endif + + return ret; +} + +static signed int mt6631_get_rom_version(void) +{ + unsigned short flag_Romcode = 0; + unsigned short nRomVersion = 0; +#define ROM_CODE_READY 0x0001 + signed int ret = 0; + + /* A1.1 DSP rom code version request enable --- set 0x61 b15=1 */ + fm_set_bits(0x61, 0x8000, 0x7FFF); + + /* A1.2 Release ASIP reset --- set 0x61 b1=1 */ + fm_set_bits(0x61, 0x0002, 0xFFFD); + + /* A1.3 Enable ASIP power --- set 0x61 b0=0 */ + fm_set_bits(0x61, 0x0000, 0xFFFE); + + /* A1.4 Wait until DSP code version ready --- wait loop 1ms */ + do { + fm_delayus(1000); + ret = fm_reg_read(0x84, &flag_Romcode); + /* ret=-4 means signal got when control FM. usually get sig 9 to kill FM process. */ + /* now cancel FM power up sequence is recommended. */ + if (ret) + return ret; + + WCN_DBG(FM_DBG | CHIP, "ROM_CODE_READY flag 0x84=%x\n", flag_Romcode); + } while (flag_Romcode != ROM_CODE_READY); + + + /* A1.5 Read FM DSP code version --- rd 0x83[15:8] */ + fm_reg_read(0x83, &nRomVersion); + nRomVersion = (nRomVersion >> 8); + + /* A1.6 DSP rom code version request disable --- set 0x61 b15=0 */ + fm_set_bits(0x61, 0x0000, 0x7FFF); + + /* A1.7 Reset ASIP --- set 0x61[1:0] = 1 */ + fm_set_bits(0x61, 0x0001, 0xFFFC); + + return (signed int) nRomVersion; +} + +static signed int mt6631_pwrup_clock_on_reg_op(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 4; + unsigned short de_emphasis; + signed int hwid = fm_wcn_ops.ei.get_hw_version(); + /* unsigned short osc_freq; */ + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + de_emphasis = fm_config.rx_cfg.deemphasis; + de_emphasis &= 0x0001; /* rang 0~1 */ + /* 2,turn on top clock */ + pkt_size += fm_bop_top_write(0xA10, 0xFFFFFFFF, &buf[pkt_size], buf_size - pkt_size); + /* wr top cr a10 ffffffff */ + + /* 3,enable MTCMOS */ + pkt_size += fm_bop_top_write(0x60, 0x00000030, &buf[pkt_size], buf_size - pkt_size); + /* wr top 60 30 */ + + pkt_size += fm_bop_top_write(0x60, 0x00000035, &buf[pkt_size], buf_size - pkt_size); + /* wr top 60 35 */ + pkt_size += fm_bop_udelay(10, &buf[pkt_size], buf_size - pkt_size); + /* delay 10us */ + pkt_size += fm_bop_top_write(0x60, 0x00000015, &buf[pkt_size], buf_size - pkt_size); + /* wr top 60 15 */ + pkt_size += fm_bop_top_write(0x60, 0x00000005, &buf[pkt_size], buf_size - pkt_size); + /* wr top 60 5 */ + + pkt_size += fm_bop_udelay(10, &buf[pkt_size], buf_size - pkt_size); + /* delay 10us */ + pkt_size += fm_bop_top_write(0x60, 0x00000045, &buf[pkt_size], buf_size - pkt_size); + /* wr top 60 45 */ + + /* 4,set comspi fm slave dumy count */ + if (hwid >= FM_CONNAC_1_5) + pkt_size += fm_bop_write(0x7f, 0x801f, &buf[pkt_size], buf_size - pkt_size); /* wr 7f 801f */ + else + pkt_size += fm_bop_write(0x7f, 0x800f, &buf[pkt_size], buf_size - pkt_size); /* wr 7f 800f */ + + /* A. FM digital clock enable */ + /* A1. Enable digital OSC */ + if (hwid <= FM_CONNAC_1_2) + pkt_size += fm_bop_write(0x60, 0x00000001, &buf[pkt_size], buf_size - pkt_size); /* wr 60 1 */ + + /* A2. Wait 3ms */ + pkt_size += fm_bop_udelay(3000, &buf[pkt_size], buf_size - pkt_size); + + /* A3. Set OSC clock output to FM */ + if (hwid <= FM_CONNAC_1_2) + pkt_size += fm_bop_write(0x60, 0x00000003, &buf[pkt_size], buf_size - pkt_size); /* wr 60 3 */ + /* A4. Release HW clock gating*/ + pkt_size += fm_bop_write(0x60, 0x00000007, &buf[pkt_size], buf_size - pkt_size); /* wr 60 7 */ + /* Enable DSP auto clock gating */ + pkt_size += fm_bop_write(0x70, 0x0040, &buf[pkt_size], buf_size - pkt_size); /* wr 70 0040 */ + /* A7. Deemphasis setting: Set 0 for 50us, Set 1 for 75us */ + pkt_size += fm_bop_modify(0x61, ~DE_EMPHASIS, (de_emphasis << 12), &buf[pkt_size], buf_size - pkt_size); + + return pkt_size - 4; +} +/* + * mt6631_pwrup_clock_on - Wholechip FM Power Up: step 1, FM Digital Clock enable + * @buf - target buf + * @buf_size - buffer size + * return package size + */ +static signed int mt6631_pwrup_clock_on(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 0; + + pkt_size = mt6631_pwrup_clock_on_reg_op(buf, buf_size); + return fm_op_seq_combine_cmd(buf, FM_ENABLE_OPCODE, pkt_size); +} + +static signed int mt6631_pwrup_digital_init_reg_op(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 4; + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + /* Part D FM RF&ADPLL divider setting */ + + /* D2.1 set cell mode */ + /* wr 30 D3:D2 00:FDD(default),01:both.10: TDD, 11 FDD */ + /* pkt_size += fm_bop_modify(0x30, 0xFFF3, 0x0000, &buf[pkt_size], buf_size - pkt_size); */ + + /* D2.2 set ADPLL divider */ + pkt_size += fm_bop_write(0x21, 0xE000, &buf[pkt_size], buf_size - pkt_size); /* wr 21 E000 */ + /* D2.3 set SDM coeff0_H */ + pkt_size += fm_bop_write(0xD8, 0x03F0, &buf[pkt_size], buf_size - pkt_size); /* wr D8 0x03F0 */ + /* D2.4 set SDM coeff0_L */ + pkt_size += fm_bop_write(0xD9, 0x3F04, &buf[pkt_size], buf_size - pkt_size); /* wr D9 0x3F04 */ + /* D2.5 set SDM coeff1_H */ + pkt_size += fm_bop_write(0xDA, 0x0014, &buf[pkt_size], buf_size - pkt_size); /* wr DA 0x0014 */ + /* D2.6 set SDM coeff1_L */ + pkt_size += fm_bop_write(0xDB, 0x2A38, &buf[pkt_size], buf_size - pkt_size); /* wr DB 0x2A38 */ + /* D2.7 set 26M clock */ + pkt_size += fm_bop_write(0x23, 0x4000, &buf[pkt_size], buf_size - pkt_size); /* wr 23 4000 */ + + /* Part E: FM Digital Init: fm_rgf_maincon */ + + /* E4. Set appropriate interrupt mask behavior as desired */ + /* Enable stc_done_mask, Enable rgf_rds_mask*/ + pkt_size += fm_bop_write(0x6A, 0x0021, &buf[pkt_size], buf_size - pkt_size); /* wr 6A 0021 */ + pkt_size += fm_bop_write(0x6B, 0x0021, &buf[pkt_size], buf_size - pkt_size); /* wr 6B 0021 */ + + /* E5. Enable hw auto control */ + pkt_size += fm_bop_write(0x60, 0x0000000F, &buf[pkt_size], buf_size - pkt_size); /* wr 60 f */ + + /* E6. Release ASIP reset */ + pkt_size += fm_bop_modify(0x61, 0xFFFD, 0x0002, &buf[pkt_size], buf_size - pkt_size); /* wr 61 D1=1 */ + /* E7. Enable ASIP power */ + pkt_size += fm_bop_modify(0x61, 0xFFFE, 0x0000, &buf[pkt_size], buf_size - pkt_size); /* wr 61 D0=0 */ + + /* E8 */ + pkt_size += fm_bop_udelay(100000, &buf[pkt_size], buf_size - pkt_size); /* delay 100ms */ + /* E9. Check HW initial complete */ + pkt_size += fm_bop_rd_until(0x64, 0x001F, 0x0002, &buf[pkt_size], buf_size - pkt_size); /* Poll 64[0~4] = 2 */ + + return pkt_size - 4; +} + +/* + * mt6631_pwrup_digital_init - Wholechip FM Power Up: step 4, FM Digital Init: fm_rgf_maincon + * @buf - target buf + * @buf_size - buffer size + * return package size + */ +static signed int mt6631_pwrup_digital_init(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 0; + + pkt_size = mt6631_pwrup_digital_init_reg_op(buf, buf_size); + return fm_op_seq_combine_cmd(buf, FM_ENABLE_OPCODE, pkt_size); +} + +static signed int mt6631_pwrup_fine_tune_reg_op(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 4; + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + /* F1 set host control RF register */ + pkt_size += fm_bop_write(0x60, 0x00000007, &buf[pkt_size], buf_size - pkt_size); + /* F2 fine tune RF setting */ + pkt_size += fm_bop_write(0x01, 0xBEE8, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x03, 0xF6ED, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x15, 0x0D80, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x16, 0x0068, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x17, 0x092A, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x34, 0x807F, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x35, 0x311E, &buf[pkt_size], buf_size - pkt_size); + /* F3 set DSP control RF register */ + pkt_size += fm_bop_write(0x60, 0x0000000F, &buf[pkt_size], buf_size - pkt_size); + + return pkt_size - 4; +} + +/* + * mt6631_pwrup_fine_tune - Wholechip FM Power Up: step 5, FM RF fine tune setting + * @buf - target buf + * @buf_size - buffer size + * return package size + */ +static signed int mt6631_pwrup_fine_tune(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 0; + + pkt_size = mt6631_pwrup_fine_tune_reg_op(buf, buf_size); + return fm_op_seq_combine_cmd(buf, FM_ENABLE_OPCODE, pkt_size); +} + +static signed int mt6631_pwrdown_reg_op(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 4; + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + /* A1:set audio output I2S Tx mode: */ + pkt_size += fm_bop_modify(0x9B, 0xFFF8, 0x0000, &buf[pkt_size], buf_size - pkt_size); + + /* B0:Disable HW clock control */ + pkt_size += fm_bop_write(0x60, 0x330F, &buf[pkt_size], buf_size - pkt_size); + /* B1:Reset ASIP : Set 0x61, [D1 = 0, D0=1] */ + pkt_size += fm_bop_modify(0x61, 0xFFFD, 0x0001, &buf[pkt_size], buf_size - pkt_size); + + /* B2:digital core + digital rgf reset */ + pkt_size += fm_bop_modify(0x6E, 0xFFF8, 0x0000, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_modify(0x6E, 0xFFF8, 0x0000, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_modify(0x6E, 0xFFF8, 0x0000, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_modify(0x6E, 0xFFF8, 0x0000, &buf[pkt_size], buf_size - pkt_size); + + /* B3:Disable all clock */ + pkt_size += fm_bop_write(0x60, 0x0000, &buf[pkt_size], buf_size - pkt_size); + /* B4:Reset rgfrf */ + pkt_size += fm_bop_write(0x60, 0x4000, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x60, 0x0000, &buf[pkt_size], buf_size - pkt_size); + + /* MTCMOS power off */ + /* C0:disable MTCMOS */ + pkt_size += fm_bop_top_write(0x60, 0x0005, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_top_write(0x60, 0x0015, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_top_write(0x60, 0x0035, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_top_write(0x60, 0x0030, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_top_rd_until(0x60, 0x0000000A, 0x0, &buf[pkt_size], buf_size - pkt_size); + + return pkt_size - 4; +} +/* + * mt6631_pwrdown - Wholechip FM Power down: Digital Modem Power Down + * @buf - target buf + * @buf_size - buffer size + * return package size + */ +static signed int mt6631_pwrdown(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 0; + + pkt_size = mt6631_pwrdown_reg_op(buf, buf_size); + return fm_op_seq_combine_cmd(buf, FM_ENABLE_OPCODE, pkt_size); +} + +static signed int mt6631_tune_reg_op(unsigned char *buf, signed int buf_size, unsigned short freq, + unsigned short chan_para) +{ + signed int pkt_size = 4; + + WCN_DBG(FM_ALT | CHIP, "%s enter mt6631_tune function\n", __func__); + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + /* A2 Enable hardware controlled tuning sequence */ + pkt_size += fm_bop_modify(FM_MAIN_CTRL, 0xFFF8, TUNE, &buf[pkt_size], buf_size - pkt_size);/*Set 0x63 D0=1*/ + /* Wait for STC_DONE interrupt */ + +#ifdef FM_TUNE_USE_POLL + /* A3 Wait for STC_DONE interrupt */ + /* A4 Wait for STC_DONE interrupt status flag */ + pkt_size += fm_bop_rd_until(FM_MAIN_INTR, FM_INTR_STC_DONE, + FM_INTR_STC_DONE, &buf[pkt_size], buf_size - pkt_size); + /* A6 Write 1 clear the STC_DONE interrupt status flag */ + pkt_size += fm_bop_modify(FM_MAIN_INTR, 0xFFFF, FM_INTR_STC_DONE, &buf[pkt_size], buf_size - pkt_size); +#endif + + pkt_size += fm_bop_udelay(100000, &buf[pkt_size], buf_size - pkt_size); + WCN_DBG(FM_ALT | CHIP, "mt6631_tune delay 100 ms wait 0x69 to change\n"); + + WCN_DBG(FM_ALT | CHIP, "%s leave mt6631_tune function\n", __func__); + + return pkt_size - 4; +} + +/* + * mt6631_tune - execute tune action, + * @buf - target buf + * @buf_size - buffer size + * @freq - 760 ~ 1080, 100KHz unit + * return package size + */ +static signed int mt6631_tune(unsigned char *buf, signed int buf_size, unsigned short freq, + unsigned short chan_para) +{ + signed int pkt_size = 0; + + pkt_size = mt6631_tune_reg_op(buf, buf_size, freq, chan_para); + return fm_op_seq_combine_cmd(buf, FM_TUNE_OPCODE, pkt_size); +} + +/* + * mt6631_pwrup_DSP_download - execute dsp/coeff patch dl action, + * @patch_tbl - current chip patch table + * return patch dl ok or not + */ +static signed int mt6631_pwrup_DSP_download(struct fm_patch_tbl *patch_tbl) +{ +#define PATCH_BUF_SIZE (4096*6) + signed int ret = 0; + signed int patch_len = 0; + unsigned char *dsp_buf = NULL; + unsigned short tmp_reg = 0; + + mt6631_hw_info.eco_ver = (signed int) mtk_wcn_wmt_ic_info_get(1); + WCN_DBG(FM_DBG | CHIP, "ECO version:0x%08x\n", mt6631_hw_info.eco_ver); + + /* Wholechip FM Power Up: step 3, get mt6631 DSP ROM version */ + ret = mt6631_get_rom_version(); + if (ret >= 0) { + mt6631_hw_info.rom_ver = ret; + WCN_DBG(FM_NTC | CHIP, "%s ROM version: v%d\n", __func__, mt6631_hw_info.rom_ver); + } else { + WCN_DBG(FM_ERR | CHIP, "get ROM version failed\n"); + if (ret == -4) + WCN_DBG(FM_ERR | CHIP, "signal got when control FM, usually get sig 9 to kill FM process.\n"); + /* now cancel FM power up sequence is recommended. */ + goto out; + } + + /* Wholechip FM Power Up: step 4 download patch */ + dsp_buf = fm_vmalloc(PATCH_BUF_SIZE); + if (!dsp_buf) { + WCN_DBG(FM_ALT | CHIP, "-ENOMEM\n"); + return -ENOMEM; + } + + patch_len = fm_get_patch_path(mt6631_hw_info.rom_ver, dsp_buf, PATCH_BUF_SIZE, patch_tbl); + if (patch_len <= 0) { + WCN_DBG(FM_ALT | CHIP, " fm_get_patch_path failed\n"); + ret = patch_len; + goto out; + } + + ret = fm_download_patch((const unsigned char *)dsp_buf, patch_len, IMG_PATCH); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " DL DSPpatch failed\n"); + goto out; + } + + patch_len = fm_get_coeff_path(mt6631_hw_info.rom_ver, dsp_buf, PATCH_BUF_SIZE, patch_tbl); + if (patch_len <= 0) { + WCN_DBG(FM_ALT | CHIP, " fm_get_coeff_path failed\n"); + ret = patch_len; + goto out; + } + + mt6631_hw_info.rom_ver += 1; + + tmp_reg = dsp_buf[38] | (dsp_buf[39] << 8); /* to be confirmed */ + mt6631_hw_info.patch_ver = (signed int) tmp_reg; + WCN_DBG(FM_NTC | CHIP, "Patch version: 0x%08x\n", mt6631_hw_info.patch_ver); + + ret = fm_download_patch((const unsigned char *)dsp_buf, patch_len, IMG_COEFFICIENT); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " Download DSP coefficient failed\n"); + goto out; + } + + /* Download HWACC coefficient */ + fm_reg_write(0x92, 0x0000); + fm_reg_write(0x90, 0x0040); /* Reset download control */ + fm_reg_write(0x90, 0x0000); /* Disable memory control from host*/ +out: + if (dsp_buf) + fm_vfree(dsp_buf); + return ret; +} +static void mt6631_show_reg(void) +{ + unsigned int host_reg[3] = {0}; + unsigned int debug_reg1[3] = {0}; + unsigned short debug_reg2[3] = {0}; + + fm_host_reg_read(0x81024030, &host_reg[0]); + fm_host_reg_read(0x81021234, &host_reg[1]); + fm_host_reg_read(0x81021138, &host_reg[2]); + WCN_DBG(FM_ALT | CHIP, + "host read 0x81024030 = 0x%08x, 0x81021234 = 0x%08x, 0x81021138 = 0x%08x\n", + host_reg[0], host_reg[1], host_reg[2]); + + fm_top_reg_read(0x00c0, &debug_reg1[0]); + fm_top_reg_read(0x00c8, &debug_reg1[1]); + fm_top_reg_read(0x0060, &debug_reg1[2]); + fm_reg_read(0x7f, &debug_reg2[0]); + fm_reg_read(0x62, &debug_reg2[1]); + fm_reg_read(0x60, &debug_reg2[2]); + WCN_DBG(FM_ALT | CHIP, + "top cr 0xc0 = 0x%08x, 0xc8 = 0x%08x, 0x60 = 0x%08x, fmreg 0x7f = 0x%08x, 0x62 = 0x%08x, 0x60 = 0x%08x\n", + debug_reg1[0], debug_reg1[1], debug_reg1[2], debug_reg2[0], debug_reg2[1], debug_reg2[2]); +} + +static signed int mt6631_PowerUp(unsigned short *chip_id, unsigned short *device_id) +{ + signed int ret = 0; + unsigned short pkt_size; + unsigned short tmp_reg = 0; + unsigned int tem = 0; + unsigned int host_reg = 0; + signed int hwid = fm_wcn_ops.ei.get_hw_version(); + + if (chip_id == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (device_id == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + WCN_DBG(FM_DBG | CHIP, "pwr on seq......\n"); + + /* Wholechip FM Power Up: step 1, set common SPI parameter */ + if (hwid >= FM_CONNAC_1_5) + ret = fm_host_reg_write(0x8102600C, 0x0000801F); + else + ret = fm_host_reg_write(0x8102600C, 0x0000800F); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup set CSPI failed\n"); + return ret; + } + + if (hwid >= FM_CONNAC_1_0) { + /* Set top_clk_en_adie to trigger sleep controller before FM power on */ + if (hwid >= FM_CONNAC_1_5) { + ret = fm_host_reg_write(0x81021500, 0x00000003); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup set top_clk_en_adie failed\n"); + return ret; + } + } else { + fm_host_reg_read(0x81021500, &tem); /* Set 0x81021500[1] = 0x1 */ + tem = tem | 0x00000002; + fm_host_reg_write(0x81021500, tem); + } + + /* Disable 26M crystal sleep */ + fm_host_reg_read(0x81021200, &tem); /* Set 0x81021200[23] = 0x1 */ + tem = tem | 0x00800000; + fm_host_reg_write(0x81021200, tem); + } else { + /* Set top_clk_en_adie to trigger sleep controller before FM power on */ + fm_host_reg_read(0x81024030, &tem); /* Set 0x81024030[1] = 0x1 */ + tem = tem | 0x00000002; + fm_host_reg_write(0x81024030, tem); + + /* Disable 26M crystal sleep */ + fm_host_reg_read(0x81021234, &tem); /* Set 0x81021234[7] = 0x1 */ + tem = tem | 0x00000080; + fm_host_reg_write(0x81021234, tem); + } + + /* turn on RG_TOP_BGLDO */ + ret = fm_top_reg_read(0x00c0, &host_reg); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "power up read top 0xc0 failed\n"); + return ret; + } + ret = fm_top_reg_write(0x00c0, host_reg | (0x3 << 27)); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "power up write top 0xc0 failed\n"); + return ret; + } + + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + + pkt_size = mt6631_pwrup_clock_on(cmd_buf, TX_BUF_SIZE); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + + if (ret) { + WCN_DBG(FM_ALT | CHIP, "mt6631_pwrup_clock_on failed\n"); + return ret; + } + + /* Wholechip FM Power Up: step 2, read HW version */ + mt6631_show_reg(); + fm_reg_read(0x62, &tmp_reg); + /* chip_id = tmp_reg; */ + if (tmp_reg == 0x6631) + *chip_id = 0x6631; + *device_id = tmp_reg; + mt6631_hw_info.chip_id = (signed int) tmp_reg; + WCN_DBG(FM_DBG | CHIP, "chip_id:0x%04x\n", tmp_reg); + + if ((mt6631_hw_info.chip_id != 0x6631)) { + mt6631_show_reg(); + WCN_DBG(FM_NTC | CHIP, "fm sys error, reset hw, chip_id = 0x%08x\n", mt6631_hw_info.chip_id); + return -FM_EFW; + + } + /* Wholechip FM Power Up: step 3, patch download */ + ret = mt6631_pwrup_DSP_download(mt6631_patch_tbl); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "mt6631_pwrup_DSP_download failed\n"); + return ret; + } + + /* Wholechip FM Power Up: step 4, FM Digital Init: fm_rgf_maincon */ + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = mt6631_pwrup_digital_init(cmd_buf, TX_BUF_SIZE); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + if (ret) { + WCN_DBG(FM_ALT | CHIP, "mt6631_pwrup_digital_init failed\n"); + return ret; + } + + /* Wholechip FM Power Up: step 5, FM RF fine tune setting */ + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = mt6631_pwrup_fine_tune(cmd_buf, TX_BUF_SIZE); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + if (ret) { + WCN_DBG(FM_ALT | CHIP, "mt6631_pwrup_fine_tune failed\n"); + return ret; + } + + /* Enable connsys FM 2 wire RX */ + fm_reg_write(0x9B, 0xF9AB); /* G2: Set audio output i2s TX mode */ + fm_host_reg_write(0x81024064, 0x00000014); /* G3: Enable aon_osc_clk_cg */ + /* G4: Enable FMAUD trigger, 20170119 */ + if (hwid >= FM_CONNAC_1_5) + fm_host_reg_write(0x81024058, 0x888100C3); + else + fm_host_reg_write(0x81024058, 0x888100F3); + fm_host_reg_write(0x81024054, 0x00000100); /* G5: Release fmsys memory power down*/ + + WCN_DBG(FM_NTC | CHIP, "pwr on seq ok\n"); + + return ret; +} + +static signed int mt6631_PowerDown(void) +{ + signed int ret = 0; + unsigned int tem = 0; + unsigned short pkt_size; + signed int hwid = fm_wcn_ops.ei.get_hw_version(); + /* unsigned int host_reg = 0; */ + + WCN_DBG(FM_DBG | CHIP, "pwr down seq\n"); + + /* A0.1. Disable aon_osc_clk_cg */ + ret = fm_host_reg_write(0x81024064, 0x00000004); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " Disable aon_osc_clk_cg failed\n"); + return ret; + } + /* A0.1. Disable FMAUD trigger */ + ret = fm_host_reg_write(0x81024058, 0x88800000); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " Disable FMAUD trigger failed\n"); + return ret; + } + + /* A0.1. issue fmsys memory powr down */ + ret = fm_host_reg_write(0x81024054, 0x00000180); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " Issue fmsys memory powr down failed\n"); + return ret; + } + + mt6631_do_SPI_hopping_26M(); + + /* Enable 26M crystal sleep */ + if (hwid >= FM_CONNAC_1_0 && hwid <= FM_CONNAC_1_2) { + WCN_DBG(FM_DBG | CHIP, "PowerDown: Enable 26M crystal sleep,Set 0x81021200[23] = 0x0\n"); + fm_host_reg_read(0x81021200, &tem); /* Set 0x81021200[23] = 0x0 */ + tem = tem & 0xFF7FFFFF; + fm_host_reg_write(0x81021200, tem); + } else { + WCN_DBG(FM_DBG | CHIP, "PowerDown: Enable 26M crystal sleep,Set 0x81021234[7] = 0x0\n"); + fm_host_reg_read(0x81021234, &tem); /* Set 0x81021234[7] = 0x0 */ + tem = tem & 0xFFFFFF7F; + fm_host_reg_write(0x81021234, tem); + } + + if (ret) + WCN_DBG(FM_ALT | CHIP, "PowerDown: Enable 26M crystal sleep,Set 0x81021234[7] = 0x0 failed\n"); + + /* A0:set audio output I2X Rx mode: */ + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = mt6631_pwrdown(cmd_buf, TX_BUF_SIZE); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + + if (ret) { + WCN_DBG(FM_ALT | CHIP, "mt6631_pwrdown failed\n"); + return ret; + } + /* FIX_ME, disable ext interrupt */ + /* fm_reg_write(FM_MAIN_EXTINTRMASK, 0x00); */ + + + /* D0. Clear top_clk_en_adie to indicate sleep controller after FM power off */ + /* ret = fm_host_reg_read(0x80101030, &host_reg); + * if (ret) { + * WCN_DBG(FM_ALT | CHIP, " pwroff read 0x80100030 failed\n"); + * return ret; + * } + * ret = fm_host_reg_write(0x80101030, host_reg & (~(0x1 << 1))); + * if (ret) { + * WCN_DBG(FM_ALT | CHIP, " pwroff disable top_ck_en_adie failed\n"); + * return ret; + * } + */ + return ret; +} + +/* just for dgb */ +#if 0 +static void mt6631_bt_write(unsigned int addr, unsigned int val) +{ + unsigned int tem, i = 0; + + fm_host_reg_write(0x80103020, addr); + fm_host_reg_write(0x80103024, val); + fm_host_reg_read(0x80103000, &tem); + while ((tem == 4) && (i < 1000)) { + i++; + fm_host_reg_read(0x80103000, &tem); + } +} +#endif + +static bool mt6631_SetFreq(unsigned short freq) +{ + signed int ret = 0; + unsigned short pkt_size; + unsigned short chan_para = 0; + unsigned short freq_reg = 0; + unsigned short tmp_reg[6] = {0}; + signed int projectid = fm_cb_op->projectid_get(); + + fm_cb_op->cur_freq_set(freq); + +#if 0 + /* MCU clock adjust if need */ + ret = mt6631_mcu_dese(freq, NULL); + if (ret < 0) + WCN_DBG(FM_ERR | MAIN, "mt6631_mcu_dese FAIL:%d\n", ret); + + WCN_DBG(FM_INF | MAIN, "MCU %d\n", ret); + + /* GPS clock adjust if need */ + ret = mt6631_gps_dese(freq, NULL); + if (ret < 0) + WCN_DBG(FM_ERR | MAIN, "mt6631_gps_dese FAIL:%d\n", ret); + + WCN_DBG(FM_INF | MAIN, "GPS %d\n", ret); +#endif + + /* A0. Host contrl RF register */ + ret = fm_set_bits(0x60, 0x0007, 0xFFF0); /* Set 0x60 [D3:D0] = 0x07*/ + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: Host Control RF register 0x60 = 0x7 failed\n", __func__); + + /* A0.1 Update FM ADPLL fast tracking mode gain */ + ret = fm_set_bits(0x0F, 0x0455, 0xF800); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: Set FM ADPLL gainA/B=0x455 failed\n", __func__); + + /* A0.2 Set FMSYS cell mode */ + if (mt6631_TDD_chan_check(freq)) { + ret = fm_set_bits(0x30, 0x0008, 0xFFF3); /* use TDD solution */ + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: freq[%d]: use TDD solution failed\n", __func__, freq); + } else { + ret = fm_set_bits(0x30, 0x0000, 0xFFF3); /* default use FDD solution */ + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: freq[%d]: default use FDD solution failed\n", __func__, freq); + } + + /* A0.3 Host control RF register */ + ret = fm_set_bits(0x60, 0x000F, 0xFFF0); /* Set 0x60 [D3:D0] = 0x0F*/ + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: Set 0x60 [D3:D0] = 0x0F failed\n", __func__); + + /* A1 Get Channel parameter from map list*/ + + chan_para = mt6631_chan_para_get(freq); + WCN_DBG(FM_DBG | CHIP, "%s: %d chan para = %d\n", __func__, (signed int) freq, (signed int) chan_para); + + freq_reg = freq; + if (fm_get_channel_space(freq_reg) == 0) + freq_reg *= 10; + + freq_reg = (freq_reg - 6400) * 2 / 10; + + /*A1 Set rgfrf_chan = XXX*/ + ret = fm_set_bits(0x65, freq_reg, 0xFC00); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "%s: set rgfrf_chan = xxx = %d failed\n", __func__, freq_reg); + return false; + } + + ret = fm_set_bits(0x65, (chan_para << 12), 0x0FFF); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "set freq wr 0x65 failed\n"); + return false; + } + + /* SPI hoppint setting*/ + if (mt6631_SPI_hopping_check(freq)) { + + WCN_DBG(FM_NTC | CHIP, "%s: freq:%d is SPI hopping channel,turn on 64M PLL\n", __func__, freq); + + if (projectid == 0x8168) { + mt8168_spi_hopping_clock_switch(true); + } else { + if (!mt6631_do_SPI_hopping_64M(freq)) + WCN_DBG(FM_ERR | CHIP, "%s: spi hopping fail!\n", __func__); + } + } + + /* A0. Host contrl RF register */ + ret = fm_set_bits(0x60, 0x0007, 0xFFF0); /* Set 0x60 [D3:D0] = 0x07*/ + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: Host Control RF register 0x60 = 0x7 failed\n", __func__); + + + fm_reg_read(0x62, &tmp_reg[0]); + fm_reg_read(0x64, &tmp_reg[1]); + fm_reg_read(0x69, &tmp_reg[2]); + fm_reg_read(0x6a, &tmp_reg[3]); + fm_reg_read(0x6b, &tmp_reg[4]); + fm_reg_read(0x9b, &tmp_reg[5]); + + WCN_DBG(FM_ALT | CHIP, "%s: Before tune--0x62 0x64 0x69 0x6a 0x6b 0x9b = %04x %04x %04x %04x %04x %04x\n", + __func__, + tmp_reg[0], + tmp_reg[1], + tmp_reg[2], + tmp_reg[3], + tmp_reg[4], + tmp_reg[5]); + + /* A0.3 Host control RF register */ + ret = fm_set_bits(0x60, 0x000F, 0xFF00); /* Set 0x60 [D3:D0] = 0x0F*/ + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: Set 0x60 [D3:D0] = 0x0F failed\n", __func__); + + if (FM_LOCK(cmd_buf_lock)) + return false; + pkt_size = mt6631_tune(cmd_buf, TX_BUF_SIZE, freq, chan_para); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_TUNE | FLAG_TUNE_DONE, SW_RETRY_CNT, TUNE_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + + + /* A0. Host contrl RF register */ + ret = fm_set_bits(0x60, 0x0007, 0xFFF0); /* Set 0x60 [D3:D0] = 0x07*/ + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: Host Control RF register 0x60 = 0x7 failed\n", __func__); + + memset(tmp_reg, 0, sizeof(tmp_reg[0])*6); + + fm_reg_read(0x62, &tmp_reg[0]); + fm_reg_read(0x64, &tmp_reg[1]); + fm_reg_read(0x69, &tmp_reg[2]); + fm_reg_read(0x6a, &tmp_reg[3]); + fm_reg_read(0x6b, &tmp_reg[4]); + fm_reg_read(0x9b, &tmp_reg[5]); + + WCN_DBG(FM_ALT | CHIP, "%s: After tune--0x62 0x64 0x69 0x6a 0x6b 0x9b = %04x %04x %04x %04x %04x %04x\n", + __func__, + tmp_reg[0], + tmp_reg[1], + tmp_reg[2], + tmp_reg[3], + tmp_reg[4], + tmp_reg[5]); + + /* A0.3 Host control RF register */ + ret = fm_set_bits(0x60, 0x000F, 0xFF00); /* Set 0x60 [D3:D0] = 0x0F*/ + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: Set 0x60 [D3:D0] = 0x0F failed\n", __func__); + + if (ret) { + WCN_DBG(FM_ALT | CHIP, "%s: mt6631_tune failed\n", __func__); + return false; + } + + WCN_DBG(FM_DBG | CHIP, "%s: set freq to %d ok\n", __func__, freq); +#if 0 + /* ADPLL setting for dbg */ + fm_top_reg_write(0x0050, 0x00000007); + fm_top_reg_write(0x0A08, 0xFFFFFFFF); + mt6631_bt_write(0x82, 0x11); + mt6631_bt_write(0x83, 0x11); + mt6631_bt_write(0x84, 0x11); + fm_top_reg_write(0x0040, 0x1C1C1C1C); + fm_top_reg_write(0x0044, 0x1C1C1C1C); + fm_reg_write(0x70, 0x0010); + /*0x0806 DCO clk + *0x0802 ref clk + *0x0804 feedback clk + */ + fm_reg_write(0xE0, 0x0806); +#endif + return true; +} + +#if 0 +/* +* mt6631_Seek +* @pFreq - IN/OUT parm, IN start freq/OUT seek valid freq +* @seekdir - 0:up, 1:down +* @space - 1:50KHz, 2:100KHz, 4:200KHz +* return true:seek success; false:seek failed +*/ +static bool mt6631_Seek(unsigned short min_freq, unsigned short max_freq, unsigned short *pFreq, + unsigned short seekdir, unsigned short space) +{ + signed int ret = 0; + unsigned short pkt_size, temp; + + mt6631_RampDown(); + fm_reg_read(FM_MAIN_CTRL, &temp); + mt6631_Mute(true); + + if (FM_LOCK(cmd_buf_lock)) + return false; + pkt_size = mt6631_seek(cmd_buf, TX_BUF_SIZE, seekdir, space, max_freq, min_freq); + ret = + fm_cmd_tx(cmd_buf, pkt_size, FLAG_SEEK | FLAG_SEEK_DONE, SW_RETRY_CNT, SEEK_TIMEOUT, + fm_get_read_result); + FM_UNLOCK(cmd_buf_lock); + + if (!ret && fm_res) { + *pFreq = fm_res->seek_result; + /* fm_cb_op->cur_freq_set(*pFreq); */ + } else { + WCN_DBG(FM_ALT | CHIP, "mt6631_seek failed\n"); + return ret; + } + + /* get the result freq */ + WCN_DBG(FM_NTC | CHIP, "seek, result freq:%d\n", *pFreq); + mt6631_RampDown(); + if ((temp & 0x0020) == 0) + mt6631_Mute(false); + + return true; +} +#endif +#define FM_CQI_LOG_PATH "/mnt/sdcard/fmcqilog" + +static signed int mt6631_full_cqi_get(signed int min_freq, signed int max_freq, signed int space, signed int cnt) +{ + signed int ret = 0; + unsigned short pkt_size; + unsigned short freq, orig_freq; + signed int i, j, k; + signed int space_val, max, min, num; + struct mt6631_full_cqi *p_cqi; + unsigned char *cqi_log_title = "Freq, RSSI, PAMD, PR, FPAMD, MR, ATDC, PRX, ATDEV, SMGain, DltaRSSI\n"; + unsigned char cqi_log_buf[100] = { 0 }; + signed int pos; + unsigned char cqi_log_path[100] = { 0 }; + + /* for soft-mute tune, and get cqi */ + freq = fm_cb_op->cur_freq_get(); + if (fm_get_channel_space(freq) == 0) + freq *= 10; + + /* get cqi */ + orig_freq = freq; + if (fm_get_channel_space(min_freq) == 0) + min = min_freq * 10; + else + min = min_freq; + + if (fm_get_channel_space(max_freq) == 0) + max = max_freq * 10; + else + max = max_freq; + + if (space == 0x0001) + space_val = 5; /* 50Khz */ + else if (space == 0x0002) + space_val = 10; /* 100Khz */ + else if (space == 0x0004) + space_val = 20; /* 200Khz */ + else + space_val = 10; + + num = (max - min) / space_val + 1; /* Eg, (8760 - 8750) / 10 + 1 = 2 */ + for (k = 0; (orig_freq == 10000) && (g_dbg_level == 0xffffffff) && (k < cnt); k++) { + WCN_DBG(FM_NTC | CHIP, "cqi file:%d\n", k + 1); + freq = min; + pos = 0; + fm_memcpy(cqi_log_path, FM_CQI_LOG_PATH, strlen(FM_CQI_LOG_PATH)); + if (sprintf(&cqi_log_path[strlen(FM_CQI_LOG_PATH)], "%d.txt", k + 1) < 0) + WCN_DBG(FM_NTC | CHIP, "sprintf fail\n"); + fm_file_write(cqi_log_path, cqi_log_title, strlen(cqi_log_title), &pos); + for (j = 0; j < num; j++) { + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = fm_full_cqi_req(cmd_buf, TX_BUF_SIZE, &freq, 1, 1); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_SM_TUNE, SW_RETRY_CNT, + SM_TUNE_TIMEOUT, fm_get_read_result); + FM_UNLOCK(cmd_buf_lock); + + if (!ret && fm_res) { + WCN_DBG(FM_NTC | CHIP, "smt cqi size %d\n", fm_res->cqi[0]); + p_cqi = (struct mt6631_full_cqi *)&fm_res->cqi[2]; + for (i = 0; i < fm_res->cqi[1]; i++) { + /* just for debug */ + WCN_DBG(FM_NTC | CHIP, + "freq %d, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x\n", + p_cqi[i].ch, p_cqi[i].rssi, p_cqi[i].pamd, + p_cqi[i].pr, p_cqi[i].fpamd, p_cqi[i].mr, + p_cqi[i].atdc, p_cqi[i].prx, p_cqi[i].atdev, + p_cqi[i].smg, p_cqi[i].drssi); + /* format to buffer */ + if (sprintf(cqi_log_buf, + "%04d, %04x, %04x, %04x, %04x, %04x, %04x, %04x, %04x, %04x, %04x,\n", + p_cqi[i].ch, p_cqi[i].rssi, p_cqi[i].pamd, + p_cqi[i].pr, p_cqi[i].fpamd, p_cqi[i].mr, + p_cqi[i].atdc, p_cqi[i].prx, p_cqi[i].atdev, + p_cqi[i].smg, p_cqi[i].drssi) < 0) + WCN_DBG(FM_NTC | CHIP, "sprintf fail\n"); + /* write back to log file */ + fm_file_write(cqi_log_path, cqi_log_buf, strlen(cqi_log_buf), &pos); + } + } else { + WCN_DBG(FM_ALT | CHIP, "smt get CQI failed\n"); + ret = -1; + } + freq += space_val; + } + fm_cb_op->cur_freq_set(0); /* avoid run too much times */ + } + + return ret; +} + +static unsigned short mt6631_read_dsp_reg(unsigned short addr) +{ + unsigned short regValue = 0; + + fm_reg_write(0x60, 0x07); + fm_reg_write(0xE2, addr); + fm_reg_write(0xE1, 0x01); + fm_reg_read(0xE4, ®Value); + fm_reg_write(0x60, 0x0F); + + return regValue; +} + +static bool mt6631_is_valid_freq(unsigned short freq) +{ + int i = 0; + bool valid = false; + signed int RSSI = 0, PAMD = 0, MR = 0; + unsigned int PRX = 0; + unsigned short softmuteGainLvl = 0; + unsigned short tmp_reg = 0; + + for (i = 0; i < 8; i++) { + fm_reg_read(0x6C, &tmp_reg); + RSSI += (((tmp_reg & 0x03FF) >= 512) ? ((tmp_reg & 0x03FF) - 1024) : (tmp_reg & 0x03FF)) >> 3; + fm_reg_read(0xB4, &tmp_reg); + PAMD += (((tmp_reg & 0x1FF) >= 256) ? ((tmp_reg & 0x01FF) - 512) : (tmp_reg & 0x01FF)) >> 3; + tmp_reg = mt6631_read_dsp_reg(0x4E1); + PRX += (tmp_reg & 0x00FF) >> 3; + fm_reg_read(0xBD, &tmp_reg); + MR += (((tmp_reg & 0x01FF) >= 256) ? ((tmp_reg & 0x01FF) - 512) : (tmp_reg & 0x01FF)) >> 3; + tmp_reg = mt6631_read_dsp_reg(0x2C4); + softmuteGainLvl += tmp_reg >> 3; + fm_delayus(2250); + } + + if ((fm_config.rx_cfg.long_ana_rssi_th <= RSSI) + && (fm_config.rx_cfg.pamd_th >= PAMD) + && (fm_config.rx_cfg.mr_th <= MR) + && (fm_config.rx_cfg.prx_th <= PRX) + && (fm_config.rx_cfg.smg_th <= softmuteGainLvl)) { + valid = true; + } + + WCN_DBG(FM_DBG | CHIP, + "freq %d valid=%d, %d, %d, 0x%04x, 0x%04x, 0x%04x\n", + freq, valid, RSSI, PAMD, PRX, MR, softmuteGainLvl); + + return valid; +} + +/* + * mt6631_GetCurRSSI - get current freq's RSSI value + * RS=RSSI + * If RS>511, then RSSI(dBm)= (RS-1024)/16*6 + * else RSSI(dBm)= RS/16*6 + */ +static signed int mt6631_GetCurRSSI(signed int *pRSSI) +{ + unsigned short tmp_reg = 0; + + fm_reg_read(FM_RSSI_IND, &tmp_reg); + tmp_reg = tmp_reg & 0x03ff; + + if (pRSSI) { + *pRSSI = (tmp_reg > 511) ? (((tmp_reg - 1024) * 6) >> 4) : ((tmp_reg * 6) >> 4); + WCN_DBG(FM_DBG | CHIP, "rssi:%d, dBm:%d\n", tmp_reg, *pRSSI); + } else { + WCN_DBG(FM_ERR | CHIP, "get rssi para error\n"); + return -FM_EPARA; + } + + return 0; +} + +static unsigned short mt6631_vol_tbl[16] = { 0x0000, 0x0519, 0x066A, 0x0814, + 0x0A2B, 0x0CCD, 0x101D, 0x1449, + 0x198A, 0x2027, 0x287A, 0x32F5, + 0x4027, 0x50C3, 0x65AD, 0x7FFF +}; + +static signed int mt6631_SetVol(unsigned char vol) +{ + signed int ret = 0; + + vol = (vol > 15) ? 15 : vol; + ret = fm_reg_write(0x7D, mt6631_vol_tbl[vol]); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "Set vol=%d Failed\n", vol); + return ret; + } + WCN_DBG(FM_DBG | CHIP, "Set vol=%d OK\n", vol); + + + if (vol == 10) { + fm_print_cmd_fifo(); /* just for debug */ + fm_print_evt_fifo(); + } + return 0; +} + +static signed int mt6631_GetVol(unsigned char *pVol) +{ + int ret = 0; + unsigned short tmp = 0; + signed int i; + + if (pVol == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + ret = fm_reg_read(0x7D, &tmp); + if (ret) { + *pVol = 0; + WCN_DBG(FM_ERR | CHIP, "Get vol Failed\n"); + return ret; + } + + for (i = 0; i < 16; i++) { + if (mt6631_vol_tbl[i] == tmp) { + *pVol = i; + break; + } + } + + WCN_DBG(FM_DBG | CHIP, "Get vol=%d OK\n", *pVol); + return 0; +} + +static signed int mt6631_dump_reg(void) +{ + signed int i; + unsigned short TmpReg = 0; + + for (i = 0; i < 0xff; i++) { + fm_reg_read(i, &TmpReg); + WCN_DBG(FM_NTC | CHIP, "0x%02x=0x%04x\n", i, TmpReg); + } + return 0; +} + +/*0:mono, 1:stereo*/ +static bool mt6631_GetMonoStereo(unsigned short *pMonoStereo) +{ +#define FM_BF_STEREO 0x1000 + unsigned short TmpReg = 0; + + if (pMonoStereo) { + fm_reg_read(FM_RSSI_IND, &TmpReg); + *pMonoStereo = (TmpReg & FM_BF_STEREO) >> 12; + } else { + WCN_DBG(FM_ERR | CHIP, "MonoStero: para err\n"); + return false; + } + + WCN_DBG(FM_NTC | CHIP, "Get MonoStero:0x%04x\n", *pMonoStereo); + return true; +} + +static signed int mt6631_SetMonoStereo(signed int MonoStereo) +{ + signed int ret = 0; + + WCN_DBG(FM_NTC | CHIP, "set to %s\n", MonoStereo ? "mono" : "auto"); + fm_reg_write(0x60, 0x0007); + + if (MonoStereo) /*mono */ + ret = fm_set_bits(0x75, 0x0008, ~0x0008); + else + ret = fm_set_bits(0x75, 0x0000, ~0x0008); + + fm_reg_write(0x60, 0x000F); + return ret; +} + +static signed int mt6631_GetCapArray(signed int *ca) +{ + unsigned short dataRead = 0; + unsigned short tmp = 0; + + if (ca == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + fm_reg_read(0x60, &tmp); + fm_reg_write(0x60, tmp & 0xFFF7); /* 0x60 D3=0 */ + + fm_reg_read(0x26, &dataRead); + *ca = dataRead; + + fm_reg_write(0x60, tmp); /* 0x60 D3=1 */ + return 0; +} + +/* + * mt6631_GetCurPamd - get current freq's PAMD value + * PA=PAMD + * If PA>511 then PAMD(dB)= (PA-1024)/16*6, + * else PAMD(dB)=PA/16*6 + */ +static bool mt6631_GetCurPamd(unsigned short *pPamdLevl) +{ + unsigned short tmp_reg = 0; + unsigned short dBvalue, valid_cnt = 0; + int i, total = 0; + + for (i = 0; i < 8; i++) { + if (fm_reg_read(FM_ADDR_PAMD, &tmp_reg)) { + *pPamdLevl = 0; + return false; + } + + tmp_reg &= 0x03FF; + dBvalue = (tmp_reg > 256) ? ((512 - tmp_reg) * 6 / 16) : 0; + if (dBvalue != 0) { + total += dBvalue; + valid_cnt++; + WCN_DBG(FM_DBG | CHIP, "[%d]PAMD=%d\n", i, dBvalue); + } + fm_delayms(3); + } + if (valid_cnt != 0) + *pPamdLevl = total / valid_cnt; + else + *pPamdLevl = 0; + + WCN_DBG(FM_NTC | CHIP, "PAMD=%d\n", *pPamdLevl); + return true; +} + +static signed int mt6631_i2s_info_get(signed int *ponoff, signed int *pmode, signed int *psample) +{ + if (ponoff == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (pmode == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (psample == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + *ponoff = fm_config.aud_cfg.i2s_info.status; + *pmode = fm_config.aud_cfg.i2s_info.mode; + *psample = fm_config.aud_cfg.i2s_info.rate; + + return 0; +} + +static signed int mt6631_get_audio_info(struct fm_audio_info_t *data) +{ + memcpy(data, &fm_config.aud_cfg, sizeof(struct fm_audio_info_t)); + return 0; +} + +static signed int mt6631_hw_info_get(struct fm_hw_info *req) +{ + if (req == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + req->chip_id = mt6631_hw_info.chip_id; + req->eco_ver = mt6631_hw_info.eco_ver; + req->patch_ver = mt6631_hw_info.patch_ver; + req->rom_ver = mt6631_hw_info.rom_ver; + + return 0; +} + +static signed int mt6631_pre_search(void) +{ + mt6631_RampDown(); + /* disable audio output I2S Rx mode */ + fm_host_reg_write(0x80101054, 0x00000000); + /* disable audio output I2S Tx mode */ + fm_reg_write(0x9B, 0x0000); + + return 0; +} + +static signed int mt6631_restore_search(void) +{ + mt6631_RampDown(); + /* set audio output I2S Tx mode */ + fm_reg_write(0x9B, 0xF9AB); + /* set audio output I2S Rx mode */ + fm_host_reg_write(0x80101054, 0x00003f35); + return 0; +} + +static signed int mt6631_soft_mute_tune(unsigned short freq, signed int *rssi, signed int *valid) +{ + signed int ret = 0; + unsigned short pkt_size; + struct mt6631_full_cqi *p_cqi; + signed int RSSI = 0, PAMD = 0, MR = 0, ATDC = 0; + unsigned int PRX = 0, ATDEV = 0; + unsigned short softmuteGainLvl = 0; + signed int projectid = fm_cb_op->projectid_get(); + + ret = mt6631_chan_para_get(freq); + if (ret == 2) + ret = fm_set_bits(FM_CHANNEL_SET, 0x2000, 0x0FFF); /* mdf HiLo */ + else + ret = fm_set_bits(FM_CHANNEL_SET, 0x0000, 0x0FFF); /* clear FA/HL/ATJ */ + + /* SPI hoppint setting*/ + if (mt6631_SPI_hopping_check(freq)) { + WCN_DBG(FM_NTC | CHIP, "%s: freq:%d is SPI hopping channel,turn on 64M PLL\n", __func__, freq); + + if (projectid == 0x8168) { + mt8168_spi_hopping_clock_switch(true); + } else { + if (!mt6631_do_SPI_hopping_64M(freq)) + WCN_DBG(FM_ERR | CHIP, "%s: spi hopping fail!\n", __func__); + } + } + + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = fm_full_cqi_req(cmd_buf, TX_BUF_SIZE, &freq, 1, 1); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_SM_TUNE, SW_RETRY_CNT, SM_TUNE_TIMEOUT, fm_get_read_result); + FM_UNLOCK(cmd_buf_lock); + + if (!ret && fm_res) { + p_cqi = (struct mt6631_full_cqi *)&fm_res->cqi[2]; + /* just for debug */ + WCN_DBG(FM_NTC | CHIP, + "freq %d, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x\n", + p_cqi->ch, p_cqi->rssi, p_cqi->pamd, p_cqi->pr, p_cqi->fpamd, p_cqi->mr, + p_cqi->atdc, p_cqi->prx, p_cqi->atdev, p_cqi->smg, p_cqi->drssi); + RSSI = ((p_cqi->rssi & 0x03FF) >= 512) ? ((p_cqi->rssi & 0x03FF) - 1024) : (p_cqi->rssi & 0x03FF); + PAMD = ((p_cqi->pamd & 0x1FF) >= 256) ? ((p_cqi->pamd & 0x01FF) - 512) : (p_cqi->pamd & 0x01FF); + MR = ((p_cqi->mr & 0x01FF) >= 256) ? ((p_cqi->mr & 0x01FF) - 512) : (p_cqi->mr & 0x01FF); + ATDC = (p_cqi->atdc >= 32768) ? (65536 - p_cqi->atdc) : (p_cqi->atdc); + if (ATDC < 0) + ATDC = (~(ATDC)) - 1; /* Get abs value of ATDC */ + + PRX = (p_cqi->prx & 0x00FF); + ATDEV = p_cqi->atdev; + softmuteGainLvl = p_cqi->smg; + /* check if the channel is valid according to each CQIs */ + if ((fm_config.rx_cfg.long_ana_rssi_th <= RSSI) + && (fm_config.rx_cfg.pamd_th >= PAMD) + && (fm_config.rx_cfg.atdc_th >= ATDC) + && (fm_config.rx_cfg.mr_th <= MR) + && (fm_config.rx_cfg.prx_th <= PRX) + && (ATDEV >= ATDC) /* sync scan algorithm */ + && (fm_config.rx_cfg.smg_th <= softmuteGainLvl)) { + *valid = true; + } else { + *valid = false; + } + *rssi = RSSI; + } else { + WCN_DBG(FM_ALT | CHIP, "smt get CQI failed\n"); + return false; + } + WCN_DBG(FM_NTC | CHIP, "valid=%d\n", *valid); + return true; +} + +static bool mt6631_em_test(unsigned short group_idx, unsigned short item_idx, unsigned int item_value) +{ + return true; +} + +/* +*parm: +* parm.th_type: 0, RSSI. 1, desense RSSI. 2, SMG. +* parm.th_val: threshold value +*/ +static signed int mt6631_set_search_th(signed int idx, signed int val, signed int reserve) +{ + switch (idx) { + case 0: { + fm_config.rx_cfg.long_ana_rssi_th = val; + WCN_DBG(FM_NTC | CHIP, "set rssi th =%d\n", val); + break; + } + case 1: { + fm_config.rx_cfg.desene_rssi_th = val; + WCN_DBG(FM_NTC | CHIP, "set desense rssi th =%d\n", val); + break; + } + case 2: { + fm_config.rx_cfg.smg_th = val; + WCN_DBG(FM_NTC | CHIP, "set smg th =%d\n", val); + break; + } + default: + break; + } + return 0; +} + +static signed int MT6631_low_power_wa_default(signed int fmon) +{ + return 0; +} + +signed int mt6631_fm_low_ops_register(struct fm_callback *cb, struct fm_basic_interface *bi) +{ + signed int ret = 0; + /* Basic functions. */ + + if (bi == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,bi invalid pointer\n", __func__); + return -FM_EPARA; + } + if (cb->cur_freq_get == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,cb->cur_freq_get invalid pointer\n", __func__); + return -FM_EPARA; + } + if (cb->cur_freq_set == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,cb->cur_freq_set invalid pointer\n", __func__); + return -FM_EPARA; + } + fm_cb_op = cb; + + bi->pwron = mt6631_pwron; + bi->pwroff = mt6631_pwroff; + bi->chipid_get = mt6631_get_chipid; + bi->mute = mt6631_Mute; + bi->rampdown = mt6631_RampDown; + bi->pwrupseq = mt6631_PowerUp; + bi->pwrdownseq = mt6631_PowerDown; + bi->setfreq = mt6631_SetFreq; + bi->low_pwr_wa = MT6631_low_power_wa_default; + bi->get_aud_info = mt6631_get_audio_info; + bi->rssiget = mt6631_GetCurRSSI; + bi->volset = mt6631_SetVol; + bi->volget = mt6631_GetVol; + bi->dumpreg = mt6631_dump_reg; + bi->msget = mt6631_GetMonoStereo; + bi->msset = mt6631_SetMonoStereo; + bi->pamdget = mt6631_GetCurPamd; + bi->em = mt6631_em_test; + bi->anaswitch = mt6631_SetAntennaType; + bi->anaget = mt6631_GetAntennaType; + bi->caparray_get = mt6631_GetCapArray; + bi->hwinfo_get = mt6631_hw_info_get; + bi->i2s_get = mt6631_i2s_info_get; + bi->is_dese_chan = mt6631_is_dese_chan; + bi->softmute_tune = mt6631_soft_mute_tune; + bi->desense_check = mt6631_desense_check; + bi->cqi_log = mt6631_full_cqi_get; + bi->pre_search = mt6631_pre_search; + bi->restore_search = mt6631_restore_search; + bi->set_search_th = mt6631_set_search_th; + bi->is_valid_freq = mt6631_is_valid_freq; + + cmd_buf_lock = fm_lock_create("31_cmd"); + ret = fm_lock_get(cmd_buf_lock); + + cmd_buf = fm_zalloc(TX_BUF_SIZE + 1); + + if (!cmd_buf) { + WCN_DBG(FM_ALT | CHIP, "6631 fm lib alloc tx buf failed\n"); + ret = -1; + } +#if 0 /* def CONFIG_MTK_FM_50KHZ_SUPPORT */ + cqi_fifo = fm_fifo_create("6628_cqi_fifo", sizeof(struct adapt_fm_cqi), 640); + if (!cqi_fifo) { + WCN_DBG(FM_ALT | CHIP, "6631 fm lib create cqi fifo failed\n"); + ret = -1; + } +#endif + + return ret; +} + +signed int mt6631_fm_low_ops_unregister(struct fm_basic_interface *bi) +{ + signed int ret = 0; + /* Basic functions. */ + if (bi == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,bi invalid pointer\n", __func__); + return -FM_EPARA; + } + +#if 0 /* def CONFIG_MTK_FM_50KHZ_SUPPORT */ + fm_fifo_release(cqi_fifo); +#endif + + if (cmd_buf) { + fm_free(cmd_buf); + cmd_buf = NULL; + } + + ret = fm_lock_put(cmd_buf_lock); + fm_memset(bi, 0, sizeof(struct fm_basic_interface)); + + fm_cb_op = NULL; + + return ret; +} + +static const signed char mt6631_chan_para_map[] = { + /* 0, X, 1, X, 2, X, 3, X, 4, X, 5, X, 6, X, 7, X, 8, X, 9, X*/ + 0, 0, 2, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6500~6595 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6600~6695 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, /* 6700~6795 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6800~6895 */ + 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6900~6995 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7000~7095 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7100~7195 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, /* 7200~7295 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, /* 7300~7395 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, /* 7400~7495 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7500~7595 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, /* 7600~7695 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7700~7795 */ + 8, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7800~7895 */ + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7900~7995 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8000~8095 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8100~8195 */ + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8200~8295 */ + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, /* 8300~8395 */ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8400~8495 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8500~8595 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8600~8695 */ + 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8700~8795 */ + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8800~8895 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8900~8995 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9000~9095 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9100~9195 */ + 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9200~9295 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9300~9395 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9400~9495 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9500~9595 */ + 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9600~9695 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9700~9795 */ + 0, 0, 0, 0, 0, 0, 8, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9800~9895 */ + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, /* 9900~9995 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10000~10095 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10100~10195 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, /* 10200~10295 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, /* 10300~10395 */ + 8, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10400~10495 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, /* 10500~10595 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10600~10695 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, /* 10700~10795 */ + 0 /* 10800 */ +}; +static const unsigned short mt6631_scan_dese_list[] = { + 6910, 6920, 7680, 7800, 8450, 9210, 9220, 9230, 9590, 9600, 9830, 9900, 9980, 9990, 10400, 10750, 10760 +}; + +static const unsigned short mt6631_SPI_hopping_list[] = { + 6510, 6520, 6530, 7780, 7790, 7800, 7810, 7820, 9090, 9100, 9110, 9120, 10380, 10390, 10400, 10410, 10420 +}; + +static const unsigned short mt6631_I2S_hopping_list[] = { + 6550, 6760, 6960, 6970, 7170, 7370, 7580, 7780, 7990, 8810, 9210, 9220, 10240 +}; + +static const unsigned short mt6631_TDD_list[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 6500~6595 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 6600~6695 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 6700~6795 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 6800~6895 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 6900~6995 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7000~7095 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7100~7195 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7200~7295 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7300~7395 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7400~7495 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7500~7595 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7600~7695 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7700~7795 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7800~7895 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7900~7995 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8000~8095 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8100~8195 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8200~8295 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8300~8395 */ + 0x0101, 0x0000, 0x0000, 0x0000, 0x0000, /* 8400~8495 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8500~8595 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8600~8695 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8700~8795 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8800~8895 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8900~8995 */ + 0x0000, 0x0000, 0x0101, 0x0101, 0x0101, /* 9000~9095 */ + 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, /* 9100~9195 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9200~9295 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9300~9395 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9400~9495 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9500~9595 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9600~9695 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0100, /* 9700~9795 */ + 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, /* 9800~9895 */ + 0x0101, 0x0101, 0x0001, 0x0000, 0x0000, /* 9900~9995 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10000~10095 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10100~10195 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10200~10295 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10300~10395 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10400~10495 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10500~10595 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0100, /* 10600~10695 */ + 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, /* 10700~10795 */ + 0x0001 /* 10800 */ +}; + +static const unsigned short mt6631_TDD_Mask[] = { + 0x0001, 0x0010, 0x0100, 0x1000 +}; + +/* return value: 0, not a de-sense channel; 1, this is a de-sense channel; else error no */ +static signed int mt6631_is_dese_chan(unsigned short freq) +{ + signed int size; + + if (1 == HQA_ZERO_DESENSE_MAP) /*HQA only :skip desense channel check. */ + return 0; + + size = ARRAY_SIZE(mt6631_scan_dese_list); + + if (fm_get_channel_space(freq) == 0) + freq *= 10; + + while (size) { + if (mt6631_scan_dese_list[size - 1] == freq) + return 1; + + size--; + } + + return 0; +} + +/* return value: +*1, is desense channel and rssi is less than threshold; +*0, not desense channel or it is but rssi is more than threshold. +*/ +static signed int mt6631_desense_check(unsigned short freq, signed int rssi) +{ + if (mt6631_is_dese_chan(freq)) { + if (rssi < fm_config.rx_cfg.desene_rssi_th) + return 1; + + WCN_DBG(FM_DBG | CHIP, "desen_rssi %d th:%d\n", rssi, fm_config.rx_cfg.desene_rssi_th); + } + return 0; +} + +static bool mt6631_TDD_chan_check(unsigned short freq) +{ + unsigned int i = 0; + unsigned short freq_tmp = freq; + signed int ret = 0; + + ret = fm_get_channel_space(freq_tmp); + if (ret == 0) + freq_tmp *= 10; + else if (ret == -1) + return false; + + i = (freq_tmp - 6500) / 5; + if ((i / 4) >= ARRAY_SIZE(mt6631_TDD_list)) { + WCN_DBG(FM_ERR | CHIP, "Freq index out of range(%d),max(%zd)\n", + i / 4, ARRAY_SIZE(mt6631_TDD_list)); + return false; + } + + if (mt6631_TDD_list[i / 4] & mt6631_TDD_Mask[i % 4]) { + WCN_DBG(FM_DBG | CHIP, "Freq %d use TDD solution\n", freq); + return true; + } else + return false; +} + +/* get channel parameter, HL side/ FA / ATJ */ +static unsigned short mt6631_chan_para_get(unsigned short freq) +{ + signed int pos, size; + + if (1 == HQA_RETURN_ZERO_MAP) { + WCN_DBG(FM_NTC | CHIP, "HQA_RETURN_ZERO_CHAN mt6631_chan_para_map enabled!\n"); + return 0; + } + + if (fm_get_channel_space(freq) == 0) + freq *= 10; + + if (freq < 6500) + return 0; + + pos = (freq - 6500) / 5; + + size = ARRAY_SIZE(mt6631_chan_para_map); + + pos = (pos > (size - 1)) ? (size - 1) : pos; + + return mt6631_chan_para_map[pos]; +} + + +static bool mt6631_SPI_hopping_check(unsigned short freq) +{ + signed int size; + + size = ARRAY_SIZE(mt6631_SPI_hopping_list); + + if (fm_get_channel_space(freq) == 0) + freq *= 10; + + while (size) { + if (mt6631_SPI_hopping_list[size - 1] == freq) + return 1; + size--; + } + + return 0; +} + diff --git a/drivers/misc/mediatek/connectivity/fmradio/chips/mt6631/pub/mt6631_fm_rds.c b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6631/pub/mt6631_fm_rds.c new file mode 100644 index 0000000000000000000000000000000000000000..7c48a23e5694a5dcaf7745e6b2b28c3d85ba4d8e --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6631/pub/mt6631_fm_rds.c @@ -0,0 +1,335 @@ +/* +* Copyright (C) 2016 MediaTek Inc. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. +*/ +#include "fm_typedef.h" +#include "fm_dbg.h" +#include "fm_err.h" +#include "fm_interface.h" +#include "fm_stdlib.h" +#include "fm_rds.h" +#include "mt6631_fm_reg.h" +#include "fm_cmd.h" + +static bool bRDS_FirstIn; /* false */ +static unsigned int gBLER_CHK_INTERVAL = 500; +static unsigned short GOOD_BLK_CNT = 0, BAD_BLK_CNT; +static unsigned char BAD_BLK_RATIO; + +static struct fm_basic_interface *fm_bi; + +static bool mt6631_RDS_support(void); +static signed int mt6631_RDS_enable(void); +static signed int mt6631_RDS_disable(void); +static unsigned short mt6631_RDS_Get_GoodBlock_Counter(void); +static unsigned short mt6631_RDS_Get_BadBlock_Counter(void); +static unsigned char mt6631_RDS_Get_BadBlock_Ratio(void); +static unsigned int mt6631_RDS_Get_BlerCheck_Interval(void); +/* static void mt6631_RDS_GetData(unsigned short *data, unsigned short datalen); */ +static void mt6631_RDS_Init_Data(struct rds_t *pstRDSData); + +static bool mt6631_RDS_support(void) +{ + return true; +} + +static signed int mt6631_RDS_enable(void) +{ + signed int ret = 0; + unsigned short dataRead = 0; + + WCN_DBG(FM_DBG | RDSC, "rds enable\n"); + ret = fm_reg_read(FM_RDS_CFG0, &dataRead); + if (ret) { + WCN_DBG(FM_NTC | RDSC, "rds enable read 0x80 fail\n"); + return ret; + } + ret = fm_reg_write(FM_RDS_CFG0, 6); /* set buf_start_th */ + if (ret) { + WCN_DBG(FM_NTC | RDSC, "rds enable write 0x80 fail\n"); + return ret; + } + ret = fm_reg_read(FM_MAIN_CTRL, &dataRead); + if (ret) { + WCN_DBG(FM_NTC | RDSC, "rds enable read 0x63 fail\n"); + return ret; + } + ret = fm_reg_write(FM_MAIN_CTRL, dataRead | (RDS_MASK)); + if (ret) { + WCN_DBG(FM_NTC | RDSC, "rds enable write 0x63 fail\n"); + return ret; + } + + return ret; +} + +static signed int mt6631_RDS_disable(void) +{ + signed int ret = 0; + unsigned short dataRead = 0; + + WCN_DBG(FM_DBG | RDSC, "rds disable\n"); + ret = fm_reg_read(FM_MAIN_CTRL, &dataRead); + if (ret) { + WCN_DBG(FM_NTC | RDSC, "rds disable read 0x63 fail\n"); + return ret; + } + ret = fm_reg_write(FM_MAIN_CTRL, dataRead & (~RDS_MASK)); + if (ret) { + WCN_DBG(FM_NTC | RDSC, "rds disable write 0x63 fail\n"); + return ret; + } + + return ret; +} + +static unsigned short mt6631_RDS_Get_GoodBlock_Counter(void) +{ + unsigned short tmp_reg = 0; + + fm_reg_read(FM_RDS_GOODBK_CNT, &tmp_reg); + GOOD_BLK_CNT = tmp_reg; + WCN_DBG(FM_DBG | RDSC, "get good block cnt:%d\n", (signed int) tmp_reg); + + return tmp_reg; +} + +static unsigned short mt6631_RDS_Get_BadBlock_Counter(void) +{ + unsigned short tmp_reg = 0; + + fm_reg_read(FM_RDS_BADBK_CNT, &tmp_reg); + BAD_BLK_CNT = tmp_reg; + WCN_DBG(FM_DBG | RDSC, "get bad block cnt:%d\n", (signed int) tmp_reg); + + return tmp_reg; +} + +static unsigned char mt6631_RDS_Get_BadBlock_Ratio(void) +{ + unsigned short tmp_reg; + unsigned short gbc; + unsigned short bbc; + + gbc = mt6631_RDS_Get_GoodBlock_Counter(); + bbc = mt6631_RDS_Get_BadBlock_Counter(); + + if ((gbc + bbc) > 0) + tmp_reg = (unsigned char) (bbc * 100 / (gbc + bbc)); + else + tmp_reg = 0; + + BAD_BLK_RATIO = tmp_reg; + WCN_DBG(FM_DBG | RDSC, "get badblock ratio:%d\n", (signed int) tmp_reg); + + return tmp_reg; +} + +static signed int mt6631_RDS_BlockCounter_Reset(void) +{ + mt6631_RDS_disable(); + mt6631_RDS_enable(); + + return 0; +} + +static unsigned int mt6631_RDS_Get_BlerCheck_Interval(void) +{ + return gBLER_CHK_INTERVAL; +} + +static signed int mt6631_RDS_BlerCheck(struct rds_t *dst) +{ + return 0; +} + +#if 0 +static void RDS_Recovery_Handler(void) +{ + unsigned short tempData = 0; + + do { + fm_reg_read(FM_RDS_DATA_REG, &tempData); + fm_reg_read(FM_RDS_POINTER, &tempData); + } while (tempData & 0x3); +} +#endif + +#if 0 +static void mt6631_RDS_GetData(unsigned short *data, unsigned short datalen) +{ +#define RDS_GROUP_DIFF_OFS 0x007C +#define RDS_FIFO_DIFF 0x007F +#define RDS_CRC_BLK_ADJ 0x0020 +#define RDS_CRC_CORR_CNT 0x001E +#define RDS_CRC_INFO 0x0001 + + unsigned short CRC = 0, i = 0, RDS_adj = 0, RDSDataCount = 0, FM_WARorrCnt = 0; + unsigned short temp = 0, OutputPofm_s32 = 0; + + WCN_DBG(FM_DBG | RDSC, "get data\n"); + fm_reg_read(FM_RDS_FIFO_STATUS0, &temp); + RDSDataCount = ((RDS_GROUP_DIFF_OFS & temp) << 2); + + if ((temp & RDS_FIFO_DIFF) >= 4) { + /* block A data and info handling */ + fm_reg_read(FM_RDS_INFO, &temp); + RDS_adj |= (temp & RDS_CRC_BLK_ADJ) << 10; + CRC |= (temp & RDS_CRC_INFO) << 3; + FM_WARorrCnt |= ((temp & RDS_CRC_CORR_CNT) << 11); + fm_reg_read(FM_RDS_DATA_REG, &data[0]); + + /* block B data and info handling */ + fm_reg_read(FM_RDS_INFO, &temp); + RDS_adj |= (temp & RDS_CRC_BLK_ADJ) << 9; + CRC |= (temp & RDS_CRC_INFO) << 2; + FM_WARorrCnt |= ((temp & RDS_CRC_CORR_CNT) << 7); + fm_reg_read(FM_RDS_DATA_REG, &data[1]); + + /* block C data and info handling */ + fm_reg_read(FM_RDS_INFO, &temp); + RDS_adj |= (temp & RDS_CRC_BLK_ADJ) << 8; + CRC |= (temp & RDS_CRC_INFO) << 1; + FM_WARorrCnt |= ((temp & RDS_CRC_CORR_CNT) << 3); + fm_reg_read(FM_RDS_DATA_REG, &data[2]); + + /* block D data and info handling */ + fm_reg_read(FM_RDS_INFO, &temp); + RDS_adj |= (temp & RDS_CRC_BLK_ADJ) << 7; + CRC |= (temp & RDS_CRC_INFO); + FM_WARorrCnt |= ((temp & RDS_CRC_CORR_CNT) >> 1); + fm_reg_read(FM_RDS_DATA_REG, &data[3]); + + data[4] = (CRC | RDS_adj | RDSDataCount); + data[5] = FM_WARorrCnt; + + fm_reg_read(FM_RDS_PWDI, &data[6]); + fm_reg_read(FM_RDS_PWDQ, &data[7]); + + fm_reg_read(FM_RDS_POINTER, &OutputPofm_s32); + + /* Go fm_s32o RDS recovery handler while RDS output pofm_s32 doesn't align to 4 in numeric */ + if (OutputPofm_s32 & 0x3) + RDS_Recovery_Handler(); + + } else { + for (; i < 8; i++) + data[i] = 0; + } +} +#endif + +static void mt6631_RDS_Init_Data(struct rds_t *pstRDSData) +{ + fm_memset(pstRDSData, 0, sizeof(struct rds_t)); + bRDS_FirstIn = true; + + pstRDSData->event_status = 0x0000; + fm_memset(pstRDSData->RT_Data.TextData, 0x20, sizeof(pstRDSData->RT_Data.TextData)); + fm_memset(pstRDSData->PS_Data.PS, '\0', sizeof(pstRDSData->PS_Data.PS)); + fm_memset(pstRDSData->PS_ON, 0x20, sizeof(pstRDSData->PS_ON)); +} + +bool mt6631_RDS_OnOff(struct rds_t *dst, bool bFlag) +{ + signed int ret = 0; + + if (mt6631_RDS_support() == false) { + WCN_DBG(FM_ALT | RDSC, "mt6631_RDS_OnOff failed, RDS not support\n"); + return false; + } + + if (bFlag) { + mt6631_RDS_Init_Data(dst); + ret = mt6631_RDS_enable(); + if (ret) { + WCN_DBG(FM_NTC | RDSC, "mt6631_RDS_OnOff enable failed\n"); + return false; + } + } else { + mt6631_RDS_Init_Data(dst); + ret = mt6631_RDS_disable(); + if (ret) { + WCN_DBG(FM_NTC | RDSC, "mt6631_RDS_OnOff disable failed\n"); + return false; + } + } + + return true; +} + +DEFINE_RDSLOG(mt6631_rds_log); + +/* mt6631_RDS_Efm_s32_Handler - response FM RDS interrupt + * @fm - main data structure of FM driver + * This function first get RDS raw data, then call RDS spec parser + */ +static signed int mt6631_rds_parser(struct rds_t *rds_dst, struct rds_rx_t *rds_raw, + signed int rds_size, unsigned short(*getfreq) (void)) +{ + mt6631_rds_log.log_in(&mt6631_rds_log, rds_raw, rds_size); + return rds_parser(rds_dst, rds_raw, rds_size, getfreq); +} + +static signed int mt6631_rds_log_get(struct rds_rx_t *dst, signed int *dst_len) +{ + return mt6631_rds_log.log_out(&mt6631_rds_log, dst, dst_len); +} + +static signed int mt6631_rds_gc_get(struct rds_group_cnt_t *dst, struct rds_t *rdsp) +{ + return rds_grp_counter_get(dst, &rdsp->gc); +} + +static signed int mt6631_rds_gc_reset(struct rds_t *rdsp) +{ + return rds_grp_counter_reset(&rdsp->gc); +} + +signed int mt6631_fm_rds_ops_register(struct fm_basic_interface *bi, struct fm_rds_interface *ri) +{ + signed int ret = 0; + + if (ri == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,ri invalid pointer\n", __func__); + return -FM_EPARA; + } + + fm_bi = bi; + + ri->rds_blercheck = mt6631_RDS_BlerCheck; + ri->rds_onoff = mt6631_RDS_OnOff; + ri->rds_parser = mt6631_rds_parser; + ri->rds_gbc_get = mt6631_RDS_Get_GoodBlock_Counter; + ri->rds_bbc_get = mt6631_RDS_Get_BadBlock_Counter; + ri->rds_bbr_get = mt6631_RDS_Get_BadBlock_Ratio; + ri->rds_bc_reset = mt6631_RDS_BlockCounter_Reset; + ri->rds_bci_get = mt6631_RDS_Get_BlerCheck_Interval; + ri->rds_log_get = mt6631_rds_log_get; + ri->rds_gc_get = mt6631_rds_gc_get; + ri->rds_gc_reset = mt6631_rds_gc_reset; + + return ret; +} + +signed int mt6631_fm_rds_ops_unregister(struct fm_rds_interface *ri) +{ + signed int ret = 0; + + if (ri == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,ri invalid pointer\n", __func__); + return -FM_EPARA; + } + + fm_bi = NULL; + fm_memset(ri, 0, sizeof(struct fm_rds_interface)); + return ret; +} diff --git a/drivers/misc/mediatek/connectivity/fmradio/chips/mt6632/inc/mt6632_fm_lib.h b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6632/inc/mt6632_fm_lib.h new file mode 100644 index 0000000000000000000000000000000000000000..1c1ae7ea5056e4290def3f5798fa8a0a5ab77a6b --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6632/inc/mt6632_fm_lib.h @@ -0,0 +1,69 @@ +/* +* Copyright (C) 2016 MediaTek Inc. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. +*/ + +#ifndef __MT6632_FM_LIB_H__ +#define __MT6632_FM_LIB_H__ + +#include "fm_typedef.h" + +enum { + DSPPATCH = 0xFFF9, + USDELAY = 0xFFFA, + MSDELAY = 0xFFFB, + HW_VER = 0xFFFD, + POLL_N = 0xFFFE, /* poling check if bit(n) is '0' */ + POLL_P = 0xFFFF, /* polling check if bit(n) is '1' */ +}; + +enum { + FM_PUS_DSPPATCH = DSPPATCH, + FM_PUS_USDELAY = USDELAY, + FM_PUS_MSDELAY = MSDELAY, + FM_PUS_HW_VER = HW_VER, + FM_PUS_POLL_N = POLL_N, /* poling check if bit(n) is '0' */ + FM_PUS_POLL_P = POLL_P, /* polling check if bit(n) is '1' */ + FM_PUS_MAX +}; + +enum { + mt6632_E1 = 0, + mt6632_E2 +}; + +struct mt6632_fm_cqi { + unsigned short ch; + unsigned short rssi; + unsigned short reserve; +}; + +struct adapt_fm_cqi { + signed int ch; + signed int rssi; + signed int reserve; +}; + +struct mt6632_full_cqi { + unsigned short ch; + unsigned short rssi; + unsigned short pamd; + unsigned short pr; + unsigned short fpamd; + unsigned short mr; + unsigned short atdc; + unsigned short prx; + unsigned short atdev; + unsigned short smg; /* soft-mute gain */ + unsigned short drssi; /* delta rssi */ +}; + +#endif diff --git a/drivers/misc/mediatek/connectivity/fmradio/chips/mt6632/inc/mt6632_fm_reg.h b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6632/inc/mt6632_fm_reg.h new file mode 100644 index 0000000000000000000000000000000000000000..d1e0f62063abae98803e9aa83d3e75885e101c88 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6632/inc/mt6632_fm_reg.h @@ -0,0 +1,58 @@ +/* +* Copyright (C) 2016 MediaTek Inc. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. +*/ + +#ifndef __MT6632_FM_REG_H__ +#define __MT6632_FM_REG_H__ + +/* RDS_BDGRP_ABD_CTRL_REG */ +enum { + BDGRP_ABD_EN = 0x0001, + BER_RUN = 0x2000 +}; +#define FM_DAC_CON1 0x83 +#define FM_DAC_CON2 0x84 +#define FM_FT_CON0 0x86 +enum { + FT_EN = 0x0001 +}; + +#define FM_I2S_CON0 0x90 +enum { + I2S_EN = 0x0001, + FORMAT = 0x0002, + WLEN = 0x0004, + I2S_SRC = 0x0008 +}; + +/* FM_MAIN_CTRL */ +enum { + TUNE = 0x0001, + SEEK = 0x0002, + SCAN = 0x0004, + CQI_READ = 0x0008, + RDS_MASK = 0x0010, + MUTE = 0x0020, + RDS_BRST = 0x0040, + RAMP_DOWN = 0x0100, +}; + +enum { + ANTENNA_TYPE = 0x0010, /* 0x61 D4, 0:long, 1:short */ + ANALOG_I2S = 0x0080, /* 0x61 D7, 0:lineout, 1:I2S */ + DE_EMPHASIS = 0x1000, /* 0x61 D12,0:50us, 1:75 us */ +}; + +#define OSC_FREQ_BITS 0x0070 /* 0x60 bit4~6 */ +#define OSC_FREQ_MASK (~OSC_FREQ_BITS) + +#endif /* __MT6632_FM_REG_H__ */ diff --git a/drivers/misc/mediatek/connectivity/fmradio/chips/mt6632/pub/mt6632_fm_lib.c b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6632/pub/mt6632_fm_lib.c new file mode 100644 index 0000000000000000000000000000000000000000..0d17b1699df32436855d388bad1950225b846d42 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6632/pub/mt6632_fm_lib.c @@ -0,0 +1,1793 @@ +/* +* Copyright (C) 2016 MediaTek Inc. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. +*/ + +#include +#include + +#include "stp_exp.h" +#include "wmt_exp.h" + +#include "fm_typedef.h" +#include "fm_dbg.h" +#include "fm_err.h" +#include "fm_interface.h" +#include "fm_stdlib.h" +#include "fm_patch.h" +#include "fm_utils.h" +#include "fm_link.h" +#include "fm_config.h" +#include "fm_cmd.h" + +#include "mt6632_fm_reg.h" +#include "mt6632_fm_lib.h" + +static struct fm_patch_tbl mt6632_patch_tbl[5] = { + {FM_ROM_V1, "mt6632_fm_v1_patch.bin", "mt6632_fm_v1_coeff.bin", NULL, NULL}, + {FM_ROM_V2, "mt6632_fm_v2_patch.bin", "mt6632_fm_v2_coeff.bin", NULL, NULL}, + {FM_ROM_V3, "mt6632_fm_v3_patch.bin", "mt6632_fm_v3_coeff.bin", NULL, NULL}, + {FM_ROM_V4, "mt6632_fm_v4_patch.bin", "mt6632_fm_v4_coeff.bin", NULL, NULL}, + {FM_ROM_V5, "mt6632_fm_v5_patch.bin", "mt6632_fm_v5_coeff.bin", NULL, NULL}, +}; + + +static struct fm_hw_info mt6632_hw_info = { + .chip_id = 0x00006632, + .eco_ver = 0x00000000, + .rom_ver = 0x00000000, + .patch_ver = 0x00000000, + .reserve = 0x00000000, +}; + +static struct fm_callback *fm_cb_op; +static unsigned char fm_packaging = 1; /*0:QFN,1:WLCSP */ +static unsigned int fm_sant_flag; /* 1,Short Antenna; 0, Long Antenna */ +static signed int mt6632_is_dese_chan(unsigned short freq); +#if 0 +static signed int mt6632_mcu_dese(unsigned short freq, void *arg); +#endif +static signed int mt6632_gps_dese(unsigned short freq, void *arg); + +static signed int mt6632_I2s_Setting(signed int onoff, signed int mode, signed int sample); +static unsigned short mt6632_chan_para_get(unsigned short freq); +static signed int mt6632_desense_check(unsigned short freq, signed int rssi); +static bool mt6632_TDD_chan_check(unsigned short freq); +static signed int mt6632_soft_mute_tune(unsigned short freq, signed int *rssi, signed int *valid); +static signed int mt6632_pwron(signed int data) +{ + if (mtk_wcn_wmt_func_on(WMTDRV_TYPE_FM) == MTK_WCN_BOOL_FALSE) { + WCN_DBG(FM_ERR | CHIP, "WMT turn on FM Fail!\n"); + return -FM_ELINK; + } + + WCN_DBG(FM_NTC | CHIP, "WMT turn on FM OK!\n"); + return 0; +} + +static signed int mt6632_pwroff(signed int data) +{ + if (mtk_wcn_wmt_func_off(WMTDRV_TYPE_FM) == MTK_WCN_BOOL_FALSE) { + WCN_DBG(FM_ERR | CHIP, "WMT turn off FM Fail!\n"); + return -FM_ELINK; + } + + WCN_DBG(FM_NTC | CHIP, "WMT turn off FM OK!\n"); + return 0; +} + +static unsigned short mt6632_get_chipid(void) +{ + return 0x6632; +} + +/* MT6632_SetAntennaType - set Antenna type + * @type - 1,Short Antenna; 0, Long Antenna + */ +static signed int mt6632_SetAntennaType(signed int type) +{ + unsigned short dataRead = 0; + + WCN_DBG(FM_NTC | CHIP, "set ana to %s\n", type ? "short" : "long"); + if (fm_packaging == 0) { + fm_sant_flag = type; + } else { + fm_reg_read(FM_MAIN_CG2_CTRL, &dataRead); + + if (type) + dataRead |= ANTENNA_TYPE; + else + dataRead &= (~ANTENNA_TYPE); + + fm_reg_write(FM_MAIN_CG2_CTRL, dataRead); + } + return 0; +} + +static signed int mt6632_GetAntennaType(void) +{ + unsigned short dataRead = 0; + + if (fm_packaging == 0) + return fm_sant_flag; + + fm_reg_read(FM_MAIN_CG2_CTRL, &dataRead); + WCN_DBG(FM_NTC | CHIP, "get ana type: %s\n", (dataRead & ANTENNA_TYPE) ? "short" : "long"); + + if (dataRead & ANTENNA_TYPE) + return FM_ANA_SHORT; /* short antenna */ + else + return FM_ANA_LONG; /* long antenna */ +} + +static signed int mt6632_Mute(bool mute) +{ + signed int ret = 0; + unsigned short dataRead = 0; + + WCN_DBG(FM_NTC | CHIP, "set %s\n", mute ? "mute" : "unmute"); + fm_reg_read(FM_MAIN_CTRL, &dataRead); + + if (mute == 1) + ret = fm_reg_write(FM_MAIN_CTRL, (dataRead & 0xFFDF) | 0x0020); + else + ret = fm_reg_write(FM_MAIN_CTRL, (dataRead & 0xFFDF)); + + return ret; +} + +static signed int mt6632_rampdown_reg_op(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 4; + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + /* Clear DSP state */ + pkt_size += fm_bop_modify(FM_MAIN_CTRL, 0xFFF0, 0x0000, &buf[pkt_size], buf_size - pkt_size); + /* Set DSP ramp down state */ + pkt_size += fm_bop_modify(FM_MAIN_CTRL, 0xFEFF, RAMP_DOWN, &buf[pkt_size], buf_size - pkt_size); + /* @Wait for STC_DONE interrupt@ */ + pkt_size += fm_bop_rd_until(FM_MAIN_INTR, FM_INTR_STC_DONE, FM_INTR_STC_DONE, &buf[pkt_size], + buf_size - pkt_size); + /* Clear DSP ramp down state */ + pkt_size += fm_bop_modify(FM_MAIN_CTRL, (~RAMP_DOWN), 0x0000, &buf[pkt_size], buf_size - pkt_size); + /* Write 1 clear the STC_DONE interrupt status flag */ + pkt_size += fm_bop_modify(FM_MAIN_INTR, 0xFFFE, FM_INTR_STC_DONE, &buf[pkt_size], buf_size - pkt_size); + + return pkt_size - 4; +} +/* + * mt6632_rampdown - f/w will wait for STC_DONE interrupt + * @buf - target buf + * @buf_size - buffer size + * return package size + */ +static signed int mt6632_rampdown(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 0; + + pkt_size = mt6632_rampdown_reg_op(buf, buf_size); + return fm_op_seq_combine_cmd(buf, FM_RAMPDOWN_OPCODE, pkt_size); +} + +static signed int mt6632_RampDown(void) +{ + signed int ret = 0; + unsigned short pkt_size; + /* unsigned short tmp; */ + + WCN_DBG(FM_NTC | CHIP, "ramp down\n"); + + ret = fm_reg_write(FM_MAIN_EXTINTRMASK, 0x0000); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "ramp down write FM_MAIN_EXTINTRMASK failed\n"); + return ret; + } + + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = mt6632_rampdown(cmd_buf, TX_BUF_SIZE); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_RAMPDOWN, SW_RETRY_CNT, RAMPDOWN_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + + if (ret) { + WCN_DBG(FM_ERR | CHIP, "ramp down failed\n"); + return ret; + } + + ret = fm_reg_write(FM_MAIN_EXTINTRMASK, 0x0021); + if (ret) + WCN_DBG(FM_ERR | CHIP, "ramp down write FM_MAIN_EXTINTRMASK failed\n"); + + return ret; +} + +static signed int mt6632_get_rom_version(void) +{ + unsigned short tmp = 0; + signed int ret = 0; + + /* set download dsp coefficient mode */ + fm_reg_write(0x90, 0xe); + /* fill in coefficient data */ + fm_reg_write(0x92, 0x0); + /* reset download control */ + fm_reg_write(0x90, 0x40); + /* disable memory control from host */ + fm_reg_write(0x90, 0x0); + + /* DSP rom code version request enable --- set 0x61 b15=1 */ + fm_set_bits(0x61, 0x8000, 0x7FFF); + + /* Release ASIP reset --- set 0x61 b1=1 */ + fm_set_bits(0x61, 0x0002, 0xFFFD); + + /* Enable ASIP power --- set 0x61 b0=0 */ + fm_set_bits(0x61, 0x0000, 0xFFFE); + + /* Wait DSP code version ready --- wait 1ms */ + do { + fm_delayus(1000); + ret = fm_reg_read(0x84, &tmp); + /* ret=-4 means signal got when control FM. usually get sig 9 to kill FM process. */ + /* now cancel FM power up sequence is recommended. */ + if (ret) + return ret; + + WCN_DBG(FM_DBG | CHIP, "0x84=%x\n", tmp); + } while (tmp != 0x0001); + + /* Get FM DSP code version --- rd 0x83[15:8] */ + fm_reg_read(0x83, &tmp); + WCN_DBG(FM_NTC | CHIP, "DSP ver=0x%x\n", tmp); + tmp = (tmp >> 8); + + /* DSP rom code version request disable --- set 0x61 b15=0 */ + fm_set_bits(0x61, 0x0000, 0x7FFF); + + /* Reset ASIP --- set 0x61[1:0] = 1 */ + fm_set_bits(0x61, 0x0001, 0xFFFC); + + /* WCN_DBG(FM_NTC | CHIP, "ROM version: v%d\n", (signed int)tmp); */ + return (signed int) tmp; +} + +static signed int mt6632_pmic_read(unsigned char addr, unsigned int *val) +{ + signed int ret = 0; + unsigned char read_reslut = 0xff; + unsigned short pkt_size; + + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = fm_pmic_get_reg(cmd_buf, TX_BUF_SIZE, addr); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_PMIC_READ, SW_RETRY_CNT, PMIC_CONTROL_TIMEOUT, fm_get_read_result); + FM_UNLOCK(cmd_buf_lock); + + if (!ret && fm_res) { + fm_memcpy(val, &fm_res->pmic_result[0], sizeof(unsigned int)); + read_reslut = fm_res->pmic_result[4]; + } else { + WCN_DBG(FM_ERR | CHIP, "mt6632_pmic_read failed,ret(%d)\n", ret); + return -1; + } + + if (read_reslut) { + WCN_DBG(FM_ERR | CHIP, "mt6632_pmic_read failed(%02x)\n", read_reslut); + return -2; + } + return ret; +} + +static signed int mt6632_pmic_write(unsigned char addr, unsigned int val) +{ + signed int ret = 0; + unsigned char read_reslut = 0xff; + unsigned short pkt_size; + + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = fm_pmic_set_reg(cmd_buf, TX_BUF_SIZE, addr, val); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_PMIC_MODIFY, SW_RETRY_CNT, + PMIC_CONTROL_TIMEOUT, fm_get_read_result); + FM_UNLOCK(cmd_buf_lock); + + if (!ret && fm_res) + read_reslut = fm_res->pmic_result[0]; + else { + WCN_DBG(FM_ERR | CHIP, "mt6632_pmic_write failed,ret(%d)\n", ret); + return -1; + } + + if (read_reslut) { + WCN_DBG(FM_ERR | CHIP, "mt6632_pmic_write failed(%02x)\n", read_reslut); + return -2; + } + + return ret; +} + +static signed int mt6632_pmic_mod(unsigned char addr, unsigned int mask_and, unsigned int mask_or) +{ + signed int ret = 0; + unsigned char read_reslut = 0xff; + unsigned short pkt_size; + + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = fm_pmic_mod_reg(cmd_buf, TX_BUF_SIZE, addr, mask_and, mask_or); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_PMIC_MODIFY, SW_RETRY_CNT, + PMIC_CONTROL_TIMEOUT, fm_get_read_result); + FM_UNLOCK(cmd_buf_lock); + + if (!ret && fm_res) + read_reslut = fm_res->pmic_result[0]; + else { + WCN_DBG(FM_ERR | CHIP, "mt6632_pmic_mod failed,ret(%d)\n", ret); + return -1; + } + + if (read_reslut) { + WCN_DBG(FM_ERR | CHIP, "mt6632_pmic_mod failed(%02x)\n", read_reslut); + return -2; + } + return ret; +} + +static signed int mt6632_pmic_ctrl(void) +{ + signed int ret = 0; + unsigned int val = 0; + + ret = mt6632_pmic_mod(0xa8, 0xFFFFFFF7, 0x00000008); + if (!ret) { + mt6632_pmic_read(0xa8, &val); + WCN_DBG(FM_NTC | CHIP, "0xa8 = %08x\n", val); + } else { + WCN_DBG(FM_ERR | CHIP, "mt6632_pmic_ctrl 0xa8 failed(%d)\n", ret); + return ret; + } + + ret = mt6632_pmic_mod(0xc7, 0x7FFFFFCF, 0x00000000); + if (!ret) { + mt6632_pmic_read(0xc7, &val); + WCN_DBG(FM_NTC | CHIP, "0xc7 = %08x\n", val); + } else { + WCN_DBG(FM_ERR | CHIP, "mt6632_pmic_ctrl 0xc7 failed(%d)\n", ret); + return ret; + } + + return ret; +} + +static signed int mt6632_pwrup_top_setting(void) +{ + signed int ret = 0, value = 0; + /* A0.1 Turn on FM buffer */ + ret = fm_host_reg_read(0x81020008, &value); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x81020008 rd failed\n"); + return ret; + } + ret = fm_host_reg_write(0x81020008, value | 0x30); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x81020008 wr failed\n"); + return ret; + } + /* A0.2 Set xtal no off when FM on */ + fm_delayus(20); + /* A0.3 release power on reset */ + ret = fm_host_reg_read(0x81020008, &value); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x81020008 rd failed\n"); + return ret; + } + ret = fm_host_reg_write(0x81020008, value | 0x1); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x81020008 wr failed\n"); + return ret; + } + /* A0.4 enable fspi_mas_bclk_ck */ + ret = fm_host_reg_read(0x80000108, &value); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x80000108 rd failed\n"); + return ret; + } + ret = fm_host_reg_write(0x80000108, value | 0x00000100); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x80000108 wr failed\n"); + return ret; + } + return ret; +} + +static signed int mt6632_pwrdown_top_setting(void) +{ + signed int ret = 0, value = 0; + /* B0.1 disable fspi_mas_bclk_ck */ + ret = fm_host_reg_read(0x80000104, &value); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x80000104 rd failed\n"); + return ret; + } + ret = fm_host_reg_write(0x80000104, value | 0x00000100); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x80000104 wr failed\n"); + return ret; + } + /* B0.2 set power off reset */ + ret = fm_host_reg_read(0x81020008, &value); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x81020008 rd failed\n"); + return ret; + } + ret = fm_host_reg_write(0x81020008, value & 0xFFFFFFFE); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x81020008 wr failed\n"); + return ret; + } + /* B0.3 */ + fm_delayus(20); + + /* B0.4 disable MTCMOS & set Iso_en */ + ret = fm_host_reg_read(0x81020008, &value); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x81020008 rd failed\n"); + return ret; + } + ret = fm_host_reg_write(0x81020008, value & 0xFFFFFFEF); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x81020008 wr failed\n"); + return ret; + } +#if 0 + /* B0.5 Turn off FM buffer */ + ret = fm_host_reg_read(0x8102123c, &value); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x8102123c rd failed\n"); + return ret; + } + ret = fm_host_reg_write(0x8102123c, value | 0x40); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x8102123c wr failed\n"); + return ret; + } + /* B0.6 Clear xtal no off when FM off */ + ret = fm_host_reg_read(0x81021134, &value); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x81021134 rd failed\n"); + return ret; + } + ret = fm_host_reg_write(0x81021134, value & 0xFFFFFF7F); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x81021134 wr failed\n"); + return ret; + } + /* B0.7 Clear top off always on when FM off */ + ret = fm_host_reg_read(0x81020010, &value); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x81020010 rd failed\n"); + return ret; + } + ret = fm_host_reg_write(0x81020010, value | 0x20000); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x81020010 wr failed\n"); + return ret; + } + /* B0.9 Disable PALDO when FM off */ + ret = fm_host_reg_read(0x81021430, &value); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x81021430 rd failed\n"); + return ret; + } + ret = fm_host_reg_write(0x81021430, value & 0x7FFFFFFF); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " 0x81021430 wr failed\n"); + return ret; + } +#endif + return ret; +} + +static signed int mt6632_pwrup_DSP_download(struct fm_patch_tbl *patch_tbl) +{ +#define PATCH_BUF_SIZE (4096*6) + signed int ret = 0; + signed int patch_len = 0; + unsigned char *dsp_buf = NULL; + unsigned short tmp_reg = 0; + + mt6632_hw_info.eco_ver = (signed int) mtk_wcn_wmt_ic_info_get(1); + WCN_DBG(FM_NTC | CHIP, "ECO version:0x%08x\n", mt6632_hw_info.eco_ver); + + /* FM ROM code version request */ + ret = mt6632_get_rom_version(); + if (ret >= 0) { + mt6632_hw_info.rom_ver = ret; + WCN_DBG(FM_NTC | CHIP, "ROM version: v%d\n", mt6632_hw_info.rom_ver); + } else { + WCN_DBG(FM_ERR | CHIP, "get ROM version failed\n"); + /* ret=-4 means signal got when control FM. usually get sig 9 to kill FM process. */ + /* now cancel FM power up sequence is recommended. */ + return ret; + } + + /* Wholechip FM Power Up: step 3, download patch */ + dsp_buf = fm_vmalloc(PATCH_BUF_SIZE); + if (!dsp_buf) { + WCN_DBG(FM_ERR | CHIP, "-ENOMEM\n"); + return -ENOMEM; + } + + patch_len = fm_get_patch_path(mt6632_hw_info.rom_ver, dsp_buf, PATCH_BUF_SIZE, patch_tbl); + if (patch_len <= 0) { + WCN_DBG(FM_ALT | CHIP, " fm_get_patch_path failed\n"); + ret = patch_len; + goto out; + } + + ret = fm_download_patch((const unsigned char *)dsp_buf, patch_len, IMG_PATCH); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " DL DSPpatch failed\n"); + goto out; + } + + patch_len = fm_get_coeff_path(mt6632_hw_info.rom_ver, dsp_buf, PATCH_BUF_SIZE, patch_tbl); + if (patch_len <= 0) { + WCN_DBG(FM_ALT | CHIP, " fm_get_coeff_path failed\n"); + ret = patch_len; + goto out; + } + + mt6632_hw_info.rom_ver += 1; + + tmp_reg = dsp_buf[38] | (dsp_buf[39] << 8); /* to be confirmed */ + mt6632_hw_info.patch_ver = (signed int) tmp_reg; + WCN_DBG(FM_NTC | CHIP, "Patch version: 0x%08x\n", mt6632_hw_info.patch_ver); + + ret = fm_download_patch((const unsigned char *)dsp_buf, patch_len, IMG_COEFFICIENT); + if (ret) { + WCN_DBG(FM_ERR | CHIP, " DL DSPcoeff failed\n"); + goto out; + } + fm_reg_write(0x90, 0x0040); + fm_reg_write(0x90, 0x0000); +out: + if (dsp_buf) { + fm_vfree(dsp_buf); + dsp_buf = NULL; + } + return ret; +} + +static signed int mt6632_pwrup_clock_on_reg_op(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 4; + unsigned short de_emphasis; + /* unsigned short osc_freq; */ + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + de_emphasis = fm_config.rx_cfg.deemphasis; + de_emphasis &= 0x0001; /* rang 0~1 */ + + /* B1.1 Enable digital OSC */ + pkt_size += fm_bop_write(0x60, 0x0003, &buf[pkt_size], buf_size - pkt_size); /* wr 60 3 */ + pkt_size += fm_bop_udelay(100, &buf[pkt_size], buf_size - pkt_size); /* delay 100us */ + /* B1.3 Release HW clock gating */ + pkt_size += fm_bop_write(0x60, 0x0007, &buf[pkt_size], buf_size - pkt_size); /* wr 60 7 */ + /* B1.4 Set FM long/short antenna:1: short_antenna 0: long antenna(default) */ + /* pkt_size += fm_bop_modify(0x61, 0xFFEF, 0x0000, &buf[pkt_size], buf_size - pkt_size); */ + /* B1.5 Set audio output mode (lineout/I2S) 0:lineout, 1:I2S */ + /* + *if (mt6632_fm_config.aud_cfg.aud_path == FM_AUD_ANALOG) + * pkt_size += fm_bop_modify(0x61, 0xFF7F, 0x0000, &buf[pkt_size], buf_size - pkt_size); + *else + * pkt_size += fm_bop_modify(0x61, 0xFF7F, 0x0080, &buf[pkt_size], buf_size - pkt_size); + */ + /* B1.6 Set deemphasis setting */ + pkt_size += fm_bop_modify(0x61, ~DE_EMPHASIS, (de_emphasis << 12), &buf[pkt_size], buf_size - pkt_size); + + /* pkt_size += fm_bop_modify(0x60, OSC_FREQ_MASK, (osc_freq << 4), &buf[pkt_size], buf_size - pkt_size); */ + + return pkt_size - 4; +} +/* + * mt6632_pwrup_clock_on - Wholechip FM Power Up: step 1, FM Digital Clock enable + * @buf - target buf + * @buf_size - buffer size + * return package size + */ +static signed int mt6632_pwrup_clock_on(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 0; + + pkt_size = mt6632_pwrup_clock_on_reg_op(buf, buf_size); + return fm_op_seq_combine_cmd(buf, FM_ENABLE_OPCODE, pkt_size); +} + +static signed int mt6632_pwrup_digital_init_reg_op(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 4; + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + /* F1.4 Set appropriate interrupt mask behavior as desired(RX) */ + /* pkt_size += fm_bop_write(0x6A, 0x0021, &buf[pkt_size], buf_size - pkt_size);//wr 6A 0021 */ + pkt_size += fm_bop_write(0x6B, 0x0021, &buf[pkt_size], buf_size - pkt_size); /* wr 6B 0021 */ + /* F1.9 Enable HW auto control */ + pkt_size += fm_bop_write(0x60, 0x000F, &buf[pkt_size], buf_size - pkt_size); /* wr 60 f */ + /* F1.10 Release ASIP reset */ + pkt_size += fm_bop_modify(0x61, 0xFFFD, 0x0002, &buf[pkt_size], buf_size - pkt_size); /* wr 61 D1=1 */ + /* F1.11 Enable ASIP power */ + pkt_size += fm_bop_modify(0x61, 0xFFFE, 0x0000, &buf[pkt_size], buf_size - pkt_size); /* wr 61 D0=0 */ + pkt_size += fm_bop_udelay(100000, &buf[pkt_size], buf_size - pkt_size); /* delay 100ms */ + /* F1.13 Check HW intitial complete */ + pkt_size += fm_bop_rd_until(0x64, 0x001F, 0x0002, &buf[pkt_size], buf_size - pkt_size); /* Poll 64[0~4] = 2 */ + + return pkt_size - 4; +} + +/* + * mt6632_pwrup_digital_init - Wholechip FM Power Up: step 4, FM Digital Init: fm_rgf_maincon + * @buf - target buf + * @buf_size - buffer size + * return package size + */ +static signed int mt6632_pwrup_digital_init(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 0; + + pkt_size = mt6632_pwrup_digital_init_reg_op(buf, buf_size); + return fm_op_seq_combine_cmd(buf, FM_ENABLE_OPCODE, pkt_size); +} + +static signed int mt6632_pwrdown_reg_op(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 4; + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + /* Disable HW clock control */ + pkt_size += fm_bop_write(0x60, 0x0107, &buf[pkt_size], buf_size - pkt_size); /* wr 60 107 */ + /* Reset ASIP */ + pkt_size += fm_bop_write(0x61, 0x0001, &buf[pkt_size], buf_size - pkt_size); /* wr 61 0001 */ + /* digital core + digital rgf reset */ + pkt_size += fm_bop_modify(0x6E, 0xFFF8, 0x0000, &buf[pkt_size], buf_size - pkt_size); /* wr 6E[0~2] 0 */ + pkt_size += fm_bop_modify(0x6E, 0xFFF8, 0x0000, &buf[pkt_size], buf_size - pkt_size); /* wr 6E[0~2] 0 */ + pkt_size += fm_bop_modify(0x6E, 0xFFF8, 0x0000, &buf[pkt_size], buf_size - pkt_size); /* wr 6E[0~2] 0 */ + pkt_size += fm_bop_modify(0x6E, 0xFFF8, 0x0000, &buf[pkt_size], buf_size - pkt_size); /* wr 6E[0~2] 0 */ + /* Disable all clock */ + pkt_size += fm_bop_write(0x60, 0x0000, &buf[pkt_size], buf_size - pkt_size); /* wr 60 0000 */ + /* Reset rgfrf */ + pkt_size += fm_bop_write(0x60, 0x4000, &buf[pkt_size], buf_size - pkt_size); /* wr 60 4000 */ + pkt_size += fm_bop_write(0x60, 0x0000, &buf[pkt_size], buf_size - pkt_size); /* wr 60 0000 */ + + return pkt_size - 4; +} +/* + * mt6632_pwrdown - Wholechip FM Power down: Digital Modem Power Down + * @buf - target buf + * @buf_size - buffer size + * return package size + */ +static signed int mt6632_pwrdown(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 0; + + pkt_size = mt6632_pwrdown_reg_op(buf, buf_size); + return fm_op_seq_combine_cmd(buf, FM_ENABLE_OPCODE, pkt_size); +} + +static signed int mt6632_tune_reg_op(unsigned char *buf, signed int buf_size, unsigned short freq, + unsigned short chan_para) +{ + signed int pkt_size = 4; + + WCN_DBG(FM_ALT | CHIP, "%s enter mt6632_tune function\n", __func__); + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + if (fm_get_channel_space(freq) == 0) + freq *= 10; + + freq = (freq - 6400) * 2 / 10; + + /* Set desired channel & channel parameter */ +#ifdef FM_TUNE_USE_POLL + pkt_size += fm_bop_write(0x6A, 0x0000, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x6B, 0x0000, &buf[pkt_size], buf_size - pkt_size); +#endif + pkt_size += fm_bop_modify(FM_CHANNEL_SET, 0xFC00, freq, &buf[pkt_size], buf_size - pkt_size); + /* channel para setting, D15~D12, D15: ATJ, D13: HL, D12: FA */ + pkt_size += fm_bop_modify(FM_CHANNEL_SET, 0x0FFF, (chan_para << 12), &buf[pkt_size], buf_size - pkt_size); + /* Enable hardware controlled tuning sequence */ + pkt_size += fm_bop_modify(FM_MAIN_CTRL, 0xFFF8, TUNE, &buf[pkt_size], buf_size - pkt_size); + /* Wait for STC_DONE interrupt */ +#ifdef FM_TUNE_USE_POLL + pkt_size += fm_bop_rd_until(FM_MAIN_INTR, FM_INTR_STC_DONE, FM_INTR_STC_DONE, &buf[pkt_size], + buf_size - pkt_size); + /* Write 1 clear the STC_DONE interrupt status flag */ + pkt_size += fm_bop_modify(FM_MAIN_INTR, 0xFFFF, FM_INTR_STC_DONE, &buf[pkt_size], buf_size - pkt_size); +#endif + + WCN_DBG(FM_ALT | CHIP, "%s leave mt6632_tune function\n", __func__); + + return pkt_size - 4; +} + +/* + * mt6632_tune - execute tune action, + * @buf - target buf + * @buf_size - buffer size + * @freq - 760 ~ 1080, 100KHz unit + * return package size + */ +static signed int mt6632_tune(unsigned char *buf, signed int buf_size, unsigned short freq, + unsigned short chan_para) +{ + signed int pkt_size = 0; + + pkt_size = mt6632_tune_reg_op(buf, buf_size, freq, chan_para); + return fm_op_seq_combine_cmd(buf, FM_TUNE_OPCODE, pkt_size); +} + +static signed int mt6632_PowerUp(unsigned short *chip_id, unsigned short *device_id) +{ + signed int ret = 0; + unsigned short pkt_size; + unsigned short tmp_reg = 0; + + if (chip_id == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (device_id == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + WCN_DBG(FM_DBG | CHIP, "pwr on seq......\n"); + + ret = mt6632_pmic_ctrl(); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "mt6632_pmic_ctrl failed\n"); + return ret; + } + fm_delayus(240); + + ret = mt6632_pwrup_top_setting(); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "mt6632_pwrup_top_setting failed\n"); + return ret; + } + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = mt6632_pwrup_clock_on(cmd_buf, TX_BUF_SIZE); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + + if (ret) { + WCN_DBG(FM_ERR | CHIP, "mt6632_pwrup_clock_on failed\n"); + return ret; + } + /* read HW version */ + fm_reg_read(0x62, &tmp_reg); + *chip_id = tmp_reg; + *device_id = tmp_reg; + mt6632_hw_info.chip_id = (signed int) tmp_reg; + WCN_DBG(FM_NTC | CHIP, "chip_id:0x%04x\n", tmp_reg); + + if (mt6632_hw_info.chip_id != 0x6632) { + WCN_DBG(FM_NTC | CHIP, "fm sys error!\n"); + return -FM_EPARA; + } + ret = mt6632_pwrup_DSP_download(mt6632_patch_tbl); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "mt6632_pwrup_DSP_download failed\n"); + return ret; + } + + if ((fm_config.aud_cfg.aud_path == FM_AUD_MRGIF) + || (fm_config.aud_cfg.aud_path == FM_AUD_I2S)) { + mt6632_I2s_Setting(FM_I2S_ON, fm_config.aud_cfg.i2s_info.mode, + fm_config.aud_cfg.i2s_info.rate); + /* mt_combo_audio_ctrl(COMBO_AUDIO_STATE_2); */ + mtk_wcn_cmb_stub_audio_ctrl((CMB_STUB_AIF_X) CMB_STUB_AIF_2); + } + /* Wholechip FM Power Up: step 4, FM Digital Init: fm_rgf_maincon */ + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = mt6632_pwrup_digital_init(cmd_buf, TX_BUF_SIZE); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "mt6632_pwrup_digital_init failed\n"); + return ret; + } + + /* FM RF fine tune setting */ + fm_reg_write(0x60, 0x7); + fm_reg_write(0x2d, 0x1fa); + fm_reg_write(0x60, 0xF); + + WCN_DBG(FM_NTC | CHIP, "pwr on seq ok\n"); + + return ret; +} + +static signed int mt6632_PowerDown(void) +{ + signed int ret = 0; + unsigned short pkt_size; + + WCN_DBG(FM_DBG | CHIP, "pwr down seq\n"); + + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = mt6632_pwrdown(cmd_buf, TX_BUF_SIZE); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + + if (ret) { + WCN_DBG(FM_ERR | CHIP, "mt6632_pwrdown failed\n"); + return ret; + } + + ret = mt6632_pwrdown_top_setting(); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "mt6632_pwrdown_top_setting failed\n"); + return ret; + } + + return ret; +} + +/* just for dgb */ +static bool mt6632_SetFreq(unsigned short freq) +{ + signed int ret = 0; + unsigned short pkt_size; + unsigned short chan_para = 0; + unsigned short tmp_reg[4]; + + fm_cb_op->cur_freq_set(freq); + +#if 0 + /* MCU clock adjust if need */ + ret = mt6632_mcu_dese(freq, NULL); + if (ret < 0) + WCN_DBG(FM_ERR | MAIN, "mt6632_mcu_dese FAIL:%d\n", ret); + + WCN_DBG(FM_INF | MAIN, "MCU %d\n", ret); +#endif + + /* GPS clock adjust if need */ + ret = mt6632_gps_dese(freq, NULL); + if (ret < 0) + WCN_DBG(FM_ERR | MAIN, "mt6632_gps_dese FAIL:%d\n", ret); + + WCN_DBG(FM_INF | MAIN, "GPS %d\n", ret); + + ret = fm_reg_write(0x60, 0x0007); + if (ret) + WCN_DBG(FM_ALT | MAIN, "set freq write 0x60 fail\n"); + + if (mt6632_TDD_chan_check(freq)) { + ret = fm_set_bits(0x30, 0x0004, 0xFFF9); /* use TDD solution */ + if (ret) + WCN_DBG(FM_ALT | MAIN, "set freq write 0x30 fail\n"); + } else { + ret = fm_set_bits(0x30, 0x0000, 0xFFF9); /* default use FDD solution */ + if (ret) + WCN_DBG(FM_ALT | MAIN, "set freq write 0x30 fail\n"); + } + ret = fm_reg_write(0x60, 0x000F); + if (ret) + WCN_DBG(FM_ALT | MAIN, "set freq write 0x60 fail\n"); + + chan_para = mt6632_chan_para_get(freq); + WCN_DBG(FM_DBG | CHIP, "%d chan para = %d\n", (signed int) freq, (signed int) chan_para); + + if (FM_LOCK(cmd_buf_lock)) + return false; + pkt_size = mt6632_tune(cmd_buf, TX_BUF_SIZE, freq, chan_para); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_TUNE | FLAG_TUNE_DONE, SW_RETRY_CNT, TUNE_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + + if (ret) { + fm_reg_read(0x64, &tmp_reg[0]); + fm_reg_read(0x69, &tmp_reg[1]); + fm_reg_read(0x6c, &tmp_reg[2]); + WCN_DBG(FM_ERR | CHIP, "mt6632_tune failed\n"); + WCN_DBG(FM_ERR | CHIP, "0x64[0x%04x],0x69[0x%04x],0x6c[0x%04x]\n", tmp_reg[0], tmp_reg[1], tmp_reg[2]); + return false; + } + + WCN_DBG(FM_DBG | CHIP, "set freq to %d ok\n", freq); + return true; +} + +#define FM_CQI_LOG_PATH "/mnt/sdcard/fmcqilog" + +static signed int mt6632_full_cqi_get(signed int min_freq, signed int max_freq, signed int space, signed int cnt) +{ + signed int ret = 0; + unsigned short pkt_size; + unsigned short freq, orig_freq; + signed int i, j, k; + signed int space_val, max, min, num; + struct mt6632_full_cqi *p_cqi; + unsigned char *cqi_log_title = "Freq, RSSI, PAMD, PR, FPAMD, MR, ATDC, PRX, ATDEV, SMGain, DltaRSSI\n"; + unsigned char cqi_log_buf[100] = { 0 }; + signed int pos; + unsigned char cqi_log_path[100] = { 0 }; + + WCN_DBG(FM_DBG | CHIP, "6632 cqi log start\n"); + /* for soft-mute tune, and get cqi */ + freq = fm_cb_op->cur_freq_get(); + if (fm_get_channel_space(freq) == 0) + freq *= 10; + + /* get cqi */ + orig_freq = freq; + if (fm_get_channel_space(min_freq) == 0) + min = min_freq * 10; + else + min = min_freq; + + if (fm_get_channel_space(max_freq) == 0) + max = max_freq * 10; + else + max = max_freq; + + if (space == 0x0001) + space_val = 5; /* 50Khz */ + else if (space == 0x0002) + space_val = 10; /* 100Khz */ + else if (space == 0x0004) + space_val = 20; /* 200Khz */ + else + space_val = 10; + + num = (max - min) / space_val + 1; /* Eg, (8760 - 8750) / 10 + 1 = 2 */ + for (k = 0; (orig_freq == 10000) && (g_dbg_level == 0xffffffff) && (k < cnt); k++) { + WCN_DBG(FM_NTC | CHIP, "cqi file:%d\n", k + 1); + freq = min; + pos = 0; + fm_memcpy(cqi_log_path, FM_CQI_LOG_PATH, strlen(FM_CQI_LOG_PATH)); + if (sprintf(&cqi_log_path[strlen(FM_CQI_LOG_PATH)], "%d.txt", k + 1) < 0) + WCN_DBG(FM_NTC | CHIP, "sprintf fail\n"); + fm_file_write(cqi_log_path, cqi_log_title, strlen(cqi_log_title), &pos); + for (j = 0; j < num; j++) { + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = fm_full_cqi_req(cmd_buf, TX_BUF_SIZE, &freq, 1, 1); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_SM_TUNE, SW_RETRY_CNT, + SM_TUNE_TIMEOUT, fm_get_read_result); + FM_UNLOCK(cmd_buf_lock); + + if (!ret && fm_res) { + WCN_DBG(FM_NTC | CHIP, "smt cqi size %d\n", fm_res->cqi[0]); + p_cqi = (struct mt6632_full_cqi *)&fm_res->cqi[2]; + for (i = 0; i < fm_res->cqi[1]; i++) { + /* just for debug */ + WCN_DBG(FM_NTC | CHIP, + "freq %d, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x\n", + p_cqi[i].ch, p_cqi[i].rssi, p_cqi[i].pamd, + p_cqi[i].pr, p_cqi[i].fpamd, p_cqi[i].mr, + p_cqi[i].atdc, p_cqi[i].prx, p_cqi[i].atdev, + p_cqi[i].smg, p_cqi[i].drssi); + /* format to buffer */ + if (sprintf(cqi_log_buf, + "%04d, %04x, %04x, %04x, %04x, %04x, %04x, %04x, %04x, %04x, %04x,\n", + p_cqi[i].ch, p_cqi[i].rssi, p_cqi[i].pamd, + p_cqi[i].pr, p_cqi[i].fpamd, p_cqi[i].mr, + p_cqi[i].atdc, p_cqi[i].prx, p_cqi[i].atdev, + p_cqi[i].smg, p_cqi[i].drssi) < 0) + WCN_DBG(FM_NTC | CHIP, "sprintf fail\n"); + /* write back to log file */ + fm_file_write(cqi_log_path, cqi_log_buf, strlen(cqi_log_buf), &pos); + } + } else { + WCN_DBG(FM_ERR | CHIP, "smt get CQI failed\n"); + ret = -1; + } + freq += space_val; + } + fm_cb_op->cur_freq_set(0); /* avoid run too much times */ + } + WCN_DBG(FM_DBG | CHIP, "6632 cqi log done\n"); + + return ret; +} + +/* + * mt6632_GetCurRSSI - get current freq's RSSI value + * RS=RSSI + * If RS>511, then RSSI(dBm)= (RS-1024)/16*6 + * else RSSI(dBm)= RS/16*6 + */ +static signed int mt6632_GetCurRSSI(signed int *pRSSI) +{ + unsigned short tmp_reg = 0; + + /* TODO: check reg */ + fm_reg_read(FM_RSSI_IND, &tmp_reg); + tmp_reg = tmp_reg & 0x03ff; + + if (pRSSI) { + *pRSSI = (tmp_reg > 511) ? (((tmp_reg - 1024) * 6) >> 4) : ((tmp_reg * 6) >> 4); + WCN_DBG(FM_DBG | CHIP, "rssi:%d, dBm:%d\n", tmp_reg, *pRSSI); + } else { + WCN_DBG(FM_ERR | CHIP, "get rssi para error\n"); + return -FM_EPARA; + } + + return 0; +} + +static unsigned short mt6632_vol_tbl[16] = { + 0x0000, 0x0519, 0x066A, 0x0814, + 0x0A2B, 0x0CCD, 0x101D, 0x1449, + 0x198A, 0x2027, 0x287A, 0x32F5, + 0x4027, 0x50C3, 0x65AD, 0x7FFF +}; + +static signed int mt6632_SetVol(unsigned char vol) +{ + signed int ret = 0; + + /* TODO: check reg */ + vol = (vol > 15) ? 15 : vol; + ret = fm_reg_write(0x7D, mt6632_vol_tbl[vol]); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "Set vol=%d Failed\n", vol); + return ret; + } + + WCN_DBG(FM_DBG | CHIP, "Set vol=%d OK\n", vol); + + if (vol == 10) { + fm_print_cmd_fifo(); /* just for debug */ + fm_print_evt_fifo(); + } + return 0; +} + +static signed int mt6632_GetVol(unsigned char *pVol) +{ + int ret = 0; + unsigned short tmp = 0; + signed int i; + + if (pVol == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + /* TODO: check reg */ + ret = fm_reg_read(0x7D, &tmp); + if (ret) { + *pVol = 0; + WCN_DBG(FM_ERR | CHIP, "Get vol Failed\n"); + return ret; + } + + for (i = 0; i < 16; i++) { + if (mt6632_vol_tbl[i] == tmp) { + *pVol = i; + break; + } + } + + WCN_DBG(FM_DBG | CHIP, "Get vol=%d OK\n", *pVol); + return 0; +} + +static signed int mt6632_dump_reg(void) +{ + signed int i; + unsigned short TmpReg = 0; + + for (i = 0; i < 0xff; i++) { + fm_reg_read(i, &TmpReg); + WCN_DBG(FM_NTC | CHIP, "0x%02x=0x%04x\n", i, TmpReg); + } + return 0; +} + +static bool mt6632_GetMonoStereo(unsigned short *pMonoStereo) +{ +#define FM_BF_STEREO 0x1000 + unsigned short TmpReg = 0; + + /* TODO: check reg */ + if (pMonoStereo) { + fm_reg_read(FM_RSSI_IND, &TmpReg); + *pMonoStereo = (TmpReg & FM_BF_STEREO) >> 12; + } else { + WCN_DBG(FM_ERR | CHIP, "MonoStero: para err\n"); + return false; + } + + WCN_DBG(FM_DBG | CHIP, "MonoStero:0x%04x\n", *pMonoStereo); + return true; +} + +static signed int mt6632_SetMonoStereo(signed int MonoStereo) +{ + signed int ret = 0; +#define FM_FORCE_MS 0x0008 + + WCN_DBG(FM_DBG | CHIP, "set to %s\n", MonoStereo ? "mono" : "auto"); + /* TODO: check reg */ + + fm_reg_write(0x60, 0x3007); + + if (MonoStereo) + ret = fm_set_bits(0x75, FM_FORCE_MS, ~FM_FORCE_MS); + else + ret = fm_set_bits(0x75, 0x0000, ~FM_FORCE_MS); + + return ret; +} + +static signed int mt6632_GetCapArray(signed int *ca) +{ + unsigned short dataRead = 0; + unsigned short tmp = 0; + + /* TODO: check reg */ + if (ca == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + fm_reg_read(0x60, &tmp); + fm_reg_write(0x60, tmp & 0xFFF7); /* 0x60 D3=0 */ + + fm_reg_read(0x26, &dataRead); + *ca = dataRead; + + fm_reg_write(0x60, tmp); /* 0x60 D3=1 */ + return 0; +} + +/* + * mt6632_GetCurPamd - get current freq's PAMD value + * PA=PAMD + * If PA>511 then PAMD(dB)= (PA-1024)/16*6, + * else PAMD(dB)=PA/16*6 + */ +static bool mt6632_GetCurPamd(unsigned short *pPamdLevl) +{ + unsigned short tmp_reg = 0; + unsigned short dBvalue, valid_cnt = 0; + int i, total = 0; + + for (i = 0; i < 8; i++) { + /* TODO: check reg */ + if (fm_reg_read(FM_ADDR_PAMD, &tmp_reg)) { + *pPamdLevl = 0; + return false; + } + + tmp_reg &= 0x03FF; + dBvalue = (tmp_reg > 256) ? ((512 - tmp_reg) * 6 / 16) : 0; + if (dBvalue != 0) { + total += dBvalue; + valid_cnt++; + WCN_DBG(FM_DBG | CHIP, "[%d]PAMD=%d\n", i, dBvalue); + } + fm_delayms(3); + } + if (valid_cnt != 0) + *pPamdLevl = total / valid_cnt; + else + *pPamdLevl = 0; + + WCN_DBG(FM_NTC | CHIP, "PAMD=%d\n", *pPamdLevl); + return true; +} + +static signed int MT6632_FMOverBT(bool enable) +{ + signed int ret = 0; + + WCN_DBG(FM_NTC | CHIP, "+%s():\n", __func__); + + if (enable == true) { + /* change I2S to slave mode and 48K sample rate */ + if (mt6632_I2s_Setting(FM_I2S_ON, FM_I2S_SLAVE, FM_I2S_48K)) + goto out; + WCN_DBG(FM_NTC | CHIP, "set FM via BT controller\n"); + } else if (enable == false) { + /* change I2S to master mode and 44.1K sample rate */ + if (mt6632_I2s_Setting(FM_I2S_ON, FM_I2S_MASTER, FM_I2S_44K)) + goto out; + WCN_DBG(FM_NTC | CHIP, "set FM via Host\n"); + } else { + WCN_DBG(FM_ERR | CHIP, "%s()\n", __func__); + ret = -FM_EPARA; + goto out; + } +out: + WCN_DBG(FM_NTC | CHIP, "-%s():[ret=%d]\n", __func__, ret); + return ret; +} + +/* + * mt6632_I2s_Setting - set the I2S state on MT6632 + * @onoff - I2S on/off + * @mode - I2S mode: Master or Slave + * + * Return:0, if success; error code, if failed + */ +static signed int mt6632_I2s_Setting(signed int onoff, signed int mode, signed int sample) +{ + unsigned short tmp_state = 0; + unsigned short tmp_mode = 0; + unsigned short tmp_sample = 0; + signed int ret = 0; + + if (onoff == FM_I2S_ON) { + tmp_state = 0x0002; /* I2S enable and standard I2S mode, 0x9B D0,D1=1 */ + fm_config.aud_cfg.i2s_info.status = FM_I2S_ON; + } else if (onoff == FM_I2S_OFF) { + tmp_state = 0x0000; /* I2S off, 0x9B D0,D1=0 */ + fm_config.aud_cfg.i2s_info.status = FM_I2S_OFF; + } else { + WCN_DBG(FM_ERR | CHIP, "%s():[onoff=%d]\n", __func__, onoff); + ret = -FM_EPARA; + goto out; + } + + if (mode == FM_I2S_MASTER) { + tmp_mode = 0x0000; /* 6632 as I2S master, set 0x9B D3=0 */ + fm_config.aud_cfg.i2s_info.mode = FM_I2S_MASTER; + } else if (mode == FM_I2S_SLAVE) { + tmp_mode = 0x0008; /* 6632 as I2S slave, set 0x9B D3=1 */ + fm_config.aud_cfg.i2s_info.mode = FM_I2S_SLAVE; + } else { + WCN_DBG(FM_ERR | CHIP, "%s():[mode=%d]\n", __func__, mode); + ret = -FM_EPARA; + goto out; + } + + if (sample == FM_I2S_32K) { + tmp_sample = 0x0000; /* 6632 I2S 32KHz sample rate, 0x5F D11~12 */ + fm_config.aud_cfg.i2s_info.rate = FM_I2S_32K; + } else if (sample == FM_I2S_44K) { + tmp_sample = 0x0800; /* 6632 I2S 44.1KHz sample rate */ + fm_config.aud_cfg.i2s_info.rate = FM_I2S_44K; + } else if (sample == FM_I2S_48K) { + tmp_sample = 0x1000; /* 6632 I2S 48KHz sample rate */ + fm_config.aud_cfg.i2s_info.rate = FM_I2S_48K; + } else { + WCN_DBG(FM_ERR | CHIP, "%s():[sample=%d]\n", __func__, sample); + ret = -FM_EPARA; + goto out; + } + + ret = fm_reg_write(0x60, 0x0007); + if (ret) + goto out; + + ret = fm_set_bits(0x5F, tmp_sample, 0xE7FF); + if (ret) + goto out; + + ret = fm_set_bits(0x9B, tmp_mode, 0xFFF7); + if (ret) + goto out; + + ret = fm_set_bits(0x9B, tmp_state, 0xFFFD); + if (ret) + goto out; + + ret = fm_reg_write(0x60, 0x000F); + if (ret) + goto out; + WCN_DBG(FM_NTC | CHIP, "[onoff=%s][mode=%s][sample=%d](0)33KHz,(1)44.1KHz,(2)48KHz\n", + (onoff == FM_I2S_ON) ? "On" : "Off", (mode == FM_I2S_MASTER) ? "Master" : "Slave", sample); +out: + return ret; +} + +static signed int mt6632fm_get_audio_info(struct fm_audio_info_t *data) +{ + fm_memcpy(data, &fm_config.aud_cfg, sizeof(struct fm_audio_info_t)); + return 0; +} + +static signed int mt6632_i2s_info_get(signed int *ponoff, signed int *pmode, signed int *psample) +{ + *ponoff = fm_config.aud_cfg.i2s_info.status; + *pmode = fm_config.aud_cfg.i2s_info.mode; + *psample = fm_config.aud_cfg.i2s_info.rate; + + return 0; +} + +static signed int mt6632_hw_info_get(struct fm_hw_info *req) +{ + if (req == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + req->chip_id = mt6632_hw_info.chip_id; + req->eco_ver = mt6632_hw_info.eco_ver; + req->patch_ver = mt6632_hw_info.patch_ver; + req->rom_ver = mt6632_hw_info.rom_ver; + + return 0; +} + +static signed int mt6632_pre_search(void) +{ + mt6632_RampDown(); + return 0; +} + +static signed int mt6632_restore_search(void) +{ + mt6632_RampDown(); + return 0; +} + +/* +*freq: 8750~10800 +*valid: true-valid channel,false-invalid channel +*return: true- smt success, false-smt fail +*/ +static signed int mt6632_soft_mute_tune(unsigned short freq, signed int *rssi, signed int *valid) +{ + signed int ret = 0; + unsigned short pkt_size; + /* unsigned short freq;//, orig_freq; */ + struct mt6632_full_cqi *p_cqi; + signed int RSSI = 0, PAMD = 0, MR = 0, ATDC = 0; + unsigned int PRX = 0, ATDEV = 0; + unsigned short softmuteGainLvl = 0; + + ret = mt6632_chan_para_get(freq); + if (ret == 2) + ret = fm_set_bits(FM_CHANNEL_SET, 0x2000, 0x0FFF); /* mdf HiLo */ + else + ret = fm_set_bits(FM_CHANNEL_SET, 0x0000, 0x0FFF); /* clear FA/HL/ATJ */ +#if 0 + fm_reg_write(0x60, 0x0007); + if (mt6632_TDD_chan_check(freq)) + fm_set_bits(0x30, 0x0004, 0xFFF9); /* use TDD solution */ + else + fm_set_bits(0x30, 0x0000, 0xFFF9); /* default use FDD solution */ + fm_reg_write(0x60, 0x000F); +#endif + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = fm_full_cqi_req(cmd_buf, TX_BUF_SIZE, &freq, 1, 1); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_SM_TUNE, SW_RETRY_CNT, SM_TUNE_TIMEOUT, fm_get_read_result); + FM_UNLOCK(cmd_buf_lock); + + if (!ret && fm_res) { + WCN_DBG(FM_DBG | CHIP, "smt cqi size %d\n", fm_res->cqi[0]); + p_cqi = (struct mt6632_full_cqi *)&fm_res->cqi[2]; + + + RSSI = ((p_cqi->rssi & 0x03FF) >= 512) ? ((p_cqi->rssi & 0x03FF) - 1024) : (p_cqi->rssi & 0x03FF); + PAMD = ((p_cqi->pamd & 0x1FF) >= 256) ? ((p_cqi->pamd & 0x01FF) - 512) : (p_cqi->pamd & 0x01FF); + MR = ((p_cqi->mr & 0x01FF) >= 256) ? ((p_cqi->mr & 0x01FF) - 512) : (p_cqi->mr & 0x01FF); + ATDC = (p_cqi->atdc >= 32768) ? (65536 - p_cqi->atdc) : (p_cqi->atdc); + if (ATDC < 0) + ATDC = (~(ATDC)) - 1; /* Get abs value of ATDC */ + + PRX = (p_cqi->prx & 0x00FF); + ATDEV = p_cqi->atdev; + softmuteGainLvl = p_cqi->smg; + /* check if the channel is valid according to each CQIs */ + if ((fm_config.rx_cfg.long_ana_rssi_th <= RSSI) + && (fm_config.rx_cfg.pamd_th >= PAMD) + && (fm_config.rx_cfg.atdc_th >= ATDC) + && (fm_config.rx_cfg.mr_th <= MR) + && (fm_config.rx_cfg.prx_th <= PRX) + && (ATDEV >= ATDC) /* sync scan algorithm */ + && (fm_config.rx_cfg.smg_th <= softmuteGainLvl)) { + *valid = true; + } else { + *valid = false; + } + WCN_DBG(FM_NTC | CHIP, + "valid=%d, freq %d, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x\n", + *valid, p_cqi->ch, p_cqi->rssi, p_cqi->pamd, p_cqi->pr, p_cqi->fpamd, p_cqi->mr, + p_cqi->atdc, p_cqi->prx, p_cqi->atdev, p_cqi->smg, p_cqi->drssi); + *rssi = RSSI; + } else { + WCN_DBG(FM_ERR | CHIP, "smt get CQI failed\n"); + return false; + } + return true; +} + +/* +*parm: +* parm.th_type: 0, RSSI. 1,desense RSSI. 2,SMG. +* parm.th_val: threshold value +*/ +static signed int mt6632_set_search_th(signed int idx, signed int val, signed int reserve) +{ + switch (idx) { + case 0: { + fm_config.rx_cfg.long_ana_rssi_th = val; + WCN_DBG(FM_NTC | CHIP, "set rssi th =%d\n", val); + break; + } + case 1: { + fm_config.rx_cfg.desene_rssi_th = val; + WCN_DBG(FM_NTC | CHIP, "set desense rssi th =%d\n", val); + break; + } + case 2: { + fm_config.rx_cfg.smg_th = val; + WCN_DBG(FM_NTC | CHIP, "set smg th =%d\n", val); + break; + } + default: + break; + } + return 0; +} + +#if 0 +static const unsigned short mt6632_mcu_dese_list[] = { + 0 /* 7630, 7800, 7940, 8320, 9260, 9600, 9710, 9920, 10400, 10410 */ +}; + +static const unsigned short mt6632_gps_dese_list[] = { + 0 /* 7850, 7860 */ +}; +#endif + +static const signed char mt6632_chan_para_map[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6500~6595 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6600~6695 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6700~6795 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6800~6895 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6900~6995 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7000~7095 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7100~7195 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7200~7295 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7300~7395 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7400~7495 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7500~7595 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7600~7695 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7700~7795 */ + 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7800~7895 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7900~7995 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8000~8095 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8100~8195 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8200~8295 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8300~8395 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8400~8495 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8500~8595 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8600~8695 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8700~8795 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8800~8895 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8900~8995 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9000~9095 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9100~9195 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9200~9295 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9300~9395 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9400~9495 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9500~9595 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9600~9695 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9700~9795 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9800~9895 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9900~9995 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10000~10095 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10100~10195 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10200~10295 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10300~10395 */ + 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10400~10495 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10500~10595 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10600~10695 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10700~10795 */ + 0 /* 10800 */ +}; + +static const unsigned short mt6632_TDD_list[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 6500~6595 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 6600~6695 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 6700~6795 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 6800~6895 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 6900~6995 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7000~7095 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7100~7195 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7200~7295 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7300~7395 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7400~7495 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7500~7595 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7600~7695 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7700~7795 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7800~7895 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7900~7995 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8000~8095 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8100~8195 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8200~8295 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8300~8395 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8400~8495 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8500~8595 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8600~8695 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8700~8795 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8800~8895 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8900~8995 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9000~9095 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9100~9195 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9200~9295 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9300~9395 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9400~9495 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9500~9595 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9600~9695 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9700~9795 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9800~9895 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9900~9995 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10000~10095 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10100~10195 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10200~10295 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10300~10395 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10400~10495 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10500~10595 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10600~10695 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10700~10795 */ + 0x0000 /* 10800 */ +}; + +static const unsigned short mt6632_TDD_Mask[] = { + 0x0001, 0x0010, 0x0100, 0x1000 +}; + +static const unsigned short mt6632_scan_dese_list[] = { + 7800, 9210, 9220, 9600, 9980, 10400, 10750, 10760 +}; + + +/* return value: 0, not a de-sense channel; 1, this is a de-sense channel; else error no */ +static signed int mt6632_is_dese_chan(unsigned short freq) +{ + signed int size; + + /* return 0;//HQA only :skip desense channel check. */ + size = ARRAY_SIZE(mt6632_scan_dese_list); + + if (fm_get_channel_space(freq) == 0) + freq *= 10; + + while (size) { + if (mt6632_scan_dese_list[size - 1] == freq) + return 1; + + size--; + } + + return 0; +} + +static bool mt6632_TDD_chan_check(unsigned short freq) +{ + unsigned int i = 0; + unsigned short freq_tmp = freq; + signed int ret = 0; + + ret = fm_get_channel_space(freq_tmp); + if (ret == 0) + freq_tmp *= 10; + else if (ret == -1) + return false; + + i = (freq_tmp - 6500) / 5; + if ((i / 4) >= ARRAY_SIZE(mt6632_TDD_list)) { + WCN_DBG(FM_ERR | CHIP, "Freq index out of range(%d),max(%zd)\n", + i / 4, ARRAY_SIZE(mt6632_TDD_list)); + return false; + } + + if (mt6632_TDD_list[i / 4] & mt6632_TDD_Mask[i % 4]) { + WCN_DBG(FM_DBG | CHIP, "Freq %d use TDD solution\n", freq); + return true; + } else + return false; +} + +/* return value: +*1, is desense channel and rssi is less than threshold; +*0, not desense channel or it is but rssi is more than threshold. +*/ +static signed int mt6632_desense_check(unsigned short freq, signed int rssi) +{ + if (mt6632_is_dese_chan(freq)) { + if (rssi < fm_config.rx_cfg.desene_rssi_th) + return 1; + + WCN_DBG(FM_DBG | CHIP, "desen_rssi %d th:%d\n", rssi, fm_config.rx_cfg.desene_rssi_th); + } + return 0; +} + +/* get channel parameter, HL side/ FA / ATJ */ +static unsigned short mt6632_chan_para_get(unsigned short freq) +{ + signed int pos, size; + + /* return 0;//for HQA only: skip FA/HL/ATJ */ + if (fm_get_channel_space(freq) == 0) + freq *= 10; + + if (freq < 6500) + return 0; + + pos = (freq - 6500) / 5; + size = ARRAY_SIZE(mt6632_chan_para_map); + + pos = (pos > (size - 1)) ? (size - 1) : pos; + + return mt6632_chan_para_map[pos]; +} + +static signed int mt6632_gps_dese(unsigned short freq, void *arg) +{ + /*enum fm_gps_desense_t state = FM_GPS_DESE_DISABLE;*/ + + if (fm_get_channel_space(freq) == 0) + freq *= 10; + + WCN_DBG(FM_NTC | CHIP, "%s, [freq=%d]\n", __func__, (int)freq); + + /* request 6632 GPS change clk */ + if ((freq >= 7690) && (freq <= 8230)) { + WCN_DBG(FM_NTC | CHIP, "gps desense disable\n"); + if (!mtk_wcn_wmt_dsns_ctrl(WMTDSNS_FM_GPS_DISABLE)) + return -1; + } + + if ((freq >= 8460) && (freq <= 9120)) { + WCN_DBG(FM_NTC | CHIP, "gps desense enable\n"); + if (!mtk_wcn_wmt_dsns_ctrl(WMTDSNS_FM_GPS_ENABLE)) + return -1; + } + + return 1; +} + + +signed int fm_low_ops_register(struct fm_callback *cb, struct fm_basic_interface *bi) +{ + signed int ret = 0; + /* Basic functions. */ + + if (bi == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,bi invalid pointer\n", __func__); + return -FM_EPARA; + } + if (cb->cur_freq_get == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,cb->cur_freq_get invalid pointer\n", __func__); + return -FM_EPARA; + } + if (cb->cur_freq_set == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,cb->cur_freq_set invalid pointer\n", __func__); + return -FM_EPARA; + } + fm_cb_op = cb; + + bi->pwron = mt6632_pwron; + bi->pwroff = mt6632_pwroff; + bi->pmic_read = mt6632_pmic_read; + bi->pmic_write = mt6632_pmic_write; + bi->chipid_get = mt6632_get_chipid; + bi->mute = mt6632_Mute; + bi->rampdown = mt6632_RampDown; + bi->pwrupseq = mt6632_PowerUp; + bi->pwrdownseq = mt6632_PowerDown; + bi->setfreq = mt6632_SetFreq; + /* bi->low_pwr_wa = MT6632fm_low_power_wa_default; */ + bi->i2s_set = mt6632_I2s_Setting; + bi->rssiget = mt6632_GetCurRSSI; + bi->volset = mt6632_SetVol; + bi->volget = mt6632_GetVol; + bi->dumpreg = mt6632_dump_reg; + bi->msget = mt6632_GetMonoStereo; + bi->msset = mt6632_SetMonoStereo; + bi->pamdget = mt6632_GetCurPamd; + /* bi->em = mt6632_em_test; */ + bi->anaswitch = mt6632_SetAntennaType; + bi->anaget = mt6632_GetAntennaType; + bi->caparray_get = mt6632_GetCapArray; + bi->hwinfo_get = mt6632_hw_info_get; + bi->fm_via_bt = MT6632_FMOverBT; + bi->i2s_get = mt6632_i2s_info_get; + bi->is_dese_chan = mt6632_is_dese_chan; + bi->softmute_tune = mt6632_soft_mute_tune; + bi->desense_check = mt6632_desense_check; + bi->cqi_log = mt6632_full_cqi_get; + bi->pre_search = mt6632_pre_search; + bi->restore_search = mt6632_restore_search; + bi->set_search_th = mt6632_set_search_th; + bi->get_aud_info = mt6632fm_get_audio_info; + + cmd_buf_lock = fm_lock_create("32_cmd"); + ret = fm_lock_get(cmd_buf_lock); + + cmd_buf = fm_zalloc(TX_BUF_SIZE + 1); + + if (!cmd_buf) { + WCN_DBG(FM_ERR | CHIP, "6632 fm lib alloc tx buf failed\n"); + ret = -1; + } + + return ret; +} + +signed int fm_low_ops_unregister(struct fm_basic_interface *bi) +{ + signed int ret = 0; + /* Basic functions. */ + if (bi == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,bi invalid pointer\n", __func__); + return -FM_EPARA; + } + + if (cmd_buf) { + fm_free(cmd_buf); + cmd_buf = NULL; + } + + ret = fm_lock_put(cmd_buf_lock); + fm_memset(bi, 0, sizeof(struct fm_basic_interface)); + + fm_cb_op = NULL; + + return ret; +} + diff --git a/drivers/misc/mediatek/connectivity/fmradio/chips/mt6632/pub/mt6632_fm_rds.c b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6632/pub/mt6632_fm_rds.c new file mode 100644 index 0000000000000000000000000000000000000000..f0160a48d0bf7edbf2386a86caebd879328fd404 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6632/pub/mt6632_fm_rds.c @@ -0,0 +1,329 @@ +/* +* Copyright (C) 2016 MediaTek Inc. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. +*/ + +#include "fm_typedef.h" +#include "fm_dbg.h" +#include "fm_err.h" +#include "fm_interface.h" +#include "fm_stdlib.h" +#include "fm_rds.h" +#include "mt6632_fm_reg.h" +#include "fm_cmd.h" + +static bool bRDS_FirstIn; /* false */ +static unsigned int gBLER_CHK_INTERVAL = 500; +static unsigned short GOOD_BLK_CNT = 0, BAD_BLK_CNT; +static unsigned char BAD_BLK_RATIO; + +static struct fm_basic_interface *fm_bi; + +static bool mt6632_RDS_support(void); +static signed int mt6632_RDS_enable(void); +static signed int mt6632_RDS_disable(void); +static unsigned short mt6632_RDS_Get_GoodBlock_Counter(void); +static unsigned short mt6632_RDS_Get_BadBlock_Counter(void); +static unsigned char mt6632_RDS_Get_BadBlock_Ratio(void); +static unsigned int mt6632_RDS_Get_BlerCheck_Interval(void); +/* static void mt6632_RDS_GetData(unsigned short *data, unsigned short datalen); */ +static void mt6632_RDS_Init_Data(struct rds_t *pstRDSData); + +static bool mt6632_RDS_support(void) +{ + return true; +} + +static signed int mt6632_RDS_enable(void) +{ + signed int ret = 0; + unsigned short dataRead = 0; + + WCN_DBG(FM_DBG | RDSC, "rds enable\n"); + /* ret = fm_reg_read(FM_RDS_CFG0, &dataRead); */ + ret = fm_reg_write(FM_RDS_CFG0, 6); /* set buf_start_th */ + if (ret) { + WCN_DBG(FM_NTC | RDSC, "rds enable write 0x80 fail\n"); + return ret; + } + ret = fm_reg_read(FM_MAIN_CTRL, &dataRead); + if (ret) { + WCN_DBG(FM_NTC | RDSC, "rds enable read 0x63 fail\n"); + return ret; + } + ret = fm_reg_write(FM_MAIN_CTRL, dataRead | (RDS_MASK)); + if (ret) { + WCN_DBG(FM_NTC | RDSC, "rds enable write 0x63 fail\n"); + return ret; + } + + return ret; +} + +static signed int mt6632_RDS_disable(void) +{ + signed int ret = 0; + unsigned short dataRead = 0; + + WCN_DBG(FM_DBG | RDSC, "rds disable\n"); + ret = fm_reg_read(FM_MAIN_CTRL, &dataRead); + if (ret) { + WCN_DBG(FM_NTC | RDSC, "rds disable read 0x63 fail\n"); + return ret; + } + ret = fm_reg_write(FM_MAIN_CTRL, dataRead & (~RDS_MASK)); + if (ret) { + WCN_DBG(FM_NTC | RDSC, "rds disable write 0x63 fail\n"); + return ret; + } + + return ret; +} + +static unsigned short mt6632_RDS_Get_GoodBlock_Counter(void) +{ + unsigned short tmp_reg = 0; + + fm_reg_read(FM_RDS_GOODBK_CNT, &tmp_reg); + GOOD_BLK_CNT = tmp_reg; + WCN_DBG(FM_DBG | RDSC, "get good block cnt:%d\n", (signed int) tmp_reg); + + return tmp_reg; +} + +static unsigned short mt6632_RDS_Get_BadBlock_Counter(void) +{ + unsigned short tmp_reg = 0; + + fm_reg_read(FM_RDS_BADBK_CNT, &tmp_reg); + BAD_BLK_CNT = tmp_reg; + WCN_DBG(FM_DBG | RDSC, "get bad block cnt:%d\n", (signed int) tmp_reg); + + return tmp_reg; +} + +static unsigned char mt6632_RDS_Get_BadBlock_Ratio(void) +{ + unsigned short tmp_reg; + unsigned short gbc; + unsigned short bbc; + + gbc = mt6632_RDS_Get_GoodBlock_Counter(); + bbc = mt6632_RDS_Get_BadBlock_Counter(); + + if ((gbc + bbc) > 0) + tmp_reg = (unsigned char) (bbc * 100 / (gbc + bbc)); + else + tmp_reg = 0; + + BAD_BLK_RATIO = tmp_reg; + WCN_DBG(FM_DBG | RDSC, "get badblock ratio:%d\n", (signed int) tmp_reg); + + return tmp_reg; +} + +static signed int mt6632_RDS_BlockCounter_Reset(void) +{ + mt6632_RDS_disable(); + mt6632_RDS_enable(); + + return 0; +} + +static unsigned int mt6632_RDS_Get_BlerCheck_Interval(void) +{ + return gBLER_CHK_INTERVAL; +} + +static signed int mt6632_RDS_BlerCheck(struct rds_t *dst) +{ + return 0; +} + +#if 0 +static void RDS_Recovery_Handler(void) +{ + unsigned short tempData = 0; + + do { + fm_reg_read(FM_RDS_DATA_REG, &tempData); + fm_reg_read(FM_RDS_POINTER, &tempData); + } while (tempData & 0x3); +} +#endif + +#if 0 +static void mt6632_RDS_GetData(unsigned short *data, unsigned short datalen) +{ +#define RDS_GROUP_DIFF_OFS 0x007C +#define RDS_FIFO_DIFF 0x007F +#define RDS_CRC_BLK_ADJ 0x0020 +#define RDS_CRC_CORR_CNT 0x001E +#define RDS_CRC_INFO 0x0001 + + unsigned short CRC = 0, i = 0, RDS_adj = 0, RDSDataCount = 0, FM_WARorrCnt = 0; + unsigned short temp = 0, OutputPofm_s32 = 0; + + WCN_DBG(FM_DBG | RDSC, "get data\n"); + fm_reg_read(FM_RDS_FIFO_STATUS0, &temp); + RDSDataCount = ((RDS_GROUP_DIFF_OFS & temp) << 2); + + if ((temp & RDS_FIFO_DIFF) >= 4) { + /* block A data and info handling */ + fm_reg_read(FM_RDS_INFO, &temp); + RDS_adj |= (temp & RDS_CRC_BLK_ADJ) << 10; + CRC |= (temp & RDS_CRC_INFO) << 3; + FM_WARorrCnt |= ((temp & RDS_CRC_CORR_CNT) << 11); + fm_reg_read(FM_RDS_DATA_REG, &data[0]); + + /* block B data and info handling */ + fm_reg_read(FM_RDS_INFO, &temp); + RDS_adj |= (temp & RDS_CRC_BLK_ADJ) << 9; + CRC |= (temp & RDS_CRC_INFO) << 2; + FM_WARorrCnt |= ((temp & RDS_CRC_CORR_CNT) << 7); + fm_reg_read(FM_RDS_DATA_REG, &data[1]); + + /* block C data and info handling */ + fm_reg_read(FM_RDS_INFO, &temp); + RDS_adj |= (temp & RDS_CRC_BLK_ADJ) << 8; + CRC |= (temp & RDS_CRC_INFO) << 1; + FM_WARorrCnt |= ((temp & RDS_CRC_CORR_CNT) << 3); + fm_reg_read(FM_RDS_DATA_REG, &data[2]); + + /* block D data and info handling */ + fm_reg_read(FM_RDS_INFO, &temp); + RDS_adj |= (temp & RDS_CRC_BLK_ADJ) << 7; + CRC |= (temp & RDS_CRC_INFO); + FM_WARorrCnt |= ((temp & RDS_CRC_CORR_CNT) >> 1); + fm_reg_read(FM_RDS_DATA_REG, &data[3]); + + data[4] = (CRC | RDS_adj | RDSDataCount); + data[5] = FM_WARorrCnt; + + fm_reg_read(FM_RDS_PWDI, &data[6]); + fm_reg_read(FM_RDS_PWDQ, &data[7]); + + fm_reg_read(FM_RDS_POINTER, &OutputPofm_s32); + + /* Go fm_s32o RDS recovery handler while RDS output pofm_s32 doesn't align to 4 in numeric */ + if (OutputPofm_s32 & 0x3) + RDS_Recovery_Handler(); + + } else { + for (; i < 8; i++) + data[i] = 0; + } +} +#endif + +static void mt6632_RDS_Init_Data(struct rds_t *pstRDSData) +{ + fm_memset(pstRDSData, 0, sizeof(struct rds_t)); + bRDS_FirstIn = true; + + fm_memset(pstRDSData->RT_Data.TextData, 0x20, sizeof(pstRDSData->RT_Data.TextData)); + fm_memset(pstRDSData->PS_Data.PS, '\0', sizeof(pstRDSData->PS_Data.PS)); + fm_memset(pstRDSData->PS_ON, 0x20, sizeof(pstRDSData->PS_ON)); +} + +bool mt6632_RDS_OnOff(struct rds_t *dst, bool bFlag) +{ + signed int ret = 0; + + if (mt6632_RDS_support() == false) { + WCN_DBG(FM_ALT | RDSC, "mt6632_RDS_OnOff failed, RDS not support\n"); + return false; + } + + if (bFlag) { + mt6632_RDS_Init_Data(dst); + ret = mt6632_RDS_enable(); + if (ret) { + WCN_DBG(FM_NTC | RDSC, "mt6632_RDS_OnOff enable failed\n"); + return false; + } + } else { + ret = mt6632_RDS_disable(); + if (ret) { + WCN_DBG(FM_NTC | RDSC, "mt6632_RDS_OnOff disable failed\n"); + return false; + } + } + + return true; +} + +DEFINE_RDSLOG(mt6632_rds_log); + +/* mt6632_RDS_Efm_s32_Handler - response FM RDS interrupt + * @fm - main data structure of FM driver + * This function first get RDS raw data, then call RDS spec parser + */ +static signed int mt6632_rds_parser(struct rds_t *rds_dst, struct rds_rx_t *rds_raw, + signed int rds_size, unsigned short(*getfreq) (void)) +{ + mt6632_rds_log.log_in(&mt6632_rds_log, rds_raw, rds_size); + return rds_parser(rds_dst, rds_raw, rds_size, getfreq); +} + +static signed int mt6632_rds_log_get(struct rds_rx_t *dst, signed int *dst_len) +{ + return mt6632_rds_log.log_out(&mt6632_rds_log, dst, dst_len); +} + +static signed int mt6632_rds_gc_get(struct rds_group_cnt_t *dst, struct rds_t *rdsp) +{ + return rds_grp_counter_get(dst, &rdsp->gc); +} + +static signed int mt6632_rds_gc_reset(struct rds_t *rdsp) +{ + return rds_grp_counter_reset(&rdsp->gc); +} + +signed int fm_rds_ops_register(struct fm_basic_interface *bi, struct fm_rds_interface *ri) +{ + signed int ret = 0; + + if (ri == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,ri invalid pointer\n", __func__); + return -FM_EPARA; + } + fm_bi = bi; + + ri->rds_blercheck = mt6632_RDS_BlerCheck; + ri->rds_onoff = mt6632_RDS_OnOff; + ri->rds_parser = mt6632_rds_parser; + ri->rds_gbc_get = mt6632_RDS_Get_GoodBlock_Counter; + ri->rds_bbc_get = mt6632_RDS_Get_BadBlock_Counter; + ri->rds_bbr_get = mt6632_RDS_Get_BadBlock_Ratio; + ri->rds_bc_reset = mt6632_RDS_BlockCounter_Reset; + ri->rds_bci_get = mt6632_RDS_Get_BlerCheck_Interval; + ri->rds_log_get = mt6632_rds_log_get; + ri->rds_gc_get = mt6632_rds_gc_get; + ri->rds_gc_reset = mt6632_rds_gc_reset; + return ret; +} + +signed int fm_rds_ops_unregister(struct fm_rds_interface *ri) +{ + signed int ret = 0; + + if (ri == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,ri invalid pointer\n", __func__); + return -FM_EPARA; + } + + fm_bi = NULL; + fm_memset(ri, 0, sizeof(struct fm_rds_interface)); + return ret; +} + diff --git a/drivers/misc/mediatek/connectivity/fmradio/chips/mt6635/inc/mt6635_fm_lib.h b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6635/inc/mt6635_fm_lib.h new file mode 100644 index 0000000000000000000000000000000000000000..339f10c41c5ae0c1327ec606fc257d697f653a6a --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6635/inc/mt6635_fm_lib.h @@ -0,0 +1,73 @@ +/* +* Copyright (C) 2016 MediaTek Inc. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. +*/ +#ifndef __MT6635_FM_LIB_H__ +#define __MT6635_FM_LIB_H__ + +#include "fm_typedef.h" + +enum { + DSPPATCH = 0xFFF9, + USDELAY = 0xFFFA, + MSDELAY = 0xFFFB, + HW_VER = 0xFFFD, + POLL_N = 0xFFFE, /* poling check if bit(n) is '0' */ + POLL_P = 0xFFFF, /* polling check if bit(n) is '1' */ +}; + +enum { + FM_PUS_DSPPATCH = DSPPATCH, + FM_PUS_USDELAY = USDELAY, + FM_PUS_MSDELAY = MSDELAY, + FM_PUS_HW_VER = HW_VER, + FM_PUS_POLL_N = POLL_N, /* poling check if bit(n) is '0' */ + FM_PUS_POLL_P = POLL_P, /* polling check if bit(n) is '1' */ + FM_PUS_MAX +}; + +enum { + mt6635_E1 = 0, + mt6635_E2 +}; + +struct mt6635_fm_cqi { + unsigned short ch; + unsigned short rssi; + unsigned short reserve; +}; + +struct adapt_fm_cqi { + signed int ch; + signed int rssi; + signed int reserve; +}; + +struct mt6635_full_cqi { + unsigned short ch; + unsigned short rssi; + unsigned short pamd; + unsigned short pr; + unsigned short fpamd; + unsigned short mr; + unsigned short atdc; + unsigned short prx; + unsigned short atdev; + unsigned short smg; /* soft-mute gain */ + unsigned short drssi; /* delta rssi */ +}; + +signed int mt6635_fm_low_ops_register(struct fm_callback *cb, struct fm_basic_interface *bi); +signed int mt6635_fm_low_ops_unregister(struct fm_basic_interface *bi); +signed int mt6635_fm_rds_ops_register(struct fm_basic_interface *bi, struct fm_rds_interface *ri); +signed int mt6635_fm_rds_ops_unregister(struct fm_rds_interface *ri); + +#endif diff --git a/drivers/misc/mediatek/connectivity/fmradio/chips/mt6635/inc/mt6635_fm_reg.h b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6635/inc/mt6635_fm_reg.h new file mode 100644 index 0000000000000000000000000000000000000000..9a2c77483fb3d9611ce3f146aac5cd5d92b778b7 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6635/inc/mt6635_fm_reg.h @@ -0,0 +1,57 @@ +/* +* Copyright (C) 2016 MediaTek Inc. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. +*/ +#ifndef __MT6635_FM_REG_H__ +#define __MT6635_FM_REG_H__ + +/* RDS_BDGRP_ABD_CTRL_REG */ +enum { + BDGRP_ABD_EN = 0x0001, + BER_RUN = 0x2000 +}; +#define FM_DAC_CON1 0x83 +#define FM_DAC_CON2 0x84 +#define FM_FT_CON0 0x86 +enum { + FT_EN = 0x0001 +}; + +#define FM_I2S_CON0 0x90 +enum { + I2S_EN = 0x0001, + FORMAT = 0x0002, + WLEN = 0x0004, + I2S_SRC = 0x0008 +}; + +/* FM_MAIN_CTRL */ +enum { + TUNE = 0x0001, + SEEK = 0x0002, + SCAN = 0x0004, + CQI_READ = 0x0008, + RDS_MASK = 0x0010, + MUTE = 0x0020, + RDS_BRST = 0x0040, + RAMP_DOWN = 0x0100, +}; + +enum { + ANTENNA_TYPE = 0x0010, /* 0x61 D4, 0:long, 1:short */ + ANALOG_I2S = 0x0080, /* 0x61 D7, 0:lineout, 1:I2S */ + DE_EMPHASIS = 0x1000, /* 0x61 D12,0:50us, 1:75 us */ +}; + +#define OSC_FREQ_BITS 0x0070 /* 0x60 bit4~6 */ +#define OSC_FREQ_MASK (~OSC_FREQ_BITS) + +#endif /* __MT6635_FM_REG_H__ */ diff --git a/drivers/misc/mediatek/connectivity/fmradio/chips/mt6635/pub/mt6635_2_fm_lib.c b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6635/pub/mt6635_2_fm_lib.c new file mode 100644 index 0000000000000000000000000000000000000000..0cd0a24b9533326a38215bd695e3e3e1445e7bbb --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6635/pub/mt6635_2_fm_lib.c @@ -0,0 +1,1966 @@ +/* +* Copyright (C) 2016 MediaTek Inc. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. +*/ +#include +#include + +#include "fm_typedef.h" +#include "fm_dbg.h" +#include "fm_err.h" +#include "fm_interface.h" +#include "fm_stdlib.h" +#include "fm_patch.h" +#include "fm_utils.h" +#include "fm_link.h" +#include "fm_config.h" +#include "fm_cmd.h" + +#include "mt6635_fm_reg.h" +#include "mt6635_fm_lib.h" + +#define HQA_RETURN_ZERO_MAP 0 +#define HQA_ZERO_DESENSE_MAP 0 + +/* #include "mach/mt_gpio.h" */ + +/* #define MT6635_FM_PATCH_PATH "/etc/firmware/mt6635/mt6635_fm_patch.bin" */ +/* #define MT6635_FM_COEFF_PATH "/etc/firmware/mt6635/mt6635_fm_coeff.bin" */ +/* #define MT6635_FM_HWCOEFF_PATH "/etc/firmware/mt6635/mt6635_fm_hwcoeff.bin" */ +/* #define MT6635_FM_ROM_PATH "/etc/firmware/mt6635/mt6635_fm_rom.bin" */ + +static struct fm_patch_tbl mt6635_patch_tbl[5] = { + {FM_ROM_V1, "mt6635_fm_v1_patch.bin", "mt6635_fm_v1_coeff.bin", NULL, NULL}, + {FM_ROM_V2, "mt6635_fm_v2_patch.bin", "mt6635_fm_v2_coeff.bin", NULL, NULL}, + {FM_ROM_V3, "mt6635_fm_v3_patch.bin", "mt6635_fm_v3_coeff.bin", NULL, NULL}, + {FM_ROM_V4, "mt6635_fm_v4_patch.bin", "mt6635_fm_v4_coeff.bin", NULL, NULL}, + {FM_ROM_V5, "mt6635_fm_v5_patch.bin", "mt6635_fm_v5_coeff.bin", NULL, NULL} +}; + +static struct fm_hw_info mt6635_hw_info = { + .chip_id = 0x00006635, + .eco_ver = 0x00000000, + .rom_ver = 0x00000000, + .patch_ver = 0x00000000, + .reserve = 0x00000000, +}; + +static struct fm_callback *fm_cb_op; + +/* static signed int Chip_Version = mt6635_E1; */ + +/* static bool rssi_th_set = false; */ + +#if 0 /* def CONFIG_MTK_FM_50KHZ_SUPPORT */ +static struct fm_fifo *cqi_fifo; +#endif +static signed int mt6635_is_dese_chan(unsigned short freq); + +static unsigned short mt6635_chan_para_get(unsigned short freq); +static signed int mt6635_desense_check(unsigned short freq, signed int rssi); +static bool mt6635_TDD_chan_check(unsigned short freq); +static bool mt6635_SPI_hopping_check(unsigned short freq); +static signed int mt6635_soft_mute_tune(unsigned short freq, signed int *rssi, signed int *valid); + +static signed int mt6635_pwron(signed int data) +{ + if (fm_wcn_ops.ei.wmt_func_on && !fm_wcn_ops.ei.wmt_func_on()) { + WCN_DBG(FM_ERR | CHIP, "WMT turn on FM Fail!\n"); + return -FM_ELINK; + } + + WCN_DBG(FM_NTC | CHIP, "WMT turn on FM OK!\n"); + return 0; +} + +static signed int mt6635_pwroff(signed int data) +{ + if (fm_wcn_ops.ei.wmt_func_off && !fm_wcn_ops.ei.wmt_func_off()) { + WCN_DBG(FM_ERR | CHIP, "WMT turn off FM Fail!\n"); + return -FM_ELINK; + } + + WCN_DBG(FM_NTC | CHIP, "WMT turn off FM OK!\n"); + return 0; +} + +static unsigned short mt6635_get_chipid(void) +{ + return 0x6635; +} + +/* MT6635_SetAntennaType - set Antenna type + * @type - 1, Short Antenna; 0, Long Antenna + */ +static signed int mt6635_SetAntennaType(signed int type) +{ + unsigned short dataRead = 0; + + WCN_DBG(FM_DBG | CHIP, "set ana to %s\n", type ? "short" : "long"); + fm_reg_read(FM_MAIN_CG2_CTRL, &dataRead); + + if (type) + dataRead |= ANTENNA_TYPE; + else + dataRead &= (~ANTENNA_TYPE); + + fm_reg_write(FM_MAIN_CG2_CTRL, dataRead); + + return 0; +} + +static signed int mt6635_GetAntennaType(void) +{ + unsigned short dataRead = 0; + + fm_reg_read(FM_MAIN_CG2_CTRL, &dataRead); + WCN_DBG(FM_DBG | CHIP, "get ana type: %s\n", (dataRead & ANTENNA_TYPE) ? "short" : "long"); + + if (dataRead & ANTENNA_TYPE) + return FM_ANA_SHORT; /* short antenna */ + else + return FM_ANA_LONG; /* long antenna */ +} + +static signed int mt6635_Mute(bool mute) +{ + signed int ret = 0; + unsigned short dataRead = 0; + + WCN_DBG(FM_DBG | CHIP, "set %s\n", mute ? "mute" : "unmute"); + /* fm_reg_read(FM_MAIN_CTRL, &dataRead); */ + fm_reg_read(0x9C, &dataRead); + + /* fm_top_reg_write(0x0050, 0x00000007); */ + if (mute == 1) + ret = fm_reg_write(0x9C, (dataRead & 0xFFFC) | 0x0003); + else + ret = fm_reg_write(0x9C, (dataRead & 0xFFFC)); + + /* fm_top_reg_write(0x0050, 0x0000000F); */ + + return ret; +} + +static signed int mt6635_rampdown_reg_op(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 4; + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + + /* A1. Clear DSP state */ + pkt_size += fm_bop_modify(FM_MAIN_CTRL, 0xFFF0, 0x0000, &buf[pkt_size], buf_size - pkt_size); + /* A2. Set DSP ramp down state */ + pkt_size += fm_bop_modify(FM_MAIN_CTRL, 0xFFFF, RAMP_DOWN, &buf[pkt_size], buf_size - pkt_size); + /* @Wait for STC_DONE interrupt@ */ + pkt_size += fm_bop_rd_until(FM_MAIN_INTR, FM_INTR_STC_DONE, FM_INTR_STC_DONE, &buf[pkt_size], + buf_size - pkt_size); + /* A6. Clear DSP ramp down state */ + pkt_size += fm_bop_modify(FM_MAIN_CTRL, (~RAMP_DOWN), 0x0000, &buf[pkt_size], buf_size - pkt_size); + /* A7. Write 1 clear the STC_DONE interrupt status flag */ + pkt_size += fm_bop_modify(FM_MAIN_INTR, 0xFFFF, FM_INTR_STC_DONE, &buf[pkt_size], buf_size - pkt_size); + + return pkt_size - 4; +} +/* + * mt6635_rampdown - f/w will wait for STC_DONE interrupt + * @buf - target buf + * @buf_size - buffer size + * return package size + */ +static signed int mt6635_rampdown(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 0; + + pkt_size = mt6635_rampdown_reg_op(buf, buf_size); + return fm_op_seq_combine_cmd(buf, FM_RAMPDOWN_OPCODE, pkt_size); +} + +/* FMSYS Ramp Down Sequence*/ +static signed int mt6635_RampDown(void) +{ + struct fm_ext_interface *ei = &fm_wcn_ops.ei; + signed int ret = 0; + unsigned int tem = 0; + unsigned short pkt_size; + /* unsigned short tmp; */ + + WCN_DBG(FM_DBG | CHIP, "ramp down\n"); + + /* switch SPI clock to 26MHz */ + if (ei->spi_clock_switch) + ret = ei->spi_clock_switch(FM_SPI_SPEED_26M); + else { + ret = -1; + WCN_DBG(FM_ERR | CHIP, "Clock switch cb is null\n"); + } + if (ret) + WCN_DBG(FM_ERR | CHIP, + "RampDown Switch SPI clock to 26MHz failed\n"); + + /* unlock 64M */ + ret = fm_host_reg_read(0x18003004, &tem); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: unlock 64M reg 0x18003004 failed\n", __func__); + ret = fm_host_reg_write(0x18003004, tem & (~(0x1 << 15))); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: unlock 64M failed\n", __func__); + + /* disable 'rf_spi_div_en' */ + ret = fm_host_reg_read(0x18001A00, &tem); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: disable rf_spi_div_en read failed\n", __func__); + ret = fm_host_reg_write(0x18001A00, tem | (0x1 << 28)); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: disable rf_spi_div_en write failed\n", __func__); + + /* A0.0 Host control RF register */ + ret = fm_set_bits(0x60, 0x0007, 0xFFF0); /*Set 0x60 [D3:D0] = 0x7*/ + if (ret) { + WCN_DBG(FM_ERR | CHIP, "ramp down HOST control rf: Set 0x60 [D3:D0] = 0x7 failed\n"); + return ret; + } + + /* A0.1 Update FM ADPLL fast tracking mode gain */ + ret = fm_set_bits(0x0F, 0x0000, 0xF800); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "ramp down ADPLL gainA/B: Set 0xFH [D10:D0] = 0x000 failed\n"); + return ret; + } + + /* A0.2 Host control RF register */ + ret = fm_set_bits(0x60, 0x000F, 0xFFF0); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "ramp down Host control RF registerwr top 0x60 failed\n"); + return ret; + } + /* A1. Clear dsp state*/ + ret = fm_set_bits(0x63, 0x0000, 0xFFF0); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "ramp down Host control RF registerwr top 0x63 failed\n"); + return ret; + } + /* A2. Set DSP ramp down state*/ + ret = fm_set_bits(0x63, 0x0010, 0xFFEF); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "ramp down Host control RF registerwr top 0x63 failed\n"); + return ret; + } + + /* A3. Clear STC_DONE interrupt */ + ret = fm_reg_write(FM_MAIN_INTRMASK, 0x0000); + if (ret) + WCN_DBG(FM_ERR | CHIP, "ramp down clean FM_MAIN_INTRMASK failed\n"); + + ret = fm_reg_write(FM_MAIN_EXTINTRMASK, 0x0000); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "ramp down clean FM_MAIN_EXTINTRMASK failed\n"); + return ret; + } + + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = mt6635_rampdown(cmd_buf, TX_BUF_SIZE); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_RAMPDOWN, SW_RETRY_CNT, RAMPDOWN_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + + if (ret) { + WCN_DBG(FM_ERR | CHIP, "ramp down failed\n"); + return ret; + } + + ret = fm_reg_write(FM_MAIN_EXTINTRMASK, 0x0021); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "ramp down wr FM_MAIN_EXTINTRMASK failed\n"); + return ret; + } + + ret = fm_reg_write(FM_MAIN_INTRMASK, 0x0021); + if (ret) + WCN_DBG(FM_ERR | CHIP, "ramp down wr FM_MAIN_INTRMASK failed\n"); + + return ret; +} + +static signed int mt6635_get_rom_version(void) +{ + unsigned short flag_Romcode = 0; + unsigned short nRomVersion = 0; +#define ROM_CODE_READY 0x0001 + signed int ret = 0; + + /* A1.1 DSP rom code version request enable --- set 0x61 b15=1 */ + fm_set_bits(0x61, 0x8000, 0x7FFF); + + /* A1.2 Release ASIP reset --- set 0x61 b1=1 */ + fm_set_bits(0x61, 0x0002, 0xFFFD); + + /* A1.3 Enable ASIP power --- set 0x61 b0=0 */ + fm_set_bits(0x61, 0x0000, 0xFFFE); + + /* A1.4 Wait until DSP code version ready --- wait loop 1ms */ + do { + fm_delayus(1000); + ret = fm_reg_read(0x84, &flag_Romcode); + /* ret=-4 means signal got when control FM. usually get sig 9 to kill FM process. */ + /* now cancel FM power up sequence is recommended. */ + if (ret) + return ret; + + WCN_DBG(FM_DBG | CHIP, "ROM_CODE_READY flag 0x84=%x\n", flag_Romcode); + } while (flag_Romcode != ROM_CODE_READY); + + + /* A1.5 Read FM DSP code version --- rd 0x83[15:8] */ + fm_reg_read(0x83, &nRomVersion); + nRomVersion = (nRomVersion >> 8); + + /* A1.6 DSP rom code version request disable --- set 0x61 b15=0 */ + fm_set_bits(0x61, 0x0000, 0x7FFF); + + /* A1.7 Reset ASIP --- set 0x61[1:0] = 1 */ + fm_set_bits(0x61, 0x0001, 0xFFFC); + + return (signed int) nRomVersion; +} + +static signed int mt6635_pwrup_clock_on_reg_op(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 4; + unsigned short de_emphasis; + /* unsigned short osc_freq; */ + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + de_emphasis = fm_config.rx_cfg.deemphasis; + de_emphasis &= 0x0001; /* rang 0~1 */ + /* 2,turn on top clock */ + pkt_size += fm_bop_top_write(0xA00, 0xFFFFFFFF, &buf[pkt_size], buf_size - pkt_size); + /* wr top cr a00 ffffffff */ + + /* 3,enable MTCMOS */ + pkt_size += fm_bop_top_write(0x160, 0x00000030, &buf[pkt_size], buf_size - pkt_size); + /* wr top 160 30 */ + + pkt_size += fm_bop_top_write(0x160, 0x00000035, &buf[pkt_size], buf_size - pkt_size); + /* wr top 160 35 */ + pkt_size += fm_bop_udelay(10, &buf[pkt_size], buf_size - pkt_size); + /* delay 10us */ + pkt_size += fm_bop_top_write(0x160, 0x00000015, &buf[pkt_size], buf_size - pkt_size); + /* wr top 160 15 */ + pkt_size += fm_bop_top_write(0x160, 0x00000005, &buf[pkt_size], buf_size - pkt_size); + /* wr top 160 5 */ + + pkt_size += fm_bop_udelay(10, &buf[pkt_size], buf_size - pkt_size); + /* delay 10us */ + pkt_size += fm_bop_top_write(0x160, 0x00000045, &buf[pkt_size], buf_size - pkt_size); + /* wr top 160 45 */ + + /* 4,set comspi fm slave dumy count */ + pkt_size += fm_bop_write(0x7f, 0x801f, &buf[pkt_size], buf_size - pkt_size); /* wr 7f 801f */ + + /* A. FM digital clock enable */ + /* A1. Wait 3ms */ + pkt_size += fm_bop_udelay(3000, &buf[pkt_size], buf_size - pkt_size); + + /* A2. Release HW clock gating*/ + pkt_size += fm_bop_write(0x60, 0x0007, &buf[pkt_size], buf_size - pkt_size); /* wr 60 7 */ + /* A3. Enable DSP auto clock gating */ + pkt_size += fm_bop_write(0x70, 0x0040, &buf[pkt_size], buf_size - pkt_size); /* wr 70 0040 */ + /* A4. Deemphasis setting: Set 0 for 50us, Set 1 for 75us */ + pkt_size += fm_bop_modify(0x61, ~DE_EMPHASIS, (de_emphasis << 12), &buf[pkt_size], buf_size - pkt_size); + + return pkt_size - 4; +} +/* + * mt6635_pwrup_clock_on - Wholechip FM Power Up: step 1, FM Digital Clock enable + * @buf - target buf + * @buf_size - buffer size + * return package size + */ +static signed int mt6635_pwrup_clock_on(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 0; + + pkt_size = mt6635_pwrup_clock_on_reg_op(buf, buf_size); + return fm_op_seq_combine_cmd(buf, FM_ENABLE_OPCODE, pkt_size); +} + +static signed int mt6635_pwrup_digital_init_reg_op(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 4; + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + /* Part D FM RF&ADPLL divider setting */ + + /* D2.1 set cell mode */ + /* wr 30 D3:D2 00:FDD(default),01:both.10: TDD, 11 FDD */ + /* pkt_size += fm_bop_modify(0x30, 0xFFF3, 0x0000, &buf[pkt_size], buf_size - pkt_size); */ + + /* D2.2 set ADPLL divider */ + pkt_size += fm_bop_write(0x21, 0xE000, &buf[pkt_size], buf_size - pkt_size); /* wr 21 E000 */ + /* D2.3 set SDM coeff0_H */ + pkt_size += fm_bop_write(0xD8, 0x03F0, &buf[pkt_size], buf_size - pkt_size); /* wr D8 0x03F0 */ + /* D2.4 set SDM coeff0_L */ + pkt_size += fm_bop_write(0xD9, 0x3F04, &buf[pkt_size], buf_size - pkt_size); /* wr D9 0x3F04 */ + /* D2.5 set SDM coeff1_H */ + pkt_size += fm_bop_write(0xDA, 0x0014, &buf[pkt_size], buf_size - pkt_size); /* wr DA 0x0014 */ + /* D2.6 set SDM coeff1_L */ + pkt_size += fm_bop_write(0xDB, 0x2A38, &buf[pkt_size], buf_size - pkt_size); /* wr DB 0x2A38 */ + /* D2.7 set 26M clock */ + pkt_size += fm_bop_write(0x23, 0x4000, &buf[pkt_size], buf_size - pkt_size); /* wr 23 4000 */ + + /* Part E: FM Digital Init: fm_rgf_maincon */ + + /* E4. Set appropriate interrupt mask behavior as desired */ + /* Enable stc_done_mask, Enable rgf_rds_mask*/ + pkt_size += fm_bop_write(0x6A, 0x0021, &buf[pkt_size], buf_size - pkt_size); /* wr 6A 0021 */ + pkt_size += fm_bop_write(0x6B, 0x0021, &buf[pkt_size], buf_size - pkt_size); /* wr 6B 0021 */ + + /* E5. Enable hw auto control */ + pkt_size += fm_bop_write(0x60, 0x0000000F, &buf[pkt_size], buf_size - pkt_size); /* wr 60 f */ + + /* E6. Release ASIP reset */ + pkt_size += fm_bop_modify(0x61, 0xFFFD, 0x0002, &buf[pkt_size], buf_size - pkt_size); /* wr 61 D1=1 */ + /* E7. Enable ASIP power */ + pkt_size += fm_bop_modify(0x61, 0xFFFE, 0x0000, &buf[pkt_size], buf_size - pkt_size); /* wr 61 D0=0 */ + + /* E8 */ + pkt_size += fm_bop_udelay(100000, &buf[pkt_size], buf_size - pkt_size); /* delay 100ms */ + /* E9. Check HW initial complete */ + pkt_size += fm_bop_rd_until(0x64, 0x001F, 0x0002, &buf[pkt_size], buf_size - pkt_size); /* Poll 64[0~4] = 2 */ + + return pkt_size - 4; +} + +/* + * mt6635_pwrup_digital_init - Wholechip FM Power Up: step 4, FM Digital Init: fm_rgf_maincon + * @buf - target buf + * @buf_size - buffer size + * return package size + */ +static signed int mt6635_pwrup_digital_init(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 0; + + pkt_size = mt6635_pwrup_digital_init_reg_op(buf, buf_size); + return fm_op_seq_combine_cmd(buf, FM_ENABLE_OPCODE, pkt_size); +} + +static signed int mt6635_pwrup_fine_tune_reg_op(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 4; + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + /* F1 set host control RF register */ + pkt_size += fm_bop_write(0x60, 0x00000007, &buf[pkt_size], buf_size - pkt_size); + + /* F2 fine tune RF setting */ + pkt_size += fm_bop_write(0x01, 0xBEE8, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x03, 0xF6ED, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x15, 0x0D80, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x16, 0x0068, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x17, 0x092A, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x34, 0x807F, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x35, 0x311E, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x40, 0x0100, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x03, 0xFAF5, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x05, 0x7A80, &buf[pkt_size], buf_size - pkt_size); + + /* F4 set DSP control RF register */ + pkt_size += fm_bop_write(0x60, 0x0000000F, &buf[pkt_size], buf_size - pkt_size); + + return pkt_size - 4; +} + +/* + * mt6635_pwrup_fine_tune - Wholechip FM Power Up: step 5, FM RF fine tune setting + * @buf - target buf + * @buf_size - buffer size + * return package size + */ +static signed int mt6635_pwrup_fine_tune(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 0; + + pkt_size = mt6635_pwrup_fine_tune_reg_op(buf, buf_size); + return fm_op_seq_combine_cmd(buf, FM_ENABLE_OPCODE, pkt_size); +} + +static signed int mt6635_pwrdown_reg_op(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 4; + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + /* A1:set audio output I2S Tx mode: */ + pkt_size += fm_bop_modify(0x9B, 0xFFF8, 0x0000, &buf[pkt_size], buf_size - pkt_size); + + /* B0:Disable HW clock control */ + pkt_size += fm_bop_write(0x60, 0x330F, &buf[pkt_size], buf_size - pkt_size); + /* B1:Reset ASIP : Set 0x61, [D1 = 0, D0=1] */ + pkt_size += fm_bop_modify(0x61, 0xFFFD, 0x0001, &buf[pkt_size], buf_size - pkt_size); + + /* B2:digital core + digital rgf reset */ + pkt_size += fm_bop_modify(0x6E, 0xFFF8, 0x0000, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_modify(0x6E, 0xFFF8, 0x0000, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_modify(0x6E, 0xFFF8, 0x0000, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_modify(0x6E, 0xFFF8, 0x0000, &buf[pkt_size], buf_size - pkt_size); + + /* B3:Disable all clock */ + pkt_size += fm_bop_write(0x60, 0x0000, &buf[pkt_size], buf_size - pkt_size); + /* B4:Reset rgfrf */ + pkt_size += fm_bop_write(0x60, 0x4000, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x60, 0x0000, &buf[pkt_size], buf_size - pkt_size); + + /* MTCMOS power off */ + /* C0:disable MTCMOS */ + pkt_size += fm_bop_top_write(0x160, 0x0005, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_top_write(0x160, 0x0015, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_top_write(0x160, 0x0035, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_top_write(0x160, 0x0030, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_top_rd_until(0x160, 0x0000000A, 0x0, &buf[pkt_size], buf_size - pkt_size); + + return pkt_size - 4; +} +/* + * mt6635_pwrdown - Wholechip FM Power down: Digital Modem Power Down + * @buf - target buf + * @buf_size - buffer size + * return package size + */ +static signed int mt6635_pwrdown(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 0; + + pkt_size = mt6635_pwrdown_reg_op(buf, buf_size); + return fm_op_seq_combine_cmd(buf, FM_ENABLE_OPCODE, pkt_size); +} + +static signed int mt6635_tune_reg_op(unsigned char *buf, signed int buf_size, unsigned short freq, + unsigned short chan_para) +{ + signed int pkt_size = 4; + + WCN_DBG(FM_ALT | CHIP, "%s enter mt6635_tune function\n", __func__); + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + /* A2 Enable hardware controlled tuning sequence */ + pkt_size += fm_bop_modify(FM_MAIN_CTRL, 0xFFF8, TUNE, &buf[pkt_size], buf_size - pkt_size);/*Set 0x63 D0=1*/ + /* Wait for STC_DONE interrupt */ + + +#ifdef FM_TUNE_USE_POLL + /* A3 Wait for STC_DONE interrupt */ + /* A4 Wait for STC_DONE interrupt status flag */ + pkt_size += fm_bop_rd_until(FM_MAIN_INTR, FM_INTR_STC_DONE, + FM_INTR_STC_DONE, &buf[pkt_size], buf_size - pkt_size); + /* A6 Write 1 clear the STC_DONE interrupt status flag */ + pkt_size += fm_bop_modify(FM_MAIN_INTR, 0xFFFF, FM_INTR_STC_DONE, &buf[pkt_size], buf_size - pkt_size); +#endif + + pkt_size += fm_bop_udelay(100000, &buf[pkt_size], buf_size - pkt_size); + WCN_DBG(FM_ALT | CHIP, "mt6635_tune delay 100 ms wait 0x69 to change\n"); + + WCN_DBG(FM_ALT | CHIP, "%s leave mt6635_tune function\n", __func__); + + return pkt_size - 4; +} + +/* + * mt6635_tune - execute tune action, + * @buf - target buf + * @buf_size - buffer size + * @freq - 760 ~ 1080, 100KHz unit + * return package size + */ +static signed int mt6635_tune(unsigned char *buf, signed int buf_size, unsigned short freq, + unsigned short chan_para) +{ + signed int pkt_size = 0; + + pkt_size = mt6635_tune_reg_op(buf, buf_size, freq, chan_para); + return fm_op_seq_combine_cmd(buf, FM_TUNE_OPCODE, pkt_size); +} + +/* + * mt6635_pwrup_DSP_download - execute dsp/coeff patch dl action, + * @patch_tbl - current chip patch table + * return patch dl ok or not + */ +static signed int mt6635_pwrup_DSP_download(struct fm_patch_tbl *patch_tbl) +{ +#define PATCH_BUF_SIZE (4096*6) + signed int ret = 0; + signed int patch_len = 0; + unsigned char *dsp_buf = NULL; + unsigned short tmp_reg = 0; + + if (fm_wcn_ops.ei.wmt_ic_info_get) + mt6635_hw_info.eco_ver = fm_wcn_ops.ei.wmt_ic_info_get(); + WCN_DBG(FM_DBG | CHIP, "ECO version:0x%08x\n", mt6635_hw_info.eco_ver); + + /* Wholechip FM Power Up: step 3, get mt6635 DSP ROM version */ + ret = mt6635_get_rom_version(); + if (ret >= 0) { + mt6635_hw_info.rom_ver = ret; + WCN_DBG(FM_NTC | CHIP, "%s ROM version: v%d\n", __func__, mt6635_hw_info.rom_ver); + } else { + WCN_DBG(FM_ERR | CHIP, "get ROM version failed\n"); + if (ret == -4) + WCN_DBG(FM_ERR | CHIP, "signal got when control FM, usually get sig 9 to kill FM process.\n"); + /* now cancel FM power up sequence is recommended. */ + goto out; + } + + /* Wholechip FM Power Up: step 4 download patch */ + dsp_buf = fm_vmalloc(PATCH_BUF_SIZE); + if (!dsp_buf) { + WCN_DBG(FM_ALT | CHIP, "-ENOMEM\n"); + return -ENOMEM; + } + + patch_len = fm_get_patch_path(mt6635_hw_info.rom_ver, dsp_buf, PATCH_BUF_SIZE, patch_tbl); + if (patch_len <= 0) { + WCN_DBG(FM_ALT | CHIP, " fm_get_patch_path failed\n"); + ret = patch_len; + goto out; + } + + ret = fm_download_patch((const unsigned char *)dsp_buf, patch_len, IMG_PATCH); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " DL DSPpatch failed\n"); + goto out; + } + + patch_len = fm_get_coeff_path(mt6635_hw_info.rom_ver, dsp_buf, PATCH_BUF_SIZE, patch_tbl); + if (patch_len <= 0) { + WCN_DBG(FM_ALT | CHIP, " fm_get_coeff_path failed\n"); + ret = patch_len; + goto out; + } + + mt6635_hw_info.rom_ver += 1; + + tmp_reg = dsp_buf[38] | (dsp_buf[39] << 8); /* to be confirmed */ + mt6635_hw_info.patch_ver = (signed int) tmp_reg; + WCN_DBG(FM_NTC | CHIP, "Patch version: 0x%08x\n", mt6635_hw_info.patch_ver); + + ret = fm_download_patch((const unsigned char *)dsp_buf, patch_len, IMG_COEFFICIENT); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " Download DSP coefficient failed\n"); + goto out; + } + + /* Download HWACC coefficient */ + fm_reg_write(0x92, 0x0000); + fm_reg_write(0x90, 0x0040); /* Reset download control */ + fm_reg_write(0x90, 0x0000); /* Disable memory control from host*/ +out: + if (dsp_buf) + fm_vfree(dsp_buf); + return ret; +} +static void mt6635_show_reg(void) +{ + unsigned int host_reg[3] = {0}; + unsigned int debug_reg1[3] = {0}; + unsigned short debug_reg2[3] = {0}; + + fm_host_reg_read(0x1800400C, &host_reg[0]); + fm_host_reg_read(0x18001900, &host_reg[1]); + fm_host_reg_read(0x18008040, &host_reg[2]); + WCN_DBG(FM_ALT | CHIP, + "host read 0x1800400C = 0x%08x, 0x18001900 = 0x%08x, 0x18008040 = 0x%08x\n", + host_reg[0], host_reg[1], host_reg[2]); + + fm_top_reg_read(0x003c, &debug_reg1[0]); + fm_top_reg_read(0x0a18, &debug_reg1[1]); + fm_top_reg_read(0x0160, &debug_reg1[2]); + fm_reg_read(0x7f, &debug_reg2[0]); + fm_reg_read(0x62, &debug_reg2[1]); + fm_reg_read(0x60, &debug_reg2[2]); + WCN_DBG(FM_ALT | CHIP, + "top cr 0x3c = 0x%08x, 0xa18 = 0x%08x, 0x160 = 0x%08x, fmreg 0x7f = 0x%08x, 0x62 = 0x%08x, 0x60 = 0x%08x\n", + debug_reg1[0], debug_reg1[1], debug_reg1[2], debug_reg2[0], debug_reg2[1], debug_reg2[2]); +} + +static signed int mt6635_PowerUp(unsigned short *chip_id, unsigned short *device_id) +{ + signed int ret = 0, count = 0; + unsigned short pkt_size; + unsigned short tmp_reg = 0; + unsigned int tem = 0; + + if (chip_id == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (device_id == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + WCN_DBG(FM_DBG | CHIP, "pwr on seq......\n"); + + /* enable osc_en to conn_infra_cfg */ + ret = fm_host_reg_write(0x18008040, 0x00000001); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "Enable osc_en to conn_infra_cfg failed\n"); + return ret; + } + + /* polling 26M rdy, max 5 times */ + do { + fm_delayus(1000); + ret = fm_host_reg_read(0x18001830, &tem); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "read 0x18001830 failed\n"); + return ret; + } + count++; + } while ((tem & 0x80000) == 0 && count < 5); + + if (count >= 5) + WCN_DBG(FM_ERR | CHIP, "polling 26M rdy failed\n"); + + /* Wholechip FM Power Up: step 1, set common SPI parameter */ + ret = fm_host_reg_write(0x1800400C, 0x0000801F); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup set CSPI failed\n"); + return ret; + } + + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + + pkt_size = mt6635_pwrup_clock_on(cmd_buf, TX_BUF_SIZE); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + + if (ret) { + WCN_DBG(FM_ALT | CHIP, "mt6635_pwrup_clock_on failed\n"); + return ret; + } + + /* Wholechip FM Power Up: step 2, read HW version */ + mt6635_show_reg(); + fm_reg_read(0x62, &tmp_reg); + /* chip_id = tmp_reg; */ + if (tmp_reg == 0x6635) + *chip_id = 0x6635; + *device_id = tmp_reg; + mt6635_hw_info.chip_id = (signed int) tmp_reg; + WCN_DBG(FM_DBG | CHIP, "chip_id:0x%04x\n", tmp_reg); + + if ((mt6635_hw_info.chip_id != 0x6635)) { + mt6635_show_reg(); + WCN_DBG(FM_NTC | CHIP, "fm sys error, reset hw, chip_id = 0x%08x\n", mt6635_hw_info.chip_id); + return -FM_EFW; + + } + /* Wholechip FM Power Up: step 3, patch download */ + ret = mt6635_pwrup_DSP_download(mt6635_patch_tbl); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "mt6635_pwrup_DSP_download failed\n"); + return ret; + } + + /* Wholechip FM Power Up: step 4, FM Digital Init: fm_rgf_maincon */ + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = mt6635_pwrup_digital_init(cmd_buf, TX_BUF_SIZE); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + if (ret) { + WCN_DBG(FM_ALT | CHIP, "mt6635_pwrup_digital_init failed\n"); + return ret; + } + + /* Wholechip FM Power Up: step 5, FM RF fine tune setting */ + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = mt6635_pwrup_fine_tune(cmd_buf, TX_BUF_SIZE); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + if (ret) { + WCN_DBG(FM_ALT | CHIP, "mt6635_pwrup_fine_tune failed\n"); + return ret; + } + + /* Enable connsys FM 2 wire RX */ + fm_reg_write(0x9B, 0xF9AB); /* G2: Set audio output i2s TX mode */ + fm_host_reg_write(0x18008064, 0x00000014); /* G4: Enable aon_osc_clk_cg */ + fm_host_reg_write(0x18008058, 0x888100C3); /* G5: Enable FMAUD trigger, 20170119 */ + fm_host_reg_write(0x18000070, 0x00000000); /* G6: Release fmsys memory power down*/ + + WCN_DBG(FM_NTC | CHIP, "pwr on seq ok\n"); + + return ret; +} + +static signed int mt6635_PowerDown(void) +{ + struct fm_ext_interface *ei = &fm_wcn_ops.ei; + signed int ret = 0; + unsigned int tem = 0; + unsigned short pkt_size; + + WCN_DBG(FM_DBG | CHIP, "pwr down seq\n"); + + /* A0.1. Disable aon_osc_clk_cg */ + ret = fm_host_reg_write(0x18008064, 0x00000004); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " Disable aon_osc_clk_cg failed\n"); + return ret; + } + /* A0.1. Disable FMAUD trigger */ + ret = fm_host_reg_write(0x18008058, 0x88800000); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " Disable FMAUD trigger failed\n"); + return ret; + } + + /* A0.1. issue fmsys memory powr down */ + ret = fm_host_reg_write(0x18000070, 0x00000001); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " Issue fmsys memory powr down failed\n"); + return ret; + } + + /* switch SPI clock to 26M */ + WCN_DBG(FM_DBG | CHIP, "PowerDown: switch SPI clock to 26M\n"); + if (ei->spi_clock_switch) + ret = ei->spi_clock_switch(FM_SPI_SPEED_26M); + else { + ret = -1; + WCN_DBG(FM_ERR | CHIP, "Clock switch cb is null\n"); + } + if (ret) + WCN_DBG(FM_ERR | CHIP, + "PowerDown: Switch SPI clock to 26M failed\n"); + + /* unlock 64M */ + ret = fm_host_reg_read(0x18003004, &tem); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: unlock 64M reg 0x18003004 failed\n", __func__); + ret = fm_host_reg_write(0x18003004, tem & (~(0x1 << 15))); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: unlock 64M failed\n", __func__); + + /* disable 'rf_spi_div_en' */ + ret = fm_host_reg_read(0x18001A00, &tem); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: disable rf_spi_div_en read failed\n", __func__); + ret = fm_host_reg_write(0x18001A00, tem | (0x1 << 28)); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: disable rf_spi_div_en write failed\n", __func__); + + if (ret) + WCN_DBG(FM_ALT | CHIP, "PowerDown: Enable 26M crystal sleep failed\n"); + + /* A0:set audio output I2X Rx mode: */ + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = mt6635_pwrdown(cmd_buf, TX_BUF_SIZE); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + + if (ret) { + WCN_DBG(FM_ALT | CHIP, "mt6635_pwrdown failed\n"); + return ret; + } + + /* RF power off */ + + /* SLP_CTRL setting */ + + /* set common spi fm parameter */ + fm_host_reg_read(0x1800400C, &tem); + tem = tem & 0xFFFF0000; /* D15:D0 */ + ret = fm_host_reg_write(0x1800400C, tem); + if (ret) + WCN_DBG(FM_ALT | CHIP, "set common spi fm parameter failed\n"); + + /* clear 26M crystal sleep */ + WCN_DBG(FM_DBG | CHIP, "PowerDown: Enable 26M crystal sleep,Set 0x18008040[0] = 0x0\n"); + fm_host_reg_read(0x18008040, &tem); + tem = tem & 0xFFFFFFFE; + fm_host_reg_write(0x18008040, tem); + + return ret; +} + +static signed int mt6635_set_freq_fine_tune_reg_op(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 4; + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + /* disable DCOC IDAC auto-disable */ + pkt_size += fm_bop_modify(0x33, 0xFDFF, 0x0000, &buf[pkt_size], buf_size - pkt_size); + /* A1 Host control RF register */ + pkt_size += fm_bop_write(0x60, 0x0007, &buf[pkt_size], buf_size - pkt_size); + /* F3 DCOC @ LNA = 7 */ + pkt_size += fm_bop_write(0x40, 0x01AF, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x03, 0xFAF5, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x07, 0x0100, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x01, 0xEEE8, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x3F, 0x3221, &buf[pkt_size], buf_size - pkt_size); + /* wait 1ms */ + pkt_size += fm_bop_udelay(1000, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_rd_until(0x3F, 0x001F, 0x0001, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x3F, 0x0220, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x40, 0x0100, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x01, 0xAEE8, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x30, 0x0000, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x36, 0x017A, &buf[pkt_size], buf_size - pkt_size); + /* set threshold = 4 */ + pkt_size += fm_bop_modify(0x3F, 0x0FFF, 0x4000, &buf[pkt_size], buf_size - pkt_size); + /* enable DCOC IDAC auto-disable */ + pkt_size += fm_bop_modify(0x33, 0xFDFF, 0x0200, &buf[pkt_size], buf_size - pkt_size); + + /* F4 set DSP control RF register */ + pkt_size += fm_bop_write(0x60, 0x000F, &buf[pkt_size], buf_size - pkt_size); + + return pkt_size - 4; +} + +/* + * mt6635_set_freq_fine_tune - FM RF fine tune setting + * @buf - target buf + * @buf_size - buffer size + * return package size + */ +static signed int mt6635_set_freq_fine_tune(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 0; + + pkt_size = mt6635_set_freq_fine_tune_reg_op(buf, buf_size); + return fm_op_seq_combine_cmd(buf, FM_ENABLE_OPCODE, pkt_size); +} + +static bool mt6635_do_SPI_hopping(unsigned short freq) +{ + struct fm_ext_interface *ei = &fm_wcn_ops.ei; + signed int ret = -1; + + if (!mt6635_SPI_hopping_check(freq)) + return true; + + /* SPI hopping setting*/ + WCN_DBG(FM_NTC | CHIP, + "%s: freq:%d is SPI hopping channel,turn on 64M PLL\n", + __func__, freq); + + /* switch SPI clock to 64MHz */ + if (ei->spi_hopping) + ret = ei->spi_hopping(); + + return ret == 0; +} + +static bool mt6635_SetFreq(unsigned short freq) +{ + signed int ret = 0; + unsigned short pkt_size; + unsigned short chan_para = 0; + unsigned short freq_reg = 0; + unsigned short tmp_reg[6] = {0}; + + fm_cb_op->cur_freq_set(freq); + + /* FM VCO Calibration */ + ret = fm_set_bits(0x60, 0x0007, 0xFFF0); /* Set 0x60 [D3:D0] = 0x07*/ + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: Host Control RF register 0x60 = 0x7 failed\n", __func__); + + fm_delayus(5); + if (freq >= 750) { + fm_reg_write(0x37, 0xF68C); + fm_reg_write(0x38, 0x0B53); + ret = fm_set_bits(0x30, 0x0014 << 8, 0xC0FF); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: Set 0x30 failed\n", __func__); + + } else { + fm_reg_write(0x37, 0x0675); + fm_reg_write(0x38, 0x0F54); + ret = fm_set_bits(0x30, 0x001C << 8, 0xC0FF); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: Set 0x30 failed\n", __func__); + } + ret = fm_set_bits(0x30, 0x0001 << 14, 0xBFFF); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: Set 0x30 failed\n", __func__); + + fm_reg_write(0x40, 0x010F); + fm_delayus(5); + fm_reg_write(0x36, 0x037A); + fm_reg_write(0x32, 0x8000); + fm_delayus(200); + ret = fm_set_bits(0x3D, 0x0001 << 2, 0xFFFB); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: Set 0x3D failed\n", __func__); + + fm_reg_write(0x32, 0x0000); + + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = mt6635_set_freq_fine_tune(cmd_buf, TX_BUF_SIZE); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + if (ret) { + WCN_DBG(FM_ALT | CHIP, "mt6635_pwrup_fine_tune failed\n"); + return ret; + } + + /* A0. Host contrl RF register */ + ret = fm_set_bits(0x60, 0x0007, 0xFFF0); /* Set 0x60 [D3:D0] = 0x07*/ + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: Host Control RF register 0x60 = 0x7 failed\n", __func__); + + /* A0.1 Update FM ADPLL fast tracking mode gain */ + ret = fm_set_bits(0x0F, 0x0455, 0xF800); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: Set FM ADPLL gainA/B=0x455 failed\n", __func__); + + /* A0.2 Set FMSYS cell mode */ + if (mt6635_TDD_chan_check(freq)) { + ret = fm_set_bits(0x30, 0x0008, 0xFFF3); /* use TDD solution */ + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: freq[%d]: use TDD solution failed\n", __func__, freq); + } else { + ret = fm_set_bits(0x30, 0x0000, 0xFFF3); /* default use FDD solution */ + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: freq[%d]: default use FDD solution failed\n", __func__, freq); + } + + /* A0.3 Host control RF register */ + ret = fm_set_bits(0x60, 0x000F, 0xFFF0); /* Set 0x60 [D3:D0] = 0x0F*/ + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: Set 0x60 [D3:D0] = 0x0F failed\n", __func__); + + /* A1 Get Channel parameter from map list*/ + + chan_para = mt6635_chan_para_get(freq); + WCN_DBG(FM_DBG | CHIP, "%s: %d chan para = %d\n", __func__, (signed int) freq, (signed int) chan_para); + + freq_reg = freq; + if (fm_get_channel_space(freq_reg) == 0) + freq_reg *= 10; + + freq_reg = (freq_reg - 6400) * 2 / 10; + + /*A1 Set rgfrf_chan = XXX*/ + ret = fm_set_bits(0x65, freq_reg, 0xFC00); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "%s: set rgfrf_chan = xxx = %d failed\n", __func__, freq_reg); + return false; + } + + ret = fm_set_bits(0x65, (chan_para << 12), 0x0FFF); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "set freq wr 0x65 failed\n"); + return false; + } + + if (!mt6635_do_SPI_hopping(freq)) + WCN_DBG(FM_ERR | CHIP, "%s: spi hopping fail!\n", __func__); + + /* A0. Host contrl RF register */ + ret = fm_set_bits(0x60, 0x0007, 0xFFF0); /* Set 0x60 [D3:D0] = 0x07*/ + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: Host Control RF register 0x60 = 0x7 failed\n", __func__); + + + fm_reg_read(0x62, &tmp_reg[0]); + fm_reg_read(0x64, &tmp_reg[1]); + fm_reg_read(0x69, &tmp_reg[2]); + fm_reg_read(0x6a, &tmp_reg[3]); + fm_reg_read(0x6b, &tmp_reg[4]); + fm_reg_read(0x9b, &tmp_reg[5]); + + WCN_DBG(FM_ALT | CHIP, "%s: Before tune--0x62 0x64 0x69 0x6a 0x6b 0x9b = %04x %04x %04x %04x %04x %04x\n", + __func__, + tmp_reg[0], + tmp_reg[1], + tmp_reg[2], + tmp_reg[3], + tmp_reg[4], + tmp_reg[5]); + + /* A0.3 Host control RF register */ + ret = fm_set_bits(0x60, 0x000F, 0xFF00); /* Set 0x60 [D3:D0] = 0x0F*/ + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: Set 0x60 [D3:D0] = 0x0F failed\n", __func__); + + if (FM_LOCK(cmd_buf_lock)) + return false; + pkt_size = mt6635_tune(cmd_buf, TX_BUF_SIZE, freq, chan_para); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_TUNE | FLAG_TUNE_DONE, SW_RETRY_CNT, TUNE_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + + + /* A0. Host contrl RF register */ + ret = fm_set_bits(0x60, 0x0007, 0xFFF0); /* Set 0x60 [D3:D0] = 0x07*/ + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: Host Control RF register 0x60 = 0x7 failed\n", __func__); + + memset(tmp_reg, 0, sizeof(tmp_reg[0])*6); + + fm_reg_read(0x62, &tmp_reg[0]); + fm_reg_read(0x64, &tmp_reg[1]); + fm_reg_read(0x69, &tmp_reg[2]); + fm_reg_read(0x6a, &tmp_reg[3]); + fm_reg_read(0x6b, &tmp_reg[4]); + fm_reg_read(0x9b, &tmp_reg[5]); + + WCN_DBG(FM_ALT | CHIP, "%s: After tune--0x62 0x64 0x69 0x6a 0x6b 0x9b = %04x %04x %04x %04x %04x %04x\n", + __func__, + tmp_reg[0], + tmp_reg[1], + tmp_reg[2], + tmp_reg[3], + tmp_reg[4], + tmp_reg[5]); + + /* A0.3 Host control RF register */ + ret = fm_set_bits(0x60, 0x000F, 0xFF00); /* Set 0x60 [D3:D0] = 0x0F*/ + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: Set 0x60 [D3:D0] = 0x0F failed\n", __func__); + + if (ret) { + WCN_DBG(FM_ALT | CHIP, "%s: mt6635_tune failed\n", __func__); + return false; + } + + WCN_DBG(FM_DBG | CHIP, "%s: set freq to %d ok\n", __func__, freq); +#if 0 + /* ADPLL setting for dbg */ + fm_top_reg_write(0x0050, 0x00000007); + fm_top_reg_write(0x0A08, 0xFFFFFFFF); + mt6635_bt_write(0x82, 0x11); + mt6635_bt_write(0x83, 0x11); + mt6635_bt_write(0x84, 0x11); + fm_top_reg_write(0x0040, 0x1C1C1C1C); + fm_top_reg_write(0x0044, 0x1C1C1C1C); + fm_reg_write(0x70, 0x0010); + /*0x0806 DCO clk + *0x0802 ref clk + *0x0804 feedback clk + */ + fm_reg_write(0xE0, 0x0806); +#endif + return true; +} + +#define FM_CQI_LOG_PATH "/mnt/sdcard/fmcqilog" + +static signed int mt6635_full_cqi_get(signed int min_freq, signed int max_freq, signed int space, signed int cnt) +{ + signed int ret = 0; + unsigned short pkt_size; + unsigned short freq, orig_freq; + signed int i, j, k; + signed int space_val, max, min, num; + struct mt6635_full_cqi *p_cqi; + unsigned char *cqi_log_title = "Freq, RSSI, PAMD, PR, FPAMD, MR, ATDC, PRX, ATDEV, SMGain, DltaRSSI\n"; + unsigned char cqi_log_buf[100] = { 0 }; + signed int pos; + unsigned char cqi_log_path[100] = { 0 }; + + /* for soft-mute tune, and get cqi */ + freq = fm_cb_op->cur_freq_get(); + if (fm_get_channel_space(freq) == 0) + freq *= 10; + + /* get cqi */ + orig_freq = freq; + if (fm_get_channel_space(min_freq) == 0) + min = min_freq * 10; + else + min = min_freq; + + if (fm_get_channel_space(max_freq) == 0) + max = max_freq * 10; + else + max = max_freq; + + if (space == 0x0001) + space_val = 5; /* 50Khz */ + else if (space == 0x0002) + space_val = 10; /* 100Khz */ + else if (space == 0x0004) + space_val = 20; /* 200Khz */ + else + space_val = 10; + + num = (max - min) / space_val + 1; /* Eg, (8760 - 8750) / 10 + 1 = 2 */ + for (k = 0; (orig_freq == 10000) && (g_dbg_level == 0xffffffff) && (k < cnt); k++) { + WCN_DBG(FM_NTC | CHIP, "cqi file:%d\n", k + 1); + freq = min; + pos = 0; + fm_memcpy(cqi_log_path, FM_CQI_LOG_PATH, strlen(FM_CQI_LOG_PATH)); + if (sprintf(&cqi_log_path[strlen(FM_CQI_LOG_PATH)], "%d.txt", k + 1) < 0) + WCN_DBG(FM_NTC | CHIP, "sprintf fail\n"); + fm_file_write(cqi_log_path, cqi_log_title, strlen(cqi_log_title), &pos); + for (j = 0; j < num; j++) { + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = fm_full_cqi_req(cmd_buf, TX_BUF_SIZE, &freq, 1, 1); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_SM_TUNE, SW_RETRY_CNT, + SM_TUNE_TIMEOUT, fm_get_read_result); + FM_UNLOCK(cmd_buf_lock); + + if (!ret && fm_res) { + WCN_DBG(FM_NTC | CHIP, "smt cqi size %d\n", fm_res->cqi[0]); + p_cqi = (struct mt6635_full_cqi *)&fm_res->cqi[2]; + for (i = 0; i < fm_res->cqi[1]; i++) { + /* just for debug */ + WCN_DBG(FM_NTC | CHIP, + "freq %d, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x\n", + p_cqi[i].ch, p_cqi[i].rssi, p_cqi[i].pamd, + p_cqi[i].pr, p_cqi[i].fpamd, p_cqi[i].mr, + p_cqi[i].atdc, p_cqi[i].prx, p_cqi[i].atdev, + p_cqi[i].smg, p_cqi[i].drssi); + /* format to buffer */ + if (sprintf(cqi_log_buf, + "%04d, %04x, %04x, %04x, %04x, %04x, %04x, %04x, %04x, %04x, %04x,\n", + p_cqi[i].ch, p_cqi[i].rssi, p_cqi[i].pamd, + p_cqi[i].pr, p_cqi[i].fpamd, p_cqi[i].mr, + p_cqi[i].atdc, p_cqi[i].prx, p_cqi[i].atdev, + p_cqi[i].smg, p_cqi[i].drssi) < 0) + WCN_DBG(FM_NTC | CHIP, "sprintf fail\n"); + /* write back to log file */ + fm_file_write(cqi_log_path, cqi_log_buf, strlen(cqi_log_buf), &pos); + } + } else { + WCN_DBG(FM_ALT | CHIP, "smt get CQI failed\n"); + ret = -1; + } + freq += space_val; + } + fm_cb_op->cur_freq_set(0); /* avoid run too much times */ + } + + return ret; +} + +/* + * mt6635_GetCurRSSI - get current freq's RSSI value + * RS=RSSI + * If RS>511, then RSSI(dBm)= (RS-1024)/16*6 + * else RSSI(dBm)= RS/16*6 + */ +static signed int mt6635_GetCurRSSI(signed int *pRSSI) +{ + unsigned short tmp_reg = 0; + + fm_reg_read(FM_RSSI_IND, &tmp_reg); + tmp_reg = tmp_reg & 0x03ff; + + if (pRSSI) { + *pRSSI = (tmp_reg > 511) ? (((tmp_reg - 1024) * 6) >> 4) : ((tmp_reg * 6) >> 4); + WCN_DBG(FM_DBG | CHIP, "rssi:%d, dBm:%d\n", tmp_reg, *pRSSI); + } else { + WCN_DBG(FM_ERR | CHIP, "get rssi para error\n"); + return -FM_EPARA; + } + + return 0; +} + +static unsigned short mt6635_vol_tbl[16] = { 0x0000, 0x0519, 0x066A, 0x0814, + 0x0A2B, 0x0CCD, 0x101D, 0x1449, + 0x198A, 0x2027, 0x287A, 0x32F5, + 0x4027, 0x50C3, 0x65AD, 0x7FFF +}; + +static signed int mt6635_SetVol(unsigned char vol) +{ + signed int ret = 0; + + vol = (vol > 15) ? 15 : vol; + ret = fm_reg_write(0x7D, mt6635_vol_tbl[vol]); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "Set vol=%d Failed\n", vol); + return ret; + } + WCN_DBG(FM_DBG | CHIP, "Set vol=%d OK\n", vol); + + + if (vol == 10) { + fm_print_cmd_fifo(); /* just for debug */ + fm_print_evt_fifo(); + } + return 0; +} + +static signed int mt6635_GetVol(unsigned char *pVol) +{ + int ret = 0; + unsigned short tmp = 0; + signed int i; + + if (pVol == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + ret = fm_reg_read(0x7D, &tmp); + if (ret) { + *pVol = 0; + WCN_DBG(FM_ERR | CHIP, "Get vol Failed\n"); + return ret; + } + + for (i = 0; i < 16; i++) { + if (mt6635_vol_tbl[i] == tmp) { + *pVol = i; + break; + } + } + + WCN_DBG(FM_DBG | CHIP, "Get vol=%d OK\n", *pVol); + return 0; +} + +static signed int mt6635_dump_reg(void) +{ + signed int i; + unsigned short TmpReg = 0; + + for (i = 0; i < 0xff; i++) { + fm_reg_read(i, &TmpReg); + WCN_DBG(FM_NTC | CHIP, "0x%02x=0x%04x\n", i, TmpReg); + } + return 0; +} + +/*0:mono, 1:stereo*/ +static bool mt6635_GetMonoStereo(unsigned short *pMonoStereo) +{ +#define FM_BF_STEREO 0x1000 + unsigned short TmpReg = 0; + + if (pMonoStereo) { + fm_reg_read(FM_RSSI_IND, &TmpReg); + *pMonoStereo = (TmpReg & FM_BF_STEREO) >> 12; + } else { + WCN_DBG(FM_ERR | CHIP, "MonoStero: para err\n"); + return false; + } + + WCN_DBG(FM_NTC | CHIP, "Get MonoStero:0x%04x\n", *pMonoStereo); + return true; +} + +static signed int mt6635_SetMonoStereo(signed int MonoStereo) +{ + signed int ret = 0; + + WCN_DBG(FM_NTC | CHIP, "set to %s\n", MonoStereo ? "mono" : "auto"); + fm_reg_write(0x60, 0x0007); + + if (MonoStereo) /*mono */ + ret = fm_set_bits(0x75, 0x0008, ~0x0008); + else + ret = fm_set_bits(0x75, 0x0000, ~0x0008); + + fm_reg_write(0x60, 0x000F); + return ret; +} + +static signed int mt6635_GetCapArray(signed int *ca) +{ + unsigned short dataRead = 0; + unsigned short tmp = 0; + + if (ca == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + fm_reg_read(0x60, &tmp); + fm_reg_write(0x60, tmp & 0xFFF7); /* 0x60 D3=0 */ + + fm_reg_read(0x26, &dataRead); + *ca = dataRead; + + fm_reg_write(0x60, tmp); /* 0x60 D3=1 */ + return 0; +} + +/* + * mt6635_GetCurPamd - get current freq's PAMD value + * PA=PAMD + * If PA>511 then PAMD(dB)= (PA-1024)/16*6, + * else PAMD(dB)=PA/16*6 + */ +static bool mt6635_GetCurPamd(unsigned short *pPamdLevl) +{ + unsigned short tmp_reg = 0; + unsigned short dBvalue, valid_cnt = 0; + int i, total = 0; + + for (i = 0; i < 8; i++) { + if (fm_reg_read(FM_ADDR_PAMD, &tmp_reg)) { + *pPamdLevl = 0; + return false; + } + + tmp_reg &= 0x03FF; + dBvalue = (tmp_reg > 256) ? ((512 - tmp_reg) * 6 / 16) : 0; + if (dBvalue != 0) { + total += dBvalue; + valid_cnt++; + WCN_DBG(FM_DBG | CHIP, "[%d]PAMD=%d\n", i, dBvalue); + } + fm_delayms(3); + } + if (valid_cnt != 0) + *pPamdLevl = total / valid_cnt; + else + *pPamdLevl = 0; + + WCN_DBG(FM_NTC | CHIP, "PAMD=%d\n", *pPamdLevl); + return true; +} + +static signed int mt6635_i2s_info_get(signed int *ponoff, signed int *pmode, signed int *psample) +{ + if (ponoff == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (pmode == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (psample == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + *ponoff = fm_config.aud_cfg.i2s_info.status; + *pmode = fm_config.aud_cfg.i2s_info.mode; + *psample = fm_config.aud_cfg.i2s_info.rate; + + return 0; +} + +static signed int mt6635_get_audio_info(struct fm_audio_info_t *data) +{ + memcpy(data, &fm_config.aud_cfg, sizeof(struct fm_audio_info_t)); + return 0; +} + +static signed int mt6635_hw_info_get(struct fm_hw_info *req) +{ + if (req == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + req->chip_id = mt6635_hw_info.chip_id; + req->eco_ver = mt6635_hw_info.eco_ver; + req->patch_ver = mt6635_hw_info.patch_ver; + req->rom_ver = mt6635_hw_info.rom_ver; + + return 0; +} + +static signed int mt6635_pre_search(void) +{ + mt6635_RampDown(); + /* disable audio output I2S Tx mode */ + fm_reg_write(0x9B, 0x0000); + + return 0; +} + +static signed int mt6635_restore_search(void) +{ + mt6635_RampDown(); + /* set audio output I2S Tx mode */ + fm_reg_write(0x9B, 0xF9AB); + return 0; +} + +static signed int mt6635_soft_mute_tune(unsigned short freq, signed int *rssi, signed int *valid) +{ + signed int ret = 0; + unsigned short pkt_size; + struct mt6635_full_cqi *p_cqi; + signed int RSSI = 0, PAMD = 0, MR = 0, ATDC = 0; + unsigned int PRX = 0, ATDEV = 0; + unsigned short softmuteGainLvl = 0; + + /* Set rgf_host2dsp_reserve[2] = 1 */ + + ret = mt6635_chan_para_get(freq); + if (ret == 2) + ret = fm_set_bits(FM_CHANNEL_SET, 0x2000, 0x0FFF); /* mdf HiLo */ + else + ret = fm_set_bits(FM_CHANNEL_SET, 0x0000, 0x0FFF); /* clear FA/HL/ATJ */ + + if (!mt6635_do_SPI_hopping(freq)) + WCN_DBG(FM_ERR | CHIP, "%s: spi hopping fail!\n", __func__); + + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = fm_full_cqi_req(cmd_buf, TX_BUF_SIZE, &freq, 1, 1); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_SM_TUNE, SW_RETRY_CNT, SM_TUNE_TIMEOUT, fm_get_read_result); + FM_UNLOCK(cmd_buf_lock); + + if (!ret && fm_res) { + p_cqi = (struct mt6635_full_cqi *)&fm_res->cqi[2]; + /* just for debug */ + WCN_DBG(FM_NTC | CHIP, + "freq %d, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x\n", + p_cqi->ch, p_cqi->rssi, p_cqi->pamd, p_cqi->pr, p_cqi->fpamd, p_cqi->mr, + p_cqi->atdc, p_cqi->prx, p_cqi->atdev, p_cqi->smg, p_cqi->drssi); + RSSI = ((p_cqi->rssi & 0x03FF) >= 512) ? ((p_cqi->rssi & 0x03FF) - 1024) : (p_cqi->rssi & 0x03FF); + PAMD = ((p_cqi->pamd & 0x1FF) >= 256) ? ((p_cqi->pamd & 0x01FF) - 512) : (p_cqi->pamd & 0x01FF); + MR = ((p_cqi->mr & 0x01FF) >= 256) ? ((p_cqi->mr & 0x01FF) - 512) : (p_cqi->mr & 0x01FF); + ATDC = (p_cqi->atdc >= 32768) ? (65536 - p_cqi->atdc) : (p_cqi->atdc); + if (ATDC < 0) + ATDC = (~(ATDC)) - 1; /* Get abs value of ATDC */ + + PRX = (p_cqi->prx & 0x00FF); + ATDEV = p_cqi->atdev; + softmuteGainLvl = p_cqi->smg; + /* check if the channel is valid according to each CQIs */ + if ((fm_config.rx_cfg.long_ana_rssi_th <= RSSI) + && (fm_config.rx_cfg.pamd_th >= PAMD) + && (fm_config.rx_cfg.atdc_th >= ATDC) + && (fm_config.rx_cfg.mr_th <= MR) + && (fm_config.rx_cfg.prx_th <= PRX) + && (ATDEV >= ATDC) /* sync scan algorithm */ + && (fm_config.rx_cfg.smg_th <= softmuteGainLvl)) { + *valid = true; + } else { + *valid = false; + } + *rssi = RSSI; + } else { + WCN_DBG(FM_ALT | CHIP, "smt get CQI failed\n"); + return false; + } + WCN_DBG(FM_NTC | CHIP, "valid=%d\n", *valid); + return true; +} + +static bool mt6635_em_test(unsigned short group_idx, unsigned short item_idx, unsigned int item_value) +{ + return true; +} + +/* +*parm: +* parm.th_type: 0, RSSI. 1, desense RSSI. 2, SMG. +* parm.th_val: threshold value +*/ +static signed int mt6635_set_search_th(signed int idx, signed int val, signed int reserve) +{ + switch (idx) { + case 0: { + fm_config.rx_cfg.long_ana_rssi_th = val; + WCN_DBG(FM_NTC | CHIP, "set rssi th =%d\n", val); + break; + } + case 1: { + fm_config.rx_cfg.desene_rssi_th = val; + WCN_DBG(FM_NTC | CHIP, "set desense rssi th =%d\n", val); + break; + } + case 2: { + fm_config.rx_cfg.smg_th = val; + WCN_DBG(FM_NTC | CHIP, "set smg th =%d\n", val); + break; + } + default: + break; + } + return 0; +} + +static signed int MT6635_low_power_wa_default(signed int fmon) +{ + return 0; +} + +signed int mt6635_fm_low_ops_register(struct fm_callback *cb, struct fm_basic_interface *bi) +{ + signed int ret = 0; + /* Basic functions. */ + + if (bi == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,bi invalid pointer\n", __func__); + return -FM_EPARA; + } + if (cb->cur_freq_get == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,cb->cur_freq_get invalid pointer\n", __func__); + return -FM_EPARA; + } + if (cb->cur_freq_set == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,cb->cur_freq_set invalid pointer\n", __func__); + return -FM_EPARA; + } + fm_cb_op = cb; + + bi->pwron = mt6635_pwron; + bi->pwroff = mt6635_pwroff; + bi->chipid_get = mt6635_get_chipid; + bi->mute = mt6635_Mute; + bi->rampdown = mt6635_RampDown; + bi->pwrupseq = mt6635_PowerUp; + bi->pwrdownseq = mt6635_PowerDown; + bi->setfreq = mt6635_SetFreq; + bi->low_pwr_wa = MT6635_low_power_wa_default; + bi->get_aud_info = mt6635_get_audio_info; + bi->rssiget = mt6635_GetCurRSSI; + bi->volset = mt6635_SetVol; + bi->volget = mt6635_GetVol; + bi->dumpreg = mt6635_dump_reg; + bi->msget = mt6635_GetMonoStereo; + bi->msset = mt6635_SetMonoStereo; + bi->pamdget = mt6635_GetCurPamd; + bi->em = mt6635_em_test; + bi->anaswitch = mt6635_SetAntennaType; + bi->anaget = mt6635_GetAntennaType; + bi->caparray_get = mt6635_GetCapArray; + bi->hwinfo_get = mt6635_hw_info_get; + bi->i2s_get = mt6635_i2s_info_get; + bi->is_dese_chan = mt6635_is_dese_chan; + bi->softmute_tune = mt6635_soft_mute_tune; + bi->desense_check = mt6635_desense_check; + bi->cqi_log = mt6635_full_cqi_get; + bi->pre_search = mt6635_pre_search; + bi->restore_search = mt6635_restore_search; + bi->set_search_th = mt6635_set_search_th; + + cmd_buf_lock = fm_lock_create("31_cmd"); + ret = fm_lock_get(cmd_buf_lock); + + cmd_buf = fm_zalloc(TX_BUF_SIZE + 1); + + if (!cmd_buf) { + WCN_DBG(FM_ALT | CHIP, "6635 fm lib alloc tx buf failed\n"); + ret = -1; + } +#if 0 /* def CONFIG_MTK_FM_50KHZ_SUPPORT */ + cqi_fifo = fm_fifo_create("6628_cqi_fifo", sizeof(struct adapt_fm_cqi), 640); + if (!cqi_fifo) { + WCN_DBG(FM_ALT | CHIP, "6635 fm lib create cqi fifo failed\n"); + ret = -1; + } +#endif + + return ret; +} + +signed int mt6635_fm_low_ops_unregister(struct fm_basic_interface *bi) +{ + signed int ret = 0; + /* Basic functions. */ + if (bi == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,bi invalid pointer\n", __func__); + return -FM_EPARA; + } + +#if 0 /* def CONFIG_MTK_FM_50KHZ_SUPPORT */ + fm_fifo_release(cqi_fifo); +#endif + + if (cmd_buf) { + fm_free(cmd_buf); + cmd_buf = NULL; + } + + ret = fm_lock_put(cmd_buf_lock); + fm_memset(bi, 0, sizeof(struct fm_basic_interface)); + + fm_cb_op = NULL; + + return ret; +} + +static const signed char mt6635_chan_para_map[] = { +/* 0, X, 1, X, 2, X, 3, X, 4, X, 5, X, 6, X, 7, X, 8, X, 9, X */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, /* 6500~6595 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6600~6695 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, /* 6700~6795 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6800~6895 */ + 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6900~6995 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7000~7095 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7100~7195 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, /* 7200~7295 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7300~7395 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, /* 7400~7495 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7500~7595 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, /* 7600~7695 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7700~7795 */ + 8, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7800~7895 */ + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7900~7995 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8000~8095 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8100~8195 */ + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8200~8295 */ + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, /* 8300~8395 */ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8400~8495 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8500~8595 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8600~8695 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8700~8795 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8800~8895 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8900~8995 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9000~9095 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9100~9195 */ + 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9200~9295 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9300~9395 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9400~9495 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9500~9595 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9600~9695 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9700~9795 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, /* 9800~9895 */ + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, /* 9900~9995 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10000~10095 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10100~10195 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10200~10295 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10300~10395 */ + 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10400~10495 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, /* 10500~10595 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10600~10695 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, /* 10700~10795 */ + 0 /* 10800 */ +}; + +static const unsigned short mt6635_scan_dese_list[] = { + 6910, 6920, 7680, 7800, 8450, 9210, 9220, 9230, 9590, 9600, 9830, 9900, 9980, 9990, 10400, 10750, 10760 +}; + +static const unsigned short mt6635_SPI_hopping_list[] = { + 6510, 6520, 6530, 7780, 7790, 7800, 7810, 7820, 9090, 9100, 9110, 9120, 10380, 10390, 10400, 10410, 10420 +}; + +static const unsigned short mt6635_I2S_hopping_list[] = { + 6550, 6760, 6960, 6970, 7170, 7370, 7580, 7780, 7990, 8810, 9210, 9220, 10240 +}; + +static const unsigned short mt6635_TDD_list[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 6500~6595 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 6600~6695 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 6700~6795 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 6800~6895 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 6900~6995 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7000~7095 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7100~7195 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7200~7295 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7300~7395 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7400~7495 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7500~7595 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7600~7695 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7700~7795 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7800~7895 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7900~7995 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8000~8095 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8100~8195 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8200~8295 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8300~8395 */ + 0x0101, 0x0000, 0x0000, 0x0000, 0x0000, /* 8400~8495 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8500~8595 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8600~8695 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8700~8795 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8800~8895 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8900~8995 */ + 0x0000, 0x0000, 0x0101, 0x0101, 0x0101, /* 9000~9095 */ + 0x0101, 0x0000, 0x0000, 0x0000, 0x0000, /* 9100~9195 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9200~9295 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9300~9395 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9400~9495 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9500~9595 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9600~9695 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0100, /* 9700~9795 */ + 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, /* 9800~9895 */ + 0x0101, 0x0101, 0x0001, 0x0000, 0x0000, /* 9900~9995 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10000~10095 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10100~10195 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10200~10295 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10300~10395 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10400~10495 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10500~10595 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0100, /* 10600~10695 */ + 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, /* 10700~10795 */ + 0x0001 /* 10800 */ +}; + +static const unsigned short mt6635_TDD_Mask[] = { + 0x0001, 0x0010, 0x0100, 0x1000 +}; + +/* return value: 0, not a de-sense channel; 1, this is a de-sense channel; else error no */ +static signed int mt6635_is_dese_chan(unsigned short freq) +{ + signed int size; + + if (1 == HQA_ZERO_DESENSE_MAP) /*HQA only :skip desense channel check. */ + return 0; + + size = ARRAY_SIZE(mt6635_scan_dese_list); + + if (fm_get_channel_space(freq) == 0) + freq *= 10; + + while (size) { + if (mt6635_scan_dese_list[size - 1] == freq) + return 1; + + size--; + } + + return 0; +} + +/* return value: +*1, is desense channel and rssi is less than threshold; +*0, not desense channel or it is but rssi is more than threshold. +*/ +static signed int mt6635_desense_check(unsigned short freq, signed int rssi) +{ + if (mt6635_is_dese_chan(freq)) { + if (rssi < fm_config.rx_cfg.desene_rssi_th) + return 1; + + WCN_DBG(FM_DBG | CHIP, "desen_rssi %d th:%d\n", rssi, fm_config.rx_cfg.desene_rssi_th); + } + return 0; +} + +static bool mt6635_TDD_chan_check(unsigned short freq) +{ + unsigned int i = 0; + unsigned short freq_tmp = freq; + signed int ret = 0; + + ret = fm_get_channel_space(freq_tmp); + if (ret == 0) + freq_tmp *= 10; + else if (ret == -1) + return false; + + i = (freq_tmp - 6500) / 5; + if ((i / 4) >= ARRAY_SIZE(mt6635_TDD_list)) { + WCN_DBG(FM_ERR | CHIP, "Freq index out of range(%d),max(%zd)\n", + i / 4, ARRAY_SIZE(mt6635_TDD_list)); + return false; + } + + if (mt6635_TDD_list[i / 4] & mt6635_TDD_Mask[i % 4]) { + WCN_DBG(FM_DBG | CHIP, "Freq %d use TDD solution\n", freq); + return true; + } else + return false; +} + +/* get channel parameter, HL side/ FA / ATJ */ +static unsigned short mt6635_chan_para_get(unsigned short freq) +{ + signed int pos, size; + + if (1 == HQA_RETURN_ZERO_MAP) { + WCN_DBG(FM_NTC | CHIP, "HQA_RETURN_ZERO_CHAN mt6635_chan_para_map enabled!\n"); + return 0; + } + + if (fm_get_channel_space(freq) == 0) + freq *= 10; + + if (freq < 6500) + return 0; + + pos = (freq - 6500) / 5; + + size = ARRAY_SIZE(mt6635_chan_para_map); + + pos = (pos > (size - 1)) ? (size - 1) : pos; + + return mt6635_chan_para_map[pos]; +} + + +static bool mt6635_SPI_hopping_check(unsigned short freq) +{ + signed int size; + + size = ARRAY_SIZE(mt6635_SPI_hopping_list); + + if (fm_get_channel_space(freq) == 0) + freq *= 10; + + while (size) { + if (mt6635_SPI_hopping_list[size - 1] == freq) + return 1; + size--; + } + + return 0; +} diff --git a/drivers/misc/mediatek/connectivity/fmradio/chips/mt6635/pub/mt6635_fm_lib.c b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6635/pub/mt6635_fm_lib.c new file mode 100644 index 0000000000000000000000000000000000000000..ab7126b34b991c14d064279b0c77197cadfdeccc --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6635/pub/mt6635_fm_lib.c @@ -0,0 +1,2109 @@ +/* +* Copyright (C) 2016 MediaTek Inc. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. +*/ +#include +#include + +#include "osal_typedef.h" +#include "stp_exp.h" +#include "wmt_exp.h" +#include "plat.h" + +#include "fm_typedef.h" +#include "fm_dbg.h" +#include "fm_err.h" +#include "fm_interface.h" +#include "fm_stdlib.h" +#include "fm_patch.h" +#include "fm_utils.h" +#include "fm_link.h" +#include "fm_config.h" +#include "fm_cmd.h" + +#include "mt6635_fm_reg.h" +#include "mt6635_fm_lib.h" + +#define HQA_RETURN_ZERO_MAP 0 +#define HQA_ZERO_DESENSE_MAP 0 + +/* #include "mach/mt_gpio.h" */ + +/* #define MT6635_FM_PATCH_PATH "/etc/firmware/mt6635/mt6635_fm_patch.bin" */ +/* #define MT6635_FM_COEFF_PATH "/etc/firmware/mt6635/mt6635_fm_coeff.bin" */ +/* #define MT6635_FM_HWCOEFF_PATH "/etc/firmware/mt6635/mt6635_fm_hwcoeff.bin" */ +/* #define MT6635_FM_ROM_PATH "/etc/firmware/mt6635/mt6635_fm_rom.bin" */ + +static struct fm_patch_tbl mt6635_patch_tbl[5] = { + {FM_ROM_V1, "mt6635_fm_v1_patch.bin", "mt6635_fm_v1_coeff.bin", NULL, NULL}, + {FM_ROM_V2, "mt6635_fm_v2_patch.bin", "mt6635_fm_v2_coeff.bin", NULL, NULL}, + {FM_ROM_V3, "mt6635_fm_v3_patch.bin", "mt6635_fm_v3_coeff.bin", NULL, NULL}, + {FM_ROM_V4, "mt6635_fm_v4_patch.bin", "mt6635_fm_v4_coeff.bin", NULL, NULL}, + {FM_ROM_V5, "mt6635_fm_v5_patch.bin", "mt6635_fm_v5_coeff.bin", NULL, NULL} +}; + +static struct fm_hw_info mt6635_hw_info = { + .chip_id = 0x00006635, + .eco_ver = 0x00000000, + .rom_ver = 0x00000000, + .patch_ver = 0x00000000, + .reserve = 0x00000000, +}; + +static struct fm_callback *fm_cb_op; + +/* static signed int Chip_Version = mt6635_E1; */ + +/* static bool rssi_th_set = false; */ + +#if 0 /* def CONFIG_MTK_FM_50KHZ_SUPPORT */ +static struct fm_fifo *cqi_fifo; +#endif +static signed int mt6635_is_dese_chan(unsigned short freq); + +static unsigned short mt6635_chan_para_get(unsigned short freq); +static signed int mt6635_desense_check(unsigned short freq, signed int rssi); +static bool mt6635_TDD_chan_check(unsigned short freq); +static bool mt6635_SPI_hopping_check(unsigned short freq); +static signed int mt6635_soft_mute_tune(unsigned short freq, signed int *rssi, signed int *valid); + +static bool mt6635_do_SPI_hopping_26M(void) +{ + struct fm_ext_interface *ei = &fm_wcn_ops.ei; + signed int ret = 0; + unsigned int tem = 0, hw_ver_id = 0; + + /* switch SPI clock to 26MHz */ + if (ei->spi_clock_switch) + ret = ei->spi_clock_switch(FM_SPI_SPEED_26M); + else { + ret = -1; + WCN_DBG(FM_ERR | CHIP, "Clock switch cb is null\n"); + } + if (ret) + WCN_DBG(FM_ERR | CHIP, "Switch SPI clock to 26MHz failed\n"); + + ret = fm_host_reg_read(0x80021010, &hw_ver_id); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: read HW ver. failed\n", __func__); + hw_ver_id = hw_ver_id >> 16; + + /* unlock 64M */ + if (hw_ver_id == 0x1005 || hw_ver_id == 0x1002) { + ret = fm_host_reg_read(0x80023008, &tem); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: unlock 64M reg 0x880023008 failed\n", __func__); + ret = fm_host_reg_write(0x80023008, tem & (~(0x1 << 21))); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: unlock 64M failed\n", __func__); + } else { + ret = fm_host_reg_read(0x81021128, &tem); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: unlock 64M reg 0x81021128 failed\n", __func__); + ret = fm_host_reg_write(0x81021128, tem & ~0x1); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: unlock 64M failed\n", __func__); + ret = fm_host_reg_read(0x81024040, &tem); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: unlock 64M reg 0x81024040 failed\n", __func__); + ret = fm_host_reg_write(0x81024040, tem & ~0x3); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: unlock 64M failed\n", __func__); + } + + return ret == 0; +} + +static bool mt6635_do_SPI_hopping_64M(unsigned short freq) +{ + struct fm_ext_interface *ei = &fm_wcn_ops.ei; + signed int ret = 0; + signed int i = 0; + unsigned int tem = 0, hw_ver_id = 0; + bool flag_spi_hopping = false; + + if (!mt6635_SPI_hopping_check(freq)) + return true; + + /* SPI hopping setting*/ + WCN_DBG(FM_NTC | CHIP, + "%s: freq:%d is SPI hopping channel,turn on 64M PLL\n", + __func__, freq); + + ret = fm_host_reg_read(0x80021010, &hw_ver_id); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: read HW ver. failed\n", __func__); + WCN_DBG(FM_NTC | CHIP, "%s: HW ver. ID = 0x%08x\n", __func__, hw_ver_id); + hw_ver_id = hw_ver_id >> 16; + + /* lock 64M */ + if (hw_ver_id == 0x1005 || hw_ver_id == 0x1002) { + ret = fm_host_reg_read(0x80023008, &tem); + if (ret) + WCN_DBG(FM_ERR | CHIP, + "%s: lock 64M reg 0x80023008 failed\n", __func__); + ret = fm_host_reg_write(0x80023008, tem | (0x1 << 21)); + if (ret) + WCN_DBG(FM_ERR | CHIP, + "%s: lock 64M failed\n", __func__); + } else { + ret = fm_host_reg_read(0x81021128, &tem); + if (ret) + WCN_DBG(FM_ERR | CHIP, + "%s: read reg 0x81021128 failed\n", __func__); + ret = fm_host_reg_write(0x81021128, tem | 0x1); + if (ret) + WCN_DBG(FM_ERR | CHIP, + "%s: enable 'rf_spi_div_en' failed\n", __func__); + ret = fm_host_reg_read(0x81024040, &tem); + if (ret) + WCN_DBG(FM_ERR | CHIP, + "%s: lock 64M reg 0x81024040 failed\n", __func__); + ret = fm_host_reg_write(0x81024040, tem | 0x3); + if (ret) + WCN_DBG(FM_ERR | CHIP, + "%s: lock 64M failed\n", __func__); + } + for (i = 0; i < 100; i++) { /*rd 0x80021118 until D27 ==1*/ + + fm_host_reg_read(0x80021118, &tem); + + if (tem & 0x08000000) { + WCN_DBG(FM_NTC | CHIP, + "%s: POLLING PLL_RDY success !\n", __func__); + if (ei->spi_clock_switch) + flag_spi_hopping = ei->spi_clock_switch(FM_SPI_SPEED_64M) == 0; + break; + } + fm_delayus(10); + } + if (false == flag_spi_hopping) + WCN_DBG(FM_ERR | CHIP, + "%s: Polling to read rd 0x80021118[27] ==0x1 failed!\n", + __func__); + + return flag_spi_hopping; +} + +static signed int mt6635_pwron(signed int data) +{ + if (fm_wcn_ops.ei.wmt_func_on && !fm_wcn_ops.ei.wmt_func_on()) { + WCN_DBG(FM_ERR | CHIP, "WMT turn on FM Fail!\n"); + return -FM_ELINK; + } + + WCN_DBG(FM_NTC | CHIP, "WMT turn on FM OK!\n"); + return 0; +} + +static signed int mt6635_pwroff(signed int data) +{ + if (fm_wcn_ops.ei.wmt_func_off && !fm_wcn_ops.ei.wmt_func_off()) { + WCN_DBG(FM_ERR | CHIP, "WMT turn off FM Fail!\n"); + return -FM_ELINK; + } + + WCN_DBG(FM_NTC | CHIP, "WMT turn off FM OK!\n"); + return 0; +} + +static unsigned short mt6635_get_chipid(void) +{ + return 0x6635; +} + +/* MT6635_SetAntennaType - set Antenna type + * @type - 1, Short Antenna; 0, Long Antenna + */ +static signed int mt6635_SetAntennaType(signed int type) +{ + unsigned short dataRead = 0; + + WCN_DBG(FM_DBG | CHIP, "set ana to %s\n", type ? "short" : "long"); + fm_reg_read(FM_MAIN_CG2_CTRL, &dataRead); + + if (type) + dataRead |= ANTENNA_TYPE; + else + dataRead &= (~ANTENNA_TYPE); + + fm_reg_write(FM_MAIN_CG2_CTRL, dataRead); + + return 0; +} + +static signed int mt6635_GetAntennaType(void) +{ + unsigned short dataRead = 0; + + fm_reg_read(FM_MAIN_CG2_CTRL, &dataRead); + WCN_DBG(FM_DBG | CHIP, "get ana type: %s\n", (dataRead & ANTENNA_TYPE) ? "short" : "long"); + + if (dataRead & ANTENNA_TYPE) + return FM_ANA_SHORT; /* short antenna */ + else + return FM_ANA_LONG; /* long antenna */ +} + +static signed int mt6635_Mute(bool mute) +{ + signed int ret = 0; + unsigned short dataRead = 0; + + WCN_DBG(FM_DBG | CHIP, "set %s\n", mute ? "mute" : "unmute"); + /* fm_reg_read(FM_MAIN_CTRL, &dataRead); */ + fm_reg_read(0x9C, &dataRead); + + /* fm_top_reg_write(0x0050, 0x00000007); */ + if (mute == 1) + ret = fm_reg_write(0x9C, (dataRead & 0xFFFC) | 0x0003); + else + ret = fm_reg_write(0x9C, (dataRead & 0xFFFC)); + + /* fm_top_reg_write(0x0050, 0x0000000F); */ + + return ret; +} + +static signed int mt6635_rampdown_reg_op(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 4; + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + + /* A1. Clear DSP state */ + pkt_size += fm_bop_modify(FM_MAIN_CTRL, 0xFFF0, 0x0000, &buf[pkt_size], buf_size - pkt_size); + /* A2. Set DSP ramp down state */ + pkt_size += fm_bop_modify(FM_MAIN_CTRL, 0xFFFF, RAMP_DOWN, &buf[pkt_size], buf_size - pkt_size); + /* @Wait for STC_DONE interrupt@ */ + pkt_size += fm_bop_rd_until(FM_MAIN_INTR, FM_INTR_STC_DONE, FM_INTR_STC_DONE, &buf[pkt_size], + buf_size - pkt_size); + /* A6. Clear DSP ramp down state */ + pkt_size += fm_bop_modify(FM_MAIN_CTRL, (~RAMP_DOWN), 0x0000, &buf[pkt_size], buf_size - pkt_size); + /* A7. Write 1 clear the STC_DONE interrupt status flag */ + pkt_size += fm_bop_modify(FM_MAIN_INTR, 0xFFFF, FM_INTR_STC_DONE, &buf[pkt_size], buf_size - pkt_size); + + return pkt_size - 4; +} +/* + * mt6635_rampdown - f/w will wait for STC_DONE interrupt + * @buf - target buf + * @buf_size - buffer size + * return package size + */ +static signed int mt6635_rampdown(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 0; + + pkt_size = mt6635_rampdown_reg_op(buf, buf_size); + return fm_op_seq_combine_cmd(buf, FM_RAMPDOWN_OPCODE, pkt_size); +} + +/* FMSYS Ramp Down Sequence*/ +static signed int mt6635_RampDown(void) +{ + signed int ret = 0; + unsigned short pkt_size; + /* unsigned short tmp; */ + + WCN_DBG(FM_DBG | CHIP, "ramp down\n"); + + mt6635_do_SPI_hopping_26M(); + + /* A0.0 Host control RF register */ + ret = fm_set_bits(0x60, 0x0007, 0xFFF0); /*Set 0x60 [D3:D0] = 0x7*/ + if (ret) { + WCN_DBG(FM_ERR | CHIP, "ramp down HOST control rf: Set 0x60 [D3:D0] = 0x7 failed\n"); + return ret; + } + + /* A0.1 Update FM ADPLL fast tracking mode gain */ + ret = fm_set_bits(0x0F, 0x0000, 0xF800); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "ramp down ADPLL gainA/B: Set 0xFH [D10:D0] = 0x000 failed\n"); + return ret; + } + + /* A0.2 Host control RF register */ + ret = fm_set_bits(0x60, 0x000F, 0xFFF0); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "ramp down Host control RF registerwr top 0x60 failed\n"); + return ret; + } + /* A1. Clear dsp state*/ + ret = fm_set_bits(0x63, 0x0000, 0xFFF0); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "ramp down Host control RF registerwr top 0x63 failed\n"); + return ret; + } + /* A2. Set DSP ramp down state*/ + ret = fm_set_bits(0x63, 0x0010, 0xFFEF); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "ramp down Host control RF registerwr top 0x63 failed\n"); + return ret; + } + + /* A3. Clear STC_DONE interrupt */ + ret = fm_reg_write(FM_MAIN_INTRMASK, 0x0000); + if (ret) + WCN_DBG(FM_ERR | CHIP, "ramp down clean FM_MAIN_INTRMASK failed\n"); + + ret = fm_reg_write(FM_MAIN_EXTINTRMASK, 0x0000); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "ramp down clean FM_MAIN_EXTINTRMASK failed\n"); + return ret; + } + + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = mt6635_rampdown(cmd_buf, TX_BUF_SIZE); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_RAMPDOWN, SW_RETRY_CNT, RAMPDOWN_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + + if (ret) { + WCN_DBG(FM_ERR | CHIP, "ramp down failed\n"); + return ret; + } + + ret = fm_reg_write(FM_MAIN_EXTINTRMASK, 0x0021); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "ramp down wr FM_MAIN_EXTINTRMASK failed\n"); + return ret; + } + + ret = fm_reg_write(FM_MAIN_INTRMASK, 0x0021); + if (ret) + WCN_DBG(FM_ERR | CHIP, "ramp down wr FM_MAIN_INTRMASK failed\n"); + + return ret; +} + +static signed int mt6635_get_rom_version(void) +{ + unsigned short flag_Romcode = 0; + unsigned short nRomVersion = 0; +#define ROM_CODE_READY 0x0001 + signed int ret = 0; + + /* A1.1 DSP rom code version request enable --- set 0x61 b15=1 */ + fm_set_bits(0x61, 0x8000, 0x7FFF); + + /* A1.2 Release ASIP reset --- set 0x61 b1=1 */ + fm_set_bits(0x61, 0x0002, 0xFFFD); + + /* A1.3 Enable ASIP power --- set 0x61 b0=0 */ + fm_set_bits(0x61, 0x0000, 0xFFFE); + + /* A1.4 Wait until DSP code version ready --- wait loop 1ms */ + do { + fm_delayus(1000); + ret = fm_reg_read(0x84, &flag_Romcode); + /* ret=-4 means signal got when control FM. usually get sig 9 to kill FM process. */ + /* now cancel FM power up sequence is recommended. */ + if (ret) + return ret; + + WCN_DBG(FM_DBG | CHIP, "ROM_CODE_READY flag 0x84=%x\n", flag_Romcode); + } while (flag_Romcode != ROM_CODE_READY); + + + /* A1.5 Read FM DSP code version --- rd 0x83[15:8] */ + fm_reg_read(0x83, &nRomVersion); + nRomVersion = (nRomVersion >> 8); + + /* A1.6 DSP rom code version request disable --- set 0x61 b15=0 */ + fm_set_bits(0x61, 0x0000, 0x7FFF); + + /* A1.7 Reset ASIP --- set 0x61[1:0] = 1 */ + fm_set_bits(0x61, 0x0001, 0xFFFC); + + return (signed int) nRomVersion; +} + +static signed int mt6635_pwrup_clock_on_reg_op(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 4; + unsigned short de_emphasis; + /* unsigned short osc_freq; */ + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + de_emphasis = fm_config.rx_cfg.deemphasis; + de_emphasis &= 0x0001; /* rang 0~1 */ + /* 2,turn on top clock */ + pkt_size += fm_bop_top_write(0xA00, 0xFFFFFFFF, &buf[pkt_size], buf_size - pkt_size); + /* wr top cr a00 ffffffff */ + + /* 3,enable MTCMOS */ + pkt_size += fm_bop_top_write(0x160, 0x00000030, &buf[pkt_size], buf_size - pkt_size); + /* wr top 160 30 */ + + pkt_size += fm_bop_top_write(0x160, 0x00000035, &buf[pkt_size], buf_size - pkt_size); + /* wr top 160 35 */ + pkt_size += fm_bop_udelay(10, &buf[pkt_size], buf_size - pkt_size); + /* delay 10us */ + pkt_size += fm_bop_top_write(0x160, 0x00000015, &buf[pkt_size], buf_size - pkt_size); + /* wr top 160 15 */ + pkt_size += fm_bop_top_write(0x160, 0x00000005, &buf[pkt_size], buf_size - pkt_size); + /* wr top 160 5 */ + + pkt_size += fm_bop_udelay(10, &buf[pkt_size], buf_size - pkt_size); + /* delay 10us */ + pkt_size += fm_bop_top_write(0x160, 0x00000045, &buf[pkt_size], buf_size - pkt_size); + /* wr top 160 45 */ + + /* 4,set comspi fm slave dumy count */ + pkt_size += fm_bop_write(0x7f, 0x801f, &buf[pkt_size], buf_size - pkt_size); /* wr 7f 801f */ + + /* A. FM digital clock enable */ + /* A1. Wait 3ms */ + pkt_size += fm_bop_udelay(3000, &buf[pkt_size], buf_size - pkt_size); + + /* A2. Release HW clock gating*/ + pkt_size += fm_bop_write(0x60, 0x0007, &buf[pkt_size], buf_size - pkt_size); /* wr 60 7 */ + /* A3. Enable DSP auto clock gating */ + pkt_size += fm_bop_write(0x70, 0x0040, &buf[pkt_size], buf_size - pkt_size); /* wr 70 0040 */ + /* A4. Deemphasis setting: Set 0 for 50us, Set 1 for 75us */ + pkt_size += fm_bop_modify(0x61, ~DE_EMPHASIS, (de_emphasis << 12), &buf[pkt_size], buf_size - pkt_size); + + return pkt_size - 4; +} +/* + * mt6635_pwrup_clock_on - Wholechip FM Power Up: step 1, FM Digital Clock enable + * @buf - target buf + * @buf_size - buffer size + * return package size + */ +static signed int mt6635_pwrup_clock_on(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 0; + + pkt_size = mt6635_pwrup_clock_on_reg_op(buf, buf_size); + return fm_op_seq_combine_cmd(buf, FM_ENABLE_OPCODE, pkt_size); +} + +static signed int mt6635_pwrup_digital_init_reg_op(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 4; + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + /* Part D FM RF&ADPLL divider setting */ + + /* D2.1 set cell mode */ + /* wr 30 D3:D2 00:FDD(default),01:both.10: TDD, 11 FDD */ + /* pkt_size += fm_bop_modify(0x30, 0xFFF3, 0x0000, &buf[pkt_size], buf_size - pkt_size); */ + + /* D2.2 set ADPLL divider */ + pkt_size += fm_bop_write(0x21, 0xE000, &buf[pkt_size], buf_size - pkt_size); /* wr 21 E000 */ + /* D2.3 set SDM coeff0_H */ + pkt_size += fm_bop_write(0xD8, 0x03F0, &buf[pkt_size], buf_size - pkt_size); /* wr D8 0x03F0 */ + /* D2.4 set SDM coeff0_L */ + pkt_size += fm_bop_write(0xD9, 0x3F04, &buf[pkt_size], buf_size - pkt_size); /* wr D9 0x3F04 */ + /* D2.5 set SDM coeff1_H */ + pkt_size += fm_bop_write(0xDA, 0x0014, &buf[pkt_size], buf_size - pkt_size); /* wr DA 0x0014 */ + /* D2.6 set SDM coeff1_L */ + pkt_size += fm_bop_write(0xDB, 0x2A38, &buf[pkt_size], buf_size - pkt_size); /* wr DB 0x2A38 */ + /* D2.7 set 26M clock */ + pkt_size += fm_bop_write(0x23, 0x4000, &buf[pkt_size], buf_size - pkt_size); /* wr 23 4000 */ + + /* Part E: FM Digital Init: fm_rgf_maincon */ + + /* E4. Set appropriate interrupt mask behavior as desired */ + /* Enable stc_done_mask, Enable rgf_rds_mask*/ + pkt_size += fm_bop_write(0x6A, 0x0021, &buf[pkt_size], buf_size - pkt_size); /* wr 6A 0021 */ + pkt_size += fm_bop_write(0x6B, 0x0021, &buf[pkt_size], buf_size - pkt_size); /* wr 6B 0021 */ + + /* E5. Enable hw auto control */ + pkt_size += fm_bop_write(0x60, 0x0000000F, &buf[pkt_size], buf_size - pkt_size); /* wr 60 f */ + + /* E6. Release ASIP reset */ + pkt_size += fm_bop_modify(0x61, 0xFFFD, 0x0002, &buf[pkt_size], buf_size - pkt_size); /* wr 61 D1=1 */ + /* E7. Enable ASIP power */ + pkt_size += fm_bop_modify(0x61, 0xFFFE, 0x0000, &buf[pkt_size], buf_size - pkt_size); /* wr 61 D0=0 */ + + /* E8 */ + pkt_size += fm_bop_udelay(100000, &buf[pkt_size], buf_size - pkt_size); /* delay 100ms */ + /* E9. Check HW initial complete */ + pkt_size += fm_bop_rd_until(0x64, 0x001F, 0x0002, &buf[pkt_size], buf_size - pkt_size); /* Poll 64[0~4] = 2 */ + + return pkt_size - 4; +} + +/* + * mt6635_pwrup_digital_init - Wholechip FM Power Up: step 4, FM Digital Init: fm_rgf_maincon + * @buf - target buf + * @buf_size - buffer size + * return package size + */ +static signed int mt6635_pwrup_digital_init(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 0; + + pkt_size = mt6635_pwrup_digital_init_reg_op(buf, buf_size); + return fm_op_seq_combine_cmd(buf, FM_ENABLE_OPCODE, pkt_size); +} + +static signed int mt6635_pwrup_fine_tune_reg_op(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 4; + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + /* F1 set host control RF register */ + pkt_size += fm_bop_write(0x60, 0x00000007, &buf[pkt_size], buf_size - pkt_size); + + /* F2 fine tune RF setting */ + pkt_size += fm_bop_write(0x01, 0xBEE8, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x03, 0xF6ED, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x15, 0x0D80, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x16, 0x0068, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x17, 0x092A, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x34, 0x807F, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x35, 0x311E, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x40, 0x0100, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x03, 0xFAF5, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x05, 0x7A80, &buf[pkt_size], buf_size - pkt_size); + + /* F4 set DSP control RF register */ + pkt_size += fm_bop_write(0x60, 0x0000000F, &buf[pkt_size], buf_size - pkt_size); + + return pkt_size - 4; +} + +/* + * mt6635_pwrup_fine_tune - Wholechip FM Power Up: step 5, FM RF fine tune setting + * @buf - target buf + * @buf_size - buffer size + * return package size + */ +static signed int mt6635_pwrup_fine_tune(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 0; + + pkt_size = mt6635_pwrup_fine_tune_reg_op(buf, buf_size); + return fm_op_seq_combine_cmd(buf, FM_ENABLE_OPCODE, pkt_size); +} + +static signed int mt6635_pwrdown_reg_op(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 4; + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + /* A1:set audio output I2S Tx mode: */ + pkt_size += fm_bop_modify(0x9B, 0xFFF8, 0x0000, &buf[pkt_size], buf_size - pkt_size); + + /* B0:Disable HW clock control */ + pkt_size += fm_bop_write(0x60, 0x330F, &buf[pkt_size], buf_size - pkt_size); + /* B1:Reset ASIP : Set 0x61, [D1 = 0, D0=1] */ + pkt_size += fm_bop_modify(0x61, 0xFFFD, 0x0001, &buf[pkt_size], buf_size - pkt_size); + + /* B2:digital core + digital rgf reset */ + pkt_size += fm_bop_modify(0x6E, 0xFFF8, 0x0000, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_modify(0x6E, 0xFFF8, 0x0000, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_modify(0x6E, 0xFFF8, 0x0000, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_modify(0x6E, 0xFFF8, 0x0000, &buf[pkt_size], buf_size - pkt_size); + + /* B3:Disable all clock */ + pkt_size += fm_bop_write(0x60, 0x0000, &buf[pkt_size], buf_size - pkt_size); + /* B4:Reset rgfrf */ + pkt_size += fm_bop_write(0x60, 0x4000, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x60, 0x0000, &buf[pkt_size], buf_size - pkt_size); + + /* MTCMOS power off */ + /* C0:disable MTCMOS */ + pkt_size += fm_bop_top_write(0x160, 0x0005, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_top_write(0x160, 0x0015, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_top_write(0x160, 0x0035, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_top_write(0x160, 0x0030, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_top_rd_until(0x160, 0x0000000A, 0x0, &buf[pkt_size], buf_size - pkt_size); + + return pkt_size - 4; +} +/* + * mt6635_pwrdown - Wholechip FM Power down: Digital Modem Power Down + * @buf - target buf + * @buf_size - buffer size + * return package size + */ +static signed int mt6635_pwrdown(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 0; + + pkt_size = mt6635_pwrdown_reg_op(buf, buf_size); + return fm_op_seq_combine_cmd(buf, FM_ENABLE_OPCODE, pkt_size); +} + +static signed int mt6635_tune_reg_op(unsigned char *buf, signed int buf_size, unsigned short freq, + unsigned short chan_para) +{ + signed int pkt_size = 4; + + WCN_DBG(FM_ALT | CHIP, "%s enter mt6635_tune function\n", __func__); + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + /* A2 Enable hardware controlled tuning sequence */ + pkt_size += fm_bop_modify(FM_MAIN_CTRL, 0xFFF8, TUNE, &buf[pkt_size], buf_size - pkt_size);/*Set 0x63 D0=1*/ + /* Wait for STC_DONE interrupt */ + + +#ifdef FM_TUNE_USE_POLL + /* A3 Wait for STC_DONE interrupt */ + /* A4 Wait for STC_DONE interrupt status flag */ + pkt_size += fm_bop_rd_until(FM_MAIN_INTR, FM_INTR_STC_DONE, + FM_INTR_STC_DONE, &buf[pkt_size], buf_size - pkt_size); + /* A6 Write 1 clear the STC_DONE interrupt status flag */ + pkt_size += fm_bop_modify(FM_MAIN_INTR, 0xFFFF, FM_INTR_STC_DONE, &buf[pkt_size], buf_size - pkt_size); +#endif + + pkt_size += fm_bop_udelay(100000, &buf[pkt_size], buf_size - pkt_size); + WCN_DBG(FM_ALT | CHIP, "mt6635_tune delay 100 ms wait 0x69 to change\n"); + + WCN_DBG(FM_ALT | CHIP, "%s leave mt6635_tune function\n", __func__); + + return pkt_size - 4; +} + +/* + * mt6635_tune - execute tune action, + * @buf - target buf + * @buf_size - buffer size + * @freq - 760 ~ 1080, 100KHz unit + * return package size + */ +static signed int mt6635_tune(unsigned char *buf, signed int buf_size, unsigned short freq, + unsigned short chan_para) +{ + signed int pkt_size = 0; + + pkt_size = mt6635_tune_reg_op(buf, buf_size, freq, chan_para); + return fm_op_seq_combine_cmd(buf, FM_TUNE_OPCODE, pkt_size); +} + +/* + * mt6635_pwrup_DSP_download - execute dsp/coeff patch dl action, + * @patch_tbl - current chip patch table + * return patch dl ok or not + */ +static signed int mt6635_pwrup_DSP_download(struct fm_patch_tbl *patch_tbl) +{ +#define PATCH_BUF_SIZE (4096*6) + signed int ret = 0; + signed int patch_len = 0; + unsigned char *dsp_buf = NULL; + unsigned short tmp_reg = 0; + + if (fm_wcn_ops.ei.wmt_ic_info_get) + mt6635_hw_info.eco_ver = fm_wcn_ops.ei.wmt_ic_info_get(); + WCN_DBG(FM_DBG | CHIP, "ECO version:0x%08x\n", mt6635_hw_info.eco_ver); + + /* Wholechip FM Power Up: step 3, get mt6635 DSP ROM version */ + ret = mt6635_get_rom_version(); + if (ret >= 0) { + mt6635_hw_info.rom_ver = ret; + WCN_DBG(FM_NTC | CHIP, "%s ROM version: v%d\n", __func__, mt6635_hw_info.rom_ver); + } else { + WCN_DBG(FM_ERR | CHIP, "get ROM version failed\n"); + if (ret == -4) + WCN_DBG(FM_ERR | CHIP, "signal got when control FM, usually get sig 9 to kill FM process.\n"); + /* now cancel FM power up sequence is recommended. */ + goto out; + } + + /* Wholechip FM Power Up: step 4 download patch */ + dsp_buf = fm_vmalloc(PATCH_BUF_SIZE); + if (!dsp_buf) { + WCN_DBG(FM_ALT | CHIP, "-ENOMEM\n"); + return -ENOMEM; + } + + patch_len = fm_get_patch_path(mt6635_hw_info.rom_ver, dsp_buf, PATCH_BUF_SIZE, patch_tbl); + if (patch_len <= 0) { + WCN_DBG(FM_ALT | CHIP, " fm_get_patch_path failed\n"); + ret = patch_len; + goto out; + } + + ret = fm_download_patch((const unsigned char *)dsp_buf, patch_len, IMG_PATCH); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " DL DSPpatch failed\n"); + goto out; + } + + patch_len = fm_get_coeff_path(mt6635_hw_info.rom_ver, dsp_buf, PATCH_BUF_SIZE, patch_tbl); + if (patch_len <= 0) { + WCN_DBG(FM_ALT | CHIP, " fm_get_coeff_path failed\n"); + ret = patch_len; + goto out; + } + + mt6635_hw_info.rom_ver += 1; + + tmp_reg = dsp_buf[38] | (dsp_buf[39] << 8); /* to be confirmed */ + mt6635_hw_info.patch_ver = (signed int) tmp_reg; + WCN_DBG(FM_NTC | CHIP, "Patch version: 0x%08x\n", mt6635_hw_info.patch_ver); + + ret = fm_download_patch((const unsigned char *)dsp_buf, patch_len, IMG_COEFFICIENT); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " Download DSP coefficient failed\n"); + goto out; + } + + /* Download HWACC coefficient */ + fm_reg_write(0x92, 0x0000); + fm_reg_write(0x90, 0x0040); /* Reset download control */ + fm_reg_write(0x90, 0x0000); /* Disable memory control from host*/ +out: + if (dsp_buf) + fm_vfree(dsp_buf); + return ret; +} +static void mt6635_show_reg(void) +{ + unsigned int host_reg[3] = {0}; + unsigned int debug_reg1[3] = {0}; + unsigned short debug_reg2[3] = {0}; + + fm_host_reg_read(0x8102600C, &host_reg[0]); + fm_host_reg_read(0x81021500, &host_reg[1]); + fm_host_reg_read(0x81021200, &host_reg[2]); + WCN_DBG(FM_ALT | CHIP, + "host read 0x8102600C = 0x%08x, 0x81021500 = 0x%08x, 0x81021200 = 0x%08x\n", + host_reg[0], host_reg[1], host_reg[2]); + + fm_top_reg_read(0x003c, &debug_reg1[0]); + fm_top_reg_read(0x0a18, &debug_reg1[1]); + fm_top_reg_read(0x0160, &debug_reg1[2]); + fm_reg_read(0x7f, &debug_reg2[0]); + fm_reg_read(0x62, &debug_reg2[1]); + fm_reg_read(0x60, &debug_reg2[2]); + WCN_DBG(FM_ALT | CHIP, + "top cr 0x3c = 0x%08x, 0xa18 = 0x%08x, 0x160 = 0x%08x, fmreg 0x7f = 0x%08x, 0x62 = 0x%08x, 0x60 = 0x%08x\n", + debug_reg1[0], debug_reg1[1], debug_reg1[2], debug_reg2[0], debug_reg2[1], debug_reg2[2]); +} + +static signed int mt6635_PowerUp(unsigned short *chip_id, unsigned short *device_id) +{ + signed int ret = 0; + unsigned short pkt_size; + unsigned short tmp_reg = 0; + unsigned int tem = 0; + unsigned int host_reg = 0; + + if (chip_id == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (device_id == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + WCN_DBG(FM_DBG | CHIP, "pwr on seq......\n"); + + /* Wholechip FM Power Up: step 1, set common SPI parameter */ + ret = fm_host_reg_write(0x8102600C, 0x0000801F); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup set CSPI failed\n"); + return ret; + } + + + /* Set top_clk_en_adie to trigger sleep controller before FM power on */ + ret = fm_host_reg_write(0x81021500, 0x00000003); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup set top_clk_en_adie failed\n"); + return ret; + } + + /* Disable 26M crystal sleep */ + fm_host_reg_read(0x81021200, &tem); /* Set 0x81021200[23] = 0x1 */ + tem = tem | 0x00800000; + fm_host_reg_write(0x81021200, tem); + + /* Enable the power_RG_ready */ + ret = fm_top_reg_read(0x0a18, &host_reg); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "power up read top 0xa18 failed\n"); + return ret; + } + ret = fm_top_reg_write(0x0a18, host_reg | (0x3 << 26)); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "power up write top 0xa18 failed\n"); + return ret; + } + + /* Enable the buffer to top digital domain */ + ret = fm_top_reg_read(0x0a18, &host_reg); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "power up read top 0xa18 failed\n"); + return ret; + } + ret = fm_top_reg_write(0x0a18, host_reg | (0x1f << 25)); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "power up write top 0xa18 failed\n"); + return ret; + } + + /* Enable the buffer to FM RF domain */ + ret = fm_top_reg_read(0x0a18, &host_reg); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "power up read top 0xa18 failed\n"); + return ret; + } + ret = fm_top_reg_write(0x0a18, host_reg | (0x01 << 12)); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "power up write top 0xa18 failed\n"); + return ret; + } + + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + + pkt_size = mt6635_pwrup_clock_on(cmd_buf, TX_BUF_SIZE); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + + if (ret) { + WCN_DBG(FM_ALT | CHIP, "mt6635_pwrup_clock_on failed\n"); + return ret; + } + + /* Wholechip FM Power Up: step 2, read HW version */ + mt6635_show_reg(); + fm_reg_read(0x62, &tmp_reg); + /* chip_id = tmp_reg; */ + if (tmp_reg == 0x6635) + *chip_id = 0x6635; + *device_id = tmp_reg; + mt6635_hw_info.chip_id = (signed int) tmp_reg; + WCN_DBG(FM_DBG | CHIP, "chip_id:0x%04x\n", tmp_reg); + + if ((mt6635_hw_info.chip_id != 0x6635)) { + mt6635_show_reg(); + WCN_DBG(FM_NTC | CHIP, "fm sys error, reset hw, chip_id = 0x%08x\n", mt6635_hw_info.chip_id); + return -FM_EFW; + + } + /* Wholechip FM Power Up: step 3, patch download */ + ret = mt6635_pwrup_DSP_download(mt6635_patch_tbl); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "mt6635_pwrup_DSP_download failed\n"); + return ret; + } + + /* Wholechip FM Power Up: step 4, FM Digital Init: fm_rgf_maincon */ + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = mt6635_pwrup_digital_init(cmd_buf, TX_BUF_SIZE); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + if (ret) { + WCN_DBG(FM_ALT | CHIP, "mt6635_pwrup_digital_init failed\n"); + return ret; + } + + /* Wholechip FM Power Up: step 5, FM RF fine tune setting */ + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = mt6635_pwrup_fine_tune(cmd_buf, TX_BUF_SIZE); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + if (ret) { + WCN_DBG(FM_ALT | CHIP, "mt6635_pwrup_fine_tune failed\n"); + return ret; + } + + /* Enable connsys FM 2 wire RX */ + fm_reg_write(0x9B, 0xF9AB); /* G2: Set audio output i2s TX mode */ + fm_host_reg_write(0x81024064, 0x00000014); /* G3: Enable aon_osc_clk_cg */ + fm_host_reg_write(0x81024058, 0x888100C3); /* G4: Enable FMAUD trigger, 20170119 */ + fm_host_reg_write(0x81024054, 0x00000100); /* G5: Release fmsys memory power down*/ + + WCN_DBG(FM_NTC | CHIP, "pwr on seq ok\n"); + + return ret; +} + +static signed int mt6635_PowerDown(void) +{ + signed int ret = 0; + unsigned int tem = 0; + unsigned short pkt_size; + unsigned int host_reg = 0; + /* unsigned int host_reg = 0; */ + + WCN_DBG(FM_DBG | CHIP, "pwr down seq\n"); + + /* A0.1. Disable aon_osc_clk_cg */ + ret = fm_host_reg_write(0x81024064, 0x00000004); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " Disable aon_osc_clk_cg failed\n"); + return ret; + } + /* A0.1. Disable FMAUD trigger */ + ret = fm_host_reg_write(0x81024058, 0x88800000); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " Disable FMAUD trigger failed\n"); + return ret; + } + + /* A0.1. issue fmsys memory powr down */ + ret = fm_host_reg_write(0x81024054, 0x00000180); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " Issue fmsys memory powr down failed\n"); + return ret; + } + + mt6635_do_SPI_hopping_26M(); + + /* Enable 26M crystal sleep */ + WCN_DBG(FM_DBG | CHIP, "PowerDown: Enable 26M crystal sleep,Set 0x81021200[23] = 0x0\n"); + fm_host_reg_read(0x81021200, &tem); /* Set 0x81021200[23] = 0x0 */ + tem = tem & 0xFF7FFFFF; + ret = fm_host_reg_write(0x81021200, tem); + + if (ret) + WCN_DBG(FM_ALT | CHIP, "PowerDown: Enable 26M crystal sleep,Set 0x81021200[23] = 0x0 failed\n"); + + /* A0:set audio output I2X Rx mode: */ + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = mt6635_pwrdown(cmd_buf, TX_BUF_SIZE); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + + if (ret) { + WCN_DBG(FM_ALT | CHIP, "mt6635_pwrdown failed\n"); + return ret; + } + + /* RF power off */ + /* Disnable the buffer to fm rf domain */ + ret = fm_top_reg_read(0x0a18, &host_reg); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "power down read top 0xa18 failed\n"); + return ret; + } + ret = fm_top_reg_write(0x0a18, host_reg & (~(0x1 << 12))); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "power down write top 0xa18 failed\n"); + return ret; + } + + return ret; +} + +static signed int mt6635_set_freq_fine_tune_reg_op(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 4; + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + /* disable DCOC IDAC auto-disable */ + pkt_size += fm_bop_modify(0x33, 0xFDFF, 0x0000, &buf[pkt_size], buf_size - pkt_size); + /* A1 Host control RF register */ + pkt_size += fm_bop_write(0x60, 0x0007, &buf[pkt_size], buf_size - pkt_size); + /* F3 DCOC @ LNA = 7 */ + pkt_size += fm_bop_write(0x40, 0x01AF, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x03, 0xFAF5, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x07, 0x0100, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x01, 0xEEE8, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x3F, 0x3221, &buf[pkt_size], buf_size - pkt_size); + /* wait 1ms */ + pkt_size += fm_bop_udelay(1000, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_rd_until(0x3F, 0x001F, 0x0001, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x3F, 0x0220, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x40, 0x0100, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x01, 0xAEE8, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x30, 0x0000, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x36, 0x017A, &buf[pkt_size], buf_size - pkt_size); + /* set threshold = 4 */ + pkt_size += fm_bop_modify(0x3F, 0x0FFF, 0x4000, &buf[pkt_size], buf_size - pkt_size); + /* enable DCOC IDAC auto-disable */ + pkt_size += fm_bop_modify(0x33, 0xFDFF, 0x0200, &buf[pkt_size], buf_size - pkt_size); + + /* F4 set DSP control RF register */ + pkt_size += fm_bop_write(0x60, 0x000F, &buf[pkt_size], buf_size - pkt_size); + + return pkt_size - 4; +} + +/* + * mt6635_set_freq_fine_tune - FM RF fine tune setting + * @buf - target buf + * @buf_size - buffer size + * return package size + */ +static signed int mt6635_set_freq_fine_tune(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 0; + + pkt_size = mt6635_set_freq_fine_tune_reg_op(buf, buf_size); + return fm_op_seq_combine_cmd(buf, FM_ENABLE_OPCODE, pkt_size); +} + +static bool mt6635_SetFreq(unsigned short freq) +{ + signed int ret = 0; + unsigned short pkt_size; + unsigned short chan_para = 0; + unsigned short freq_reg = 0; + unsigned short tmp_reg[6] = {0}; + + fm_cb_op->cur_freq_set(freq); + + /* FM VCO Calibration */ + ret = fm_set_bits(0x60, 0x0007, 0xFFF0); /* Set 0x60 [D3:D0] = 0x07*/ + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: Host Control RF register 0x60 = 0x7 failed\n", __func__); + + fm_delayus(5); + if (freq >= 750) { + fm_reg_write(0x37, 0xF68C); + fm_reg_write(0x38, 0x0B53); + ret = fm_set_bits(0x30, 0x0014 << 8, 0xC0FF); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: Set 0x30 failed\n", __func__); + + } else { + fm_reg_write(0x37, 0x0675); + fm_reg_write(0x38, 0x0F54); + ret = fm_set_bits(0x30, 0x001C << 8, 0xC0FF); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: Set 0x30 failed\n", __func__); + } + ret = fm_set_bits(0x30, 0x0001 << 14, 0xBFFF); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: Set 0x30 failed\n", __func__); + + fm_reg_write(0x40, 0x010F); + fm_delayus(5); + fm_reg_write(0x36, 0x037A); + fm_reg_write(0x32, 0x8000); + fm_delayus(200); + ret = fm_set_bits(0x3D, 0x0001 << 2, 0xFFFB); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: Set 0x3D failed\n", __func__); + + fm_reg_write(0x32, 0x0000); + + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = mt6635_set_freq_fine_tune(cmd_buf, TX_BUF_SIZE); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + if (ret) { + WCN_DBG(FM_ALT | CHIP, "mt6635_pwrup_fine_tune failed\n"); + return ret; + } + + /* A0. Host contrl RF register */ + ret = fm_set_bits(0x60, 0x0007, 0xFFF0); /* Set 0x60 [D3:D0] = 0x07*/ + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: Host Control RF register 0x60 = 0x7 failed\n", __func__); + + /* A0.1 Update FM ADPLL fast tracking mode gain */ + ret = fm_set_bits(0x0F, 0x0455, 0xF800); + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: Set FM ADPLL gainA/B=0x455 failed\n", __func__); + + /* A0.2 Set FMSYS cell mode */ + if (mt6635_TDD_chan_check(freq)) { + ret = fm_set_bits(0x30, 0x0008, 0xFFF3); /* use TDD solution */ + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: freq[%d]: use TDD solution failed\n", __func__, freq); + } else { + ret = fm_set_bits(0x30, 0x0000, 0xFFF3); /* default use FDD solution */ + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: freq[%d]: default use FDD solution failed\n", __func__, freq); + } + + /* A0.3 Host control RF register */ + ret = fm_set_bits(0x60, 0x000F, 0xFFF0); /* Set 0x60 [D3:D0] = 0x0F*/ + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: Set 0x60 [D3:D0] = 0x0F failed\n", __func__); + + /* A1 Get Channel parameter from map list*/ + + chan_para = mt6635_chan_para_get(freq); + WCN_DBG(FM_DBG | CHIP, "%s: %d chan para = %d\n", __func__, (signed int) freq, (signed int) chan_para); + + freq_reg = freq; + if (fm_get_channel_space(freq_reg) == 0) + freq_reg *= 10; + + freq_reg = (freq_reg - 6400) * 2 / 10; + + /*A1 Set rgfrf_chan = XXX*/ + ret = fm_set_bits(0x65, freq_reg, 0xFC00); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "%s: set rgfrf_chan = xxx = %d failed\n", __func__, freq_reg); + return false; + } + + ret = fm_set_bits(0x65, (chan_para << 12), 0x0FFF); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "set freq wr 0x65 failed\n"); + return false; + } + + if (!mt6635_do_SPI_hopping_64M(freq)) + WCN_DBG(FM_ERR | CHIP, "%s: spi hopping fail!\n", __func__); + + /* A0. Host contrl RF register */ + ret = fm_set_bits(0x60, 0x0007, 0xFFF0); /* Set 0x60 [D3:D0] = 0x07*/ + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: Host Control RF register 0x60 = 0x7 failed\n", __func__); + + + fm_reg_read(0x62, &tmp_reg[0]); + fm_reg_read(0x64, &tmp_reg[1]); + fm_reg_read(0x69, &tmp_reg[2]); + fm_reg_read(0x6a, &tmp_reg[3]); + fm_reg_read(0x6b, &tmp_reg[4]); + fm_reg_read(0x9b, &tmp_reg[5]); + + WCN_DBG(FM_ALT | CHIP, "%s: Before tune--0x62 0x64 0x69 0x6a 0x6b 0x9b = %04x %04x %04x %04x %04x %04x\n", + __func__, + tmp_reg[0], + tmp_reg[1], + tmp_reg[2], + tmp_reg[3], + tmp_reg[4], + tmp_reg[5]); + + /* A0.3 Host control RF register */ + ret = fm_set_bits(0x60, 0x000F, 0xFF00); /* Set 0x60 [D3:D0] = 0x0F*/ + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: Set 0x60 [D3:D0] = 0x0F failed\n", __func__); + + if (FM_LOCK(cmd_buf_lock)) + return false; + pkt_size = mt6635_tune(cmd_buf, TX_BUF_SIZE, freq, chan_para); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_TUNE | FLAG_TUNE_DONE, SW_RETRY_CNT, TUNE_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + + + /* A0. Host contrl RF register */ + ret = fm_set_bits(0x60, 0x0007, 0xFFF0); /* Set 0x60 [D3:D0] = 0x07*/ + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: Host Control RF register 0x60 = 0x7 failed\n", __func__); + + memset(tmp_reg, 0, sizeof(tmp_reg[0])*6); + + fm_reg_read(0x62, &tmp_reg[0]); + fm_reg_read(0x64, &tmp_reg[1]); + fm_reg_read(0x69, &tmp_reg[2]); + fm_reg_read(0x6a, &tmp_reg[3]); + fm_reg_read(0x6b, &tmp_reg[4]); + fm_reg_read(0x9b, &tmp_reg[5]); + + WCN_DBG(FM_ALT | CHIP, "%s: After tune--0x62 0x64 0x69 0x6a 0x6b 0x9b = %04x %04x %04x %04x %04x %04x\n", + __func__, + tmp_reg[0], + tmp_reg[1], + tmp_reg[2], + tmp_reg[3], + tmp_reg[4], + tmp_reg[5]); + + /* A0.3 Host control RF register */ + ret = fm_set_bits(0x60, 0x000F, 0xFF00); /* Set 0x60 [D3:D0] = 0x0F*/ + if (ret) + WCN_DBG(FM_ERR | CHIP, "%s: Set 0x60 [D3:D0] = 0x0F failed\n", __func__); + + if (ret) { + WCN_DBG(FM_ALT | CHIP, "%s: mt6635_tune failed\n", __func__); + return false; + } + + WCN_DBG(FM_DBG | CHIP, "%s: set freq to %d ok\n", __func__, freq); +#if 0 + /* ADPLL setting for dbg */ + fm_top_reg_write(0x0050, 0x00000007); + fm_top_reg_write(0x0A08, 0xFFFFFFFF); + mt6635_bt_write(0x82, 0x11); + mt6635_bt_write(0x83, 0x11); + mt6635_bt_write(0x84, 0x11); + fm_top_reg_write(0x0040, 0x1C1C1C1C); + fm_top_reg_write(0x0044, 0x1C1C1C1C); + fm_reg_write(0x70, 0x0010); + /*0x0806 DCO clk + *0x0802 ref clk + *0x0804 feedback clk + */ + fm_reg_write(0xE0, 0x0806); +#endif + return true; +} + +#define FM_CQI_LOG_PATH "/mnt/sdcard/fmcqilog" + +static signed int mt6635_full_cqi_get(signed int min_freq, signed int max_freq, signed int space, signed int cnt) +{ + signed int ret = 0; + unsigned short pkt_size; + unsigned short freq, orig_freq; + signed int i, j, k; + signed int space_val, max, min, num; + struct mt6635_full_cqi *p_cqi; + unsigned char *cqi_log_title = "Freq, RSSI, PAMD, PR, FPAMD, MR, ATDC, PRX, ATDEV, SMGain, DltaRSSI\n"; + unsigned char cqi_log_buf[100] = { 0 }; + signed int pos; + unsigned char cqi_log_path[100] = { 0 }; + + /* for soft-mute tune, and get cqi */ + freq = fm_cb_op->cur_freq_get(); + if (fm_get_channel_space(freq) == 0) + freq *= 10; + + /* get cqi */ + orig_freq = freq; + if (fm_get_channel_space(min_freq) == 0) + min = min_freq * 10; + else + min = min_freq; + + if (fm_get_channel_space(max_freq) == 0) + max = max_freq * 10; + else + max = max_freq; + + if (space == 0x0001) + space_val = 5; /* 50Khz */ + else if (space == 0x0002) + space_val = 10; /* 100Khz */ + else if (space == 0x0004) + space_val = 20; /* 200Khz */ + else + space_val = 10; + + num = (max - min) / space_val + 1; /* Eg, (8760 - 8750) / 10 + 1 = 2 */ + for (k = 0; (orig_freq == 10000) && (g_dbg_level == 0xffffffff) && (k < cnt); k++) { + WCN_DBG(FM_NTC | CHIP, "cqi file:%d\n", k + 1); + freq = min; + pos = 0; + fm_memcpy(cqi_log_path, FM_CQI_LOG_PATH, strlen(FM_CQI_LOG_PATH)); + if (sprintf(&cqi_log_path[strlen(FM_CQI_LOG_PATH)], "%d.txt", k + 1) < 0) + WCN_DBG(FM_NTC | CHIP, "sprintf fail\n"); + fm_file_write(cqi_log_path, cqi_log_title, strlen(cqi_log_title), &pos); + for (j = 0; j < num; j++) { + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = fm_full_cqi_req(cmd_buf, TX_BUF_SIZE, &freq, 1, 1); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_SM_TUNE, SW_RETRY_CNT, + SM_TUNE_TIMEOUT, fm_get_read_result); + FM_UNLOCK(cmd_buf_lock); + + if (!ret && fm_res) { + WCN_DBG(FM_NTC | CHIP, "smt cqi size %d\n", fm_res->cqi[0]); + p_cqi = (struct mt6635_full_cqi *)&fm_res->cqi[2]; + for (i = 0; i < fm_res->cqi[1]; i++) { + /* just for debug */ + WCN_DBG(FM_NTC | CHIP, + "freq %d, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x\n", + p_cqi[i].ch, p_cqi[i].rssi, p_cqi[i].pamd, + p_cqi[i].pr, p_cqi[i].fpamd, p_cqi[i].mr, + p_cqi[i].atdc, p_cqi[i].prx, p_cqi[i].atdev, + p_cqi[i].smg, p_cqi[i].drssi); + /* format to buffer */ + if (sprintf(cqi_log_buf, + "%04d, %04x, %04x, %04x, %04x, %04x, %04x, %04x, %04x, %04x, %04x,\n", + p_cqi[i].ch, p_cqi[i].rssi, p_cqi[i].pamd, + p_cqi[i].pr, p_cqi[i].fpamd, p_cqi[i].mr, + p_cqi[i].atdc, p_cqi[i].prx, p_cqi[i].atdev, + p_cqi[i].smg, p_cqi[i].drssi) < 0) + WCN_DBG(FM_NTC | CHIP, "sprintf fail\n"); + /* write back to log file */ + fm_file_write(cqi_log_path, cqi_log_buf, strlen(cqi_log_buf), &pos); + } + } else { + WCN_DBG(FM_ALT | CHIP, "smt get CQI failed\n"); + ret = -1; + } + freq += space_val; + } + fm_cb_op->cur_freq_set(0); /* avoid run too much times */ + } + + return ret; +} + +static unsigned short mt6635_read_dsp_reg(unsigned short addr) +{ + unsigned short regValue = 0; + + fm_reg_write(0x60, 0x07); + fm_reg_write(0xE2, addr); + fm_reg_write(0xE1, 0x01); + fm_reg_read(0xE4, ®Value); + fm_reg_write(0x60, 0x0F); + + return regValue; +} + +static bool mt6635_is_valid_freq(unsigned short freq) +{ + int i = 0; + bool valid = false; + signed int RSSI = 0, PAMD = 0, MR = 0; + unsigned int PRX = 0; + unsigned short softmuteGainLvl = 0; + unsigned short tmp_reg = 0; + + for (i = 0; i < 8; i++) { + fm_reg_read(0x6C, &tmp_reg); + RSSI += (((tmp_reg & 0x03FF) >= 512) ? + ((tmp_reg & 0x03FF) - 1024) : (tmp_reg & 0x03FF)) >> 3; + fm_reg_read(0xB4, &tmp_reg); + PAMD += (((tmp_reg & 0x1FF) >= 256) ? + ((tmp_reg & 0x01FF) - 512) : (tmp_reg & 0x01FF)) >> 3; + tmp_reg = mt6635_read_dsp_reg(0x4E1); + PRX += (tmp_reg & 0x00FF) >> 3; + fm_reg_read(0xBD, &tmp_reg); + MR += (((tmp_reg & 0x01FF) >= 256) ? + ((tmp_reg & 0x01FF) - 512) : (tmp_reg & 0x01FF)) >> 3; + tmp_reg = mt6635_read_dsp_reg(0x2C4); + softmuteGainLvl += tmp_reg >> 3; + fm_delayus(2250); + } + + if ((fm_config.rx_cfg.long_ana_rssi_th <= RSSI) + && (fm_config.rx_cfg.pamd_th >= PAMD) + && (fm_config.rx_cfg.mr_th <= MR) + && (fm_config.rx_cfg.prx_th <= PRX) + && (fm_config.rx_cfg.smg_th <= softmuteGainLvl)) { + valid = true; + } + + WCN_DBG(FM_DBG | CHIP, + "freq %d valid=%d, %d, %d, 0x%04x, 0x%04x, 0x%04x\n", + freq, valid, RSSI, PAMD, PRX, MR, softmuteGainLvl); + + return valid; +} + +/* + * mt6635_GetCurRSSI - get current freq's RSSI value + * RS=RSSI + * If RS>511, then RSSI(dBm)= (RS-1024)/16*6 + * else RSSI(dBm)= RS/16*6 + */ +static signed int mt6635_GetCurRSSI(signed int *pRSSI) +{ + unsigned short tmp_reg = 0; + + fm_reg_read(FM_RSSI_IND, &tmp_reg); + tmp_reg = tmp_reg & 0x03ff; + + if (pRSSI) { + *pRSSI = (tmp_reg > 511) ? (((tmp_reg - 1024) * 6) >> 4) : ((tmp_reg * 6) >> 4); + WCN_DBG(FM_DBG | CHIP, "rssi:%d, dBm:%d\n", tmp_reg, *pRSSI); + } else { + WCN_DBG(FM_ERR | CHIP, "get rssi para error\n"); + return -FM_EPARA; + } + + return 0; +} + +static unsigned short mt6635_vol_tbl[16] = { 0x0000, 0x0519, 0x066A, 0x0814, + 0x0A2B, 0x0CCD, 0x101D, 0x1449, + 0x198A, 0x2027, 0x287A, 0x32F5, + 0x4027, 0x50C3, 0x65AD, 0x7FFF +}; + +static signed int mt6635_SetVol(unsigned char vol) +{ + signed int ret = 0; + + vol = (vol > 15) ? 15 : vol; + ret = fm_reg_write(0x7D, mt6635_vol_tbl[vol]); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "Set vol=%d Failed\n", vol); + return ret; + } + WCN_DBG(FM_DBG | CHIP, "Set vol=%d OK\n", vol); + + + if (vol == 10) { + fm_print_cmd_fifo(); /* just for debug */ + fm_print_evt_fifo(); + } + return 0; +} + +static signed int mt6635_GetVol(unsigned char *pVol) +{ + int ret = 0; + unsigned short tmp = 0; + signed int i; + + if (pVol == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + ret = fm_reg_read(0x7D, &tmp); + if (ret) { + *pVol = 0; + WCN_DBG(FM_ERR | CHIP, "Get vol Failed\n"); + return ret; + } + + for (i = 0; i < 16; i++) { + if (mt6635_vol_tbl[i] == tmp) { + *pVol = i; + break; + } + } + + WCN_DBG(FM_DBG | CHIP, "Get vol=%d OK\n", *pVol); + return 0; +} + +static signed int mt6635_dump_reg(void) +{ + signed int i; + unsigned short TmpReg = 0; + + for (i = 0; i < 0xff; i++) { + fm_reg_read(i, &TmpReg); + WCN_DBG(FM_NTC | CHIP, "0x%02x=0x%04x\n", i, TmpReg); + } + return 0; +} + +/*0:mono, 1:stereo*/ +static bool mt6635_GetMonoStereo(unsigned short *pMonoStereo) +{ +#define FM_BF_STEREO 0x1000 + unsigned short TmpReg = 0; + + if (pMonoStereo) { + fm_reg_read(FM_RSSI_IND, &TmpReg); + *pMonoStereo = (TmpReg & FM_BF_STEREO) >> 12; + } else { + WCN_DBG(FM_ERR | CHIP, "MonoStero: para err\n"); + return false; + } + + WCN_DBG(FM_NTC | CHIP, "Get MonoStero:0x%04x\n", *pMonoStereo); + return true; +} + +static signed int mt6635_SetMonoStereo(signed int MonoStereo) +{ + signed int ret = 0; + + WCN_DBG(FM_NTC | CHIP, "set to %s\n", MonoStereo ? "mono" : "auto"); + fm_reg_write(0x60, 0x0007); + + if (MonoStereo) /*mono */ + ret = fm_set_bits(0x75, 0x0008, ~0x0008); + else + ret = fm_set_bits(0x75, 0x0000, ~0x0008); + + fm_reg_write(0x60, 0x000F); + return ret; +} + +static signed int mt6635_GetCapArray(signed int *ca) +{ + unsigned short dataRead = 0; + unsigned short tmp = 0; + + if (ca == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + fm_reg_read(0x60, &tmp); + fm_reg_write(0x60, tmp & 0xFFF7); /* 0x60 D3=0 */ + + fm_reg_read(0x26, &dataRead); + *ca = dataRead; + + fm_reg_write(0x60, tmp); /* 0x60 D3=1 */ + return 0; +} + +/* + * mt6635_GetCurPamd - get current freq's PAMD value + * PA=PAMD + * If PA>511 then PAMD(dB)= (PA-1024)/16*6, + * else PAMD(dB)=PA/16*6 + */ +static bool mt6635_GetCurPamd(unsigned short *pPamdLevl) +{ + unsigned short tmp_reg = 0; + unsigned short dBvalue, valid_cnt = 0; + int i, total = 0; + + for (i = 0; i < 8; i++) { + if (fm_reg_read(FM_ADDR_PAMD, &tmp_reg)) { + *pPamdLevl = 0; + return false; + } + + tmp_reg &= 0x03FF; + dBvalue = (tmp_reg > 256) ? ((512 - tmp_reg) * 6 / 16) : 0; + if (dBvalue != 0) { + total += dBvalue; + valid_cnt++; + WCN_DBG(FM_DBG | CHIP, "[%d]PAMD=%d\n", i, dBvalue); + } + fm_delayms(3); + } + if (valid_cnt != 0) + *pPamdLevl = total / valid_cnt; + else + *pPamdLevl = 0; + + WCN_DBG(FM_NTC | CHIP, "PAMD=%d\n", *pPamdLevl); + return true; +} + +static signed int mt6635_i2s_info_get(signed int *ponoff, signed int *pmode, signed int *psample) +{ + if (ponoff == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (pmode == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (psample == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + *ponoff = fm_config.aud_cfg.i2s_info.status; + *pmode = fm_config.aud_cfg.i2s_info.mode; + *psample = fm_config.aud_cfg.i2s_info.rate; + + return 0; +} + +static signed int mt6635_get_audio_info(struct fm_audio_info_t *data) +{ + memcpy(data, &fm_config.aud_cfg, sizeof(struct fm_audio_info_t)); + return 0; +} + +static signed int mt6635_hw_info_get(struct fm_hw_info *req) +{ + if (req == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + req->chip_id = mt6635_hw_info.chip_id; + req->eco_ver = mt6635_hw_info.eco_ver; + req->patch_ver = mt6635_hw_info.patch_ver; + req->rom_ver = mt6635_hw_info.rom_ver; + + return 0; +} + +static signed int mt6635_pre_search(void) +{ + mt6635_RampDown(); + /* disable audio output I2S Rx mode */ + fm_host_reg_write(0x80101054, 0x00000000); + /* disable audio output I2S Tx mode */ + fm_reg_write(0x9B, 0x0000); + + return 0; +} + +static signed int mt6635_restore_search(void) +{ + mt6635_RampDown(); + /* set audio output I2S Tx mode */ + fm_reg_write(0x9B, 0xF9AB); + /* set audio output I2S Rx mode */ + fm_host_reg_write(0x80101054, 0x00003f35); + return 0; +} + +static signed int mt6635_soft_mute_tune(unsigned short freq, signed int *rssi, signed int *valid) +{ + signed int ret = 0; + unsigned short pkt_size; + struct mt6635_full_cqi *p_cqi; + signed int RSSI = 0, PAMD = 0, MR = 0, ATDC = 0; + unsigned int PRX = 0, ATDEV = 0; + unsigned short softmuteGainLvl = 0; + + /* Set rgf_host2dsp_reserve[2] = 1 */ + WCN_DBG(FM_NTC | CHIP, "start %s\n", __func__); + + ret = mt6635_chan_para_get(freq); + if (ret == 2) + ret = fm_set_bits(FM_CHANNEL_SET, 0x2000, 0x0FFF); /* mdf HiLo */ + else + ret = fm_set_bits(FM_CHANNEL_SET, 0x0000, 0x0FFF); /* clear FA/HL/ATJ */ + + if (!mt6635_do_SPI_hopping_64M(freq)) + WCN_DBG(FM_ERR | CHIP, "%s: spi hopping fail!\n", __func__); + + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = fm_full_cqi_req(cmd_buf, TX_BUF_SIZE, &freq, 1, 1); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_SM_TUNE, SW_RETRY_CNT, SM_TUNE_TIMEOUT, fm_get_read_result); + FM_UNLOCK(cmd_buf_lock); + + if (!ret && fm_res) { + p_cqi = (struct mt6635_full_cqi *)&fm_res->cqi[2]; + /* just for debug */ + WCN_DBG(FM_NTC | CHIP, + "freq %d, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x\n", + p_cqi->ch, p_cqi->rssi, p_cqi->pamd, p_cqi->pr, p_cqi->fpamd, p_cqi->mr, + p_cqi->atdc, p_cqi->prx, p_cqi->atdev, p_cqi->smg, p_cqi->drssi); + RSSI = ((p_cqi->rssi & 0x03FF) >= 512) ? ((p_cqi->rssi & 0x03FF) - 1024) : (p_cqi->rssi & 0x03FF); + PAMD = ((p_cqi->pamd & 0x1FF) >= 256) ? ((p_cqi->pamd & 0x01FF) - 512) : (p_cqi->pamd & 0x01FF); + MR = ((p_cqi->mr & 0x01FF) >= 256) ? ((p_cqi->mr & 0x01FF) - 512) : (p_cqi->mr & 0x01FF); + ATDC = (p_cqi->atdc >= 32768) ? (65536 - p_cqi->atdc) : (p_cqi->atdc); + if (ATDC < 0) + ATDC = (~(ATDC)) - 1; /* Get abs value of ATDC */ + + PRX = (p_cqi->prx & 0x00FF); + ATDEV = p_cqi->atdev; + softmuteGainLvl = p_cqi->smg; + /* check if the channel is valid according to each CQIs */ + if ((fm_config.rx_cfg.long_ana_rssi_th <= RSSI) + && (fm_config.rx_cfg.pamd_th >= PAMD) + && (fm_config.rx_cfg.atdc_th >= ATDC) + && (fm_config.rx_cfg.mr_th <= MR) + && (fm_config.rx_cfg.prx_th <= PRX) + && (ATDEV >= ATDC) /* sync scan algorithm */ + && (fm_config.rx_cfg.smg_th <= softmuteGainLvl)) { + *valid = true; + } else { + *valid = false; + } + *rssi = RSSI; + } else { + WCN_DBG(FM_ALT | CHIP, "smt get CQI failed\n"); + return false; + } + WCN_DBG(FM_NTC | CHIP, "valid=%d\n", *valid); + return true; +} + +static bool mt6635_em_test(unsigned short group_idx, unsigned short item_idx, unsigned int item_value) +{ + return true; +} + +/* +*parm: +* parm.th_type: 0, RSSI. 1, desense RSSI. 2, SMG. +* parm.th_val: threshold value +*/ +static signed int mt6635_set_search_th(signed int idx, signed int val, signed int reserve) +{ + switch (idx) { + case 0: { + fm_config.rx_cfg.long_ana_rssi_th = val; + WCN_DBG(FM_NTC | CHIP, "set rssi th =%d\n", val); + break; + } + case 1: { + fm_config.rx_cfg.desene_rssi_th = val; + WCN_DBG(FM_NTC | CHIP, "set desense rssi th =%d\n", val); + break; + } + case 2: { + fm_config.rx_cfg.smg_th = val; + WCN_DBG(FM_NTC | CHIP, "set smg th =%d\n", val); + break; + } + default: + break; + } + return 0; +} + +static signed int MT6635_low_power_wa_default(signed int fmon) +{ + return 0; +} + +signed int mt6635_fm_low_ops_register(struct fm_callback *cb, struct fm_basic_interface *bi) +{ + signed int ret = 0; + /* Basic functions. */ + + if (bi == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,bi invalid pointer\n", __func__); + return -FM_EPARA; + } + if (cb->cur_freq_get == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,cb->cur_freq_get invalid pointer\n", __func__); + return -FM_EPARA; + } + if (cb->cur_freq_set == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,cb->cur_freq_set invalid pointer\n", __func__); + return -FM_EPARA; + } + fm_cb_op = cb; + + bi->pwron = mt6635_pwron; + bi->pwroff = mt6635_pwroff; + bi->chipid_get = mt6635_get_chipid; + bi->mute = mt6635_Mute; + bi->rampdown = mt6635_RampDown; + bi->pwrupseq = mt6635_PowerUp; + bi->pwrdownseq = mt6635_PowerDown; + bi->setfreq = mt6635_SetFreq; + bi->low_pwr_wa = MT6635_low_power_wa_default; + bi->get_aud_info = mt6635_get_audio_info; + bi->rssiget = mt6635_GetCurRSSI; + bi->volset = mt6635_SetVol; + bi->volget = mt6635_GetVol; + bi->dumpreg = mt6635_dump_reg; + bi->msget = mt6635_GetMonoStereo; + bi->msset = mt6635_SetMonoStereo; + bi->pamdget = mt6635_GetCurPamd; + bi->em = mt6635_em_test; + bi->anaswitch = mt6635_SetAntennaType; + bi->anaget = mt6635_GetAntennaType; + bi->caparray_get = mt6635_GetCapArray; + bi->hwinfo_get = mt6635_hw_info_get; + bi->i2s_get = mt6635_i2s_info_get; + bi->is_dese_chan = mt6635_is_dese_chan; + bi->softmute_tune = mt6635_soft_mute_tune; + bi->desense_check = mt6635_desense_check; + bi->cqi_log = mt6635_full_cqi_get; + bi->pre_search = mt6635_pre_search; + bi->restore_search = mt6635_restore_search; + bi->set_search_th = mt6635_set_search_th; + bi->is_valid_freq = mt6635_is_valid_freq; + + cmd_buf_lock = fm_lock_create("31_cmd"); + ret = fm_lock_get(cmd_buf_lock); + + cmd_buf = fm_zalloc(TX_BUF_SIZE + 1); + + if (!cmd_buf) { + WCN_DBG(FM_ALT | CHIP, "6635 fm lib alloc tx buf failed\n"); + ret = -1; + } +#if 0 /* def CONFIG_MTK_FM_50KHZ_SUPPORT */ + cqi_fifo = fm_fifo_create("6628_cqi_fifo", sizeof(struct adapt_fm_cqi), 640); + if (!cqi_fifo) { + WCN_DBG(FM_ALT | CHIP, "6635 fm lib create cqi fifo failed\n"); + ret = -1; + } +#endif + + return ret; +} + +signed int mt6635_fm_low_ops_unregister(struct fm_basic_interface *bi) +{ + signed int ret = 0; + /* Basic functions. */ + if (bi == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,bi invalid pointer\n", __func__); + return -FM_EPARA; + } + +#if 0 /* def CONFIG_MTK_FM_50KHZ_SUPPORT */ + fm_fifo_release(cqi_fifo); +#endif + + if (cmd_buf) { + fm_free(cmd_buf); + cmd_buf = NULL; + } + + ret = fm_lock_put(cmd_buf_lock); + fm_memset(bi, 0, sizeof(struct fm_basic_interface)); + + fm_cb_op = NULL; + + return ret; +} + +static const signed char mt6635_chan_para_map[] = { +/* 0, X, 1, X, 2, X, 3, X, 4, X, 5, X, 6, X, 7, X, 8, X, 9, X */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, /* 6500~6595 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6600~6695 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, /* 6700~6795 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6800~6895 */ + 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6900~6995 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7000~7095 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7100~7195 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, /* 7200~7295 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7300~7395 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, /* 7400~7495 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7500~7595 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, /* 7600~7695 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7700~7795 */ + 8, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7800~7895 */ + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7900~7995 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8000~8095 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8100~8195 */ + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8200~8295 */ + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, /* 8300~8395 */ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8400~8495 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8500~8595 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8600~8695 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8700~8795 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8800~8895 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8900~8995 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9000~9095 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9100~9195 */ + 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9200~9295 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9300~9395 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9400~9495 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9500~9595 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9600~9695 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9700~9795 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, /* 9800~9895 */ + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, /* 9900~9995 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10000~10095 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10100~10195 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10200~10295 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10300~10395 */ + 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10400~10495 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, /* 10500~10595 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10600~10695 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, /* 10700~10795 */ + 0 /* 10800 */ +}; + +static const unsigned short mt6635_scan_dese_list[] = { + 6910, 6920, 7680, 7800, 8450, 9210, 9220, 9230, 9590, 9600, 9830, 9900, 9980, 9990, 10400, 10750, 10760 +}; + +static const unsigned short mt6635_SPI_hopping_list[] = { + 6510, 6520, 6530, 7780, 7790, 7800, 7810, 7820, 9090, 9100, 9110, 9120, 10380, 10390, 10400, 10410, 10420 +}; + +static const unsigned short mt6635_I2S_hopping_list[] = { + 6550, 6760, 6960, 6970, 7170, 7370, 7580, 7780, 7990, 8810, 9210, 9220, 10240 +}; + +static const unsigned short mt6635_TDD_list[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 6500~6595 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 6600~6695 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 6700~6795 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 6800~6895 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 6900~6995 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7000~7095 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7100~7195 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7200~7295 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7300~7395 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7400~7495 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7500~7595 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7600~7695 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7700~7795 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7800~7895 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7900~7995 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8000~8095 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8100~8195 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8200~8295 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8300~8395 */ + 0x0101, 0x0000, 0x0000, 0x0000, 0x0000, /* 8400~8495 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8500~8595 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8600~8695 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8700~8795 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8800~8895 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8900~8995 */ + 0x0000, 0x0000, 0x0101, 0x0101, 0x0101, /* 9000~9095 */ + 0x0101, 0x0000, 0x0000, 0x0000, 0x0000, /* 9100~9195 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9200~9295 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9300~9395 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9400~9495 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9500~9595 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9600~9695 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0100, /* 9700~9795 */ + 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, /* 9800~9895 */ + 0x0101, 0x0101, 0x0001, 0x0000, 0x0000, /* 9900~9995 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10000~10095 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10100~10195 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10200~10295 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10300~10395 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10400~10495 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10500~10595 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0100, /* 10600~10695 */ + 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, /* 10700~10795 */ + 0x0001 /* 10800 */ +}; + +static const unsigned short mt6635_TDD_Mask[] = { + 0x0001, 0x0010, 0x0100, 0x1000 +}; + +/* return value: 0, not a de-sense channel; 1, this is a de-sense channel; else error no */ +static signed int mt6635_is_dese_chan(unsigned short freq) +{ + signed int size; + + if (1 == HQA_ZERO_DESENSE_MAP) /*HQA only :skip desense channel check. */ + return 0; + + size = ARRAY_SIZE(mt6635_scan_dese_list); + + if (fm_get_channel_space(freq) == 0) + freq *= 10; + + while (size) { + if (mt6635_scan_dese_list[size - 1] == freq) + return 1; + + size--; + } + + return 0; +} + +/* return value: +*1, is desense channel and rssi is less than threshold; +*0, not desense channel or it is but rssi is more than threshold. +*/ +static signed int mt6635_desense_check(unsigned short freq, signed int rssi) +{ + if (mt6635_is_dese_chan(freq)) { + if (rssi < fm_config.rx_cfg.desene_rssi_th) + return 1; + + WCN_DBG(FM_DBG | CHIP, "desen_rssi %d th:%d\n", rssi, fm_config.rx_cfg.desene_rssi_th); + } + return 0; +} + +static bool mt6635_TDD_chan_check(unsigned short freq) +{ + unsigned int i = 0; + unsigned short freq_tmp = freq; + signed int ret = 0; + + ret = fm_get_channel_space(freq_tmp); + if (ret == 0) + freq_tmp *= 10; + else if (ret == -1) + return false; + + i = (freq_tmp - 6500) / 5; + if ((i / 4) >= ARRAY_SIZE(mt6635_TDD_list)) { + WCN_DBG(FM_ERR | CHIP, "Freq index out of range(%d),max(%zd)\n", + i / 4, ARRAY_SIZE(mt6635_TDD_list)); + return false; + } + + if (mt6635_TDD_list[i / 4] & mt6635_TDD_Mask[i % 4]) { + WCN_DBG(FM_DBG | CHIP, "Freq %d use TDD solution\n", freq); + return true; + } else + return false; +} + +/* get channel parameter, HL side/ FA / ATJ */ +static unsigned short mt6635_chan_para_get(unsigned short freq) +{ + signed int pos, size; + + if (1 == HQA_RETURN_ZERO_MAP) { + WCN_DBG(FM_NTC | CHIP, "HQA_RETURN_ZERO_CHAN mt6635_chan_para_map enabled!\n"); + return 0; + } + + if (fm_get_channel_space(freq) == 0) + freq *= 10; + + if (freq < 6500) + return 0; + + pos = (freq - 6500) / 5; + + size = ARRAY_SIZE(mt6635_chan_para_map); + + pos = (pos > (size - 1)) ? (size - 1) : pos; + + return mt6635_chan_para_map[pos]; +} + + +static bool mt6635_SPI_hopping_check(unsigned short freq) +{ + signed int size; + + size = ARRAY_SIZE(mt6635_SPI_hopping_list); + + if (fm_get_channel_space(freq) == 0) + freq *= 10; + + while (size) { + if (mt6635_SPI_hopping_list[size - 1] == freq) + return 1; + size--; + } + + return 0; +} diff --git a/drivers/misc/mediatek/connectivity/fmradio/chips/mt6635/pub/mt6635_fm_rds.c b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6635/pub/mt6635_fm_rds.c new file mode 100644 index 0000000000000000000000000000000000000000..5098adacb32466c0b68ce056a26a2b24845360ca --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/chips/mt6635/pub/mt6635_fm_rds.c @@ -0,0 +1,335 @@ +/* +* Copyright (C) 2016 MediaTek Inc. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. +*/ +#include "fm_typedef.h" +#include "fm_dbg.h" +#include "fm_err.h" +#include "fm_interface.h" +#include "fm_stdlib.h" +#include "fm_rds.h" +#include "mt6635_fm_reg.h" +#include "fm_cmd.h" + +static bool bRDS_FirstIn; /* false */ +static unsigned int gBLER_CHK_INTERVAL = 500; +static unsigned short GOOD_BLK_CNT = 0, BAD_BLK_CNT; +static unsigned char BAD_BLK_RATIO; + +static struct fm_basic_interface *fm_bi; + +static bool mt6635_RDS_support(void); +static signed int mt6635_RDS_enable(void); +static signed int mt6635_RDS_disable(void); +static unsigned short mt6635_RDS_Get_GoodBlock_Counter(void); +static unsigned short mt6635_RDS_Get_BadBlock_Counter(void); +static unsigned char mt6635_RDS_Get_BadBlock_Ratio(void); +static unsigned int mt6635_RDS_Get_BlerCheck_Interval(void); +/* static void mt6635_RDS_GetData(unsigned short *data, unsigned short datalen); */ +static void mt6635_RDS_Init_Data(struct rds_t *pstRDSData); + +static bool mt6635_RDS_support(void) +{ + return true; +} + +static signed int mt6635_RDS_enable(void) +{ + signed int ret = 0; + unsigned short dataRead = 0; + + WCN_DBG(FM_DBG | RDSC, "rds enable\n"); + ret = fm_reg_read(FM_RDS_CFG0, &dataRead); + if (ret) { + WCN_DBG(FM_NTC | RDSC, "rds enable read 0x80 fail\n"); + return ret; + } + ret = fm_reg_write(FM_RDS_CFG0, 6); /* set buf_start_th */ + if (ret) { + WCN_DBG(FM_NTC | RDSC, "rds enable write 0x80 fail\n"); + return ret; + } + ret = fm_reg_read(FM_MAIN_CTRL, &dataRead); + if (ret) { + WCN_DBG(FM_NTC | RDSC, "rds enable read 0x63 fail\n"); + return ret; + } + ret = fm_reg_write(FM_MAIN_CTRL, dataRead | (RDS_MASK)); + if (ret) { + WCN_DBG(FM_NTC | RDSC, "rds enable write 0x63 fail\n"); + return ret; + } + + return ret; +} + +static signed int mt6635_RDS_disable(void) +{ + signed int ret = 0; + unsigned short dataRead = 0; + + WCN_DBG(FM_DBG | RDSC, "rds disable\n"); + ret = fm_reg_read(FM_MAIN_CTRL, &dataRead); + if (ret) { + WCN_DBG(FM_NTC | RDSC, "rds disable read 0x63 fail\n"); + return ret; + } + ret = fm_reg_write(FM_MAIN_CTRL, dataRead & (~RDS_MASK)); + if (ret) { + WCN_DBG(FM_NTC | RDSC, "rds disable write 0x63 fail\n"); + return ret; + } + + return ret; +} + +static unsigned short mt6635_RDS_Get_GoodBlock_Counter(void) +{ + unsigned short tmp_reg = 0; + + fm_reg_read(FM_RDS_GOODBK_CNT, &tmp_reg); + GOOD_BLK_CNT = tmp_reg; + WCN_DBG(FM_DBG | RDSC, "get good block cnt:%d\n", (signed int) tmp_reg); + + return tmp_reg; +} + +static unsigned short mt6635_RDS_Get_BadBlock_Counter(void) +{ + unsigned short tmp_reg = 0; + + fm_reg_read(FM_RDS_BADBK_CNT, &tmp_reg); + BAD_BLK_CNT = tmp_reg; + WCN_DBG(FM_DBG | RDSC, "get bad block cnt:%d\n", (signed int) tmp_reg); + + return tmp_reg; +} + +static unsigned char mt6635_RDS_Get_BadBlock_Ratio(void) +{ + unsigned short tmp_reg; + unsigned short gbc; + unsigned short bbc; + + gbc = mt6635_RDS_Get_GoodBlock_Counter(); + bbc = mt6635_RDS_Get_BadBlock_Counter(); + + if ((gbc + bbc) > 0) + tmp_reg = (unsigned char) (bbc * 100 / (gbc + bbc)); + else + tmp_reg = 0; + + BAD_BLK_RATIO = tmp_reg; + WCN_DBG(FM_DBG | RDSC, "get badblock ratio:%d\n", (signed int) tmp_reg); + + return tmp_reg; +} + +static signed int mt6635_RDS_BlockCounter_Reset(void) +{ + mt6635_RDS_disable(); + mt6635_RDS_enable(); + + return 0; +} + +static unsigned int mt6635_RDS_Get_BlerCheck_Interval(void) +{ + return gBLER_CHK_INTERVAL; +} + +static signed int mt6635_RDS_BlerCheck(struct rds_t *dst) +{ + return 0; +} + +#if 0 +static void RDS_Recovery_Handler(void) +{ + unsigned short tempData = 0; + + do { + fm_reg_read(FM_RDS_DATA_REG, &tempData); + fm_reg_read(FM_RDS_POINTER, &tempData); + } while (tempData & 0x3); +} +#endif + +#if 0 +static void mt6635_RDS_GetData(unsigned short *data, unsigned short datalen) +{ +#define RDS_GROUP_DIFF_OFS 0x007C +#define RDS_FIFO_DIFF 0x007F +#define RDS_CRC_BLK_ADJ 0x0020 +#define RDS_CRC_CORR_CNT 0x001E +#define RDS_CRC_INFO 0x0001 + + unsigned short CRC = 0, i = 0, RDS_adj = 0, RDSDataCount = 0, FM_WARorrCnt = 0; + unsigned short temp = 0, OutputPofm_s32 = 0; + + WCN_DBG(FM_DBG | RDSC, "get data\n"); + fm_reg_read(FM_RDS_FIFO_STATUS0, &temp); + RDSDataCount = ((RDS_GROUP_DIFF_OFS & temp) << 2); + + if ((temp & RDS_FIFO_DIFF) >= 4) { + /* block A data and info handling */ + fm_reg_read(FM_RDS_INFO, &temp); + RDS_adj |= (temp & RDS_CRC_BLK_ADJ) << 10; + CRC |= (temp & RDS_CRC_INFO) << 3; + FM_WARorrCnt |= ((temp & RDS_CRC_CORR_CNT) << 11); + fm_reg_read(FM_RDS_DATA_REG, &data[0]); + + /* block B data and info handling */ + fm_reg_read(FM_RDS_INFO, &temp); + RDS_adj |= (temp & RDS_CRC_BLK_ADJ) << 9; + CRC |= (temp & RDS_CRC_INFO) << 2; + FM_WARorrCnt |= ((temp & RDS_CRC_CORR_CNT) << 7); + fm_reg_read(FM_RDS_DATA_REG, &data[1]); + + /* block C data and info handling */ + fm_reg_read(FM_RDS_INFO, &temp); + RDS_adj |= (temp & RDS_CRC_BLK_ADJ) << 8; + CRC |= (temp & RDS_CRC_INFO) << 1; + FM_WARorrCnt |= ((temp & RDS_CRC_CORR_CNT) << 3); + fm_reg_read(FM_RDS_DATA_REG, &data[2]); + + /* block D data and info handling */ + fm_reg_read(FM_RDS_INFO, &temp); + RDS_adj |= (temp & RDS_CRC_BLK_ADJ) << 7; + CRC |= (temp & RDS_CRC_INFO); + FM_WARorrCnt |= ((temp & RDS_CRC_CORR_CNT) >> 1); + fm_reg_read(FM_RDS_DATA_REG, &data[3]); + + data[4] = (CRC | RDS_adj | RDSDataCount); + data[5] = FM_WARorrCnt; + + fm_reg_read(FM_RDS_PWDI, &data[6]); + fm_reg_read(FM_RDS_PWDQ, &data[7]); + + fm_reg_read(FM_RDS_POINTER, &OutputPofm_s32); + + /* Go fm_s32o RDS recovery handler while RDS output pofm_s32 doesn't align to 4 in numeric */ + if (OutputPofm_s32 & 0x3) + RDS_Recovery_Handler(); + + } else { + for (; i < 8; i++) + data[i] = 0; + } +} +#endif + +static void mt6635_RDS_Init_Data(struct rds_t *pstRDSData) +{ + fm_memset(pstRDSData, 0, sizeof(struct rds_t)); + bRDS_FirstIn = true; + + pstRDSData->event_status = 0x0000; + fm_memset(pstRDSData->RT_Data.TextData, 0x20, sizeof(pstRDSData->RT_Data.TextData)); + fm_memset(pstRDSData->PS_Data.PS, '\0', sizeof(pstRDSData->PS_Data.PS)); + fm_memset(pstRDSData->PS_ON, 0x20, sizeof(pstRDSData->PS_ON)); +} + +bool mt6635_RDS_OnOff(struct rds_t *dst, bool bFlag) +{ + signed int ret = 0; + + if (mt6635_RDS_support() == false) { + WCN_DBG(FM_ALT | RDSC, "mt6635_RDS_OnOff failed, RDS not support\n"); + return false; + } + + if (bFlag) { + mt6635_RDS_Init_Data(dst); + ret = mt6635_RDS_enable(); + if (ret) { + WCN_DBG(FM_NTC | RDSC, "mt6635_RDS_OnOff enable failed\n"); + return false; + } + } else { + mt6635_RDS_Init_Data(dst); + ret = mt6635_RDS_disable(); + if (ret) { + WCN_DBG(FM_NTC | RDSC, "mt6635_RDS_OnOff disable failed\n"); + return false; + } + } + + return true; +} + +DEFINE_RDSLOG(mt6635_rds_log); + +/* mt6635_RDS_Efm_s32_Handler - response FM RDS interrupt + * @fm - main data structure of FM driver + * This function first get RDS raw data, then call RDS spec parser + */ +static signed int mt6635_rds_parser(struct rds_t *rds_dst, struct rds_rx_t *rds_raw, + signed int rds_size, unsigned short(*getfreq) (void)) +{ + mt6635_rds_log.log_in(&mt6635_rds_log, rds_raw, rds_size); + return rds_parser(rds_dst, rds_raw, rds_size, getfreq); +} + +static signed int mt6635_rds_log_get(struct rds_rx_t *dst, signed int *dst_len) +{ + return mt6635_rds_log.log_out(&mt6635_rds_log, dst, dst_len); +} + +static signed int mt6635_rds_gc_get(struct rds_group_cnt_t *dst, struct rds_t *rdsp) +{ + return rds_grp_counter_get(dst, &rdsp->gc); +} + +static signed int mt6635_rds_gc_reset(struct rds_t *rdsp) +{ + return rds_grp_counter_reset(&rdsp->gc); +} + +signed int mt6635_fm_rds_ops_register(struct fm_basic_interface *bi, struct fm_rds_interface *ri) +{ + signed int ret = 0; + + if (ri == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,ri invalid pointer\n", __func__); + return -FM_EPARA; + } + + fm_bi = bi; + + ri->rds_blercheck = mt6635_RDS_BlerCheck; + ri->rds_onoff = mt6635_RDS_OnOff; + ri->rds_parser = mt6635_rds_parser; + ri->rds_gbc_get = mt6635_RDS_Get_GoodBlock_Counter; + ri->rds_bbc_get = mt6635_RDS_Get_BadBlock_Counter; + ri->rds_bbr_get = mt6635_RDS_Get_BadBlock_Ratio; + ri->rds_bc_reset = mt6635_RDS_BlockCounter_Reset; + ri->rds_bci_get = mt6635_RDS_Get_BlerCheck_Interval; + ri->rds_log_get = mt6635_rds_log_get; + ri->rds_gc_get = mt6635_rds_gc_get; + ri->rds_gc_reset = mt6635_rds_gc_reset; + + return ret; +} + +signed int mt6635_fm_rds_ops_unregister(struct fm_rds_interface *ri) +{ + signed int ret = 0; + + if (ri == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,ri invalid pointer\n", __func__); + return -FM_EPARA; + } + + fm_bi = NULL; + fm_memset(ri, 0, sizeof(struct fm_rds_interface)); + return ret; +} diff --git a/drivers/misc/mediatek/connectivity/fmradio/chips/soc/inc/soc_drv_dsp.h b/drivers/misc/mediatek/connectivity/fmradio/chips/soc/inc/soc_drv_dsp.h new file mode 100644 index 0000000000000000000000000000000000000000..957a869719bc3b704380f6891ca4bb6b4c1fa400 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/chips/soc/inc/soc_drv_dsp.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2015 MediaTek Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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. + */ + + +const unsigned char channel_parameter[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0 +}; diff --git a/drivers/misc/mediatek/connectivity/fmradio/chips/soc/inc/soc_fm_lib.h b/drivers/misc/mediatek/connectivity/fmradio/chips/soc/inc/soc_fm_lib.h new file mode 100644 index 0000000000000000000000000000000000000000..7e2f049f7010ba91280f1613cf823b5248e92f40 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/chips/soc/inc/soc_fm_lib.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2015 MediaTek Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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. + */ + +#ifndef __MT6580_FM_LIB_H__ +#define __MT6580_FM_LIB_H__ + +#include "fm_typedef.h" + +enum { + DSPPATCH = 0xFFF9, + USDELAY = 0xFFFA, + MSDELAY = 0xFFFB, + HW_VER = 0xFFFD, + POLL_N = 0xFFFE, /* poling check if bit(n) is '0' */ + POLL_P = 0xFFFF, /* polling check if bit(n) is '1' */ +}; + +enum { + FM_PUS_DSPPATCH = DSPPATCH, + FM_PUS_USDELAY = USDELAY, + FM_PUS_MSDELAY = MSDELAY, + FM_PUS_HW_VER = HW_VER, + FM_PUS_POLL_N = POLL_N, /* poling check if bit(n) is '0' */ + FM_PUS_POLL_P = POLL_P, /* polling check if bit(n) is '1' */ + FM_PUS_MAX +}; + +enum { + mt6580_E1 = 0, + mt6580_E2 +}; + +struct mt6580_fm_cqi { + unsigned short ch; + unsigned short rssi; + unsigned short reserve; +}; + +struct adapt_fm_cqi { + signed int ch; + signed int rssi; + signed int reserve; +}; + +struct mt6580_full_cqi { + unsigned short ch; + unsigned short rssi; + unsigned short pamd; + unsigned short pr; + unsigned short fpamd; + unsigned short mr; + unsigned short atdc; + unsigned short prx; + unsigned short atdev; + unsigned short smg; /* soft-mute gain */ + unsigned short drssi; /* delta rssi */ +}; + +#endif diff --git a/drivers/misc/mediatek/connectivity/fmradio/chips/soc/inc/soc_fm_reg.h b/drivers/misc/mediatek/connectivity/fmradio/chips/soc/inc/soc_fm_reg.h new file mode 100644 index 0000000000000000000000000000000000000000..5a52de14649787386b747e57ee9e2ccbd20a45b8 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/chips/soc/inc/soc_fm_reg.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2015 MediaTek Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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. + */ + +#ifndef __MT6580_FM_REG_H__ +#define __MT6580_FM_REG_H__ + +enum MT6580_HOSTREG { + MCUPLL_CON1 = 0x80000224, + CONN_RF_CG = 0x80102090 +}; + +/* RDS_BDGRP_ABD_CTRL_REG */ +enum { + BDGRP_ABD_EN = 0x0001, + BER_RUN = 0x2000 +}; +#define FM_DAC_CON1 0x83 +#define FM_DAC_CON2 0x84 +#define FM_FT_CON0 0x86 +enum { + FT_EN = 0x0001 +}; + +#define FM_I2S_CON0 0x90 +enum { + I2S_EN = 0x0001, + FORMAT = 0x0002, + WLEN = 0x0004, + I2S_SRC = 0x0008 +}; + +/* FM_MAIN_CTRL */ +enum { + TUNE = 0x0001, + SEEK = 0x0002, + SCAN = 0x0004, + CQI_READ = 0x0008, + RDS_MASK = 0x0010, + MUTE = 0x0020, + RDS_BRST = 0x0040, + RAMP_DOWN = 0x0100, +}; + +enum { + ANTENNA_TYPE = 0x0010, /* 0x61 D4, 0:long, 1:short */ + ANALOG_I2S = 0x0080, /* 0x61 D7, 0:lineout, 1:I2S */ + DE_EMPHASIS = 0x1000, /* 0x61 D12,0:50us, 1:75 us */ +}; + +#define OSC_FREQ_BITS 0x0070 /* 0x60 bit4~6 */ +#define OSC_FREQ_MASK (~OSC_FREQ_BITS) + +#endif /* __MT6580_FM_REG_H__ */ diff --git a/drivers/misc/mediatek/connectivity/fmradio/chips/soc/pub/soc_fm_lib.c b/drivers/misc/mediatek/connectivity/fmradio/chips/soc/pub/soc_fm_lib.c new file mode 100644 index 0000000000000000000000000000000000000000..c33263efbae6b0ad39b299924308bc947b6fd033 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/chips/soc/pub/soc_fm_lib.c @@ -0,0 +1,1841 @@ +/* + * Copyright (C) 2015 MediaTek Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 +#include + +#include "osal_typedef.h" +#include "stp_exp.h" +#include "wmt_exp.h" + +#include "fm_typedef.h" +#include "fm_dbg.h" +#include "fm_err.h" +#include "fm_interface.h" +#include "fm_stdlib.h" +#include "fm_patch.h" +#include "fm_utils.h" +#include "fm_link.h" +#include "fm_config.h" +#include "fm_cmd.h" + +#include "soc_fm_reg.h" +#include "soc_fm_lib.h" + +/* #include "mach/mt_gpio.h" */ + +static struct fm_patch_tbl mt6580_patch_tbl[5] = { + {FM_ROM_V1, "soc_fm_v1_patch.bin", "soc_fm_v1_coeff.bin", NULL, NULL}, + {FM_ROM_V2, "soc_fm_v2_patch.bin", "soc_fm_v2_coeff.bin", NULL, NULL}, + {FM_ROM_V3, "soc_fm_v3_patch.bin", "soc_fm_v3_coeff.bin", NULL, NULL}, + {FM_ROM_V4, "soc_fm_v4_patch.bin", "soc_fm_v4_coeff.bin", NULL, NULL}, + {FM_ROM_V5, "soc_fm_v5_patch.bin", "soc_fm_v5_coeff.bin", NULL, NULL} +}; + +static struct fm_hw_info mt6580_hw_info = { + .chip_id = 0x00006580, + .eco_ver = 0x00000000, + .rom_ver = 0x00000000, + .patch_ver = 0x00000000, + .reserve = 0x00000000, +}; + +static struct fm_callback *fm_cb_op; +/* static signed int Chip_Version = mt6580_E1; */ + +/* static bool rssi_th_set = false; */ + +#if 0 /* def CONFIG_MTK_FM_50KHZ_SUPPORT */ +static struct fm_fifo *cqi_fifo; +#endif +static signed int mt6580_is_dese_chan(unsigned short freq); + +#if 0 +static signed int mt6580_mcu_dese(unsigned short freq, void *arg); +static signed int mt6580_gps_dese(unsigned short freq, void *arg); +static signed int mt6580_I2s_Setting(signed int onoff, signed int mode, signed int sample); +#endif +static unsigned short mt6580_chan_para_get(unsigned short freq); +static signed int mt6580_desense_check(unsigned short freq, signed int rssi); +/*static bool mt6580_TDD_chan_check(unsigned short freq);*/ +static signed int mt6580_soft_mute_tune(unsigned short freq, signed int *rssi, signed int *valid); +static signed int mt6580_pwron(signed int data) +{ + if (mtk_wcn_wmt_func_on(WMTDRV_TYPE_FM) == MTK_WCN_BOOL_FALSE) { + WCN_DBG(FM_ERR | CHIP, "WMT turn on FM Fail!\n"); + return -FM_ELINK; + } + + WCN_DBG(FM_NTC | CHIP, "WMT turn on FM OK!\n"); + return 0; +} + +static signed int mt6580_pwroff(signed int data) +{ + if (mtk_wcn_wmt_func_off(WMTDRV_TYPE_FM) == MTK_WCN_BOOL_FALSE) { + WCN_DBG(FM_ERR | CHIP, "WMT turn off FM Fail!\n"); + return -FM_ELINK; + } + + WCN_DBG(FM_NTC | CHIP, "WMT turn off FM OK!\n"); + return 0; +} + +#if 0 +static signed int mt6580_top_set_bits(unsigned short addr, unsigned int bits, unsigned int mask) +{ + signed int ret = 0; + unsigned int val; + + ret = fm_top_reg_read(addr, &val); + + if (ret) + return ret; + + val = ((val & (mask)) | bits); + ret = fm_top_reg_write(addr, val); + + return ret; +} +#endif + +#if 0 +static signed int mt6580_DSP_write(unsigned short addr, unsigned short val) +{ + fm_reg_write(0xE2, addr); + fm_reg_write(0xE3, val); + fm_reg_write(0xE1, 0x0002); + return 0; +} +static signed int mt6580_DSP_read(unsigned short addr, unsigned short *val) +{ + signed int ret = -1; + + fm_reg_write(0xE2, addr); + fm_reg_write(0xE1, 0x0001); + ret = fm_reg_read(0xE4, val); + return ret; +} +#endif + +static unsigned short mt6580_get_chipid(void) +{ + return 0x6580; +} + +/* MT6580_SetAntennaType - set Antenna type + * @type - 1,Short Antenna; 0, Long Antenna + */ +static signed int mt6580_SetAntennaType(signed int type) +{ + unsigned short dataRead = 0; + + WCN_DBG(FM_DBG | CHIP, "set ana to %s\n", type ? "short" : "long"); + fm_reg_read(FM_MAIN_CG2_CTRL, &dataRead); + + if (type) + dataRead |= ANTENNA_TYPE; + else + dataRead &= (~ANTENNA_TYPE); + + fm_reg_write(FM_MAIN_CG2_CTRL, dataRead); + + return 0; +} + +static signed int mt6580_GetAntennaType(void) +{ + unsigned short dataRead = 0; + + fm_reg_read(FM_MAIN_CG2_CTRL, &dataRead); + WCN_DBG(FM_DBG | CHIP, "get ana type: %s\n", (dataRead & ANTENNA_TYPE) ? "short" : "long"); + + if (dataRead & ANTENNA_TYPE) + return FM_ANA_SHORT; /* short antenna */ + else + return FM_ANA_LONG; /* long antenna */ +} + +static signed int mt6580_Mute(bool mute) +{ + signed int ret = 0; + unsigned short dataRead = 0; + + WCN_DBG(FM_DBG | CHIP, "set %s\n", mute ? "mute" : "unmute"); + /* fm_reg_read(FM_MAIN_CTRL, &dataRead); */ + fm_reg_read(0x9C, &dataRead); + + /* fm_top_reg_write(0x0050,0x00000007); */ + + if (mute == 1) + ret = fm_reg_write(0x9C, (dataRead & 0xFFFC) | 0x0003); + else + ret = fm_reg_write(0x9C, (dataRead & 0xFFFC)); + + /* fm_top_reg_write(0x0050,0x0000000F); */ + + return ret; +} + +#if 0 +static signed int mt6580_set_RSSITh(unsigned short TH_long, unsigned short TH_short) +{ + fm_reg_write(0xE2, 0x3072); + fm_reg_write(0xE3, TH_long); + fm_reg_write(0xE1, 0x0002); + fm_delayms(1); + fm_reg_write(0xE2, 0x307A); + fm_reg_write(0xE3, TH_short); + fm_reg_write(0xE1, 0x0002); + + WCN_DBG(FM_DBG | CHIP, "RSSI TH, long:0x%04x, short:0x%04x", TH_long, TH_short); + return 0; +} + +static signed int mt6580_set_SMGTh(signed int ver, unsigned short TH_smg) +{ + if (mt6580_E1 == ver) { + fm_reg_write(0xE2, 0x321E); + fm_reg_write(0xE3, TH_smg); + fm_reg_write(0xE1, 0x0002); + } else { + fm_reg_write(0xE2, 0x3218); + fm_reg_write(0xE3, TH_smg); + fm_reg_write(0xE1, 0x0002); + } + + WCN_DBG(FM_DBG | CHIP, "Soft-mute gain TH %d\n", (int)TH_smg); + return 0; +} +#endif + +static signed int mt6580_rampdown_reg_op(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 4; + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + /* Clear DSP state */ + pkt_size += fm_bop_modify(FM_MAIN_CTRL, 0xFFF0, 0x0000, &buf[pkt_size], buf_size - pkt_size); + /* Set DSP ramp down state */ + pkt_size += fm_bop_modify(FM_MAIN_CTRL, 0xFFFF, RAMP_DOWN, &buf[pkt_size], buf_size - pkt_size); + /* @Wait for STC_DONE interrupt@ */ + pkt_size += fm_bop_rd_until(FM_MAIN_INTR, FM_INTR_STC_DONE, FM_INTR_STC_DONE, &buf[pkt_size], + buf_size - pkt_size); + /* Clear DSP ramp down state */ + pkt_size += fm_bop_modify(FM_MAIN_CTRL, (~RAMP_DOWN), 0x0000, &buf[pkt_size], buf_size - pkt_size); + /* Write 1 clear the STC_DONE interrupt status flag */ + pkt_size += fm_bop_modify(FM_MAIN_INTR, 0xFFFF, FM_INTR_STC_DONE, &buf[pkt_size], buf_size - pkt_size); + + return pkt_size - 4; +} +/* + * mt6580_rampdown - f/w will wait for STC_DONE interrupt + * @buf - target buf + * @buf_size - buffer size + * return package size + */ +static signed int mt6580_rampdown(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 0; + + pkt_size = mt6580_rampdown_reg_op(buf, buf_size); + return fm_op_seq_combine_cmd(buf, FM_RAMPDOWN_OPCODE, pkt_size); +} + +static signed int mt6580_RampDown(void) +{ + signed int ret = 0; + unsigned short pkt_size; + + WCN_DBG(FM_DBG | CHIP, "ramp down\n"); + ret = fm_reg_write(0x60, 0x00000007); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "ramp down wr 0x60 failed\n"); + return ret; + } + ret = fm_reg_write(0x60, 0x0000000f); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "ramp down wr 0x60 failed\n"); + return ret; + } + + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = mt6580_rampdown(cmd_buf, TX_BUF_SIZE); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_RAMPDOWN, SW_RETRY_CNT, RAMPDOWN_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "ramp down failed\n"); + return ret; + } + + return ret; +} + +static signed int mt6580_get_rom_version(void) +{ + unsigned short tmp; + signed int ret; + + fm_reg_write(0x90, 0xe); + fm_reg_write(0x92, 0x0); + fm_reg_write(0x90, 0x40); + fm_reg_write(0x90, 0x0); + + /* DSP rom code version request enable --- set 0x61 b15=1 */ + fm_set_bits(0x61, 0x8000, 0x7FFF); + + /* Release ASIP reset --- set 0x61 b1=1 */ + fm_set_bits(0x61, 0x0002, 0xFFFD); + + /* Enable ASIP power --- set 0x61 b0=0 */ + fm_set_bits(0x61, 0x0000, 0xFFFE); + + /* Wait DSP code version ready --- wait 1ms */ + do { + fm_delayus(1000); + ret = fm_reg_read(0x84, &tmp); + /* ret=-4 means signal got when control FM. usually get sig 9 to kill FM process. */ + /* now cancel FM power up sequence is recommended. */ + if (ret) + return ret; + + WCN_DBG(FM_NTC | CHIP, "0x84=%x\n", tmp); + } while (tmp != 0x0001); + + /* Get FM DSP code version --- rd 0x83[15:8] */ + fm_reg_read(0x83, &tmp); + tmp = (tmp >> 8); + + /* DSP rom code version request disable --- set 0x61 b15=0 */ + fm_set_bits(0x61, 0x0000, 0x7FFF); + + /* Reset ASIP --- set 0x61[1:0] = 1 */ + fm_set_bits(0x61, 0x0001, 0xFFFC); + + /* WCN_DBG(FM_NTC | CHIP, "ROM version: v%d\n", (signed int)tmp); */ + return (signed int) tmp; +} + +static signed int mt6580_enable_pmic_tldo(void) +{ + signed int ret = 0; + unsigned int hostreg = 0; + + /* set 26M clock mannual on */ + ret = fm_host_reg_read(MCUPLL_CON1, &hostreg); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup rd MCUPLL_CON1 failed\n"); + return ret; + } + ret = fm_host_reg_write(MCUPLL_CON1, hostreg | (0x1 << 0)); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup wr MCUPLL_CON1 failed\n"); + return ret; + } + + ret = fm_host_reg_read(MCUPLL_CON1, &hostreg); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup rd MCUPLL_CON1 failed\n"); + return ret; + } + ret = fm_host_reg_write(MCUPLL_CON1, hostreg | (0x1 << 6)); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup wr MCUPLL_CON1 failed\n"); + return ret; + } + + ret = fm_host_reg_read(MCUPLL_CON1, &hostreg); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup rd MCUPLL_CON1 failed\n"); + return ret; + } + ret = fm_host_reg_write(MCUPLL_CON1, hostreg | (0x1 << 16)); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup wr MCUPLL_CON1 failed\n"); + return ret; + } + + ret = fm_host_reg_read(MCUPLL_CON1, &hostreg); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup rd MCUPLL_CON1 failed\n"); + return ret; + } + ret = fm_host_reg_write(MCUPLL_CON1, hostreg | (0x1 << 22)); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup wr MCUPLL_CON1 failed\n"); + return ret; + } + + /* set RX_DET_OUT Gating off */ + ret = fm_host_reg_read(CONN_RF_CG, &hostreg); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup rd CONN_RF_CG failed\n"); + return ret; + } + ret = fm_host_reg_write(CONN_RF_CG, hostreg | (0x1 << 16)); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup wr CONN_RF_CG failed\n"); + return ret; + } + + /* set ADC_QD Gating off */ + ret = fm_host_reg_read(CONN_RF_CG, &hostreg); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup rd CONN_RF_CG failed\n"); + return ret; + } + ret = fm_host_reg_write(CONN_RF_CG, hostreg | (0x1 << 15)); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup wr CONN_RF_CG failed\n"); + return ret; + } + + /* set ADC_ID Gating off */ + ret = fm_host_reg_read(CONN_RF_CG, &hostreg); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup rd CONN_RF_CG failed\n"); + return ret; + } + ret = fm_host_reg_write(CONN_RF_CG, hostreg | (0x1 << 14)); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup wr CONN_RF_CG failed\n"); + return ret; + } + + /* set ADC_CK Gating off */ + ret = fm_host_reg_read(CONN_RF_CG, &hostreg); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup rd CONN_RF_CG failed\n"); + return ret; + } + ret = fm_host_reg_write(CONN_RF_CG, hostreg | (0x1 << 7)); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup wr CONN_RF_CG failed\n"); + return ret; + } + + /* set DIG_CK Gating off */ + ret = fm_host_reg_read(CONN_RF_CG, &hostreg); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup rd CONN_RF_CG failed\n"); + return ret; + } + ret = fm_host_reg_write(CONN_RF_CG, hostreg | (0x1 << 6)); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup wr CONN_RF_CG failed\n"); + return ret; + } + + return ret; +} + +static signed int mt6580_disable_pmic_tldo(void) +{ + signed int ret = 0; + unsigned int hostreg = 0; + + /* set 26M clock mannual on */ + ret = fm_host_reg_read(MCUPLL_CON1, &hostreg); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup rd MCUPLL_CON1 failed\n"); + return ret; + } + ret = fm_host_reg_write(MCUPLL_CON1, hostreg & (~(0x1 << 22))); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup wr MCUPLL_CON1 failed\n"); + return ret; + } + + ret = fm_host_reg_read(MCUPLL_CON1, &hostreg); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup rd MCUPLL_CON1 failed\n"); + return ret; + } + ret = fm_host_reg_write(MCUPLL_CON1, hostreg & (~(0x1 << 16))); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup wr MCUPLL_CON1 failed\n"); + return ret; + } + + ret = fm_host_reg_read(MCUPLL_CON1, &hostreg); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup rd MCUPLL_CON1 failed\n"); + return ret; + } + ret = fm_host_reg_write(MCUPLL_CON1, hostreg & (~(0x1 << 6))); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup wr MCUPLL_CON1 failed\n"); + return ret; + } + + ret = fm_host_reg_read(MCUPLL_CON1, &hostreg); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup rd MCUPLL_CON1 failed\n"); + return ret; + } + ret = fm_host_reg_write(MCUPLL_CON1, hostreg & (~(0x1 << 0))); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup wr MCUPLL_CON1 failed\n"); + return ret; + } + + /* set RX_DET_OUT Gating off */ + ret = fm_host_reg_read(CONN_RF_CG, &hostreg); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup rd CONN_RF_CG failed\n"); + return ret; + } + ret = fm_host_reg_write(CONN_RF_CG, hostreg & (~(0x1 << 16))); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup wr CONN_RF_CG failed\n"); + return ret; + } + + /* set ADC_QD Gating off */ + ret = fm_host_reg_read(CONN_RF_CG, &hostreg); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup rd CONN_RF_CG failed\n"); + return ret; + } + ret = fm_host_reg_write(CONN_RF_CG, hostreg & (~(0x1 << 15))); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup wr CONN_RF_CG failed\n"); + return ret; + } + + /* set ADC_ID Gating off */ + ret = fm_host_reg_read(CONN_RF_CG, &hostreg); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup rd CONN_RF_CG failed\n"); + return ret; + } + ret = fm_host_reg_write(CONN_RF_CG, hostreg & (~(0x1 << 14))); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup wr CONN_RF_CG failed\n"); + return ret; + } + + /* set ADC_CK Gating off */ + ret = fm_host_reg_read(CONN_RF_CG, &hostreg); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup rd CONN_RF_CG failed\n"); + return ret; + } + ret = fm_host_reg_write(CONN_RF_CG, hostreg & (~(0x1 << 7))); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup wr CONN_RF_CG failed\n"); + return ret; + } + + /* set DIG_CK Gating off */ + ret = fm_host_reg_read(CONN_RF_CG, &hostreg); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup rd CONN_RF_CG failed\n"); + return ret; + } + ret = fm_host_reg_write(CONN_RF_CG, hostreg & (~(0x1 << 6))); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " pwrup wr CONN_RF_CG failed\n"); + return ret; + } + + return ret; +} + +static signed int mt6580_pwrup_clock_on_reg_op(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 4; + unsigned short de_emphasis; + /* unsigned short osc_freq; */ + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + de_emphasis = fm_config.rx_cfg.deemphasis; /* fm_cust_config_fetch(FM_CFG_RX_DEEMPHASIS); */ + de_emphasis &= 0x0001; /* rang 0~1 */ + + /* turn on top clock */ + pkt_size += fm_bop_top_write(0xA10, 0xFFFFFFFF, &buf[pkt_size], buf_size - pkt_size); /* wr a10 ffffffff */ + /* enable MTCMOS */ + pkt_size += fm_bop_top_write(0x60, 0x00000030, &buf[pkt_size], buf_size - pkt_size); /* wr 60 30 */ + pkt_size += fm_bop_top_write(0x60, 0x00000005, &buf[pkt_size], buf_size - pkt_size); /* wr 60 5 */ + pkt_size += fm_bop_udelay(10, &buf[pkt_size], buf_size - pkt_size); /* delay 10us */ + pkt_size += fm_bop_top_write(0x60, 0x00000045, &buf[pkt_size], buf_size - pkt_size); /* wr 60 45 */ + + /* enable digital OSC */ + pkt_size += fm_bop_write(0x60, 0x00000001, &buf[pkt_size], buf_size - pkt_size); /* wr 60 1 */ + /* set OSC clock output to fm */ + pkt_size += fm_bop_write(0x60, 0x00000003, &buf[pkt_size], buf_size - pkt_size); /* wr 60 3 */ + /* release HW clock gating */ + pkt_size += fm_bop_write(0x60, 0x00000007, &buf[pkt_size], buf_size - pkt_size); /* wr 60 7 */ + /* enable DSP auto clock gating */ + pkt_size += fm_bop_write(0x70, 0x0040, &buf[pkt_size], buf_size - pkt_size); /* wr 70 0040 */ + /* deemphasis setting */ + pkt_size += fm_bop_modify(0x61, ~DE_EMPHASIS, (de_emphasis << 12), &buf[pkt_size], buf_size - pkt_size); + + return pkt_size - 4; +} +/* + * mt6580_pwrup_clock_on - Wholechip FM Power Up: step 1, FM Digital Clock enable + * @buf - target buf + * @buf_size - buffer size + * return package size + */ +static signed int mt6580_pwrup_clock_on(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 0; + + pkt_size = mt6580_pwrup_clock_on_reg_op(buf, buf_size); + return fm_op_seq_combine_cmd(buf, FM_ENABLE_OPCODE, pkt_size); +} + +static signed int mt6580_pwrup_digital_init_reg_op(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 4; + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + /* FM Digital Init: fm_rgf_maincon */ + pkt_size += fm_bop_write(0x6A, 0x0021, &buf[pkt_size], buf_size - pkt_size); + /* wr 6A 0021, set 1 to enable interrupt */ + pkt_size += fm_bop_write(0x6B, 0x0021, &buf[pkt_size], buf_size - pkt_size); /* wr 6B 0021 */ + pkt_size += fm_bop_write(0x60, 0x0000000F, &buf[pkt_size], buf_size - pkt_size); /* wr 60 f */ + pkt_size += fm_bop_modify(0x61, 0xFFFD, 0x0002, &buf[pkt_size], buf_size - pkt_size); /* wr 61 D1=1 */ + pkt_size += fm_bop_modify(0x61, 0xFFFE, 0x0000, &buf[pkt_size], buf_size - pkt_size); /* wr 61 D0=0 */ + pkt_size += fm_bop_udelay(100000, &buf[pkt_size], buf_size - pkt_size); /* delay 100ms */ + pkt_size += fm_bop_rd_until(0x64, 0x001F, 0x0002, &buf[pkt_size], buf_size - pkt_size); /* Poll 64[0~4] = 2 */ + pkt_size += fm_bop_write(0x60, 0x00000007, &buf[pkt_size], buf_size - pkt_size); /* wr 60 7 */ + pkt_size += fm_bop_write(0x2d, 0x000001fa, &buf[pkt_size], buf_size - pkt_size); /* wr 2d 1fa */ + pkt_size += fm_bop_write(0x60, 0x0000000F, &buf[pkt_size], buf_size - pkt_size); /* wr 60 f */ + + return pkt_size - 4; +} + +/* + * mt6580_pwrup_digital_init - Wholechip FM Power Up: step 4, FM Digital Init: fm_rgf_maincon + * @buf - target buf + * @buf_size - buffer size + * return package size + */ +static signed int mt6580_pwrup_digital_init(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 0; + + pkt_size = mt6580_pwrup_digital_init_reg_op(buf, buf_size); + return fm_op_seq_combine_cmd(buf, FM_ENABLE_OPCODE, pkt_size); +} + +static signed int mt6580_pwrdown_reg_op(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 4; + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + /* A1:set audio output I2S Tx mode: */ + pkt_size += fm_bop_modify(0x9B, 0xFFF8, 0x0000, &buf[pkt_size], buf_size - pkt_size); /* wr 9B[0~2] 0 */ + + /* B0:Disable HW clock control */ + pkt_size += fm_bop_write(0x60, 0x330F, &buf[pkt_size], buf_size - pkt_size); /* wr 60 330F */ + /* B1:Reset ASIP */ + pkt_size += fm_bop_write(0x61, 0x0001, &buf[pkt_size], buf_size - pkt_size); /* wr 61 0001 */ + /* B2:digital core + digital rgf reset */ + pkt_size += fm_bop_modify(0x6E, 0xFFF8, 0x0000, &buf[pkt_size], buf_size - pkt_size); /* wr 6E[0~2] 0 */ + pkt_size += fm_bop_modify(0x6E, 0xFFF8, 0x0000, &buf[pkt_size], buf_size - pkt_size); /* wr 6E[0~2] 0 */ + pkt_size += fm_bop_modify(0x6E, 0xFFF8, 0x0000, &buf[pkt_size], buf_size - pkt_size); /* wr 6E[0~2] 0 */ + pkt_size += fm_bop_modify(0x6E, 0xFFF8, 0x0000, &buf[pkt_size], buf_size - pkt_size); /* wr 6E[0~2] 0 */ + /* B3:Disable all clock */ + pkt_size += fm_bop_write(0x60, 0x0000, &buf[pkt_size], buf_size - pkt_size); /* wr 60 0000 */ + /* B4:Reset rgfrf */ + pkt_size += fm_bop_write(0x60, 0x4000, &buf[pkt_size], buf_size - pkt_size); /* wr 60 4000 */ + pkt_size += fm_bop_write(0x60, 0x0000, &buf[pkt_size], buf_size - pkt_size); /* wr 60 0000 */ + /* MTCMOS power off */ + /* C0:disable MTCMOS */ + pkt_size += fm_bop_top_write(0x60, 0x0005, &buf[pkt_size], buf_size - pkt_size); /* wr top60 0005 */ + pkt_size += fm_bop_top_write(0x60, 0x0015, &buf[pkt_size], buf_size - pkt_size); /* wr top60 0015 */ + + return pkt_size - 4; +} +/* + * mt6580_pwrdown - Wholechip FM Power down: Digital Modem Power Down + * @buf - target buf + * @buf_size - buffer size + * return package size + */ +static signed int mt6580_pwrdown(unsigned char *buf, signed int buf_size) +{ + signed int pkt_size = 0; + + pkt_size = mt6580_pwrdown_reg_op(buf, buf_size); + return fm_op_seq_combine_cmd(buf, FM_ENABLE_OPCODE, pkt_size); +} + +static signed int mt6580_tune_reg_op(unsigned char *buf, signed int buf_size, unsigned short freq, + unsigned short chan_para) +{ + signed int pkt_size = 4; + + WCN_DBG(FM_ALT | CHIP, "%s enter mt6580_tune function\n", __func__); + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s invalid pointer\n", __func__); + return -1; + } + if (buf_size < TX_BUF_SIZE) { + WCN_DBG(FM_ERR | CHIP, "%s invalid buf size(%d)\n", __func__, buf_size); + return -2; + } + + /* Set desired channel & channel parameter */ +#ifdef FM_TUNE_USE_POLL + pkt_size += fm_bop_write(0x6A, 0x0000, &buf[pkt_size], buf_size - pkt_size); + pkt_size += fm_bop_write(0x6B, 0x0000, &buf[pkt_size], buf_size - pkt_size); +#endif + /* Enable hardware controlled tuning sequence */ + pkt_size += fm_bop_modify(FM_MAIN_CTRL, 0xFFF8, TUNE, &buf[pkt_size], buf_size - pkt_size); + /* Wait for STC_DONE interrupt */ +#ifdef FM_TUNE_USE_POLL + pkt_size += fm_bop_rd_until(FM_MAIN_INTR, FM_INTR_STC_DONE, FM_INTR_STC_DONE, &buf[pkt_size], + buf_size - pkt_size); + /* Write 1 clear the STC_DONE interrupt status flag */ + pkt_size += fm_bop_modify(FM_MAIN_INTR, 0xFFFF, FM_INTR_STC_DONE, &buf[pkt_size], buf_size - pkt_size); +#endif + + WCN_DBG(FM_ALT | CHIP, "%s leave mt6580_tune function\n", __func__); + + return pkt_size - 4; +} + +/* + * mt6580_tune - execute tune action, + * @buf - target buf + * @buf_size - buffer size + * @freq - 760 ~ 1080, 100KHz unit + * return package size + */ +static signed int mt6580_tune(unsigned char *buf, signed int buf_size, unsigned short freq, + unsigned short chan_para) +{ + signed int pkt_size = 0; + + pkt_size = mt6580_tune_reg_op(buf, buf_size, freq, chan_para); + return fm_op_seq_combine_cmd(buf, FM_TUNE_OPCODE, pkt_size); +} + +/* + * mt6580_pwrup_DSP_download - execute dsp/coeff patch dl action, + * @patch_tbl - current chip patch table + * return patch dl ok or not + */ +static signed int mt6580_pwrup_DSP_download(struct fm_patch_tbl *patch_tbl) +{ +#define PATCH_BUF_SIZE (4096*6) + signed int ret = 0; + signed int patch_len = 0; + unsigned char *dsp_buf = NULL; + unsigned short tmp_reg = 0; + + mt6580_hw_info.eco_ver = (signed int) mtk_wcn_wmt_hwver_get(); + WCN_DBG(FM_NTC | CHIP, "ECO version:0x%08x\n", mt6580_hw_info.eco_ver); + mt6580_hw_info.eco_ver += 1; + + /* get mt6580 DSP rom version */ + ret = mt6580_get_rom_version(); + if (ret >= 0) { + mt6580_hw_info.rom_ver = ret; + WCN_DBG(FM_NTC | CHIP, "ROM version: v%d\n", mt6580_hw_info.rom_ver); + } else { + WCN_DBG(FM_ERR | CHIP, "get ROM version failed\n"); + /* ret=-4 means signal got when control FM. usually get sig 9 to kill FM process. */ + /* now cancel FM power up sequence is recommended. */ + goto out; + } + + dsp_buf = fm_vmalloc(PATCH_BUF_SIZE); + if (!dsp_buf) { + WCN_DBG(FM_ALT | CHIP, "-ENOMEM\n"); + return -ENOMEM; + } + + patch_len = fm_get_patch_path(mt6580_hw_info.rom_ver, dsp_buf, PATCH_BUF_SIZE, patch_tbl); + if (patch_len <= 0) { + WCN_DBG(FM_ALT | CHIP, " fm_get_patch_path failed\n"); + ret = patch_len; + goto out; + } + + ret = fm_download_patch((const unsigned char *)dsp_buf, patch_len, IMG_PATCH); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " DL DSPpatch failed\n"); + goto out; + } + + patch_len = fm_get_coeff_path(mt6580_hw_info.rom_ver, dsp_buf, PATCH_BUF_SIZE, patch_tbl); + if (patch_len <= 0) { + WCN_DBG(FM_ALT | CHIP, " fm_get_coeff_path failed\n"); + ret = patch_len; + goto out; + } + + mt6580_hw_info.rom_ver += 1; + + tmp_reg = dsp_buf[38] | (dsp_buf[39] << 8); /* to be confirmed */ + mt6580_hw_info.patch_ver = (signed int) tmp_reg; + WCN_DBG(FM_NTC | CHIP, "Patch version: 0x%08x\n", mt6580_hw_info.patch_ver); + + if (ret == 1) { + dsp_buf[4] = 0x00; /* if we found rom version undefined, we should disable patch */ + dsp_buf[5] = 0x00; + } + + ret = fm_download_patch((const unsigned char *)dsp_buf, patch_len, IMG_COEFFICIENT); + if (ret) { + WCN_DBG(FM_ALT | CHIP, " DL DSPcoeff failed\n"); + goto out; + } + fm_reg_write(0x92, 0x0000); + fm_reg_write(0x90, 0x0040); + fm_reg_write(0x90, 0x0000); +out: + if (dsp_buf) { + fm_vfree(dsp_buf); + dsp_buf = NULL; + } + return ret; +} + + +static signed int mt6580_PowerUp(unsigned short *chip_id, unsigned short *device_id) +{ + signed int ret = 0; + unsigned short pkt_size; + unsigned short tmp_reg = 0; + + if (chip_id == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (device_id == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + WCN_DBG(FM_DBG | CHIP, "pwr on seq......\n"); + + mt6580_enable_pmic_tldo(); + + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = mt6580_pwrup_clock_on(cmd_buf, TX_BUF_SIZE); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + if (ret) { + WCN_DBG(FM_ALT | CHIP, "mt6580_pwrup_clock_on failed\n"); + return ret; + } + + fm_reg_read(0x62, &tmp_reg); + /* *chip_id = tmp_reg; */ + if ((tmp_reg == 0x6580) || (tmp_reg == 0x0633)) + *chip_id = 0x6580; + *device_id = tmp_reg; + mt6580_hw_info.chip_id = (signed int) tmp_reg; + WCN_DBG(FM_NTC | CHIP, "chip_id:0x%04x\n", tmp_reg); + + if ((mt6580_hw_info.chip_id != 0x6580) && (mt6580_hw_info.chip_id != 0x0633)) { + WCN_DBG(FM_NTC | CHIP, "fm sys error, reset hw\n"); + return -FM_EFW; + } + + ret = mt6580_pwrup_DSP_download(mt6580_patch_tbl); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "mt6580_pwrup_DSP_download failed\n"); + return ret; + } + + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = mt6580_pwrup_digital_init(cmd_buf, TX_BUF_SIZE); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + if (ret) { + WCN_DBG(FM_ALT | CHIP, "mt6580_pwrup_digital_init failed\n"); + return ret; + } + + /* set audio output I2S TX mode */ + fm_reg_write(0x9B, 0x3); + + WCN_DBG(FM_NTC | CHIP, "pwr on seq ok\n"); + + return ret; +} + +static signed int mt6580_PowerDown(void) +{ + signed int ret = 0; + unsigned short pkt_size; + unsigned short dataRead = 0; + + WCN_DBG(FM_DBG | CHIP, "pwr down seq\n"); + + /*SW work around for MCUFA issue. + *if interrupt happen before doing rampdown, DSP can't switch MCUFA back well. + * In case read interrupt, and clean if interrupt found before rampdown. + */ + fm_reg_read(FM_MAIN_INTR, &dataRead); + + if (dataRead & 0x1) { + ret = fm_reg_write(FM_MAIN_INTR, dataRead); /* clear status flag */ + if (ret) + WCN_DBG(FM_ALT | CHIP, "mt6580_pwrdown wr FM_MAIN_INTR failed\n"); + } + /* mt6580_RampDown(); */ + + /* set audio output I2X Rx mode: */ + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = mt6580_pwrdown(cmd_buf, TX_BUF_SIZE); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + if (ret) { + WCN_DBG(FM_ALT | CHIP, "mt6580_pwrdown failed\n"); + return ret; + } + + mt6580_disable_pmic_tldo(); + + return ret; +} + +static bool mt6580_SetFreq(unsigned short freq) +{ + signed int ret = 0; + unsigned short pkt_size; + unsigned short chan_para = 0; + unsigned short freq_reg = 0; + + fm_cb_op->cur_freq_set(freq); + + chan_para = mt6580_chan_para_get(freq); + WCN_DBG(FM_DBG | CHIP, "%d chan para = %d\n", (signed int) freq, (signed int) chan_para); + freq_reg = freq; + if (fm_get_channel_space(freq_reg) == 0) + freq_reg *= 10; + WCN_DBG(FM_DBG | CHIP, "freq_reg = %d\n", freq_reg); + ret = fm_reg_write(0x60, 0x00000007); + if (ret) + WCN_DBG(FM_ERR | CHIP, "set freq wr 0x60 failed\n"); + /* add this paragragh to resolve FM sensitivity bad in low band issue */ +#if 0 + if (mt6580_TDD_chan_check(freq)) { + ret = fm_set_bits(0x39, 0x0008, 0xFFF3); /* use TDD solution */ + WCN_DBG(FM_ERR | CHIP, "set freq wr 0x30 failed\n"); + } else { + ret = fm_set_bits(0x39, 0x0000, 0xFFF3); /* default use FDD solution */ + WCN_DBG(FM_ERR | CHIP, "set freq wr 0x30 failed\n"); + } +#endif + if ((freq_reg >= 6500) && (freq_reg <= 7290)) { + ret = fm_reg_write(0x39, 0xd002); + if (ret) + WCN_DBG(FM_ERR | CHIP, "set freq wr 0x39 failed\n"); + } else if ((freq_reg >= 7295) && (freq_reg <= 8410)) { + ret = fm_reg_write(0x39, 0xce02); + if (ret) + WCN_DBG(FM_ERR | CHIP, "set freq wr 0x39 failed\n"); + } else if ((freq_reg >= 8415) && (freq_reg <= 9815)) { + ret = fm_reg_write(0x39, 0xcc02); + if (ret) + WCN_DBG(FM_ERR | CHIP, "set freq wr 0x39 failed\n"); + } else if ((freq_reg >= 9820) && (freq_reg <= 9830)) { + ret = fm_reg_write(0x39, 0xca02); + if (ret) + WCN_DBG(FM_ERR | CHIP, "set freq wr 0x39 failed\n"); + } else if ((freq_reg >= 9835) && (freq_reg <= 9940)) { + ret = fm_reg_write(0x39, 0xcc02); + if (ret) + WCN_DBG(FM_ERR | CHIP, "set freq wr 0x39 failed\n"); + } else if ((freq_reg >= 9845) && (freq_reg <= 10800)) { + ret = fm_reg_write(0x39, 0xca02); + if (ret) + WCN_DBG(FM_ERR | CHIP, "set freq wr 0x39 failed\n"); + } else { + ret = fm_reg_write(0x39, 0xca02); + if (ret) + WCN_DBG(FM_ERR | CHIP, "set freq wr 0x39 failed\n"); + } + + /* end */ + ret = fm_reg_write(0x6a, 0x00000021); + if (ret) + WCN_DBG(FM_ERR | CHIP, "set freq wr 0x6a failed\n"); + + ret = fm_reg_write(0x6b, 0x00000021); + if (ret) + WCN_DBG(FM_ERR | CHIP, "set freq wr 0x6b failed\n"); + + ret = fm_reg_write(0x60, 0x0000000F); + if (ret) + WCN_DBG(FM_ERR | CHIP, "set freq wr 0x60 failed\n"); + + + freq_reg = (freq_reg - 6400) * 2 / 10; + ret = fm_set_bits(0x65, freq_reg, 0xFC00); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "set freq wr 0x65 failed\n"); + return false; + } + ret = fm_set_bits(0x65, (chan_para << 12), 0x0FFF); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "set freq wr 0x65 failed\n"); + return false; + } + + if (FM_LOCK(cmd_buf_lock)) + return false; + pkt_size = mt6580_tune(cmd_buf, TX_BUF_SIZE, freq, chan_para); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_TUNE | FLAG_TUNE_DONE, SW_RETRY_CNT, TUNE_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + + if (ret) { + WCN_DBG(FM_ALT | CHIP, "mt6580_tune failed\n"); + return false; + } + + WCN_DBG(FM_DBG | CHIP, "set freq to %d ok\n", freq); + + return true; +} + +#define FM_CQI_LOG_PATH "/mnt/sdcard/fmcqilog" + +static signed int mt6580_full_cqi_get(signed int min_freq, signed int max_freq, signed int space, signed int cnt) +{ + signed int ret = 0; + unsigned short pkt_size; + unsigned short freq, orig_freq; + signed int i, j, k; + signed int space_val, max, min, num; + struct mt6580_full_cqi *p_cqi; + unsigned char *cqi_log_title = "Freq, RSSI, PAMD, PR, FPAMD, MR, ATDC, PRX, ATDEV, SMGain, DltaRSSI\n"; + unsigned char cqi_log_buf[100] = { 0 }; + signed int pos; + unsigned char cqi_log_path[100] = { 0 }; + + WCN_DBG(FM_DBG | CHIP, "6580 cqi log start\n"); + /* for soft-mute tune, and get cqi */ + freq = fm_cb_op->cur_freq_get(); + if (fm_get_channel_space(freq) == 0) + freq *= 10; + + /* get cqi */ + orig_freq = freq; + if (fm_get_channel_space(min_freq) == 0) + min = min_freq * 10; + else + min = min_freq; + + if (fm_get_channel_space(max_freq) == 0) + max = max_freq * 10; + else + max = max_freq; + + if (space == 0x0001) + space_val = 5; /* 50Khz */ + else if (space == 0x0002) + space_val = 10; /* 100Khz */ + else if (space == 0x0004) + space_val = 20; /* 200Khz */ + else + space_val = 10; + + num = (max - min) / space_val + 1; /* Eg, (8760 - 8750) / 10 + 1 = 2 */ + for (k = 0; (orig_freq == 10000) && (g_dbg_level == 0xffffffff) && (k < cnt); k++) { + WCN_DBG(FM_NTC | CHIP, "cqi file:%d\n", k + 1); + freq = min; + pos = 0; + fm_memcpy(cqi_log_path, FM_CQI_LOG_PATH, strlen(FM_CQI_LOG_PATH)); + if (sprintf(&cqi_log_path[strlen(FM_CQI_LOG_PATH)], "%d.txt", k + 1) < 0) + WCN_DBG(FM_NTC | CHIP, "sprintf fail\n"); + fm_file_write(cqi_log_path, cqi_log_title, strlen(cqi_log_title), &pos); + for (j = 0; j < num; j++) { + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = fm_full_cqi_req(cmd_buf, TX_BUF_SIZE, &freq, 1, 1); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_SM_TUNE, SW_RETRY_CNT, + SM_TUNE_TIMEOUT, fm_get_read_result); + FM_UNLOCK(cmd_buf_lock); + + if (!ret && fm_res) { + WCN_DBG(FM_NTC | CHIP, "smt cqi size %d\n", fm_res->cqi[0]); + p_cqi = (struct mt6580_full_cqi *)&fm_res->cqi[2]; + for (i = 0; i < fm_res->cqi[1]; i++) { + /* just for debug */ + WCN_DBG(FM_NTC | CHIP, + "freq %d, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x\n", + p_cqi[i].ch, p_cqi[i].rssi, p_cqi[i].pamd, + p_cqi[i].pr, p_cqi[i].fpamd, p_cqi[i].mr, + p_cqi[i].atdc, p_cqi[i].prx, p_cqi[i].atdev, + p_cqi[i].smg, p_cqi[i].drssi); + /* format to buffer */ + if (sprintf(cqi_log_buf, + "%04d, %04x, %04x, %04x, %04x, %04x, %04x, %04x, %04x, %04x, %04x,\n", + p_cqi[i].ch, p_cqi[i].rssi, p_cqi[i].pamd, + p_cqi[i].pr, p_cqi[i].fpamd, p_cqi[i].mr, + p_cqi[i].atdc, p_cqi[i].prx, p_cqi[i].atdev, + p_cqi[i].smg, p_cqi[i].drssi) < 0) + WCN_DBG(FM_NTC | CHIP, "sprintf fail\n"); + /* write back to log file */ + fm_file_write(cqi_log_path, cqi_log_buf, strlen(cqi_log_buf), &pos); + } + } else { + WCN_DBG(FM_ALT | CHIP, "smt get CQI failed\n"); + ret = -1; + } + freq += space_val; + } + fm_cb_op->cur_freq_set(0); /* avoid run too much times */ + } + WCN_DBG(FM_DBG | CHIP, "6580 cqi log done\n"); + + return ret; +} + +/* + * mt6580_GetCurRSSI - get current freq's RSSI value + * RS=RSSI + * If RS>511, then RSSI(dBm)= (RS-1024)/16*6 + * else RSSI(dBm)= RS/16*6 + */ +static signed int mt6580_GetCurRSSI(signed int *pRSSI) +{ + unsigned short tmp_reg = 0; + + fm_reg_read(FM_RSSI_IND, &tmp_reg); + tmp_reg = tmp_reg & 0x03ff; + + if (pRSSI) { + *pRSSI = (tmp_reg > 511) ? (((tmp_reg - 1024) * 6) >> 4) : ((tmp_reg * 6) >> 4); + WCN_DBG(FM_DBG | CHIP, "rssi:%d, dBm:%d\n", tmp_reg, *pRSSI); + } else { + WCN_DBG(FM_ERR | CHIP, "get rssi para error\n"); + return -FM_EPARA; + } + + return 0; +} + +static unsigned short mt6580_vol_tbl[16] = { 0x0000, 0x0519, 0x066A, 0x0814, + 0x0A2B, 0x0CCD, 0x101D, 0x1449, + 0x198A, 0x2027, 0x287A, 0x32F5, + 0x4027, 0x50C3, 0x65AD, 0x7FFF +}; + +static signed int mt6580_SetVol(unsigned char vol) +{ + signed int ret = 0; + + vol = (vol > 15) ? 15 : vol; + ret = fm_reg_write(0x7D, mt6580_vol_tbl[vol]); + if (ret) { + WCN_DBG(FM_ERR | CHIP, "Set vol=%d Failed\n", vol); + return ret; + } + + WCN_DBG(FM_DBG | CHIP, "Set vol=%d OK\n", vol); + + if (vol == 10) { + fm_print_cmd_fifo(); /* just for debug */ + fm_print_evt_fifo(); + } + return 0; +} + +static signed int mt6580_GetVol(unsigned char *pVol) +{ + int ret = 0; + unsigned short tmp = 0; + signed int i; + + if (pVol == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + ret = fm_reg_read(0x7D, &tmp); + if (ret) { + *pVol = 0; + WCN_DBG(FM_ERR | CHIP, "Get vol Failed\n"); + return ret; + } + + for (i = 0; i < 16; i++) { + if (mt6580_vol_tbl[i] == tmp) { + *pVol = i; + break; + } + } + + WCN_DBG(FM_DBG | CHIP, "Get vol=%d OK\n", *pVol); + return 0; +} + +static signed int mt6580_dump_reg(void) +{ + signed int i; + unsigned short TmpReg = 0; + + for (i = 0; i < 0xff; i++) { + fm_reg_read(i, &TmpReg); + WCN_DBG(FM_NTC | CHIP, "0x%02x=0x%04x\n", i, TmpReg); + } + return 0; +} + +/*0:mono, 1:stereo*/ +static bool mt6580_GetMonoStereo(unsigned short *pMonoStereo) +{ +#define FM_BF_STEREO 0x1000 + unsigned short TmpReg = 0; + + if (pMonoStereo) { + fm_reg_read(FM_RSSI_IND, &TmpReg); + *pMonoStereo = (TmpReg & FM_BF_STEREO) >> 12; + } else { + WCN_DBG(FM_ERR | CHIP, "MonoStero: para err\n"); + return false; + } + + WCN_DBG(FM_NTC | CHIP, "Get MonoStero:0x%04x\n", *pMonoStereo); + return true; +} + +static signed int mt6580_SetMonoStereo(signed int MonoStereo) +{ + signed int ret = 0; + + WCN_DBG(FM_NTC | CHIP, "set to %s\n", MonoStereo ? "mono" : "auto"); + fm_top_reg_write(0x50, 0x0007); + + if (MonoStereo) { /*mono */ + ret = fm_set_bits(0x75, 0x0008, ~0x0008); + } else { /*auto switch */ + + ret = fm_set_bits(0x75, 0x0000, ~0x0008); + } + + fm_top_reg_write(0x50, 0x000F); + return ret; +} + +static signed int mt6580_GetCapArray(signed int *ca) +{ + unsigned short dataRead = 0; + unsigned short tmp = 0; + + if (ca == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + fm_reg_read(0x60, &tmp); + fm_reg_write(0x60, tmp & 0xFFF7); /* 0x60 D3=0 */ + + fm_reg_read(0x26, &dataRead); + *ca = dataRead; + + fm_reg_write(0x60, tmp); /* 0x60 D3=1 */ + return 0; +} + +/* + * mt6580_GetCurPamd - get current freq's PAMD value + * PA=PAMD + * If PA>511 then PAMD(dB)= (PA-1024)/16*6, + * else PAMD(dB)=PA/16*6 + */ +static bool mt6580_GetCurPamd(unsigned short *pPamdLevl) +{ + unsigned short tmp_reg = 0; + unsigned short dBvalue, valid_cnt = 0; + int i, total = 0; + + for (i = 0; i < 8; i++) { + if (fm_reg_read(FM_ADDR_PAMD, &tmp_reg)) { + *pPamdLevl = 0; + return false; + } + + tmp_reg &= 0x03FF; + dBvalue = (tmp_reg > 256) ? ((512 - tmp_reg) * 6 / 16) : 0; + if (dBvalue != 0) { + total += dBvalue; + valid_cnt++; + WCN_DBG(FM_DBG | CHIP, "[%d]PAMD=%d\n", i, dBvalue); + } + fm_delayms(3); + } + if (valid_cnt != 0) + *pPamdLevl = total / valid_cnt; + else + *pPamdLevl = 0; + + WCN_DBG(FM_NTC | CHIP, "PAMD=%d\n", *pPamdLevl); + return true; +} + +static signed int mt6580_i2s_info_get(signed int *ponoff, signed int *pmode, signed int *psample) +{ + if (ponoff == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (pmode == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (psample == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + *ponoff = fm_config.aud_cfg.i2s_info.status; + *pmode = fm_config.aud_cfg.i2s_info.mode; + *psample = fm_config.aud_cfg.i2s_info.rate; + + return 0; +} + +static signed int mt6580fm_get_audio_info(struct fm_audio_info_t *data) +{ + memcpy(data, &fm_config.aud_cfg, sizeof(struct fm_audio_info_t)); + return 0; +} + +static signed int mt6580_hw_info_get(struct fm_hw_info *req) +{ + if (req == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + req->chip_id = mt6580_hw_info.chip_id; + req->eco_ver = mt6580_hw_info.eco_ver; + req->patch_ver = mt6580_hw_info.patch_ver; + req->rom_ver = mt6580_hw_info.rom_ver; + + return 0; +} + +static signed int mt6580_pre_search(void) +{ + mt6580_RampDown(); + /* disable audio output I2S Rx mode */ + fm_host_reg_write(0x80101054, 0x00000000); + /* disable audio output I2S Tx mode */ + fm_reg_write(0x9B, 0x0000); + + return 0; +} + +static signed int mt6580_restore_search(void) +{ + mt6580_RampDown(); + /* set audio output I2S Tx mode */ + fm_reg_write(0x9B, 0xF9AB); + /* set audio output I2S Rx mode */ + fm_host_reg_write(0x80101054, 0x00003f35); + return 0; +} + +static signed int mt6580_soft_mute_tune(unsigned short freq, signed int *rssi, signed int *valid) +{ + signed int ret = 0; + unsigned short pkt_size; + struct mt6580_full_cqi *p_cqi; + signed int RSSI = 0, PAMD = 0, MR = 0, ATDC = 0; + unsigned int PRX = 0, ATDEV = 0; + unsigned short softmuteGainLvl = 0; + unsigned short freq_reg = 0; + + /* add this paragragh to resolve FM sensitivity bad in low band issue */ +#if 0 + ret = mt6580_chan_para_get(freq); + if (ret == 2) + ret = fm_set_bits(FM_CHANNEL_SET, 0x2000, 0x0FFF); /* mdf HiLo */ + else + ret = fm_set_bits(FM_CHANNEL_SET, 0x0000, 0x0FFF); /* clear FA/HL/ATJ */ +#endif + freq_reg = freq; + if (fm_get_channel_space(freq_reg) == 0) + freq_reg *= 10; + + ret = fm_reg_write(0x60, 0x00000007); + if (ret) + WCN_DBG(FM_ERR | CHIP, "set freq wr 0x60 failed\n"); + + if ((freq_reg >= 6500) && (freq_reg <= 7290)) { + ret = fm_reg_write(0x39, 0xd002); + if (ret) + WCN_DBG(FM_ERR | CHIP, "set freq wr 0x39 failed\n"); + } else if ((freq_reg >= 7295) && (freq_reg <= 8410)) { + ret = fm_reg_write(0x39, 0xce02); + if (ret) + WCN_DBG(FM_ERR | CHIP, "set freq wr 0x39 failed\n"); + } else if ((freq_reg >= 8415) && (freq_reg <= 9815)) { + ret = fm_reg_write(0x39, 0xcc02); + if (ret) + WCN_DBG(FM_ERR | CHIP, "set freq wr 0x39 failed\n"); + } else if ((freq_reg >= 9820) && (freq_reg <= 9830)) { + ret = fm_reg_write(0x39, 0xca02); + if (ret) + WCN_DBG(FM_ERR | CHIP, "set freq wr 0x39 failed\n"); + } else if ((freq_reg >= 9835) && (freq_reg <= 9940)) { + ret = fm_reg_write(0x39, 0xcc02); + if (ret) + WCN_DBG(FM_ERR | CHIP, "set freq wr 0x39 failed\n"); + } else if ((freq_reg >= 9845) && (freq_reg <= 10800)) { + ret = fm_reg_write(0x39, 0xca02); + if (ret) + WCN_DBG(FM_ERR | CHIP, "set freq wr 0x39 failed\n"); + } else { + ret = fm_reg_write(0x39, 0xca02); + if (ret) + WCN_DBG(FM_ERR | CHIP, "set freq wr 0x39 failed\n"); + } + + ret = fm_reg_write(0x60, 0x0000000f); + if (ret) + WCN_DBG(FM_ERR | CHIP, "set freq wr 0x60 failed\n"); + /* end */ + + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = fm_full_cqi_req(cmd_buf, TX_BUF_SIZE, &freq, 1, 1); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_SM_TUNE, SW_RETRY_CNT, SM_TUNE_TIMEOUT, fm_get_read_result); + FM_UNLOCK(cmd_buf_lock); + + if (!ret && fm_res) { + WCN_DBG(FM_NTC | CHIP, "smt cqi size %d\n", fm_res->cqi[0]); + p_cqi = (struct mt6580_full_cqi *)&fm_res->cqi[2]; + /* just for debug */ + WCN_DBG(FM_NTC | CHIP, + "freq %d, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x\n", + p_cqi->ch, p_cqi->rssi, p_cqi->pamd, p_cqi->pr, p_cqi->fpamd, p_cqi->mr, + p_cqi->atdc, p_cqi->prx, p_cqi->atdev, p_cqi->smg, p_cqi->drssi); + RSSI = ((p_cqi->rssi & 0x03FF) >= 512) ? ((p_cqi->rssi & 0x03FF) - 1024) : (p_cqi->rssi & 0x03FF); + PAMD = ((p_cqi->pamd & 0x1FF) >= 256) ? ((p_cqi->pamd & 0x01FF) - 512) : (p_cqi->pamd & 0x01FF); + MR = ((p_cqi->mr & 0x01FF) >= 256) ? ((p_cqi->mr & 0x01FF) - 512) : (p_cqi->mr & 0x01FF); + ATDC = (p_cqi->atdc >= 32768) ? (65536 - p_cqi->atdc) : (p_cqi->atdc); + if (ATDC < 0) + ATDC = (~(ATDC)) - 1; /* Get abs value of ATDC */ + + PRX = (p_cqi->prx & 0x00FF); + ATDEV = p_cqi->atdev; + softmuteGainLvl = p_cqi->smg; + /* check if the channel is valid according to each CQIs */ + if ((fm_config.rx_cfg.long_ana_rssi_th <= RSSI) + && (fm_config.rx_cfg.pamd_th >= PAMD) + && (fm_config.rx_cfg.atdc_th >= ATDC) + && (fm_config.rx_cfg.mr_th <= MR) + && (fm_config.rx_cfg.prx_th <= PRX) + && (ATDEV >= ATDC) /* sync scan algorithm */ + && (fm_config.rx_cfg.smg_th <= softmuteGainLvl)) { + *valid = true; + } else { + *valid = false; + } + *rssi = RSSI; +/* if(RSSI < -296) +* WCN_DBG(FM_NTC | CHIP, "rssi\n"); +* else if(PAMD > -12) +* WCN_DBG(FM_NTC | CHIP, "PAMD\n"); +* else if(ATDC > 3496) +* WCN_DBG(FM_NTC | CHIP, "ATDC\n"); +* else if(MR < -67) +* WCN_DBG(FM_NTC | CHIP, "MR\n"); +* else if(PRX < 80) +* WCN_DBG(FM_NTC | CHIP, "PRX\n"); +* else if(ATDEV < ATDC) +* WCN_DBG(FM_NTC | CHIP, "ATDEV\n"); +* else if(softmuteGainLvl < 16421) +* WCN_DBG(FM_NTC | CHIP, "softmuteGainLvl\n"); +*/ + } else { + WCN_DBG(FM_ALT | CHIP, "smt get CQI failed\n"); + return false; + } + WCN_DBG(FM_NTC | CHIP, "valid=%d\n", *valid); + return true; +} + +static bool mt6580_em_test(unsigned short group_idx, unsigned short item_idx, unsigned int item_value) +{ + return true; +} + +/* +*parm: +* parm.th_type: 0, RSSI. 1,desense RSSI. 2,SMG. +* parm.th_val: threshold value +*/ +static signed int mt6580_set_search_th(signed int idx, signed int val, signed int reserve) +{ + switch (idx) { + case 0: + { + fm_config.rx_cfg.long_ana_rssi_th = val; + WCN_DBG(FM_NTC | CHIP, "set rssi th =%d\n", val); + break; + } + case 1: + { + fm_config.rx_cfg.desene_rssi_th = val; + WCN_DBG(FM_NTC | CHIP, "set desense rssi th =%d\n", val); + break; + } + case 2: + { + fm_config.rx_cfg.smg_th = val; + WCN_DBG(FM_NTC | CHIP, "set smg th =%d\n", val); + break; + } + default: + break; + } + return 0; +} + +static signed int MT6580fm_low_power_wa_default(signed int fmon) +{ + return 0; +} + +signed int fm_low_ops_register(struct fm_callback *cb, struct fm_basic_interface *bi) +{ + signed int ret = 0; + /* Basic functions. */ + + if (bi == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,bi invalid pointer\n", __func__); + return -FM_EPARA; + } + if (cb->cur_freq_get == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,cb->cur_freq_get invalid pointer\n", __func__); + return -FM_EPARA; + } + if (cb->cur_freq_set == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,cb->cur_freq_set invalid pointer\n", __func__); + return -FM_EPARA; + } + fm_cb_op = cb; + + bi->pwron = mt6580_pwron; + bi->pwroff = mt6580_pwroff; + bi->chipid_get = mt6580_get_chipid; + bi->mute = mt6580_Mute; + bi->rampdown = mt6580_RampDown; + bi->pwrupseq = mt6580_PowerUp; + bi->pwrdownseq = mt6580_PowerDown; + bi->setfreq = mt6580_SetFreq; + bi->low_pwr_wa = MT6580fm_low_power_wa_default; + bi->get_aud_info = mt6580fm_get_audio_info; + bi->rssiget = mt6580_GetCurRSSI; + bi->volset = mt6580_SetVol; + bi->volget = mt6580_GetVol; + bi->dumpreg = mt6580_dump_reg; + bi->msget = mt6580_GetMonoStereo; + bi->msset = mt6580_SetMonoStereo; + bi->pamdget = mt6580_GetCurPamd; + bi->em = mt6580_em_test; + bi->anaswitch = mt6580_SetAntennaType; + bi->anaget = mt6580_GetAntennaType; + bi->caparray_get = mt6580_GetCapArray; + bi->hwinfo_get = mt6580_hw_info_get; + bi->i2s_get = mt6580_i2s_info_get; + bi->is_dese_chan = mt6580_is_dese_chan; + bi->softmute_tune = mt6580_soft_mute_tune; + bi->desense_check = mt6580_desense_check; + bi->cqi_log = mt6580_full_cqi_get; + bi->pre_search = mt6580_pre_search; + bi->restore_search = mt6580_restore_search; + bi->set_search_th = mt6580_set_search_th; + + cmd_buf_lock = fm_lock_create("80_cmd"); + ret = fm_lock_get(cmd_buf_lock); + + cmd_buf = fm_zalloc(TX_BUF_SIZE + 1); + + if (!cmd_buf) { + WCN_DBG(FM_ALT | CHIP, "6580 fm lib alloc tx buf failed\n"); + ret = -1; + } +#if 0 /* def CONFIG_MTK_FM_50KHZ_SUPPORT */ + cqi_fifo = fm_fifo_create("6628_cqi_fifo", sizeof(struct adapt_fm_cqi), 640); + if (!cqi_fifo) { + WCN_DBG(FM_ALT | CHIP, "6627 fm lib create cqi fifo failed\n"); + ret = -1; + } +#endif + + return ret; +} + +signed int fm_low_ops_unregister(struct fm_basic_interface *bi) +{ + signed int ret = 0; + /* Basic functions. */ + if (bi == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + +#if 0 /* def CONFIG_MTK_FM_50KHZ_SUPPORT */ + fm_fifo_release(cqi_fifo); +#endif + + if (cmd_buf) { + fm_free(cmd_buf); + cmd_buf = NULL; + } + + ret = fm_lock_put(cmd_buf_lock); + fm_memset(bi, 0, sizeof(struct fm_basic_interface)); + return ret; +} + +/* static struct fm_pub pub; */ +/* static struct fm_pub_cb *pub_cb = &pub.pub_tbl; */ + +static const unsigned short mt6580_mcu_dese_list[] = { + 0 +}; + +static const unsigned short mt6580_gps_dese_list[] = { + 7850, 7860 +}; + +static const signed char mt6580_chan_para_map[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6500~6595 */ + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, /* 6600~6695 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6700~6795 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6800~6895 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, /* 6900~6995 */ + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7000~7095 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7100~7195 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, /* 7200~7295 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, /* 7300~7395 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7400~7495 */ + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, /* 7500~7595 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7600~7695 */ + 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7700~7795 */ + 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, /* 7800~7895 */ + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7900~7995 */ + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8000~8095 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, /* 8100~8195 */ + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8200~8295 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, /* 8300~8395 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8400~8495 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8500~8595 */ + 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, /* 8600~8695 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8700~8795 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8800~8895 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8900~8995 */ + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9000~9095 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9100~9195 */ + 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, /* 9200~9295 */ + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9300~9395 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9400~9495 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9500~9595 */ + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, /* 9600~9695 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9700~9795 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9800~9895 */ + 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9900~9995 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10000~10095 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10100~10195 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10200~10295 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10300~10395 */ + 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10400~10495 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10500~10595 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10600~10695 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10700~10795 */ + 0 /* 10800 */ +}; + +static const unsigned short mt6580_scan_dese_list[] = { + 6700, 7800, 9210, 9220, 9300, 1040, 1041 +}; + +static const unsigned short mt6580_TDD_list[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 6500~6595 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 6600~6695 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 6700~6795 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 6800~6895 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 6900~6995 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7000~7095 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7100~7195 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7200~7295 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7300~7395 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7400~7495 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7500~7595 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7600~7695 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7700~7795 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7800~7895 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7900~7995 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8000~8095 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8100~8195 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8200~8295 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8300~8395 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8400~8495 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8500~8595 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8600~8695 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8700~8795 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8800~8895 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8900~8995 */ + 0x0000, 0x0000, 0x0000, 0x0100, 0x0000, /* 9000~9095 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9100~9195 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9200~9295 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9300~9395 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9400~9495 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9500~9595 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9600~9695 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9700~9795 */ + 0x0000, 0x0101, 0x0000, 0x0000, 0x0000, /* 9800~9895 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9900~9995 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10000~10095 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10100~10195 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10200~10295 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10300~10395 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10400~10495 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10500~10595 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 10600~10695 */ + 0x0000, 0x0001, 0x0000, 0x0000, 0x0000, /* 10700~10795 */ + 0x0000 /* 10800 */ +}; + +static const unsigned short mt6580_TDD_Mask[] = { + 0x0001, 0x0010, 0x0100, 0x1000 +}; + +/* return value: 0, not a de-sense channel; 1, this is a de-sense channel; else error no */ +static signed int mt6580_is_dese_chan(unsigned short freq) +{ + signed int size; + + /* return 0;//HQA only :skip desense channel check. */ + size = ARRAY_SIZE(mt6580_scan_dese_list); + + if (fm_get_channel_space(freq) == 0) + freq *= 10; + + while (size) { + if (mt6580_scan_dese_list[size - 1] == freq) + return 1; + + size--; + } + + return 0; +} + +/* return value: +*1, is desense channel and rssi is less than threshold; +*0, not desense channel or it is but rssi is more than threshold. +*/ +static signed int mt6580_desense_check(unsigned short freq, signed int rssi) +{ + if (mt6580_is_dese_chan(freq)) { + if (rssi < fm_config.rx_cfg.desene_rssi_th) + return 1; + + WCN_DBG(FM_DBG | CHIP, "desen_rssi %d th:%d\n", rssi, fm_config.rx_cfg.desene_rssi_th); + } + return 0; +} +#if 0 +static bool mt6580_TDD_chan_check(unsigned short freq) +{ + unsigned int i = 0; + unsigned short freq_tmp = freq; + signed int ret = 0; + + ret = fm_get_channel_space(freq_tmp); + if (ret == 0) + freq_tmp *= 10; + else if (-1 == ret) + return false; + + i = (freq_tmp - 6500) / 5; + if ((i / 4) >= ARRAY_SIZE(mt6580_TDD_list)) { + WCN_DBG(FM_ERR | CHIP, "Freq index out of range(%d),max(%zd)\n", + i / 4, ARRAY_SIZE(mt6580_TDD_list)); + return false; + } + + WCN_DBG(FM_NTC | CHIP, "Freq %d is 0x%4x, mask is 0x%4x\n", freq, (mt6580_TDD_list[i / 4]), + mt6580_TDD_Mask[i % 4]); + if (mt6580_TDD_list[i / 4] & mt6580_TDD_Mask[i % 4]) { + WCN_DBG(FM_NTC | CHIP, "Freq %d use TDD solution\n", freq); + return true; + } else + return false; +} +#endif +/* get channel parameter, HL side/ FA / ATJ */ +static unsigned short mt6580_chan_para_get(unsigned short freq) +{ + signed int pos, size; + + /* return 0;//for HQA only: skip FA/HL/ATJ */ + if (fm_get_channel_space(freq) == 0) + freq *= 10; + + if (freq < 6500) + return 0; + + pos = (freq - 6500) / 5; + + size = ARRAY_SIZE(mt6580_chan_para_map); + + pos = (pos > (size - 1)) ? (size - 1) : pos; + + return mt6580_chan_para_map[pos]; +} diff --git a/drivers/misc/mediatek/connectivity/fmradio/chips/soc/pub/soc_fm_rds.c b/drivers/misc/mediatek/connectivity/fmradio/chips/soc/pub/soc_fm_rds.c new file mode 100644 index 0000000000000000000000000000000000000000..49d9ebef5803dd0e27db2e32e3d5075de140a489 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/chips/soc/pub/soc_fm_rds.c @@ -0,0 +1,334 @@ +/* + * Copyright (C) 2015 MediaTek Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 "fm_typedef.h" +#include "fm_dbg.h" +#include "fm_err.h" +#include "fm_interface.h" +#include "fm_stdlib.h" +#include "fm_rds.h" +#include "soc_fm_reg.h" +#include "fm_cmd.h" + +static bool bRDS_FirstIn; /* false */ +static unsigned int gBLER_CHK_INTERVAL = 500; +static unsigned short GOOD_BLK_CNT = 0, BAD_BLK_CNT; +static unsigned char BAD_BLK_RATIO; + +static struct fm_basic_interface *fm_bi; + +static bool mt6580_RDS_support(void); +static signed int mt6580_RDS_enable(void); +static signed int mt6580_RDS_disable(void); +static unsigned short mt6580_RDS_Get_GoodBlock_Counter(void); +static unsigned short mt6580_RDS_Get_BadBlock_Counter(void); +static unsigned char mt6580_RDS_Get_BadBlock_Ratio(void); +static unsigned int mt6580_RDS_Get_BlerCheck_Interval(void); +/* static void mt6580_RDS_GetData(unsigned short *data, unsigned short datalen); */ +static void mt6580_RDS_Init_Data(struct rds_t *pstRDSData); + +static bool mt6580_RDS_support(void) +{ + return true; +} + +static signed int mt6580_RDS_enable(void) +{ + signed int ret = 0; + unsigned short dataRead = 0; + + WCN_DBG(FM_DBG | RDSC, "rds enable\n"); + ret = fm_reg_read(FM_RDS_CFG0, &dataRead); + if (ret) { + WCN_DBG(FM_NTC | RDSC, "rds enable read 0x80 fail\n"); + return ret; + } + ret = fm_reg_write(FM_RDS_CFG0, 6); /* set buf_start_th */ + if (ret) { + WCN_DBG(FM_NTC | RDSC, "rds enable write 0x80 fail\n"); + return ret; + } + ret = fm_reg_read(FM_MAIN_CTRL, &dataRead); + if (ret) { + WCN_DBG(FM_NTC | RDSC, "rds enable read 0x63 fail\n"); + return ret; + } + ret = fm_reg_write(FM_MAIN_CTRL, dataRead | (RDS_MASK)); + if (ret) { + WCN_DBG(FM_NTC | RDSC, "rds enable write 0x63 fail\n"); + return ret; + } + + return ret; +} + +static signed int mt6580_RDS_disable(void) +{ + signed int ret = 0; + unsigned short dataRead = 0; + + WCN_DBG(FM_DBG | RDSC, "rds disable\n"); + ret = fm_reg_read(FM_MAIN_CTRL, &dataRead); + if (ret) { + WCN_DBG(FM_NTC | RDSC, "rds disable read 0x63 fail\n"); + return ret; + } + ret = fm_reg_write(FM_MAIN_CTRL, dataRead & (~RDS_MASK)); + if (ret) { + WCN_DBG(FM_NTC | RDSC, "rds disable write 0x63 fail\n"); + return ret; + } + + return ret; +} + +static unsigned short mt6580_RDS_Get_GoodBlock_Counter(void) +{ + unsigned short tmp_reg = 0; + + fm_reg_read(FM_RDS_GOODBK_CNT, &tmp_reg); + GOOD_BLK_CNT = tmp_reg; + WCN_DBG(FM_DBG | RDSC, "get good block cnt:%d\n", (signed int) tmp_reg); + + return tmp_reg; +} + +static unsigned short mt6580_RDS_Get_BadBlock_Counter(void) +{ + unsigned short tmp_reg = 0; + + fm_reg_read(FM_RDS_BADBK_CNT, &tmp_reg); + BAD_BLK_CNT = tmp_reg; + WCN_DBG(FM_DBG | RDSC, "get bad block cnt:%d\n", (signed int) tmp_reg); + + return tmp_reg; +} + +static unsigned char mt6580_RDS_Get_BadBlock_Ratio(void) +{ + unsigned short tmp_reg; + unsigned short gbc; + unsigned short bbc; + + gbc = mt6580_RDS_Get_GoodBlock_Counter(); + bbc = mt6580_RDS_Get_BadBlock_Counter(); + + if ((gbc + bbc) > 0) + tmp_reg = (unsigned char) (bbc * 100 / (gbc + bbc)); + else + tmp_reg = 0; + + BAD_BLK_RATIO = tmp_reg; + WCN_DBG(FM_DBG | RDSC, "get badblock ratio:%d\n", (signed int) tmp_reg); + + return tmp_reg; +} + +static signed int mt6580_RDS_BlockCounter_Reset(void) +{ + mt6580_RDS_disable(); + mt6580_RDS_enable(); + + return 0; +} + +static unsigned int mt6580_RDS_Get_BlerCheck_Interval(void) +{ + return gBLER_CHK_INTERVAL; +} + +static signed int mt6580_RDS_BlerCheck(struct rds_t *dst) +{ + return 0; +} + +#if 0 +static void RDS_Recovery_Handler(void) +{ + unsigned short tempData = 0; + + do { + fm_reg_read(FM_RDS_DATA_REG, &tempData); + fm_reg_read(FM_RDS_POINTER, &tempData); + } while (tempData & 0x3); +} +#endif + +#if 0 +static void mt6580_RDS_GetData(unsigned short *data, unsigned short datalen) +{ +#define RDS_GROUP_DIFF_OFS 0x007C +#define RDS_FIFO_DIFF 0x007F +#define RDS_CRC_BLK_ADJ 0x0020 +#define RDS_CRC_CORR_CNT 0x001E +#define RDS_CRC_INFO 0x0001 + + unsigned short CRC = 0, i = 0, RDS_adj = 0, RDSDataCount = 0, FM_WARorrCnt = 0; + unsigned short temp = 0, OutputPofm_s32 = 0; + + WCN_DBG(FM_DBG | RDSC, "get data\n"); + fm_reg_read(FM_RDS_FIFO_STATUS0, &temp); + RDSDataCount = ((RDS_GROUP_DIFF_OFS & temp) << 2); + + if ((temp & RDS_FIFO_DIFF) >= 4) { + /* block A data and info handling */ + fm_reg_read(FM_RDS_INFO, &temp); + RDS_adj |= (temp & RDS_CRC_BLK_ADJ) << 10; + CRC |= (temp & RDS_CRC_INFO) << 3; + FM_WARorrCnt |= ((temp & RDS_CRC_CORR_CNT) << 11); + fm_reg_read(FM_RDS_DATA_REG, &data[0]); + + /* block B data and info handling */ + fm_reg_read(FM_RDS_INFO, &temp); + RDS_adj |= (temp & RDS_CRC_BLK_ADJ) << 9; + CRC |= (temp & RDS_CRC_INFO) << 2; + FM_WARorrCnt |= ((temp & RDS_CRC_CORR_CNT) << 7); + fm_reg_read(FM_RDS_DATA_REG, &data[1]); + + /* block C data and info handling */ + fm_reg_read(FM_RDS_INFO, &temp); + RDS_adj |= (temp & RDS_CRC_BLK_ADJ) << 8; + CRC |= (temp & RDS_CRC_INFO) << 1; + FM_WARorrCnt |= ((temp & RDS_CRC_CORR_CNT) << 3); + fm_reg_read(FM_RDS_DATA_REG, &data[2]); + + /* block D data and info handling */ + fm_reg_read(FM_RDS_INFO, &temp); + RDS_adj |= (temp & RDS_CRC_BLK_ADJ) << 7; + CRC |= (temp & RDS_CRC_INFO); + FM_WARorrCnt |= ((temp & RDS_CRC_CORR_CNT) >> 1); + fm_reg_read(FM_RDS_DATA_REG, &data[3]); + + data[4] = (CRC | RDS_adj | RDSDataCount); + data[5] = FM_WARorrCnt; + + fm_reg_read(FM_RDS_PWDI, &data[6]); + fm_reg_read(FM_RDS_PWDQ, &data[7]); + + fm_reg_read(FM_RDS_POINTER, &OutputPofm_s32); + + /* Go fm_s32o RDS recovery handler while RDS output pofm_s32 doesn't align to 4 in numeric */ + if (OutputPofm_s32 & 0x3) + RDS_Recovery_Handler(); + + } else { + for (; i < 8; i++) + data[i] = 0; + } +} +#endif + +static void mt6580_RDS_Init_Data(struct rds_t *pstRDSData) +{ + fm_memset(pstRDSData, 0, sizeof(struct rds_t)); + bRDS_FirstIn = true; + + pstRDSData->event_status = 0x0000; + fm_memset(pstRDSData->RT_Data.TextData, 0x20, sizeof(pstRDSData->RT_Data.TextData)); + fm_memset(pstRDSData->PS_Data.PS, '\0', sizeof(pstRDSData->PS_Data.PS)); + fm_memset(pstRDSData->PS_ON, 0x20, sizeof(pstRDSData->PS_ON)); +} + +bool mt6580_RDS_OnOff(struct rds_t *dst, bool bFlag) +{ + signed int ret = 0; + + if (mt6580_RDS_support() == false) { + WCN_DBG(FM_ALT | RDSC, "mt6580_RDS_OnOff failed, RDS not support\n"); + return false; + } + + if (bFlag) { + mt6580_RDS_Init_Data(dst); + ret = mt6580_RDS_enable(); + if (ret) { + WCN_DBG(FM_NTC | RDSC, "mt6580_RDS_OnOff enable failed\n"); + return false; + } + } else { + mt6580_RDS_Init_Data(dst); + ret = mt6580_RDS_disable(); + if (ret) { + WCN_DBG(FM_NTC | RDSC, "mt6580_RDS_OnOff disable failed\n"); + return false; + } + } + + return true; +} + +DEFINE_RDSLOG(mt6580_rds_log); + +/* mt6580_RDS_Efm_s32_Handler - response FM RDS interrupt + * @fm - main data structure of FM driver + * This function first get RDS raw data, then call RDS spec parser + */ +static signed int mt6580_rds_parser(struct rds_t *rds_dst, struct rds_rx_t *rds_raw, + signed int rds_size, unsigned short(*getfreq) (void)) +{ + mt6580_rds_log.log_in(&mt6580_rds_log, rds_raw, rds_size); + return rds_parser(rds_dst, rds_raw, rds_size, getfreq); +} + +static signed int mt6580_rds_log_get(struct rds_rx_t *dst, signed int *dst_len) +{ + return mt6580_rds_log.log_out(&mt6580_rds_log, dst, dst_len); +} + +static signed int mt6580_rds_gc_get(struct rds_group_cnt_t *dst, struct rds_t *rdsp) +{ + return rds_grp_counter_get(dst, &rdsp->gc); +} + +static signed int mt6580_rds_gc_reset(struct rds_t *rdsp) +{ + return rds_grp_counter_reset(&rdsp->gc); +} + +signed int fm_rds_ops_register(struct fm_basic_interface *bi, struct fm_rds_interface *ri) +{ + signed int ret = 0; + + if (ri == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,ri invalid pointer\n", __func__); + return -FM_EPARA; + } + fm_bi = bi; + + ri->rds_blercheck = mt6580_RDS_BlerCheck; + ri->rds_onoff = mt6580_RDS_OnOff; + ri->rds_parser = mt6580_rds_parser; + ri->rds_gbc_get = mt6580_RDS_Get_GoodBlock_Counter; + ri->rds_bbc_get = mt6580_RDS_Get_BadBlock_Counter; + ri->rds_bbr_get = mt6580_RDS_Get_BadBlock_Ratio; + ri->rds_bc_reset = mt6580_RDS_BlockCounter_Reset; + ri->rds_bci_get = mt6580_RDS_Get_BlerCheck_Interval; + ri->rds_log_get = mt6580_rds_log_get; + ri->rds_gc_get = mt6580_rds_gc_get; + ri->rds_gc_reset = mt6580_rds_gc_reset; + return ret; +} + +signed int fm_rds_ops_unregister(struct fm_rds_interface *ri) +{ + signed int ret = 0; + + if (ri == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,ri invalid pointer\n", __func__); + return -FM_EPARA; + } + + fm_bi = NULL; + fm_memset(ri, 0, sizeof(struct fm_rds_interface)); + return ret; +} diff --git a/drivers/misc/mediatek/connectivity/fmradio/core/fm_cmd.c b/drivers/misc/mediatek/connectivity/fmradio/core/fm_cmd.c new file mode 100644 index 0000000000000000000000000000000000000000..e79d41b5200d68fc139ef74e2c1ad3ccf4f8bc57 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/core/fm_cmd.c @@ -0,0 +1,842 @@ +/* +* Copyright (C) 2016 MediaTek Inc. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. +*/ + +#include +#include + +#include "fm_typedef.h" +#include "fm_dbg.h" +#include "fm_err.h" +#include "fm_rds.h" +#include "fm_config.h" +#include "fm_link.h" +#include "fm_cmd.h" + +signed int fm_bop_write(unsigned char addr, unsigned short value, unsigned char *buf, signed int size) +{ + if (size < (FM_WRITE_BASIC_OP_SIZE + 2)) { + WCN_DBG(FM_ERR | CHIP, "%s : left size(%d)/need size(%d)\n", + __func__, size, FM_WRITE_BASIC_OP_SIZE + 2); + return -1; + } + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s :buf invalid pointer\n", __func__); + return -2; + } + + buf[0] = FM_WRITE_BASIC_OP; + buf[1] = FM_WRITE_BASIC_OP_SIZE; + buf[2] = addr; + buf[3] = (unsigned char) ((value) & 0x00FF); + buf[4] = (unsigned char) ((value >> 8) & 0x00FF); + + WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x\n", buf[0], buf[1], buf[2], buf[3], buf[4]); + + return FM_WRITE_BASIC_OP_SIZE + 2; +} + +signed int fm_bop_udelay(unsigned int value, unsigned char *buf, signed int size) +{ + if (size < (FM_UDELAY_BASIC_OP_SIZE + 2)) { + WCN_DBG(FM_ERR | CHIP, "%s : left size(%d)/need size(%d)\n", + __func__, size, FM_UDELAY_BASIC_OP_SIZE + 2); + return -1; + } + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s :buf invalid pointer\n", __func__); + return -2; + } + + buf[0] = FM_UDELAY_BASIC_OP; + buf[1] = FM_UDELAY_BASIC_OP_SIZE; + buf[2] = (unsigned char) ((value) & 0x000000FF); + buf[3] = (unsigned char) ((value >> 8) & 0x000000FF); + buf[4] = (unsigned char) ((value >> 16) & 0x000000FF); + buf[5] = (unsigned char) ((value >> 24) & 0x000000FF); + + WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x %02x\n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); + + return FM_UDELAY_BASIC_OP_SIZE + 2; +} + +signed int fm_bop_rd_until(unsigned char addr, unsigned short mask, unsigned short value, + unsigned char *buf, signed int size) +{ + if (size < (FM_RD_UNTIL_BASIC_OP_SIZE + 2)) { + WCN_DBG(FM_ERR | CHIP, "%s : left size(%d)/need size(%d)\n", + __func__, size, FM_RD_UNTIL_BASIC_OP_SIZE + 2); + return -1; + } + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s :buf invalid pointer\n", __func__); + return -2; + } + + buf[0] = FM_RD_UNTIL_BASIC_OP; + buf[1] = FM_RD_UNTIL_BASIC_OP_SIZE; + buf[2] = addr; + buf[3] = (unsigned char) ((mask) & 0x00FF); + buf[4] = (unsigned char) ((mask >> 8) & 0x00FF); + buf[5] = (unsigned char) ((value) & 0x00FF); + buf[6] = (unsigned char) ((value >> 8) & 0x00FF); + + WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x %02x %02x\n", buf[0], buf[1], buf[2], + buf[3], buf[4], buf[5], buf[6]); + + return FM_RD_UNTIL_BASIC_OP_SIZE + 2; +} + +signed int fm_bop_modify(unsigned char addr, unsigned short mask_and, unsigned short mask_or, + unsigned char *buf, signed int size) +{ + if (size < (FM_MODIFY_BASIC_OP_SIZE + 2)) { + WCN_DBG(FM_ERR | CHIP, "%s : left size(%d)/need size(%d)\n", + __func__, size, FM_MODIFY_BASIC_OP_SIZE + 2); + return -1; + } + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s :buf invalid pointer\n", __func__); + return -2; + } + + buf[0] = FM_MODIFY_BASIC_OP; + buf[1] = FM_MODIFY_BASIC_OP_SIZE; + buf[2] = addr; + buf[3] = (unsigned char) ((mask_and) & 0x00FF); + buf[4] = (unsigned char) ((mask_and >> 8) & 0x00FF); + buf[5] = (unsigned char) ((mask_or) & 0x00FF); + buf[6] = (unsigned char) ((mask_or >> 8) & 0x00FF); + + WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x %02x %02x\n", buf[0], buf[1], buf[2], + buf[3], buf[4], buf[5], buf[6]); + + return FM_MODIFY_BASIC_OP_SIZE + 2; +} + +signed int fm_bop_top_write(unsigned short addr, unsigned int value, unsigned char *buf, signed int size) +{ + if (size < (FM_TOP_WRITE_BOP_SIZE + 2)) { + WCN_DBG(FM_ERR | CHIP, "%s : left size(%d)/need size(%d)\n", + __func__, size, FM_TOP_WRITE_BOP_SIZE + 2); + return -1; + } + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s :buf invalid pointer\n", __func__); + return -2; + } + + buf[0] = FM_WRITE_SPI_BASIC_OP; + buf[1] = FM_TOP_WRITE_BOP_SIZE; + buf[2] = top_index; + buf[3] = (unsigned char) ((addr) & 0x00FF); + buf[4] = (unsigned char) ((addr >> 8) & 0x00FF); + buf[5] = (unsigned char) ((value) & 0x00FF); + buf[6] = (unsigned char) ((value >> 8) & 0x00FF); + buf[7] = (unsigned char) ((value >> 16) & 0x00FF); + buf[8] = (unsigned char) ((value >> 24) & 0x00FF); + + WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x %02x %02x %02x %02x\n", buf[0], buf[1], + buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], buf[8]); + + return FM_TOP_WRITE_BOP_SIZE + 2; +} + +signed int fm_bop_top_rd_until(unsigned short addr, unsigned int mask, unsigned int value, + unsigned char *buf, signed int size) +{ + if (size < (FM_TOP_RD_UNTIL_BOP_SIZE + 2)) { + WCN_DBG(FM_ERR | CHIP, "%s : left size(%d)/need size(%d)\n", + __func__, size, FM_TOP_RD_UNTIL_BOP_SIZE + 2); + return -1; + } + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s :buf invalid pointer\n", __func__); + return -2; + } + + buf[0] = FM_RD_SPI_UNTIL_BASIC_OP; + buf[1] = FM_TOP_RD_UNTIL_BOP_SIZE; + buf[2] = top_index; + buf[3] = (unsigned char) ((addr) & 0x00FF); + buf[4] = (unsigned char) ((addr >> 8) & 0x00FF); + buf[5] = (unsigned char) ((mask) & 0x00FF); + buf[6] = (unsigned char) ((mask >> 8) & 0x00FF); + buf[7] = (unsigned char) ((mask >> 16) & 0x00FF); + buf[8] = (unsigned char) ((mask >> 24) & 0x00FF); + buf[9] = (unsigned char) ((value) & 0x00FF); + buf[10] = (unsigned char) ((value >> 8) & 0x00FF); + buf[11] = (unsigned char) ((value >> 16) & 0x00FF); + buf[12] = (unsigned char) ((value >> 24) & 0x00FF); + + WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", + buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], buf[8], buf[9], + buf[10], buf[11], buf[12]); + + return FM_TOP_RD_UNTIL_BOP_SIZE + 2; +} + +signed int fm_op_seq_combine_cmd(unsigned char *buf, unsigned char opcode, signed int pkt_size) +{ + signed int total_size = 0; + + if (buf == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s :buf invalid pointer\n", __func__); + return -1; + } + + buf[0] = FM_TASK_COMMAND_PKT_TYPE; + buf[1] = opcode; + buf[2] = (unsigned char) (pkt_size & 0x00FF); + buf[3] = (unsigned char) ((pkt_size >> 8) & 0x00FF); + WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x\n", buf[0], buf[1], buf[2], buf[3]); + + total_size = pkt_size + 4; + + return total_size; +} + +/* + * fm_patch_download - Wholechip FM Power Up: step 3, download patch to f/w, + * @buf - target buf + * @buf_size - buffer size + * @seg_num - total segments that this patch divided into + * @seg_id - No. of Segments: segment that will now be sent + * @src - patch source buffer + * @seg_len - segment size: segment that will now be sent + * return package size + */ +signed int fm_patch_download(unsigned char *buf, signed int buf_size, unsigned char seg_num, unsigned char seg_id, + const unsigned char *src, signed int seg_len) +{ + signed int pkt_size = 0; + unsigned char *dst = NULL; + + if (buf_size < TX_BUF_SIZE) + return -1; + + buf[0] = FM_TASK_COMMAND_PKT_TYPE; + buf[1] = FM_PATCH_DOWNLOAD_OPCODE; + pkt_size = 4; + + buf[pkt_size++] = seg_num; + buf[pkt_size++] = seg_id; + + if (seg_len > (buf_size - pkt_size)) + return -1; + + dst = &buf[pkt_size]; + pkt_size += seg_len; + + /* copy patch to tx buffer */ + while (seg_len--) { + *dst = *src; + src++; + dst++; + } + + buf[2] = (unsigned char) ((pkt_size - 4) & 0x00FF); + buf[3] = (unsigned char) (((pkt_size - 4) >> 8) & 0x00FF); + WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x %02x %02x\n", buf[0], buf[1], buf[2], + buf[3], buf[4], buf[5], buf[6]); + + return pkt_size; +} + +/* + * fm_coeff_download - Wholechip FM Power Up: step 3,download coeff to f/w, + * @buf - target buf + * @buf_size - buffer size + * @seg_num - total segments that this patch divided into + * @seg_id - No. of Segments: segment that will now be sent + * @src - patch source buffer + * @seg_len - segment size: segment that will now be sent + * return package size + */ +signed int fm_coeff_download(unsigned char *buf, signed int buf_size, unsigned char seg_num, unsigned char seg_id, + const unsigned char *src, signed int seg_len) +{ + signed int pkt_size = 0; + unsigned char *dst = NULL; + + if (buf_size < TX_BUF_SIZE) + return -1; + + buf[0] = FM_TASK_COMMAND_PKT_TYPE; + buf[1] = FM_COEFF_DOWNLOAD_OPCODE; + pkt_size = 4; + + buf[pkt_size++] = seg_num; + buf[pkt_size++] = seg_id; + + if (seg_len > (buf_size - pkt_size)) + return -1; + + dst = &buf[pkt_size]; + pkt_size += seg_len; + + /* copy patch to tx buffer */ + while (seg_len--) { + *dst = *src; + src++; + dst++; + } + + buf[2] = (unsigned char) ((pkt_size - 4) & 0x00FF); + buf[3] = (unsigned char) (((pkt_size - 4) >> 8) & 0x00FF); + WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x %02x %02x\n", buf[0], buf[1], buf[2], + buf[3], buf[4], buf[5], buf[6]); + + return pkt_size; +} + +/* + * fm_full_cqi_req - execute request cqi info action, + * @buf - target buf + * @buf_size - buffer size + * @freq - 7600 ~ 10800, freq array + * @cnt - channel count + * @type - request type, 1: a single channel; 2: multi channel; + * 3:multi channel with 100Khz step; 4: multi channel with 50Khz step + * + * return package size + */ +signed int fm_full_cqi_req(unsigned char *buf, signed int buf_size, unsigned short *freq, + signed int cnt, signed int type) +{ + signed int pkt_size = 0; + + if (buf_size < TX_BUF_SIZE) + return -1; + + buf[0] = FM_TASK_COMMAND_PKT_TYPE; + buf[1] = FM_SOFT_MUTE_TUNE_OPCODE; + pkt_size = 4; + + switch (type) { + case 1: + buf[pkt_size] = 0x0001; + pkt_size++; + buf[pkt_size] = (unsigned char) ((*freq) & 0x00FF); + pkt_size++; + buf[pkt_size] = (unsigned char) ((*freq >> 8) & 0x00FF); + pkt_size++; + break; + case 2: + buf[pkt_size] = 0x0002; + pkt_size++; + break; + case 3: + buf[pkt_size] = 0x0003; + pkt_size++; + break; + case 4: + buf[pkt_size] = 0x0004; + pkt_size++; + break; + default: + buf[pkt_size] = (unsigned short) type; + pkt_size++; + break; + } + + buf[2] = (unsigned char) ((pkt_size - 4) & 0x00FF); + buf[3] = (unsigned char) (((pkt_size - 4) >> 8) & 0x00FF); + + return pkt_size; +} + + +signed int fm_get_reg(unsigned char *buf, signed int buf_size, unsigned char addr) +{ + if (buf_size < TX_BUF_SIZE) + return -1; + + buf[0] = FM_TASK_COMMAND_PKT_TYPE; + buf[1] = FSPI_READ_OPCODE; + buf[2] = 0x01; + buf[3] = 0x00; + buf[4] = addr; + + WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x\n", buf[0], buf[1], buf[2], buf[3], buf[4]); + return 5; +} + +signed int fm_set_reg(unsigned char *buf, signed int buf_size, unsigned char addr, unsigned short value) +{ + if (buf_size < TX_BUF_SIZE) + return -1; + + buf[0] = FM_TASK_COMMAND_PKT_TYPE; + buf[1] = FSPI_WRITE_OPCODE; + buf[2] = 0x03; + buf[3] = 0x00; + buf[4] = addr; + buf[5] = (unsigned char) ((value) & 0x00FF); + buf[6] = (unsigned char) ((value >> 8) & 0x00FF); + + WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x %02x %02x\n", buf[0], buf[1], buf[2], + buf[3], buf[4], buf[5], buf[6]); + return 7; +} + +signed int fm_set_bits_reg(unsigned char *buf, signed int buf_size, unsigned char addr, + unsigned short bits, unsigned short mask) +{ + signed int pkt_size = 0; + + if (buf_size < TX_BUF_SIZE) + return -1; + + buf[0] = FM_TASK_COMMAND_PKT_TYPE; + buf[1] = 0x11; /* 0x11 this opcode won't be parsed as an opcode, so set here as spcial case. */ + pkt_size = 4; + pkt_size += fm_bop_modify(addr, mask, bits, &buf[pkt_size], buf_size - pkt_size); + + buf[2] = (unsigned char) ((pkt_size - 4) & 0x00FF); + buf[3] = (unsigned char) (((pkt_size - 4) >> 8) & 0x00FF); + + return pkt_size; +} + +/*top register read*/ +signed int fm_top_get_reg(unsigned char *buf, signed int buf_size, unsigned short addr) +{ + if (buf_size < TX_BUF_SIZE) + return -1; + + buf[0] = FM_TASK_COMMAND_PKT_TYPE; + buf[1] = CSPI_READ_OPCODE; + buf[2] = 0x03; + buf[3] = 0x00; + buf[4] = top_index; + buf[5] = (unsigned char) ((addr) & 0x00FF); + buf[6] = (unsigned char) ((addr >> 8) & 0x00FF); + + WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x %02x %02x\n", buf[0], buf[1], buf[2], + buf[3], buf[4], buf[5], buf[6]); + return 7; +} + +signed int fm_top_set_reg(unsigned char *buf, signed int buf_size, unsigned short addr, unsigned int value) +{ + if (buf_size < TX_BUF_SIZE) + return -1; + + buf[0] = FM_TASK_COMMAND_PKT_TYPE; + buf[1] = CSPI_WRITE_OPCODE; + buf[2] = 0x07; + buf[3] = 0x00; + buf[4] = top_index; + buf[5] = (unsigned char) ((addr) & 0x00FF); + buf[6] = (unsigned char) ((addr >> 8) & 0x00FF); + buf[7] = (unsigned char) ((value) & 0x00FF); + buf[8] = (unsigned char) ((value >> 8) & 0x00FF); + buf[9] = (unsigned char) ((value >> 16) & 0x00FF); + buf[10] = (unsigned char) ((value >> 24) & 0x00FF); + + WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", buf[0], + buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], buf[8], buf[9], buf[10]); + return 11; +} + +/*host register read*/ +signed int fm_host_get_reg(unsigned char *buf, signed int buf_size, unsigned int addr) +{ + if (buf_size < TX_BUF_SIZE) + return -1; + + buf[0] = FM_TASK_COMMAND_PKT_TYPE; + buf[1] = FM_HOST_READ_OPCODE; + buf[2] = 0x04; + buf[3] = 0x00; + buf[4] = (unsigned char) ((addr) & 0x00FF); + buf[5] = (unsigned char) ((addr >> 8) & 0x00FF); + buf[6] = (unsigned char) ((addr >> 16) & 0x00FF); + buf[7] = (unsigned char) ((addr >> 24) & 0x00FF); + + WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x %02x %02x %02x\n", buf[0], buf[1], buf[2], + buf[3], buf[4], buf[5], buf[6], buf[7]); + return 8; +} + +signed int fm_host_set_reg(unsigned char *buf, signed int buf_size, unsigned int addr, unsigned int value) +{ + if (buf_size < TX_BUF_SIZE) + return -1; + + buf[0] = FM_TASK_COMMAND_PKT_TYPE; + buf[1] = FM_HOST_WRITE_OPCODE; + buf[2] = 0x08; + buf[3] = 0x00; + buf[4] = (unsigned char) ((addr) & 0x00FF); + buf[5] = (unsigned char) ((addr >> 8) & 0x00FF); + buf[6] = (unsigned char) ((addr >> 16) & 0x00FF); + buf[7] = (unsigned char) ((addr >> 24) & 0x00FF); + buf[8] = (unsigned char) ((value) & 0x00FF); + buf[9] = (unsigned char) ((value >> 8) & 0x00FF); + buf[10] = (unsigned char) ((value >> 16) & 0x00FF); + buf[11] = (unsigned char) ((value >> 24) & 0x00FF); + + WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", + buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], buf[8], buf[9], buf[10], buf[11]); + return 12; +} + +signed int fm_pmic_get_reg(unsigned char *buf, signed int buf_size, unsigned char addr) +{ + if (buf_size < TX_BUF_SIZE) + return -1; + + if (buf == NULL) + return -2; + + buf[0] = FM_TASK_COMMAND_PKT_TYPE; + buf[1] = FM_READ_PMIC_CR_OPCODE; + buf[2] = 0x01; + buf[3] = 0x00; + buf[4] = addr; + + WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x\n", buf[0], buf[1], buf[2], + buf[3], buf[4]); + return 5; +} + +signed int fm_pmic_set_reg(unsigned char *buf, signed int buf_size, unsigned char addr, unsigned int val) +{ + if (buf_size < TX_BUF_SIZE) + return -1; + + if (buf == NULL) + return -2; + + buf[0] = FM_TASK_COMMAND_PKT_TYPE; + buf[1] = FM_WRITE_PMIC_CR_OPCODE; + buf[2] = 0x05; + buf[3] = 0x00; + buf[4] = addr; + buf[5] = (unsigned char) ((val) & 0x00FF); + buf[6] = (unsigned char) ((val >> 8) & 0x00FF); + buf[7] = (unsigned char) ((val >> 16) & 0x00FF); + buf[8] = (unsigned char) ((val >> 24) & 0x00FF); + + WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x %02x %02x %02x %02x\n", + buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], buf[8]); + return 9; +} + +signed int fm_pmic_mod_reg(unsigned char *buf, signed int buf_size, unsigned char addr, + unsigned int mask_and, unsigned int mask_or) +{ + if (buf_size < TX_BUF_SIZE) + return -1; + + if (buf == NULL) + return -2; + + buf[0] = FM_TASK_COMMAND_PKT_TYPE; + buf[1] = FM_MODIFY_PMIC_CR_OPCODE; + buf[2] = 0x09; + buf[3] = 0x00; + buf[4] = addr; + buf[5] = (unsigned char) ((mask_and) & 0x00FF); + buf[6] = (unsigned char) ((mask_and >> 8) & 0x00FF); + buf[7] = (unsigned char) ((mask_and >> 16) & 0x00FF); + buf[8] = (unsigned char) ((mask_and >> 24) & 0x00FF); + buf[9] = (unsigned char) ((mask_or) & 0x00FF); + buf[10] = (unsigned char) ((mask_or >> 8) & 0x00FF); + buf[11] = (unsigned char) ((mask_or >> 16) & 0x00FF); + buf[12] = (unsigned char) ((mask_or >> 24) & 0x00FF); + + WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", buf[0], + buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], buf[8], buf[9], buf[10], buf[11], buf[12]); + + return 13; +} + +signed int fm_get_patch_path(signed int ver, unsigned char *buff, int buffsize, struct fm_patch_tbl *patch_tbl) +{ + signed int i; + signed int patch_len = 0; + signed int max = FM_ROM_MAX; + const signed char *ppath = NULL; + + /* check if the ROM version is defined or not */ + for (i = 0; i < max; i++) { + if (patch_tbl[i].idx == ver) { + ppath = patch_tbl[i].patch; + WCN_DBG(FM_NTC | CHIP, "Get ROM version OK\n"); + break; + } + } + + if (ppath == NULL) { + /* Load latest default patch */ + for (i = max; i > 0; i--) { + patch_len = fm_file_read(patch_tbl[i - 1].patch, buff, buffsize, 0); + if (patch_len >= 0) { + WCN_DBG(FM_NTC | CHIP, "undefined ROM version, load %s\n", patch_tbl[i - 1].patch); + return patch_len; + } + } + } else { + /* Load patch */ + patch_len = fm_file_read(ppath, buff, buffsize, 0); + if (patch_len >= 0) + return patch_len; + } + + /* get path failed */ + WCN_DBG(FM_ERR | CHIP, "No valid patch file\n"); + return -FM_EPATCH; +} + +signed int fm_get_coeff_path(signed int ver, unsigned char *buff, int buffsize, struct fm_patch_tbl *patch_tbl) +{ + signed int i; + signed int patch_len = 0; + const signed char *ppath = NULL; + signed int max = FM_ROM_MAX; + + /* check if the ROM version is defined or not */ + for (i = 0; i < max; i++) { + if (patch_tbl[i].idx == ver) { + ppath = patch_tbl[i].coeff; + WCN_DBG(FM_NTC | CHIP, "Get ROM version OK\n"); + break; + } + } + + if (ppath == NULL) { + /* Load default patch */ + for (i = max; i > 0; i--) { + patch_len = fm_file_read(patch_tbl[i - 1].coeff, buff, buffsize, 0); + if (patch_len >= 0) { + WCN_DBG(FM_NTC | CHIP, "undefined ROM version, load %s\n", patch_tbl[i - 1].coeff); + return patch_len; + } + } + } else { + /* Load patch by patch path*/ + patch_len = fm_file_read(ppath, buff, buffsize, 0); + if (patch_len >= 0) + return patch_len; + } + + /* get path failed */ + WCN_DBG(FM_ERR | CHIP, "No valid coeff file\n"); + return -FM_EPATCH; +} + +/* +* DspPatch - DSP download procedure +* @img - source dsp bin code +* @len - patch length in byte +* @type - rom/patch/coefficient/hw_coefficient +*/ +signed int fm_download_patch(const unsigned char *img, signed int len, enum IMG_TYPE type) +{ + unsigned char seg_num; + unsigned char seg_id = 0; + signed int seg_len; + signed int ret = 0; + unsigned short pkt_size; + + if (img == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + if (len <= 0) + return -1; + + seg_num = len / PATCH_SEG_LEN + 1; + WCN_DBG(FM_NTC | CHIP, "binary len:%d, seg num:%d\n", len, seg_num); + + switch (type) { + case IMG_PATCH: + + for (seg_id = 0; seg_id < seg_num; seg_id++) { + seg_len = ((seg_id + 1) < seg_num) ? PATCH_SEG_LEN : (len % PATCH_SEG_LEN); + WCN_DBG(FM_INF | CHIP, "patch,[seg_id:%d], [seg_len:%d]\n", seg_id, seg_len); + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = + fm_patch_download(cmd_buf, TX_BUF_SIZE, seg_num, seg_id, + &img[seg_id * PATCH_SEG_LEN], seg_len); + WCN_DBG(FM_INF | CHIP, "pkt_size:%d\n", (signed int) pkt_size); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_PATCH, SW_RETRY_CNT, PATCH_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + + if (ret) { + WCN_DBG(FM_ERR | CHIP, "fm_patch_download failed\n"); + return ret; + } + } + + break; + + case IMG_COEFFICIENT: + + for (seg_id = 0; seg_id < seg_num; seg_id++) { + seg_len = ((seg_id + 1) < seg_num) ? PATCH_SEG_LEN : (len % PATCH_SEG_LEN); + WCN_DBG(FM_INF | CHIP, "coeff,[seg_id:%d], [seg_len:%d]\n", seg_id, seg_len); + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = + fm_coeff_download(cmd_buf, TX_BUF_SIZE, seg_num, seg_id, + &img[seg_id * PATCH_SEG_LEN], seg_len); + WCN_DBG(FM_INF | CHIP, "pkt_size:%d\n", (signed int) pkt_size); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_COEFF, SW_RETRY_CNT, COEFF_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + + if (ret) { + WCN_DBG(FM_ERR | CHIP, "fm_coeff_download failed\n"); + return ret; + } + } + + break; + default: + break; + } + + return 0; +} + +signed int fm_get_read_result(struct fm_res_ctx *result) +{ + if (result == NULL) { + WCN_DBG(FM_ERR | CHIP, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + fm_res = result; + + return 0; +} + +signed int fm_reg_read(unsigned char addr, unsigned short *val) +{ + signed int ret = 0; + unsigned short pkt_size; + + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = fm_get_reg(cmd_buf, TX_BUF_SIZE, addr); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_FSPI_RD, SW_RETRY_CNT, FSPI_RD_TIMEOUT, fm_get_read_result); + + if (!ret && fm_res) + *val = fm_res->fspi_rd; + + FM_UNLOCK(cmd_buf_lock); + + return ret; +} + +signed int fm_reg_write(unsigned char addr, unsigned short val) +{ + signed int ret = 0; + unsigned short pkt_size; + + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = fm_set_reg(cmd_buf, TX_BUF_SIZE, addr, val); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_FSPI_WR, SW_RETRY_CNT, FSPI_WR_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + + return ret; +} + +signed int fm_set_bits(unsigned char addr, unsigned short bits, unsigned short mask) +{ + signed int ret = 0; + unsigned short pkt_size; + + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = fm_set_bits_reg(cmd_buf, TX_BUF_SIZE, addr, bits, mask); + ret = fm_cmd_tx(cmd_buf, pkt_size, (1 << 0x11), SW_RETRY_CNT, FSPI_WR_TIMEOUT, NULL); + /* 0x11 this opcode won't be parsed as an opcode, so set here as spcial case. */ + FM_UNLOCK(cmd_buf_lock); + + return ret; +} + +signed int fm_top_reg_read(unsigned short addr, unsigned int *val) +{ + signed int ret = 0; + unsigned short pkt_size; + + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = fm_top_get_reg(cmd_buf, TX_BUF_SIZE, addr); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_CSPI_READ, SW_RETRY_CNT, FSPI_RD_TIMEOUT, fm_get_read_result); + + if (!ret && fm_res) + *val = fm_res->cspi_rd; + + FM_UNLOCK(cmd_buf_lock); + + return ret; +} + +signed int fm_top_reg_write(unsigned short addr, unsigned int val) +{ + signed int ret = 0; + unsigned short pkt_size; + + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = fm_top_set_reg(cmd_buf, TX_BUF_SIZE, addr, val); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_CSPI_WRITE, SW_RETRY_CNT, FSPI_WR_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + + return ret; +} + +signed int fm_host_reg_read(unsigned int addr, unsigned int *val) +{ + signed int ret = 0; + unsigned short pkt_size; + + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = fm_host_get_reg(cmd_buf, TX_BUF_SIZE, addr); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_HOST_READ, SW_RETRY_CNT, FSPI_RD_TIMEOUT, fm_get_read_result); + + if (!ret && fm_res) + *val = fm_res->cspi_rd; + + FM_UNLOCK(cmd_buf_lock); + + return ret; +} + +signed int fm_host_reg_write(unsigned int addr, unsigned int val) +{ + signed int ret = 0; + unsigned short pkt_size; + + if (FM_LOCK(cmd_buf_lock)) + return -FM_ELOCK; + pkt_size = fm_host_set_reg(cmd_buf, TX_BUF_SIZE, addr, val); + ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_HOST_WRITE, SW_RETRY_CNT, FSPI_WR_TIMEOUT, NULL); + FM_UNLOCK(cmd_buf_lock); + + return ret; +} diff --git a/drivers/misc/mediatek/connectivity/fmradio/core/fm_config.c b/drivers/misc/mediatek/connectivity/fmradio/core/fm_config.c new file mode 100644 index 0000000000000000000000000000000000000000..deebbcb1eb9d394ee033f57fea14ead33ce283a5 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/core/fm_config.c @@ -0,0 +1,625 @@ +/* + * Copyright (C) 2015 MediaTek Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 +#include + +#include "fm_typedef.h" +#include "fm_rds.h" +#include "fm_dbg.h" +#include "fm_err.h" +#include "fm_stdlib.h" +#include "fm_patch.h" +#include "fm_config.h" + +struct fm_cust_cfg fm_config; +unsigned short g_fm_chipid; +enum fm_cfg_chip_type g_fm_chip_type = FM_CHIP_TYPE_MAX; + +#define FM_CUST_CFG_PATH "fm_cust.cfg" + +signed int to_upper_n(signed char *str, signed int len) +{ + signed int i = 0; + + for (i = 0; i < len; i++) { + if (('a' <= str[i]) && (str[i] <= 'z')) + str[i] = str[i] - ('a' - 'A'); + } + + return 0; +} + +signed int check_hex_str(signed char *str, signed int len) +{ + signed int i = 0; + + for (i = 0; i < len; i++) { + if ((('a' <= str[i]) && (str[i] <= 'z')) || (('A' <= str[i]) && (str[i] <= 'Z')) + || (('0' <= str[i]) && (str[i] <= '9'))) { + ; + } else { + return -1; + } + } + + return 0; +} + +signed int check_dec_str(signed char *str, signed int len) +{ + signed int i = 0; + + for (i = 0; i < len; i++) { + if (('0' <= str[i]) && (str[i] <= '9')) + ; + else + return -1; + } + + return 0; +} + +signed int ascii_to_hex(signed char *in_ascii, unsigned short *out_hex) +{ + signed int len = (signed int) strlen(in_ascii); + int i = 0; + unsigned short tmp; + + len = (len > 4) ? 4 : len; + + if (check_hex_str(in_ascii, len)) + return -1; + + to_upper_n(in_ascii, len); + *out_hex = 0; + + for (i = 0; i < len; i++) { + if (in_ascii[len - i - 1] < 'A') { + tmp = in_ascii[len - i - 1]; + *out_hex |= ((tmp - '0') << (4 * i)); + } else { + tmp = in_ascii[len - i - 1]; + *out_hex |= ((tmp - 'A' + 10) << (4 * i)); + } + } + + return 0; +} + +signed int ascii_to_dec(signed char *in_ascii, signed int *out_dec) +{ + signed int len = (signed int) strlen(in_ascii); + int i = 0; + int flag; + int multi = 1; + + len = (len > 10) ? 10 : len; + + if (in_ascii[0] == '-') { + flag = -1; + in_ascii += 1; + len -= 1; + } else { + flag = 1; + } + + if (check_dec_str(in_ascii, len)) + return -1; + + *out_dec = 0; + multi = 1; + + for (i = 0; i < len; i++) { + *out_dec += ((in_ascii[len - i - 1] - '0') * multi); + multi *= 10; + } + + *out_dec *= flag; + return 0; +} + +signed int trim_string(signed char **start) +{ + signed char *end = *start; + + /* Advance to non-space character */ + while (*(*start) == ' ') + (*start)++; + + /* Move to end of string */ + while (*end != '\0') + (end)++; + + /* Backup to non-space character */ + do { + end--; + } while ((end >= *start) && (*end == ' ')); + + /* Terminate string after last non-space character */ + *(++end) = '\0'; + return end - *start; +} + +signed int trim_path(signed char **start) +{ + signed char *end = *start; + + while (*(*start) == ' ') + (*start)++; + + while (*end != '\0') + (end)++; + + do { + end--; + } while ((end >= *start) && ((*end == ' ') || (*end == '\n') || (*end == '\r'))); + + *(++end) = '\0'; + return end - *start; +} + +signed int check_path(signed char *str, signed int len) +{ + signed int i = 0; + + for (i = 0; i < len; i++) { + if ((('a' <= str[i]) && (str[i] <= 'z')) || + (('A' <= str[i]) && (str[i] <= 'Z')) || + (('0' <= str[i]) && (str[i] <= '9')) || + ('/' == str[i]) || ('_' == str[i]) || + ('.' == str[i])) { + ; + } else { + return -1; + } + } + return 0; +} + +signed int cfg_parser(signed char *buffer, CFG_HANDLER handler, struct fm_cust_cfg *cfg) +{ + signed int ret = 0; + signed char *p = buffer; + signed char *group_start = NULL; + signed char *key_start = NULL; + signed char *value_start = NULL; + + enum fm_cfg_parser_state state = FM_CFG_STAT_NONE; + + if (p == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + for (p = buffer; *p != '\0'; p++) { + switch (state) { + case FM_CFG_STAT_NONE:{ + if (*p == '[') { + /* if we get char '[' in none state, it means a new group name start */ + state = FM_CFG_STAT_GROUP; + group_start = p + 1; + } else if (*p == COMMENT_CHAR) { + /* if we get char '#' in none state, it means a new comment start */ + state = FM_CFG_STAT_COMMENT; + } else if (!isspace(*p) && (*p != '\n') && (*p != '\r')) { + /* if we get an nonspace char in none state, it means a new key start */ + state = FM_CFG_STAT_KEY; + key_start = p; + } + + break; + } + case FM_CFG_STAT_GROUP:{ + if (*p == ']') { + /* if we get char ']' in group state, it means a group name complete */ + *p = '\0'; + /* FIX_ME */ + /* record group name */ + state = FM_CFG_STAT_NONE; + trim_string(&group_start); + /* WCN_DBG(FM_NTC|MAIN, "g=%s\n", group_start); */ + } + + break; + } + case FM_CFG_STAT_COMMENT:{ + if (*p == '\n') { + /* if we get char '\n' in comment state, it means new line start */ + state = FM_CFG_STAT_NONE; + group_start = p + 1; + } + + break; + } + case FM_CFG_STAT_KEY:{ + if (*p == DELIMIT_CHAR) { + /* if we get char '=' in key state, it means a key name complete */ + *p = '\0'; + /* FIX_ME */ + /* record key name */ + state = FM_CFG_STAT_VALUE; + value_start = p + 1; + trim_string(&key_start); + /* WCN_DBG(FM_NTC|MAIN, "k=%s\n", key_start); */ + } + + break; + } + case FM_CFG_STAT_VALUE:{ + if (*p == '\n' || *p == '\r') { + /* if we get char '\n' or '\r' in value state, it means a value complete */ + *p = '\0'; + /* record value */ + trim_string(&value_start); + /* WCN_DBG(FM_NTC|MAIN, "v=%s\n", value_start); */ + + if (handler) + ret = handler(group_start, key_start, value_start, cfg); + + state = FM_CFG_STAT_NONE; + } + + break; + } + default: + break; + } + } + + return ret; +} + +signed int cfg_item_match(signed char *src_key, signed char *src_val, signed char *dst_key, signed int *dst_val) +{ + signed int ret = 0; + unsigned short tmp_hex; + signed int tmp_dec; + + /* WCN_DBG(FM_NTC|MAIN,"src_key=%s,src_val=%s\n", src_key,src_val); */ + /* WCN_DBG(FM_NTC|MAIN,"dst_key=%s\n", dst_key); */ + if (strcmp(src_key, dst_key) == 0) { + if (strncmp(src_val, "0x", strlen("0x")) == 0) { + src_val += strlen("0x"); + /* WCN_DBG(FM_NTC|MAIN,"%s\n", src_val); */ + ret = ascii_to_hex(src_val, &tmp_hex); + + if (!ret) { + *dst_val = tmp_hex; + /* WCN_DBG(FM_NTC|MAIN, "%s 0x%04x\n", dst_key, tmp_hex); */ + return 0; + } + /* WCN_DBG(FM_ERR | MAIN, "%s format error\n", dst_key); */ + return 1; + } + + ret = ascii_to_dec(src_val, &tmp_dec); + + if (!ret /*&& ((0 <= tmp_dec) && (tmp_dec <= 0xFFFF)) */) { + *dst_val = tmp_dec; + /* WCN_DBG(FM_NTC|MAIN, "%s %d\n", dst_key, tmp_dec); */ + return 0; + } + /* WCN_DBG(FM_ERR | MAIN, "%s format error\n", dst_key); */ + return 1; + } + /* else */ + /* { */ + /* WCN_DBG(FM_ERR | MAIN, "src_key!=dst_key\n"); */ + /* } */ + + return -1; +} + +static signed int cfg_item_handler(signed char *grp, signed char *key, signed char *val, struct fm_cust_cfg *cfg) +{ + signed int ret = 0; + struct fm_rx_cust_cfg *rx_cfg = &cfg->rx_cfg; + struct fm_tx_cust_cfg *tx_cfg = &cfg->tx_cfg; + + + ret = cfg_item_match(key, val, "FM_RX_RSSI_TH_LONG", &rx_cfg->long_ana_rssi_th); + if (ret >= 0) + return ret; + + ret = cfg_item_match(key, val, "FM_RX_RSSI_TH_SHORT", &rx_cfg->short_ana_rssi_th); + if (ret >= 0) + return ret; + + ret = cfg_item_match(key, val, "FM_RX_DESENSE_RSSI", &rx_cfg->desene_rssi_th); + if (ret >= 0) + return ret; + + ret = cfg_item_match(key, val, "FM_RX_SMG_TH", &rx_cfg->smg_th); + if (ret >= 0) + return ret; + + ret = cfg_item_match(key, val, "FM_RX_DEEMPHASIS", &rx_cfg->deemphasis); + if (ret >= 0) + return ret; + + ret = cfg_item_match(key, val, "FM_RX_OSC_FREQ", &rx_cfg->osc_freq); + if (ret >= 0) + return ret; + + ret = cfg_item_match(key, val, "FM_RX_PAMD_TH", &rx_cfg->pamd_th); + if (ret >= 0) + return ret; + + ret = cfg_item_match(key, val, "FM_RX_MR_TH", &rx_cfg->mr_th); + if (ret >= 0) + return ret; + + ret = cfg_item_match(key, val, "FM_RX_ATDC_TH", &rx_cfg->atdc_th); + if (ret >= 0) + return ret; + + ret = cfg_item_match(key, val, "FM_RX_PRX_TH", &rx_cfg->prx_th); + if (ret >= 0) + return ret; + + ret = cfg_item_match(key, val, "FM_TX_PAMD_TH", &tx_cfg->pamd_th); + if (ret >= 0) + return ret; + + ret = cfg_item_match(key, val, "FM_TX_MR_TH", &tx_cfg->mr_th); + if (ret >= 0) + return ret; + + ret = cfg_item_match(key, val, "FM_TX_SMG_TH", &tx_cfg->smg_th); + if (ret >= 0) + return ret; + + + WCN_DBG(FM_WAR | MAIN, "invalid key\n"); + return -1; +} + +static signed int fm_cust_config_default(struct fm_cust_cfg *cfg) +{ + if (cfg == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + /*RX Threshold config*/ + cfg->rx_cfg.long_ana_rssi_th = FM_RX_RSSI_TH_LONG; + cfg->rx_cfg.short_ana_rssi_th = FM_RX_RSSI_TH_SHORT; + cfg->rx_cfg.desene_rssi_th = FM_RX_DESENSE_RSSI; + cfg->rx_cfg.pamd_th = FM_RX_PAMD_TH; + cfg->rx_cfg.mr_th = FM_RX_MR_TH; + cfg->rx_cfg.atdc_th = FM_RX_ATDC_TH; + cfg->rx_cfg.prx_th = FM_RX_PRX_TH; + cfg->rx_cfg.smg_th = FM_RX_SMG_TH; + cfg->rx_cfg.deemphasis = FM_RX_DEEMPHASIS; + cfg->rx_cfg.osc_freq = FM_RX_OSC_FREQ; + + /*TX Threshold config*/ + cfg->tx_cfg.pamd_th = FM_TX_PAMD_TH; + cfg->tx_cfg.mr_th = FM_TX_MR_TH; + cfg->tx_cfg.smg_th = FM_TX_SMG_TH; + + /*Audio path config*/ + if (g_fm_chip_type == FM_COMBO_CHIP) { + /* combo chip config MT6630,MT6632 */ +#ifdef CONFIG_MTK_MERGE_INTERFACE_SUPPORT + cfg->aud_cfg.aud_path = FM_AUD_MRGIF; + cfg->aud_cfg.i2s_info.status = FM_I2S_OFF; + cfg->aud_cfg.i2s_info.mode = FM_I2S_SLAVE; + if (g_fm_chipid == 0x6632) + cfg->aud_cfg.i2s_info.rate = FM_I2S_48K; + else + cfg->aud_cfg.i2s_info.rate = FM_I2S_44K; + cfg->aud_cfg.i2s_pad = FM_I2S_PAD_IO; +#elif defined FM_DIGITAL_INPUT + cfg->aud_cfg.aud_path = FM_AUD_I2S; + cfg->aud_cfg.i2s_info.status = FM_I2S_OFF; + cfg->aud_cfg.i2s_info.mode = FM_I2S_SLAVE; + if (g_fm_chipid == 0x6632) + cfg->aud_cfg.i2s_info.rate = FM_I2S_48K; + else + cfg->aud_cfg.i2s_info.rate = FM_I2S_44K; + cfg->aud_cfg.i2s_pad = FM_I2S_PAD_IO; +#elif defined FM_ANALOG_INPUT + cfg->aud_cfg.aud_path = FM_AUD_ANALOG; + cfg->aud_cfg.i2s_info.status = FM_I2S_STATE_ERR; + cfg->aud_cfg.i2s_info.mode = FM_I2S_MODE_ERR; + cfg->aud_cfg.i2s_info.rate = FM_I2S_SR_ERR; + cfg->aud_cfg.i2s_pad = FM_I2S_PAD_ERR; +#else + cfg->aud_cfg.aud_path = FM_AUD_ERR; + cfg->aud_cfg.i2s_info.status = FM_I2S_STATE_ERR; + cfg->aud_cfg.i2s_info.mode = FM_I2S_MODE_ERR; + cfg->aud_cfg.i2s_info.rate = FM_I2S_SR_ERR; + cfg->aud_cfg.i2s_pad = FM_I2S_PAD_ERR; +#endif + } else if ((g_fm_chip_type == FM_AD_DIE_CHIP) || (g_fm_chip_type == FM_SOC_CHIP)) { + /* MT6627 MT6580 MT6631 ?*/ + cfg->aud_cfg.aud_path = FM_AUD_I2S; + cfg->aud_cfg.i2s_info.status = FM_I2S_OFF; + cfg->aud_cfg.i2s_info.mode = FM_I2S_MASTER; + cfg->aud_cfg.i2s_info.rate = FM_I2S_32K; + cfg->aud_cfg.i2s_pad = FM_I2S_PAD_CONN; + } else { + WCN_DBG(FM_ALT | MAIN, "Invalid chip type %d\n", g_fm_chip_type); + cfg->aud_cfg.aud_path = FM_AUD_ERR; + cfg->aud_cfg.i2s_info.status = FM_I2S_STATE_ERR; + cfg->aud_cfg.i2s_info.mode = FM_I2S_MODE_ERR; + cfg->aud_cfg.i2s_info.rate = FM_I2S_SR_ERR; + cfg->aud_cfg.i2s_pad = FM_I2S_PAD_ERR; + } + return 0; +} + +static signed int fm_cust_config_file(const signed char *filename, struct fm_cust_cfg *cfg) +{ + signed int ret = 0; + signed char *buf = NULL; + signed int file_len = 0; + + buf = fm_zalloc(4096); + if (!buf) { + WCN_DBG(FM_ALT | MAIN, "-ENOMEM\n"); + return -ENOMEM; + } + + file_len = fm_file_read(filename, buf, 4096, 0); + + if (file_len <= 0) { + WCN_DBG(FM_ALT | MAIN, "fail to read config file = %s\n", filename); + ret = -1; + goto out; + } + + ret = cfg_parser(buf, cfg_item_handler, cfg); + +out: + if (buf) + fm_free(buf); + + return ret; +} + +static signed int fm_cust_config_print(struct fm_cust_cfg *cfg) +{ + WCN_DBG(FM_NTC | MAIN, "0x%x configs:\n", g_fm_chipid); + WCN_DBG(FM_NTC | MAIN, "RX->rssi_l:\t%d\n", cfg->rx_cfg.long_ana_rssi_th); + WCN_DBG(FM_NTC | MAIN, "RX->rssi_s:\t%d\n", cfg->rx_cfg.short_ana_rssi_th); + WCN_DBG(FM_NTC | MAIN, "RX->pamd_th:\t%d\n", cfg->rx_cfg.pamd_th); + WCN_DBG(FM_NTC | MAIN, "RX->mr_th:\t%d\n", cfg->rx_cfg.mr_th); + WCN_DBG(FM_NTC | MAIN, "RX->atdc_th:\t%d\n", cfg->rx_cfg.atdc_th); + WCN_DBG(FM_NTC | MAIN, "RX->prx_th:\t%d\n", cfg->rx_cfg.prx_th); + WCN_DBG(FM_NTC | MAIN, "RX->smg_th:\t%d\n", cfg->rx_cfg.smg_th); + WCN_DBG(FM_NTC | MAIN, "RX->de_emphasis:\t%d\n", cfg->rx_cfg.deemphasis); + WCN_DBG(FM_NTC | MAIN, "RX->osc_freq:\t%d\n", cfg->rx_cfg.osc_freq); + WCN_DBG(FM_NTC | MAIN, "RX->desense_rssi_th:\t%d\n", cfg->rx_cfg.desene_rssi_th); + + WCN_DBG(FM_NTC | MAIN, "TX->scan_hole_low:\t%d\n", cfg->tx_cfg.scan_hole_low); + WCN_DBG(FM_NTC | MAIN, "TX->scan_hole_high:\t%d\n", cfg->tx_cfg.scan_hole_high); + WCN_DBG(FM_NTC | MAIN, "TX->power_level:\t%d\n", cfg->tx_cfg.power_level); + + WCN_DBG(FM_NTC | MAIN, "aud path[%d]I2S state[%d]mode[%d]rate[%d]pad[%d]\n", + cfg->aud_cfg.aud_path, + cfg->aud_cfg.i2s_info.status, + cfg->aud_cfg.i2s_info.mode, + cfg->aud_cfg.i2s_info.rate, + cfg->aud_cfg.i2s_pad); + return 0; +} + +signed int fm_cust_config_setup(const signed char *filepath) +{ + signed int ret = 0; + signed char *filep = NULL; + signed char file_path[51] = { 0 }; + + fm_cust_config_default(&fm_config); + WCN_DBG(FM_NTC | MAIN, "FM default config\n"); + fm_cust_config_print(&fm_config); + + if (!filepath) { + filep = FM_CUST_CFG_PATH; + } else { + memcpy(file_path, filepath, (strlen(filepath) > 50) ? 50 : strlen(filepath)); + filep = file_path; + file_path[50] = '\0'; + trim_path(&filep); + } + + if (check_path(filep, strlen(filep)) != 0) { + WCN_DBG(FM_ALT | MAIN, + "Invalid config file: %s\n", filep); + return -FM_EPATCH; + } + + ret = fm_cust_config_file(filep, &fm_config); + WCN_DBG(FM_NTC | MAIN, "FM cust config\n"); + fm_cust_config_print(&fm_config); + return ret; +} + +unsigned short fm_cust_config_fetch(enum fm_cust_cfg_op op_code) +{ + unsigned short tmp = 0; + + switch (op_code) { + /* For FM RX */ + case FM_CFG_RX_RSSI_TH_LONG: + tmp = fm_config.rx_cfg.long_ana_rssi_th; + break; + case FM_CFG_RX_RSSI_TH_SHORT: + tmp = fm_config.rx_cfg.short_ana_rssi_th; + break; + case FM_CFG_RX_DESENSE_RSSI_TH: + tmp = fm_config.rx_cfg.desene_rssi_th; + break; + case FM_CFG_RX_PAMD_TH: + tmp = fm_config.rx_cfg.pamd_th; + break; + case FM_CFG_RX_MR_TH: + tmp = fm_config.rx_cfg.mr_th; + break; + case FM_CFG_RX_ATDC_TH: + tmp = fm_config.rx_cfg.atdc_th; + break; + case FM_CFG_RX_PRX_TH: + tmp = fm_config.rx_cfg.prx_th; + break; + case FM_CFG_RX_ATDEV_TH: + tmp = fm_config.rx_cfg.atdev_th; + break; + case FM_CFG_RX_CQI_TH: + tmp = fm_config.rx_cfg.cqi_th; + break; + case FM_CFG_RX_SMG_TH: + tmp = fm_config.rx_cfg.smg_th; + break; + case FM_CFG_RX_DEEMPHASIS: + tmp = fm_config.rx_cfg.deemphasis; + break; + case FM_CFG_RX_OSC_FREQ: + tmp = fm_config.rx_cfg.osc_freq; + break; + + case FM_CFG_TX_SCAN_HOLE_LOW: + tmp = fm_config.tx_cfg.scan_hole_low; + break; + case FM_CFG_TX_SCAN_HOLE_HIGH: + tmp = fm_config.tx_cfg.scan_hole_high; + break; + case FM_CFG_TX_PWR_LEVEL: + tmp = fm_config.tx_cfg.power_level; + break; + case FM_CFG_TX_PAMD_TH: + tmp = fm_config.tx_cfg.pamd_th; + break; + case FM_CFG_TX_DEEMPHASIS: + tmp = fm_config.tx_cfg.mr_th; + break; + case FM_CFG_TX_SMG_TH: + tmp = fm_config.tx_cfg.smg_th; + break; + default: + break; + } + + WCN_DBG(FM_DBG | MAIN, "cust cfg %d: 0x%04x\n", op_code, tmp); + return tmp; +} +unsigned short fm_cust_config_chip(unsigned short chipid, enum fm_cfg_chip_type type) +{ + g_fm_chipid = chipid; + g_fm_chip_type = type; + + return 0; +} diff --git a/drivers/misc/mediatek/connectivity/fmradio/core/fm_eint.c b/drivers/misc/mediatek/connectivity/fmradio/core/fm_eint.c new file mode 100644 index 0000000000000000000000000000000000000000..066ee1aae3f1a2742cf5b5076d7779be5d3d71ea --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/core/fm_eint.c @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2015 MediaTek Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 "fm_typedef.h" +#include "fm_dbg.h" +#include "fm_err.h" +#include "fm_eint.h" +#include "fm_reg_utils.h" + +signed int fm_enable_eint(void) +{ + struct fm_ext_interface *ei = &fm_wcn_ops.ei; + + if (ei->enable_eint) + ei->enable_eint(); + + return 0; +} + +signed int fm_disable_eint(void) +{ + struct fm_ext_interface *ei = &fm_wcn_ops.ei; + + if (ei->disable_eint) + ei->disable_eint(); + + return 0; +} + +signed int fm_request_eint(void (*parser) (void)) +{ + struct fm_ext_interface *ei = &fm_wcn_ops.ei; + + if (ei->stp_register_event_cb) + ei->stp_register_event_cb(parser); + + return 0; +} + +signed int fm_eint_pin_cfg(signed int mode) +{ + return 0; +} + diff --git a/drivers/misc/mediatek/connectivity/fmradio/core/fm_link.c b/drivers/misc/mediatek/connectivity/fmradio/core/fm_link.c new file mode 100644 index 0000000000000000000000000000000000000000..d91359ed37516abfb19e19e2bbea416afbf3109d --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/core/fm_link.c @@ -0,0 +1,570 @@ +/* + * Copyright (C) 2015 MediaTek Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 +#include +#include + +#include "fm_typedef.h" +#include "fm_dbg.h" +#include "fm_err.h" +#include "fm_stdlib.h" +#include "fm_link.h" +#include "fm_reg_utils.h" + +static struct fm_link_event *link_event; + +static struct fm_trace_fifo_t *cmd_fifo; + +static struct fm_trace_fifo_t *evt_fifo; + +signed int fm_link_setup(void *data) +{ + signed int ret = 0; + + link_event = fm_zalloc(sizeof(struct fm_link_event)); + if (!link_event) { + WCN_DBG(FM_ALT | LINK, "fm_zalloc(fm_link_event) -ENOMEM\n"); + return -1; + } + + link_event->ln_event = fm_flag_event_create("ln_evt"); + + if (!link_event->ln_event) { + WCN_DBG(FM_ALT | LINK, "create mt6620_ln_event failed\n"); + fm_free(link_event); + return -1; + } + + fm_flag_event_get(link_event->ln_event); + + WCN_DBG(FM_NTC | LINK, "fm link setup\n"); + + cmd_fifo = fm_trace_fifo_create("cmd_fifo"); + if (!cmd_fifo) { + WCN_DBG(FM_ALT | LINK, "create cmd_fifo failed\n"); + ret = -1; + goto failed; + } + + evt_fifo = fm_trace_fifo_create("evt_fifo"); + if (!evt_fifo) { + WCN_DBG(FM_ALT | LINK, "create evt_fifo failed\n"); + ret = -1; + goto failed; + } + + if (fm_wcn_ops.ei.wmt_msgcb_reg) + fm_wcn_ops.ei.wmt_msgcb_reg(data); + + return 0; + +failed: + fm_trace_fifo_release(evt_fifo); + fm_trace_fifo_release(cmd_fifo); + if (link_event) { + fm_flag_event_put(link_event->ln_event); + fm_free(link_event); + } + + return ret; +} + +signed int fm_link_release(void) +{ + + fm_trace_fifo_release(evt_fifo); + fm_trace_fifo_release(cmd_fifo); + if (link_event) { + fm_flag_event_put(link_event->ln_event); + fm_free(link_event); + } + WCN_DBG(FM_NTC | LINK, "fm link release\n"); + return 0; +} + +/* + * fm_ctrl_rx + * the low level func to read a rigister + * @addr - rigister address + * @val - the pointer of target buf + * If success, return 0; else error code + */ +signed int fm_ctrl_rx(unsigned char addr, unsigned short *val) +{ + return 0; +} + +/* + * fm_ctrl_tx + * the low level func to write a rigister + * @addr - rigister address + * @val - value will be writed in the rigister + * If success, return 0; else error code + */ +signed int fm_ctrl_tx(unsigned char addr, unsigned short val) +{ + return 0; +} + +/* + * fm_cmd_tx() - send cmd to FM firmware and wait event + * @buf - send buffer + * @len - the length of cmd + * @mask - the event flag mask + * @ cnt - the retry conter + * @timeout - timeout per cmd + * Return 0, if success; error code, if failed + */ +signed int fm_cmd_tx(unsigned char *buf, unsigned short len, signed int mask, signed int cnt, signed int timeout, + signed int (*callback)(struct fm_res_ctx *result)) +{ + signed int ret_time = 0; + struct task_struct *task = current; + struct fm_trace_t trace; + + if ((buf == NULL) || (len < 0) || (mask == 0) + || (cnt > SW_RETRY_CNT_MAX) || (timeout > SW_WAIT_TIMEOUT_MAX)) { + WCN_DBG(FM_ERR | LINK, "cmd tx, invalid para\n"); + return -FM_EPARA; + } + + FM_EVENT_CLR(link_event->ln_event, mask); + +#ifdef FM_TRACE_ENABLE + trace.type = buf[0]; + trace.opcode = buf[1]; + trace.len = len - 4; + trace.tid = (signed int) task->pid; + fm_memset(trace.pkt, 0, FM_TRACE_PKT_SIZE); + fm_memcpy(trace.pkt, &buf[4], (trace.len > FM_TRACE_PKT_SIZE) ? FM_TRACE_PKT_SIZE : trace.len); +#endif + + +#ifdef FM_TRACE_ENABLE + if (true == FM_TRACE_FULL(cmd_fifo)) + FM_TRACE_OUT(cmd_fifo, NULL); + + FM_TRACE_IN(cmd_fifo, &trace); +#endif + + /* send cmd to FM firmware */ + if (fm_wcn_ops.ei.stp_send_data) + ret_time = fm_wcn_ops.ei.stp_send_data(buf, len); + if (ret_time <= 0) { + WCN_DBG(FM_EMG | LINK, "send data over stp failed[%d]\n", ret_time); + return -FM_ELINK; + } + /* wait the response form FM firmware */ + ret_time = FM_EVENT_WAIT_TIMEOUT(link_event->ln_event, mask, timeout); + + if (!ret_time) { + if (cnt-- > 0) { + WCN_DBG(FM_WAR | LINK, "wait event timeout, [retry_cnt=%d], pid=%d\n", cnt, task->pid); + fm_print_cmd_fifo(); + fm_print_evt_fifo(); + } else + WCN_DBG(FM_ALT | LINK, "fatal error, SW retry failed, reset HW\n"); + + return -FM_EFW; + } + + FM_EVENT_CLR(link_event->ln_event, mask); + + if (callback) + callback(&link_event->result); + + return 0; +} + +signed int fm_event_parser(signed int(*rds_parser) (struct rds_rx_t *, signed int)) +{ + signed int len; + signed int i = 0; + unsigned char opcode = 0; + unsigned short length = 0; + unsigned char ch; + unsigned char rx_buf[RX_BUF_SIZE + 10] = { 0 }; /* the 10 bytes are protect gaps */ + unsigned int rx_len = 0; + + static enum fm_task_parser_state state = FM_TASK_RX_PARSER_PKT_TYPE; + struct fm_trace_t trace; + struct task_struct *task = current; + + if (fm_wcn_ops.ei.stp_recv_data) + len = fm_wcn_ops.ei.stp_recv_data(rx_buf, RX_BUF_SIZE); + WCN_DBG_LIMITED(FM_DBG | LINK, "[len=%d],[CMD=0x%02x 0x%02x 0x%02x 0x%02x]\n", len, rx_buf[0], + rx_buf[1], rx_buf[2], rx_buf[3]); + + while (i < len) { + ch = rx_buf[i]; + + switch (state) { + case FM_TASK_RX_PARSER_PKT_TYPE: + + if (ch == FM_TASK_EVENT_PKT_TYPE) { + if ((i + 5) < RX_BUF_SIZE) { + if (i != 0) { + WCN_DBG(FM_DBG | LINK, + "0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", + rx_buf[i], rx_buf[i + 1], rx_buf[i + 2], + rx_buf[i + 3], rx_buf[i + 4], rx_buf[i + 5]); + } + } else { + WCN_DBG(FM_DBG | LINK, "0x%02x 0x%02x\n", rx_buf[i], rx_buf[i + 1]); + } + + state = FM_TASK_RX_PARSER_OPCODE; + } else { + WCN_DBG(FM_ALT | LINK, "event pkt type error (rx_buf[%d] = 0x%02x)\n", i, ch); + } + + i++; + break; + + case FM_TASK_RX_PARSER_OPCODE: + i++; + opcode = ch; + state = FM_TASK_RX_PARSER_PKT_LEN_1; + break; + + case FM_TASK_RX_PARSER_PKT_LEN_1: + i++; + length = ch; + state = FM_TASK_RX_PARSER_PKT_LEN_2; + break; + + case FM_TASK_RX_PARSER_PKT_LEN_2: + i++; + length |= (unsigned short) (ch << 0x8); + +#ifdef FM_TRACE_ENABLE + trace.type = FM_TASK_EVENT_PKT_TYPE; + trace.opcode = opcode; + trace.len = length; + trace.tid = (signed int) task->pid; + fm_memset(trace.pkt, 0, FM_TRACE_PKT_SIZE); + rx_len = (length > FM_TRACE_PKT_SIZE) ? FM_TRACE_PKT_SIZE : length; + rx_len = (rx_len > (sizeof(rx_buf) - i)) ? sizeof(rx_buf) - i : rx_len; + fm_memcpy(trace.pkt, &rx_buf[i], rx_len); + + if (true == FM_TRACE_FULL(evt_fifo)) + FM_TRACE_OUT(evt_fifo, NULL); + + FM_TRACE_IN(evt_fifo, &trace); +#endif + if (length > 0) { + state = FM_TASK_RX_PARSER_PKT_PAYLOAD; + } else if (opcode == CSPI_WRITE_OPCODE) { + state = FM_TASK_RX_PARSER_PKT_TYPE; + FM_EVENT_SEND(link_event->ln_event, FLAG_CSPI_WRITE); + } else { + state = FM_TASK_RX_PARSER_PKT_TYPE; + FM_EVENT_SEND(link_event->ln_event, (1 << opcode)); + } + + break; + + case FM_TASK_RX_PARSER_PKT_PAYLOAD: + + switch (opcode) { + case FM_TUNE_OPCODE: + + if ((length == 1) && (rx_buf[i] == 1)) + FM_EVENT_SEND(link_event->ln_event, FLAG_TUNE_DONE); + + break; + + case FM_SOFT_MUTE_TUNE_OPCODE: + + if (length >= 2) { + fm_memcpy(link_event->result.cqi, &rx_buf[i], + (length > FM_CQI_BUF_SIZE) ? FM_CQI_BUF_SIZE : length); + FM_EVENT_SEND(link_event->ln_event, FLAG_SM_TUNE); + } + break; + + case FM_SEEK_OPCODE: + + if ((i + 1) < RX_BUF_SIZE) + link_event->result.seek_result = rx_buf[i] + (rx_buf[i + 1] << 8); + + FM_EVENT_SEND(link_event->ln_event, FLAG_SEEK_DONE); + break; + + case FM_SCAN_OPCODE: + + /* check if the result data is long enough */ + if ((RX_BUF_SIZE - i) < (sizeof(unsigned short) * FM_SCANTBL_SIZE)) { + WCN_DBG(FM_ALT | LINK, + "FM_SCAN_OPCODE err, [tblsize=%d],[bufsize=%d]\n", + (unsigned int)(sizeof(unsigned short) * FM_SCANTBL_SIZE), + (unsigned int)(RX_BUF_SIZE - i)); + FM_EVENT_SEND(link_event->ln_event, FLAG_SCAN_DONE); + return 0; + } else if ((length >= FM_CQI_BUF_SIZE) + && ((RX_BUF_SIZE - i) >= FM_CQI_BUF_SIZE)) { + fm_memcpy(link_event->result.cqi, &rx_buf[i], FM_CQI_BUF_SIZE); + FM_EVENT_SEND(link_event->ln_event, FLAG_CQI_DONE); + } else { + fm_memcpy(link_event->result.scan_result, &rx_buf[i], + sizeof(unsigned short) * FM_SCANTBL_SIZE); + FM_EVENT_SEND(link_event->ln_event, FLAG_SCAN_DONE); + } + + break; + + case FSPI_READ_OPCODE: + + if ((i + 1) < RX_BUF_SIZE) + link_event->result.fspi_rd = (rx_buf[i] + (rx_buf[i + 1] << 8)); + + FM_EVENT_SEND(link_event->ln_event, (1 << opcode)); + break; + case CSPI_READ_OPCODE: + { + if ((i + 1) < RX_BUF_SIZE) { + link_event->result.cspi_rd = + (rx_buf[i] + (rx_buf[i + 1] << 8) + + (rx_buf[i + 2] << 16) + (rx_buf[i + 3] << 24)); + } + + FM_EVENT_SEND(link_event->ln_event, FLAG_CSPI_READ); + break; + } + case FM_HOST_READ_OPCODE: + { + if ((i + 1) < RX_BUF_SIZE) { + link_event->result.cspi_rd = + (rx_buf[i] + (rx_buf[i + 1] << 8) + + (rx_buf[i + 2] << 16) + (rx_buf[i + 3] << 24)); + } + + FM_EVENT_SEND(link_event->ln_event, (1 << opcode)); + break; + } + case FM_WRITE_PMIC_CR_OPCODE: + case FM_MODIFY_PMIC_CR_OPCODE: + { + link_event->result.pmic_result[0] = rx_buf[i]; + + FM_EVENT_SEND(link_event->ln_event, FLAG_PMIC_MODIFY); + break; + } + case FM_READ_PMIC_CR_OPCODE: + { + fm_memcpy(&link_event->result.pmic_result[0], &rx_buf[i], length); + FM_EVENT_SEND(link_event->ln_event, FLAG_PMIC_READ); + break; + } + case RDS_RX_DATA_OPCODE: + + /* check if the rds data is long enough */ + if ((RX_BUF_SIZE - i) < length) { + WCN_DBG(FM_ALT | LINK, + "RDS RX err, [rxlen=%d],[bufsize=%d]\n", + (signed int) length, (RX_BUF_SIZE - i)); + FM_EVENT_SEND(link_event->ln_event, (1 << opcode)); + break; + } + + if (length > sizeof(struct rds_rx_t)) { + WCN_DBG(FM_ALT | LINK, + "RDS RX len out of range, [rxlen=%d],[needmaxlen=%zd]\n", + (signed int) length, (sizeof(struct rds_rx_t))); + FM_EVENT_SEND(link_event->ln_event, (1 << opcode)); + break; + } + /* copy rds data to rds buf */ + fm_memcpy(&link_event->result.rds_rx_result, &rx_buf[i], length); + + /*Handle the RDS data that we get */ + if (rds_parser) + rds_parser(&link_event->result.rds_rx_result, length); + else + WCN_DBG(FM_WAR | LINK, "no method to parse RDS data\n"); + + FM_EVENT_SEND(link_event->ln_event, (1 << opcode)); + break; + + default: + FM_EVENT_SEND(link_event->ln_event, (1 << opcode)); + break; + } + + state = FM_TASK_RX_PARSER_PKT_TYPE; + i += length; + break; + + default: + break; + } + } + + return 0; +} + +bool fm_wait_stc_done(unsigned int sec) +{ + return true; +} + +signed int fm_force_active_event(unsigned int mask) +{ + unsigned int flag; + + flag = FM_EVENT_GET(link_event->ln_event); + WCN_DBG(FM_WAR | LINK, "before force active event, [flag=0x%08x]\n", flag); + flag = FM_EVENT_SEND(link_event->ln_event, mask); + WCN_DBG(FM_WAR | LINK, "after force active event, [flag=0x%08x]\n", flag); + + return 0; +} + +extern signed int fm_print_cmd_fifo(void) +{ +#ifdef FM_TRACE_ENABLE + struct fm_trace_t trace; + signed int i = 0; + + fm_memset(&trace, 0, sizeof(struct fm_trace_t)); + + while (false == FM_TRACE_EMPTY(cmd_fifo)) { + fm_memset(trace.pkt, 0, FM_TRACE_PKT_SIZE); + FM_TRACE_OUT(cmd_fifo, &trace); + WCN_DBG_LIMITED(FM_ALT | LINK, "trace, type %d, op %d, len %d, tid %d, time %d\n", + trace.type, trace.opcode, trace.len, trace.tid, jiffies_to_msecs(abs(trace.time))); + i = 0; + while ((trace.len > 0) && (i < trace.len) && (i < (FM_TRACE_PKT_SIZE - 8))) { + WCN_DBG_LIMITED(FM_ALT | LINK, "trace, %02x %02x %02x %02x %02x %02x %02x %02x\n", + trace.pkt[i], trace.pkt[i + 1], trace.pkt[i + 2], trace.pkt[i + 3], + trace.pkt[i + 4], trace.pkt[i + 5], trace.pkt[i + 6], trace.pkt[i + 7]); + i += 8; + } + WCN_DBG_LIMITED(FM_ALT | LINK, "trace\n"); + } +#endif + + return 0; +} + +extern signed int fm_print_evt_fifo(void) +{ +#ifdef FM_TRACE_ENABLE + struct fm_trace_t trace; + signed int i = 0; + + fm_memset(&trace, 0, sizeof(struct fm_trace_t)); + + while (false == FM_TRACE_EMPTY(evt_fifo)) { + fm_memset(trace.pkt, 0, FM_TRACE_PKT_SIZE); + FM_TRACE_OUT(evt_fifo, &trace); + WCN_DBG_LIMITED(FM_ALT | LINK, "%s: op %d, len %d, %d\n", evt_fifo->name, trace.opcode, + trace.len, jiffies_to_msecs(abs(trace.time))); + i = 0; + while ((trace.len > 0) && (i < trace.len) && (i < (FM_TRACE_PKT_SIZE - 8))) { + WCN_DBG_LIMITED(FM_ALT | LINK, "%s: %02x %02x %02x %02x %02x %02x %02x %02x\n", + evt_fifo->name, trace.pkt[i], trace.pkt[i + 1], trace.pkt[i + 2], + trace.pkt[i + 3], trace.pkt[i + 4], trace.pkt[i + 5], + trace.pkt[i + 6], trace.pkt[i + 7]); + i += 8; + } + WCN_DBG_LIMITED(FM_ALT | LINK, "%s\n", evt_fifo->name); + } +#endif + + return 0; +} + +signed int fm_trace_in(struct fm_trace_fifo_t *thiz, struct fm_trace_t *new_tra) +{ + if (new_tra == NULL) { + WCN_DBG(FM_ERR | LINK, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + if (thiz->len < thiz->size) { + fm_memcpy(&(thiz->trace[thiz->in]), new_tra, sizeof(struct fm_trace_t)); + thiz->trace[thiz->in].time = jiffies; + thiz->in = (thiz->in + 1) % thiz->size; + thiz->len++; + /* WCN_DBG(FM_DBG | RDSC, "add a new tra[len=%d]\n", thiz->len); */ + } else { + WCN_DBG(FM_WAR | LINK, "tra buf is full\n"); + return -FM_ENOMEM; + } + + return 0; +} + +signed int fm_trace_out(struct fm_trace_fifo_t *thiz, struct fm_trace_t *dst_tra) +{ + if (thiz->len > 0) { + if (dst_tra) { + fm_memcpy(dst_tra, &(thiz->trace[thiz->out]), sizeof(struct fm_trace_t)); + fm_memset(&(thiz->trace[thiz->out]), 0, sizeof(struct fm_trace_t)); + } + thiz->out = (thiz->out + 1) % thiz->size; + thiz->len--; + /* WCN_DBG(FM_DBG | LINK, "del a tra[len=%d]\n", thiz->len); */ + } else { + WCN_DBG(FM_WAR | LINK, "tra buf is empty\n"); + } + + return 0; +} + +bool fm_trace_is_full(struct fm_trace_fifo_t *thiz) +{ + return (thiz->len == thiz->size) ? true : false; +} + +bool fm_trace_is_empty(struct fm_trace_fifo_t *thiz) +{ + return (thiz->len == 0) ? true : false; +} + +struct fm_trace_fifo_t *fm_trace_fifo_create(const signed char *name) +{ + struct fm_trace_fifo_t *tmp; + + tmp = fm_zalloc(sizeof(struct fm_trace_fifo_t)); + if (!tmp) { + WCN_DBG(FM_ALT | MAIN, "fm_zalloc(fm_trace_fifo) -ENOMEM\n"); + return NULL; + } + + fm_memcpy(tmp->name, name, (strlen(name) + 1)); + tmp->size = FM_TRACE_FIFO_SIZE; + tmp->in = 0; + tmp->out = 0; + tmp->len = 0; + tmp->trace_in = fm_trace_in; + tmp->trace_out = fm_trace_out; + tmp->is_full = fm_trace_is_full; + tmp->is_empty = fm_trace_is_empty; + + WCN_DBG(FM_NTC | LINK, "%s created\n", tmp->name); + + return tmp; +} + +signed int fm_trace_fifo_release(struct fm_trace_fifo_t *fifo) +{ + if (fifo) { + WCN_DBG(FM_NTC | LINK, "%s released\n", fifo->name); + fm_free(fifo); + } + + return 0; +} diff --git a/drivers/misc/mediatek/connectivity/fmradio/core/fm_main.c b/drivers/misc/mediatek/connectivity/fmradio/core/fm_main.c new file mode 100644 index 0000000000000000000000000000000000000000..34055026b2488cec71bc7a7123a22f366042957e --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/core/fm_main.c @@ -0,0 +1,2897 @@ +/* + * Copyright (C) 2015 MediaTek Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 +#include +#include +#include + +#include "fm_main.h" +#include "fm_err.h" +#include "fm_reg_utils.h" +/* #include "fm_cust_cfg.h" */ +#include "fm_cmd.h" + +/* fm main data structure */ +static struct fm *g_fm_struct; +/* we must get low level interface first, when add a new chip, the main effort is this interface */ +static struct fm_lowlevel_ops fm_low_ops; + +/* mutex for char device ops */ +static struct fm_lock *fm_ops_lock; +/* mutex for RDS parsing and read result */ +static struct fm_lock *fm_read_lock; +/* for get rds block counter */ +static struct fm_lock *fm_rds_cnt; +/* mutex for fm timer, RDS reset */ +static struct fm_lock *fm_timer_lock; +static struct fm_lock *fm_rxtx_lock; /* protect FM RX TX mode switch */ +static struct fm_lock *fm_rtc_mutex; /* protect FM GPS RTC drift info */ + +static struct fm_timer *fm_timer_sys; + +#if (FM_INVALID_CHAN_NOISE_REDUCING) +static struct fm_timer *fm_cqi_check_timer; +#endif + +#define FM_CHIP_CAN_SUSPEND 0x00006631 +FM_WAKE_LOCK_T *fm_wake_lock; + +static bool scan_stop_flag; /* false */ +static struct fm_gps_rtc_info gps_rtc_info; +static bool g_fm_stat[3] = { + false, /* RX power */ + false, /* TX power */ + false, /* TX scan */ +}; + +/* chipid porting table */ +static struct fm_chip_mapping fm_support_chip_array[] = { +{ 0x6572, 0x6627, FM_AD_DIE_CHIP }, +{ 0x6582, 0x6627, FM_AD_DIE_CHIP }, +{ 0x6592, 0x6627, FM_AD_DIE_CHIP }, +{ 0x8127, 0x6627, FM_AD_DIE_CHIP }, +{ 0x6571, 0x6627, FM_AD_DIE_CHIP }, +{ 0x6752, 0x6627, FM_AD_DIE_CHIP }, +{ 0x0321, 0x6627, FM_AD_DIE_CHIP }, +{ 0x0335, 0x6627, FM_AD_DIE_CHIP }, +{ 0x0337, 0x6627, FM_AD_DIE_CHIP }, +{ 0x6735, 0x6627, FM_AD_DIE_CHIP }, +{ 0x8163, 0x6627, FM_AD_DIE_CHIP }, +{ 0x6755, 0x6627, FM_AD_DIE_CHIP }, +{ 0x0326, 0x6627, FM_AD_DIE_CHIP }, +{ 0x6570, 0x0633, FM_SOC_CHIP }, +{ 0x6580, 0x6580, FM_SOC_CHIP }, +{ 0x6630, 0x6630, FM_COMBO_CHIP }, +{ 0x6797, 0x6631, FM_AD_DIE_CHIP }, +{ 0x6759, 0x6631, FM_AD_DIE_CHIP }, +{ 0x6758, 0x6631, FM_AD_DIE_CHIP }, +{ 0x6632, 0x6632, FM_COMBO_CHIP }, +{ 0x6757, 0x6627, FM_AD_DIE_CHIP }, +{ 0x6763, 0x6627, FM_AD_DIE_CHIP }, +{ 0x6765, 0x6631, FM_AD_DIE_CHIP }, +{ 0x6761, 0x6631, FM_AD_DIE_CHIP }, +{ 0x6739, 0x6627, FM_AD_DIE_CHIP }, +{ 0x3967, 0x6631, FM_AD_DIE_CHIP }, +{ 0x6771, 0x6631, FM_AD_DIE_CHIP }, +{ 0x6775, 0x6631, FM_AD_DIE_CHIP }, +{ 0x6768, 0x6631, FM_AD_DIE_CHIP }, +{ 0x6779, 0x6635, FM_AD_DIE_CHIP }, +}; + +unsigned char top_index; + +/* RDS reset related functions */ +static unsigned short fm_cur_freq_get(void); +static signed int fm_cur_freq_set(unsigned short new_freq); +static enum fm_op_state fm_op_state_get(struct fm *fmp); +static enum fm_op_state fm_op_state_set(struct fm *fmp, enum fm_op_state sta); +#if KERNEL_VERSION(4, 15, 0) <= LINUX_VERSION_CODE +static void fm_timer_func(struct timer_list *timer); +#else +static void fm_timer_func(unsigned long data); +#endif +static void fm_enable_rds_BlerCheck(struct fm *fm); +static void fm_disable_rds_BlerCheck(void); +static void fm_rds_reset_work_func(struct work_struct *work); +/* when interrupt be triggered by FM chip, fm_eint_handler will first be executed */ +/* then fm_eint_handler will schedule fm_eint_work_func to run */ +static void fm_eint_handler(void); +static void fm_eint_work_func(struct work_struct *work); +static signed int pwrdown_flow(struct fm *fm); + +static unsigned short fm_cur_freq_get(void) +{ + return g_fm_struct ? g_fm_struct->cur_freq : 0; +} + +static signed int fm_cur_freq_set(unsigned short new_freq) +{ + if (g_fm_struct) + g_fm_struct->cur_freq = new_freq; + + return 0; +} + +static signed int fm_projectid_get(void) +{ + return g_fm_struct ? g_fm_struct->projectid : 0; +} + +static enum fm_op_state fm_op_state_get(struct fm *fmp) +{ + if (fmp) { + WCN_DBG(FM_DBG | MAIN, "op state get %d\n", fmp->op_sta); + return fmp->op_sta; + } + + WCN_DBG(FM_ERR | MAIN, "op state get para error\n"); + return FM_STA_UNKNOWN; +} + +static enum fm_op_state fm_op_state_set(struct fm *fmp, enum fm_op_state sta) +{ + if (fmp && (sta < FM_STA_MAX)) { + fmp->op_sta = sta; + WCN_DBG(FM_DBG | MAIN, "op state set to %d\n", sta); + return fmp->op_sta; + } + + WCN_DBG(FM_ERR | MAIN, "op state set para error, %d\n", sta); + return FM_STA_UNKNOWN; +} + +enum fm_pwr_state fm_pwr_state_get(struct fm *fmp) +{ + if (fmp) { + WCN_DBG(FM_DBG | MAIN, "pwr state get %d\n", fmp->pwr_sta); + return fmp->pwr_sta; + } + + WCN_DBG(FM_ERR | MAIN, "pwr state get para error\n"); + return FM_PWR_MAX; +} + +enum fm_pwr_state fm_pwr_state_set(struct fm *fmp, enum fm_pwr_state sta) +{ + if (fmp && (sta < FM_PWR_MAX)) { + fmp->pwr_sta = sta; + WCN_DBG(FM_DBG | MAIN, "pwr state set to %d\n", sta); + return fmp->pwr_sta; + } + + WCN_DBG(FM_ERR | MAIN, "pwr state set para error, %d\n", sta); + return FM_PWR_MAX; +} + +signed int fm_set_stat(struct fm *fmp, int which, bool stat) +{ + signed int ret = 0; + + if (fmp == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + if (which >= 0 && which < ARRAY_SIZE(g_fm_stat)) { + g_fm_stat[which] = stat; + WCN_DBG(FM_DBG | MAIN, "fm set stat object=%d, stat=%d\n", which, stat); + } else { + ret = -1; + WCN_DBG(FM_ERR | MAIN, "fm set stat error, object=%d, stat=%d\n", which, stat); + } + + FM_UNLOCK(fm_ops_lock); + return ret; +} + +signed int fm_get_stat(struct fm *fmp, int which, bool *stat) +{ + signed int ret = 0; + + if (fmp == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (stat == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + if (which >= 0 && which < ARRAY_SIZE(g_fm_stat)) { + *stat = g_fm_stat[which]; + WCN_DBG(FM_DBG | MAIN, "fm get stat object=%d, stat=%d\n", which, *stat); + } else { + ret = -1; + WCN_DBG(FM_ERR | MAIN, "fm get stat error, object=%d\n", which); + } + + FM_UNLOCK(fm_ops_lock); + return ret; +} + +static signed int subsys_rst_state = FM_SUBSYS_RST_OFF; + +signed int fm_sys_state_get(struct fm *fmp) +{ + return subsys_rst_state; +} + +signed int fm_sys_state_set(struct fm *fmp, signed int sta) +{ + if ((sta >= FM_SUBSYS_RST_OFF) && (sta < FM_SUBSYS_RST_MAX)) { + WCN_DBG(FM_NTC | MAIN, "sys state set from %d to %d\n", subsys_rst_state, sta); + subsys_rst_state = sta; + } else { + WCN_DBG(FM_ERR | MAIN, "sys state set para error, %d\n", sta); + } + + return subsys_rst_state; +} + +signed int fm_subsys_reset(struct fm *fm) +{ + /* check if we are resetting */ + if (fm_sys_state_get(fm) != FM_SUBSYS_RST_OFF) { + WCN_DBG(FM_NTC | MAIN, "subsys reset is ongoing\n"); + goto out; + } + + if (fm == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + fm->timer_wkthd->add_work(fm->timer_wkthd, fm->rst_wk); + +out: + return 0; +} + +signed int fm_wholechip_rst_cb(signed int sta) +{ + struct fm *fm = g_fm_struct; + + if (!fm) + return 0; + + if (sta == 1) { + if (fm_sys_state_get(fm) == FM_SUBSYS_RST_OFF) + fm_sys_state_set(fm, FM_SUBSYS_RST_START); + } else if (sta == 2) { + if (fm_sys_state_get(fm) == FM_SUBSYS_RST_START) + fm_sys_state_set(fm, FM_SUBSYS_RST_OFF); + } else + fm->timer_wkthd->add_work(fm->timer_wkthd, fm->rst_wk); + + return 0; +} + +static signed int fm_which_chip(unsigned short chipid, enum fm_cfg_chip_type *type) +{ + signed short fm_chip = -1; + signed short i = 0; + + if (fm_wcn_ops.ei.get_get_adie) { + fm_chip = (signed short)fm_wcn_ops.ei.get_get_adie(); + if (fm_chip == 0x6631 || fm_chip == 0x6635) { + if (type) + *type = FM_AD_DIE_CHIP; + return fm_chip; + } + } + + for (i = 0; i < (sizeof(fm_support_chip_array)/sizeof(struct fm_chip_mapping)); i++) { + if (chipid == fm_support_chip_array[i].con_chip) { + fm_chip = fm_support_chip_array[i].fm_chip; + break; + } + } + + if (type) { + for (i = 0; i < (sizeof(fm_support_chip_array)/sizeof(struct fm_chip_mapping)); i++) { + if (chipid == fm_support_chip_array[i].fm_chip) { + *type = fm_support_chip_array[i].type; + break; + } + } + } + + return fm_chip; +} + +signed int fm_open(struct fm *fmp) +{ + signed int ret = 0; + signed int chipid = 0; + + if (fmp == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + if (fmp->chipon == false) { + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + if (fm_wcn_ops.ei.wmt_chipid_query) + chipid = fm_wcn_ops.ei.wmt_chipid_query(); + fmp->projectid = chipid; + WCN_DBG(FM_NTC | MAIN, "wmt chip id=0x%x\n", chipid); + + if (fm_wcn_ops.ei.get_top_index) + top_index = fm_wcn_ops.ei.get_top_index(); + else + top_index = 4; + WCN_DBG(FM_NTC | MAIN, "mcu top index = 0x%x\n", top_index); + /* what's the purpose of put chipid to fmp->chip_id ? */ + fmp->chip_id = fm_which_chip(chipid, NULL); + WCN_DBG(FM_NTC | MAIN, "fm chip id=0x%x\n", fmp->chip_id); + + fm_eint_pin_cfg(FM_EINT_PIN_EINT_MODE); + fm_request_eint(fm_eint_handler); + + FM_UNLOCK(fm_ops_lock); + } + return ret; +} + +signed int fm_close(struct fm *fmp) +{ + signed int ret = 0; + + if (fmp == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + fm_eint_pin_cfg(FM_EINT_PIN_GPIO_MODE); + + FM_UNLOCK(fm_ops_lock); + + return ret; +} + +signed int fm_rds_read(struct fm *fmp, signed char *dst, signed int len) +{ + signed int copy_len = 0, left = 0; + + copy_len = sizeof(struct rds_t); + + if (FM_EVENT_GET(fmp->rds_event) == FM_RDS_DATA_READY) { + if (FM_LOCK(fm_read_lock)) + return -FM_ELOCK; + + left = copy_to_user((void *)dst, fmp->pstRDSData, (unsigned long)copy_len); + if (left) + WCN_DBG(FM_ALT | MAIN, "fm_read copy failed\n"); + else + fmp->pstRDSData->event_status = 0x0000; + + WCN_DBG(FM_DBG | MAIN, "fm_read copy len:%d\n", (copy_len - left)); + + FM_EVENT_RESET(fmp->rds_event); + FM_UNLOCK(fm_read_lock); + } else { + /*if (FM_EVENT_WAIT(fmp->rds_event, FM_RDS_DATA_READY) == 0) { + * WCN_DBG(FM_DBG | MAIN, "fm_read wait ok\n"); + * goto RESTART; + * } else { + * WCN_DBG(FM_ALT | MAIN, "fm_read wait err\n"); + * return 0; + * } *//*event wait caused AP stop RDS thread and re-read RDS, which caused issue ALPS00595367 */ + + WCN_DBG(FM_DBG | MAIN, "fm_read no event now\n"); + return 0; + } + + return copy_len - left; +} + +signed int fm_powerup(struct fm *fm, struct fm_tune_parm *parm) +{ + signed int ret = 0; + unsigned char tmp_vol; + + if (fm_low_ops.bi.pwron == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (fm_low_ops.bi.pwrupseq == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + /* for normal case */ + if (fm_low_ops.bi.pwron == NULL) { + WCN_DBG(FM_NTC | MAIN, "get fm_low_ops fail\n"); + ret = -ENODEV; + goto out; + } + + if (fm->chipon == false) { + ret = fm_low_ops.bi.pwron(0); + if (ret) { + ret = -ENODEV; + goto out; + } + fm->chipon = true; + } + + if (fm_pwr_state_get(fm) == FM_PWR_RX_ON) { + WCN_DBG(FM_NTC | MAIN, "already pwron!\n"); + goto out; + } else if (fm_pwr_state_get(fm) == FM_PWR_TX_ON) { + /* if Tx is on, we need pwr down TX first */ + WCN_DBG(FM_NTC | MAIN, "power down TX first!\n"); + + ret = fm_powerdowntx(fm); + if (ret) { + WCN_DBG(FM_ERR | MAIN, "FM pwr down Tx fail!\n"); + goto out; + } + } + + fm_pwr_state_set(fm, FM_PWR_RX_ON); + + /* execute power on sequence */ + ret = fm_low_ops.bi.pwrupseq(&fm->chip_id, &fm->device_id); + if (ret) { + fm_pwr_state_set(fm, FM_PWR_OFF); + WCN_DBG(FM_ERR | MAIN, "powerup fail!!!\n"); + goto out; + } + + fm_cur_freq_set(parm->freq); + + parm->err = FM_SUCCESS; + if (fm_low_ops.bi.low_pwr_wa) + fm_low_ops.bi.low_pwr_wa(1); + + fm_low_ops.bi.volget(&tmp_vol); + WCN_DBG(FM_INF | MAIN, "vol=%d!!!\n", tmp_vol); + + /* fm_low_ops.bi.volset(0); */ + fm->vol = 15; + if (fm_low_ops.ri.rds_bci_get) { + fm_timer_sys->init(fm_timer_sys, fm_timer_func, (unsigned long)g_fm_struct, + fm_low_ops.ri.rds_bci_get(), 0); + fm_timer_sys->start(fm_timer_sys); + } else { + WCN_DBG(FM_NTC | MAIN, "start timer fail!!!\n"); + } + + if (fm_wake_lock) { + fm_wakelock_get(fm_wake_lock); + WCN_DBG(FM_NTC | MAIN, "acquire fm_wake_lock\n"); + } +out: + FM_UNLOCK(fm_ops_lock); + return ret; +} + +/* + * fm_powerup_tx + */ +signed int fm_powerup_tx(struct fm *fm, struct fm_tune_parm *parm) +{ + signed int ret = 0; + + if (fm_low_ops.bi.pwron == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (fm_low_ops.bi.pwrupseq_tx == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + if (fm_pwr_state_get(fm) == FM_PWR_TX_ON) { + WCN_DBG(FM_NTC | MAIN, "already pwron!\n"); + parm->err = FM_BADSTATUS; + return ret; + } else if (fm_pwr_state_get(fm) == FM_PWR_RX_ON) { + /* if Rx is on, we need pwr down first */ + ret = fm_powerdown(fm, 0); + if (ret) { + WCN_DBG(FM_ERR | MAIN, "FM pwr down Rx fail!\n"); + return ret; + } + } + + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + /* for normal case */ + if (fm->chipon == false) { + fm_low_ops.bi.pwron(0); + fm->chipon = true; + } + + fm_pwr_state_set(fm, FM_PWR_TX_ON); + ret = fm_low_ops.bi.pwrupseq_tx(); + + if (ret) { + parm->err = FM_FAILED; + fm_pwr_state_set(fm, FM_PWR_OFF); + WCN_DBG(FM_ERR | MAIN, "FM pwr up Tx fail!\n"); + } else { + parm->err = FM_SUCCESS; + } + fm_cur_freq_set(parm->freq); + + FM_UNLOCK(fm_ops_lock); + return ret; +} + +static signed int pwrdown_flow(struct fm *fm) +{ + signed int ret = 0; + + if (fm_low_ops.ri.rds_onoff == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (fm_low_ops.bi.pwrdownseq == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + if (fm_pwr_state_get(fm) == FM_PWR_OFF) { + WCN_DBG(FM_NTC | MAIN, "FMSYS already pwroff!\n"); + goto out; + } + + if (fm_pwr_state_get(fm) == FM_PWR_RX_ON) { + /* Disable all interrupt */ + fm_disable_rds_BlerCheck(); + fm_low_ops.ri.rds_onoff(fm->pstRDSData, false); + + fm_pwr_state_set(fm, FM_PWR_OFF); + + /* execute power down sequence */ + ret = fm_low_ops.bi.pwrdownseq(); + + if (fm_low_ops.bi.low_pwr_wa) + fm_low_ops.bi.low_pwr_wa(0); + + WCN_DBG(FM_ALT | MAIN, "pwrdown_flow exit\n"); + } +out: + return ret; +} + +signed int fm_powerdown(struct fm *fm, int type) +{ + signed int ret = 0; + + if (fm_wake_lock) { + fm_wakelock_put(fm_wake_lock); + WCN_DBG(FM_NTC | MAIN, "release fm_wake_lock\n"); + } + +#if (FM_INVALID_CHAN_NOISE_REDUCING) + fm_cqi_check_timer->stop(fm_cqi_check_timer); +#endif + + if (type == 1) { /* 0: RX 1: TX */ + ret = fm_powerdowntx(fm); + } else { + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + if (FM_LOCK(fm_rxtx_lock)) { + FM_UNLOCK(fm_ops_lock); + return -FM_ELOCK; + } + + ret = pwrdown_flow(fm); + + FM_UNLOCK(fm_rxtx_lock); + FM_UNLOCK(fm_ops_lock); + } + + if ((fm_pwr_state_get(fm) == FM_PWR_OFF) && (fm->chipon == true)) { + fm_low_ops.bi.pwroff(0); + fm->chipon = false; + } + + return ret; +} + +signed int fm_powerdowntx(struct fm *fm) +{ + signed int ret = 0; + + if (fm_low_ops.bi.pwrdownseq_tx == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (FM_LOCK(fm_rxtx_lock)) + return -FM_ELOCK; + + if (fm_pwr_state_get(fm) == FM_PWR_TX_ON) { + /* fm_low_ops.ri.rds_onoff(fm->pstRDSData, false); */ + /* execute power down sequence */ + ret = fm_low_ops.bi.pwrdownseq_tx(); + if (ret) + WCN_DBG(FM_ERR | MAIN, "pwrdown tx fail\n"); + + fm_pwr_state_set(fm, FM_PWR_OFF); + WCN_DBG(FM_NTC | MAIN, "pwrdown tx ok\n"); + } + + FM_UNLOCK(fm_rxtx_lock); + /* FM_UNLOCK(fm_ops_lock); */ + return ret; +} + +/*********************************************************** +* Function: fm_tx_scan() +* +* Description: get the valid channels for fm tx function +* +* Para: fm--->fm driver global info +* parm--->input/output parameter +* +* Return: 0, if success; error code, if failed +***********************************************************/ +signed int fm_tx_scan(struct fm *fm, struct fm_tx_scan_parm *parm) +{ + signed int ret = 0; + unsigned short scandir = 0; + unsigned short space = parm->space; + + if (fm_low_ops.bi.tx_scan == NULL) { + pr_err("%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + if (fm->chipon != true) { + parm->err = FM_BADSTATUS; + ret = -EPERM; + WCN_DBG(FM_ERR | MAIN, "tx scan chip not on\n"); + goto out; + } + switch (parm->scandir) { + case FM_TX_SCAN_UP: + scandir = 0; + break; + case FM_TX_SCAN_DOWN: + scandir = 1; + break; + default: + scandir = 0; + break; + } + + if (parm->band == FM_BAND_UE) { + fm->min_freq = FM_UE_FREQ_MIN; + fm->max_freq = FM_UE_FREQ_MAX; + } else if (parm->band == FM_BAND_JAPANW) { + fm->min_freq = FM_JP_FREQ_MIN; + fm->max_freq = FM_JP_FREQ_MAX; + } else if (parm->band == FM_BAND_SPECIAL) { + fm->min_freq = FM_FREQ_MIN; + fm->max_freq = FM_FREQ_MAX; + } else { + WCN_DBG(FM_ERR | MAIN, "band:%d out of range\n", parm->band); + parm->err = FM_EPARM; + ret = -EPERM; + goto out; + } + + if (unlikely((parm->freq < fm->min_freq) || (parm->freq > fm->max_freq))) { + parm->err = FM_EPARM; + ret = -EPERM; + WCN_DBG(FM_ERR | MAIN, "%s parm->freq:%d fm->min_freq: %d fm->max_freq:%d\n", + __func__, parm->freq, fm->min_freq, fm->max_freq); + goto out; + } + + if (unlikely(parm->ScanTBLSize < TX_SCAN_MIN || parm->ScanTBLSize > TX_SCAN_MAX)) { + parm->err = FM_EPARM; + ret = -EPERM; + WCN_DBG(FM_ERR | MAIN, "%s parm->ScanTBLSize:%d TX_SCAN_MIN:%d TX_SCAN_MAX:%d\n", + __func__, parm->ScanTBLSize, TX_SCAN_MIN, TX_SCAN_MAX); + goto out; + } + + ret = fm_low_ops.bi.anaswitch(FM_ANA_SHORT); + if (ret) { + WCN_DBG(FM_ERR | MAIN, "switch to short ana failed\n"); + goto out; + } + /* do tx scan */ + ret = fm_low_ops.bi.tx_scan(fm->min_freq, fm->max_freq, &(parm->freq), + parm->ScanTBL, &(parm->ScanTBLSize), scandir, space); + if (!ret) { + parm->err = FM_SUCCESS; + } else { + WCN_DBG(FM_ERR | MAIN, "fm_tx_scan failed\n"); + parm->err = FM_SCAN_FAILED; + } +out: + FM_UNLOCK(fm_ops_lock); + return ret; +} + +signed int fm_cqi_get(struct fm *fm, signed int ch_num, signed char *buf, signed int buf_size) +{ + signed int ret = 0; + signed int idx = 0; + + if (fm_low_ops.bi.cqi_get == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + if (true == scan_stop_flag) { + WCN_DBG(FM_NTC | MAIN, "scan flow aborted, do not get CQI\n"); + ret = -1; + goto out; + } + + if (fm_pwr_state_get(fm) != FM_PWR_RX_ON) { + ret = -EPERM; + goto out; + } + + if (ch_num * sizeof(struct fm_cqi) > buf_size) { + ret = -EPERM; + goto out; + } + + fm_op_state_set(fm, FM_STA_SCAN); + + idx = 0; + WCN_DBG(FM_NTC | MAIN, "cqi num %d\n", ch_num); + + while (ch_num > 0) { + ret = + fm_low_ops.bi.cqi_get(buf + 16 * sizeof(struct fm_cqi) * idx, + buf_size - 16 * sizeof(struct fm_cqi) * idx); + + if (ret) + goto out; + + ch_num -= 16; + idx++; + } + + fm_op_state_set(fm, FM_STA_STOP); + +out: + FM_UNLOCK(fm_ops_lock); + return ret; +} + +/* fm_is_dese_chan -- check if gived channel is a de-sense channel or not + * @pfm - fm driver global DS + * @freq - gived channel + * return value: 0, not a dese chan; 1, a dese chan; else error NO. + */ +signed int fm_is_dese_chan(struct fm *pfm, unsigned short freq) +{ + signed int ret = 0; + + if (pfm == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (fm_low_ops.bi.is_dese_chan) { + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + ret = fm_low_ops.bi.is_dese_chan(freq); + FM_UNLOCK(fm_ops_lock); + } + + return ret; +} + +/* fm_is_dese_chan -- check if gived channel is a de-sense channel or not + * @pfm - fm driver global DS + * @freq - gived channel + * return value: 0, not a dese chan; 1, a dese chan; else error NO. + */ +signed int fm_desense_check(struct fm *pfm, unsigned short freq, signed int rssi) +{ + signed int ret = 0; + + if (pfm == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (fm_low_ops.bi.desense_check) { + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + ret = fm_low_ops.bi.desense_check(freq, rssi); + FM_UNLOCK(fm_ops_lock); + } + + return ret; +} + +signed int fm_dump_reg(void) +{ + signed int ret = 0; + + if (fm_low_ops.bi.dumpreg) { + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + ret = fm_low_ops.bi.dumpreg(); + FM_UNLOCK(fm_ops_lock); + } + return ret; +} + +/* fm_get_hw_info -- hw info: chip id, ECO version, DSP ROM version, Patch version + * @pfm - fm driver global DS + * @freq - target buffer + * return value: 0, success; else error NO. + */ +signed int fm_get_hw_info(struct fm *pfm, struct fm_hw_info *req) +{ + signed int ret = 0; + + if (req == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + /* default value for all chips */ + req->chip_id = 0x000066FF; + req->eco_ver = 0x00000000; + req->rom_ver = 0x00000001; + req->patch_ver = 0x00000100; + req->reserve = 0x00000000; + + /* get actual chip hw info */ + if (fm_low_ops.bi.hwinfo_get) { + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + ret = fm_low_ops.bi.hwinfo_get(req); + FM_UNLOCK(fm_ops_lock); + } + + return ret; +} + +signed int fm_get_aud_info(struct fm_audio_info_t *data) +{ + if (fm_low_ops.bi.get_aud_info) + return fm_low_ops.bi.get_aud_info(data); + + data->aud_path = FM_AUD_ERR; + data->i2s_info.mode = FM_I2S_MODE_ERR; + data->i2s_info.status = FM_I2S_STATE_ERR; + data->i2s_info.rate = FM_I2S_SR_ERR; + data->i2s_pad = FM_I2S_PAD_ERR; + return 0; +} + +/* fm_get_i2s_info -- i2s info: on/off, master/slave, sample rate + * @pfm - fm driver global DS + * @req - target buffer + * return value: 0, success; else error NO. + */ +signed int fm_get_i2s_info(struct fm *pfm, struct fm_i2s_info *req) +{ + if (fm_low_ops.bi.i2s_get == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + return fm_low_ops.bi.i2s_get(&req->status, &req->mode, &req->rate); +} + +signed int fm_hwscan_stop(struct fm *fm) +{ + signed int ret = 0; + + if ((fm_op_state_get(fm) != FM_STA_SCAN) && (fm_op_state_get(fm) != FM_STA_SEEK)) { + WCN_DBG(FM_WAR | MAIN, "fm isn't on scan, no need stop\n"); + return ret; + } + + if (fm_low_ops.bi.scanstop == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + fm_low_ops.bi.scanstop(); + fm_low_ops.bi.seekstop(); + scan_stop_flag = true; + WCN_DBG(FM_DBG | MAIN, "fm will stop scan\n"); + + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + fm_low_ops.bi.rampdown(); + fm_low_ops.bi.setfreq(fm_cur_freq_get()); + + FM_UNLOCK(fm_ops_lock); + + return ret; +} + +/* fm_ana_switch -- switch antenna to long/short + * @fm - fm driver main data structure + * @antenna - 0, long; 1, short + * If success, return 0; else error code + */ +signed int fm_ana_switch(struct fm *fm, signed int antenna) +{ + signed int ret = 0; + + if (fm_low_ops.bi.anaswitch == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + WCN_DBG(FM_DBG | MAIN, "Switching ana to %s\n", antenna ? "short" : "long"); + fm->ana_type = antenna; + + if ((fm_pwr_state_get(fm) == FM_PWR_RX_ON) || (fm_pwr_state_get(fm) == FM_PWR_TX_ON)) + ret = fm_low_ops.bi.anaswitch(antenna); + + if (ret) + WCN_DBG(FM_ALT | MAIN, "Switch ana Failed\n"); + else + WCN_DBG(FM_DBG | MAIN, "Switch ana OK!\n"); + + FM_UNLOCK(fm_ops_lock); + return ret; +} + +/* volume?[0~15] */ +signed int fm_setvol(struct fm *fm, unsigned int vol) +{ + unsigned char tmp_vol; + + if (fm_pwr_state_get(fm) != FM_PWR_RX_ON) + return -EPERM; + + if (fm_low_ops.bi.volset == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + tmp_vol = (vol > 15) ? 15 : vol; + fm_low_ops.bi.volset(tmp_vol); + fm->vol = (signed int) tmp_vol; + + FM_UNLOCK(fm_ops_lock); + return 0; +} + +signed int fm_getvol(struct fm *fm, unsigned int *vol) +{ + unsigned char tmp_vol; + + if (fm_pwr_state_get(fm) != FM_PWR_RX_ON) + return -EPERM; + + if (fm_low_ops.bi.volget == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + fm_low_ops.bi.volget(&tmp_vol); + *vol = (unsigned int) tmp_vol; + + FM_UNLOCK(fm_ops_lock); + return 0; +} + +signed int fm_mute(struct fm *fm, unsigned int bmute) +{ + signed int ret = 0; + + if (fm_pwr_state_get(fm) != FM_PWR_RX_ON) { + ret = -EPERM; + return ret; + } + if (fm_low_ops.bi.mute == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + if (bmute) { + ret = fm_low_ops.bi.mute(true); + fm->mute = true; + } else { + ret = fm_low_ops.bi.mute(false); + fm->mute = false; + } + + FM_UNLOCK(fm_ops_lock); + return ret; +} + +signed int fm_getrssi(struct fm *fm, signed int *rssi) +{ + signed int ret = 0; + + if (fm_pwr_state_get(fm) != FM_PWR_RX_ON) { + ret = -EPERM; + return ret; + } + if (fm_low_ops.bi.rssiget == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + ret = fm_low_ops.bi.rssiget(rssi); + + FM_UNLOCK(fm_ops_lock); + return ret; +} + +signed int fm_read(struct fm *fm, unsigned char addr, unsigned short *val) +{ + signed int ret = 0; + + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + ret = fm_reg_read(addr, val); + + FM_UNLOCK(fm_ops_lock); + return ret; +} + +signed int fm_write(struct fm *fm, unsigned char addr, unsigned short val) +{ + signed int ret = 0; + + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + ret = fm_reg_write(addr, val); + + FM_UNLOCK(fm_ops_lock); + return ret; +} + +signed int fm_top_read(struct fm *fm, unsigned short addr, unsigned int *val) +{ + signed int ret = 0; + + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + ret = fm_top_reg_read(addr, val); + + FM_UNLOCK(fm_ops_lock); + return ret; +} + +signed int fm_top_write(struct fm *fm, unsigned short addr, unsigned int val) +{ + signed int ret = 0; + + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + ret = fm_top_reg_write(addr, val); + + FM_UNLOCK(fm_ops_lock); + return ret; +} + +signed int fm_host_read(struct fm *fm, unsigned int addr, unsigned int *val) +{ + signed int ret = 0; + + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + ret = fm_host_reg_read(addr, val); + + FM_UNLOCK(fm_ops_lock); + return ret; +} + +signed int fm_host_write(struct fm *fm, unsigned int addr, unsigned int val) +{ + signed int ret = 0; + + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + ret = fm_host_reg_write(addr, val); + + FM_UNLOCK(fm_ops_lock); + return ret; +} + +signed int fm_pmic_read(struct fm *fm, unsigned char addr, unsigned int *val) +{ + signed int ret = 0; + + if (fm_low_ops.bi.pmic_read == NULL) { + pr_err("%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + ret = fm_low_ops.bi.pmic_read(addr, val); + + FM_UNLOCK(fm_ops_lock); + return ret; +} + +signed int fm_pmic_write(struct fm *fm, unsigned char addr, unsigned int val) +{ + signed int ret = 0; + + if (fm_low_ops.bi.pmic_write == NULL) { + pr_err("%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + ret = fm_low_ops.bi.pmic_write(addr, val); + + FM_UNLOCK(fm_ops_lock); + return ret; +} + +signed int fm_chipid_get(struct fm *fm, unsigned short *chipid) +{ + if (chipid == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + *chipid = fm->chip_id; + + FM_UNLOCK(fm_ops_lock); + return 0; +} + +signed int fm_monostereo_get(struct fm *fm, unsigned short *ms) +{ + signed int ret = 0; + + if (fm_low_ops.bi.msget == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (ms == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + if (fm_low_ops.bi.msget(ms) == false) + ret = -FM_EPARA; + + FM_UNLOCK(fm_ops_lock); + return ret; +} + +/* + * Force set to stero/mono mode + * @MonoStereo -- 0, auto; 1, mono + * If success, return 0; else error code + */ +signed int fm_monostereo_set(struct fm *fm, signed int ms) +{ + signed int ret = 0; + + if (fm_low_ops.bi.msset == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + ret = fm_low_ops.bi.msset(ms); + + FM_UNLOCK(fm_ops_lock); + return ret; +} + +signed int fm_pamd_get(struct fm *fm, unsigned short *pamd) +{ + signed int ret = 0; + + if (fm_low_ops.bi.pamdget == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (pamd == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + if (fm_low_ops.bi.pamdget(pamd) == false) + ret = -FM_EPARA; + + FM_UNLOCK(fm_ops_lock); + return ret; +} + +signed int fm_caparray_get(struct fm *fm, signed int *ca) +{ + signed int ret = 0; + + if (fm_low_ops.bi.caparray_get == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (ca == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + ret = fm_low_ops.bi.caparray_get(ca); + + FM_UNLOCK(fm_ops_lock); + return ret; +} + +signed int fm_em_test(struct fm *fm, unsigned short group, unsigned short item, unsigned int val) +{ + signed int ret = 0; + + if (fm_low_ops.bi.em == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + if (false == fm_low_ops.bi.em(group, item, val)) + ret = -FM_EPARA; + + FM_UNLOCK(fm_ops_lock); + return ret; +} + +signed int fm_set_search_th(struct fm *fm, struct fm_search_threshold_t parm) +{ + signed int ret = 0; + + if (fm_low_ops.bi.set_search_th == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + ret = fm_low_ops.bi.set_search_th(parm.th_type, parm.th_val, parm.reserve); + + FM_UNLOCK(fm_ops_lock); + return ret; +} + +signed int fm_rds_tx(struct fm *fm, struct fm_rds_tx_parm *parm) +{ + signed int ret = 0; + + if (fm_low_ops.ri.rds_tx == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (fm_pwr_state_get(fm) != FM_PWR_TX_ON) { + parm->err = FM_BADSTATUS; + ret = -FM_EPARA; + goto out; + } + if (parm->other_rds_cnt > 29) { + parm->err = FM_EPARM; + WCN_DBG(FM_ERR | MAIN, "other_rds_cnt=%d\n", parm->other_rds_cnt); + ret = -FM_EPARA; + goto out; + } + + ret = fm_low_ops.ri.rds_tx(parm->pi, parm->ps, parm->other_rds, parm->other_rds_cnt); + if (ret) { + WCN_DBG(FM_ERR | MAIN, "Rds_Tx failed!\n"); + goto out; + } +/* fm_cxt->txcxt.rdsTxOn = true; */ +/* fm_cxt->txcxt.pi = parm->pi; */ +/* memcpy(fm_cxt->txcxt.ps, parm->ps,sizeof(parm->ps)); */ +/* memcpy(fm_cxt->txcxt.other_rds, parm->other_rds,sizeof(parm->other_rds)); */ +/* fm_cxt->txcxt.other_rds_cnt = parm->other_rds_cnt; */ +out: + return ret; +} + +signed int fm_rds_onoff(struct fm *fm, unsigned short rdson_off) +{ + signed int ret = 0; + + if (fm_pwr_state_get(fm) != FM_PWR_RX_ON) { + return -EPERM; + } + if (fm_low_ops.ri.rds_onoff == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + if (rdson_off) { + fm->rds_on = true; + if (fm_low_ops.ri.rds_onoff(fm->pstRDSData, true) == false) { + WCN_DBG(FM_ALT | MAIN, "FM_IOCTL_RDS_ONOFF on faield\n"); + ret = -EPERM; + goto out; + } + + fm_enable_rds_BlerCheck(fm); + } else { + fm->rds_on = false; + fm_disable_rds_BlerCheck(); + if (fm_low_ops.ri.rds_onoff(fm->pstRDSData, false) == false) { + WCN_DBG(FM_ALT | MAIN, "FM_IOCTL_RDS_ONOFF off faield\n"); + ret = -EPERM; + }; + } + +out: + FM_UNLOCK(fm_ops_lock); + return ret; +} + +signed int fm_rds_good_bc_get(struct fm *fm, unsigned short *gbc) +{ + signed int ret = 0; + + if (fm_low_ops.ri.rds_gbc_get == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (gbc == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + *gbc = fm_low_ops.ri.rds_gbc_get(); + + FM_UNLOCK(fm_ops_lock); + return ret; +} + +signed int fm_rds_bad_bc_get(struct fm *fm, unsigned short *bbc) +{ + signed int ret = 0; + + if (fm_low_ops.ri.rds_gbc_get == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (bbc == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + *bbc = fm_low_ops.ri.rds_bbc_get(); + + FM_UNLOCK(fm_ops_lock); + return ret; +} + +signed int fm_rds_bler_ratio_get(struct fm *fm, unsigned short *bbr) +{ + signed int ret = 0; + + if (fm_low_ops.ri.rds_bbr_get == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (bbr == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + *bbr = (unsigned short) fm_low_ops.ri.rds_bbr_get(); + + FM_UNLOCK(fm_ops_lock); + return ret; +} + +signed int fm_rds_group_cnt_get(struct fm *fm, struct rds_group_cnt_t *dst) +{ + signed int ret = 0; + + if (fm_low_ops.ri.rds_gc_get == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (dst == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (FM_LOCK(fm_rds_cnt)) + return -FM_ELOCK; + + ret = fm_low_ops.ri.rds_gc_get(dst, fm->pstRDSData); + + FM_UNLOCK(fm_rds_cnt); + return ret; +} + +signed int fm_rds_group_cnt_reset(struct fm *fm) +{ + signed int ret = 0; + + if (fm_low_ops.ri.rds_gc_reset == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (FM_LOCK(fm_rds_cnt)) + return -FM_ELOCK; + + ret = fm_low_ops.ri.rds_gc_reset(fm->pstRDSData); + + FM_UNLOCK(fm_rds_cnt); + return ret; +} + +signed int fm_rds_log_get(struct fm *fm, struct rds_rx_t *dst, signed int *dst_len) +{ + signed int ret = 0; + + if (fm_low_ops.ri.rds_log_get == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (dst == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (dst_len == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (FM_LOCK(fm_read_lock)) + return -FM_ELOCK; + + ret = fm_low_ops.ri.rds_log_get(dst, dst_len); + + FM_UNLOCK(fm_read_lock); + return ret; +} + +signed int fm_rds_block_cnt_reset(struct fm *fm) +{ + signed int ret = 0; + + if (fm_low_ops.ri.rds_bc_reset == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + ret = fm_low_ops.ri.rds_bc_reset(); + + FM_UNLOCK(fm_ops_lock); + return ret; +} + +signed int fm_i2s_set(struct fm *fm, signed int onoff, signed int mode, signed int sample) +{ + signed int ret = 0; + + if (fm_low_ops.bi.i2s_set == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if ((onoff != 0) && (onoff != 1)) + onoff = 0; /* default set i2s on in case user input illegal.*/ + + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + if ((fm_pwr_state_get(fm) == FM_PWR_RX_ON) || (fm_pwr_state_get(fm) == FM_PWR_TX_ON)) + ret = fm_low_ops.bi.i2s_set(onoff, mode, sample); + if (ret) + WCN_DBG(FM_ALT | MAIN, "i2s setting Failed\n"); + else + WCN_DBG(FM_INF | MAIN, "i2s setting OK!\n"); + + FM_UNLOCK(fm_ops_lock); + return ret; +} + +/* + * fm_tune_tx + */ +signed int fm_tune_tx(struct fm *fm, struct fm_tune_parm *parm) +{ + signed int ret = 0; + + if (fm_low_ops.bi.tune_tx == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + if (fm_pwr_state_get(fm) != FM_PWR_TX_ON) { + parm->err = FM_BADSTATUS; + return -EPERM; + } + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + WCN_DBG(FM_DBG | MAIN, "%s\n", __func__); + + fm_op_state_set(fm, FM_STA_TUNE); + WCN_DBG(FM_NTC | MAIN, "Tx tune to %d\n", parm->freq); + /* tune to desired channel */ + if (true != fm_low_ops.bi.tune_tx(parm->freq)) { + parm->err = FM_TUNE_FAILED; + WCN_DBG(FM_ALT | MAIN, "Tx tune failed\n"); + ret = -EPERM; + } + fm_op_state_set(fm, FM_STA_PLAY); + FM_UNLOCK(fm_ops_lock); + + return ret; +} + +/* + * fm_tune + */ +signed int fm_tune(struct fm *fm, struct fm_tune_parm *parm) +{ + signed int ret = 0; + signed int len = 0; + struct rds_raw_t rds_log; + +#if (FM_INVALID_CHAN_NOISE_REDUCING) + fm_cqi_check_timer->stop(fm_cqi_check_timer); +#endif + + if (fm_low_ops.bi.mute == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (fm_low_ops.bi.rampdown == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (fm_low_ops.bi.setfreq == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + WCN_DBG(FM_INF | MAIN, "%s\n", __func__); + + /* clean RDS first in case RDS event report before tune success */ + /* clean RDS data */ + fm_memset(fm->pstRDSData, 0, sizeof(struct rds_t)); + + /* clean RDS log buffer */ + do { + ret = fm_rds_log_get(fm, (struct rds_rx_t *)&(rds_log.data), &len); + rds_log.dirty = true; + rds_log.len = (len < sizeof(rds_log.data)) ? len : sizeof(rds_log.data); + WCN_DBG(FM_ALT | MAIN, "clean rds log, rds_log.len =%d\n", rds_log.len); + if (ret < 0) + break; + } while (rds_log.len > 0); + + if (fm_pwr_state_get(fm) != FM_PWR_RX_ON) { + parm->err = FM_BADSTATUS; + ret = -EPERM; + goto out; + } +/* fm_low_ops.bi.mute(true); */ + ret = fm_low_ops.bi.rampdown(); + if (ret) { + WCN_DBG(FM_ALT | MAIN, "FM ramp down failed\n"); + goto out; + } + + fm_op_state_set(fm, FM_STA_TUNE); + WCN_DBG(FM_ALT | MAIN, "tuning to %d\n", parm->freq); + + if (true != fm_low_ops.bi.setfreq(parm->freq)) { + parm->err = FM_TUNE_FAILED; + WCN_DBG(FM_ALT | MAIN, "FM tune failed\n"); + ret = -FM_EFW; + } + +#if (FM_INVALID_CHAN_NOISE_REDUCING) + if (fm_low_ops.bi.is_valid_freq) { + if (fm_low_ops.bi.is_valid_freq(parm->freq)) { + if (fm->vol != 15) { + fm_low_ops.bi.volset(15); + fm->vol = 15; + WCN_DBG(FM_NTC | MAIN, "Valid freq, volset: 15\n"); + } + WCN_DBG(FM_NTC | MAIN, "FM tune to a valid channel resume volume.\n"); + } else { + if (fm->vol != 5) { + fm_low_ops.bi.volset(5); + fm->vol = 5; + WCN_DBG(FM_NTC | MAIN, "Not a valid freq, volset: 5\n"); + } + WCN_DBG(FM_NTC | MAIN, "FM tune to an invalid channel.\n"); + fm_cqi_check_timer->start(fm_cqi_check_timer); + } + } +#endif + /* fm_low_ops.bi.mute(false);//open for dbg */ + fm_op_state_set(fm, FM_STA_PLAY); +out: + FM_UNLOCK(fm_ops_lock); + return ret; +} + +/* cqi log tool entry */ +signed int fm_cqi_log(void) +{ + signed int ret = 0; + unsigned short freq; + + if (fm_low_ops.bi.cqi_log == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + freq = fm_cur_freq_get(); + if (fm_get_channel_space(freq) == 0) + freq *= 10; + + if ((freq != 10000) && (g_dbg_level != 0xffffffff)) + return -FM_EPARA; + + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + ret = fm_low_ops.bi.cqi_log(8750, 10800, 2, 5); + FM_UNLOCK(fm_ops_lock); + return ret; +} + +signed int fm_pre_search(struct fm *fm) +{ + signed int ret = 0; + + if (fm_low_ops.bi.pre_search == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (fm_pwr_state_get(fm) != FM_PWR_RX_ON) + return -FM_EPARA; + + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + WCN_DBG(FM_INF | MAIN, "%s\n", __func__); + + ret = fm_low_ops.bi.pre_search(); + FM_UNLOCK(fm_ops_lock); + return ret; +} + +signed int fm_restore_search(struct fm *fm) +{ + signed int ret = 0; + + if (fm_low_ops.bi.restore_search == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (fm_pwr_state_get(fm) != FM_PWR_RX_ON) + return -FM_EPARA; + + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + WCN_DBG(FM_INF | MAIN, "%s\n", __func__); + + ret = fm_low_ops.bi.restore_search(); + FM_UNLOCK(fm_ops_lock); + return ret; +} + +/*fm soft mute tune function*/ +signed int fm_soft_mute_tune(struct fm *fm, struct fm_softmute_tune_t *parm) +{ + signed int ret = 0; + +#if (FM_INVALID_CHAN_NOISE_REDUCING) + fm_cqi_check_timer->stop(fm_cqi_check_timer); +#endif + + if (fm_low_ops.bi.softmute_tune == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + if (fm_pwr_state_get(fm) != FM_PWR_RX_ON) { + parm->valid = false; + ret = -EPERM; + goto out; + } + /* fm_low_ops.bi.mute(true); */ + /* fm_op_state_set(fm, FM_STA_TUNE); */ + + if (false == fm_low_ops.bi.softmute_tune(parm->freq, &parm->rssi, &parm->valid)) { + parm->valid = false; + WCN_DBG(FM_ALT | MAIN, "sm tune failed\n"); + ret = -EPERM; + } +/* fm_low_ops.bi.mute(false); */ + WCN_DBG(FM_INF | MAIN, "%s, freq=%d, rssi=%d, valid=%d\n", __func__, parm->freq, parm->rssi, parm->valid); + +out: + FM_UNLOCK(fm_ops_lock); + + return ret; +} + +signed int fm_over_bt(struct fm *fm, signed int flag) +{ + signed int ret = 0; + + if (fm_low_ops.bi.fm_via_bt == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + if (fm_pwr_state_get(fm) != FM_PWR_RX_ON) + return -EPERM; + + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + ret = fm_low_ops.bi.fm_via_bt(flag); + if (ret) + WCN_DBG(FM_ALT | MAIN, "%s(),failed!\n", __func__); + else + fm->via_bt = flag; + + WCN_DBG(FM_NTC | MAIN, "%s(),[ret=%d]!\n", __func__, ret); + FM_UNLOCK(fm_ops_lock); + return ret; +} + +signed int fm_tx_support(struct fm *fm, signed int *support) +{ + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + if (fm_low_ops.bi.tx_support) + fm_low_ops.bi.tx_support(support); + else + *support = 0; + + WCN_DBG(FM_NTC | MAIN, "%s(),[%d]!\n", __func__, *support); + FM_UNLOCK(fm_ops_lock); + return 0; +} + +signed int fm_rdstx_support(struct fm *fm, signed int *support) +{ + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + + if (fm_low_ops.ri.rdstx_support) + fm_low_ops.ri.rdstx_support(support); + else + *support = 0; + + WCN_DBG(FM_NTC | MAIN, "support=[%d]!\n", *support); + FM_UNLOCK(fm_ops_lock); + return 0; +} + +/*1:on,0:off*/ +signed int fm_rdstx_enable(struct fm *fm, signed int enable) +{ + signed int ret = -1; + + if (fm_low_ops.ri.rds_tx_enable == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (fm_low_ops.ri.rds_tx_disable == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + if (fm_pwr_state_get(fm) != FM_PWR_TX_ON) + return -FM_EPARA; + + if (FM_LOCK(fm_ops_lock)) + return -FM_ELOCK; + if (enable == 1) { + ret = fm_low_ops.ri.rds_tx_enable(); + if (ret) + WCN_DBG(FM_ERR | MAIN, "rds_tx_enable fail=[%d]!\n", ret); + + fm->rdstx_on = true; + } else { + ret = fm_low_ops.ri.rds_tx_disable(); + if (ret) + WCN_DBG(FM_ERR | MAIN, "rds_tx_disable fail=[%d]!\n", ret); + + fm->rdstx_on = false; + } + WCN_DBG(FM_NTC | MAIN, "rds tx enable=[%d]!\n", enable); + FM_UNLOCK(fm_ops_lock); + return 0; +} + +#if KERNEL_VERSION(4, 15, 0) <= LINUX_VERSION_CODE +static void fm_timer_func(struct timer_list *timer) +#else +static void fm_timer_func(unsigned long data) +#endif +{ + struct fm *fm = g_fm_struct; + + if (FM_LOCK(fm_timer_lock)) + return; + + if (fm_timer_sys->update(fm_timer_sys)) { + WCN_DBG(FM_NTC | MAIN, "timer skip\n"); + goto out; /* fm timer is stopped before timeout */ + } + + if (fm != NULL) { + WCN_DBG(FM_DBG | MAIN, "timer:rds_wk\n"); + fm->timer_wkthd->add_work(fm->timer_wkthd, fm->rds_wk); + } + +out: + FM_UNLOCK(fm_timer_lock); +} + +#if (FM_INVALID_CHAN_NOISE_REDUCING) +#if KERNEL_VERSION(4, 15, 0) <= LINUX_VERSION_CODE +static void fm_cqi_check_timer_func(struct timer_list *timer) +#else +static void fm_cqi_check_timer_func(unsigned long data) +#endif +{ + struct fm *fm = g_fm_struct; + + if (FM_LOCK(fm_timer_lock)) + return; + + if (fm_cqi_check_timer->update(fm_cqi_check_timer)) { + WCN_DBG(FM_NTC | MAIN, "timer skip\n"); + goto out; /* fm timer is stopped before timeout */ + } + + if (fm != NULL) { + WCN_DBG(FM_DBG | MAIN, "timer:ch_valid_check_wk\n"); + fm->timer_wkthd->add_work(fm->timer_wkthd, fm->ch_valid_check_wk); + } + +out: + FM_UNLOCK(fm_timer_lock); +} +#endif + +static void fm_tx_power_ctrl_worker_func(struct work_struct *work) +{ + signed int ctrl = 0, ret = 0; + struct fm *fm = g_fm_struct; + + WCN_DBG(FM_NTC | MAIN, "+%s():\n", __func__); + + if (fm_low_ops.bi.tx_pwr_ctrl == NULL) + return; + if (FM_LOCK(fm_rxtx_lock)) + return; + + if (fm_pwr_state_get(fm) != FM_PWR_TX_ON) { + WCN_DBG(FM_ERR | MAIN, "FM is not on TX mode\n"); + goto out; + } + + ctrl = fm->tx_pwr; + WCN_DBG(FM_NTC | MAIN, "tx pwr %ddb\n", ctrl); + ret = fm_low_ops.bi.tx_pwr_ctrl(fm_cur_freq_get(), &ctrl); + if (ret) + WCN_DBG(FM_ERR | MAIN, "tx_pwr_ctrl fail\n"); + +out: + FM_UNLOCK(fm_rxtx_lock); + WCN_DBG(FM_NTC | MAIN, "-%s()\n", __func__); +} + +static void fm_tx_rtc_ctrl_worker_func(struct work_struct *work) +{ + signed int ret = 0; + signed int ctrl = 0; + struct fm_gps_rtc_info rtcInfo; + /* struct timeval curTime; */ + /* struct fm *fm = (struct fm*)fm_cb; */ + unsigned long curTime = 0; + + WCN_DBG(FM_NTC | MAIN, "+%s():\n", __func__); + + if (FM_LOCK(fm_rtc_mutex)) + return; + + if (gps_rtc_info.flag == FM_GPS_RTC_INFO_NEW) { + memcpy(&rtcInfo, &gps_rtc_info, sizeof(struct fm_gps_rtc_info)); + gps_rtc_info.flag = FM_GPS_RTC_INFO_OLD; + FM_UNLOCK(fm_rtc_mutex); + } else { + WCN_DBG(FM_NTC | MAIN, "there's no new rtc drift info\n"); + FM_UNLOCK(fm_rtc_mutex); + goto out; + } + + if (rtcInfo.age > rtcInfo.ageThd) { + WCN_DBG(FM_WAR | MAIN, "age over it's threshlod\n"); + goto out; + } + if ((rtcInfo.drift <= rtcInfo.driftThd) && (rtcInfo.drift >= -rtcInfo.driftThd)) { + WCN_DBG(FM_WAR | MAIN, "drift over it's MIN threshlod\n"); + goto out; + } + + if (rtcInfo.drift > FM_GPS_RTC_DRIFT_MAX) { + WCN_DBG(FM_WAR | MAIN, "drift over it's +MAX threshlod\n"); + rtcInfo.drift = FM_GPS_RTC_DRIFT_MAX; + goto out; + } else if (rtcInfo.drift < -FM_GPS_RTC_DRIFT_MAX) { + WCN_DBG(FM_WAR | MAIN, "drift over it's -MAX threshlod\n"); + rtcInfo.drift = -FM_GPS_RTC_DRIFT_MAX; + goto out; + } + + curTime = jiffies; + if (((long)curTime - (long)rtcInfo.stamp) / HZ > rtcInfo.tvThd.tv_sec) { + WCN_DBG(FM_WAR | MAIN, "time diff over it's threshlod\n"); + goto out; + } + if (fm_low_ops.bi.rtc_drift_ctrl != NULL) { + ctrl = rtcInfo.drift; + WCN_DBG(FM_NTC | MAIN, "RTC_drift_ctrl[0x%08x]\n", ctrl); + + ret = fm_low_ops.bi.rtc_drift_ctrl(fm_cur_freq_get(), &ctrl); + if (ret) + goto out; + } +out: + WCN_DBG(FM_NTC | MAIN, "-%s()\n", __func__); +} + +static void fm_tx_desense_wifi_worker_func(struct work_struct *work) +{ + signed int ret = 0; + signed int ctrl = 0; + struct fm *fm = g_fm_struct; + + WCN_DBG(FM_NTC | MAIN, "+%s():\n", __func__); + + if (FM_LOCK(fm_rxtx_lock)) + return; + + if (fm_pwr_state_get(fm) != FM_PWR_TX_ON) { + WCN_DBG(FM_ERR | MAIN, "FM is not on TX mode\n"); + goto out; + } + + fm_tx_rtc_ctrl_worker_func(0); + + ctrl = fm->vcoon; + if (fm_low_ops.bi.tx_desense_wifi) { + WCN_DBG(FM_NTC | MAIN, "tx_desense_wifi[%d]\n", ctrl); + ret = fm_low_ops.bi.tx_desense_wifi(fm_cur_freq_get(), &ctrl); + if (ret) + WCN_DBG(FM_ERR | MAIN, "tx_desense_wifi fail\n"); + } +out: + FM_UNLOCK(fm_rxtx_lock); + WCN_DBG(FM_NTC | MAIN, "-%s()\n", __func__); +} + +/* +************************************************************************************ +Function: fm_get_gps_rtc_info() + +Description: get GPS RTC drift info, and this function should not block + +Date: 2011/04/10 + +Return Value: success:0, failed: error coe +************************************************************************************ +*/ +signed int fm_get_gps_rtc_info(struct fm_gps_rtc_info *src) +{ + signed int ret = 0; +/* signed int retry_cnt = 0; */ + struct fm_gps_rtc_info *dst = &gps_rtc_info; + + if (src == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (dst == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + if (src->retryCnt > 0) { + dst->retryCnt = src->retryCnt; + WCN_DBG(FM_NTC | MAIN, "%s, new [retryCnt=%d]\n", __func__, dst->retryCnt); + } + if (src->ageThd > 0) { + dst->ageThd = src->ageThd; + WCN_DBG(FM_NTC | MAIN, "%s, new [ageThd=%d]\n", __func__, dst->ageThd); + } + if (src->driftThd > 0) { + dst->driftThd = src->driftThd; + WCN_DBG(FM_NTC | MAIN, "%s, new [driftThd=%d]\n", __func__, dst->driftThd); + } + if (src->tvThd.tv_sec > 0) { + dst->tvThd.tv_sec = src->tvThd.tv_sec; + WCN_DBG(FM_NTC | MAIN, "%s, new [tvThd=%d]\n", __func__, (signed int) dst->tvThd.tv_sec); + } + ret = fm_rtc_mutex->trylock(fm_rtc_mutex, dst->retryCnt); + if (ret) + goto out; + + dst->age = src->age; + dst->drift = src->drift; + dst->stamp = jiffies; /* get curren time stamp */ + dst->flag = FM_GPS_RTC_INFO_NEW; + + FM_UNLOCK(fm_rtc_mutex); + + +out: + return ret; +} + +static void fm_enable_rds_BlerCheck(struct fm *fm) +{ + if (FM_LOCK(fm_timer_lock)) + return; + fm_timer_sys->start(fm_timer_sys); + FM_UNLOCK(fm_timer_lock); + WCN_DBG(FM_INF | MAIN, "enable rds timer ok\n"); +} + +static void fm_disable_rds_BlerCheck(void) +{ + if (FM_LOCK(fm_timer_lock)) + return; + fm_timer_sys->stop(fm_timer_sys); + FM_UNLOCK(fm_timer_lock); + WCN_DBG(FM_INF | MAIN, "stop rds timer ok\n"); +} + +void fm_rds_reset_work_func(struct work_struct *work) +{ + signed int ret = 0; + + if (!fm_low_ops.ri.rds_blercheck) + return; + + if (FM_LOCK(fm_rxtx_lock)) + return; + + if (FM_LOCK(fm_rds_cnt)) + return; + + ret = fm_low_ops.ri.rds_blercheck(g_fm_struct->pstRDSData); + + if (ret || g_fm_struct->pstRDSData->AF_Data.Addr_Cnt || g_fm_struct->pstRDSData->event_status) { + WCN_DBG(FM_NTC | MAIN, "ret=%d, Addr_Cnt=0x%02x, event_status=0x%04x\n", ret, + g_fm_struct->pstRDSData->AF_Data.Addr_Cnt, g_fm_struct->pstRDSData->event_status); + } + /* check af list get,can't use event==af_list because event will clear after read rds every time */ + if (g_fm_struct->pstRDSData->AF_Data.Addr_Cnt == 0xFF) + g_fm_struct->pstRDSData->event_status |= RDS_EVENT_AF; + + if (!ret && g_fm_struct->pstRDSData->event_status) + FM_EVENT_SEND(g_fm_struct->rds_event, FM_RDS_DATA_READY); + + FM_UNLOCK(fm_rds_cnt); + FM_UNLOCK(fm_rxtx_lock); +} + +#if (FM_INVALID_CHAN_NOISE_REDUCING) +void fm_cqi_check_work_func(struct work_struct *work) +{ + struct fm *fm = g_fm_struct; + + if (!fm) + return; + + if (FM_LOCK(fm_ops_lock)) + return; + + if (fm_low_ops.bi.is_valid_freq) { + if (fm_low_ops.bi.is_valid_freq(fm->cur_freq)) { + if (fm->vol != 15) { + fm_low_ops.bi.volset(15); + fm->vol = 15; + WCN_DBG(FM_NTC | MAIN, "Valid freq, volset: 15\n"); + } + } else { + if (fm->vol != 5) { + fm_low_ops.bi.volset(5); + fm->vol = 5; + WCN_DBG(FM_NTC | MAIN, "Not a valid freq, volset: 5\n"); + } + } + } + + FM_UNLOCK(fm_ops_lock); +} +#endif + +void fm_subsys_reset_work_func(struct work_struct *work) +{ + g_dbg_level = 0xffffffff; + if (FM_LOCK(fm_ops_lock)) + return; + + fm_sys_state_set(g_fm_struct, FM_SUBSYS_RST_START); + + if (g_fm_struct->chipon == false) { + WCN_DBG(FM_ALT | MAIN, "chip off no need do recover\n"); + goto out; + } + + /* if whole chip reset, wmt will clear fm-on-flag, and firmware turn fm to off status, + * so no need turn fm off again + */ + if (g_fm_struct->wholechiprst == false) { + fm_low_ops.bi.pwrdownseq(); + /* subsystem power off */ + if (fm_low_ops.bi.pwroff(0)) { + WCN_DBG(FM_ALT | MAIN, "chip off fail\n"); + goto out; + } + } + + /* subsystem power on */ + if (fm_low_ops.bi.pwron(0)) { + WCN_DBG(FM_ALT | MAIN, "chip on fail\n"); + goto out; + } + /* recover context */ + if (g_fm_struct->chipon == false) { + fm_low_ops.bi.pwroff(0); + WCN_DBG(FM_ALT | MAIN, "no need do recover\n"); + goto out; + } + + if (fm_pwr_state_get(g_fm_struct) == FM_PWR_RX_ON) { + fm_low_ops.bi.pwrupseq(&g_fm_struct->chip_id, &g_fm_struct->device_id); + } else { + WCN_DBG(FM_ALT | MAIN, "no need do re-powerup\n"); + goto out; + } + + fm_low_ops.bi.anaswitch(g_fm_struct->ana_type); + + fm_low_ops.bi.setfreq(fm_cur_freq_get()); + + fm_low_ops.bi.volset((unsigned char) g_fm_struct->vol); + + g_fm_struct->mute = 0; + fm_low_ops.bi.mute(g_fm_struct->mute); + + if (fm_low_ops.ri.rds_bci_get) { + fm_timer_sys->init(fm_timer_sys, fm_timer_func, (unsigned long)g_fm_struct, fm_low_ops.ri.rds_bci_get(), + 0); + WCN_DBG(FM_NTC | MAIN, "initial timer ok\n"); + } else { + WCN_DBG(FM_NTC | MAIN, "initial timer fail!!!\n"); + } + +#if (FM_INVALID_CHAN_NOISE_REDUCING) + fm_cqi_check_timer->init(fm_cqi_check_timer, fm_cqi_check_timer_func, + (unsigned long)g_fm_struct, 1000, 0); +#endif + g_fm_struct->rds_on = 1; + fm_low_ops.ri.rds_onoff(g_fm_struct->pstRDSData, g_fm_struct->rds_on); + + WCN_DBG(FM_ALT | MAIN, "recover done\n"); + +out: + fm_sys_state_set(g_fm_struct, FM_SUBSYS_RST_END); + fm_sys_state_set(g_fm_struct, FM_SUBSYS_RST_OFF); + g_fm_struct->wholechiprst = true; + + FM_UNLOCK(fm_ops_lock); + g_dbg_level = 0xfffffff5; +} + +void fm_pwroff_work_func(struct work_struct *work) +{ + fm_powerdown(g_fm_struct, 0); +} + +static void fm_eint_handler(void) +{ + struct fm *fm = g_fm_struct; + + WCN_DBG(FM_DBG | MAIN, "intr occur, ticks:%d\n", jiffies_to_msecs(jiffies)); + + if (fm != NULL) + fm->eint_wkthd->add_work(fm->eint_wkthd, fm->eint_wk); +} + +signed int fm_rds_parser(struct rds_rx_t *rds_raw, signed int rds_size) +{ + struct fm *fm = g_fm_struct; /* (struct fm *)work->data; */ + struct rds_t *pstRDSData = fm->pstRDSData; + + if (FM_LOCK(fm_read_lock)) + return -FM_ELOCK; + /* parsing RDS data */ + fm_low_ops.ri.rds_parser(pstRDSData, rds_raw, rds_size, fm_cur_freq_get); + FM_UNLOCK(fm_read_lock); + + if ((pstRDSData->event_status != 0x0000) && (pstRDSData->event_status != RDS_EVENT_AF_LIST)) { + WCN_DBG(FM_NTC | MAIN, "Notify user to read, [event:0x%04x]\n", pstRDSData->event_status); + FM_EVENT_SEND(fm->rds_event, FM_RDS_DATA_READY); + } + + return 0; +} + +static void fm_eint_work_func(struct work_struct *work) +{ + if (fm_wcn_ops.ei.eint_handler) + fm_wcn_ops.ei.eint_handler(); + /* re-enable eint if need */ + fm_enable_eint(); +} + +static signed int fm_callback_register(struct fm_callback *cb) +{ + if (cb == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + cb->cur_freq_get = fm_cur_freq_get; + cb->cur_freq_set = fm_cur_freq_set; + cb->projectid_get = fm_projectid_get; + return 0; +} + +static signed int fm_ops_register(struct fm_lowlevel_ops *ops) +{ + signed int ret = 0; + + ret = fm_wcn_ops_register(); + if (ret) { + WCN_DBG(FM_ERR | MAIN, "fm_wcn_ops_register fail(%d)\n", ret); + return ret; + } + + ret = fm_callback_register(&ops->cb); + if (ret) { + WCN_DBG(FM_ERR | MAIN, "fm_callback_register fail(%d)\n", ret); + return ret; + } + + if (fm_wcn_ops.ei.low_ops_register) + ret = fm_wcn_ops.ei.low_ops_register(&ops->cb, &ops->bi); + else + ret = -1; + if (ret) { + WCN_DBG(FM_ERR | MAIN, "fm_low_ops_register fail(%d)\n", ret); + return ret; + } + + if (fm_wcn_ops.ei.rds_ops_register) + ret = fm_wcn_ops.ei.rds_ops_register(&ops->bi, &ops->ri); + else + ret = -1; + if (ret) { + WCN_DBG(FM_ERR | MAIN, "rds_ops_register fail(%d)\n", ret); + return ret; + } + + return ret; +} +static signed int fm_callback_unregister(struct fm_callback *cb) +{ + if (cb == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,cb invalid pointer\n", __func__); + return -FM_EPARA; + } + + fm_memset(cb, 0, sizeof(struct fm_callback)); + return 0; +} + +static signed int fm_ops_unregister(struct fm_lowlevel_ops *ops) +{ + signed int ret = 0; + + if (fm_wcn_ops.ei.rds_ops_unregister) + ret = fm_wcn_ops.ei.rds_ops_unregister(&ops->ri); + else + ret = -1; + if (ret) { + WCN_DBG(FM_ERR | MAIN, "fm_rds_ops_unregister fail(%d)\n", ret); + return ret; + } + + if (fm_wcn_ops.ei.low_ops_unregister) + ret = fm_wcn_ops.ei.low_ops_unregister(&ops->bi); + else + ret = -1; + if (ret) { + WCN_DBG(FM_ERR | MAIN, "fm_low_ops_unregister fail(%d)\n", ret); + return ret; + } + + ret = fm_callback_unregister(&ops->cb); + if (ret) { + WCN_DBG(FM_ERR | MAIN, "fm_callback_unregister fail(%d)\n", ret); + return ret; + } + + return ret; +} + +static signed short fm_cust_config_setting(void) +{ + unsigned short chipid = 0; + enum fm_cfg_chip_type type = FM_CHIP_TYPE_MAX; + + if (fm_low_ops.bi.chipid_get) + chipid = fm_low_ops.bi.chipid_get(); + fm_which_chip(chipid, &type); + WCN_DBG(FM_NTC | MAIN, "chipid:0x%x, chip type:%d\n", chipid, type); + + fm_cust_config_chip(chipid, type); + /* init customer config parameter */ + fm_cust_config_setup(NULL); + + return 0; +} + +struct fm *fm_dev_init(unsigned int arg) +{ + signed int ret = 0; + struct fm *fm = NULL; + +/* if (!fm_low_ops.ri.rds_bci_get) */ +/* return NULL; */ + + /* alloc fm main data structure */ + fm = fm_zalloc(sizeof(struct fm)); + if (!fm) { + WCN_DBG(FM_ALT | MAIN, "-ENOMEM\n"); + ret = -ENOMEM; + return NULL; + } + + fm->ref = 0; + fm->chipon = false; + fm_pwr_state_set(fm, FM_PWR_OFF); + /* FM Tx */ + fm->vcoon = FM_TX_VCO_ON_DEFAULT; + fm->vcooff = FM_TX_VCO_OFF_DEFAULT; + fm->txpwrctl = FM_TX_PWR_CTRL_INVAL_DEFAULT; + fm->tx_pwr = FM_TX_PWR_LEVEL_MAX; + fm->wholechiprst = true; + gps_rtc_info.err = 0; + gps_rtc_info.age = 0; + gps_rtc_info.drift = 0; + gps_rtc_info.tv.tv_sec = 0; + gps_rtc_info.tv.tv_usec = 0; + gps_rtc_info.ageThd = FM_GPS_RTC_AGE_TH; + gps_rtc_info.driftThd = FM_GPS_RTC_DRIFT_TH; + gps_rtc_info.tvThd.tv_sec = FM_GPS_RTC_TIME_DIFF_TH; + gps_rtc_info.retryCnt = FM_GPS_RTC_RETRY_CNT; + gps_rtc_info.flag = FM_GPS_RTC_INFO_OLD; + + fm->rds_event = fm_flag_event_create("fm_rds_event"); + if (!fm->rds_event) { + WCN_DBG(FM_ALT | MAIN, "-ENOMEM for RDS event\n"); + ret = -ENOMEM; + goto ERR_EXIT; + } + + fm_flag_event_get(fm->rds_event); + + /* alloc fm rds data structure */ + fm->pstRDSData = fm_zalloc(sizeof(struct rds_t)); + if (!fm->pstRDSData) { + WCN_DBG(FM_ALT | MAIN, "-ENOMEM for RDS\n"); + ret = -ENOMEM; + goto ERR_EXIT; + } + + g_fm_struct = fm; + + fm->timer_wkthd = fm_workthread_create("fm_timer_wq"); + + if (!fm->timer_wkthd) { + WCN_DBG(FM_ALT | MAIN, "-ENOMEM for fm_timer_wq\n"); + ret = -ENOMEM; + goto ERR_EXIT; + } + + fm_workthread_get(fm->timer_wkthd); + + fm->eint_wkthd = fm_workthread_create("fm_eint_wq"); + + if (!fm->eint_wkthd) { + WCN_DBG(FM_ALT | MAIN, "-ENOMEM for fm_eint_wq\n"); + ret = -ENOMEM; + goto ERR_EXIT; + } + + fm_workthread_get(fm->eint_wkthd); + + fm->eint_wk = fm_work_create("fm_eint_work"); + + if (!fm->eint_wk) { + WCN_DBG(FM_ALT | MAIN, "-ENOMEM for eint_wk\n"); + ret = -ENOMEM; + goto ERR_EXIT; + } else { + fm_work_get(fm->eint_wk); + fm->eint_wk->init(fm->eint_wk, fm_eint_work_func, (unsigned long)fm); + } + + /* create reset work */ + fm->rst_wk = fm_work_create("fm_rst_work"); + + if (!fm->rst_wk) { + WCN_DBG(FM_ALT | MAIN, "-ENOMEM for rst_wk\n"); + ret = -ENOMEM; + goto ERR_EXIT; + } else { + fm_work_get(fm->rst_wk); + fm->rst_wk->init(fm->rst_wk, fm_subsys_reset_work_func, (unsigned long)fm); + } + + fm->rds_wk = fm_work_create("fm_rds_work"); + if (!fm->rds_wk) { + WCN_DBG(FM_ALT | MAIN, "-ENOMEM for rds_wk\n"); + ret = -ENOMEM; + goto ERR_EXIT; + } else { + fm_work_get(fm->rds_wk); + fm->rds_wk->init(fm->rds_wk, fm_rds_reset_work_func, (unsigned long)fm); + } + +#if (FM_INVALID_CHAN_NOISE_REDUCING) + fm->ch_valid_check_wk = fm_work_create("fm_ch_valid_check_work"); + if (!fm->ch_valid_check_wk) { + WCN_DBG(FM_ALT | MAIN, "-ENOMEM for ch_valid_check_wk\n"); + ret = -ENOMEM; + goto ERR_EXIT; + } else { + fm_work_get(fm->ch_valid_check_wk); + fm->ch_valid_check_wk->init(fm->ch_valid_check_wk, + fm_cqi_check_work_func, (unsigned long)fm); + } +#endif + + fm->fm_tx_power_ctrl_work = fm_work_create("tx_pwr_ctl_work"); + if (!fm->fm_tx_power_ctrl_work) { + WCN_DBG(FM_ALT | MAIN, "-ENOMEM for tx_pwr_ctl_work\n"); + ret = -ENOMEM; + goto ERR_EXIT; + } else { + fm_work_get(fm->fm_tx_power_ctrl_work); + fm->fm_tx_power_ctrl_work->init(fm->fm_tx_power_ctrl_work, + fm_tx_power_ctrl_worker_func, (unsigned long)fm); + } + + fm->fm_tx_desense_wifi_work = fm_work_create("tx_desen_wifi_work"); + if (!fm->fm_tx_desense_wifi_work) { + WCN_DBG(FM_ALT | MAIN, "-ENOMEM for tx_desen_wifi_work\n"); + ret = -ENOMEM; + goto ERR_EXIT; + } else { + fm_work_get(fm->fm_tx_desense_wifi_work); + fm->fm_tx_desense_wifi_work->init(fm->fm_tx_desense_wifi_work, + fm_tx_desense_wifi_worker_func, (unsigned long)fm); + } + + fm->pwroff_wk = fm_work_create("fm_pwroff_work"); + + if (!fm->pwroff_wk) { + WCN_DBG(FM_ALT | MAIN, "-ENOMEM for pwroff_wk\n"); + ret = -ENOMEM; + goto ERR_EXIT; + } else { + fm_work_get(fm->pwroff_wk); + fm->pwroff_wk->init(fm->pwroff_wk, fm_pwroff_work_func, (unsigned long)fm); + } + + /* fm timer was created in fm_env_setp() */ +/* fm_timer_sys->init(fm_timer_sys, fm_timer_func, (unsigned long)g_fm_struct, fm_low_ops.ri.rds_bci_get(), 0); */ +/* fm_timer_sys->start(fm_timer_sys); */ + fm_cust_config_setting(); + + return g_fm_struct; + +ERR_EXIT: + + if (!fm) { + WCN_DBG(FM_NTC | MAIN, "fm is null\n"); + return NULL; + } + + if (fm->eint_wkthd) { + ret = fm_workthread_put(fm->eint_wkthd); + if (!ret) + fm->eint_wkthd = NULL; + } + + if (fm->timer_wkthd) { + ret = fm_workthread_put(fm->timer_wkthd); + if (!ret) + fm->timer_wkthd = NULL; + } + + if (fm->eint_wk) { + ret = fm_work_put(fm->eint_wk); + if (!ret) + fm->eint_wk = NULL; + } + + if (fm->rds_wk) { + ret = fm_work_put(fm->rds_wk); + if (!ret) + fm->rds_wk = NULL; + } + + if (fm->ch_valid_check_wk) { + ret = fm_work_put(fm->ch_valid_check_wk); + if (!ret) + fm->ch_valid_check_wk = NULL; + } + + if (fm->rst_wk) { + ret = fm_work_put(fm->rst_wk); + if (!ret) + fm->rst_wk = NULL; + } + + if (fm->fm_tx_desense_wifi_work) { + ret = fm_work_put(fm->fm_tx_desense_wifi_work); + if (!ret) + fm->fm_tx_desense_wifi_work = NULL; + } + + if (fm->fm_tx_power_ctrl_work) { + ret = fm_work_put(fm->fm_tx_power_ctrl_work); + if (!ret) + fm->fm_tx_power_ctrl_work = NULL; + } + + if (fm->pwroff_wk) { + ret = fm_work_put(fm->pwroff_wk); + if (!ret) + fm->pwroff_wk = NULL; + } + + if (fm->pstRDSData) { + fm_free(fm->pstRDSData); + fm->pstRDSData = NULL; + } + + fm_free(fm); + g_fm_struct = NULL; + return NULL; +} + +signed int fm_dev_destroy(struct fm *fm) +{ + signed int ret = 0; + + WCN_DBG(FM_DBG | MAIN, "%s\n", __func__); + + fm_timer_sys->stop(fm_timer_sys); +#if (FM_INVALID_CHAN_NOISE_REDUCING) + fm_timer_sys->stop(fm_cqi_check_timer); +#endif + if (!fm) { + WCN_DBG(FM_NTC | MAIN, "fm is null\n"); + return -1; + } + + if (fm->eint_wkthd) { + ret = fm_workthread_put(fm->eint_wkthd); + if (!ret) + fm->eint_wkthd = NULL; + } + + if (fm->timer_wkthd) { + ret = fm_workthread_put(fm->timer_wkthd); + if (!ret) + fm->timer_wkthd = NULL; + } + + if (fm->eint_wk) { + ret = fm_work_put(fm->eint_wk); + if (!ret) + fm->eint_wk = NULL; + } + + if (fm->rds_wk) { + ret = fm_work_put(fm->rds_wk); + if (!ret) + fm->rds_wk = NULL; + } + + if (fm->ch_valid_check_wk) { + ret = fm_work_put(fm->ch_valid_check_wk); + if (!ret) + fm->ch_valid_check_wk = NULL; + } + + if (fm->rst_wk) { + ret = fm_work_put(fm->rst_wk); + if (!ret) + fm->rst_wk = NULL; + } + + if (fm->pwroff_wk) { + ret = fm_work_put(fm->pwroff_wk); + if (!ret) + fm->pwroff_wk = NULL; + } + + if (fm->pstRDSData) { + fm_free(fm->pstRDSData); + fm->pstRDSData = NULL; + } + + if (fm->pstRDSData) { + fm_free(fm->pstRDSData); + fm->pstRDSData = NULL; + } + + fm_flag_event_put(fm->rds_event); + + /* free all memory */ + if (fm) { + fm_free(fm); + fm = NULL; + g_fm_struct = NULL; + } + + return ret; +} + +signed int fm_env_setup(void) +{ + signed int ret = 0; + struct fm_hw_info hwinfo; + + WCN_DBG(FM_NTC | MAIN, "%s\n", __func__); + + ret = fm_ops_register(&fm_low_ops); + if (ret) + return ret; + + WCN_DBG(FM_NTC | MAIN, "fm ops registered\n"); + + + fm_ops_lock = fm_lock_create("ops_lock"); + if (!fm_ops_lock) + return -1; + + fm_read_lock = fm_lock_create("rds_read"); + if (!fm_read_lock) + return -1; + + fm_rds_cnt = fm_lock_create("rds_cnt"); + if (!fm_rds_cnt) + return -1; + + fm_timer_lock = fm_spin_lock_create("timer_lock"); + if (!fm_timer_lock) + return -1; + + fm_rxtx_lock = fm_lock_create("rxtx_lock"); + if (!fm_rxtx_lock) + return -1; + + fm_rtc_mutex = fm_lock_create("rtc_lock"); + if (!fm_rxtx_lock) + return -1; + + fm_wcn_ops.tx_lock = fm_lock_create("tx_lock"); + if (!fm_wcn_ops.tx_lock) + return -1; + + fm_wcn_ops.own_lock = fm_lock_create("own_lock"); + if (!fm_wcn_ops.own_lock) + return -1; + + fm_lock_get(fm_ops_lock); + fm_lock_get(fm_read_lock); + fm_lock_get(fm_rds_cnt); + fm_spin_lock_get(fm_timer_lock); + fm_lock_get(fm_rxtx_lock); + fm_lock_get(fm_rtc_mutex); + fm_lock_get(fm_wcn_ops.tx_lock); + fm_lock_get(fm_wcn_ops.own_lock); + WCN_DBG(FM_NTC | MAIN, "fm locks created\n"); + + fm_timer_sys = fm_timer_create("fm_sys_timer"); + + if (!fm_timer_sys) + return -1; + + fm_timer_get(fm_timer_sys); + +#if (FM_INVALID_CHAN_NOISE_REDUCING) + fm_cqi_check_timer = fm_timer_create("fm_cqi_check_timer"); + if (!fm_cqi_check_timer) + return -1; + fm_timer_get(fm_cqi_check_timer); + fm_cqi_check_timer->init(fm_cqi_check_timer, fm_cqi_check_timer_func, (unsigned long)g_fm_struct, 500, 0); +#endif + + WCN_DBG(FM_NTC | MAIN, "fm timer created\n"); + + ret = fm_link_setup((void *)fm_wholechip_rst_cb); + + if (ret) { + WCN_DBG(FM_ERR | MAIN, "fm link setup Failed\n"); + return -1; + } + + /* this wake_lock is used by legacy project */ + if (fm_low_ops.bi.hwinfo_get) { + ret = fm_low_ops.bi.hwinfo_get(&hwinfo); + if (hwinfo.chip_id < FM_CHIP_CAN_SUSPEND) { + fm_wake_lock = fm_wakelock_create("fm_wakelock"); + if (!fm_wake_lock) { + WCN_DBG(FM_ERR | MAIN, "fm_wakelock_init Failed\n"); + return -1; + } + } else { + fm_wake_lock = NULL; + } + } + + return ret; +} + +signed int fm_env_destroy(void) +{ + signed int ret = 0; + + WCN_DBG(FM_NTC | MAIN, "%s\n", __func__); + + fm_link_release(); + + ret = fm_ops_unregister(&fm_low_ops); + if (ret) + return ret; + + WCN_DBG(FM_NTC | MAIN, "fm ops unregistered\n"); + + ret = fm_lock_put(fm_ops_lock); + if (!ret) + fm_ops_lock = NULL; + + ret = fm_lock_put(fm_read_lock); + if (!ret) + fm_read_lock = NULL; + + ret = fm_lock_put(fm_rds_cnt); + if (!ret) + fm_rds_cnt = NULL; + + ret = fm_spin_lock_put(fm_timer_lock); + if (!ret) + fm_timer_lock = NULL; + + ret = fm_lock_put(fm_rxtx_lock); + if (!ret) + fm_rxtx_lock = NULL; + + ret = fm_lock_put(fm_rtc_mutex); + if (!ret) + fm_rtc_mutex = NULL; + + ret = fm_timer_put(fm_timer_sys); + if (!ret) + fm_timer_sys = NULL; + +#if (FM_INVALID_CHAN_NOISE_REDUCING) + ret = fm_timer_put(fm_cqi_check_timer); + if (!ret) + fm_cqi_check_timer = NULL; +#endif + + ret = fm_lock_put(fm_wcn_ops.tx_lock); + if (!ret) + fm_wcn_ops.tx_lock = NULL; + ret = fm_lock_put(fm_wcn_ops.own_lock); + if (!ret) + fm_wcn_ops.own_lock = NULL; + + if (fm_wake_lock) + fm_wakelock_destroy(fm_wake_lock); + + return ret; +} + +/* + * GetChannelSpace - get the spcace of gived channel + * @freq - value in 760~1080 or 7600~10800 + * + * Return 0, if 760~1080; return 1, if 7600 ~ 10800, else err code < 0 + */ +signed int fm_get_channel_space(signed int freq) +{ + if ((freq >= 640) && (freq <= 1080)) + return 0; + else if ((freq >= 6400) && (freq <= 10800)) + return 1; + else + return -1; +} diff --git a/drivers/misc/mediatek/connectivity/fmradio/core/fm_module.c b/drivers/misc/mediatek/connectivity/fmradio/core/fm_module.c new file mode 100644 index 0000000000000000000000000000000000000000..6bcde0cc36008b4138696bf2bc7dd425b5d2ab35 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/core/fm_module.c @@ -0,0 +1,1690 @@ +/* + * Copyright (C) 2015 MediaTek Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* udelay() */ +#include +#include +#include +#include + +#include "fm_config.h" +#include "fm_main.h" +#include "fm_ioctl.h" + +#define FM_PROC_FILE "fm" + +unsigned int g_dbg_level = 0xfffffff5; /* Debug level of FM */ + +#define FM_NO_LNA_PIN 0xffffffff +unsigned int g_fm_lna_pin_num = FM_NO_LNA_PIN; + +/* fm main data structure */ +static struct fm *g_fm; +/* proc file entry */ +static struct proc_dir_entry *g_fm_proc; + +/* char device interface */ +static signed int fm_cdev_setup(struct fm *fm); +static signed int fm_cdev_destroy(struct fm *fm); + +static long fm_ops_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); +#ifdef CONFIG_COMPAT +static long fm_ops_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); +#endif +static loff_t fm_ops_lseek(struct file *filp, loff_t off, signed int whence); +static ssize_t fm_ops_read(struct file *filp, char *buf, size_t len, loff_t *off); +static signed int fm_ops_open(struct inode *inode, struct file *filp); +static signed int fm_ops_release(struct inode *inode, struct file *filp); +static signed int fm_ops_flush(struct file *filp, fl_owner_t Id); +static const struct file_operations fm_ops = { + .owner = THIS_MODULE, + .unlocked_ioctl = fm_ops_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = fm_ops_compat_ioctl, +#endif + .llseek = fm_ops_lseek, + .read = fm_ops_read, + .open = fm_ops_open, + .release = fm_ops_release, + .flush = fm_ops_flush, +}; + +/* static signed int fm_proc_read(char *page, char **start, off_t off, signed int count, + * signed int *eof, void *data); + */ +static ssize_t fm_proc_read(struct file *file, char __user *buf, size_t count, loff_t *ppos); +static ssize_t fm_proc_write(struct file *file, const char *buffer, size_t count, loff_t *ppos); + +static const struct file_operations fm_proc_ops = { + .owner = THIS_MODULE, + .read = fm_proc_read, + .write = fm_proc_write, +}; + +#ifdef CONFIG_COMPAT +static long fm_ops_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + long ret; + + WCN_DBG(FM_NTC | MAIN, "COMPAT %s---pid(%d)---cmd(0x%08x)---arg(0x%08x)\n", current->comm, + current->pid, cmd, (unsigned int) arg); + + if (!filp->f_op || !filp->f_op->unlocked_ioctl) + return -ENOTTY; + switch (cmd) { + case COMPAT_FM_IOCTL_GET_AUDIO_INFO: { + ret = filp->f_op->unlocked_ioctl(filp, FM_IOCTL_GET_AUDIO_INFO, arg); + break; + } + default: + ret = filp->f_op->unlocked_ioctl(filp, ((cmd & 0xFF) | (FM_IOCTL_POWERUP & 0xFFFFFF00)), arg); + break; + } + return ret; +} +#endif + +static long fm_ops_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + signed int ret = 0; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) + struct fm_platform *plat = container_of(filp->f_path.dentry->d_inode->i_cdev, struct fm_platform, cdev); +#else + struct fm_platform *plat = container_of(filp->f_dentry->d_inode->i_cdev, struct fm_platform, cdev); +#endif + struct fm *fm = container_of(plat, struct fm, platform); + + WCN_DBG(FM_INF | MAIN, "%s---pid(%d)---cmd(0x%08x)---arg(0x%08x)\n", current->comm, + current->pid, cmd, (unsigned int) arg); + + if (fm_sys_state_get(fm) != FM_SUBSYS_RST_OFF) { + WCN_DBG(FM_ALT | MAIN, "FM subsys is resetting, retry later\n"); + ret = -FM_ESRST; + return ret; + } + + switch (cmd) { + case FM_IOCTL_POWERUP:{ + struct fm_tune_parm parm; + + WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_POWERUP:0\n"); + if (copy_from_user(&parm, (void *)arg, sizeof(struct fm_tune_parm))) { + ret = -EFAULT; + goto out; + } + + if (parm.freq <= 0 || parm.freq > FM_FREQ_MAX) { + struct fm_tune_parm_old *old_parm = + (struct fm_tune_parm_old *)&parm; + + if (old_parm->freq > 0 && old_parm->freq <= FM_FREQ_MAX) { + WCN_DBG(FM_WAR | MAIN, + "convert to old version fm_tune_parm [%u]->[%u]\n", + parm.freq, old_parm->freq); + parm.freq = old_parm->freq; + parm.deemphasis = 0; + } + } + + if (parm.deemphasis == 1) + fm_config.rx_cfg.deemphasis = 1; + else + fm_config.rx_cfg.deemphasis = 0; + + if (g_fm_lna_pin_num == FM_NO_LNA_PIN) { + WCN_DBG(FM_NTC | MAIN, "%s: no fm lna\n", __func__); + } else { + gpio_set_value(g_fm_lna_pin_num, 1); + WCN_DBG(FM_NTC | MAIN, "%s: gpio_set_value %d: 1\n", + __func__, g_fm_lna_pin_num); + } + + ret = fm_powerup(fm, &parm); + if (ret < 0) { + WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_POWERUP:fail in fm_powerup, return\n"); + goto out; + } + ret = fm_tune(fm, &parm); + if (ret < 0) { + WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_POWERUP:fail in fm_tune, return\n"); + goto out; + } + + if (copy_to_user((void *)arg, &parm, sizeof(struct fm_tune_parm))) { + ret = -EFAULT; + goto out; + } + WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_POWERUP:1\n"); + + break; + } + + case FM_IOCTL_POWERDOWN:{ + int powerdwn_type = 0; + + WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_POWERDOWN:0\n"); + + if (copy_from_user(&powerdwn_type, (void *)arg, sizeof(int))) { + ret = -EFAULT; + goto out; + } + + if (g_fm_lna_pin_num == FM_NO_LNA_PIN) { + WCN_DBG(FM_NTC | MAIN, "%s: no fm lna\n", __func__); + } else { + gpio_set_value(g_fm_lna_pin_num, 0); + WCN_DBG(FM_NTC | MAIN, "%s: gpio_set_value %d: 0\n", + __func__, g_fm_lna_pin_num); + } + + ret = fm_powerdown(fm, powerdwn_type); /* 0: RX 1: TX */ + WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_POWERDOWN:1\n"); + break; + } + + case FM_IOCTL_TUNE:{ + struct fm_tune_parm parm; + + WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_TUNE:0\n"); + + if (copy_from_user(&parm, (void *)arg, sizeof(struct fm_tune_parm))) { + ret = -EFAULT; + goto out; + } + + if (parm.freq <= 0 || parm.freq > FM_FREQ_MAX) { + struct fm_tune_parm_old *old_parm = + (struct fm_tune_parm_old *)&parm; + + if (old_parm->freq > 0 && old_parm->freq <= FM_FREQ_MAX) { + WCN_DBG(FM_WAR | MAIN, + "convert to old version fm_tune_parm [%u]->[%u]\n", + parm.freq, old_parm->freq); + parm.freq = old_parm->freq; + parm.deemphasis = 0; + } + } + + ret = fm_tune(fm, &parm); + if (ret < 0) + goto out; + + if (copy_to_user((void *)arg, &parm, sizeof(struct fm_tune_parm))) { + ret = -EFAULT; + goto out; + } + + WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_TUNE:1\n"); + break; + } + + case FM_IOCTL_SOFT_MUTE_TUNE: + { + struct fm_softmute_tune_t parm; + + fm_cqi_log(); /* cqi log tool */ + if (copy_from_user(&parm, (void *)arg, sizeof(struct fm_softmute_tune_t))) { + ret = -EFAULT; + goto out; + } + + ret = fm_soft_mute_tune(fm, &parm); + if (ret < 0) + goto out; + + if (copy_to_user((void *)arg, &parm, sizeof(struct fm_softmute_tune_t))) { + ret = -EFAULT; + goto out; + } + break; + } + case FM_IOCTL_PRE_SEARCH: + { + ret = fm_pre_search(fm); + break; + } + case FM_IOCTL_RESTORE_SEARCH: + { + ret = fm_restore_search(fm); + break; + } + case FM_IOCTL_CQI_GET:{ + struct fm_cqi_req cqi_req; + signed char *buf = NULL; + signed int tmp; + unsigned int cpy_size = 0; + + WCN_DBG(FM_INF | MAIN, "FM_IOCTL_CQI_GET\n"); + + if (copy_from_user(&cqi_req, (void *)arg, sizeof(struct fm_cqi_req))) { + WCN_DBG(FM_ALT | MAIN, "copy_from_user failed\n"); + ret = -EFAULT; + goto out; + } + + if ((cqi_req.ch_num * sizeof(struct fm_cqi) > cqi_req.buf_size) + || !cqi_req.cqi_buf) { + ret = -FM_EPARA; + goto out; + } + + tmp = cqi_req.ch_num / 16 + ((cqi_req.ch_num % 16) ? 1 : 0); + tmp = tmp * 16 * sizeof(struct fm_cqi); + buf = fm_zalloc(tmp); + + if (!buf) { + ret = -FM_ENOMEM; + goto out; + } + + ret = fm_cqi_get(fm, cqi_req.ch_num, buf, tmp); + + if (ret) { + fm_free(buf); + WCN_DBG(FM_ALT | MAIN, "get cqi failed\n"); + goto out; + } + + cpy_size = cqi_req.ch_num * sizeof(struct fm_cqi); + if (cpy_size > tmp) + cpy_size = tmp; + if (copy_to_user((void *)cqi_req.cqi_buf, buf, cpy_size)) { + fm_free(buf); + ret = -EFAULT; + goto out; + } + + fm_free(buf); + break; + } + + case FM_IOCTL_GET_HW_INFO:{ + struct fm_hw_info info; + + WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_GET_HW_INFO\n"); + + ret = fm_get_hw_info(fm, &info); + + if (ret) { + WCN_DBG(FM_ALT | MAIN, "get hw info failed\n"); + goto out; + } + + if (copy_to_user((void *)arg, &info, sizeof(struct fm_hw_info))) { + ret = -EFAULT; + goto out; + } + + break; + } + + case FM_IOCTL_GET_I2S_INFO:{ + struct fm_i2s_info i2sinfo; + + WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_GET_I2S_INFO\n"); + + ret = fm_get_i2s_info(fm, &i2sinfo); + + if (ret) { + WCN_DBG(FM_ALT | MAIN, "get i2s info failed\n"); + goto out; + } + + if (copy_to_user((void *)arg, &i2sinfo, sizeof(struct fm_i2s_info))) { + ret = -EFAULT; + goto out; + } + + break; + } + + case FM_IOCTL_SETVOL:{ + unsigned int vol; + + WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_SETVOL start\n"); + if (copy_from_user(&vol, (void *)arg, sizeof(unsigned int))) { + WCN_DBG(FM_ALT | MAIN, "copy_from_user failed\n"); + ret = -EFAULT; + goto out; + } + + ret = fm_setvol(fm, vol); + WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_SETVOL end:%d\n", vol); + break; + } + case FM_IOCTL_GETVOL:{ + unsigned int vol; + + WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_GETVOL start\n"); + ret = fm_getvol(fm, &vol); + if (ret < 0) + goto out; + + if (copy_to_user((void *)arg, &vol, sizeof(unsigned int))) { + ret = -EFAULT; + goto out; + } + + WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_GETVOL end=%d\n", vol); + break; + } + + case FM_IOCTL_MUTE:{ + unsigned int bmute; + + if (copy_from_user(&bmute, (void *)arg, sizeof(unsigned int))) { + ret = -EFAULT; + goto out; + } + + ret = fm_mute(fm, bmute); + WCN_DBG(FM_INF | MAIN, "FM_IOCTL_MUTE end-%d\n", bmute); + break; + } + + case FM_IOCTL_GETRSSI:{ + signed int rssi = 0; + + ret = fm_getrssi(fm, &rssi); + if (ret < 0) + goto out; + + if (copy_to_user((void *)arg, &rssi, sizeof(signed int))) { + ret = -EFAULT; + goto out; + } + + WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_GETRSSI:%d\n", rssi); + break; + } + + case FM_IOCTL_RW_REG:{ + struct fm_ctl_parm parm_ctl; + + WCN_DBG(FM_INF | MAIN, "FM_IOCTL_RW_REG\n"); + if (fm->chipon == false || fm_pwr_state_get(fm) == FM_PWR_OFF) { + WCN_DBG(FM_ERR | MAIN, "ERROR, FM chip is OFF\n"); + ret = -EFAULT; + goto out; + } + + if (copy_from_user(&parm_ctl, (void *)arg, sizeof(struct fm_ctl_parm))) { + WCN_DBG(FM_ALT | MAIN, "copy from user error\n"); + ret = -EFAULT; + goto out; + } + + if (parm_ctl.rw_flag == 0) + ret = fm_write(fm, parm_ctl.addr, parm_ctl.val); + else + ret = fm_read(fm, parm_ctl.addr, &parm_ctl.val); + + if (ret < 0) + goto out; + + if ((parm_ctl.rw_flag == 0x01) && (!ret)) { + if (copy_to_user((void *)arg, &parm_ctl, sizeof(struct fm_ctl_parm))) { + ret = -EFAULT; + goto out; + } + } + + break; + } + case FM_IOCTL_TOP_RDWR: + { + struct fm_top_rw_parm parm_ctl; + + WCN_DBG(FM_INF | MAIN, "FM_IOCTL_TOP_RDWR\n"); + +#ifdef CONFIG_MTK_USER_BUILD + WCN_DBG(FM_ERR | MAIN, "Not support FM_IOCTL_TOP_RDWR\n"); + ret = -EFAULT; + goto out; +#endif + + if (g_dbg_level != 0xfffffff7) { + WCN_DBG(FM_ERR | MAIN, "Not support FM_IOCTL_TOP_RDWR\n"); + ret = -EFAULT; + goto out; + } + + if (fm->chipon == false || fm_pwr_state_get(fm) == FM_PWR_OFF) { + WCN_DBG(FM_ERR | MAIN, "ERROR, FM chip is OFF\n"); + ret = -EFAULT; + goto out; + } + + if (copy_from_user(&parm_ctl, (void *)arg, sizeof(struct fm_top_rw_parm))) { + WCN_DBG(FM_ALT | MAIN, "copy from user error\n"); + ret = -EFAULT; + goto out; + } + + if (parm_ctl.rw_flag == 0) + ret = fm_top_write(fm, parm_ctl.addr, parm_ctl.val); + else + ret = fm_top_read(fm, parm_ctl.addr, &parm_ctl.val); + + if (ret < 0) + goto out; + + if ((parm_ctl.rw_flag == 0x01) && (!ret)) { + if (copy_to_user((void *)arg, &parm_ctl, sizeof(struct fm_top_rw_parm))) { + ret = -EFAULT; + goto out; + } + } + + break; + } + case FM_IOCTL_HOST_RDWR: + { + struct fm_host_rw_parm parm_ctl; + + WCN_DBG(FM_INF | MAIN, "FM_IOCTL_HOST_RDWR\n"); + +#ifdef CONFIG_MTK_USER_BUILD + WCN_DBG(FM_ERR | MAIN, "Not support FM_IOCTL_HOST_RDWR\n"); + ret = -EFAULT; + goto out; +#endif + + if (g_dbg_level != 0xfffffff7) { + WCN_DBG(FM_ERR | MAIN, "Not support FM_IOCTL_HOST_RDWR\n"); + ret = -EFAULT; + goto out; + } + + if (fm->chipon == false || fm_pwr_state_get(fm) == FM_PWR_OFF) { + WCN_DBG(FM_ERR | MAIN, "ERROR, FM chip is OFF\n"); + ret = -EFAULT; + goto out; + } + + if (copy_from_user(&parm_ctl, (void *)arg, sizeof(struct fm_host_rw_parm))) { + WCN_DBG(FM_ALT | MAIN, "copy from user error\n"); + ret = -EFAULT; + goto out; + } + + /* 4 bytes alignment and illegal address */ + if (parm_ctl.addr % 4 != 0 || parm_ctl.addr >= 0x90000000) { + ret = -FM_EPARA; + goto out; + } + WCN_DBG(FM_NTC | MAIN, "rw? (%d), addr: %x\n", parm_ctl.rw_flag, parm_ctl.addr); + if (parm_ctl.rw_flag == 0) + ret = fm_host_write(fm, parm_ctl.addr, parm_ctl.val); + else + ret = fm_host_read(fm, parm_ctl.addr, &parm_ctl.val); + + if (ret < 0) + goto out; + + if ((parm_ctl.rw_flag == 0x01) && (!ret)) { + if (copy_to_user((void *)arg, &parm_ctl, sizeof(struct fm_host_rw_parm))) { + ret = -EFAULT; + goto out; + } + } + + break; + } + case FM_IOCTL_PMIC_RDWR: + { + struct fm_pmic_rw_parm parm_ctl; + + WCN_DBG(FM_INF | MAIN, "FM_IOCTL_PMIC_RDWR\n"); + if (fm->chipon == false || fm_pwr_state_get(fm) == FM_PWR_OFF) { + WCN_DBG(FM_ERR | MAIN, "ERROR, FM chip is OFF\n"); + ret = -EFAULT; + goto out; + } + + if (copy_from_user(&parm_ctl, (void *)arg, sizeof(struct fm_pmic_rw_parm))) { + WCN_DBG(FM_ALT | MAIN, "copy from user error\n"); + ret = -EFAULT; + goto out; + } + + if (parm_ctl.rw_flag == 0) + ret = fm_pmic_write(fm, parm_ctl.addr, parm_ctl.val); + else + ret = fm_pmic_read(fm, parm_ctl.addr, &parm_ctl.val); + + if (ret < 0) + goto out; + + if ((parm_ctl.rw_flag == 0x01) && (!ret)) { + if (copy_to_user((void *)arg, &parm_ctl, sizeof(struct fm_pmic_rw_parm))) { + ret = -EFAULT; + goto out; + } + } + + break; + } + case FM_IOCTL_GETCHIPID:{ + unsigned short chipid = 0; + + ret = fm_chipid_get(fm, &chipid); + WCN_DBG(FM_INF | MAIN, "FM_IOCTL_GETCHIPID:%04x\n", chipid); + if (ret < 0) + goto out; + + if (copy_to_user((void *)arg, &chipid, sizeof(unsigned short))) { + ret = -EFAULT; + goto out; + } + break; + } + + case FM_IOCTL_GETMONOSTERO:{ + unsigned short usStereoMono = 0; + + ret = fm_monostereo_get(fm, &usStereoMono); + WCN_DBG(FM_INF | MAIN, "FM_IOCTL_GETMONOSTERO:%04x\n", usStereoMono); + if (ret < 0) + goto out; + + if (copy_to_user((void *)arg, &usStereoMono, sizeof(unsigned short))) { + ret = -EFAULT; + goto out; + } + break; + } + + case FM_IOCTL_SETMONOSTERO:{ + signed int monostero; + + WCN_DBG(FM_INF | MAIN, "FM_IOCTL_SETMONOSTERO\n"); + if (copy_from_user(&monostero, (void *)arg, sizeof(signed int))) { + WCN_DBG(FM_ALT | MAIN, "copy from user error\n"); + ret = -EFAULT; + goto out; + } + ret = fm_monostereo_set(fm, monostero); + break; + } + + case FM_IOCTL_GETCURPAMD:{ + unsigned short PamdLevl = 0; + + ret = fm_pamd_get(fm, &PamdLevl); + WCN_DBG(FM_INF | MAIN, "FM_IOCTL_GETCURPAMD:%d\n", PamdLevl); + if (ret < 0) + goto out; + + if (copy_to_user((void *)arg, &PamdLevl, sizeof(unsigned short))) + ret = -EFAULT; + goto out; + + break; + } + + case FM_IOCTL_GETCAPARRAY:{ + signed int ca = 0; + + ret = fm_caparray_get(fm, &ca); + WCN_DBG(FM_INF | MAIN, "FM_IOCTL_GETCAPARRAY:%d\n", ca); + if (ret < 0) + goto out; + + if (copy_to_user((void *)arg, &ca, sizeof(signed int))) { + ret = -EFAULT; + goto out; + } + break; + } + + case FM_IOCTL_EM_TEST:{ + struct fm_em_parm parm_em; + + WCN_DBG(FM_DBG | MAIN, "FM_IOCTL_EM_TEST\n"); + + if (copy_from_user(&parm_em, (void *)arg, sizeof(struct fm_em_parm))) { + ret = -EFAULT; + goto out; + } + ret = fm_em_test(fm, parm_em.group_idx, parm_em.item_idx, parm_em.item_value); + break; + } + + case FM_IOCTL_RDS_SUPPORT:{ + signed int support = FM_RDS_ENABLE; + + WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_RDS_SUPPORT\n"); + + if (copy_to_user((void *)arg, &support, sizeof(signed int))) { + ret = -EFAULT; + goto out; + } + break; + } + + case FM_IOCTL_IS_FM_POWERED_UP:{ + unsigned int powerup; + + WCN_DBG(FM_DBG | MAIN, "FM_IOCTL_IS_FM_POWERED_UP"); + + if (fm->chipon && fm_pwr_state_get(fm)) + powerup = 1; + else + powerup = 0; + + if (copy_to_user((void *)arg, &powerup, sizeof(unsigned int))) { + ret = -EFAULT; + goto out; + } + break; + } + + case FM_IOCTL_FM_SET_STATUS:{ + struct fm_status_t fm_stat; + + WCN_DBG(FM_DBG | MAIN, "FM_IOCTL_FM_SET_STATUS"); + + if (copy_from_user(&fm_stat, (void *)arg, sizeof(struct fm_status_t))) { + ret = -EFAULT; + goto out; + } + + fm_set_stat(fm, fm_stat.which, fm_stat.stat); + + break; + } + + case FM_IOCTL_FM_GET_STATUS:{ + struct fm_status_t fm_stat; + + WCN_DBG(FM_DBG | MAIN, "FM_IOCTL_FM_GET_STATUS"); + + if (copy_from_user(&fm_stat, (void *)arg, sizeof(struct fm_status_t))) { + ret = -EFAULT; + goto out; + } + + fm_get_stat(fm, fm_stat.which, &fm_stat.stat); + + if (copy_to_user((void *)arg, &fm_stat, sizeof(struct fm_status_t))) { + ret = -EFAULT; + goto out; + } + + break; + } + + case FM_IOCTL_RDS_ONOFF:{ + unsigned short rdson_off = 0; + + WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_RDS_ONOFF start\n"); + + if (copy_from_user(&rdson_off, (void *)arg, sizeof(unsigned short))) { + ret = -EFAULT; + goto out; + } + ret = fm_rds_onoff(fm, rdson_off); + WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_RDS_ONOFF end:%d\n", rdson_off); + break; + } + + case FM_IOCTL_GETGOODBCNT:{ + unsigned short uGBLCNT = 0; + + ret = fm_rds_good_bc_get(fm, &uGBLCNT); + WCN_DBG(FM_DBG | MAIN, "FM_IOCTL_GETGOODBCNT:%d\n", uGBLCNT); + if (ret < 0) + goto out; + + if (copy_to_user((void *)arg, &uGBLCNT, sizeof(unsigned short))) { + ret = -EFAULT; + goto out; + } + break; + } + + case FM_IOCTL_GETBADBNT:{ + unsigned short uBadBLCNT = 0; + + ret = fm_rds_bad_bc_get(fm, &uBadBLCNT); + WCN_DBG(FM_DBG | MAIN, "FM_IOCTL_GETBADBNT:%d\n", uBadBLCNT); + if (ret < 0) + goto out; + + if (copy_to_user((void *)arg, &uBadBLCNT, sizeof(unsigned short))) { + ret = -EFAULT; + goto out; + } + break; + } + + case FM_IOCTL_GETBLERRATIO:{ + unsigned short uBlerRatio = 0; + + ret = fm_rds_bler_ratio_get(fm, &uBlerRatio); + WCN_DBG(FM_DBG | MAIN, "FM_IOCTL_GETBLERRATIO:%d\n", uBlerRatio); + if (ret < 0) + goto out; + + if (copy_to_user((void *)arg, &uBlerRatio, sizeof(unsigned short))) { + ret = -EFAULT; + goto out; + } + break; + } + + case FM_IOCTL_ANA_SWITCH:{ + signed int antenna = -1; + + WCN_DBG(FM_DBG | MAIN, "FM_IOCTL_ANA_SWITCH\n"); + + if (copy_from_user(&antenna, (void *)arg, sizeof(signed int))) { + WCN_DBG(FM_ALT | MAIN, "copy from user error\n"); + ret = -EFAULT; + goto out; + } + + ret = fm_ana_switch(fm, antenna); + break; + } + + case FM_IOCTL_RDS_GROUPCNT:{ + struct rds_group_cnt_req_t gc_req; + + WCN_DBG(FM_DBG | MAIN, "......FM_IOCTL_RDS_GROUPCNT......\n"); + + if (copy_from_user(&gc_req, (void *)arg, sizeof(struct rds_group_cnt_req_t))) { + WCN_DBG(FM_ALT | MAIN, "copy_from_user error\n"); + ret = -EFAULT; + goto out; + } + /* handle group counter request */ + switch (gc_req.op) { + case RDS_GROUP_CNT_READ: + ret = fm_rds_group_cnt_get(fm, &gc_req.gc); + break; + case RDS_GROUP_CNT_WRITE: + break; + case RDS_GROUP_CNT_RESET: + ret = fm_rds_group_cnt_reset(fm); + break; + default: + break; + } + + if (copy_to_user((void *)arg, &gc_req, sizeof(struct rds_group_cnt_req_t))) { + WCN_DBG(FM_ALT | MAIN, "copy_to_user error\n"); + ret = -EFAULT; + goto out; + } + + break; + } + + case FM_IOCTL_RDS_GET_LOG:{ + struct rds_raw_t rds_log; + signed int len = 0; + + memset(rds_log.data, 0, sizeof(rds_log.data)); + WCN_DBG(FM_DBG | MAIN, "......FM_IOCTL_RDS_GET_LOG......\n"); + /* fetch a record form RDS log buffer */ + ret = fm_rds_log_get(fm, (struct rds_rx_t *)&(rds_log.data), &len); + rds_log.dirty = true; + rds_log.len = (len < sizeof(rds_log.data)) ? len : sizeof(rds_log.data); + if (ret < 0) + goto out; + + if (copy_to_user((void *)arg, &rds_log, rds_log.len + 2 * sizeof(signed int))) { + WCN_DBG(FM_ALT | MAIN, "copy_to_user error\n"); + ret = -EFAULT; + goto out; + } + + break; + } + + case FM_IOCTL_RDS_BC_RST:{ + WCN_DBG(FM_DBG | MAIN, "FM_IOCTL_RDS_BC_RST\n"); + ret = fm_rds_block_cnt_reset(fm); + break; + } + + case FM_IOCTL_I2S_SETTING:{ + struct fm_i2s_setting i2s_cfg; + + WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_I2S_SETTING\n"); + + if (copy_from_user(&i2s_cfg, (void *)arg, sizeof(struct fm_i2s_setting))) { + WCN_DBG(FM_ALT | MAIN, "i2s set, copy_from_user err\n"); + ret = -EFAULT; + goto out; + } + + ret = fm_i2s_set(fm, i2s_cfg.onoff, i2s_cfg.mode, i2s_cfg.sample); + + if (ret) { + WCN_DBG(FM_ALT | MAIN, "Set i2s err\n"); + goto out; + } + + break; + } + + case FM_IOCTL_IS_DESE_CHAN:{ + signed int tmp; + + WCN_DBG(FM_INF | MAIN, "FM_IOCTL_IS_DESE_CHAN\n"); + + if (copy_from_user(&tmp, (void *)arg, sizeof(signed int))) { + WCN_DBG(FM_ALT | MAIN, "is dese chan, copy_from_user err\n"); + ret = -EFAULT; + goto out; + } + + tmp = fm_is_dese_chan(fm, (unsigned short) tmp); + + if (copy_to_user((void *)arg, &tmp, sizeof(signed int))) { + WCN_DBG(FM_ALT | MAIN, "is dese chan, copy_to_user err\n"); + ret = -EFAULT; + goto out; + } + + break; + } + case FM_IOCTL_DESENSE_CHECK: + { + struct fm_desense_check_t tmp; + + WCN_DBG(FM_INF | MAIN, "FM_IOCTL_DESENSE_CHECK\n"); + + if (copy_from_user(&tmp, (void *)arg, sizeof(struct fm_desense_check_t))) { + WCN_DBG(FM_ALT | MAIN, "desene check, copy_from_user err\n"); + ret = -EFAULT; + goto out; + } + ret = fm_desense_check(fm, (unsigned short) tmp.freq, tmp.rssi); + + /*if (copy_to_user((void*)arg, &tmp, sizeof(struct fm_desense_check_t))) { + * WCN_DBG(FM_ALT | MAIN, "desene check, copy_to_user err\n"); + * ret = -EFAULT; + * goto out; + * } + */ + + break; + } + case FM_IOCTL_SCAN_GETRSSI: + { + WCN_DBG(FM_ALT | MAIN, "FM_IOCTL_SCAN_GETRSSI:not support\n"); + break; + } + + case FM_IOCTL_DUMP_REG: + { + WCN_DBG(FM_NTC | MAIN, "......FM_IOCTL_DUMP_REG......\n"); + if (g_dbg_level != 0xfffffff7) { + WCN_DBG(FM_ERR | MAIN, "Not support FM_IOCTL_HOST_RDWR\n"); + ret = -EFAULT; + goto out; + } + if (fm->chipon == false || fm_pwr_state_get(fm) == FM_PWR_OFF) { + WCN_DBG(FM_ERR | MAIN, "ERROR, FM chip is OFF\n"); + ret = -EFAULT; + goto out; + } + ret = fm_dump_reg(); + if (ret) + WCN_DBG(FM_ALT | MAIN, "fm_dump_reg err\n"); + break; + } + case FM_IOCTL_GPS_RTC_DRIFT:{ + struct fm_gps_rtc_info rtc_info; + + WCN_DBG(FM_NTC | MAIN, "......FM_IOCTL_GPS_RTC_DRIFT......\n"); + + if (false == fm->chipon) { + WCN_DBG(FM_ERR | MAIN, "ERROR, FM chip is OFF\n"); + ret = -EFAULT; + goto out; + } + if (copy_from_user(&rtc_info, (void *)arg, sizeof(struct fm_gps_rtc_info))) { + WCN_DBG(FM_ERR | MAIN, "copy_from_user error\n"); + ret = -EFAULT; + goto out; + } + + ret = fm_get_gps_rtc_info(&rtc_info); + if (ret) { + WCN_DBG(FM_ERR | MAIN, "fm_get_gps_rtc_info error\n"); + goto out; + } + break; + } + case FM_IOCTL_OVER_BT_ENABLE: + { + signed int fm_via_bt = -1; + + WCN_DBG(FM_NTC | MAIN, "......FM_IOCTL_OVER_BT_ENABLE......\n"); + + if (copy_from_user(&fm_via_bt, (void *)arg, sizeof(int32_t))) { + WCN_DBG(FM_ERR | MAIN, "copy_from_user error\n"); + ret = -EFAULT; + goto out; + } + + ret = fm_over_bt(fm, fm_via_bt); + if (ret) + WCN_DBG(FM_ERR | MAIN, "fm_over_bt err\n"); + break; + } + + case FM_IOCTL_SET_SEARCH_THRESHOLD: + { + struct fm_search_threshold_t parm; + + WCN_DBG(FM_NTC | MAIN, "......FM_IOCTL_SET_SEARCH_THRESHOLD......\n"); + + if (copy_from_user(&parm, (void *)arg, sizeof(struct fm_search_threshold_t))) { + WCN_DBG(FM_ALT | MAIN, "copy_from_user error\n"); + ret = -EFAULT; + goto out; + } + ret = fm_set_search_th(fm, parm); + if (ret < 0) + WCN_DBG(FM_ERR | MAIN, "FM_IOCTL_SET_SEARCH_THRESHOLD not supported\n"); + break; + } + case FM_IOCTL_GET_AUDIO_INFO: + { + struct fm_audio_info_t aud_data; + + ret = fm_get_aud_info(&aud_data); + if (ret) + WCN_DBG(FM_ERR | MAIN, "fm_get_aud_info err\n"); + + if (copy_to_user((void *)arg, &aud_data, sizeof(struct fm_audio_info_t))) { + WCN_DBG(FM_ERR | MAIN, "copy_to_user error\n"); + ret = -EFAULT; + goto out; + } + + WCN_DBG(FM_INF | MAIN, "fm_get_aud_info ret=%d\n", ret); + break; + } + /***************************FM Tx function************************************/ + case FM_IOCTL_TX_SUPPORT: + { + signed int tx_support = -1; + + WCN_DBG(FM_NTC | MAIN, "......FM_IOCTL_TX_SUPPORT......\n"); + + ret = fm_tx_support(fm, &tx_support); + if (ret) + WCN_DBG(FM_ERR | MAIN, "fm_tx_support err\n"); + + if (copy_to_user((void *)arg, &tx_support, sizeof(signed int))) { + WCN_DBG(FM_ERR | MAIN, "copy_to_user error\n"); + ret = -EFAULT; + goto out; + } + break; + } + case FM_IOCTL_POWERUP_TX: + { + struct fm_tune_parm parm; + + WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_POWERUP_TX:0\n"); + if (copy_from_user(&parm, (void *)arg, sizeof(struct fm_tune_parm))) { + ret = -EFAULT; + goto out; + } + + ret = fm_powerup_tx(fm, &parm); + if (ret < 0) + goto out; + + ret = fm_tune_tx(fm, &parm); + if (ret < 0) + goto out; + + if (copy_to_user((void *)arg, &parm, sizeof(struct fm_tune_parm))) { + ret = -EFAULT; + goto out; + } + WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_POWERUP_TX:1\n"); + break; + } + + case FM_IOCTL_TUNE_TX: + { + struct fm_tune_parm parm; + + WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_TUNE_TX:0\n"); + + if (copy_from_user(&parm, (void *)arg, sizeof(struct fm_tune_parm))) { + ret = -EFAULT; + goto out; + } + + ret = fm_tune_tx(fm, &parm); + if (ret < 0) + goto out; + + if (copy_to_user((void *)arg, &parm, sizeof(struct fm_tune_parm))) { + ret = -EFAULT; + goto out; + } + + WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_TUNE_TX:1\n"); + break; + } + case FM_IOCTL_RDSTX_SUPPORT: + { + signed int rds_tx_support = -1; + + WCN_DBG(FM_NTC | MAIN, "......FM_IOCTL_RDSTX_SUPPORT......\n"); + + ret = fm_rdstx_support(fm, &rds_tx_support); + if (ret) + WCN_DBG(FM_ERR | MAIN, "fm_rdstx_support err\n"); + + if (copy_to_user((void *)arg, &rds_tx_support, sizeof(signed int))) { + WCN_DBG(FM_ERR | MAIN, "copy_to_user error\n"); + ret = -EFAULT; + goto out; + } + break; + } + + case FM_IOCTL_RDSTX_ENABLE: + { + signed int onoff = -1; + + WCN_DBG(FM_NTC | MAIN, "......FM_IOCTL_RDSTX_ENABLE......\n"); + + if (copy_from_user(&onoff, (void *)arg, sizeof(signed int))) { + WCN_DBG(FM_ALT | MAIN, "FM_IOCTL_RDSTX_ENABLE, copy_from_user err\n"); + ret = -EFAULT; + goto out; + } + + ret = fm_rdstx_enable(fm, onoff); + if (ret) + WCN_DBG(FM_ERR | MAIN, "fm_rdstx_enable err\n"); + + break; + } + + case FM_IOCTL_RDS_TX: + { + struct fm_rds_tx_parm parm; + + WCN_DBG(FM_NTC | MAIN, "......FM_IOCTL_RDS_TX......\n"); + + if (copy_from_user(&parm, (void *)arg, sizeof(struct fm_rds_tx_parm))) { + WCN_DBG(FM_ALT | MAIN, "RDS Tx, copy_from_user err\n"); + ret = -EFAULT; + goto out; + } + + ret = fm_rds_tx(fm, &parm); + if (ret) + WCN_DBG(FM_ALT | MAIN, "fm_rds_tx err\n"); + + if (copy_to_user((void *)arg, &parm, sizeof(struct fm_rds_tx_parm))) { + WCN_DBG(FM_ALT | MAIN, "RDS Tx, copy_to_user err\n"); + ret = -EFAULT; + goto out; + } + break; + } + + case FM_IOCTL_TX_SCAN: + { + struct fm_tx_scan_parm parm; + + WCN_DBG(FM_NTC | MAIN, "......FM_IOCTL_TX_SCAN......\n"); + + if (copy_from_user(&parm, (void *)arg, sizeof(struct fm_tx_scan_parm))) { + WCN_DBG(FM_ALT | MAIN, "copy_from_user error\n"); + ret = -EFAULT; + goto out; + } + ret = fm_tx_scan(fm, &parm); + if (ret < 0) + WCN_DBG(FM_ERR | MAIN, "FM_IOCTL_TX_SCAN failed\n"); + + if (copy_to_user((void *)arg, &parm, sizeof(struct fm_tx_scan_parm))) { + WCN_DBG(FM_ALT | MAIN, "copy_to_user error\n"); + ret = -EFAULT; + goto out; + } + break; + } + + default: + ret = -EPERM; + } + +out: + if (ret == -FM_EFW) { + if (fm_sys_state_get(fm) == FM_SUBSYS_RST_OFF) { + fm->wholechiprst = false; + /* subsystem reset */ + WCN_DBG(FM_NTC | MAIN, "fm_subsys_reset START\n"); + fm_subsys_reset(fm); + WCN_DBG(FM_NTC | MAIN, "fm_subsys_reset END\n"); + } + } + + return ret; +} + +static loff_t fm_ops_lseek(struct file *filp, loff_t off, signed int whence) +{ + struct fm *fm = filp->private_data; + + if (whence == SEEK_END) + fm_hwscan_stop(fm); + else if (whence == SEEK_SET) + FM_EVENT_SEND(fm->rds_event, FM_RDS_DATA_READY); + + return off; +} + +static ssize_t fm_ops_read(struct file *filp, char *buf, size_t len, loff_t *off) +{ + struct fm *fm = filp->private_data; + signed int copy_len = 0; + + if (!fm) { + WCN_DBG(FM_ALT | MAIN, "fm_read invalid fm pointer\n"); + return 0; + } + + WCN_DBG(FM_DBG | MAIN, "rds buf len=%zu\n", len); + WCN_DBG(FM_DBG | MAIN, "sizeof(struct rds_t)=%zu\n", sizeof(struct rds_t)); + + if (!buf || len < sizeof(struct rds_t)) { + WCN_DBG(FM_NTC | MAIN, "fm_read invliad buf\n"); + return 0; + } + /* return if FM is resetting */ + if (fm_sys_state_get(fm) != FM_SUBSYS_RST_OFF) { + WCN_DBG(FM_ALT | MAIN, "fm subsys underring reset\n"); + return 0; + } + + copy_len = sizeof(struct rds_t); + + return fm_rds_read(fm, buf, copy_len); +} + +atomic_t g_counter = ATOMIC_INIT(0); +static signed int fm_ops_open(struct inode *inode, struct file *filp) +{ + signed int ret = 0; + struct fm_platform *plat = container_of(inode->i_cdev, struct fm_platform, cdev); + struct fm *fm = container_of(plat, struct fm, platform); + + if (fm_sys_state_get(fm) != FM_SUBSYS_RST_OFF) { + WCN_DBG(FM_ALT | MAIN, "FM subsys is resetting, retry later\n"); + ret = -FM_ESRST; + return ret; + } + + ret = fm_open(fm); + filp->private_data = fm; + atomic_inc(&g_counter); + + WCN_DBG(FM_NTC | MAIN, "fm_ops_open:%d [%d]\n", current->pid, atomic_read(&g_counter)); + return ret; +} + +static signed int fm_ops_release(struct inode *inode, struct file *filp) +{ +/* signed int ret = 0; */ +/* struct fm_platform *plat = container_of(inode->i_cdev, struct fm_platform, cdev); */ +/* struct fm *fm = container_of(plat, struct fm, platform); */ + struct fm *fm = filp->private_data; + + WCN_DBG(FM_NTC | MAIN, "fm_ops_release:%d [%d]\n", current->pid, atomic_read(&g_counter)); + + if (atomic_dec_and_test(&g_counter)) { + WCN_DBG(FM_ALT | MAIN, "FM power down... [%d]\n", atomic_read(&g_counter)); + if (-FM_ELOCK == fm_powerdown(fm, 0)) { + WCN_DBG(FM_ALT | MAIN, "FM power down fail. Do it later.\n"); + fm->timer_wkthd->add_work(fm->timer_wkthd, fm->pwroff_wk); + } + } + + filp->private_data = NULL; + return 0; +} + +static signed int fm_ops_flush(struct file *filp, fl_owner_t Id) +{ + signed int ret = 0; + struct fm *fm = filp->private_data; + + WCN_DBG(FM_NTC | MAIN, "fm_ops_flush:%d\n", current->pid); + fm_close(fm); + filp->private_data = fm; + return ret; +} + +static ssize_t fm_proc_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) +{ + struct fm *fm = g_fm; + ssize_t length = 0; + char tmpbuf[3]; + unsigned long pos = *ppos; + + WCN_DBG(FM_NTC | MAIN, "Enter fm_proc_read.\n"); + /* WCN_DBG(FM_NTC | MAIN, "count = %d\n", count); */ + /* WCN_DBG(FM_NTC | MAIN, "ppos = %d\n", pos); */ + + if (pos != 0) + return 0; + + if (!fm) { + WCN_DBG(FM_ALT | MAIN, "para err\n"); + return 0; + } + + if (fm->chipon && (fm_pwr_state_get(fm) == FM_PWR_RX_ON)) { + length = snprintf(tmpbuf, sizeof(tmpbuf), "1\n"); + WCN_DBG(FM_NTC | MAIN, " FM_PWR_RX_ON\n"); + } else if (fm->chipon && (fm_pwr_state_get(fm) == FM_PWR_TX_ON)) { + length = snprintf(tmpbuf, sizeof(tmpbuf), "2\n"); + WCN_DBG(FM_NTC | MAIN, " FM_PWR_TX_ON\n"); + } else { + length = snprintf(tmpbuf, sizeof(tmpbuf), "0\n"); + WCN_DBG(FM_NTC | MAIN, " FM POWER OFF\n"); + } + + if (copy_to_user(buf, tmpbuf, length)) { + WCN_DBG(FM_NTC | MAIN, " Read FM status fail!\n"); + return 0; + } + + pos += length; + *ppos = pos; + WCN_DBG(FM_NTC | MAIN, "Leave fm_proc_read. length = %zu\n", length); + + return length; +} + +static ssize_t fm_proc_write(struct file *file, const char *buffer, size_t count, loff_t *ppos) +{ + struct fm *fm = g_fm; + signed char tmp_buf[51] = { 0 }; + unsigned int copysize; + + WCN_DBG(FM_NTC | MAIN, "fm_proc_write:0 count = %zu\n", count); + if (count <= 0 || buffer == NULL) { + WCN_DBG(FM_ERR | MAIN, "failed parameter not accept\n"); + return -EFAULT; + } + + copysize = (count < (sizeof(tmp_buf) - 1)) ? count : (sizeof(tmp_buf) - 1); + + memset(tmp_buf, 0, sizeof(tmp_buf)); + if (copy_from_user(tmp_buf, buffer, copysize)) { + WCN_DBG(FM_ERR | MAIN, "failed copy_from_user\n"); + return -EFAULT; + } + + if (strncmp(tmp_buf, "subsys reset", strlen("subsys reset")) == 0) { + fm_subsys_reset(fm); + return count; + } + + if (!fm->chipon || (fm_pwr_state_get(fm) != FM_PWR_RX_ON)) { + WCN_DBG(FM_ERR | MAIN, "FM is off.\n"); + return -EFAULT; + } + + if (kstrtouint(tmp_buf, 0, &g_dbg_level)) { + tmp_buf[50] = '\0'; + WCN_DBG(FM_ERR | MAIN, "Not a valid dbg_level: %s\n", tmp_buf); + if (!fm_cust_config_setup(tmp_buf)) { + WCN_DBG(FM_NTC | MAIN, "get config form %s ok\n", tmp_buf); + return count; + } + return -EFAULT; + } + + WCN_DBG(FM_NTC | MAIN, "fm_proc_write:1 g_dbg_level = 0x%x\n", g_dbg_level); + return count; +} + +/* #define FM_DEV_STATIC_ALLOC */ +/* #define FM_DEV_MAJOR 193 */ +/* static int FM_major = FM_DEV_MAJOR; *//* dynamic allocation */ + +static signed int fm_cdev_setup(struct fm *fm) +{ + signed int ret = 0; + struct fm_platform *plat = &fm->platform; + +#ifdef FM_DEV_STATIC_ALLOC + /*static allocate chrdev */ + plat->dev_t = MKDEV(FM_major, 0); + ret = register_chrdev_region(plat->dev_t, 1, FM_NAME); + + if (ret) { + WCN_DBG(FM_ERR | MAIN, "%s():fail to register chrdev\n", __func__); + return ret; + } +#endif + +#ifndef FM_DEV_STATIC_ALLOC + ret = alloc_chrdev_region(&plat->dev_t, 0, 1, FM_NAME); + + if (ret) { + WCN_DBG(FM_ALT | MAIN, "alloc dev_t failed\n"); + return ret; + } +#endif + + WCN_DBG(FM_NTC | MAIN, "alloc %s:%d:%d\n", FM_NAME, MAJOR(plat->dev_t), MINOR(plat->dev_t)); + + cdev_init(&plat->cdev, &fm_ops); + + plat->cdev.owner = THIS_MODULE; + plat->cdev.ops = &fm_ops; + + ret = cdev_add(&plat->cdev, plat->dev_t, 1); + + if (ret) { + WCN_DBG(FM_ALT | MAIN, "add dev_t failed\n"); + return ret; + } +#ifndef FM_DEV_STATIC_ALLOC + plat->cls = class_create(THIS_MODULE, FM_NAME); + + if (IS_ERR(plat->cls)) { + ret = PTR_ERR(plat->cls); + WCN_DBG(FM_ALT | MAIN, "class_create err:%d\n", ret); + return ret; + } + + plat->dev = device_create(plat->cls, NULL, plat->dev_t, NULL, FM_NAME); +#endif + + return ret; +} + +static signed int fm_cdev_destroy(struct fm *fm) +{ + if (fm == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + device_destroy(fm->platform.cls, fm->platform.dev_t); + class_destroy(fm->platform.cls); + cdev_del(&fm->platform.cdev); + unregister_chrdev_region(fm->platform.dev_t, 1); + + return 0; +} + +static signed int fm_mod_init(unsigned int arg) +{ + signed int ret = 0; + struct fm *fm = NULL; + + fm = fm_dev_init(0); + + if (!fm) { + ret = -ENOMEM; + goto ERR_EXIT; + } + + ret = fm_cdev_setup(fm); + if (ret) + goto ERR_EXIT; + + /* fm proc file create "/proc/fm" */ + g_fm_proc = proc_create(FM_PROC_FILE, 0444, NULL, &fm_proc_ops); + + if (g_fm_proc == NULL) { + WCN_DBG(FM_ALT | MAIN, "create_proc_entry failed\n"); + ret = -ENOMEM; + goto ERR_EXIT; + } else { + WCN_DBG(FM_NTC | MAIN, "create_proc_entry success\n"); + } + + g_fm = fm; + return 0; + +ERR_EXIT: + + if (fm) { + fm_cdev_destroy(fm); + fm_dev_destroy(fm); + } + + remove_proc_entry(FM_PROC_FILE, NULL); + return ret; +} + +static signed int fm_mod_destroy(struct fm *fm) +{ + signed int ret = 0; + + if (fm == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + WCN_DBG(FM_NTC | MAIN, "%s\n", __func__); + remove_proc_entry(FM_PROC_FILE, NULL); + fm_cdev_destroy(fm); + fm_dev_destroy(fm); + + return ret; +} + +static signed int fm_request_gpio(unsigned int pin) +{ + signed int ret = 0; + + /* request gpio pin */ + ret = gpio_request(pin, "fmlna"); + if (ret == 0) { + WCN_DBG(FM_NTC | MAIN, "request gpio pin %d ok\n", pin); + + /* set gpio direction to output */ + gpio_direction_output(pin, 0); + } else { + if (ret == -EINVAL) + WCN_DBG(FM_ERR | MAIN, "gpio pin %d is not valid\n", pin); + else if (ret == -EBUSY) + WCN_DBG(FM_ERR | MAIN, "gpio pin %d is busy\n", pin); + else + WCN_DBG(FM_ERR | MAIN, "gpio pin %d unknown error\n", pin); + } + + return ret; +} + +static signed int mt_fm_probe(struct platform_device *pdev) +{ + signed int ret = 0; +#ifdef CONFIG_OF + struct device_node *node = NULL; + signed int pin_ret = 0; +#endif + + WCN_DBG(FM_NTC | MAIN, "%s\n", __func__); + +#ifdef CONFIG_OF + node = of_find_compatible_node(NULL, NULL, "mediatek,fmradio"); + if (!node) + WCN_DBG(FM_NTC | MAIN, "FM-OF: no fm device node\n"); + else { + pin_ret = of_get_named_gpio(node, "fm_lna_gpio", 0); + if (pin_ret < 0) + WCN_DBG(FM_NTC | MAIN, + "FM-OF: cannot find pins. pin_ret: %d\n", + pin_ret); + else { + g_fm_lna_pin_num = pin_ret; + WCN_DBG(FM_NTC | MAIN, + "FM-OF: FM LNA gpio pin number:%d.\n", + g_fm_lna_pin_num); + + pin_ret = fm_request_gpio(g_fm_lna_pin_num); + if (pin_ret) { + g_fm_lna_pin_num = FM_NO_LNA_PIN; + WCN_DBG(FM_ERR | MAIN, + "FM-OF: fm_request_gpio failed. pin_ret: %d\n", + pin_ret); + } + } + } +#endif + + ret = fm_mod_init(0); + + if (ret) { + WCN_DBG(FM_ERR | MAIN, "fm mod init err\n"); + return -ENOMEM; + } + + return ret; +} + +static signed int mt_fm_remove(struct platform_device *pdev) +{ + WCN_DBG(FM_NTC | MAIN, "%s\n", __func__); + + fm_mod_destroy(g_fm); + g_fm = NULL; + return 0; +} + +static struct platform_device *pr_fm_device; +/* +static struct platform_device mt_fm_device = { + .name = FM_NAME, + .id = -1, +}; +*/ + +/* platform driver entry */ +static struct platform_driver mt_fm_dev_drv = { + .probe = mt_fm_probe, + .remove = mt_fm_remove, + .driver = { + .name = FM_NAME, + .owner = THIS_MODULE, + } +}; + +static signed int mt_fm_init(void) +{ + signed int ret = 0; + + ret = fm_env_setup(); + + if (ret) { + fm_env_destroy(); + return ret; + } + /* register fm device to platform bus */ + /* ret = platform_device_register(&mt_fm_device); + * + * if (ret) + * return ret; + */ + + pr_fm_device = platform_device_alloc(FM_NAME, 0); + if (!pr_fm_device) { + WCN_DBG(FM_ERR | MAIN, "fm platform device alloc fail\n"); + return -ENOMEM; + } + + ret = platform_device_add(pr_fm_device); + if (ret) { + WCN_DBG(FM_ERR | MAIN, "fm platform device add failed(%d)\n", ret); + platform_device_put(pr_fm_device); + return ret; + } + + /* register fm driver to platform bus */ + ret = platform_driver_register(&mt_fm_dev_drv); + + if (ret) { + WCN_DBG(FM_ERR | MAIN, "fm platform driver register fail(%d)\n", ret); + platform_device_unregister(pr_fm_device); + return ret; + } + + fm_register_irq(&mt_fm_dev_drv); + + WCN_DBG(FM_NTC | MAIN, "6. fm platform driver registered\n"); + return ret; +} + +static void mt_fm_exit(void) +{ + WCN_DBG(FM_NTC | MAIN, "%s\n", __func__); + + if (g_fm_lna_pin_num != FM_NO_LNA_PIN) { + gpio_free(g_fm_lna_pin_num); + WCN_DBG(FM_NTC | MAIN, "free gpio pin %d ok\n", g_fm_lna_pin_num); + } + + platform_driver_unregister(&mt_fm_dev_drv); + /* platform_device_unregister(&mt_fm_device); */ + platform_device_unregister(pr_fm_device); + fm_env_destroy(); +} + +#ifdef MTK_WCN_REMOVE_KERNEL_MODULE +int mtk_wcn_fm_init(void) +{ + return mt_fm_init(); +} +EXPORT_SYMBOL(mtk_wcn_fm_init); + +void mtk_wcn_fm_exit(void) +{ + mt_fm_exit(); +} +EXPORT_SYMBOL(mtk_wcn_fm_exit); +#else +module_init(mt_fm_init); +module_exit(mt_fm_exit); +#endif +EXPORT_SYMBOL(g_dbg_level); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("MediaTek FM Driver"); +MODULE_AUTHOR("Hongcheng "); diff --git a/drivers/misc/mediatek/connectivity/fmradio/core/fm_patch.c b/drivers/misc/mediatek/connectivity/fmradio/core/fm_patch.c new file mode 100644 index 0000000000000000000000000000000000000000..cf42b79dd1697137ed10a8890e508e14381b44f8 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/core/fm_patch.c @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2015 MediaTek Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 +#include +#include +#include +#include + +#include "fm_patch.h" +#include "fm_typedef.h" +#include "fm_dbg.h" +#include "fm_err.h" + +static struct fm_file_read_data g_file_read_data; + +int file_read_thread(void *arg) +{ + struct fm_file_read_data *data = (struct fm_file_read_data *)arg; + const struct firmware *fw = NULL; + + if (!data) + return 0; + + data->ret = request_firmware(&fw, data->filename, NULL); + if (data->ret) { + WCN_DBG(FM_ERR | CHIP, "Failed to load firmware \"%s\"\n", + data->filename); + release_firmware(fw); + data->ret = -FM_EPATCH; + + complete(&data->comp); + return 0; + } + WCN_DBG(FM_NTC | CHIP, "load firmware \"%s\" ok\n", data->filename); + + if (data->len >= fw->size) { + memcpy(data->dst, fw->data, fw->size); + WCN_DBG(FM_NTC | CHIP, "Copy file data(%p) size(%zu)\n", + fw->data, fw->size); + data->ret = fw->size; + } else { + WCN_DBG(FM_NTC | CHIP, + "Copy file data failed fw->size(%zu) > bufsize(%d)\n", + fw->size, data->len); + data->ret = -FM_EPATCH; + } + release_firmware(fw); + + complete(&data->comp); + + return 0; +} + +/* + * fm_file_read - read FM DSP patch/coeff/hwcoeff/rom binary file + * @filename - source file name + * @dst - target buffer + * @len - desired read length + * @position - the read position + * If success, return read length in bytes, else error code + */ +signed int fm_file_read(const signed char *filename, unsigned char *dst, signed int len, signed int position) +{ + struct fm_file_read_data *data = &g_file_read_data; + struct task_struct *k; + + init_completion(&data->comp); + + data->filename = filename; + data->dst = dst; + data->len = len; + data->position = position; + data->ret = 0; + + k = kthread_run(file_read_thread, (void *)data, "file_read_thread"); + if (IS_ERR(k)) { + WCN_DBG(FM_NTC | CHIP, "%s error ret:%d\n", __func__, PTR_ERR(k)); + data->ret = -FM_EPATCH; + } else + wait_for_completion(&data->comp); + return data->ret; +} + +signed int fm_file_write(const signed char *filename, unsigned char *dst, signed int len, signed int *ppos) +{ + signed int ret = 0; + return ret; +} diff --git a/drivers/misc/mediatek/connectivity/fmradio/core/fm_rds_parser.c b/drivers/misc/mediatek/connectivity/fmradio/core/fm_rds_parser.c new file mode 100644 index 0000000000000000000000000000000000000000..dcb7aa43093a16e6113e80ecca8c7233b81ea738 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/core/fm_rds_parser.c @@ -0,0 +1,2004 @@ +/* + * Copyright (C) 2015 MediaTek Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 + +#include "fm_typedef.h" +#include "fm_rds.h" +#include "fm_dbg.h" +#include "fm_err.h" +#include "fm_stdlib.h" + +/* static enum rds_ps_state_machine_t ps_state_machine = RDS_PS_START; */ +/* static enum rds_rt_state_machine_t rt_state_machine = RDS_RT_START; */ +struct fm_state_machine { + signed int state; + signed int (*state_get)(struct fm_state_machine *thiz); + signed int (*state_set)(struct fm_state_machine *thiz, signed int new_state); +}; + +static signed int fm_state_get(struct fm_state_machine *thiz) +{ + return thiz->state; +} + +static signed int fm_state_set(struct fm_state_machine *thiz, signed int new_state) +{ + return thiz->state = new_state; +} + +#define STATE_SET(a, s) \ +{ \ + if ((a)->state_set) { \ + (a)->state_set((a), (s)); \ + } \ +} + +#define STATE_GET(a) \ +({ \ + signed int __ret = 0; \ + if ((a)->state_get) { \ + __ret = (a)->state_get((a)); \ + } \ + __ret; \ +}) + +static unsigned short (*rds_get_freq)(void); + +/* RDS spec related handle flow */ +/* + * rds_cnt_get + * To get rds group count form raw data + * If success return 0, else return error code +*/ +static signed int rds_cnt_get(struct rds_rx_t *rds_raw, signed int raw_size, signed int *cnt) +{ + signed int gap = sizeof(rds_raw->cos) + sizeof(rds_raw->sin); + + if (rds_raw == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (cnt == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + *cnt = (raw_size - gap) / sizeof(struct rds_packet_t); + WCN_DBG(FM_INF | RDSC, "group cnt=%d\n", *cnt); + + return 0; +} + +/* + * rds_grp_get + * To get rds group[n] data form raw data with index + * If success return 0, else return error code +*/ +static signed int rds_grp_get(unsigned short *dst, struct rds_rx_t *raw, signed int idx) +{ + if (dst == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (raw == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + if (idx > (MAX_RDS_RX_GROUP_CNT - 1) || idx < 0) + return -FM_EPARA; + + dst[0] = raw->data[idx].blkA; + dst[1] = raw->data[idx].blkB; + dst[2] = raw->data[idx].blkC; + dst[3] = raw->data[idx].blkD; + dst[4] = raw->data[idx].crc; + dst[5] = raw->data[idx].cbc; + + WCN_DBG(FM_NTC | RDSC, "BLOCK:%04x %04x %04x %04x, CRC:%04x CBC:%04x\n", dst[0], dst[1], + dst[2], dst[3], dst[4], dst[5]); + + return 0; +} + +/* + * rds_checksum_check + * To check CRC rerult, if OK, *valid=true, else *valid=false + * If success return 0, else return error code +*/ +static signed int rds_checksum_check(unsigned short crc, signed int mask, bool *valid) +{ + if (valid == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + if ((crc & mask) == mask) + *valid = true; + else + *valid = false; + + return 0; +} + +/* + * rds_event_set + * To set rds event, and user space can use this flag to juge which event happened + * If success return 0, else return error code +*/ +static signed int rds_event_set(unsigned short *events, signed int event_mask) +{ + if (events == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + WCN_DBG(FM_INF | RDSC, "rds set event[0x%04x->0x%04x]\n", event_mask, *events); + *events |= event_mask; + + return 0; +} + +/* + * rds_flag_set + * To set rds event flag, and user space can use this flag to juge which event happened + * If success return 0, else return error code +*/ +static signed int rds_flag_set(unsigned int *flags, signed int flag_mask) +{ + if (flags == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + WCN_DBG(FM_INF | RDSC, "rds set flag[0x%04x->0x%04x]\n", flag_mask, *flags); + *flags |= flag_mask; + + return 0; +} + +/* + * rds_grp_type_get + * To get rds group type form blockB + * If success return 0, else return error code +*/ +static signed int rds_grp_type_get(unsigned short crc, unsigned short blk, unsigned char *type, unsigned char *subtype) +{ + bool valid = false; + + if (type == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (subtype == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + /* to get the group type from block B */ + rds_checksum_check(crc, FM_RDS_GDBK_IND_B, &valid); + + if (valid == true) { + *type = (blk & 0xF000) >> 12; /* Group type(4bits) */ + *subtype = (blk & 0x0800) >> 11; /* version code(1bit), 0=vesionA, 1=versionB */ + } else { + WCN_DBG(FM_WAR | RDSC, "Block1 CRC err\n"); + return -FM_ECRC; + } + + WCN_DBG(FM_DBG | RDSC, "Type=%d, subtype:%s\n", (signed int) *type, *subtype ? "version B" : "version A"); + return 0; +} + +/* + * rds_grp_counter_add + * @type -- group type, rang: 0~15 + * @subtype -- sub group type, rang:0~1 + * + * add group counter, g0a~g15b + * we use type value as the index + * If success return 0, else return error code +*/ +static signed int rds_grp_counter_add(unsigned char type, unsigned char subtype, struct rds_group_cnt_t *gc) +{ + if (gc == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + if (type > 15) + return -FM_EPARA; + + switch (subtype) { + case RDS_GRP_VER_A: + gc->groupA[type]++; + break; + case RDS_GRP_VER_B: + gc->groupB[type]++; + break; + default: + return -FM_EPARA; + } + + gc->total++; + WCN_DBG(FM_INF | RDSC, "group counter:%d\n", (signed int) gc->total); + return 0; +} + +/* + * rds_grp_counter_get + * + * read group counter , g0a~g15b + * If success return 0, else return error code +*/ +extern signed int rds_grp_counter_get(struct rds_group_cnt_t *dst, struct rds_group_cnt_t *src) +{ + if (dst == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (src == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + fm_memcpy(dst, src, sizeof(struct rds_group_cnt_t)); + WCN_DBG(FM_DBG | RDSC, "rds gc get[total=%d]\n", (signed int) dst->total); + return 0; +} + +/* + * rds_grp_counter_reset + * + * clear group counter to 0, g0a~g15b + * If success return 0, else return error code +*/ +extern signed int rds_grp_counter_reset(struct rds_group_cnt_t *gc) +{ + if (gc == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + fm_memset(gc, 0, sizeof(struct rds_group_cnt_t)); + return 0; +} + +extern signed int rds_log_in(struct rds_log_t *thiz, struct rds_rx_t *new_log, signed int new_len) +{ + if (new_log == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + new_len = (new_len < sizeof(struct rds_rx_t)) ? new_len : sizeof(struct rds_rx_t); + fm_memcpy(&(thiz->rds_log[thiz->in]), new_log, new_len); + thiz->log_len[thiz->in] = new_len; + thiz->in = (thiz->in + 1) % thiz->size; + thiz->len++; + thiz->len = (thiz->len >= thiz->size) ? thiz->size : thiz->len; + WCN_DBG(FM_DBG | RDSC, "add a new log[len=%d]\n", thiz->len); + + return 0; +} + +extern signed int rds_log_out(struct rds_log_t *thiz, struct rds_rx_t *dst, signed int *dst_len) +{ + if (dst == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (dst_len == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + if (thiz->len > 0) { + *dst_len = thiz->log_len[thiz->out]; + *dst_len = (*dst_len < sizeof(struct rds_rx_t)) ? *dst_len : sizeof(struct rds_rx_t); + fm_memcpy(dst, &(thiz->rds_log[thiz->out]), *dst_len); + thiz->out = (thiz->out + 1) % thiz->size; + thiz->len--; + WCN_DBG(FM_DBG | RDSC, "del a new log[len=%d]\n", thiz->len); + } else { + *dst_len = 0; + WCN_DBG(FM_WAR | RDSC, "rds log buf is empty\n"); + } + + return 0; +} + +/* + * rds_grp_pi_get + * To get rds group pi code form blockA + * If success return 0, else return error code +*/ +static signed int rds_grp_pi_get(unsigned short crc, unsigned short blk, unsigned short *pi, bool *dirty) +{ + signed int ret = 0; + bool valid = false; + + if (pi == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (dirty == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + /* to get the group pi code from block A */ + ret = rds_checksum_check(crc, FM_RDS_GDBK_IND_A, &valid); + + if (valid == true) { + if (*pi != blk) { + /* PI=program Identication */ + *pi = blk; + *dirty = true; /* yes, we got new PI code */ + } else { + *dirty = false; /* PI is the same as last one */ + } + } else { + WCN_DBG(FM_WAR | RDSC, "Block0 CRC err\n"); + return -FM_ECRC; + } + + WCN_DBG(FM_INF | RDSC, "PI=0x%04x, %s\n", *pi, *dirty ? "new" : "old"); + return ret; +} + +/* + * rds_grp_pty_get + * To get rds group pty code form blockB + * If success return 0, else return error code +*/ +static signed int rds_grp_pty_get(unsigned short crc, unsigned short blk, unsigned char *pty, bool *dirty) +{ + signed int ret = 0; +/* bool valid = false; */ + + if (pty == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (dirty == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + /* to get PTY code from block B */ +/* ret = rds_checksum_check(crc, FM_RDS_GDBK_IND_B, &valid); */ + +/* if (valid == false) { */ +/* WCN_DBG(FM_WAR | RDSC, "Block1 CRC err\n"); */ +/* return -FM_ECRC; */ +/* } */ + + if (*pty != ((blk & 0x03E0) >> 5)) { + /* PTY=Program Type Code */ + *pty = (blk & 0x03E0) >> 5; + *dirty = true; /* yes, we got new PTY code */ + } else { + *dirty = false; /* PTY is the same as last one */ + } + + WCN_DBG(FM_INF | RDSC, "PTY=%d, %s\n", (signed int) *pty, *dirty ? "new" : "old"); + return ret; +} + +/* + * rds_grp_tp_get + * To get rds group tp code form blockB + * If success return 0, else return error code +*/ +static signed int rds_grp_tp_get(unsigned short crc, unsigned short blk, unsigned char *tp, bool *dirty) +{ + signed int ret = 0; +/* bool valid = false; */ + + if (tp == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (dirty == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + /* to get TP code from block B */ +/* ret = rds_checksum_check(crc, FM_RDS_GDBK_IND_B, &valid); */ + +/* if (valid == false) { */ +/* WCN_DBG(FM_WAR | RDSC, "Block1 CRC err\n"); */ +/* return -FM_ECRC; */ +/* } */ + + if (*tp != ((blk & 0x0400) >> 10)) { + /* Tranfic Program Identification */ + *tp = (blk & 0x0400) >> 10; + *dirty = true; /* yes, we got new TP code */ + } else { + *dirty = false; /* TP is the same as last one */ + } + + /* WCN_DBG(FM_INF | RDSC, "TP=%d, %s\n", (signed int) *tp, *dirty ? "new" : "old"); */ + return ret; +} + +/* + * rds_g0_ta_get + * To get rds group ta code form blockB + * If success return 0, else return error code +*/ +static signed int rds_g0_ta_get(unsigned short blk, unsigned char *ta, bool *dirty) +{ + signed int ret = 0; + + if (ta == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (dirty == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + /* TA=Traffic Announcement code */ + if (*ta != ((blk & 0x0010) >> 4)) { + *ta = (blk & 0x0010) >> 4; + *dirty = true; /* yes, we got new TA code */ + } else { + *dirty = false; /* TA is the same as last one */ + } + + WCN_DBG(FM_INF | RDSC, "TA=%d, %s\n", (signed int) *ta, *dirty ? "new" : "old"); + return ret; +} + +/* + * rds_g0_music_get + * To get music-speech switch code form blockB + * If success return 0, else return error code +*/ +static signed int rds_g0_music_get(unsigned short blk, unsigned char *music, bool *dirty) +{ + signed int ret = 0; + + if (music == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (dirty == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + /* M/S=music speech switch code */ + if (*music != ((blk & 0x0008) >> 3)) { + *music = (blk & 0x0008) >> 3; + *dirty = true; /* yes, we got new music code */ + } else { + *dirty = false; /* music is the same as last one */ + } + + WCN_DBG(FM_INF | RDSC, "Music=%d, %s\n", (signed int) *music, *dirty ? "new" : "old"); + return ret; +} + +/* + * rds_g0_ps_addr_get + * To get ps addr form blockB, blkB b0~b1 + * If success return 0, else return error code +*/ +static signed int rds_g0_ps_addr_get(unsigned short blkB, unsigned char *addr) +{ + if (addr == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + *addr = (unsigned char) blkB & 0x03; + + WCN_DBG(FM_INF | RDSC, "addr=0x%02x\n", *addr); + return 0; +} + +/* + * rds_g0_di_flag_get + * To get DI segment flag form blockB, blkB b2 + * If success return 0, else return error code +*/ +static signed int rds_g0_di_flag_get(unsigned short blkB, unsigned char *flag) +{ + if (flag == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + *flag = (unsigned char) ((blkB & 0x0004) >> 2); + + WCN_DBG(FM_INF | RDSC, "flag=0x%02x\n", *flag); + return 0; +} + +static signed int rds_g0_ps_get(unsigned short crc, unsigned short blkD, unsigned char addr, unsigned char *buf) +{ +/* bool valid = false; */ + signed int idx = 0; + + if (buf == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + /* ps segment addr rang 0~3 */ + if (addr > 0x03) { + WCN_DBG(FM_ERR | RDSC, "addr invalid(0x%02x)\n", addr); + return -FM_EPARA; + } + + idx = 2 * addr; + buf[idx] = blkD >> 8; + buf[idx + 1] = blkD & 0xFF; +#if 0 + rds_checksum_check(crc, FM_RDS_GDBK_IND_D, &valid); + + if (valid == true) { + buf[idx] = blkD >> 8; + buf[idx + 1] = blkD & 0xFF; + } else { + WCN_DBG(FM_ERR | RDSC, "ps crc check err\n"); + return -FM_ECRC; + } +#endif + + WCN_DBG(FM_INF | RDSC, "PS:addr[%02x]:0x%02x 0x%02x\n", addr, buf[idx], buf[idx + 1]); + return 0; +} + +/* + * rds_g0_ps_cmp + * this function is the most importent flow for PS parsing + * 1.Compare fresh buf with once buf per byte, if eque copy this byte to twice buf, else copy it to once buf + * 2.Check whether we got a full segment + * If success return 0, else return error code +*/ +static signed int rds_g0_ps_cmp(unsigned char addr, unsigned short cbc, unsigned char *fresh, + unsigned char *once, unsigned char *twice, /*bool *valid, */ unsigned char *bm) +{ + signed int ret = 0, indx; + /* signed int i = 0; */ + /* signed int j = 0; */ + /* signed int cnt = 0; */ + unsigned char AF_H, AF_L, PS_Num; + /* unsigned char corrBitCnt_BlkB, corrBitCnt_BlkD; */ + static signed char Pre_PS_Num = -1; + + if (fresh == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + if (once == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + if (twice == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + if (addr > 3) { /* ps limited in 8 chars */ + WCN_DBG(FM_NTC | RDSC, "PS Address error, addr=%x\n", addr); + return -1; + } + + /* j = 2; // PS segment width */ + PS_Num = addr; + /* corrBitCnt_BlkB = rds_cbc_get(cbc, RDS_BLK_B); */ + /* corrBitCnt_BlkD = rds_cbc_get(cbc, RDS_BLK_D); */ + + AF_H = once[2 * PS_Num]; + AF_L = once[2 * PS_Num + 1]; + if ((fresh[2 * PS_Num] == AF_H) && (fresh[2 * PS_Num + 1] == AF_L)) { + twice[2 * PS_Num] = once[2 * PS_Num]; + twice[2 * PS_Num + 1] = once[2 * PS_Num + 1]; + *bm |= 1 << PS_Num; + } else { + if (PS_Num - Pre_PS_Num > 1) { + for (indx = Pre_PS_Num + 1; indx < PS_Num; indx++) { + *bm &= ~(1 << indx); + once[2 * indx] = 0x00; + once[2 * indx + 1] = 0x00; + twice[2 * indx] = 0x00; + twice[2 * indx + 1] = 0x00; + } + } else if (PS_Num - Pre_PS_Num < 1) { + for (indx = 0; indx < PS_Num; indx++) { + *bm &= ~(1 << indx); + once[2 * indx] = 0x00; + once[2 * indx + 1] = 0x00; + twice[2 * indx] = 0x00; + twice[2 * indx + 1] = 0x00; + } + } + + if ((once[2 * PS_Num] != 0) || (once[2 * PS_Num + 1] != 0)) { + for (indx = PS_Num; indx < 4; indx++) + *bm &= ~(1 << indx); + } + /* if((corrBitCnt_BlkB == 0) && (corrBitCnt_BlkD == 0)) */ + /* ALPS00523685:6627 CBC sometime is unreliable */ +#ifdef RDS_CBC_DEPENDENCY + if (cbc == 0) { + *bm |= 1 << PS_Num; + once[2 * PS_Num] = fresh[2 * PS_Num]; + once[2 * PS_Num + 1] = fresh[2 * PS_Num + 1]; + twice[2 * PS_Num] = fresh[2 * PS_Num]; + twice[2 * PS_Num + 1] = fresh[2 * PS_Num + 1]; + } else +#endif + { + once[2 * PS_Num] = fresh[2 * PS_Num]; + once[2 * PS_Num + 1] = fresh[2 * PS_Num + 1]; + } + } + + Pre_PS_Num = PS_Num; +#if 0 + if (rds_cbc_get(cbc, RDS_BLK_D) == 0) { + once[j * addr] = fresh[j * addr]; + once[j * addr + 1] = fresh[j * addr + 1]; + } + if ((once[j * addr] == fresh[j * addr]) && (once[j * addr + 1] == fresh[j * addr + 1])) { + twice[j * addr] = once[j * addr]; + twice[j * addr + 1] = once[j * addr + 1]; + *valid = true; + } else { + once[j * addr] = fresh[j * addr]; + once[j * addr + 1] = fresh[j * addr + 1]; + *valid = false; + } +#endif +#if 0 + for (i = 0; i < j; i++) { + if (fresh[j * addr + i] == once[j * addr + i]) { + twice[j * addr + i] = once[j * addr + i]; /* get the same byte 2 times */ + cnt++; + } else { + once[j * addr + i] = fresh[j * addr + i]; /* use new val */ + } + } + + /* check if we got a valid segment */ + if (cnt == j) + *valid = true; + else + *valid = false; +#endif + /* WCN_DBG(FM_NTC | RDSC, "PS seg=%s\n", *valid == true ? "true" : "false"); */ + WCN_DBG(FM_INF | RDSC, "bitmap=%x\n", *bm); + WCN_DBG(FM_INF | RDSC, "PS[%02x][1][2]=%x %x|%x %x|%x %x|%x %x|%x %x|%x %x|%x %x|%x %x\n", + addr, once[0], twice[0], once[1], twice[1], once[2], twice[2], once[3], twice[3], + once[4], twice[4], once[5], twice[5], once[6], twice[6], once[7], twice[7]); + return ret; +} + +struct rds_bitmap { + unsigned short bm; + signed int cnt; + signed int max_addr; + unsigned short (*bm_get)(struct rds_bitmap *thiz); + signed int (*bm_cnt_get)(struct rds_bitmap *thiz); + signed int (*bm_get_pos)(struct rds_bitmap *thiz); + signed int (*bm_clr)(struct rds_bitmap *thiz); + signed int (*bm_cmp)(struct rds_bitmap *thiz, struct rds_bitmap *that); + signed int (*bm_set)(struct rds_bitmap *thiz, unsigned char addr); +}; + +static unsigned short rds_bm_get(struct rds_bitmap *thiz) +{ + return thiz->bm; +} + +static signed int rds_bm_cnt_get(struct rds_bitmap *thiz) +{ + return thiz->cnt; +} + +#define FM_RDS_USE_SOLUTION_B + +static signed int rds_bm_get_pos(struct rds_bitmap *thiz) +{ + signed int i = thiz->max_addr; + signed int j; + + j = 0; + + while ((i > -1) && !(thiz->bm & (1 << i))) + i--; + +#ifdef FM_RDS_USE_SOLUTION_B + for (j = i; j >= 0; j--) { + if (!(thiz->bm & (1 << j))) { + WCN_DBG(FM_NTC | RDSC, "uncomplete msg 0x%04x, delete it\n", thiz->bm); + return -1; + } + } +#endif + + return i; +} + +static signed int rds_bm_clr(struct rds_bitmap *thiz) +{ + thiz->bm = 0x0000; + thiz->cnt = 0; + return 0; +} + +static signed int rds_bm_cmp(struct rds_bitmap *bitmap1, struct rds_bitmap *bitmap2) +{ + return (signed int) (bitmap1->bm - bitmap2->bm); +} + +static signed int rds_bm_set(struct rds_bitmap *thiz, unsigned char addr) +{ + struct rds_bitmap bm_old; + + /* text segment addr rang */ + if (addr > thiz->max_addr) { + WCN_DBG(FM_ERR | RDSC, "addr invalid(0x%02x)\n", addr); + return -FM_EPARA; + } + + bm_old.bm = thiz->bm; + thiz->bm |= (1 << addr); /* set bitmap */ + + if (!rds_bm_cmp(&bm_old, thiz)) + thiz->cnt++; /* multi get a segment */ + else if (thiz->cnt > 0) + thiz->cnt--; + + return 0; +} + +/* + * rds_g2_rt_addr_get + * To get rt addr form blockB + * If success return 0, else return error code +*/ +static signed int rds_g2_rt_addr_get(unsigned short blkB, unsigned char *addr) +{ + signed int ret = 0; + + if (addr == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + *addr = (unsigned char) blkB & 0x0F; + + WCN_DBG(FM_INF | RDSC, "addr=0x%02x\n", *addr); + return ret; +} + +static signed int rds_g2_txtAB_get(unsigned short blk, unsigned char *txtAB, bool *dirty) +{ + signed int ret = 0; + static bool once_dirty; /* false */ + + if (txtAB == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (dirty == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + *dirty = false; + if (*txtAB != ((blk & 0x0010) >> 4)) { + if (once_dirty) { + *txtAB = (blk & 0x0010) >> 4; + *dirty = true; /* yes, we got new txtAB code */ + once_dirty = false; + WCN_DBG(FM_NTC | RDSC, "changed! txtAB=%d\n", *txtAB); + return ret; + } + once_dirty = true; + } else { + once_dirty = false; /* txtAB is the same as last one */ + } + + WCN_DBG(FM_INF | RDSC, "txtAB=%d, %s\n", *txtAB, *dirty ? "new" : "old"); + return ret; +} + +static signed int rds_g2_rt_get(unsigned short crc, unsigned char subtype, unsigned short blkC, unsigned short blkD, + unsigned char addr, unsigned char *buf) +{ + signed int ret = 0; + bool valid = false; + signed int idx = 0; + + if (buf == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + /* text segment addr rang 0~15 */ + if (addr > 0x0F) { + WCN_DBG(FM_ERR | RDSC, "addr invalid(0x%02x)\n", addr); + ret = -FM_EPARA; + return ret; + } + + switch (subtype) { + case RDS_GRP_VER_A: + idx = 4 * addr; + ret = rds_checksum_check(crc, FM_RDS_GDBK_IND_C | FM_RDS_GDBK_IND_D, &valid); + + if (valid == true) { + buf[idx] = blkC >> 8; + buf[idx + 1] = blkC & 0xFF; + buf[idx + 2] = blkD >> 8; + buf[idx + 3] = blkD & 0xFF; + } else { + WCN_DBG(FM_ERR | RDSC, "rt crc check err\n"); + ret = -FM_ECRC; + } + + break; + case RDS_GRP_VER_B: + idx = 2 * addr; + ret = rds_checksum_check(crc, FM_RDS_GDBK_IND_D, &valid); + + if (valid == true) { + buf[idx] = blkD >> 8; + buf[idx + 1] = blkD & 0xFF; + } else { + WCN_DBG(FM_ERR | RDSC, "rt crc check err\n"); + ret = -FM_ECRC; + } + + break; + default: + break; + } + + WCN_DBG(FM_NTC | RDSC, "fresh addr[%02x]:0x%02x%02x 0x%02x%02x\n", addr, buf[idx], + buf[idx + 1], buf[idx + 2], buf[idx + 3]); + return ret; +} + +static signed int rds_g2_rt_get_len(unsigned char subtype, signed int pos, signed int *len) +{ + signed int ret = 0; + + if (len == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + if (subtype == RDS_GRP_VER_A) + *len = 4 * (pos + 1); + else + *len = 2 * (pos + 1); + + return ret; +} + +/* + * rds_g2_rt_cmp + * this function is the most importent flow for RT parsing + * 1.Compare fresh buf with once buf per byte, if eque copy this byte to twice buf, else copy it to once buf + * 2.Check whether we got a full segment, for typeA if copyed 4bytes to twice buf, for typeB 2bytes copyed to twice buf + * 3.Check whether we got the end of RT, if we got 0x0D + * 4.If we got the end, then caculate the RT length + * If success return 0, else return error code +*/ +static signed int rds_g2_rt_cmp(unsigned char addr, unsigned short cbc, unsigned char subtype, unsigned char *fresh, + unsigned char *once, unsigned char *twice, bool *valid) +{ + signed int ret = 0; + signed int i = 0; + signed int j = 0; + signed int cnt = 0; + + if (fresh == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (once == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (twice == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (valid == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + j = (subtype == RDS_GRP_VER_A) ? 4 : 2; /* RT segment width */ + + if (subtype == RDS_GRP_VER_A) { + /* if (rds_cbc_get(cbc, RDS_BLK_C) == 0) */ +#ifdef RDS_CBC_DEPENDENCY + if (cbc == 0) { +#endif + once[j * addr + 0] = fresh[j * addr + 0]; + once[j * addr + 1] = fresh[j * addr + 1]; + once[j * addr + 2] = fresh[j * addr + 2]; + once[j * addr + 3] = fresh[j * addr + 3]; +#ifdef RDS_CBC_DEPENDENCY + } +#endif + } else if (subtype == RDS_GRP_VER_B) { +#ifdef RDS_CBC_DEPENDENCY + if (cbc == 0) { +#endif + once[j * addr + 0] = fresh[j * addr + 0]; + once[j * addr + 1] = fresh[j * addr + 1]; +#ifdef RDS_CBC_DEPENDENCY + } +#endif + } +#ifdef RDS_CBC_DEPENDENCY + for (i = 0; i < j; i++) { + if (fresh[j * addr + i] == once[j * addr + i]) { + twice[j * addr + i] = once[j * addr + i]; /* get the same byte 2 times */ + cnt++; + /* WCN_DBG(FM_NTC | RDSC, "twice=%d\n", j * addr + i); */ + } else { + once[j * addr + i] = fresh[j * addr + i]; /* use new val */ + /* WCN_DBG(FM_NTC | RDSC, "once=%d\n", j * addr + i); */ + } + } +#else + for (i = 0; i < j; i++) { + if (twice[j * addr + i] == once[j * addr + i]) { + cnt++; + /* WCN_DBG(FM_NTC | RDSC, "twice=%d\n", j * addr + i); */ + } else { + twice[j * addr + i] = once[j * addr + i]; + /* WCN_DBG(FM_NTC | RDSC, "once=%d\n", j * addr + i); */ + } + } +#endif + + /* check if we got a valid segment 4bytes for typeA, 2bytes for typeB */ + if (cnt == j) + *valid = true; + else + *valid = false; + + WCN_DBG(FM_INF | RDSC, "RT seg=%s\n", *valid == true ? "true" : "false"); +/* WCN_DBG(FM_INF | RDSC, "RT end=%s\n", *end == true ? "true" : "false"); */ +/* WCN_DBG(FM_INF | RDSC, "RT len=%d\n", *len); */ + return ret; +} + +/* + * rds_g2_rt_check_end + * check 0x0D end flag + * If we got the end, then caculate the RT length + * If success return 0, else return error code +*/ +static signed int rds_g2_rt_check_end(unsigned char addr, unsigned char subtype, unsigned char *twice, bool *end) +{ + signed int i = 0; + signed int j = 0; + + if (twice == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (end == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + j = (subtype == RDS_GRP_VER_A) ? 4 : 2; /* RT segment width */ + *end = false; + + for (i = 0; i < j; i++) { + /* if we got 0x0D twice, it means a RT end */ + if (twice[j * addr + i] == 0x0D) { + *end = true; + WCN_DBG(FM_NTC | RDSC, "get 0x0D\n"); + break; + } + } + + return 0; +} + +static signed int rds_retrieve_g0_af(unsigned short *block_data, unsigned char SubType, struct rds_t *pstRDSData) +{ + static signed short preAF_Num; + unsigned char indx, indx2, AF_H, AF_L, num; + signed short temp_H, temp_L; + signed int ret = 0; + bool valid = false; + bool dirty = false; + unsigned short *event = &pstRDSData->event_status; + unsigned int *flag = &pstRDSData->RDSFlag.flag_status; + +/* ret = rds_checksum_check(block_data[4], FM_RDS_GDBK_IND_D, &valid); */ + +/* if (valid == false) { */ +/* WCN_DBG(FM_WAR | RDSC, "Group0 BlockD crc err\n"); */ +/* return -FM_ECRC; */ +/* } */ + + ret = rds_g0_ta_get(block_data[1], &pstRDSData->RDSFlag.TA, &dirty); + + if (ret) { + WCN_DBG(FM_WAR | RDSC, "get ta failed[ret=%d]\n", ret); + } else if (dirty == true) { + ret = rds_event_set(event, RDS_EVENT_FLAGS); /* yes, we got new TA code */ + ret = rds_flag_set(flag, RDS_FLAG_IS_TA); + } + + ret = rds_g0_music_get(block_data[1], &pstRDSData->RDSFlag.Music, &dirty); + + if (ret) { + WCN_DBG(FM_WAR | RDSC, "get music failed[ret=%d]\n", ret); + } else if (dirty == true) { + ret = rds_event_set(event, RDS_EVENT_FLAGS); /* yes, we got new MUSIC code */ + ret = rds_flag_set(flag, RDS_FLAG_IS_MUSIC); + } + + if ((pstRDSData->Switch_TP) && (pstRDSData->RDSFlag.TP) && !(pstRDSData->RDSFlag.TA)) + ret = rds_event_set(event, RDS_EVENT_TAON_OFF); + + if (SubType) /* Type B no AF information */ + goto out; + + /* Type A */ + + ret = rds_checksum_check(block_data[4], FM_RDS_GDBK_IND_C, &valid); + + if (valid == false) { + WCN_DBG(FM_WAR | RDSC, "Group0 BlockC crc err\n"); + return -FM_ECRC; + } + + AF_H = (block_data[2] & 0xFF00) >> 8; + AF_L = block_data[2] & 0x00FF; + + if ((AF_H > 224) && (AF_H < 250)) { + /* Followed AF Number, see RDS spec Table 11, valid(224-249) */ + WCN_DBG(FM_INF | RDSC, "RetrieveGroup0 AF_H:%d, AF_L:%d\n", AF_H, AF_L); + preAF_Num = AF_H - 224; /* AF Number */ + + if (preAF_Num != pstRDSData->AF_Data.AF_Num) { + pstRDSData->AF_Data.AF_Num = preAF_Num; + pstRDSData->AF_Data.isAFNum_Get = 0; + } else { + /* Get the same AFNum two times */ + pstRDSData->AF_Data.isAFNum_Get = 1; + } + + if ((AF_L < 205) && (AF_L > 0)) { + /* See RDS Spec table 10, valid VHF */ + pstRDSData->AF_Data.AF[0][0] = AF_L + 875; /* convert to 100KHz */ + pstRDSData->AF_Data.AF[0][0] *= 10; + WCN_DBG(FM_NTC | RDSC, "RetrieveGroup0 AF[0][0]:%d\n", + pstRDSData->AF_Data.AF[0][0]); + + if ((pstRDSData->AF_Data.AF[0][0]) != (pstRDSData->AF_Data.AF[1][0])) { + pstRDSData->AF_Data.AF[1][0] = pstRDSData->AF_Data.AF[0][0]; + } else { + if (pstRDSData->AF_Data.AF[1][0] != rds_get_freq()) + pstRDSData->AF_Data.isMethod_A = 1; + else + pstRDSData->AF_Data.isMethod_A = 0; + } + + WCN_DBG(FM_NTC | RDSC, + "RetrieveGroup0 isAFNum_Get:%d, isMethod_A:%d\n", + pstRDSData->AF_Data.isAFNum_Get, pstRDSData->AF_Data.isMethod_A); + + /* only one AF handle */ + if ((pstRDSData->AF_Data.isAFNum_Get) + && (pstRDSData->AF_Data.AF_Num == 1)) { + pstRDSData->AF_Data.Addr_Cnt = 0xFF; + pstRDSData->event_status |= RDS_EVENT_AF_LIST; + WCN_DBG(FM_NTC | RDSC, "RetrieveGroup0 RDS_EVENT_AF_LIST update\n"); + } + } + } else if ((pstRDSData->AF_Data.isAFNum_Get) + && (pstRDSData->AF_Data.Addr_Cnt != 0xFF)) { + /* AF Num correct */ + num = pstRDSData->AF_Data.AF_Num; + num = (num > 25) ? 25 : num; + num = num >> 1; + WCN_DBG(FM_INF | RDSC, "RetrieveGroup0 +num:%d\n", num); + + /* Put AF freq into buffer and check if AF freq is repeat again */ + for (indx = 1; indx < (num + 1); indx++) { + if ((AF_H == (pstRDSData->AF_Data.AF[0][2 * indx - 1] / 10 - 875)) + && (AF_L == (pstRDSData->AF_Data.AF[0][2 * indx] / 10 - 875))) { + WCN_DBG(FM_NTC | RDSC, + "RetrieveGroup0 +num:%d AF same as indx:%d\n", num, indx); + break; + } else if (!(pstRDSData->AF_Data.AF[0][2 * indx - 1])) { + /* null buffer */ + /* convert to 100KHz */ + pstRDSData->AF_Data.AF[0][2 * indx - 1] = AF_H + 875; + pstRDSData->AF_Data.AF[0][2 * indx] = AF_L + 875; + + pstRDSData->AF_Data.AF[0][2 * indx - 1] *= 10; + pstRDSData->AF_Data.AF[0][2 * indx] *= 10; + + WCN_DBG(FM_NTC | RDSC, + "RetrieveGroup0 +num:%d AF[0][%d]:%d, AF[0][%d]:%d\n", + num, 2 * indx - 1, + pstRDSData->AF_Data.AF[0][2 * indx - 1], + 2 * indx, pstRDSData->AF_Data.AF[0][2 * indx]); + break; + } + } + + num = pstRDSData->AF_Data.AF_Num; + num = (num > 25) ? 25 : num; + WCN_DBG(FM_NTC | RDSC, "RetrieveGroup0 ++num:%d\n", num); + + if (num <= 0) + goto out; + + if ((pstRDSData->AF_Data.AF[0][num - 1]) == 0) + goto out; + + num = num >> 1; + WCN_DBG(FM_NTC | RDSC, "RetrieveGroup0 +++num:%d\n", num); + + /* arrange frequency from low to high:start */ + for (indx = 1; indx < num; indx++) { + for (indx2 = indx + 1; indx2 < (num + 1); indx2++) { + temp_H = pstRDSData->AF_Data.AF[0][2 * indx - 1]; + temp_L = pstRDSData->AF_Data.AF[0][2 * indx]; + + if (temp_H > (pstRDSData->AF_Data.AF[0][2 * indx2 - 1])) { + pstRDSData->AF_Data.AF[0][2 * indx - 1] = + pstRDSData->AF_Data.AF[0][2 * indx2 - 1]; + pstRDSData->AF_Data.AF[0][2 * indx] = + pstRDSData->AF_Data.AF[0][2 * indx2]; + pstRDSData->AF_Data.AF[0][2 * indx2 - 1] = temp_H; + pstRDSData->AF_Data.AF[0][2 * indx2] = temp_L; + } else if (temp_H == (pstRDSData->AF_Data.AF[0][2 * indx2 - 1])) { + if (temp_L > (pstRDSData->AF_Data.AF[0][2 * indx2])) { + pstRDSData->AF_Data.AF[0][2 * indx - 1] = + pstRDSData->AF_Data.AF[0][2 * indx2 - 1]; + pstRDSData->AF_Data.AF[0][2 * indx] = + pstRDSData->AF_Data.AF[0][2 * indx2]; + pstRDSData->AF_Data.AF[0][2 * indx2 - 1] = temp_H; + pstRDSData->AF_Data.AF[0][2 * indx2] = temp_L; + } + } + } + } + + /* arrange frequency from low to high:end */ + /* compare AF buff0 and buff1 data:start */ + num = pstRDSData->AF_Data.AF_Num; + num = (num > 25) ? 25 : num; + indx2 = 0; + + for (indx = 0; indx < num; indx++) { + if ((pstRDSData->AF_Data.AF[1][indx]) == (pstRDSData->AF_Data.AF[0][indx])) { + if (pstRDSData->AF_Data.AF[1][indx] != 0) + indx2++; + } else + pstRDSData->AF_Data.AF[1][indx] = pstRDSData->AF_Data.AF[0][indx]; + } + + WCN_DBG(FM_NTC | RDSC, "RetrieveGroup0 indx2:%d, num:%d\n", indx2, num); + + /* compare AF buff0 and buff1 data:end */ + if (indx2 == num) { + pstRDSData->AF_Data.Addr_Cnt = 0xFF; + pstRDSData->event_status |= RDS_EVENT_AF_LIST; + WCN_DBG(FM_NTC | RDSC, + "RetrieveGroup0 AF_Num:%d\n", + pstRDSData->AF_Data.AF_Num); + + for (indx = 0; indx < num; indx++) { + if ((pstRDSData->AF_Data.AF[1][indx]) == 0) { + pstRDSData->AF_Data.Addr_Cnt = 0x0F; + pstRDSData->event_status &= (~RDS_EVENT_AF_LIST); + } + } + } else + pstRDSData->AF_Data.Addr_Cnt = 0x0F; + } + +out: return ret; +} + +static signed int rds_retrieve_g0_di(unsigned short *block_data, unsigned char SubType, struct rds_t *pstRDSData) +{ + unsigned char DI_Code, DI_Flag; + signed int ret = 0; +/* bool valid = false; */ + + unsigned short *event = &pstRDSData->event_status; + unsigned int *flag = &pstRDSData->RDSFlag.flag_status; + + /* parsing Program service name segment (in BlockD) */ +/* ret = rds_checksum_check(block_data[4], FM_RDS_GDBK_IND_D, &valid); */ + +/* if (valid == false) { */ +/* WCN_DBG(FM_WAR | RDSC, "Group0 BlockD crc err\n"); */ +/* return -FM_ECRC; */ +/* } */ + + rds_g0_ps_addr_get(block_data[1], &DI_Code); + rds_g0_di_flag_get(block_data[1], &DI_Flag); + + switch (DI_Code) { + case 3: + + if (pstRDSData->RDSFlag.Stereo != DI_Flag) { + pstRDSData->RDSFlag.Stereo = DI_Flag; + ret = rds_event_set(event, RDS_EVENT_FLAGS); + ret = rds_flag_set(flag, RDS_FLAG_IS_STEREO); + } + + break; + case 2: + + if (pstRDSData->RDSFlag.Artificial_Head != DI_Flag) { + pstRDSData->RDSFlag.Artificial_Head = DI_Flag; + ret = rds_event_set(event, RDS_EVENT_FLAGS); + ret = rds_flag_set(flag, RDS_FLAG_IS_ARTIFICIAL_HEAD); + } + + break; + case 1: + + if (pstRDSData->RDSFlag.Compressed != DI_Flag) { + pstRDSData->RDSFlag.Compressed = DI_Flag; + ret = rds_event_set(event, RDS_EVENT_FLAGS); + ret = rds_flag_set(flag, RDS_FLAG_IS_COMPRESSED); + } + + break; + case 0: + + if (pstRDSData->RDSFlag.Dynamic_PTY != DI_Flag) { + pstRDSData->RDSFlag.Dynamic_PTY = DI_Flag; + ret = rds_event_set(event, RDS_EVENT_FLAGS); + ret = rds_flag_set(flag, RDS_FLAG_IS_DYNAMIC_PTY); + } + + break; + default: + break; + } + + return ret; +} + +static signed int rds_retrieve_g0_ps(unsigned short *block_data, unsigned char SubType, struct rds_t *pstRDSData) +{ + unsigned char ps_addr; + signed int ret = 0, i, num; + bool valid = false; +/* signed int pos = 0; */ + static struct fm_state_machine ps_sm = { + .state = RDS_PS_START, + .state_get = fm_state_get, + .state_set = fm_state_set, + }; +#if 0 + static struct rds_bitmap ps_bm = { + .bm = 0, + .cnt = 0, + .max_addr = 0x03, + .bm_get = rds_bm_get, + .bm_cnt_get = rds_bm_cnt_get, + .bm_set = rds_bm_set, + .bm_get_pos = rds_bm_get_pos, + .bm_clr = rds_bm_clr, + .bm_cmp = rds_bm_cmp, + }; +#endif + unsigned short *event = &pstRDSData->event_status; + + /* parsing Program service name segment (in BlockD) */ + ret = rds_checksum_check(block_data[4], FM_RDS_GDBK_IND_D, &valid); + + if (valid == false) { + WCN_DBG(FM_WAR | RDSC, "Group0 BlockD crc err\n"); + return -FM_ECRC; + } + + rds_g0_ps_addr_get(block_data[1], &ps_addr); + + /* PS parsing state machine run */ + while (1) { + switch (STATE_GET(&ps_sm)) { + case RDS_PS_START: + if (rds_g0_ps_get(block_data[4], block_data[3], ps_addr, pstRDSData->PS_Data.PS[0])) { + STATE_SET(&ps_sm, RDS_PS_FINISH); /* if CRC error, we should not do parsing */ + break; + } + + rds_g0_ps_cmp(ps_addr, block_data[5], pstRDSData->PS_Data.PS[0], + pstRDSData->PS_Data.PS[1], pstRDSData->PS_Data.PS[2], + /*&valid, */ &pstRDSData->PS_Data.Addr_Cnt); + + /* if (valid == true) { */ + /* ps_bm.bm_set(&ps_bm, ps_addr); */ + /* } */ + + STATE_SET(&ps_sm, RDS_PS_DECISION); + break; + case RDS_PS_DECISION: + + if (pstRDSData->PS_Data.Addr_Cnt == 0x000F) { /* get max 8 chars */ + STATE_SET(&ps_sm, RDS_PS_GETLEN); + } else { + STATE_SET(&ps_sm, RDS_PS_FINISH); + } + + break; + case RDS_PS_GETLEN: + { + num = 0; + WCN_DBG(FM_INF | RDSC, "PS[3]=%x %x %x %x %x %x %x %x\n", + pstRDSData->PS_Data.PS[3][0], + pstRDSData->PS_Data.PS[3][1], + pstRDSData->PS_Data.PS[3][2], + pstRDSData->PS_Data.PS[3][3], + pstRDSData->PS_Data.PS[3][4], + pstRDSData->PS_Data.PS[3][5], + pstRDSData->PS_Data.PS[3][6], pstRDSData->PS_Data.PS[3][7]); + for (i = 0; i < 8; i++) { /* compare with last PS. */ + if (pstRDSData->PS_Data.PS[3][i] == pstRDSData->PS_Data.PS[2][i]) + num++; + } + if (num != 8) { + num = 0; + for (i = 0; i < 8; i++) { + /* even ps=0x20 and bitmap=0xF, send event to host to cover last ps. */ + if (pstRDSData->PS_Data.PS[2][i] == 0x0) + num++; + } + if (num != 8) { + fm_memcpy(pstRDSData->PS_Data.PS[3], pstRDSData->PS_Data.PS[2], 8); + rds_event_set(event, RDS_EVENT_PROGRAMNAME); + WCN_DBG(FM_NTC | RDSC, "Yes, get an PS!\n"); + } else { + /* clear bitmap */ + pstRDSData->PS_Data.Addr_Cnt = 0; + } + } else { + /* if px3==ps2,clear bitmap */ + pstRDSData->PS_Data.Addr_Cnt = 0; + /* clear buf */ + fm_memset(pstRDSData->PS_Data.PS[0], 0x00, 8); + fm_memset(pstRDSData->PS_Data.PS[1], 0x00, 8); + fm_memset(pstRDSData->PS_Data.PS[2], 0x00, 8); + } + } +#if 0 + ps_bm.bm_clr(&ps_bm); + /* clear buf */ + fm_memset(pstRDSData->PS_Data.PS[0], 0x20, 8); + fm_memset(pstRDSData->PS_Data.PS[1], 0x20, 8); + fm_memset(pstRDSData->PS_Data.PS[2], 0x20, 8); +#endif + STATE_SET(&ps_sm, RDS_PS_FINISH); + break; + case RDS_PS_FINISH: + STATE_SET(&ps_sm, RDS_PS_START); + goto out; + default: + break; + } + } + +out: + return ret; +} + +static signed int rds_retrieve_g0(unsigned short *block_data, unsigned char SubType, struct rds_t *pstRDSData) +{ + signed int ret = 0; + + ret = rds_retrieve_g0_af(block_data, SubType, pstRDSData); + + if (ret) + return ret; + + ret = rds_retrieve_g0_di(block_data, SubType, pstRDSData); + + if (ret) + return ret; + + ret = rds_retrieve_g0_ps(block_data, SubType, pstRDSData); + + if (ret) + return ret; + + return ret; +} + +static signed int rds_ecc_get(unsigned short blk, unsigned char *ecc, bool *dirty) +{ + signed int ret = 0; + + if (ecc == NULL) { + pr_err("%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (dirty == NULL) { + pr_err("%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + if (*ecc != (blk & 0xFF)) { + *ecc = (unsigned char)blk & 0xFF; + *dirty = true; /* yes, we got new ecc code */ + } else { + *dirty = false; /* ecc is the same as last one */ + } + + WCN_DBG(FM_NTC | RDSC, "ecc=%02x, %s\n", *ecc, *dirty ? "new" : "old"); + return ret; +} + +static signed int rds_retrieve_g1(unsigned short *block_data, unsigned char SubType, struct rds_t *pstRDSData) +{ + unsigned char variant_code = (block_data[2] & 0x7000) >> 12; + signed int ret = 0; + bool dirty = false; + + if (variant_code == 0) { + ret = rds_ecc_get(block_data[2], &pstRDSData->Extend_Country_Code, &dirty); + if (!ret) { + if (dirty == true) + rds_event_set(&pstRDSData->event_status, RDS_EVENT_ECC_CODE); + } else + WCN_DBG(FM_ERR | RDSC, "get ecc fail(%d)\n", ret); + WCN_DBG(FM_DBG | RDSC, "Extend_Country_Code:%d\n", pstRDSData->Extend_Country_Code); + } else if (variant_code == 3) { + pstRDSData->Language_Code = block_data[2] & 0xFFF; + WCN_DBG(FM_DBG | RDSC, "Language_Code:%d\n", pstRDSData->Language_Code); + } + + pstRDSData->Radio_Page_Code = block_data[1] & 0x001F; + pstRDSData->Program_Item_Number_Code = block_data[3]; + + return ret; +} + +static signed int rds_retrieve_g2(unsigned short *source, unsigned char subtype, struct rds_t *target) +{ + signed int ret = 0; + unsigned short crc, cbc; + unsigned short blkA, blkB, blkC, blkD; + unsigned char *fresh, *once, *twice, *display; + unsigned short *event; + unsigned int *flag; + unsigned short i = 0; + static struct fm_state_machine rt_sm = { + .state = RDS_RT_START, + .state_get = fm_state_get, + .state_set = fm_state_set, + }; + static struct rds_bitmap rt_bm = { + .bm = 0, + .cnt = 0, + .max_addr = 0xF, + .bm_get = rds_bm_get, + .bm_cnt_get = rds_bm_cnt_get, + .bm_set = rds_bm_set, + .bm_get_pos = rds_bm_get_pos, + .bm_clr = rds_bm_clr, + .bm_cmp = rds_bm_cmp, + }; + unsigned char rt_addr = 0; + bool txtAB_change = false; /* text AB flag 0 --> 1 or 1-->0 meas new RT incoming */ + bool txt_end = false; /* 0x0D means text end */ + bool seg_ok = 0; + signed int pos = 0; + signed int rt_len = 0, indx = 0, invalid_cnt = 0; + signed int bufsize = 0; + + if (source == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (target == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + /* source */ + blkA = source[0]; + blkB = source[1]; + blkC = source[2]; + blkD = source[3]; + crc = source[4]; + cbc = source[5]; + /* target */ + fresh = target->RT_Data.TextData[0]; + once = target->RT_Data.TextData[1]; + twice = target->RT_Data.TextData[2]; + display = target->RT_Data.TextData[3]; + event = &target->event_status; + flag = &target->RDSFlag.flag_status; + bufsize = sizeof(target->RT_Data.TextData[0]); + rt_bm.bm = target->RT_Data.Addr_Cnt; + + /* get basic info: addr, txtAB */ + if (rds_g2_rt_addr_get(blkB, &rt_addr)) + return ret; + + if (rds_g2_txtAB_get(blkB, &target->RDSFlag.Text_AB, &txtAB_change)) + return ret; + if (txtAB_change == true) { + /* clear buf */ + fm_memset(fresh, 0x20, bufsize); + fm_memset(once, 0x20, bufsize); + fm_memset(twice, 0x20, bufsize); + rt_bm.bm_clr(&rt_bm); + } + /* RT parsing state machine run */ + while (1) { + switch (STATE_GET(&rt_sm)) { + case RDS_RT_START: + { +#if 0 + if (txtAB_change == true) + STATE_SET(&rt_sm, RDS_RT_DECISION); + else +#endif + { + if (rds_g2_rt_get(crc, subtype, blkC, blkD, rt_addr, fresh) == 0) { + rds_g2_rt_cmp(rt_addr, cbc, subtype, fresh, once, twice, &seg_ok); + + if (seg_ok == true) + rt_bm.bm_set(&rt_bm, rt_addr); + else + rt_bm.bm &= ~(1 << rt_addr); + } + WCN_DBG(FM_NTC | RDSC, "bitmap=0x%04x, bmcnt=%d\n", rt_bm.bm, rt_bm.cnt); + rds_g2_rt_check_end(rt_addr, subtype, twice, &txt_end); + + STATE_SET(&rt_sm, RDS_RT_DECISION); + } + break; + } + case RDS_RT_DECISION: + { + if ((txt_end == true) || (rt_bm.bm_get(&rt_bm) == 0xFFFF) /* get max 64 chars */ + || (rt_bm.bm_cnt_get(&rt_bm) > RDS_RT_MULTI_REV_TH)) { + /* repeate many times, but no end char get */ + pos = rt_bm.bm_get_pos(&rt_bm); + rds_g2_rt_get_len(subtype, pos, &rt_len); + + if (pos == -1) { + STATE_SET(&rt_sm, RDS_RT_FINISH); + } else { + if (rt_addr == pos) { + STATE_SET(&rt_sm, RDS_RT_GETLEN); + } else if (pos > rt_addr) { + rt_bm.bm &= ~(1 << (rt_addr + 1)); + STATE_SET(&rt_sm, RDS_RT_FINISH); + } else + STATE_SET(&rt_sm, RDS_RT_FINISH); + } + + if (txt_end == true) { + for (i = rt_addr + 1; i < rt_bm.max_addr; i++) + rt_bm.bm &= ~(1 << i); + } + } else { + STATE_SET(&rt_sm, RDS_RT_FINISH); + } + + break; + } + case RDS_RT_GETLEN: + if (rt_len > 0) { + for (indx = 0; indx < rt_len; indx++) { + if (twice[indx] == 0x20) + invalid_cnt++; + } + if (invalid_cnt != rt_len) { + if (memcmp(display, twice, bufsize) != 0) { + fm_memcpy(display, twice, bufsize); + target->RT_Data.TextLength = rt_len; + rds_event_set(event, RDS_EVENT_LAST_RADIOTEXT); + /* yes we got a new RT */ + WCN_DBG(FM_NTC | RDSC, "Yes, get an RT! [len=%d]\n", rt_len); + } + rt_bm.bm_clr(&rt_bm); + /* clear buf */ + fm_memset(fresh, 0x20, bufsize); + fm_memset(once, 0x20, bufsize); + fm_memset(twice, 0x20, bufsize); + } else + WCN_DBG(FM_NTC | RDSC, "Get 0x20 RT %d\n", invalid_cnt); + } +#if 0 + if (txtAB_change == true) { + txtAB_change = false; + /* we need get new RT after show the old RT to the display */ + STATE_SET(&rt_sm, RDS_RT_START); + } else +#endif + { + STATE_SET(&rt_sm, RDS_RT_FINISH); + } + break; + case RDS_RT_FINISH: + STATE_SET(&rt_sm, RDS_RT_START); + goto out; + default: + break; + } + } + +out: + target->RT_Data.Addr_Cnt = rt_bm.bm; + return ret; +} + +static signed int rds_retrieve_g4(unsigned short *block_data, unsigned char SubType, struct rds_t *pstRDSData) +{ + unsigned short year, month, k = 0, D2, minute; + unsigned int MJD, D1; + signed int ret = 0; + + WCN_DBG(FM_DBG | RDSC, "RetrieveGroup4 %d\n", SubType); + + if (!SubType) { + /* Type A */ + if ((block_data[4] & FM_RDS_GDBK_IND_C) && (block_data[4] & FM_RDS_GDBK_IND_D)) { + MJD = (unsigned int) (((block_data[1] & 0x0003) << 15) + ((block_data[2] & 0xFFFE) >> 1)); + year = (MJD * 100 - 1507820) / 36525; + + if (year > 1000) { + WCN_DBG(FM_DBG | RDSC, "Abnormal year: %d.\n", year); + return ret; + } + + month = (MJD * 10000 - 149561000 - 3652500 * year) / 306001; + + if ((month == 14) || (month == 15)) + k = 1; + + D1 = (unsigned int) ((36525 * year) / 100); + D2 = (unsigned short) ((306001 * month) / 10000); + pstRDSData->CT.Year = 1900 + year + k; + pstRDSData->CT.Month = month - 1 - k * 12; + pstRDSData->CT.Day = (unsigned short) (MJD - 14956 - D1 - D2); + pstRDSData->CT.Hour = ((block_data[2] & 0x0001) << 4) + ((block_data[3] & 0xF000) >> 12); + minute = (block_data[3] & 0x0FC0) >> 6; + + if (block_data[3] & 0x0020) + pstRDSData->CT.Local_Time_offset_signbit = 1; /* 0=+, 1=- */ + + pstRDSData->CT.Local_Time_offset_half_hour = block_data[3] & 0x001F; + + if (pstRDSData->CT.Minute != minute) { + pstRDSData->CT.Minute = (block_data[3] & 0x0FC0) >> 6; + pstRDSData->event_status |= RDS_EVENT_UTCDATETIME; + } + } + } + + return ret; +} + +static signed int rds_retrieve_g14(unsigned short *block_data, unsigned char SubType, struct rds_t *pstRDSData) +{ + static signed short preAFON_Num; + unsigned char TP_ON, TA_ON, PI_ON, AF_H, AF_L, indx, indx2, num; + unsigned short PS_Num = 0; + signed int ret = 0; + + WCN_DBG(FM_DBG | RDSC, "RetrieveGroup14 %d\n", SubType); + /* SubType = (*(block_data+1)&0x0800)>>11; */ + PI_ON = block_data[3]; + TP_ON = block_data[1] & 0x0010; + + if ((!SubType) && (block_data[4] & FM_RDS_GDBK_IND_C)) { + /* Type A */ + PS_Num = block_data[1] & 0x000F; /* variant code */ + + if (PS_Num >= 0 && PS_Num < 4) { /* variant code = 0~3 represent PS */ + for (indx = 0; indx < 2; indx++) { + pstRDSData->PS_ON[2 * PS_Num] = block_data[2] >> 8; + pstRDSData->PS_ON[2 * PS_Num + 1] = block_data[2] & 0xFF; + } + + goto out; + } else if (PS_Num < 0 || PS_Num > 4) /* variant code > 4 */ + goto out; + + /* variant code = 4 represent AF(ON) */ + + AF_H = (block_data[2] & 0xFF00) >> 8; + AF_L = block_data[2] & 0x00FF; + + if ((AF_H > 224) && (AF_H < 250)) { + /* Followed AF Number */ + pstRDSData->AFON_Data.isAFNum_Get = 0; + preAFON_Num = AF_H - 224; + + if (pstRDSData->AFON_Data.AF_Num != preAFON_Num) + pstRDSData->AFON_Data.AF_Num = preAFON_Num; + else + pstRDSData->AFON_Data.isAFNum_Get = 1; + + if (AF_L < 205) { + pstRDSData->AFON_Data.AF[0][0] = AF_L + 875; + + if ((pstRDSData->AFON_Data.AF[0][0]) != (pstRDSData->AFON_Data.AF[1][0])) + pstRDSData->AFON_Data.AF[1][0] = pstRDSData->AFON_Data.AF[0][0]; + else + pstRDSData->AFON_Data.isMethod_A = 1; + } + + goto out; + } + + if (!(pstRDSData->AFON_Data.isAFNum_Get) || ((pstRDSData->AFON_Data.Addr_Cnt) == 0xFF)) + goto out; + + /* AF Num correct */ + num = pstRDSData->AFON_Data.AF_Num; + num = (num > 25) ? 25 : num; + num = num >> 1; + + /* Put AF freq into buffer and check if AF freq is repeat again */ + for (indx = 1; indx < (num + 1); indx++) { + if ((AF_H == (pstRDSData->AFON_Data.AF[0][2 * indx - 1])) + && (AF_L == (pstRDSData->AFON_Data.AF[0][2 * indx]))) { + WCN_DBG(FM_NTC | RDSC, "RetrieveGroup14 AFON same as indx:%d\n", indx); + break; + } else if (!(pstRDSData->AFON_Data.AF[0][2 * indx - 1])) { + /* null buffer */ + pstRDSData->AFON_Data.AF[0][2 * indx - 1] = AF_H + 875; + pstRDSData->AFON_Data.AF[0][2 * indx] = AF_L + 875; + break; + } + } + + num = pstRDSData->AFON_Data.AF_Num; + num = (num > 25) ? 25 : num; + if (num <= 0) + goto out; + + if ((pstRDSData->AFON_Data.AF[0][num - 1]) == 0) + goto out; + + num = num >> 1; + /* arrange frequency from low to high:start */ + for (indx = 1; indx < num; indx++) { + for (indx2 = indx + 1; indx2 < (num + 1); indx2++) { + AF_H = pstRDSData->AFON_Data.AF[0][2 * indx - 1]; + AF_L = pstRDSData->AFON_Data.AF[0][2 * indx]; + + if (AF_H > (pstRDSData->AFON_Data.AF[0][2 * indx2 - 1])) { + pstRDSData->AFON_Data.AF[0][2 * indx - 1] = + pstRDSData->AFON_Data.AF[0][2 * indx2 - 1]; + pstRDSData->AFON_Data.AF[0][2 * indx] = + pstRDSData->AFON_Data.AF[0][2 * indx2]; + pstRDSData->AFON_Data.AF[0][2 * indx2 - 1] = + AF_H; + pstRDSData->AFON_Data.AF[0][2 * indx2] = AF_L; + } else if (AF_H == (pstRDSData->AFON_Data.AF[0][2 * indx2 - 1])) { + if (AF_L > (pstRDSData->AFON_Data.AF[0][2 * indx2])) { + pstRDSData->AFON_Data.AF[0][2 * indx - 1] = + pstRDSData->AFON_Data.AF[0][2 * indx2 - 1]; + pstRDSData->AFON_Data.AF[0][2 * indx] = + pstRDSData->AFON_Data.AF[0][2 * indx2]; + pstRDSData->AFON_Data.AF[0][2 * indx2 - 1] = AF_H; + pstRDSData->AFON_Data.AF[0][2 * indx2] = AF_L; + } + } + } + } + + /* arrange frequency from low to high:end */ + /* compare AF buff0 and buff1 data:start */ + num = pstRDSData->AFON_Data.AF_Num; + num = (num > 25) ? 25 : num; + indx2 = 0; + + for (indx = 0; indx < num; indx++) { + if ((pstRDSData->AFON_Data.AF[1][indx]) == (pstRDSData->AFON_Data.AF[0][indx])) { + if (pstRDSData->AFON_Data.AF[1][indx] != 0) + indx2++; + } else + pstRDSData->AFON_Data.AF[1][indx] = pstRDSData->AFON_Data.AF[0][indx]; + } + + /* compare AF buff0 and buff1 data:end */ + if (indx2 == num) { + pstRDSData->AFON_Data.Addr_Cnt = 0xFF; + pstRDSData->event_status |= RDS_EVENT_AFON_LIST; + + for (indx = 0; indx < num; indx++) { + if ((pstRDSData->AFON_Data.AF[1][indx]) == 0) { + pstRDSData->AFON_Data.Addr_Cnt = 0x0F; + pstRDSData->event_status &= (~RDS_EVENT_AFON_LIST); + } + } + } else + pstRDSData->AFON_Data.Addr_Cnt = 0x0F; + } else { + /* Type B */ + TA_ON = block_data[1] & 0x0008; + WCN_DBG(FM_DBG | RDSC, + "TA g14 typeB pstRDSData->RDSFlag.TP=%d pstRDSData->RDSFlag.TA=%d TP_ON=%d TA_ON=%d\n", + pstRDSData->RDSFlag.TP, pstRDSData->RDSFlag.TA, TP_ON, TA_ON); + + if ((!pstRDSData->RDSFlag.TP) && (pstRDSData->RDSFlag.TA) && TP_ON && TA_ON) { + signed int TA_num = 0; + + for (num = 0; num < 25; num++) { + if (pstRDSData->AFON_Data.AF[1][num] != 0) + TA_num++; + else + break; + } + + WCN_DBG(FM_NTC | RDSC, "TA set RDS_EVENT_TAON"); + + if (TA_num == pstRDSData->AFON_Data.AF_Num) + pstRDSData->event_status |= RDS_EVENT_TAON; + } + } + +out: return ret; +} + +/* + * rds_parser + * Block0: PI code(16bits) + * Block1: Group type(4bits), B0=version code(1bit), TP=traffic program code(1bit), + * PTY=program type code(5bits), other(5bits) + * Block2: 16bits + * Block3: 16bits + * @rds_dst - target buffer that record RDS parsing result + * @rds_raw - rds raw data + * @rds_size - size of rds raw data + * @getfreq - function pointer, AF need get current freq + */ +signed int rds_parser(struct rds_t *rds_dst, struct rds_rx_t *rds_raw, + signed int rds_size, unsigned short(*getfreq) (void)) +{ + signed int ret = 0; + /* block_data[0] = blockA, block_data[1] = blockB, block_data[2] = blockC, block_data[3] = blockD, */ + /* block_data[4] = CRC, block_data[5] = CBC */ + unsigned short block_data[6]; + unsigned char GroupType, SubType = 0; + signed int rds_cnt = 0; + signed int i = 0; + bool dirty = false; + /* target buf to fill the result in */ + unsigned short *event = &rds_dst->event_status; + unsigned int *flag = &rds_dst->RDSFlag.flag_status; + + if (getfreq == NULL) { + WCN_DBG(FM_ERR | RDSC, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + rds_get_freq = getfreq; + + ret = rds_cnt_get(rds_raw, rds_size, &rds_cnt); + + if (ret) { + WCN_DBG(FM_WAR | RDSC, "get cnt err[ret=%d]\n", ret); + return ret; + } + + while (rds_cnt > 0) { + ret = rds_grp_get(&block_data[0], rds_raw, i); + + if (ret) { + WCN_DBG(FM_WAR | RDSC, "get group err[ret=%d]\n", ret); + goto do_next; + } + + ret = rds_grp_type_get(block_data[4], block_data[1], &GroupType, &SubType); + + if (ret) { + WCN_DBG(FM_WAR | RDSC, "get group type err[ret=%d]\n", ret); + goto do_next; + } + + ret = rds_grp_counter_add(GroupType, SubType, &rds_dst->gc); + + ret = rds_grp_pi_get(block_data[4], block_data[0], &rds_dst->PI, &dirty); + + if (ret) { + WCN_DBG(FM_WAR | RDSC, "get group pi err[ret=%d]\n", ret); + goto do_next; + } else if (dirty == false) { + WCN_DBG(FM_INF | RDSC, "dirty = %d, update PI event\n", dirty); + ret = rds_event_set(event, RDS_EVENT_PI_CODE); /* yes, we got same PI, can be trust */ + } + + ret = rds_grp_pty_get(block_data[4], block_data[1], &rds_dst->PTY, &dirty); + + if (ret) { + WCN_DBG(FM_WAR | RDSC, "get group pty err[ret=%d]\n", ret); + goto do_next; + } else if (dirty == true) { + ret = rds_event_set(event, RDS_EVENT_PTY_CODE); /* yes, we got new PTY code */ + } + + ret = rds_grp_tp_get(block_data[4], block_data[1], &rds_dst->RDSFlag.TP, &dirty); + + if (ret) { + WCN_DBG(FM_WAR | RDSC, "get group tp err[ret=%d]\n", ret); + goto do_next; + } else if (dirty == true) { + ret = rds_event_set(event, RDS_EVENT_FLAGS); /* yes, we got new TP code */ + ret = rds_flag_set(flag, RDS_FLAG_IS_TP); + } + + switch (GroupType) { + case 0: + ret = rds_retrieve_g0(&block_data[0], SubType, rds_dst); + if (ret) + goto do_next; + + break; + case 1: + ret = rds_retrieve_g1(&block_data[0], SubType, rds_dst); + if (ret) + goto do_next; + + break; + case 2: + ret = rds_retrieve_g2(&block_data[0], SubType, rds_dst); + if (ret) + goto do_next; + + break; + case 4: + ret = rds_retrieve_g4(&block_data[0], SubType, rds_dst); + if (ret) + goto do_next; + + break; + case 14: + ret = rds_retrieve_g14(&block_data[0], SubType, rds_dst); + if (ret) + goto do_next; + + break; + default: + break; + } + +do_next: + + if (ret && (ret != -FM_ECRC)) { + WCN_DBG(FM_ERR | RDSC, "parsing err[ret=%d]\n", ret); + return ret; + } + + rds_cnt--; + i++; + } + + return ret; +} diff --git a/drivers/misc/mediatek/connectivity/fmradio/core/fm_reg_utils.c b/drivers/misc/mediatek/connectivity/fmradio/core/fm_reg_utils.c new file mode 100644 index 0000000000000000000000000000000000000000..24e4851d9e066ba1fbe4dc1fee0099d0a0e41014 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/core/fm_reg_utils.c @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +#include "fm_typedef.h" +#include "fm_dbg.h" +#include "fm_err.h" +#include "fm_stdlib.h" +#include "fm_link.h" +#include "fm_utils.h" +#include "fm_reg_utils.h" +#include "plat.h" + +struct fm_wcn_reg_ops fm_wcn_ops; +unsigned char *cmd_buf; +struct fm_lock *cmd_buf_lock; +struct fm_res_ctx *fm_res; + +void fw_spi_read(unsigned char addr, unsigned short *data) +{ + struct fm_spi_interface *si = &fm_wcn_ops.si; + int ret = 0; + unsigned int rdata; + + ret = si->sys_spi_read(si, SYS_SPI_FM, addr, &rdata); + if (ret) + WCN_DBG(FM_ERR | CHIP, "read error[%d].\n", ret); + *data = (unsigned short)rdata; +} + +void fw_spi_write(unsigned char addr, unsigned short data) +{ + struct fm_spi_interface *si = &fm_wcn_ops.si; + int ret = 0; + unsigned int wdata = (unsigned int)data; + + ret = si->sys_spi_write(si, SYS_SPI_FM, addr, wdata); + if (ret) + WCN_DBG(FM_ERR | CHIP, "write error[%d].\n", ret); +} + +void fw_bop_udelay(unsigned int usec) +{ + fm_delayus(usec); +} + +void fw_bop_rd_until(unsigned char addr, unsigned short mask, + unsigned short value) +{ + unsigned short data, count = 0; + + do { + fm_delayus(1000); + fw_spi_read(addr, &data); + count++; + } while (((data & mask) != value) && (count < 3000)); + + /* 3000ms should be big enough for polling bits */ + if (count == 3000) + WCN_DBG(FM_WAR | CHIP, "Value is never changed.\n"); +} + +void fw_bop_modify(unsigned char addr, unsigned short mask_and, + unsigned short mask_or) +{ + unsigned short data; + + fw_spi_read(addr, &data); + data &= mask_and; + data |= mask_or; + fw_spi_write(addr, data); +} + +void fw_bop_spi_rd_until(unsigned char subsys, unsigned short addr, + unsigned int mask, unsigned int value) +{ + struct fm_spi_interface *si = &fm_wcn_ops.si; + unsigned int data; + unsigned short count = 0; + + do { + fm_delayus(1000); + si->sys_spi_read(si, subsys, addr, &data); + count++; + } while (((data & mask) != value) && (count < 3000)); + + /* 3000ms should be big enough for polling bits */ + if (count == 3000) + WCN_DBG(FM_WAR | CHIP, "Value is never changed.\n"); +} + +void fw_bop_spi_modify(unsigned char subsys, unsigned short addr, + unsigned int mask_and, unsigned int mask_or) +{ + struct fm_spi_interface *si = &fm_wcn_ops.si; + unsigned int data; + + si->sys_spi_read(si, subsys, addr, &data); + data &= mask_and; + data |= mask_or; + si->sys_spi_write(si, subsys, addr, data); +} diff --git a/drivers/misc/mediatek/connectivity/fmradio/core/fm_utils.c b/drivers/misc/mediatek/connectivity/fmradio/core/fm_utils.c new file mode 100644 index 0000000000000000000000000000000000000000..b620512166437b99def10c5069fb77d772d5e9da --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/core/fm_utils.c @@ -0,0 +1,859 @@ +/* + * Copyright (C) 2015 MediaTek Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include "fm_typedef.h" +#include "fm_dbg.h" +#include "fm_err.h" +#include "fm_stdlib.h" +#include "fm_utils.h" + +signed int fm_delayms(unsigned int data) +{ + WCN_DBG(FM_DBG | CHIP, "delay %dms\n", data); + msleep(data); + return 0; +} + +signed int fm_delayus(unsigned int data) +{ + WCN_DBG(FM_DBG | CHIP, "delay %dus\n", data); + udelay(data); + return 0; +} + +static unsigned int fm_event_send(struct fm_flag_event *thiz, unsigned int mask) +{ + thiz->flag |= mask; + /* WCN_DBG(FM_DBG|MAIN, "%s set 0x%08x\n", thiz->name, thiz->flag); */ + wake_up((wait_queue_head_t *) (thiz->priv)); + + return thiz->flag; +} + +static signed int fm_event_wait(struct fm_flag_event *thiz, unsigned int mask) +{ + return wait_event_interruptible(*(wait_queue_head_t *) (thiz->priv), ((thiz->flag & mask) == mask)); +} + +/** + * fm_event_check - sleep until a condition gets true or a timeout elapses + * @thiz: the pointer of current object + * @mask: bitmap in unsigned int + * @timeout: timeout, in jiffies + * + * fm_event_set() has to be called after changing any variable that could + * change the result of the wait condition. + * + * The function returns 0 if the @timeout elapsed, and the remaining + * jiffies if the condition evaluated to true before the timeout elapsed. + */ +long fm_event_wait_timeout(struct fm_flag_event *thiz, unsigned int mask, long timeout) +{ + return wait_event_timeout(*((wait_queue_head_t *) (thiz->priv)), ((thiz->flag & mask) == mask), timeout * HZ); +} + +static unsigned int fm_event_clr(struct fm_flag_event *thiz, unsigned int mask) +{ + thiz->flag &= ~mask; + /* WCN_DBG(FM_DBG|MAIN, "%s clr 0x%08x\n", thiz->name, thiz->flag); */ + return thiz->flag; +} + +static unsigned int fm_event_get(struct fm_flag_event *thiz) +{ + return thiz->flag; + +} + +static unsigned int fm_event_rst(struct fm_flag_event *thiz) +{ + return thiz->flag = 0; +} + +struct fm_flag_event *fm_flag_event_create(const signed char *name) +{ + struct fm_flag_event *tmp; + wait_queue_head_t *wq; + + tmp = fm_zalloc(sizeof(struct fm_flag_event)); + if (!tmp) { + WCN_DBG(FM_ALT | MAIN, "fm_zalloc(fm_event) -ENOMEM\n"); + return NULL; + } + + wq = fm_zalloc(sizeof(wait_queue_head_t)); + if (!wq) { + WCN_DBG(FM_ALT | MAIN, "fm_zalloc(wait_queue_head_t) -ENOMEM\n"); + fm_free(tmp); + return NULL; + } + + fm_memcpy(tmp->name, name, (strlen(name) > FM_NAME_MAX) ? (FM_NAME_MAX) : (strlen(name))); + tmp->priv = wq; + init_waitqueue_head(wq); + tmp->ref = 0; + + tmp->send = fm_event_send; + tmp->wait = fm_event_wait; + tmp->wait_timeout = fm_event_wait_timeout; + tmp->clr = fm_event_clr; + tmp->get = fm_event_get; + tmp->rst = fm_event_rst; + + tmp->rst(tmp); /* set flag to 0x00000000 */ + + return tmp; +} + +signed int fm_flag_event_get(struct fm_flag_event *thiz) +{ + if (thiz == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + thiz->ref++; + return 0; +} + +signed int fm_flag_event_put(struct fm_flag_event *thiz) +{ + if (thiz == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + thiz->ref--; + + if (thiz->ref == 0) { + fm_free(thiz->priv); + fm_free(thiz); + return 0; + } else if (thiz->ref > 0) { + return -FM_EINUSE; + } else { + return -FM_EPARA; + } +} + +/* fm lock methods */ +static signed int fm_lock_try(struct fm_lock *thiz, signed int retryCnt) +{ + signed int retry_cnt = 0; + struct semaphore *sem; + struct task_struct *task = current; + + if (thiz == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (thiz->priv == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + while (down_trylock((struct semaphore *)thiz->priv)) { + WCN_DBG(FM_WAR | MAIN, "down_trylock failed\n"); + if (++retry_cnt < retryCnt) { + WCN_DBG(FM_WAR | MAIN, "[retryCnt=%d]\n", retry_cnt); + msleep_interruptible(50); + continue; + } else { + WCN_DBG(FM_CRT | MAIN, "down_trylock retry failed\n"); + return -FM_ELOCK; + } + } + + sem = (struct semaphore *)thiz->priv; + WCN_DBG(FM_NTC | MAIN, "%s --->trylock, cnt=%d, pid=%d\n", thiz->name, (int)sem->count, task->pid); + return 0; +} + +/* fm try lock methods */ +static signed int fm_lock_lock(struct fm_lock *thiz) +{ + struct semaphore *sem; + struct task_struct *task = current; + + if (thiz == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (thiz->priv == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + if (down_interruptible((struct semaphore *)thiz->priv)) { + WCN_DBG(FM_CRT | MAIN, "get mutex failed\n"); + return -FM_ELOCK; + } + + sem = (struct semaphore *)thiz->priv; + WCN_DBG(FM_DBG | MAIN, "%s --->lock, cnt=%d, pid=%d\n", + thiz->name, (int)sem->count, task->pid); + return 0; +} + +static signed int fm_lock_unlock(struct fm_lock *thiz) +{ + struct semaphore *sem; + struct task_struct *task = current; + + if (thiz == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (thiz->priv == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + sem = (struct semaphore *)thiz->priv; + WCN_DBG(FM_DBG | MAIN, "%s <---unlock, cnt=%d, pid=%d\n", + thiz->name, (int)sem->count + 1, task->pid); + up((struct semaphore *)thiz->priv); + return 0; +} + +struct fm_lock *fm_lock_create(const signed char *name) +{ + struct fm_lock *tmp; + struct semaphore *mutex; + + tmp = fm_zalloc(sizeof(struct fm_lock)); + if (!tmp) { + WCN_DBG(FM_ALT | MAIN, "fm_zalloc(fm_lock) -ENOMEM\n"); + return NULL; + } + + mutex = fm_zalloc(sizeof(struct semaphore)); + if (!mutex) { + WCN_DBG(FM_ALT | MAIN, "fm_zalloc(struct semaphore) -ENOMEM\n"); + fm_free(tmp); + return NULL; + } + + tmp->priv = mutex; + sema_init(mutex, 1); + tmp->ref = 0; + fm_memcpy(tmp->name, name, (strlen(name) > FM_NAME_MAX) ? (FM_NAME_MAX) : (strlen(name))); + + tmp->lock = fm_lock_lock; + tmp->trylock = fm_lock_try; + tmp->unlock = fm_lock_unlock; + + return tmp; +} + +signed int fm_lock_get(struct fm_lock *thiz) +{ + if (thiz == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + thiz->ref++; + return 0; +} + +signed int fm_lock_put(struct fm_lock *thiz) +{ + if (thiz == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + thiz->ref--; + + if (thiz->ref == 0) { + fm_free(thiz->priv); + fm_free(thiz); + return 0; + } else if (thiz->ref > 0) { + return -FM_EINUSE; + } else { + return -FM_EPARA; + } +} + +/* fm lock methods */ +static signed int fm_spin_lock_lock(struct fm_lock *thiz) +{ + struct task_struct *task = current; + + if (thiz == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (thiz->priv == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + spin_lock_bh((spinlock_t *) thiz->priv); + + WCN_DBG(FM_DBG | MAIN, "%s --->lock pid=%d\n", thiz->name, task->pid); + return 0; +} + +static signed int fm_spin_lock_unlock(struct fm_lock *thiz) +{ + struct task_struct *task = current; + + if (thiz == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (thiz->priv == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + WCN_DBG(FM_DBG | MAIN, "%s <---unlock, pid=%d\n", thiz->name, task->pid); + spin_unlock_bh((spinlock_t *) thiz->priv); + return 0; +} + +struct fm_lock *fm_spin_lock_create(const signed char *name) +{ + struct fm_lock *tmp; + spinlock_t *spin_lock; + + tmp = fm_zalloc(sizeof(struct fm_lock)); + if (!tmp) { + WCN_DBG(FM_ALT | MAIN, "fm_zalloc(fm_lock) -ENOMEM\n"); + return NULL; + } + + spin_lock = fm_zalloc(sizeof(spinlock_t)); + if (!spin_lock) { + WCN_DBG(FM_ALT | MAIN, "fm_zalloc(spinlock_t) -ENOMEM\n"); + fm_free(tmp); + return NULL; + } + + tmp->priv = spin_lock; + spin_lock_init(spin_lock); + tmp->ref = 0; + fm_memcpy(tmp->name, name, (strlen(name) > FM_NAME_MAX) ? (FM_NAME_MAX) : (strlen(name))); + + tmp->lock = fm_spin_lock_lock; + tmp->unlock = fm_spin_lock_unlock; + + return tmp; +} + +signed int fm_spin_lock_get(struct fm_lock *thiz) +{ + if (thiz == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + thiz->ref++; + return 0; +} + +signed int fm_spin_lock_put(struct fm_lock *thiz) +{ + if (thiz == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + thiz->ref--; + + if (thiz->ref == 0) { + fm_free(thiz->priv); + fm_free(thiz); + return 0; + } else if (thiz->ref > 0) { + return -FM_EINUSE; + } else { + return -FM_EPARA; + } +} + +/* + * fm timer + * + */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) +static signed int fm_timer_init(struct fm_timer *thiz, void (*timeout) (struct timer_list *timer), + unsigned long data, signed long time, signed int flag) +#else +static signed int fm_timer_init(struct fm_timer *thiz, void (*timeout) (unsigned long data), + unsigned long data, signed long time, signed int flag) +#endif +{ + struct timer_list *timerlist = (struct timer_list *)thiz->priv; + + thiz->flag = flag; + thiz->flag &= ~FM_TIMER_FLAG_ACTIVATED; + thiz->timeout_func = timeout; + thiz->data = data; + thiz->timeout_ms = time; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) + timer_setup(timerlist, thiz->timeout_func, 0); +#else + init_timer(timerlist); + timerlist->function = thiz->timeout_func; + timerlist->data = (unsigned long)thiz->data; +#endif + timerlist->expires = jiffies + (thiz->timeout_ms) / (1000 / HZ); + + return 0; +} + +static signed int fm_timer_start(struct fm_timer *thiz) +{ + struct timer_list *timerlist = (struct timer_list *)thiz->priv; + + thiz->flag |= FM_TIMER_FLAG_ACTIVATED; + mod_timer(timerlist, jiffies + (thiz->timeout_ms) / (1000 / HZ)); + + return 0; +} + +static signed int fm_timer_update(struct fm_timer *thiz) +{ + struct timer_list *timerlist = (struct timer_list *)thiz->priv; + + if (thiz->flag & FM_TIMER_FLAG_ACTIVATED) { + mod_timer(timerlist, jiffies + (thiz->timeout_ms) / (1000 / HZ)); + return 0; + } else { + return 1; + } +} + +static signed int fm_timer_stop(struct fm_timer *thiz) +{ + struct timer_list *timerlist = (struct timer_list *)thiz->priv; + + thiz->flag &= ~FM_TIMER_FLAG_ACTIVATED; + del_timer(timerlist); + + return 0; +} + +static signed int fm_timer_control(struct fm_timer *thiz, enum fm_timer_ctrl cmd, void *arg) +{ + + return 0; +} + +struct fm_timer *fm_timer_create(const signed char *name) +{ + struct fm_timer *tmp; + struct timer_list *timerlist; + + tmp = fm_zalloc(sizeof(struct fm_timer)); + if (!tmp) { + WCN_DBG(FM_ALT | MAIN, "fm_zalloc(fm_timer) -ENOMEM\n"); + return NULL; + } + + timerlist = fm_zalloc(sizeof(struct timer_list)); + if (!timerlist) { + WCN_DBG(FM_ALT | MAIN, "fm_zalloc(struct timer_list) -ENOMEM\n"); + fm_free(tmp); + return NULL; + } + + fm_memcpy(tmp->name, name, (strlen(name) > FM_NAME_MAX) ? (FM_NAME_MAX) : (strlen(name))); + tmp->priv = timerlist; + tmp->ref = 0; + tmp->init = fm_timer_init; + tmp->start = fm_timer_start; + tmp->stop = fm_timer_stop; + tmp->update = fm_timer_update; + tmp->control = fm_timer_control; + + return tmp; +} + +signed int fm_timer_get(struct fm_timer *thiz) +{ + if (thiz == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + thiz->ref++; + return 0; +} + +signed int fm_timer_put(struct fm_timer *thiz) +{ + if (thiz == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + thiz->ref--; + + if (thiz->ref == 0) { + fm_free(thiz->priv); + fm_free(thiz); + return 0; + } else if (thiz->ref > 0) { + return -FM_EINUSE; + } else { + return -FM_EPARA; + } +} + +/* + * FM work thread mechanism + */ +static signed int fm_work_init(struct fm_work *thiz, work_func_t work_func, unsigned long data) +{ + struct work_struct *sys_work = (struct work_struct *)thiz->priv; + work_func_t func; + + thiz->work_func = work_func; + thiz->data = data; + func = (work_func_t) thiz->work_func; + + INIT_WORK(sys_work, func); + + return 0; + +} + +struct fm_work *fm_work_create(const signed char *name) +{ + struct fm_work *my_work; + struct work_struct *sys_work; + + my_work = fm_zalloc(sizeof(struct fm_work)); + if (!my_work) { + WCN_DBG(FM_ALT | MAIN, "fm_zalloc(fm_work) -ENOMEM\n"); + return NULL; + } + + sys_work = fm_zalloc(sizeof(struct work_struct)); + if (!sys_work) { + WCN_DBG(FM_ALT | MAIN, "fm_zalloc(struct work_struct) -ENOMEM\n"); + fm_free(my_work); + return NULL; + } + + fm_memcpy(my_work->name, name, (strlen(name) > FM_NAME_MAX) ? (FM_NAME_MAX) : (strlen(name))); + my_work->priv = sys_work; + my_work->init = fm_work_init; + + return my_work; +} + +signed int fm_work_get(struct fm_work *thiz) +{ + if (thiz == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + thiz->ref++; + return 0; +} + +signed int fm_work_put(struct fm_work *thiz) +{ + if (thiz == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + thiz->ref--; + + if (thiz->ref == 0) { + fm_free(thiz->priv); + fm_free(thiz); + return 0; + } else if (thiz->ref > 0) { + return -FM_EINUSE; + } else { + return -FM_EPARA; + } +} + +static signed int fm_workthread_add_work(struct fm_workthread *thiz, struct fm_work *work) +{ + if (thiz == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + if (work == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + queue_work((struct workqueue_struct *)thiz->priv, (struct work_struct *)work->priv); + return 0; +} + +struct fm_workthread *fm_workthread_create(const signed char *name) +{ + struct fm_workthread *my_thread; + struct workqueue_struct *sys_thread; + + my_thread = fm_zalloc(sizeof(struct fm_workthread)); + if (!my_thread) { + WCN_DBG(FM_ALT | MAIN, "fm_zalloc(fm_workthread) -ENOMEM\n"); + return NULL; + } + + sys_thread = create_singlethread_workqueue(name); + + fm_memcpy(my_thread->name, name, (strlen(name) > FM_NAME_MAX) ? (FM_NAME_MAX) : (strlen(name))); + my_thread->priv = sys_thread; + my_thread->add_work = fm_workthread_add_work; + + return my_thread; +} + +signed int fm_workthread_get(struct fm_workthread *thiz) +{ + if (thiz == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + thiz->ref++; + return 0; +} + +signed int fm_workthread_put(struct fm_workthread *thiz) +{ + if (thiz == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + thiz->ref--; + + if (thiz->ref == 0) { + destroy_workqueue((struct workqueue_struct *)thiz->priv); + fm_free(thiz); + return 0; + } else if (thiz->ref > 0) { + return -FM_EINUSE; + } else { + return -FM_EPARA; + } +} + +FM_WAKE_LOCK_T *fm_wakelock_create(const signed char *name) +{ + FM_WAKE_LOCK_T *lock; +#if (KERNEL_VERSION(4, 14, 149) <= LINUX_VERSION_CODE) + lock = wakeup_source_register(NULL, name); +#elif (KERNEL_VERSION(4, 9, 0) <= LINUX_VERSION_CODE) + lock = fm_zalloc(sizeof(FM_WAKE_LOCK_T)); + if (lock) + wakeup_source_init(lock, name); +#else + lock = fm_zalloc(sizeof(FM_WAKE_LOCK_T)); + if (lock) + wake_lock_init(lock, WAKE_LOCK_SUSPEND, name); +#endif + return lock; +} + +void fm_wakelock_destroy(FM_WAKE_LOCK_T *lock) +{ +#if (KERNEL_VERSION(4, 14, 149) <= LINUX_VERSION_CODE) + wakeup_source_unregister(lock); +#elif (KERNEL_VERSION(4, 9, 0) <= LINUX_VERSION_CODE) + wakeup_source_trash(lock); + fm_free(lock); +#else + wake_lock_destroy(lock); + fm_free(lock); +#endif + lock = NULL; +} + +void fm_wakelock_get(FM_WAKE_LOCK_T *lock) +{ + if (lock) +#if (KERNEL_VERSION(4, 9, 0) <= LINUX_VERSION_CODE) + __pm_stay_awake(lock); +#else + wake_lock(lock); +#endif +} + +void fm_wakelock_put(FM_WAKE_LOCK_T *lock) +{ + if (lock) +#if (KERNEL_VERSION(4, 9, 0) <= LINUX_VERSION_CODE) + __pm_relax(lock); +#else + wake_unlock(lock); +#endif +} + +signed int fm_fifo_in(struct fm_fifo *thiz, void *item) +{ + if (item == NULL) { + WCN_DBG(FM_ERR | MAIN, "%s,invalid pointer\n", __func__); + return -FM_EPARA; + } + + if (thiz->len < thiz->size) { + fm_memcpy((thiz->obj.priv + (thiz->item_size * thiz->in)), item, thiz->item_size); + thiz->in = (thiz->in + 1) % thiz->size; + thiz->len++; + /* WCN_DBG(FM_DBG | MAIN, "add a new item[len=%d]\n", thiz->len); */ + } else { + WCN_DBG(FM_WAR | MAIN, "%s fifo is full\n", thiz->obj.name); + return -FM_ENOMEM; + } + + return 0; +} + +signed int fm_fifo_out(struct fm_fifo *thiz, void *item) +{ + if (thiz->len > 0) { + if (item) { + fm_memcpy(item, (thiz->obj.priv + (thiz->item_size * thiz->out)), thiz->item_size); + fm_memset((thiz->obj.priv + (thiz->item_size * thiz->out)), 0, thiz->item_size); + } + thiz->out = (thiz->out + 1) % thiz->size; + thiz->len--; + /* WCN_DBG(FM_DBG | MAIN, "del an item[len=%d]\n", thiz->len); */ + } else { + WCN_DBG(FM_WAR | MAIN, "%s fifo is empty\n", thiz->obj.name); + } + + return 0; +} + +bool fm_fifo_is_full(struct fm_fifo *thiz) +{ + return (thiz->len == thiz->size) ? true : false; +} + +bool fm_fifo_is_empty(struct fm_fifo *thiz) +{ + return (thiz->len == 0) ? true : false; +} + +signed int fm_fifo_get_total_len(struct fm_fifo *thiz) +{ + return thiz->size; +} + +signed int fm_fifo_get_valid_len(struct fm_fifo *thiz) +{ + return thiz->len; +} + +signed int fm_fifo_reset(struct fm_fifo *thiz) +{ + fm_memset(thiz->obj.priv, 0, thiz->item_size * thiz->size); + thiz->in = 0; + thiz->out = 0; + thiz->len = 0; + + return 0; +} + +struct fm_fifo *fm_fifo_init(struct fm_fifo *fifo, void *buf, const signed char *name, signed int item_size, + signed int item_num) +{ + fm_memcpy(fifo->obj.name, name, 20); + fifo->size = item_num; + fifo->in = 0; + fifo->out = 0; + fifo->len = 0; + fifo->item_size = item_size; + fifo->obj.priv = buf; + + fifo->input = fm_fifo_in; + fifo->output = fm_fifo_out; + fifo->is_full = fm_fifo_is_full; + fifo->is_empty = fm_fifo_is_empty; + fifo->get_total_len = fm_fifo_get_total_len; + fifo->get_valid_len = fm_fifo_get_valid_len; + fifo->reset = fm_fifo_reset; + + WCN_DBG(FM_NTC | LINK, "%s inited\n", fifo->obj.name); + + return fifo; +} + +struct fm_fifo *fm_fifo_create(const signed char *name, signed int item_size, signed int item_num) +{ + struct fm_fifo *tmp; + void *buf; + + tmp = fm_zalloc(sizeof(struct fm_fifo)); + if (!tmp) { + WCN_DBG(FM_ALT | MAIN, "fm_zalloc(fm_fifo) -ENOMEM\n"); + return NULL; + } + + buf = fm_zalloc(item_size * item_num); + if (!buf) { + WCN_DBG(FM_ALT | MAIN, "fm_zalloc(fm_fifo) -ENOMEM\n"); + fm_free(tmp); + return NULL; + } + + tmp = fm_fifo_init(tmp, buf, name, item_size, item_num); + + WCN_DBG(FM_NTC | LINK, "%s created\n", tmp->obj.name); + + return tmp; +} + +signed int fm_fifo_release(struct fm_fifo *fifo) +{ + if (fifo) { + WCN_DBG(FM_NTC | LINK, "%s released\n", fifo->obj.name); + if (fifo->obj.priv) + fm_free(fifo->obj.priv); + + fm_free(fifo); + } + + return 0; +} + +unsigned short fm_get_u16_from_auc(unsigned char *buf) +{ + return (unsigned short)((unsigned short)buf[0] + ((unsigned short) buf[1] << 8)); +} + +void fm_set_u16_to_auc(unsigned char *buf, unsigned short val) +{ + buf[0] = (unsigned char)(val & 0xFF); + buf[1] = (unsigned char)(val >> 8); +} + +unsigned int fm_get_u32_from_auc(unsigned char *buf) +{ + return ((unsigned int)(*buf) + ((unsigned int)(*(buf + 1)) << 8) + + ((unsigned int)(*(buf + 2)) << 16) + ((unsigned int)(*(buf + 3)) << 24)); +} + +void fm_set_u32_to_auc(unsigned char *buf, unsigned int val) +{ + buf[0] = (unsigned char)val; + buf[1] = (unsigned char)(val >> 8); + buf[2] = (unsigned char)(val >> 16); + buf[3] = (unsigned char)(val >> 24); +} diff --git a/drivers/misc/mediatek/connectivity/fmradio/dummy.c b/drivers/misc/mediatek/connectivity/fmradio/dummy.c new file mode 100644 index 0000000000000000000000000000000000000000..872b38b4a31a0ae5b882cbdbf551fefe901fa179 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/dummy.c @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2015 MediaTek Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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. + */ + +/* dummy.c + * This dummy file is just for meetting the build system's rule. + */ diff --git a/drivers/misc/mediatek/connectivity/fmradio/inc/fm_cmd.h b/drivers/misc/mediatek/connectivity/fmradio/inc/fm_cmd.h new file mode 100644 index 0000000000000000000000000000000000000000..7ec1a88165681947a47638844d9262fa9cc2343b --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/inc/fm_cmd.h @@ -0,0 +1,96 @@ +/* +* Copyright (C) 2016 MediaTek Inc. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. +*/ + +#ifndef __FM_CMD_H__ +#define __FM_CMD_H__ + +#include +#include "fm_typedef.h" +#include "fm_patch.h" +#include "fm_link.h" +#include "fm_reg_utils.h" + +extern unsigned char *cmd_buf; +extern struct fm_lock *cmd_buf_lock; +extern struct fm_res_ctx *fm_res; +extern unsigned char top_index; + +#define PATCH_SEG_LEN 512 +enum IMG_TYPE { + IMG_WRONG = 0, + IMG_ROM, + IMG_PATCH, + IMG_COEFFICIENT, + IMG_HW_COEFFICIENT +}; + +/* FM BOP's size */ +#define FM_TOP_WRITE_BOP_SIZE (7) +#define FM_TOP_RD_UNTIL_BOP_SIZE (11) +#define FM_TOP_MODIFY_BOP_SIZE (11) + +#define FM_WRITE_BASIC_OP_SIZE (3) +#define FM_UDELAY_BASIC_OP_SIZE (4) +#define FM_RD_UNTIL_BASIC_OP_SIZE (5) +#define FM_MODIFY_BASIC_OP_SIZE (5) +#define FM_MSLEEP_BASIC_OP_SIZE (4) + +signed int fm_bop_write(unsigned char addr, unsigned short value, unsigned char *buf, signed int size); +signed int fm_bop_udelay(unsigned int value, unsigned char *buf, signed int size); +signed int fm_bop_rd_until(unsigned char addr, unsigned short mask, unsigned short value, unsigned char *buf, + signed int size); +signed int fm_bop_modify(unsigned char addr, unsigned short mask_and, unsigned short mask_or, unsigned char *buf, + signed int size); +signed int fm_bop_top_write(unsigned short addr, unsigned int value, unsigned char *buf, signed int size); +signed int fm_bop_top_rd_until(unsigned short addr, unsigned int mask, unsigned int value, unsigned char *buf, + signed int size); +signed int fm_op_seq_combine_cmd(unsigned char *buf, unsigned char opcode, signed int pkt_size); +signed int fm_get_reg(unsigned char *buf, signed int buf_size, unsigned char addr); +signed int fm_set_reg(unsigned char *buf, signed int buf_size, unsigned char addr, unsigned short value); +signed int fm_patch_download(unsigned char *buf, signed int buf_size, unsigned char seg_num, unsigned char seg_id, + const unsigned char *src, signed int seg_len); +signed int fm_coeff_download(unsigned char *buf, signed int buf_size, unsigned char seg_num, unsigned char seg_id, + const unsigned char *src, signed int seg_len); +signed int fm_full_cqi_req(unsigned char *buf, signed int buf_size, unsigned short *freq, signed int cnt, + signed int type); +signed int fm_top_get_reg(unsigned char *buf, signed int buf_size, unsigned short addr); +signed int fm_top_set_reg(unsigned char *buf, signed int buf_size, unsigned short addr, unsigned int value); +signed int fm_host_get_reg(unsigned char *buf, signed int buf_size, unsigned int addr); +signed int fm_host_set_reg(unsigned char *buf, signed int buf_size, unsigned int addr, unsigned int value); +signed int fm_set_bits_reg(unsigned char *buf, signed int buf_size, unsigned char addr, unsigned short bits, + unsigned short mask); +signed int fm_pmic_get_reg(unsigned char *buf, signed int buf_size, unsigned char addr); +signed int fm_pmic_set_reg(unsigned char *buf, signed int buf_size, unsigned char addr, unsigned int val); +signed int fm_pmic_mod_reg(unsigned char *buf, signed int buf_size, unsigned char addr, unsigned int mask_and, + unsigned int mask_or); +signed int fm_get_patch_path(signed int ver, unsigned char *buff, int buffsize, struct fm_patch_tbl *patch_tbl); +signed int fm_get_coeff_path(signed int ver, unsigned char *buff, int buffsize, struct fm_patch_tbl *patch_tbl); +signed int fm_download_patch(const unsigned char *img, signed int len, enum IMG_TYPE type); +signed int fm_get_read_result(struct fm_res_ctx *result); +signed int fm_reg_read(unsigned char addr, unsigned short *val); +signed int fm_reg_write(unsigned char addr, unsigned short val); +signed int fm_set_bits(unsigned char addr, unsigned short bits, unsigned short mask); +signed int fm_top_reg_read(unsigned short addr, unsigned int *val); +signed int fm_top_reg_write(unsigned short addr, unsigned int val); +signed int fm_host_reg_read(unsigned int addr, unsigned int *val); +signed int fm_host_reg_write(unsigned int addr, unsigned int val); + +/* + * fm_get_channel_space - get the spcace of gived channel + * @freq - value in 760~1080 or 7600~10800 + * + * Return 0, if 760~1080; return 1, if 7600 ~ 10800, else err code < 0 + */ +extern signed int fm_get_channel_space(int freq); + +#endif diff --git a/drivers/misc/mediatek/connectivity/fmradio/inc/fm_config.h b/drivers/misc/mediatek/connectivity/fmradio/inc/fm_config.h new file mode 100644 index 0000000000000000000000000000000000000000..ebd369db881142fd5544c79a511f06f411513b0d --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/inc/fm_config.h @@ -0,0 +1,186 @@ +/* + * Copyright (C) 2015 MediaTek Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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. + */ + +#ifndef __FM_CONFIG_H__ +#define __FM_CONFIG_H__ + +#include "fm_typedef.h" +#include "fm_rds.h" +#include "fm_dbg.h" +#include "fm_err.h" +#include "fm_stdlib.h" +#include "fm_interface.h" +/* band */ +#define FM_BAND_UNKNOWN 0 +#define FM_BAND_UE 1 /* US/Europe band 87.5MHz ~ 108MHz (DEFAULT) */ +#define FM_BAND_JAPAN 2 /* Japan band 76MHz ~ 90MHz */ +#define FM_BAND_JAPANW 3 /* Japan wideband 76MHZ ~ 108MHz */ +#define FM_BAND_SPECIAL 4 /* special band between 76MHZ and 108MHz */ +#define FM_BAND_DEFAULT FM_BAND_UE +#define FM_RAIDO_BAND FM_BAND_UE +#define FM_FREQ_MIN FM_RX_BAND_FREQ_L +#define FM_FREQ_MAX FM_RX_BAND_FREQ_H + +#define FM_UE_FREQ_MIN 8750 +#define FM_UE_FREQ_MAX 10800 +#define FM_JP_FREQ_MIN 7600 +#define FM_JP_FREQ_MAX 10800 + +#define FM_RX_BAND_FREQ_L 8750 /* FM radio special band low freq(Default 87.5MHz) */ +#define FM_RX_BAND_FREQ_H 10800 /* FM radio special band high freq(Default 108.0MHz) */ +/* TX */ +#define FM_TX_SCAN_HOLE_LOW 9230 /* 92.3MHz~95.4MHz should not show to user */ +#define FM_TX_SCAN_HOLE_HIGH 9540 /* 92.3MHz~95.4MHz should not show to user */ + +/* space */ +#define FM_SPACE_UNKNOWN 0 +#define FM_SPACE_100K 1 +#define FM_SPACE_200K 2 +#define FM_SPACE_50K 5 + +#define FM_INVALID_CHAN_NOISE_REDUCING 0 + +#define FM_TX_SCAN_UP (0) +#define FM_TX_SCAN_DOWN (1) +#define FM_TX_SCAN_MAX 10 +#define FM_TX_SCAN_MIN 1 + +/* seek direction */ +#define FM_SEEK_UP 0 +#define FM_SEEK_DOWN 1 + +/* ***************************************************************************************** */ +/* ***************************FM default config for customer: start************************* */ +/* ***************************************************************************************** */ + +/* RX */ +#define FM_RX_RSSI_TH_LONG -296 /* FM radio long antenna RSSI threshold(-4dBuV) */ +#define FM_RX_RSSI_TH_SHORT -296 /* FM radio short antenna RSSI threshold(-4dBuV) */ +#define FM_RX_DESENSE_RSSI -240 +#define FM_RX_PAMD_TH -12 +#define FM_RX_MR_TH -67 +#define FM_RX_ATDC_TH 3496 +#define FM_RX_PRX_TH 64 +#define FM_RX_SMG_TH 16421 /* FM soft-mute gain threshold */ +#define FM_RX_DEEMPHASIS 0 /* 0-50us, China Mainland; 1-75us China Taiwan */ +#define FM_RX_OSC_FREQ 0 /* 0-26MHz; 1-19MHz; 2-24MHz; 3-38.4MHz; 4-40MHz; 5-52MHz */ +#define FM_AUTO_HILO_OFF 0 +#define FM_AUTO_HILO_ON 1 + +/* seek threshold */ +#define FM_SEEKTH_LEVEL_DEFAULT 4 + +/* TX threshold*/ +/* #define FM_TX_PWR_LEVEL_MAX 120 */ +/* #define FM_TX_SCAN_HOLE_LOW 923 //92.3MHz~95.4MHz should not show to user */ +/* #define FM_TX_SCAN_HOLE_HIGH 954 //92.3MHz~95.4MHz should not show to user */ +#define FM_TX_PAMD_TH -23 +#define FM_TX_MR_TH 60 +#define FM_TX_SMG_TH 8231 + +/* ***************************************************************************************** */ +/* ***************************FM default config for customer: end*************************** */ +/* ***************************************************************************************** */ + +enum fm_cfg_parser_state { + FM_CFG_STAT_NONE = 0, + FM_CFG_STAT_GROUP, + FM_CFG_STAT_KEY, + FM_CFG_STAT_VALUE, + FM_CFG_STAT_COMMENT +}; + +#define COMMENT_CHAR '#' +#define DELIMIT_CHAR '=' + +#define isspace(a) ((a) == 0x20) + +struct fm_rx_cust_cfg { + signed int desene_rssi_th; + signed int pamd_th; + signed int mr_th; + signed int atdc_th; + signed int prx_th; + signed int atdev_th; + signed int short_ana_rssi_th; + signed int long_ana_rssi_th; + signed int cqi_th; + signed int smg_th; + signed int deemphasis; + signed int osc_freq; +}; + +struct fm_tx_cust_cfg { + signed int scan_hole_low; + signed int scan_hole_high; + signed int power_level; + signed int pamd_th; + signed int mr_th; + signed int smg_th; +}; +struct fm_cust_cfg { + struct fm_rx_cust_cfg rx_cfg; + struct fm_tx_cust_cfg tx_cfg; + struct fm_audio_info_t aud_cfg; +}; + +enum fm_cust_cfg_op { + FM_CFG_RX_RSSI_TH_LONG = 0, + FM_CFG_RX_RSSI_TH_SHORT, + FM_CFG_RX_CQI_TH, + FM_CFG_RX_MR_TH, + FM_CFG_RX_SMG_TH, + FM_CFG_RX_DEEMPHASIS, + FM_CFG_RX_OSC_FREQ, + FM_CFG_RX_DESENSE_RSSI_TH, + FM_CFG_RX_PAMD_TH, + FM_CFG_RX_ATDC_TH, + FM_CFG_RX_PRX_TH, + FM_CFG_RX_ATDEV_TH, + + FM_CFG_TX_SCAN_HOLE_LOW, + FM_CFG_TX_SCAN_HOLE_HIGH, + FM_CFG_TX_PWR_LEVEL, + FM_CFG_TX_PAMD_TH, + FM_CFG_TX_DEEMPHASIS, + FM_CFG_TX_SMG_TH, + + FM_CFG_MAX +}; + +enum fm_cfg_chip_type { + FM_COMBO_CHIP = 0, + FM_AD_DIE_CHIP, + FM_SOC_CHIP, + FM_CHIP_TYPE_MAX +}; + +typedef signed int(*CFG_HANDLER) (signed char *grp, signed char *key, signed char *val, struct fm_cust_cfg *cfg); +extern signed int to_upper_n(signed char *str, signed int len); +extern signed int check_hex_str(signed char *str, signed int len); +extern signed int check_dec_str(signed char *str, signed int len); +extern signed int ascii_to_hex(signed char *in_ascii, unsigned short *out_hex); +extern signed int ascii_to_dec(signed char *in_ascii, signed int *out_dec); +extern signed int trim_string(signed char **start); +extern signed int trim_path(signed char **start); +extern signed int cfg_parser(signed char *buffer, CFG_HANDLER handler, struct fm_cust_cfg *cfg); +extern signed int cfg_item_match(signed char *src_key, signed char *src_val, signed char *dst_key, signed int *dst_val); + +extern signed int fm_cust_config_setup(const signed char *filename); +extern unsigned short fm_cust_config_fetch(enum fm_cust_cfg_op op_code); +extern unsigned short fm_cust_config_chip(unsigned short chipid, enum fm_cfg_chip_type type); + +extern struct fm_cust_cfg fm_config; +extern unsigned short g_fm_chipid; +extern enum fm_cfg_chip_type g_fm_chip_type; +#endif /* __FM_CONFIG_H__ */ diff --git a/drivers/misc/mediatek/connectivity/fmradio/inc/fm_dbg.h b/drivers/misc/mediatek/connectivity/fmradio/inc/fm_dbg.h new file mode 100644 index 0000000000000000000000000000000000000000..d8da8421dbef145ade8be0933cdaa8f4fd7d6b0d --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/inc/fm_dbg.h @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2015 MediaTek Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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. + */ + +#ifndef __FM_DBG_H__ +#define __FM_DBG_H__ + +/* #include //for printk() */ +#include +#include + +/* DBG zone */ +#define BASE 4 +#define MAIN (1 << (BASE+0)) +#define LINK (1 << (BASE+1)) +#define EINT (1 << (BASE+2)) +#define CHIP (1 << (BASE+3)) +#define RDSC (1 << (BASE+4)) +#define G0 (1 << (BASE+5)) +#define G1 (1 << (BASE+6)) +#define G2 (1 << (BASE+7)) +#define G3 (1 << (BASE+8)) +#define G4 (1 << (BASE+9)) +#define G14 (1 << (BASE+10)) +#define RAW (1 << (BASE+11)) +#define OPEN (1 << (BASE+12)) +#define IOCTL (1 << (BASE+13)) +#define READ_ (1 << (BASE+14)) +#define CLOSE (1 << (BASE+15)) +#define CQI (1 << (BASE+16)) +#define ALL 0xfffffff0 + +/* DBG level */ +#define L0 0x00000000 /* EMERG, system will crush */ +#define L1 0x00000001 /* ALERT, need action in time */ +#define L2 0x00000002 /* CRIT, important HW or SW operation failed */ +#define L3 0x00000003 /* ERR, normal HW or SW ERR */ +#define L4 0x00000004 /* WARNING, importan path or somewhere may occurs err */ +#define L5 0x00000005 /* NOTICE, normal case */ +#define L6 0x00000006 /* INFO, print info if need */ +#define L7 0x00000007 /* DEBUG, for debug info */ + +#define FM_EMG L0 +#define FM_ALT L1 +#define FM_CRT L2 +#define FM_ERR L3 +#define FM_WAR L4 +#define FM_NTC L5 +#define FM_INF L6 +#define FM_DBG L7 +#define FM_DEF(x) ((x)&0x0000000f) + +extern unsigned int g_dbg_level; + +#define WCN_DBG(flag, fmt, args...) \ + do { \ + if ((FM_DEF(flag) <= (g_dbg_level&0x0000000f)) && ((flag)&ALL) & g_dbg_level) { \ + pr_info("[" #flag "] %s: " fmt, __func__, ## args); \ + } \ + } while (0) + +#define WCN_DBG_LIMITED(flag, fmt, args...) \ + do { \ + if ((FM_DEF(flag) <= (g_dbg_level&0x0000000f)) && ((flag)&ALL) & g_dbg_level) { \ + pr_info_ratelimited("[" #flag "]" fmt, ## args); \ + } \ + } while (0) + +#define FM_LOG_DBG(flag, fmt, args...) \ + do { \ + if ((FM_DBG <= (g_dbg_level&0x0000000f)) && ((flag)&0xfffffff0) & g_dbg_level) { \ + pr_info("[" #flag "]" fmt, ## args); \ + } \ + } while (0) + +#define FM_LOG_INF(flag, fmt, args...) \ + do { \ + if ((FM_INF <= (g_dbg_level&0x0000000f)) && ((flag)&0xfffffff0) & g_dbg_level) { \ + pr_info("[" #flag "]" fmt, ## args); \ + } \ + } while (0) + +#define FM_LOG_NTC(flag, fmt, args...) \ + do { \ + if ((FM_NTC <= (g_dbg_level&0x0000000f)) && ((flag)&0xfffffff0) & g_dbg_level) { \ + pr_info("[" #flag "]" fmt, ## args); \ + } \ + } while (0) + +#define FM_LOG_WAR(flag, fmt, args...) \ + do { \ + if ((FM_WAR <= (g_dbg_level&0x0000000f)) && ((flag)&0xfffffff0) & g_dbg_level) { \ + pr_notice("[" #flag "]" fmt, ## args); \ + } \ + } while (0) + +#define FM_LOG_ERR(flag, fmt, args...) \ + do { \ + if ((FM_ERR <= (g_dbg_level&0x0000000f)) && ((flag)&0xfffffff0) & g_dbg_level) { \ + pr_notice("[" #flag "]" fmt, ## args); \ + } \ + } while (0) + +#define FM_LOG_CRT(flag, fmt, args...) \ + do { \ + if ((FM_CRT <= (g_dbg_level&0x0000000f)) && ((flag)&0xfffffff0) & g_dbg_level) { \ + pr_notice("[" #flag "]" fmt, ## args); \ + } \ + } while (0) + +#define FM_LOG_ALT(flag, fmt, args...) \ + do { \ + if ((FM_ALT <= (g_dbg_level&0x0000000f)) && ((flag)&0xfffffff0) & g_dbg_level) { \ + pr_notice("[" #flag "]" fmt, ## args); \ + } \ + } while (0) + +#define FM_LOG_EMG(flag, fmt, args...) \ + do { \ + if ((FM_EMG <= (g_dbg_level&0x0000000f)) && ((flag)&0xfffffff0) & g_dbg_level) { \ + pr_notice("[" #flag "]" fmt, ## args); \ + } \ + } while (0) + +#endif /* __FM_DBG_H__ */ diff --git a/drivers/misc/mediatek/connectivity/fmradio/inc/fm_eint.h b/drivers/misc/mediatek/connectivity/fmradio/inc/fm_eint.h new file mode 100644 index 0000000000000000000000000000000000000000..8b912e23792108abb9b5543ecfc542420cf0ff42 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/inc/fm_eint.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2015 MediaTek Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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. + */ + +#ifndef __FM_EINT_H__ +#define __FM_EINT_H__ + +#include "fm_typedef.h" + +enum { + FM_EINT_PIN_EINT_MODE, + FM_EINT_PIN_GPIO_MODE, + FM_EINT_PIN_MAX_MODE +}; + +extern signed int fm_enable_eint(void); +extern signed int fm_disable_eint(void); +extern signed int fm_request_eint(void (*parser) (void)); +extern signed int fm_eint_pin_cfg(signed int mode); + +#endif /* __FM_EINT_H__ */ diff --git a/drivers/misc/mediatek/connectivity/fmradio/inc/fm_err.h b/drivers/misc/mediatek/connectivity/fmradio/inc/fm_err.h new file mode 100644 index 0000000000000000000000000000000000000000..b118021420e0c66a9a4b5be6190beb0fd545517d --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/inc/fm_err.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2015 MediaTek Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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. + */ + +#ifndef __FM_ERR_H__ +#define __FM_ERR_H__ + +#include /* for printk() */ + +#define FM_ERR_BASE 1000 +enum fm_drv_err_t { + FM_EOK = FM_ERR_BASE, + FM_EBUF, + FM_EPARA, + FM_ELINK, + FM_ELOCK, + FM_EFW, + FM_ECRC, + FM_EWRST, /* wholechip reset */ + FM_ESRST, /* subsystem reset */ + FM_EPATCH, + FM_ENOMEM, + FM_EINUSE, /* other client is using this object */ + FM_EMAX +}; + +#endif /* __FM_ERR_H__ */ diff --git a/drivers/misc/mediatek/connectivity/fmradio/inc/fm_ext_api.h b/drivers/misc/mediatek/connectivity/fmradio/inc/fm_ext_api.h new file mode 100644 index 0000000000000000000000000000000000000000..0f526a12194ee766e22d9e6f0c04f92f821fd1bc --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/inc/fm_ext_api.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +#ifndef FM_EXT_API_H +#define FM_EXT_API_H + +#include + +#include "fm_interface.h" + +enum fm_spi_speed { + FM_SPI_SPEED_26M, + FM_SPI_SPEED_64M, + FM_SPI_SPEED_MAX +}; + +struct fm_ext_interface { + void (*eint_handler)(void); + void (*eint_cb)(void); + void (*enable_eint)(void); + void (*disable_eint)(void); + int (*stp_send_data)(unsigned char *buf, unsigned int len); + int (*stp_recv_data)(unsigned char *buf, unsigned int len); + int (*stp_register_event_cb)(void *cb); + int (*wmt_msgcb_reg)(void *data); + int (*wmt_func_on)(void); + int (*wmt_func_off)(void); + unsigned int (*wmt_ic_info_get)(void); + int (*wmt_chipid_query)(void); + int (*get_hw_version)(void); + unsigned char (*get_top_index)(void); + unsigned int (*get_get_adie)(void); + int (*spi_clock_switch)(enum fm_spi_speed speed); + bool (*is_bus_hang)(void); + int (*spi_hopping)(void); + signed int (*low_ops_register)(struct fm_callback *cb, struct fm_basic_interface *bi); + signed int (*low_ops_unregister)(struct fm_basic_interface *bi); + signed int (*rds_ops_register)(struct fm_basic_interface *bi, struct fm_rds_interface *ri); + signed int (*rds_ops_unregister)(struct fm_rds_interface *ri); + + struct platform_driver *drv; + unsigned int irq_id; +}; + +#endif /* FM_EXT_API_H */ diff --git a/drivers/misc/mediatek/connectivity/fmradio/inc/fm_interface.h b/drivers/misc/mediatek/connectivity/fmradio/inc/fm_interface.h new file mode 100644 index 0000000000000000000000000000000000000000..26575c6fb8f4abe2a2748608267c2c7152259a70 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/inc/fm_interface.h @@ -0,0 +1,287 @@ +/* + * Copyright (C) 2015 MediaTek Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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. + */ + +#ifndef __FM_INTERFACE_H__ +#define __FM_INTERFACE_H__ + +#include +#include +#include + +#include "fm_typedef.h" +#include "fm_rds.h" +#include "fm_utils.h" + +/****************************************************************************** + * STRUCTURE DEFINITIONS + *****************************************************************************/ +enum fm_op_state { + FM_STA_STOP = 0, + FM_STA_PLAY = 1, + FM_STA_TUNE = 2, + FM_STA_SEEK = 3, + FM_STA_SCAN = 4, + FM_STA_RAMPDOWN = 5, + FM_STA_UNKNOWN = 100, + FM_STA_MAX +}; + +enum fm_pwr_state { + FM_PWR_OFF = 0, + FM_PWR_RX_ON = 1, + FM_PWR_TX_ON = 2, + FM_PWR_MAX +}; + +enum fm_antenna_type { + FM_ANA_LONG = 0, /* long antenna */ + FM_ANA_SHORT = 1, /* short antenna */ + FM_ANA_MAX +}; + +enum fm_gps_desense_t { + FM_GPS_DESE_ENABLE, + FM_GPS_DESE_DISABLE +}; + +struct fm_hw_info { + signed int chip_id; /* chip ID, eg. 6620 */ + signed int eco_ver; /* chip ECO version, eg. E3 */ + signed int rom_ver; /* FM DSP rom code version, eg. V2 */ + signed int patch_ver; /* FM DSP patch version, eg. 1.11 */ + signed int reserve; +}; + +struct fm_i2s_setting { + signed int onoff; + signed int mode; + signed int sample; +}; + +enum fm_i2s_state_e { + FM_I2S_ON = 0, + FM_I2S_OFF, + FM_I2S_STATE_ERR +}; + +enum fm_i2s_mode_e { + FM_I2S_MASTER = 0, + FM_I2S_SLAVE, + FM_I2S_MODE_ERR +}; + +enum fm_i2s_sample_e { + FM_I2S_32K = 0, + FM_I2S_44K, + FM_I2S_48K, + FM_I2S_SR_ERR +}; + +struct fm_i2s_info { + signed int status; /*0:FM_I2S_ON, 1:FM_I2S_OFF,2:error */ + signed int mode; /*0:FM_I2S_MASTER, 1:FM_I2S_SLAVE,2:error */ + signed int rate; /*0:FM_I2S_32K:32000,1:FM_I2S_44K:44100,2:FM_I2S_48K:48000,3:error */ +}; + +enum fm_audio_path_e { + FM_AUD_ANALOG = 0, + FM_AUD_I2S = 1, + FM_AUD_MRGIF = 2, + FM_AUD_ERR +}; + +enum fm_i2s_pad_sel_e { + FM_I2S_PAD_CONN = 0, /* sco fm chip: e.g.6627 */ + FM_I2S_PAD_IO = 1, /* combo fm chip: e.g.6628 */ + FM_I2S_PAD_ERR +}; + +struct fm_audio_info_t { + enum fm_audio_path_e aud_path; + struct fm_i2s_info i2s_info; + enum fm_i2s_pad_sel_e i2s_pad; +}; + +struct fm_platform { + struct cdev cdev; + dev_t dev_t; + struct class *cls; + struct device *dev; +}; + +struct fm { + /* chip info */ + signed int projectid; + unsigned short chip_id; /* chip id, such as 6616/6620/6626/6628 */ + unsigned short device_id; /* chip version */ + /* basic run time info */ + signed int ref; /* fm driver can be multi opened */ + bool chipon; /* Chip power state */ + enum fm_pwr_state pwr_sta; /* FM module power state */ + enum fm_op_state op_sta; /* current operation state: tune, seek, scan ... */ + /* enum fm_audio_path aud_path; //I2S or Analog */ + signed int vol; /* current audio volume from chip side */ + bool mute; /* true: mute, false: playing */ + bool rds_on; /* true: on, false: off */ + enum fm_antenna_type ana_type; /* long/short antenna */ + bool via_bt; /* true: fm over bt controller; false: fm over host */ + unsigned short min_freq; /* for UE, 875KHz */ + unsigned short max_freq; /* for UE, 1080KHz */ + unsigned short cur_freq; /* current frequency */ + unsigned char band; /* UE/JAPAN/JPANWD */ + /*FM Tx */ + unsigned int vcoon; /* TX VCO tracking ON duiration(ms) */ + unsigned int vcooff; /* TX RTC VCO tracking interval(s) */ + unsigned int txpwrctl; /* TX power contrl interval(s) */ + unsigned int tx_pwr; + bool rdstx_on; /* false:rds tx off, true:rds tx on */ + bool wholechiprst; + /* RDS data */ + struct fm_flag_event *rds_event; /* pointer to rds event */ + struct rds_t *pstRDSData; /* rds spec data buffer */ + /* platform data */ + struct fm_platform platform; /* platform related members */ + + struct fm_workthread *eint_wkthd; + struct fm_workthread *timer_wkthd; + struct fm_work *eint_wk; + struct fm_work *rds_wk; + struct fm_work *rst_wk; /* work for subsystem reset */ + struct fm_work *pwroff_wk; + struct fm_work *ch_valid_check_wk; + /* Tx */ + struct fm_work *fm_tx_desense_wifi_work; + struct fm_work *fm_tx_power_ctrl_work; + +}; + +struct fm_callback { + /* call backs */ + unsigned short (*cur_freq_get)(void); + signed int (*cur_freq_set)(unsigned short new_freq); + signed int (*projectid_get)(void); +/* unsigned short(*chan_para_get)(unsigned short freq); //get channel parameter, HL side/ FA / ATJ */ +}; + +struct fm_basic_interface { + /* mt66x6 lib interfaces */ + signed int (*low_pwr_wa)(signed int onoff); + signed int (*pwron)(signed int data); + signed int (*pwroff)(signed int data); + signed int (*pmic_read)(unsigned char addr, unsigned int *val); + signed int (*pmic_write)(unsigned char addr, unsigned int val); + unsigned short (*chipid_get)(void); + signed int (*mute)(bool mute); + signed int (*rampdown)(void); + signed int (*pwrupseq)(unsigned short *chip_id, unsigned short *device_id); + signed int (*pwrdownseq)(void); + bool (*setfreq)(unsigned short freq); + bool (*seek)(unsigned short min_freq, unsigned short max_freq, unsigned short *freq, unsigned short dir, + unsigned short space); + signed int (*seekstop)(void); + bool (*scan)(unsigned short min_freq, unsigned short max_freq, unsigned short *freq, unsigned short *tbl, + unsigned short *tblsize, unsigned short dir, unsigned short space); + bool (*jammer_scan)(unsigned short min_freq, unsigned short max_freq, unsigned short *freq, unsigned short *tbl, + unsigned short *tblsize, unsigned short dir, unsigned short space); + signed int (*cqi_get)(signed char *buf, signed int buf_len); + signed int (*scanstop)(void); + signed int (*rssiget)(signed int *rssi); + signed int (*volset)(unsigned char vol); + signed int (*volget)(unsigned char *vol); + signed int (*dumpreg)(void); + bool (*msget)(unsigned short *ms); /* mono/stereo indicator get */ + signed int (*msset)(signed int ms); /* mono/stereo force set */ + bool (*pamdget)(unsigned short *pamd); + bool (*em)(unsigned short group, unsigned short item, unsigned int val); + signed int (*anaswitch)(signed int ana); + signed int (*anaget)(void); + signed int (*caparray_get)(signed int *ca); + signed int (*i2s_set)(signed int onoff, signed int mode, signed int sample); + signed int (*i2s_get)(signed int *ponoff, signed int *pmode, signed int *psample); + signed int (*hwinfo_get)(struct fm_hw_info *req); + /* check if this is a de-sense channel */ + signed int (*is_dese_chan)(unsigned short freq); + signed int (*softmute_tune)(unsigned short freq, signed int *rssi, signed int *valid); + signed int (*pre_search)(void); + signed int (*restore_search)(void); + /* check if this is a valid channel */ + signed int (*desense_check)(unsigned short freq, signed int rssi); + signed int (*get_freq_cqi)(unsigned short freq, signed int *cqi); + /* cqi log tool */ + signed int (*cqi_log)(signed int min_freq, signed int max_freq, signed int space, signed int cnt); + signed int (*fm_via_bt)(bool flag); /* fm over BT:1:enable,0:disable */ + signed int (*set_search_th)(signed int idx, signed int val, signed int reserve); + signed int (*get_aud_info)(struct fm_audio_info_t *data); + /*tx function */ + signed int (*tx_support)(signed int *sup); + signed int (*rdstx_enable)(signed int *flag); + bool (*tune_tx)(unsigned short freq); + signed int (*pwrupseq_tx)(void); + signed int (*pwrdownseq_tx)(void); + signed int (*tx_pwr_ctrl)(unsigned short freq, signed int *ctr); + signed int (*rtc_drift_ctrl)(unsigned short freq, signed int *ctr); + signed int (*tx_desense_wifi)(unsigned short freq, signed int *ctr); + signed int (*tx_scan)(unsigned short min_freq, unsigned short max_freq, unsigned short *pFreq, + unsigned short *pScanTBL, unsigned short *ScanTBLsize, + unsigned short scandir, unsigned short space); + signed int (*rds_tx_adapter)(unsigned short pi, unsigned short *ps, unsigned short *other_rds, + unsigned char other_rds_cnt); + bool (*is_valid_freq)(unsigned short freq); + +}; + +struct fm_rds_interface { + /* rds lib interfaces */ + signed int (*rds_blercheck)(struct rds_t *dst); + bool (*rds_onoff)(struct rds_t *dst, bool onoff); + signed int (*rds_parser)(struct rds_t *rds_dst, struct rds_rx_t *rds_raw, + signed int rds_size, unsigned short(*getfreq) (void)); + unsigned short (*rds_gbc_get)(void); /* good block counter */ + unsigned short (*rds_bbc_get)(void); /* bad block counter */ + unsigned char (*rds_bbr_get)(void); /* bad block ratio */ + signed int (*rds_bc_reset)(void); /* reset block counter */ + unsigned int (*rds_bci_get)(void); /* bler check interval */ + signed int (*rds_log_get)(struct rds_rx_t *dst, signed int *dst_len); + signed int (*rds_gc_get)(struct rds_group_cnt_t *dst, struct rds_t *rdsp); + signed int (*rds_gc_reset)(struct rds_t *rdsp); + /*Tx */ + signed int (*rds_tx)(unsigned short pi, unsigned short *ps, unsigned short *other_rds, + unsigned char other_rds_cnt); + signed int (*rds_tx_enable)(void); + signed int (*rds_tx_disable)(void); + signed int (*rdstx_support)(signed int *sup); +}; + +struct fm_lowlevel_ops { + struct fm_callback cb; + struct fm_basic_interface bi; + struct fm_rds_interface ri; +}; + +extern signed int fm_low_ops_register(struct fm_callback *cb, struct fm_basic_interface *bi); +extern signed int fm_low_ops_unregister(struct fm_basic_interface *bi); +extern signed int fm_rds_ops_register(struct fm_basic_interface *bi, struct fm_rds_interface *ri); +extern signed int fm_rds_ops_unregister(struct fm_rds_interface *ri); +extern signed int fm_wcn_ops_register(void); +extern signed int fm_wcn_ops_unregister(void); +extern int fm_register_irq(struct platform_driver *drv); + +/* + * fm_get_channel_space - get the spcace of gived channel + * @freq - value in 760~1080 or 7600~10800 + * + * Return 0, if 760~1080; return 1, if 7600 ~ 10800, else err code < 0 + */ + +extern signed int fm_get_channel_space(int freq); +#endif /* __FM_INTERFACE_H__ */ diff --git a/drivers/misc/mediatek/connectivity/fmradio/inc/fm_ioctl.h b/drivers/misc/mediatek/connectivity/fmradio/inc/fm_ioctl.h new file mode 100644 index 0000000000000000000000000000000000000000..ba120c637e6750b90871f23ed25a345d2d81aee5 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/inc/fm_ioctl.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2015 MediaTek Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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. + */ + +#ifndef __FM_IOCTL_H__ +#define __FM_IOCTL_H__ +#include "fm_typedef.h" +#include "fm_rds.h" +#include "fm_main.h" + +#define FM_IOC_MAGIC 0xf5 /* FIXME: any conflict? */ +#define FM_IOCTL_POWERUP _IOWR(FM_IOC_MAGIC, 0, struct fm_tune_parm*) +#define FM_IOCTL_POWERDOWN _IOWR(FM_IOC_MAGIC, 1, int32_t*) +#define FM_IOCTL_TUNE _IOWR(FM_IOC_MAGIC, 2, struct fm_tune_parm*) +#define FM_IOCTL_SEEK _IOWR(FM_IOC_MAGIC, 3, struct fm_seek_parm*) +#define FM_IOCTL_SETVOL _IOWR(FM_IOC_MAGIC, 4, uint32_t*) +#define FM_IOCTL_GETVOL _IOWR(FM_IOC_MAGIC, 5, uint32_t*) +#define FM_IOCTL_MUTE _IOWR(FM_IOC_MAGIC, 6, uint32_t*) +#define FM_IOCTL_GETRSSI _IOWR(FM_IOC_MAGIC, 7, int32_t*) +#define FM_IOCTL_SCAN _IOWR(FM_IOC_MAGIC, 8, struct fm_scan_parm*) +#define FM_IOCTL_STOP_SCAN _IO(FM_IOC_MAGIC, 9) + +/* IOCTL and struct for test */ +#define FM_IOCTL_GETCHIPID _IOWR(FM_IOC_MAGIC, 10, uint16_t*) +#define FM_IOCTL_EM_TEST _IOWR(FM_IOC_MAGIC, 11, struct fm_em_parm*) +#define FM_IOCTL_RW_REG _IOWR(FM_IOC_MAGIC, 12, struct fm_ctl_parm*) +#define FM_IOCTL_GETMONOSTERO _IOWR(FM_IOC_MAGIC, 13, uint16_t*) +#define FM_IOCTL_GETCURPAMD _IOWR(FM_IOC_MAGIC, 14, uint16_t*) +#define FM_IOCTL_GETGOODBCNT _IOWR(FM_IOC_MAGIC, 15, uint16_t*) +#define FM_IOCTL_GETBADBNT _IOWR(FM_IOC_MAGIC, 16, uint16_t*) +#define FM_IOCTL_GETBLERRATIO _IOWR(FM_IOC_MAGIC, 17, uint16_t*) + +/* IOCTL for RDS */ +#define FM_IOCTL_RDS_ONOFF _IOWR(FM_IOC_MAGIC, 18, uint16_t*) +#define FM_IOCTL_RDS_SUPPORT _IOWR(FM_IOC_MAGIC, 19, int32_t*) + +#define FM_IOCTL_POWERUP_TX _IOWR(FM_IOC_MAGIC, 20, struct fm_tune_parm*) +#define FM_IOCTL_TUNE_TX _IOWR(FM_IOC_MAGIC, 21, struct fm_tune_parm*) +#define FM_IOCTL_RDS_TX _IOWR(FM_IOC_MAGIC, 22, struct fm_rds_tx_parm*) + +#define FM_IOCTL_RDS_SIM_DATA _IOWR(FM_IOC_MAGIC, 23, uint32_t*) +#define FM_IOCTL_IS_FM_POWERED_UP _IOWR(FM_IOC_MAGIC, 24, uint32_t*) + +/* IOCTL for FM Tx */ +#define FM_IOCTL_TX_SUPPORT _IOWR(FM_IOC_MAGIC, 25, int32_t*) +#define FM_IOCTL_RDSTX_SUPPORT _IOWR(FM_IOC_MAGIC, 26, int32_t*) +#define FM_IOCTL_RDSTX_ENABLE _IOWR(FM_IOC_MAGIC, 27, int32_t*) +#define FM_IOCTL_TX_SCAN _IOWR(FM_IOC_MAGIC, 28, struct fm_tx_scan_parm*) + +/* IOCTL for FM over BT */ +#define FM_IOCTL_OVER_BT_ENABLE _IOWR(FM_IOC_MAGIC, 29, int32_t*) + +/* IOCTL for FM ANTENNA SWITCH */ +#define FM_IOCTL_ANA_SWITCH _IOWR(FM_IOC_MAGIC, 30, int32_t*) +#define FM_IOCTL_GETCAPARRAY _IOWR(FM_IOC_MAGIC, 31, int32_t*) + +/* IOCTL for FM compensation by GPS RTC */ +#define FM_IOCTL_GPS_RTC_DRIFT _IOWR(FM_IOC_MAGIC, 32, struct fm_gps_rtc_info*) + +/* IOCTL for FM I2S Setting */ +#define FM_IOCTL_I2S_SETTING _IOWR(FM_IOC_MAGIC, 33, struct fm_i2s_setting*) + +#define FM_IOCTL_RDS_GROUPCNT _IOWR(FM_IOC_MAGIC, 34, struct rds_group_cnt_req_t*) +#define FM_IOCTL_RDS_GET_LOG _IOWR(FM_IOC_MAGIC, 35, struct rds_raw_t*) + +#define FM_IOCTL_SCAN_GETRSSI _IOWR(FM_IOC_MAGIC, 36, struct fm_rssi_req*) +#define FM_IOCTL_SETMONOSTERO _IOWR(FM_IOC_MAGIC, 37, int32_t) + +#define FM_IOCTL_RDS_BC_RST _IOWR(FM_IOC_MAGIC, 38, int32_t*) +#define FM_IOCTL_CQI_GET _IOWR(FM_IOC_MAGIC, 39, struct fm_cqi_req*) +#define FM_IOCTL_GET_HW_INFO _IOWR(FM_IOC_MAGIC, 40, struct fm_hw_info*) +#define FM_IOCTL_GET_I2S_INFO _IOWR(FM_IOC_MAGIC, 41, struct fm_i2s_info*) +#define FM_IOCTL_IS_DESE_CHAN _IOWR(FM_IOC_MAGIC, 42, int32_t*) + +#define FM_IOCTL_TOP_RDWR _IOWR(FM_IOC_MAGIC, 43, struct fm_top_rw_parm*) +#define FM_IOCTL_HOST_RDWR _IOWR(FM_IOC_MAGIC, 44, struct fm_host_rw_parm*) + +#define FM_IOCTL_PRE_SEARCH _IOWR(FM_IOC_MAGIC, 45, int32_t) +#define FM_IOCTL_RESTORE_SEARCH _IOWR(FM_IOC_MAGIC, 46, int32_t) + +#define FM_IOCTL_SET_SEARCH_THRESHOLD _IOWR(FM_IOC_MAGIC, 47, struct fm_search_threshold_t*) + +#define FM_IOCTL_GET_AUDIO_INFO _IOWR(FM_IOC_MAGIC, 48, struct fm_audio_info_t*) +#define FM_IOCTL_FM_SET_STATUS _IOWR(FM_IOC_MAGIC, 49, struct fm_status_t) +#define FM_IOCTL_FM_GET_STATUS _IOWR(FM_IOC_MAGIC, 50, struct fm_status_t) + +#define FM_IOCTL_SCAN_NEW _IOWR(FM_IOC_MAGIC, 60, struct fm_scan_t*) +#define FM_IOCTL_SEEK_NEW _IOWR(FM_IOC_MAGIC, 61, struct fm_seek_t*) +#define FM_IOCTL_TUNE_NEW _IOWR(FM_IOC_MAGIC, 62, struct fm_tune_t*) +#define FM_IOCTL_SOFT_MUTE_TUNE _IOWR(FM_IOC_MAGIC, 63, struct fm_softmute_tune_t*) /*for soft mute tune */ +#define FM_IOCTL_DESENSE_CHECK _IOWR(FM_IOC_MAGIC, 64, struct fm_desense_check_t*) + +#define COMPAT_FM_IOCTL_GET_AUDIO_INFO _IOWR(FM_IOC_MAGIC, 48, struct fm_audio_info_t*) + +#define FM_IOCTL_PMIC_RDWR _IOWR(FM_IOC_MAGIC, 65, struct fm_pmic_rw_parm*) + +#define FM_IOCTL_DUMP_REG _IO(FM_IOC_MAGIC, 0xFF) +#endif /* __FM_IOCTL_H__ */ diff --git a/drivers/misc/mediatek/connectivity/fmradio/inc/fm_link.h b/drivers/misc/mediatek/connectivity/fmradio/inc/fm_link.h new file mode 100644 index 0000000000000000000000000000000000000000..75e6b2fee022bc8a17fc3fabba46154d107e01d7 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/inc/fm_link.h @@ -0,0 +1,247 @@ +/* + * Copyright (C) 2015 MediaTek Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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. + */ + +#ifndef __FM_LINK_H__ +#define __FM_LINK_H__ + +#include "fm_typedef.h" +#include "fm_rds.h" +#include "fm_utils.h" + +enum fm_task_parser_state { + FM_TASK_RX_PARSER_PKT_TYPE = 0, + FM_TASK_RX_PARSER_OPCODE, + FM_TASK_RX_PARSER_PKT_LEN_1, + FM_TASK_RX_PARSER_PKT_LEN_2, + FM_TASK_RX_PARSER_PKT_PAYLOAD, + FM_TASK_RX_PARSER_BUFFER_CONGESTION +}; + +enum { + FM_TASK_COMMAND_PKT_TYPE = 0x01, + FM_TASK_EVENT_PKT_TYPE = 0x04 +}; + +/* FM opcode */ +enum { + FM_STP_TEST_OPCODE = 0x00, + FSPI_ENABLE_OPCODE = 0x01, + FSPI_MUX_SEL_OPCODE = 0x02, + FSPI_READ_OPCODE = 0x03, + FSPI_WRITE_OPCODE = 0x04, + FI2C_READ_OPCODE = 0x05, + FI2C_WRITE_OPCODE = 0x06, + FM_ENABLE_OPCODE = 0x07, + FM_RESET_OPCODE = 0x08, + FM_TUNE_OPCODE = 0x09, + FM_SEEK_OPCODE = 0x0a, + FM_SCAN_OPCODE = 0x0b, + RDS_RX_ENABLE_OPCODE = 0x0c, + RDS_RX_DATA_OPCODE = 0x0d, + FM_RAMPDOWN_OPCODE = 0x0e, + FM_MCUCLK_SEL_OPCODE = 0x0f, + FM_MODEMCLK_SEL_OPCODE = 0x10, + RDS_TX_OPCODE = 0x11, + FM_PATCH_DOWNLOAD_OPCODE = 0x12, + FM_COEFF_DOWNLOAD_OPCODE = 0x13, + FM_HWCOEFF_DOWNLOAD_OPCODE = 0x14, + FM_ROM_DOWNLOAD_OPCODE = 0x15, + FM_SOFT_MUTE_TUNE_OPCODE = 0x17, + FM_HOST_READ_OPCODE = 0x18, /* mcu register read */ + FM_HOST_WRITE_OPCODE = 0x19, + CSPI_WRITE_OPCODE = 0x20, + CSPI_READ_OPCODE = 0x21, /* common SPI read */ + FM_HOST_MODIFY_OPCODE = 0x22, + FM_READ_PMIC_CR_OPCODE = 0x23, + FM_WRITE_PMIC_CR_OPCODE = 0x24, + FM_MODIFY_PMIC_CR_OPCODE = 0x25, + FM_OPCODE_MAX +}; + +enum { + FLAG_TEST = (1 << FM_STP_TEST_OPCODE), + FLAG_FSPI_EN = (1 << FSPI_ENABLE_OPCODE), + FLAG_FSPI_MUXSEL = (1 << FSPI_MUX_SEL_OPCODE), + FLAG_FSPI_RD = (1 << FSPI_READ_OPCODE), + FLAG_FSPI_WR = (1 << FSPI_WRITE_OPCODE), + FLAG_I2C_RD = (1 << FI2C_READ_OPCODE), + FLAG_I2C_WR = (1 << FI2C_WRITE_OPCODE), + FLAG_EN = (1 << FM_ENABLE_OPCODE), + FLAG_PMIC_READ = (1 << 8), + FLAG_TUNE = (1 << FM_TUNE_OPCODE), + FLAG_SEEK = (1 << FM_SEEK_OPCODE), + FLAG_SCAN = (1 << FM_SCAN_OPCODE), + FLAG_RDS_RX_EN = (1 << RDS_RX_ENABLE_OPCODE), + FLAG_RDS_DATA = (1 << RDS_RX_DATA_OPCODE), + FLAG_RAMPDOWN = (1 << FM_RAMPDOWN_OPCODE), + FLAG_PMIC_MODIFY = (1 << 15), + FLAG_MODEMCLK = (1 << FM_MODEMCLK_SEL_OPCODE), + FLAG_RDS_TX = (1 << RDS_TX_OPCODE), + FLAG_PATCH = (1 << FM_PATCH_DOWNLOAD_OPCODE), + FLAG_COEFF = (1 << FM_COEFF_DOWNLOAD_OPCODE), + FLAG_HWCOEFF = (1 << FM_HWCOEFF_DOWNLOAD_OPCODE), + FLAG_ROM = (1 << FM_ROM_DOWNLOAD_OPCODE), + FLAG_CSPI_READ = (1 << 22), /* 22 */ + FLAG_SM_TUNE = (1 << FM_SOFT_MUTE_TUNE_OPCODE), /* 23 */ + FLAG_HOST_READ = (1 << FM_HOST_READ_OPCODE), /* 24 */ + FLAG_HOST_WRITE = (1 << FM_HOST_WRITE_OPCODE), /* 25 */ + FLAG_CSPI_WRITE = (1 << 26), /* 26 */ + FLAG_CQI_DONE = (1 << 27), + FLAG_TUNE_DONE = (1 << 28), + FLAG_SEEK_DONE = (1 << 29), + FLAG_SCAN_DONE = (1 << 30), + FLAG_TERMINATE = (1 << 31) +}; + +#define FM_SCANTBL_SIZE 16 +#define FM_CQI_BUF_SIZE 96 +struct fm_res_ctx { + unsigned short fspi_rd; + unsigned short seek_result; + unsigned short scan_result[FM_SCANTBL_SIZE]; + signed char cqi[FM_CQI_BUF_SIZE]; + struct rds_rx_t rds_rx_result; + unsigned int cspi_rd; /* common spi read data */ + unsigned char pmic_result[8]; +}; + +#define FM_TRACE_ENABLE + +#define FM_TRACE_FIFO_SIZE 200 +#define FM_TRACE_PKT_SIZE 60 +struct fm_trace_t { + signed int type; + signed int opcode; + signed int len; + unsigned char pkt[FM_TRACE_PKT_SIZE]; /* full packet */ + unsigned long time; + signed int tid; +}; + +struct fm_trace_fifo_t { + signed char name[20 + 1]; + struct fm_trace_t trace[FM_TRACE_FIFO_SIZE]; + unsigned int size; + unsigned int in; + unsigned int out; + unsigned int len; + signed int (*trace_in)(struct fm_trace_fifo_t *thiz, struct fm_trace_t *new_tra); + signed int (*trace_out)(struct fm_trace_fifo_t *thiz, struct fm_trace_t *dst_tra); + + bool (*is_full)(struct fm_trace_fifo_t *thiz); + bool (*is_empty)(struct fm_trace_fifo_t *thiz); +}; + +#define FM_TRACE_IN(fifop, tracep) \ +({ \ + signed int __ret = (signed int)0; \ + if (fifop && (fifop)->trace_in) { \ + __ret = (fifop)->trace_in(fifop, tracep); \ + } \ + __ret; \ +}) + +#define FM_TRACE_OUT(fifop, tracep) \ +({ \ + signed int __ret = (signed int)0; \ + if (fifop && (fifop)->trace_out) { \ + __ret = (fifop)->trace_out(fifop, tracep); \ + } \ + __ret; \ +}) + +#define FM_TRACE_FULL(fifop) \ +({ \ + bool __ret = (bool)false; \ + if (fifop && (fifop)->is_full) { \ + __ret = (fifop)->is_full(fifop); \ + } \ + __ret; \ +}) + +#define FM_TRACE_EMPTY(fifop) \ +({ \ + bool __ret = (bool)false; \ + if (fifop && (fifop)->is_empty) { \ + __ret = (fifop)->is_empty(fifop); \ + } \ + __ret; \ +}) + +#define RX_BUF_SIZE 256 +#define TX_BUF_SIZE 1024 + +#define SW_RETRY_CNT (1) +#define SW_RETRY_CNT_MAX (5) +#define SW_WAIT_TIMEOUT_MAX (100) +/* FM operation timeout define for error handle */ +#define TEST_TIMEOUT (3) +#define FSPI_EN_TIMEOUT (3) +#define FSPI_MUXSEL_TIMEOUT (3) +#define FSPI_RD_TIMEOUT (3) +#define FSPI_WR_TIMEOUT (3) +#define I2C_RD_TIMEOUT (3) +#define I2C_WR_TIMEOUT (3) +#define EN_TIMEOUT (3) +#define RST_TIMEOUT (3) +#define TUNE_TIMEOUT (3) +#define SM_TUNE_TIMEOUT (6) +#define SEEK_TIMEOUT (15) +#define SCAN_TIMEOUT (15) /* usually scan will cost 10 seconds */ +#define RDS_RX_EN_TIMEOUT (3) +#define RDS_DATA_TIMEOUT (100) +#define RAMPDOWN_TIMEOUT (3) +#define MCUCLK_TIMEOUT (3) +#define MODEMCLK_TIMEOUT (3) +#define RDS_TX_TIMEOUT (3) +#define PATCH_TIMEOUT (3) +#define COEFF_TIMEOUT (3) +#define HWCOEFF_TIMEOUT (3) +#define ROM_TIMEOUT (3) +#define PMIC_CONTROL_TIMEOUT (3) + + +struct fm_link_event { + struct fm_flag_event *ln_event; + struct fm_res_ctx result; /* seek/scan/read/RDS */ +}; + +/* + * FM data and ctrl link APIs: platform related and bus related + */ +extern signed int fm_link_setup(void *data); + +extern signed int fm_link_release(void); + +extern signed int fm_cmd_tx(unsigned char *buf, unsigned short len, signed int mask, signed int cnt, signed int timeout, + signed int (*callback)(struct fm_res_ctx *result)); + +extern signed int fm_event_parser(signed int (*rds_parser)(struct rds_rx_t *, signed int)); + +extern signed int fm_ctrl_rx(unsigned char addr, unsigned short *val); + +extern signed int fm_ctrl_tx(unsigned char addr, unsigned short val); + +extern signed int fm_force_active_event(unsigned int mask); + +extern bool fm_wait_stc_done(unsigned int sec); + +extern struct fm_trace_fifo_t *fm_trace_fifo_create(const signed char *name); + +extern signed int fm_trace_fifo_release(struct fm_trace_fifo_t *fifo); + +extern signed int fm_print_cmd_fifo(void); + +extern signed int fm_print_evt_fifo(void); + +#endif /* __FM_LINK_H__ */ diff --git a/drivers/misc/mediatek/connectivity/fmradio/inc/fm_main.h b/drivers/misc/mediatek/connectivity/fmradio/inc/fm_main.h new file mode 100644 index 0000000000000000000000000000000000000000..4e726931087e148fdf7afd705f7802903798b677 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/inc/fm_main.h @@ -0,0 +1,406 @@ +/* + * Copyright (C) 2015 MediaTek Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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. + */ + +#ifndef __FM_MAIN_H__ +#define __FM_MAIN_H__ + +#include "fm_typedef.h" +#include "fm_dbg.h" +#include "fm_err.h" +#include "fm_rds.h" +#include "fm_eint.h" +#include "fm_link.h" +#include "fm_interface.h" +#include "fm_stdlib.h" +#include "fm_config.h" + +#define FM_NAME "fm" +#define FM_DEVICE_NAME "/dev/fm" + +#define FM_VOL_MAX 0x2B /* 43 volume(0-15) */ +#define FM_TIMER_TIMEOUT_DEFAULT 1000 +#define FM_TIMER_TIMEOUT_MIN 1000 +#define FM_TIMER_TIMEOUT_MAX 1000000 +/* FM Tx */ +#define FM_TX_PWR_LEVEL_MAX 120 /* FM transmitter power level, rang: 85db~120db, default 120db */ + +#define FM_TX_PWR_CTRL_INVAL_DEFAULT 10 +#define FM_TX_PWR_CTRL_INVAL_MIN 5 +#define FM_TX_PWR_CTRL_INVAL_MAX 10000 + +#define FM_TX_VCO_OFF_DEFAULT 5 +#define FM_TX_VCO_OFF_MIN 1 +#define FM_TX_VCO_OFF_MAX 10000 + +#define FM_TX_VCO_ON_DEFAULT 100 +#define FM_TX_VCO_ON_MIN 10 +#define FM_TX_VCO_ON_MAX 10000 + +#define FM_GPS_RTC_AGE_TH 2 +#define FM_GPS_RTC_DRIFT_TH 0 +#define FM_GPS_RTC_TIME_DIFF_TH 10 +#define FM_GPS_RTC_RETRY_CNT 1 +#define FM_GPS_RTC_DRIFT_MAX 5000 +enum { + FM_GPS_RTC_INFO_OLD = 0, + FM_GPS_RTC_INFO_NEW = 1, + FM_GPS_RTC_INFO_MAX +}; + +enum fm_over_bt_enable_state { + FM_OVER_BT_DISABLE = 0, + FM_OVER_BT_ENABLE +}; + +#define FM_RDS_ENABLE 0x01 /* 1: enable RDS, 0:disable RDS */ +#define FM_RDS_DATA_READY (1 << 0) + +/* errno */ +#define FM_SUCCESS 0 +#define FM_FAILED 1 +#define FM_EPARM 2 +#define FM_BADSTATUS 3 +#define FM_TUNE_FAILED 4 +#define FM_SEEK_FAILED 5 +#define FM_BUSY 6 +#define FM_SCAN_FAILED 7 + +struct fm_tune_parm { + unsigned char err; + unsigned char band; + unsigned char space; + unsigned char hilo; + unsigned char deemphasis; + unsigned short freq; /* IN/OUT parameter */ +}; + +struct fm_tune_parm_old { + unsigned char err; + unsigned char band; + unsigned char space; + unsigned char hilo; + unsigned short freq; /* IN/OUT parameter */ +}; + +struct fm_seek_parm { + unsigned char err; + unsigned char band; + unsigned char space; + unsigned char hilo; + unsigned char seekdir; + unsigned char seekth; + unsigned short freq; /* IN/OUT parameter */ +}; + +struct fm_scan_parm { + unsigned char err; + unsigned char band; + unsigned char space; + unsigned char hilo; + unsigned short freq; /* OUT parameter */ + unsigned short ScanTBL[26]; /* need no less than the chip */ + unsigned short ScanTBLSize; /* IN/OUT parameter */ +}; + +struct fm_cqi { + signed int ch; + signed int rssi; + signed int reserve; +}; + +struct fm_cqi_req { + unsigned short ch_num; + signed int buf_size; + signed char *cqi_buf; +}; + +struct fm_ch_rssi { + unsigned short freq; + signed int rssi; +}; + +enum fm_scan_cmd_t { + FM_SCAN_CMD_INIT = 0, + FM_SCAN_CMD_START, + FM_SCAN_CMD_GET_NUM, + FM_SCAN_CMD_GET_CH, + FM_SCAN_CMD_GET_RSSI, + FM_SCAN_CMD_GET_CH_RSSI, + FM_SCAN_CMD_MAX +}; + +struct fm_scan_t { + enum fm_scan_cmd_t cmd; + signed int ret; /* 0, success; else error code */ + unsigned short lower; /* lower band, Eg, 7600 -> 76.0Mhz */ + unsigned short upper; /* upper band, Eg, 10800 -> 108.0Mhz */ + signed int space; /* 5: 50KHz, 10: 100Khz, 20: 200Khz */ + signed int num; /* valid channel number */ + void *priv; + signed int sr_size; /* scan result buffer size in bytes */ + union { + unsigned short *ch_buf; /* channel buffer */ + signed int *rssi_buf; /* rssi buffer */ + struct fm_ch_rssi *ch_rssi_buf; /* channel and RSSI buffer */ + } sr; +}; + +struct fm_seek_t { + signed int ret; /* 0, success; else error code */ + unsigned short freq; + unsigned short lower; /* lower band, Eg, 7600 -> 76.0Mhz */ + unsigned short upper; /* upper band, Eg, 10800 -> 108.0Mhz */ + signed int space; /* 5: 50KHz, 10: 100Khz, 20: 200Khz */ + signed int dir; /* 0: up; 1: down */ + signed int th; /* seek threshold in dbm(Eg, -95dbm) */ + void *priv; +}; + +struct fm_tune_t { + signed int ret; /* 0, success; else error code */ + unsigned short freq; + unsigned short lower; /* lower band, Eg, 7600 -> 76.0Mhz */ + unsigned short upper; /* upper band, Eg, 10800 -> 108.0Mhz */ + signed int space; /* 5: 50KHz, 10: 100Khz, 20: 200Khz */ + void *priv; +}; + +struct fm_rssi_req { + unsigned short num; + unsigned short read_cnt; + struct fm_ch_rssi cr[26 * 16]; +}; + +struct fm_rds_tx_parm { + unsigned char err; + unsigned short pi; + unsigned short ps[12]; /* 4 ps */ + unsigned short other_rds[87]; /* 0~29 other groups */ + unsigned char other_rds_cnt; /* # of other group */ +}; + +struct fm_rds_tx_req { + unsigned char pty; /* 0~31 integer */ + unsigned char rds_rbds; /* 0:RDS, 1:RBDS */ + unsigned char dyn_pty; /* 0:static, 1:dynamic */ + unsigned short pi_code; /* 2-byte hex */ + unsigned char ps_buf[8]; /* hex buf of PS */ + unsigned char ps_len; /* length of PS, must be 0 / 8" */ + unsigned char af; /* 0~204, 0:not used, 1~204:(87.5+0.1*af)MHz */ + unsigned char ah; /* Artificial head, 0:no, 1:yes */ + unsigned char stereo; /* 0:mono, 1:stereo */ + unsigned char compress; /* Audio compress, 0:no, 1:yes */ + unsigned char tp; /* traffic program, 0:no, 1:yes */ + unsigned char ta; /* traffic announcement, 0:no, 1:yes */ + unsigned char speech; /* 0:music, 1:speech */ +}; + +#define TX_SCAN_MAX 10 +#define TX_SCAN_MIN 1 + +struct fm_tx_scan_parm { + unsigned char err; + unsigned char band; /* 87.6~108MHz */ + unsigned char space; + unsigned char hilo; + unsigned short freq; /* start freq, if less than band min freq, then will use band min freq */ + unsigned char scandir; + unsigned short ScanTBL[TX_SCAN_MAX]; /* need no less than the chip */ + unsigned short ScanTBLSize; /* IN: desired size, OUT: scan result size */ +}; + +struct fm_gps_rtc_info { + signed int err; /* error number, 0: success, other: err code */ + signed int retryCnt; /* GPS mnl can decide retry times */ + signed int ageThd; /* GPS 3D fix time diff threshold */ + signed int driftThd; /* GPS RTC drift threshold */ + struct timeval tvThd; /* time value diff threshold */ + signed int age; /* GPS 3D fix time diff */ + signed int drift; /* GPS RTC drift */ + union { + unsigned long stamp; /* time stamp in jiffies */ + struct timeval tv; /* time stamp value in RTC */ + }; + signed int flag; /* rw flag */ +}; + +struct fm_desense_check_t { + signed int freq; + signed int rssi; +}; + +struct fm_full_cqi_log_t { + uint16_t lower; /* lower band, Eg, 7600 -> 76.0Mhz */ + uint16_t upper; /* upper band, Eg, 10800 -> 108.0Mhz */ + int space; /* 0x1: 50KHz, 0x2: 100Khz, 0x4: 200Khz */ + int cycle; /* repeat times */ +}; + +enum { + FM_RX = 0, + FM_TX = 1 +}; + +struct fm_ctl_parm { + unsigned char err; + unsigned char addr; + unsigned short val; + unsigned short rw_flag; /* 0:write, 1:read */ +}; +struct fm_em_parm { + unsigned short group_idx; + unsigned short item_idx; + unsigned int item_value; +}; +struct fm_top_rw_parm { + unsigned char err; + unsigned char rw_flag; /* 0:write, 1:read */ + unsigned short addr; + unsigned int val; +}; +struct fm_host_rw_parm { + unsigned char err; + unsigned char rw_flag; /* 0:write, 1:read */ + unsigned int addr; + unsigned int val; +}; +struct fm_pmic_rw_parm { + unsigned char err; + unsigned char rw_flag; /* 0:write, 1:read */ + unsigned char addr; + unsigned int val; +}; +enum { + FM_SUBSYS_RST_OFF, + FM_SUBSYS_RST_START, + FM_SUBSYS_RST_END, + FM_SUBSYS_RST_MAX +}; +enum { + FM_TX_PWR_CTRL_DISABLE, + FM_TX_PWR_CTRL_ENABLE, + FM_TX_PWR_CTRL_MAX +}; + +enum { + FM_TX_RTC_CTRL_DISABLE, + FM_TX_RTC_CTRL_ENABLE, + FM_TX_RTC_CTRL_MAX +}; + +enum { + FM_TX_DESENSE_DISABLE, + FM_TX_DESENSE_ENABLE, + FM_TX_DESENSE_MAX +}; + +struct fm_softmute_tune_t { + signed int rssi; /* RSSI of current channel */ + unsigned short freq; /* current frequency */ + signed int valid; /* current channel is valid(true) or not(false) */ +}; +struct fm_search_threshold_t { + signed int th_type; /* 0, RSSI. 1,desense RSSI. 2,SMG. */ + signed int th_val; /* threshold value */ + signed int reserve; +}; + +struct fm_status_t { + int which; + bool stat; +}; + +struct fm_chip_mapping { + unsigned short con_chip; + unsigned short fm_chip; + enum fm_cfg_chip_type type; +}; + +/* init and deinit APIs */ +extern signed int fm_env_setup(void); +extern signed int fm_env_destroy(void); +extern struct fm *fm_dev_init(unsigned int arg); +extern signed int fm_dev_destroy(struct fm *fm); + +/* fm main basic APIs */ +extern enum fm_pwr_state fm_pwr_state_get(struct fm *fmp); +extern enum fm_pwr_state fm_pwr_state_set(struct fm *fmp, enum fm_pwr_state sta); +extern signed int fm_open(struct fm *fmp); +extern signed int fm_close(struct fm *fmp); +extern signed int fm_rds_read(struct fm *fmp, signed char *dst, signed int len); +extern signed int fm_powerup(struct fm *fm, struct fm_tune_parm *parm); +extern signed int fm_powerdown(struct fm *fm, int type); +extern signed int fm_cqi_get(struct fm *fm, signed int ch_num, signed char *buf, signed int buf_size); +extern signed int fm_get_hw_info(struct fm *pfm, struct fm_hw_info *req); +extern signed int fm_hwscan_stop(struct fm *fm); +extern signed int fm_ana_switch(struct fm *fm, signed int antenna); +extern signed int fm_setvol(struct fm *fm, unsigned int vol); +extern signed int fm_getvol(struct fm *fm, unsigned int *vol); +extern signed int fm_mute(struct fm *fm, unsigned int bmute); +extern signed int fm_getrssi(struct fm *fm, signed int *rssi); +extern signed int fm_read(struct fm *fm, unsigned char addr, unsigned short *val); +extern signed int fm_write(struct fm *fm, unsigned char addr, unsigned short val); +extern signed int fm_top_read(struct fm *fm, unsigned short addr, unsigned int *val); +extern signed int fm_top_write(struct fm *fm, unsigned short addr, unsigned int val); +extern signed int fm_host_read(struct fm *fm, unsigned int addr, unsigned int *val); +extern signed int fm_host_write(struct fm *fm, unsigned int addr, unsigned int val); +extern signed int fm_pmic_read(struct fm *fm, unsigned char addr, unsigned int *val); +extern signed int fm_pmic_write(struct fm *fm, unsigned char addr, unsigned int val); +extern signed int fm_chipid_get(struct fm *fm, unsigned short *chipid); +extern signed int fm_monostereo_get(struct fm *fm, unsigned short *ms); +extern signed int fm_monostereo_set(struct fm *fm, signed int ms); +extern signed int fm_pamd_get(struct fm *fm, unsigned short *pamd); +extern signed int fm_caparray_get(struct fm *fm, signed int *ca); +extern signed int fm_em_test(struct fm *fm, unsigned short group, unsigned short item, unsigned int val); +extern signed int fm_rds_onoff(struct fm *fm, unsigned short rdson_off); +extern signed int fm_rds_good_bc_get(struct fm *fm, unsigned short *gbc); +extern signed int fm_rds_bad_bc_get(struct fm *fm, unsigned short *bbc); +extern signed int fm_rds_bler_ratio_get(struct fm *fm, unsigned short *bbr); +extern signed int fm_rds_group_cnt_get(struct fm *fm, struct rds_group_cnt_t *dst); +extern signed int fm_rds_group_cnt_reset(struct fm *fm); +extern signed int fm_rds_log_get(struct fm *fm, struct rds_rx_t *dst, signed int *dst_len); +extern signed int fm_rds_block_cnt_reset(struct fm *fm); +extern signed int fm_i2s_set(struct fm *fm, signed int onoff, signed int mode, signed int sample); +extern signed int fm_get_i2s_info(struct fm *pfm, struct fm_i2s_info *req); +extern signed int fm_tune(struct fm *fm, struct fm_tune_parm *parm); +extern signed int fm_is_dese_chan(struct fm *pfm, unsigned short freq); +extern signed int fm_desense_check(struct fm *pfm, unsigned short freq, signed int rssi); +extern signed int fm_sys_state_get(struct fm *fmp); +extern signed int fm_sys_state_set(struct fm *fmp, signed int sta); +extern signed int fm_set_stat(struct fm *fmp, int which, bool stat); +extern signed int fm_get_stat(struct fm *fmp, int which, bool *stat); +extern signed int fm_subsys_reset(struct fm *fm); +extern signed int fm_cqi_log(void); +extern signed int fm_soft_mute_tune(struct fm *fm, struct fm_softmute_tune_t *parm); +extern signed int fm_pre_search(struct fm *fm); +extern signed int fm_restore_search(struct fm *fm); + +extern signed int fm_dump_reg(void); +extern signed int fm_get_gps_rtc_info(struct fm_gps_rtc_info *src); +extern signed int fm_over_bt(struct fm *fm, signed int flag); +extern signed int fm_set_search_th(struct fm *fm, struct fm_search_threshold_t parm); +extern signed int fm_get_aud_info(struct fm_audio_info_t *data); +/*tx function*/ +extern signed int fm_tx_support(struct fm *fm, signed int *support); + +extern signed int fm_powerup_tx(struct fm *fm, struct fm_tune_parm *parm); +extern signed int fm_tune_tx(struct fm *fm, struct fm_tune_parm *parm); +extern signed int fm_powerdowntx(struct fm *fm); +extern signed int fm_rds_tx(struct fm *fm, struct fm_rds_tx_parm *parm); +extern signed int fm_rdstx_support(struct fm *fm, signed int *support); +extern signed int fm_rdstx_enable(struct fm *fm, signed int enable); +extern signed int fm_tx_scan(struct fm *fm, struct fm_tx_scan_parm *parm); +signed int fm_full_cqi_logger(struct fm_full_cqi_log_t *setting); +signed int fm_rds_parser(struct rds_rx_t *rds_raw, signed int rds_size); + +#endif /* __FM_MAIN_H__ */ diff --git a/drivers/misc/mediatek/connectivity/fmradio/inc/fm_patch.h b/drivers/misc/mediatek/connectivity/fmradio/inc/fm_patch.h new file mode 100644 index 0000000000000000000000000000000000000000..10496381decab47f9df1759054dfc40394f1dde7 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/inc/fm_patch.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2015 MediaTek Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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. + */ + +#ifndef __FM_PATCH_H__ +#define __FM_PATCH_H__ + +enum { + FM_ROM_V1 = 0, + FM_ROM_V2 = 1, + FM_ROM_V3 = 2, + FM_ROM_V4 = 3, + FM_ROM_V5 = 4, + FM_ROM_MAX +}; + +struct fm_patch_tbl { + signed int idx; + signed char *patch; + signed char *coeff; + signed char *rom; + signed char *hwcoeff; +}; + +struct fm_file_read_data { + const signed char *filename; + unsigned char *dst; + signed int len; + signed int position; + signed int ret; + struct completion comp; +}; + +extern signed int fm_file_read(const signed char *filename, unsigned char *dst, signed int len, signed int position); + +extern signed int fm_file_write(const signed char *filename, unsigned char *dst, signed int len, signed int *ppos); + +#endif /* __FM_PATCH_H__ */ diff --git a/drivers/misc/mediatek/connectivity/fmradio/inc/fm_rds.h b/drivers/misc/mediatek/connectivity/fmradio/inc/fm_rds.h new file mode 100644 index 0000000000000000000000000000000000000000..c2d74e9b6acbcf3ed7eae1119e720608a68c5243 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/inc/fm_rds.h @@ -0,0 +1,230 @@ +/* + * Copyright (C) 2015 MediaTek Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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. + */ + +#ifndef __FM_RDS_H__ +#define __FM_RDS_H__ +#include "fm_typedef.h" + +/* FM_RDS_DATA_CRC_FFOST */ +#define FM_RDS_GDBK_IND_A (0x08) +#define FM_RDS_GDBK_IND_B (0x04) +#define FM_RDS_GDBK_IND_C (0x02) +#define FM_RDS_GDBK_IND_D (0x01) +#define FM_RDS_DCO_FIFO_OFST (0x01E0) +#define FM_RDS_READ_DELAY (0x80) + +#define RDS_RX_BLOCK_PER_GROUP (4) +#define RDS_RX_GROUP_SIZE (2*RDS_RX_BLOCK_PER_GROUP) +#define MAX_RDS_RX_GROUP_CNT (12) +#define RDS_RT_MULTI_REV_TH 80 /* 100 */ +/* #define RDS_CBC_DEPENDENCY */ + +struct rds_packet_t { + unsigned short blkA; + unsigned short blkB; + unsigned short blkC; + unsigned short blkD; + unsigned short cbc; /* correct bit cnt */ + unsigned short crc; /* crc checksum */ +}; + +struct rds_rx_t { + unsigned short sin; + unsigned short cos; + struct rds_packet_t data[MAX_RDS_RX_GROUP_CNT]; +}; + +enum rds_ps_state_machine_t { + RDS_PS_START = 0, + RDS_PS_DECISION, + RDS_PS_GETLEN, + RDS_PS_DISPLAY, + RDS_PS_FINISH, + RDS_PS_MAX +}; + +enum rds_rt_state_machine_t { + RDS_RT_START = 0, + RDS_RT_DECISION, + RDS_RT_GETLEN, + RDS_RT_DISPLAY, + RDS_RT_FINISH, + RDS_RT_MAX +}; + +enum { + RDS_GRP_VER_A = 0, /* group version A */ + RDS_GRP_VER_B +}; + +enum rds_blk_t { + RDS_BLK_A = 0, + RDS_BLK_B, + RDS_BLK_C, + RDS_BLK_D, + RDS_BLK_MAX +}; + +/* For RDS feature, these strcutures also be defined in "fm.h" */ +struct rds_flag_t { + unsigned char TP; + unsigned char TA; + unsigned char Music; + unsigned char Stereo; + unsigned char Artificial_Head; + unsigned char Compressed; + unsigned char Dynamic_PTY; + unsigned char Text_AB; + unsigned int flag_status; +}; + +struct rds_ct_t { + unsigned short Month; + unsigned short Day; + unsigned short Year; + unsigned short Hour; + unsigned short Minute; + unsigned char Local_Time_offset_signbit; + unsigned char Local_Time_offset_half_hour; +}; + +struct rds_af_t { + signed short AF_Num; + signed short AF[2][25]; /* 100KHz */ + unsigned char Addr_Cnt; + unsigned char isMethod_A; + unsigned char isAFNum_Get; +}; + +struct rds_ps_t { + unsigned char PS[4][8]; + unsigned char Addr_Cnt; +}; + +struct rds_rt_t { + unsigned char TextData[4][64]; + unsigned char GetLength; + unsigned char isRTDisplay; + unsigned char TextLength; + unsigned char isTypeA; + unsigned char BufCnt; + unsigned short Addr_Cnt; +}; + +struct rds_raw_t { + signed int dirty; /* indicate if the data changed or not */ + signed int len; /* the data len form chip */ + unsigned char data[148]; +}; + +struct rds_group_cnt_t { + unsigned int total; + unsigned int groupA[16]; /* RDS groupA counter */ + unsigned int groupB[16]; /* RDS groupB counter */ +}; + +enum rds_group_cnt_op_t { + RDS_GROUP_CNT_READ = 0, + RDS_GROUP_CNT_WRITE, + RDS_GROUP_CNT_RESET, + RDS_GROUP_CNT_MAX +}; + +struct rds_group_cnt_req_t { + signed int err; + enum rds_group_cnt_op_t op; + struct rds_group_cnt_t gc; +}; + +struct rds_t { + struct rds_ct_t CT; + struct rds_flag_t RDSFlag; + unsigned short PI; + unsigned char Switch_TP; + unsigned char PTY; + struct rds_af_t AF_Data; + struct rds_af_t AFON_Data; + unsigned char Radio_Page_Code; + unsigned short Program_Item_Number_Code; + unsigned char Extend_Country_Code; + unsigned short Language_Code; + struct rds_ps_t PS_Data; + unsigned char PS_ON[8]; + struct rds_rt_t RT_Data; + /* will use RDSFlag_Struct RDSFlag->flag_status to check which event, is that ok? */ + unsigned short event_status; + struct rds_group_cnt_t gc; +}; + +/* Need care the following definition. */ +/* valid Rds Flag for notify */ +enum rds_flag_status_t { + RDS_FLAG_IS_TP = 0x0001, /* Program is a traffic program */ + RDS_FLAG_IS_TA = 0x0002, /* Program currently broadcasts a traffic ann. */ + RDS_FLAG_IS_MUSIC = 0x0004, /* Program currently broadcasts music */ + RDS_FLAG_IS_STEREO = 0x0008, /* Program is transmitted in stereo */ + RDS_FLAG_IS_ARTIFICIAL_HEAD = 0x0010, /* Program is an artificial head recording */ + RDS_FLAG_IS_COMPRESSED = 0x0020, /* Program content is compressed */ + RDS_FLAG_IS_DYNAMIC_PTY = 0x0040, /* Program type can change */ + RDS_FLAG_TEXT_AB = 0x0080 /* If this flag changes state, a new radio text string begins */ +}; + +enum rds_event_status_t { + RDS_EVENT_FLAGS = 0x0001, /* One of the RDS flags has changed state */ + RDS_EVENT_PI_CODE = 0x0002, /* The program identification code has changed */ + RDS_EVENT_PTY_CODE = 0x0004, /* The program type code has changed */ + RDS_EVENT_PROGRAMNAME = 0x0008, /* The program name has changed */ + RDS_EVENT_UTCDATETIME = 0x0010, /* A new UTC date/time is available */ + RDS_EVENT_LOCDATETIME = 0x0020, /* A new local date/time is available */ + RDS_EVENT_LAST_RADIOTEXT = 0x0040, /* A radio text string was completed */ + RDS_EVENT_AF = 0x0080, /* Current Channel RF signal strength too weak, need do AF switch */ + RDS_EVENT_AF_LIST = 0x0100, /* An alternative frequency list is ready */ + RDS_EVENT_AFON_LIST = 0x0200, /* An alternative frequency list is ready */ + RDS_EVENT_TAON = 0x0400, /* Other Network traffic announcement start */ + RDS_EVENT_TAON_OFF = 0x0800, /* Other Network traffic announcement finished. */ + RDS_EVENT_ECC_CODE = 0x1000, /* ECC code */ + RDS_EVENT_RDS = 0x2000, /* RDS Interrupt had arrived durint timer period */ + RDS_EVENT_NO_RDS = 0x4000, /* RDS Interrupt not arrived durint timer period */ + RDS_EVENT_RDS_TIMER = 0x8000 /* Timer for RDS Bler Check. ---- BLER block error rate */ +}; + +#define RDS_LOG_SIZE 1 +struct rds_log_t { + struct rds_rx_t rds_log[RDS_LOG_SIZE]; + signed int log_len[RDS_LOG_SIZE]; + unsigned int size; + unsigned int in; + unsigned int out; + unsigned int len; + signed int (*log_in)(struct rds_log_t *thiz, struct rds_rx_t *new_log, signed int new_len); + signed int (*log_out)(struct rds_log_t *thiz, struct rds_rx_t *dst, signed int *dst_len); +}; + +extern signed int rds_parser(struct rds_t *rds_dst, struct rds_rx_t *rds_raw, + signed int rds_size, unsigned short(*getfreq) (void)); +extern signed int rds_grp_counter_get(struct rds_group_cnt_t *dst, struct rds_group_cnt_t *src); +extern signed int rds_grp_counter_reset(struct rds_group_cnt_t *gc); +extern signed int rds_log_in(struct rds_log_t *thiz, struct rds_rx_t *new_log, signed int new_len); +extern signed int rds_log_out(struct rds_log_t *thiz, struct rds_rx_t *dst, signed int *dst_len); + +#define DEFINE_RDSLOG(name) \ + struct rds_log_t name = { \ + .size = RDS_LOG_SIZE, \ + .in = 0, \ + .out = 0, \ + .len = 0, \ + .log_in = rds_log_in, \ + .log_out = rds_log_out, \ + } + +#endif /* __FM_RDS_H__ */ diff --git a/drivers/misc/mediatek/connectivity/fmradio/inc/fm_reg_utils.h b/drivers/misc/mediatek/connectivity/fmradio/inc/fm_reg_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..1ff2c57f696cb796d1f4a484f6915a54eb0bcfe4 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/inc/fm_reg_utils.h @@ -0,0 +1,394 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +#ifndef FM_REG_UTILS_H +#define FM_REG_UTILS_H + +#include +#include +#include +#include +#include + +#include + +/* SPI register address */ +#if CFG_FM_CONNAC2 +#define SYS_SPI_BASE_ADDR (0x0000) +#else +#define SYS_SPI_BASE_ADDR (0x6000) +#endif +#define SYS_SPI_STA (0x00 + SYS_SPI_BASE_ADDR) +#define SYS_SPI_CRTL (0x04 + SYS_SPI_BASE_ADDR) +#define SYS_SPI_DIV (0x08 + SYS_SPI_BASE_ADDR) +#define SYS_SPI_FM_CTRL (0x0C + SYS_SPI_BASE_ADDR) + +/* control bit for SPI_STA */ +#define SYS_SPI_ADDR_CR_MASK (0x0FFF) +#define SYS_SPI_ADDR_CR_READ (0x01 << 12) +#define SYS_SPI_ADDR_CR_WRITE (0x00 << 12) + +#define SYS_SPI_ADDR_CR_WF1 (0x00 << 13) +#define SYS_SPI_ADDR_CR_WF (0x01 << 13) +#define SYS_SPI_ADDR_CR_BT (0x02 << 13) +#define SYS_SPI_ADDR_CR_FM (0x03 << 13) +#define SYS_SPI_ADDR_CR_GPS (0x04 << 13) +#define SYS_SPI_ADDR_CR_TOP (0x05 << 13) + +#define SYS_SPI_STA_WF_BUSY_ADDR SYS_SPI_STA +#define SYS_SPI_STA_WF_BUSY_MASK 0x0002 +#define SYS_SPI_STA_WF_BUSY_SHFT 1 + +#define SYS_SPI_STA_BT_BUSY_ADDR SYS_SPI_STA +#define SYS_SPI_STA_BT_BUSY_MASK 0x0004 +#define SYS_SPI_STA_BT_BUSY_SHFT 2 + +#define SYS_SPI_STA_FM_BUSY_ADDR SYS_SPI_STA +#define SYS_SPI_STA_FM_BUSY_MASK 0x0008 +#define SYS_SPI_STA_FM_BUSY_SHFT 3 + +#define SYS_SPI_STA_GPS_BUSY_ADDR SYS_SPI_STA +#define SYS_SPI_STA_GPS_BUSY_MASK 0x0010 +#define SYS_SPI_STA_GPS_BUSY_SHFT 4 + +#define SYS_SPI_STA_TOP_BUSY_ADDR SYS_SPI_STA +#define SYS_SPI_STA_TOP_BUSY_MASK 0x0020 +#define SYS_SPI_STA_TOP_BUSY_SHFT 5 + +/* control bit for SPI_STA */ +#define SYS_SPI_CRTL_MASTER_EN_ADDR SYS_SPI_CRTL +#define SYS_SPI_CRTL_MASTER_EN_MASK 0x8000 +#define SYS_SPI_CRTL_MASTER_EN_SHFT 15 + +/* control bit for SPI_DIV */ +#define SYS_SPI_DIV_DIV_CNT_ADDR SYS_SPI_DIV +#define SYS_SPI_DIV_DIV_CNT_MASK 0x00FF +#define SYS_SPI_DIV_DIV_CNT_SHFT 0 + +/* control bit for SPI_FM_CTRL */ +#define SYS_SPI_FM_CTRL_FM_RD_EXT_CNT_ADDR SYS_SPI_FM_CTRL +#define SYS_SPI_FM_CTRL_FM_RD_EXT_CNT_MASK 0x00FF +#define SYS_SPI_FM_CTRL_FM_RD_EXT_CNT_SHFT 0 + +#define SYS_SPI_FM_CTRL_FM_RD_EXT_EN_ADDR SYS_SPI_FM_CTRL +#define SYS_SPI_FM_CTRL_FM_RD_EXT_EN_MASK 0x8000 +#define SYS_SPI_FM_CTRL_FM_RD_EXT_EN_SHFT 15 + +/* WIFI data addr & mask */ +#define SYS_SPI_WF_ADDR_ADDR (0x10 + SYS_SPI_BASE_ADDR) +#define SYS_SPI_WF_ADDR_MASK 0xFFFF +#define SYS_SPI_WF_ADDR_SHFT 0 + +#define SYS_SPI_WF_WDAT_ADDR (0x14 + SYS_SPI_BASE_ADDR) +#define SYS_SPI_WF_WDAT_MASK 0xFFFFFFFF +#define SYS_SPI_WF_WDAT_SHFT 0 + +#define SYS_SPI_WF_RDAT_ADDR (0x18 + SYS_SPI_BASE_ADDR) +#define SYS_SPI_WF_RDAT_MASK 0xFFFFFFFF +#define SYS_SPI_WF_RDAT_SHFT 0 + +/* BT data addr & mask */ +#define SYS_SPI_BT_ADDR_ADDR (0x20 + SYS_SPI_BASE_ADDR) +#define SYS_SPI_BT_ADDR_MASK 0xFFFF +#define SYS_SPI_BT_ADDR_SHFT 0 + +#define SYS_SPI_BT_WDAT_ADDR (0x24 + SYS_SPI_BASE_ADDR) +#define SYS_SPI_BT_WDAT_MASK 0xFF +#define SYS_SPI_BT_WDAT_SHFT 0 + +#define SYS_SPI_BT_RDAT_ADDR (0x28 + SYS_SPI_BASE_ADDR) +#define SYS_SPI_BT_RDAT_MASK 0xFF +#define SYS_SPI_BT_RDAT_SHFT 0 + +/* FM data addr & mask */ +#define SYS_SPI_FM_ADDR_ADDR (0x30 + SYS_SPI_BASE_ADDR) +#define SYS_SPI_FM_ADDR_MASK 0xFFFF +#define SYS_SPI_FM_ADDR_SHFT 0 + +#define SYS_SPI_FM_WDAT_ADDR (0x34 + SYS_SPI_BASE_ADDR) +#define SYS_SPI_FM_WDAT_MASK 0xFFFF +#define SYS_SPI_FM_WDAT_SHFT 0 + +#define SYS_SPI_FM_RDAT_ADDR (0x38 + SYS_SPI_BASE_ADDR) +#define SYS_SPI_FM_RDAT_MASK 0xFFFF +#define SYS_SPI_FM_RDAT_SHFT 0 + +/* GPS data addr & mask */ +#define SYS_SPI_GPS_ADDR_ADDR (0x40 + SYS_SPI_BASE_ADDR) +#define SYS_SPI_GPS_ADDR_MASK 0xFFFF +#define SYS_SPI_GPS_ADDR_SHFT 0 + +#define SYS_SPI_GPS_WDAT_ADDR (0x44 + SYS_SPI_BASE_ADDR) +#define SYS_SPI_GPS_WDAT_MASK 0xFFFFFFFF +#define SYS_SPI_GPS_WDAT_SHFT 0 + +#define SYS_SPI_GPS_RDAT_ADDR (0x48 + SYS_SPI_BASE_ADDR) +#define SYS_SPI_GPS_RDAT_MASK 0xFFFFFFFF +#define SYS_SPI_GPS_RDAT_SHFT 0 + +/* TOP data addr & mask */ +#define SYS_SPI_TOP_ADDR_ADDR (0x50 + SYS_SPI_BASE_ADDR) +#define SYS_SPI_TOP_ADDR_MASK 0xFFFF +#define SYS_SPI_TOP_ADDR_SHFT 0 + +#define SYS_SPI_TOP_WDAT_ADDR (0x54 + SYS_SPI_BASE_ADDR) +#define SYS_SPI_TOP_WDAT_MASK 0xFFFFFFFF +#define SYS_SPI_TOP_WDAT_SHFT 0 + +#define SYS_SPI_TOP_RDAT_ADDR (0x58 + SYS_SPI_BASE_ADDR) +#define SYS_SPI_TOP_RDAT_MASK 0xFFFFFFFF +#define SYS_SPI_TOP_RDAT_SHFT 0 + +/* A-die TOP SPI registers */ +#define SYSCTL_HW_ID 0x24 +#define SYSCTL_ADIE_TOP_THADC 0xC4 +#define SYSCTL_CLK_STATUS 0xA00 +#define SYSCTL_WF_CLK_EN 0xA04 +#define SYSCTL_BT_CLK_EN 0xA08 +#define SYSCTL_GPS_CLK_EN 0xA0C +#define SYSCTL_TOP_CLK_EN 0xA10 + +#define SYSCTL_EFUSE_SIZE 32 +#define SYSCTL_Macro0_Efuse_D0 0x11C +#define SYSCTL_Macro1_Efuse_D0 0x124 + +/* FM basic-operation's opcode */ +#define FM_BOP_BASE (0x80) +enum { + FM_WRITE_BASIC_OP = (FM_BOP_BASE + 0x00), + FM_UDELAY_BASIC_OP = (FM_BOP_BASE + 0x01), + FM_RD_UNTIL_BASIC_OP = (FM_BOP_BASE + 0x02), + FM_MODIFY_BASIC_OP = (FM_BOP_BASE + 0x03), + FM_MSLEEP_BASIC_OP = (FM_BOP_BASE + 0x04), + FM_WRITE_SPI_BASIC_OP = (FM_BOP_BASE + 0x05), + FM_RD_SPI_UNTIL_BASIC_OP = (FM_BOP_BASE + 0x06), + FM_MODIFY_SPI_BASIC_OP = (FM_BOP_BASE + 0x07), + FM_MAX_BASIC_OP = (FM_BOP_BASE + 0x08) +}; + +/* FM SPI control registers */ +#define FSPI_MAS_BASE (0x80060000) +#define FSPI_MAS_CONTROL_REG (FSPI_MAS_BASE + 0x0000) +#define FSPI_MAS_ADDR_REG (FSPI_MAS_BASE + 0x0004) +#define FSPI_MAS_WRDATA_REG (FSPI_MAS_BASE + 0x0008) +#define FSPI_MAS_RDDATA_REG (FSPI_MAS_BASE + 0x000C) +#define FSPI_MAS_CFG1_REG (FSPI_MAS_BASE + 0x0010) +#define FSPI_MAS_CFG2_REG (FSPI_MAS_BASE + 0x0014) +#define FSPI_MAS_MODESEL_REG (FSPI_MAS_BASE + 0x0020) +#define FSPI_MAS_RESET_REG (FSPI_MAS_BASE + 0x0030) +#define FSPI_MAS_DEBUG1_REG (FSPI_MAS_BASE + 0x0034) +#define FSPI_MAS_DEBUG2_REG (FSPI_MAS_BASE + 0x0038) +#define FSPI_MAS_DEBUG3_REG (FSPI_MAS_BASE + 0x003C) +#define FSPI_MAS_DEBUG4_REG (FSPI_MAS_BASE + 0x0040) +#define FSPI_MAS_DEBUG5_REG (FSPI_MAS_BASE + 0x0048) + +/* FM Main Control Register */ +#define FM_MAIN_CTRL_TUNE (0x0001) +#define FM_MAIN_CTRL_SEEK (0x0002) +#define FM_MAIN_CTRL_SCAN (0x0004) +#define FM_MAIN_CTRL_DSP_INIT (0x0008) +#define FM_MAIN_CTRL_SCAN_CQI (0x0008) +#define FM_MAIN_CTRL_RDS (0x0010) +#define FM_MAIN_CTRL_DCOC (0x0020) +#define FM_MAIN_CTRL_MUTE (0x0040) +#define FM_MAIN_CTRL_IQCAL (0x0080) +#define FM_MAIN_CTRL_RAMPDOWN (0x0100) +#define FM_MAIN_CTRL_MEM_FLUSH (0x0200) +#define FM_MAIN_CTRL_MASK (0x0Fff) + +/* RDS control registers */ +#define FM_RDS_BASE (0x0) +#define RDS_INFO_REG (FM_RDS_BASE + 0x81) +#define RDS_CRC_CORR_CNT 0x001E +#define RDS_CRC_INFO 0x0001 +#define RDS_DATA_REG (FM_RDS_BASE + 0x82) +#define SCAN_BUFF_LEN 0xF +#define RDS_SIN_REG (FM_RDS_BASE + 0x85) +#define RDS_COS_REG (FM_RDS_BASE + 0x86) +#define RDS_FIFO_STATUS0 (FM_RDS_BASE + 0x87) +#define RDS_POINTER (FM_RDS_BASE + 0xF0) + +/* RDS Interrupt Status Register */ +#define RDS_INTR_THRE (0x0001) +#define RDS_INTR_TO (0x0002) +#define RDS_INTR_FULL (0x0004) +#define RDS_INTR_MASK (0x0007) +#define RDS_TX_INTR_MASK (0x0070) +#define RDS_TX_INTR_EMPTY (0x0010) +#define RDS_TX_INTR_LOW (0x0020) +#define RDS_TX_INTR_FULL (0x0040) +#define RDS_TX_INTR_EMPTY_MASK (0x0001) +#define RDS_TX_INTR_LOW_MASK (0x0002) +#define RDS_TX_INTR_FULL_MASK (0x0004) + +/* RDS Data CRC Offset Register */ +#define RDS_DCO_FIFO_OFST (0x007C) +#define RDS_DCO_FIFO_OFST_SHFT 2 + +/* Parameter for RDS */ +/* total 12 groups */ +#define RDS_RX_FIFO_CNT (12) +/* delay 1us between each register read */ +#define RDS_READ_DELAY (1) +#define RDS_GROUP_READ_DELAY (85) +#define FIFO_LEN (48) + +/* Parameter for DSP download */ +#define OFFSET_REG 0x91 +#define CONTROL_REG 0x90 +#define DATA_REG 0x92 + +#define FM_SOFTMUTE_TUNE_CQI_SIZE 0x16 + +#define FM_SPI_COUNT_LIMIT 100000 + +#define FM_BUFFER_SIZE (2048) +#define FM_HDR_SIZE (4) + +/* FM main registers */ +enum { + FM_MAIN_MCLKDESENSE = 0x38, + FM_MAIN_CG1_CTRL = 0x60, + FM_MAIN_CG2_CTRL = 0x61, + FM_MAIN_HWVER = 0x62, + FM_MAIN_CTRL = 0x63, + FM_MAIN_EN1 = 0x64, + FM_CHANNEL_SET = 0x65, + FM_MAIN_CFG1 = 0x66, + FM_MAIN_CFG2 = 0x67, + FM_MAIN_CFG3 = 0x68, + FM_MAIN_INTR = 0x69, + FM_MAIN_INTRMASK = 0x6A, + FM_MAIN_EXTINTRMASK = 0x6B, + FM_RSSI_IND = 0x6C, + FM_RSSI_TH = 0x6D, + FM_MAIN_RESET = 0x6E, + FM_MAIN_CHANDETSTAT = 0x6F, + FM_MAIN_IQCOMP1 = 0x70, + FM_MAIN_IQCOMP2 = 0x71, + FM_MAIN_IQCOMP3 = 0x72, + FM_MAIN_IQCOMP4 = 0x73, + FM_MAIN_RXCALSTAT1 = 0x74, + FM_MAIN_RXCALSTAT2 = 0x75, + FM_MAIN_RXCALSTAT3 = 0x76, + FM_MAIN_MCLKDESENSE2 = 0x77, + FM_MAIN_MCLKDESENSE3 = 0x78, + FM_MAIN_CHNLSCAN_CTRL = 0x79, + FM_MAIN_CHNLSCAN_STAT = 0x7a, + FM_MAIN_CHNLSCAN_STAT2 = 0x7b, + FM_RDS_CFG0 = 0x80, + FM_RDS_INFO = 0x81, + FM_RDS_DATA_REG = 0x82, + FM_RDS_GOODBK_CNT = 0x83, + FM_RDS_BADBK_CNT = 0x84, + FM_RDS_PWDI = 0x85, + FM_RDS_PWDQ = 0x86, + FM_RDS_FIFO_STATUS0 = 0x87, + FM_FT_CON9 = 0x8F, + FM_DSP_PATCH_CTRL = 0x90, + FM_DSP_PATCH_OFFSET = 0x91, + FM_DSP_PATCH_DATA = 0x92, + FM_DSP_MEM_CTRL4 = 0x93, + FM_MAIN_PGSEL = 0x9f, + FM_ADDR_PAMD = 0xB4, + FM_RDS_BDGRP_ABD_CTRL_REG = 0xB6, + FM_RDS_POINTER = 0xF0, +}; + +/* FM Main Interrupt Register */ +enum { + FM_INTR_STC_DONE = 0x0001, + FM_INTR_IQCAL_DONE = 0x0002, + FM_INTR_DESENSE_HIT = 0x0004, + FM_INTR_CHNL_CHG = 0x0008, + FM_INTR_SW_INTR = 0x0010, + FM_INTR_RDS = 0x0020, + FM_INTR_CQI = 0x0021, + FM_INTR_MASK = 0x003f +}; + +enum { + DSP_ROM = 0, + DSP_PATCH, + DSP_COEFF, + DSP_HWCOEFF +}; + +struct fm_wcn_reg_info { + phys_addr_t spi_phy_addr; + void __iomem *spi_vir_addr; + unsigned int spi_size; + phys_addr_t top_phy_addr; + void __iomem *top_vir_addr; + unsigned int top_size; + phys_addr_t mcu_phy_addr; + void __iomem *mcu_vir_addr; + unsigned int mcu_size; +}; + +struct fm_spi_interface { + struct fm_wcn_reg_info info; + void (*spi_read)(struct fm_spi_interface *si, unsigned int addr, unsigned int *val); + void (*spi_write)(struct fm_spi_interface *si, unsigned int addr, unsigned int val); + void (*host_read)(struct fm_spi_interface *si, unsigned int addr, unsigned int *val); + void (*host_write)(struct fm_spi_interface *si, unsigned int addr, unsigned int val); + int (*sys_spi_read)(struct fm_spi_interface *si, unsigned int subsystem, + unsigned int addr, unsigned int *data); + int (*sys_spi_write)(struct fm_spi_interface *si, unsigned int subsystem, + unsigned int addr, unsigned int data); + bool (*set_own)(void); + bool (*clr_own)(void); +}; + +struct fm_wcn_reg_ops { + struct fm_ext_interface ei; + struct fm_spi_interface si; + unsigned char rx_buf[FM_BUFFER_SIZE]; + unsigned int rx_len; + struct fm_lock *tx_lock; + struct fm_lock *own_lock; +}; + +struct fm_full_cqi { + unsigned short ch; + unsigned short rssi; + unsigned short pamd; + unsigned short pr; + unsigned short fpamd; + unsigned short mr; + unsigned short atdc; + unsigned short prx; + unsigned short atdev; + unsigned short smg; /* soft-mute gain */ + unsigned short drssi; /* delta rssi */ +}; + +/* FM interface */ +void fw_spi_read(unsigned char addr, unsigned short *data); +void fw_spi_write(unsigned char addr, unsigned short data); +void fw_bop_udelay(unsigned int usec); +void fw_bop_rd_until(unsigned char addr, unsigned short mask, + unsigned short value); +void fw_bop_modify(unsigned char addr, unsigned short mask_and, + unsigned short mask_or); +void fw_bop_spi_rd_until(unsigned char subsys, unsigned short addr, + unsigned int mask, unsigned int value); +void fw_bop_spi_modify(unsigned char subsys, unsigned short addr, + unsigned int mask_and, unsigned int mask_or); + +extern struct fm_wcn_reg_ops fm_wcn_ops; +extern unsigned char *cmd_buf; +extern struct fm_lock *cmd_buf_lock; +extern struct fm_res_ctx *fm_res; + +#endif /* FM_REG_UTILS_H */ diff --git a/drivers/misc/mediatek/connectivity/fmradio/inc/fm_stdlib.h b/drivers/misc/mediatek/connectivity/fmradio/inc/fm_stdlib.h new file mode 100644 index 0000000000000000000000000000000000000000..4922e6f586412195bf5ea37b48346057f4c2bdf2 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/inc/fm_stdlib.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2015 MediaTek Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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. + */ + +#ifndef __FM_STDLIB_H__ +#define __FM_STDLIB_H__ + +#include "fm_typedef.h" +#include +#include + +#if 1 +#define fm_memset(buf, a, len) \ +({ \ + void *__ret = (void *)0; \ + __ret = memset((buf), (a), (len)); \ + __ret; \ +}) + +#define fm_memcpy(dst, src, len) \ +({ \ + void *__ret = (void *)0; \ + __ret = memcpy((dst), (src), (len)); \ + __ret; \ +}) + +#define fm_malloc(len) \ +({ \ + void *__ret = (void *)0; \ + __ret = kmalloc(len, GFP_KERNEL); \ + __ret; \ +}) + +#define fm_zalloc(len) \ +({ \ + void *__ret = (void *)0; \ + __ret = kzalloc(len, GFP_KERNEL); \ + __ret; \ +}) + +#define fm_free(ptr) kfree(ptr) + +#define fm_vmalloc(len) \ +({ \ + void *__ret = (void *)0; \ + __ret = vmalloc(len); \ + __ret; \ +}) + +#define fm_vfree(ptr) vfree(ptr) + +#else +inline void *fm_memset(void *buf, signed char val, signed int len) +{ + return memset(buf, val, len); +} + +inline void *fm_memcpy(void *dst, const void *src, signed int len) +{ + return memcpy(dst, src, len); +} + +#endif + +#endif /* __FM_STDLIB_H__ */ diff --git a/drivers/misc/mediatek/connectivity/fmradio/inc/fm_typedef.h b/drivers/misc/mediatek/connectivity/fmradio/inc/fm_typedef.h new file mode 100644 index 0000000000000000000000000000000000000000..9d9039463a0d05a2778305bfee70cfdde36942fb --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/inc/fm_typedef.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2015 MediaTek Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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. + */ + +#ifndef __FM_TYPEDEF_H__ +#define __FM_TYPEDEF_H__ + + +#endif /* __FM_TYPEDEF_H__ */ diff --git a/drivers/misc/mediatek/connectivity/fmradio/inc/fm_utils.h b/drivers/misc/mediatek/connectivity/fmradio/inc/fm_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..e4d3f2b8c0ea72150a901b99d1b60960ed2dac0a --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/inc/fm_utils.h @@ -0,0 +1,370 @@ +/* + * Copyright (C) 2015 MediaTek Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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. + */ + +#ifndef __FM_UTILS_H__ +#define __FM_UTILS_H__ + +#include + +#if (KERNEL_VERSION(4, 9, 0) <= LINUX_VERSION_CODE) +#include +#include +#else +#include +#endif + +#include "fm_typedef.h" + +/** +* Base structure of fm object +*/ +#define FM_NAME_MAX 20 +struct fm_object { + signed char name[FM_NAME_MAX + 1]; /* name of fm object */ + unsigned char type; /* type of fm object */ + unsigned char flag; /* flag of fm object */ + signed int ref; + void *priv; +}; + +/* + * FM FIFO + */ +struct fm_fifo { + struct fm_object obj; + signed int size; + signed int in; + signed int out; + signed int len; + signed int item_size; + signed int (*input)(struct fm_fifo *thiz, void *item); + signed int (*output)(struct fm_fifo *thiz, void *item); + bool (*is_full)(struct fm_fifo *thiz); + bool (*is_empty)(struct fm_fifo *thiz); + signed int (*get_total_len)(struct fm_fifo *thiz); + signed int (*get_valid_len)(struct fm_fifo *thiz); + signed int (*reset)(struct fm_fifo *thiz); +}; + +extern struct fm_fifo *fm_fifo_init(struct fm_fifo *fifo, void *buf, const signed char *name, + signed int item_size, signed int item_num); + +extern struct fm_fifo *fm_fifo_create(const signed char *name, signed int item_size, signed int item_num); + +extern signed int fm_fifo_release(struct fm_fifo *fifo); + +#define FM_FIFO_INPUT(fifop, item) \ +({ \ + signed int __ret = (signed int)0; \ + if (fifop && (fifop)->input) { \ + __ret = (fifop)->input(fifop, item); \ + } \ + __ret; \ +}) + +#define FM_FIFO_OUTPUT(fifop, item) \ +({ \ + signed int __ret = (signed int)0; \ + if (fifop && (fifop)->output) { \ + __ret = (fifop)->output(fifop, item); \ + } \ + __ret; \ +}) + +#define FM_FIFO_IS_FULL(fifop) \ +({ \ + bool __ret = false; \ + if (fifop && (fifop)->is_full) { \ + __ret = (fifop)->is_full(fifop); \ + } \ + __ret; \ +}) + +#define FM_FIFO_IS_EMPTY(fifop) \ +({ \ + bool __ret = false; \ + if (fifop && (fifop)->is_empty) { \ + __ret = (fifop)->is_empty(fifop); \ + } \ + __ret; \ +}) + +#define FM_FIFO_RESET(fifop) \ +({ \ + signed int __ret = (signed int)0; \ + if (fifop && (fifop)->reset) { \ + __ret = (fifop)->reset(fifop); \ + } \ + __ret; \ +}) + +#define FM_FIFO_GET_TOTAL_LEN(fifop) \ +({ \ + signed int __ret = (signed int)0; \ + if (fifop && (fifop)->get_total_len) { \ + __ret = (fifop)->get_total_len(fifop); \ + } \ + __ret; \ +}) + +#define FM_FIFO_GET_VALID_LEN(fifop) \ +({ \ + signed int __ret = (signed int)0; \ + if (fifop && (fifop)->get_valid_len) { \ + __ret = (fifop)->get_valid_len(fifop); \ + } \ + __ret; \ +}) + +/* + * FM asynchronous information mechanism + */ +struct fm_flag_event { + signed int ref; + signed char name[FM_NAME_MAX + 1]; + void *priv; + + unsigned int flag; + + /* flag methods */ + unsigned int (*send)(struct fm_flag_event *thiz, unsigned int mask); + signed int (*wait)(struct fm_flag_event *thiz, unsigned int mask); + long (*wait_timeout)(struct fm_flag_event *thiz, unsigned int mask, long timeout); + unsigned int (*clr)(struct fm_flag_event *thiz, unsigned int mask); + unsigned int (*get)(struct fm_flag_event *thiz); + unsigned int (*rst)(struct fm_flag_event *thiz); +}; + +extern struct fm_flag_event *fm_flag_event_create(const signed char *name); + +extern signed int fm_flag_event_get(struct fm_flag_event *thiz); + +extern signed int fm_flag_event_put(struct fm_flag_event *thiz); + +#define FM_EVENT_SEND(eventp, mask) \ +({ \ + unsigned int __ret = (unsigned int)0; \ + if (eventp && (eventp)->send) { \ + __ret = (eventp)->send(eventp, mask); \ + } \ + __ret; \ +}) + +#define FM_EVENT_WAIT(eventp, mask) \ +({ \ + signed int __ret = (signed int)0; \ + if (eventp && (eventp)->wait) { \ + __ret = (eventp)->wait(eventp, mask); \ + } \ + __ret; \ +}) + +#define FM_EVENT_WAIT_TIMEOUT(eventp, mask, timeout) \ +({ \ + long __ret = (long)0; \ + if (eventp && (eventp)->wait_timeout) { \ + __ret = (eventp)->wait_timeout(eventp, mask, timeout); \ + } \ + __ret; \ +}) + +#define FM_EVENT_GET(eventp) \ +({ \ + unsigned int __ret = (unsigned int)0; \ + if (eventp && (eventp)->get) { \ + __ret = (eventp)->get(eventp); \ + } \ + __ret; \ +}) + +#define FM_EVENT_RESET(eventp) \ +({ \ + unsigned int __ret = (unsigned int)0; \ + if (eventp && (eventp)->rst) { \ + __ret = (eventp)->rst(eventp); \ + } \ + __ret; \ +}) + +#define FM_EVENT_CLR(eventp, mask) \ +({ \ + unsigned int __ret = (unsigned int)0; \ + if (eventp && (eventp)->clr) { \ + __ret = (eventp)->clr(eventp, mask); \ + } \ + __ret; \ +}) + +/* + * FM wake lock + */ +#if (KERNEL_VERSION(4, 9, 0) <= LINUX_VERSION_CODE) +#define FM_WAKE_LOCK_T struct wakeup_source +#else +#define FM_WAKE_LOCK_T struct wake_lock +#endif + +/* + * FM lock mechanism + */ +struct fm_lock { + signed char name[FM_NAME_MAX + 1]; + signed int ref; + void *priv; + + /* lock methods */ + signed int (*lock)(struct fm_lock *thiz); + signed int (*trylock)(struct fm_lock *thiz, signed int retryCnt); + signed int (*unlock)(struct fm_lock *thiz); +}; + +extern struct fm_lock *fm_lock_create(const signed char *name); + +extern signed int fm_lock_get(struct fm_lock *thiz); + +extern signed int fm_lock_put(struct fm_lock *thiz); + +extern struct fm_lock *fm_spin_lock_create(const signed char *name); + +extern signed int fm_spin_lock_get(struct fm_lock *thiz); + +extern signed int fm_spin_lock_put(struct fm_lock *thiz); + +#define FM_LOCK(a) \ + ({ \ + signed int __ret = (signed int)0; \ + if (!a) { \ + __ret = -1; \ + } else if ((a)->lock) { \ + __ret = (a)->lock(a); \ + } \ + __ret; \ + }) + +#define FM_UNLOCK(a) \ + { \ + if (a && (a)->unlock) { \ + (a)->unlock(a); \ + } \ + } + +/* + * FM timer mechanism + */ +enum fm_timer_ctrl { + FM_TIMER_CTRL_GET_TIME = 0, + FM_TIMER_CTRL_SET_TIME = 1, + FM_TIMER_CTRL_MAX +}; + +#define FM_TIMER_FLAG_ACTIVATED (1<<0) + +struct fm_timer { + signed int ref; + signed char name[FM_NAME_MAX + 1]; + void *priv; /* platform detail impliment */ + + signed int flag; /* timer active/inactive */ +#if KERNEL_VERSION(4, 15, 0) <= LINUX_VERSION_CODE + void (*timeout_func)(struct timer_list *timer); /* timeout function */ +#else + void (*timeout_func)(unsigned long data); /* timeout function */ +#endif + unsigned long data; /* timeout function's parameter */ + signed long timeout_ms; /* timeout tick */ + /* Tx parameters */ + unsigned int count; + unsigned char tx_pwr_ctrl_en; + unsigned char tx_rtc_ctrl_en; + unsigned char tx_desense_en; + + /* timer methods */ +#if KERNEL_VERSION(4, 15, 0) <= LINUX_VERSION_CODE + signed int (*init)(struct fm_timer *thiz, void (*timeout) (struct timer_list *timer), + unsigned long data, signed long time, signed int flag); +#else + signed int (*init)(struct fm_timer *thiz, void (*timeout) (unsigned long data), + unsigned long data, signed long time, signed int flag); +#endif + signed int (*start)(struct fm_timer *thiz); + signed int (*update)(struct fm_timer *thiz); + signed int (*stop)(struct fm_timer *thiz); + signed int (*control)(struct fm_timer *thiz, enum fm_timer_ctrl cmd, void *arg); +}; + +extern struct fm_timer *fm_timer_create(const signed char *name); + +extern signed int fm_timer_get(struct fm_timer *thiz); + +extern signed int fm_timer_put(struct fm_timer *thiz); + +/* + * FM work thread mechanism + */ +struct fm_work { + signed int ref; + signed char name[FM_NAME_MAX + 1]; + void *priv; + + work_func_t work_func; + unsigned long data; + /* work methods */ + signed int (*init)(struct fm_work *thiz, work_func_t work_func, unsigned long data); +}; + +extern struct fm_work *fm_work_create(const signed char *name); + +extern signed int fm_work_get(struct fm_work *thiz); + +extern signed int fm_work_put(struct fm_work *thiz); + +struct fm_workthread { + signed int ref; + signed char name[FM_NAME_MAX + 1]; + void *priv; + + /* workthread methods */ + signed int (*add_work)(struct fm_workthread *thiz, struct fm_work *work); +}; + +extern struct fm_workthread *fm_workthread_create(const signed char *name); + +extern signed int fm_workthread_get(struct fm_workthread *thiz); + +extern signed int fm_workthread_put(struct fm_workthread *thiz); + +/* + * FM wake lock mechanism + */ + +extern FM_WAKE_LOCK_T *fm_wakelock_create(const signed char *name); + +extern void fm_wakelock_destroy(FM_WAKE_LOCK_T *lock); + +extern void fm_wakelock_get(FM_WAKE_LOCK_T *lock); + +extern void fm_wakelock_put(FM_WAKE_LOCK_T *lock); + +signed int fm_delayms(unsigned int data); + +signed int fm_delayus(unsigned int data); + +unsigned short fm_get_u16_from_auc(unsigned char *buf); + +void fm_set_u16_to_auc(unsigned char *buf, unsigned short val); + +unsigned int fm_get_u32_from_auc(unsigned char *buf); + +void fm_set_u32_to_auc(unsigned char *buf, unsigned int val); + +#endif /* __FM_UTILS_H__ */ diff --git a/drivers/misc/mediatek/connectivity/fmradio/init.fmradio_drv.rc b/drivers/misc/mediatek/connectivity/fmradio/init.fmradio_drv.rc new file mode 100644 index 0000000000000000000000000000000000000000..d1111d0c41c48f3e4a83dcead7e54fc4eabfd7e2 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/init.fmradio_drv.rc @@ -0,0 +1,5 @@ + +# load fmradio_drv +on property:vendor.connsys.driver.ready=yes + insmod /vendor/lib/modules/fmradio_drv.ko + diff --git a/drivers/misc/mediatek/connectivity/fmradio/plat/conn_infra.c b/drivers/misc/mediatek/connectivity/fmradio/plat/conn_infra.c new file mode 100644 index 0000000000000000000000000000000000000000..9850f0272581630ba9d904eb52fe2f11cae0803c --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/plat/conn_infra.c @@ -0,0 +1,1505 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +#include "plat.h" + +/* CONNSYS register address */ +#if CFG_FM_CONNAC2 +#define AP_BASE_ADDRESS 0x18000000 +#define MCU_CFG_ADDR (AP_BASE_ADDRESS + 0x0) +#define MCU_CFG_CONSYS_BASE MCU_CFG_ADDR +#define MCU_CFG_SIZE 0x10000 +#define TOP_MISC_OFF_ADDR (AP_BASE_ADDRESS + 0x60000) +#define TOP_MISC_OFF_CONSYS_BASE TOP_MISC_OFF_ADDR +#define TOP_MISC_OFF_SIZE 0x1000 +#define TOP_RF_SPI_AON_ADDR (AP_BASE_ADDRESS + 0x4000) +#define TOP_RF_SPI_AON_CONSYS_BASE TOP_RF_SPI_AON_ADDR +#define TOP_RF_SPI_AON_SIZE 0x1000 +#else +#define AP_BASE_ADDRESS 0x18000000 +#define MCU_CFG_ADDR (AP_BASE_ADDRESS + 0x02000) +#define MCU_CFG_CONSYS_BASE 0x80000000 +#define MCU_CFG_SIZE 0x1000 +#define TOP_MISC_OFF_ADDR (AP_BASE_ADDRESS + 0xB0000) +#define TOP_MISC_OFF_CONSYS_BASE 0x80020000 +#define TOP_MISC_OFF_SIZE 0x10000 +#define TOP_RF_SPI_AON_ADDR (AP_BASE_ADDRESS + 0xC0000) +#define TOP_RF_SPI_AON_CONSYS_BASE 0x81020000 +#define TOP_RF_SPI_AON_SIZE 0x10000 +#endif /* CFG_FM_CONNAC2 */ + +#define FM_IRQ_NUMBER 0 +#define MAX_SET_OWN_COUNT 1000 + +#if CFG_FM_CONNAC2 +static int (*whole_chip_reset)(signed int sta); + +static int fm_pre_whole_chip_rst(enum consys_drv_type drv, char *reason) +{ + WCN_DBG(FM_WAR | LINK, "FM pre whole chip rst!\n"); + if (whole_chip_reset) + whole_chip_reset(1); + return 0; +} + +static int fm_post_whole_chip_rst(void) +{ + WCN_DBG(FM_WAR | LINK, "FM post whole chip rst!\n"); + if (whole_chip_reset) + whole_chip_reset(0); + return 0; +} + +static struct sub_drv_ops_cb fm_drv_cbs = { + .rst_cb.pre_whole_chip_rst = fm_pre_whole_chip_rst, + .rst_cb.post_whole_chip_rst = fm_post_whole_chip_rst, + .pre_cal_cb.pwr_on_cb = NULL, + .pre_cal_cb.do_cal_cb = NULL, +}; + +static int drv_sys_spi_read( + struct fm_spi_interface *si, unsigned int subsystem, + unsigned int addr, unsigned int *data) +{ + WCN_DBG(FM_DBG | CHIP, "[0x%08x]=[0x%08x]\n", addr, *data); + return conninfra_spi_read(subsystem, addr, data); +} + +static int drv_sys_spi_write( + struct fm_spi_interface *si, unsigned int subsystem, + unsigned int addr, unsigned int data) +{ + WCN_DBG(FM_DBG | CHIP, "[0x%08x]=[0x%08x]\n", addr, data); + return conninfra_spi_write(subsystem, addr, data); +} +#else /* CFG_FM_CONNAC2 */ +static int sys_spi_wait(unsigned int spi_busy) +{ + struct fm_spi_interface *si = &fm_wcn_ops.si; + unsigned int spi_count, rdata; + + /* It needs to prevent infinite loop */ + for (spi_count = 0; spi_count < FM_SPI_COUNT_LIMIT; spi_count++) { + si->spi_read(si, SYS_SPI_STA, &rdata); + if ((rdata & spi_busy) == 0) + break; + } + if (spi_count == FM_SPI_COUNT_LIMIT) { + WCN_DBG(FM_WAR | CHIP, + "SPI busy[0x%08x], retry count reached maximum.\n", + rdata); + return FM_SYS_SPI_BUSY; + } + return FM_SYS_SPI_OK; +} + +static int fm_sys_spi_read( + struct fm_spi_interface *si, unsigned int subsystem, + unsigned int addr, unsigned int *data) +{ + unsigned int spi_busy, spi_addr, spi_mask, spi_wdat, spi_rdat, rdata; + + if (!si->spi_read || !si->spi_write) { + WCN_DBG(FM_ERR | CHIP, "spi api is NULL.\n"); + return FM_SYS_SPI_ERR; + } + + switch (subsystem) { + case SYS_SPI_WF: + spi_busy = 1 << SYS_SPI_STA_WF_BUSY_SHFT; + spi_addr = SYS_SPI_WF_ADDR_ADDR; + spi_mask = SYS_SPI_WF_RDAT_MASK; + spi_wdat = SYS_SPI_WF_WDAT_ADDR; + spi_rdat = SYS_SPI_WF_RDAT_ADDR; + addr = SYS_SPI_ADDR_CR_READ | SYS_SPI_ADDR_CR_WF | (addr & SYS_SPI_ADDR_CR_MASK); + break; + case SYS_SPI_BT: + spi_busy = 1 << SYS_SPI_STA_BT_BUSY_SHFT; + spi_addr = SYS_SPI_BT_ADDR_ADDR; + spi_mask = SYS_SPI_BT_RDAT_MASK; + spi_wdat = SYS_SPI_BT_WDAT_ADDR; + spi_rdat = SYS_SPI_BT_RDAT_ADDR; + addr = SYS_SPI_ADDR_CR_READ | SYS_SPI_ADDR_CR_BT | (addr & SYS_SPI_ADDR_CR_MASK); + break; + case SYS_SPI_FM: + spi_busy = 1 << SYS_SPI_STA_FM_BUSY_SHFT; + spi_addr = SYS_SPI_FM_ADDR_ADDR; + spi_mask = SYS_SPI_FM_RDAT_MASK; + spi_wdat = SYS_SPI_FM_WDAT_ADDR; + spi_rdat = SYS_SPI_FM_RDAT_ADDR; + addr = SYS_SPI_ADDR_CR_READ | SYS_SPI_ADDR_CR_FM | (addr & SYS_SPI_ADDR_CR_MASK); + break; + case SYS_SPI_GPS: + spi_busy = 1 << SYS_SPI_STA_GPS_BUSY_SHFT; + spi_addr = SYS_SPI_GPS_ADDR_ADDR; + spi_mask = SYS_SPI_GPS_RDAT_MASK; + spi_wdat = SYS_SPI_GPS_WDAT_ADDR; + spi_rdat = SYS_SPI_GPS_RDAT_ADDR; + addr = SYS_SPI_ADDR_CR_READ | SYS_SPI_ADDR_CR_GPS | (addr & SYS_SPI_ADDR_CR_MASK); + break; + case SYS_SPI_TOP: + spi_busy = 1 << SYS_SPI_STA_TOP_BUSY_SHFT; + spi_addr = SYS_SPI_TOP_ADDR_ADDR; + spi_mask = SYS_SPI_TOP_RDAT_MASK; + spi_wdat = SYS_SPI_TOP_WDAT_ADDR; + spi_rdat = SYS_SPI_TOP_RDAT_ADDR; + addr = SYS_SPI_ADDR_CR_READ | SYS_SPI_ADDR_CR_TOP | (addr & SYS_SPI_ADDR_CR_MASK); + break; + case SYS_SPI_WF1: + spi_busy = 1 << SYS_SPI_STA_WF_BUSY_SHFT; + spi_addr = SYS_SPI_WF_ADDR_ADDR; + spi_mask = SYS_SPI_WF_RDAT_MASK; + spi_wdat = SYS_SPI_WF_WDAT_ADDR; + spi_rdat = SYS_SPI_WF_RDAT_ADDR; + addr = SYS_SPI_ADDR_CR_READ | SYS_SPI_ADDR_CR_WF1 | (addr & SYS_SPI_ADDR_CR_MASK); + break; + default: + return FM_SYS_SPI_ERR; + } + + if (sys_spi_wait(spi_busy) == FM_SYS_SPI_BUSY) + return FM_SYS_SPI_BUSY; + + si->spi_write(si, spi_addr, addr); + si->spi_write(si, spi_wdat, 0); + + sys_spi_wait(spi_busy); + + si->spi_read(si, spi_rdat, &rdata); + *data = rdata & spi_mask; + + WCN_DBG(FM_DBG | CHIP, "[0x%08x]=[0x%08x]\n", addr, *data); + + return FM_SYS_SPI_OK; +} + +static int fm_sys_spi_write( + struct fm_spi_interface *si, unsigned int subsystem, + unsigned int addr, unsigned int data) +{ + unsigned int spi_busy, spi_addr, spi_mask, spi_wdat; + + if (!si->spi_read || !si->spi_write) { + WCN_DBG(FM_ERR | CHIP, "spi api is NULL.\n"); + return FM_SYS_SPI_ERR; + } + + switch (subsystem) { + case SYS_SPI_WF: + spi_busy = 1 << SYS_SPI_STA_WF_BUSY_SHFT; + spi_addr = SYS_SPI_WF_ADDR_ADDR; + spi_mask = SYS_SPI_WF_WDAT_MASK; + spi_wdat = SYS_SPI_WF_WDAT_ADDR; + addr = SYS_SPI_ADDR_CR_WRITE | SYS_SPI_ADDR_CR_WF | (addr & SYS_SPI_ADDR_CR_MASK); + break; + case SYS_SPI_BT: + spi_busy = 1 << SYS_SPI_STA_BT_BUSY_SHFT; + spi_addr = SYS_SPI_BT_ADDR_ADDR; + spi_mask = SYS_SPI_BT_WDAT_MASK; + spi_wdat = SYS_SPI_BT_WDAT_ADDR; + addr = SYS_SPI_ADDR_CR_WRITE | SYS_SPI_ADDR_CR_BT | (addr & SYS_SPI_ADDR_CR_MASK); + break; + case SYS_SPI_FM: + spi_busy = 1 << SYS_SPI_STA_FM_BUSY_SHFT; + spi_addr = SYS_SPI_FM_ADDR_ADDR; + spi_mask = SYS_SPI_FM_WDAT_MASK; + spi_wdat = SYS_SPI_FM_WDAT_ADDR; + addr = SYS_SPI_ADDR_CR_WRITE | SYS_SPI_ADDR_CR_FM | (addr & SYS_SPI_ADDR_CR_MASK); + break; + case SYS_SPI_TOP: + spi_busy = 1 << SYS_SPI_STA_TOP_BUSY_SHFT; + spi_addr = SYS_SPI_TOP_ADDR_ADDR; + spi_mask = SYS_SPI_TOP_WDAT_MASK; + spi_wdat = SYS_SPI_TOP_WDAT_ADDR; + addr = SYS_SPI_ADDR_CR_WRITE | SYS_SPI_ADDR_CR_TOP | (addr & SYS_SPI_ADDR_CR_MASK); + break; + case SYS_SPI_WF1: + spi_busy = 1 << SYS_SPI_STA_WF_BUSY_SHFT; + spi_addr = SYS_SPI_WF_ADDR_ADDR; + spi_mask = SYS_SPI_WF_WDAT_MASK; + spi_wdat = SYS_SPI_WF_WDAT_ADDR; + addr = SYS_SPI_ADDR_CR_WRITE | SYS_SPI_ADDR_CR_WF1 | (addr & SYS_SPI_ADDR_CR_MASK); + break; + default: + return FM_SYS_SPI_ERR; + } + + if (sys_spi_wait(spi_busy) == FM_SYS_SPI_BUSY) + return FM_SYS_SPI_BUSY; + + si->spi_write(si, spi_addr, addr); + si->spi_write(si, spi_wdat, (data & spi_mask)); + + sys_spi_wait(spi_busy); + + WCN_DBG(FM_DBG | CHIP, "[0x%08x]=[0x%08x]\n", addr, data); + + return FM_SYS_SPI_OK; +} +#endif /* CFG_FM_CONNAC2 */ + +static void drv_spi_read( + struct fm_spi_interface *si, unsigned int addr, unsigned int *val) +{ + *val = readl(si->info.spi_vir_addr + addr); +} + +static void drv_spi_write( + struct fm_spi_interface *si, unsigned int addr, unsigned int val) +{ + writel(val, si->info.spi_vir_addr + addr); +} + +static void drv_top_read( + struct fm_spi_interface *si, unsigned int addr, unsigned int *val) +{ + *val = readl(si->info.top_vir_addr + addr); +} + +static void drv_top_write( + struct fm_spi_interface *si, unsigned int addr, unsigned int val) +{ + writel(val, si->info.top_vir_addr + addr); +} + +static void drv_mcu_read( + struct fm_spi_interface *si, unsigned int addr, unsigned int *val) +{ + *val = readl(si->info.mcu_vir_addr + addr); +} + +static void drv_mcu_write( + struct fm_spi_interface *si, unsigned int addr, unsigned int val) +{ + writel(val, si->info.mcu_vir_addr + addr); +} + +static void drv_host_read( + struct fm_spi_interface *si, unsigned int addr, unsigned int *data) +{ + unsigned new_addr = addr; + + if (addr >= TOP_RF_SPI_AON_CONSYS_BASE && + addr <= TOP_RF_SPI_AON_CONSYS_BASE + TOP_RF_SPI_AON_SIZE) { + new_addr = addr - TOP_RF_SPI_AON_CONSYS_BASE; + drv_spi_read(si, new_addr, data); + } else if (addr >= MCU_CFG_CONSYS_BASE && + addr <= MCU_CFG_CONSYS_BASE + MCU_CFG_SIZE) { + new_addr = addr - MCU_CFG_CONSYS_BASE; + drv_mcu_read(si, new_addr, data); + } else if (addr >= TOP_MISC_OFF_CONSYS_BASE && + addr <= TOP_MISC_OFF_CONSYS_BASE + TOP_MISC_OFF_SIZE) { + new_addr = addr - TOP_MISC_OFF_CONSYS_BASE; + drv_top_read(si, new_addr, data); + } else { + WCN_DBG(FM_WAR | CHIP, "not support addr[0x%08x].\n", addr); + return; + } + + WCN_DBG(FM_DBG | CHIP, "read [0x%08x]=[0x%08x]\n", + new_addr, addr, *data); +} + +static void drv_host_write( + struct fm_spi_interface *si, unsigned int addr, unsigned int data) +{ + unsigned new_addr = addr; + + if (addr >= TOP_RF_SPI_AON_CONSYS_BASE && + addr <= TOP_RF_SPI_AON_CONSYS_BASE + TOP_RF_SPI_AON_SIZE) { + new_addr = addr - TOP_RF_SPI_AON_CONSYS_BASE; + drv_spi_write(si, new_addr, data); + } else if (addr >= MCU_CFG_CONSYS_BASE && + addr <= MCU_CFG_CONSYS_BASE + MCU_CFG_SIZE) { + new_addr = addr - MCU_CFG_CONSYS_BASE; + drv_mcu_write(si, new_addr, data); + } else if (addr >= TOP_MISC_OFF_CONSYS_BASE && + addr <= TOP_MISC_OFF_CONSYS_BASE + TOP_MISC_OFF_SIZE) { + new_addr = addr - TOP_MISC_OFF_CONSYS_BASE; + drv_top_write(si, new_addr, data); + } else { + WCN_DBG(FM_WAR | CHIP, "not support addr[0x%08x].\n", addr); + return; + } + + WCN_DBG(FM_DBG | CHIP, "write [0x%08x/0x%08x]=[0x%08x]\n", + new_addr, addr, data); +} + +/** + * Send TX data via STP format + * + * @param None + * + * @return None + */ +static void fm_tx(unsigned char *buf, unsigned short length) +{ + if (FM_LOCK(fm_wcn_ops.tx_lock)) + return; + + if (length == 0xFFFF) { + length = (unsigned short)buf[2] + + (unsigned short)(buf[3] << 8) + FM_HDR_SIZE; + } + + memset(fm_wcn_ops.rx_buf, 0, RX_BUF_SIZE); + memcpy(fm_wcn_ops.rx_buf, buf, length); + fm_wcn_ops.rx_len = length; + fm_event_parser(fm_rds_parser); + + FM_UNLOCK(fm_wcn_ops.tx_lock); +} + +static void fm_stc_done_rechandler(void) +{ + unsigned short i, reg_value, freq, isr_value; + + fw_spi_read(FM_MAIN_CTRL, &isr_value); + + WCN_DBG(FM_NTC | CHIP, "isr_value[%04x]\n", isr_value); + + if (isr_value & FM_MAIN_CTRL_SEEK) { + unsigned char data[6]; + + fw_spi_read(FM_MAIN_CHANDETSTAT, ®_value); + + /* freq's unit is 10kHz */ + freq = ((((reg_value & 0x3ff0) >> 4) >> 1) + 640) * 10; + + data[0] = FM_TASK_EVENT_PKT_TYPE; + data[1] = FM_SEEK_OPCODE; + /* payload length */ + data[2] = 2; + data[3] = 0x00; + data[4] = (unsigned char)freq & 0xFF; + data[5] = (unsigned char)(freq >> 8); + + fm_tx(data, 0xFFFF); + } else if (isr_value & FM_MAIN_CTRL_SCAN) { + unsigned char data[36]; + + for (i = 0; i <= SCAN_BUFF_LEN; i++) { + fw_spi_read(RDS_DATA_REG, ®_value); + data[4 + (i * 2)] = reg_value & 0xff; + data[4 + (i * 2) + 1] = (reg_value & 0xff00) >> 8; + } + + data[0] = FM_TASK_EVENT_PKT_TYPE; + data[1] = FM_SCAN_OPCODE; + /* payload length */ + data[2] = 32; + data[3] = 0x00; + + fm_tx(data, 0xFFFF); + } else if (isr_value & FM_MAIN_CTRL_TUNE) { + unsigned char data[5]; + + data[0] = FM_TASK_EVENT_PKT_TYPE; + data[1] = FM_TUNE_OPCODE; + /* payload length */ + data[2] = 0x01; + data[3] = 0x00; + data[4] = 0x01; + fm_tx(data, 0x0005); + } +} + +static void fm_rds_rechandler(void) +{ + unsigned short fifo_cnt, reg_value, rds_data[6], reg_sin, reg_cos; + unsigned short crc = 0, corr_cnt = 0, rds_info; + unsigned short output_point, temp_data; + unsigned short i = 0; + unsigned char data[128]; + + do { + fw_spi_read(RDS_FIFO_STATUS0, &fifo_cnt); + fifo_cnt = (fifo_cnt & RDS_DCO_FIFO_OFST) >> + RDS_DCO_FIFO_OFST_SHFT; + + /* block A data and info handling */ + fw_spi_read(RDS_INFO_REG, &rds_info); + crc |= (rds_info & RDS_CRC_INFO) << 3; + corr_cnt |= ((rds_info & RDS_CRC_CORR_CNT) << 11); + fw_spi_read(RDS_DATA_REG, &(rds_data[0])); + + /* block B data and info handling */ + fw_spi_read(RDS_INFO_REG, &rds_info); + crc |= (rds_info & RDS_CRC_INFO) << 2; + corr_cnt |= ((rds_info & RDS_CRC_CORR_CNT) << 7); + fw_spi_read(RDS_DATA_REG, &(rds_data[1])); + + /* block C data and info handling */ + fw_spi_read(RDS_INFO_REG, &rds_info); + crc |= (rds_info & RDS_CRC_INFO) << 1; + corr_cnt |= ((rds_info & RDS_CRC_CORR_CNT) << 3); + fw_spi_read(RDS_DATA_REG, &(rds_data[2])); + + /* block D data and info handling */ + fw_spi_read(RDS_INFO_REG, &rds_info); + crc |= (rds_info & RDS_CRC_INFO); + corr_cnt |= ((rds_info & RDS_CRC_CORR_CNT) >> 1); + fw_spi_read(RDS_DATA_REG, &(rds_data[3])); + + + rds_data[4] = corr_cnt; + rds_data[5] = crc; + + /* -1 due to H/W behavior */ + if (fifo_cnt > 0) + fifo_cnt--; + + /* RDS recovery start */ + /* check if reading doesn't start at block A */ + fw_spi_read(RDS_POINTER, &output_point); + while (output_point & 0x3) { + fw_spi_read(RDS_DATA_REG, &temp_data); + fw_spi_read(RDS_POINTER, &output_point); + } + /* RDS recovery end */ + + fm_set_u16_to_auc(&(data[8 + 12 * i]), rds_data[0]); + fm_set_u16_to_auc(&(data[10 + 12 * i]), rds_data[1]); + fm_set_u16_to_auc(&(data[12 + 12 * i]), rds_data[2]); + fm_set_u16_to_auc(&(data[14 + 12 * i]), rds_data[3]); + fm_set_u16_to_auc(&(data[16 + 12 * i]), rds_data[4]); + fm_set_u16_to_auc(&(data[18 + 12 * i]), rds_data[5]); + + i++; + } while ((i < 10) && ((fifo_cnt & 0x1F) > 0)); + + if (i > 0) { + fw_spi_read(RDS_SIN_REG, ®_sin); + fw_spi_read(RDS_COS_REG, ®_cos); + + data[0] = FM_TASK_EVENT_PKT_TYPE; + data[1] = RDS_RX_DATA_OPCODE; + /* payload length */ + data[2] = (unsigned char)(12 * i + 4); + data[3] = 0x00; + fm_set_u16_to_auc(&(data[4]), reg_sin); + fm_set_u16_to_auc(&(data[6]), reg_cos); + fm_tx(data, 0xFFFF); + } + + fw_spi_read(FM_MAIN_EXTINTRMASK, ®_value); + reg_value |= (FM_INTR_RDS << 8); + fw_spi_write(FM_MAIN_EXTINTRMASK, reg_value); +} + +static void fm_fifo_rechandler(unsigned short intr) +{ + unsigned short reg_value; + + /* Handle channel info. data in FIFO if RDS interrupt + * and CQI interrupt arise simultaneously + */ + if ((intr & 0x0001) && (intr & 0x0020)) { + unsigned short i; + unsigned char data[100]; + + for (i = 0; i < FIFO_LEN; i++) { + fw_spi_read(RDS_DATA_REG, ®_value); + data[4 + (i * 2)] = reg_value & 0xff; + data[4 + (i * 2) + 1] = (reg_value & 0xff00) >> 8; + } + + data[0] = FM_TASK_EVENT_PKT_TYPE; + data[1] = FM_SCAN_OPCODE; + /* payload length */ + data[2] = (unsigned char)(FIFO_LEN<<1); + data[3] = 0x00; + + fm_tx(data, 0xFFFF); + } + /* Handle RDS data in FIFO, while only RDS interrupt issues */ + else if (intr & 0x0020) { + + fw_spi_read(FM_MAIN_EXTINTRMASK, ®_value); + reg_value &= ~(FM_INTR_RDS << 8); + fw_spi_write(FM_MAIN_EXTINTRMASK, reg_value); + + fm_rds_rechandler(); + } + +} + +static void fm_softmute_tune(unsigned short freq, unsigned char *pos) +{ + unsigned short rdata; + unsigned int i = 0, PRX = 0, ATEDV = 0, PR = 0; + int RSSI = 0, PAMD = 0, FPAMD = 0, MR = 0, ATDC = 0; + struct fm_full_cqi *p_cqi = (struct fm_full_cqi *)pos; + + p_cqi->ch = freq; + + /* soft mute tune */ + fw_bop_modify(FM_MAIN_CG2_CTRL, 0xBFFF, 0x4000); + /* disable interrupt */ + fw_spi_write(FM_MAIN_INTRMASK, 0x0000); + fw_spi_write(FM_MAIN_EXTINTRMASK, 0x0000); + /* ramp down */ + fw_bop_modify(FM_MAIN_CTRL, 0xFFF0, 0x0000); + /* Set DSP ramp down state */ + fw_bop_modify(FM_MAIN_CTRL, 0xFFFF, 0x0100); + + fw_bop_rd_until(FM_MAIN_INTR, 0x0001, 0x0001); + + fw_bop_modify(FM_MAIN_CTRL, 0xFEFF, 0x0000); + fw_bop_modify(FM_MAIN_INTR, 0xFFFF, 0x0001); + + /* tune */ + freq = freq / 5 - 1280; + fw_bop_modify(0x65, 0xFC00, freq); + fw_bop_modify(FM_MAIN_CTRL, 0xFFFF, 0x0001); + fw_bop_rd_until(FM_MAIN_INTR, 0x0001, 0x0001); + fw_bop_modify(FM_MAIN_INTR, 0xFFFF, 0x0001); + + /* get CQI */ + fw_bop_udelay(9000); + for (i = 0; i < 8; i++) { + /* RSSI */ + fw_spi_read(0x6C, &rdata); + RSSI += ((rdata & 0x3FF) >= 512) ? + ((rdata & 0x3FF) - 1024) : (rdata & 0x3FF); + + /* PAMD */ + fw_spi_read(0xB4, &rdata); + PAMD += ((rdata & 0x1FF) >= 256) ? + ((rdata & 0x1FF) - 512) : (rdata & 0x1FF); + + /* PR */ + fw_spi_read(0xB5, &rdata); + PR += (rdata & 0x3FF); + + /* FPAMD */ + fw_spi_read(0xBC, &rdata); + FPAMD += ((rdata & 0xFFF) >= 2048) ? + ((rdata & 0xFFF) - 4096) : (rdata & 0xFFF); + + /* MR */ + fw_spi_read(0xBD, &rdata); + MR += ((rdata & 0x1FF) >= 256) ? + ((rdata & 0x1FF) - 512) : (rdata & 0x1FF); + + /* ATDC */ + fw_spi_read(0x83, &rdata); + ATDC += (rdata >= 32768) ? (65536 - rdata) : rdata; + + /* PRX */ + fw_spi_read(0x84, &rdata); + PRX += rdata & 0xFF; + + /* ATDEV */ + fw_spi_read(0x85, &rdata); + ATEDV += rdata; + + fw_bop_udelay(2250); + } + + RSSI = (RSSI + 4) / 8; + p_cqi->rssi = RSSI & 0x03FF; + PAMD = (PAMD + 4) / 8; + p_cqi->pamd = PAMD & 0x01FF; + PR = (PR + 4) / 8; + p_cqi->pr = PR & 0x03FF; + FPAMD = (FPAMD + 4) / 8; + p_cqi->fpamd = FPAMD & 0x0FFF; + MR = (MR + 4) / 8; + p_cqi->mr = MR & 0x01FF; + ATDC = (ATDC + 4) / 8; + p_cqi->atdc = ATDC & 0xFFFF; + PRX = (PRX + 4) / 8; + p_cqi->prx = PRX & 0x00FF; + ATEDV = (ATEDV + 4) / 8; + p_cqi->atdev = ATEDV & 0xFFFF; + + /* Soft_mute Gain */ + fw_spi_read(0x86, &rdata); + p_cqi->smg = rdata; + + /* delta RSSI */ + fw_spi_read(0x88, &rdata); + p_cqi->drssi = rdata; + + /* clear soft mute tune */ + fw_bop_modify(FM_MAIN_CG2_CTRL, 0xBFFF, 0x0000); + + WCN_DBG(FM_NTC | CHIP, + "freq %d, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x\n", + p_cqi->ch, p_cqi->rssi, p_cqi->pamd, + p_cqi->pr, p_cqi->fpamd, p_cqi->mr, + p_cqi->atdc, p_cqi->prx, p_cqi->atdev, + p_cqi->smg, p_cqi->drssi); +} + +static void fm_dsp_download( + unsigned char target, unsigned short length, + unsigned char total_seg, unsigned char current_seg, + unsigned char *data) +{ + unsigned int control_code = 0; + unsigned short i; + + switch (target) { + case DSP_ROM: + case DSP_PATCH: + control_code = 0x10; + break; + case DSP_COEFF: + control_code = 0xe; + break; + case DSP_HWCOEFF: + control_code = 0xd; + break; + default: + break; + } + + if (current_seg == 0) { + fw_spi_write(CONTROL_REG, 0); + /* Start address */ + fw_spi_write(OFFSET_REG, data[1] << 8 | data[0]); + /* Reset download control */ + fw_spi_write(CONTROL_REG, 0x40); + /* Set download control */ + fw_spi_write(CONTROL_REG, control_code); + data += 4; + length -= 4; + } + + if (length > 0) { + for (i = 0; i < (length >> 1); i++) + fw_spi_write(DATA_REG, data[2 * i + 1] << 8 | data[2 * i]); + } else { + WCN_DBG(FM_ERR | CHIP, "incorrect length[%d].\n", length); + } +} + +static void fm_task_rx_basic_op( + unsigned char bop, unsigned char length, unsigned char *buf) +{ + struct fm_spi_interface *si = &fm_wcn_ops.si; + + switch (bop) { + case FM_WRITE_BASIC_OP: + fw_spi_write(buf[0], fm_get_u16_from_auc(&buf[1])); + break; + + case FM_UDELAY_BASIC_OP: + fw_bop_udelay(fm_get_u32_from_auc(&buf[0])); + break; + + case FM_RD_UNTIL_BASIC_OP: + fw_bop_rd_until(buf[0], fm_get_u16_from_auc(&buf[1]), + fm_get_u16_from_auc(&buf[3])); + break; + + case FM_MODIFY_BASIC_OP: + fw_bop_modify(buf[0], fm_get_u16_from_auc(&buf[1]), + fm_get_u16_from_auc(&buf[3])); + break; + + case FM_MSLEEP_BASIC_OP: + fm_delayms(fm_get_u32_from_auc(&buf[0])); + break; + + case FM_WRITE_SPI_BASIC_OP: + si->sys_spi_write(si, buf[0], fm_get_u16_from_auc(&buf[1]), + fm_get_u32_from_auc(&buf[3])); + break; + case FM_RD_SPI_UNTIL_BASIC_OP: + fw_bop_spi_rd_until(buf[0], fm_get_u16_from_auc(&buf[1]), + fm_get_u32_from_auc(&buf[3]), + fm_get_u32_from_auc(&buf[7])); + break; + case FM_MODIFY_SPI_BASIC_OP: + fw_bop_spi_modify(buf[0], fm_get_u16_from_auc(&buf[1]), + fm_get_u32_from_auc(&buf[3]), + fm_get_u32_from_auc(&buf[7])); + break; + + default: + break; + } +} + +/** + * FM task rx dispatcher default functions for basic operation processing + * + * @param opcode opcode for different packet type + * @param length the length of parameters + * @param buf the parameters for different packet type + * + * @return None + */ +static void fm_task_rx_dispatcher_default( + unsigned char opcode, unsigned short length, unsigned char *buf) +{ + int unused_op_size = length; + unsigned short used_op_size = 0; + + while (unused_op_size > 0) { + unsigned char basic_op = buf[used_op_size]; + unsigned char basic_op_length = buf[used_op_size + 1]; + unsigned char *basic_op_buf = &buf[used_op_size + 2]; + + fm_task_rx_basic_op(basic_op, basic_op_length, + basic_op_buf); + unused_op_size -= (int)(basic_op_length + 2); + used_op_size += (unsigned short)(basic_op_length + 2); + } +} + +/** + * FM task rx dispatcher functions for different packet type + * + * @param opcode opcode for different packet type + * @param length the length of parameters + * @param buf the parameters for different packet type + * + * @return None + */ +static void fm_task_rx_dispatcher( + unsigned char opcode, unsigned short length, unsigned char *buf) +{ + unsigned char event[28]; + + /* Prepare FM event packet, default no payload */ + event[0] = FM_TASK_EVENT_PKT_TYPE; + event[1] = opcode; + event[2] = 0x0; + event[3] = 0x0; + + switch (opcode) { + case FM_STP_TEST_OPCODE: + event[2] = 0x3; + event[3] = 0x0; + event[4] = 0x0; + event[5] = 0x1; + event[6] = 0x2; + break; + case FSPI_ENABLE_OPCODE: + break; + case FSPI_MUX_SEL_OPCODE: + break; + case FSPI_READ_OPCODE: + { + unsigned short data; + + fw_spi_read(buf[0], &data); + event[2] = 0x2; + event[3] = 0x0; + fm_set_u16_to_auc(&event[4], data); + break; + } + case FSPI_WRITE_OPCODE: + fw_spi_write(buf[0], fm_get_u16_from_auc(&buf[1])); + break; + + case FM_PATCH_DOWNLOAD_OPCODE: + fm_dsp_download(DSP_PATCH, length - 2, buf[0], buf[1], &buf[2]); + break; + + case FM_COEFF_DOWNLOAD_OPCODE: + fm_dsp_download(DSP_COEFF, length - 2, buf[0], buf[1], &buf[2]); + break; + + case FM_HWCOEFF_DOWNLOAD_OPCODE: + fm_dsp_download(DSP_HWCOEFF, length - 2, buf[0], buf[1], &buf[2]); + break; + + case FM_ROM_DOWNLOAD_OPCODE: + fm_dsp_download(DSP_ROM, length - 2, buf[0], buf[1], &buf[2]); + break; + case FM_SOFT_MUTE_TUNE_OPCODE: + { + switch (buf[0]) { + case 1: + { + unsigned short freq = 0; + + fm_set_u16_to_auc(&event[2], + (FM_SOFTMUTE_TUNE_CQI_SIZE + 2)); + event[4] = FM_SOFTMUTE_TUNE_CQI_SIZE; + event[5] = 0x01; + freq = fm_get_u16_from_auc(&buf[1]); + fm_softmute_tune(freq, &event[6]); + break; + } + case 2: + case 3: + case 4: + default: + { + event[2] = 0x00; + event[3] = 0x00; + memcpy(&event[2], buf, 3); + break; + } + } + break; + } + case FM_HOST_READ_OPCODE: + { + struct fm_spi_interface *si = &fm_wcn_ops.si; + unsigned int addr, data; + + addr = fm_get_u32_from_auc(&buf[0]); + si->host_read(si, addr, &data); + event[2] = 0x4; + event[3] = 0x0; + fm_set_u32_to_auc(&event[4], data); + } + break; + case FM_HOST_WRITE_OPCODE: + { + struct fm_spi_interface *si = &fm_wcn_ops.si; + unsigned int addr, data; + + addr = fm_get_u32_from_auc(&buf[0]); + data = fm_get_u32_from_auc(&buf[4]); + si->host_write(si, addr, data); + + break; + } + case CSPI_WRITE_OPCODE: + { + struct fm_spi_interface *si = &fm_wcn_ops.si; + + si->sys_spi_write(si, buf[0], fm_get_u16_from_auc(&buf[1]), + fm_get_u32_from_auc(&buf[3])); + break; + } + case CSPI_READ_OPCODE: + { + struct fm_spi_interface *si = &fm_wcn_ops.si; + unsigned int data; + unsigned short ret; + + ret = si->sys_spi_read( + si, buf[0], fm_get_u16_from_auc(&buf[1]), &data); + + if (ret != 0) + data = (unsigned short)ret; + + event[2] = 0x4; + event[3] = 0x0; + fm_set_u32_to_auc(&event[4], data); + break; + } + case FM_HOST_MODIFY_OPCODE: + { + struct fm_spi_interface *si = &fm_wcn_ops.si; + unsigned int addr, data; + + addr = fm_get_u32_from_auc(&buf[0]); + si->host_read(si, addr, &data); + data &= fm_get_u32_from_auc(&buf[4]); + data |= fm_get_u32_from_auc(&buf[8]); + si->host_write(si, addr, data); + break; + } + default: + fm_task_rx_dispatcher_default(opcode, length, buf); + break; + } + fm_tx(event, 0xFFFF); +} + +static bool drv_set_own(void) +{ + struct fm_spi_interface *si = &fm_wcn_ops.si; + struct fm_ext_interface *ei = &fm_wcn_ops.ei; + unsigned int val, tmp, i; + int ret = 0; + + ret = FM_LOCK(fm_wcn_ops.own_lock); + for (i = 0; ret && i < MAX_SET_OWN_COUNT; i++) { + fm_delayms(2); + ret = FM_LOCK(fm_wcn_ops.own_lock); + } + + /* get lock fail */ + if (i == MAX_SET_OWN_COUNT) { + WCN_DBG(FM_ERR | CHIP, "get own lock fail[%d]\n", ret); + return false; + } + + /* wakeup conninfra */ + drv_host_write(si, 0x180601B0, 0x1); + + /* polling chipid */ + drv_host_read(si, 0x18001000, &val); + for (i = 0; (val & 0xFFFF0000) != 0x20010000 && i < MAX_SET_OWN_COUNT; i++) { + fm_delayus(5000); + drv_host_read(si, 0x18001000, &val); + } + + /* polling fail */ + if (i == MAX_SET_OWN_COUNT) { + /* unlock if set own fail */ + drv_host_read(si, 0x180601B0, &val); + drv_host_read(si, 0x18001808, &tmp); + WCN_DBG(FM_ERR | CHIP, + "polling chip id fail [0x180601B0]=[0x%08x], [0x18001808]=[0x%08x]\n", + val, tmp); + FM_UNLOCK(fm_wcn_ops.own_lock); + return false; + } + + if (ei->is_bus_hang && ei->is_bus_hang()) { + FM_UNLOCK(fm_wcn_ops.own_lock); + return false; + } + + /* conn_infra bus debug function setting */ + conninfra_config_setup(); + + return true; +} + +static bool drv_clr_own(void) +{ + struct fm_spi_interface *si = &fm_wcn_ops.si; + + drv_host_write(si, 0x180601B0, 0x0); + + FM_UNLOCK(fm_wcn_ops.own_lock); + + return true; +} + +static int drv_stp_send_data(unsigned char *buf, unsigned int len) +{ + struct fm_spi_interface *si = &fm_wcn_ops.si; + + if (len < 4) { + WCN_DBG(FM_ERR | CHIP, "buf length error[%d].\n", len); + return -1; + } + + if (si->set_own && !si->set_own()) { + WCN_DBG(FM_ERR | CHIP, "set_own fail\n"); + return -1; + } + + fm_task_rx_dispatcher(buf[1], len - 4, buf + 4); + + if (si->clr_own) + si->clr_own(); + + WCN_DBG(FM_DBG | CHIP, "buffer: %02x %02x %02x %02x %02x %02x\n", + buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); + + return 1; +} + +static int drv_stp_recv_data(unsigned char *buf, unsigned int len) +{ + unsigned int length = fm_wcn_ops.rx_len; + + if (length > len) + length = len; + + memcpy(buf, fm_wcn_ops.rx_buf, length); + + return length; +} + +static int drv_spi_hopping(void) +{ + struct fm_spi_interface *si = &fm_wcn_ops.si; + int ret = 0, i = 0; + unsigned int val = 0; + + if (si->set_own && !si->set_own()) { + WCN_DBG(FM_ERR | CHIP, "set_own fail\n"); + return -1; + } + + /* enable 'rf_spi_div_en' */ + drv_host_read(si, 0x18001A00, &val); + drv_host_write(si, 0x18001A00, val | (0x1 << 28)); + + /* lock 64M */ + drv_host_read(si, 0x18003004, &val); + drv_host_write(si, 0x18003004, val | (0x1 << 15)); + + /*rd 0x18001810 until D1 == 1*/ + for (i = 0; i < 100; i++) { + drv_host_read(si, 0x18001810, &val); + if (val & 0x00000002) { + WCN_DBG(FM_NTC | CHIP, + "%s: POLLING PLL_RDY success !\n", __func__); + /* switch SPI clock to 64MHz */ + if (conninfra_spi_clock_switch(CONNSYS_SPI_SPEED_64M) == -1) { + WCN_DBG(FM_ERR | CHIP, + "conninfra clock switch 64M fail.\n"); + ret = -1; + } + break; + } + fm_delayus(10); + } + + if (i == 100) { + ret = -1; + WCN_DBG(FM_ERR | CHIP, + "%s: Polling to read rd 0x18001810[1] ==0x1 failed !\n", + __func__); + } + + if (si->clr_own) + si->clr_own(); + + return ret; +} + +static void drv_enable_eint(void) +{ + struct fm_ext_interface *ei = &fm_wcn_ops.ei; + + enable_irq(ei->irq_id); +} + +static void drv_disable_eint(void) +{ + struct fm_ext_interface *ei = &fm_wcn_ops.ei; + + disable_irq_nosync(ei->irq_id); +} + +static void drv_eint_handler(void) +{ + struct fm_spi_interface *si = &fm_wcn_ops.si; + unsigned short main_isr; + + if (si->set_own && !si->set_own()) { + WCN_DBG(FM_ERR | CHIP, "set_own fail\n"); + return; + } + + fw_spi_read(FM_MAIN_INTR, &main_isr); + main_isr &= FM_INTR_MASK; + + WCN_DBG(FM_NTC | CHIP, "interrupt[%04x]\n", main_isr); + + if (main_isr & FM_INTR_STC_DONE) + fm_stc_done_rechandler(); + + if (main_isr & FM_INTR_RDS) + fm_fifo_rechandler(main_isr); + + fw_spi_write(FM_MAIN_INTR, main_isr); + + if (si->clr_own) + si->clr_own(); +} + +static int drv_interface_init(void) +{ + struct fm_spi_interface *interface = &fm_wcn_ops.si; + struct fm_wcn_reg_info *info = &interface->info; + + info->spi_phy_addr = TOP_RF_SPI_AON_ADDR; + info->spi_size = TOP_RF_SPI_AON_SIZE; + request_mem_region(info->spi_phy_addr, info->spi_size, "FM_SPI"); + info->spi_vir_addr = ioremap_nocache( + info->spi_phy_addr, info->spi_size); + if (info->spi_vir_addr == NULL) { + WCN_DBG(FM_ERR | CHIP, "Cannot remap address.\n"); + return -1; + } + + info->top_phy_addr = TOP_MISC_OFF_ADDR; + info->top_size = TOP_MISC_OFF_SIZE; + request_mem_region(info->top_phy_addr, info->top_size, "FM_TOP"); + info->top_vir_addr = ioremap_nocache( + info->top_phy_addr, info->top_size); + if (info->top_vir_addr == NULL) { + WCN_DBG(FM_ERR | CHIP, "Cannot remap address.\n"); + return -1; + } + + info->mcu_phy_addr = MCU_CFG_ADDR; + info->mcu_size = MCU_CFG_SIZE; + request_mem_region(info->mcu_phy_addr, info->mcu_size, "FM_MCU"); + info->mcu_vir_addr = ioremap_nocache( + info->mcu_phy_addr, info->mcu_size); + if (info->mcu_vir_addr == NULL) { + WCN_DBG(FM_ERR | CHIP, "Cannot remap address.\n"); + return -1; + } + + interface->spi_read = drv_spi_read; + interface->spi_write = drv_spi_write; + interface->host_read = drv_host_read; + interface->host_write = drv_host_write; +#if CFG_FM_CONNAC2 + interface->sys_spi_read = drv_sys_spi_read; + interface->sys_spi_write = drv_sys_spi_write; + interface->set_own = drv_set_own; + interface->clr_own = drv_clr_own; +#else + interface->sys_spi_read = fm_sys_spi_read; + interface->sys_spi_write = fm_sys_spi_write; + interface->set_own = NULL; + interface->clr_own = NULL; +#endif + + return 0; +} + +static int drv_interface_uninit(void) +{ + struct fm_spi_interface *interface = &fm_wcn_ops.si; + struct fm_wcn_reg_info *info = &interface->info; + + if (info->spi_vir_addr) { + iounmap(info->spi_vir_addr); + release_mem_region(info->spi_phy_addr, info->spi_size); + } + + if (info->top_vir_addr) { + iounmap(info->top_vir_addr); + release_mem_region(info->top_phy_addr, info->top_size); + } + + if (info->mcu_vir_addr) { + iounmap(info->mcu_vir_addr); + release_mem_region(info->mcu_phy_addr, info->mcu_size); + } + return 0; +} + +static int drv_get_hw_version(void) +{ + return FM_CONNAC_2_1; +} + +static unsigned char drv_get_top_index(void) +{ + return SYS_SPI_TOP; +} + +static unsigned int drv_get_get_adie(void) +{ + return 0x6635; +} + +#if CFG_FM_CONNAC2 + +static int fm_conninfra_stp_register_event_cb(void *cb) +{ + fm_wcn_ops.ei.eint_cb = (void (*)(void))cb; + return 0; +} + +static int fm_conninfra_msgcb_reg(void *data) +{ + /* get whole chip reset cb */ + whole_chip_reset = data; + return conninfra_sub_drv_ops_register( + CONNDRV_TYPE_FM, &fm_drv_cbs); +} + +static int fm_conninfra_func_on(void) +{ + struct fm_spi_interface *si = &fm_wcn_ops.si; + int ret = 0; + + ret = conninfra_pwr_on(CONNDRV_TYPE_FM); + if (ret == -1) { + WCN_DBG(FM_ERR | CHIP, "conninfra power on fail.\n"); + return 0; + } + + if (si->set_own && !si->set_own()) { + WCN_DBG(FM_ERR | CHIP, "set_own fail\n"); + return 0; + } + + ret = conninfra_adie_top_ck_en_on(CONNSYS_ADIE_CTL_HOST_FM); + + if (si->clr_own) + si->clr_own(); + + if (ret == -1) { + WCN_DBG(FM_ERR | CHIP, "top ck en fail.\n"); + return 0; + } + + return 1; +} + +static int fm_conninfra_func_off(void) +{ + struct fm_spi_interface *si = &fm_wcn_ops.si; + int ret = 0; + + if (si->set_own && !si->set_own()) { + WCN_DBG(FM_ERR | CHIP, "set_own fail\n"); + return 0; + } + + ret = conninfra_adie_top_ck_en_off(CONNSYS_ADIE_CTL_HOST_FM); + + if (si->clr_own) + si->clr_own(); + + if (ret == -1) { + WCN_DBG(FM_ERR | CHIP, "top ck en off fail.\n"); + return 0; + } + + ret = conninfra_pwr_off(CONNDRV_TYPE_FM); + if (ret == -1) { + WCN_DBG(FM_ERR | CHIP, "conninfra power off fail.\n"); + return 0; + } + + return 1; +} + +static int fm_conninfra_chipid_query(void) +{ +#ifdef CFG_FM_CHIP_ID + return CFG_FM_CHIP_ID; +#else + return 0; +#endif +} + +static int fm_conninfra_spi_clock_switch(enum fm_spi_speed speed) +{ + struct fm_spi_interface *si = &fm_wcn_ops.si; + enum connsys_spi_speed_type sp_type = CONNSYS_SPI_SPEED_26M; + int ret = 0; + + if (si->set_own && !si->set_own()) { + WCN_DBG(FM_ERR | CHIP, "set_own fail\n"); + return -2; + } + + switch (speed) { + case FM_SPI_SPEED_26M: + sp_type = CONNSYS_SPI_SPEED_26M; + break; + case FM_SPI_SPEED_64M: + sp_type = CONNSYS_SPI_SPEED_64M; + break; + default: + break; + } + + ret = conninfra_spi_clock_switch(sp_type); + + if (si->clr_own) + si->clr_own(); + + if (ret == -1) { + WCN_DBG(FM_ERR | CHIP, "conninfra clock switch fail.\n"); + return -1; + } + + return 0; +} + +static bool fm_conninfra_is_bus_hang(void) +{ + int ret = 0; + + if (conninfra_reg_readable()) + return false; + + /* Check conninfra bus before accessing BGF's CR */ + ret = conninfra_is_bus_hang(); + if (ret > 0) { + WCN_DBG(FM_ERR | CHIP, "conninfra bus is hang[0x%x]\n", ret); + conninfra_trigger_whole_chip_rst(CONNDRV_TYPE_FM, "bus hang"); + return true; + } + + WCN_DBG(FM_ERR | CHIP, + "conninfra not readable, but not bus hang ret = %d", ret); + + return false; +} + +#else /* CFG_FM_CONNAC2 */ + + +static int fm_stp_register_event_cb(void *cb) +{ + fm_wcn_ops.ei.eint_cb = (void (*)(void))cb; + return mtk_wcn_stp_register_event_cb(FM_TASK_INDX, cb); +} + +static int fm_wmt_msgcb_reg(void *data) +{ + /* get whole chip reset cb */ + return 0; +} + +static int fm_wmt_func_on(void) +{ + return mtk_wcn_wmt_func_on(WMTDRV_TYPE_FM) != MTK_WCN_BOOL_FALSE; +} + +static int fm_wmt_func_off(void) +{ + return mtk_wcn_wmt_func_off(WMTDRV_TYPE_FM) != MTK_WCN_BOOL_FALSE; +} + +static unsigned int fm_wmt_ic_info_get(void) +{ + return mtk_wcn_wmt_ic_info_get(1); +} + +static int fm_wmt_chipid_query(void) +{ + return mtk_wcn_wmt_chipid_query(); +} + +static int fm_wmt_spi_clock_switch(enum fm_spi_speed speed) +{ + struct fm_spi_interface *si = &fm_wcn_ops.si; + unsigned int reg_val = 0; + + switch (speed) { + case FM_SPI_SPEED_26M: + si->host_read(si, 0x18004004, ®_val); + reg_val &= 0xFFFFFFFE; + si->host_write(si, 0x18004004, reg_val); + break; + case FM_SPI_SPEED_64M: + si->host_read(si, 0x18004004, ®_val); + reg_val |= 0x00000001; + si->host_write(si, 0x18004004, reg_val); + break; + default: + break; + } + + return 0; +} +#endif /* CFG_FM_CONNAC2 */ + +static irqreturn_t fm_isr(int irq, void *dev) +{ + struct fm_ext_interface *ei = &fm_wcn_ops.ei; + + if (!ei->eint_cb) { + WCN_DBG(FM_WAR | CHIP, "fm eint cb is NULL\n"); + return IRQ_NONE; + } + + if (ei->disable_eint) + ei->disable_eint(); + + ei->eint_cb(); + + return IRQ_HANDLED; +} + +int fm_register_irq(struct platform_driver *drv) +{ +#ifdef CONFIG_OF + struct device_node *node = NULL; +#endif + struct fm_ext_interface *ei = &fm_wcn_ops.ei; + int ret = 0; + + ei->drv = drv; + ei->irq_id = FM_IRQ_NUMBER; +#ifdef CONFIG_OF + node = of_find_compatible_node(NULL, NULL, "mediatek,fm"); + if (node) + ei->irq_id = irq_of_parse_and_map(node, 0); + else + WCN_DBG(FM_ERR | CHIP, "get fm dts node fail\n"); +#endif + WCN_DBG(FM_NTC | CHIP, "request_irq num(%d)\n", ei->irq_id); + ret = request_irq(ei->irq_id, fm_isr, IRQF_SHARED, FM_NAME, drv); + if (ret != 0) + WCN_DBG(FM_ERR | CHIP, "request_irq ERROR(%d)\n", ret); + + return ret; +} + +static void register_drv_ops_init(void) +{ + struct fm_ext_interface *ei = &fm_wcn_ops.ei; + + drv_interface_init(); + ei->eint_handler = drv_eint_handler; + ei->stp_send_data = drv_stp_send_data; + ei->stp_recv_data = drv_stp_recv_data; + ei->get_hw_version = drv_get_hw_version; + ei->get_top_index = drv_get_top_index; + ei->get_get_adie = drv_get_get_adie; + +#if CFG_FM_CONNAC2 + ei->enable_eint = drv_enable_eint; + ei->disable_eint = drv_disable_eint; + ei->stp_register_event_cb = fm_conninfra_stp_register_event_cb; + ei->wmt_msgcb_reg = fm_conninfra_msgcb_reg; + ei->wmt_func_on = fm_conninfra_func_on; + ei->wmt_func_off = fm_conninfra_func_off; + ei->wmt_ic_info_get = NULL; + ei->wmt_chipid_query = fm_conninfra_chipid_query; + ei->spi_clock_switch = fm_conninfra_spi_clock_switch; + ei->is_bus_hang = fm_conninfra_is_bus_hang; + ei->spi_hopping = drv_spi_hopping; +#else + ei->enable_eint = NULL; + ei->disable_eint = NULL; + ei->stp_register_event_cb = fm_stp_register_event_cb; + ei->wmt_msgcb_reg = fm_wmt_msgcb_reg; + ei->wmt_func_on = fm_wmt_func_on; + ei->wmt_func_off = fm_wmt_func_off; + ei->wmt_ic_info_get = fm_wmt_ic_info_get; + ei->wmt_chipid_query = fm_wmt_chipid_query; + ei->spi_clock_switch = fm_wmt_spi_clock_switch; + ei->is_bus_hang = NULL; + ei->spi_hopping = NULL; +#endif + ei->low_ops_register = mt6635_fm_low_ops_register; + ei->rds_ops_unregister = mt6635_fm_rds_ops_unregister; + ei->rds_ops_register = mt6635_fm_rds_ops_register; + ei->rds_ops_unregister = mt6635_fm_rds_ops_unregister; +} + +static void register_drv_ops_uninit(void) +{ + struct fm_ext_interface *ei = &fm_wcn_ops.ei; + + if (ei->irq_id) + free_irq(ei->irq_id, ei->drv); + drv_interface_uninit(); + fm_memset(&fm_wcn_ops, 0, sizeof(struct fm_wcn_reg_ops)); +} + +int fm_wcn_ops_register(void) +{ + register_drv_ops_init(); + return 0; +} + +int fm_wcn_ops_unregister(void) +{ + register_drv_ops_uninit(); + return 0; +} diff --git a/drivers/misc/mediatek/connectivity/fmradio/plat/inc/plat.h b/drivers/misc/mediatek/connectivity/fmradio/plat/inc/plat.h new file mode 100644 index 0000000000000000000000000000000000000000..3e65ef7c4e6125f1280292273f5b45f724fe7d71 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/plat/inc/plat.h @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +#ifndef FM_PLAT_H +#define FM_PLAT_H + +#include +#include +#include +#include +#include +#include +#include + +#include "fm_typedef.h" +#include "fm_dbg.h" +#include "fm_err.h" +#include "fm_stdlib.h" +#include "fm_link.h" +#include "fm_utils.h" +#include "fm_rds.h" +#include "fm_ext_api.h" +#include "fm_reg_utils.h" +#include "fm_main.h" + +#if CFG_FM_CONNAC2 + +#include "conninfra.h" + +#else /* CFG_FM_CONNAC2 */ + +#include "osal_typedef.h" +#include "stp_exp.h" +#include "wmt_exp.h" + +enum { + SYS_SPI_WF1 = 0x00, + SYS_SPI_WF = 0x01, + SYS_SPI_BT = 0x02, + SYS_SPI_FM = 0x03, + SYS_SPI_GPS = 0x04, + SYS_SPI_TOP = 0x05, + SYS_SPI_WF2 = 0x06, + SYS_SPI_WF3 = 0x07, + SYS_SPI_MAX +}; + +#endif /* CFG_FM_CONNAC2 */ + +enum { + FM_SYS_SPI_OK = 0, + FM_SYS_SPI_BUSY, + FM_SYS_SPI_ERR +}; + +enum { + FM_CONNAC_LEGACY = 0, + FM_CONNAC_1_0, + FM_CONNAC_1_2, + FM_CONNAC_1_5, + FM_CONNAC_2_0, + FM_CONNAC_2_1, + FM_CONNAC_UNKNOWN +}; + +extern signed int fm_rds_parser( + struct rds_rx_t *rds_raw, signed int rds_size); + +extern signed int mt6631_fm_low_ops_register( + struct fm_callback *cb, struct fm_basic_interface *bi); +extern signed int mt6631_fm_low_ops_unregister( + struct fm_basic_interface *bi); +extern signed int mt6631_fm_rds_ops_register( + struct fm_basic_interface *bi, struct fm_rds_interface *ri); +extern signed int mt6631_fm_rds_ops_unregister( + struct fm_rds_interface *ri); +extern signed int mt6635_fm_low_ops_register( + struct fm_callback *cb, struct fm_basic_interface *bi); +extern signed int mt6635_fm_low_ops_unregister( + struct fm_basic_interface *bi); +extern signed int mt6635_fm_rds_ops_register( + struct fm_basic_interface *bi, struct fm_rds_interface *ri); +extern signed int mt6635_fm_rds_ops_unregister( + struct fm_rds_interface *ri); + +#endif /* FM_PLAT_H */ diff --git a/drivers/misc/mediatek/connectivity/fmradio/plat/legacy_wmt.c b/drivers/misc/mediatek/connectivity/fmradio/plat/legacy_wmt.c new file mode 100644 index 0000000000000000000000000000000000000000..9a0a3cfb83c54129273949db576513986a443e93 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/fmradio/plat/legacy_wmt.c @@ -0,0 +1,423 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +#include "plat.h" + +#include "fm_cmd.h" + +static int (*whole_chip_reset)(signed int sta); + +static void WCNfm_wholechip_rst_cb( + ENUM_WMTDRV_TYPE_T src, ENUM_WMTDRV_TYPE_T dst, + ENUM_WMTMSG_TYPE_T type, void *buf, unsigned int sz) +{ + /* To handle reset procedure please */ + ENUM_WMTRSTMSG_TYPE_T rst_msg; + + if (sz > sizeof(ENUM_WMTRSTMSG_TYPE_T)) { + /*message format invalid */ + WCN_DBG(FM_WAR | LINK, "message format invalid!\n"); + return; + } + + memcpy((char *)&rst_msg, (char *)buf, sz); + WCN_DBG(FM_WAR | LINK, + "[src=%d], [dst=%d], [type=%d], [buf=0x%x], [sz=%d], [max=%d]\n", + src, dst, type, rst_msg, sz, WMTRSTMSG_RESET_MAX); + + if ((src == WMTDRV_TYPE_WMT) && (dst == WMTDRV_TYPE_FM) + && (type == WMTMSG_TYPE_RESET)) { + + if (rst_msg == WMTRSTMSG_RESET_START) { + WCN_DBG(FM_WAR | LINK, "FM restart start!\n"); + if (whole_chip_reset) + whole_chip_reset(1); + } else if (rst_msg == WMTRSTMSG_RESET_END_FAIL) { + WCN_DBG(FM_WAR | LINK, "FM restart end fail!\n"); + if (whole_chip_reset) + whole_chip_reset(2); + } else if (rst_msg == WMTRSTMSG_RESET_END) { + WCN_DBG(FM_WAR | LINK, "FM restart end!\n"); + if (whole_chip_reset) + whole_chip_reset(0); + } + } +} + +static void fw_eint_handler(void) +{ + fm_event_parser(fm_rds_parser); +} + +static int fm_stp_send_data(unsigned char *buf, unsigned int len) +{ + return mtk_wcn_stp_send_data(buf, len, FM_TASK_INDX); +} + +static int fm_stp_recv_data(unsigned char *buf, unsigned int len) +{ + return mtk_wcn_stp_receive_data(buf, len, FM_TASK_INDX); +} + +static int fm_stp_register_event_cb(void *cb) +{ + return mtk_wcn_stp_register_event_cb(FM_TASK_INDX, cb); +} + +static int fm_wmt_msgcb_reg(void *data) +{ + /* get whole chip reset cb */ + whole_chip_reset = data; + return mtk_wcn_wmt_msgcb_reg( + WMTDRV_TYPE_FM, WCNfm_wholechip_rst_cb); +} + +static int fm_wmt_func_on(void) +{ + int ret = 0; + + ret = mtk_wcn_wmt_func_on(WMTDRV_TYPE_FM) != MTK_WCN_BOOL_FALSE; + + return ret; +} + +static int fm_wmt_func_off(void) +{ + int ret = 0; + + ret = mtk_wcn_wmt_func_off(WMTDRV_TYPE_FM) != MTK_WCN_BOOL_FALSE; + + return ret; +} + +static unsigned int fm_wmt_ic_info_get(void) +{ + return mtk_wcn_wmt_ic_info_get(WMTCHIN_HWVER); +} + +static int fm_wmt_chipid_query(void) +{ + return mtk_wcn_wmt_chipid_query(); +} + +static signed int fm_drv_switch_clk_64m(void) +{ + unsigned int val = 0; + int i = 0, ret = 0; + + /* switch SPI clock to 64MHz */ + fm_host_reg_read(0x81026004, &val); + /* Set 0x81026004[0] = 0x1 */ + ret = fm_host_reg_write(0x81026004, val | 0x1); + if (ret) { + WCN_DBG(FM_ERR | CHIP, + "Switch SPI clock to 64MHz failed\n"); + return -1; + } + + for (i = 0; i < 100; i++) { + fm_host_reg_read(0x81026004, &val); + if ((val & 0x18) == 0x10) + break; + fm_delayus(10); + } + + if (i == 100) { + WCN_DBG(FM_ERR | CHIP, + "switch_SPI_clock_to_64MHz polling timeout\n"); + return -1; + } + + /* Capture next (with SPI Clock: 64MHz) */ + fm_host_reg_read(0x81026004, &val); + /* Set 0x81026004[2] = 0x1 */ + ret = fm_host_reg_write(0x81026004, val | 0x4); + if (ret) { + WCN_DBG(FM_ERR | CHIP, + "Switch SPI clock to 64MHz failed\n"); + return -1; + } + + return 0; +} + +static signed int fm_drv_switch_clk_26m(void) +{ + unsigned int val = 0; + int i = 0, ret = 0; + + /* Capture next (with SPI Clock: 26MHz) */ + fm_host_reg_read(0x81026004, &val); + /* Set 0x81026004[2] = 0x0 */ + ret = fm_host_reg_write(0x81026004, val & 0xFFFFFFFB); + if (ret) { + WCN_DBG(FM_ERR | CHIP, + "Switch SPI clock to 26MHz failed\n"); + return -1; + } + + /* switch SPI clock to 26MHz */ + fm_host_reg_read(0x81026004, &val); + /* Set 0x81026004[0] = 0x0 */ + ret = fm_host_reg_write(0x81026004, val & 0xFFFFFFFE); + if (ret) { + WCN_DBG(FM_ERR | CHIP, + "Switch SPI clock to 26MHz failed\n"); + return -1; + } + + for (i = 0; i < 100; i++) { + fm_host_reg_read(0x81026004, &val); + if ((val & 0x18) == 0x8) + break; + fm_delayus(10); + } + + if (i == 100) { + WCN_DBG(FM_ERR | CHIP, + "switch_SPI_clock_to_26MHz polling timeout\n"); + return -1; + } + + return 0; +} + +static int fm_drv_spi_clock_switch(enum fm_spi_speed speed) +{ + int ret = 0; + + switch (speed) { + case FM_SPI_SPEED_26M: + ret = fm_drv_switch_clk_26m(); + break; + case FM_SPI_SPEED_64M: + ret = fm_drv_switch_clk_64m(); + break; + default: + ret = -1; + break; + } + + return ret; +} + +static int drv_get_hw_version(void) +{ +#if defined(MT6625_FM) || defined(MT6627_FM) || defined(MT6630_FM) || defined(MT6632_FM) || defined(soc) + return FM_CONNAC_LEGACY; +#else + int id = fm_wmt_chipid_query(); + int ret = FM_CONNAC_UNKNOWN; + + switch (id) { + case 0x6758: + case 0x6759: + case 0x6771: + case 0x6775: + case 0x6797: + ret = FM_CONNAC_LEGACY; + break; + case 0x6765: + case 0x6761: + case 0x3967: + ret = FM_CONNAC_1_0; + break; + case 0x6768: + case 0x6785: + case 0x8168: + ret = FM_CONNAC_1_2; + break; + case 0x6779: + case 0x6873: + case 0x6853: + ret = FM_CONNAC_1_5; + break; + default: + ret = FM_CONNAC_UNKNOWN; + break; + } + + return ret; +#endif +} + +static unsigned char drv_get_top_index(void) +{ + if (drv_get_hw_version() < FM_CONNAC_1_5) + return 4; + return 5; +} + +static unsigned int drv_get_get_adie(void) +{ +#if defined(MT6625_FM) || defined(MT6627_FM) || defined(MT6630_FM) || defined(MT6632_FM) || defined(soc) + return 0; +#elif defined(MT6631_FM) + return 0x6631; +#elif defined(MT6635_FM) + return 0x6635; +#else + return mtk_wcn_wmt_ic_info_get(WMTCHIN_ADIE); +#endif +} + +signed int __weak fm_low_ops_register(struct fm_callback *cb, + struct fm_basic_interface *bi) +{ + WCN_DBG(FM_NTC | CHIP, "default %s\n", __func__); + return -1; +} + +signed int __weak fm_low_ops_unregister(struct fm_basic_interface *bi) +{ + WCN_DBG(FM_NTC | CHIP, "default %s\n", __func__); + return -1; +} + +signed int __weak fm_rds_ops_register(struct fm_basic_interface *bi, + struct fm_rds_interface *ri) +{ + WCN_DBG(FM_NTC | CHIP, "default %s\n", __func__); + return -1; +} + +signed int __weak fm_rds_ops_unregister(struct fm_rds_interface *ri) +{ + WCN_DBG(FM_NTC | CHIP, "default %s\n", __func__); + return -1; +} + +signed int __weak mt6631_fm_low_ops_register( + struct fm_callback *cb, struct fm_basic_interface *bi) +{ + WCN_DBG(FM_NTC | CHIP, "default %s\n", __func__); + return -1; +} + +signed int __weak mt6631_fm_low_ops_unregister(struct fm_basic_interface *bi) +{ + WCN_DBG(FM_NTC | CHIP, "default %s\n", __func__); + return -1; +} + +signed int __weak mt6631_fm_rds_ops_register( + struct fm_basic_interface *bi, struct fm_rds_interface *ri) +{ + WCN_DBG(FM_NTC | CHIP, "default %s\n", __func__); + return -1; +} + +signed int __weak mt6631_fm_rds_ops_unregister(struct fm_rds_interface *ri) +{ + WCN_DBG(FM_NTC | CHIP, "default %s\n", __func__); + return -1; +} +signed int __weak mt6635_fm_low_ops_register( + struct fm_callback *cb, struct fm_basic_interface *bi) +{ + WCN_DBG(FM_NTC | CHIP, "default %s\n", __func__); + return -1; +} + +signed int __weak mt6635_fm_low_ops_unregister(struct fm_basic_interface *bi) +{ + WCN_DBG(FM_NTC | CHIP, "default %s\n", __func__); + return -1; +} + +signed int __weak mt6635_fm_rds_ops_register( + struct fm_basic_interface *bi, struct fm_rds_interface *ri) +{ + WCN_DBG(FM_NTC | CHIP, "default %s\n", __func__); + return -1; +} + +signed int __weak mt6635_fm_rds_ops_unregister(struct fm_rds_interface *ri) +{ + WCN_DBG(FM_NTC | CHIP, "default %s\n", __func__); + return -1; +} + +void register_fw_ops_init(void) +{ + struct fm_ext_interface *ei = &fm_wcn_ops.ei; + unsigned int adie = drv_get_get_adie(); + + ei->eint_handler = fw_eint_handler; + ei->stp_send_data = fm_stp_send_data; + ei->stp_recv_data = fm_stp_recv_data; + ei->stp_register_event_cb = fm_stp_register_event_cb; + ei->wmt_msgcb_reg = fm_wmt_msgcb_reg; + ei->wmt_func_on = fm_wmt_func_on; + ei->wmt_func_off = fm_wmt_func_off; + ei->wmt_ic_info_get = fm_wmt_ic_info_get; + ei->wmt_chipid_query = fm_wmt_chipid_query; + ei->spi_clock_switch = fm_drv_spi_clock_switch; + ei->get_hw_version = drv_get_hw_version; + ei->get_top_index = drv_get_top_index; + ei->get_get_adie = drv_get_get_adie; + + WCN_DBG(FM_NTC | CHIP, "adie=0x%x\n", adie); + + if (adie == 0x6631) { + ei->low_ops_register = mt6631_fm_low_ops_register; + ei->low_ops_unregister = mt6631_fm_low_ops_unregister; + ei->rds_ops_register = mt6631_fm_rds_ops_register; + ei->rds_ops_unregister = mt6631_fm_rds_ops_unregister; + } else if (adie == 0x6635) { + ei->low_ops_register = mt6635_fm_low_ops_register; + ei->low_ops_unregister = mt6635_fm_low_ops_unregister; + ei->rds_ops_register = mt6635_fm_rds_ops_register; + ei->rds_ops_unregister = mt6635_fm_rds_ops_unregister; + } else { +#if defined(MT6631_FM) + ei->low_ops_register = mt6631_fm_low_ops_register; + ei->low_ops_unregister = mt6631_fm_low_ops_unregister; + ei->rds_ops_register = mt6631_fm_rds_ops_register; + ei->rds_ops_unregister = mt6631_fm_rds_ops_unregister; +#elif defined(MT6635_FM) + ei->low_ops_register = mt6635_fm_low_ops_register; + ei->low_ops_unregister = mt6635_fm_low_ops_unregister; + ei->rds_ops_register = mt6635_fm_rds_ops_register; + ei->rds_ops_unregister = mt6635_fm_rds_ops_unregister; +#else + ei->low_ops_register = fm_low_ops_register; + ei->low_ops_unregister = fm_low_ops_unregister; + ei->rds_ops_register = fm_rds_ops_register; + ei->rds_ops_unregister = fm_rds_ops_unregister; +#endif + } +} + +void register_fw_ops_uninit(void) +{ +} + +int fm_register_irq(struct platform_driver *drv) +{ + return 0; +} + +int fm_wcn_ops_register(void) +{ + register_fw_ops_init(); + + return 0; +} + +int fm_wcn_ops_unregister(void) +{ + register_fw_ops_uninit(); + + return 0; +} diff --git a/drivers/misc/mediatek/connectivity/gps/Makefile b/drivers/misc/mediatek/connectivity/gps/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..a1c2efbe363615a5ede6adb4da16c081849b0c61 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/Makefile @@ -0,0 +1,212 @@ +MTK_PLATFORM := $(subst ",,$(CONFIG_MTK_PLATFORM)) +# drivers/barcelona/gps/Makefile +# +# Makefile for the Barcelona GPS driver. +# +# Copyright (C) 2004,2005 TomTom BV +# Author: Dimitry Andric +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. + +MTK_PLATFORM := $(subst ",,$(CONFIG_MTK_PLATFORM)) +ifeq ($(CONFIG_MTK_GPS_SUPPORT), y) + +# Force build fail on modpost warning +KBUILD_MODPOST_FAIL_ON_WARNINGS := y +############################################################################### + +# only WMT align this design flow, but gps use this also. +#ccflags-y += -D MTK_WCN_REMOVE_KERNEL_MODULE + +ifeq ($(CONFIG_ARM64), y) + ccflags-y += -D CONFIG_MTK_WCN_ARM64 +endif + +ifeq ($(CONFIG_MTK_CONN_LTE_IDC_SUPPORT),y) + ccflags-y += -D WMT_IDC_SUPPORT=1 +else + ccflags-y += -D WMT_IDC_SUPPORT=0 +endif +ccflags-y += -D MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT + +ccflags-y += -I$(srctree)/drivers/misc/mediatek/include +ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat +ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include +ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include/mach +ccflags-y += -I$(srctree)/drivers/misc/mediatek/freqhopping +ccflags-y += -I$(srctree)/drivers/misc/mediatek/freqhopping/$(MTK_PLATFORM) +ccflags-y += -I$(srctree)/drivers/misc/mediatek/emi/submodule +ccflags-y += -I$(srctree)/drivers/misc/mediatek/emi/$(MTK_PLATFORM) +ccflags-y += -I$(srctree)/drivers/misc/mediatek/connectivity/common +ccflags-y += -I$(srctree)/drivers/misc/mediatek/mach/$(MTK_PLATFORM)/include/mach +ccflags-y += -I$(srctree)/drivers/misc/mediatek/base/power/$(MTK_PLATFORM) +ccflags-y += -I$(srctree)/drivers/misc/mediatek/base/power/include +ccflags-y += -I$(srctree)/drivers/misc/mediatek/base/power/include/clkbuf_v1 +ccflags-y += -I$(srctree)/drivers/misc/mediatek/base/power/include/clkbuf_v1/$(MTK_PLATFORM) +ccflags-y += -I$(srctree)/drivers/devfreq +############################################################################### + +MODULE_NAME := gps_drv +obj-m += $(MODULE_NAME).o + +GPS_DRV_CONTROL_LNA := n +SELECT_GPS_DL_DRV := n +GPS_DL_HAS_MOCK := n +GPS_DL_HAS_CONNINFRA_DRV := n +GPS_SRC_FOLDER := $(srctree)/drivers/misc/mediatek/connectivity/gps + +ifeq ($(CONFIG_ARCH_MTK_PROJECT),"k6833v1_64_swrgo") +ccflags-y += -DCONFIG_GPSL5_SUPPORT +ccflags-y += -DCONFIG_GPS_CTRL_LNA_SUPPORT +GPS_DRV_CONTROL_LNA := y +endif + +ifeq ($(CONFIG_MACH_MT6833),y) +ccflags-y += -DCONFIG_GPSL5_SUPPORT +ccflags-y += -DCONFIG_GPS_CTRL_LNA_SUPPORT +GPS_DRV_CONTROL_LNA := y +endif + +ifeq ($(CONFIG_MACH_MT6885),y) +SELECT_GPS_DL_DRV := y +ccflags-y += -I$(GPS_SRC_FOLDER)/data_link/hw/inc/connac2_0 +ccflags-y += -I$(GPS_SRC_FOLDER)/data_link/hw/inc/connac2_0/coda_gen +ifeq ($(CONFIG_MTK_COMBO_CHIP_CONSYS_6885),y) +GPS_DL_HAS_CONNINFRA_DRV := y +endif +ifeq ($(CONFIG_MTK_COMBO_CHIP_CONSYS_6893),y) +GPS_DL_HAS_CONNINFRA_DRV := y +endif +endif + +ifeq ($(CONFIG_MACH_MT6893),y) +SELECT_GPS_DL_DRV := y +# For MT6893, the CODA is same as connac2_0 +ccflags-y += -I$(GPS_SRC_FOLDER)/data_link/hw/inc/connac2_0 +ccflags-y += -I$(GPS_SRC_FOLDER)/data_link/hw/inc/connac2_0/coda_gen +ifeq ($(CONFIG_MTK_COMBO_CHIP_CONSYS_6885),y) +GPS_DL_HAS_CONNINFRA_DRV := y +endif +ifeq ($(CONFIG_MTK_COMBO_CHIP_CONSYS_6893),y) +GPS_DL_HAS_CONNINFRA_DRV := y +endif +endif + +ifeq ($(SELECT_GPS_DL_DRV),y) # New GPS driver with L1+L5 support +ifeq ($(GPS_DL_HAS_CONNINFRA_DRV),y) +CONNINFRA_SRC_FOLDER := $(srctree)/drivers/misc/mediatek/connectivity/conninfra +ccflags-y += -I$(CONNINFRA_SRC_FOLDER)/include +ccflags-y += -DGPS_DL_HAS_CONNINFRA_DRV=1 +endif + +ccflags-y += -I$(GPS_SRC_FOLDER)/data_link/inc +ccflags-y += -I$(GPS_SRC_FOLDER)/data_link/linux/inc +ccflags-y += -I$(GPS_SRC_FOLDER)/data_link/link/inc +ccflags-y += -I$(GPS_SRC_FOLDER)/data_link/lib/inc +ccflags-y += -I$(GPS_SRC_FOLDER)/data_link/hal/inc +ccflags-y += -I$(GPS_SRC_FOLDER)/data_link/hw/inc +ccflags-y += -I$(GPS_SRC_FOLDER)/data_link_mock/mock/inc + +$(MODULE_NAME)-objs += gps_dl_module.o +$(MODULE_NAME)-objs += data_link/gps_dl_context.o + +$(MODULE_NAME)-objs += data_link/lib/gps_dl_dma_buf.o +$(MODULE_NAME)-objs += data_link/lib/gps_dl_lib_misc.o +$(MODULE_NAME)-objs += data_link/lib/gps_dl_hist_rec.o +$(MODULE_NAME)-objs += data_link/lib/gps_dl_time_tick.o +$(MODULE_NAME)-objs += data_link/lib/gps_dl_name_list.o + +$(MODULE_NAME)-objs += data_link/hw/gps_dl_hw_conn_infra.o +$(MODULE_NAME)-objs += data_link/hw/gps_dl_hw_bgf.o +$(MODULE_NAME)-objs += data_link/hw/gps_dl_hw_gps.o +$(MODULE_NAME)-objs += data_link/hw/gps_dl_hw_power_ctrl.o +$(MODULE_NAME)-objs += data_link/hw/gps_dl_hw_usrt_apb.o +$(MODULE_NAME)-objs += data_link/hw/gps_dl_hw_util.o + +$(MODULE_NAME)-objs += data_link/hal/gps_dl_hal.o +$(MODULE_NAME)-objs += data_link/hal/gps_dl_hal_util.o +$(MODULE_NAME)-objs += data_link/hal/gps_dsp_fsm.o +$(MODULE_NAME)-objs += data_link/hal/gps_dl_power_ctrl.o +$(MODULE_NAME)-objs += data_link/hal/gps_dl_isr.o +$(MODULE_NAME)-objs += data_link/hal/gps_dl_dma.o +$(MODULE_NAME)-objs += data_link/hal/gps_dl_mcub.o +$(MODULE_NAME)-objs += data_link/hal/gps_dl_zbus.o +$(MODULE_NAME)-objs += data_link/hal/gps_dl_conn_infra.o + +$(MODULE_NAME)-objs += data_link/link/gps_dl_subsys_reset.o +$(MODULE_NAME)-objs += data_link/gps_each_link.o + +$(MODULE_NAME)-objs += data_link/linux/gps_data_link_devices.o +$(MODULE_NAME)-objs += data_link/linux/gps_each_device.o +$(MODULE_NAME)-objs += data_link/linux/gps_dl_linux.o +$(MODULE_NAME)-objs += data_link/linux/gps_dl_linux_plat_drv.o +$(MODULE_NAME)-objs += data_link/linux/gps_dl_linux_reserved_mem.o +$(MODULE_NAME)-objs += data_link/linux/gps_dl_emi.o +$(MODULE_NAME)-objs += data_link/linux/gps_dl_ctrld.o +$(MODULE_NAME)-objs += data_link/linux/gps_dl_procfs.o +$(MODULE_NAME)-objs += data_link/linux/gps_dl_osal.o + +ifeq ($(GPS_DL_HAS_MOCK),y) +$(MODULE_NAME)-objs += data_link_mock/mock/gps_mock_mvcd.o +$(MODULE_NAME)-objs += data_link_mock/mock/gps_mock_hal.o +ccflags-y += -DGPS_DL_HAS_MOCK=1 +endif + +else #Legacy drivers +WMT_SRC_FOLDER := $(srctree)/drivers/misc/mediatek/connectivity/common + +ifeq ($(CONFIG_MTK_COMBO_CHIP),) + $(error CONFIG_MTK_COMBO_CHIP not defined) +endif + +ifneq ($(filter "CONSYS_%",$(CONFIG_MTK_COMBO_CHIP)),) + ccflags-y += -DSOC_CO_CLOCK_FLAG=1 + ccflags-y += -DWMT_CREATE_NODE_DYNAMIC=1 + ccflags-y += -DREMOVE_MK_NODE=0 + +ccflags-y += -I$(WMT_SRC_FOLDER)/common_main/$(MTK_PLATFORM)/include + +else + ccflags-y += -DSOC_CO_CLOCK_FLAG=0 + ccflags-y += -DWMT_CREATE_NODE_DYNAMIC=0 + ccflags-y += -DREMOVE_MK_NODE=1 +endif + +ccflags-y += -I$(WMT_SRC_FOLDER)/common_main/include +ccflags-y += -I$(WMT_SRC_FOLDER)/common_main/linux/include +ccflags-y += -I$(WMT_SRC_FOLDER)/common_main/core/include +ccflags-y += -I$(WMT_SRC_FOLDER)/common_main/platform/include +ifneq ($(CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH),) +ccflags-y += -I$(WMT_SRC_FOLDER)/debug_utility +endif +ifeq ($(GPS_DRV_CONTROL_LNA),y) +ccflags-y += -I$(GPS_SRC_FOLDER)/lna_ctrl/inc +endif + +ifeq ($(CONFIG_MTK_CONN_MT3337_CHIP_SUPPORT),y) + $(MODULE_NAME)-objs += gps_mt3337.o +else + $(MODULE_NAME)-objs += stp_chrdev_gps.o +ifeq ($(CONFIG_ARCH_MTK_PROJECT),"k6833v1_64_swrgo") + $(MODULE_NAME)-objs += stp_chrdev_gps2.o +endif +ifeq ($(CONFIG_MACH_MT6833),y) + $(MODULE_NAME)-objs += stp_chrdev_gps2.o +endif +ifeq ($(GPS_DRV_CONTROL_LNA),y) + $(MODULE_NAME)-objs += lna_ctrl/src/gps_lna_drv.o +endif +endif +ifneq ($(CONFIG_MTK_GPS_EMI),) +$(MODULE_NAME)-objs += gps_emi.o +endif +ifneq ($(CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH),) +$(MODULE_NAME)-objs += fw_log_gps.o +endif + +endif + +endif #ifeq ($(CONFIG_MTK_GPS_SUPPORT), y) +# EOF diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/gps_dl_context.c b/drivers/misc/mediatek/connectivity/gps/data_link/gps_dl_context.c new file mode 100644 index 0000000000000000000000000000000000000000..9f4a6f311aa681ccf56d29b61f5ef3fe38b4be8a --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/gps_dl_context.c @@ -0,0 +1,252 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#include "gps_dl_config.h" +#include "gps_dl_context.h" +#include "gps_dl_hw_api.h" + +#if GPS_DL_ON_LINUX +#define GPS_DL_ISR_DATA0 gps_dl_linux_irq_dispatcher +#define GPS_DL_ISR_NODATA0 gps_dl_linux_irq_dispatcher +#define GPS_DL_ISR_MCUB0 gps_dl_linux_irq_dispatcher +#define GPS_DL_ISR_DATA1 gps_dl_linux_irq_dispatcher +#define GPS_DL_ISR_NODATA1 gps_dl_linux_irq_dispatcher +#define GPS_DL_ISR_MCUB1 gps_dl_linux_irq_dispatcher +#define GPS_DL_ISR_DMA gps_dl_linux_irq_dispatcher +#elif GPS_DL_ON_CTP +#define GPS_DL_ISR_DATA0 gps_dl_isr_dl0_has_data +#define GPS_DL_ISR_NODATA0 gps_dl_isr_dl0_has_nodata +#define GPS_DL_ISR_MCUB0 gps_dl_isr_dl0_mcub +#define GPS_DL_ISR_DATA1 gps_dl_isr_dl1_has_data +#define GPS_DL_ISR_NODATA1 gps_dl_isr_dl1_has_nodata +#define GPS_DL_ISR_MCUB1 gps_dl_isr_dl1_mcub +#define GPS_DL_ISR_DMA gps_dl_isr_dma_done +#endif + +static struct gps_dl_ctx s_gps_dl_ctx = { + .links = { + /* for /dev/gpsdl0 */ + {.cfg = {.tx_buf_size = GPS_DL_TX_BUF_SIZE, .rx_buf_size = GPS_DL_RX_BUF_SIZE} }, + + /* for /dev/gpsdl1 */ + {.cfg = {.tx_buf_size = GPS_DL_TX_BUF_SIZE, .rx_buf_size = GPS_DL_RX_BUF_SIZE} }, + }, + .irqs = { + {.cfg = {.index = GPS_DL_IRQ_LINK0_DATA, .name = "gps_da0", + .trig_type = GPS_DL_IRQ_TRIG_LEVEL_HIGH, + .isr = (void *)GPS_DL_ISR_DATA0} }, + {.cfg = {.index = GPS_DL_IRQ_LINK0_NODATA, .name = "gps_nd0", + .trig_type = GPS_DL_IRQ_TRIG_LEVEL_HIGH, + .isr = (void *)GPS_DL_ISR_NODATA0} }, + {.cfg = {.index = GPS_DL_IRQ_LINK0_MCUB, .name = "gps_mb0", + .trig_type = GPS_DL_IRQ_TRIG_LEVEL_HIGH, + .isr = (void *)GPS_DL_ISR_MCUB0} }, + {.cfg = {.index = GPS_DL_IRQ_LINK1_DATA, .name = "gps_da1", + .trig_type = GPS_DL_IRQ_TRIG_LEVEL_HIGH, + .isr = (void *)GPS_DL_ISR_DATA1} }, + {.cfg = {.index = GPS_DL_IRQ_LINK1_NODATA, .name = "gps_nd1", + .trig_type = GPS_DL_IRQ_TRIG_LEVEL_HIGH, + .isr = (void *)GPS_DL_ISR_NODATA1} }, + {.cfg = {.index = GPS_DL_IRQ_LINK1_MCUB, .name = "gps_mb1", + .trig_type = GPS_DL_IRQ_TRIG_LEVEL_HIGH, + .isr = (void *)GPS_DL_ISR_MCUB1} }, + {.cfg = {.index = GPS_DL_IRQ_DMA, .name = "gps_dma", + .trig_type = GPS_DL_IRQ_TRIG_LEVEL_HIGH, + .isr = (void *)GPS_DL_ISR_DMA} }, + }, +#if GPS_DL_ON_LINUX + .devices = { + /* for /dev/gpsdl0 */ + {.cfg = {.dev_name = "gpsdl0", .index = 0} }, + + /* for /dev/gpsdl1 */ + {.cfg = {.dev_name = "gpsdl1", .index = 1} }, + }, +#endif /* GPS_DL_ON_LINUX */ +}; + +static struct gps_dl_runtime_cfg s_gps_rt_cfg = { + .dma_is_1byte_mode = false, + .dma_is_enabled = true, + .show_reg_rw_log = false, + .show_reg_wait_log = true, + .only_show_wait_done_log = true, + .log_level = GPS_DL_LOG_DEF_SETTING_LEVEL, + .log_mod_bitmask = GPS_DL_LOG_DEF_SETTING_MODULES, + .log_reg_rw_bitmask = GPS_DL_LOG_REG_RW_BITMASK, +}; + +struct gps_each_link *gps_dl_link_get(enum gps_dl_link_id_enum link_id) +{ + if (link_id >= 0 && link_id < GPS_DATA_LINK_NUM) + return &s_gps_dl_ctx.links[link_id]; + + return NULL; +} + +struct gps_each_irq *gps_dl_irq_get(enum gps_dl_irq_index_enum irq_idx) +{ + if (irq_idx >= 0 && irq_idx < GPS_DL_IRQ_NUM) + return &s_gps_dl_ctx.irqs[irq_idx]; + + return NULL; +} + +#if GPS_DL_ON_LINUX +struct gps_each_device *gps_dl_device_get(enum gps_dl_link_id_enum link_id) +{ + if (link_id >= 0 && link_id < GPS_DATA_LINK_NUM) + return &s_gps_dl_ctx.devices[link_id]; + + return NULL; +} +#endif + +struct gps_dl_remap_ctx *gps_dl_remap_ctx_get(void) +{ + return &s_gps_dl_ctx.remap_ctx; +} + +bool gps_dl_is_1byte_mode(void) +{ + return s_gps_rt_cfg.dma_is_1byte_mode; +} + +bool gps_dl_set_1byte_mode(bool is_1byte_mode) +{ + bool old = s_gps_rt_cfg.dma_is_1byte_mode; + + s_gps_rt_cfg.dma_is_1byte_mode = is_1byte_mode; + return old; +} + +bool gps_dl_is_dma_enabled(void) +{ + return s_gps_rt_cfg.dma_is_enabled; +} + +bool gps_dl_set_dma_enabled(bool to_enable) +{ + bool old = s_gps_rt_cfg.dma_is_enabled; + + s_gps_rt_cfg.dma_is_enabled = to_enable; + return old; +} + +bool gps_dl_show_reg_rw_log(void) +{ + return s_gps_rt_cfg.show_reg_rw_log; +} + +bool gps_dl_show_reg_wait_log(void) +{ + return s_gps_rt_cfg.show_reg_wait_log; +} + +bool gps_dl_only_show_wait_done_log(void) +{ + return s_gps_rt_cfg.only_show_wait_done_log; +} + +bool gps_dl_set_show_reg_rw_log(bool on) +{ + bool last_on = s_gps_rt_cfg.show_reg_rw_log; + + s_gps_rt_cfg.show_reg_rw_log = on; + return last_on; +} + +void gps_dl_set_show_reg_wait_log(bool on) +{ + s_gps_rt_cfg.show_reg_wait_log = on; +} + +int gps_dl_set_rx_transfer_max(enum gps_dl_link_id_enum link_id, int max) +{ + struct gps_each_link *p_link; + int old_max = 0; + + p_link = gps_dl_link_get(link_id); + + if (p_link) { + old_max = p_link->rx_dma_buf.transfer_max; + p_link->rx_dma_buf.transfer_max = max; + GDL_LOGXD(link_id, "old_max = %d, new_max = %d", old_max, max); + } + + return old_max; +} + +int gps_dl_set_tx_transfer_max(enum gps_dl_link_id_enum link_id, int max) +{ + struct gps_each_link *p_link; + int old_max = 0; + + p_link = gps_dl_link_get(link_id); + + if (p_link) { + old_max = p_link->tx_dma_buf.transfer_max; + p_link->tx_dma_buf.transfer_max = max; + GDL_LOGXD(link_id, "old_max = %d, new_max = %d", old_max, max); + } + + return old_max; +} + +enum gps_dl_log_level_enum gps_dl_log_level_get(void) +{ + return s_gps_rt_cfg.log_level; +} + +void gps_dl_log_level_set(enum gps_dl_log_level_enum level) +{ + s_gps_rt_cfg.log_level = level; +} + +bool gps_dl_log_mod_is_on(enum gps_dl_log_module_enum mod) +{ + return (bool)(s_gps_rt_cfg.log_mod_bitmask & (1UL << mod)); +} + +void gps_dl_log_mod_on(enum gps_dl_log_module_enum mod) +{ + s_gps_rt_cfg.log_mod_bitmask |= (1UL << mod); +} + +void gps_dl_log_mod_off(enum gps_dl_log_module_enum mod) +{ + s_gps_rt_cfg.log_mod_bitmask &= ~(1UL << mod); +} + +void gps_dl_log_mod_bitmask_set(unsigned int bitmask) +{ + s_gps_rt_cfg.log_mod_bitmask = bitmask; +} + +unsigned int gps_dl_log_mod_bitmask_get(void) +{ + return s_gps_rt_cfg.log_mod_bitmask; +} + +bool gps_dl_log_reg_rw_is_on(enum gps_dl_log_reg_rw_ctrl_enum log_reg_rw) +{ + return (bool)(s_gps_rt_cfg.log_reg_rw_bitmask & (1UL << log_reg_rw)); +} + +void gps_dl_log_info_show(void) +{ + bool show_reg_rw_log = gps_dl_show_reg_rw_log(); + + GDL_LOGE("level = %d, bitmask = 0x%08x, rrw = %d", + s_gps_rt_cfg.log_level, s_gps_rt_cfg.log_mod_bitmask, show_reg_rw_log); +} + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/gps_each_link.c b/drivers/misc/mediatek/connectivity/gps/data_link/gps_each_link.c new file mode 100644 index 0000000000000000000000000000000000000000..109d8e41308f73031267cff48f627768db6d08e1 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/gps_each_link.c @@ -0,0 +1,1714 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#include "gps_dl_config.h" +#include "gps_dl_time_tick.h" + +#include "gps_each_link.h" +#include "gps_dl_hal.h" +#include "gps_dl_hal_api.h" +#include "gps_dl_hal_util.h" +#include "gps_dl_hw_api.h" +#include "gps_dl_isr.h" +#include "gps_dl_lib_misc.h" +#include "gps_dsp_fsm.h" +#include "gps_dl_osal.h" +#include "gps_dl_name_list.h" +#include "gps_dl_context.h" +#include "gps_dl_subsys_reset.h" + +#include "linux/jiffies.h" + +#include "linux/errno.h" +#if GPS_DL_HAS_PLAT_DRV +#include "gps_dl_linux_plat_drv.h" +#endif + +void gps_each_link_set_bool_flag(enum gps_dl_link_id_enum link_id, + enum gps_each_link_bool_state name, bool value) +{ + struct gps_each_link *p = gps_dl_link_get(link_id); + + if (!p) + return; + + gps_each_link_spin_lock_take(link_id, GPS_DL_SPINLOCK_FOR_LINK_STATE); + switch (name) { + case LINK_TO_BE_CLOSED: + p->sub_states.to_be_closed = value; + break; + case LINK_USER_OPEN: + p->sub_states.user_open = value; + break; + case LINK_OPEN_RESULT_OKAY: + p->sub_states.open_result_okay = value; + break; + case LINK_NEED_A2Z_DUMP: + p->sub_states.need_a2z_dump = value; + break; + case LINK_SUSPEND_TO_CLK_EXT: + p->sub_states.suspend_to_clk_ext = value; + break; + default: + break; /* do nothing */ + } + gps_each_link_spin_lock_give(link_id, GPS_DL_SPINLOCK_FOR_LINK_STATE); +} + +bool gps_each_link_get_bool_flag(enum gps_dl_link_id_enum link_id, + enum gps_each_link_bool_state name) +{ + struct gps_each_link *p = gps_dl_link_get(link_id); + bool value = false; + + if (!p) + return false; + + gps_each_link_spin_lock_take(link_id, GPS_DL_SPINLOCK_FOR_LINK_STATE); + switch (name) { + case LINK_TO_BE_CLOSED: + value = p->sub_states.to_be_closed; + break; + case LINK_USER_OPEN: + value = p->sub_states.user_open; + break; + case LINK_OPEN_RESULT_OKAY: + value = p->sub_states.open_result_okay; + break; + case LINK_NEED_A2Z_DUMP: + value = p->sub_states.need_a2z_dump; + break; + case LINK_SUSPEND_TO_CLK_EXT: + value = p->sub_states.suspend_to_clk_ext; + break; + default: + break; /* TODO: warning it */ + } + gps_each_link_spin_lock_give(link_id, GPS_DL_SPINLOCK_FOR_LINK_STATE); + + return value; +} + +void gps_dl_link_set_ready_to_write(enum gps_dl_link_id_enum link_id, bool is_ready) +{ + struct gps_each_link *p = gps_dl_link_get(link_id); + + gps_each_link_spin_lock_take(link_id, GPS_DL_SPINLOCK_FOR_LINK_STATE); + if (p) + p->sub_states.is_ready_to_write = is_ready; + gps_each_link_spin_lock_give(link_id, GPS_DL_SPINLOCK_FOR_LINK_STATE); +} + +bool gps_dl_link_is_ready_to_write(enum gps_dl_link_id_enum link_id) +{ + struct gps_each_link *p = gps_dl_link_get(link_id); + bool ready; + + gps_each_link_spin_lock_take(link_id, GPS_DL_SPINLOCK_FOR_LINK_STATE); + if (p) + ready = p->sub_states.is_ready_to_write; + else + ready = false; + gps_each_link_spin_lock_give(link_id, GPS_DL_SPINLOCK_FOR_LINK_STATE); + + return ready; +} + +void gps_each_link_set_active(enum gps_dl_link_id_enum link_id, bool is_active) +{ + struct gps_each_link *p = gps_dl_link_get(link_id); + + gps_each_link_spin_lock_take(link_id, GPS_DL_SPINLOCK_FOR_LINK_STATE); + if (p) + p->sub_states.is_active = is_active; + gps_each_link_spin_lock_give(link_id, GPS_DL_SPINLOCK_FOR_LINK_STATE); +} + +bool gps_each_link_is_active(enum gps_dl_link_id_enum link_id) +{ + struct gps_each_link *p = gps_dl_link_get(link_id); + bool ready; + + gps_each_link_spin_lock_take(link_id, GPS_DL_SPINLOCK_FOR_LINK_STATE); + if (p) + ready = p->sub_states.is_active; + else + ready = false; + gps_each_link_spin_lock_give(link_id, GPS_DL_SPINLOCK_FOR_LINK_STATE); + + return ready; +} + +void gps_each_link_inc_session_id(enum gps_dl_link_id_enum link_id) +{ + struct gps_each_link *p = gps_dl_link_get(link_id); + int sid; + + gps_each_link_spin_lock_take(link_id, GPS_DL_SPINLOCK_FOR_LINK_STATE); + if (p->session_id >= GPS_EACH_LINK_SID_MAX) + p->session_id = 1; + else + p->session_id++; + sid = p->session_id; + gps_each_link_spin_lock_give(link_id, GPS_DL_SPINLOCK_FOR_LINK_STATE); + + GDL_LOGXD(link_id, "new sid = %d, 1byte_mode = %d", sid, gps_dl_is_1byte_mode()); +} + +int gps_each_link_get_session_id(enum gps_dl_link_id_enum link_id) +{ + struct gps_each_link *p = gps_dl_link_get(link_id); + int sid; + + gps_each_link_spin_lock_take(link_id, GPS_DL_SPINLOCK_FOR_LINK_STATE); + sid = p->session_id; + gps_each_link_spin_lock_give(link_id, GPS_DL_SPINLOCK_FOR_LINK_STATE); + + return sid; +} + +void gps_dl_link_open_wait(enum gps_dl_link_id_enum link_id, long *p_sigval) +{ + struct gps_each_link *p = gps_dl_link_get(link_id); + enum GDL_RET_STATUS gdl_ret; + long sigval; + + gdl_ret = gps_dl_link_wait_on(&p->waitables[GPS_DL_WAIT_OPEN_CLOSE], &sigval); + if (gdl_ret == GDL_FAIL_SIGNALED) { + if (p_sigval != NULL) { + *p_sigval = sigval; + return; + } + } else if (gdl_ret == GDL_FAIL_NOT_SUPPORT) + ; /* show warnning */ +} + +void gps_dl_link_open_ack(enum gps_dl_link_id_enum link_id, bool okay, bool hw_resume) +{ +#if 0 + enum GDL_RET_STATUS gdl_ret; + struct gdl_dma_buf_entry dma_buf_entry; +#endif + struct gps_each_link *p = gps_dl_link_get(link_id); + bool send_msg = false; + + GDL_LOGXD_ONF(link_id, "hw_resume = %d", hw_resume); + + /* TODO: open fail case */ + gps_each_link_set_bool_flag(link_id, LINK_OPEN_RESULT_OKAY, okay); + gps_dl_link_wake_up(&p->waitables[GPS_DL_WAIT_OPEN_CLOSE]); + + gps_each_link_take_big_lock(link_id, GDL_LOCK_FOR_OPEN_DONE); + if (gps_each_link_get_bool_flag(link_id, LINK_USER_OPEN) && okay) { + GDL_LOGXW_ONF(link_id, + "user still online, try to change to opened"); + + /* Note: if pre_status not OPENING, it might be RESETTING, not handle it here */ + if (hw_resume) + gps_each_link_change_state_from(link_id, LINK_RESUMING, LINK_OPENED); + else + gps_each_link_change_state_from(link_id, LINK_OPENING, LINK_OPENED); + + /* TODO: ack on DSP reset done */ +#if 0 + /* if has pending data, can send it now */ + gdl_ret = gdl_dma_buf_get_data_entry(&p->tx_dma_buf, &dma_buf_entry); + if (gdl_ret == GDL_OKAY) + gps_dl_hal_a2d_tx_dma_start(link_id, &dma_buf_entry); +#endif + } else { + GDL_LOGXW_ONF(link_id, + "okay = %d or user already offline, try to change to closing", okay); + + /* Note: if pre_status not OPENING, it might be RESETTING, not handle it here */ + if (gps_each_link_change_state_from(link_id, LINK_OPENING, LINK_CLOSING)) + send_msg = true; + } + gps_each_link_give_big_lock(link_id); + + if (send_msg) { + gps_dl_link_event_send(GPS_DL_EVT_LINK_CLOSE, link_id); + gps_each_link_set_bool_flag(link_id, LINK_TO_BE_CLOSED, true); + } +} + +void gps_each_link_init(enum gps_dl_link_id_enum link_id) +{ + struct gps_each_link *p = gps_dl_link_get(link_id); + + p->session_id = 0; + gps_each_link_mutexes_init(p); + gps_each_link_spin_locks_init(p); + gps_each_link_set_active(link_id, false); + gps_dl_link_set_ready_to_write(link_id, false); + gps_each_link_context_init(link_id); + gps_each_link_set_state(link_id, LINK_CLOSED); +} + +void gps_each_link_deinit(enum gps_dl_link_id_enum link_id) +{ + struct gps_each_link *p = gps_dl_link_get(link_id); + + gps_each_link_set_state(link_id, LINK_UNINIT); + gps_each_link_mutexes_deinit(p); + gps_each_link_spin_locks_deinit(p); +} + +void gps_each_link_context_init(enum gps_dl_link_id_enum link_id) +{ + enum gps_each_link_waitable_type j; + + for (j = 0; j < GPS_DL_WAIT_NUM; j++) + gps_dl_link_waitable_reset(link_id, j); +} + +void gps_each_link_context_clear(enum gps_dl_link_id_enum link_id) +{ + gps_dl_link_waitable_reset(link_id, GPS_DL_WAIT_WRITE); + gps_dl_link_waitable_reset(link_id, GPS_DL_WAIT_READ); +} + +int gps_each_link_open(enum gps_dl_link_id_enum link_id) +{ + enum gps_each_link_state_enum state, state2; + enum GDL_RET_STATUS gdl_ret; + long sigval = 0; + bool okay; + int retval; +#if GPS_DL_ON_CTP + /* Todo: is it need on LINUX? */ + struct gps_each_link *p_link = gps_dl_link_get(link_id); + + gps_dma_buf_align_as_byte_mode(&p_link->tx_dma_buf); + gps_dma_buf_align_as_byte_mode(&p_link->rx_dma_buf); +#endif + +#if 0 +#if (GPS_DL_ON_LINUX && !GPS_DL_NO_USE_IRQ && !GPS_DL_HW_IS_MOCK) + if (!p_link->sub_states.irq_is_init_done) { + gps_dl_irq_init(); + p_link->sub_states.irq_is_init_done = true; + } +#endif +#endif + + state = gps_each_link_get_state(link_id); + + switch (state) { + case LINK_RESUMING: + case LINK_SUSPENDED: + case LINK_SUSPENDING: + retval = -EAGAIN; + break; + + case LINK_CLOSING: + case LINK_RESETTING: + case LINK_DISABLED: + retval = -EAGAIN; + break; + + case LINK_RESET_DONE: + /* RESET_DONE stands for user space not close me */ + retval = -EBUSY; /* twice open not allowed */ + break; + + case LINK_OPENED: + case LINK_OPENING: + retval = -EBUSY;; /* twice open not allowed */ + break; + + case LINK_CLOSED: + okay = gps_each_link_change_state_from(link_id, LINK_CLOSED, LINK_OPENING); + if (!okay) { + retval = -EBUSY; + break; + } + + /* TODO: simplify the flags */ + gps_each_link_set_bool_flag(link_id, LINK_TO_BE_CLOSED, false); + gps_each_link_set_bool_flag(link_id, LINK_USER_OPEN, true); + + gps_dl_link_waitable_reset(link_id, GPS_DL_WAIT_OPEN_CLOSE); + gps_dl_link_event_send(GPS_DL_EVT_LINK_OPEN, link_id); + gps_dl_link_open_wait(link_id, &sigval); + + /* TODO: Check this mutex can be removed? + * the possible purpose is make it's atomic from LINK_USER_OPEN and LINK_OPEN_RESULT_OKAY. + */ + gps_each_link_take_big_lock(link_id, GDL_LOCK_FOR_OPEN); + if (sigval != 0) { + gps_each_link_set_bool_flag(link_id, LINK_USER_OPEN, false); + + gdl_ret = gps_dl_link_try_wait_on(link_id, GPS_DL_WAIT_OPEN_CLOSE); + if (gdl_ret == GDL_OKAY) { + okay = gps_each_link_change_state_from(link_id, LINK_OPENED, LINK_CLOSING); + + /* Change okay, need to send event to trigger close */ + if (okay) { + gps_each_link_give_big_lock(link_id); + gps_dl_link_event_send(GPS_DL_EVT_LINK_CLOSE, link_id); + GDL_LOGXW_ONF(link_id, + "sigval = %ld, corner case 1: close it", sigval); + retval = -EBUSY; + break; + } + + /* Not change okay, state maybe RESETTING or RESET_DONE */ + state2 = gps_each_link_get_state(link_id); + if (state2 == LINK_RESET_DONE) + gps_each_link_set_state(link_id, LINK_CLOSED); + + gps_each_link_give_big_lock(link_id); + GDL_LOGXW_ONF(link_id, "sigval = %ld, corner case 2: %s", + sigval, gps_dl_link_state_name(state2)); + retval = -EBUSY; + break; + } + + gps_each_link_give_big_lock(link_id); + GDL_LOGXW_ONF(link_id, "sigval = %ld, normal case", sigval); + retval = -EINVAL; + break; + } + + okay = gps_each_link_get_bool_flag(link_id, LINK_OPEN_RESULT_OKAY); + gps_each_link_give_big_lock(link_id); + + if (okay) + retval = 0; + else { + gps_each_link_set_bool_flag(link_id, LINK_USER_OPEN, false); + retval = -EBUSY; + } + break; + + default: + retval = -EINVAL; + break; + } + + if (retval == 0) { + GDL_LOGXD_ONF(link_id, "prev_state = %s, retval = %d", + gps_dl_link_state_name(state), retval); + } else { + GDL_LOGXW_ONF(link_id, "prev_state = %s, retval = %d", + gps_dl_link_state_name(state), retval); + } + + return retval; +} + +int gps_each_link_reset(enum gps_dl_link_id_enum link_id) +{ + /* + * - set each link resetting flag + */ + enum gps_each_link_state_enum state, state2; + bool okay; + int retval; + + state = gps_each_link_get_state(link_id); + + switch (state) { + case LINK_OPENING: + case LINK_CLOSING: + case LINK_CLOSED: + case LINK_DISABLED: + retval = -EBUSY; + break; + + case LINK_RESETTING: + case LINK_RESET_DONE: + retval = 0; + break; + + case LINK_RESUMING: + case LINK_SUSPENDING: + case LINK_SUSPENDED: + case LINK_OPENED: +_try_change_to_reset_again: + okay = gps_each_link_change_state_from(link_id, state, LINK_RESETTING); + if (!okay) { + state2 = gps_each_link_get_state(link_id); + + /* Already reset or close, not trigger reseeting again */ + GDL_LOGXW_ONF(link_id, "state flip to %s - corner case", + gps_dl_link_state_name(state2)); + + /* -ing state may become -ed state, try change to reset again */ + if ((state == LINK_SUSPENDING && state2 == LINK_SUSPENDED) || + (state == LINK_RESUMING && state2 == LINK_OPENED)) { + state = state2; + goto _try_change_to_reset_again; + } + + if (state2 == LINK_RESETTING || state2 == LINK_RESET_DONE) + retval = 0; + else + retval = -EBUSY; + break; + } + + gps_each_link_set_bool_flag(link_id, LINK_IS_RESETTING, true); + + /* no need to wait reset ack + * TODO: make sure message send okay + */ + gps_dl_link_waitable_reset(link_id, GPS_DL_WAIT_RESET); + gps_dl_link_event_send(GPS_DL_EVT_LINK_RESET_DSP, link_id); + retval = 0; + break; + + default: + retval = -EINVAL; + break; + } + + /* wait until cttld thread ack the status */ + if (retval == 0) { + GDL_LOGXD_ONF(link_id, "prev_state = %s, retval = %d", + gps_dl_link_state_name(state), retval); + } else { + GDL_LOGXW_ONF(link_id, "prev_state = %s, retval = %d", + gps_dl_link_state_name(state), retval); + } + + return retval; +} + +void gps_dl_ctrld_set_resest_status(void) +{ + gps_each_link_set_active(GPS_DATA_LINK_ID0, false); + gps_each_link_set_active(GPS_DATA_LINK_ID1, false); +} + +void gps_dl_link_reset_ack_inner(enum gps_dl_link_id_enum link_id, bool post_conn_reset) +{ + struct gps_each_link *p = gps_dl_link_get(link_id); + enum gps_each_link_state_enum old_state, new_state; + enum gps_each_link_reset_level old_level, new_level; + bool user_still_open; + bool both_clear_done = false; + bool try_conn_infra_off = false; + + gps_each_link_take_big_lock(link_id, GDL_LOCK_FOR_RESET_DONE); + gps_each_link_spin_lock_take(link_id, GPS_DL_SPINLOCK_FOR_LINK_STATE); + old_state = p->state_for_user; + old_level = p->reset_level; + user_still_open = p->sub_states.user_open; + + switch (old_level) { + case GPS_DL_RESET_LEVEL_GPS_SINGLE_LINK: + p->reset_level = GPS_DL_RESET_LEVEL_NONE; + if (p->sub_states.user_open) + p->state_for_user = LINK_RESET_DONE; + else + p->state_for_user = LINK_CLOSED; + break; + + case GPS_DL_RESET_LEVEL_CONNSYS: + if (!post_conn_reset) + break; + p->reset_level = GPS_DL_RESET_LEVEL_NONE; + both_clear_done = gps_dl_link_try_to_clear_both_resetting_status(); + try_conn_infra_off = true; + break; + + case GPS_DL_RESET_LEVEL_GPS_SUBSYS: + p->reset_level = GPS_DL_RESET_LEVEL_NONE; + both_clear_done = gps_dl_link_try_to_clear_both_resetting_status(); + break; + + default: + break; + } + + new_state = p->state_for_user; + new_level = p->reset_level; + gps_each_link_spin_lock_give(link_id, GPS_DL_SPINLOCK_FOR_LINK_STATE); + + if (try_conn_infra_off) { + /* During connsys resetting, conninfra_pwr_off may fail, + * it need to be called again when connsys reset done. + */ + gps_dl_hal_conn_infra_driver_off(); + } + + /* TODO: if both clear, show another link's log */ + GDL_LOGXE_STA(link_id, + "state change: %s -> %s, level: %d -> %d, user = %d, post_reset = %d, both_clear = %d", + gps_dl_link_state_name(old_state), gps_dl_link_state_name(new_state), + old_level, new_level, + user_still_open, post_conn_reset, both_clear_done); + + gps_each_link_give_big_lock(link_id); + + /* Note: for CONNSYS or GPS_SUBSYS RESET, here might be still RESETTING, + * if any other link not reset done (see both_clear_done print). + */ + gps_dl_link_wake_up(&p->waitables[GPS_DL_WAIT_RESET]); +} + +bool gps_dl_link_try_to_clear_both_resetting_status(void) +{ + enum gps_dl_link_id_enum link_id; + struct gps_each_link *p; + + for (link_id = 0; link_id < GPS_DATA_LINK_NUM; link_id++) { + p = gps_dl_link_get(link_id); + if (p->reset_level != GPS_DL_RESET_LEVEL_NONE) + return false; + } + + for (link_id = 0; link_id < GPS_DATA_LINK_NUM; link_id++) { + p = gps_dl_link_get(link_id); + + if (p->sub_states.user_open) + p->state_for_user = LINK_RESET_DONE; + else + p->state_for_user = LINK_CLOSED; + } + + return true; +} + +void gps_dl_link_reset_ack(enum gps_dl_link_id_enum link_id) +{ + gps_dl_link_reset_ack_inner(link_id, false); +} + +void gps_dl_link_on_post_conn_reset(enum gps_dl_link_id_enum link_id) +{ + gps_dl_link_reset_ack_inner(link_id, true); +} + +void gps_dl_link_close_wait(enum gps_dl_link_id_enum link_id, long *p_sigval) +{ + struct gps_each_link *p = gps_dl_link_get(link_id); + enum GDL_RET_STATUS gdl_ret; + long sigval; + + gdl_ret = gps_dl_link_wait_on(&p->waitables[GPS_DL_WAIT_OPEN_CLOSE], &sigval); + if (gdl_ret == GDL_FAIL_SIGNALED) { + if (p_sigval != NULL) { + *p_sigval = sigval; + return; + } + } else if (gdl_ret == GDL_FAIL_NOT_SUPPORT) + ; /* show warnning */ +} + +void gps_dl_link_close_ack(enum gps_dl_link_id_enum link_id, bool hw_suspend) +{ + struct gps_each_link *p = gps_dl_link_get(link_id); + + GDL_LOGXD_ONF(link_id, "hw_suspend = %d", hw_suspend); + gps_dl_link_wake_up(&p->waitables[GPS_DL_WAIT_OPEN_CLOSE]); + + gps_each_link_take_big_lock(link_id, GDL_LOCK_FOR_CLOSE_DONE); + + /* gps_each_link_set_state(link_id, LINK_CLOSED); */ + /* For case of reset_done */ + if (hw_suspend) { + gps_each_link_change_state_from(link_id, LINK_SUSPENDING, LINK_SUSPENDED); + /* TODO */ + } else + gps_each_link_change_state_from(link_id, LINK_CLOSING, LINK_CLOSED); + + gps_each_link_give_big_lock(link_id); +} + +int gps_each_link_close_or_suspend_inner(enum gps_dl_link_id_enum link_id, + enum gps_each_link_state_enum state, + enum gps_each_link_close_or_suspend_op close_or_suspend_op) +{ + enum gps_each_link_state_enum state2; + bool okay; + int retval = 0; + bool hw_suspend; + + hw_suspend = !!(close_or_suspend_op == GDL_DPSTOP || close_or_suspend_op == GDL_CLKEXT); + gps_each_link_take_big_lock(link_id, GDL_LOCK_FOR_CLOSE); + do { + if (hw_suspend) { + okay = gps_each_link_change_state_from(link_id, LINK_OPENED, LINK_SUSPENDING); + if (!okay) { + state2 = gps_each_link_get_state(link_id); + gps_each_link_give_big_lock(link_id); + GDL_LOGXW_ONF(link_id, "state check: %s, return hw suspend fail", + gps_dl_link_state_name(state2)); + retval = -EINVAL; + break; + } + + gps_each_link_set_bool_flag(link_id, + LINK_SUSPEND_TO_CLK_EXT, close_or_suspend_op == GDL_CLKEXT); + } else { + if (state == LINK_SUSPENDED) { + okay = gps_each_link_change_state_from( + link_id, LINK_SUSPENDED, LINK_CLOSING); + } else { + okay = gps_each_link_change_state_from( + link_id, LINK_OPENED, LINK_CLOSING); + } + gps_each_link_set_bool_flag(link_id, LINK_USER_OPEN, false); + if (!okay) { + state2 = gps_each_link_get_state(link_id); + if (state2 == LINK_RESET_DONE) + gps_each_link_set_state(link_id, LINK_CLOSED); + else { + GDL_LOGXW_ONF(link_id, "state check: %s, return close ok", + gps_dl_link_state_name(state2)); + } + gps_each_link_give_big_lock(link_id); + retval = 0; + break; + } + } + gps_each_link_give_big_lock(link_id); + } while (0); + return retval; +} + +int gps_each_link_close_or_suspend(enum gps_dl_link_id_enum link_id, + enum gps_each_link_close_or_suspend_op close_or_suspend_op) +{ + enum gps_each_link_state_enum state; + long sigval = 0; + int retval; + bool hw_suspend; + + state = gps_each_link_get_state(link_id); + hw_suspend = !!(close_or_suspend_op == GDL_DPSTOP || close_or_suspend_op == GDL_CLKEXT); + + switch (state) { + case LINK_OPENING: + case LINK_CLOSING: + case LINK_CLOSED: + case LINK_DISABLED: + /* twice close */ + /* TODO: show user open flag */ + retval = -EINVAL; + break; + + case LINK_SUSPENDING: + case LINK_RESUMING: + case LINK_RESETTING: + if (hw_suspend) { + if (state == LINK_SUSPENDING) + retval = 0; + else if (state == LINK_RESUMING) + retval = -EBUSY; + else + retval = -EINVAL; + break; + } + + /* close on xxx-ing states: just recording user is not online + * ctrld will handle it on the end of xxx-ing handling + */ + gps_each_link_set_bool_flag(link_id, LINK_USER_OPEN, false); + GDL_LOGXE_ONF(link_id, "state check: %s, return close ok", gps_dl_link_state_name(state)); + /* return okay to avoid twice close */ + retval = 0; + break; + + case LINK_RESET_DONE: + if (hw_suspend) { + retval = -EINVAL; + break; + } + gps_each_link_set_bool_flag(link_id, LINK_USER_OPEN, false); + gps_each_link_set_state(link_id, LINK_CLOSED); + retval = 0; + break; + + case LINK_SUSPENDED: + case LINK_OPENED: + retval = gps_each_link_close_or_suspend_inner(link_id, state, close_or_suspend_op); + if (retval != 0) + break; + + /* clean the done(fired) flag before send and wait */ + gps_dl_link_waitable_reset(link_id, GPS_DL_WAIT_OPEN_CLOSE); + if (hw_suspend) + gps_dl_link_event_send(GPS_DL_EVT_LINK_ENTER_DPSTOP, link_id); + else + gps_dl_link_event_send(GPS_DL_EVT_LINK_CLOSE, link_id); + + /* set this status, hal proc will by pass the message from the link + * it can make LINK_CLOSE be processed faster + */ + gps_each_link_set_bool_flag(link_id, LINK_TO_BE_CLOSED, true); + gps_dl_link_close_wait(link_id, &sigval); + + if (sigval) { + retval = -EINVAL; + break; + } + + retval = 0; + break; + default: + retval = -EINVAL; + break; + } + + if (retval == 0) { + GDL_LOGXD_ONF(link_id, "prev_state = %s, retval = %d, op = %d", + gps_dl_link_state_name(state), retval, close_or_suspend_op); + } else { + GDL_LOGXW_ONF(link_id, "prev_state = %s, retval = %d, op = %d", + gps_dl_link_state_name(state), retval, close_or_suspend_op); + } + + return retval; +} + +int gps_each_link_close(enum gps_dl_link_id_enum link_id) +{ + return gps_each_link_close_or_suspend(link_id, GDL_CLOSE); +} +int gps_each_link_check(enum gps_dl_link_id_enum link_id, int reason) +{ + enum gps_each_link_state_enum state; + enum gps_dl_link_event_id event; + int retval = 0; + + state = gps_each_link_get_state(link_id); + + switch (state) { + case LINK_OPENING: + case LINK_CLOSING: + case LINK_CLOSED: + case LINK_DISABLED: + break; + + case LINK_RESETTING: +#if 0 + if (rstflag == 1) { + /* chip resetting */ + retval = -888; + } else if (rstflag == 2) { + /* chip reset end */ + retval = -889; + } else { + /* normal */ + retval = 0; + } +#endif + retval = -888; + break; + + case LINK_RESET_DONE: + retval = 889; + break; + + case LINK_RESUMING: + case LINK_SUSPENDING: + case LINK_SUSPENDED: + case LINK_OPENED: + if (reason == 2) + event = GPS_DL_EVT_LINK_PRINT_HW_STATUS; + else if (reason == 4) + event = GPS_DL_EVT_LINK_PRINT_DATA_STATUS; + else + break; + + /* if L1 trigger it, also print L5 status + * for this case, dump L5 firstly. + */ + if (link_id == GPS_DATA_LINK_ID0) + gps_dl_link_event_send(event, GPS_DATA_LINK_ID1); + + gps_dl_link_event_send(event, link_id); + break; + + default: + break; + } + + GDL_LOGXW_ONF(link_id, "prev_state = %s, reason = %d, retval = %d", + gps_dl_link_state_name(state), reason, retval); + + return retval; +} + +int gps_each_link_enter_dsleep(enum gps_dl_link_id_enum link_id) +{ + struct gps_each_link *p_link = gps_dl_link_get(link_id); + + gps_dl_link_event_send(GPS_DL_EVT_LINK_ENTER_DPSLEEP, link_id); + gps_dma_buf_reset(&p_link->tx_dma_buf); + gps_dma_buf_reset(&p_link->rx_dma_buf); + return 0; +} + +int gps_each_link_leave_dsleep(enum gps_dl_link_id_enum link_id) +{ +#if GPS_DL_ON_CTP + struct gps_each_link *p_link = gps_dl_link_get(link_id); + + gps_dma_buf_align_as_byte_mode(&p_link->tx_dma_buf); + gps_dma_buf_align_as_byte_mode(&p_link->rx_dma_buf); +#endif + gps_dl_link_event_send(GPS_DL_EVT_LINK_LEAVE_DPSLEEP, link_id); + return 0; +} + + +int gps_each_link_hw_suspend(enum gps_dl_link_id_enum link_id, bool need_clk_ext) +{ + enum gps_each_link_close_or_suspend_op op; + + if (need_clk_ext) + op = GDL_CLKEXT; + else + op = GDL_DPSTOP; + return gps_each_link_close_or_suspend(link_id, op); +} + +int gps_each_link_hw_resume(enum gps_dl_link_id_enum link_id) +{ + enum gps_each_link_state_enum state; + long sigval = 0; + bool okay; + int retval; +#if GPS_DL_ON_CTP + struct gps_each_link *p_link = gps_dl_link_get(link_id); +#endif + + state = gps_each_link_get_state(link_id); + do { + if (state != LINK_SUSPENDED) { + retval = -EINVAL; + break; + } + + okay = gps_each_link_change_state_from(link_id, LINK_SUSPENDED, LINK_RESUMING); + if (!okay) { + retval = -EBUSY; + break; + } + + gps_each_link_set_bool_flag(link_id, LINK_TO_BE_CLOSED, false); + gps_dl_link_waitable_reset(link_id, GPS_DL_WAIT_OPEN_CLOSE); +#if GPS_DL_ON_CTP + gps_dma_buf_align_as_byte_mode(&p_link->tx_dma_buf); + gps_dma_buf_align_as_byte_mode(&p_link->rx_dma_buf); +#endif + gps_dl_link_event_send(GPS_DL_EVT_LINK_LEAVE_DPSTOP, link_id); + gps_dl_link_open_wait(link_id, &sigval); + if (sigval != 0) { + GDL_LOGXW_ONF(link_id, "sigval = %ld", sigval); + retval = -EBUSY; + break; + } + + okay = gps_each_link_get_bool_flag(link_id, LINK_OPEN_RESULT_OKAY); + if (okay) + retval = 0; + else + retval = -EBUSY; + } while (0); + + if (retval == 0) { + GDL_LOGXD_ONF(link_id, "prev_state = %s, retval = %d", + gps_dl_link_state_name(state), retval); + } else { + GDL_LOGXW_ONF(link_id, "prev_state = %s, retval = %d", + gps_dl_link_state_name(state), retval); + } + return retval; +} + +void gps_dl_link_waitable_init(struct gps_each_link_waitable *p, + enum gps_each_link_waitable_type type) +{ + p->type = type; + p->fired = false; +#if GPS_DL_ON_LINUX + init_waitqueue_head(&p->wq); +#endif +} + +void gps_dl_link_waitable_reset(enum gps_dl_link_id_enum link_id, enum gps_each_link_waitable_type type) +{ + struct gps_each_link *p_link = gps_dl_link_get(link_id); + + /* TOOD: check NULL and boundary */ + p_link->waitables[type].fired = false; +} + +#define GDL_TEST_TRUE_AND_SET_FALSE(x, x_old) \ + do { \ + x_old = x; \ + if (x_old) { \ + x = false; \ + } } while (0) + +#define GDL_TEST_FALSE_AND_SET_TRUE(x, x_old) \ + do { \ + x_old = x; \ + if (!x_old) { \ + x = true; \ + } } while (0) + +enum GDL_RET_STATUS gps_dl_link_wait_on(struct gps_each_link_waitable *p, long *p_sigval) +{ +#if GPS_DL_ON_LINUX + long val; + bool is_fired; + + p->waiting = true; + /* TODO: check race conditions? */ + GDL_TEST_TRUE_AND_SET_FALSE(p->fired, is_fired); + if (is_fired) { + GDL_LOGD("waitable = %s, no wait return", gps_dl_waitable_type_name(p->type)); + p->waiting = false; + return GDL_OKAY; + } + + GDL_LOGD("waitable = %s, wait start", gps_dl_waitable_type_name(p->type)); + val = wait_event_interruptible(p->wq, p->fired); + p->waiting = false; + + if (val) { + GDL_LOGI("signaled by %ld", val); + if (p_sigval) + *p_sigval = val; + p->waiting = false; + return GDL_FAIL_SIGNALED; + } + + p->fired = false; + p->waiting = false; + GDL_LOGD("waitable = %s, wait done", gps_dl_waitable_type_name(p->type)); + return GDL_OKAY; +#else + return GDL_FAIL_NOT_SUPPORT; +#endif +} + +enum GDL_RET_STATUS gps_dl_link_try_wait_on(enum gps_dl_link_id_enum link_id, + enum gps_each_link_waitable_type type) +{ + struct gps_each_link *p_link; + struct gps_each_link_waitable *p; + bool is_fired; + + p_link = gps_dl_link_get(link_id); + p = &p_link->waitables[type]; + + GDL_TEST_TRUE_AND_SET_FALSE(p->fired, is_fired); + if (is_fired) { + GDL_LOGD("waitable = %s, okay", gps_dl_waitable_type_name(p->type)); + p->waiting = false; + return GDL_OKAY; + } + + return GDL_FAIL; +} + +void gps_dl_link_wake_up(struct gps_each_link_waitable *p) +{ + bool is_fired; + + ASSERT_NOT_NULL(p, GDL_VOIDF()); + + if (!p->waiting) { + if (p->type == GPS_DL_WAIT_WRITE || p->type == GPS_DL_WAIT_READ) { + /* normal case for read/write, not show warning */ + GDL_LOGD("waitable = %s, nobody waiting", + gps_dl_waitable_type_name(p->type)); + } else { + /* not return, just show warning */ + GDL_LOGW("waitable = %s, nobody waiting", + gps_dl_waitable_type_name(p->type)); + } + } + + GDL_TEST_FALSE_AND_SET_TRUE(p->fired, is_fired); + GDL_LOGD("waitable = %s, fired = %d", gps_dl_waitable_type_name(p->type), is_fired); + + if (!is_fired) { +#if GPS_DL_ON_LINUX + wake_up(&p->wq); +#else +#endif + } +} + +/* TODO: determine return value type */ +int gps_each_link_write(enum gps_dl_link_id_enum link_id, + unsigned char *buf, unsigned int len) +{ + return gps_each_link_write_with_opt(link_id, buf, len, true); +} + +#define GPS_DL_READ_SHOW_BUF_MAX_LEN (32) +int gps_each_link_write_with_opt(enum gps_dl_link_id_enum link_id, + unsigned char *buf, unsigned int len, bool wait_tx_done) +{ + struct gps_each_link *p = gps_dl_link_get(link_id); + enum GDL_RET_STATUS gdl_ret; + long sigval = 0; + + if (NULL == p) + return -1; + + if (len > p->tx_dma_buf.len) + return -1; + + if (gps_each_link_get_state(link_id) != LINK_OPENED) { + GDL_LOGXW_DRW(link_id, "not opened, drop the write data len = %d", len); + return -EBUSY; + } + + if (len <= GPS_DL_READ_SHOW_BUF_MAX_LEN) + gps_dl_hal_show_buf("wr_buf", buf, len); + else + GDL_LOGXD_DRW(link_id, "wr_buf, len = %d", len); + + while (1) { + gdl_ret = gdl_dma_buf_put(&p->tx_dma_buf, buf, len); + + if (gdl_ret == GDL_OKAY) { + gps_dl_link_event_send(GPS_DL_EVT_LINK_WRITE, link_id); +#if (GPS_DL_NO_USE_IRQ == 1) + if (wait_tx_done) { + do { + gps_dl_hal_a2d_tx_dma_wait_until_done_and_stop_it( + link_id, GPS_DL_RW_NO_TIMEOUT, false); + gps_dl_hal_event_send(GPS_DL_HAL_EVT_A2D_TX_DMA_DONE, link_id); + /* for case tx transfer_max > 0, GPS_DL_HAL_EVT_A2D_TX_DMA_DONE may */ + /* start anthor dma session again, need to loop again until all data done */ + } while (!gps_dma_buf_is_empty(&p->tx_dma_buf)); + } +#endif + return 0; + } else if (gdl_ret == GDL_FAIL_NOSPACE || gdl_ret == GDL_FAIL_BUSY || + gdl_ret == GDL_FAIL_NOENTRY) { + /* TODO: */ + /* 1. note: BUSY stands for others thread is do write, it should be impossible */ + /* - If wait on BUSY, should wake up the waitings or return eno_again? */ + /* 2. note: NOSPACE stands for need wait for tx dma working done */ + gps_dma_buf_show(&p->tx_dma_buf, false); + GDL_LOGXD(link_id, + "wait due to gdl_dma_buf_put ret = %s", gdl_ret_to_name(gdl_ret)); + gdl_ret = gps_dl_link_wait_on(&p->waitables[GPS_DL_WAIT_WRITE], &sigval); + if (gdl_ret == GDL_FAIL_SIGNALED) + break; + } else { + gps_dma_buf_show(&p->tx_dma_buf, true); + GDL_LOGXW(link_id, + "fail due to gdl_dma_buf_put ret = %s", gdl_ret_to_name(gdl_ret)); + break; + } + } + + return -1; +} + +int gps_each_link_read(enum gps_dl_link_id_enum link_id, + unsigned char *buf, unsigned int len) { + return gps_each_link_read_with_timeout(link_id, buf, len, GPS_DL_RW_NO_TIMEOUT, NULL); +} + +int gps_each_link_read_with_timeout(enum gps_dl_link_id_enum link_id, + unsigned char *buf, unsigned int len, int timeout_usec, bool *p_is_nodata) +{ + struct gps_each_link *p = gps_dl_link_get(link_id); + enum GDL_RET_STATUS gdl_ret; +#if (GPS_DL_NO_USE_IRQ == 0) + long sigval = 0; +#endif + unsigned int data_len; + + if (NULL == p) + return -1; + + while (1) { + gdl_ret = gdl_dma_buf_get(&p->rx_dma_buf, buf, len, &data_len, p_is_nodata); + + if (gdl_ret == GDL_OKAY) { + if (data_len <= GPS_DL_READ_SHOW_BUF_MAX_LEN) + gps_dl_hal_show_buf("rd_buf", buf, data_len); + else + GDL_LOGXD_DRW(link_id, "rd_buf, len = %d", data_len); + + gps_each_link_spin_lock_take(link_id, GPS_DL_SPINLOCK_FOR_DMA_BUF); + if (p->rx_dma_buf.has_pending_rx) { + p->rx_dma_buf.has_pending_rx = false; + gps_each_link_spin_lock_give(link_id, GPS_DL_SPINLOCK_FOR_DMA_BUF); + + GDL_LOGXI_DRW(link_id, "has pending rx, trigger again"); + gps_dl_hal_event_send(GPS_DL_HAL_EVT_D2A_RX_HAS_DATA, link_id); + } else + gps_each_link_spin_lock_give(link_id, GPS_DL_SPINLOCK_FOR_DMA_BUF); + + return data_len; + } else if (gdl_ret == GDL_FAIL_NODATA) { + GDL_LOGXD_DRW(link_id, "gdl_dma_buf_get no data and wait"); +#if (GPS_DL_NO_USE_IRQ == 1) + gdl_ret = gps_dl_hal_wait_and_handle_until_usrt_has_data( + link_id, timeout_usec); + if (gdl_ret == GDL_FAIL_TIMEOUT) + return -1; + + gdl_ret = gps_dl_hal_wait_and_handle_until_usrt_has_nodata_or_rx_dma_done( + link_id, timeout_usec, true); + if (gdl_ret == GDL_FAIL_TIMEOUT) + return -1; + continue; +#else + gdl_ret = gps_dl_link_wait_on(&p->waitables[GPS_DL_WAIT_READ], &sigval); + if (gdl_ret == GDL_FAIL_SIGNALED || gdl_ret == GDL_FAIL_NOT_SUPPORT) + return -1; +#endif + } else { + GDL_LOGXW_DRW(link_id, "gdl_dma_buf_get fail %s", gdl_ret_to_name(gdl_ret)); + return -1; + } + } + + return 0; +} + +void gps_dl_link_event_send(enum gps_dl_link_event_id evt, + enum gps_dl_link_id_enum link_id) +{ +#if (GPS_DL_HAS_CTRLD == 0) + gps_dl_link_event_proc(evt, link_id); +#else + { + struct gps_dl_osal_lxop *pOp; + struct gps_dl_osal_signal *pSignal; + int iRet; + + pOp = gps_dl_get_free_op(); + if (!pOp) + return; + + pSignal = &pOp->signal; + pSignal->timeoutValue = 0;/* send data need to wait ?ms */ + if (link_id < GPS_DATA_LINK_NUM) { + pOp->op.opId = GPS_DL_OPID_LINK_EVENT_PROC; + pOp->op.au4OpData[0] = link_id; + pOp->op.au4OpData[1] = evt; + iRet = gps_dl_put_act_op(pOp); + } else { + gps_dl_put_op_to_free_queue(pOp); + /*printf error msg*/ + return; + } + } +#endif +} + +void gps_dl_link_irq_set(enum gps_dl_link_id_enum link_id, bool enable) +{ + struct gps_each_link *p_link = gps_dl_link_get(link_id); + bool dma_working, pending_rx; + bool bypass_unmask_irq; + + if (enable) { + gps_dl_irq_each_link_unmask(link_id, GPS_DL_IRQ_TYPE_HAS_DATA, GPS_DL_IRQ_CTRL_FROM_THREAD); + gps_dl_irq_each_link_unmask(link_id, GPS_DL_IRQ_TYPE_HAS_NODATA, GPS_DL_IRQ_CTRL_FROM_THREAD); + + /* check if MCUB ROM ready */ + if (gps_dl_test_mask_mcub_irq_on_open_get(link_id)) { + GDL_LOGXE(link_id, "test mask mcub irq, not unmask irq and wait reset"); + gps_dl_hal_set_mcub_irq_dis_flag(link_id, true); + gps_dl_test_mask_mcub_irq_on_open_set(link_id, false); + } else if (!gps_dl_hal_mcub_flag_handler(link_id)) { + GDL_LOGXE(link_id, "mcub_flag_handler not okay, not unmask irq and wait reset"); + gps_dl_hal_set_mcub_irq_dis_flag(link_id, true); + } else { + gps_dl_irq_each_link_unmask(link_id, + GPS_DL_IRQ_TYPE_MCUB, GPS_DL_IRQ_CTRL_FROM_THREAD); + } + } else { + if (gps_dl_hal_get_mcub_irq_dis_flag(link_id)) { + GDL_LOGXW(link_id, "mcub irq already disable, bypass mask irq"); + gps_dl_hal_set_mcub_irq_dis_flag(link_id, false); + } else { + gps_dl_irq_each_link_mask(link_id, + GPS_DL_IRQ_TYPE_MCUB, GPS_DL_IRQ_CTRL_FROM_THREAD); + } + + bypass_unmask_irq = false; + if (gps_dl_hal_get_irq_dis_flag(link_id, GPS_DL_IRQ_TYPE_HAS_DATA)) { + GDL_LOGXW(link_id, "hasdata irq already disable, bypass mask irq"); + gps_dl_hal_set_irq_dis_flag(link_id, GPS_DL_IRQ_TYPE_HAS_DATA, false); + bypass_unmask_irq = true; + } + + gps_each_link_spin_lock_take(link_id, GPS_DL_SPINLOCK_FOR_DMA_BUF); + dma_working = p_link->rx_dma_buf.dma_working_entry.is_valid; + pending_rx = p_link->rx_dma_buf.has_pending_rx; + if (dma_working || pending_rx) { + p_link->rx_dma_buf.has_pending_rx = false; + gps_each_link_spin_lock_give(link_id, GPS_DL_SPINLOCK_FOR_DMA_BUF); + + /* It means this irq has already masked, */ + /* DON'T mask again, otherwise twice unmask might be needed */ + GDL_LOGXW(link_id, + "has dma_working = %d, pending rx = %d, bypass mask irq", + dma_working, pending_rx); + } else { + gps_each_link_spin_lock_give(link_id, GPS_DL_SPINLOCK_FOR_DMA_BUF); + if (!bypass_unmask_irq) { + gps_dl_irq_each_link_mask(link_id, + GPS_DL_IRQ_TYPE_HAS_DATA, GPS_DL_IRQ_CTRL_FROM_THREAD); + } + } + + /* TODO: avoid twice mask need to be handled if HAS_CTRLD */ + gps_dl_irq_each_link_mask(link_id, GPS_DL_IRQ_TYPE_HAS_NODATA, GPS_DL_IRQ_CTRL_FROM_THREAD); + } +} + +void gps_dl_link_pre_off_setting(enum gps_dl_link_id_enum link_id) +{ + /* + * The order is important: + * 1. disallow write, avoiding to start dma + * 2. stop tx/rx dma and mask dma irq if it is last link + * 3. mask link's irqs + * 4. set inactive after all irq mask done + * (at this time isr can check inactive and unmask irq safely due to step 3 already mask irqs) + */ + gps_dl_link_set_ready_to_write(link_id, false); + gps_dl_hal_link_confirm_dma_stop(link_id); + gps_dl_link_irq_set(link_id, false); + gps_each_link_set_active(link_id, false); +} + +void gps_dl_link_event_proc(enum gps_dl_link_event_id evt, + enum gps_dl_link_id_enum link_id) +{ + struct gps_each_link *p_link = gps_dl_link_get(link_id); + bool show_log = false; + bool show_log2 = false; + unsigned long j0, j1; + int ret; + enum gps_dsp_state_t dsp_state; + + j0 = jiffies; + GDL_LOGXD_EVT(link_id, "evt = %s", gps_dl_link_event_name(evt)); + + switch (evt) { + case GPS_DL_EVT_LINK_OPEN: + /* show_log = gps_dl_set_show_reg_rw_log(true); */ + gps_each_dsp_reg_gourp_read_init(link_id); + gps_each_link_inc_session_id(link_id); + gps_each_link_set_active(link_id, true); + gps_each_link_set_bool_flag(link_id, LINK_NEED_A2Z_DUMP, false); + + ret = gps_dl_hal_conn_power_ctrl(link_id, 1); + if (ret != 0) { + gps_dl_link_open_ack(link_id, false, false); + break; + } + + ret = gps_dl_hal_link_power_ctrl(link_id, GPS_DL_HAL_POWER_ON); + if (ret != 0) { + gps_dl_link_open_ack(link_id, false, false); + break; + } + + gps_dsp_fsm(GPS_DSP_EVT_FUNC_ON, link_id); + gps_dl_link_irq_set(link_id, true); +#if GPS_DL_NO_USE_IRQ + gps_dl_wait_us(1000); /* wait 1ms */ +#endif + /* set ready to write before open ack, otherwise need to check pending tx data + * gps_dl_link_set_ready_to_write(link_id, true); + * move it to DSP reset done handler + */ + gps_dl_link_open_ack(link_id, true, false); /* TODO: ack on DSP reset done */ + /* gps_dl_set_show_reg_rw_log(show_log); */ + break; + case GPS_DL_EVT_LINK_LEAVE_DPSTOP: + gps_each_dsp_reg_gourp_read_init(link_id); + gps_each_link_inc_session_id(link_id); + gps_each_link_set_active(link_id, true); + gps_each_link_set_bool_flag(link_id, LINK_NEED_A2Z_DUMP, false); + ret = gps_dl_hal_link_power_ctrl(link_id, GPS_DL_HAL_LEAVE_DPSTOP); + if (ret != 0) + gps_dl_link_open_ack(link_id, false, true); + else { + gps_dsp_fsm(GPS_DSP_EVT_HW_STOP_EXIT, link_id); + gps_dl_link_irq_set(link_id, true); + gps_dl_link_open_ack(link_id, true, true); + } + break; + case GPS_DL_EVT_LINK_LEAVE_DPSLEEP: + gps_dl_hal_link_power_ctrl(link_id, GPS_DL_HAL_LEAVE_DPSLEEP); + gps_dl_link_irq_set(link_id, true); + break; + case GPS_DL_EVT_LINK_ENTER_DPSLEEP: + gps_dl_link_pre_off_setting(link_id); + gps_dl_hal_link_power_ctrl(link_id, GPS_DL_HAL_ENTER_DPSLEEP); + break; + case GPS_DL_EVT_LINK_ENTER_DPSTOP: + dsp_state = gps_dsp_state_get(link_id); + if ((GPS_DSP_ST_WORKING != dsp_state) && (GPS_DSP_ST_RESET_DONE != dsp_state)) { + /* TODO: ever working check */ + GDL_LOGXE(link_id, "not enter dpstop due to dsp state = %s", + gps_dl_dsp_state_name(dsp_state)); + + /* TODO: ack fail */ + gps_dl_link_close_ack(link_id, true); + break; + } + + if (GPS_DSP_ST_WORKING == dsp_state) { + GDL_LOGXW(link_id, "enter dpstop with dsp state = %s", + gps_dl_dsp_state_name(dsp_state)); + } + + gps_dl_hal_set_need_clk_ext_flag(link_id, + gps_each_link_get_bool_flag(link_id, LINK_SUSPEND_TO_CLK_EXT)); + + gps_dl_link_pre_off_setting(link_id); + /* TODO: handle fail */ + gps_dl_hal_link_power_ctrl(link_id, GPS_DL_HAL_ENTER_DPSTOP); + gps_dsp_fsm(GPS_DSP_EVT_HW_STOP_REQ, link_id); + gps_each_link_context_clear(link_id); +#if GPS_DL_ON_LINUX + gps_dma_buf_reset(&p_link->tx_dma_buf); + gps_dma_buf_reset(&p_link->rx_dma_buf); +#endif + gps_dl_link_close_ack(link_id, true); + break; + case GPS_DL_EVT_LINK_DSP_ROM_READY_TIMEOUT: + /* check again mcub not ready triggered */ + if (false) + break; /* wait hal handle it */ + + /* true: */ + if (!gps_each_link_change_state_from(link_id, LINK_OPENED, LINK_RESETTING)) { + /* no handle it again */ + break; + } + /* TODO: go and do close */ + case GPS_DL_EVT_LINK_CLOSE: + case GPS_DL_EVT_LINK_RESET_DSP: + case GPS_DL_EVT_LINK_RESET_GPS: + case GPS_DL_EVT_LINK_PRE_CONN_RESET: + if (evt != GPS_DL_EVT_LINK_CLOSE) + show_log = gps_dl_set_show_reg_rw_log(true); + + /* handle open fail case */ + if (!gps_each_link_get_bool_flag(link_id, LINK_OPEN_RESULT_OKAY)) { + GDL_LOGXD(link_id, "not open okay, just power off for %s", + gps_dl_link_event_name(evt)); + + gps_each_link_set_active(link_id, false); + gps_dl_hal_link_power_ctrl(link_id, GPS_DL_HAL_POWER_OFF); + gps_dl_hal_conn_power_ctrl(link_id, 0); + goto _close_or_reset_ack; + } + + /* to avoid twice enter */ + if (GPS_DSP_ST_OFF == gps_dsp_state_get(link_id)) { + GDL_LOGXD(link_id, "dsp state is off, do nothing for %s", + gps_dl_link_event_name(evt)); + + if (evt != GPS_DL_EVT_LINK_CLOSE) + gps_dl_set_show_reg_rw_log(show_log); + + goto _close_or_reset_ack; + } else if (GPS_DSP_ST_HW_STOP_MODE == gps_dsp_state_get(link_id)) { + /* exit deep stop mode and turn off it + * before exit deep stop, need clear pwr stat to make sure dsp is in hold-on state + * after exit deep stop mode. + */ + gps_dl_hal_link_clear_hw_pwr_stat(link_id); + gps_dl_hal_link_power_ctrl(link_id, GPS_DL_HAL_LEAVE_DPSTOP); + } else { + /* make sure current link's DMAs are stopped and mask the IRQs */ + gps_dl_link_pre_off_setting(link_id); + } + gps_dl_hal_set_need_clk_ext_flag(link_id, false); + + if (evt != GPS_DL_EVT_LINK_CLOSE) { + /* try to dump host csr info if not normal close operation */ + if (gps_dl_conninfra_is_okay_or_handle_it(NULL, true)) + gps_dl_hw_dump_host_csr_gps_info(true); + } + + if (gps_each_link_get_bool_flag(link_id, LINK_NEED_A2Z_DUMP)) { + show_log2 = gps_dl_set_show_reg_rw_log(true); + gps_dl_hw_do_gps_a2z_dump(); + gps_dl_set_show_reg_rw_log(show_log2); + } + + gps_dl_hal_link_power_ctrl(link_id, GPS_DL_HAL_POWER_OFF); + gps_dl_hal_conn_power_ctrl(link_id, 0); + + gps_dsp_fsm(GPS_DSP_EVT_FUNC_OFF, link_id); + + gps_each_link_context_clear(link_id); +#if GPS_DL_ON_LINUX + gps_dma_buf_reset(&p_link->tx_dma_buf); + gps_dma_buf_reset(&p_link->rx_dma_buf); +#endif + +_close_or_reset_ack: + if (evt != GPS_DL_EVT_LINK_CLOSE) + gps_dl_set_show_reg_rw_log(show_log); + + if (GPS_DL_EVT_LINK_CLOSE == evt) + gps_dl_link_close_ack(link_id, false); /* TODO: check fired race */ + else + gps_dl_link_reset_ack(link_id); + break; + + case GPS_DL_EVT_LINK_POST_CONN_RESET: + gps_dl_link_on_post_conn_reset(link_id); + break; + + case GPS_DL_EVT_LINK_WRITE: + /* gps_dl_hw_print_usrt_status(link_id); */ + if (gps_dl_link_is_ready_to_write(link_id)) + gps_dl_link_start_tx_dma_if_has_data(link_id); + else + GDL_LOGXW(link_id, "too early writing"); + break; + + case GPS_DL_EVT_LINK_PRINT_HW_STATUS: + case GPS_DL_EVT_LINK_PRINT_DATA_STATUS: + if (!gps_each_link_is_active(link_id)) { + GDL_LOGXW(link_id, "inactive, do not dump hw status"); + break; + } + + gps_dma_buf_show(&p_link->rx_dma_buf, true); + gps_dma_buf_show(&p_link->tx_dma_buf, true); + if (!gps_dl_conninfra_is_okay_or_handle_it(NULL, true)) + break; + + show_log = gps_dl_set_show_reg_rw_log(true); + if (evt == GPS_DL_EVT_LINK_PRINT_HW_STATUS) { + gps_dl_hw_dump_host_csr_gps_info(true); + gps_dl_hw_print_hw_status(link_id, true); + gps_each_dsp_reg_gourp_read_start(link_id, true, 4); + } else { + gps_dl_hw_print_hw_status(link_id, false); + gps_each_dsp_reg_gourp_read_start(link_id, true, 2); + } + gps_dl_set_show_reg_rw_log(show_log); + break; + + case GPS_DL_EVT_LINK_DSP_FSM_TIMEOUT: + gps_dsp_fsm(GPS_DSP_EVT_CTRL_TIMER_EXPIRE, link_id); + break; +#if 0 + case GPS_DL_EVT_LINK_RESET_GPS: + /* turn off GPS power directly */ + break; + + case GPS_DL_EVT_LINK_PRE_CONN_RESET: + /* turn off Connsys power directly + * 1. no need to do anything, just make sure the message queue is empty + * 2. how to handle ctrld block issue + */ + /* gps_dl_link_open_ack(link_id); */ + break; +#endif + default: + break; + } + + j1 = jiffies; + GDL_LOGXI_EVT(link_id, "evt = %s, dj = %lu", gps_dl_link_event_name(evt), j1 - j0); +} + +void gps_each_link_mutexes_init(struct gps_each_link *p) +{ + enum gps_each_link_mutex i; + + for (i = 0; i < GPS_DL_MTX_NUM; i++) + gps_dl_osal_sleepable_lock_init(&p->mutexes[i]); +} + +void gps_each_link_mutexes_deinit(struct gps_each_link *p) +{ + enum gps_each_link_mutex i; + + for (i = 0; i < GPS_DL_MTX_NUM; i++) + gps_dl_osal_sleepable_lock_deinit(&p->mutexes[i]); +} + +void gps_each_link_spin_locks_init(struct gps_each_link *p) +{ + enum gps_each_link_spinlock i; + + for (i = 0; i < GPS_DL_SPINLOCK_NUM; i++) + gps_dl_osal_unsleepable_lock_init(&p->spin_locks[i]); +} + +void gps_each_link_spin_locks_deinit(struct gps_each_link *p) +{ +#if 0 + enum gps_each_link_spinlock i; + + for (i = 0; i < GPS_DL_SPINLOCK_NUM; i++) + osal_unsleepable_lock_deinit(&p->spin_locks[i]); +#endif +} + +void gps_each_link_mutex_take(enum gps_dl_link_id_enum link_id, enum gps_each_link_mutex mtx_id) +{ + /* TODO: check range */ + struct gps_each_link *p = gps_dl_link_get(link_id); + + /* TODO: handle killed */ + gps_dl_osal_lock_sleepable_lock(&p->mutexes[mtx_id]); +} + +void gps_each_link_mutex_give(enum gps_dl_link_id_enum link_id, enum gps_each_link_mutex mtx_id) +{ + /* TODO: check range */ + struct gps_each_link *p = gps_dl_link_get(link_id); + + gps_dl_osal_unlock_sleepable_lock(&p->mutexes[mtx_id]); +} + +void gps_each_link_spin_lock_take(enum gps_dl_link_id_enum link_id, enum gps_each_link_spinlock spin_lock_id) +{ + /* TODO: check range */ + struct gps_each_link *p = gps_dl_link_get(link_id); + + gps_dl_osal_lock_unsleepable_lock(&p->spin_locks[spin_lock_id]); +} + +void gps_each_link_spin_lock_give(enum gps_dl_link_id_enum link_id, enum gps_each_link_spinlock spin_lock_id) +{ + /* TODO: check range */ + struct gps_each_link *p = gps_dl_link_get(link_id); + + gps_dl_osal_unlock_unsleepable_lock(&p->spin_locks[spin_lock_id]); +} + +int gps_each_link_take_big_lock(enum gps_dl_link_id_enum link_id, + enum gps_each_link_lock_reason reason) +{ + gps_each_link_mutex_take(link_id, GPS_DL_MTX_BIG_LOCK); + return 0; +} + +int gps_each_link_give_big_lock(enum gps_dl_link_id_enum link_id) +{ + gps_each_link_mutex_give(link_id, GPS_DL_MTX_BIG_LOCK); + return 0; +} + +enum gps_each_link_state_enum gps_each_link_get_state(enum gps_dl_link_id_enum link_id) +{ + struct gps_each_link *p = gps_dl_link_get(link_id); + enum gps_each_link_state_enum state; + + gps_each_link_spin_lock_take(link_id, GPS_DL_SPINLOCK_FOR_LINK_STATE); + state = p->state_for_user; + gps_each_link_spin_lock_give(link_id, GPS_DL_SPINLOCK_FOR_LINK_STATE); + + return state; +} + +void gps_each_link_set_state(enum gps_dl_link_id_enum link_id, enum gps_each_link_state_enum state) +{ + struct gps_each_link *p = gps_dl_link_get(link_id); + enum gps_each_link_state_enum pre_state; + + + gps_each_link_spin_lock_take(link_id, GPS_DL_SPINLOCK_FOR_LINK_STATE); + pre_state = p->state_for_user; + p->state_for_user = state; + gps_each_link_spin_lock_give(link_id, GPS_DL_SPINLOCK_FOR_LINK_STATE); + + GDL_LOGXI_STA(link_id, "state change: %s -> %s", + gps_dl_link_state_name(pre_state), gps_dl_link_state_name(state)); +} + +bool gps_each_link_change_state_from(enum gps_dl_link_id_enum link_id, + enum gps_each_link_state_enum from, enum gps_each_link_state_enum to) +{ + bool is_okay = false; + struct gps_each_link *p = gps_dl_link_get(link_id); + enum gps_each_link_state_enum pre_state; + enum gps_each_link_reset_level old_level, new_level; + + gps_each_link_spin_lock_take(link_id, GPS_DL_SPINLOCK_FOR_LINK_STATE); + pre_state = p->state_for_user; + if (from == pre_state) { + p->state_for_user = to; + is_okay = true; + + if (to == LINK_RESETTING) { + old_level = p->reset_level; + if (old_level < GPS_DL_RESET_LEVEL_GPS_SINGLE_LINK) + p->reset_level = GPS_DL_RESET_LEVEL_GPS_SINGLE_LINK; + new_level = p->reset_level; + } + } + gps_each_link_spin_lock_give(link_id, GPS_DL_SPINLOCK_FOR_LINK_STATE); + + if (is_okay && (to == LINK_RESETTING)) { + GDL_LOGXI_STA(link_id, "state change: %s -> %s, okay, level: %d -> %d", + gps_dl_link_state_name(from), gps_dl_link_state_name(to), + old_level, new_level); + } else if (is_okay) { + GDL_LOGXI_STA(link_id, "state change: %s -> %s, okay", + gps_dl_link_state_name(from), gps_dl_link_state_name(to)); + } else { + GDL_LOGXW_STA(link_id, "state change: %s -> %s, fail on pre_state = %s", + gps_dl_link_state_name(from), gps_dl_link_state_name(to), + gps_dl_link_state_name(pre_state)); + } + + return is_okay; +} + +bool gps_dl_link_start_tx_dma_if_has_data(enum gps_dl_link_id_enum link_id) +{ + struct gps_each_link *p_link = gps_dl_link_get(link_id); + struct gdl_dma_buf_entry dma_buf_entry; + enum GDL_RET_STATUS gdl_ret; + bool tx_dma_started; + + gdl_ret = gdl_dma_buf_get_data_entry(&p_link->tx_dma_buf, &dma_buf_entry); + + if (gdl_ret == GDL_OKAY) { + /* wait until dsp recevie last data done or timeout(10ms) + * TODO: handle timeout case + */ + gps_dl_hw_poll_usrt_dsp_rx_empty(link_id); + gps_dl_hal_a2d_tx_dma_claim_emi_usage(link_id, true); + gps_dl_hal_a2d_tx_dma_start(link_id, &dma_buf_entry); + tx_dma_started = true; + } else { + GDL_LOGD("gdl_dma_buf_get_data_entry ret = %s", gdl_ret_to_name(gdl_ret)); + tx_dma_started = false; + } + + return tx_dma_started; +} + +int gps_dl_link_get_clock_flag(void) +{ + return gps_dl_hal_get_clock_flag(); +} + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hal/gps_dl_conn_infra.c b/drivers/misc/mediatek/connectivity/gps/data_link/hal/gps_dl_conn_infra.c new file mode 100644 index 0000000000000000000000000000000000000000..93caba4c4a093fe5785b898bf4f50a6a99c2e669 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hal/gps_dl_conn_infra.c @@ -0,0 +1,109 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#include "gps_dl_config.h" + +#include "gps_dl_context.h" +#include "gps_dl_hw_ver.h" +#include "gps_dl_hw_api.h" +#include "gps_dl_hal_api.h" +#if GPS_DL_HAS_PLAT_DRV +#include "gps_dl_linux_reserved_mem.h" +#endif + +#define GPS_EMI_REMAP_BASE_MASK (0xFFFFF0000) /* start from 64KB boundary, get msb20 of 36bit */ +#define GPS_EMI_REMAP_LENGTH (64 * 1024 * 1024UL) +#define GPS_EMI_BUS_BASE (0x78000000) + +void gps_dl_emi_remap_set(unsigned int min_addr, unsigned int max_addr) +{ + unsigned int aligned_addr = 0; + unsigned int _20msb_of_36bit_phy_addr; + + /* TODO: addr may not use uint, due to addr might be 36bit and uint might be only 32bit */ + aligned_addr = (min_addr & GPS_EMI_REMAP_BASE_MASK); + + + if (max_addr - aligned_addr > GPS_EMI_REMAP_LENGTH) { + GDL_LOGE("min = 0x%09x, max = 0x%09x, base = 0x%09x, over range", + min_addr, max_addr, aligned_addr); + } else { + GDL_LOGD("min = 0x%09x, max = 0x%09x, base = 0x%09x", + min_addr, max_addr, aligned_addr); + } + + _20msb_of_36bit_phy_addr = aligned_addr >> 16; + GDL_LOGD("icap_buf: remap setting = 0x%08x", _20msb_of_36bit_phy_addr); + gps_dl_hw_set_gps_emi_remapping(_20msb_of_36bit_phy_addr); + gps_dl_remap_ctx_get()->gps_emi_phy_high20 = aligned_addr; +} + +enum GDL_RET_STATUS gps_dl_emi_remap_phy_to_bus_addr(unsigned int phy_addr, unsigned int *bus_addr) +{ + unsigned int remap_setting = gps_dl_remap_ctx_get()->gps_emi_phy_high20; + + if ((phy_addr >= remap_setting) && + (phy_addr < (remap_setting + GPS_EMI_REMAP_LENGTH))) { + *bus_addr = GPS_EMI_BUS_BASE + (phy_addr - remap_setting); + return GDL_OKAY; + } + + *bus_addr = 0; + return GDL_FAIL; +} + +void gps_dl_emi_remap_calc_and_set(void) +{ + enum gps_dl_link_id_enum i; + struct gps_each_link *p_link; + + unsigned int min_addr = 0xFFFFFFFF; + unsigned int max_addr = 0; + unsigned int tx_end; + unsigned int rx_end; + +#if GPS_DL_HAS_PLAT_DRV + if (gps_dl_reserved_mem_is_ready()) { + gps_dl_reserved_mem_show_info(); + gps_dl_reserved_mem_get_range(&min_addr, &max_addr); + gps_dl_emi_remap_set(min_addr, max_addr); + return; + } +#endif + + for (i = 0; i < GPS_DATA_LINK_NUM; i++) { + p_link = gps_dl_link_get(i); + + min_addr = (p_link->rx_dma_buf.phy_addr < min_addr) ? p_link->rx_dma_buf.phy_addr : min_addr; + min_addr = (p_link->tx_dma_buf.phy_addr < min_addr) ? p_link->tx_dma_buf.phy_addr : min_addr; + + rx_end = p_link->rx_dma_buf.phy_addr + p_link->rx_dma_buf.len; + tx_end = p_link->tx_dma_buf.phy_addr + p_link->tx_dma_buf.len; + + max_addr = (rx_end > min_addr) ? rx_end : max_addr; + max_addr = (tx_end > min_addr) ? tx_end : max_addr; + } + GDL_LOGD("cal from dma buffers: min = 0x%x, max = 0x%x", min_addr, max_addr); + gps_dl_emi_remap_set(min_addr, max_addr); +} + + +unsigned int g_gps_dl_hal_conn_infra_poll_ok_ver; + +void gps_dl_hal_set_conn_infra_ver(unsigned int ver) +{ + g_gps_dl_hal_conn_infra_poll_ok_ver = ver; +} + +unsigned int gps_dl_hal_get_conn_infra_ver(void) +{ + return g_gps_dl_hal_conn_infra_poll_ok_ver; +} + +bool gps_dl_hal_conn_infra_ver_is_mt6885(void) +{ + /* is_mt6885 valid after gps_dl_hw_gps_common_on */ + return (gps_dl_hal_get_conn_infra_ver() == GDL_HW_CONN_INFRA_VER_MT6885); +} + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hal/gps_dl_dma.c b/drivers/misc/mediatek/connectivity/gps/data_link/hal/gps_dl_dma.c new file mode 100644 index 0000000000000000000000000000000000000000..6a92b431ff4c220839b6ae7ca0d73f92668987f5 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hal/gps_dl_dma.c @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#include "gps_dl_config.h" +#include "gps_dl_context.h" + +#include "gps_dl_hal.h" +#include "gps_dl_hal_api.h" +#include "gps_dl_hal_util.h" +#include "gps_each_link.h" + +#if GPS_DL_MOCK_HAL +#include "gps_mock_hal.h" +#endif +#include "gps_dl_hw_api.h" + +void gps_dl_hal_dma_init(void) +{ +} + +void gps_dl_hal_dma_config(enum gps_dl_hal_dma_ch_index ch) +{ +} + + +void gps_dl_hal_a2d_tx_dma_start(enum gps_dl_link_id_enum link_id, + struct gdl_dma_buf_entry *p_entry) +{ + struct gps_each_link *p_link = gps_dl_link_get(link_id); + + p_link->tx_dma_buf.dma_working_entry = *p_entry; + + GDL_LOGXD(link_id, ""); + + if (link_id == GPS_DATA_LINK_ID0) + gps_dl_hal_dma_start(GPS_DL_DMA_LINK0_A2D, p_entry); + else if (link_id == GPS_DATA_LINK_ID1) + gps_dl_hal_dma_start(GPS_DL_DMA_LINK1_A2D, p_entry); +} + +void gps_dl_hal_a2d_tx_dma_stop(enum gps_dl_link_id_enum link_id) +{ + if (link_id == GPS_DATA_LINK_ID0) + gps_dl_hal_dma_stop(GPS_DL_DMA_LINK0_A2D); + else if (link_id == GPS_DATA_LINK_ID1) + gps_dl_hal_dma_stop(GPS_DL_DMA_LINK1_A2D); +} + +enum GDL_RET_STATUS gps_dl_hal_a2d_tx_dma_wait_until_done_and_stop_it( + enum gps_dl_link_id_enum link_id, int timeout_usec, bool return_if_not_start) +{ + GDL_LOGXD(link_id, ""); + if (link_id == GPS_DATA_LINK_ID0) { + return gps_dl_hw_wait_until_dma_complete_and_stop_it( + GPS_DL_DMA_LINK0_A2D, timeout_usec, return_if_not_start); + } else if (link_id == GPS_DATA_LINK_ID1) { + return gps_dl_hw_wait_until_dma_complete_and_stop_it( + GPS_DL_DMA_LINK1_A2D, timeout_usec, return_if_not_start); + } + + return GDL_FAIL; +} + +void gps_dl_hal_d2a_rx_dma_start(enum gps_dl_link_id_enum link_id, + struct gdl_dma_buf_entry *p_entry) +{ + struct gps_each_link *p_link = gps_dl_link_get(link_id); + + ASSERT_LINK_ID(link_id, GDL_VOIDF()); + ASSERT_NOT_NULL(p_entry, GDL_VOIDF()); + + p_link->rx_dma_buf.dma_working_entry = *p_entry; + + if (link_id == GPS_DATA_LINK_ID0) + gps_dl_hal_dma_start(GPS_DL_DMA_LINK0_D2A, p_entry); + else if (link_id == GPS_DATA_LINK_ID1) + gps_dl_hal_dma_start(GPS_DL_DMA_LINK1_D2A, p_entry); +} + +void gps_dl_hal_d2a_rx_dma_stop(enum gps_dl_link_id_enum link_id) +{ + if (link_id == GPS_DATA_LINK_ID0) + gps_dl_hal_dma_stop(GPS_DL_DMA_LINK0_D2A); + else if (link_id == GPS_DATA_LINK_ID1) + gps_dl_hal_dma_stop(GPS_DL_DMA_LINK1_D2A); +} + +enum GDL_RET_STATUS gps_dl_hal_d2a_rx_dma_wait_until_done( + enum gps_dl_link_id_enum link_id, int timeout_usec) +{ + if (link_id == GPS_DATA_LINK_ID0) { + return gps_dl_hw_wait_until_dma_complete_and_stop_it( + GPS_DL_DMA_LINK0_D2A, timeout_usec, false); + } else if (link_id == GPS_DATA_LINK_ID1) { + return gps_dl_hw_wait_until_dma_complete_and_stop_it( + GPS_DL_DMA_LINK1_D2A, timeout_usec, false); + } + + return GDL_FAIL; +} + +unsigned int gps_dl_hal_d2a_rx_dma_get_rx_len(enum gps_dl_link_id_enum link_id) +{ + return 0; +} + +enum GDL_RET_STATUS gps_dl_real_dma_get_rx_write_index( + enum gps_dl_link_id_enum link_id, unsigned int *p_write_index) +{ + enum GDL_RET_STATUS gdl_ret; + unsigned int left_len; + enum gps_dl_hal_dma_ch_index ch; + struct gps_each_link *p_link = gps_dl_link_get(link_id); + + ASSERT_LINK_ID(link_id, GDL_FAIL_ASSERT); + + if (link_id == GPS_DATA_LINK_ID0) + ch = GPS_DL_DMA_LINK0_D2A; + else + ch = GPS_DL_DMA_LINK1_D2A; + + left_len = gps_dl_hw_get_dma_left_len(ch); + if (!gps_dl_is_1byte_mode()) + left_len *= 4; + + gdl_ret = gdl_dma_buf_entry_transfer_left_to_write_index( + &p_link->rx_dma_buf.dma_working_entry, left_len, p_write_index); + + return gdl_ret; +} + +enum GDL_RET_STATUS gps_dl_hal_d2a_rx_dma_get_write_index( + enum gps_dl_link_id_enum link_id, unsigned int *p_write_index) +{ +#if GPS_DL_MOCK_HAL + unsigned int write_index_from_mock; + enum GDL_RET_STATUS gdl_from_mock; +#endif + enum GDL_RET_STATUS gdl_ret; + + ASSERT_NOT_NULL(p_write_index, GDL_FAIL_ASSERT); +#if GPS_DL_MOCK_HAL + gdl_from_mock = gps_dl_mock_dma_get_rx_write_index(link_id, &write_index_from_mock); + if (gdl_from_mock != GDL_OKAY) + return gdl_from_mock; +#endif + gdl_ret = gps_dl_real_dma_get_rx_write_index(link_id, p_write_index); + GDL_LOGD("real gdl_ret = %s", gdl_ret_to_name(gdl_ret)); + +#if GPS_DL_MOCK_HAL + *p_write_index = write_index_from_mock; + return gdl_from_mock; +#else + return gdl_ret; +#endif +} + +void gps_dl_real_dma_start(enum gps_dl_hal_dma_ch_index ch, + struct gdl_dma_buf_entry *p_entry) +{ + enum GDL_RET_STATUS gdl_ret; + enum gps_dl_link_id_enum link_id; + struct gdl_hw_dma_transfer dma_transfer; + + ASSERT_NOT_NULL(p_entry, GDL_VOIDF()); + + link_id = DMA_CH_TO_LINK_ID(ch); + ASSERT_LINK_ID(link_id, GDL_VOIDF()); + + GDL_LOGXD(link_id, "ch = %d, r = %u, w = %u, addr = 0x%p", + ch, p_entry->read_index, p_entry->write_index, + p_entry->vir_addr); + + if (DMA_CH_IS_TX(ch)) + gdl_ret = gdl_dma_buf_entry_to_transfer(p_entry, &dma_transfer, true); + else if (DMA_CH_IS_RX(ch)) + gdl_ret = gdl_dma_buf_entry_to_transfer(p_entry, &dma_transfer, false); + else + GDL_ASSERT(false, GDL_VOIDF(), ""); + GDL_ASSERT(gdl_ret == GDL_OKAY, GDL_VOIDF(), "gdl_ret = %d", gdl_ret); + gps_dl_hw_set_dma_start(ch, &dma_transfer); +} + +void gps_dl_hal_dma_start(enum gps_dl_hal_dma_ch_index ch, + struct gdl_dma_buf_entry *p_entry) +{ + gps_dl_real_dma_start(ch, p_entry); +#if GPS_DL_MOCK_HAL + gps_dl_mock_dma_start(ch, p_entry); +#endif +} + +void gps_dl_hal_dma_stop(enum gps_dl_hal_dma_ch_index ch) +{ +#if GPS_DL_MOCK_HAL + gps_dl_mock_dma_stop(ch); +#endif + gps_dl_hw_set_dma_stop(ch); +} + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hal/gps_dl_hal.c b/drivers/misc/mediatek/connectivity/gps/data_link/hal/gps_dl_hal.c new file mode 100644 index 0000000000000000000000000000000000000000..ac551bbfca841dd97e28b68297c7a9c460f46a94 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hal/gps_dl_hal.c @@ -0,0 +1,446 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#include "gps_dl_hal.h" +#include "gps_dl_hw_api.h" +#include "gps_dsp_fsm.h" +#include "gps_each_link.h" +#include "gps_dl_isr.h" +#include "gps_dl_context.h" +#include "gps_dl_name_list.h" +#include "gps_dl_subsys_reset.h" +#if GPS_DL_HAS_CONNINFRA_DRV +#include "conninfra.h" +#endif + +#include "linux/jiffies.h" + +void gps_dl_hal_event_send(enum gps_dl_hal_event_id evt, + enum gps_dl_link_id_enum link_id) +{ +#if (GPS_DL_HAS_CTRLD == 0) + gps_dl_hal_event_proc(evt, link_id, gps_each_link_get_session_id(link_id)); +#else + { + struct gps_dl_osal_lxop *pOp; + struct gps_dl_osal_signal *pSignal; + int iRet; + + pOp = gps_dl_get_free_op(); + if (!pOp) + return; + + pSignal = &pOp->signal; + pSignal->timeoutValue = 0;/* send data need to wait ?ms */ + if (link_id < GPS_DATA_LINK_NUM) { + pOp->op.opId = GPS_DL_OPID_HAL_EVENT_PROC; + pOp->op.au4OpData[0] = link_id; + pOp->op.au4OpData[1] = evt; + pOp->op.au4OpData[2] = gps_each_link_get_session_id(link_id); + iRet = gps_dl_put_act_op(pOp); + } else { + gps_dl_put_op_to_free_queue(pOp); + /*printf error msg*/ + return; + } + } +#endif +} + +void gps_dl_hal_event_proc(enum gps_dl_hal_event_id evt, + enum gps_dl_link_id_enum link_id, int sid_on_evt) +{ + struct gps_each_link *p_link = gps_dl_link_get(link_id); + struct gdl_dma_buf_entry dma_buf_entry; + enum GDL_RET_STATUS gdl_ret; + unsigned int write_index; + int curr_sid; + bool last_session_msg = false; + unsigned long j0, j1; + bool show_log, reg_rw_log; + bool conninfra_okay, dma_irq_en; + + j0 = jiffies; + curr_sid = gps_each_link_get_session_id(link_id); + + if (!gps_dl_reset_level_is_none(link_id) || + gps_each_link_get_bool_flag(link_id, LINK_IS_RESETTING)) { + /* ack the reset status */ + last_session_msg = true; + } else if (sid_on_evt != curr_sid && sid_on_evt != GPS_EACH_LINK_SID_NO_CHECK) { + GDL_LOGXW_EVT(link_id, "curr_sid = %d, evt = %s, on_sid = %d, not matching", + curr_sid, gps_dl_hal_event_name(evt), sid_on_evt); + last_session_msg = true; + } else if (!gps_each_link_is_active(link_id) || + gps_each_link_get_bool_flag(link_id, LINK_TO_BE_CLOSED)) { + GDL_LOGXW_EVT(link_id, "curr_sid = %d, evt = %s, on_sid = %d, not active", + curr_sid, gps_dl_hal_event_name(evt), sid_on_evt); + last_session_msg = true; + } + + if (last_session_msg) { + /* unmask irq to make it balance */ + if (evt == GPS_DL_HAL_EVT_D2A_RX_HAS_NODATA) { + gps_dl_irq_each_link_unmask(link_id, + GPS_DL_IRQ_TYPE_HAS_NODATA, GPS_DL_IRQ_CTRL_FROM_HAL); + } else if (evt == GPS_DL_HAL_EVT_D2A_RX_HAS_DATA) { + gps_dl_irq_each_link_unmask(link_id, + GPS_DL_IRQ_TYPE_HAS_DATA, GPS_DL_IRQ_CTRL_FROM_HAL); + } else if (evt == GPS_DL_HAL_EVT_MCUB_HAS_IRQ) { + gps_dl_irq_each_link_unmask(link_id, + GPS_DL_IRQ_TYPE_MCUB, GPS_DL_IRQ_CTRL_FROM_HAL); + } else if (evt == GPS_DL_HAL_EVT_DMA_ISR_PENDING) { + /* + * do nothing if last_session_msg + */ + } + return; + } + + if (sid_on_evt == GPS_EACH_LINK_SID_NO_CHECK) { + GDL_LOGXW_EVT(link_id, "curr_sid = %d, evt = %s, on_sid = %d, no check", + curr_sid, gps_dl_hal_event_name(evt), sid_on_evt); + } else if (sid_on_evt <= 0 || sid_on_evt > GPS_EACH_LINK_SID_MAX) { + GDL_LOGXW_EVT(link_id, "curr_sid = %d, evt = %s, on_sid = %d, out of range", + curr_sid, gps_dl_hal_event_name(evt), sid_on_evt); + } else { + GDL_LOGXD_EVT(link_id, "curr_sid = %d, evt = %s, on_sid = %d", + curr_sid, gps_dl_hal_event_name(evt), sid_on_evt); + } + + GDL_LOGXD_EVT(link_id, "evt = %s", gps_dl_hal_event_name(evt)); + switch (evt) { + case GPS_DL_HAL_EVT_D2A_RX_HAS_DATA: + gdl_ret = gdl_dma_buf_get_free_entry( + &p_link->rx_dma_buf, &dma_buf_entry, true); + + if (gdl_ret == GDL_OKAY) { + gps_dl_hal_d2a_rx_dma_claim_emi_usage(link_id, true); + gps_dl_hal_d2a_rx_dma_start(link_id, &dma_buf_entry); + } else { + + /* TODO: has pending rx: GDL_FAIL_NOSPACE_PENDING_RX */ + GDL_LOGXI_DRW(link_id, "rx dma not start due to %s", gdl_ret_to_name(gdl_ret)); + } + break; + + /* TODO: handle the case data_len is just equal to buf_len, */ + /* the rx_dma_done and usrt_has_nodata both happen. */ + case GPS_DL_HAL_EVT_D2A_RX_DMA_DONE: + /* TODO: to make mock work with it */ + + /* stop and clear int flag in isr */ + /* gps_dl_hal_d2a_rx_dma_stop(link_id); */ + p_link->rx_dma_buf.dma_working_entry.write_index = + p_link->rx_dma_buf.dma_working_entry.read_index; + + /* check whether no data also happen */ + if (gps_dl_hw_usrt_has_set_nodata_flag(link_id)) { + p_link->rx_dma_buf.dma_working_entry.is_nodata = true; + gps_dl_hw_usrt_clear_nodata_irq(link_id); + } else + p_link->rx_dma_buf.dma_working_entry.is_nodata = false; + + gdl_ret = gdl_dma_buf_set_free_entry(&p_link->rx_dma_buf, + &p_link->rx_dma_buf.dma_working_entry); + + if (gdl_ret == GDL_OKAY) { + p_link->rx_dma_buf.dma_working_entry.is_valid = false; + gps_dl_link_wake_up(&p_link->waitables[GPS_DL_WAIT_READ]); + } + + gps_dl_hal_d2a_rx_dma_claim_emi_usage(link_id, false); + /* mask data irq */ + gps_dl_irq_each_link_unmask(link_id, GPS_DL_IRQ_TYPE_HAS_DATA, GPS_DL_IRQ_CTRL_FROM_HAL); + break; + + case GPS_DL_HAL_EVT_D2A_RX_HAS_NODATA: + /* get rx length */ + gdl_ret = gps_dl_hal_d2a_rx_dma_get_write_index(link_id, &write_index); + + /* 20181118 for mock, rx dma stop must after get write index */ + gps_dl_hal_d2a_rx_dma_stop(link_id); + + if (gdl_ret == GDL_OKAY) { + /* no need to mask data irq */ + p_link->rx_dma_buf.dma_working_entry.write_index = write_index; + p_link->rx_dma_buf.dma_working_entry.is_nodata = true; + + gdl_ret = gdl_dma_buf_set_free_entry(&p_link->rx_dma_buf, + &p_link->rx_dma_buf.dma_working_entry); + + if (gdl_ret != GDL_OKAY) + GDL_LOGD("gdl_dma_buf_set_free_entry ret = %s", gdl_ret_to_name(gdl_ret)); + + } else + GDL_LOGD("gps_dl_hal_d2a_rx_dma_get_write_index ret = %s", gdl_ret_to_name(gdl_ret)); + + if (gdl_ret == GDL_OKAY) { + p_link->rx_dma_buf.dma_working_entry.is_valid = false; + gps_dl_link_wake_up(&p_link->waitables[GPS_DL_WAIT_READ]); + } + + gps_dl_hal_d2a_rx_dma_claim_emi_usage(link_id, false); + gps_dl_hw_usrt_clear_nodata_irq(link_id); + gps_dl_irq_each_link_unmask(link_id, GPS_DL_IRQ_TYPE_HAS_NODATA, GPS_DL_IRQ_CTRL_FROM_HAL); + if (gps_dl_test_mask_hasdata_irq_get(link_id)) { + GDL_LOGXE(link_id, "test mask hasdata irq, not unmask irq and wait reset"); + gps_dl_test_mask_hasdata_irq_set(link_id, false); + gps_dl_hal_set_irq_dis_flag(link_id, GPS_DL_IRQ_TYPE_HAS_DATA, true); + } else + gps_dl_irq_each_link_unmask(link_id, GPS_DL_IRQ_TYPE_HAS_DATA, GPS_DL_IRQ_CTRL_FROM_HAL); + break; + + case GPS_DL_HAL_EVT_A2D_TX_DMA_DONE: + /* gps_dl_hw_print_usrt_status(link_id); */ + + /* data tx finished */ + gdl_ret = gdl_dma_buf_set_data_entry(&p_link->tx_dma_buf, + &p_link->tx_dma_buf.dma_working_entry); + + p_link->tx_dma_buf.dma_working_entry.is_valid = false; + + GDL_LOGD("gdl_dma_buf_set_data_entry ret = %s", gdl_ret_to_name(gdl_ret)); + + /* stop tx dma, should stop and clear int flag in isr */ + /* gps_dl_hal_a2d_tx_dma_stop(link_id); */ + + /* wakeup writer if it's pending on it */ + gps_dl_link_wake_up(&p_link->waitables[GPS_DL_WAIT_WRITE]); + gps_dl_hal_a2d_tx_dma_claim_emi_usage(link_id, false); + gps_dl_link_start_tx_dma_if_has_data(link_id); + break; + + case GPS_DL_HAL_EVT_DMA_ISR_PENDING: + conninfra_okay = gps_dl_conninfra_is_okay_or_handle_it(NULL, true); + dma_irq_en = gps_dl_hal_get_dma_irq_en_flag(); + + GDL_LOGXE(link_id, "conninfra_okay = %d, dma_irq_en = %d", conninfra_okay, dma_irq_en); + if (conninfra_okay && !dma_irq_en) { + gps_dl_irq_unmask_dma_intr(GPS_DL_IRQ_CTRL_FROM_HAL); + gps_dl_hal_set_dma_irq_en_flag(true); + } + break; + + case GPS_DL_HAL_EVT_MCUB_HAS_IRQ: + reg_rw_log = gps_dl_log_reg_rw_is_on(GPS_DL_REG_RW_MCUB_IRQ_HANDLER); + if (reg_rw_log) + show_log = gps_dl_set_show_reg_rw_log(true); + if (!gps_dl_hal_mcub_flag_handler(link_id)) { + GDL_LOGXE(link_id, "mcub_flag_handler not okay, not unmask irq and wait reset"); + gps_dl_hal_set_mcub_irq_dis_flag(link_id, true); + } else + gps_dl_irq_each_link_unmask(link_id, GPS_DL_IRQ_TYPE_MCUB, GPS_DL_IRQ_CTRL_FROM_HAL); + if (reg_rw_log) + gps_dl_set_show_reg_rw_log(show_log); + break; + +#if 0 + case GPS_DL_HAL_EVT_DSP_ROM_START: + gps_dsp_fsm(GPS_DSP_EVT_RESET_DONE, link_id); + + /* if has pending data, can send it now */ + gdl_ret = gdl_dma_buf_get_data_entry(&p_link->tx_dma_buf, &dma_buf_entry); + if (gdl_ret == GDL_OKAY) + gps_dl_hal_a2d_tx_dma_start(link_id, &dma_buf_entry); + break; + + case GPS_DL_HAL_EVT_DSP_RAM_START: + gps_dsp_fsm(GPS_DSP_EVT_RAM_CODE_READY, link_id); + + /* start reg polling */ + break; +#endif + + default: + break; + } + + j1 = jiffies; + GDL_LOGXI_EVT(link_id, "evt = %s, on_sid = %d, dj = %lu", + gps_dl_hal_event_name(evt), sid_on_evt, j1 - j0); +} + +bool gps_dl_hal_mcub_flag_handler(enum gps_dl_link_id_enum link_id) +{ + struct gps_dl_hal_mcub_info d2a; + bool conninfra_okay; + + /* Todo: while condition make sure DSP is on and session ID */ + while (1) { + conninfra_okay = gps_dl_conninfra_is_okay_or_handle_it(NULL, true); + if (!conninfra_okay) { + GDL_LOGXE(link_id, "conninfra_okay = %d", conninfra_okay); + return false; /* not okay */ + } + + gps_dl_hw_get_mcub_info(link_id, &d2a); + if (d2a.flag == 0) + break; + + if (d2a.flag == GPS_MCUB_D2AF_MASK_DSP_REG_READ_READY) { + /* do nothing + * + * only "reg read ready" in flag bits, print the information in + * gps_each_dsp_reg_read_ack, rather than here. + */ + } else { + GDL_LOGXI(link_id, "d2a: flag = 0x%04x, d0 = 0x%04x, d1 = 0x%04x", + d2a.flag, d2a.dat0, d2a.dat1); + } + + if (d2a.flag == 0xdeadfeed) { + gps_dl_hw_dump_host_csr_gps_info(true); + gps_dl_hw_dump_sleep_prot_status(); + + GDL_LOGXE(link_id, "deadfeed, trigger connsys reset"); + gps_dl_trigger_connsys_reset(); + return false; + } + + /* Todo: if (dsp is off) -> break */ + /* Note: clear flag before check and handle the flage event, + * avoiding race condtion when dsp do "too fast twice ack". + * EX: gps_each_dsp_reg_gourp_read_next + */ + gps_dl_hw_clear_mcub_d2a_flag(link_id, d2a.flag); + + if (d2a.flag & GPS_MCUB_D2AF_MASK_DSP_RESET_DONE) { + /* gps_dl_hal_event_send(GPS_DL_HAL_EVT_DSP_ROM_START, link_id); */ + gps_dsp_fsm(GPS_DSP_EVT_RESET_DONE, link_id); + } + + if (d2a.flag & GPS_MCUB_D2AF_MASK_DSP_RAMCODE_READY) { + if (d2a.dat1 == 0xDEAD || d2a.dat1 == 0xBEEF) { + GDL_LOGXW(link_id, + "d2a: flag = 0x%04x, d0 = 0x%04x, d1 = 0x%04x, do dump", + d2a.flag, d2a.dat0, d2a.dat1); + gps_dl_hw_dump_host_csr_gps_info(true); +#if GPS_DL_HAS_CONNINFRA_DRV + /* API to check and dump host csr */ + conninfra_is_bus_hang(); +#else + gps_dl_hw_dump_host_csr_conninfra_info(true); +#endif + gps_dl_hw_print_hw_status(link_id, true); + gps_dl_hw_dump_host_csr_gps_info(true); + continue; + } + + /* bypass gps_dsp_fsm if ariving here and the status is already working */ + if (GPS_DSP_ST_WORKING == gps_dsp_state_get(link_id)) + continue; + + /* gps_dl_hal_event_send(GPS_DL_HAL_EVT_DSP_RAM_START, link_id); */ + gps_dsp_fsm(GPS_DSP_EVT_RAM_CODE_READY, link_id); + + /* start reg polling */ + gps_each_dsp_reg_gourp_read_start(link_id, false, 1); + } + + if (d2a.flag & GPS_MCUB_D2AF_MASK_DSP_REG_READ_READY) + gps_each_dsp_reg_read_ack(link_id, &d2a); + + } + + return true; +} + + +unsigned int g_gps_dl_hal_emi_usage_bitmask; + +void gps_dl_hal_emi_usage_init(void) +{ + unsigned int old_mask; + + old_mask = g_gps_dl_hal_emi_usage_bitmask; + g_gps_dl_hal_emi_usage_bitmask = 0; + + if (old_mask) + GDL_LOGW("mask is 0x%x, force it to 0", old_mask); + else + GDL_LOGD("mask is 0"); + + /* Not claim/disclaim it for low power + * gps_dl_hal_emi_usage_claim(GPS_DL_EMI_USER_GPS_ON, true); + */ +} + +void gps_dl_hal_emi_usage_deinit(void) +{ + unsigned int old_mask; + + /* Not claim/disclaim it for low power + * gps_dl_hal_emi_usage_claim(GPS_DL_EMI_USER_GPS_ON, false); + */ + + old_mask = g_gps_dl_hal_emi_usage_bitmask; + + if (old_mask) + GDL_LOGW("mask is 0x%x, force to release emi usage", old_mask); + else + GDL_LOGD("mask is 0"); + + /* force to release it anyway */ + gps_dl_hw_gps_sw_request_emi_usage(false); +} + +void gps_dl_hal_emi_usage_claim(enum gps_dl_hal_emi_user user, bool use_emi) +{ + unsigned int old_mask, new_mask; + bool changed = false, usage = false; + + /* TODO: protect them using spin lock to make it more safe, + * currently only one thread call me, no racing. + */ + old_mask = g_gps_dl_hal_emi_usage_bitmask; + if (use_emi) + g_gps_dl_hal_emi_usage_bitmask = old_mask | (1UL << user); + else + g_gps_dl_hal_emi_usage_bitmask = old_mask & ~(1UL << user); + new_mask = g_gps_dl_hal_emi_usage_bitmask; + + if (old_mask == 0 && new_mask != 0) { + gps_dl_hw_gps_sw_request_emi_usage(true); + changed = true; + usage = true; + } else if (old_mask != 0 && new_mask == 0) { + gps_dl_hw_gps_sw_request_emi_usage(false); + changed = true; + usage = false; + } + + if (changed) { + GDL_LOGD("user = %d, use = %d, old_mask = 0x%x, new_mask = 0x%x, change = %d/%d", + user, use_emi, old_mask, new_mask, changed, usage); + } else { + GDL_LOGD("user = %d, use = %d, old_mask = 0x%x, new_mask = 0x%x, change = %d", + user, use_emi, old_mask, new_mask, changed); + } +} + +void gps_dl_hal_a2d_tx_dma_claim_emi_usage(enum gps_dl_link_id_enum link_id, bool use_emi) +{ + if (link_id == GPS_DATA_LINK_ID0) + gps_dl_hal_emi_usage_claim(GPS_DL_EMI_USER_TX_DMA0, use_emi); + else if (link_id == GPS_DATA_LINK_ID1) + gps_dl_hal_emi_usage_claim(GPS_DL_EMI_USER_TX_DMA1, use_emi); +} + +void gps_dl_hal_d2a_rx_dma_claim_emi_usage(enum gps_dl_link_id_enum link_id, bool use_emi) +{ + if (link_id == GPS_DATA_LINK_ID0) + gps_dl_hal_emi_usage_claim(GPS_DL_EMI_USER_RX_DMA0, use_emi); + else if (link_id == GPS_DATA_LINK_ID1) + gps_dl_hal_emi_usage_claim(GPS_DL_EMI_USER_RX_DMA1, use_emi); +} + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hal/gps_dl_hal_util.c b/drivers/misc/mediatek/connectivity/gps/data_link/hal/gps_dl_hal_util.c new file mode 100644 index 0000000000000000000000000000000000000000..a9bff23abac7ff60ece01ab0a5bf440161e284de --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hal/gps_dl_hal_util.c @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + + + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hal/gps_dl_isr.c b/drivers/misc/mediatek/connectivity/gps/data_link/hal/gps_dl_isr.c new file mode 100644 index 0000000000000000000000000000000000000000..87a1c852a14b9e613c0fa86cf682e71e90ac1ec8 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hal/gps_dl_isr.c @@ -0,0 +1,335 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#include "gps_dl_config.h" +#include "gps_dl_isr.h" +#include "gps_dl_hal.h" +#include "gps_dl_hw_api.h" +#include "gps_dl_hal_util.h" +#include "gps_dsp_fsm.h" +#include "gps_each_link.h" +#include "gps/gps_usrt_apb.h" +#include "gps/gps_l5_usrt_apb.h" + +/* TODO: IRQ hwirq, irq_id, gdl_irq_index */ +/* On CTP: hwirq == irq_id */ +/* On Linux: hwirq != irq_id */ +#if GPS_DL_ON_CTP +/* x_define_irq.h 198 -> 415 */ +#define GPS_DL_IRQ_BASE_ID (GPS_L1_IRQ_BUS_BIT0_ID) +#else +#define GPS_DL_IRQ_BASE_ID (383) /* (415 - 32) */ +#endif + +#define GPS_IRQ_ID_DL0_HAS_DATA (GPS_DL_IRQ_BASE_ID + 0) +#define GPS_IRQ_ID_DL0_HAS_NODATA (GPS_DL_IRQ_BASE_ID + 1) +#define GPS_IRQ_ID_DL0_MCUB (GPS_DL_IRQ_BASE_ID + 2) +#define GPS_IRQ_ID_DL1_HAS_DATA (GPS_DL_IRQ_BASE_ID + 3) +#define GPS_IRQ_ID_DL1_HAS_NODATA (GPS_DL_IRQ_BASE_ID + 4) +#define GPS_IRQ_ID_DL1_MCUB (GPS_DL_IRQ_BASE_ID + 5) +#define GPS_IRQ_ID_DMA_DONE (GPS_DL_IRQ_BASE_ID + 6) + +#if GPS_DL_ON_LINUX +/* TODO: hwirq and linux irq id */ +int g_gps_irq_index_to_id_table[GPS_DL_IRQ_NUM]; +void gps_dl_irq_set_id(enum gps_dl_irq_index_enum irq_idx, int irq_id) +{ + g_gps_irq_index_to_id_table[irq_idx] = irq_id; +} +#else +int g_gps_irq_index_to_id_table[GPS_DL_IRQ_NUM] = { + [GPS_DL_IRQ_LINK0_DATA] = GPS_IRQ_ID_DL0_HAS_DATA, + [GPS_DL_IRQ_LINK0_NODATA] = GPS_IRQ_ID_DL0_HAS_NODATA, + [GPS_DL_IRQ_LINK0_MCUB] = GPS_IRQ_ID_DL0_MCUB, + [GPS_DL_IRQ_LINK1_DATA] = GPS_IRQ_ID_DL1_HAS_DATA, + [GPS_DL_IRQ_LINK1_NODATA] = GPS_IRQ_ID_DL1_HAS_NODATA, + [GPS_DL_IRQ_LINK1_MCUB] = GPS_IRQ_ID_DL1_MCUB, + [GPS_DL_IRQ_DMA] = GPS_IRQ_ID_DMA_DONE, +}; +#endif + +int gps_dl_irq_index_to_id(enum gps_dl_irq_index_enum irq_idx) +{ + ASSERT_IRQ_IDX(irq_idx, -1); + return g_gps_irq_index_to_id_table[irq_idx]; +} + +int g_gps_irq_type_to_hwirq_table[GPS_DATA_LINK_NUM][GPS_DL_IRQ_TYPE_NUM] = { + [GPS_DATA_LINK_ID0][GPS_DL_IRQ_TYPE_HAS_DATA] = + GPS_IRQ_ID_DL0_HAS_DATA, + [GPS_DATA_LINK_ID0][GPS_DL_IRQ_TYPE_HAS_NODATA] = + GPS_IRQ_ID_DL0_HAS_NODATA, + [GPS_DATA_LINK_ID0][GPS_DL_IRQ_TYPE_MCUB] = + GPS_IRQ_ID_DL0_MCUB, + + [GPS_DATA_LINK_ID1][GPS_DL_IRQ_TYPE_HAS_DATA] = + GPS_IRQ_ID_DL1_HAS_DATA, + [GPS_DATA_LINK_ID1][GPS_DL_IRQ_TYPE_HAS_NODATA] = + GPS_IRQ_ID_DL1_HAS_NODATA, + [GPS_DATA_LINK_ID1][GPS_DL_IRQ_TYPE_MCUB] = + GPS_IRQ_ID_DL1_MCUB, +}; + +int gps_dl_irq_type_to_hwirq(enum gps_dl_link_id_enum link_id, + enum gps_dl_each_link_irq_type irq_type) +{ + ASSERT_LINK_ID(link_id, -1); + ASSERT_IRQ_TYPE(irq_type, -1); + return g_gps_irq_type_to_hwirq_table[link_id][irq_type]; +} + +int g_gps_irq_type_to_index_table[GPS_DATA_LINK_NUM][GPS_DL_IRQ_TYPE_NUM] = { + [GPS_DATA_LINK_ID0][GPS_DL_IRQ_TYPE_HAS_DATA] = + GPS_DL_IRQ_LINK0_DATA, + [GPS_DATA_LINK_ID0][GPS_DL_IRQ_TYPE_HAS_NODATA] = + GPS_DL_IRQ_LINK0_NODATA, + [GPS_DATA_LINK_ID0][GPS_DL_IRQ_TYPE_MCUB] = + GPS_DL_IRQ_LINK0_MCUB, + + [GPS_DATA_LINK_ID1][GPS_DL_IRQ_TYPE_HAS_DATA] = + GPS_DL_IRQ_LINK1_DATA, + [GPS_DATA_LINK_ID1][GPS_DL_IRQ_TYPE_HAS_NODATA] = + GPS_DL_IRQ_LINK1_NODATA, + [GPS_DATA_LINK_ID1][GPS_DL_IRQ_TYPE_MCUB] = + GPS_DL_IRQ_LINK1_MCUB, + +}; + +int gps_dl_irq_type_to_id(enum gps_dl_link_id_enum link_id, + enum gps_dl_each_link_irq_type irq_type) +{ + int irq_index; + int irq_id; + + ASSERT_LINK_ID(link_id, -1); + ASSERT_IRQ_TYPE(irq_type, -1); + + irq_index = g_gps_irq_type_to_index_table[link_id][irq_type]; + irq_id = g_gps_irq_index_to_id_table[irq_index]; + + return irq_id; +} + +void gps_dl_irq_each_link_control(enum gps_dl_link_id_enum link_id, + enum gps_dl_each_link_irq_type irq_type, bool mask_it, + enum gps_dl_irq_ctrl_from from) +{ + int irq_id; + + ASSERT_LINK_ID(link_id, GDL_VOIDF()); + + irq_id = gps_dl_irq_type_to_id(link_id, irq_type); + + GDL_LOGXD(link_id, "irq ctrl: from = %d, mask = %d, type = %d, irq_id = %d", + from, mask_it, irq_type, irq_id); +#if !GPS_DL_HW_IS_MOCK + if (mask_it) + gps_dl_irq_mask(irq_id, from); + else + gps_dl_irq_unmask(irq_id, from); +#endif +} + +void gps_dl_irq_each_link_mask(enum gps_dl_link_id_enum link_id, + enum gps_dl_each_link_irq_type irq_type, enum gps_dl_irq_ctrl_from from) +{ +#if (GPS_DL_ON_CTP && !GPS_DL_NO_USE_IRQ) + if (irq_type == GPS_DL_IRQ_TYPE_HAS_DATA && + gps_dl_link_is_ready_to_write(link_id)) + /* Note: CTP isr main always unmask ARM IRQ when return. */ + /* we need irq not go for some cases, so musk it form GPS side. */ + gps_dl_hw_usrt_rx_irq_enable(link_id, false); +#endif + gps_dl_irq_each_link_control(link_id, irq_type, true, from); +} + +void gps_dl_irq_each_link_unmask(enum gps_dl_link_id_enum link_id, + enum gps_dl_each_link_irq_type irq_type, enum gps_dl_irq_ctrl_from from) +{ +#if (GPS_DL_ON_CTP && !GPS_DL_NO_USE_IRQ) + if (irq_type == GPS_DL_IRQ_TYPE_HAS_DATA && + gps_dl_link_is_ready_to_write(link_id)) + gps_dl_hw_usrt_rx_irq_enable(link_id, true); +#endif + gps_dl_irq_each_link_control(link_id, irq_type, false, from); +} + +void gps_dl_irq_mask_dma_intr(enum gps_dl_irq_ctrl_from from) +{ + GDL_LOGD("from = %d", from); +#if !GPS_DL_HW_IS_MOCK + gps_dl_irq_mask(gps_dl_irq_index_to_id(GPS_DL_IRQ_DMA), from); +#endif +} + +void gps_dl_irq_unmask_dma_intr(enum gps_dl_irq_ctrl_from from) +{ + GDL_LOGD("from = %d", from); +#if !GPS_DL_HW_IS_MOCK + gps_dl_irq_unmask(gps_dl_irq_index_to_id(GPS_DL_IRQ_DMA), from); +#endif +} + +void gps_dl_isr_usrt_has_data(enum gps_dl_link_id_enum link_id) +{ + GDL_LOGXD(link_id, "start"); + gps_dl_irq_each_link_mask(link_id, GPS_DL_IRQ_TYPE_HAS_DATA, GPS_DL_IRQ_CTRL_POSSIBLE_FROM_ISR); + + if (gps_each_link_is_active(link_id)) + gps_dl_hal_event_send(GPS_DL_HAL_EVT_D2A_RX_HAS_DATA, link_id); + else { + /* NOTE: ctrld has already unmask it, still unmask here to keep balance */ + gps_dl_irq_each_link_unmask(link_id, GPS_DL_IRQ_TYPE_HAS_DATA, + GPS_DL_IRQ_CTRL_POSSIBLE_FROM_ISR); + GDL_LOGXD(link_id, "bypass due to link not active"); + } +} + +void gps_dl_isr_usrt_has_nodata(enum gps_dl_link_id_enum link_id) +{ + GDL_LOGXD(link_id, "ch = %d", GET_RX_DMA_CH_OF(link_id)); + + gps_dl_irq_each_link_mask(link_id, GPS_DL_IRQ_TYPE_HAS_NODATA, GPS_DL_IRQ_CTRL_POSSIBLE_FROM_ISR); + + if (gps_each_link_is_active(link_id)) + gps_dl_hal_event_send(GPS_DL_HAL_EVT_D2A_RX_HAS_NODATA, link_id); + else { + gps_dl_irq_each_link_unmask(link_id, GPS_DL_IRQ_TYPE_HAS_NODATA, + GPS_DL_IRQ_CTRL_POSSIBLE_FROM_ISR); + GDL_LOGXD(link_id, "bypass due to link not active"); + } +} + +void gps_dl_isr_d2a_rx_dma_done(enum gps_dl_link_id_enum link_id) +{ + GDL_LOGXD(link_id, "ch = %d", GET_RX_DMA_CH_OF(link_id)); + + /* gps_dl_irq_each_link_mask(link_id, GPS_DL_IRQ_TYPE_MCUB); */ + gps_dl_hal_d2a_rx_dma_stop(link_id); + + gps_dl_hal_event_send(GPS_DL_HAL_EVT_D2A_RX_DMA_DONE, link_id); +} + +void gps_dl_isr_a2d_tx_dma_done(enum gps_dl_link_id_enum link_id) +{ + GDL_LOGXD(link_id, "ch = %d", GET_TX_DMA_CH_OF(link_id)); + + /* gps_dl_irq_mask_dma_intr(); */ + gps_dl_hal_a2d_tx_dma_stop(link_id); + + /* update dma buf write pointor */ + /* notify controller thread */ + gps_dl_hal_event_send(GPS_DL_HAL_EVT_A2D_TX_DMA_DONE, link_id); + + /* by ctrld thread determine whether start next dma session */ +} + +void gps_dl_isr_dma_done(void) +{ + enum gps_dl_hal_dma_ch_index i; + + gps_dl_irq_mask_dma_intr(GPS_DL_IRQ_CTRL_POSSIBLE_FROM_ISR); + + if (!gps_dl_conninfra_is_readable()) { + /* set it for gps_ctrld to check, avoiding twice mask */ + gps_dl_hal_set_dma_irq_en_flag(false); + gps_dl_hal_event_send(GPS_DL_HAL_EVT_DMA_ISR_PENDING, GPS_DATA_LINK_ID0); + gps_dl_hal_event_send(GPS_DL_HAL_EVT_DMA_ISR_PENDING, GPS_DATA_LINK_ID1); + GDL_LOGE("pending due to readable check fail"); + return; + } + + /* dma isr must copy the data and restore the intr flag + * no need to copy data, the data is copied in ctrld thread + */ + + /* TODO: not always starts on i = 0 to make it's fair for each DMA ch */ + for (i = 0; i < GPS_DL_DMA_CH_NUM; i++) { + /* TODO: is the dma ch is active */ + + if (gps_dl_hw_get_dma_int_status(i)) { +#if 0 + DMA_Stop((kal_uint8)(index)); + set_dma_acki(index); + while (DMA_CheckRunStat(index)) + ; + DMA_Clock_Disable(index); +#endif + switch (i) { + case GPS_DL_DMA_LINK0_A2D: + gps_dl_isr_a2d_tx_dma_done(GPS_DATA_LINK_ID0); + break; + case GPS_DL_DMA_LINK0_D2A: + gps_dl_isr_d2a_rx_dma_done(GPS_DATA_LINK_ID0); + break; + case GPS_DL_DMA_LINK1_A2D: + gps_dl_isr_a2d_tx_dma_done(GPS_DATA_LINK_ID1); + break; + case GPS_DL_DMA_LINK1_D2A: + gps_dl_isr_d2a_rx_dma_done(GPS_DATA_LINK_ID1); + break; + default: + break; + } + } + } + /* TODO: end for-loop until all DMA is stopped */ + + gps_dl_irq_unmask_dma_intr(GPS_DL_IRQ_CTRL_POSSIBLE_FROM_ISR); +} + +void gps_dl_isr_mcub(enum gps_dl_link_id_enum link_id) +{ + GDL_LOGXD(link_id, "start"); + gps_dl_irq_each_link_mask(link_id, GPS_DL_IRQ_TYPE_MCUB, GPS_DL_IRQ_CTRL_FROM_ISR); + + if (gps_each_link_is_active(link_id)) + gps_dl_hal_event_send(GPS_DL_HAL_EVT_MCUB_HAS_IRQ, link_id); + else { + gps_dl_irq_each_link_unmask(link_id, GPS_DL_IRQ_TYPE_MCUB, + GPS_DL_IRQ_CTRL_POSSIBLE_FROM_ISR); + GDL_LOGXD(link_id, "bypass due to link not active"); + } +} + +#if GPS_DL_ON_CTP +void gps_dl_isr_dl0_has_data(void) +{ + gps_dl_isr_usrt_has_data(GPS_DATA_LINK_ID0); +} + +void gps_dl_isr_dl0_has_nodata(void) +{ + gps_dl_isr_usrt_has_nodata(GPS_DATA_LINK_ID0); +} + +void gps_dl_isr_dl0_mcub(void) +{ + gps_dl_isr_mcub(GPS_DATA_LINK_ID0); +} + +void gps_dl_isr_dl1_has_data(void) +{ + gps_dl_isr_usrt_has_data(GPS_DATA_LINK_ID1); +} + +void gps_dl_isr_dl1_has_nodata(void) +{ + gps_dl_isr_usrt_has_nodata(GPS_DATA_LINK_ID1); +} + +void gps_dl_isr_dl1_mcub(void) +{ + gps_dl_isr_mcub(GPS_DATA_LINK_ID1); +} +#endif + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hal/gps_dl_mcub.c b/drivers/misc/mediatek/connectivity/gps/data_link/hal/gps_dl_mcub.c new file mode 100644 index 0000000000000000000000000000000000000000..f172562187336f83a752dca76ebc8f67a2b0eac1 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hal/gps_dl_mcub.c @@ -0,0 +1,182 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#include "gps_dl_config.h" +#include "gps_dl_log.h" +#include "gps_dl_hw_api.h" +#include "gps_dsp_fsm.h" + +#define GPS_DSP_REG_POLL_MAX (11) +const unsigned int c_gps_dsp_reg_list[GPS_DATA_LINK_NUM][GPS_DSP_REG_POLL_MAX] = { + /* 8: HW TICK H/L, BG tick H/L, TX_END/TX_RD, RX_END/RX_WR + * 3: PC, GALMAN CNT, WRHOST CNT + */ + { + 0x5028, 0x5029, 0x0100, 0x0101, 0x4882, 0x4883, 0x4886, 0x4887, + 0xEF00, 0xEF01, 0xEF02, + }, + { + 0x5014, 0x5015, 0x0100, 0x0101, 0x4882, 0x4883, 0x4886, 0x4887, + 0xEF00, 0xEF01, 0xEF02, + } +}; + +#define GPS_DSP_REG_DBG_POLL_MAX (20) +const unsigned int c_gps_dsp_reg_dbg_list[GPS_DATA_LINK_NUM][GPS_DSP_REG_DBG_POLL_MAX] = { + /* 9: PC, GALMAN CNT, WRHOST CNT, DBTT CNT, NEXT CNT, BG TICK H/L, HW TICK H/L + * 11: USRT CTL, STA, TX_END/RD/MAX, RX_MAX/END/WR, TX_CNT, RX_CNT, MISC + */ + { + 0xEF00, 0xEF01, 0xEF02, 0xEF03, 0xEF04, 0x0100, 0x0101, 0x5028, 0x5029, + 0x4880, 0x4881, 0x4882, 0x4883, 0x4884, 0x4885, 0x4886, 0x4887, 0x4888, 0x4889, 0x488a, + }, + { + 0xEF00, 0xEF01, 0xEF02, 0xEF03, 0xEF04, 0x0100, 0x0101, 0x5014, 0x5015, + 0x4880, 0x4881, 0x4882, 0x4883, 0x4884, 0x4885, 0x4886, 0x4887, 0x4888, 0x4889, 0x488a, + } +}; + + + +struct gps_each_dsp_reg_read_context { + bool poll_ongoing; + int poll_index; + unsigned int poll_addr; + + /* a "poll" means one register in c_gps_dsp_reg_list. + * a "round" means a round to poll all registers in c_gps_dsp_reg_list. + * sometimes for debug we need for several rounds + * to check the changing of the values of each register. + */ + unsigned int round_max; + unsigned int round_index; + const unsigned int *poll_list_ptr; + int poll_list_len; +}; + +struct gps_each_dsp_reg_read_context g_gps_each_dsp_reg_read_context[GPS_DATA_LINK_NUM]; + + +enum GDL_RET_STATUS gps_each_dsp_reg_read_request( + enum gps_dl_link_id_enum link_id, unsigned int reg_addr) +{ + enum GDL_RET_STATUS ret; + + ASSERT_LINK_ID(link_id, GDL_FAIL_INVAL); + ret = gps_dl_hw_mcub_dsp_read_request(link_id, reg_addr); + + if (ret == GDL_OKAY) { + g_gps_each_dsp_reg_read_context[link_id].poll_addr = reg_addr; + g_gps_each_dsp_reg_read_context[link_id].poll_ongoing = true; + } + + return ret; +} + +void gps_each_dsp_reg_gourp_read_next(enum gps_dl_link_id_enum link_id, bool restart) +{ + unsigned int reg_addr; + enum GDL_RET_STATUS ret; + struct gps_each_dsp_reg_read_context *p_read_context; + int i; + + ASSERT_LINK_ID(link_id, GDL_VOIDF()); + p_read_context = &g_gps_each_dsp_reg_read_context[link_id]; + if (restart) { + p_read_context->poll_index = 0; + p_read_context->round_index = 0; + } else { + p_read_context->poll_index++; + if (p_read_context->poll_index >= p_read_context->poll_list_len) { + p_read_context->round_index++; + if (p_read_context->round_index >= p_read_context->round_max) { + /* all polling end */ + return; + } + /* next round */ + p_read_context->poll_index = 0; + } + } + + i = p_read_context->poll_index; + reg_addr = p_read_context->poll_list_ptr[i]; + ret = gps_each_dsp_reg_read_request(link_id, reg_addr); + GDL_LOGXD(link_id, "i = %d/%d, addr = 0x%04x, status = %s", + i, p_read_context->poll_list_len, reg_addr, gdl_ret_to_name(ret)); +} + +void gps_each_dsp_reg_read_ack( + enum gps_dl_link_id_enum link_id, const struct gps_dl_hal_mcub_info *p_d2a) +{ + ASSERT_LINK_ID(link_id, GDL_VOIDF()); + + GDL_LOGXI(link_id, + "n = %d/%d, addr = 0x%04x, val = 0x%04x/0x%04x, round = %d/%d", + g_gps_each_dsp_reg_read_context[link_id].poll_index + 1, + g_gps_each_dsp_reg_read_context[link_id].poll_list_len, + g_gps_each_dsp_reg_read_context[link_id].poll_addr, + p_d2a->dat0, p_d2a->dat1, + g_gps_each_dsp_reg_read_context[link_id].round_index + 1, + g_gps_each_dsp_reg_read_context[link_id].round_max); + + g_gps_each_dsp_reg_read_context[link_id].poll_ongoing = false; + gps_each_dsp_reg_gourp_read_next(link_id, false); +} + +void gps_each_dsp_reg_gourp_read_start(enum gps_dl_link_id_enum link_id, + bool dbg, unsigned int round_max) +{ + unsigned int a2d_flag; + struct gps_dl_hal_mcub_info d2a; + + ASSERT_LINK_ID(link_id, GDL_VOIDF()); + + if (g_gps_each_dsp_reg_read_context[link_id].poll_ongoing) { + GDL_LOGXW(link_id, "n = %d/%d, addr = 0x%04x, seem busy, check it", + g_gps_each_dsp_reg_read_context[link_id].poll_index + 1, + g_gps_each_dsp_reg_read_context[link_id].poll_list_len, + g_gps_each_dsp_reg_read_context[link_id].poll_addr); + + /* TODO: show hw status */ + a2d_flag = gps_dl_hw_get_mcub_a2d_flag(link_id); + gps_dl_hw_get_mcub_info(link_id, &d2a); + GDL_LOGXW(link_id, "a2d_flag = %d, d2a_flag = %d, d0 = 0x%04x, d1 = 0x%04x", + a2d_flag, d2a.flag, d2a.dat0, d2a.dat1); + + if (a2d_flag & GPS_MCUB_A2DF_MASK_DSP_REG_READ_REQ || + d2a.flag & GPS_MCUB_D2AF_MASK_DSP_REG_READ_READY) { + /* real busy, bypass */ + return; + } + } + + if (dbg) { + g_gps_each_dsp_reg_read_context[link_id].poll_list_ptr = + &c_gps_dsp_reg_dbg_list[link_id][0]; + g_gps_each_dsp_reg_read_context[link_id].poll_list_len = GPS_DSP_REG_DBG_POLL_MAX; + } else { + g_gps_each_dsp_reg_read_context[link_id].poll_list_ptr = + &c_gps_dsp_reg_list[link_id][0]; + g_gps_each_dsp_reg_read_context[link_id].poll_list_len = GPS_DSP_REG_POLL_MAX; + } + g_gps_each_dsp_reg_read_context[link_id].round_max = round_max; + gps_each_dsp_reg_gourp_read_next(link_id, true); +} + +void gps_each_dsp_reg_gourp_read_init(enum gps_dl_link_id_enum link_id) +{ + ASSERT_LINK_ID(link_id, GDL_VOIDF()); + + memset(&g_gps_each_dsp_reg_read_context[link_id], 0, + sizeof(g_gps_each_dsp_reg_read_context[link_id])); +} + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hal/gps_dl_power_ctrl.c b/drivers/misc/mediatek/connectivity/gps/data_link/hal/gps_dl_power_ctrl.c new file mode 100644 index 0000000000000000000000000000000000000000..d2d1d01f0d526299ba53e339dfa6e78c697cf4ea --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hal/gps_dl_power_ctrl.c @@ -0,0 +1,654 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#include "gps_dl_config.h" +#include "gps_dl_context.h" + +#include "gps_dl_hal.h" +#include "gps_dl_hw_api.h" +#include "gps_dl_hal.h" +#if GPS_DL_MOCK_HAL +#include "gps_mock_hal.h" +#endif +#if GPS_DL_HAS_CONNINFRA_DRV +#if GPS_DL_ON_LINUX +#include "conninfra.h" +#elif GPS_DL_ON_CTP +#include "conninfra_ext.h" +#endif +#endif + +#if GPS_DL_HAS_PLAT_DRV +#include "gps_dl_linux_plat_drv.h" +#endif +#if GPS_DL_ON_CTP +#include "gps_dl_ctp.h" +#endif + +/* TODO: move them into a single structure */ +bool g_gps_common_on; +bool g_gps_dsp_on_array[GPS_DATA_LINK_NUM]; +int g_gps_dsp_off_ret_array[GPS_DATA_LINK_NUM]; +bool g_gps_conninfa_on; +bool g_gps_pta_init_done; +bool g_gps_tia_on; +bool g_gps_dma_irq_en; +bool g_gps_irqs_dis[GPS_DATA_LINK_NUM][GPS_DL_IRQ_TYPE_NUM]; +bool g_gps_need_clk_ext[GPS_DATA_LINK_NUM]; +int g_gps_conn_clock_flag = GPSDL_CLOCK_FLAG_COTMS; +unsigned int g_conn_user; + +bool gps_dl_hal_get_dma_irq_en_flag(void) +{ + bool enable; + + /* spin lock protection between gps_dl_isr_dma_done and gps_kctrld + * both link 0 & 1 spin lock can be used, use 0's. + */ + gps_each_link_spin_lock_take(GPS_DATA_LINK_ID0, GPS_DL_SPINLOCK_FOR_LINK_STATE); + enable = g_gps_dma_irq_en; + gps_each_link_spin_lock_give(GPS_DATA_LINK_ID0, GPS_DL_SPINLOCK_FOR_LINK_STATE); + return enable; +} + +void gps_dl_hal_set_dma_irq_en_flag(bool enable) +{ + gps_each_link_spin_lock_take(GPS_DATA_LINK_ID0, GPS_DL_SPINLOCK_FOR_LINK_STATE); + g_gps_dma_irq_en = enable; + gps_each_link_spin_lock_give(GPS_DATA_LINK_ID0, GPS_DL_SPINLOCK_FOR_LINK_STATE); +} + +bool gps_dl_hal_get_mcub_irq_dis_flag(enum gps_dl_link_id_enum link_id) +{ + return gps_dl_hal_get_irq_dis_flag(link_id, GPS_DL_IRQ_TYPE_MCUB); +} + +void gps_dl_hal_set_mcub_irq_dis_flag(enum gps_dl_link_id_enum link_id, bool disable) +{ + gps_dl_hal_set_irq_dis_flag(link_id, GPS_DL_IRQ_TYPE_MCUB, disable); +} + +bool gps_dl_hal_get_irq_dis_flag(enum gps_dl_link_id_enum link_id, + enum gps_dl_each_link_irq_type type) +{ + bool disable; + + ASSERT_LINK_ID(link_id, false); + ASSERT_IRQ_TYPE(type, false); + gps_each_link_spin_lock_take(link_id, GPS_DL_SPINLOCK_FOR_LINK_STATE); + disable = g_gps_irqs_dis[link_id][type]; + gps_each_link_spin_lock_give(link_id, GPS_DL_SPINLOCK_FOR_LINK_STATE); + return disable; +} + +void gps_dl_hal_set_irq_dis_flag(enum gps_dl_link_id_enum link_id, + enum gps_dl_each_link_irq_type type, bool disable) +{ + ASSERT_LINK_ID(link_id, GDL_VOIDF()); + ASSERT_IRQ_TYPE(type, GDL_VOIDF()); + gps_each_link_spin_lock_take(link_id, GPS_DL_SPINLOCK_FOR_LINK_STATE); + g_gps_irqs_dis[link_id][type] = disable; + gps_each_link_spin_lock_give(link_id, GPS_DL_SPINLOCK_FOR_LINK_STATE); +} + +bool gps_dl_hal_get_need_clk_ext_flag(enum gps_dl_link_id_enum link_id) +{ + bool need; + + ASSERT_LINK_ID(link_id, false); + gps_each_link_spin_lock_take(link_id, GPS_DL_SPINLOCK_FOR_LINK_STATE); + need = g_gps_need_clk_ext[link_id]; + gps_each_link_spin_lock_give(link_id, GPS_DL_SPINLOCK_FOR_LINK_STATE); + return need; +} + +void gps_dl_hal_set_need_clk_ext_flag(enum gps_dl_link_id_enum link_id, bool need) +{ + ASSERT_LINK_ID(link_id, GDL_VOIDF()); + gps_each_link_spin_lock_take(link_id, GPS_DL_SPINLOCK_FOR_LINK_STATE); + g_gps_need_clk_ext[link_id] = need; + gps_each_link_spin_lock_give(link_id, GPS_DL_SPINLOCK_FOR_LINK_STATE); +} + +int gps_dl_hal_link_power_ctrl(enum gps_dl_link_id_enum link_id, + enum gps_dl_hal_power_ctrl_op_enum op) +{ + bool wakeup_okay; + bool conninfra_okay; + bool keep_conninfra_clk; + int hung_value = 0; + int ret = 0; + + wakeup_okay = gps_dl_hw_gps_force_wakeup_conninfra_top_off(true); + conninfra_okay = gps_dl_conninfra_is_okay_or_handle_it(&hung_value, true); + keep_conninfra_clk = !!( + op == GPS_DL_HAL_POWER_ON || + op == GPS_DL_HAL_LEAVE_DPSLEEP || + op == GPS_DL_HAL_LEAVE_DPSTOP); + GDL_LOGXW_ONF(link_id, + "op = %d, conn_okay = %d/%d/0x%x, gps_common = %d, L1 = %d, L5 = %d, cfg = %d/0x%x", + op, wakeup_okay, conninfra_okay, hung_value, g_gps_common_on, + g_gps_dsp_on_array[GPS_DATA_LINK_ID0], + g_gps_dsp_on_array[GPS_DATA_LINK_ID1], + keep_conninfra_clk, + gps_dl_hw_get_mcub_a2d1_cfg(link_id, gps_dl_is_1byte_mode())); + + if (!wakeup_okay && conninfra_okay) { +#if (GPS_DL_HAS_CONNINFRA_DRV) + int trigger_ret; + trigger_ret = conninfra_trigger_whole_chip_rst(CONNDRV_TYPE_GPS, "GPS conninfra wake fail"); + GDL_LOGXE(link_id, "conninfra wake fail, trigger reset ret = %d", trigger_ret); +#else + GDL_LOGXE(link_id, "conninfra wake fail, trigger reset not support"); +#endif + ret = -1; + } else if (!conninfra_okay && hung_value != 0) { + g_gps_common_on = false; + g_gps_dsp_on_array[GPS_DATA_LINK_ID0] = false; + g_gps_dsp_on_array[GPS_DATA_LINK_ID1] = false; + GDL_LOGXE(link_id, "reset flags due to conninfa not okay"); + ret = -1; + } else { +#if (GPS_DL_HAS_CONNINFRA_DRV) + /* Due to GPS on or GPS exit deep sleep/stop mode may change osc_en from 0 to 1, + * keeping conninfra_bus_clock will make it more safety. + */ + if (keep_conninfra_clk) { + conninfra_bus_clock_ctrl(CONNDRV_TYPE_GPS, + CONNINFRA_BUS_CLOCK_WPLL | CONNINFRA_BUS_CLOCK_BPLL, 1); + } + + ret = gps_dl_hal_link_power_ctrl_inner(link_id, op); + + if (keep_conninfra_clk) { + conninfra_bus_clock_ctrl(CONNDRV_TYPE_GPS, + CONNINFRA_BUS_CLOCK_WPLL | CONNINFRA_BUS_CLOCK_BPLL, 0); + } +#else + ret = gps_dl_hal_link_power_ctrl_inner(link_id, op); +#endif + } + gps_dl_hw_gps_force_wakeup_conninfra_top_off(false); + return ret; +} + +int gps_dl_hal_link_power_ctrl_inner(enum gps_dl_link_id_enum link_id, + enum gps_dl_hal_power_ctrl_op_enum op) +{ + int dsp_ctrl_ret; + + if (1 == op) { + /* GPS common */ + if (!g_gps_common_on) { + if (gps_dl_hw_gps_common_on() != 0) + return -1; + gps_dl_hal_md_blanking_ctrl(true); + g_gps_common_on = true; + } + + if (g_gps_dsp_on_array[link_id]) + return 0; + g_gps_dsp_on_array[link_id] = true; + +#if GPS_DL_HAS_PLAT_DRV + gps_dl_lna_pin_ctrl(link_id, true, false); +#endif +#if GPS_DL_MOCK_HAL + gps_dl_mock_open(link_id); +#endif + + if (GPS_DATA_LINK_ID0 == link_id) + dsp_ctrl_ret = gps_dl_hw_gps_dsp_ctrl(GPS_L1_DSP_ON); + else if (GPS_DATA_LINK_ID1 == link_id) + dsp_ctrl_ret = gps_dl_hw_gps_dsp_ctrl(GPS_L5_DSP_ON); + else + dsp_ctrl_ret = -1; + return dsp_ctrl_ret; + } else if (3 == op || 5 == op) { + gps_dl_lna_pin_ctrl(link_id, true, false); + if (GPS_DATA_LINK_ID0 == link_id) { + if (3 == op) + gps_dl_hw_gps_dsp_ctrl(GPS_L1_DSP_EXIT_DSLEEP); + else if (5 == op) + gps_dl_hw_gps_dsp_ctrl(GPS_L1_DSP_EXIT_DSTOP); + } else if (GPS_DATA_LINK_ID1 == link_id) { + if (3 == op) + gps_dl_hw_gps_dsp_ctrl(GPS_L5_DSP_EXIT_DSLEEP); + else if (5 == op) + gps_dl_hw_gps_dsp_ctrl(GPS_L5_DSP_EXIT_DSTOP); + } + return 0; + } else if (2 == op || 4 == op) { + if (GPS_DATA_LINK_ID0 == link_id) { + if (2 == op) + gps_dl_hw_gps_dsp_ctrl(GPS_L1_DSP_ENTER_DSLEEP); + else if (4 == op) + gps_dl_hw_gps_dsp_ctrl(GPS_L1_DSP_ENTER_DSTOP); + } else if (GPS_DATA_LINK_ID1 == link_id) { + if (2 == op) + gps_dl_hw_gps_dsp_ctrl(GPS_L5_DSP_ENTER_DSLEEP); + else if (4 == op) + gps_dl_hw_gps_dsp_ctrl(GPS_L5_DSP_ENTER_DSTOP); + } + gps_dl_lna_pin_ctrl(link_id, false, false); + return 0; + } else if (0 == op) { + if (g_gps_dsp_on_array[link_id]) { + g_gps_dsp_on_array[link_id] = false; + if (GPS_DATA_LINK_ID0 == link_id) { +#if 0 + if (g_gps_dsp_l5_on && + (0x1 == GDL_HW_GET_GPS_ENTRY(GPS_RGU_ON_GPS_L5_CR_RGU_GPS_L5_ON))) + /* TODO: ASSERT SW status and HW status are same */ +#endif + g_gps_dsp_off_ret_array[link_id] = gps_dl_hw_gps_dsp_ctrl(GPS_L1_DSP_OFF); + } else if (GPS_DATA_LINK_ID1 == link_id) { +#if 0 + if (g_gps_dsp_l1_on && + (0x1 == GDL_HW_GET_GPS_ENTRY(GPS_RGU_ON_GPS_L1_CR_RGU_GPS_L1_ON))) + /* TODO: ASSERT SW status and HW status are same */ +#endif + g_gps_dsp_off_ret_array[link_id] = gps_dl_hw_gps_dsp_ctrl(GPS_L5_DSP_OFF); + } + +#if GPS_DL_HAS_PLAT_DRV + gps_dl_lna_pin_ctrl(link_id, false, false); +#endif +#if GPS_DL_MOCK_HAL + gps_dl_mock_close(link_id); +#endif + } + + if (!g_gps_dsp_on_array[GPS_DATA_LINK_ID0] && !g_gps_dsp_on_array[GPS_DATA_LINK_ID1]) { + if ((g_gps_dsp_off_ret_array[GPS_DATA_LINK_ID0] != 0) || + (g_gps_dsp_off_ret_array[GPS_DATA_LINK_ID1] != 0)) { + GDL_LOGXE(link_id, "l1 ret = %d, l5 ret = %d, force adie off", + g_gps_dsp_off_ret_array[GPS_DATA_LINK_ID0], + g_gps_dsp_off_ret_array[GPS_DATA_LINK_ID1]); + gps_dl_hw_gps_adie_force_off(); + } + + if (g_gps_common_on) { + gps_dl_hal_md_blanking_ctrl(false); + g_gps_common_on = false; + g_gps_dsp_off_ret_array[GPS_DATA_LINK_ID0] = 0; + g_gps_dsp_off_ret_array[GPS_DATA_LINK_ID1] = 0; + if (gps_dl_hw_gps_common_off() != 0) { + /* already trigger connssy reset if arrive here, + * no need to call gps_dl_hw_gps_force_wakeup_conninfra_top_off. + */ + GDL_LOGE("gps_dl_hw_gps_common_off fail"); + return -1; + } + } + } + return 0; + } + return -1; +} + +void gps_dl_hal_link_clear_hw_pwr_stat(enum gps_dl_link_id_enum link_id) +{ + if (GPS_DATA_LINK_ID0 == link_id) + gps_dl_hw_gps_dsp_ctrl(GPS_L1_DSP_CLEAR_PWR_STAT); + else if (GPS_DATA_LINK_ID1 == link_id) + gps_dl_hw_gps_dsp_ctrl(GPS_L5_DSP_CLEAR_PWR_STAT); +} + +int gps_dl_hal_conn_power_ctrl(enum gps_dl_link_id_enum link_id, int op) +{ + bool dma_en_flag = gps_dl_hal_get_dma_irq_en_flag(); + + GDL_LOGXI_ONF(link_id, + "sid = %d, op = %d, conn_user = 0x%x,%d, tia_on = %d, dma_irq_en = %d, mcub_cfg = 0x%x", + gps_each_link_get_session_id(link_id), + op, g_conn_user, g_gps_conninfa_on, g_gps_tia_on, dma_en_flag, + gps_dl_hw_get_mcub_a2d1_cfg(link_id, gps_dl_is_1byte_mode())); + + if (1 == op) { + if (g_conn_user == 0) { + gps_dl_log_info_show(); + if (!gps_dl_hal_conn_infra_driver_on()) + return -1; + + gps_dl_hal_load_clock_flag(); + gps_dl_emi_remap_calc_and_set(); +#if GPS_DL_HAS_PLAT_DRV + gps_dl_wake_lock_hold(true); +#if GPS_DL_USE_TIA + gps_dl_tia_gps_ctrl(true); + g_gps_tia_on = true; +#endif +#endif + gps_dl_irq_unmask_dma_intr(GPS_DL_IRQ_CTRL_FROM_THREAD); + gps_dl_hal_set_dma_irq_en_flag(true); + } + g_conn_user |= (1UL << link_id); + } else if (0 == op) { + g_conn_user &= ~(1UL << link_id); + if (g_conn_user == 0) { + if (dma_en_flag) { + gps_dl_irq_mask_dma_intr(GPS_DL_IRQ_CTRL_FROM_THREAD); + gps_dl_hal_set_dma_irq_en_flag(false); + } +#if GPS_DL_HAS_PLAT_DRV +#if GPS_DL_USE_TIA + if (g_gps_tia_on) { + gps_dl_tia_gps_ctrl(false); + g_gps_tia_on = false; + } +#endif + gps_dl_wake_lock_hold(false); +#endif + gps_dl_hal_conn_infra_driver_off(); + } + } + + return 0; +} + +#define GPS_DL_WAIT_DMA_DONE_TIMEOUT_MS (5) +void gps_dl_hal_link_confirm_dma_stop(enum gps_dl_link_id_enum link_id) +{ + struct gps_each_link *p_link = gps_dl_link_get(link_id); + unsigned int conn_user; + bool tx_working, rx_working; + enum GDL_RET_STATUS stop_tx_status, stop_rx_status; + bool old_dma_en, do_dma_en_ctrl; + + /* make sure dma irq is mask done */ + old_dma_en = gps_dl_hal_get_dma_irq_en_flag(); + do_dma_en_ctrl = false; + if (old_dma_en) { + /* Note1: currently, twice mask should not happen here, + * due to ISR does mask/unmask pair operations, + * except one case, please see Note2 + */ + gps_dl_irq_mask_dma_intr(GPS_DL_IRQ_CTRL_FROM_THREAD); + + /* Note2: double-get to check race condition, if en_flag changed + * it must gps_dl_isr_dma_done change it, need to unmask to make balance + */ + if (!gps_dl_hal_get_dma_irq_en_flag()) + gps_dl_irq_unmask_dma_intr(GPS_DL_IRQ_CTRL_FROM_THREAD); + else { + gps_dl_hal_set_dma_irq_en_flag(false); + do_dma_en_ctrl = true; + } + } + + /* If DMA is working, must stop it when it at proper status -> + * polling until it done or timeout + */ + tx_working = p_link->tx_dma_buf.dma_working_entry.is_valid; + rx_working = p_link->rx_dma_buf.dma_working_entry.is_valid; + stop_tx_status = GDL_OKAY; + stop_rx_status = GDL_OKAY; + + if (tx_working) { + stop_tx_status = gps_dl_hal_a2d_tx_dma_wait_until_done_and_stop_it( + link_id, GPS_DL_WAIT_DMA_DONE_TIMEOUT_MS * 1000, true); + + if (stop_tx_status == GDL_FAIL_TIMEOUT) + gps_dl_hal_a2d_tx_dma_stop(link_id); + } + + if (rx_working && stop_tx_status != GDL_FAIL_CONN_NOT_OKAY) { + stop_rx_status = gps_dl_hal_wait_and_handle_until_usrt_has_nodata_or_rx_dma_done( + link_id, GPS_DL_WAIT_DMA_DONE_TIMEOUT_MS * 1000, false); + + if (stop_rx_status == GDL_FAIL_TIMEOUT) + gps_dl_hal_d2a_rx_dma_stop(link_id); + } + + /* enable the dma irq anyway, leave gps_dl_hal_conn_power_ctrl to disable it */ + if (do_dma_en_ctrl) { + gps_dl_hal_set_dma_irq_en_flag(true); + gps_dl_irq_unmask_dma_intr(GPS_DL_IRQ_CTRL_FROM_THREAD); + } + + /* check the active users */ + conn_user = g_conn_user; + GDL_LOGXW(link_id, "conn_user = 0x%x, old_dma_en = %d/%d, tx = %d/%s, rx = %d/%s", + conn_user, old_dma_en, do_dma_en_ctrl, + tx_working, gdl_ret_to_name(stop_tx_status), + rx_working, gdl_ret_to_name(stop_rx_status)); +} + +bool gps_dl_hal_conn_infra_driver_on(void) +{ +#if GPS_DL_HAS_CONNINFRA_DRV + int ret; + +#if GPS_DL_ON_LINUX + ret = conninfra_pwr_on(CONNDRV_TYPE_GPS); +#elif GPS_DL_ON_CTP + ret = conninfra_power_on(CONNDRV_TYPE_GPS); +#endif + if (ret != 0) { + GDL_LOGE("conninfra_pwr_on fail, ret = %d", ret); + return false; /* not okay */ + } + g_gps_conninfa_on = true; +#endif + return true; /* okay */ +} + +void gps_dl_hal_conn_infra_driver_off(void) +{ +#if GPS_DL_HAS_CONNINFRA_DRV + int ret; + + if (g_gps_conninfa_on) { +#if GPS_DL_ON_LINUX + ret = conninfra_pwr_off(CONNDRV_TYPE_GPS); +#elif GPS_DL_ON_CTP + ret = conninfra_power_off(CONNDRV_TYPE_GPS); +#endif + if (ret != 0) { + GDL_LOGE("conninfra_pwr_off fail, ret = %d", ret); + + /* TODO: trigger whole chip reset? */ + return; + } + + GDL_LOGW("conninfra_pwr_off okay"); + g_gps_conninfa_on = false; + } else + GDL_LOGW("conninfra_pwr_off already done"); +#endif +} + +#if GPS_DL_HAS_PTA +bool gps_dl_hal_md_blanking_init_pta_idc_mode(void) +{ + bool okay, done; + + /* do pta uart init firstly */ + done = gps_dl_hw_is_pta_uart_init_done(); + if (!done) { + okay = gps_dl_hw_init_pta_uart(); + if (!okay) { + GDL_LOGE("gps_dl_hw_init_pta_uart fail"); + return false; + } + } else + GDL_LOGW("pta uart already init done"); + + /* do pta init secondly */ + done = gps_dl_hw_is_pta_init_done(); + if (!done) + gps_dl_hw_init_pta(); + else + GDL_LOGW("pta already init done"); + + gps_dl_hw_claim_pta_used_by_gps(); + + /* use_direct_path = false */ + gps_dl_hw_set_pta_blanking_parameter(false); + return true; +} + +void gps_dl_hal_md_blanking_init_pta_direct_path(void) +{ + /* use_direct_path = true */ + gps_dl_hw_set_pta_blanking_parameter(true); +} + +bool gps_dl_hal_md_blanking_init_pta(void) +{ + bool okay, done; + bool is_mt6885; + bool clk_is_ready; + bool use_direct_path; + + is_mt6885 = gps_dl_hal_conn_infra_ver_is_mt6885(); + use_direct_path = true; + GDL_LOGW("is_mt6885 = %d, use_direct_path = %d", is_mt6885, use_direct_path); + + if (g_gps_pta_init_done) { + GDL_LOGW("already init done, do nothing return"); + return false; + } + + clk_is_ready = true; + if (!gps_dl_hw_is_pta_clk_cfg_ready()) { + GDL_LOGE("gps_dl_hw_is_pta_clk_cfg_ready fail"); + clk_is_ready = false; + } + + okay = gps_dl_hw_take_conn_coex_hw_sema(100); + if (!okay) { + GDL_LOGE("gps_dl_hw_take_conn_coex_hw_sema fail"); + return false; + } + + if (!clk_is_ready) { + gps_dl_hw_set_ptk_clk_cfg(); + if (!gps_dl_hw_is_pta_clk_cfg_ready()) { + GDL_LOGE("gps_dl_hw_is_pta_clk_cfg_ready 2nd fail"); + gps_dl_hw_give_conn_coex_hw_sema(); + return false; + } + } + + if (!use_direct_path) { + /* idc mode */ + okay = gps_dl_hal_md_blanking_init_pta_idc_mode(); + if (!okay) { + gps_dl_hw_give_conn_coex_hw_sema(); + return false; + } + } else { + /* direct path */ + gps_dl_hal_md_blanking_init_pta_direct_path(); + } + + gps_dl_hw_give_conn_coex_hw_sema(); + + /* okay, update flags */ +#if GPS_DL_HAS_PLAT_DRV + gps_dl_update_status_for_md_blanking(true); +#endif + g_gps_pta_init_done = true; + + return true; /* okay */ +} + +void gps_dl_hal_md_blanking_deinit_pta(void) +{ + bool okay; + + /* clear the flags anyway */ +#if GPS_DL_HAS_PLAT_DRV + gps_dl_update_status_for_md_blanking(false); +#endif + if (!g_gps_pta_init_done) { + GDL_LOGW("already deinit done, do nothing return"); + return; + } + g_gps_pta_init_done = false; + + /* Currently, deinit is no need. + * Just keep the bellow code for future usage. + */ + okay = gps_dl_hw_take_conn_coex_hw_sema(0); /* 0 stands for polling just one time */ + if (!okay) { + GDL_LOGE("gps_dl_hw_take_conn_coex_hw_sema fail"); + return; + } + + gps_dl_hw_disclaim_pta_used_by_gps(); + + if (gps_dl_hw_is_pta_init_done()) + gps_dl_hw_deinit_pta(); + else + GDL_LOGW("pta already deinit done"); + + if (gps_dl_hw_is_pta_uart_init_done()) + gps_dl_hw_deinit_pta_uart(); + else + GDL_LOGW("pta uart already deinit done"); + + gps_dl_hw_give_conn_coex_hw_sema(); +} +#endif /* GPS_DL_HAS_PTA */ + +void gps_dl_hal_md_blanking_ctrl(bool on) +{ +#if GPS_DL_HAS_PTA + if (on) + gps_dl_hal_md_blanking_init_pta(); + else + gps_dl_hal_md_blanking_deinit_pta(); +#else + /* For directly connection case, there is no PTA, just update status for md. */ +#if GPS_DL_HAS_PLAT_DRV + gps_dl_update_status_for_md_blanking(on); +#endif +#endif +} + +int gps_dl_hal_get_clock_flag(void) +{ + return g_gps_conn_clock_flag; +} + +void gps_dl_hal_load_clock_flag(void) +{ + int gps_clock_flag; +#if GPS_DL_HAS_CONNINFRA_DRV + enum connsys_clock_schematic clock_sch; + + clock_sch = (enum connsys_clock_schematic)conninfra_get_clock_schematic(); + switch (clock_sch) { + case CONNSYS_CLOCK_SCHEMATIC_26M_COTMS: + gps_clock_flag = GPSDL_CLOCK_FLAG_COTMS; + break; + case CONNSYS_CLOCK_SCHEMATIC_52M_COTMS: + gps_clock_flag = GPSDL_CLOCK_FLAG_52M_COTMS; + break; + case CONNSYS_CLOCK_SCHEMATIC_26M_EXTCXO: + gps_clock_flag = GPSDL_CLOCK_FLAG_TCXO; + break; + default: + gps_clock_flag = GPSDL_CLOCK_FLAG_COTMS; + break; + } + GDL_LOGW("clk: sch from conninfra = %d, mapping to flag = 0x%x", clock_sch, gps_clock_flag); +#else + gps_clock_flag = GPSDL_CLOCK_FLAG_COTMS; + GDL_LOGW("clk: no conninfra drv, default flag = 0x%x", gps_clock_flag); +#endif + g_gps_conn_clock_flag = gps_clock_flag; +} + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hal/gps_dl_zbus.c b/drivers/misc/mediatek/connectivity/gps/data_link/hal/gps_dl_zbus.c new file mode 100644 index 0000000000000000000000000000000000000000..3187861b569fea2a819b19882fd8983780c53d3a --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hal/gps_dl_zbus.c @@ -0,0 +1,12 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hal/gps_dsp_fsm.c b/drivers/misc/mediatek/connectivity/gps/data_link/hal/gps_dsp_fsm.c new file mode 100644 index 0000000000000000000000000000000000000000..70df18e5ba5a146c5a98d25477975b5baba38e0a --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hal/gps_dsp_fsm.c @@ -0,0 +1,289 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +/* #include "autoconf.h" */ + +#if 1 + +/* #ifdef CONFIG_GPS_SUPPORT */ +#if 0 +#include "gps_reroute.h" +#include "gps_reroute_emi.h" +#include "emi_symbol_hook.h" +#include "gps_util.h" +#include "wmt_task.h" +#include "cos_api.h" +#endif + +#include "gps_dsp_fsm.h" +#include "gps_dl_log.h" +#include "gps_each_link.h" +#include "gps_dl_name_list.h" +#include "gps_dl_hal.h" +#include "gps_dl_hw_api.h" + + +/* extern kal_uint32 g_mcu_real_clock_rate; */ +/* extern kal_uint32 g_max_mcu_clock_rate; */ +/* #define GPS_REQ_CLOCK_FREQ_MHZ_MVCD (g_max_mcu_clock_rate/ 1000000UL) */ +/* #define GPS_REQ_CLOCK_FREQ_MHZ_NORMAL (1) 1MHz */ + +enum gps_dsp_state_t g_gps_dsp_state[GPS_DATA_LINK_NUM]; + + +enum gps_dsp_state_t gps_dsp_state_get(enum gps_dl_link_id_enum link_id) +{ + return g_gps_dsp_state[link_id]; +} + +bool gps_dsp_state_is(enum gps_dsp_state_t state, enum gps_dl_link_id_enum link_id) +{ + ASSERT_LINK_ID(link_id, false); + return !!(g_gps_dsp_state[link_id] == state); +} + +void gps_dsp_state_change_to(enum gps_dsp_state_t next_state, enum gps_dl_link_id_enum link_id) +{ + ASSERT_LINK_ID(link_id, GDL_VOIDF()); + + if (next_state == GPS_DSP_ST_TURNED_ON) { + /* gps_clock_switch (GPS_REQ_CLOCK_FREQ_MHZ_MVCD); */ + /* gps_ctrl_timer_start(GPS_DSP_RESET_TIMEOUT_MS); */ + } + + if (next_state == GPS_DSP_ST_RESET_DONE) { + /* Note: here is just a candidate caller, if no problem, we call it */ + /* in GPS_Reroute_Ext_Power_Ctrl_Inner */ + /* GPS_Reroute_Set_DSP_Config_By_MCUB(); */ + + /* gps_clock_switch (GPS_REQ_CLOCK_FREQ_MHZ_MVCD); */ + /* gps_ctrl_timer_start(GPS_DSP_MVCD_TIMEOUT_MS); */ +#if 0 + if (!g_gps_bypass_dsp_turned_on_state) { + /* ready to do reroute */ + gps_data_reroute_set_pending(false); + GPS_Reroute_Buffer_to_GPS_port_real(); + } +#endif + gps_dl_link_set_ready_to_write(link_id, true); + gps_dl_link_start_tx_dma_if_has_data(link_id); + } + + if (next_state == GPS_DSP_ST_WAKEN_UP) { + /* gps_ctrl_timer_start(GPS_DSP_WAKEUP_TIMEOUT_MS); + */ + } + + if (next_state == GPS_DSP_ST_WORKING) { + /* gps_clock_switch (GPS_REQ_CLOCK_FREQ_MHZ_NORMAL); */ + gps_dl_hal_link_clear_hw_pwr_stat(link_id); + gps_dl_hal_set_need_clk_ext_flag(link_id, false); + } + + if (next_state == GPS_DSP_ST_OFF) { + /* gps_clock_switch (0); - already done before gps_dsp_fsm */ + /* gps_ctrl_timer_stop(); */ + } + + g_gps_dsp_state[link_id] = next_state; +} + +void gps_dsp_fsm(enum gps_dsp_event_t evt, enum gps_dl_link_id_enum link_id) +{ +#if 1 + bool abnormal_flag = true; + enum gps_dsp_state_t last_state = gps_dsp_state_get(link_id); + + if (GPS_DSP_EVT_FUNC_ON != evt && GPS_DSP_ST_OFF == last_state) { + /* bypass all event except gps func on when gps is off */ + abnormal_flag = true; + goto _last_check; + } + + if (GPS_DSP_EVT_FUNC_OFF == evt) { +#if 0 + if (GPS_DSP_ST_HW_SLEEP_MODE == last_state || + GPS_DSP_ST_HW_STOP_MODE == last_state) { + /* Special handing rather than GPS_Reroute_Ext_Power_Ctrl_Inner */ + if (GPS_DSP_ST_HW_SLEEP_MODE == last_state) + ; /* wmt_task_subsystem_power_ctrl_handler(COS_GPS_CTRL, 3); */ + else if (GPS_DSP_ST_HW_STOP_MODE == last_state) + ; /* wmt_task_subsystem_power_ctrl_handler(COS_GPS_CTRL, 5); */ + + /* wmt_task_subsystem_power_ctrl_handler(COS_GPS_CTRL, 0); */ + /* GPS_Reroute_Buffer_to_GPS_port_drop(); */ + /* GPS_Reroute_Cos_Sleep_Enable(); */ + } +#endif + if (GPS_DSP_ST_RESET_DONE == last_state || + GPS_DSP_ST_HW_STOP_MODE == last_state) + abnormal_flag = false; + gps_dsp_state_change_to(GPS_DSP_ST_OFF, link_id); + goto _last_check; + } + + if (GPS_DSP_EVT_CTRL_TIMER_EXPIRE == evt) { + /* if (!gps_ctrl_timer_check_valid()) */ + { + abnormal_flag = true; + goto _last_check; + } + + /* TODO: unmask it when timer ready */ +#if 0 + switch (last_state) { + case GPS_DSP_ST_TURNED_ON: + /* GPS_DSP_EVT_RESET_DONE timeout (180ms) */ + /* GPS_Reroute_Buffer_to_GPS_port_drop(); */ + /* gps_dsp_state_change_to(GPS_DSP_ST_RESET_DONE, link_id); */ + /* ERROR timeout - each DSP restart */ + + /* TODO: gps_each_link_reset(link_id); */ + break; + case GPS_DSP_ST_RESET_DONE: + /* GPS_DSP_EVT_RAM_CODE_READY timeout (1s) */ + gps_dsp_state_change_to(GPS_DSP_ST_WORKING, link_id); + break; +#if 0 + case GPS_DSP_ST_HW_SLEEP_MODE: + GPS_Reroute_Ext_Power_Ctrl_Inner(3); + /* cos_resource_enable(COS_SLEEP_MODE, g_gps_sleep_handle); */ + gps_dsp_state_change_to(GPS_DSP_ST_WAKEN_UP, link_id); + break; + case GPS_DSP_ST_WAKEN_UP: + gps_dsp_state_change_to(GPS_DSP_ST_WORKING, link_id); + break; +#endif + default: + abnormal_flag = true; + } + goto _last_check; +#endif + } + + switch (last_state) { + case GPS_DSP_ST_OFF: + if (GPS_DSP_EVT_FUNC_ON == evt) { +#if 0 + if (g_gps_bypass_dsp_turned_on_state) + gps_dsp_state_change_to(GPS_DSP_ST_RESET_DONE, link_id); + else + gps_dsp_state_change_to(GPS_DSP_ST_TURNED_ON, link_id); +#endif + gps_dsp_state_change_to(GPS_DSP_ST_TURNED_ON, link_id); + abnormal_flag = false; + } + break; + + case GPS_DSP_ST_TURNED_ON: + if (GPS_DSP_EVT_RESET_DONE == evt) { + gps_dsp_state_change_to(GPS_DSP_ST_RESET_DONE, link_id); + abnormal_flag = false; + } else + abnormal_flag = true; + break; + + case GPS_DSP_ST_RESET_DONE: + if (GPS_DSP_EVT_RAM_CODE_READY == evt) { + /* TODO */ + /* gps_ctrl_timer_stop(); */ + gps_dsp_state_change_to(GPS_DSP_ST_WORKING, link_id); + abnormal_flag = false; + } else if (GPS_DSP_EVT_HW_STOP_REQ == evt) { + /* already done outside + * GPS_Reroute_Ext_Power_Ctrl_Inner(4); + */ + gps_dsp_state_change_to(GPS_DSP_ST_HW_STOP_MODE, link_id); + abnormal_flag = false; + } else + abnormal_flag = true; + break; + + case GPS_DSP_ST_WORKING: + if (GPS_DSP_EVT_RESET_DONE == evt) { + /* PMTK101 like restart or to be powered off */ + gps_dsp_state_change_to(GPS_DSP_ST_RESET_DONE, link_id); + abnormal_flag = false; + } else if (GPS_DSP_EVT_HW_STOP_REQ == evt) { + /* already done outside + * GPS_Reroute_Ext_Power_Ctrl_Inner(4); + */ + gps_dsp_state_change_to(GPS_DSP_ST_HW_STOP_MODE, link_id); + abnormal_flag = true; /* just show warning */ + } else + abnormal_flag = true; +#if 0 + else if (GPS_DSP_EVT_HW_SLEEP_REQ == evt) { + GPS_Reroute_Ext_Power_Ctrl_Inner(2); + /* to_do_timer check!!! - dynamic change timer */ + /* gps_ctrl_timer_start(800); */ + gps_dsp_state_change_to(GPS_DSP_ST_HW_SLEEP_MODE, link_id); + } else + abnormal_flag = true; +#endif + break; + + case GPS_DSP_ST_HW_SLEEP_MODE: +#if 0 + if (GPS_DSP_EVT_HW_SLEEP_EXIT == evt) { + /* from host - only for test */ + GPS_Reroute_Ext_Power_Ctrl_Inner(3); + gps_dsp_state_change_to(GPS_DSP_ST_WAKEN_UP, link_id); + } else + abnormal_flag = true; +#endif + abnormal_flag = true; + break; + + case GPS_DSP_ST_HW_STOP_MODE: + if (GPS_DSP_EVT_HW_STOP_EXIT == evt) { + /* GPS_Reroute_Ext_Power_Ctrl_Inner(5); */ + gps_dsp_state_change_to(GPS_DSP_ST_WAKEN_UP, link_id); + abnormal_flag = false; + } else if (GPS_DSP_EVT_RESET_DONE == evt) { + gps_dsp_state_change_to(GPS_DSP_ST_RESET_DONE, link_id); + abnormal_flag = false; + } else + abnormal_flag = true; + break; + + case GPS_DSP_ST_WAKEN_UP: + if (GPS_DSP_EVT_RAM_CODE_READY == evt) { + /* gps_ctrl_timer_stop(); */ + gps_dl_link_set_ready_to_write(link_id, true); + gps_dl_link_start_tx_dma_if_has_data(link_id); + gps_dsp_state_change_to(GPS_DSP_ST_WORKING, link_id); + abnormal_flag = false; + } else + abnormal_flag = true; + break; + + default: + abnormal_flag = true; + } + +_last_check: + if (abnormal_flag) { + GDL_LOGXW_STA(link_id, "gps_dsp_fsm: old_st=%s, evt=%s, new_st=%s, is_err=%d", + gps_dl_dsp_state_name(last_state), gps_dl_dsp_event_name(evt), + gps_dl_dsp_state_name(gps_dsp_state_get(link_id)), abnormal_flag); + } else { + GDL_LOGXI_STA(link_id, "gps_dsp_fsm: old_st=%s, evt=%s, new_st=%s", + gps_dl_dsp_state_name(last_state), gps_dl_dsp_event_name(evt), + gps_dl_dsp_state_name(gps_dsp_state_get(link_id))); + } + return; +#endif +} + +#endif /* CONFIG_GPS_SUPPORT */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hal/inc/gps_dl_hal.h b/drivers/misc/mediatek/connectivity/gps/data_link/hal/inc/gps_dl_hal.h new file mode 100644 index 0000000000000000000000000000000000000000..d1c5f9308c5bba5553f80cf57a2f2df3e2fe9996 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hal/inc/gps_dl_hal.h @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#ifndef _GPS_DL_HAL_H +#define _GPS_DL_HAL_H + +#include "gps_dl_config.h" +#include "gps_dl_dma_buf.h" +#include "gps_dl_hal_type.h" +#include "gps_dl_isr.h" + +/* for gps_each_device.c */ + + +/* for gps_each_link.c */ +enum gps_dl_hal_power_ctrl_op_enum { + GPS_DL_HAL_POWER_OFF = 0, + GPS_DL_HAL_POWER_ON = 1, + GPS_DL_HAL_ENTER_DPSLEEP = 2, + GPS_DL_HAL_LEAVE_DPSLEEP = 3, + GPS_DL_HAL_ENTER_DPSTOP = 4, + GPS_DL_HAL_LEAVE_DPSTOP = 5, + GPS_DL_HAL_POWER_OP_MAX +}; + +bool gps_dl_hal_conn_infra_driver_on(void); +void gps_dl_hal_conn_infra_driver_off(void); +void gps_dl_hal_link_confirm_dma_stop(enum gps_dl_link_id_enum link_id); +int gps_dl_hal_conn_power_ctrl(enum gps_dl_link_id_enum link_id, int op); +int gps_dl_hal_link_power_ctrl(enum gps_dl_link_id_enum link_id, + enum gps_dl_hal_power_ctrl_op_enum op); +int gps_dl_hal_link_power_ctrl_inner(enum gps_dl_link_id_enum link_id, + enum gps_dl_hal_power_ctrl_op_enum op); +void gps_dl_hal_link_clear_hw_pwr_stat(enum gps_dl_link_id_enum link_id); +#if GPS_DL_ON_LINUX +bool gps_dl_hal_md_blanking_init_pta(void); +void gps_dl_hal_md_blanking_deinit_pta(void); +#endif +void gps_dl_hal_md_blanking_ctrl(bool on); +void gps_dl_hal_a2d_tx_dma_start(enum gps_dl_link_id_enum link_id, + struct gdl_dma_buf_entry *p_entry); +void gps_dl_hal_d2a_rx_dma_start(enum gps_dl_link_id_enum link_id, + struct gdl_dma_buf_entry *p_entry); + +void gps_dl_hal_a2d_tx_dma_stop(enum gps_dl_link_id_enum link_id); +void gps_dl_hal_d2a_rx_dma_stop(enum gps_dl_link_id_enum link_id); + +unsigned int gps_dl_hal_d2a_rx_dma_get_rx_len(enum gps_dl_link_id_enum link_id); +enum GDL_RET_STATUS gps_dl_hal_d2a_rx_dma_get_write_index( + enum gps_dl_link_id_enum link_id, unsigned int *p_write_index); + +enum GDL_RET_STATUS gps_dl_hal_a2d_tx_dma_wait_until_done_and_stop_it( + enum gps_dl_link_id_enum link_id, int timeout_usec, bool return_if_not_start); +enum GDL_RET_STATUS gps_dl_hal_d2a_rx_dma_wait_until_done( + enum gps_dl_link_id_enum link_id, int timeout_usec); +enum GDL_RET_STATUS gps_dl_hal_wait_and_handle_until_usrt_has_data( + enum gps_dl_link_id_enum link_id, int timeout_usec); +enum GDL_RET_STATUS gps_dl_hal_wait_and_handle_until_usrt_has_nodata_or_rx_dma_done( + enum gps_dl_link_id_enum link_id, int timeout_usec, bool to_handle); + +enum GDL_RET_STATUS gps_dl_hal_poll_event( + unsigned int L1_evt_in, unsigned int L5_evt_in, + unsigned int *pL1_evt_out, unsigned int *pL5_evt_out, unsigned int timeout_usec); + +int gps_dl_hal_usrt_direct_write(enum gps_dl_link_id_enum link_id, + unsigned char *buf, unsigned int len); +int gps_dl_hal_usrt_direct_read(enum gps_dl_link_id_enum link_id, + unsigned char *buf, unsigned int len); + +void gps_each_dsp_reg_read_ack( + enum gps_dl_link_id_enum link_id, const struct gps_dl_hal_mcub_info *p_d2a); +void gps_each_dsp_reg_gourp_read_init(enum gps_dl_link_id_enum link_id); +void gps_each_dsp_reg_gourp_read_start(enum gps_dl_link_id_enum link_id, + bool dbg, unsigned int round_max); + +enum GDL_RET_STATUS gps_each_dsp_reg_read_request( + enum gps_dl_link_id_enum link_id, unsigned int reg_addr); +void gps_each_dsp_reg_gourp_read_next(enum gps_dl_link_id_enum link_id, bool restart); + +bool gps_dl_hal_get_dma_irq_en_flag(void); +void gps_dl_hal_set_dma_irq_en_flag(bool enable); +bool gps_dl_hal_get_mcub_irq_dis_flag(enum gps_dl_link_id_enum link_id); +void gps_dl_hal_set_mcub_irq_dis_flag(enum gps_dl_link_id_enum link_id, bool disable); +bool gps_dl_hal_get_irq_dis_flag(enum gps_dl_link_id_enum link_id, + enum gps_dl_each_link_irq_type type); +void gps_dl_hal_set_irq_dis_flag(enum gps_dl_link_id_enum link_id, + enum gps_dl_each_link_irq_type type, bool disable); +bool gps_dl_hal_get_need_clk_ext_flag(enum gps_dl_link_id_enum link_id); +void gps_dl_hal_set_need_clk_ext_flag(enum gps_dl_link_id_enum link_id, bool need); + +#define GPSDL_CLOCK_FLAG_TCXO (0x00) +#define GPSDL_CLOCK_FLAG_COTMS (0x21) +#define GPSDL_CLOCK_FLAG_52M_COTMS (0x51) +int gps_dl_hal_get_clock_flag(void); +void gps_dl_hal_load_clock_flag(void); + +void gps_dl_hal_set_conn_infra_ver(unsigned int ver); +unsigned int gps_dl_hal_get_conn_infra_ver(void); +bool gps_dl_hal_conn_infra_ver_is_mt6885(void); + +#endif /* _GPS_DL_HAL_H */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hal/inc/gps_dl_hal_api.h b/drivers/misc/mediatek/connectivity/gps/data_link/hal/inc/gps_dl_hal_api.h new file mode 100644 index 0000000000000000000000000000000000000000..bc55ec04ebc9d7c9bd5e24160bbcda7274e97153 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hal/inc/gps_dl_hal_api.h @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#ifndef _GPS_DL_HAL_API_H +#define _GPS_DL_HAL_API_H + +#include "gps_dl_config.h" +#include "gps_dl_dma_buf.h" + +/* provide function declaration for gps_dl_hal.c */ +/* the functions are implemented in hal/gps_dl*.c */ +enum gps_dl_hal_event_id { + GPS_DL_HAL_EVT_A2D_TX_DMA_DONE, + GPS_DL_HAL_EVT_D2A_RX_HAS_DATA, + GPS_DL_HAL_EVT_D2A_RX_DMA_DONE, + GPS_DL_HAL_EVT_D2A_RX_HAS_NODATA, + GPS_DL_HAL_EVT_MCUB_HAS_IRQ, + GPS_DL_HAL_EVT_DSP_ROM_START, + GPS_DL_HAL_EVT_DSP_RAM_START, + GPS_DL_HAL_EVT_A2D_TX_DMA_TIMEOUT, /* exception */ + GPS_DL_HAL_EVT_A2D_RX_DMA_TIMEOUT, + GPS_DL_HAL_EVT_DMA_ISR_PENDING, + GPD_DL_HAL_EVT_NUM +}; + +enum gps_dl_hal_poll_id { + GPS_DL_POLL_TX_DMA_DONE, + GPS_DL_POLL_RX_DMA_DONE, + GPS_DL_POLL_USRT_HAS_DATA, + GPS_DL_POLL_USRT_HAS_NODATA, + GPS_DL_POLL_MCUB_D2A_FLAG_SET, + GPS_DL_POLL_MAX +}; + +void gps_dl_hal_event_send(enum gps_dl_hal_event_id evt, + enum gps_dl_link_id_enum link_id); + +void gps_dl_hal_event_proc(enum gps_dl_hal_event_id evt, + enum gps_dl_link_id_enum link_id, int sid_on_evt); + +/* DMA operations */ +enum gps_dl_hal_dma_ch_index { + GPS_DL_DMA_LINK0_A2D, + GPS_DL_DMA_LINK0_D2A, + GPS_DL_DMA_LINK1_A2D, + GPS_DL_DMA_LINK1_D2A, + GPS_DL_DMA_CH_NUM, +}; + +enum gps_dl_hal_emi_user { + GPS_DL_EMI_USER_TX_DMA0 = GPS_DL_DMA_LINK0_A2D, + GPS_DL_EMI_USER_RX_DMA0 = GPS_DL_DMA_LINK0_D2A, + GPS_DL_EMI_USER_TX_DMA1 = GPS_DL_DMA_LINK1_A2D, + GPS_DL_EMI_USER_RX_DMA1 = GPS_DL_DMA_LINK1_D2A, + GPS_DL_EMI_USER_ICAP, /* reserved, driver not use it */ + GPS_DL_EMI_USER_GPS_ON, /* may remove this user later */ + GPS_DL_EMI_USER_NUM +}; + +#define DMA_CH_TO_LINK_ID(ch) (\ + ((ch) == GPS_DL_DMA_LINK0_A2D || (ch) == GPS_DL_DMA_LINK0_D2A) ? GPS_DATA_LINK_ID0 : (\ + ((ch) == GPS_DL_DMA_LINK1_A2D || (ch) == GPS_DL_DMA_LINK1_D2A) ? GPS_DATA_LINK_ID1 : (\ + 0xFF))) + +#define DMA_CH_IS_TX(ch) \ + ((ch) == GPS_DL_DMA_LINK0_A2D || (ch) == GPS_DL_DMA_LINK1_A2D) + +#define DMA_CH_IS_RX(ch) \ + ((ch) == GPS_DL_DMA_LINK0_D2A || (ch) == GPS_DL_DMA_LINK1_D2A) + +#define GET_TX_DMA_CH_OF(link_id) \ + CHOOSE_BY_LINK_ID(link_id, GPS_DL_DMA_LINK0_A2D, GPS_DL_DMA_LINK1_A2D, 0xFF) + +#define GET_RX_DMA_CH_OF(link_id) \ + CHOOSE_BY_LINK_ID(link_id, GPS_DL_DMA_LINK0_D2A, GPS_DL_DMA_LINK1_D2A, 0xFF) + +void gps_dl_hal_dma_init(void); + +void gps_dl_hal_dma_config(enum gps_dl_hal_dma_ch_index ch); +void gps_dl_hal_dma_start(enum gps_dl_hal_dma_ch_index ch, + struct gdl_dma_buf_entry *p_entry); +void gps_dl_hal_dma_stop(enum gps_dl_hal_dma_ch_index ch); + +void gps_dl_emi_remap_calc_and_set(void); +enum GDL_RET_STATUS gps_dl_emi_remap_phy_to_bus_addr(unsigned int phy_addr, unsigned int *bus_addr); + +void gps_dl_hal_emi_usage_init(void); +void gps_dl_hal_emi_usage_deinit(void); +void gps_dl_hal_emi_usage_claim(enum gps_dl_hal_emi_user user, bool use_emi); +void gps_dl_hal_a2d_tx_dma_claim_emi_usage(enum gps_dl_link_id_enum link_id, bool use_emi); +void gps_dl_hal_d2a_rx_dma_claim_emi_usage(enum gps_dl_link_id_enum link_id, bool use_emi); + + +#endif /* _GPS_DL_HAL_API_H */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hal/inc/gps_dl_hal_type.h b/drivers/misc/mediatek/connectivity/gps/data_link/hal/inc/gps_dl_hal_type.h new file mode 100644 index 0000000000000000000000000000000000000000..20a4b3eca05fb680d8f41143025b8c2f9877b30a --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hal/inc/gps_dl_hal_type.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#ifndef _GPS_DL_HAL_TYPE_H +#define _GPS_DL_HAL_TYPE_H + +struct gps_dl_hal_mcub_info { + unsigned int flag; + unsigned int dat0; + unsigned int dat1; +}; + +#endif /* _GPS_DL_HAL_TYPE_H */ diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hal/inc/gps_dl_hal_util.h b/drivers/misc/mediatek/connectivity/gps/data_link/hal/inc/gps_dl_hal_util.h new file mode 100644 index 0000000000000000000000000000000000000000..f32ef2c7b01753bfabf160f392985afb11f0f69e --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hal/inc/gps_dl_hal_util.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#ifndef _GPS_DL_HAL_UTIL_H +#define _GPS_DL_HAL_UTIL_H + + + +/* bool gps_dl_hal_get_dma_int_status(enum gps_dl_hal_dma_ch_index channel); */ + + +enum GPS_DL_HWCR_OWNER_ENUM { + GPS_DL_HWCR_OWNER_POS, /* for power on sequence */ + GPS_DL_HWCR_OWNER_DMA, /* for dma control */ + GPS_DL_HWCR_OWNER_NUM +}; + + +/* Must claim the owner before access hardware control registers */ +enum GDL_RET_STATUS gps_dl_hwcr_access_claim(enum GPS_DL_HWCR_OWNER_ENUM owner); +enum GDL_RET_STATUS gps_dl_hwcr_access_disclaim(enum GPS_DL_HWCR_OWNER_ENUM owner); + + +#endif /* _GPS_DL_HAL_UTIL_H */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hal/inc/gps_dl_isr.h b/drivers/misc/mediatek/connectivity/gps/data_link/hal/inc/gps_dl_isr.h new file mode 100644 index 0000000000000000000000000000000000000000..a478d0e132bc14a0721141b939233db35659ae3d --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hal/inc/gps_dl_isr.h @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#ifndef _GPS_DL_ISR_H +#define _GPS_DL_ISR_H + +#include "gps_dl_config.h" +#include "gps_each_link.h" + +enum gps_dl_irq_index_enum { + GPS_DL_IRQ_LINK0_DATA, + GPS_DL_IRQ_LINK0_NODATA, + GPS_DL_IRQ_LINK0_MCUB, + GPS_DL_IRQ_LINK1_DATA, + GPS_DL_IRQ_LINK1_NODATA, + GPS_DL_IRQ_LINK1_MCUB, + GPS_DL_IRQ_DMA, + GPS_DL_IRQ_NUM, +}; + +enum gps_dl_irq_trigger_type { + GPS_DL_IRQ_TRIG_LEVEL_HIGH, + GPS_DL_IRQ_TRIG_EDGE_RISING, + GPS_DL_IRQ_TRIG_NUM, +}; + +struct gps_each_irq_cfg { + int sens_type; + enum gps_dl_irq_index_enum index; + void *isr; + const char *name; + enum gps_dl_irq_trigger_type trig_type; +}; + +struct gps_each_irq { + struct gps_each_irq_cfg cfg; + bool register_done; + int reg_irq_id; +}; + +#define IRQ_IDX_IS_VALID(irq_idx) \ + (((irq_idx) >= 0) && ((irq_idx) < GPS_DL_IRQ_NUM)) + +#define ASSERT_IRQ_IDX(irq_idx, ret) \ + GDL_ASSERT(IRQ_IDX_IS_VALID(irq_idx), ret, "invalid irq index: %d", irq_idx) + +struct gps_each_irq *gps_dl_irq_get(enum gps_dl_irq_index_enum irq_idx); + + +enum gps_dl_each_link_irq_type { + GPS_DL_IRQ_TYPE_HAS_DATA, + GPS_DL_IRQ_TYPE_HAS_NODATA, + GPS_DL_IRQ_TYPE_MCUB, + GPS_DL_IRQ_TYPE_NUM, +}; +#define IRQ_TYPE_IS_VALID(irq_type) \ + (((irq_type) >= 0) && ((irq_type) < GPS_DL_IRQ_TYPE_NUM)) + +#define ASSERT_IRQ_TYPE(irq_type, ret) \ + GDL_ASSERT(IRQ_TYPE_IS_VALID(irq_type), ret, "invalid irq type: %d", irq_type) + + +enum gps_dl_irq_ctrl_from { + GPS_DL_IRQ_CTRL_FROM_ISR, + GPS_DL_IRQ_CTRL_FROM_THREAD, + GPS_DL_IRQ_CTRL_FROM_MAX, +}; + +#if GPS_DL_USE_THREADED_IRQ +/* + * #define GPS_DL_IRQ_CTRL_POSSIBLE_FROM_ISR GPS_DL_IRQ_CTRL_FROM_THREAD + * threaded_irq still can't call disable_irq + */ +#define GPS_DL_IRQ_CTRL_POSSIBLE_FROM_ISR GPS_DL_IRQ_CTRL_FROM_ISR +#else +#define GPS_DL_IRQ_CTRL_POSSIBLE_FROM_ISR GPS_DL_IRQ_CTRL_FROM_ISR +#endif + +#if GPS_DL_HAS_CTRLD +#define GPS_DL_IRQ_CTRL_FROM_HAL GPS_DL_IRQ_CTRL_FROM_THREAD +#else +#define GPS_DL_IRQ_CTRL_FROM_HAL GPS_DL_IRQ_CTRL_POSSIBLE_FROM_ISR +#endif + + +void gps_dl_irq_mask(int irq_id, enum gps_dl_irq_ctrl_from from); +void gps_dl_irq_unmask(int irq_id, enum gps_dl_irq_ctrl_from from); + +#if GPS_DL_ON_LINUX +void gps_dl_irq_set_id(enum gps_dl_irq_index_enum irq_idx, int irq_id); +#endif + +int gps_dl_irq_index_to_id(enum gps_dl_irq_index_enum irq_idx); +int gps_dl_irq_type_to_id(enum gps_dl_link_id_enum link_id, + enum gps_dl_each_link_irq_type irq_type); +int gps_dl_irq_type_to_hwirq(enum gps_dl_link_id_enum link_id, + enum gps_dl_each_link_irq_type irq_type); + +void gps_dl_irq_each_link_control(enum gps_dl_link_id_enum link_id, + enum gps_dl_each_link_irq_type irq_type, bool mask_it, enum gps_dl_irq_ctrl_from from); +void gps_dl_irq_each_link_mask(enum gps_dl_link_id_enum link_id, + enum gps_dl_each_link_irq_type irq_type, enum gps_dl_irq_ctrl_from from); +void gps_dl_irq_each_link_unmask(enum gps_dl_link_id_enum link_id, + enum gps_dl_each_link_irq_type irq_type, enum gps_dl_irq_ctrl_from from); + +int gps_dl_irq_init(void); +int gps_dl_irq_deinit(void); +void gps_dl_irq_mask_dma_intr(enum gps_dl_irq_ctrl_from from); +void gps_dl_irq_unmask_dma_intr(enum gps_dl_irq_ctrl_from from); + +void gps_dl_isr_usrt_has_data(enum gps_dl_link_id_enum link_id); +void gps_dl_isr_usrt_has_nodata(enum gps_dl_link_id_enum link_id); +void gps_dl_isr_a2d_tx_dma_done(enum gps_dl_link_id_enum link_id); +void gps_dl_isr_d2a_rx_dma_done(enum gps_dl_link_id_enum link_id); +void gps_dl_isr_mcub(enum gps_dl_link_id_enum link_id); +bool gps_dl_hal_mcub_flag_handler(enum gps_dl_link_id_enum link_id); + +#if GPS_DL_ON_CTP +void gps_dl_isr_dl0_has_data(void); +void gps_dl_isr_dl0_has_nodata(void); +void gps_dl_isr_dl0_mcub(void); +void gps_dl_isr_dl1_has_data(void); +void gps_dl_isr_dl1_has_nodata(void); +void gps_dl_isr_dl1_mcub(void); +#endif + +void gps_dl_isr_dma_done(void); + +#endif /* _GPS_DL_ISR_H */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hal/inc/gps_dsp_fsm.h b/drivers/misc/mediatek/connectivity/gps/data_link/hal/inc/gps_dsp_fsm.h new file mode 100644 index 0000000000000000000000000000000000000000..f8ed928d69588f6ecb3d879c704d28a0e4bb111d --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hal/inc/gps_dsp_fsm.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#ifndef _GPS_DSP_FSM_H_ +#define _GPS_DSP_FSM_H_ + +#include "gps_dl_config.h" + +enum gps_dsp_state_t { + /* GPS and DSP are function off */ + GPS_DSP_ST_OFF, /* 0 */ + + /* MCU turned DSP on and just released the reset flag */ + GPS_DSP_ST_TURNED_ON, /* 1 */ + + /* DSP notified MCU about it's reset flow done */ + /* It will also stand for DSP finished Mbist flow if DSP has this flow */ + /* MCU should suspend the data reoute until change to this state */ + /* When change to this state, MVCD flow should start immediately */ + GPS_DSP_ST_RESET_DONE, /* 2 */ + + /* DSP raw code download finish/DSP wakeup and raw code start working */ + GPS_DSP_ST_WORKING, /* 3 */ + + /* DSP in HW sleep mode for GLP duty cycle mode */ + GPS_DSP_ST_HW_SLEEP_MODE, /* 4 */ + + /* DSP in HW stop mode. MVCD flow can be skipped after wakeup */ + GPS_DSP_ST_HW_STOP_MODE, /* 5 */ + + /* Wakeup from sleep/stop mode */ + /* No MVCD procedure, should directly goto GPS_DSP_ST_WORKING */ + GPS_DSP_ST_WAKEN_UP, /* 6 */ + + GPS_DSP_ST_MAX +}; + + +/* DSP to MCU MCUB flag bit usage definition */ +#define GPS_MCUB_D2AF_MASK_DSP_RAMCODE_READY 0x1 /* bit0 */ +#define GPS_MCUB_D2AF_MASK_DSP_REG_READ_READY 0x2 /* bit1 */ +#define GPS_MCUB_D2AF_MASK_DSP_REQUEST_MCU_ACTION 0x4 /* bit2 */ +/* To be renamed to GPS_MCUB_D2AF_MASK_DSP_RESET_DONE */ +/* #define GPS_MCUB_D2AF_MASK_DSP_MBIST_READY 0b1000 */ +#define GPS_MCUB_D2AF_MASK_DSP_RESET_DONE 0x8 /* bit3 */ + + +/* MCU to DSP MCUB flag bit usage definition */ +#define GPS_MCUB_A2DF_MASK_DSP_DCLK_79MHZ_REQ 0x1 /* bit0 */ +#define GPS_MCUB_A2DF_MASK_DSP_DCLK_88MHZ_REQ 0x2 /* bit1 */ +#define GPS_MCUB_A2DF_MASK_DSP_REG_READ_REQ 0x4 /* bit2 */ +/* Will be available on MT6779. The previous chips don't use it */ +#define GPS_MCUB_A2DF_MASK_DSP_SET_CFG_REQ 0x8 /* bit3 */ + + +enum gps_dsp_event_t { + GPS_DSP_EVT_FUNC_OFF, /* 0 From host */ + GPS_DSP_EVT_FUNC_ON, /* 1 From host */ + GPS_DSP_EVT_RESET_DONE, /* 2 From DSP D2AF[3] */ + GPS_DSP_EVT_RAM_CODE_READY, /* 3 From DSP D2AF[0] */ + GPS_DSP_EVT_CTRL_TIMER_EXPIRE, /* 4 From timer */ + GPS_DSP_EVT_HW_SLEEP_REQ, /* 5 From DSP D2AF[2] - DSP request it; from host for test */ + GPS_DSP_EVT_HW_SLEEP_EXIT, /* 6 From host - just for test */ + GPS_DSP_EVT_HW_STOP_REQ, /* 7 From host */ + GPS_DSP_EVT_HW_STOP_EXIT, /* 8 From host */ + GPS_DSP_EVT_MAX +}; + +#define GPS_DSP_RESET_TIMEOUT_MS (180) +#define GPS_DSP_MVCD_TIMEOUT_MS (1000) +#define GPS_DSP_WAKEUP_TIMEOUT_MS (180) + + +enum gps_dsp_state_t gps_dsp_state_get(enum gps_dl_link_id_enum link_id); +void gps_dsp_state_change_to(enum gps_dsp_state_t state, enum gps_dl_link_id_enum link_id); +bool gps_dsp_state_is(enum gps_dsp_state_t state, enum gps_dl_link_id_enum link_id); + +void gps_dsp_fsm(enum gps_dsp_event_t evt, enum gps_dl_link_id_enum link_id); + +#endif /* _GPS_DSP_FSM_H_ */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hal/inc/hal_common.h b/drivers/misc/mediatek/connectivity/gps/data_link/hal/inc/hal_common.h new file mode 100644 index 0000000000000000000000000000000000000000..ca22ff30bf1dc90f76d5c1614d37cb169a374179 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hal/inc/hal_common.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#ifndef ___HAL_COMMON_H__ +#define ___HAL_COMMON_H__ + + +#endif /* ___HAL_COMMON_H__ */ diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hw/gps_dl_hw_bgf.c b/drivers/misc/mediatek/connectivity/gps/data_link/hw/gps_dl_hw_bgf.c new file mode 100644 index 0000000000000000000000000000000000000000..8faa31121fab5a6c4dc9e069133e1cf4fd647466 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hw/gps_dl_hw_bgf.c @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#include "gps_dl_config.h" +#include "gps_dl_hw_priv_util.h" +/* #include "bgf/bgf_cfg.h" */ +/* #include "bgf/bgf_cfg_on.h" */ + +#define BGF_ADDR_ENTRY_NUM (1) +static const struct gps_dl_addr_map_entry g_bfg_addr_table[BGF_ADDR_ENTRY_NUM] = { + {0, 0, 0} + /* {0x18812000, BGF_CFG_BASE, 0x1000}, */ + /* {0x18813000, BGF_CFG_ON_BASE, 0x1000}, */ +}; + +unsigned int bgf_bus_to_host(unsigned int bgf_addr) +{ + unsigned int i; + const struct gps_dl_addr_map_entry *p; + + for (i = 0; i < BGF_ADDR_ENTRY_NUM; i++) { + p = &g_bfg_addr_table[i]; + if (bgf_addr >= p->bus_addr && + bgf_addr < (p->bus_addr + p->length)) + return ((bgf_addr - p->bus_addr) + p->host_addr); + } + + return 0; +} + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hw/gps_dl_hw_conn_infra.c b/drivers/misc/mediatek/connectivity/gps/data_link/hw/gps_dl_hw_conn_infra.c new file mode 100644 index 0000000000000000000000000000000000000000..1ef54eb63e08ef627a5a0e53edb680c60028e034 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hw/gps_dl_hw_conn_infra.c @@ -0,0 +1,680 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#include "gps_dl_config.h" + +#include "gps_dl_context.h" +#include "gps_dl_hw_api.h" +#include "gps_dl_hw_dep_api.h" +#include "gps_dl_hw_priv_util.h" + +#include "conn_infra/conn_host_csr_top.h" +#include "conn_infra/conn_infra_cfg.h" +#if GPS_DL_HAS_PTA +#include "conn_infra/conn_uart_pta.h" +#include "conn_infra/conn_pta6.h" +#endif +#include "conn_infra/conn_semaphore.h" +#include "conn_infra/conn_rf_spi_mst_reg.h" + +void gps_dl_hw_set_gps_emi_remapping(unsigned int _20msb_of_36bit_phy_addr) +{ + GDL_HW_SET_CONN_INFRA_ENTRY( + CONN_HOST_CSR_TOP_CONN2AP_REMAP_GPS_EMI_BASE_ADDR_CONN2AP_REMAP_GPS_EMI_BASE_ADDR, + _20msb_of_36bit_phy_addr); +} + +unsigned int gps_dl_hw_get_gps_emi_remapping(void) +{ + return GDL_HW_GET_CONN_INFRA_ENTRY( + CONN_HOST_CSR_TOP_CONN2AP_REMAP_GPS_EMI_BASE_ADDR_CONN2AP_REMAP_GPS_EMI_BASE_ADDR); +} + +void gps_dl_hw_print_hw_status(enum gps_dl_link_id_enum link_id, bool dump_rf_cr) +{ + struct gps_dl_hw_dma_status_struct a2d_dma_status, d2a_dma_status; + struct gps_dl_hw_usrt_status_struct usrt_status; + enum gps_dl_hal_dma_ch_index a2d_dma_ch, d2a_dma_ch; + + if (gps_dl_show_reg_wait_log()) + GDL_LOGXD(link_id, ""); + + if (link_id == GPS_DATA_LINK_ID0) { + a2d_dma_ch = GPS_DL_DMA_LINK0_A2D; + d2a_dma_ch = GPS_DL_DMA_LINK0_D2A; + } else if (link_id == GPS_DATA_LINK_ID1) { + a2d_dma_ch = GPS_DL_DMA_LINK1_A2D; + d2a_dma_ch = GPS_DL_DMA_LINK1_D2A; + } else + return; + + gps_dl_hw_save_usrt_status_struct(link_id, &usrt_status); + gps_dl_hw_print_usrt_status_struct(link_id, &usrt_status); + + gps_dl_hw_save_dma_status_struct(a2d_dma_ch, &a2d_dma_status); + gps_dl_hw_print_dma_status_struct(a2d_dma_ch, &a2d_dma_status); + + gps_dl_hw_save_dma_status_struct(d2a_dma_ch, &d2a_dma_status); + gps_dl_hw_print_dma_status_struct(d2a_dma_ch, &d2a_dma_status); + + GDL_HW_RD_GPS_REG(0x80073160); /* DL0 */ + GDL_HW_RD_GPS_REG(0x80073134); /* DL1 */ + + GDL_HW_RD_CONN_INFRA_REG(CONN_RF_SPI_MST_ADDR_SPI_STA_ADDR); + GDL_HW_RD_CONN_INFRA_REG(CONN_RF_SPI_MST_ADDR_SPI_GPS_GPS_ADDR_ADDR); + GDL_HW_RD_CONN_INFRA_REG(CONN_RF_SPI_MST_ADDR_SPI_GPS_GPS_WDAT_ADDR); + GDL_HW_RD_CONN_INFRA_REG(CONN_RF_SPI_MST_ADDR_SPI_GPS_GPS_RDAT_ADDR); + GDL_HW_RD_CONN_INFRA_REG(CONN_RF_SPI_MST_ADDR_SPI_STA_ADDR); + + if (dump_rf_cr) { + gps_dl_hw_gps_dump_top_rf_cr(); + gps_dl_hw_gps_dump_gps_rf_cr(); + } + + /* only need for L1 */ + gps_each_link_set_bool_flag(GPS_DATA_LINK_ID0, LINK_NEED_A2Z_DUMP, true); +} + +void gps_dl_hw_do_gps_a2z_dump(void) +{ + GDL_HW_WR_GPS_REG(0x80073120, 1); /* enable A2Z */ + GDL_HW_RD_GPS_REG(0x800706C0); + GDL_HW_RD_GPS_REG(0x80070450); + GDL_HW_RD_GPS_REG(0x80080450); +} + +void gps_dl_hw_dump_sleep_prot_status(void) +{ + bool show_log = true; + + show_log = gps_dl_set_show_reg_rw_log(true); + GDL_HW_DUMP_SLP_RPOT_STATUS(); + gps_dl_set_show_reg_rw_log(show_log); +} + +void gps_dl_hw_dump_host_csr_gps_info(bool force_show_log) +{ + int i; + bool show_log = true; + + if (force_show_log) + show_log = gps_dl_set_show_reg_rw_log(true); + +#if 0 + GDL_HW_GET_CONN_INFRA_ENTRY(CONN_HOST_CSR_TOP_HOST2GPS_DEGUG_SEL_HOST2GPS_DEGUG_SEL); + GDL_HW_GET_CONN_INFRA_ENTRY(CONN_HOST_CSR_TOP_GPS_CFG2HOST_DEBUG_GPS_CFG2HOST_DEBUG); +#else + gps_dl_bus_rd_opt(GPS_DL_CONN_INFRA_BUS, + CONN_HOST_CSR_TOP_HOST2GPS_DEGUG_SEL_ADDR, + BMASK_RW_FORCE_PRINT); + gps_dl_bus_rd_opt(GPS_DL_CONN_INFRA_BUS, + CONN_HOST_CSR_TOP_GPS_CFG2HOST_DEBUG_ADDR, + BMASK_RW_FORCE_PRINT); +#endif + + for (i = 0xA2; i <= 0xB7; i++) { +#if 0 + GDL_HW_SET_CONN_INFRA_ENTRY(CONN_HOST_CSR_TOP_HOST2GPS_DEGUG_SEL_HOST2GPS_DEGUG_SEL, i); + GDL_HW_GET_CONN_INFRA_ENTRY(CONN_HOST_CSR_TOP_GPS_CFG2HOST_DEBUG_GPS_CFG2HOST_DEBUG); +#else + gps_dl_bus_wr_opt(GPS_DL_CONN_INFRA_BUS, + CONN_HOST_CSR_TOP_HOST2GPS_DEGUG_SEL_ADDR, i, + BMASK_RW_FORCE_PRINT); + gps_dl_bus_rd_opt(GPS_DL_CONN_INFRA_BUS, + CONN_HOST_CSR_TOP_GPS_CFG2HOST_DEBUG_ADDR, + BMASK_RW_FORCE_PRINT); +#endif + } + + if (force_show_log) + gps_dl_set_show_reg_rw_log(show_log); +} + +void gps_dl_bus_check_and_print(unsigned int host_addr) +{ + /* not do rw check because here is the checking */ + GDL_LOGI("for addr = 0x%08x", host_addr); + gps_dl_bus_wr_opt(GPS_DL_CONN_INFRA_BUS, + CONN_HOST_CSR_TOP_CONN_INFRA_DEBUG_AO_DEBUGSYS_ADDR, 0x000D0001, + BMASK_RW_FORCE_PRINT); + + gps_dl_bus_rd_opt(GPS_DL_CONN_INFRA_BUS, + CONN_HOST_CSR_TOP_CONN_INFRA_DEBUG_CTRL_AO2SYS_OUT_ADDR, + BMASK_RW_FORCE_PRINT); + + gps_dl_bus_wr_opt(GPS_DL_CONN_INFRA_BUS, + CONN_HOST_CSR_TOP_CONN_INFRA_DEBUG_AO_DEBUGSYS_ADDR, 0x000B0001, + BMASK_RW_FORCE_PRINT); + + gps_dl_bus_rd_opt(GPS_DL_CONN_INFRA_BUS, + CONN_HOST_CSR_TOP_CONN_INFRA_DEBUG_CTRL_AO2SYS_OUT_ADDR, + BMASK_RW_FORCE_PRINT); + + gps_dl_bus_wr_opt(GPS_DL_CONN_INFRA_BUS, + CONN_HOST_CSR_TOP_CONN_INFRA_DEBUG_AO_DEBUGSYS_ADDR, 0x000A0001, + BMASK_RW_FORCE_PRINT); + + gps_dl_bus_rd_opt(GPS_DL_CONN_INFRA_BUS, + CONN_HOST_CSR_TOP_CONN_INFRA_DEBUG_CTRL_AO2SYS_OUT_ADDR, + BMASK_RW_FORCE_PRINT); +} + +void gps_dl_hw_dump_host_csr_conninfra_info_inner(unsigned int selection, int n) +{ + int i; + + for (i = 0; i < n; i++) { +#if 0 + GDL_HW_SET_CONN_INFRA_ENTRY( + CONN_HOST_CSR_TOP_CONN_INFRA_DEBUG_AO_DEBUGSYS_CONN_INFRA_DEBUG_CTRL_AO_DEBUGSYS_CTRL, + selection); + GDL_HW_GET_CONN_INFRA_ENTRY( + CONN_HOST_CSR_TOP_CONN_INFRA_DEBUG_CTRL_AO2SYS_OUT_CONN_INFRA_DEBUG_CTRL_AO2SYS_OUT); +#else + /* Due to RW_DO_CHECK might be enabled, not use + * GDL_HW_SET_CONN_INFRA_ENTRY and GDL_HW_GET_CONN_INFRA_ENTRY to avoid redundant print. + */ + gps_dl_bus_wr_opt(GPS_DL_CONN_INFRA_BUS, + CONN_HOST_CSR_TOP_CONN_INFRA_DEBUG_AO_DEBUGSYS_ADDR, selection, + BMASK_RW_FORCE_PRINT); + + gps_dl_bus_rd_opt(GPS_DL_CONN_INFRA_BUS, + CONN_HOST_CSR_TOP_CONN_INFRA_DEBUG_CTRL_AO2SYS_OUT_ADDR, + BMASK_RW_FORCE_PRINT); +#endif + selection -= 0x10000; + } +} + +void gps_dl_hw_dump_host_csr_conninfra_info(bool force_show_log) +{ + bool show_log = true; + + if (force_show_log) + show_log = gps_dl_set_show_reg_rw_log(true); + + gps_dl_hw_dump_host_csr_conninfra_info_inner(0x000F0001, 15); + gps_dl_hw_dump_host_csr_conninfra_info_inner(0x00030002, 3); + gps_dl_hw_dump_host_csr_conninfra_info_inner(0x00040003, 4); + + if (force_show_log) + gps_dl_set_show_reg_rw_log(show_log); +} + +#if GPS_DL_HAS_PTA +/* CONN_INFRA_CFG_CKGEN_BUS_ADDR[5:2] */ +#define CONN_INFRA_CFG_PTA_CLK_ADDR CONN_INFRA_CFG_CKGEN_BUS_ADDR +#define CONN_INFRA_CFG_PTA_CLK_MASK (\ + CONN_INFRA_CFG_CKGEN_BUS_CONN_CO_EXT_UART_PTA_OSC_CKEN_MASK | \ + CONN_INFRA_CFG_CKGEN_BUS_CONN_CO_EXT_UART_PTA_HCLK_CKEN_MASK | \ + CONN_INFRA_CFG_CKGEN_BUS_CONN_CO_EXT_UART_PTA5_OSC_CKEN_MASK | \ + CONN_INFRA_CFG_CKGEN_BUS_CONN_CO_EXT_UART_PTA5_HCLK_CKEN_MASK) +#define CONN_INFRA_CFG_PTA_CLK_SHFT \ + CONN_INFRA_CFG_CKGEN_BUS_CONN_CO_EXT_UART_PTA5_HCLK_CKEN_SHFT + +bool gps_dl_hw_is_pta_clk_cfg_ready(void) +{ + unsigned int pta_clk_cfg; + bool okay = true; + + pta_clk_cfg = GDL_HW_GET_CONN_INFRA_ENTRY(CONN_INFRA_CFG_PTA_CLK); + if (pta_clk_cfg != 0xF) { + /* clock cfg is default ready, no need to set it + * if not as excepted, skip pta and pta_uart init + */ + okay = false; + } + + if (!okay) + GDL_LOGE("pta_clk_cfg = 0x%x", pta_clk_cfg); + return okay; +} + +void gps_dl_hw_set_ptk_clk_cfg(void) +{ + GDL_HW_SET_CONN_INFRA_ENTRY(CONN_INFRA_CFG_PTA_CLK, 0xF); +} + +bool gps_dl_hw_is_pta_uart_init_done(void) +{ + bool done; + unsigned int pta_uart_en; + + pta_uart_en = GDL_HW_GET_CONN_INFRA_ENTRY(CONN_PTA6_RO_PTA_CTRL_ro_uart_apb_hw_en); + done = (pta_uart_en == 1); + GDL_LOGD("done = %d, pta_uart_en = %d", done, pta_uart_en); + + return done; +} + +/* Only check bit7, so not use CONN_UART_PTA_FCR_RFTL */ +#define CONN_UART_PTA_FCR_RFTL_HIGH_BIT_ADDR CONN_UART_PTA_FCR_ADDR +#define CONN_UART_PTA_FCR_RFTL_HIGH_BIT_MASK 0x00000080 +#define CONN_UART_PTA_FCR_RFTL_HIGH_BIT_SHFT 7 + +bool gps_dl_hw_init_pta_uart(void) +{ +#if 0 + unsigned int pta_uart_en; +#endif + bool show_log; + bool poll_okay; + bool reg_rw_log = gps_dl_log_reg_rw_is_on(GPS_DL_REG_RW_HOST_CSR_PTA_INIT); + + /* 20191008 after DE checking, bellow steps are no need */ +#if 0 + /* Set pta uart to MCU mode before init it. + * Note: both wfset and btset = 0, then pta_uart_en should become 0, + * set one of them = 1, then pta_uart_en should become 1. + */ + GDL_HW_SET_CONN_INFRA_ENTRY(CONN_PTA6_WFSET_PTA_CTRL_r_wfset_uart_apb_hw_en, 0); + GDL_HW_SET_CONN_INFRA_ENTRY(CONN_PTA6_BTSET_PTA_CTRL_r_btset_uart_apb_hw_en, 0); + pta_uart_en = GDL_HW_GET_CONN_INFRA_ENTRY(CONN_PTA6_RO_PTA_CTRL_ro_uart_apb_hw_en); + + if (pta_uart_en != 0) { + GDL_LOGE("ro_uart_apb_hw_en not become 0, fail"); + return false; + } +#endif + + if (reg_rw_log) { + gps_dl_hw_dump_host_csr_conninfra_info(true); + show_log = gps_dl_set_show_reg_rw_log(true); + } + GDL_HW_SET_CONN_INFRA_ENTRY(CONN_UART_PTA_HIGHSPEED_SPEED, 3); + GDL_HW_SET_CONN_INFRA_ENTRY(CONN_UART_PTA_SAMPLE_COUNT_SAMPLE_COUNT, 5); + GDL_HW_SET_CONN_INFRA_ENTRY(CONN_UART_PTA_SAMPLE_POINT_SAMPLE_POINT, 2); + + /* UART_PTA_BASE + 0x3C = 0x12, this step is no-need now + * GDL_HW_SET_CONN_INFRA_ENTRY(CONN_UART_PTA_GUARD_GUARD_CNT, 2); + * GDL_HW_SET_CONN_INFRA_ENTRY(CONN_UART_PTA_GUARD_GUARD_EN, 1); + */ + + GDL_HW_SET_CONN_INFRA_ENTRY(CONN_UART_PTA_VFIFO_EN_RX_TIME_EN, 1); /* bit7 */ + GDL_HW_SET_CONN_INFRA_ENTRY(CONN_UART_PTA_VFIFO_EN_PTA_RX_FE_EN, 1); /* bit3 */ + GDL_HW_SET_CONN_INFRA_ENTRY(CONN_UART_PTA_VFIFO_EN_PTA_RX_MODE, 1); /* bit2 */ + + GDL_HW_SET_CONN_INFRA_ENTRY(CONN_UART_PTA_FRACDIV_L_FRACDIV_L, 0x55); + GDL_HW_SET_CONN_INFRA_ENTRY(CONN_UART_PTA_FRACDIV_M_FRACDIV_M, 2); + + /* UART_PTA_BASE + 0x3C[4] = 0, this step is no-need now + * GDL_HW_SET_CONN_INFRA_ENTRY(CONN_UART_PTA_GUARD_GUARD_EN, 0); + */ + + GDL_HW_WR_CONN_INFRA_REG(CONN_UART_PTA_LCR_ADDR, 0xBF); + GDL_HW_WR_CONN_INFRA_REG(CONN_UART_PTA_DLL_ADDR, 1); + GDL_HW_WR_CONN_INFRA_REG(CONN_UART_PTA_DLM_ADDR, 0); + GDL_HW_WR_CONN_INFRA_REG(CONN_UART_PTA_LCR_ADDR, 3); + + /* 20191008 after DE checking, add CONN_UART_PTA_FCR_ADDR read-back checking */ + + /* dump value before setting */ + GDL_HW_RD_CONN_INFRA_REG(CONN_UART_PTA_FCR_ADDR); + GDL_HW_WR_CONN_INFRA_REG(CONN_UART_PTA_FCR_ADDR, 0x37); + /* dump value after setting and poll until bit7 become 1 or timeout */ + GDL_HW_POLL_CONN_INFRA_ENTRY(CONN_UART_PTA_FCR_RFTL_HIGH_BIT, 1, POLL_DEFAULT, &poll_okay); + if (!poll_okay) { + if (reg_rw_log) + gps_dl_set_show_reg_rw_log(show_log); + GDL_LOGE("CONN_UART_PTA_FCR bit7 not become 1, fail"); + return false; + } + + GDL_HW_SET_CONN_INFRA_ENTRY(CONN_PTA6_WFSET_PTA_CTRL_r_wfset_uart_apb_hw_en, 1); + + /* 20191008 after DE checking, add this step */ + GDL_HW_SET_CONN_INFRA_ENTRY(CONN_PTA6_BTSET_PTA_CTRL_r_btset_uart_apb_hw_en, 1); + + GDL_HW_SET_CONN_INFRA_ENTRY(CONN_PTA6_WFSET_PTA_CTRL_r_wfset_lte_pta_en, 1); + + GDL_HW_SET_CONN_INFRA_ENTRY(CONN_PTA6_TMR_CTRL_1_r_idc_2nd_byte_tmout, 4); /* us */ + + if (reg_rw_log) + gps_dl_set_show_reg_rw_log(show_log); + + return true; +} + +void gps_dl_hw_deinit_pta_uart(void) +{ + /* Currently no need to do pta uart deinit */ +} + + +#define PTA_1M_CNT_VALUE 26 /* mobile platform uses 26M */ + +bool gps_dl_hw_is_pta_init_done(void) +{ + bool done; + unsigned int pta_en; + unsigned int pta_arb_en; + unsigned int pta_1m_cnt; + + pta_en = GDL_HW_GET_CONN_INFRA_ENTRY(CONN_PTA6_RO_PTA_CTRL_ro_pta_en); + pta_arb_en = GDL_HW_GET_CONN_INFRA_ENTRY(CONN_PTA6_RO_PTA_CTRL_ro_en_pta_arb); + pta_1m_cnt = GDL_HW_GET_CONN_INFRA_ENTRY(CONN_PTA6_PTA_CLK_CFG_r_pta_1m_cnt); + + done = ((pta_en == 1) && (pta_arb_en == 1) && (pta_1m_cnt == PTA_1M_CNT_VALUE)); + GDL_LOGD("done = %d, pta_en = %d, pta_arb_en = %d, pta_1m_cnt = 0x%x", + done, pta_en, pta_arb_en, pta_1m_cnt); + + return done; +} + +void gps_dl_hw_init_pta(void) +{ + unsigned int pta_en; + unsigned int pta_arb_en; + + GDL_HW_SET_CONN_INFRA_ENTRY(CONN_PTA6_PTA_CLK_CFG_r_pta_1m_cnt, PTA_1M_CNT_VALUE); + + /* Note: GPS use WFSET */ + GDL_HW_SET_CONN_INFRA_ENTRY(CONN_PTA6_WFSET_PTA_CTRL_r_wfset_en_pta_arb, 1); + GDL_HW_SET_CONN_INFRA_ENTRY(CONN_PTA6_WFSET_PTA_CTRL_r_wfset_pta_en, 1); + + /* just confirm status change properly */ + pta_en = GDL_HW_GET_CONN_INFRA_ENTRY(CONN_PTA6_RO_PTA_CTRL_ro_pta_en); + pta_arb_en = GDL_HW_GET_CONN_INFRA_ENTRY(CONN_PTA6_RO_PTA_CTRL_ro_en_pta_arb); + + if (!((pta_en == 1) && (pta_arb_en == 1))) { + /* should not happen, do nothing but just show log */ + GDL_LOGE("pta_en = %d, pta_arb_en = %d, fail", pta_en, pta_arb_en); + } else + GDL_LOGI("pta_en = %d, pta_arb_en = %d, okay", pta_en, pta_arb_en); +} + +void gps_dl_hw_deinit_pta(void) +{ + /* Currently no need to do pta deinit */ +} + + +void gps_dl_hw_claim_pta_used_by_gps(void) +{ + /* Currently it's empty */ +} + +void gps_dl_hw_disclaim_pta_used_by_gps(void) +{ + /* Currently it's empty */ +} + +void gps_dl_hw_set_pta_blanking_parameter(bool use_direct_path) +{ + if (use_direct_path) { + /* Use direct path - just cfg src, no other parameter */ + GDL_HW_SET_CONN_INFRA_ENTRY(CONN_PTA6_GPS_BLANK_CFG_r_gps_blank_src, 1); + return; + } + + /* Set timeout threashold: ms */ + GDL_HW_SET_CONN_INFRA_ENTRY(CONN_PTA6_TMR_CTRL_3_r_gps_l5_blank_tmr_thld, 3); + GDL_HW_SET_CONN_INFRA_ENTRY(CONN_PTA6_TMR_CTRL_3_r_gps_l1_blank_tmr_thld, 3); + + /* Set blanking source: both LTE and NR */ + GDL_HW_SET_CONN_INFRA_ENTRY(CONN_PTA6_GPS_BLANK_CFG_r_idc_gps_l1_blank_src, 2); + GDL_HW_SET_CONN_INFRA_ENTRY(CONN_PTA6_GPS_BLANK_CFG_r_idc_gps_l5_blank_src, 2); + + /* Use IDC mode */ + GDL_HW_SET_CONN_INFRA_ENTRY(CONN_PTA6_GPS_BLANK_CFG_r_gps_blank_src, 0); +} + +/* + * COS_SEMA_COEX_INDEX = 5(see conninfra/platform/include/consys_hw.h) + * GPS use M3 + */ +#define COS_SEMA_COEX_STA_ENTRY_FOR_GPS \ + CONN_SEMAPHORE_CONN_SEMA05_M3_OWN_STA_CONN_SEMA05_M3_OWN_STA + +#define COS_SEMA_COEX_REL_ENTRY_FOR_GPS \ + CONN_SEMAPHORE_CONN_SEMA05_M3_OWN_REL_CONN_SEMA05_M3_OWN_REL + +bool gps_dl_hw_take_conn_coex_hw_sema(unsigned int try_timeout_ms) +{ + bool okay; + bool show_log; + unsigned int poll_us, poll_max_us; + unsigned int val; + + show_log = gps_dl_set_show_reg_rw_log(true); + /* poll until value is expected or timeout */ + poll_us = 0; + poll_max_us = POLL_US * 1000 * try_timeout_ms; + okay = false; + while (!okay) { + val = GDL_HW_GET_CONN_INFRA_ENTRY(COS_SEMA_COEX_STA_ENTRY_FOR_GPS); + /* 2bit value: + * 0 -> need waiting + * 1,3 -> okay; 2 -> already taken + */ + if (val != 0) { + okay = true; + break; + } + if (poll_us >= poll_max_us) { + okay = false; + break; + } + gps_dl_wait_us(POLL_INTERVAL_US); + poll_us += POLL_INTERVAL_US; + } + gps_dl_set_show_reg_rw_log(show_log); + + if (!okay) + GDL_LOGW("okay = %d", okay); + else + GDL_LOGD("okay = %d", okay); + return okay; +} + +void gps_dl_hw_give_conn_coex_hw_sema(void) +{ + bool show_log; + + show_log = gps_dl_set_show_reg_rw_log(true); + GDL_HW_SET_CONN_INFRA_ENTRY(COS_SEMA_COEX_REL_ENTRY_FOR_GPS, 1); + gps_dl_set_show_reg_rw_log(show_log); + + GDL_LOGD(""); +} +#endif /* GPS_DL_HAS_PTA */ + +/* + * COS_SEMA_RFSPI_INDEX = 11(see conninfra/platform/include/consys_hw.h) + * GPS use M3 + */ +#define COS_SEMA_RFSPI_STA_ENTRY_FOR_GPS \ + CONN_SEMAPHORE_CONN_SEMA11_M3_OWN_STA_CONN_SEMA11_M3_OWN_STA + +#define COS_SEMA_RFSPI_REL_ENTRY_FOR_GPS \ + CONN_SEMAPHORE_CONN_SEMA11_M3_OWN_REL_CONN_SEMA11_M3_OWN_REL + +bool gps_dl_hw_take_conn_rfspi_hw_sema(unsigned int try_timeout_ms) +{ + bool okay; + bool show_log; + unsigned int poll_us, poll_max_us; + unsigned int val; + + show_log = gps_dl_set_show_reg_rw_log(true); + /* poll until value is expected or timeout */ + poll_us = 0; + poll_max_us = POLL_US * 1000 * try_timeout_ms; + okay = false; + while (!okay) { + val = GDL_HW_GET_CONN_INFRA_ENTRY(COS_SEMA_RFSPI_STA_ENTRY_FOR_GPS); + /* 2bit value: + * 0 -> need waiting + * 1,3 -> okay; 2 -> already taken + */ + if (val != 0) { + okay = true; + break; + } + if (poll_us >= poll_max_us) { + okay = false; + break; + } + gps_dl_wait_us(POLL_INTERVAL_US); + poll_us += POLL_INTERVAL_US; + } + gps_dl_set_show_reg_rw_log(show_log); + + GDL_LOGI("okay = %d", okay); + + return okay; +} + +void gps_dl_hw_give_conn_rfspi_hw_sema(void) +{ + bool show_log; + + show_log = gps_dl_set_show_reg_rw_log(true); + GDL_HW_SET_CONN_INFRA_ENTRY(COS_SEMA_RFSPI_REL_ENTRY_FOR_GPS, 1); + gps_dl_set_show_reg_rw_log(show_log); + + GDL_LOGI(""); +} + + +#define GPS_DL_RFSPI_BUSY_POLL_MAX (10*1000*POLL_US) /* 10ms */ + +/* note: must be protect by gps_dl_hw_take_conn_rfspi_hw_sema */ +static bool gps_dl_hw_gps_fmspi_state_backup(unsigned int *p_rd_ext_en_bk, unsigned int *p_rd_ext_cnt_bk) +{ + bool okay = true; + bool poll_okay; + + if (p_rd_ext_en_bk == NULL || p_rd_ext_cnt_bk == NULL) + return false; + + GDL_HW_POLL_CONN_INFRA_ENTRY(CONN_RF_SPI_MST_REG_SPI_STA_FM_BUSY, 0, + GPS_DL_RFSPI_BUSY_POLL_MAX, &poll_okay); + if (!poll_okay) + return false; + + *p_rd_ext_en_bk = GDL_HW_GET_CONN_INFRA_ENTRY(CONN_RF_SPI_MST_REG_FM_CTRL_FM_RD_EXT_EN); + *p_rd_ext_cnt_bk = GDL_HW_GET_CONN_INFRA_ENTRY(CONN_RF_SPI_MST_REG_FM_CTRL_FM_RD_EXT_CNT); + return okay; +} + +/* note: must be protect by gps_dl_hw_take_conn_rfspi_hw_sema */ +static void gps_dl_hw_gps_fmspi_state_restore(unsigned int rd_ext_en_bk, unsigned int rd_ext_cnt_bk) +{ + GDL_HW_SET_CONN_INFRA_ENTRY(CONN_RF_SPI_MST_REG_FM_CTRL_FM_RD_EXT_EN, rd_ext_en_bk); + GDL_HW_SET_CONN_INFRA_ENTRY(CONN_RF_SPI_MST_REG_FM_CTRL_FM_RD_EXT_CNT, rd_ext_cnt_bk); +} + +/* note: must be protect by gps_dl_hw_take_conn_rfspi_hw_sema */ +static bool gps_dl_hw_gps_fmspi_read_rfcr(unsigned int addr, unsigned int *p_val) +{ + unsigned int val; + bool okay; + bool poll_okay; + unsigned int tmp; + + if (p_val == NULL) + return false; + + GDL_HW_POLL_CONN_INFRA_ENTRY(CONN_RF_SPI_MST_REG_SPI_STA_FM_BUSY, 0, + GPS_DL_RFSPI_BUSY_POLL_MAX, &poll_okay); + if (!poll_okay) + return false; + + GDL_HW_SET_CONN_INFRA_ENTRY(CONN_RF_SPI_MST_REG_FM_CTRL_FM_RD_EXT_EN, 0); + GDL_HW_SET_CONN_INFRA_ENTRY(CONN_RF_SPI_MST_REG_FM_CTRL_FM_RD_EXT_CNT, 0); + + tmp = ((addr & 0xFFF) | (1 << 12UL) | (4 << 13UL) | (0 << 16UL)); + GDL_HW_WR_CONN_INFRA_REG(CONN_RF_SPI_MST_ADDR_SPI_FM_ADDR_ADDR, tmp); + GDL_HW_WR_CONN_INFRA_REG(CONN_RF_SPI_MST_ADDR_SPI_FM_WDAT_ADDR, 0); + + GDL_HW_POLL_CONN_INFRA_ENTRY(CONN_RF_SPI_MST_REG_SPI_STA_FM_BUSY, 0, + GPS_DL_RFSPI_BUSY_POLL_MAX, &poll_okay); + if (!poll_okay) { + GDL_HW_RD_CONN_INFRA_REG(CONN_RF_SPI_MST_ADDR_SPI_FM_RDAT_ADDR); + return false; + } + + val = GDL_HW_RD_CONN_INFRA_REG(CONN_RF_SPI_MST_ADDR_SPI_FM_RDAT_ADDR); + *p_val = val; + okay = true; + return okay; +} + +static bool gps_dl_hw_gps_fmspi_write_rfcr(unsigned int addr, unsigned int val) +{ + bool okay; + bool poll_okay; + unsigned int tmp; + + GDL_HW_POLL_CONN_INFRA_ENTRY(CONN_RF_SPI_MST_REG_SPI_STA_FM_BUSY, 0, + GPS_DL_RFSPI_BUSY_POLL_MAX, &poll_okay); + if (!poll_okay) + return false; + + tmp = ((addr & 0xFFF) | (0 << 12UL) | (4 << 13UL) | (0 << 16UL)); + GDL_HW_WR_CONN_INFRA_REG(CONN_RF_SPI_MST_ADDR_SPI_FM_ADDR_ADDR, tmp); + GDL_HW_WR_CONN_INFRA_REG(CONN_RF_SPI_MST_ADDR_SPI_FM_WDAT_ADDR, val); + + GDL_HW_POLL_CONN_INFRA_ENTRY(CONN_RF_SPI_MST_REG_SPI_STA_FM_BUSY, 0, + GPS_DL_RFSPI_BUSY_POLL_MAX, &poll_okay); + if (!poll_okay) { + GDL_HW_RD_CONN_INFRA_REG(CONN_RF_SPI_MST_ADDR_SPI_FM_RDAT_ADDR); + return false; + } + + okay = true; + return okay; +} + +void gps_dl_hw_gps_dump_gps_rf_cr(void) +{ + bool show_log, backup_okay; + unsigned int addr, val; + unsigned int rd_ext_en_bk, rd_ext_cnt_bk; + + gps_dl_hw_take_conn_rfspi_hw_sema(100); + show_log = gps_dl_set_show_reg_rw_log(true); + backup_okay = gps_dl_hw_gps_fmspi_state_backup(&rd_ext_en_bk, &rd_ext_cnt_bk); + + /* read: 0x500 ~ 0x51b */ + for (addr = 0x500; addr <= 0x51B; addr++) { + if (gps_dl_hw_gps_fmspi_read_rfcr(addr, &val)) + GDL_LOGW("rd: addr = 0x%x, val = 0x%x", addr, val); + else + GDL_LOGW("rd: addr = 0x%x, fail", addr); + } + + /* write: 0x51a = 1 */ + addr = 0x51A; + val = 1; + if (gps_dl_hw_gps_fmspi_write_rfcr(addr, val)) + GDL_LOGW("wr: addr = 0x%x, val = 0x%x, okay", addr, val); + else + GDL_LOGW("wr: addr = 0x%x, val = 0x%x, fail", addr, val); + + /* read: 0x51a & 0x51b */ + for (addr = 0x51A; addr <= 0x51B; addr++) { + if (gps_dl_hw_gps_fmspi_read_rfcr(addr, &val)) + GDL_LOGW("rd: addr = 0x%x, val = 0x%x", addr, val); + else + GDL_LOGW("rd: addr = 0x%x, fail", addr); + } + + if (backup_okay) + gps_dl_hw_gps_fmspi_state_restore(rd_ext_en_bk, rd_ext_cnt_bk); + else + GDL_LOGW("not do gps_dl_hw_gps_fmspi_state_restore due to backup failed!"); + gps_dl_set_show_reg_rw_log(show_log); + gps_dl_hw_give_conn_rfspi_hw_sema(); +} + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hw/gps_dl_hw_gps.c b/drivers/misc/mediatek/connectivity/gps/data_link/hw/gps_dl_hw_gps.c new file mode 100644 index 0000000000000000000000000000000000000000..a6f3236561dbd45217b93d278f2cf80ab2e43b37 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hw/gps_dl_hw_gps.c @@ -0,0 +1,500 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#include "gps_dl_config.h" + +#include "gps_dl_context.h" +#include "gps_dl_time_tick.h" +#include "gps_dsp_fsm.h" +#include "gps_dl_hw_api.h" +#include "gps_dl_hw_priv_util.h" +#include "gps/bgf_gps_dma.h" +#include "gps/gps_aon_top.h" +#include "gps/gps_usrt_apb.h" +#include "gps/gps_l5_usrt_apb.h" + +#define GPS_ADDR_ENTRY_NUM (1) +static const struct gps_dl_addr_map_entry g_gps_addr_table[GPS_ADDR_ENTRY_NUM] = { + /* Put base list here: */ + /* BGF_GPS_CFG_BASE */ + {0x18C00000, 0x80000000, 0x90000}, +}; + +unsigned int gps_bus_to_host(unsigned int gps_addr) +{ + unsigned int i; + const struct gps_dl_addr_map_entry *p; + + for (i = 0; i < GPS_ADDR_ENTRY_NUM; i++) { + p = &g_gps_addr_table[i]; + if (gps_addr >= p->bus_addr && + gps_addr < (p->bus_addr + p->length)) + return ((gps_addr - p->bus_addr) + p->host_addr); + } + + return 0; +} + + +void gps_dl_hw_set_dma_start(enum gps_dl_hal_dma_ch_index channel, + struct gdl_hw_dma_transfer *p_transfer) +{ + unsigned int bus_addr_of_data_start; + unsigned int bus_addr_of_buf_start; + unsigned int gdl_ret; + + gdl_ret = gps_dl_emi_remap_phy_to_bus_addr(p_transfer->transfer_start_addr, &bus_addr_of_data_start); + gdl_ret = gps_dl_emi_remap_phy_to_bus_addr(p_transfer->buf_start_addr, &bus_addr_of_buf_start); + + switch (channel) { + case GPS_DL_DMA_LINK0_A2D: + if (gps_dl_is_1byte_mode()) + GDL_HW_WR_GPS_REG(BGF_GPS_DMA_DMA1_CON_ADDR, 0x00128014); + else + GDL_HW_WR_GPS_REG(BGF_GPS_DMA_DMA1_CON_ADDR, 0x00128016); + + GDL_HW_WR_GPS_REG(BGF_GPS_DMA_DMA1_PGMADDR_PGMADDR_ADDR, + bus_addr_of_data_start); + GDL_HW_WR_GPS_REG(BGF_GPS_DMA_DMA1_WPTO_WPTO_ADDR, + bus_addr_of_buf_start); + GDL_HW_SET_GPS_ENTRY(BGF_GPS_DMA_DMA1_WPPT_WPPT, p_transfer->len_to_wrap); + GDL_HW_SET_GPS_ENTRY(BGF_GPS_DMA_DMA1_COUNT_LEN, p_transfer->transfer_max_len); + GDL_HW_SET_GPS_ENTRY(BGF_GPS_DMA_DMA1_START_STR, 1); + break; + case GPS_DL_DMA_LINK0_D2A: + if (gps_dl_is_1byte_mode()) + GDL_HW_WR_GPS_REG(BGF_GPS_DMA_DMA2_CON_ADDR, 0x00078018); + else + GDL_HW_WR_GPS_REG(BGF_GPS_DMA_DMA2_CON_ADDR, 0x0007801A); + + GDL_HW_WR_GPS_REG(BGF_GPS_DMA_DMA2_PGMADDR_PGMADDR_ADDR, + bus_addr_of_data_start); + GDL_HW_WR_GPS_REG(BGF_GPS_DMA_DMA2_WPTO_WPTO_ADDR, + bus_addr_of_buf_start); + GDL_HW_SET_GPS_ENTRY(BGF_GPS_DMA_DMA2_WPPT_WPPT, p_transfer->len_to_wrap); + GDL_HW_SET_GPS_ENTRY(BGF_GPS_DMA_DMA2_COUNT_LEN, p_transfer->transfer_max_len); + GDL_HW_SET_GPS_ENTRY(BGF_GPS_DMA_DMA2_START_STR, 1); + break; + case GPS_DL_DMA_LINK1_A2D: + if (gps_dl_is_1byte_mode()) + GDL_HW_WR_GPS_REG(BGF_GPS_DMA_DMA3_CON_ADDR, 0x00328014); + else + GDL_HW_WR_GPS_REG(BGF_GPS_DMA_DMA3_CON_ADDR, 0x00328016); + + GDL_HW_WR_GPS_REG(BGF_GPS_DMA_DMA3_PGMADDR_PGMADDR_ADDR, + bus_addr_of_data_start); + GDL_HW_WR_GPS_REG(BGF_GPS_DMA_DMA3_WPTO_WPTO_ADDR, + bus_addr_of_buf_start); + GDL_HW_SET_GPS_ENTRY(BGF_GPS_DMA_DMA3_WPPT_WPPT, p_transfer->len_to_wrap); + GDL_HW_SET_GPS_ENTRY(BGF_GPS_DMA_DMA3_COUNT_LEN, p_transfer->transfer_max_len); + GDL_HW_SET_GPS_ENTRY(BGF_GPS_DMA_DMA3_START_STR, 1); + break; + case GPS_DL_DMA_LINK1_D2A: + if (gps_dl_is_1byte_mode()) + GDL_HW_WR_GPS_REG(BGF_GPS_DMA_DMA4_CON_ADDR, 0x00278018); + else + GDL_HW_WR_GPS_REG(BGF_GPS_DMA_DMA4_CON_ADDR, 0x0027801A); + + GDL_HW_WR_GPS_REG(BGF_GPS_DMA_DMA4_PGMADDR_PGMADDR_ADDR, + bus_addr_of_data_start); + GDL_HW_WR_GPS_REG(BGF_GPS_DMA_DMA4_WPTO_WPTO_ADDR, + bus_addr_of_buf_start); + GDL_HW_SET_GPS_ENTRY(BGF_GPS_DMA_DMA4_WPPT_WPPT, p_transfer->len_to_wrap); + GDL_HW_SET_GPS_ENTRY(BGF_GPS_DMA_DMA4_COUNT_LEN, p_transfer->transfer_max_len); + GDL_HW_SET_GPS_ENTRY(BGF_GPS_DMA_DMA4_START_STR, 1); + break; + default: + return; + } +} + +void gps_dl_hw_set_dma_stop(enum gps_dl_hal_dma_ch_index channel) +{ + /* Poll until DMA IDLE */ + switch (channel) { + case GPS_DL_DMA_LINK0_A2D: + GDL_HW_SET_GPS_ENTRY(BGF_GPS_DMA_DMA1_START_STR, 0); + GDL_HW_SET_GPS_ENTRY(BGF_GPS_DMA_DMA1_ACKINT_ACK, 1); + break; + case GPS_DL_DMA_LINK0_D2A: + GDL_HW_SET_GPS_ENTRY(BGF_GPS_DMA_DMA2_START_STR, 0); + GDL_HW_SET_GPS_ENTRY(BGF_GPS_DMA_DMA2_ACKINT_ACK, 1); + break; + case GPS_DL_DMA_LINK1_A2D: + GDL_HW_SET_GPS_ENTRY(BGF_GPS_DMA_DMA3_START_STR, 0); + GDL_HW_SET_GPS_ENTRY(BGF_GPS_DMA_DMA3_ACKINT_ACK, 1); + break; + case GPS_DL_DMA_LINK1_D2A: + GDL_HW_SET_GPS_ENTRY(BGF_GPS_DMA_DMA4_START_STR, 0); + GDL_HW_SET_GPS_ENTRY(BGF_GPS_DMA_DMA4_ACKINT_ACK, 1); + break; + default: + return; + } +} + +bool gps_dl_hw_get_dma_int_status(enum gps_dl_hal_dma_ch_index channel) +{ + /* ASSERT(channel >= 0 && channel <= GPS_DL_DMA_CH_NUM); */ + switch (channel) { + case GPS_DL_DMA_LINK0_A2D: + return (bool)GDL_HW_GET_GPS_ENTRY(BGF_GPS_DMA_DMA1_INTSTA_INT); + case GPS_DL_DMA_LINK0_D2A: + return (bool)GDL_HW_GET_GPS_ENTRY(BGF_GPS_DMA_DMA2_INTSTA_INT); + case GPS_DL_DMA_LINK1_A2D: + return (bool)GDL_HW_GET_GPS_ENTRY(BGF_GPS_DMA_DMA3_INTSTA_INT); + case GPS_DL_DMA_LINK1_D2A: + return (bool)GDL_HW_GET_GPS_ENTRY(BGF_GPS_DMA_DMA4_INTSTA_INT); + default: + return false; + } +} + +void gps_dl_hw_save_dma_status_struct( + enum gps_dl_hal_dma_ch_index ch, struct gps_dl_hw_dma_status_struct *p) +{ + unsigned int offset = + (BGF_GPS_DMA_DMA2_WPPT_ADDR - BGF_GPS_DMA_DMA1_WPPT_ADDR) * ch; + + p->wrap_count = GDL_HW_RD_GPS_REG(BGF_GPS_DMA_DMA1_WPPT_ADDR + offset); + p->wrap_to_addr = GDL_HW_RD_GPS_REG(BGF_GPS_DMA_DMA1_WPTO_ADDR + offset); + p->total_count = GDL_HW_RD_GPS_REG(BGF_GPS_DMA_DMA1_COUNT_ADDR + offset); + p->config = GDL_HW_RD_GPS_REG(BGF_GPS_DMA_DMA1_CON_ADDR + offset); + p->start_flag = GDL_HW_RD_GPS_REG(BGF_GPS_DMA_DMA1_START_ADDR + offset); + p->intr_flag = GDL_HW_RD_GPS_REG(BGF_GPS_DMA_DMA1_INTSTA_ADDR + offset); + p->left_count = GDL_HW_RD_GPS_REG(BGF_GPS_DMA_DMA1_RLCT_ADDR + offset); + p->curr_addr = GDL_HW_RD_GPS_REG(BGF_GPS_DMA_DMA1_PGMADDR_ADDR + offset); + p->state = GDL_HW_RD_GPS_REG(BGF_GPS_DMA_DMA1_STATE_ADDR + offset); +} + +void gps_dl_hw_print_dma_status_struct( + enum gps_dl_hal_dma_ch_index ch, struct gps_dl_hw_dma_status_struct *p) +{ + if (!gps_dl_show_reg_wait_log()) + return; + + GDL_LOGW("dma ch %d, wrap = 0x%08x; tra = 0x%08x, count l/w/t = %d/%d/%d, str/int/sta = %d/%d/%d", + ch, p->wrap_to_addr, + p->curr_addr, p->left_count, p->wrap_count, p->total_count, + GDL_HW_EXTRACT_ENTRY(BGF_GPS_DMA_DMA1_START_STR, p->start_flag), + GDL_HW_EXTRACT_ENTRY(BGF_GPS_DMA_DMA1_INTSTA_INT, p->intr_flag), + GDL_HW_EXTRACT_ENTRY(BGF_GPS_DMA_DMA1_STATE_STATE, p->state)); + + GDL_LOGW("dma ch %d, conf = 0x%08x, master = %d, b2w = %d, w2b = %d, size = %d", + ch, p->config, + GDL_HW_EXTRACT_ENTRY(BGF_GPS_DMA_DMA1_CON_MAS, p->config), + GDL_HW_EXTRACT_ENTRY(BGF_GPS_DMA_DMA1_CON_B2W, p->config), + GDL_HW_EXTRACT_ENTRY(BGF_GPS_DMA_DMA1_CON_W2B, p->config), + GDL_HW_EXTRACT_ENTRY(BGF_GPS_DMA_DMA1_CON_SIZE, p->config)); +} + +enum GDL_RET_STATUS gps_dl_hw_wait_until_dma_complete_and_stop_it( + enum gps_dl_hal_dma_ch_index ch, int timeout_usec, bool return_if_not_start) +{ + struct gps_dl_hw_dma_status_struct dma_status; + struct gps_dl_hw_usrt_status_struct usrt_status; + enum gps_dl_link_id_enum link_id = DMA_CH_TO_LINK_ID(ch); + bool last_rw_log_on; + unsigned long tick0, tick1; + bool conninfra_okay; + bool do_stop = true; + enum GDL_RET_STATUS ret = GDL_OKAY; + int loop_cnt; + + tick0 = gps_dl_tick_get(); + loop_cnt = 0; + while (1) { + gps_dl_hw_save_dma_status_struct(ch, &dma_status); + if (gps_dl_only_show_wait_done_log()) + last_rw_log_on = gps_dl_set_show_reg_rw_log(false); + else + gps_dl_hw_print_dma_status_struct(ch, &dma_status); + + if (GDL_HW_EXTRACT_ENTRY(BGF_GPS_DMA_DMA1_START_STR, dma_status.start_flag)) { + if (gps_dl_only_show_wait_done_log()) { + gps_dl_set_show_reg_rw_log(last_rw_log_on); + gps_dl_hw_print_dma_status_struct(ch, &dma_status); + gps_dl_hw_save_dma_status_struct(ch, &dma_status); + } + break; /* to next while-loop */ + } else if (return_if_not_start) { + ret = GDL_OKAY; + do_stop = false; + goto _end; + } + + tick1 = gps_dl_tick_get(); + if (timeout_usec > GPS_DL_RW_NO_TIMEOUT && ( + gps_dl_tick_delta_to_usec(tick0, tick1) >= timeout_usec || + loop_cnt * GDL_HW_STATUS_POLL_INTERVAL_USEC >= timeout_usec)) { + ret = GDL_FAIL_TIMEOUT; + do_stop = false; + goto _end; + } + + gps_dl_wait_us(GDL_HW_STATUS_POLL_INTERVAL_USEC); + loop_cnt++; + } + + while (1) { + conninfra_okay = gps_dl_conninfra_is_okay_or_handle_it(NULL, true); + if (!conninfra_okay) { + ret = GDL_FAIL_CONN_NOT_OKAY; + do_stop = false; + break; + } + + gps_dl_hw_save_dma_status_struct(ch, &dma_status); + gps_dl_hw_save_usrt_status_struct(link_id, &usrt_status); + if (gps_dl_only_show_wait_done_log()) + last_rw_log_on = gps_dl_set_show_reg_rw_log(false); + else { + gps_dl_hw_print_dma_status_struct(ch, &dma_status); + gps_dl_hw_print_usrt_status_struct(link_id, &usrt_status); + } + + if (GDL_HW_EXTRACT_ENTRY(BGF_GPS_DMA_DMA1_INTSTA_INT, dma_status.intr_flag) && + GDL_HW_EXTRACT_ENTRY(BGF_GPS_DMA_DMA1_STATE_STATE, dma_status.state) == 0x01) { + if (gps_dl_only_show_wait_done_log()) { + gps_dl_set_show_reg_rw_log(last_rw_log_on); + gps_dl_hw_print_dma_status_struct(ch, &dma_status); + gps_dl_hw_save_dma_status_struct(ch, &dma_status); + } + + /* DMA ready to stop */ + gps_dl_hw_set_dma_stop(ch); + gps_dl_hw_save_dma_status_struct(ch, &dma_status); + gps_dl_hw_print_dma_status_struct(ch, &dma_status); + ret = GDL_OKAY; + do_stop = true; + break; + } + + tick1 = gps_dl_tick_get(); + if (timeout_usec > GPS_DL_RW_NO_TIMEOUT && ( + gps_dl_tick_delta_to_usec(tick0, tick1) >= timeout_usec || + loop_cnt * GDL_HW_STATUS_POLL_INTERVAL_USEC >= timeout_usec)) { + ret = GDL_FAIL_TIMEOUT; + do_stop = false; + break; + } + + gps_dl_wait_us(GDL_HW_STATUS_POLL_INTERVAL_USEC); + loop_cnt++; + } + +_end: + tick1 = gps_dl_tick_get(); + GDL_LOGW("ch = %d, d_us = %d, do_stop = %d, ret = %s", + ch, gps_dl_tick_delta_to_usec(tick0, tick1), do_stop, gdl_ret_to_name(ret)); + return ret; +} + +unsigned int gps_dl_hw_get_dma_left_len(enum gps_dl_hal_dma_ch_index channel) +{ + /* ASSERT(channel >= 0 && channel <= GPS_DL_DMA_CH_NUM); */ + switch (channel) { + case GPS_DL_DMA_LINK0_A2D: + return GDL_HW_GET_GPS_ENTRY(BGF_GPS_DMA_DMA1_RLCT_RLCT); + case GPS_DL_DMA_LINK0_D2A: + return GDL_HW_GET_GPS_ENTRY(BGF_GPS_DMA_DMA2_RLCT_RLCT); + case GPS_DL_DMA_LINK1_A2D: + return GDL_HW_GET_GPS_ENTRY(BGF_GPS_DMA_DMA3_RLCT_RLCT); + case GPS_DL_DMA_LINK1_D2A: + return GDL_HW_GET_GPS_ENTRY(BGF_GPS_DMA_DMA4_RLCT_RLCT); + default: + return 0; + } +} + +void gps_dl_hw_get_link_status( + enum gps_dl_link_id_enum link_id, struct gps_dl_hw_link_status_struct *p) +{ + unsigned int reg_val; + unsigned int offset = + (GPS_L5_USRT_APB_APB_CTRL_ADDR - GPS_USRT_APB_APB_CTRL_ADDR) * link_id; + + /* todo: link_id error handling */ + + if (link_id == GPS_DATA_LINK_ID0) { + p->tx_dma_done = gps_dl_hw_get_dma_int_status(GPS_DL_DMA_LINK0_A2D); + p->rx_dma_done = gps_dl_hw_get_dma_int_status(GPS_DL_DMA_LINK0_D2A); + } else if (link_id == GPS_DATA_LINK_ID1) { + p->tx_dma_done = gps_dl_hw_get_dma_int_status(GPS_DL_DMA_LINK1_A2D); + p->rx_dma_done = gps_dl_hw_get_dma_int_status(GPS_DL_DMA_LINK1_D2A); + } else { + p->tx_dma_done = false; + p->rx_dma_done = false; + } + + reg_val = GDL_HW_RD_GPS_REG(GPS_USRT_APB_APB_STA_ADDR + offset); + p->usrt_has_data = GDL_HW_EXTRACT_ENTRY(GPS_USRT_APB_APB_STA_TX_IND, reg_val); + p->usrt_has_nodata = GDL_HW_EXTRACT_ENTRY(GPS_USRT_APB_APB_STA_NODAINTB, reg_val); +} + +void gps_dl_hw_save_usrt_status_struct( + enum gps_dl_link_id_enum link_id, struct gps_dl_hw_usrt_status_struct *p) +{ + unsigned int offset = + (GPS_L5_USRT_APB_APB_CTRL_ADDR - GPS_USRT_APB_APB_CTRL_ADDR) * link_id; + + p->ctrl_setting = GDL_HW_RD_GPS_REG(GPS_USRT_APB_APB_CTRL_ADDR + offset); + p->intr_enable = GDL_HW_RD_GPS_REG(GPS_USRT_APB_APB_INTEN_ADDR + offset); + p->state = GDL_HW_RD_GPS_REG(GPS_USRT_APB_APB_STA_ADDR + offset); + + p->mcub_a2d_flag = GDL_HW_RD_GPS_REG(GPS_USRT_APB_MCUB_A2DF_ADDR + offset); + p->mcub_d2a_flag = GDL_HW_RD_GPS_REG(GPS_USRT_APB_MCUB_D2AF_ADDR + offset); + + p->mcub_a2d_d0 = GDL_HW_RD_GPS_REG(GPS_USRT_APB_MCU_A2D0_ADDR + offset); + p->mcub_a2d_d1 = GDL_HW_RD_GPS_REG(GPS_USRT_APB_MCU_A2D1_ADDR + offset); + p->mcub_d2a_d0 = GDL_HW_RD_GPS_REG(GPS_USRT_APB_MCU_D2A0_ADDR + offset); + p->mcub_d2a_d1 = GDL_HW_RD_GPS_REG(GPS_USRT_APB_MCU_D2A1_ADDR + offset); +} + +void gps_dl_hw_print_usrt_status_struct( + enum gps_dl_link_id_enum link_id, struct gps_dl_hw_usrt_status_struct *p) +{ + if (!gps_dl_show_reg_wait_log()) + return; + + GDL_LOGXW(link_id, "usrt ctrl = 0x%08x[DMA_EN RX=%d,TX=%d; 1BYTE=%d], intr_en = 0x%08x", + p->ctrl_setting, + GDL_HW_EXTRACT_ENTRY(GPS_USRT_APB_APB_CTRL_RX_EN, p->ctrl_setting), + GDL_HW_EXTRACT_ENTRY(GPS_USRT_APB_APB_CTRL_TX_EN, p->ctrl_setting), + GDL_HW_EXTRACT_ENTRY(GPS_USRT_APB_APB_CTRL_BYTEN, p->ctrl_setting), + p->intr_enable); + + GDL_LOGXW(link_id, "usrt state = 0x%08x, [UOEFS]RX=%d%d%d%d(%d),TX=%d%d%d%d(%d)", + p->state, + GDL_HW_EXTRACT_ENTRY(GPS_USRT_APB_APB_STA_RX_UNDR, p->state), + GDL_HW_EXTRACT_ENTRY(GPS_USRT_APB_APB_STA_RX_OVF, p->state), + GDL_HW_EXTRACT_ENTRY(GPS_USRT_APB_APB_STA_RX_EMP, p->state), + GDL_HW_EXTRACT_ENTRY(GPS_USRT_APB_APB_STA_RX_FULL, p->state), + GDL_HW_EXTRACT_ENTRY(GPS_USRT_APB_APB_STA_RX_ST, p->state), + GDL_HW_EXTRACT_ENTRY(GPS_USRT_APB_APB_STA_TX_UNDR, p->state), + GDL_HW_EXTRACT_ENTRY(GPS_USRT_APB_APB_STA_TX_OVF, p->state), + GDL_HW_EXTRACT_ENTRY(GPS_USRT_APB_APB_STA_TX_EMP, p->state), + GDL_HW_EXTRACT_ENTRY(GPS_USRT_APB_APB_STA_TX_FULL, p->state), + GDL_HW_EXTRACT_ENTRY(GPS_USRT_APB_APB_STA_TX_ST, p->state)); + + GDL_LOGXW(link_id, "usrt TxReg_em=%d, TX_IND=%d, TX_IND=%d, U_em=%d, NOD_INT=%d", + GDL_HW_EXTRACT_ENTRY(GPS_USRT_APB_APB_STA_REGE, p->state), + GDL_HW_EXTRACT_ENTRY(GPS_USRT_APB_APB_STA_TX_IND, p->state), + GDL_HW_EXTRACT_ENTRY(GPS_USRT_APB_APB_STA_TXINTB, p->state), + GDL_HW_EXTRACT_ENTRY(GPS_USRT_APB_APB_STA_URAME, p->state), + GDL_HW_EXTRACT_ENTRY(GPS_USRT_APB_APB_STA_NODAINTB, p->state)); + + GDL_LOGXW(link_id, "mcub d2a flag=0x%08x, d0=0x%08x, d1=0x%08x", + p->mcub_d2a_flag, p->mcub_d2a_d0, p->mcub_d2a_d1); + + GDL_LOGXW(link_id, "mcub a2d flag=0x%08x, d0=0x%08x, d1=0x%08x", + p->mcub_a2d_flag, p->mcub_a2d_d0, p->mcub_a2d_d1); +} + +void gps_dl_hw_switch_dsp_jtag(void) +{ + unsigned int value, value_new; + + value = GDL_HW_RD_GPS_REG(0x80073160); + value_new = value & 0xFFFFFFFE; + value_new = value_new | ((~(value & 0x00000001)) & 0x00000001); + GDL_HW_WR_GPS_REG(0x80073160, value_new); +} + +enum GDL_HW_RET gps_dl_hw_get_mcub_info(enum gps_dl_link_id_enum link_id, struct gps_dl_hal_mcub_info *p) +{ + if (p == NULL) + return E_INV_PARAMS; + + if (link_id == GPS_DATA_LINK_ID0) { + p->flag = GDL_HW_RD_GPS_REG(GPS_USRT_APB_MCUB_D2AF_ADDR); + p->dat0 = GDL_HW_RD_GPS_REG(GPS_USRT_APB_MCU_D2A0_ADDR); + p->dat1 = GDL_HW_RD_GPS_REG(GPS_USRT_APB_MCU_D2A1_ADDR); + return HW_OKAY; + } else if (link_id == GPS_DATA_LINK_ID1) { + p->flag = GDL_HW_RD_GPS_REG(GPS_L5_USRT_APB_MCUB_D2AF_ADDR); + p->dat0 = GDL_HW_RD_GPS_REG(GPS_L5_USRT_APB_MCU_D2A0_ADDR); + p->dat1 = GDL_HW_RD_GPS_REG(GPS_L5_USRT_APB_MCU_D2A1_ADDR); + return HW_OKAY; + } else + return E_INV_PARAMS; +} + +void gps_dl_hw_clear_mcub_d2a_flag(enum gps_dl_link_id_enum link_id, unsigned int d2a_flag) +{ + if (link_id == GPS_DATA_LINK_ID0) + GDL_HW_WR_GPS_REG(GPS_USRT_APB_MCUB_D2AF_ADDR, d2a_flag); + else if (link_id == GPS_DATA_LINK_ID1) + GDL_HW_WR_GPS_REG(GPS_L5_USRT_APB_MCUB_D2AF_ADDR, d2a_flag); +} + +unsigned int gps_dl_hw_get_mcub_a2d_flag(enum gps_dl_link_id_enum link_id) +{ + unsigned int val = 0; + + if (link_id == GPS_DATA_LINK_ID0) + val = GDL_HW_RD_GPS_REG(GPS_USRT_APB_MCUB_A2DF_ADDR); + else if (link_id == GPS_DATA_LINK_ID1) + val = GDL_HW_RD_GPS_REG(GPS_L5_USRT_APB_MCUB_A2DF_ADDR); + + return val; +} + +enum GDL_RET_STATUS gps_dl_hw_mcub_dsp_read_request(enum gps_dl_link_id_enum link_id, u16 dsp_addr) +{ + unsigned int a2d_flag = 0; + + /* Fill addr to A2D0 and trigger A2DF bit2 + * (0x04, GPS_MCUB_A2DF_MASK_DSP_REG_READ_REQ), + * the result will be put into D2A0 after D2AF bit1 + * (0x02, GPS_MCUB_D2AF_MASK_DSP_REG_READ_READY) set. + */ + + if (link_id == GPS_DATA_LINK_ID0) + a2d_flag = GDL_HW_RD_GPS_REG(GPS_USRT_APB_MCUB_A2DF_ADDR); + else if (link_id == GPS_DATA_LINK_ID1) + a2d_flag = GDL_HW_RD_GPS_REG(GPS_L5_USRT_APB_MCUB_A2DF_ADDR); + else + return GDL_FAIL_INVAL; + + /* A2DF bit2 must be cleared, otherwise dsp is busy */ + if ((a2d_flag & GPS_MCUB_A2DF_MASK_DSP_REG_READ_REQ) != 0) { + GDL_LOGXD(link_id, "a2d_flag = 0x%x, mask = 0x%x, busy", + a2d_flag, GPS_MCUB_A2DF_MASK_DSP_REG_READ_REQ); + return GDL_FAIL_BUSY; + } + + if (link_id == GPS_DATA_LINK_ID0) { + GDL_HW_WR_GPS_REG(GPS_USRT_APB_MCU_A2D0_ADDR, (dsp_addr & 0xFFFF)); + GDL_HW_WR_GPS_REG(GPS_USRT_APB_MCUB_A2DF_ADDR, + GPS_MCUB_A2DF_MASK_DSP_REG_READ_REQ); + } else if (link_id == GPS_DATA_LINK_ID1) { + GDL_HW_WR_GPS_REG(GPS_L5_USRT_APB_MCU_A2D0_ADDR, (dsp_addr & 0xFFFF)); + GDL_HW_WR_GPS_REG(GPS_L5_USRT_APB_MCUB_A2DF_ADDR, + GPS_MCUB_A2DF_MASK_DSP_REG_READ_REQ); + } + + return GDL_OKAY; +} + +void gps_dl_hw_print_ms_counter_status(void) +{ + bool show_log; + + show_log = gps_dl_set_show_reg_rw_log(true); + gps_dl_bus_rd_opt(GPS_DL_GPS_BUS, GPS_AON_TOP_DSLEEP_CTL_ADDR, BMASK_RW_FORCE_PRINT); + gps_dl_bus_rd_opt(GPS_DL_GPS_BUS, GPS_AON_TOP_WAKEUP_CTL_ADDR, BMASK_RW_FORCE_PRINT); + gps_dl_bus_rd_opt(GPS_DL_GPS_BUS, GPS_AON_TOP_TCXO_MS_H_ADDR, BMASK_RW_FORCE_PRINT); + gps_dl_bus_rd_opt(GPS_DL_GPS_BUS, GPS_AON_TOP_TCXO_MS_L_ADDR, BMASK_RW_FORCE_PRINT); + gps_dl_set_show_reg_rw_log(show_log); +} + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hw/gps_dl_hw_power_ctrl.c b/drivers/misc/mediatek/connectivity/gps/data_link/hw/gps_dl_hw_power_ctrl.c new file mode 100644 index 0000000000000000000000000000000000000000..fcb98bac25815fb02e70546e2737efd926601e17 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hw/gps_dl_hw_power_ctrl.c @@ -0,0 +1,695 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#include "gps_dl_config.h" +#include "gps_dl_context.h" + +#include "gps_dl_hal.h" +#if GPS_DL_MOCK_HAL +#include "gps_mock_hal.h" +#endif +#if GPS_DL_HAS_CONNINFRA_DRV +#if GPS_DL_ON_LINUX +#include "conninfra.h" +#elif GPS_DL_ON_CTP +#include "conninfra_ext.h" +#endif +#endif + +#include "gps_dl_hw_api.h" +#include "gps_dl_hw_dep_api.h" +#include "gps_dl_hw_priv_util.h" +#include "gps_dl_hal_util.h" +#include "gps_dsp_fsm.h" +#include "gps_dl_subsys_reset.h" + +#include "conn_infra/conn_infra_rgu.h" +#include "conn_infra/conn_infra_cfg.h" +#include "conn_infra/conn_host_csr_top.h" + +#include "gps/gps_rgu_on.h" +#include "gps/gps_cfg_on.h" +#include "gps/gps_aon_top.h" +#include "gps/bgf_gps_cfg.h" + +static int gps_dl_hw_gps_sleep_prot_ctrl(int op) +{ + bool poll_okay; + + if (1 == op) { + /* disable when on */ + GDL_HW_SET_CONN2GPS_SLP_PROT_RX_VAL(0); + GDL_HW_POLL_CONN2GPS_SLP_PROT_RX_UNTIL_VAL(0, POLL_DEFAULT, &poll_okay); + if (!poll_okay) { + GDL_LOGE("_fail_disable_gps_slp_prot - conn2gps rx"); + goto _fail_disable_gps_slp_prot; + } + + GDL_HW_SET_CONN2GPS_SLP_PROT_TX_VAL(0); + GDL_HW_POLL_CONN2GPS_SLP_PROT_TX_UNTIL_VAL(0, POLL_DEFAULT, &poll_okay); + if (!poll_okay) { + GDL_LOGE("_fail_disable_gps_slp_prot - conn2gps tx"); + goto _fail_disable_gps_slp_prot; + } + + GDL_HW_SET_GPS2CONN_SLP_PROT_RX_VAL(0); + GDL_HW_POLL_GPS2CONN_SLP_PROT_RX_UNTIL_VAL(0, POLL_DEFAULT, &poll_okay); + if (!poll_okay) { + GDL_LOGE("_fail_disable_gps_slp_prot - gps2conn rx"); + goto _fail_disable_gps_slp_prot; + } + + GDL_HW_SET_GPS2CONN_SLP_PROT_TX_VAL(0); + GDL_HW_POLL_GPS2CONN_SLP_PROT_TX_UNTIL_VAL(0, POLL_DEFAULT, &poll_okay); + if (!poll_okay) { + GDL_LOGE("_fail_disable_gps_slp_prot - gps2conn tx"); + goto _fail_disable_gps_slp_prot; + } + return 0; + +_fail_disable_gps_slp_prot: +#if 0 + GDL_HW_WR_CONN_INFRA_REG(CONN_INFRA_CFG_GALS_GPS2CONN_SLP_CTRL_ADDR, + CONN_INFRA_CFG_GALS_CONN2GPS_SLP_CTRL_R_CONN2GPS_SLP_PROT_RX_EN_MASK | + CONN_INFRA_CFG_GALS_CONN2GPS_SLP_CTRL_R_CONN2GPS_SLP_PROT_TX_EN_MASK | + CONN_INFRA_CFG_GALS_GPS2CONN_SLP_CTRL_R_GPS2CONN_SLP_PROT_RX_EN_MASK | + CONN_INFRA_CFG_GALS_GPS2CONN_SLP_CTRL_R_GPS2CONN_SLP_PROT_TX_EN_MASK); +#endif + return -1; + } else if (0 == op) { + /* enable when off */ + GDL_HW_SET_CONN2GPS_SLP_PROT_TX_VAL(1); + GDL_HW_POLL_CONN2GPS_SLP_PROT_TX_UNTIL_VAL(1, POLL_DEFAULT, &poll_okay); + if (!poll_okay) { + /* From DE: need to trigger connsys reset */ + GDL_LOGE("_fail_enable_gps_slp_prot - conn2gps tx"); + goto _fail_enable_gps_slp_prot; + } + + GDL_HW_SET_CONN2GPS_SLP_PROT_RX_VAL(1); + GDL_HW_POLL_CONN2GPS_SLP_PROT_RX_UNTIL_VAL(1, POLL_DEFAULT, &poll_okay); + if (!poll_okay) { + /* not handle it, just show warning */ + GDL_LOGE("_fail_enable_gps_slp_prot - conn2gps rx"); + } + + GDL_HW_SET_GPS2CONN_SLP_PROT_TX_VAL(1); + GDL_HW_POLL_GPS2CONN_SLP_PROT_TX_UNTIL_VAL(1, POLL_DEFAULT, &poll_okay); + if (!poll_okay) { + /* not handle it, just show warning */ + GDL_LOGE("_fail_enable_gps_slp_prot - gps2conn tx"); + } + + GDL_HW_SET_GPS2CONN_SLP_PROT_RX_VAL(1); + GDL_HW_POLL_GPS2CONN_SLP_PROT_RX_UNTIL_VAL(1, POLL_DEFAULT, &poll_okay); + if (!poll_okay) { + /* From DE: need to trigger connsys reset */ + GDL_LOGE("_fail_enable_gps_slp_prot - gps2conn rx"); + goto _fail_enable_gps_slp_prot; + } + + return 0; + +_fail_enable_gps_slp_prot: + /* trigger reset on outer function */ +#if 0 + gps_dl_trigger_connsys_reset(); +#endif + return -1; + } + + return 0; +} + +bool gps_dl_hw_gps_force_wakeup_conninfra_top_off(bool enable) +{ + bool poll_okay; + + if (enable) { + GDL_HW_SET_CONN_INFRA_ENTRY(CONN_HOST_CSR_TOP_CONN_INFRA_WAKEPU_GPS_CONN_INFRA_WAKEPU_GPS, 1); + GDL_HW_MAY_WAIT_CONN_INFRA_SLP_PROT_DISABLE_ACK(&poll_okay); + if (!poll_okay) { + GDL_LOGE("_fail_conn_slp_prot_not_okay"); + return false; /* not okay */ + } + } else + GDL_HW_SET_CONN_INFRA_ENTRY(CONN_HOST_CSR_TOP_CONN_INFRA_WAKEPU_GPS_CONN_INFRA_WAKEPU_GPS, 0); + + return true; +} + +void gps_dl_hw_gps_sw_request_emi_usage(bool request) +{ + bool show_log; + bool reg_rw_log = gps_dl_log_reg_rw_is_on(GPS_DL_REG_RW_EMI_SW_REQ_CTRL); + + if (reg_rw_log) { + show_log = gps_dl_set_show_reg_rw_log(true); + GDL_HW_RD_CONN_INFRA_REG(CONN_INFRA_CFG_EMI_CTL_TOP_ADDR); + GDL_HW_RD_CONN_INFRA_REG(CONN_INFRA_CFG_EMI_CTL_WF_ADDR); + GDL_HW_RD_CONN_INFRA_REG(CONN_INFRA_CFG_EMI_CTL_BT_ADDR); + GDL_HW_RD_CONN_INFRA_REG(CONN_INFRA_CFG_EMI_CTL_GPS_ADDR); + } +#if (GPS_DL_USE_TIA) + /* If use TIA, CONN_INFRA_CFG_EMI_CTL_GPS used by DSP, driver use TOP's. */ + if (request) + GDL_HW_SET_CONN_INFRA_ENTRY(CONN_INFRA_CFG_EMI_CTL_TOP_EMI_REQ_TOP, 1); + else + GDL_HW_SET_CONN_INFRA_ENTRY(CONN_INFRA_CFG_EMI_CTL_TOP_EMI_REQ_TOP, 0); +#else + if (request) + GDL_HW_SET_CONN_INFRA_ENTRY(CONN_INFRA_CFG_EMI_CTL_GPS_EMI_REQ_GPS, 1); + else + GDL_HW_SET_CONN_INFRA_ENTRY(CONN_INFRA_CFG_EMI_CTL_GPS_EMI_REQ_GPS, 0); +#endif + if (reg_rw_log) + gps_dl_set_show_reg_rw_log(show_log); +} + +int gps_dl_hw_gps_common_on(void) +{ + bool poll_okay; + unsigned int poll_ver; + int i; + + /* Enable Conninfra BGF */ + GDL_HW_SET_CONN_INFRA_BGF_EN(1); + + /* Poll conninfra hw version */ + GDL_HW_CHECK_CONN_INFRA_VER(&poll_okay, &poll_ver); + if (!poll_okay) { + GDL_LOGE("_fail_conn_hw_ver_not_okay, poll_ver = 0x%08x", poll_ver); + goto _fail_conn_hw_ver_not_okay; + } + + /* GDL_HW_CHECK_CONN_INFRA_VER may check a list and return ok if poll_ver is in the list, + * record the poll_ver here and we can know which one it is, + * and it may help for debug purpose. + */ + gps_dl_hal_set_conn_infra_ver(poll_ver); + GDL_LOGW("%s: poll_ver = 0x%08x is ok", GDL_HW_SUPPORT_LIST, poll_ver); + + /* GPS SW EMI request + * gps_dl_hw_gps_sw_request_emi_usage(true); + */ + gps_dl_hal_emi_usage_init(); + + /* Enable GPS function */ + GDL_HW_SET_GPS_FUNC_EN(1); + + /* bit24: BGFSYS_ON_TOP primary power ack */ + GDL_HW_POLL_CONN_INFRA_ENTRY(CONN_INFRA_RGU_BGFSYS_ON_TOP_PWR_ACK_ST_BGFSYS_ON_TOP_PWR_ACK, 1, + POLL_DEFAULT, &poll_okay); + if (!poll_okay) { + GDL_LOGE("_fail_bgf_top_1st_pwr_ack_not_okay"); + goto _fail_bgf_top_1st_pwr_ack_not_okay; + } + + /* bit25: BGFSYS_ON_TOP secondary power ack */ + GDL_HW_POLL_CONN_INFRA_ENTRY(CONN_INFRA_RGU_BGFSYS_ON_TOP_PWR_ACK_ST_AN_BGFSYS_ON_TOP_PWR_ACK_S, 1, + POLL_DEFAULT, &poll_okay); + if (!poll_okay) { + GDL_LOGE("_fail_bgf_top_2nd_pwr_ack_not_okay"); + goto _fail_bgf_top_2nd_pwr_ack_not_okay; + } + + GDL_WAIT_US(200); + + /* sleep prot */ + if (gps_dl_hw_gps_sleep_prot_ctrl(1) != 0) { + GDL_LOGE("_fail_disable_gps_slp_prot_not_okay"); + goto _fail_disable_gps_slp_prot_not_okay; + } + + /* polling status and version */ + /* Todo: set GPS host csr flag selection */ + /* 0x18060240[3:0] == 4h'2 gps_top_off is GPS_ACTIVE state */ + GDL_HW_SET_CONN_INFRA_ENTRY(CONN_HOST_CSR_TOP_HOST2GPS_DEGUG_SEL_HOST2GPS_DEGUG_SEL, 0x80); + for (i = 0; i < 3; i++) { + GDL_HW_POLL_CONN_INFRA_ENTRY(CONN_HOST_CSR_TOP_GPS_CFG2HOST_DEBUG_GPS_CFG2HOST_DEBUG, 2, + POLL_DEFAULT, &poll_okay); + if (poll_okay) + break; + /* + * TODO: + * if (!gps_dl_reset_level_is_none()) break; + */ + if (i > 0) + GDL_LOGW("_poll_gps_top_off_active, cnt = %d", i + 1); + } + if (!poll_okay) { + GDL_LOGE("_fail_gps_top_off_active_not_okay"); + goto _fail_gps_top_off_active_not_okay; + } + + /* 0x18c21010[31:0] bgf ip version */ + GDL_HW_POLL_GPS_ENTRY(BGF_GPS_CFG_BGF_IP_VERSION_BGFSYS_VERSION, + GDL_HW_BGF_VER, POLL_DEFAULT, &poll_okay); + if (!poll_okay) { + GDL_LOGE("_fail_bgf_ip_ver_not_okay"); + goto _fail_bgf_ip_ver_not_okay; + } + + /* 0x18c21014[7:0] bgf ip cfg */ + GDL_HW_POLL_GPS_ENTRY(BGF_GPS_CFG_BGF_IP_CONFIG_BGFSYS_CONFIG, 0, + POLL_DEFAULT, &poll_okay); + if (!poll_okay) { + GDL_LOGE("_fail_bgf_ip_cfg_not_okay"); + goto _fail_bgf_ip_cfg_not_okay; + } + +#if (GPS_DL_HAS_CONNINFRA_DRV) + /* conninfra driver add an API to do bellow step */ + conninfra_config_setup(); +#else + /* Enable conninfra bus hung detection */ + GDL_HW_WR_CONN_INFRA_REG(0x1800F000, 0xF000001C); +#endif + + /* host csr gps bus debug mode enable 0x18c60000 = 0x10 */ + GDL_HW_WR_GPS_REG(0x80060000, 0x10); + + /* Power on A-die top clock */ +#if (GPS_DL_HAS_CONNINFRA_DRV) + conninfra_adie_top_ck_en_on(CONNSYS_ADIE_CTL_HOST_GPS); +#endif + + /* Enable PLL driver */ + GDL_HW_SET_GPS_ENTRY(GPS_CFG_ON_GPS_CLKGEN1_CTL_CR_GPS_DIGCK_DIV_EN, 1); + + return 0; + +_fail_bgf_ip_cfg_not_okay: +_fail_bgf_ip_ver_not_okay: +_fail_gps_top_off_active_not_okay: +_fail_disable_gps_slp_prot_not_okay: +_fail_bgf_top_2nd_pwr_ack_not_okay: +_fail_bgf_top_1st_pwr_ack_not_okay: + GDL_HW_SET_GPS_FUNC_EN(0); + GDL_HW_SET_CONN_INFRA_ENTRY(CONN_INFRA_CFG_EMI_CTL_GPS_EMI_REQ_GPS, 0); + +_fail_conn_hw_ver_not_okay: + return -1; +} + +int gps_dl_hw_gps_common_off(void) +{ + /* Power off A-die top clock */ +#if (GPS_DL_HAS_CONNINFRA_DRV) + conninfra_adie_top_ck_en_off(CONNSYS_ADIE_CTL_HOST_GPS); +#endif + + if (gps_dl_hw_gps_sleep_prot_ctrl(0) != 0) { + GDL_LOGE("enable sleep prot fail, trigger connsys reset"); + gps_dl_trigger_connsys_reset(); + return -1; + } + + /* GPS SW EMI request + * gps_dl_hw_gps_sw_request_emi_usage(false); + */ + gps_dl_hal_emi_usage_deinit(); + + if (gps_dl_log_reg_rw_is_on(GPS_DL_REG_RW_HOST_CSR_GPS_OFF)) + gps_dl_hw_dump_host_csr_conninfra_info(true); + + /* Disable GPS function */ + GDL_HW_SET_GPS_FUNC_EN(0); + + /* Disable Conninfra BGF */ + GDL_HW_SET_CONN_INFRA_BGF_EN(0); + + return 0; +} + +/* L1 and L5 share same pwr stat and current we can support the bellow case: + * 1. Both L1 and L5 on / off + * 2. Both L1 and L5 enter deep stop mode and wakeup + * 3. L5 stays off, L1 do on / off + * 4. L5 stays off, L1 enter deep stop mode and wakeup + */ +unsigned int g_gps_pwr_stat; +int gps_dl_hw_gps_pwr_stat_ctrl(enum dsp_ctrl_enum ctrl) +{ + bool clk_ext = gps_dl_hal_get_need_clk_ext_flag(GPS_DATA_LINK_ID0); + + switch (ctrl) { + case GPS_L1_DSP_ON: + case GPS_L5_DSP_ON: + case GPS_L1_DSP_OFF: + case GPS_L5_DSP_OFF: + GDL_HW_SET_GPS_ENTRY(GPS_AON_TOP_DSLEEP_CTL_GPS_PWR_STAT, 0); + GDL_HW_SET_GPS_ENTRY(GPS_AON_TOP_DSLEEP_CTL_FORCE_OSC_EN_ON, 0); + g_gps_pwr_stat = 0; + break; + + case GPS_L1_DSP_CLEAR_PWR_STAT: + case GPS_L5_DSP_CLEAR_PWR_STAT: + gps_dl_hw_print_ms_counter_status(); + GDL_HW_SET_GPS_ENTRY(GPS_AON_TOP_DSLEEP_CTL_GPS_PWR_STAT, 0); + GDL_HW_SET_GPS_ENTRY(GPS_AON_TOP_DSLEEP_CTL_FORCE_OSC_EN_ON, 0); + g_gps_pwr_stat = 0; + break; + + case GPS_L1_DSP_ENTER_DSTOP: + case GPS_L5_DSP_ENTER_DSTOP: + GDL_HW_SET_GPS_ENTRY(GPS_AON_TOP_DSLEEP_CTL_GPS_PWR_STAT, 1); + GDL_HW_SET_GPS_ENTRY(GPS_AON_TOP_DSLEEP_CTL_FORCE_OSC_EN_ON, clk_ext); + gps_dl_hw_print_ms_counter_status(); + g_gps_pwr_stat = 1; + break; + + case GPS_L1_DSP_EXIT_DSTOP: + case GPS_L5_DSP_EXIT_DSTOP: + /* do nothing */ + gps_dl_hw_print_ms_counter_status(); + break; + + case GPS_L1_DSP_ENTER_DSLEEP: + case GPS_L5_DSP_ENTER_DSLEEP: + GDL_HW_SET_GPS_ENTRY(GPS_AON_TOP_DSLEEP_CTL_GPS_PWR_STAT, 3); + GDL_HW_SET_GPS_ENTRY(GPS_AON_TOP_DSLEEP_CTL_FORCE_OSC_EN_ON, clk_ext); + g_gps_pwr_stat = 3; + break; + + case GPS_L1_DSP_EXIT_DSLEEP: + case GPS_L5_DSP_EXIT_DSLEEP: + /* do nothong */ + break; + + default: + break; + } + + return 0; +} + +int gps_dl_hw_gps_dsp_ctrl(enum dsp_ctrl_enum ctrl) +{ + bool poll_okay; + bool dsp_off_done; + + switch (ctrl) { + case GPS_L1_DSP_ON: + case GPS_L1_DSP_EXIT_DSTOP: + case GPS_L1_DSP_EXIT_DSLEEP: + gps_dl_hw_gps_pwr_stat_ctrl(ctrl); + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L1_CR_RGU_GPS_L1_ON, 1); + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L1_CR_RGU_GPS_L1_SOFT_RST_B, 1); + GDL_HW_POLL_GPS_ENTRY(GPS_CFG_ON_GPS_L1_SLP_PWR_CTL_GPS_L1_SLP_PWR_CTL_CS, 3, + POLL_DEFAULT, &poll_okay); + if (!poll_okay) { + GDL_LOGE("ctrl = %d fail", ctrl); + return -1; + } + + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L1_MEM_DLY_CTL_RGU_GPSSYS_L1_MEM_ADJ_DLY_EN, 1); + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L1_DLY_CHAIN_CTL_RGU_GPS_L1_MEM_PDN_DELAY_DUMMY_NUM, 5); + gps_dl_wait_us(100); /* 3 x 32k clk ~= 100us */ + gps_dl_hw_usrt_ctrl(GPS_DATA_LINK_ID0, + true, gps_dl_is_dma_enabled(), gps_dl_is_1byte_mode()); + break; + + case GPS_L1_DSP_CLEAR_PWR_STAT: + gps_dl_hw_gps_pwr_stat_ctrl(ctrl); + return 0; + + case GPS_L1_DSP_OFF: + case GPS_L1_DSP_ENTER_DSTOP: + case GPS_L1_DSP_ENTER_DSLEEP: + gps_dl_hw_usrt_ctrl(GPS_DATA_LINK_ID0, + false, gps_dl_is_dma_enabled(), gps_dl_is_1byte_mode()); + + /* poll */ + dsp_off_done = gps_dl_hw_gps_dsp_is_off_done(GPS_DATA_LINK_ID0); + + gps_dl_hw_gps_pwr_stat_ctrl(ctrl); + if (ctrl == GPS_L1_DSP_ENTER_DSLEEP) { + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L1_DSPPRAM_PDN_EN_RGU_GPS_L1_PRAM_HWCTL_PDN, 0); + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L1_DSPPRAM_SLP_EN_RGU_GPS_L1_PRAM_HWCTL_SLP, 0x1FF); + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L1_DSPXRAM_PDN_EN_RGU_GPS_L1_XRAM_HWCTL_PDN, 0); + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L1_DSPXRAM_SLP_EN_RGU_GPS_L1_XRAM_HWCTL_SLP, 0xF); + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L1_DSPYRAM_PDN_EN_RGU_GPS_L1_YRAM_HWCTL_PDN, 0); + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L1_DSPYRAM_SLP_EN_RGU_GPS_L1_YRAM_HWCTL_SLP, 0x1FF); + } else if (ctrl == GPS_L1_DSP_ENTER_DSTOP) { + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L1_DSPPRAM_PDN_EN_RGU_GPS_L1_PRAM_HWCTL_PDN, 0); + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L1_DSPPRAM_SLP_EN_RGU_GPS_L1_PRAM_HWCTL_SLP, 0x1FF); + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L1_DSPXRAM_PDN_EN_RGU_GPS_L1_XRAM_HWCTL_PDN, 0); + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L1_DSPXRAM_SLP_EN_RGU_GPS_L1_XRAM_HWCTL_SLP, 0xF); + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L1_DSPYRAM_PDN_EN_RGU_GPS_L1_YRAM_HWCTL_PDN, 0x1FF); + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L1_DSPYRAM_SLP_EN_RGU_GPS_L1_YRAM_HWCTL_SLP, 0); + } else { + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L1_DSPPRAM_PDN_EN_RGU_GPS_L1_PRAM_HWCTL_PDN, 0x1FF); + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L1_DSPPRAM_SLP_EN_RGU_GPS_L1_PRAM_HWCTL_SLP, 0); + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L1_DSPXRAM_PDN_EN_RGU_GPS_L1_XRAM_HWCTL_PDN, 0xF); + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L1_DSPXRAM_SLP_EN_RGU_GPS_L1_XRAM_HWCTL_SLP, 0); + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L1_DSPYRAM_PDN_EN_RGU_GPS_L1_YRAM_HWCTL_PDN, 0x1FF); + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L1_DSPYRAM_SLP_EN_RGU_GPS_L1_YRAM_HWCTL_SLP, 0); + } + + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L1_CR_RGU_GPS_L1_SOFT_RST_B, 0); + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L1_CR_RGU_GPS_L1_ON, 0); + + if (dsp_off_done) + return 0; + else + return -1; + + case GPS_L5_DSP_ON: + case GPS_L5_DSP_EXIT_DSTOP: + case GPS_L5_DSP_EXIT_DSLEEP: + gps_dl_hw_gps_pwr_stat_ctrl(ctrl); + + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L5_CR_RGU_GPS_L5_ON, 1); + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L5_CR_RGU_GPS_L5_SOFT_RST_B, 1); + GDL_HW_POLL_GPS_ENTRY(GPS_CFG_ON_GPS_L5_SLP_PWR_CTL_GPS_L5_SLP_PWR_CTL_CS, 3, + POLL_DEFAULT, &poll_okay); + if (!poll_okay) { + GDL_LOGE("ctrl = %d fail", ctrl); + return -1; + } + + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L5_MEM_DLY_CTL_RGU_GPSSYS_L5_MEM_ADJ_DLY_EN, 1); + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L5_DLY_CHAIN_CTL_RGU_GPS_L5_MEM_PDN_DELAY_DUMMY_NUM, 9); + gps_dl_wait_us(100); /* 3 x 32k clk ~= 1ms */ + gps_dl_hw_usrt_ctrl(GPS_DATA_LINK_ID1, + true, gps_dl_is_dma_enabled(), gps_dl_is_1byte_mode()); + break; + + case GPS_L5_DSP_CLEAR_PWR_STAT: + gps_dl_hw_gps_pwr_stat_ctrl(ctrl); + return 0; + + case GPS_L5_DSP_OFF: + case GPS_L5_DSP_ENTER_DSTOP: + case GPS_L5_DSP_ENTER_DSLEEP: + gps_dl_hw_usrt_ctrl(GPS_DATA_LINK_ID1, + false, gps_dl_is_dma_enabled(), gps_dl_is_1byte_mode()); + + /* poll */ + dsp_off_done = gps_dl_hw_gps_dsp_is_off_done(GPS_DATA_LINK_ID1); + + gps_dl_hw_gps_pwr_stat_ctrl(ctrl); + if (ctrl == GPS_L5_DSP_ENTER_DSLEEP) { + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L5_DSPPRAM_PDN_EN_RGU_GPS_L5_PRAM_HWCTL_PDN, 0); + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L5_DSPPRAM_SLP_EN_RGU_GPS_L5_PRAM_HWCTL_SLP, 0x3FF); + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L5_DSPXRAM_PDN_EN_RGU_GPS_L5_XRAM_HWCTL_PDN, 0); + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L5_DSPXRAM_SLP_EN_RGU_GPS_L5_XRAM_HWCTL_SLP, 0xF); + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L5_DSPYRAM_PDN_EN_RGU_GPS_L5_YRAM_HWCTL_PDN, 0); + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L5_DSPYRAM_SLP_EN_RGU_GPS_L5_YRAM_HWCTL_SLP, 0x3FF); + } else if (ctrl == GPS_L5_DSP_ENTER_DSTOP) { + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L5_DSPPRAM_PDN_EN_RGU_GPS_L5_PRAM_HWCTL_PDN, 0); + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L5_DSPPRAM_SLP_EN_RGU_GPS_L5_PRAM_HWCTL_SLP, 0x3FF); + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L5_DSPXRAM_PDN_EN_RGU_GPS_L5_XRAM_HWCTL_PDN, 0); + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L5_DSPXRAM_SLP_EN_RGU_GPS_L5_XRAM_HWCTL_SLP, 0xF); + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L5_DSPYRAM_PDN_EN_RGU_GPS_L5_YRAM_HWCTL_PDN, 0x3FF); + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L5_DSPYRAM_SLP_EN_RGU_GPS_L5_YRAM_HWCTL_SLP, 0); + } else { + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L5_DSPPRAM_PDN_EN_RGU_GPS_L5_PRAM_HWCTL_PDN, 0x3FF); + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L5_DSPPRAM_SLP_EN_RGU_GPS_L5_PRAM_HWCTL_SLP, 0); + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L5_DSPXRAM_PDN_EN_RGU_GPS_L5_XRAM_HWCTL_PDN, 0xF); + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L5_DSPXRAM_SLP_EN_RGU_GPS_L5_XRAM_HWCTL_SLP, 0); + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L5_DSPYRAM_PDN_EN_RGU_GPS_L5_YRAM_HWCTL_PDN, 0x3FF); + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L5_DSPYRAM_SLP_EN_RGU_GPS_L5_YRAM_HWCTL_SLP, 0); + } + + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L5_CR_RGU_GPS_L5_SOFT_RST_B, 0); + GDL_HW_SET_GPS_ENTRY(GPS_RGU_ON_GPS_L5_CR_RGU_GPS_L5_ON, 0); + + if (dsp_off_done) + return 0; + else + return -1; + + default: + return -1; + } + + return 0; +} + +bool gps_dl_hw_gps_dsp_is_off_done(enum gps_dl_link_id_enum link_id) +{ + int i; + bool done; + bool show_log; + + /* TODO: move it to proper place */ + if (GPS_DSP_ST_HW_STOP_MODE == gps_dsp_state_get(link_id)) { + /* expect it change to RESET_DONE after this call */ + if (!gps_dl_hal_mcub_flag_handler(link_id)) { + GDL_LOGXW(link_id, "pre-check fail"); + return false; + } + } + + if (GPS_DSP_ST_RESET_DONE == gps_dsp_state_get(link_id)) { + GDL_LOGXD(link_id, "1st return, done = 1"); + return true; + } + + i = 0; + + show_log = gps_dl_set_show_reg_rw_log(true); + do { + /* MCUB IRQ already mask at this time */ + if (!gps_dl_hal_mcub_flag_handler(link_id)) { + done = false; + break; + } + + done = true; + while (GPS_DSP_ST_RESET_DONE != gps_dsp_state_get(link_id)) { + /* poll 10ms */ + if (i > 10) { + done = false; + break; + } + gps_dl_wait_us(1000); + + /* read dummy cr confirm dsp state for debug */ + if (GPS_DATA_LINK_ID0 == link_id) + GDL_HW_RD_GPS_REG(0x80073160); + else if (GPS_DATA_LINK_ID1 == link_id) + GDL_HW_RD_GPS_REG(0x80073134); + + if (!gps_dl_hal_mcub_flag_handler(link_id)) { + done = false; + break; + } + i++; + } + } while (0); + gps_dl_set_show_reg_rw_log(show_log); + GDL_LOGXW(link_id, "2nd return, done = %d, i = %d", done, i); + return done; +} + +void gps_dl_hw_gps_adie_force_off(void) +{ +#if GPS_DL_HAS_CONNINFRA_DRV + unsigned int spi_data; + int rd_status; + int wr_status; + + /* TOP: 0xFC[1:0] = 2'b11 */ + spi_data = 0; + rd_status = conninfra_spi_read(SYS_SPI_TOP, 0xFC, &spi_data); + ASSERT_ZERO(rd_status, GDL_VOIDF()); + GDL_LOGW("spi_data = 0x%x", spi_data); + wr_status = conninfra_spi_write(SYS_SPI_TOP, 0xFC, spi_data | 3UL); + ASSERT_ZERO(wr_status, GDL_VOIDF()); + + /* TOP: 0xA0C[31:0] = 0xFFFFFFFF; 0xAFC[31:0] = 0xFFFFFFFF */ + wr_status = conninfra_spi_write(SYS_SPI_TOP, 0xA0C, 0xFFFFFFFF); + ASSERT_ZERO(wr_status, GDL_VOIDF()); + wr_status = conninfra_spi_write(SYS_SPI_TOP, 0xAFC, 0xFFFFFFFF); + ASSERT_ZERO(wr_status, GDL_VOIDF()); + + /* TOP: 0xF8[0] = 1'b0 */ + spi_data = 0; + rd_status = conninfra_spi_read(SYS_SPI_TOP, 0xF8, &spi_data); + ASSERT_ZERO(rd_status, GDL_VOIDF()); + GDL_LOGW("spi_data = 0x%x", spi_data); + wr_status = conninfra_spi_write(SYS_SPI_TOP, 0xF8, spi_data & (~1UL)); + ASSERT_ZERO(wr_status, GDL_VOIDF()); + + /* GPS: 0x0[15] = 1'b1 */ + spi_data = 0; + rd_status = conninfra_spi_read(SYS_SPI_GPS, 0x0, &spi_data); + ASSERT_ZERO(rd_status, GDL_VOIDF()); + GDL_LOGW("spi_data = 0x%x", spi_data); + wr_status = conninfra_spi_write(SYS_SPI_GPS, 0x0, spi_data & (1UL << 15)); + ASSERT_ZERO(wr_status, GDL_VOIDF()); + + /* TOP: 0xF8[0] = 1'b1 */ + spi_data = 0; + rd_status = conninfra_spi_read(SYS_SPI_TOP, 0xF8, &spi_data); + ASSERT_ZERO(rd_status, GDL_VOIDF()); + GDL_LOGW("spi_data = 0x%x", spi_data); + wr_status = conninfra_spi_write(SYS_SPI_TOP, 0xF8, spi_data | 1UL); + ASSERT_ZERO(wr_status, GDL_VOIDF()); + + /* GPS: 0x0[15] = 1'b1 */ + spi_data = 0; + rd_status = conninfra_spi_read(SYS_SPI_GPS, 0x0, &spi_data); + ASSERT_ZERO(rd_status, GDL_VOIDF()); + GDL_LOGW("spi_data = 0x%x", spi_data); + wr_status = conninfra_spi_write(SYS_SPI_GPS, 0x0, spi_data & (1UL << 15)); + ASSERT_ZERO(wr_status, GDL_VOIDF()); + + /* TOP: 0xF8[0] = 1'b0 */ + spi_data = 0; + rd_status = conninfra_spi_read(SYS_SPI_TOP, 0xF8, &spi_data); + ASSERT_ZERO(rd_status, GDL_VOIDF()); + GDL_LOGW("spi_data = 0x%x", spi_data); + wr_status = conninfra_spi_write(SYS_SPI_TOP, 0xF8, spi_data & (~1UL)); + ASSERT_ZERO(wr_status, GDL_VOIDF()); + + /* TOP: 0xA0C[31:0] = 0; 0xAFC[31:0] = 0 */ + wr_status = conninfra_spi_write(SYS_SPI_TOP, 0xA0C, 0); + ASSERT_ZERO(wr_status, GDL_VOIDF()); + wr_status = conninfra_spi_write(SYS_SPI_TOP, 0xAFC, 0); + ASSERT_ZERO(wr_status, GDL_VOIDF()); + + /* TOP: 0xFC[1:0] = 2'b00 */ + rd_status = conninfra_spi_read(SYS_SPI_TOP, 0xFC, &spi_data); + ASSERT_ZERO(rd_status, GDL_VOIDF()); + GDL_LOGW("spi_data = 0x%x", spi_data); + wr_status = conninfra_spi_write(SYS_SPI_TOP, 0xFC, spi_data & (~3UL)); + ASSERT_ZERO(wr_status, GDL_VOIDF()); +#else + GDL_LOGE("no conninfra driver"); +#endif +} + +void gps_dl_hw_gps_dump_top_rf_cr(void) +{ +#if GPS_DL_HAS_CONNINFRA_DRV + unsigned int spi_data; + int rd_status; + int i; + const int rd_addr_list[] = {0x03C, 0xA18, 0xA1C, 0x0C8, 0xA00, 0x0B4, 0x34C}; + int rd_addr; + + for (i = 0; i < ARRAY_SIZE(rd_addr_list); i++) { + rd_addr = rd_addr_list[i]; + spi_data = 0; + rd_status = conninfra_spi_read(SYS_SPI_TOP, rd_addr, &spi_data); + GDL_LOGW("rd: addr = 0x%x, val = 0x%x, rd_status = %d", + rd_addr, spi_data, rd_status); + } +#else + GDL_LOGE("no conninfra driver"); +#endif +} + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hw/gps_dl_hw_priv_util.h b/drivers/misc/mediatek/connectivity/gps/data_link/hw/gps_dl_hw_priv_util.h new file mode 100644 index 0000000000000000000000000000000000000000..46c92768005507418d50c42d994843d06861dc1e --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hw/gps_dl_hw_priv_util.h @@ -0,0 +1,221 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#ifndef _GPS_DL_HW_UTIL_H +#define _GPS_DL_HW_UTIL_H + +#include "gps_dl_config.h" +#include "gps_dl_hw_type.h" +#include "gps_dl_time_tick.h" + +enum GPS_DL_BUS_ENUM { + GPS_DL_GPS_BUS, + GPS_DL_BGF_BUS, + GPS_DL_CONN_INFRA_BUS, + GPS_DL_BUS_NUM +}; + +enum gps_dl_bus_rw_opt_enum { + WR_NO_READ_BACK, + RW_DO_CHECK, + RW_FORCE_PRINT, + RW_FULL_PRINT, + RW_OPT_MAX = 32 +}; +#define BMASK_WR_NO_READ_BACK (1UL << WR_NO_READ_BACK) +#define BMASK_RW_DO_CHECK (1UL << RW_DO_CHECK) +#define BMASK_RW_FORCE_PRINT (1UL << RW_FORCE_PRINT) +#define BMASK_RW_FULL_PRINT (1UL << RW_FULL_PRINT) + +void gps_dl_bus_wr_opt(enum GPS_DL_BUS_ENUM bus_id, unsigned int bus_addr, unsigned int val, + unsigned int opt_bitmask); +unsigned int gps_dl_bus_rd_opt(enum GPS_DL_BUS_ENUM bus_id, unsigned int bus_addr, + unsigned int opt_bitmask); + + +/* the function will convert bus addr to host-view addr by remaping */ +#if 0 +void gps_dl_bus_wr32(u32 bus_addr, u32 val); +u32 gps_dl_bus_rd32(u32 bus_addr); +#endif +void gps_dl_bus_write(enum GPS_DL_BUS_ENUM bus_id, unsigned int bus_addr, unsigned int val); +void gps_dl_bus_write_no_rb(enum GPS_DL_BUS_ENUM bus_id, unsigned int bus_addr, unsigned int val); +unsigned int gps_dl_bus_read(enum GPS_DL_BUS_ENUM bus_id, unsigned int bus_addr); +void gps_dl_bus_check_and_print(unsigned int host_addr); + + +/* provide function/macro declaration for c files under hal folder */ + +/* todo: writel, mb */ +#define ADDR(Field) (Field##_ADDR) +#define MASK(Field) (Field##_MASK) +#define SHFT(Field) (Field##_SHFT) + +/* TODO: using volatile in kernel is almost an error */ +#if 0 +#define DL_SET_ENTRY(Field, Value) \ + { conn_reg * addr = ADDR(Field); \ + *addr = ((((conn_reg)(Value) << SHFT(Field)) \ + & MASK(Field)) | (*addr & ~MASK(Field))) ; } + +#define DL_GET_ENTRY(Field) \ + ((*ADDR(Field) & (MASK(Field))) >> SHFT(Field)) +#endif + +/* todo + * 1. iomap the region to access or just writel can work? + * 2. using volatile in kernel is almost an error. Replace it with accessor functions + */ +#if GPS_DL_ON_CTP +#define GPS_DL_HOST_REG_WR(host_addr, val) ((*(conn_reg *)host_addr) = (val)) +#define GPS_DL_HOST_REG_RD(host_addr) (*(conn_reg *)host_addr) +#else +#define GPS_DL_HOST_REG_WR(host_addr, val) do {} while (0) +#define GPS_DL_HOST_REG_RD(host_addr) (0) +#endif + +#define GDL_HW_WR_CONN_INFRA_REG(Addr, Value) gps_dl_bus_write(GPS_DL_CONN_INFRA_BUS, Addr, Value) +#define GDL_HW_RD_CONN_INFRA_REG(Addr) gps_dl_bus_read(GPS_DL_CONN_INFRA_BUS, Addr) + +#define GDL_HW_WR_BGF_REG(Addr, Value) gps_dl_bus_write(GPS_DL_BGF_BUS, Addr, Value) +#define GDL_HW_RD_BGF_REG(Addr) gps_dl_bus_read(GPS_DL_BGF_BUS, Addr) + +#define GDL_HW_WR_GPS_REG(Addr, Value) gps_dl_bus_write(GPS_DL_GPS_BUS, Addr, Value) +#define GDL_HW_RD_GPS_REG(Addr) gps_dl_bus_read(GPS_DL_GPS_BUS, Addr) + + +#define GDL_HW_SET_ENTRY(Bus_ID, Field, Value) do { \ + conn_reg val; \ + val = gps_dl_bus_read(Bus_ID, ADDR(Field)); \ + val &= (~MASK(Field)); \ + val |= ((Value << SHFT(Field)) & MASK(Field)); \ + gps_dl_bus_write(Bus_ID, ADDR(Field), val); \ + } while (0) + +#define GDL_HW_GET_ENTRY(Bus_ID, Field) \ + ((gps_dl_bus_read(Bus_ID, ADDR(Field)) & (MASK(Field))) >> SHFT(Field)) + +#define GDL_HW_EXTRACT_ENTRY(Field, Val) \ + ((Val & (MASK(Field))) >> SHFT(Field)) + +#define POLL_INTERVAL_US (100) +#define POLL_US (1) +#define POLL_1_TIME (0) +#define POLL_FOREVER (-1) +#define POLL_DEFAULT (1000 * POLL_US) +#if (GPS_DL_ON_CTP || GPS_DL_ON_LINUX) +#define GDL_HW_POLL_ENTRY_VERBOSE(Bus_ID, Field, pIsOkay, pLastValue, TimeoutUsec, condExpected) \ + do { \ + if (pIsOkay != NULL) { \ + *pIsOkay = false; \ + } \ + if (POLL_1_TIME == TimeoutUsec) { \ + if (pLastValue != NULL) { \ + *pLastValue = GDL_HW_GET_ENTRY(Bus_ID, Field); \ + } \ + if ((condExpected)) { \ + if (pIsOkay != NULL) { \ + *pIsOkay = true; \ + } \ + } \ + } else if (TimeoutUsec > 0) { \ + unsigned int poll_wait_cnt = 0; \ + while (true) { \ + if (pLastValue != NULL) { \ + *pLastValue = GDL_HW_GET_ENTRY(Bus_ID, Field); \ + } \ + if ((condExpected)) { \ + if (pIsOkay != NULL) { \ + *pIsOkay = true; \ + } \ + break; \ + } \ + if (poll_wait_cnt >= TimeoutUsec) { \ + break; \ + } \ + gps_dl_wait_us(POLL_INTERVAL_US); \ + poll_wait_cnt += POLL_INTERVAL_US; \ + } \ + } else if (TimeoutUsec <= POLL_FOREVER) { \ + while (true) { \ + if (pLastValue != NULL) { \ + *pLastValue = GDL_HW_GET_ENTRY(Bus_ID, Field); \ + } \ + if ((condExpected)) { \ + if (pIsOkay != NULL) { \ + *pIsOkay = true; \ + } \ + break; \ + } \ + gps_dl_wait_us(POLL_INTERVAL_US); \ + } \ + } \ + } while (0) + +#define GDL_HW_POLL_ENTRY(Bus_ID, Field, ValueExpected, TimeoutUsec, pIsOkay) \ + do { \ + unsigned int gdl_hw_poll_value; \ + GDL_HW_POLL_ENTRY_VERBOSE(Bus_ID, Field, \ + pIsOkay, &gdl_hw_poll_value, \ + TimeoutUsec, (gdl_hw_poll_value == ValueExpected)); \ + } while (0) +#else +#define GDL_HW_POLL_ENTRY(Bus_ID, Field, ValueExpected, TimeoutUsec, pIsOkay) \ + do { \ + if (ValueExpected == GDL_HW_GET_ENTRY(Bus_ID, Field)) { \ + ; \ + } \ + } while (0) +#endif + + + +#define GDL_HW_SET_CONN_INFRA_ENTRY(Field, Value) GDL_HW_SET_ENTRY(GPS_DL_CONN_INFRA_BUS, Field, Value) +#define GDL_HW_GET_CONN_INFRA_ENTRY(Field) GDL_HW_GET_ENTRY(GPS_DL_CONN_INFRA_BUS, Field) +#define GDL_HW_POLL_CONN_INFRA_ENTRY(Field, ValueExpected, TimeoutUsec, pIsOkay) \ + GDL_HW_POLL_ENTRY(GPS_DL_CONN_INFRA_BUS, Field, ValueExpected, TimeoutUsec, pIsOkay) + +#define GDL_HW_SET_BGF_ENTRY(Field, Value) GDL_HW_SET_ENTRY(GPS_DL_BGF_BUS, Field, Value) +#define GDL_HW_GET_BGF_ENTRY(Field) GDL_HW_GET_ENTRY(GPS_DL_BGF_BUS, Field) +#define GDL_HW_POLL_BGF_ENTRY(Field, ValueExpected, TimeoutUsec, pIsOkay) \ + GDL_HW_POLL_ENTRY(GPS_DL_BGF_BUS, Field, ValueExpected, TimeoutUsec, pIsOkay) + +#define GDL_HW_SET_GPS_ENTRY(Field, Value) GDL_HW_SET_ENTRY(GPS_DL_GPS_BUS, Field, Value) +#define GDL_HW_SET_GPS_ENTRY2(LinkID, Value, Field1, Field2) do { \ + if (GPS_DATA_LINK_ID0 == LinkID) \ + GDL_HW_SET_GPS_ENTRY(Field1, Value); \ + else if (GPS_DATA_LINK_ID1 == LinkID) \ + GDL_HW_SET_GPS_ENTRY(Field2, Value); \ + } while (0) + +#define GDL_HW_GET_GPS_ENTRY(Field) GDL_HW_GET_ENTRY(GPS_DL_GPS_BUS, Field) +#define GDL_HW_GET_GPS_ENTRY2(LinkID, Field1, Field2) ( \ + (GPS_DATA_LINK_ID0 == LinkID) ? \ + GDL_HW_GET_GPS_ENTRY(Field1) : \ + ((GPS_DATA_LINK_ID1 == LinkID) ? \ + GDL_HW_GET_GPS_ENTRY(Field2) : 0) \ + ) + +#define GDL_HW_POLL_GPS_ENTRY(Field, ValueExpected, TimeoutUsec, pIsOkay) \ + GDL_HW_POLL_ENTRY(GPS_DL_GPS_BUS, Field, ValueExpected, TimeoutUsec, pIsOkay) + +struct gps_dl_addr_map_entry { + unsigned int host_addr; + unsigned int bus_addr; + unsigned int length; +}; + +unsigned int bgf_bus_to_host(unsigned int bgf_addr); +unsigned int gps_bus_to_host(unsigned int gps_addr); + + +#endif /* _GPS_DL_HW_UTIL_H */ diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hw/gps_dl_hw_usrt_apb.c b/drivers/misc/mediatek/connectivity/gps/data_link/hw/gps_dl_hw_usrt_apb.c new file mode 100644 index 0000000000000000000000000000000000000000..40a1921dd70bcd8e1918d917ad4b91b21ffeb1e5 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hw/gps_dl_hw_usrt_apb.c @@ -0,0 +1,450 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#include "gps_dl_config.h" +#include "gps_dl_context.h" +#include "gps_dl_time_tick.h" + +#include "gps_dl_hal.h" +#if GPS_DL_MOCK_HAL +#include "gps_mock_hal.h" +#endif + +#include "gps_dl_hw_api.h" +#include "gps_dl_hw_priv_util.h" + +#include "gps/gps_usrt_apb.h" +#include "gps/gps_l5_usrt_apb.h" +#include "gps/bgf_gps_dma.h" +#include "conn_infra/conn_host_csr_top.h" + +void gps_dl_hw_usrt_rx_irq_enable(enum gps_dl_link_id_enum link_id, bool enable) +{ + if (enable) + GDL_HW_SET_GPS_ENTRY2(link_id, 1, GPS_USRT_APB_APB_INTEN_TXIEN, GPS_L5_USRT_APB_APB_INTEN_TXIEN); + else + GDL_HW_SET_GPS_ENTRY2(link_id, 0, GPS_USRT_APB_APB_INTEN_TXIEN, GPS_L5_USRT_APB_APB_INTEN_TXIEN); +} + +#define GPS_DSP_CFG_BITMASK_ADIE_IS_MT6631 (1UL << 0) +#define GPS_DSP_CFG_BITMASK_MVCD_SPEED_UP (1UL << 1) +#define GPS_DSP_CFG_BITMASK_ADIE_IS_MT6635_E2_OR_AFTER (1UL << 2) +#define GPS_DSP_CFG_BITMASK_USRT_4BYTE_MODE (1UL << 3) +#define GPS_DSP_CFG_BITMASK_COLOCK_USE_TIA (1UL << 6) +#define GPS_DSP_CFG_BITMASK_CLOCK_EXTENSION_WAKEUP (1UL << 7) + +unsigned int gps_dl_hw_get_mcub_a2d1_cfg(enum gps_dl_link_id_enum link_id, bool is_1byte_mode) +{ + unsigned int cfg = 0; + + cfg |= GPS_DSP_CFG_BITMASK_MVCD_SPEED_UP; + cfg |= GPS_DSP_CFG_BITMASK_ADIE_IS_MT6635_E2_OR_AFTER; + if (!is_1byte_mode) + cfg |= GPS_DSP_CFG_BITMASK_USRT_4BYTE_MODE; +#if GPS_DL_USE_TIA + cfg |= GPS_DSP_CFG_BITMASK_COLOCK_USE_TIA; +#endif + if (gps_dl_hal_get_need_clk_ext_flag(link_id)) + cfg |= GPS_DSP_CFG_BITMASK_CLOCK_EXTENSION_WAKEUP; + return cfg; +} + +void gps_dl_hw_usrt_ctrl(enum gps_dl_link_id_enum link_id, + bool is_on, bool is_dma_mode, bool is_1byte_mode) +{ + bool poll_okay; + + if (is_1byte_mode) + GDL_HW_SET_GPS_ENTRY2(link_id, 1, GPS_USRT_APB_APB_CTRL_BYTEN, GPS_L5_USRT_APB_APB_CTRL_BYTEN); + else + GDL_HW_SET_GPS_ENTRY2(link_id, 0, GPS_USRT_APB_APB_CTRL_BYTEN, GPS_L5_USRT_APB_APB_CTRL_BYTEN); + + if (!is_on) { + GDL_HW_SET_GPS_ENTRY2(link_id, 0, GPS_USRT_APB_APB_CTRL_TX_EN, GPS_L5_USRT_APB_APB_CTRL_TX_EN); + GDL_HW_SET_GPS_ENTRY2(link_id, 0, GPS_USRT_APB_APB_CTRL_RX_EN, GPS_L5_USRT_APB_APB_CTRL_RX_EN); + GDL_HW_SET_GPS_ENTRY2(link_id, 0, GPS_USRT_APB_APB_INTEN_TXIEN, GPS_L5_USRT_APB_APB_INTEN_TXIEN); + GDL_HW_SET_GPS_ENTRY2(link_id, 0, GPS_USRT_APB_APB_INTEN_NODAIEN, GPS_L5_USRT_APB_APB_INTEN_NODAIEN); + } else if (is_dma_mode) { + GDL_HW_SET_GPS_ENTRY2(link_id, 1, GPS_USRT_APB_APB_CTRL_TX_EN, GPS_L5_USRT_APB_APB_CTRL_TX_EN); + GDL_HW_SET_GPS_ENTRY2(link_id, 1, GPS_USRT_APB_APB_CTRL_RX_EN, GPS_L5_USRT_APB_APB_CTRL_RX_EN); + GDL_HW_SET_GPS_ENTRY2(link_id, 1, GPS_USRT_APB_APB_INTEN_TXIEN, GPS_L5_USRT_APB_APB_INTEN_TXIEN); + GDL_HW_SET_GPS_ENTRY2(link_id, 1, GPS_USRT_APB_APB_INTEN_NODAIEN, GPS_L5_USRT_APB_APB_INTEN_NODAIEN); + } else { + GDL_HW_SET_GPS_ENTRY2(link_id, 0, GPS_USRT_APB_APB_CTRL_TX_EN, GPS_L5_USRT_APB_APB_CTRL_TX_EN); + GDL_HW_SET_GPS_ENTRY2(link_id, 0, GPS_USRT_APB_APB_CTRL_RX_EN, GPS_L5_USRT_APB_APB_CTRL_RX_EN); + GDL_HW_SET_GPS_ENTRY2(link_id, 1, GPS_USRT_APB_APB_INTEN_TXIEN, GPS_L5_USRT_APB_APB_INTEN_TXIEN); + GDL_HW_SET_GPS_ENTRY2(link_id, 0, GPS_USRT_APB_APB_INTEN_NODAIEN, GPS_L5_USRT_APB_APB_INTEN_NODAIEN); + } + + GDL_HW_SET_GPS_ENTRY2(link_id, gps_dl_hw_get_mcub_a2d1_cfg(link_id, is_1byte_mode), + GPS_USRT_APB_MCU_A2D1_A2D_1, GPS_L5_USRT_APB_MCU_A2D1_A2D_1); + + GDL_HW_SET_GPS_ENTRY2(link_id, 1, GPS_USRT_APB_MCUB_A2DF_A2DF3, GPS_L5_USRT_APB_MCUB_A2DF_A2DF3); + + /* wait ROM okay flag */ + if (link_id == GPS_DATA_LINK_ID0) + GDL_HW_POLL_GPS_ENTRY(GPS_USRT_APB_MCUB_D2AF_D2AF3, 1, POLL_DEFAULT, &poll_okay); + else + GDL_HW_POLL_GPS_ENTRY(GPS_L5_USRT_APB_MCUB_D2AF_D2AF3, 1, POLL_DEFAULT, &poll_okay); +} + +bool gps_dl_hw_usrt_has_set_nodata_flag(enum gps_dl_link_id_enum link_id) +{ + return (bool)GDL_HW_GET_GPS_ENTRY2(link_id, + GPS_USRT_APB_APB_STA_NODAINTB, GPS_L5_USRT_APB_APB_STA_NODAINTB); +} + +void gps_dl_hw_usrt_clear_nodata_irq(enum gps_dl_link_id_enum link_id) +{ + GDL_HW_SET_GPS_ENTRY2(link_id, 1, GPS_USRT_APB_APB_STA_NODAINTB, GPS_L5_USRT_APB_APB_STA_NODAINTB); +} + +void gps_dl_hw_print_usrt_status(enum gps_dl_link_id_enum link_id) +{ + bool show_log; + unsigned int value; + + show_log = gps_dl_set_show_reg_rw_log(true); + if (link_id == GPS_DATA_LINK_ID0) { + value = GDL_HW_RD_GPS_REG(GPS_USRT_APB_APB_STA_ADDR); + value = GDL_HW_RD_GPS_REG(GPS_USRT_APB_MONF_ADDR); + } else if (link_id == GPS_DATA_LINK_ID1) { + value = GDL_HW_RD_GPS_REG(GPS_L5_USRT_APB_APB_STA_ADDR); + value = GDL_HW_RD_GPS_REG(GPS_L5_USRT_APB_MONF_ADDR); + } + gps_dl_set_show_reg_rw_log(show_log); +} + +bool gps_dl_hw_poll_usrt_dsp_rx_empty(enum gps_dl_link_id_enum link_id) +{ + bool poll_okay = false; + + if (link_id == GPS_DATA_LINK_ID0) + GDL_HW_POLL_GPS_ENTRY(GPS_USRT_APB_APB_STA_RX_EMP, 1, 10000 * POLL_US, &poll_okay); + else if (link_id == GPS_DATA_LINK_ID1) + GDL_HW_POLL_GPS_ENTRY(GPS_L5_USRT_APB_APB_STA_RX_EMP, 1, 10000 * POLL_US, &poll_okay); + + if (!poll_okay) + GDL_LOGXE_DRW(link_id, "okay = %d", poll_okay); + + return poll_okay; +} + +enum GDL_RET_STATUS gps_dl_hal_wait_and_handle_until_usrt_has_data( + enum gps_dl_link_id_enum link_id, int timeout_usec) +{ + struct gps_dl_hw_usrt_status_struct usrt_status; + bool last_rw_log_on; + unsigned long tick0, tick1; + + tick0 = gps_dl_tick_get(); + + if (gps_dl_show_reg_wait_log()) + GDL_LOGXD(link_id, "timeout = %d", timeout_usec); + + while (1) { + gps_dl_hw_save_usrt_status_struct(link_id, &usrt_status); + + if (gps_dl_only_show_wait_done_log()) + last_rw_log_on = gps_dl_set_show_reg_rw_log(false); + else + gps_dl_hw_print_usrt_status_struct(link_id, &usrt_status); + + if (GDL_HW_EXTRACT_ENTRY(GPS_USRT_APB_APB_STA_TX_IND, usrt_status.state)) { + if (gps_dl_only_show_wait_done_log()) { + gps_dl_set_show_reg_rw_log(last_rw_log_on); + gps_dl_hw_print_usrt_status_struct(link_id, &usrt_status); + gps_dl_hw_save_usrt_status_struct(link_id, &usrt_status); + } + + gps_dl_hal_event_send(GPS_DL_HAL_EVT_D2A_RX_HAS_DATA, link_id); + break; + } + + tick1 = gps_dl_tick_get(); + if (timeout_usec > GPS_DL_RW_NO_TIMEOUT && + gps_dl_tick_delta_to_usec(tick0, tick1) >= timeout_usec) + return GDL_FAIL_TIMEOUT; + + gps_dl_wait_us(GDL_HW_STATUS_POLL_INTERVAL_USEC); + } + + return GDL_OKAY; +} + +enum GDL_RET_STATUS gps_dl_hal_wait_and_handle_until_usrt_has_nodata_or_rx_dma_done( + enum gps_dl_link_id_enum link_id, int timeout_usec, bool to_handle) +{ + struct gps_dl_hw_dma_status_struct dma_status; + struct gps_dl_hw_usrt_status_struct usrt_status; + enum gps_dl_hal_dma_ch_index dma_ch; + bool last_rw_log_on; + unsigned long tick0, tick1; + bool conninfra_okay; + bool do_stop = true; + enum GDL_RET_STATUS ret = GDL_OKAY; + int loop_cnt; + + if (link_id == GPS_DATA_LINK_ID0) + dma_ch = GPS_DL_DMA_LINK0_D2A; + else if (link_id == GPS_DATA_LINK_ID1) + dma_ch = GPS_DL_DMA_LINK1_D2A; + else + return GDL_FAIL; + + if (gps_dl_show_reg_wait_log()) + GDL_LOGXD(link_id, "timeout = %d", timeout_usec); + + tick0 = gps_dl_tick_get(); + loop_cnt = 0; + while (1) { + conninfra_okay = gps_dl_conninfra_is_okay_or_handle_it(NULL, true); + if (!conninfra_okay) { + ret = GDL_FAIL_CONN_NOT_OKAY; + do_stop = false; + break; + } + + gps_dl_hw_save_dma_status_struct(dma_ch, &dma_status); + if (gps_dl_only_show_wait_done_log()) + last_rw_log_on = gps_dl_set_show_reg_rw_log(false); + else + gps_dl_hw_print_dma_status_struct(dma_ch, &dma_status); + + if (GDL_HW_EXTRACT_ENTRY(BGF_GPS_DMA_DMA1_START_STR, dma_status.intr_flag) && + GDL_HW_EXTRACT_ENTRY(BGF_GPS_DMA_DMA1_STATE_STATE, dma_status.state) == 0x01) { + if (gps_dl_only_show_wait_done_log()) { + gps_dl_set_show_reg_rw_log(last_rw_log_on); + gps_dl_hw_print_dma_status_struct(dma_ch, &dma_status); + gps_dl_hw_save_dma_status_struct(dma_ch, &dma_status); + } + + /* DMA has stopped */ + gps_dl_hw_set_dma_stop(dma_ch); + gps_dl_hw_save_dma_status_struct(dma_ch, &dma_status); + gps_dl_hw_print_dma_status_struct(dma_ch, &dma_status); + if (to_handle) + gps_dl_hal_event_send(GPS_DL_HAL_EVT_D2A_RX_DMA_DONE, link_id); + ret = GDL_OKAY; + do_stop = true; + break; + } + + gps_dl_hw_save_usrt_status_struct(link_id, &usrt_status); + if (gps_dl_only_show_wait_done_log()) + last_rw_log_on = gps_dl_set_show_reg_rw_log(false); + else + gps_dl_hw_print_usrt_status_struct(link_id, &usrt_status); + + if (GDL_HW_EXTRACT_ENTRY(GPS_USRT_APB_APB_STA_REGE, usrt_status.state) || + GDL_HW_EXTRACT_ENTRY(GPS_USRT_APB_APB_STA_NODAINTB, usrt_status.state)) { + if (gps_dl_only_show_wait_done_log()) { + gps_dl_set_show_reg_rw_log(last_rw_log_on); + gps_dl_hw_print_usrt_status_struct(link_id, &usrt_status); + gps_dl_hw_save_usrt_status_struct(link_id, &usrt_status); + } + if (to_handle) + gps_dl_hal_event_send(GPS_DL_HAL_EVT_D2A_RX_HAS_NODATA, link_id); + else { + gps_dl_hw_set_dma_stop(dma_ch); + gps_dl_hw_save_dma_status_struct(dma_ch, &dma_status); + gps_dl_hw_print_dma_status_struct(dma_ch, &dma_status); + } + ret = GDL_OKAY; + do_stop = true; + break; + } + + tick1 = gps_dl_tick_get(); + if (timeout_usec > GPS_DL_RW_NO_TIMEOUT && ( + gps_dl_tick_delta_to_usec(tick0, tick1) >= timeout_usec || + loop_cnt * GDL_HW_STATUS_POLL_INTERVAL_USEC >= timeout_usec)) { + ret = GDL_FAIL_TIMEOUT; + do_stop = false; + break; + } + + gps_dl_wait_us(GDL_HW_STATUS_POLL_INTERVAL_USEC); + loop_cnt++; + } + + tick1 = gps_dl_tick_get(); + GDL_LOGXW(link_id, "d_us = %d, cnt = %d, do_stop = %d, ret = %s", + gps_dl_tick_delta_to_usec(tick0, tick1), loop_cnt, do_stop, gdl_ret_to_name(ret)); + return ret; +} + +void gps_dl_hal_poll_single_link(enum gps_dl_link_id_enum link_id, + unsigned int evt_in, unsigned int *p_evt_out) +{ + unsigned int evt_out = 0; + struct gps_dl_hw_link_status_struct hw_status; + + gps_dl_hw_get_link_status(link_id, &hw_status); + + if (evt_in & (1UL << GPS_DL_POLL_TX_DMA_DONE)) { + if (hw_status.tx_dma_done) { + evt_out |= (1UL << GPS_DL_POLL_TX_DMA_DONE); + gps_dl_isr_a2d_tx_dma_done(link_id); + } + } + + if (evt_in & (1UL << GPS_DL_POLL_RX_DMA_DONE)) { + if (hw_status.rx_dma_done) { + evt_out |= (1UL << GPS_DL_POLL_RX_DMA_DONE); + gps_dl_isr_d2a_rx_dma_done(link_id); + } + } + + if (evt_in & (1UL << GPS_DL_POLL_USRT_HAS_DATA)) { + if (hw_status.usrt_has_data) { + evt_out |= (1UL << GPS_DL_POLL_USRT_HAS_DATA); + gps_dl_isr_usrt_has_data(link_id); + } + } + + if (evt_in & (1UL << GPS_DL_POLL_USRT_HAS_NODATA)) { + if (hw_status.usrt_has_nodata) { + evt_out |= (1UL << GPS_DL_POLL_USRT_HAS_NODATA); + gps_dl_isr_usrt_has_nodata(link_id); + } + } + + *p_evt_out = evt_out; +} + +enum GDL_RET_STATUS gps_dl_hal_poll_event( + unsigned int L1_evt_in, unsigned int L5_evt_in, + unsigned int *pL1_evt_out, unsigned int *pL5_evt_out, unsigned int timeout_usec) +{ + unsigned int L1_evt_out = 0; + unsigned int L5_evt_out = 0; + enum GDL_RET_STATUS ret_val = GDL_OKAY; + unsigned long tick0, tick1; + int take_usec; + + if (L1_evt_in == 0 && L5_evt_in == 0) { + *pL1_evt_out = 0; + *pL5_evt_out = 0; + return GDL_OKAY; + } + + tick0 = gps_dl_tick_get(); + while (1) { + if (L1_evt_in) + gps_dl_hal_poll_single_link(GPS_DATA_LINK_ID0, L1_evt_in, &L1_evt_out); + + if (L5_evt_in) + gps_dl_hal_poll_single_link(GPS_DATA_LINK_ID1, L5_evt_in, &L5_evt_out); + + tick1 = gps_dl_tick_get(); + take_usec = gps_dl_tick_delta_to_usec(tick0, tick1); + + if (L1_evt_out || L5_evt_out) + break; + + GDL_LOGD("tick0 = %ld, tick1 = %ld, usec = %d/%d", + tick0, tick1, take_usec, timeout_usec); + + if (take_usec >= timeout_usec) { + ret_val = GDL_FAIL_TIMEOUT; + break; + } + + gps_dl_wait_us(GDL_HW_STATUS_POLL_INTERVAL_USEC); + } + + GDL_LOGD("ret = %d, L1 = 0x%x, L5 = 0x%x, usec = %d/%d", + ret_val, L1_evt_out, L5_evt_out, take_usec, timeout_usec); + + if (ret_val != GDL_OKAY) + return ret_val; + + /* TODO: read one more time? */ + *pL1_evt_out = L1_evt_out; + *pL5_evt_out = L5_evt_out; + return GDL_OKAY; +} + +int gps_dl_hal_usrt_direct_write(enum gps_dl_link_id_enum link_id, + unsigned char *buf, unsigned int len) +{ + unsigned int reg_val; + unsigned int reg_addr; + int i, j; + + if (link_id == GPS_DATA_LINK_ID0) + reg_addr = GPS_USRT_APB_GPS_APB_DATA_ADDR; + else if (link_id == GPS_DATA_LINK_ID1) + reg_addr = GPS_L5_USRT_APB_GPS_APB_DATA_ADDR; + else + return -1; + + if (gps_dl_is_1byte_mode()) { + for (i = 0; i < len; i++) + gps_dl_bus_write_no_rb(GPS_DL_GPS_BUS, reg_addr, buf[i]); + } else { + for (i = 0; i < len;) { + reg_val = (unsigned int) buf[i++]; + + for (j = 1; j < 4 && i < len; j++, i++) + reg_val |= (((unsigned int) buf[i]) << (j * 8)); + + gps_dl_bus_write_no_rb(GPS_DL_GPS_BUS, reg_addr, reg_val); + } + } + + return 0; +} + +int gps_dl_hal_usrt_direct_read(enum gps_dl_link_id_enum link_id, + unsigned char *buf, unsigned int len) +{ + unsigned int reg_val; + unsigned int reg_addr; + struct gps_dl_hw_link_status_struct hw_status; + int i; + + if (link_id == GPS_DATA_LINK_ID0) + reg_addr = GPS_USRT_APB_GPS_APB_DATA_ADDR; + else if (link_id == GPS_DATA_LINK_ID1) + reg_addr = GPS_L5_USRT_APB_GPS_APB_DATA_ADDR; + else + return -1; + + /* GPS_USRT_APB_APB_STA_TXINTB_SHFT */ + /* APB_STA[7:0]: 0x22000030 -> 0x20000009 -> 0x22000019 -> 0x22000030 */ + do { + gps_dl_hw_get_link_status(link_id, &hw_status); + } while (!hw_status.usrt_has_data); + + for (i = 0; i < len; ) { + reg_val = GDL_HW_RD_GPS_REG(reg_addr); + + if (gps_dl_is_1byte_mode()) + buf[i++] = (unsigned char)reg_val; + else { + buf[i++] = (unsigned char)(reg_val >> 0); + buf[i++] = (unsigned char)(reg_val >> 8); + buf[i++] = (unsigned char)(reg_val >> 16); + buf[i++] = (unsigned char)(reg_val >> 24); + } + + gps_dl_hw_get_link_status(link_id, &hw_status); + if (!hw_status.usrt_has_data) /* no need: hw_status.usrt_has_nodata */ + break; + } + + GDL_LOGXD(link_id, "read len = %d", i); + return i; +} + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hw/gps_dl_hw_util.c b/drivers/misc/mediatek/connectivity/gps/data_link/hw/gps_dl_hw_util.c new file mode 100644 index 0000000000000000000000000000000000000000..7c7398e14758010c121d4926bf953b85113eb01b --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hw/gps_dl_hw_util.c @@ -0,0 +1,223 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#include "gps_dl_config.h" +#include "gps_dl_context.h" +#include "gps_dl_hw_priv_util.h" +#include "gps_dl_subsys_reset.h" + +#if GPS_DL_ON_LINUX +#include +#include +#include +#include "gps_dl_linux.h" +#if GPS_DL_HAS_PLAT_DRV +#include "gps_dl_linux_plat_drv.h" +#endif +#elif GPS_DL_ON_CTP +#include "kernel_to_ctp.h" +#endif + +unsigned int gps_dl_bus_to_host_addr(enum GPS_DL_BUS_ENUM bus_id, unsigned int bus_addr) +{ + unsigned int host_addr = 0; + + switch (bus_id) { + case GPS_DL_GPS_BUS: + host_addr = gps_bus_to_host(bus_addr); + break; + case GPS_DL_BGF_BUS: + host_addr = bgf_bus_to_host(bus_addr); + break; + case GPS_DL_CONN_INFRA_BUS: + host_addr = bus_addr; + break; + default: + host_addr = 0; + } + + return host_addr; +} + +void gps_dl_bus_wr_opt(enum GPS_DL_BUS_ENUM bus_id, unsigned int bus_addr, unsigned int val, + unsigned int opt_bitmask) +{ + bool no_read_back = !!(opt_bitmask & BMASK_WR_NO_READ_BACK); + bool do_check = !!(opt_bitmask & BMASK_RW_DO_CHECK); + bool force_print = !!(opt_bitmask & BMASK_RW_FORCE_PRINT); + bool full_print = !!(opt_bitmask & BMASK_RW_FULL_PRINT); + bool print_vir_addr = false; + + unsigned int read_back_val = 0; + unsigned int host_addr = gps_dl_bus_to_host_addr(bus_id, bus_addr); +#if GPS_DL_ON_LINUX +#if GPS_DL_HAS_PLAT_DRV + void __iomem *host_vir_addr = gps_dl_host_addr_to_virt(host_addr); +#else + void __iomem *host_vir_addr = phys_to_virt(host_addr); +#endif +#else + void *host_vir_addr = NULL; +#endif + + /* + * For linux preparation and checking + */ +#if GPS_DL_ON_LINUX + if (host_vir_addr == NULL) { + GDL_LOGW_RRW("bus_id = %d, addr = 0x%p/0x%08x/0x%08x, NULL!", + bus_id, host_vir_addr, host_addr, bus_addr); + return; + } + print_vir_addr = true; + + if (do_check) { + /* gps_dl_conninfra_not_readable_show_warning(host_addr); */ + gps_dl_bus_check_and_print(host_addr); + } +#endif /* GPS_DL_ON_LINUX */ + + /* + * Do writing + */ +#if GPS_DL_HW_IS_MOCK + /* do nothing if it's mock */ +#elif GPS_DL_ON_LINUX + gps_dl_linux_sync_writel(val, host_vir_addr); +#else + GPS_DL_HOST_REG_WR(host_addr, val); +#endif + + /* + * Do reading back + */ + if (!no_read_back) { +#if GPS_DL_HW_IS_MOCK + /* do nothing if it's mock */ +#elif GPS_DL_ON_LINUX + read_back_val = __raw_readl(host_vir_addr); +#else + read_back_val = GPS_DL_HOST_REG_RD(host_addr); +#endif + } + if (!(gps_dl_show_reg_rw_log() || force_print)) + return; + + /* + * Do printing if need + */ + if (no_read_back && (!full_print)) { + GDL_LOGI_RRW("bus_id = %d, addr = 0x%08x, w_val = 0x%08x", + bus_id, host_addr, val); + } else if (no_read_back && (full_print && !print_vir_addr)) { + GDL_LOGI_RRW("bus_id = %d, addr = 0x%08x/0x%08x, w_val = 0x%08x", + bus_id, host_addr, bus_addr, val); + } else if (no_read_back && (full_print && print_vir_addr)) { + GDL_LOGI_RRW("bus_id = %d, addr = 0x%p/0x%08x/0x%08x, w_val = 0x%08x", + bus_id, host_vir_addr, host_addr, bus_addr, val); + } else if (!no_read_back && (!full_print)) { + GDL_LOGI_RRW("bus_id = %d, addr = 0x%08x, w_val = 0x%08x, r_back = 0x%08x", + bus_id, host_addr, val, read_back_val); + } else if (!no_read_back && (full_print && !print_vir_addr)) { + GDL_LOGI_RRW("bus_id = %d, addr = 0x%08x/0x%08x, w_val = 0x%08x, r_back = 0x%08x", + bus_id, host_addr, bus_addr, val, read_back_val); + } else { + /* if (!no_read_back && (full_print && print_vir_addr)) */ + GDL_LOGI_RRW("bus_id = %d, addr = 0x%p/0x%08x/0x%08x, w_val = 0x%08x, r_back = 0x%08x", + bus_id, host_vir_addr, host_addr, bus_addr, val, read_back_val); + } +} + +void gps_dl_bus_write(enum GPS_DL_BUS_ENUM bus_id, unsigned int bus_addr, unsigned int val) +{ + /* gps_dl_bus_wr_opt(bus_id, bus_addr, val, BMASK_RW_DO_CHECK); */ + gps_dl_bus_wr_opt(bus_id, bus_addr, val, 0); +} + +void gps_dl_bus_write_no_rb(enum GPS_DL_BUS_ENUM bus_id, unsigned int bus_addr, unsigned int val) +{ + gps_dl_bus_wr_opt(bus_id, bus_addr, val, BMASK_WR_NO_READ_BACK); +} + +unsigned int gps_dl_bus_rd_opt(enum GPS_DL_BUS_ENUM bus_id, unsigned int bus_addr, + unsigned int opt_bitmask) +{ + bool do_check = !!(opt_bitmask & BMASK_RW_DO_CHECK); + bool force_print = !!(opt_bitmask & BMASK_RW_FORCE_PRINT); + bool full_print = !!(opt_bitmask & BMASK_RW_FULL_PRINT); + bool print_vir_addr = false; + + unsigned int val = 0; + unsigned int host_addr = gps_dl_bus_to_host_addr(bus_id, bus_addr); +#if GPS_DL_ON_LINUX +#if GPS_DL_HAS_PLAT_DRV + void __iomem *host_vir_addr = gps_dl_host_addr_to_virt(host_addr); +#else + void __iomem *host_vir_addr = phys_to_virt(host_addr); +#endif +#else + void *host_vir_addr = NULL; +#endif + + /* + * For linux preparation and checking + */ +#if GPS_DL_ON_LINUX + if (host_vir_addr == NULL) { + GDL_LOGW_RRW("bus_id = %d, addr = 0x%p/0x%08x/0x%08x, NULL!", + bus_id, host_vir_addr, host_addr, bus_addr); + return 0; + } + print_vir_addr = true; + + if (do_check) { + /* gps_dl_conninfra_not_readable_show_warning(host_addr); */ + gps_dl_bus_check_and_print(host_addr); + } +#endif /* GPS_DL_ON_LINUX */ + + /* + * Do reading + */ +#if GPS_DL_HW_IS_MOCK + /* do nothing if it's mock */ +#elif GPS_DL_ON_LINUX + val = __raw_readl(host_vir_addr); +#else + val = GPS_DL_HOST_REG_RD(host_addr); +#endif + if (!(gps_dl_show_reg_rw_log() || force_print)) + return val; + + /* + * Do printing if need + */ + if (!full_print) { + GDL_LOGI_RRW("bus_id = %d, addr = 0x%08x, r_val = 0x%08x", + bus_id, host_addr, val); + } else if (full_print && !print_vir_addr) { + GDL_LOGI_RRW("bus_id = %d, addr = 0x%08x/0x%08x, r_val = 0x%08x", + bus_id, host_addr, bus_addr, val); + } else { + /* if (full_print && print_vir_addr) */ + GDL_LOGI_RRW("bus_id = %d, addr = 0x%p/0x%08x/0x%08x, r_val = 0x%08x", + bus_id, host_vir_addr, host_addr, bus_addr, val); + } + return val; +} + +unsigned int gps_dl_bus_read(enum GPS_DL_BUS_ENUM bus_id, unsigned int bus_addr) +{ + /* return gps_dl_bus_rd_opt(bus_id, bus_addr, BMASK_RW_DO_CHECK); */ + return gps_dl_bus_rd_opt(bus_id, bus_addr, 0); +} + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/conn_infra/conn_host_csr_top.h b/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/conn_infra/conn_host_csr_top.h new file mode 100644 index 0000000000000000000000000000000000000000..3b7edcff8eb8ccd29f30171d5b9921afcc8e5fee --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/conn_infra/conn_host_csr_top.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ +#ifndef __CONN_HOST_CSR_TOP_REGS_H__ +#define __CONN_HOST_CSR_TOP_REGS_H__ + +#define CONN_HOST_CSR_TOP_BASE 0x18060000 + +#define CONN_HOST_CSR_TOP_HOST2GPS_DEGUG_SEL_ADDR (CONN_HOST_CSR_TOP_BASE + 0x00B0) +#define CONN_HOST_CSR_TOP_CONN_INFRA_DEBUG_AO_DEBUGSYS_ADDR (CONN_HOST_CSR_TOP_BASE + 0x0128) +#define CONN_HOST_CSR_TOP_CONN_INFRA_DEBUG_CTRL_AO2SYS_OUT_ADDR (CONN_HOST_CSR_TOP_BASE + 0x0148) +#define CONN_HOST_CSR_TOP_CONN_SLP_PROT_CTRL_ADDR (CONN_HOST_CSR_TOP_BASE + 0x0184) +#define CONN_HOST_CSR_TOP_CONN_INFRA_WAKEPU_GPS_ADDR (CONN_HOST_CSR_TOP_BASE + 0x01AC) +#define CONN_HOST_CSR_TOP_CONN2AP_REMAP_GPS_EMI_BASE_ADDR_ADDR (CONN_HOST_CSR_TOP_BASE + 0x01D0) +#define CONN_HOST_CSR_TOP_GPS_CFG2HOST_DEBUG_ADDR (CONN_HOST_CSR_TOP_BASE + 0x0240) + + +#define CONN_HOST_CSR_TOP_HOST2GPS_DEGUG_SEL_HOST2GPS_DEGUG_SEL_ADDR CONN_HOST_CSR_TOP_HOST2GPS_DEGUG_SEL_ADDR +#define CONN_HOST_CSR_TOP_HOST2GPS_DEGUG_SEL_HOST2GPS_DEGUG_SEL_MASK 0x000000FF +#define CONN_HOST_CSR_TOP_HOST2GPS_DEGUG_SEL_HOST2GPS_DEGUG_SEL_SHFT 0 + +#define CONN_HOST_CSR_TOP_CONN_INFRA_DEBUG_AO_DEBUGSYS_CONN_INFRA_DEBUG_CTRL_AO_DEBUGSYS_CTRL_ADDR \ + CONN_HOST_CSR_TOP_CONN_INFRA_DEBUG_AO_DEBUGSYS_ADDR +#define CONN_HOST_CSR_TOP_CONN_INFRA_DEBUG_AO_DEBUGSYS_CONN_INFRA_DEBUG_CTRL_AO_DEBUGSYS_CTRL_MASK 0xFFFFFFFF +#define CONN_HOST_CSR_TOP_CONN_INFRA_DEBUG_AO_DEBUGSYS_CONN_INFRA_DEBUG_CTRL_AO_DEBUGSYS_CTRL_SHFT 0 + +#define CONN_HOST_CSR_TOP_CONN_INFRA_DEBUG_CTRL_AO2SYS_OUT_CONN_INFRA_DEBUG_CTRL_AO2SYS_OUT_ADDR \ + CONN_HOST_CSR_TOP_CONN_INFRA_DEBUG_CTRL_AO2SYS_OUT_ADDR +#define CONN_HOST_CSR_TOP_CONN_INFRA_DEBUG_CTRL_AO2SYS_OUT_CONN_INFRA_DEBUG_CTRL_AO2SYS_OUT_MASK 0xFFFFFFFF +#define CONN_HOST_CSR_TOP_CONN_INFRA_DEBUG_CTRL_AO2SYS_OUT_CONN_INFRA_DEBUG_CTRL_AO2SYS_OUT_SHFT 0 + +#define CONN_HOST_CSR_TOP_CONN_SLP_PROT_CTRL_CONN_INFRA_ON2OFF_SLP_PROT_ACK_ADDR \ + CONN_HOST_CSR_TOP_CONN_SLP_PROT_CTRL_ADDR +#define CONN_HOST_CSR_TOP_CONN_SLP_PROT_CTRL_CONN_INFRA_ON2OFF_SLP_PROT_ACK_MASK 0x00000020 +#define CONN_HOST_CSR_TOP_CONN_SLP_PROT_CTRL_CONN_INFRA_ON2OFF_SLP_PROT_ACK_SHFT 5 + +#define CONN_HOST_CSR_TOP_CONN_INFRA_WAKEPU_GPS_CONN_INFRA_WAKEPU_GPS_ADDR CONN_HOST_CSR_TOP_CONN_INFRA_WAKEPU_GPS_ADDR +#define CONN_HOST_CSR_TOP_CONN_INFRA_WAKEPU_GPS_CONN_INFRA_WAKEPU_GPS_MASK 0x00000001 +#define CONN_HOST_CSR_TOP_CONN_INFRA_WAKEPU_GPS_CONN_INFRA_WAKEPU_GPS_SHFT 0 + +#define CONN_HOST_CSR_TOP_CONN2AP_REMAP_GPS_EMI_BASE_ADDR_CONN2AP_REMAP_GPS_EMI_BASE_ADDR_ADDR \ + CONN_HOST_CSR_TOP_CONN2AP_REMAP_GPS_EMI_BASE_ADDR_ADDR +#define CONN_HOST_CSR_TOP_CONN2AP_REMAP_GPS_EMI_BASE_ADDR_CONN2AP_REMAP_GPS_EMI_BASE_ADDR_MASK 0x000FFFFF +#define CONN_HOST_CSR_TOP_CONN2AP_REMAP_GPS_EMI_BASE_ADDR_CONN2AP_REMAP_GPS_EMI_BASE_ADDR_SHFT 0 + +#define CONN_HOST_CSR_TOP_GPS_CFG2HOST_DEBUG_GPS_CFG2HOST_DEBUG_ADDR CONN_HOST_CSR_TOP_GPS_CFG2HOST_DEBUG_ADDR +#define CONN_HOST_CSR_TOP_GPS_CFG2HOST_DEBUG_GPS_CFG2HOST_DEBUG_MASK 0x0000FFFF +#define CONN_HOST_CSR_TOP_GPS_CFG2HOST_DEBUG_GPS_CFG2HOST_DEBUG_SHFT 0 + +#endif /* __CONN_HOST_CSR_TOP_REGS_H__ */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/conn_infra/conn_infra_cfg.h b/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/conn_infra/conn_infra_cfg.h new file mode 100644 index 0000000000000000000000000000000000000000..425dbb171f82b0cfdf427cb0b3c6564ccb7b3600 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/conn_infra/conn_infra_cfg.h @@ -0,0 +1,86 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ +#ifndef __CONN_INFRA_CFG_REGS_H__ +#define __CONN_INFRA_CFG_REGS_H__ + +#define CONN_INFRA_CFG_BASE 0x18001000 + +#define CONN_INFRA_CFG_CONN_HW_VER_ADDR (CONN_INFRA_CFG_BASE + 0x0000) +#define CONN_INFRA_CFG_GALS_CONN2GPS_SLP_CTRL_ADDR (CONN_INFRA_CFG_BASE + 0x0618) +#define CONN_INFRA_CFG_GALS_GPS2CONN_SLP_CTRL_ADDR (CONN_INFRA_CFG_BASE + 0x061C) +#define CONN_INFRA_CFG_PLL_STATUS_ADDR (CONN_INFRA_CFG_BASE + 0x0810) +#define CONN_INFRA_CFG_GPS_PWRCTRL0_ADDR (CONN_INFRA_CFG_BASE + 0x0878) +#define CONN_INFRA_CFG_CKGEN_BUS_ADDR (CONN_INFRA_CFG_BASE + 0x0A00) +#define CONN_INFRA_CFG_EMI_CTL_TOP_ADDR (CONN_INFRA_CFG_BASE + 0x0C10) +#define CONN_INFRA_CFG_EMI_CTL_WF_ADDR (CONN_INFRA_CFG_BASE + 0x0C14) +#define CONN_INFRA_CFG_EMI_CTL_BT_ADDR (CONN_INFRA_CFG_BASE + 0x0C18) +#define CONN_INFRA_CFG_EMI_CTL_GPS_ADDR (CONN_INFRA_CFG_BASE + 0x0C1C) + + +#define CONN_INFRA_CFG_CONN_HW_VER_RO_CONN_HW_VERSION_ADDR CONN_INFRA_CFG_CONN_HW_VER_ADDR +#define CONN_INFRA_CFG_CONN_HW_VER_RO_CONN_HW_VERSION_MASK 0xFFFFFFFF +#define CONN_INFRA_CFG_CONN_HW_VER_RO_CONN_HW_VERSION_SHFT 0 + +#define CONN_INFRA_CFG_GALS_CONN2GPS_SLP_CTRL_R_CONN2GPS_SLP_PROT_TX_EN_ADDR CONN_INFRA_CFG_GALS_CONN2GPS_SLP_CTRL_ADDR +#define CONN_INFRA_CFG_GALS_CONN2GPS_SLP_CTRL_R_CONN2GPS_SLP_PROT_TX_EN_MASK 0x00000001 +#define CONN_INFRA_CFG_GALS_CONN2GPS_SLP_CTRL_R_CONN2GPS_SLP_PROT_TX_EN_SHFT 0 +#define CONN_INFRA_CFG_GALS_CONN2GPS_SLP_CTRL_R_CONN2GPS_SLP_PROT_TX_RDY_ADDR \ + CONN_INFRA_CFG_GALS_CONN2GPS_SLP_CTRL_ADDR +#define CONN_INFRA_CFG_GALS_CONN2GPS_SLP_CTRL_R_CONN2GPS_SLP_PROT_TX_RDY_MASK 0x00000008 +#define CONN_INFRA_CFG_GALS_CONN2GPS_SLP_CTRL_R_CONN2GPS_SLP_PROT_TX_RDY_SHFT 3 +#define CONN_INFRA_CFG_GALS_CONN2GPS_SLP_CTRL_R_CONN2GPS_SLP_PROT_RX_EN_ADDR CONN_INFRA_CFG_GALS_CONN2GPS_SLP_CTRL_ADDR +#define CONN_INFRA_CFG_GALS_CONN2GPS_SLP_CTRL_R_CONN2GPS_SLP_PROT_RX_EN_MASK 0x00000010 +#define CONN_INFRA_CFG_GALS_CONN2GPS_SLP_CTRL_R_CONN2GPS_SLP_PROT_RX_EN_SHFT 4 +#define CONN_INFRA_CFG_GALS_CONN2GPS_SLP_CTRL_R_CONN2GPS_SLP_PROT_RX_RDY_ADDR \ + CONN_INFRA_CFG_GALS_CONN2GPS_SLP_CTRL_ADDR +#define CONN_INFRA_CFG_GALS_CONN2GPS_SLP_CTRL_R_CONN2GPS_SLP_PROT_RX_RDY_MASK 0x00000080 +#define CONN_INFRA_CFG_GALS_CONN2GPS_SLP_CTRL_R_CONN2GPS_SLP_PROT_RX_RDY_SHFT 7 + +#define CONN_INFRA_CFG_GALS_GPS2CONN_SLP_CTRL_R_GPS2CONN_SLP_PROT_TX_EN_ADDR CONN_INFRA_CFG_GALS_GPS2CONN_SLP_CTRL_ADDR +#define CONN_INFRA_CFG_GALS_GPS2CONN_SLP_CTRL_R_GPS2CONN_SLP_PROT_TX_EN_MASK 0x00000001 +#define CONN_INFRA_CFG_GALS_GPS2CONN_SLP_CTRL_R_GPS2CONN_SLP_PROT_TX_EN_SHFT 0 +#define CONN_INFRA_CFG_GALS_GPS2CONN_SLP_CTRL_R_GPS2CONN_SLP_PROT_TX_RDY_ADDR \ + CONN_INFRA_CFG_GALS_GPS2CONN_SLP_CTRL_ADDR +#define CONN_INFRA_CFG_GALS_GPS2CONN_SLP_CTRL_R_GPS2CONN_SLP_PROT_TX_RDY_MASK 0x00000008 +#define CONN_INFRA_CFG_GALS_GPS2CONN_SLP_CTRL_R_GPS2CONN_SLP_PROT_TX_RDY_SHFT 3 +#define CONN_INFRA_CFG_GALS_GPS2CONN_SLP_CTRL_R_GPS2CONN_SLP_PROT_RX_EN_ADDR CONN_INFRA_CFG_GALS_GPS2CONN_SLP_CTRL_ADDR +#define CONN_INFRA_CFG_GALS_GPS2CONN_SLP_CTRL_R_GPS2CONN_SLP_PROT_RX_EN_MASK 0x00000010 +#define CONN_INFRA_CFG_GALS_GPS2CONN_SLP_CTRL_R_GPS2CONN_SLP_PROT_RX_EN_SHFT 4 +#define CONN_INFRA_CFG_GALS_GPS2CONN_SLP_CTRL_R_GPS2CONN_SLP_PROT_RX_RDY_ADDR \ + CONN_INFRA_CFG_GALS_GPS2CONN_SLP_CTRL_ADDR +#define CONN_INFRA_CFG_GALS_GPS2CONN_SLP_CTRL_R_GPS2CONN_SLP_PROT_RX_RDY_MASK 0x00000080 +#define CONN_INFRA_CFG_GALS_GPS2CONN_SLP_CTRL_R_GPS2CONN_SLP_PROT_RX_RDY_SHFT 7 + +#define CONN_INFRA_CFG_PLL_STATUS_BPLL_RDY_ADDR CONN_INFRA_CFG_PLL_STATUS_ADDR +#define CONN_INFRA_CFG_PLL_STATUS_BPLL_RDY_MASK 0x00000002 +#define CONN_INFRA_CFG_PLL_STATUS_BPLL_RDY_SHFT 1 + +#define CONN_INFRA_CFG_GPS_PWRCTRL0_GP_FUNCTION_EN_ADDR CONN_INFRA_CFG_GPS_PWRCTRL0_ADDR +#define CONN_INFRA_CFG_GPS_PWRCTRL0_GP_FUNCTION_EN_MASK 0x00000001 +#define CONN_INFRA_CFG_GPS_PWRCTRL0_GP_FUNCTION_EN_SHFT 0 + +#define CONN_INFRA_CFG_CKGEN_BUS_CONN_CO_EXT_UART_PTA_OSC_CKEN_ADDR CONN_INFRA_CFG_CKGEN_BUS_ADDR +#define CONN_INFRA_CFG_CKGEN_BUS_CONN_CO_EXT_UART_PTA_OSC_CKEN_MASK 0x00000020 +#define CONN_INFRA_CFG_CKGEN_BUS_CONN_CO_EXT_UART_PTA_OSC_CKEN_SHFT 5 +#define CONN_INFRA_CFG_CKGEN_BUS_CONN_CO_EXT_UART_PTA_HCLK_CKEN_ADDR CONN_INFRA_CFG_CKGEN_BUS_ADDR +#define CONN_INFRA_CFG_CKGEN_BUS_CONN_CO_EXT_UART_PTA_HCLK_CKEN_MASK 0x00000010 +#define CONN_INFRA_CFG_CKGEN_BUS_CONN_CO_EXT_UART_PTA_HCLK_CKEN_SHFT 4 +#define CONN_INFRA_CFG_CKGEN_BUS_CONN_CO_EXT_UART_PTA5_OSC_CKEN_ADDR CONN_INFRA_CFG_CKGEN_BUS_ADDR +#define CONN_INFRA_CFG_CKGEN_BUS_CONN_CO_EXT_UART_PTA5_OSC_CKEN_MASK 0x00000008 +#define CONN_INFRA_CFG_CKGEN_BUS_CONN_CO_EXT_UART_PTA5_OSC_CKEN_SHFT 3 +#define CONN_INFRA_CFG_CKGEN_BUS_CONN_CO_EXT_UART_PTA5_HCLK_CKEN_ADDR CONN_INFRA_CFG_CKGEN_BUS_ADDR +#define CONN_INFRA_CFG_CKGEN_BUS_CONN_CO_EXT_UART_PTA5_HCLK_CKEN_MASK 0x00000004 +#define CONN_INFRA_CFG_CKGEN_BUS_CONN_CO_EXT_UART_PTA5_HCLK_CKEN_SHFT 2 + +#define CONN_INFRA_CFG_EMI_CTL_TOP_EMI_REQ_TOP_ADDR CONN_INFRA_CFG_EMI_CTL_TOP_ADDR +#define CONN_INFRA_CFG_EMI_CTL_TOP_EMI_REQ_TOP_MASK 0x00000001 +#define CONN_INFRA_CFG_EMI_CTL_TOP_EMI_REQ_TOP_SHFT 0 + +#define CONN_INFRA_CFG_EMI_CTL_GPS_EMI_REQ_GPS_ADDR CONN_INFRA_CFG_EMI_CTL_GPS_ADDR +#define CONN_INFRA_CFG_EMI_CTL_GPS_EMI_REQ_GPS_MASK 0x00000001 +#define CONN_INFRA_CFG_EMI_CTL_GPS_EMI_REQ_GPS_SHFT 0 + +#endif /* __CONN_INFRA_CFG_REGS_H__ */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/conn_infra/conn_infra_rgu.h b/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/conn_infra/conn_infra_rgu.h new file mode 100644 index 0000000000000000000000000000000000000000..598da98008e87fa020757893e2d28223b393eaa7 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/conn_infra/conn_infra_rgu.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ +#ifndef __CONN_INFRA_RGU_REGS_H__ +#define __CONN_INFRA_RGU_REGS_H__ + +#define CONN_INFRA_RGU_BASE 0x18000000 + +#define CONN_INFRA_RGU_BGFYS_ON_TOP_PWR_CTL_ADDR (CONN_INFRA_RGU_BASE + 0x0008) +#define CONN_INFRA_RGU_BGFSYS_ON_TOP_PWR_ACK_ST_ADDR (CONN_INFRA_RGU_BASE + 0x0114) + + +#define CONN_INFRA_RGU_BGFYS_ON_TOP_PWR_CTL_BGFSYS_ON_TOP_PWR_ON_ADDR CONN_INFRA_RGU_BGFYS_ON_TOP_PWR_CTL_ADDR +#define CONN_INFRA_RGU_BGFYS_ON_TOP_PWR_CTL_BGFSYS_ON_TOP_PWR_ON_MASK 0x00000080 +#define CONN_INFRA_RGU_BGFYS_ON_TOP_PWR_CTL_BGFSYS_ON_TOP_PWR_ON_SHFT 7 + +#define CONN_INFRA_RGU_BGFSYS_ON_TOP_PWR_ACK_ST_AN_BGFSYS_ON_TOP_PWR_ACK_S_ADDR \ + CONN_INFRA_RGU_BGFSYS_ON_TOP_PWR_ACK_ST_ADDR +#define CONN_INFRA_RGU_BGFSYS_ON_TOP_PWR_ACK_ST_AN_BGFSYS_ON_TOP_PWR_ACK_S_MASK 0x02000000 +#define CONN_INFRA_RGU_BGFSYS_ON_TOP_PWR_ACK_ST_AN_BGFSYS_ON_TOP_PWR_ACK_S_SHFT 25 +#define CONN_INFRA_RGU_BGFSYS_ON_TOP_PWR_ACK_ST_BGFSYS_ON_TOP_PWR_ACK_ADDR CONN_INFRA_RGU_BGFSYS_ON_TOP_PWR_ACK_ST_ADDR +#define CONN_INFRA_RGU_BGFSYS_ON_TOP_PWR_ACK_ST_BGFSYS_ON_TOP_PWR_ACK_MASK 0x01000000 +#define CONN_INFRA_RGU_BGFSYS_ON_TOP_PWR_ACK_ST_BGFSYS_ON_TOP_PWR_ACK_SHFT 24 + +#endif /* __CONN_INFRA_RGU_REGS_H__ */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/conn_infra/conn_pta6.h b/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/conn_infra/conn_pta6.h new file mode 100644 index 0000000000000000000000000000000000000000..9ebb76589c25318262df377d46fc59176840249c --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/conn_infra/conn_pta6.h @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ +#ifndef __CONN_PTA6_REGS_H__ +#define __CONN_PTA6_REGS_H__ + +#define CONN_PTA6_BASE 0x1800C000 + +#define CONN_PTA6_WFSET_PTA_CTRL_ADDR (CONN_PTA6_BASE + 0x0000) +#define CONN_PTA6_PTA_CLK_CFG_ADDR (CONN_PTA6_BASE + 0x0004) +#define CONN_PTA6_BTSET_PTA_CTRL_ADDR (CONN_PTA6_BASE + 0x0008) +#define CONN_PTA6_RO_PTA_CTRL_ADDR (CONN_PTA6_BASE + 0x000C) +#define CONN_PTA6_GPS_BLANK_CFG_ADDR (CONN_PTA6_BASE + 0x0240) +#define CONN_PTA6_TMR_CTRL_1_ADDR (CONN_PTA6_BASE + 0x02C4) +#define CONN_PTA6_TMR_CTRL_3_ADDR (CONN_PTA6_BASE + 0x02CC) + + +#define CONN_PTA6_WFSET_PTA_CTRL_r_wfset_uart_apb_hw_en_ADDR CONN_PTA6_WFSET_PTA_CTRL_ADDR +#define CONN_PTA6_WFSET_PTA_CTRL_r_wfset_uart_apb_hw_en_MASK 0x00010000 +#define CONN_PTA6_WFSET_PTA_CTRL_r_wfset_uart_apb_hw_en_SHFT 16 +#define CONN_PTA6_WFSET_PTA_CTRL_r_wfset_lte_pta_en_ADDR CONN_PTA6_WFSET_PTA_CTRL_ADDR +#define CONN_PTA6_WFSET_PTA_CTRL_r_wfset_lte_pta_en_MASK 0x000000FC +#define CONN_PTA6_WFSET_PTA_CTRL_r_wfset_lte_pta_en_SHFT 2 +#define CONN_PTA6_WFSET_PTA_CTRL_r_wfset_en_pta_arb_ADDR CONN_PTA6_WFSET_PTA_CTRL_ADDR +#define CONN_PTA6_WFSET_PTA_CTRL_r_wfset_en_pta_arb_MASK 0x00000002 +#define CONN_PTA6_WFSET_PTA_CTRL_r_wfset_en_pta_arb_SHFT 1 +#define CONN_PTA6_WFSET_PTA_CTRL_r_wfset_pta_en_ADDR CONN_PTA6_WFSET_PTA_CTRL_ADDR +#define CONN_PTA6_WFSET_PTA_CTRL_r_wfset_pta_en_MASK 0x00000001 +#define CONN_PTA6_WFSET_PTA_CTRL_r_wfset_pta_en_SHFT 0 + +#define CONN_PTA6_PTA_CLK_CFG_r_pta_1m_cnt_ADDR CONN_PTA6_PTA_CLK_CFG_ADDR +#define CONN_PTA6_PTA_CLK_CFG_r_pta_1m_cnt_MASK 0x000000FF +#define CONN_PTA6_PTA_CLK_CFG_r_pta_1m_cnt_SHFT 0 + +#define CONN_PTA6_BTSET_PTA_CTRL_r_btset_uart_apb_hw_en_ADDR CONN_PTA6_BTSET_PTA_CTRL_ADDR +#define CONN_PTA6_BTSET_PTA_CTRL_r_btset_uart_apb_hw_en_MASK 0x00010000 +#define CONN_PTA6_BTSET_PTA_CTRL_r_btset_uart_apb_hw_en_SHFT 16 + +#define CONN_PTA6_RO_PTA_CTRL_ro_uart_apb_hw_en_ADDR CONN_PTA6_RO_PTA_CTRL_ADDR +#define CONN_PTA6_RO_PTA_CTRL_ro_uart_apb_hw_en_MASK 0x00010000 +#define CONN_PTA6_RO_PTA_CTRL_ro_uart_apb_hw_en_SHFT 16 +#define CONN_PTA6_RO_PTA_CTRL_ro_en_pta_arb_ADDR CONN_PTA6_RO_PTA_CTRL_ADDR +#define CONN_PTA6_RO_PTA_CTRL_ro_en_pta_arb_MASK 0x00000002 +#define CONN_PTA6_RO_PTA_CTRL_ro_en_pta_arb_SHFT 1 +#define CONN_PTA6_RO_PTA_CTRL_ro_pta_en_ADDR CONN_PTA6_RO_PTA_CTRL_ADDR +#define CONN_PTA6_RO_PTA_CTRL_ro_pta_en_MASK 0x00000001 +#define CONN_PTA6_RO_PTA_CTRL_ro_pta_en_SHFT 0 + +#define CONN_PTA6_GPS_BLANK_CFG_r_idc_gps_l5_blank_src_ADDR CONN_PTA6_GPS_BLANK_CFG_ADDR +#define CONN_PTA6_GPS_BLANK_CFG_r_idc_gps_l5_blank_src_MASK 0x00000018 +#define CONN_PTA6_GPS_BLANK_CFG_r_idc_gps_l5_blank_src_SHFT 3 +#define CONN_PTA6_GPS_BLANK_CFG_r_idc_gps_l1_blank_src_ADDR CONN_PTA6_GPS_BLANK_CFG_ADDR +#define CONN_PTA6_GPS_BLANK_CFG_r_idc_gps_l1_blank_src_MASK 0x00000006 +#define CONN_PTA6_GPS_BLANK_CFG_r_idc_gps_l1_blank_src_SHFT 1 +#define CONN_PTA6_GPS_BLANK_CFG_r_gps_blank_src_ADDR CONN_PTA6_GPS_BLANK_CFG_ADDR +#define CONN_PTA6_GPS_BLANK_CFG_r_gps_blank_src_MASK 0x00000001 +#define CONN_PTA6_GPS_BLANK_CFG_r_gps_blank_src_SHFT 0 + +#define CONN_PTA6_TMR_CTRL_1_r_idc_2nd_byte_tmout_ADDR CONN_PTA6_TMR_CTRL_1_ADDR +#define CONN_PTA6_TMR_CTRL_1_r_idc_2nd_byte_tmout_MASK 0xFF000000 +#define CONN_PTA6_TMR_CTRL_1_r_idc_2nd_byte_tmout_SHFT 24 + +#define CONN_PTA6_TMR_CTRL_3_r_gps_l5_blank_tmr_thld_ADDR CONN_PTA6_TMR_CTRL_3_ADDR +#define CONN_PTA6_TMR_CTRL_3_r_gps_l5_blank_tmr_thld_MASK 0x0000FF00 +#define CONN_PTA6_TMR_CTRL_3_r_gps_l5_blank_tmr_thld_SHFT 8 +#define CONN_PTA6_TMR_CTRL_3_r_gps_l1_blank_tmr_thld_ADDR CONN_PTA6_TMR_CTRL_3_ADDR +#define CONN_PTA6_TMR_CTRL_3_r_gps_l1_blank_tmr_thld_MASK 0x000000FF +#define CONN_PTA6_TMR_CTRL_3_r_gps_l1_blank_tmr_thld_SHFT 0 + +#endif /* __CONN_PTA6_REGS_H__ */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/conn_infra/conn_rf_spi_mst_reg.h b/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/conn_infra/conn_rf_spi_mst_reg.h new file mode 100644 index 0000000000000000000000000000000000000000..849e60a92358993ce9b117259e3c48263b3080b9 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/conn_infra/conn_rf_spi_mst_reg.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ +#ifndef __CONN_RF_SPI_MST_REG_REGS_H__ +#define __CONN_RF_SPI_MST_REG_REGS_H__ + +#define CONN_RF_SPI_MST_REG_BASE 0x18004000 + +#define CONN_RF_SPI_MST_ADDR_SPI_STA_ADDR (CONN_RF_SPI_MST_REG_BASE + 0x0000) +#define CONN_RF_SPI_MST_ADDR_FM_CTRL_ADDR (CONN_RF_SPI_MST_REG_BASE + 0x000C) +#define CONN_RF_SPI_MST_ADDR_SPI_FM_ADDR_ADDR (CONN_RF_SPI_MST_REG_BASE + 0x0030) +#define CONN_RF_SPI_MST_ADDR_SPI_FM_WDAT_ADDR (CONN_RF_SPI_MST_REG_BASE + 0x0034) +#define CONN_RF_SPI_MST_ADDR_SPI_FM_RDAT_ADDR (CONN_RF_SPI_MST_REG_BASE + 0x0038) +#define CONN_RF_SPI_MST_ADDR_SPI_GPS_GPS_ADDR_ADDR (CONN_RF_SPI_MST_REG_BASE + 0x0210) +#define CONN_RF_SPI_MST_ADDR_SPI_GPS_GPS_WDAT_ADDR (CONN_RF_SPI_MST_REG_BASE + 0x0214) +#define CONN_RF_SPI_MST_ADDR_SPI_GPS_GPS_RDAT_ADDR (CONN_RF_SPI_MST_REG_BASE + 0x0218) + + +#define CONN_RF_SPI_MST_REG_SPI_STA_FM_BUSY_ADDR CONN_RF_SPI_MST_ADDR_SPI_STA_ADDR +#define CONN_RF_SPI_MST_REG_SPI_STA_FM_BUSY_MASK 0x00000008 +#define CONN_RF_SPI_MST_REG_SPI_STA_FM_BUSY_SHFT 3 + +#define CONN_RF_SPI_MST_REG_FM_CTRL_FM_RD_EXT_EN_ADDR CONN_RF_SPI_MST_ADDR_FM_CTRL_ADDR +#define CONN_RF_SPI_MST_REG_FM_CTRL_FM_RD_EXT_EN_MASK 0x00008000 +#define CONN_RF_SPI_MST_REG_FM_CTRL_FM_RD_EXT_EN_SHFT 15 +#define CONN_RF_SPI_MST_REG_FM_CTRL_FM_RD_EXT_CNT_ADDR CONN_RF_SPI_MST_ADDR_FM_CTRL_ADDR +#define CONN_RF_SPI_MST_REG_FM_CTRL_FM_RD_EXT_CNT_MASK 0x000000FF +#define CONN_RF_SPI_MST_REG_FM_CTRL_FM_RD_EXT_CNT_SHFT 0 + +#endif /* __CONN_RF_SPI_MST_REG_REGS_H__ */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/conn_infra/conn_semaphore.h b/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/conn_infra/conn_semaphore.h new file mode 100644 index 0000000000000000000000000000000000000000..7b807463e18a1f24b2207def780fe8734e14003b --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/conn_infra/conn_semaphore.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ +#ifndef __CONN_SEMAPHORE_REGS_H__ +#define __CONN_SEMAPHORE_REGS_H__ + +#define CONN_SEMAPHORE_BASE 0x18070000 + +#define CONN_SEMAPHORE_CONN_SEMA05_M3_OWN_STA_ADDR (CONN_SEMAPHORE_BASE + 0x3014) +#define CONN_SEMAPHORE_CONN_SEMA11_M3_OWN_STA_ADDR (CONN_SEMAPHORE_BASE + 0x302C) +#define CONN_SEMAPHORE_CONN_SEMA05_M3_OWN_REL_ADDR (CONN_SEMAPHORE_BASE + 0x3214) +#define CONN_SEMAPHORE_CONN_SEMA11_M3_OWN_REL_ADDR (CONN_SEMAPHORE_BASE + 0x322C) + + +#define CONN_SEMAPHORE_CONN_SEMA05_M3_OWN_STA_CONN_SEMA05_M3_OWN_STA_ADDR CONN_SEMAPHORE_CONN_SEMA05_M3_OWN_STA_ADDR +#define CONN_SEMAPHORE_CONN_SEMA05_M3_OWN_STA_CONN_SEMA05_M3_OWN_STA_MASK 0x00000003 +#define CONN_SEMAPHORE_CONN_SEMA05_M3_OWN_STA_CONN_SEMA05_M3_OWN_STA_SHFT 0 + +#define CONN_SEMAPHORE_CONN_SEMA11_M3_OWN_STA_CONN_SEMA11_M3_OWN_STA_ADDR CONN_SEMAPHORE_CONN_SEMA11_M3_OWN_STA_ADDR +#define CONN_SEMAPHORE_CONN_SEMA11_M3_OWN_STA_CONN_SEMA11_M3_OWN_STA_MASK 0x00000003 +#define CONN_SEMAPHORE_CONN_SEMA11_M3_OWN_STA_CONN_SEMA11_M3_OWN_STA_SHFT 0 + +#define CONN_SEMAPHORE_CONN_SEMA05_M3_OWN_REL_CONN_SEMA05_M3_OWN_REL_ADDR CONN_SEMAPHORE_CONN_SEMA05_M3_OWN_REL_ADDR +#define CONN_SEMAPHORE_CONN_SEMA05_M3_OWN_REL_CONN_SEMA05_M3_OWN_REL_MASK 0x00000001 +#define CONN_SEMAPHORE_CONN_SEMA05_M3_OWN_REL_CONN_SEMA05_M3_OWN_REL_SHFT 0 + +#define CONN_SEMAPHORE_CONN_SEMA11_M3_OWN_REL_CONN_SEMA11_M3_OWN_REL_ADDR CONN_SEMAPHORE_CONN_SEMA11_M3_OWN_REL_ADDR +#define CONN_SEMAPHORE_CONN_SEMA11_M3_OWN_REL_CONN_SEMA11_M3_OWN_REL_MASK 0x00000001 +#define CONN_SEMAPHORE_CONN_SEMA11_M3_OWN_REL_CONN_SEMA11_M3_OWN_REL_SHFT 0 + +#endif /* __CONN_SEMAPHORE_REGS_H__ */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/conn_infra/conn_uart_pta.h b/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/conn_infra/conn_uart_pta.h new file mode 100644 index 0000000000000000000000000000000000000000..518fca56e74f7e07e965e0a212dbf75953426a8d --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/conn_infra/conn_uart_pta.h @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ +#ifndef __CONN_UART_PTA_REGS_H__ +#define __CONN_UART_PTA_REGS_H__ + +#define CONN_UART_PTA_BASE 0x1800D000 + +#define CONN_UART_PTA_FCR_ADDR (CONN_UART_PTA_BASE + 0x0008) +#define CONN_UART_PTA_LCR_ADDR (CONN_UART_PTA_BASE + 0x000C) +#define CONN_UART_PTA_DLL_ADDR (CONN_UART_PTA_BASE + 0x0000) +#define CONN_UART_PTA_DLM_ADDR (CONN_UART_PTA_BASE + 0x0004) +#define CONN_UART_PTA_HIGHSPEED_ADDR (CONN_UART_PTA_BASE + 0x0024) +#define CONN_UART_PTA_SAMPLE_COUNT_ADDR (CONN_UART_PTA_BASE + 0x0028) +#define CONN_UART_PTA_SAMPLE_POINT_ADDR (CONN_UART_PTA_BASE + 0x002C) +#define CONN_UART_PTA_GUARD_ADDR (CONN_UART_PTA_BASE + 0x003C) +#define CONN_UART_PTA_VFIFO_EN_ADDR (CONN_UART_PTA_BASE + 0x004C) +#define CONN_UART_PTA_FRACDIV_L_ADDR (CONN_UART_PTA_BASE + 0x0054) +#define CONN_UART_PTA_FRACDIV_M_ADDR (CONN_UART_PTA_BASE + 0x0058) + + +#define CONN_UART_PTA_FCR_RFTL_ADDR CONN_UART_PTA_FCR_ADDR +#define CONN_UART_PTA_FCR_RFTL_MASK 0x000000C0 +#define CONN_UART_PTA_FCR_RFTL_SHFT 6 + +#define CONN_UART_PTA_HIGHSPEED_SPEED_ADDR CONN_UART_PTA_HIGHSPEED_ADDR +#define CONN_UART_PTA_HIGHSPEED_SPEED_MASK 0x00000003 +#define CONN_UART_PTA_HIGHSPEED_SPEED_SHFT 0 + +#define CONN_UART_PTA_SAMPLE_COUNT_SAMPLE_COUNT_ADDR CONN_UART_PTA_SAMPLE_COUNT_ADDR +#define CONN_UART_PTA_SAMPLE_COUNT_SAMPLE_COUNT_MASK 0x000000FF +#define CONN_UART_PTA_SAMPLE_COUNT_SAMPLE_COUNT_SHFT 0 + +#define CONN_UART_PTA_SAMPLE_POINT_SAMPLE_POINT_ADDR CONN_UART_PTA_SAMPLE_POINT_ADDR +#define CONN_UART_PTA_SAMPLE_POINT_SAMPLE_POINT_MASK 0x000000FF +#define CONN_UART_PTA_SAMPLE_POINT_SAMPLE_POINT_SHFT 0 + +#define CONN_UART_PTA_GUARD_GUARD_EN_ADDR CONN_UART_PTA_GUARD_ADDR +#define CONN_UART_PTA_GUARD_GUARD_EN_MASK 0x00000010 +#define CONN_UART_PTA_GUARD_GUARD_EN_SHFT 4 +#define CONN_UART_PTA_GUARD_GUARD_CNT_ADDR CONN_UART_PTA_GUARD_ADDR +#define CONN_UART_PTA_GUARD_GUARD_CNT_MASK 0x0000000F +#define CONN_UART_PTA_GUARD_GUARD_CNT_SHFT 0 + +#define CONN_UART_PTA_VFIFO_EN_RX_TIME_EN_ADDR CONN_UART_PTA_VFIFO_EN_ADDR +#define CONN_UART_PTA_VFIFO_EN_RX_TIME_EN_MASK 0x00000080 +#define CONN_UART_PTA_VFIFO_EN_RX_TIME_EN_SHFT 7 +#define CONN_UART_PTA_VFIFO_EN_PTA_RX_FE_EN_ADDR CONN_UART_PTA_VFIFO_EN_ADDR +#define CONN_UART_PTA_VFIFO_EN_PTA_RX_FE_EN_MASK 0x00000008 +#define CONN_UART_PTA_VFIFO_EN_PTA_RX_FE_EN_SHFT 3 +#define CONN_UART_PTA_VFIFO_EN_PTA_RX_MODE_ADDR CONN_UART_PTA_VFIFO_EN_ADDR +#define CONN_UART_PTA_VFIFO_EN_PTA_RX_MODE_MASK 0x00000004 +#define CONN_UART_PTA_VFIFO_EN_PTA_RX_MODE_SHFT 2 + +#define CONN_UART_PTA_FRACDIV_L_FRACDIV_L_ADDR CONN_UART_PTA_FRACDIV_L_ADDR +#define CONN_UART_PTA_FRACDIV_L_FRACDIV_L_MASK 0x000000FF +#define CONN_UART_PTA_FRACDIV_L_FRACDIV_L_SHFT 0 + +#define CONN_UART_PTA_FRACDIV_M_FRACDIV_M_ADDR CONN_UART_PTA_FRACDIV_M_ADDR +#define CONN_UART_PTA_FRACDIV_M_FRACDIV_M_MASK 0x00000003 +#define CONN_UART_PTA_FRACDIV_M_FRACDIV_M_SHFT 0 + +#endif /* __CONN_UART_PTA_REGS_H__ */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/gps/bgf_gps_cfg.h b/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/gps/bgf_gps_cfg.h new file mode 100644 index 0000000000000000000000000000000000000000..3106378892b53a885c40fe026d7c39bfc37b4268 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/gps/bgf_gps_cfg.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ +#ifndef __BGF_GPS_CFG_REGS_H__ +#define __BGF_GPS_CFG_REGS_H__ + +#define BGF_GPS_CFG_BASE 0x80021000 + +#define BGF_GPS_CFG_BGF_IP_VERSION_ADDR (BGF_GPS_CFG_BASE + 0x0010) +#define BGF_GPS_CFG_BGF_IP_CONFIG_ADDR (BGF_GPS_CFG_BASE + 0x0014) + + +#define BGF_GPS_CFG_BGF_IP_VERSION_BGFSYS_VERSION_ADDR BGF_GPS_CFG_BGF_IP_VERSION_ADDR +#define BGF_GPS_CFG_BGF_IP_VERSION_BGFSYS_VERSION_MASK 0xFFFFFFFF +#define BGF_GPS_CFG_BGF_IP_VERSION_BGFSYS_VERSION_SHFT 0 + +#define BGF_GPS_CFG_BGF_IP_CONFIG_BGFSYS_CONFIG_ADDR BGF_GPS_CFG_BGF_IP_CONFIG_ADDR +#define BGF_GPS_CFG_BGF_IP_CONFIG_BGFSYS_CONFIG_MASK 0x000000FF +#define BGF_GPS_CFG_BGF_IP_CONFIG_BGFSYS_CONFIG_SHFT 0 + +#endif /* __BGF_GPS_CFG_REGS_H__ */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/gps/bgf_gps_dma.h b/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/gps/bgf_gps_dma.h new file mode 100644 index 0000000000000000000000000000000000000000..681be8114d979ff8a5d44778a8e3061a6f500fc8 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/gps/bgf_gps_dma.h @@ -0,0 +1,195 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ +#ifndef __BGF_GPS_DMA_REGS_H__ +#define __BGF_GPS_DMA_REGS_H__ + +#define BGF_GPS_DMA_BASE 0x80010000 + +#define BGF_GPS_DMA_DMA1_WPPT_ADDR (BGF_GPS_DMA_BASE + 0x0108) +#define BGF_GPS_DMA_DMA1_WPTO_ADDR (BGF_GPS_DMA_BASE + 0x010C) +#define BGF_GPS_DMA_DMA1_COUNT_ADDR (BGF_GPS_DMA_BASE + 0x0110) +#define BGF_GPS_DMA_DMA1_CON_ADDR (BGF_GPS_DMA_BASE + 0x0114) +#define BGF_GPS_DMA_DMA1_START_ADDR (BGF_GPS_DMA_BASE + 0x0118) +#define BGF_GPS_DMA_DMA1_INTSTA_ADDR (BGF_GPS_DMA_BASE + 0x011C) +#define BGF_GPS_DMA_DMA1_ACKINT_ADDR (BGF_GPS_DMA_BASE + 0x0120) +#define BGF_GPS_DMA_DMA1_RLCT_ADDR (BGF_GPS_DMA_BASE + 0x0124) +#define BGF_GPS_DMA_DMA1_PGMADDR_ADDR (BGF_GPS_DMA_BASE + 0x012C) +#define BGF_GPS_DMA_DMA1_STATE_ADDR (BGF_GPS_DMA_BASE + 0x0148) +#define BGF_GPS_DMA_DMA2_WPPT_ADDR (BGF_GPS_DMA_BASE + 0x0208) +#define BGF_GPS_DMA_DMA2_WPTO_ADDR (BGF_GPS_DMA_BASE + 0x020C) +#define BGF_GPS_DMA_DMA2_COUNT_ADDR (BGF_GPS_DMA_BASE + 0x0210) +#define BGF_GPS_DMA_DMA2_CON_ADDR (BGF_GPS_DMA_BASE + 0x0214) +#define BGF_GPS_DMA_DMA2_START_ADDR (BGF_GPS_DMA_BASE + 0x0218) +#define BGF_GPS_DMA_DMA2_INTSTA_ADDR (BGF_GPS_DMA_BASE + 0x021C) +#define BGF_GPS_DMA_DMA2_ACKINT_ADDR (BGF_GPS_DMA_BASE + 0x0220) +#define BGF_GPS_DMA_DMA2_RLCT_ADDR (BGF_GPS_DMA_BASE + 0x0224) +#define BGF_GPS_DMA_DMA2_PGMADDR_ADDR (BGF_GPS_DMA_BASE + 0x022C) +#define BGF_GPS_DMA_DMA3_WPPT_ADDR (BGF_GPS_DMA_BASE + 0x0308) +#define BGF_GPS_DMA_DMA3_WPTO_ADDR (BGF_GPS_DMA_BASE + 0x030C) +#define BGF_GPS_DMA_DMA3_COUNT_ADDR (BGF_GPS_DMA_BASE + 0x0310) +#define BGF_GPS_DMA_DMA3_CON_ADDR (BGF_GPS_DMA_BASE + 0x0314) +#define BGF_GPS_DMA_DMA3_START_ADDR (BGF_GPS_DMA_BASE + 0x0318) +#define BGF_GPS_DMA_DMA3_INTSTA_ADDR (BGF_GPS_DMA_BASE + 0x031C) +#define BGF_GPS_DMA_DMA3_ACKINT_ADDR (BGF_GPS_DMA_BASE + 0x0320) +#define BGF_GPS_DMA_DMA3_RLCT_ADDR (BGF_GPS_DMA_BASE + 0x0324) +#define BGF_GPS_DMA_DMA3_PGMADDR_ADDR (BGF_GPS_DMA_BASE + 0x032C) +#define BGF_GPS_DMA_DMA4_WPPT_ADDR (BGF_GPS_DMA_BASE + 0x0408) +#define BGF_GPS_DMA_DMA4_WPTO_ADDR (BGF_GPS_DMA_BASE + 0x040C) +#define BGF_GPS_DMA_DMA4_COUNT_ADDR (BGF_GPS_DMA_BASE + 0x0410) +#define BGF_GPS_DMA_DMA4_CON_ADDR (BGF_GPS_DMA_BASE + 0x0414) +#define BGF_GPS_DMA_DMA4_START_ADDR (BGF_GPS_DMA_BASE + 0x0418) +#define BGF_GPS_DMA_DMA4_INTSTA_ADDR (BGF_GPS_DMA_BASE + 0x041C) +#define BGF_GPS_DMA_DMA4_ACKINT_ADDR (BGF_GPS_DMA_BASE + 0x0420) +#define BGF_GPS_DMA_DMA4_RLCT_ADDR (BGF_GPS_DMA_BASE + 0x0424) +#define BGF_GPS_DMA_DMA4_PGMADDR_ADDR (BGF_GPS_DMA_BASE + 0x042C) + + +#define BGF_GPS_DMA_DMA1_WPPT_WPPT_ADDR BGF_GPS_DMA_DMA1_WPPT_ADDR +#define BGF_GPS_DMA_DMA1_WPPT_WPPT_MASK 0x0000FFFF +#define BGF_GPS_DMA_DMA1_WPPT_WPPT_SHFT 0 + +#define BGF_GPS_DMA_DMA1_WPTO_WPTO_ADDR BGF_GPS_DMA_DMA1_WPTO_ADDR +#define BGF_GPS_DMA_DMA1_WPTO_WPTO_MASK 0xFFFFFFFF +#define BGF_GPS_DMA_DMA1_WPTO_WPTO_SHFT 0 + +#define BGF_GPS_DMA_DMA1_COUNT_LEN_ADDR BGF_GPS_DMA_DMA1_COUNT_ADDR +#define BGF_GPS_DMA_DMA1_COUNT_LEN_MASK 0x0000FFFF +#define BGF_GPS_DMA_DMA1_COUNT_LEN_SHFT 0 + +#define BGF_GPS_DMA_DMA1_CON_MAS_ADDR BGF_GPS_DMA_DMA1_CON_ADDR +#define BGF_GPS_DMA_DMA1_CON_MAS_MASK 0x00300000 +#define BGF_GPS_DMA_DMA1_CON_MAS_SHFT 20 +#define BGF_GPS_DMA_DMA1_CON_W2B_ADDR BGF_GPS_DMA_DMA1_CON_ADDR +#define BGF_GPS_DMA_DMA1_CON_W2B_MASK 0x00000040 +#define BGF_GPS_DMA_DMA1_CON_W2B_SHFT 6 +#define BGF_GPS_DMA_DMA1_CON_B2W_ADDR BGF_GPS_DMA_DMA1_CON_ADDR +#define BGF_GPS_DMA_DMA1_CON_B2W_MASK 0x00000020 +#define BGF_GPS_DMA_DMA1_CON_B2W_SHFT 5 +#define BGF_GPS_DMA_DMA1_CON_SIZE_ADDR BGF_GPS_DMA_DMA1_CON_ADDR +#define BGF_GPS_DMA_DMA1_CON_SIZE_MASK 0x00000003 +#define BGF_GPS_DMA_DMA1_CON_SIZE_SHFT 0 + +#define BGF_GPS_DMA_DMA1_START_STR_ADDR BGF_GPS_DMA_DMA1_START_ADDR +#define BGF_GPS_DMA_DMA1_START_STR_MASK 0x00008000 +#define BGF_GPS_DMA_DMA1_START_STR_SHFT 15 + +#define BGF_GPS_DMA_DMA1_INTSTA_INT_ADDR BGF_GPS_DMA_DMA1_INTSTA_ADDR +#define BGF_GPS_DMA_DMA1_INTSTA_INT_MASK 0x00008000 +#define BGF_GPS_DMA_DMA1_INTSTA_INT_SHFT 15 + +#define BGF_GPS_DMA_DMA1_ACKINT_ACK_ADDR BGF_GPS_DMA_DMA1_ACKINT_ADDR +#define BGF_GPS_DMA_DMA1_ACKINT_ACK_MASK 0x00008000 +#define BGF_GPS_DMA_DMA1_ACKINT_ACK_SHFT 15 + +#define BGF_GPS_DMA_DMA1_RLCT_RLCT_ADDR BGF_GPS_DMA_DMA1_RLCT_ADDR +#define BGF_GPS_DMA_DMA1_RLCT_RLCT_MASK 0x0000FFFF +#define BGF_GPS_DMA_DMA1_RLCT_RLCT_SHFT 0 + +#define BGF_GPS_DMA_DMA1_PGMADDR_PGMADDR_ADDR BGF_GPS_DMA_DMA1_PGMADDR_ADDR +#define BGF_GPS_DMA_DMA1_PGMADDR_PGMADDR_MASK 0xFFFFFFFF +#define BGF_GPS_DMA_DMA1_PGMADDR_PGMADDR_SHFT 0 + +#define BGF_GPS_DMA_DMA1_STATE_STATE_ADDR BGF_GPS_DMA_DMA1_STATE_ADDR +#define BGF_GPS_DMA_DMA1_STATE_STATE_MASK 0x0000007F +#define BGF_GPS_DMA_DMA1_STATE_STATE_SHFT 0 + +#define BGF_GPS_DMA_DMA2_WPPT_WPPT_ADDR BGF_GPS_DMA_DMA2_WPPT_ADDR +#define BGF_GPS_DMA_DMA2_WPPT_WPPT_MASK 0x0000FFFF +#define BGF_GPS_DMA_DMA2_WPPT_WPPT_SHFT 0 + +#define BGF_GPS_DMA_DMA2_WPTO_WPTO_ADDR BGF_GPS_DMA_DMA2_WPTO_ADDR +#define BGF_GPS_DMA_DMA2_WPTO_WPTO_MASK 0xFFFFFFFF +#define BGF_GPS_DMA_DMA2_WPTO_WPTO_SHFT 0 + +#define BGF_GPS_DMA_DMA2_COUNT_LEN_ADDR BGF_GPS_DMA_DMA2_COUNT_ADDR +#define BGF_GPS_DMA_DMA2_COUNT_LEN_MASK 0x0000FFFF +#define BGF_GPS_DMA_DMA2_COUNT_LEN_SHFT 0 + +#define BGF_GPS_DMA_DMA2_START_STR_ADDR BGF_GPS_DMA_DMA2_START_ADDR +#define BGF_GPS_DMA_DMA2_START_STR_MASK 0x00008000 +#define BGF_GPS_DMA_DMA2_START_STR_SHFT 15 + +#define BGF_GPS_DMA_DMA2_INTSTA_INT_ADDR BGF_GPS_DMA_DMA2_INTSTA_ADDR +#define BGF_GPS_DMA_DMA2_INTSTA_INT_MASK 0x00008000 +#define BGF_GPS_DMA_DMA2_INTSTA_INT_SHFT 15 + +#define BGF_GPS_DMA_DMA2_ACKINT_ACK_ADDR BGF_GPS_DMA_DMA2_ACKINT_ADDR +#define BGF_GPS_DMA_DMA2_ACKINT_ACK_MASK 0x00008000 +#define BGF_GPS_DMA_DMA2_ACKINT_ACK_SHFT 15 + +#define BGF_GPS_DMA_DMA2_RLCT_RLCT_ADDR BGF_GPS_DMA_DMA2_RLCT_ADDR +#define BGF_GPS_DMA_DMA2_RLCT_RLCT_MASK 0x0000FFFF +#define BGF_GPS_DMA_DMA2_RLCT_RLCT_SHFT 0 + +#define BGF_GPS_DMA_DMA2_PGMADDR_PGMADDR_ADDR BGF_GPS_DMA_DMA2_PGMADDR_ADDR +#define BGF_GPS_DMA_DMA2_PGMADDR_PGMADDR_MASK 0xFFFFFFFF +#define BGF_GPS_DMA_DMA2_PGMADDR_PGMADDR_SHFT 0 + +#define BGF_GPS_DMA_DMA3_WPPT_WPPT_ADDR BGF_GPS_DMA_DMA3_WPPT_ADDR +#define BGF_GPS_DMA_DMA3_WPPT_WPPT_MASK 0x0000FFFF +#define BGF_GPS_DMA_DMA3_WPPT_WPPT_SHFT 0 + +#define BGF_GPS_DMA_DMA3_WPTO_WPTO_ADDR BGF_GPS_DMA_DMA3_WPTO_ADDR +#define BGF_GPS_DMA_DMA3_WPTO_WPTO_MASK 0xFFFFFFFF +#define BGF_GPS_DMA_DMA3_WPTO_WPTO_SHFT 0 + +#define BGF_GPS_DMA_DMA3_COUNT_LEN_ADDR BGF_GPS_DMA_DMA3_COUNT_ADDR +#define BGF_GPS_DMA_DMA3_COUNT_LEN_MASK 0x0000FFFF +#define BGF_GPS_DMA_DMA3_COUNT_LEN_SHFT 0 + +#define BGF_GPS_DMA_DMA3_START_STR_ADDR BGF_GPS_DMA_DMA3_START_ADDR +#define BGF_GPS_DMA_DMA3_START_STR_MASK 0x00008000 +#define BGF_GPS_DMA_DMA3_START_STR_SHFT 15 + +#define BGF_GPS_DMA_DMA3_INTSTA_INT_ADDR BGF_GPS_DMA_DMA3_INTSTA_ADDR +#define BGF_GPS_DMA_DMA3_INTSTA_INT_MASK 0x00008000 +#define BGF_GPS_DMA_DMA3_INTSTA_INT_SHFT 15 + +#define BGF_GPS_DMA_DMA3_ACKINT_ACK_ADDR BGF_GPS_DMA_DMA3_ACKINT_ADDR +#define BGF_GPS_DMA_DMA3_ACKINT_ACK_MASK 0x00008000 +#define BGF_GPS_DMA_DMA3_ACKINT_ACK_SHFT 15 + +#define BGF_GPS_DMA_DMA3_RLCT_RLCT_ADDR BGF_GPS_DMA_DMA3_RLCT_ADDR +#define BGF_GPS_DMA_DMA3_RLCT_RLCT_MASK 0x0000FFFF +#define BGF_GPS_DMA_DMA3_RLCT_RLCT_SHFT 0 + +#define BGF_GPS_DMA_DMA3_PGMADDR_PGMADDR_ADDR BGF_GPS_DMA_DMA3_PGMADDR_ADDR +#define BGF_GPS_DMA_DMA3_PGMADDR_PGMADDR_MASK 0xFFFFFFFF +#define BGF_GPS_DMA_DMA3_PGMADDR_PGMADDR_SHFT 0 + +#define BGF_GPS_DMA_DMA4_WPPT_WPPT_ADDR BGF_GPS_DMA_DMA4_WPPT_ADDR +#define BGF_GPS_DMA_DMA4_WPPT_WPPT_MASK 0x0000FFFF +#define BGF_GPS_DMA_DMA4_WPPT_WPPT_SHFT 0 + +#define BGF_GPS_DMA_DMA4_WPTO_WPTO_ADDR BGF_GPS_DMA_DMA4_WPTO_ADDR +#define BGF_GPS_DMA_DMA4_WPTO_WPTO_MASK 0xFFFFFFFF +#define BGF_GPS_DMA_DMA4_WPTO_WPTO_SHFT 0 + +#define BGF_GPS_DMA_DMA4_COUNT_LEN_ADDR BGF_GPS_DMA_DMA4_COUNT_ADDR +#define BGF_GPS_DMA_DMA4_COUNT_LEN_MASK 0x0000FFFF +#define BGF_GPS_DMA_DMA4_COUNT_LEN_SHFT 0 + +#define BGF_GPS_DMA_DMA4_START_STR_ADDR BGF_GPS_DMA_DMA4_START_ADDR +#define BGF_GPS_DMA_DMA4_START_STR_MASK 0x00008000 +#define BGF_GPS_DMA_DMA4_START_STR_SHFT 15 + +#define BGF_GPS_DMA_DMA4_INTSTA_INT_ADDR BGF_GPS_DMA_DMA4_INTSTA_ADDR +#define BGF_GPS_DMA_DMA4_INTSTA_INT_MASK 0x00008000 +#define BGF_GPS_DMA_DMA4_INTSTA_INT_SHFT 15 + +#define BGF_GPS_DMA_DMA4_ACKINT_ACK_ADDR BGF_GPS_DMA_DMA4_ACKINT_ADDR +#define BGF_GPS_DMA_DMA4_ACKINT_ACK_MASK 0x00008000 +#define BGF_GPS_DMA_DMA4_ACKINT_ACK_SHFT 15 + +#define BGF_GPS_DMA_DMA4_RLCT_RLCT_ADDR BGF_GPS_DMA_DMA4_RLCT_ADDR +#define BGF_GPS_DMA_DMA4_RLCT_RLCT_MASK 0x0000FFFF +#define BGF_GPS_DMA_DMA4_RLCT_RLCT_SHFT 0 + +#define BGF_GPS_DMA_DMA4_PGMADDR_PGMADDR_ADDR BGF_GPS_DMA_DMA4_PGMADDR_ADDR +#define BGF_GPS_DMA_DMA4_PGMADDR_PGMADDR_MASK 0xFFFFFFFF +#define BGF_GPS_DMA_DMA4_PGMADDR_PGMADDR_SHFT 0 + +#endif /* __BGF_GPS_DMA_REGS_H__ */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/gps/gps_aon_top.h b/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/gps/gps_aon_top.h new file mode 100644 index 0000000000000000000000000000000000000000..ce7b4cedfa45e3c0b78017ee85ca9797b4b6a5c5 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/gps/gps_aon_top.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ +#ifndef __GPS_AON_TOP_REGS_H__ +#define __GPS_AON_TOP_REGS_H__ + +#define GPS_AON_TOP_BASE 0x80073000 + +#define GPS_AON_TOP_DSLEEP_CTL_ADDR (GPS_AON_TOP_BASE + 0x0108) +#define GPS_AON_TOP_WAKEUP_CTL_ADDR (GPS_AON_TOP_BASE + 0x0110) +#define GPS_AON_TOP_TCXO_MS_H_ADDR (GPS_AON_TOP_BASE + 0x0114) +#define GPS_AON_TOP_TCXO_MS_L_ADDR (GPS_AON_TOP_BASE + 0x0118) + + +#define GPS_AON_TOP_DSLEEP_CTL_FORCE_OSC_EN_ON_ADDR GPS_AON_TOP_DSLEEP_CTL_ADDR +#define GPS_AON_TOP_DSLEEP_CTL_FORCE_OSC_EN_ON_MASK 0x00000008 +#define GPS_AON_TOP_DSLEEP_CTL_FORCE_OSC_EN_ON_SHFT 3 +#define GPS_AON_TOP_DSLEEP_CTL_GPS_PWR_STAT_ADDR GPS_AON_TOP_DSLEEP_CTL_ADDR +#define GPS_AON_TOP_DSLEEP_CTL_GPS_PWR_STAT_MASK 0x00000003 +#define GPS_AON_TOP_DSLEEP_CTL_GPS_PWR_STAT_SHFT 0 + +#endif /* __GPS_AON_TOP_REGS_H__ */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/gps/gps_cfg_on.h b/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/gps/gps_cfg_on.h new file mode 100644 index 0000000000000000000000000000000000000000..2dd8ce5ec6ecdd2ed883c7fc93e177f26e1decfa --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/gps/gps_cfg_on.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ +#ifndef __GPS_CFG_ON_REGS_H__ +#define __GPS_CFG_ON_REGS_H__ + +#define GPS_CFG_ON_BASE 0x80001000 + +#define GPS_CFG_ON_GPS_L1_SLP_PWR_CTL_ADDR (GPS_CFG_ON_BASE + 0x0020) +#define GPS_CFG_ON_GPS_L5_SLP_PWR_CTL_ADDR (GPS_CFG_ON_BASE + 0x0024) +#define GPS_CFG_ON_GPS_CLKGEN1_CTL_ADDR (GPS_CFG_ON_BASE + 0x003C) + + +#define GPS_CFG_ON_GPS_L1_SLP_PWR_CTL_GPS_L1_SLP_PWR_CTL_CS_ADDR GPS_CFG_ON_GPS_L1_SLP_PWR_CTL_ADDR +#define GPS_CFG_ON_GPS_L1_SLP_PWR_CTL_GPS_L1_SLP_PWR_CTL_CS_MASK 0x0000000F +#define GPS_CFG_ON_GPS_L1_SLP_PWR_CTL_GPS_L1_SLP_PWR_CTL_CS_SHFT 0 + +#define GPS_CFG_ON_GPS_L5_SLP_PWR_CTL_GPS_L5_SLP_PWR_CTL_CS_ADDR GPS_CFG_ON_GPS_L5_SLP_PWR_CTL_ADDR +#define GPS_CFG_ON_GPS_L5_SLP_PWR_CTL_GPS_L5_SLP_PWR_CTL_CS_MASK 0x0000000F +#define GPS_CFG_ON_GPS_L5_SLP_PWR_CTL_GPS_L5_SLP_PWR_CTL_CS_SHFT 0 + +#define GPS_CFG_ON_GPS_CLKGEN1_CTL_CR_GPS_DIGCK_DIV_EN_ADDR GPS_CFG_ON_GPS_CLKGEN1_CTL_ADDR +#define GPS_CFG_ON_GPS_CLKGEN1_CTL_CR_GPS_DIGCK_DIV_EN_MASK 0x00000010 +#define GPS_CFG_ON_GPS_CLKGEN1_CTL_CR_GPS_DIGCK_DIV_EN_SHFT 4 + +#endif /* __GPS_CFG_ON_REGS_H__ */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/gps/gps_l5_sys_adrdec.h b/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/gps/gps_l5_sys_adrdec.h new file mode 100644 index 0000000000000000000000000000000000000000..ef074d699aac40641945829498c8dbb51d93ab16 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/gps/gps_l5_sys_adrdec.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ +#ifndef __GPS_L5_SYS_ADRDEC_REGS_H__ +#define __GPS_L5_SYS_ADRDEC_REGS_H__ + +#define GPS_L5_SYS_ADRDEC_BASE 0x80080400 + + + + +#endif /* __GPS_L5_SYS_ADRDEC_REGS_H__ */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/gps/gps_l5_usrt_apb.h b/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/gps/gps_l5_usrt_apb.h new file mode 100644 index 0000000000000000000000000000000000000000..2e0a17f80aab043110acf9cdee85bc54704c414e --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/gps/gps_l5_usrt_apb.h @@ -0,0 +1,60 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ +#ifndef __GPS_L5_USRT_APB_REGS_H__ +#define __GPS_L5_USRT_APB_REGS_H__ + +#define GPS_L5_USRT_APB_BASE 0x80083000 + +#define GPS_L5_USRT_APB_GPS_APB_DATA_ADDR (GPS_L5_USRT_APB_BASE + 0x0000) +#define GPS_L5_USRT_APB_APB_CTRL_ADDR (GPS_L5_USRT_APB_BASE + 0x0004) +#define GPS_L5_USRT_APB_APB_INTEN_ADDR (GPS_L5_USRT_APB_BASE + 0x0008) +#define GPS_L5_USRT_APB_APB_STA_ADDR (GPS_L5_USRT_APB_BASE + 0x000C) +#define GPS_L5_USRT_APB_MONF_ADDR (GPS_L5_USRT_APB_BASE + 0x0010) +#define GPS_L5_USRT_APB_MCUB_A2DF_ADDR (GPS_L5_USRT_APB_BASE + 0x0020) +#define GPS_L5_USRT_APB_MCUB_D2AF_ADDR (GPS_L5_USRT_APB_BASE + 0x0024) +#define GPS_L5_USRT_APB_MCU_A2D0_ADDR (GPS_L5_USRT_APB_BASE + 0x0030) +#define GPS_L5_USRT_APB_MCU_A2D1_ADDR (GPS_L5_USRT_APB_BASE + 0x0034) +#define GPS_L5_USRT_APB_MCU_D2A0_ADDR (GPS_L5_USRT_APB_BASE + 0x0050) +#define GPS_L5_USRT_APB_MCU_D2A1_ADDR (GPS_L5_USRT_APB_BASE + 0x0054) + + +#define GPS_L5_USRT_APB_APB_CTRL_BYTEN_ADDR GPS_L5_USRT_APB_APB_CTRL_ADDR +#define GPS_L5_USRT_APB_APB_CTRL_BYTEN_MASK 0x00000008 +#define GPS_L5_USRT_APB_APB_CTRL_BYTEN_SHFT 3 +#define GPS_L5_USRT_APB_APB_CTRL_TX_EN_ADDR GPS_L5_USRT_APB_APB_CTRL_ADDR +#define GPS_L5_USRT_APB_APB_CTRL_TX_EN_MASK 0x00000002 +#define GPS_L5_USRT_APB_APB_CTRL_TX_EN_SHFT 1 +#define GPS_L5_USRT_APB_APB_CTRL_RX_EN_ADDR GPS_L5_USRT_APB_APB_CTRL_ADDR +#define GPS_L5_USRT_APB_APB_CTRL_RX_EN_MASK 0x00000001 +#define GPS_L5_USRT_APB_APB_CTRL_RX_EN_SHFT 0 + +#define GPS_L5_USRT_APB_APB_INTEN_NODAIEN_ADDR GPS_L5_USRT_APB_APB_INTEN_ADDR +#define GPS_L5_USRT_APB_APB_INTEN_NODAIEN_MASK 0x00000002 +#define GPS_L5_USRT_APB_APB_INTEN_NODAIEN_SHFT 1 +#define GPS_L5_USRT_APB_APB_INTEN_TXIEN_ADDR GPS_L5_USRT_APB_APB_INTEN_ADDR +#define GPS_L5_USRT_APB_APB_INTEN_TXIEN_MASK 0x00000001 +#define GPS_L5_USRT_APB_APB_INTEN_TXIEN_SHFT 0 + +#define GPS_L5_USRT_APB_APB_STA_RX_EMP_ADDR GPS_L5_USRT_APB_APB_STA_ADDR +#define GPS_L5_USRT_APB_APB_STA_RX_EMP_MASK 0x20000000 +#define GPS_L5_USRT_APB_APB_STA_RX_EMP_SHFT 29 +#define GPS_L5_USRT_APB_APB_STA_NODAINTB_ADDR GPS_L5_USRT_APB_APB_STA_ADDR +#define GPS_L5_USRT_APB_APB_STA_NODAINTB_MASK 0x00000002 +#define GPS_L5_USRT_APB_APB_STA_NODAINTB_SHFT 1 + +#define GPS_L5_USRT_APB_MCUB_A2DF_A2DF3_ADDR GPS_L5_USRT_APB_MCUB_A2DF_ADDR +#define GPS_L5_USRT_APB_MCUB_A2DF_A2DF3_MASK 0x00000008 +#define GPS_L5_USRT_APB_MCUB_A2DF_A2DF3_SHFT 3 + +#define GPS_L5_USRT_APB_MCUB_D2AF_D2AF3_ADDR GPS_L5_USRT_APB_MCUB_D2AF_ADDR +#define GPS_L5_USRT_APB_MCUB_D2AF_D2AF3_MASK 0x00000008 +#define GPS_L5_USRT_APB_MCUB_D2AF_D2AF3_SHFT 3 + +#define GPS_L5_USRT_APB_MCU_A2D1_A2D_1_ADDR GPS_L5_USRT_APB_MCU_A2D1_ADDR +#define GPS_L5_USRT_APB_MCU_A2D1_A2D_1_MASK 0x0000FFFF +#define GPS_L5_USRT_APB_MCU_A2D1_A2D_1_SHFT 0 + +#endif /* __GPS_L5_USRT_APB_REGS_H__ */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/gps/gps_rgu_on.h b/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/gps/gps_rgu_on.h new file mode 100644 index 0000000000000000000000000000000000000000..835340b3993b0b69bc2844538d7f60852134d607 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/gps/gps_rgu_on.h @@ -0,0 +1,109 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ +#ifndef __GPS_RGU_ON_REGS_H__ +#define __GPS_RGU_ON_REGS_H__ + +#define GPS_RGU_ON_BASE 0x80000000 + +#define GPS_RGU_ON_GPS_L1_CR_ADDR (GPS_RGU_ON_BASE + 0x0014) +#define GPS_RGU_ON_GPS_L1_DSPPRAM_PDN_EN_ADDR (GPS_RGU_ON_BASE + 0x0048) +#define GPS_RGU_ON_GPS_L1_DSPPRAM_SLP_EN_ADDR (GPS_RGU_ON_BASE + 0x004C) +#define GPS_RGU_ON_GPS_L1_DSPXRAM_PDN_EN_ADDR (GPS_RGU_ON_BASE + 0x0050) +#define GPS_RGU_ON_GPS_L1_DSPXRAM_SLP_EN_ADDR (GPS_RGU_ON_BASE + 0x0054) +#define GPS_RGU_ON_GPS_L1_DSPYRAM_PDN_EN_ADDR (GPS_RGU_ON_BASE + 0x0058) +#define GPS_RGU_ON_GPS_L1_DSPYRAM_SLP_EN_ADDR (GPS_RGU_ON_BASE + 0x005C) +#define GPS_RGU_ON_GPS_L1_DLY_CHAIN_CTL_ADDR (GPS_RGU_ON_BASE + 0x0160) +#define GPS_RGU_ON_GPS_L1_MEM_DLY_CTL_ADDR (GPS_RGU_ON_BASE + 0x0164) +#define GPS_RGU_ON_GPS_L5_CR_ADDR (GPS_RGU_ON_BASE + 0x0214) +#define GPS_RGU_ON_GPS_L5_DSPPRAM_PDN_EN_ADDR (GPS_RGU_ON_BASE + 0x0248) +#define GPS_RGU_ON_GPS_L5_DSPPRAM_SLP_EN_ADDR (GPS_RGU_ON_BASE + 0x024C) +#define GPS_RGU_ON_GPS_L5_DSPXRAM_PDN_EN_ADDR (GPS_RGU_ON_BASE + 0x0250) +#define GPS_RGU_ON_GPS_L5_DSPXRAM_SLP_EN_ADDR (GPS_RGU_ON_BASE + 0x0254) +#define GPS_RGU_ON_GPS_L5_DSPYRAM_PDN_EN_ADDR (GPS_RGU_ON_BASE + 0x0258) +#define GPS_RGU_ON_GPS_L5_DSPYRAM_SLP_EN_ADDR (GPS_RGU_ON_BASE + 0x025C) +#define GPS_RGU_ON_GPS_L5_DLY_CHAIN_CTL_ADDR (GPS_RGU_ON_BASE + 0x0360) +#define GPS_RGU_ON_GPS_L5_MEM_DLY_CTL_ADDR (GPS_RGU_ON_BASE + 0x0364) + + +#define GPS_RGU_ON_GPS_L1_CR_RGU_GPS_L1_SOFT_RST_B_ADDR GPS_RGU_ON_GPS_L1_CR_ADDR +#define GPS_RGU_ON_GPS_L1_CR_RGU_GPS_L1_SOFT_RST_B_MASK 0x00000020 +#define GPS_RGU_ON_GPS_L1_CR_RGU_GPS_L1_SOFT_RST_B_SHFT 5 +#define GPS_RGU_ON_GPS_L1_CR_RGU_GPS_L1_ON_ADDR GPS_RGU_ON_GPS_L1_CR_ADDR +#define GPS_RGU_ON_GPS_L1_CR_RGU_GPS_L1_ON_MASK 0x00000001 +#define GPS_RGU_ON_GPS_L1_CR_RGU_GPS_L1_ON_SHFT 0 + +#define GPS_RGU_ON_GPS_L1_DSPPRAM_PDN_EN_RGU_GPS_L1_PRAM_HWCTL_PDN_ADDR GPS_RGU_ON_GPS_L1_DSPPRAM_PDN_EN_ADDR +#define GPS_RGU_ON_GPS_L1_DSPPRAM_PDN_EN_RGU_GPS_L1_PRAM_HWCTL_PDN_MASK 0x000001FF +#define GPS_RGU_ON_GPS_L1_DSPPRAM_PDN_EN_RGU_GPS_L1_PRAM_HWCTL_PDN_SHFT 0 + +#define GPS_RGU_ON_GPS_L1_DSPPRAM_SLP_EN_RGU_GPS_L1_PRAM_HWCTL_SLP_ADDR GPS_RGU_ON_GPS_L1_DSPPRAM_SLP_EN_ADDR +#define GPS_RGU_ON_GPS_L1_DSPPRAM_SLP_EN_RGU_GPS_L1_PRAM_HWCTL_SLP_MASK 0x000001FF +#define GPS_RGU_ON_GPS_L1_DSPPRAM_SLP_EN_RGU_GPS_L1_PRAM_HWCTL_SLP_SHFT 0 + +#define GPS_RGU_ON_GPS_L1_DSPXRAM_PDN_EN_RGU_GPS_L1_XRAM_HWCTL_PDN_ADDR GPS_RGU_ON_GPS_L1_DSPXRAM_PDN_EN_ADDR +#define GPS_RGU_ON_GPS_L1_DSPXRAM_PDN_EN_RGU_GPS_L1_XRAM_HWCTL_PDN_MASK 0x0000000F +#define GPS_RGU_ON_GPS_L1_DSPXRAM_PDN_EN_RGU_GPS_L1_XRAM_HWCTL_PDN_SHFT 0 + +#define GPS_RGU_ON_GPS_L1_DSPXRAM_SLP_EN_RGU_GPS_L1_XRAM_HWCTL_SLP_ADDR GPS_RGU_ON_GPS_L1_DSPXRAM_SLP_EN_ADDR +#define GPS_RGU_ON_GPS_L1_DSPXRAM_SLP_EN_RGU_GPS_L1_XRAM_HWCTL_SLP_MASK 0x0000000F +#define GPS_RGU_ON_GPS_L1_DSPXRAM_SLP_EN_RGU_GPS_L1_XRAM_HWCTL_SLP_SHFT 0 + +#define GPS_RGU_ON_GPS_L1_DSPYRAM_PDN_EN_RGU_GPS_L1_YRAM_HWCTL_PDN_ADDR GPS_RGU_ON_GPS_L1_DSPYRAM_PDN_EN_ADDR +#define GPS_RGU_ON_GPS_L1_DSPYRAM_PDN_EN_RGU_GPS_L1_YRAM_HWCTL_PDN_MASK 0x000001FF +#define GPS_RGU_ON_GPS_L1_DSPYRAM_PDN_EN_RGU_GPS_L1_YRAM_HWCTL_PDN_SHFT 0 + +#define GPS_RGU_ON_GPS_L1_DSPYRAM_SLP_EN_RGU_GPS_L1_YRAM_HWCTL_SLP_ADDR GPS_RGU_ON_GPS_L1_DSPYRAM_SLP_EN_ADDR +#define GPS_RGU_ON_GPS_L1_DSPYRAM_SLP_EN_RGU_GPS_L1_YRAM_HWCTL_SLP_MASK 0x000001FF +#define GPS_RGU_ON_GPS_L1_DSPYRAM_SLP_EN_RGU_GPS_L1_YRAM_HWCTL_SLP_SHFT 0 + +#define GPS_RGU_ON_GPS_L1_DLY_CHAIN_CTL_RGU_GPS_L1_MEM_PDN_DELAY_DUMMY_NUM_ADDR GPS_RGU_ON_GPS_L1_DLY_CHAIN_CTL_ADDR +#define GPS_RGU_ON_GPS_L1_DLY_CHAIN_CTL_RGU_GPS_L1_MEM_PDN_DELAY_DUMMY_NUM_MASK 0x000F0000 +#define GPS_RGU_ON_GPS_L1_DLY_CHAIN_CTL_RGU_GPS_L1_MEM_PDN_DELAY_DUMMY_NUM_SHFT 16 + +#define GPS_RGU_ON_GPS_L1_MEM_DLY_CTL_RGU_GPSSYS_L1_MEM_ADJ_DLY_EN_ADDR GPS_RGU_ON_GPS_L1_MEM_DLY_CTL_ADDR +#define GPS_RGU_ON_GPS_L1_MEM_DLY_CTL_RGU_GPSSYS_L1_MEM_ADJ_DLY_EN_MASK 0x80000000 +#define GPS_RGU_ON_GPS_L1_MEM_DLY_CTL_RGU_GPSSYS_L1_MEM_ADJ_DLY_EN_SHFT 31 + +#define GPS_RGU_ON_GPS_L5_CR_RGU_GPS_L5_SOFT_RST_B_ADDR GPS_RGU_ON_GPS_L5_CR_ADDR +#define GPS_RGU_ON_GPS_L5_CR_RGU_GPS_L5_SOFT_RST_B_MASK 0x00000020 +#define GPS_RGU_ON_GPS_L5_CR_RGU_GPS_L5_SOFT_RST_B_SHFT 5 +#define GPS_RGU_ON_GPS_L5_CR_RGU_GPS_L5_ON_ADDR GPS_RGU_ON_GPS_L5_CR_ADDR +#define GPS_RGU_ON_GPS_L5_CR_RGU_GPS_L5_ON_MASK 0x00000001 +#define GPS_RGU_ON_GPS_L5_CR_RGU_GPS_L5_ON_SHFT 0 + +#define GPS_RGU_ON_GPS_L5_DSPPRAM_PDN_EN_RGU_GPS_L5_PRAM_HWCTL_PDN_ADDR GPS_RGU_ON_GPS_L5_DSPPRAM_PDN_EN_ADDR +#define GPS_RGU_ON_GPS_L5_DSPPRAM_PDN_EN_RGU_GPS_L5_PRAM_HWCTL_PDN_MASK 0x000003FF +#define GPS_RGU_ON_GPS_L5_DSPPRAM_PDN_EN_RGU_GPS_L5_PRAM_HWCTL_PDN_SHFT 0 + +#define GPS_RGU_ON_GPS_L5_DSPPRAM_SLP_EN_RGU_GPS_L5_PRAM_HWCTL_SLP_ADDR GPS_RGU_ON_GPS_L5_DSPPRAM_SLP_EN_ADDR +#define GPS_RGU_ON_GPS_L5_DSPPRAM_SLP_EN_RGU_GPS_L5_PRAM_HWCTL_SLP_MASK 0x000003FF +#define GPS_RGU_ON_GPS_L5_DSPPRAM_SLP_EN_RGU_GPS_L5_PRAM_HWCTL_SLP_SHFT 0 + +#define GPS_RGU_ON_GPS_L5_DSPXRAM_PDN_EN_RGU_GPS_L5_XRAM_HWCTL_PDN_ADDR GPS_RGU_ON_GPS_L5_DSPXRAM_PDN_EN_ADDR +#define GPS_RGU_ON_GPS_L5_DSPXRAM_PDN_EN_RGU_GPS_L5_XRAM_HWCTL_PDN_MASK 0x0000000F +#define GPS_RGU_ON_GPS_L5_DSPXRAM_PDN_EN_RGU_GPS_L5_XRAM_HWCTL_PDN_SHFT 0 + +#define GPS_RGU_ON_GPS_L5_DSPXRAM_SLP_EN_RGU_GPS_L5_XRAM_HWCTL_SLP_ADDR GPS_RGU_ON_GPS_L5_DSPXRAM_SLP_EN_ADDR +#define GPS_RGU_ON_GPS_L5_DSPXRAM_SLP_EN_RGU_GPS_L5_XRAM_HWCTL_SLP_MASK 0x0000000F +#define GPS_RGU_ON_GPS_L5_DSPXRAM_SLP_EN_RGU_GPS_L5_XRAM_HWCTL_SLP_SHFT 0 + +#define GPS_RGU_ON_GPS_L5_DSPYRAM_PDN_EN_RGU_GPS_L5_YRAM_HWCTL_PDN_ADDR GPS_RGU_ON_GPS_L5_DSPYRAM_PDN_EN_ADDR +#define GPS_RGU_ON_GPS_L5_DSPYRAM_PDN_EN_RGU_GPS_L5_YRAM_HWCTL_PDN_MASK 0x000003FF +#define GPS_RGU_ON_GPS_L5_DSPYRAM_PDN_EN_RGU_GPS_L5_YRAM_HWCTL_PDN_SHFT 0 + +#define GPS_RGU_ON_GPS_L5_DSPYRAM_SLP_EN_RGU_GPS_L5_YRAM_HWCTL_SLP_ADDR GPS_RGU_ON_GPS_L5_DSPYRAM_SLP_EN_ADDR +#define GPS_RGU_ON_GPS_L5_DSPYRAM_SLP_EN_RGU_GPS_L5_YRAM_HWCTL_SLP_MASK 0x000003FF +#define GPS_RGU_ON_GPS_L5_DSPYRAM_SLP_EN_RGU_GPS_L5_YRAM_HWCTL_SLP_SHFT 0 + +#define GPS_RGU_ON_GPS_L5_DLY_CHAIN_CTL_RGU_GPS_L5_MEM_PDN_DELAY_DUMMY_NUM_ADDR GPS_RGU_ON_GPS_L5_DLY_CHAIN_CTL_ADDR +#define GPS_RGU_ON_GPS_L5_DLY_CHAIN_CTL_RGU_GPS_L5_MEM_PDN_DELAY_DUMMY_NUM_MASK 0x000F0000 +#define GPS_RGU_ON_GPS_L5_DLY_CHAIN_CTL_RGU_GPS_L5_MEM_PDN_DELAY_DUMMY_NUM_SHFT 16 + +#define GPS_RGU_ON_GPS_L5_MEM_DLY_CTL_RGU_GPSSYS_L5_MEM_ADJ_DLY_EN_ADDR GPS_RGU_ON_GPS_L5_MEM_DLY_CTL_ADDR +#define GPS_RGU_ON_GPS_L5_MEM_DLY_CTL_RGU_GPSSYS_L5_MEM_ADJ_DLY_EN_MASK 0x80000000 +#define GPS_RGU_ON_GPS_L5_MEM_DLY_CTL_RGU_GPSSYS_L5_MEM_ADJ_DLY_EN_SHFT 31 + +#endif /* __GPS_RGU_ON_REGS_H__ */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/gps/gps_sys_adrdec.h b/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/gps/gps_sys_adrdec.h new file mode 100644 index 0000000000000000000000000000000000000000..5a81b94aa30400885f255ceb6a35621608bb2be5 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/gps/gps_sys_adrdec.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ +#ifndef __GPS_SYS_ADRDEC_REGS_H__ +#define __GPS_SYS_ADRDEC_REGS_H__ + +#define GPS_SYS_ADRDEC_BASE 0x80070400 + + + + +#endif /* __GPS_SYS_ADRDEC_REGS_H__ */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/gps/gps_usrt_apb.h b/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/gps/gps_usrt_apb.h new file mode 100644 index 0000000000000000000000000000000000000000..99153d3608ec2992bae9cc9bda479bbc5c8e7474 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/coda_gen/gps/gps_usrt_apb.h @@ -0,0 +1,99 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ +#ifndef __GPS_USRT_APB_REGS_H__ +#define __GPS_USRT_APB_REGS_H__ + +#define GPS_USRT_APB_BASE 0x80073000 + +#define GPS_USRT_APB_GPS_APB_DATA_ADDR (GPS_USRT_APB_BASE + 0x0000) +#define GPS_USRT_APB_APB_CTRL_ADDR (GPS_USRT_APB_BASE + 0x0004) +#define GPS_USRT_APB_APB_INTEN_ADDR (GPS_USRT_APB_BASE + 0x0008) +#define GPS_USRT_APB_APB_STA_ADDR (GPS_USRT_APB_BASE + 0x000C) +#define GPS_USRT_APB_MONF_ADDR (GPS_USRT_APB_BASE + 0x0010) +#define GPS_USRT_APB_MCUB_A2DF_ADDR (GPS_USRT_APB_BASE + 0x0020) +#define GPS_USRT_APB_MCUB_D2AF_ADDR (GPS_USRT_APB_BASE + 0x0024) +#define GPS_USRT_APB_MCU_A2D0_ADDR (GPS_USRT_APB_BASE + 0x0030) +#define GPS_USRT_APB_MCU_A2D1_ADDR (GPS_USRT_APB_BASE + 0x0034) +#define GPS_USRT_APB_MCU_D2A0_ADDR (GPS_USRT_APB_BASE + 0x0050) +#define GPS_USRT_APB_MCU_D2A1_ADDR (GPS_USRT_APB_BASE + 0x0054) + + +#define GPS_USRT_APB_APB_CTRL_BYTEN_ADDR GPS_USRT_APB_APB_CTRL_ADDR +#define GPS_USRT_APB_APB_CTRL_BYTEN_MASK 0x00000008 +#define GPS_USRT_APB_APB_CTRL_BYTEN_SHFT 3 +#define GPS_USRT_APB_APB_CTRL_TX_EN_ADDR GPS_USRT_APB_APB_CTRL_ADDR +#define GPS_USRT_APB_APB_CTRL_TX_EN_MASK 0x00000002 +#define GPS_USRT_APB_APB_CTRL_TX_EN_SHFT 1 +#define GPS_USRT_APB_APB_CTRL_RX_EN_ADDR GPS_USRT_APB_APB_CTRL_ADDR +#define GPS_USRT_APB_APB_CTRL_RX_EN_MASK 0x00000001 +#define GPS_USRT_APB_APB_CTRL_RX_EN_SHFT 0 + +#define GPS_USRT_APB_APB_INTEN_NODAIEN_ADDR GPS_USRT_APB_APB_INTEN_ADDR +#define GPS_USRT_APB_APB_INTEN_NODAIEN_MASK 0x00000002 +#define GPS_USRT_APB_APB_INTEN_NODAIEN_SHFT 1 +#define GPS_USRT_APB_APB_INTEN_TXIEN_ADDR GPS_USRT_APB_APB_INTEN_ADDR +#define GPS_USRT_APB_APB_INTEN_TXIEN_MASK 0x00000001 +#define GPS_USRT_APB_APB_INTEN_TXIEN_SHFT 0 + +#define GPS_USRT_APB_APB_STA_RX_UNDR_ADDR GPS_USRT_APB_APB_STA_ADDR +#define GPS_USRT_APB_APB_STA_RX_UNDR_MASK 0x80000000 +#define GPS_USRT_APB_APB_STA_RX_UNDR_SHFT 31 +#define GPS_USRT_APB_APB_STA_RX_OVF_ADDR GPS_USRT_APB_APB_STA_ADDR +#define GPS_USRT_APB_APB_STA_RX_OVF_MASK 0x40000000 +#define GPS_USRT_APB_APB_STA_RX_OVF_SHFT 30 +#define GPS_USRT_APB_APB_STA_RX_EMP_ADDR GPS_USRT_APB_APB_STA_ADDR +#define GPS_USRT_APB_APB_STA_RX_EMP_MASK 0x20000000 +#define GPS_USRT_APB_APB_STA_RX_EMP_SHFT 29 +#define GPS_USRT_APB_APB_STA_RX_FULL_ADDR GPS_USRT_APB_APB_STA_ADDR +#define GPS_USRT_APB_APB_STA_RX_FULL_MASK 0x10000000 +#define GPS_USRT_APB_APB_STA_RX_FULL_SHFT 28 +#define GPS_USRT_APB_APB_STA_TX_UNDR_ADDR GPS_USRT_APB_APB_STA_ADDR +#define GPS_USRT_APB_APB_STA_TX_UNDR_MASK 0x08000000 +#define GPS_USRT_APB_APB_STA_TX_UNDR_SHFT 27 +#define GPS_USRT_APB_APB_STA_TX_OVF_ADDR GPS_USRT_APB_APB_STA_ADDR +#define GPS_USRT_APB_APB_STA_TX_OVF_MASK 0x04000000 +#define GPS_USRT_APB_APB_STA_TX_OVF_SHFT 26 +#define GPS_USRT_APB_APB_STA_TX_EMP_ADDR GPS_USRT_APB_APB_STA_ADDR +#define GPS_USRT_APB_APB_STA_TX_EMP_MASK 0x02000000 +#define GPS_USRT_APB_APB_STA_TX_EMP_SHFT 25 +#define GPS_USRT_APB_APB_STA_TX_FULL_ADDR GPS_USRT_APB_APB_STA_ADDR +#define GPS_USRT_APB_APB_STA_TX_FULL_MASK 0x01000000 +#define GPS_USRT_APB_APB_STA_TX_FULL_SHFT 24 +#define GPS_USRT_APB_APB_STA_TX_ST_ADDR GPS_USRT_APB_APB_STA_ADDR +#define GPS_USRT_APB_APB_STA_TX_ST_MASK 0x00700000 +#define GPS_USRT_APB_APB_STA_TX_ST_SHFT 20 +#define GPS_USRT_APB_APB_STA_RX_ST_ADDR GPS_USRT_APB_APB_STA_ADDR +#define GPS_USRT_APB_APB_STA_RX_ST_MASK 0x00070000 +#define GPS_USRT_APB_APB_STA_RX_ST_SHFT 16 +#define GPS_USRT_APB_APB_STA_REGE_ADDR GPS_USRT_APB_APB_STA_ADDR +#define GPS_USRT_APB_APB_STA_REGE_MASK 0x00000020 +#define GPS_USRT_APB_APB_STA_REGE_SHFT 5 +#define GPS_USRT_APB_APB_STA_URAME_ADDR GPS_USRT_APB_APB_STA_ADDR +#define GPS_USRT_APB_APB_STA_URAME_MASK 0x00000010 +#define GPS_USRT_APB_APB_STA_URAME_SHFT 4 +#define GPS_USRT_APB_APB_STA_TX_IND_ADDR GPS_USRT_APB_APB_STA_ADDR +#define GPS_USRT_APB_APB_STA_TX_IND_MASK 0x00000008 +#define GPS_USRT_APB_APB_STA_TX_IND_SHFT 3 +#define GPS_USRT_APB_APB_STA_NODAINTB_ADDR GPS_USRT_APB_APB_STA_ADDR +#define GPS_USRT_APB_APB_STA_NODAINTB_MASK 0x00000002 +#define GPS_USRT_APB_APB_STA_NODAINTB_SHFT 1 +#define GPS_USRT_APB_APB_STA_TXINTB_ADDR GPS_USRT_APB_APB_STA_ADDR +#define GPS_USRT_APB_APB_STA_TXINTB_MASK 0x00000001 +#define GPS_USRT_APB_APB_STA_TXINTB_SHFT 0 + +#define GPS_USRT_APB_MCUB_A2DF_A2DF3_ADDR GPS_USRT_APB_MCUB_A2DF_ADDR +#define GPS_USRT_APB_MCUB_A2DF_A2DF3_MASK 0x00000008 +#define GPS_USRT_APB_MCUB_A2DF_A2DF3_SHFT 3 + +#define GPS_USRT_APB_MCUB_D2AF_D2AF3_ADDR GPS_USRT_APB_MCUB_D2AF_ADDR +#define GPS_USRT_APB_MCUB_D2AF_D2AF3_MASK 0x00000008 +#define GPS_USRT_APB_MCUB_D2AF_D2AF3_SHFT 3 + +#define GPS_USRT_APB_MCU_A2D1_A2D_1_ADDR GPS_USRT_APB_MCU_A2D1_ADDR +#define GPS_USRT_APB_MCU_A2D1_A2D_1_MASK 0x0000FFFF +#define GPS_USRT_APB_MCU_A2D1_A2D_1_SHFT 0 + +#endif /* __GPS_USRT_APB_REGS_H__ */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/gps_dl_hw_dep_api.h b/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/gps_dl_hw_dep_api.h new file mode 100644 index 0000000000000000000000000000000000000000..43cdb537d4d88dc71c47a09c5957d3954c21dc03 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/connac2_0/gps_dl_hw_dep_api.h @@ -0,0 +1,97 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ +#ifndef _GPS_DL_HW_DEP_API_H +#define _GPS_DL_HW_DEP_API_H + +#include "gps_dl_hw_ver.h" +#include "conn_infra/conn_infra_cfg.h" +#include "conn_infra/conn_host_csr_top.h" + +#define GDL_HW_SUPPORT_LIST "SUPPORT:MT6885,MT6893" + +#define GDL_HW_CHECK_CONN_INFRA_VER(p_poll_okay, p_poll_ver) \ + GDL_HW_POLL_ENTRY_VERBOSE(GPS_DL_CONN_INFRA_BUS, \ + CONN_INFRA_CFG_CONN_HW_VER_RO_CONN_HW_VERSION, \ + p_poll_okay, p_poll_ver, POLL_DEFAULT, ( \ + (*p_poll_ver == GDL_HW_CONN_INFRA_VER_MT6885) || \ + (*p_poll_ver == GDL_HW_CONN_INFRA_VER_MT6893)) \ + ) + + +#define GDL_HW_SET_CONN2GPS_SLP_PROT_RX_VAL(val) \ + GDL_HW_SET_CONN_INFRA_ENTRY( \ + CONN_INFRA_CFG_GALS_CONN2GPS_SLP_CTRL_R_CONN2GPS_SLP_PROT_RX_EN, val) + +#define GDL_HW_POLL_CONN2GPS_SLP_PROT_RX_UNTIL_VAL(val, timeout, p_is_okay) \ + GDL_HW_POLL_CONN_INFRA_ENTRY( \ + CONN_INFRA_CFG_GALS_CONN2GPS_SLP_CTRL_R_CONN2GPS_SLP_PROT_RX_RDY, \ + val, timeout, p_is_okay) + + +#define GDL_HW_SET_CONN2GPS_SLP_PROT_TX_VAL(val) \ + GDL_HW_SET_CONN_INFRA_ENTRY( \ + CONN_INFRA_CFG_GALS_CONN2GPS_SLP_CTRL_R_CONN2GPS_SLP_PROT_TX_EN, val) + +#define GDL_HW_POLL_CONN2GPS_SLP_PROT_TX_UNTIL_VAL(val, timeout, p_is_okay) \ + GDL_HW_POLL_CONN_INFRA_ENTRY( \ + CONN_INFRA_CFG_GALS_CONN2GPS_SLP_CTRL_R_CONN2GPS_SLP_PROT_TX_RDY, \ + val, timeout, p_is_okay) + + +#define GDL_HW_SET_GPS2CONN_SLP_PROT_RX_VAL(val) \ + GDL_HW_SET_CONN_INFRA_ENTRY( \ + CONN_INFRA_CFG_GALS_GPS2CONN_SLP_CTRL_R_GPS2CONN_SLP_PROT_RX_EN, val) + +#define GDL_HW_POLL_GPS2CONN_SLP_PROT_RX_UNTIL_VAL(val, timeout, p_is_okay) \ + GDL_HW_POLL_CONN_INFRA_ENTRY( \ + CONN_INFRA_CFG_GALS_GPS2CONN_SLP_CTRL_R_GPS2CONN_SLP_PROT_RX_RDY, \ + val, timeout, p_is_okay) + + +#define GDL_HW_SET_GPS2CONN_SLP_PROT_TX_VAL(val) \ + GDL_HW_SET_CONN_INFRA_ENTRY( \ + CONN_INFRA_CFG_GALS_GPS2CONN_SLP_CTRL_R_GPS2CONN_SLP_PROT_TX_EN, val) + +#define GDL_HW_POLL_GPS2CONN_SLP_PROT_TX_UNTIL_VAL(val, timeout, p_is_okay) \ + GDL_HW_POLL_CONN_INFRA_ENTRY( \ + CONN_INFRA_CFG_GALS_GPS2CONN_SLP_CTRL_R_GPS2CONN_SLP_PROT_TX_RDY, \ + val, timeout, p_is_okay) + + +/* For Connac2.0, wait until sleep prot disable done, or after polling 10 x 1ms */ +#define GDL_HW_MAY_WAIT_CONN_INFRA_SLP_PROT_DISABLE_ACK(p_poll_okay) \ + GDL_HW_POLL_CONN_INFRA_ENTRY( \ + CONN_HOST_CSR_TOP_CONN_SLP_PROT_CTRL_CONN_INFRA_ON2OFF_SLP_PROT_ACK, \ + 0, 10 * 1000 * POLL_US, p_poll_okay) + + +/* The dump address list for Connac2.0 */ +#define GDL_HW_DUMP_SLP_RPOT_STATUS() do {\ + gps_dl_bus_rd_opt(GPS_DL_CONN_INFRA_BUS, \ + CONN_INFRA_CFG_GALS_CONN2GPS_SLP_CTRL_ADDR, \ + BMASK_RW_FORCE_PRINT); \ + gps_dl_bus_rd_opt(GPS_DL_CONN_INFRA_BUS, \ + CONN_INFRA_CFG_GALS_GPS2CONN_SLP_CTRL_ADDR, \ + BMASK_RW_FORCE_PRINT); \ + } while (0) + + +#if (GPS_DL_HAS_CONNINFRA_DRV) +/* + * For MT6885 and MT6893, conninfra driver do it due to GPS/BT share same bit, + * so do nothing here if conninfra driver ready. + */ +#define GDL_HW_SET_CONN_INFRA_BGF_EN_MT6885_MT6893(val) +#else +#define GDL_HW_SET_CONN_INFRA_BGF_EN_MT6885_MT6893(val) \ + GDL_HW_SET_CONN_INFRA_ENTRY(CONN_INFRA_RGU_BGFYS_ON_TOP_PWR_CTL_BGFSYS_ON_TOP_PWR_ON, val) +#endif +#define GDL_HW_SET_CONN_INFRA_BGF_EN(val) GDL_HW_SET_CONN_INFRA_BGF_EN_MT6885_MT6893(val) + +#define GDL_HW_SET_GPS_FUNC_EN(val) \ + GDL_HW_SET_CONN_INFRA_ENTRY(CONN_INFRA_CFG_GPS_PWRCTRL0_GP_FUNCTION_EN, val) + +#endif /* _GPS_DL_HW_DEP_API_H */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/gps_dl_hw_api.h b/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/gps_dl_hw_api.h new file mode 100644 index 0000000000000000000000000000000000000000..7a13a7bebfe8ea5a74c8653bb9f07b8e876d8e6f --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/gps_dl_hw_api.h @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#ifndef _GPS_DL_HW_API_H +#define _GPS_DL_HW_API_H + +#include "gps_dl_config.h" +#include "gps_dl_dma_buf.h" +#include "gps_dl_hal_api.h" +#include "gps_dl_hal_type.h" + +enum GDL_HW_RET { + HW_OKAY, /* hw CRs access okay */ + E_INV_PARAMS, /* invalid parameters */ + E_RESETTING, /* whole chip reset is on-going */ + E_POLL_TIMEOUT, /* timeout when waiting CR change to excepted value */ + E_MAX +}; + +#if GPS_DL_ON_LINUX +#define GDL_HW_STATUS_POLL_INTERVAL_USEC (1) /* 1us */ +#else +#define GDL_HW_STATUS_POLL_INTERVAL_USEC (2*1000) /* 2ms */ +#endif + +enum dsp_ctrl_enum { + GPS_L1_DSP_ON, + GPS_L1_DSP_OFF, + GPS_L5_DSP_ON, + GPS_L5_DSP_OFF, + GPS_L1_DSP_ENTER_DSLEEP, + GPS_L1_DSP_EXIT_DSLEEP, + GPS_L1_DSP_ENTER_DSTOP, + GPS_L1_DSP_EXIT_DSTOP, + GPS_L5_DSP_ENTER_DSLEEP, + GPS_L5_DSP_EXIT_DSLEEP, + GPS_L5_DSP_ENTER_DSTOP, + GPS_L5_DSP_EXIT_DSTOP, + GPS_L1_DSP_CLEAR_PWR_STAT, + GPS_L5_DSP_CLEAR_PWR_STAT, + GPS_DSP_CTRL_MAX +}; +int gps_dl_hw_gps_dsp_ctrl(enum dsp_ctrl_enum ctrl); +bool gps_dl_hw_gps_dsp_is_off_done(enum gps_dl_link_id_enum link_id); +void gps_dl_hw_gps_adie_force_off(void); +void gps_dl_hw_gps_dump_top_rf_cr(void); + +int gps_dl_hw_gps_common_on(void); +int gps_dl_hw_gps_common_off(void); +bool gps_dl_hw_gps_force_wakeup_conninfra_top_off(bool enable); +void gps_dl_hw_gps_sw_request_emi_usage(bool request); + +enum GDL_HW_RET gps_dl_hw_get_mcub_info( + enum gps_dl_link_id_enum link_id, struct gps_dl_hal_mcub_info *p); + +void gps_dl_hw_clear_mcub_d2a_flag( + enum gps_dl_link_id_enum link_id, unsigned int d2a_flag); + +unsigned int gps_dl_hw_get_mcub_a2d_flag(enum gps_dl_link_id_enum link_id); + +enum GDL_RET_STATUS gps_dl_hw_mcub_dsp_read_request( + enum gps_dl_link_id_enum link_id, u16 dsp_addr); + +void gps_dl_hw_set_gps_emi_remapping(unsigned int _20msb_of_36bit_phy_addr); +unsigned int gps_dl_hw_get_gps_emi_remapping(void); + +void gps_dl_hw_set_dma_start(enum gps_dl_hal_dma_ch_index channel, + struct gdl_hw_dma_transfer *p_transfer); + +void gps_dl_hw_set_dma_stop(enum gps_dl_hal_dma_ch_index channel); + +bool gps_dl_hw_get_dma_int_status(enum gps_dl_hal_dma_ch_index channel); + +unsigned int gps_dl_hw_get_dma_left_len(enum gps_dl_hal_dma_ch_index channel); + +struct gps_dl_hw_dma_status_struct { + unsigned int wrap_count; + unsigned int wrap_to_addr; + unsigned int total_count; + unsigned int config; + unsigned int start_flag; + unsigned int intr_flag; + unsigned int left_count; + unsigned int curr_addr; + unsigned int state; +}; + +void gps_dl_hw_save_dma_status_struct( + enum gps_dl_hal_dma_ch_index ch, struct gps_dl_hw_dma_status_struct *p); + +void gps_dl_hw_print_dma_status_struct( + enum gps_dl_hal_dma_ch_index ch, struct gps_dl_hw_dma_status_struct *p); + +enum GDL_RET_STATUS gps_dl_hw_wait_until_dma_complete_and_stop_it( + enum gps_dl_hal_dma_ch_index ch, int timeout_usec, bool return_if_not_start); + + +struct gps_dl_hw_usrt_status_struct { + unsigned int ctrl_setting; + unsigned int intr_enable; + unsigned int state; + unsigned int mcub_d2a_flag; + unsigned int mcub_d2a_d0; + unsigned int mcub_d2a_d1; + unsigned int mcub_a2d_flag; + unsigned int mcub_a2d_d0; + unsigned int mcub_a2d_d1; +}; + +/* TODO: replace gps_dl_hw_usrt_status_struct */ +struct gps_dl_hw_link_status_struct { + bool usrt_has_data; + bool usrt_has_nodata; + bool rx_dma_done; + bool tx_dma_done; +}; + +void gps_dl_hw_get_link_status( + enum gps_dl_link_id_enum link_id, struct gps_dl_hw_link_status_struct *p); + +void gps_dl_hw_save_usrt_status_struct( + enum gps_dl_link_id_enum link_id, struct gps_dl_hw_usrt_status_struct *p); + +void gps_dl_hw_print_usrt_status_struct( + enum gps_dl_link_id_enum link_id, struct gps_dl_hw_usrt_status_struct *p); + +void gps_dl_hw_dump_sleep_prot_status(void); +void gps_dl_hw_dump_host_csr_gps_info(bool force_show_log); +void gps_dl_hw_dump_host_csr_conninfra_info(bool force_show_log); +void gps_dl_hw_print_hw_status(enum gps_dl_link_id_enum link_id, bool dump_rf_cr); +void gps_dl_hw_do_gps_a2z_dump(void); +void gps_dl_hw_print_usrt_status(enum gps_dl_link_id_enum link_id); +bool gps_dl_hw_poll_usrt_dsp_rx_empty(enum gps_dl_link_id_enum link_id); +void gps_dl_hw_gps_dump_gps_rf_cr(void); +void gps_dl_hw_print_ms_counter_status(void); + +void gps_dl_hw_switch_dsp_jtag(void); + +void gps_dl_hw_usrt_rx_irq_enable( + enum gps_dl_link_id_enum link_id, bool enable); +void gps_dl_hw_usrt_ctrl(enum gps_dl_link_id_enum link_id, + bool is_on, bool is_dma_mode, bool is_1byte_mode); +void gps_dl_hw_usrt_clear_nodata_irq(enum gps_dl_link_id_enum link_id); +bool gps_dl_hw_usrt_has_set_nodata_flag(enum gps_dl_link_id_enum link_id); + + +bool gps_dl_hw_is_pta_clk_cfg_ready(void); +void gps_dl_hw_set_ptk_clk_cfg(void); + +bool gps_dl_hw_is_pta_uart_init_done(void); +bool gps_dl_hw_init_pta_uart(void); +void gps_dl_hw_deinit_pta_uart(void); + +bool gps_dl_hw_is_pta_init_done(void); +void gps_dl_hw_init_pta(void); +void gps_dl_hw_deinit_pta(void); + +void gps_dl_hw_claim_pta_used_by_gps(void); +void gps_dl_hw_disclaim_pta_used_by_gps(void); +void gps_dl_hw_set_pta_blanking_parameter(bool use_direct_path); + +bool gps_dl_hw_take_conn_coex_hw_sema(unsigned int timeout_ms); +void gps_dl_hw_give_conn_coex_hw_sema(void); +bool gps_dl_hw_take_conn_rfspi_hw_sema(unsigned int timeout_ms); +void gps_dl_hw_give_conn_rfspi_hw_sema(void); + +unsigned int gps_dl_hw_get_mcub_a2d1_cfg(enum gps_dl_link_id_enum link_id, bool is_1byte_mode); + +#endif /* _GPS_DL_HW_API_H */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/gps_dl_hw_type.h b/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/gps_dl_hw_type.h new file mode 100644 index 0000000000000000000000000000000000000000..62f9b3517234d0d35a0a977fbc7df7529e2589c7 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/gps_dl_hw_type.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#ifndef _GPS_DL_HW_TYPE_H +#define _GPS_DL_HW_TYPE_H + +#include "gps_dl_config.h" + +/* to import u32 series types */ +#if GPS_DL_ON_LINUX +#include +#elif GPS_DL_ON_CTP +#include "kernel_to_ctp.h" +#endif + +typedef u32 conn_reg; + + +#define GPS_DL_HW_INVALID_ADDR (0xFFFFFFFF) + +#endif /* _GPS_DL_HW_TYPE_H */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/gps_dl_hw_ver.h b/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/gps_dl_hw_ver.h new file mode 100644 index 0000000000000000000000000000000000000000..5119e104d3542d31659e06bfda230fc169f3465e --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/hw/inc/gps_dl_hw_ver.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ +#ifndef _GPS_DL_HW_VER_H +#define _GPS_DL_HW_VER_H + + +#define GDL_HW_CONN_INFRA_VER_MT6885 (0x20010000) +#define GDL_HW_CONN_INFRA_VER_MT6893 (0x20010101) + + +#define GDL_HW_BGF_VER (0x20010000) + + +#endif /* _GPS_DL_HW_VER_H */ diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/inc/gps_dl_config.h b/drivers/misc/mediatek/connectivity/gps/data_link/inc/gps_dl_config.h new file mode 100644 index 0000000000000000000000000000000000000000..04febfa26eb1b5d5ed3718ed74d93f02cffbf96c --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/inc/gps_dl_config.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#ifndef _GPS_DL_CONFIG_H +#define _GPS_DL_CONFIG_H + +enum gps_dl_link_id_enum { + GPS_DATA_LINK_ID0 = 0, + GPS_DATA_LINK_ID1 = 1, + GPS_DATA_LINK_NUM = 2, +}; + +#define LINK_ID_IS_VALID(link_id) \ + (((link_id) >= 0) && ((link_id) < GPS_DATA_LINK_NUM)) + +#define CHOOSE_BY_LINK_ID(link_id, val_for_id0, val_for_id1, val_for_otherwise) \ + (!LINK_ID_IS_VALID((link_id)) ? (val_for_otherwise) : ( \ + (link_id == GPS_DATA_LINK_ID0) ? val_for_id0 : val_for_id1)) + +#ifdef GPS_DL_HAS_MOCK +#define GPS_DL_HW_IS_MOCK (1) +#define GPS_DL_MOCK_HAL (1) +#else +#define GPS_DL_HW_IS_MOCK (0) +#define GPS_DL_MOCK_HAL (0) +#endif + +#define GPS_DL_MOCK_RX_TIMEOUT (0) + +#define GPS_DL_ON_LINUX (1) +#define GPS_DL_ON_CTP (0) + +#define GPS_DL_HAS_CTRLD (1) +#define GPS_DL_NO_USE_IRQ (0) +#define GPS_DL_USE_THREADED_IRQ (1) + +#ifndef GPS_DL_HAS_CONNINFRA_DRV +#define GPS_DL_HAS_CONNINFRA_DRV (0) +#endif + +#define GPS_DL_HAS_PLAT_DRV (1) +#define GPS_DL_HAS_PTA (1) +#define GPS_DL_USE_TIA (0) + +#define GPS_DL_IS_MODULE (1) + +#define GPS_DL_USE_MTK_SYNC_WRITE (1) +#define GPS_DL_SET_EMI_MPU_CFG (1) +#define GPS_DL_GET_RSV_MEM_IN_MODULE (0) + + +#include "gps_dl_log.h" + +#endif /* _GPS_DL_CONFIG_H */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/inc/gps_dl_context.h b/drivers/misc/mediatek/connectivity/gps/data_link/inc/gps_dl_context.h new file mode 100644 index 0000000000000000000000000000000000000000..402aa01877bb529387356b95945d3baf9437af08 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/inc/gps_dl_context.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#ifndef _GPS_DL_CONTEXT_H +#define _GPS_DL_CONTEXT_H + +#include "gps_dl_config.h" +#include "gps_each_link.h" +#include "gps_dl_isr.h" + +#if GPS_DL_ON_LINUX +#include "gps_each_device.h" +#include "gps_dl_linux.h" +#include "gps_dl_ctrld.h" +#define GPS_DL_TX_BUF_SIZE (8 * 1024) +#define GPS_DL_RX_BUF_SIZE (8 * 1024) +#else +#define GPS_DL_TX_BUF_SIZE (4 * 1024) +#define GPS_DL_RX_BUF_SIZE (4 * 1024) +#endif + +struct gps_dl_remap_ctx { + unsigned int gps_emi_phy_high20; +}; + +struct gps_dl_ctx { + int major; + int minor; +#if GPS_DL_ON_LINUX + struct gps_each_device devices[GPS_DATA_LINK_NUM]; +#endif + struct gps_each_link links[GPS_DATA_LINK_NUM]; + struct gps_each_irq irqs[GPS_DL_IRQ_NUM]; + struct gps_dl_remap_ctx remap_ctx; +}; + +struct gps_dl_remap_ctx *gps_dl_remap_ctx_get(void); + +struct gps_dl_runtime_cfg { + bool dma_is_1byte_mode; + bool dma_is_enabled; + bool show_reg_rw_log; + bool show_reg_wait_log; + bool only_show_wait_done_log; + enum gps_dl_log_level_enum log_level; + unsigned int log_mod_bitmask; + unsigned int log_reg_rw_bitmask; +}; + +bool gps_dl_is_1byte_mode(void); +bool gps_dl_is_dma_enabled(void); + +bool gps_dl_show_reg_rw_log(void); +bool gps_dl_show_reg_wait_log(void); +bool gps_dl_only_show_wait_done_log(void); + +bool gps_dl_set_1byte_mode(bool is_1byte_mode); +bool gps_dl_set_dma_enabled(bool to_enable); + +bool gps_dl_set_show_reg_rw_log(bool on); +void gps_dl_set_show_reg_wait_log(bool on); + +int gps_dl_set_rx_transfer_max(enum gps_dl_link_id_enum link_id, int max); +int gps_dl_set_tx_transfer_max(enum gps_dl_link_id_enum link_id, int max); + +#endif /* _GPS_DL_CONTEXT_H */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/inc/gps_dl_log.h b/drivers/misc/mediatek/connectivity/gps/data_link/inc/gps_dl_log.h new file mode 100644 index 0000000000000000000000000000000000000000..b82c94cf5a5a50f94c0162bedcd4e00c7d36d245 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/inc/gps_dl_log.h @@ -0,0 +1,255 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#ifndef _GPS_DL_LOG_H +#define _GPS_DL_LOG_H + +#include "gps_dl_config.h" +#if GPS_DL_ON_LINUX +#include +#elif GPS_DL_ON_CTP +#include "gps_dl_ctp_log.h" +#endif + +enum gps_dl_log_level_enum { + GPS_DL_LOG_LEVEL_DBG = 1, + GPS_DL_LOG_LEVEL_INFO = 3, + GPS_DL_LOG_LEVEL_WARN = 5, + GPS_DL_LOG_LEVEL_ERR = 7, +}; + +enum gps_dl_log_module_enum { + GPS_DL_LOG_MOD_DEFAULT = 0, + GPS_DL_LOG_MOD_OPEN_CLOSE = 1, + GPS_DL_LOG_MOD_READ_WRITE = 2, + GPS_DL_LOG_MOD_REG_RW = 3, + GPS_DL_LOG_MOD_STATUS = 4, + GPS_DL_LOG_MOD_EVENT = 5, + GPS_DL_LOG_MOD_INIT = 6, + + GPS_DL_LOG_MOD_MAX = 32 +}; + +enum gps_dl_log_reg_rw_ctrl_enum { + GPS_DL_REG_RW_HOST_CSR_PTA_INIT, + GPS_DL_REG_RW_HOST_CSR_GPS_OFF, + GPS_DL_REG_RW_EMI_SW_REQ_CTRL, + GPS_DL_REG_RW_MCUB_IRQ_HANDLER, + + GPS_DL_REG_RW_MAX = 32 +}; + +#define GPS_DL_LOG_DEF_SETTING_LEVEL GPS_DL_LOG_LEVEL_INFO +#define GPS_DL_LOG_DEF_SETTING_MODULES ( \ + (1UL << GPS_DL_LOG_MOD_DEFAULT) | \ + (1UL << GPS_DL_LOG_MOD_OPEN_CLOSE) | \ + (0UL << GPS_DL_LOG_MOD_READ_WRITE) | \ + (1UL << GPS_DL_LOG_MOD_REG_RW) | \ + (1UL << GPS_DL_LOG_MOD_STATUS) | \ + (0UL << GPS_DL_LOG_MOD_EVENT) | \ + (1UL << GPS_DL_LOG_MOD_INIT) | \ + 0) +#define GPS_DL_LOG_REG_RW_BITMASK ( \ + (0UL << GPS_DL_REG_RW_HOST_CSR_PTA_INIT) |\ + (0UL << GPS_DL_REG_RW_HOST_CSR_GPS_OFF) |\ + (0UL << GPS_DL_REG_RW_EMI_SW_REQ_CTRL) |\ + (0UL << GPS_DL_REG_RW_MCUB_IRQ_HANDLER) |\ + 0) + +enum gps_dl_log_level_enum gps_dl_log_level_get(void); +void gps_dl_log_level_set(enum gps_dl_log_level_enum level); + +unsigned int gps_dl_log_mod_bitmask_get(void); +void gps_dl_log_mod_bitmask_set(unsigned int bitmask); +bool gps_dl_log_mod_is_on(enum gps_dl_log_module_enum mod); +void gps_dl_log_mod_on(enum gps_dl_log_module_enum mod); +void gps_dl_log_mod_off(enum gps_dl_log_module_enum mod); + +bool gps_dl_log_reg_rw_is_on(enum gps_dl_log_reg_rw_ctrl_enum log_reg_rw); + +void gps_dl_log_info_show(void); + + +#if GPS_DL_ON_LINUX +#define __GDL_LOGE(mod, fmt, ...) pr_notice("GDL[E:%d] [%s:%d]: "fmt, \ + mod, __func__, __LINE__, ##__VA_ARGS__) +#define __GDL_LOGW(mod, fmt, ...) pr_notice("GDL[W:%d] [%s:%d]: "fmt, \ + mod, __func__, __LINE__, ##__VA_ARGS__) +#define __GDL_LOGI(mod, fmt, ...) pr_info("GDL[I:%d] [%s:%d]: "fmt, \ + mod, __func__, __LINE__, ##__VA_ARGS__) +#define __GDL_LOGD(mod, fmt, ...) pr_info("GDL[D:%d] [%s:%d]: "fmt, \ + mod, __func__, __LINE__, ##__VA_ARGS__) + +#define __GDL_LOGXE(mod, link_id, fmt, ...) pr_notice("GDL-%d[E:%d] [%s:%d]: "fmt, \ + link_id, mod, __func__, __LINE__, ##__VA_ARGS__) + +#define __GDL_LOGXW(mod, link_id, fmt, ...) pr_notice("GDL-%d[W:%d] [%s:%d]: "fmt, \ + link_id, mod, __func__, __LINE__, ##__VA_ARGS__) + +#define __GDL_LOGXI(mod, link_id, fmt, ...) pr_info("GDL-%d[I:%d] [%s:%d]: "fmt, \ + link_id, mod, __func__, __LINE__, ##__VA_ARGS__) + +#define __GDL_LOGXD(mod, link_id, fmt, ...) pr_info("GDL-%d[D:%d] [%s:%d]: "fmt, \ + link_id, mod, __func__, __LINE__, ##__VA_ARGS__) +#endif /* GPS_DL_ON_XX */ + + +#define _GDL_LOGE(...) \ + do { if (gps_dl_log_level_get() <= GPS_DL_LOG_LEVEL_ERR) __GDL_LOGE(__VA_ARGS__); } while (0) +#define _GDL_LOGW(...) \ + do { if (gps_dl_log_level_get() <= GPS_DL_LOG_LEVEL_WARN) __GDL_LOGW(__VA_ARGS__); } while (0) +#define _GDL_LOGI(...) \ + do { if (gps_dl_log_level_get() <= GPS_DL_LOG_LEVEL_INFO) __GDL_LOGI(__VA_ARGS__); } while (0) +#define _GDL_LOGD(...) \ + do { if (gps_dl_log_level_get() <= GPS_DL_LOG_LEVEL_DBG) __GDL_LOGD(__VA_ARGS__); } while (0) +#define _GDL_LOGXE(...) \ + do { if (gps_dl_log_level_get() <= GPS_DL_LOG_LEVEL_ERR) __GDL_LOGXE(__VA_ARGS__); } while (0) +#define _GDL_LOGXW(...) \ + do { if (gps_dl_log_level_get() <= GPS_DL_LOG_LEVEL_WARN) __GDL_LOGXW(__VA_ARGS__); } while (0) +#define _GDL_LOGXI(...) \ + do { if (gps_dl_log_level_get() <= GPS_DL_LOG_LEVEL_INFO) __GDL_LOGXI(__VA_ARGS__); } while (0) +#define _GDL_LOGXD(...) \ + do { if (gps_dl_log_level_get() <= GPS_DL_LOG_LEVEL_DBG) __GDL_LOGXD(__VA_ARGS__); } while (0) + + +#define GDL_LOGE2(mod, ...) \ + do { if (1) \ + _GDL_LOGE(mod, __VA_ARGS__); } while (0) +#define GDL_LOGW2(mod, ...) \ + do { if (1) \ + _GDL_LOGW(mod, __VA_ARGS__); } while (0) +#define GDL_LOGI2(mod, ...) \ + do { if (gps_dl_log_mod_is_on(mod)) \ + _GDL_LOGI(mod, __VA_ARGS__); } while (0) +#define GDL_LOGD2(mod, ...) \ + do { if (gps_dl_log_mod_is_on(mod)) \ + _GDL_LOGD(mod, __VA_ARGS__); } while (0) + +/* Usage: + * 1. Bellow macro can be used to output log: + * err level: GDL_LOGE, GDL_LOGE_YYY, GDL_LOGXE, GDL_LOGXE_YYY + * warn level: GDL_LOGW, GDL_LOGW_YYY, GDL_LOGXW, GDL_LOGXW_YYY + * info level: GDL_LOGI, GDL_LOGI_YYY, GDL_LOGXI, GDL_LOGXI_YYY + * dbg level: GDL_LOGD, GDL_LOGE_YYY, GDL_LOGXD, GDL_LOGXD_YYY + * + * 2. _YYY stands for log module(group), the list are: + * _ONF for device/link open or close flow + * _DRW for devcie/link read or write flow + * _RRW for hw register read or write flow + * _STA for state machine related flow + * _EVT for event processing related flow + * _INI for device initialization/deinitializaion flow + * if they are used, the log can be easily filtered by keywords like "[E:2]", "[I:5]" and so on + * if you don't know which to use, just use: GDL_LOG* or GDL_LOGX*, which have no _YYY subfix + * + * 3. Log of info and dbg level can be showed seeing log level and module setting meet: + * a) log level setting <= INFO or DBG and + * b) log module bitmask bit is 1 for the module + * + * 4. Log of warn and err level is showed only seeing log level: + * a) log level setting <= WARN or ERR + * + * 5. Difference between GDL_LOG* and GDL_LOGX*: + * GDL_LOG* can be used like: GDL_LOGD("a = %d", a) + * GDL_LOGX* can take a parameters of link_id, like: GDL_LOGXD(link_id, "a = %d", a) + */ +#define GDL_LOGE(...) GDL_LOGE2(GPS_DL_LOG_MOD_DEFAULT, __VA_ARGS__) +#define GDL_LOGW(...) GDL_LOGW2(GPS_DL_LOG_MOD_DEFAULT, __VA_ARGS__) +#define GDL_LOGI(...) GDL_LOGI2(GPS_DL_LOG_MOD_DEFAULT, __VA_ARGS__) +#define GDL_LOGD(...) GDL_LOGD2(GPS_DL_LOG_MOD_DEFAULT, __VA_ARGS__) + +#define GDL_LOGD_ONF(...) GDL_LOGD2(GPS_DL_LOG_MOD_OPEN_CLOSE, __VA_ARGS__) + +#define GDL_LOGI_DRW(...) GDL_LOGI2(GPS_DL_LOG_MOD_READ_WRITE, __VA_ARGS__) + +#define GDL_LOGW_RRW(...) GDL_LOGI2(GPS_DL_LOG_MOD_REG_RW, __VA_ARGS__) +#define GDL_LOGI_RRW(...) GDL_LOGI2(GPS_DL_LOG_MOD_REG_RW, __VA_ARGS__) + +#define GDL_LOGE_EVT(...) GDL_LOGE2(GPS_DL_LOG_MOD_EVENT, __VA_ARGS__) +#define GDL_LOGW_EVT(...) GDL_LOGW2(GPS_DL_LOG_MOD_EVENT, __VA_ARGS__) +#define GDL_LOGD_EVT(...) GDL_LOGD2(GPS_DL_LOG_MOD_EVENT, __VA_ARGS__) + +#define GDL_LOGE_INI(...) GDL_LOGE2(GPS_DL_LOG_MOD_INIT, __VA_ARGS__) +#define GDL_LOGW_INI(...) GDL_LOGW2(GPS_DL_LOG_MOD_INIT, __VA_ARGS__) +#define GDL_LOGI_INI(...) GDL_LOGI2(GPS_DL_LOG_MOD_INIT, __VA_ARGS__) +#define GDL_LOGD_INI(...) GDL_LOGD2(GPS_DL_LOG_MOD_INIT, __VA_ARGS__) + +#define GDL_LOGXE2(mod, ...) \ + do { if (1) \ + _GDL_LOGXE(mod, __VA_ARGS__); } while (0) +#define GDL_LOGXW2(mod, ...) \ + do { if (1) \ + _GDL_LOGXW(mod, __VA_ARGS__); } while (0) +#define GDL_LOGXI2(mod, ...) \ + do { if (gps_dl_log_mod_is_on(mod)) \ + _GDL_LOGXI(mod, __VA_ARGS__); } while (0) +#define GDL_LOGXD2(mod, ...) \ + do { if (gps_dl_log_mod_is_on(mod)) \ + _GDL_LOGXD(mod, __VA_ARGS__); } while (0) + +#define GDL_LOGXE(...) GDL_LOGXE2(GPS_DL_LOG_MOD_DEFAULT, __VA_ARGS__) +#define GDL_LOGXW(...) GDL_LOGXW2(GPS_DL_LOG_MOD_DEFAULT, __VA_ARGS__) +#define GDL_LOGXI(...) GDL_LOGXI2(GPS_DL_LOG_MOD_DEFAULT, __VA_ARGS__) +#define GDL_LOGXD(...) GDL_LOGXD2(GPS_DL_LOG_MOD_DEFAULT, __VA_ARGS__) + +#define GDL_LOGXE_ONF(...) GDL_LOGXE2(GPS_DL_LOG_MOD_OPEN_CLOSE, __VA_ARGS__) +#define GDL_LOGXW_ONF(...) GDL_LOGXW2(GPS_DL_LOG_MOD_OPEN_CLOSE, __VA_ARGS__) +#define GDL_LOGXI_ONF(...) GDL_LOGXI2(GPS_DL_LOG_MOD_OPEN_CLOSE, __VA_ARGS__) +#define GDL_LOGXD_ONF(...) GDL_LOGXD2(GPS_DL_LOG_MOD_OPEN_CLOSE, __VA_ARGS__) + +#define GDL_LOGXE_DRW(...) GDL_LOGXE2(GPS_DL_LOG_MOD_READ_WRITE, __VA_ARGS__) +#define GDL_LOGXW_DRW(...) GDL_LOGXW2(GPS_DL_LOG_MOD_READ_WRITE, __VA_ARGS__) +#define GDL_LOGXI_DRW(...) GDL_LOGXI2(GPS_DL_LOG_MOD_READ_WRITE, __VA_ARGS__) +#define GDL_LOGXD_DRW(...) GDL_LOGXD2(GPS_DL_LOG_MOD_READ_WRITE, __VA_ARGS__) + +#define GDL_LOGXE_STA(...) GDL_LOGXE2(GPS_DL_LOG_MOD_STATUS, __VA_ARGS__) +#define GDL_LOGXW_STA(...) GDL_LOGXW2(GPS_DL_LOG_MOD_STATUS, __VA_ARGS__) +#define GDL_LOGXI_STA(...) GDL_LOGXI2(GPS_DL_LOG_MOD_STATUS, __VA_ARGS__) + +#define GDL_LOGXW_EVT(...) GDL_LOGXW2(GPS_DL_LOG_MOD_EVENT, __VA_ARGS__) +#define GDL_LOGXI_EVT(...) GDL_LOGXI2(GPS_DL_LOG_MOD_EVENT, __VA_ARGS__) +#define GDL_LOGXD_EVT(...) GDL_LOGXD2(GPS_DL_LOG_MOD_EVENT, __VA_ARGS__) + +#define GDL_LOGXE_INI(...) GDL_LOGXE2(GPS_DL_LOG_MOD_INIT, __VA_ARGS__) +#define GDL_LOGXI_INI(...) GDL_LOGXI2(GPS_DL_LOG_MOD_INIT, __VA_ARGS__) +#define GDL_LOGXD_INI(...) GDL_LOGXD2(GPS_DL_LOG_MOD_INIT, __VA_ARGS__) + + +#define GDL_ASSERT(cond, ret, fmt, ...) \ + do { if (!(cond)) { \ + GDL_LOGE("{** GDL_ASSERT: [(%s) = %d] **}: "fmt, \ + #cond, (cond), ##__VA_ARGS__); \ + return ret; \ + } } while (0) + +void GDL_VOIDF(void); + +#define GDL_ASSERT_RET_OKAY(gdl_ret) \ + GDL_ASSERT((callee_ret) != GDL_OKAY, GDL_FAIL_ASSERT, "") + +#define GDL_ASSERT_RET_NOT_ASSERT(callee_ret, ret_to_caller) \ + GDL_ASSERT((callee_ret) == GDL_FAIL_ASSERT, ret_to_caller, "") + +#define ASSERT_NOT_ZERO(val, ret)\ + GDL_ASSERT(val != 0, ret, "%s should not be 0!", #val) + +#define ASSERT_ZERO(val, ret)\ + GDL_ASSERT(val == 0, ret, "%s should be 0!", #val) + +#define ASSERT_NOT_NULL(ptr, ret)\ + GDL_ASSERT(ptr != NULL, ret, "null ptr!") + +#define ASSERT_LINK_ID(link_id, ret) \ + GDL_ASSERT(LINK_ID_IS_VALID(link_id), ret, "invalid link_id: %d", link_id) + +#endif /* _GPS_DL_LOG_H */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/inc/gps_each_link.h b/drivers/misc/mediatek/connectivity/gps/data_link/inc/gps_each_link.h new file mode 100644 index 0000000000000000000000000000000000000000..0876ada70de91e7cf2455487cd3c67e2033043b0 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/inc/gps_each_link.h @@ -0,0 +1,264 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#ifndef _GPS_EACH_LINK_H +#define _GPS_EACH_LINK_H + +#include "gps_dl_config.h" + +#if GPS_DL_ON_LINUX +#include +#endif + +#if GPS_DL_ON_CTP +#include "gps_dl_ctp_osal.h" +#endif + +#if GPS_DL_HAS_CTRLD +#include "gps_dl_ctrld.h" +#endif + +#include "gps_dl_subsys_reset.h" +#include "gps_dl_dma_buf.h" + +struct gps_each_link_cfg { + int tx_buf_size; + int rx_buf_size; +}; + +enum gps_each_link_waitable_type { + GPS_DL_WAIT_OPEN_CLOSE, + GPS_DL_WAIT_WRITE, + GPS_DL_WAIT_READ, + GPS_DL_WAIT_RESET, + GPS_DL_WAIT_NUM +}; + +struct gps_each_link_state_list { + bool is_ready_to_write; + bool is_active; + bool to_be_closed; + bool is_resetting; + bool open_result_okay; + bool user_open; + bool need_a2z_dump; + bool suspend_to_clk_ext; +}; + +enum gps_each_link_bool_state { + LINK_WRITE_READY, + LINK_IS_ACTIVE, + LINK_TO_BE_CLOSED, + LINK_USER_OPEN, + LINK_WAIT_RESET_DONE, + LINK_IS_RESETTING, + LINK_OPEN_RESULT_OKAY, + LINK_NEED_A2Z_DUMP, + LINK_SUSPEND_TO_CLK_EXT, + BOOL_STATE_NUM +}; + +void gps_each_link_set_bool_flag(enum gps_dl_link_id_enum link_id, + enum gps_each_link_bool_state name, bool value); +bool gps_each_link_get_bool_flag(enum gps_dl_link_id_enum link_id, + enum gps_each_link_bool_state name); + +bool gps_dl_link_is_ready_to_write(enum gps_dl_link_id_enum link_id); +void gps_dl_link_set_ready_to_write(enum gps_dl_link_id_enum link_id, bool is_ready); + +bool gps_each_link_is_active(enum gps_dl_link_id_enum link_id); +void gps_each_link_set_active(enum gps_dl_link_id_enum link_id, bool is_active); + +enum gps_each_link_wait_status { + WAITING, + OKAY, + FAIL, + SIGNAL, +}; + +struct gps_each_link_waitable { +#if GPS_DL_ON_LINUX + /* TODO: use completion */ + wait_queue_head_t wq; +#endif + bool fired; + bool waiting; + enum gps_each_link_wait_status status; + enum gps_each_link_waitable_type type; +}; + +enum gps_each_link_mutex { + GPS_DL_MTX_BIG_LOCK, + GPS_DL_MTX_NUM +}; + +void gps_each_link_mutex_take(enum gps_dl_link_id_enum link_id, enum gps_each_link_mutex mtx_id); +void gps_each_link_mutex_give(enum gps_dl_link_id_enum link_id, enum gps_each_link_mutex mtx_id); + +enum gps_each_link_spinlock { + GPS_DL_SPINLOCK_FOR_LINK_STATE, + GPS_DL_SPINLOCK_FOR_DMA_BUF, + GPS_DL_SPINLOCK_NUM +}; + +void gps_each_link_spin_lock_take(enum gps_dl_link_id_enum link_id, enum gps_each_link_spinlock spin_lock_id); +void gps_each_link_spin_lock_give(enum gps_dl_link_id_enum link_id, enum gps_each_link_spinlock spin_lock_id); + + +enum gps_each_link_state_enum { + LINK_UNINIT, + LINK_CLOSED, + LINK_OPENING, + LINK_OPENED, + LINK_CLOSING, + LINK_RESETTING, /* Not distinguish EACH_LINK or WHOLE_GPS or WHOLE_CONNSYS */ + LINK_RESET_DONE, + LINK_DISABLED, + LINK_SUSPENDING, + LINK_SUSPENDED, + LINK_RESUMING, + LINK_STATE_NUM +}; + +#define GPS_EACH_LINK_SID_MAX (0x7FFFFFFE) +#define GPS_EACH_LINK_SID_NO_CHECK (0xFFFFFFFF) +struct gps_each_link { + struct gps_each_link_cfg cfg; + struct gps_each_device *p_device; + struct gps_dl_dma_buf tx_dma_buf; + struct gps_dl_dma_buf rx_dma_buf; + struct gps_each_link_waitable waitables[GPS_DL_WAIT_NUM]; + struct gps_dl_osal_sleepable_lock mutexes[GPS_DL_MTX_NUM]; + struct gps_dl_osal_unsleepable_lock spin_locks[GPS_DL_SPINLOCK_NUM]; + struct gps_each_link_state_list sub_states; + enum gps_each_link_state_enum state_for_user; + enum gps_each_link_reset_level reset_level; + int session_id; +}; + +void gps_each_link_mutexes_init(struct gps_each_link *p); +void gps_each_link_mutexes_deinit(struct gps_each_link *p); +void gps_each_link_spin_locks_init(struct gps_each_link *p); +void gps_each_link_spin_locks_deinit(struct gps_each_link *p); + + +struct gps_common_context { + struct gps_dl_osal_sleepable_lock big_lock; +}; + +/* only ctrld can change it */ +struct gps_dl_ctrl_context { + bool gps_reset; + bool connsys_reset; +}; + +struct gps_each_link *gps_dl_link_get(enum gps_dl_link_id_enum link_id); + +void gps_each_link_init(enum gps_dl_link_id_enum link_id); +void gps_each_link_deinit(enum gps_dl_link_id_enum link_id); +void gps_each_link_context_init(enum gps_dl_link_id_enum link_id); +void gps_each_link_context_clear(enum gps_dl_link_id_enum link_id); +void gps_each_link_inc_session_id(enum gps_dl_link_id_enum link_id); +int gps_each_link_get_session_id(enum gps_dl_link_id_enum link_id); + +int gps_each_link_open(enum gps_dl_link_id_enum link_id); +void gps_dl_link_open_ack(enum gps_dl_link_id_enum link_id, bool okay, bool hw_resume); + +enum gps_each_link_lock_reason { + GDL_LOCK_FOR_OPEN, + GDL_LOCK_FOR_OPEN_DONE, + GDL_LOCK_FOR_CLOSE, + GDL_LOCK_FOR_CLOSE_DONE, + GDL_LOCK_FOR_RESET, + GDL_LOCK_FOR_RESET_DONE, +}; + +enum gps_each_link_state_enum gps_each_link_get_state(enum gps_dl_link_id_enum link_id); +void gps_each_link_set_state(enum gps_dl_link_id_enum link_id, enum gps_each_link_state_enum state); +bool gps_each_link_change_state_from(enum gps_dl_link_id_enum link_id, + enum gps_each_link_state_enum from, enum gps_each_link_state_enum to); + + +int gps_each_link_take_big_lock(enum gps_dl_link_id_enum link_id, + enum gps_each_link_lock_reason reason); +int gps_each_link_give_big_lock(enum gps_dl_link_id_enum link_id); + +int gps_each_link_reset(enum gps_dl_link_id_enum link_id); +void gps_dl_link_reset_ack(enum gps_dl_link_id_enum link_id); +void gps_dl_link_on_post_conn_reset(enum gps_dl_link_id_enum link_id); +bool gps_dl_link_try_to_clear_both_resetting_status(void); +int gps_dl_link_get_clock_flag(void); + +enum gps_each_link_close_or_suspend_op { + GDL_CLOSE, + GDL_DPSTOP, + GDL_CLKEXT, +}; +int gps_each_link_enter_dsleep(enum gps_dl_link_id_enum link_id); +int gps_each_link_leave_dsleep(enum gps_dl_link_id_enum link_id); +int gps_each_link_hw_suspend(enum gps_dl_link_id_enum link_id, bool need_clk_ext); +int gps_each_link_hw_resume(enum gps_dl_link_id_enum link_id); +int gps_each_link_close(enum gps_dl_link_id_enum link_id); +int gps_each_link_check(enum gps_dl_link_id_enum link_id, int reason); + +int gps_each_link_write(enum gps_dl_link_id_enum link_id, + unsigned char *buf, unsigned int len); +int gps_each_link_write_with_opt(enum gps_dl_link_id_enum link_id, + unsigned char *buf, unsigned int len, bool wait_tx_done); +int gps_each_link_read(enum gps_dl_link_id_enum link_id, + unsigned char *buf, unsigned int len); +int gps_each_link_read_with_timeout(enum gps_dl_link_id_enum link_id, + unsigned char *buf, unsigned int len, int timeout_usec, bool *p_is_nodata); + +bool gps_dl_link_start_tx_dma_if_has_data(enum gps_dl_link_id_enum link_id); + +void gps_dl_link_waitable_init(struct gps_each_link_waitable *p, + enum gps_each_link_waitable_type type); + +void gps_dl_link_waitable_reset(enum gps_dl_link_id_enum link_id, enum gps_each_link_waitable_type type); + +enum GDL_RET_STATUS gps_dl_link_wait_on(struct gps_each_link_waitable *p, long *p_sigval); + +enum GDL_RET_STATUS gps_dl_link_try_wait_on(enum gps_dl_link_id_enum link_id, + enum gps_each_link_waitable_type type); + +void gps_dl_link_wake_up(struct gps_each_link_waitable *p); + +enum gps_dl_link_event_id { + GPS_DL_EVT_LINK_OPEN, + GPS_DL_EVT_LINK_CLOSE, + GPS_DL_EVT_LINK_WRITE, + GPS_DL_EVT_LINK_READ, + GPS_DL_EVT_LINK_DSP_ROM_READY_TIMEOUT, + GPS_DL_EVT_LINK_DSP_FSM_TIMEOUT, + GPS_DL_EVT_LINK_RESET_DSP, + GPS_DL_EVT_LINK_RESET_GPS, + GPS_DL_EVT_LINK_PRE_CONN_RESET, + GPS_DL_EVT_LINK_POST_CONN_RESET, + GPS_DL_EVT_LINK_PRINT_HW_STATUS, + GPS_DL_EVT_LINK_ENTER_DPSLEEP, + GPS_DL_EVT_LINK_LEAVE_DPSLEEP, + GPS_DL_EVT_LINK_ENTER_DPSTOP, + GPS_DL_EVT_LINK_LEAVE_DPSTOP, + GPS_DL_EVT_LINK_UPDATE_SETTING, + GPS_DL_EVT_LINK_PRINT_DATA_STATUS, + GPS_DL_LINK_EVT_NUM, +}; + +void gps_dl_link_event_send(enum gps_dl_link_event_id evt, + enum gps_dl_link_id_enum link_id); + +void gps_dl_link_event_proc(enum gps_dl_link_event_id evt, + enum gps_dl_link_id_enum link_id); + +#endif /* _GPS_EACH_LINK_H */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/lib/gps_dl_dma_buf.c b/drivers/misc/mediatek/connectivity/gps/data_link/lib/gps_dl_dma_buf.c new file mode 100644 index 0000000000000000000000000000000000000000..8e2ff3a870687c0c3c9562e8e2b90685e83d472c --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/lib/gps_dl_dma_buf.c @@ -0,0 +1,722 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#include "gps_dl_config.h" +#include "gps_dl_context.h" + +#include "gps_dl_dma_buf.h" +#if GPS_DL_ON_LINUX +#include "asm/barrier.h" +#endif + +#define GDL_COUNT_FREE(r, w, l)\ + ((w >= r) ? (l + r - w) : (r - w)) + +#define GDL_COUNT_DATA(r, w, l)\ + ((w >= r) ? (w - r) : (l + w - r)) + +void gps_dma_buf_reset(struct gps_dl_dma_buf *p_dma) +{ + gps_each_link_spin_lock_take(p_dma->dev_index, GPS_DL_SPINLOCK_FOR_DMA_BUF); + p_dma->read_index = 0; + p_dma->reader_working = 0; + p_dma->write_index = 0; + p_dma->writer_working = 0; + p_dma->dma_working_entry.is_valid = false; + p_dma->entry_r = 0; + p_dma->entry_w = 0; + memset(&p_dma->data_entries[0], 0, sizeof(p_dma->data_entries)); + gps_each_link_spin_lock_give(p_dma->dev_index, GPS_DL_SPINLOCK_FOR_DMA_BUF); + + GDL_LOGXD(p_dma->dev_index, "dir = %d", p_dma->dir); +} + +void gps_dma_buf_show(struct gps_dl_dma_buf *p_dma, bool is_warning) +{ + unsigned int ri, wi, fl, re, we, fe; + bool r_working, w_working; + + gps_each_link_spin_lock_take(p_dma->dev_index, GPS_DL_SPINLOCK_FOR_DMA_BUF); + ri = p_dma->read_index; + r_working = p_dma->reader_working; + wi = p_dma->write_index; + w_working = p_dma->writer_working; + fl = GDL_COUNT_FREE(p_dma->read_index, p_dma->writer_working, p_dma->len); + re = p_dma->entry_r; + we = p_dma->entry_w; + fe = GDL_COUNT_FREE(p_dma->entry_r, p_dma->entry_w, GPS_DL_DMA_BUF_ENTRY_MAX); + gps_each_link_spin_lock_give(p_dma->dev_index, GPS_DL_SPINLOCK_FOR_DMA_BUF); + + if (is_warning) { + GDL_LOGXW_DRW(p_dma->dev_index, + "dir = %d, l = %d, r = %d(%d), w = %d(%d), fl = %d, re = %d, we = %d, fe = %d", + p_dma->dir, p_dma->len, ri, r_working, wi, w_working, fl, re, we, fe); + } else { + GDL_LOGXD_DRW(p_dma->dev_index, + "dir = %d, l = %d, r = %d(%d), w = %d(%d), fl = %d, re = %d, we = %d, fe = %d", + p_dma->dir, p_dma->len, ri, r_working, wi, w_working, fl, re, we, fe); + } +} + +void gps_dma_buf_align_as_byte_mode(struct gps_dl_dma_buf *p_dma) +{ + unsigned int ri, wi; + unsigned int ri_new, wi_new; + + gps_each_link_spin_lock_take(p_dma->dev_index, GPS_DL_SPINLOCK_FOR_DMA_BUF); + ri = p_dma->read_index; + wi = p_dma->write_index; + + if (!gps_dl_is_1byte_mode()) { + p_dma->read_index = ((p_dma->read_index + 3) / 4) * 4; + if (p_dma->read_index >= p_dma->len) + p_dma->read_index -= p_dma->len; + p_dma->reader_working = 0; + + p_dma->write_index = ((p_dma->write_index + 3) / 4) * 4; + if (p_dma->write_index >= p_dma->len) + p_dma->write_index -= p_dma->len; + p_dma->writer_working = 0; + p_dma->dma_working_entry.is_valid = false; + } + + ri_new = p_dma->read_index; + wi_new = p_dma->write_index; + + /* clear it anyway */ + p_dma->read_index = p_dma->write_index; + gps_each_link_spin_lock_give(p_dma->dev_index, GPS_DL_SPINLOCK_FOR_DMA_BUF); + + GDL_LOGXD(p_dma->dev_index, "is_1byte = %d, ri: %u -> %u, wi: %u -> %u", + gps_dl_is_1byte_mode(), ri, ri_new, wi, wi_new); +} + +#if 0 +enum GDL_RET_STATUS gdl_dma_buf_init(struct gps_dl_dma_buf *p_dma_buf) +{ + return GDL_OKAY; +} + +enum GDL_RET_STATUS gdl_dma_buf_deinit(struct gps_dl_dma_buf *p_dma_buf) +{ + return GDL_OKAY; +} +#endif + +bool gps_dma_buf_is_empty(struct gps_dl_dma_buf *p_dma) +{ + bool is_empty; + + gps_each_link_spin_lock_take(p_dma->dev_index, GPS_DL_SPINLOCK_FOR_DMA_BUF); + is_empty = (p_dma->read_index == p_dma->write_index); + gps_each_link_spin_lock_give(p_dma->dev_index, GPS_DL_SPINLOCK_FOR_DMA_BUF); + + return is_empty; +} + +enum GDL_RET_STATUS gdl_dma_buf_put(struct gps_dl_dma_buf *p_dma, + const unsigned char *p_buf, unsigned int buf_len) +{ + struct gdl_dma_buf_entry entry; + struct gdl_dma_buf_entry *p_entry = &entry; + + /* unsigned int free_len; */ + /* unsigned int wrap_len; */ + enum GDL_RET_STATUS gdl_ret; + + ASSERT_NOT_NULL(p_dma, GDL_FAIL_ASSERT); + ASSERT_NOT_NULL(p_buf, GDL_FAIL_ASSERT); + + gdl_ret = gdl_dma_buf_get_free_entry(p_dma, p_entry, false); + + if (GDL_OKAY != gdl_ret) + return gdl_ret; + +#if 0 + free_len = GDL_COUNT_FREE(p_entry->read_index, + p_entry->write_index, p_entry->buf_length); + GDL_LOGD("r=%u, w=%u, l=%u, f=%u", p_entry->read_index, + p_entry->write_index, p_entry->buf_length, free_len); + + if (free_len < buf_len) { + gdl_dma_buf_set_free_entry(p_dma, NULL); + return GDL_FAIL_NOSPACE; + } + + wrap_len = p_entry->buf_length - p_entry->write_index; + if (wrap_len >= buf_len) { + memcpy(((unsigned char *)p_entry->vir_addr) + p_entry->write_index, + p_buf, buf_len); + + p_entry->write_index += buf_len; + if (p_entry->write_index >= p_entry->buf_length) + p_entry->write_index = 0; + } else { + memcpy(((unsigned char *)p_entry->vir_addr) + p_entry->write_index, + p_buf, wrap_len); + + memcpy(((unsigned char *)p_entry->vir_addr) + 0, + p_buf + wrap_len, buf_len - wrap_len); + + p_entry->write_index = buf_len - wrap_len; + } +#endif + gdl_ret = gdl_dma_buf_buf_to_entry(p_entry, p_buf, buf_len, + &p_entry->write_index); + + if (GDL_OKAY != gdl_ret) + return gdl_ret; + + /* TODO: make a data entry */ + + GDL_LOGD("new_w=%u", p_entry->write_index); + gdl_dma_buf_set_free_entry(p_dma, p_entry); + + return GDL_OKAY; +} + +enum GDL_RET_STATUS gdl_dma_buf_get(struct gps_dl_dma_buf *p_dma, + unsigned char *p_buf, unsigned int buf_len, unsigned int *p_data_len, + bool *p_is_nodata) +{ + struct gdl_dma_buf_entry entry; + struct gdl_dma_buf_entry *p_entry = &entry; + + /* unsigned int data_len; */ + /* unsigned int wrap_len; */ + enum GDL_RET_STATUS gdl_ret; + + ASSERT_NOT_NULL(p_entry, GDL_FAIL_ASSERT); + ASSERT_NOT_NULL(p_buf, GDL_FAIL_ASSERT); + ASSERT_NOT_ZERO(buf_len, GDL_FAIL_ASSERT); + ASSERT_NOT_NULL(p_data_len, GDL_FAIL_ASSERT); + + gdl_ret = gdl_dma_buf_get_data_entry(p_dma, p_entry); + + if (GDL_OKAY != gdl_ret) + return gdl_ret; + +#if 0 + data_len = GDL_COUNT_DATA(p_entry->read_index, + p_entry->write_index, p_entry->buf_length); + GDL_LOGD("r=%u, w=%u, l=%u, d=%u", p_entry->read_index, + p_entry->write_index, p_entry->buf_length, data_len); + + /* assert data_len > 0 */ + + if (data_len > buf_len) { + /* TODO: improve it */ + gdl_dma_buf_set_data_entry(p_dma, p_entry); + return GDL_FAIL_NOSPACE; + } + + if (p_entry->write_index > p_entry->read_index) { + memcpy(p_buf, ((unsigned char *)p_entry->vir_addr) + p_entry->read_index, + data_len); + } else { + wrap_len = p_entry->buf_length - p_entry->read_index; + + memcpy(p_buf, ((unsigned char *)p_entry->vir_addr) + p_entry->read_index, + wrap_len); + + memcpy(p_buf + wrap_len, ((unsigned char *)p_entry->vir_addr) + 0, + data_len - wrap_len); + } +#endif + gdl_ret = gdl_dma_buf_entry_to_buf(p_entry, p_buf, buf_len, p_data_len); + + if (GDL_OKAY != gdl_ret) + return gdl_ret; + + /* Todo: Case1: buf < data in entry */ + /* Note: we can limit the rx transfer max to 512, then case1 should not be happened */ + + /* Todo: Case2: buf > data in entry, need to combine multiple entry until no data entry? */ + + if (p_is_nodata) + *p_is_nodata = p_entry->is_nodata; + + /* *p_data_len = data_len; */ + p_entry->read_index = p_entry->write_index; + gdl_dma_buf_set_data_entry(p_dma, p_entry); + + return GDL_OKAY; +} + +static enum GDL_RET_STATUS gdl_dma_buf_get_data_entry_inner(struct gps_dl_dma_buf *p_dma, + struct gdl_dma_buf_entry *p_entry) +{ + struct gdl_dma_buf_entry *p_data_entry; + unsigned int data_len; + + if (p_dma->reader_working) + return GDL_FAIL_BUSY; + + p_dma->reader_working = true; + + if (p_dma->read_index == p_dma->write_index) { + p_dma->reader_working = false; + return GDL_FAIL_NODATA; + } + + if (p_dma->entry_r == p_dma->entry_w) { + /* impossible: has data but no data entry */ + p_dma->reader_working = false; + return GDL_FAIL_NOENTRY; + } + + p_data_entry = &p_dma->data_entries[p_dma->entry_r]; + p_entry->write_index = p_data_entry->write_index; + p_entry->is_nodata = p_data_entry->is_nodata; + if ((p_dma->transfer_max > 0) && (p_dma->dir == GDL_DMA_A2D)) { + data_len = GDL_COUNT_DATA(p_data_entry->read_index, + p_data_entry->write_index, p_data_entry->buf_length); + + if (data_len > p_dma->transfer_max) { + p_entry->write_index = p_data_entry->read_index + p_dma->transfer_max; + if (p_entry->write_index >= p_data_entry->buf_length) + p_entry->write_index -= p_data_entry->buf_length; + p_entry->is_nodata = false; + } + } + p_entry->read_index = p_data_entry->read_index; + p_entry->buf_length = p_data_entry->buf_length; + p_entry->phy_addr = p_data_entry->phy_addr; + p_entry->vir_addr = p_data_entry->vir_addr; + p_entry->is_valid = true; + return GDL_OKAY; +} +enum GDL_RET_STATUS gdl_dma_buf_get_data_entry(struct gps_dl_dma_buf *p_dma, + struct gdl_dma_buf_entry *p_entry) +{ + enum GDL_RET_STATUS ret; + + ASSERT_NOT_NULL(p_dma, GDL_FAIL_ASSERT); + ASSERT_NOT_NULL(p_entry, GDL_FAIL_ASSERT); + + gps_each_link_spin_lock_take(p_dma->dev_index, GPS_DL_SPINLOCK_FOR_DMA_BUF); + ret = gdl_dma_buf_get_data_entry_inner(p_dma, p_entry); + gps_each_link_spin_lock_give(p_dma->dev_index, GPS_DL_SPINLOCK_FOR_DMA_BUF); + + return ret; +} + + +static enum GDL_RET_STATUS gdl_dma_buf_set_data_entry_inner(struct gps_dl_dma_buf *p_dma, + struct gdl_dma_buf_entry *p_entry) +{ + struct gdl_dma_buf_entry *p_data_entry; + + if (!p_dma->reader_working) + return GDL_FAIL_STATE_MISMATCH; + + if (NULL == p_entry) { + p_dma->reader_working = false; + return GDL_OKAY; + } + + if (p_dma->entry_r == p_dma->entry_w) { + /* impossible due to get_data_entry already check it */ + p_dma->writer_working = false; + return GDL_FAIL_NOENTRY2; + } + + p_data_entry = &p_dma->data_entries[p_dma->entry_r]; + if (p_entry->write_index == p_data_entry->write_index) { + p_data_entry->is_valid = false; + p_dma->entry_r++; + if (p_dma->entry_r >= GPS_DL_DMA_BUF_ENTRY_MAX) + p_dma->entry_r = 0; + } else + p_data_entry->read_index = p_entry->write_index; + + p_dma->read_index = p_entry->write_index; + p_dma->reader_working = false; + return GDL_OKAY; +} + +enum GDL_RET_STATUS gdl_dma_buf_set_data_entry(struct gps_dl_dma_buf *p_dma, + struct gdl_dma_buf_entry *p_entry) +{ + enum GDL_RET_STATUS ret; + + ASSERT_NOT_NULL(p_dma, GDL_FAIL_ASSERT); + + gps_each_link_spin_lock_take(p_dma->dev_index, GPS_DL_SPINLOCK_FOR_DMA_BUF); + ret = gdl_dma_buf_set_data_entry_inner(p_dma, p_entry); + gps_each_link_spin_lock_give(p_dma->dev_index, GPS_DL_SPINLOCK_FOR_DMA_BUF); + + return ret; +} + + +static enum GDL_RET_STATUS gdl_dma_buf_get_free_entry_inner(struct gps_dl_dma_buf *p_dma, + struct gdl_dma_buf_entry *p_entry) +{ + unsigned int free_len; + + if (p_dma->writer_working) + return GDL_FAIL_BUSY; + + p_dma->writer_working = true; + + if (GDL_COUNT_FREE(p_dma->read_index, p_dma->write_index, p_dma->len) <= 1) { + /* dma buf is full */ + p_dma->writer_working = false; + return GDL_FAIL_NOSPACE; + } + + if (GDL_COUNT_FREE(p_dma->entry_r, p_dma->entry_w, GPS_DL_DMA_BUF_ENTRY_MAX) <= 1) { + /* entries is all used (not use the last one) */ + p_dma->writer_working = false; + return GDL_FAIL_NOENTRY; + } + + p_entry->read_index = p_dma->read_index; + if ((p_dma->transfer_max > 0) && (p_dma->dir == GDL_DMA_D2A)) { + /* the free space is between write_index to read_index, + * if transfer_max set and free_len > it, + * limit the free space from write_index to write_index + transfer_max + */ + free_len = GDL_COUNT_FREE(p_dma->read_index, p_dma->write_index, p_dma->len); + if (free_len > p_dma->transfer_max) { + p_entry->read_index = p_dma->write_index + p_dma->transfer_max; + if (p_entry->read_index >= p_dma->len) + p_entry->read_index -= p_dma->len; + } + } + p_entry->write_index = p_dma->write_index; + p_entry->buf_length = p_dma->len; + p_entry->phy_addr = p_dma->phy_addr; + p_entry->vir_addr = p_dma->vir_addr; + p_entry->is_valid = true; + + /* This field not used for free entry, just make static analysis tool happy. */ + p_entry->is_nodata = false; + return GDL_OKAY; +} + +enum GDL_RET_STATUS gdl_dma_buf_get_free_entry(struct gps_dl_dma_buf *p_dma, + struct gdl_dma_buf_entry *p_entry, bool nospace_set_pending_rx) +{ + enum GDL_RET_STATUS ret; + + ASSERT_NOT_NULL(p_dma, GDL_FAIL_ASSERT); + ASSERT_NOT_NULL(p_entry, GDL_FAIL_ASSERT); + + gps_each_link_spin_lock_take(p_dma->dev_index, GPS_DL_SPINLOCK_FOR_DMA_BUF); + ret = gdl_dma_buf_get_free_entry_inner(p_dma, p_entry); + if (nospace_set_pending_rx && + (ret == GDL_FAIL_NOSPACE || ret == GDL_FAIL_NOENTRY)) { + p_dma->has_pending_rx = true; + ret = GDL_FAIL_NOSPACE_PENDING_RX; + } + gps_each_link_spin_lock_give(p_dma->dev_index, GPS_DL_SPINLOCK_FOR_DMA_BUF); + + return ret; +} + +static enum GDL_RET_STATUS gdl_dma_buf_set_free_entry_inner(struct gps_dl_dma_buf *p_dma, + struct gdl_dma_buf_entry *p_entry) +{ + struct gdl_dma_buf_entry *p_data_entry; + + if (!p_dma->writer_working) + return GDL_FAIL_STATE_MISMATCH; + + if (GDL_COUNT_FREE(p_dma->entry_r, p_dma->entry_w, GPS_DL_DMA_BUF_ENTRY_MAX) <= 1) { + /* impossible due to get_free_entry already check it */ + p_dma->writer_working = false; + return GDL_FAIL_NOENTRY2; + } + + p_data_entry = &p_dma->data_entries[p_dma->entry_w]; + p_dma->entry_w++; + if (p_dma->entry_w >= GPS_DL_DMA_BUF_ENTRY_MAX) + p_dma->entry_w = 0; + + p_data_entry->read_index = p_dma->write_index; + p_data_entry->write_index = p_entry->write_index; + p_data_entry->buf_length = p_dma->len; + p_data_entry->phy_addr = p_dma->phy_addr; + p_data_entry->vir_addr = p_dma->vir_addr; + p_data_entry->is_valid = true; + p_data_entry->is_nodata = p_entry->is_nodata; + + p_dma->write_index = p_entry->write_index; + p_dma->writer_working = false; + + return GDL_OKAY; +} + +enum GDL_RET_STATUS gdl_dma_buf_set_free_entry(struct gps_dl_dma_buf *p_dma, + struct gdl_dma_buf_entry *p_entry) +{ + enum GDL_RET_STATUS ret; + + ASSERT_NOT_NULL(p_dma, GDL_FAIL_ASSERT); + ASSERT_NOT_NULL(p_entry, GDL_FAIL_ASSERT); + + gps_each_link_spin_lock_take(p_dma->dev_index, GPS_DL_SPINLOCK_FOR_DMA_BUF); + ret = gdl_dma_buf_set_free_entry_inner(p_dma, p_entry); + gps_each_link_spin_lock_give(p_dma->dev_index, GPS_DL_SPINLOCK_FOR_DMA_BUF); + + return ret; +} + + +void gps_dma_buf_memcpy_from_rx(void *p_dst, const void *p_src, unsigned int len) +{ + /* TODO: + * __dma_unmap_area((void *)p_dst, len, DMA_FROM_DEVICE); + * dma_sync_single_for_cpu(DMA_FROM_DEVICE); + */ +#if GPS_DL_ON_LINUX + memcpy_fromio(p_dst, p_src, len); +#elif GPS_DL_ON_CTP + /* gps_dl_ctp_memcpy((unsigned char *)p_dst, (const unsigned char *)p_src, len); */ + memcpy(p_dst, p_src, len); +#else + memcpy(p_dst, p_src, len); +#endif +} + +void gps_dma_buf_memcpy_to_tx(void *p_dst, const void *p_src, unsigned int len) +{ +#if GPS_DL_ON_LINUX + memcpy_toio(p_dst, p_src, len); +#elif GPS_DL_ON_CTP + /* gps_dl_ctp_memcpy((unsigned char *)p_dst, (const unsigned char *)p_src, len); */ + memcpy(p_dst, p_src, len); +#else + memcpy(p_dst, p_src, len); +#endif + /* Use mb to make sure memcpy is done by CPU, and then DMA can be started. */ + mb(); + /* TODO: + * __dma_flush_area((void *)p_dst, len); + * dma_sync_single_for_device(DMA_TO_DEVICE); + */ +} + +void gps_dma_buf_memset_io(void *p_dst, unsigned char val, unsigned int len) +{ +#if GPS_DL_ON_LINUX + memset_io(p_dst, val, len); +#elif GPS_DL_ON_CTP + gps_dl_ctp_memset((unsigned char *)p_dst, val, len); +#else + memset(p_dst, val, len); +#endif + /* Use mb to make sure memcpy is done by CPU, and then DMA can be started. */ + mb(); + /* TODO: + * __dma_flush_area((void *)p_dst, len); + * dma_sync_single_for_device(DMA_TO_DEVICE); + */ +} + +enum GDL_RET_STATUS gdl_dma_buf_entry_to_buf(const struct gdl_dma_buf_entry *p_entry, + unsigned char *p_buf, unsigned int buf_len, unsigned int *p_data_len) +{ + unsigned int data_len; + unsigned int wrap_len; + unsigned char *p_src; + + ASSERT_NOT_NULL(p_entry, GDL_FAIL_ASSERT); + ASSERT_NOT_NULL(p_buf, GDL_FAIL_ASSERT); + ASSERT_NOT_ZERO(buf_len, GDL_FAIL_ASSERT); + ASSERT_NOT_NULL(p_data_len, GDL_FAIL_ASSERT); + + data_len = GDL_COUNT_DATA(p_entry->read_index, + p_entry->write_index, p_entry->buf_length); + GDL_LOGD("r=%u, w=%u, l=%u, d=%u", p_entry->read_index, + p_entry->write_index, p_entry->buf_length, data_len); + + if (data_len > buf_len) { + *p_data_len = 0; + return GDL_FAIL_NOSPACE; + } + + if (p_entry->write_index > p_entry->read_index) { + p_src = ((unsigned char *)p_entry->vir_addr) + p_entry->read_index; + gps_dma_buf_memcpy_from_rx(p_buf, p_src, data_len); + } else { + wrap_len = p_entry->buf_length - p_entry->read_index; + + p_src = ((unsigned char *)p_entry->vir_addr) + p_entry->read_index; + gps_dma_buf_memcpy_from_rx(p_buf, p_src, wrap_len); + + p_src = ((unsigned char *)p_entry->vir_addr) + 0; + gps_dma_buf_memcpy_from_rx(p_buf + wrap_len, p_src, data_len - wrap_len); + } + + *p_data_len = data_len; + return GDL_OKAY; +} + +enum GDL_RET_STATUS gdl_dma_buf_buf_to_entry(const struct gdl_dma_buf_entry *p_entry, + const unsigned char *p_buf, unsigned int data_len, unsigned int *p_write_index) +{ + unsigned int free_len; + unsigned int wrap_len; + unsigned int write_index; + unsigned int alligned_data_len; + unsigned int fill_zero_len; + unsigned char *p_dst; + + if (gps_dl_is_1byte_mode()) { + alligned_data_len = data_len; + fill_zero_len = 0; + } else { + alligned_data_len = ((data_len + 3) / 4) * 4; + fill_zero_len = alligned_data_len - data_len; + GDL_LOGD("data_len = %u, alligned = %u", data_len, alligned_data_len); + } + + ASSERT_NOT_NULL(p_entry, GDL_FAIL_ASSERT); + ASSERT_NOT_NULL(p_buf, GDL_FAIL_ASSERT); + ASSERT_NOT_ZERO(data_len, GDL_FAIL_ASSERT); + ASSERT_NOT_NULL(p_write_index, GDL_FAIL_ASSERT); + + /* TODO: make dma done event */ + + free_len = GDL_COUNT_FREE(p_entry->read_index, + p_entry->write_index, p_entry->buf_length); + + GDL_LOGD("r=%u, w=%u, l=%u, f=%u", p_entry->read_index, + p_entry->write_index, p_entry->buf_length, free_len); + + if (free_len < alligned_data_len) + return GDL_FAIL_NOSPACE; + + wrap_len = p_entry->buf_length - p_entry->write_index; + if (wrap_len >= data_len) { + p_dst = ((unsigned char *)p_entry->vir_addr) + p_entry->write_index; + gps_dma_buf_memcpy_to_tx(p_dst, p_buf, data_len); + + write_index = p_entry->write_index + data_len; + if (write_index >= p_entry->buf_length) + write_index = 0; + } else { + p_dst = ((unsigned char *)p_entry->vir_addr) + p_entry->write_index; + gps_dma_buf_memcpy_to_tx(p_dst, p_buf, wrap_len); + + p_dst = ((unsigned char *)p_entry->vir_addr) + 0; + gps_dma_buf_memcpy_to_tx(p_dst, p_buf + wrap_len, data_len - wrap_len); + + write_index = data_len - wrap_len; + } + + /* fill it to allignment */ + if (fill_zero_len > 0) { + wrap_len = p_entry->buf_length - write_index; + if (wrap_len >= fill_zero_len) { + p_dst = ((unsigned char *)p_entry->vir_addr) + write_index; + gps_dma_buf_memset_io(p_dst, 0, fill_zero_len); + + write_index += fill_zero_len; + if (write_index >= p_entry->buf_length) + write_index = 0; + } else { + /* impossible case when buf_len is an integral multiple of 4byte */ + p_dst = ((unsigned char *)p_entry->vir_addr) + write_index; + gps_dma_buf_memset_io(p_dst, 0, wrap_len); + + p_dst = ((unsigned char *)p_entry->vir_addr) + 0; + gps_dma_buf_memset_io(p_dst, 0, fill_zero_len - wrap_len); + + write_index = fill_zero_len - wrap_len; + } + } + + GDL_LOGD("new_w=%u", write_index); + *p_write_index = write_index; + + return GDL_OKAY; +} + +enum GDL_RET_STATUS gdl_dma_buf_entry_to_transfer( + const struct gdl_dma_buf_entry *p_entry, + struct gdl_hw_dma_transfer *p_transfer, bool is_tx) +{ + ASSERT_NOT_NULL(p_entry, GDL_FAIL_ASSERT); + ASSERT_NOT_NULL(p_transfer, GDL_FAIL_ASSERT); + + p_transfer->buf_start_addr = (unsigned int)p_entry->phy_addr; + if (is_tx) { + p_transfer->transfer_start_addr = + (unsigned int)p_entry->phy_addr + p_entry->read_index; + p_transfer->len_to_wrap = p_entry->buf_length - p_entry->read_index; + p_transfer->transfer_max_len = GDL_COUNT_DATA( + p_entry->read_index, p_entry->write_index, p_entry->buf_length); + + if (!gps_dl_is_1byte_mode()) { + p_transfer->len_to_wrap /= 4; + p_transfer->transfer_max_len /= 4; + } + } else { + p_transfer->transfer_start_addr = + (unsigned int)p_entry->phy_addr + p_entry->write_index; + p_transfer->len_to_wrap = p_entry->buf_length - p_entry->write_index; + p_transfer->transfer_max_len = GDL_COUNT_FREE( + p_entry->read_index, p_entry->write_index, p_entry->buf_length); + + if (!gps_dl_is_1byte_mode()) { + p_transfer->len_to_wrap /= 4; + p_transfer->transfer_max_len /= 4; + } + } + + GDL_LOGD("r=%u, w=%u, l=%u, is_tx=%d, transfer: ba=0x%08x, ta=0x%08x, wl=%d, tl=%d", + p_entry->read_index, p_entry->write_index, p_entry->buf_length, is_tx, + p_transfer->buf_start_addr, p_transfer->buf_start_addr, + p_transfer->len_to_wrap, p_transfer->transfer_max_len); + + ASSERT_NOT_ZERO(p_transfer->buf_start_addr, GDL_FAIL_ASSERT); + ASSERT_NOT_ZERO(p_transfer->transfer_start_addr, GDL_FAIL_ASSERT); + ASSERT_NOT_ZERO(p_transfer->len_to_wrap, GDL_FAIL_ASSERT); + ASSERT_NOT_ZERO(p_transfer->transfer_max_len, GDL_FAIL_ASSERT); + + return GDL_OKAY; +} + +enum GDL_RET_STATUS gdl_dma_buf_entry_transfer_left_to_write_index( + const struct gdl_dma_buf_entry *p_entry, + unsigned int left_len, unsigned int *p_write_index) +{ + unsigned int free_len; + unsigned int new_write_index; + + ASSERT_NOT_NULL(p_entry, GDL_FAIL_ASSERT); + ASSERT_NOT_NULL(p_write_index, GDL_FAIL_ASSERT); + + free_len = GDL_COUNT_FREE(p_entry->read_index, + p_entry->write_index, p_entry->buf_length); + + GDL_ASSERT(free_len > left_len, GDL_FAIL_ASSERT, ""); + + new_write_index = p_entry->write_index + free_len - left_len; + if (new_write_index >= p_entry->buf_length) + new_write_index -= p_entry->buf_length; + + GDL_LOGD("r=%u, w=%u, l=%u, left=%d, new_w=%d", + p_entry->read_index, p_entry->write_index, p_entry->buf_length, + left_len, new_write_index); + GDL_ASSERT(new_write_index < p_entry->buf_length, GDL_FAIL_ASSERT, ""); + + *p_write_index = new_write_index; + + return GDL_OKAY; +} + + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/lib/gps_dl_hist_rec.c b/drivers/misc/mediatek/connectivity/gps/data_link/lib/gps_dl_hist_rec.c new file mode 100644 index 0000000000000000000000000000000000000000..03068ac9954c5fc8d9e9fb1a8b29293b86017f1d --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/lib/gps_dl_hist_rec.c @@ -0,0 +1,159 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include "gps_dl_config.h" + +#include "gps_each_link.h" +#include "gps_dl_osal.h" +#include "gps_dl_hist_rec.h" + +enum gps_dl_hist_rec_rw_type { + GPS_DL_HIST_REC_RW_READ, + GPS_DL_HIST_REC_RW_WRITE, + GPS_DL_HIST_REC_RW_TYPE_MAX +}; + +enum gps_dl_hist_rec_rw_dump_point { + GPS_DL_HIST_REC_RW_DUMP_ON_REC_FULL, + GPS_DL_HIST_REC_RW_DUMP_ON_INTERVAL, + GPS_DL_HIST_REC_RW_DUMP_ON_PID_CHANGED, + GPS_DL_HIST_REC_RW_DUMP_ON_FORCE_DUMP, + GPS_DL_HIST_REC_RW_DUMP_ON_ERROR_LEN, +}; + +struct gps_dl_hist_rec_rw_item { + int len; +}; + +#define GPS_DL_HIST_REC_RW_ITEM_MAX (8) +struct gps_dl_hist_rec_rw_list { + struct gps_dl_hist_rec_rw_item items[GPS_DL_HIST_REC_RW_ITEM_MAX]; + unsigned int n_item; + unsigned int rec_idx; + int pid; + enum gps_dl_hist_rec_rw_rec_point rec_point; + enum gps_dl_hist_rec_rw_type type; +}; + +struct gps_dl_hist_rec_rw_list g_gps_dl_hist_rec_rw_list[GPS_DATA_LINK_NUM][GPS_DL_HIST_REC_RW_TYPE_MAX]; + + +static void gps_dl_hist_rec_rw_do_dump(enum gps_dl_link_id_enum link_id, + struct gps_dl_hist_rec_rw_list *p_list, enum gps_dl_hist_rec_rw_dump_point dump_point) +{ + GDL_LOGXW_DRW(link_id, "%s: dp=%d, pid=%d, i=%d, n=%d(%d), l=%d %d %d %d; %d %d %d %d", + (p_list->type == GPS_DL_HIST_REC_RW_READ) ? "rd" : "wr", + dump_point, p_list->pid, p_list->rec_idx, p_list->n_item, p_list->rec_point, + p_list->items[0].len, p_list->items[1].len, p_list->items[2].len, p_list->items[3].len, + p_list->items[4].len, p_list->items[5].len, p_list->items[6].len, p_list->items[7].len); + p_list->rec_idx += p_list->n_item; + p_list->n_item = 0; + memset(&p_list->items, 0, sizeof(p_list->items)); +} + +static void gps_dl_hist_rec_rw_check_dump(enum gps_dl_link_id_enum link_id, + struct gps_dl_hist_rec_rw_list *p_list, enum gps_dl_hist_rec_rw_rec_point rec_point) +{ + if (p_list->n_item > GPS_DL_HIST_REC_RW_ITEM_MAX) { + GDL_LOGXE_DRW(link_id, "type=%d, n_rec=%d, rec_point=%d", + p_list->type, p_list->n_item, rec_point); + p_list->n_item = GPS_DL_HIST_REC_RW_ITEM_MAX; + } + + if (p_list->n_item == GPS_DL_HIST_REC_RW_ITEM_MAX) + gps_dl_hist_rec_rw_do_dump(link_id, p_list, GPS_DL_HIST_REC_RW_DUMP_ON_REC_FULL); +} + +static void gps_dl_hist_rec_rw_add_rec(enum gps_dl_link_id_enum link_id, + enum gps_dl_hist_rec_rw_type type, + enum gps_dl_hist_rec_rw_rec_point rec_point, + int pid, int len) +{ + struct gps_dl_hist_rec_rw_list *p_list; + struct gps_dl_hist_rec_rw_item *p_item; + enum gps_dl_hist_rec_rw_rec_point last_point; + + ASSERT_LINK_ID(link_id, GDL_VOIDF()); + /* TODO: check type & rec_point */ + + /* TODO: protect it by lock */ + p_list = &g_gps_dl_hist_rec_rw_list[link_id][type]; + if (p_list->pid == 0) + p_list->pid = pid; + else if (pid != p_list->pid && rec_point == DRW_RETURN) { + gps_dl_hist_rec_rw_do_dump(link_id, p_list, GPS_DL_HIST_REC_RW_DUMP_ON_PID_CHANGED); + p_list->pid = pid; + } + gps_dl_hist_rec_rw_check_dump(link_id, p_list, rec_point); + + p_item = &p_list->items[p_list->n_item]; + last_point = p_list->rec_point; + p_list->rec_point = rec_point; + + if (last_point == DRW_RETURN && rec_point == DRW_ENTER) { + /* TODO: record tiemstamp */ + p_item->len = len; + } else if (last_point == DRW_ENTER && rec_point == DRW_RETURN) { + p_item->len = len; + p_list->n_item++; + if (len <= 0) + gps_dl_hist_rec_rw_do_dump(link_id, p_list, GPS_DL_HIST_REC_RW_DUMP_ON_PID_CHANGED); + else + gps_dl_hist_rec_rw_check_dump(link_id, p_list, DRW_RETURN); + } else { + GDL_LOGXE_DRW(link_id, "type=%d, n_rec=%d, mismatch rec_point=%d/%d, len=%d, pid=%d", + p_list->type, p_list->n_item, last_point, rec_point, len, pid); + } +} + + +void gps_each_link_rec_read(enum gps_dl_link_id_enum link_id, int pid, int len, + enum gps_dl_hist_rec_rw_rec_point rec_point) +{ + ASSERT_LINK_ID(link_id, GDL_VOIDF()); + gps_each_link_mutex_take(link_id, GPS_DL_MTX_BIG_LOCK); + gps_dl_hist_rec_rw_add_rec(link_id, GPS_DL_HIST_REC_RW_READ, rec_point, pid, len); + gps_each_link_mutex_give(link_id, GPS_DL_MTX_BIG_LOCK); +} + +void gps_each_link_rec_write(enum gps_dl_link_id_enum link_id, int pid, int len, + enum gps_dl_hist_rec_rw_rec_point rec_point) +{ + ASSERT_LINK_ID(link_id, GDL_VOIDF()); + gps_each_link_mutex_take(link_id, GPS_DL_MTX_BIG_LOCK); + gps_dl_hist_rec_rw_add_rec(link_id, GPS_DL_HIST_REC_RW_WRITE, rec_point, pid, len); + gps_each_link_mutex_give(link_id, GPS_DL_MTX_BIG_LOCK); +} + +void gps_each_link_rec_reset(enum gps_dl_link_id_enum link_id) +{ + enum gps_dl_hist_rec_rw_type type; + struct gps_dl_hist_rec_rw_list *p_list; + + ASSERT_LINK_ID(link_id, GDL_VOIDF()); + gps_each_link_mutex_take(link_id, GPS_DL_MTX_BIG_LOCK); + for (type = 0; type < GPS_DL_HIST_REC_RW_TYPE_MAX; type++) { + p_list = &g_gps_dl_hist_rec_rw_list[link_id][type]; + memset(p_list, 0, sizeof(*p_list)); + p_list->type = type; + p_list->rec_point = DRW_RETURN; + } + gps_each_link_mutex_give(link_id, GPS_DL_MTX_BIG_LOCK); +} + +void gps_each_link_rec_force_dump(enum gps_dl_link_id_enum link_id) +{ + enum gps_dl_hist_rec_rw_type type; + struct gps_dl_hist_rec_rw_list *p_list; + + ASSERT_LINK_ID(link_id, GDL_VOIDF()); + gps_each_link_mutex_take(link_id, GPS_DL_MTX_BIG_LOCK); + for (type = 0; type < GPS_DL_HIST_REC_RW_TYPE_MAX; type++) { + p_list = &g_gps_dl_hist_rec_rw_list[link_id][type]; + gps_dl_hist_rec_rw_do_dump(link_id, p_list, GPS_DL_HIST_REC_RW_DUMP_ON_FORCE_DUMP); + } + gps_each_link_mutex_give(link_id, GPS_DL_MTX_BIG_LOCK); +} + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/lib/gps_dl_lib_misc.c b/drivers/misc/mediatek/connectivity/gps/data_link/lib/gps_dl_lib_misc.c new file mode 100644 index 0000000000000000000000000000000000000000..7f1f00c15424249a1462baaa0cd1c8f424dab3d9 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/lib/gps_dl_lib_misc.c @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#include "gps_dl_lib_misc.h" +#include "gps_dl_log.h" + +bool gps_dl_hal_comp_buf_match(unsigned char *data_buf, unsigned int data_len, + unsigned char *golden_buf, unsigned int golden_len, unsigned int data_shift) { + bool is_match = true; + + int i; + + if (data_len < golden_len + data_shift) { + GDL_LOGD("not match len: %d, %d, %d", data_len, golden_len, data_shift); + is_match = false; + } + + if (is_match) { + for (i = 0; i < data_shift; i++) { + if (data_buf[i] != 0) { + GDL_LOGD("not fill 0 on start %d: %x", i, data_buf[i]); + is_match = false; + break; + } + } + } + + if (is_match) { + for (; i < data_shift + golden_len; i++) { + if (data_buf[i] != golden_buf[i - data_shift]) { + GDL_LOGD("not match on data[%d] -> %x, gold[%d] -> %x", + i, data_buf[i], i - data_shift, golden_buf[i - data_shift]); + is_match = false; + break; + } + } + } + + if (is_match) { + for (; i < data_len; i++) { + if (data_buf[i] != 0) { + GDL_LOGD("not fill 0 on end %d: %x", i, data_buf[i]); + is_match = false; + break; + } + } + } + + GDL_LOGD("match = %d, data_len = %d, golden_len = %d, data_shift = %d", + is_match, data_len, golden_len, data_shift); + + if (!is_match) { + gps_dl_hal_show_buf("data", data_buf, data_len); + gps_dl_hal_show_buf("golden", golden_buf, golden_len); + } + + return is_match; +} + +#define SHOW_BUF_MAX_LINE 2 +void gps_dl_hal_show_buf(unsigned char *tag, + unsigned char *buf, unsigned int len) +{ + int base = 0, line_idx = 0; + int line_len = 8; + int left_len = len; +#define SHOW_BUF_FMT0 "[%s] len = %u" +#define SHOW_BUF_FMT1 SHOW_BUF_FMT0", data = %02x" +#define SHOW_BUF_FMT2 SHOW_BUF_FMT1" %02x" +#define SHOW_BUF_FMT3 SHOW_BUF_FMT2" %02x" +#define SHOW_BUF_FMT4 SHOW_BUF_FMT3" %02x" +#define SHOW_BUF_FMT5 SHOW_BUF_FMT4", %02x" +#define SHOW_BUF_FMT6 SHOW_BUF_FMT5" %02x" +#define SHOW_BUF_FMT7 SHOW_BUF_FMT6" %02x" +#define SHOW_BUF_FMT8 SHOW_BUF_FMT7" %02x" + +#define SHOW_BUF_ARG0 do {GDL_LOGI_DRW(SHOW_BUF_FMT0, tag, len); } while (0) + +#define SHOW_BUF_ARG1 do {GDL_LOGI_DRW(SHOW_BUF_FMT1, tag, len, buf[base+0]); } while (0) + +#define SHOW_BUF_ARG2 do {GDL_LOGI_DRW(SHOW_BUF_FMT2, tag, len, buf[base+0], buf[base+1]); } while (0) + +#define SHOW_BUF_ARG3 do {GDL_LOGI_DRW(SHOW_BUF_FMT3, tag, len, buf[base+0], buf[base+1], buf[base+2]) \ + ; } while (0) + +#define SHOW_BUF_ARG4 do {GDL_LOGI_DRW(SHOW_BUF_FMT4, tag, len, buf[base+0], buf[base+1], buf[base+2], \ + buf[base+3]); } while (0) + +#define SHOW_BUF_ARG5 do {GDL_LOGI_DRW(SHOW_BUF_FMT5, tag, len, buf[base+0], buf[base+1], buf[base+2], \ + buf[base+3], buf[base+4]); } while (0) + +#define SHOW_BUF_ARG6 do {GDL_LOGI_DRW(SHOW_BUF_FMT6, tag, len, buf[base+0], buf[base+1], buf[base+2], \ + buf[base+3], buf[base+4], buf[base+5]); } while (0) + +#define SHOW_BUF_ARG7 do {GDL_LOGI_DRW(SHOW_BUF_FMT7, tag, len, buf[base+0], buf[base+1], buf[base+2], \ + buf[base+3], buf[base+4], buf[base+5], buf[base+6]); } while (0) + +#define SHOW_BUF_ARG8 do {GDL_LOGI_DRW(SHOW_BUF_FMT8, tag, len, buf[base+0], buf[base+1], buf[base+2], \ + buf[base+3], buf[base+4], buf[base+5], buf[base+6], buf[base+7]); } while (0) + + for (left_len = len, base = 0, line_idx = 0; + left_len > 0 && line_idx < SHOW_BUF_MAX_LINE; + left_len -= 8, base += 8, line_idx++) { + + if (left_len > 8) + line_len = 8; + else + line_len = left_len; + + switch (line_len) { +#if 0 + /* case 0 is impossible */ + case 0: + SHOW_BUF_ARG0; break; +#endif + case 1: + SHOW_BUF_ARG1; break; + case 2: + SHOW_BUF_ARG2; break; + case 3: + SHOW_BUF_ARG3; break; + case 4: + SHOW_BUF_ARG4; break; + case 5: + SHOW_BUF_ARG5; break; + case 6: + SHOW_BUF_ARG6; break; + case 7: + SHOW_BUF_ARG7; break; + default: + SHOW_BUF_ARG8; break; + } + } +} + +void GDL_VOIDF(void) {} + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/lib/gps_dl_name_list.c b/drivers/misc/mediatek/connectivity/gps/data_link/lib/gps_dl_name_list.c new file mode 100644 index 0000000000000000000000000000000000000000..b22a25baa849188e9091204b77a2dc9e5c50b888 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/lib/gps_dl_name_list.c @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#include "gps_dl_config.h" + +#include "gps_dl_base.h" +#include "gps_dl_name_list.h" + +#if GPS_DL_ON_LINUX +/* Make sure num for RETURN_NAME_IN_LIST is const to detect coding error such + * as swapping the position of num and index. + * MASK_BE_CONST can be empty if compiler not support the macros used. + */ +#define MUST_BE_CONST(num) BUILD_BUG_ON(!__builtin_constant_p(num)) +#else +#define MUST_BE_CONST(num) +#endif +#define NAME_ON_NULL "(NULL)" +#define RETURN_NAME_IN_LIST(list, num, index, retval) \ + do { \ + MUST_BE_CONST(num); \ + if (((index) >= 0) && ((index) < (num))) { \ + if ((list)[index]) \ + retval = (list)[index]; \ + else { \ + GDL_LOGW("name is null for index: %d", index); \ + retval = NAME_ON_NULL; \ + } \ + } else { \ + GDL_LOGW("name index: %d out of range", index); \ + retval = (list)[num]; \ + } \ + } while (0) + + +const char *const gps_dl_ret_name_list[GDL_RET_NUM + 1] = { + [GDL_OKAY] = "OKAY", + [GDL_FAIL] = "FAIL_GENERAL", + [GDL_FAIL_ASSERT] = "FAIL_ASSERT", + [GDL_FAIL_BUSY] = "FAIL_BUSY", + [GDL_FAIL_NOSPACE] = "FAIL_NOSPACE", + [GDL_FAIL_NOSPACE_PENDING_RX] = "FAIL_NOSPACE_PENDING_RX", + [GDL_FAIL_NODATA] = "FAIL_NODATA", + [GDL_FAIL_STATE_MISMATCH] = "FAIL_STATE_MISMATCH", + [GDL_FAIL_SIGNALED] = "FAIL_SIGNALED", + [GDL_FAIL_TIMEOUT] = "FAIL_TIMEOUT", + [GDL_FAIL_NOT_SUPPORT] = "FAIL_NOT_SUPPORT", + [GDL_FAIL_INVAL] = "FAIL_INVAL", + [GDL_FAIL_NOENTRY] = "FAIL_NOENTRY", + [GDL_FAIL_NOENTRY2] = "FAIL_NOENTRY2", + [GDL_FAIL_CONN_NOT_OKAY] = "FAIL_CONN_NOT_OKAY", + [GDL_RET_NUM] = "FAIL_UNKNOWN" +}; + +const char *gdl_ret_to_name(enum GDL_RET_STATUS gdl_ret) +{ + const char *retval; + + RETURN_NAME_IN_LIST(gps_dl_ret_name_list, GDL_RET_NUM, gdl_ret, retval); + return retval; +} + + +const char *const gps_dl_dsp_state_name_list[GPS_DSP_ST_MAX + 1] = { + [GPS_DSP_ST_OFF] = "OFF ", + [GPS_DSP_ST_TURNED_ON] = "ON ", + [GPS_DSP_ST_RESET_DONE] = "RST ", + [GPS_DSP_ST_WORKING] = "WORK", + [GPS_DSP_ST_HW_SLEEP_MODE] = "SLP ", + [GPS_DSP_ST_HW_STOP_MODE] = "STOP", + [GPS_DSP_ST_WAKEN_UP] = "WAKE", + [GPS_DSP_ST_MAX] = "UNKN" +}; + +const char *gps_dl_dsp_state_name(enum gps_dsp_state_t state) +{ + const char *retval; + + RETURN_NAME_IN_LIST(gps_dl_dsp_state_name_list, GPS_DSP_ST_MAX, state, retval); + return retval; +} + + +const char *const gps_dl_dsp_event_name_list[GPS_DSP_EVT_MAX + 1] = { + [GPS_DSP_EVT_FUNC_OFF] = "FUNC_OFF", + [GPS_DSP_EVT_FUNC_ON] = "FUNC_ON ", + [GPS_DSP_EVT_RESET_DONE] = "RST_DONE", + [GPS_DSP_EVT_RAM_CODE_READY] = "RAM_OKAY", + [GPS_DSP_EVT_CTRL_TIMER_EXPIRE] = "TIMEOUT ", + [GPS_DSP_EVT_HW_SLEEP_REQ] = "SLP_REQ ", + [GPS_DSP_EVT_HW_SLEEP_EXIT] = "SLP_WAK ", + [GPS_DSP_EVT_HW_STOP_REQ] = "STOP_REQ", + [GPS_DSP_EVT_HW_STOP_EXIT] = "STOP_WAK", + [GPS_DSP_EVT_MAX] = "UNKNOWN " +}; + +const char *gps_dl_dsp_event_name(enum gps_dsp_event_t event) +{ + const char *retval; + + RETURN_NAME_IN_LIST(gps_dl_dsp_event_name_list, GPS_DSP_EVT_MAX, event, retval); + return retval; +} + + +const char * const gps_dl_link_state_name_list[LINK_STATE_NUM + 1] = { + [LINK_UNINIT] = "UNINIT", + [LINK_CLOSED] = "CLOSED", + [LINK_OPENING] = "OPENING", + [LINK_OPENED] = "OPENED", + [LINK_CLOSING] = "CLOSING", + [LINK_RESETTING] = "RESETTING", + [LINK_RESET_DONE] = "RESET_DONE", + [LINK_DISABLED] = "DISABLED", + [LINK_SUSPENDING] = "SUSPNEDING", + [LINK_SUSPENDED] = "SUSPENDED", + [LINK_RESUMING] = "RESUMING", + /* [LNK_INIT_FAIL] = "INIT_FAIL", */ + [LINK_STATE_NUM] = "INVALID" +}; + +const char *gps_dl_link_state_name(enum gps_each_link_state_enum state) +{ + const char *retval; + + RETURN_NAME_IN_LIST(gps_dl_link_state_name_list, LINK_STATE_NUM, state, retval); + return retval; +} + + +const char *const gps_dl_link_event_name_list[GPS_DL_LINK_EVT_NUM + 1] = { + [GPS_DL_EVT_LINK_OPEN] = "LINK_OPEN", + [GPS_DL_EVT_LINK_CLOSE] = "LINK_CLOSE", + [GPS_DL_EVT_LINK_WRITE] = "LINK_WRITE", + [GPS_DL_EVT_LINK_READ] = "LINK_READ", + [GPS_DL_EVT_LINK_DSP_ROM_READY_TIMEOUT] = "ROM_READY_TIMEOUT", + [GPS_DL_EVT_LINK_DSP_FSM_TIMEOUT] = "DSP_FSM_TIMEOUT", + [GPS_DL_EVT_LINK_RESET_DSP] = "RESET_DSP", + [GPS_DL_EVT_LINK_RESET_GPS] = "RESET_GPS", + [GPS_DL_EVT_LINK_PRE_CONN_RESET] = "PRE_CONN_RESET", + [GPS_DL_EVT_LINK_POST_CONN_RESET] = "POST_CONN_RESET", + [GPS_DL_EVT_LINK_PRINT_HW_STATUS] = "PRINT_HW_STATUS", + [GPS_DL_EVT_LINK_ENTER_DPSLEEP] = "ENTER_DPSLEEP", + [GPS_DL_EVT_LINK_LEAVE_DPSLEEP] = "LEAVE_DPSLEEP", + [GPS_DL_EVT_LINK_ENTER_DPSTOP] = "ENTER_DPSTOP", + [GPS_DL_EVT_LINK_LEAVE_DPSTOP] = "LEAVE_DPSTOP", + [GPS_DL_EVT_LINK_PRINT_DATA_STATUS] = "PRINT_DATA_STATUS", + [GPS_DL_LINK_EVT_NUM] = "LINK_INVALID_EVT" +}; + +const char *gps_dl_link_event_name(enum gps_dl_link_event_id event) +{ + const char *retval; + + RETURN_NAME_IN_LIST(gps_dl_link_event_name_list, GPS_DL_LINK_EVT_NUM, event, retval); + return retval; +} + +const char *gps_dl_hal_event_name_list[GPD_DL_HAL_EVT_NUM + 1] = { + [GPS_DL_HAL_EVT_A2D_TX_DMA_DONE] = "HAL_TX_DMA_DONE", + [GPS_DL_HAL_EVT_D2A_RX_HAS_DATA] = "HAL_RX_HAS_DATA", + [GPS_DL_HAL_EVT_D2A_RX_HAS_NODATA] = "HAL_RX_HAS_NODATA", + [GPS_DL_HAL_EVT_D2A_RX_DMA_DONE] = "HAL_RX_DMA_DONE", + [GPS_DL_HAL_EVT_MCUB_HAS_IRQ] = "HAL_MCUB_HAS_FLAG", + [GPS_DL_HAL_EVT_DMA_ISR_PENDING] = "HAL_DMA_ISR_PENDING", + [GPD_DL_HAL_EVT_NUM] = "HAL_INVALID_EVT", +}; + +const char *gps_dl_hal_event_name(enum gps_dl_hal_event_id event) +{ + const char *retval; + + RETURN_NAME_IN_LIST(gps_dl_hal_event_name_list, GPD_DL_HAL_EVT_NUM, event, retval); + return retval; +} + +const char *const gps_dl_waitable_name_list[GPS_DL_WAIT_NUM + 1] = { + [GPS_DL_WAIT_OPEN_CLOSE] = "OPEN_OR_CLOSE", + [GPS_DL_WAIT_WRITE] = "WRITE", + [GPS_DL_WAIT_READ] = "READ", + [GPS_DL_WAIT_RESET] = "RESET", + [GPS_DL_WAIT_NUM] = "INVALID" +}; + +const char *gps_dl_waitable_type_name(enum gps_each_link_waitable_type type) +{ + const char *retval; + + RETURN_NAME_IN_LIST(gps_dl_waitable_name_list, GPS_DL_WAIT_NUM, type, retval); + return retval; +} + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/lib/gps_dl_time_tick.c b/drivers/misc/mediatek/connectivity/gps/data_link/lib/gps_dl_time_tick.c new file mode 100644 index 0000000000000000000000000000000000000000..7b6a20d2c0bb97c18ac127f9ae9ffce8a0430655 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/lib/gps_dl_time_tick.c @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#include "gps_dl_config.h" +#include "gps_dl_time_tick.h" + +#if GPS_DL_ON_LINUX +#include +#include +#elif GPS_DL_ON_CTP +#include "kernel_to_ctp.h" +#endif + +void gps_dl_wait_us(unsigned int us) +{ +#if GPS_DL_ON_LINUX + udelay(us); +#elif GPS_DL_ON_CTP + udelay(us); /* GPT_Delay_us(us); */ +#endif +} + +unsigned long gps_dl_tick_get(void) +{ +#if GPS_DL_ON_LINUX + return jiffies; +#elif GPS_DL_ON_CTP + return GPT_GetTickCount(0); +#else + return 0; +#endif +} + +int gps_dl_tick_delta_to_usec(unsigned int tick0, unsigned int tick1) +{ +#if GPS_DL_ON_LINUX + return (int)((tick1 - tick0) * 1000 * 1000 / HZ); +#elif GPS_DL_ON_CTP + return (int)((tick1 - tick0) / 13); +#else + return 0; +#endif +} + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/lib/inc/gps_dl_base.h b/drivers/misc/mediatek/connectivity/gps/data_link/lib/inc/gps_dl_base.h new file mode 100644 index 0000000000000000000000000000000000000000..79e079d942af465d719c2b0321f079cf776a3e94 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/lib/inc/gps_dl_base.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#ifndef _GPS_DL_BASE_H +#define _GPS_DL_BASE_H + +enum GDL_RET_STATUS { + GDL_OKAY = 0, + GDL_FAIL, /* general fail */ + GDL_FAIL_ASSERT, + GDL_FAIL_BUSY, + GDL_FAIL_NOSPACE, + GDL_FAIL_NODATA, + GDL_FAIL_STATE_MISMATCH, + GDL_FAIL_SIGNALED, + GDL_FAIL_TIMEOUT, + GDL_FAIL_NOT_SUPPORT, + GDL_FAIL_INVAL, + GDL_FAIL_NOSPACE_PENDING_RX, + GDL_FAIL_NOENTRY, + GDL_FAIL_NOENTRY2, + GDL_FAIL_CONN_NOT_OKAY, + GDL_RET_NUM, +}; + +const char *gdl_ret_to_name(enum GDL_RET_STATUS gdl_ret); + +#endif /* _GPS_DL_BASE_H */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/lib/inc/gps_dl_dma_buf.h b/drivers/misc/mediatek/connectivity/gps/data_link/lib/inc/gps_dl_dma_buf.h new file mode 100644 index 0000000000000000000000000000000000000000..b7f53de0309f7a63beb625478d4430bd5d98bf31 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/lib/inc/gps_dl_dma_buf.h @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#ifndef _GPS_DL_DMA_BUF_H +#define _GPS_DL_DMA_BUF_H + +#include "gps_dl_config.h" + +#if GPS_DL_ON_LINUX +#include "linux/semaphore.h" +#include "linux/dma-mapping.h" +#elif GPS_DL_ON_CTP +#include "kernel_to_ctp.h" +#include "gps_dl_ctp_osal.h" +#endif + +#include "gps_dl_base.h" + +enum gps_dl_dma_dir { + GDL_DMA_A2D, + GDL_DMA_D2A, + GDL_DMA_DIR_NUM +}; + +/* for lock free structure */ +struct gdl_dma_buf_idx { + unsigned int rd_idx; + unsigned int wr_idx; +}; + +#if GPS_DL_ON_LINUX +struct gdl_dma_lock { + struct semaphore internal_lock; +}; + +enum GDL_RET_STATUS gdl_dma_lock_init(struct gdl_dma_lock *p_lock); +enum GDL_RET_STATUS gdl_dma_lock_take(struct gdl_dma_lock *p_lock); +enum GDL_RET_STATUS gdl_dma_lock_give(struct gdl_dma_lock *p_lock); +void gdl_dma_lock_deinit(struct gdl_dma_lock *p_lock); +#endif + +struct gdl_dma_buf_entry { + void *vir_addr; +#if GPS_DL_ON_LINUX + dma_addr_t phy_addr; +#else + unsigned int phy_addr; +#endif + unsigned int read_index; + unsigned int write_index; + unsigned int buf_length; + bool is_valid; + bool is_nodata; +}; + +#if GPS_DL_ON_LINUX +/* if set to 2, it likes not use multi entry */ +#define GPS_DL_DMA_BUF_ENTRY_MAX (2) +#else +#define GPS_DL_DMA_BUF_ENTRY_MAX (4) +#endif +struct gps_dl_dma_buf { + int dev_index; + enum gps_dl_dma_dir dir; + unsigned int len; + + void *vir_addr; +#if GPS_DL_ON_LINUX + dma_addr_t phy_addr; +#else + unsigned int phy_addr; +#endif + unsigned int read_index; + unsigned int write_index; + unsigned int transfer_max; + bool writer_working; + bool reader_working; + + /* TODO: better way is put it to LINK rather than dma_buf */ + bool has_pending_rx; + + struct gdl_dma_buf_entry dma_working_entry; + struct gdl_dma_buf_entry data_entries[GPS_DL_DMA_BUF_ENTRY_MAX]; + unsigned int entry_r; + unsigned int entry_w; + +#if 0 + struct gdl_dma_buf_idx reader; + struct gdl_dma_buf_idx writer; + struct gdl_dma_lock lock; +#endif +}; + + +struct gdl_hw_dma_transfer { + unsigned int buf_start_addr; + unsigned int transfer_start_addr; + unsigned int len_to_wrap; + unsigned int transfer_max_len; +}; + +int gps_dl_dma_buf_alloc(struct gps_dl_dma_buf *p_dma_buf, enum gps_dl_link_id_enum link_id, + enum gps_dl_dma_dir dir, unsigned int len); +void gps_dma_buf_reset(struct gps_dl_dma_buf *p_dma); +void gps_dma_buf_show(struct gps_dl_dma_buf *p_dma, bool is_warning); +void gps_dma_buf_align_as_byte_mode(struct gps_dl_dma_buf *p_dma); +bool gps_dma_buf_is_empty(struct gps_dl_dma_buf *p_dma); + +/* enum GDL_RET_STATUS gdl_dma_buf_init(struct gps_dl_dma_buf *p_dma); */ +/* enum GDL_RET_STATUS gdl_dma_buf_deinit(struct gps_dl_dma_buf *p_dma); */ + +enum GDL_RET_STATUS gdl_dma_buf_put(struct gps_dl_dma_buf *p_dma, + const unsigned char *p_buf, unsigned int buf_len); + +enum GDL_RET_STATUS gdl_dma_buf_get(struct gps_dl_dma_buf *p_dma, + unsigned char *p_buf, unsigned int buf_len, unsigned int *p_data_len, + bool *p_is_nodata); + + +enum GDL_RET_STATUS gdl_dma_buf_get_data_entry(struct gps_dl_dma_buf *p_dma, + struct gdl_dma_buf_entry *p_entry); + +enum GDL_RET_STATUS gdl_dma_buf_set_data_entry(struct gps_dl_dma_buf *p_dma, + struct gdl_dma_buf_entry *p_entry); + +enum GDL_RET_STATUS gdl_dma_buf_get_free_entry(struct gps_dl_dma_buf *p_dma, + struct gdl_dma_buf_entry *p_entry, bool nospace_set_pending_rx); + +enum GDL_RET_STATUS gdl_dma_buf_set_free_entry(struct gps_dl_dma_buf *p_dma, + struct gdl_dma_buf_entry *p_entry); + + +enum GDL_RET_STATUS gdl_dma_buf_entry_to_buf(const struct gdl_dma_buf_entry *p_entry, + unsigned char *p_buf, unsigned int buf_len, unsigned int *p_data_len); + +enum GDL_RET_STATUS gdl_dma_buf_buf_to_entry(const struct gdl_dma_buf_entry *p_entry, + const unsigned char *p_buf, unsigned int data_len, unsigned int *p_write_index); + +enum GDL_RET_STATUS gdl_dma_buf_entry_to_transfer( + const struct gdl_dma_buf_entry *p_entry, + struct gdl_hw_dma_transfer *p_transfer, bool is_tx); + +enum GDL_RET_STATUS gdl_dma_buf_entry_transfer_left_to_write_index( + const struct gdl_dma_buf_entry *p_entry, + unsigned int left_len, unsigned int *p_write_index); + +#endif /* _GPS_DL_DMA_BUF_H */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/lib/inc/gps_dl_hist_rec.h b/drivers/misc/mediatek/connectivity/gps/data_link/lib/inc/gps_dl_hist_rec.h new file mode 100644 index 0000000000000000000000000000000000000000..8573f8785692b63ae74574dfc51604b19f7391c4 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/lib/inc/gps_dl_hist_rec.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#ifndef _GPS_DL_HIST_REC_H +#define _GPS_DL_HIST_REC_H + +#include "gps_dl_config.h" + +enum gps_dl_hist_rec_rw_rec_point { + DRW_ENTER, + DRW_RETURN +}; + +void gps_each_link_rec_read(enum gps_dl_link_id_enum link_id, int pid, int len, + enum gps_dl_hist_rec_rw_rec_point rec_point); +void gps_each_link_rec_write(enum gps_dl_link_id_enum link_id, int pid, int len, + enum gps_dl_hist_rec_rw_rec_point rec_point); +void gps_each_link_rec_reset(enum gps_dl_link_id_enum link_id); +void gps_each_link_rec_force_dump(enum gps_dl_link_id_enum link_id); + +#endif /* _GPS_DL_HIST_REC_H */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/lib/inc/gps_dl_lib_misc.h b/drivers/misc/mediatek/connectivity/gps/data_link/lib/inc/gps_dl_lib_misc.h new file mode 100644 index 0000000000000000000000000000000000000000..2ee1830ab021437603f8d5becfe01dcd36f1326a --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/lib/inc/gps_dl_lib_misc.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#ifndef _GPS_DL_LIB_MISC_H +#define _GPS_DL_LIB_MISC_H + +#include "gps_dl_config.h" +#include "gps_dl_base.h" +#if GPS_DL_ON_LINUX +#include /* for bool */ +#endif + +void gps_dl_hal_show_buf(unsigned char *tag, + unsigned char *buf, unsigned int len); + +bool gps_dl_hal_comp_buf_match(unsigned char *data_buf, unsigned int data_len, + unsigned char *golden_buf, unsigned int golden_len, unsigned int data_shift); + +#endif /* _GPS_DL_LIB_MISC_H */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/lib/inc/gps_dl_name_list.h b/drivers/misc/mediatek/connectivity/gps/data_link/lib/inc/gps_dl_name_list.h new file mode 100644 index 0000000000000000000000000000000000000000..6e8217f428cca6517d7813612e8c49667b7a6037 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/lib/inc/gps_dl_name_list.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#ifndef _GPS_DL_NAME_LIST_H +#define _GPS_DL_NAME_LIST_H + +#include "gps_dl_config.h" + +#include "gps_each_link.h" +#include "gps_dl_hal_api.h" +#include "gps_dsp_fsm.h" +#include "gps_dl_base.h" + +const char *gps_dl_dsp_state_name(enum gps_dsp_state_t state); +const char *gps_dl_dsp_event_name(enum gps_dsp_event_t event); + +const char *gps_dl_link_state_name(enum gps_each_link_state_enum state); +const char *gps_dl_link_event_name(enum gps_dl_link_event_id event); +const char *gps_dl_hal_event_name(enum gps_dl_hal_event_id event); + +const char *gps_dl_waitable_type_name(enum gps_each_link_waitable_type type); + +#endif /* _GPS_DL_NAME_LIST_H */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/lib/inc/gps_dl_time_tick.h b/drivers/misc/mediatek/connectivity/gps/data_link/lib/inc/gps_dl_time_tick.h new file mode 100644 index 0000000000000000000000000000000000000000..7ec941c301c97494e6665ade65ccb7b97059a99a --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/lib/inc/gps_dl_time_tick.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#ifndef _GPS_DL_TIME_TICK_H +#define _GPS_DL_TIME_TICK_H + +#define GPS_DL_RW_NO_TIMEOUT (-1) +void gps_dl_wait_us(unsigned int us); +#define GDL_WAIT_US(Usec) gps_dl_wait_us(Usec) +unsigned long gps_dl_tick_get(void); +int gps_dl_tick_delta_to_usec(unsigned int tick0, unsigned int tick1); + +#endif /* _GPS_DL_TIME_TICK_H */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/link/gps_dl_subsys_reset.c b/drivers/misc/mediatek/connectivity/gps/data_link/link/gps_dl_subsys_reset.c new file mode 100644 index 0000000000000000000000000000000000000000..b46058ec06087ea61d1ffd75311d410468ead3e2 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/link/gps_dl_subsys_reset.c @@ -0,0 +1,401 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#include "gps_dl_config.h" + +#include "gps_dl_context.h" +#include "gps_dl_subsys_reset.h" +#include "gps_each_link.h" +#include "gps_dl_name_list.h" +#include "gps_dl_hw_api.h" + +#if GPS_DL_HAS_CONNINFRA_DRV +#include "conninfra.h" +#endif + +bool gps_dl_reset_level_is_none(enum gps_dl_link_id_enum link_id) +{ + struct gps_each_link *p = gps_dl_link_get(link_id); + enum gps_each_link_state_enum state; + enum gps_each_link_reset_level level; + bool is_none; + + gps_each_link_spin_lock_take(link_id, GPS_DL_SPINLOCK_FOR_LINK_STATE); + state = p->state_for_user; + level = p->reset_level; + is_none = (level == GPS_DL_RESET_LEVEL_NONE); + gps_each_link_spin_lock_give(link_id, GPS_DL_SPINLOCK_FOR_LINK_STATE); + + if (!is_none) + GDL_LOGW("state = %s, level = %d", gps_dl_link_state_name(state), level); + + return is_none; +} + +enum GDL_RET_STATUS gps_dl_reset_level_set_and_trigger( + enum gps_each_link_reset_level level, bool wait_reset_done) +{ + enum gps_dl_link_id_enum link_id; + struct gps_each_link *p; + enum gps_each_link_state_enum old_state, new_state; + enum gps_each_link_reset_level old_level, new_level; + bool need_wait[GPS_DATA_LINK_NUM] = {false}; + bool to_send_reset_event; + long sigval; + enum GDL_RET_STATUS wait_status; + + if (level != GPS_DL_RESET_LEVEL_GPS_SUBSYS && level != GPS_DL_RESET_LEVEL_CONNSYS) { + GDL_LOGW("level = %d, do nothing and return", level); + return GDL_FAIL_INVAL; + } + + if (wait_reset_done) + ; /* TODO: take mutex to allow pending more waiter */ + + for (link_id = 0; link_id < GPS_DATA_LINK_NUM; link_id++) { + p = gps_dl_link_get(link_id); + to_send_reset_event = false; + + gps_each_link_spin_lock_take(link_id, GPS_DL_SPINLOCK_FOR_LINK_STATE); + old_state = p->state_for_user; + old_level = p->reset_level; + + switch (old_state) { + case LINK_CLOSED: + need_wait[link_id] = false; + p->state_for_user = LINK_DISABLED; + p->reset_level = level; + + /* Send reset event to ctld: + * + * for GPS_DL_RESET_LEVEL_GPS_SUBSYS ctrld do nothing but + * just change state from DISABLED back to CLOSED + * + * for GPS_DL_RESET_LEVEL_CONNSYS ctrld do nothing but + * just change state from DISABLED state back to CLOSED + */ + to_send_reset_event = true; + break; + + case LINK_OPENING: + case LINK_OPENED: + case LINK_CLOSING: + case LINK_RESET_DONE: + case LINK_RESUMING: + case LINK_SUSPENDING: + case LINK_SUSPENDED: + need_wait[link_id] = true; + p->state_for_user = LINK_RESETTING; + p->reset_level = level; + to_send_reset_event = true; + break; + + case LINK_RESETTING: + need_wait[link_id] = true; + if (old_level < level) + p->reset_level = level; + break; + + case LINK_DISABLED: + case LINK_UNINIT: + need_wait[link_id] = false; + break; + + default: + need_wait[link_id] = false; + break; + } + + new_state = p->state_for_user; + new_level = p->reset_level; + gps_each_link_spin_lock_give(link_id, GPS_DL_SPINLOCK_FOR_LINK_STATE); + + if (to_send_reset_event) { + gps_dl_link_waitable_reset(link_id, GPS_DL_WAIT_RESET); + if (level == GPS_DL_RESET_LEVEL_CONNSYS) + gps_dl_link_event_send(GPS_DL_EVT_LINK_PRE_CONN_RESET, link_id); + else + gps_dl_link_event_send(GPS_DL_EVT_LINK_RESET_GPS, link_id); + } + + GDL_LOGXE_STA(link_id, + "state change: %s -> %s, level = %d (%d -> %d), is_sent = %d, to_wait = %d", + gps_dl_link_state_name(old_state), gps_dl_link_state_name(new_state), + level, old_level, new_level, + to_send_reset_event, need_wait[link_id]); + } + + if (!wait_reset_done) { + GDL_LOGE("force no wait"); + return GDL_OKAY; + } + + for (link_id = 0; link_id < GPS_DATA_LINK_NUM; link_id++) { + if (!need_wait[link_id]) + continue; + + sigval = 0; + p = gps_dl_link_get(link_id); + wait_status = gps_dl_link_wait_on(&p->waitables[GPS_DL_WAIT_RESET], &sigval); + if (wait_status == GDL_FAIL_SIGNALED) { + GDL_LOGXE(link_id, "sigval = %ld", sigval); + return GDL_FAIL_SIGNALED; + } + + GDL_LOGXE(link_id, "wait ret = %s", gdl_ret_to_name(wait_status)); + } + + if (wait_reset_done) + ; /* TODO: take mutex to allow pending more waiter */ + + return GDL_OKAY; +} + +int gps_dl_trigger_gps_subsys_reset(bool wait_reset_done) +{ + enum GDL_RET_STATUS ret_status; + + ret_status = gps_dl_reset_level_set_and_trigger(GPS_DL_RESET_LEVEL_GPS_SUBSYS, wait_reset_done); + if (ret_status != GDL_OKAY) { + GDL_LOGE("status %s is not okay, return -1", gdl_ret_to_name(ret_status)); + return -1; + } + return 0; +} + +void gps_dl_trigger_gps_print_hw_status(void) +{ + GDL_LOGE(""); + gps_dl_link_event_send(GPS_DL_EVT_LINK_PRINT_HW_STATUS, GPS_DATA_LINK_ID0); + gps_dl_link_event_send(GPS_DL_EVT_LINK_PRINT_HW_STATUS, GPS_DATA_LINK_ID1); +} + +void gps_dl_trigger_gps_print_data_status(void) +{ + GDL_LOGE(""); + gps_dl_link_event_send(GPS_DL_EVT_LINK_PRINT_DATA_STATUS, GPS_DATA_LINK_ID0); + gps_dl_link_event_send(GPS_DL_EVT_LINK_PRINT_DATA_STATUS, GPS_DATA_LINK_ID1); +} + +void gps_dl_handle_connsys_reset_done(void) +{ + enum gps_dl_link_id_enum link_id; + struct gps_each_link *p; + enum gps_each_link_state_enum state; + enum gps_each_link_reset_level level; + bool to_send_reset_event; + + for (link_id = 0; link_id < GPS_DATA_LINK_NUM; link_id++) { + p = gps_dl_link_get(link_id); + to_send_reset_event = false; + + gps_each_link_spin_lock_take(link_id, GPS_DL_SPINLOCK_FOR_LINK_STATE); + state = p->state_for_user; + level = p->reset_level; + + if (level == GPS_DL_RESET_LEVEL_CONNSYS) { + if (state == LINK_DISABLED || state == LINK_RESETTING) + to_send_reset_event = true; + } + gps_each_link_spin_lock_give(link_id, GPS_DL_SPINLOCK_FOR_LINK_STATE); + + if (to_send_reset_event) + gps_dl_link_event_send(GPS_DL_EVT_LINK_POST_CONN_RESET, link_id); + + GDL_LOGXE_STA(link_id, "state check: %s, level = %d, is_sent = %d", + gps_dl_link_state_name(state), level, to_send_reset_event); + } +} + +int gps_dl_trigger_connsys_reset(void) +{ +#if GPS_DL_HAS_CONNINFRA_DRV + int ret; + + GDL_LOGE(""); + ret = conninfra_trigger_whole_chip_rst(CONNDRV_TYPE_GPS, "GPS debug"); + GDL_LOGE("conninfra_trigger_whole_chip_rst return = %d", ret); +#else + GDL_LOGE("has no conninfra_drv"); +#endif + return 0; +} + +#if GPS_DL_HAS_CONNINFRA_DRV +static bool gps_dl_connsys_is_resetting; +int gps_dl_on_pre_connsys_reset(enum consys_drv_type drv, char *reason) +{ + enum GDL_RET_STATUS ret_status; + + GDL_LOGE("already in resetting = %d", gps_dl_connsys_is_resetting); + gps_dl_connsys_is_resetting = true; + + ret_status = gps_dl_reset_level_set_and_trigger(GPS_DL_RESET_LEVEL_CONNSYS, true); + + if (ret_status != GDL_OKAY) { + GDL_LOGE("status %s is not okay, return -1", gdl_ret_to_name(ret_status)); + return -1; + } + + return 0; +} + +int gps_dl_on_post_connsys_reset(void) +{ + GDL_LOGE("already in resetting = %d", gps_dl_connsys_is_resetting); + gps_dl_connsys_is_resetting = false; + + gps_dl_handle_connsys_reset_done(); + return 0; +} + +struct sub_drv_ops_cb gps_dl_conninfra_ops_cb; +#endif + +void gps_dl_register_conninfra_reset_cb(void) +{ +#if GPS_DL_HAS_CONNINFRA_DRV + memset(&gps_dl_conninfra_ops_cb, 0, sizeof(gps_dl_conninfra_ops_cb)); + gps_dl_conninfra_ops_cb.rst_cb.pre_whole_chip_rst = gps_dl_on_pre_connsys_reset; + gps_dl_conninfra_ops_cb.rst_cb.post_whole_chip_rst = gps_dl_on_post_connsys_reset; + + conninfra_sub_drv_ops_register(CONNDRV_TYPE_GPS, &gps_dl_conninfra_ops_cb); +#endif +} + +void gps_dl_unregister_conninfra_reset_cb(void) +{ +#if GPS_DL_HAS_CONNINFRA_DRV + conninfra_sub_drv_ops_unregister(CONNDRV_TYPE_GPS); +#endif +} + +bool gps_dl_conninfra_is_readable(void) +{ +#if GPS_DL_HAS_CONNINFRA_DRV + return (conninfra_reg_readable() != 0); +#else + return true; +#endif +} + +void gps_dl_conninfra_not_readable_show_warning(unsigned int host_addr) +{ +#if GPS_DL_HAS_CONNINFRA_DRV + int readable; + int hung_value = 0; + + readable = conninfra_reg_readable(); + if (readable) + return; + + hung_value = conninfra_is_bus_hang(); + GDL_LOGW("readable = %d, hung_value = %d, before access 0x%08x", + readable, hung_value, host_addr); +#endif +} + +bool gps_dl_conninfra_is_okay_or_handle_it(int *p_hung_value, bool dump_on_hung_value_zero) +{ +#if GPS_DL_HAS_CONNINFRA_DRV + int readable; + int hung_value = 0; + bool trigger = false; + int trigger_ret = 0; + bool check_again; + int check_cnt = 0; + + do { + check_again = false; + readable = conninfra_reg_readable(); + if (readable) { + GDL_LOGD("readable = %d, okay", readable); + return true; + } + + hung_value = conninfra_is_bus_hang(); + if (p_hung_value != NULL) + *p_hung_value = hung_value; + + /* hung_value > 0, need to trigger reset + * hung_value < 0, already in reset status + * hung_value = 0, connsys may not in proper status (such as conn_top_off is in sleep) + */ + if (hung_value > 0) { + /* it's safe to cump gps host csr even hang value > 0 */ + gps_dl_hw_dump_host_csr_gps_info(true); + + trigger = true; + trigger_ret = conninfra_trigger_whole_chip_rst( + CONNDRV_TYPE_GPS, "GPS detect hung - case1"); + } else if (hung_value == 0) { + if (dump_on_hung_value_zero) + gps_dl_hw_dump_host_csr_gps_info(true); + if (check_cnt < 1) { + /* readable = 0 and hung_value = 0 may not be a stable state, + * check again to double confirm + */ + check_again = true; + } else { + /* trigger connsys reset if same result of checking again */ + trigger = true; + trigger_ret = conninfra_trigger_whole_chip_rst( + CONNDRV_TYPE_GPS, "GPS detect hung - case2"); + } + } else { + /* alreay in connsys resetting + * do nothing + */ + } + + check_cnt++; + GDL_LOGE("cnt=%d, readable=%d, hung_value=0x%x, trigger_reset=%d(%d,%d)", + check_cnt, readable, hung_value, trigger, trigger_ret, dump_on_hung_value_zero); + } while (check_again); + return false; +#else + return true; +#endif +} + + +bool g_gps_dl_test_mask_mcub_irq_on_open_flag[GPS_DATA_LINK_NUM]; +bool g_gps_dl_test_mask_hasdata_irq_flag[GPS_DATA_LINK_NUM]; + +void gps_dl_test_mask_mcub_irq_on_open_set(enum gps_dl_link_id_enum link_id, bool mask) +{ + ASSERT_LINK_ID(link_id, GDL_VOIDF()); + + g_gps_dl_test_mask_mcub_irq_on_open_flag[link_id] = mask; +} + +bool gps_dl_test_mask_mcub_irq_on_open_get(enum gps_dl_link_id_enum link_id) +{ + ASSERT_LINK_ID(link_id, false); + + return g_gps_dl_test_mask_mcub_irq_on_open_flag[link_id]; +} + +void gps_dl_test_mask_hasdata_irq_set(enum gps_dl_link_id_enum link_id, bool mask) +{ + ASSERT_LINK_ID(link_id, GDL_VOIDF()); + + g_gps_dl_test_mask_hasdata_irq_flag[link_id] = mask; +} + +bool gps_dl_test_mask_hasdata_irq_get(enum gps_dl_link_id_enum link_id) +{ + ASSERT_LINK_ID(link_id, false); + + return g_gps_dl_test_mask_hasdata_irq_flag[link_id]; +} + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/link/inc/gps_dl_subsys_reset.h b/drivers/misc/mediatek/connectivity/gps/data_link/link/inc/gps_dl_subsys_reset.h new file mode 100644 index 0000000000000000000000000000000000000000..1727444cb120c25a86969f7a4d6e558da2f9170d --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/link/inc/gps_dl_subsys_reset.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#ifndef _GPS_DL_SUBSYS_RESET_H +#define _GPS_DL_SUBSYS_RESET_H + +#include "gps_dl_base.h" + +enum gps_each_link_reset_level { + GPS_DL_RESET_LEVEL_NONE, + GPS_DL_RESET_LEVEL_GPS_SINGLE_LINK, + GPS_DL_RESET_LEVEL_GPS_SUBSYS, + GPS_DL_RESET_LEVEL_CONNSYS, + GPS_DL_RESET_LEVEL_NUM +}; + +enum GDL_RET_STATUS gps_dl_reset_level_set_and_trigger( + enum gps_each_link_reset_level level, bool wait_reset_done); + +bool gps_dl_reset_level_is_none(enum gps_dl_link_id_enum link_id); +bool gps_dl_reset_level_is_single(void); +bool gps_dl_reset_level_gt_single(void); + +void gps_dl_trigger_gps_print_hw_status(void); +void gps_dl_trigger_gps_print_data_status(void); +int gps_dl_trigger_gps_subsys_reset(bool wait_reset_done); +int gps_dl_trigger_connsys_reset(void); +void gps_dl_handle_connsys_reset_done(void); + +void gps_dl_register_conninfra_reset_cb(void); +void gps_dl_unregister_conninfra_reset_cb(void); + +bool gps_dl_conninfra_is_readable(void); +void gps_dl_conninfra_not_readable_show_warning(unsigned int host_addr); +bool gps_dl_conninfra_is_okay_or_handle_it(int *p_hung_value, bool dump_on_hung_value_zero); + +void gps_dl_test_mask_mcub_irq_on_open_set(enum gps_dl_link_id_enum link_id, bool mask); +bool gps_dl_test_mask_mcub_irq_on_open_get(enum gps_dl_link_id_enum link_id); + +void gps_dl_test_mask_hasdata_irq_set(enum gps_dl_link_id_enum link_id, bool mask); +bool gps_dl_test_mask_hasdata_irq_get(enum gps_dl_link_id_enum link_id); + +#endif /* _GPS_DL_SUBSYS_RESET_H */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/linux/gps_data_link_devices.c b/drivers/misc/mediatek/connectivity/gps/data_link/linux/gps_data_link_devices.c new file mode 100644 index 0000000000000000000000000000000000000000..bcbbd0c1d5e3b23af8788fe7b1140e93db7fb6c2 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/linux/gps_data_link_devices.c @@ -0,0 +1,343 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#include +#include + +#include +#include + +#include "gps_dl_config.h" +#include "gps_dl_context.h" +#include "gps_dl_hw_api.h" +#include "gps_dl_isr.h" +#include "gps_data_link_devices.h" +#include "gps_each_link.h" +#if GPS_DL_HAS_PLAT_DRV +#include "gps_dl_linux_plat_drv.h" +#include "gps_dl_linux_reserved_mem.h" +#endif +#if GPS_DL_MOCK_HAL +#include "gps_mock_hal.h" +#endif +#include "gps_dl_procfs.h" +#include "gps_dl_subsys_reset.h" + +#define GPS_DATA_LINK_DEV_NAME "gps_data_link_cdev" +int gps_dl_devno_major; +int gps_dl_devno_minor; + +void gps_dl_dma_buf_free(struct gps_dl_dma_buf *p_dma_buf, enum gps_dl_link_id_enum link_id) +{ + struct gps_each_device *p_dev; + + p_dev = gps_dl_device_get(link_id); + if (p_dev == NULL) { + GDL_LOGXE_INI(link_id, "gps_dl_device_get return null"); + return; + } + + if (p_dma_buf->vir_addr) + dma_free_coherent(p_dev->dev, + p_dma_buf->len, p_dma_buf->vir_addr, p_dma_buf->phy_addr); + + memset(p_dma_buf, 0, sizeof(*p_dma_buf)); +} + +int gps_dl_dma_buf_alloc(struct gps_dl_dma_buf *p_dma_buf, enum gps_dl_link_id_enum link_id, + enum gps_dl_dma_dir dir, unsigned int len) +{ + struct gps_each_device *p_dev; + struct device *p_linux_plat_dev; + + p_dev = gps_dl_device_get(link_id); + if (p_dev == NULL) { + GDL_LOGXE_INI(link_id, "gps_dl_device_get return null"); + return -1; + } + + p_linux_plat_dev = (struct device *)p_dev->private_data; + + memset(p_dma_buf, 0, sizeof(*p_dma_buf)); + p_dma_buf->dev_index = link_id; + p_dma_buf->dir = dir; + p_dma_buf->len = len; + + GDL_LOGI_INI("p_linux_plat_dev = 0x%p", p_linux_plat_dev); + if (p_linux_plat_dev == NULL) { + p_dma_buf->vir_addr = dma_zalloc_coherent( + p_dev->dev, len, &p_dma_buf->phy_addr, GFP_DMA | GFP_DMA32); + } else { + p_dma_buf->vir_addr = dma_zalloc_coherent( + p_linux_plat_dev, len, &p_dma_buf->phy_addr, GFP_DMA);/* | GFP_DMA32); */ + } + + GDL_LOGI_INI( +#if GPS_DL_ON_LINUX + "alloc gps dl dma buf(%d,%d), addr: vir=0x%p, phy=0x%pad, len=%u", +#else + "alloc gps dl dma buf(%d,%d), addr: vir=0x%p, phy=0x%08x, len=%u", +#endif + p_dma_buf->dev_index, p_dma_buf->dir, + p_dma_buf->vir_addr, p_dma_buf->phy_addr, p_dma_buf->len); + + if (NULL == p_dma_buf->vir_addr) { + GDL_LOGXE_INI(link_id, + "alloc gps dl dma buf(%d,%d)(len = %u) fail", link_id, dir, len); + /* force move forward even fail */ + /* return -ENOMEM; */ + } + + return 0; +} + +int gps_dl_dma_buf_alloc2(enum gps_dl_link_id_enum link_id) +{ + int retval; + struct gps_each_device *p_dev; + struct gps_each_link *p_link; + + p_dev = gps_dl_device_get(link_id); + p_link = gps_dl_link_get(link_id); + if (p_dev == NULL) { + GDL_LOGXE_INI(link_id, "gps_dl_device_get return null"); + return -1; + } + + of_dma_configure(p_dev->dev, p_dev->dev->of_node); + + if (!p_dev->dev->coherent_dma_mask) + p_dev->dev->coherent_dma_mask = DMA_BIT_MASK(32); + + if (!p_dev->dev->dma_mask) + p_dev->dev->dma_mask = &p_dev->dev->coherent_dma_mask; + + + retval = gps_dl_dma_buf_alloc( + &p_link->tx_dma_buf, link_id, GDL_DMA_A2D, p_link->cfg.tx_buf_size); + + if (retval) + return retval; + + retval = gps_dl_dma_buf_alloc( + &p_link->rx_dma_buf, link_id, GDL_DMA_D2A, p_link->cfg.rx_buf_size); + + if (retval) + return retval; + + return 0; +} + +void gps_dl_ctx_links_deinit(void) +{ + enum gps_dl_link_id_enum link_id; + + struct gps_each_device *p_dev; + struct gps_each_link *p_link; + + for (link_id = 0; link_id < GPS_DATA_LINK_NUM; link_id++) { + p_dev = gps_dl_device_get(link_id); + p_link = gps_dl_link_get(link_id); + + if (gps_dl_reserved_mem_is_ready()) { + gps_dl_reserved_mem_dma_buf_deinit(&p_link->tx_dma_buf); + gps_dl_reserved_mem_dma_buf_deinit(&p_link->rx_dma_buf); + + } else { + gps_dl_dma_buf_free(&p_link->tx_dma_buf, link_id); + gps_dl_dma_buf_free(&p_link->rx_dma_buf, link_id); + } + + /* un-binding each device and link */ + p_link->p_device = NULL; + p_dev->p_link = NULL; + gps_each_link_deinit(link_id); + } +} + +int gps_dl_ctx_links_init(void) +{ + int retval; + enum gps_dl_link_id_enum link_id; + struct gps_each_device *p_dev; + struct gps_each_link *p_link; + enum gps_each_link_waitable_type j; + + for (link_id = 0; link_id < GPS_DATA_LINK_NUM; link_id++) { + p_dev = gps_dl_device_get(link_id); + p_link = gps_dl_link_get(link_id); + + if (gps_dl_reserved_mem_is_ready()) { + gps_dl_reserved_mem_dma_buf_init(&p_link->tx_dma_buf, + link_id, GDL_DMA_A2D, p_link->cfg.tx_buf_size); + + gps_dl_reserved_mem_dma_buf_init(&p_link->rx_dma_buf, + link_id, GDL_DMA_D2A, p_link->cfg.rx_buf_size); + } else { + retval = gps_dl_dma_buf_alloc2(link_id); + if (retval) + return retval; + } + + for (j = 0; j < GPS_DL_WAIT_NUM; j++) + gps_dl_link_waitable_init(&p_link->waitables[j], j); + + /* binding each device and link */ + p_link->p_device = p_dev; + p_dev->p_link = p_link; + + /* Todo: MNL read buf is 512, here is work-around */ + /* the solution should be make on gdl_dma_buf_get */ + gps_dl_set_rx_transfer_max(link_id, GPS_LIBMNL_READ_MAX); + gps_each_link_init(link_id); + } + + return 0; +} + +static void gps_dl_devices_exit(void) +{ + enum gps_dl_link_id_enum link_id; + dev_t devno = MKDEV(gps_dl_devno_major, gps_dl_devno_minor); + struct gps_each_device *p_dev; + + gps_dl_device_context_deinit(); + +#if GPS_DL_HAS_PLAT_DRV + gps_dl_linux_plat_drv_unregister(); +#endif + + for (link_id = 0; link_id < GPS_DATA_LINK_NUM; link_id++) { + p_dev = gps_dl_device_get(link_id); + gps_dl_cdev_cleanup(p_dev, link_id); + } + + unregister_chrdev_region(devno, GPS_DATA_LINK_NUM); +} + +void gps_dl_device_context_deinit(void) +{ + gps_dl_procfs_remove(); + + gps_dl_unregister_conninfra_reset_cb(); + + gps_dl_irq_deinit(); + +#if GPS_DL_HAS_CTRLD + gps_dl_ctrld_deinit(); +#endif + +#if GPS_DL_MOCK_HAL + gps_dl_mock_deinit(); +#endif + + gps_dl_ctx_links_deinit(); + gps_dl_reserved_mem_deinit(); +} + +int gps_dl_irq_init(void) +{ +#if 0 + enum gps_dl_irq_index_enum irq_idx; + + for (irq_idx = 0; irq_idx < GPS_DL_IRQ_NUM; irq_idx++) + ; +#endif + + gps_dl_linux_irqs_register(gps_dl_irq_get(0), GPS_DL_IRQ_NUM); + + return 0; +} + +int gps_dl_irq_deinit(void) +{ + gps_dl_linux_irqs_unregister(gps_dl_irq_get(0), GPS_DL_IRQ_NUM); + return 0; +} + +static int gps_dl_devices_init(void) +{ + int result; + enum gps_dl_link_id_enum link_id; + dev_t devno = 0; + struct gps_each_device *p_dev; + + result = alloc_chrdev_region(&devno, gps_dl_devno_minor, + GPS_DATA_LINK_NUM, GPS_DATA_LINK_DEV_NAME); + + gps_dl_devno_major = MAJOR(devno); + + if (result < 0) { + GDL_LOGE_INI("fail to get major %d\n", gps_dl_devno_major); + return result; + } + + GDL_LOGW_INI("success to get major %d\n", gps_dl_devno_major); + + for (link_id = 0; link_id < GPS_DATA_LINK_NUM; link_id++) { + devno = MKDEV(gps_dl_devno_major, gps_dl_devno_minor + link_id); + p_dev = gps_dl_device_get(link_id); + p_dev->devno = devno; + result = gps_dl_cdev_setup(p_dev, link_id); + if (result) { + /* error happened */ + gps_dl_devices_exit(); + return result; + } + } + + +#if GPS_DL_HAS_PLAT_DRV + gps_dl_linux_plat_drv_register(); +#else + gps_dl_device_context_init(); +#endif + + return 0; +} + +void gps_dl_device_context_init(void) +{ + gps_dl_reserved_mem_init(); + gps_dl_ctx_links_init(); + +#if GPS_DL_MOCK_HAL + gps_dl_mock_init(); +#endif + +#if GPS_DL_HAS_CTRLD + gps_dl_ctrld_init(); +#endif + +#if (!(GPS_DL_NO_USE_IRQ || GPS_DL_HW_IS_MOCK)) + /* must after gps_dl_ctx_links_init */ + gps_dl_irq_init(); +#endif + gps_dl_register_conninfra_reset_cb(); + + gps_dl_procfs_setup(); +} + +void mtk_gps_data_link_devices_exit(void) +{ + GDL_LOGI_INI("mtk_gps_data_link_devices_exit"); + gps_dl_devices_exit(); +} + +int mtk_gps_data_link_devices_init(void) +{ + GDL_LOGI_INI("mtk_gps_data_link_devices_init"); + gps_dl_devices_init(); + /* GDL_ASSERT(false, 0, "test assert"); */ + return 0; +} + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/linux/gps_dl_ctrld.c b/drivers/misc/mediatek/connectivity/gps/data_link/linux/gps_dl_ctrld.c new file mode 100644 index 0000000000000000000000000000000000000000..a5f18c88edc9c3019d397af9c3a624fef38b9ce2 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/linux/gps_dl_ctrld.c @@ -0,0 +1,372 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#include "gps_dl_ctrld.h" +#include "gps_each_device.h" +#if GPS_DL_MOCK_HAL +#include "gps_mock_mvcd.h" +#endif +#include "gps_data_link_devices.h" +#include "gps_dl_hal_api.h" + +struct gps_dl_ctrld_context gps_dl_ctrld; + +static int gps_dl_opfunc_link_event_proc(struct gps_dl_osal_op_dat *pOpDat); +static int gps_dl_opfunc_hal_event_proc(struct gps_dl_osal_op_dat *pOpDat); +static struct gps_dl_osal_lxop *gps_dl_get_op(struct gps_dl_osal_lxop_q *pOpQ); +static int gps_dl_put_op(struct gps_dl_osal_lxop_q *pOpQ, struct gps_dl_osal_lxop *pOp); + +static const GPS_DL_OPID_FUNC gps_dl_core_opfunc[] = { + [GPS_DL_OPID_LINK_EVENT_PROC] = gps_dl_opfunc_link_event_proc, + [GPS_DL_OPID_HAL_EVENT_PROC] = gps_dl_opfunc_hal_event_proc, +}; + +static int gps_dl_opfunc_link_event_proc(struct gps_dl_osal_op_dat *pOpDat) +{ + enum gps_dl_link_event_id evt; + enum gps_dl_link_id_enum link_id; + + link_id = (enum gps_dl_link_id_enum)pOpDat->au4OpData[0]; + evt = (enum gps_dl_link_event_id)pOpDat->au4OpData[1]; + gps_dl_link_event_proc(evt, link_id); + + return 0; +} + +static int gps_dl_opfunc_hal_event_proc(struct gps_dl_osal_op_dat *pOpDat) +{ + enum gps_dl_hal_event_id evt; + enum gps_dl_link_id_enum link_id; + int sid_on_evt; + + link_id = (enum gps_dl_link_id_enum)pOpDat->au4OpData[0]; + evt = (enum gps_dl_hal_event_id)pOpDat->au4OpData[1]; + sid_on_evt = (int)pOpDat->au4OpData[2]; + gps_dl_hal_event_proc(evt, link_id, sid_on_evt); + + return 0; +} + +unsigned int gps_dl_wait_event_checker(struct gps_dl_osal_thread *pThread) +{ + struct gps_dl_ctrld_context *pgps_dl_ctrld; + + if (pThread) { + pgps_dl_ctrld = (struct gps_dl_ctrld_context *) (pThread->pThreadData); + return !RB_EMPTY(&pgps_dl_ctrld->rOpQ); + } + GDL_LOGE_EVT("pThread null"); + return 0; +} + +static int gps_dl_core_opid(struct gps_dl_osal_op_dat *pOpDat) +{ + int ret; + + if (pOpDat == NULL) { + GDL_LOGE_EVT("null operation data"); + /*print some message with error info */ + return -1; + } + + if (pOpDat->opId >= GPS_DL_OPID_MAX) { + GDL_LOGE_EVT("Invalid OPID(%d)", pOpDat->opId); + return -2; + } + + if (gps_dl_core_opfunc[pOpDat->opId]) { + GDL_LOGD_EVT("GPS data link: operation id(%d)", pOpDat->opId); + ret = (*(gps_dl_core_opfunc[pOpDat->opId])) (pOpDat); + return ret; + } + + GDL_LOGE_EVT("GPS data link: null handler (%d)", pOpDat->opId); + + return -2; +} + +static int gps_dl_put_op(struct gps_dl_osal_lxop_q *pOpQ, struct gps_dl_osal_lxop *pOp) +{ + int iRet; + + if (!pOpQ || !pOp) { + GDL_LOGW_EVT("invalid input param: pOpQ(0x%p), pLxOp(0x%p)", pOpQ, pOp); + gps_dl_osal_assert(pOpQ); + gps_dl_osal_assert(pOp); + return -1; + } + + iRet = gps_dl_osal_lock_sleepable_lock(&pOpQ->sLock); + if (iRet) { + GDL_LOGW_EVT("gps_dl_osal_lock_sleepable_lock iRet(%d)", iRet); + return -1; + } + + /* acquire lock success */ + if (!RB_FULL(pOpQ)) + RB_PUT(pOpQ, pOp); + else { + GDL_LOGW("RB_FULL(%p -> %p)", pOp, pOpQ); + iRet = -1; + } + + gps_dl_osal_unlock_sleepable_lock(&pOpQ->sLock); + + if (iRet) + return -1; + return 0; +} + +int gps_dl_put_act_op(struct gps_dl_osal_lxop *pOp) +{ + struct gps_dl_ctrld_context *pgps_dl_ctrld = &gps_dl_ctrld; + struct gps_dl_osal_signal *pSignal = NULL; + int waitRet = -1; + int bRet = 0; + + gps_dl_osal_assert(pgps_dl_ctrld); + gps_dl_osal_assert(pOp); + + do { + if (!pgps_dl_ctrld || !pOp) { + GDL_LOGE("pgps_dl_ctx(0x%p), pOp(0x%p)", pgps_dl_ctrld, pOp); + break; + } + + /* Init ref_count to 1 indicating that current thread holds a ref to it */ + atomic_set(&pOp->ref_count, 1); + + pSignal = &pOp->signal; + if (pSignal->timeoutValue) { + pOp->result = -9; + gps_dl_osal_signal_init(pSignal); + } + + /* Increment ref_count by 1 as gps control thread will hold a reference also, + * this must be done here instead of on target thread, because + * target thread might not be scheduled until a much later time, + * allowing current thread to decrement ref_count at the end of function, + * putting op back to free queue before target thread has a chance to process. + */ + atomic_inc(&pOp->ref_count); + + /* put to active Q */ + bRet = gps_dl_put_op(&pgps_dl_ctrld->rOpQ, pOp); + if (bRet == -1) { + GDL_LOGE("put to active queue fail"); + atomic_dec(&pOp->ref_count); + break; + } + + /* wake up gps control thread */ + gps_dl_osal_trigger_event(&pgps_dl_ctrld->rgpsdlWq); + + if (pSignal->timeoutValue == 0) { + bRet = -1; + break; + } + + /* check result */ + waitRet = gps_dl_osal_wait_for_signal_timeout(pSignal, &pgps_dl_ctrld->thread); + + if (waitRet == 0) + GDL_LOGE("opId(%d) completion timeout", pOp->op.opId); + else if (pOp->result) + GDL_LOGW("opId(%d) result:%d", pOp->op.opId, pOp->result); + + /* op completes, check result */ + bRet = (pOp->result) ? -1 : 0; + } while (0); + + if (pOp && atomic_dec_and_test(&pOp->ref_count)) { + /* put Op back to freeQ */ + gps_dl_put_op(&pgps_dl_ctrld->rFreeOpQ, pOp); + } + + return bRet; +} + +struct gps_dl_osal_lxop *gps_dl_get_free_op(void) +{ + struct gps_dl_osal_lxop *pOp = NULL; + struct gps_dl_ctrld_context *pgps_dl_ctrld = &gps_dl_ctrld; + + gps_dl_osal_assert(pgps_dl_ctrld); + pOp = gps_dl_get_op(&pgps_dl_ctrld->rFreeOpQ); + if (pOp) + gps_dl_osal_memset(pOp, 0, sizeof(struct gps_dl_osal_lxop)); + return pOp; +} + +static struct gps_dl_osal_lxop *gps_dl_get_op(struct gps_dl_osal_lxop_q *pOpQ) +{ + struct gps_dl_osal_lxop *pOp; + int iRet; + + if (pOpQ == NULL) { + GDL_LOGE("pOpQ = NULL"); + gps_dl_osal_assert(pOpQ); + return NULL; + } + + iRet = gps_dl_osal_lock_sleepable_lock(&pOpQ->sLock); + if (iRet) { + GDL_LOGE("gps_dl_osal_lock_sleepable_lock iRet(%d)", iRet); + return NULL; + } + + /* acquire lock success */ + RB_GET(pOpQ, pOp); + gps_dl_osal_unlock_sleepable_lock(&pOpQ->sLock); + + if (pOp == NULL) { + GDL_LOGW("RB_GET(%p) return NULL", pOpQ); + gps_dl_osal_assert(pOp); + return NULL; + } + + return pOp; +} + +int gps_dl_put_op_to_free_queue(struct gps_dl_osal_lxop *pOp) +{ + struct gps_dl_ctrld_context *pgps_dl_ctrld = &gps_dl_ctrld; + + if (gps_dl_put_op(&pgps_dl_ctrld->rFreeOpQ, pOp) < 0) + return -1; + + return 0; +} + +static int gps_dl_ctrl_thread(void *pData) +{ + struct gps_dl_ctrld_context *pgps_dl_ctrld = (struct gps_dl_ctrld_context *) pData; + struct gps_dl_osal_event *pEvent = NULL; + struct gps_dl_osal_lxop *pOp; + int iResult; + + if (pgps_dl_ctrld == NULL) { + GDL_LOGE("pgps_dl_ctx is NULL"); + return -1; + } + + GDL_LOGI("gps control thread starts"); + + pEvent = &(pgps_dl_ctrld->rgpsdlWq); + + for (;;) { + pOp = NULL; + pEvent->timeoutValue = 0; + + gps_dl_osal_thread_wait_for_event(&pgps_dl_ctrld->thread, pEvent, gps_dl_wait_event_checker); + + if (gps_dl_osal_thread_should_stop(&pgps_dl_ctrld->thread)) { + GDL_LOGW(" thread should stop now..."); + /* TODO: clean up active opQ */ + break; + } + + /* get Op from Queue */ + pOp = gps_dl_get_op(&pgps_dl_ctrld->rOpQ); + if (!pOp) { + GDL_LOGW("get_lxop activeQ fail"); + continue; + } + + /*Execute operation*/ + iResult = gps_dl_core_opid(&pOp->op); + + if (atomic_dec_and_test(&pOp->ref_count)) + gps_dl_put_op(&pgps_dl_ctrld->rFreeOpQ, pOp); + else if (gps_dl_osal_op_is_wait_for_signal(pOp)) + gps_dl_osal_op_raise_signal(pOp, iResult); + + if (iResult) + GDL_LOGW("opid (0x%x) failed, iRet(%d)", pOp->op.opId, iResult); + + } + + GDL_LOGI("gps control thread exits succeed"); + + return 0; +} + +int gps_dl_ctrld_init(void) +{ + struct gps_dl_ctrld_context *pgps_dl_ctrld; + struct gps_dl_osal_thread *pThread; + int iRet; + int i; + + pgps_dl_ctrld = &gps_dl_ctrld; + gps_dl_osal_memset(&gps_dl_ctrld, 0, sizeof(gps_dl_ctrld)); + + /* Create gps data link control thread */ + pThread = &gps_dl_ctrld.thread; + gps_dl_osal_strncpy(pThread->threadName, "gps_kctrld", sizeof(pThread->threadName)); + pThread->pThreadData = (void *)pgps_dl_ctrld; + pThread->pThreadFunc = (void *)gps_dl_ctrl_thread; + + iRet = gps_dl_osal_thread_create(pThread); + if (iRet) { + GDL_LOGE("Create gps data link control thread fail:%d", iRet); + return -1; + } + + /* Initialize gps control Thread Information: Thread */ + gps_dl_osal_event_init(&pgps_dl_ctrld->rgpsdlWq); + gps_dl_osal_sleepable_lock_init(&pgps_dl_ctrld->rOpQ.sLock); + gps_dl_osal_sleepable_lock_init(&pgps_dl_ctrld->rFreeOpQ.sLock); + /* Initialize op queue */ + RB_INIT(&pgps_dl_ctrld->rOpQ, GPS_DL_OP_BUF_SIZE); + RB_INIT(&pgps_dl_ctrld->rFreeOpQ, GPS_DL_OP_BUF_SIZE); + + /* Put all to free Q */ + for (i = 0; i < GPS_DL_OP_BUF_SIZE; i++) { + gps_dl_osal_signal_init(&(pgps_dl_ctrld->arQue[i].signal)); + gps_dl_put_op(&pgps_dl_ctrld->rFreeOpQ, &(pgps_dl_ctrld->arQue[i])); + } + + iRet = gps_dl_osal_thread_run(pThread); + if (iRet) { + GDL_LOGE("gps data link ontrol thread run fail:%d", iRet); + return -1; + } + + return 0; +} + +int gps_dl_ctrld_deinit(void) +{ + struct gps_dl_osal_thread *pThread; + int iRet; + + pThread = &gps_dl_ctrld.thread; + + iRet = gps_dl_osal_thread_stop(pThread); + if (iRet) + GDL_LOGE("gps data link ontrol thread stop fail:%d", iRet); + else + GDL_LOGI("gps data link ontrol thread stop okay:%d", iRet); + + gps_dl_osal_event_deinit(&gps_dl_ctrld.rgpsdlWq); + + iRet = gps_dl_osal_thread_destroy(pThread); + if (iRet) { + GDL_LOGE("gps data link ontrol thread destroy fail:%d", iRet); + return -1; + } + GDL_LOGI("gps data link ontrol thread destroy okay:%d\n", iRet); + + return 0; +} + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/linux/gps_dl_emi.c b/drivers/misc/mediatek/connectivity/gps/data_link/linux/gps_dl_emi.c new file mode 100644 index 0000000000000000000000000000000000000000..ddef3321738044aa718438b28259df6c4628d084 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/linux/gps_dl_emi.c @@ -0,0 +1,228 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#include "gps_dl_config.h" + +#if GPS_DL_HAS_PLAT_DRV +/******************************************************************************* +* Dependency +*******************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gps_dl_log.h" +#include "gps_dl_linux_reserved_mem.h" +#include "gps_dl_emi.h" + +/****************************************************************************** + * Definition +******************************************************************************/ +/* device name and major number */ +#define GPS_DL_EMI_DEVNAME "gps_emi" +#define IOCTL_EMI_MEMORY_INIT 1 +#define IOCTL_MNL_NVRAM_FILE_TO_MEM 2 +#define IOCTL_MNL_NVRAM_MEM_TO_FILE 3 +#define IOCTL_ADC_CAPTURE_ADDR_GET 4 + + +/******************************************************************************* +* structure & enumeration +*******************************************************************************/ +/*---------------------------------------------------------------------------*/ +struct gps_icap_dev { + struct class *cls; + struct device *dev; + dev_t devno; + struct cdev chdev; +}; + +struct gps_icap_dev *gps_icap_dev_ptr; + +char gps_icap_local_buf[GPS_ICAP_BUF_SIZE]; + + +/*---------------------------------------------------------------------------*/ +long gps_icap_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + int retval = 0; +#if 0 + unsigned int *tmp; +#endif + + GDL_LOGI("cmd (%d),arg(%ld)\n", cmd, arg); + + switch (cmd) { + case IOCTL_EMI_MEMORY_INIT: + GDL_LOGW("IOCTL_EMI_MEMORY_INIT"); + break; + + case IOCTL_MNL_NVRAM_FILE_TO_MEM: + GDL_LOGW("IOCTL_MNL_NVRAM_FILE_TO_MEM"); + break; + + case IOCTL_MNL_NVRAM_MEM_TO_FILE: + GDL_LOGW("IOCTL_MNL_NVRAM_MEM_TO_FILE"); + break; + + case IOCTL_ADC_CAPTURE_ADDR_GET: +#if 0 + tmp = (unsigned int *)&gGpsIcapPhyBase; + GPS_DBG("gps_emi:gGpsIcapPhyBase (%x)\n", &gGpsIcapPhyBase); + GPS_DBG("gps_emi:tmp (%x)\n", tmp); + if (copy_to_user((unsigned int __user *)arg, tmp, sizeof(unsigned int))) + retval = -1; +#endif + GDL_LOGW("IOCTL_ADC_CAPTURE_ADDR_GET,(%d)", retval); + break; + + default: + GDL_LOGW("unknown cmd (%d)", cmd); + retval = 0; + break; + } + return retval; + +} + +/******************************************************************************/ +long gps_icap_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + return gps_icap_unlocked_ioctl(filp, cmd, arg); +} + +/*****************************************************************************/ +static int gps_icap_open(struct inode *inode, struct file *file) +{ + return nonseekable_open(inode, file); +} + +/*****************************************************************************/ + + +/*****************************************************************************/ +static int gps_icap_release(struct inode *inode, struct file *file) +{ + return 0; +} + +/******************************************************************************/ +static ssize_t gps_icap_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) +{ + void *p_src; + + GDL_LOGI("begin"); + + if (count > GPS_ICAP_BUF_SIZE) + count = GPS_ICAP_BUF_SIZE; + + p_src = gps_dl_reserved_mem_icap_buf_get_vir_addr(); + + if (p_src == NULL) { + GDL_LOGW("src is null, return"); + return 0; + } + + memcpy_fromio(&gps_icap_local_buf[0], p_src, GPS_ICAP_BUF_SIZE); + + if (copy_to_user(buf, (char *)&gps_icap_local_buf[0], count)) { + GDL_LOGW("copy to user fail, return"); + return 0; + } + + GDL_LOGI("finish, count = %ld", count); + return count; +} + +/******************************************************************************/ +static ssize_t gps_icap_write(struct file *file, const char __user *buf, size_t count, + loff_t *ppos) +{ + ssize_t ret = 0; + + GDL_LOGW("count = %ld", count); + + return ret; +} + +/*****************************************************************************/ +/* Kernel interface */ +static const struct file_operations gps_icap_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = gps_icap_unlocked_ioctl, + .compat_ioctl = gps_icap_compat_ioctl, + .open = gps_icap_open, + .read = gps_icap_read, + .write = gps_icap_write, + .release = gps_icap_release, +}; + +/*****************************************************************************/ +void gps_icap_probe(void) +{ + int ret = 0, err = 0; + + GDL_LOGI("start"); + + gps_icap_dev_ptr = kzalloc(sizeof(*gps_icap_dev_ptr), GFP_KERNEL); + if (gps_icap_dev_ptr == NULL) { + err = -ENOMEM; + ret = -ENOMEM; + goto err_out; + } + + GDL_LOGD("registering chardev"); + ret = alloc_chrdev_region(&gps_icap_dev_ptr->devno, 0, 1, GPS_DL_EMI_DEVNAME); + if (ret) { + GDL_LOGE("alloc_chrdev_region fail: %d", ret); + err = -ENOMEM; + goto err_out; + } else + GDL_LOGI("major: %d, minor: %d", + MAJOR(gps_icap_dev_ptr->devno), MINOR(gps_icap_dev_ptr->devno)); + + cdev_init(&gps_icap_dev_ptr->chdev, &gps_icap_fops); + gps_icap_dev_ptr->chdev.owner = THIS_MODULE; + err = cdev_add(&gps_icap_dev_ptr->chdev, gps_icap_dev_ptr->devno, 1); + if (err) { + GDL_LOGE("cdev_add fail: %d", err); + goto err_out; + } + + gps_icap_dev_ptr->cls = class_create(THIS_MODULE, "gpsemi"); + if (IS_ERR(gps_icap_dev_ptr->cls)) { + GDL_LOGE("unable to create class, err = %d\n", (int)PTR_ERR(gps_icap_dev_ptr->cls)); + goto err_out; + } + gps_icap_dev_ptr->dev = device_create(gps_icap_dev_ptr->cls, + NULL, gps_icap_dev_ptr->devno, gps_icap_dev_ptr, "gps_emi"); + + GDL_LOGI("done"); + return; + +err_out: + if (gps_icap_dev_ptr != NULL) { + if (err == 0) + cdev_del(&gps_icap_dev_ptr->chdev); + if (ret == 0) + unregister_chrdev_region(gps_icap_dev_ptr->devno, 1); + + kfree(gps_icap_dev_ptr); + gps_icap_dev_ptr = NULL; + } +} + +#endif /* GPS_DL_HAS_PLAT_DRV */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/linux/gps_dl_linux.c b/drivers/misc/mediatek/connectivity/gps/data_link/linux/gps_dl_linux.c new file mode 100644 index 0000000000000000000000000000000000000000..183decbdad7b65893a97e4000d9d58a0baeda309 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/linux/gps_dl_linux.c @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#include "gps_dl_linux.h" +#include "gps_dl_hal.h" +#include "gps_dl_log.h" + +void gps_dl_irq_mask(int irq_id, enum gps_dl_irq_ctrl_from from) +{ + /* TODO: */ + /* threaded_irq thread_fn still need to call disable_irq_nosync, + * otherwise it might be hung. + */ + if (from == GPS_DL_IRQ_CTRL_FROM_ISR) + disable_irq_nosync(irq_id); + else + /* It returns until irq done */ + disable_irq(irq_id); +} + +void gps_dl_irq_unmask(int irq_id, enum gps_dl_irq_ctrl_from from) +{ + /* TODO: */ + enable_irq(irq_id); +} + +static int gps_dl_linux_irq_index_to_id(enum gps_dl_irq_index_enum index) +{ + /* TODO: fill the real number or the value from dts */ + return gps_dl_irq_index_to_id(index); +} + +/* TODO: call it when module init */ +int gps_dl_linux_irqs_register(struct gps_each_irq *p_irqs, int irq_num) +{ + int irq_id, i_ret, i; + unsigned long sys_irq_flags; + + for (i = 0; i < irq_num; i++) { + irq_id = gps_dl_linux_irq_index_to_id(p_irqs[i].cfg.index); + + if (irq_id == 0) { + GDL_LOGE_INI("i = %d, irq_id = %d, name = %s, bypass", + i, irq_id, p_irqs[i].cfg.name); + continue; + } + + if (p_irqs[i].cfg.trig_type == GPS_DL_IRQ_TRIG_LEVEL_HIGH) + sys_irq_flags = IRQF_TRIGGER_HIGH; + else if (p_irqs[i].cfg.trig_type == GPS_DL_IRQ_TRIG_EDGE_RISING) + sys_irq_flags = IRQF_TRIGGER_RISING; + else + return -1; + + /* TODO: Use the dts to auto request the irqs */ +#if GPS_DL_USE_THREADED_IRQ + /* IRQF_ONESHOT is required for threaded irq */ + sys_irq_flags |= IRQF_ONESHOT; + i_ret = request_threaded_irq(irq_id, NULL, + (irq_handler_t)p_irqs[i].cfg.isr, + sys_irq_flags, p_irqs[i].cfg.name, &p_irqs[i]); +#else + i_ret = request_irq(irq_id, + (irq_handler_t)p_irqs[i].cfg.isr, /* gps_dl_linux_irq_dispatcher */ + sys_irq_flags, p_irqs[i].cfg.name, &p_irqs[i]); +#endif + GDL_LOGW_INI("i = %d, irq_id = %d, name = %s, flags = 0x%lx, ret = %d", + i, irq_id, p_irqs[i].cfg.name, sys_irq_flags, i_ret); + if (i_ret) { + /* show error log */ + /* return i_ret; */ + continue; /* not stop even fail */ + } + + /* The init status is unmask, mask them here */ + gps_dl_irq_mask(irq_id, GPS_DL_IRQ_CTRL_FROM_THREAD); + p_irqs[i].register_done = true; + p_irqs[i].reg_irq_id = irq_id; + } + + return 0; +} + +int gps_dl_linux_irqs_unregister(struct gps_each_irq *p_irqs, int irq_num) +{ + int irq_id, i; + + for (i = 0; i < irq_num; i++) { + if (p_irqs[i].register_done) { + irq_id = gps_dl_linux_irq_index_to_id(p_irqs[i].cfg.index); + /* assert irq_id = p_irqs[i].reg_irq_id */ + free_irq(irq_id, &p_irqs[i]); + + p_irqs[i].register_done = false; + p_irqs[i].reg_irq_id = 0; + } + } + + return 0; +} + +irqreturn_t gps_dl_linux_irq_dispatcher(int irq, void *data) +{ + struct gps_each_irq *p_irq; + + p_irq = (struct gps_each_irq *)data; + + switch (p_irq->cfg.index) { + case GPS_DL_IRQ_LINK0_DATA: + gps_dl_isr_usrt_has_data(GPS_DATA_LINK_ID0); + break; + case GPS_DL_IRQ_LINK0_NODATA: + gps_dl_isr_usrt_has_nodata(GPS_DATA_LINK_ID0); + break; + case GPS_DL_IRQ_LINK0_MCUB: + gps_dl_isr_mcub(GPS_DATA_LINK_ID0); + break; + + case GPS_DL_IRQ_LINK1_DATA: + gps_dl_isr_usrt_has_data(GPS_DATA_LINK_ID1); + break; + case GPS_DL_IRQ_LINK1_NODATA: + gps_dl_isr_usrt_has_nodata(GPS_DATA_LINK_ID1); + break; + case GPS_DL_IRQ_LINK1_MCUB: + gps_dl_isr_mcub(GPS_DATA_LINK_ID1); + break; + + case GPS_DL_IRQ_DMA: + gps_dl_isr_dma_done(); + break; + + default: + break; + } + + return IRQ_HANDLED; +} + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/linux/gps_dl_linux_plat_drv.c b/drivers/misc/mediatek/connectivity/gps/data_link/linux/gps_dl_linux_plat_drv.c new file mode 100644 index 0000000000000000000000000000000000000000..0410a0b3937ed025f1602f4f1edea75fe7d82c33 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/linux/gps_dl_linux_plat_drv.c @@ -0,0 +1,555 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#include "gps_dl_config.h" + +#if GPS_DL_HAS_PLAT_DRV +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gps_dl_linux.h" +#include "gps_dl_linux_plat_drv.h" +#include "gps_dl_linux_reserved_mem.h" +#include "gps_dl_isr.h" +#include "gps_each_device.h" + +/* #ifdef CONFIG_OF */ +const struct of_device_id gps_dl_of_ids[] = { + { .compatible = "mediatek,mt6885-gps", }, + {} +}; +/* #endif */ +#define GPS_DL_IOMEM_NUM 2 + +struct gps_dl_iomem_addr_map_entry g_gps_dl_iomem_arrary[GPS_DL_IOMEM_NUM]; +struct gps_dl_iomem_addr_map_entry g_gps_dl_status_dummy_cr; +struct gps_dl_iomem_addr_map_entry g_gps_dl_tia1_gps; +struct gps_dl_iomem_addr_map_entry g_gps_dl_tia2_gps_on; +struct gps_dl_iomem_addr_map_entry g_gps_dl_tia2_gps_rc_sel; + + +void __iomem *gps_dl_host_addr_to_virt(unsigned int host_addr) +{ + int i; + int offset; + struct gps_dl_iomem_addr_map_entry *p; + + for (i = 0; i < GPS_DL_IOMEM_NUM; i++) { + p = &g_gps_dl_iomem_arrary[i]; + + if (p->length == 0) + continue; + + offset = host_addr - p->host_phys_addr; + if (offset >= 0 && offset < p->length) + return p->host_virt_addr + offset; + } + + return (void __iomem *)0; +} + +void gps_dl_update_status_for_md_blanking(bool gps_is_on) +{ + void __iomem *p = g_gps_dl_status_dummy_cr.host_virt_addr; + unsigned int val = (gps_is_on ? 1 : 0); + unsigned int val_old, val_new; + + if (p != NULL) { + val_old = __raw_readl(p); + gps_dl_linux_sync_writel(val, p); + val_new = __raw_readl(p); + GDL_LOGI_INI("dummy cr updated: %d -> %d, due to on = %d", + val_old, val_new, gps_is_on); + } else + GDL_LOGW_INI("dummy cr addr is invalid, can not update (on = %d)", gps_is_on); +} + +void gps_dl_tia1_gps_ctrl(bool gps_is_on) +{ + void __iomem *p = g_gps_dl_tia1_gps.host_virt_addr; + unsigned int tia_gps_on, tia_gps_ctrl, tia_temp; + unsigned int tia_gps_on1, tia_gps_ctrl1, tia_temp1; + + if (p == NULL) { + GDL_LOGW_INI("on = %d, tia_gps addr is null", gps_is_on); + return; + } + + tia_gps_on = __raw_readl(p); + tia_gps_ctrl = __raw_readl(p + 4); + tia_temp = __raw_readl(p + 8); + + if (gps_is_on) { + /* 0x1001C018[0] = 1 (GPS on) */ + gps_dl_linux_sync_writel(tia_gps_on | 1UL, p); + + /* 0x1001C01C[11:0] = 100 (~3ms update period, 1/32k = 0.03125ms) + * 0x1001C01C[12] = 1 (enable TSX) + * 0x1001C01C[13] = 1 (enable DCXO) + */ + /* 20190923 period changed to 196 (0xC4, 6ms) */ + gps_dl_linux_sync_writel((196UL | (1UL << 12) | (1UL << 13)), p + 4); + } else { + /* 0x1001C018[0] = 0 (GPS off) */ + gps_dl_linux_sync_writel(tia_gps_on & ~1UL, p); + } + + tia_gps_on1 = __raw_readl(p); + tia_gps_ctrl1 = __raw_readl(p + 4); + tia_temp1 = __raw_readl(p + 8); + + GDL_LOGI_INI( + "on = %d, tia_gps_on = 0x%08x/0x%08x, ctrl = 0x%08x/0x%08x, temp = 0x%08x/0x%08x", + gps_is_on, tia_gps_on, tia_gps_on1, + tia_gps_ctrl, tia_gps_ctrl1, + tia_temp, tia_temp1); +} + +void gps_dl_tia2_gps_ctrl(bool gps_is_on) +{ + void __iomem *p_gps_on = g_gps_dl_tia2_gps_on.host_virt_addr; + void __iomem *p_gps_rc_sel = g_gps_dl_tia2_gps_rc_sel.host_virt_addr; + unsigned int tia2_gps_on_old = 0, tia2_gps_rc_sel_old = 0; + unsigned int tia2_gps_on_new = 0, tia2_gps_rc_sel_new = 0; + + if (p_gps_on == NULL) { + GDL_LOGW_INI("on = %d, tia2_gps_on addr is null", gps_is_on); + return; + } + + tia2_gps_on_old = __raw_readl(p_gps_on); + if (gps_is_on) { + /* 0x1001C000[5] = 1 (GPS on) */ + gps_dl_linux_sync_writel(tia2_gps_on_old | (1UL << 5), p_gps_on); + + if (p_gps_rc_sel == NULL) + GDL_LOGW_INI("on = %d, p_gps_rc_sel addr is null", gps_is_on); + else { + /* 0x1001C030[ 1: 0] = 0 + * 0x1001C030[ 5: 4] = 0 + * 0x1001C030[ 9: 8] = 0 + * 0x1001C030[13:12] = 0 + * 0x1001C030[17:16] = 0 + */ + tia2_gps_rc_sel_old = __raw_readl(p_gps_rc_sel); + gps_dl_linux_sync_writel(tia2_gps_rc_sel_old & ~(0x00033333), p_gps_rc_sel); + tia2_gps_rc_sel_new = __raw_readl(p_gps_rc_sel); + } + } else { + tia2_gps_rc_sel_old = __raw_readl(p_gps_rc_sel); + + /* 0x1001C000[5] = 0 (GPS off) */ + gps_dl_linux_sync_writel(tia2_gps_on_old & ~(1UL << 5), p_gps_on); + } + tia2_gps_on_new = __raw_readl(p_gps_on); + GDL_LOGI_INI( + "on = %d, tia2_gps_on = 0x%08x/0x%08x, rc_sel = 0x%08x/0x%08x", + gps_is_on, + tia2_gps_on_old, tia2_gps_on_new, + tia2_gps_rc_sel_old, tia2_gps_rc_sel_new); +} + +void gps_dl_tia_gps_ctrl(bool gps_is_on) +{ + if (g_gps_dl_tia2_gps_on.host_virt_addr != NULL) + gps_dl_tia2_gps_ctrl(gps_is_on); + else if (g_gps_dl_tia1_gps.host_virt_addr != NULL) + gps_dl_tia1_gps_ctrl(gps_is_on); + else + GDL_LOGE("tia reg not found, bypass!"); +} + +enum gps_dl_pinctrl_state_enum { + GPS_DL_L1_LNA_DISABLE, + GPS_DL_L1_LNA_DSP_CTRL, + GPS_DL_L1_LNA_ENABLE, + GPS_DL_L5_LNA_DISABLE, + GPS_DL_L5_LNA_DSP_CTRL, + GPS_DL_L5_LNA_ENABLE, + GPS_DL_PINCTRL_STATE_CNT +}; + +const char *const gps_dl_pinctrl_state_name_list[GPS_DL_PINCTRL_STATE_CNT] = { + "gps_l1_lna_disable", + "gps_l1_lna_dsp_ctrl", + "gps_l1_lna_enable", + "gps_l5_lna_disable", + "gps_l5_lna_dsp_ctrl", + "gps_l5_lna_enable", +}; + +struct pinctrl_state *g_gps_dl_pinctrl_state_struct_list[GPS_DL_PINCTRL_STATE_CNT]; +struct pinctrl *g_gps_dl_pinctrl_ptr; + +void gps_dl_pinctrl_show_info(void) +{ + enum gps_dl_pinctrl_state_enum state_id; + const char *p_name; + struct pinctrl_state *p_state; + + GDL_LOGD_INI("pinctrl_ptr = 0x%p", g_gps_dl_pinctrl_ptr); + + for (state_id = 0; state_id < GPS_DL_PINCTRL_STATE_CNT; state_id++) { + p_name = gps_dl_pinctrl_state_name_list[state_id]; + p_state = g_gps_dl_pinctrl_state_struct_list[state_id]; + GDL_LOGD_INI("state id = %d, ptr = 0x%p, name = %s", + state_id, p_state, p_name); + } +} + +void gps_dl_pinctrl_context_init(void) +{ + enum gps_dl_pinctrl_state_enum state_id; + const char *p_name; + struct pinctrl_state *p_state; + + if (IS_ERR(g_gps_dl_pinctrl_ptr)) { + GDL_LOGE_INI("pinctrl is error"); + return; + } + + for (state_id = 0; state_id < GPS_DL_PINCTRL_STATE_CNT; state_id++) { + p_name = gps_dl_pinctrl_state_name_list[state_id]; + p_state = pinctrl_lookup_state(g_gps_dl_pinctrl_ptr, p_name); + + if (IS_ERR(p_state)) { + GDL_LOGE_INI("lookup fail: state id = %d, name = %s", state_id, p_name); + g_gps_dl_pinctrl_state_struct_list[state_id] = NULL; + continue; + } + + g_gps_dl_pinctrl_state_struct_list[state_id] = p_state; + GDL_LOGW_INI("lookup okay: state id = %d, name = %s", state_id, p_name); + } +} + +void gps_dl_lna_pin_ctrl(enum gps_dl_link_id_enum link_id, bool dsp_is_on, bool force_en) +{ + struct pinctrl_state *p_state = NULL; + int ret; + + ASSERT_LINK_ID(link_id, GDL_VOIDF()); + + if (GPS_DATA_LINK_ID0 == link_id) { + if (dsp_is_on && force_en) + p_state = g_gps_dl_pinctrl_state_struct_list[GPS_DL_L1_LNA_ENABLE]; + else if (dsp_is_on) + p_state = g_gps_dl_pinctrl_state_struct_list[GPS_DL_L1_LNA_DSP_CTRL]; + else + p_state = g_gps_dl_pinctrl_state_struct_list[GPS_DL_L1_LNA_DISABLE]; + } + + if (GPS_DATA_LINK_ID1 == link_id) { + if (dsp_is_on && force_en) + p_state = g_gps_dl_pinctrl_state_struct_list[GPS_DL_L5_LNA_ENABLE]; + else if (dsp_is_on) + p_state = g_gps_dl_pinctrl_state_struct_list[GPS_DL_L5_LNA_DSP_CTRL]; + else + p_state = g_gps_dl_pinctrl_state_struct_list[GPS_DL_L5_LNA_DISABLE]; + } + + if (p_state == NULL) { + GDL_LOGXW(link_id, "on = %d, force = %d, state is null", dsp_is_on, force_en); + return; + } + + ret = pinctrl_select_state(g_gps_dl_pinctrl_ptr, p_state); + if (ret != 0) + GDL_LOGXW(link_id, "on = %d, force = %d, select ret = %d", dsp_is_on, force_en, ret); + else + GDL_LOGXD(link_id, "on = %d, force = %d, select ret = %d", dsp_is_on, force_en, ret); +} + +bool gps_dl_get_iomem_by_name(struct platform_device *pdev, const char *p_name, + struct gps_dl_iomem_addr_map_entry *p_entry) +{ + struct resource *regs; + bool okay; + + regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, p_name); + if (regs != NULL) { + p_entry->length = resource_size(regs); + p_entry->host_phys_addr = regs->start; + p_entry->host_virt_addr = devm_ioremap(&pdev->dev, p_entry->host_phys_addr, p_entry->length); + okay = true; + } else { + p_entry->length = 0; + p_entry->host_phys_addr = 0; + p_entry->host_virt_addr = 0; + okay = false; + } + + GDL_LOGW_INI("phy_addr = 0x%08x, vir_addr = 0x%p, ok = %d, size = 0x%x, name = %s", + p_entry->host_phys_addr, p_entry->host_virt_addr, okay, p_entry->length, p_name); + + return okay; +} + +#if (GPS_DL_GET_RSV_MEM_IN_MODULE) +phys_addr_t gGpsRsvMemPhyBase; +unsigned long long gGpsRsvMemSize; +static int gps_dl_get_reserved_memory(struct device *dev) +{ + struct device_node *np; + struct reserved_mem *rmem; + + np = of_parse_phandle(dev->of_node, "memory-region", 0); + if (!np) { + GDL_LOGE_INI("no memory-region 1"); + return -EINVAL; + } + rmem = of_reserved_mem_lookup(np); + of_node_put(np); + if (!rmem) { + GDL_LOGE_INI("no memory-region 2"); + return -EINVAL; + } + GDL_LOGW_INI("resource base=%pa, size=%pa", &rmem->base, &rmem->size); + gGpsRsvMemPhyBase = (phys_addr_t)rmem->base; + gGpsRsvMemSize = (unsigned long long)rmem->size; + return 0; +} +#endif + +static int gps_dl_probe(struct platform_device *pdev) +{ + struct resource *irq; + struct gps_each_device *p_each_dev0 = gps_dl_device_get(GPS_DATA_LINK_ID0); + struct gps_each_device *p_each_dev1 = gps_dl_device_get(GPS_DATA_LINK_ID1); + int i; + bool okay; + +#if (GPS_DL_GET_RSV_MEM_IN_MODULE) + gps_dl_get_reserved_memory(&pdev->dev); +#endif + gps_dl_get_iomem_by_name(pdev, "conn_infra_base", &g_gps_dl_iomem_arrary[0]); + gps_dl_get_iomem_by_name(pdev, "conn_gps_base", &g_gps_dl_iomem_arrary[1]); + + okay = gps_dl_get_iomem_by_name(pdev, "status_dummy_cr", &g_gps_dl_status_dummy_cr); + if (okay) + gps_dl_update_status_for_md_blanking(false); + + /* TIA 1 */ + gps_dl_get_iomem_by_name(pdev, "tia_gps", &g_gps_dl_tia1_gps); + + /* TIA 2 */ + gps_dl_get_iomem_by_name(pdev, "tia2_gps_on", &g_gps_dl_tia2_gps_on); + gps_dl_get_iomem_by_name(pdev, "tia2_gps_rc_sel", &g_gps_dl_tia2_gps_rc_sel); + + for (i = 0; i < GPS_DL_IRQ_NUM; i++) { + irq = platform_get_resource(pdev, IORESOURCE_IRQ, i); + if (irq == NULL) { + GDL_LOGE_INI("irq idx = %d, ptr = NULL!", i); + continue; + } + + GDL_LOGW_INI("irq idx = %d, start = %lld, end = %lld, name = %s, flag = 0x%lx", + i, irq->start, irq->end, irq->name, irq->flags); + gps_dl_irq_set_id(i, irq->start); + } + + g_gps_dl_pinctrl_ptr = devm_pinctrl_get(&pdev->dev); + if (IS_ERR(g_gps_dl_pinctrl_ptr)) + GDL_LOGE_INI("devm_pinctrl_get fail"); + else { + gps_dl_pinctrl_context_init(); + gps_dl_pinctrl_show_info(); + } + + GDL_LOGW_INI("do gps_dl_probe"); + platform_set_drvdata(pdev, p_each_dev0); + p_each_dev0->private_data = (struct device *)&pdev->dev; + p_each_dev1->private_data = (struct device *)&pdev->dev; + + gps_dl_device_context_init(); + + return 0; +} + +static int gps_dl_remove(struct platform_device *pdev) +{ + struct gps_each_device *p_each_dev = gps_dl_device_get(GPS_DATA_LINK_ID0); + + GDL_LOGW_INI("do gps_dl_remove"); + platform_set_drvdata(pdev, NULL); + p_each_dev->private_data = NULL; + return 0; +} + +static int gps_dl_drv_suspend(struct device *dev) +{ +#if 0 + struct platform_device *pdev = to_platform_device(dev); + pm_message_t state = PMSG_SUSPEND; + + return mtk_btif_suspend(pdev, state); +#endif + return 0; +} + +static int gps_dl_drv_resume(struct device *dev) +{ +#if 0 + struct platform_device *pdev = to_platform_device(dev); + + return mtk_btif_resume(pdev); +#endif + return 0; +} + +static int gps_dl_plat_suspend(struct platform_device *pdev, pm_message_t state) +{ +#if 0 + int i_ret = 0; + struct _mtk_btif_ *p_btif = NULL; + + BTIF_DBG_FUNC("++\n"); + p_btif = platform_get_drvdata(pdev); + i_ret = _btif_suspend(p_btif); + BTIF_DBG_FUNC("--, i_ret:%d\n", i_ret); + return i_ret; +#endif + return 0; +} + +static int gps_dl_plat_resume(struct platform_device *pdev) +{ +#if 0 + int i_ret = 0; + struct _mtk_btif_ *p_btif = NULL; + + BTIF_DBG_FUNC("++\n"); + p_btif = platform_get_drvdata(pdev); + i_ret = _btif_resume(p_btif); + BTIF_DBG_FUNC("--, i_ret:%d\n", i_ret); + return i_ret; +#endif + return 0; +} + + +const struct dev_pm_ops gps_dl_drv_pm_ops = { + .suspend = gps_dl_drv_suspend, + .resume = gps_dl_drv_resume, +}; + +struct platform_driver gps_dl_dev_drv = { + .probe = gps_dl_probe, + .remove = gps_dl_remove, +/* #ifdef CONFIG_PM */ + .suspend = gps_dl_plat_suspend, + .resume = gps_dl_plat_resume, +/* #endif */ + .driver = { + .name = "gps", /* mediatek,gps */ + .owner = THIS_MODULE, +/* #ifdef CONFIG_PM */ + .pm = &gps_dl_drv_pm_ops, +/* #endif */ +/* #ifdef CONFIG_OF */ + .of_match_table = gps_dl_of_ids, +/* #endif */ + } +}; + +static ssize_t driver_flag_read(struct device_driver *drv, char *buf) +{ + return sprintf(buf, "gps dl driver debug level:%d\n", 1); +} + +static ssize_t driver_flag_set(struct device_driver *drv, + const char *buffer, size_t count) +{ + GDL_LOGW_INI("buffer = %s, count = %zd", buffer, count); + return count; +} + +#define DRIVER_ATTR(_name, _mode, _show, _store) \ + struct driver_attribute driver_attr_##_name = \ + __ATTR(_name, _mode, _show, _store) +static DRIVER_ATTR(flag, 0644, driver_flag_read, driver_flag_set); + + +int gps_dl_linux_plat_drv_register(void) +{ + int result; + gps_dl_wake_lock_init(); + + result = platform_driver_register(&gps_dl_dev_drv); + /* if (result) */ + GDL_LOGW_INI("platform_driver_register, ret(%d)\n", result); + + result = driver_create_file(&gps_dl_dev_drv.driver, &driver_attr_flag); + /* if (result) */ + GDL_LOGW_INI("driver_create_file, ret(%d)\n", result); + + return 0; +} + +int gps_dl_linux_plat_drv_unregister(void) +{ + driver_remove_file(&gps_dl_dev_drv.driver, &driver_attr_flag); + platform_driver_unregister(&gps_dl_dev_drv); + gps_dl_wake_lock_deinit(); + + return 0; +} + +static struct wakeup_source *g_gps_dl_wake_lock_ptr; +const char c_gps_dl_wake_lock_name[] = "gpsdl_wakelock"; +void gps_dl_wake_lock_init(void) +{ + GDL_LOGD_INI(""); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 149) + g_gps_dl_wake_lock_ptr = wakeup_source_register(NULL, c_gps_dl_wake_lock_name); +#else + g_gps_dl_wake_lock_ptr = wakeup_source_register(c_gps_dl_wake_lock_name); +#endif +} + +void gps_dl_wake_lock_deinit(void) +{ + GDL_LOGD_INI(""); + wakeup_source_unregister(g_gps_dl_wake_lock_ptr); +} + +void gps_dl_wake_lock_hold(bool hold) +{ + GDL_LOGD_ONF("hold = %d", hold); + if (hold) + __pm_stay_awake(g_gps_dl_wake_lock_ptr); + else + __pm_relax(g_gps_dl_wake_lock_ptr); +} + +#endif /* GPS_DL_HAS_PLAT_DRV */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/linux/gps_dl_linux_reserved_mem.c b/drivers/misc/mediatek/connectivity/gps/data_link/linux/gps_dl_linux_reserved_mem.c new file mode 100644 index 0000000000000000000000000000000000000000..2207129e68ac126373befa600d886ba4500fa848 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/linux/gps_dl_linux_reserved_mem.c @@ -0,0 +1,204 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#include "gps_dl_config.h" + +#if GPS_DL_HAS_PLAT_DRV +#include "gps_dl_context.h" +#include "gps_dl_linux_plat_drv.h" +#include "gps_dl_linux_reserved_mem.h" +#include "gps_dl_emi.h" + +#include + +#if (GPS_DL_SET_EMI_MPU_CFG) +#include +#if (defined(CONFIG_MACH_MT6885) || defined(CONFIG_MACH_MT6893)) +#define GPS_DL_EMI_MPU_DOMAIN_AP 0 +#define GPS_DL_EMI_MPU_DOMAIN_CONN 2 +#define GPS_DL_EMI_MPU_REGION_NUM 29 +#endif +#endif + +#define GPS_ICAP_MEM_SIZE (GPS_ICAP_BUF_SIZE) +#define GPS_RESERVED_MEM_PADDING_SIZE (4*1024) + +struct gps_dl_reserved_mem_layout { + unsigned char icap_buf[GPS_ICAP_MEM_SIZE]; + unsigned char padding1[GPS_RESERVED_MEM_PADDING_SIZE]; + unsigned char tx_dma_buf[GPS_DATA_LINK_NUM][GPS_DL_RX_BUF_SIZE + GPS_RESERVED_MEM_PADDING_SIZE]; + unsigned char rx_dma_buf[GPS_DATA_LINK_NUM][GPS_DL_RX_BUF_SIZE + GPS_RESERVED_MEM_PADDING_SIZE]; +}; + +struct gps_dl_iomem_addr_map_entry g_gps_dl_res_emi; + +void gps_dl_reserved_mem_init(void) +{ + void __iomem *host_virt_addr = NULL; +#if (GPS_DL_SET_EMI_MPU_CFG) + struct emimpu_region_t region; + int emimpu_ret1, emimpu_ret2, emimpu_ret3, emimpu_ret4, emimpu_ret5, emimpu_ret6; +#endif + unsigned int min_size = sizeof(struct gps_dl_reserved_mem_layout); + + if (gGpsRsvMemPhyBase == (phys_addr_t)NULL || gGpsRsvMemSize < min_size) { + GDL_LOGE_INI("res_mem: base = 0x%llx, size = 0x%llx, min_size = %d, not enough", + (unsigned long long)gGpsRsvMemPhyBase, + (unsigned long long)gGpsRsvMemSize, min_size); + return; + } + + host_virt_addr = ioremap_nocache(gGpsRsvMemPhyBase, gGpsRsvMemSize); + if (host_virt_addr == NULL) { + GDL_LOGE_INI("res_mem: base = 0x%llx, size = 0x%llx, ioremap fail", + (unsigned long long)gGpsRsvMemPhyBase, (unsigned long long)gGpsRsvMemSize); + return; + } + + /* Set EMI MPU permission */ +#if (GPS_DL_SET_EMI_MPU_CFG) + GDL_LOGI_INI("emi mpu cfg: region = %d, no protection domain = %d, %d", + GPS_DL_EMI_MPU_REGION_NUM, GPS_DL_EMI_MPU_DOMAIN_AP, GPS_DL_EMI_MPU_DOMAIN_CONN); + emimpu_ret1 = mtk_emimpu_init_region(®ion, GPS_DL_EMI_MPU_REGION_NUM); + emimpu_ret2 = mtk_emimpu_set_addr(®ion, gGpsRsvMemPhyBase, gGpsRsvMemPhyBase + gGpsRsvMemSize - 1); + emimpu_ret3 = mtk_emimpu_set_apc(®ion, GPS_DL_EMI_MPU_DOMAIN_AP, MTK_EMIMPU_NO_PROTECTION); + emimpu_ret4 = mtk_emimpu_set_apc(®ion, GPS_DL_EMI_MPU_DOMAIN_CONN, MTK_EMIMPU_NO_PROTECTION); + emimpu_ret5 = mtk_emimpu_set_protection(®ion); + emimpu_ret6 = mtk_emimpu_free_region(®ion); + GDL_LOGI_INI("emi mpu cfg: ret = %d, %d, %d, %d, %d, %d", + emimpu_ret1, emimpu_ret2, emimpu_ret3, emimpu_ret4, emimpu_ret5, emimpu_ret6); +#endif + + g_gps_dl_res_emi.host_phys_addr = gGpsRsvMemPhyBase; + g_gps_dl_res_emi.host_virt_addr = host_virt_addr; + g_gps_dl_res_emi.length = gGpsRsvMemSize; + + GDL_LOGI_INI("phy_addr = 0x%08x, vir_addr = 0x%p, size = 0x%x, min_size = 0x%x", + g_gps_dl_res_emi.host_phys_addr, + g_gps_dl_res_emi.host_virt_addr, + g_gps_dl_res_emi.length, min_size); + gps_dl_reserved_mem_show_info(); + gps_icap_probe(); +} + +void gps_dl_reserved_mem_deinit(void) +{ + GDL_LOGI_INI("phy_addr = 0x%08x, vir_addr = 0x%p, size = 0x%x", + g_gps_dl_res_emi.host_phys_addr, + g_gps_dl_res_emi.host_virt_addr, + g_gps_dl_res_emi.length); + + if (g_gps_dl_res_emi.host_virt_addr != NULL) + iounmap(g_gps_dl_res_emi.host_virt_addr); + else + GDL_LOGW_INI("host_virt_addr already null, not do iounmap"); + + g_gps_dl_res_emi.host_phys_addr = (dma_addr_t)NULL; + g_gps_dl_res_emi.host_virt_addr = (void *)NULL; + g_gps_dl_res_emi.length = 0; +} + +bool gps_dl_reserved_mem_is_ready(void) +{ + return (g_gps_dl_res_emi.host_virt_addr != NULL); +} + +void gps_dl_reserved_mem_get_range(unsigned int *p_min, unsigned int *p_max) +{ + *p_min = g_gps_dl_res_emi.host_phys_addr; + *p_max = g_gps_dl_res_emi.host_phys_addr + g_gps_dl_res_emi.length; +} + +void gps_dl_reserved_mem_show_info(void) +{ + unsigned int min_size = sizeof(struct gps_dl_reserved_mem_layout); + struct gps_dl_reserved_mem_layout *p_mem_vir; + unsigned int p_mem_phy; + unsigned int p_buf_phy, offset; + enum gps_dl_link_id_enum link_id; + + p_mem_phy = g_gps_dl_res_emi.host_phys_addr; + p_mem_vir = (struct gps_dl_reserved_mem_layout *)g_gps_dl_res_emi.host_virt_addr; + + GDL_LOGI_INI("phy_addr = 0x%08x, vir_addr = 0x%p, size = 0x%x, min_size = 0x%x", + g_gps_dl_res_emi.host_phys_addr, + g_gps_dl_res_emi.host_virt_addr, + g_gps_dl_res_emi.length, min_size); + + offset = (unsigned int)((void *)&p_mem_vir->icap_buf[0] - (void *)p_mem_vir); + GDL_LOGD_INI("icap_buf: phy_addr = 0x%08x, vir_addr = 0x%p, size = 0x%x", + p_mem_phy + offset, &p_mem_vir->icap_buf[0], GPS_ICAP_MEM_SIZE); + + for (link_id = 0; link_id < GPS_DATA_LINK_NUM; link_id++) { + offset = (unsigned int)((void *)&p_mem_vir->tx_dma_buf[link_id][0] - (void *)p_mem_vir); + p_buf_phy = p_mem_phy + offset; + GDL_LOGXD_INI(link_id, "tx_dma_buf: phy_addr = 0x%08x, vir_addr = 0x%p, size = 0x%x", + p_buf_phy, &p_mem_vir->tx_dma_buf[link_id][0], GPS_DL_TX_BUF_SIZE); + + offset = (unsigned int)((void *)&p_mem_vir->rx_dma_buf[link_id][0] - (void *)p_mem_vir); + p_buf_phy = p_mem_phy + offset; + GDL_LOGXD_INI(link_id, "rx_dma_buf: phy_addr = 0x%08x, vir_addr = 0x%p, size = 0x%x", + p_buf_phy, &p_mem_vir->rx_dma_buf[link_id][0], GPS_DL_RX_BUF_SIZE); + } +} + +void gps_dl_reserved_mem_dma_buf_init(struct gps_dl_dma_buf *p_dma_buf, + enum gps_dl_link_id_enum link_id, enum gps_dl_dma_dir dir, unsigned int len) +{ + struct gps_dl_reserved_mem_layout *p_mem_vir; + unsigned int p_mem_phy, offset; + + p_mem_vir = (struct gps_dl_reserved_mem_layout *)g_gps_dl_res_emi.host_virt_addr; + p_mem_phy = g_gps_dl_res_emi.host_phys_addr; + + memset(p_dma_buf, 0, sizeof(*p_dma_buf)); + p_dma_buf->dev_index = link_id; + p_dma_buf->dir = dir; + p_dma_buf->len = len; + + if (dir == GDL_DMA_A2D) { + p_dma_buf->vir_addr = (void *)&p_mem_vir->tx_dma_buf[link_id][0]; + } else if (dir == GDL_DMA_D2A) { + p_dma_buf->vir_addr = (void *)&p_mem_vir->rx_dma_buf[link_id][0]; + } else { + GDL_LOGXE(link_id, ""); + return; + } + + offset = (unsigned int)((void *)p_dma_buf->vir_addr - (void *)p_mem_vir); + p_dma_buf->phy_addr = p_mem_phy + offset; + + GDL_LOGI_INI("init gps dl dma buf(%d,%d) in arch64, addr: vir=0x%p, phy=0x%llx, len=%u\n", + p_dma_buf->dev_index, p_dma_buf->dir, + p_dma_buf->vir_addr, + p_dma_buf->phy_addr, p_dma_buf->len); +} + +void gps_dl_reserved_mem_dma_buf_deinit(struct gps_dl_dma_buf *p_dma_buf) +{ + memset(p_dma_buf, 0, sizeof(*p_dma_buf)); +} + +void *gps_dl_reserved_mem_icap_buf_get_vir_addr(void) +{ + struct gps_dl_reserved_mem_layout *p_mem_vir; + unsigned int p_mem_phy, offset; + + p_mem_phy = g_gps_dl_res_emi.host_phys_addr; + p_mem_vir = (struct gps_dl_reserved_mem_layout *)g_gps_dl_res_emi.host_virt_addr; + + if (p_mem_vir == NULL) { + GDL_LOGE("gps_icap_buf: null"); + return NULL; + } + + offset = (unsigned int)((void *)&p_mem_vir->icap_buf[0] - (void *)p_mem_vir); + GDL_LOGI("gps_icap_buf: phy_addr = 0x%08x, vir_addr = 0x%p, size = 0x%x", + p_mem_phy + offset, &p_mem_vir->icap_buf[0], GPS_ICAP_MEM_SIZE); + + return (void *)&p_mem_vir->icap_buf[0]; +} + +#endif /* GPS_DL_HAS_PLAT_DRV */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/linux/gps_dl_osal.c b/drivers/misc/mediatek/connectivity/gps/data_link/linux/gps_dl_osal.c new file mode 100644 index 0000000000000000000000000000000000000000..2dc57d6a9450ad4d50feca8731b2721b17234906 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/linux/gps_dl_osal.c @@ -0,0 +1,326 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#include "gps_dl_config.h" + +#include "gps_dl_osal.h" +#include "gps_dl_log.h" + + +char *gps_dl_osal_strncpy(char *dst, const char *src, unsigned int len) +{ + return strncpy(dst, src, len); +} + +char *gps_dl_osal_strsep(char **str, const char *c) +{ + return strsep(str, c); +} + +int gps_dl_osal_strtol(const char *str, unsigned int adecimal, long *res) +{ + if (sizeof(long) == 4) + return kstrtou32(str, adecimal, (unsigned int *) res); + else + return kstrtol(str, adecimal, res); +} + +void *gps_dl_osal_memset(void *buf, int i, unsigned int len) +{ + return memset(buf, i, len); +} + +int gps_dl_osal_thread_create(struct gps_dl_osal_thread *pThread) +{ + if (!pThread) + return -1; + + pThread->pThread = kthread_create(pThread->pThreadFunc, pThread->pThreadData, pThread->threadName); + if (pThread->pThread == NULL) + return -1; + + return 0; +} + +int gps_dl_osal_thread_run(struct gps_dl_osal_thread *pThread) +{ + if ((pThread) && (pThread->pThread)) { + wake_up_process(pThread->pThread); + return 0; + } else + return -1; +} + +int gps_dl_osal_thread_stop(struct gps_dl_osal_thread *pThread) +{ + int iRet; + + if ((pThread) && (pThread->pThread)) { + iRet = kthread_stop(pThread->pThread); + /* pThread->pThread = NULL; */ + return iRet; + } + return -1; +} + +int gps_dl_osal_thread_should_stop(struct gps_dl_osal_thread *pThread) +{ + if ((pThread) && (pThread->pThread)) + return kthread_should_stop(); + else + return 1; + +} + +int gps_dl_osal_thread_destroy(struct gps_dl_osal_thread *pThread) +{ + if (pThread && (pThread->pThread)) { + kthread_stop(pThread->pThread); + pThread->pThread = NULL; + } + return 0; +} + +int gps_dl_osal_thread_wait_for_event(struct gps_dl_osal_thread *pThread, + struct gps_dl_osal_event *pEvent, OSAL_EVENT_CHECKER pChecker) +{ + if ((pThread) && (pThread->pThread) && (pEvent) && (pChecker)) { + return wait_event_interruptible(pEvent->waitQueue, ( + gps_dl_osal_thread_should_stop(pThread) + || (*pChecker) (pThread))); + } + return -1; +} + +int gps_dl_osal_signal_init(struct gps_dl_osal_signal *pSignal) +{ + if (pSignal) { + init_completion(&pSignal->comp); + return 0; + } else + return -1; +} + +int gps_dl_osal_wait_for_signal(struct gps_dl_osal_signal *pSignal) +{ + if (pSignal) { + wait_for_completion_interruptible(&pSignal->comp); + return 0; + } else + return -1; +} + +/* + * gps_dl_osal_wait_for_signal_timeout + * + * Wait for a signal to be triggered by the corresponding thread, within the + * expected timeout specified by the signal's timeoutValue. + * When the pThread parameter is specified, the thread's scheduling ability is + * considered, the timeout will be extended when thread cannot acquire CPU + * resource, and will only extend for a number of times specified by the + * signal's timeoutExtension should the situation continues. + * + * Return value: + * 0 : timeout + * >0 : signal triggered + */ +int gps_dl_osal_wait_for_signal_timeout(struct gps_dl_osal_signal *pSignal, struct gps_dl_osal_thread *pThread) +{ + /* struct gps_dl_osal_thread_schedstats schedstats; */ + /* int waitRet; */ + + /* return wait_for_completion_interruptible_timeout(&pSignal->comp, msecs_to_jiffies(pSignal->timeoutValue)); */ + /* [ChangeFeature][George] gps driver may be closed by -ERESTARTSYS. + * Avoid using *interruptible" version in order to complete our jobs, such + * as function off gracefully. + */ + if (!pThread || !pThread->pThread) + return wait_for_completion_timeout(&pSignal->comp, msecs_to_jiffies(pSignal->timeoutValue)); +#if 0 + do { + osal_thread_sched_mark(pThread, &schedstats); + waitRet = wait_for_completion_timeout(&pSignal->comp, msecs_to_jiffies(pSignal->timeoutValue)); + osal_thread_sched_unmark(pThread, &schedstats); + + if (waitRet > 0) + break; + + if (schedstats.runnable > schedstats.exec) { + gps_dl_osal_err_print( + "[E]%s:wait completion timeout, %s cannot get CPU, extension(%d), show backtrace:\n", + __func__, + pThread->threadName, + pSignal->timeoutExtension); + } else { + gps_dl_osal_err_print("[E]%s:wait completion timeout, show %s backtrace:\n", + __func__, + pThread->threadName); + pSignal->timeoutExtension = 0; + } + gps_dl_osal_err_print("[E]%s:\tduration:%llums, sched(x%llu/r%llu/i%llu)\n", + __func__, + schedstats.time, + schedstats.exec, + schedstats.runnable, + schedstats.iowait); + /* + * no need to disginguish combo or A/D die projects + * osal_dump_thread_state will just return if target thread does not exist + */ + osal_dump_thread_state("mtk_wmtd"); + osal_dump_thread_state("btif_rxd"); + osal_dump_thread_state("mtk_stp_psm"); + osal_dump_thread_state("mtk_stp_btm"); + osal_dump_thread_state("stp_sdio_tx_rx"); + } while (pSignal->timeoutExtension--); + return waitRet; +#endif + return 1; +} + +int gps_dl_osal_raise_signal(struct gps_dl_osal_signal *pSignal) +{ + if (pSignal) { + complete(&pSignal->comp); + return 0; + } else + return -1; +} + +int gps_dl_osal_signal_active_state(struct gps_dl_osal_signal *pSignal) +{ + if (pSignal) + return pSignal->timeoutValue; + else + return -1; +} + +int gps_dl_osal_op_is_wait_for_signal(struct gps_dl_osal_lxop *pOp) +{ + return (pOp && pOp->signal.timeoutValue) ? 1 : 0; +} + +void gps_dl_osal_op_raise_signal(struct gps_dl_osal_lxop *pOp, int result) +{ + if (pOp) { + pOp->result = result; + gps_dl_osal_raise_signal(&pOp->signal); + } +} + +int gps_dl_osal_signal_deinit(struct gps_dl_osal_signal *pSignal) +{ + if (pSignal) { + pSignal->timeoutValue = 0; + return 0; + } else + return -1; +} + +/* + *OSAL layer Event Opeartion related APIs + *initialization + *wait for signal + *wait for signal timerout + *raise signal + *destroy a signal + * +*/ + +int gps_dl_osal_event_init(struct gps_dl_osal_event *pEvent) +{ + if (pEvent) { + init_waitqueue_head(&pEvent->waitQueue); + return 0; + } + return -1; +} + +int gps_dl_osal_trigger_event(struct gps_dl_osal_event *pEvent) +{ + int ret = 0; + + if (pEvent) { + wake_up_interruptible(&pEvent->waitQueue); + return ret; + } + return -1; +} + +int gps_dl_osal_wait_for_event(struct gps_dl_osal_event *pEvent, int (*condition)(void *), void *cond_pa) +{ + if (pEvent) + return wait_event_interruptible(pEvent->waitQueue, condition(cond_pa)); + else + return -1; +} + +int gps_dl_osal_wait_for_event_timeout(struct gps_dl_osal_event *pEvent, int (*condition)(void *), void *cond_pa) +{ + if (pEvent) + return wait_event_interruptible_timeout(pEvent->waitQueue, + condition(cond_pa), + msecs_to_jiffies(pEvent->timeoutValue)); + return -1; +} + +int gps_dl_osal_event_deinit(struct gps_dl_osal_event *pEvent) +{ + return 0; +} + +int gps_dl_osal_sleepable_lock_init(struct gps_dl_osal_sleepable_lock *pSL) +{ + mutex_init(&pSL->lock); + return 0; +} + +int gps_dl_osal_lock_sleepable_lock(struct gps_dl_osal_sleepable_lock *pSL) +{ + return mutex_lock_killable(&pSL->lock); +} + +int gps_dl_osal_unlock_sleepable_lock(struct gps_dl_osal_sleepable_lock *pSL) +{ + mutex_unlock(&pSL->lock); + return 0; +} + +int gps_dl_osal_trylock_sleepable_lock(struct gps_dl_osal_sleepable_lock *pSL) +{ + return mutex_trylock(&pSL->lock); +} + +int gps_dl_osal_sleepable_lock_deinit(struct gps_dl_osal_sleepable_lock *pSL) +{ + mutex_destroy(&pSL->lock); + return 0; +} + +int gps_dl_osal_unsleepable_lock_init(struct gps_dl_osal_unsleepable_lock *pUSL) +{ + spin_lock_init(&(pUSL->lock)); + return 0; +} + +int gps_dl_osal_lock_unsleepable_lock(struct gps_dl_osal_unsleepable_lock *pUSL) +{ + spin_lock_irqsave(&(pUSL->lock), pUSL->flag); + return 0; +} + +int gps_dl_osal_unlock_unsleepable_lock(struct gps_dl_osal_unsleepable_lock *pUSL) +{ + spin_unlock_irqrestore(&(pUSL->lock), pUSL->flag); + return 0; +} + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/linux/gps_dl_procfs.c b/drivers/misc/mediatek/connectivity/gps/data_link/linux/gps_dl_procfs.c new file mode 100644 index 0000000000000000000000000000000000000000..bb92ed55e55ff6c7f4ff1b40a725fee639f5e0ca --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/linux/gps_dl_procfs.c @@ -0,0 +1,239 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#include "gps_dl_config.h" + +#include +#include +#include +#include "gps_dl_osal.h" +#include "gps_dl_procfs.h" +#include "gps_dl_context.h" +#include "gps_each_link.h" +#include "gps_dl_subsys_reset.h" + +int gps_dl_procfs_dummy_op(int y, int z) +{ + GDL_LOGW("do nothing: y = %d, z = %d", y, z); + return 0; +} + +int gps_dl_procfs_set_opt(int y, int z) +{ + if (y == 0) + gps_dl_log_info_show(); + else if (y == 1) { + enum gps_dl_log_level_enum level_old, level_new; + + level_old = gps_dl_log_level_get(); + gps_dl_log_level_set(z); + level_new = gps_dl_log_level_get(); + GDL_LOGW("log level change: %d to %d", level_old, level_new); + } else if (y == 2) { + unsigned int mod_old, mod_new; + + mod_old = gps_dl_log_mod_bitmask_get(); + gps_dl_log_mod_bitmask_set(z); + mod_new = gps_dl_log_level_get(); + GDL_LOGW("log modules change: 0x%x to 0x%x", mod_old, mod_new); + } else if (y == 3) { + unsigned int mod_old, mod_new; + + mod_old = gps_dl_log_mod_bitmask_get(); + gps_dl_log_mod_on(z); + mod_new = gps_dl_log_level_get(); + GDL_LOGW("log modules change: 0x%x to 0x%x", mod_old, mod_new); + } else if (y == 4) { + unsigned int mod_old, mod_new; + + mod_old = gps_dl_log_mod_bitmask_get(); + gps_dl_log_mod_off(z); + mod_new = gps_dl_log_level_get(); + GDL_LOGW("log modules change: 0x%x to 0x%x", mod_old, mod_new); + } else if (y == 5) { + bool rrw_old, rrw_new; + + rrw_old = gps_dl_show_reg_rw_log(); + if (z == 0) + gps_dl_set_show_reg_rw_log(false); + else if (z == 1) + gps_dl_set_show_reg_rw_log(true); + rrw_new = gps_dl_show_reg_rw_log(); + GDL_LOGW("log rrw change: %d to %d", rrw_old, rrw_new); + } + + return 0; +} + +int gps_dl_procfs_trigger_reset(int y, int z) +{ + if (y == 0) + gps_dl_trigger_connsys_reset(); + else if (y == 1) + gps_dl_trigger_gps_subsys_reset((bool)z); + else if (y == 2 && (z >= 0 && z <= GPS_DATA_LINK_NUM)) + gps_each_link_reset(z); + else if (y == 3) + gps_dl_trigger_gps_print_hw_status(); + else if (y == 4 && (z >= 0 && z <= GPS_DATA_LINK_NUM)) + gps_dl_test_mask_hasdata_irq_set(z, true); + else if (y == 6 && (z >= 0 && z <= GPS_DATA_LINK_NUM)) + gps_dl_test_mask_mcub_irq_on_open_set(z, true); + else if (y == 7) + gps_dl_trigger_gps_print_data_status(); + return 0; +} + +gps_dl_procfs_test_func_type g_gps_dl_proc_test_func_list[] = { + [0x00] = gps_dl_procfs_dummy_op, + /* [0x01] = TODO: reg read */ + /* [0x02] = TODO: reg write */ + [0x03] = gps_dl_procfs_set_opt, + [0x04] = gps_dl_procfs_trigger_reset, +}; + +#define UNLOCK_MAGIC 0xDB9DB9 +#define PROCFS_WR_BUF_SIZE 256 +ssize_t gps_dl_procfs_write(struct file *filp, const char __user *buffer, size_t count, loff_t *f_pos) +{ + size_t len = count, sub_len; + char buf[PROCFS_WR_BUF_SIZE]; + char *pBuf; + int x = 0, y = 0, z = 0; + char *pToken = NULL; + long res; + static bool gpsdl_dbg_enabled; + + GDL_LOGD("write parameter len = %d", (int)len); + if (len >= PROCFS_WR_BUF_SIZE) { + GDL_LOGE("input handling fail!"); + return -1; + } + + if (copy_from_user(buf, buffer, len)) + return -EFAULT; + + buf[len] = '\0'; + pBuf = buf; + do { + if (!pBuf) { + GDL_LOGW("x,y,z use default value - case0"); + break; + } + res = 0; + sub_len = strlen(pBuf); + GDL_LOGD("write parameter data = %s, len = %ld", pBuf, sub_len); + if (sub_len != 0) + pToken = gps_dl_osal_strsep(&pBuf, "\t\n\r "); + if (sub_len != 0 && pToken != NULL) { + gps_dl_osal_strtol(pToken, 16, &res); + x = (int)res; + } else { + GDL_LOGW("x use default value"); + break; + } + + if (!pBuf) { + GDL_LOGW("y use default value - case1"); + break; + } + res = 0; + sub_len = strlen(pBuf); + GDL_LOGD("write parameter data = %s, len = %ld", pBuf, sub_len); + if (sub_len != 0) + pToken = gps_dl_osal_strsep(&pBuf, "\t\n\r "); + if (sub_len != 0 && pToken != NULL) { + gps_dl_osal_strtol(pToken, 16, &res); + y = (int)res; + } else { + GDL_LOGW("y use default value - case2"); + break; + } + + if (!pBuf) { + GDL_LOGW("z use default value - case1"); + break; + } + res = 0; + sub_len = strlen(pBuf); + GDL_LOGD("write parameter data = %s, len = %ld", pBuf, sub_len); + if (sub_len != 0) + pToken = gps_dl_osal_strsep(&pBuf, "\t\n\r "); + if (sub_len != 0 && pToken != NULL) { + gps_dl_osal_strtol(pToken, 16, &res); + z = (int)res; + } else { + GDL_LOGW("z use default value - case2"); + break; + } + } while (0); + GDL_LOGW("x = 0x%08x, y = 0x%08x, z = 0x%08x", x, y, z); + + /* For eng and userdebug load, have to enable gpsdl_dbg by + * writing 0xDB9DB9 to * "/proc/driver/gpsdl_dbg" to avoid + * some malicious use + */ + if (x == UNLOCK_MAGIC) { + gpsdl_dbg_enabled = true; + return len; + } + + if (!gpsdl_dbg_enabled) { + GDL_LOGW("please enable gpsdl_dbg firstly"); + return len; + } + + if (ARRAY_SIZE(g_gps_dl_proc_test_func_list) > x && NULL != g_gps_dl_proc_test_func_list[x]) + (*g_gps_dl_proc_test_func_list[x])(y, z); + else + GDL_LOGW("no handler defined for command id, x = 0x%08x", x); + + return len; +} + +ssize_t gps_dl_procfs_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) +{ + return 0; +} + +static const struct file_operations gps_dl_procfs_fops = { + .owner = THIS_MODULE, + .read = gps_dl_procfs_read, + .write = gps_dl_procfs_write, +}; + +static struct proc_dir_entry *g_gps_dl_procfs_entry; +#define GPS_DL_PROCFS_NAME "driver/gpsdl_dbg" + +int gps_dl_procfs_setup(void) +{ + + int i_ret = 0; + + g_gps_dl_procfs_entry = proc_create(GPS_DL_PROCFS_NAME, + 0664, NULL, &gps_dl_procfs_fops); + + if (g_gps_dl_procfs_entry == NULL) { + GDL_LOGE("Unable to create gps proc entry"); + i_ret = -1; + } + + return i_ret; +} + +int gps_dl_procfs_remove(void) +{ + if (g_gps_dl_procfs_entry != NULL) + proc_remove(g_gps_dl_procfs_entry); + return 0; +} + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/linux/gps_each_device.c b/drivers/misc/mediatek/connectivity/gps/data_link/linux/gps_each_device.c new file mode 100644 index 0000000000000000000000000000000000000000..928590299764854e8b15474c46f693accc9db300 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/linux/gps_each_device.c @@ -0,0 +1,469 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#include "gps_each_device.h" +#include "gps_each_link.h" +#include "gps_dsp_fsm.h" +#if GPS_DL_MOCK_HAL +#include "gps_mock_mvcd.h" +#endif +#include "gps_dl_hal.h" +#include "gps_dl_ctrld.h" +#include "gps_data_link_devices.h" +#include "gps_dl_subsys_reset.h" +#include "gps_dl_hist_rec.h" + +static ssize_t gps_each_device_read(struct file *filp, + char __user *buf, size_t count, loff_t *f_pos) +{ + int retval; + int retlen; + int pid; + struct gps_each_device *dev; + enum gps_dl_link_id_enum link_id; + bool print_log = false; + + dev = (struct gps_each_device *)filp->private_data; + pid = current->pid; + link_id = (enum gps_dl_link_id_enum)dev->index; + + /* show read log after ram code downloading to avoid print too much */ + if (gps_dsp_state_get(link_id) != GPS_DSP_ST_RESET_DONE) { + GDL_LOGXI_DRW(link_id, "buf_len = %ld, pid = %d", count, pid); + print_log = true; + } else { + GDL_LOGXD_DRW(link_id, "buf_len = %ld, pid = %d", count, pid); + } + gps_each_link_rec_read(link_id, pid, count, DRW_ENTER); + + retlen = gps_each_link_read(link_id, &dev->i_buf[0], count); + if (retlen > 0) { + retval = copy_to_user(buf, &dev->i_buf[0], retlen); + if (retval != 0) { + GDL_LOGXW_DRW(link_id, "copy to user len = %d, retval = %d", + retlen, retval); + retlen = -EFAULT; + } + } + if (print_log) + GDL_LOGXI_DRW(link_id, "ret_len = %d", retlen); + else + GDL_LOGXD_DRW(link_id, "ret_len = %d", retlen); + gps_each_link_rec_read(link_id, pid, retlen, DRW_RETURN); + return retlen; +} + +static ssize_t gps_each_device_write(struct file *filp, + const char __user *buf, size_t count, loff_t *f_pos) +{ + int retval; + int retlen = 0; + int copy_size; + int pid; + struct gps_each_device *dev; + enum gps_dl_link_id_enum link_id; + bool print_log = false; + + dev = (struct gps_each_device *)filp->private_data; + pid = current->pid; + link_id = (enum gps_dl_link_id_enum)dev->index; + + /* show write log after ram code downloading to avoid print too much */ + if (gps_dsp_state_get(link_id) != GPS_DSP_ST_RESET_DONE) { + GDL_LOGXI_DRW(link_id, "len = %ld, pid = %d", count, pid); + print_log = true; + } else { + GDL_LOGXD_DRW(link_id, "len = %ld, pid = %d", count, pid); + } + gps_each_link_rec_write(link_id, pid, count, DRW_ENTER); + + if (count > 0) { + if (count > GPS_DATA_PATH_BUF_MAX) { + GDL_LOGXW_DRW(link_id, "len = %ld is too long", count); + copy_size = GPS_DATA_PATH_BUF_MAX; + } else + copy_size = count; + + retval = copy_from_user(&dev->o_buf[0], &buf[0], copy_size); + if (retval != 0) { + GDL_LOGXW_DRW(link_id, "copy from user len = %d, retval = %d", + copy_size, retval); + retlen = -EFAULT; + } else { + retval = gps_each_link_write(link_id, &dev->o_buf[0], copy_size); + if (retval == 0) + retlen = copy_size; + else + retlen = 0; + } + } + + if (print_log) + GDL_LOGXI_DRW(link_id, "ret_len = %d", retlen); + else + GDL_LOGXD_DRW(link_id, "ret_len = %d", retlen); + gps_each_link_rec_write(link_id, pid, retlen, DRW_RETURN); + return retlen; +} + +#if 0 +void gps_each_device_data_submit(unsigned char *buf, unsigned int len, int index) +{ + struct gps_each_device *dev; + + dev = gps_dl_device_get(index); + + GDL_LOGI("gps_each_device_data_submit len = %d, index = %d, dev = %p", + len, index, dev); + + if (!dev) + return; + + if (!dev->is_open) + return; + +#if GPS_DL_CTRLD_MOCK_LINK_LAYER + /* TODO: using mutex, len check */ + memcpy(&dev->i_buf[0], buf, len); + dev->i_len = len; + wake_up(&dev->r_wq); +#else + gps_dl_add_to_rx_queue(buf, len, index); + /* wake_up(&dev->r_wq); */ +#endif + + GDL_LOGI("gps_each_device_data_submit copy and wakeup done"); +} +#endif + +static int gps_each_device_open(struct inode *inode, struct file *filp) +{ + struct gps_each_device *dev; /* device information */ + int retval; + + dev = container_of(inode->i_cdev, struct gps_each_device, cdev); + filp->private_data = dev; /* for other methods */ + + GDL_LOGXW(dev->index, "major = %d, minor = %d, pid = %d", + imajor(inode), iminor(inode), current->pid); + + if (!dev->is_open) { + retval = gps_each_link_open((enum gps_dl_link_id_enum)dev->index); + + if (0 == retval) { + dev->is_open = true; + gps_each_link_rec_reset(dev->index); + } else + return retval; + } + + return 0; +} + +static int gps_each_device_hw_resume(enum gps_dl_link_id_enum link_id) +{ + int pid; + int retval; + + pid = current->pid; + GDL_LOGXW(link_id, "pid = %d", pid); + + retval = gps_each_link_hw_resume(link_id); + + /* device read may arrive before resume, not reset the recording here + * gps_each_link_rec_reset(link_id); + */ + + return retval; +} + +static int gps_each_device_release(struct inode *inode, struct file *filp) +{ + struct gps_each_device *dev; + + dev = (struct gps_each_device *)filp->private_data; + dev->is_open = false; + + GDL_LOGXW(dev->index, "major = %d, minor = %d, pid = %d", + imajor(inode), iminor(inode), current->pid); + + gps_each_link_close((enum gps_dl_link_id_enum)dev->index); + gps_each_link_rec_force_dump(dev->index); + + return 0; +} + +static int gps_each_device_hw_suspend(enum gps_dl_link_id_enum link_id, bool need_clk_ext) +{ + int pid; + int retval; + + pid = current->pid; + GDL_LOGXW(link_id, "pid = %d, clk_ext = %d", pid, need_clk_ext); + + retval = gps_each_link_hw_suspend(link_id, need_clk_ext); + gps_each_link_rec_force_dump(link_id); + + return retval; +} + +#define GPSDL_IOC_GPS_HWVER 6 +#define GPSDL_IOC_GPS_IC_HW_VERSION 7 +#define GPSDL_IOC_GPS_IC_FW_VERSION 8 +#define GPSDL_IOC_D1_EFUSE_GET 9 +#define GPSDL_IOC_RTC_FLAG 10 +#define GPSDL_IOC_CO_CLOCK_FLAG 11 +#define GPSDL_IOC_TRIGGER_ASSERT 12 +#define GPSDL_IOC_QUERY_STATUS 13 +#define GPSDL_IOC_TAKE_GPS_WAKELOCK 14 +#define GPSDL_IOC_GIVE_GPS_WAKELOCK 15 +#define GPSDL_IOC_GET_GPS_LNA_PIN 16 +#define GPSDL_IOC_GPS_FWCTL 17 +#define GPSDL_IOC_GPS_HW_SUSPEND 18 +#define GPSDL_IOC_GPS_HW_RESUME 19 +#define GPSDL_IOC_GPS_LISTEN_RST_EVT 20 + +static int gps_each_device_ioctl_inner(struct file *filp, unsigned int cmd, unsigned long arg, bool is_compat) +{ + struct gps_each_device *dev; /* device information */ + int retval; + +#if 0 + dev = container_of(inode->i_cdev, struct gps_each_device, cdev); + filp->private_data = dev; /* for other methods */ +#endif + dev = (struct gps_each_device *)(filp->private_data); + + GDL_LOGXD(dev->index, "cmd = %d, is_compat = %d", cmd, is_compat); +#if 0 + int retval = 0; + ENUM_WMTHWVER_TYPE_T hw_ver_sym = WMTHWVER_INVALID; + UINT32 hw_version = 0; + UINT32 fw_version = 0; + UINT32 gps_lna_pin = 0; +#endif + switch (cmd) { + case GPSDL_IOC_TRIGGER_ASSERT: + /* Trigger FW assert for debug */ + GDL_LOGXW_DRW(dev->index, "GPSDL_IOC_TRIGGER_ASSERT, reason = %ld", arg); + + /* TODO: assert dev->is_open */ + if (dev->index == GPS_DATA_LINK_ID0) + retval = gps_dl_trigger_gps_subsys_reset(false); + else + retval = gps_each_link_reset(dev->index); + break; + case GPSDL_IOC_QUERY_STATUS: + retval = gps_each_link_check(dev->index, arg); + gps_each_link_rec_force_dump(dev->index); + GDL_LOGXW_DRW(dev->index, "GPSDL_IOC_QUERY_STATUS, reason = %ld, ret = %d", arg, retval); + break; + case GPSDL_IOC_CO_CLOCK_FLAG: + retval = gps_dl_link_get_clock_flag(); + GDL_LOGXD_ONF(dev->index, "gps clock flag = 0x%x", retval); + break; +#if 0 + case GPSDL_IOC_GPS_HWVER: + /*get combo hw version */ + /* hw_ver_sym = mtk_wcn_wmt_hwver_get(); */ + + GPS_DBG_FUNC("GPS_ioctl(): get hw version = %d, sizeof(hw_ver_sym) = %zd\n", + hw_ver_sym, sizeof(hw_ver_sym)); + if (copy_to_user((int __user *)arg, &hw_ver_sym, sizeof(hw_ver_sym))) + retval = -EFAULT; + + break; + case GPSDL_IOC_GPS_IC_HW_VERSION: + /*get combo hw version from ic, without wmt mapping */ + hw_version = mtk_wcn_wmt_ic_info_get(WMTCHIN_HWVER); + + GPS_DBG_FUNC("GPS_ioctl(): get hw version = 0x%x\n", hw_version); + if (copy_to_user((int __user *)arg, &hw_version, sizeof(hw_version))) + retval = -EFAULT; + + break; + + case GPSDL_IOC_GPS_IC_FW_VERSION: + /*get combo fw version from ic, without wmt mapping */ + fw_version = mtk_wcn_wmt_ic_info_get(WMTCHIN_FWVER); + + GPS_DBG_FUNC("GPS_ioctl(): get fw version = 0x%x\n", fw_version); + if (copy_to_user((int __user *)arg, &fw_version, sizeof(fw_version))) + retval = -EFAULT; + + break; + case GPSDL_IOC_RTC_FLAG: + + retval = rtc_GPS_low_power_detected(); + + GPS_DBG_FUNC("low power flag (%d)\n", retval); + break; + case GPSDL_IOC_CO_CLOCK_FLAG: +#if SOC_CO_CLOCK_FLAG + retval = mtk_wcn_wmt_co_clock_flag_get(); +#endif + GPS_DBG_FUNC("GPS co_clock_flag (%d)\n", retval); + break; + case GPSDL_IOC_D1_EFUSE_GET: +#if defined(CONFIG_MACH_MT6735) + do { + char *addr = ioremap(0x10206198, 0x4); + + retval = *(unsigned int *)addr; + GPS_DBG_FUNC("D1 efuse (0x%x)\n", retval); + iounmap(addr); + } while (0); +#elif defined(CONFIG_MACH_MT6763) + do { + char *addr = ioremap(0x11f10048, 0x4); + + retval = *(unsigned int *)addr; + GPS_DBG_FUNC("MT6763 efuse (0x%x)\n", retval); + iounmap(addr); + } while (0); +#else + GPS_ERR_FUNC("Read Efuse not supported in this platform\n"); +#endif + break; + + case GPSDL_IOC_TAKE_GPS_WAKELOCK: + GPS_INFO_FUNC("Ioctl to take gps wakelock\n"); + gps_hold_wake_lock(1); + if (wake_lock_acquired == 1) + retval = 0; + else + retval = -EAGAIN; + break; + case GPSDL_IOC_GIVE_GPS_WAKELOCK: + GPS_INFO_FUNC("Ioctl to give gps wakelock\n"); + gps_hold_wake_lock(0); + if (wake_lock_acquired == 0) + retval = 0; + else + retval = -EAGAIN; + break; +#ifdef GPS_FWCTL_SUPPORT + case GPSDL_IOC_GPS_FWCTL: + GPS_INFO_FUNC("GPSDL_IOC_GPS_FWCTL\n"); + retval = GPS_fwctl((struct gps_fwctl_data *)arg); + break; +#endif + case GPSDL_IOC_GET_GPS_LNA_PIN: + gps_lna_pin = mtk_wmt_get_gps_lna_pin_num(); + GPS_DBG_FUNC("GPS_ioctl(): get gps lna pin = %d\n", gps_lna_pin); + if (copy_to_user((int __user *)arg, &gps_lna_pin, sizeof(gps_lna_pin))) + retval = -EFAULT; + break; +#endif + case GPSDL_IOC_GPS_HW_SUSPEND: + /* arg == 1 stand for need clk extension, otherwise is normal deep sotp mode */ + retval = gps_each_device_hw_suspend(dev->index, (arg == 1)); + GDL_LOGXI_ONF(dev->index, + "GPSDL_IOC_GPS_HW_SUSPEND: arg = %ld, ret = %d", arg, retval); + break; + case GPSDL_IOC_GPS_HW_RESUME: + retval = gps_each_device_hw_resume(dev->index); + GDL_LOGXI_ONF(dev->index, + "GPSDL_IOC_GPS_HW_RESUME: arg = %ld, ret = %d", arg, retval); + break; + case GPSDL_IOC_GPS_LISTEN_RST_EVT: + retval = -EINVAL; + GDL_LOGXI_ONF(dev->index, + "GPSDL_IOC_GPS_LISTEN_RST_EVT retval = %d", retval); + break; + case 21505: + case 21506: + case 21515: + /* known unsupported cmd */ + retval = -EFAULT; + GDL_LOGXD_DRW(dev->index, "cmd = %d, not support", cmd); + break; + default: + retval = -EFAULT; + GDL_LOGXI_DRW(dev->index, "cmd = %d, not support", cmd); + break; + } + + return retval; +} + + +static long gps_each_device_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + return gps_each_device_ioctl_inner(filp, cmd, arg, false); +} + +static long gps_each_device_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + return gps_each_device_ioctl_inner(filp, cmd, arg, true); +} + +static const struct file_operations gps_each_device_fops = { + .owner = THIS_MODULE, + .open = gps_each_device_open, + .read = gps_each_device_read, + .write = gps_each_device_write, + .release = gps_each_device_release, + .unlocked_ioctl = gps_each_device_unlocked_ioctl, + .compat_ioctl = gps_each_device_compat_ioctl, +}; + +int gps_dl_cdev_setup(struct gps_each_device *dev, int index) +{ + int result; + + init_waitqueue_head(&dev->r_wq); + dev->i_len = 0; + + dev->index = index; + /* assert dev->index == dev->cfg.index */ + + cdev_init(&dev->cdev, &gps_each_device_fops); + dev->cdev.owner = THIS_MODULE; + dev->cdev.ops = &gps_each_device_fops; + + result = cdev_add(&dev->cdev, dev->devno, 1); + if (result) { + GDL_LOGE("cdev_add error %d on index %d", result, index); + return result; + } + + dev->cls = class_create(THIS_MODULE, dev->cfg.dev_name); + if (IS_ERR(dev->cls)) { + GDL_LOGE("class_create fail on %s", dev->cfg.dev_name); + return -1; + } + + dev->dev = device_create(dev->cls, NULL, dev->devno, NULL, dev->cfg.dev_name); + if (IS_ERR(dev->dev)) { + GDL_LOGE("device_create fail on %s", dev->cfg.dev_name); + return -1; + } + + return 0; +} + +void gps_dl_cdev_cleanup(struct gps_each_device *dev, int index) +{ + if (dev->dev) { + device_destroy(dev->cls, dev->devno); + dev->dev = NULL; + } + + if (dev->cls) { + class_destroy(dev->cls); + dev->cls = NULL; + } + + cdev_del(&dev->cdev); +} + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/linux/inc/gps_data_link_devices.h b/drivers/misc/mediatek/connectivity/gps/data_link/linux/inc/gps_data_link_devices.h new file mode 100644 index 0000000000000000000000000000000000000000..d23e0ebc14f428100ac397a8a6f8e8f253e8cff7 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/linux/inc/gps_data_link_devices.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#ifndef _GPS_DATA_LINK_DEVICES_H +#define _GPS_DATA_LINK_DEVICES_H + +#include "gps_dl_config.h" + +int mtk_gps_data_link_devices_init(void); +void mtk_gps_data_link_devices_exit(void); + +#endif /* _GPS_DATA_LINK_DEVICES_H */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/linux/inc/gps_dl_ctrld.h b/drivers/misc/mediatek/connectivity/gps/data_link/linux/inc/gps_dl_ctrld.h new file mode 100644 index 0000000000000000000000000000000000000000..6f95e8ff8a375336114288e94851d18309165d06 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/linux/inc/gps_dl_ctrld.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#ifndef _GPS_DL_CTRLD_H +#define _GPS_DL_CTRLD_H +#include "gps_dl_osal.h" +#include "gps_dl_config.h" + +#define GPS_DL_OP_BUF_SIZE (16) + +enum gps_dl_ctrld_opid { + GPS_DL_OPID_LINK_EVENT_PROC, + GPS_DL_OPID_HAL_EVENT_PROC, + GPS_DL_OPID_MAX +}; + +struct gps_dl_ctrld_context { + struct gps_dl_osal_event rgpsdlWq; /* rename */ + struct gps_dl_osal_lxop_q rOpQ; /* active op queue */ + struct gps_dl_osal_lxop_q rFreeOpQ; /* free op queue */ + struct gps_dl_osal_lxop arQue[GPS_DL_OP_BUF_SIZE]; /* real op instances */ + struct gps_dl_osal_thread thread; +}; + +typedef int(*GPS_DL_OPID_FUNC) (struct gps_dl_osal_op_dat *); + +unsigned int gps_dl_wait_event_checker(struct gps_dl_osal_thread *pThread); +int gps_dl_put_act_op(struct gps_dl_osal_lxop *pOp); +struct gps_dl_osal_lxop *gps_dl_get_free_op(void); +int gps_dl_put_op_to_free_queue(struct gps_dl_osal_lxop *pOp); +int gps_dl_ctrld_init(void); +int gps_dl_ctrld_deinit(void); + +#endif /* _GPS_DL_CTRLD_H */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/linux/inc/gps_dl_emi.h b/drivers/misc/mediatek/connectivity/gps/data_link/linux/inc/gps_dl_emi.h new file mode 100644 index 0000000000000000000000000000000000000000..0ff6f65c07c0c04a05267f55ae20d5a72b386464 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/linux/inc/gps_dl_emi.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#ifndef _GPS_GPS_DL_EMI_H +#define _GPS_GPS_DL_EMI_H + +#include "gps_dl_config.h" + +#if GPS_DL_HAS_PLAT_DRV +#define GPS_ICAP_BUF_SIZE 0x50000 /* 320KB */ + +void gps_icap_probe(void); +#endif + +#endif /* _GPS_GPS_DL_EMI_H */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/linux/inc/gps_dl_linux.h b/drivers/misc/mediatek/connectivity/gps/data_link/linux/inc/gps_dl_linux.h new file mode 100644 index 0000000000000000000000000000000000000000..8a1948bf04e15dea84f58b6c9dc32e73c513dd4b --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/linux/inc/gps_dl_linux.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#ifndef _GPS_DL_LINUX_H +#define _GPS_DL_LINUX_H + +#include "gps_dl_config.h" + +#include +#include + +#if (GPS_DL_USE_MTK_SYNC_WRITE) +#include +#define gps_dl_linux_sync_writel(v, a) mt_reg_sync_writel(v, a) +#else +/* Add mb after writel to make sure it takes effect before next operation */ +#define gps_dl_mb() mb() +#define gps_dl_linux_sync_writel(v, a) \ + do { \ + writel((v), (void __force __iomem *)((a))); \ + gps_dl_mb(); \ + } while (0) +#endif + +#include "gps_dl_isr.h" +#include "gps_each_link.h" + +/* put linux proprietary items here otherwise put into gps_dl_osal.h */ +irqreturn_t gps_dl_linux_irq_dispatcher(int irq, void *data); +int gps_dl_linux_irqs_register(struct gps_each_irq *p_irqs, int irq_num); +int gps_dl_linux_irqs_unregister(struct gps_each_irq *p_irqs, int irq_num); + +#endif /* _GPS_DL_LINUX_H */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/linux/inc/gps_dl_linux_plat_drv.h b/drivers/misc/mediatek/connectivity/gps/data_link/linux/inc/gps_dl_linux_plat_drv.h new file mode 100644 index 0000000000000000000000000000000000000000..2b32e9ae71ecec304ae1e5c5af9873ab0fc289dd --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/linux/inc/gps_dl_linux_plat_drv.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#ifndef _GPS_DL_LINUX_PLAT_DRV_H +#define _GPS_DL_LINUX_PLAT_DRV_H + +#include "gps_dl_config.h" + +#if GPS_DL_HAS_PLAT_DRV +#include +struct gps_dl_iomem_addr_map_entry { + void __iomem *host_virt_addr; + unsigned int host_phys_addr; + unsigned int length; +}; +#endif + +#if GPS_DL_HAS_PLAT_DRV +int gps_dl_linux_plat_drv_register(void); +int gps_dl_linux_plat_drv_unregister(void); +void __iomem *gps_dl_host_addr_to_virt(unsigned int host_addr); +void gps_dl_update_status_for_md_blanking(bool gps_is_on); +void gps_dl_tia_gps_ctrl(bool gps_is_on); +void gps_dl_lna_pin_ctrl(enum gps_dl_link_id_enum link_id, bool dsp_is_on, bool force_en); +void gps_dl_reserved_mem_show_info(void); +void gps_dl_wake_lock_init(void); +void gps_dl_wake_lock_deinit(void); +void gps_dl_wake_lock_hold(bool hold); +#endif + +#endif /* _GPS_DL_LINUX_PLAT_DRV_H */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/linux/inc/gps_dl_linux_reserved_mem.h b/drivers/misc/mediatek/connectivity/gps/data_link/linux/inc/gps_dl_linux_reserved_mem.h new file mode 100644 index 0000000000000000000000000000000000000000..b1e6ec80e857852c72c7a5a6296392fa1ae47902 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/linux/inc/gps_dl_linux_reserved_mem.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#ifndef _GPS_DL_LINUX_RESERVED_MEM_H +#define _GPS_DL_LINUX_RESERVED_MEM_H + +#include "gps_dl_config.h" + +#ifdef GPS_DL_HAS_PLAT_DRV +#include "gps_dl_dma_buf.h" + +extern phys_addr_t gGpsRsvMemPhyBase; +extern unsigned long long gGpsRsvMemSize; + +void gps_dl_reserved_mem_init(void); +void gps_dl_reserved_mem_deinit(void); +bool gps_dl_reserved_mem_is_ready(void); +void gps_dl_reserved_mem_get_range(unsigned int *p_min, unsigned int *p_max); +void gps_dl_reserved_mem_show_info(void); + +void gps_dl_reserved_mem_dma_buf_init(struct gps_dl_dma_buf *p_dma_buf, + enum gps_dl_link_id_enum link_id, enum gps_dl_dma_dir dir, unsigned int len); +void gps_dl_reserved_mem_dma_buf_deinit(struct gps_dl_dma_buf *p_dma_buf); +void *gps_dl_reserved_mem_icap_buf_get_vir_addr(void); +#endif + +#endif /* _GPS_DL_LINUX_RESERVED_MEM_H */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/linux/inc/gps_dl_osal.h b/drivers/misc/mediatek/connectivity/gps/data_link/linux/inc/gps_dl_osal.h new file mode 100644 index 0000000000000000000000000000000000000000..72beb97b7194b9a13ef581dd2b44f3e50410a8f3 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/linux/inc/gps_dl_osal.h @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#ifndef _GPS_DL_OSAL_H +#define _GPS_DL_OSAL_H +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DBG_LOG_STR_SIZE 256 + +#define RB_LATEST(prb) ((prb)->write - 1) +#define RB_SIZE(prb) ((prb)->size) +#define RB_MASK(prb) (RB_SIZE(prb) - 1) +#define RB_COUNT(prb) ((prb)->write - (prb)->read) +#define RB_FULL(prb) (RB_COUNT(prb) >= RB_SIZE(prb)) +#define RB_EMPTY(prb) ((prb)->write == (prb)->read) + +#define RB_INIT(prb, qsize) \ +do { \ + (prb)->read = (prb)->write = 0; \ + (prb)->size = (qsize); \ +} while (0) + +#define RB_PUT(prb, value) \ +do { \ + if (!RB_FULL(prb)) { \ + (prb)->queue[(prb)->write & RB_MASK(prb)] = value; \ + ++((prb)->write); \ + } \ + else { \ + gps_dl_osal_assert(!RB_FULL(prb)); \ + } \ +} while (0) + +#define RB_GET(prb, value) \ +do { \ + if (!RB_EMPTY(prb)) { \ + value = (prb)->queue[(prb)->read & RB_MASK(prb)]; \ + ++((prb)->read); \ + if (RB_EMPTY(prb)) { \ + (prb)->read = (prb)->write = 0; \ + } \ + } \ + else { \ + value = NULL; \ + gps_dl_osal_assert(!RB_EMPTY(prb)); \ + } \ +} while (0) + +#define RB_GET_LATEST(prb, value) \ +do { \ + if (!RB_EMPTY(prb)) { \ + value = (prb)->queue[RB_LATEST(prb) & RB_MASK(prb)]; \ + if (RB_EMPTY(prb)) { \ + (prb)->read = (prb)->write = 0; \ + } \ + } \ + else { \ + value = NULL; \ + } \ +} while (0) + +#define MAX_THREAD_NAME_LEN 128 +#define OSAL_OP_DATA_SIZE 32 +#define OSAL_OP_BUF_SIZE 16 + +typedef void(*P_TIMEOUT_HANDLER) (unsigned long); +typedef int(*P_COND) (void *); + +struct gps_dl_osal_timer { + struct timer_list timer; + P_TIMEOUT_HANDLER timeoutHandler; + unsigned long timeroutHandlerData; +}; + +struct gps_dl_osal_unsleepable_lock { + spinlock_t lock; + unsigned long flag; +}; + +struct gps_dl_osal_sleepable_lock { + struct mutex lock; +}; + +struct gps_dl_osal_signal { + struct completion comp; + unsigned int timeoutValue; + unsigned int timeoutExtension; /* max number of timeout caused by thread not able to acquire CPU */ +}; + +struct gps_dl_osal_event { + wait_queue_head_t waitQueue; + unsigned int timeoutValue; + int waitFlag; +}; + +struct gps_dl_osal_op_dat { + unsigned int opId; /* Event ID */ + unsigned int u4InfoBit; /* Reserved */ + unsigned long au4OpData[OSAL_OP_DATA_SIZE]; /* OP Data */ +}; + +struct gps_dl_osal_lxop { + struct gps_dl_osal_op_dat op; + struct gps_dl_osal_signal signal; + int result; + atomic_t ref_count; +}; + +struct gps_dl_osal_lxop_q { + struct gps_dl_osal_sleepable_lock sLock; + unsigned int write; + unsigned int read; + unsigned int size; + struct gps_dl_osal_lxop *queue[OSAL_OP_BUF_SIZE]; +}; + +struct gps_dl_osal_thread { + struct task_struct *pThread; + void *pThreadFunc; + void *pThreadData; + char threadName[MAX_THREAD_NAME_LEN]; +}; + +typedef unsigned int(*OSAL_EVENT_CHECKER) (struct gps_dl_osal_thread *pThread); + +char *gps_dl_osal_strncpy(char *dst, const char *src, unsigned int len); +char *gps_dl_osal_strsep(char **str, const char *c); +int gps_dl_osal_strtol(const char *str, unsigned int adecimal, long *res); +void *gps_dl_osal_memset(void *buf, int i, unsigned int len); +int gps_dl_osal_thread_create(struct gps_dl_osal_thread *pThread); +int gps_dl_osal_thread_run(struct gps_dl_osal_thread *pThread); +int gps_dl_osal_thread_stop(struct gps_dl_osal_thread *pThread); +int gps_dl_osal_thread_should_stop(struct gps_dl_osal_thread *pThread); +int gps_dl_osal_thread_destroy(struct gps_dl_osal_thread *pThread); +int gps_dl_osal_thread_wait_for_event(struct gps_dl_osal_thread *pThread, + struct gps_dl_osal_event *pEvent, OSAL_EVENT_CHECKER pChecker); +int gps_dl_osal_signal_init(struct gps_dl_osal_signal *pSignal); +int gps_dl_osal_wait_for_signal(struct gps_dl_osal_signal *pSignal); +int gps_dl_osal_wait_for_signal_timeout(struct gps_dl_osal_signal *pSignal, struct gps_dl_osal_thread *pThread); +int gps_dl_osal_raise_signal(struct gps_dl_osal_signal *pSignal); +int gps_dl_osal_signal_active_state(struct gps_dl_osal_signal *pSignal); +int gps_dl_osal_op_is_wait_for_signal(struct gps_dl_osal_lxop *pOp); +void gps_dl_osal_op_raise_signal(struct gps_dl_osal_lxop *pOp, int result); +int gps_dl_osal_signal_deinit(struct gps_dl_osal_signal *pSignal); +int gps_dl_osal_event_init(struct gps_dl_osal_event *pEvent); +int gps_dl_osal_trigger_event(struct gps_dl_osal_event *pEvent); +int gps_dl_osal_wait_for_event(struct gps_dl_osal_event *pEvent, int (*condition)(void *), void *cond_pa); +int gps_dl_osal_wait_for_event_timeout(struct gps_dl_osal_event *pEvent, int (*condition)(void *), void *cond_pa); +int gps_dl_osal_event_deinit(struct gps_dl_osal_event *pEvent); +int gps_dl_osal_sleepable_lock_init(struct gps_dl_osal_sleepable_lock *pSL); +int gps_dl_osal_lock_sleepable_lock(struct gps_dl_osal_sleepable_lock *pSL); +int gps_dl_osal_unlock_sleepable_lock(struct gps_dl_osal_sleepable_lock *pSL); +int gps_dl_osal_trylock_sleepable_lock(struct gps_dl_osal_sleepable_lock *pSL); +int gps_dl_osal_sleepable_lock_deinit(struct gps_dl_osal_sleepable_lock *pSL); +int gps_dl_osal_unsleepable_lock_init(struct gps_dl_osal_unsleepable_lock *pUSL); +int gps_dl_osal_lock_unsleepable_lock(struct gps_dl_osal_unsleepable_lock *pUSL); +int gps_dl_osal_unlock_unsleepable_lock(struct gps_dl_osal_unsleepable_lock *pUSL); + +#define gps_dl_osal_assert(condition) \ +do { \ + if (!(condition)) { \ + GDL_LOGE("ASSERT: (%s)", #condition); \ + } \ +} while (0) + +#endif /* _GPS_DL_OSAL_H */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/linux/inc/gps_dl_procfs.h b/drivers/misc/mediatek/connectivity/gps/data_link/linux/inc/gps_dl_procfs.h new file mode 100644 index 0000000000000000000000000000000000000000..ce604f4eec298d2b85fe955bd7fc532e4de3aba0 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/linux/inc/gps_dl_procfs.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#ifndef _GPS_DL_PROCFS_H +#define _GPS_DL_PROCFS_H + +int gps_dl_procfs_setup(void); +int gps_dl_procfs_remove(void); + +typedef int(*gps_dl_procfs_test_func_type)(int y, int z); + +#endif /* _GPS_DL_PROCFS_H */ + diff --git a/drivers/misc/mediatek/connectivity/gps/data_link/linux/inc/gps_each_device.h b/drivers/misc/mediatek/connectivity/gps/data_link/linux/inc/gps_each_device.h new file mode 100644 index 0000000000000000000000000000000000000000..d6c60d4e4f7923a63cfa4c69dca6b17117be50c7 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/data_link/linux/inc/gps_each_device.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#ifndef _GPS_EACH_DEVICE_H +#define _GPS_EACH_DEVICE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gps_each_link.h" +#include "gps_dl_dma_buf.h" + +#define GPS_DATA_PATH_BUF_MAX 2048 + +/* Todo: should not use this const, currently it's a work-around */ +#define GPS_LIBMNL_READ_MAX 512 + +struct gps_each_device_cfg { + char *dev_name; + int index; +}; + +struct gps_each_device { + struct gps_each_device_cfg cfg; + struct gps_each_link *p_link; + int index; + dev_t devno; + struct class *cls; + struct device *dev; + struct cdev cdev; + bool is_open; + unsigned char i_buf[GPS_DATA_PATH_BUF_MAX]; + unsigned char o_buf[GPS_DATA_PATH_BUF_MAX]; + unsigned int i_len; + wait_queue_head_t r_wq; + void *private_data; +}; + +int gps_dl_cdev_setup(struct gps_each_device *dev, int index); +void gps_dl_cdev_cleanup(struct gps_each_device *dev, int index); +struct gps_each_device *gps_dl_device_get(enum gps_dl_link_id_enum link_id); + +void gps_each_device_data_submit(unsigned char *buf, unsigned int len, int index); + +void gps_dl_device_context_init(void); +void gps_dl_device_context_deinit(void); + +#endif /* _GPS_EACH_DEVICE_H */ + diff --git a/drivers/misc/mediatek/connectivity/gps/fw_log_gps.c b/drivers/misc/mediatek/connectivity/gps/fw_log_gps.c new file mode 100644 index 0000000000000000000000000000000000000000..e5320fa9b7f13b22cadae009457b1b70232a01ef --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/fw_log_gps.c @@ -0,0 +1,259 @@ +/* + * Implementation of the GPS EMI driver. + * + * Copyright (C) 2014 Mediatek + * Authors: + * Heiping + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/******************************************************************************* +* Dependency +*******************************************************************************/ +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0) +#include +#else +#include +#endif +#include +#include "gps.h" +#include "connsys_debug_utility.h" +#ifdef pr_fmt +#undef pr_fmt +#endif +#define pr_fmt(fmt) "["KBUILD_MODNAME"]" fmt + +/****************************************************************************** + * Definition +******************************************************************************/ +/* device name and major number */ +#define GPSFWLOG_DEVNAME "fw_log_gps" +#define GPS_FW_LOG_IOC_MAGIC (0xfc) +#define GPS_FW_LOG_IOCTL_ON_OFF _IOW(GPS_FW_LOG_IOC_MAGIC, 0, int) +#define GPS_FW_LOG_IOCTL_SET_LEVEL _IOW(GPS_FW_LOG_IOC_MAGIC, 1, int) +#define GPS_FW_LOG_IOCTL_GET_LEVEL _IOW(GPS_FW_LOG_IOC_MAGIC, 2, int) + +/******************************************************************************* +* structure & enumeration +*******************************************************************************/ +/*---------------------------------------------------------------------------*/ +struct gps_fw_log_dev { + struct class *cls; + struct device *dev; + dev_t devno; + struct cdev chdev; +}; +/* typedef unsigned char UINT8, *PUINT8, **PPUINT8; */ + +/****************************************************************************** + * local variables +******************************************************************************/ +/* static int flag; */ +struct gps_fw_log_dev *logdevobj; +static wait_queue_head_t GPS_log_wq; +bool fgGps_fw_log_ON; + +/*---------------------------------------------------------------------------*/ +static void log_event_cb(void); + +long fw_log_gps_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + long retval = 0; + + switch (cmd) { + case GPS_FW_LOG_IOCTL_ON_OFF: + pr_info("gps PS_FW_LOG_IOCTL_ON_OFF(%lu)\n", arg); + GPS_fwlog_ctrl((bool)arg); + break; + + case GPS_FW_LOG_IOCTL_SET_LEVEL: + pr_info("gps GPS_FW_LOG_IOCTL_SET_LEVEL\n"); + break; + case GPS_FW_LOG_IOCTL_GET_LEVEL: + pr_info("gps GPS_FW_LOG_IOCTL_GET_LEVEL\n"); + break; + + default: + pr_warn("gps unknown cmd (%d)\n", cmd); + break; + } + return retval; +} + +long fw_log_gps_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + return fw_log_gps_unlocked_ioctl(filp, cmd, arg); +} + +/******************************************************************************/ +/*****************************************************************************/ +static int fw_log_open(struct inode *inode, struct file *file) +{ + pr_info("%s: gps major %d minor %d (pid %d)\n", __func__, imajor(inode), iminor(inode), current->pid); + return 0; +} + +/*****************************************************************************/ + + +/*****************************************************************************/ +static int fw_log_close(struct inode *inode, struct file *file) +{ + pr_info("%s: gps major %d minor %d (pid %d)\n", __func__, imajor(inode), iminor(inode), current->pid); + return 0; +} + +/******************************************************************************/ +static ssize_t fw_log_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) +{ + int retval; + + #if 0 + pr_info("GPS fw_log_read,len=%d\n", count); + #endif + + retval = connsys_log_read_to_user(CONNLOG_TYPE_GPS, buf, count); + return retval; +} +/******************************************************************************/ +static unsigned int fw_log_poll(struct file *file, poll_table *wait) +{ + unsigned int mask = 0; + + poll_wait(file, &GPS_log_wq, wait); + if (connsys_log_get_buf_size(CONNLOG_TYPE_GPS) > 0) + mask = (POLLIN | POLLRDNORM); + + return mask; +} + +/*****************************************************************************/ +/* Kernel interface */ +static const struct file_operations gps_fw_log_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = fw_log_gps_unlocked_ioctl, + .compat_ioctl = fw_log_gps_compat_ioctl, + .open = fw_log_open, + .read = fw_log_read, + .release = fw_log_close, + .poll = fw_log_poll, +}; + +void log_event_cb(void) +{ + wake_up_interruptible(&GPS_log_wq); +} + +static int __init gps_fw_log_init(void) +{ + int ret = 0; + int err = 0; + + logdevobj = kzalloc(sizeof(*logdevobj), GFP_KERNEL); + if (logdevobj == NULL) { + err = -ENOMEM; + ret = -ENOMEM; + goto err_out; + } + + pr_info("Registering chardev\n"); + ret = alloc_chrdev_region(&logdevobj->devno, 0, 1, GPSFWLOG_DEVNAME); + if (ret) { + pr_err("alloc_chrdev_region fail: %d\n", ret); + err = -ENOMEM; + goto err_out; + } else { + pr_info("major: %d, minor: %d\n", MAJOR(logdevobj->devno), MINOR(logdevobj->devno)); + } + cdev_init(&logdevobj->chdev, &gps_fw_log_fops); + logdevobj->chdev.owner = THIS_MODULE; + err = cdev_add(&logdevobj->chdev, logdevobj->devno, 1); + if (err) { + pr_err("cdev_add fail: %d\n", err); + goto err_out; + } + logdevobj->cls = class_create(THIS_MODULE, "gpsfwlog"); + if (IS_ERR(logdevobj->cls)) { + pr_err("Unable to create class, err = %d\n", (int)PTR_ERR(logdevobj->cls)); + goto err_out; + } + logdevobj->dev = device_create(logdevobj->cls, NULL, logdevobj->devno, logdevobj, "fw_log_gps"); + + connsys_log_init(CONNLOG_TYPE_GPS); + init_waitqueue_head(&GPS_log_wq); + connsys_log_register_event_cb(CONNLOG_TYPE_GPS, log_event_cb); + + pr_info("GPS FW LOG device init Done\n"); + return 0; + +err_out: + if (logdevobj != NULL) { + if (err == 0) + cdev_del(&logdevobj->chdev); + if (ret == 0) + unregister_chrdev_region(logdevobj->devno, 1); + kfree(logdevobj); + logdevobj = NULL; + } + return -1; +} + +/*****************************************************************************/ +static void __exit gps_fw_log_exit(void) +{ + if (!logdevobj) { + pr_err("null pointer: %p\n", logdevobj); + return; + } + + pr_info("Unregistering chardev\n"); + connsys_log_deinit(CONNLOG_TYPE_GPS); + cdev_del(&logdevobj->chdev); + unregister_chrdev_region(logdevobj->devno, 1); + device_destroy(logdevobj->cls, logdevobj->devno); + class_destroy(logdevobj->cls); + kfree(logdevobj); + logdevobj = NULL; + pr_info("Done\n"); +} + +int mtk_gps_fw_log_init(void) +{ + pr_info("gps fw log init begin"); + return gps_fw_log_init(); +} + +void mtk_gps_fw_log_exit(void) +{ + pr_info("gps fw log exit begin"); + return gps_fw_log_exit(); +} + +/*****************************************************************************/ +#if 0 +module_init(gps_emi_mod_init); +module_exit(gps_emi_mod_exit); +#endif +/*****************************************************************************/ +MODULE_AUTHOR("Chaoran Zhang "); +MODULE_DESCRIPTION("GPS FW log driver"); +MODULE_LICENSE("GPL"); +#endif diff --git a/drivers/misc/mediatek/connectivity/gps/gps.h b/drivers/misc/mediatek/connectivity/gps/gps.h new file mode 100644 index 0000000000000000000000000000000000000000..9d5b6048328899d40758463f47cbd088b9fb86f7 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/gps.h @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * brief Declaration of library functions + * Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. + */ + +#ifndef _GPS_H_ +#define _GPS_H_ + +#include "wmt_core.h" +#include "wmt_dev.h" +#include "osal.h" +#include "mtk_wcn_consys_hw.h" + +#if defined(CONFIG_MACH_MT6765) || defined(CONFIG_MACH_MT6761) || defined(CONFIG_MACH_MT6779) \ +|| defined(CONFIG_MACH_MT6768) || defined(CONFIG_MACH_MT6785) || defined(CONFIG_MACH_MT6873) \ +|| defined(CONFIG_MACH_MT6853) || defined(CONFIG_MACH_MT6833) +#define GPS_FWCTL_SUPPORT +#endif + +#ifdef GPS_FWCTL_SUPPORT +/* Disable: #define GPS_FWCTL_IOCTL_SUPPORT */ + +#define GPS_HW_SUSPEND_SUPPORT +#endif /* GPS_FWCTL_SUPPORT */ + +enum gps_ctrl_status_enum { + GPS_CLOSED, + GPS_OPENED, + GPS_SUSPENDED, + GPS_RESET_START, + GPS_RESET_DONE, + GPS_CTRL_STATUS_NUM +}; + +enum gps_reference_count_cmd { + FWLOG_CTRL_INNER = 0, + HANDLE_DESENSE, + GPS_FWCTL_READY, +}; + +#ifdef GPS_FWCTL_SUPPORT +#define GPS_FWCTL_OPCODE_ENTER_SLEEP_MODE (2) +#define GPS_FWCTL_OPCODE_EXIT_SLEEP_MODE (3) +#define GPS_FWCTL_OPCODE_ENTER_STOP_MODE (4) +#define GPS_FWCTL_OPCODE_EXIT_STOP_MODE (5) +#define GPS_FWCTL_OPCODE_LOG_CFG (6) +#define GPS_FWCTL_OPCODE_LOOPBACK_TEST (7) +#define GPS2_FWCTL_OPCODE_ENTER_STOP_MODE (8) +#define GPS2_FWCTL_OPCODE_EXIT_STOP_MODE (9) + +#endif + +enum gps_data_link_id_enum { + GPS_DATA_LINK_ID0 = 0, + GPS_DATA_LINK_ID1 = 1, + GPS_DATA_LINK_NUM = 2, +}; + +extern void GPS_reference_count(enum gps_reference_count_cmd cmd, bool flag, enum gps_data_link_id_enum user); + +extern phys_addr_t gConEmiPhyBase; + +extern int mtk_wcn_stpgps_drv_init(void); +extern void mtk_wcn_stpgps_drv_exit(void); +#ifdef CONFIG_MTK_GPS_EMI +extern int mtk_gps_emi_init(void); +extern void mtk_gps_emi_exit(void); +#endif +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH +extern int mtk_gps_fw_log_init(void); +extern void mtk_gps_fw_log_exit(void); +void GPS_fwlog_ctrl(bool on); +#endif + +#ifdef CONFIG_GPSL5_SUPPORT +/* stp_chrdev_gps2 */ +extern struct wakeup_source gps2_wake_lock; +extern struct semaphore wr_mtx2, rd_mtx2, status_mtx2; +extern const struct file_operations GPS2_fops; +#endif + +extern struct semaphore fwctl_mtx; + +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH +extern bool fgGps_fwlog_on; +#endif + +#ifdef GPS_FWCTL_SUPPORT +extern bool fgGps_fwctl_ready; +#endif + +#endif diff --git a/drivers/misc/mediatek/connectivity/gps/gps_dl_module.c b/drivers/misc/mediatek/connectivity/gps/gps_dl_module.c new file mode 100644 index 0000000000000000000000000000000000000000..df5152d9aca680cd79267a17099fc713b3fddad2 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/gps_dl_module.c @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2019 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ +#include +#include + +#include "gps_dl_config.h" + +#if GPS_DL_IS_MODULE +#include "gps_data_link_devices.h" + +/*****************************************************************************/ +static int gps_dl_mod_init(void) +{ + int ret = 0; + + mtk_gps_data_link_devices_init(); + + return ret; +} + +/*****************************************************************************/ +static void gps_dl_mod_exit(void) +{ + mtk_gps_data_link_devices_exit(); +} + +#ifdef MTK_WCN_REMOVE_KERNEL_MODULE +int mtk_wcn_gpsdl_drv_init(void) +{ + return gps_dl_mod_init(); +} +EXPORT_SYMBOL(mtk_wcn_gpsdl_drv_init); + +void mtk_wcn_gpsdl_drv_exit(void) +{ + return gps_dl_mod_exit(); +} +EXPORT_SYMBOL(mtk_wcn_gpsdl_drv_exit); + +#else +module_init(gps_dl_mod_init); +module_exit(gps_dl_mod_exit); + +#endif + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Hua Fu"); +#endif + diff --git a/drivers/misc/mediatek/connectivity/gps/gps_emi.c b/drivers/misc/mediatek/connectivity/gps/gps_emi.c new file mode 100644 index 0000000000000000000000000000000000000000..44923c30aa5925e1b24b20ed4558cf7dc09f08f5 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/gps_emi.c @@ -0,0 +1,507 @@ +/* + * Implementation of the GPS EMI driver. + * + * Copyright (C) 2014 Mediatek + * Authors: + * Heiping + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/******************************************************************************* +* Dependency +*******************************************************************************/ +#ifdef CONFIG_MTK_GPS_EMI +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "gps.h" + +#ifdef pr_fmt +#undef pr_fmt +#endif +#define pr_fmt(fmt) "["KBUILD_MODNAME"]" fmt + +/****************************************************************************** + * Definition +******************************************************************************/ +/* device name and major number */ +#define GPSEMI_DEVNAME "gps_emi" +#define IOCTL_EMI_MEMORY_INIT 1 +#define IOCTL_MNL_NVRAM_FILE_TO_MEM 2 +#define IOCTL_MNL_NVRAM_MEM_TO_FILE 3 +#define IOCTL_ADC_CAPTURE_ADDR_GET 4 + +#if defined(CONFIG_MACH_MT6765) || defined(CONFIG_MACH_MT6761) || defined(CONFIG_MACH_MT6768) +#define GPS_EMI_MPU_REGION 29 +#define GPS_EMI_BASE_ADDR_OFFSET (2*SZ_1M + SZ_1M/2 + 0x1000) +#define GPS_EMI_MPU_SIZE (SZ_1M + SZ_1M/2 - 0x2000) +#define EMI_MPU_PROTECTION_IS_READY 1 +#if EMI_MPU_PROTECTION_IS_READY +#include +#endif +#endif +#if defined(CONFIG_MACH_MT6779) && (LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0)) +#define GPS_EMI_MPU_REGION 29 +#define GPS_EMI_BASE_ADDR_OFFSET (3*SZ_1M + 0x10000) +#define GPS_EMI_MPU_SIZE (0xF0000) +#define EMI_MPU_PROTECTION_IS_READY 1 +#if EMI_MPU_PROTECTION_IS_READY +#include +#endif +#endif +#if defined(CONFIG_MACH_MT6771) || defined(CONFIG_MACH_MT6775) || defined(CONFIG_MACH_MT6758) +#define GPS_EMI_MPU_REGION 30 +#define GPS_EMI_BASE_ADDR_OFFSET (SZ_1M) +#define GPS_EMI_MPU_SIZE (SZ_1M) +#define EMI_MPU_PROTECTION_IS_READY 1 +#if EMI_MPU_PROTECTION_IS_READY +#include +#endif +#endif +#if defined(CONFIG_MACH_MT6873) || defined(CONFIG_MACH_MT6853) || defined(CONFIG_MACH_MT6893) +#define GPS_EMI_NEW_API +#define GPS_EMI_MPU_REGION 29 +#define GPS_EMI_BASE_ADDR_OFFSET (3*SZ_1M + 0x10000) +#define GPS_EMI_MPU_SIZE (0xF0000) +#define GPS_DL_EMI_MPU_DOMAIN_AP 0 +#define GPS_DL_EMI_MPU_DOMAIN_CONN 2 +#define EMI_MPU_PROTECTION_IS_READY 1 +#if EMI_MPU_PROTECTION_IS_READY +#include +#endif +#endif +#if defined(CONFIG_MACH_MT6833) +#define GPS_EMI_NEW_API +#define GPS_EMI_MPU_REGION 29 +#define GPS_EMI_BASE_ADDR_OFFSET (4*SZ_1M) +#define GPS_EMI_MPU_SIZE (0xFFFFF) +#define GPS_DL_EMI_MPU_DOMAIN_AP 0 +#define GPS_DL_EMI_MPU_DOMAIN_CONN 2 +#define EMI_MPU_PROTECTION_IS_READY 0 +#if EMI_MPU_PROTECTION_IS_READY +#include +#endif +#endif +#if defined(CONFIG_MACH_MT6779) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) +#define GPS_EMI_NEW_API +#define GPS_EMI_MPU_REGION 29 +#define GPS_EMI_BASE_ADDR_OFFSET (3*SZ_1M + 0x10000) +#define GPS_EMI_MPU_SIZE (0xF0000) +#define GPS_DL_EMI_MPU_DOMAIN_AP 0 +#define GPS_DL_EMI_MPU_DOMAIN_CONN 2 +#define EMI_MPU_PROTECTION_IS_READY 1 +#if EMI_MPU_PROTECTION_IS_READY +#include +#endif +#endif + +#define GPS_ADC_CAPTURE_BUFF_SIZE 0x50000 +/****************************************************************************** + * Debug configuration +******************************************************************************/ +#define GPS_DBG_NONE(fmt, arg...) do {} while (0) +#define GPS_DBG pr_err +#define GPS_TRC GPS_DBG_NONE +#define GPS_VER pr_err +#define GPS_ERR pr_err +/******************************************************************************* +* structure & enumeration +*******************************************************************************/ +/*---------------------------------------------------------------------------*/ +struct gps_emi_dev { + struct class *cls; + struct device *dev; + dev_t devno; + struct cdev chdev; +}; +/* typedef unsigned char UINT8, *PUINT8, **PPUINT8; */ + +/****************************************************************************** + * local variables +******************************************************************************/ +phys_addr_t gGpsEmiPhyBase; +void __iomem *pGpsEmibaseaddr; +struct gps_emi_dev *devobj; + +static struct semaphore fw_dl_mtx; + +void mtk_wcn_consys_gps_memory_reserve(void) +{ +#if 0 +#ifdef MTK_WCN_ARM64 + gGpsEmiPhyBase = arm64_memblock_steal(SZ_1M, SZ_1M); +#else + gGpsEmiPhyBase = arm_memblock_steal(SZ_1M, SZ_1M); +#endif +#else + #if EMI_MPU_PROTECTION_IS_READY + gGpsEmiPhyBase = gConEmiPhyBase + GPS_EMI_BASE_ADDR_OFFSET; + #endif +#endif + if (gGpsEmiPhyBase) + GPS_DBG("Con:0x%zx, Gps:0x%zx\n", (size_t)gConEmiPhyBase, (size_t)gGpsEmiPhyBase); + else + GPS_DBG("memblock fail\n"); +} + +INT32 gps_emi_mpu_set_region_protection(INT32 region) +{ +#if EMI_MPU_PROTECTION_IS_READY +#if defined(GPS_EMI_NEW_API) + struct emimpu_region_t region_info; + int emimpu_ret1, emimpu_ret2, emimpu_ret3, emimpu_ret4, emimpu_ret5, emimpu_ret6; + /* Set EMI MPU permission */ + GPS_DBG("emi mpu cfg: region = %d, no protection domain = %d, %d", + region, GPS_DL_EMI_MPU_DOMAIN_AP, GPS_DL_EMI_MPU_DOMAIN_CONN); + emimpu_ret1 = mtk_emimpu_init_region(®ion_info, region); + emimpu_ret2 = mtk_emimpu_set_addr(®ion_info, gGpsEmiPhyBase, gGpsEmiPhyBase + GPS_EMI_MPU_SIZE - 1); + emimpu_ret3 = mtk_emimpu_set_apc(®ion_info, GPS_DL_EMI_MPU_DOMAIN_AP, MTK_EMIMPU_NO_PROTECTION); + emimpu_ret4 = mtk_emimpu_set_apc(®ion_info, GPS_DL_EMI_MPU_DOMAIN_CONN, MTK_EMIMPU_NO_PROTECTION); + emimpu_ret5 = mtk_emimpu_set_protection(®ion_info); + emimpu_ret6 = mtk_emimpu_free_region(®ion_info); + GPS_DBG("emi mpu cfg: ret = %d, %d, %d, %d, %d, %d", + emimpu_ret1, emimpu_ret2, emimpu_ret3, emimpu_ret4, emimpu_ret5, emimpu_ret6); +#else + struct emi_region_info_t region_info; + /*set MPU for EMI share Memory */ + GPS_DBG("setting MPU for EMI share memory\n"); + region_info.start = gGpsEmiPhyBase; + region_info.end = gGpsEmiPhyBase + GPS_EMI_MPU_SIZE - 1; + region_info.region = region; + SET_ACCESS_PERMISSION(region_info.apc, LOCK, + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, + NO_PROTECTION, FORBIDDEN, NO_PROTECTION); + emi_mpu_set_protection(®ion_info); +#endif +#endif + return 0; +} + +INT32 gps_emi_patch_get(PUINT8 pPatchName, osal_firmware **ppPatch) +{ + INT32 iRet; + osal_firmware *fw; + + iRet = -1; + fw = NULL; + if (!ppPatch) { + GPS_DBG("invalid ppBufptr!\n"); + return -1; + } + *ppPatch = NULL; + iRet = request_firmware((const struct firmware **)&fw, pPatchName, NULL); + if (iRet != 0) { + GPS_DBG("failed to open or read!(%s)\n", pPatchName); + release_firmware(fw); + return -1; + } + GPS_DBG("loader firmware %s ok!!\n", pPatchName); + iRet = 0; + *ppPatch = fw; + + return iRet; +} + +INT32 mtk_wcn_consys_gps_emi_init(void) +{ + INT32 iRet; + + iRet = -1; + down(&fw_dl_mtx); + mtk_wcn_consys_gps_memory_reserve(); + if (gGpsEmiPhyBase) { + /*set MPU for EMI share Memory*/ + #if EMI_MPU_PROTECTION_IS_READY + GPS_DBG("setting MPU for EMI share memory\n"); + gps_emi_mpu_set_region_protection(GPS_EMI_MPU_REGION); + #endif + GPS_DBG("get consys start phy address(0x%zx)\n", (size_t)gGpsEmiPhyBase); + #if 0 + /*consys to ap emi remapping register:10001310, cal remapping address*/ + addrPhy = (gGpsEmiPhyBase & 0xFFF00000) >> 20; + + /*enable consys to ap emi remapping bit12*/ + addrPhy -= 0x400;/*Gavin ??*/ + addrPhy = addrPhy | 0x1000; + + CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET, + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET) | addrPhy); + + GPS_DBG("GPS_EMI_MAPPING dump(0x%08x)\n", + CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET)); + #endif + #if EMI_MPU_PROTECTION_IS_READY + pGpsEmibaseaddr = ioremap_nocache(gGpsEmiPhyBase, GPS_EMI_MPU_SIZE); + #endif + iRet = 1; + #if 0 + if (pGpsEmibaseaddr != NULL) { + unsigned char *pFullPatchName = "MNL.bin"; + osal_firmware *pPatch = NULL; + + GPS_DBG("EMI mapping OK(0x%p)\n", pGpsEmibaseaddr); + memset_io(pGpsEmibaseaddr, 0, GPS_EMI_MPU_SIZE); + if ((pFullPatchName != NULL) + && (gps_emi_patch_get(pFullPatchName, &pPatch) == 0)) { + if (pPatch != NULL) { + /*get full name patch success*/ + GPS_DBG("get full patch name(%s) buf(0x%p) size(%ld)\n", + pFullPatchName, (pPatch)->data, (pPatch)->size); + GPS_DBG("AF get patch, pPatch(0x%p)\n", pPatch); + } + } + if (pPatch != NULL) { + if ((pPatch)->size <= GPS_EMI_MPU_SIZE) { + GPS_DBG("Prepare to copy FW\n"); + memcpy(pGpsEmibaseaddr, (pPatch)->data, (pPatch)->size); + iRet = 1; + GPS_DBG("pGpsEmibaseaddr_1:0x%08x 0x%08x 0x%08x 0x%08x\n", + *(unsigned int *)pGpsEmibaseaddr, + *(((unsigned int *)pGpsEmibaseaddr)+1), + *(((unsigned int *)pGpsEmibaseaddr)+2), + *(((unsigned int *)pGpsEmibaseaddr)+3)); + GPS_DBG("pGpsEmibaseaddr_2:0x%08x 0x%08x 0x%08x 0x%08x\n", + *(((unsigned int *)pGpsEmibaseaddr)+4), + *(((unsigned int *)pGpsEmibaseaddr)+5), + *(((unsigned int *)pGpsEmibaseaddr)+6), + *(((unsigned int *)pGpsEmibaseaddr)+7)); + } + release_firmware(pPatch); + pPatch = NULL; + } + iounmap(pGpsEmibaseaddr); + } else { + GPS_DBG("EMI mapping fail\n"); + } + #endif + } else { + GPS_DBG("gps emi memory address gGpsEmiPhyBase invalid\n"); + } + up(&fw_dl_mtx); + return iRet; +} + +/*---------------------------------------------------------------------------*/ +long gps_emi_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + int retval; + unsigned int *tmp; + + retval = 0; + GPS_DBG("gps_emi:cmd (%d),arg(%ld)\n", cmd, arg); + + switch (cmd) { + case IOCTL_EMI_MEMORY_INIT: + retval = mtk_wcn_consys_gps_emi_init(); + GPS_DBG("IOCTL_EMI_MEMORY_INIT\n"); + break; + + case IOCTL_MNL_NVRAM_FILE_TO_MEM: + GPS_DBG("IOCTL_MNL_NVRAM_FILE_TO_MEM\n"); + break; + + case IOCTL_MNL_NVRAM_MEM_TO_FILE: + GPS_DBG("IOCTL_MNL_NVRAM_MEM_TO_FILE\n"); + break; + + case IOCTL_ADC_CAPTURE_ADDR_GET: + tmp = (unsigned int *)&gGpsEmiPhyBase; + GPS_DBG("gps_emi:gGpsEmiPhyBase (%x)\n", &gGpsEmiPhyBase); + GPS_DBG("gps_emi:tmp (%x)\n", tmp); + if (copy_to_user((unsigned int __user *)arg, tmp, sizeof(unsigned int))) + retval = -1; + GPS_DBG("IOCTL_ADC_CAPTURE_ADDR_GET,(%d)\n", retval); + break; + + default: + GPS_DBG("unknown cmd (%d)\n", cmd); + retval = 0; + break; + } + return retval; + +} + +/******************************************************************************/ +long gps_emi_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + return gps_emi_unlocked_ioctl(filp, cmd, arg); +} + +/*****************************************************************************/ +static int gps_emi_open(struct inode *inode, struct file *file) +{ + GPS_TRC(); + return nonseekable_open(inode, file); +} + +/*****************************************************************************/ + + +/*****************************************************************************/ +static int gps_emi_release(struct inode *inode, struct file *file) +{ + GPS_TRC(); + + return 0; +} + +/******************************************************************************/ +static ssize_t gps_emi_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) +{ + ssize_t ret; + + ret = 0; + GPS_DBG("gps_emi_read begin\n"); + if (count > GPS_ADC_CAPTURE_BUFF_SIZE) + count = GPS_ADC_CAPTURE_BUFF_SIZE; + if (pGpsEmibaseaddr != NULL) { + if (copy_to_user(buf, (char *)pGpsEmibaseaddr, count)) + pr_err("Copy to user failed\n"); + } + GPS_DBG("gps_emi_read finish\n"); + return ret; +} +/******************************************************************************/ +static ssize_t gps_emi_write(struct file *file, const char __user *buf, size_t count, + loff_t *ppos) +{ + ssize_t ret = 0; + + GPS_TRC(); + + return ret; +} + + +/*****************************************************************************/ +/* Kernel interface */ +static const struct file_operations gps_emi_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = gps_emi_unlocked_ioctl, + .compat_ioctl = gps_emi_compat_ioctl, + .open = gps_emi_open, + .read = gps_emi_read, + .write = gps_emi_write, + .release = gps_emi_release, +}; + +/*****************************************************************************/ +#ifdef CONFIG_OF +static const struct of_device_id apgps_of_ids[] = { + { .compatible = "mediatek,gps_emi-v1", }, + {} +}; +#endif +/*****************************************************************************/ +static int __init gps_emi_mod_init(void) +{ + int ret = 0; + int err = 0; + + GPS_ERR("gps emi mod register begin"); + + sema_init(&fw_dl_mtx, 1); + + devobj = kzalloc(sizeof(*devobj), GFP_KERNEL); + if (devobj == NULL) { + err = -ENOMEM; + ret = -ENOMEM; + goto err_out; + } + + GPS_ERR("Registering chardev\n"); + ret = alloc_chrdev_region(&devobj->devno, 0, 1, GPSEMI_DEVNAME); + if (ret) { + GPS_ERR("alloc_chrdev_region fail: %d\n", ret); + err = -ENOMEM; + goto err_out; + } else { + GPS_ERR("major: %d, minor: %d\n", MAJOR(devobj->devno), MINOR(devobj->devno)); + } + cdev_init(&devobj->chdev, &gps_emi_fops); + devobj->chdev.owner = THIS_MODULE; + err = cdev_add(&devobj->chdev, devobj->devno, 1); + if (err) { + GPS_ERR("cdev_add fail: %d\n", err); + goto err_out; + } + devobj->cls = class_create(THIS_MODULE, "gpsemi"); + if (IS_ERR(devobj->cls)) { + GPS_ERR("Unable to create class, err = %d\n", (int)PTR_ERR(devobj->cls)); + goto err_out; + } + devobj->dev = device_create(devobj->cls, NULL, devobj->devno, devobj, "gps_emi"); + + + GPS_ERR("GPS EMI Done\n"); + return 0; + +err_out: + if (devobj != NULL) { + if (err == 0) + cdev_del(&devobj->chdev); + if (ret == 0) + unregister_chrdev_region(devobj->devno, 1); + + kfree(devobj); + devobj = NULL; + } + return -1; +} + +/*****************************************************************************/ +static void __exit gps_emi_mod_exit(void) +{ + if (!devobj) { + GPS_ERR("null pointer: %p\n", devobj); + return; + } + + GPS_ERR("Unregistering chardev\n"); + cdev_del(&devobj->chdev); + unregister_chrdev_region(devobj->devno, 1); + device_destroy(devobj->cls, devobj->devno); + class_destroy(devobj->cls); + kfree(devobj); + GPS_ERR("Done\n"); +} + +int mtk_gps_emi_init(void) +{ + GPS_ERR("gps emi mod init begin"); + return gps_emi_mod_init(); +} + +void mtk_gps_emi_exit(void) +{ + GPS_ERR("gps emi mod exit begin"); + return gps_emi_mod_exit(); +} + +/*****************************************************************************/ +#if 0 +module_init(gps_emi_mod_init); +module_exit(gps_emi_mod_exit); +#endif +/*****************************************************************************/ +MODULE_AUTHOR("Heiping Lei "); +MODULE_DESCRIPTION("GPS EMI Driver"); +MODULE_LICENSE("GPL"); +#endif diff --git a/drivers/misc/mediatek/connectivity/gps/gps_mt3337.c b/drivers/misc/mediatek/connectivity/gps/gps_mt3337.c new file mode 100644 index 0000000000000000000000000000000000000000..ef9e8de2e3805ceb5fe96adeffa92f589de9a63c --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/gps_mt3337.c @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEVICE_NAME "mt3337_gpsonly" + +#ifdef pr_fmt +#undef pr_fmt +#endif +#define pr_fmt(fmt) "["KBUILD_MODNAME"]" fmt + +#define GPS_POWER_IOCTL _IOW('G', 0, int) + +static long gps_ioctrl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + struct miscdevice *dev; + struct regulator *reg; + int ret; + + switch (cmd) { + case GPS_POWER_IOCTL: + dev = (struct miscdevice *)filp->private_data; + reg = dev_get_drvdata(dev->this_device); + if (arg) + ret = regulator_enable(reg); + else + ret = regulator_disable(reg); + return ret; + default: + return -EINVAL; + } + return 0; +} + +static const struct file_operations gps_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = gps_ioctrl, + .compat_ioctl = gps_ioctrl, +}; + +static struct miscdevice mt3337_gps_driver = { + .minor = MISC_DYNAMIC_MINOR, + .name = DEVICE_NAME, + .fops = &gps_fops, +}; + +static int mt3337_gps_probe(struct platform_device *pdev) +{ + int ret; + struct regulator *regulator; + + regulator = devm_regulator_get(&pdev->dev, "power"); + if (IS_ERR(regulator)) + return PTR_ERR(regulator); + + ret = misc_register(&mt3337_gps_driver); + if (ret < 0) + return ret; + + dev_set_drvdata(mt3337_gps_driver.this_device, regulator); + + return 0; +} + +static const struct of_device_id mt3337_gps_of_match[] = { + { .compatible = "mediatek,mt3337" }, + {}, +}; + +static struct platform_driver mt3337_gps_pdriver = { + .probe = mt3337_gps_probe, + .driver = { + .name = DEVICE_NAME, + .of_match_table = of_match_ptr(mt3337_gps_of_match), + }, +}; + +module_platform_driver(mt3337_gps_pdriver); + +MODULE_AUTHOR("Hao Dong "); +MODULE_DESCRIPTION("MT3337 GPS Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/misc/mediatek/connectivity/gps/init.gps_drv.rc b/drivers/misc/mediatek/connectivity/gps/init.gps_drv.rc new file mode 100644 index 0000000000000000000000000000000000000000..258aa6811002b2b8500e4e8acc172ebd711cb2d1 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/init.gps_drv.rc @@ -0,0 +1,4 @@ + +# load gps_drv +on property:vendor.connsys.driver.ready=yes + insmod /vendor/lib/modules/gps_drv.ko diff --git a/drivers/misc/mediatek/connectivity/gps/lna_ctrl/inc/gps_lna_drv.h b/drivers/misc/mediatek/connectivity/gps/lna_ctrl/inc/gps_lna_drv.h new file mode 100644 index 0000000000000000000000000000000000000000..2c3c5a035755d88fac43d821020b9669127dff66 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/lna_ctrl/inc/gps_lna_drv.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ +#ifndef _GPS_LNA_DRV_H +#define _GPS_LNA_DRV_H + +#include "gps.h" + +int gps_lna_linux_plat_drv_register(void); +int gps_lna_linux_plat_drv_unregister(void); +void gps_lna_pin_ctrl(enum gps_data_link_id_enum link_id, bool dsp_is_on, bool force_en); +void gps_lna_update_status_for_md_blanking(bool gps_is_on); + +#endif /* _GPS_DL_LINUX_PLAT_DRV_H */ + diff --git a/drivers/misc/mediatek/connectivity/gps/lna_ctrl/src/gps_lna_drv.c b/drivers/misc/mediatek/connectivity/gps/lna_ctrl/src/gps_lna_drv.c new file mode 100644 index 0000000000000000000000000000000000000000..2d8ce5426298d9eab865f0e676a01c2052ae617a --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/lna_ctrl/src/gps_lna_drv.c @@ -0,0 +1,295 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "gps_lna_drv.h" +#include "gps.h" + +#define PFX "[LNA_CTL] " +#define GPS_LOG_INFO 2 +static unsigned int gDbgLevel = GPS_LOG_INFO; + +#define GPS_INFO_FUNC(fmt, arg...) \ +do { if (gDbgLevel >= GPS_LOG_INFO) \ + pr_info(PFX "[I]%s: " fmt, __func__, ##arg); \ +} while (0) + + +/* #ifdef CONFIG_OF */ +const struct of_device_id gps_lna_of_ids[] = { + { .compatible = "mediatek,gps", }, + {} +}; +/* #endif */ + +enum gps_lna_pinctrl_state_enum { + GPS_DL_L1_LNA_DISABLE, + GPS_DL_L1_LNA_DSP_CTRL, + GPS_DL_L1_LNA_ENABLE, + GPS_DL_L5_LNA_DISABLE, + GPS_DL_L5_LNA_DSP_CTRL, + GPS_DL_L5_LNA_ENABLE, + GPS_DL_PINCTRL_STATE_CNT +}; + +const char *const gps_lna_pinctrl_state_name_list[GPS_DL_PINCTRL_STATE_CNT] = { + "gps_l1_lna_disable", + "gps_l1_lna_dsp_ctrl", + "gps_l1_lna_enable", + "gps_l5_lna_disable", + "gps_l5_lna_dsp_ctrl", + "gps_l5_lna_enable", +}; + +struct pinctrl_state *g_gps_lna_pinctrl_state_struct_list[GPS_DL_PINCTRL_STATE_CNT]; +struct pinctrl *g_gps_lna_pinctrl_ptr; + +void gps_lna_pinctrl_show_info(void) +{ + enum gps_lna_pinctrl_state_enum state_id; + const char *p_name; + struct pinctrl_state *p_state; + + GPS_INFO_FUNC("pinctrl_ptr = 0x%p", g_gps_lna_pinctrl_ptr); + + for (state_id = 0; state_id < GPS_DL_PINCTRL_STATE_CNT; state_id++) { + p_name = gps_lna_pinctrl_state_name_list[state_id]; + p_state = g_gps_lna_pinctrl_state_struct_list[state_id]; + GPS_INFO_FUNC("state id = %d, ptr = 0x%p, name = %s", state_id, p_state, p_name); + } +} + +void gps_lna_pinctrl_context_init(void) +{ + enum gps_lna_pinctrl_state_enum state_id; + const char *p_name; + struct pinctrl_state *p_state; + + if (IS_ERR(g_gps_lna_pinctrl_ptr)) { + GPS_INFO_FUNC("pinctrl is error"); + return; + } + + for (state_id = 0; state_id < GPS_DL_PINCTRL_STATE_CNT; state_id++) { + p_name = gps_lna_pinctrl_state_name_list[state_id]; + p_state = pinctrl_lookup_state(g_gps_lna_pinctrl_ptr, p_name); + + if (IS_ERR(p_state)) { + GPS_INFO_FUNC("lookup fail: state id = %d, name = %s", state_id, p_name); + g_gps_lna_pinctrl_state_struct_list[state_id] = NULL; + continue; + } + + g_gps_lna_pinctrl_state_struct_list[state_id] = p_state; + GPS_INFO_FUNC("lookup okay: state id = %d, name = %s", state_id, p_name); + } +} + +void gps_lna_pin_ctrl(enum gps_data_link_id_enum link_id, bool dsp_is_on, bool force_en) +{ + struct pinctrl_state *p_state = NULL; + int ret; + + /*ASSERT_LINK_ID(link_id, GDL_VOIDF());*/ + + if (GPS_DATA_LINK_ID0 == link_id) { + if (dsp_is_on && force_en) + p_state = g_gps_lna_pinctrl_state_struct_list[GPS_DL_L1_LNA_ENABLE]; + else if (dsp_is_on) + p_state = g_gps_lna_pinctrl_state_struct_list[GPS_DL_L1_LNA_DSP_CTRL]; + else + p_state = g_gps_lna_pinctrl_state_struct_list[GPS_DL_L1_LNA_DISABLE]; + } + + if (GPS_DATA_LINK_ID1 == link_id) { + if (dsp_is_on && force_en) + p_state = g_gps_lna_pinctrl_state_struct_list[GPS_DL_L5_LNA_ENABLE]; + else if (dsp_is_on) + p_state = g_gps_lna_pinctrl_state_struct_list[GPS_DL_L5_LNA_DSP_CTRL]; + else + p_state = g_gps_lna_pinctrl_state_struct_list[GPS_DL_L5_LNA_DISABLE]; + } + + if (p_state == NULL) { + GPS_INFO_FUNC("link_id = %d, on = %d, force = %d, state is null", link_id, dsp_is_on, force_en); + return; + } + + if (g_gps_lna_pinctrl_ptr == NULL) { + GPS_INFO_FUNC("link_id = %d, on = %d, force = %d, g_gps_lna_pinctrl_ptr is null", + link_id, dsp_is_on, force_en); + return; + } + ret = pinctrl_select_state(g_gps_lna_pinctrl_ptr, p_state); + if (ret != 0) + GPS_INFO_FUNC("link_id = %d, on = %d, force = %d, select ret = %d", link_id, dsp_is_on, force_en, ret); + else + GPS_INFO_FUNC("link_id = %d, on = %d, force = %d, select ret = %d", link_id, dsp_is_on, force_en, ret); +} + +static int gps_lna_probe(struct platform_device *pdev) +{ + struct resource *irq; + int i; + bool okay; + + g_gps_lna_pinctrl_ptr = devm_pinctrl_get(&pdev->dev); + if (IS_ERR(g_gps_lna_pinctrl_ptr)) + GPS_INFO_FUNC("devm_pinctrl_get fail"); + if (!IS_ERR(g_gps_lna_pinctrl_ptr)) { + gps_lna_pinctrl_context_init(); + gps_lna_pinctrl_show_info(); + } + GPS_INFO_FUNC("do gps_lna_probe"); + + return 0; +} + +static int gps_lna_remove(struct platform_device *pdev) +{ + GPS_INFO_FUNC("do gps_lna_remove"); + platform_set_drvdata(pdev, NULL); + return 0; +} + +static int gps_lna_drv_suspend(struct device *dev) +{ +#if 0 + struct platform_device *pdev = to_platform_device(dev); + pm_message_t state = PMSG_SUSPEND; + + return mtk_btif_suspend(pdev, state); +#endif + return 0; +} + +static int gps_lna_drv_resume(struct device *dev) +{ +#if 0 + struct platform_device *pdev = to_platform_device(dev); + + return mtk_btif_resume(pdev); +#endif + return 0; +} + +static int gps_lna_plat_suspend(struct platform_device *pdev, pm_message_t state) +{ +#if 0 + int i_ret = 0; + struct _mtk_btif_ *p_btif = NULL; + + BTIF_DBG_FUNC("++\n"); + p_btif = platform_get_drvdata(pdev); + i_ret = _btif_suspend(p_btif); + BTIF_DBG_FUNC("--, i_ret:%d\n", i_ret); + return i_ret; +#endif + return 0; +} + +static int gps_lna_plat_resume(struct platform_device *pdev) +{ +#if 0 + int i_ret = 0; + struct _mtk_btif_ *p_btif = NULL; + + BTIF_DBG_FUNC("++\n"); + p_btif = platform_get_drvdata(pdev); + i_ret = _btif_resume(p_btif); + BTIF_DBG_FUNC("--, i_ret:%d\n", i_ret); + return i_ret; +#endif + return 0; +} + + +const struct dev_pm_ops gps_lna_drv_pm_ops = { + .suspend = gps_lna_drv_suspend, + .resume = gps_lna_drv_resume, +}; + +struct platform_driver gps_lna_dev_drv = { + .probe = gps_lna_probe, + .remove = gps_lna_remove, +/* #ifdef CONFIG_PM */ + .suspend = gps_lna_plat_suspend, + .resume = gps_lna_plat_resume, +/* #endif */ + .driver = { + .name = "gps", /* mediatek,gps */ + .owner = THIS_MODULE, +/* #ifdef CONFIG_PM */ + .pm = &gps_lna_drv_pm_ops, +/* #endif */ +/* #ifdef CONFIG_OF */ + .of_match_table = gps_lna_of_ids, +/* #endif */ + } +}; + +static ssize_t driver_flag_read(struct device_driver *drv, char *buf) +{ + return sprintf(buf, "gps lna driver debug level:%d\n", 1); +} + +static ssize_t driver_flag_set(struct device_driver *drv, + const char *buffer, size_t count) +{ + GPS_INFO_FUNC("buffer = %s, count = %zd", buffer, count); + return count; +} + +#define DRIVER_ATTR(_name, _mode, _show, _store) \ + struct driver_attribute driver_attr_##_name = \ + __ATTR(_name, _mode, _show, _store) +static DRIVER_ATTR(flag, 0644, driver_flag_read, driver_flag_set); + + +int gps_lna_linux_plat_drv_register(void) +{ + int result; + + result = platform_driver_register(&gps_lna_dev_drv); + /* if (result) */ + GPS_INFO_FUNC("platform_driver_register, ret(%d)\n", result); + + result = driver_create_file(&gps_lna_dev_drv.driver, &driver_attr_flag); + /* if (result) */ + GPS_INFO_FUNC("driver_create_file, ret(%d)\n", result); + + return 0; +} + +int gps_lna_linux_plat_drv_unregister(void) +{ + driver_remove_file(&gps_lna_dev_drv.driver, &driver_attr_flag); + platform_driver_unregister(&gps_lna_dev_drv); + + return 0; +} + diff --git a/drivers/misc/mediatek/connectivity/gps/stp_chrdev_gps.c b/drivers/misc/mediatek/connectivity/gps/stp_chrdev_gps.c new file mode 100644 index 0000000000000000000000000000000000000000..633f29b952ba9302b5575b9adffd87b124a2260a --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/stp_chrdev_gps.c @@ -0,0 +1,1378 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "osal_typedef.h" +#include "stp_exp.h" +#include "wmt_exp.h" +#include +#if defined(CONFIG_MACH_MT6580) +#include +#endif +#include "gps.h" +#if defined(CONFIG_MACH_MT6739) +#include +#include +#endif +#if defined(CONFIG_MACH_MT6765) || defined(CONFIG_MACH_MT6761) + +#include + +#endif +#include + +#ifdef CONFIG_GPS_CTRL_LNA_SUPPORT +#include "gps_lna_drv.h" +#endif +MODULE_LICENSE("GPL"); + +#define GPS_DRIVER_NAME "mtk_stp_GPS_chrdev" +#define GPS2_DRIVER_NAME "mtk_stp_GPS2_chrdev" + +#define GPS_DEV_MAJOR 191 /* never used number */ +#define GPS_DEBUG_TRACE_GPIO 0 +#define GPS_DEBUG_DUMP 0 + +#define PFX "[GPS] " +#define GPS_LOG_DBG 3 +#define GPS_LOG_INFO 2 +#define GPS_LOG_WARN 1 +#define GPS_LOG_ERR 0 + +#define COMBO_IOC_GPS_HWVER 6 +#define COMBO_IOC_GPS_IC_HW_VERSION 7 +#define COMBO_IOC_GPS_IC_FW_VERSION 8 +#define COMBO_IOC_D1_EFUSE_GET 9 +#define COMBO_IOC_RTC_FLAG 10 +#define COMBO_IOC_CO_CLOCK_FLAG 11 +#define COMBO_IOC_TRIGGER_WMT_ASSERT 12 +#define COMBO_IOC_WMT_STATUS 13 +#define COMBO_IOC_TAKE_GPS_WAKELOCK 14 +#define COMBO_IOC_GIVE_GPS_WAKELOCK 15 +#define COMBO_IOC_GET_GPS_LNA_PIN 16 +#define COMBO_IOC_GPS_FWCTL 17 +#define COMBO_IOC_GPS_HW_SUSPEND 18 +#define COMBO_IOC_GPS_HW_RESUME 19 +#define COMBO_IOC_GPS_LISTEN_RST_EVT 20 + +static UINT32 gDbgLevel = GPS_LOG_DBG; + +#define GPS_DBG_FUNC(fmt, arg...) \ +do { if (gDbgLevel >= GPS_LOG_DBG) \ + pr_debug(PFX "[D]%s: " fmt, __func__, ##arg); \ +} while (0) +#define GPS_INFO_FUNC(fmt, arg...) \ +do { if (gDbgLevel >= GPS_LOG_INFO) \ + pr_info(PFX "[I]%s: " fmt, __func__, ##arg); \ +} while (0) +#define GPS_WARN_FUNC(fmt, arg...) \ +do { if (gDbgLevel >= GPS_LOG_WARN) \ + pr_warn(PFX "[W]%s: " fmt, __func__, ##arg); \ +} while (0) +#define GPS_ERR_FUNC(fmt, arg...) \ +do { if (gDbgLevel >= GPS_LOG_ERR) \ + pr_err(PFX "[E]%s: " fmt, __func__, ##arg); \ +} while (0) +#define GPS_TRC_FUNC(f) \ +do { if (gDbgLevel >= GPS_LOG_DBG) \ + pr_info(PFX "<%s> <%d>\n", __func__, __LINE__); \ +} while (0) + +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH +bool fgGps_fwlog_on; +#endif + +#ifdef GPS_FWCTL_SUPPORT +bool fgGps_fwctl_ready; +#endif + +static int GPS_devs = 1; /* device count */ +static int GPS_major = GPS_DEV_MAJOR; /* dynamic allocation */ +module_param(GPS_major, uint, 0); +static struct cdev GPS_cdev; +#ifdef CONFIG_GPSL5_SUPPORT +static int GPS2_devs = 2; /* device count */ +static struct cdev GPS2_cdev; +#endif + +static struct wakeup_source *gps_wake_lock_ptr; +const char gps_wake_lock_name[] = "gpswakelock"; +static unsigned char wake_lock_acquired; /* default: 0 */ + +#if (defined(CONFIG_MTK_GMO_RAM_OPTIMIZE) && !defined(CONFIG_MTK_ENG_BUILD)) +#define STP_GPS_BUFFER_SIZE 2048 +#else +#define STP_GPS_BUFFER_SIZE MTKSTP_BUFFER_SIZE +#endif +static unsigned char i_buf[STP_GPS_BUFFER_SIZE]; /* input buffer of read() */ +static unsigned char o_buf[STP_GPS_BUFFER_SIZE]; /* output buffer of write() */ +static struct semaphore wr_mtx, rd_mtx, status_mtx; +struct semaphore fwctl_mtx; + +static DECLARE_WAIT_QUEUE_HEAD(GPS_wq); +static DECLARE_WAIT_QUEUE_HEAD(GPS_rst_wq); +static int flag; +static int rstflag; +static int rst_listening_flag; +static int rst_happened_or_gps_close_flag; + +static enum gps_ctrl_status_enum g_gps_ctrl_status; + +static void GPS_check_and_wakeup_rst_listener(enum gps_ctrl_status_enum to) +{ + if (to == GPS_RESET_START || to == GPS_RESET_DONE || to == GPS_CLOSED) { + rst_happened_or_gps_close_flag = 1; + if (rst_listening_flag) { + wake_up(&GPS_rst_wq); + GPS_WARN_FUNC("Set GPS rst_happened_or_gps_close_flag because to = %d", to); + } + } +} + +#ifdef GPS_HW_SUSPEND_SUPPORT +static void GPS_ctrl_status_change_from_to(enum gps_ctrl_status_enum from, enum gps_ctrl_status_enum to) +{ + bool okay = true; + enum gps_ctrl_status_enum status_backup; + + down(&status_mtx); + /* Due to checking status and setting status are not atomic, + * mutex is needed to make sure they are an atomic operation. + * Note: reading the status is no need to protect + */ + status_backup = g_gps_ctrl_status; + if (status_backup == from) + g_gps_ctrl_status = to; + else + okay = false; + up(&status_mtx); + + if (!okay) + GPS_WARN_FUNC("GPS unexpected status %d, not chagne from %d to %d", status_backup, from, to); + else + GPS_check_and_wakeup_rst_listener(to); +} +#endif + +static enum gps_ctrl_status_enum GPS_ctrl_status_change_to(enum gps_ctrl_status_enum to) +{ + enum gps_ctrl_status_enum status_backup; + + down(&status_mtx); + status_backup = g_gps_ctrl_status; + g_gps_ctrl_status = to; + up(&status_mtx); + + GPS_check_and_wakeup_rst_listener(to); + + return status_backup; +} + +static void GPS_event_cb(void); + +static void gps_hold_wake_lock(int hold) +{ + if (hold == 1) { + if (!wake_lock_acquired) { + GPS_DBG_FUNC("acquire gps wake_lock acquired = %d\n", wake_lock_acquired); + __pm_stay_awake(gps_wake_lock_ptr); + wake_lock_acquired = 1; + } else { + GPS_DBG_FUNC("acquire gps wake_lock acquired = %d (do nothing)\n", wake_lock_acquired); + } + } else if (hold == 0) { + if (wake_lock_acquired) { + GPS_DBG_FUNC("release gps wake_lock acquired = %d\n", wake_lock_acquired); + __pm_relax(gps_wake_lock_ptr); + wake_lock_acquired = 0; + } else { + GPS_DBG_FUNC("release gps wake_lock acquired = %d (do nothing)\n", wake_lock_acquired); + } + } +} + +bool rtc_GPS_low_power_detected(void) +{ + static bool first_query = true; + + if (first_query) { + first_query = false; + /*return rtc_low_power_detected();*/ + return 0; + } else { + return false; + } +} + +ssize_t GPS_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) +{ + int retval = 0; + int written = 0; + + down(&wr_mtx); + + /* GPS_TRC_FUNC(); */ + + /*pr_warn("%s: count %d pos %lld\n", __func__, count, *f_pos); */ + if (count > 0) { + int copy_size = (count < STP_GPS_BUFFER_SIZE) ? count : STP_GPS_BUFFER_SIZE; + + if (copy_from_user(&o_buf[0], &buf[0], copy_size)) { + retval = -EFAULT; + goto out; + } + /* pr_warn("%02x ", val); */ +#if GPS_DEBUG_TRACE_GPIO + mtk_wcn_stp_debug_gpio_assert(IDX_GPS_TX, DBG_TIE_LOW); +#endif + written = mtk_wcn_stp_send_data(&o_buf[0], copy_size, GPS_TASK_INDX); +#if GPS_DEBUG_TRACE_GPIO + mtk_wcn_stp_debug_gpio_assert(IDX_GPS_TX, DBG_TIE_HIGH); +#endif + +#if GPS_DEBUG_DUMP + { + unsigned char *buf_ptr = &o_buf[0]; + int k = 0; + + pr_warn("--[GPS-WRITE]--"); + for (k = 0; k < 10; k++) { + if (k % 16 == 0) + pr_warn("\n"); + pr_warn("0x%02x ", o_buf[k]); + } + pr_warn("\n"); + } +#endif + if (written == 0) { + retval = -ENOSPC; + /* no windowspace in STP is available, */ + /* native process should not call GPS_write with no delay at all */ + GPS_ERR_FUNC + ("target packet length:%zd, write success length:%d, retval = %d.\n", + count, written, retval); + } else { + retval = written; + } + } else { + retval = -EFAULT; + GPS_ERR_FUNC("target packet length:%zd is not allowed, retval = %d.\n", count, retval); + } +out: + up(&wr_mtx); + return retval; +} + +ssize_t GPS_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) +{ + long val = 0; + int retval; + + down(&rd_mtx); + + /* pr_debug("GPS_read(): count %d pos %lld\n", count, *f_pos); */ + if (rstflag == 1) { + if (filp->f_flags & O_NONBLOCK) { + /* GPS_DBG_FUNC("Non-blocking read, whole chip reset occurs! rstflag=%d\n", rstflag); */ + retval = -EIO; + goto OUT; + } + } + + if (count > STP_GPS_BUFFER_SIZE) + count = STP_GPS_BUFFER_SIZE; + +#if GPS_DEBUG_TRACE_GPIO + mtk_wcn_stp_debug_gpio_assert(IDX_GPS_RX, DBG_TIE_LOW); +#endif + retval = mtk_wcn_stp_receive_data(i_buf, count, GPS_TASK_INDX); +#if GPS_DEBUG_TRACE_GPIO + mtk_wcn_stp_debug_gpio_assert(IDX_GPS_RX, DBG_TIE_HIGH); +#endif + + while (retval == 0) { + /* got nothing, wait for STP's signal */ + /* wait_event(GPS_wq, flag != 0); *//* George: let signal wake up */ + if (filp->f_flags & O_NONBLOCK) { + /* GPS_DBG_FUNC("Non-blocking read, no data is available!\n"); */ + retval = -EAGAIN; + goto OUT; + } + + val = wait_event_interruptible(GPS_wq, flag != 0); + flag = 0; + +#if GPS_DEBUG_TRACE_GPIO + mtk_wcn_stp_debug_gpio_assert(IDX_GPS_RX, DBG_TIE_LOW); +#endif + + retval = mtk_wcn_stp_receive_data(i_buf, count, GPS_TASK_INDX); + +#if GPS_DEBUG_TRACE_GPIO + mtk_wcn_stp_debug_gpio_assert(IDX_GPS_RX, DBG_TIE_HIGH); +#endif + /* if we are signaled */ + if (val) { + if (-ERESTARTSYS == val) + GPS_DBG_FUNC("signaled by -ERESTARTSYS(%ld)\n ", val); + else + GPS_DBG_FUNC("signaled by %ld\n ", val); + + break; + } + } + +#if GPS_DEBUG_DUMP + { + unsigned char *buf_ptr = &i_buf[0]; + int k = 0; + + pr_warn("--[GPS-READ]--"); + for (k = 0; k < 10; k++) { + if (k % 16 == 0) + pr_warn("\n"); + pr_warn("0x%02x ", i_buf[k]); + } + pr_warn("--\n"); + } +#endif + + if (retval > 0) { + /* we got something from STP driver */ + if (copy_to_user(buf, i_buf, retval)) { + retval = -EFAULT; + goto OUT; + } else { + /* success */ + } + } else { + /* we got nothing from STP driver, being signaled */ + retval = val; + } + +OUT: + up(&rd_mtx); +/* pr_warn("GPS_read(): retval = %d\n", retval);*/ + return retval; +} + +#ifdef GPS_FWCTL_SUPPORT +#ifdef GPS_FWCTL_IOCTL_SUPPORT +struct gps_fwctl_data { + UINT32 size; + UINT32 tx_len; + UINT32 rx_max; + UINT32 pad; /* 128byte */ + UINT64 p_tx_buf; /* cast pointer to UINT64 to be compatible both 32/64bit */ + UINT64 p_rx_buf; /* 256byte */ + UINT64 p_rx_len; + UINT64 p_reserved; /* 384byte */ +}; + +#define GPS_FWCTL_BUF_MAX (128) +long GPS_fwctl(struct gps_fwctl_data *user_ptr) +{ + UINT8 tx_buf[GPS_FWCTL_BUF_MAX]; + UINT8 rx_buf[GPS_FWCTL_BUF_MAX]; + UINT8 tx0 = 0; + UINT8 rx0 = 0; + UINT8 rx1 = 0; + UINT32 rx_len = 0; + UINT32 rx_to_user_len; + struct gps_fwctl_data ctl_data; + INT32 status = 0; + UINT64 delta_time = 0; + bool fwctl_ready; + int retval = 0; + + if (copy_from_user(&ctl_data, user_ptr, sizeof(struct gps_fwctl_data))) { + pr_err("GPS_fwctl: copy_from_user error - ctl_data"); + return -EFAULT; + } + + if (ctl_data.size < sizeof(struct gps_fwctl_data)) { + /* user space data size not enough, risk to use it */ + pr_err("GPS_fwctl: struct size(%u) is too short than(%u)", + ctl_data.size, (UINT32)sizeof(struct gps_fwctl_data)); + return -EFAULT; + } + + if ((ctl_data.tx_len > GPS_FWCTL_BUF_MAX) || (ctl_data.tx_len == 0)) { + /* check tx data len */ + pr_err("GPS_fwctl: tx_len=%u too long (> %u) or too short", + ctl_data.tx_len, GPS_FWCTL_BUF_MAX); + return -EFAULT; + } + + if (copy_from_user(&tx_buf[0], (PUINT8)ctl_data.p_tx_buf, ctl_data.tx_len)) { + pr_err("GPS_fwctl: copy_from_user error - tx_buf"); + return -EFAULT; + } + + down(&fwctl_mtx); + if (fgGps_fwctl_ready) { + delta_time = local_clock(); + status = mtk_wmt_gps_mcu_ctrl( + &tx_buf[0], ctl_data.tx_len, &rx_buf[0], GPS_FWCTL_BUF_MAX, &rx_len); + delta_time = local_clock() - delta_time; + do_div(delta_time, 1e3); /* convert to us */ + fwctl_ready = true; + } else { + fwctl_ready = false; + } + up(&fwctl_mtx); + + tx0 = tx_buf[0]; + if (fwctl_ready && (status == 0) && (rx_len <= GPS_FWCTL_BUF_MAX) && (rx_len >= 2)) { + rx0 = rx_buf[0]; + rx1 = rx_buf[1]; + pr_info("GPS_fwctl: st=%d, tx_len=%u ([0]=%u), rx_len=%u ([0]=%u, [1]=%u), us=%u", + status, ctl_data.tx_len, tx0, rx_len, rx0, rx1, (UINT32)delta_time); + + if (ctl_data.rx_max < rx_len) + rx_to_user_len = ctl_data.rx_max; + else + rx_to_user_len = rx_len; + + if (copy_to_user((PUINT8)ctl_data.p_rx_buf, &rx_buf[0], rx_to_user_len)) { + pr_err("GPS_fwctl: copy_to_user error - rx_buf"); + retval = -EFAULT; + } + + if (copy_to_user((PUINT32)ctl_data.p_rx_len, &rx_len, sizeof(UINT32))) { + pr_err("GPS_fwctl: copy_to_user error - rx_len"); + retval = -EFAULT; + } + return retval; + } + + pr_info("GPS_fwctl: st=%d, tx_len=%u ([0]=%u), rx_len=%u, us=%u, ready=%u", + status, ctl_data.tx_len, tx0, rx_len, (UINT32)delta_time, (UINT32)fwctl_ready); + return -EFAULT; +} +#endif /* GPS_FWCTL_IOCTL_SUPPORT */ + +#define GPS_FWLOG_CTRL_BUF_MAX (20) + +#define GPS_NSEC_IN_MSEC (1000000) +UINT64 GPS_get_local_clock_ms(void) +{ + UINT64 tmp; + + /* tmp is ns */ + tmp = local_clock(); + + /* tmp is changed to ms after */ + do_div(tmp, GPS_NSEC_IN_MSEC); + + return tmp; +} + +void GPS_fwlog_ctrl_inner(bool on) +{ + UINT8 tx_buf[GPS_FWLOG_CTRL_BUF_MAX]; + UINT8 rx_buf[GPS_FWLOG_CTRL_BUF_MAX]; + UINT8 rx0 = 0; + UINT8 rx1 = 0; + UINT32 tx_len; + UINT32 rx_len = 0; + INT32 status; + UINT32 fw_tick = 0; + UINT32 local_ms0, local_ms1; + struct timeval tv; + + do_gettimeofday(&tv); + + /* 32bit ms overflow almost 4.9 days, it's enough here */ + local_ms0 = (UINT32)GPS_get_local_clock_ms(); + + tx_buf[0] = GPS_FWCTL_OPCODE_LOG_CFG; + tx_buf[1] = (UINT8)on; + tx_buf[2] = 0; + tx_buf[3] = 0; + tx_buf[4] = 0; /* bitmask, reserved now */ + tx_buf[5] = (UINT8)((local_ms0 >> 0) & 0xFF); + tx_buf[6] = (UINT8)((local_ms0 >> 8) & 0xFF); + tx_buf[7] = (UINT8)((local_ms0 >> 16) & 0xFF); + tx_buf[8] = (UINT8)((local_ms0 >> 24) & 0xFF); /* local time msecs */ + tx_buf[9] = (UINT8)((tv.tv_usec >> 0) & 0xFF); + tx_buf[10] = (UINT8)((tv.tv_usec >> 8) & 0xFF); + tx_buf[11] = (UINT8)((tv.tv_usec >> 16) & 0xFF); + tx_buf[12] = (UINT8)((tv.tv_usec >> 24) & 0xFF); /* utc usec */ + tx_buf[13] = (UINT8)((tv.tv_sec >> 0) & 0xFF); + tx_buf[14] = (UINT8)((tv.tv_sec >> 8) & 0xFF); + tx_buf[15] = (UINT8)((tv.tv_sec >> 16) & 0xFF); + tx_buf[16] = (UINT8)((tv.tv_sec >> 24) & 0xFF); /* utc sec */ + tx_len = 17; + + status = mtk_wmt_gps_mcu_ctrl(&tx_buf[0], tx_len, &rx_buf[0], GPS_FWLOG_CTRL_BUF_MAX, &rx_len); + + /* local_ms1 = jiffies_to_msecs(jiffies); */ + local_ms1 = (UINT32)GPS_get_local_clock_ms(); + + if (status == 0) { + if (rx_len >= 2) { + rx0 = rx_buf[0]; + rx1 = rx_buf[1]; + } + + if (rx_len >= 6) { + fw_tick |= (((UINT32)rx_buf[2]) << 0); + fw_tick |= (((UINT32)rx_buf[3]) << 8); + fw_tick |= (((UINT32)rx_buf[4]) << 16); + fw_tick |= (((UINT32)rx_buf[5]) << 24); + } + } + + pr_info("GPS_fwlog: st=%d, rx_len=%u ([0]=%u, [1]=%u), ms0=%u, ms1=%u, fw_tick=%u", + status, rx_len, rx0, rx1, local_ms0, local_ms1, fw_tick); +} + +#ifdef GPS_HW_SUSPEND_SUPPORT +#define HW_SUSPEND_CTRL_TX_LEN (3) +#define HW_SUSPEND_CTRL_RX_LEN (3) + +/* return 0 if okay, otherwise is fail */ +static int GPS_hw_suspend_ctrl(bool to_suspend, UINT8 mode) +{ + UINT8 tx_buf[HW_SUSPEND_CTRL_TX_LEN] = {0}; + UINT8 rx_buf[HW_SUSPEND_CTRL_RX_LEN] = {0}; + UINT8 rx0 = 0; + UINT8 rx1 = 0; + UINT32 tx_len; + UINT32 rx_len = 0; + INT32 wmt_status; + UINT32 local_ms0, local_ms1; + struct timeval tv; + + do_gettimeofday(&tv); + + /* 32bit ms overflow almost 4.9 days, it's enough here */ + local_ms0 = (UINT32)GPS_get_local_clock_ms(); + + tx_buf[0] = to_suspend ? GPS_FWCTL_OPCODE_ENTER_STOP_MODE : + GPS_FWCTL_OPCODE_EXIT_STOP_MODE; + tx_buf[1] = mode; /*mode value should be set in mnld, 0: HW suspend mode, 1: clock extension mode*/ + tx_len = 2; + + wmt_status = mtk_wmt_gps_mcu_ctrl(&tx_buf[0], tx_len, + &rx_buf[0], HW_SUSPEND_CTRL_RX_LEN, &rx_len); + + /* local_ms1 = jiffies_to_msecs(jiffies); */ + local_ms1 = (UINT32)GPS_get_local_clock_ms(); + + if (wmt_status == 0) { /* 0 is okay */ + if (rx_len >= 2) { + rx0 = rx_buf[0]; /* fw_status, 0 is okay */ + rx1 = rx_buf[1]; /* opcode */ + } + } + + if (wmt_status != 0 || rx0 != 0) { + /* Fail due to WMT fail or FW not support, + * bypass the following operations + */ + GPS_WARN_FUNC("GPS_hw_suspend_ctrl %d: st=%d, rx_len=%u ([0]=%u, [1]=%u), ms0=%u, ms1=%u, mode=%u", + to_suspend, wmt_status, rx_len, rx0, rx1, local_ms0, local_ms1, mode); + return -1; + } + + /* Okay */ + GPS_INFO_FUNC("GPS_hw_suspend_ctrl %d: st=%d, rx_len=%u ([0]=%u, [1]=%u), ms0=%u, ms1=%u, mode=%u", + to_suspend, wmt_status, rx_len, rx0, rx1, local_ms0, local_ms1, mode); + return 0; +} + +static int GPS_hw_suspend(UINT8 mode) +{ + MTK_WCN_BOOL wmt_okay; + enum gps_ctrl_status_enum gps_status; + + gps_status = g_gps_ctrl_status; + if (gps_status == GPS_OPENED) { + if (GPS_hw_suspend_ctrl(true, mode) != 0) + return -EINVAL; /* Stands for not support */ + +#ifdef CONFIG_GPSL5_SUPPORT + wmt_okay = mtk_wmt_gps_l1_suspend_ctrl(MTK_WCN_BOOL_TRUE); +#else + wmt_okay = mtk_wmt_gps_suspend_ctrl(MTK_WCN_BOOL_TRUE); +#endif + if (!wmt_okay) + GPS_WARN_FUNC("mtk_wmt_gps_l1_suspend_ctrl(1), is_ok = %d", wmt_okay); + + /* register event cb will clear GPS STP buffer */ + mtk_wcn_stp_register_event_cb(GPS_TASK_INDX, 0x0); + GPS_DBG_FUNC("mtk_wcn_stp_register_event_cb to null"); + + /* No need to clear the flag due to it just a flag and not stands for has data + * flag = 0; + * + * Keep msgcb due to GPS still need to recevice reset event under HW suspend mode + * mtk_wcn_wmt_msgcb_unreg(WMTDRV_TYPE_GPS); + */ + + GPS_reference_count(HANDLE_DESENSE, false, GPS_DATA_LINK_ID0); + gps_hold_wake_lock(0); + GPS_WARN_FUNC("gps_hold_wake_lock(0)\n"); + + GPS_ctrl_status_change_from_to(GPS_OPENED, GPS_SUSPENDED); + } else + GPS_WARN_FUNC("GPS_hw_suspend(): status %d not match\n", gps_status); + + return 0; +} + +static int GPS_hw_resume(UINT8 mode) +{ + MTK_WCN_BOOL wmt_okay; + enum gps_ctrl_status_enum gps_status; + + gps_status = g_gps_ctrl_status; + if (gps_status == GPS_SUSPENDED) { + GPS_reference_count(HANDLE_DESENSE, true, GPS_DATA_LINK_ID0); + gps_hold_wake_lock(1); + GPS_WARN_FUNC("gps_hold_wake_lock(1)\n"); + +#ifdef CONFIG_GPSL5_SUPPORT + wmt_okay = mtk_wmt_gps_l1_suspend_ctrl(MTK_WCN_BOOL_FALSE); +#else + wmt_okay = mtk_wmt_gps_suspend_ctrl(MTK_WCN_BOOL_FALSE); +#endif + if (!wmt_okay) + GPS_WARN_FUNC("mtk_wmt_gps_l1_suspend_ctrl(0), is_ok = %d", wmt_okay); + + /* should register it before real resuming to prepare for receiving data */ + mtk_wcn_stp_register_event_cb(GPS_TASK_INDX, GPS_event_cb); + if (GPS_hw_suspend_ctrl(false, mode) != 0) /*Ignore mode value for resume stage*/ + return -EINVAL; /* Stands for not support */ + + GPS_ctrl_status_change_from_to(GPS_SUSPENDED, GPS_OPENED); + } else + GPS_WARN_FUNC("GPS_hw_resume(): status %d not match\n", gps_status); + + return 0; +} +#endif /* GPS_HW_SUSPEND_SUPPORT */ + +#endif /* GPS_FWCTL_SUPPORT */ + +void GPS_fwlog_ctrl(bool on) +{ +#if (defined(GPS_FWCTL_SUPPORT) && defined(CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH)) + down(&fwctl_mtx); + if (fgGps_fwctl_ready) + GPS_fwlog_ctrl_inner(on); + fgGps_fwlog_on = on; + up(&fwctl_mtx); +#endif +} + +/* block until wmt reset happen or GPS_close */ +static int GPS_listen_wmt_rst(void) +{ + long val = 0; + + rst_listening_flag = 1; + while (!rst_happened_or_gps_close_flag) { + val = wait_event_interruptible(GPS_rst_wq, rst_happened_or_gps_close_flag); + + GPS_WARN_FUNC("GPS_listen_wmt_rst(): val = %ld, cond = %d, rstflag = %d, status = %d\n", + val, rst_happened_or_gps_close_flag, rstflag, g_gps_ctrl_status); + + /* if we are signaled */ + if (val) { + rst_listening_flag = 0; + return val; + } + } + + rst_listening_flag = 0; + return 0; +} + +/* int GPS_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) */ +long GPS_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + int retval = 0; + #if 0 + ENUM_WMTHWVER_TYPE_T hw_ver_sym = WMTHWVER_INVALID; + #endif + UINT32 hw_version = 0; + UINT32 fw_version = 0; + UINT32 gps_lna_pin = 0; + + pr_warn("GPS_ioctl(): cmd (%d)\n", cmd); + + switch (cmd) { + case 0: /* enable/disable STP */ + GPS_DBG_FUNC("GPS_ioctl(): disable STP control from GPS dev\n"); + retval = -EINVAL; +#if 1 +#else + /* George: STP is controlled by WMT only */ + mtk_wcn_stp_enable(arg); +#endif + break; + + case 1: /* send raw data */ + GPS_DBG_FUNC("GPS_ioctl(): disable raw data from GPS dev\n"); + retval = -EINVAL; + break; + + #if 0 + case COMBO_IOC_GPS_HWVER: + /*get combo hw version */ + hw_ver_sym = mtk_wcn_wmt_hwver_get(); + + GPS_DBG_FUNC("GPS_ioctl(): get hw version = %d, sizeof(hw_ver_sym) = %zd\n", + hw_ver_sym, sizeof(hw_ver_sym)); + if (copy_to_user((int __user *)arg, &hw_ver_sym, sizeof(hw_ver_sym))) + retval = -EFAULT; + + break; + #endif + case COMBO_IOC_GPS_IC_HW_VERSION: + /*get combo hw version from ic, without wmt mapping */ + hw_version = mtk_wcn_wmt_ic_info_get(WMTCHIN_HWVER); + + GPS_DBG_FUNC("GPS_ioctl(): get hw version = 0x%x\n", hw_version); + if (copy_to_user((int __user *)arg, &hw_version, sizeof(hw_version))) + retval = -EFAULT; + + break; + + case COMBO_IOC_GPS_IC_FW_VERSION: + /*get combo fw version from ic, without wmt mapping */ + fw_version = mtk_wcn_wmt_ic_info_get(WMTCHIN_FWVER); + + GPS_DBG_FUNC("GPS_ioctl(): get fw version = 0x%x\n", fw_version); + if (copy_to_user((int __user *)arg, &fw_version, sizeof(fw_version))) + retval = -EFAULT; + + break; + case COMBO_IOC_RTC_FLAG: + + retval = rtc_GPS_low_power_detected(); + + GPS_DBG_FUNC("low power flag (%d)\n", retval); + break; + case COMBO_IOC_CO_CLOCK_FLAG: +#if SOC_CO_CLOCK_FLAG + retval = mtk_wcn_wmt_co_clock_flag_get(); +#endif + GPS_DBG_FUNC("GPS co_clock_flag (%d)\n", retval); + break; + case COMBO_IOC_D1_EFUSE_GET: +#if defined(CONFIG_MACH_MT6735) + do { + char *addr = ioremap(0x10206198, 0x4); + + retval = *(volatile unsigned int *)addr; + GPS_DBG_FUNC("D1 efuse (0x%x)\n", retval); + iounmap(addr); + } while (0); +#elif defined(CONFIG_MACH_MT6763) + do { + char *addr = ioremap(0x11f10048, 0x4); + + retval = *(volatile unsigned int *)addr; + GPS_DBG_FUNC("bianco efuse (0x%x)\n", retval); + iounmap(addr); + } while (0); +#else + GPS_ERR_FUNC("Read Efuse not supported in this platform\n"); +#endif + break; + + case COMBO_IOC_TRIGGER_WMT_ASSERT: + /* Trigger FW assert for debug */ + GPS_INFO_FUNC("%s: Host trigger FW assert......, reason:%lu\n", __func__, arg); + retval = mtk_wcn_wmt_assert(WMTDRV_TYPE_GPS, arg); + if (retval == MTK_WCN_BOOL_TRUE) { + GPS_INFO_FUNC("Host trigger FW assert succeed\n"); + retval = 0; + } else { + GPS_ERR_FUNC("Host trigger FW assert Failed\n"); + retval = (-EBUSY); + } + break; + case COMBO_IOC_WMT_STATUS: + if (rstflag == 1) { + /* chip resetting */ + retval = -888; + } else if (rstflag == 2) { + /* chip reset end */ + retval = -889; + /* + * rstflag = 0 is cleared by GPS_open or GPS_close, + * no need to clear it here + */ + } else { + /* normal */ + retval = 0; + } + GPS_DBG_FUNC("rstflag(%d), retval(%d)\n", rstflag, retval); + break; + case COMBO_IOC_TAKE_GPS_WAKELOCK: + GPS_INFO_FUNC("Ioctl to take gps wakelock\n"); + gps_hold_wake_lock(1); + if (wake_lock_acquired == 1) + retval = 0; + else + retval = -EAGAIN; + break; + case COMBO_IOC_GIVE_GPS_WAKELOCK: + GPS_INFO_FUNC("Ioctl to give gps wakelock\n"); + gps_hold_wake_lock(0); + if (wake_lock_acquired == 0) + retval = 0; + else + retval = -EAGAIN; + break; +#ifdef GPS_FWCTL_IOCTL_SUPPORT + case COMBO_IOC_GPS_FWCTL: + GPS_INFO_FUNC("COMBO_IOC_GPS_FWCTL\n"); + retval = GPS_fwctl((struct gps_fwctl_data *)arg); + break; +#endif + +#ifdef GPS_HW_SUSPEND_SUPPORT + case COMBO_IOC_GPS_HW_SUSPEND: + GPS_INFO_FUNC("COMBO_IOC_GPS_HW_SUSPEND: mode %lu\n", arg); + retval = GPS_hw_suspend((UINT8)(arg&0xFF)); + break; + case COMBO_IOC_GPS_HW_RESUME: + GPS_INFO_FUNC("COMBO_IOC_GPS_HW_RESUME: mode %lu\n", arg); + retval = GPS_hw_resume((UINT8)(arg&0xFF)); + break; +#endif /* GPS_HW_SUSPEND_SUPPORT */ + + case COMBO_IOC_GPS_LISTEN_RST_EVT: + GPS_INFO_FUNC("COMBO_IOC_GPS_LISTEN_RST_EVT\n"); + retval = GPS_listen_wmt_rst(); + break; + + case COMBO_IOC_GET_GPS_LNA_PIN: + gps_lna_pin = mtk_wmt_get_gps_lna_pin_num(); + GPS_DBG_FUNC("GPS_ioctl(): get gps lna pin = %d\n", gps_lna_pin); + if (copy_to_user((int __user *)arg, &gps_lna_pin, sizeof(gps_lna_pin))) + retval = -EFAULT; + break; + default: + retval = -EFAULT; + GPS_DBG_FUNC("GPS_ioctl(): unknown cmd (%d)\n", cmd); + break; + } + +/*OUT:*/ + return retval; +} + +long GPS_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + long ret; + + pr_warn("%s: cmd (%d)\n", __func__, cmd); + ret = GPS_unlocked_ioctl(filp, cmd, arg); + pr_warn("%s: cmd (%d)\n", __func__, cmd); + return ret; +} + +static void gps_cdev_rst_cb(ENUM_WMTDRV_TYPE_T src, + ENUM_WMTDRV_TYPE_T dst, ENUM_WMTMSG_TYPE_T type, void *buf, unsigned int sz) +{ + + /* To handle reset procedure please */ + ENUM_WMTRSTMSG_TYPE_T rst_msg; + + GPS_DBG_FUNC("sizeof(ENUM_WMTRSTMSG_TYPE_T) = %zd\n", sizeof(ENUM_WMTRSTMSG_TYPE_T)); + if (sz <= sizeof(ENUM_WMTRSTMSG_TYPE_T)) { + memcpy((char *)&rst_msg, (char *)buf, sz); + GPS_DBG_FUNC("src = %d, dst = %d, type = %d, buf = 0x%x sz = %d, max = %d\n", src, + dst, type, rst_msg, sz, WMTRSTMSG_RESET_MAX); + + if ((src == WMTDRV_TYPE_WMT) && (dst == WMTDRV_TYPE_GPS) && (type == WMTMSG_TYPE_RESET)) { + switch (rst_msg) { + case WMTRSTMSG_RESET_START: + GPS_INFO_FUNC("Whole chip reset start!\n"); + rstflag = 1; +#ifdef GPS_FWCTL_SUPPORT + down(&fwctl_mtx); + fgGps_fwctl_ready = false; +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH + /* clean FWLOG_CTRL_INNER flag in reference_count ,for rst*/ + GPS_reference_count(FWLOG_CTRL_INNER, false, GPS_DATA_LINK_ID0); +#endif + up(&fwctl_mtx); +#endif + GPS_ctrl_status_change_to(GPS_RESET_START); + break; + case WMTRSTMSG_RESET_END: + case WMTRSTMSG_RESET_END_FAIL: + if (rst_msg == WMTRSTMSG_RESET_END) + GPS_INFO_FUNC("Whole chip reset end!\n"); + else + GPS_INFO_FUNC("Whole chip reset fail!\n"); + rstflag = 2; + + GPS_ctrl_status_change_to(GPS_RESET_DONE); + break; + default: + break; + } + } + } else { + /*message format invalid */ + GPS_WARN_FUNC("Invalid message format!\n"); + } +} + +static bool desense_handled_flag; +static void GPS_handle_desense(bool on) +{ + bool to_do = false, handled = false; + + down(&status_mtx); + handled = desense_handled_flag; + if ((on && !handled) || (!on && handled)) + to_do = true; + else + to_do = false; + + if (on) + desense_handled_flag = true; + else + desense_handled_flag = false; + up(&status_mtx); + + if (!to_do) { + GPS_WARN_FUNC("GPS_handle_desense(%d) not to go due to handled = %d", on, handled); + return; + } + + if (on) { +#if defined(CONFIG_MACH_MT6739) + if (freqhopping_config(FH_MEM_PLLID, 0, 1) == 0) + GPS_WARN_FUNC("Enable MEMPLL successfully\n"); + else + GPS_WARN_FUNC("Error to enable MEMPLL\n"); +#endif +#if defined(CONFIG_MACH_MT6580) + GPS_WARN_FUNC("export_clk_buf: %x\n", CLK_BUF_AUDIO); + KERNEL_clk_buf_ctrl(CLK_BUF_AUDIO, 1); +#endif +#if defined(CONFIG_MACH_MT6765) || defined(CONFIG_MACH_MT6761) + dvfsrc_enable_dvfs_freq_hopping(1); + GPS_WARN_FUNC("mt6765/61 GPS desense solution on\n"); +#endif + } else { +#if defined(CONFIG_MACH_MT6739) + if (freqhopping_config(FH_MEM_PLLID, 0, 0) == 0) + GPS_WARN_FUNC("disable MEMPLL successfully\n"); + else + GPS_WARN_FUNC("Error to disable MEMPLL\n"); +#endif +#if defined(CONFIG_MACH_MT6765) || defined(CONFIG_MACH_MT6761) + dvfsrc_enable_dvfs_freq_hopping(0); + GPS_WARN_FUNC("mt6765/61 GPS desense solution off\n"); +#endif +#if defined(CONFIG_MACH_MT6580) + GPS_WARN_FUNC("export_clk_buf: %x\n", CLK_BUF_AUDIO); + KERNEL_clk_buf_ctrl(CLK_BUF_AUDIO, 0); +#endif + } +} + +static int GPS_open(struct inode *inode, struct file *file) +{ + pr_warn("%s: major %d minor %d (pid %d)\n", __func__, imajor(inode), iminor(inode), current->pid); + if (current->pid == 1) + return 0; + if (rstflag == 1) { + GPS_WARN_FUNC("whole chip resetting...\n"); + return -EPERM; + } + +#if 1 /* GeorgeKuo: turn on function before check stp ready */ + /* turn on BT */ +#ifdef CONFIG_GPS_CTRL_LNA_SUPPORT + gps_lna_pin_ctrl(GPS_DATA_LINK_ID0, true, false); +#endif + if (mtk_wcn_wmt_func_on(WMTDRV_TYPE_GPS) == MTK_WCN_BOOL_FALSE) { + GPS_WARN_FUNC("WMT turn on GPS fail!\n"); + return -ENODEV; + } + + mtk_wcn_wmt_msgcb_reg(WMTDRV_TYPE_GPS, gps_cdev_rst_cb); + GPS_WARN_FUNC("WMT turn on GPS OK!\n"); + rstflag = 0; + +#endif + + if (mtk_wcn_stp_is_ready()) { +#if 0 + if (mtk_wcn_wmt_func_on(WMTDRV_TYPE_GPS) == MTK_WCN_BOOL_FALSE) { + GPS_WARN_FUNC("WMT turn on GPS fail!\n"); + return -ENODEV; + } + GPS_DBG_FUNC("WMT turn on GPS OK!\n"); +#endif + mtk_wcn_stp_register_event_cb(GPS_TASK_INDX, GPS_event_cb); + } else { + GPS_ERR_FUNC("STP is not ready, Cannot open GPS Devices\n\r"); + + /*return error code */ + return -ENODEV; + } + gps_hold_wake_lock(1); + GPS_WARN_FUNC("gps_hold_wake_lock(1)\n"); + + GPS_reference_count(HANDLE_DESENSE, true, GPS_DATA_LINK_ID0); + +#ifdef GPS_FWCTL_SUPPORT + down(&fwctl_mtx); + GPS_reference_count(GPS_FWCTL_READY, true, GPS_DATA_LINK_ID0); +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH + if (fgGps_fwlog_on) { + /* GPS fw clear log on flag when GPS on, no need to send it if log setting is off */ + GPS_reference_count(FWLOG_CTRL_INNER, fgGps_fwlog_on, GPS_DATA_LINK_ID0); + } +#endif + up(&fwctl_mtx); +#endif /* GPS_FWCTL_SUPPORT */ + + rst_happened_or_gps_close_flag = 0; + GPS_ctrl_status_change_to(GPS_OPENED); + return 0; +} + +static int GPS_close(struct inode *inode, struct file *file) +{ + int ret = 0; + pr_warn("%s: major %d minor %d (pid %d)\n", __func__, imajor(inode), iminor(inode), current->pid); + if (current->pid == 1) + return 0; + + if (rstflag == 1) { + GPS_WARN_FUNC("whole chip resetting...\n"); + ret = -EPERM; + goto _out; + } + +#ifdef GPS_FWCTL_SUPPORT + down(&fwctl_mtx); + GPS_reference_count(GPS_FWCTL_READY, false, GPS_DATA_LINK_ID0); +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH + /* GPS fw clear log on flag when GPS on, this just to clear flag in gps_drv reference count */ + GPS_reference_count(FWLOG_CTRL_INNER, false, GPS_DATA_LINK_ID0); +#endif + up(&fwctl_mtx); +#endif +#ifdef CONFIG_GPS_CTRL_LNA_SUPPORT + gps_lna_pin_ctrl(GPS_DATA_LINK_ID0, false, false); +#endif + if (mtk_wcn_wmt_func_off(WMTDRV_TYPE_GPS) == MTK_WCN_BOOL_FALSE) { + GPS_WARN_FUNC("WMT turn off GPS fail!\n"); + ret = -EIO; /* mostly, native programer does not care this return vlaue, */ + /* but we still return error code. */ + goto _out; + } + GPS_WARN_FUNC("WMT turn off GPS OK!\n"); + rstflag = 0; + /*Flush Rx Queue */ + mtk_wcn_stp_register_event_cb(GPS_TASK_INDX, 0x0); /* unregister event callback function */ + mtk_wcn_wmt_msgcb_unreg(WMTDRV_TYPE_GPS); + +_out: + gps_hold_wake_lock(0); + GPS_WARN_FUNC("gps_hold_wake_lock(0)\n"); + + GPS_reference_count(HANDLE_DESENSE, false, GPS_DATA_LINK_ID0); + + GPS_ctrl_status_change_to(GPS_CLOSED); + return ret; +} + +const struct file_operations GPS_fops = { + .open = GPS_open, + .release = GPS_close, + .read = GPS_read, + .write = GPS_write, +/* .ioctl = GPS_ioctl */ + .unlocked_ioctl = GPS_unlocked_ioctl, + .compat_ioctl = GPS_compat_ioctl, +}; + +void GPS_event_cb(void) +{ +/* pr_debug("GPS_event_cb()\n");*/ + + flag = 1; + wake_up(&GPS_wq); +} + +#if WMT_CREATE_NODE_DYNAMIC || REMOVE_MK_NODE +struct class *stpgps_class; +#ifdef CONFIG_GPSL5_SUPPORT +struct class *stpgps2_class; +#endif +#endif + +static int GPS_init(void) +{ + dev_t dev = MKDEV(GPS_major, 0); + int cdev_err = 0; +#if WMT_CREATE_NODE_DYNAMIC || REMOVE_MK_NODE + struct device *stpgps_dev = NULL; +#endif +#ifdef CONFIG_GPSL5_SUPPORT + dev_t dev2 = MKDEV(GPS_major, 1); + int cdev2_err = 0; +#if WMT_CREATE_NODE_DYNAMIC || REMOVE_MK_NODE + struct device *stpgps2_dev = NULL; +#endif +#endif + int alloc_ret = 0; + + + /*static allocate chrdev */ + alloc_ret = register_chrdev_region(dev, 1, GPS_DRIVER_NAME); + if (alloc_ret) { + pr_warn("fail to register chrdev\n"); + return alloc_ret; + } + + cdev_init(&GPS_cdev, &GPS_fops); + GPS_cdev.owner = THIS_MODULE; + + cdev_err = cdev_add(&GPS_cdev, dev, GPS_devs); + if (cdev_err) + goto error; +#if WMT_CREATE_NODE_DYNAMIC || REMOVE_MK_NODE + + stpgps_class = class_create(THIS_MODULE, "stpgps"); + if (IS_ERR(stpgps_class)) + goto error; + stpgps_dev = device_create(stpgps_class, NULL, dev, NULL, "stpgps"); + if (IS_ERR(stpgps_dev)) + goto error; +#endif + +#ifdef CONFIG_GPSL5_SUPPORT + /*static allocate chrdev */ + alloc_ret = register_chrdev_region(dev2, 1, GPS2_DRIVER_NAME); + if (alloc_ret) { + pr_info("fail to register chrdev\n"); + return alloc_ret; + } + + cdev_init(&GPS2_cdev, &GPS2_fops); + GPS2_cdev.owner = THIS_MODULE; + + cdev2_err = cdev_add(&GPS2_cdev, dev2, GPS2_devs); + if (cdev2_err) + goto error; +#if WMT_CREATE_NODE_DYNAMIC || REMOVE_MK_NODE + + stpgps2_class = class_create(THIS_MODULE, "stpgps2"); + if (IS_ERR(stpgps2_class)) + goto error; + stpgps2_dev = device_create(stpgps2_class, NULL, dev2, NULL, "stpgps2"); + if (IS_ERR(stpgps2_dev)) + goto error; +#endif +#endif + pr_warn("%s driver(major %d) installed.\n", GPS_DRIVER_NAME, GPS_major); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 149) + gps_wake_lock_ptr = wakeup_source_register(NULL, gps_wake_lock_name); +#else + gps_wake_lock_ptr = wakeup_source_register(gps_wake_lock_name); +#endif + if (!gps_wake_lock_ptr) { + pr_info("%s %d: init wakeup source fail!", __func__, __LINE__); + goto error; + } + + sema_init(&status_mtx, 1); + sema_init(&fwctl_mtx, 1); + /* init_MUTEX(&wr_mtx); */ + sema_init(&wr_mtx, 1); + /* init_MUTEX(&rd_mtx); */ + sema_init(&rd_mtx, 1); + +#ifdef CONFIG_GPSL5_SUPPORT + wakeup_source_init(&gps2_wake_lock, "gpswakelock"); + + sema_init(&status_mtx2, 1); + /* init_MUTEX(&wr_mtx); */ + sema_init(&wr_mtx2, 1); + /* init_MUTEX(&rd_mtx); */ + sema_init(&rd_mtx2, 1); +#endif +#ifdef CONFIG_GPS_CTRL_LNA_SUPPORT + gps_lna_linux_plat_drv_register(); +#endif + return 0; + +error: + +#if WMT_CREATE_NODE_DYNAMIC || REMOVE_MK_NODE + if (!IS_ERR(stpgps_dev)) + device_destroy(stpgps_class, dev); + if (!IS_ERR(stpgps_class)) { + class_destroy(stpgps_class); + stpgps_class = NULL; + } +#ifdef CONFIG_GPSL5_SUPPORT + if (!IS_ERR(stpgps2_dev)) + device_destroy(stpgps2_class, dev2); + if (!IS_ERR(stpgps2_class)) { + class_destroy(stpgps2_class); + stpgps2_class = NULL; + } +#endif +#endif + if (cdev_err == 0) + cdev_del(&GPS_cdev); +#ifdef CONFIG_GPSL5_SUPPORT + if (cdev2_err == 0) + cdev_del(&GPS2_cdev); +#endif + if (alloc_ret == 0) { + unregister_chrdev_region(dev, GPS_devs); +#ifdef CONFIG_GPSL5_SUPPORT + unregister_chrdev_region(dev2, GPS2_devs); +#endif + } + + return -1; +} + +static void GPS_exit(void) +{ + dev_t dev = MKDEV(GPS_major, 0); +#ifdef CONFIG_GPSL5_SUPPORT + dev_t dev2 = MKDEV(GPS_major, 1); +#endif +#if WMT_CREATE_NODE_DYNAMIC || REMOVE_MK_NODE + device_destroy(stpgps_class, dev); + class_destroy(stpgps_class); + stpgps_class = NULL; +#ifdef CONFIG_GPSL5_SUPPORT + device_destroy(stpgps2_class, dev2); + class_destroy(stpgps2_class); + stpgps2_class = NULL; +#endif +#endif + + cdev_del(&GPS_cdev); + unregister_chrdev_region(dev, GPS_devs); + pr_warn("%s driver removed.\n", GPS_DRIVER_NAME); + +#ifdef CONFIG_GPSL5_SUPPORT + cdev_del(&GPS2_cdev); + unregister_chrdev_region(dev2, GPS2_devs); + pr_info("%s driver removed.\n", GPS2_DRIVER_NAME); + +#endif +#ifdef CONFIG_GPS_CTRL_LNA_SUPPORT + gps_lna_linux_plat_drv_unregister(); +#endif + wakeup_source_unregister(gps_wake_lock_ptr); +} + +int mtk_wcn_stpgps_drv_init(void) +{ + return GPS_init(); +} +EXPORT_SYMBOL(mtk_wcn_stpgps_drv_init); + +void mtk_wcn_stpgps_drv_exit(void) +{ + return GPS_exit(); +} +EXPORT_SYMBOL(mtk_wcn_stpgps_drv_exit); + +/*****************************************************************************/ +static int __init gps_mod_init(void) +{ + int ret = 0; + + mtk_wcn_stpgps_drv_init(); + #ifdef CONFIG_MTK_GPS_EMI + mtk_gps_emi_init(); + #endif + #ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH + mtk_gps_fw_log_init(); + #endif + return ret; +} + +/*****************************************************************************/ +static void __exit gps_mod_exit(void) +{ + mtk_wcn_stpgps_drv_exit(); + #ifdef CONFIG_MTK_GPS_EMI + mtk_gps_emi_exit(); + #endif + #ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH + mtk_gps_fw_log_exit(); + #endif +} + +module_init(gps_mod_init); +module_exit(gps_mod_exit); + +int reference_count_bitmap[2] = {0}; +void GPS_reference_count(enum gps_reference_count_cmd cmd, bool flag, enum gps_data_link_id_enum user) +{ + bool old_state = false; + bool new_state = false; + + old_state = (reference_count_bitmap[0] & (0x01 << (int)cmd)) + || (reference_count_bitmap[1] & (0x01 << (int)cmd)); + if (flag == true) + reference_count_bitmap[(int)user] |= (0x01 << (int)cmd); + else + reference_count_bitmap[(int)user] &= ~(0x01 << (int)cmd); + new_state = (reference_count_bitmap[0] & (0x01 << (int)cmd)) + || (reference_count_bitmap[1] & (0x01 << (int)cmd)); + + switch (cmd) { + case FWLOG_CTRL_INNER: +#ifdef GPS_FWCTL_SUPPORT + /* (new_state != false) when came to disable, just need clear flag in reference_count_bitmap , */ + if ((old_state != new_state) && (new_state != false)) + GPS_fwlog_ctrl_inner(new_state); +#endif + break; + case HANDLE_DESENSE: + if (old_state != new_state) + GPS_handle_desense(new_state); + break; + case GPS_FWCTL_READY: +#ifdef GPS_FWCTL_SUPPORT + if (old_state != new_state) + fgGps_fwctl_ready = new_state; +#endif + break; + } +} + diff --git a/drivers/misc/mediatek/connectivity/gps/stp_chrdev_gps2.c b/drivers/misc/mediatek/connectivity/gps/stp_chrdev_gps2.c new file mode 100644 index 0000000000000000000000000000000000000000..2e90aef7099e9c4a7552deaee43941063dae0602 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/gps/stp_chrdev_gps2.c @@ -0,0 +1,852 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "osal_typedef.h" +#include "stp_exp.h" +#include "wmt_exp.h" +#include +#if defined(CONFIG_MACH_MT6580) +#include +#endif +#include "gps.h" +#if defined(CONFIG_MACH_MT6739) +#include +#include +#endif +#if defined(CONFIG_MACH_MT6765) || defined(CONFIG_MACH_MT6761) +#include +#endif +#ifdef CONFIG_GPS_CTRL_LNA_SUPPORT +#include "gps_lna_drv.h" +#endif + +#define GPS2_DEBUG_TRACE_GPIO 0 +#define GPS2_DEBUG_DUMP 0 + +#define PFX2 "[GPS2] " +#define GPS2_LOG_DBG 3 +#define GPS2_LOG_INFO 2 +#define GPS2_LOG_WARN 1 +#define GPS2_LOG_ERR 0 + +#define COMBO_IOC_GPS2_HWVER 6 +#define COMBO_IOC_GPS2_IC_HW_VERSION 7 +#define COMBO_IOC_GPS2_IC_FW_VERSION 8 +#define COMBO_IOC_D1_EFUSE_GET2 9 +#define COMBO_IOC_RTC_FLAG2 10 +#define COMBO_IOC_CO_CLOCK_FLAG2 11 +#define COMBO_IOC_TRIGGER_WMT_ASSERT2 12 +#define COMBO_IOC_WMT_STATUS2 13 +#define COMBO_IOC_TAKE_GPS2_WAKELOCK 14 +#define COMBO_IOC_GIVE_GPS2_WAKELOCK 15 +#define COMBO_IOC_GET_GPS2_LNA_PIN 16 +#define COMBO_IOC_GPS2_FWCTL 17 +#define COMBO_IOC_GPS2_HW_SUSPEND 18 +#define COMBO_IOC_GPS2_HW_RESUME 19 +#define COMBO_IOC_GPS2_LISTEN_RST_EVT 20 + +static UINT32 g2DbgLevel = GPS2_LOG_DBG; + +#define GPS2_DBG_FUNC(fmt, arg...) \ +do { if (g2DbgLevel >= GPS2_LOG_DBG) \ + pr_debug(PFX2 "[D]%s: " fmt, __func__, ##arg); \ +} while (0) +#define GPS2_INFO_FUNC(fmt, arg...) \ +do { if (g2DbgLevel >= GPS2_LOG_INFO) \ + pr_info(PFX2 "[I]%s: " fmt, __func__, ##arg); \ +} while (0) +#define GPS2_WARN_FUNC(fmt, arg...) \ +do { if (g2DbgLevel >= GPS2_LOG_WARN) \ + pr_info(PFX2 "[W]%s: " fmt, __func__, ##arg); \ +} while (0) +#define GPS2_ERR_FUNC(fmt, arg...) \ +do { if (g2DbgLevel >= GPS2_LOG_ERR) \ + pr_info(PFX2 "[E]%s: " fmt, __func__, ##arg); \ +} while (0) +#define GPS2_TRC_FUNC(f) \ +do { if (g2DbgLevel >= GPS2_LOG_DBG) \ + pr_info(PFX2 "<%s> <%d>\n", __func__, __LINE__); \ +} while (0) + +struct wakeup_source gps2_wake_lock; +static unsigned char wake_lock_acquired2; /* default: 0 */ + +#if (defined(CONFIG_MTK_GMO_RAM_OPTIMIZE) && !defined(CONFIG_MTK_ENG_BUILD)) +#define STP_GPS_BUFFER_SIZE2 2048 +#else +#define STP_GPS_BUFFER_SIZE2 MTKSTP_BUFFER_SIZE +#endif +static unsigned char i_buf2[STP_GPS_BUFFER_SIZE2]; /* input buffer of read() */ +static unsigned char o_buf2[STP_GPS_BUFFER_SIZE2]; /* output buffer of write() */ +struct semaphore wr_mtx2, rd_mtx2, status_mtx2; +static DECLARE_WAIT_QUEUE_HEAD(GPS2_wq); +static DECLARE_WAIT_QUEUE_HEAD(GPS2_rst_wq); +static int flag2; +static int rstflag2; +static int rst_listening_flag2; +static int rst_happened_or_gps_close_flag2; + +static enum gps_ctrl_status_enum g_gps2_ctrl_status; + +static void GPS2_check_and_wakeup_rst_listener(enum gps_ctrl_status_enum to) +{ + if (to == GPS_RESET_START || to == GPS_RESET_DONE || to == GPS_CLOSED) { + rst_happened_or_gps_close_flag2 = 1; + if (rst_listening_flag2) { + wake_up(&GPS2_rst_wq); + GPS2_WARN_FUNC("Set GPS rst_happened_or_gps_close_flag2 because to = %d", to); + } + } +} + +#ifdef GPS_HW_SUSPEND_SUPPORT +static void GPS2_ctrl_status_change_from_to(enum gps_ctrl_status_enum from, enum gps_ctrl_status_enum to) +{ + bool okay = true; + enum gps_ctrl_status_enum status_backup; + + down(&status_mtx2); + /* Due to checking status and setting status are not atomic, + * mutex is needed to make sure they are an atomic operation. + * Note: reading the status is no need to protect + */ + status_backup = g_gps2_ctrl_status; + if (status_backup == from) + g_gps2_ctrl_status = to; + else + okay = false; + up(&status_mtx2); + + if (!okay) + GPS2_WARN_FUNC("GPS unexpected status %d, not chagne from %d to %d", status_backup, from, to); + else + GPS2_check_and_wakeup_rst_listener(to); +} +#endif + +static enum gps_ctrl_status_enum GPS2_ctrl_status_change_to(enum gps_ctrl_status_enum to) +{ + enum gps_ctrl_status_enum status_backup; + + down(&status_mtx2); + status_backup = g_gps2_ctrl_status; + g_gps2_ctrl_status = to; + up(&status_mtx2); + + GPS2_check_and_wakeup_rst_listener(to); + + return status_backup; +} + +static void GPS2_event_cb(void); + +static void gps2_hold_wake_lock(int hold) +{ + if (hold == 1) { + if (!wake_lock_acquired2) { + GPS2_DBG_FUNC("acquire gps2 wake_lock acquired = %d\n", wake_lock_acquired2); + __pm_stay_awake(&gps2_wake_lock); + wake_lock_acquired2 = 1; + } else { + GPS2_DBG_FUNC("acquire gps2 wake_lock acquired = %d (do nothing)\n", wake_lock_acquired2); + } + } else if (hold == 0) { + if (wake_lock_acquired2) { + GPS2_DBG_FUNC("release gps2 wake_lock acquired = %d\n", wake_lock_acquired2); + __pm_relax(&gps2_wake_lock); + wake_lock_acquired2 = 0; + } else { + GPS2_DBG_FUNC("release gps2 wake_lock acquired = %d (do nothing)\n", wake_lock_acquired2); + } + } +} + +bool rtc_GPS2_low_power_detected(void) +{ + static bool first_query = true; + + if (first_query) { + first_query = false; + /*return rtc_low_power_detected();*/ + return 0; + } else { + return false; + } +} + +ssize_t GPS2_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) +{ + int retval = 0; + int written = 0; + + down(&wr_mtx2); + + /* GPS2_TRC_FUNC(); */ + + /*pr_info("%s: count %d pos %lld\n", __func__, count, *f_pos); */ + if (count > 0) { + int copy_size = (count < STP_GPS_BUFFER_SIZE2) ? count : STP_GPS_BUFFER_SIZE2; + + if (copy_from_user(&o_buf2[0], &buf[0], copy_size)) { + retval = -EFAULT; + goto out; + } + /* pr_info("%02x ", val); */ +#if GPS2_DEBUG_TRACE_GPIO + mtk_wcn_stp_debug_gpio_assert(IDX_GPS_TX, DBG_TIE_LOW); +#endif + written = mtk_wcn_stp_send_data(&o_buf2[0], copy_size, GPSL5_TASK_INDX); +#if GPS2_DEBUG_TRACE_GPIO + mtk_wcn_stp_debug_gpio_assert(IDX_GPS_TX, DBG_TIE_HIGH); +#endif + +#if GPS2_DEBUG_DUMP + { + unsigned char *buf_ptr = &o_buf2[0]; + int k = 0; + + pr_info("--[GPS2-WRITE]--"); + for (k = 0; k < 10; k++) { + if (k % 16 == 0) + pr_info("\n"); + pr_info("0x%02x ", o_buf2[k]); + } + pr_info("\n"); + } +#endif + if (written == 0) { + retval = -ENOSPC; + /* no windowspace in STP is available, */ + /* native process should not call GPS2_write with no delay at all */ + GPS2_ERR_FUNC + ("target packet length:%zd, write success length:%d, retval = %d.\n", + count, written, retval); + } else { + retval = written; + } + } else { + retval = -EFAULT; + GPS2_ERR_FUNC("target packet length:%zd is not allowed, retval = %d.\n", count, retval); + } +out: + up(&wr_mtx2); + return retval; +} + +ssize_t GPS2_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) +{ + long val = 0; + int retval; + + down(&rd_mtx2); + + /* pr_debug("GPS2_read(): count %d pos %lld\n", count, *f_pos); */ + if (rstflag2 == 1) { + if (filp->f_flags & O_NONBLOCK) { + /* GPS2_DBG_FUNC("Non-blocking read, whole chip reset occurs! rstflag2=%d\n", rstflag2); */ + retval = -EIO; + goto OUT; + } + } + + if (count > STP_GPS_BUFFER_SIZE2) + count = STP_GPS_BUFFER_SIZE2; + +#if GPS2_DEBUG_TRACE_GPIO + mtk_wcn_stp_debug_gpio_assert(IDX_GPS_RX, DBG_TIE_LOW); +#endif + retval = mtk_wcn_stp_receive_data(i_buf2, count, GPSL5_TASK_INDX); +#if GPS2_DEBUG_TRACE_GPIO + mtk_wcn_stp_debug_gpio_assert(IDX_GPS_RX, DBG_TIE_HIGH); +#endif + + while (retval == 0) { + /* got nothing, wait for STP's signal */ + /* wait_event(GPS2_wq, flag2 != 0); *//* George: let signal wake up */ + if (filp->f_flags & O_NONBLOCK) { + /* GPS2_DBG_FUNC("Non-blocking read, no data is available!\n"); */ + retval = -EAGAIN; + goto OUT; + } + + val = wait_event_interruptible(GPS2_wq, flag2 != 0); + flag2 = 0; + +#if GPS2_DEBUG_TRACE_GPIO + mtk_wcn_stp_debug_gpio_assert(IDX_GPS_RX, DBG_TIE_LOW); +#endif + + retval = mtk_wcn_stp_receive_data(i_buf2, count, GPSL5_TASK_INDX); + +#if GPS2_DEBUG_TRACE_GPIO + mtk_wcn_stp_debug_gpio_assert(IDX_GPS_RX, DBG_TIE_HIGH); +#endif + /* if we are signaled */ + if (val) { + if (-ERESTARTSYS == val) + GPS2_DBG_FUNC("signaled by -ERESTARTSYS(%ld)\n ", val); + else + GPS2_DBG_FUNC("signaled by %ld\n ", val); + + break; + } + } + +#if GPS2_DEBUG_DUMP + { + unsigned char *buf_ptr = &i_buf2[0]; + int k = 0; + + pr_info("--[GPS2-READ]--"); + for (k = 0; k < 10; k++) { + if (k % 16 == 0) + pr_info("\n"); + pr_info("0x%02x ", i_buf2[k]); + } + pr_info("--\n"); + } +#endif + + if (retval > 0) { + /* we got something from STP driver */ + if (copy_to_user(buf, i_buf2, retval)) { + retval = -EFAULT; + goto OUT; + } else { + /* success */ + } + } else { + /* we got nothing from STP driver, being signaled */ + retval = val; + } + +OUT: + up(&rd_mtx2); +/* pr_info("GPS2_read(): retval = %d\n", retval);*/ + return retval; +} + +#ifdef GPS_FWCTL_SUPPORT +#ifdef GPS_HW_SUSPEND_SUPPORT +#define HW_SUSPEND_CTRL_TX_LEN2 (2) +#define HW_SUSPEND_CTRL_RX_LEN2 (3) + +/* return 0 if okay, otherwise is fail */ +static int GPS2_hw_suspend_ctrl(bool to_suspend) +{ + UINT8 tx_buf[HW_SUSPEND_CTRL_TX_LEN2]; + UINT8 rx_buf[HW_SUSPEND_CTRL_RX_LEN2]; + UINT8 rx0 = 0; + UINT8 rx1 = 0; + UINT32 tx_len; + UINT32 rx_len = 0; + INT32 wmt_status; + UINT32 local_ms0, local_ms1; + struct timeval tv; + UINT64 tmp; + + do_gettimeofday(&tv); + tmp = local_clock(); + do_div(tmp, 1e6); + local_ms0 = (UINT32)tmp; /* overflow almost 4.9 days */ + + tx_buf[0] = to_suspend ? GPS2_FWCTL_OPCODE_ENTER_STOP_MODE : + GPS2_FWCTL_OPCODE_EXIT_STOP_MODE; + tx_len = 1; + + wmt_status = mtk_wmt_gps_mcu_ctrl(&tx_buf[0], tx_len, + &rx_buf[0], HW_SUSPEND_CTRL_RX_LEN2, &rx_len); + + /* local_ms1 = jiffies_to_msecs(jiffies); */ + tmp = local_clock(); + do_div(tmp, 1e6); + local_ms1 = (UINT32)tmp; + + if (wmt_status == 0) { /* 0 is okay */ + if (rx_len >= 2) { + rx0 = rx_buf[0]; /* fw_status, 0 is okay */ + rx1 = rx_buf[1]; /* opcode */ + } + } + + if (wmt_status != 0 || rx0 != 0) { + /* Fail due to WMT fail or FW not support, + * bypass the following operations + */ + GPS2_WARN_FUNC("GPS2_hw_suspend_ctrl %d: st=%d, rx_len=%u ([0]=%u, [1]=%u), ms0=%u, ms1=%u", + to_suspend, wmt_status, rx_len, rx0, rx1, local_ms0, local_ms1); + return -1; + } + + /* Okay */ + GPS2_INFO_FUNC("GPS2_hw_suspend_ctrl %d: st=%d, rx_len=%u ([0]=%u, [1]=%u), ms0=%u, ms1=%u", + to_suspend, wmt_status, rx_len, rx0, rx1, local_ms0, local_ms1); + return 0; +} + +static int GPS2_hw_suspend(void) +{ + MTK_WCN_BOOL wmt_okay; + enum gps_ctrl_status_enum gps_status; + + gps_status = g_gps2_ctrl_status; + if (gps_status == GPS_OPENED) { + if (GPS2_hw_suspend_ctrl(true) != 0) + return -EINVAL; /* Stands for not support */ + + wmt_okay = mtk_wmt_gps_l5_suspend_ctrl(MTK_WCN_BOOL_TRUE); + if (!wmt_okay) + GPS2_WARN_FUNC("mtk_wmt_gps_l5_suspend_ctrl(1), is_ok = %d", wmt_okay); + + /* register event cb will clear GPS STP buffer */ + mtk_wcn_stp_register_event_cb(GPSL5_TASK_INDX, 0x0); + GPS2_DBG_FUNC("mtk_wcn_stp_register_event_cb to null"); + + /* No need to clear the flag2 due to it just a flag2 and not stands for has data + * flag2 = 0; + * + * Keep msgcb due to GPS still need to recevice reset event under HW suspend mode + * mtk_wcn_wmt_msgcb_unreg(WMTDRV_TYPE_GPSL5); + */ + + GPS_reference_count(HANDLE_DESENSE, false, GPS_DATA_LINK_ID1); + gps2_hold_wake_lock(0); + GPS2_WARN_FUNC("gps2_hold_wake_lock(0)\n"); + + GPS2_ctrl_status_change_from_to(GPS_OPENED, GPS_SUSPENDED); + } else + GPS2_WARN_FUNC("GPS2_hw_suspend(): status %d not match\n", gps_status); + + return 0; +} + +static int GPS2_hw_resume(void) +{ + MTK_WCN_BOOL wmt_okay; + enum gps_ctrl_status_enum gps_status; + + gps_status = g_gps2_ctrl_status; + if (gps_status == GPS_SUSPENDED) { + GPS_reference_count(HANDLE_DESENSE, true, GPS_DATA_LINK_ID1); + gps2_hold_wake_lock(1); + GPS2_WARN_FUNC("gps2_hold_wake_lock(1)\n"); + + wmt_okay = mtk_wmt_gps_l5_suspend_ctrl(MTK_WCN_BOOL_FALSE); + if (!wmt_okay) + GPS2_WARN_FUNC("mtk_wmt_gps_l5_suspend_ctrl(0), is_ok = %d", wmt_okay); + + if (GPS2_hw_suspend_ctrl(false) != 0) + return -EINVAL; /* Stands for not support */ + + mtk_wcn_stp_register_event_cb(GPSL5_TASK_INDX, GPS2_event_cb); + GPS2_ctrl_status_change_from_to(GPS_SUSPENDED, GPS_OPENED); + } else + GPS2_WARN_FUNC("GPS2_hw_resume(): status %d not match\n", gps_status); + + return 0; +} +#endif /* GPS_HW_SUSPEND_SUPPORT */ + +#endif /* GPS_FWCTL_SUPPORT */ + +/* block until wmt reset happen or GPS_close */ +static int GPS2_listen_wmt_rst(void) +{ + long val = 0; + + rst_listening_flag2 = 1; + while (!rst_happened_or_gps_close_flag2) { + val = wait_event_interruptible(GPS2_rst_wq, rst_happened_or_gps_close_flag2); + + GPS2_WARN_FUNC("GPS2_listen_wmt_rst(): val = %ld, cond = %d, rstflag2 = %d, status = %d\n", + val, rst_happened_or_gps_close_flag2, rstflag2, g_gps2_ctrl_status); + + /* if we are signaled */ + if (val) { + rst_listening_flag2 = 0; + return val; + } + } + + rst_listening_flag2 = 0; + return 0; +} + +/* int GPS_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) */ +long GPS2_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + int retval = 0; + #if 0 + ENUM_WMTHWVER_TYPE_T hw_ver_sym = WMTHWVER_INVALID; + #endif + UINT32 hw_version = 0; + UINT32 fw_version = 0; + UINT32 gps_lna_pin = 0; + + pr_info("GPS2_ioctl(): cmd (%d)\n", cmd); + + switch (cmd) { + case 0: /* enable/disable STP */ + GPS2_DBG_FUNC("GPS_ioctl(): disable STP control from GPS2 dev\n"); + retval = -EINVAL; +#if 1 +#else + /* George: STP is controlled by WMT only */ + mtk_wcn_stp_enable(arg); +#endif + break; + + case 1: /* send raw data */ + GPS2_DBG_FUNC("GPS2_ioctl(): disable raw data from GPS2 dev\n"); + retval = -EINVAL; + break; + + #if 0 + case COMBO_IOC_GPS2_HWVER: + /*get combo hw version */ + hw_ver_sym = mtk_wcn_wmt_hwver_get(); + + GPS2_DBG_FUNC("GPS_ioctl(): get hw version = %d, sizeof(hw_ver_sym) = %zd\n", + hw_ver_sym, sizeof(hw_ver_sym)); + if (copy_to_user((int __user *)arg, &hw_ver_sym, sizeof(hw_ver_sym))) + retval = -EFAULT; + + break; + #endif + case COMBO_IOC_GPS2_IC_HW_VERSION: + /*get combo hw version from ic, without wmt mapping */ + hw_version = mtk_wcn_wmt_ic_info_get(WMTCHIN_HWVER); + + GPS2_DBG_FUNC("GPS2_ioctl(): get hw version = 0x%x\n", hw_version); + if (copy_to_user((int __user *)arg, &hw_version, sizeof(hw_version))) + retval = -EFAULT; + + break; + + case COMBO_IOC_GPS2_IC_FW_VERSION: + /*get combo fw version from ic, without wmt mapping */ + fw_version = mtk_wcn_wmt_ic_info_get(WMTCHIN_FWVER); + + GPS2_DBG_FUNC("GPS2_ioctl(): get fw version = 0x%x\n", fw_version); + if (copy_to_user((int __user *)arg, &fw_version, sizeof(fw_version))) + retval = -EFAULT; + + break; + case COMBO_IOC_RTC_FLAG2: + + retval = rtc_GPS2_low_power_detected(); + + GPS2_DBG_FUNC("low power flag2 (%d)\n", retval); + break; + case COMBO_IOC_CO_CLOCK_FLAG2: +#if SOC_CO_CLOCK_FLAG + retval = mtk_wcn_wmt_co_clock_flag_get(); +#endif + GPS2_DBG_FUNC("GPS co_clock_flag (%d)\n", retval); + break; + case COMBO_IOC_D1_EFUSE_GET2: +#if defined(CONFIG_MACH_MT6735) + do { + char *addr = ioremap(0x10206198, 0x4); + + retval = *(unsigned int *)addr; + GPS2_DBG_FUNC("D1 efuse (0x%x)\n", retval); + iounmap(addr); + } while (0); +#elif defined(CONFIG_MACH_MT6763) + do { + char *addr = ioremap(0x11f10048, 0x4); + + retval = *(unsigned int *)addr; + GPS2_DBG_FUNC("6763 efuse (0x%x)\n", retval); + iounmap(addr); + } while (0); +#else + GPS2_ERR_FUNC("Read Efuse not supported in this platform\n"); +#endif + break; + + case COMBO_IOC_TRIGGER_WMT_ASSERT2: + /* Trigger FW assert for debug */ + GPS2_INFO_FUNC("%s: Host trigger FW assert......, reason:%lu\n", __func__, arg); + retval = mtk_wcn_wmt_assert(WMTDRV_TYPE_GPSL5, arg); + if (retval == MTK_WCN_BOOL_TRUE) { + GPS2_INFO_FUNC("Host trigger FW assert succeed\n"); + retval = 0; + } else { + GPS2_ERR_FUNC("Host trigger FW assert Failed\n"); + retval = (-EBUSY); + } + break; + case COMBO_IOC_WMT_STATUS2: + if (rstflag2 == 1) { + /* chip resetting */ + retval = -888; + } else if (rstflag2 == 2) { + /* chip reset end */ + retval = -889; + /* + * rstflag2 = 0 is cleared by GPS_open or GPS_close, + * no need to clear it here + */ + } else { + /* normal */ + retval = 0; + } + GPS2_DBG_FUNC("rstflag2(%d), retval(%d)\n", rstflag2, retval); + break; + case COMBO_IOC_TAKE_GPS2_WAKELOCK: + GPS2_INFO_FUNC("Ioctl to take gps2 wakelock\n"); + gps2_hold_wake_lock(1); + if (wake_lock_acquired2 == 1) + retval = 0; + else + retval = -EAGAIN; + break; + case COMBO_IOC_GIVE_GPS2_WAKELOCK: + GPS2_INFO_FUNC("Ioctl to give gps2 wakelock\n"); + gps2_hold_wake_lock(0); + if (wake_lock_acquired2 == 0) + retval = 0; + else + retval = -EAGAIN; + break; + +#ifdef GPS_HW_SUSPEND_SUPPORT + case COMBO_IOC_GPS2_HW_SUSPEND: + GPS2_INFO_FUNC("COMBO_IOC_GPS2_HW_SUSPEND\n"); + retval = GPS2_hw_suspend(); + break; + case COMBO_IOC_GPS2_HW_RESUME: + GPS2_INFO_FUNC("COMBO_IOC_GPS2_HW_RESUME\n"); + retval = GPS2_hw_resume(); + break; +#endif /* GPS_HW_SUSPEND_SUPPORT */ + + case COMBO_IOC_GPS2_LISTEN_RST_EVT: + GPS2_INFO_FUNC("COMBO_IOC_GPS2_LISTEN_RST_EVT\n"); + retval = GPS2_listen_wmt_rst(); + break; + + case COMBO_IOC_GET_GPS2_LNA_PIN: + gps_lna_pin = mtk_wmt_get_gps_lna_pin_num(); + GPS2_DBG_FUNC("GPS2_ioctl(): get gps lna pin = %d\n", gps_lna_pin); + if (copy_to_user((int __user *)arg, &gps_lna_pin, sizeof(gps_lna_pin))) + retval = -EFAULT; + break; + default: + retval = -EFAULT; + GPS2_DBG_FUNC("GPS2_ioctl(): unknown cmd (%d)\n", cmd); + break; + } + +/*OUT:*/ + return retval; +} + +long GPS2_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + long ret; + + pr_info("%s: cmd (%d)\n", __func__, cmd); + ret = GPS2_unlocked_ioctl(filp, cmd, arg); + pr_info("%s: cmd (%d)\n", __func__, cmd); + return ret; +} + +static void gps2_cdev_rst_cb(ENUM_WMTDRV_TYPE_T src, + ENUM_WMTDRV_TYPE_T dst, ENUM_WMTMSG_TYPE_T type, void *buf, unsigned int sz) +{ + + /* To handle reset procedure please */ + ENUM_WMTRSTMSG_TYPE_T rst_msg; + + GPS2_DBG_FUNC("sizeof(ENUM_WMTRSTMSG_TYPE_T) = %zd\n", sizeof(ENUM_WMTRSTMSG_TYPE_T)); + if (sz <= sizeof(ENUM_WMTRSTMSG_TYPE_T)) { + memcpy((char *)&rst_msg, (char *)buf, sz); + GPS2_DBG_FUNC("src = %d, dst = %d, type = %d, buf = 0x%x sz = %d, max = %d\n", src, + dst, type, rst_msg, sz, WMTRSTMSG_RESET_MAX); + + if ((src == WMTDRV_TYPE_WMT) && (dst == WMTDRV_TYPE_GPSL5) && (type == WMTMSG_TYPE_RESET)) { + switch (rst_msg) { + case WMTRSTMSG_RESET_START: + GPS2_INFO_FUNC("Whole chip reset start!\n"); + rstflag2 = 1; +#ifdef GPS_FWCTL_SUPPORT + down(&fwctl_mtx); + fgGps_fwctl_ready = false; +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH + /* clean FWLOG_CTRL_INNER flag in reference_count ,for rst*/ + GPS_reference_count(FWLOG_CTRL_INNER, false, GPS_DATA_LINK_ID1); +#endif + up(&fwctl_mtx); +#endif + GPS2_ctrl_status_change_to(GPS_RESET_START); + break; + case WMTRSTMSG_RESET_END: + case WMTRSTMSG_RESET_END_FAIL: + if (rst_msg == WMTRSTMSG_RESET_END) + GPS2_INFO_FUNC("Whole chip reset end!\n"); + else + GPS2_INFO_FUNC("Whole chip reset fail!\n"); + rstflag2 = 2; + + GPS2_ctrl_status_change_to(GPS_RESET_DONE); + break; + default: + break; + } + } + } else { + /*message format invalid */ + GPS2_WARN_FUNC("Invalid message format!\n"); + } +} + +static int GPS2_open(struct inode *inode, struct file *file) +{ + pr_info("%s: major %d minor %d (pid %d)\n", __func__, imajor(inode), iminor(inode), current->pid); + if (current->pid == 1) + return 0; + if (rstflag2 == 1) { + GPS2_WARN_FUNC("whole chip resetting...\n"); + return -EPERM; + } + +#if 1 /* GeorgeKuo: turn on function before check stp ready */ + /* turn on BT */ +#ifdef CONFIG_GPS_CTRL_LNA_SUPPORT + gps_lna_pin_ctrl(GPS_DATA_LINK_ID1, true, false); +#endif + if (mtk_wcn_wmt_func_on(WMTDRV_TYPE_GPSL5) == MTK_WCN_BOOL_FALSE) { + GPS2_WARN_FUNC("WMT turn on GPS2 fail!\n"); + return -ENODEV; + } + + mtk_wcn_wmt_msgcb_reg(WMTDRV_TYPE_GPSL5, gps2_cdev_rst_cb); + GPS2_WARN_FUNC("WMT turn on GPS2 OK!\n"); + rstflag2 = 0; + +#endif + + if (mtk_wcn_stp_is_ready()) { +#if 0 + if (mtk_wcn_wmt_func_on(WMTDRV_TYPE_GPSL5) == MTK_WCN_BOOL_FALSE) { + GPS2_WARN_FUNC("WMT turn on GPS fail!\n"); + return -ENODEV; + } + GPS2_DBG_FUNC("WMT turn on GPS2 OK!\n"); +#endif + mtk_wcn_stp_register_event_cb(GPSL5_TASK_INDX, GPS2_event_cb); + } else { + GPS2_ERR_FUNC("STP is not ready, Cannot open GPS2 Devices\n\r"); + + /*return error code */ + return -ENODEV; + } + gps2_hold_wake_lock(1); + GPS2_WARN_FUNC("gps2_hold_wake_lock(1)\n"); + + GPS_reference_count(HANDLE_DESENSE, true, GPS_DATA_LINK_ID1); + +#ifdef GPS_FWCTL_SUPPORT + down(&fwctl_mtx); + GPS_reference_count(GPS_FWCTL_READY, true, GPS_DATA_LINK_ID1); +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH + if (fgGps_fwlog_on) { + /* GPS fw clear log on flag2 when GPS on, no need to send it if log setting is off */ + GPS_reference_count(FWLOG_CTRL_INNER, fgGps_fwlog_on, GPS_DATA_LINK_ID1); + } +#endif + up(&fwctl_mtx); +#endif /* GPS_FWCTL_SUPPORT */ + + rst_happened_or_gps_close_flag2 = 0; + GPS2_ctrl_status_change_to(GPS_OPENED); + return 0; +} + +static int GPS2_close(struct inode *inode, struct file *file) +{ + int ret = 0; + + pr_info("%s: major %d minor %d (pid %d)\n", __func__, imajor(inode), iminor(inode), current->pid); + if (current->pid == 1) + return 0; + + if (rstflag2 == 1) { + GPS2_WARN_FUNC("whole chip resetting...\n"); + ret = -EPERM; + goto _out; + } + +#ifdef GPS_FWCTL_SUPPORT + down(&fwctl_mtx); + GPS_reference_count(GPS_FWCTL_READY, false, GPS_DATA_LINK_ID1); +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH + /* GPS fw clear log on flag when GPS on, this just to clear flag in gps_drv reference count */ + GPS_reference_count(FWLOG_CTRL_INNER, false, GPS_DATA_LINK_ID1); +#endif + up(&fwctl_mtx); +#endif +#ifdef CONFIG_GPS_CTRL_LNA_SUPPORT + gps_lna_pin_ctrl(GPS_DATA_LINK_ID1, false, false); +#endif + if (mtk_wcn_wmt_func_off(WMTDRV_TYPE_GPSL5) == MTK_WCN_BOOL_FALSE) { + GPS2_WARN_FUNC("WMT turn off GPS2 fail!\n"); + ret = -EIO; + goto _out; + } + + GPS2_WARN_FUNC("WMT turn off GPS2 OK!\n"); + rstflag2 = 0; + /*Flush Rx Queue */ + mtk_wcn_stp_register_event_cb(GPSL5_TASK_INDX, 0x0); /* unregister event callback function */ + mtk_wcn_wmt_msgcb_unreg(WMTDRV_TYPE_GPSL5); + +_out: + gps2_hold_wake_lock(0); + GPS2_WARN_FUNC("gps2_hold_wake_lock(0)\n"); + + GPS_reference_count(HANDLE_DESENSE, false, GPS_DATA_LINK_ID1); + + GPS2_ctrl_status_change_to(GPS_CLOSED); + return ret; +} + +const struct file_operations GPS2_fops = { + .open = GPS2_open, + .release = GPS2_close, + .read = GPS2_read, + .write = GPS2_write, +/* .ioctl = GPS_ioctl */ + .unlocked_ioctl = GPS2_unlocked_ioctl, + .compat_ioctl = GPS2_compat_ioctl, +}; + +void GPS2_event_cb(void) +{ +/* pr_debug("GPS2_event_cb()\n");*/ + + flag2 = 1; + wake_up(&GPS2_wq); +} + diff --git a/drivers/misc/mediatek/connectivity/wlan/adaptor/Makefile b/drivers/misc/mediatek/connectivity/wlan/adaptor/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..892f0a4bbbc422315f31b2114411a6d0e03d4b91 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/adaptor/Makefile @@ -0,0 +1,56 @@ +# Force build fail on modpost warning +KBUILD_MODPOST_FAIL_ON_WARNINGS := y + +ccflags-y += \ + -I$(srctree)/drivers/misc/mediatek/include/mt-plat \ + -I$(srctree)/drivers/misc/mediatek/connectivity/common/common_main/include \ + -I$(srctree)/drivers/misc/mediatek/connectivity/common/common_main/linux/include + +ifeq ($(ADAPTOR_OPTS),CONNAC2X2_SOC3_0) +ccflags-y += -I$(srctree)/drivers/misc/mediatek/connectivity/conninfra/include +ccflags-y += -I$(srctree)/drivers/misc/mediatek/connectivity/conninfra/debug_utility +ccflags-y += -I$(srctree)/drivers/misc/mediatek/connectivity/conninfra/debug_utility/include +ccflags-y += -I$(srctree)/drivers/misc/mediatek/connectivity/conninfra/debug_utility/connsyslog +ccflags-y += -I$(srctree)/drivers/misc/mediatek/connectivity/conninfra/debug_utility/coredump +endif + +ifneq ($(CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH),) +ccflags-y += -DCONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH +ccflags-y += -I$(srctree)/drivers/misc/mediatek/connectivity/common/debug_utility +endif + +ifeq ($(CONFIG_MTK_CONN_LTE_IDC_SUPPORT),y) + ccflags-y += -DWMT_IDC_SUPPORT=1 +else + ccflags-y += -DWMT_IDC_SUPPORT=0 +endif + +ifeq ($(ADAPTOR_OPTS),CONNAC2X2_SOC3_0) +ccflags-y += -DCFG_ANDORID_CONNINFRA_SUPPORT=1 +ccflags-y += -DCFG_ANDORID_CONNINFRA_COREDUMP_SUPPORT=1 +else +ccflags-y += -DCFG_ANDORID_CONNINFRA_SUPPORT=0 +ccflags-y += -DCFG_ANDORID_CONNINFRA_COREDUMP_SUPPORT=0 +endif + +ccflags-y += -D MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT + +ccflags-y += -D CREATE_NODE_DYNAMIC=1 + +MODULE_NAME := wmt_chrdev_wifi +ifeq ($(CONFIG_WLAN_DRV_BUILD_IN),y) +$(warning $(MODULE_NAME) build-in boot.img) +obj-y += $(MODULE_NAME).o +else +$(warning $(MODULE_NAME) is kernel module) +obj-m += $(MODULE_NAME).o +endif + +# Wi-Fi character device driver +$(MODULE_NAME)-objs += wmt_cdev_wifi.o +ifneq ($(CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH),) +$(MODULE_NAME)-objs += fw_log_wifi.o +endif +ifeq ($(ADAPTOR_OPTS),CONNAC2X2_SOC3_0) +$(MODULE_NAME)-objs += wifi_pwr_on.o +endif diff --git a/drivers/misc/mediatek/connectivity/wlan/adaptor/fw_log_wifi.c b/drivers/misc/mediatek/connectivity/wlan/adaptor/fw_log_wifi.c new file mode 100644 index 0000000000000000000000000000000000000000..d5318b05340482ca9c29a9eb7eff7c0f8ea21e90 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/adaptor/fw_log_wifi.c @@ -0,0 +1,392 @@ +/* +* Copyright (C) 2016 MediaTek Inc. +* +* This program is free software: you can redistribute it and/or modify it under the terms of the +* GNU General Public License version 2 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. +* +* You should have received a copy of the GNU General Public License along with this program. +* If not, see . +*/ + +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wmt_exp.h" +#include "stp_exp.h" +#include "connsys_debug_utility.h" + +#if (CFG_ANDORID_CONNINFRA_SUPPORT == 1) +#include "fw_log_wifi.h" +#include "conninfra.h" +#endif + +MODULE_LICENSE("Dual BSD/GPL"); + +#define PFX "[WIFI-FW] " +#define WIFI_FW_LOG_DBG 3 +#define WIFI_FW_LOG_INFO 2 +#define WIFI_FW_LOG_WARN 1 +#define WIFI_FW_LOG_ERR 0 + +uint32_t fwDbgLevel = WIFI_FW_LOG_DBG; + +#define WIFI_DBG_FUNC(fmt, arg...) \ + do { \ + if (fwDbgLevel >= WIFI_FW_LOG_DBG) \ + pr_info(PFX "%s[D]: " fmt, __func__, ##arg); \ + } while (0) +#define WIFI_INFO_FUNC(fmt, arg...) \ + do { \ + if (fwDbgLevel >= WIFI_FW_LOG_INFO) \ + pr_info(PFX "%s[I]: " fmt, __func__, ##arg); \ + } while (0) +#define WIFI_INFO_FUNC_LIMITED(fmt, arg...) \ + do { \ + if (fwDbgLevel >= WIFI_FW_LOG_INFO) \ + pr_info_ratelimited(PFX "%s[L]: " fmt, __func__, ##arg); \ + } while (0) +#define WIFI_WARN_FUNC(fmt, arg...) \ + do { \ + if (fwDbgLevel >= WIFI_FW_LOG_WARN) \ + pr_info(PFX "%s[W]: " fmt, __func__, ##arg); \ + } while (0) +#define WIFI_ERR_FUNC(fmt, arg...) \ + do { \ + if (fwDbgLevel >= WIFI_FW_LOG_ERR) \ + pr_info(PFX "%s[E]: " fmt, __func__, ##arg); \ + } while (0) + + +#define WIFI_FW_LOG_IOC_MAGIC (0xfc) +#define WIFI_FW_LOG_IOCTL_ON_OFF _IOW(WIFI_FW_LOG_IOC_MAGIC, 0, int) +#define WIFI_FW_LOG_IOCTL_SET_LEVEL _IOW(WIFI_FW_LOG_IOC_MAGIC, 1, int) + +#define WIFI_FW_LOG_CMD_ON_OFF 0 +#define WIFI_FW_LOG_CMD_SET_LEVEL 1 + +#if (CFG_ANDORID_CONNINFRA_SUPPORT == 1) +#define CONNLOG_TYPE_WIFI 0 /* CONN_DEBUG_TYPE_WIFI */ +#endif + +typedef void (*wifi_fwlog_event_func_cb)(int, int); +wifi_fwlog_event_func_cb pfFwEventFuncCB; +static wait_queue_head_t wq; + +#if (CFG_ANDORID_CONNINFRA_SUPPORT == 1) +typedef int (*wifi_fwlog_chkbushang_func_cb)(void *, uint8_t); +wifi_fwlog_chkbushang_func_cb gpfn_check_bus_hang; +#endif + +static struct semaphore ioctl_mtx; + +#if (CFG_ANDORID_CONNINFRA_SUPPORT == 1) +#if (CFG_ANDORID_CONNINFRA_COREDUMP_SUPPORT == 1) +struct connsys_dump_ctx *g_wifi_coredump_handler; +struct coredump_event_cb g_wifi_coredump_cb = { + .reg_readable = fw_log_reg_readable, + .poll_cpupcr = NULL, +}; +#endif /* CFG_ANDORID_CONNINFRA_COREDUMP_SUPPORT */ +#endif /* CFG_ANDORID_CONNINFRA_SUPPORT */ + +void wifi_fwlog_event_func_register(wifi_fwlog_event_func_cb func) +{ + WIFI_INFO_FUNC("wifi_fwlog_event_func_register %p\n", func); + pfFwEventFuncCB = func; +} +EXPORT_SYMBOL(wifi_fwlog_event_func_register); + +int wifi_fwlog_onoff_status(void) +{ + int ret = 88; + return ret; +} +EXPORT_SYMBOL(wifi_fwlog_onoff_status); + +static int fw_log_wifi_open(struct inode *inode, struct file *file) +{ + WIFI_INFO_FUNC("major %d minor %d (pid %d)\n", imajor(inode), iminor(inode), current->pid); + + return 0; +} + +static int fw_log_wifi_release(struct inode *inode, struct file *file) +{ + WIFI_INFO_FUNC("major %d minor %d (pid %d)\n", imajor(inode), iminor(inode), current->pid); + + return 0; +} + +static ssize_t fw_log_wifi_read(struct file *filp, char __user *buf, size_t len, loff_t *off) +{ + size_t ret = 0; + + WIFI_INFO_FUNC_LIMITED("fw_log_wifi_read len --> %d\n", (uint32_t) len); + + ret = connsys_log_read_to_user(CONNLOG_TYPE_WIFI, buf, len); + + return ret; +} + +static unsigned int fw_log_wifi_poll(struct file *filp, poll_table *wait) +{ + poll_wait(filp, &wq, wait); + + if (connsys_log_get_buf_size(CONNLOG_TYPE_WIFI) > 0) + return POLLIN|POLLRDNORM; + return 0; +} + + +static long fw_log_wifi_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + int ret = 0; + + down(&ioctl_mtx); + switch (cmd) { + case WIFI_FW_LOG_IOCTL_ON_OFF:{ + unsigned int log_on_off = (unsigned int) arg; + + WIFI_INFO_FUNC("fw_log_wifi_unlocked_ioctl WIFI_FW_LOG_IOCTL_ON_OFF start\n"); + + if (pfFwEventFuncCB) { + WIFI_INFO_FUNC("WIFI_FW_LOG_IOCTL_ON_OFF invoke:%d\n", (int)log_on_off); + pfFwEventFuncCB(WIFI_FW_LOG_CMD_ON_OFF, log_on_off); + } + + WIFI_INFO_FUNC("fw_log_wifi_unlocked_ioctl WIFI_FW_LOG_IOCTL_ON_OFF end\n"); + break; + } + case WIFI_FW_LOG_IOCTL_SET_LEVEL:{ + unsigned int log_level = (unsigned int) arg; + + WIFI_INFO_FUNC("fw_log_wifi_unlocked_ioctl WIFI_FW_LOG_IOCTL_SET_LEVEL start\n"); + + if (pfFwEventFuncCB) { + WIFI_INFO_FUNC("WIFI_FW_LOG_IOCTL_SET_LEVEL invoke:%d\n", (int)log_level); + pfFwEventFuncCB(WIFI_FW_LOG_CMD_SET_LEVEL, log_level); + } + + WIFI_INFO_FUNC("fw_log_wifi_unlocked_ioctl WIFI_FW_LOG_IOCTL_SET_LEVEL end\n"); + break; + } + default: + ret = -EPERM; + } + WIFI_INFO_FUNC("fw_log_wifi_unlocked_ioctl cmd --> %d, ret=%d\n", cmd, ret); + up(&ioctl_mtx); + return ret; +} + + +#if (CFG_ANDORID_CONNINFRA_SUPPORT == 1) +int fw_log_wifi_irq_handler(void) +{ + return connsys_log_irq_handler(CONN_DEBUG_TYPE_WIFI); +} +EXPORT_SYMBOL(fw_log_wifi_irq_handler); + +#if (CFG_ANDORID_CONNINFRA_COREDUMP_SUPPORT == 1) + +void fw_log_bug_hang_register(void *func) +{ + WIFI_INFO_FUNC("fw_log_bug_hang_register: %p\n", func); + gpfn_check_bus_hang = (wifi_fwlog_chkbushang_func_cb)func; +} +EXPORT_SYMBOL(fw_log_bug_hang_register); + +int fw_log_reg_readable(void) +{ + int ret = 1; + + if (conninfra_reg_readable() == 0) { + WIFI_INFO_FUNC("conninfra_reg_readable: 0\n"); + ret = 0; + } + + if (gpfn_check_bus_hang) { + if (gpfn_check_bus_hang(NULL, 0) != 0) { + WIFI_INFO_FUNC("gpfn_check_bus_hang: 1\n"); + ret = 0; + } + } + + WIFI_INFO_FUNC("fw_log_reg_readable: %d\n", ret); + + return ret; +} + +void fw_log_connsys_coredump_init(void) +{ + g_wifi_coredump_handler = connsys_coredump_init(CONN_DEBUG_TYPE_WIFI, &g_wifi_coredump_cb); + if (g_wifi_coredump_handler == NULL) + WIFI_INFO_FUNC("connsys_coredump_init init fail!\n"); +} +EXPORT_SYMBOL(fw_log_connsys_coredump_init); + +void fw_log_connsys_coredump_deinit(void) +{ + connsys_coredump_deinit(g_wifi_coredump_handler); +} +EXPORT_SYMBOL(fw_log_connsys_coredump_deinit); + +void fw_log_connsys_coredump_start(unsigned int drv, char *reason) +{ + connsys_coredump_start(g_wifi_coredump_handler, 0, (enum consys_drv_type)drv, reason); + connsys_coredump_clean(g_wifi_coredump_handler); +} +EXPORT_SYMBOL(fw_log_connsys_coredump_start); +#endif /* CFG_ANDORID_CONNINFRA_COREDUMP_SUPPORT */ +#endif /* CFG_ANDORID_CONNINFRA_SUPPORT */ + +#ifdef CONFIG_COMPAT +static long fw_log_wifi_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + long ret = 0; + + WIFI_INFO_FUNC("COMPAT fw_log_wifi_compact_ioctl cmd --> %d\n", cmd); + + if (!filp->f_op || !filp->f_op->unlocked_ioctl) + return -ENOTTY; + + fw_log_wifi_unlocked_ioctl(filp, cmd, arg); + return ret; +} +#endif + +const struct file_operations fw_log_wifi_fops = { + .open = fw_log_wifi_open, + .release = fw_log_wifi_release, + .read = fw_log_wifi_read, + .poll = fw_log_wifi_poll, + .unlocked_ioctl = fw_log_wifi_unlocked_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = fw_log_wifi_compat_ioctl, +#endif +}; + +struct fw_log_wifi_device { + struct cdev cdev; + dev_t devno; + struct class *driver_class; + struct device *class_dev; +}; + +#define FW_LOG_WIFI_DRIVER_NAME "fw_log_wifi" +static struct fw_log_wifi_device *fw_log_wifi_dev; +static int fw_log_wifi_major; + +static void fw_log_wifi_event_cb(void) +{ + wake_up_interruptible(&wq); +} + +int fw_log_wifi_init(void) +{ + int result = 0; + int err = 0; + + fw_log_wifi_dev = kmalloc(sizeof(struct fw_log_wifi_device), GFP_KERNEL); + + if (fw_log_wifi_dev == NULL) { + result = -ENOMEM; + goto return_fn; + } + + fw_log_wifi_dev->devno = MKDEV(fw_log_wifi_major, 0); + + result = alloc_chrdev_region(&fw_log_wifi_dev->devno, 0, 1, FW_LOG_WIFI_DRIVER_NAME); + fw_log_wifi_major = MAJOR(fw_log_wifi_dev->devno); + WIFI_INFO_FUNC("alloc_chrdev_region result %d, major %d\n", result, fw_log_wifi_major); + + if (result < 0) + return result; + + fw_log_wifi_dev->driver_class = class_create(THIS_MODULE, FW_LOG_WIFI_DRIVER_NAME); + + if (IS_ERR(fw_log_wifi_dev->driver_class)) { + result = -ENOMEM; + WIFI_ERR_FUNC("class_create failed %d.\n", result); + goto unregister_chrdev_region; + } + + fw_log_wifi_dev->class_dev = device_create(fw_log_wifi_dev->driver_class, + NULL, fw_log_wifi_dev->devno, NULL, FW_LOG_WIFI_DRIVER_NAME); + + if (!fw_log_wifi_dev->class_dev) { + result = -ENOMEM; + WIFI_ERR_FUNC("class_device_create failed %d.\n", result); + goto class_destroy; + } + + cdev_init(&fw_log_wifi_dev->cdev, &fw_log_wifi_fops); + + fw_log_wifi_dev->cdev.owner = THIS_MODULE; + fw_log_wifi_dev->cdev.ops = &fw_log_wifi_fops; + + err = cdev_add(&fw_log_wifi_dev->cdev, fw_log_wifi_dev->devno, 1); + if (err) { + result = -ENOMEM; + WIFI_ERR_FUNC("Error %d adding fw_log_wifi dev.\n", err); + goto cdev_del; + } + + /* integrated with common debug utility */ + init_waitqueue_head(&wq); + connsys_log_init(CONNLOG_TYPE_WIFI); + connsys_log_register_event_cb(CONNLOG_TYPE_WIFI, fw_log_wifi_event_cb); + sema_init(&ioctl_mtx, 1); + pfFwEventFuncCB = NULL; +#if (CFG_ANDORID_CONNINFRA_COREDUMP_SUPPORT == 1) + gpfn_check_bus_hang = NULL; +#endif + goto return_fn; + +cdev_del: + cdev_del(&fw_log_wifi_dev->cdev); +class_destroy: + class_destroy(fw_log_wifi_dev->driver_class); +unregister_chrdev_region: + unregister_chrdev_region(fw_log_wifi_dev->devno, 1); + kfree(fw_log_wifi_dev); +return_fn: + return result; +} +EXPORT_SYMBOL(fw_log_wifi_init); + +int fw_log_wifi_deinit(void) +{ + device_destroy(fw_log_wifi_dev->driver_class, fw_log_wifi_dev->devno); + class_destroy(fw_log_wifi_dev->driver_class); + cdev_del(&fw_log_wifi_dev->cdev); + kfree(fw_log_wifi_dev); + unregister_chrdev_region(MKDEV(fw_log_wifi_major, 0), 1); + WIFI_INFO_FUNC("unregister_chrdev_region major %d\n", fw_log_wifi_major); + + /* integrated with common debug utility */ + connsys_log_deinit(CONNLOG_TYPE_WIFI); + return 0; +} +EXPORT_SYMBOL(fw_log_wifi_deinit); + +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/adaptor/fw_log_wifi.h b/drivers/misc/mediatek/connectivity/wlan/adaptor/fw_log_wifi.h new file mode 100644 index 0000000000000000000000000000000000000000..c8776f12e1ae83294bff14f48f8090a2d9b83613 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/adaptor/fw_log_wifi.h @@ -0,0 +1,34 @@ +/* +* Copyright (C) 2016 MediaTek Inc. +* +* This program is free software: you can redistribute it and/or modify it under the terms of the +* GNU General Public License version 2 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. +* +* You should have received a copy of the GNU General Public License along with this program. +* If not, see . +*/ + +#ifndef _FW_LOG_WIFI_H_ +#define _FW_LOG_WIFI_H_ + +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH +int fw_log_wifi_init(void); +int fw_log_wifi_deinit(void); +#endif /* CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH */ + +#if (CFG_ANDORID_CONNINFRA_SUPPORT == 1) +int fw_log_wifi_irq_handler(void); +#endif /* CFG_ANDORID_CONNINFRA_SUPPORT */ + +#if (CFG_ANDORID_CONNINFRA_COREDUMP_SUPPORT == 1) +void fw_log_connsys_coredump_init(void); +void fw_log_connsys_coredump_deinit(void); +void fw_log_connsys_coredump_start(unsigned int, char *); +int fw_log_reg_readable(void); +#endif + +#endif /*_FW_LOG_WIFI_H_*/ diff --git a/drivers/misc/mediatek/connectivity/wlan/adaptor/init.wlan_drv.rc b/drivers/misc/mediatek/connectivity/wlan/adaptor/init.wlan_drv.rc new file mode 100644 index 0000000000000000000000000000000000000000..b880d95df6046f87eaa4fca4a9b0500cfc3b13fe --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/adaptor/init.wlan_drv.rc @@ -0,0 +1,6 @@ + +# load wifi driver after wmt_loader finish +on property:vendor.connsys.driver.ready=yes + insmod /vendor/lib/modules/wmt_chrdev_wifi.ko + insmod /vendor/lib/modules/wlan_drv_${ro.vendor.wlan.gen}.ko + start wlan_assistant diff --git a/drivers/misc/mediatek/connectivity/wlan/adaptor/wifi_pwr_on.c b/drivers/misc/mediatek/connectivity/wlan/adaptor/wifi_pwr_on.c new file mode 100644 index 0000000000000000000000000000000000000000..5ed423f6a45d920abd8591afb4dc23ed573a1c1a --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/adaptor/wifi_pwr_on.c @@ -0,0 +1,229 @@ + +/* +* Copyright (C) 2019 MediaTek Inc. +* +* This program is free software: you can redistribute it and/or modify it under the terms of the +* GNU General Public License version 2 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. +* +* You should have received a copy of the GNU General Public License along with this program. +* If not, see . +*/ + + +#include +#include +#include +#include +#include +#include +#include "wifi_pwr_on.h" + + + + + +MODULE_LICENSE("Dual BSD/GPL"); + +#define PFX "[WIFI-FW] " +#define WIFI_FW_LOG_DBG 3 +#define WIFI_FW_LOG_INFO 2 +#define WIFI_FW_LOG_WARN 1 +#define WIFI_FW_LOG_ERR 0 + +uint32_t DbgLevel = WIFI_FW_LOG_INFO; + +#define WIFI_DBG_FUNC(fmt, arg...) \ + do { \ + if (DbgLevel >= WIFI_FW_LOG_DBG) \ + pr_info(PFX "%s[D]: " fmt, __func__, ##arg); \ + } while (0) +#define WIFI_INFO_FUNC(fmt, arg...) \ + do { \ + if (DbgLevel >= WIFI_FW_LOG_INFO) \ + pr_info(PFX "%s[I]: " fmt, __func__, ##arg); \ + } while (0) +#define WIFI_INFO_FUNC_LIMITED(fmt, arg...) \ + do { \ + if (DbgLevel >= WIFI_FW_LOG_INFO) \ + pr_info_ratelimited(PFX "%s[L]: " fmt, __func__, ##arg); \ + } while (0) +#define WIFI_WARN_FUNC(fmt, arg...) \ + do { \ + if (DbgLevel >= WIFI_FW_LOG_WARN) \ + pr_info(PFX "%s[W]: " fmt, __func__, ##arg); \ + } while (0) +#define WIFI_ERR_FUNC(fmt, arg...) \ + do { \ + if (DbgLevel >= WIFI_FW_LOG_ERR) \ + pr_info(PFX "%s[E]: " fmt, __func__, ##arg); \ + } while (0) + + +wlan_probe_cb mtk_wlan_probe_function; +wlan_remove_cb mtk_wlan_remove_function; + + +struct completion wlan_pendComp; + +int g_data; + +wait_queue_head_t g_waitq_onoff; +unsigned long g_ulOnoffFlag; +bool g_fgIsWiFiOn; +struct task_struct *wland_thread; + +static int mtk_wland_thread_main(void *data); + +int wifi_pwr_on_init(void) +{ + int result = 0; + + init_completion(&wlan_pendComp); + init_waitqueue_head(&g_waitq_onoff); + + wland_thread = kthread_run(mtk_wland_thread_main, + NULL, "mtk_wland_thread"); + WIFI_INFO_FUNC("Do wifi_pwr_on_init.\n"); + return result; +} +EXPORT_SYMBOL(wifi_pwr_on_init); + +int wifi_pwr_on_deinit(void) +{ + WIFI_INFO_FUNC("Do wifi_pwr_on_deinit.\n"); + set_bit(ADAPTOR_FLAG_HALT_BIT, &g_ulOnoffFlag); + wake_up_interruptible(&g_waitq_onoff); + return 0; +} +EXPORT_SYMBOL(wifi_pwr_on_deinit); +int mtk_wcn_wlan_reg(struct MTK_WCN_WLAN_CB_INFO *pWlanCbInfo) +{ + if (!pWlanCbInfo) { + WIFI_ERR_FUNC("wlan cb info in null!\n"); + return -1; + } + WIFI_INFO_FUNC("wmt wlan cb register\n"); + mtk_wlan_probe_function = pWlanCbInfo->wlan_probe_cb; + mtk_wlan_remove_function = pWlanCbInfo->wlan_remove_cb; + + return 0; +} +EXPORT_SYMBOL(mtk_wcn_wlan_reg); + +int mtk_wcn_wlan_unreg(void) +{ + WIFI_INFO_FUNC("wmt wlan cb unregister\n"); + mtk_wlan_probe_function = NULL; + mtk_wlan_remove_function = NULL; + + return 0; +} +EXPORT_SYMBOL(mtk_wcn_wlan_unreg); + +void kalSetOnoffEvent(enum ENUM_WLAN_OPID opId) +{ + + if (opId == WLAN_OPID_FUNC_ON) + set_bit(ADAPTOR_FLAG_ON_BIT, &g_ulOnoffFlag); + else if (opId == WLAN_OPID_FUNC_OFF) + set_bit(ADAPTOR_FLAG_OFF_BIT, &g_ulOnoffFlag); + else { + WIFI_ERR_FUNC("Invalid OPID\n"); + return; + } + /* when we got event, we wake up servie thread */ + wake_up_interruptible(&g_waitq_onoff); +} + + +int mtk_wland_thread_main(void *data) +{ + int ret = 0; + + WIFI_INFO_FUNC("%s:%u starts running...\n", + current->comm, current->pid); + while (1) { + + /* + * sleep on waitqueue if no events occurred. Event contain + * (1) ADAPTOR_FLAG_HALT (2) ADAPTOR_FLAG_ON + * (3) ADAPTOR_FLAG_OFF + */ + do { + ret = wait_event_interruptible(g_waitq_onoff, + ((g_ulOnoffFlag & ADAPTOR_FLAG_ON_OFF_PROCESS) + != 0)); + } while (ret != 0); + + if (test_and_clear_bit(ADAPTOR_FLAG_HALT_BIT, &g_ulOnoffFlag)) { + WIFI_INFO_FUNC("mtk_wland_thread should stop now...\n"); + break; + } + + if (test_and_clear_bit(ADAPTOR_FLAG_ON_BIT, &g_ulOnoffFlag)) { + if (!g_fgIsWiFiOn) { + if (mtk_wlan_probe_function != NULL) { + while (get_pre_cal_status() == 1) { + WIFI_DBG_FUNC("Precal is ongoing.\n"); + msleep(300); + } + g_data = (*mtk_wlan_probe_function)(); + if (g_data == 0) + g_fgIsWiFiOn = MTK_WCN_BOOL_TRUE; + } else { + g_data = ADAPTOR_INVALID_POINTER; + WIFI_ERR_FUNC("Invalid pointer\n"); + } + } else { + WIFI_ERR_FUNC("Wi-Fi is already on\n"); + } + } else if (test_and_clear_bit(ADAPTOR_FLAG_OFF_BIT, &g_ulOnoffFlag)) { + if (g_fgIsWiFiOn) { + if (mtk_wlan_remove_function != NULL) { + g_data = (*mtk_wlan_remove_function)(); + if (g_data == 0) + g_fgIsWiFiOn = MTK_WCN_BOOL_FALSE; + } else { + g_data = ADAPTOR_INVALID_POINTER; + WIFI_ERR_FUNC("Invalid pointer\n"); + } + } else { + WIFI_ERR_FUNC("Wi-Fi is already off\n"); + } + } + complete(&wlan_pendComp); + } + + WIFI_INFO_FUNC("%s:%u stopped!\n", current->comm, current->pid); + + return 0; +} + +int mtk_wcn_wlan_func_ctrl(enum ENUM_WLAN_OPID opId) +{ + bool bRet = MTK_WCN_BOOL_TRUE; + uint32_t waitRet = 0; + reinit_completion(&wlan_pendComp); + + kalSetOnoffEvent(opId); + waitRet = wait_for_completion_timeout(&wlan_pendComp, MSEC_TO_JIFFIES(WIFI_PWR_ON_TIMEOUT)); + if (waitRet > 0) { + /* Case 1: No timeout. */ + if (g_data != 0) + bRet = MTK_WCN_BOOL_FALSE; + } else { + /* Case 2: timeout */ + WIFI_ERR_FUNC("WiFi on/off takes more than %d seconds\n", WIFI_PWR_ON_TIMEOUT/1000); + bRet = MTK_WCN_BOOL_FALSE; + } + return bRet; +} +EXPORT_SYMBOL(mtk_wcn_wlan_func_ctrl); + + + + diff --git a/drivers/misc/mediatek/connectivity/wlan/adaptor/wifi_pwr_on.h b/drivers/misc/mediatek/connectivity/wlan/adaptor/wifi_pwr_on.h new file mode 100644 index 0000000000000000000000000000000000000000..76f479d920ad4a12548c7bac998e0c6c259ab410 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/adaptor/wifi_pwr_on.h @@ -0,0 +1,66 @@ +/* +* Copyright (C) 2019 MediaTek Inc. +* +* This program is free software: you can redistribute it and/or modify it under the terms of the +* GNU General Public License version 2 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. +* +* You should have received a copy of the GNU General Public License along with this program. +* If not, see . +*/ + +#ifndef _WIFI_PWR_ON_H_ +#define _WIFI_PWR_ON_H_ + +int wifi_pwr_on_init(void); +int wifi_pwr_on_deinit(void); + +typedef int(*wlan_probe_cb) (void); +typedef int(*wlan_remove_cb) (void); + + +struct MTK_WCN_WLAN_CB_INFO { + wlan_probe_cb wlan_probe_cb; + wlan_remove_cb wlan_remove_cb; +}; +extern int mtk_wcn_wlan_reg(struct MTK_WCN_WLAN_CB_INFO *pWlanCbInfo); + +extern uint8_t get_pre_cal_status(void); + +enum ENUM_WLAN_OPID { + WLAN_OPID_FUNC_ON = 0, + WLAN_OPID_FUNC_OFF = 1, + WLAN_OPID_MAX +}; +extern int mtk_wcn_wlan_func_ctrl(enum ENUM_WLAN_OPID opId); + +extern wlan_probe_cb mtk_wlan_probe_function; +extern wlan_remove_cb mtk_wlan_remove_function; + +extern bool g_fgIsWiFiOn; + +#ifndef MTK_WCN_BOOL_TRUE +#define MTK_WCN_BOOL_FALSE ((int) 0) +#define MTK_WCN_BOOL_TRUE ((int) 1) +#endif + +#define MSEC_TO_JIFFIES(_msec) msecs_to_jiffies(_msec) + +#define WIFI_PWR_ON_TIMEOUT 10000 + +#define ADAPTOR_FLAG_HALT BIT(0) +#define ADAPTOR_FLAG_ON BIT(1) +#define ADAPTOR_FLAG_OFF BIT(2) + +#define ADAPTOR_FLAG_HALT_BIT (0) +#define ADAPTOR_FLAG_ON_BIT (1) +#define ADAPTOR_FLAG_OFF_BIT (2) + +#define ADAPTOR_FLAG_ON_OFF_PROCESS (ADAPTOR_FLAG_HALT |\ + ADAPTOR_FLAG_ON |\ + ADAPTOR_FLAG_OFF) +#define ADAPTOR_INVALID_POINTER 0xdeaddead +#endif /*_WIFI_PWR_ON_H_*/ diff --git a/drivers/misc/mediatek/connectivity/wlan/adaptor/wmt_cdev_wifi.c b/drivers/misc/mediatek/connectivity/wlan/adaptor/wmt_cdev_wifi.c new file mode 100644 index 0000000000000000000000000000000000000000..f3418326076c8a7a7ad02da00a6085e9e4deed86 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/adaptor/wmt_cdev_wifi.c @@ -0,0 +1,818 @@ +/* +* Copyright (C) 2016 MediaTek Inc. +* +* This program is free software: you can redistribute it and/or modify it under the terms of the +* GNU General Public License version 2 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. +* +* You should have received a copy of the GNU General Public License along with this program. +* If not, see . +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "fw_log_wifi.h" +#if (CFG_ANDORID_CONNINFRA_SUPPORT == 1) +#include "wifi_pwr_on.h" +#else +#include "wmt_exp.h" +#include "stp_exp.h" +#endif +MODULE_LICENSE("Dual BSD/GPL"); + +#define WIFI_DRIVER_NAME "mtk_wmt_wifi_chrdev" +#define WIFI_DEV_MAJOR 0 + +#define PFX "[MTK-WIFI] " +#define WIFI_LOG_DBG 3 +#define WIFI_LOG_INFO 2 +#define WIFI_LOG_WARN 1 +#define WIFI_LOG_ERR 0 + +uint32_t gDbgLevel = WIFI_LOG_DBG; + +#define WIFI_DBG_FUNC(fmt, arg...) \ + do { \ + if (gDbgLevel >= WIFI_LOG_DBG) \ + pr_info(PFX "%s[D]: " fmt, __func__, ##arg); \ + } while (0) +#define WIFI_INFO_FUNC(fmt, arg...) \ + do { \ + if (gDbgLevel >= WIFI_LOG_INFO) \ + pr_info(PFX "%s[I]: " fmt, __func__, ##arg); \ + } while (0) +#define WIFI_INFO_FUNC_LIMITED(fmt, arg...) \ + do { \ + if (gDbgLevel >= WIFI_LOG_INFO) \ + pr_info_ratelimited(PFX "%s[L]: " fmt, __func__, ##arg); \ + } while (0) +#define WIFI_WARN_FUNC(fmt, arg...) \ + do { \ + if (gDbgLevel >= WIFI_LOG_WARN) \ + pr_info(PFX "%s[W]: " fmt, __func__, ##arg); \ + } while (0) +#define WIFI_ERR_FUNC(fmt, arg...) \ + do { \ + if (gDbgLevel >= WIFI_LOG_ERR) \ + pr_info(PFX "%s[E]: " fmt, __func__, ##arg); \ + } while (0) + +#define VERSION "2.0" + +static int32_t WIFI_devs = 1; +static int32_t WIFI_major = WIFI_DEV_MAJOR; +static dev_t wifi_devno; +module_param(WIFI_major, uint, 0); +static struct cdev WIFI_cdev; +#if CREATE_NODE_DYNAMIC +static struct class *wmtwifi_class; +static struct device *wmtwifi_dev; +#endif + +static struct semaphore wr_mtx; + +#define WLAN_IFACE_NAME "wlan0" + +enum { + WLAN_MODE_HALT, + WLAN_MODE_AP, + WLAN_MODE_STA_P2P, + WLAN_MODE_STA_AP_P2P, + WLAN_MODE_MAX +}; +static int32_t wlan_mode = WLAN_MODE_HALT; +static int32_t powered; +static int32_t isconcurrent; +static char *ifname = WLAN_IFACE_NAME; +static uint32_t driver_loaded; +static int32_t low_latency_mode; +#if (CFG_ANDORID_CONNINFRA_SUPPORT == 1) +static uint8_t driver_resetting; +static uint8_t write_processing; +static uint8_t pre_cal_ongoing; +#endif +/******************************************************************* + */ +enum ENUM_RESET_STATUS { + RESET_FAIL, + RESET_SUCCESS +}; + +/* + * enable = 1, mode = 0 => init P2P network + * enable = 1, mode = 1 => init Soft AP network + * enable = 0 => uninit P2P/AP network + */ +struct PARAM_CUSTOM_P2P_SET_STRUCT { + uint32_t u4Enable; + uint32_t u4Mode; +}; +typedef int32_t(*set_p2p_mode) (struct net_device *netdev, struct PARAM_CUSTOM_P2P_SET_STRUCT p2pmode); + +static set_p2p_mode pf_set_p2p_mode; +void register_set_p2p_mode_handler(set_p2p_mode handler) +{ + WIFI_INFO_FUNC("(pid %d) register set p2p mode handler %p\n", current->pid, handler); + pf_set_p2p_mode = handler; +} +EXPORT_SYMBOL(register_set_p2p_mode_handler); + +void update_driver_loaded_status(uint8_t loaded) +{ + WIFI_INFO_FUNC("update_driver_loaded_status: %d\n", loaded); + driver_loaded = loaded; +} +EXPORT_SYMBOL(update_driver_loaded_status); + +static int atoh(const char *str, uint32_t *hval) +{ + unsigned int i; + uint32_t val = 0; + + WIFI_INFO_FUNC("*str : %s, len = %zu\n", str, + strlen((const char *)str)); + for (i = 0; i < strlen((const char *)str); i++) { + if (str[i] >= 'a' && str[i] <= 'f') + val = (val << 4) + (str[i] - 'a' + 10); + else if (str[i] >= 'A' && str[i] <= 'F') + val = (val << 4) + (str[i] - 'A' + 10); + else if (*(str + i) >= '0' && *(str + i) <= '9') + val = (val << 4) + (*(str + i) - '0'); + } + + *hval = val; + + return 0; +} + +void set_low_latency_mode(const char *mode) +{ + atoh(mode, &low_latency_mode); + WIFI_INFO_FUNC("LLM : %d\n", low_latency_mode); +} + +uint32_t get_low_latency_mode(void) +{ + WIFI_INFO_FUNC("LLM : %d\n", low_latency_mode); + return low_latency_mode; +} +EXPORT_SYMBOL(get_low_latency_mode); + +#if (CFG_ANDORID_CONNINFRA_SUPPORT == 1) +void update_driver_reset_status(uint8_t fgIsResetting) +{ + WIFI_INFO_FUNC("update_driver_reset_status: %d\n", fgIsResetting); + driver_resetting = fgIsResetting; +} +EXPORT_SYMBOL(update_driver_reset_status); +int32_t get_wifi_powered_status(void) +{ + WIFI_INFO_FUNC("wifi power status : %d\n", powered); + return powered; +} +EXPORT_SYMBOL(get_wifi_powered_status); +int32_t get_wifi_process_status(void) +{ + WIFI_INFO_FUNC("wifi write status: %d\n", write_processing); + return write_processing; +} +EXPORT_SYMBOL(get_wifi_process_status); +void update_pre_cal_status(uint8_t fgIsPreCal) +{ + WIFI_INFO_FUNC("update_pre_cal_status: %d\n", fgIsPreCal); + pre_cal_ongoing = fgIsPreCal; +} +EXPORT_SYMBOL(update_pre_cal_status); +uint8_t get_pre_cal_status(void) +{ + WIFI_INFO_FUNC("pre cal status: %d\n", pre_cal_ongoing); + return pre_cal_ongoing; +} +EXPORT_SYMBOL(get_pre_cal_status); +#endif + +enum ENUM_WLAN_DRV_BUF_TYPE_T { + BUF_TYPE_NVRAM, + BUF_TYPE_DRV_CFG, + BUF_TYPE_FW_CFG, + BUF_TYPE_NUM +}; + +typedef uint8_t(*file_buf_handler)(void *ctx, const char __user *buf, uint16_t length); +static file_buf_handler buf_handler[BUF_TYPE_NUM]; +static void *buf_handler_ctx[BUF_TYPE_NUM]; +void register_file_buf_handler(file_buf_handler handler, void *handler_ctx, uint8_t ucType) +{ + if (ucType < BUF_TYPE_NUM) { + buf_handler[ucType] = handler; + buf_handler_ctx[ucType] = handler_ctx; + } +} +EXPORT_SYMBOL(register_file_buf_handler); + +/******************************************************************* + * WHOLE CHIP RESET PROCEDURE: + * + * WMTRSTMSG_RESET_START callback + * -> wlanRemove + * -> WMTRSTMSG_RESET_END callback + * + ******************************************************************* +*/ +/*-----------------------------------------------------------------*/ +/* + * Receiving RESET_START message + */ +/*-----------------------------------------------------------------*/ +int32_t wifi_reset_start(void) +{ + struct net_device *netdev = NULL; + struct PARAM_CUSTOM_P2P_SET_STRUCT p2pmode; + + down(&wr_mtx); + + if (powered == 1) { + netdev = dev_get_by_name(&init_net, ifname); + if (netdev == NULL) { + WIFI_ERR_FUNC("Fail to get %s net device\n", ifname); + } else { + p2pmode.u4Enable = 0; + p2pmode.u4Mode = 0; + + if (pf_set_p2p_mode) { + if (pf_set_p2p_mode(netdev, p2pmode) != 0) + WIFI_ERR_FUNC("Turn off p2p/ap mode fail"); + else + WIFI_INFO_FUNC("Turn off p2p/ap mode"); + } + dev_put(netdev); + netdev = NULL; + } + } else { + /* WIFI is off before whole chip reset, do nothing */ + } + + return 0; +} +EXPORT_SYMBOL(wifi_reset_start); + +/*-----------------------------------------------------------------*/ +/* + * Receiving RESET_END/RESET_END_FAIL message + */ +/*-----------------------------------------------------------------*/ +int32_t wifi_reset_end(enum ENUM_RESET_STATUS status) +{ + struct net_device *netdev = NULL; + struct PARAM_CUSTOM_P2P_SET_STRUCT p2pmode; + int32_t wait_cnt = 0; + int32_t ret = -1; + + if (status == RESET_FAIL) { + /* whole chip reset fail, donot recover WIFI */ + ret = 0; + up(&wr_mtx); + } else if (status == RESET_SUCCESS) { + WIFI_WARN_FUNC("WIFI state recovering...\n"); + + if (powered == 1) { + /* WIFI is on before whole chip reset, reopen it now */ +#if (CFG_ANDORID_CONNINFRA_SUPPORT == 1) + /* + * mtk_wland_thread_main will check this flag for current state. + * if this flag is TRUE, mtk_wland_thread_main will not do power on again. + * Set this flag to FALSE to finish the reset procedure + */ + g_fgIsWiFiOn = MTK_WCN_BOOL_FALSE; + if (mtk_wcn_wlan_func_ctrl(WLAN_OPID_FUNC_ON) == MTK_WCN_BOOL_FALSE) { +#else + if (mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI) == MTK_WCN_BOOL_FALSE) { +#endif + WIFI_ERR_FUNC("WMT turn on WIFI fail!\n"); + goto done; + } else { + WIFI_INFO_FUNC("WMT turn on WIFI success!\n"); + } + + if (pf_set_p2p_mode == NULL) { + WIFI_ERR_FUNC("Set p2p mode handler is NULL\n"); + goto done; + } + + netdev = dev_get_by_name(&init_net, ifname); + wait_cnt = 0; + while (netdev == NULL && wait_cnt < 10) { + WIFI_ERR_FUNC("Fail to get %s net device, sleep 300ms\n", ifname); + msleep(300); + wait_cnt++; + netdev = dev_get_by_name(&init_net, ifname); + } + if (wait_cnt >= 10) { + WIFI_ERR_FUNC("Get %s net device timeout\n", ifname); + goto done; + } + + if (wlan_mode == WLAN_MODE_STA_P2P) { + p2pmode.u4Enable = 1; + p2pmode.u4Mode = 0; + if (pf_set_p2p_mode(netdev, p2pmode) != 0) { + WIFI_ERR_FUNC("Set wlan mode 0 fail\n"); + } else { + WIFI_WARN_FUNC("Set wlan mode %d\n", WLAN_MODE_STA_P2P); + ret = 0; + } + } else if (wlan_mode == WLAN_MODE_AP) { + p2pmode.u4Enable = 1; + p2pmode.u4Mode = 1; + if (pf_set_p2p_mode(netdev, p2pmode) != 0) { + WIFI_ERR_FUNC("Set wlan mode 1 fail\n"); + } else { + WIFI_WARN_FUNC("Set wlan mode %d\n", WLAN_MODE_AP); + ret = 0; + } + } else if (wlan_mode == WLAN_MODE_STA_AP_P2P) { + p2pmode.u4Enable = 1; + p2pmode.u4Mode = 3; + if (pf_set_p2p_mode(netdev, p2pmode) != 0) { + WIFI_ERR_FUNC("Set wlan mode 3 fail\n"); + } else { + WIFI_WARN_FUNC("Set wlan mode %d\n", WLAN_MODE_STA_AP_P2P); + ret = 0; + } + } else + ret = 0; +done: + if (netdev != NULL) + dev_put(netdev); + } else { + /* WIFI is off before whole chip reset, do nothing */ + ret = 0; + } + up(&wr_mtx); + } + + return ret; +} +EXPORT_SYMBOL(wifi_reset_end); + +static int WIFI_open(struct inode *inode, struct file *file) +{ + WIFI_INFO_FUNC("major %d minor %d (pid %d)\n", imajor(inode), iminor(inode), current->pid); + + return 0; +} + +static int WIFI_close(struct inode *inode, struct file *file) +{ + WIFI_INFO_FUNC("major %d minor %d (pid %d)\n", imajor(inode), iminor(inode), current->pid); + + return 0; +} + +ssize_t WIFI_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) +{ + int32_t retval = -EIO; + int8_t local[20] = { 0 }; + struct net_device *netdev = NULL; + struct PARAM_CUSTOM_P2P_SET_STRUCT p2pmode; + int32_t wait_cnt = 0; + int copy_size = 0; + + down(&wr_mtx); + if (count <= 0) { + WIFI_ERR_FUNC("WIFI_write invalid param\n"); + goto done; + } +#if (CFG_ANDORID_CONNINFRA_SUPPORT == 1) + if (driver_resetting == 1) { + WIFI_ERR_FUNC("Wi-Fi is resetting\n"); + goto done; + } +#endif + copy_size = min(sizeof(local) - 1, count); + if (copy_size < 0) { + WIFI_ERR_FUNC("Invalid copy_size: %d\n", copy_size); + goto done; + } + if (copy_from_user(local, buf, copy_size) == 0) { + local[copy_size] = '\0'; + WIFI_INFO_FUNC("WIFI_write %s, length %zu, copy_size %d\n", + local, count, copy_size); + + if (local[0] == '0') { +#if (CFG_ANDORID_CONNINFRA_SUPPORT == 1) + write_processing = 1; +#endif + if (powered == 0) { + WIFI_INFO_FUNC("WIFI is already power off!\n"); + retval = count; + wlan_mode = WLAN_MODE_HALT; + goto done; + } + + netdev = dev_get_by_name(&init_net, ifname); + if (netdev == NULL) { + WIFI_ERR_FUNC("Fail to get %s net device\n", ifname); + } else { + p2pmode.u4Enable = 0; + p2pmode.u4Mode = 0; + + if (pf_set_p2p_mode) { + if (pf_set_p2p_mode(netdev, p2pmode) != 0) { + WIFI_ERR_FUNC("Turn off p2p/ap mode fail"); + } else { + WIFI_INFO_FUNC("Turn off p2p/ap mode"); + wlan_mode = WLAN_MODE_HALT; + } + } + dev_put(netdev); + netdev = NULL; + } + +#if (CFG_ANDORID_CONNINFRA_SUPPORT == 1) + if (mtk_wcn_wlan_func_ctrl(WLAN_OPID_FUNC_OFF) == MTK_WCN_BOOL_FALSE) { +#else + if (mtk_wcn_wmt_func_off(WMTDRV_TYPE_WIFI) == MTK_WCN_BOOL_FALSE) { +#endif + WIFI_ERR_FUNC("WMT turn off WIFI fail!\n"); + } else { + WIFI_INFO_FUNC("WMT turn off WIFI success!\n"); + powered = 0; + retval = count; + wlan_mode = WLAN_MODE_HALT; + } + } else if (local[0] == '1') { +#if (CFG_ANDORID_CONNINFRA_SUPPORT == 1) + write_processing = 1; +#endif + if (powered == 1) { + WIFI_INFO_FUNC("WIFI is already power on!\n"); + retval = count; + goto done; + } +#if (CFG_ANDORID_CONNINFRA_SUPPORT == 1) + if (mtk_wcn_wlan_func_ctrl(WLAN_OPID_FUNC_ON) == MTK_WCN_BOOL_FALSE) { +#else + if (mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI) == MTK_WCN_BOOL_FALSE) { +#endif + WIFI_ERR_FUNC("WMT turn on WIFI fail!\n"); + } else { + powered = 1; + retval = count; + WIFI_INFO_FUNC("WMT turn on WIFI success!\n"); + wlan_mode = WLAN_MODE_HALT; + } + } else if (!strncmp(local, "WR-BUF:", 7)) { + file_buf_handler handler = NULL; + void *ctx = NULL; + + if (!strncmp(&local[7], "NVRAM", 5)) { + copy_size = count - 12; + buf += 12; + wait_cnt = 0; + while (wait_cnt < 20) { + handler = buf_handler[BUF_TYPE_NVRAM]; + ctx = buf_handler_ctx[BUF_TYPE_NVRAM]; + if (handler) + break; + msleep(100); + wait_cnt++; + } + + if (!handler) + WIFI_ERR_FUNC("Wi-Fi driver is not ready for write NVRAM\n"); + else + WIFI_INFO_FUNC("Wi-Fi handler = %p\n", handler); + } else if (!strncmp(&local[7], "DRVCFG", 6)) { + copy_size = count - 13; + buf += 13; + handler = buf_handler[BUF_TYPE_DRV_CFG]; + ctx = buf_handler_ctx[BUF_TYPE_DRV_CFG]; + } else if (!strncmp(&local[7], "FWCFG", 5)) { + copy_size = count - 12; + buf += 12; + handler = buf_handler[BUF_TYPE_FW_CFG]; + ctx = buf_handler_ctx[BUF_TYPE_FW_CFG]; + } + if (handler && !handler(ctx, buf, (uint16_t)copy_size)) + retval = count; + else + retval = -ENOTSUPP; + } else if (!strncmp(local, "RM-BUF:", 7)) { + file_buf_handler handler = NULL; + void *ctx = NULL; + + if (!strncmp(&local[7], "DRVCFG", 6)) { + handler = buf_handler[BUF_TYPE_DRV_CFG]; + ctx = buf_handler_ctx[BUF_TYPE_DRV_CFG]; + } else if (!strncmp(&local[7], "FWCFG", 5)) { + handler = buf_handler[BUF_TYPE_FW_CFG]; + ctx = buf_handler_ctx[BUF_TYPE_FW_CFG]; + } + + if (handler && !handler(ctx, NULL, 0)) + retval = count; + else + retval = -ENOTSUPP; + } else if (local[0] == 'S' || local[0] == 'P' || local[0] == 'A') { + if (powered == 1 && driver_loaded == 0) { + WIFI_INFO_FUNC("In fact wifi is already turned off! reset related states.\n"); + powered = 0; + wlan_mode = WLAN_MODE_HALT; + } + + if (powered == 0) { + /* If WIFI is off, turn on WIFI first */ +#if (CFG_ANDORID_CONNINFRA_SUPPORT == 1) + if (mtk_wcn_wlan_func_ctrl(WLAN_OPID_FUNC_ON) == MTK_WCN_BOOL_FALSE) { +#else + if (mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI) == MTK_WCN_BOOL_FALSE) { +#endif + WIFI_ERR_FUNC("WMT turn on WIFI fail!\n"); + goto done; + } else { + powered = 1; + WIFI_INFO_FUNC("WMT turn on WIFI success!\n"); + wlan_mode = WLAN_MODE_HALT; + } + } + + if (pf_set_p2p_mode == NULL) { + WIFI_ERR_FUNC("Set p2p mode handler is NULL\n"); + goto done; + } + + netdev = dev_get_by_name(&init_net, ifname); + wait_cnt = 0; + while (netdev == NULL && wait_cnt < 10) { + WIFI_ERR_FUNC("Fail to get %s net device, sleep 300ms\n", ifname); + msleep(300); + wait_cnt++; + netdev = dev_get_by_name(&init_net, ifname); + } + if (wait_cnt >= 10) { + WIFI_ERR_FUNC("Get %s net device timeout\n", ifname); + goto done; + } + + /* 1. Concurrent mode */ + if (isconcurrent) { + if (wlan_mode == WLAN_MODE_STA_AP_P2P) { + WIFI_INFO_FUNC("WIFI is already in cocurrent mode %d!\n", wlan_mode); + retval = count; + goto done; + } + p2pmode.u4Enable = 1; + p2pmode.u4Mode = 3; + if (pf_set_p2p_mode(netdev, p2pmode) != 0) { + WIFI_ERR_FUNC("Set wlan mode fail\n"); + /* Goto Non-concurrent mode */ + } else { + WIFI_INFO_FUNC("Set wlan mode %d --> %d\n", wlan_mode, WLAN_MODE_STA_AP_P2P); + wlan_mode = WLAN_MODE_STA_AP_P2P; + retval = count; + goto done; + } + } + + /* 2. Non-concurrent mode */ + if ((wlan_mode == WLAN_MODE_STA_P2P && (local[0] == 'S' || local[0] == 'P')) || + (wlan_mode == WLAN_MODE_AP && (local[0] == 'A'))) { + WIFI_INFO_FUNC("WIFI is already in mode %d!\n", wlan_mode); + retval = count; + goto done; + } + + if ((wlan_mode == WLAN_MODE_AP && (local[0] == 'S' || local[0] == 'P')) || + (wlan_mode == WLAN_MODE_STA_P2P && (local[0] == 'A'))) { + p2pmode.u4Enable = 0; + p2pmode.u4Mode = 0; + if (pf_set_p2p_mode(netdev, p2pmode) != 0) { + WIFI_ERR_FUNC("Turn off p2p/ap mode fail"); + goto done; + } + } + + if (local[0] == 'S' || local[0] == 'P') { + p2pmode.u4Enable = 1; + p2pmode.u4Mode = 0; + if (pf_set_p2p_mode(netdev, p2pmode) != 0) { + WIFI_ERR_FUNC("Set wlan mode fail\n"); + } else { + WIFI_INFO_FUNC("Set wlan mode %d --> %d\n", wlan_mode, WLAN_MODE_STA_P2P); + wlan_mode = WLAN_MODE_STA_P2P; + retval = count; + } + } else if (local[0] == 'A') { + p2pmode.u4Enable = 1; + p2pmode.u4Mode = 1; + if (pf_set_p2p_mode(netdev, p2pmode) != 0) { + WIFI_ERR_FUNC("Set wlan mode fail\n"); + } else { + WIFI_INFO_FUNC("Set wlan mode %d --> %d\n", wlan_mode, WLAN_MODE_AP); + wlan_mode = WLAN_MODE_AP; + retval = count; + } + } + dev_put(netdev); + netdev = NULL; + } else if (local[0] == 'C') { + if ((isconcurrent == 0) && + ((wlan_mode == WLAN_MODE_STA_P2P) + || (wlan_mode == WLAN_MODE_AP))) { + netdev = dev_get_by_name(&init_net, ifname); + if (netdev && pf_set_p2p_mode) { + p2pmode.u4Enable = 0; + p2pmode.u4Mode = 0; + if (pf_set_p2p_mode(netdev, p2pmode) != 0) + WIFI_ERR_FUNC("Turn off p2p/ap mode fail"); + else + WIFI_INFO_FUNC("Turn off p2p/ap mode success"); + } else + WIFI_ERR_FUNC("Fail to get %s netdev\n", ifname); + } + isconcurrent = 1; + WIFI_INFO_FUNC("Enable concurrent mode\n"); + retval = count; + } else if (local[0] == 'N') { + if ((isconcurrent == 1) && + (wlan_mode == WLAN_MODE_STA_AP_P2P)) { + netdev = dev_get_by_name(&init_net, ifname); + if (netdev && pf_set_p2p_mode) { + p2pmode.u4Enable = 0; + p2pmode.u4Mode = 0; + if (pf_set_p2p_mode(netdev, p2pmode) != 0) + WIFI_ERR_FUNC("Turn off p2p/ap mode fail"); + else + WIFI_INFO_FUNC("Turn off p2p/ap mode success"); + } else + WIFI_ERR_FUNC("Fail to get %s netdev\n", ifname); + } + isconcurrent = 0; + WIFI_INFO_FUNC("Disable concurrent mode\n"); + retval = count; + } else if (!strncmp(local, "LLM", 3)) { + WIFI_INFO_FUNC("local = %s", local); + if (!strncmp(local + 4, "0x", 2)) { + WIFI_INFO_FUNC("LLM val = %s", local + 6); + set_low_latency_mode(local + 6); + retval = count; + } else { + retval = -ENOTSUPP; + } + } + } +done: + if (netdev != NULL) + dev_put(netdev); +#if (CFG_ANDORID_CONNINFRA_SUPPORT == 1) + write_processing = 0; +#endif + up(&wr_mtx); + return retval; +} + +const struct file_operations WIFI_fops = { + .open = WIFI_open, + .release = WIFI_close, + .write = WIFI_write, +}; + +static int WIFI_init(void) +{ + int32_t alloc_ret = 0; + int32_t cdev_err = 0; + + low_latency_mode = 0; + + sema_init(&wr_mtx, 1); + + /* Allocate char device */ + if (WIFI_major) { + wifi_devno = MKDEV(WIFI_major, 0); + alloc_ret = register_chrdev_region(wifi_devno, WIFI_devs, + WIFI_DRIVER_NAME); + } else { + alloc_ret = alloc_chrdev_region(&wifi_devno, 0, WIFI_devs, + WIFI_DRIVER_NAME); + } + if (alloc_ret) { + WIFI_ERR_FUNC("Fail to register device numbers\n"); + return alloc_ret; + } + + cdev_init(&WIFI_cdev, &WIFI_fops); + WIFI_cdev.owner = THIS_MODULE; + + cdev_err = cdev_add(&WIFI_cdev, wifi_devno, WIFI_devs); + if (cdev_err) + goto error; + +#if CREATE_NODE_DYNAMIC /* mknod replace */ + wmtwifi_class = class_create(THIS_MODULE, "wmtWifi"); + if (IS_ERR(wmtwifi_class)) + goto error; + wmtwifi_dev = device_create(wmtwifi_class, NULL, wifi_devno, NULL, + "wmtWifi"); + if (IS_ERR(wmtwifi_dev)) + goto error; +#endif + + WIFI_INFO_FUNC("%s driver(major %d %d) installed.\n", WIFI_DRIVER_NAME, + WIFI_major, MAJOR(wifi_devno)); + +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH + if (fw_log_wifi_init() < 0) { + WIFI_INFO_FUNC("connsys debug node init failed!!\n"); + goto error; + } +#endif +#if (CFG_ANDORID_CONNINFRA_SUPPORT == 1) + wifi_pwr_on_init(); +#endif + return 0; + +error: +#if CREATE_NODE_DYNAMIC + if (wmtwifi_dev && !IS_ERR(wmtwifi_dev)) { + device_destroy(wmtwifi_class, wifi_devno); + wmtwifi_dev = NULL; + } + if (wmtwifi_class && !IS_ERR(wmtwifi_class)) { + class_destroy(wmtwifi_class); + wmtwifi_class = NULL; + } +#endif + if (cdev_err == 0) + cdev_del(&WIFI_cdev); + + if (alloc_ret == 0) + unregister_chrdev_region(wifi_devno, WIFI_devs); + + return -1; +} + +static void WIFI_exit(void) +{ +#if CREATE_NODE_DYNAMIC + if (wmtwifi_dev && !IS_ERR(wmtwifi_dev)) { + device_destroy(wmtwifi_class, wifi_devno); + wmtwifi_dev = NULL; + } + if (wmtwifi_class && !IS_ERR(wmtwifi_class)) { + class_destroy(wmtwifi_class); + wmtwifi_class = NULL; + } +#endif + + cdev_del(&WIFI_cdev); + unregister_chrdev_region(wifi_devno, WIFI_devs); + + WIFI_INFO_FUNC("%s driver removed\n", WIFI_DRIVER_NAME); + +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH + fw_log_wifi_deinit(); +#endif +#if (CFG_ANDORID_CONNINFRA_SUPPORT == 1) + wifi_pwr_on_deinit(); +#endif +} + +#ifdef MTK_WCN_BUILT_IN_DRIVER + +int mtk_wcn_wmt_wifi_init(void) +{ + return WIFI_init(); +} +EXPORT_SYMBOL(mtk_wcn_wmt_wifi_init); + +void mtk_wcn_wmt_wifi_exit(void) +{ + return WIFI_exit(); +} +EXPORT_SYMBOL(mtk_wcn_wmt_wifi_exit); + +#else + +module_init(WIFI_init); +module_exit(WIFI_exit); + +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/Makefile b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..0644dc5964d2c46cbd33d7817dbe0da96beee898 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/Makefile @@ -0,0 +1,745 @@ +MTK_PLATFORM := $(subst ",,$(CONFIG_MTK_PLATFORM)) +# --------------------------------------------------- +# OS option +# --------------------------------------------------- +os=$(CONFIG_MTK_SUPPORT_OS) + +ifeq ($(os),) +os=linux +endif + +ccflags-y += -Wno-unused-value +ccflags-y += -Wno-unused-result +ccflags-y += -Wno-format +ccflags-y += -Wno-parentheses + +ifeq ($(os), none) +ccflags-y += -I/usr/include/ +ccflags-y += -DCFG_VIRTUAL_OS +ccflags-y += -DCFG_REMIND_IMPLEMENT +endif + +$(info os option: $(os)) +# --------------------------------------------------- +# ALPS Setting +# --------------------------------------------------- +ifeq ($(KBUILD_MODPOST_FAIL_ON_WARNINGS),) + # Force build fail on modpost warning + KBUILD_MODPOST_FAIL_ON_WARNINGS=y +endif + +DRIVER_BUILD_DATE=$(shell date +%Y%m%d%H%M%S) +ccflags-y += -DDRIVER_BUILD_DATE='"$(DRIVER_BUILD_DATE)"' +# --------------------------------------------------- +# Compile Options +# --------------------------------------------------- +WLAN_CHIP_LIST:=-UMT6620 -UMT6628 -UMT5931 -UMT6630 -UMT6632 -UMT7663 -UCONNAC -UCONNAC2X2 -UUT_TEST_MODE -UMT7915 -USOC3_0 -UMT7961 +# '-D' and '-U' options are processed in the order they are given on the command line. +# All '-imacros file' and '-include file' options are processed after all '-D' and '-U' options. +ccflags-y += $(WLAN_CHIP_LIST) + +ifeq ($(MTK_COMBO_CHIP),) +MTK_COMBO_CHIP = MT6632 +endif + +MTK_WLAN_SERVICE=yes +MTK_ANDROID_EMI=y +MODULE_NAME=wlan_drv_gen4m + +$(info $$MTK_PLATFORM is [${MTK_PLATFORM}]) +$(info $$WLAN_CHIP_ID is [${WLAN_CHIP_ID}]) +$(info $$MTK_COMBO_CHIP is [${MTK_COMBO_CHIP}]) + +ifneq ($(CONFIG_MTK_EMI),) +ccflags-y += -DCONFIG_MTK_EMI=1 +endif + +ifneq ($(CONFIG_MEDIATEK_EMI),) +ccflags-y += -DCONFIG_MTK_EMI=1 +endif + +ifeq ($(WLAN_CHIP_ID),) +WLAN_CHIP_ID=$(word 1, $(MTK_COMBO_CHIP)) +endif + +ccflags-y += -DCFG_SUPPORT_DEBUG_FS=0 +ccflags-y += -DWLAN_INCLUDE_PROC +ccflags-y += -DCFG_SUPPORT_AGPS_ASSIST=0 +ccflags-y += -DCFG_SUPPORT_TSF_USING_BOOTTIME=1 +ccflags-y += -DARP_MONITER_ENABLE=1 +ccflags-y += -Werror +#ccflags-y:=$(filter-out -U$(WLAN_CHIP_ID),$(ccflags-y)) +#ccflags-y += -DLINUX -D$(WLAN_CHIP_ID) +#workaround: also needed for none LINUX system +# because some of common part code is surrounded with this flag +ccflags-y += -DLINUX + +ifneq ($(filter MT6632,$(MTK_COMBO_CHIP)),) +ccflags-y:=$(filter-out -UMT6632,$(ccflags-y)) +ccflags-y += -DMT6632 +endif + +ifneq ($(filter MT7668,$(MTK_COMBO_CHIP)),) +ccflags-y:=$(filter-out -UMT7668,$(ccflags-y)) +ccflags-y += -DMT7668 +endif + +ifneq ($(filter MT7663,$(MTK_COMBO_CHIP)),) +ccflags-y:=$(filter-out -UMT7663,$(ccflags-y)) +ccflags-y += -DMT7663 +endif + +ifneq ($(filter CONNAC,$(MTK_COMBO_CHIP)),) +ccflags-y:=$(filter-out -UCONNAC,$(ccflags-y)) +ccflags-y += -DCONNAC +endif + +ifneq ($(filter CONNAC2X2,$(MTK_COMBO_CHIP)),) +ccflags-y:=$(filter-out -UCONNAC2X2,$(ccflags-y)) +ccflags-y += -DCONNAC2X2 +endif + +ifneq ($(findstring MT7915,$(MTK_COMBO_CHIP)),) +ccflags-y:=$(filter-out -UMT7915,$(ccflags-y)) +ccflags-y += -DMT7915 +CONFIG_MTK_WIFI_CONNAC2X=y +CONFIG_MTK_WIFI_11AX_SUPPORT=y +CONFIG_MTK_WIFI_TWT_SUPPORT=y +CONFIG_MTK_WIFI_TWT_SMART_STA=n +CONFIG_NUM_OF_WFDMA_RX_RING=5 +CONFIG_NUM_OF_WFDMA_TX_RING=1 +endif + +ifneq ($(findstring 3_0,$(MTK_COMBO_CHIP)),) +ccflags-y:=$(filter-out -USOC3_0,$(ccflags-y)) +ccflags-y += -DSOC3_0 +CONFIG_MTK_WIFI_CONNAC2X=y +CONFIG_MTK_WIFI_11AX_SUPPORT=y +CONFIG_MTK_WIFI_TWT_SUPPORT=y +CONFIG_MTK_WIFI_TWT_SMART_STA=n +CONFIG_NUM_OF_WFDMA_RX_RING=3 +CONFIG_NUM_OF_WFDMA_TX_RING=0 +CONFIG_MTK_WIFI_CONNINFRA_SUPPORT=y +CONFIG_MTK_WIFI_CONNAC2X_2x2=y +ccflags-y += -DCFG_POWER_ON_DOWNLOAD_EMI_ROM_PATCH=1 +ccflags-y += -DCFG_DOWNLOAD_DYN_MEMORY_MAP=1 +ccflags-y += -DCFG_ROM_PATCH_NO_SEM_CTRL=1 +ccflags-y += -DCFG_ANDORID_CONNINFRA_SUPPORT=1 +else +ccflags-y += -DCFG_ANDORID_CONNINFRA_SUPPORT=0 +endif + +ifneq ($(findstring MT7961,$(MTK_COMBO_CHIP)),) +ccflags-y:=$(filter-out -UMT7961,$(ccflags-y)) +ccflags-y += -DMT7961 +CONFIG_MTK_WIFI_CONNAC2X=y +CONFIG_MTK_WIFI_11AX_SUPPORT=y +CONFIG_MTK_WIFI_TWT_SUPPORT=y +CONFIG_MTK_WIFI_TWT_SMART_STA=n +CONFIG_NUM_OF_WFDMA_RX_RING=5 +CONFIG_NUM_OF_WFDMA_TX_RING=1 +endif + +ifneq ($(filter 6873, $(WLAN_CHIP_ID)),) + ccflags-y += -DCFG_ENABLE_HOST_BUS_TIMEOUT=1 +else + ccflags-y += -DCFG_ENABLE_HOST_BUS_TIMEOUT=0 +endif + +ifeq ($(CONFIG_MTK_WIFI_CONNAC2X), y) + ccflags-y += -DCFG_SUPPORT_CONNAC2X=1 +else + ccflags-y += -DCFG_SUPPORT_CONNAC2X=0 +endif + +ifeq ($(CONFIG_MTK_WIFI_CONNAC2X_2x2), y) + ccflags-y += -DCFG_SUPPORT_CONNAC2X_2x2=1 +else + ccflags-y += -DCFG_SUPPORT_CONNAC2X_2x2=0 +endif + +ifeq ($(CONFIG_MTK_WIFI_11AX_SUPPORT), y) + ccflags-y += -DCFG_SUPPORT_802_11AX=1 +else + ccflags-y += -DCFG_SUPPORT_802_11AX=0 +endif + +ifeq ($(CONFIG_MTK_WIFI_TWT_SUPPORT), y) + ccflags-y += -DCFG_SUPPORT_TWT=1 + ifeq ($(CONFIG_MTK_WIFI_TWT_SMART_STA), y) + ccflags-y += -DCFG_TWT_SMART_STA=1 + else + ccflags-y += -DCFG_TWT_SMART_STA=0 + endif +else + ccflags-y += -DCFG_SUPPORT_TWT=0 + ccflags-y += -DCFG_TWT_SMART_STA=0 +endif + +ifneq ($(CONFIG_NUM_OF_WFDMA_TX_RING),) + ccflags-y += -DCONFIG_NUM_OF_WFDMA_TX_RING=$(CONFIG_NUM_OF_WFDMA_TX_RING) +endif + +ifneq ($(CONFIG_NUM_OF_WFDMA_RX_RING),) + ccflags-y += -DCONFIG_NUM_OF_WFDMA_RX_RING=$(CONFIG_NUM_OF_WFDMA_RX_RING) +endif + +ifeq ($(WIFI_ENABLE_GCOV), y) + GCOV_PROFILE := y +endif + +ccflags-y += -DCFG_DRIVER_INITIAL_RUNNING_MODE=3 + +ifneq ($(filter 6765, $(WLAN_CHIP_ID)),) + ccflags-y += -DCFG_SUPPORT_DUAL_STA=0 +else ifeq ($(CONFIG_MTK_TC10_FEATURE), y) + ccflags-y += -DCFG_SUPPORT_DUAL_STA=0 +else + ccflags-y += -DCFG_SUPPORT_DUAL_STA=1 +endif + +ifneq ($(filter 6779, $(WLAN_CHIP_ID)),) + ccflags-y += -DCFG_FORCE_AP1NSS +endif + +ifeq ($(MTK_ANDROID_WMT), y) + ccflags-y += -DCFG_MTK_ANDROID_WMT=1 + WMT_SUPPORT := y +else ifneq ($(filter MT6632,$(MTK_COMBO_CHIP)),) + ccflags-y += -DCFG_MTK_ANDROID_WMT=1 + WMT_SUPPORT := y +else + ccflags-y += -DCFG_MTK_ANDROID_WMT=0 + WMT_SUPPORT := n +endif + +ifeq ($(CONFIG_MTK_WIFI_CONNINFRA_SUPPORT), y) + ccflags-y += -DCFG_SUPPORT_CONNINFRA=1 + ccflags-y += -DCFG_SUPPORT_PRE_ON_PHY_ACTION=1 + ccflags-y += -I$(srctree)/drivers/misc/mediatek/connectivity/conninfra/include + ccflags-y += -DCFG_ANDORID_CONNINFRA_COREDUMP_SUPPORT=1 + ifneq ($(CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH),) + ccflags-y += -I$(srctree)/drivers/misc/mediatek/connectivity/conninfra/include + ccflags-y += -I$(srctree)/drivers/misc/mediatek/connectivity/conninfra/platform/include + ccflags-y += -I$(srctree)/drivers/misc/mediatek/connectivity/conninfra/base/include + ccflags-y += -I$(srctree)/drivers/misc/mediatek/connectivity/conninfra/debug_utility + ccflags-y += -I$(srctree)/drivers/misc/mediatek/connectivity/conninfra/debug_utility/include + ccflags-y += -I$(srctree)/drivers/misc/mediatek/connectivity/conninfra/debug_utility/connsyslog + ccflags-y += -I$(srctree)/drivers/misc/mediatek/connectivity/conninfra/debug_utility/coredump + ccflags-y += -I$(srctree)/drivers/misc/mediatek/connectivity/conninfra/debug_utility/coredump/platform/include + ccflags-y += -I$(srctree)/drivers/misc/mediatek/connectivity/wlan/adaptor + endif +else + ccflags-y += -DCFG_SUPPORT_CONNINFRA=0 + ccflags-y += -DCFG_ANDORID_CONNINFRA_COREDUMP_SUPPORT=0 + ccflags-y += -DCFG_SUPPORT_PRE_ON_PHY_ACTION=0 + ifeq ($(WMT_SUPPORT), y) + ccflags-y += -I$(srctree)/drivers/misc/mediatek/connectivity/common/common_main/include + ccflags-y += -I$(srctree)/drivers/misc/mediatek/connectivity/common/common_main/linux/include + ifeq ($(CONFIG_MTK_CONN_LTE_IDC_SUPPORT),y) + ccflags-y += -DWMT_IDC_SUPPORT=1 + else + ccflags-y += -DWMT_IDC_SUPPORT=0 + endif + ccflags-y += -DMTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT + endif +endif + +ifeq ($(MTK_ANDROID_EMI), y) + ccflags-y += -DCFG_MTK_ANDROID_EMI=1 +else + ccflags-y += -DCFG_MTK_ANDROID_EMI=0 +endif + +ifneq ($(WIFI_IP_SET),) + ccflags-y += -DCFG_WIFI_IP_SET=$(WIFI_IP_SET) +else + ccflags-y += -DCFG_WIFI_IP_SET=1 +endif + +ifneq ($(filter MTK_WCN_REMOVE_KERNEL_MODULE,$(KBUILD_SUBDIR_CCFLAGS)),) + ccflags-y += -DCFG_BUILT_IN_DRIVER=1 +else + ccflags-y += -DCFG_BUILT_IN_DRIVER=0 +endif + +ifneq ($(findstring UT_TEST_MODE,$(MTK_COMBO_CHIP)),) +ccflags-y:=$(filter-out -UUT_TEST_MODE,$(ccflags-y)) +ccflags-y += -DUT_TEST_MODE +endif + +CONFIG_MTK_WIFI_MCC_SUPPORT=y +ifeq ($(CONFIG_MTK_WIFI_MCC_SUPPORT), y) + ccflags-y += -DCFG_SUPPORT_CHNL_CONFLICT_REVISE=0 +else + ccflags-y += -DCFG_SUPPORT_CHNL_CONFLICT_REVISE=1 +endif + +ifeq ($(CONFIG_MTK_AEE_FEATURE), y) + ccflags-y += -DCFG_SUPPORT_AEE=1 +else + ccflags-y += -DCFG_SUPPORT_AEE=0 +endif + +# Disable ASSERT() for user load, enable for others +ifneq ($(TARGET_BUILD_VARIANT),user) + ccflags-y += -DBUILD_QA_DBG=1 +else + ccflags-y += -DBUILD_QA_DBG=0 +endif + +ifeq ($(CONFIG_MTK_COMBO_WIFI),y) + ccflags-y += -DCFG_WPS_DISCONNECT=1 +endif + +ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), sdio) + ccflags-y += -D_HIF_SDIO=1 +else ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), pcie) + ccflags-y += -D_HIF_PCIE=1 +else ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), usb) + ccflags-y += -D_HIF_USB=1 +else ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), axi) + ccflags-y += -D_HIF_AXI=1 +else ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), ut) + # Increase frame size to 2048 because of 'cfg80211_connect_result' exceed stack size + ccflags-y += -D_HIF_UT=1 -Wno-unused-function -Wno-unused-variable -Wframe-larger-than=2048 +else ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), none) + ccflags-y += -D_HIF_NONE=1 +else + $(error Unsuppoted HIF=$(CONFIG_MTK_COMBO_WIFI_HIF)!!) +endif + +ifneq ($(CFG_CFG80211_VERSION),) +VERSION_STR = $(subst \",,$(subst ., , $(subst -, ,$(subst v,,$(CFG_CFG80211_VERSION))))) +$(info VERSION_STR=$(VERSION_STR)) +X = $(firstword $(VERSION_STR)) +Y = $(word 2 ,$(VERSION_STR)) +Z = $(word 3 ,$(VERSION_STR)) +VERSION := $(shell echo "$$(( $X * 65536 + $Y * 256 + $Z))" ) +ccflags-y += -DCFG_CFG80211_VERSION=$(VERSION) +$(info DCFG_CFG80211_VERSION=$(VERSION)) +endif + + +ifeq ($(CONFIG_MTK_PASSPOINT_R2_SUPPORT), y) + ccflags-y += -DCFG_SUPPORT_PASSPOINT=1 + ccflags-y += -DCFG_HS20_DEBUG=1 + ccflags-y += -DCFG_ENABLE_GTK_FRAME_FILTER=1 +else + ccflags-y += -DCFG_SUPPORT_PASSPOINT=0 + ccflags-y += -DCFG_HS20_DEBUG=0 + ccflags-y += -DCFG_ENABLE_GTK_FRAME_FILTER=0 +endif + +MTK_MET_PROFILING_SUPPORT = yes +ifeq ($(MTK_MET_PROFILING_SUPPORT), yes) + ccflags-y += -DCFG_MET_PACKET_TRACE_SUPPORT=1 +else + ccflags-y += -DCFG_MET_PACKET_TRACE_SUPPORT=0 +endif + +MTK_MET_TAG_SUPPORT = no +ifeq ($(MTK_MET_TAG_SUPPORT), yes) + ccflags-y += -DMET_USER_EVENT_SUPPORT + ccflags-y += -DCFG_MET_TAG_SUPPORT=1 +else + ccflags-y += -DCFG_MET_TAG_SUPPORT=0 +endif + +MTK_TC3_SUPPORT = no +ifeq ($(MTK_TC3_SUPPORT), yes) + ccflags-y += -DCFG_TC3_FEATURE=1 + ccflags-y += -DCFG_P2P_CONNECT_ALL_BSS=1 + ccflags-y += -DCFG_P2P_DEFAULT_CLIENT_COUNT=1 + ccflags-y += -DCFG_P2P_SCAN_REPORT_ALL_BSS=1 +else + ccflags-y += -DCFG_TC3_FEATURE=0 +endif + +ifeq ($(CONFIG_MTK_TC10_FEATURE), y) + ccflags-y += -DCFG_TC10_FEATURE=1 +else + ccflags-y += -DCFG_TC10_FEATURE=0 +endif + +ifeq ($(CONFIG_MTK_TC1_FEATURE), y) + ccflags-y += -I$(srctree)/drivers/misc/mediatek/tc1_interface + ccflags-y += -DCFG_TC1_FEATURE=1 +else + ccflags-y += -DCFG_TC1_FEATURE=0 +endif + +ifeq ($(MODULE_NAME),) + MODULE_NAME := wlan_$(shell echo $(strip $(WLAN_CHIP_ID)) | tr A-Z a-z)_$(CONFIG_MTK_COMBO_WIFI_HIF) +endif + +ccflags-y += -DDBG=0 +ccflags-y += -I$(src)/os -I$(src)/os/$(os)/include +ccflags-y += -I$(src)/include -I$(src)/include/nic -I$(src)/include/mgmt -I$(src)/include/chips +ifeq ($(CFG_SUPPORT_WIFI_SYSDVT), 1) +ccflags-y += -I$(src)/include/dvt +endif +ccflags-y += -I$(srctree)/drivers/misc/mediatek/base/power/include/ +ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/ +ccflags-y += -I$(srctree)/drivers/misc/mediatek/performance/include/ +ccflags-y += -I$(srctree)/drivers/misc/mediatek/emi/$(MTK_PLATFORM) +ccflags-y += -I$(srctree)/drivers/misc/mediatek/emi/submodule +ccflags-y += -I$(srctree)/drivers/misc/mediatek/connectivity/common +ccflags-y += -I$(srctree)/drivers/devfreq/ +ccflags-y += -I$(srctree)/net + +ifeq ($(CONFIG_MTK_MCIF_WIFI_SUPPORT), y) +ccflags-y += -I$(srctree)/drivers/misc/mediatek/mddp/include/ +ccflags-y += -DCFG_MTK_MCIF_WIFI_SUPPORT=1 +ifeq ($(CONFIG_MTK_MDDP_WH_SUPPORT), y) +ccflags-y += -DCFG_MTK_MDDP_WH_SUPPORT=1 +else +ccflags-y += -DCFG_MTK_MDDP_WH_SUPPORT=0 +endif +else +ccflags-y += -DCFG_MTK_MCIF_WIFI_SUPPORT=0 +ccflags-y += -DCFG_MTK_MDDP_WH_SUPPORT=0 +endif + +ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), sdio) +ccflags-y += -I$(src)/os/$(os)/hif/sdio/include +else ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), pcie) +ccflags-y += -I$(src)/os/$(os)/hif/common/include +ccflags-y += -I$(src)/os/$(os)/hif/pcie/include +ifneq ($(findstring 3_0,$(MTK_COMBO_CHIP)),) +ccflags-y += -I$(src)/include/chips/coda/soc3_0 +endif +else ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), axi) +ccflags-y += -I$(src)/os/$(os)/hif/common/include +ccflags-y += -I$(src)/os/$(os)/hif/axi/include +else ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), usb) +ccflags-y += -I$(src)/os/$(os)/hif/usb/include +else ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), ut) +ccflags-y += -I$(src)/test -I$(src)/test/lib/include -I$(src)/test/testcases -I$(src)/test/lib/hif +else ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), none) +ccflags-y += -I$(src)/os/$(os)/hif/none/include +endif + +ifneq ($(PLATFORM_FLAGS), ) + ccflags-y += $(PLATFORM_FLAGS) +endif + +ifeq ($(CONFIG_MTK_WIFI_ONLY),$(filter $(CONFIG_MTK_WIFI_ONLY),m y)) +obj-$(CONFIG_MTK_WIFI_ONLY) += $(MODULE_NAME).o +else +obj-$(CONFIG_MTK_COMBO_WIFI) += $(MODULE_NAME).o +#obj-y += $(MODULE_NAME).o +endif + +ifeq ($(CONFIG_WLAN_DRV_BUILD_IN),y) +$(warning $(MODULE_NAME) build-in boot.img) +obj-y += $(MODULE_NAME).o +ccflags-y += -DCONFIG_WLAN_DRV_BUILD_IN=1 +else +$(warning $(MODULE_NAME) is kernel module) +obj-m += $(MODULE_NAME).o +ccflags-y += -DCONFIG_WLAN_DRV_BUILD_IN=0 +endif + +# --------------------------------------------------- +# Directory List +# --------------------------------------------------- +COMMON_DIR := common/ +OS_DIR := os/$(os)/ +HIF_COMMON_DIR := $(OS_DIR)hif/common/ +ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), sdio) +HIF_DIR := os/$(os)/hif/sdio/ +else ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), pcie) +HIF_DIR := os/$(os)/hif/pcie/ +else ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), axi) +HIF_DIR := os/$(os)/hif/axi/ +else ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), usb) +HIF_DIR := os/$(os)/hif/usb/ +else ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), ut) +HIF_DIR := test/lib/hif/ +else ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), none) +HIF_DIR := os/$(os)/hif/none/ +endif +NIC_DIR := nic/ +MGMT_DIR := mgmt/ +CHIPS := chips/ +CHIPS_CMM := $(CHIPS)common/ + +ifneq ($(WLAN_CHIP_ID),) +PLAT_DIR := os/$(os)/plat/mt$(WLAN_CHIP_ID)/ +endif +SYSDVT_DIR := dvt/ + +# --------------------------------------------------- +# Objects List +# --------------------------------------------------- + +COMMON_OBJS := $(COMMON_DIR)dump.o \ + $(COMMON_DIR)wlan_lib.o \ + $(COMMON_DIR)wlan_oid.o \ + $(COMMON_DIR)wlan_bow.o \ + $(COMMON_DIR)debug.o + +NIC_OBJS := $(NIC_DIR)nic.o \ + $(NIC_DIR)nic_tx.o \ + $(NIC_DIR)nic_txd_v1.o \ + $(NIC_DIR)nic_rxd_v1.o \ + $(NIC_DIR)nic_rx.o \ + $(NIC_DIR)nic_pwr_mgt.o \ + $(NIC_DIR)nic_rate.o \ + $(NIC_DIR)cmd_buf.o \ + $(NIC_DIR)que_mgt.o \ + $(NIC_DIR)nic_cmd_event.o \ + $(NIC_DIR)nic_umac.o + +ifeq ($(os), none) +OS_OBJS := $(OS_DIR)gl_dependent.o \ + $(OS_DIR)gl_init.o \ + $(OS_DIR)gl_kal.o \ + $(OS_DIR)gl_ate_agent.o \ + $(OS_DIR)gl_qa_agent.o +else +OS_OBJS := $(OS_DIR)gl_init.o \ + $(OS_DIR)gl_kal.o \ + $(OS_DIR)gl_bow.o \ + $(OS_DIR)gl_wext.o \ + $(OS_DIR)gl_wext_priv.o \ + $(OS_DIR)gl_ate_agent.o \ + $(OS_DIR)gl_qa_agent.o \ + $(OS_DIR)gl_hook_api.o \ + $(OS_DIR)gl_rst.o \ + $(OS_DIR)gl_cfg80211.o \ + $(OS_DIR)gl_proc.o \ + $(OS_DIR)gl_sys.o \ + $(OS_DIR)gl_vendor.o \ + $(OS_DIR)platform.o +endif + +MGMT_OBJS := $(MGMT_DIR)ais_fsm.o \ + $(MGMT_DIR)aaa_fsm.o \ + $(MGMT_DIR)assoc.o \ + $(MGMT_DIR)auth.o \ + $(MGMT_DIR)bss.o \ + $(MGMT_DIR)cnm.o \ + $(MGMT_DIR)cnm_timer.o \ + $(MGMT_DIR)cnm_mem.o \ + $(MGMT_DIR)hem_mbox.o \ + $(MGMT_DIR)mib.o \ + $(MGMT_DIR)privacy.o \ + $(MGMT_DIR)rate.o \ + $(MGMT_DIR)rlm.o \ + $(MGMT_DIR)rlm_domain.o \ + $(MGMT_DIR)reg_rule.o \ + $(MGMT_DIR)rlm_obss.o \ + $(MGMT_DIR)rlm_protection.o \ + $(MGMT_DIR)rrm.o \ + $(MGMT_DIR)rsn.o \ + $(MGMT_DIR)saa_fsm.o \ + $(MGMT_DIR)scan.o \ + $(MGMT_DIR)scan_fsm.o \ + $(MGMT_DIR)scan_cache.o \ + $(MGMT_DIR)swcr.o \ + $(MGMT_DIR)roaming_fsm.o \ + $(MGMT_DIR)tkip_mic.o \ + $(MGMT_DIR)hs20.o \ + $(MGMT_DIR)tdls.o \ + $(MGMT_DIR)wnm.o \ + $(MGMT_DIR)qosmap.o \ + $(MGMT_DIR)ap_selection.o \ + $(MGMT_DIR)wmm.o \ + $(MGMT_DIR)mddp.o \ + +# --------------------------------------------------- +# Chips Objects List +# --------------------------------------------------- +MGMT_OBJS += $(MGMT_DIR)stats.o + + +CHIPS_OBJS += $(CHIPS_CMM)cmm_asic_connac.o +CHIPS_OBJS += $(CHIPS_CMM)dbg_connac.o +ifeq ($(CONFIG_MTK_WIFI_CONNAC2X), y) +CHIPS_OBJS += $(CHIPS_CMM)dbg_connac2x.o +endif + +ifeq ($(CONFIG_MTK_WIFI_CONNAC2X), y) +CHIPS_OBJS += $(CHIPS_CMM)cmm_asic_connac2x.o +NIC_OBJS += $(NIC_DIR)nic_ext_cmd_event.o \ + $(NIC_DIR)nic_txd_v2.o \ + $(NIC_DIR)nic_rxd_v2.o +endif +CHIPS_OBJS += $(CHIPS_CMM)fw_dl.o + +ifneq ($(filter MT6632,$(MTK_COMBO_CHIP)),) +CHIPS_OBJS += $(CHIPS)mt6632/mt6632.o +endif +ifneq ($(filter MT7668,$(MTK_COMBO_CHIP)),) +CHIPS_OBJS += $(CHIPS)mt7668/mt7668.o +endif +ifneq ($(filter MT7663,$(MTK_COMBO_CHIP)),) +CHIPS_OBJS += $(CHIPS)mt7663/mt7663.o +endif +ifneq ($(filter CONNAC,$(MTK_COMBO_CHIP)),) +CHIPS_OBJS += $(CHIPS)connac/connac.o +endif +ifneq ($(filter CONNAC2X2,$(MTK_COMBO_CHIP)),) +CHIPS_OBJS += $(CHIPS)connac2x2/connac2x2.o +endif +ifneq ($(findstring MT7915,$(MTK_COMBO_CHIP)),) +CHIPS_OBJS += $(CHIPS)mt7915/mt7915.o +CHIPS_OBJS += $(CHIPS)mt7915/dbg_mt7915.o +endif +ifneq ($(findstring 3_0,$(MTK_COMBO_CHIP)),) +CHIPS_OBJS += $(CHIPS)soc3_0/soc3_0.o +CHIPS_OBJS += $(CHIPS)soc3_0/dbg_soc3_0.o +CHIPS_OBJS += $(CHIPS)soc3_0/hal_dmashdl_soc3_0.o +endif +ifneq ($(findstring MT7961,$(MTK_COMBO_CHIP)),) +CHIPS_OBJS += $(CHIPS)mt7961/mt7961.o +CHIPS_OBJS += $(CHIPS)mt7961/dbg_mt7961.o +CHIPS_OBJS += $(CHIPS)mt7961/hal_dmashdl_mt7961.o +endif + +# --------------------------------------------------- +# P2P Objects List +# --------------------------------------------------- + +COMMON_OBJS += $(COMMON_DIR)wlan_p2p.o + +NIC_OBJS += $(NIC_DIR)p2p_nic.o + +ifneq ($(os), none) +OS_OBJS += $(OS_DIR)gl_p2p.o \ + $(OS_DIR)gl_p2p_cfg80211.o \ + $(OS_DIR)gl_p2p_init.o \ + $(OS_DIR)gl_p2p_kal.o +endif + +MGMT_OBJS += $(MGMT_DIR)p2p_dev_fsm.o\ + $(MGMT_DIR)p2p_dev_state.o\ + $(MGMT_DIR)p2p_role_fsm.o\ + $(MGMT_DIR)p2p_role_state.o\ + $(MGMT_DIR)p2p_func.o\ + $(MGMT_DIR)p2p_scan.o\ + $(MGMT_DIR)p2p_ie.o\ + $(MGMT_DIR)p2p_rlm.o\ + $(MGMT_DIR)p2p_assoc.o\ + $(MGMT_DIR)p2p_bss.o\ + $(MGMT_DIR)p2p_rlm_obss.o\ + $(MGMT_DIR)p2p_fsm.o + +MGMT_OBJS += $(MGMT_DIR)wapi.o + +# --------------------------------------------------- +# HE Objects List +# --------------------------------------------------- + +COMMON_OBJS += $(COMMON_DIR)wlan_he.o + +ifeq ($(CONFIG_MTK_WIFI_11AX_SUPPORT), y) +MGMT_OBJS += $(MGMT_DIR)he_ie.o \ + $(MGMT_DIR)he_rlm.o +endif + +ifeq ($(CONFIG_MTK_WIFI_TWT_SUPPORT), y) +MGMT_OBJS += $(MGMT_DIR)twt_req_fsm.o \ + $(MGMT_DIR)twt.o \ + $(MGMT_DIR)twt_planner.o +endif + +ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), sdio) +HIF_OBJS := $(HIF_DIR)arm.o \ + $(HIF_DIR)sdio.o \ + $(HIF_DIR)hal_api.o \ + $(HIF_DIR)sdio_test_driver_core.o \ + $(HIF_DIR)sdio_test_driver_ops.o +else ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), pcie) +HIF_OBJS := $(HIF_COMMON_DIR)hal_pdma.o \ + $(HIF_COMMON_DIR)kal_pdma.o \ + $(HIF_COMMON_DIR)dbg_pdma.o \ + $(HIF_DIR)pcie.o +else ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), axi) +HIF_OBJS := $(HIF_COMMON_DIR)hal_pdma.o \ + $(HIF_COMMON_DIR)kal_pdma.o \ + $(HIF_COMMON_DIR)dbg_pdma.o \ + $(HIF_DIR)axi.o +else ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), usb) +HIF_OBJS := $(HIF_DIR)usb.o \ + $(HIF_DIR)hal_api.o +else ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), ut) +HIF_OBJS := $(HIF_DIR)ut.o \ + $(HIF_DIR)hal_api.o +else ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), none) +HIF_OBJS := $(HIF_DIR)none.o +endif +# --------------------------------------------------- +# Platform Objects List +# --------------------------------------------------- +ifneq ($(PLAT_DIR),) + +PLAT_PRIV_C = $(src)/$(PLAT_DIR)plat_priv.c + +# search path (out of kernel tree) +IS_EXIST_PLAT_PRIV_C := $(wildcard $(PLAT_PRIV_C)) +# search path (build-in kernel tree) +IS_EXIST_PLAT_PRIV_C += $(wildcard $(srctree)/$(PLAT_PRIV_C)) + +ifneq ($(strip $(IS_EXIST_PLAT_PRIV_C)),) +PLAT_OBJS := $(PLAT_DIR)plat_priv.o +$(MODULE_NAME)-objs += $(PLAT_OBJS) +endif +endif + +# --------------------------------------------------- +# System Dvt Objects List +# --------------------------------------------------- +ifeq ($(CFG_SUPPORT_WIFI_SYSDVT), 1) +SYSDVT_OBJS += $(SYSDVT_DIR)dvt_common.o + +ifeq ($(CFG_SUPPORT_DMASHDL_SYSDVT), 1) +SYSDVT_OBJS += $(SYSDVT_DIR)dvt_dmashdl.o +endif +endif + +# --------------------------------------------------- +# Service git List +# --------------------------------------------------- +SERVICE_DIR := wlan_service/ + +ifneq ($(findstring wlan_service,$(MTK_WLAN_SERVICE_PATH)),) +MTK_WLAN_SERVICE=yes +SERVICE_DIR := $(MTK_WLAN_SERVICE_PATH) +$(info SERVICE_DIR is [{$(MTK_WLAN_SERVICE_PATH)}]) +endif + +ifeq ($(MTK_WLAN_SERVICE), yes) +ccflags-y += -DCONFIG_WLAN_SERVICE=1 +ccflags-y += -DCONFIG_TEST_ENGINE_OFFLOAD=1 +ccflags-y += -I$(src)/$(SERVICE_DIR)include +ccflags-y += -I$(src)/$(SERVICE_DIR)service/include +ccflags-y += -I$(src)/$(SERVICE_DIR)glue/osal/include +ccflags-y += -I$(src)/$(SERVICE_DIR)glue/hal/include +$(info $$CCFLAG is [{$(ccflags-y)}]) +SERVICE_OBJS := $(SERVICE_DIR)agent/agent.o \ + $(SERVICE_DIR)service/service_test.o \ + $(SERVICE_DIR)service/test_engine.o \ + $(SERVICE_DIR)glue/osal/gen4m/sys_adaption_gen4m.o \ + $(SERVICE_DIR)glue/osal/gen4m/net_adaption_gen4m.o \ + $(SERVICE_DIR)glue/hal/gen4m/operation_gen4m.o +$(MODULE_NAME)-objs += $(SERVICE_OBJS) +$(info $$MTK_WLAN_SERVICE is [{$(SERVICE_OBJS)}]) +else +ccflags-y += -DCONFIG_WLAN_SERVICE=0 +ccflags-y += -DCONFIG_TEST_ENGINE_OFFLOAD=0 +endif + +$(MODULE_NAME)-objs += $(COMMON_OBJS) +$(MODULE_NAME)-objs += $(NIC_OBJS) +$(MODULE_NAME)-objs += $(OS_OBJS) +$(MODULE_NAME)-objs += $(HIF_OBJS) +$(MODULE_NAME)-objs += $(MGMT_OBJS) +$(MODULE_NAME)-objs += $(CHIPS_OBJS) +$(MODULE_NAME)-objs += $(SYSDVT_OBJS) + +ifneq ($(findstring UT_TEST_MODE,$(MTK_COMBO_CHIP)),) +include $(src)/test/ut.make +endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/Makefile.ce b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/Makefile.ce new file mode 100644 index 0000000000000000000000000000000000000000..eb4cbd0b5bbda3913789691d14cee1810b1e1f9f --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/Makefile.ce @@ -0,0 +1,269 @@ +# Makefile for MT76x8 combo driver + +############################################################## +# Common settings +############################################################## +export MTK_COMBO_CHIP=MT6632 +export HIF=usb +export CONFIG_MTK_WIFI_ONLY=m +export CONFIG_MTK_COMBO=m +export CONFIG_MTK_COMBO_WIFI=m +export CONFIG_MTK_COMBO_COMM=m +export CONFIG_MTK_COMBO_COMM_UART=m +export CONFIG_MTK_COMBO_COMM_SDIO=m +export CONFIG_MT_WIFI_CHRDEV=m +WIFI_TARGET := mt76x8 + +ifeq ($(HIF),) + HIF=usb +endif + +export CONFIG_MTK_COMBO_WIFI_HIF=$(HIF) +MODULE_NAME := wlan_$(WIFI_TARGET)_$(HIF) + + +############################################################## +# Platform specific +############################################################## +# Set default platform +PLATFORM = MT53XX + +ifeq ($(PLATFORM),) +PLATFORM = MT53XX +endif + +#- - - - -- - - - - - - - - - +# MT53XX start +#- - - - -- - - - - - - - - - +ifeq ($(PLATFORM),MT53XX) + +# Sets DRIVER_PARTIAL_BUILD to y to compile driver only, otherwise set to n +DRIVER_PARTIAL_BUILD=n +# Set if 64 bit platform +64BIT_MODE=true +export WIFI_TARGET +TARGET = LINUX + +ifeq ($(DRIVER_PARTIAL_BUILD),y) +# *****For driver partial build***** +LINUX_ROOT ?= $(word 1, $(subst /apollo/,/apollo /, $(shell pwd -L))) +# Modify the build parameters below to fit your build +SYSBUILD_NAME=m-base +RELEASE_NAME=mediatek/mt5891_eu_64 +KERNEL_VER=3.18 +KERNEL_CONFIG=mt5891_android_smp_mod_defconfig +ifeq ($(64BIT_MODE),true) +export 64BIT_MODE=true +export KERNEL_64BIT=true +export TOOL_CHAIN_64BIT=4.9.3 +endif +# +LINUX_SRC=$(LINUX_ROOT)/../android/$(SYSBUILD_NAME)/out/mediatek_linux/output/$(RELEASE_NAME)/rel/obj/kernel/linux_core/kernel/linux-$(KERNEL_VER)/$(KERNEL_CONFIG)_modules +OBJ_ROOT ?= $(LINUX_ROOT)/../android/$(SYSBUILD_NAME)/out/mediatek_linux/output/$(RELEASE_NAME)/rel/obj +export KERNEL_OBJ_ROOT=$(LINUX_SRC)/../.. +else +# *****For system auto build***** +LINUX_SRC=$(KERNEL_OBJ_ROOT)/$(KERNEL_VER)/$(KERNEL_CONFIG)_modules +# overwrite $(OUT_STA_KO) for MT53XX platform +OUT_STA_KO = $(OBJ_ROOT)/third_party/source/wlan/mtk/$(WIFI_TARGET)/$(MODULE_NAME).ko +endif + +include $(LINUX_ROOT)/linux_mts/mak/toolchain.mak +ifeq ($(CROSS_COMPILE),) +CROSS_COMPILE=/mtkoss/gnuarm/vfp_4.5.1_2.6.27_cortex-a9-rhel4/i686/bin/armv7a-mediatek451_001_vfp-linux-gnueabi- +endif +ifeq "$(CC)" "gcc" +CC ?= $(CROSS_COMPILE)gcc +endif +$(warning =============================================) +$(warning wifi driver LINUX_SRC=$(LINUX_SRC)) +$(warning CROSS_COMPILE=$(CROSS_COMPILE)) +$(warning =============================================) + +DRIVER_DIR=$(LINUX_ROOT)/third_party/source/wlan/mtk/$(WIFI_TARGET) + +endif +#- - - - -- - - - - - - - - - +# MT53XX end +#- - - - -- - - - - - - - - - + + +############################################################## +# Compile options +############################################################## +#/***** Common part ******/ + +# Define maximum different channels supported for ieee80211_iface_combination setting. +CFG_NUM_DIFFERENT_CHANNELS_STA=1 +CFG_NUM_DIFFERENT_CHANNELS_P2P=1 + +# Define initial driver running mode. +# 0=RUNNING_P2P_MODE, 1=RUNNING_AP_MODE, 2=RUNNING_DUAL_AP_MODE, 3=RUNNING_P2P_AP_MODE +CFG_DRIVER_INITIAL_RUNNING_MODE=3 + +# Define to enable Android wake_lock +CFG_ENABLE_WAKE_LOCK=0 + +CFG_DEFAULT_DBG_LEVEL=0xF + +CFG_TX_DIRECT_USB=0 + +CFG_RX_DIRECT_USB=0 + +CFG_USB_REQ_TX_DATA_FFA_CNT=6 + +CFG_USB_REQ_TX_DATA_CNT=2 + +CFG_USB_REQ_RX_DATA_CNT=4 + +CFG_ENABLE_EFUSE_MAC_ADDR=1 + +# Report all bss networks to cfg80211 when do p2p scan +CFG_P2P_SCAN_REPORT_ALL_BSS=0 + +# Support to change sta, p2p, ap interface names +# y: enable, n: disable +# eg. insmod wlan_mt76x8_usb.ko sta=wlan p2p=p2p ap=ap +CFG_DRIVER_INF_NAME_CHANGE=n + +# 1: Enable SDIO RX Tasklet De-Aggregation +# 0: Disable (default) +CFG_SDIO_RX_AGG_TASKLET=0 + +#CFG_SUPPORT_SINGLE_SKU_LOCAL_DB=0 + +#/***** Platform dependent part ******/ +ifeq ($(PLATFORM),MT53XX) +CFG_SUPPORT_ROAMING=0 +endif + +# For wpa_supplicant w/o MTK priv lib +# y: enable, n: disable +CFG_ANDROID_AOSP_PRIV_CMD=n + +#/***** Manage configs into compile options ******/ +ifneq ($(CFG_NUM_DIFFERENT_CHANNELS_STA),) +PLATFORM_FLAGS += -DCFG_NUM_DIFFERENT_CHANNELS_STA=$(CFG_NUM_DIFFERENT_CHANNELS_STA) +endif + +ifneq ($(CFG_NUM_DIFFERENT_CHANNELS_P2P),) +PLATFORM_FLAGS += -DCFG_NUM_DIFFERENT_CHANNELS_P2P=$(CFG_NUM_DIFFERENT_CHANNELS_P2P) +endif + +ifneq ($(CFG_DRIVER_INITIAL_RUNNING_MODE),) +PLATFORM_FLAGS += -DCFG_DRIVER_INITIAL_RUNNING_MODE=$(CFG_DRIVER_INITIAL_RUNNING_MODE) +endif + +ifneq ($(CFG_ENABLE_WAKE_LOCK),) +PLATFORM_FLAGS += -DCFG_ENABLE_WAKE_LOCK=$(CFG_ENABLE_WAKE_LOCK) +endif + +ifneq ($(CFG_DEFAULT_DBG_LEVEL),) +PLATFORM_FLAGS += -DCFG_DEFAULT_DBG_LEVEL=$(CFG_DEFAULT_DBG_LEVEL) +endif + +ifneq ($(CFG_TX_DIRECT_USB),) +PLATFORM_FLAGS += -DCFG_TX_DIRECT_USB=$(CFG_TX_DIRECT_USB) +endif + +ifneq ($(CFG_RX_DIRECT_USB),) +PLATFORM_FLAGS += -DCFG_RX_DIRECT_USB=$(CFG_RX_DIRECT_USB) +endif + +ifneq ($(CFG_USB_REQ_TX_DATA_FFA_CNT),) +PLATFORM_FLAGS += -DCFG_USB_REQ_TX_DATA_FFA_CNT=$(CFG_USB_REQ_TX_DATA_FFA_CNT) +endif + +ifneq ($(CFG_USB_REQ_TX_DATA_CNT),) +PLATFORM_FLAGS += -DCFG_USB_REQ_TX_DATA_CNT=$(CFG_USB_REQ_TX_DATA_CNT) +endif + +ifneq ($(CFG_USB_REQ_RX_DATA_CNT),) +PLATFORM_FLAGS += -DCFG_USB_REQ_RX_DATA_CNT=$(CFG_USB_REQ_RX_DATA_CNT) +endif + +ifneq ($(CFG_ENABLE_EFUSE_MAC_ADDR),) +PLATFORM_FLAGS += -DCFG_ENABLE_EFUSE_MAC_ADDR=$(CFG_ENABLE_EFUSE_MAC_ADDR) +endif + +ifeq ($(CFG_DRIVER_INF_NAME_CHANGE), y) +PLATFORM_FLAGS += -DCFG_DRIVER_INF_NAME_CHANGE +endif + +ifneq ($(CFG_P2P_SCAN_REPORT_ALL_BSS),) +PLATFORM_FLAGS += -DCFG_P2P_SCAN_REPORT_ALL_BSS=$(CFG_P2P_SCAN_REPORT_ALL_BSS) +endif + +ifneq ($(CFG_SUPPORT_ROAMING),) +PLATFORM_FLAGS += -DCFG_SUPPORT_ROAMING=$(CFG_SUPPORT_ROAMING) +endif + +ifeq ($(CFG_ANDROID_AOSP_PRIV_CMD), y) +PLATFORM_FLAGS += -DCFG_ANDROID_AOSP_PRIV_CMD +endif + +ifneq ($(CFG_SDIO_RX_AGG_TASKLET),) +PLATFORM_FLAGS += -DCFG_SDIO_RX_AGG_TASKLET=$(CFG_SDIO_RX_AGG_TASKLET) +endif + +############################################################## +# Compile settings +############################################################## + +all: driver + +driver: + +cd $(DRIVER_DIR) && make -C $(LINUX_SRC) M=$(DRIVER_DIR) MODULE_NAME=$(MODULE_NAME) PLATFORM_FLAGS="$(PLATFORM_FLAGS)" modules +ifeq ($(PLATFORM),MT53XX) +ifeq ($(DRIVER_PARTIAL_BUILD), y) + @cd $(DRIVER_DIR) && $(CROSS_COMPILE)strip --strip-unneeded $(MODULE_NAME).ko +else +ifneq ($(ANDROID),true) + if [ ! -d $(THIRDPARTY_LIB_ROOT)/wlan/$(KERNEL_VER_FOR_3RD)/mtk/$(WIFI_TARGET) ]; then \ + mkdir -p $(THIRDPARTY_LIB_ROOT)/wlan/$(KERNEL_VER_FOR_3RD)/mtk/$(WIFI_TARGET)/; \ + fi + cp -f $(OUT_STA_KO) $(THIRDPARTY_LIB_ROOT)/wlan/$(KERNEL_VER_FOR_3RD)/mtk/$(WIFI_TARGET)/$(MODULE_NAME).ko +else +ifeq "$(BUILD_CFG)" "debug" + echo "ANDROID_VERSION=$(ANDROID_VERSION)" + if [ ! -d $(LINUX_ROOT)/../android/$(ANDROID_VERSION)/vendor/mediatek/open/hardware/prebuilt/wifi/$(ANDROID_IC_SETTING)/dbg ]; then \ + mkdir -p $(LINUX_ROOT)/../android/$(ANDROID_VERSION)/vendor/mediatek/open/hardware/prebuilt/wifi/$(ANDROID_IC_SETTING)/dbg; \ + fi + cp -f $(OUT_STA_KO) $(LINUX_ROOT)/../android/$(ANDROID_VERSION)/vendor/mediatek/open/hardware/prebuilt/wifi/$(ANDROID_IC_SETTING)/dbg/$(MODULE_NAME).ko + + if [ -d $(OUTPUT_ROOT)/basic/modules ]; then \ + cp -f $(OUT_STA_KO) $(OUTPUT_ROOT)/basic/modules/wlan.ko; \ + fi +else + if [ ! -d $(LINUX_ROOT)/../android/$(ANDROID_VERSION)/vendor/mediatek/open/hardware/prebuilt/wifi/$(ANDROID_IC_SETTING) ]; then \ + mkdir -p $(LINUX_ROOT)/../android/$(ANDROID_VERSION)/vendor/mediatek/open/hardware/prebuilt/wifi/$(ANDROID_IC_SETTING); \ + fi + cp -f $(OUT_STA_KO) $(LINUX_ROOT)/../android/$(ANDROID_VERSION)/vendor/mediatek/open/hardware/prebuilt/wifi/$(ANDROID_IC_SETTING)/$(MODULE_NAME).ko + + if [ -d $(OUTPUT_ROOT)/basic/modules ]; then \ + cp -f $(OUT_STA_KO) $(OUTPUT_ROOT)/basic/modules/wlan.ko; \ + fi +endif +endif +endif +endif +# @cd $(DRIVER_DIR) && cp $(MODULES_NAME)_$(HIF).ko $(MODULES_NAME).ko + +#common: +# +cd $(COMMON_DIR) && make -C $(LINUX_SRC) M=$(COMMON_DIR) modules +# @cat $(COMMON_DIR)/Module.symvers >> $(LINUX_SRC)/Module.symvers + +clean: driver_clean + +#symvers_clean: driver_clean +# @cp $(LINUX_SRC)/Module.symvers.original $(LINUX_SRC)/Module.symvers + +driver_clean: + cd $(DRIVER_DIR) && make -C $(LINUX_SRC) M=$(DRIVER_DIR) MODULE_NAME=$(MODULE_NAME) clean + if [ -e $(DRIVER_DIR)/$(MODULE_NAME).ko ]; then rm $(DRIVER_DIR)/$(MODULE_NAME).ko; fi; + +#common_clean: +# cd $(COMMON_DIR) && make -C $(LINUX_SRC) M=$(COMMON_DIR) clean + +.PHONY: all clean driver driver_clean + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/Makefile.none b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/Makefile.none new file mode 100644 index 0000000000000000000000000000000000000000..77b8ecd2f6a29649db33c8f1b00d35a3d74e07bb --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/Makefile.none @@ -0,0 +1,217 @@ +# Makefile.none: Makefile for build without linux kernel only gcc +# hif = virtual, empty hif +# Examples: +# - Default=wlan_mt6632_virtual: +# make -f Makefile.none +# - wlan_mt7663_virtual: +# make -f Makefile.none MTK_COMBO_CHIP=MT7663 +# Note: Chip ID must be uppercase. E.g., MT7663 + +src=$(shell pwd) +DRIVER_DIR=$(src) +# compiler choosing +#CROSS_CC = /mtkoss/gcc-arm-none-eabi/6-2017q2 +#CC_INCLUDE := $(CROSS_CC)/arm-none-eabi/include +#CC_BIN := $(CROSS_CC)/bin/ +#BIN_PREFIX := arm-none-eabi- +CC := $(CC_BIN)$(BIN_PREFIX)gcc + +# CFLAGS initial +# by pass undefined reference for linker +#CFLAGS := -Wl,--warn-unresolved-symbols +#CFLAGS := -Wfatal-errors -Wall +#CFLAGS := -Wall +CFLAGS := -Wl,--warn-once +#-Wimplicit -O -Wstrict-aliasing=2 +#CFLAGS += -Wshadow # Local variable is shadow by other local var +# CFG_REMIND_IMPLEMENT: +# flag for change header file prototype to define +# to remind user of driver who port this driver to other os +# need to implement the function +CFLAGS += -DCFG_REMIND_IMPLEMENT +CFLAGS += -DCFG_VIRTUAL_OS + +# default include path for standard library +# refer to the define in Linux Makefile +# LINUX_SRC=/lib/modules/$(shell uname -r)/build +# /lib is server dependent +# /usr/include should be fine +CFLAGS += -I$(CC_INCLUDE) +#CFLAGS += -I/usr/include + +# Build driver default option +hif := none +MTK_COMBO_CHIP := MT6632 + +export MTK_COMBO_CHIP +export CONFIG_MTK_COMBO_PLATFORM=x86 +export CONFIG_MTK_WIFI_ONLY=m +export CONFIG_MTK_COMBO=m +export CONFIG_MTK_COMBO_WIFI=m +export CONFIG_MTK_COMBO_COMM=m +export CONFIG_MTK_COMBO_COMM_UART=m +export CONFIG_MTK_COMBO_COMM_SDIO=m +export CONFIG_MT_WIFI_CHRDEV=m +#export MTK_WLAN_SERVICE_PATH=../../wlan_service/ + +MODULES_NAME := wlan_$(shell echo $(word 1, $(MTK_COMBO_CHIP)) | tr A-Z a-z) + +export CONFIG_MTK_COMBO_WIFI_HIF=$(hif) + +export CONFIG_MTK_COMBO_PLAT_PATH=x86 + +export CONFIG_MTK_SUPPORT_OS=none + +# leverage Makefile for common build option +include Makefile + +############################################################## +# Compile options +############################################################## +#/***** Common part ******/ + +# Define maximum different channels supported for ieee80211_iface_combination setting. +#CFG_NUM_DIFFERENT_CHANNELS_STA=1 +#CFG_NUM_DIFFERENT_CHANNELS_P2P=1 + +# Define initial driver running mode. +# 0=RUNNING_P2P_MODE, 1=RUNNING_AP_MODE, 2=RUNNING_DUAL_AP_MODE, 3=RUNNING_P2P_AP_MODE +#CFG_DRIVER_INITIAL_RUNNING_MODE=3 + +# Define to enable Android wake_lock +#CFG_ENABLE_WAKE_LOCK=0 + +# For wpa_supplicant w/o MTK priv lib +# y: enable, n: disable +CFG_ANDROID_AOSP_PRIV_CMD=n + +#CFG_DEFAULT_DBG_LEVEL=0xF + +CFG_TX_DIRECT_USB=1 + +CFG_RX_DIRECT_USB=1 + +CFG_USB_REQ_TX_DATA_FFA_CNT=10 + +CFG_USB_REQ_TX_DATA_CNT=2 + +CFG_USB_REQ_RX_DATA_CNT=2 + +#CFG_SUPPORT_DFS_MASTER=1 + +#CFG_SUPPORT_SINGLE_SKU_LOCAL_DB=0 + +# Report all bss networks to cfg80211 when do p2p scan +CFG_P2P_SCAN_REPORT_ALL_BSS=0 + +# Support to change sta, p2p, ap interface names +# y: enable, n: disable +# eg. insmod wlan_mt76x8_usb.ko sta=wlan p2p=p2p ap=ap +CFG_DRIVER_INF_NAME_CHANGE=n + +# Support firmware auto roaming +#CFG_SUPPORT_ROAMING=0 + +ifeq ($(CFG_ANDROID_AOSP_PRIV_CMD), y) +PLATFORM_FLAGS += -DCFG_ANDROID_AOSP_PRIV_CMD +endif + +# 1: Enable SDIO RX Tasklet De-Aggregation +# 0: Disable (default) +CFG_SDIO_RX_AGG_TASKLET=0 + +#/***** Manage configs into compile options ******/ +ifneq ($(CFG_NUM_DIFFERENT_CHANNELS_STA),) +PLATFORM_FLAGS += -DCFG_NUM_DIFFERENT_CHANNELS_STA=$(CFG_NUM_DIFFERENT_CHANNELS_STA) +endif + +ifneq ($(CFG_NUM_DIFFERENT_CHANNELS_P2P),) +PLATFORM_FLAGS += -DCFG_NUM_DIFFERENT_CHANNELS_P2P=$(CFG_NUM_DIFFERENT_CHANNELS_P2P) +endif + +ifneq ($(CFG_DRIVER_INITIAL_RUNNING_MODE),) +PLATFORM_FLAGS += -DCFG_DRIVER_INITIAL_RUNNING_MODE=$(CFG_DRIVER_INITIAL_RUNNING_MODE) +endif + +ifneq ($(CFG_ENABLE_WAKE_LOCK),) +PLATFORM_FLAGS += -DCFG_ENABLE_WAKE_LOCK=$(CFG_ENABLE_WAKE_LOCK) +endif + +ifneq ($(CFG_DEFAULT_DBG_LEVEL),) +PLATFORM_FLAGS += -DCFG_DEFAULT_DBG_LEVEL=$(CFG_DEFAULT_DBG_LEVEL) +endif + +ifneq ($(CFG_TX_DIRECT_USB),) +PLATFORM_FLAGS += -DCFG_TX_DIRECT_USB=$(CFG_TX_DIRECT_USB) +endif + +ifneq ($(CFG_RX_DIRECT_USB),) +PLATFORM_FLAGS += -DCFG_RX_DIRECT_USB=$(CFG_RX_DIRECT_USB) +endif + +ifneq ($(CFG_USB_REQ_TX_DATA_FFA_CNT),) +PLATFORM_FLAGS += -DCFG_USB_REQ_TX_DATA_FFA_CNT=$(CFG_USB_REQ_TX_DATA_FFA_CNT) +endif + +ifneq ($(CFG_USB_REQ_TX_DATA_CNT),) +PLATFORM_FLAGS += -DCFG_USB_REQ_TX_DATA_CNT=$(CFG_USB_REQ_TX_DATA_CNT) +endif + +ifneq ($(CFG_USB_REQ_RX_DATA_CNT),) +PLATFORM_FLAGS += -DCFG_USB_REQ_RX_DATA_CNT=$(CFG_USB_REQ_RX_DATA_CNT) +endif + +ifneq ($(CFG_SUPPORT_ROAMING),) +PLATFORM_FLAGS += -DCFG_SUPPORT_ROAMING=$(CFG_SUPPORT_ROAMING) +endif + +ifneq ($(CFG_SUPPORT_DFS_MASTER),) +PLATFORM_FLAGS += -DCFG_SUPPORT_DFS_MASTER=$(CFG_SUPPORT_DFS_MASTER) +endif + +ifneq ($(CFG_SUPPORT_SINGLE_SKU_LOCAL_DB),) +PLATFORM_FLAGS += -DCFG_SUPPORT_SINGLE_SKU_LOCAL_DB=$(CFG_SUPPORT_SINGLE_SKU_LOCAL_DB) +endif + +ifeq ($(CFG_DRIVER_INF_NAME_CHANGE), y) +PLATFORM_FLAGS += -DCFG_DRIVER_INF_NAME_CHANGE +endif + +ifneq ($(CFG_P2P_SCAN_REPORT_ALL_BSS),) +PLATFORM_FLAGS += -DCFG_P2P_SCAN_REPORT_ALL_BSS=$(CFG_P2P_SCAN_REPORT_ALL_BSS) +endif + +ifneq ($(CFG_SDIO_RX_AGG_TASKLET),) +PLATFORM_FLAGS += -DCFG_SDIO_RX_AGG_TASKLET=$(CFG_SDIO_RX_AGG_TASKLET) +endif + +ifeq ($(CONFIG_MTK_COMBO_PLATFORM), x86) +PLATFORM_FLAGS += -DCFG_BUILD_X86_PLATFORM +endif + +CFLAGS += $(ccflags-y) +CFLAGS += $(PLATFORM_FLAGS) + +OBJS = $($(MODULE_NAME)-objs) +TARGET = $(MODULES_NAME)_$(hif) + +$(info flags: $(CFLAGS)) +$(info CC: $(CC)) +$(info target: $(TARGET)) + +REBUILDABLES = $(OBJS) $(TARGET) + +all : $(TARGET) + @echo build pass + +$(TARGET) : $(OBJS) + @${CC} $(OBJS) $(CFLAGS) -o $@ +%.o : %.c + @echo [CC] $@ + @$(CC) -g -o $@ -c $< $(CFLAGS) + +clean : + @rm -f $(REBUILDABLES) + @echo clean + +.PHONY: clean all diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/Makefile.openwrt b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/Makefile.openwrt new file mode 100644 index 0000000000000000000000000000000000000000..cefa9742fde411fefe097c3bd2f6992590960ed4 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/Makefile.openwrt @@ -0,0 +1,654 @@ +# --------------------------------------------------- +# OS option +# --------------------------------------------------- +os=$(CONFIG_MTK_SUPPORT_OS) + +ifeq ($(os),) +os=linux +endif + +ifeq ($(os), none) +ccflags-y += -I/usr/include/ +ccflags-y += -DCFG_VIRTUAL_OS +ccflags-y += -DCFG_REMIND_IMPLEMENT +endif + +$(info os option: $(os)) +# --------------------------------------------------- +# ALPS Setting +# --------------------------------------------------- +ifneq ($(KERNEL_OUT),) + ccflags-y += -imacros $(KERNEL_OUT)/include/generated/autoconf.h +endif + +ifeq ($(KBUILD_MODPOST_FAIL_ON_WARNINGS),) + # Force build fail on modpost warning + KBUILD_MODPOST_FAIL_ON_WARNINGS=y +endif + +DRIVER_BUILD_DATE=$(shell date +%Y%m%d%H%M%S) +ccflags-y += -DDRIVER_BUILD_DATE='"$(DRIVER_BUILD_DATE)"' +# --------------------------------------------------- +# Compile Options +# --------------------------------------------------- + +#Bring up Openwrt Platform ==================================================== +ifeq ($(CONFIG_SUPPORT_OPENWRT),y) +ifeq ($(hif),) + hif=pcie +endif +WIFI_DRV_PATH := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))/.. +CONFIG_MTK_COMBO_WIFI_HIF=$(hif) +else +ifeq ($(CONFIG_DEFAULTS_KERNEL_4_4),y) +WIFI_DRV_PATH = drivers/net/wireless/mediatek +else +WIFI_DRV_PATH = drivers/net/wireless +endif +endif + +ccflags-y := -I$(WIFI_DRV_PATH)/gen4m/include \ + -I$(WIFI_DRV_PATH)/gen4m/os \ + -I$(WIFI_DRV_PATH)/gen4m/os/linux/include \ + -I$(WIFI_DRV_PATH)/gen4m/include/nic \ + -I$(WIFI_DRV_PATH)/gen4m/include/mgmt \ + -I$(WIFI_DRV_PATH)/gen4m/include/chips \ + -I$(WIFI_DRV_PATH)/gen4m/include/dvt \ + +MODULE_NAME = gen4m +SRC_DIR = ../gen4m + +ifeq ($(CONFIG_SUPPORT_OPENWRT),y) +ccflags-y += -DCONFIG_SUPPORT_OPENWRT +obj-m += $(MODULE_NAME).o +else +obj-$(CONFIG_GEN4M_SUPPORT) += $(MODULE_NAME).o +endif +#============================================================================== + +WLAN_CHIP_LIST:=-UMT6620 -UMT6628 -UMT5931 -UMT6630 -UMT6632 -UMT7663 -UCONNAC -UCONNAC2X2 -UUT_TEST_MODE -UMT7915 -USOC3_0 -UMT7961 +# '-D' and '-U' options are processed in the order they are given on the command line. +# All '-imacros file' and '-include file' options are processed after all '-D' and '-U' options. +ccflags-y += $(WLAN_CHIP_LIST) + +ifeq ($(MTK_COMBO_CHIP),) +MTK_COMBO_CHIP = MT7915 +endif + +$(info $$MTK_PLATFORM is [${MTK_PLATFORM}]) +$(info $$WLAN_CHIP_ID is [${WLAN_CHIP_ID}]) + +ifeq ($(WLAN_CHIP_ID),) +WLAN_CHIP_ID=$(word 1, $(MTK_COMBO_CHIP)) +endif + +ccflags-y += -DCFG_SUPPORT_DEBUG_FS=0 +ccflags-y += -DWLAN_INCLUDE_PROC +ccflags-y += -DCFG_SUPPORT_AGPS_ASSIST=0 +ccflags-y += -DCFG_SUPPORT_TSF_USING_BOOTTIME=1 +ccflags-y += -DARP_MONITER_ENABLE=1 +ccflags-y += -Werror +#ccflags-y:=$(filter-out -U$(WLAN_CHIP_ID),$(ccflags-y)) +#ccflags-y += -DLINUX -D$(WLAN_CHIP_ID) +#workaround: also needed for none LINUX system +# because some of common part code is surrounded with this flag +ccflags-y += -DLINUX + +ifneq ($(filter MT6632,$(MTK_COMBO_CHIP)),) +ccflags-y:=$(filter-out -UMT6632,$(ccflags-y)) +ccflags-y += -DMT6632 +endif + +ifneq ($(filter MT7668,$(MTK_COMBO_CHIP)),) +ccflags-y:=$(filter-out -UMT7668,$(ccflags-y)) +ccflags-y += -DMT7668 +endif + +ifneq ($(filter MT7663,$(MTK_COMBO_CHIP)),) +ccflags-y:=$(filter-out -UMT7663,$(ccflags-y)) +ccflags-y += -DMT7663 +endif + +ifneq ($(filter CONNAC,$(MTK_COMBO_CHIP)),) +ccflags-y:=$(filter-out -UCONNAC,$(ccflags-y)) +ccflags-y += -DCONNAC +endif + +ifneq ($(filter CONNAC2X2,$(MTK_COMBO_CHIP)),) +ccflags-y:=$(filter-out -UCONNAC2X2,$(ccflags-y)) +ccflags-y += -DCONNAC2X2 +endif + +ifneq ($(findstring MT7915,$(MTK_COMBO_CHIP)),) +ccflags-y:=$(filter-out -UMT7915,$(ccflags-y)) +ccflags-y += -DMT7915 +CONFIG_MTK_WIFI_CONNAC2X=y +CONFIG_MTK_WIFI_11AX_SUPPORT=y +CONFIG_MTK_WIFI_TWT_SUPPORT=y +endif + +ifneq ($(findstring 3_0,$(MTK_COMBO_CHIP)),) +ccflags-y:=$(filter-out -USOC3_0,$(ccflags-y)) +ccflags-y += -DSOC3_0 +CONFIG_MTK_WIFI_CONNAC2X=y +CONFIG_MTK_WIFI_11AX_SUPPORT=y +CONFIG_MTK_WIFI_TWT_SUPPORT=y +endif + +ifneq ($(findstring MT7961,$(MTK_COMBO_CHIP)),) +ccflags-y:=$(filter-out -UMT7961,$(ccflags-y)) +ccflags-y += -DMT7961 +CONFIG_MTK_WIFI_CONNAC2X=y +CONFIG_MTK_WIFI_11AX_SUPPORT=y +CONFIG_MTK_WIFI_TWT_SUPPORT=y +endif + +ifeq ($(CONFIG_MTK_WIFI_CONNAC2X), y) + ccflags-y += -DCFG_SUPPORT_CONNAC2X=1 +else + ccflags-y += -DCFG_SUPPORT_CONNAC2X=0 +endif + +ifeq ($(CONFIG_MTK_WIFI_11AX_SUPPORT), y) + ccflags-y += -DCFG_SUPPORT_802_11AX=1 +else + ccflags-y += -DCFG_SUPPORT_802_11AX=0 +endif + +ifeq ($(CONFIG_MTK_WIFI_TWT_SUPPORT), y) + ccflags-y += -DCFG_SUPPORT_TWT=1 +else + ccflags-y += -DCFG_SUPPORT_TWT=0 +endif + +ifeq ($(WIFI_ENABLE_GCOV), y) +GCOV_PROFILE := y +endif + +ifeq ($(MTK_ANDROID_WMT), y) + ccflags-y += -DCFG_MTK_ANDROID_WMT=1 +else ifneq ($(filter MT6632,$(MTK_COMBO_CHIP)),) + ccflags-y += -DCFG_MTK_ANDROID_WMT=1 +else + ccflags-y += -DCFG_MTK_ANDROID_WMT=0 +endif + +ifeq ($(MTK_ANDROID_EMI), y) + ccflags-y += -DCFG_MTK_ANDROID_EMI=1 +else + ccflags-y += -DCFG_MTK_ANDROID_EMI=0 +endif + +ifneq ($(WIFI_IP_SET),) + ccflags-y += -DCFG_WIFI_IP_SET=$(WIFI_IP_SET) +else + ccflags-y += -DCFG_WIFI_IP_SET=1 +endif + +ifneq ($(filter MTK_WCN_REMOVE_KERNEL_MODULE,$(KBUILD_SUBDIR_CCFLAGS)),) + ccflags-y += -DCFG_BUILT_IN_DRIVER=1 +else + ccflags-y += -DCFG_BUILT_IN_DRIVER=0 +endif + +ifneq ($(findstring UT_TEST_MODE,$(MTK_COMBO_CHIP)),) +ccflags-y:=$(filter-out -UUT_TEST_MODE,$(ccflags-y)) +ccflags-y += -DUT_TEST_MODE +endif + +CONFIG_MTK_WIFI_MCC_SUPPORT=y +ifeq ($(CONFIG_MTK_WIFI_MCC_SUPPORT), y) + ccflags-y += -DCFG_SUPPORT_CHNL_CONFLICT_REVISE=0 +else + ccflags-y += -DCFG_SUPPORT_CHNL_CONFLICT_REVISE=1 +endif + +ifeq ($(CONFIG_MTK_AEE_FEATURE), y) + ccflags-y += -DCFG_SUPPORT_AEE=1 +else + ccflags-y += -DCFG_SUPPORT_AEE=0 +endif + +# Disable ASSERT() for user load, enable for others +ifneq ($(TARGET_BUILD_VARIANT),user) + ccflags-y += -DBUILD_QA_DBG=1 +else + ccflags-y += -DBUILD_QA_DBG=0 +endif + +ifeq ($(CONFIG_MTK_COMBO_WIFI),y) + ccflags-y += -DCFG_WPS_DISCONNECT=1 +endif + +ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), sdio) + ccflags-y += -D_HIF_SDIO=1 +else ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), pcie) + ccflags-y += -D_HIF_PCIE=1 +else ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), usb) + ccflags-y += -D_HIF_USB=1 +else ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), axi) + ccflags-y += -D_HIF_AXI=1 +else ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), ut) + # Increase frame size to 2048 because of 'cfg80211_connect_result' exceed stack size + ccflags-y += -D_HIF_UT=1 -Wno-unused-function -Wno-unused-variable -Wframe-larger-than=2048 +else ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), none) + ccflags-y += -D_HIF_NONE=1 +else + $(error Unsuppoted HIF=$(CONFIG_MTK_COMBO_WIFI_HIF)!!) +endif + +ifeq ($(CONFIG_MTK_WIFI_POWER_ON_DOWNLOAD_EMI_ROM_PATCH), y) + ccflags-y += -DCFG_POWER_ON_DOWNLOAD_EMI_ROM_PATCH=1 +else + ccflags-y += -DCFG_POWER_ON_DOWNLOAD_EMI_ROM_PATCH=0 +endif + +ifeq ($(CONFIG_MTK_WIFI_DOWNLOAD_DYN_MEMORY_MAP), y) + ccflags-y += -DCFG_DOWNLOAD_DYN_MEMORY_MAP=1 +else + ccflags-y += -DCFG_DOWNLOAD_DYN_MEMORY_MAP=0 +endif + +ifeq ($(CONFIG_MTK_WIFI_ROM_PATCH_NO_SEM_CTRL), y) + ccflags-y += -DCFG_ROM_PATCH_NO_SEM_CTRL=1 +else + ccflags-y += -DCFG_ROM_PATCH_NO_SEM_CTRL=0 +endif + +ifneq ($(CFG_CFG80211_VERSION),) +VERSION_STR = $(subst \",,$(subst ., , $(subst -, ,$(subst v,,$(CFG_CFG80211_VERSION))))) +$(info VERSION_STR=$(VERSION_STR)) +X = $(firstword $(VERSION_STR)) +Y = $(word 2 ,$(VERSION_STR)) +Z = $(word 3 ,$(VERSION_STR)) +VERSION := $(shell echo "$$(( $X * 65536 + $Y * 256 + $Z))" ) +ccflags-y += -DCFG_CFG80211_VERSION=$(VERSION) +$(info DCFG_CFG80211_VERSION=$(VERSION)) +endif + + +ifeq ($(CONFIG_MTK_PASSPOINT_R2_SUPPORT), y) + ccflags-y += -DCFG_SUPPORT_PASSPOINT=1 + ccflags-y += -DCFG_HS20_DEBUG=1 + ccflags-y += -DCFG_ENABLE_GTK_FRAME_FILTER=1 +else + ccflags-y += -DCFG_SUPPORT_PASSPOINT=0 + ccflags-y += -DCFG_HS20_DEBUG=0 + ccflags-y += -DCFG_ENABLE_GTK_FRAME_FILTER=0 +endif + +MTK_MET_PROFILING_SUPPORT = yes +ifeq ($(MTK_MET_PROFILING_SUPPORT), yes) + ccflags-y += -DCFG_MET_PACKET_TRACE_SUPPORT=1 +else + ccflags-y += -DCFG_MET_PACKET_TRACE_SUPPORT=0 +endif + +MTK_MET_TAG_SUPPORT = no +ifeq ($(MTK_MET_TAG_SUPPORT), yes) + ccflags-y += -DMET_USER_EVENT_SUPPORT + ccflags-y += -DCFG_MET_TAG_SUPPORT=1 +else + ccflags-y += -DCFG_MET_TAG_SUPPORT=0 +endif + +ifeq ($(CONFIG_MTK_TC10_FEATURE), y) + ccflags-y += -DCFG_TC10_FEATURE=1 +else + ccflags-y += -DCFG_TC10_FEATURE=0 +endif + +ifeq ($(CONFIG_MTK_TC1_FEATURE), y) + ccflags-y += -I$(srctree)/drivers/misc/mediatek/tc1_interface + ccflags-y += -DCFG_TC1_FEATURE=1 +else + ccflags-y += -DCFG_TC1_FEATURE=0 +endif + +ccflags-y += -DDBG=0 +ccflags-y += -I$(src)/os -I$(src)/os/$(os)/include +ccflags-y += -I$(src)/include -I$(src)/include/nic -I$(src)/include/mgmt -I$(src)/include/chips +ifeq ($(CFG_SUPPORT_WIFI_SYSDVT), 1) +ccflags-y += -I$(src)/include/dvt +endif +ccflags-y += -I$(srctree)/drivers/misc/mediatek/base/power/include/ +ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/ +ccflags-y += -I$(srctree)/drivers/misc/mediatek/performance/include/ +ccflags-y += -I$(srctree)/drivers/misc/mediatek/emi/$(MTK_PLATFORM) +ccflags-y += -I$(srctree)/drivers/misc/mediatek/emi/submodule +ccflags-y += -I$(srctree)/drivers/devfreq/ +ccflags-y += -I$(srctree)/net + +ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), sdio) +ccflags-y += -I$(src)/os/$(os)/hif/sdio/include +else ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), pcie) +ccflags-y += -I$(src)/os/$(os)/hif/common/include +ccflags-y += -I$(src)/os/$(os)/hif/pcie/include +ifneq ($(findstring 3_0,$(MTK_COMBO_CHIP)),) +ccflags-y += -I$(src)/include/chips/coda/soc3_0 +endif +else ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), axi) +ccflags-y += -I$(src)/os/$(os)/hif/common/include +ccflags-y += -I$(src)/os/$(os)/hif/axi/include +else ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), usb) +ccflags-y += -I$(src)/os/$(os)/hif/usb/include +else ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), ut) +ccflags-y += -I$(src)/test -I$(src)/test/lib/include -I$(src)/test/testcases -I$(src)/test/lib/hif +else ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), none) +ccflags-y += -I$(src)/os/$(os)/hif/none/include +endif + +ifneq ($(PLATFORM_FLAGS), ) + ccflags-y += $(PLATFORM_FLAGS) +endif + +ifeq ($(CONFIG_MTK_WIFI_ONLY),$(filter $(CONFIG_MTK_WIFI_ONLY),m y)) +obj-$(CONFIG_MTK_WIFI_ONLY) += $(MODULE_NAME).o +else +obj-$(CONFIG_MTK_COMBO_WIFI) += $(MODULE_NAME).o +#obj-y += $(MODULE_NAME).o +endif + +ifeq ($(CONFIG_WLAN_DRV_BUILD_IN),y) +$(warning $(MODULE_NAME) build-in boot.img) +obj-y += $(MODULE_NAME).o +else +$(warning $(MODULE_NAME) is kernel module) +obj-m += $(MODULE_NAME).o +endif + +# --------------------------------------------------- +# Directory List +# --------------------------------------------------- +COMMON_DIR := common/ +OS_DIR := os/$(os)/ +HIF_COMMON_DIR := $(OS_DIR)hif/common/ +ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), sdio) +HIF_DIR := os/$(os)/hif/sdio/ +else ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), pcie) +HIF_DIR := os/$(os)/hif/pcie/ +else ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), axi) +HIF_DIR := os/$(os)/hif/axi/ +else ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), usb) +HIF_DIR := os/$(os)/hif/usb/ +else ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), ut) +HIF_DIR := test/lib/hif/ +else ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), none) +HIF_DIR := os/$(os)/hif/none/ +endif +NIC_DIR := nic/ +MGMT_DIR := mgmt/ +CHIPS := chips/ +CHIPS_CMM := $(CHIPS)common/ + +ifneq ($(MTK_PLATFORM),) +PLAT_DIR := os/$(os)/plat/$(MTK_PLATFORM)/ +endif +SYSDVT_DIR := dvt/ + +# --------------------------------------------------- +# Objects List +# --------------------------------------------------- + +COMMON_OBJS := $(COMMON_DIR)dump.o \ + $(COMMON_DIR)wlan_lib.o \ + $(COMMON_DIR)wlan_oid.o \ + $(COMMON_DIR)wlan_bow.o \ + $(COMMON_DIR)debug.o + +NIC_OBJS := $(NIC_DIR)nic.o \ + $(NIC_DIR)nic_tx.o \ + $(NIC_DIR)nic_txd_v1.o \ + $(NIC_DIR)nic_rxd_v1.o \ + $(NIC_DIR)nic_rx.o \ + $(NIC_DIR)nic_pwr_mgt.o \ + $(NIC_DIR)nic_rate.o \ + $(NIC_DIR)cmd_buf.o \ + $(NIC_DIR)que_mgt.o \ + $(NIC_DIR)nic_cmd_event.o \ + $(NIC_DIR)nic_umac.o + +ifeq ($(os), none) +OS_OBJS := $(OS_DIR)gl_dependent.o \ + $(OS_DIR)gl_init.o \ + $(OS_DIR)gl_kal.o \ + $(OS_DIR)gl_ate_agent.o \ + $(OS_DIR)gl_qa_agent.o +else +OS_OBJS := $(OS_DIR)gl_init.o \ + $(OS_DIR)gl_kal.o \ + $(OS_DIR)gl_bow.o \ + $(OS_DIR)gl_wext.o \ + $(OS_DIR)gl_wext_priv.o \ + $(OS_DIR)gl_ate_agent.o \ + $(OS_DIR)gl_qa_agent.o \ + $(OS_DIR)gl_hook_api.o \ + $(OS_DIR)gl_rst.o \ + $(OS_DIR)gl_cfg80211.o \ + $(OS_DIR)gl_proc.o \ + $(OS_DIR)gl_vendor.o \ + $(OS_DIR)platform.o +endif + +MGMT_OBJS := $(MGMT_DIR)ais_fsm.o \ + $(MGMT_DIR)aaa_fsm.o \ + $(MGMT_DIR)assoc.o \ + $(MGMT_DIR)auth.o \ + $(MGMT_DIR)bss.o \ + $(MGMT_DIR)cnm.o \ + $(MGMT_DIR)cnm_timer.o \ + $(MGMT_DIR)cnm_mem.o \ + $(MGMT_DIR)hem_mbox.o \ + $(MGMT_DIR)mib.o \ + $(MGMT_DIR)privacy.o \ + $(MGMT_DIR)rate.o \ + $(MGMT_DIR)rlm.o \ + $(MGMT_DIR)rlm_domain.o \ + $(MGMT_DIR)reg_rule.o \ + $(MGMT_DIR)rlm_obss.o \ + $(MGMT_DIR)rlm_protection.o \ + $(MGMT_DIR)rsn.o \ + $(MGMT_DIR)saa_fsm.o \ + $(MGMT_DIR)scan.o \ + $(MGMT_DIR)scan_fsm.o \ + $(MGMT_DIR)scan_cache.o \ + $(MGMT_DIR)swcr.o \ + $(MGMT_DIR)roaming_fsm.o \ + $(MGMT_DIR)tkip_mic.o \ + $(MGMT_DIR)hs20.o \ + $(MGMT_DIR)tdls.o \ + $(MGMT_DIR)wnm.o \ + $(MGMT_DIR)qosmap.o \ + $(MGMT_DIR)ap_selection.o \ + $(MGMT_DIR)wmm.o + +# --------------------------------------------------- +# Chips Objects List +# --------------------------------------------------- +MGMT_OBJS += $(MGMT_DIR)stats.o + + +CHIPS_OBJS += $(CHIPS_CMM)cmm_asic_connac.o +CHIPS_OBJS += $(CHIPS_CMM)dbg_connac.o +ifeq ($(CONFIG_MTK_WIFI_CONNAC2X), y) +CHIPS_OBJS += $(CHIPS_CMM)dbg_connac2x.o +endif + +ifeq ($(CONFIG_MTK_WIFI_CONNAC2X), y) +CHIPS_OBJS += $(CHIPS_CMM)cmm_asic_connac2x.o +NIC_OBJS += $(NIC_DIR)nic_ext_cmd_event.o \ + $(NIC_DIR)nic_txd_v2.o \ + $(NIC_DIR)nic_rxd_v2.o +endif +CHIPS_OBJS += $(CHIPS_CMM)fw_dl.o + +ifneq ($(filter MT6632,$(MTK_COMBO_CHIP)),) +CHIPS_OBJS += $(CHIPS)mt6632/mt6632.o +endif +ifneq ($(filter MT7668,$(MTK_COMBO_CHIP)),) +CHIPS_OBJS += $(CHIPS)mt7668/mt7668.o +endif +ifneq ($(filter MT7663,$(MTK_COMBO_CHIP)),) +CHIPS_OBJS += $(CHIPS)mt7663/mt7663.o +endif +ifneq ($(filter CONNAC,$(MTK_COMBO_CHIP)),) +CHIPS_OBJS += $(CHIPS)connac/connac.o +endif +ifneq ($(filter CONNAC2X2,$(MTK_COMBO_CHIP)),) +CHIPS_OBJS += $(CHIPS)connac2x2/connac2x2.o +endif +ifneq ($(findstring MT7915,$(MTK_COMBO_CHIP)),) +CHIPS_OBJS += $(CHIPS)mt7915/mt7915.o +CHIPS_OBJS += $(CHIPS)mt7915/dbg_mt7915.o +endif +ifneq ($(findstring 3_0,$(MTK_COMBO_CHIP)),) +CHIPS_OBJS += $(CHIPS)soc3_0/soc3_0.o +endif +ifneq ($(findstring MT7961,$(MTK_COMBO_CHIP)),) +CHIPS_OBJS += $(CHIPS)mt7961/mt7961.o +endif + +# --------------------------------------------------- +# P2P Objects List +# --------------------------------------------------- + +COMMON_OBJS += $(COMMON_DIR)wlan_p2p.o + +NIC_OBJS += $(NIC_DIR)p2p_nic.o + +ifneq ($(os), none) +OS_OBJS += $(OS_DIR)gl_p2p.o \ + $(OS_DIR)gl_p2p_cfg80211.o \ + $(OS_DIR)gl_p2p_init.o \ + $(OS_DIR)gl_p2p_kal.o +endif + +MGMT_OBJS += $(MGMT_DIR)p2p_dev_fsm.o\ + $(MGMT_DIR)p2p_dev_state.o\ + $(MGMT_DIR)p2p_role_fsm.o\ + $(MGMT_DIR)p2p_role_state.o\ + $(MGMT_DIR)p2p_func.o\ + $(MGMT_DIR)p2p_scan.o\ + $(MGMT_DIR)p2p_ie.o\ + $(MGMT_DIR)p2p_rlm.o\ + $(MGMT_DIR)p2p_assoc.o\ + $(MGMT_DIR)p2p_bss.o\ + $(MGMT_DIR)p2p_rlm_obss.o\ + $(MGMT_DIR)p2p_fsm.o + +MGMT_OBJS += $(MGMT_DIR)wapi.o + +# --------------------------------------------------- +# HE Objects List +# --------------------------------------------------- + +COMMON_OBJS += $(COMMON_DIR)wlan_he.o + +ifeq ($(CONFIG_MTK_WIFI_11AX_SUPPORT), y) +MGMT_OBJS += $(MGMT_DIR)he_ie.o \ + $(MGMT_DIR)he_rlm.o +endif + +ifeq ($(CONFIG_MTK_WIFI_TWT_SUPPORT), y) +MGMT_OBJS += $(MGMT_DIR)twt_req_fsm.o \ + $(MGMT_DIR)twt.o \ + $(MGMT_DIR)twt_planner.o +endif + +ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), sdio) +HIF_OBJS := $(HIF_DIR)arm.o \ + $(HIF_DIR)sdio.o \ + $(HIF_DIR)hal_api.o \ + $(HIF_DIR)sdio_test_driver_core.o \ + $(HIF_DIR)sdio_test_driver_ops.o +else ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), pcie) +HIF_OBJS := $(HIF_COMMON_DIR)hal_pdma.o \ + $(HIF_COMMON_DIR)kal_pdma.o \ + $(HIF_COMMON_DIR)dbg_pdma.o \ + $(HIF_DIR)pcie.o +else ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), axi) +HIF_OBJS := $(HIF_COMMON_DIR)hal_pdma.o \ + $(HIF_COMMON_DIR)kal_pdma.o \ + $(HIF_COMMON_DIR)dbg_pdma.o \ + $(HIF_DIR)axi.o +else ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), usb) +HIF_OBJS := $(HIF_DIR)usb.o \ + $(HIF_DIR)hal_api.o +else ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), ut) +HIF_OBJS := $(HIF_DIR)ut.o \ + $(HIF_DIR)hal_api.o +else ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF), none) +HIF_OBJS := $(HIF_DIR)none.o +endif +# --------------------------------------------------- +# Platform Objects List +# --------------------------------------------------- +ifneq ($(MTK_PLATFORM),) + +PLAT_PRIV_C = $(src)/$(PLAT_DIR)plat_priv.c + +# search path (out of kernel tree) +IS_EXIST_PLAT_PRIV_C := $(wildcard $(PLAT_PRIV_C)) +# search path (build-in kernel tree) +IS_EXIST_PLAT_PRIV_C += $(wildcard $(srctree)/$(PLAT_PRIV_C)) + +ifneq ($(strip $(IS_EXIST_PLAT_PRIV_C)),) +PLAT_OBJS := $(PLAT_DIR)plat_priv.o +$(MODULE_NAME)-objs += $(PLAT_OBJS) +endif +endif + +# --------------------------------------------------- +# System Dvt Objects List +# --------------------------------------------------- +ifeq ($(CFG_SUPPORT_WIFI_SYSDVT), 1) +SYSDVT_OBJS += $(SYSDVT_DIR)dvt_common.o + +ifeq ($(CFG_SUPPORT_DMASHDL_SYSDVT), 1) +SYSDVT_OBJS += $(SYSDVT_DIR)dvt_dmashdl.o +endif +endif + +# --------------------------------------------------- +# Service git List +# --------------------------------------------------- +SERVICE_DIR := wlan_service/ + +ifneq ($(findstring wlan_service,$(MTK_WLAN_SERVICE_PATH)),) +MTK_WLAN_SERVICE=yes +SERVICE_DIR := $(MTK_WLAN_SERVICE_PATH) +$(info SERVICE_DIR is [{$(MTK_WLAN_SERVICE_PATH)}]) +endif + +ifeq ($(MTK_WLAN_SERVICE), yes) +ccflags-y += -DCONFIG_WLAN_SERVICE=1 +ccflags-y += -DCONFIG_TEST_ENGINE_OFFLOAD=1 +ccflags-y += -I$(src)/$(SERVICE_DIR)include +ccflags-y += -I$(src)/$(SERVICE_DIR)service/include +ccflags-y += -I$(src)/$(SERVICE_DIR)glue/osal/include +ccflags-y += -I$(src)/$(SERVICE_DIR)glue/hal/include +$(info $$CCFLAG is [{$(ccflags-y)}]) +SERVICE_OBJS := $(SERVICE_DIR)agent/agent.o \ + $(SERVICE_DIR)service/service_test.o \ + $(SERVICE_DIR)service/test_engine.o \ + $(SERVICE_DIR)glue/osal/gen4m/sys_adaption_gen4m.o \ + $(SERVICE_DIR)glue/osal/gen4m/net_adaption_gen4m.o \ + $(SERVICE_DIR)glue/hal/gen4m/operation_gen4m.o +$(MODULE_NAME)-objs += $(SERVICE_OBJS) +$(info $$MTK_WLAN_SERVICE is [{$(SERVICE_OBJS)}]) +else +ccflags-y += -DCONFIG_WLAN_SERVICE=0 +ccflags-y += -DCONFIG_TEST_ENGINE_OFFLOAD=0 +endif + +$(MODULE_NAME)-objs += $(COMMON_OBJS) +$(MODULE_NAME)-objs += $(NIC_OBJS) +$(MODULE_NAME)-objs += $(OS_OBJS) +$(MODULE_NAME)-objs += $(HIF_OBJS) +$(MODULE_NAME)-objs += $(MGMT_OBJS) +$(MODULE_NAME)-objs += $(CHIPS_OBJS) +$(MODULE_NAME)-objs += $(SYSDVT_OBJS) + +ifneq ($(findstring UT_TEST_MODE,$(MTK_COMBO_CHIP)),) +include $(src)/test/ut.make +endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/Makefile.x86 b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/Makefile.x86 new file mode 100644 index 0000000000000000000000000000000000000000..6d5423f7b0b063ba3f87cc0b1ca5a9506d54b860 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/Makefile.x86 @@ -0,0 +1,218 @@ +# Makefile.x86: Makefile for Linux PC +# You can build specific .ko name by assiging the "MTK_COMBO_CHIP" and "hif" parameters +# hif = pcie or sdio or usb +# Examples: +# - Default=wlan_mt6632_pcie.ko: +# make -f Makefile.x86 +# - wlan_mt7663_usb.ko: +# make -f Makefile.x86 MTK_COMBO_CHIP=MT7663 hif=usb +# Note: Chip ID must be uppercase. E.g., MT7663 + +LINUX_SRC=/lib/modules/$(shell uname -r)/build + +export CONFIG_MTK_COMBO_PLATFORM=x86 +export MTK_COMBO_CHIP=MT6632 + +PWD=$(shell pwd) +DRIVER_DIR=$(PWD) + +export CONFIG_MTK_WIFI_ONLY=m +export CONFIG_MTK_COMBO=m +export CONFIG_MTK_COMBO_WIFI=m +export CONFIG_MTK_COMBO_COMM=m +export CONFIG_MTK_COMBO_COMM_UART=m +export CONFIG_MTK_COMBO_COMM_SDIO=m +export CONFIG_MT_WIFI_CHRDEV=m +ifneq (,$(wildcard ../../wlan_service/)) +export MTK_WLAN_SERVICE_PATH=../../wlan_service/ +endif +ifneq ($(BACKPORTED_KERNEL_VERSION),) +export CFG_CFG80211_VERSION ?= $(BACKPORTED_KERNEL_VERSION) +endif + +# pcie | sdio | usb | ut +ifeq ($(hif),) + hif=pcie +endif + +MODULES_NAME := wlan_$(shell echo $(word 1, $(MTK_COMBO_CHIP)) | tr A-Z a-z) + +export CONFIG_MTK_COMBO_WIFI_HIF=$(hif) + +export CONFIG_MTK_COMBO_PLAT_PATH=x86 + +#need to support these 3 CONFIG_ in Android.mk::Begin +export CONFIG_MTK_WIFI_POWER_ON_DOWNLOAD_EMI_ROM_PATCH=$(wifi_pwron_emi_patch_dl) + +export CONFIG_MTK_WIFI_DOWNLOAD_DYN_MEMORY_MAP=$(wifi_dl_dyn_mem_map) + +export CONFIG_MTK_WIFI_ROM_PATCH_NO_SEM_CTRL=$(wifi_rom_patch_no_sem_ctrl) +#need to support these 3 CONFIG_ in Android.mk::End + +############################################################## +# Compile options +############################################################## +#/***** Common part ******/ + +# Define maximum different channels supported for ieee80211_iface_combination setting. +#CFG_NUM_DIFFERENT_CHANNELS_STA=1 +#CFG_NUM_DIFFERENT_CHANNELS_P2P=1 + +# Define initial driver running mode. +# 0=RUNNING_P2P_MODE, 1=RUNNING_AP_MODE, 2=RUNNING_DUAL_AP_MODE, 3=RUNNING_P2P_AP_MODE +#CFG_DRIVER_INITIAL_RUNNING_MODE=3 + +# Define to enable Android wake_lock +#CFG_ENABLE_WAKE_LOCK=0 + +# For wpa_supplicant w/o MTK priv lib +# y: enable, n: disable +CFG_ANDROID_AOSP_PRIV_CMD=n + +#CFG_DEFAULT_DBG_LEVEL=0xF + +CFG_TX_DIRECT_USB=1 + +CFG_RX_DIRECT_USB=1 + +CFG_USB_REQ_TX_DATA_FFA_CNT=10 + +CFG_USB_REQ_TX_DATA_CNT=2 + +CFG_USB_REQ_RX_DATA_CNT=2 + +CFG_SYS_DVT_SUPPORT=0 + +CFG_SYS_DVT_DMASCHDL_SUPPORT=0 + +#CFG_SUPPORT_DFS_MASTER=1 + +#CFG_SUPPORT_SINGLE_SKU_LOCAL_DB=0 + +# Report all bss networks to cfg80211 when do p2p scan +CFG_P2P_SCAN_REPORT_ALL_BSS=0 + +# Support to change sta, p2p, ap interface names +# y: enable, n: disable +# eg. insmod wlan_mt76x8_usb.ko sta=wlan p2p=p2p ap=ap +CFG_DRIVER_INF_NAME_CHANGE=n + +# Support firmware auto roaming +#CFG_SUPPORT_ROAMING=0 + +ifeq ($(CFG_ANDROID_AOSP_PRIV_CMD), y) +PLATFORM_FLAGS += -DCFG_ANDROID_AOSP_PRIV_CMD +endif + +# 1: Enable SDIO RX Tasklet De-Aggregation +# 0: Disable (default) +CFG_SDIO_RX_AGG_TASKLET=0 + +# CFG_WIFI_WORKAROUND_HWITS00012836_WTBL_SEARCH_FAIL +ifeq ($(MTK_COMBO_CHIP), soc3_0) +CFG_WIFI_WORKAROUND_HWITS00012836_WTBL_SEARCH_FAIL=1 +endif + +#/***** Manage configs into compile options ******/ +ifneq ($(CFG_DFS_CHSW_FORCE_BW20),) +PLATFORM_FLAGS += -DCFG_DFS_CHSW_FORCE_BW20=$(CFG_DFS_CHSW_FORCE_BW20) +endif + +ifneq ($(CFG_NUM_DIFFERENT_CHANNELS_STA),) +PLATFORM_FLAGS += -DCFG_NUM_DIFFERENT_CHANNELS_STA=$(CFG_NUM_DIFFERENT_CHANNELS_STA) +endif + +ifneq ($(CFG_NUM_DIFFERENT_CHANNELS_P2P),) +PLATFORM_FLAGS += -DCFG_NUM_DIFFERENT_CHANNELS_P2P=$(CFG_NUM_DIFFERENT_CHANNELS_P2P) +endif + +ifneq ($(CFG_DRIVER_INITIAL_RUNNING_MODE),) +PLATFORM_FLAGS += -DCFG_DRIVER_INITIAL_RUNNING_MODE=$(CFG_DRIVER_INITIAL_RUNNING_MODE) +endif + +ifneq ($(CFG_ENABLE_WAKE_LOCK),) +PLATFORM_FLAGS += -DCFG_ENABLE_WAKE_LOCK=$(CFG_ENABLE_WAKE_LOCK) +endif + +ifneq ($(CFG_DEFAULT_DBG_LEVEL),) +PLATFORM_FLAGS += -DCFG_DEFAULT_DBG_LEVEL=$(CFG_DEFAULT_DBG_LEVEL) +endif + +ifneq ($(CFG_TX_DIRECT_USB),) +PLATFORM_FLAGS += -DCFG_TX_DIRECT_USB=$(CFG_TX_DIRECT_USB) +endif + +ifneq ($(CFG_RX_DIRECT_USB),) +PLATFORM_FLAGS += -DCFG_RX_DIRECT_USB=$(CFG_RX_DIRECT_USB) +endif + +ifneq ($(CFG_USB_REQ_TX_DATA_FFA_CNT),) +PLATFORM_FLAGS += -DCFG_USB_REQ_TX_DATA_FFA_CNT=$(CFG_USB_REQ_TX_DATA_FFA_CNT) +endif + +ifneq ($(CFG_USB_REQ_TX_DATA_CNT),) +PLATFORM_FLAGS += -DCFG_USB_REQ_TX_DATA_CNT=$(CFG_USB_REQ_TX_DATA_CNT) +endif + +ifneq ($(CFG_USB_REQ_RX_DATA_CNT),) +PLATFORM_FLAGS += -DCFG_USB_REQ_RX_DATA_CNT=$(CFG_USB_REQ_RX_DATA_CNT) +endif + +ifneq ($(CFG_SUPPORT_ROAMING),) +PLATFORM_FLAGS += -DCFG_SUPPORT_ROAMING=$(CFG_SUPPORT_ROAMING) +endif + +ifneq ($(CFG_SUPPORT_DFS_MASTER),) +PLATFORM_FLAGS += -DCFG_SUPPORT_DFS_MASTER=$(CFG_SUPPORT_DFS_MASTER) +endif + +ifneq ($(CFG_SUPPORT_SINGLE_SKU_LOCAL_DB),) +PLATFORM_FLAGS += -DCFG_SUPPORT_SINGLE_SKU_LOCAL_DB=$(CFG_SUPPORT_SINGLE_SKU_LOCAL_DB) +endif + +ifeq ($(CFG_DRIVER_INF_NAME_CHANGE), y) +PLATFORM_FLAGS += -DCFG_DRIVER_INF_NAME_CHANGE +endif + +ifneq ($(CFG_SYS_DVT_SUPPORT),) +ifeq ($(CFG_SYS_DVT_SUPPORT), 0) +# Check dependency +CFG_SYS_DVT_DMASCHDL_SUPPORT=0 +endif +PLATFORM_FLAGS += -DCFG_SUPPORT_WIFI_SYSDVT=$(CFG_SYS_DVT_SUPPORT) +export CFG_SUPPORT_WIFI_SYSDVT=$(CFG_SYS_DVT_SUPPORT) +ifneq ($(CFG_SYS_DVT_DMASCHDL_SUPPORT),) +PLATFORM_FLAGS += -DCFG_SUPPORT_DMASHDL_SYSDVT=$(CFG_SYS_DVT_DMASCHDL_SUPPORT) +export CFG_SUPPORT_DMASHDL_SYSDVT=$(CFG_SYS_DVT_DMASCHDL_SUPPORT) +endif +endif + +ifneq ($(CFG_P2P_SCAN_REPORT_ALL_BSS),) +PLATFORM_FLAGS += -DCFG_P2P_SCAN_REPORT_ALL_BSS=$(CFG_P2P_SCAN_REPORT_ALL_BSS) +endif + +ifneq ($(CFG_SDIO_RX_AGG_TASKLET),) +PLATFORM_FLAGS += -DCFG_SDIO_RX_AGG_TASKLET=$(CFG_SDIO_RX_AGG_TASKLET) +endif + +# CFG_WIFI_WORKAROUND_HWITS00012836_WTBL_SEARCH_FAIL +ifeq ($(MTK_COMBO_CHIP), soc3_0) +PLATFORM_FLAGS += -DCFG_WIFI_WORKAROUND_HWITS00012836_WTBL_SEARCH_FAIL=$(CFG_WIFI_WORKAROUND_HWITS00012836_WTBL_SEARCH_FAIL) +endif + +ifeq ($(CONFIG_MTK_COMBO_PLATFORM), x86) +PLATFORM_FLAGS += -DCFG_BUILD_X86_PLATFORM +endif + +all: driver + +driver: + +cd $(DRIVER_DIR) && make -C $(LINUX_SRC) M=$(DRIVER_DIR) PLATFORM_FLAGS="$(PLATFORM_FLAGS)" modules + @cd $(DRIVER_DIR) && cp $(MODULES_NAME)_$(hif).ko $(MODULES_NAME).ko + +clean: driver_clean + +driver_clean: + cd $(DRIVER_DIR) && make -C $(LINUX_SRC) M=$(DRIVER_DIR) clean + +.PHONY: all clean driver driver_clean diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/common/cmm_asic_connac.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/common/cmm_asic_connac.c new file mode 100644 index 0000000000000000000000000000000000000000..1a416cb3f7b089958df3ec175ff7906c46907cd2 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/common/cmm_asic_connac.c @@ -0,0 +1,1868 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/*! \file connac.c + * \brief Internal driver stack will export the required procedures + * here for GLUE Layer. + * + * This file contains all routines which are exported from MediaTek 802.11 + * Wireless LAN driver stack to GLUE Layer. + */ + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" + + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +#if defined(_HIF_USB) +/* + * USB Endpoint OUT/DMA Scheduler Group Mapping (HW Define) + * EP#4 / Group0 (DATA) + * EP#5 / Group1 (DATA) + * EP#6 / Group2 (DATA) + * EP#7 / Group3 (DATA) + * EP#9 / Group4 (DATA) + * EP#8 / Group15 (CMD) + */ +uint8_t arAcQIdx2GroupId[MAC_TXQ_NUM] = { + GROUP0_INDEX, /* MAC_TXQ_AC0_INDEX */ + GROUP1_INDEX, /* MAC_TXQ_AC1_INDEX */ + GROUP2_INDEX, /* MAC_TXQ_AC2_INDEX */ + GROUP3_INDEX, /* MAC_TXQ_AC3_INDEX */ + + GROUP4_INDEX, /* MAC_TXQ_AC10_INDEX */ + GROUP4_INDEX, /* MAC_TXQ_AC11_INDEX */ + GROUP4_INDEX, /* MAC_TXQ_AC12_INDEX */ + GROUP4_INDEX, /* MAC_TXQ_AC13_INDEX */ + + GROUP4_INDEX, /* MAC_TXQ_AC20_INDEX */ + GROUP4_INDEX, /* MAC_TXQ_AC21_INDEX */ + GROUP4_INDEX, /* MAC_TXQ_AC22_INDEX */ + GROUP4_INDEX, /* MAC_TXQ_AC23_INDEX */ + + GROUP4_INDEX, /* MAC_TXQ_AC30_INDEX */ + GROUP4_INDEX, /* MAC_TXQ_AC31_INDEX */ + GROUP4_INDEX, /* MAC_TXQ_AC32_INDEX */ + GROUP4_INDEX, /* MAC_TXQ_AC33_INDEX */ + + GROUP4_INDEX, /* MAC_TXQ_ALTX_0_INDEX */ + GROUP4_INDEX, /* MAC_TXQ_BMC_0_INDEX */ + GROUP4_INDEX, /* MAC_TXQ_BCN_0_INDEX */ + GROUP4_INDEX, /* MAC_TXQ_PSMP_0_INDEX */ + + GROUP5_INDEX, /* Reserved */ + GROUP5_INDEX, /* Reserved */ + GROUP5_INDEX, /* Reserved */ + GROUP5_INDEX, /* Reserved */ + + GROUP5_INDEX, /* Reserved */ + GROUP5_INDEX, /* Reserved */ +}; +#endif /* _HIF_USB */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ +#if defined(_HIF_USB) +#define USB_DMA_SHDL_GROUP_DEF_SEQUENCE_ORDER 0xFFFEFFFF +#define USB_DMA_SHDL_GROUP_DEF_MIN_QUOTA 0x3 +#define USB_DMA_SHDL_GROUP_DEF_MAX_QUOTA 0x1FF +#define USB_ACCESS_RETRY_LIMIT 1 +#endif /* _HIF_USB */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +void asicCapInit(IN struct ADAPTER *prAdapter) +{ + struct GLUE_INFO *prGlueInfo; + struct mt66xx_chip_info *prChipInfo; + struct BUS_INFO *prBusInfo = NULL; + + ASSERT(prAdapter); + + prGlueInfo = prAdapter->prGlueInfo; + prChipInfo = prAdapter->chip_info; + prBusInfo = prChipInfo->bus_info; + + prChipInfo->u2HifTxdSize = 0; + prChipInfo->u2TxInitCmdPort = 0; + prChipInfo->u2TxFwDlPort = 0; + prChipInfo->fillHifTxDesc = NULL; + prChipInfo->u4ExtraTxByteCount = 0; + prChipInfo->asicFillInitCmdTxd = asicFillInitCmdTxd; + prChipInfo->asicFillCmdTxd = asicFillCmdTxd; + prChipInfo->u2CmdTxHdrSize = sizeof(struct WIFI_CMD); + prChipInfo->u2RxSwPktBitMap = RXM_RXD_PKT_TYPE_SW_BITMAP; + prChipInfo->u2RxSwPktEvent = RXM_RXD_PKT_TYPE_SW_EVENT; + prChipInfo->u2RxSwPktFrame = RXM_RXD_PKT_TYPE_SW_FRAME; + asicInitTxdHook(prChipInfo->prTxDescOps); + asicInitRxdHook(prChipInfo->prRxDescOps); +#if (CFG_SUPPORT_MSP == 1) + prChipInfo->asicRxProcessRxvforMSP = asicRxProcessRxvforMSP; +#endif /* CFG_SUPPORT_MSP == 1 */ + prChipInfo->asicRxGetRcpiValueFromRxv = asicRxGetRcpiValueFromRxv; +#if (CFG_SUPPORT_PERF_IND == 1) + prChipInfo->asicRxPerfIndProcessRXV = asicRxPerfIndProcessRXV; +#endif +#if (CFG_CHIP_RESET_SUPPORT == 1) && (CFG_WMT_RESET_API_SUPPORT == 0) + prChipInfo->rst_L0_notify_step2 = conn1_rst_L0_notify_step2; +#endif +#if CFG_SUPPORT_WIFI_SYSDVT + prAdapter->u2TxTest = TX_TEST_UNLIMITIED; + prAdapter->u2TxTestCount = 0; + prAdapter->ucTxTestUP = TX_TEST_UP_UNDEF; +#endif /* CFG_SUPPORT_WIFI_SYSDVT */ + + switch (prGlueInfo->u4InfType) { +#if defined(_HIF_PCIE) || defined(_HIF_AXI) + case MT_DEV_INF_PCIE: + case MT_DEV_INF_AXI: + prChipInfo->u2TxInitCmdPort = TX_RING_FWDL_IDX_3; + prChipInfo->u2TxFwDlPort = TX_RING_FWDL_IDX_3; + prChipInfo->ucPacketFormat = TXD_PKT_FORMAT_TXD; + prChipInfo->u4HifDmaShdlBaseAddr = PCIE_HIF_DMASHDL_BASE; + + HAL_MCR_WR(prAdapter, CONN_HIF_ON_IRQ_ENA, BIT(0)); + break; +#endif /* _HIF_PCIE */ +#if defined(_HIF_USB) + case MT_DEV_INF_USB: + prChipInfo->u2HifTxdSize = USB_HIF_TXD_LEN; + prChipInfo->fillHifTxDesc = fillUsbHifTxDesc; + prChipInfo->u2TxInitCmdPort = USB_DATA_BULK_OUT_EP8; + prChipInfo->u2TxFwDlPort = USB_DATA_BULK_OUT_EP4; + prChipInfo->ucPacketFormat = TXD_PKT_FORMAT_TXD_PAYLOAD; + prChipInfo->u4ExtraTxByteCount = + EXTRA_TXD_SIZE_FOR_TX_BYTE_COUNT; + prChipInfo->u4HifDmaShdlBaseAddr = USB_HIF_DMASHDL_BASE; + if (prBusInfo->DmaShdlInit) + prBusInfo->DmaShdlInit(prAdapter); + asicUdmaTxTimeoutEnable(prAdapter); + asicUdmaRxFlush(prAdapter, FALSE); + asicPdmaHifReset(prAdapter, TRUE); + break; +#endif /* _HIF_USB */ +#if defined(_HIF_SDIO) + case MT_DEV_INF_SDIO: + prChipInfo->ucPacketFormat = TXD_PKT_FORMAT_TXD_PAYLOAD; + prChipInfo->u4ExtraTxByteCount = + EXTRA_TXD_SIZE_FOR_TX_BYTE_COUNT; + break; +#endif /* _HIF_SDIO */ + default: + break; + } +} + +uint32_t asicGetFwDlInfo(struct ADAPTER *prAdapter, + char *pcBuf, int i4TotalLen) +{ + struct TAILER_COMMON_FORMAT_T *prComTailer; + uint32_t u4Offset = 0; + uint8_t aucBuf[32]; + + prComTailer = &prAdapter->rVerInfo.rCommonTailer; + + kalMemZero(aucBuf, sizeof(aucBuf)); + kalMemCopy(aucBuf, prComTailer->aucRamVersion, + sizeof(prComTailer->aucRamVersion)); + u4Offset += snprintf(pcBuf + u4Offset, i4TotalLen - u4Offset, + "Tailer Ver[%u:%u] %s (%s) info %u:E%u\n", + prComTailer->ucFormatVer, + prComTailer->ucFormatFlag, + aucBuf, + prComTailer->aucRamBuiltDate, + prComTailer->ucChipInfo, + prComTailer->ucEcoCode + 1); + + if (prComTailer->ucFormatFlag) { + u4Offset += snprintf(pcBuf + u4Offset, i4TotalLen - u4Offset, + "Release manifest: %s\n", + prAdapter->rVerInfo.aucReleaseManifest); + } + return u4Offset; +} + +uint32_t asicGetChipID(struct ADAPTER *prAdapter) +{ + struct mt66xx_chip_info *prChipInfo; + uint32_t u4ChipID = 0; + + ASSERT(prAdapter); + prChipInfo = prAdapter->chip_info; + ASSERT(prChipInfo); + + /* Compose chipID from chip ip version + * + * BIT(30, 31) : Coding type, 00: compact, 01: index table + * BIT(24, 29) : IP config (6 bits) + * BIT(8, 23) : IP version + * BIT(0, 7) : A die info + */ + + u4ChipID = (0x0 << 30) | + ((prChipInfo->u4ChipIpConfig & 0x3F) << 24) | + ((prChipInfo->u4ChipIpVersion & 0xF0000000) >> 8) | + ((prChipInfo->u4ChipIpVersion & 0x000F0000) >> 0) | + ((prChipInfo->u4ChipIpVersion & 0x00000F00) << 4) | + ((prChipInfo->u4ChipIpVersion & 0x0000000F) << 8) | + (prChipInfo->u2ADieChipVersion & 0xFF); + + log_dbg(HAL, INFO, "ChipID = [0x%08x]\n", u4ChipID); + return u4ChipID; +} + +void asicEnableFWDownload(IN struct ADAPTER *prAdapter, + IN u_int8_t fgEnable) +{ + struct GLUE_INFO *prGlueInfo; + + ASSERT(prAdapter); + + prGlueInfo = prAdapter->prGlueInfo; + + switch (prGlueInfo->u4InfType) { +#if defined(_HIF_PCIE) || defined(_HIF_AXI) + case MT_DEV_INF_PCIE: + case MT_DEV_INF_AXI: + { + union WPDMA_GLO_CFG_STRUCT GloCfg; + + kalDevRegRead(prGlueInfo, WPDMA_GLO_CFG, &GloCfg.word); + + GloCfg.field_conn.bypass_dmashdl_txring3 = fgEnable; + + kalDevRegWrite(prGlueInfo, WPDMA_GLO_CFG, GloCfg.word); + } + break; +#endif /* _HIF_PCIE */ + +#if defined(_HIF_USB) + case MT_DEV_INF_USB: + { + uint32_t u4Value = 0; + + ASSERT(prAdapter); + + HAL_MCR_RD(prAdapter, CONNAC_UDMA_TX_QSEL, &u4Value); + + if (fgEnable) + u4Value |= FW_DL_EN; + else + u4Value &= ~FW_DL_EN; + + HAL_MCR_WR(prAdapter, CONNAC_UDMA_TX_QSEL, u4Value); + } + break; +#endif /* _HIF_USB */ + + default: + break; + } +} + +void fillNicTxDescAppend(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + OUT uint8_t *prTxDescBuffer) +{ + struct mt66xx_chip_info *prChipInfo = prAdapter->chip_info; + union HW_MAC_TX_DESC_APPEND *prHwTxDescAppend; + + /* Fill TxD append */ + prHwTxDescAppend = (union HW_MAC_TX_DESC_APPEND *) + prTxDescBuffer; + kalMemZero(prHwTxDescAppend, prChipInfo->txd_append_size); +} + +void fillNicTxDescAppendWithCR4(IN struct ADAPTER + *prAdapter, IN struct MSDU_INFO *prMsduInfo, + OUT uint8_t *prTxDescBuffer) +{ + struct mt66xx_chip_info *prChipInfo = prAdapter->chip_info; + union HW_MAC_TX_DESC_APPEND *prHwTxDescAppend; + + /* Fill TxD append */ + prHwTxDescAppend = (union HW_MAC_TX_DESC_APPEND *) + prTxDescBuffer; + kalMemZero(prHwTxDescAppend, prChipInfo->txd_append_size); + prHwTxDescAppend->CR4_APPEND.u2PktFlags = + HIF_PKT_FLAGS_CT_INFO_APPLY_TXD; + prHwTxDescAppend->CR4_APPEND.ucBssIndex = + prMsduInfo->ucBssIndex; +} + +void fillTxDescAppendByHost(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, IN uint16_t u4MsduId, + IN phys_addr_t rDmaAddr, IN uint32_t u4Idx, + IN u_int8_t fgIsLast, + OUT uint8_t *pucBuffer) +{ + union HW_MAC_TX_DESC_APPEND *prHwTxDescAppend; + struct TXD_PTR_LEN *prPtrLen; + + prHwTxDescAppend = (union HW_MAC_TX_DESC_APPEND *) ( + pucBuffer + NIC_TX_DESC_LONG_FORMAT_LENGTH); + prHwTxDescAppend->CONNAC_APPEND.au2MsduId[u4Idx] = + u4MsduId | TXD_MSDU_ID_VLD; + prPtrLen = &prHwTxDescAppend->CONNAC_APPEND.arPtrLen[u4Idx >> 1]; + if ((u4Idx & 1) == 0) { + prPtrLen->u4Ptr0 = rDmaAddr; + prPtrLen->u2Len0 = prMsduInfo->u2FrameLength | TXD_LEN_ML; + if (fgIsLast) + prPtrLen->u2Len0 |= TXD_LEN_AL; + } else { + prPtrLen->u4Ptr1 = rDmaAddr; + prPtrLen->u2Len1 = prMsduInfo->u2FrameLength | TXD_LEN_ML; + if (fgIsLast) + prPtrLen->u2Len1 |= TXD_LEN_AL; + } +} + +void fillTxDescAppendByHostV2(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, IN uint16_t u4MsduId, + IN phys_addr_t rDmaAddr, IN uint32_t u4Idx, + IN u_int8_t fgIsLast, + OUT uint8_t *pucBuffer) +{ + union HW_MAC_TX_DESC_APPEND *prHwTxDescAppend; + struct TXD_PTR_LEN *prPtrLen; + uint64_t u8Addr = (uint64_t)rDmaAddr; + + prHwTxDescAppend = (union HW_MAC_TX_DESC_APPEND *) + (pucBuffer + NIC_TX_DESC_LONG_FORMAT_LENGTH); + prHwTxDescAppend->CONNAC_APPEND.au2MsduId[u4Idx] = + u4MsduId | TXD_MSDU_ID_VLD; + prPtrLen = &prHwTxDescAppend->CONNAC_APPEND.arPtrLen[u4Idx >> 1]; + + if ((u4Idx & 1) == 0) { + prPtrLen->u4Ptr0 = (uint32_t)u8Addr; + prPtrLen->u2Len0 = + (prMsduInfo->u2FrameLength & TXD_LEN_MASK_V2) | + ((u8Addr >> TXD_ADDR2_OFFSET) & TXD_ADDR2_MASK); + prPtrLen->u2Len0 |= TXD_LEN_ML_V2; + } else { + prPtrLen->u4Ptr1 = (uint32_t)u8Addr; + prPtrLen->u2Len1 = + (prMsduInfo->u2FrameLength & TXD_LEN_MASK_V2) | + ((u8Addr >> TXD_ADDR2_OFFSET) & TXD_ADDR2_MASK); + prPtrLen->u2Len1 |= TXD_LEN_ML_V2; + } +} + +void fillTxDescAppendByCR4(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, IN uint16_t u4MsduId, + IN phys_addr_t rDmaAddr, IN uint32_t u4Idx, + IN u_int8_t fgIsLast, + OUT uint8_t *pucBuffer) +{ + union HW_MAC_TX_DESC_APPEND *prHwTxDescAppend; + + prHwTxDescAppend = (union HW_MAC_TX_DESC_APPEND *) + (pucBuffer + NIC_TX_DESC_LONG_FORMAT_LENGTH); + prHwTxDescAppend->CR4_APPEND.u2MsduToken = u4MsduId; + prHwTxDescAppend->CR4_APPEND.ucBufNum = u4Idx + 1; + prHwTxDescAppend->CR4_APPEND.au4BufPtr[u4Idx] = rDmaAddr; + prHwTxDescAppend->CR4_APPEND.au2BufLen[u4Idx] = + prMsduInfo->u2FrameLength; +} + +void fillTxDescTxByteCount(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + void *prTxDesc) +{ + struct mt66xx_chip_info *prChipInfo; + uint32_t u4TxByteCount = NIC_TX_DESC_LONG_FORMAT_LENGTH; + + ASSERT(prAdapter); + ASSERT(prMsduInfo); + ASSERT(prTxDesc); + + prChipInfo = prAdapter->chip_info; + u4TxByteCount += prMsduInfo->u2FrameLength; + + if (prMsduInfo->ucPacketType == TX_PACKET_TYPE_DATA) + u4TxByteCount += prChipInfo->u4ExtraTxByteCount; + + /* Calculate Tx byte count */ + HAL_MAC_TX_DESC_SET_TX_BYTE_COUNT( + (struct HW_MAC_TX_DESC *)prTxDesc, u4TxByteCount); +} + +void fillTxDescTxByteCountWithCR4(IN struct ADAPTER + *prAdapter, IN struct MSDU_INFO *prMsduInfo, + void *prTxDesc) +{ + struct mt66xx_chip_info *prChipInfo; + uint32_t u4TxByteCount = NIC_TX_DESC_LONG_FORMAT_LENGTH; + + ASSERT(prAdapter); + ASSERT(prMsduInfo); + ASSERT(prTxDesc); + + prChipInfo = prAdapter->chip_info; + u4TxByteCount += prMsduInfo->u2FrameLength; + + if (prMsduInfo->ucPacketType == TX_PACKET_TYPE_DATA) + u4TxByteCount += prChipInfo->txd_append_size; + + /* Calculate Tx byte count */ + HAL_MAC_TX_DESC_SET_TX_BYTE_COUNT( + (struct HW_MAC_TX_DESC *)prTxDesc, u4TxByteCount); +} + +#if defined(_HIF_PCIE) || defined(_HIF_AXI) +void asicPcieDmaShdlInit(IN struct ADAPTER *prAdapter) +{ + uint32_t u4BaseAddr, u4MacVal = 0; + struct mt66xx_chip_info *prChipInfo; + struct BUS_INFO *prBusInfo; + uint32_t u4FreePageCnt = 0; + + ASSERT(prAdapter); + + prChipInfo = prAdapter->chip_info; + prBusInfo = prChipInfo->bus_info; + u4BaseAddr = prChipInfo->u4HifDmaShdlBaseAddr; + + HAL_MCR_RD(prAdapter, + CONN_HIF_DMASHDL_PACKET_MAX_SIZE(u4BaseAddr), &u4MacVal); + u4MacVal &= ~(PLE_PKT_MAX_SIZE_MASK | PSE_PKT_MAX_SIZE_MASK); + u4MacVal |= PLE_PKT_MAX_SIZE_NUM(0x1); + u4MacVal |= PSE_PKT_MAX_SIZE_NUM(0x18); /* 0x18 * 128 = 3K */ + HAL_MCR_WR(prAdapter, + CONN_HIF_DMASHDL_PACKET_MAX_SIZE(u4BaseAddr), u4MacVal); + + u4MacVal = + (CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP1_REFILL_DISABLE_MASK | + CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP2_REFILL_DISABLE_MASK | + CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP3_REFILL_DISABLE_MASK | + CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP4_REFILL_DISABLE_MASK | + CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP5_REFILL_DISABLE_MASK | + CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP6_REFILL_DISABLE_MASK | + CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP7_REFILL_DISABLE_MASK | + CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP8_REFILL_DISABLE_MASK | + CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP9_REFILL_DISABLE_MASK | + CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP10_REFILL_DISABLE_MASK | + CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP11_REFILL_DISABLE_MASK | + CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP12_REFILL_DISABLE_MASK | + CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP13_REFILL_DISABLE_MASK | + CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP14_REFILL_DISABLE_MASK | + CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP15_REFILL_DISABLE_MASK); + /* Always use group 1 if we support 2 Data TxRing */ + if (prBusInfo->tx_ring0_data_idx != prBusInfo->tx_ring1_data_idx) { + u4MacVal &= + ~CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP1_REFILL_DISABLE_MASK; + } + HAL_MCR_WR(prAdapter, + CONN_HIF_DMASHDL_REFILL_CONTROL(u4BaseAddr), u4MacVal); + + /* Always use group 1 if we support 2 TxRing for data */ + if (prBusInfo->tx_ring0_data_idx != prBusInfo->tx_ring1_data_idx) { + /* HW has no gruantee to switch Quota at runtime */ + /* Just separate equally. */ + HAL_MCR_RD(prAdapter, + CONN_HIF_DMASHDL_STATUS_RD(u4BaseAddr), &u4FreePageCnt); + u4FreePageCnt = (u4FreePageCnt & DMASHDL_FREE_PG_CNT_MASK) + >> DMASHDL_FREE_PG_CNT_OFFSET; + u4MacVal = DMASHDL_MIN_QUOTA_NUM(0x3); + u4MacVal |= DMASHDL_MAX_QUOTA_NUM(0xFFF); + HAL_MCR_WR(prAdapter, + CONN_HIF_DMASHDL_GROUP0_CTRL(u4BaseAddr), u4MacVal); + HAL_MCR_WR(prAdapter, + CONN_HIF_DMASHDL_GROUP1_CTRL(u4BaseAddr), u4MacVal); + /* Wmm1: group 1, others group 0 */ + HAL_MCR_WR(prAdapter, + CONN_HIF_DMASHDL_Q_MAP0(u4BaseAddr), 0x11110000); + } else { + u4MacVal = DMASHDL_MIN_QUOTA_NUM(0x3); + u4MacVal |= DMASHDL_MAX_QUOTA_NUM(0xFFF); + HAL_MCR_WR(prAdapter, + CONN_HIF_DMASHDL_GROUP0_CTRL(u4BaseAddr), u4MacVal); + u4MacVal = 0; + HAL_MCR_WR(prAdapter, + CONN_HIF_DMASHDL_GROUP1_CTRL(u4BaseAddr), u4MacVal); + } + + u4MacVal = 0; + HAL_MCR_WR(prAdapter, + CONN_HIF_DMASHDL_GROUP2_CTRL(u4BaseAddr), u4MacVal); + HAL_MCR_WR(prAdapter, + CONN_HIF_DMASHDL_GROUP3_CTRL(u4BaseAddr), u4MacVal); + HAL_MCR_WR(prAdapter, + CONN_HIF_DMASHDL_GROUP4_CTRL(u4BaseAddr), u4MacVal); + HAL_MCR_WR(prAdapter, + CONN_HIF_DMASHDL_GROUP5_CTRL(u4BaseAddr), u4MacVal); + HAL_MCR_WR(prAdapter, + CONN_HIF_DMASHDL_GROUP6_CTRL(u4BaseAddr), u4MacVal); + HAL_MCR_WR(prAdapter, + CONN_HIF_DMASHDL_GROUP7_CTRL(u4BaseAddr), u4MacVal); + HAL_MCR_WR(prAdapter, + CONN_HIF_DMASHDL_GROUP8_CTRL(u4BaseAddr), u4MacVal); + HAL_MCR_WR(prAdapter, + CONN_HIF_DMASHDL_GROUP9_CTRL(u4BaseAddr), u4MacVal); + HAL_MCR_WR(prAdapter, + CONN_HIF_DMASHDL_GROUP10_CTRL(u4BaseAddr), u4MacVal); + HAL_MCR_WR(prAdapter, + CONN_HIF_DMASHDL_GROUP11_CTRL(u4BaseAddr), u4MacVal); + HAL_MCR_WR(prAdapter, + CONN_HIF_DMASHDL_GROUP12_CTRL(u4BaseAddr), u4MacVal); + HAL_MCR_WR(prAdapter, + CONN_HIF_DMASHDL_GROUP13_CTRL(u4BaseAddr), u4MacVal); + HAL_MCR_WR(prAdapter, + CONN_HIF_DMASHDL_GROUP14_CTRL(u4BaseAddr), u4MacVal); +} + +void asicPdmaLoopBackConfig(struct GLUE_INFO *prGlueInfo, u_int8_t fgEnable) +{ + union WPDMA_GLO_CFG_STRUCT GloCfg; + uint32_t word = 1; + + kalDevRegRead(prGlueInfo, WPDMA_GLO_CFG, &GloCfg.word); + + GloCfg.field_conn.bypass_dmashdl_txring3 = 1; + GloCfg.field_conn.pdma_addr_ext_en = 0; + GloCfg.field_conn.omit_rx_info = 1; + GloCfg.field_conn.omit_tx_info = 1; + GloCfg.field_conn.multi_dma_en = 0; + GloCfg.field_conn.pdma_addr_ext_en = 0; + GloCfg.field_conn.tx_dma_en = 1; + GloCfg.field_conn.rx_dma_en = 1; + GloCfg.field_conn.multi_dma_en = 0; + + kalDevRegWrite(prGlueInfo, WPDMA_FIFO_TEST_MOD, word); + kalDevRegWrite(prGlueInfo, WPDMA_GLO_CFG, GloCfg.word); +} + +#if CFG_MTK_MCIF_WIFI_SUPPORT +static void configPdmaRxRingThreshold(struct GLUE_INFO *prGlueInfo) +{ + uint32_t u4OldVal = 0, u4NewVal = 0; + + if (!prGlueInfo) + return; + + /* Config RX ring0 & ring1 */ + kalDevRegRead(prGlueInfo, WPDMA_PAUSE_RX_Q_TH10, &u4OldVal); + u4NewVal += (WPDMA_PAUSE_RX_Q_TH0 << WPDMA_PAUSE_RX_Q_TH0_SHFT); + u4NewVal += (WPDMA_PAUSE_RX_Q_TH1 << WPDMA_PAUSE_RX_Q_TH1_SHFT); + kalDevRegWrite(prGlueInfo, WPDMA_PAUSE_RX_Q_TH10, u4NewVal); + DBGLOG(HAL, TRACE, "RX_RING[0, 1] TH(0x%x) from 0x%x to 0x%x\n", + WPDMA_PAUSE_RX_Q_TH10, u4OldVal, u4NewVal); + + /* Config RX ring2 & ring3 */ + u4OldVal = u4NewVal = 0; + kalDevRegRead(prGlueInfo, WPDMA_PAUSE_RX_Q_TH32, &u4OldVal); + u4NewVal += (WPDMA_PAUSE_RX_Q_TH2 << WPDMA_PAUSE_RX_Q_TH2_SHFT); + u4NewVal += (WPDMA_PAUSE_RX_Q_TH3 << WPDMA_PAUSE_RX_Q_TH3_SHFT); + kalDevRegWrite(prGlueInfo, WPDMA_PAUSE_RX_Q_TH32, u4NewVal); + DBGLOG(HAL, TRACE, "RX_RING[2, 3] TH(0x%x) from 0x%x to 0x%x\n", + WPDMA_PAUSE_RX_Q_TH32, u4OldVal, u4NewVal); +} +#endif + +void asicPdmaIntMaskConfig(struct GLUE_INFO *prGlueInfo, + u_int8_t fgEnable) +{ + struct BUS_INFO *prBusInfo = + prGlueInfo->prAdapter->chip_info->bus_info; + union WPDMA_INT_MASK IntMask; + + kalDevRegRead(prGlueInfo, WPDMA_INT_MSK, &IntMask.word); + + if (fgEnable == TRUE) { + IntMask.field.rx_done_0 = 1; + IntMask.field.rx_done_1 = 1; + IntMask.field.tx_done = + BIT(prBusInfo->tx_ring_fwdl_idx) | + BIT(prBusInfo->tx_ring_cmd_idx) | + BIT(prBusInfo->tx_ring0_data_idx) | + BIT(prBusInfo->tx_ring1_data_idx); + IntMask.field_conn.tx_coherent = 0; + IntMask.field_conn.rx_coherent = 0; + IntMask.field_conn.tx_dly_int = 0; + IntMask.field_conn.rx_dly_int = 0; + IntMask.field_conn.mcu2host_sw_int_ena = 1; + } else { + IntMask.field_conn.rx_done_0 = 0; + IntMask.field_conn.rx_done_1 = 0; + IntMask.field_conn.tx_done = 0; + IntMask.field_conn.tx_coherent = 0; + IntMask.field_conn.rx_coherent = 0; + IntMask.field_conn.tx_dly_int = 0; + IntMask.field_conn.rx_dly_int = 0; + IntMask.field_conn.mcu2host_sw_int_ena = 0; + } + + kalDevRegWrite(prGlueInfo, WPDMA_INT_MSK, IntMask.word); +} + +void asicPdmaConfig(struct GLUE_INFO *prGlueInfo, u_int8_t fgEnable, + bool fgResetHif) +{ + struct BUS_INFO *prBusInfo = + prGlueInfo->prAdapter->chip_info->bus_info; + union WPDMA_GLO_CFG_STRUCT GloCfg; + uint32_t u4Val = 0; + + asicPdmaIntMaskConfig(prGlueInfo, fgEnable); + kalDevRegRead(prGlueInfo, WPDMA_GLO_CFG, &GloCfg.word); + + if (fgEnable == TRUE) { + GloCfg.field_conn.tx_dma_en = 1; + GloCfg.field_conn.rx_dma_en = 1; + GloCfg.field_conn.pdma_bt_size = 3; + GloCfg.field_conn.pdma_addr_ext_en = + (prBusInfo->u4DmaMask > 32) ? 1 : 0; + GloCfg.field_conn.tx_wb_ddone = 1; + GloCfg.field_conn.multi_dma_en = 2; + GloCfg.field_conn.fifo_little_endian = 1; + GloCfg.field_conn.clk_gate_dis = 1; + } else { + GloCfg.field_conn.tx_dma_en = 0; + GloCfg.field_conn.rx_dma_en = 0; + } + + kalDevRegWrite(prGlueInfo, WPDMA_GLO_CFG, GloCfg.word); + kalDevRegWrite(prGlueInfo, WPDMA_PAUSE_TX_Q, 0); + kalDevRegWrite(prGlueInfo, MCU2HOST_SW_INT_ENA, + ERROR_DETECT_MASK); + + /* Set PDMA APSRC_ACK CR */ + kalDevRegRead(prGlueInfo, WPDMA_APSRC_ACK_LOCK_SLPPROT, &u4Val); + kalDevRegWrite(prGlueInfo, WPDMA_APSRC_ACK_LOCK_SLPPROT, + u4Val | BIT(4)); + + if (fgEnable) { + kalDevRegWrite(prGlueInfo, WPDMA_PAUSE_TX_Q, 0); +#if CFG_MTK_MCIF_WIFI_SUPPORT + configPdmaRxRingThreshold(prGlueInfo); +#endif + } else { + halWpdmaWaitIdle(prGlueInfo, 100, 1000); + /* Reset DMA Index */ + kalDevRegWrite(prGlueInfo, WPDMA_RST_PTR, 0xFFFFFFFF); +#if CFG_MTK_MCIF_WIFI_SUPPORT + if (fgResetHif) { + halEnableSlpProt(prGlueInfo); + halHifRst(prGlueInfo); + halDisableSlpProt(prGlueInfo); + } +#endif + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is used to update DmaSchdl max quota. + * + * @param prAdapter + * @param u2Port, the TxRing number + * @param u4MaxQuota, the desired max quota for the TxRing. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +uint32_t asicUpdatTxRingMaxQuota(IN struct ADAPTER *prAdapter, + IN uint16_t u2Port, IN uint32_t u4MaxQuota) +{ + struct GLUE_INFO *prGlueInfo; + uint32_t u4BaseAddr, u4GroupIdx; + uint32_t u4MacVal = 0, u4SrcCnt, u4RsvCnt, u4TxRingBitmap = 0; + +#define DMASHDL_MAX_QUOTA (DMASHDL_MAX_QUOTA_MASK >> DMASHDL_MAX_QUOTA_OFFSET) + ASSERT(prAdapter); + if (u4MaxQuota > DMASHDL_MAX_QUOTA) + u4MaxQuota = DMASHDL_MAX_QUOTA; +#undef DMASHDL_MAX_QUOTA + + prGlueInfo = prAdapter->prGlueInfo; + u4BaseAddr = prAdapter->chip_info->u4HifDmaShdlBaseAddr; + + /* The mapping must be equal to CONN_HIF_DMASHDL_Q_MAP0 + * in asicPcieDmaShdlInit. + */ + switch (u2Port) { + case TX_RING_DATA0_IDX_0: + u4GroupIdx = 0; + break; + case TX_RING_DATA1_IDX_1: + u4GroupIdx = 1; + break; + default: + return WLAN_STATUS_NOT_ACCEPTED; + } + + /* Step 1. Pause the TxRing */ + kalDevRegRead(prGlueInfo, WPDMA_PAUSE_TX_Q, &u4TxRingBitmap); + kalDevRegWrite(prGlueInfo, WPDMA_PAUSE_TX_Q, + u4TxRingBitmap | + (BIT(u2Port) << WPDMA_PAUSE_TX_Q_RINGIDX_OFFSET)); + + /* Step 2. Check MaxQuota >= rsv_cnt + src_cnt */ + HAL_MCR_RD(prAdapter, + CONN_HIF_DMASHDL_STATUS_RD_GP0(u4BaseAddr) + 4*u4GroupIdx, + &u4MacVal); + u4SrcCnt = (u4MacVal & DMASHDL_SRC_CNT_MASK) >> DMASHDL_SRC_CNT_OFFSET; + u4RsvCnt = (u4MacVal & DMASHDL_RSV_CNT_MASK) >> DMASHDL_RSV_CNT_OFFSET; + + /* BE CAREFUL! Caller must call this function again until + * WLAN_STATUS_SUCCESS or unlock the TxRing by itself. + */ + if (u4MaxQuota < u4SrcCnt+u4RsvCnt) { + DBGLOG(HAL, INFO, + "WmmQuota,CannotUpdateNow,Port,%u,Grp,%u,reqMax,%u,src,%u,rsv,%u\n", + u2Port, u4GroupIdx, u4MaxQuota, u4SrcCnt, u4RsvCnt); + return WLAN_STATUS_PENDING; + } + + /* Step 3. Update MaxQuota */ + HAL_MCR_RD(prAdapter, + CONN_HIF_DMASHDL_GROUP0_CTRL(u4BaseAddr) + 4*u4GroupIdx, + &u4MacVal); + u4MacVal &= ~(DMASHDL_MAX_QUOTA_NUM(0xFFF)); + u4MacVal |= DMASHDL_MAX_QUOTA_NUM(u4MaxQuota); + HAL_MCR_WR(prAdapter, + CONN_HIF_DMASHDL_GROUP0_CTRL(u4BaseAddr) + 4*u4GroupIdx, + u4MacVal); + + /* Step 4. Unlock the TxRing */ + kalDevRegWrite(prGlueInfo, WPDMA_PAUSE_TX_Q, + u4TxRingBitmap & + (~(BIT(u2Port) << WPDMA_PAUSE_TX_Q_RINGIDX_OFFSET))); + + return WLAN_STATUS_SUCCESS; +} + + +void asicEnableInterrupt(IN struct ADAPTER *prAdapter) +{ + struct GL_HIF_INFO *prHifInfo = NULL; + + ASSERT(prAdapter); + + prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + enable_irq(prHifInfo->u4IrqId); +} + +void asicDisableInterrupt(IN struct ADAPTER *prAdapter) +{ + struct GL_HIF_INFO *prHifInfo = NULL; + + ASSERT(prAdapter); + + prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + disable_irq_nosync(prHifInfo->u4IrqId); +} + +void asicLowPowerOwnRead(IN struct ADAPTER *prAdapter, + OUT u_int8_t *pfgResult) +{ + uint32_t u4RegValue = 0; + + HAL_MCR_RD(prAdapter, CONN_HIF_ON_LPCTL, &u4RegValue); + *pfgResult = (u4RegValue & PCIE_LPCR_HOST_SET_OWN) == 0 ? + TRUE : FALSE; +} + +void asicLowPowerOwnSet(IN struct ADAPTER *prAdapter, + OUT u_int8_t *pfgResult) +{ + uint32_t u4RegValue = 0; + + HAL_MCR_WR(prAdapter, CONN_HIF_ON_LPCTL, + PCIE_LPCR_HOST_SET_OWN); + HAL_MCR_RD(prAdapter, CONN_HIF_ON_LPCTL, &u4RegValue); + *pfgResult = (u4RegValue & PCIE_LPCR_HOST_SET_OWN) == 1; +} + +void asicLowPowerOwnClear(IN struct ADAPTER *prAdapter, + OUT u_int8_t *pfgResult) +{ + uint32_t u4RegValue = 0; + + HAL_MCR_WR(prAdapter, CONN_HIF_ON_LPCTL, + PCIE_LPCR_HOST_CLR_OWN); + HAL_MCR_RD(prAdapter, CONN_HIF_ON_LPCTL, &u4RegValue); + *pfgResult = (u4RegValue & PCIE_LPCR_HOST_SET_OWN) == 0; +} + +#if defined(_HIF_PCIE) +void asicLowPowerOwnClearPCIe(IN struct ADAPTER *prAdapter, + OUT u_int8_t *pfgResult) +{ + struct GLUE_INFO *prGlueInfo; + struct GL_HIF_INFO *prHif = NULL; + + prGlueInfo = prAdapter->prGlueInfo; + prHif = &prGlueInfo->rHifInfo; + + pci_write_config_byte(prHif->pdev, + PCIE_DOORBELL_PUSH, + CR_PCIE_CFG_CLEAR_OWN); +} +#endif + +void asicWakeUpWiFi(IN struct ADAPTER *prAdapter) +{ + u_int8_t fgResult; + + ASSERT(prAdapter); + + HAL_LP_OWN_RD(prAdapter, &fgResult); + + if (fgResult) { + prAdapter->fgIsFwOwn = FALSE; + DBGLOG(HAL, WARN, + "Already DriverOwn, set flag only\n"); + } + else + HAL_LP_OWN_CLR(prAdapter, &fgResult); +} + +bool asicIsValidRegAccess(IN struct ADAPTER *prAdapter, IN uint32_t u4Register) +{ + uint32_t au4ExcludeRegs[] = { CONN_HIF_ON_LPCTL }; + uint32_t u4Idx, u4Size = sizeof(au4ExcludeRegs) / sizeof(uint32_t); + + if (wlanIsChipNoAck(prAdapter)) + return false; + + /* driver can access all consys registers on driver own */ + if (!prAdapter->fgIsFwOwn) + return true; + + /* only own control register can be accessed on fw own */ + for (u4Idx = 0; u4Idx < u4Size; u4Idx++) { + if (u4Register == au4ExcludeRegs[u4Idx]) + return true; + } + + return false; +} + +void asicGetMailboxStatus(IN struct ADAPTER *prAdapter, + OUT uint32_t *pu4Val) +{ + uint32_t u4RegValue = 0; + + HAL_MCR_RD(prAdapter, + CONN_MCU_CONFG_ON_HOST_MAILBOX_WF_ADDR, &u4RegValue); + *pu4Val = u4RegValue; +} + +void asicSetDummyReg(struct GLUE_INFO *prGlueInfo) +{ + kalDevRegWrite(prGlueInfo, CONN_DUMMY_CR, PDMA_DUMMY_MAGIC_NUM); +} + +void asicCheckDummyReg(struct GLUE_INFO *prGlueInfo) +{ + struct GL_HIF_INFO *prHifInfo; + struct ADAPTER *prAdapter; + uint32_t u4Value = 0; + uint32_t u4Idx; + + prAdapter = prGlueInfo->prAdapter; + prHifInfo = &prGlueInfo->rHifInfo; + kalDevRegRead(prGlueInfo, CONN_DUMMY_CR, &u4Value); + DBGLOG(HAL, TRACE, "Check sleep mode DummyReg[0x%x]\n", u4Value); + if (u4Value != PDMA_DUMMY_RESET_VALUE) + return; + + for (u4Idx = 0; u4Idx < NUM_OF_TX_RING; u4Idx++) + prHifInfo->TxRing[u4Idx].TxSwUsedIdx = 0; + DBGLOG(HAL, TRACE, "Weakup from sleep mode\n"); + + if (halWpdmaGetRxDmaDoneCnt(prGlueInfo, RX_RING_EVT_IDX_1)) { + DBGLOG(HAL, TRACE, "Force to read RX event\n"); + prAdapter->u4NoMoreRfb |= BIT(RX_RING_EVT_IDX_1); + } + if (halWpdmaGetRxDmaDoneCnt(prGlueInfo, RX_RING_DATA_IDX_0)) { + DBGLOG(HAL, TRACE, "Force to read RX data\n"); + prAdapter->u4NoMoreRfb |= BIT(RX_RING_DATA_IDX_0); + } + /* Write sleep mode magic num to dummy reg */ + asicSetDummyReg(prGlueInfo); +} + +void asicPdmaTxRingExtCtrl( + struct GLUE_INFO *prGlueInfo, + struct RTMP_TX_RING *tx_ring, + uint32_t index) +{ + struct BUS_INFO *prBusInfo; + struct ADAPTER *prAdapter = prGlueInfo->prAdapter; + uint32_t phy_addr_ext = 0, ext_offset = 0; + struct RTMP_DMACB *prTxCell; + + prBusInfo = prGlueInfo->prAdapter->chip_info->bus_info; + prTxCell = &tx_ring->Cell[0]; + +#ifdef CONFIG_PHYS_ADDR_T_64BIT + phy_addr_ext = (((uint64_t)prTxCell->AllocPa >> + DMA_BITS_OFFSET) & DMA_HIGHER_4BITS_MASK); +#endif + ext_offset = index * MT_RINGREG_EXT_DIFF; + + tx_ring->hw_desc_base_ext = + prBusInfo->host_tx_ring_ext_ctrl_base + ext_offset; + + HAL_MCR_WR(prAdapter, tx_ring->hw_desc_base_ext, + phy_addr_ext); +} + +void asicPdmaRxRingExtCtrl( + struct GLUE_INFO *prGlueInfo, + struct RTMP_RX_RING *rx_ring, + uint32_t index) +{ + struct BUS_INFO *prBusInfo; + struct ADAPTER *prAdapter = prGlueInfo->prAdapter; + uint32_t phy_addr_ext = 0, ext_offset = 0; + + prBusInfo = prGlueInfo->prAdapter->chip_info->bus_info; + +#ifdef CONFIG_PHYS_ADDR_T_64BIT + phy_addr_ext = (((uint64_t)rx_ring->Cell[0].AllocPa >> + DMA_BITS_OFFSET) & DMA_HIGHER_4BITS_MASK); +#endif + ext_offset = index * MT_RINGREG_EXT_DIFF; + rx_ring->hw_desc_base_ext = + prBusInfo->host_rx_ring_ext_ctrl_base + ext_offset; + + HAL_MCR_WR(prAdapter, rx_ring->hw_desc_base_ext, + phy_addr_ext); +} +#endif /* _HIF_PCIE || _HIF_AXI */ + +#if defined(_HIF_USB) +/* DMS Scheduler Init */ +void asicUsbDmaShdlGroupInit(IN struct ADAPTER *prAdapter, + uint32_t u4RefillGroup) +{ + uint32_t u4BaseAddr, u4MacVal = 0; + struct mt66xx_chip_info *prChipInfo; + uint32_t u4CfgVal = 0; + + ASSERT(prAdapter); + + prChipInfo = prAdapter->chip_info; + u4BaseAddr = prChipInfo->u4HifDmaShdlBaseAddr; + + HAL_MCR_RD(prAdapter, + CONN_HIF_DMASHDL_PACKET_MAX_SIZE(u4BaseAddr), &u4MacVal); + u4MacVal &= ~(PLE_PKT_MAX_SIZE_MASK | PSE_PKT_MAX_SIZE_MASK); + u4MacVal |= PLE_PKT_MAX_SIZE_NUM(0x1); + u4MacVal |= PSE_PKT_MAX_SIZE_NUM(0x8); + HAL_MCR_WR(prAdapter, + CONN_HIF_DMASHDL_PACKET_MAX_SIZE(u4BaseAddr), u4MacVal); + + u4RefillGroup |= + (CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP2_REFILL_PRIORITY_MASK + | + CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP3_REFILL_PRIORITY_MASK); + HAL_MCR_WR(prAdapter, + CONN_HIF_DMASHDL_REFILL_CONTROL(u4BaseAddr), u4RefillGroup); + + /* Use "User program group sequence order" by default.[16]1'b0 */ + HAL_MCR_RD(prAdapter, + CONN_HIF_DMASHDL_PAGE_SETTING(u4BaseAddr), &u4MacVal); + u4MacVal &= USB_DMA_SHDL_GROUP_DEF_SEQUENCE_ORDER; + HAL_MCR_WR(prAdapter, + CONN_HIF_DMASHDL_PAGE_SETTING(u4BaseAddr), u4MacVal); + +#if CFG_SUPPORT_CFG_FILE + u4CfgVal = wlanCfgGetUint32(prAdapter, + "DmaShdlGroup1MinQuota", + USB_DMA_SHDL_GROUP_DEF_MIN_QUOTA); + u4MacVal = DMASHDL_MIN_QUOTA_NUM(u4CfgVal); + u4CfgVal = wlanCfgGetUint32(prAdapter, + "DmaShdlGroup1MaxQuota", + USB_DMA_SHDL_GROUP_DEF_MAX_QUOTA); + u4MacVal |= DMASHDL_MAX_QUOTA_NUM(u4CfgVal); +#else /* CFG_SUPPORT_CFG_FILE */ + u4MacVal = DMASHDL_MIN_QUOTA_NUM( + USB_DMA_SHDL_GROUP_DEF_MIN_QUOTA); + u4MacVal |= DMASHDL_MAX_QUOTA_NUM( + USB_DMA_SHDL_GROUP_DEF_MAX_QUOTA); +#endif /* !CFG_SUPPORT_CFG_FILE */ + HAL_MCR_WR(prAdapter, + CONN_HIF_DMASHDL_GROUP1_CTRL(u4BaseAddr), u4MacVal); + +#if CFG_SUPPORT_CFG_FILE + u4CfgVal = wlanCfgGetUint32(prAdapter, + "DmaShdlGroup0MinQuota", + USB_DMA_SHDL_GROUP_DEF_MIN_QUOTA); + u4MacVal = DMASHDL_MIN_QUOTA_NUM(u4CfgVal); + u4CfgVal = wlanCfgGetUint32(prAdapter, + "DmaShdlGroup0MaxQuota", + USB_DMA_SHDL_GROUP_DEF_MAX_QUOTA); + u4MacVal |= DMASHDL_MAX_QUOTA_NUM(u4CfgVal); +#else /* CFG_SUPPORT_CFG_FILE */ + u4MacVal = DMASHDL_MIN_QUOTA_NUM( + USB_DMA_SHDL_GROUP_DEF_MIN_QUOTA); + u4MacVal |= DMASHDL_MAX_QUOTA_NUM( + USB_DMA_SHDL_GROUP_DEF_MAX_QUOTA); +#endif /* !CFG_SUPPORT_CFG_FILE */ + HAL_MCR_WR(prAdapter, + CONN_HIF_DMASHDL_GROUP0_CTRL(u4BaseAddr), u4MacVal); + +#if CFG_SUPPORT_CFG_FILE + u4CfgVal = wlanCfgGetUint32(prAdapter, + "DmaShdlGroup2MinQuota", + USB_DMA_SHDL_GROUP_DEF_MIN_QUOTA); + u4MacVal = DMASHDL_MIN_QUOTA_NUM(u4CfgVal); + u4CfgVal = wlanCfgGetUint32(prAdapter, + "DmaShdlGroup2MaxQuota", + USB_DMA_SHDL_GROUP_DEF_MAX_QUOTA); + u4MacVal |= DMASHDL_MAX_QUOTA_NUM(u4CfgVal); +#else /* CFG_SUPPORT_CFG_FILE */ + u4MacVal = DMASHDL_MIN_QUOTA_NUM( + USB_DMA_SHDL_GROUP_DEF_MIN_QUOTA); + u4MacVal |= DMASHDL_MAX_QUOTA_NUM( + USB_DMA_SHDL_GROUP_DEF_MAX_QUOTA); +#endif /* !CFG_SUPPORT_CFG_FILE */ + HAL_MCR_WR(prAdapter, + CONN_HIF_DMASHDL_GROUP2_CTRL(u4BaseAddr), u4MacVal); + +#if CFG_SUPPORT_CFG_FILE + u4CfgVal = wlanCfgGetUint32(prAdapter, + "DmaShdlGroup3MinQuota", + USB_DMA_SHDL_GROUP_DEF_MIN_QUOTA); + u4MacVal = DMASHDL_MIN_QUOTA_NUM(u4CfgVal); + u4CfgVal = wlanCfgGetUint32(prAdapter, + "DmaShdlGroup3MaxQuota", + USB_DMA_SHDL_GROUP_DEF_MAX_QUOTA); + u4MacVal |= DMASHDL_MAX_QUOTA_NUM(u4CfgVal); +#else /* CFG_SUPPORT_CFG_FILE */ + u4MacVal = DMASHDL_MIN_QUOTA_NUM( + USB_DMA_SHDL_GROUP_DEF_MIN_QUOTA); + u4MacVal |= DMASHDL_MAX_QUOTA_NUM( + USB_DMA_SHDL_GROUP_DEF_MAX_QUOTA); +#endif /* !CFG_SUPPORT_CFG_FILE */ + HAL_MCR_WR(prAdapter, + CONN_HIF_DMASHDL_GROUP3_CTRL(u4BaseAddr), u4MacVal); + +#if CFG_SUPPORT_CFG_FILE + u4CfgVal = wlanCfgGetUint32(prAdapter, + "DmaShdlGroup4MinQuota", + USB_DMA_SHDL_GROUP_DEF_MIN_QUOTA); + u4MacVal = DMASHDL_MIN_QUOTA_NUM(u4CfgVal); + u4CfgVal = wlanCfgGetUint32(prAdapter, + "DmaShdlGroup4MaxQuota", + USB_DMA_SHDL_GROUP_DEF_MAX_QUOTA); + u4MacVal |= DMASHDL_MAX_QUOTA_NUM(u4CfgVal); +#else /* CFG_SUPPORT_CFG_FILE */ + u4MacVal = DMASHDL_MIN_QUOTA_NUM( + USB_DMA_SHDL_GROUP_DEF_MIN_QUOTA); + u4MacVal |= DMASHDL_MAX_QUOTA_NUM( + USB_DMA_SHDL_GROUP_DEF_MAX_QUOTA); +#endif /* !CFG_SUPPORT_CFG_FILE */ + HAL_MCR_WR(prAdapter, + CONN_HIF_DMASHDL_GROUP4_CTRL(u4BaseAddr), u4MacVal); + + u4MacVal = ((arAcQIdx2GroupId[MAC_TXQ_AC0_INDEX] << + CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE0_MAPPING) | + (arAcQIdx2GroupId[MAC_TXQ_AC1_INDEX] << + CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE1_MAPPING) | + (arAcQIdx2GroupId[MAC_TXQ_AC2_INDEX] << + CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE2_MAPPING) | + (arAcQIdx2GroupId[MAC_TXQ_AC3_INDEX] << + CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE3_MAPPING) | + (arAcQIdx2GroupId[MAC_TXQ_AC10_INDEX] << + CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE4_MAPPING) | + (arAcQIdx2GroupId[MAC_TXQ_AC11_INDEX] << + CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE5_MAPPING) | + (arAcQIdx2GroupId[MAC_TXQ_AC12_INDEX] << + CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE6_MAPPING) | + (arAcQIdx2GroupId[MAC_TXQ_AC13_INDEX] << + CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE7_MAPPING)); + HAL_MCR_WR(prAdapter, CONN_HIF_DMASHDL_Q_MAP0(u4BaseAddr), + u4MacVal); + + u4MacVal = ((arAcQIdx2GroupId[MAC_TXQ_AC20_INDEX] << + CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE8_MAPPING) | + (arAcQIdx2GroupId[MAC_TXQ_AC21_INDEX] << + CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE9_MAPPING) | + (arAcQIdx2GroupId[MAC_TXQ_AC22_INDEX] << + CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE10_MAPPING) | + (arAcQIdx2GroupId[MAC_TXQ_AC23_INDEX] << + CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE11_MAPPING) | + (arAcQIdx2GroupId[MAC_TXQ_AC30_INDEX] << + CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE12_MAPPING) | + (arAcQIdx2GroupId[MAC_TXQ_AC31_INDEX] << + CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE13_MAPPING) | + (arAcQIdx2GroupId[MAC_TXQ_AC32_INDEX] << + CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE14_MAPPING) | + (arAcQIdx2GroupId[MAC_TXQ_AC33_INDEX] << + CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE15_MAPPING)); + HAL_MCR_WR(prAdapter, CONN_HIF_DMASHDL_Q_MAP1(u4BaseAddr), + u4MacVal); + + u4MacVal = ((arAcQIdx2GroupId[MAC_TXQ_ALTX_0_INDEX] << + CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE16_MAPPING) | + (arAcQIdx2GroupId[MAC_TXQ_BMC_0_INDEX] << + CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE17_MAPPING) | + (arAcQIdx2GroupId[MAC_TXQ_BCN_0_INDEX] << + CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE18_MAPPING) | + (arAcQIdx2GroupId[MAC_TXQ_PSMP_0_INDEX] << + CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE19_MAPPING)); + HAL_MCR_WR(prAdapter, CONN_HIF_DMASHDL_Q_MAP2(u4BaseAddr), + u4MacVal); +} + +void asicUsbDmaShdlInit(IN struct ADAPTER *prAdapter) +{ + uint32_t u4BaseAddr, u4MacVal; + struct mt66xx_chip_info *prChipInfo; + + ASSERT(prAdapter); + + prChipInfo = prAdapter->chip_info; + u4BaseAddr = prChipInfo->u4HifDmaShdlBaseAddr; + + /* + * Enable refill control group 0, 1, 2, 3, 4. + * Keep all group low refill priority to prevent low + * group starvation if we have high group. + */ + u4MacVal = + (CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP5_REFILL_DISABLE_MASK + | + CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP6_REFILL_DISABLE_MASK + | + CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP7_REFILL_DISABLE_MASK + | + CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP8_REFILL_DISABLE_MASK + | + CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP9_REFILL_DISABLE_MASK + | + CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP10_REFILL_DISABLE_MASK + | + CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP11_REFILL_DISABLE_MASK + | + CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP12_REFILL_DISABLE_MASK + | + CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP13_REFILL_DISABLE_MASK + | + CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP14_REFILL_DISABLE_MASK + | + CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP15_REFILL_DISABLE_MASK); + + asicUsbDmaShdlGroupInit(prAdapter, u4MacVal); + + /* + * HIF Scheduler Setting + * Group15(CMD) is highest priority. + */ + HAL_MCR_WR(prAdapter, + CONN_HIF_DMASHDL_SHDL_SET0(u4BaseAddr), 0x6501234f); + HAL_MCR_WR(prAdapter, + CONN_HIF_DMASHDL_SHDL_SET1(u4BaseAddr), 0xedcba987); + + HAL_MCR_WR(prAdapter, + CONN_HIF_DMASHDL_OPTIONAL_CONTROL(u4BaseAddr), 0x7004801c); +} + +u_int8_t asicUsbSuspend(IN struct ADAPTER *prAdapter, + IN struct GLUE_INFO *prGlueInfo) +{ + uint32_t u4Value; + uint32_t count = 0; + int32_t ret = 0; + struct BUS_INFO *prBusInfo; + + DBGLOG(HAL, INFO, "%s ---->\n", __func__); + prBusInfo = prAdapter->chip_info->bus_info; + + /* Disable PDMA TX */ + HAL_MCR_RD(prAdapter, PDMA_IF_MISC, &u4Value); + u4Value &= ~PDMA_IF_MISC_TX_ENABLE_MASK; + HAL_MCR_WR(prAdapter, PDMA_IF_MISC, u4Value); + + /* Set PDMA Debug flag */ + u4Value = 0x00000116; + HAL_MCR_WR(prAdapter, PDMA_DEBUG_EN, u4Value); + /* Polling PDMA_dmashdl_request done */ + while (count < PDMA_TX_IDLE_WAIT_COUNT) { + HAL_MCR_RD(prAdapter, PDMA_DEBUG_STATUS, &u4Value); + DBGLOG(HAL, INFO, "%s: 0x%08x = 0x%08x\n", __func__, + PDMA_DEBUG_STATUS, u4Value); + if (!(u4Value & PDMA_DEBUG_DMASHDL_REQUEST_DONE_MASK) + && (count >= 3)) + break; + mdelay(1); + count++; + } + + if (count >= PDMA_TX_IDLE_WAIT_COUNT) { + DBGLOG(HAL, ERROR, + "%s:: 2.2 suspend fail, enable PDMA TX again.\n", + __func__); + /* Enable PDMA TX again */ + HAL_MCR_RD(prAdapter, PDMA_IF_MISC, &u4Value); + u4Value |= PDMA_IF_MISC_TX_ENABLE_MASK; + HAL_MCR_WR(prAdapter, PDMA_IF_MISC, u4Value); + return FALSE; + } + + u4Value = 0x00000101; + HAL_MCR_WR(prAdapter, PDMA_DEBUG_EN, u4Value); + count = 0; + while (count < PDMA_TX_IDLE_WAIT_COUNT) { + HAL_MCR_RD(prAdapter, PDMA_DEBUG_STATUS, &u4Value); + DBGLOG(HAL, INFO, "%s:: 0x%08x = 0x%08x\n", + __func__, PDMA_DEBUG_STATUS, u4Value); + if ((u4Value == PDMA_DEBUG_TX_STATUS_MASK) + && (count >= 3)) { + DBGLOG(HAL, ERROR, "%s:: PDMA Tx idle~\n", __func__); + break; + } + DBGLOG(HAL, ERROR, "%s:: PDMA Tx busy.....\n", __func__); + count++; + } + + if (count >= PDMA_TX_IDLE_WAIT_COUNT) { + DBGLOG(HAL, ERROR, + "%s:: 2.4 suspend fail, enable PDMA TX again.\n", + __func__); + /* Enable PDMA TX again */ + HAL_MCR_RD(prAdapter, PDMA_IF_MISC, &u4Value); + u4Value |= PDMA_IF_MISC_TX_ENABLE_MASK; + HAL_MCR_WR(prAdapter, PDMA_IF_MISC, u4Value); + return FALSE; + } + + prGlueInfo->rHifInfo.state = USB_STATE_SUSPEND; + halDisableInterrupt(prGlueInfo->prAdapter); + halTxCancelAllSending(prGlueInfo->prAdapter); + + ret = usb_control_msg(prGlueInfo->rHifInfo.udev, + usb_sndctrlpipe(prGlueInfo->rHifInfo.udev, 0), + VND_REQ_FEATURE_SET, + prBusInfo->u4device_vender_request_out, + FEATURE_SET_WVALUE_SUSPEND, 0, + NULL, 0, + VENDOR_TIMEOUT_MS); + if (ret) { + DBGLOG(HAL, ERROR, + "%s:: VendorRequest FeatureSetResume ERROR:", __func__); + DBGLOG(HAL, ERROR, + " %x, enable PDMA TX again.\n", (unsigned int)ret); + /* Enable PDMA TX again */ + HAL_MCR_RD(prAdapter, PDMA_IF_MISC, &u4Value); + u4Value |= PDMA_IF_MISC_TX_ENABLE_MASK; + HAL_MCR_WR(prAdapter, PDMA_IF_MISC, u4Value); + DBGLOG(HAL, INFO, "%s <----\n", __func__); + return FALSE; + } + DBGLOG(HAL, INFO, "%s <----\n", __func__); + return TRUE; +} + +uint8_t asicUsbEventEpDetected(IN struct ADAPTER *prAdapter) +{ + struct GL_HIF_INFO *prHifInfo = NULL; + struct GLUE_INFO *prGlueInfo = NULL; + struct BUS_INFO *prBusInfo = NULL; + int32_t ret = 0; + uint8_t ucRetryCount = 0; + u_int8_t ucEp5Disable = FALSE; + + ASSERT(FALSE == 0); + prGlueInfo = prAdapter->prGlueInfo; + prHifInfo = &prGlueInfo->rHifInfo; + prBusInfo = prGlueInfo->prAdapter->chip_info->bus_info; + + if (prHifInfo->fgEventEpDetected == FALSE) { + prHifInfo->fgEventEpDetected = TRUE; + do { + ret = mtk_usb_vendor_request(prGlueInfo, 0, + prBusInfo->u4device_vender_request_in, + VND_REQ_EP5_IN_INFO, + 0, 0, &ucEp5Disable, + sizeof(ucEp5Disable)); + if (ret || ucRetryCount) + DBGLOG(HAL, ERROR, + "usb_control_msg() status: %x retry: %u\n", + (unsigned int)ret, ucRetryCount); + ucRetryCount++; + if (ucRetryCount > USB_ACCESS_RETRY_LIMIT) + break; + } while (ret); + + if (ret) { + kalSendAeeWarning(HIF_USB_ERR_TITLE_STR, + HIF_USB_ERR_DESC_STR + "USB() reports error: %x retry: %u", + ret, ucRetryCount); + DBGLOG(HAL, ERROR, + "usb_readl() reports error: %x retry: %u\n", ret, + ucRetryCount); + } else { + DBGLOG(HAL, INFO, + "%s: Get ucEp5Disable = %d\n", __func__, + ucEp5Disable); + if (ucEp5Disable) + prHifInfo->eEventEpType = EVENT_EP_TYPE_DATA_EP; + } + } + if (prHifInfo->eEventEpType == EVENT_EP_TYPE_DATA_EP) + return USB_DATA_EP_IN; + else + return USB_EVENT_EP_IN; +} + +void asicUdmaTxTimeoutEnable(IN struct ADAPTER *prAdapter) +{ + struct BUS_INFO *prBusInfo; + uint32_t u4Value; + + prBusInfo = prAdapter->chip_info->bus_info; + HAL_MCR_RD(prAdapter, prBusInfo->u4UdmaWlCfg_1_Addr, + &u4Value); + u4Value &= ~UDMA_WLCFG_1_TX_TIMEOUT_LIMIT_MASK; + u4Value |= UDMA_WLCFG_1_TX_TIMEOUT_LIMIT( + prBusInfo->u4UdmaTxTimeout); + HAL_MCR_WR(prAdapter, prBusInfo->u4UdmaWlCfg_1_Addr, + u4Value); + + HAL_MCR_RD(prAdapter, prBusInfo->u4UdmaWlCfg_0_Addr, + &u4Value); + u4Value |= UDMA_WLCFG_0_TX_TIMEOUT_EN_MASK; + HAL_MCR_WR(prAdapter, prBusInfo->u4UdmaWlCfg_0_Addr, + u4Value); +} + +void asicUdmaRxFlush(IN struct ADAPTER *prAdapter, + IN u_int8_t bEnable) +{ + struct BUS_INFO *prBusInfo; + uint32_t u4Value; + + prBusInfo = prAdapter->chip_info->bus_info; + + HAL_MCR_RD(prAdapter, prBusInfo->u4UdmaWlCfg_0_Addr, + &u4Value); + if (bEnable) + u4Value |= UDMA_WLCFG_0_RX_FLUSH_MASK; + else + u4Value &= ~UDMA_WLCFG_0_RX_FLUSH_MASK; + HAL_MCR_WR(prAdapter, prBusInfo->u4UdmaWlCfg_0_Addr, + u4Value); +} + +void asicPdmaHifReset(IN struct ADAPTER *prAdapter, + IN u_int8_t bRelease) +{ + uint32_t u4Value; + + HAL_MCR_RD(prAdapter, PDMA_HIF_RESET, &u4Value); + if (bRelease) + u4Value |= DPMA_HIF_LOGIC_RESET_MASK; + else + u4Value &= ~DPMA_HIF_LOGIC_RESET_MASK; + HAL_MCR_WR(prAdapter, PDMA_HIF_RESET, u4Value); +} + +void fillUsbHifTxDesc(IN uint8_t **pDest, + IN uint16_t *pInfoBufLen) +{ + /*USB TX Descriptor (4 bytes)*/ + /* BIT[15:0] - TX Bytes Count + * (Not including USB TX Descriptor and 4-bytes zero padding. + */ + kalMemZero((void *)*pDest, sizeof(uint32_t)); + kalMemCopy((void *)*pDest, (void *) pInfoBufLen, + sizeof(uint16_t)); +} +#endif /* _HIF_USB */ + +static void asicFillInitCmdTxdInfo( + struct ADAPTER *prAdapter, + struct WIFI_CMD_INFO *prCmdInfo, + u_int8_t *pucSeqNum) +{ + struct INIT_HIF_TX_HEADER *prInitHifTxHeader; + struct INIT_HIF_TX_HEADER_PENDING_FOR_HW_32BYTES + *prInitHifTxHeaderPending; + uint32_t u4TxdLen = + sizeof(struct INIT_HIF_TX_HEADER_PENDING_FOR_HW_32BYTES); + + prInitHifTxHeaderPending = + (struct INIT_HIF_TX_HEADER_PENDING_FOR_HW_32BYTES *) + (prCmdInfo->pucInfoBuffer); + prInitHifTxHeader = (struct INIT_HIF_TX_HEADER *) + (prCmdInfo->pucInfoBuffer + u4TxdLen); + + prInitHifTxHeaderPending->u2TxByteCount = prCmdInfo->u2InfoBufLen; + if (!prCmdInfo->ucCID) { + prInitHifTxHeaderPending->u2PQ_ID = + INIT_CMD_PDA_PQ_ID; + prInitHifTxHeaderPending->ucHeaderFormat = + INIT_CMD_PDA_PACKET_TYPE_ID; + prInitHifTxHeaderPending->ucPktFt = + INIT_PKT_FT_PDA_FWDL; + } else { + prInitHifTxHeaderPending->u2PQ_ID = + INIT_CMD_PQ_ID; + prInitHifTxHeaderPending->ucHeaderFormat = + INIT_CMD_PACKET_TYPE_ID; + prInitHifTxHeaderPending->ucPktFt = + INIT_PKT_FT_CMD; + } + + prInitHifTxHeader->rInitWifiCmd.ucCID = prCmdInfo->ucCID; + prInitHifTxHeader->rInitWifiCmd.ucPktTypeID = prCmdInfo->ucPktTypeID; + prInitHifTxHeader->rInitWifiCmd.ucSeqNum = + nicIncreaseCmdSeqNum(prAdapter); + prInitHifTxHeader->u2TxByteCount = + prInitHifTxHeaderPending->u2TxByteCount - u4TxdLen; + + if (pucSeqNum) + *pucSeqNum = prInitHifTxHeader->rInitWifiCmd.ucSeqNum; + + DBGLOG_LIMITED(INIT, INFO, "TX CMD: ID[0x%02X] SEQ[%u] LEN[%u]\n", + prInitHifTxHeader->rInitWifiCmd.ucCID, + prInitHifTxHeader->rInitWifiCmd.ucSeqNum, + prInitHifTxHeader->u2TxByteCount); +} + +static void asicFillCmdTxdInfo( + struct ADAPTER *prAdapter, + struct WIFI_CMD_INFO *prCmdInfo, + u_int8_t *pucSeqNum) +{ + struct WIFI_CMD *prWifiCmd; + + prWifiCmd = (struct WIFI_CMD *)prCmdInfo->pucInfoBuffer; + + prWifiCmd->u2TxByteCount = prCmdInfo->u2InfoBufLen; + prWifiCmd->u2PQ_ID = + CMD_PQ_ID; + prWifiCmd->ucHeaderFormat = + CMD_PACKET_TYPE_ID; + prWifiCmd->ucPktFt = + TXD_PKT_FT_CMD; + + prWifiCmd->ucCID = prCmdInfo->ucCID; + prWifiCmd->ucExtenCID = prCmdInfo->ucExtCID; + prWifiCmd->ucPktTypeID = prCmdInfo->ucPktTypeID; + prWifiCmd->ucSetQuery = prCmdInfo->ucSetQuery; + prWifiCmd->ucSeqNum = nicIncreaseCmdSeqNum(prAdapter); + prWifiCmd->ucS2DIndex = S2D_INDEX_CMD_H2N_H2C; + prWifiCmd->u2Length = + prWifiCmd->u2TxByteCount + - (uint16_t) OFFSET_OF(struct WIFI_CMD, u2Length); + + if (pucSeqNum) + *pucSeqNum = prWifiCmd->ucSeqNum; + + DBGLOG_LIMITED(INIT, INFO, + "TX CMD: ID[0x%02X] SEQ[%u] SET[%u] LEN[%u]\n", + prWifiCmd->ucCID, prWifiCmd->ucSeqNum, + prWifiCmd->ucSetQuery, prWifiCmd->u2Length); +} + + +void asicFillInitCmdTxd( + struct ADAPTER *prAdapter, + struct WIFI_CMD_INFO *prCmdInfo, + uint16_t *pu2BufInfoLen, + u_int8_t *pucSeqNum, + void **pCmdBuf) +{ + struct INIT_HIF_TX_HEADER *prInitHifTxHeader; + + prInitHifTxHeader = (struct INIT_HIF_TX_HEADER *) + (prCmdInfo->pucInfoBuffer + + sizeof(struct INIT_HIF_TX_HEADER_PENDING_FOR_HW_32BYTES)); + + if (!prCmdInfo->ucCID) { + *pu2BufInfoLen += sizeof(struct INIT_HIF_TX_HEADER) + + sizeof(struct INIT_HIF_TX_HEADER_PENDING_FOR_HW_32BYTES); + prCmdInfo->u2InfoBufLen = *pu2BufInfoLen; + } + asicFillInitCmdTxdInfo(prAdapter, prCmdInfo, pucSeqNum); + + if (pCmdBuf) + *pCmdBuf = prInitHifTxHeader->rInitWifiCmd.aucBuffer; +} + +void asicFillCmdTxd( + struct ADAPTER *prAdapter, + struct WIFI_CMD_INFO *prCmdInfo, + u_int8_t *pucSeqNum, + void **pCmdBuf) +{ + struct WIFI_CMD *prWifiCmd; + + prWifiCmd = (struct WIFI_CMD *)prCmdInfo->pucInfoBuffer; + asicFillCmdTxdInfo(prAdapter, prCmdInfo, pucSeqNum); + + if (pCmdBuf) + *pCmdBuf = &prWifiCmd->aucBuffer[0]; +} + +void asicInitTxdHook( + struct TX_DESC_OPS_T *prTxDescOps) +{ + ASSERT(prTxDescOps); + prTxDescOps->nic_txd_long_format_op = nic_txd_v1_long_format_op; + prTxDescOps->nic_txd_tid_op = nic_txd_v1_tid_op; + prTxDescOps->nic_txd_queue_idx_op = nic_txd_v1_queue_idx_op; +#if (CFG_TCP_IP_CHKSUM_OFFLOAD == 1) + prTxDescOps->nic_txd_chksum_op = nic_txd_v1_chksum_op; +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD == 1 */ + prTxDescOps->nic_txd_header_format_op = nic_txd_v1_header_format_op; + prTxDescOps->nic_txd_fill_by_pkt_option = + nic_txd_v1_fill_by_pkt_option; + prTxDescOps->nic_txd_compose = nic_txd_v1_compose; + prTxDescOps->nic_txd_compose_security_frame = + nic_txd_v1_compose_security_frame; + prTxDescOps->nic_txd_set_pkt_fixed_rate_option_full = + nic_txd_v1_set_pkt_fixed_rate_option_full; + prTxDescOps->nic_txd_set_pkt_fixed_rate_option = + nic_txd_v1_set_pkt_fixed_rate_option; + prTxDescOps->nic_txd_set_hw_amsdu_template = + nic_txd_v1_set_hw_amsdu_template; + prTxDescOps->nic_txd_change_data_port_by_ac = + nic_txd_v1_change_data_port_by_ac; +} + +void asicInitRxdHook( + struct RX_DESC_OPS_T *prRxDescOps) +{ + ASSERT(prRxDescOps); + prRxDescOps->nic_rxd_get_rx_byte_count = nic_rxd_v1_get_rx_byte_count; + prRxDescOps->nic_rxd_get_pkt_type = nic_rxd_v1_get_packet_type; + prRxDescOps->nic_rxd_get_wlan_idx = nic_rxd_v1_get_wlan_idx; + prRxDescOps->nic_rxd_get_sec_mode = nic_rxd_v1_get_sec_mode; + prRxDescOps->nic_rxd_get_sw_class_error_bit = + nic_rxd_v1_get_sw_class_error_bit; + prRxDescOps->nic_rxd_get_ch_num = nic_rxd_v1_get_ch_num; + prRxDescOps->nic_rxd_get_rf_band = nic_rxd_v1_get_rf_band; + prRxDescOps->nic_rxd_get_tcl = nic_rxd_v1_get_tcl; + prRxDescOps->nic_rxd_get_ofld = nic_rxd_v1_get_ofld; + prRxDescOps->nic_rxd_fill_rfb = nic_rxd_v1_fill_rfb; + prRxDescOps->nic_rxd_sanity_check = nic_rxd_v1_sanity_check; +#if CFG_SUPPORT_WAKEUP_REASON_DEBUG + prRxDescOps->nic_rxd_check_wakeup_reason = + nic_rxd_v1_check_wakeup_reason; +#endif /* CFG_SUPPORT_WAKEUP_REASON_DEBUG */ +} + +#if (CFG_SUPPORT_MSP == 1) +void asicRxProcessRxvforMSP( + IN struct ADAPTER *prAdapter, + IN OUT struct SW_RFB *prRetSwRfb) +{ + struct HW_MAC_RX_STS_GROUP_3 *prGroup3; + + if (prRetSwRfb->ucStaRecIdx >= CFG_STA_REC_NUM) { + DBGLOG(RX, LOUD, + "prRetSwRfb->ucStaRecIdx(%d) >= CFG_STA_REC_NUM(%d)\n", + prRetSwRfb->ucStaRecIdx, CFG_STA_REC_NUM); + return; + } + prGroup3 = + (struct HW_MAC_RX_STS_GROUP_3 *)prRetSwRfb->prRxStatusGroup3; + if (prRetSwRfb->ucGroupVLD & BIT(RX_GROUP_VLD_3)) { + prAdapter->arStaRec[ + prRetSwRfb->ucStaRecIdx].u4RxVector0 = + HAL_RX_VECTOR_GET_RX_VECTOR( + prGroup3, 0); + + prAdapter->arStaRec[ + prRetSwRfb->ucStaRecIdx].u4RxVector1 = + HAL_RX_VECTOR_GET_RX_VECTOR( + prGroup3, 1); + + prAdapter->arStaRec[ + prRetSwRfb->ucStaRecIdx].u4RxVector2 = + HAL_RX_VECTOR_GET_RX_VECTOR( + prGroup3, 2); + + prAdapter->arStaRec[ + prRetSwRfb->ucStaRecIdx].u4RxVector3 = + HAL_RX_VECTOR_GET_RX_VECTOR( + prGroup3, 3); + + prAdapter->arStaRec[ + prRetSwRfb->ucStaRecIdx].u4RxVector4 = + HAL_RX_VECTOR_GET_RX_VECTOR( + prGroup3, 4); + } +} +#endif /* CFG_SUPPORT_MSP */ + +uint8_t asicRxGetRcpiValueFromRxv( + IN uint8_t ucRcpiMode, + IN struct SW_RFB *prSwRfb) +{ + uint8_t ucRcpi0, ucRcpi1; + uint8_t ucRcpiValue = 0; + struct HW_MAC_RX_STS_GROUP_3 *prGroup3; + + ASSERT(prSwRfb); + + if (ucRcpiMode >= RCPI_MODE_NUM) { + DBGLOG(RX, WARN, + "Rcpi Mode=%d is invalid for getting uint8_t value from RXV\n", + ucRcpiMode); + return 0; + } + + prGroup3 = (struct HW_MAC_RX_STS_GROUP_3 *)prSwRfb->prRxStatusGroup3; + ucRcpi0 = HAL_RX_STATUS_GET_RCPI0(prGroup3); + ucRcpi1 = HAL_RX_STATUS_GET_RCPI1(prGroup3); + + switch (ucRcpiMode) { + case RCPI_MODE_WF0: + ucRcpiValue = ucRcpi0; + break; + + case RCPI_MODE_WF1: + ucRcpiValue = ucRcpi1; + break; + + case RCPI_MODE_WF2: + case RCPI_MODE_WF3: + DBGLOG(RX, WARN, + "Rcpi Mode = %d is invalid for", ucRcpiMode); + DBGLOG(RX, WARN, + " device with only 2 antenna, use default rcpi0\n"); + ucRcpiValue = ucRcpi0; + break; + + case RCPI_MODE_AVG: /*Not recommended for CBW80+80*/ + if (ucRcpi0 <= RCPI_HIGH_BOUND && + ucRcpi1 <= RCPI_HIGH_BOUND) + ucRcpiValue = (ucRcpi0 + ucRcpi1) / 2; + else + ucRcpiValue = ucRcpi0 <= RCPI_HIGH_BOUND ? + (ucRcpi0) : (ucRcpi1); + break; + + case RCPI_MODE_MAX: + if (ucRcpi0 <= RCPI_HIGH_BOUND && + ucRcpi1 <= RCPI_HIGH_BOUND) + ucRcpiValue = + (ucRcpi0 > ucRcpi1) ? + (ucRcpi0) : (ucRcpi1); + else + ucRcpiValue = ucRcpi0 <= RCPI_HIGH_BOUND ? + (ucRcpi0) : (ucRcpi1); + break; + + case RCPI_MODE_MIN: + ucRcpiValue = + (ucRcpi0 < ucRcpi1) ? (ucRcpi0) : (ucRcpi1); + break; + + default: + break; + } + + if (ucRcpiValue < RCPI_MEASUREMENT_NOT_AVAILABLE) + return ucRcpiValue; + + DBGLOG(RX, ERROR, + "Invalid ucRcpiValue: %d\n", ucRcpiValue); + return 0; +} + +#if (CFG_SUPPORT_PERF_IND == 1) +void asicRxPerfIndProcessRXV(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, + IN uint8_t ucBssIndex) +{ + /* This Feature First MP on Lafite*/ + struct HW_MAC_RX_STS_GROUP_3 *prRxStatusGroup3; + uint8_t ucRxRate; + uint8_t ucRxMode; + uint8_t ucMcs; + uint8_t ucFrMode; + uint8_t ucShortGI, ucGroupid, ucMu, ucNsts = 1; + uint32_t u4PhyRate; + uint8_t ucRCPI0 = 0, ucRCPI1 = 0; + /* Rate + * Bit Number 2 + * Unit 500 Kbps + */ + uint16_t u2Rate = 0; + + ASSERT(prAdapter); + ASSERT(prSwRfb); + + if (ucBssIndex >= BSSID_NUM) + return; + + /* can't parse radiotap info if no rx vector */ + if (((prSwRfb->ucGroupVLD & BIT(RX_GROUP_VLD_2)) == 0) + || ((prSwRfb->ucGroupVLD & BIT(RX_GROUP_VLD_3)) == 0)) { + return; + } + + prRxStatusGroup3 = prSwRfb->prRxStatusGroup3; + + ucRxMode = (((prRxStatusGroup3)->u4RxVector[0] & + RX_VT_RX_MODE_MASK) >> RX_VT_RX_MODE_OFFSET); + + /* RATE & NSS */ + if ((ucRxMode == RX_VT_LEGACY_CCK) + || (ucRxMode == RX_VT_LEGACY_OFDM)) { + /* Bit[2:0] for Legacy CCK, Bit[3:0] for Legacy OFDM */ + ucRxRate = (HAL_RX_VECTOR_GET_RX_VECTOR( + prRxStatusGroup3, 0) & RX_VT_RX_RATE_AC_MASK); + u2Rate = nicGetHwRateByPhyRate(ucRxRate); + } else { + ucMcs = (HAL_RX_VECTOR_GET_RX_VECTOR( + prRxStatusGroup3, 0) & RX_VT_RX_RATE_AC_MASK); + ucNsts = ((HAL_RX_VECTOR_GET_RX_VECTOR( + prRxStatusGroup3, 1) & + RX_VT_NSTS_MASK) >> RX_VT_NSTS_OFFSET); + ucGroupid = ((HAL_RX_VECTOR_GET_RX_VECTOR( + prRxStatusGroup3, 1) & + RX_VT_GROUP_ID_MASK) >> RX_VT_GROUP_ID_OFFSET); + + if (ucNsts == 0) + ucNsts = 1; + + if (ucGroupid && ucGroupid != 63) + ucMu = 1; + else { + ucMu = 0; + ucNsts += 1; + } + + /* VHTA1 B0-B1 */ + ucFrMode = ((HAL_RX_VECTOR_GET_RX_VECTOR( + prRxStatusGroup3, 0) & + RX_VT_FR_MODE_MASK) >> RX_VT_FR_MODE_OFFSET); + ucShortGI = (HAL_RX_VECTOR_GET_RX_VECTOR( + prRxStatusGroup3, 0) & + RX_VT_SHORT_GI) ? 1 : 0; /* VHTA2 B0 */ + + if ((ucMcs > PHY_RATE_MCS9) || + (ucFrMode > RX_VT_FR_MODE_160) || + (ucShortGI > MAC_GI_SHORT)) + return; + + /* ucRate(500kbs) = u4PhyRate(100kbps) */ + u4PhyRate = nicGetPhyRateByMcsRate(ucMcs, ucFrMode, + ucShortGI); + u2Rate = u4PhyRate / 5; + + } + + /* RCPI */ + ucRCPI0 = HAL_RX_STATUS_GET_RCPI0(prRxStatusGroup3); + ucRCPI1 = HAL_RX_STATUS_GET_RCPI1(prRxStatusGroup3); + + + /* Record peak rate to Traffic Indicator*/ + if (u2Rate > prAdapter->prGlueInfo + ->PerfIndCache.u2CurRxRate[ucBssIndex]) { + prAdapter->prGlueInfo->PerfIndCache. + u2CurRxRate[ucBssIndex] = u2Rate; + prAdapter->prGlueInfo->PerfIndCache. + ucCurRxNss[ucBssIndex] = ucNsts; + prAdapter->prGlueInfo->PerfIndCache. + ucCurRxRCPI0[ucBssIndex] = ucRCPI0; + prAdapter->prGlueInfo->PerfIndCache. + ucCurRxRCPI1[ucBssIndex] = ucRCPI1; + } +} +#endif + + +#if (CFG_CHIP_RESET_SUPPORT == 1) && (CFG_WMT_RESET_API_SUPPORT == 0) +u_int8_t conn1_rst_L0_notify_step2(void) +{ + typedef int (*p_bt_fun_type) (void); + p_bt_fun_type bt_func; + char *bt_func_name = "WF_rst_L0_notify_BT_step2"; + + DBGLOG(INIT, STATE, "[SER][L0] %s\n", bt_func_name); + bt_func = (p_bt_fun_type)(uintptr_t) GLUE_LOOKUP_FUN(bt_func_name); + if (bt_func) + bt_func(); + else { + DBGLOG(INIT, WARN, "[SER][L0] %s does not exist\n", + bt_func_name); + return FALSE; + } + return TRUE; +} +#endif + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/common/cmm_asic_connac2x.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/common/cmm_asic_connac2x.c new file mode 100644 index 0000000000000000000000000000000000000000..045b3610e321b990fb3512895f6a1ef4d3a876dd --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/common/cmm_asic_connac2x.c @@ -0,0 +1,1807 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/*! \file cmm_asic_connac2x.c +* \brief Internal driver stack will export the required procedures here for +* GLUE Layer. +* +* This file contains all routines which are exported from MediaTek 802.11 +* Wireless +* LAN driver stack to GLUE Layer. +*/ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +#if (CFG_SUPPORT_CONNAC2X == 1) + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include "coda/mt7915/wf_wfdma_host_dma0.h" +#include "coda/mt7915/wf_wfdma_host_dma1.h" + + +#include "precomp.h" +#include "wlan_lib.h" + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ +#define CONNAC2X_HIF_DMASHDL_BASE 0x52000000 + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +#define USB_ACCESS_RETRY_LIMIT 1 + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +void asicConnac2xCapInit( + struct ADAPTER *prAdapter) +{ + struct GLUE_INFO *prGlueInfo; + struct mt66xx_chip_info *prChipInfo; + struct BUS_INFO *prBusInfo = NULL; + uint32_t u4HostWpdamBase = 0; + + ASSERT(prAdapter); + if (prAdapter->chip_info->is_support_wfdma1) + u4HostWpdamBase = CONNAC2X_HOST_WPDMA_1_BASE; + else + u4HostWpdamBase = CONNAC2X_HOST_WPDMA_0_BASE; + + prGlueInfo = prAdapter->prGlueInfo; + prChipInfo = prAdapter->chip_info; + prBusInfo = prChipInfo->bus_info; + + prChipInfo->u2HifTxdSize = 0; + prChipInfo->u2TxInitCmdPort = 0; + prChipInfo->u2TxFwDlPort = 0; + prChipInfo->fillHifTxDesc = NULL; + prChipInfo->u2CmdTxHdrSize = sizeof(struct CONNAC2X_WIFI_CMD); + prChipInfo->asicFillInitCmdTxd = asicConnac2xFillInitCmdTxd; + prChipInfo->asicFillCmdTxd = asicConnac2xFillCmdTxd; + prChipInfo->u2RxSwPktBitMap = CONNAC2X_RX_STATUS_PKT_TYPE_SW_BITMAP; + prChipInfo->u2RxSwPktEvent = CONNAC2X_RX_STATUS_PKT_TYPE_SW_EVENT; + prChipInfo->u2RxSwPktFrame = CONNAC2X_RX_STATUS_PKT_TYPE_SW_FRAME; + prChipInfo->u4ExtraTxByteCount = 0; + asicConnac2xInitTxdHook(prChipInfo->prTxDescOps); + asicConnac2xInitRxdHook(prChipInfo->prRxDescOps); +#if (CFG_SUPPORT_MSP == 1) + prChipInfo->asicRxProcessRxvforMSP = asicConnac2xRxProcessRxvforMSP; +#endif /* CFG_SUPPORT_MSP == 1 */ + prChipInfo->asicRxGetRcpiValueFromRxv = + asicConnac2xRxGetRcpiValueFromRxv; +#if (CFG_SUPPORT_PERF_IND == 1) + prChipInfo->asicRxPerfIndProcessRXV = asicConnac2xRxPerfIndProcessRXV; +#endif +#if (CFG_CHIP_RESET_SUPPORT == 1) && (CFG_WMT_RESET_API_SUPPORT == 0) + prChipInfo->rst_L0_notify_step2 = conn2_rst_L0_notify_step2; +#endif +#if CFG_SUPPORT_WIFI_SYSDVT + prAdapter->u2TxTest = TX_TEST_UNLIMITIED; + prAdapter->u2TxTestCount = 0; + prAdapter->ucTxTestUP = TX_TEST_UP_UNDEF; +#endif /* CFG_SUPPORT_WIFI_SYSDVT */ + +#if (CFG_SUPPORT_802_11AX == 1) + if (fgEfuseCtrlAxOn == 1) { + prAdapter->fgEnShowHETrigger = FALSE; + heRlmInitHeHtcACtrlOMAndUPH(prAdapter); + } +#endif + + switch (prGlueInfo->u4InfType) { +#if defined(_HIF_PCIE) || defined(_HIF_AXI) + case MT_DEV_INF_PCIE: + case MT_DEV_INF_AXI: + + prChipInfo->u2TxInitCmdPort = + TX_RING_CMD_IDX_2; /* Ring17 for CMD */ + prChipInfo->u2TxFwDlPort = + TX_RING_FWDL_IDX_3; /* Ring16 for FWDL */ + prChipInfo->ucPacketFormat = TXD_PKT_FORMAT_TXD; + prChipInfo->u4HifDmaShdlBaseAddr = CONNAC2X_HIF_DMASHDL_BASE; + prChipInfo->rx_event_port = WFDMA1_RX_RING_IDX_0; + + HAL_MCR_WR(prAdapter, + CONNAC2X_BN0_IRQ_ENA_ADDR, + BIT(0)); + + if (prChipInfo->is_support_asic_lp) { + HAL_MCR_WR(prAdapter, + CONNAC2X_WPDMA_MCU2HOST_SW_INT_MASK + (u4HostWpdamBase), + BITS(0, 15)); + } + break; +#endif /* _HIF_PCIE */ +#if defined(_HIF_USB) + case MT_DEV_INF_USB: + prChipInfo->u2HifTxdSize = USB_HIF_TXD_LEN; + prChipInfo->fillHifTxDesc = fillUsbHifTxDesc; + prChipInfo->u2TxInitCmdPort = USB_DATA_BULK_OUT_EP8; + prChipInfo->u2TxFwDlPort = USB_DATA_BULK_OUT_EP4; + if (prChipInfo->is_support_wacpu) + prChipInfo->ucPacketFormat = TXD_PKT_FORMAT_TXD; + else + prChipInfo->ucPacketFormat = + TXD_PKT_FORMAT_TXD_PAYLOAD; + prChipInfo->u4ExtraTxByteCount = + EXTRA_TXD_SIZE_FOR_TX_BYTE_COUNT; + prChipInfo->u4HifDmaShdlBaseAddr = USB_HIF_DMASHDL_BASE; + if (prBusInfo->DmaShdlInit) + prBusInfo->DmaShdlInit(prAdapter); + +#if (CFG_ENABLE_FW_DOWNLOAD == 1) + prChipInfo->asicEnableFWDownload = asicConnac2xEnableUsbFWDL; +#endif /* CFG_ENABLE_FW_DOWNLOAD == 1 */ + if (prChipInfo->asicUsbInit) + prChipInfo->asicUsbInit(prAdapter, prChipInfo); + asicConnac2xUdmaRxFlush(prAdapter, FALSE); + break; +#endif /* _HIF_USB */ + default: + break; + } +} + +static void asicConnac2xFillInitCmdTxdInfo( + struct ADAPTER *prAdapter, + struct WIFI_CMD_INFO *prCmdInfo, + u_int8_t *pucSeqNum) +{ + struct INIT_HIF_TX_HEADER *prInitHifTxHeader; + struct HW_MAC_CONNAC2X_TX_DESC *prInitHifTxHeaderPadding; + uint32_t u4TxdLen = sizeof(struct HW_MAC_CONNAC2X_TX_DESC); + + prInitHifTxHeaderPadding = + (struct HW_MAC_CONNAC2X_TX_DESC *) (prCmdInfo->pucInfoBuffer); + prInitHifTxHeader = (struct INIT_HIF_TX_HEADER *) + (prCmdInfo->pucInfoBuffer + u4TxdLen); + + HAL_MAC_CONNAC2X_TXD_SET_TX_BYTE_COUNT(prInitHifTxHeaderPadding, + prCmdInfo->u2InfoBufLen); + if (!prCmdInfo->ucCID) + HAL_MAC_CONNAC2X_TXD_SET_PKT_FORMAT(prInitHifTxHeaderPadding, + INIT_PKT_FT_PDA_FWDL) + else + HAL_MAC_CONNAC2X_TXD_SET_PKT_FORMAT(prInitHifTxHeaderPadding, + INIT_PKT_FT_CMD) + HAL_MAC_CONNAC2X_TXD_SET_HEADER_FORMAT(prInitHifTxHeaderPadding, + HEADER_FORMAT_COMMAND); + prInitHifTxHeader->rInitWifiCmd.ucCID = prCmdInfo->ucCID; + prInitHifTxHeader->rInitWifiCmd.ucPktTypeID = prCmdInfo->ucPktTypeID; + prInitHifTxHeader->rInitWifiCmd.ucSeqNum = + nicIncreaseCmdSeqNum(prAdapter); + prInitHifTxHeader->u2TxByteCount = + prCmdInfo->u2InfoBufLen - u4TxdLen; + + if (pucSeqNum) + *pucSeqNum = prInitHifTxHeader->rInitWifiCmd.ucSeqNum; + + DBGLOG(INIT, INFO, "TX CMD: ID[0x%02X] SEQ[%u] LEN[%u]\n", + prInitHifTxHeader->rInitWifiCmd.ucCID, + prInitHifTxHeader->rInitWifiCmd.ucSeqNum, + prCmdInfo->u2InfoBufLen); +} + + +static void asicConnac2xFillCmdTxdInfo( + struct ADAPTER *prAdapter, + struct WIFI_CMD_INFO *prCmdInfo, + u_int8_t *pucSeqNum) +{ + struct CONNAC2X_WIFI_CMD *prWifiCmd; + uint32_t u4TxdLen = sizeof(struct HW_MAC_CONNAC2X_TX_DESC); + + prWifiCmd = (struct CONNAC2X_WIFI_CMD *)prCmdInfo->pucInfoBuffer; + + HAL_MAC_CONNAC2X_TXD_SET_TX_BYTE_COUNT( + (struct HW_MAC_CONNAC2X_TX_DESC *)prWifiCmd, + prCmdInfo->u2InfoBufLen); + HAL_MAC_CONNAC2X_TXD_SET_PKT_FORMAT( + (struct HW_MAC_CONNAC2X_TX_DESC *)prWifiCmd, + INIT_PKT_FT_CMD); + HAL_MAC_CONNAC2X_TXD_SET_HEADER_FORMAT( + (struct HW_MAC_CONNAC2X_TX_DESC *)prWifiCmd, + HEADER_FORMAT_COMMAND); + + prWifiCmd->ucCID = prCmdInfo->ucCID; + prWifiCmd->ucExtenCID = prCmdInfo->ucExtCID; + prWifiCmd->ucPktTypeID = prCmdInfo->ucPktTypeID; + prWifiCmd->ucSetQuery = prCmdInfo->ucSetQuery; + prWifiCmd->ucSeqNum = nicIncreaseCmdSeqNum(prAdapter); + prWifiCmd->ucS2DIndex = prCmdInfo->ucS2DIndex; + prWifiCmd->u2Length = prCmdInfo->u2InfoBufLen - u4TxdLen; + + if (pucSeqNum) + *pucSeqNum = prWifiCmd->ucSeqNum; + + DBGLOG_LIMITED(INIT, INFO, + "TX CMD: ID[0x%02X] SEQ[%u] SET[%u] LEN[%u]\n", + prWifiCmd->ucCID, prWifiCmd->ucSeqNum, + prWifiCmd->ucSetQuery, prCmdInfo->u2InfoBufLen); +} + +void asicConnac2xFillInitCmdTxd( + struct ADAPTER *prAdapter, + struct WIFI_CMD_INFO *prCmdInfo, + u_int16_t *pu2BufInfoLen, + u_int8_t *pucSeqNum, OUT void **pCmdBuf) +{ + struct INIT_HIF_TX_HEADER *prInitHifTxHeader; + uint32_t u4TxdLen = sizeof(struct HW_MAC_CONNAC2X_TX_DESC); + + /* We don't need to append TXD while sending fw frames. */ + if (!prCmdInfo->ucCID && pCmdBuf) + *pCmdBuf = prCmdInfo->pucInfoBuffer; + else { + prInitHifTxHeader = (struct INIT_HIF_TX_HEADER *) + (prCmdInfo->pucInfoBuffer + u4TxdLen); + asicConnac2xFillInitCmdTxdInfo( + prAdapter, + prCmdInfo, + pucSeqNum); + if (pCmdBuf) + *pCmdBuf = + &prInitHifTxHeader->rInitWifiCmd.aucBuffer[0]; + } +} + +void asicConnac2xWfdmaDummyCrRead( + struct ADAPTER *prAdapter, + u_int8_t *pfgResult) +{ + u_int32_t u4RegValue = 0; + + HAL_MCR_RD(prAdapter, + CONNAC2X_WFDMA_DUMMY_CR, + &u4RegValue); + *pfgResult = (u4RegValue & + CONNAC2X_WFDMA_NEED_REINIT_BIT) + == 0 ? TRUE : FALSE; +} + + +void asicConnac2xWfdmaDummyCrWrite( + struct ADAPTER *prAdapter) +{ + u_int32_t u4RegValue = 0; + + HAL_MCR_RD(prAdapter, + CONNAC2X_WFDMA_DUMMY_CR, + &u4RegValue); + u4RegValue |= CONNAC2X_WFDMA_NEED_REINIT_BIT; + + HAL_MCR_WR(prAdapter, + CONNAC2X_WFDMA_DUMMY_CR, + u4RegValue); +} +void asicConnac2xWfdmaReInit( + struct ADAPTER *prAdapter) +{ + u_int8_t fgResult; + struct BUS_INFO *prBusInfo = prAdapter->chip_info->bus_info; + + /*WFDMA re-init flow after chip deep sleep*/ + asicConnac2xWfdmaDummyCrRead(prAdapter, &fgResult); + if (fgResult) { +#if defined(_HIF_PCIE) || defined(_HIF_AXI) + +#if 0 /* Original Driver re-init Host WFDAM flow */ + DBGLOG(INIT, INFO, "WFDMA host sw-reinit due to deep sleep\n"); + halWpdmaInitRing(prAdapter->prGlueInfo, false); +#else /* Do Driver re-init Host WFDMA flow with FW bk/sr solution */ + { + struct GL_HIF_INFO *prHifInfo; + uint32_t u4Idx; + + DBGLOG(INIT, TRACE, "WFDMA reinit after bk/sr(deep sleep)\n"); + prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + for (u4Idx = 0; u4Idx < NUM_OF_TX_RING; u4Idx++) { + prHifInfo->TxRing[u4Idx].TxSwUsedIdx = 0; + prHifInfo->TxRing[u4Idx].u4UsedCnt = 0; + prHifInfo->TxRing[u4Idx].TxCpuIdx = 0; + } + + if (halWpdmaGetRxDmaDoneCnt(prAdapter->prGlueInfo, + WFDMA1_RX_RING_IDX_0)) { + prAdapter->u4NoMoreRfb |= BIT(WFDMA1_RX_RING_IDX_0); + } + } +#endif + /* Write sleep mode magic num to dummy reg */ + if (prBusInfo->setDummyReg) + prBusInfo->setDummyReg(prAdapter->prGlueInfo); + +#endif /* _HIF_PCIE */ + asicConnac2xWfdmaDummyCrWrite(prAdapter); + } +} + +void asicConnac2xFillCmdTxd( + struct ADAPTER *prAdapter, + struct WIFI_CMD_INFO *prCmdInfo, + u_int8_t *pucSeqNum, + void **pCmdBuf) +{ + struct CONNAC2X_WIFI_CMD *prWifiCmd; + + /* 2. Setup common CMD Info Packet */ + prWifiCmd = (struct CONNAC2X_WIFI_CMD *)prCmdInfo->pucInfoBuffer; + asicConnac2xFillCmdTxdInfo(prAdapter, prCmdInfo, pucSeqNum); + if (pCmdBuf) + *pCmdBuf = &prWifiCmd->aucBuffer[0]; +} + +#if defined(_HIF_PCIE) || defined(_HIF_AXI) +uint32_t asicConnac2xWfdmaCfgAddrGet( + struct GLUE_INFO *prGlueInfo, + u_int8_t ucDmaIdx) +{ + struct BUS_INFO *prBusInfo = prGlueInfo->prAdapter->chip_info->bus_info; + + if (ucDmaIdx == 0) + return CONNAC2X_WPDMA_GLO_CFG(prBusInfo->host_dma0_base); + else + return CONNAC2X_WPDMA_GLO_CFG(prBusInfo->host_dma1_base); +} + +uint32_t asicConnac2xWfdmaIntRstDtxPtrAddrGet( + struct GLUE_INFO *prGlueInfo, + u_int8_t ucDmaIdx) +{ + struct BUS_INFO *prBusInfo = prGlueInfo->prAdapter->chip_info->bus_info; + + if (ucDmaIdx == 0) + return CONNAC2X_WPDMA_RST_DTX_PTR(prBusInfo->host_dma0_base); + else + return CONNAC2X_WPDMA_RST_DTX_PTR(prBusInfo->host_dma1_base); +} + +uint32_t asicConnac2xWfdmaIntRstDrxPtrAddrGet( + struct GLUE_INFO *prGlueInfo, + u_int8_t ucDmaIdx) +{ + struct BUS_INFO *prBusInfo = prGlueInfo->prAdapter->chip_info->bus_info; + + if (ucDmaIdx == 0) + return CONNAC2X_WPDMA_RST_DRX_PTR(prBusInfo->host_dma0_base); + else + return CONNAC2X_WPDMA_RST_DRX_PTR(prBusInfo->host_dma1_base); +} + +uint32_t asicConnac2xWfdmaHifRstAddrGet( + struct GLUE_INFO *prGlueInfo, + u_int8_t ucDmaIdx) +{ + struct BUS_INFO *prBusInfo = prGlueInfo->prAdapter->chip_info->bus_info; + + if (ucDmaIdx == 0) + return CONNAC2X_WPDMA_HIF_RST(prBusInfo->host_dma0_base); + else + return CONNAC2X_WPDMA_HIF_RST(prBusInfo->host_dma1_base); +} + +static void asicConnac2xWfdmaControl( + struct GLUE_INFO *prGlueInfo, + u_int8_t ucDmaIdx, + u_int8_t enable) +{ + struct ADAPTER *prAdapter = prGlueInfo->prAdapter; + union WPDMA_GLO_CFG_STRUCT GloCfg; + uint32_t u4DmaCfgCr; + uint32_t u4DmaRstDtxPtrCr; + uint32_t u4DmaRstDrxPtrCr; + + ASSERT(ucDmaIdx < CONNAC2X_WFDMA_COUNT); + u4DmaCfgCr = asicConnac2xWfdmaCfgAddrGet(prGlueInfo, ucDmaIdx); + u4DmaRstDtxPtrCr = + asicConnac2xWfdmaIntRstDtxPtrAddrGet(prGlueInfo, ucDmaIdx); + u4DmaRstDrxPtrCr = + asicConnac2xWfdmaIntRstDrxPtrAddrGet(prGlueInfo, ucDmaIdx); + + HAL_MCR_RD(prAdapter, u4DmaCfgCr, &GloCfg.word); + if (enable == TRUE) { + GloCfg.field_conn2x.pdma_bt_size = 3; + GloCfg.field_conn2x.tx_wb_ddone = 1; + GloCfg.field_conn2x.fifo_little_endian = 1; + GloCfg.field_conn2x.clk_gate_dis = 1; + GloCfg.field_conn2x.omit_tx_info = 1; + if (ucDmaIdx == 1) + GloCfg.field_conn2x.omit_rx_info = 1; + GloCfg.field_conn2x.csr_disp_base_ptr_chain_en = 1; + GloCfg.field_conn2x.omit_rx_info_pfet2 = 1; + } else { + GloCfg.field_conn2x.tx_dma_en = 0; + GloCfg.field_conn2x.rx_dma_en = 0; + GloCfg.field_conn2x.csr_disp_base_ptr_chain_en = 0; + GloCfg.field_conn2x.omit_tx_info = 0; + GloCfg.field_conn2x.omit_rx_info = 0; + GloCfg.field_conn2x.omit_rx_info_pfet2 = 0; + } + HAL_MCR_WR(prAdapter, u4DmaCfgCr, GloCfg.word); + + if (!enable) { + asicConnac2xWfdmaWaitIdle(prGlueInfo, ucDmaIdx, 100, 1000); + /* Reset DMA Index */ + HAL_MCR_WR(prAdapter, u4DmaRstDtxPtrCr, 0xFFFFFFFF); + HAL_MCR_WR(prAdapter, u4DmaRstDrxPtrCr, 0xFFFFFFFF); + } +} + +void asicConnac2xWpdmaConfig( + struct GLUE_INFO *prGlueInfo, + u_int8_t enable, + bool fgResetHif) +{ + struct ADAPTER *prAdapter = prGlueInfo->prAdapter; + union WPDMA_GLO_CFG_STRUCT GloCfg[CONNAC2X_WFDMA_COUNT] = {0}; + uint32_t u4DmaCfgCr; + uint32_t idx; + struct mt66xx_chip_info *chip_info = prAdapter->chip_info; + + for (idx = 0; idx < CONNAC2X_WFDMA_COUNT; idx++) { + if (!chip_info->is_support_wfdma1 && idx) + break; + asicConnac2xWfdmaControl(prGlueInfo, idx, enable); + u4DmaCfgCr = asicConnac2xWfdmaCfgAddrGet(prGlueInfo, idx); + HAL_MCR_RD(prAdapter, u4DmaCfgCr, &GloCfg[idx].word); + } + + if (enable) { + for (idx = 0; idx < CONNAC2X_WFDMA_COUNT; idx++) { + if (!chip_info->is_support_wfdma1 && idx) + break; + u4DmaCfgCr = + asicConnac2xWfdmaCfgAddrGet(prGlueInfo, idx); + GloCfg[idx].field_conn2x.tx_dma_en = 1; + GloCfg[idx].field_conn2x.rx_dma_en = 1; + HAL_MCR_WR(prAdapter, u4DmaCfgCr, GloCfg[idx].word); + } + } +} + +u_int8_t asicConnac2xWfdmaWaitIdle( + struct GLUE_INFO *prGlueInfo, + u_int8_t index, + uint32_t round, + uint32_t wait_us) +{ + uint32_t i = 0; + uint32_t u4RegAddr = 0; + union WPDMA_GLO_CFG_STRUCT GloCfg; + struct BUS_INFO *prBusInfo = prGlueInfo->prAdapter->chip_info->bus_info; + struct ADAPTER *prAdapter = prGlueInfo->prAdapter; + + if (index == 0) + u4RegAddr = prBusInfo->host_dma0_base; + else if (index == 1) + u4RegAddr = prBusInfo->host_dma1_base; + else { + DBGLOG(HAL, ERROR, "Unknown wfdma index(=%d)\n", index); + return FALSE; + } + + do { + HAL_MCR_RD(prAdapter, u4RegAddr, &GloCfg.word); + if ((GloCfg.field.TxDMABusy == 0) && + (GloCfg.field.RxDMABusy == 0)) { + DBGLOG(HAL, TRACE, "==> DMAIdle, GloCfg=0x%x\n", + GloCfg.word); + return TRUE; + } + kalUdelay(wait_us); + } while ((i++) < round); + + DBGLOG(HAL, INFO, "==> DMABusy, GloCfg=0x%x\n", GloCfg.word); + + return FALSE; +} + +void asicConnac2xWfdmaTxRingExtCtrl( + struct GLUE_INFO *prGlueInfo, + struct RTMP_TX_RING *tx_ring, + u_int32_t index) +{ + struct BUS_INFO *prBusInfo; + uint32_t ext_offset = 0; + struct ADAPTER *prAdapter = prGlueInfo->prAdapter; + struct mt66xx_chip_info *prChipInfo; + + prChipInfo = prGlueInfo->prAdapter->chip_info; + prBusInfo = prGlueInfo->prAdapter->chip_info->bus_info; + + if (index == TX_RING_CMD_IDX_2) + ext_offset = prBusInfo->tx_ring_cmd_idx * 4; + else if (index == TX_RING_FWDL_IDX_3) + ext_offset = prBusInfo->tx_ring_fwdl_idx * 4; + else if (prChipInfo->is_support_wacpu) { + if (index == TX_RING_DATA0_IDX_0) + ext_offset = prBusInfo->tx_ring0_data_idx * 4; + if (index == TX_RING_DATA1_IDX_1) + ext_offset = prBusInfo->tx_ring1_data_idx * 4; + if (index == TX_RING_WA_CMD_IDX_4) + ext_offset = prBusInfo->tx_ring_wa_cmd_idx * 4; + } else + ext_offset = index * 4; + + tx_ring->hw_desc_base_ext = + prBusInfo->host_tx_ring_ext_ctrl_base + ext_offset; + HAL_MCR_WR(prAdapter, tx_ring->hw_desc_base_ext, + CONNAC2X_TX_RING_DISP_MAX_CNT); +} + +void asicConnac2xWfdmaRxRingExtCtrl( + struct GLUE_INFO *prGlueInfo, + struct RTMP_RX_RING *rx_ring, + u_int32_t index) +{ + struct BUS_INFO *prBusInfo; + uint32_t ext_offset; + struct ADAPTER *prAdapter = prGlueInfo->prAdapter; + + prBusInfo = prGlueInfo->prAdapter->chip_info->bus_info; + + if (index >= WFDMA1_RX_RING_IDX_0) { + ext_offset = (index - WFDMA1_RX_RING_IDX_0) * 4; + rx_ring->hw_desc_base_ext = + prBusInfo->host_wfdma1_rx_ring_ext_ctrl_base + + ext_offset; + } else { + ext_offset = index * 4; + rx_ring->hw_desc_base_ext = + prBusInfo->host_rx_ring_ext_ctrl_base + ext_offset; + } + + HAL_MCR_WR(prAdapter, rx_ring->hw_desc_base_ext, + CONNAC2X_RX_RING_DISP_MAX_CNT); +} + +void asicConnac2xWfdmaManualPrefetch( + struct GLUE_INFO *prGlueInfo) +{ + struct ADAPTER *prAdapter = prGlueInfo->prAdapter; + u_int32_t val = 0; + + HAL_MCR_RD(prAdapter, WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR, &val); + /* disable prefetch offset calculation auto-mode */ + val &= + ~WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN_MASK; + HAL_MCR_WR(prAdapter, WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR, val); + + HAL_MCR_RD(prAdapter, WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR, &val); + /* disable prefetch offset calculation auto-mode */ + val &= + ~WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN_MASK; + HAL_MCR_WR(prAdapter, WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR, val); + + + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_EXT_CTRL_ADDR, 0x00000004); + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_EXT_CTRL_ADDR, 0x00400004); + + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_EXT_CTRL_ADDR, 0x00800004); + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_EXT_CTRL_ADDR, 0x00c00004); + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_EXT_CTRL_ADDR, 0x01000004); + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_EXT_CTRL_ADDR, 0x01400004); + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_EXT_CTRL_ADDR, 0x01800004); + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_EXT_CTRL_ADDR, 0x01c00004); + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_EXT_CTRL_ADDR, 0x02000004); + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_EXT_CTRL_ADDR, 0x02400004); + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_EXT_CTRL_ADDR, 0x02800004); + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_EXT_CTRL_ADDR, 0x02c00004); + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_EXT_CTRL_ADDR, 0x03000004); + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_EXT_CTRL_ADDR, 0x03400004); + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_EXT_CTRL_ADDR, 0x03800004); + + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_EXT_CTRL_ADDR, 0x03c00004); + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_EXT_CTRL_ADDR, 0x04000004); + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_EXT_CTRL_ADDR, 0x04400004); + + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_EXT_CTRL_ADDR, 0x04800004); + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_EXT_CTRL_ADDR, 0x04c00004); + + /* reset dma idx */ + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_ADDR, 0xFFFFFFFF); + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR, 0xFFFFFFFF); +} + +void asicConnac2xEnablePlatformIRQ(IN struct ADAPTER *prAdapter) +{ + struct GL_HIF_INFO *prHifInfo = NULL; + + ASSERT(prAdapter); + + prAdapter->fgIsIntEnable = TRUE; + + prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + enable_irq(prHifInfo->u4IrqId); +} + +void asicConnac2xDisablePlatformIRQ(IN struct ADAPTER *prAdapter) +{ + struct GL_HIF_INFO *prHifInfo = NULL; + + ASSERT(prAdapter); + + prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + disable_irq_nosync(prHifInfo->u4IrqId); + + prAdapter->fgIsIntEnable = FALSE; +} + +void asicConnac2xEnableExtInterrupt( + struct ADAPTER *prAdapter) +{ + + union WPDMA_INT_MASK IntMask; + + prAdapter->fgIsIntEnable = TRUE; + + IntMask.word = 0; + IntMask.field_conn2x_ext.wfdma0_rx_done_0 = 1; + IntMask.field_conn2x_ext.wfdma0_rx_done_1 = 1; + IntMask.field_conn2x_ext.wfdma0_rx_done_2 = 1; + IntMask.field_conn2x_ext.wfdma0_rx_done_3 = 1; + IntMask.field_conn2x_ext.wfdma1_rx_done_0 = 1; + IntMask.field_conn2x_ext.wfdma1_rx_done_1 = 1; + IntMask.field_conn2x_ext.wfdma1_rx_done_2 = 1; + + IntMask.field_conn2x_ext.wfdma1_tx_done_0 = 1; + /*IntMask.field_conn2x_ext.wfdma1_tx_done_1 = 1;*/ + IntMask.field_conn2x_ext.wfdma1_tx_done_16 = 1; + IntMask.field_conn2x_ext.wfdma1_tx_done_17 = 1; + IntMask.field_conn2x_ext.wfdma1_tx_done_18 = 1; + IntMask.field_conn2x_ext.wfdma1_tx_done_19 = 1; + IntMask.field_conn2x_ext.wfdma1_tx_done_20 = 1; + + IntMask.field_conn2x_ext.wfdma0_rx_coherent = 0; + IntMask.field_conn2x_ext.wfdma0_tx_coherent = 0; + IntMask.field_conn2x_ext.wfdma1_rx_coherent = 0; + IntMask.field_conn2x_ext.wfdma1_tx_coherent = 0; + + IntMask.field_conn2x_ext.wfdma1_mcu2host_sw_int_en = 1; + + HAL_MCR_WR(prAdapter, + CONNAC2X_WPDMA_EXT_INT_MASK(CONNAC2X_HOST_EXT_CONN_HIF_WRAP), + IntMask.word); + HAL_MCR_RD(prAdapter, + CONNAC2X_WPDMA_EXT_INT_MASK(CONNAC2X_HOST_EXT_CONN_HIF_WRAP), + &IntMask.word); + DBGLOG(HAL, TRACE, "%s [0x%08x]\n", __func__, IntMask.word); + + if (prAdapter->chip_info->is_support_wfdma1) { + /* WFDMA issue workaround : + * enable TX RX priority interrupt sel 7c025298/7c02529c + * to force writeback clear int_stat + */ + HAL_MCR_WR(prAdapter, + (CONNAC2X_HOST_WPDMA_1_BASE + 0x29c), 0x000f00ff); + HAL_MCR_WR(prAdapter, + (CONNAC2X_HOST_WPDMA_1_BASE + 0x298), 0xf); + } +} /* end of nicEnableInterrupt() */ + +void asicConnac2xDisableExtInterrupt( + struct ADAPTER *prAdapter) +{ + struct GLUE_INFO *prGlueInfo = NULL; + union WPDMA_INT_MASK IntMask; + + ASSERT(prAdapter); + + prGlueInfo = prAdapter->prGlueInfo; + + IntMask.word = 0; + + HAL_MCR_WR(prAdapter, + CONNAC2X_WPDMA_EXT_INT_MASK(CONNAC2X_HOST_EXT_CONN_HIF_WRAP), + IntMask.word); + HAL_MCR_RD(prAdapter, + CONNAC2X_WPDMA_EXT_INT_MASK(CONNAC2X_HOST_EXT_CONN_HIF_WRAP), + &IntMask.word); + + prAdapter->fgIsIntEnable = FALSE; + + DBGLOG(HAL, TRACE, "%s\n", __func__); + +} + +void asicConnac2xProcessTxInterrupt(IN struct ADAPTER *prAdapter) +{ + struct GL_HIF_INFO *prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + union WPDMA_INT_STA_STRUCT rIntrStatus; + + rIntrStatus = (union WPDMA_INT_STA_STRUCT)prHifInfo->u4IntStatus; + if (rIntrStatus.field_conn2x_ext.wfdma1_tx_done_16) + halWpdmaProcessCmdDmaDone(prAdapter->prGlueInfo, + TX_RING_FWDL_IDX_3); + + if (rIntrStatus.field_conn2x_ext.wfdma1_tx_done_17) + halWpdmaProcessCmdDmaDone(prAdapter->prGlueInfo, + TX_RING_CMD_IDX_2); + + if (rIntrStatus.field_conn2x_ext.wfdma1_tx_done_20) + halWpdmaProcessCmdDmaDone(prAdapter->prGlueInfo, + TX_RING_WA_CMD_IDX_4); + + if (rIntrStatus.field_conn2x_ext.wfdma1_tx_done_18) { + halWpdmaProcessDataDmaDone(prAdapter->prGlueInfo, + TX_RING_DATA0_IDX_0); + + kalSetTxEvent2Hif(prAdapter->prGlueInfo); + } + + if (rIntrStatus.field_conn2x_ext.wfdma1_tx_done_19) { + halWpdmaProcessDataDmaDone(prAdapter->prGlueInfo, + TX_RING_DATA1_IDX_1); + + kalSetTxEvent2Hif(prAdapter->prGlueInfo); + } + +} + +void asicConnac2xLowPowerOwnRead( + struct ADAPTER *prAdapter, + u_int8_t *pfgResult) +{ + struct mt66xx_chip_info *prChipInfo; + + prChipInfo = prAdapter->chip_info; + + if (prChipInfo->is_support_asic_lp) { + u_int32_t u4RegValue; + + HAL_MCR_RD(prAdapter, + CONNAC2X_BN0_LPCTL_ADDR, + &u4RegValue); + *pfgResult = (u4RegValue & + PCIE_LPCR_AP_HOST_OWNER_STATE_SYNC) + == 0 ? TRUE : FALSE; + } else + *pfgResult = TRUE; +} + +void asicConnac2xLowPowerOwnSet( + struct ADAPTER *prAdapter, + u_int8_t *pfgResult) +{ + struct mt66xx_chip_info *prChipInfo; + + prChipInfo = prAdapter->chip_info; + + if (prChipInfo->is_support_asic_lp) { + u_int32_t u4RegValue; + + HAL_MCR_WR(prAdapter, + CONNAC2X_BN0_LPCTL_ADDR, + PCIE_LPCR_HOST_SET_OWN); + HAL_MCR_RD(prAdapter, + CONNAC2X_BN0_LPCTL_ADDR, + &u4RegValue); + *pfgResult = (u4RegValue & + PCIE_LPCR_AP_HOST_OWNER_STATE_SYNC) == 0x4; + } else + *pfgResult = TRUE; +} + +void asicConnac2xLowPowerOwnClear( + struct ADAPTER *prAdapter, + u_int8_t *pfgResult) +{ + struct mt66xx_chip_info *prChipInfo; + + prChipInfo = prAdapter->chip_info; + + if (prChipInfo->is_support_asic_lp) { + u_int32_t u4RegValue; + + HAL_MCR_WR(prAdapter, + CONNAC2X_BN0_LPCTL_ADDR, + PCIE_LPCR_HOST_CLR_OWN); + HAL_MCR_RD(prAdapter, + CONNAC2X_BN0_LPCTL_ADDR, + &u4RegValue); + *pfgResult = (u4RegValue & + PCIE_LPCR_AP_HOST_OWNER_STATE_SYNC) == 0; + } else + *pfgResult = TRUE; +} + +void asicConnac2xProcessSoftwareInterrupt( + struct ADAPTER *prAdapter) +{ + struct GLUE_INFO *prGlueInfo; + struct GL_HIF_INFO *prHifInfo; + struct ERR_RECOVERY_CTRL_T *prErrRecoveryCtrl; + uint32_t u4Status = 0; + uint32_t u4HostWpdamBase = 0; + + if (prAdapter->prGlueInfo == NULL) { + DBGLOG(HAL, ERROR, "prGlueInfo is NULL\n"); + return; + } + + prGlueInfo = prAdapter->prGlueInfo; + prHifInfo = &prGlueInfo->rHifInfo; + prErrRecoveryCtrl = &prHifInfo->rErrRecoveryCtl; + + if (prAdapter->chip_info->is_support_wfdma1) + u4HostWpdamBase = CONNAC2X_HOST_WPDMA_1_BASE; + else + u4HostWpdamBase = CONNAC2X_HOST_WPDMA_0_BASE; + + kalDevRegRead(prGlueInfo, + CONNAC2X_WPDMA_MCU2HOST_SW_INT_STA(u4HostWpdamBase), + &u4Status); + + if (u4Status & ERROR_DETECT_MASK) { + prErrRecoveryCtrl->u4Status = u4Status; + kalDevRegWrite(prGlueInfo, + CONNAC2X_WPDMA_MCU2HOST_SW_INT_STA(u4HostWpdamBase), + u4Status); + halHwRecoveryFromError(prAdapter); + } else + kalDevRegWrite(prGlueInfo, + CONNAC2X_WPDMA_MCU2HOST_SW_INT_STA(u4HostWpdamBase), + u4Status); +} + + +void asicConnac2xSoftwareInterruptMcu( + struct ADAPTER *prAdapter, u_int32_t intrBitMask) +{ + struct GLUE_INFO *prGlueInfo; + uint32_t u4McuWpdamBase = 0; + + if (prAdapter == NULL || prAdapter->prGlueInfo == NULL) { + DBGLOG(HAL, ERROR, "prAdapter or prGlueInfo is NULL\n"); + return; + } + + prGlueInfo = prAdapter->prGlueInfo; + if (prAdapter->chip_info->is_support_wfdma1) + u4McuWpdamBase = CONNAC2X_MCU_WPDMA_1_BASE; + else + u4McuWpdamBase = CONNAC2X_MCU_WPDMA_0_BASE; + kalDevRegWrite(prGlueInfo, + CONNAC2X_WPDMA_HOST2MCU_SW_INT_SET(u4McuWpdamBase), + intrBitMask); +} + + +void asicConnac2xHifRst( + struct GLUE_INFO *prGlueInfo) +{ + uint32_t u4HifRstCr; + + u4HifRstCr = asicConnac2xWfdmaHifRstAddrGet(prGlueInfo, 0); + /* Reset dmashdl and wpdma */ + kalDevRegWrite(prGlueInfo, u4HifRstCr, 0x00000000); + kalDevRegWrite(prGlueInfo, u4HifRstCr, 0x00000030); + + u4HifRstCr = asicConnac2xWfdmaHifRstAddrGet(prGlueInfo, 1); + /* Reset dmashdl and wpdma */ + kalDevRegWrite(prGlueInfo, u4HifRstCr, 0x00000000); + kalDevRegWrite(prGlueInfo, u4HifRstCr, 0x00000030); +} + +void asicConnac2xReadExtIntStatus( + struct ADAPTER *prAdapter, + uint32_t *pu4IntStatus) +{ + uint32_t u4RegValue = 0; + struct GL_HIF_INFO *prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + struct BUS_INFO *prBusInfo = prAdapter->chip_info->bus_info; + + *pu4IntStatus = 0; + + HAL_MCR_RD(prAdapter, + CONNAC2X_WPDMA_EXT_INT_STA( + prBusInfo->host_ext_conn_hif_wrap_base), + &u4RegValue); + + if (HAL_IS_CONNAC2X_EXT_RX_DONE_INTR(u4RegValue, + prBusInfo->host_int_rxdone_bits)) + *pu4IntStatus |= WHISR_RX0_DONE_INT; + + if (HAL_IS_CONNAC2X_EXT_TX_DONE_INTR(u4RegValue, + prBusInfo->host_int_txdone_bits)) + *pu4IntStatus |= WHISR_TX_DONE_INT; + + if (u4RegValue & CONNAC_MCU_SW_INT) + *pu4IntStatus |= WHISR_D2H_SW_INT; + + prHifInfo->u4IntStatus = u4RegValue; + + /* clear interrupt */ + HAL_MCR_WR(prAdapter, + CONNAC2X_WPDMA_EXT_INT_STA( + prBusInfo->host_ext_conn_hif_wrap_base), + u4RegValue); +} + +void asicConnac2xProcessRxInterrupt( + struct ADAPTER *prAdapter) +{ + struct GL_HIF_INFO *prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + union WPDMA_INT_STA_STRUCT rIntrStatus; + + rIntrStatus = (union WPDMA_INT_STA_STRUCT)prHifInfo->u4IntStatus; + if (rIntrStatus.field_conn2x_ext.wfdma1_rx_done_0) + halRxReceiveRFBs(prAdapter, WFDMA1_RX_RING_IDX_0, FALSE); + if (rIntrStatus.field_conn2x_ext.wfdma1_rx_done_1) + halRxReceiveRFBs(prAdapter, WFDMA1_RX_RING_IDX_1, FALSE); + if (rIntrStatus.field_conn2x_ext.wfdma1_rx_done_2) + halRxReceiveRFBs(prAdapter, WFDMA1_RX_RING_IDX_2, FALSE); + if (rIntrStatus.field_conn2x_ext.wfdma0_rx_done_0) + halRxReceiveRFBs(prAdapter, RX_RING_DATA_IDX_0, TRUE); + if (rIntrStatus.field_conn2x_ext.wfdma0_rx_done_1) + halRxReceiveRFBs(prAdapter, RX_RING_EVT_IDX_1, TRUE); + if (rIntrStatus.field_conn2x_ext.wfdma0_rx_done_2) + halRxReceiveRFBs(prAdapter, WFDMA0_RX_RING_IDX_2, TRUE); + if (rIntrStatus.field_conn2x_ext.wfdma0_rx_done_3) + halRxReceiveRFBs(prAdapter, WFDMA0_RX_RING_IDX_3, TRUE); +} +#endif /* _HIF_PCIE */ + +#if defined(_HIF_USB) +/* + * tx_ring config + * 1.1tx_ring_ext_ctrl + * 7c025600[31:0]: 0x00800004 (ring 0 BASE_PTR & max_cnt for EP4) + * 7c025604[31:0]: 0x00c00004 (ring 1 BASE_PTR & max_cnt for EP5) + * 7c025608[31:0]: 0x01000004 (ring 2 BASE_PTR & max_cnt for EP6) + * 7c02560c[31:0]: 0x01400004 (ring 3 BASE_PTR & max_cnt for EP7) + * 7c025610[31:0]: 0x01800004 (ring 4 BASE_PTR & max_cnt for EP9) + * 7c025640[31:0]: 0x02800004 (ring 16 BASE_PTR & max_cnt for EP4/FWDL) + * 7c025644[31:0]: 0x02c00004 (ring 17 BASE_PTR & max_cnt for EP8/WMCPU) + * 7c025650[31:0]: 0x03800004 (ring 20 BASE_PTR & max_cnt for EP8/WACPU) + * + * WFDMA_GLO_CFG Setting + * 2.1 WFDMA_GLO_CFG: 7c025208[28][27]=2'b11; + * 2.2 WFDMA_GLO_CFG: 7c025208[20]=1'b1; + * 2.3 WFDMA_GLO_CFG: 7c025208[9]=1'b1; + * + * 3. trx_dma_en: + * 3.1 WFDMA_GLO_CFG: 7c025208[2][0]=1'b1; + */ +void asicConnac2xWfdmaInitForUSB( + struct ADAPTER *prAdapter, + struct mt66xx_chip_info *prChipInfo) +{ + struct BUS_INFO *prBusInfo; + uint32_t idx; + uint32_t u4WfdmaAddr, u4WfdmaCr; + + prBusInfo = prChipInfo->bus_info; + + if (prChipInfo->is_support_wfdma1) { + u4WfdmaAddr = + CONNAC2X_TX_RING_EXT_CTRL_BASE(CONNAC2X_HOST_WPDMA_1_BASE); + } else { + u4WfdmaAddr = + CONNAC2X_TX_RING_EXT_CTRL_BASE(CONNAC2X_HOST_WPDMA_0_BASE); + } + /* + * HOST_DMA1_WPDMA_TX_RING0_EXT_CTRL ~ HOST_DMA1_WPDMA_TX_RING4_EXT_CTRL + */ + for (idx = 0; idx < USB_TX_EPOUT_NUM; idx++) { + HAL_MCR_RD(prAdapter, u4WfdmaAddr + (idx*4), &u4WfdmaCr); + u4WfdmaCr &= ~CONNAC2X_WFDMA_DISP_MAX_CNT_MASK; + u4WfdmaCr |= CONNAC2X_TX_RING_DISP_MAX_CNT; + u4WfdmaCr &= ~CONNAC2X_WFDMA_DISP_BASE_PTR_MASK; + u4WfdmaCr |= (0x008 + 0x4 * idx)<<20; + HAL_MCR_WR(prAdapter, u4WfdmaAddr + (idx*4), u4WfdmaCr); + } + + /* HOST_DMA1_WPDMA_TX_RING16_EXT_CTRL_ADDR */ + HAL_MCR_RD(prAdapter, u4WfdmaAddr + 0x40, &u4WfdmaCr); + u4WfdmaCr &= ~CONNAC2X_WFDMA_DISP_MAX_CNT_MASK; + u4WfdmaCr |= CONNAC2X_TX_RING_DISP_MAX_CNT; + u4WfdmaCr &= ~CONNAC2X_WFDMA_DISP_BASE_PTR_MASK; + u4WfdmaCr |= 0x02800000; + HAL_MCR_WR(prAdapter, u4WfdmaAddr + 0x40, u4WfdmaCr); + + /* HOST_DMA1_WPDMA_TX_RING17_EXT_CTRL_ADDR */ + HAL_MCR_RD(prAdapter, u4WfdmaAddr + 0x44, &u4WfdmaCr); + u4WfdmaCr &= ~CONNAC2X_WFDMA_DISP_MAX_CNT_MASK; + u4WfdmaCr |= CONNAC2X_TX_RING_DISP_MAX_CNT; + u4WfdmaCr &= ~CONNAC2X_WFDMA_DISP_BASE_PTR_MASK; + u4WfdmaCr |= 0x02c00000; + HAL_MCR_WR(prAdapter, u4WfdmaAddr + 0x44, u4WfdmaCr); + + + if (prChipInfo->is_support_wacpu) { + /* HOST_DMA1_WPDMA_TX_RING20_EXT_CTRL_ADDR */ + HAL_MCR_RD(prAdapter, u4WfdmaAddr + 0x50, &u4WfdmaCr); + u4WfdmaCr &= ~CONNAC2X_WFDMA_DISP_MAX_CNT_MASK; + u4WfdmaCr |= CONNAC2X_TX_RING_DISP_MAX_CNT; + u4WfdmaCr &= ~CONNAC2X_WFDMA_DISP_BASE_PTR_MASK; + u4WfdmaCr |= 0x03800000; + HAL_MCR_WR(prAdapter, u4WfdmaAddr + 0x50, u4WfdmaCr); + } + + if (prChipInfo->is_support_wfdma1) { + u4WfdmaAddr = + CONNAC2X_WPDMA_GLO_CFG(CONNAC2X_HOST_WPDMA_1_BASE); + HAL_MCR_RD(prAdapter, u4WfdmaAddr, &u4WfdmaCr); + u4WfdmaCr |= + (CONNAC2X_WPDMA1_GLO_CFG_OMIT_TX_INFO | + CONNAC2X_WPDMA1_GLO_CFG_OMIT_RX_INFO | + CONNAC2X_WPDMA1_GLO_CFG_FW_DWLD_Bypass_dmashdl | + CONNAC2X_WPDMA1_GLO_CFG_RX_DMA_EN | + CONNAC2X_WPDMA1_GLO_CFG_TX_DMA_EN); + HAL_MCR_WR(prAdapter, u4WfdmaAddr, u4WfdmaCr); + + /* Enable WFDMA0 RX for receiving data frame */ + u4WfdmaAddr = + CONNAC2X_WPDMA_GLO_CFG(CONNAC2X_HOST_WPDMA_0_BASE); + HAL_MCR_RD(prAdapter, u4WfdmaAddr, &u4WfdmaCr); + u4WfdmaCr |= + (CONNAC2X_WPDMA1_GLO_CFG_RX_DMA_EN); + HAL_MCR_WR(prAdapter, u4WfdmaAddr, u4WfdmaCr); + } else { + u4WfdmaAddr = + CONNAC2X_WPDMA_GLO_CFG(CONNAC2X_HOST_WPDMA_0_BASE); + HAL_MCR_RD(prAdapter, u4WfdmaAddr, &u4WfdmaCr); + u4WfdmaCr &= ~(CONNAC2X_WPDMA1_GLO_CFG_OMIT_RX_INFO); + u4WfdmaCr |= + (CONNAC2X_WPDMA1_GLO_CFG_OMIT_TX_INFO | + CONNAC2X_WPDMA1_GLO_CFG_OMIT_RX_INFO_PFET2 | + CONNAC2X_WPDMA1_GLO_CFG_FW_DWLD_Bypass_dmashdl | + CONNAC2X_WPDMA1_GLO_CFG_RX_DMA_EN | + CONNAC2X_WPDMA1_GLO_CFG_TX_DMA_EN); + HAL_MCR_WR(prAdapter, u4WfdmaAddr, u4WfdmaCr); + + } + + prChipInfo->is_support_dma_shdl = wlanCfgGetUint32(prAdapter, + "DmaShdlEnable", + FEATURE_ENABLED); + if (!prChipInfo->is_support_dma_shdl) { + /* + * To disable 0x7C0252B0[6] DMASHDL + */ + if (prChipInfo->is_support_wfdma1) { + u4WfdmaAddr = CONNAC2X_WPDMA_GLO_CFG_EXT0( + CONNAC2X_HOST_WPDMA_1_BASE); + } else { + u4WfdmaAddr = CONNAC2X_WPDMA_GLO_CFG_EXT0( + CONNAC2X_HOST_WPDMA_0_BASE); + } + HAL_MCR_RD(prAdapter, u4WfdmaAddr, &u4WfdmaCr); + u4WfdmaCr &= ~CONNAC2X_WPDMA1_GLO_CFG_EXT0_TX_DMASHDL_EN; + HAL_MCR_WR(prAdapter, u4WfdmaAddr, u4WfdmaCr); + + /* + * [28]DMASHDL_BYPASS + * DMASHDL host ask and quota control function bypass + * 0: Disable + * 1: Enable + */ + u4WfdmaAddr = CONNAC2X_HOST_DMASHDL_SW_CONTROL( + CONNAC2X_HOST_DMASHDL); + HAL_MCR_RD(prAdapter, u4WfdmaAddr, &u4WfdmaCr); + u4WfdmaCr |= CONNAC2X_HIF_DMASHDL_BYPASS_EN; + HAL_MCR_WR(prAdapter, u4WfdmaAddr, u4WfdmaCr); + } + + if (prChipInfo->asicUsbInit_ic_specific) + prChipInfo->asicUsbInit_ic_specific(prAdapter, prChipInfo); +} + +static void asicConnac2xUsbRxEvtEP4Setting( + struct ADAPTER *prAdapter, + u_int8_t fgEnable) +{ + struct GLUE_INFO *prGlueInfo; + struct BUS_INFO *prBusInfo; + uint32_t u4Value = 0; + uint32_t u4WfdmaValue = 0; + uint32_t i = 0; + uint32_t dma_base; + + ASSERT(prAdapter); + + prGlueInfo = prAdapter->prGlueInfo; + prBusInfo = prAdapter->chip_info->bus_info; + if (prAdapter->chip_info->is_support_wfdma1) + dma_base = CONNAC2X_HOST_WPDMA_1_BASE; + else + dma_base = CONNAC2X_HOST_WPDMA_0_BASE; + HAL_MCR_RD(prAdapter, CONNAC2X_WFDMA_HOST_CONFIG_ADDR, &u4WfdmaValue); + if (fgEnable) + u4WfdmaValue |= CONNAC2X_WFDMA_HOST_CONFIG_USB_RXEVT_EP4_EN; + else + u4WfdmaValue &= ~CONNAC2X_WFDMA_HOST_CONFIG_USB_RXEVT_EP4_EN; + do { + HAL_MCR_RD(prAdapter, CONNAC2X_WPDMA_GLO_CFG(dma_base), + &u4Value); + if ((u4Value & CONNAC2X_WPDMA1_GLO_CFG_RX_DMA_BUSY) == 0) { + u4Value &= ~CONNAC2X_WPDMA1_GLO_CFG_RX_DMA_EN; + HAL_MCR_WR(prAdapter, CONNAC2X_WPDMA_GLO_CFG(dma_base), + u4Value); + break; + } + kalUdelay(1000); + } while ((i++) < 100); + if (i > 100) + DBGLOG(HAL, ERROR, "WFDMA1 RX keep busy....\n"); + else { + HAL_MCR_WR(prAdapter, + CONNAC2X_WFDMA_HOST_CONFIG_ADDR, + u4WfdmaValue); + HAL_MCR_RD(prAdapter, CONNAC2X_WPDMA_GLO_CFG(dma_base), + &u4Value); + u4Value |= CONNAC2X_WPDMA1_GLO_CFG_RX_DMA_EN; + HAL_MCR_WR(prAdapter, CONNAC2X_WPDMA_GLO_CFG(dma_base), + u4Value); + } +} + + +uint8_t asicConnac2xUsbEventEpDetected(IN struct ADAPTER *prAdapter) +{ + struct GL_HIF_INFO *prHifInfo = NULL; + struct GLUE_INFO *prGlueInfo = NULL; + struct BUS_INFO *prBusInfo = NULL; + int32_t ret = 0; + uint8_t ucRetryCount = 0; + u_int8_t ucEp5Disable = FALSE; + + ASSERT(FALSE == 0); + prGlueInfo = prAdapter->prGlueInfo; + prHifInfo = &prGlueInfo->rHifInfo; + prBusInfo = prGlueInfo->prAdapter->chip_info->bus_info; + + if (prHifInfo->fgEventEpDetected == FALSE) { + prHifInfo->fgEventEpDetected = TRUE; + do { + ret = mtk_usb_vendor_request(prGlueInfo, 0, + prBusInfo->u4device_vender_request_in, + VND_REQ_EP5_IN_INFO, + 0, 0, &ucEp5Disable, + sizeof(ucEp5Disable)); + if (ret || ucRetryCount) + DBGLOG(HAL, ERROR, + "usb_control_msg() status: %x retry: %u\n", + (unsigned int)ret, ucRetryCount); + ucRetryCount++; + if (ucRetryCount > USB_ACCESS_RETRY_LIMIT) + break; + } while (ret); + + if (ret) { + kalSendAeeWarning(HIF_USB_ERR_TITLE_STR, + HIF_USB_ERR_DESC_STR + "USB() reports error: %x retry: %u", + ret, ucRetryCount); + DBGLOG(HAL, ERROR, + "usb_readl() reports error: %x retry: %u\n", ret, + ucRetryCount); + } else { + DBGLOG(HAL, INFO, + "%s: Get ucEp5Disable = %d\n", __func__, + ucEp5Disable); + if (ucEp5Disable) + prHifInfo->eEventEpType = EVENT_EP_TYPE_DATA_EP; + } + + if (prHifInfo->eEventEpType == EVENT_EP_TYPE_DATA_EP) + asicConnac2xUsbRxEvtEP4Setting(prAdapter, TRUE); + else + asicConnac2xUsbRxEvtEP4Setting(prAdapter, FALSE); + } + + if (prHifInfo->eEventEpType == EVENT_EP_TYPE_DATA_EP) + return USB_DATA_EP_IN; + else + return USB_EVENT_EP_IN; +} + +void asicConnac2xEnableUsbCmdTxRing( + struct ADAPTER *prAdapter, + u_int8_t ucDstRing) +{ + struct GLUE_INFO *prGlueInfo; + struct BUS_INFO *prBusInfo; + uint32_t u4Value = 0; + uint32_t u4WfdmaValue = 0; + uint32_t i = 0; + uint32_t dma_base; + ASSERT(prAdapter); + + prGlueInfo = prAdapter->prGlueInfo; + prBusInfo = prAdapter->chip_info->bus_info; + if (prAdapter->chip_info->is_support_wfdma1) + dma_base = CONNAC2X_HOST_WPDMA_1_BASE; + else + dma_base = CONNAC2X_HOST_WPDMA_0_BASE; + + HAL_MCR_RD(prAdapter, CONNAC2X_WFDMA_HOST_CONFIG_ADDR, &u4WfdmaValue); + u4WfdmaValue &= ~CONNAC2X_WFDMA_HOST_CONFIG_USB_CMDPKT_DST_MASK; + u4WfdmaValue |= CONNAC2X_WFDMA_HOST_CONFIG_USB_CMDPKT_DST(ucDstRing); + do { + HAL_MCR_RD(prAdapter, CONNAC2X_WPDMA_GLO_CFG(dma_base), + &u4Value); + if ((u4Value & CONNAC2X_WPDMA1_GLO_CFG_TX_DMA_BUSY) == 0) { + u4Value &= ~CONNAC2X_WPDMA1_GLO_CFG_TX_DMA_EN; + HAL_MCR_WR(prAdapter, CONNAC2X_WPDMA_GLO_CFG(dma_base), + u4Value); + break; + } + kalUdelay(1000); + } while ((i++) < 100); + if (i > 100) + DBGLOG(HAL, ERROR, "WFDMA1 TX keep busy....\n"); + else { + HAL_MCR_WR(prAdapter, + CONNAC2X_WFDMA_HOST_CONFIG_ADDR, + u4WfdmaValue); + HAL_MCR_RD(prAdapter, CONNAC2X_WPDMA_GLO_CFG(dma_base), + &u4Value); + u4Value |= CONNAC2X_WPDMA1_GLO_CFG_TX_DMA_EN; + HAL_MCR_WR(prAdapter, CONNAC2X_WPDMA_GLO_CFG(dma_base), + u4Value); + } +} + +#if CFG_ENABLE_FW_DOWNLOAD +void asicConnac2xEnableUsbFWDL( + struct ADAPTER *prAdapter, + u_int8_t fgEnable) +{ + struct GLUE_INFO *prGlueInfo; + struct BUS_INFO *prBusInfo; + struct mt66xx_chip_info *prChipInfo; + + uint32_t u4Value = 0; + + ASSERT(prAdapter); + + prGlueInfo = prAdapter->prGlueInfo; + prChipInfo = prAdapter->chip_info; + prBusInfo = prChipInfo->bus_info; + + HAL_MCR_RD(prAdapter, prBusInfo->u4UdmaTxQsel, &u4Value); + if (fgEnable) { + u4Value |= FW_DL_EN; + } else { + u4Value &= ~FW_DL_EN; + } + + HAL_MCR_WR(prAdapter, prBusInfo->u4UdmaTxQsel, u4Value); + + if (prChipInfo->is_support_wacpu) { + /* command packet forward to TX ring 17 (WMCPU) or + * TX ring 20 (WACPU) + */ + asicConnac2xEnableUsbCmdTxRing(prAdapter, + fgEnable ? CONNAC2X_USB_CMDPKT2WM : + CONNAC2X_USB_CMDPKT2WA); + } +} +#endif /* CFG_ENABLE_FW_DOWNLOAD */ +u_int8_t asicConnac2xUsbResume(IN struct ADAPTER *prAdapter, + IN struct GLUE_INFO *prGlueInfo) +{ + uint8_t count = 0; + struct mt66xx_chip_info *prChipInfo = NULL; + + prChipInfo = prAdapter->chip_info; + +#if 0 /* enable it if need to do bug fixing by vender request */ + /* NOTE: USB bus may not really do suspend and resume*/ + ret = usb_control_msg(prGlueInfo->rHifInfo.udev, + usb_sndctrlpipe(prGlueInfo->rHifInfo.udev, 0), + VND_REQ_FEATURE_SET, + prBusInfo->u4device_vender_request_out, + FEATURE_SET_WVALUE_RESUME, 0, NULL, 0, + VENDOR_TIMEOUT_MS); + if (ret) + DBGLOG(HAL, ERROR, + "VendorRequest FeatureSetResume ERROR: %x\n", + (unsigned int)ret); +#endif + + glUsbSetState(&prGlueInfo->rHifInfo, USB_STATE_PRE_RESUME); + + /* reinit USB because LP could clear WFDMA's CR */ + if (prChipInfo->is_support_asic_lp && prChipInfo->asicUsbInit) + prChipInfo->asicUsbInit(prAdapter, prChipInfo); + + /* To trigger CR4 path */ + wlanSendDummyCmd(prGlueInfo->prAdapter, FALSE); + halEnableInterrupt(prGlueInfo->prAdapter); + + /* using inband cmd to inform FW instead of vendor request */ + /* All Resume operations move to FW */ + halUSBPreResumeCmd(prGlueInfo->prAdapter); + + while (prGlueInfo->rHifInfo.state != USB_STATE_LINK_UP) { + if (count > 50) { + DBGLOG(HAL, ERROR, "pre_resume timeout\n"); + break; + } + msleep(20); + count++; + } + + DBGLOG(HAL, STATE, "pre_resume event check(count %d)\n", count); + + wlanResumePmHandle(prGlueInfo); + + return TRUE; +} + +void asicConnac2xUdmaRxFlush( + struct ADAPTER *prAdapter, + u_int8_t bEnable) +{ + struct BUS_INFO *prBusInfo; + uint32_t u4Value; + + prBusInfo = prAdapter->chip_info->bus_info; + + HAL_MCR_RD(prAdapter, prBusInfo->u4UdmaWlCfg_0_Addr, + &u4Value); + if (bEnable) + u4Value |= UDMA_WLCFG_0_RX_FLUSH_MASK; + else + u4Value &= ~UDMA_WLCFG_0_RX_FLUSH_MASK; + HAL_MCR_WR(prAdapter, prBusInfo->u4UdmaWlCfg_0_Addr, + u4Value); +} + +uint16_t asicConnac2xUsbRxByteCount( + struct ADAPTER *prAdapter, + struct BUS_INFO *prBusInfo, + uint8_t *pRXD) +{ + + uint16_t u2RxByteCount; + uint8_t ucPacketType; + + ucPacketType = HAL_MAC_CONNAC2X_RX_STATUS_GET_PKT_TYPE( + (struct HW_MAC_CONNAC2X_RX_DESC *)pRXD); + u2RxByteCount = HAL_MAC_CONNAC2X_RX_STATUS_GET_RX_BYTE_CNT( + (struct HW_MAC_CONNAC2X_RX_DESC *)pRXD); + + /* According to Barry's rule, it can be summarized as below formula: + * 1. Event packet (including WIFI packet sent by MCU) + -> RX padding for 4B alignment + * 2. WIFI packet from UMAC + * -> RX padding for 8B alignment first, + then extra 4B padding + */ + if (ucPacketType == RX_PKT_TYPE_RX_DATA) + u2RxByteCount = ALIGN_8(u2RxByteCount) + + LEN_USB_RX_PADDING_CSO; + else + u2RxByteCount = ALIGN_4(u2RxByteCount); + + return u2RxByteCount; +} + +#endif /* _HIF_USB */ + +void fillConnac2xTxDescTxByteCount( + struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo, + void *prTxDesc) +{ + struct mt66xx_chip_info *prChipInfo; + uint32_t u4TxByteCount = NIC_TX_DESC_LONG_FORMAT_LENGTH; + + ASSERT(prAdapter); + ASSERT(prMsduInfo); + ASSERT(prTxDesc); + + prChipInfo = prAdapter->chip_info; + u4TxByteCount += prMsduInfo->u2FrameLength; + + if (prMsduInfo->ucPacketType == TX_PACKET_TYPE_DATA) + u4TxByteCount += prChipInfo->u4ExtraTxByteCount; + + /* Calculate Tx byte count */ + HAL_MAC_CONNAC2X_TXD_SET_TX_BYTE_COUNT( + (struct HW_MAC_CONNAC2X_TX_DESC *)prTxDesc, u4TxByteCount); +} + +void fillConnac2xTxDescAppendWithWaCpu( + struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo, + uint8_t *prTxDescBuffer) +{ + struct mt66xx_chip_info *prChipInfo = prAdapter->chip_info; + union HW_MAC_TX_DESC_APPEND *prHwTxDescAppend; + + /* Fill TxD append */ + prHwTxDescAppend = (union HW_MAC_TX_DESC_APPEND *) + prTxDescBuffer; + kalMemZero(prHwTxDescAppend, prChipInfo->txd_append_size); + prHwTxDescAppend->CR4_APPEND.u2PktFlags = + HIF_PKT_FLAGS_CT_INFO_APPLY_TXD; + prHwTxDescAppend->CR4_APPEND.ucBssIndex = + prMsduInfo->ucBssIndex; + prHwTxDescAppend->CR4_APPEND.ucWtblIndex = + prMsduInfo->ucWlanIndex; +} + +void fillConnac2xTxDescAppendByWaCpu( + struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo, + uint16_t u4MsduId, + dma_addr_t rDmaAddr, + uint32_t u4Idx, + u_int8_t fgIsLast, + uint8_t *pucBuffer) +{ + union HW_MAC_TX_DESC_APPEND *prHwTxDescAppend; + + prHwTxDescAppend = (union HW_MAC_TX_DESC_APPEND *) + (pucBuffer + NIC_TX_DESC_LONG_FORMAT_LENGTH); + prHwTxDescAppend->CR4_APPEND.u2MsduToken = u4MsduId; + prHwTxDescAppend->CR4_APPEND.ucBufNum = u4Idx + 1; + prHwTxDescAppend->CR4_APPEND.au4BufPtr[u4Idx] = rDmaAddr; + prHwTxDescAppend->CR4_APPEND.au2BufLen[u4Idx] = + prMsduInfo->u2FrameLength; +} + +void fillTxDescTxByteCountWithWaCpu( + struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo, + void *prTxDesc) +{ + struct mt66xx_chip_info *prChipInfo; + uint32_t u4TxByteCount = NIC_TX_DESC_LONG_FORMAT_LENGTH; + + ASSERT(prAdapter); + ASSERT(prMsduInfo); + ASSERT(prTxDesc); + + prChipInfo = prAdapter->chip_info; + u4TxByteCount += prMsduInfo->u2FrameLength; + + if (prMsduInfo->ucPacketType == TX_PACKET_TYPE_DATA) + u4TxByteCount += prChipInfo->txd_append_size; + + /* Calculate Tx byte count */ + HAL_MAC_CONNAC2X_TXD_SET_TX_BYTE_COUNT( + (struct HW_MAC_CONNAC2X_TX_DESC *)prTxDesc, u4TxByteCount); +} + +void asicConnac2xInitTxdHook( + struct TX_DESC_OPS_T *prTxDescOps) +{ + ASSERT(prTxDescOps); + prTxDescOps->nic_txd_long_format_op = nic_txd_v2_long_format_op; + prTxDescOps->nic_txd_tid_op = nic_txd_v2_tid_op; + prTxDescOps->nic_txd_queue_idx_op = nic_txd_v2_queue_idx_op; +#if (CFG_TCP_IP_CHKSUM_OFFLOAD == 1) + prTxDescOps->nic_txd_chksum_op = nic_txd_v2_chksum_op; +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD == 1 */ + prTxDescOps->nic_txd_header_format_op = nic_txd_v2_header_format_op; + prTxDescOps->nic_txd_fill_by_pkt_option = nic_txd_v2_fill_by_pkt_option; + prTxDescOps->nic_txd_compose = nic_txd_v2_compose; + prTxDescOps->nic_txd_compose_security_frame = + nic_txd_v2_compose_security_frame; + prTxDescOps->nic_txd_set_pkt_fixed_rate_option_full = + nic_txd_v2_set_pkt_fixed_rate_option_full; + prTxDescOps->nic_txd_set_pkt_fixed_rate_option = + nic_txd_v2_set_pkt_fixed_rate_option; + prTxDescOps->nic_txd_set_hw_amsdu_template = + nic_txd_v2_set_hw_amsdu_template; +} + +void asicConnac2xInitRxdHook( + struct RX_DESC_OPS_T *prRxDescOps) +{ + ASSERT(prRxDescOps); + prRxDescOps->nic_rxd_get_rx_byte_count = nic_rxd_v2_get_rx_byte_count; + prRxDescOps->nic_rxd_get_pkt_type = nic_rxd_v2_get_packet_type; + prRxDescOps->nic_rxd_get_wlan_idx = nic_rxd_v2_get_wlan_idx; + prRxDescOps->nic_rxd_get_sec_mode = nic_rxd_v2_get_sec_mode; + prRxDescOps->nic_rxd_get_sw_class_error_bit = + nic_rxd_v2_get_sw_class_error_bit; + prRxDescOps->nic_rxd_get_ch_num = nic_rxd_v2_get_ch_num; + prRxDescOps->nic_rxd_get_rf_band = nic_rxd_v2_get_rf_band; + prRxDescOps->nic_rxd_get_tcl = nic_rxd_v2_get_tcl; + prRxDescOps->nic_rxd_get_ofld = nic_rxd_v2_get_ofld; + prRxDescOps->nic_rxd_fill_rfb = nic_rxd_v2_fill_rfb; + prRxDescOps->nic_rxd_sanity_check = nic_rxd_v2_sanity_check; + prRxDescOps->nic_rxd_check_wakeup_reason = + nic_rxd_v2_check_wakeup_reason; +} + +#if (CFG_SUPPORT_MSP == 1) +void asicConnac2xRxProcessRxvforMSP(IN struct ADAPTER *prAdapter, + IN OUT struct SW_RFB *prRetSwRfb) { + struct HW_MAC_RX_STS_GROUP_3_V2 *prGroup3; + + if (prRetSwRfb->ucStaRecIdx >= CFG_STA_REC_NUM) { + DBGLOG(RX, LOUD, + "prRetSwRfb->ucStaRecIdx(%d) >= CFG_STA_REC_NUM(%d)\n", + prRetSwRfb->ucStaRecIdx, CFG_STA_REC_NUM); + return; + } + + if (CONNAC2X_RXV_FROM_RX_RPT(prAdapter)) + return; + + prGroup3 = + (struct HW_MAC_RX_STS_GROUP_3_V2 *)prRetSwRfb->prRxStatusGroup3; + if (prRetSwRfb->ucGroupVLD & BIT(RX_GROUP_VLD_3)) { + /* P-RXV1[0:31] */ + prAdapter->arStaRec[ + prRetSwRfb->ucStaRecIdx].u4RxVector0 = + CONNAC2X_HAL_RX_VECTOR_GET_RX_VECTOR(prGroup3, 0); + prAdapter->arStaRec[ + prRetSwRfb->ucStaRecIdx].u4RxVector4 = + CONNAC2X_HAL_RX_VECTOR_GET_RX_VECTOR(prGroup3, 1); + } else { + prAdapter->arStaRec[ + prRetSwRfb->ucStaRecIdx].u4RxVector0 = 0; + prAdapter->arStaRec[ + prRetSwRfb->ucStaRecIdx].u4RxVector4 = 0; + } + + if (prRetSwRfb->ucGroupVLD & BIT(RX_GROUP_VLD_5)) { + /* C-B-0[0:31] */ + prAdapter->arStaRec[ + prRetSwRfb->ucStaRecIdx].u4RxVector1 = + CONNAC2X_HAL_RX_VECTOR_GET_RX_VECTOR( + prRetSwRfb->prRxStatusGroup5, 0); + /* C-B-1[0:31] */ + prAdapter->arStaRec[ + prRetSwRfb->ucStaRecIdx].u4RxVector2 = + CONNAC2X_HAL_RX_VECTOR_GET_RX_VECTOR( + prRetSwRfb->prRxStatusGroup5, 2); + /* C-B-2[0:31] */ + prAdapter->arStaRec[ + prRetSwRfb->ucStaRecIdx].u4RxVector3 = + CONNAC2X_HAL_RX_VECTOR_GET_RX_VECTOR( + prRetSwRfb->prRxStatusGroup5, 4); + /* C-B-3[0:31] */ + prAdapter->arStaRec[ + prRetSwRfb->ucStaRecIdx].u4RxVector4 = + CONNAC2X_HAL_RX_VECTOR_GET_RX_VECTOR( + prRetSwRfb->prRxStatusGroup5, 6); + } else { + prAdapter->arStaRec[ + prRetSwRfb->ucStaRecIdx].u4RxVector1 = 0; + prAdapter->arStaRec[ + prRetSwRfb->ucStaRecIdx].u4RxVector2 = 0; + prAdapter->arStaRec[ + prRetSwRfb->ucStaRecIdx].u4RxVector3 = 0; + } +} +#endif /* CFG_SUPPORT_MSP == 1 */ + +uint8_t asicConnac2xRxGetRcpiValueFromRxv( + IN uint8_t ucRcpiMode, + IN struct SW_RFB *prSwRfb) +{ + uint8_t ucRcpi0, ucRcpi1, ucRcpi2, ucRcpi3; + uint8_t ucRcpiValue = 0; + /* falcon IP donot have this field 'ucRxNum' */ + /* uint8_t ucRxNum; */ + + ASSERT(prSwRfb); + + if (ucRcpiMode >= RCPI_MODE_NUM) { + DBGLOG(RX, WARN, + "Rcpi Mode = %d is invalid for getting uint8_t value from RXV\n", + ucRcpiMode); + return 0; + } + + ucRcpi0 = HAL_RX_STATUS_GET_RCPI0( + (struct HW_MAC_RX_STS_GROUP_3_V2 *) + prSwRfb->prRxStatusGroup3); + ucRcpi1 = HAL_RX_STATUS_GET_RCPI1( + (struct HW_MAC_RX_STS_GROUP_3_V2 *) + prSwRfb->prRxStatusGroup3); + ucRcpi2 = HAL_RX_STATUS_GET_RCPI2( + (struct HW_MAC_RX_STS_GROUP_3_V2 *) + prSwRfb->prRxStatusGroup3); + ucRcpi3 = HAL_RX_STATUS_GET_RCPI3( + (struct HW_MAC_RX_STS_GROUP_3_V2 *) + prSwRfb->prRxStatusGroup3); + + /*If Rcpi is not available, set it to zero*/ + if (ucRcpi0 == RCPI_MEASUREMENT_NOT_AVAILABLE) + ucRcpi0 = RCPI_LOW_BOUND; + if (ucRcpi1 == RCPI_MEASUREMENT_NOT_AVAILABLE) + ucRcpi1 = RCPI_LOW_BOUND; + DBGLOG(RX, TRACE, "RCPI WF0:%d WF1:%d WF2:%d WF3:%d\n", + ucRcpi0, ucRcpi1, ucRcpi2, ucRcpi3); + + switch (ucRcpiMode) { + case RCPI_MODE_WF0: + ucRcpiValue = ucRcpi0; + break; + + case RCPI_MODE_WF1: + ucRcpiValue = ucRcpi1; + break; + + case RCPI_MODE_WF2: + ucRcpiValue = ucRcpi2; + break; + + case RCPI_MODE_WF3: + ucRcpiValue = ucRcpi3; + break; + + case RCPI_MODE_AVG: /*Not recommended for CBW80+80*/ + ucRcpiValue = (ucRcpi0 + ucRcpi1) / 2; + break; + + case RCPI_MODE_MAX: + ucRcpiValue = + (ucRcpi0 > ucRcpi1) ? (ucRcpi0) : (ucRcpi1); + break; + + case RCPI_MODE_MIN: + ucRcpiValue = + (ucRcpi0 < ucRcpi1) ? (ucRcpi0) : (ucRcpi1); + break; + + default: + break; + } + + return ucRcpiValue; +} + +#if (CFG_SUPPORT_PERF_IND == 1) +void asicConnac2xRxPerfIndProcessRXV(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, + IN uint8_t ucBssIndex) +{ + struct HW_MAC_RX_STS_GROUP_3 *prRxStatusGroup3; + uint8_t ucRCPI0 = 0, ucRCPI1 = 0; + + ASSERT(prAdapter); + ASSERT(prSwRfb); + /* REMOVE DATA RATE Parsing Logic:Workaround only for 6885*/ + /* Since MT6885 can not get Rx Data Rate dur to RXV HW Bug*/ + + if (ucBssIndex >= BSSID_NUM) + return; + + /* can't parse radiotap info if no rx vector */ + if (((prSwRfb->ucGroupVLD & BIT(RX_GROUP_VLD_2)) == 0) + || ((prSwRfb->ucGroupVLD & BIT(RX_GROUP_VLD_3)) == 0)) { + return; + } + + prRxStatusGroup3 = prSwRfb->prRxStatusGroup3; + + /* RCPI */ + ucRCPI0 = HAL_RX_STATUS_GET_RCPI0(prRxStatusGroup3); + ucRCPI1 = HAL_RX_STATUS_GET_RCPI1(prRxStatusGroup3); + + /* Record peak rate to Traffic Indicator*/ + prAdapter->prGlueInfo->PerfIndCache. + ucCurRxRCPI0[ucBssIndex] = ucRCPI0; + prAdapter->prGlueInfo->PerfIndCache. + ucCurRxRCPI1[ucBssIndex] = ucRCPI1; + +} +#endif + +#if (CFG_CHIP_RESET_SUPPORT == 1) && (CFG_WMT_RESET_API_SUPPORT == 0) +u_int8_t conn2_rst_L0_notify_step2(void) +{ + if (glGetRstReason() == RST_BT_TRIGGER) { + typedef void (*p_bt_fun_type) (void); + p_bt_fun_type bt_func; + char *bt_func_name = "WF_rst_L0_notify_BT_step2"; + + bt_func = (p_bt_fun_type)(uintptr_t) + GLUE_LOOKUP_FUN(bt_func_name); + if (bt_func) { + bt_func(); + } else { + DBGLOG(INIT, WARN, "[SER][L0] %s does not exist\n", + bt_func_name); + return FALSE; + } + } else { + /* if wifi trigger, then wait bt ready notify */ + DBGLOG(INIT, WARN, "[SER][L0] not support..\n"); + } + + return TRUE; +} +#endif + +#endif /* CFG_SUPPORT_CONNAC2X == 1 */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/common/dbg_connac.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/common/dbg_connac.c new file mode 100644 index 0000000000000000000000000000000000000000..dd9c5b105a4d57c27cc36cf10ea6db2c52a0342e --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/common/dbg_connac.c @@ -0,0 +1,2111 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/****************************************************************************** + *[File] dbg_connac.c + *[Version] v1.0 + *[Revision Date] 2015-09-08 + *[Author] + *[Description] + * The program provides WIFI MAC Debug APIs + *[Copyright] + * Copyright (C) 2015 MediaTek Incorporation. All Rights Reserved. + ******************************************************************************/ + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" + +#include "pse.h" +#include "wf_ple.h" +#include "host_csr.h" +#include "dma_sch.h" +#include "mt_dmac.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ +#if (CFG_SUPPORT_RA_GEN == 0) +static char *RATE_TBLE[] = {"B", "G", "N", "N_2SS", "AC", "AC_2SS", "N/A"}; +#else +static char *RATE_TBLE[] = {"B", "G", "N", "N_2SS", "AC", "AC_2SS", "BG", + "N/A"}; +static char *RA_STATUS_TBLE[] = {"INVALID", "POWER_SAVING", "SLEEP", "STANDBY", + "RUNNING", "N/A"}; +static char *LT_MODE_TBLE[] = {"RSSI", "LAST_RATE", "TRACKING", "N/A"}; +static char *SGI_UNSP_STATE_TBLE[] = {"INITIAL", "PROBING", "SUCCESS", + "FAILURE", "N/A"}; +static char *BW_STATE_TBLE[] = {"UNCHANGED", "DOWN", "N/A"}; +#endif +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +void halShowPseInfo(IN struct ADAPTER *prAdapter) +{ +#define BUF_SIZE 512 + + uint32_t pse_buf_ctrl = 0, pg_sz, pg_num; + uint32_t pse_stat = 0, pse_queue_empty_mask = 0, pg_flow_ctrl[16] = {0}; + uint32_t fpg_cnt, ffa_cnt, fpg_head, fpg_tail; + uint32_t max_q, min_q, rsv_pg, used_pg; + uint32_t i, page_offset, addr, value = 0, pos = 0; + char *buf; + + HAL_MCR_RD(prAdapter, PSE_PBUF_CTRL, &pse_buf_ctrl); + HAL_MCR_RD(prAdapter, PSE_QUEUE_EMPTY, &pse_stat); + HAL_MCR_RD(prAdapter, PSE_QUEUE_EMPTY_MASK, &pse_queue_empty_mask); + HAL_MCR_RD(prAdapter, PSE_FREEPG_CNT, &pg_flow_ctrl[0]); + HAL_MCR_RD(prAdapter, PSE_FREEPG_HEAD_TAIL, &pg_flow_ctrl[1]); + HAL_MCR_RD(prAdapter, PSE_PG_HIF0_GROUP, &pg_flow_ctrl[2]); + HAL_MCR_RD(prAdapter, PSE_HIF0_PG_INFO, &pg_flow_ctrl[3]); + HAL_MCR_RD(prAdapter, PSE_PG_HIF1_GROUP, &pg_flow_ctrl[4]); + HAL_MCR_RD(prAdapter, PSE_HIF1_PG_INFO, &pg_flow_ctrl[5]); + HAL_MCR_RD(prAdapter, PSE_PG_CPU_GROUP, &pg_flow_ctrl[6]); + HAL_MCR_RD(prAdapter, PSE_CPU_PG_INFO, &pg_flow_ctrl[7]); + HAL_MCR_RD(prAdapter, PSE_PG_LMAC0_GROUP, &pg_flow_ctrl[8]); + HAL_MCR_RD(prAdapter, PSE_LMAC0_PG_INFO, &pg_flow_ctrl[9]); + HAL_MCR_RD(prAdapter, PSE_PG_LMAC1_GROUP, &pg_flow_ctrl[10]); + HAL_MCR_RD(prAdapter, PSE_LMAC1_PG_INFO, &pg_flow_ctrl[11]); + HAL_MCR_RD(prAdapter, PSE_PG_LMAC2_GROUP, &pg_flow_ctrl[12]); + HAL_MCR_RD(prAdapter, PSE_LMAC2_PG_INFO, &pg_flow_ctrl[13]); + HAL_MCR_RD(prAdapter, PSE_PG_PLE_GROUP, &pg_flow_ctrl[14]); + HAL_MCR_RD(prAdapter, PSE_PLE_PG_INFO, &pg_flow_ctrl[15]); + + /* Configuration Info */ + DBGLOG(HAL, INFO, "PSE Configuration Info:\n"); + + HAL_MCR_RD(prAdapter, PSE_GC, &value); + DBGLOG(HAL, INFO, "\tGC(0x82068000): 0x%08x\n", value); + HAL_MCR_RD(prAdapter, PSE_INT_STS, &value); + DBGLOG(HAL, INFO, "\tINT_STS(0x82068024): 0x%08x\n", value); + HAL_MCR_RD(prAdapter, PSE_INT_ERR_STS, &value); + DBGLOG(HAL, INFO, "\tINT_ERR_STS(0x82068028): 0x%08x\n", value); + + DBGLOG(HAL, INFO, "\tPacket Buffer Control(0x82068014): 0x%08x\n", + pse_buf_ctrl); + pg_sz = (pse_buf_ctrl & (0x1 << 31)) >> 31; + DBGLOG(HAL, INFO, + "\t\tPage Size=%d(%d bytes per page)\n", + pg_sz, (pg_sz == 1 ? 256 : 128)); + page_offset = (pse_buf_ctrl & 0x3FFFFFF) >> 17; + DBGLOG(HAL, INFO, + "\t\tPage Offset=%d(in unit of 2KB)\n", page_offset); + pg_num = (pse_buf_ctrl & PSE_TOTAL_PAGE_NUM_MASK); + DBGLOG(HAL, INFO, "\t\tAvailable Total Page=%d pages\n", pg_num); + /* Page Flow Control */ + DBGLOG(HAL, INFO, "PSE Page Flow Control:\n"); + + DBGLOG(HAL, INFO, + "\tFree page counter(0x82068100): 0x%08x\n", pg_flow_ctrl[0]); + fpg_cnt = pg_flow_ctrl[0] & 0xfff; + DBGLOG(HAL, INFO, + "\t\tThe toal page number of free=0x%03x\n", fpg_cnt); + ffa_cnt = (pg_flow_ctrl[0] & (0xfff << 16)) >> 16; + DBGLOG(HAL, INFO, + "\t\tThe free page numbers of free for all=0x%03x\n", ffa_cnt); + DBGLOG(HAL, INFO, + "\tFree page head and tail(0x82068104): 0x%08x\n", + pg_flow_ctrl[1]); + fpg_head = pg_flow_ctrl[1] & 0xfff; + fpg_tail = (pg_flow_ctrl[1] & (0xfff << 16)) >> 16; + DBGLOG(HAL, INFO, + "\t\tThe tail/head page of free page list=0x%03x/0x%03x\n", + fpg_tail, fpg_head); + DBGLOG(HAL, INFO, + "\tReserved page counter of HIF0 group(0x82068110): 0x%08x\n", + pg_flow_ctrl[2]); + DBGLOG(HAL, INFO, + "\tHIF0 group page status(0x82068114): 0x%08x\n", + pg_flow_ctrl[3]); + min_q = pg_flow_ctrl[2] & 0xfff; + max_q = (pg_flow_ctrl[2] & (0xfff << 16)) >> 16; + DBGLOG(HAL, INFO, + "\t\tThe max/min quota pages of HIF0 group=0x%03x/0x%03x\n", + max_q, min_q); + rsv_pg = pg_flow_ctrl[3] & 0xfff; + used_pg = (pg_flow_ctrl[3] & (0xfff << 16)) >> 16; + DBGLOG(HAL, INFO, + "\t\tThe used/reserved pages of HIF0 group=0x%03x/0x%03x\n", + used_pg, rsv_pg); + DBGLOG(HAL, INFO, + "\tReserved page counter of HIF1 group(0x82068118): 0x%08x\n", + pg_flow_ctrl[4]); + DBGLOG(HAL, INFO, + "\tHIF1 group page status(0x8206811c): 0x%08x\n", + pg_flow_ctrl[5]); + min_q = pg_flow_ctrl[4] & 0xfff; + max_q = (pg_flow_ctrl[4] & (0xfff << 16)) >> 16; + DBGLOG(HAL, INFO, + "\t\tThe max/min quota pages of HIF1 group=0x%03x/0x%03x\n", + max_q, min_q); + rsv_pg = pg_flow_ctrl[5] & 0xfff; + used_pg = (pg_flow_ctrl[5] & (0xfff << 16)) >> 16; + DBGLOG(HAL, INFO, + "\t\tThe used/reserved pages of HIF1 group=0x%03x/0x%03x\n", + used_pg, rsv_pg); + DBGLOG(HAL, INFO, + "\tReserved page counter of CPU group(0x82068150): 0x%08x\n", + pg_flow_ctrl[6]); + DBGLOG(HAL, INFO, + "\tCPU group page status(0x82068154): 0x%08x\n", + pg_flow_ctrl[7]); + min_q = pg_flow_ctrl[6] & 0xfff; + max_q = (pg_flow_ctrl[6] & (0xfff << 16)) >> 16; + DBGLOG(HAL, INFO, + "\t\tThe max/min quota pages of CPU group=0x%03x/0x%03x\n", + max_q, min_q); + rsv_pg = pg_flow_ctrl[7] & 0xfff; + used_pg = (pg_flow_ctrl[7] & (0xfff << 16)) >> 16; + DBGLOG(HAL, INFO, + "\t\tThe used/reserved pages of CPU group=0x%03x/0x%03x\n", + used_pg, rsv_pg); + DBGLOG(HAL, INFO, + "\tReserved page counter of LMAC0 group(0x82068170): 0x%08x\n", + pg_flow_ctrl[8]); + DBGLOG(HAL, INFO, + "\tLMAC0 group page status(0x82068174): 0x%08x\n", + pg_flow_ctrl[9]); + min_q = pg_flow_ctrl[8] & 0xfff; + max_q = (pg_flow_ctrl[8] & (0xfff << 16)) >> 16; + DBGLOG(HAL, INFO, + "\t\tThe max/min quota pages of LMAC0 group=0x%03x/0x%03x\n", + max_q, min_q); + rsv_pg = pg_flow_ctrl[9] & 0xfff; + used_pg = (pg_flow_ctrl[9] & (0xfff << 16)) >> 16; + DBGLOG(HAL, INFO, + "\t\tThe used/reserved pages of LMAC0 group=0x%03x/0x%03x\n", + used_pg, rsv_pg); + DBGLOG(HAL, INFO, + "\tReserved page counter of LMAC1 group(0x82068178): 0x%08x\n", + pg_flow_ctrl[10]); + DBGLOG(HAL, INFO, + "\tLMAC1 group page status(0x8206817c): 0x%08x\n", + pg_flow_ctrl[11]); + min_q = pg_flow_ctrl[10] & 0xfff; + max_q = (pg_flow_ctrl[10] & (0xfff << 16)) >> 16; + DBGLOG(HAL, INFO, + "\t\tThe max/min quota pages of LMAC1 group=0x%03x/0x%03x\n", + max_q, min_q); + rsv_pg = pg_flow_ctrl[11] & 0xfff; + used_pg = (pg_flow_ctrl[11] & (0xfff << 16)) >> 16; + DBGLOG(HAL, INFO, + "\t\tThe used/reserved pages of LMAC1 group=0x%03x/0x%03x\n", + used_pg, rsv_pg); + DBGLOG(HAL, INFO, + "\tReserved page counter of LMAC2 group(0x82068180): 0x%08x\n", + pg_flow_ctrl[12]); + DBGLOG(HAL, INFO, + "\tLMAC2 group page status(0x82068184): 0x%08x\n", + pg_flow_ctrl[13]); + min_q = pg_flow_ctrl[12] & 0xfff; + max_q = (pg_flow_ctrl[12] & (0xfff << 16)) >> 16; + DBGLOG(HAL, INFO, + "\t\tThe max/min quota pages of LMAC2 group=0x%03x/0x%03x\n", + max_q, min_q); + rsv_pg = pg_flow_ctrl[13] & 0xfff; + used_pg = (pg_flow_ctrl[13] & (0xfff << 16)) >> 16; + DBGLOG(HAL, INFO, + "\t\tThe used/reserved pages of LMAC2 group=0x%03x/0x%03x\n", + used_pg, rsv_pg); + DBGLOG(HAL, INFO, + "\tReserved page counter of PLE group(0x82068190): 0x%08x\n", + pg_flow_ctrl[14]); + DBGLOG(HAL, INFO, + "\tPLE group page status(0x82068194): 0x%08x\n", + pg_flow_ctrl[15]); + min_q = pg_flow_ctrl[14] & 0xfff; + max_q = (pg_flow_ctrl[14] & (0xfff << 16)) >> 16; + DBGLOG(HAL, INFO, + "\t\tThe max/min quota pages of PLE group=0x%03x/0x%03x\n", + max_q, min_q); + rsv_pg = pg_flow_ctrl[15] & 0xfff; + used_pg = (pg_flow_ctrl[15] & (0xfff << 16)) >> 16; + DBGLOG(HAL, INFO, + "\t\tThe used/reserved pages of PLE group=0x%03x/0x%03x\n", + used_pg, rsv_pg); + /* Queue Empty Status */ + DBGLOG(HAL, INFO, "PSE Queue Empty Status:\n"); + DBGLOG(HAL, INFO, + "\tQUEUE_EMPTY(0x820680b0): 0x%08x\n", + pse_stat); + DBGLOG(HAL, INFO, + "\tQUEUE_EMPTY_MASK(0x820680b4): 0x%08x\n", + pse_queue_empty_mask); + DBGLOG(HAL, INFO, + "\t\tCPU Q0/1/2/3 empty=%d/%d/%d/%d\n", + pse_stat & 0x1, ((pse_stat & 0x2) >> 1), + ((pse_stat & 0x4) >> 2), ((pse_stat & 0x8) >> 3)); + DBGLOG(HAL, INFO, + "\t\tHIF Q0/1/2/3 empty=%d/%d/%d/%d\n", + ((pse_stat & (0x1 << 16)) >> 16), + ((pse_stat & (0x1 << 17)) >> 17), + ((pse_stat & (0x1 << 18)) >> 18), + ((pse_stat & (0x1 << 19)) >> 19)); + DBGLOG(HAL, INFO, + "\t\tLMAC TX Q empty=%d\n", + ((pse_stat & (0x1 << 24)) >> 24)); + DBGLOG(HAL, INFO, + "\t\tRLS_Q empty=%d\n", + ((pse_stat & (0x1 << 31)) >> 31)); + + buf = (char *) kalMemAlloc(BUF_SIZE, VIR_MEM_TYPE); + if (buf) { + kalMemZero(buf, BUF_SIZE); + pos = 0; + for (i = 0; i < PSE_PEEK_CR_NUM; i++) { + addr = PSE_PEEK_CR_0 + PSE_PEEK_CR_OFFSET * i; + HAL_MCR_RD(prAdapter, addr, &value); + pos += kalSnprintf(buf + pos, 40, + "PSE_PEEK_CR_%u[0x%08x/0x%08x] ", + i, addr, value); + } + DBGLOG(HAL, INFO, "%s\n", buf); + + kalMemZero(buf, BUF_SIZE); + pos = 0; + for (i = 0; i < PSE_ENDEQ_NUM; i++) { + addr = PSE_ENQ_0 + PSE_ENDEQ_OFFSET * i; + HAL_MCR_RD(prAdapter, addr, &value); + pos += kalSnprintf(buf + pos, 40, + "PSE_ENQ_%u[0x%08x/0x%08x] ", + i, addr, value); + } + DBGLOG(HAL, INFO, "%s\n", buf); + + kalMemZero(buf, BUF_SIZE); + pos = 0; + for (i = 0; i < PSE_ENDEQ_NUM; i++) { + addr = PSE_DEQ_0 + PSE_ENDEQ_OFFSET * i; + HAL_MCR_RD(prAdapter, addr, &value); + pos += kalSnprintf(buf + pos, 40, + "PSE_DEQ_%u[0x%08x/0x%08x] ", + i, addr, value); + } + DBGLOG(HAL, INFO, "%s\n", buf); + + kalMemFree(buf, VIR_MEM_TYPE, BUF_SIZE); + } + +#undef BUF_SIZE +} + +static int8_t *sta_ctrl_reg[] = {"ENABLE", "*DISABLE", "*PAUSE"}; +static struct EMPTY_QUEUE_INFO Queue_Empty_info[] = { + {"CPU Q0", ENUM_UMAC_CPU_PORT_1, ENUM_UMAC_CTX_Q_0}, + {"CPU Q1", ENUM_UMAC_CPU_PORT_1, ENUM_UMAC_CTX_Q_1}, + {"CPU Q2", ENUM_UMAC_CPU_PORT_1, ENUM_UMAC_CTX_Q_2}, + {"CPU Q3", ENUM_UMAC_CPU_PORT_1, ENUM_UMAC_CTX_Q_3}, + {NULL, 0, 0}, {NULL, 0, 0}, {NULL, 0, 0}, {NULL, 0, 0}, + {"ALTX Q0", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_ALTX_0}, + {"BMC Q0", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_BMC_0}, + {"BCN Q0", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_BNC_0}, + {"PSMP Q0", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_PSMP_0}, + {"ALTX Q1", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_ALTX_1}, + {"BMC Q1", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_BMC_1}, + {"BCN Q1", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_BNC_1}, + {"PSMP Q1", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_PSMP_1}, + {"NAF Q", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_NAF}, + {"NBCN Q", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_NBCN}, + {NULL, 0, 0}, {NULL, 0, 0}, {NULL, 0, 0}, + {NULL, 0, 0}, {NULL, 0, 0}, {NULL, 0, 0}, + {NULL, 0, 0}, {NULL, 0, 0}, {NULL, 0, 0}, + {NULL, 0, 0}, {NULL, 0, 0}, {NULL, 0, 0}, + {"RLS Q", ENUM_PLE_CTRL_PSE_PORT_3, ENUM_UMAC_PLE_CTRL_P3_Q_0X1E}, + {"RLS2 Q", ENUM_PLE_CTRL_PSE_PORT_3, ENUM_UMAC_PLE_CTRL_P3_Q_0X1F} +}; + +void halShowPleInfo(IN struct ADAPTER *prAdapter, + u_int8_t fgDumpTxd) +{ +#define BUF_SIZE 1024 + + uint32_t ple_buf_ctrl[3] = {0}, pg_sz, pg_num, bit_field_1, bit_field_2; + uint32_t ple_stat[17] = {0}, pg_flow_ctrl[6] = {0}; + uint32_t sta_pause[4] = {0}, dis_sta_map[4] = {0}; + uint32_t fpg_cnt, ffa_cnt, fpg_head, fpg_tail, hif_max_q, hif_min_q; + uint32_t rpg_hif, upg_hif, cpu_max_q, cpu_min_q, rpg_cpu, upg_cpu; + uint32_t i, j, addr, value = 0, pos = 0; + char *buf; + + HAL_MCR_RD(prAdapter, PLE_PBUF_CTRL, &ple_buf_ctrl[0]); + HAL_MCR_RD(prAdapter, PLE_RELEASE_CTRL, &ple_buf_ctrl[1]); + HAL_MCR_RD(prAdapter, PLE_HIF_REPORT, &ple_buf_ctrl[2]); + HAL_MCR_RD(prAdapter, PLE_QUEUE_EMPTY, &ple_stat[0]); + HAL_MCR_RD(prAdapter, PLE_AC0_QUEUE_EMPTY_0, &ple_stat[1]); + HAL_MCR_RD(prAdapter, PLE_AC0_QUEUE_EMPTY_1, &ple_stat[2]); + HAL_MCR_RD(prAdapter, PLE_AC0_QUEUE_EMPTY_2, &ple_stat[3]); + HAL_MCR_RD(prAdapter, PLE_AC0_QUEUE_EMPTY_3, &ple_stat[4]); + HAL_MCR_RD(prAdapter, PLE_AC1_QUEUE_EMPTY_0, &ple_stat[5]); + HAL_MCR_RD(prAdapter, PLE_AC1_QUEUE_EMPTY_1, &ple_stat[6]); + HAL_MCR_RD(prAdapter, PLE_AC1_QUEUE_EMPTY_2, &ple_stat[7]); + HAL_MCR_RD(prAdapter, PLE_AC1_QUEUE_EMPTY_3, &ple_stat[8]); + HAL_MCR_RD(prAdapter, PLE_AC2_QUEUE_EMPTY_0, &ple_stat[9]); + HAL_MCR_RD(prAdapter, PLE_AC2_QUEUE_EMPTY_1, &ple_stat[10]); + HAL_MCR_RD(prAdapter, PLE_AC2_QUEUE_EMPTY_2, &ple_stat[11]); + HAL_MCR_RD(prAdapter, PLE_AC2_QUEUE_EMPTY_3, &ple_stat[12]); + HAL_MCR_RD(prAdapter, PLE_AC3_QUEUE_EMPTY_0, &ple_stat[13]); + HAL_MCR_RD(prAdapter, PLE_AC3_QUEUE_EMPTY_1, &ple_stat[14]); + HAL_MCR_RD(prAdapter, PLE_AC3_QUEUE_EMPTY_2, &ple_stat[15]); + HAL_MCR_RD(prAdapter, PLE_AC3_QUEUE_EMPTY_3, &ple_stat[16]); + HAL_MCR_RD(prAdapter, PLE_FREEPG_CNT, &pg_flow_ctrl[0]); + HAL_MCR_RD(prAdapter, PLE_FREEPG_HEAD_TAIL, &pg_flow_ctrl[1]); + HAL_MCR_RD(prAdapter, PLE_PG_HIF_GROUP, &pg_flow_ctrl[2]); + HAL_MCR_RD(prAdapter, PLE_HIF_PG_INFO, &pg_flow_ctrl[3]); + HAL_MCR_RD(prAdapter, PLE_PG_CPU_GROUP, &pg_flow_ctrl[4]); + HAL_MCR_RD(prAdapter, PLE_CPU_PG_INFO, &pg_flow_ctrl[5]); + HAL_MCR_RD(prAdapter, DIS_STA_MAP0, &dis_sta_map[0]); + HAL_MCR_RD(prAdapter, DIS_STA_MAP1, &dis_sta_map[1]); + HAL_MCR_RD(prAdapter, DIS_STA_MAP2, &dis_sta_map[2]); + HAL_MCR_RD(prAdapter, DIS_STA_MAP3, &dis_sta_map[3]); + HAL_MCR_RD(prAdapter, STATION_PAUSE0, &sta_pause[0]); + HAL_MCR_RD(prAdapter, STATION_PAUSE1, &sta_pause[1]); + HAL_MCR_RD(prAdapter, STATION_PAUSE2, &sta_pause[2]); + HAL_MCR_RD(prAdapter, STATION_PAUSE3, &sta_pause[3]); + /* Configuration Info */ + DBGLOG(HAL, INFO, "PLE Configuration Info:\n"); + + HAL_MCR_RD(prAdapter, PLE_GC, &value); + DBGLOG(HAL, INFO, "\tGC(0x82060000): 0x%08x\n", value); + HAL_MCR_RD(prAdapter, PLE_INT_STS, &value); + DBGLOG(HAL, INFO, "\tINT_STS(0x82060024): 0x%08x\n", value); + HAL_MCR_RD(prAdapter, PLE_INT_ERR_STS, &value); + DBGLOG(HAL, INFO, "\tINT_ERR_STS(0x82060028): 0x%08x\n", value); + HAL_MCR_RD(prAdapter, PLE_QUEUE_CMD_ERR_STS, &value); + DBGLOG(HAL, INFO, "\tQUEUE_CMD_ERR_STS(0x82060550): 0x%08x\n", value); + + DBGLOG(HAL, INFO, + "\tPacket Buffer Control(0x82060014): 0x%08x\n", + ple_buf_ctrl[0]); + pg_sz = (ple_buf_ctrl[0] & (0x1 << 31)) >> 31; + DBGLOG(HAL, INFO, + "\t\tPage Size=%d(%d bytes per page)\n", + pg_sz, (pg_sz == 1 ? 128 : 64)); + DBGLOG(HAL, INFO, + "\t\tPage Offset=%d(in unit of 2KB)\n", + (ple_buf_ctrl[0] & (0xf << 17)) >> 17); + pg_num = (ple_buf_ctrl[0] & 0xfff); + DBGLOG(HAL, INFO, + "\t\tTotal Page=%d pages\n", (ple_buf_ctrl[0] & 0xfff)); + DBGLOG(HAL, INFO, + "\tRelease Control(0x82060030): 0x%08x\n", ple_buf_ctrl[1]); + bit_field_1 = (ple_buf_ctrl[1] & 0x1f); + bit_field_2 = ((ple_buf_ctrl[1] & (0x3 << 6)) >> 6); + DBGLOG(HAL, INFO, + "\t\tNormalTx Release Pid/Qid=%d/%d\n", + bit_field_2, bit_field_1); + bit_field_1 = ((ple_buf_ctrl[1] & (0x1f << 8)) >> 8); + bit_field_2 = ((ple_buf_ctrl[1] & (0x3 << 14)) >> 14); + DBGLOG(HAL, INFO, + "\t\tDropTx Release Pid/Qid=%d/%d\n", bit_field_2, bit_field_1); + bit_field_1 = ((ple_buf_ctrl[1] & (0x1f << 16)) >> 16); + bit_field_2 = ((ple_buf_ctrl[1] & (0x3 << 22)) >> 22); + DBGLOG(HAL, INFO, + "\t\tBCN0 Release Pid/Qid=%d/%d\n", bit_field_2, bit_field_1); + bit_field_1 = ((ple_buf_ctrl[1] & (0x1f << 24)) >> 24); + bit_field_2 = ((ple_buf_ctrl[1] & (0x3 << 30)) >> 30); + DBGLOG(HAL, INFO, + "\t\tBCN1 Release Pid/Qid=%d/%d\n", bit_field_2, bit_field_1); + DBGLOG(HAL, INFO, + "\tHIF Report Control(0x82060034): 0x%08x\n", ple_buf_ctrl[2]); + bit_field_1 = ((ple_buf_ctrl[2] & (0x1 << 1)) >> 1); + DBGLOG(HAL, INFO, + "\t\tHostReportQSel/HostReportDisable=%d/%d\n", + (ple_buf_ctrl[2] & 0x1), bit_field_1); + /* Page Flow Control */ + DBGLOG(HAL, INFO, "PLE Page Flow Control:\n"); + DBGLOG(HAL, INFO, + "\tFree page counter(0x82060100): 0x%08x\n", pg_flow_ctrl[0]); + fpg_cnt = pg_flow_ctrl[0] & 0xfff; + DBGLOG(HAL, INFO, + "\t\tThe toal page number of free=0x%03x\n", fpg_cnt); + ffa_cnt = (pg_flow_ctrl[0] & (0xfff << 16)) >> 16; + DBGLOG(HAL, INFO, + "\t\tThe free page numbers of free for all=0x%03x\n", ffa_cnt); + DBGLOG(HAL, INFO, + "\tFree page head and tail(0x82060104): 0x%08x\n", + pg_flow_ctrl[1]); + fpg_head = pg_flow_ctrl[1] & 0xfff; + fpg_tail = (pg_flow_ctrl[1] & (0xfff << 16)) >> 16; + DBGLOG(HAL, INFO, + "\t\tThe tail/head page of free page list=0x%03x/0x%03x\n", + fpg_tail, fpg_head); + DBGLOG(HAL, INFO, + "\tReserved page counter of HIF group(0x82060110): 0x%08x\n", + pg_flow_ctrl[2]); + DBGLOG(HAL, INFO, + "\tHIF group page status(0x82060114): 0x%08x\n", + pg_flow_ctrl[3]); + hif_min_q = pg_flow_ctrl[2] & 0xfff; + hif_max_q = (pg_flow_ctrl[2] & (0xfff << 16)) >> 16; + DBGLOG(HAL, INFO, + "\t\tThe max/min quota pages of HIF group=0x%03x/0x%03x\n", + hif_max_q, hif_min_q); + rpg_hif = pg_flow_ctrl[3] & 0xfff; + upg_hif = (pg_flow_ctrl[3] & (0xfff << 16)) >> 16; + DBGLOG(HAL, INFO, + "\t\tThe used/reserved pages of HIF group=0x%03x/0x%03x\n", + upg_hif, rpg_hif); + DBGLOG(HAL, INFO, + "\tReserved page counter of CPU group(0x82060150): 0x%08x\n", + pg_flow_ctrl[4]); + DBGLOG(HAL, INFO, + "\tCPU group page status(0x82060154): 0x%08x\n", + pg_flow_ctrl[5]); + cpu_min_q = pg_flow_ctrl[4] & 0xfff; + cpu_max_q = (pg_flow_ctrl[4] & (0xfff << 16)) >> 16; + DBGLOG(HAL, INFO, + "\t\tThe max/min quota pages of CPU group=0x%03x/0x%03x\n", + cpu_max_q, cpu_min_q); + rpg_cpu = pg_flow_ctrl[5] & 0xfff; + upg_cpu = (pg_flow_ctrl[5] & (0xfff << 16)) >> 16; + DBGLOG(HAL, INFO, + "\t\tThe used/reserved pages of CPU group=0x%03x/0x%03x\n", + upg_cpu, rpg_cpu); + + if (((ple_stat[0] & (0x1 << 24)) >> 24) == 0) { + DBGLOG(HAL, INFO, + "\tAC0_QUEUE_EMPTY0(0x82060300): 0x%08x\n", + ple_stat[1]); + DBGLOG(HAL, INFO, + "\tAC1_QUEUE_EMPTY0(0x82060310): 0x%08x\n", + ple_stat[5]); + DBGLOG(HAL, INFO, + "\tAC2_QUEUE_EMPTY0(0x82060320): 0x%08x\n", + ple_stat[9]); + DBGLOG(HAL, INFO, + "\tAC3_QUEUE_EMPTY0(0x82060330): 0x%08x\n", + ple_stat[13]); + + for (j = 0; j < 16; j = j + 4) { + if (j % 4 == 0) + DBGLOG(HAL, INFO, "\tNonempty AC%d Q of STA#:", + j / 4); + + for (i = 0; i < 32; i++) { + if (((ple_stat[j + 1] & (0x1 << i)) >> i) == 0) + DBGLOG(HAL, INFO, "%d ", + i + (j % 4) * 32); + } + } + + DBGLOG(HAL, INFO, "\n"); + } + + DBGLOG(HAL, INFO, "Nonempty Q info:\n"); + + for (i = 0; i < 31; i++) { + if (((ple_stat[0] & (0x1 << i)) >> i) == 0) { + if (Queue_Empty_info[i].QueueName != NULL) + DBGLOG(HAL, INFO, "\t%s: ", + Queue_Empty_info[i].QueueName); + else + continue; + } + } + + for (j = 0; j < 16; j = j + 4) { /* show AC Q info */ + for (i = 0; i < 32; i++) { + if (((ple_stat[j + 1] & (0x1 << i)) >> i) == 0) { + uint32_t ac_num = j / 4, ctrl = 0; + uint32_t sta_num = i + (j % 4) * 32; + + DBGLOG(HAL, INFO, "\tSTA%d AC%d: ", + sta_num, ac_num); + if (((sta_pause[j % 4] & 0x1 << i) >> i) == 1) + ctrl = 2; + + if (((dis_sta_map[j % 4] & 0x1 << i) >> i) == 1) + ctrl = 1; + + DBGLOG(HAL, INFO, " ctrl = %s", + sta_ctrl_reg[ctrl]); + } + } + } + + buf = (char *) kalMemAlloc(BUF_SIZE, VIR_MEM_TYPE); + if (buf) { + kalMemZero(buf, BUF_SIZE); + for (i = 0; i < PLE_PEEK_CR_NUM; i++) { + addr = PLE_PEEK_CR_0 + PLE_PEEK_CR_OFFSET * i; + HAL_MCR_RD(prAdapter, addr, &value); + pos += kalSnprintf(buf + pos, 40, + "PLE_PEEK_CR_%u[0x%08x/0x%08x]%s", + i, addr, value, + i == (PLE_PEEK_CR_NUM - 1) ? "\n" : ", "); + } + DBGLOG(HAL, INFO, "%s\n", buf); + kalMemFree(buf, VIR_MEM_TYPE, BUF_SIZE); + } + +#undef BUF_SIZE +} + +void halShowDmaschInfo(IN struct ADAPTER *prAdapter) +{ + struct mt66xx_chip_info *prChipInfo; + uint32_t value = 0; + uint32_t ple_pkt_max_sz; + uint32_t pse_pkt_max_sz; + uint32_t max_quota; + uint32_t min_quota; + uint32_t rsv_cnt; + uint32_t src_cnt; + uint32_t pse_rsv_cnt = 0; + uint32_t pse_src_cnt = 0; + uint32_t odd_group_pktin_cnt = 0; + uint32_t odd_group_ask_cnt = 0; + uint32_t pktin_cnt; + uint32_t ask_cnt; + uint32_t total_src_cnt = 0; + uint32_t total_rsv_cnt = 0; + uint32_t ffa_cnt; + uint32_t free_pg_cnt; + uint32_t Group_Mapping_Q[16] = {0}; + uint32_t qmapping_addr = MT_HIF_DMASHDL_Q_MAP0; + uint32_t status_addr = MT_HIF_DMASHDL_STATUS_RD_GP0; + uint32_t quota_addr = MT_HIF_DMASHDL_GROUP0_CTRL; + uint32_t pkt_cnt_addr = MT_HIF_DMASHDLRD_GP_PKT_CNT_0; + uint32_t mapping_mask = 0xf; + uint32_t mapping_offset = 0; + uint32_t mapping_qidx; + uint32_t groupidx = 0; + uint8_t idx = 0; + u_int8_t pktin_int_refill_ena; + u_int8_t pdma_add_int_refill_ena; + u_int8_t ple_add_int_refill_ena; + u_int8_t ple_sub_ena; + u_int8_t hif_ask_sub_ena; + u_int8_t ple_txd_gt_max_size_flag_clr; + uint32_t ple_rpg_hif; + uint32_t ple_upg_hif; + uint32_t pse_rpg_hif = 0; + uint32_t pse_upg_hif = 0; + uint8_t is_mismatch = FALSE; + uint32_t u4BaseAddr; + + prChipInfo = prAdapter->chip_info; + u4BaseAddr = prChipInfo->u4HifDmaShdlBaseAddr; + for (mapping_qidx = 0; mapping_qidx < 32; mapping_qidx++) { + uint32_t mapping_group; + + idx = 0; + + if (mapping_qidx == 0) { + qmapping_addr = MT_HIF_DMASHDL_Q_MAP0; + mapping_mask = 0xf; + mapping_offset = 0; + } else if ((mapping_qidx % 8) == 0) { + qmapping_addr += 0x4; + mapping_mask = 0xf; + mapping_offset = 0; + } else { + mapping_offset += 4; + mapping_mask = 0xf << mapping_offset; + } + + HAL_MCR_RD(prAdapter, qmapping_addr, &value); + mapping_group = (value & mapping_mask) >> mapping_offset; + Group_Mapping_Q[mapping_group] |= 1 << mapping_qidx; + } + + DBGLOG(HAL, INFO, "Dma scheduler info:\n"); + HAL_MCR_RD(prAdapter, MT_HIF_DMASHDL_CTRL_SIGNAL, &value); + pktin_int_refill_ena = + (value & DMASHDL_PKTIN_INT_REFILL_ENA) ? TRUE : FALSE; + pdma_add_int_refill_ena = + (value & DMASHDL_PDMA_ADD_INT_REFILL_ENA) ? TRUE : FALSE; + ple_add_int_refill_ena = + (value & DMASHDL_PLE_ADD_INT_REFILL_ENA) ? TRUE : FALSE; + ple_sub_ena = (value & DMASHDL_PLE_SUB_ENA) ? TRUE : FALSE; + hif_ask_sub_ena = (value & DMASHDL_HIF_ASK_SUB_ENA) ? TRUE : FALSE; + ple_txd_gt_max_size_flag_clr = + (value & DMASHDL_PLE_TXD_GT_MAX_SIZE_FLAG_CLR) ? TRUE : FALSE; + DBGLOG(HAL, INFO, "DMASHDL Ctrl Signal(0x5000A018): 0x%08x\n", value); + DBGLOG(HAL, INFO, "\tple_txd_gt_max_size_flag_clr(BIT0) = %d\n", + ple_txd_gt_max_size_flag_clr); + DBGLOG(HAL, INFO, "\thif_ask_sub_ena(BIT16) = %d\n", hif_ask_sub_ena); + DBGLOG(HAL, INFO, "\tple_sub_ena(BIT17) = %d\n", ple_sub_ena); + DBGLOG(HAL, INFO, "\tple_add_int_refill_ena(BIT29) = %d\n", + ple_add_int_refill_ena); + DBGLOG(HAL, INFO, "\tpdma_add_int_refill_ena(BIT30) = %d\n", + pdma_add_int_refill_ena); + DBGLOG(HAL, INFO, "\tpktin_int_refill(BIT31)_ena = %d\n", + pktin_int_refill_ena); + HAL_MCR_RD(prAdapter, MT_HIF_DMASHDL_PKT_MAX_SIZE, &value); + ple_pkt_max_sz = GET_PLE_PKT_MAX_SIZE_NUM(value); + pse_pkt_max_sz = GET_PSE_PKT_MAX_SIZE_NUM(value); + DBGLOG(HAL, INFO, + "DMASHDL Packet_max_size(0x5000A01c): 0x%08x\n", value); + DBGLOG(HAL, INFO, + "PLE/PSE packet max size=0x%03x/0x%03x\n", + ple_pkt_max_sz, pse_pkt_max_sz); + HAL_MCR_RD(prAdapter, MT_HIF_DMASHDL_ERROR_FLAG_CTRL, &value); + DBGLOG(HAL, INFO, "DMASHDL ERR FLAG CTRL(0x5000A09c): 0x%08x\n", value); + HAL_MCR_RD(prAdapter, MT_HIF_DMASHDL_STATUS_RD, &value); + ffa_cnt = (value & DMASHDL_FFA_CNT_MASK) >> DMASHDL_FFA_CNT_OFFSET; + free_pg_cnt = (value & DMASHDL_FREE_PG_CNT_MASK) >> + DMASHDL_FREE_PG_CNT_OFFSET; + DBGLOG(HAL, INFO, "DMASHDL Status_RD(0x5000A100): 0x%08x\n", value); + DBGLOG(HAL, INFO, + "free page cnt = 0x%03x, ffa cnt = 0x%03x\n", + free_pg_cnt, ffa_cnt); + HAL_MCR_RD(prAdapter, + CONN_HIF_DMASHDL_REFILL_CONTROL(u4BaseAddr), &value); + DBGLOG(HAL, INFO, + "DMASHDL ReFill Control(0x5000A010): 0x%08x\n", value); + + for (groupidx = 0; groupidx < 16; groupidx++) { + DBGLOG(HAL, INFO, "Group %d info:", groupidx); + HAL_MCR_RD(prAdapter, status_addr, &value); + rsv_cnt = (value & DMASHDL_RSV_CNT_MASK) >> + DMASHDL_RSV_CNT_OFFSET; + src_cnt = (value & DMASHDL_SRC_CNT_MASK) >> + DMASHDL_SRC_CNT_OFFSET; + DBGLOG(HAL, INFO, + "\tDMASHDL Status_RD_GP%d(0x%08x): 0x%08x\n", + groupidx, status_addr, value); + HAL_MCR_RD(prAdapter, quota_addr, &value); + max_quota = (value & DMASHDL_MAX_QUOTA_MASK) >> + DMASHDL_MAX_QUOTA_OFFSET; + min_quota = (value & DMASHDL_MIN_QUOTA_MASK) >> + DMASHDL_MIN_QUOTA_OFFSET; + DBGLOG(HAL, INFO, + "\tDMASHDL Group%d control(0x%08x): 0x%08x\n", + groupidx, quota_addr, value); + + if ((groupidx & 0x1) == 0) { + HAL_MCR_RD(prAdapter, pkt_cnt_addr, &value); + DBGLOG(HAL, INFO, + "\tDMASHDL RD_group_pkt_cnt_%d(0x%08x): 0x%08x\n", + groupidx / 2, pkt_cnt_addr, value); + odd_group_pktin_cnt = GET_ODD_GROUP_PKT_IN_CNT(value); + odd_group_ask_cnt = GET_ODD_GROUP_ASK_CNT(value); + pktin_cnt = GET_EVEN_GROUP_PKT_IN_CNT(value); + ask_cnt = GET_EVEN_GROUP_ASK_CNT(value); + } else { + pktin_cnt = odd_group_pktin_cnt; + ask_cnt = odd_group_ask_cnt; + } + + DBGLOG(HAL, INFO, + "\trsv_cnt = 0x%03x, src_cnt = 0x%03x\n", + rsv_cnt, src_cnt); + DBGLOG(HAL, INFO, + "\tmax/min quota = 0x%03x/ 0x%03x\n", + max_quota, min_quota); + DBGLOG(HAL, INFO, + "\tpktin_cnt = 0x%02x, ask_cnt = 0x%02x", + pktin_cnt, ask_cnt); + + if (hif_ask_sub_ena && pktin_cnt != ask_cnt) { + DBGLOG(HAL, INFO, ", mismatch!"); + is_mismatch = TRUE; + } + + /* Group15 is for PSE */ + if (groupidx == 15 && Group_Mapping_Q[groupidx] == 0) { + pse_src_cnt = src_cnt; + pse_rsv_cnt = rsv_cnt; + break; + } + + DBGLOG(HAL, INFO, "\tMapping Qidx: 0x%x", + Group_Mapping_Q[groupidx]); + + total_src_cnt += src_cnt; + total_rsv_cnt += rsv_cnt; + status_addr = status_addr + 4; + quota_addr = quota_addr + 4; + + if (groupidx & 0x1) + pkt_cnt_addr = pkt_cnt_addr + 4; + } + + DBGLOG(HAL, INFO, "\nCounter Check:\n"); + HAL_MCR_RD(prAdapter, PLE_HIF_PG_INFO, &value); + ple_rpg_hif = value & 0xfff; + ple_upg_hif = (value & (0xfff << 16)) >> 16; + DBGLOG(HAL, INFO, + "PLE:\n\tThe used/reserved pages of PLE HIF group=0x%03x/0x%03x\n", + ple_upg_hif, ple_rpg_hif); + HAL_MCR_RD(prAdapter, PSE_HIF1_PG_INFO, &value); + pse_rpg_hif = value & 0xfff; + pse_upg_hif = (value & (0xfff << 16)) >> 16; + DBGLOG(HAL, INFO, + "PSE:\n\tThe used/reserved pages of PSE HIF group=0x%03x/0x%03x\n", + pse_upg_hif, pse_rpg_hif); + DBGLOG(HAL, INFO, + "DMASHDL:\n\tThe total used pages of group0~14=0x%03x", + total_src_cnt); + + if (ple_upg_hif != total_src_cnt) { + DBGLOG(HAL, INFO, ", mismatch!"); + is_mismatch = TRUE; + } + + DBGLOG(HAL, INFO, "\n"); + DBGLOG(HAL, INFO, + "\tThe total reserved pages of group0~14=0x%03x\n", + total_rsv_cnt); + DBGLOG(HAL, INFO, + "\tThe total ffa pages of group0~14=0x%03x\n", + ffa_cnt); + DBGLOG(HAL, INFO, + "\tThe total free pages of group0~14=0x%03x", free_pg_cnt); + + if (free_pg_cnt != total_rsv_cnt + ffa_cnt) { + DBGLOG(HAL, INFO, + ", mismatch(total_rsv_cnt + ffa_cnt in DMASHDL)"); + is_mismatch = TRUE; + } + + if (free_pg_cnt != ple_rpg_hif) { + DBGLOG(HAL, INFO, ", mismatch(reserved pages in PLE)"); + is_mismatch = TRUE; + } + + DBGLOG(HAL, INFO, "\n"); + DBGLOG(HAL, INFO, "\tThe used pages of group15=0x%03x", pse_src_cnt); + + if (pse_upg_hif != pse_src_cnt) { + DBGLOG(HAL, INFO, ", mismatch!"); + is_mismatch = TRUE; + } + + DBGLOG(HAL, INFO, "\n"); + DBGLOG(HAL, INFO, + "\tThe reserved pages of group15=0x%03x", pse_rsv_cnt); + + if (pse_rpg_hif != pse_rsv_cnt) { + DBGLOG(HAL, INFO, ", mismatch!"); + is_mismatch = TRUE; + } + + DBGLOG(HAL, INFO, "\n"); + + if (!is_mismatch) + DBGLOG(HAL, INFO, "DMASHDL: no counter mismatch\n"); +} + +void haldumpMacInfo(struct ADAPTER *prAdapter) +{ + uint32_t i = 0, j = 0; + uint32_t value = 0, index = 0, flag = 0, queue = 0; + + DBGLOG(HAL, INFO, "Print 0x820F3190 5*20 times\n"); + for (i = 0; i < 5; i++) { + for (j = 0; j < 20; j++) { + HAL_MCR_RD(prAdapter, 0x820F3190, &value); + DBGLOG(HAL, INFO, "0x820F3190: 0x%08x\n", value); + } + kalMdelay(1); + } + + for (j = 0; j < 20; j++) { + HAL_MCR_RD(prAdapter, 0x820FD020, &value); + DBGLOG(HAL, INFO, "slot idle: 0x820FD020: 0x%08x\n", value); + HAL_MCR_RD(prAdapter, 0x820F4128, &value); + DBGLOG(HAL, INFO, + "TX state machine/CCA: 0x820F4128 = 0x%08x\n", value); + HAL_MCR_RD(prAdapter, 0x820F20D0, &value); + DBGLOG(HAL, INFO, + "AGG state machine band0: 0x820F20D0 = 0x%08x\n", value); + HAL_MCR_RD(prAdapter, 0x820F20D4, &value); + DBGLOG(HAL, INFO, + "AGG state machine band1: 0x820F20D4 = 0x%08x\n", value); + /* 1: empty, 0: non-empty */ + HAL_MCR_RD(prAdapter, 0x82060220, &value); + DBGLOG(HAL, INFO, "queue empty: 0x82060220: 0x%08x\n", value); + HAL_MCR_RD(prAdapter, 0x820603EC, &value); + DBGLOG(HAL, INFO, + "PLE MACTX CurState: 0x820603EC: 0x%08x\n", value); + kalMdelay(1); + } + + HAL_MCR_RD(prAdapter, 0x820F4124, &value); + DBGLOG(HAL, INFO, "TXV count: 0x820F4124 = %08x\n", value); + + /* Band 0 TXV1-TXV7 */ + for (j = 0x820F4130; j < 0x820F4148; j += 4) { + HAL_MCR_RD(prAdapter, j, &value); + DBGLOG(HAL, INFO, "0x%08x: 0x%08x\n", j, value); + kalMdelay(1); + } + + /* Band 1 TXV1-TXV7 */ + for (j = 0x820F414C; j < 0x820F4164; j += 4) { + HAL_MCR_RD(prAdapter, j, &value); + DBGLOG(HAL, INFO, "0x%08x: 0x%08x\n", j, value); + kalMdelay(1); + } + + HAL_MCR_RD(prAdapter, 0x820F409C, &value); + DBGLOG(HAL, INFO, "Dump CR: 0x820F409C = %08x\n", value); + + HAL_MCR_RD(prAdapter, 0x820F409C, &value); + DBGLOG(HAL, INFO, "Dump CR: 0x820F409C = %08x\n", value); + + HAL_MCR_RD(prAdapter, 0x820F3080, &value); + DBGLOG(HAL, INFO, "Dump CR: 0x820F3080 = %08x\n", value); + + DBGLOG(HAL, INFO, "Dump ARB CR: 820F3000~820F33FF\n"); + for (index = 0x820f3000; index < 0x820f33ff; index += 4) { + HAL_MCR_RD(prAdapter, index, &value); + DBGLOG(HAL, INFO, "0x%08x: 0x%08x\n", index, value); + } + + DBGLOG(HAL, INFO, "Dump AGG CR: 820F000~820F21FF\n"); + for (index = 0x820f2000; index < 0x820f21ff; index += 4) { + HAL_MCR_RD(prAdapter, index, &value); + DBGLOG(HAL, INFO, "0x%08x: 0x%08x\n", index, value); + } + + DBGLOG(HAL, INFO, "Dump TRB\n"); + HAL_MCR_WR(prAdapter, 0x80025104, 0x02020202); + flag = 0x01010000; + for (i = 0; i < 64; i++) { + HAL_MCR_WR(prAdapter, 0x80025108, flag); + HAL_MCR_RD(prAdapter, 0x820f0024, &value); + DBGLOG(HAL, INFO, "write flag = 0x%08x, 0x820f0024: 0x%08x\n", + flag, value); + flag += 0x02020202; + } + + DBGLOG(HAL, INFO, "Dump ARB\n"); + for (i = 0; i < 20; i++) { + HAL_MCR_RD(prAdapter, 0x802f3190, &value); + DBGLOG(HAL, INFO, "0x802f3190: 0x%08x\n", value); + } + + HAL_MCR_WR(prAdapter, 0x820f082C, 0xf); + HAL_MCR_WR(prAdapter, 0x80025100, 0x1f); + HAL_MCR_WR(prAdapter, 0x80025104, 0x04040404); + + HAL_MCR_WR(prAdapter, 0x80025108, 0x41414040); + HAL_MCR_RD(prAdapter, 0x820f0024, &value); + DBGLOG(HAL, INFO, "0x820f0024: 0x%08x\n", value); + HAL_MCR_RD(prAdapter, 0x820f20d0, &value); + DBGLOG(HAL, INFO, "0x820f20d0: 0x%08x\n", value); + HAL_MCR_RD(prAdapter, 0x820f20d4, &value); + DBGLOG(HAL, INFO, "0x820f20d4: 0x%08x\n", value); + + queue = 0; + flag = 0x00000101; + for (i = 0; i < 25; i++) { + HAL_MCR_WR(prAdapter, 0x820f3060, queue); + flag = 0x00000101; + for (j = 0; j < 8; j++) { + HAL_MCR_WR(prAdapter, 0x80025108, flag); + HAL_MCR_RD(prAdapter, 0x820f0024, &value); + DBGLOG(HAL, INFO, + "write queue = 0x%08x flag = 0x%08x, 0x820f0024: 0x%08x\n", + queue, flag, value); + flag += 0x02020202; + } + queue += 0x01010101; + } + + queue = 0x01010000; + flag = 0x04040505; + HAL_MCR_WR(prAdapter, 0x820f3060, queue); + for (i = 0; i < 3; i++) { + HAL_MCR_WR(prAdapter, 0x80025108, flag); + HAL_MCR_RD(prAdapter, 0x820f0024, &value); + DBGLOG(HAL, INFO, "write flag = 0x%08x, 0x820f0024: 0x%08x\n", + flag, value); + flag += 0x02020202; + } + + flag = 0x00000101; + HAL_MCR_WR(prAdapter, 0x820f3060, 0); /* BSSID = 0 */ + for (i = 0; i < 128; i++) { + HAL_MCR_WR(prAdapter, 0x80025108, flag); + HAL_MCR_RD(prAdapter, 0x820f0024, &value); + DBGLOG(HAL, INFO, "write flag = 0x%08x, 0x820f0024: 0x%08x\n", + flag, value); + flag += 0x02020202; + } + + DBGLOG(HAL, INFO, "Dump AGG\n"); + HAL_MCR_WR(prAdapter, 0x80025104, 0x05050505); + flag = 0x01010000; + for (i = 0; i < 64; i++) { + HAL_MCR_WR(prAdapter, 0x80025108, flag); + HAL_MCR_RD(prAdapter, 0x820f0024, &value); + DBGLOG(HAL, INFO, "write flag = 0x%08x, 0x820f0024: 0x%08x\n", + flag, value); + flag += 0x02020202; + } + + DBGLOG(HAL, INFO, "Dump DMA\n"); + HAL_MCR_WR(prAdapter, 0x80025104, 0x06060606); + flag = 0x01010000; + for (i = 0; i < 64; i++) { + HAL_MCR_WR(prAdapter, 0x80025108, flag); + HAL_MCR_RD(prAdapter, 0x820f0024, &value); + DBGLOG(HAL, INFO, "write flag = 0x%08x, 0x820f0024: 0x%08x\n", + flag, value); + flag += 0x02020202; + } + + DBGLOG(HAL, INFO, "Dump TMAC\n"); + HAL_MCR_WR(prAdapter, 0x80025104, 0x07070707); + flag = 0x01010000; + for (i = 0; i < 33; i++) { + HAL_MCR_WR(prAdapter, 0x80025108, flag); + HAL_MCR_RD(prAdapter, 0x820f0024, &value); + DBGLOG(HAL, INFO, "write flag = 0x%08x, 0x820f0024: 0x%08x\n", + flag, value); + flag += 0x02020202; + } + + DBGLOG(HAL, TRACE, "Dump extra ARB\n"); + HAL_MCR_WR(prAdapter, 0x820f082C, 0xf); + HAL_MCR_WR(prAdapter, 0x80025100, 0x1f); + HAL_MCR_WR(prAdapter, 0x80025104, 0x04040404); + HAL_MCR_WR(prAdapter, 0x80025108, 0x7c7c6d6d); + HAL_MCR_RD(prAdapter, 0x820f0024, &value); + DBGLOG(HAL, TRACE, "Read 0x820f0024: 0x%08x\n", value); + + DBGLOG(HAL, TRACE, " -> check UMAC busy\n"); + HAL_MCR_WR(prAdapter, 0x80025108, 0x40404141); + for (i = 0; i < 30; i++) { + HAL_MCR_RD(prAdapter, 0x820f0024, &value); + DBGLOG(HAL, TRACE, " Read 0x820f0024: 0x%08x\n", value); + } + HAL_MCR_WR(prAdapter, 0x80025108, 0xe0e0e5e5); + for (i = 0; i < 30; i++) { + HAL_MCR_RD(prAdapter, 0x820f0024, &value); + DBGLOG(HAL, TRACE, " Read 0x820f0024: 0x%08x\n", value); + } + + DBGLOG(HAL, TRACE, " -> check txq_num\n"); + HAL_MCR_WR(prAdapter, 0x80025108, 0x4d4d3131); + for (i = 0; i < 30; i++) { + HAL_MCR_RD(prAdapter, 0x820f0024, &value); + DBGLOG(HAL, TRACE, " Read 0x820f0024: 0x%08x\n", value); + } + + DBGLOG(HAL, TRACE, " -> check station pause\n"); + HAL_MCR_RD(prAdapter, 0x82060360, &value); + DBGLOG(HAL, TRACE, " Read 0x82060360: 0x%08x\n", value); + HAL_MCR_RD(prAdapter, 0x82060364, &value); + DBGLOG(HAL, TRACE, " Read 0x82060364: 0x%08x\n", value); + HAL_MCR_RD(prAdapter, 0x82060368, &value); + DBGLOG(HAL, TRACE, " Read 0x82060368: 0x%08x\n", value); + HAL_MCR_RD(prAdapter, 0x8206036C, &value); + DBGLOG(HAL, TRACE, " Read 0x8206036C: 0x%08x\n", value); +} + +static char *q_idx_mcu_str[] = {"RQ0", "RQ1", "RQ2", "RQ3", "Invalid"}; +static char *pkt_ft_str[] = {"cut_through", "store_forward", + "cmd", "PDA_FW_Download"}; +static char *hdr_fmt_str[] = { + "Non-80211-Frame", + "Command-Frame", + "Normal-80211-Frame", + "enhanced-80211-Frame", +}; +static char *p_idx_str[] = {"LMAC", "MCU"}; +static char *q_idx_lmac_str[] = {"WMM0_AC0", "WMM0_AC1", "WMM0_AC2", "WMM0_AC3", + "WMM1_AC0", "WMM1_AC1", "WMM1_AC2", "WMM1_AC3", + "WMM2_AC0", "WMM2_AC1", "WMM2_AC2", "WMM2_AC3", + "WMM3_AC0", "WMM3_AC1", "WMM3_AC2", "WMM3_AC3", + "Band0_ALTX", "Band0_BMC", "Band0_BNC", "Band0_PSMP", + "Band1_ALTX", "Band1_BMC", "Band1_BNC", "Band1_PSMP", + "Invalid"}; + +void halDumpTxdInfo(IN struct ADAPTER *prAdapter, uint32_t *tmac_info) +{ + struct TMAC_TXD_S *txd_s; + struct TMAC_TXD_0 *txd_0; + struct TMAC_TXD_1 *txd_1; + uint8_t q_idx = 0; + + txd_s = (struct TMAC_TXD_S *)tmac_info; + txd_0 = &txd_s->TxD0; + txd_1 = &txd_s->TxD1; + + DBGLOG(HAL, INFO, "TMAC_TXD Fields:\n"); + DBGLOG(HAL, INFO, "\tTMAC_TXD_0:\n"); + DBGLOG(HAL, INFO, "\t\tPortID=%d(%s)\n", + txd_0->p_idx, p_idx_str[txd_0->p_idx]); + + if (txd_0->p_idx == P_IDX_LMAC) + q_idx = txd_0->q_idx % 0x18; + else + q_idx = ((txd_0->q_idx == TxQ_IDX_MCU_PDA) ? + txd_0->q_idx : (txd_0->q_idx % 0x4)); + + DBGLOG(HAL, INFO, "\t\tQueID=0x%x(%s %s)\n", txd_0->q_idx, + (txd_0->p_idx == P_IDX_LMAC ? "LMAC" : "MCU"), + txd_0->p_idx == P_IDX_LMAC ? + q_idx_lmac_str[q_idx] : q_idx_mcu_str[q_idx]); + DBGLOG(HAL, INFO, "\t\tTxByteCnt=%d\n", txd_0->TxByteCount); + DBGLOG(HAL, INFO, "\t\tIpChkSumOffload=%d\n", txd_0->IpChkSumOffload); + DBGLOG(HAL, INFO, "\t\tUdpTcpChkSumOffload=%d\n", + txd_0->UdpTcpChkSumOffload); + DBGLOG(HAL, INFO, "\t\tEthTypeOffset=%d\n", txd_0->EthTypeOffset); + + DBGLOG(HAL, INFO, "\tTMAC_TXD_1:\n"); + DBGLOG(HAL, INFO, "\t\twlan_idx=%d\n", txd_1->wlan_idx); + DBGLOG(HAL, INFO, "\t\tHdrFmt=%d(%s)\n", + txd_1->hdr_format, hdr_fmt_str[txd_1->hdr_format]); + DBGLOG(HAL, INFO, "\t\tHdrInfo=0x%x\n", txd_1->hdr_info); + + switch (txd_1->hdr_format) { + case TMI_HDR_FT_NON_80211: + DBGLOG(HAL, INFO, + "\t\t\tMRD=%d, EOSP=%d, RMVL=%d, VLAN=%d, ETYP=%d\n", + txd_1->hdr_info & (1 << TMI_HDR_INFO_0_BIT_MRD), + txd_1->hdr_info & (1 << TMI_HDR_INFO_0_BIT_EOSP), + txd_1->hdr_info & (1 << TMI_HDR_INFO_0_BIT_RMVL), + txd_1->hdr_info & (1 << TMI_HDR_INFO_0_BIT_VLAN), + txd_1->hdr_info & (1 << TMI_HDR_INFO_0_BIT_ETYP)); + break; + + case TMI_HDR_FT_CMD: + DBGLOG(HAL, INFO, "\t\t\tRsvd=0x%x\n", txd_1->hdr_info); + break; + + case TMI_HDR_FT_NOR_80211: + DBGLOG(HAL, INFO, "\t\t\tHeader Len=%d(WORD)\n", + txd_1->hdr_info & TMI_HDR_INFO_2_MASK_LEN); + break; + + case TMI_HDR_FT_ENH_80211: + DBGLOG(HAL, INFO, "\t\t\tEOSP=%d, AMS=%d\n", + txd_1->hdr_info & (1 << TMI_HDR_INFO_3_BIT_EOSP), + txd_1->hdr_info & (1 << TMI_HDR_INFO_3_BIT_AMS)); + break; + } + + DBGLOG(HAL, INFO, "\t\tTxDFormatType=%d(%s format)\n", txd_1->ft, + (txd_1->ft == TMI_FT_LONG ? + "Long - 8 DWORD" : "Short - 3 DWORD")); + DBGLOG(HAL, INFO, "\t\ttxd_len=%d page(%d DW)\n", + txd_1->txd_len == 0 ? 1 : 2, (txd_1->txd_len + 1) * 16); + DBGLOG(HAL, INFO, + "\t\tHdrPad=%d(Padding Mode: %s, padding bytes: %d)\n", + txd_1->hdr_pad, + ((txd_1->hdr_pad & (TMI_HDR_PAD_MODE_TAIL << 1)) ? + "tail" : "head"), (txd_1->hdr_pad & 0x1 ? 2 : 0)); + DBGLOG(HAL, INFO, "\t\tUNxV=%d\n", txd_1->UNxV); + DBGLOG(HAL, INFO, "\t\tamsdu=%d\n", txd_1->amsdu); + DBGLOG(HAL, INFO, "\t\tTID=%d\n", txd_1->tid); + DBGLOG(HAL, INFO, "\t\tpkt_ft=%d(%s)\n", + txd_1->pkt_ft, pkt_ft_str[txd_1->pkt_ft]); + DBGLOG(HAL, INFO, "\t\town_mac=%d\n", txd_1->OwnMacAddr); + + if (txd_s->TxD1.ft == TMI_FT_LONG) { + struct TMAC_TXD_L *txd_l = (struct TMAC_TXD_L *)tmac_info; + struct TMAC_TXD_2 *txd_2 = &txd_l->TxD2; + struct TMAC_TXD_3 *txd_3 = &txd_l->TxD3; + struct TMAC_TXD_4 *txd_4 = &txd_l->TxD4; + struct TMAC_TXD_5 *txd_5 = &txd_l->TxD5; + struct TMAC_TXD_6 *txd_6 = &txd_l->TxD6; + + DBGLOG(HAL, INFO, "\tTMAC_TXD_2:\n"); + DBGLOG(HAL, INFO, "\t\tsub_type=%d\n", txd_2->sub_type); + DBGLOG(HAL, INFO, "\t\tfrm_type=%d\n", txd_2->frm_type); + DBGLOG(HAL, INFO, "\t\tNDP=%d\n", txd_2->ndp); + DBGLOG(HAL, INFO, "\t\tNDPA=%d\n", txd_2->ndpa); + DBGLOG(HAL, INFO, "\t\tSounding=%d\n", txd_2->sounding); + DBGLOG(HAL, INFO, "\t\tRTS=%d\n", txd_2->rts); + DBGLOG(HAL, INFO, "\t\tbc_mc_pkt=%d\n", txd_2->bc_mc_pkt); + DBGLOG(HAL, INFO, "\t\tBIP=%d\n", txd_2->bip); + DBGLOG(HAL, INFO, "\t\tDuration=%d\n", txd_2->duration); + DBGLOG(HAL, INFO, "\t\tHE(HTC Exist)=%d\n", txd_2->htc_vld); + DBGLOG(HAL, INFO, "\t\tFRAG=%d\n", txd_2->frag); + DBGLOG(HAL, INFO, "\t\tReamingLife/MaxTx time=%d\n", + txd_2->max_tx_time); + DBGLOG(HAL, INFO, "\t\tpwr_offset=%d\n", txd_2->pwr_offset); + DBGLOG(HAL, INFO, "\t\tba_disable=%d\n", txd_2->ba_disable); + DBGLOG(HAL, INFO, "\t\ttiming_measure=%d\n", + txd_2->timing_measure); + DBGLOG(HAL, INFO, "\t\tfix_rate=%d\n", txd_2->fix_rate); + DBGLOG(HAL, INFO, "\tTMAC_TXD_3:\n"); + DBGLOG(HAL, INFO, "\t\tNoAck=%d\n", txd_3->no_ack); + DBGLOG(HAL, INFO, "\t\tPF=%d\n", txd_3->protect_frm); + DBGLOG(HAL, INFO, "\t\ttx_cnt=%d\n", txd_3->tx_cnt); + DBGLOG(HAL, INFO, "\t\tremain_tx_cnt=%d\n", + txd_3->remain_tx_cnt); + DBGLOG(HAL, INFO, "\t\tsn=%d\n", txd_3->sn); + DBGLOG(HAL, INFO, "\t\tpn_vld=%d\n", txd_3->pn_vld); + DBGLOG(HAL, INFO, "\t\tsn_vld=%d\n", txd_3->sn_vld); + DBGLOG(HAL, INFO, "\tTMAC_TXD_4:\n"); + DBGLOG(HAL, INFO, "\t\tpn_low=0x%x\n", txd_4->pn_low); + DBGLOG(HAL, INFO, "\tTMAC_TXD_5:\n"); + DBGLOG(HAL, INFO, "\t\ttx_status_2_host=%d\n", + txd_5->tx_status_2_host); + DBGLOG(HAL, INFO, "\t\ttx_status_2_mcu=%d\n", + txd_5->tx_status_2_mcu); + DBGLOG(HAL, INFO, "\t\ttx_status_fmt=%d\n", + txd_5->tx_status_fmt); + + if (txd_5->tx_status_2_host || txd_5->tx_status_2_mcu) + DBGLOG(HAL, INFO, "\t\tpid=%d\n", txd_5->pid); + + if (txd_2->fix_rate) + DBGLOG(HAL, INFO, + "\t\tda_select=%d\n", txd_5->da_select); + + DBGLOG(HAL, INFO, "\t\tpwr_mgmt=0x%x\n", txd_5->pwr_mgmt); + DBGLOG(HAL, INFO, "\t\tpn_high=0x%x\n", txd_5->pn_high); + + if (txd_2->fix_rate) { + DBGLOG(HAL, INFO, "\tTMAC_TXD_6:\n"); + DBGLOG(HAL, INFO, "\t\tfix_rate_mode=%d\n", + txd_6->fix_rate_mode); + DBGLOG(HAL, INFO, "\t\tGI=%d(%s)\n", txd_6->gi, + (txd_6->gi == 0 ? "LONG" : "SHORT")); + DBGLOG(HAL, INFO, "\t\tldpc=%d(%s)\n", txd_6->ldpc, + (txd_6->ldpc == 0 ? "BCC" : "LDPC")); + DBGLOG(HAL, INFO, "\t\tTxBF=%d\n", txd_6->TxBF); + DBGLOG(HAL, INFO, "\t\ttx_rate=0x%x\n", txd_6->tx_rate); + DBGLOG(HAL, INFO, "\t\tant_id=%d\n", txd_6->ant_id); + DBGLOG(HAL, INFO, "\t\tdyn_bw=%d\n", txd_6->dyn_bw); + DBGLOG(HAL, INFO, "\t\tbw=%d\n", txd_6->bw); + } + } +} + +void halShowTxdInfo( + struct ADAPTER *prAdapter, + u_int32_t fid) +{ + /* + * TODO: Follow connac 2x design and get TXD from PLE by FW. + + uint32_t txd_info[16] = {0}; + + halGetPleTxdInfo(prAdapter, fid, txd_info); + halDumpTxdInfo(prAdapter, txd_info); + */ +} + +int32_t halShowStatInfo(struct ADAPTER *prAdapter, + IN char *pcCommand, IN int i4TotalLen, + struct PARAM_HW_WLAN_INFO *prHwWlanInfo, + struct PARAM_GET_STA_STATISTICS *prQueryStaStatistics, + u_int8_t fgResetCnt, uint32_t u4StatGroup) +{ + int32_t i4BytesWritten = 0; + int32_t rRssi; + uint16_t u2LinkSpeed; + uint32_t u4Per, u4RxPer[ENUM_BAND_NUM], u4AmpduPer[ENUM_BAND_NUM], + u4InstantPer; + uint8_t ucDbdcIdx, ucSkipAr, ucStaIdx, ucNss; + static uint32_t u4TotalTxCnt, u4TotalFailCnt; + static uint32_t u4Rate1TxCnt, u4Rate1FailCnt; + static uint32_t au4RxMpduCnt[ENUM_BAND_NUM] = {0}; + static uint32_t au4FcsError[ENUM_BAND_NUM] = {0}; + static uint32_t au4RxFifoCnt[ENUM_BAND_NUM] = {0}; + static uint32_t au4AmpduTxSfCnt[ENUM_BAND_NUM] = {0}; + static uint32_t au4AmpduTxAckSfCnt[ENUM_BAND_NUM] = {0}; + struct RX_CTRL *prRxCtrl; + uint32_t u4InstantRxPer[ENUM_BAND_NUM]; + struct PARAM_CUSTOM_SW_CTRL_STRUCT rSwCtrlInfo; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + int16_t i2Wf0AvgPwr = 0, i2Wf1AvgPwr = 0; + uint32_t u4BufLen = 0; +#if (CFG_SUPPORT_RA_GEN == 1) + uint8_t ucRaTableNum = sizeof(RATE_TBLE) / sizeof(char *); + uint8_t ucRaStatusNum = sizeof(RA_STATUS_TBLE) / sizeof(char *); + uint8_t ucRaLtModeNum = sizeof(LT_MODE_TBLE) / sizeof(char *); + uint8_t ucRaSgiUnSpStateNum = sizeof(SGI_UNSP_STATE_TBLE) / + sizeof(char *); + uint8_t ucRaBwStateNum = sizeof(BW_STATE_TBLE) / sizeof(char *); + uint8_t ucAggRange[AGG_RANGE_SEL_NUM] = {0}; + uint32_t u4RangeCtrl_0, u4RangeCtrl_1; + enum AGG_RANGE_TYPE_T eRangeType = ENUM_AGG_RANGE_TYPE_TX; +#endif + uint8_t ucBssIndex = AIS_DEFAULT_INDEX; + struct PARAM_LINK_SPEED_EX rLinkSpeed; + + ucSkipAr = prQueryStaStatistics->ucSkipAr; + prRxCtrl = &prAdapter->rRxCtrl; + ucNss = prAdapter->rWifiVar.ucNSS; + + if (ucSkipAr) { +#if (CFG_SUPPORT_RA_GEN == 1) + u4TotalTxCnt += prQueryStaStatistics->u4TransmitCount; + u4TotalFailCnt += prQueryStaStatistics->u4TransmitFailCount; + u4Rate1TxCnt += prQueryStaStatistics->u4Rate1TxCnt; + u4Rate1FailCnt += prQueryStaStatistics->u4Rate1FailCnt; + + u4Per = (u4Rate1TxCnt == 0) ? + (0) : (1000 * (u4Rate1FailCnt) / (u4Rate1TxCnt)); + u4InstantPer = (prQueryStaStatistics->u4Rate1TxCnt == 0) ? + (0) : (1000 * (prQueryStaStatistics->u4Rate1FailCnt) / + (prQueryStaStatistics->u4Rate1TxCnt)); +#else + u4TotalTxCnt += prHwWlanInfo->rWtblTxCounter.u2CurBwTxCnt + + prHwWlanInfo->rWtblTxCounter.u2OtherBwTxCnt; + u4TotalFailCnt += prHwWlanInfo->rWtblTxCounter.u2CurBwFailCnt + + prHwWlanInfo->rWtblTxCounter.u2OtherBwFailCnt; + u4Rate1TxCnt += prHwWlanInfo->rWtblTxCounter.u2Rate1TxCnt; + u4Rate1FailCnt += prHwWlanInfo->rWtblTxCounter.u2Rate1FailCnt; + u4Per = (prHwWlanInfo->rWtblTxCounter.u2Rate1TxCnt == 0) ? + (0) : (1000 * u4Rate1FailCnt / u4Rate1TxCnt); + u4InstantPer = + (prHwWlanInfo->rWtblTxCounter.u2Rate1TxCnt == 0) ? (0) : + (1000 * (prHwWlanInfo->rWtblTxCounter.u2Rate1FailCnt) / + (prHwWlanInfo->rWtblTxCounter.u2Rate1TxCnt)); +#endif + } else { + u4Per = (prQueryStaStatistics->u4Rate1TxCnt == 0) ? + (0) : (1000 * (prQueryStaStatistics->u4Rate1FailCnt) / + (prQueryStaStatistics->u4Rate1TxCnt)); + u4InstantPer = (prQueryStaStatistics->ucPer == 0) ? + (0) : (prQueryStaStatistics->ucPer); + } + + for (ucDbdcIdx = 0; ucDbdcIdx < ENUM_BAND_NUM; ucDbdcIdx++) { + au4RxMpduCnt[ucDbdcIdx] += + prQueryStaStatistics->rMibInfo[ucDbdcIdx].u4RxMpduCnt; + au4FcsError[ucDbdcIdx] += + prQueryStaStatistics->rMibInfo[ucDbdcIdx].u4FcsError; + au4RxFifoCnt[ucDbdcIdx] += + prQueryStaStatistics->rMibInfo[ucDbdcIdx].u4RxFifoFull; + au4AmpduTxSfCnt[ucDbdcIdx] += + prQueryStaStatistics->rMibInfo[ucDbdcIdx].u4AmpduTxSfCnt; + au4AmpduTxAckSfCnt[ucDbdcIdx] += + prQueryStaStatistics->rMibInfo[ucDbdcIdx].u4AmpduTxAckSfCnt; + + u4RxPer[ucDbdcIdx] = + ((au4RxMpduCnt[ucDbdcIdx] + au4FcsError[ucDbdcIdx]) == 0) ? + (0) : (1000 * au4FcsError[ucDbdcIdx] / + (au4RxMpduCnt[ucDbdcIdx] + + au4FcsError[ucDbdcIdx])); + + u4AmpduPer[ucDbdcIdx] = + (au4AmpduTxSfCnt[ucDbdcIdx] == 0) ? + (0) : (1000 * (au4AmpduTxSfCnt[ucDbdcIdx] - + au4AmpduTxAckSfCnt[ucDbdcIdx]) / + au4AmpduTxSfCnt[ucDbdcIdx]); + + u4InstantRxPer[ucDbdcIdx] = + ((prQueryStaStatistics->rMibInfo[ucDbdcIdx].u4RxMpduCnt + + prQueryStaStatistics->rMibInfo[ucDbdcIdx].u4FcsError) + == 0) ? (0) : (1000 * prQueryStaStatistics-> + rMibInfo[ucDbdcIdx].u4FcsError / + (prQueryStaStatistics->rMibInfo[ucDbdcIdx].u4RxMpduCnt + + prQueryStaStatistics->rMibInfo[ucDbdcIdx].u4FcsError)); + } + + rRssi = RCPI_TO_dBm(prQueryStaStatistics->ucRcpi); + u2LinkSpeed = (prQueryStaStatistics->u2LinkSpeed == 0) ? 0 : + prQueryStaStatistics->u2LinkSpeed / 2; + + /* =========== Group 0x0001 =========== */ + if (u4StatGroup & 0x0001) { + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", "\n----- STA Stat (Group 0x01) -----\n"); + + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "CurrTemperature", " = ", + prQueryStaStatistics->ucTemperature); + + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "Tx Total cnt", " = ", + ucSkipAr ? (u4TotalTxCnt) : + (prQueryStaStatistics->u4TransmitCount)); + + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "Tx Fail Cnt", " = ", + ucSkipAr ? (u4TotalFailCnt) : + (prQueryStaStatistics->u4TransmitFailCount)); + + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "Rate1 Tx Cnt", " = ", + ucSkipAr ? (u4Rate1TxCnt) : + (prQueryStaStatistics->u4Rate1TxCnt)); + + if (ucSkipAr) + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d, PER = %d.%1d%%, instant PER = %d.%1d%%\n", + "Rate1 Fail Cnt", " = ", + u4Rate1FailCnt, u4Per/10, u4Per%10, + u4InstantPer/10, u4InstantPer%10); + else + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d, PER = %d.%1d%%, instant PER = %d%%\n", + "Rate1 Fail Cnt", " = ", + prQueryStaStatistics->u4Rate1FailCnt, + u4Per/10, u4Per%10, u4InstantPer); + + if ((ucSkipAr) && (fgResetCnt)) { + u4TotalTxCnt = 0; + u4TotalFailCnt = 0; + u4Rate1TxCnt = 0; + u4Rate1FailCnt = 0; + } + } + + /* =========== Group 0x0002 =========== */ + if (u4StatGroup & 0x0002) { + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", "----- MIB Info (Group 0x02) -----\n"); + + for (ucDbdcIdx = 0; ucDbdcIdx < ENUM_BAND_NUM; ucDbdcIdx++) { + if (prAdapter->rWifiVar.fgDbDcModeEn) + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "[DBDC_%d] :\n", ucDbdcIdx); + + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "RX Success", " = ", + au4RxMpduCnt[ucDbdcIdx]); + + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d, PER = %d.%1d%%, instant PER = %d.%1d%%\n", + "RX with CRC", " = ", au4FcsError[ucDbdcIdx], + u4RxPer[ucDbdcIdx] / 10, + u4RxPer[ucDbdcIdx] % 10, + u4InstantRxPer[ucDbdcIdx] / 10, + u4InstantRxPer[ucDbdcIdx] % 10); + + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "RX drop FIFO full", " = ", + au4RxFifoCnt[ucDbdcIdx]); + + if (!prAdapter->rWifiVar.fgDbDcModeEn) + break; + } + + if (fgResetCnt) { + kalMemZero(au4RxMpduCnt, sizeof(au4RxMpduCnt)); + kalMemZero(au4FcsError, sizeof(au4RxMpduCnt)); + kalMemZero(au4RxFifoCnt, sizeof(au4RxMpduCnt)); + kalMemZero(au4AmpduTxSfCnt, sizeof(au4RxMpduCnt)); + kalMemZero(au4AmpduTxAckSfCnt, sizeof(au4RxMpduCnt)); + } + } + + /* =========== Group 0x0004 =========== */ + if (u4StatGroup & 0x0004) { + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", "----- Last Rx Info (Group 0x04) -----\n"); + + /* get Beacon RSSI */ + ucBssIndex = secGetBssIdxByWlanIdx + (prAdapter, (uint8_t)(prHwWlanInfo->u4Index)); + + rStatus = kalIoctlByBssIdx(prAdapter->prGlueInfo, + wlanoidQueryRssi, &rLinkSpeed, + sizeof(rLinkSpeed), TRUE, TRUE, TRUE, + &u4BufLen, ucBssIndex); + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(REQ, WARN, "unable to retrieve rssi\n"); + if (ucBssIndex < BSSID_NUM) + rRssi = rLinkSpeed.rLq[ucBssIndex].cRssi; + + rSwCtrlInfo.u4Data = 0; + rSwCtrlInfo.u4Id = CMD_SW_DBGCTL_ADVCTL_GET_ID + 1; +#if (CFG_SUPPORT_RA_GEN == 0) + rStatus = kalIoctl(prAdapter->prGlueInfo, + wlanoidQuerySwCtrlRead, &rSwCtrlInfo, + sizeof(rSwCtrlInfo), TRUE, TRUE, TRUE, + &u4BufLen); +#endif + DBGLOG(REQ, LOUD, "rStatus %u, rSwCtrlInfo.u4Data 0x%x\n", + rStatus, rSwCtrlInfo.u4Data); + if (rStatus == WLAN_STATUS_SUCCESS) { + i2Wf0AvgPwr = rSwCtrlInfo.u4Data & 0xFFFF; + i2Wf1AvgPwr = (rSwCtrlInfo.u4Data >> 16) & 0xFFFF; + + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d %d\n", "NOISE", " = ", + i2Wf0AvgPwr, i2Wf1AvgPwr); + } + + /* Last RX Rate */ + i4BytesWritten += nicGetRxRateInfo(prAdapter, + pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten, + (uint8_t)(prHwWlanInfo->u4Index)); + + /* Last RX RSSI */ + i4BytesWritten += nicRxGetLastRxRssi(prAdapter, + pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten, + (uint8_t)(prHwWlanInfo->u4Index)); + + /* Last TX Resp RSSI */ + if (ucNss > 2) + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d %d %d %d\n", + "Tx Response RSSI", " = ", + RCPI_TO_dBm( + prHwWlanInfo->rWtblRxCounter.ucRxRcpi0), + RCPI_TO_dBm( + prHwWlanInfo->rWtblRxCounter.ucRxRcpi1), + RCPI_TO_dBm( + prHwWlanInfo->rWtblRxCounter.ucRxRcpi2), + RCPI_TO_dBm( + prHwWlanInfo->rWtblRxCounter.ucRxRcpi3)); + else + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d %d\n", "Tx Response RSSI", " = ", + RCPI_TO_dBm( + prHwWlanInfo->rWtblRxCounter.ucRxRcpi0), + RCPI_TO_dBm( + prHwWlanInfo->rWtblRxCounter.ucRxRcpi1)); + + /* Last Beacon RSSI */ + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "Beacon RSSI", " = ", rRssi); + } + + /* =========== Group 0x0008 =========== */ + if (u4StatGroup & 0x0008) { + /* TxV */ + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", "----- Last TX Info (Group 0x08) -----\n"); + + for (ucDbdcIdx = 0; ucDbdcIdx < ENUM_BAND_NUM; ucDbdcIdx++) { + if (prAdapter->rWifiVar.fgDbDcModeEn) + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "[DBDC_%d] :\n", ucDbdcIdx); + + i4BytesWritten += nicTxGetVectorInfo( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + &prQueryStaStatistics->rTxVector[ucDbdcIdx]); + + if (prQueryStaStatistics->rTxVector[ucDbdcIdx] + .u4TxV[0] == 0xFFFFFFFF) + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%s\n", "Chip Out TX Power", + " = ", "N/A"); + else + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%ld.%1ld dBm\n", + "Chip Out TX Power", " = ", + TX_VECTOR_GET_TX_PWR( + &prQueryStaStatistics->rTxVector[ + ucDbdcIdx]) >> 1, + 5 * (TX_VECTOR_GET_TX_PWR( + &prQueryStaStatistics->rTxVector[ + ucDbdcIdx]) % 2)); + + if (!prAdapter->rWifiVar.fgDbDcModeEn) + break; + } + } + + /* =========== Group 0x0010 =========== */ + if (u4StatGroup & 0x0010) { + /* RX Reorder */ + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", "----- RX Reorder (Group 0x10) -----\n"); + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%llu\n", "Rx reorder miss", " = ", + RX_GET_CNT(prRxCtrl, RX_DATA_REORDER_MISS_COUNT)); + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%llu\n", "Rx reorder within", " = ", + RX_GET_CNT(prRxCtrl, RX_DATA_REORDER_WITHIN_COUNT)); + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%llu\n", "Rx reorder ahead", " = ", + RX_GET_CNT(prRxCtrl, RX_DATA_REORDER_AHEAD_COUNT)); + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%llu\n", "Rx reorder behind", " = ", + RX_GET_CNT(prRxCtrl, RX_DATA_REORDER_BEHIND_COUNT)); + } + + /* =========== Group 0x0020 =========== */ + if (u4StatGroup & 0x0020) { + /* RA info */ + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", "----- RA Info (Group 0x20) -----\n"); + + /* Last TX Rate */ + i4BytesWritten += nicGetTxRateInfo( + pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten, + FALSE, prHwWlanInfo, prQueryStaStatistics); + + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%-20s%s%d\n", "LinkSpeed", + " = ", u2LinkSpeed); + + if (!prQueryStaStatistics->ucSkipAr) { + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%s\n", "RateTable", " = ", +#if (CFG_SUPPORT_RA_GEN == 1) + prQueryStaStatistics->ucArTableIdx < + (ucRaTableNum - 1) ? + RATE_TBLE[prQueryStaStatistics->ucArTableIdx] : + RATE_TBLE[ucRaTableNum - 1]); +#else + prQueryStaStatistics->ucArTableIdx < 6 ? + RATE_TBLE[prQueryStaStatistics->ucArTableIdx] : + RATE_TBLE[6]); +#endif + + if (wlanGetStaIdxByWlanIdx(prAdapter, + (uint8_t)(prHwWlanInfo->u4Index), &ucStaIdx) == + WLAN_STATUS_SUCCESS) { + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "2G Support 256QAM TX", + " = ", +#if (CFG_SUPPORT_RA_GEN == 1) + ((prAdapter->arStaRec[ucStaIdx].u4Flags + & MTK_SYNERGY_CAP_SUPPORT_24G_MCS89) || + (prQueryStaStatistics-> + ucDynamicGband256QAMState == 2)) ? + 1 : 0); +#else + (prAdapter->arStaRec[ucStaIdx].u4Flags & + MTK_SYNERGY_CAP_SUPPORT_24G_MCS89) ? + 1 : 0); +#endif + } + +#if (CFG_SUPPORT_RA_GEN == 0) + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d%%\n", "Rate1 instantPer", " = ", + u4InstantPer); +#endif + + if (prQueryStaStatistics->ucAvePer == 0xFF) { + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%s\n", "Train Down", " = ", + "N/A"); + + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%s\n", "Train Up", " = ", + "N/A"); + } else { + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d -> %d\n", "Train Down", + " = ", + (uint16_t) + (prQueryStaStatistics->u2TrainDown + & BITS(0, 7)), + (uint16_t) + ((prQueryStaStatistics->u2TrainDown >> + 8) & BITS(0, 7))); + + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d -> %d\n", "Train Up", " = ", + (uint16_t) + (prQueryStaStatistics->u2TrainUp + & BITS(0, 7)), + (uint16_t) + ((prQueryStaStatistics->u2TrainUp >> 8) + & BITS(0, 7))); + } + + if (prQueryStaStatistics->fgIsForceTxStream == 0) + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%s\n", "Force Tx Stream", + " = ", "N/A"); + else + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "Force Tx Stream", " = ", + prQueryStaStatistics-> + fgIsForceTxStream); + + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "Force SE off", " = ", + prQueryStaStatistics->fgIsForceSeOff); + +#if (CFG_SUPPORT_RA_GEN == 1) + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%s\n", "LtMode", " = ", + prQueryStaStatistics->ucLowTrafficMode < + (ucRaLtModeNum - 1) ? + LT_MODE_TBLE[prQueryStaStatistics-> + ucLowTrafficMode] : + LT_MODE_TBLE[ucRaLtModeNum - 1]); + + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%s\n", "SgiState", " = ", + prQueryStaStatistics->ucDynamicSGIState < + (ucRaSgiUnSpStateNum - 1) ? + SGI_UNSP_STATE_TBLE[prQueryStaStatistics-> + ucDynamicSGIState] : + SGI_UNSP_STATE_TBLE[ucRaSgiUnSpStateNum - 1]); + + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%s\n", "BwState", " = ", + prQueryStaStatistics->ucDynamicBWState < + (ucRaBwStateNum - 1) ? + BW_STATE_TBLE[prQueryStaStatistics-> + ucDynamicBWState] : + BW_STATE_TBLE[ucRaBwStateNum - 1]); + + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%s\n", "NonSpState", " = ", + prQueryStaStatistics->ucDynamicSGIState < + (ucRaSgiUnSpStateNum - 1) ? + SGI_UNSP_STATE_TBLE[prQueryStaStatistics-> + ucVhtNonSpRateState] : + SGI_UNSP_STATE_TBLE[ucRaSgiUnSpStateNum - 1]); +#endif + } + +#if (CFG_SUPPORT_RA_GEN == 1) + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "RunningCnt", " = ", + prQueryStaStatistics->u2RaRunningCnt); + + prQueryStaStatistics->ucRaStatus &= ~0x80; + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%s\n", "Status", " = ", + prQueryStaStatistics->ucRaStatus < (ucRaStatusNum - 1) ? + RA_STATUS_TBLE[prQueryStaStatistics->ucRaStatus] : + RA_STATUS_TBLE[ucRaStatusNum - 1]); + + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "MaxAF", " = ", + prHwWlanInfo->rWtblPeerCap.ucAmpduFactor); + + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s0x%x\n", "SpeIdx", " = ", + prHwWlanInfo->rWtblPeerCap.ucSpatialExtensionIndex); +#endif + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "CBRN", " = ", + prHwWlanInfo->rWtblPeerCap.ucChangeBWAfterRateN); + + /* Rate1~Rate8 */ + i4BytesWritten += nicGetTxRateInfo( + pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten, + TRUE, prHwWlanInfo, prQueryStaStatistics); + } + + /* =========== Group 0x0040 =========== */ + if (u4StatGroup & 0x0040) { +#if (CFG_SUPPORT_RA_GEN == 1) + u4RangeCtrl_0 = prQueryStaStatistics->u4AggRangeCtrl_0; + u4RangeCtrl_1 = prQueryStaStatistics->u4AggRangeCtrl_1; + eRangeType = (enum AGG_RANGE_TYPE_T) + prQueryStaStatistics->ucRangeType; + + ucAggRange[0] = (((u4RangeCtrl_0) & AGG_RANGE_SEL_0_MASK) >> + AGG_RANGE_SEL_0_OFFSET); + ucAggRange[1] = (((u4RangeCtrl_0) & AGG_RANGE_SEL_1_MASK) >> + AGG_RANGE_SEL_1_OFFSET); + ucAggRange[2] = (((u4RangeCtrl_0) & AGG_RANGE_SEL_2_MASK) >> + AGG_RANGE_SEL_2_OFFSET); + ucAggRange[3] = (((u4RangeCtrl_0) & AGG_RANGE_SEL_3_MASK) >> + AGG_RANGE_SEL_3_OFFSET); + ucAggRange[4] = (((u4RangeCtrl_1) & AGG_RANGE_SEL_4_MASK) >> + AGG_RANGE_SEL_4_OFFSET); + ucAggRange[5] = (((u4RangeCtrl_1) & AGG_RANGE_SEL_5_MASK) >> + AGG_RANGE_SEL_5_OFFSET); + ucAggRange[6] = (((u4RangeCtrl_1) & AGG_RANGE_SEL_6_MASK) >> + AGG_RANGE_SEL_6_OFFSET); + + /* Tx Agg */ + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s%s%s", "------ ", + (eRangeType) ? ( + (eRangeType == ENUM_AGG_RANGE_TYPE_TRX) ? + ("TRX") : ("RX")) : ("TX"), + " AGG (Group 0x40) -----\n"); + + if (eRangeType == ENUM_AGG_RANGE_TYPE_TRX) { + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-6s%8d%5d%1s%2d%5d%1s%2d%5d%3s", + " TX :", ucAggRange[0] + 1, + ucAggRange[0] + 2, "~", ucAggRange[1] + 1, + ucAggRange[1] + 2, "~", ucAggRange[2] + 1, + ucAggRange[2] + 2, "~64\n"); + + for (ucDbdcIdx = 0; ucDbdcIdx < ENUM_BAND_NUM; + ucDbdcIdx++) { + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "DBDC%d:", ucDbdcIdx); + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%8d%8d%8d%8d\n", + prQueryStaStatistics-> + rMibInfo[ucDbdcIdx].au2TxRangeAmpduCnt[ + 0], + prQueryStaStatistics-> + rMibInfo[ucDbdcIdx].au2TxRangeAmpduCnt[ + 1], + prQueryStaStatistics-> + rMibInfo[ucDbdcIdx].au2TxRangeAmpduCnt[ + 2], + prQueryStaStatistics-> + rMibInfo[ucDbdcIdx].au2TxRangeAmpduCnt[ + 3]); + + if (!prAdapter->rWifiVar.fgDbDcModeEn) + break; + } + + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-6s%8d%5d%1s%2d%5d%1s%2d%5d%3s", + " RX :", ucAggRange[3] + 1, + ucAggRange[3] + 2, "~", ucAggRange[4] + 1, + ucAggRange[4] + 2, "~", ucAggRange[5] + 1, + ucAggRange[5] + 2, "~64\n"); + + for (ucDbdcIdx = 0; ucDbdcIdx < ENUM_BAND_NUM; + ucDbdcIdx++) { + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "DBDC%d:", ucDbdcIdx); + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%8d%8d%8d%8d\n", + prQueryStaStatistics-> + rMibInfo[ucDbdcIdx].au2TxRangeAmpduCnt[ + 4], + prQueryStaStatistics-> + rMibInfo[ucDbdcIdx].au2TxRangeAmpduCnt[ + 5], + prQueryStaStatistics-> + rMibInfo[ucDbdcIdx].au2TxRangeAmpduCnt[ + 6], + prQueryStaStatistics-> + rMibInfo[ucDbdcIdx].au2TxRangeAmpduCnt[ + 7]); + + if (!prAdapter->rWifiVar.fgDbDcModeEn) + break; + } + } else { + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten, + "%-6s%8d%5d%1s%2d%5d%1s%2d%5d%1s%2d%5d%1s%2d%5d%1s%2d%5d%1s%2d%5d%3s", + "Range:", ucAggRange[0] + 1, + ucAggRange[0] + 2, "~", ucAggRange[1] + 1, + ucAggRange[1] + 2, "~", ucAggRange[2] + 1, + ucAggRange[2] + 2, "~", ucAggRange[3] + 1, + ucAggRange[3] + 2, "~", ucAggRange[4] + 1, + ucAggRange[4] + 2, "~", ucAggRange[5] + 1, + ucAggRange[5] + 2, "~", ucAggRange[6] + 1, + ucAggRange[6] + 2, "~64\n"); + + for (ucDbdcIdx = 0; ucDbdcIdx < ENUM_BAND_NUM; + ucDbdcIdx++) { + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "DBDC%d:", ucDbdcIdx); + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%8d%8d%8d%8d%8d%8d%8d%8d\n", + prQueryStaStatistics-> + rMibInfo[ucDbdcIdx].au2TxRangeAmpduCnt[ + 0], + prQueryStaStatistics-> + rMibInfo[ucDbdcIdx].au2TxRangeAmpduCnt[ + 1], + prQueryStaStatistics-> + rMibInfo[ucDbdcIdx].au2TxRangeAmpduCnt[ + 2], + prQueryStaStatistics-> + rMibInfo[ucDbdcIdx].au2TxRangeAmpduCnt[ + 3], + prQueryStaStatistics-> + rMibInfo[ucDbdcIdx].au2TxRangeAmpduCnt[ + 4], + prQueryStaStatistics-> + rMibInfo[ucDbdcIdx].au2TxRangeAmpduCnt[ + 5], + prQueryStaStatistics-> + rMibInfo[ucDbdcIdx].au2TxRangeAmpduCnt[ + 6], + prQueryStaStatistics-> + rMibInfo[ucDbdcIdx].au2TxRangeAmpduCnt[ + 7]); + + if (!prAdapter->rWifiVar.fgDbDcModeEn) + break; + } + } +#else + /* Tx Agg */ + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", "------ TX AGG (Group 0x40) -----\n"); + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-12s%s", "Range:", + "1 2~5 6~15 16~22 23~33 34~49 50~57 58~64\n"); + for (ucDbdcIdx = 0; ucDbdcIdx < ENUM_BAND_NUM; ucDbdcIdx++) { + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "DBDC%d:", ucDbdcIdx); + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%7d%8d%9d%9d%9d%9d%9d%9d\n", + prQueryStaStatistics-> + rMibInfo[ucDbdcIdx].au2TxRangeAmpduCnt[ + 0], + prQueryStaStatistics-> + rMibInfo[ucDbdcIdx].au2TxRangeAmpduCnt[ + 1], + prQueryStaStatistics-> + rMibInfo[ucDbdcIdx].au2TxRangeAmpduCnt[ + 2], + prQueryStaStatistics-> + rMibInfo[ucDbdcIdx].au2TxRangeAmpduCnt[ + 3], + prQueryStaStatistics-> + rMibInfo[ucDbdcIdx].au2TxRangeAmpduCnt[ + 4], + prQueryStaStatistics-> + rMibInfo[ucDbdcIdx].au2TxRangeAmpduCnt[ + 5], + prQueryStaStatistics-> + rMibInfo[ucDbdcIdx].au2TxRangeAmpduCnt[ + 6], + prQueryStaStatistics-> + rMibInfo[ucDbdcIdx].au2TxRangeAmpduCnt[ + 7]); + if (!prAdapter->rWifiVar.fgDbDcModeEn) + break; + } +#endif + } + + return i4BytesWritten; +} + +#ifdef CFG_SUPPORT_LINK_QUALITY_MONITOR +int connac_get_rx_rate_info(IN struct ADAPTER *prAdapter, + OUT uint32_t *pu4Rate, OUT uint32_t *pu4Nss, + OUT uint32_t *pu4RxMode, OUT uint32_t *pu4FrMode, + OUT uint32_t *pu4Sgi) +{ + struct STA_RECORD *prStaRec; + uint32_t rxmode = 0, rate = 0, frmode = 0, sgi = 0, nsts = 0; + uint32_t groupid = 0, stbc = 0, nss = 0; + uint32_t u4RxVector0 = 0, u4RxVector1 = 0; + uint8_t ucWlanIdx, ucStaIdx; + + if ((!pu4Rate) || (!pu4Nss) || (!pu4RxMode) || (!pu4FrMode) || + (!pu4Sgi)) + return -1; + + prStaRec = aisGetStaRecOfAP(prAdapter, AIS_DEFAULT_INDEX); + if (prStaRec) { + ucWlanIdx = prStaRec->ucWlanIndex; + } else { + DBGLOG(SW4, ERROR, "prStaRecOfAP is null\n"); + return -1; + } + + if (wlanGetStaIdxByWlanIdx(prAdapter, ucWlanIdx, &ucStaIdx) == + WLAN_STATUS_SUCCESS) { + u4RxVector0 = prAdapter->arStaRec[ucStaIdx].u4RxVector0; + u4RxVector1 = prAdapter->arStaRec[ucStaIdx].u4RxVector1; + if ((u4RxVector0 == 0) || (u4RxVector1 == 0)) { + DBGLOG(SW4, WARN, "RxVector1 or RxVector2 is 0\n"); + return -1; + } + } else { + DBGLOG(SW4, ERROR, "wlanGetStaIdxByWlanIdx fail\n"); + return -1; + } + + rate = (u4RxVector0 & RX_VT_RX_RATE_MASK) >> RX_VT_RX_RATE_OFFSET; + nsts = ((u4RxVector1 & RX_VT_NSTS_MASK) >> RX_VT_NSTS_OFFSET); + stbc = ((u4RxVector0 & RX_VT_STBC_MASK) >> RX_VT_STBC_OFFSET); + rxmode = (u4RxVector0 & RX_VT_RX_MODE_MASK) >> RX_VT_RX_MODE_OFFSET; + frmode = (u4RxVector0 & RX_VT_FR_MODE_MASK) >> RX_VT_FR_MODE_OFFSET; + sgi = u4RxVector0 & RX_VT_SHORT_GI; + groupid = (u4RxVector1 & RX_VT_GROUP_ID_MASK) >> RX_VT_GROUP_ID_OFFSET; + + if ((groupid == 0) || (groupid == 63)) + nsts += 1; + + nss = stbc ? (nsts >> 1) : nsts; + + sgi = (sgi == 0) ? 0 : 1; + + if (frmode >= 4) { + DBGLOG(SW4, ERROR, "frmode error: %u\n", frmode); + return -1; + } + + *pu4Rate = rate; + *pu4Nss = nss; + *pu4RxMode = rxmode; + *pu4FrMode = frmode; + *pu4Sgi = sgi; + + DBGLOG(SW4, TRACE, + "rxmode=[%u], rate=[%u], bw=[%u], sgi=[%u], nss=[%u]\n", + rxmode, rate, frmode, sgi, nss + ); + + return 0; +} +#endif + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/common/dbg_connac2x.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/common/dbg_connac2x.c new file mode 100644 index 0000000000000000000000000000000000000000..6d1fa4b11d9738c1f0bc4bdecc0acb5087aedef1 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/common/dbg_connac2x.c @@ -0,0 +1,2819 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/****************************************************************************** + *[File] dbg_connac2x.c + *[Version] v1.0 + *[Revision Date] 2019-04-09 + *[Author] + *[Description] + * The program provides WIFI FALCON MAC Debug APIs + *[Copyright] + * Copyright (C) 2015 MediaTek Incorporation. All Rights Reserved. + ******************************************************************************/ + +#if (CFG_SUPPORT_CONNAC2X == 1) +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" +#include "mt_dmac.h" +#include "wf_ple.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#if defined(MT7915) +#define WTBL_VER 1 +#elif defined(SOC3_0) +#define WTBL_VER 2 +#else +#define WTBL_VER 3 +#endif + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ +static char *RATE_V2_HW_TX_MODE_STR[] = { + "CCK", "OFDM", "MM", "GF", "VHT", "PLR", + "N/A", "N/A", "HE_SU", "HE_ER", "HE_TRIG", "HE_MU"}; + +static char *RATE_TBLE[] = {"B", "G", "N", "N_2SS", "AC", "AC_2SS", "BG", + "HE", "HE_2SS", "N/A"}; + +static char *RA_STATUS_TBLE[] = {"INVALID", "POWER_SAVING", "SLEEP", "STANDBY", + "RUNNING", "N/A"}; + +#if 0 +static char *LT_MODE_TBLE[] = {"RSSI", "LAST_RATE", "TRACKING", "N/A"}; + +static char *SGI_UNSP_STATE_TBLE[] = {"INITIAL", "PROBING", "SUCCESS", + "FAILURE", "N/A"}; + +static char *BW_STATE_TBLE[] = {"UNCHANGED", "DOWN", "N/A"}; +#endif + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +static void connac2x_dump_tmac_info( + struct ADAPTER *prAdapter, + uint8_t *tmac_info) +{ + static const char * const pkt_ft_str[] = { + "cut_through", + "store_forward", + "cmd", + "PDA_FW_Download" + }; + + static const char * const hdr_fmt_str[] = { + "Non-80211-Frame", + "Command-Frame", + "Normal-80211-Frame", + "enhanced-80211-Frame", + }; + struct HW_MAC_CONNAC2X_TX_DESC *txd = + (struct HW_MAC_CONNAC2X_TX_DESC *)tmac_info; + + DBGLOG(HAL, INFO, "TMAC_TXD Fields:\n"); + DBGLOG(HAL, INFO, "\tTMAC_TXD_0:\n"); + + /* DW0 */ + /* TX Byte Count [15:0] */ + DBGLOG(HAL, INFO, "\t\tTxByteCnt = %d\n", + ((txd->u4DW0 & CONNAC2X_TX_DESC_TX_BYTE_COUNT_MASK) >> + CONNAC2X_TX_DESC_TX_BYTE_COUNT_OFFSET)); + + /* PKT_FT: Packet Format [24:23] */ + DBGLOG(HAL, INFO, "\t\tpkt_ft = %d(%s)\n", + ((txd->u4DW0 & CONNAC2X_TX_DESC_PACKET_FORMAT_MASK) >> + CONNAC2X_TX_DESC_PACKET_FORMAT_OFFSET), + pkt_ft_str[((txd->u4DW0 & CONNAC2X_TX_DESC_PACKET_FORMAT_MASK) >> + CONNAC2X_TX_DESC_PACKET_FORMAT_OFFSET)]); + + /* Q_IDX [31:25] */ + DBGLOG(HAL, INFO, "\t\tQueID =0x%x\n", + ((txd->u4DW0 & CONNAC2X_TX_DESC_QUEUE_INDEX_MASK) >> + CONNAC2X_TX_DESC_QUEUE_INDEX_OFFSET)); + + DBGLOG(HAL, INFO, "\tTMAC_TXD_1:\n"); + /* DW1 */ + /* WLAN Indec [9:0] */ + DBGLOG(HAL, INFO, "\t\tWlan Index = %d\n", + ((txd->u4DW1 & CONNAC2X_TX_DESC_WLAN_INDEX_MASK) >> + CONNAC2X_TX_DESC_WLAN_INDEX_OFFSET)); + + /* HF: Header Format [17:16] */ + DBGLOG(HAL, INFO, "\t\tHdrFmt = %d(%s)\n", + ((txd->u4DW1 & CONNAC2X_TX_DESC_HEADER_FORMAT_MASK) >> + CONNAC2X_TX_DESC_HEADER_FORMAT_OFFSET), + hdr_fmt_str[((txd->u4DW1 & CONNAC2X_TX_DESC_HEADER_FORMAT_MASK) >> + CONNAC2X_TX_DESC_HEADER_FORMAT_OFFSET)]); + + switch ((txd->u4DW1 & CONNAC2X_TX_DESC_HEADER_FORMAT_MASK) >> + CONNAC2X_TX_DESC_HEADER_FORMAT_OFFSET) { + case TMI_HDR_FT_NON_80211: + /* MRD [11], EOSP [12], RMVL [13], VLAN [14], ETYPE [15] */ + DBGLOG(HAL, INFO, + "\t\t\tMRD = %d, EOSP = %d, RMVL = %d, VLAN = %d, ETYP = %d\n", + (txd->u4DW1 & CONNAC2X_TX_DESC_NON_802_11_MORE_DATA) ? 1 : 0, + (txd->u4DW1 & CONNAC2X_TX_DESC_NON_802_11_EOSP) ? 1 : 0, + (txd->u4DW1 & CONNAC2X_TX_DESC_NON_802_11_REMOVE_VLAN) ? 1 : 0, + (txd->u4DW1 & CONNAC2X_TX_DESC_NON_802_11_VLAN_FIELD) ? 1 : 0, + (txd->u4DW1 & CONNAC2X_TX_DESC_NON_802_11_ETHERNET_II) ? 1 : 0); + break; + + case TMI_HDR_FT_NOR_80211: + /* HEADER_LENGTH [15:11] */ + DBGLOG(HAL, INFO, "\t\t\tHeader Len = %d(WORD)\n", + ((txd->u4DW1 & CONNAC2X_TX_DESC_NOR_802_11_HEADER_LENGTH_MASK) + >> CONNAC2X_TX_DESC_NOR_802_11_HEADER_LENGTH_OFFSET)); + break; + + case TMI_HDR_FT_ENH_80211: + /* EOSP [12], AMS [13] */ + DBGLOG(HAL, INFO, "\t\t\tEOSP = %d, AMS = %d\n", + (txd->u4DW1 & CONNAC2X_TX_DESC_ENH_802_11_EOSP) ? 1 : 0, + (txd->u4DW1 & CONNAC2X_TX_DESC_ENH_802_11_AMSDU) ? 1 : 0); + break; + } + + /* Header Padding [19:18] */ + DBGLOG(HAL, INFO, "\t\tHdrPad Mode = %d\n", + (txd->u4DW1 & CONNAC2X_TX_DESC_HEADER_PADDING_MODE) ? 1 : 0); + DBGLOG(HAL, INFO, "\t\tHdrPad Len = %d\n", + ((txd->u4DW1 & CONNAC2X_TX_DESC_HEADER_PADDING_LENGTH_MASK) >> + CONNAC2X_TX_DESC_HEADER_PADDING_LENGTH_OFFSET)); + + /* TID [22:20] */ + DBGLOG(HAL, INFO, "\t\tTID = %d\n", + ((txd->u4DW1 & CONNAC2X_TX_DESC_TID_MASK) >> + CONNAC2X_TX_DESC_TID_OFFSET)); + + /* UtxB/AMSDU_C/AMSDU [23] */ + DBGLOG(HAL, INFO, "\t\tamsdu = %d\n", + ((txd->u4DW1 & CONNAC2X_TX_DESC_TXD_UTXB_AMSDU_MASK) ? 1 : 0)); + + /* OM [29:24] */ + DBGLOG(HAL, INFO, "\t\town_mac = %d\n", + ((txd->u4DW1 & CONNAC2X_TX_DESC_OWN_MAC_MASK) >> + CONNAC2X_TX_DESC_OWN_MAC_OFFSET)); + + /* FT [31] */ + DBGLOG(HAL, INFO, "\t\tTxDFormatType = %d\n", + (txd->u4DW1 & CONNAC2X_TX_DESC_FORMAT) ? 1 : 0); + + DBGLOG(HAL, INFO, "\tTMAC_TXD_2:\n"); + /* DW2 */ + /* Subtype [3:0] */ + DBGLOG(HAL, INFO, "\t\tsub_type = %d\n", + ((txd->u4DW2 & CONNAC2X_TX_DESC_SUB_TYPE_MASK) >> + CONNAC2X_TX_DESC_SUB_TYPE_OFFSET)); + + /* Type[5:4] */ + DBGLOG(HAL, INFO, "\t\tfrm_type = %d\n", + ((txd->u4DW2 & CONNAC2X_TX_DESC_TYPE_MASK) >> + CONNAC2X_TX_DESC_TYPE_OFFSET)); + + /* NDP [6] */ + DBGLOG(HAL, INFO, "\t\tNDP = %d\n", + ((txd->u4DW2 & CONNAC2X_TX_DESC_NDP) ? 1 : 0)); + + /* NDPA [7] */ + DBGLOG(HAL, INFO, "\t\tNDPA = %d\n", + ((txd->u4DW2 & CONNAC2X_TX_DESC_NDPA) ? 1 : 0)); + + /* SD [8] */ + DBGLOG(HAL, INFO, "\t\tSounding = %d\n", + ((txd->u4DW2 & CONNAC2X_TX_DESC_SOUNDING) ? 1 : 0)); + + /* RTS [9] */ + DBGLOG(HAL, INFO, "\t\tRTS = %d\n", + ((txd->u4DW2 & CONNAC2X_TX_DESC_FORCE_RTS_CTS) ? 1 : 0)); + + /* BM [10] */ + DBGLOG(HAL, INFO, "\t\tbc_mc_pkt = %d\n", + ((txd->u4DW2 & CONNAC2X_TX_DESC_BROADCAST_MULTICAST) ? 1 : 0)); + + /* B [11] */ + DBGLOG(HAL, INFO, "\t\tBIP = %d\n", + ((txd->u4DW2 & CONNAC2X_TX_DESC_BIP_PROTECTED) ? 1 : 0)); + + /* DU [12] */ + DBGLOG(HAL, INFO, "\t\tDuration = %d\n", + ((txd->u4DW2 & CONNAC2X_TX_DESC_DURATION_FIELD_CONTROL) ? 1 : 0)); + + /* HE [13] */ + DBGLOG(HAL, INFO, "\t\tHE(HTC Exist) = %d\n", + ((txd->u4DW2 & CONNAC2X_TX_DESC_HTC_EXISTS) ? 1 : 0)); + + /* FRAG [15:14] */ + DBGLOG(HAL, INFO, "\t\tFRAG = %d\n", + ((txd->u4DW2 & CONNAC2X_TX_DESC_FRAGMENT_MASK) >> + CONNAC2X_TX_DESC_FRAGMENT_OFFSET)); + + /* Remaining Life Time [23:16]*/ + DBGLOG(HAL, INFO, "\t\tReamingLife/MaxTx time = %d\n", + ((txd->u4DW2 & CONNAC2X_TX_DESC_REMAINING_MAX_TX_TIME_MASK) >> + CONNAC2X_TX_DESC_REMAINING_MAX_TX_TIME_OFFSET)); + + /* Power Offset [29:24] */ + DBGLOG(HAL, INFO, "\t\tpwr_offset = %d\n", + ((txd->u4DW2 & CONNAC2X_TX_DESC_POWER_OFFSET_MASK) >> + CONNAC2X_TX_DESC_POWER_OFFSET_OFFSET)); + + /* FRM [30] */ + DBGLOG(HAL, INFO, "\t\tfix rate mode = %d\n", + (txd->u4DW2 & CONNAC2X_TX_DESC_FIXED_RATE_MODE) ? 1 : 0); + + /* FR[31] */ + DBGLOG(HAL, INFO, "\t\tfix rate = %d\n", + (txd->u4DW2 & CONNAC2X_TX_DESC_FIXED_RATE) ? 1 : 0); + + DBGLOG(HAL, INFO, "\tTMAC_TXD_3:\n"); + /* DW3 */ + /* NA [0] */ + DBGLOG(HAL, INFO, "\t\tNoAck = %d\n", + (txd->u4DW3 & CONNAC2X_TX_DESC_NO_ACK) ? 1 : 0); + + /* PF [1] */ + DBGLOG(HAL, INFO, "\t\tPF = %d\n", + (txd->u4DW3 & CONNAC2X_TX_DESC_PROTECTED_FRAME) ? 1 : 0); + + /* EMRD [2] */ + DBGLOG(HAL, INFO, "\t\tEMRD = %d\n", + (txd->u4DW3 & CONNAC2X_TX_DESC_EXTEND_MORE_DATA) ? 1 : 0); + + /* EEOSP [3] */ + DBGLOG(HAL, INFO, "\t\tEEOSP = %d\n", + (txd->u4DW3 & CONNAC2X_TX_DESC_EXTEND_EOSP) ? 1 : 0); + + /* DAS [4] */ + DBGLOG(HAL, INFO, "\t\tda_select = %d\n", + (txd->u4DW3 & CONNAC2X_TX_DESC_DA_SOURCE) ? 1 : 0); + + /* TM [5] */ + DBGLOG(HAL, INFO, "\t\ttm = %d\n", + (txd->u4DW3 & CONNAC2X_TX_DESC_TIMING_MEASUREMENT) ? 1 : 0); + + /* TX Count [10:6] */ + DBGLOG(HAL, INFO, "\t\ttx_cnt = %d\n", + ((txd->u4DW3 & CONNAC2X_TX_DESC_TX_COUNT_MASK) >> + CONNAC2X_TX_DESC_TX_COUNT_OFFSET)); + + /* Remaining TX Count [15:11] */ + DBGLOG(HAL, INFO, "\t\tremain_tx_cnt = %d\n", + ((txd->u4DW3 & CONNAC2X_TX_DESC_REMAINING_TX_COUNT_MASK) >> + CONNAC2X_TX_DESC_REMAINING_TX_COUNT_OFFSET)); + + /* SN [27:16] */ + DBGLOG(HAL, INFO, "\t\tsn = %d\n", + ((txd->u4DW3 & CONNAC2X_TX_DESC_SEQUENCE_NUMBER_MASK) >> + CONNAC2X_TX_DESC_SEQUENCE_NUMBER_MASK_OFFSET)); + + /* BA_DIS [28] */ + DBGLOG(HAL, INFO, "\t\tba dis = %d\n", + (txd->u4DW3 & CONNAC2X_TX_DESC_BA_DISABLE) ? 1 : 0); + + /* Power Management [29] */ + DBGLOG(HAL, INFO, "\t\tpwr_mgmt = 0x%x\n", + (txd->u4DW3 & CONNAC2X_TX_DESC_POWER_MANAGEMENT_CONTROL) ? 1 : 0); + + /* PN_VLD [30] */ + DBGLOG(HAL, INFO, "\t\tpn_vld = %d\n", + (txd->u4DW3 & CONNAC2X_TX_DESC_PN_IS_VALID) ? 1 : 0); + + /* SN_VLD [31] */ + DBGLOG(HAL, INFO, "\t\tsn_vld = %d\n", + (txd->u4DW3 & CONNAC2X_TX_DESC_SN_IS_VALID) ? 1 : 0); + + /* DW4 */ + DBGLOG(HAL, INFO, "\tTMAC_TXD_4:\n"); + + /* PN_LOW [31:0] */ + DBGLOG(HAL, INFO, "\t\tpn_low = 0x%x\n", txd->u4PN1); + + /* DW5 */ + DBGLOG(HAL, INFO, "\tTMAC_TXD_5:\n"); + + /* PN_HIGH [31:16] */ + DBGLOG(HAL, INFO, "\t\tpn_high = 0x%x\n", txd->u2PN2); + + /* PID [7:0] */ + DBGLOG(HAL, INFO, "\t\tpid = %d\n", + (txd->u2DW5_0 & CONNAC2X_TX_DESC_PACKET_ID_MASK) >> + CONNAC2X_TX_DESC_PACKET_ID_OFFSET); + + /* TXSFM [8] */ + DBGLOG(HAL, INFO, "\t\ttx_status_fmt = %d\n", + (txd->u2DW5_0 & CONNAC2X_TX_DESC_TX_STATUS_FORMAT) ? 1 : 0); + + /* TXS2M [9] */ + DBGLOG(HAL, INFO, "\t\ttx_status_2_mcu = %d\n", + (txd->u2DW5_0 & CONNAC2X_TX_DESC_TX_STATUS_TO_MCU) ? 1 : 0); + + /* TXS2H [10] */ + DBGLOG(HAL, INFO, "\t\ttx_status_2_host = %d\n", + (txd->u2DW5_0 & CONNAC2X_TX_DESC_TX_STATUS_TO_HOST) ? 1 : 0); + + /* DW6 */ + DBGLOG(HAL, INFO, "\tTMAC_TXD_6:\n"); + if (txd->u4DW2 & CONNAC2X_TX_DESC_FIXED_RATE) { + /* Fixed BandWidth mode [2:0] */ + DBGLOG(HAL, INFO, "\t\tbw = %d\n", + (txd->u4DW6 & CONNAC2X_TX_DESC_BANDWIDTH_MASK) >> + CONNAC2X_TX_DESC_BANDWIDTH_OFFSET); + + /* DYN_BW [3] */ + DBGLOG(HAL, INFO, "\t\tdyn_bw = %d\n", + (txd->u4DW6 & CONNAC2X_TX_DESC_DYNAMIC_BANDWIDTH) + ? 1 : 0); + + /* ANT_ID [7:4] */ + DBGLOG(HAL, INFO, "\t\tant_id = %d\n", + (txd->u4DW6 & CONNAC2X_TX_DESC_ANTENNA_INDEX_MASK) >> + CONNAC2X_TX_DESC_ANTENNA_INDEX_OFFSET); + + /* SPE_IDX_SEL [10] */ + DBGLOG(HAL, INFO, "\t\tspe idx sel = %d\n", + (txd->u4DW6 & CONNAC2X_TX_DESC_SPE_IDX_SEL) ? 1 : 0); + + /* LDPC [11] */ + DBGLOG(HAL, INFO, "\t\tldpc = %d\n", + (txd->u4DW6 & CONNAC2X_TX_DESC_LDPC) ? 1 : 0); + + /* HELTF Type[13:12] */ + DBGLOG(HAL, INFO, "\t\tHELTF Type = %d\n", + (txd->u4DW6 & CONNAC2X_TX_DESC_HE_LTF_MASK) >> + CONNAC2X_TX_DESC_HE_LTF_OFFSET); + + /* GI Type [15:14] */ + DBGLOG(HAL, INFO, "\t\tGI = %d\n", + (txd->u4DW6 & CONNAC2X_TX_DESC_GI_TYPE) >> + CONNAC2X_TX_DESC_GI_TYPE_OFFSET); + + /* Rate to be Fixed [29:16] */ + DBGLOG(HAL, INFO, "\t\ttx_rate = 0x%x\n", + (txd->u4DW6 & CONNAC2X_TX_DESC_FIXDE_RATE_MASK) >> + CONNAC2X_TX_DESC_FIXDE_RATE_OFFSET); + } + + /* TXEBF [30] */ + DBGLOG(HAL, INFO, "\t\ttxebf = %d\n", + (txd->u4DW6 & CONNAC2X_TX_DESC_TXE_BF) ? 1 : 0); + + /* TXIBF [31] */ + DBGLOG(HAL, INFO, "\t\ttxibf = %d\n", + (txd->u4DW6 & CONNAC2X_TX_DESC_TXI_BF) ? 1 : 0); + + /* DW7 */ + DBGLOG(HAL, INFO, "\tTMAC_TXD_7:\n"); + + /* TXD Arrival Time [9:0] */ + DBGLOG(HAL, INFO, "\t\tarrival time = %d\n", + txd->u4DW7 & CONNAC2X_TX_DESC_TXD_ARRIVAL_TIME_MASK); + + /* HW_AMSDU_CAP [10] */ + DBGLOG(HAL, INFO, "\t\thw amsdu cap = %d\n", + (txd->u4DW7 & CONNAC2X_TX_DESC_HW_AMSDU) ? 1 : 0); + + /* SPE_IDX [15:11] */ + if (txd->u4DW2 & CONNAC2X_TX_DESC_FIXED_RATE) + DBGLOG(HAL, INFO, "\t\tspe_idx = 0x%x\n", + ((txd->u4DW7 & CONNAC2X_TX_DESC_SPE_EXT_IDX_MASK) >> + CONNAC2X_TX_DESC_SPE_EXT_IDX_OFFSET)); + + /* PSE_FID [27:16], Indicate frame ID in PSE for this TXD */ + DBGLOG(HAL, INFO, "\t\tpse_fid = 0x%x\n", + ((txd->u4DW7 & CONNAC2X_TX_DESC_PSE_FID_MASK) >> + CONNAC2X_TX_DESC_PSE_FID_OFFSET)); + + /* Subtype [19:16], HW reserved, PP use only */ + DBGLOG(HAL, INFO, "\t\tpp_sub_type=%d\n", + ((txd->u4DW7 & CONNAC2X_TX_DESC7_SUB_TYPE_MASK) >> + CONNAC2X_TX_DESC7_SUB_TYPE_OFFSET)); + + /* Type [21:20], HW reserved, PP use only */ + DBGLOG(HAL, INFO, "\t\tpp_type=%d\n", + ((txd->u4DW7 & CONNAC2X_TX_DESC7_TYPE_MASK) >> + CONNAC2X_TX_DESC7_TYPE_OFFSET)); + + /* CTXD_CNT [25:23], overwritten with PSE_FID by PP */ + DBGLOG(HAL, INFO, "\t\tctxd cnt=0x%x\n", + ((txd->u4DW7 & CONNAC2X_TX_DESC_CTXD_CNT_MASK) >> + CONNAC2X_TX_DESC_CTXD_CNT_OFFSET)); + + /* CTXD [26], overwritten with PSE_FID by PP */ + DBGLOG(HAL, INFO, "\t\tctxd = %d\n", + (txd->u4DW7 & CONNAC2X_TX_DESC_CTXD) ? 1 : 0); + + /* I [28] */ + DBGLOG(HAL, INFO, "\t\ti = %d\n", + (txd->u4DW7 & CONNAC2X_TX_DESC_IP_CHKSUM_OFFLOAD) ? 1 : 0); + + /* UT [29] */ + DBGLOG(HAL, INFO, "\t\tUT = %d\n", + (txd->u4DW7 & CONNAC2X_TX_DESC_TCP_UDP_CHKSUM_OFFLOAD) ? 1 : 0); + + /* TXDLEN [31:30] */ + DBGLOG(HAL, INFO, "\t\ttxd len= %d\n", + ((txd->u4DW7 & CONNAC2X_TX_DESC_TXD_LENGTH_MASK) >> + CONNAC2X_TX_DESC_TXD_LENGTH_OFFSET)); +} + +static void connac2x_event_dump_txd_mem( + struct ADAPTER *prAdapter, + struct CMD_INFO *prCmdInfo, + uint8_t *pucEventBuf) + +{ + struct EXT_CMD_EVENT_DUMP_MEM_T *prEventDumpMem; + uint8_t data[DUMP_MEM_SIZE]; + uint32_t i = 0; + + ASSERT(prAdapter); + ASSERT(prCmdInfo); + ASSERT(pucEventBuf); + + kalMemZero(data, sizeof(data)); + prEventDumpMem = (struct EXT_CMD_EVENT_DUMP_MEM_T *)(pucEventBuf); + kalMemCopy(data, prEventDumpMem->ucData, sizeof(data)); + for (i = 0; i < DUMP_MEM_SIZE; i = i + 4) + DBGLOG(HAL, INFO, "DW%02d: 0x%02x%02x%02x%02x\n", + i / 4, + data[i + 3], + data[i + 2], + data[i + 1], + data[i] + ); + connac2x_dump_tmac_info(prAdapter, &data[0]); +} + +void connac2x_show_txd_Info( + struct ADAPTER *prAdapter, + u_int32_t fid) +{ + struct EXT_CMD_EVENT_DUMP_MEM_T CmdMemDump; + u_int32_t Addr = 0; + u_int32_t rWlanStatus = WLAN_STATUS_SUCCESS; + + DBGLOG(HAL, INFO, "inShowTXDINFO fid=%d 0x%x\n", fid, fid); + + if (fid >= UMAC_FID_FAULT) + return; + + Addr = 0xa << 28 | fid << 16; /* TXD addr: 0x{a}{fid}{0000}*/ + + kalMemSet(&CmdMemDump, 0, sizeof(struct EXT_CMD_EVENT_DUMP_MEM_T)); + + CmdMemDump.u4MemAddr = Addr; + rWlanStatus = wlanSendSetQueryExtCmd( + prAdapter, + CMD_ID_LAYER_0_EXT_MAGIC_NUM, EXT_CMD_ID_DUMP_MEM, + FALSE, /* Query Bit: True->write False->read*/ + TRUE, + FALSE, + connac2x_event_dump_txd_mem, + nicOidCmdTimeoutCommon, + sizeof(struct EXT_CMD_EVENT_DUMP_MEM_T), + (u_int8_t *)(&CmdMemDump), + NULL, + 0); +} + +static u_int8_t connac2x_wtbl_get_sgi_info( + struct fwtbl_lmac_struct *pWtbl) +{ + if (!pWtbl) + return FALSE; + + switch (pWtbl->trx_cap.wtbl_d9.field.fcap) { + case BW_20: + return ((pWtbl->trx_cap.wtbl_d2.field.he) ? + (pWtbl->trx_cap.wtbl_d7.field.g2_he) : + (pWtbl->trx_cap.wtbl_d7.field.g2)); + case BW_40: + return ((pWtbl->trx_cap.wtbl_d2.field.he) ? + (pWtbl->trx_cap.wtbl_d7.field.g4_he) : + (pWtbl->trx_cap.wtbl_d7.field.g4)); + case BW_80: + return ((pWtbl->trx_cap.wtbl_d2.field.he) ? + (pWtbl->trx_cap.wtbl_d7.field.g8_he) : + (pWtbl->trx_cap.wtbl_d7.field.g8)); + case BW_160: + return ((pWtbl->trx_cap.wtbl_d2.field.he) ? + (pWtbl->trx_cap.wtbl_d7.field.g16_he) : + (pWtbl->trx_cap.wtbl_d7.field.g16)); + default: + return FALSE; + } +} + +static u_int8_t connac2x_wtbl_get_ldpc_info( + struct fwtbl_lmac_struct *pWtbl) +{ + if (!pWtbl) + return FALSE; + + if (pWtbl->trx_cap.wtbl_d2.field.he) + return pWtbl->trx_cap.wtbl_d4.field.ldpc_he; + else if (pWtbl->trx_cap.wtbl_d2.field.vht) + return pWtbl->trx_cap.wtbl_d4.field.ldpc_vht; + else + return pWtbl->trx_cap.wtbl_d4.field.ldpc_ht; +} + +static int32_t connac2x_wtbl_rate_to_string( + char *pcCommand, + int i4TotalLen, + uint8_t TxRx, + struct fwtbl_lmac_struct *pWtbl) +{ + uint8_t i, txmode, rate, stbc; + uint8_t nss, gi; + int32_t i4BytesWritten = 0; + uint16_t arTxRate[8]; + + arTxRate[0] = pWtbl->auto_rate_tb.wtbl_d10.field.rate1; + arTxRate[1] = pWtbl->auto_rate_tb.wtbl_d10.field.rate2; + arTxRate[2] = pWtbl->auto_rate_tb.wtbl_d11.field.rate3; + arTxRate[3] = pWtbl->auto_rate_tb.wtbl_d11.field.rate4; + arTxRate[4] = pWtbl->auto_rate_tb.wtbl_d12.field.rate5; + arTxRate[5] = pWtbl->auto_rate_tb.wtbl_d12.field.rate6; + arTxRate[6] = pWtbl->auto_rate_tb.wtbl_d13.field.rate7; + arTxRate[7] = pWtbl->auto_rate_tb.wtbl_d13.field.rate8; + for (i = 0; i < AUTO_RATE_NUM; i++) { + + txmode = CONNAC2X_HW_TX_RATE_TO_MODE(arTxRate[i]); + if (txmode >= ENUM_TX_MODE_NUM) + txmode = ENUM_TX_MODE_NUM - 1; + rate = HW_TX_RATE_TO_MCS(arTxRate[i]); + nss = CONNAC2X_HW_TX_RATE_TO_NSS(arTxRate[i]) + 1; + stbc = CONNAC2X_HW_TX_RATE_TO_STBC(arTxRate[i]); + gi = connac2x_wtbl_get_sgi_info(pWtbl); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tRateIdx[%d] ", i); + + if (pWtbl->trx_cap.wtbl_d9.field.rate_idx == i) { + if (TxRx == 0) + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", "[Last RX Rate] "); + else + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", "[Last TX Rate] "); + } else + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", " "); + + if (txmode == TX_RATE_MODE_CCK) + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s, ", + rate < 4 ? HW_TX_RATE_CCK_STR[rate] : + HW_TX_RATE_CCK_STR[4]); + else if (txmode == TX_RATE_MODE_OFDM) + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s, ", + nicHwRateOfdmStr(rate)); + else if ((txmode == TX_RATE_MODE_HTMIX) || + (txmode == TX_RATE_MODE_HTGF)) + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "MCS%d, ", rate); + else { + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s%d_MCS%d, ", stbc ? "NSTS" : "NSS", + nss, rate); + } + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s, ", + (pWtbl->trx_cap.wtbl_d9.field.fcap < 4) ? + HW_TX_RATE_BW[pWtbl->trx_cap.wtbl_d9.field.fcap] : + HW_TX_RATE_BW[4]); + + if (txmode == TX_RATE_MODE_CCK) + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s, ", + rate < 4 ? "LP" : "SP"); + else if (txmode == TX_RATE_MODE_OFDM) + ; + else if (txmode >= TX_RATE_MODE_HTMIX + && txmode <= TX_RATE_MODE_PLR) + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s, ", + gi == 0 ? "LGI" : "SGI"); + else + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s, ", gi == 0 ? "SGI" : + (gi == 1 ? "MGI" : "LGI")); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s%s %s\n", + RATE_V2_HW_TX_MODE_STR[txmode], stbc ? "STBC" : " ", + connac2x_wtbl_get_ldpc_info(pWtbl) == 0 ? "BCC" : "LDPC"); + } + + return i4BytesWritten; +} + +static int32_t connac2x_dump_helper_wtbl_info( + struct ADAPTER *prAdapter, + char *pcCommand, + int i4TotalLen, + struct fwtbl_lmac_struct *pWtbl, + uint32_t u4Index) +{ + int32_t i4BytesWritten = 0; + uint8_t aucPA[MAC_ADDR_LEN]; + uint8_t u1BeamChgDw5 = 0, u1Dw3NewContent = 1; + uint8_t u1Dw5SR_R_Old = 0, u1Dw9NewContent = 1; + uint8_t u1Dw30Rssi = 1; + + if (!pcCommand) { + DBGLOG(HAL, ERROR, "%s: pcCommand is NULL.\n", + __func__); + return i4BytesWritten; + } + + if ((WTBL_VER == 1) && (wlanGetEcoVersion(prAdapter) < ECO_VER_2)) { + u1BeamChgDw5 = 1; + u1Dw3NewContent = 0; + u1Dw5SR_R_Old = 1; + u1Dw9NewContent = 0; + u1Dw30Rssi = 0; + } else if ((WTBL_VER == 2) && + (wlanGetEcoVersion(prAdapter) < ECO_VER_2)) { + u1Dw3NewContent = 0; + u1Dw30Rssi = 0; + } + + aucPA[0] = + pWtbl->peer_basic_info.wtbl_d1.field.addr_0 & 0xff; + aucPA[1] = + ((pWtbl->peer_basic_info.wtbl_d1.field.addr_0 & + 0xff00) >> 8); + aucPA[2] = + ((pWtbl->peer_basic_info.wtbl_d1.field.addr_0 & + 0xff0000) >> 16); + aucPA[3] = + ((pWtbl->peer_basic_info.wtbl_d1.field.addr_0 & + 0xff000000) >> 24); + aucPA[4] = + pWtbl->peer_basic_info.wtbl_d0.field.addr_4 & 0xff; + aucPA[5] = + pWtbl->peer_basic_info.wtbl_d0.field.addr_5 & 0xff; + + i4BytesWritten = kalSnprintf(pcCommand, i4TotalLen, "%s", + "\n\nwtbl:\n"); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "Dump WTBL info of WLAN_IDX = %d\n", + u4Index); + /* DW0~DW1 */ + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "\tADDR="MACSTR"\n", + MAC2STR(aucPA)); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tKID/RCID/RV/WPI:%d/%d/%d/%d\n", + pWtbl->peer_basic_info.wtbl_d0.field.muar_idx, + pWtbl->peer_basic_info.wtbl_d0.field.fd, + pWtbl->peer_basic_info.wtbl_d0.field.td, + pWtbl->peer_basic_info.wtbl_d0.field.rc_a1, + pWtbl->peer_basic_info.wtbl_d0.field.rc_a2); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tKID:%d/RCID:%d/RKV:NA/RV:%d/IKV:NA/WPI_FLAG:%d\n", + pWtbl->peer_basic_info.wtbl_d0.field.kid, + pWtbl->peer_basic_info.wtbl_d0.field.rc_id, + pWtbl->peer_basic_info.wtbl_d0.field.rv, + pWtbl->peer_basic_info.wtbl_d0.field.wpi_flg); + /* DW2 */ + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tAID12/GID_SU/SPP_EN/WPI_EVEN/AAD_OM:%d/%d/%d/%d/%d\n", + pWtbl->trx_cap.wtbl_d2.field.aid12, + pWtbl->trx_cap.wtbl_d2.field.gid_su, + pWtbl->trx_cap.wtbl_d2.field.spp_en, + pWtbl->trx_cap.wtbl_d2.field.wpi_even, + pWtbl->trx_cap.wtbl_d2.field.aad_om); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tCipher/IGTK:%d/%d\n", + pWtbl->trx_cap.wtbl_d2.field.cipher_suit, + pWtbl->trx_cap.wtbl_d2.field.cipher_suit_igtk); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tSW/UL/TXPS/QoS/MESH:%d/%d/%d/%d/%d\n", + pWtbl->trx_cap.wtbl_d2.field.sw, + pWtbl->trx_cap.wtbl_d2.field.ul, + pWtbl->trx_cap.wtbl_d2.field.tx_ps, + pWtbl->trx_cap.wtbl_d2.field.qos, + pWtbl->trx_cap.wtbl_d2.field.mesh); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tHT/VHT/HE/LDPC[HT/VHT/HE]:%d/%d/%d/%d/%d/%d\n", + pWtbl->trx_cap.wtbl_d2.field.ht, + pWtbl->trx_cap.wtbl_d2.field.vht, + pWtbl->trx_cap.wtbl_d2.field.he, + pWtbl->trx_cap.wtbl_d4.field.ldpc_ht, + pWtbl->trx_cap.wtbl_d4.field.ldpc_vht, + pWtbl->trx_cap.wtbl_d4.field.ldpc_he); + /* DW3 */ + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tWMMQ/RXD_DUP_M/VLAN2ETH/BEAM_CHG:%d/%d/%d/%d\n", + pWtbl->trx_cap.wtbl_d3.field.wmm_q, + pWtbl->trx_cap.wtbl_d3.field.rxd_dup_mode, + pWtbl->trx_cap.wtbl_d3.field.vlan_2e_th, + (u1BeamChgDw5 > 0) ? (pWtbl->trx_cap.wtbl_d5.field.beam_chg) : + (pWtbl->trx_cap.wtbl_d3.field_v2.beam_chg)); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tPFMU_IDX/RIBF/TBF[HT/VHT/HE]:%d/%d/%d/%d/%d\n", + pWtbl->trx_cap.wtbl_d3.field.pfmu_index, + pWtbl->trx_cap.wtbl_d3.field.ribf, + pWtbl->trx_cap.wtbl_d3.field.tebf, + pWtbl->trx_cap.wtbl_d3.field.tebf_vht, + pWtbl->trx_cap.wtbl_d3.field.tebf_he); + + if (u1Dw3NewContent > 0) + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tBA_M/ULPF_IDX/ULPF/IGN_FBK:%d/%d/%d/%d\n", + pWtbl->trx_cap.wtbl_d3.field_v2.ba_mode, + pWtbl->trx_cap.wtbl_d3.field_v2.ulpf_index, + pWtbl->trx_cap.wtbl_d3.field_v2.ulpf, + pWtbl->trx_cap.wtbl_d3.field_v2.ign_fbk); + /* DW4 */ + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tANT_ID0/1/2/3/4/5/6/7:%d/%d/%d/%d/%d/%d/%d/%d\n", + pWtbl->trx_cap.wtbl_d4.field.ant_id_sts0, + pWtbl->trx_cap.wtbl_d4.field.ant_id_sts1, + pWtbl->trx_cap.wtbl_d4.field.ant_id_sts2, + pWtbl->trx_cap.wtbl_d4.field.ant_id_sts3, + pWtbl->trx_cap.wtbl_d4.field.ant_id_sts4, + pWtbl->trx_cap.wtbl_d4.field.ant_id_sts5, + pWtbl->trx_cap.wtbl_d4.field.ant_id_sts6, + pWtbl->trx_cap.wtbl_d4.field.ant_id_sts7); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tCASCAD/DIS_RHTR/ALL_ACK/DROP/ACK_EN:%d/%d/%d/%d/%d\n", + pWtbl->trx_cap.wtbl_d4.field.cascad, + pWtbl->trx_cap.wtbl_d4.field.dis_rhtr, + pWtbl->trx_cap.wtbl_d4.field.all_ack, + pWtbl->trx_cap.wtbl_d4.field.drop, + pWtbl->trx_cap.wtbl_d4.field.ack_en); + /* DW5 */ + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tAF/AFHE/RTS/SMPS/DYNBW/MMSS:%d/%d/%d/%d/%d/%d\n", + pWtbl->trx_cap.wtbl_d5.field.af, + pWtbl->trx_cap.wtbl_d5.field.af_he, + pWtbl->trx_cap.wtbl_d5.field.rts, + pWtbl->trx_cap.wtbl_d5.field.smps, + pWtbl->trx_cap.wtbl_d5.field.dyn_bw, + pWtbl->trx_cap.wtbl_d5.field.mmss); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tUSR/SR_R/SR_A/MPDU_SZ/PE:%d/%d/%d/%d/%d\n", + pWtbl->trx_cap.wtbl_d5.field.usr, + (u1Dw5SR_R_Old > 0) ? (pWtbl->trx_cap.wtbl_d5.field.sr_r) : + (pWtbl->trx_cap.wtbl_d5.field_v2.sr_r), + pWtbl->trx_cap.wtbl_d5.field.sr_abort, + pWtbl->trx_cap.wtbl_d5.field.mpdu_size, + pWtbl->trx_cap.wtbl_d5.field.pe); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tTXPWR_OFST/DOPPL/TXOP_PS_CAP:%d/%d/%d\n", + pWtbl->trx_cap.wtbl_d5.field.tx_power_offset, + pWtbl->trx_cap.wtbl_d5.field.doppl, + pWtbl->trx_cap.wtbl_d5.field.txop_ps_cap); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tDU_I_PSM/I_PSM/PSM/SKIP_TX:%d/%d/%d/%d\n", + pWtbl->trx_cap.wtbl_d5.field.du_i_psm, + pWtbl->trx_cap.wtbl_d5.field.i_psm, + pWtbl->trx_cap.wtbl_d5.field.psm, + pWtbl->trx_cap.wtbl_d5.field.skip_tx); + /* DW6 */ + if (pWtbl->trx_cap.wtbl_d2.field.qos) + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tBaWinSize TID0/1/2/3/4/5/6/7:%d/%d/%d/%d/%d/%d/%d/%d\n", + (uint32_t) + (pWtbl->trx_cap.wtbl_d6.field.ba_win_size_tid0), + (uint32_t) + (pWtbl->trx_cap.wtbl_d6.field.ba_win_size_tid1), + (uint32_t) + (pWtbl->trx_cap.wtbl_d6.field.ba_win_size_tid2), + (uint32_t) + (pWtbl->trx_cap.wtbl_d6.field.ba_win_size_tid3), + (uint32_t) + (pWtbl->trx_cap.wtbl_d6.field.ba_win_size_tid4), + (uint32_t) + (pWtbl->trx_cap.wtbl_d6.field.ba_win_size_tid5), + (uint32_t) + (pWtbl->trx_cap.wtbl_d6.field.ba_win_size_tid6), + (uint32_t) + (pWtbl->trx_cap.wtbl_d6.field.ba_win_size_tid7)); + /* DW7 */ + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tCBRN/DBNSS_EN/BAFEN/RDGBA/R:%d/%d/%d/%d/%d\n", + pWtbl->trx_cap.wtbl_d7.field.cb_rn, + pWtbl->trx_cap.wtbl_d7.field.dbnss_en, + pWtbl->trx_cap.wtbl_d7.field.bafen, + pWtbl->trx_cap.wtbl_d7.field.rdg_ba, + pWtbl->trx_cap.wtbl_d7.field.r); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tG2/G4/G8/G16/SPE:%d/%d/%d/%d/%d\n", + pWtbl->trx_cap.wtbl_d7.field.g2, + pWtbl->trx_cap.wtbl_d7.field.g4, + pWtbl->trx_cap.wtbl_d7.field.g8, + pWtbl->trx_cap.wtbl_d7.field.g16, + pWtbl->trx_cap.wtbl_d7.field.spe_idx); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tHE[G2/G4/G8/G16]:%d/%d/%d/%d\n", + pWtbl->trx_cap.wtbl_d7.field.g2_he, + pWtbl->trx_cap.wtbl_d7.field.g4_he, + pWtbl->trx_cap.wtbl_d7.field.g8_he, + pWtbl->trx_cap.wtbl_d7.field.g16_he); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tLTF[G2/G4/G8/G16]:%d/%d/%d/%d\n", + pWtbl->trx_cap.wtbl_d7.field.g2_ltf, + pWtbl->trx_cap.wtbl_d7.field.g4_ltf, + pWtbl->trx_cap.wtbl_d7.field.g8_ltf, + pWtbl->trx_cap.wtbl_d7.field.g16_ltf); + /* DW8 */ + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tCHK_PER/P_AID:%d/%d\n", + pWtbl->trx_cap.wtbl_d8.field.chk_per, + pWtbl->trx_cap.wtbl_d8.field.partial_aid); + /* DW9 */ + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tFCAP/PRITX[DCM/ER160/ERSU]:%d/%d/%d/%d\n", + pWtbl->trx_cap.wtbl_d9.field.fcap, + pWtbl->trx_cap.wtbl_d9.field.pritx_dcm, + pWtbl->trx_cap.wtbl_d9.field.pritx_er160, + pWtbl->trx_cap.wtbl_d9.field.pritx_ersu); + + if (u1Dw9NewContent > 0) + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tPRITX[SW_M/PLR]:%d/%d\n", + pWtbl->trx_cap.wtbl_d9.field_v2.pritx_sw_mode, + pWtbl->trx_cap.wtbl_d9.field_v2.pritx_plr); + + if (u1Dw30Rssi > 0) + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tRSSI = %d %d %d %d\n", + RCPI_TO_dBm(pWtbl->rx_stat.wtbl_d30.field_v2.resp_rcpi_0), + RCPI_TO_dBm(pWtbl->rx_stat.wtbl_d30.field_v2.resp_rcpi_1), + RCPI_TO_dBm(pWtbl->rx_stat.wtbl_d30.field_v2.resp_rcpi_2), + RCPI_TO_dBm(pWtbl->rx_stat.wtbl_d30.field_v2.resp_rcpi_3)); + else + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tRSSI = %d %d %d %d\n", + RCPI_TO_dBm(pWtbl->rx_stat.wtbl_d29.field.resp_rcpi_0), + RCPI_TO_dBm(pWtbl->rx_stat.wtbl_d29.field.resp_rcpi_1), + RCPI_TO_dBm(pWtbl->rx_stat.wtbl_d29.field.resp_rcpi_2), + RCPI_TO_dBm(pWtbl->rx_stat.wtbl_d29.field.resp_rcpi_3)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s", "\tRate Info\n"); + + i4BytesWritten += connac2x_wtbl_rate_to_string( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, 1, pWtbl); + + return i4BytesWritten; +} + +static void connac2x_print_wtbl_info( + struct ADAPTER *prAdapter, + int32_t idx) +{ + struct mt66xx_chip_info *prChipInfo; + int32_t start_idx, end_idx; + uint32_t wtbl_offset, addr; + uint32_t u4Value = 0; + uint32_t wtbl_lmac_baseaddr; + unsigned char *wtbl_raw_dw = NULL; + struct fwtbl_lmac_struct *pwtbl; + unsigned char myaddr[6]; + uint16_t txrate[8], rate_idx, txmode, mcs, nss, stbc; + uint8_t u1BeamChgDw5 = 0, u1Dw3NewContent = 1; + uint8_t u1WtblSize = 0; + + prChipInfo = prAdapter->chip_info; + if ((idx >= 0) && (idx < prAdapter->ucWtblEntryNum)) + start_idx = end_idx = idx; + else { + start_idx = 0; + end_idx = prAdapter->ucWtblEntryNum - 1; + } + + if ((WTBL_VER == 1) && (wlanGetEcoVersion(prAdapter) < ECO_VER_2)) { + u1WtblSize = sizeof(struct fwtbl_lmac_struct); + u1BeamChgDw5 = 1; + u1Dw3NewContent = 0; + } else if ((WTBL_VER == 2) && + (wlanGetEcoVersion(prAdapter) < ECO_VER_2)) { + u1WtblSize = sizeof(struct fwtbl_lmac_struct); + u1Dw3NewContent = 0; + } else { + u1WtblSize = + sizeof(struct fwtbl_lmac_struct) - sizeof(uint32_t); + } + + for (idx = start_idx; idx <= end_idx; idx++) { + /* LMAC */ + CONNAC2X_LWTBL_CONFIG(prAdapter, + prChipInfo->u4LmacWtblDUAddr, idx); + wtbl_lmac_baseaddr = CONNAC2X_LWTBL_IDX2BASE( + prChipInfo->u4LmacWtblDUAddr, idx, 0); + HAL_MCR_RD(prAdapter, prChipInfo->u4LmacWtblDUAddr, + &u4Value); + + LOG_FUNC("\n\tLMAC WTBL Addr: group: 0x%x=0x%x addr: 0x%x\n", + prChipInfo->u4LmacWtblDUAddr, + u4Value, + wtbl_lmac_baseaddr); + + wtbl_raw_dw = (unsigned char *)kalMemAlloc( + sizeof(struct fwtbl_lmac_struct), VIR_MEM_TYPE); + if (!wtbl_raw_dw) { + DBGLOG(REQ, ERROR, "WTBL PRN : Memory alloc failed\n"); + return; + } + /* Read LWTBL Entries */ + for (wtbl_offset = 0; wtbl_offset < + sizeof(struct fwtbl_lmac_struct); + wtbl_offset += 4) { + addr = wtbl_lmac_baseaddr + wtbl_offset; + HAL_MCR_RD(prAdapter, addr, + &u4Value); + kalMemCopy( + (uint32_t *)&wtbl_raw_dw[wtbl_offset], + &u4Value, sizeof(uint32_t)); + } + pwtbl = (struct fwtbl_lmac_struct *)wtbl_raw_dw; + kalMemMove(&myaddr[0], + (unsigned char *)&pwtbl->peer_basic_info, 4); + myaddr[0] = + pwtbl->peer_basic_info.wtbl_d1.field.addr_0 & + 0xff; + myaddr[1] = + ((pwtbl->peer_basic_info.wtbl_d1.field.addr_0 & + 0xff00) >> + 8); + myaddr[2] = + ((pwtbl->peer_basic_info.wtbl_d1.field.addr_0 & + 0xff0000) >> + 16); + myaddr[3] = + ((pwtbl->peer_basic_info.wtbl_d1.field.addr_0 & + 0xff000000) >> + 24); + myaddr[4] = + pwtbl->peer_basic_info.wtbl_d0.field.addr_4 & + 0xff; + myaddr[5] = + pwtbl->peer_basic_info.wtbl_d0.field.addr_5 & + 0xff; + LOG_FUNC( + "\n\tLWTBL DW 0,1:\n" + "\tAddr: %x:%x:%x:%x:%x:%x(D0[B0~15], D1[B0~31])\n" + "\tMUAR_Idx(D0[B16~21]):%d\n" + "\tRCA1:%d\n" + "\tKID:%d\n" + "\tRCID:%d\n" + "\tFROM_DS:%d\n" + "\tTO_DS:%d\n" + "\tRV:%d\n" + "\tRCA2:%d\n" + "\tWPI_FLAG:%d\n", + myaddr[0], myaddr[1], myaddr[2], myaddr[3], + myaddr[4], myaddr[5], + pwtbl->peer_basic_info.wtbl_d0.field.muar_idx, + pwtbl->peer_basic_info.wtbl_d0.field.rc_a1, + pwtbl->peer_basic_info.wtbl_d0.field.kid, + pwtbl->peer_basic_info.wtbl_d0.field.rc_id, + pwtbl->peer_basic_info.wtbl_d0.field.fd, + pwtbl->peer_basic_info.wtbl_d0.field.td, + pwtbl->peer_basic_info.wtbl_d0.field.rv, + pwtbl->peer_basic_info.wtbl_d0.field.rc_a2, + pwtbl->peer_basic_info.wtbl_d0.field.wpi_flg); + + LOG_FUNC( + "\n\tLWTBL DW 2\n" + "\tAID12:%d\n" + "\tGID_SU:%d\n" + "\tSPP_EN:%d\n" + "\tWPI_EVEN:%d\n" + "\tAAD_OM:%d\n" + "\tCIPHER_SUITE:%d\n" + "\tCIPHER_SUITE_IGTK:%d\n" + "\tRSVD:%d\n" + "\tSW:%d\n" + "\tUL:%d\n" + "\tPOWER_SAVE:%d\n" + "\tQOS:%d\n" + "\tHT:%d\n" + "\tVHT:%d\n" + "\tHE:%d\n" + "\tMESH:%d\n", + pwtbl->trx_cap.wtbl_d2.field.aid12, + pwtbl->trx_cap.wtbl_d2.field.gid_su, + pwtbl->trx_cap.wtbl_d2.field.spp_en, + pwtbl->trx_cap.wtbl_d2.field.wpi_even, + pwtbl->trx_cap.wtbl_d2.field.aad_om, + pwtbl->trx_cap.wtbl_d2.field.cipher_suit, + pwtbl->trx_cap.wtbl_d2.field.cipher_suit_igtk, + pwtbl->trx_cap.wtbl_d2.field.rsvd, + pwtbl->trx_cap.wtbl_d2.field.sw, + pwtbl->trx_cap.wtbl_d2.field.ul, + pwtbl->trx_cap.wtbl_d2.field.tx_ps, + pwtbl->trx_cap.wtbl_d2.field.qos, + pwtbl->trx_cap.wtbl_d2.field.ht, + pwtbl->trx_cap.wtbl_d2.field.vht, + pwtbl->trx_cap.wtbl_d2.field.he, + pwtbl->trx_cap.wtbl_d2.field.mesh); + + if (u1Dw3NewContent > 0) + LOG_FUNC( + "\n\tLWTBL DW 3\n" + "\tWMM_Q:%d\n" + "\tRXD_DUP_MODE:%d\n" + "\tVLAN2ETH:%d\n" + "\tBEAM_CHG:%d\n" + "\tBA_MODE:%d\n" + "\tPFMU_IDX:%d\n" + "\tULPF_IDX:%d\n" + "\tRIBF:%d\n" + "\tULPF:%d\n" + "\tIGN_FBK:%d\n" + "\tTEBF:%d\n" + "\tTEBF_VHT:%d\n" + "\tTEBF_HE:%d\n", + pwtbl->trx_cap.wtbl_d3.field.wmm_q, + pwtbl->trx_cap.wtbl_d3.field.rxd_dup_mode, + pwtbl->trx_cap.wtbl_d3.field.vlan_2e_th, + pwtbl->trx_cap.wtbl_d3.field_v2.beam_chg, + pwtbl->trx_cap.wtbl_d3.field_v2.ba_mode, + pwtbl->trx_cap.wtbl_d3.field.pfmu_index, + pwtbl->trx_cap.wtbl_d3.field_v2.ulpf_index, + pwtbl->trx_cap.wtbl_d3.field.ribf, + pwtbl->trx_cap.wtbl_d3.field_v2.ulpf, + pwtbl->trx_cap.wtbl_d3.field_v2.ign_fbk, + pwtbl->trx_cap.wtbl_d3.field.tebf, + pwtbl->trx_cap.wtbl_d3.field.tebf_vht, + pwtbl->trx_cap.wtbl_d3.field.tebf_he); + else { + if (u1BeamChgDw5 > 0) + LOG_FUNC( + "\n\tLWTBL DW 3\n" + "\tWMM_Q:%d\n" + "\tRXD_DUP_MODE:%d\n" + "\tVLAN2ETH:%d\n" + "\tPFMU_IDX:%d\n" + "\tRIBF:%d\n" + "\tTEBF:%d\n" + "\tTEBF_VHT:%d\n" + "\tTEBF_HE:%d\n", + pwtbl->trx_cap.wtbl_d3.field.wmm_q, + pwtbl->trx_cap.wtbl_d3.field.rxd_dup_mode, + pwtbl->trx_cap.wtbl_d3.field.vlan_2e_th, + pwtbl->trx_cap.wtbl_d3.field.pfmu_index, + pwtbl->trx_cap.wtbl_d3.field.ribf, + pwtbl->trx_cap.wtbl_d3.field.tebf, + pwtbl->trx_cap.wtbl_d3.field.tebf_vht, + pwtbl->trx_cap.wtbl_d3.field.tebf_he); + else + LOG_FUNC( + "\n\tLWTBL DW 3\n" + "\tWMM_Q:%d\n" + "\tRXD_DUP_MODE:%d\n" + "\tVLAN2ETH:%d\n" + "\tBEAM_CHG:%d\n" + "\tPFMU_IDX:%d\n" + "\tRIBF:%d\n" + "\tTEBF:%d\n" + "\tTEBF_VHT:%d\n" + "\tTEBF_HE:%d\n", + pwtbl->trx_cap.wtbl_d3.field.wmm_q, + pwtbl->trx_cap.wtbl_d3.field.rxd_dup_mode, + pwtbl->trx_cap.wtbl_d3.field.vlan_2e_th, + pwtbl->trx_cap.wtbl_d3.field_v2.beam_chg, + pwtbl->trx_cap.wtbl_d3.field.pfmu_index, + pwtbl->trx_cap.wtbl_d3.field.ribf, + pwtbl->trx_cap.wtbl_d3.field.tebf, + pwtbl->trx_cap.wtbl_d3.field.tebf_vht, + pwtbl->trx_cap.wtbl_d3.field.tebf_he); + } + + LOG_FUNC( + "\n\tLWTBL DW 4\n" + "\tANT_ID_STS0:%d\n" + "\tANT_ID_STS1:%d\n" + "\tANT_ID_STS2:%d\n" + "\tANT_ID_STS3:%d\n" + "\tANT_ID_STS4:%d\n" + "\tANT_ID_STS5:%d\n" + "\tANT_ID_STS6:%d\n" + "\tANT_ID_STS7:%d\n" + "\tCASCAD:%d\n" + "\tLDPC_HT:%d\n" + "\tLDPC_VHT:%d\n" + "\tLDPC_HE:%d\n" + "\tDIS_RTHR:%d\n" + "\tALL_ACK:%d\n" + "\tDROP:%d\n" + "\tACK_EN:%d\n", + pwtbl->trx_cap.wtbl_d4.field.ant_id_sts0, + pwtbl->trx_cap.wtbl_d4.field.ant_id_sts1, + pwtbl->trx_cap.wtbl_d4.field.ant_id_sts2, + pwtbl->trx_cap.wtbl_d4.field.ant_id_sts3, + pwtbl->trx_cap.wtbl_d4.field.ant_id_sts4, + pwtbl->trx_cap.wtbl_d4.field.ant_id_sts5, + pwtbl->trx_cap.wtbl_d4.field.ant_id_sts6, + pwtbl->trx_cap.wtbl_d4.field.ant_id_sts7, + pwtbl->trx_cap.wtbl_d4.field.cascad, + pwtbl->trx_cap.wtbl_d4.field.ldpc_ht, + pwtbl->trx_cap.wtbl_d4.field.ldpc_vht, + pwtbl->trx_cap.wtbl_d4.field.ldpc_he, + pwtbl->trx_cap.wtbl_d4.field.dis_rhtr, + pwtbl->trx_cap.wtbl_d4.field.all_ack, + pwtbl->trx_cap.wtbl_d4.field.drop, + pwtbl->trx_cap.wtbl_d4.field.ack_en); + + if (u1BeamChgDw5 > 0) + LOG_FUNC( + "\n\tLWTBL DW 5\n" + "\tAF:%d\n" + "\tAF_HE:%d\n" + "\tRTS:%d\n" + "\tSMPS:%d\n" + "\tDYN_BW:%d\n" + "\tMMSS:%d\n" + "\tUSR:%d\n" + "\tSR_R:%d\n" + "\tBEAM_CHG:%d\n" + "\tSR_ABORT:%d\n" + "\tTX_POWER_OFFSET:%d\n" + "\tMPDU_SIZE:%d\n" + "\tPE:%d\n" + "\tDOPPL:%d\n" + "\tTXOP_PS_CAP:%d\n" + "\tDONOT_UPDATE_I_PSM:%d\n" + "\tI_PSM:%d\n" + "\tPSM:%d\n" + "\tSKIP_TX:%d\n", + pwtbl->trx_cap.wtbl_d5.field.af, + pwtbl->trx_cap.wtbl_d5.field.af_he, + pwtbl->trx_cap.wtbl_d5.field.rts, + pwtbl->trx_cap.wtbl_d5.field.smps, + pwtbl->trx_cap.wtbl_d5.field.dyn_bw, + pwtbl->trx_cap.wtbl_d5.field.mmss, + pwtbl->trx_cap.wtbl_d5.field.usr, + pwtbl->trx_cap.wtbl_d5.field.sr_r, + pwtbl->trx_cap.wtbl_d5.field.beam_chg, + pwtbl->trx_cap.wtbl_d5.field.sr_abort, + pwtbl->trx_cap.wtbl_d5.field.tx_power_offset, + pwtbl->trx_cap.wtbl_d5.field.mpdu_size, + pwtbl->trx_cap.wtbl_d5.field.pe, + pwtbl->trx_cap.wtbl_d5.field.doppl, + pwtbl->trx_cap.wtbl_d5.field.txop_ps_cap, + pwtbl->trx_cap.wtbl_d5.field.du_i_psm, + pwtbl->trx_cap.wtbl_d5.field.i_psm, + pwtbl->trx_cap.wtbl_d5.field.psm, + pwtbl->trx_cap.wtbl_d5.field.skip_tx); + else + LOG_FUNC( + "\n\tLWTBL DW 5\n" + "\tAF:%d\n" + "\tAF_HE:%d\n" + "\tRTS:%d\n" + "\tSMPS:%d\n" + "\tDYN_BW:%d\n" + "\tMMSS:%d\n" + "\tUSR:%d\n" + "\tSR_R:%d\n" + "\tSR_ABORT:%d\n" + "\tTX_POWER_OFFSET:%d\n" + "\tMPDU_SIZE:%d\n" + "\tPE:%d\n" + "\tDOPPL:%d\n" + "\tTXOP_PS_CAP:%d\n" + "\tDONOT_UPDATE_I_PSM:%d\n" + "\tI_PSM:%d\n" + "\tPSM:%d\n" + "\tSKIP_TX:%d\n", + pwtbl->trx_cap.wtbl_d5.field.af, + pwtbl->trx_cap.wtbl_d5.field.af_he, + pwtbl->trx_cap.wtbl_d5.field.rts, + pwtbl->trx_cap.wtbl_d5.field.smps, + pwtbl->trx_cap.wtbl_d5.field.dyn_bw, + pwtbl->trx_cap.wtbl_d5.field.mmss, + pwtbl->trx_cap.wtbl_d5.field.usr, + pwtbl->trx_cap.wtbl_d5.field_v2.sr_r, + pwtbl->trx_cap.wtbl_d5.field.sr_abort, + pwtbl->trx_cap.wtbl_d5.field.tx_power_offset, + pwtbl->trx_cap.wtbl_d5.field.mpdu_size, + pwtbl->trx_cap.wtbl_d5.field.pe, + pwtbl->trx_cap.wtbl_d5.field.doppl, + pwtbl->trx_cap.wtbl_d5.field.txop_ps_cap, + pwtbl->trx_cap.wtbl_d5.field.du_i_psm, + pwtbl->trx_cap.wtbl_d5.field.i_psm, + pwtbl->trx_cap.wtbl_d5.field.psm, + pwtbl->trx_cap.wtbl_d5.field.skip_tx); + + LOG_FUNC( + "\n\tLWTBL DW 6\n" + "\tTID0 BA_WIN_SIZE:%d\n" + "\tTID1 BA_WIN_SIZE:%d\n" + "\tTID2 BA_WIN_SIZE:%d\n" + "\tTID3 BA_WIN_SIZE:%d\n" + "\tTID4 BA_WIN_SIZE:%d\n" + "\tTID5 BA_WIN_SIZE:%d\n" + "\tTID6 BA_WIN_SIZE:%d\n" + "\tTID7 BA_WIN_SIZE:%d\n", + pwtbl->trx_cap.wtbl_d6.field.ba_win_size_tid0, + pwtbl->trx_cap.wtbl_d6.field.ba_win_size_tid1, + pwtbl->trx_cap.wtbl_d6.field.ba_win_size_tid2, + pwtbl->trx_cap.wtbl_d6.field.ba_win_size_tid3, + pwtbl->trx_cap.wtbl_d6.field.ba_win_size_tid4, + pwtbl->trx_cap.wtbl_d6.field.ba_win_size_tid5, + pwtbl->trx_cap.wtbl_d6.field.ba_win_size_tid6, + pwtbl->trx_cap.wtbl_d6.field.ba_win_size_tid7); + + + LOG_FUNC( + "\n\tLWTBL DW 7\n" + "\tCBRN:%d\n" + "\tDBNSS_EN:%d\n" + "\tBAF_EN:%d\n" + "\tRDGBA:%d\n" + "\tR:%d\n" + "\tSPE_IDX:%d\n" + "\tG2:%d\n" + "\tG4:%d\n" + "\tG8:%d\n" + "\tG16:%d\n" + "\tG2_LTF:%d\n" + "\tG4_LTF:%d\n" + "\tG8_LTF:%d\n" + "\tG16_LTF:%d\n" + "\tG2_HE:%d\n" + "\tG4_HE:%d\n" + "\tG8_HE:%d\n" + "\tG16_HE:%d\n", + pwtbl->trx_cap.wtbl_d7.field.cb_rn, + pwtbl->trx_cap.wtbl_d7.field.dbnss_en, + pwtbl->trx_cap.wtbl_d7.field.bafen, + pwtbl->trx_cap.wtbl_d7.field.rdg_ba, + pwtbl->trx_cap.wtbl_d7.field.r, + pwtbl->trx_cap.wtbl_d7.field.spe_idx, + pwtbl->trx_cap.wtbl_d7.field.g2, + pwtbl->trx_cap.wtbl_d7.field.g4, + pwtbl->trx_cap.wtbl_d7.field.g8, + pwtbl->trx_cap.wtbl_d7.field.g16, + pwtbl->trx_cap.wtbl_d7.field.g2_ltf, + pwtbl->trx_cap.wtbl_d7.field.g4_ltf, + pwtbl->trx_cap.wtbl_d7.field.g8_ltf, + pwtbl->trx_cap.wtbl_d7.field.g16_ltf, + pwtbl->trx_cap.wtbl_d7.field.g2_he, + pwtbl->trx_cap.wtbl_d7.field.g4_he, + pwtbl->trx_cap.wtbl_d7.field.g8_he, + pwtbl->trx_cap.wtbl_d7.field.g16_he); + + LOG_FUNC( + "\n\tLWTBL DW 9\n" + "\tFCAP:0x%x\n" + "\tFCAP_20_40_MHZ:%d\n" + "\tFCAP_20_TO_160_MHZ:%d\n" + "\tFCAP_20_TO_80_MHZ:%d\n", + pwtbl->trx_cap.wtbl_d9.field.fcap, + ((pwtbl->trx_cap.wtbl_d9.field.fcap) & + (BIT(0))), + pwtbl->trx_cap.wtbl_d9.field.fcap, + (((pwtbl->trx_cap.wtbl_d9.field.fcap) & + (BIT(1))) >> 1)); + + /* Rate Info (DW10~13) */ + LOG_FUNC("Rate Info (DW10~13):"); + txrate[0] = pwtbl->auto_rate_tb.wtbl_d10.field.rate1; + txrate[1] = pwtbl->auto_rate_tb.wtbl_d10.field.rate2; + txrate[2] = pwtbl->auto_rate_tb.wtbl_d11.field.rate3; + txrate[3] = pwtbl->auto_rate_tb.wtbl_d11.field.rate4; + txrate[4] = pwtbl->auto_rate_tb.wtbl_d12.field.rate5; + txrate[5] = pwtbl->auto_rate_tb.wtbl_d12.field.rate6; + txrate[6] = pwtbl->auto_rate_tb.wtbl_d13.field.rate7; + txrate[7] = pwtbl->auto_rate_tb.wtbl_d13.field.rate8; + + for (rate_idx = 0; rate_idx < 8; rate_idx++) { + txmode = (((txrate[rate_idx]) & + (0xf << 6)) >> 6); + mcs = ((txrate[rate_idx]) & + (0x3f)); + nss = (((txrate[rate_idx]) & + (0x7 << 10)) >> 10) + 1; + stbc = (((txrate[rate_idx]) & + (0x1 << 13)) >> 13); + + if (!(rate_idx%2)) + LOG_FUNC("LWTBL DW %d\n", + (rate_idx/2)+10); + + if (txmode == TX_RATE_MODE_CCK) + LOG_FUNC( + "\tRate%d(0x%x):TxMode=%d(%s) TxRate=%d(%s) Nsts=%d STBC=%d\n", + rate_idx + 1, + txrate[rate_idx], + txmode, + (txmode < ENUM_TX_MODE_NUM ? + RATE_V2_HW_TX_MODE_STR[txmode] : "N/A"), + mcs, + mcs < 4 ? HW_TX_RATE_CCK_STR[mcs] : + HW_TX_RATE_CCK_STR[4], + nss, stbc); + else if (txmode == TX_RATE_MODE_OFDM) + LOG_FUNC( + "\tRate%d(0x%x):TxMode=%d(%s) TxRate=%d(%s) Nsts=%d STBC=%d\n", + rate_idx + 1, + txrate[rate_idx], + txmode, + (txmode < ENUM_TX_MODE_NUM ? + RATE_V2_HW_TX_MODE_STR[txmode] : "N/A"), + mcs, + nicHwRateOfdmStr(mcs), + nss, stbc); + else + LOG_FUNC( + "\tRate%d(0x%x):TxMode=%d(%s) TxRate=%d(MCS%d) Nsts=%d STBC=%d\n", + rate_idx + 1, + txrate[rate_idx], + txmode, + (txmode < ENUM_TX_MODE_NUM ? + RATE_V2_HW_TX_MODE_STR[txmode] : "N/A"), + mcs, + mcs, + nss, stbc); + } + LOG_FUNC("\n"); + + /* Show LWTBL RAW Data */ + for (wtbl_offset = 0; wtbl_offset < u1WtblSize; + wtbl_offset += 4) { + kalMemCopy(&u4Value, + (uint32_t *)&wtbl_raw_dw[wtbl_offset], + sizeof(uint32_t)); + LOG_FUNC( + "\tDW%02d: %02x %02x %02x %02x\n", + wtbl_offset / 4, + (u4Value & 0xff000000) >> 24, + (u4Value & 0xff0000) >> 16, + (u4Value & 0xff00) >> 8, + u4Value & 0xff); + } + LOG_FUNC("\n"); + kalMemFree(wtbl_raw_dw, VIR_MEM_TYPE, + sizeof(struct fwtbl_lmac_struct)); + } +} + +int32_t connac2x_show_wtbl_info( + struct ADAPTER *prAdapter, + uint32_t u4Index, + char *pcCommand, + int i4TotalLen) +{ + struct mt66xx_chip_info *prChipInfo; + uint32_t u4Value = 0; + uint32_t wtbl_lmac_baseaddr; + uint32_t wtbl_offset, addr; + unsigned char *wtbl_raw_dw = NULL; + struct fwtbl_lmac_struct *pwtbl; + int32_t i4BytesWritten = 0; + + prChipInfo = prAdapter->chip_info; + DBGLOG(REQ, INFO, "WTBL : index = %d\n", u4Index); + + wtbl_raw_dw = (unsigned char *)kalMemAlloc( + sizeof(struct fwtbl_lmac_struct), VIR_MEM_TYPE); + if (!wtbl_raw_dw) { + DBGLOG(REQ, ERROR, "WTBL : Memory alloc failed\n"); + return 0; + } + + /* LMAC */ + CONNAC2X_LWTBL_CONFIG(prAdapter, prChipInfo->u4LmacWtblDUAddr, u4Index); + wtbl_lmac_baseaddr = CONNAC2X_LWTBL_IDX2BASE( + prChipInfo->u4LmacWtblDUAddr, u4Index, 0); + HAL_MCR_RD(prAdapter, prChipInfo->u4LmacWtblDUAddr, + &u4Value); + + DBGLOG(REQ, INFO, "LMAC WTBL Addr: group: 0x%x=0x%x addr: 0x%x\n", + prChipInfo->u4LmacWtblDUAddr, + u4Value, + wtbl_lmac_baseaddr); + + /* Read LWTBL Entries */ + for (wtbl_offset = 0; wtbl_offset < + sizeof(struct fwtbl_lmac_struct); + wtbl_offset += 4) { + addr = wtbl_lmac_baseaddr + wtbl_offset; + HAL_MCR_RD(prAdapter, addr, + &u4Value); + kalMemCopy( + (uint32_t *)&wtbl_raw_dw[wtbl_offset], + &u4Value, sizeof(uint32_t)); + } + + pwtbl = (struct fwtbl_lmac_struct *)wtbl_raw_dw; + i4BytesWritten = connac2x_dump_helper_wtbl_info( + prAdapter, + pcCommand, + i4TotalLen, + pwtbl, + u4Index); + + kalMemFree(wtbl_raw_dw, VIR_MEM_TYPE, + sizeof(struct fwtbl_lmac_struct)); + + connac2x_print_wtbl_info(prAdapter, u4Index); + return i4BytesWritten; +} + +int32_t connac2x_show_umac_wtbl_info( + struct ADAPTER *prAdapter, + uint32_t u4Index, + char *pcCommand, + int i4TotalLen) +{ + struct mt66xx_chip_info *prChipInfo; + int32_t i4BytesWritten = 0; + uint8_t keytbl[32] = {0}; + uint8_t keytbl2[32] = {0}; + uint16_t x; + uint32_t *dest_cpy = (uint32_t *)keytbl; + uint32_t sizeInDW = 8; + uint32_t u4SrcAddr = 0; + uint32_t u4Value = 0; + uint32_t wtbl_offset, addr; + uint32_t wtbl_umac_baseaddr; + unsigned char *wtbl_raw_dw = NULL; + struct fwtbl_umac_struct *puwtbl; + unsigned long long pn = 0; + + prChipInfo = prAdapter->chip_info; + /* UMAC */ + CONNAC2X_UWTBL_CONFIG(prAdapter, prChipInfo->u4UmacWtblDUAddr, u4Index); + wtbl_umac_baseaddr = CONNAC2X_UWTBL_IDX2BASE( + prChipInfo->u4UmacWtblDUAddr, u4Index, 0); + HAL_MCR_RD(prAdapter, prChipInfo->u4UmacWtblDUAddr, &u4Value); + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "UMAC WTBL Addr: group: 0x%x=0x%x addr: 0x%x\n", + prChipInfo->u4UmacWtblDUAddr, + u4Value, + wtbl_umac_baseaddr); + + wtbl_raw_dw = (unsigned char *)kalMemAlloc( + sizeof(struct fwtbl_umac_struct), VIR_MEM_TYPE); + if (!wtbl_raw_dw) { + DBGLOG(REQ, ERROR, "WTBL : Memory alloc failed\n"); + return 0; + } + /* Read UWTBL Entries */ + for (wtbl_offset = 0; wtbl_offset < + sizeof(struct fwtbl_umac_struct); + wtbl_offset += 4) { + addr = wtbl_umac_baseaddr + wtbl_offset; + HAL_MCR_RD(prAdapter, addr, + &u4Value); + kalMemCopy( + (uint32_t *)&wtbl_raw_dw[wtbl_offset], + &u4Value, sizeof(uint32_t)); + } + puwtbl = (struct fwtbl_umac_struct *)wtbl_raw_dw; + pn = ((pn || (puwtbl->serial_no.wtbl_d1.field.pn1) << 5) + || puwtbl->serial_no.wtbl_d0.field.pn0); + /* UMAC WTBL DW 0,1 */ + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "UWTBL DW 0,1\n\tpn:%d\n\tcom_sn:%d\n", + pn, + puwtbl->serial_no.wtbl_d1.field.com_sn); + + /* UMAC WTBL DW 5 */ + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "UWTBL DW 5\n" + "\tKey_loc0:%d\n" + "\tKey_loc1:%d\n" + "\tQoS:%d\n" + "\tHT:%d\n" + "\tHW_AMSDU_CFG:%d\n", + puwtbl->klink_amsdu.wtbl_d5.field.key_loc0, + puwtbl->klink_amsdu.wtbl_d5.field.key_loc1, + puwtbl->klink_amsdu.wtbl_d5.field.qos, + puwtbl->klink_amsdu.wtbl_d5.field.ht, + puwtbl->klink_amsdu.wtbl_d6.field.hw_amsdu_cfg); + + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "\n\nkeyloc0:%d\n", + puwtbl->klink_amsdu.wtbl_d5.field.key_loc0); + + if (puwtbl->klink_amsdu.wtbl_d5.field.key_loc0 != + (CONNAC2X_WTBL_KEY_LINK_DW_KEY_LOC0_MASK >> + CONNAC2X_WTBL_KEY_LINK_DW_KEY_LOC0_OFFSET)) { + /* will write new value WTBL_UMAC_TOP_BASE */ + CONNAC2X_KEYTBL_CONFIG(prAdapter, prChipInfo->u4UmacWtblDUAddr, + puwtbl->klink_amsdu.wtbl_d5.field.key_loc0); + u4SrcAddr = CONNAC2X_KEYTBL_IDX2BASE( + prChipInfo->u4UmacWtblDUAddr, + puwtbl->klink_amsdu.wtbl_d5.field.key_loc0, 0); + + HAL_MCR_RD(prAdapter, prChipInfo->u4UmacWtblDUAddr, + &u4Value); + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "KEY WTBL Addr: group:0x%x=0x%x addr: 0x%x\n", + prChipInfo->u4UmacWtblDUAddr, + u4Value, + u4SrcAddr); + + /* Read Entries */ + while (sizeInDW--) { + HAL_MCR_RD(prAdapter, u4SrcAddr, &u4Value); + kalMemCopy(dest_cpy, &u4Value, sizeof(uint32_t)); + dest_cpy++; + u4SrcAddr += 4; + } + + for (x = 0; x < 8; x++) { + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "DW%02d: %02x %02x %02x %02x\n", + x, + keytbl[x * 4 + 3], + keytbl[x * 4 + 2], + keytbl[x * 4 + 1], + keytbl[x * 4]); + } + } + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "\nkeyloc1:%d\n", + puwtbl->klink_amsdu.wtbl_d5.field.key_loc1); + + if (puwtbl->klink_amsdu.wtbl_d5.field.key_loc1 != + (CONNAC2X_WTBL_KEY_LINK_DW_KEY_LOC1_MASK >> + CONNAC2X_WTBL_KEY_LINK_DW_KEY_LOC1_OFFSET)) { + dest_cpy = (uint32_t *)keytbl2; + sizeInDW = 8; + + /* will write new value WF_WTBLON_TOP_WDUCR_ADDR */ + CONNAC2X_KEYTBL_CONFIG(prAdapter, prChipInfo->u4UmacWtblDUAddr, + puwtbl->klink_amsdu.wtbl_d5.field.key_loc1); + u4SrcAddr = CONNAC2X_KEYTBL_IDX2BASE( + prChipInfo->u4UmacWtblDUAddr, + puwtbl->klink_amsdu.wtbl_d5.field.key_loc1, 0); + + HAL_MCR_RD(prAdapter, prChipInfo->u4UmacWtblDUAddr, + &u4Value); + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "KEY WTBL Addr: group:0x%x=0x%x addr: 0x%x\n", + prChipInfo->u4UmacWtblDUAddr, + u4Value, + u4SrcAddr); + + /* Read Entries */ + while (sizeInDW--) { + HAL_MCR_RD(prAdapter, u4SrcAddr, &u4Value); + kalMemCopy(dest_cpy, &u4Value, sizeof(uint32_t)); + dest_cpy++; + u4SrcAddr += 4; + } + + for (x = 0; x < 8; x++) { + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "DW%02d: %02x %02x %02x %02x\n", + x, + keytbl2[x * 4 + 3], + keytbl2[x * 4 + 2], + keytbl2[x * 4 + 1], + keytbl2[x * 4]); + } + } + kalMemFree(wtbl_raw_dw, VIR_MEM_TYPE, + sizeof(struct fwtbl_umac_struct)); + + return i4BytesWritten; +} + +int32_t connac2x_show_rx_rate_info( + struct ADAPTER *prAdapter, + char *pcCommand, + int32_t i4TotalLen, + uint8_t ucStaIdx) +{ + int32_t i4BytesWritten = 0; + uint32_t txmode, rate, frmode, sgi, nsts, ldpc, stbc, groupid, mu; + uint32_t u4RxVector0 = 0, u4RxVector1 = 0, u4RxVector2 = 0; + + /* Group3 PRXV1[0:31] */ + u4RxVector0 = prAdapter->arStaRec[ucStaIdx].u4RxVector0; + /* Group5 C-B-0[0:31] */ + u4RxVector1 = prAdapter->arStaRec[ucStaIdx].u4RxVector1; + /* Group5 C-B-1[0:31] */ + u4RxVector2 = prAdapter->arStaRec[ucStaIdx].u4RxVector2; + + DBGLOG(REQ, LOUD, "****** P-RXVector1 = 0x%08x ******\n", + u4RxVector0); + DBGLOG(REQ, LOUD, "****** C-RXVector1 = 0x%08x ******\n", + u4RxVector1); + DBGLOG(REQ, LOUD, "****** C-RXVector2 = 0x%08x ******\n", + u4RxVector2); + + /* P-RXV1 */ + rate = (u4RxVector0 & CONNAC2X_RX_VT_RX_RATE_MASK) + >> CONNAC2X_RX_VT_RX_RATE_OFFSET; + nsts = ((u4RxVector0 & CONNAC2X_RX_VT_NSTS_MASK) + >> CONNAC2X_RX_VT_NSTS_OFFSET); + ldpc = u4RxVector0 & CONNAC2X_RX_VT_LDPC; + + /* C-B-0 */ + stbc = (u4RxVector1 & CONNAC2X_RX_VT_STBC_MASK) + >> CONNAC2X_RX_VT_STBC_OFFSET; + txmode = (u4RxVector1 & CONNAC2X_RX_VT_RX_MODE_MASK) + >> CONNAC2X_RX_VT_RX_MODE_OFFSET; + frmode = (u4RxVector1 & CONNAC2X_RX_VT_FR_MODE_MASK) + >> CONNAC2X_RX_VT_FR_MODE_OFFSET; + sgi = (u4RxVector1 & CONNAC2X_RX_VT_SHORT_GI_MASK) + >> CONNAC2X_RX_VT_SHORT_GI_OFFSET; + /* C-B-1 */ + groupid = (u4RxVector2 & CONNAC2X_RX_VT_GROUP_ID_MASK) + >> CONNAC2X_RX_VT_GROUP_ID_OFFSET; + + if (groupid && groupid != 63) { + mu = 1; + } else { + mu = 0; + nsts += 1; + } + + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%-20s%s", "Last RX Rate", " = "); + + if (txmode == TX_RATE_MODE_CCK) + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s, ", + rate < 4 ? HW_TX_RATE_CCK_STR[rate] : + (rate < 8 ? HW_TX_RATE_CCK_STR[rate - 4] : + HW_TX_RATE_CCK_STR[4])); + else if (txmode == TX_RATE_MODE_OFDM) + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s, ", + nicHwRateOfdmStr(rate)); + else if ((txmode == TX_RATE_MODE_HTMIX) || + (txmode == TX_RATE_MODE_HTGF)) + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "MCS%d, ", rate); + else + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s%d_MCS%d, ", + stbc == 1 ? "NSTS" : "NSS", nsts, rate); + + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s, ", + frmode < 4 ? HW_TX_RATE_BW[frmode] : HW_TX_RATE_BW[4]); + + if (txmode == TX_RATE_MODE_CCK) + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s, ", + rate < 4 ? "LP" : "SP"); + else if (txmode == TX_RATE_MODE_OFDM) + ; + else if (txmode == TX_RATE_MODE_HTMIX || + txmode == TX_RATE_MODE_HTGF || + txmode == TX_RATE_MODE_VHT) + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s, ", + sgi == 0 ? "LGI" : "SGI"); + else + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s, ", + sgi == 0 ? "SGI" : (sgi == 1 ? "MGI" : "LGI")); + + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s", stbc == 0 ? "" : "STBC, "); + + if (mu) { + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s, %s, %s (%d)\n", + txmode < ENUM_TX_MODE_NUM ? + HW_TX_MODE_STR[txmode] : "N/A", + ldpc == 0 ? "BCC" : "LDPC", "MU", groupid); + } else { + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s, %s\n", + txmode < ENUM_TX_MODE_NUM ? + HW_TX_MODE_STR[txmode] : "N/A", + ldpc == 0 ? "BCC" : "LDPC"); + } + + return i4BytesWritten; +} + +int32_t connac2x_show_rx_rssi_info( + struct ADAPTER *prAdapter, + char *pcCommand, + int32_t i4TotalLen, + uint8_t ucStaIdx) +{ + int32_t i4RSSI0 = 0, i4RSSI1 = 0, i4RSSI2 = 0, i4RSSI3 = 0; + int32_t i4BytesWritten = 0; + uint32_t u4CRxv4th = 0; + + /* Group5 C-B-3[0:31] */ + u4CRxv4th = prAdapter->arStaRec[ucStaIdx].u4RxVector4; + + DBGLOG(REQ, LOUD, "****** C-RXVector4th cycle = 0x%08x ******\n", + u4CRxv4th); + + i4RSSI0 = RCPI_TO_dBm((u4CRxv4th & CONNAC2X_RX_VT_RCPI0_MASK) >> + CONNAC2X_RX_VT_RCPI0_OFFSET); + i4RSSI1 = RCPI_TO_dBm((u4CRxv4th & CONNAC2X_RX_VT_RCPI1_MASK) >> + CONNAC2X_RX_VT_RCPI1_OFFSET); + + if (prAdapter->rWifiVar.ucNSS > 2) { + i4RSSI2 = RCPI_TO_dBm((u4CRxv4th & CONNAC2X_RX_VT_RCPI2_MASK) >> + CONNAC2X_RX_VT_RCPI2_OFFSET); + i4RSSI3 = RCPI_TO_dBm((u4CRxv4th & CONNAC2X_RX_VT_RCPI3_MASK) >> + CONNAC2X_RX_VT_RCPI3_OFFSET); + + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%-20s%s%d %d %d %d\n", + "Last RX Data RSSI", " = ", + i4RSSI0, i4RSSI1, i4RSSI2, i4RSSI3); + } else + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%-20s%s%d %d\n", + "Last RX Data RSSI", " = ", i4RSSI0, i4RSSI1); + + return i4BytesWritten; +} + +int32_t connac2x_show_stat_info( + struct ADAPTER *prAdapter, + char *pcCommand, + int32_t i4TotalLen, + struct PARAM_HW_WLAN_INFO *prHwWlanInfo, + struct PARAM_GET_STA_STATISTICS *prQueryStaStatistics, + uint8_t fgResetCnt, + uint32_t u4StatGroup) +{ + int32_t i4BytesWritten = 0; + int32_t rRssi; + uint16_t u2LinkSpeed, u2Idx = 0; + uint32_t u4Per, u4RxPer[ENUM_BAND_NUM], u4TxMpduPer[ENUM_BAND_NUM], + u4InstantPer; + uint8_t ucDbdcIdx, ucSkipAr, ucStaIdx, ucNss; + static uint32_t u4TotalTxCnt[CFG_STAT_DBG_PEER_NUM] = {0}; + static uint32_t u4TotalFailCnt[CFG_STAT_DBG_PEER_NUM] = {0}; + static uint32_t u4Rate1TxCnt[CFG_STAT_DBG_PEER_NUM] = {0}; + static uint32_t u4Rate1FailCnt[CFG_STAT_DBG_PEER_NUM] = {0}; + static uint32_t au4RxMpduCnt[ENUM_BAND_NUM] = {0}; + static uint32_t au4FcsError[ENUM_BAND_NUM] = {0}; + static uint32_t au4RxFifoCnt[ENUM_BAND_NUM] = {0}; + static uint32_t au4AmpduTxSfCnt[ENUM_BAND_NUM] = {0}; + static uint32_t au4AmpduTxAckSfCnt[ENUM_BAND_NUM] = {0}; + struct RX_CTRL *prRxCtrl; + uint32_t u4InstantRxPer[ENUM_BAND_NUM]; + uint32_t u4InstantTxMpduPer[ENUM_BAND_NUM]; + struct PARAM_CUSTOM_SW_CTRL_STRUCT rSwCtrlInfo; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + int16_t i2Wf0AvgPwr = 0, i2Wf1AvgPwr = 0; + uint32_t u4BufLen = 0; + uint8_t ucRaTableNum = sizeof(RATE_TBLE) / sizeof(char *); + uint8_t ucRaStatusNum = sizeof(RA_STATUS_TBLE) / sizeof(char *); + uint8_t ucBssIndex = AIS_DEFAULT_INDEX; + struct PARAM_LINK_SPEED_EX rLinkSpeed; + +#if 0 + uint8_t ucRaLtModeNum = sizeof(LT_MODE_TBLE) / sizeof(char *); + uint8_t ucRaSgiUnSpStateNum = sizeof(SGI_UNSP_STATE_TBLE) / + sizeof(char *); + uint8_t ucRaBwStateNum = sizeof(BW_STATE_TBLE) / sizeof(char *); +#endif + uint8_t aucAggRange[AGG_RANGE_SEL_NUM]; + uint32_t au4RangeCtrl[AGG_RANGE_SEL_4BYTE_NUM]; + enum AGG_RANGE_TYPE_T eRangeType = ENUM_AGG_RANGE_TYPE_TX; + + ucSkipAr = prQueryStaStatistics->ucSkipAr; + prRxCtrl = &prAdapter->rRxCtrl; + ucNss = prAdapter->rWifiVar.ucNSS; + + if (ucSkipAr) { + u2Idx = nicGetStatIdxInfo(prAdapter, + (uint8_t)(prHwWlanInfo->u4Index)); + + if (u2Idx == 0xFFFF) + return i4BytesWritten; + } + + if (ucSkipAr) { + u4TotalTxCnt[u2Idx] += prQueryStaStatistics->u4TransmitCount; + u4TotalFailCnt[u2Idx] += prQueryStaStatistics-> + u4TransmitFailCount; + u4Rate1TxCnt[u2Idx] += prQueryStaStatistics->u4Rate1TxCnt; + u4Rate1FailCnt[u2Idx] += prQueryStaStatistics->u4Rate1FailCnt; + } + + if (ucSkipAr) { + u4Per = (u4Rate1TxCnt[u2Idx] == 0) ? + (0) : (1000 * (u4Rate1FailCnt[u2Idx]) / + (u4Rate1TxCnt[u2Idx])); + + u4InstantPer = (prQueryStaStatistics->u4Rate1TxCnt == 0) ? + (0) : (1000 * (prQueryStaStatistics->u4Rate1FailCnt) / + (prQueryStaStatistics->u4Rate1TxCnt)); + } else { + u4Per = (prQueryStaStatistics->u4Rate1TxCnt == 0) ? + (0) : (1000 * (prQueryStaStatistics->u4Rate1FailCnt) / + (prQueryStaStatistics->u4Rate1TxCnt)); + + u4InstantPer = (prQueryStaStatistics->ucPer == 0) ? + (0) : (prQueryStaStatistics->ucPer); + } + + for (ucDbdcIdx = 0; ucDbdcIdx < ENUM_BAND_NUM; ucDbdcIdx++) { + au4RxMpduCnt[ucDbdcIdx] += g_arMibInfo[ucDbdcIdx].u4RxMpduCnt; + au4FcsError[ucDbdcIdx] += g_arMibInfo[ucDbdcIdx].u4FcsError; + au4RxFifoCnt[ucDbdcIdx] += g_arMibInfo[ucDbdcIdx].u4RxFifoFull; + au4AmpduTxSfCnt[ucDbdcIdx] += + g_arMibInfo[ucDbdcIdx].u4AmpduTxSfCnt; + au4AmpduTxAckSfCnt[ucDbdcIdx] += + g_arMibInfo[ucDbdcIdx].u4AmpduTxAckSfCnt; + + u4RxPer[ucDbdcIdx] = + ((au4RxMpduCnt[ucDbdcIdx] + au4FcsError[ucDbdcIdx]) == 0) ? + (0) : (1000 * au4FcsError[ucDbdcIdx] / + (au4RxMpduCnt[ucDbdcIdx] + + au4FcsError[ucDbdcIdx])); + + u4TxMpduPer[ucDbdcIdx] = + (au4AmpduTxSfCnt[ucDbdcIdx] == 0) ? + (0) : (1000 * (au4AmpduTxSfCnt[ucDbdcIdx] - + au4AmpduTxAckSfCnt[ucDbdcIdx]) / + au4AmpduTxSfCnt[ucDbdcIdx]); + + u4InstantRxPer[ucDbdcIdx] = + ((prQueryStaStatistics->rMibInfo[ucDbdcIdx].u4RxMpduCnt + + prQueryStaStatistics->rMibInfo[ucDbdcIdx].u4FcsError) + == 0) ? + (0) : (1000 * prQueryStaStatistics-> + rMibInfo[ucDbdcIdx].u4FcsError / + (prQueryStaStatistics->rMibInfo[ucDbdcIdx]. + u4RxMpduCnt + + prQueryStaStatistics->rMibInfo[ucDbdcIdx]. + u4FcsError)); + u4InstantTxMpduPer[ucDbdcIdx] = + (prQueryStaStatistics->rMibInfo[ucDbdcIdx]. + u4AmpduTxSfCnt == 0) ? + (0) : (1000 * + (prQueryStaStatistics->rMibInfo[ucDbdcIdx]. + u4AmpduTxSfCnt - + prQueryStaStatistics->rMibInfo[ucDbdcIdx]. + u4AmpduTxAckSfCnt) / + prQueryStaStatistics->rMibInfo[ucDbdcIdx]. + u4AmpduTxSfCnt); + } + + rRssi = RCPI_TO_dBm(prQueryStaStatistics->ucRcpi); + u2LinkSpeed = (prQueryStaStatistics->u2LinkSpeed == 0) ? 0 : + prQueryStaStatistics->u2LinkSpeed / 2; + + if (ucSkipAr) { + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d(%d)\n", "\nWlanIdx(BackupIdx)", " = ", + prHwWlanInfo->u4Index, u2Idx); + } else { + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "\nWlanIdx", " = ", + prHwWlanInfo->u4Index); + } + + /* =========== Group 0x0001 =========== */ + if (u4StatGroup & 0x0001) { + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", "----- STA Stat (Group 0x01) -----\n"); + + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "CurrTemperature", " = ", + prQueryStaStatistics->ucTemperature); + + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "Tx Total cnt", " = ", + ucSkipAr ? (u4TotalTxCnt[u2Idx]) : + (prQueryStaStatistics->u4TransmitCount)); + + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "Tx Fail Cnt", " = ", + ucSkipAr ? (u4TotalFailCnt[u2Idx]) : + (prQueryStaStatistics->u4TransmitFailCount)); + + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "Rate1 Tx Cnt", " = ", + ucSkipAr ? (u4Rate1TxCnt[u2Idx]) : + (prQueryStaStatistics->u4Rate1TxCnt)); + + if (ucSkipAr) + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d, PER = %d.%1d%%, instant PER = %d.%1d%%\n", + "Rate1 Fail Cnt", " = ", + u4Rate1FailCnt[u2Idx], u4Per/10, u4Per%10, + u4InstantPer/10, u4InstantPer%10); + else + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d, PER = %d.%1d%%, instant PER = %d%%\n", + "Rate1 Fail Cnt", " = ", + prQueryStaStatistics->u4Rate1FailCnt, + u4Per/10, u4Per%10, u4InstantPer); + + if ((ucSkipAr) && (fgResetCnt)) { + u4TotalTxCnt[u2Idx] = 0; + u4TotalFailCnt[u2Idx] = 0; + u4Rate1TxCnt[u2Idx] = 0; + u4Rate1FailCnt[u2Idx] = 0; + } + } + + /* =========== Group 0x0002 =========== */ + if (u4StatGroup & 0x0002) { + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", "----- MIB Info (Group 0x02) -----\n"); + + for (ucDbdcIdx = 0; ucDbdcIdx < ENUM_BAND_NUM; ucDbdcIdx++) { + if (prAdapter->rWifiVar.fgDbDcModeEn) + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "[DBDC_%d] :\n", ucDbdcIdx); + + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "RX Success", " = ", + au4RxMpduCnt[ucDbdcIdx]); + + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d, PER = %d.%1d%%, instant PER = %d.%1d%%\n", + "RX with CRC", " = ", au4FcsError[ucDbdcIdx], + u4RxPer[ucDbdcIdx]/10, u4RxPer[ucDbdcIdx]%10, + u4InstantRxPer[ucDbdcIdx]/10, + u4InstantRxPer[ucDbdcIdx]%10); + + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "RX drop FIFO full", " = ", + au4RxFifoCnt[ucDbdcIdx]); +#if 0 + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "TX MPDU Success", " = ", + au4AmpduTxAckSfCnt[ucDbdcIdx]); + + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d, PER = %d.%1d%%, instant PER = %d.%1d%%\n", + "TX MPDU Fail", " = ", + au4AmpduTxSfCnt[ucDbdcIdx] - + au4AmpduTxAckSfCnt[ucDbdcIdx], + u4TxMpduPer[ucDbdcIdx]/10, + u4TxMpduPer[ucDbdcIdx]%10, + u4InstantTxMpduPer[ucDbdcIdx]/10, + u4InstantTxMpduPer[ucDbdcIdx]%10); +#endif + if (!prAdapter->rWifiVar.fgDbDcModeEn) + break; + } + + if (fgResetCnt) { + kalMemZero(au4RxMpduCnt, sizeof(au4RxMpduCnt)); + kalMemZero(au4FcsError, sizeof(au4RxMpduCnt)); + kalMemZero(au4RxFifoCnt, sizeof(au4RxMpduCnt)); + kalMemZero(au4AmpduTxSfCnt, sizeof(au4RxMpduCnt)); + kalMemZero(au4AmpduTxAckSfCnt, sizeof(au4RxMpduCnt)); + } + } + + /* =========== Group 0x0004 =========== */ + if (u4StatGroup & 0x0004) { + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", "----- Last Rx Info (Group 0x04) -----\n"); + + /* get Beacon RSSI */ + ucBssIndex = secGetBssIdxByWlanIdx + (prAdapter, (uint8_t)(prHwWlanInfo->u4Index)); + + rStatus = kalIoctlByBssIdx(prAdapter->prGlueInfo, + wlanoidQueryRssi, + &rLinkSpeed, sizeof(rLinkSpeed), + TRUE, TRUE, TRUE, + &u4BufLen, ucBssIndex); + + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(REQ, WARN, "unable to retrieve rssi\n"); + + if (IS_BSS_INDEX_VALID(ucBssIndex)) + rRssi = rLinkSpeed.rLq[ucBssIndex].cRssi; + + rSwCtrlInfo.u4Data = 0; + rSwCtrlInfo.u4Id = CMD_SW_DBGCTL_ADVCTL_GET_ID + 1; +#if 0 + rStatus = kalIoctl(prAdapter->prGlueInfo, + wlanoidQuerySwCtrlRead, &rSwCtrlInfo, + sizeof(rSwCtrlInfo), TRUE, TRUE, TRUE, + &u4BufLen); +#endif + DBGLOG(REQ, LOUD, "rStatus %u, rSwCtrlInfo.u4Data 0x%x\n", + rStatus, rSwCtrlInfo.u4Data); + if (rStatus == WLAN_STATUS_SUCCESS) { + i2Wf0AvgPwr = rSwCtrlInfo.u4Data & 0xFFFF; + i2Wf1AvgPwr = (rSwCtrlInfo.u4Data >> 16) & 0xFFFF; + + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d %d\n", "NOISE", " = ", + i2Wf0AvgPwr, i2Wf1AvgPwr); + } + +#ifndef SOC3_0 + /* Last RX Rate */ + i4BytesWritten += nicGetRxRateInfo(prAdapter, + pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten, + (uint8_t)(prHwWlanInfo->u4Index)); +#endif + /* Last RX RSSI */ + i4BytesWritten += nicRxGetLastRxRssi(prAdapter, + pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten, + (uint8_t)(prHwWlanInfo->u4Index)); + + /* Last TX Resp RSSI */ + if (ucNss > 2) + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d %d %d %d\n", + "Tx Response RSSI", " = ", + RCPI_TO_dBm( + prHwWlanInfo->rWtblRxCounter.ucRxRcpi0), + RCPI_TO_dBm( + prHwWlanInfo->rWtblRxCounter.ucRxRcpi1), + RCPI_TO_dBm( + prHwWlanInfo->rWtblRxCounter.ucRxRcpi2), + RCPI_TO_dBm( + prHwWlanInfo->rWtblRxCounter.ucRxRcpi3)); + else + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d %d\n", "Tx Response RSSI", " = ", + RCPI_TO_dBm( + prHwWlanInfo->rWtblRxCounter.ucRxRcpi0), + RCPI_TO_dBm( + prHwWlanInfo->rWtblRxCounter.ucRxRcpi1)); + + /* Last Beacon RSSI */ + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "Beacon RSSI", " = ", rRssi); + } + + /* =========== Group 0x0008 =========== */ + if (u4StatGroup & 0x0008) { + /* TxV */ + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", "----- Last TX Info (Group 0x08) -----\n"); + + for (ucDbdcIdx = 0; ucDbdcIdx < ENUM_BAND_NUM; ucDbdcIdx++) { + int8_t txpwr, pos_txpwr; + + txpwr = TX_VECTOR_GET_TX_PWR( + &prQueryStaStatistics->rTxVector[ucDbdcIdx]); + + if (prAdapter->rWifiVar.fgDbDcModeEn) + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "[DBDC_%d] :\n", ucDbdcIdx); + + i4BytesWritten += nicTxGetVectorInfo( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + &prQueryStaStatistics->rTxVector[ucDbdcIdx]); + + if (prQueryStaStatistics->rTxVector[ucDbdcIdx] + .u4TxV[0] == 0xFFFFFFFF) + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%s\n", "Chip Out TX Power", + " = ", "N/A"); + else { + pos_txpwr = (txpwr < 0) ? + (~txpwr + 1) : (txpwr); + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%c%d.%1d dBm\n", + "Chip Out TX Power", " = ", + (txpwr < 0) ? '-' : '+', + (pos_txpwr / 2), + 5 * (pos_txpwr % 2)); + } + + if (!prAdapter->rWifiVar.fgDbDcModeEn) + break; + } + } + + /* =========== Group 0x0010 =========== */ + if (u4StatGroup & 0x0010) { + /* RX Reorder */ + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", "----- RX Reorder (Group 0x10) -----\n"); + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%lu\n", "Rx reorder miss", " = ", + RX_GET_CNT(prRxCtrl, RX_DATA_REORDER_MISS_COUNT)); + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%lu\n", "Rx reorder within", " = ", + RX_GET_CNT(prRxCtrl, RX_DATA_REORDER_WITHIN_COUNT)); + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%lu\n", "Rx reorder ahead", " = ", + RX_GET_CNT(prRxCtrl, RX_DATA_REORDER_AHEAD_COUNT)); + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%lu\n", "Rx reorder behind", " = ", + RX_GET_CNT(prRxCtrl, RX_DATA_REORDER_BEHIND_COUNT)); + } + + /* =========== Group 0x0020 =========== */ + if (u4StatGroup & 0x0020) { + /* RA info */ + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", "----- RA Info (Group 0x20) -----\n"); +#if 0 + /* Last TX Rate */ + i4BytesWritten += nicGetTxRateInfo( + pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten, + FALSE, prHwWlanInfo, prQueryStaStatistics); +#endif + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%-20s%s%d\n", "LinkSpeed", + " = ", u2LinkSpeed); + + if (!prQueryStaStatistics->ucSkipAr) { + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%s\n", "RateTable", " = ", + prQueryStaStatistics->ucArTableIdx < + (ucRaTableNum - 1) ? + RATE_TBLE[ + prQueryStaStatistics->ucArTableIdx] : + RATE_TBLE[ucRaTableNum - 1]); + + if (wlanGetStaIdxByWlanIdx(prAdapter, + (uint8_t)(prHwWlanInfo->u4Index), &ucStaIdx) == + WLAN_STATUS_SUCCESS){ + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "2G Support 256QAM TX", + " = ", + ((prAdapter->arStaRec[ucStaIdx].u4Flags + & MTK_SYNERGY_CAP_SUPPORT_24G_MCS89) || + (prQueryStaStatistics-> + ucDynamicGband256QAMState == 2)) ? + 1 : 0); + } +#if 0 + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d%%\n", "Rate1 instantPer", " = ", + u4InstantPer); +#endif + if (prQueryStaStatistics->ucAvePer == 0xFF) { + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%s\n", "Train Down", " = ", + "N/A"); + + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%s\n", "Train Up", " = ", + "N/A"); + } else { + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d -> %d\n", "Train Down", + " = ", + (uint16_t) + (prQueryStaStatistics->u2TrainDown + & BITS(0, 7)), + (uint16_t) + ((prQueryStaStatistics->u2TrainDown >> + 8) & BITS(0, 7))); + + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d -> %d\n", "Train Up", " = ", + (uint16_t) + (prQueryStaStatistics->u2TrainUp + & BITS(0, 7)), + (uint16_t) + ((prQueryStaStatistics->u2TrainUp >> 8) + & BITS(0, 7))); + } + + if (prQueryStaStatistics->fgIsForceTxStream == 0) + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%s\n", "Force Tx Stream", + " = ", "N/A"); + else + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "Force Tx Stream", " = ", + prQueryStaStatistics-> + fgIsForceTxStream); + + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "Force SE off", " = ", + prQueryStaStatistics->fgIsForceSeOff); +#if 0 + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%s%d%s%d%s%d%s%d\n", "TxQuality", " = ", + "KEEP_", prQueryStaStatistics->aucTxQuality[0], + ", UP_", prQueryStaStatistics->aucTxQuality[1], + ", DOWN_", prQueryStaStatistics-> + aucTxQuality[2], + ", BWUP_", prQueryStaStatistics-> + aucTxQuality[3]); + + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "UpPenalty", " = ", + prQueryStaStatistics->ucTxRateUpPenalty); + + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%s\n", "LtMode", " = ", + prQueryStaStatistics->ucLowTrafficMode < + (ucRaLtModeNum - 1) ? + LT_MODE_TBLE[prQueryStaStatistics-> + ucLowTrafficMode] : + LT_MODE_TBLE[ucRaLtModeNum - 1]); + + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "LtCnt", " = ", + prQueryStaStatistics->ucLowTrafficCount); + + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "LtDashBoard", " = ", + prQueryStaStatistics->ucLowTrafficDashBoard); + + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%s\n", "SgiState", " = ", + prQueryStaStatistics->ucDynamicSGIState < + (ucRaSgiUnSpStateNum - 1) ? + SGI_UNSP_STATE_TBLE[prQueryStaStatistics-> + ucDynamicSGIState] : + SGI_UNSP_STATE_TBLE[ucRaSgiUnSpStateNum - 1]); + + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "SgiScore", " = ", + prQueryStaStatistics->ucDynamicSGIScore); + + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%s\n", "BwState", " = ", + prQueryStaStatistics->ucDynamicBWState < + (ucRaBwStateNum - 1) ? + BW_STATE_TBLE[prQueryStaStatistics-> + ucDynamicBWState] : + BW_STATE_TBLE[ucRaBwStateNum - 1]); + + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%s\n", "NonSpState", " = ", + prQueryStaStatistics->ucDynamicSGIState < + (ucRaSgiUnSpStateNum - 1) ? + SGI_UNSP_STATE_TBLE[prQueryStaStatistics-> + ucVhtNonSpRateState] : + SGI_UNSP_STATE_TBLE[ucRaSgiUnSpStateNum - 1]); +#endif + } + + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "RunningCnt", " = ", + prQueryStaStatistics->u2RaRunningCnt); + + prQueryStaStatistics->ucRaStatus &= ~0x80; + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%s\n", "Status", " = ", + prQueryStaStatistics->ucRaStatus < (ucRaStatusNum - 1) ? + RA_STATUS_TBLE[prQueryStaStatistics->ucRaStatus] : + RA_STATUS_TBLE[ucRaStatusNum - 1]); + + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "MaxAF", " = ", + prHwWlanInfo->rWtblPeerCap.ucAmpduFactor); + + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s0x%x\n", "SpeIdx", " = ", + prHwWlanInfo->rWtblPeerCap.ucSpatialExtensionIndex); +#if 0 + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "CBRN", " = ", + prHwWlanInfo->rWtblPeerCap.ucChangeBWAfterRateN); +#endif + /* Rate1~Rate8 */ + i4BytesWritten += nicGetTxRateInfo( + pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten, + TRUE, prHwWlanInfo, prQueryStaStatistics); + } + + /* =========== Group 0x0040 =========== */ + if (u4StatGroup & 0x0040) { + uint8_t ucIdx, ucInt; + + au4RangeCtrl[0] = prQueryStaStatistics->u4AggRangeCtrl_0; + au4RangeCtrl[1] = prQueryStaStatistics->u4AggRangeCtrl_1; + au4RangeCtrl[2] = prQueryStaStatistics->u4AggRangeCtrl_2; + au4RangeCtrl[3] = prQueryStaStatistics->u4AggRangeCtrl_3; + + eRangeType = (enum AGG_RANGE_TYPE_T) + prQueryStaStatistics->ucRangeType; + + for (ucIdx = 0; ucIdx < AGG_RANGE_SEL_NUM; ucIdx++) { + ucInt = ucIdx >> 2; + if (ucIdx % 4 == 0) + aucAggRange[ucIdx] = + ((au4RangeCtrl[ucInt] & + AGG_RANGE_SEL_0_MASK) >> + AGG_RANGE_SEL_0_OFFSET); + else if (ucIdx % 4 == 1) + aucAggRange[ucIdx] = + ((au4RangeCtrl[ucInt] & + AGG_RANGE_SEL_1_MASK) >> + AGG_RANGE_SEL_1_OFFSET); + else if (ucIdx % 4 == 2) + aucAggRange[ucIdx] = + ((au4RangeCtrl[ucInt] & + AGG_RANGE_SEL_2_MASK) >> + AGG_RANGE_SEL_2_OFFSET); + else if (ucIdx % 4 == 3) + aucAggRange[ucIdx] = + ((au4RangeCtrl[ucInt] & + AGG_RANGE_SEL_3_MASK) >> + AGG_RANGE_SEL_3_OFFSET); + } + + /* Tx Agg */ + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s%s%s", "------ ", + (eRangeType > ENUM_AGG_RANGE_TYPE_TX) ? ( + (eRangeType == ENUM_AGG_RANGE_TYPE_TRX) ? + ("TRX") : ("RX")) : ("TX"), + " AGG (Group 0x40) -----\n"); + + if (eRangeType == ENUM_AGG_RANGE_TYPE_TRX) { + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-6s%8d%5d%1s%2d%5d%1s%2d%5d%1s%2d%5d%1s%2d%5d%1s%2d%5d%1s%2d%5d%3s", + " TX :", aucAggRange[0] + 1, + aucAggRange[0] + 2, "~", aucAggRange[1] + 1, + aucAggRange[1] + 2, "~", aucAggRange[2] + 1, + aucAggRange[2] + 2, "~", aucAggRange[3] + 1, + aucAggRange[3] + 2, "~", aucAggRange[4] + 1, + aucAggRange[4] + 2, "~", aucAggRange[5] + 1, + aucAggRange[5] + 2, "~", aucAggRange[6] + 1, + aucAggRange[6] + 2, "~256\n"); + + for (ucDbdcIdx = 0; ucDbdcIdx < ENUM_BAND_NUM; + ucDbdcIdx++) { + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "DBDC%d:", ucDbdcIdx); + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%8d%8d%8d%8d%8d%8d%8d%8d\n", + g_arMibInfo[ucDbdcIdx]. + au2TxRangeAmpduCnt[0], + g_arMibInfo[ucDbdcIdx]. + au2TxRangeAmpduCnt[1], + g_arMibInfo[ucDbdcIdx]. + au2TxRangeAmpduCnt[2], + g_arMibInfo[ucDbdcIdx]. + au2TxRangeAmpduCnt[3], + g_arMibInfo[ucDbdcIdx]. + au2TxRangeAmpduCnt[4], + g_arMibInfo[ucDbdcIdx]. + au2TxRangeAmpduCnt[5], + g_arMibInfo[ucDbdcIdx]. + au2TxRangeAmpduCnt[6], + g_arMibInfo[ucDbdcIdx]. + au2TxRangeAmpduCnt[7]); + + if (!prAdapter->rWifiVar.fgDbDcModeEn) + break; + } + + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-6s%8d%5d%1s%2d%5d%1s%2d%5d%1s%2d%5d%1s%2d%5d%1s%2d%5d%1s%2d%5d%3s", + " RX :", aucAggRange[7] + 1, + aucAggRange[7] + 2, "~", aucAggRange[8] + 1, + aucAggRange[8] + 2, "~", aucAggRange[9] + 1, + aucAggRange[9] + 2, "~", aucAggRange[10] + 1, + aucAggRange[10] + 2, "~", aucAggRange[11] + 1, + aucAggRange[11] + 2, "~", aucAggRange[12] + 1, + aucAggRange[12] + 2, "~", aucAggRange[13] + 1, + aucAggRange[13] + 2, "~256\n"); + + for (ucDbdcIdx = 0; ucDbdcIdx < ENUM_BAND_NUM; + ucDbdcIdx++) { + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "DBDC%d:", ucDbdcIdx); + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%8d%8d%8d%8d%8d%8d%8d%8d\n", + g_arMibInfo[ucDbdcIdx]. + au2TxRangeAmpduCnt[8], + g_arMibInfo[ucDbdcIdx]. + au2TxRangeAmpduCnt[9], + g_arMibInfo[ucDbdcIdx]. + au2TxRangeAmpduCnt[10], + g_arMibInfo[ucDbdcIdx]. + au2TxRangeAmpduCnt[11], + g_arMibInfo[ucDbdcIdx]. + au2TxRangeAmpduCnt[12], + g_arMibInfo[ucDbdcIdx]. + au2TxRangeAmpduCnt[13], + g_arMibInfo[ucDbdcIdx]. + au2TxRangeAmpduCnt[14], + g_arMibInfo[ucDbdcIdx]. + au2TxRangeAmpduCnt[15]); + + if (!prAdapter->rWifiVar.fgDbDcModeEn) + break; + } + } else { + for (ucDbdcIdx = 0; ucDbdcIdx < ENUM_BAND_NUM; + ucDbdcIdx++) { + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "DBDC%d:\n", ucDbdcIdx); + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-6s%8d%6d%1s%2d%6d%1s%2d%6d%1s%2d%6d%1s%2d%6d%1s%2d%6d%1s%2d%6d%1s%2d\n", + "Range:", aucAggRange[0] + 1, + aucAggRange[0] + 2, "~", + aucAggRange[1] + 1, + aucAggRange[1] + 2, "~", + aucAggRange[2] + 1, + aucAggRange[2] + 2, "~", + aucAggRange[3] + 1, + aucAggRange[3] + 2, "~", + aucAggRange[4] + 1, + aucAggRange[4] + 2, "~", + aucAggRange[5] + 1, + aucAggRange[5] + 2, "~", + aucAggRange[6] + 1, + aucAggRange[6] + 2, "~", + aucAggRange[7] + 1); + + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%14d%9d%9d%9d%9d%9d%9d%9d\n", + g_arMibInfo[ucDbdcIdx]. + au2TxRangeAmpduCnt[0], + g_arMibInfo[ucDbdcIdx]. + au2TxRangeAmpduCnt[1], + g_arMibInfo[ucDbdcIdx]. + au2TxRangeAmpduCnt[2], + g_arMibInfo[ucDbdcIdx]. + au2TxRangeAmpduCnt[3], + g_arMibInfo[ucDbdcIdx]. + au2TxRangeAmpduCnt[4], + g_arMibInfo[ucDbdcIdx]. + au2TxRangeAmpduCnt[5], + g_arMibInfo[ucDbdcIdx]. + au2TxRangeAmpduCnt[6], + g_arMibInfo[ucDbdcIdx]. + au2TxRangeAmpduCnt[7]); + + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-6s%4d%1s%2d%5d%1s%2d%5d%1s%2d%5d%1s%2d%5d%1s%2d%5d%1s%2d%5d%1s%2d%5d%3s", + "Range:", aucAggRange[7] + 2, "~", + aucAggRange[8] + 1, + aucAggRange[8] + 2, "~", + aucAggRange[9] + 1, + aucAggRange[9] + 2, "~", + aucAggRange[10] + 1, + aucAggRange[10] + 2, "~", + aucAggRange[11] + 1, + aucAggRange[11] + 2, "~", + aucAggRange[12] + 1, + aucAggRange[12] + 2, "~", + aucAggRange[13] + 1, + aucAggRange[13] + 2, "~", + aucAggRange[14] + 1, + aucAggRange[14] + 2, "~256\n"); + + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%14d%9d%9d%9d%9d%9d%9d%9d\n", + g_arMibInfo[ucDbdcIdx]. + au2TxRangeAmpduCnt[8], + g_arMibInfo[ucDbdcIdx]. + au2TxRangeAmpduCnt[9], + g_arMibInfo[ucDbdcIdx]. + au2TxRangeAmpduCnt[10], + g_arMibInfo[ucDbdcIdx]. + au2TxRangeAmpduCnt[11], + g_arMibInfo[ucDbdcIdx]. + au2TxRangeAmpduCnt[12], + g_arMibInfo[ucDbdcIdx]. + au2TxRangeAmpduCnt[13], + g_arMibInfo[ucDbdcIdx]. + au2TxRangeAmpduCnt[14], + g_arMibInfo[ucDbdcIdx]. + au2TxRangeAmpduCnt[15]); + + if (!prAdapter->rWifiVar.fgDbDcModeEn) + break; + } + } + } + + kalMemZero(g_arMibInfo, sizeof(g_arMibInfo)); + + return i4BytesWritten; +} + +#ifdef CFG_SUPPORT_LINK_QUALITY_MONITOR +int connac2x_get_rx_rate_info(IN struct ADAPTER *prAdapter, + OUT uint32_t *pu4Rate, OUT uint32_t *pu4Nss, + OUT uint32_t *pu4RxMode, OUT uint32_t *pu4FrMode, + OUT uint32_t *pu4Sgi) +{ + struct STA_RECORD *prStaRec; + uint32_t rxmode = 0, rate = 0, frmode = 0, sgi = 0, nsts = 0; + uint32_t groupid = 0, stbc = 0, nss = 0; + uint32_t u4RxVector0 = 0, u4RxVector1 = 0, u4RxVector2 = 0; + uint8_t ucWlanIdx, ucStaIdx; + + if ((!pu4Rate) || (!pu4Nss) || (!pu4RxMode) || (!pu4FrMode) || + (!pu4Sgi)) + return -1; + + prStaRec = aisGetStaRecOfAP(prAdapter, AIS_DEFAULT_INDEX); + if (prStaRec) { + ucWlanIdx = prStaRec->ucWlanIndex; + } else { + DBGLOG(SW4, ERROR, "prStaRecOfAP is null\n"); + return -1; + } + + if (wlanGetStaIdxByWlanIdx(prAdapter, ucWlanIdx, &ucStaIdx) == + WLAN_STATUS_SUCCESS) { + u4RxVector0 = prAdapter->arStaRec[ucStaIdx].u4RxVector0; + u4RxVector1 = prAdapter->arStaRec[ucStaIdx].u4RxVector1; + u4RxVector2 = prAdapter->arStaRec[ucStaIdx].u4RxVector2; + if ((u4RxVector0 == 0) || (u4RxVector1 == 0) || + (u4RxVector2 == 0)) { + DBGLOG(SW4, WARN, "RxVector1 or RxVector2 is 0\n"); + return -1; + } + } else { + DBGLOG(SW4, ERROR, "wlanGetStaIdxByWlanIdx fail\n"); + return -1; + } + + /* P-RXV1 */ + rate = (u4RxVector0 & CONNAC2X_RX_VT_RX_RATE_MASK) + >> CONNAC2X_RX_VT_RX_RATE_OFFSET; + nsts = ((u4RxVector0 & CONNAC2X_RX_VT_NSTS_MASK) + >> CONNAC2X_RX_VT_NSTS_OFFSET); + + /* C-B-0 */ + rxmode = (u4RxVector1 & CONNAC2X_RX_VT_RX_MODE_MASK) + >> CONNAC2X_RX_VT_RX_MODE_OFFSET; + frmode = (u4RxVector1 & CONNAC2X_RX_VT_FR_MODE_MASK) + >> CONNAC2X_RX_VT_FR_MODE_OFFSET; + sgi = (u4RxVector1 & CONNAC2X_RX_VT_SHORT_GI_MASK) + >> CONNAC2X_RX_VT_SHORT_GI_OFFSET; + stbc = (u4RxVector1 & CONNAC2X_RX_VT_STBC_MASK) + >> CONNAC2X_RX_VT_STBC_OFFSET; + /* C-B-1 */ + groupid = (u4RxVector2 & CONNAC2X_RX_VT_GROUP_ID_MASK) + >> CONNAC2X_RX_VT_GROUP_ID_OFFSET; + + /* Since NSTS gets from RXRPT, always plus one */ + nsts += 1; + nss = stbc ? (nsts >> 1) : nsts; + + if (frmode >= 4) { + DBGLOG(SW4, ERROR, "frmode error: %u\n", frmode); + return -1; + } + + *pu4Rate = rate; + *pu4Nss = nss; + *pu4RxMode = rxmode; + *pu4FrMode = frmode; + *pu4Sgi = sgi; + + DBGLOG(SW4, TRACE, + "rxmode=[%u], rate=[%u], bw=[%u], sgi=[%u], nss=[%u]\n", + rxmode, rate, frmode, sgi, nss + ); + + return 0; +} +#endif + +#endif /* CFG_SUPPORT_CONNAC2X */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/common/fw_dl.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/common/fw_dl.c new file mode 100644 index 0000000000000000000000000000000000000000..e72432306fe2f753cbb4b95730865445dda28848 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/common/fw_dl.c @@ -0,0 +1,2532 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/*! \file fw_dl.c + */ + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#if CFG_ENABLE_FW_DOWNLOAD +uint32_t wlanGetDataMode(IN struct ADAPTER *prAdapter, + IN enum ENUM_IMG_DL_IDX_T eDlIdx, IN uint8_t ucFeatureSet) +{ + uint32_t u4DataMode = 0; + + if (ucFeatureSet & FW_FEATURE_SET_ENCRY) { + u4DataMode |= DOWNLOAD_CONFIG_RESET_OPTION; + u4DataMode |= (ucFeatureSet & + FW_FEATURE_SET_KEY_MASK); + u4DataMode |= DOWNLOAD_CONFIG_ENCRYPTION_MODE; + if (ucFeatureSet & FW_FEATURE_ENCRY_MODE) + u4DataMode |= DOWNLOAD_CONFIG_ENCRY_MODE_SEL; + } + + if (eDlIdx == IMG_DL_IDX_CR4_FW) + u4DataMode |= DOWNLOAD_CONFIG_WORKING_PDA_OPTION; + +#if CFG_ENABLE_FW_DOWNLOAD_ACK + u4DataMode |= DOWNLOAD_CONFIG_ACK_OPTION; /* ACK needed */ +#endif + return u4DataMode; +} + +void wlanGetHarvardFwInfo(IN struct ADAPTER *prAdapter, + IN uint8_t u4SecIdx, IN enum ENUM_IMG_DL_IDX_T eDlIdx, + OUT uint32_t *pu4Addr, OUT uint32_t *pu4Len, + OUT uint32_t *pu4DataMode, OUT u_int8_t *pfgIsEMIDownload, + OUT u_int8_t *pfgIsNotDownload) +{ + struct TAILER_FORMAT_T *prTailer; + + if (eDlIdx == IMG_DL_IDX_N9_FW) + prTailer = &prAdapter->rVerInfo.rN9tailer[u4SecIdx]; + else + prTailer = &prAdapter->rVerInfo.rCR4tailer[u4SecIdx]; + + *pu4Addr = prTailer->addr; + *pu4Len = (prTailer->len + LEN_4_BYTE_CRC); + *pu4DataMode = wlanGetDataMode(prAdapter, eDlIdx, + prTailer->feature_set); + *pfgIsEMIDownload = FALSE; + *pfgIsNotDownload = FALSE; +} + +void wlanGetConnacFwInfo(IN struct ADAPTER *prAdapter, + IN uint8_t u4SecIdx, IN enum ENUM_IMG_DL_IDX_T eDlIdx, + OUT uint32_t *pu4Addr, OUT uint32_t *pu4Len, + OUT uint32_t *pu4DataMode, OUT u_int8_t *pfgIsEMIDownload, + OUT u_int8_t *pfgIsNotDownload) +{ + struct TAILER_REGION_FORMAT_T *prTailer = + &prAdapter->rVerInfo.rRegionTailers[u4SecIdx]; + + *pu4Addr = prTailer->u4Addr; + *pu4Len = prTailer->u4Len; + *pu4DataMode = wlanGetDataMode(prAdapter, eDlIdx, + prTailer->ucFeatureSet); + *pfgIsEMIDownload = prTailer->ucFeatureSet & + DOWNLOAD_CONFIG_EMI; + *pfgIsNotDownload = prTailer->ucFeatureSet & + FW_FEATURE_NOT_DOWNLOAD; +} + +#if CFG_SUPPORT_COMPRESSION_FW_OPTION +void wlanImageSectionGetCompressFwInfo(IN struct ADAPTER + *prAdapter, IN void *pvFwImageMapFile, + IN uint32_t u4FwImageFileLength, IN uint8_t ucTotSecNum, + IN uint8_t ucCurSecNum, IN enum ENUM_IMG_DL_IDX_T eDlIdx, + OUT uint32_t *pu4Addr, OUT uint32_t *pu4Len, + OUT uint32_t *pu4DataMode, OUT uint32_t *pu4BlockSize, + OUT uint32_t *pu4CRC, OUT uint32_t *pu4UncompressedLength) +{ + struct FW_IMAGE_TAILER_T_2 *prFwHead; + struct TAILER_FORMAT_T_2 *prTailer; + uint8_t aucBuf[32]; + + prFwHead = (struct FW_IMAGE_TAILER_T_2 *) + (pvFwImageMapFile + u4FwImageFileLength - sizeof( + struct FW_IMAGE_TAILER_T_2)); + if (ucTotSecNum == 1) + prTailer = &prFwHead->dlm_info; + else + prTailer = &prFwHead->ilm_info; + + prTailer = &prTailer[ucCurSecNum]; + + *pu4Addr = prTailer->addr; + *pu4Len = (prTailer->len); + *pu4BlockSize = (prTailer->block_size); + *pu4CRC = (prTailer->crc); + *pu4UncompressedLength = (prTailer->real_size); + *pu4DataMode = wlanGetDataMode(prAdapter, eDlIdx, + prTailer->feature_set); + + /* Dump image information */ + if (ucCurSecNum == 0) { + DBGLOG(INIT, INFO, + "%s INFO: chip_info[%u:E%u] feature[0x%02X]\n", + (eDlIdx == IMG_DL_IDX_N9_FW) ? "N9" : "CR4", + prTailer->chip_info, + prTailer->eco_code, prTailer->feature_set); + kalMemZero(aucBuf, 32); + kalStrnCpy(aucBuf, prTailer->ram_version, + sizeof(prTailer->ram_version)); + DBGLOG(INIT, INFO, "date[%s] version[%s]\n", + prTailer->ram_built_date, aucBuf); + } + /* Backup to FW version info */ + if (eDlIdx == IMG_DL_IDX_N9_FW) { + kalMemCopy(&prAdapter->rVerInfo.rN9Compressedtailer, + prTailer, sizeof(struct TAILER_FORMAT_T_2)); + prAdapter->rVerInfo.fgIsN9CompressedFW = TRUE; + } else { + kalMemCopy(&prAdapter->rVerInfo.rCR4Compressedtailer, + prTailer, sizeof(struct TAILER_FORMAT_T_2)); + prAdapter->rVerInfo.fgIsCR4CompressedFW = TRUE; + } +} +#endif + +void wlanImageSectionGetPatchInfo(IN struct ADAPTER + *prAdapter, + IN void *pvFwImageMapFile, IN uint32_t u4FwImageFileLength, + OUT uint32_t *pu4StartOffset, OUT uint32_t *pu4Addr, + OUT uint32_t *pu4Len, + OUT uint32_t *pu4DataMode) +{ + struct PATCH_FORMAT_T *prPatchFormat; + uint8_t aucBuffer[32]; + struct mt66xx_chip_info *prChipInfo = prAdapter->chip_info; + + prPatchFormat = (struct PATCH_FORMAT_T *) pvFwImageMapFile; + + *pu4StartOffset = offsetof(struct PATCH_FORMAT_T, + ucPatchImage); + *pu4Addr = prChipInfo->patch_addr; + *pu4Len = u4FwImageFileLength - offsetof(struct + PATCH_FORMAT_T, ucPatchImage); + *pu4DataMode = wlanGetDataMode(prAdapter, IMG_DL_IDX_PATCH, + 0); + + /* Dump image information */ + kalMemZero(aucBuffer, 32); + kalStrnCpy(aucBuffer, prPatchFormat->aucPlatform, 4); + DBGLOG(INIT, INFO, + "PATCH INFO: platform[%s] HW/SW ver[0x%04X] ver[0x%04X]\n", + aucBuffer, prPatchFormat->u4SwHwVersion, + prPatchFormat->u4PatchVersion); + + kalStrnCpy(aucBuffer, prPatchFormat->aucBuildDate, 16); + DBGLOG(INIT, INFO, "date[%s]\n", aucBuffer); + + /* Backup to FW version info */ + kalMemCopy(&prAdapter->rVerInfo.rPatchHeader, prPatchFormat, + sizeof(struct PATCH_FORMAT_T)); +} + +void wlanImageSectionGetPatchInfoV2(IN struct ADAPTER + *prAdapter, + IN void *pvFwImageMapFile, IN uint32_t u4FwImageFileLength, + OUT uint32_t *pu4DataMode, + struct patch_dl_target *target) +{ + struct PATCH_FORMAT_V2_T *prPatchFormat; + uint8_t aucBuffer[32]; + struct PATCH_GLO_DESC *glo_desc; + struct PATCH_SEC_MAP *sec_map; + uint8_t *img_ptr; + uint32_t num_of_region, i; + + /* patch header */ + img_ptr = pvFwImageMapFile; + prPatchFormat = (struct PATCH_FORMAT_V2_T *)img_ptr; + + /* Dump image information */ + kalMemZero(aucBuffer, 32); + kalStrnCpy(aucBuffer, prPatchFormat->aucPlatform, 4); + DBGLOG(INIT, INFO, + "PATCH INFO: platform[%s] HW/SW ver[0x%04X] ver[0x%04X]\n", + aucBuffer, prPatchFormat->u4SwHwVersion, + prPatchFormat->u4PatchVersion); + + kalStrnCpy(aucBuffer, prPatchFormat->aucBuildDate, 16); + DBGLOG(INIT, INFO, "date[%s]\n", aucBuffer); + + /* Backup to FW version info */ + kalMemCopy(&prAdapter->rVerInfo.rPatchHeader, prPatchFormat, + sizeof(struct PATCH_FORMAT_T)); + + /* global descriptor */ + img_ptr += sizeof(struct PATCH_FORMAT_V2_T); + glo_desc = (struct PATCH_GLO_DESC *)img_ptr; + num_of_region = be2cpu32(glo_desc->section_num); + DBGLOG(INIT, INFO, + "\tPatch ver: 0x%x, Section num: 0x%x, subsys: 0x%x\n", + glo_desc->patch_ver, + num_of_region, + be2cpu32(glo_desc->subsys)); + + if (num_of_region < 0) { + DBGLOG(INIT, WARN, "parse patch failed! num_of_region < 0.\n"); + return; + } + + /* section map */ + img_ptr += sizeof(struct PATCH_GLO_DESC); + + target->num_of_region = num_of_region; + target->patch_region = (struct patch_dl_buf *)kalMemAlloc( + num_of_region * sizeof(struct patch_dl_buf), PHY_MEM_TYPE); + + if (!target->patch_region) { + DBGLOG(INIT, WARN, + "parse patch failed!No memory to allocate.\n"); + return; + } + + for (i = 0; i < num_of_region; i++) { + struct patch_dl_buf *region; + uint32_t section_type; + + region = &target->patch_region[i]; + sec_map = (struct PATCH_SEC_MAP *)img_ptr; + img_ptr += sizeof(struct PATCH_SEC_MAP); + + section_type = be2cpu32(sec_map->section_type); + DBGLOG(INIT, INFO, + "\tSection %d: type = 0x%x, offset = 0x%x, size = 0x%x\n", + i, section_type, be2cpu32(sec_map->section_offset), + be2cpu32(sec_map->section_size)); + + if ((section_type & PATCH_SEC_TYPE_MASK) == + PATCH_SEC_TYPE_BIN_INFO) { + region->img_dest_addr = + be2cpu32(sec_map->bin_info_spec.dl_addr); + region->img_size = + be2cpu32(sec_map->bin_info_spec.dl_size); + region->img_ptr = pvFwImageMapFile + + be2cpu32(sec_map->section_offset); + + DBGLOG(INIT, INFO, + "\tTarget address: 0x%x, length: 0x%x\n", + region->img_dest_addr, region->img_size); + } else { + region->img_ptr = NULL; + DBGLOG(INIT, INFO, "\tNot binary\n"); + } + } + *pu4DataMode = wlanGetDataMode(prAdapter, IMG_DL_IDX_PATCH, 0); +} + +uint32_t wlanDownloadSection(IN struct ADAPTER *prAdapter, + IN uint32_t u4Addr, IN uint32_t u4Len, + IN uint32_t u4DataMode, IN uint8_t *pucStartPtr, + IN enum ENUM_IMG_DL_IDX_T eDlIdx) +{ + uint32_t u4ImgSecSize, u4Offset; + uint8_t *pucSecBuf; + + if (wlanImageSectionConfig(prAdapter, u4Addr, u4Len, + u4DataMode, eDlIdx) != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, ERROR, + "Firmware download configuration failed!\n"); + return WLAN_STATUS_FAILURE; + } + + for (u4Offset = 0; u4Offset < u4Len; + u4Offset += CMD_PKT_SIZE_FOR_IMAGE) { + if (u4Offset + CMD_PKT_SIZE_FOR_IMAGE < u4Len) + u4ImgSecSize = CMD_PKT_SIZE_FOR_IMAGE; + else + u4ImgSecSize = u4Len - u4Offset; + + pucSecBuf = (uint8_t *) pucStartPtr + u4Offset; + if (wlanImageSectionDownload(prAdapter, u4ImgSecSize, + pucSecBuf) != + WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, ERROR, + "Firmware scatter download failed!\n"); + return WLAN_STATUS_FAILURE; + } + } + + return WLAN_STATUS_SUCCESS; +} + +uint32_t wlanDownloadSectionV2(IN struct ADAPTER *prAdapter, + IN uint32_t u4DataMode, + IN enum ENUM_IMG_DL_IDX_T eDlIdx, + struct patch_dl_target *target) +{ + uint32_t u4ImgSecSize, u4Offset; + uint8_t *pucSecBuf; + uint32_t num_of_region, i; + uint32_t u4Status = WLAN_STATUS_SUCCESS; + + num_of_region = target->num_of_region; + if (num_of_region < 0) { + DBGLOG(INIT, ERROR, + "Firmware download num_of_region < 0 !\n"); + u4Status = WLAN_STATUS_FAILURE; + goto out; + } + + + for (i = 0; i < num_of_region; i++) { + struct patch_dl_buf *region; + + region = &target->patch_region[i]; + if (region->img_ptr == NULL) + continue; + + /* 2. config PDA */ + if (wlanImageSectionConfig(prAdapter, region->img_dest_addr, + region->img_size, u4DataMode, eDlIdx) != + WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, ERROR, + "Firmware download configuration failed!\n"); + u4Status = WLAN_STATUS_FAILURE; + goto out; + } + + /* 3. image scatter */ + for (u4Offset = 0; u4Offset < region->img_size; + u4Offset += CMD_PKT_SIZE_FOR_IMAGE) { + if (u4Offset + CMD_PKT_SIZE_FOR_IMAGE < + region->img_size) + u4ImgSecSize = CMD_PKT_SIZE_FOR_IMAGE; + else + u4ImgSecSize = region->img_size - u4Offset; + + pucSecBuf = (uint8_t *) region->img_ptr + u4Offset; + if (wlanImageSectionDownload(prAdapter, u4ImgSecSize, + pucSecBuf) != + WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, ERROR, + "Firmware scatter download failed!\n"); + return WLAN_STATUS_FAILURE; + } + } + } + +out: + kalMemFree(target->patch_region, PHY_MEM_TYPE, + num_of_region * sizeof(struct patch_dl_buf)); + target->patch_region = NULL; + target->num_of_region = 0; + return u4Status; +} + +uint32_t wlanDownloadEMISection(IN struct ADAPTER + *prAdapter, IN uint32_t u4DestAddr, + IN uint32_t u4Len, IN uint8_t *pucStartPtr) +{ +#if CFG_MTK_ANDROID_EMI + uint8_t __iomem *pucEmiBaseAddr = NULL; + uint32_t u4Offset = u4DestAddr & WIFI_EMI_ADDR_MASK; + + if (!gConEmiPhyBaseFinal) { + DBGLOG(INIT, ERROR, + "Consys emi memory address gConEmiPhyBaseFinal invalid\n"); + return WLAN_STATUS_FAILURE; + } + + request_mem_region(gConEmiPhyBaseFinal, gConEmiSizeFinal, "WIFI-EMI"); + kalSetEmiMpuProtection(gConEmiPhyBaseFinal, false); + pucEmiBaseAddr = + ioremap_nocache(gConEmiPhyBaseFinal, gConEmiSizeFinal); + DBGLOG_LIMITED(INIT, INFO, + "EmiPhyBase:0x%llx offset:0x%x, ioremap region 0x%lX @ 0x%lX\n", + (uint64_t)gConEmiPhyBaseFinal, u4Offset, gConEmiSizeFinal, + pucEmiBaseAddr); + if (!pucEmiBaseAddr) { + DBGLOG(INIT, ERROR, "ioremap failed\n"); + return WLAN_STATUS_FAILURE; + } + + kalMemCopy((pucEmiBaseAddr + u4Offset), pucStartPtr, u4Len); + + kalSetEmiMpuProtection(gConEmiPhyBaseFinal, true); + iounmap(pucEmiBaseAddr); + release_mem_region(gConEmiPhyBaseFinal, gConEmiSizeFinal); +#endif /* CFG_MTK_ANDROID_EMI */ + return WLAN_STATUS_SUCCESS; +} + +#if CFG_SUPPORT_COMPRESSION_FW_OPTION +u_int8_t wlanImageSectionCheckFwCompressInfo( + IN struct ADAPTER *prAdapter, + IN void *pvFwImageMapFile, IN uint32_t u4FwImageFileLength, + IN enum ENUM_IMG_DL_IDX_T eDlIdx) +{ + uint8_t ucCompression; + struct FW_IMAGE_TAILER_CHECK *prCheckInfo; + + if (eDlIdx == IMG_DL_IDX_PATCH) + return FALSE; + + prCheckInfo = (struct FW_IMAGE_TAILER_CHECK *) + (pvFwImageMapFile + u4FwImageFileLength - sizeof( + struct FW_IMAGE_TAILER_CHECK)); + DBGLOG(INIT, INFO, "feature_set %d\n", + prCheckInfo->feature_set); + ucCompression = (uint8_t)((prCheckInfo->feature_set & + COMPRESSION_OPTION_MASK) + >> COMPRESSION_OPTION_OFFSET); + DBGLOG(INIT, INFO, "Compressed Check INFORMATION %d\n", + ucCompression); + if (ucCompression == 1) { + DBGLOG(INIT, INFO, "Compressed FW\n"); + return TRUE; + } + return FALSE; +} + +uint32_t wlanCompressedImageSectionDownloadStage( + IN struct ADAPTER *prAdapter, IN void *pvFwImageMapFile, + IN uint32_t u4FwImageFileLength, IN uint8_t ucSectionNumber, + IN enum ENUM_IMG_DL_IDX_T eDlIdx, + OUT uint8_t *pucIsCompressed, + OUT struct INIT_CMD_WIFI_DECOMPRESSION_START *prFwImageInFo) +{ + uint32_t i; + int32_t i4TotalLen; + uint32_t u4FileOffset = 0; + uint32_t u4StartOffset = 0; + uint32_t u4DataMode = 0; + uint32_t u4Addr, u4Len, u4BlockSize, u4CRC; + uint32_t u4UnCompressedLength; + uint32_t u4Status = WLAN_STATUS_SUCCESS; + uint8_t *pucStartPtr; + uint32_t u4offset = 0, u4ChunkSize; + /* 3a. parse file header for decision of + * divided firmware download or not + */ + if (wlanImageSectionCheckFwCompressInfo(prAdapter, + pvFwImageMapFile, + u4FwImageFileLength, + eDlIdx) == TRUE) { + for (i = 0; i < ucSectionNumber; ++i) { + wlanImageSectionGetCompressFwInfo(prAdapter, + pvFwImageMapFile, + u4FwImageFileLength, ucSectionNumber, i, eDlIdx, + &u4Addr, &u4Len, &u4DataMode, + &u4BlockSize, &u4CRC, &u4UnCompressedLength); + u4offset = 0; + if (i == 0) { + prFwImageInFo->u4BlockSize = u4BlockSize; + prFwImageInFo->u4Region1Address = u4Addr; + prFwImageInFo->u4Region1CRC = u4CRC; + prFwImageInFo->u4Region1length = + u4UnCompressedLength; + } else { + prFwImageInFo->u4Region2Address = u4Addr; + prFwImageInFo->u4Region2CRC = u4CRC; + prFwImageInFo->u4Region2length = + u4UnCompressedLength; + } + i4TotalLen = u4Len; + DBGLOG(INIT, INFO, + "DL Offset[%u] addr[0x%08x] len[%u] datamode[0x%08x]\n", + u4FileOffset, u4Addr, u4Len, u4DataMode); + DBGLOG(INIT, INFO, "DL BLOCK[%u] COMlen[%u] CRC[%u]\n", + u4BlockSize, u4UnCompressedLength, u4CRC); + pucStartPtr = + (uint8_t *) pvFwImageMapFile + u4StartOffset; + while (i4TotalLen) { + u4ChunkSize = *((unsigned int *)(pucStartPtr + + u4FileOffset)); + u4FileOffset += 4; + DBGLOG(INIT, INFO, + "Downloaded Length %d! Addr %x\n", + i4TotalLen, u4Addr + u4offset); + DBGLOG(INIT, INFO, + "u4ChunkSize Length %d!\n", + u4ChunkSize); + + u4Status = wlanDownloadSection(prAdapter, + u4Addr + u4offset, + u4ChunkSize, + u4DataMode, + pvFwImageMapFile + u4FileOffset, + eDlIdx); + /* escape from loop if any + * pending error occurs + */ + if (u4Status == WLAN_STATUS_FAILURE) + break; + + i4TotalLen -= u4ChunkSize; + u4offset += u4BlockSize; + u4FileOffset += u4ChunkSize; + if (i4TotalLen < 0) { + DBGLOG(INIT, ERROR, + "Firmware scatter download failed!\n"); + u4Status = WLAN_STATUS_FAILURE; + break; + } + } + } + *pucIsCompressed = TRUE; + } else { + u4Status = wlanImageSectionDownloadStage(prAdapter, + pvFwImageMapFile, u4FwImageFileLength, + ucSectionNumber, eDlIdx); + *pucIsCompressed = FALSE; + } + return u4Status; +} +#endif + +uint32_t wlanImageSectionDownloadStage( + IN struct ADAPTER *prAdapter, IN void *pvFwImageMapFile, + IN uint32_t u4FwImageFileLength, IN uint8_t ucSectionNumber, + IN enum ENUM_IMG_DL_IDX_T eDlIdx) +{ + uint32_t u4SecIdx, u4Offset = 0; + uint32_t u4Addr, u4Len, u4DataMode = 0; + u_int8_t fgIsEMIDownload = FALSE; + u_int8_t fgIsNotDownload = FALSE; + uint32_t u4Status = WLAN_STATUS_SUCCESS; + struct mt66xx_chip_info *prChipInfo = prAdapter->chip_info; + struct patch_dl_target target; + struct PATCH_FORMAT_T *prPatchHeader; + struct FWDL_OPS_T *prFwDlOps; + + prFwDlOps = prChipInfo->fw_dl_ops; + + /* 3a. parse file header for decision of + * divided firmware download or not + */ + if (eDlIdx == IMG_DL_IDX_PATCH) { + prPatchHeader = pvFwImageMapFile; + if (prPatchHeader->u4PatchVersion == PATCH_VERSION_MAGIC_NUM) { + wlanImageSectionGetPatchInfoV2(prAdapter, + pvFwImageMapFile, + u4FwImageFileLength, + &u4DataMode, + &target); + DBGLOG_LIMITED(INIT, INFO, + "FormatV2 num_of_regoin[%d] datamode[0x%08x]\n", + target.num_of_region, u4DataMode); + } else { + wlanImageSectionGetPatchInfo(prAdapter, + pvFwImageMapFile, + u4FwImageFileLength, + &u4Offset, &u4Addr, + &u4Len, &u4DataMode); + DBGLOG_LIMITED(INIT, INFO, + "FormatV1 DL Offset[%u] addr[0x%08x] len[%u] datamode[0x%08x]\n", + u4Offset, u4Addr, u4Len, u4DataMode); + } + + if (prPatchHeader->u4PatchVersion == PATCH_VERSION_MAGIC_NUM) + u4Status = wlanDownloadSectionV2(prAdapter, + u4DataMode, eDlIdx, &target); + else +/* For dynamic memory map::Begin */ +#if (CFG_DOWNLOAD_DYN_MEMORY_MAP == 1) + u4Status = prFwDlOps->downloadByDynMemMap( + prAdapter, u4Addr, u4Len, + pvFwImageMapFile + + u4Offset, + eDlIdx); +#else + u4Status = wlanDownloadSection( + prAdapter, + u4Addr, + u4Len, + u4DataMode, + pvFwImageMapFile + + u4Offset, + eDlIdx); +#endif +/* For dynamic memory map::End */ + } else { + for (u4SecIdx = 0; u4SecIdx < ucSectionNumber; + u4SecIdx++, u4Offset += u4Len) { + prChipInfo->fw_dl_ops->getFwInfo(prAdapter, u4SecIdx, + eDlIdx, &u4Addr, + &u4Len, &u4DataMode, &fgIsEMIDownload, + &fgIsNotDownload); + + DBGLOG(INIT, TRACE, + "DL Offset[%u] addr[0x%08x] len[%u] datamode[0x%08x]\n", + u4Offset, u4Addr, u4Len, u4DataMode); + + if (fgIsNotDownload) + continue; + else if (fgIsEMIDownload) + u4Status = wlanDownloadEMISection(prAdapter, + u4Addr, u4Len, + pvFwImageMapFile + u4Offset); +/* For dynamic memory map:: Begin */ +#if (CFG_DOWNLOAD_DYN_MEMORY_MAP == 1) + else if ((u4DataMode & + DOWNLOAD_CONFIG_ENCRYPTION_MODE) == 0) { + /* Non-encrypted F/W region, + * use dynamic memory mapping for download + */ + u4Status = prFwDlOps->downloadByDynMemMap( + prAdapter, + u4Addr, + u4Len, + pvFwImageMapFile + u4Offset, + eDlIdx); + } +#endif +/* For dynamic memory map:: End */ + else + u4Status = wlanDownloadSection(prAdapter, + u4Addr, u4Len, + u4DataMode, + pvFwImageMapFile + u4Offset, eDlIdx); + + /* escape from loop if any pending error occurs */ + if (u4Status == WLAN_STATUS_FAILURE) + break; + } + } + return u4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called to confirm the status of + * previously patch semaphore control + * + * @param prAdapter Pointer to the Adapter structure. + * ucCmdSeqNum Sequence number of previous firmware scatter + * + * @return WLAN_STATUS_SUCCESS + * WLAN_STATUS_FAILURE + */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanPatchRecvSemaResp(IN struct ADAPTER *prAdapter, + IN uint8_t ucCmdSeqNum, OUT uint8_t *pucPatchStatus) +{ + struct mt66xx_chip_info *prChipInfo; + uint8_t *aucBuffer; + uint32_t u4EventSize; + struct INIT_WIFI_EVENT *prInitEvent; + struct INIT_EVENT_CMD_RESULT *prEventCmdResult; + uint32_t u4RxPktLength; + + ASSERT(prAdapter); + prChipInfo = prAdapter->chip_info; + + if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE + || fgIsBusAccessFailed == TRUE) + return WLAN_STATUS_FAILURE; + + u4EventSize = prChipInfo->rxd_size + prChipInfo->init_event_size + + sizeof(struct INIT_EVENT_CMD_RESULT); + aucBuffer = kalMemAlloc(u4EventSize, PHY_MEM_TYPE); + if (aucBuffer == NULL) { + DBGLOG(INIT, ERROR, "Alloc CMD buffer failed\n"); + return WLAN_STATUS_FAILURE; + } + + if (nicRxWaitResponse(prAdapter, 0, aucBuffer, u4EventSize, + &u4RxPktLength) != WLAN_STATUS_SUCCESS) { + + DBGLOG(INIT, WARN, "Wait patch semaphore response fail\n"); + kalMemFree(aucBuffer, PHY_MEM_TYPE, u4EventSize); + return WLAN_STATUS_FAILURE; + } + + prInitEvent = (struct INIT_WIFI_EVENT *) + (aucBuffer + prChipInfo->rxd_size); + if (prInitEvent == NULL) { + DBGLOG(INIT, ERROR, "prInitEvent is NULL\n"); + kalMemFree(aucBuffer, PHY_MEM_TYPE, u4EventSize); + return WLAN_STATUS_FAILURE; + } + if (prInitEvent->ucEID != INIT_EVENT_ID_PATCH_SEMA_CTRL) { + DBGLOG(INIT, WARN, "Unexpected EVENT ID, get 0x%0x\n", + prInitEvent->ucEID); + kalMemFree(aucBuffer, PHY_MEM_TYPE, u4EventSize); + return WLAN_STATUS_FAILURE; + } + + if (prInitEvent->ucSeqNum != ucCmdSeqNum) { + DBGLOG(INIT, WARN, "Unexpected SeqNum %d, %d\n", + ucCmdSeqNum, prInitEvent->ucSeqNum); + kalMemFree(aucBuffer, PHY_MEM_TYPE, u4EventSize); + return WLAN_STATUS_FAILURE; + } + + prEventCmdResult = (struct INIT_EVENT_CMD_RESULT *) + prInitEvent->aucBuffer; + + *pucPatchStatus = prEventCmdResult->ucStatus; + + kalMemFree(aucBuffer, PHY_MEM_TYPE, u4EventSize); + + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called to check the patch semaphore control. + * + * @param prAdapter Pointer to the Adapter structure. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanPatchSendSemaControl(IN struct ADAPTER + *prAdapter, OUT uint8_t *pucSeqNum) +{ + struct mt66xx_chip_info *prChipInfo; + struct CMD_INFO *prCmdInfo; + uint32_t u4Status = WLAN_STATUS_SUCCESS; + struct INIT_CMD_PATCH_SEMA_CONTROL *prPatchSemaControl; + + ASSERT(prAdapter); + prChipInfo = prAdapter->chip_info; + + DEBUGFUNC("wlanImagePatchSemaphoreCheck"); + + /* 1. Allocate CMD Info Packet and its Buffer. */ + prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, + sizeof(struct INIT_HIF_TX_HEADER) + + sizeof(struct INIT_HIF_TX_HEADER_PENDING_FOR_HW_32BYTES) + + sizeof(struct INIT_CMD_PATCH_SEMA_CONTROL)); + + if (!prCmdInfo) { + DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); + return WLAN_STATUS_FAILURE; + } + + prCmdInfo->u2InfoBufLen = sizeof(struct INIT_HIF_TX_HEADER) + + sizeof(struct INIT_HIF_TX_HEADER_PENDING_FOR_HW_32BYTES) + + sizeof(struct INIT_CMD_PATCH_SEMA_CONTROL); + + NIC_FILL_CMD_TX_HDR(prAdapter, + prCmdInfo->pucInfoBuffer, + prCmdInfo->u2InfoBufLen, + INIT_CMD_ID_PATCH_SEMAPHORE_CONTROL, + INIT_CMD_PDA_PACKET_TYPE_ID, + pucSeqNum, FALSE, + (void **)&prPatchSemaControl, TRUE, 0, S2D_INDEX_CMD_H2N); + + kalMemZero(prPatchSemaControl, + sizeof(struct INIT_CMD_PATCH_SEMA_CONTROL)); + + /* Setup DOWNLOAD_BUF */ + kalMemZero(prPatchSemaControl, + sizeof(struct INIT_CMD_PATCH_SEMA_CONTROL)); + prPatchSemaControl->ucGetSemaphore = PATCH_GET_SEMA_CONTROL; + + /* 4. Send FW_Download command */ + if (nicTxInitCmd(prAdapter, prCmdInfo, + prChipInfo->u2TxInitCmdPort) != WLAN_STATUS_SUCCESS) { + u4Status = WLAN_STATUS_FAILURE; + DBGLOG(INIT, ERROR, + "Fail to transmit image download command\n"); + } + /* 5. Free CMD Info Packet. */ + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + + return u4Status; +} + +u_int8_t wlanPatchIsDownloaded(IN struct ADAPTER *prAdapter) +{ + uint8_t ucSeqNum, ucPatchStatus; + uint32_t rStatus; + uint32_t u4Count; + + ucPatchStatus = PATCH_STATUS_NO_SEMA_NEED_PATCH; + u4Count = 0; + + while (ucPatchStatus == PATCH_STATUS_NO_SEMA_NEED_PATCH) { + if (u4Count) + kalMdelay(100); + + rStatus = wlanPatchSendSemaControl(prAdapter, &ucSeqNum); + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, WARN, + "Send patch SEMA control CMD failed!!\n"); + break; + } + + rStatus = wlanPatchRecvSemaResp(prAdapter, ucSeqNum, + &ucPatchStatus); + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, WARN, + "Recv patch SEMA control EVT failed!!\n"); + break; + } + + u4Count++; + + if (u4Count > 50) { + DBGLOG(INIT, WARN, "Patch status check timeout!!\n"); + break; + } + } + + if (ucPatchStatus == PATCH_STATUS_NO_NEED_TO_PATCH) + return TRUE; + else + return FALSE; +} + +uint32_t wlanPatchSendComplete(IN struct ADAPTER *prAdapter) +{ + struct CMD_INFO *prCmdInfo; + uint8_t ucTC, ucCmdSeqNum; + uint32_t u4Status = WLAN_STATUS_SUCCESS; + struct mt66xx_chip_info *prChipInfo; + struct INIT_CMD_PATCH_FINISH *prPatchFinish; + + ASSERT(prAdapter); + prChipInfo = prAdapter->chip_info; + + /* 1. Allocate CMD Info Packet and its Buffer. */ + prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, + sizeof(struct INIT_HIF_TX_HEADER) + + sizeof(struct INIT_HIF_TX_HEADER_PENDING_FOR_HW_32BYTES) + + sizeof(struct INIT_CMD_PATCH_FINISH)); + + if (!prCmdInfo) { + DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); + return WLAN_STATUS_FAILURE; + } + + kalMemZero(prCmdInfo->pucInfoBuffer, + sizeof(struct INIT_HIF_TX_HEADER) + + sizeof(struct INIT_HIF_TX_HEADER_PENDING_FOR_HW_32BYTES) + + sizeof(struct INIT_CMD_PATCH_FINISH)); + prCmdInfo->u2InfoBufLen = sizeof(struct INIT_HIF_TX_HEADER) + + sizeof(struct INIT_HIF_TX_HEADER_PENDING_FOR_HW_32BYTES) + + sizeof(struct INIT_CMD_PATCH_FINISH); + +#if (CFG_USE_TC4_RESOURCE_FOR_INIT_CMD == 1) + /* 2. Always use TC4 (TC4 as CPU) */ + ucTC = TC4_INDEX; +#else + /* 2. Use TC0's resource to send patch finish command. + * Only TC0 is allowed because SDIO HW always reports + * MCU's TXQ_CNT at TXQ0_CNT in CR4 architecutre) + */ + ucTC = TC0_INDEX; +#endif + + NIC_FILL_CMD_TX_HDR(prAdapter, + prCmdInfo->pucInfoBuffer, + prCmdInfo->u2InfoBufLen, + INIT_CMD_ID_PATCH_FINISH, + INIT_CMD_PACKET_TYPE_ID, + &ucCmdSeqNum, + FALSE, + (void **)&prPatchFinish, TRUE, 0, S2D_INDEX_CMD_H2N); + + prPatchFinish->ucCheckCrc = 0; + + /* 5. Seend WIFI start command */ + while (1) { + /* 5.1 Acquire TX Resource */ + if (nicTxAcquireResource(prAdapter, ucTC, + nicTxGetPageCount(prAdapter, + prCmdInfo->u2InfoBufLen, TRUE), + TRUE) == WLAN_STATUS_RESOURCES) { + if (nicTxPollingResource(prAdapter, + ucTC) != WLAN_STATUS_SUCCESS) { + u4Status = WLAN_STATUS_FAILURE; + DBGLOG(INIT, ERROR, + "Fail to get TX resource return within timeout\n"); + goto exit; + } + continue; + } + /* 5.2 Send CMD Info Packet */ + if (nicTxInitCmd(prAdapter, prCmdInfo, + prChipInfo->u2TxInitCmdPort) != + WLAN_STATUS_SUCCESS) { + u4Status = WLAN_STATUS_FAILURE; + DBGLOG(INIT, ERROR, + "Fail to transmit WIFI start command\n"); + goto exit; + } + + break; + }; + + DBGLOG(INIT, INFO, + "PATCH FINISH CMD send, waiting for RSP\n"); + + /* kalMdelay(10000); */ + + u4Status = wlanConfigWifiFuncStatus(prAdapter, ucCmdSeqNum); + + if (u4Status != WLAN_STATUS_SUCCESS) + DBGLOG(INIT, INFO, "PATCH FINISH EVT failed\n"); + else + DBGLOG(INIT, INFO, "PATCH FINISH EVT success!!\n"); + +exit: + /* 6. Free CMD Info Packet. */ + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + + return u4Status; +} + +#if (CFG_DOWNLOAD_DYN_MEMORY_MAP == 1) +uint32_t wlanPatchDynMemMapSendComplete(IN struct ADAPTER *prAdapter) +{ + struct CMD_INFO *prCmdInfo; + uint8_t ucTC, ucCmdSeqNum; + uint32_t u4Status = WLAN_STATUS_SUCCESS; + struct mt66xx_chip_info *prChipInfo; + struct INIT_CMD_PATCH_FINISH *prPatchFinish; + + ASSERT(prAdapter); + prChipInfo = prAdapter->chip_info; + + /* 1. Allocate CMD Info Packet and its Buffer. */ + prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, + sizeof(struct INIT_HIF_TX_HEADER) + + sizeof(struct INIT_HIF_TX_HEADER_PENDING_FOR_HW_32BYTES) + + sizeof(struct INIT_CMD_PATCH_FINISH)); + + if (!prCmdInfo) { + DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); + + return WLAN_STATUS_FAILURE; + } + + kalMemZero(prCmdInfo->pucInfoBuffer, + sizeof(struct INIT_HIF_TX_HEADER) + + sizeof(struct INIT_HIF_TX_HEADER_PENDING_FOR_HW_32BYTES) + + sizeof(struct INIT_CMD_PATCH_FINISH)); + + prCmdInfo->u2InfoBufLen = sizeof(struct INIT_HIF_TX_HEADER) + + sizeof(struct INIT_HIF_TX_HEADER_PENDING_FOR_HW_32BYTES) + + sizeof(struct INIT_CMD_PATCH_FINISH); + +#if (CFG_USE_TC4_RESOURCE_FOR_INIT_CMD == 1) + /* 2. Always use TC4 (TC4 as CPU) */ + ucTC = TC4_INDEX; +#else + /* 2. Use TC0's resource to send patch finish command. + * Only TC0 is allowed because SDIO HW always reports + * MCU's TXQ_CNT at TXQ0_CNT in CR4 architecutre) + */ + ucTC = TC0_INDEX; +#endif + + NIC_FILL_CMD_TX_HDR(prAdapter, + prCmdInfo->pucInfoBuffer, + prCmdInfo->u2InfoBufLen, + INIT_CMD_ID_DYN_MEM_MAP_PATCH_FINISH, + INIT_CMD_PACKET_TYPE_ID, + &ucCmdSeqNum, + FALSE, + (void **)&prPatchFinish, TRUE, 0, S2D_INDEX_CMD_H2N); + + prPatchFinish->ucCheckCrc = 0; + + /* 5. Seend WIFI start command */ + while (1) { + /* 5.1 Acquire TX Resource */ + if (nicTxAcquireResource(prAdapter, ucTC, + nicTxGetPageCount(prAdapter, + prCmdInfo->u2InfoBufLen, TRUE), + TRUE) == WLAN_STATUS_RESOURCES) { + if (nicTxPollingResource(prAdapter, + ucTC) != WLAN_STATUS_SUCCESS) { + u4Status = WLAN_STATUS_FAILURE; + DBGLOG(INIT, ERROR, + "Fail to get TX resource return within timeout\n"); + goto exit; + } + continue; + } + /* 5.2 Send CMD Info Packet */ + if (nicTxInitCmd(prAdapter, prCmdInfo, + prChipInfo->u2TxInitCmdPort) != + WLAN_STATUS_SUCCESS) { + u4Status = WLAN_STATUS_FAILURE; + DBGLOG(INIT, ERROR, + "Fail to transmit WIFI start command\n"); + goto exit; + } + + break; + }; + + DBGLOG(INIT, INFO, + "PATCH FINISH CMD send, waiting for RSP\n"); + + /* kalMdelay(10000); */ + + u4Status = wlanConfigWifiFuncStatus(prAdapter, ucCmdSeqNum); + + if (u4Status != WLAN_STATUS_SUCCESS) + DBGLOG(INIT, INFO, "PATCH FINISH EVT failed\n"); + else + DBGLOG(INIT, INFO, "PATCH FINISH EVT success!!\n"); + +exit: + /* 6. Free CMD Info Packet. */ + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + + return u4Status; +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called to configure FWDL parameters + * + * @param prAdapter Pointer to the Adapter structure. + * u4DestAddr Address of destination address + * u4ImgSecSize Length of the firmware block + * fgReset should be set to TRUE if this is the 1st configuration + * + * @return WLAN_STATUS_SUCCESS + * WLAN_STATUS_FAILURE + */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanImageSectionConfig( + IN struct ADAPTER *prAdapter, + IN uint32_t u4DestAddr, IN uint32_t u4ImgSecSize, + IN uint32_t u4DataMode, + IN enum ENUM_IMG_DL_IDX_T eDlIdx) +{ + struct CMD_INFO *prCmdInfo; + struct INIT_CMD_DOWNLOAD_CONFIG *prInitCmdDownloadConfig; + uint8_t ucTC, ucCmdSeqNum; + uint32_t u4Status = WLAN_STATUS_SUCCESS; + struct mt66xx_chip_info *prChipInfo; + + ASSERT(prAdapter); + prChipInfo = prAdapter->chip_info; + + DEBUGFUNC("wlanImageSectionConfig"); + + if (u4ImgSecSize == 0) + return WLAN_STATUS_SUCCESS; + /* 1. Allocate CMD Info Packet and its Buffer. */ + prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, + sizeof(struct INIT_HIF_TX_HEADER) + + sizeof(struct INIT_HIF_TX_HEADER_PENDING_FOR_HW_32BYTES) + + sizeof(struct INIT_CMD_DOWNLOAD_CONFIG)); + + if (!prCmdInfo) { + DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); + return WLAN_STATUS_FAILURE; + } + + prCmdInfo->u2InfoBufLen = sizeof(struct INIT_HIF_TX_HEADER) + + sizeof(struct INIT_HIF_TX_HEADER_PENDING_FOR_HW_32BYTES) + + sizeof(struct INIT_CMD_DOWNLOAD_CONFIG); + +#if (CFG_USE_TC4_RESOURCE_FOR_INIT_CMD == 1) + /* 2. Use TC4's resource to download image. (TC4 as CPU) */ + ucTC = TC4_INDEX; +#else + /* 2. Use TC0's resource to send init_cmd. + * Only TC0 is allowed because SDIO HW always reports + * MCU's TXQ_CNT at TXQ0_CNT in CR4 architecutre) + */ + ucTC = TC0_INDEX; +#endif + + if (eDlIdx == IMG_DL_IDX_PATCH) { + NIC_FILL_CMD_TX_HDR(prAdapter, + prCmdInfo->pucInfoBuffer, + prCmdInfo->u2InfoBufLen, + INIT_CMD_ID_PATCH_START, + INIT_CMD_PACKET_TYPE_ID, + &ucCmdSeqNum, + FALSE, + (void **)&prInitCmdDownloadConfig, + TRUE, 0, S2D_INDEX_CMD_H2N); + } else { + NIC_FILL_CMD_TX_HDR( + prAdapter, + prCmdInfo->pucInfoBuffer, + prCmdInfo->u2InfoBufLen, + INIT_CMD_ID_DOWNLOAD_CONFIG, + INIT_CMD_PACKET_TYPE_ID, + &ucCmdSeqNum, + FALSE, + (void **)&prInitCmdDownloadConfig, + TRUE, 0, S2D_INDEX_CMD_H2N); + } + + prInitCmdDownloadConfig->u4Address = u4DestAddr; + prInitCmdDownloadConfig->u4Length = u4ImgSecSize; + prInitCmdDownloadConfig->u4DataMode = u4DataMode; + + /* 6. Send FW_Download command */ + while (1) { + /* 6.1 Acquire TX Resource */ + if (nicTxAcquireResource(prAdapter, ucTC, + nicTxGetPageCount(prAdapter, + prCmdInfo->u2InfoBufLen, TRUE), + TRUE) == WLAN_STATUS_RESOURCES) { + if (nicTxPollingResource(prAdapter, + ucTC) != WLAN_STATUS_SUCCESS) { + u4Status = WLAN_STATUS_FAILURE; + DBGLOG(INIT, ERROR, + "Fail to get TX resource return within timeout\n"); + goto exit; + } + continue; + } + /* 6.2 Send CMD Info Packet */ + if (nicTxInitCmd(prAdapter, prCmdInfo, + prChipInfo->u2TxInitCmdPort) != + WLAN_STATUS_SUCCESS) { + u4Status = WLAN_STATUS_FAILURE; + DBGLOG(INIT, ERROR, + "Fail to transmit image download command\n"); + goto exit; + } + + break; + }; + +#if CFG_ENABLE_FW_DOWNLOAD_ACK + /* 7. Wait for INIT_EVENT_ID_CMD_RESULT */ + u4Status = wlanConfigWifiFuncStatus(prAdapter, ucCmdSeqNum); +#endif + +exit: + /* 8. Free CMD Info Packet. */ + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + + return u4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called to download FW image. + * + * @param prAdapter Pointer to the Adapter structure. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanImageSectionDownload(IN struct ADAPTER + *prAdapter, IN uint32_t u4ImgSecSize, + IN uint8_t *pucImgSecBuf) +{ + struct CMD_INFO *prCmdInfo; + uint8_t *prBuf; + uint32_t u4Status = WLAN_STATUS_SUCCESS; + struct mt66xx_chip_info *prChipInfo; + + ASSERT(prAdapter); + ASSERT(pucImgSecBuf); + ASSERT(u4ImgSecSize <= CMD_PKT_SIZE_FOR_IMAGE); + + DEBUGFUNC("wlanImageSectionDownload"); + + prChipInfo = prAdapter->chip_info; + + if (u4ImgSecSize == 0) + return WLAN_STATUS_SUCCESS; + /* 1. Allocate CMD Info Packet and its Buffer. */ + prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, + sizeof(struct INIT_HIF_TX_HEADER) + + sizeof(struct INIT_HIF_TX_HEADER_PENDING_FOR_HW_32BYTES) + + u4ImgSecSize); + + if (!prCmdInfo) { + DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); + return WLAN_STATUS_FAILURE; + } + + /* + * For falcon WFDMA, driver doesn't need to append TXD. + * For old project/talos, + * TXD length will be included in asicFillInitCmdTxd. + */ + prCmdInfo->u2InfoBufLen = (uint16_t) u4ImgSecSize; + + /* 2. Setup common CMD Info Packet */ + NIC_FILL_CMD_TX_HDR(prAdapter, + prCmdInfo->pucInfoBuffer, + prCmdInfo->u2InfoBufLen, + 0, INIT_CMD_PDA_PACKET_TYPE_ID, + NULL, FALSE, (void **)&prBuf, TRUE, 0, S2D_INDEX_CMD_H2N); + + /* 3. Setup DOWNLOAD_BUF */ + kalMemCopy(prBuf, pucImgSecBuf, u4ImgSecSize); + + /* 4. Send FW_Download command */ + if (nicTxInitCmd(prAdapter, prCmdInfo, + prChipInfo->u2TxFwDlPort) != WLAN_STATUS_SUCCESS) { + u4Status = WLAN_STATUS_FAILURE; + DBGLOG(INIT, ERROR, + "Fail to transmit image download command\n"); + } + /* 5. Free CMD Info Packet. */ + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + + return u4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called to confirm previously firmware + * download is done without error + * + * @param prAdapter Pointer to the Adapter structure. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanImageQueryStatus(IN struct ADAPTER *prAdapter) +{ + struct mt66xx_chip_info *prChipInfo; + struct CMD_INFO *prCmdInfo; + uint8_t *aucBuffer; + uint32_t u4EventSize; + uint32_t u4RxPktLength; + struct INIT_WIFI_EVENT *prInitEvent; + struct INIT_EVENT_CMD_RESULT *prEventPendingError; + uint32_t u4Status = WLAN_STATUS_SUCCESS; + uint8_t ucTC, ucCmdSeqNum; + + ASSERT(prAdapter); + prChipInfo = prAdapter->chip_info; + + DEBUGFUNC("wlanImageQueryStatus"); + + /* 1. Allocate CMD Info Packet and it Buffer. */ + prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, + sizeof(struct INIT_HIF_TX_HEADER) + + sizeof(struct INIT_HIF_TX_HEADER_PENDING_FOR_HW_32BYTES)); + + if (!prCmdInfo) { + DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); + return WLAN_STATUS_FAILURE; + } + + u4EventSize = prChipInfo->rxd_size + prChipInfo->init_event_size + + sizeof(struct INIT_EVENT_CMD_RESULT); + aucBuffer = kalMemAlloc(u4EventSize, PHY_MEM_TYPE); + if (aucBuffer == NULL) { + DBGLOG(INIT, ERROR, "Alloc CMD buffer failed\n"); + return WLAN_STATUS_FAILURE; + } + + kalMemZero(prCmdInfo->pucInfoBuffer, + sizeof(struct INIT_HIF_TX_HEADER) + + sizeof(struct INIT_HIF_TX_HEADER_PENDING_FOR_HW_32BYTES)); + prCmdInfo->u2InfoBufLen = sizeof(struct INIT_HIF_TX_HEADER) + + sizeof(struct INIT_HIF_TX_HEADER_PENDING_FOR_HW_32BYTES); + +#if (CFG_USE_TC4_RESOURCE_FOR_INIT_CMD == 1) + /* 2. Always use TC4 */ + ucTC = TC4_INDEX; +#else + /* 2. Use TC0's resource to send init_cmd + * Only TC0 is allowed because SDIO HW always reports + * CPU's TXQ_CNT at TXQ0_CNT in CR4 architecutre) + */ + ucTC = TC0_INDEX; +#endif + + NIC_FILL_CMD_TX_HDR(prAdapter, + prCmdInfo->pucInfoBuffer, + prCmdInfo->u2InfoBufLen, + INIT_CMD_ID_QUERY_PENDING_ERROR, + INIT_CMD_PACKET_TYPE_ID, + &ucCmdSeqNum, FALSE, NULL, TRUE, 0, S2D_INDEX_CMD_H2N); + + /* 5. Send command */ + while (1) { + /* 5.1 Acquire TX Resource */ + if (nicTxAcquireResource(prAdapter, ucTC, + nicTxGetPageCount(prAdapter, + prCmdInfo->u2InfoBufLen, TRUE), + TRUE) == WLAN_STATUS_RESOURCES) { + if (nicTxPollingResource(prAdapter, + ucTC) != WLAN_STATUS_SUCCESS) { + u4Status = WLAN_STATUS_FAILURE; + DBGLOG(INIT, ERROR, + "Fail to get TX resource return within timeout\n"); + break; + } + continue; + + } + /* 5.2 Send CMD Info Packet */ + if (nicTxInitCmd(prAdapter, prCmdInfo, + prChipInfo->u2TxInitCmdPort) != + WLAN_STATUS_SUCCESS) { + u4Status = WLAN_STATUS_FAILURE; + DBGLOG(INIT, ERROR, + "Fail to transmit image download command\n"); + } + + break; + }; + + /* 6. Wait for INIT_EVENT_ID_PENDING_ERROR */ + do { + if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE + || fgIsBusAccessFailed == TRUE) { + u4Status = WLAN_STATUS_FAILURE; + } else if (nicRxWaitResponse(prAdapter, 0, + aucBuffer, u4EventSize, + &u4RxPktLength) != + WLAN_STATUS_SUCCESS) { + u4Status = WLAN_STATUS_FAILURE; + } else { + prInitEvent = (struct INIT_WIFI_EVENT *) + (aucBuffer + prChipInfo->rxd_size); + if (prInitEvent == NULL) { + DBGLOG(INIT, ERROR, "prInitEvent is NULL\n"); + u4Status = WLAN_STATUS_FAILURE; + break; + } + + /* EID / SeqNum check */ + if (prInitEvent->ucEID != INIT_EVENT_ID_PENDING_ERROR) + u4Status = WLAN_STATUS_FAILURE; + else if (prInitEvent->ucSeqNum != ucCmdSeqNum) + u4Status = WLAN_STATUS_FAILURE; + else { + prEventPendingError = + (struct INIT_EVENT_CMD_RESULT *) + prInitEvent->aucBuffer; + /* 0 for download success */ + if (prEventPendingError->ucStatus != 0) + u4Status = WLAN_STATUS_FAILURE; + else + u4Status = WLAN_STATUS_SUCCESS; + } + } + } while (FALSE); + + /* 7. Free CMD Info Packet. */ + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + + kalMemFree(aucBuffer, PHY_MEM_TYPE, u4EventSize); + + return u4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called to confirm the status of + * previously downloaded firmware scatter + * + * @param prAdapter Pointer to the Adapter structure. + * ucCmdSeqNum Sequence number of previous firmware scatter + * + * @return WLAN_STATUS_SUCCESS + * WLAN_STATUS_FAILURE + */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanConfigWifiFuncStatus(IN struct ADAPTER + *prAdapter, IN uint8_t ucCmdSeqNum) +{ + struct mt66xx_chip_info *prChipInfo; + uint8_t *aucBuffer; + uint32_t u4EventSize; + struct INIT_WIFI_EVENT *prInitEvent; + struct INIT_EVENT_CMD_RESULT *prEventCmdResult; + uint32_t u4RxPktLength; + uint32_t u4Status; + uint8_t ucPortIdx = IMG_DL_STATUS_PORT_IDX; + + ASSERT(prAdapter); + prChipInfo = prAdapter->chip_info; + + u4EventSize = prChipInfo->init_evt_rxd_size + + prChipInfo->init_event_size + + sizeof(struct INIT_EVENT_CMD_RESULT); + aucBuffer = kalMemAlloc(u4EventSize, PHY_MEM_TYPE); + if (aucBuffer == NULL) { + DBGLOG(INIT, ERROR, "Alloc CMD buffer failed\n"); + return WLAN_STATUS_FAILURE; + } + + do { + if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE + || fgIsBusAccessFailed == TRUE) { + u4Status = WLAN_STATUS_FAILURE; + } else if (nicRxWaitResponse(prAdapter, ucPortIdx, + aucBuffer, u4EventSize, + &u4RxPktLength) != + WLAN_STATUS_SUCCESS) { + u4Status = WLAN_STATUS_FAILURE; + } else { + prInitEvent = (struct INIT_WIFI_EVENT *) + (aucBuffer + prChipInfo->init_evt_rxd_size); + + /* EID / SeqNum check */ + if (prInitEvent->ucEID != INIT_EVENT_ID_CMD_RESULT) + u4Status = WLAN_STATUS_FAILURE; + else if (prInitEvent->ucSeqNum != ucCmdSeqNum) + u4Status = WLAN_STATUS_FAILURE; + else { + prEventCmdResult = + (struct INIT_EVENT_CMD_RESULT *) + prInitEvent->aucBuffer; + + /* 0 for download success */ + if (prEventCmdResult->ucStatus != 0) { + DBGLOG(INIT, ERROR, + "Start CMD failed, status[%u]\n", + prEventCmdResult->ucStatus); +#if CFG_SUPPORT_COMPRESSION_FW_OPTION + if (prEventCmdResult->ucStatus == + WIFI_FW_DECOMPRESSION_FAILED) + DBGLOG(INIT, ERROR, + "Start Decompression CMD failed, status[%u]\n", + prEventCmdResult->ucStatus); +#endif + u4Status = WLAN_STATUS_FAILURE; + } else { + u4Status = WLAN_STATUS_SUCCESS; + } + } + } + } while (FALSE); + + kalMemFree(aucBuffer, PHY_MEM_TYPE, u4EventSize); + + return u4Status; +} + +uint32_t wlanConfigWifiFunc(IN struct ADAPTER *prAdapter, + IN u_int8_t fgEnable, IN uint32_t u4StartAddress, + IN uint8_t ucPDA) +{ + struct CMD_INFO *prCmdInfo; + struct INIT_CMD_WIFI_START *prInitCmdWifiStart; + uint8_t ucTC, ucCmdSeqNum; + uint32_t u4Status = WLAN_STATUS_SUCCESS; + struct mt66xx_chip_info *prChipInfo; + + ASSERT(prAdapter); + prChipInfo = prAdapter->chip_info; + + DEBUGFUNC("wlanConfigWifiFunc"); + + /* 1. Allocate CMD Info Packet and its Buffer. */ + prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, + sizeof(struct INIT_HIF_TX_HEADER) + + sizeof(struct INIT_HIF_TX_HEADER_PENDING_FOR_HW_32BYTES) + + sizeof(struct INIT_CMD_WIFI_START)); + + if (!prCmdInfo) { + DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); + return WLAN_STATUS_FAILURE; + } + + kalMemZero(prCmdInfo->pucInfoBuffer, + sizeof(struct INIT_HIF_TX_HEADER) + + sizeof(struct INIT_HIF_TX_HEADER_PENDING_FOR_HW_32BYTES) + + sizeof(struct INIT_CMD_WIFI_START)); + prCmdInfo->u2InfoBufLen = sizeof(struct INIT_HIF_TX_HEADER) + + sizeof(struct INIT_HIF_TX_HEADER_PENDING_FOR_HW_32BYTES) + + sizeof(struct INIT_CMD_WIFI_START); + +#if (CFG_USE_TC4_RESOURCE_FOR_INIT_CMD == 1) + /* 2. Always use TC4 (TC4 as CPU) */ + ucTC = TC4_INDEX; +#else + /* 2. Use TC0's resource to send init_cmd. + * Only TC0 is allowed because SDIO HW always reports + * CPU's TXQ_CNT at TXQ0_CNT in CR4 architecutre) + */ + ucTC = TC0_INDEX; +#endif + + NIC_FILL_CMD_TX_HDR(prAdapter, + prCmdInfo->pucInfoBuffer, + prCmdInfo->u2InfoBufLen, + INIT_CMD_ID_WIFI_START, + INIT_CMD_PACKET_TYPE_ID, + &ucCmdSeqNum, + FALSE, + (void **)&prInitCmdWifiStart, + TRUE, 0, S2D_INDEX_CMD_H2N); + + prInitCmdWifiStart->u4Override = 0; + if (fgEnable) + prInitCmdWifiStart->u4Override |= + START_OVERRIDE_START_ADDRESS; + + /* 5G cal until send efuse buffer mode CMD */ +#if (CFG_EFUSE_BUFFER_MODE_DELAY_CAL == 1) + if (prAdapter->fgIsSupportDelayCal == TRUE) + prInitCmdWifiStart->u4Override |= START_DELAY_CALIBRATION; +#endif + + if (ucPDA == PDA_CR4) + prInitCmdWifiStart->u4Override |= START_WORKING_PDA_OPTION; + + prInitCmdWifiStart->u4Address = u4StartAddress; + + /* 5. Seend WIFI start command */ + while (1) { + /* 5.1 Acquire TX Resource */ + if (nicTxAcquireResource(prAdapter, ucTC, + nicTxGetPageCount(prAdapter, + prCmdInfo->u2InfoBufLen, TRUE), + TRUE) == WLAN_STATUS_RESOURCES) { + if (nicTxPollingResource(prAdapter, + ucTC) != WLAN_STATUS_SUCCESS) { + u4Status = WLAN_STATUS_FAILURE; + DBGLOG(INIT, ERROR, + "Fail to get TX resource return within timeout\n"); + goto exit; + } + continue; + } + /* 5.2 Send CMD Info Packet */ + if (nicTxInitCmd(prAdapter, prCmdInfo, + prChipInfo->u2TxInitCmdPort) + != WLAN_STATUS_SUCCESS) { + u4Status = WLAN_STATUS_FAILURE; + DBGLOG(INIT, ERROR, + "Fail to transmit WIFI start command\n"); + goto exit; + } + + break; + }; + + DBGLOG(INIT, INFO, "FW_START CMD send, waiting for RSP\n"); + + u4Status = wlanConfigWifiFuncStatus(prAdapter, ucCmdSeqNum); + + if (u4Status != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, INFO, "FW_START EVT failed\n"); + GL_RESET_TRIGGER(prAdapter, RST_FLAG_CHIP_RESET); + } else { + DBGLOG(INIT, INFO, "FW_START EVT success!!\n"); + +#if defined(_HIF_PCIE) + if (ucPDA == PDA_CR4 && prChipInfo->is_support_wacpu) + prChipInfo->rx_event_port = WFDMA1_RX_RING_IDX_1; +#endif /* _HIF_PCIE */ + + } + +exit: + /* 6. Free CMD Info Packet. */ + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + + return u4Status; +} + +#if (CFG_DOWNLOAD_DYN_MEMORY_MAP == 1) +uint32_t wlanRamCodeDynMemMapSendComplete(IN struct ADAPTER *prAdapter, + IN u_int8_t fgEnable, IN uint32_t u4StartAddress, + IN uint8_t ucPDA) +{ + struct CMD_INFO *prCmdInfo; + struct INIT_CMD_WIFI_START *prInitCmdWifiStart; + uint8_t ucTC, ucCmdSeqNum; + uint32_t u4Status = WLAN_STATUS_SUCCESS; + struct mt66xx_chip_info *prChipInfo; + + ASSERT(prAdapter); + prChipInfo = prAdapter->chip_info; + + DEBUGFUNC("wlanConfigWifiFunc"); + + /* 1. Allocate CMD Info Packet and its Buffer. */ + prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, + sizeof(struct INIT_HIF_TX_HEADER) + + sizeof(struct INIT_HIF_TX_HEADER_PENDING_FOR_HW_32BYTES) + + sizeof(struct INIT_CMD_WIFI_START)); + + if (!prCmdInfo) { + DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); + return WLAN_STATUS_FAILURE; + } + + kalMemZero(prCmdInfo->pucInfoBuffer, + sizeof(struct INIT_HIF_TX_HEADER) + + sizeof(struct INIT_HIF_TX_HEADER_PENDING_FOR_HW_32BYTES) + + sizeof(struct INIT_CMD_WIFI_START)); + + prCmdInfo->u2InfoBufLen = sizeof(struct INIT_HIF_TX_HEADER) + + sizeof(struct INIT_HIF_TX_HEADER_PENDING_FOR_HW_32BYTES) + + sizeof(struct INIT_CMD_WIFI_START); + +#if (CFG_USE_TC4_RESOURCE_FOR_INIT_CMD == 1) + /* 2. Always use TC4 (TC4 as CPU) */ + ucTC = TC4_INDEX; +#else + /* 2. Use TC0's resource to send init_cmd. + * Only TC0 is allowed because SDIO HW always reports + * CPU's TXQ_CNT at TXQ0_CNT in CR4 architecutre) + */ + ucTC = TC0_INDEX; +#endif + + NIC_FILL_CMD_TX_HDR(prAdapter, + prCmdInfo->pucInfoBuffer, + prCmdInfo->u2InfoBufLen, + INIT_CMD_ID_DYN_MEM_MAP_FW_FINISH, + INIT_CMD_PACKET_TYPE_ID, + &ucCmdSeqNum, + FALSE, + (void **)&prInitCmdWifiStart, + TRUE, 0, S2D_INDEX_CMD_H2N); + + prInitCmdWifiStart->u4Override = 0; + if (fgEnable) + prInitCmdWifiStart->u4Override |= + START_OVERRIDE_START_ADDRESS; + + /* 5G cal until send efuse buffer mode CMD */ +#if (CFG_EFUSE_BUFFER_MODE_DELAY_CAL == 1) + if (prAdapter->fgIsSupportDelayCal == TRUE) + prInitCmdWifiStart->u4Override |= START_DELAY_CALIBRATION; +#endif + + if (ucPDA == PDA_CR4) + prInitCmdWifiStart->u4Override |= START_WORKING_PDA_OPTION; + + prInitCmdWifiStart->u4Address = u4StartAddress; + + /* 5. Seend WIFI start command */ + while (1) { + /* 5.1 Acquire TX Resource */ + if (nicTxAcquireResource(prAdapter, ucTC, + nicTxGetPageCount(prAdapter, + prCmdInfo->u2InfoBufLen, TRUE), + TRUE) == WLAN_STATUS_RESOURCES) { + if (nicTxPollingResource(prAdapter, + ucTC) != WLAN_STATUS_SUCCESS) { + u4Status = WLAN_STATUS_FAILURE; + DBGLOG(INIT, ERROR, + "Fail to get TX resource return within timeout\n"); + goto exit; + } + continue; + } + /* 5.2 Send CMD Info Packet */ + if (nicTxInitCmd(prAdapter, prCmdInfo, + prChipInfo->u2TxInitCmdPort) + != WLAN_STATUS_SUCCESS) { + u4Status = WLAN_STATUS_FAILURE; + DBGLOG(INIT, ERROR, + "Fail to transmit WIFI start command\n"); + goto exit; + } + + break; + }; + if (prAdapter->chip_info->checkbushang) + prAdapter->chip_info->checkbushang((void *) prAdapter, FALSE); + + DBGLOG(INIT, INFO, "FW_START CMD send, waiting for RSP\n"); + + if (ucPDA == PDA_CR4 && prChipInfo->is_support_wacpu) { + prChipInfo->rx_event_port = WFDMA1_RX_RING_IDX_1; + /* workaround for harrier powerOnCal too long issue + * skip FW start event, fw ready bit check can cover this. + */ + return WLAN_STATUS_SUCCESS; + } + + u4Status = wlanConfigWifiFuncStatus(prAdapter, ucCmdSeqNum); + + if (u4Status != WLAN_STATUS_SUCCESS) + DBGLOG(INIT, INFO, "FW_START EVT failed\n"); + else + DBGLOG(INIT, INFO, "FW_START EVT success!!\n"); + +exit: + /* 6. Free CMD Info Packet. */ + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + + return u4Status; +} +#endif + +#if CFG_SUPPORT_COMPRESSION_FW_OPTION +uint32_t +wlanCompressedFWConfigWifiFunc(IN struct ADAPTER *prAdapter, + IN u_int8_t fgEnable, + IN uint32_t u4StartAddress, IN uint8_t ucPDA, + IN struct INIT_CMD_WIFI_DECOMPRESSION_START *prFwImageInFo) +{ + struct CMD_INFO *prCmdInfo; + struct INIT_CMD_WIFI_DECOMPRESSION_START *prInitCmdWifiStart; + uint8_t ucTC, ucCmdSeqNum; + uint32_t u4Status = WLAN_STATUS_SUCCESS; + struct mt66xx_chip_info *prChipInfo; + + ASSERT(prAdapter); + prChipInfo = prAdapter->chip_info; + + DEBUGFUNC("wlanConfigWifiFunc"); + /* 1. Allocate CMD Info Packet and its Buffer. */ + prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, + sizeof(struct INIT_HIF_TX_HEADER) + + sizeof(struct INIT_HIF_TX_HEADER_PENDING_FOR_HW_32BYTES) + + sizeof(struct INIT_CMD_WIFI_DECOMPRESSION_START)); + + if (!prCmdInfo) { + DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); + return WLAN_STATUS_FAILURE; + } + + kalMemZero(prCmdInfo->pucInfoBuffer, + sizeof(struct INIT_HIF_TX_HEADER) + + sizeof(struct INIT_HIF_TX_HEADER_PENDING_FOR_HW_32BYTES) + + sizeof(struct INIT_CMD_WIFI_DECOMPRESSION_START)); + prCmdInfo->u2InfoBufLen = + sizeof(struct INIT_HIF_TX_HEADER) + + sizeof(struct INIT_HIF_TX_HEADER_PENDING_FOR_HW_32BYTES) + + sizeof(struct INIT_CMD_WIFI_DECOMPRESSION_START); + + /* 2. Always use TC0 */ + ucTC = TC0_INDEX; + + NIC_FILL_CMD_TX_HDR(prAdapter, + prCmdInfo->pucInfoBuffer, + prCmdInfo->u2InfoBufLen, + INIT_CMD_ID_DECOMPRESSED_WIFI_START, + INIT_CMD_PACKET_TYPE_ID, + &ucCmdSeqNum, + FALSE, + &prInitCmdWifiStart, TRUE, 0, S2D_INDEX_CMD_H2N); + + prInitCmdWifiStart->u4Override = 0; + if (fgEnable) + prInitCmdWifiStart->u4Override |= + START_OVERRIDE_START_ADDRESS; + + /* 5G cal until send efuse buffer mode CMD */ +#if (CFG_EFUSE_BUFFER_MODE_DELAY_CAL == 1) + if (prAdapter->fgIsSupportDelayCal == TRUE) + prInitCmdWifiStart->u4Override |= START_DELAY_CALIBRATION; +#endif + if (ucPDA == PDA_CR4) + prInitCmdWifiStart->u4Override |= START_WORKING_PDA_OPTION; + +#if CFG_COMPRESSION_DEBUG + prInitCmdWifiStart->u4Override |= START_CRC_CHECK; +#endif +#if CFG_DECOMPRESSION_TMP_ADDRESS + prInitCmdWifiStart->u4Override |= + CHANGE_DECOMPRESSION_TMP_ADDRESS; + prInitCmdWifiStart->u4DecompressTmpAddress = 0xE6000; +#endif + prInitCmdWifiStart->u4Address = u4StartAddress; + prInitCmdWifiStart->u4Region1Address = + prFwImageInFo->u4Region1Address; + prInitCmdWifiStart->u4Region1CRC = + prFwImageInFo->u4Region1CRC; + prInitCmdWifiStart->u4BlockSize = + prFwImageInFo->u4BlockSize; + prInitCmdWifiStart->u4Region1length = + prFwImageInFo->u4Region1length; + prInitCmdWifiStart->u4Region2Address = + prFwImageInFo->u4Region2Address; + prInitCmdWifiStart->u4Region2CRC = + prFwImageInFo->u4Region2CRC; + prInitCmdWifiStart->u4Region2length = + prFwImageInFo->u4Region2length; + + while (1) { + /* 5.1 Acquire TX Resource */ + if (nicTxAcquireResource(prAdapter, ucTC, + nicTxGetPageCount(prAdapter, + prCmdInfo->u2InfoBufLen, TRUE), + TRUE) == WLAN_STATUS_RESOURCES) { + if (nicTxPollingResource(prAdapter, + ucTC) != WLAN_STATUS_SUCCESS) { + u4Status = WLAN_STATUS_FAILURE; + DBGLOG(INIT, ERROR, + "Fail to get TX resource return within timeout\n"); + break; + } + continue; + + } + /* 5.2 Send CMD Info Packet */ + if (nicTxInitCmd(prAdapter, prCmdInfo, + prChipInfo->u2TxInitCmdPort) + != WLAN_STATUS_SUCCESS) { + u4Status = WLAN_STATUS_FAILURE; + DBGLOG(INIT, ERROR, + "Fail to transmit WIFI start command\n"); + } + + break; + }; + + DBGLOG(INIT, INFO, "FW_START CMD send, waiting for RSP\n"); + + u4Status = wlanConfigWifiFuncStatus(prAdapter, ucCmdSeqNum); + + if (u4Status != WLAN_STATUS_SUCCESS) + DBGLOG(INIT, INFO, "FW_START EVT failed\n"); + else + DBGLOG(INIT, INFO, "FW_START EVT success!!\n"); + + + /* 6. Free CMD Info Packet. */ + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + + return u4Status; +} +#endif +#if 0 +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is used to generate CRC32 checksum + * + * @param buf Pointer to the data. + * @param len data length + * + * @return crc32 value + */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanCRC32(uint8_t *buf, uint32_t len) +{ + uint32_t i, crc32 = 0xFFFFFFFF; + const uint32_t crc32_ccitt_table[256] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, + 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, + 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, + 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, + 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, + 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, + 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, + 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, + 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, + 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, + 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, + 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, + 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, + 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, + 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, + 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, + 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, + 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, + 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, + 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, + 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, + 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, + 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, + 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, + 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, + 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, + 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, + 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, + 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, + 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, + 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, + 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, + 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, + 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, + 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, + 0x2d02ef8d + }; + + for (i = 0; i < len; i++) + crc32 = crc32_ccitt_table[(crc32 ^ buf[i]) & 0xff] ^ + (crc32 >> 8); + + return ~crc32; +} +#endif + +uint32_t wlanGetHarvardTailerInfo(IN struct ADAPTER + *prAdapter, IN void *prFwBuffer, IN uint32_t u4FwSize, + IN uint32_t ucTotSecNum, IN enum ENUM_IMG_DL_IDX_T eDlIdx) +{ + struct TAILER_FORMAT_T *prTailers; + uint8_t *pucStartPtr; + uint32_t u4SecIdx; + uint8_t aucBuf[32]; + + pucStartPtr = prFwBuffer + u4FwSize - sizeof( + struct TAILER_FORMAT_T) * ucTotSecNum; + if (eDlIdx == IMG_DL_IDX_N9_FW) { + kalMemCopy(&prAdapter->rVerInfo.rN9tailer, pucStartPtr, + sizeof(struct TAILER_FORMAT_T) * ucTotSecNum); + prTailers = prAdapter->rVerInfo.rN9tailer; + } else { + kalMemCopy(&prAdapter->rVerInfo.rCR4tailer, pucStartPtr, + sizeof(struct TAILER_FORMAT_T) * ucTotSecNum); + prTailers = prAdapter->rVerInfo.rCR4tailer; + } + + for (u4SecIdx = 0; u4SecIdx < ucTotSecNum; u4SecIdx++) { + /* Dump image information */ + DBGLOG(INIT, INFO, + "%s Section[%d]: chip_info[%u:E%u] feature[0x%02X]\n", + (eDlIdx == IMG_DL_IDX_N9_FW) ? "N9" : "CR4", u4SecIdx, + prTailers[u4SecIdx].chip_info, + prTailers[u4SecIdx].eco_code + 1, + prTailers[u4SecIdx].feature_set); + + kalMemZero(aucBuf, 32); + kalStrnCpy(aucBuf, prTailers[u4SecIdx].ram_version, + sizeof(prTailers[u4SecIdx].ram_version)); + DBGLOG(INIT, INFO, "date[%s] version[%s]\n", + prTailers[u4SecIdx].ram_built_date, aucBuf); + } + + return WLAN_STATUS_SUCCESS; +} + +uint32_t wlanGetConnacTailerInfo(IN struct ADAPTER + *prAdapter, IN void *prFwBuffer, + IN uint32_t u4FwSize, IN enum ENUM_IMG_DL_IDX_T eDlIdx) +{ + struct WIFI_VER_INFO *prVerInfo = &prAdapter->rVerInfo; + struct TAILER_COMMON_FORMAT_T *prComTailer; + struct TAILER_REGION_FORMAT_T *prRegTailer; + uint8_t *pucImgPtr; + uint8_t *pucTailertPtr; + uint8_t *pucStartPtr; + uint32_t u4SecIdx; + uint8_t aucBuf[32]; + + pucImgPtr = prFwBuffer; + pucStartPtr = prFwBuffer + u4FwSize - + sizeof(struct TAILER_COMMON_FORMAT_T); + prComTailer = (struct TAILER_COMMON_FORMAT_T *) pucStartPtr; + kalMemCopy(&prVerInfo->rCommonTailer, prComTailer, + sizeof(struct TAILER_COMMON_FORMAT_T)); + + kalMemZero(aucBuf, 32); + kalStrnCpy(aucBuf, prComTailer->aucRamVersion, + sizeof(prComTailer->aucRamVersion)); + + /* Dump image information */ + DBGLOG(INIT, INFO, + "%s: chip_info[%u:E%u] region_num[%d] date[%s] version[%s]\n", + (eDlIdx == IMG_DL_IDX_N9_FW) ? "N9" : "CR4", + prComTailer->ucChipInfo, + prComTailer->ucEcoCode + 1, + prComTailer->ucRegionNum, + prComTailer->aucRamBuiltDate, + aucBuf); + + if (prComTailer->ucRegionNum > MAX_FWDL_SECTION_NUM) { + DBGLOG(INIT, INFO, + "Regions number[%d] > max section number[%d]\n", + prComTailer->ucRegionNum, MAX_FWDL_SECTION_NUM); + return WLAN_STATUS_FAILURE; + } + + pucStartPtr -= (prComTailer->ucRegionNum * + sizeof(struct TAILER_REGION_FORMAT_T)); + pucTailertPtr = pucStartPtr; + for (u4SecIdx = 0; u4SecIdx < prComTailer->ucRegionNum; u4SecIdx++) { + prRegTailer = (struct TAILER_REGION_FORMAT_T *) pucStartPtr; + kalMemCopy(&prVerInfo->rRegionTailers[u4SecIdx], + prRegTailer, sizeof(struct TAILER_REGION_FORMAT_T)); + + /* Dump image information */ + DBGLOG(INIT, TRACE, + "Region[%d]: addr[0x%08X] feature[0x%02X] size[%u]\n", + u4SecIdx, prRegTailer->u4Addr, + prRegTailer->ucFeatureSet, prRegTailer->u4Len); + DBGLOG(INIT, TRACE, + "uncompress_crc[0x%08X] uncompress_size[0x%08X] block_size[0x%08X]\n", + prRegTailer->u4CRC, prRegTailer->u4RealSize, + prRegTailer->u4BlockSize); + pucImgPtr += prRegTailer->u4Len; + pucStartPtr += sizeof(struct TAILER_REGION_FORMAT_T); + } + + if (prComTailer->ucFormatFlag && pucImgPtr < pucTailertPtr) + fwDlGetReleaseInfoSection(prAdapter, pucImgPtr); + + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is used to extract the wifi ram code start address + * + * @param prVerInfo Pointer to the P_WIFI_VER_INFO_T structure. + * + * @return addr The ram code entry address. + * 0: use firmware defaut setting + * others: use it as the start address + */ +/*----------------------------------------------------------------------------*/ + +uint32_t wlanDetectRamEntry(IN struct WIFI_VER_INFO + *prVerInfo) +{ + uint32_t addr = 0; + uint32_t u4SecIdx; + struct TAILER_COMMON_FORMAT_T *prComTailer = + &prVerInfo->rCommonTailer; + struct TAILER_REGION_FORMAT_T *prRegTailer; + + for (u4SecIdx = 0; u4SecIdx < prComTailer->ucRegionNum; + u4SecIdx++) { + prRegTailer = &(prVerInfo->rRegionTailers[u4SecIdx]); + + if (prRegTailer->ucFeatureSet & + DOWNLOAD_CONFIG_VALID_RAM_ENTRY) { + addr = prRegTailer->u4Addr; + break; + } + } + + return addr; +} + +uint32_t wlanHarvardFormatDownload(IN struct ADAPTER + *prAdapter, IN enum ENUM_IMG_DL_IDX_T eDlIdx) +{ + uint32_t u4FwSize = 0; + void *prFwBuffer = NULL; + uint32_t rDlStatus = 0; + uint32_t rCfgStatus = 0; + uint32_t ucTotSecNum; + uint8_t ucPDA; +#if CFG_SUPPORT_COMPRESSION_FW_OPTION + u_int8_t fgIsCompressed = FALSE; + struct INIT_CMD_WIFI_DECOMPRESSION_START rFwImageInFo; +#endif + + if (eDlIdx == IMG_DL_IDX_N9_FW) { + ucTotSecNum = N9_FWDL_SECTION_NUM; + ucPDA = PDA_N9; + } else { + ucTotSecNum = CR4_FWDL_SECTION_NUM; + ucPDA = PDA_CR4; + } + + kalFirmwareImageMapping(prAdapter->prGlueInfo, &prFwBuffer, + &u4FwSize, eDlIdx); + if (prFwBuffer == NULL) { + DBGLOG(INIT, WARN, "FW[%u] load error!\n", eDlIdx); + return WLAN_STATUS_FAILURE; + } + + wlanGetHarvardTailerInfo(prAdapter, prFwBuffer, u4FwSize, + ucTotSecNum, eDlIdx); +#if CFG_SUPPORT_COMPRESSION_FW_OPTION + rDlStatus = wlanCompressedImageSectionDownloadStage( + prAdapter, prFwBuffer, u4FwSize, ucTotSecNum, + eDlIdx, &fgIsCompressed, &rFwImageInFo); + if (eDlIdx == IMG_DL_IDX_CR4_FW) + prAdapter->fgIsCr4FwDownloaded = TRUE; + if (fgIsCompressed == TRUE) + rCfgStatus = wlanCompressedFWConfigWifiFunc(prAdapter, + FALSE, 0, ucPDA, &rFwImageInFo); + else + rCfgStatus = wlanConfigWifiFunc(prAdapter, FALSE, 0, ucPDA); +#else + rDlStatus = wlanImageSectionDownloadStage(prAdapter, + prFwBuffer, u4FwSize, ucTotSecNum, eDlIdx); + if (eDlIdx == IMG_DL_IDX_CR4_FW) + prAdapter->fgIsCr4FwDownloaded = TRUE; + rCfgStatus = wlanConfigWifiFunc(prAdapter, FALSE, 0, ucPDA); +#endif + kalFirmwareImageUnmapping(prAdapter->prGlueInfo, NULL, + prFwBuffer); + + if ((rDlStatus != WLAN_STATUS_SUCCESS) + || (rCfgStatus != WLAN_STATUS_SUCCESS)) + return WLAN_STATUS_FAILURE; + + return WLAN_STATUS_SUCCESS; +} + +uint32_t wlanConnacFormatDownload(IN struct ADAPTER + *prAdapter, IN enum ENUM_IMG_DL_IDX_T eDlIdx) +{ + void *prFwBuffer = NULL; + uint32_t u4FwSize = 0; + uint32_t ram_entry = 0; + uint32_t rDlStatus = 0; + uint32_t rCfgStatus = 0; + uint8_t ucRegionNum; + uint8_t ucPDA; + + kalFirmwareImageMapping(prAdapter->prGlueInfo, &prFwBuffer, + &u4FwSize, eDlIdx); + if (prFwBuffer == NULL) { + DBGLOG(INIT, WARN, "FW[%u] load error!\n", eDlIdx); + return WLAN_STATUS_FAILURE; + } + + if (wlanGetConnacTailerInfo(prAdapter, prFwBuffer, u4FwSize, + eDlIdx) != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, WARN, "Get tailer info error!\n"); + rDlStatus = WLAN_STATUS_FAILURE; + goto exit; + } + + if (prAdapter->chip_info->checkbushang) { + if (prAdapter->chip_info->checkbushang((void *) prAdapter, + TRUE) != 0) { + DBGLOG(INIT, WARN, "Check bus hang failed.\n"); + rDlStatus = WLAN_STATUS_FAILURE; + goto exit; + } + } + + ucRegionNum = prAdapter->rVerInfo.rCommonTailer.ucRegionNum; + ucPDA = (eDlIdx == IMG_DL_IDX_N9_FW) ? PDA_N9 : PDA_CR4; + + rDlStatus = wlanImageSectionDownloadStage(prAdapter, + prFwBuffer, u4FwSize, ucRegionNum, eDlIdx); + + ram_entry = wlanDetectRamEntry(&prAdapter->rVerInfo); + +/* To support dynamic memory map for WiFi RAM code download::Begin */ +#if (CFG_DOWNLOAD_DYN_MEMORY_MAP == 1) + rCfgStatus = wlanRamCodeDynMemMapSendComplete(prAdapter, + (ram_entry == 0) ? FALSE : TRUE, + ram_entry, ucPDA); +#else + rCfgStatus = wlanConfigWifiFunc(prAdapter, + (ram_entry == 0) ? FALSE : TRUE, + ram_entry, ucPDA); +#endif +/* To support dynamic memory map for WiFi RAM code download::End */ + +exit: + kalFirmwareImageUnmapping(prAdapter->prGlueInfo, NULL, + prFwBuffer); + + if ((rDlStatus != WLAN_STATUS_SUCCESS) + || (rCfgStatus != WLAN_STATUS_SUCCESS)) + return WLAN_STATUS_FAILURE; + + return WLAN_STATUS_SUCCESS; +} + +uint32_t wlanDownloadFW(IN struct ADAPTER *prAdapter) +{ + uint32_t rStatus = 0; + u_int8_t fgReady; + struct mt66xx_chip_info *prChipInfo; + struct FWDL_OPS_T *prFwDlOps; +#if (CFG_SUPPORT_CONNINFRA == 1) + uint32_t rPccifstatus = 0; +#endif + + if (!prAdapter) + return WLAN_STATUS_FAILURE; + + prChipInfo = prAdapter->chip_info; + prFwDlOps = prChipInfo->fw_dl_ops; + + DBGLOG(INIT, INFO, + "wlanDownloadFW:: Check ready_bits(=0x%x)\n", + prChipInfo->sw_ready_bits); + HAL_WIFI_FUNC_READY_CHECK(prAdapter, + prChipInfo->sw_ready_bits, &fgReady); + + if (fgReady) { + DBGLOG(INIT, INFO, + "Wi-Fi is already ON!, turn off before FW DL!\n"); + + if (wlanPowerOffWifi(prAdapter) != WLAN_STATUS_SUCCESS) + return WLAN_STATUS_FAILURE; + + nicpmWakeUpWiFi(prAdapter); + HAL_HIF_INIT(prAdapter); + } + + HAL_ENABLE_FWDL(prAdapter, TRUE); + + if (prFwDlOps->downloadPatch) + prFwDlOps->downloadPatch(prAdapter); + + if (prFwDlOps->phyAction) + prFwDlOps->phyAction(prAdapter); + + if (prChipInfo->coantVFE28En) + prChipInfo->coantVFE28En(prAdapter); + + DBGLOG(INIT, INFO, "FW download Start\n"); +#if (CFG_SUPPORT_CONNINFRA == 1) + if (prChipInfo->coexpccifon) { + rPccifstatus = prChipInfo->coexpccifon(); + if (rPccifstatus != 0) + DBGLOG(INIT, WARN, "pccif on fail\n"); + } +#endif + + if (prFwDlOps->downloadFirmware) { + rStatus = prFwDlOps->downloadFirmware(prAdapter, + IMG_DL_IDX_N9_FW); + if ((prChipInfo->is_support_cr4 || prChipInfo->is_support_wacpu) + && rStatus == WLAN_STATUS_SUCCESS) + rStatus = prFwDlOps->downloadFirmware(prAdapter, + IMG_DL_IDX_CR4_FW); + } else { + DBGLOG(INIT, WARN, "Without downlaod firmware Ops\n"); +#if (CFG_SUPPORT_CONNINFRA == 1) + if (prChipInfo->coexpccifoff) { + prChipInfo->coexpccifoff(); + DBGLOG(INIT, TRACE, "pccif off\n"); + } +#endif + } + DBGLOG(INIT, TRACE, "FW download End\n"); + + HAL_ENABLE_FWDL(prAdapter, FALSE); + + + return rStatus; +} + +uint32_t wlanDownloadPatch(IN struct ADAPTER *prAdapter) +{ + uint32_t u4FwSize = 0; + void *prFwBuffer = NULL; + uint32_t u4Status; +#if CFG_SUPPORT_COMPRESSION_FW_OPTION + uint8_t ucIsCompressed; +#endif + if (!prAdapter) + return WLAN_STATUS_FAILURE; + + + DBGLOG(INIT, INFO, "Patch download start\n"); + + prAdapter->rVerInfo.fgPatchIsDlByDrv = FALSE; + + kalFirmwareImageMapping(prAdapter->prGlueInfo, &prFwBuffer, + &u4FwSize, IMG_DL_IDX_PATCH); + if (prFwBuffer == NULL) { + DBGLOG(INIT, WARN, "FW[%u] load error!\n", + IMG_DL_IDX_PATCH); + return WLAN_STATUS_FAILURE; + } + +#if (CFG_ROM_PATCH_NO_SEM_CTRL == 0) +#pragma message("ROM code supports SEM-CTRL for ROM patch download") + if (wlanPatchIsDownloaded(prAdapter)) { + kalFirmwareImageUnmapping(prAdapter->prGlueInfo, NULL, + prFwBuffer); + DBGLOG(INIT, INFO, "No need to download patch\n"); + return WLAN_STATUS_SUCCESS; + } +#else +#pragma message("ROM code supports no SEM-CTRL for ROM patch download") +#endif + + /* Patch DL */ + do { +#if CFG_SUPPORT_COMPRESSION_FW_OPTION + u4Status = wlanCompressedImageSectionDownloadStage( + prAdapter, prFwBuffer, u4FwSize, 1, + IMG_DL_IDX_PATCH, &ucIsCompressed, NULL); +#else + u4Status = wlanImageSectionDownloadStage( + prAdapter, prFwBuffer, u4FwSize, 1, IMG_DL_IDX_PATCH); +#endif + +/* Dynamic memory map::Begin */ +#if (CFG_DOWNLOAD_DYN_MEMORY_MAP == 1) + if (u4Status == WLAN_STATUS_SUCCESS) + wlanPatchDynMemMapSendComplete(prAdapter); + else if (u4Status == WLAN_STATUS_NOT_ACCEPTED) + u4Status = WLAN_STATUS_SUCCESS; /* already download*/ +#else + wlanPatchSendComplete(prAdapter); +#endif +/* Dynamic memory map::End */ + + kalFirmwareImageUnmapping(prAdapter->prGlueInfo, NULL, + prFwBuffer); + + prAdapter->rVerInfo.fgPatchIsDlByDrv = TRUE; + } while (0); + + DBGLOG(INIT, INFO, "Patch download end[%d].\n", u4Status); + + return u4Status; +} + +uint32_t wlanGetPatchInfo(IN struct ADAPTER *prAdapter) +{ + uint32_t u4FwSize = 0; + void *prFwBuffer = NULL; + uint32_t u4StartOffset, u4Addr, u4Len, u4DataMode; + + if (!prAdapter) + return WLAN_STATUS_FAILURE; + + kalFirmwareImageMapping(prAdapter->prGlueInfo, &prFwBuffer, + &u4FwSize, IMG_DL_IDX_PATCH); + if (prFwBuffer == NULL) { + DBGLOG(INIT, WARN, "FW[%u] load error!\n", + IMG_DL_IDX_PATCH); + return WLAN_STATUS_FAILURE; + } + + wlanImageSectionGetPatchInfo(prAdapter, prFwBuffer, + u4FwSize, &u4StartOffset, + &u4Addr, &u4Len, &u4DataMode); + + kalFirmwareImageUnmapping(prAdapter->prGlueInfo, NULL, + prFwBuffer); + + return WLAN_STATUS_SUCCESS; +} + +uint32_t fwDlGetFwdlInfo(struct ADAPTER *prAdapter, + char *pcBuf, int i4TotalLen) +{ + struct WIFI_VER_INFO *prVerInfo = &prAdapter->rVerInfo; + struct FWDL_OPS_T *prFwDlOps; + uint32_t u4Offset = 0; + uint8_t aucBuf[32], aucDate[32]; + + prFwDlOps = prAdapter->chip_info->fw_dl_ops; + + kalMemZero(aucBuf, sizeof(aucBuf)); + kalStrnCpy(aucBuf, prVerInfo->aucFwBranchInfo, sizeof(aucBuf) - 1); + kalMemZero(aucDate, sizeof(aucDate)); + kalStrnCpy(aucDate, prVerInfo->aucFwDateCode, sizeof(aucDate) - 1); + + u4Offset += snprintf(pcBuf + u4Offset, + i4TotalLen - u4Offset, + "\nN9 FW version %s-%u.%u.%u[DEC] (%s)\n", + aucBuf, + (uint32_t)(prVerInfo->u2FwOwnVersion >> 8), + (uint32_t)(prVerInfo->u2FwOwnVersion & BITS(0, 7)), + prVerInfo->ucFwBuildNumber, aucDate); + + if (prFwDlOps->getFwDlInfo) + u4Offset += prFwDlOps->getFwDlInfo(prAdapter, + pcBuf + u4Offset, + i4TotalLen - u4Offset); + + if (!prVerInfo->fgPatchIsDlByDrv) { + u4Offset += snprintf(pcBuf + u4Offset, + i4TotalLen - u4Offset, + "MCU patch is not downloaded by wlan driver, read patch info\n"); +#if (CFG_MTK_ANDROID_WMT == 0) + wlanGetPatchInfo(prAdapter); +#endif + } + + kalMemZero(aucBuf, sizeof(aucBuf)); + kalMemZero(aucDate, sizeof(aucDate)); + kalStrnCpy(aucBuf, prVerInfo->rPatchHeader.aucPlatform, + sizeof(aucBuf) - 1); + kalStrnCpy(aucDate, prVerInfo->rPatchHeader.aucBuildDate, + sizeof(aucDate) - 1); + u4Offset += snprintf(pcBuf + u4Offset, + i4TotalLen - u4Offset, + "Patch platform %s version 0x%04X %s\n", + aucBuf, prVerInfo->rPatchHeader.u4PatchVersion, + aucDate); + + u4Offset += snprintf(pcBuf + u4Offset, i4TotalLen - u4Offset, + "Drv version %u.%u[DEC]\n", + (uint32_t)(prVerInfo->u2FwPeerVersion >> 8), + (uint32_t)(prVerInfo->u2FwPeerVersion & BITS(0, 7))); + return u4Offset; +} + +void fwDlGetReleaseInfoSection(struct ADAPTER *prAdapter, uint8_t *pucStartPtr) +{ + struct HEADER_RELEASE_INFO *prFirstInfo; + struct HEADER_RELEASE_INFO *prRelInfo; + uint8_t *pucCurPtr = pucStartPtr + RELEASE_INFO_SEPARATOR_LEN; + uint16_t u2Len = 0, u2Offset = 0; + uint8_t ucManifestExist = 0; + + prFirstInfo = (struct HEADER_RELEASE_INFO *)pucCurPtr; + DBGLOG(INIT, TRACE, "Release info tag[%u] len[%u]\n", + prFirstInfo->ucTag, prFirstInfo->u2Len); + + pucCurPtr += sizeof(struct HEADER_RELEASE_INFO); + while (u2Offset < prFirstInfo->u2Len) { + prRelInfo = (struct HEADER_RELEASE_INFO *)pucCurPtr; + DBGLOG(INIT, TRACE, + "Release info tag[%u] len[%u] padding[%u]\n", + prRelInfo->ucTag, prRelInfo->u2Len, + prRelInfo->ucPaddingLen); + + pucCurPtr += sizeof(struct HEADER_RELEASE_INFO); + switch (prRelInfo->ucTag) { + case 0x01: + fwDlGetReleaseManifest(prAdapter, prRelInfo, pucCurPtr); + ucManifestExist = 1; + break; + case 0x02: + if (!ucManifestExist) + fwDlGetReleaseManifest(prAdapter, + prRelInfo, pucCurPtr); + break; + default: + DBGLOG(INIT, WARN, "Not support release info tag[%u]\n", + prRelInfo->ucTag); + } + + u2Len = prRelInfo->u2Len + prRelInfo->ucPaddingLen; + pucCurPtr += u2Len; + u2Offset += u2Len + sizeof(struct HEADER_RELEASE_INFO); + } +} + +void fwDlGetReleaseManifest(struct ADAPTER *prAdapter, + struct HEADER_RELEASE_INFO *prRelInfo, + uint8_t *pucStartPtr) +{ + kalMemZero(&prAdapter->rVerInfo.aucReleaseManifest, + sizeof(prAdapter->rVerInfo.aucReleaseManifest)); + kalMemCopy(&prAdapter->rVerInfo.aucReleaseManifest, + pucStartPtr, prRelInfo->u2Len); + DBGLOG(INIT, INFO, "Release manifest: %s\n", + prAdapter->rVerInfo.aucReleaseManifest); +} + +#endif /* CFG_ENABLE_FW_DOWNLOAD */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/connac/connac.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/connac/connac.c new file mode 100644 index 0000000000000000000000000000000000000000..eb3731f4acaabc80687b896436178f11c4c0cc88 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/connac/connac.c @@ -0,0 +1,392 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/*! \file connac.c + * \brief Internal driver stack will export the required procedures here + * for GLUE Layer. + * + * This file contains all routines which are exported from MediaTek 802.11 + * Wireless LAN driver stack to GLUE Layer. + */ + +#ifdef CONNAC + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" + +#include "connac.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +uint8_t *apucConnacFwName[] = { + (uint8_t *) CFG_FW_FILENAME "_soc1_0", + NULL +}; + +struct ECO_INFO connac_eco_table[] = { + /* HW version, ROM version, Factory version */ + {0x00, 0x00, 0xA, 0x1}, /* E1 */ + {0x00, 0x00, 0x0, 0x0} /* End of table */ +}; + +#if defined(_HIF_PCIE) || defined(_HIF_AXI) +struct PCIE_CHIP_CR_MAPPING connac_bus2chip_cr_mapping[] = { + /* chip addr, bus addr, range */ + {0x80000000, 0x00002000, 0x00001000}, /* MCU_CFG */ + + {0x50000000, 0x00004000, 0x00004000}, /* CONN_HIF (PDMA) */ + {0x50002000, 0x00005000, 0x00001000}, /* CONN_HIF (Reserved) */ + {0x5000A000, 0x00006000, 0x00001000}, /* CONN_HIF (DMASHDL) */ + {0x000E0000, 0x00007000, 0x00001000}, /* CONN_HIF_ON (HOST_CSR) */ + + {0x82060000, 0x00008000, 0x00004000}, /* WF_UMAC_TOP (PLE) */ + {0x82068000, 0x0000C000, 0x00002000}, /* WF_UMAC_TOP (PSE) */ + {0x8206C000, 0x0000E000, 0x00002000}, /* WF_UMAC_TOP (PP) */ + {0x82070000, 0x00010000, 0x00010000}, /* WF_PHY */ + {0x820F0000, 0x00020000, 0x00010000}, /* WF_LMAC_TOP */ + {0x820E0000, 0x00030000, 0x00010000}, /* WF_LMAC_TOP (WF_WTBL) */ + + {0x81000000, 0x00050000, 0x00010000}, /* BTSYS_OFF */ + {0x80070000, 0x00060000, 0x00010000}, /* GPSSYS */ + {0x40000000, 0x00070000, 0x00010000}, /* WF_SYSRAM */ + {0x00300000, 0x00080000, 0x00010000}, /* MCU_SYSRAM */ + + {0x80010000, 0x000A1000, 0x00001000}, /* CONN_MCU_DMA */ + {0x80030000, 0x000A2000, 0x00001000}, /* CONN_MCU_BTIF0 */ + {0x81030000, 0x000A3000, 0x00001000}, /* CONN_MCU_CFG_ON */ + {0x80050000, 0x000A4000, 0x00001000}, /* CONN_UART_PTA */ + {0x81040000, 0x000A5000, 0x00001000}, /* CONN_MCU_CIRQ */ + {0x81050000, 0x000A6000, 0x00001000}, /* CONN_MCU_GPT */ + {0x81060000, 0x000A7000, 0x00001000}, /* CONN_PTA */ + {0x81080000, 0x000A8000, 0x00001000}, /* CONN_MCU_WDT */ + {0x81090000, 0x000A9000, 0x00001000}, /* CONN_MCU_PDA */ + {0x810A0000, 0x000AA000, 0x00001000}, /* CONN_RDD_AHB_WRAP0 */ + {0x810B0000, 0x000AB000, 0x00001000}, /* BTSYS_ON */ + {0x810C0000, 0x000AC000, 0x00001000}, /* CONN_RBIST_TOP */ + {0x810D0000, 0x000AD000, 0x00001000}, /* CONN_RDD_AHB_WRAP0 */ + {0x820D0000, 0x000AE000, 0x00001000}, /* WFSYS_ON */ + {0x60000000, 0x000AF000, 0x00001000}, /* CONN_MCU_PDA */ + + {0x80020000, 0x000B0000, 0x00010000}, /* CONN_TOP_MISC_OFF */ + {0x81020000, 0x000C0000, 0x00010000}, /* CONN_TOP_MISC_ON */ + + {0x0, 0x0, 0x0} +}; +#endif /* _HIF_PCIE || _HIF_AXI */ + +void connacConstructFirmwarePrio(struct GLUE_INFO *prGlueInfo, + uint8_t **apucNameTable, uint8_t **apucName, + uint8_t *pucNameIdx, uint8_t ucMaxNameIdx) +{ + uint8_t ucIdx = 0; + uint8_t aucFlavor[2] = {0}; + int ret = 0; + + kalGetFwFlavor(&aucFlavor[0]); + for (ucIdx = 0; apucConnacFwName[ucIdx]; ucIdx++) { + if ((*pucNameIdx + 3) >= ucMaxNameIdx) { + /* the table is not large enough */ + DBGLOG(INIT, ERROR, + "kalFirmwareImageMapping >> file name array is not enough.\n"); + ASSERT(0); + continue; + } + + /* Type 1. WIFI_RAM_CODE_soc1_0_1_1.bin */ + ret = kalSnprintf(*(apucName + (*pucNameIdx)), + CFG_FW_NAME_MAX_LEN, + "%s_%u%s_%u.bin", + apucConnacFwName[ucIdx], + CFG_WIFI_IP_SET, + aucFlavor, + wlanGetEcoVersion( + prGlueInfo->prAdapter)); + if (ret >= 0 && ret < CFG_FW_NAME_MAX_LEN) + (*pucNameIdx) += 1; + else + DBGLOG(INIT, ERROR, + "[%u] kalSnprintf failed, ret: %d\n", + __LINE__, ret); + + /* Type 2. WIFI_RAM_CODE_soc1_0_1_1 */ + ret = kalSnprintf(*(apucName + (*pucNameIdx)), + CFG_FW_NAME_MAX_LEN, + "%s_%u%s_%u", + apucConnacFwName[ucIdx], + CFG_WIFI_IP_SET, + aucFlavor, + wlanGetEcoVersion( + prGlueInfo->prAdapter)); + if (ret >= 0 && ret < CFG_FW_NAME_MAX_LEN) + (*pucNameIdx) += 1; + else + DBGLOG(INIT, ERROR, + "[%u] kalSnprintf failed, ret: %d\n", + __LINE__, ret); + + /* Type 3. WIFI_RAM_CODE_soc1_0 */ + ret = kalSnprintf(*(apucName + (*pucNameIdx)), + CFG_FW_NAME_MAX_LEN, "%s", + apucConnacFwName[ucIdx]); + if (ret >= 0 && ret < CFG_FW_NAME_MAX_LEN) + (*pucNameIdx) += 1; + else + DBGLOG(INIT, ERROR, + "[%u] kalSnprintf failed, ret: %d\n", + __LINE__, ret); + + /* Type 4. WIFI_RAM_CODE_soc1_0.bin */ + ret = kalSnprintf(*(apucName + (*pucNameIdx)), + CFG_FW_NAME_MAX_LEN, "%s.bin", + apucConnacFwName[ucIdx]); + if (ret >= 0 && ret < CFG_FW_NAME_MAX_LEN) + (*pucNameIdx) += 1; + else + DBGLOG(INIT, ERROR, + "[%u] kalSnprintf failed, ret: %d\n", + __LINE__, ret); + } +} + +void connacConstructPatchName(struct GLUE_INFO *prGlueInfo, + uint8_t **apucName, uint8_t *pucNameIdx) +{ + int ret = 0; + + ret = kalSnprintf(apucName[(*pucNameIdx)], + CFG_FW_NAME_MAX_LEN, "mtsoc1_0_patch_e%x_hdr.bin", + wlanGetEcoVersion(prGlueInfo->prAdapter)); + if (ret < 0 || ret >= CFG_FW_NAME_MAX_LEN) + DBGLOG(INIT, ERROR, "kalSnprintf failed, ret: %d\n", ret); +} + +struct BUS_INFO connac_bus_info = { +#if defined(_HIF_PCIE) || defined(_HIF_AXI) + .top_cfg_base = CONNAC_TOP_CFG_BASE, + .host_tx_ring_base = MT_TX_RING_BASE, + .host_tx_ring_ext_ctrl_base = MT_TX_RING_BASE_EXT, + .host_tx_ring_cidx_addr = MT_TX_RING_CIDX, + .host_tx_ring_didx_addr = MT_TX_RING_DIDX, + .host_tx_ring_cnt_addr = MT_TX_RING_CNT, + + .host_rx_ring_base = MT_RX_RING_BASE, + .host_rx_ring_ext_ctrl_base = MT_RX_RING_BASE_EXT, + .host_rx_ring_cidx_addr = MT_RX_RING_CIDX, + .host_rx_ring_didx_addr = MT_RX_RING_DIDX, + .host_rx_ring_cnt_addr = MT_RX_RING_CNT, + .bus2chip = connac_bus2chip_cr_mapping, + .tx_ring_fwdl_idx = 3, + .tx_ring_cmd_idx = 15, + .tx_ring0_data_idx = 0, + .tx_ring1_data_idx = 0, /* no used */ + .fw_own_clear_addr = WPDMA_INT_STA, + .fw_own_clear_bit = WPDMA_FW_CLR_OWN_INT, + .max_static_map_addr = 0x00040000, + .fgCheckDriverOwnInt = FALSE, + .u4DmaMask = 36, + + .pdmaSetup = asicPdmaConfig, + .updateTxRingMaxQuota = NULL, + .enableInterrupt = asicEnableInterrupt, + .disableInterrupt = asicDisableInterrupt, + .lowPowerOwnRead = asicLowPowerOwnRead, + .lowPowerOwnSet = asicLowPowerOwnSet, + .lowPowerOwnClear = asicLowPowerOwnClear, + .wakeUpWiFi = asicWakeUpWiFi, + .isValidRegAccess = asicIsValidRegAccess, + .getMailboxStatus = asicGetMailboxStatus, + .setDummyReg = asicSetDummyReg, + .checkDummyReg = asicCheckDummyReg, + .tx_ring_ext_ctrl = asicPdmaTxRingExtCtrl, + .rx_ring_ext_ctrl = asicPdmaRxRingExtCtrl, + .hifRst = NULL, + .initPcieInt = NULL, + .DmaShdlInit = asicPcieDmaShdlInit, + .setPdmaIntMask = asicPdmaIntMaskConfig, +#endif /* _HIF_PCIE || _HIF_AXI */ +#if defined(_HIF_USB) + .u4UdmaWlCfg_0_Addr = CONNAC_UDMA_WLCFG_0, + .u4UdmaWlCfg_1_Addr = CONNAC_UDMA_WLCFG_1, + .u4UdmaWlCfg_0 = + (UDMA_WLCFG_0_TX_EN(1) | + UDMA_WLCFG_0_RX_EN(1) | + UDMA_WLCFG_0_RX_MPSZ_PAD0(1) | + UDMA_WLCFG_0_1US_TIMER_EN(1)), + .u4device_vender_request_in = DEVICE_VENDOR_REQUEST_IN, + .u4device_vender_request_out = DEVICE_VENDOR_REQUEST_OUT, + .asicUsbSuspend = NULL, + .asicUsbResume = NULL, + .asicUsbEventEpDetected = NULL, + .asicUsbRxByteCount = NULL, + .DmaShdlInit = asicUsbDmaShdlInit, +#endif /* _HIF_USB */ +}; + +struct FWDL_OPS_T connac_fw_dl_ops = { + .constructFirmwarePrio = connacConstructFirmwarePrio, + .constructPatchName = connacConstructPatchName, +#if !CFG_MTK_ANDROID_WMT + .downloadPatch = wlanDownloadPatch, +#endif + .downloadFirmware = wlanConnacFormatDownload, + .downloadByDynMemMap = NULL, + .getFwInfo = wlanGetConnacFwInfo, + .getFwDlInfo = asicGetFwDlInfo, + .phyAction = NULL, +}; + +struct TX_DESC_OPS_T connacTxDescOps = { + .fillNicAppend = fillNicTxDescAppend, + .fillHifAppend = fillTxDescAppendByHostV2, + .fillTxByteCount = fillTxDescTxByteCount, +}; + +struct RX_DESC_OPS_T connacRxDescOps = { +}; + +#if CFG_SUPPORT_QA_TOOL +struct ATE_OPS_T connacAteOps = { + .setICapStart = connacSetICapStart, + .getICapStatus = connacGetICapStatus, + .getICapIQData = connacGetICapIQData, + .getRbistDataDumpEvent = nicExtEventICapIQData, +}; +#endif + +struct CHIP_DBG_OPS connac_debug_ops = { +#if defined(_HIF_PCIE) || defined(_HIF_AXI) + .showPdmaInfo = halShowPdmaInfo, + .showPseInfo = halShowPseInfo, + .showPleInfo = halShowPleInfo, + .showTxdInfo = halShowTxdInfo, + .showCsrInfo = halShowHostCsrInfo, + .showDmaschInfo = halShowDmaschInfo, + .dumpMacInfo = haldumpMacInfo, +#else + .showPdmaInfo = NULL, + .showPseInfo = NULL, + .showPleInfo = NULL, + .showTxdInfo = NULL, + .showCsrInfo = NULL, + .showDmaschInfo = NULL, + .dumpMacInfo = NULL, +#endif + .showWtblInfo = NULL, + .showHifInfo = NULL, + .printHifDbgInfo = halPrintHifDbgInfo, + .show_stat_info = halShowStatInfo, +#ifdef CFG_SUPPORT_LINK_QUALITY_MONITOR + .get_rx_rate_info = connac_get_rx_rate_info, +#endif +}; + +struct mt66xx_chip_info mt66xx_chip_info_connac = { + .bus_info = &connac_bus_info, + .fw_dl_ops = &connac_fw_dl_ops, + .prTxDescOps = &connacTxDescOps, + .prRxDescOps = &connacRxDescOps, +#if CFG_SUPPORT_QA_TOOL + .prAteOps = &connacAteOps, +#endif + .prDebugOps = &connac_debug_ops, + + .chip_id = CONNAC_CHIP_ID, + .should_verify_chip_id = FALSE, + .sw_sync0 = CONNAC_SW_SYNC0, + .sw_ready_bits = WIFI_FUNC_NO_CR4_READY_BITS, + .sw_ready_bit_offset = CONNAC_SW_SYNC0_RDY_OFFSET, + .patch_addr = CONNAC_PATCH_START_ADDR, + .is_support_cr4 = FALSE, + .txd_append_size = CONNAC_TX_DESC_APPEND_LENGTH, + .rxd_size = CONNAC_RX_DESC_LENGTH, + .init_evt_rxd_size = CONNAC_INIT_EVT_RX_DESC_LENGTH, + .pse_header_length = NIC_TX_PSE_HEADER_LENGTH, + .init_event_size = CONNAC_RX_INIT_EVENT_LENGTH, + .event_hdr_size = CONNAC_RX_EVENT_HDR_LENGTH, + .eco_info = connac_eco_table, + .isNicCapV1 = FALSE, + .is_support_efuse = FALSE, + + /* IP info, should be overwrite by getNicCapabalityV2 */ + .u4ChipIpVersion = CONNAC_CHIP_IP_VERSION, + .u4ChipIpConfig = CONNAC_CHIP_IP_CONFIG, + .u2ADieChipVersion = CONNAC_CHIP_ADIE_INFO, + .asicCapInit = asicCapInit, + .asicEnableFWDownload = asicEnableFWDownload, + .asicGetChipID = asicGetChipID, + .downloadBufferBin = NULL, + .is_support_hw_amsdu = FALSE, + .ucMaxSwAmsduNum = 4, + .ucMaxSwapAntenna = 2, + .workAround = 0, + + .top_hcr = TOP_HCR, + .top_hvr = TOP_HVR, + .top_fvr = TOP_FVR, + .custom_oid_interface_version = MTK_CUSTOM_OID_INTERFACE_VERSION, + .em_interface_version = MTK_EM_INTERFACE_VERSION, +}; + +struct mt66xx_hif_driver_data mt66xx_driver_data_connac = { + .chip_info = &mt66xx_chip_info_connac, +}; + +#endif /* CONNAC */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/connac2x2/connac2x2.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/connac2x2/connac2x2.c new file mode 100644 index 0000000000000000000000000000000000000000..a362a70c6aa82a0ff467da03f32e7c9ed1978906 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/connac2x2/connac2x2.c @@ -0,0 +1,448 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/*! \file connac.c + * \brief Internal driver stack will export the required procedures here + * for GLUE Layer. + * + * This file contains all routines which are exported from MediaTek 802.11 + * Wireless LAN driver stack to GLUE Layer. + */ + +#ifdef CONNAC2X2 + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" + +#include "connac2x2.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +uint8_t *apucConnac2x2FwName[] = { + (uint8_t *) CFG_FW_FILENAME "_soc2_0", + NULL +}; + +struct ECO_INFO connac2x2_eco_table[] = { + /* HW version, ROM version, Factory version */ + {0x00, 0x00, 0xA, 0x1}, /* E1 */ + {0x00, 0x00, 0x0, 0x0} /* End of table */ +}; + +#if defined(_HIF_PCIE) || defined(_HIF_AXI) +struct PCIE_CHIP_CR_MAPPING connac2x2_bus2chip_cr_mapping[] = { + /* chip addr, bus addr, range */ + {0x80000000, 0x00002000, 0x00001000}, /* MCU_CFG */ + + {0x50000000, 0x00004000, 0x00004000}, /* CONN_HIF (PDMA) */ + {0x50002000, 0x00005000, 0x00001000}, /* CONN_HIF (Reserved) */ + {0x5000A000, 0x00006000, 0x00001000}, /* CONN_HIF (DMASHDL) */ + {0x000E0000, 0x00007000, 0x00001000}, /* CONN_HIF_ON (HOST_CSR) */ + + {0x82060000, 0x00008000, 0x00004000}, /* WF_UMAC_TOP (PLE) */ + {0x82068000, 0x0000C000, 0x00002000}, /* WF_UMAC_TOP (PSE) */ + {0x8206C000, 0x0000E000, 0x00002000}, /* WF_UMAC_TOP (PP) */ + {0x82070000, 0x00010000, 0x00010000}, /* WF_PHY */ + {0x820F0000, 0x00020000, 0x00010000}, /* WF_LMAC_TOP */ + {0x820E0000, 0x00030000, 0x00010000}, /* WF_LMAC_TOP (WF_WTBL) */ + + {0x81000000, 0x00050000, 0x00010000}, /* BTSYS_OFF */ + {0x80070000, 0x00060000, 0x00010000}, /* GPSSYS */ + {0x40000000, 0x00070000, 0x00010000}, /* WF_SYSRAM */ + {0x00300000, 0x00080000, 0x00010000}, /* MCU_SYSRAM */ + + {0x80010000, 0x000A1000, 0x00001000}, /* CONN_MCU_DMA */ + {0x80030000, 0x000A2000, 0x00001000}, /* CONN_MCU_BTIF0 */ + {0x81030000, 0x000A3000, 0x00001000}, /* CONN_MCU_CFG_ON */ + {0x80050000, 0x000A4000, 0x00001000}, /* CONN_UART_PTA */ + {0x81040000, 0x000A5000, 0x00001000}, /* CONN_MCU_CIRQ */ + {0x81050000, 0x000A6000, 0x00001000}, /* CONN_MCU_GPT */ + {0x81060000, 0x000A7000, 0x00001000}, /* CONN_PTA */ + {0x81080000, 0x000A8000, 0x00001000}, /* CONN_MCU_WDT */ + {0x81090000, 0x000A9000, 0x00001000}, /* CONN_MCU_PDA */ + {0x810A0000, 0x000AA000, 0x00001000}, /* CONN_RDD_AHB_WRAP0 */ + {0x810B0000, 0x000AB000, 0x00001000}, /* BTSYS_ON */ + {0x810C0000, 0x000AC000, 0x00001000}, /* CONN_RBIST_TOP */ + {0x810D0000, 0x000AD000, 0x00001000}, /* CONN_RDD_AHB_WRAP0 */ + {0x820D0000, 0x000AE000, 0x00001000}, /* WFSYS_ON */ + {0x60000000, 0x000AF000, 0x00001000}, /* CONN_MCU_PDA */ + + {0x80020000, 0x000B0000, 0x00010000}, /* CONN_TOP_MISC_OFF */ + {0x81020000, 0x000C0000, 0x00010000}, /* CONN_TOP_MISC_ON */ + + {0x0, 0x0, 0x0} +}; +#endif /* _HIF_PCIE || _HIF_AXI */ + +void connac2x2ShowHifInfo(IN struct ADAPTER *prAdapter) +{ + uint32_t u4Value = 0; + + /* conn2ap axi master sleep info */ + HAL_MCR_RD(prAdapter, 0xBC010, &u4Value); + DBGLOG(HAL, INFO, + "Conn2ap axi master sleep prot info: 0x%08x\n", u4Value); + + /* conn_mcu2ap axi master sleep info */ + HAL_MCR_RD(prAdapter, 0xBC014, &u4Value); + DBGLOG(HAL, INFO, + "Conn_mcu2ap axi master sleep info: 0x%08x\n", u4Value); + + /* conn2ap axi gals bus info */ + HAL_MCR_RD(prAdapter, 0xBC018, &u4Value); + DBGLOG(HAL, INFO, "Conn2ap axi gals bus info: 0x%08x\n", u4Value); + + /* conn2ap mux4to1 debug info */ + HAL_MCR_RD(prAdapter, 0xBC01C, &u4Value); + DBGLOG(HAL, INFO, "Conn2ap mux4to1 debug info: 0x%08x\n", u4Value); + + /* conn_hif_off bus busy info */ + HAL_MCR_RD(prAdapter, 0xBC020, &u4Value); + DBGLOG(HAL, INFO, "Conn_hif_off bus busy info: 0x%08x\n", u4Value); + + /* conn_hif_on misc info */ + HAL_MCR_RD(prAdapter, 0x0713C, &u4Value); + DBGLOG(HAL, INFO, "Conn_hif_on misc info: 0x%08x\n", u4Value); + + /* conn_on_host debug flag */ + HAL_MCR_RD(prAdapter, 0xC1144, &u4Value); + DBGLOG(HAL, INFO, "Conn_on_host debug flag: 0x%08x\n", u4Value); +} + +void connac2x2ConstructFirmwarePrio(struct GLUE_INFO *prGlueInfo, + uint8_t **apucNameTable, uint8_t **apucName, + uint8_t *pucNameIdx, uint8_t ucMaxNameIdx) +{ + uint8_t ucIdx = 0; + uint8_t aucFlavor[2] = {0}; + int ret = 0; + + kalGetFwFlavor(&aucFlavor[0]); + for (ucIdx = 0; apucConnac2x2FwName[ucIdx]; ucIdx++) { + if ((*pucNameIdx + 3) >= ucMaxNameIdx) { + /* the table is not large enough */ + DBGLOG(INIT, ERROR, + "kalFirmwareImageMapping >> file name array is not enough.\n"); + ASSERT(0); + continue; + } + + /* Type 1. WIFI_RAM_CODE_soc1_0_1_1.bin */ + ret = kalSnprintf(*(apucName + (*pucNameIdx)), + CFG_FW_NAME_MAX_LEN, + "%s_%u%s_%u.bin", + apucConnac2x2FwName[ucIdx], + CFG_WIFI_IP_SET, + aucFlavor, + wlanGetEcoVersion( + prGlueInfo->prAdapter)); + if (ret >= 0 && ret < CFG_FW_NAME_MAX_LEN) + (*pucNameIdx) += 1; + else + DBGLOG(INIT, ERROR, + "[%u] kalSnprintf failed, ret: %d\n", + __LINE__, ret); + + /* Type 2. WIFI_RAM_CODE_soc1_0_1_1 */ + ret = kalSnprintf(*(apucName + (*pucNameIdx)), + CFG_FW_NAME_MAX_LEN, + "%s_%u%s_%u", + apucConnac2x2FwName[ucIdx], + CFG_WIFI_IP_SET, + aucFlavor, + wlanGetEcoVersion( + prGlueInfo->prAdapter)); + if (ret >= 0 && ret < CFG_FW_NAME_MAX_LEN) + (*pucNameIdx) += 1; + else + DBGLOG(INIT, ERROR, + "[%u] kalSnprintf failed, ret: %d\n", + __LINE__, ret); + + /* Type 3. WIFI_RAM_CODE_soc1_0 */ + ret = kalSnprintf(*(apucName + (*pucNameIdx)), + CFG_FW_NAME_MAX_LEN, "%s", + apucConnac2x2FwName[ucIdx]); + if (ret >= 0 && ret < CFG_FW_NAME_MAX_LEN) + (*pucNameIdx) += 1; + else + DBGLOG(INIT, ERROR, + "[%u] kalSnprintf failed, ret: %d\n", + __LINE__, ret); + + /* Type 4. WIFI_RAM_CODE_soc1_0.bin */ + ret = kalSnprintf(*(apucName + (*pucNameIdx)), + CFG_FW_NAME_MAX_LEN, "%s.bin", + apucConnac2x2FwName[ucIdx]); + if (ret >= 0 && ret < CFG_FW_NAME_MAX_LEN) + (*pucNameIdx) += 1; + else + DBGLOG(INIT, ERROR, + "[%u] kalSnprintf failed, ret: %d\n", + __LINE__, ret); + } +} + +void connac2x2ConstructPatchName(struct GLUE_INFO *prGlueInfo, + uint8_t **apucName, uint8_t *pucNameIdx) +{ + int ret = 0; + + ret = kalSnprintf(apucName[(*pucNameIdx)], + CFG_FW_NAME_MAX_LEN, "mtsoc1_0_patch_e%x_hdr.bin", + wlanGetEcoVersion(prGlueInfo->prAdapter)); + if (ret < 0 || ret >= CFG_FW_NAME_MAX_LEN) + DBGLOG(INIT, ERROR, "kalSnprintf failed, ret: %d\n", ret); +} + +void connac2x2wlanCalDebugCmd(uint32_t cmd, uint32_t para) +{ + DBGLOG(RFTEST, INFO, "Cal CMD: (%d, %d) -> WMT reset\n", cmd, para); + mtk_wcn_wmt_do_reset_only(WMTDRV_TYPE_WIFI); + /* wait for reset done */ + fgIsResetting = TRUE; + do { + kalMsleep(500); + } while (kalIsResetting()); +} + +struct BUS_INFO connac2x2_bus_info = { +#if defined(_HIF_PCIE) || defined(_HIF_AXI) + .top_cfg_base = CONNAC2X2_TOP_CFG_BASE, + .host_tx_ring_base = MT_TX_RING_BASE, + .host_tx_ring_ext_ctrl_base = MT_TX_RING_BASE_EXT, + .host_tx_ring_cidx_addr = MT_TX_RING_CIDX, + .host_tx_ring_didx_addr = MT_TX_RING_DIDX, + .host_tx_ring_cnt_addr = MT_TX_RING_CNT, + + .host_rx_ring_base = MT_RX_RING_BASE, + .host_rx_ring_ext_ctrl_base = MT_RX_RING_BASE_EXT, + .host_rx_ring_cidx_addr = MT_RX_RING_CIDX, + .host_rx_ring_didx_addr = MT_RX_RING_DIDX, + .host_rx_ring_cnt_addr = MT_RX_RING_CNT, + .bus2chip = connac2x2_bus2chip_cr_mapping, + .tx_ring_fwdl_idx = 3, + .tx_ring_cmd_idx = 15, + .tx_ring0_data_idx = 0, + /* Make sure your HIF_TX_MSDU_TOKEN_NUM is larger enough + * to support max HW(or SW) AMSDU number. + */ + .tx_ring1_data_idx = 1, + .fw_own_clear_addr = WPDMA_INT_STA, + .fw_own_clear_bit = WPDMA_FW_CLR_OWN_INT, + .max_static_map_addr = 0x000E0000, + .fgCheckDriverOwnInt = FALSE, + .u4DmaMask = 36, + + .pdmaSetup = asicPdmaConfig, + .updateTxRingMaxQuota = asicUpdatTxRingMaxQuota, + .enableInterrupt = asicEnableInterrupt, + .disableInterrupt = asicDisableInterrupt, + .lowPowerOwnRead = asicLowPowerOwnRead, + .lowPowerOwnSet = asicLowPowerOwnSet, + .lowPowerOwnClear = asicLowPowerOwnClear, + .wakeUpWiFi = asicWakeUpWiFi, + .isValidRegAccess = asicIsValidRegAccess, + .getMailboxStatus = asicGetMailboxStatus, + .setDummyReg = asicSetDummyReg, + .checkDummyReg = asicCheckDummyReg, + .tx_ring_ext_ctrl = asicPdmaTxRingExtCtrl, + .rx_ring_ext_ctrl = asicPdmaRxRingExtCtrl, + .hifRst = NULL, + .initPcieInt = NULL, + .DmaShdlInit = asicPcieDmaShdlInit, + .setPdmaIntMask = asicPdmaIntMaskConfig, +#endif /* _HIF_PCIE || _HIF_AXI */ +#if defined(_HIF_USB) + .u4UdmaWlCfg_0_Addr = CONNAC_UDMA_WLCFG_0, + .u4UdmaWlCfg_1_Addr = CONNAC_UDMA_WLCFG_1, + .u4UdmaWlCfg_0 = + (UDMA_WLCFG_0_TX_EN(1) | + UDMA_WLCFG_0_RX_EN(1) | + UDMA_WLCFG_0_RX_MPSZ_PAD0(1) | + UDMA_WLCFG_0_1US_TIMER_EN(1)), + .u4device_vender_request_in = DEVICE_VENDOR_REQUEST_IN, + .u4device_vender_request_out = DEVICE_VENDOR_REQUEST_OUT, + .asicUsbSuspend = NULL, + .asicUsbResume = NULL, + .asicUsbEventEpDetected = NULL, + .asicUsbRxByteCount = NULL, + .DmaShdlInit = NULL, /* for owner to hook */ +#endif /* _HIF_USB */ +}; + +struct FWDL_OPS_T connac2x2_fw_dl_ops = { + .constructFirmwarePrio = connac2x2ConstructFirmwarePrio, + .constructPatchName = connac2x2ConstructPatchName, +#if !CFG_MTK_ANDROID_WMT + .downloadPatch = wlanDownloadPatch, +#endif + .downloadFirmware = wlanConnacFormatDownload, + .downloadByDynMemMap = NULL, + .getFwInfo = wlanGetConnacFwInfo, + .getFwDlInfo = asicGetFwDlInfo, + .phyAction = NULL, +}; + +struct TX_DESC_OPS_T connac2x2TxDescOps = { + .fillNicAppend = fillNicTxDescAppend, + .fillHifAppend = fillTxDescAppendByHostV2, + .fillTxByteCount = fillTxDescTxByteCount, +}; + +struct RX_DESC_OPS_T connac2x2RxDescOps = { +}; + +#if CFG_SUPPORT_QA_TOOL +struct ATE_OPS_T connac2x2AteOps = { + .setICapStart = connacSetICapStart, + .getICapStatus = connacGetICapStatus, + .getICapIQData = connacGetICapIQData, + .getRbistDataDumpEvent = nicExtEventICapIQData, +}; +#endif + +struct CHIP_DBG_OPS connac2x2_debug_ops = { +#if defined(_HIF_PCIE) || defined(_HIF_AXI) + .showPdmaInfo = halShowPdmaInfo, + .showPseInfo = halShowPseInfo, + .showPleInfo = halShowPleInfo, + .showTxdInfo = halShowTxdInfo, + .showCsrInfo = halShowHostCsrInfo, + .showDmaschInfo = halShowDmaschInfo, + .dumpMacInfo = haldumpMacInfo, + .showHifInfo = connac2x2ShowHifInfo, +#else + .showPdmaInfo = NULL, + .showPseInfo = NULL, + .showPleInfo = NULL, + .showTxdInfo = NULL, + .showCsrInfo = NULL, + .showDmaschInfo = NULL, + .dumpMacInfo = NULL, + .showHifInfo = NULL, +#endif + .showWtblInfo = NULL, + .printHifDbgInfo = halPrintHifDbgInfo, + .show_stat_info = halShowStatInfo, +#ifdef CFG_SUPPORT_LINK_QUALITY_MONITOR + .get_rx_rate_info = connac_get_rx_rate_info, +#endif +}; + +struct mt66xx_chip_info mt66xx_chip_info_connac2x2 = { + .bus_info = &connac2x2_bus_info, + .fw_dl_ops = &connac2x2_fw_dl_ops, + .prTxDescOps = &connac2x2TxDescOps, + .prRxDescOps = &connac2x2RxDescOps, +#if CFG_SUPPORT_QA_TOOL + .prAteOps = &connac2x2AteOps, +#endif + .prDebugOps = &connac2x2_debug_ops, + + .chip_id = CONNAC2X2_CHIP_ID, + .should_verify_chip_id = FALSE, + .sw_sync0 = CONNAC2X2_SW_SYNC0, + .sw_ready_bits = WIFI_FUNC_NO_CR4_READY_BITS, + .sw_ready_bit_offset = CONNAC2X2_SW_SYNC0_RDY_OFFSET, + .patch_addr = CONNAC2X2_PATCH_START_ADDR, + .is_support_cr4 = FALSE, + .txd_append_size = CONNAC2X2_TX_DESC_APPEND_LENGTH, + .rxd_size = CONNAC2X2_RX_DESC_LENGTH, + .init_evt_rxd_size = CONNAC2X2_RX_DESC_LENGTH, + .pse_header_length = NIC_TX_PSE_HEADER_LENGTH, + .init_event_size = CONNAC2X2_RX_INIT_EVENT_LENGTH, + .event_hdr_size = CONNAC2X2_RX_EVENT_HDR_LENGTH, + .eco_info = connac2x2_eco_table, + .isNicCapV1 = FALSE, + .is_support_efuse = FALSE, + + /* IP info, should be overwrite by getNicCapabalityV2 */ + .u4ChipIpVersion = CONNAC_CHIP_IP_VERSION, + .u4ChipIpConfig = CONNAC_CHIP_IP_CONFIG, + .u2ADieChipVersion = CONNAC_CHIP_ADIE_INFO, + .asicCapInit = asicCapInit, + .asicEnableFWDownload = asicEnableFWDownload, + .asicGetChipID = asicGetChipID, + .downloadBufferBin = NULL, + .is_support_hw_amsdu = TRUE, + .ucMaxSwAmsduNum = 0, + /* Driver uses SOC to decide to use connac or connac2x2 configs + * But sometimes one SOC may use connac2x2 on 1x1 chip + * So we have to update the related configs for compatibility + */ + .ucMaxSwapAntenna = 2, + .workAround = 0, + + .top_hcr = TOP_HCR, + .top_hvr = TOP_HVR, + .top_fvr = TOP_FVR, + .custom_oid_interface_version = MTK_CUSTOM_OID_INTERFACE_VERSION, + .em_interface_version = MTK_EM_INTERFACE_VERSION, + + .calDebugCmd = connac2x2wlanCalDebugCmd, +}; + +struct mt66xx_hif_driver_data mt66xx_driver_data_connac2x2 = { + .chip_info = &mt66xx_chip_info_connac2x2, +}; + +#endif /* CONNAC2X2 */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/mt6632/mt6632.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/mt6632/mt6632.c new file mode 100644 index 0000000000000000000000000000000000000000..5acd7153add8547c22aab6e9f66fab2c06e41ed3 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/mt6632/mt6632.c @@ -0,0 +1,495 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/*! \file mt6632.c + * \brief Internal driver stack will export the required procedures here + * for GLUE Layer. + * + * This file contains all routines which are exported from MediaTek 802.11 + * Wireless LAN driver stack to GLUE Layer. + */ + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" + +#include "mt6632.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +struct ECO_INFO mt6632_eco_table[] = { + /* HW version, ROM version, Factory version, Eco version */ + {0x00, 0x00, 0xA, 0x1}, /* E1 */ + {0x00, 0x00, 0xA, 0x2}, /* E2 */ + {0x10, 0x10, 0xA, 0x3}, /* E3 */ + + {0x00, 0x00, 0x0, 0x0} /* End of table */ +}; + +#if defined(_HIF_PCIE) +struct PCIE_CHIP_CR_MAPPING mt6632_bus2chip_cr_mapping[] = { + /* chip addr, bus addr, range */ + {0x82060000, 0x00008000, 0x00000450}, /* WF_PLE */ + {0x82068000, 0x0000c000, 0x00000450}, /* WF_PSE */ + {0x8206c000, 0x0000e000, 0x00000300}, /* PP */ + {0x820d0000, 0x00020000, 0x00000200}, /* WF_AON */ + {0x820f0000, 0x00020200, 0x00000400}, /* WF_CFG */ + {0x820f0800, 0x00020600, 0x00000200}, /* WF_CFGOFF */ + {0x820f1000, 0x00020800, 0x00000200}, /* WF_TRB */ + {0x820f2000, 0x00020a00, 0x00000200}, /* WF_AGG */ + {0x820f3000, 0x00020c00, 0x00000400}, /* WF_ARB */ + {0x820f4000, 0x00021000, 0x00000200}, /* WF_TMAC */ + {0x820f5000, 0x00021200, 0x00000400}, /* WF_RMAC */ + {0x820f6000, 0x00021600, 0x00000200}, /* WF_SEC */ + {0x820f7000, 0x00021800, 0x00000200}, /* WF_DMA */ + + {0x820f8000, 0x00022000, 0x00001000}, /* WF_PF */ + {0x820f9000, 0x00023000, 0x00000400}, /* WF_WTBLON */ + {0x820f9800, 0x00023400, 0x00000200}, /* WF_WTBLOFF */ + + {0x820fa000, 0x00024000, 0x00000200}, /* WF_ETBF */ + {0x820fb000, 0x00024200, 0x00000400}, /* WF_LPON */ + {0x820fc000, 0x00024600, 0x00000200}, /* WF_INT */ + {0x820fd000, 0x00024800, 0x00000400}, /* WF_MIB */ + + {0x820fe000, 0x00025000, 0x00002000}, /* WF_MU */ + + {0x820e0000, 0x00030000, 0x00010000}, /* WF_WTBL */ + + {0x80020000, 0x00000000, 0x00002000}, /* TOP_CFG */ + {0x80000000, 0x00002000, 0x00002000}, /* MCU_CFG */ + {0x50000000, 0x00004000, 0x00004000}, /* PDMA_CFG */ + {0xA0000000, 0x00008000, 0x00008000}, /* PSE_CFG */ + {0x82070000, 0x00010000, 0x00010000}, /* WF_PHY */ + + {0x0, 0x0, 0x0} +}; +#endif /* _HIF_PCIE */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +void mt6632CapInit(IN struct ADAPTER *prAdapter) +{ + struct GLUE_INFO *prGlueInfo; + struct mt66xx_chip_info *prChipInfo; + + ASSERT(prAdapter); + + prGlueInfo = prAdapter->prGlueInfo; + prChipInfo = prAdapter->chip_info; + + prChipInfo->u2HifTxdSize = 0; + prChipInfo->u2TxInitCmdPort = 0; + prChipInfo->u2TxFwDlPort = 0; + prChipInfo->fillHifTxDesc = NULL; + prChipInfo->ucPacketFormat = TXD_PKT_FORMAT_TXD; + prChipInfo->u4ExtraTxByteCount = 0; + prChipInfo->asicFillInitCmdTxd = asicFillInitCmdTxd; + prChipInfo->asicFillCmdTxd = asicFillCmdTxd; + prChipInfo->u2CmdTxHdrSize = sizeof(struct WIFI_CMD); + prChipInfo->u2RxSwPktBitMap = RXM_RXD_PKT_TYPE_SW_BITMAP; + prChipInfo->u2RxSwPktEvent = RXM_RXD_PKT_TYPE_SW_EVENT; + prChipInfo->u2RxSwPktFrame = RXM_RXD_PKT_TYPE_SW_FRAME; + asicInitTxdHook(prChipInfo->prTxDescOps); + asicInitRxdHook(prChipInfo->prRxDescOps); +#if CFG_SUPPORT_WIFI_SYSDVT + prAdapter->u2TxTest = TX_TEST_UNLIMITIED; + prAdapter->u2TxTestCount = 0; + prAdapter->ucTxTestUP = TX_TEST_UP_UNDEF; +#endif /* CFG_SUPPORT_WIFI_SYSDVT */ + + switch (prGlueInfo->u4InfType) { +#if defined(_HIF_PCIE) + case MT_DEV_INF_PCIE: + prChipInfo->u2TxInitCmdPort = TX_RING_FWDL_IDX_3; + prChipInfo->u2TxFwDlPort = TX_RING_FWDL_IDX_3; + break; +#endif /* _HIF_PCIE */ +#if defined(_HIF_USB) + case MT_DEV_INF_USB: + prChipInfo->u2TxInitCmdPort = USB_DATA_BULK_OUT_EP8; + prChipInfo->u2TxFwDlPort = USB_DATA_BULK_OUT_EP8; + break; +#endif /* _HIF_USB */ + default: + break; + } +} + +uint32_t mt6632GetFwDlInfo(struct ADAPTER *prAdapter, + char *pcBuf, int i4TotalLen) +{ + struct WIFI_VER_INFO *prVerInfo = &prAdapter->rVerInfo; +#if CFG_SUPPORT_COMPRESSION_FW_OPTION + struct TAILER_FORMAT_T_2 *prTailer; +#else + struct TAILER_FORMAT_T *prTailer; +#endif + uint32_t u4Offset = 0; + uint8_t aucBuf[32]; + +#if CFG_SUPPORT_COMPRESSION_FW_OPTION + prTailer = &prVerInfo->rN9Compressedtailer; +#else + prTailer = &prVerInfo->rN9tailer[0]; +#endif + kalMemZero(aucBuf, 32); + kalMemCopy(aucBuf, prTailer->ram_version, 10); + u4Offset += snprintf(pcBuf + u4Offset, i4TotalLen - u4Offset, + "N9 tailer version %s (%s) info %u:E%u\n", + aucBuf, prTailer->ram_built_date, prTailer->chip_info, + prTailer->eco_code + 1); + +#if CFG_SUPPORT_COMPRESSION_FW_OPTION + prTailer = &prVerInfo->rCR4Compressedtailer; +#else + prTailer = &prVerInfo->rCR4tailer[0]; +#endif + kalMemZero(aucBuf, 32); + kalMemCopy(aucBuf, prTailer->ram_version, 10); + u4Offset += snprintf(pcBuf + u4Offset, i4TotalLen - u4Offset, + "CR4 tailer version %s (%s) info %u:E%u\n", + aucBuf, prTailer->ram_built_date, prTailer->chip_info, + prTailer->eco_code + 1); + + return u4Offset; +} + +#if defined(_HIF_PCIE) + +void mt6632PdmaConfig(struct GLUE_INFO *prGlueInfo, u_int8_t enable, + bool fgResetHif) +{ + struct BUS_INFO *prBusInfo = prGlueInfo->prAdapter->chip_info->bus_info; + union WPDMA_GLO_CFG_STRUCT GloCfg; + union WPDMA_INT_MASK IntMask; + + kalDevRegRead(prGlueInfo, WPDMA_GLO_CFG, &GloCfg.word); + + kalDevRegRead(prGlueInfo, WPDMA_INT_MSK, &IntMask.word); + + if (enable == TRUE) { + GloCfg.field.EnableTxDMA = 1; + GloCfg.field.EnableRxDMA = 1; + GloCfg.field.EnTXWriteBackDDONE = 1; + GloCfg.field.WPDMABurstSIZE = 3; + GloCfg.field.omit_tx_info = 1; + GloCfg.field.fifo_little_endian = 1; + GloCfg.field.multi_dma_en = 3; + GloCfg.field.clk_gate_dis = 1; + + IntMask.field.rx_done_0 = 1; + IntMask.field.rx_done_1 = 1; + IntMask.field.tx_done = BIT(prBusInfo->tx_ring_fwdl_idx) | + BIT(prBusInfo->tx_ring_cmd_idx) | + BIT(prBusInfo->tx_ring0_data_idx)| + BIT(prBusInfo->tx_ring1_data_idx); + } else { + GloCfg.field.EnableRxDMA = 0; + GloCfg.field.EnableTxDMA = 0; + GloCfg.field.multi_dma_en = 2; + + IntMask.field.rx_done_0 = 0; + IntMask.field.rx_done_1 = 0; + IntMask.field.tx_done = 0; + } + + kalDevRegWrite(prGlueInfo, WPDMA_INT_MSK, IntMask.word); + + kalDevRegWrite(prGlueInfo, WPDMA_GLO_CFG, GloCfg.word); +} + +void mt6632LowPowerOwnRead(IN struct ADAPTER *prAdapter, + OUT u_int8_t *pfgResult) +{ + uint32_t u4RegValue; + + HAL_MCR_RD(prAdapter, WPDMA_INT_STA, &u4RegValue); + *pfgResult = ((u4RegValue & WPDMA_FW_CLR_OWN_INT) ? TRUE : FALSE); +} + +void mt6632LowPowerOwnSet(IN struct ADAPTER *prAdapter, OUT u_int8_t *pfgResult) +{ + uint32_t u4RegValue; + + HAL_MCR_WR(prAdapter, CFG_PCIE_LPCR_HOST, PCIE_LPCR_HOST_SET_OWN); + HAL_MCR_RD(prAdapter, CFG_PCIE_LPCR_HOST, &u4RegValue); + *pfgResult = (u4RegValue == 0); +} + +void mt6632LowPowerOwnClear(IN struct ADAPTER *prAdapter, + OUT u_int8_t *pfgResult) +{ + uint32_t u4RegValue; + + HAL_MCR_WR(prAdapter, CFG_PCIE_LPCR_HOST, PCIE_LPCR_HOST_CLR_OWN); + HAL_MCR_RD(prAdapter, CFG_PCIE_LPCR_HOST, &u4RegValue); + *pfgResult = (u4RegValue == 0); +} + +void mt6632EnableInterrupt(IN struct ADAPTER *prAdapter) +{ + struct BUS_INFO *prBusInfo = prAdapter->chip_info->bus_info; + union WPDMA_INT_MASK IntMask; + + HAL_MCR_RD(prAdapter, WPDMA_INT_MSK, &IntMask.word); + + IntMask.field.rx_done_0 = 1; + IntMask.field.rx_done_1 = 1; + IntMask.field.tx_done = BIT(prBusInfo->tx_ring_fwdl_idx) | + BIT(prBusInfo->tx_ring_cmd_idx) | + BIT(prBusInfo->tx_ring0_data_idx)| + BIT(prBusInfo->tx_ring1_data_idx); + IntMask.field.tx_coherent = 0; + IntMask.field.rx_coherent = 0; + IntMask.field.tx_dly_int = 0; + IntMask.field.rx_dly_int = 0; + IntMask.field.fw_clr_own = 1; + + HAL_MCR_WR(prAdapter, WPDMA_INT_MSK, IntMask.word); + + DBGLOG(HAL, TRACE, "%s [0x%08x]\n", __func__, IntMask.word); +} + +void mt6632DisableInterrupt(IN struct ADAPTER *prAdapter) +{ + union WPDMA_INT_MASK IntMask; + + ASSERT(prAdapter); + + IntMask.word = 0; + + HAL_MCR_WR(prAdapter, WPDMA_INT_MSK, IntMask.word); + HAL_MCR_RD(prAdapter, WPDMA_INT_MSK, &IntMask.word); + + DBGLOG(HAL, TRACE, "%s\n", __func__); +} + +void mt6632WakeUpWiFi(IN struct ADAPTER *prAdapter) +{ + u_int8_t fgResult; + + ASSERT(prAdapter); + + HAL_LP_OWN_RD(prAdapter, &fgResult); + + if (fgResult) + prAdapter->fgIsFwOwn = FALSE; + else + HAL_LP_OWN_CLR(prAdapter, &fgResult); +} +#endif /* _HIF_PCIE */ + +struct BUS_INFO mt6632_bus_info = { +#if defined(_HIF_PCIE) + .top_cfg_base = MT6632_TOP_CFG_BASE, + .host_tx_ring_base = MT_TX_RING_BASE, + .host_tx_ring_ext_ctrl_base = MT_TX_RING_BASE_EXT, + .host_tx_ring_cidx_addr = MT_TX_RING_CIDX, + .host_tx_ring_didx_addr = MT_TX_RING_DIDX, + .host_tx_ring_cnt_addr = MT_TX_RING_CNT, + + .host_rx_ring_base = MT_RX_RING_BASE, + .host_rx_ring_ext_ctrl_base = MT_RX_RING_BASE_EXT, + .host_rx_ring_cidx_addr = MT_RX_RING_CIDX, + .host_rx_ring_didx_addr = MT_RX_RING_DIDX, + .host_rx_ring_cnt_addr = MT_RX_RING_CNT, + .bus2chip = mt6632_bus2chip_cr_mapping, + .tx_ring_fwdl_idx = 3, + .tx_ring_cmd_idx = 2, + .tx_ring0_data_idx = 0, + .tx_ring1_data_idx = 0, /* no used */ + .fw_own_clear_addr = WPDMA_INT_STA, + .fw_own_clear_bit = WPDMA_FW_CLR_OWN_INT, + .max_static_map_addr = 0x00040000, + .fgCheckDriverOwnInt = TRUE, + .u4DmaMask = 32, + + .pdmaSetup = mt6632PdmaConfig, + .updateTxRingMaxQuota = NULL, + .enableInterrupt = mt6632EnableInterrupt, + .disableInterrupt = mt6632DisableInterrupt, + .lowPowerOwnRead = mt6632LowPowerOwnRead, + .lowPowerOwnSet = mt6632LowPowerOwnSet, + .lowPowerOwnClear = mt6632LowPowerOwnClear, + .wakeUpWiFi = mt6632WakeUpWiFi, + .isValidRegAccess = NULL, + .getMailboxStatus = NULL, + .setDummyReg = NULL, + .checkDummyReg = NULL, + .tx_ring_ext_ctrl = asicPdmaTxRingExtCtrl, + .rx_ring_ext_ctrl = asicPdmaRxRingExtCtrl, + .hifRst = NULL, + .initPcieInt = NULL, + .DmaShdlInit = NULL, +#endif /* _HIF_PCIE */ +#if defined(_HIF_USB) + .u4UdmaWlCfg_0_Addr = UDMA_WLCFG_0, + .u4UdmaWlCfg_1_Addr = UDMA_WLCFG_1, + .u4UdmaWlCfg_0 = + (UDMA_WLCFG_0_TX_EN(1) | UDMA_WLCFG_0_RX_EN(1) | + UDMA_WLCFG_0_RX_MPSZ_PAD0(1)), + .u4device_vender_request_in = DEVICE_VENDOR_REQUEST_IN, + .u4device_vender_request_out = DEVICE_VENDOR_REQUEST_OUT, + .asicUsbSuspend = NULL, + .asicUsbResume = NULL, + .asicUsbEventEpDetected = NULL, + .asicUsbRxByteCount = NULL, + .DmaShdlInit = NULL, +#endif /* _HIF_USB */ +#if defined(_HIF_SDIO) + .halTxGetFreeResource = NULL, + .halTxReturnFreeResource = NULL, + .halRestoreTxResource = NULL, + .halUpdateTxDonePendingCount = NULL, +#endif /* _HIF_SDIO */ +}; + +struct FWDL_OPS_T mt6632_fw_dl_ops = { + .constructFirmwarePrio = NULL, + .downloadPatch = NULL, + .downloadFirmware = wlanHarvardFormatDownload, + .downloadByDynMemMap = NULL, + .getFwInfo = wlanGetHarvardFwInfo, + .getFwDlInfo = mt6632GetFwDlInfo, + .phyAction = NULL, +}; + +struct TX_DESC_OPS_T mt6632TxDescOps = { + .fillNicAppend = fillNicTxDescAppendWithCR4, + .fillHifAppend = fillTxDescAppendByCR4, + .fillTxByteCount = fillTxDescTxByteCountWithCR4, +}; + +struct RX_DESC_OPS_T mt6632RxDescOps = { +}; + +#if CFG_SUPPORT_QA_TOOL +struct ATE_OPS_T mt6632AteOps = { + .setICapStart = mt6632SetICapStart, + .getICapStatus = mt6632GetICapStatus, + .getICapIQData = commonGetICapIQData, + .getRbistDataDumpEvent = nicExtEventQueryMemDump, +}; +#endif + +struct CHIP_DBG_OPS mt6632_debug_ops = { + .showPdmaInfo = NULL, + .showPseInfo = NULL, + .showPleInfo = NULL, + .showTxdInfo = NULL, + .showCsrInfo = NULL, + .showDmaschInfo = NULL, + .dumpMacInfo = NULL, + .showWtblInfo = NULL, + .showHifInfo = NULL, + .printHifDbgInfo = NULL, +}; + +/* Litien code refine to support multi chip */ +struct mt66xx_chip_info mt66xx_chip_info_mt6632 = { + .bus_info = &mt6632_bus_info, + .fw_dl_ops = &mt6632_fw_dl_ops, + .prTxDescOps = &mt6632TxDescOps, + .prRxDescOps = &mt6632RxDescOps, +#if CFG_SUPPORT_QA_TOOL + .prAteOps = &mt6632AteOps, +#endif + .prDebugOps = &mt6632_debug_ops, + + .chip_id = MT6632_CHIP_ID, + .should_verify_chip_id = TRUE, + .sw_sync0 = MT6632_SW_SYNC0, + .sw_ready_bits = WIFI_FUNC_READY_BITS, + .sw_ready_bit_offset = MT6632_SW_SYNC0_RDY_OFFSET, + .patch_addr = MT6632_PATCH_START_ADDR, + .is_support_cr4 = TRUE, + .txd_append_size = MT6632_TX_DESC_APPEND_LENGTH, + .rxd_size = MT6632_RX_DESC_LENGTH, + .init_evt_rxd_size = MT6632_RX_DESC_LENGTH, + .pse_header_length = NIC_TX_PSE_HEADER_LENGTH, + .init_event_size = MT6632_RX_INIT_EVENT_LENGTH, + .event_hdr_size = MT6632_RX_EVENT_HDR_LENGTH, + .eco_info = mt6632_eco_table, + .isNicCapV1 = TRUE, + .is_support_efuse = TRUE, + + .asicCapInit = mt6632CapInit, + .asicEnableFWDownload = NULL, + .asicGetChipID = NULL, + .downloadBufferBin = wlanDownloadBufferBin, + .features = 0, + .is_support_hw_amsdu = FALSE, + .ucMaxSwAmsduNum = 0, + .ucMaxSwapAntenna = 0, + .workAround = 0, + + .top_hcr = TOP_HCR, + .top_hvr = TOP_HVR, + .top_fvr = TOP_FVR, +}; + +struct mt66xx_hif_driver_data mt66xx_driver_data_mt6632 = { + .chip_info = &mt66xx_chip_info_mt6632, +}; diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/mt7663/mt7663.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/mt7663/mt7663.c new file mode 100644 index 0000000000000000000000000000000000000000..d5da69ecb4b4b655da2adef7cf37af93c7c9d503 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/mt7663/mt7663.c @@ -0,0 +1,321 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/*! \file mt7663.c + * \brief Internal driver stack will export the required procedures here + * for GLUE Layer. + * + * This file contains all routines which are exported from MediaTek 802.11 + * Wireless LAN driver stack to GLUE Layer. + */ + +#ifdef MT7663 + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" + +#include "mt7663.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#if defined(_HIF_PCIE) +static void mt7663InitPcieInt(struct GLUE_INFO *prGlueInfo) +{ + HAL_MCR_WR(prGlueInfo->prAdapter, MT_PCIE_IRQ_ENABLE, 1); +} +#endif /* _HIF_PCIE */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ +struct ECO_INFO mt7663_eco_table[] = { + /* HW version, ROM version, Factory version */ + {0x00, 0x00, 0x0A, 0x01}, /* E1 */ + {0x10, 0x01, 0x0A, 0x02}, /* E2 */ + {0x00, 0x00, 0x00, 0x00} /* End of table */ +}; + +#if defined(_HIF_PCIE) +struct PCIE_CHIP_CR_MAPPING mt7663_bus2chip_cr_mapping[] = { + /* chip addr, bus addr, range */ + {0x80000000, 0x00002000, 0x00001000}, /* MCU_CFG */ + + {0x50000000, 0x00004000, 0x00004000}, /* CONN_HIF (PDMA) */ + {0x50002000, 0x00005000, 0x00001000}, /* CONN_HIF (Reserved) */ + {0x5000A000, 0x00006000, 0x00001000}, /* CONN_HIF (DMASHDL) */ + {0x000E0000, 0x00007000, 0x00001000}, /* CONN_HIF_ON (HOST_CSR) */ + + {0x82060000, 0x00008000, 0x00004000}, /* WF_UMAC_TOP (PLE) */ + {0x82068000, 0x0000C000, 0x00002000}, /* WF_UMAC_TOP (PSE) */ + {0x8206C000, 0x0000E000, 0x00002000}, /* WF_UMAC_TOP (PP) */ + {0x82070000, 0x00010000, 0x00010000}, /* WF_PHY */ + {0x820F0000, 0x00020000, 0x00010000}, /* WF_LMAC_TOP */ + {0x820E0000, 0x00030000, 0x00010000}, /* WF_LMAC_TOP (WF_WTBL) */ + + {0x81000000, 0x00050000, 0x00010000}, /* BTSYS_OFF */ + {0x80070000, 0x00060000, 0x00010000}, /* GPSSYS */ + {0x40000000, 0x00070000, 0x00010000}, /* WF_SYSRAM */ + {0x00300000, 0x00080000, 0x00010000}, /* MCU_SYSRAM */ + + {0x80010000, 0x000A1000, 0x00001000}, /* CONN_MCU_DMA */ + {0x80030000, 0x000A2000, 0x00001000}, /* CONN_MCU_BTIF0 */ + {0x81030000, 0x000A3000, 0x00001000}, /* CONN_MCU_CFG_ON */ + {0x80050000, 0x000A4000, 0x00001000}, /* CONN_UART_PTA */ + {0x81040000, 0x000A5000, 0x00001000}, /* CONN_MCU_CIRQ */ + {0x81050000, 0x000A6000, 0x00001000}, /* CONN_MCU_GPT */ + {0x81060000, 0x000A7000, 0x00001000}, /* CONN_PTA */ + {0x81080000, 0x000A8000, 0x00001000}, /* CONN_MCU_WDT */ + {0x81090000, 0x000A9000, 0x00001000}, /* CONN_MCU_PDA */ + {0x810A0000, 0x000AA000, 0x00001000}, /* CONN_RDD_AHB_WRAP0 */ + {0x810B0000, 0x000AB000, 0x00001000}, /* BTSYS_ON */ + {0x810C0000, 0x000AC000, 0x00001000}, /* CONN_RBIST_TOP */ + {0x810D0000, 0x000AD000, 0x00001000}, /* CONN_RDD_AHB_WRAP0 */ + {0x820D0000, 0x000AE000, 0x00001000}, /* WFSYS_ON */ + {0x60000000, 0x000AF000, 0x00001000}, /* CONN_MCU_PDA */ + + {0x80020000, 0x000B0000, 0x00010000}, /* CONN_TOP_MISC_OFF */ + {0x81020000, 0x000C0000, 0x00010000}, /* CONN_TOP_MISC_ON */ + {0x7c030000, 0x000F0000, 0x00010000}, /* CONN_TOP_MISC_ON */ + + {0x0, 0x0, 0x0} +}; +#endif /* _HIF_PCIE */ + +struct BUS_INFO mt7663_bus_info = { +#if defined(_HIF_PCIE) + .top_cfg_base = MT7663_TOP_CFG_BASE, + .host_tx_ring_base = MT_TX_RING_BASE, + .host_tx_ring_ext_ctrl_base = MT_TX_RING_BASE_EXT, + .host_tx_ring_cidx_addr = MT_TX_RING_CIDX, + .host_tx_ring_didx_addr = MT_TX_RING_DIDX, + .host_tx_ring_cnt_addr = MT_TX_RING_CNT, + + .host_rx_ring_base = MT_RX_RING_BASE, + .host_rx_ring_ext_ctrl_base = MT_RX_RING_BASE_EXT, + .host_rx_ring_cidx_addr = MT_RX_RING_CIDX, + .host_rx_ring_didx_addr = MT_RX_RING_DIDX, + .host_rx_ring_cnt_addr = MT_RX_RING_CNT, + .bus2chip = mt7663_bus2chip_cr_mapping, + .tx_ring_fwdl_idx = 3, + .tx_ring_cmd_idx = 15, + .tx_ring0_data_idx = 0, + .tx_ring1_data_idx = 0, + .fw_own_clear_addr = WPDMA_INT_STA, + .fw_own_clear_bit = WPDMA_FW_CLR_OWN_INT, + .max_static_map_addr = 0x00040000, + .fgCheckDriverOwnInt = FALSE, + .u4DmaMask = 36, + + .pdmaSetup = asicPdmaConfig, + .updateTxRingMaxQuota = NULL, + .enableInterrupt = asicEnableInterrupt, + .disableInterrupt = asicDisableInterrupt, + .lowPowerOwnRead = asicLowPowerOwnRead, + .lowPowerOwnSet = asicLowPowerOwnSet, + .lowPowerOwnClear = asicLowPowerOwnClearPCIe, + .wakeUpWiFi = asicWakeUpWiFi, + .isValidRegAccess = NULL, + .getMailboxStatus = asicGetMailboxStatus, + .setDummyReg = asicSetDummyReg, + .checkDummyReg = asicCheckDummyReg, + .tx_ring_ext_ctrl = asicPdmaTxRingExtCtrl, + .rx_ring_ext_ctrl = asicPdmaRxRingExtCtrl, + .hifRst = NULL, + .initPcieInt = mt7663InitPcieInt, + .DmaShdlInit = asicPcieDmaShdlInit, +#endif /* _HIF_PCIE */ +#if defined(_HIF_USB) + .u4UdmaWlCfg_0_Addr = CONNAC_UDMA_WLCFG_0, + .u4UdmaWlCfg_1_Addr = CONNAC_UDMA_WLCFG_1, + .u4UdmaWlCfg_0 = + (UDMA_WLCFG_0_TX_EN(1) | + UDMA_WLCFG_0_RX_EN(1) | + UDMA_WLCFG_0_RX_MPSZ_PAD0(1) | + UDMA_WLCFG_0_1US_TIMER_EN(1)), + .u4UdmaTxTimeout = UDMA_TX_TIMEOUT_LIMIT, + .u4device_vender_request_in = DEVICE_VENDOR_REQUEST_IN, + .u4device_vender_request_out = DEVICE_VENDOR_REQUEST_OUT, + .asicUsbSuspend = asicUsbSuspend, + .asicUsbResume = NULL, + .asicUsbEventEpDetected = asicUsbEventEpDetected, + .asicUsbRxByteCount = NULL, + .DmaShdlInit = asicUsbDmaShdlInit, +#endif /* _HIF_USB */ +#if defined(_HIF_SDIO) + .halTxGetFreeResource = halTxGetFreeResource_v1, + .halTxReturnFreeResource = halTxReturnFreeResource_v1, + .halRestoreTxResource = halRestoreTxResource_v1, + .halUpdateTxDonePendingCount = halUpdateTxDonePendingCount_v1, +#endif /* _HIF_SDIO */ +}; + +struct FWDL_OPS_T mt7663_fw_dl_ops = { + .constructFirmwarePrio = NULL, + .downloadPatch = wlanDownloadPatch, + .downloadFirmware = wlanConnacFormatDownload, + .downloadByDynMemMap = NULL, + .getFwInfo = wlanGetConnacFwInfo, + .getFwDlInfo = asicGetFwDlInfo, + .phyAction = NULL, +}; + +struct TX_DESC_OPS_T mt7663TxDescOps = { + .fillNicAppend = fillNicTxDescAppend, + .fillHifAppend = fillTxDescAppendByHostV2, + .fillTxByteCount = fillTxDescTxByteCount, +}; + +struct RX_DESC_OPS_T mt7663RxDescOps = { +}; + +#if CFG_SUPPORT_QA_TOOL +struct ATE_OPS_T mt7663AteOps = { + .setICapStart = connacSetICapStart, + .getICapStatus = connacGetICapStatus, + .getICapIQData = connacGetICapIQData, + .getRbistDataDumpEvent = nicExtEventICapIQData, +}; +#endif + +struct CHIP_DBG_OPS mt7663_debug_ops = { +#if defined(_HIF_PCIE) || defined(_HIF_AXI) + .showPdmaInfo = halShowPdmaInfo, + .showCsrInfo = halShowHostCsrInfo, +#else + .showPdmaInfo = NULL, + .showCsrInfo = NULL, +#endif + .showPseInfo = halShowPseInfo, + .showPleInfo = halShowPleInfo, + .showTxdInfo = halShowTxdInfo, + .showDmaschInfo = halShowDmaschInfo, + .dumpMacInfo = haldumpMacInfo, + .showWtblInfo = NULL, + .showHifInfo = NULL, + .printHifDbgInfo = halPrintHifDbgInfo, +}; + +/* Litien code refine to support multi chip */ +struct mt66xx_chip_info mt66xx_chip_info_mt7663 = { + .bus_info = &mt7663_bus_info, + .fw_dl_ops = &mt7663_fw_dl_ops, + .prTxDescOps = &mt7663TxDescOps, + .prRxDescOps = &mt7663RxDescOps, +#if CFG_SUPPORT_QA_TOOL + .prAteOps = &mt7663AteOps, +#endif + .prDebugOps = &mt7663_debug_ops, + + .chip_id = MT7663_CHIP_ID, + .should_verify_chip_id = FALSE, + .sw_sync0 = MT7663_SW_SYNC0, + .sw_ready_bits = WIFI_FUNC_NO_CR4_READY_BITS, + .sw_ready_bit_offset = MT7663_SW_SYNC0_RDY_OFFSET, + .patch_addr = MT7663_PATCH_START_ADDR, + .is_support_cr4 = FALSE, + .txd_append_size = MT7663_TX_DESC_APPEND_LENGTH, + .rxd_size = MT7663_RX_DESC_LENGTH, + .init_evt_rxd_size = MT7663_RX_DESC_LENGTH, + .pse_header_length = NIC_TX_PSE_HEADER_LENGTH, + .init_event_size = MT7663_RX_INIT_EVENT_LENGTH, + .event_hdr_size = MT7663_RX_EVENT_HDR_LENGTH, + .eco_info = mt7663_eco_table, + .isNicCapV1 = FALSE, + .is_support_efuse = TRUE, + + .asicCapInit = asicCapInit, + .asicEnableFWDownload = asicEnableFWDownload, + .asicGetChipID = NULL, + .downloadBufferBin = wlanConnacDownloadBufferBin, + .is_support_hw_amsdu = TRUE, + .ucMaxSwAmsduNum = 0, + .workAround = 0, + .prTxPwrLimitFile = "TxPwrLimit_MT76x3.dat", + .ucTxPwrLimitBatchSize = 16, + + .top_hcr = TOP_HCR, + .top_hvr = TOP_HVR, + .top_fvr = TOP_FVR, + .ucMaxSwapAntenna = 0, +}; + +struct mt66xx_hif_driver_data mt66xx_driver_data_mt7663 = { + .chip_info = &mt66xx_chip_info_mt7663, +}; + +#endif /* MT7663 */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/mt7668/mt7668.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/mt7668/mt7668.c new file mode 100644 index 0000000000000000000000000000000000000000..c865d6703ab3736f4d0f4d6230ac7e20eed44baa --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/mt7668/mt7668.c @@ -0,0 +1,571 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/*! \file mt7668.c + * \brief Internal driver stack will export the required procedures here + * for GLUE Layer. + * + * This file contains all routines which are exported from MediaTek 802.11 + * Wireless LAN driver stack to GLUE Layer. + */ + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" + +#include "mt7668.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +struct ECO_INFO mt7668_eco_table[] = { + /* HW version, ROM version, Factory version, Eco version */ + {0x00, 0x00, 0xA, 0x1}, /* E1 */ + {0x10, 0x01, 0xB, 0x2}, /* E2 */ + {0x11, 0x01, 0xB, 0x2}, /* E2 */ + {0x00, 0x00, 0x0, 0x0} /* End of table */ +}; + +#if defined(_HIF_PCIE) +struct PCIE_CHIP_CR_MAPPING mt7668_bus2chip_cr_mapping[] = { + /* chip addr, bus addr, range */ + {0x82060000, 0x00008000, 0x00000450}, /* WF_PLE */ + {0x82068000, 0x0000c000, 0x00000450}, /* WF_PSE */ + {0x8206c000, 0x0000e000, 0x00000300}, /* PP */ + {0x820d0000, 0x00020000, 0x00000200}, /* WF_AON */ + {0x820f0000, 0x00020200, 0x00000400}, /* WF_CFG */ + {0x820f0800, 0x00020600, 0x00000200}, /* WF_CFGOFF */ + {0x820f1000, 0x00020800, 0x00000200}, /* WF_TRB */ + {0x820f2000, 0x00020a00, 0x00000200}, /* WF_AGG */ + {0x820f3000, 0x00020c00, 0x00000400}, /* WF_ARB */ + {0x820f4000, 0x00021000, 0x00000200}, /* WF_TMAC */ + {0x820f5000, 0x00021200, 0x00000400}, /* WF_RMAC */ + {0x820f6000, 0x00021600, 0x00000200}, /* WF_SEC */ + {0x820f7000, 0x00021800, 0x00000200}, /* WF_DMA */ + + {0x820f8000, 0x00022000, 0x00001000}, /* WF_PF */ + {0x820f9000, 0x00023000, 0x00000400}, /* WF_WTBLON */ + {0x820f9800, 0x00023400, 0x00000200}, /* WF_WTBLOFF */ + + {0x820fa000, 0x00024000, 0x00000200}, /* WF_ETBF */ + {0x820fb000, 0x00024200, 0x00000400}, /* WF_LPON */ + {0x820fc000, 0x00024600, 0x00000200}, /* WF_INT */ + {0x820fd000, 0x00024800, 0x00000400}, /* WF_MIB */ + + {0x820fe000, 0x00025000, 0x00002000}, /* WF_MU */ + + {0x820e0000, 0x00030000, 0x00010000}, /* WF_WTBL */ + + {0x80020000, 0x00000000, 0x00002000}, /* TOP_CFG */ + {0x80000000, 0x00002000, 0x00002000}, /* MCU_CFG */ + {0x50000000, 0x00004000, 0x00004000}, /* PDMA_CFG */ + {0xA0000000, 0x00008000, 0x00008000}, /* PSE_CFG */ + {0x82070000, 0x00010000, 0x00010000}, /* WF_PHY */ + + {0x0, 0x0, 0x0} +}; +#endif /* _HIF_PCIE */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +void +mt7668ConstructFirmwarePrio(struct GLUE_INFO *prGlueInfo, + uint8_t **apucNameTable, uint8_t **apucName, + uint8_t *pucNameIdx, uint8_t ucMaxNameIdx) +{ + struct mt66xx_chip_info *prChipInfo = prGlueInfo->prAdapter->chip_info; + uint32_t chip_id = prChipInfo->chip_id; + uint8_t sub_idx = 0; + + for (sub_idx = 0; apucNameTable[sub_idx]; sub_idx++) { + if (((*pucNameIdx) + 3) < ucMaxNameIdx) { + /* Type 1. WIFI_RAM_CODE_MTxxxx.bin */ + snprintf(*(apucName + (*pucNameIdx)), + CFG_FW_NAME_MAX_LEN, "%s%x.bin", + apucNameTable[sub_idx], chip_id); + (*pucNameIdx) += 1; + + /* Type 2. WIFI_RAM_CODE_MTxxxx */ + snprintf(*(apucName + (*pucNameIdx)), + CFG_FW_NAME_MAX_LEN, "%s%x", + apucNameTable[sub_idx], chip_id); + (*pucNameIdx) += 1; + + /* Type 3. WIFI_RAM_CODE_MTxxxx_Ex.bin */ + snprintf(*(apucName + (*pucNameIdx)), + CFG_FW_NAME_MAX_LEN, "%s%x_E%u.bin", + apucNameTable[sub_idx], chip_id, + wlanGetEcoVersion( + prGlueInfo->prAdapter)); + (*pucNameIdx) += 1; + + /* Type 4. WIFI_RAM_CODE_MTxxxx_Ex */ + snprintf(*(apucName + (*pucNameIdx)), + CFG_FW_NAME_MAX_LEN, "%s%x_E%u", + apucNameTable[sub_idx], chip_id, + wlanGetEcoVersion( + prGlueInfo->prAdapter)); + (*pucNameIdx) += 1; + } else { + /* the table is not large enough */ + DBGLOG(INIT, ERROR, + "kalFirmwareImageMapping >> file name array is not enough.\n"); + ASSERT(0); + } + } +} + +void mt7668CapInit(IN struct ADAPTER *prAdapter) +{ + struct GLUE_INFO *prGlueInfo; + struct mt66xx_chip_info *prChipInfo; + + ASSERT(prAdapter); + + prGlueInfo = prAdapter->prGlueInfo; + prChipInfo = prAdapter->chip_info; + + prChipInfo->u2HifTxdSize = 0; + prChipInfo->u2TxInitCmdPort = 0; + prChipInfo->u2TxFwDlPort = 0; + prChipInfo->fillHifTxDesc = NULL; + prChipInfo->ucPacketFormat = TXD_PKT_FORMAT_TXD; + prChipInfo->u4ExtraTxByteCount = 0; + prChipInfo->asicFillInitCmdTxd = asicFillInitCmdTxd; + prChipInfo->asicFillCmdTxd = asicFillCmdTxd; + prChipInfo->u2CmdTxHdrSize = sizeof(struct WIFI_CMD); + prChipInfo->u2RxSwPktBitMap = RXM_RXD_PKT_TYPE_SW_BITMAP; + prChipInfo->u2RxSwPktEvent = RXM_RXD_PKT_TYPE_SW_EVENT; + prChipInfo->u2RxSwPktFrame = RXM_RXD_PKT_TYPE_SW_FRAME; + asicInitTxdHook(prChipInfo->prTxDescOps); + asicInitRxdHook(prChipInfo->prRxDescOps); +#if CFG_SUPPORT_WIFI_SYSDVT + prAdapter->u2TxTest = TX_TEST_UNLIMITIED; + prAdapter->u2TxTestCount = 0; + prAdapter->ucTxTestUP = TX_TEST_UP_UNDEF; +#endif /* CFG_SUPPORT_WIFI_SYSDVT */ + + switch (prGlueInfo->u4InfType) { +#if defined(_HIF_PCIE) + case MT_DEV_INF_PCIE: + prChipInfo->u2TxInitCmdPort = TX_RING_FWDL_IDX_3; + prChipInfo->u2TxFwDlPort = TX_RING_FWDL_IDX_3; + break; +#endif /* _HIF_PCIE */ +#if defined(_HIF_USB) + case MT_DEV_INF_USB: + prChipInfo->u2TxInitCmdPort = USB_DATA_BULK_OUT_EP8; + prChipInfo->u2TxFwDlPort = USB_DATA_BULK_OUT_EP8; + break; +#endif /* _HIF_USB */ + default: + break; + } +} + +uint32_t mt7668GetFwDlInfo(struct ADAPTER *prAdapter, + char *pcBuf, int i4TotalLen) +{ + struct WIFI_VER_INFO *prVerInfo = &prAdapter->rVerInfo; +#if CFG_SUPPORT_COMPRESSION_FW_OPTION + struct TAILER_FORMAT_T_2 *prTailer; +#else + struct TAILER_FORMAT_T *prTailer; +#endif + uint32_t u4Offset = 0; + uint8_t aucBuf[32]; + +#if CFG_SUPPORT_COMPRESSION_FW_OPTION + prTailer = &prVerInfo->rN9Compressedtailer; +#else + prTailer = &prVerInfo->rN9tailer[0]; +#endif + kalMemZero(aucBuf, 32); + kalMemCopy(aucBuf, prTailer->ram_version, 10); + u4Offset += snprintf(pcBuf + u4Offset, i4TotalLen - u4Offset, + "N9 tailer version %s (%s) info %u:E%u\n", + aucBuf, prTailer->ram_built_date, prTailer->chip_info, + prTailer->eco_code + 1); + +#if CFG_SUPPORT_COMPRESSION_FW_OPTION + prTailer = &prVerInfo->rCR4Compressedtailer; +#else + prTailer = &prVerInfo->rCR4tailer[0]; +#endif + kalMemZero(aucBuf, 32); + kalMemCopy(aucBuf, prTailer->ram_version, 10); + u4Offset += snprintf(pcBuf + u4Offset, i4TotalLen - u4Offset, + "CR4 tailer version %s (%s) info %u:E%u\n", + aucBuf, prTailer->ram_built_date, prTailer->chip_info, + prTailer->eco_code + 1); + + return u4Offset; +} + +#if defined(_HIF_PCIE) + +void mt7668PdmaConfig(struct GLUE_INFO *prGlueInfo, u_int8_t enable, + bool fgResetHif) +{ + struct BUS_INFO *prBusInfo = prGlueInfo->prAdapter->chip_info->bus_info; + union WPDMA_GLO_CFG_STRUCT GloCfg; + union WPDMA_INT_MASK IntMask; + + kalDevRegRead(prGlueInfo, WPDMA_GLO_CFG, &GloCfg.word); + + kalDevRegRead(prGlueInfo, WPDMA_INT_MSK, &IntMask.word); + + if (enable == TRUE) { + /*0x4208 = 5440_1E70*/ + GloCfg.field_1.EnableTxDMA = 1; + GloCfg.field_1.EnableRxDMA = 1; + + GloCfg.field_1.WPDMABurstSIZE = 3; + GloCfg.field_1.EnTXWriteBackDDONE = 1; + + GloCfg.field_1.tx_bt_size = 1; + GloCfg.field_1.multi_dma_en = 3; + GloCfg.field_1.fifo_little_endian = 1; + + GloCfg.field_1.tx_bt_size_bit21 = 1; + GloCfg.field_1.first_token = 1; + GloCfg.field_1.omit_tx_info = 1; + GloCfg.field_1.reserve_30 = 1; + + IntMask.field.rx_done_0 = 1; + IntMask.field.rx_done_1 = 1; + IntMask.field.tx_done = BIT(prBusInfo->tx_ring_fwdl_idx) | + BIT(prBusInfo->tx_ring_cmd_idx) | + BIT(prBusInfo->tx_ring0_data_idx)| + BIT(prBusInfo->tx_ring1_data_idx); + IntMask.field.tx_dly_int = 0; + } else { + GloCfg.field_1.EnableRxDMA = 0; + GloCfg.field_1.EnableTxDMA = 0; + + IntMask.field.rx_done_0 = 0; + IntMask.field.rx_done_1 = 0; + IntMask.field.tx_done = 0; + IntMask.field.tx_dly_int = 0; + } + + kalDevRegWrite(prGlueInfo, WPDMA_INT_MSK, IntMask.word); + kalDevRegWrite(prGlueInfo, WPDMA_GLO_CFG, GloCfg.word); + + + /* new PDMA */ + /* 0x4260 = 0000_0005 */ + kalDevRegWrite(prGlueInfo, WPDMA_PAUSE_RX_Q_TH10, 0x5); + + /* 0x4500 = 0000_0001*/ + kalDevRegWrite(prGlueInfo, MT_WPDMA_GLO_CFG_1, 0x1); + + /* 0x4510 = 000F_0000*/ + kalDevRegWrite(prGlueInfo, MT_WPDMA_TX_PRE_CFG, 0xF0000); + + /* 0x4520 = 0F7F_0000 */ + kalDevRegWrite(prGlueInfo, MT_WPDMA_RX_PRE_CFG, 0xF7F0000); + + /* 0x4530 = 0EA6_0026 */ + kalDevRegWrite(prGlueInfo, MT_WPDMA_ABT_CFG, 0x0EA60026); + + /* 0x4534 = E4E4_E4E4*/ + kalDevRegWrite(prGlueInfo, MT_WPDMA_ABT_CFG1, 0xE4E4E4E4); + +} + +void mt7668LowPowerOwnRead(IN struct ADAPTER *prAdapter, + OUT u_int8_t *pfgResult) +{ + uint32_t u4RegValue; + + HAL_MCR_RD(prAdapter, WPDMA_INT_STA, &u4RegValue); + *pfgResult = ((u4RegValue & WPDMA_FW_CLR_OWN_INT) ? TRUE : FALSE); +} + +void mt7668LowPowerOwnSet(IN struct ADAPTER *prAdapter, OUT u_int8_t *pfgResult) +{ + uint32_t u4RegValue; + + HAL_MCR_WR(prAdapter, CFG_PCIE_LPCR_HOST, PCIE_LPCR_HOST_SET_OWN); + HAL_MCR_RD(prAdapter, CFG_PCIE_LPCR_HOST, &u4RegValue); + *pfgResult = (u4RegValue == 0); +} + +void mt7668LowPowerOwnClear(IN struct ADAPTER *prAdapter, + OUT u_int8_t *pfgResult) +{ + uint32_t u4RegValue; + + HAL_MCR_WR(prAdapter, CFG_PCIE_LPCR_HOST, PCIE_LPCR_HOST_CLR_OWN); + HAL_MCR_RD(prAdapter, CFG_PCIE_LPCR_HOST, &u4RegValue); + *pfgResult = (u4RegValue == 0); +} +void mt7668EnableInterrupt(IN struct ADAPTER *prAdapter) +{ + struct BUS_INFO *prBusInfo = prAdapter->chip_info->bus_info; + union WPDMA_INT_MASK IntMask; + + HAL_MCR_RD(prAdapter, WPDMA_INT_MSK, &IntMask.word); + + IntMask.field.rx_done_0 = 1; + IntMask.field.rx_done_1 = 1; + IntMask.field.tx_done = BIT(prBusInfo->tx_ring_fwdl_idx) | + BIT(prBusInfo->tx_ring_cmd_idx) | + BIT(prBusInfo->tx_ring0_data_idx)| + BIT(prBusInfo->tx_ring1_data_idx); + IntMask.field.tx_coherent = 0; + IntMask.field.rx_coherent = 0; + IntMask.field.tx_dly_int = 0; + IntMask.field.rx_dly_int = 0; + IntMask.field.fw_clr_own = 1; + + HAL_MCR_WR(prAdapter, WPDMA_INT_MSK, IntMask.word); + + DBGLOG(HAL, TRACE, "%s [0x%08x]\n", __func__, IntMask.word); +} + +void mt7668DisableInterrupt(IN struct ADAPTER *prAdapter) +{ + union WPDMA_INT_MASK IntMask; + + ASSERT(prAdapter); + + IntMask.word = 0; + + HAL_MCR_WR(prAdapter, WPDMA_INT_MSK, IntMask.word); + HAL_MCR_RD(prAdapter, WPDMA_INT_MSK, &IntMask.word); + + DBGLOG(HAL, TRACE, "%s\n", __func__); +} + +void mt7668WakeUpWiFi(IN struct ADAPTER *prAdapter) +{ + u_int8_t fgResult; + + ASSERT(prAdapter); + + HAL_LP_OWN_RD(prAdapter, &fgResult); + + if (fgResult) + prAdapter->fgIsFwOwn = FALSE; + else + HAL_LP_OWN_CLR(prAdapter, &fgResult); +} +#endif /* _HIF_PCIE */ + +struct BUS_INFO mt7668_bus_info = { +#if defined(_HIF_PCIE) + .top_cfg_base = MT7668_TOP_CFG_BASE, + .host_tx_ring_base = MT_TX_RING_BASE, + .host_tx_ring_ext_ctrl_base = MT_TX_RING_BASE_EXT, + .host_tx_ring_cidx_addr = MT_TX_RING_CIDX, + .host_tx_ring_didx_addr = MT_TX_RING_DIDX, + .host_tx_ring_cnt_addr = MT_TX_RING_CNT, + + .host_rx_ring_base = MT_RX_RING_BASE, + .host_rx_ring_ext_ctrl_base = MT_RX_RING_BASE_EXT, + .host_rx_ring_cidx_addr = MT_RX_RING_CIDX, + .host_rx_ring_didx_addr = MT_RX_RING_DIDX, + .host_rx_ring_cnt_addr = MT_RX_RING_CNT, + .bus2chip = mt7668_bus2chip_cr_mapping, + .tx_ring_fwdl_idx = 3, + .tx_ring_cmd_idx = 2, + .tx_ring0_data_idx = 0, + .tx_ring1_data_idx = 0, + .fw_own_clear_addr = WPDMA_INT_STA, + .fw_own_clear_bit = WPDMA_FW_CLR_OWN_INT, + .max_static_map_addr = 0x00040000, + .fgCheckDriverOwnInt = FALSE, + .u4DmaMask = 32, + + .pdmaSetup = mt7668PdmaConfig, + .updateTxRingMaxQuota = NULL, + .enableInterrupt = mt7668EnableInterrupt, + .disableInterrupt = mt7668DisableInterrupt, + .lowPowerOwnRead = mt7668LowPowerOwnRead, + .lowPowerOwnSet = mt7668LowPowerOwnSet, + .lowPowerOwnClear = mt7668LowPowerOwnClear, + .wakeUpWiFi = mt7668WakeUpWiFi, + .isValidRegAccess = NULL, + .getMailboxStatus = NULL, + .setDummyReg = NULL, + .checkDummyReg = NULL, + .tx_ring_ext_ctrl = asicPdmaTxRingExtCtrl, + .rx_ring_ext_ctrl = asicPdmaRxRingExtCtrl, + .hifRst = NULL, + .initPcieInt = NULL, + .DmaShdlInit = NULL, +#endif /* _HIF_PCIE */ +#if defined(_HIF_USB) + .u4UdmaWlCfg_0_Addr = UDMA_WLCFG_0, + .u4UdmaWlCfg_1_Addr = UDMA_WLCFG_1, + .u4UdmaWlCfg_0 = + (UDMA_WLCFG_0_TX_EN(1) | UDMA_WLCFG_0_RX_EN(1) | + UDMA_WLCFG_0_RX_MPSZ_PAD0(1)), + .u4device_vender_request_in = DEVICE_VENDOR_REQUEST_IN, + .u4device_vender_request_out = DEVICE_VENDOR_REQUEST_OUT, + .asicUsbSuspend = NULL, + .asicUsbResume = NULL, + .asicUsbEventEpDetected = NULL, + .asicUsbRxByteCount = NULL, + .DmaShdlInit = NULL, +#endif /* _HIF_USB */ +#if defined(_HIF_SDIO) + .halTxGetFreeResource = NULL, + .halTxReturnFreeResource = NULL, + .halRestoreTxResource = NULL, + .halUpdateTxDonePendingCount = NULL, +#endif /* _HIF_SDIO */ +}; + +struct FWDL_OPS_T mt7668_fw_dl_ops = { + .constructFirmwarePrio = mt7668ConstructFirmwarePrio, + .downloadPatch = wlanDownloadPatch, + .downloadFirmware = wlanHarvardFormatDownload, + .downloadByDynMemMap = NULL, + .getFwInfo = wlanGetHarvardFwInfo, + .getFwDlInfo = mt7668GetFwDlInfo, + .phyAction = NULL, +}; + +struct TX_DESC_OPS_T mt7668TxDescOps = { + .fillNicAppend = fillNicTxDescAppendWithCR4, + .fillHifAppend = fillTxDescAppendByCR4, + .fillTxByteCount = fillTxDescTxByteCountWithCR4, +}; + +struct RX_DESC_OPS_T mt7668RxDescOps = { +}; + +#if CFG_SUPPORT_QA_TOOL +struct ATE_OPS_T mt7668AteOps = { + .setICapStart = mt6632SetICapStart, + .getICapStatus = mt6632GetICapStatus, + .getICapIQData = commonGetICapIQData, + .getRbistDataDumpEvent = nicExtEventQueryMemDump, +}; +#endif + +struct CHIP_DBG_OPS mt7668_debug_ops = { + .showPdmaInfo = NULL, + .showPseInfo = NULL, + .showPleInfo = NULL, + .showTxdInfo = NULL, + .showCsrInfo = NULL, + .showDmaschInfo = NULL, + .dumpMacInfo = NULL, + .showWtblInfo = NULL, + .showHifInfo = NULL, + .printHifDbgInfo = NULL, +}; + +/* Litien code refine to support multi chip */ +struct mt66xx_chip_info mt66xx_chip_info_mt7668 = { + .bus_info = &mt7668_bus_info, + .fw_dl_ops = &mt7668_fw_dl_ops, + .prTxDescOps = &mt7668TxDescOps, + .prRxDescOps = &mt7668RxDescOps, +#if CFG_SUPPORT_QA_TOOL + .prAteOps = &mt7668AteOps, +#endif + .prDebugOps = &mt7668_debug_ops, + + .chip_id = MT7668_CHIP_ID, + .should_verify_chip_id = TRUE, + .sw_sync0 = MT7668_SW_SYNC0, + .sw_ready_bits = WIFI_FUNC_READY_BITS, + .sw_ready_bit_offset = MT7668_SW_SYNC0_RDY_OFFSET, + .patch_addr = MT7668_PATCH_START_ADDR, + .is_support_cr4 = TRUE, + .txd_append_size = MT7668_TX_DESC_APPEND_LENGTH, + .rxd_size = MT7668_RX_DESC_LENGTH, + .init_evt_rxd_size = MT7668_RX_DESC_LENGTH, + .pse_header_length = NIC_TX_PSE_HEADER_LENGTH, + .init_event_size = MT7668_RX_INIT_EVENT_LENGTH, + .event_hdr_size = MT7668_RX_EVENT_HDR_LENGTH, + .eco_info = mt7668_eco_table, + .isNicCapV1 = TRUE, + .is_support_efuse = TRUE, + + .asicCapInit = mt7668CapInit, + .asicEnableFWDownload = NULL, + .asicGetChipID = NULL, + .downloadBufferBin = wlanDownloadBufferBin, + .features = 0, + .is_support_hw_amsdu = FALSE, + .ucMaxSwAmsduNum = 0, + .ucMaxSwapAntenna = 0, + .workAround = 0, + .prTxPwrLimitFile = "TxPwrLimit_MT76x8.dat", + .ucTxPwrLimitBatchSize = 32, + + .top_hcr = TOP_HCR, + .top_hvr = TOP_HVR, + .top_fvr = TOP_FVR, +}; + +struct mt66xx_hif_driver_data mt66xx_driver_data_mt7668 = { + .chip_info = &mt66xx_chip_info_mt7668, +}; + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/mt7915/dbg_mt7915.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/mt7915/dbg_mt7915.c new file mode 100644 index 0000000000000000000000000000000000000000..9867b2fd8d7d0406e56b637ff358334fc8deee46 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/mt7915/dbg_mt7915.c @@ -0,0 +1,967 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/****************************************************************************** + *[File] dbg_mt7915.c + *[Version] v1.0 + *[Revision Date] 2019-04-09 + *[Author] + *[Description] + * The program provides WIFI FALCON MAC Debug APIs + *[Copyright] + * Copyright (C) 2015 MediaTek Incorporation. All Rights Reserved. + ******************************************************************************/ + +#ifdef MT7915 +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "coda/mt7915/wf_ple_top.h" +#include "coda/mt7915/wf_pse_top.h" +#include "precomp.h" +#include "mt_dmac.h" +#include "wf_ple.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +static struct EMPTY_QUEUE_INFO ple_queue_empty_info[] = { + {"CPU Q0", MCU_Q0_INDEX, ENUM_UMAC_CTX_Q_0}, + {"CPU Q1", ENUM_UMAC_CPU_PORT_1, ENUM_UMAC_CTX_Q_1}, + {"CPU Q2", ENUM_UMAC_CPU_PORT_1, ENUM_UMAC_CTX_Q_2}, + {"CPU Q3", ENUM_UMAC_CPU_PORT_1, ENUM_UMAC_CTX_Q_3}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, /* 4~7 not defined */ + {"ALTX Q0", ENUM_UMAC_LMAC_PORT_2, + ENUM_UMAC_LMAC_PLE_TX_Q_ALTX_0}, /* Q16 */ + {"BMC Q0", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_BMC_0}, + {"BCN Q0", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_BNC_0}, + {"PSMP Q0", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_PSMP_0}, + {"ALTX Q1", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_ALTX_1}, + {"BMC Q1", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_BMC_1}, + {"BCN Q1", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_BNC_1}, + {"PSMP Q1", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_PSMP_1}, + {"NAF Q", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_NAF}, + {"NBCN Q", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_NBCN}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, /* 18~29 not defined */ + {"RLS Q", ENUM_PLE_CTRL_PSE_PORT_3, ENUM_UMAC_PLE_CTRL_P3_Q_0X1E}, + {"RLS2 Q", ENUM_PLE_CTRL_PSE_PORT_3, ENUM_UMAC_PLE_CTRL_P3_Q_0X1F} }; + +static struct EMPTY_QUEUE_INFO pse_queue_empty_info[] = { + {"CPU Q0", ENUM_UMAC_CPU_PORT_1, ENUM_UMAC_CTX_Q_0}, + {"CPU Q1", ENUM_UMAC_CPU_PORT_1, ENUM_UMAC_CTX_Q_1}, + {"CPU Q2", ENUM_UMAC_CPU_PORT_1, ENUM_UMAC_CTX_Q_2}, + {"CPU Q3", ENUM_UMAC_CPU_PORT_1, ENUM_UMAC_CTX_Q_3}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, /* 4~7 not defined */ + {"HIF Q0", ENUM_UMAC_HIF_PORT_0, 0}, /* Q8 */ + {"HIF Q1", ENUM_UMAC_HIF_PORT_0, 1}, + {"HIF Q2", ENUM_UMAC_HIF_PORT_0, 2}, + {"HIF Q3", ENUM_UMAC_HIF_PORT_0, 3}, + {"HIF Q4", ENUM_UMAC_HIF_PORT_0, 4}, + {"HIF Q5", ENUM_UMAC_HIF_PORT_0, 5}, + {NULL, 0, 0}, + {NULL, 0, 0}, /* 14~15 not defined */ + {"LMAC Q", ENUM_UMAC_LMAC_PORT_2, 0}, + {"MDP TX Q", ENUM_UMAC_LMAC_PORT_2, 1}, + {"MDP RX Q", ENUM_UMAC_LMAC_PORT_2, 2}, + {"SEC TX Q", ENUM_UMAC_LMAC_PORT_2, 3}, + {"SEC RX Q", ENUM_UMAC_LMAC_PORT_2, 4}, + {"SFD_PARK Q", ENUM_UMAC_LMAC_PORT_2, 5}, + {"MDP_TXIOC Q", ENUM_UMAC_LMAC_PORT_2, 6}, + {"MDP_RXIOC Q", ENUM_UMAC_LMAC_PORT_2, 7}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, /* 24~30 not defined */ + {"RLS Q", ENUM_PLE_CTRL_PSE_PORT_3, ENUM_UMAC_PLE_CTRL_P3_Q_0X1F} }; + +static u_int8_t *sta_ctrl_reg[] = {"ENABLE", "DISABLE", "PAUSE"}; + +static struct EMPTY_QUEUE_INFO ple_txcmd_queue_empty_info[] = { + {"AC00Q", ENUM_UMAC_LMAC_PORT_2, 0x40}, + {"AC01Q", ENUM_UMAC_LMAC_PORT_2, 0x41}, + {"AC02Q", ENUM_UMAC_LMAC_PORT_2, 0x42}, + {"AC03Q", ENUM_UMAC_LMAC_PORT_2, 0x43}, + {"AC10Q", ENUM_UMAC_LMAC_PORT_2, 0x44}, + {"AC11Q", ENUM_UMAC_LMAC_PORT_2, 0x45}, + {"AC12Q", ENUM_UMAC_LMAC_PORT_2, 0x46}, + {"AC13Q", ENUM_UMAC_LMAC_PORT_2, 0x47}, + {"AC20Q", ENUM_UMAC_LMAC_PORT_2, 0x48}, + {"AC21Q", ENUM_UMAC_LMAC_PORT_2, 0x49}, + {"AC22Q", ENUM_UMAC_LMAC_PORT_2, 0x4a}, + {"AC23Q", ENUM_UMAC_LMAC_PORT_2, 0x4b}, + {"AC30Q", ENUM_UMAC_LMAC_PORT_2, 0x4c}, + {"AC31Q", ENUM_UMAC_LMAC_PORT_2, 0x4d}, + {"AC32Q", ENUM_UMAC_LMAC_PORT_2, 0x4e}, + {"AC33Q", ENUM_UMAC_LMAC_PORT_2, 0x4f}, + {"ALTX Q0", ENUM_UMAC_LMAC_PORT_2, 0x50}, + {"TF Q0", ENUM_UMAC_LMAC_PORT_2, 0x51}, + {"TWT TSF-TF Q0", ENUM_UMAC_LMAC_PORT_2, 0x52}, + {"TWT DL Q0", ENUM_UMAC_LMAC_PORT_2, 0x53}, + {"TWT UL Q0", ENUM_UMAC_LMAC_PORT_2, 0x54}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0} }; + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +void mt7915_show_ple_info( + struct ADAPTER *prAdapter, + u_int8_t fgDumpTxd) +{ + u_int32_t ple_buf_ctrl, pg_sz, pg_num; + u_int32_t ple_stat[25] = {0}, pg_flow_ctrl[8] = {0}; + u_int32_t sta_pause[6] = {0}, dis_sta_map[6] = {0}; + u_int32_t fpg_cnt, ffa_cnt, fpg_head, fpg_tail, hif_max_q, hif_min_q; + u_int32_t rpg_hif, upg_hif, cpu_max_q, cpu_min_q, rpg_cpu, upg_cpu; + u_int32_t i, j; + u_int32_t ple_txcmd_stat; + + HAL_MCR_RD(prAdapter, WF_PLE_TOP_PBUF_CTRL_ADDR, &ple_buf_ctrl); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_QUEUE_EMPTY_ADDR, &ple_stat[0]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC0_QUEUE_EMPTY0_ADDR, &ple_stat[1]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC0_QUEUE_EMPTY1_ADDR, &ple_stat[2]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC0_QUEUE_EMPTY2_ADDR, &ple_stat[3]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC0_QUEUE_EMPTY3_ADDR, &ple_stat[4]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC0_QUEUE_EMPTY4_ADDR, &ple_stat[5]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC0_QUEUE_EMPTY5_ADDR, &ple_stat[6]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC1_QUEUE_EMPTY0_ADDR, &ple_stat[7]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC1_QUEUE_EMPTY1_ADDR, &ple_stat[8]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC1_QUEUE_EMPTY2_ADDR, &ple_stat[9]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC1_QUEUE_EMPTY3_ADDR, &ple_stat[10]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC1_QUEUE_EMPTY4_ADDR, &ple_stat[11]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC1_QUEUE_EMPTY5_ADDR, &ple_stat[12]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC2_QUEUE_EMPTY0_ADDR, &ple_stat[13]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC2_QUEUE_EMPTY1_ADDR, &ple_stat[14]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC2_QUEUE_EMPTY2_ADDR, &ple_stat[15]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC2_QUEUE_EMPTY3_ADDR, &ple_stat[16]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC2_QUEUE_EMPTY4_ADDR, &ple_stat[17]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC2_QUEUE_EMPTY5_ADDR, &ple_stat[18]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC3_QUEUE_EMPTY0_ADDR, &ple_stat[19]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC3_QUEUE_EMPTY1_ADDR, &ple_stat[20]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC3_QUEUE_EMPTY2_ADDR, &ple_stat[21]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC3_QUEUE_EMPTY3_ADDR, &ple_stat[22]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC3_QUEUE_EMPTY4_ADDR, &ple_stat[23]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC3_QUEUE_EMPTY5_ADDR, &ple_stat[24]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_TXCMD_QUEUE_EMPTY_ADDR, + &ple_txcmd_stat); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_FREEPG_CNT_ADDR, &pg_flow_ctrl[0]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_FREEPG_HEAD_TAIL_ADDR, + &pg_flow_ctrl[1]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_PG_HIF_GROUP_ADDR, &pg_flow_ctrl[2]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_HIF_PG_INFO_ADDR, &pg_flow_ctrl[3]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_PG_CPU_GROUP_ADDR, &pg_flow_ctrl[4]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_CPU_PG_INFO_ADDR, &pg_flow_ctrl[5]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_PG_HIF_TXCMD_GROUP_ADDR, + &pg_flow_ctrl[6]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_HIF_TXCMD_PG_INFO_ADDR, + &pg_flow_ctrl[7]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_DIS_STA_MAP0_ADDR, &dis_sta_map[0]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_DIS_STA_MAP1_ADDR, &dis_sta_map[1]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_DIS_STA_MAP2_ADDR, &dis_sta_map[2]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_DIS_STA_MAP3_ADDR, &dis_sta_map[3]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_DIS_STA_MAP4_ADDR, &dis_sta_map[4]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_DIS_STA_MAP5_ADDR, &dis_sta_map[5]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_STATION_PAUSE0_ADDR, &sta_pause[0]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_STATION_PAUSE1_ADDR, &sta_pause[1]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_STATION_PAUSE2_ADDR, &sta_pause[2]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_STATION_PAUSE3_ADDR, &sta_pause[3]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_STATION_PAUSE4_ADDR, &sta_pause[4]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_STATION_PAUSE5_ADDR, &sta_pause[5]); + /* Configuration Info */ + DBGLOG(HAL, INFO, "PLE Configuration Info:\n"); + + DBGLOG(HAL, INFO, "\tPacket Buffer Control(0x%08x): 0x%08x\n", + WF_PLE_TOP_PBUF_CTRL_ADDR, + ple_buf_ctrl); + pg_sz = (ple_buf_ctrl & WF_PLE_TOP_PBUF_CTRL_PAGE_SIZE_CFG_MASK) >> + WF_PLE_TOP_PBUF_CTRL_PAGE_SIZE_CFG_SHFT; + DBGLOG(HAL, INFO, "\t\tPage Size=%d(%d bytes per page)\n", pg_sz, + (pg_sz == 1 ? 128 : 64)); + DBGLOG(HAL, INFO, "\t\tPage Offset=%d(in unit of 2KB)\n", + (ple_buf_ctrl & WF_PLE_TOP_PBUF_CTRL_PBUF_OFFSET_MASK) >> + WF_PLE_TOP_PBUF_CTRL_PBUF_OFFSET_SHFT); + pg_num = (ple_buf_ctrl & WF_PLE_TOP_PBUF_CTRL_TOTAL_PAGE_NUM_MASK) >> + WF_PLE_TOP_PBUF_CTRL_TOTAL_PAGE_NUM_SHFT; + DBGLOG(HAL, INFO, "\t\tTotal Page=%d pages\n", pg_num); + + /* Page Flow Control */ + DBGLOG(HAL, INFO, "PLE Page Flow Control:\n"); + DBGLOG(HAL, INFO, "\tFree page counter(0x%08x): 0x%08x\n", + WF_PLE_TOP_FREEPG_CNT_ADDR, + pg_flow_ctrl[0]); + fpg_cnt = (pg_flow_ctrl[0] & WF_PLE_TOP_FREEPG_CNT_FREEPG_CNT_MASK) >> + WF_PLE_TOP_FREEPG_CNT_FREEPG_CNT_SHFT; + DBGLOG(HAL, INFO, "\t\tThe toal page number of free=0x%03x\n", fpg_cnt); + ffa_cnt = (pg_flow_ctrl[0] & WF_PLE_TOP_FREEPG_CNT_FFA_CNT_MASK) >> + WF_PLE_TOP_FREEPG_CNT_FFA_CNT_SHFT; + DBGLOG(HAL, INFO, "\t\tThe free page numbers of free for all=0x%03x\n", + ffa_cnt); + DBGLOG(HAL, INFO, "\tFree page head and tail(0x%08x): 0x%08x\n", + WF_PLE_TOP_FREEPG_HEAD_TAIL_ADDR, + pg_flow_ctrl[1]); + fpg_head = (pg_flow_ctrl[1] & + WF_PLE_TOP_FREEPG_HEAD_TAIL_FREEPG_HEAD_MASK) >> + WF_PLE_TOP_FREEPG_HEAD_TAIL_FREEPG_HEAD_SHFT; + fpg_tail = (pg_flow_ctrl[1] & + WF_PLE_TOP_FREEPG_HEAD_TAIL_FREEPG_TAIL_MASK) >> + WF_PLE_TOP_FREEPG_HEAD_TAIL_FREEPG_TAIL_SHFT; + DBGLOG(HAL, INFO, + "\t\tThe tail/head page of free page list=0x%03x/0x%03x\n", + fpg_tail, fpg_head); + DBGLOG(HAL, INFO, + "\tReserved page counter of HIF group(0x%08x): 0x%08x\n", + WF_PLE_TOP_PG_HIF_GROUP_ADDR, + pg_flow_ctrl[2]); + DBGLOG(HAL, INFO, "\tHIF group page status(0x%08x): 0x%08x\n", + WF_PLE_TOP_HIF_PG_INFO_ADDR, + pg_flow_ctrl[3]); + hif_min_q = (pg_flow_ctrl[2] & + WF_PLE_TOP_PG_HIF_GROUP_HIF_MIN_QUOTA_MASK) >> + WF_PLE_TOP_PG_HIF_GROUP_HIF_MIN_QUOTA_SHFT; + hif_max_q = (pg_flow_ctrl[2] & + WF_PLE_TOP_PG_HIF_GROUP_HIF_MAX_QUOTA_MASK) >> + WF_PLE_TOP_PG_HIF_GROUP_HIF_MAX_QUOTA_SHFT; + DBGLOG(HAL, INFO, + "\t\tThe max/min quota pages of HIF group=0x%03x/0x%03x\n", + hif_max_q, hif_min_q); + rpg_hif = (pg_flow_ctrl[3] & WF_PLE_TOP_HIF_PG_INFO_HIF_RSV_CNT_MASK) >> + WF_PLE_TOP_HIF_PG_INFO_HIF_RSV_CNT_SHFT; + upg_hif = (pg_flow_ctrl[3] & WF_PLE_TOP_HIF_PG_INFO_HIF_SRC_CNT_MASK) >> + WF_PLE_TOP_HIF_PG_INFO_HIF_SRC_CNT_SHFT; + DBGLOG(HAL, INFO, + "\t\tThe used/reserved pages of HIF group=0x%03x/0x%03x\n", + upg_hif, rpg_hif); + + DBGLOG(HAL, INFO, + "\tReserved page counter of HIF_TXCMD group(0x%08x): 0x%08x\n", + WF_PLE_TOP_PG_HIF_WMTXD_GROUP_ADDR, + pg_flow_ctrl[6]); + DBGLOG(HAL, INFO, "\tHIF_TXCMD group page status(0x%08x): 0x%08x\n", + WF_PLE_TOP_HIF_WMTXD_PG_INFO_ADDR, + pg_flow_ctrl[7]); + cpu_min_q = (pg_flow_ctrl[6] & + WF_PLE_TOP_PG_HIF_TXCMD_GROUP_HIF_TXCMD_MIN_QUOTA_MASK) >> + WF_PLE_TOP_PG_HIF_TXCMD_GROUP_HIF_TXCMD_MIN_QUOTA_SHFT; + cpu_max_q = (pg_flow_ctrl[6] & + WF_PLE_TOP_PG_HIF_TXCMD_GROUP_HIF_TXCMD_MAX_QUOTA_MASK) >> + WF_PLE_TOP_PG_HIF_TXCMD_GROUP_HIF_TXCMD_MAX_QUOTA_SHFT; + DBGLOG(HAL, INFO, + "\t\tThe max/min quota pages of HIF_TXCMD group=0x%03x/0x%03x\n", + cpu_max_q, cpu_min_q); + rpg_cpu = (pg_flow_ctrl[7] & + WF_PLE_TOP_HIF_TXCMD_PG_INFO_HIF_TXCMD_SRC_CNT_MASK) >> + WF_PLE_TOP_HIF_TXCMD_PG_INFO_HIF_TXCMD_SRC_CNT_SHFT; + upg_cpu = (pg_flow_ctrl[7] & + WF_PLE_TOP_HIF_TXCMD_PG_INFO_HIF_TXCMD_RSV_CNT_MASK) >> + WF_PLE_TOP_HIF_TXCMD_PG_INFO_HIF_TXCMD_RSV_CNT_SHFT; + DBGLOG(HAL, INFO, + "\t\tThe used/reserved pages of HIF_TXCMD group=0x%03x/0x%03x\n", + upg_cpu, rpg_cpu); + + DBGLOG(HAL, INFO, + "\tReserved page counter of CPU group(0x%08x): 0x%08x\n", + WF_PLE_TOP_PG_CPU_GROUP_ADDR, + pg_flow_ctrl[4]); + DBGLOG(HAL, INFO, "\tCPU group page status(0x%08x): 0x%08x\n", + WF_PLE_TOP_CPU_PG_INFO_ADDR, + pg_flow_ctrl[5]); + cpu_min_q = (pg_flow_ctrl[4] & + WF_PLE_TOP_PG_CPU_GROUP_CPU_MIN_QUOTA_MASK) >> + WF_PLE_TOP_PG_CPU_GROUP_CPU_MIN_QUOTA_SHFT; + cpu_max_q = (pg_flow_ctrl[4] & + WF_PLE_TOP_PG_CPU_GROUP_CPU_MAX_QUOTA_MASK) >> + WF_PLE_TOP_PG_CPU_GROUP_CPU_MAX_QUOTA_SHFT; + DBGLOG(HAL, INFO, + "\t\tThe max/min quota pages of CPU group=0x%03x/0x%03x\n", + cpu_max_q, cpu_min_q); + rpg_cpu = (pg_flow_ctrl[5] & WF_PLE_TOP_CPU_PG_INFO_CPU_RSV_CNT_MASK) >> + WF_PLE_TOP_CPU_PG_INFO_CPU_RSV_CNT_SHFT; + upg_cpu = (pg_flow_ctrl[5] & WF_PLE_TOP_CPU_PG_INFO_CPU_SRC_CNT_MASK) >> + WF_PLE_TOP_CPU_PG_INFO_CPU_SRC_CNT_SHFT; + DBGLOG(HAL, INFO, + "\t\tThe used/reserved pages of CPU group=0x%03x/0x%03x\n", + upg_cpu, rpg_cpu); + + if ((ple_stat[0] & WF_PLE_TOP_QUEUE_EMPTY_ALL_AC_EMPTY_MASK) == 0) { + for (j = 0; j < 24; j = j + 6) { + if (j % 6 == 0) { + DBGLOG(HAL, INFO, + "\tNonempty AC%d Q of STA#: ", j / 6); + } + + for (i = 0; i < 32; i++) { + if (((ple_stat[j + 1] & (0x1 << i)) >> i) == + 0) { + DBGLOG(HAL, INFO, "%d ", + i + (j % 6) * 32); + } + } + } + + DBGLOG(HAL, INFO, "\n"); + } + + DBGLOG(HAL, INFO, "Nonempty Q info:\n"); + + for (i = 0; i < 31; i++) { + if (((ple_stat[0] & (0x1 << i)) >> i) == 0) { + uint32_t hfid, tfid, pktcnt, fl_que_ctrl[3] = {0}; + + if (ple_queue_empty_info[i].QueueName != NULL) { + DBGLOG(HAL, INFO, "\t%s: ", + ple_queue_empty_info[i].QueueName); + fl_que_ctrl[0] |= + WF_PLE_TOP_FL_QUE_CTRL_0_EXECUTE_MASK; + fl_que_ctrl[0] |= + (ple_queue_empty_info[i].Portid + << WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_PID_SHFT); + fl_que_ctrl[0] |= + (ple_queue_empty_info[i].Queueid + << WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_QID_SHFT); + } else + continue; + + HAL_MCR_WR(prAdapter, WF_PLE_TOP_FL_QUE_CTRL_0_ADDR, + fl_que_ctrl[0]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_FL_QUE_CTRL_2_ADDR, + &fl_que_ctrl[1]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_FL_QUE_CTRL_3_ADDR, + &fl_que_ctrl[2]); + hfid = (fl_que_ctrl[1] & + WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_HEAD_FID_MASK) >> + WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_HEAD_FID_SHFT; + tfid = (fl_que_ctrl[1] & + WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_TAIL_FID_MASK) >> + WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_TAIL_FID_SHFT; + pktcnt = + (fl_que_ctrl[2] & + WF_PLE_TOP_FL_QUE_CTRL_3_QUEUE_PKT_NUM_MASK) >> + WF_PLE_TOP_FL_QUE_CTRL_3_QUEUE_PKT_NUM_SHFT; + DBGLOG(HAL, INFO, + "tail/head fid = 0x%03x/0x%03x, pkt cnt = 0x%03x\n", + tfid, hfid, pktcnt); + if (pktcnt > 0 && fgDumpTxd) + connac2x_show_txd_Info( + prAdapter, hfid); + } + } + + for (j = 0; j < 24; j = j + 6) { /* show AC Q info */ + for (i = 0; i < 32; i++) { + if (((ple_stat[j + 1] & (0x1 << i)) >> i) == 0) { + uint32_t hfid, tfid, pktcnt, ac_num = j / 6, + ctrl = 0; + uint32_t sta_num = i + (j % 6) * 32, + fl_que_ctrl[3] = {0}; + uint32_t wmmidx = 0; + + DBGLOG(HAL, INFO, "\tSTA%d AC%d: ", sta_num, + ac_num); + + fl_que_ctrl[0] |= + WF_PLE_TOP_FL_QUE_CTRL_0_EXECUTE_MASK; + fl_que_ctrl[0] |= + (ENUM_UMAC_LMAC_PORT_2 + << WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_PID_SHFT); + fl_que_ctrl[0] |= + (ac_num + << WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_QID_SHFT); + fl_que_ctrl[0] |= + (sta_num + << WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_WLANID_SHFT); + HAL_MCR_WR(prAdapter, + WF_PLE_TOP_FL_QUE_CTRL_0_ADDR, + fl_que_ctrl[0]); + HAL_MCR_RD(prAdapter, + WF_PLE_TOP_FL_QUE_CTRL_2_ADDR, + &fl_que_ctrl[1]); + HAL_MCR_RD(prAdapter, + WF_PLE_TOP_FL_QUE_CTRL_3_ADDR, + &fl_que_ctrl[2]); + hfid = (fl_que_ctrl[1] & + WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_HEAD_FID_MASK) >> + WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_HEAD_FID_SHFT; + tfid = (fl_que_ctrl[1] & + WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_TAIL_FID_MASK) >> + WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_TAIL_FID_SHFT; + + pktcnt = + (fl_que_ctrl[2] & + WF_PLE_TOP_FL_QUE_CTRL_3_QUEUE_PKT_NUM_MASK) >> + WF_PLE_TOP_FL_QUE_CTRL_3_QUEUE_PKT_NUM_SHFT; + DBGLOG(HAL, INFO, + "tail/head fid = 0x%03x/0x%03x, pkt cnt = %x", + tfid, hfid, pktcnt); + + if (((sta_pause[j % 6] & 0x1 << i) >> i) == 1) + ctrl = 2; + + if (((dis_sta_map[j % 6] & 0x1 << i) >> i) == 1) + ctrl = 1; + + DBGLOG(HAL, INFO, " ctrl = %s", + sta_ctrl_reg[ctrl]); + DBGLOG(HAL, INFO, " (wmmidx=%d)\n", + wmmidx); + if (pktcnt > 0 && fgDumpTxd) + connac2x_show_txd_Info( + prAdapter, hfid); + } + } + } + + if (~ple_txcmd_stat) { + DBGLOG(HAL, INFO, "Nonempty TXCMD Q info:\n"); + for (i = 0; i < 31; i++) { + if (((ple_txcmd_stat & (0x1 << i)) >> i) == 0) { + uint32_t hfid, tfid; + uint32_t pktcnt, fl_que_ctrl[3] = {0}; + + if (ple_txcmd_queue_empty_info[i].QueueName != + NULL) { + DBGLOG(HAL, INFO, "\t%s: ", + ple_txcmd_queue_empty_info[i] + .QueueName); + fl_que_ctrl[0] |= + WF_PLE_TOP_FL_QUE_CTRL_0_EXECUTE_MASK; + fl_que_ctrl[0] |= + (ple_txcmd_queue_empty_info[i] + .Portid + << WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_PID_SHFT); + fl_que_ctrl[0] |= + (ple_txcmd_queue_empty_info[i] + .Queueid + << WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_QID_SHFT); + } else + continue; + + HAL_MCR_WR(prAdapter, + WF_PLE_TOP_FL_QUE_CTRL_0_ADDR, + fl_que_ctrl[0]); + HAL_MCR_RD(prAdapter, + WF_PLE_TOP_FL_QUE_CTRL_2_ADDR, + &fl_que_ctrl[1]); + HAL_MCR_RD(prAdapter, + WF_PLE_TOP_FL_QUE_CTRL_3_ADDR, + &fl_que_ctrl[2]); + hfid = (fl_que_ctrl[1] & + WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_HEAD_FID_MASK) >> + WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_HEAD_FID_SHFT; + tfid = (fl_que_ctrl[1] & + WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_TAIL_FID_MASK) >> + WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_TAIL_FID_SHFT; + pktcnt = + (fl_que_ctrl[2] & + WF_PLE_TOP_FL_QUE_CTRL_3_QUEUE_PKT_NUM_MASK) >> + WF_PLE_TOP_FL_QUE_CTRL_3_QUEUE_PKT_NUM_SHFT; + DBGLOG(HAL, INFO, "tail/head fid ="); + DBGLOG(HAL, INFO, "0x%03x/0x%03x,", tfid, hfid); + DBGLOG(HAL, INFO, "pkt cnt = 0x%03x\n", pktcnt); + } + } + } +} + +void mt7915_show_pse_info( + struct ADAPTER *prAdapter) +{ + u_int32_t pse_buf_ctrl, pg_sz, pg_num; + u_int32_t pse_stat, pg_flow_ctrl[20] = {0}; + u_int32_t fpg_cnt, ffa_cnt, fpg_head, fpg_tail; + u_int32_t max_q, min_q, rsv_pg, used_pg; + u_int32_t i; + + HAL_MCR_RD(prAdapter, WF_PSE_TOP_PBUF_CTRL_ADDR, &pse_buf_ctrl); + HAL_MCR_RD(prAdapter, WF_PSE_TOP_QUEUE_EMPTY_ADDR, &pse_stat); + HAL_MCR_RD(prAdapter, WF_PSE_TOP_FREEPG_CNT_ADDR, &pg_flow_ctrl[0]); + HAL_MCR_RD(prAdapter, WF_PSE_TOP_FREEPG_HEAD_TAIL_ADDR, + &pg_flow_ctrl[1]); + HAL_MCR_RD(prAdapter, WF_PSE_TOP_PG_HIF0_GROUP_ADDR, &pg_flow_ctrl[2]); + HAL_MCR_RD(prAdapter, WF_PSE_TOP_HIF0_PG_INFO_ADDR, &pg_flow_ctrl[3]); + HAL_MCR_RD(prAdapter, WF_PSE_TOP_PG_HIF1_GROUP_ADDR, &pg_flow_ctrl[4]); + HAL_MCR_RD(prAdapter, WF_PSE_TOP_HIF1_PG_INFO_ADDR, &pg_flow_ctrl[5]); + HAL_MCR_RD(prAdapter, WF_PSE_TOP_PG_CPU_GROUP_ADDR, &pg_flow_ctrl[6]); + HAL_MCR_RD(prAdapter, WF_PSE_TOP_CPU_PG_INFO_ADDR, &pg_flow_ctrl[7]); + HAL_MCR_RD(prAdapter, WF_PSE_TOP_PG_LMAC0_GROUP_ADDR, &pg_flow_ctrl[8]); + HAL_MCR_RD(prAdapter, WF_PSE_TOP_LMAC0_PG_INFO_ADDR, &pg_flow_ctrl[9]); + HAL_MCR_RD(prAdapter, WF_PSE_TOP_PG_LMAC1_GROUP_ADDR, + &pg_flow_ctrl[10]); + HAL_MCR_RD(prAdapter, WF_PSE_TOP_LMAC1_PG_INFO_ADDR, &pg_flow_ctrl[11]); + HAL_MCR_RD(prAdapter, WF_PSE_TOP_PG_LMAC2_GROUP_ADDR, + &pg_flow_ctrl[12]); + HAL_MCR_RD(prAdapter, WF_PSE_TOP_LMAC2_PG_INFO_ADDR, &pg_flow_ctrl[13]); + HAL_MCR_RD(prAdapter, WF_PSE_TOP_PG_PLE_GROUP_ADDR, &pg_flow_ctrl[14]); + HAL_MCR_RD(prAdapter, WF_PSE_TOP_PLE_PG_INFO_ADDR, &pg_flow_ctrl[15]); + HAL_MCR_RD(prAdapter, WF_PSE_TOP_PG_LMAC3_GROUP_ADDR, + &pg_flow_ctrl[16]); + HAL_MCR_RD(prAdapter, WF_PSE_TOP_LMAC3_PG_INFO_ADDR, &pg_flow_ctrl[17]); + HAL_MCR_RD(prAdapter, WF_PSE_TOP_PG_MDP_GROUP_ADDR, &pg_flow_ctrl[18]); + HAL_MCR_RD(prAdapter, WF_PSE_TOP_MDP_PG_INFO_ADDR, &pg_flow_ctrl[19]); + /* Configuration Info */ + DBGLOG(HAL, INFO, "PSE Configuration Info:\n"); + DBGLOG(HAL, INFO, "\tPacket Buffer Control(0x%08x): 0x%08x\n", + WF_PSE_TOP_PBUF_CTRL_ADDR, + pse_buf_ctrl); + pg_sz = (pse_buf_ctrl & WF_PSE_TOP_PBUF_CTRL_PAGE_SIZE_CFG_MASK) >> + WF_PSE_TOP_PBUF_CTRL_PAGE_SIZE_CFG_SHFT; + DBGLOG(HAL, INFO, "\t\tPage Size=%d(%d bytes per page)\n", pg_sz, + (pg_sz == 1 ? 256 : 128)); + DBGLOG(HAL, INFO, "\t\tPage Offset=%d(in unit of 64KB)\n", + (pse_buf_ctrl & WF_PSE_TOP_PBUF_CTRL_PBUF_OFFSET_MASK) >> + WF_PSE_TOP_PBUF_CTRL_PBUF_OFFSET_SHFT); + pg_num = (pse_buf_ctrl & WF_PSE_TOP_PBUF_CTRL_TOTAL_PAGE_NUM_MASK) >> + WF_PSE_TOP_PBUF_CTRL_TOTAL_PAGE_NUM_SHFT; + DBGLOG(HAL, INFO, "\t\tTotal page numbers=%d pages\n", pg_num); + /* Page Flow Control */ + DBGLOG(HAL, INFO, "PSE Page Flow Control:\n"); + DBGLOG(HAL, INFO, "\tFree page counter(0x%08x): 0x%08x\n", + WF_PSE_TOP_FREEPG_CNT_ADDR, + pg_flow_ctrl[0]); + fpg_cnt = (pg_flow_ctrl[0] & WF_PSE_TOP_FREEPG_CNT_FREEPG_CNT_MASK) >> + WF_PSE_TOP_FREEPG_CNT_FREEPG_CNT_SHFT; + DBGLOG(HAL, INFO, "\t\tThe toal page number of free=0x%03x\n", fpg_cnt); + ffa_cnt = (pg_flow_ctrl[0] & WF_PSE_TOP_FREEPG_CNT_FFA_CNT_MASK) >> + WF_PSE_TOP_FREEPG_CNT_FFA_CNT_SHFT; + DBGLOG(HAL, INFO, "\t\tThe free page numbers of free for all=0x%03x\n", + ffa_cnt); + DBGLOG(HAL, INFO, "\tFree page head and tail(0x%08x): 0x%08x\n", + WF_PSE_TOP_FREEPG_HEAD_TAIL_ADDR, + pg_flow_ctrl[1]); + fpg_head = (pg_flow_ctrl[1] & + WF_PSE_TOP_FREEPG_HEAD_TAIL_FREEPG_HEAD_MASK) >> + WF_PSE_TOP_FREEPG_HEAD_TAIL_FREEPG_HEAD_SHFT; + fpg_tail = (pg_flow_ctrl[1] & + WF_PSE_TOP_FREEPG_HEAD_TAIL_FREEPG_TAIL_MASK) >> + WF_PSE_TOP_FREEPG_HEAD_TAIL_FREEPG_TAIL_SHFT; + DBGLOG(HAL, INFO, + "\t\tThe tail/head page of free page list=0x%03x/0x%03x\n", + fpg_tail, fpg_head); + DBGLOG(HAL, INFO, + "\tReserved page counter of HIF0 group(0x%08x): 0x%08x\n", + WF_PSE_TOP_PG_HIF0_GROUP_ADDR, + pg_flow_ctrl[2]); + DBGLOG(HAL, INFO, "\tHIF0 group page status(0x%08x): 0x%08x\n", + WF_PSE_TOP_HIF0_PG_INFO_ADDR, + pg_flow_ctrl[3]); + min_q = (pg_flow_ctrl[2] & + WF_PSE_TOP_PG_HIF0_GROUP_HIF0_MIN_QUOTA_MASK) >> + WF_PSE_TOP_PG_HIF0_GROUP_HIF0_MIN_QUOTA_SHFT; + max_q = (pg_flow_ctrl[2] & + WF_PSE_TOP_PG_HIF0_GROUP_HIF0_MAX_QUOTA_MASK) >> + WF_PSE_TOP_PG_HIF0_GROUP_HIF0_MAX_QUOTA_SHFT; + DBGLOG(HAL, INFO, + "\t\tThe max/min quota pages of HIF0 group=0x%03x/0x%03x\n", + max_q, min_q); + rsv_pg = + (pg_flow_ctrl[3] & WF_PSE_TOP_HIF0_PG_INFO_HIF0_RSV_CNT_MASK) >> + WF_PSE_TOP_HIF0_PG_INFO_HIF0_RSV_CNT_SHFT; + used_pg = + (pg_flow_ctrl[3] & WF_PSE_TOP_HIF0_PG_INFO_HIF0_SRC_CNT_MASK) >> + WF_PSE_TOP_HIF0_PG_INFO_HIF0_SRC_CNT_SHFT; + DBGLOG(HAL, INFO, + "\t\tThe used/reserved pages of HIF0 group=0x%03x/0x%03x\n", + used_pg, rsv_pg); + DBGLOG(HAL, INFO, + "\tReserved page counter of HIF1 group(0x%08x): 0x%08x\n", + WF_PSE_TOP_PG_HIF1_GROUP_ADDR, + pg_flow_ctrl[4]); + DBGLOG(HAL, INFO, "\tHIF1 group page status(0x%08x): 0x%08x\n", + WF_PSE_TOP_HIF1_PG_INFO_ADDR, + pg_flow_ctrl[5]); + min_q = (pg_flow_ctrl[4] & + WF_PSE_TOP_PG_HIF1_GROUP_HIF1_MIN_QUOTA_MASK) >> + WF_PSE_TOP_PG_HIF1_GROUP_HIF1_MIN_QUOTA_SHFT; + max_q = (pg_flow_ctrl[4] & + WF_PSE_TOP_PG_HIF1_GROUP_HIF1_MAX_QUOTA_MASK) >> + WF_PSE_TOP_PG_HIF1_GROUP_HIF1_MAX_QUOTA_SHFT; + DBGLOG(HAL, INFO, + "\t\tThe max/min quota pages of HIF1 group=0x%03x/0x%03x\n", + max_q, min_q); + rsv_pg = + (pg_flow_ctrl[5] & WF_PSE_TOP_HIF1_PG_INFO_HIF1_RSV_CNT_MASK) >> + WF_PSE_TOP_HIF1_PG_INFO_HIF1_RSV_CNT_SHFT; + used_pg = + (pg_flow_ctrl[5] & WF_PSE_TOP_HIF1_PG_INFO_HIF1_SRC_CNT_MASK) >> + WF_PSE_TOP_HIF1_PG_INFO_HIF1_SRC_CNT_SHFT; + DBGLOG(HAL, INFO, + "\t\tThe used/reserved pages of HIF1 group=0x%03x/0x%03x\n", + used_pg, rsv_pg); + DBGLOG(HAL, INFO, + "\tReserved page counter of CPU group(0x%08x): 0x%08x\n", + WF_PSE_TOP_PG_CPU_GROUP_ADDR, + pg_flow_ctrl[6]); + DBGLOG(HAL, INFO, "\tCPU group page status(0x%08x): 0x%08x\n", + WF_PSE_TOP_CPU_PG_INFO_ADDR, + pg_flow_ctrl[7]); + min_q = (pg_flow_ctrl[6] & + WF_PSE_TOP_PG_CPU_GROUP_CPU_MIN_QUOTA_MASK) >> + WF_PSE_TOP_PG_CPU_GROUP_CPU_MIN_QUOTA_SHFT; + max_q = (pg_flow_ctrl[6] & + WF_PSE_TOP_PG_CPU_GROUP_CPU_MAX_QUOTA_MASK) >> + WF_PSE_TOP_PG_CPU_GROUP_CPU_MAX_QUOTA_SHFT; + DBGLOG(HAL, INFO, + "\t\tThe max/min quota pages of CPU group=0x%03x/0x%03x\n", + max_q, min_q); + rsv_pg = (pg_flow_ctrl[7] & WF_PSE_TOP_CPU_PG_INFO_CPU_RSV_CNT_MASK) >> + WF_PSE_TOP_CPU_PG_INFO_CPU_RSV_CNT_SHFT; + used_pg = (pg_flow_ctrl[7] & WF_PSE_TOP_CPU_PG_INFO_CPU_SRC_CNT_MASK) >> + WF_PSE_TOP_CPU_PG_INFO_CPU_SRC_CNT_SHFT; + DBGLOG(HAL, INFO, + "\t\tThe used/reserved pages of CPU group=0x%03x/0x%03x\n", + used_pg, rsv_pg); + DBGLOG(HAL, INFO, + "\tReserved page counter of LMAC0 group(0x%08x): 0x%08x\n", + WF_PSE_TOP_PG_LMAC0_GROUP_ADDR, + pg_flow_ctrl[8]); + DBGLOG(HAL, INFO, "\tLMAC0 group page status(0x%08x): 0x%08x\n", + WF_PSE_TOP_LMAC0_PG_INFO_ADDR, + pg_flow_ctrl[9]); + min_q = (pg_flow_ctrl[8] & + WF_PSE_TOP_PG_LMAC0_GROUP_LMAC0_MIN_QUOTA_MASK) >> + WF_PSE_TOP_PG_LMAC0_GROUP_LMAC0_MIN_QUOTA_SHFT; + max_q = (pg_flow_ctrl[8] & + WF_PSE_TOP_PG_LMAC0_GROUP_LMAC0_MAX_QUOTA_MASK) >> + WF_PSE_TOP_PG_LMAC0_GROUP_LMAC0_MAX_QUOTA_SHFT; + DBGLOG(HAL, INFO, + "\t\tThe max/min quota pages of LMAC0 group=0x%03x/0x%03x\n", + max_q, min_q); + rsv_pg = (pg_flow_ctrl[9] & + WF_PSE_TOP_LMAC0_PG_INFO_LMAC0_RSV_CNT_MASK) >> + WF_PSE_TOP_LMAC0_PG_INFO_LMAC0_RSV_CNT_SHFT; + used_pg = (pg_flow_ctrl[9] & + WF_PSE_TOP_LMAC0_PG_INFO_LMAC0_SRC_CNT_MASK) >> + WF_PSE_TOP_LMAC0_PG_INFO_LMAC0_SRC_CNT_SHFT; + DBGLOG(HAL, INFO, + "\t\tThe used/reserved pages of LMAC0 group=0x%03x/0x%03x\n", + used_pg, rsv_pg); + DBGLOG(HAL, INFO, + "\tReserved page counter of LMAC1 group(0x%08x): 0x%08x\n", + WF_PSE_TOP_PG_LMAC1_GROUP_ADDR, + pg_flow_ctrl[10]); + DBGLOG(HAL, INFO, "\tLMAC1 group page status(0x%08x): 0x%08x\n", + WF_PSE_TOP_LMAC1_PG_INFO_ADDR, + pg_flow_ctrl[11]); + min_q = (pg_flow_ctrl[10] & + WF_PSE_TOP_PG_LMAC1_GROUP_LMAC1_MIN_QUOTA_MASK) >> + WF_PSE_TOP_PG_LMAC1_GROUP_LMAC1_MIN_QUOTA_SHFT; + max_q = (pg_flow_ctrl[10] & + WF_PSE_TOP_PG_LMAC1_GROUP_LMAC1_MAX_QUOTA_MASK) >> + WF_PSE_TOP_PG_LMAC1_GROUP_LMAC1_MAX_QUOTA_SHFT; + DBGLOG(HAL, INFO, + "\t\tThe max/min quota pages of LMAC1 group=0x%03x/0x%03x\n", + max_q, min_q); + rsv_pg = (pg_flow_ctrl[11] & + WF_PSE_TOP_LMAC1_PG_INFO_LMAC1_RSV_CNT_MASK) >> + WF_PSE_TOP_LMAC1_PG_INFO_LMAC1_RSV_CNT_SHFT; + used_pg = (pg_flow_ctrl[11] & + WF_PSE_TOP_LMAC1_PG_INFO_LMAC1_SRC_CNT_MASK) >> + WF_PSE_TOP_LMAC1_PG_INFO_LMAC1_SRC_CNT_SHFT; + DBGLOG(HAL, INFO, + "\t\tThe used/reserved pages of LMAC1 group=0x%03x/0x%03x\n", + used_pg, rsv_pg); + DBGLOG(HAL, INFO, + "\tReserved page counter of LMAC2 group(0x%08x): 0x%08x\n", + WF_PSE_TOP_PG_LMAC2_GROUP_ADDR, + pg_flow_ctrl[11]); + DBGLOG(HAL, INFO, "\tLMAC2 group page status(0x%08x): 0x%08x\n", + WF_PSE_TOP_LMAC2_PG_INFO_ADDR, + pg_flow_ctrl[12]); + min_q = (pg_flow_ctrl[12] & + WF_PSE_TOP_PG_LMAC2_GROUP_LMAC2_MIN_QUOTA_MASK) >> + WF_PSE_TOP_PG_LMAC2_GROUP_LMAC2_MIN_QUOTA_SHFT; + max_q = (pg_flow_ctrl[12] & + WF_PSE_TOP_PG_LMAC2_GROUP_LMAC2_MAX_QUOTA_MASK) >> + WF_PSE_TOP_PG_LMAC2_GROUP_LMAC2_MAX_QUOTA_SHFT; + DBGLOG(HAL, INFO, + "\t\tThe max/min quota pages of LMAC2 group=0x%03x/0x%03x\n", + max_q, min_q); + rsv_pg = (pg_flow_ctrl[13] & + WF_PSE_TOP_LMAC2_PG_INFO_LMAC2_RSV_CNT_MASK) >> + WF_PSE_TOP_LMAC2_PG_INFO_LMAC2_RSV_CNT_SHFT; + used_pg = (pg_flow_ctrl[13] & + WF_PSE_TOP_LMAC2_PG_INFO_LMAC2_SRC_CNT_MASK) >> + WF_PSE_TOP_LMAC2_PG_INFO_LMAC2_SRC_CNT_SHFT; + DBGLOG(HAL, INFO, + "\t\tThe used/reserved pages of LMAC2 group=0x%03x/0x%03x\n", + used_pg, rsv_pg); + DBGLOG(HAL, INFO, + "\tReserved page counter of LMAC3 group(0x%08x): 0x%08x\n", + WF_PSE_TOP_PG_LMAC3_GROUP_ADDR, + pg_flow_ctrl[16]); + DBGLOG(HAL, INFO, "\tLMAC3 group page status(0x%08x): 0x%08x\n", + WF_PSE_TOP_LMAC3_PG_INFO_ADDR, + pg_flow_ctrl[17]); + min_q = (pg_flow_ctrl[16] & + WF_PSE_TOP_PG_LMAC3_GROUP_LMAC3_MIN_QUOTA_MASK) >> + WF_PSE_TOP_PG_LMAC3_GROUP_LMAC3_MIN_QUOTA_SHFT; + max_q = (pg_flow_ctrl[16] & + WF_PSE_TOP_PG_LMAC3_GROUP_LMAC3_MAX_QUOTA_MASK) >> + WF_PSE_TOP_PG_LMAC3_GROUP_LMAC3_MAX_QUOTA_SHFT; + DBGLOG(HAL, INFO, + "\t\tThe max/min quota pages of LMAC3 group=0x%03x/0x%03x\n", + max_q, min_q); + rsv_pg = (pg_flow_ctrl[17] & + WF_PSE_TOP_LMAC3_PG_INFO_LMAC3_RSV_CNT_MASK) >> + WF_PSE_TOP_LMAC3_PG_INFO_LMAC3_RSV_CNT_SHFT; + used_pg = (pg_flow_ctrl[17] & + WF_PSE_TOP_LMAC3_PG_INFO_LMAC3_SRC_CNT_MASK) >> + WF_PSE_TOP_LMAC3_PG_INFO_LMAC3_SRC_CNT_SHFT; + DBGLOG(HAL, INFO, + "\t\tThe used/reserved pages of LMAC3 group=0x%03x/0x%03x\n", + used_pg, rsv_pg); + DBGLOG(HAL, INFO, + "\tReserved page counter of PLE group(0x%08x): 0x%08x\n", + WF_PSE_TOP_PG_PLE_GROUP_ADDR, + pg_flow_ctrl[14]); + DBGLOG(HAL, INFO, "\tPLE group page status(0x%08x): 0x%08x\n", + WF_PSE_TOP_PLE_PG_INFO_ADDR, + pg_flow_ctrl[15]); + min_q = (pg_flow_ctrl[14] & + WF_PSE_TOP_PG_PLE_GROUP_PLE_MIN_QUOTA_MASK) >> + WF_PSE_TOP_PG_PLE_GROUP_PLE_MIN_QUOTA_SHFT; + max_q = (pg_flow_ctrl[14] & + WF_PSE_TOP_PG_PLE_GROUP_PLE_MAX_QUOTA_MASK) >> + WF_PSE_TOP_PG_PLE_GROUP_PLE_MAX_QUOTA_SHFT; + DBGLOG(HAL, INFO, + "\t\tThe max/min quota pages of PLE group=0x%03x/0x%03x\n", + max_q, min_q); + rsv_pg = (pg_flow_ctrl[15] & WF_PSE_TOP_PLE_PG_INFO_PLE_RSV_CNT_MASK) >> + WF_PSE_TOP_PLE_PG_INFO_PLE_RSV_CNT_SHFT; + used_pg = + (pg_flow_ctrl[15] & WF_PSE_TOP_PLE_PG_INFO_PLE_SRC_CNT_MASK) >> + WF_PSE_TOP_PLE_PG_INFO_PLE_SRC_CNT_SHFT; + DBGLOG(HAL, INFO, + "\t\tThe used/reserved pages of PLE group=0x%03x/0x%03x\n", + used_pg, rsv_pg); + DBGLOG(HAL, INFO, + "\tReserved page counter of MDP group(0x%08x): 0x%08x\n", + WF_PSE_TOP_PG_MDP_GROUP_ADDR, + pg_flow_ctrl[18]); + DBGLOG(HAL, INFO, "\tMDP group page status(0x%08x): 0x%08x\n", + WF_PSE_TOP_MDP_PG_INFO_ADDR, + pg_flow_ctrl[19]); + min_q = (pg_flow_ctrl[18] & + WF_PSE_TOP_PG_MDP_GROUP_MDP_MIN_QUOTA_MASK) >> + WF_PSE_TOP_PG_MDP_GROUP_MDP_MIN_QUOTA_SHFT; + max_q = (pg_flow_ctrl[18] & + WF_PSE_TOP_PG_MDP_GROUP_MDP_MAX_QUOTA_MASK) >> + WF_PSE_TOP_PG_MDP_GROUP_MDP_MAX_QUOTA_SHFT; + DBGLOG(HAL, INFO, + "\t\tThe max/min quota pages of MDP group=0x%03x/0x%03x\n", + max_q, min_q); + rsv_pg = (pg_flow_ctrl[19] & WF_PSE_TOP_MDP_PG_INFO_MDP_RSV_CNT_MASK) >> + WF_PSE_TOP_MDP_PG_INFO_MDP_RSV_CNT_SHFT; + used_pg = + (pg_flow_ctrl[19] & WF_PSE_TOP_MDP_PG_INFO_MDP_SRC_CNT_MASK) >> + WF_PSE_TOP_MDP_PG_INFO_MDP_SRC_CNT_SHFT; + DBGLOG(HAL, INFO, + "\t\tThe used/reserved pages of MDP group=0x%03x/0x%03x\n", + used_pg, rsv_pg); + /* Queue Empty Status */ + DBGLOG(HAL, INFO, "PSE Queue Empty Status:\n"); + DBGLOG(HAL, INFO, "\tQUEUE_EMPTY(0x%08x): 0x%08x\n", + WF_PSE_TOP_QUEUE_EMPTY_ADDR, + pse_stat); + DBGLOG(HAL, INFO, "\t\tCPU Q0/1/2/3 empty=%d/%d/%d/%d\n", + (pse_stat & WF_PSE_TOP_QUEUE_EMPTY_CPU_Q0_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_CPU_Q0_EMPTY_SHFT, + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_CPU_Q1_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_CPU_Q1_EMPTY_SHFT), + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_CPU_Q2_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_CPU_Q2_EMPTY_SHFT), + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_CPU_Q3_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_CPU_Q3_EMPTY_SHFT)); + DBGLOG(HAL, INFO, "\t\tHIF Q0/1/2/3/4/5 empty=%d/%d/%d/%d/%d/%d\n", + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_HIF_0_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_HIF_0_EMPTY_SHFT), + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_HIF_1_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_HIF_1_EMPTY_SHFT), + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_HIF_2_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_HIF_2_EMPTY_SHFT), + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_HIF_3_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_HIF_3_EMPTY_SHFT), + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_HIF_4_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_HIF_4_EMPTY_SHFT), + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_HIF_5_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_HIF_5_EMPTY_SHFT)); + DBGLOG(HAL, INFO, "\t\tLMAC TX Q empty=%d\n", + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_LMAC_TX_QUEUE_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_LMAC_TX_QUEUE_EMPTY_SHFT)); + DBGLOG(HAL, INFO, "\t\tMDP TX Q/RX Q empty=%d/%d\n", + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_MDP_TX_QUEUE_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_MDP_TX_QUEUE_EMPTY_SHFT), + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_MDP_RX_QUEUE_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_MDP_RX_QUEUE_EMPTY_SHFT)); + DBGLOG(HAL, INFO, "\t\tSEC TX Q/RX Q empty=%d/%d\n", + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_SEC_TX_QUEUE_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_SEC_TX_QUEUE_EMPTY_SHFT), + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_SEC_RX_QUEUE_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_SEC_RX_QUEUE_EMPTY_SHFT)); + DBGLOG(HAL, INFO, "\t\tSFD PARK Q empty=%d\n", + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_SFD_PARK_QUEUE_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_SFD_PARK_QUEUE_EMPTY_SHFT)); + DBGLOG(HAL, INFO, "\t\tMDP TXIOC Q/RXIOC Q empty=%d/%d\n", + ((pse_stat & + WF_PSE_TOP_QUEUE_EMPTY_MDP_TXIOC_QUEUE_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_MDP_TXIOC_QUEUE_EMPTY_SHFT), + ((pse_stat & + WF_PSE_TOP_QUEUE_EMPTY_MDP_RXIOC_QUEUE_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_MDP_RXIOC_QUEUE_EMPTY_SHFT)); + DBGLOG(HAL, INFO, "\t\tRLS Q empty=%d\n", + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_RLS_Q_EMTPY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_RLS_Q_EMTPY_SHFT)); + DBGLOG(HAL, INFO, "Nonempty Q info:\n"); + + for (i = 0; i < 31; i++) { + if (((pse_stat & (0x1 << i)) >> i) == 0) { + uint32_t hfid, tfid, pktcnt, fl_que_ctrl[3] = {0}; + + if (pse_queue_empty_info[i].QueueName != NULL) { + DBGLOG(HAL, INFO, "\t%s: ", + pse_queue_empty_info[i].QueueName); + fl_que_ctrl[0] |= + WF_PSE_TOP_FL_QUE_CTRL_0_EXECUTE_MASK; + fl_que_ctrl[0] |= + (pse_queue_empty_info[i].Portid + << WF_PSE_TOP_FL_QUE_CTRL_0_Q_BUF_PID_SHFT); + fl_que_ctrl[0] |= + (pse_queue_empty_info[i].Queueid + << WF_PSE_TOP_FL_QUE_CTRL_0_Q_BUF_QID_SHFT); + } else + continue; + + fl_que_ctrl[0] |= (0x1 << 31); + HAL_MCR_WR(prAdapter, WF_PSE_TOP_FL_QUE_CTRL_0_ADDR, + fl_que_ctrl[0]); + HAL_MCR_RD(prAdapter, WF_PSE_TOP_FL_QUE_CTRL_2_ADDR, + &fl_que_ctrl[1]); + HAL_MCR_RD(prAdapter, WF_PSE_TOP_FL_QUE_CTRL_3_ADDR, + &fl_que_ctrl[2]); + hfid = (fl_que_ctrl[1] & + WF_PSE_TOP_FL_QUE_CTRL_2_QUEUE_HEAD_FID_MASK) >> + WF_PSE_TOP_FL_QUE_CTRL_2_QUEUE_HEAD_FID_SHFT; + tfid = (fl_que_ctrl[1] & + WF_PSE_TOP_FL_QUE_CTRL_2_QUEUE_TAIL_FID_MASK) >> + WF_PSE_TOP_FL_QUE_CTRL_2_QUEUE_TAIL_FID_SHFT; + pktcnt = + (fl_que_ctrl[2] & + WF_PSE_TOP_FL_QUE_CTRL_3_QUEUE_PKT_NUM_MASK) >> + WF_PSE_TOP_FL_QUE_CTRL_3_QUEUE_PKT_NUM_SHFT; + DBGLOG(HAL, INFO, + "tail/head fid = 0x%03x/0x%03x, pkt cnt = 0x%03x\n", + tfid, hfid, pktcnt); + } + } +} +#endif /* MT7915 */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/mt7915/mt7915.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/mt7915/mt7915.c new file mode 100644 index 0000000000000000000000000000000000000000..8d907bb8a5ac930c3efecbdd83b0ee959ac33490 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/mt7915/mt7915.c @@ -0,0 +1,602 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/*! \file mt7915.c +* \brief Internal driver stack will export +* the required procedures here for GLUE Layer. +* +* This file contains all routines which are exported + from MediaTek 802.11 Wireless LAN driver stack to GLUE Layer. +*/ + +#ifdef MT7915 + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include "precomp.h" + +#include "mt7915.h" +#include "coda/mt7915/wf_cr_sw_def.h" + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ +#define CONN_MCU_CONFG_BASE 0x88000000 +#define CONN_MCU_CONFG_COM_REG0_ADDR (CONN_MCU_CONFG_BASE + 0x200) + +#define PATCH_SEMAPHORE_COMM_REG 0 +#define PATCH_SEMAPHORE_COMM_REG_PATCH_DONE 1 /* bit0 is for patch. */ +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ +struct ECO_INFO mt7915_eco_table[] = { + /* HW version, ROM version, Factory version */ + {0x00, 0x00, 0xA, 0x1}, /* E1 */ + {0x10, 0x01, 0xA, 0x2}, /* E2 */ + {0x00, 0x00, 0x0} /* End of table */ +}; + +#if defined(_HIF_PCIE) +struct PCIE_CHIP_CR_MAPPING mt7915_bus2chip_cr_mapping[] = { + /* chip addr, bus addr, range */ + {0x54000000, 0x02000, 0x1000}, /* WFDMA PCIE0 MCU DMA0 */ + {0x55000000, 0x03000, 0x1000}, /* WFDMA PCIE0 MCU DMA1 */ + {0x56000000, 0x04000, 0x1000}, /* WFDMA reserved */ + {0x57000000, 0x05000, 0x1000}, /* WFDMA MCU wrap CR */ + {0x58000000, 0x06000, 0x1000}, /* WFDMA PCIE1 MCU DMA0 (MEM_DMA) */ + {0x59000000, 0x07000, 0x1000}, /* WFDMA PCIE1 MCU DMA1 */ + {0x820c0000, 0x08000, 0x4000}, /* WF_UMAC_TOP (PLE) */ + {0x820c8000, 0x0c000, 0x2000}, /* WF_UMAC_TOP (PSE) */ + {0x820cc000, 0x0e000, 0x2000}, /* WF_UMAC_TOP (PP) */ + {0x820e0000, 0x20000, 0x0400}, /* WF_LMAC_TOP BN0 (WF_CFG) */ + {0x820e1000, 0x20400, 0x0200}, /* WF_LMAC_TOP BN0 (WF_TRB) */ + {0x820e2000, 0x20800, 0x0400}, /* WF_LMAC_TOP BN0 (WF_AGG) */ + {0x820e3000, 0x20c00, 0x0400}, /* WF_LMAC_TOP BN0 (WF_ARB) */ + {0x820e4000, 0x21000, 0x0400}, /* WF_LMAC_TOP BN0 (WF_TMAC) */ + {0x820e5000, 0x21400, 0x0800}, /* WF_LMAC_TOP BN0 (WF_RMAC) */ + {0x820ce000, 0x21c00, 0x0200}, /* WF_LMAC_TOP (WF_SEC) */ + {0x820e7000, 0x21e00, 0x0200}, /* WF_LMAC_TOP BN0 (WF_DMA) */ + {0x820cf000, 0x22000, 0x1000}, /* WF_LMAC_TOP (WF_PF) */ + {0x820e9000, 0x23400, 0x0200}, /* WF_LMAC_TOP BN0 (WF_WTBLOFF) */ + {0x820ea000, 0x24000, 0x0200}, /* WF_LMAC_TOP BN0 (WF_ETBF) */ + {0x820eb000, 0x24200, 0x0400}, /* WF_LMAC_TOP BN0 (WF_LPON) */ + {0x820ec000, 0x24600, 0x0200}, /* WF_LMAC_TOP BN0 (WF_INT) */ + {0x820ed000, 0x24800, 0x0800}, /* WF_LMAC_TOP BN0 (WF_MIB) */ + {0x820ca000, 0x26000, 0x2000}, /* WF_LMAC_TOP BN0 (WF_MUCOP) */ + {0x820d0000, 0x30000, 0x10000}, /* WF_LMAC_TOP (WF_WTBLON) */ + {0x40000000, 0x70000, 0x10000}, /* WF_UMAC_SYSRAM */ + {0x00400000, 0x80000, 0x10000}, /* WF_MCU_SYSRAM */ + {0x00410000, 0x90000, 0x10000}, /* WF_MCU_SYSRAM (configure register) */ + {0x820f0000, 0xa0000, 0x0400}, /* WF_LMAC_TOP BN1 (WF_CFG) */ + {0x820f1000, 0xa0600, 0x0200}, /* WF_LMAC_TOP BN1 (WF_TRB) */ + {0x820f2000, 0xa0800, 0x0400}, /* WF_LMAC_TOP BN1 (WF_AGG) */ + {0x820f3000, 0xa0c00, 0x0400}, /* WF_LMAC_TOP BN1 (WF_ARB) */ + {0x820f4000, 0xa1000, 0x0400}, /* WF_LMAC_TOP BN1 (WF_TMAC) */ + {0x820f5000, 0xa1400, 0x0800}, /* WF_LMAC_TOP BN1 (WF_RMAC) */ + {0x820f7000, 0xa1e00, 0x0200}, /* WF_LMAC_TOP BN1 (WF_DMA) */ + {0x820f9000, 0xa3400, 0x0200}, /* WF_LMAC_TOP BN1 (WF_WTBLOFF) */ + {0x820fa000, 0xa4000, 0x0200}, /* WF_LMAC_TOP BN1 (WF_ETBF) */ + {0x820fb000, 0xa4200, 0x0400}, /* WF_LMAC_TOP BN1 (WF_LPON) */ + {0x820fc000, 0xa4600, 0x0200}, /* WF_LMAC_TOP BN1 (WF_INT) */ + {0x820fd000, 0xa4800, 0x0800}, /* WF_LMAC_TOP BN1 (WF_MIB) */ + {0x820cc000, 0xa5000, 0x2000}, /* WF_LMAC_TOP BN1 (WF_MUCOP) */ + {0x820c4000, 0xa8000, 0x4000}, /* WF_LMAC_TOP BN1 (WF_MUCOP) */ + {0x820b0000, 0xae000, 0x1000}, /* [APB2] WFSYS_ON */ + {0x80020000, 0xb0000, 0x10000}, /* WF_TOP_MISC_OFF */ + {0x81020000, 0xc0000, 0x10000}, /* WF_TOP_MISC_ON */ + {0x7c020000, 0xd0000, 0x10000}, /* CONN_INFRA, wfdma */ + {0x7c060000, 0xe0000, 0x10000}, /* CONN_INFRA, conn_host_csr_top */ + {0x7c000000, 0xf0000, 0x10000}, /* CONN_INFRA */ + {0x000f0000, 0xf0000, 0x10000}, + {0x000e0000, 0xe0000, 0x10000}, + {0x0, 0x0, 0x0} +}; +#endif /* _HIF_PCIE */ + +#if defined(_HIF_USB) +uint16_t wlanHarrierUsbRxByteCount( + struct ADAPTER *prAdapter, + struct BUS_INFO *prBusInfo, + uint8_t *pRXD) +{ + uint16_t u2RxByteCount; + uint8_t ucPacketType; + + ucPacketType = HAL_MAC_CONNAC2X_RX_STATUS_GET_PKT_TYPE( + (struct HW_MAC_CONNAC2X_RX_DESC *)pRXD); + u2RxByteCount = HAL_MAC_CONNAC2X_RX_STATUS_GET_RX_BYTE_CNT( + (struct HW_MAC_CONNAC2X_RX_DESC *)pRXD); + + /* According to Barry's rule, it can be summarized as below formula: + * 1. Event packet (including WIFI packet sent by MCU) + -> RX padding for 4B alignment + * 2. WIFI packet from UMAC + * E1: + * case 1. In case byte length = + 128*N-7 ~ 128*N -> RX padding for 4B alignment + * case 2. RX padding for 8B alignment first, + then extra 4B padding + * E2: + * RX padding for 8B alignment + 4B CSO + */ + if (nicIsEcoVerEqualOrLaterTo(prAdapter, ECO_VER_2)) { + if (ucPacketType == RX_PKT_TYPE_RX_DATA) { + u2RxByteCount = ALIGN_8(u2RxByteCount) + + LEN_USB_RX_PADDING_CSO; + } else { + u2RxByteCount = ALIGN_4(u2RxByteCount); + } + } else { + if ((ucPacketType == RX_PKT_TYPE_RX_DATA) && + (u2RxByteCount & BITS(0, 6)) != 0 && + (u2RxByteCount & BITS(0, 6)) < 121) + u2RxByteCount = ALIGN_8(u2RxByteCount) + + LEN_USB_RX_PADDING_CSO; + else { + u2RxByteCount = ALIGN_4(u2RxByteCount); + } + } + + return u2RxByteCount; +} +#endif /* defined(_HIF_USB) */ + +#if defined(_HIF_PCIE) +static void wlanHarrierInitPcieInt( + struct GLUE_INFO *prGlueInfo) +{ + uint32_t u4MacVal; + + /* Backup original setting */ + HAL_MCR_RD(prGlueInfo->prAdapter, + 0xF11AC, + &u4MacVal); + + /* + * To set 0x74030188 = 0x000000FF + * 1. set 0xF11AC = 0x7403 + * 2. set 0xE0188 = 0x000000FF + */ + HAL_MCR_WR(prGlueInfo->prAdapter, + 0xF11AC, + 0x7403); + HAL_MCR_WR(prGlueInfo->prAdapter, + 0xE0188, + 0x000000FF); + + /* Recovery original setting */ + HAL_MCR_WR(prGlueInfo->prAdapter, + 0xF11AC, + u4MacVal); +} + +static bool mt7915WfdmaAllocRxRing( + struct GLUE_INFO *prGlueInfo, + bool fgAllocMem) +{ + if (!halWpdmaAllocRxRing(prGlueInfo, WFDMA0_RX_RING_IDX_2, + RX_RING1_SIZE, RXD_SIZE, RX_BUFFER_AGGRESIZE, + fgAllocMem)) { + DBGLOG(HAL, ERROR, "AllocWfdmaRxRing fail\n"); + return false; + } + if (!halWpdmaAllocRxRing(prGlueInfo, WFDMA0_RX_RING_IDX_3, + RX_RING1_SIZE, RXD_SIZE, RX_BUFFER_AGGRESIZE, + fgAllocMem)) { + DBGLOG(HAL, ERROR, "AllocWfdmaRxRing fail\n"); + return false; + } + if (!halWpdmaAllocRxRing(prGlueInfo, WFDMA1_RX_RING_IDX_0, + RX_RING1_SIZE, RXD_SIZE, RX_BUFFER_AGGRESIZE, + fgAllocMem)) { + DBGLOG(HAL, ERROR, "AllocWfdmaRxRing fail\n"); + return false; + } + if (!halWpdmaAllocRxRing(prGlueInfo, WFDMA1_RX_RING_IDX_1, + RX_RING_SIZE, RXD_SIZE, RX_BUFFER_AGGRESIZE, + fgAllocMem)) { + DBGLOG(HAL, ERROR, "AllocWfdmaRxRing fail\n"); + return false; + } + if (!halWpdmaAllocRxRing(prGlueInfo, WFDMA1_RX_RING_IDX_2, + RX_RING_SIZE, RXD_SIZE, RX_BUFFER_AGGRESIZE, + fgAllocMem)) { + DBGLOG(HAL, ERROR, "AllocWfdmaRxRing fail\n"); + return false; + } + return true; +} + +#endif /* _HIF_PCIE */ + +void mt7915DumpSerDummyCR( + struct ADAPTER *prAdapter) +{ + uint32_t u4MacVal; + + DBGLOG(HAL, INFO, "%s\n", __func__); + + DBGLOG(HAL, INFO, "=====Dump Start====\n"); + + HAL_MCR_RD(prAdapter, WF_SW_DEF_CR_SER_STATUS_ADDR, &u4MacVal); + DBGLOG(HAL, INFO, "SER STATUS[0x%08x]: 0x%08x\n", + WF_SW_DEF_CR_SER_STATUS_ADDR, u4MacVal); + + HAL_MCR_RD(prAdapter, WF_SW_DEF_CR_PLE_STATUS_ADDR, &u4MacVal); + DBGLOG(HAL, INFO, "PLE STATUS[0x%08x]: 0x%08x\n", + WF_SW_DEF_CR_PLE_STATUS_ADDR, u4MacVal); + + HAL_MCR_RD(prAdapter, WF_SW_DEF_CR_PLE1_STATUS_ADDR, &u4MacVal); + DBGLOG(HAL, INFO, "PLE1 STATUS[0x%08x]: 0x%08x\n", + WF_SW_DEF_CR_PLE1_STATUS_ADDR, u4MacVal); + + HAL_MCR_RD(prAdapter, WF_SW_DEF_CR_PLE_AMSDU_STATUS_ADDR, &u4MacVal); + DBGLOG(HAL, INFO, "PLE AMSDU STATUS[0x%08x]: 0x%08x\n", + WF_SW_DEF_CR_PLE_AMSDU_STATUS_ADDR, u4MacVal); + + HAL_MCR_RD(prAdapter, WF_SW_DEF_CR_PSE_STATUS_ADDR, &u4MacVal); + DBGLOG(HAL, INFO, "PSE STATUS[0x%08x]: 0x%08x\n", + WF_SW_DEF_CR_PSE_STATUS_ADDR, u4MacVal); + + HAL_MCR_RD(prAdapter, WF_SW_DEF_CR_PSE1_STATUS_ADDR, &u4MacVal); + DBGLOG(HAL, INFO, "PSE1 STATUS[0x%08x]: 0x%08x\n", + WF_SW_DEF_CR_PSE1_STATUS_ADDR, u4MacVal); + + HAL_MCR_RD(prAdapter, WF_SW_DEF_CR_LAMC_WISR6_BN0_STATUS_ADDR, + &u4MacVal); + DBGLOG(HAL, INFO, "LMAC WISR6 BN0 STATUS[0x%08x]: 0x%08x\n", + WF_SW_DEF_CR_LAMC_WISR6_BN0_STATUS_ADDR, u4MacVal); + + HAL_MCR_RD(prAdapter, WF_SW_DEF_CR_LAMC_WISR6_BN1_STATUS_ADDR, + &u4MacVal); + DBGLOG(HAL, INFO, "LMAC WISR6 BN1 STATUS[0x%08x]: 0x%08x\n", + WF_SW_DEF_CR_LAMC_WISR6_BN1_STATUS_ADDR, u4MacVal); + + HAL_MCR_RD(prAdapter, WF_SW_DEF_CR_LAMC_WISR7_BN0_STATUS_ADDR, + &u4MacVal); + DBGLOG(HAL, INFO, "LMAC WISR7 BN0 STATUS[0x%08x]: 0x%08x\n", + WF_SW_DEF_CR_LAMC_WISR7_BN0_STATUS_ADDR, u4MacVal); + + HAL_MCR_RD(prAdapter, WF_SW_DEF_CR_LAMC_WISR7_BN1_STATUS_ADDR, + &u4MacVal); + DBGLOG(HAL, INFO, "LMAC WISR7 BN1 STATUS[0x%08x]: 0x%08x\n", + WF_SW_DEF_CR_LAMC_WISR7_BN1_STATUS_ADDR, u4MacVal); + + DBGLOG(HAL, INFO, "=====Dump End====\n"); + +} + +/* check capability of chip depends on different ECO version */ +void mt7915CheckAsicCap( + struct ADAPTER *prAdapter) +{ + struct mt66xx_chip_info *prChipInfo = prAdapter->chip_info; + + /* check capability of chip depends on different ECO version */ + if (nicIsEcoVerEqualTo(prAdapter, ECO_VER_1)) { + /* FALCON: DW 18~33 for harrier E1, + * DW 18~35 for harrier E2 of Group5. + */ + prChipInfo->group5_size = + sizeof(struct HW_MAC_RX_STS_HARRIER_E1_GROUP_5); + + /* MT7915U E1 cannot support CS0 RX. */ + prAdapter->u4CSUMFlags = CSUM_OFFLOAD_EN_TX_MASK; + } +} + +#if defined(_HIF_USB) +void mt7915Connac2xWfdmaInitForUSB( + struct ADAPTER *prAdapter, + struct mt66xx_chip_info *prChipInfo) +{ + uint32_t u4WfdmaCr; + + /* 7915U E1 Workaround. TODO: check chip version */ + /* Driver need to write rx ring cpu index for receiving data */ + HAL_MCR_WR(prAdapter, + CONNAC2X_RX_RING_CIDX(CONNAC2X_HOST_WPDMA_0_BASE), 0x1); + + /* enable RX CSO option bit for E2 RX padding, only work after E2 */ + HAL_MCR_RD(prAdapter, + CONNAC2X_WFDMA_HOST_CONFIG_ADDR, &u4WfdmaCr); + u4WfdmaCr |= CONNAC2X_WFDMA_RX_CSO_OPTION; + HAL_MCR_WR(prAdapter, + CONNAC2X_WFDMA_HOST_CONFIG_ADDR, u4WfdmaCr); +} +#endif + +struct BUS_INFO mt7915_bus_info = { +#if defined(_HIF_PCIE) + .top_cfg_base = MT7915_TOP_CFG_BASE, + /* host_dma0 for TXP */ + .host_dma0_base = CONNAC2X_HOST_WPDMA_0_BASE, + /* host_dma1 for TXD and host cmd to WX_CPU */ + .host_dma1_base = CONNAC2X_HOST_WPDMA_1_BASE, + .host_ext_conn_hif_wrap_base = CONNAC2X_HOST_EXT_CONN_HIF_WRAP, + .host_int_status_addr = + CONNAC2X_WPDMA_EXT_INT_STA(CONNAC2X_HOST_EXT_CONN_HIF_WRAP), + .host_int_txdone_bits = (CONNAC2X_EXT_WFDMA1_TX_DONE_INT0 + | CONNAC2X_EXT_WFDMA1_TX_DONE_INT1 + | CONNAC2X_EXT_WFDMA1_TX_DONE_INT2 + | CONNAC2X_EXT_WFDMA1_TX_DONE_INT16 + | CONNAC2X_EXT_WFDMA1_TX_DONE_INT17 + | CONNAC2X_EXT_WFDMA1_TX_DONE_INT18 + | CONNAC2X_EXT_WFDMA1_TX_DONE_INT19 + | CONNAC2X_EXT_WFDMA1_TX_DONE_INT20), + .host_int_rxdone_bits = (CONNAC2X_EXT_WFDMA1_RX_DONE_INT0 + | CONNAC2X_EXT_WFDMA1_RX_DONE_INT1 + | CONNAC2X_EXT_WFDMA1_RX_DONE_INT2 + | CONNAC2X_EXT_WFDMA0_RX_DONE_INT0 + | CONNAC2X_EXT_WFDMA0_RX_DONE_INT1 + ), + .host_tx_ring_base = + CONNAC2X_TX_RING_BASE(CONNAC2X_HOST_WPDMA_1_BASE), + .host_tx_ring_ext_ctrl_base = + CONNAC2X_TX_RING_EXT_CTRL_BASE(CONNAC2X_HOST_WPDMA_1_BASE), + .host_tx_ring_cidx_addr = + CONNAC2X_TX_RING_CIDX(CONNAC2X_HOST_WPDMA_1_BASE), + .host_tx_ring_didx_addr = + CONNAC2X_TX_RING_DIDX(CONNAC2X_HOST_WPDMA_1_BASE), + .host_tx_ring_cnt_addr = + CONNAC2X_TX_RING_CNT(CONNAC2X_HOST_WPDMA_1_BASE), + + .host_rx_ring_base = + CONNAC2X_RX_RING_BASE(CONNAC2X_HOST_WPDMA_0_BASE), + .host_rx_ring_ext_ctrl_base = + CONNAC2X_RX_RING_EXT_CTRL_BASE(CONNAC2X_HOST_WPDMA_0_BASE), + .host_rx_ring_cidx_addr = + CONNAC2X_RX_RING_CIDX(CONNAC2X_HOST_WPDMA_0_BASE), + .host_rx_ring_didx_addr = + CONNAC2X_RX_RING_DIDX(CONNAC2X_HOST_WPDMA_0_BASE), + .host_rx_ring_cnt_addr = + CONNAC2X_RX_RING_CNT(CONNAC2X_HOST_WPDMA_0_BASE), + + .host_wfdma1_rx_ring_base = + CONNAC2X_WFDMA1_RX_RING_BASE(CONNAC2X_HOST_WPDMA_1_BASE), + .host_wfdma1_rx_ring_cidx_addr = + CONNAC2X_WFDMA1_RX_RING_CIDX(CONNAC2X_HOST_WPDMA_1_BASE), + .host_wfdma1_rx_ring_didx_addr = + CONNAC2X_WFDMA1_RX_RING_DIDX(CONNAC2X_HOST_WPDMA_1_BASE), + .host_wfdma1_rx_ring_cnt_addr = + CONNAC2X_WFDMA1_RX_RING_CNT(CONNAC2X_HOST_WPDMA_1_BASE), + .host_wfdma1_rx_ring_ext_ctrl_base = + CONNAC2X_WFDMA1_RX_RING_EXT_CTRL_BASE( + CONNAC2X_HOST_WPDMA_1_BASE), + + .bus2chip = mt7915_bus2chip_cr_mapping, + .max_static_map_addr = 0x000f0000, + .tx_ring_fwdl_idx = CONNAC2X_FWDL_TX_RING_IDX, + .tx_ring_cmd_idx = CONNAC2X_CMD_TX_RING_IDX, + .tx_ring_wa_cmd_idx = CONNAC2X_CMD_TX_WA_RING_IDX, + .tx_ring0_data_idx = CONNAC2X_DATA0_TXD_IDX, + .tx_ring1_data_idx = CONNAC2X_DATA1_TXD_IDX, + .fw_own_clear_addr = CONNAC2X_BN0_IRQ_STAT_ADDR, + .fw_own_clear_bit = PCIE_LPCR_FW_CLR_OWN, + + .fgCheckDriverOwnInt = FALSE, + .u4DmaMask = 32, + + .pdmaSetup = asicConnac2xWpdmaConfig, + .enableInterrupt = asicConnac2xEnableExtInterrupt, + .disableInterrupt = asicConnac2xDisableExtInterrupt, + .processTxInterrupt = asicConnac2xProcessTxInterrupt, + .tx_ring_ext_ctrl = asicConnac2xWfdmaTxRingExtCtrl, + .rx_ring_ext_ctrl = asicConnac2xWfdmaRxRingExtCtrl, + /* null wfdmaManualPrefetch if want to disable manual mode */ + .wfdmaManualPrefetch = asicConnac2xWfdmaManualPrefetch, + .lowPowerOwnRead = asicConnac2xLowPowerOwnRead, + .lowPowerOwnSet = asicConnac2xLowPowerOwnSet, + .lowPowerOwnClear = asicConnac2xLowPowerOwnClear, + .wakeUpWiFi = asicWakeUpWiFi, + .processSoftwareInterrupt = asicConnac2xProcessSoftwareInterrupt, + .softwareInterruptMcu = asicConnac2xSoftwareInterruptMcu, + .hifRst = asicConnac2xHifRst, + .processRxInterrupt = asicConnac2xProcessRxInterrupt, + .initPcieInt = wlanHarrierInitPcieInt, + .devReadIntStatus = asicConnac2xReadExtIntStatus, + .DmaShdlInit = NULL, + .wfdmaAllocRxRing = mt7915WfdmaAllocRxRing, +#endif /* _HIF_PCIE */ +#if defined(_HIF_USB) + .u4UdmaWlCfg_0_Addr = CONNAC2X_UDMA_WLCFG_0, + .u4UdmaWlCfg_1_Addr = CONNAC2X_UDMA_WLCFG_1, + .u4UdmaTxQsel = CONNAC2X_UDMA_TX_QSEL, + .u4device_vender_request_in = DEVICE_VENDOR_REQUEST_IN_CONNAC2, + .u4device_vender_request_out = DEVICE_VENDOR_REQUEST_OUT_CONNAC2, + .u4usb_tx_cmd_queue_mask = USB_TX_CMD_QUEUE_MASK, + .u4UdmaWlCfg_0 = + (CONNAC2X_UDMA_WLCFG_0_WL_TX_EN(1) | + CONNAC2X_UDMA_WLCFG_0_WL_RX_EN(1) | + CONNAC2X_UDMA_WLCFG_0_WL_RX_MPSZ_PAD0(1) | + CONNAC2X_UDMA_WLCFG_0_TICK_1US_EN(1)), + .u4UdmaTxTimeout = CONNAC2X_UDMA_TX_TIMEOUT_LIMIT, + .u4SuspendVer = SUSPEND_V2, + .asicUsbSuspend = NULL, /*asicUsbSuspend*/ + .asicUsbResume = asicConnac2xUsbResume, + .asicUsbEventEpDetected = asicConnac2xUsbEventEpDetected, + .asicUsbRxByteCount = wlanHarrierUsbRxByteCount, + .DmaShdlInit = NULL, +#endif /* _HIF_USB */ +#if defined(_HIF_SDIO) + .halTxGetFreeResource = halTxGetFreeResource_v1, + .halTxReturnFreeResource = halTxReturnFreeResource_v1, + .halRestoreTxResource = halRestoreTxResource_v1, + .halUpdateTxDonePendingCount = halUpdateTxDonePendingCount_v1, +#endif /* _HIF_SDIO */ +}; + +#if CFG_ENABLE_FW_DOWNLOAD +struct FWDL_OPS_T mt7915_fw_dl_ops = { + .constructFirmwarePrio = NULL, + .downloadPatch = wlanDownloadPatch, + .downloadFirmware = wlanConnacFormatDownload, + .downloadByDynMemMap = NULL, + .getFwInfo = wlanGetConnacFwInfo, + .getFwDlInfo = asicGetFwDlInfo, + .phyAction = NULL, +}; +#endif /* CFG_ENABLE_FW_DOWNLOAD */ + +struct TX_DESC_OPS_T mt7915TxDescOps = { + .fillNicAppend = fillConnac2xTxDescAppendWithWaCpu, + .fillHifAppend = fillConnac2xTxDescAppendByWaCpu, + .fillTxByteCount = fillTxDescTxByteCountWithWaCpu, +}; + +struct RX_DESC_OPS_T mt7915RxDescOps = { +}; + + +struct CHIP_DBG_OPS mt7915_debug_ops = { + .showPdmaInfo = NULL, + .showPseInfo = mt7915_show_pse_info, + .showPleInfo = mt7915_show_ple_info, + .showTxdInfo = connac2x_show_txd_Info, + .showWtblInfo = connac2x_show_wtbl_info, + .showUmacFwtblInfo = connac2x_show_umac_wtbl_info, + .showCsrInfo = NULL, + .showDmaschInfo = NULL, + .dumpMacInfo = NULL, + .showHifInfo = NULL, + .printHifDbgInfo = NULL, + .show_rx_rate_info = connac2x_show_rx_rate_info, + .show_rx_rssi_info = connac2x_show_rx_rssi_info, + .show_stat_info = connac2x_show_stat_info, +#ifdef CFG_SUPPORT_LINK_QUALITY_MONITOR + .get_rx_rate_info = connac2x_get_rx_rate_info +#endif +}; + +/* Litien code refine to support multi chip */ +struct mt66xx_chip_info mt66xx_chip_info_mt7915 = { + .bus_info = &mt7915_bus_info, +#if CFG_ENABLE_FW_DOWNLOAD + .fw_dl_ops = &mt7915_fw_dl_ops, +#endif /* CFG_ENABLE_FW_DOWNLOAD */ + .prDebugOps = &mt7915_debug_ops, + .prTxDescOps = &mt7915TxDescOps, + .prRxDescOps = &mt7915RxDescOps, + .chip_id = MT7915_CHIP_ID, + .should_verify_chip_id = FALSE, + .sw_sync0 = MT7915_SW_SYNC0, + .sw_ready_bits = WIFI_FUNC_READY_BITS, + .sw_ready_bit_offset = MT7915_SW_SYNC0_RDY_OFFSET, + .patch_addr = MT7915_PATCH_START_ADDR, + .is_support_cr4 = FALSE, + .is_support_wacpu = TRUE, + .txd_append_size = MT7915_TX_DESC_APPEND_LENGTH, + .rxd_size = MT7915_RX_DESC_LENGTH, + .init_evt_rxd_size = MT7915_RX_DESC_LENGTH, + .pse_header_length = CONNAC2X_NIC_TX_PSE_HEADER_LENGTH, + .init_event_size = CONNAC2X_RX_INIT_EVENT_LENGTH, + .eco_info = mt7915_eco_table, + .isNicCapV1 = FALSE, + .top_hcr = CONNAC2X_TOP_HCR, + .top_hvr = CONNAC2X_TOP_HVR, + .top_fvr = CONNAC2X_TOP_FVR, + .arb_ac_mode_addr = MT7915_ARB_AC_MODE_ADDR, + .asicCapInit = asicConnac2xCapInit, +#if defined(_HIF_USB) + .asicUsbInit = asicConnac2xWfdmaInitForUSB, + .asicUsbInit_ic_specific = mt7915Connac2xWfdmaInitForUSB, + .u4SerUsbMcuEventAddr = WF_SW_DEF_CR_USB_MCU_EVENT_ADD, + .u4SerUsbHostAckAddr = WF_SW_DEF_CR_USB_HOST_ACK_ADDR, +#endif + .asicDumpSerDummyCR = mt7915DumpSerDummyCR, +#if CFG_ENABLE_FW_DOWNLOAD + .asicEnableFWDownload = NULL, +#endif /* CFG_ENABLE_FW_DOWNLOAD */ + .asicGetChipID = NULL, + .downloadBufferBin = wlanConnacDownloadBufferBin, + .is_support_hw_amsdu = TRUE, + .is_support_asic_lp = TRUE, + .is_support_wfdma1 = TRUE, + .asicWfdmaReInit = asicConnac2xWfdmaReInit, + .asicWfdmaReInit_handshakeInit = asicConnac2xWfdmaDummyCrWrite, + .group5_size = sizeof(struct HW_MAC_RX_STS_GROUP_5), + .wlanCheckAsicCap = mt7915CheckAsicCap, + .u4LmacWtblDUAddr = CONNAC2X_WIFI_LWTBL_BASE, + .u4UmacWtblDUAddr = CONNAC2X_WIFI_UWTBL_BASE, + .cmd_max_pkt_size = CFG_TX_MAX_PKT_SIZE, /* size 1600 */ +}; + +struct mt66xx_hif_driver_data mt66xx_driver_data_mt7915 = { + .chip_info = &mt66xx_chip_info_mt7915, +}; + +#endif /* MT7915 */ + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/mt7961/dbg_mt7961.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/mt7961/dbg_mt7961.c new file mode 100644 index 0000000000000000000000000000000000000000..5864507cfa1d430468c2daa9353c3329bc2cb920 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/mt7961/dbg_mt7961.c @@ -0,0 +1,833 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/****************************************************************************** + *[File] dbg_mt7961.c + *[Version] v1.0 + *[Revision Date] 2019-04-09 + *[Author] + *[Description] + * The program provides WIFI FALCON MAC Debug APIs + *[Copyright] + * Copyright (C) 2015 MediaTek Incorporation. All Rights Reserved. + ******************************************************************************/ + +#ifdef MT7961 +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "coda/mt7961/wf_ple_top.h" +#include "coda/mt7961/wf_pse_top.h" +#include "precomp.h" +#include "mt_dmac.h" +#include "wf_ple.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +struct pse_group_info { + char name[8]; + u_int32_t quota_addr; + u_int32_t pg_info_addr; +}; + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +static struct EMPTY_QUEUE_INFO ple_queue_empty_info[] = { + {"CPU Q0", MCU_Q0_INDEX, ENUM_UMAC_CTX_Q_0}, + {"CPU Q1", ENUM_UMAC_CPU_PORT_1, ENUM_UMAC_CTX_Q_1}, + {"CPU Q2", ENUM_UMAC_CPU_PORT_1, ENUM_UMAC_CTX_Q_2}, + {"CPU Q3", ENUM_UMAC_CPU_PORT_1, ENUM_UMAC_CTX_Q_3}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, /* 4~7 not defined */ + {"ALTX Q0", ENUM_UMAC_LMAC_PORT_2, + ENUM_UMAC_LMAC_PLE_TX_Q_ALTX_0}, /* Q16 */ + {"BMC Q0", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_BMC_0}, + {"BCN Q0", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_BNC_0}, + {"PSMP Q0", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_PSMP_0}, + {"ALTX Q1", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_ALTX_1}, + {"BMC Q1", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_BMC_1}, + {"BCN Q1", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_BNC_1}, + {"PSMP Q1", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_PSMP_1}, + {"NAF Q", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_NAF}, + {"NBCN Q", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_NBCN}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, /* 18~29 not defined */ + {"RLS Q", ENUM_PLE_CTRL_PSE_PORT_3, ENUM_UMAC_PLE_CTRL_P3_Q_0X1E}, + {"RLS2 Q", ENUM_PLE_CTRL_PSE_PORT_3, ENUM_UMAC_PLE_CTRL_P3_Q_0X1F} }; + +static struct EMPTY_QUEUE_INFO pse_queue_empty_info[] = { + {"CPU Q0", ENUM_UMAC_CPU_PORT_1, ENUM_UMAC_CTX_Q_0}, + {"CPU Q1", ENUM_UMAC_CPU_PORT_1, ENUM_UMAC_CTX_Q_1}, + {"CPU Q2", ENUM_UMAC_CPU_PORT_1, ENUM_UMAC_CTX_Q_2}, + {"CPU Q3", ENUM_UMAC_CPU_PORT_1, ENUM_UMAC_CTX_Q_3}, + {"HIF Q8", ENUM_UMAC_HIF_PORT_0, 8}, + {"HIF Q9", ENUM_UMAC_HIF_PORT_0, 9}, + {"HIF Q10", ENUM_UMAC_HIF_PORT_0, 10}, + {"HIF Q11", ENUM_UMAC_HIF_PORT_0, 11}, + {"HIF Q0", ENUM_UMAC_HIF_PORT_0, 0}, /*bit 8*/ + {"HIF Q1", ENUM_UMAC_HIF_PORT_0, 1}, + {"HIF Q2", ENUM_UMAC_HIF_PORT_0, 2}, + {"HIF Q3", ENUM_UMAC_HIF_PORT_0, 3}, + {"HIF Q4", ENUM_UMAC_HIF_PORT_0, 4}, + {"HIF Q5", ENUM_UMAC_HIF_PORT_0, 5}, + {"HIF Q6", ENUM_UMAC_HIF_PORT_0, 6}, + {"HIF Q7", ENUM_UMAC_HIF_PORT_0, 7}, + {"LMAC Q", ENUM_UMAC_LMAC_PORT_2, 0}, /*bit 16*/ + {"MDP TX Q", ENUM_UMAC_LMAC_PORT_2, 1}, + {"MDP RX Q", ENUM_UMAC_LMAC_PORT_2, 2}, + {"SEC TX Q", ENUM_UMAC_LMAC_PORT_2, 3}, + {"SEC RX Q", ENUM_UMAC_LMAC_PORT_2, 4}, + {"SFD_PARK Q", ENUM_UMAC_LMAC_PORT_2, 5}, + {"MDP_TXIOC Q", ENUM_UMAC_LMAC_PORT_2, 6}, + {"MDP_RXIOC Q", ENUM_UMAC_LMAC_PORT_2, 7}, + {"MDP_TX1 Q", ENUM_UMAC_LMAC_PORT_2, 17}, /*bit 24*/ + {"SEC_TX1 Q", ENUM_UMAC_LMAC_PORT_2, 19}, + {"MDP_TXIOC1 Q", ENUM_UMAC_LMAC_PORT_2, 22}, + {"MDP_RXIOC1 Q", ENUM_UMAC_LMAC_PORT_2, 23}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, /* 28~30 not defined */ + {"RLS Q", ENUM_PLE_CTRL_PSE_PORT_3, ENUM_UMAC_PLE_CTRL_P3_Q_0X1F} }; + +static u_int8_t *sta_ctrl_reg[] = {"ENABLE", "DISABLE", "PAUSE"}; + +#if 0 +static struct EMPTY_QUEUE_INFO ple_txcmd_queue_empty_info[] = { + {"AC00Q", ENUM_UMAC_LMAC_PORT_2, 0x40}, + {"AC01Q", ENUM_UMAC_LMAC_PORT_2, 0x41}, + {"AC02Q", ENUM_UMAC_LMAC_PORT_2, 0x42}, + {"AC03Q", ENUM_UMAC_LMAC_PORT_2, 0x43}, + {"AC10Q", ENUM_UMAC_LMAC_PORT_2, 0x44}, + {"AC11Q", ENUM_UMAC_LMAC_PORT_2, 0x45}, + {"AC12Q", ENUM_UMAC_LMAC_PORT_2, 0x46}, + {"AC13Q", ENUM_UMAC_LMAC_PORT_2, 0x47}, + {"AC20Q", ENUM_UMAC_LMAC_PORT_2, 0x48}, + {"AC21Q", ENUM_UMAC_LMAC_PORT_2, 0x49}, + {"AC22Q", ENUM_UMAC_LMAC_PORT_2, 0x4a}, + {"AC23Q", ENUM_UMAC_LMAC_PORT_2, 0x4b}, + {"AC30Q", ENUM_UMAC_LMAC_PORT_2, 0x4c}, + {"AC31Q", ENUM_UMAC_LMAC_PORT_2, 0x4d}, + {"AC32Q", ENUM_UMAC_LMAC_PORT_2, 0x4e}, + {"AC33Q", ENUM_UMAC_LMAC_PORT_2, 0x4f}, + {"ALTX Q0", ENUM_UMAC_LMAC_PORT_2, 0x50}, + {"TF Q0", ENUM_UMAC_LMAC_PORT_2, 0x51}, + {"TWT TSF-TF Q0", ENUM_UMAC_LMAC_PORT_2, 0x52}, + {"TWT DL Q0", ENUM_UMAC_LMAC_PORT_2, 0x53}, + {"TWT UL Q0", ENUM_UMAC_LMAC_PORT_2, 0x54}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0} }; +#endif + + + +struct pse_group_info pse_group[] = { + {"HIF0", WF_PSE_TOP_PG_HIF0_GROUP_ADDR, WF_PSE_TOP_HIF0_PG_INFO_ADDR}, + {"HIF1", WF_PSE_TOP_PG_HIF1_GROUP_ADDR, WF_PSE_TOP_HIF1_PG_INFO_ADDR}, + {"HIF2", WF_PSE_TOP_PG_HIF2_GROUP_ADDR, WF_PSE_TOP_HIF2_PG_INFO_ADDR}, + {"CPU", WF_PSE_TOP_PG_CPU_GROUP_ADDR, WF_PSE_TOP_CPU_PG_INFO_ADDR}, + {"PLE", WF_PSE_TOP_PG_PLE_GROUP_ADDR, WF_PSE_TOP_PLE_PG_INFO_ADDR}, + {"PLE1", WF_PSE_TOP_PG_PLE1_GROUP_ADDR, WF_PSE_TOP_PLE1_PG_INFO_ADDR}, + {"LMAC0", WF_PSE_TOP_PG_LMAC0_GROUP_ADDR, + WF_PSE_TOP_LMAC0_PG_INFO_ADDR}, + {"LMAC1", WF_PSE_TOP_PG_LMAC1_GROUP_ADDR, + WF_PSE_TOP_LMAC1_PG_INFO_ADDR}, + {"LMAC2", WF_PSE_TOP_PG_LMAC2_GROUP_ADDR, + WF_PSE_TOP_LMAC2_PG_INFO_ADDR}, + {"LMAC3", WF_PSE_TOP_PG_LMAC3_GROUP_ADDR, + WF_PSE_TOP_LMAC3_PG_INFO_ADDR}, + {"MDP", WF_PSE_TOP_PG_MDP_GROUP_ADDR, WF_PSE_TOP_MDP_PG_INFO_ADDR}, + {"MDP1", WF_PSE_TOP_PG_MDP1_GROUP_ADDR, WF_PSE_TOP_MDP1_PG_INFO_ADDR}, + {"MDP2", WF_PSE_TOP_PG_MDP2_GROUP_ADDR, WF_PSE_TOP_MDP2_PG_INFO_ADDR}, +}; + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +void mt7961_show_ple_info( + struct ADAPTER *prAdapter, + u_int8_t fgDumpTxd) +{ + u_int32_t ple_buf_ctrl, pg_sz, pg_num; + u_int32_t ple_stat[25] = {0}, pg_flow_ctrl[8] = {0}; + u_int32_t sta_pause[6] = {0}, dis_sta_map[6] = {0}; + u_int32_t fpg_cnt, ffa_cnt, fpg_head, fpg_tail, hif_max_q, hif_min_q; + u_int32_t rpg_hif, upg_hif, cpu_max_q, cpu_min_q, rpg_cpu, upg_cpu; + u_int32_t i, j; +#if 0 + u_int32_t ple_txcmd_stat; +#endif + + HAL_MCR_RD(prAdapter, WF_PLE_TOP_PBUF_CTRL_ADDR, &ple_buf_ctrl); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_QUEUE_EMPTY_ADDR, &ple_stat[0]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC0_QUEUE_EMPTY0_ADDR, &ple_stat[1]); +#if 0 + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC0_QUEUE_EMPTY1_ADDR, &ple_stat[2]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC0_QUEUE_EMPTY2_ADDR, &ple_stat[3]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC0_QUEUE_EMPTY3_ADDR, &ple_stat[4]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC0_QUEUE_EMPTY4_ADDR, &ple_stat[5]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC0_QUEUE_EMPTY5_ADDR, &ple_stat[6]); +#endif + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC1_QUEUE_EMPTY0_ADDR, &ple_stat[7]); +#if 0 + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC1_QUEUE_EMPTY1_ADDR, &ple_stat[8]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC1_QUEUE_EMPTY2_ADDR, &ple_stat[9]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC1_QUEUE_EMPTY3_ADDR, &ple_stat[10]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC1_QUEUE_EMPTY4_ADDR, &ple_stat[11]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC1_QUEUE_EMPTY5_ADDR, &ple_stat[12]); +#endif + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC2_QUEUE_EMPTY0_ADDR, &ple_stat[13]); +#if 0 + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC2_QUEUE_EMPTY1_ADDR, &ple_stat[14]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC2_QUEUE_EMPTY2_ADDR, &ple_stat[15]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC2_QUEUE_EMPTY3_ADDR, &ple_stat[16]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC2_QUEUE_EMPTY4_ADDR, &ple_stat[17]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC2_QUEUE_EMPTY5_ADDR, &ple_stat[18]); +#endif + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC3_QUEUE_EMPTY0_ADDR, &ple_stat[19]); +#if 0 + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC3_QUEUE_EMPTY1_ADDR, &ple_stat[20]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC3_QUEUE_EMPTY2_ADDR, &ple_stat[21]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC3_QUEUE_EMPTY3_ADDR, &ple_stat[22]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC3_QUEUE_EMPTY4_ADDR, &ple_stat[23]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC3_QUEUE_EMPTY5_ADDR, &ple_stat[24]); +#endif +#if 0 + HAL_MCR_RD(prAdapter, WF_PLE_TOP_TXCMD_QUEUE_EMPTY_ADDR, + &ple_txcmd_stat); +#endif + HAL_MCR_RD(prAdapter, WF_PLE_TOP_FREEPG_CNT_ADDR, &pg_flow_ctrl[0]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_FREEPG_HEAD_TAIL_ADDR, + &pg_flow_ctrl[1]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_PG_HIF_GROUP_ADDR, &pg_flow_ctrl[2]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_HIF_PG_INFO_ADDR, &pg_flow_ctrl[3]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_PG_CPU_GROUP_ADDR, &pg_flow_ctrl[4]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_CPU_PG_INFO_ADDR, &pg_flow_ctrl[5]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_PG_HIF_TXCMD_GROUP_ADDR, + &pg_flow_ctrl[6]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_HIF_TXCMD_PG_INFO_ADDR, + &pg_flow_ctrl[7]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_DIS_STA_MAP0_ADDR, &dis_sta_map[0]); +#if 0 + HAL_MCR_RD(prAdapter, WF_PLE_TOP_DIS_STA_MAP1_ADDR, &dis_sta_map[1]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_DIS_STA_MAP2_ADDR, &dis_sta_map[2]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_DIS_STA_MAP3_ADDR, &dis_sta_map[3]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_DIS_STA_MAP4_ADDR, &dis_sta_map[4]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_DIS_STA_MAP5_ADDR, &dis_sta_map[5]); +#endif + HAL_MCR_RD(prAdapter, WF_PLE_TOP_STATION_PAUSE0_ADDR, &sta_pause[0]); +#if 0 + HAL_MCR_RD(prAdapter, WF_PLE_TOP_STATION_PAUSE1_ADDR, &sta_pause[1]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_STATION_PAUSE2_ADDR, &sta_pause[2]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_STATION_PAUSE3_ADDR, &sta_pause[3]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_STATION_PAUSE4_ADDR, &sta_pause[4]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_STATION_PAUSE5_ADDR, &sta_pause[5]); +#endif + /* Configuration Info */ + DBGLOG(HAL, INFO, "PLE Configuration Info:\n"); + + DBGLOG(HAL, INFO, "\tPacket Buffer Control(0x%08x): 0x%08x\n", + WF_PLE_TOP_PBUF_CTRL_ADDR, + ple_buf_ctrl); + pg_sz = (ple_buf_ctrl & WF_PLE_TOP_PBUF_CTRL_PAGE_SIZE_CFG_MASK) >> + WF_PLE_TOP_PBUF_CTRL_PAGE_SIZE_CFG_SHFT; + DBGLOG(HAL, INFO, "\t\tPage Size=%d(%d bytes per page)\n", pg_sz, + (pg_sz == 1 ? 128 : 64)); + DBGLOG(HAL, INFO, "\t\tPage Offset=%d(in unit of 2KB)\n", + (ple_buf_ctrl & WF_PLE_TOP_PBUF_CTRL_PBUF_OFFSET_MASK) >> + WF_PLE_TOP_PBUF_CTRL_PBUF_OFFSET_SHFT); + pg_num = (ple_buf_ctrl & WF_PLE_TOP_PBUF_CTRL_TOTAL_PAGE_NUM_MASK) >> + WF_PLE_TOP_PBUF_CTRL_TOTAL_PAGE_NUM_SHFT; + DBGLOG(HAL, INFO, "\t\tTotal Page=%d pages\n", pg_num); + + /* Page Flow Control */ + DBGLOG(HAL, INFO, "PLE Page Flow Control:\n"); + DBGLOG(HAL, INFO, "\tFree page counter(0x%08x): 0x%08x\n", + WF_PLE_TOP_FREEPG_CNT_ADDR, + pg_flow_ctrl[0]); + fpg_cnt = (pg_flow_ctrl[0] & WF_PLE_TOP_FREEPG_CNT_FREEPG_CNT_MASK) >> + WF_PLE_TOP_FREEPG_CNT_FREEPG_CNT_SHFT; + DBGLOG(HAL, INFO, "\t\tThe toal page number of free=0x%03x\n", fpg_cnt); + ffa_cnt = (pg_flow_ctrl[0] & WF_PLE_TOP_FREEPG_CNT_FFA_CNT_MASK) >> + WF_PLE_TOP_FREEPG_CNT_FFA_CNT_SHFT; + DBGLOG(HAL, INFO, "\t\tThe free page numbers of free for all=0x%03x\n", + ffa_cnt); + DBGLOG(HAL, INFO, "\tFree page head and tail(0x%08x): 0x%08x\n", + WF_PLE_TOP_FREEPG_HEAD_TAIL_ADDR, + pg_flow_ctrl[1]); + fpg_head = (pg_flow_ctrl[1] & + WF_PLE_TOP_FREEPG_HEAD_TAIL_FREEPG_HEAD_MASK) >> + WF_PLE_TOP_FREEPG_HEAD_TAIL_FREEPG_HEAD_SHFT; + fpg_tail = (pg_flow_ctrl[1] & + WF_PLE_TOP_FREEPG_HEAD_TAIL_FREEPG_TAIL_MASK) >> + WF_PLE_TOP_FREEPG_HEAD_TAIL_FREEPG_TAIL_SHFT; + DBGLOG(HAL, INFO, + "\t\tThe tail/head page of free page list=0x%03x/0x%03x\n", + fpg_tail, fpg_head); + DBGLOG(HAL, INFO, + "\tReserved page counter of HIF group(0x%08x): 0x%08x\n", + WF_PLE_TOP_PG_HIF_GROUP_ADDR, + pg_flow_ctrl[2]); + DBGLOG(HAL, INFO, "\tHIF group page status(0x%08x): 0x%08x\n", + WF_PLE_TOP_HIF_PG_INFO_ADDR, + pg_flow_ctrl[3]); + hif_min_q = (pg_flow_ctrl[2] & + WF_PLE_TOP_PG_HIF_GROUP_HIF_MIN_QUOTA_MASK) >> + WF_PLE_TOP_PG_HIF_GROUP_HIF_MIN_QUOTA_SHFT; + hif_max_q = (pg_flow_ctrl[2] & + WF_PLE_TOP_PG_HIF_GROUP_HIF_MAX_QUOTA_MASK) >> + WF_PLE_TOP_PG_HIF_GROUP_HIF_MAX_QUOTA_SHFT; + DBGLOG(HAL, INFO, + "\t\tThe max/min quota pages of HIF group=0x%03x/0x%03x\n", + hif_max_q, hif_min_q); + rpg_hif = (pg_flow_ctrl[3] & WF_PLE_TOP_HIF_PG_INFO_HIF_RSV_CNT_MASK) >> + WF_PLE_TOP_HIF_PG_INFO_HIF_RSV_CNT_SHFT; + upg_hif = (pg_flow_ctrl[3] & WF_PLE_TOP_HIF_PG_INFO_HIF_SRC_CNT_MASK) >> + WF_PLE_TOP_HIF_PG_INFO_HIF_SRC_CNT_SHFT; + DBGLOG(HAL, INFO, + "\t\tThe used/reserved pages of HIF group=0x%03x/0x%03x\n", + upg_hif, rpg_hif); + + DBGLOG(HAL, INFO, + "\tReserved page counter of HIF_TXCMD group(0x%08x): 0x%08x\n", + WF_PLE_TOP_PG_HIF_WMTXD_GROUP_ADDR, + pg_flow_ctrl[6]); + DBGLOG(HAL, INFO, "\tHIF_TXCMD group page status(0x%08x): 0x%08x\n", + WF_PLE_TOP_HIF_WMTXD_PG_INFO_ADDR, + pg_flow_ctrl[7]); + cpu_min_q = (pg_flow_ctrl[6] & + WF_PLE_TOP_PG_HIF_TXCMD_GROUP_HIF_TXCMD_MIN_QUOTA_MASK) >> + WF_PLE_TOP_PG_HIF_TXCMD_GROUP_HIF_TXCMD_MIN_QUOTA_SHFT; + cpu_max_q = (pg_flow_ctrl[6] & + WF_PLE_TOP_PG_HIF_TXCMD_GROUP_HIF_TXCMD_MAX_QUOTA_MASK) >> + WF_PLE_TOP_PG_HIF_TXCMD_GROUP_HIF_TXCMD_MAX_QUOTA_SHFT; + DBGLOG(HAL, INFO, + "\t\tThe max/min quota pages of HIF_TXCMD group=0x%03x/0x%03x\n", + cpu_max_q, cpu_min_q); + rpg_cpu = (pg_flow_ctrl[7] & + WF_PLE_TOP_HIF_TXCMD_PG_INFO_HIF_TXCMD_SRC_CNT_MASK) >> + WF_PLE_TOP_HIF_TXCMD_PG_INFO_HIF_TXCMD_SRC_CNT_SHFT; + upg_cpu = (pg_flow_ctrl[7] & + WF_PLE_TOP_HIF_TXCMD_PG_INFO_HIF_TXCMD_RSV_CNT_MASK) >> + WF_PLE_TOP_HIF_TXCMD_PG_INFO_HIF_TXCMD_RSV_CNT_SHFT; + DBGLOG(HAL, INFO, + "\t\tThe used/reserved pages of HIF_TXCMD group=0x%03x/0x%03x\n", + upg_cpu, rpg_cpu); + + DBGLOG(HAL, INFO, + "\tReserved page counter of CPU group(0x%08x): 0x%08x\n", + WF_PLE_TOP_PG_CPU_GROUP_ADDR, + pg_flow_ctrl[4]); + DBGLOG(HAL, INFO, "\tCPU group page status(0x%08x): 0x%08x\n", + WF_PLE_TOP_CPU_PG_INFO_ADDR, + pg_flow_ctrl[5]); + cpu_min_q = (pg_flow_ctrl[4] & + WF_PLE_TOP_PG_CPU_GROUP_CPU_MIN_QUOTA_MASK) >> + WF_PLE_TOP_PG_CPU_GROUP_CPU_MIN_QUOTA_SHFT; + cpu_max_q = (pg_flow_ctrl[4] & + WF_PLE_TOP_PG_CPU_GROUP_CPU_MAX_QUOTA_MASK) >> + WF_PLE_TOP_PG_CPU_GROUP_CPU_MAX_QUOTA_SHFT; + DBGLOG(HAL, INFO, + "\t\tThe max/min quota pages of CPU group=0x%03x/0x%03x\n", + cpu_max_q, cpu_min_q); + rpg_cpu = (pg_flow_ctrl[5] & WF_PLE_TOP_CPU_PG_INFO_CPU_RSV_CNT_MASK) >> + WF_PLE_TOP_CPU_PG_INFO_CPU_RSV_CNT_SHFT; + upg_cpu = (pg_flow_ctrl[5] & WF_PLE_TOP_CPU_PG_INFO_CPU_SRC_CNT_MASK) >> + WF_PLE_TOP_CPU_PG_INFO_CPU_SRC_CNT_SHFT; + DBGLOG(HAL, INFO, + "\t\tThe used/reserved pages of CPU group=0x%03x/0x%03x\n", + upg_cpu, rpg_cpu); + + if ((ple_stat[0] & WF_PLE_TOP_QUEUE_EMPTY_ALL_AC_EMPTY_MASK) == 0) { + for (j = 0; j < 24; j = j + 6) { + if (j % 6 == 0) { + DBGLOG(HAL, INFO, + "\tNonempty AC%d Q of STA#: ", j / 6); + } + + for (i = 0; i < 32; i++) { + if (((ple_stat[j + 1] & (0x1 << i)) >> i) == + 0) { + DBGLOG(HAL, INFO, "%d ", + i + (j % 6) * 32); + } + } + } + + DBGLOG(HAL, INFO, "\n"); + } + + DBGLOG(HAL, INFO, "Nonempty Q info:\n"); + + for (i = 0; i < 31; i++) { + if (((ple_stat[0] & (0x1 << i)) >> i) == 0) { + uint32_t hfid, tfid, pktcnt, fl_que_ctrl[3] = {0}; + + if (ple_queue_empty_info[i].QueueName != NULL) { + DBGLOG(HAL, INFO, "\t%s: ", + ple_queue_empty_info[i].QueueName); + fl_que_ctrl[0] |= + WF_PLE_TOP_FL_QUE_CTRL_0_EXECUTE_MASK; + fl_que_ctrl[0] |= + (ple_queue_empty_info[i].Portid + << WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_PID_SHFT); + fl_que_ctrl[0] |= + (ple_queue_empty_info[i].Queueid + << WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_QID_SHFT); + } else + continue; + + HAL_MCR_WR(prAdapter, WF_PLE_TOP_FL_QUE_CTRL_0_ADDR, + fl_que_ctrl[0]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_FL_QUE_CTRL_2_ADDR, + &fl_que_ctrl[1]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_FL_QUE_CTRL_3_ADDR, + &fl_que_ctrl[2]); + hfid = (fl_que_ctrl[1] & + WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_HEAD_FID_MASK) >> + WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_HEAD_FID_SHFT; + tfid = (fl_que_ctrl[1] & + WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_TAIL_FID_MASK) >> + WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_TAIL_FID_SHFT; + pktcnt = + (fl_que_ctrl[2] & + WF_PLE_TOP_FL_QUE_CTRL_3_QUEUE_PKT_NUM_MASK) >> + WF_PLE_TOP_FL_QUE_CTRL_3_QUEUE_PKT_NUM_SHFT; + DBGLOG(HAL, INFO, + "tail/head fid = 0x%03x/0x%03x, pkt cnt = 0x%03x\n", + tfid, hfid, pktcnt); + if (pktcnt > 0 && fgDumpTxd) + connac2x_show_txd_Info( + prAdapter, hfid); + } + } + + for (j = 0; j < 24; j = j + 6) { /* show AC Q info */ + for (i = 0; i < 32; i++) { + if (((ple_stat[j + 1] & (0x1 << i)) >> i) == 0) { + uint32_t hfid, tfid, pktcnt, ac_num = j / 6, + ctrl = 0; + uint32_t sta_num = i + (j % 6) * 32, + fl_que_ctrl[3] = {0}; + uint32_t wmmidx = 0; + + DBGLOG(HAL, INFO, "\tSTA%d AC%d: ", sta_num, + ac_num); + + fl_que_ctrl[0] |= + WF_PLE_TOP_FL_QUE_CTRL_0_EXECUTE_MASK; + fl_que_ctrl[0] |= + (ENUM_UMAC_LMAC_PORT_2 + << WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_PID_SHFT); + fl_que_ctrl[0] |= + (ac_num + << WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_QID_SHFT); + fl_que_ctrl[0] |= + (sta_num + << WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_WLANID_SHFT); + HAL_MCR_WR(prAdapter, + WF_PLE_TOP_FL_QUE_CTRL_0_ADDR, + fl_que_ctrl[0]); + HAL_MCR_RD(prAdapter, + WF_PLE_TOP_FL_QUE_CTRL_2_ADDR, + &fl_que_ctrl[1]); + HAL_MCR_RD(prAdapter, + WF_PLE_TOP_FL_QUE_CTRL_3_ADDR, + &fl_que_ctrl[2]); + hfid = (fl_que_ctrl[1] & + WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_HEAD_FID_MASK) >> + WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_HEAD_FID_SHFT; + tfid = (fl_que_ctrl[1] & + WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_TAIL_FID_MASK) >> + WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_TAIL_FID_SHFT; + + pktcnt = + (fl_que_ctrl[2] & + WF_PLE_TOP_FL_QUE_CTRL_3_QUEUE_PKT_NUM_MASK) >> + WF_PLE_TOP_FL_QUE_CTRL_3_QUEUE_PKT_NUM_SHFT; + DBGLOG(HAL, INFO, + "tail/head fid = 0x%03x/0x%03x, pkt cnt = %x", + tfid, hfid, pktcnt); + + if (((sta_pause[j % 6] & 0x1 << i) >> i) == 1) + ctrl = 2; + + if (((dis_sta_map[j % 6] & 0x1 << i) >> i) == 1) + ctrl = 1; + + DBGLOG(HAL, INFO, " ctrl = %s", + sta_ctrl_reg[ctrl]); + DBGLOG(HAL, INFO, " (wmmidx=%d)\n", + wmmidx); + if (pktcnt > 0 && fgDumpTxd) + connac2x_show_txd_Info( + prAdapter, hfid); + } + } + } +#if 0 + if (~ple_txcmd_stat) { + DBGLOG(HAL, INFO, "Nonempty TXCMD Q info:\n"); + for (i = 0; i < 31; i++) { + if (((ple_txcmd_stat & (0x1 << i)) >> i) == 0) { + uint32_t hfid, tfid; + uint32_t pktcnt, fl_que_ctrl[3] = {0}; + + if (ple_txcmd_queue_empty_info[i].QueueName != + NULL) { + DBGLOG(HAL, INFO, "\t%s: ", + ple_txcmd_queue_empty_info[i] + .QueueName); + fl_que_ctrl[0] |= + WF_PLE_TOP_FL_QUE_CTRL_0_EXECUTE_MASK; + fl_que_ctrl[0] |= + (ple_txcmd_queue_empty_info[i] + .Portid + << WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_PID_SHFT); + fl_que_ctrl[0] |= + (ple_txcmd_queue_empty_info[i] + .Queueid + << WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_QID_SHFT); + } else + continue; + + HAL_MCR_WR(prAdapter, + WF_PLE_TOP_FL_QUE_CTRL_0_ADDR, + fl_que_ctrl[0]); + HAL_MCR_RD(prAdapter, + WF_PLE_TOP_FL_QUE_CTRL_2_ADDR, + &fl_que_ctrl[1]); + HAL_MCR_RD(prAdapter, + WF_PLE_TOP_FL_QUE_CTRL_3_ADDR, + &fl_que_ctrl[2]); + hfid = (fl_que_ctrl[1] & + WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_HEAD_FID_MASK) >> + WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_HEAD_FID_SHFT; + tfid = (fl_que_ctrl[1] & + WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_TAIL_FID_MASK) >> + WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_TAIL_FID_SHFT; + pktcnt = + (fl_que_ctrl[2] & + WF_PLE_TOP_FL_QUE_CTRL_3_QUEUE_PKT_NUM_MASK) >> + WF_PLE_TOP_FL_QUE_CTRL_3_QUEUE_PKT_NUM_SHFT; + DBGLOG(HAL, INFO, "tail/head fid ="); + DBGLOG(HAL, INFO, "0x%03x/0x%03x,", tfid, hfid); + DBGLOG(HAL, INFO, "pkt cnt = 0x%03x\n", pktcnt); + } + } + } +#endif +} + +void mt7961_show_pse_info( + struct ADAPTER *prAdapter) +{ + u_int32_t pse_buf_ctrl, pg_sz, pg_num; + u_int32_t pse_stat; + u_int32_t fpg_cnt, ffa_cnt, fpg_head, fpg_tail; + u_int32_t max_q, min_q, rsv_pg, used_pg; + u_int32_t i, group_cnt; + u_int32_t group_quota, group_info, freepg_cnt, freepg_head_tail; + struct pse_group_info *group; + char *str; + + HAL_MCR_RD(prAdapter, WF_PSE_TOP_PBUF_CTRL_ADDR, &pse_buf_ctrl); + HAL_MCR_RD(prAdapter, WF_PSE_TOP_QUEUE_EMPTY_ADDR, &pse_stat); + HAL_MCR_RD(prAdapter, WF_PSE_TOP_FREEPG_CNT_ADDR, &freepg_cnt); + HAL_MCR_RD(prAdapter, WF_PSE_TOP_FREEPG_HEAD_TAIL_ADDR, + &freepg_head_tail); + + /* Configuration Info */ + DBGLOG(HAL, INFO, "PSE Configuration Info:\n"); + DBGLOG(HAL, INFO, "\tPacket Buffer Control(0x%08x): 0x%08x\n", + WF_PSE_TOP_PBUF_CTRL_ADDR, + pse_buf_ctrl); + pg_sz = (pse_buf_ctrl & WF_PSE_TOP_PBUF_CTRL_PAGE_SIZE_CFG_MASK) >> + WF_PSE_TOP_PBUF_CTRL_PAGE_SIZE_CFG_SHFT; + DBGLOG(HAL, INFO, "\t\tPage Size=%d(%d bytes per page)\n", pg_sz, + (pg_sz == 1 ? 256 : 128)); + DBGLOG(HAL, INFO, "\t\tPage Offset=%d(in unit of 64KB)\n", + (pse_buf_ctrl & WF_PSE_TOP_PBUF_CTRL_PBUF_OFFSET_MASK) >> + WF_PSE_TOP_PBUF_CTRL_PBUF_OFFSET_SHFT); + pg_num = (pse_buf_ctrl & WF_PSE_TOP_PBUF_CTRL_TOTAL_PAGE_NUM_MASK) >> + WF_PSE_TOP_PBUF_CTRL_TOTAL_PAGE_NUM_SHFT; + DBGLOG(HAL, INFO, "\t\tTotal page numbers=%d pages\n", pg_num); + /* Page Flow Control */ + DBGLOG(HAL, INFO, "PSE Page Flow Control:\n"); + DBGLOG(HAL, INFO, "\tFree page counter(0x%08x): 0x%08x\n", + WF_PSE_TOP_FREEPG_CNT_ADDR, freepg_cnt); + fpg_cnt = (freepg_cnt & WF_PSE_TOP_FREEPG_CNT_FREEPG_CNT_MASK) >> + WF_PSE_TOP_FREEPG_CNT_FREEPG_CNT_SHFT; + DBGLOG(HAL, INFO, "\t\tThe toal page number of free=0x%03x\n", fpg_cnt); + ffa_cnt = (freepg_cnt & WF_PSE_TOP_FREEPG_CNT_FFA_CNT_MASK) >> + WF_PSE_TOP_FREEPG_CNT_FFA_CNT_SHFT; + DBGLOG(HAL, INFO, "\t\tThe free page numbers of free for all=0x%03x\n", + ffa_cnt); + DBGLOG(HAL, INFO, "\tFree page head and tail(0x%08x): 0x%08x\n", + WF_PSE_TOP_FREEPG_HEAD_TAIL_ADDR, freepg_head_tail); + fpg_head = (freepg_head_tail & + WF_PSE_TOP_FREEPG_HEAD_TAIL_FREEPG_HEAD_MASK) >> + WF_PSE_TOP_FREEPG_HEAD_TAIL_FREEPG_HEAD_SHFT; + fpg_tail = (freepg_head_tail & + WF_PSE_TOP_FREEPG_HEAD_TAIL_FREEPG_TAIL_MASK) >> + WF_PSE_TOP_FREEPG_HEAD_TAIL_FREEPG_TAIL_SHFT; + DBGLOG(HAL, INFO, + "\t\tThe tail/head page of free page list=0x%03x/0x%03x\n", + fpg_tail, fpg_head); + + group_cnt = sizeof(pse_group) / sizeof(struct pse_group_info); + for (i = 0; i < group_cnt; i++) { + group = &pse_group[i]; + HAL_MCR_RD(prAdapter, group->quota_addr, &group_quota); + HAL_MCR_RD(prAdapter, group->pg_info_addr, &group_info); + + DBGLOG(HAL, INFO, + "\tReserved page counter of %s group(0x%08x): 0x%08x\n", + group->name, group->quota_addr, group_quota); + DBGLOG(HAL, INFO, "\t%s group page status(0x%08x): 0x%08x\n", + group->name, group->pg_info_addr, group_info); + min_q = (group_quota & + WF_PSE_TOP_PG_HIF0_GROUP_HIF0_MIN_QUOTA_MASK) >> + WF_PSE_TOP_PG_HIF0_GROUP_HIF0_MIN_QUOTA_SHFT; + max_q = (group_quota & + WF_PSE_TOP_PG_HIF0_GROUP_HIF0_MAX_QUOTA_MASK) >> + WF_PSE_TOP_PG_HIF0_GROUP_HIF0_MAX_QUOTA_SHFT; + DBGLOG(HAL, INFO, + "\t\tThe max/min quota pages of %s group=0x%03x/0x%03x\n", + group->name, max_q, min_q); + rsv_pg = + (group_info & WF_PSE_TOP_HIF0_PG_INFO_HIF0_RSV_CNT_MASK) >> + WF_PSE_TOP_HIF0_PG_INFO_HIF0_RSV_CNT_SHFT; + used_pg = + (group_info & WF_PSE_TOP_HIF0_PG_INFO_HIF0_SRC_CNT_MASK) >> + WF_PSE_TOP_HIF0_PG_INFO_HIF0_SRC_CNT_SHFT; + DBGLOG(HAL, INFO, + "\t\tThe used/reserved pages of %s group=0x%03x/0x%03x\n", + group->name, used_pg, rsv_pg); + } + + /* Queue Empty Status */ + DBGLOG(HAL, INFO, "PSE Queue Empty Status:\n"); + DBGLOG(HAL, INFO, "\tQUEUE_EMPTY(0x%08x): 0x%08x\n", + WF_PSE_TOP_QUEUE_EMPTY_ADDR, + pse_stat); + DBGLOG(HAL, INFO, "\t\tCPU Q0/1/2/3 empty=%d/%d/%d/%d\n", + (pse_stat & WF_PSE_TOP_QUEUE_EMPTY_CPU_Q0_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_CPU_Q0_EMPTY_SHFT, + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_CPU_Q1_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_CPU_Q1_EMPTY_SHFT), + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_CPU_Q2_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_CPU_Q2_EMPTY_SHFT), + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_CPU_Q3_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_CPU_Q3_EMPTY_SHFT)); + str = "\t\tHIF Q0/1/2/3/4/5/6/7/8/9/10/11"; + DBGLOG(HAL, INFO, + "%s empty=%d/%d/%d/%d/%d/%d/%d/%d/%d/%d/%d/%d\n", str, + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_HIF_0_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_HIF_0_EMPTY_SHFT), + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_HIF_1_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_HIF_1_EMPTY_SHFT), + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_HIF_2_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_HIF_2_EMPTY_SHFT), + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_HIF_3_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_HIF_3_EMPTY_SHFT), + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_HIF_4_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_HIF_4_EMPTY_SHFT), + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_HIF_5_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_HIF_5_EMPTY_SHFT), + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_HIF_6_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_HIF_6_EMPTY_SHFT), + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_HIF_7_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_HIF_7_EMPTY_SHFT), + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_HIF_8_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_HIF_8_EMPTY_SHFT), + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_HIF_9_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_HIF_9_EMPTY_SHFT), + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_HIF_10_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_HIF_10_EMPTY_SHFT), + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_HIF_11_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_HIF_11_EMPTY_SHFT)); + DBGLOG(HAL, INFO, "\t\tLMAC TX Q empty=%d\n", + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_LMAC_TX_QUEUE_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_LMAC_TX_QUEUE_EMPTY_SHFT)); + DBGLOG(HAL, INFO, "\t\tMDP TX Q/RX Q empty=%d/%d\n", + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_MDP_TX_QUEUE_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_MDP_TX_QUEUE_EMPTY_SHFT), + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_MDP_RX_QUEUE_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_MDP_RX_QUEUE_EMPTY_SHFT)); + DBGLOG(HAL, INFO, "\t\tSEC TX Q/RX Q empty=%d/%d\n", + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_SEC_TX_QUEUE_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_SEC_TX_QUEUE_EMPTY_SHFT), + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_SEC_RX_QUEUE_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_SEC_RX_QUEUE_EMPTY_SHFT)); + DBGLOG(HAL, INFO, "\t\tSFD PARK Q empty=%d\n", + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_SFD_PARK_QUEUE_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_SFD_PARK_QUEUE_EMPTY_SHFT)); + DBGLOG(HAL, INFO, "\t\tMDP TXIOC Q/RXIOC Q empty=%d/%d\n", + ((pse_stat & + WF_PSE_TOP_QUEUE_EMPTY_MDP_TXIOC_QUEUE_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_MDP_TXIOC_QUEUE_EMPTY_SHFT), + ((pse_stat & + WF_PSE_TOP_QUEUE_EMPTY_MDP_RXIOC_QUEUE_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_MDP_RXIOC_QUEUE_EMPTY_SHFT)); + DBGLOG(HAL, INFO, "\t\tMDP TX1 Q empty=%d\n", + ((pse_stat & + WF_PSE_TOP_QUEUE_EMPTY_MDP_TX1_QUEUE_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_MDP_TX1_QUEUE_EMPTY_SHFT)); + DBGLOG(HAL, INFO, "\t\tSEC TX1 Q empty=%d\n", + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_SEC_TX1_QUEUE_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_SEC_TX1_QUEUE_EMPTY_SHFT)); + DBGLOG(HAL, INFO, "\t\tMDP TXIOC1 Q/RXIOC1 Q empty=%d/%d\n", + ((pse_stat & + WF_PSE_TOP_QUEUE_EMPTY_MDP_TXIOC1_QUEUE_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_MDP_TXIOC1_QUEUE_EMPTY_SHFT), + ((pse_stat & + WF_PSE_TOP_QUEUE_EMPTY_MDP_RXIOC1_QUEUE_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_MDP_RXIOC1_QUEUE_EMPTY_SHFT)); + DBGLOG(HAL, INFO, "\t\tRLS Q empty=%d\n", + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_RLS_Q_EMTPY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_RLS_Q_EMTPY_SHFT)); + DBGLOG(HAL, INFO, "Nonempty Q info:\n"); + + for (i = 0; i < 31; i++) { + if (((pse_stat & (0x1 << i)) >> i) == 0) { + uint32_t hfid, tfid, pktcnt, fl_que_ctrl[3] = {0}; + + if (pse_queue_empty_info[i].QueueName != NULL) { + DBGLOG(HAL, INFO, "\t%s: ", + pse_queue_empty_info[i].QueueName); + fl_que_ctrl[0] |= + WF_PSE_TOP_FL_QUE_CTRL_0_EXECUTE_MASK; + fl_que_ctrl[0] |= + (pse_queue_empty_info[i].Portid + << WF_PSE_TOP_FL_QUE_CTRL_0_Q_BUF_PID_SHFT); + fl_que_ctrl[0] |= + (pse_queue_empty_info[i].Queueid + << WF_PSE_TOP_FL_QUE_CTRL_0_Q_BUF_QID_SHFT); + } else + continue; + + fl_que_ctrl[0] |= (0x1 << 31); + HAL_MCR_WR(prAdapter, WF_PSE_TOP_FL_QUE_CTRL_0_ADDR, + fl_que_ctrl[0]); + HAL_MCR_RD(prAdapter, WF_PSE_TOP_FL_QUE_CTRL_2_ADDR, + &fl_que_ctrl[1]); + HAL_MCR_RD(prAdapter, WF_PSE_TOP_FL_QUE_CTRL_3_ADDR, + &fl_que_ctrl[2]); + hfid = (fl_que_ctrl[1] & + WF_PSE_TOP_FL_QUE_CTRL_2_QUEUE_HEAD_FID_MASK) >> + WF_PSE_TOP_FL_QUE_CTRL_2_QUEUE_HEAD_FID_SHFT; + tfid = (fl_que_ctrl[1] & + WF_PSE_TOP_FL_QUE_CTRL_2_QUEUE_TAIL_FID_MASK) >> + WF_PSE_TOP_FL_QUE_CTRL_2_QUEUE_TAIL_FID_SHFT; + pktcnt = + (fl_que_ctrl[2] & + WF_PSE_TOP_FL_QUE_CTRL_3_QUEUE_PKT_NUM_MASK) >> + WF_PSE_TOP_FL_QUE_CTRL_3_QUEUE_PKT_NUM_SHFT; + DBGLOG(HAL, INFO, + "tail/head fid = 0x%03x/0x%03x, pkt cnt = 0x%03x\n", + tfid, hfid, pktcnt); + } + } +} +#endif /* MT7961 */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/mt7961/hal_dmashdl_mt7961.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/mt7961/hal_dmashdl_mt7961.c new file mode 100644 index 0000000000000000000000000000000000000000..8a3ead51f43d91723701623100138ae6f23c257a --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/mt7961/hal_dmashdl_mt7961.c @@ -0,0 +1,411 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2019 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2019 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/*! \file hal_dmashdl_mt7961.c +* \brief DMASHDL HAL API for MT7961 +* +* This file contains all routines which are exported + from MediaTek 802.11 Wireless LAN driver stack to GLUE Layer. +*/ + +#ifdef MT7961 +#if defined(_HIF_PCIE) || defined(_HIF_AXI) || defined(_HIF_USB) + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +#include "precomp.h" +#include "mt7961.h" +#include "coda/mt7961/wf_hif_dmashdl_top.h" +#include "hal_dmashdl_mt7961.h" + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +struct MT7961_DMASHDL_CFG rMT7961DmashdlCfg = { + .fgSlotArbiterEn = MT7961_DMASHDL_SLOT_ARBITER_EN, + + .u2PktPleMaxPage = MT7961_DMASHDL_PKT_PLE_MAX_PAGE, + + .u2PktPseMaxPage = MT7961_DMASHDL_PKT_PSE_MAX_PAGE, + + .afgRefillEn = { + MT7961_DMASHDL_GROUP_0_REFILL_EN, + MT7961_DMASHDL_GROUP_1_REFILL_EN, + MT7961_DMASHDL_GROUP_2_REFILL_EN, + MT7961_DMASHDL_GROUP_3_REFILL_EN, + MT7961_DMASHDL_GROUP_4_REFILL_EN, + MT7961_DMASHDL_GROUP_5_REFILL_EN, + MT7961_DMASHDL_GROUP_6_REFILL_EN, + MT7961_DMASHDL_GROUP_7_REFILL_EN, + MT7961_DMASHDL_GROUP_8_REFILL_EN, + MT7961_DMASHDL_GROUP_9_REFILL_EN, + MT7961_DMASHDL_GROUP_10_REFILL_EN, + MT7961_DMASHDL_GROUP_11_REFILL_EN, + MT7961_DMASHDL_GROUP_12_REFILL_EN, + MT7961_DMASHDL_GROUP_13_REFILL_EN, + MT7961_DMASHDL_GROUP_14_REFILL_EN, + MT7961_DMASHDL_GROUP_15_REFILL_EN, + }, + + .au2MaxQuota = { + MT7961_DMASHDL_GROUP_0_MAX_QUOTA, + MT7961_DMASHDL_GROUP_1_MAX_QUOTA, + MT7961_DMASHDL_GROUP_2_MAX_QUOTA, + MT7961_DMASHDL_GROUP_3_MAX_QUOTA, + MT7961_DMASHDL_GROUP_4_MAX_QUOTA, + MT7961_DMASHDL_GROUP_5_MAX_QUOTA, + MT7961_DMASHDL_GROUP_6_MAX_QUOTA, + MT7961_DMASHDL_GROUP_7_MAX_QUOTA, + MT7961_DMASHDL_GROUP_8_MAX_QUOTA, + MT7961_DMASHDL_GROUP_9_MAX_QUOTA, + MT7961_DMASHDL_GROUP_10_MAX_QUOTA, + MT7961_DMASHDL_GROUP_11_MAX_QUOTA, + MT7961_DMASHDL_GROUP_12_MAX_QUOTA, + MT7961_DMASHDL_GROUP_13_MAX_QUOTA, + MT7961_DMASHDL_GROUP_14_MAX_QUOTA, + MT7961_DMASHDL_GROUP_15_MAX_QUOTA, + }, + + .au2MinQuota = { + MT7961_DMASHDL_GROUP_0_MIN_QUOTA, + MT7961_DMASHDL_GROUP_1_MIN_QUOTA, + MT7961_DMASHDL_GROUP_2_MIN_QUOTA, + MT7961_DMASHDL_GROUP_3_MIN_QUOTA, + MT7961_DMASHDL_GROUP_4_MIN_QUOTA, + MT7961_DMASHDL_GROUP_5_MIN_QUOTA, + MT7961_DMASHDL_GROUP_6_MIN_QUOTA, + MT7961_DMASHDL_GROUP_7_MIN_QUOTA, + MT7961_DMASHDL_GROUP_8_MIN_QUOTA, + MT7961_DMASHDL_GROUP_9_MIN_QUOTA, + MT7961_DMASHDL_GROUP_10_MIN_QUOTA, + MT7961_DMASHDL_GROUP_11_MIN_QUOTA, + MT7961_DMASHDL_GROUP_12_MIN_QUOTA, + MT7961_DMASHDL_GROUP_13_MIN_QUOTA, + MT7961_DMASHDL_GROUP_14_MIN_QUOTA, + MT7961_DMASHDL_GROUP_15_MIN_QUOTA, + }, + + .aucQueue2Group = { + MT7961_DMASHDL_QUEUE_0_TO_GROUP, + MT7961_DMASHDL_QUEUE_1_TO_GROUP, + MT7961_DMASHDL_QUEUE_2_TO_GROUP, + MT7961_DMASHDL_QUEUE_3_TO_GROUP, + MT7961_DMASHDL_QUEUE_4_TO_GROUP, + MT7961_DMASHDL_QUEUE_5_TO_GROUP, + MT7961_DMASHDL_QUEUE_6_TO_GROUP, + MT7961_DMASHDL_QUEUE_7_TO_GROUP, + MT7961_DMASHDL_QUEUE_8_TO_GROUP, + MT7961_DMASHDL_QUEUE_9_TO_GROUP, + MT7961_DMASHDL_QUEUE_10_TO_GROUP, + MT7961_DMASHDL_QUEUE_11_TO_GROUP, + MT7961_DMASHDL_QUEUE_12_TO_GROUP, + MT7961_DMASHDL_QUEUE_13_TO_GROUP, + MT7961_DMASHDL_QUEUE_14_TO_GROUP, + MT7961_DMASHDL_QUEUE_15_TO_GROUP, + MT7961_DMASHDL_QUEUE_16_TO_GROUP, + MT7961_DMASHDL_QUEUE_17_TO_GROUP, + MT7961_DMASHDL_QUEUE_18_TO_GROUP, + MT7961_DMASHDL_QUEUE_19_TO_GROUP, + MT7961_DMASHDL_QUEUE_20_TO_GROUP, + MT7961_DMASHDL_QUEUE_21_TO_GROUP, + MT7961_DMASHDL_QUEUE_22_TO_GROUP, + MT7961_DMASHDL_QUEUE_23_TO_GROUP, + MT7961_DMASHDL_QUEUE_24_TO_GROUP, + MT7961_DMASHDL_QUEUE_25_TO_GROUP, + MT7961_DMASHDL_QUEUE_26_TO_GROUP, + MT7961_DMASHDL_QUEUE_27_TO_GROUP, + MT7961_DMASHDL_QUEUE_28_TO_GROUP, + MT7961_DMASHDL_QUEUE_29_TO_GROUP, + MT7961_DMASHDL_QUEUE_30_TO_GROUP, + MT7961_DMASHDL_QUEUE_31_TO_GROUP, + }, + + .aucPriority2Group = { + MT7961_DMASHDL_PRIORITY0_GROUP, + MT7961_DMASHDL_PRIORITY1_GROUP, + MT7961_DMASHDL_PRIORITY2_GROUP, + MT7961_DMASHDL_PRIORITY3_GROUP, + MT7961_DMASHDL_PRIORITY4_GROUP, + MT7961_DMASHDL_PRIORITY5_GROUP, + MT7961_DMASHDL_PRIORITY6_GROUP, + MT7961_DMASHDL_PRIORITY7_GROUP, + MT7961_DMASHDL_PRIORITY8_GROUP, + MT7961_DMASHDL_PRIORITY9_GROUP, + MT7961_DMASHDL_PRIORITY10_GROUP, + MT7961_DMASHDL_PRIORITY11_GROUP, + MT7961_DMASHDL_PRIORITY12_GROUP, + MT7961_DMASHDL_PRIORITY13_GROUP, + MT7961_DMASHDL_PRIORITY14_GROUP, + MT7961_DMASHDL_PRIORITY15_GROUP, + }, +}; + +void mt7961HalDmashdlSetPlePktMaxPage(struct ADAPTER *prAdapter, + uint16_t u2MaxPage) +{ + uint32_t u4Val; + + HAL_MCR_RD(prAdapter, WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_ADDR, &u4Val); + + u4Val &= ~WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_PLE_PACKET_MAX_SIZE_MASK; + u4Val |= (u2MaxPage << + WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_PLE_PACKET_MAX_SIZE_SHFT) & + WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_PLE_PACKET_MAX_SIZE_MASK; + + HAL_MCR_WR(prAdapter, WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_ADDR, u4Val); +} + +void mt7961HalDmashdlSetPsePktMaxPage(struct ADAPTER *prAdapter, + uint16_t u2MaxPage) +{ + uint32_t u4Val; + + HAL_MCR_RD(prAdapter, WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_ADDR, &u4Val); + + u4Val &= ~WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_PSE_PACKET_MAX_SIZE_MASK; + u4Val |= (u2MaxPage << + WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_PSE_PACKET_MAX_SIZE_SHFT) & + WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_PSE_PACKET_MAX_SIZE_MASK; + + HAL_MCR_WR(prAdapter, WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_ADDR, u4Val); +} + +void mt7961HalDmashdlSetRefill(struct ADAPTER *prAdapter, uint8_t ucGroup, + u_int8_t fgEnable) +{ + uint32_t u4Val, u4Mask; + + if (ucGroup >= ENUM_MT7961_DMASHDL_GROUP_NUM) + ASSERT(0); + + u4Mask = WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP0_REFILL_DISABLE_MASK + << ucGroup; + + HAL_MCR_RD(prAdapter, WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR, &u4Val); + + if (fgEnable) + u4Val &= ~u4Mask; + else + u4Val |= u4Mask; + + HAL_MCR_WR(prAdapter, WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR, u4Val); +} + +void mt7961HalDmashdlSetMaxQuota(struct ADAPTER *prAdapter, uint8_t ucGroup, + uint16_t u2MaxQuota) +{ + uint32_t u4Addr, u4Val; + + if (ucGroup >= ENUM_MT7961_DMASHDL_GROUP_NUM) + ASSERT(0); + + u4Addr = WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_ADDR + (ucGroup << 2); + + HAL_MCR_RD(prAdapter, u4Addr, &u4Val); + + u4Val &= ~WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_GROUP0_MAX_QUOTA_MASK; + u4Val |= (u2MaxQuota << + WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_GROUP0_MAX_QUOTA_SHFT) & + WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_GROUP0_MAX_QUOTA_MASK; + + HAL_MCR_WR(prAdapter, u4Addr, u4Val); +} + +void mt7961HalDmashdlSetMinQuota(struct ADAPTER *prAdapter, uint8_t ucGroup, + uint16_t u2MinQuota) +{ + uint32_t u4Addr, u4Val; + + if (ucGroup >= ENUM_MT7961_DMASHDL_GROUP_NUM) + ASSERT(0); + + u4Addr = WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_ADDR + (ucGroup << 2); + + HAL_MCR_RD(prAdapter, u4Addr, &u4Val); + + u4Val &= ~WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_GROUP0_MIN_QUOTA_MASK; + u4Val |= (u2MinQuota << + WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_GROUP0_MIN_QUOTA_SHFT) & + WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_GROUP0_MIN_QUOTA_MASK; + + HAL_MCR_WR(prAdapter, u4Addr, u4Val); +} + +void mt7961HalDmashdlSetQueueMapping(struct ADAPTER *prAdapter, uint8_t ucQueue, + uint8_t ucGroup) +{ + uint32_t u4Addr, u4Val, u4Mask, u4Shft; + + if (ucQueue >= 32) + ASSERT(0); + + if (ucGroup >= ENUM_MT7961_DMASHDL_GROUP_NUM) + ASSERT(0); + + u4Addr = WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_ADDR + + ((ucQueue >> 3) << 2); + u4Mask = WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE0_MAPPING_MASK << + ((ucQueue % 8) << 2); + u4Shft = (ucQueue % 8) << 2; + + HAL_MCR_RD(prAdapter, u4Addr, &u4Val); + + u4Val &= ~u4Mask; + u4Val |= (ucGroup << u4Shft) & u4Mask; + + HAL_MCR_WR(prAdapter, u4Addr, u4Val); +} + +void mt7961HalDmashdlSetSlotArbiter(struct ADAPTER *prAdapter, + u_int8_t fgEnable) +{ + uint32_t u4Val; + + HAL_MCR_RD(prAdapter, WF_HIF_DMASHDL_TOP_PAGE_SETTING_ADDR, &u4Val); + + if (fgEnable) + u4Val |= + WF_HIF_DMASHDL_TOP_PAGE_SETTING_GROUP_SEQUENCE_ORDER_TYPE_MASK; + else + u4Val &= + ~WF_HIF_DMASHDL_TOP_PAGE_SETTING_GROUP_SEQUENCE_ORDER_TYPE_MASK; + + HAL_MCR_WR(prAdapter, WF_HIF_DMASHDL_TOP_PAGE_SETTING_ADDR, u4Val); +} + +void mt7961HalDmashdlSetUserDefinedPriority(struct ADAPTER *prAdapter, + uint8_t ucPriority, uint8_t ucGroup) +{ + uint32_t u4Addr, u4Val, u4Mask, u4Shft; + + ASSERT(ucPriority < 16); + ASSERT(ucGroup < ENUM_MT7961_DMASHDL_GROUP_NUM); + + u4Addr = WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_ADDR + + ((ucPriority >> 3) << 2); + u4Mask = WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY0_GROUP_MASK + << ((ucPriority % 8) << 2); + u4Shft = (ucPriority % 8) << 2; + + HAL_MCR_RD(prAdapter, u4Addr, &u4Val); + + u4Val &= ~u4Mask; + u4Val |= (ucGroup << u4Shft) & u4Mask; + + HAL_MCR_WR(prAdapter, u4Addr, u4Val); +} + +void mt7961DmashdlInit(struct ADAPTER *prAdapter) +{ + uint32_t idx; + + mt7961HalDmashdlSetPlePktMaxPage(prAdapter, + rMT7961DmashdlCfg.u2PktPleMaxPage); + + mt7961HalDmashdlSetPsePktMaxPage(prAdapter, + rMT7961DmashdlCfg.u2PktPseMaxPage); + + for (idx = 0; idx < ENUM_MT7961_DMASHDL_GROUP_NUM; idx++) { + mt7961HalDmashdlSetRefill(prAdapter, idx, + rMT7961DmashdlCfg.afgRefillEn[idx]); + + mt7961HalDmashdlSetMaxQuota(prAdapter, idx, + rMT7961DmashdlCfg.au2MaxQuota[idx]); + + mt7961HalDmashdlSetMinQuota(prAdapter, idx, + rMT7961DmashdlCfg.au2MinQuota[idx]); + } + + for (idx = 0; idx < 32; idx++) + mt7961HalDmashdlSetQueueMapping(prAdapter, idx, + rMT7961DmashdlCfg.aucQueue2Group[idx]); + + for (idx = 0; idx < 16; idx++) + mt7961HalDmashdlSetUserDefinedPriority(prAdapter, idx, + rMT7961DmashdlCfg.aucPriority2Group[idx]); + + mt7961HalDmashdlSetSlotArbiter(prAdapter, + rMT7961DmashdlCfg.fgSlotArbiterEn); +} + +#endif /* defined(_HIF_PCIE) || defined(_HIF_AXI) || defined(_HIF_USB) */ +#endif /* MT7961 */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/mt7961/mt7961.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/mt7961/mt7961.c new file mode 100644 index 0000000000000000000000000000000000000000..aa14bed8333b1d9d508e9206615f27d3c3ecee21 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/mt7961/mt7961.c @@ -0,0 +1,665 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/*! \file mt7961.c +* \brief Internal driver stack will export +* the required procedures here for GLUE Layer. +* +* This file contains all routines which are exported + from MediaTek 802.11 Wireless LAN driver stack to GLUE Layer. +*/ + +#ifdef MT7961 + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +#include "coda/mt7961/wf_wfdma_host_dma0.h" +#include "coda/mt7961/wf_cr_sw_def.h" +#include "precomp.h" +#include "mt7961.h" +#include "hal_dmashdl_mt7961.h" + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +#define CONN_MCU_CONFG_BASE 0x88000000 +#define CONN_MCU_CONFG_COM_REG0_ADDR (CONN_MCU_CONFG_BASE + 0x200) + +#define PATCH_SEMAPHORE_COMM_REG 0 +#define PATCH_SEMAPHORE_COMM_REG_PATCH_DONE 1 /* bit0 is for patch. */ + +#define SW_WORKAROUND_FOR_WFDMA_ISSUE_HWITS00009838 1 + +#define RX_DATA_RING_BASE_IDX 2 + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +struct ECO_INFO mt7961_eco_table[] = { + /* HW version, ROM version, Factory version */ + {0x00, 0x00, 0xA, 0x1}, /* E1 */ + {0x00, 0x00, 0x0, 0x0} /* End of table */ +}; + +#if defined(_HIF_PCIE) || defined(_HIF_AXI) +struct PCIE_CHIP_CR_MAPPING mt7961_bus2chip_cr_mapping[] = { + /* chip addr, bus addr, range */ + {0x54000000, 0x02000, 0x1000}, /* WFDMA PCIE0 MCU DMA0 */ + {0x55000000, 0x03000, 0x1000}, /* WFDMA PCIE0 MCU DMA1 */ + {0x56000000, 0x04000, 0x1000}, /* WFDMA reserved */ + {0x57000000, 0x05000, 0x1000}, /* WFDMA MCU wrap CR */ + {0x58000000, 0x06000, 0x1000}, /* WFDMA PCIE1 MCU DMA0 (MEM_DMA) */ + {0x59000000, 0x07000, 0x1000}, /* WFDMA PCIE1 MCU DMA1 */ + {0x820c0000, 0x08000, 0x4000}, /* WF_UMAC_TOP (PLE) */ + {0x820c8000, 0x0c000, 0x2000}, /* WF_UMAC_TOP (PSE) */ + {0x820cc000, 0x0e000, 0x2000}, /* WF_UMAC_TOP (PP) */ + {0x820e0000, 0x20000, 0x0400}, /* WF_LMAC_TOP BN0 (WF_CFG) */ + {0x820e1000, 0x20400, 0x0200}, /* WF_LMAC_TOP BN0 (WF_TRB) */ + {0x820e2000, 0x20800, 0x0400}, /* WF_LMAC_TOP BN0 (WF_AGG) */ + {0x820e3000, 0x20c00, 0x0400}, /* WF_LMAC_TOP BN0 (WF_ARB) */ + {0x820e4000, 0x21000, 0x0400}, /* WF_LMAC_TOP BN0 (WF_TMAC) */ + {0x820e5000, 0x21400, 0x0800}, /* WF_LMAC_TOP BN0 (WF_RMAC) */ + {0x820ce000, 0x21c00, 0x0200}, /* WF_LMAC_TOP (WF_SEC) */ + {0x820e7000, 0x21e00, 0x0200}, /* WF_LMAC_TOP BN0 (WF_DMA) */ + {0x820cf000, 0x22000, 0x1000}, /* WF_LMAC_TOP (WF_PF) */ + {0x820e9000, 0x23400, 0x0200}, /* WF_LMAC_TOP BN0 (WF_WTBLOFF) */ + {0x820ea000, 0x24000, 0x0200}, /* WF_LMAC_TOP BN0 (WF_ETBF) */ + {0x820eb000, 0x24200, 0x0400}, /* WF_LMAC_TOP BN0 (WF_LPON) */ + {0x820ec000, 0x24600, 0x0200}, /* WF_LMAC_TOP BN0 (WF_INT) */ + {0x820ed000, 0x24800, 0x0800}, /* WF_LMAC_TOP BN0 (WF_MIB) */ + {0x820ca000, 0x26000, 0x2000}, /* WF_LMAC_TOP BN0 (WF_MUCOP) */ + {0x820d0000, 0x30000, 0x10000}, /* WF_LMAC_TOP (WF_WTBLON) */ + {0x40000000, 0x70000, 0x10000}, /* WF_UMAC_SYSRAM */ + {0x00400000, 0x80000, 0x10000}, /* WF_MCU_SYSRAM */ + {0x00410000, 0x90000, 0x10000}, /* WF_MCU_SYSRAM (configure register) */ + {0x820f0000, 0xa0000, 0x0400}, /* WF_LMAC_TOP BN1 (WF_CFG) */ + {0x820f1000, 0xa0600, 0x0200}, /* WF_LMAC_TOP BN1 (WF_TRB) */ + {0x820f2000, 0xa0800, 0x0400}, /* WF_LMAC_TOP BN1 (WF_AGG) */ + {0x820f3000, 0xa0c00, 0x0400}, /* WF_LMAC_TOP BN1 (WF_ARB) */ + {0x820f4000, 0xa1000, 0x0400}, /* WF_LMAC_TOP BN1 (WF_TMAC) */ + {0x820f5000, 0xa1400, 0x0800}, /* WF_LMAC_TOP BN1 (WF_RMAC) */ + {0x820f7000, 0xa1e00, 0x0200}, /* WF_LMAC_TOP BN1 (WF_DMA) */ + {0x820f9000, 0xa3400, 0x0200}, /* WF_LMAC_TOP BN1 (WF_WTBLOFF) */ + {0x820fa000, 0xa4000, 0x0200}, /* WF_LMAC_TOP BN1 (WF_ETBF) */ + {0x820fb000, 0xa4200, 0x0400}, /* WF_LMAC_TOP BN1 (WF_LPON) */ + {0x820fc000, 0xa4600, 0x0200}, /* WF_LMAC_TOP BN1 (WF_INT) */ + {0x820fd000, 0xa4800, 0x0800}, /* WF_LMAC_TOP BN1 (WF_MIB) */ + {0x820cc000, 0xa5000, 0x2000}, /* WF_LMAC_TOP BN1 (WF_MUCOP) */ + {0x820c4000, 0xa8000, 0x4000}, /* WF_LMAC_TOP BN1 (WF_MUCOP) */ + {0x820b0000, 0xae000, 0x1000}, /* [APB2] WFSYS_ON */ + {0x80020000, 0xb0000, 0x10000}, /* WF_TOP_MISC_OFF */ + {0x81020000, 0xc0000, 0x10000}, /* WF_TOP_MISC_ON */ + {0x7c020000, 0xd0000, 0x10000}, /* CONN_INFRA, wfdma */ + {0x7c060000, 0xe0000, 0x10000}, /* CONN_INFRA, conn_host_csr_top */ + {0x7c000000, 0xf0000, 0x10000}, /* CONN_INFRA */ +}; + +static void mt7961EnableInterrupt( + struct ADAPTER *prAdapter) +{ + union WPDMA_INT_MASK IntMask; + + prAdapter->fgIsIntEnable = TRUE; + + HAL_MCR_RD(prAdapter, + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR, &IntMask.word); + IntMask.word = 0; + IntMask.field_conn2x_single.wfdma0_rx_done_0 = 1; + IntMask.field_conn2x_single.wfdma0_rx_done_2 = 1; + IntMask.field_conn2x_single.wfdma0_rx_done_3 = 1; + IntMask.field_conn2x_single.wfdma0_rx_done_4 = 1; + IntMask.field_conn2x_single.wfdma0_rx_done_5 = 1; + IntMask.field_conn2x_single.wfdma0_tx_done_0 = 1; + IntMask.field_conn2x_single.wfdma0_tx_done_16 = 1; + IntMask.field_conn2x_single.wfdma0_tx_done_17 = 1; + IntMask.field_conn2x_single.wfdma0_mcu2host_sw_int_en = 1; + + IntMask.field_conn2x_single.wfdma0_rx_coherent = 0; + IntMask.field_conn2x_single.wfdma0_tx_coherent = 0; + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR, IntMask.word); + + DBGLOG(HAL, TRACE, "%s [0x%08x]\n", __func__, IntMask.word); +} /* end of nicEnableInterrupt() */ + +static void mt7961DisableInterrupt( + struct ADAPTER *prAdapter) +{ + struct GLUE_INFO *prGlueInfo = NULL; + union WPDMA_INT_MASK IntMask; + + ASSERT(prAdapter); + + prGlueInfo = prAdapter->prGlueInfo; + + IntMask.word = 0; + + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR, IntMask.word); + HAL_MCR_RD(prAdapter, + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR, &IntMask.word); + + prAdapter->fgIsIntEnable = FALSE; + + DBGLOG(HAL, TRACE, "%s\n", __func__); +} + +static uint8_t mt7961SetRxRingHwAddr( + struct RTMP_RX_RING *prRxRing, + struct BUS_INFO *prBusInfo, + uint32_t u4SwRingIdx) +{ + uint32_t offset = 0; + + /* + * RX_RING_EVT_IDX_1 (RX_Ring0) - Rx Event + * RX_RING_DATA_IDX_0 (RX_Ring2) - Band0 Rx Data + * WFDMA0_RX_RING_IDX_2 (RX_Ring3) - Band1 Rx Data + * WFDMA0_RX_RING_IDX_3 (RX_Ring4) - Band0 Tx Free Done Event + * WFDMA1_RX_RING_IDX_0 (RX_Ring5) - Band1 Tx Free Done Event + */ + switch (u4SwRingIdx) { + case RX_RING_EVT_IDX_1: + offset = 0; + break; + case RX_RING_DATA_IDX_0: + offset = RX_DATA_RING_BASE_IDX * MT_RINGREG_DIFF; + break; + case WFDMA0_RX_RING_IDX_2: + case WFDMA0_RX_RING_IDX_3: + case WFDMA1_RX_RING_IDX_0: + offset = (u4SwRingIdx + 1) * MT_RINGREG_DIFF; + break; + default: + return FALSE; + } + + prRxRing->hw_desc_base = prBusInfo->host_rx_ring_base + offset; + prRxRing->hw_cidx_addr = prBusInfo->host_rx_ring_cidx_addr + offset; + prRxRing->hw_didx_addr = prBusInfo->host_rx_ring_didx_addr + offset; + prRxRing->hw_cnt_addr = prBusInfo->host_rx_ring_cnt_addr + offset; + + return TRUE; +} + +static bool mt7961LiteWfdmaAllocRxRing( + struct GLUE_INFO *prGlueInfo, + bool fgAllocMem) +{ + /* Band1 Data Rx path */ + if (!halWpdmaAllocRxRing(prGlueInfo, + WFDMA0_RX_RING_IDX_2, RX_RING0_SIZE, + RXD_SIZE, CFG_RX_MAX_PKT_SIZE, fgAllocMem)) { + DBGLOG(HAL, ERROR, "AllocRxRing[0] fail\n"); + return false; + } + /* Band0 Tx Free Done Event */ + if (!halWpdmaAllocRxRing(prGlueInfo, + WFDMA0_RX_RING_IDX_3, RX_RING1_SIZE, + RXD_SIZE, RX_BUFFER_AGGRESIZE, fgAllocMem)) { + DBGLOG(HAL, ERROR, "AllocRxRing[1] fail\n"); + return false; + } + /* Band1 Tx Free Done Event */ + if (!halWpdmaAllocRxRing(prGlueInfo, + WFDMA1_RX_RING_IDX_0, RX_RING1_SIZE, + RXD_SIZE, RX_BUFFER_AGGRESIZE, fgAllocMem)) { + DBGLOG(HAL, ERROR, "AllocRxRing[1] fail\n"); + return false; + } + return true; +} + +static void mt7961Connac2xProcessTxInterrupt( + struct ADAPTER *prAdapter) +{ + struct GL_HIF_INFO *prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + union WPDMA_INT_STA_STRUCT rIntrStatus; + + rIntrStatus = (union WPDMA_INT_STA_STRUCT)prHifInfo->u4IntStatus; + if (rIntrStatus.field_conn2x_single.wfdma0_tx_done_16) + halWpdmaProcessCmdDmaDone( + prAdapter->prGlueInfo, TX_RING_FWDL_IDX_3); + + if (rIntrStatus.field_conn2x_single.wfdma0_tx_done_17) + halWpdmaProcessCmdDmaDone( + prAdapter->prGlueInfo, TX_RING_CMD_IDX_2); + + if (rIntrStatus.field_conn2x_single.wfdma0_tx_done_0) { + halWpdmaProcessDataDmaDone( + prAdapter->prGlueInfo, TX_RING_DATA0_IDX_0); + kalSetTxEvent2Hif(prAdapter->prGlueInfo); + } +} + +static void mt7961Connac2xProcessRxInterrupt( + struct ADAPTER *prAdapter) +{ + struct GL_HIF_INFO *prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + union WPDMA_INT_STA_STRUCT rIntrStatus; + + rIntrStatus = (union WPDMA_INT_STA_STRUCT)prHifInfo->u4IntStatus; + if (rIntrStatus.field_conn2x_single.wfdma0_rx_done_0) + halRxReceiveRFBs(prAdapter, RX_RING_EVT_IDX_1, FALSE); + + if (rIntrStatus.field_conn2x_single.wfdma0_rx_done_2) + halRxReceiveRFBs(prAdapter, RX_RING_DATA_IDX_0, TRUE); + + if (rIntrStatus.field_conn2x_single.wfdma0_rx_done_3) + halRxReceiveRFBs(prAdapter, WFDMA0_RX_RING_IDX_2, TRUE); + + if (rIntrStatus.field_conn2x_single.wfdma0_rx_done_4) + halRxReceiveRFBs(prAdapter, WFDMA0_RX_RING_IDX_3, TRUE); + + if (rIntrStatus.field_conn2x_single.wfdma0_rx_done_5) + halRxReceiveRFBs(prAdapter, WFDMA1_RX_RING_IDX_0, TRUE); +} + +static void mt7961Connac2xWfdmaManualPrefetch( + struct GLUE_INFO *prGlueInfo) +{ + struct ADAPTER *prAdapter = prGlueInfo->prAdapter; + u_int32_t val = 0; + + HAL_MCR_RD(prAdapter, WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR, &val); + /* disable prefetch offset calculation auto-mode */ + val &= + ~WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN_MASK; + HAL_MCR_WR(prAdapter, WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR, val); + + HAL_MCR_WR(prAdapter, WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_EXT_CTRL_ADDR, + 0x00000004); + HAL_MCR_WR(prAdapter, WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_EXT_CTRL_ADDR, + 0x00400004); + HAL_MCR_WR(prAdapter, WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_EXT_CTRL_ADDR, + 0x00800004); + HAL_MCR_WR(prAdapter, WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_EXT_CTRL_ADDR, + 0x00c00004); + HAL_MCR_WR(prAdapter, WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_EXT_CTRL_ADDR, + 0x01000004); + + HAL_MCR_WR(prAdapter, WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_EXT_CTRL_ADDR, + 0x01400004); + HAL_MCR_WR(prAdapter, WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_EXT_CTRL_ADDR, + 0x01800004); + HAL_MCR_WR(prAdapter, WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_EXT_CTRL_ADDR, + 0x01c00004); + + HAL_MCR_WR(prAdapter, WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_EXT_CTRL_ADDR, + 0x02000004); + HAL_MCR_WR(prAdapter, WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_EXT_CTRL_ADDR, + 0x02400004); + HAL_MCR_WR(prAdapter, WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_EXT_CTRL_ADDR, + 0x02800004); + HAL_MCR_WR(prAdapter, WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_EXT_CTRL_ADDR, + 0x02c00004); + + HAL_MCR_WR(prAdapter, WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_EXT_CTRL_ADDR, + 0x03400004); + HAL_MCR_WR(prAdapter, WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_EXT_CTRL_ADDR, + 0x03800004); + + /* reset dma idx */ + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_ADDR, 0xFFFFFFFF); +} + +static void mt7961ReadIntStatus( + struct ADAPTER *prAdapter, + uint32_t *pu4IntStatus) +{ + uint32_t u4RegValue; + struct GL_HIF_INFO *prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + struct BUS_INFO *prBusInfo = prAdapter->chip_info->bus_info; + + *pu4IntStatus = 0; + + HAL_MCR_RD(prAdapter, + WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR, &u4RegValue); + + if (HAL_IS_CONNAC2X_EXT_RX_DONE_INTR(u4RegValue, + prBusInfo->host_int_rxdone_bits)) + *pu4IntStatus |= WHISR_RX0_DONE_INT; + + if (HAL_IS_CONNAC2X_EXT_TX_DONE_INTR(u4RegValue, + prBusInfo->host_int_txdone_bits)) + *pu4IntStatus |= WHISR_TX_DONE_INT; + + if (u4RegValue & CONNAC_MCU_SW_INT) + *pu4IntStatus |= WHISR_D2H_SW_INT; + + prHifInfo->u4IntStatus = u4RegValue; + + /* clear interrupt */ + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR, u4RegValue); +} + +#endif /*_HIF_PCIE || _HIF_AXI */ + +#if defined(_HIF_USB) +void mt7961Connac2xWfdmaInitForUSB( + struct ADAPTER *prAdapter, + struct mt66xx_chip_info *prChipInfo) +{ + HAL_MCR_WR(prAdapter, 0x74000004, 0); + HAL_MCR_WR(prAdapter, 0x74000014, 0); + HAL_MCR_WR(prAdapter, 0x74000300, 0); +} + +#endif + +void mt7961DumpSerDummyCR( + struct ADAPTER *prAdapter) +{ + uint32_t u4MacVal; + + DBGLOG(HAL, INFO, "%s\n", __func__); + + DBGLOG(HAL, INFO, "=====Dump Start====\n"); + + HAL_MCR_RD(prAdapter, WF_SW_DEF_CR_SER_STATUS_ADDR, &u4MacVal); + DBGLOG(HAL, INFO, "SER STATUS[0x%08x]: 0x%08x\n", + WF_SW_DEF_CR_SER_STATUS_ADDR, u4MacVal); + + HAL_MCR_RD(prAdapter, WF_SW_DEF_CR_PLE_STATUS_ADDR, &u4MacVal); + DBGLOG(HAL, INFO, "PLE STATUS[0x%08x]: 0x%08x\n", + WF_SW_DEF_CR_PLE_STATUS_ADDR, u4MacVal); + + HAL_MCR_RD(prAdapter, WF_SW_DEF_CR_PLE1_STATUS_ADDR, &u4MacVal); + DBGLOG(HAL, INFO, "PLE1 STATUS[0x%08x]: 0x%08x\n", + WF_SW_DEF_CR_PLE1_STATUS_ADDR, u4MacVal); + + HAL_MCR_RD(prAdapter, WF_SW_DEF_CR_PLE_AMSDU_STATUS_ADDR, &u4MacVal); + DBGLOG(HAL, INFO, "PLE AMSDU STATUS[0x%08x]: 0x%08x\n", + WF_SW_DEF_CR_PLE_AMSDU_STATUS_ADDR, u4MacVal); + + HAL_MCR_RD(prAdapter, WF_SW_DEF_CR_PSE_STATUS_ADDR, &u4MacVal); + DBGLOG(HAL, INFO, "PSE STATUS[0x%08x]: 0x%08x\n", + WF_SW_DEF_CR_PSE_STATUS_ADDR, u4MacVal); + + HAL_MCR_RD(prAdapter, WF_SW_DEF_CR_PSE1_STATUS_ADDR, &u4MacVal); + DBGLOG(HAL, INFO, "PSE1 STATUS[0x%08x]: 0x%08x\n", + WF_SW_DEF_CR_PSE1_STATUS_ADDR, u4MacVal); + + HAL_MCR_RD(prAdapter, WF_SW_DEF_CR_LAMC_WISR6_BN0_STATUS_ADDR, + &u4MacVal); + DBGLOG(HAL, INFO, "LMAC WISR6 BN0 STATUS[0x%08x]: 0x%08x\n", + WF_SW_DEF_CR_LAMC_WISR6_BN0_STATUS_ADDR, u4MacVal); + + HAL_MCR_RD(prAdapter, WF_SW_DEF_CR_LAMC_WISR6_BN1_STATUS_ADDR, + &u4MacVal); + DBGLOG(HAL, INFO, "LMAC WISR6 BN1 STATUS[0x%08x]: 0x%08x\n", + WF_SW_DEF_CR_LAMC_WISR6_BN1_STATUS_ADDR, u4MacVal); + + HAL_MCR_RD(prAdapter, WF_SW_DEF_CR_LAMC_WISR7_BN0_STATUS_ADDR, + &u4MacVal); + DBGLOG(HAL, INFO, "LMAC WISR7 BN0 STATUS[0x%08x]: 0x%08x\n", + WF_SW_DEF_CR_LAMC_WISR7_BN0_STATUS_ADDR, u4MacVal); + + HAL_MCR_RD(prAdapter, WF_SW_DEF_CR_LAMC_WISR7_BN1_STATUS_ADDR, + &u4MacVal); + DBGLOG(HAL, INFO, "LMAC WISR7 BN1 STATUS[0x%08x]: 0x%08x\n", + WF_SW_DEF_CR_LAMC_WISR7_BN1_STATUS_ADDR, u4MacVal); + + DBGLOG(HAL, INFO, "=====Dump End====\n"); + +} + + +struct BUS_INFO mt7961_bus_info = { +#if defined(_HIF_PCIE) || defined(_HIF_AXI) + .top_cfg_base = MT7961_TOP_CFG_BASE, + + /* host_dma0 for TXP */ + .host_dma0_base = WF_WFDMA_HOST_DMA0_BASE, + .host_int_status_addr = WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR, + + .host_int_txdone_bits = + (CONNAC2X_WFDMA_TX_DONE_INT0 | CONNAC2X_WFDMA_TX_DONE_INT1 | + CONNAC2X_WFDMA_TX_DONE_INT2 | CONNAC2X_WFDMA_TX_DONE_INT3 | + CONNAC2X_WFDMA_TX_DONE_INT4 | CONNAC2X_WFDMA_TX_DONE_INT5 | + CONNAC2X_WFDMA_TX_DONE_INT6 | CONNAC2X_WFDMA_TX_DONE_INT16 | + CONNAC2X_WFDMA_TX_DONE_INT17), + .host_int_rxdone_bits = + (CONNAC2X_WFDMA_RX_DONE_INT0 | CONNAC2X_WFDMA_RX_DONE_INT0 | + CONNAC2X_WFDMA_RX_DONE_INT2 | CONNAC2X_WFDMA_RX_DONE_INT3 | + CONNAC2X_WFDMA_RX_DONE_INT4 | CONNAC2X_WFDMA_RX_DONE_INT5), + + .host_tx_ring_base = WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL0_ADDR, + .host_tx_ring_ext_ctrl_base = + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_EXT_CTRL_ADDR, + .host_tx_ring_cidx_addr = WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL2_ADDR, + .host_tx_ring_didx_addr = WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL3_ADDR, + .host_tx_ring_cnt_addr = WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL1_ADDR, + + .host_rx_ring_base = WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL0_ADDR, + .host_rx_ring_ext_ctrl_base = + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_EXT_CTRL_ADDR, + .host_rx_ring_cidx_addr = WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL2_ADDR, + .host_rx_ring_didx_addr = WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL3_ADDR, + .host_rx_ring_cnt_addr = WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL1_ADDR, + + .bus2chip = mt7961_bus2chip_cr_mapping, + .max_static_map_addr = 0x000f0000, + + .tx_ring_fwdl_idx = CONNAC2X_FWDL_TX_RING_IDX, + .tx_ring_cmd_idx = CONNAC2X_CMD_TX_RING_IDX, + .tx_ring0_data_idx = 0, + .tx_ring1_data_idx = 1, + .fw_own_clear_addr = CONNAC2X_BN0_IRQ_STAT_ADDR, + .fw_own_clear_bit = PCIE_LPCR_FW_CLR_OWN, + .fgCheckDriverOwnInt = FALSE, + .u4DmaMask = 32, + .pdmaSetup = asicConnac2xWpdmaConfig, + .enableInterrupt = mt7961EnableInterrupt, + .disableInterrupt = mt7961DisableInterrupt, + .processTxInterrupt = mt7961Connac2xProcessTxInterrupt, + .processRxInterrupt = mt7961Connac2xProcessRxInterrupt, + .tx_ring_ext_ctrl = asicConnac2xWfdmaTxRingExtCtrl, + .rx_ring_ext_ctrl = asicConnac2xWfdmaRxRingExtCtrl, + /* null wfdmaManualPrefetch if want to disable manual mode */ + .wfdmaManualPrefetch = mt7961Connac2xWfdmaManualPrefetch, + .lowPowerOwnRead = asicConnac2xLowPowerOwnRead, + .lowPowerOwnSet = asicConnac2xLowPowerOwnSet, + .lowPowerOwnClear = asicConnac2xLowPowerOwnClear, + .wakeUpWiFi = asicWakeUpWiFi, + .processSoftwareInterrupt = asicConnac2xProcessSoftwareInterrupt, + .softwareInterruptMcu = asicConnac2xSoftwareInterruptMcu, + .hifRst = asicConnac2xHifRst, + + .initPcieInt = NULL, /* Todo: check if enable INT on driver side */ + .devReadIntStatus = mt7961ReadIntStatus, + .DmaShdlInit = mt7961DmashdlInit, + .setRxRingHwAddr = mt7961SetRxRingHwAddr, + .wfdmaAllocRxRing = mt7961LiteWfdmaAllocRxRing, +#endif /*_HIF_PCIE || _HIF_AXI */ + +#if defined(_HIF_USB) + .u4UdmaWlCfg_0_Addr = CONNAC2X_UDMA_WLCFG_0, + .u4UdmaWlCfg_1_Addr = CONNAC2X_UDMA_WLCFG_1, + .u4UdmaWlCfg_0 = + (CONNAC2X_UDMA_WLCFG_0_WL_TX_EN(1) | + CONNAC2X_UDMA_WLCFG_0_WL_RX_EN(1) | + CONNAC2X_UDMA_WLCFG_0_WL_RX_MPSZ_PAD0(1) | + CONNAC2X_UDMA_WLCFG_0_TICK_1US_EN(1)), + .u4UdmaTxQsel = CONNAC2X_UDMA_TX_QSEL, + .u4device_vender_request_in = DEVICE_VENDOR_REQUEST_IN_CONNAC2, + .u4device_vender_request_out = DEVICE_VENDOR_REQUEST_OUT_CONNAC2, + .asicUsbEventEpDetected = asicConnac2xUsbEventEpDetected, + .asicUsbRxByteCount = asicConnac2xUsbRxByteCount, + .DmaShdlInit = mt7961DmashdlInit, +#endif +}; + +#if CFG_ENABLE_FW_DOWNLOAD +struct FWDL_OPS_T mt7961_fw_dl_ops = { + .constructFirmwarePrio = NULL, + .constructPatchName = NULL, + .downloadPatch = wlanDownloadPatch, + .downloadFirmware = wlanConnacFormatDownload, + .getFwInfo = wlanGetConnacFwInfo, + .getFwDlInfo = asicGetFwDlInfo, + .phyAction = NULL, +}; +#endif /* CFG_ENABLE_FW_DOWNLOAD */ + +struct TX_DESC_OPS_T mt7961TxDescOps = { + .fillNicAppend = fillNicTxDescAppend, + .fillHifAppend = fillTxDescAppendByHostV2, + .fillTxByteCount = fillConnac2xTxDescTxByteCount, +}; + +struct RX_DESC_OPS_T mt7961RxDescOps = {}; + +struct CHIP_DBG_OPS mt7961DebugOps = { + .showPdmaInfo = NULL, + .showPseInfo = mt7961_show_pse_info, + .showPleInfo = mt7961_show_ple_info, + .showTxdInfo = connac2x_show_txd_Info, + .showWtblInfo = connac2x_show_wtbl_info, + .showUmacFwtblInfo = connac2x_show_umac_wtbl_info, + .showCsrInfo = NULL, + .showDmaschInfo = NULL, + .dumpMacInfo = NULL, + .showHifInfo = NULL, + .printHifDbgInfo = NULL, + .show_rx_rate_info = connac2x_show_rx_rate_info, + .show_rx_rssi_info = connac2x_show_rx_rssi_info, + .show_stat_info = connac2x_show_stat_info, +#ifdef CFG_SUPPORT_LINK_QUALITY_MONITOR + .get_rx_rate_info = connac2x_get_rx_rate_info +#endif +}; + +/* Litien code refine to support multi chip */ +struct mt66xx_chip_info mt66xx_chip_info_mt7961 = { + .bus_info = &mt7961_bus_info, +#if CFG_ENABLE_FW_DOWNLOAD + .fw_dl_ops = &mt7961_fw_dl_ops, +#endif /* CFG_ENABLE_FW_DOWNLOAD */ + .prTxDescOps = &mt7961TxDescOps, + .prRxDescOps = &mt7961RxDescOps, + .prDebugOps = &mt7961DebugOps, + .chip_id = MT7961_CHIP_ID, + .should_verify_chip_id = FALSE, + .sw_sync0 = MT7961_SW_SYNC0, + .sw_ready_bits = WIFI_FUNC_NO_CR4_READY_BITS, + .sw_ready_bit_offset = MT7961_SW_SYNC0_RDY_OFFSET, + .patch_addr = MT7961_PATCH_START_ADDR, + .is_support_cr4 = FALSE, + .is_support_wacpu = FALSE, + .txd_append_size = MT7961_TX_DESC_APPEND_LENGTH, + .rxd_size = MT7961_RX_DESC_LENGTH, + .init_evt_rxd_size = MT7961_RX_DESC_LENGTH, + .pse_header_length = CONNAC2X_NIC_TX_PSE_HEADER_LENGTH, + .init_event_size = CONNAC2X_RX_INIT_EVENT_LENGTH, + .eco_info = mt7961_eco_table, + .isNicCapV1 = FALSE, + .top_hcr = CONNAC2X_TOP_HCR, + .top_hvr = CONNAC2X_TOP_HVR, + .top_fvr = CONNAC2X_TOP_FVR, + .arb_ac_mode_addr = MT7961_ARB_AC_MODE_ADDR, + .asicCapInit = asicConnac2xCapInit, +#if CFG_ENABLE_FW_DOWNLOAD + .asicEnableFWDownload = NULL, +#endif /* CFG_ENABLE_FW_DOWNLOAD */ + .asicDumpSerDummyCR = mt7961DumpSerDummyCR, + .downloadBufferBin = wlanConnacDownloadBufferBin, + .is_support_hw_amsdu = TRUE, + .is_support_asic_lp = TRUE, + .is_support_wfdma1 = FALSE, + .asicWfdmaReInit = asicConnac2xWfdmaReInit, + .asicWfdmaReInit_handshakeInit = asicConnac2xWfdmaDummyCrWrite, +#if defined(_HIF_USB) + .asicUsbInit = asicConnac2xWfdmaInitForUSB, + .asicUsbInit_ic_specific = mt7961Connac2xWfdmaInitForUSB, + .u4SerUsbMcuEventAddr = WF_SW_DEF_CR_USB_MCU_EVENT_ADD, + .u4SerUsbHostAckAddr = WF_SW_DEF_CR_USB_HOST_ACK_ADDR, +#endif + .group5_size = sizeof(struct HW_MAC_RX_STS_GROUP_5), + .u4LmacWtblDUAddr = MT7961_WIFI_LWTBL_BASE, + .u4UmacWtblDUAddr = MT7961_WIFI_UWTBL_BASE, + .cmd_max_pkt_size = CFG_TX_MAX_PKT_SIZE, /* size 1600 */ +}; + +struct mt66xx_hif_driver_data mt66xx_driver_data_mt7961 = { + .chip_info = &mt66xx_chip_info_mt7961, +}; + +#endif /* MT7961 */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/soc3_0/dbg_soc3_0.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/soc3_0/dbg_soc3_0.c new file mode 100644 index 0000000000000000000000000000000000000000..dfad6ae807a3a263592f0937ac768e3e3e9793a1 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/soc3_0/dbg_soc3_0.c @@ -0,0 +1,2085 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/****************************************************************************** + *[File] dbg_soc3_0.c + *[Version] v1.0 + *[Revision Date] 2019-09-09 + *[Author] + *[Description] + * The program provides WIFI FALCON MAC Debug APIs + *[Copyright] + * Copyright (C) 2015 MediaTek Incorporation. All Rights Reserved. + ******************************************************************************/ + +#ifdef SOC3_0 +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "coda/soc3_0/wf_ple_top.h" +#include "coda/soc3_0/wf_pse_top.h" +#include "coda/soc3_0/wf_wfdma_host_dma0.h" +#include "coda/soc3_0/wf_wfdma_host_dma1.h" +#include "coda/soc3_0/wf_hif_dmashdl_top.h" +#include "precomp.h" +#include "mt_dmac.h" +#include "wf_ple.h" +#include "hal_dmashdl_soc3_0.h" +#include "soc3_0.h" +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/* TODO : need to Merge related API with non-driver base */ +#define WFSYS_SUPPORT_BUS_HANG_READ_FROM_DRIVER_BASE 1 + +/* define WFDMA CODA here */ +#define WF_WFDMA_MCU_DMA0_WPDMA_TX_RING0_CTRL0_ADDR \ + (CONNAC2X_MCU_WPDMA_0_BASE + 0x300) +#define WF_WFDMA_MCU_DMA1_WPDMA_TX_RING0_CTRL0_ADDR \ + (CONNAC2X_MCU_WPDMA_1_BASE + 0x300) +#define WF_WFDMA_MCU_DMA1_WPDMA_TX_RING1_CTRL0_ADDR \ + (CONNAC2X_MCU_WPDMA_1_BASE + 0x310) +#define WF_WFDMA_MCU_DMA0_WPDMA_RX_RING0_CTRL0_ADDR \ + (CONNAC2X_MCU_WPDMA_0_BASE + 0x500) +#define WF_WFDMA_MCU_DMA0_WPDMA_RX_RING1_CTRL0_ADDR \ + (CONNAC2X_MCU_WPDMA_0_BASE + 0x510) +#define WF_WFDMA_MCU_DMA1_WPDMA_RX_RING0_CTRL0_ADDR \ + (CONNAC2X_MCU_WPDMA_1_BASE + 0x500) +#define WF_WFDMA_MCU_DMA1_WPDMA_RX_RING1_CTRL0_ADDR \ + (CONNAC2X_MCU_WPDMA_1_BASE + 0x510) +#define WF_WFDMA_MCU_DMA1_WPDMA_RX_RING2_CTRL0_ADDR \ + (CONNAC2X_MCU_WPDMA_1_BASE + 0x520) + +/* define PLE/PSE FSM CR here */ +#define WF_PLE_FSM_PEEK_CR_00 (WF_PLE_TOP_BASE + 0x03D0) +#define WF_PLE_FSM_PEEK_CR_01 (WF_PLE_TOP_BASE + 0x03D4) +#define WF_PLE_FSM_PEEK_CR_02 (WF_PLE_TOP_BASE + 0x03D8) +#define WF_PLE_FSM_PEEK_CR_03 (WF_PLE_TOP_BASE + 0x03DC) +#define WF_PLE_FSM_PEEK_CR_04 (WF_PLE_TOP_BASE + 0x03E0) +#define WF_PLE_FSM_PEEK_CR_05 (WF_PLE_TOP_BASE + 0x03E4) +#define WF_PLE_FSM_PEEK_CR_06 (WF_PLE_TOP_BASE + 0x03E8) +#define WF_PLE_FSM_PEEK_CR_07 (WF_PLE_TOP_BASE + 0x03EC) +#define WF_PLE_FSM_PEEK_CR_08 (WF_PLE_TOP_BASE + 0x03F0) +#define WF_PLE_FSM_PEEK_CR_09 (WF_PLE_TOP_BASE + 0x03F4) +#define WF_PLE_FSM_PEEK_CR_10 (WF_PLE_TOP_BASE + 0x03F8) +#define WF_PLE_FSM_PEEK_CR_11 (WF_PLE_TOP_BASE + 0x03FC) + +#define WF_PSE_FSM_PEEK_CR_00 (WF_PSE_TOP_BASE + 0x03D0) +#define WF_PSE_FSM_PEEK_CR_01 (WF_PSE_TOP_BASE + 0x03D4) +#define WF_PSE_FSM_PEEK_CR_02 (WF_PSE_TOP_BASE + 0x03D8) +#define WF_PSE_FSM_PEEK_CR_03 (WF_PSE_TOP_BASE + 0x03DC) +#define WF_PSE_FSM_PEEK_CR_04 (WF_PSE_TOP_BASE + 0x03E0) +#define WF_PSE_FSM_PEEK_CR_05 (WF_PSE_TOP_BASE + 0x03E4) +#define WF_PSE_FSM_PEEK_CR_06 (WF_PSE_TOP_BASE + 0x03E8) +#define WF_PSE_FSM_PEEK_CR_07 (WF_PSE_TOP_BASE + 0x03EC) +#define WF_PSE_FSM_PEEK_CR_08 (WF_PSE_TOP_BASE + 0x03F0) +#define WF_PSE_FSM_PEEK_CR_09 (WF_PSE_TOP_BASE + 0x03F4) + +#if WFSYS_SUPPORT_BUS_HANG_READ_FROM_DRIVER_BASE +/* define for read Driver Base CR */ +#define CONNAC2X_MCU_WPDMA_0_DRIVER_BASE 0x18402000 +#define CONNAC2X_MCU_WPDMA_1_DRIVER_BASE 0x18403000 +#define CONNAC2X_HOST_WPDMA_0_DRIVER_BASE 0x18024000 +#define CONNAC2X_HOST_WPDMA_1_DRIVER_BASE 0x18025000 + +#define CONNAC2X_HOST_EXT_CONN_HIF_WRAP_DRIVER_BASE 0x18027000 +#define CONNAC2X_MCU_INT_CONN_HIF_WRAP_DRIVER_BASE 0x18405000 + +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL0_ADDR_DRIVER_BASE \ + (CONNAC2X_HOST_WPDMA_1_DRIVER_BASE + 0x300) /* 5300 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL1_ADDR_DRIVER_BASE \ + (CONNAC2X_HOST_WPDMA_1_DRIVER_BASE + 0x304) /* 5304 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL0_ADDR_DRIVER_BASE \ + (CONNAC2X_HOST_WPDMA_1_DRIVER_BASE + 0x400) /* 5400 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL0_ADDR_DRIVER_BASE \ + (CONNAC2X_HOST_WPDMA_1_DRIVER_BASE + 0x380) /* 5380 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL0_ADDR_DRIVER_BASE \ + (CONNAC2X_HOST_WPDMA_1_DRIVER_BASE + 0x410) /* 5410 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL0_ADDR_DRIVER_BASE \ + (CONNAC2X_HOST_WPDMA_1_DRIVER_BASE + 0x420) /* 5420 */ + +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL0_ADDR_DRIVER_BASE \ + (CONNAC2X_HOST_WPDMA_0_DRIVER_BASE + 0x500) /* 4500 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL0_ADDR_DRIVER_BASE \ + (CONNAC2X_HOST_WPDMA_0_DRIVER_BASE + 0x510) /* 4510 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL0_ADDR_DRIVER_BASE \ + (CONNAC2X_HOST_WPDMA_0_DRIVER_BASE + 0x520) /* 4520 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL0_ADDR_DRIVER_BASE \ + (CONNAC2X_HOST_WPDMA_0_DRIVER_BASE + 0x530) /* 4530 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL0_ADDR_DRIVER_BASE \ + (CONNAC2X_HOST_WPDMA_1_DRIVER_BASE + 0x500) /* 5500 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL0_ADDR_DRIVER_BASE \ + (CONNAC2X_HOST_WPDMA_0_DRIVER_BASE + 0x540) /* 4540 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL0_ADDR_DRIVER_BASE \ + (CONNAC2X_HOST_WPDMA_0_DRIVER_BASE + 0x550) /* 4550 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL0_ADDR_DRIVER_BASE \ + (CONNAC2X_HOST_WPDMA_0_DRIVER_BASE + 0x560) /* 4560 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL0_ADDR_DRIVER_BASE \ + (CONNAC2X_HOST_WPDMA_0_DRIVER_BASE + 0x570) /* 4570 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL0_ADDR_DRIVER_BASE \ + (CONNAC2X_HOST_WPDMA_1_DRIVER_BASE + 0x510) /* 5510 */ + +#define WF_WFDMA_MCU_DMA0_WPDMA_TX_RING0_CTRL0_ADDR_DRIVER_BASE \ + (CONNAC2X_MCU_WPDMA_0_DRIVER_BASE + 0x300) +#define WF_WFDMA_MCU_DMA1_WPDMA_TX_RING0_CTRL0_ADDR_DRIVER_BASE \ + (CONNAC2X_MCU_WPDMA_0_DRIVER_BASE + 0x300) +#define WF_WFDMA_MCU_DMA1_WPDMA_TX_RING1_CTRL0_ADDR_DRIVER_BASE \ + (CONNAC2X_MCU_WPDMA_1_DRIVER_BASE + 0x310) +#define WF_WFDMA_MCU_DMA0_WPDMA_RX_RING0_CTRL0_ADDR_DRIVER_BASE \ + (CONNAC2X_MCU_WPDMA_1_DRIVER_BASE + 0x500) +#define WF_WFDMA_MCU_DMA0_WPDMA_RX_RING1_CTRL0_ADDR_DRIVER_BASE \ + (CONNAC2X_MCU_WPDMA_0_DRIVER_BASE + 0x510) +#define WF_WFDMA_MCU_DMA1_WPDMA_RX_RING0_CTRL0_ADDR_DRIVER_BASE \ + (CONNAC2X_MCU_WPDMA_1_DRIVER_BASE + 0x500) +#define WF_WFDMA_MCU_DMA1_WPDMA_RX_RING1_CTRL0_ADDR_DRIVER_BASE \ + (CONNAC2X_MCU_WPDMA_1_DRIVER_BASE + 0x510) +#define WF_WFDMA_MCU_DMA1_WPDMA_RX_RING2_CTRL0_ADDR_DRIVER_BASE \ + (CONNAC2X_MCU_WPDMA_1_DRIVER_BASE + 0x520) + +#endif /* WFSYS_SUPPORT_BUS_HANG_READ_FROM_DRIVER_BASE */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +struct pse_group_info { + char name[20]; + u_int32_t quota_addr; + u_int32_t pg_info_addr; +}; + +struct wfdma_group_info { + char name[20]; + u_int32_t hw_desc_base; +}; + +enum _ENUM_WFDMA_TYPE_T { + WFDMA_TYPE_HOST = 0, + WFDMA_TYPE_WM +}; + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +static struct EMPTY_QUEUE_INFO ple_queue_empty_info[] = { + {"CPU Q0", MCU_Q0_INDEX, ENUM_UMAC_CTX_Q_0}, + {"CPU Q1", ENUM_UMAC_CPU_PORT_1, ENUM_UMAC_CTX_Q_1}, + {"CPU Q2", ENUM_UMAC_CPU_PORT_1, ENUM_UMAC_CTX_Q_2}, + {"CPU Q3", ENUM_UMAC_CPU_PORT_1, ENUM_UMAC_CTX_Q_3}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, /* 4~7 not defined */ + {"ALTX Q0", ENUM_UMAC_LMAC_PORT_2, + ENUM_UMAC_LMAC_PLE_TX_Q_ALTX_0}, /* Q16 */ + {"BMC Q0", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_BMC_0}, + {"BCN Q0", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_BNC_0}, + {"PSMP Q0", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_PSMP_0}, + {"ALTX Q1", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_ALTX_1}, + {"BMC Q1", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_BMC_1}, + {"BCN Q1", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_BNC_1}, + {"PSMP Q1", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_PSMP_1}, + {"NAF Q", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_NAF}, + {"NBCN Q", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_NBCN}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, /* 18~29 not defined */ + {"RLS Q", ENUM_PLE_CTRL_PSE_PORT_3, ENUM_UMAC_PLE_CTRL_P3_Q_0X1E}, + {"RLS2 Q", ENUM_PLE_CTRL_PSE_PORT_3, ENUM_UMAC_PLE_CTRL_P3_Q_0X1F} }; + +static struct EMPTY_QUEUE_INFO pse_queue_empty_info[] = { + {"CPU Q0", ENUM_UMAC_CPU_PORT_1, ENUM_UMAC_CTX_Q_0}, + {"CPU Q1", ENUM_UMAC_CPU_PORT_1, ENUM_UMAC_CTX_Q_1}, + {"CPU Q2", ENUM_UMAC_CPU_PORT_1, ENUM_UMAC_CTX_Q_2}, + {"CPU Q3", ENUM_UMAC_CPU_PORT_1, ENUM_UMAC_CTX_Q_3}, + {"HIF Q8", ENUM_UMAC_HIF_PORT_0, 8}, + {"HIF Q9", ENUM_UMAC_HIF_PORT_0, 9}, + {"HIF Q10", ENUM_UMAC_HIF_PORT_0, 10}, + {"HIF Q11", ENUM_UMAC_HIF_PORT_0, 11}, + {"HIF Q0", ENUM_UMAC_HIF_PORT_0, 0}, /*bit 8*/ + {"HIF Q1", ENUM_UMAC_HIF_PORT_0, 1}, + {"HIF Q2", ENUM_UMAC_HIF_PORT_0, 2}, + {"HIF Q3", ENUM_UMAC_HIF_PORT_0, 3}, + {"HIF Q4", ENUM_UMAC_HIF_PORT_0, 4}, + {"HIF Q5", ENUM_UMAC_HIF_PORT_0, 5}, + {"HIF Q6", ENUM_UMAC_HIF_PORT_0, 6}, + {"HIF Q7", ENUM_UMAC_HIF_PORT_0, 7}, + {"LMAC Q", ENUM_UMAC_LMAC_PORT_2, 0}, /*bit 16*/ + {"MDP TX Q", ENUM_UMAC_LMAC_PORT_2, 1}, + {"MDP RX Q", ENUM_UMAC_LMAC_PORT_2, 2}, + {"SEC TX Q", ENUM_UMAC_LMAC_PORT_2, 3}, + {"SEC RX Q", ENUM_UMAC_LMAC_PORT_2, 4}, + {"SFD_PARK Q", ENUM_UMAC_LMAC_PORT_2, 5}, + {"MDP_TXIOC Q", ENUM_UMAC_LMAC_PORT_2, 6}, + {"MDP_RXIOC Q", ENUM_UMAC_LMAC_PORT_2, 7}, + {"MDP_TX1 Q", ENUM_UMAC_LMAC_PORT_2, 17}, /*bit 24*/ + {"SEC_TX1 Q", ENUM_UMAC_LMAC_PORT_2, 19}, + {"MDP_TXIOC1 Q", ENUM_UMAC_LMAC_PORT_2, 22}, + {"MDP_RXIOC1 Q", ENUM_UMAC_LMAC_PORT_2, 23}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, /* 28~30 not defined */ + {"RLS Q", ENUM_PLE_CTRL_PSE_PORT_3, ENUM_UMAC_PLE_CTRL_P3_Q_0X1F} }; + +static u_int8_t *sta_ctrl_reg[] = {"ENABLE", "DISABLE", "PAUSE"}; + +#if 0 +static struct EMPTY_QUEUE_INFO ple_txcmd_queue_empty_info[] = { + {"AC00Q", ENUM_UMAC_LMAC_PORT_2, 0x40}, + {"AC01Q", ENUM_UMAC_LMAC_PORT_2, 0x41}, + {"AC02Q", ENUM_UMAC_LMAC_PORT_2, 0x42}, + {"AC03Q", ENUM_UMAC_LMAC_PORT_2, 0x43}, + {"AC10Q", ENUM_UMAC_LMAC_PORT_2, 0x44}, + {"AC11Q", ENUM_UMAC_LMAC_PORT_2, 0x45}, + {"AC12Q", ENUM_UMAC_LMAC_PORT_2, 0x46}, + {"AC13Q", ENUM_UMAC_LMAC_PORT_2, 0x47}, + {"AC20Q", ENUM_UMAC_LMAC_PORT_2, 0x48}, + {"AC21Q", ENUM_UMAC_LMAC_PORT_2, 0x49}, + {"AC22Q", ENUM_UMAC_LMAC_PORT_2, 0x4a}, + {"AC23Q", ENUM_UMAC_LMAC_PORT_2, 0x4b}, + {"AC30Q", ENUM_UMAC_LMAC_PORT_2, 0x4c}, + {"AC31Q", ENUM_UMAC_LMAC_PORT_2, 0x4d}, + {"AC32Q", ENUM_UMAC_LMAC_PORT_2, 0x4e}, + {"AC33Q", ENUM_UMAC_LMAC_PORT_2, 0x4f}, + {"ALTX Q0", ENUM_UMAC_LMAC_PORT_2, 0x50}, + {"TF Q0", ENUM_UMAC_LMAC_PORT_2, 0x51}, + {"TWT TSF-TF Q0", ENUM_UMAC_LMAC_PORT_2, 0x52}, + {"TWT DL Q0", ENUM_UMAC_LMAC_PORT_2, 0x53}, + {"TWT UL Q0", ENUM_UMAC_LMAC_PORT_2, 0x54}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0}, + {NULL, 0, 0} }; +#endif + +struct pse_group_info pse_group[] = { + {"HIF0(TX data)", WF_PSE_TOP_PG_HIF0_GROUP_ADDR, + WF_PSE_TOP_HIF0_PG_INFO_ADDR}, + {"HIF1(Talos CMD)", WF_PSE_TOP_PG_HIF1_GROUP_ADDR, + WF_PSE_TOP_HIF1_PG_INFO_ADDR}, +#if 0 + {"HIF2", WF_PSE_TOP_PG_HIF2_GROUP_ADDR, + WF_PSE_TOP_HIF2_PG_INFO_ADDR}, +#endif + {"CPU(I/O r/w)", WF_PSE_TOP_PG_CPU_GROUP_ADDR, + WF_PSE_TOP_CPU_PG_INFO_ADDR}, + {"PLE(host report)", WF_PSE_TOP_PG_PLE_GROUP_ADDR, + WF_PSE_TOP_PLE_PG_INFO_ADDR}, + {"PLE1(SPL report)", WF_PSE_TOP_PG_PLE1_GROUP_ADDR, + WF_PSE_TOP_PLE1_PG_INFO_ADDR}, + {"LMAC0(RX data)", WF_PSE_TOP_PG_LMAC0_GROUP_ADDR, + WF_PSE_TOP_LMAC0_PG_INFO_ADDR}, + {"LMAC1(RX_VEC)", WF_PSE_TOP_PG_LMAC1_GROUP_ADDR, + WF_PSE_TOP_LMAC1_PG_INFO_ADDR}, + {"LMAC2(TXS)", WF_PSE_TOP_PG_LMAC2_GROUP_ADDR, + WF_PSE_TOP_LMAC2_PG_INFO_ADDR}, + {"LMAC3(TXCMD/RXRPT)", WF_PSE_TOP_PG_LMAC3_GROUP_ADDR, + WF_PSE_TOP_LMAC3_PG_INFO_ADDR}, + {"MDP", WF_PSE_TOP_PG_MDP_GROUP_ADDR, + WF_PSE_TOP_MDP_PG_INFO_ADDR}, +#if 0 + {"MDP1", WF_PSE_TOP_PG_MDP1_GROUP_ADDR, + WF_PSE_TOP_MDP1_PG_INFO_ADDR}, + {"MDP2", WF_PSE_TOP_PG_MDP2_GROUP_ADDR, + WF_PSE_TOP_MDP2_PG_INFO_ADDR}, +#endif +}; + +struct wfdma_group_info wfmda_host_tx_group[] = { + {"P1T0:AP DATA0", WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL0_ADDR}, + {"P1T1:AP DATA1", WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL0_ADDR}, + {"P1T16:FWDL", WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL0_ADDR}, + {"P1T17:AP CMD", WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL0_ADDR}, + {"P1T8:MD DATA", WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL0_ADDR}, + {"P1T18:MD CMD", WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL0_ADDR}, +}; + +struct wfdma_group_info wfmda_host_rx_group[] = { + {"P0R0:AP DATA0", WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL0_ADDR}, + {"P0R1:AP DATA1", WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL0_ADDR}, + {"P0R2:AP TDONE0", WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL0_ADDR}, + {"P0R3:AP TDONE1", WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL0_ADDR}, + {"P1R0:AP EVENT", WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL0_ADDR}, + {"P0R4:MD DATA0", WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL0_ADDR}, + {"P0R5:MD DATA1", WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL0_ADDR}, + {"P0R6:MD TDONE0", WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL0_ADDR}, + {"P0R7:MD TDONE1", WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL0_ADDR}, + {"P1R1:MD EVENT", WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL0_ADDR}, +}; + +struct wfdma_group_info wfmda_wm_tx_group[] = { + {"P0T0:DATA", WF_WFDMA_MCU_DMA0_WPDMA_TX_RING0_CTRL0_ADDR}, + {"P1T0:AP EVENT", WF_WFDMA_MCU_DMA1_WPDMA_TX_RING0_CTRL0_ADDR}, + {"P1T1:MD EVENT", WF_WFDMA_MCU_DMA1_WPDMA_TX_RING1_CTRL0_ADDR}, +}; + +struct wfdma_group_info wfmda_wm_rx_group[] = { + {"P0R0:DATA", WF_WFDMA_MCU_DMA0_WPDMA_RX_RING0_CTRL0_ADDR}, + {"P0R1:TXDONE", WF_WFDMA_MCU_DMA0_WPDMA_RX_RING1_CTRL0_ADDR}, + {"P1R0:FWDL", WF_WFDMA_MCU_DMA1_WPDMA_RX_RING0_CTRL0_ADDR}, + {"P1R1:AP CMD", WF_WFDMA_MCU_DMA1_WPDMA_RX_RING1_CTRL0_ADDR}, + {"P1R2:MD CMD", WF_WFDMA_MCU_DMA1_WPDMA_RX_RING2_CTRL0_ADDR}, +}; + +#if WFSYS_SUPPORT_BUS_HANG_READ_FROM_DRIVER_BASE +struct wfdma_group_info wfmda_host_tx_group_driver_base[] = { + {"P1T0:AP DATA0", + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL0_ADDR_DRIVER_BASE}, + {"P1T1:AP DATA1", + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL0_ADDR_DRIVER_BASE}, + {"P1T16:FWDL", + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL0_ADDR_DRIVER_BASE}, + {"P1T17:AP CMD", + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL0_ADDR_DRIVER_BASE}, + {"P1T8:MD DATA", + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL0_ADDR_DRIVER_BASE}, + {"P1T18:MD CMD", + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL0_ADDR_DRIVER_BASE}, +}; + +struct wfdma_group_info wfmda_host_rx_group_driver_base[] = { + {"P0R0:AP DATA0", + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL0_ADDR_DRIVER_BASE}, + {"P0R1:AP DATA1", + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL0_ADDR_DRIVER_BASE}, + {"P0R2:AP TDONE0", + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL0_ADDR_DRIVER_BASE}, + {"P0R3:AP TDONE1", + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL0_ADDR_DRIVER_BASE}, + {"P1R0:AP EVENT", + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL0_ADDR_DRIVER_BASE}, + {"P0R4:MD DATA0", + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL0_ADDR_DRIVER_BASE}, + {"P0R5:MD DATA1", + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL0_ADDR_DRIVER_BASE}, + {"P0R6:MD TDONE0", + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL0_ADDR_DRIVER_BASE}, + {"P0R7:MD TDONE1", + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL0_ADDR_DRIVER_BASE}, + {"P1R1:MD EVENT", + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL0_ADDR_DRIVER_BASE}, +}; + +struct wfdma_group_info wfmda_wm_tx_group_driver_base[] = { + {"P0T0:DATA", + WF_WFDMA_MCU_DMA0_WPDMA_TX_RING0_CTRL0_ADDR_DRIVER_BASE}, + {"P1T0:AP EVENT", + WF_WFDMA_MCU_DMA1_WPDMA_TX_RING0_CTRL0_ADDR_DRIVER_BASE}, + {"P1T1:MD EVENT", + WF_WFDMA_MCU_DMA1_WPDMA_TX_RING1_CTRL0_ADDR_DRIVER_BASE}, +}; + +struct wfdma_group_info wfmda_wm_rx_group_driver_base[] = { + {"P0R0:DATA", + WF_WFDMA_MCU_DMA0_WPDMA_RX_RING0_CTRL0_ADDR_DRIVER_BASE}, + {"P0R1:TXDONE", + WF_WFDMA_MCU_DMA0_WPDMA_RX_RING1_CTRL0_ADDR_DRIVER_BASE}, + {"P1R0:FWDL", + WF_WFDMA_MCU_DMA1_WPDMA_RX_RING0_CTRL0_ADDR_DRIVER_BASE}, + {"P1R1:AP CMD", + WF_WFDMA_MCU_DMA1_WPDMA_RX_RING1_CTRL0_ADDR_DRIVER_BASE}, + {"P1R2:MD CMD", + WF_WFDMA_MCU_DMA1_WPDMA_RX_RING2_CTRL0_ADDR_DRIVER_BASE}, +}; +#endif /* WFSYS_SUPPORT_BUS_HANG_READ_FROM_DRIVER_BASE */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +void soc3_0_show_ple_info( + struct ADAPTER *prAdapter, + u_int8_t fgDumpTxd) +{ + u_int32_t int_n9_err = 0; + u_int32_t int_n9_err1 = 0; + u_int32_t ple_buf_ctrl = 0, pg_sz, pg_num; + u_int32_t ple_stat[25] = {0}, pg_flow_ctrl[10] = {0}; + u_int32_t sta_pause[6] = {0}, dis_sta_map[6] = {0}; + u_int32_t fpg_cnt, ffa_cnt, fpg_head, fpg_tail, hif_max_q, hif_min_q; + u_int32_t rpg_hif, upg_hif, cpu_max_q, cpu_min_q, rpg_cpu, upg_cpu; + u_int32_t i, j; + u_int32_t ple_peek[12] = {0}; + u_int32_t ple_empty = 0; + u_int32_t ple_txd_empty = 0; + +#if 0 + u_int32_t ple_txcmd_stat; +#endif + + HAL_MCR_RD(prAdapter, WF_PLE_TOP_INT_N9_ERR_STS_ADDR, &int_n9_err); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR, &int_n9_err1); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_QUEUE_EMPTY_ADDR, &ple_empty); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR, &ple_txd_empty); + + HAL_MCR_RD(prAdapter, WF_PLE_TOP_PBUF_CTRL_ADDR, &ple_buf_ctrl); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_QUEUE_EMPTY_ADDR, &ple_stat[0]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC0_QUEUE_EMPTY0_ADDR, &ple_stat[1]); +#if 0 + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC0_QUEUE_EMPTY1_ADDR, &ple_stat[2]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC0_QUEUE_EMPTY2_ADDR, &ple_stat[3]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC0_QUEUE_EMPTY3_ADDR, &ple_stat[4]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC0_QUEUE_EMPTY4_ADDR, &ple_stat[5]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC0_QUEUE_EMPTY5_ADDR, &ple_stat[6]); +#endif + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC1_QUEUE_EMPTY0_ADDR, &ple_stat[7]); +#if 0 + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC1_QUEUE_EMPTY1_ADDR, &ple_stat[8]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC1_QUEUE_EMPTY2_ADDR, &ple_stat[9]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC1_QUEUE_EMPTY3_ADDR, &ple_stat[10]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC1_QUEUE_EMPTY4_ADDR, &ple_stat[11]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC1_QUEUE_EMPTY5_ADDR, &ple_stat[12]); +#endif + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC2_QUEUE_EMPTY0_ADDR, &ple_stat[13]); +#if 0 + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC2_QUEUE_EMPTY1_ADDR, &ple_stat[14]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC2_QUEUE_EMPTY2_ADDR, &ple_stat[15]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC2_QUEUE_EMPTY3_ADDR, &ple_stat[16]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC2_QUEUE_EMPTY4_ADDR, &ple_stat[17]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC2_QUEUE_EMPTY5_ADDR, &ple_stat[18]); +#endif + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC3_QUEUE_EMPTY0_ADDR, &ple_stat[19]); +#if 0 + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC3_QUEUE_EMPTY1_ADDR, &ple_stat[20]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC3_QUEUE_EMPTY2_ADDR, &ple_stat[21]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC3_QUEUE_EMPTY3_ADDR, &ple_stat[22]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC3_QUEUE_EMPTY4_ADDR, &ple_stat[23]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_AC3_QUEUE_EMPTY5_ADDR, &ple_stat[24]); +#endif +#if 0 + HAL_MCR_RD(prAdapter, WF_PLE_TOP_TXCMD_QUEUE_EMPTY_ADDR, + &ple_txcmd_stat); +#endif + HAL_MCR_RD(prAdapter, WF_PLE_TOP_FREEPG_CNT_ADDR, &pg_flow_ctrl[0]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_FREEPG_HEAD_TAIL_ADDR, + &pg_flow_ctrl[1]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_PG_HIF_GROUP_ADDR, &pg_flow_ctrl[2]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_HIF_PG_INFO_ADDR, &pg_flow_ctrl[3]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_PG_CPU_GROUP_ADDR, &pg_flow_ctrl[4]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_CPU_PG_INFO_ADDR, &pg_flow_ctrl[5]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_PG_HIF_TXCMD_GROUP_ADDR, + &pg_flow_ctrl[6]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_HIF_TXCMD_PG_INFO_ADDR, + &pg_flow_ctrl[7]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_PG_HIF_WMTXD_GROUP_ADDR, + &pg_flow_ctrl[8]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_HIF_WMTXD_PG_INFO_ADDR, + &pg_flow_ctrl[9]); + + HAL_MCR_RD(prAdapter, WF_PLE_TOP_DIS_STA_MAP0_ADDR, &dis_sta_map[0]); +#if 0 + HAL_MCR_RD(prAdapter, WF_PLE_TOP_DIS_STA_MAP1_ADDR, &dis_sta_map[1]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_DIS_STA_MAP2_ADDR, &dis_sta_map[2]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_DIS_STA_MAP3_ADDR, &dis_sta_map[3]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_DIS_STA_MAP4_ADDR, &dis_sta_map[4]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_DIS_STA_MAP5_ADDR, &dis_sta_map[5]); +#endif + HAL_MCR_RD(prAdapter, WF_PLE_TOP_STATION_PAUSE0_ADDR, &sta_pause[0]); +#if 0 + HAL_MCR_RD(prAdapter, WF_PLE_TOP_STATION_PAUSE1_ADDR, &sta_pause[1]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_STATION_PAUSE2_ADDR, &sta_pause[2]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_STATION_PAUSE3_ADDR, &sta_pause[3]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_STATION_PAUSE4_ADDR, &sta_pause[4]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_STATION_PAUSE5_ADDR, &sta_pause[5]); +#endif + + HAL_MCR_RD(prAdapter, WF_PLE_FSM_PEEK_CR_00, &ple_peek[0]); + HAL_MCR_RD(prAdapter, WF_PLE_FSM_PEEK_CR_01, &ple_peek[1]); + HAL_MCR_RD(prAdapter, WF_PLE_FSM_PEEK_CR_02, &ple_peek[2]); + HAL_MCR_RD(prAdapter, WF_PLE_FSM_PEEK_CR_03, &ple_peek[3]); + HAL_MCR_RD(prAdapter, WF_PLE_FSM_PEEK_CR_04, &ple_peek[4]); + HAL_MCR_RD(prAdapter, WF_PLE_FSM_PEEK_CR_05, &ple_peek[5]); + HAL_MCR_RD(prAdapter, WF_PLE_FSM_PEEK_CR_06, &ple_peek[6]); + HAL_MCR_RD(prAdapter, WF_PLE_FSM_PEEK_CR_07, &ple_peek[7]); + HAL_MCR_RD(prAdapter, WF_PLE_FSM_PEEK_CR_08, &ple_peek[8]); + HAL_MCR_RD(prAdapter, WF_PLE_FSM_PEEK_CR_09, &ple_peek[9]); + HAL_MCR_RD(prAdapter, WF_PLE_FSM_PEEK_CR_10, &ple_peek[10]); + HAL_MCR_RD(prAdapter, WF_PLE_FSM_PEEK_CR_11, &ple_peek[11]); + + /* Error Status Info */ + DBGLOG(HAL, INFO, + "PLE Error Status(0x%08x):0x%08x,Error Status1(0x%08x):0x%08x\n", + WF_PLE_TOP_INT_N9_ERR_STS_ADDR, int_n9_err, + WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR, int_n9_err1); + + /* FSM PEEK CR */ + DBGLOG(HAL, INFO, + "00(0x%08x):0x%08x,01(0x%08x):0x%08x,02(0x%08x):0x%08x,03(0x%08x):0x%08x,04(0x%08x):0x%08x,05(0x%08x):0x%08x,", + WF_PLE_FSM_PEEK_CR_00, ple_peek[0], + WF_PLE_FSM_PEEK_CR_01, ple_peek[1], + WF_PLE_FSM_PEEK_CR_02, ple_peek[2], + WF_PLE_FSM_PEEK_CR_03, ple_peek[3], + WF_PLE_FSM_PEEK_CR_04, ple_peek[4], + WF_PLE_FSM_PEEK_CR_05, ple_peek[5]); + + DBGLOG(HAL, INFO, + "06(0x%08x):0x%08x,07(0x%08x):0x%08x,08(0x%08x):0x%08x,09(0x%08x):0x%08x,10(0x%08x):0x%08x,11(0x%08x):0x%08x\n", + WF_PLE_FSM_PEEK_CR_06, ple_peek[6], + WF_PLE_FSM_PEEK_CR_07, ple_peek[7], + WF_PLE_FSM_PEEK_CR_08, ple_peek[8], + WF_PLE_FSM_PEEK_CR_09, ple_peek[9], + WF_PLE_FSM_PEEK_CR_10, ple_peek[10], + WF_PLE_FSM_PEEK_CR_11, ple_peek[11]); + + /* Configuration Info */ + + pg_sz = (ple_buf_ctrl & WF_PLE_TOP_PBUF_CTRL_PAGE_SIZE_CFG_MASK) >> + WF_PLE_TOP_PBUF_CTRL_PAGE_SIZE_CFG_SHFT; + pg_num = (ple_buf_ctrl & WF_PLE_TOP_PBUF_CTRL_TOTAL_PAGE_NUM_MASK) >> + WF_PLE_TOP_PBUF_CTRL_TOTAL_PAGE_NUM_SHFT; + + DBGLOG(HAL, INFO, + "Buffer Control(0x%08x):0x%08x,Page Size=%d, Page Offset=%d, Total Page=%d\n", + WF_PLE_TOP_PBUF_CTRL_ADDR, + ple_buf_ctrl, + pg_sz, + (ple_buf_ctrl & WF_PLE_TOP_PBUF_CTRL_PBUF_OFFSET_MASK) >> + WF_PLE_TOP_PBUF_CTRL_PBUF_OFFSET_SHFT, + pg_num); + + /* Flow-Control: Page Flow Control */ + fpg_cnt = (pg_flow_ctrl[0] & WF_PLE_TOP_FREEPG_CNT_FREEPG_CNT_MASK) >> + WF_PLE_TOP_FREEPG_CNT_FREEPG_CNT_SHFT; + ffa_cnt = (pg_flow_ctrl[0] & WF_PLE_TOP_FREEPG_CNT_FFA_CNT_MASK) >> + WF_PLE_TOP_FREEPG_CNT_FFA_CNT_SHFT; + + DBGLOG(HAL, INFO, + "Free page counter(0x%08x):0x%08x,The toal page number of free=0x%03x,The free page numbers of free for all=0x%03x\n", + WF_PLE_TOP_FREEPG_CNT_ADDR, + pg_flow_ctrl[0], fpg_cnt, ffa_cnt); + + /* PLE tail / head FID */ + fpg_head = (pg_flow_ctrl[1] & + WF_PLE_TOP_FREEPG_HEAD_TAIL_FREEPG_HEAD_MASK) >> + WF_PLE_TOP_FREEPG_HEAD_TAIL_FREEPG_HEAD_SHFT; + fpg_tail = (pg_flow_ctrl[1] & + WF_PLE_TOP_FREEPG_HEAD_TAIL_FREEPG_TAIL_MASK) >> + WF_PLE_TOP_FREEPG_HEAD_TAIL_FREEPG_TAIL_SHFT; + DBGLOG(HAL, INFO, + "Free page tail/head FID(0x%08x):0x%08x,The tail/head page of free page list=0x%03x/0x%03x\n", + WF_PLE_TOP_FREEPG_HEAD_TAIL_ADDR, + pg_flow_ctrl[1], fpg_tail, fpg_head); + + /* Flow-Control: Show PLE HIF Group information */ + DBGLOG(HAL, INFO, + "Reserved page counter of HIF group(0x%08x):0x%08x,status(0x%08x):0x%08x\n", + WF_PLE_TOP_PG_HIF_GROUP_ADDR, pg_flow_ctrl[2], + WF_PLE_TOP_HIF_PG_INFO_ADDR, pg_flow_ctrl[3]); + + hif_min_q = (pg_flow_ctrl[2] & + WF_PLE_TOP_PG_HIF_GROUP_HIF_MIN_QUOTA_MASK) >> + WF_PLE_TOP_PG_HIF_GROUP_HIF_MIN_QUOTA_SHFT; + hif_max_q = (pg_flow_ctrl[2] & + WF_PLE_TOP_PG_HIF_GROUP_HIF_MAX_QUOTA_MASK) >> + WF_PLE_TOP_PG_HIF_GROUP_HIF_MAX_QUOTA_SHFT; + DBGLOG(HAL, TRACE, + "\tThe max/min quota pages of HIF group=0x%03x/0x%03x\n", + hif_max_q, hif_min_q); + rpg_hif = (pg_flow_ctrl[3] & WF_PLE_TOP_HIF_PG_INFO_HIF_RSV_CNT_MASK) >> + WF_PLE_TOP_HIF_PG_INFO_HIF_RSV_CNT_SHFT; + upg_hif = (pg_flow_ctrl[3] & WF_PLE_TOP_HIF_PG_INFO_HIF_SRC_CNT_MASK) >> + WF_PLE_TOP_HIF_PG_INFO_HIF_SRC_CNT_SHFT; + DBGLOG(HAL, TRACE, + "\tThe used/reserved pages of HIF group=0x%03x/0x%03x\n", + upg_hif, rpg_hif); + + /* Flow-Control: Show PLE CPU Group information */ + DBGLOG(HAL, INFO, + "Reserved page counter of CPU group(0x%08x):0x%08x,status(0x%08x):0x%08x\n", + WF_PLE_TOP_PG_CPU_GROUP_ADDR, pg_flow_ctrl[4], + WF_PLE_TOP_CPU_PG_INFO_ADDR, pg_flow_ctrl[5]); + + cpu_min_q = (pg_flow_ctrl[4] & + WF_PLE_TOP_PG_CPU_GROUP_CPU_MIN_QUOTA_MASK) >> + WF_PLE_TOP_PG_CPU_GROUP_CPU_MIN_QUOTA_SHFT; + cpu_max_q = (pg_flow_ctrl[4] & + WF_PLE_TOP_PG_CPU_GROUP_CPU_MAX_QUOTA_MASK) >> + WF_PLE_TOP_PG_CPU_GROUP_CPU_MAX_QUOTA_SHFT; + DBGLOG(HAL, TRACE, + "\tThe max/min quota pages of CPU group=0x%03x/0x%03x\n", + cpu_max_q, cpu_min_q); + rpg_cpu = (pg_flow_ctrl[5] & WF_PLE_TOP_CPU_PG_INFO_CPU_RSV_CNT_MASK) >> + WF_PLE_TOP_CPU_PG_INFO_CPU_RSV_CNT_SHFT; + upg_cpu = (pg_flow_ctrl[5] & WF_PLE_TOP_CPU_PG_INFO_CPU_SRC_CNT_MASK) >> + WF_PLE_TOP_CPU_PG_INFO_CPU_SRC_CNT_SHFT; + DBGLOG(HAL, TRACE, + "\tThe used/reserved pages of CPU group=0x%03x/0x%03x\n", + upg_cpu, rpg_cpu); + + /* Flow-Control: Show PLE WMTXD Group information */ + DBGLOG(HAL, INFO, + "Reserved page counter of HIF_WMTXD group(0x%08x):0x%08x,status(0x%08x):0x%08x\n", + WF_PLE_TOP_PG_HIF_WMTXD_GROUP_ADDR, pg_flow_ctrl[8], + WF_PLE_TOP_HIF_WMTXD_PG_INFO_ADDR, pg_flow_ctrl[9]); + cpu_min_q = (pg_flow_ctrl[8] & + WF_PLE_TOP_PG_HIF_WMTXD_GROUP_HIF_WMTXD_MIN_QUOTA_MASK) >> + WF_PLE_TOP_PG_HIF_WMTXD_GROUP_HIF_WMTXD_MIN_QUOTA_SHFT; + cpu_max_q = (pg_flow_ctrl[8] & + WF_PLE_TOP_PG_HIF_WMTXD_GROUP_HIF_WMTXD_MAX_QUOTA_MASK) >> + WF_PLE_TOP_PG_HIF_WMTXD_GROUP_HIF_WMTXD_MAX_QUOTA_SHFT; + DBGLOG(HAL, TRACE, + "\tThe max/min quota pages of HIF_WMTXD group=0x%03x/0x%03x\n", + cpu_max_q, cpu_min_q); + rpg_cpu = (pg_flow_ctrl[9] & + WF_PLE_TOP_HIF_WMTXD_PG_INFO_HIF_WMTXD_RSV_CNT_MASK) >> + WF_PLE_TOP_HIF_WMTXD_PG_INFO_HIF_WMTXD_RSV_CNT_SHFT; + upg_cpu = (pg_flow_ctrl[9] & + WF_PLE_TOP_HIF_WMTXD_PG_INFO_HIF_WMTXD_SRC_CNT_MASK) >> + WF_PLE_TOP_HIF_WMTXD_PG_INFO_HIF_WMTXD_SRC_CNT_SHFT; + DBGLOG(HAL, TRACE, + "\tThe used/reserved pages of HIF_WMTXD group=0x%03x/0x%03x\n", + upg_cpu, rpg_cpu); + + /* Flow-Control: Show PLE TXCMD Group information */ + DBGLOG(HAL, INFO, + "Reserved page counter of HIF_TXCMD group(0x%08x):0x%08x,status(0x%08x):0x%08x\n", + WF_PLE_TOP_PG_HIF_TXCMD_GROUP_ADDR, pg_flow_ctrl[6], + WF_PLE_TOP_HIF_TXCMD_PG_INFO_ADDR, pg_flow_ctrl[7]); + cpu_min_q = (pg_flow_ctrl[6] & + WF_PLE_TOP_PG_HIF_TXCMD_GROUP_HIF_TXCMD_MIN_QUOTA_MASK) >> + WF_PLE_TOP_PG_HIF_TXCMD_GROUP_HIF_TXCMD_MIN_QUOTA_SHFT; + cpu_max_q = (pg_flow_ctrl[6] & + WF_PLE_TOP_PG_HIF_TXCMD_GROUP_HIF_TXCMD_MAX_QUOTA_MASK) >> + WF_PLE_TOP_PG_HIF_TXCMD_GROUP_HIF_TXCMD_MAX_QUOTA_SHFT; + DBGLOG(HAL, TRACE, + "\t\tThe max/min quota pages of HIF_TXCMD group=0x%03x/0x%03x\n", + cpu_max_q, cpu_min_q); + rpg_cpu = (pg_flow_ctrl[7] & + WF_PLE_TOP_HIF_TXCMD_PG_INFO_HIF_TXCMD_SRC_CNT_MASK) >> + WF_PLE_TOP_HIF_TXCMD_PG_INFO_HIF_TXCMD_SRC_CNT_SHFT; + upg_cpu = (pg_flow_ctrl[7] & + WF_PLE_TOP_HIF_TXCMD_PG_INFO_HIF_TXCMD_RSV_CNT_MASK) >> + WF_PLE_TOP_HIF_TXCMD_PG_INFO_HIF_TXCMD_RSV_CNT_SHFT; + DBGLOG(HAL, TRACE, + "\t\tThe used/reserved pages of HIF_TXCMD group=0x%03x/0x%03x\n", + upg_cpu, rpg_cpu); + + if ((ple_stat[0] & WF_PLE_TOP_QUEUE_EMPTY_ALL_AC_EMPTY_MASK) == 0) { + for (j = 0; j < 24; j = j + 6) { + if (j % 6 == 0) { + DBGLOG(HAL, INFO, + "\tNonempty AC%d Q of STA#: ", j / 6); + } + + for (i = 0; i < 32; i++) { + if (((ple_stat[j + 1] & (0x1 << i)) >> i) == + 0) { + DBGLOG(HAL, INFO, "%d ", + i + (j % 6) * 32); + } + } + } + DBGLOG(HAL, INFO, ", "); + } + + /* Queue Empty Status */ + DBGLOG(HAL, INFO, + "QUEUE_EMPTY(0x%08x):0x%08xTXD QUEUE_EMPTY(0x%08x):0x%08x\n", + WF_PLE_TOP_QUEUE_EMPTY_ADDR, ple_empty, + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR, ple_txd_empty); + + /* Nonempty Queue Status */ + DBGLOG(HAL, INFO, "Nonempty Q info:"); + + for (i = 0; i < 31; i++) { + if (((ple_stat[0] & (0x1 << i)) >> i) == 0) { + uint32_t hfid, tfid, pktcnt, fl_que_ctrl[3] = {0}; + + if (ple_queue_empty_info[i].QueueName != NULL) { + DBGLOG(HAL, INFO, "\t%s: ", + ple_queue_empty_info[i].QueueName); + fl_que_ctrl[0] |= + WF_PLE_TOP_FL_QUE_CTRL_0_EXECUTE_MASK; + fl_que_ctrl[0] |= + (ple_queue_empty_info[i].Portid + << WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_PID_SHFT); + fl_que_ctrl[0] |= + (ple_queue_empty_info[i].Queueid + << WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_QID_SHFT); + } else + continue; + + HAL_MCR_WR(prAdapter, WF_PLE_TOP_FL_QUE_CTRL_0_ADDR, + fl_que_ctrl[0]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_FL_QUE_CTRL_2_ADDR, + &fl_que_ctrl[1]); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_FL_QUE_CTRL_3_ADDR, + &fl_que_ctrl[2]); + hfid = (fl_que_ctrl[1] & + WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_HEAD_FID_MASK) >> + WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_HEAD_FID_SHFT; + tfid = (fl_que_ctrl[1] & + WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_TAIL_FID_MASK) >> + WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_TAIL_FID_SHFT; + pktcnt = + (fl_que_ctrl[2] & + WF_PLE_TOP_FL_QUE_CTRL_3_QUEUE_PKT_NUM_MASK) >> + WF_PLE_TOP_FL_QUE_CTRL_3_QUEUE_PKT_NUM_SHFT; + DBGLOG(HAL, INFO, + "tail/head fid = 0x%03x/0x%03x, pkt cnt = 0x%03x\n", + tfid, hfid, pktcnt); + if (pktcnt > 0 && fgDumpTxd) + connac2x_show_txd_Info( + prAdapter, hfid); + } + } + + for (j = 0; j < 24; j = j + 6) { /* show AC Q info */ + for (i = 0; i < 32; i++) { + if (((ple_stat[j + 1] & (0x1 << i)) >> i) == 0) { + uint32_t hfid, tfid, pktcnt, ac_num = j / 6, + ctrl = 0; + uint32_t sta_num = i + (j % 6) * 32, + fl_que_ctrl[3] = {0}; + uint32_t wmmidx = 0; + + DBGLOG(HAL, INFO, "\tSTA%d AC%d: ", sta_num, + ac_num); + + fl_que_ctrl[0] |= + WF_PLE_TOP_FL_QUE_CTRL_0_EXECUTE_MASK; + fl_que_ctrl[0] |= + (ENUM_UMAC_LMAC_PORT_2 + << WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_PID_SHFT); + fl_que_ctrl[0] |= + (ac_num + << WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_QID_SHFT); + fl_que_ctrl[0] |= + (sta_num + << WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_WLANID_SHFT); + HAL_MCR_WR(prAdapter, + WF_PLE_TOP_FL_QUE_CTRL_0_ADDR, + fl_que_ctrl[0]); + HAL_MCR_RD(prAdapter, + WF_PLE_TOP_FL_QUE_CTRL_2_ADDR, + &fl_que_ctrl[1]); + HAL_MCR_RD(prAdapter, + WF_PLE_TOP_FL_QUE_CTRL_3_ADDR, + &fl_que_ctrl[2]); + hfid = (fl_que_ctrl[1] & + WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_HEAD_FID_MASK) >> + WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_HEAD_FID_SHFT; + tfid = (fl_que_ctrl[1] & + WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_TAIL_FID_MASK) >> + WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_TAIL_FID_SHFT; + + pktcnt = + (fl_que_ctrl[2] & + WF_PLE_TOP_FL_QUE_CTRL_3_QUEUE_PKT_NUM_MASK) >> + WF_PLE_TOP_FL_QUE_CTRL_3_QUEUE_PKT_NUM_SHFT; + DBGLOG(HAL, INFO, + "tail/head fid = 0x%03x/0x%03x, pkt cnt = %x", + tfid, hfid, pktcnt); + + if (((sta_pause[j % 6] & 0x1 << i) >> i) == 1) + ctrl = 2; + + if (((dis_sta_map[j % 6] & 0x1 << i) >> i) == 1) + ctrl = 1; + + DBGLOG(HAL, INFO, " ctrl = %s", + sta_ctrl_reg[ctrl]); + DBGLOG(HAL, INFO, " (wmmidx=%d)\n", + wmmidx); + if (pktcnt > 0 && fgDumpTxd) + connac2x_show_txd_Info( + prAdapter, hfid); + } + } + } +#if 0 + if (~ple_txcmd_stat) { + DBGLOG(HAL, INFO, "Nonempty TXCMD Q info:\n"); + for (i = 0; i < 31; i++) { + if (((ple_txcmd_stat & (0x1 << i)) >> i) == 0) { + uint32_t hfid, tfid; + uint32_t pktcnt, fl_que_ctrl[3] = {0}; + + if (ple_txcmd_queue_empty_info[i].QueueName != + NULL) { + DBGLOG(HAL, INFO, "\t%s: ", + ple_txcmd_queue_empty_info[i] + .QueueName); + fl_que_ctrl[0] |= + WF_PLE_TOP_FL_QUE_CTRL_0_EXECUTE_MASK; + fl_que_ctrl[0] |= + (ple_txcmd_queue_empty_info[i] + .Portid + << WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_PID_SHFT); + fl_que_ctrl[0] |= + (ple_txcmd_queue_empty_info[i] + .Queueid + << WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_QID_SHFT); + } else + continue; + + HAL_MCR_WR(prAdapter, + WF_PLE_TOP_FL_QUE_CTRL_0_ADDR, + fl_que_ctrl[0]); + HAL_MCR_RD(prAdapter, + WF_PLE_TOP_FL_QUE_CTRL_2_ADDR, + &fl_que_ctrl[1]); + HAL_MCR_RD(prAdapter, + WF_PLE_TOP_FL_QUE_CTRL_3_ADDR, + &fl_que_ctrl[2]); + hfid = (fl_que_ctrl[1] & + WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_HEAD_FID_MASK) >> + WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_HEAD_FID_SHFT; + tfid = (fl_que_ctrl[1] & + WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_TAIL_FID_MASK) >> + WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_TAIL_FID_SHFT; + pktcnt = + (fl_que_ctrl[2] & + WF_PLE_TOP_FL_QUE_CTRL_3_QUEUE_PKT_NUM_MASK) >> + WF_PLE_TOP_FL_QUE_CTRL_3_QUEUE_PKT_NUM_SHFT; + DBGLOG(HAL, INFO, "tail/head fid ="); + DBGLOG(HAL, INFO, "0x%03x/0x%03x,", tfid, hfid); + DBGLOG(HAL, INFO, "pkt cnt = 0x%03x\n", pktcnt); + } + } + } +#endif +} + +void soc3_0_show_pse_info( + struct ADAPTER *prAdapter) +{ + u_int32_t int_n9_err = 0; + u_int32_t int_n9_err1 = 0; + u_int32_t pse_buf_ctrl = 0; + u_int32_t pg_sz = 0; + u_int32_t pg_num = 0; + u_int32_t pse_stat = 0; + u_int32_t pse_stat_mask = 0; + u_int32_t fpg_cnt, ffa_cnt, fpg_head, fpg_tail; + u_int32_t max_q, min_q, rsv_pg, used_pg; + u_int32_t i, group_cnt; + u_int32_t group_quota = 0; + u_int32_t group_info = 0; + u_int32_t freepg_cnt = 0; + u_int32_t freepg_head_tail = 0; + struct pse_group_info *group; + char *str; + u_int32_t pse_peek[10] = {0}; + + HAL_MCR_RD(prAdapter, WF_PSE_TOP_PBUF_CTRL_ADDR, &pse_buf_ctrl); + HAL_MCR_RD(prAdapter, WF_PSE_TOP_QUEUE_EMPTY_ADDR, &pse_stat); + HAL_MCR_RD(prAdapter, WF_PSE_TOP_QUEUE_EMPTY_MASK_ADDR, &pse_stat_mask); + HAL_MCR_RD(prAdapter, WF_PSE_TOP_FREEPG_CNT_ADDR, &freepg_cnt); + HAL_MCR_RD(prAdapter, WF_PSE_TOP_FREEPG_HEAD_TAIL_ADDR, + &freepg_head_tail); + + HAL_MCR_RD(prAdapter, WF_PSE_TOP_INT_N9_ERR_STS_ADDR, &int_n9_err); + HAL_MCR_RD(prAdapter, WF_PSE_TOP_INT_N9_ERR1_STS_ADDR, &int_n9_err1); + + HAL_MCR_RD(prAdapter, WF_PSE_FSM_PEEK_CR_00, &pse_peek[0]); + HAL_MCR_RD(prAdapter, WF_PSE_FSM_PEEK_CR_01, &pse_peek[1]); + HAL_MCR_RD(prAdapter, WF_PSE_FSM_PEEK_CR_02, &pse_peek[2]); + HAL_MCR_RD(prAdapter, WF_PSE_FSM_PEEK_CR_03, &pse_peek[3]); + HAL_MCR_RD(prAdapter, WF_PSE_FSM_PEEK_CR_04, &pse_peek[4]); + HAL_MCR_RD(prAdapter, WF_PSE_FSM_PEEK_CR_05, &pse_peek[5]); + HAL_MCR_RD(prAdapter, WF_PSE_FSM_PEEK_CR_06, &pse_peek[6]); + HAL_MCR_RD(prAdapter, WF_PSE_FSM_PEEK_CR_07, &pse_peek[7]); + HAL_MCR_RD(prAdapter, WF_PSE_FSM_PEEK_CR_08, &pse_peek[8]); + HAL_MCR_RD(prAdapter, WF_PSE_FSM_PEEK_CR_09, &pse_peek[9]); + + /* Error Status Info */ + DBGLOG(HAL, INFO, + "PSE Error Status(0x%08x):0x%08x,PSE Error 1 Status(0x%08x):0x%08x\n", + WF_PSE_TOP_INT_N9_ERR_STS_ADDR, int_n9_err, + WF_PSE_TOP_INT_N9_ERR1_STS_ADDR, int_n9_err1); + + DBGLOG(HAL, INFO, + "00(0x%08x):0x%08x,01(0x%08x):0x%08x02(0x%08x):0x%08x,03(0x%08x):0x%08x04(0x%08x):0x%08x,05(0x%08x):0x%08x\n", + WF_PSE_FSM_PEEK_CR_00, pse_peek[0], + WF_PSE_FSM_PEEK_CR_01, pse_peek[1], + WF_PSE_FSM_PEEK_CR_02, pse_peek[2], + WF_PSE_FSM_PEEK_CR_03, pse_peek[3], + WF_PSE_FSM_PEEK_CR_04, pse_peek[4], + WF_PSE_FSM_PEEK_CR_05, pse_peek[5]); + + DBGLOG(HAL, INFO, + "06(0x%08x):0x%08x,07(0x%08x):0x%08x08(0x%08x):0x%08x,09(0x%08x):0x%08x\n", + WF_PSE_FSM_PEEK_CR_06, pse_peek[6], + WF_PSE_FSM_PEEK_CR_07, pse_peek[7], + WF_PSE_FSM_PEEK_CR_08, pse_peek[8], + WF_PSE_FSM_PEEK_CR_09, pse_peek[9]); + + /* Configuration Info */ + pg_sz = (pse_buf_ctrl & WF_PSE_TOP_PBUF_CTRL_PAGE_SIZE_CFG_MASK) >> + WF_PSE_TOP_PBUF_CTRL_PAGE_SIZE_CFG_SHFT; + pg_num = (pse_buf_ctrl & WF_PSE_TOP_PBUF_CTRL_TOTAL_PAGE_NUM_MASK) >> + WF_PSE_TOP_PBUF_CTRL_TOTAL_PAGE_NUM_SHFT; + + DBGLOG(HAL, INFO, + "Packet Buffer Control(0x%08x): 0x%08x,Page Size=%d, Page Offset=%d, Total page=%d\n", + WF_PSE_TOP_PBUF_CTRL_ADDR, + pse_buf_ctrl, pg_sz, + ((pse_buf_ctrl & WF_PSE_TOP_PBUF_CTRL_PBUF_OFFSET_MASK) >> + WF_PSE_TOP_PBUF_CTRL_PBUF_OFFSET_SHFT), + pg_num); + + /* Page Flow Control */ + fpg_cnt = (freepg_cnt & WF_PSE_TOP_FREEPG_CNT_FREEPG_CNT_MASK) >> + WF_PSE_TOP_FREEPG_CNT_FREEPG_CNT_SHFT; + + ffa_cnt = (freepg_cnt & WF_PSE_TOP_FREEPG_CNT_FFA_CNT_MASK) >> + WF_PSE_TOP_FREEPG_CNT_FFA_CNT_SHFT; + + + DBGLOG(HAL, INFO, + "Free page counter(0x%08x): 0x%08x,The toal page number of free=0x%03x,The free page numbers of free for all=0x%03x\n", + WF_PSE_TOP_FREEPG_CNT_ADDR, freepg_cnt, + fpg_cnt, ffa_cnt); + + /* PLE tail / head FID */ + fpg_head = (freepg_head_tail & + WF_PSE_TOP_FREEPG_HEAD_TAIL_FREEPG_HEAD_MASK) >> + WF_PSE_TOP_FREEPG_HEAD_TAIL_FREEPG_HEAD_SHFT; + fpg_tail = (freepg_head_tail & + WF_PSE_TOP_FREEPG_HEAD_TAIL_FREEPG_TAIL_MASK) >> + WF_PSE_TOP_FREEPG_HEAD_TAIL_FREEPG_TAIL_SHFT; + + DBGLOG(HAL, INFO, + "Free page tail/head(0x%08x): 0x%08x,The tail/head page of free page list=0x%03x/0x%03x\n", + WF_PSE_TOP_FREEPG_HEAD_TAIL_ADDR, freepg_head_tail, + fpg_tail, fpg_head); + + /*Each Group page status */ + group_cnt = sizeof(pse_group) / sizeof(struct pse_group_info); + for (i = 0; i < group_cnt; i++) { + group = &pse_group[i]; + HAL_MCR_RD(prAdapter, group->quota_addr, &group_quota); + HAL_MCR_RD(prAdapter, group->pg_info_addr, &group_info); + + DBGLOG(HAL, INFO, + "Reserved page counter of %s group(0x%08x):0x%08x,status(0x%08x):0x%08x\n", + group->name, group->quota_addr, group_quota, + group->pg_info_addr, group_info); + min_q = (group_quota & + WF_PSE_TOP_PG_HIF0_GROUP_HIF0_MIN_QUOTA_MASK) >> + WF_PSE_TOP_PG_HIF0_GROUP_HIF0_MIN_QUOTA_SHFT; + max_q = (group_quota & + WF_PSE_TOP_PG_HIF0_GROUP_HIF0_MAX_QUOTA_MASK) >> + WF_PSE_TOP_PG_HIF0_GROUP_HIF0_MAX_QUOTA_SHFT; + DBGLOG(HAL, TRACE, + "\tThe max/min quota pages of %s group=0x%03x/0x%03x\n", + group->name, max_q, min_q); + rsv_pg = + (group_info & WF_PSE_TOP_HIF0_PG_INFO_HIF0_RSV_CNT_MASK) >> + WF_PSE_TOP_HIF0_PG_INFO_HIF0_RSV_CNT_SHFT; + used_pg = + (group_info & WF_PSE_TOP_HIF0_PG_INFO_HIF0_SRC_CNT_MASK) >> + WF_PSE_TOP_HIF0_PG_INFO_HIF0_SRC_CNT_SHFT; + DBGLOG(HAL, TRACE, + "\tThe used/reserved pages of %s group=0x%03x/0x%03x\n", + group->name, used_pg, rsv_pg); + } + + /* Queue Empty Status */ + DBGLOG(HAL, INFO, + "QUEUE_EMPTY(0x%08x):0x%08x,QUEUE_EMPTY_MASK(0x%08x):0x%08x\n", + WF_PSE_TOP_QUEUE_EMPTY_ADDR, pse_stat, + WF_PSE_TOP_QUEUE_EMPTY_MASK_ADDR, pse_stat_mask); + + DBGLOG(HAL, TRACE, "\t\tCPU Q0/1/2/3 empty=%d/%d/%d/%d\n", + (pse_stat & WF_PSE_TOP_QUEUE_EMPTY_CPU_Q0_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_CPU_Q0_EMPTY_SHFT, + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_CPU_Q1_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_CPU_Q1_EMPTY_SHFT), + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_CPU_Q2_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_CPU_Q2_EMPTY_SHFT), + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_CPU_Q3_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_CPU_Q3_EMPTY_SHFT)); + str = "\t\tHIF Q0/1/2/3/4/5/6/7/8/9/10/11"; + DBGLOG(HAL, TRACE, + "%s empty=%d/%d/%d/%d/%d/%d/%d/%d/%d/%d/%d/%d\n", str, + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_HIF_0_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_HIF_0_EMPTY_SHFT), + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_HIF_1_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_HIF_1_EMPTY_SHFT), + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_HIF_2_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_HIF_2_EMPTY_SHFT), + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_HIF_3_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_HIF_3_EMPTY_SHFT), + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_HIF_4_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_HIF_4_EMPTY_SHFT), + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_HIF_5_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_HIF_5_EMPTY_SHFT), + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_HIF_6_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_HIF_6_EMPTY_SHFT), + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_HIF_7_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_HIF_7_EMPTY_SHFT), + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_HIF_8_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_HIF_8_EMPTY_SHFT), + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_HIF_9_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_HIF_9_EMPTY_SHFT), + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_HIF_10_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_HIF_10_EMPTY_SHFT), + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_HIF_11_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_HIF_11_EMPTY_SHFT)); + DBGLOG(HAL, TRACE, "\t\tLMAC TX Q empty=%d\n", + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_LMAC_TX_QUEUE_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_LMAC_TX_QUEUE_EMPTY_SHFT)); + DBGLOG(HAL, TRACE, "\t\tMDP TX Q/RX Q empty=%d/%d\n", + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_MDP_TX_QUEUE_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_MDP_TX_QUEUE_EMPTY_SHFT), + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_MDP_RX_QUEUE_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_MDP_RX_QUEUE_EMPTY_SHFT)); + DBGLOG(HAL, TRACE, "\t\tSEC TX Q/RX Q empty=%d/%d\n", + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_SEC_TX_QUEUE_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_SEC_TX_QUEUE_EMPTY_SHFT), + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_SEC_RX_QUEUE_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_SEC_RX_QUEUE_EMPTY_SHFT)); + DBGLOG(HAL, TRACE, "\t\tSFD PARK Q empty=%d\n", + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_SFD_PARK_QUEUE_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_SFD_PARK_QUEUE_EMPTY_SHFT)); + DBGLOG(HAL, TRACE, "\t\tMDP TXIOC Q/RXIOC Q empty=%d/%d\n", + ((pse_stat & + WF_PSE_TOP_QUEUE_EMPTY_MDP_TXIOC_QUEUE_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_MDP_TXIOC_QUEUE_EMPTY_SHFT), + ((pse_stat & + WF_PSE_TOP_QUEUE_EMPTY_MDP_RXIOC_QUEUE_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_MDP_RXIOC_QUEUE_EMPTY_SHFT)); + DBGLOG(HAL, TRACE, "\t\tMDP TX1 Q empty=%d\n", + ((pse_stat & + WF_PSE_TOP_QUEUE_EMPTY_MDP_TX1_QUEUE_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_MDP_TX1_QUEUE_EMPTY_SHFT)); + DBGLOG(HAL, TRACE, "\t\tSEC TX1 Q empty=%d\n", + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_SEC_TX1_QUEUE_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_SEC_TX1_QUEUE_EMPTY_SHFT)); + DBGLOG(HAL, TRACE, "\t\tMDP TXIOC1 Q/RXIOC1 Q empty=%d/%d\n", + ((pse_stat & + WF_PSE_TOP_QUEUE_EMPTY_MDP_TXIOC1_QUEUE_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_MDP_TXIOC1_QUEUE_EMPTY_SHFT), + ((pse_stat & + WF_PSE_TOP_QUEUE_EMPTY_MDP_RXIOC1_QUEUE_EMPTY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_MDP_RXIOC1_QUEUE_EMPTY_SHFT)); + DBGLOG(HAL, TRACE, "\t\tRLS Q empty=%d\n", + ((pse_stat & WF_PSE_TOP_QUEUE_EMPTY_RLS_Q_EMTPY_MASK) >> + WF_PSE_TOP_QUEUE_EMPTY_RLS_Q_EMTPY_SHFT)); + + /* Nonempty Queue Status */ + DBGLOG(HAL, INFO, "Nonempty Q info:"); + for (i = 0; i < 31; i++) { + if (((pse_stat & (0x1 << i)) >> i) == 0) { + uint32_t hfid, tfid, pktcnt, fl_que_ctrl[3] = {0}; + + if (pse_queue_empty_info[i].QueueName != NULL) { + DBGLOG(HAL, INFO, "\t%s: ", + pse_queue_empty_info[i].QueueName); + fl_que_ctrl[0] |= + WF_PSE_TOP_FL_QUE_CTRL_0_EXECUTE_MASK; + fl_que_ctrl[0] |= + (pse_queue_empty_info[i].Portid + << WF_PSE_TOP_FL_QUE_CTRL_0_Q_BUF_PID_SHFT); + fl_que_ctrl[0] |= + (pse_queue_empty_info[i].Queueid + << WF_PSE_TOP_FL_QUE_CTRL_0_Q_BUF_QID_SHFT); + } else + continue; + + fl_que_ctrl[0] |= (0x1 << 31); + HAL_MCR_WR(prAdapter, WF_PSE_TOP_FL_QUE_CTRL_0_ADDR, + fl_que_ctrl[0]); + HAL_MCR_RD(prAdapter, WF_PSE_TOP_FL_QUE_CTRL_2_ADDR, + &fl_que_ctrl[1]); + HAL_MCR_RD(prAdapter, WF_PSE_TOP_FL_QUE_CTRL_3_ADDR, + &fl_que_ctrl[2]); + hfid = (fl_que_ctrl[1] & + WF_PSE_TOP_FL_QUE_CTRL_2_QUEUE_HEAD_FID_MASK) >> + WF_PSE_TOP_FL_QUE_CTRL_2_QUEUE_HEAD_FID_SHFT; + tfid = (fl_que_ctrl[1] & + WF_PSE_TOP_FL_QUE_CTRL_2_QUEUE_TAIL_FID_MASK) >> + WF_PSE_TOP_FL_QUE_CTRL_2_QUEUE_TAIL_FID_SHFT; + pktcnt = + (fl_que_ctrl[2] & + WF_PSE_TOP_FL_QUE_CTRL_3_QUEUE_PKT_NUM_MASK) >> + WF_PSE_TOP_FL_QUE_CTRL_3_QUEUE_PKT_NUM_SHFT; + DBGLOG(HAL, INFO, + "tail/head fid = 0x%03x/0x%03x, pkt cnt = 0x%03x\n", + tfid, hfid, pktcnt); + } + } +} + +static void DumpPPDebugCr(struct ADAPTER *prAdapter) +{ + uint32_t ReadRegValue[4]; + uint32_t u4Value[4] = {0}; + + /* 0x820CC0F0 : PP DBG_CTRL */ + ReadRegValue[0] = 0x820CC0F0; + HAL_MCR_RD(prAdapter, ReadRegValue[0], &u4Value[0]); + + /* 0x820CC0F8 : PP DBG_CS0 */ + ReadRegValue[1] = 0x820CC0F8; + HAL_MCR_RD(prAdapter, ReadRegValue[1], &u4Value[1]); + + /* 0x820CC0FC : PP DBG_CS1 */ + ReadRegValue[2] = 0x820CC0FC; + HAL_MCR_RD(prAdapter, ReadRegValue[2], &u4Value[2]); + + /* 0x820CC100 : PP DBG_CS2 */ + ReadRegValue[3] = 0x820CC100; + HAL_MCR_RD(prAdapter, ReadRegValue[3], &u4Value[3]); + + DBGLOG(HAL, INFO, + "PP[0x%08x]=0x%08x,[0x%08x]=0x%08x,[0x%08x]=0x%08x,[0x%08x]=0x%08x,", + ReadRegValue[0], u4Value[0], + ReadRegValue[1], u4Value[1], + ReadRegValue[2], u4Value[2], + ReadRegValue[3], u4Value[3]); +} + +void show_wfdma_interrupt_info( + IN struct ADAPTER *prAdapter, + IN enum _ENUM_WFDMA_TYPE_T enum_wfdma_type) +{ + uint32_t idx; + uint32_t u4hostBaseCrAddr; + uint32_t u4DmaCfgCrAddr = 0; + uint32_t u4DmaCfgCrAddrByWFDMA[CONNAC2X_WFDMA_COUNT]; + uint32_t u4RegValue = 0; + uint32_t u4RegValueByWFDMA[CONNAC2X_WFDMA_COUNT] = {0}; + + /* Dump Interrupt Status info */ + if (enum_wfdma_type == WFDMA_TYPE_HOST) { + /* Dump Global Status CR only in WFMDA HOST*/ + u4hostBaseCrAddr = CONNAC2X_HOST_EXT_CONN_HIF_WRAP; + + u4DmaCfgCrAddr = CONNAC2X_WPDMA_EXT_INT_STA(u4hostBaseCrAddr); + HAL_MCR_RD(prAdapter, u4DmaCfgCrAddr, &u4RegValue); + } + + /* Dump PDMA Status CR */ + for (idx = 0; idx < CONNAC2X_WFDMA_COUNT; idx++) { + + if (enum_wfdma_type == WFDMA_TYPE_HOST) + u4hostBaseCrAddr = idx ? + CONNAC2X_HOST_WPDMA_1_BASE : + CONNAC2X_HOST_WPDMA_0_BASE; + else + u4hostBaseCrAddr = idx ? + CONNAC2X_MCU_WPDMA_1_BASE : + CONNAC2X_MCU_WPDMA_0_BASE; + + u4DmaCfgCrAddrByWFDMA[idx] = + CONNAC2X_WPDMA_INT_STA(u4hostBaseCrAddr); + + HAL_MCR_RD(prAdapter, + u4DmaCfgCrAddrByWFDMA[idx], &u4RegValueByWFDMA[idx]); + } + + DBGLOG(INIT, INFO, + "G_INT_S(0x%08x):0x%08x,W_%d(0x%08x):0x%08x, W_%d(0x%08x):0x%08x\n", + u4DmaCfgCrAddr, u4RegValue, + 0, u4DmaCfgCrAddrByWFDMA[0], u4RegValueByWFDMA[0], + 1, u4DmaCfgCrAddrByWFDMA[1], u4RegValueByWFDMA[1]); + + /* Dump Interrupt Enable Info */ + if (enum_wfdma_type == WFDMA_TYPE_HOST) { + + /* Dump Global Enable CR */ + u4hostBaseCrAddr = CONNAC2X_HOST_EXT_CONN_HIF_WRAP; + + u4DmaCfgCrAddr = CONNAC2X_WPDMA_EXT_INT_MASK(u4hostBaseCrAddr); + + HAL_MCR_RD(prAdapter, u4DmaCfgCrAddr, &u4RegValue); + } + + /* Dump PDMA Enable CR */ + for (idx = 0; idx < CONNAC2X_WFDMA_COUNT; idx++) { + + if (enum_wfdma_type == WFDMA_TYPE_HOST) + u4hostBaseCrAddr = idx ? + CONNAC2X_HOST_WPDMA_1_BASE : + CONNAC2X_HOST_WPDMA_0_BASE; + else + u4hostBaseCrAddr = idx ? + CONNAC2X_MCU_WPDMA_1_BASE : + CONNAC2X_MCU_WPDMA_0_BASE; + + u4DmaCfgCrAddrByWFDMA[idx] = + CONNAC2X_WPDMA_INT_MASK(u4hostBaseCrAddr); + + HAL_MCR_RD(prAdapter, + u4DmaCfgCrAddrByWFDMA[idx], &u4RegValueByWFDMA[idx]); + } + + DBGLOG(INIT, INFO, + "G_INT_E(0x%08x):0x%08x,W_%d(0x%08x):0x%08x, W_%d(0x%08x):0x%08x\n", + u4DmaCfgCrAddr, u4RegValue, + 0, u4DmaCfgCrAddrByWFDMA[0], u4RegValueByWFDMA[0], + 1, u4DmaCfgCrAddrByWFDMA[1], u4RegValueByWFDMA[1]); +} + +void show_wfdma_glo_info( + IN struct ADAPTER *prAdapter, + IN enum _ENUM_WFDMA_TYPE_T enum_wfdma_type) +{ + uint32_t idx; + uint32_t u4hostBaseCrAddr; + uint32_t u4DmaCfgCrAddr = 0; + union WPDMA_GLO_CFG_STRUCT GloCfgValue; + + for (idx = 0; idx < CONNAC2X_WFDMA_COUNT; idx++) { + + if (enum_wfdma_type == WFDMA_TYPE_HOST) + u4hostBaseCrAddr = idx ? + CONNAC2X_HOST_WPDMA_1_BASE : + CONNAC2X_HOST_WPDMA_0_BASE; + else + u4hostBaseCrAddr = idx ? + CONNAC2X_MCU_WPDMA_1_BASE : + CONNAC2X_MCU_WPDMA_0_BASE; + + u4DmaCfgCrAddr = CONNAC2X_WPDMA_GLO_CFG(u4hostBaseCrAddr); + + HAL_MCR_RD(prAdapter, u4DmaCfgCrAddr, &GloCfgValue.word); + + DBGLOG(INIT, INFO, + "WFDMA_%d GLO(0x%08x):0x%08x,EN T/R=(%d/%d), Busy T/R=(%d/%d)\n", + idx, u4DmaCfgCrAddr, GloCfgValue.word, + GloCfgValue.field_conn2x.tx_dma_en, + GloCfgValue.field_conn2x.rx_dma_en, + GloCfgValue.field_conn2x.tx_dma_busy, + GloCfgValue.field_conn2x.rx_dma_busy); + } + +} + +void show_wfdma_ring_info( + IN struct ADAPTER *prAdapter, + IN enum _ENUM_WFDMA_TYPE_T enum_wfdma_type) +{ + + uint32_t idx; + uint32_t group_cnt; + uint32_t u4DmaCfgCrAddr = 0; + struct wfdma_group_info *group; + uint32_t u4_hw_desc_base_value = 0; + uint32_t u4_hw_cnt_value = 0; + uint32_t u4_hw_cidx_value = 0; + uint32_t u4_hw_didx_value = 0; + uint32_t queue_cnt; + + /* Dump All TX Ring Info */ + DBGLOG(HAL, INFO, "----------- TX Ring Config -----------\n"); + DBGLOG(HAL, INFO, "%4s %16s %8s %10s %6s %6s %6s %6s\n", + "Idx", "Attr", "Reg", "Base", "Cnt", "CIDX", "DIDX", "QCnt"); + + /* Dump TX Ring */ + if (enum_wfdma_type == WFDMA_TYPE_HOST) + group_cnt = sizeof(wfmda_host_tx_group) / + sizeof(struct wfdma_group_info); + else + group_cnt = sizeof(wfmda_wm_tx_group) / + sizeof(struct wfdma_group_info); + + for (idx = 0; idx < group_cnt; idx++) { + if (enum_wfdma_type == WFDMA_TYPE_HOST) + group = &wfmda_host_tx_group[idx]; + else + group = &wfmda_wm_tx_group[idx]; + + u4DmaCfgCrAddr = group->hw_desc_base; + + HAL_MCR_RD(prAdapter, u4DmaCfgCrAddr, &u4_hw_desc_base_value); + HAL_MCR_RD(prAdapter, u4DmaCfgCrAddr+0x04, &u4_hw_cnt_value); + HAL_MCR_RD(prAdapter, u4DmaCfgCrAddr+0x08, &u4_hw_cidx_value); + HAL_MCR_RD(prAdapter, u4DmaCfgCrAddr+0x0c, &u4_hw_didx_value); + + queue_cnt = (u4_hw_cidx_value >= u4_hw_didx_value) ? + (u4_hw_cidx_value - u4_hw_didx_value) : + (u4_hw_cidx_value - u4_hw_didx_value + u4_hw_cnt_value); + + DBGLOG(HAL, INFO, "%4d %16s %8x %10x %6x %6x %6x %6x\n", + idx, + group->name, + u4DmaCfgCrAddr, u4_hw_desc_base_value, + u4_hw_cnt_value, u4_hw_cidx_value, + u4_hw_didx_value, queue_cnt); + + } + + /* Dump All RX Ring Info */ + DBGLOG(HAL, INFO, "----------- RX Ring Config -----------\n"); + DBGLOG(HAL, INFO, "%4s %16s %8s %10s %6s %6s %6s %6s\n", + "Idx", "Attr", "Reg", "Base", "Cnt", "CIDX", "DIDX", "QCnt"); + + /* Dump RX Ring */ + if (enum_wfdma_type == WFDMA_TYPE_HOST) + group_cnt = sizeof(wfmda_host_rx_group) / + sizeof(struct wfdma_group_info); + else + group_cnt = sizeof(wfmda_wm_rx_group) / + sizeof(struct wfdma_group_info); + + for (idx = 0; idx < group_cnt; idx++) { + if (enum_wfdma_type == WFDMA_TYPE_HOST) + group = &wfmda_host_rx_group[idx]; + else + group = &wfmda_wm_rx_group[idx]; + + u4DmaCfgCrAddr = group->hw_desc_base; + + HAL_MCR_RD(prAdapter, u4DmaCfgCrAddr, &u4_hw_desc_base_value); + HAL_MCR_RD(prAdapter, u4DmaCfgCrAddr+0x04, &u4_hw_cnt_value); + HAL_MCR_RD(prAdapter, u4DmaCfgCrAddr+0x08, &u4_hw_cidx_value); + HAL_MCR_RD(prAdapter, u4DmaCfgCrAddr+0x0c, &u4_hw_didx_value); + + queue_cnt = (u4_hw_didx_value > u4_hw_cidx_value) ? + (u4_hw_didx_value - u4_hw_cidx_value - 1) : + (u4_hw_didx_value - u4_hw_cidx_value + + u4_hw_cnt_value - 1); + + DBGLOG(HAL, INFO, "%4d %16s %8x %10x %6x %6x %6x %6x\n", + idx, + group->name, + u4DmaCfgCrAddr, u4_hw_desc_base_value, + u4_hw_cnt_value, u4_hw_cidx_value, + u4_hw_didx_value, queue_cnt); + } + +} + +static void dump_wfdma_dbg_value( + IN struct ADAPTER *prAdapter, + IN enum _ENUM_WFDMA_TYPE_T enum_wfdma_type, + IN uint32_t wfdma_idx) +{ +#define BUF_SIZE 1024 + + uint32_t pdma_base_cr; + uint32_t set_debug_flag_value; + char *buf; + uint32_t pos = 0; + uint32_t set_debug_cr, get_debug_cr, get_debug_value = 0; + + if (enum_wfdma_type == WFDMA_TYPE_HOST) { + if (wfdma_idx == 0) + pdma_base_cr = CONNAC2X_HOST_WPDMA_0_BASE; + else + pdma_base_cr = CONNAC2X_HOST_WPDMA_1_BASE; + } else { + if (wfdma_idx == 0) + pdma_base_cr = CONNAC2X_MCU_WPDMA_0_BASE; + else + pdma_base_cr = CONNAC2X_MCU_WPDMA_1_BASE; + } + + buf = (char *) kalMemAlloc(BUF_SIZE, VIR_MEM_TYPE); + if (!buf) { + DBGLOG(HAL, ERROR, "Mem allocation failed.\n"); + return; + } + set_debug_cr = pdma_base_cr + 0x124; + get_debug_cr = pdma_base_cr + 0x128; + kalMemZero(buf, BUF_SIZE); + pos += kalSnprintf(buf + pos, 50, + "set_debug_cr:0x%08x get_debug_cr:0x%08x; ", + set_debug_cr, get_debug_cr); + for (set_debug_flag_value = 0x100; set_debug_flag_value <= 0x112; + set_debug_flag_value++) { + HAL_MCR_WR(prAdapter, set_debug_cr, set_debug_flag_value); + HAL_MCR_RD(prAdapter, get_debug_cr, &get_debug_value); + pos += kalSnprintf(buf + pos, 40, "Set:0x%03x, result=0x%08x%s", + set_debug_flag_value, + get_debug_value, + set_debug_flag_value == 0x112 ? "\n" : "; "); + } + DBGLOG(HAL, INFO, "%s", buf); + kalMemFree(buf, VIR_MEM_TYPE, BUF_SIZE); +} + +void show_wfdma_dbg_flag_log( + IN struct ADAPTER *prAdapter, + IN enum _ENUM_WFDMA_TYPE_T enum_wfdma_type) +{ + dump_wfdma_dbg_value(prAdapter, enum_wfdma_type, 0); + dump_wfdma_dbg_value(prAdapter, enum_wfdma_type, 1); +} + +void show_wfdma_dbg_log( + IN struct ADAPTER *prAdapter, + IN enum _ENUM_WFDMA_TYPE_T enum_wfdma_type) +{ + /* Dump Host WFMDA info */ + DBGLOG(HAL, TRACE, "WFMDA Configuration:\n"); + show_wfdma_interrupt_info(prAdapter, enum_wfdma_type); + show_wfdma_glo_info(prAdapter, enum_wfdma_type); + show_wfdma_ring_info(prAdapter, enum_wfdma_type); +} + +void soc3_0_show_wfdma_info(IN struct ADAPTER *prAdapter) +{ + /* dump WFDMA info by host or WM*/ + show_wfdma_dbg_log(prAdapter, WFDMA_TYPE_HOST); + show_wfdma_dbg_log(prAdapter, WFDMA_TYPE_WM); + + /* dump debug flag CR by host or WM*/ + show_wfdma_dbg_flag_log(prAdapter, WFDMA_TYPE_HOST); + show_wfdma_dbg_flag_log(prAdapter, WFDMA_TYPE_WM); + + DumpPPDebugCr(prAdapter); +} + +void soc3_0_show_wfdma_info_by_type(IN struct ADAPTER *prAdapter, + IN bool bShowWFDMA_type) +{ + if (bShowWFDMA_type) { + show_wfdma_dbg_log(prAdapter, WFDMA_TYPE_WM); + show_wfdma_dbg_flag_log(prAdapter, WFDMA_TYPE_WM); + } else { + show_wfdma_dbg_log(prAdapter, WFDMA_TYPE_HOST); + show_wfdma_dbg_flag_log(prAdapter, WFDMA_TYPE_HOST); + } +} + +void soc3_0_show_dmashdl_info(IN struct ADAPTER *prAdapter) +{ + uint32_t value = 0; + uint8_t idx; + uint32_t rsv_cnt = 0; + uint32_t src_cnt = 0; + uint32_t total_src_cnt = 0; + uint32_t total_rsv_cnt = 0; + uint32_t ffa_cnt = 0; + uint32_t free_pg_cnt = 0; + uint32_t ple_rpg_hif; + uint32_t ple_upg_hif; + uint8_t is_mismatch = FALSE; + + DBGLOG(HAL, INFO, "DMASHDL info:\n"); + + mt6885HalDmashdlGetRefill(prAdapter); + mt6885HalDmashdlGetPktMaxPage(prAdapter); + + HAL_MCR_RD(prAdapter, WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_ADDR, &value); + DBGLOG(HAL, INFO, "DMASHDL ERR FLAG CTRL(0x%08x): 0x%08x\n", + WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_ADDR, value); + + for (idx = 0; idx < ENUM_MT6885_DMASHDL_GROUP_2; idx++) { + DBGLOG(HAL, INFO, "Group %d info:\n", idx); + mt6885HalDmashdlGetGroupControl(prAdapter, idx); + rsv_cnt = mt6885HalDmashdlGetRsvCount(prAdapter, idx); + src_cnt = mt6885HalDmashdlGetSrcCount(prAdapter, idx); + mt6885HalDmashdlGetPKTCount(prAdapter, idx); + total_src_cnt += src_cnt; + total_rsv_cnt += rsv_cnt; + } + HAL_MCR_RD(prAdapter, WF_HIF_DMASHDL_TOP_STATUS_RD_ADDR, &value); + ffa_cnt = (value & WF_HIF_DMASHDL_TOP_STATUS_RD_FFA_CNT_MASK) >> + WF_HIF_DMASHDL_TOP_STATUS_RD_FFA_CNT_SHFT; + free_pg_cnt = (value & + WF_HIF_DMASHDL_TOP_STATUS_RD_FREE_PAGE_CNT_MASK) >> + WF_HIF_DMASHDL_TOP_STATUS_RD_FREE_PAGE_CNT_SHFT; + DBGLOG(HAL, INFO, "\tDMASHDL Status_RD(0x%08x): 0x%08x\n", + WF_HIF_DMASHDL_TOP_STATUS_RD_ADDR, value); + DBGLOG(HAL, INFO, "\tfree page cnt = 0x%03x, ffa cnt = 0x%03x\n", + free_pg_cnt, ffa_cnt); + + DBGLOG(HAL, INFO, "\nDMASHDL Counter Check:\n"); + HAL_MCR_RD(prAdapter, WF_PLE_TOP_HIF_PG_INFO_ADDR, &value); + ple_rpg_hif = (value & WF_PLE_TOP_HIF_PG_INFO_HIF_RSV_CNT_MASK) >> + WF_PLE_TOP_HIF_PG_INFO_HIF_RSV_CNT_SHFT; + ple_upg_hif = (value & WF_PLE_TOP_HIF_PG_INFO_HIF_SRC_CNT_MASK) >> + WF_PLE_TOP_HIF_PG_INFO_HIF_SRC_CNT_SHFT; + DBGLOG(HAL, INFO, + "\tPLE:The used/reserved pages of PLE HIF group=0x%03x/0x%03x\n", + ple_upg_hif, ple_rpg_hif); + DBGLOG(HAL, INFO, + "\tDMASHDL:The total used pages of group0~14=0x%03x\n", + total_src_cnt); + + if (ple_upg_hif != total_src_cnt) { + DBGLOG(HAL, INFO, + "\tPLE used pages & total used pages mismatch!\n"); + is_mismatch = TRUE; + } + + DBGLOG(HAL, INFO, + "\tThe total reserved pages of group0~14=0x%03x\n", + total_rsv_cnt); + DBGLOG(HAL, INFO, + "\tThe total ffa pages of group0~14=0x%03x\n", + ffa_cnt); + DBGLOG(HAL, INFO, + "\tThe total free pages of group0~14=0x%03x\n", + free_pg_cnt); + + if (free_pg_cnt != total_rsv_cnt + ffa_cnt) { + DBGLOG(HAL, INFO, + "\tmismatch(total_rsv_cnt + ffa_cnt in DMASHDL)\n"); + is_mismatch = TRUE; + } + + if (free_pg_cnt != ple_rpg_hif) { + DBGLOG(HAL, INFO, "\tmismatch(reserved pages in PLE)\n"); + is_mismatch = TRUE; + } + + + if (!is_mismatch) + DBGLOG(HAL, INFO, "DMASHDL: no counter mismatch\n"); +} + +void soc3_0_dump_mac_info(IN struct ADAPTER *prAdapter) +{ +#define BUF_SIZE 1024 +#define CR_COUNT 12 +#define LOOP_COUNT 30 + + uint32_t i = 0, j = 0, pos = 0; + uint32_t value = 0; + uint32_t cr_band0[] = { + 0x820ED020, + 0x820E4120, + 0x820E4128, + 0x820E22F0, + 0x820E22F4, + 0x820E22F8, + 0x820E22FC, + 0x820E3190, + 0x820C0220, + 0x820C0114, + 0x820C0154, + 0x820E0024 + }; + uint32_t cr_band1[] = { + 0x820FD020, + 0x820F4120, + 0x820F4128, + 0x820F22F0, + 0x820F22F4, + 0x820F22F8, + 0x820F22FC, + 0x820F3190, + 0x820C0220, + 0x820C0114, + 0x820C0154, + 0x820F0024 + }; + + char *buf = (char *) kalMemAlloc(BUF_SIZE, VIR_MEM_TYPE); + + DBGLOG(HAL, INFO, "Dump for band0\n"); + HAL_MCR_WR(prAdapter, 0x7C006100, 0x1F); + HAL_MCR_WR(prAdapter, 0x7C006104, 0x07070707); + HAL_MCR_WR(prAdapter, 0x7C006108, 0x0A0A0909); + HAL_MCR_RD(prAdapter, 0x820D0000, &value); + DBGLOG(HAL, INFO, "Dump CR: 0x820D0000 = 0x%08x\n", value); + HAL_MCR_RD(prAdapter, 0x820E3080, &value); + DBGLOG(HAL, INFO, "Dump CR: 0x820E3080 = 0x%08x\n", value); + HAL_MCR_RD(prAdapter, 0x820C0028, &value); + DBGLOG(HAL, INFO, "Dump CR: 0x820C0028 = 0x%08x\n", value); + HAL_MCR_RD(prAdapter, 0x820C8028, &value); + DBGLOG(HAL, INFO, "Dump CR: 0x820C8028 = 0x%08x\n", value); + HAL_MCR_RD(prAdapter, 0x820C8030, &value); + DBGLOG(HAL, INFO, "Dump CR: 0x820C8030 = 0x%08x\n", value); + /* Band 0 TXV_C and TXV_P */ + for (i = 0x820E412C; i < 0x820E4160; i += 4) { + HAL_MCR_RD(prAdapter, i, &value); + DBGLOG(HAL, INFO, "Dump CR: 0x%08x = 0x%08x\n", i, value); + kalMdelay(1); + } + HAL_MCR_RD(prAdapter, 0x820E206C, &value); + DBGLOG(HAL, INFO, "Dump CR: 0x820E206C = 0x%08x\n", value); + + if (buf) { + kalMemZero(buf, BUF_SIZE); + for (i = 0; i < LOOP_COUNT; i++) { + for (j = 0; j < CR_COUNT; j++) { + HAL_MCR_RD(prAdapter, cr_band0[j], &value); + pos += kalSnprintf(buf + pos, 25, + "0x%08x = 0x%08x%s", cr_band0[j], value, + j == CR_COUNT - 1 ? ";" : ","); + } + DBGLOG(HAL, INFO, "Dump CR: %s\n", buf); + pos = 0; + kalMdelay(1); + } + } + + DBGLOG(HAL, INFO, "Dump for band1\n"); + HAL_MCR_WR(prAdapter, 0x7C006400, 0x1F); + HAL_MCR_WR(prAdapter, 0x7C006404, 0x07070707); + HAL_MCR_WR(prAdapter, 0x7C006408, 0x0A0A0909); + HAL_MCR_RD(prAdapter, 0x820D0000, &value); + DBGLOG(HAL, INFO, "Dump CR: 0x820D0000 = 0x%08x\n", value); + HAL_MCR_RD(prAdapter, 0x820F3080, &value); + DBGLOG(HAL, INFO, "Dump CR: 0x820F3080 = 0x%08x\n", value); + HAL_MCR_RD(prAdapter, 0x820C0028, &value); + DBGLOG(HAL, INFO, "Dump CR: 0x820C0028 = 0x%08x\n", value); + HAL_MCR_RD(prAdapter, 0x820C8028, &value); + DBGLOG(HAL, INFO, "Dump CR: 0x820C8028 = 0x%08x\n", value); + HAL_MCR_RD(prAdapter, 0x820C8030, &value); + DBGLOG(HAL, INFO, "Dump CR: 0x820C8030 = 0x%08x\n", value); + /* Band 0 TXV_C and TXV_P */ + for (i = 0x820F412C; i < 0x820F4160; i += 4) { + HAL_MCR_RD(prAdapter, i, &value); + DBGLOG(HAL, INFO, "Dump CR: 0x%08x = 0x%08x\n", i, value); + kalMdelay(1); + } + HAL_MCR_RD(prAdapter, 0x820F206C, &value); + DBGLOG(HAL, INFO, "Dump CR: 0x820F206C = 0x%08x\n", value); + + if (buf) { + kalMemZero(buf, BUF_SIZE); + for (i = 0; i < LOOP_COUNT; i++) { + for (j = 0; j < CR_COUNT; j++) { + HAL_MCR_RD(prAdapter, cr_band1[j], &value); + pos += kalSnprintf(buf + pos, 25, + "0x%08x = 0x%08x%s", cr_band1[j], value, + j == CR_COUNT - 1 ? ";" : ","); + } + DBGLOG(HAL, INFO, "Dump CR: %s\n", buf); + pos = 0; + kalMdelay(1); + } + } + + if (buf) + kalMemFree(buf, VIR_MEM_TYPE, BUF_SIZE); +} + +#if WFSYS_SUPPORT_BUS_HANG_READ_FROM_DRIVER_BASE +void show_wfdma_interrupt_info_without_adapter( + IN enum _ENUM_WFDMA_TYPE_T enum_wfdma_type) +{ + uint32_t idx; + uint32_t u4hostBaseCrAddr = 0; + uint32_t u4DmaCfgCrAddr = 0; + uint32_t u4DmaCfgCrAddrByWFDMA[CONNAC2X_WFDMA_COUNT]; + uint32_t u4RegValue = 0; + uint32_t u4RegValueByWFDMA[CONNAC2X_WFDMA_COUNT] = {0}; + + /* Dump Interrupt Status info */ + if (enum_wfdma_type == WFDMA_TYPE_HOST) { + /* Dump Global Status CR only in WFMDA HOST*/ + u4hostBaseCrAddr = CONNAC2X_HOST_EXT_CONN_HIF_WRAP_DRIVER_BASE; + + u4DmaCfgCrAddr = CONNAC2X_WPDMA_EXT_INT_STA(u4hostBaseCrAddr); + wf_ioremap_read(u4DmaCfgCrAddr, &u4RegValue); + } + + /* Dump PDMA Status CR */ + for (idx = 0; idx < CONNAC2X_WFDMA_COUNT; idx++) { + + if (enum_wfdma_type == WFDMA_TYPE_HOST) + u4hostBaseCrAddr = idx ? + CONNAC2X_HOST_WPDMA_1_DRIVER_BASE : + CONNAC2X_HOST_WPDMA_0_DRIVER_BASE; + else + u4hostBaseCrAddr = idx ? + CONNAC2X_MCU_WPDMA_1_DRIVER_BASE : + CONNAC2X_MCU_WPDMA_0_DRIVER_BASE; + + u4DmaCfgCrAddrByWFDMA[idx] = + CONNAC2X_WPDMA_INT_STA(u4hostBaseCrAddr); + + wf_ioremap_read(u4DmaCfgCrAddrByWFDMA[idx], + &u4RegValueByWFDMA[idx]); + } + + DBGLOG(INIT, INFO, + "G_INT_S(0x%08x):0x%08x,W_%d(0x%08x):0x%08x, W_%d(0x%08x):0x%08x\n", + u4DmaCfgCrAddr, u4RegValue, + 0, u4DmaCfgCrAddrByWFDMA[0], u4RegValueByWFDMA[0], + 1, u4DmaCfgCrAddrByWFDMA[1], u4RegValueByWFDMA[1]); + + /* Dump Interrupt Enable Info */ + if (enum_wfdma_type == WFDMA_TYPE_HOST) { + + /* Dump Global Enable CR */ + u4hostBaseCrAddr = CONNAC2X_HOST_EXT_CONN_HIF_WRAP_DRIVER_BASE; + + u4DmaCfgCrAddr = CONNAC2X_WPDMA_EXT_INT_MASK(u4hostBaseCrAddr); + + wf_ioremap_read(u4DmaCfgCrAddr, &u4RegValue); + } + + /* Dump PDMA Enable CR */ + for (idx = 0; idx < CONNAC2X_WFDMA_COUNT; idx++) { + + if (enum_wfdma_type == WFDMA_TYPE_HOST) + u4hostBaseCrAddr = idx ? + CONNAC2X_HOST_WPDMA_1_DRIVER_BASE : + CONNAC2X_HOST_WPDMA_0_DRIVER_BASE; + else + u4hostBaseCrAddr = idx ? + CONNAC2X_MCU_WPDMA_1_DRIVER_BASE : + CONNAC2X_MCU_WPDMA_0_DRIVER_BASE; + + u4DmaCfgCrAddrByWFDMA[idx] = + CONNAC2X_WPDMA_INT_MASK(u4hostBaseCrAddr); + + wf_ioremap_read(u4DmaCfgCrAddrByWFDMA[idx], + &u4RegValueByWFDMA[idx]); + } + + DBGLOG(INIT, INFO, + "G_INT_E(0x%08x):0x%08x,W_%d(0x%08x):0x%08x, W_%d(0x%08x):0x%08x\n", + u4DmaCfgCrAddr, u4RegValue, + 0, u4DmaCfgCrAddrByWFDMA[0], u4RegValueByWFDMA[0], + 1, u4DmaCfgCrAddrByWFDMA[1], u4RegValueByWFDMA[1]); +} + +void show_wfdma_glo_info_without_adapter( + IN enum _ENUM_WFDMA_TYPE_T enum_wfdma_type) +{ + uint32_t idx; + uint32_t u4hostBaseCrAddr = 0; + uint32_t u4DmaCfgCrAddr = 0; + union WPDMA_GLO_CFG_STRUCT GloCfgValue; + + for (idx = 0; idx < CONNAC2X_WFDMA_COUNT; idx++) { + + if (enum_wfdma_type == WFDMA_TYPE_HOST) + u4hostBaseCrAddr = idx ? + CONNAC2X_HOST_WPDMA_1_DRIVER_BASE : + CONNAC2X_HOST_WPDMA_0_DRIVER_BASE; + else + u4hostBaseCrAddr = idx ? + CONNAC2X_MCU_WPDMA_1_DRIVER_BASE : + CONNAC2X_MCU_WPDMA_0_DRIVER_BASE; + + u4DmaCfgCrAddr = CONNAC2X_WPDMA_GLO_CFG(u4hostBaseCrAddr); + + wf_ioremap_read(u4DmaCfgCrAddr, &GloCfgValue.word); + + DBGLOG(INIT, INFO, + "WFDMA_%d GLO(0x%08x):0x%08x,EN T/R=(%d/%d), Busy T/R=(%d/%d)\n", + idx, u4DmaCfgCrAddr, GloCfgValue.word, + GloCfgValue.field_conn2x.tx_dma_en, + GloCfgValue.field_conn2x.rx_dma_en, + GloCfgValue.field_conn2x.tx_dma_busy, + GloCfgValue.field_conn2x.rx_dma_busy); + } + +} + +void show_wfdma_ring_info_without_adapter( + IN enum _ENUM_WFDMA_TYPE_T enum_wfdma_type) +{ + + uint32_t idx = 0; + uint32_t group_cnt = 0; + uint32_t u4DmaCfgCrAddr; + struct wfdma_group_info *group; + uint32_t u4_hw_desc_base_value = 0; + uint32_t u4_hw_cnt_value = 0; + uint32_t u4_hw_cidx_value = 0; + uint32_t u4_hw_didx_value = 0; + uint32_t queue_cnt; + + /* Dump All TX Ring Info */ + DBGLOG(HAL, TRACE, "----------- TX Ring Config -----------\n"); + DBGLOG(HAL, TRACE, "%4s %16s %8s %10s %6s %6s %6s %6s\n", + "Idx", "Attr", "Reg", "Base", "Cnt", "CIDX", "DIDX", "QCnt"); + + /* Dump TX Ring */ + if (enum_wfdma_type == WFDMA_TYPE_HOST) + group_cnt = sizeof(wfmda_host_tx_group_driver_base) / + sizeof(struct wfdma_group_info); + else + group_cnt = sizeof(wfmda_wm_tx_group_driver_base) / + sizeof(struct wfdma_group_info); + + for (idx = 0; idx < group_cnt; idx++) { + if (enum_wfdma_type == WFDMA_TYPE_HOST) + group = &wfmda_host_tx_group_driver_base[idx]; + else + group = &wfmda_wm_tx_group_driver_base[idx]; + + u4DmaCfgCrAddr = group->hw_desc_base; + + wf_ioremap_read(u4DmaCfgCrAddr, &u4_hw_desc_base_value); + wf_ioremap_read(u4DmaCfgCrAddr+0x04, &u4_hw_cnt_value); + wf_ioremap_read(u4DmaCfgCrAddr+0x08, &u4_hw_cidx_value); + wf_ioremap_read(u4DmaCfgCrAddr+0x0c, &u4_hw_didx_value); + + queue_cnt = (u4_hw_cidx_value >= u4_hw_didx_value) ? + (u4_hw_cidx_value - u4_hw_didx_value) : + (u4_hw_cidx_value - u4_hw_didx_value + u4_hw_cnt_value); + + DBGLOG(HAL, INFO, "%4d %16s %8x %10x %6x %6x %6x %6x\n", + idx, + group->name, + u4DmaCfgCrAddr, u4_hw_desc_base_value, + u4_hw_cnt_value, u4_hw_cidx_value, + u4_hw_didx_value, queue_cnt); + + } + + /* Dump All RX Ring Info */ + DBGLOG(HAL, TRACE, "----------- RX Ring Config -----------\n"); + DBGLOG(HAL, TRACE, "%4s %16s %8s %10s %6s %6s %6s %6s\n", + "Idx", "Attr", "Reg", "Base", "Cnt", "CIDX", "DIDX", "QCnt"); + + /* Dump RX Ring */ + if (enum_wfdma_type == WFDMA_TYPE_HOST) + group_cnt = sizeof(wfmda_host_rx_group_driver_base) / + sizeof(struct wfdma_group_info); + else + group_cnt = sizeof(wfmda_wm_rx_group_driver_base) / + sizeof(struct wfdma_group_info); + + for (idx = 0; idx < group_cnt; idx++) { + if (enum_wfdma_type == WFDMA_TYPE_HOST) + group = &wfmda_host_rx_group_driver_base[idx]; + else + group = &wfmda_wm_rx_group_driver_base[idx]; + + u4DmaCfgCrAddr = group->hw_desc_base; + + wf_ioremap_read(u4DmaCfgCrAddr, &u4_hw_desc_base_value); + wf_ioremap_read(u4DmaCfgCrAddr+0x04, &u4_hw_cnt_value); + wf_ioremap_read(u4DmaCfgCrAddr+0x08, &u4_hw_cidx_value); + wf_ioremap_read(u4DmaCfgCrAddr+0x0c, &u4_hw_didx_value); + + queue_cnt = (u4_hw_didx_value > u4_hw_cidx_value) ? + (u4_hw_didx_value - u4_hw_cidx_value - 1) : + (u4_hw_didx_value - u4_hw_cidx_value + + u4_hw_cnt_value - 1); + + DBGLOG(HAL, INFO, "%4d %16s %8x %10x %6x %6x %6x %6x\n", + idx, + group->name, + u4DmaCfgCrAddr, u4_hw_desc_base_value, + u4_hw_cnt_value, u4_hw_cidx_value, + u4_hw_didx_value, queue_cnt); + } + +} + +static void dump_dbg_value_without_adapter( + IN uint32_t pdma_base_cr, + IN uint32_t set_value, + IN uint32_t isMandatoryDump) +{ + uint32_t set_debug_cr = 0; + uint32_t get_debug_cr = 0; + uint32_t get_debug_value = 0; + + set_debug_cr = pdma_base_cr + 0x124; + get_debug_cr = pdma_base_cr + 0x128; + + wf_ioremap_write(set_debug_cr, set_value); + wf_ioremap_read(get_debug_cr, &get_debug_value); + + if (isMandatoryDump == 1) { + DBGLOG(INIT, INFO, "set(0x%08x):0x%08x, get(0x%08x):0x%08x,", + set_debug_cr, set_value, + get_debug_cr, get_debug_value); + } else { + DBGLOG(INIT, TRACE, "set(0x%08x):0x%08x, get(0x%08x):0x%08x,", + set_debug_cr, set_value, + get_debug_cr, get_debug_value); + } +} + +static void dump_wfdma_dbg_value_without_adapter( + IN enum _ENUM_WFDMA_TYPE_T enum_wfdma_type, + IN uint32_t wfdma_idx, + IN uint32_t isMandatoryDump) +{ + uint32_t pdma_base_cr = 0; + uint32_t set_debug_flag_value = 0; + + if (enum_wfdma_type == WFDMA_TYPE_HOST) { + if (wfdma_idx == 0) + pdma_base_cr = CONNAC2X_HOST_WPDMA_0_DRIVER_BASE; + else + pdma_base_cr = CONNAC2X_HOST_WPDMA_1_DRIVER_BASE; + } else{ + if (wfdma_idx == 0) + pdma_base_cr = CONNAC2X_MCU_WPDMA_0_DRIVER_BASE; + else + pdma_base_cr = CONNAC2X_MCU_WPDMA_1_DRIVER_BASE; + } + + set_debug_flag_value = 0x100; + dump_dbg_value_without_adapter(pdma_base_cr, + set_debug_flag_value, isMandatoryDump); + + set_debug_flag_value = 0x101; + dump_dbg_value_without_adapter(pdma_base_cr, + set_debug_flag_value, isMandatoryDump); + + set_debug_flag_value = 0x102; + dump_dbg_value_without_adapter(pdma_base_cr, + set_debug_flag_value, isMandatoryDump); + + set_debug_flag_value = 0x103; + dump_dbg_value_without_adapter(pdma_base_cr, + set_debug_flag_value, isMandatoryDump); + + set_debug_flag_value = 0x104; + dump_dbg_value_without_adapter(pdma_base_cr, + set_debug_flag_value, isMandatoryDump); + + set_debug_flag_value = 0x105; + dump_dbg_value_without_adapter(pdma_base_cr, + set_debug_flag_value, isMandatoryDump); + + set_debug_flag_value = 0x107; + dump_dbg_value_without_adapter(pdma_base_cr, + set_debug_flag_value, isMandatoryDump); + + set_debug_flag_value = 0x10A; + dump_dbg_value_without_adapter(pdma_base_cr, + set_debug_flag_value, isMandatoryDump); + + set_debug_flag_value = 0x10D; + dump_dbg_value_without_adapter(pdma_base_cr, + set_debug_flag_value, isMandatoryDump); + + set_debug_flag_value = 0x10E; + dump_dbg_value_without_adapter(pdma_base_cr, + set_debug_flag_value, isMandatoryDump); + + set_debug_flag_value = 0x10F; + dump_dbg_value_without_adapter(pdma_base_cr, + set_debug_flag_value, isMandatoryDump); + + set_debug_flag_value = 0x110; + dump_dbg_value_without_adapter(pdma_base_cr, + set_debug_flag_value, isMandatoryDump); + + set_debug_flag_value = 0x111; + dump_dbg_value_without_adapter(pdma_base_cr, + set_debug_flag_value, isMandatoryDump); + + set_debug_flag_value = 0x112; + dump_dbg_value_without_adapter(pdma_base_cr, + set_debug_flag_value, isMandatoryDump); + +} + +static void show_wfdma_dbg_flag_log_without_adapter( + IN enum _ENUM_WFDMA_TYPE_T enum_wfdma_type, + IN uint32_t isMandatoryDump) +{ + dump_wfdma_dbg_value_without_adapter( + enum_wfdma_type, 0, isMandatoryDump); + dump_wfdma_dbg_value_without_adapter( + enum_wfdma_type, 1, isMandatoryDump); +} + +static void show_wfdma_dbg_log_without_adapter( + IN enum _ENUM_WFDMA_TYPE_T enum_wfdma_type) +{ + /* Dump Host WFMDA info */ + DBGLOG(HAL, TRACE, "WFMDA Configuration:\n"); + show_wfdma_interrupt_info_without_adapter(enum_wfdma_type); + show_wfdma_glo_info_without_adapter(enum_wfdma_type); + show_wfdma_ring_info_without_adapter(enum_wfdma_type); +} + +/* bIsHostDMA = 1 (how Host PDMA) else (WM PDMA) */ +void soc3_0_show_wfdma_info_by_type_without_adapter( + IN bool bShowWFDMA_type) +{ + if (bShowWFDMA_type) { + show_wfdma_dbg_log_without_adapter(WFDMA_TYPE_WM); + show_wfdma_dbg_flag_log_without_adapter(WFDMA_TYPE_WM, TRUE); + } else { + show_wfdma_dbg_log_without_adapter(WFDMA_TYPE_HOST); + show_wfdma_dbg_flag_log_without_adapter(WFDMA_TYPE_HOST, TRUE); + } +} + +#endif /* WFSYS_SUPPORT_BUS_HANG_READ_FROM_DRIVER_BASE */ + +#endif /* SOC3_0 */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/soc3_0/hal_dmashdl_soc3_0.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/soc3_0/hal_dmashdl_soc3_0.c new file mode 100644 index 0000000000000000000000000000000000000000..fa94b6d19e8363f2af698d7c244ea54c95969767 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/soc3_0/hal_dmashdl_soc3_0.c @@ -0,0 +1,480 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +/*! \file hal_dmashdl_mt6885.c +* \brief DMASHDL HAL API for MT6885 +* +* This file contains all routines which are exported + from MediaTek 802.11 Wireless LAN driver stack to GLUE Layer. +*/ + +#ifdef SOC3_0 +#if defined(_HIF_PCIE) || defined(_HIF_AXI) + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +#include "precomp.h" +#include "soc3_0.h" +#include "coda/soc3_0/wf_hif_dmashdl_top.h" +#include "hal_dmashdl_soc3_0.h" +#include "dma_sch.h" + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +struct MT6885_DMASHDL_CFG rMT6885DmashdlCfg = { + .fgSlotArbiterEn = MT6885_DMASHDL_SLOT_ARBITER_EN, + + .u2PktPleMaxPage = MT6885_DMASHDL_PKT_PLE_MAX_PAGE, + + .u2PktPseMaxPage = MT6885_DMASHDL_PKT_PSE_MAX_PAGE, + + .afgRefillEn = { + MT6885_DMASHDL_GROUP_0_REFILL_EN, + MT6885_DMASHDL_GROUP_1_REFILL_EN, + MT6885_DMASHDL_GROUP_2_REFILL_EN, + MT6885_DMASHDL_GROUP_3_REFILL_EN, + MT6885_DMASHDL_GROUP_4_REFILL_EN, + MT6885_DMASHDL_GROUP_5_REFILL_EN, + MT6885_DMASHDL_GROUP_6_REFILL_EN, + MT6885_DMASHDL_GROUP_7_REFILL_EN, + MT6885_DMASHDL_GROUP_8_REFILL_EN, + MT6885_DMASHDL_GROUP_9_REFILL_EN, + MT6885_DMASHDL_GROUP_10_REFILL_EN, + MT6885_DMASHDL_GROUP_11_REFILL_EN, + MT6885_DMASHDL_GROUP_12_REFILL_EN, + MT6885_DMASHDL_GROUP_13_REFILL_EN, + MT6885_DMASHDL_GROUP_14_REFILL_EN, + MT6885_DMASHDL_GROUP_15_REFILL_EN, + }, + + .au2MaxQuota = { + MT6885_DMASHDL_GROUP_0_MAX_QUOTA, + MT6885_DMASHDL_GROUP_1_MAX_QUOTA, + MT6885_DMASHDL_GROUP_2_MAX_QUOTA, + MT6885_DMASHDL_GROUP_3_MAX_QUOTA, + MT6885_DMASHDL_GROUP_4_MAX_QUOTA, + MT6885_DMASHDL_GROUP_5_MAX_QUOTA, + MT6885_DMASHDL_GROUP_6_MAX_QUOTA, + MT6885_DMASHDL_GROUP_7_MAX_QUOTA, + MT6885_DMASHDL_GROUP_8_MAX_QUOTA, + MT6885_DMASHDL_GROUP_9_MAX_QUOTA, + MT6885_DMASHDL_GROUP_10_MAX_QUOTA, + MT6885_DMASHDL_GROUP_11_MAX_QUOTA, + MT6885_DMASHDL_GROUP_12_MAX_QUOTA, + MT6885_DMASHDL_GROUP_13_MAX_QUOTA, + MT6885_DMASHDL_GROUP_14_MAX_QUOTA, + MT6885_DMASHDL_GROUP_15_MAX_QUOTA, + }, + + .au2MinQuota = { + MT6885_DMASHDL_GROUP_0_MIN_QUOTA, + MT6885_DMASHDL_GROUP_1_MIN_QUOTA, + MT6885_DMASHDL_GROUP_2_MIN_QUOTA, + MT6885_DMASHDL_GROUP_3_MIN_QUOTA, + MT6885_DMASHDL_GROUP_4_MIN_QUOTA, + MT6885_DMASHDL_GROUP_5_MIN_QUOTA, + MT6885_DMASHDL_GROUP_6_MIN_QUOTA, + MT6885_DMASHDL_GROUP_7_MIN_QUOTA, + MT6885_DMASHDL_GROUP_8_MIN_QUOTA, + MT6885_DMASHDL_GROUP_9_MIN_QUOTA, + MT6885_DMASHDL_GROUP_10_MIN_QUOTA, + MT6885_DMASHDL_GROUP_11_MIN_QUOTA, + MT6885_DMASHDL_GROUP_12_MIN_QUOTA, + MT6885_DMASHDL_GROUP_13_MIN_QUOTA, + MT6885_DMASHDL_GROUP_14_MIN_QUOTA, + MT6885_DMASHDL_GROUP_15_MIN_QUOTA, + }, + + .aucQueue2Group = { + MT6885_DMASHDL_QUEUE_0_TO_GROUP, + MT6885_DMASHDL_QUEUE_1_TO_GROUP, + MT6885_DMASHDL_QUEUE_2_TO_GROUP, + MT6885_DMASHDL_QUEUE_3_TO_GROUP, + MT6885_DMASHDL_QUEUE_4_TO_GROUP, + MT6885_DMASHDL_QUEUE_5_TO_GROUP, + MT6885_DMASHDL_QUEUE_6_TO_GROUP, + MT6885_DMASHDL_QUEUE_7_TO_GROUP, + MT6885_DMASHDL_QUEUE_8_TO_GROUP, + MT6885_DMASHDL_QUEUE_9_TO_GROUP, + MT6885_DMASHDL_QUEUE_10_TO_GROUP, + MT6885_DMASHDL_QUEUE_11_TO_GROUP, + MT6885_DMASHDL_QUEUE_12_TO_GROUP, + MT6885_DMASHDL_QUEUE_13_TO_GROUP, + MT6885_DMASHDL_QUEUE_14_TO_GROUP, + MT6885_DMASHDL_QUEUE_15_TO_GROUP, + MT6885_DMASHDL_QUEUE_16_TO_GROUP, + MT6885_DMASHDL_QUEUE_17_TO_GROUP, + MT6885_DMASHDL_QUEUE_18_TO_GROUP, + MT6885_DMASHDL_QUEUE_19_TO_GROUP, + MT6885_DMASHDL_QUEUE_20_TO_GROUP, + MT6885_DMASHDL_QUEUE_21_TO_GROUP, + MT6885_DMASHDL_QUEUE_22_TO_GROUP, + MT6885_DMASHDL_QUEUE_23_TO_GROUP, + MT6885_DMASHDL_QUEUE_24_TO_GROUP, + MT6885_DMASHDL_QUEUE_25_TO_GROUP, + MT6885_DMASHDL_QUEUE_26_TO_GROUP, + MT6885_DMASHDL_QUEUE_27_TO_GROUP, + MT6885_DMASHDL_QUEUE_28_TO_GROUP, + MT6885_DMASHDL_QUEUE_29_TO_GROUP, + MT6885_DMASHDL_QUEUE_30_TO_GROUP, + MT6885_DMASHDL_QUEUE_31_TO_GROUP, + }, + + .aucPriority2Group = { + MT6885_DMASHDL_PRIORITY0_GROUP, + MT6885_DMASHDL_PRIORITY1_GROUP, + MT6885_DMASHDL_PRIORITY2_GROUP, + MT6885_DMASHDL_PRIORITY3_GROUP, + MT6885_DMASHDL_PRIORITY4_GROUP, + MT6885_DMASHDL_PRIORITY5_GROUP, + MT6885_DMASHDL_PRIORITY6_GROUP, + MT6885_DMASHDL_PRIORITY7_GROUP, + MT6885_DMASHDL_PRIORITY8_GROUP, + MT6885_DMASHDL_PRIORITY9_GROUP, + MT6885_DMASHDL_PRIORITY10_GROUP, + MT6885_DMASHDL_PRIORITY11_GROUP, + MT6885_DMASHDL_PRIORITY12_GROUP, + MT6885_DMASHDL_PRIORITY13_GROUP, + MT6885_DMASHDL_PRIORITY14_GROUP, + MT6885_DMASHDL_PRIORITY15_GROUP, + }, +}; + +void mt6885HalDmashdlSetPlePktMaxPage(struct ADAPTER *prAdapter, + uint16_t u2MaxPage) +{ + uint32_t u4Val = 0; + + HAL_MCR_RD(prAdapter, WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_ADDR, &u4Val); + + u4Val &= ~WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_PLE_PACKET_MAX_SIZE_MASK; + u4Val |= (u2MaxPage << + WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_PLE_PACKET_MAX_SIZE_SHFT) & + WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_PLE_PACKET_MAX_SIZE_MASK; + + HAL_MCR_WR(prAdapter, WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_ADDR, u4Val); +} + +void mt6885HalDmashdlSetPsePktMaxPage(struct ADAPTER *prAdapter, + uint16_t u2MaxPage) +{ + uint32_t u4Val = 0; + + HAL_MCR_RD(prAdapter, WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_ADDR, &u4Val); + + u4Val &= ~WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_PSE_PACKET_MAX_SIZE_MASK; + u4Val |= (u2MaxPage << + WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_PSE_PACKET_MAX_SIZE_SHFT) & + WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_PSE_PACKET_MAX_SIZE_MASK; + + HAL_MCR_WR(prAdapter, WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_ADDR, u4Val); +} + +void mt6885HalDmashdlGetPktMaxPage(struct ADAPTER *prAdapter) +{ + uint32_t u4Val = 0; + uint32_t ple_pkt_max_sz; + uint32_t pse_pkt_max_sz; + + HAL_MCR_RD(prAdapter, WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_ADDR, &u4Val); + + ple_pkt_max_sz = (u4Val & + WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_PLE_PACKET_MAX_SIZE_MASK)>> + WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_PLE_PACKET_MAX_SIZE_SHFT; + pse_pkt_max_sz = (u4Val & + WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_PSE_PACKET_MAX_SIZE_MASK)>> + WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_PSE_PACKET_MAX_SIZE_SHFT; + + DBGLOG(HAL, INFO, "DMASHDL PLE_PACKET_MAX_SIZE (0x%08x): 0x%08x\n", + WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_ADDR, u4Val); + DBGLOG(HAL, INFO, "PLE/PSE packet max size=0x%03x/0x%03x\n", + ple_pkt_max_sz, pse_pkt_max_sz); + +} +void mt6885HalDmashdlSetRefill(struct ADAPTER *prAdapter, uint8_t ucGroup, + u_int8_t fgEnable) +{ + uint32_t u4Mask; + uint32_t u4Val = 0; + + if (ucGroup >= ENUM_MT6885_DMASHDL_GROUP_NUM) + ASSERT(0); + + u4Mask = WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP0_REFILL_DISABLE_MASK + << ucGroup; + + HAL_MCR_RD(prAdapter, WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR, &u4Val); + + if (fgEnable) + u4Val &= ~u4Mask; + else + u4Val |= u4Mask; + + HAL_MCR_WR(prAdapter, WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR, u4Val); +} + +void mt6885HalDmashdlGetRefill(struct ADAPTER *prAdapter) +{ + uint32_t u4Val = 0; + + HAL_MCR_RD(prAdapter, WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR, &u4Val); + DBGLOG(HAL, INFO, "DMASHDL ReFill Control (0x%08x): 0x%08x\n", + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR, u4Val); +} + +void mt6885HalDmashdlSetMaxQuota(struct ADAPTER *prAdapter, uint8_t ucGroup, + uint16_t u2MaxQuota) +{ + uint32_t u4Addr; + uint32_t u4Val = 0; + + if (ucGroup >= ENUM_MT6885_DMASHDL_GROUP_NUM) + ASSERT(0); + + u4Addr = WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_ADDR + (ucGroup << 2); + + HAL_MCR_RD(prAdapter, u4Addr, &u4Val); + + u4Val &= ~WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_GROUP0_MAX_QUOTA_MASK; + u4Val |= (u2MaxQuota << + WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_GROUP0_MAX_QUOTA_SHFT) & + WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_GROUP0_MAX_QUOTA_MASK; + + HAL_MCR_WR(prAdapter, u4Addr, u4Val); +} + +void mt6885HalDmashdlSetMinQuota(struct ADAPTER *prAdapter, uint8_t ucGroup, + uint16_t u2MinQuota) +{ + uint32_t u4Addr; + uint32_t u4Val = 0; + + if (ucGroup >= ENUM_MT6885_DMASHDL_GROUP_NUM) + ASSERT(0); + + u4Addr = WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_ADDR + (ucGroup << 2); + + HAL_MCR_RD(prAdapter, u4Addr, &u4Val); + + u4Val &= ~WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_GROUP0_MIN_QUOTA_MASK; + u4Val |= (u2MinQuota << + WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_GROUP0_MIN_QUOTA_SHFT) & + WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_GROUP0_MIN_QUOTA_MASK; + + HAL_MCR_WR(prAdapter, u4Addr, u4Val); +} + +void mt6885HalDmashdlGetGroupControl(struct ADAPTER *prAdapter, uint8_t ucGroup) +{ + uint32_t u4Addr; + uint32_t u4Val = 0; + uint32_t max_quota; + uint32_t min_quota; + + u4Addr = WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_ADDR + (ucGroup << 2); + + HAL_MCR_RD(prAdapter, u4Addr, &u4Val); + + max_quota = GET_DMASHDL_MAX_QUOTA_NUM(u4Val); + min_quota = GET_DMASHDL_MIN_QUOTA_NUM(u4Val); + DBGLOG(HAL, INFO, "\tDMASHDL Group%d control(0x%08x): 0x%08x\n", + ucGroup, u4Addr, u4Val); + DBGLOG(HAL, INFO, "\tmax/min quota = 0x%03x/ 0x%03x\n", + max_quota, min_quota); + +} +void mt6885HalDmashdlSetQueueMapping(struct ADAPTER *prAdapter, uint8_t ucQueue, + uint8_t ucGroup) +{ + uint32_t u4Addr, u4Mask, u4Shft; + uint32_t u4Val = 0; + + if (ucQueue >= 32) + ASSERT(0); + + if (ucGroup >= ENUM_MT6885_DMASHDL_GROUP_NUM) + ASSERT(0); + + u4Addr = WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_ADDR + + ((ucQueue >> 3) << 2); + u4Mask = WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE0_MAPPING_MASK << + ((ucQueue % 8) << 2); + u4Shft = (ucQueue % 8) << 2; + + HAL_MCR_RD(prAdapter, u4Addr, &u4Val); + + u4Val &= ~u4Mask; + u4Val |= (ucGroup << u4Shft) & u4Mask; + + HAL_MCR_WR(prAdapter, u4Addr, u4Val); +} + +void mt6885HalDmashdlSetSlotArbiter(struct ADAPTER *prAdapter, + u_int8_t fgEnable) +{ + uint32_t u4Val = 0; + + HAL_MCR_RD(prAdapter, WF_HIF_DMASHDL_TOP_PAGE_SETTING_ADDR, &u4Val); + + if (fgEnable) + u4Val |= + WF_HIF_DMASHDL_TOP_PAGE_SETTING_GROUP_SEQUENCE_ORDER_TYPE_MASK; + else + u4Val &= + ~WF_HIF_DMASHDL_TOP_PAGE_SETTING_GROUP_SEQUENCE_ORDER_TYPE_MASK; + + HAL_MCR_WR(prAdapter, WF_HIF_DMASHDL_TOP_PAGE_SETTING_ADDR, u4Val); +} + +void mt6885HalDmashdlSetUserDefinedPriority(struct ADAPTER *prAdapter, + uint8_t ucPriority, uint8_t ucGroup) +{ + uint32_t u4Addr, u4Mask, u4Shft; + uint32_t u4Val = 0; + + ASSERT(ucPriority < 16); + ASSERT(ucGroup < ENUM_MT6885_DMASHDL_GROUP_NUM); + + u4Addr = WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_ADDR + + ((ucPriority >> 3) << 2); + u4Mask = WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY0_GROUP_MASK + << ((ucPriority % 8) << 2); + u4Shft = (ucPriority % 8) << 2; + + HAL_MCR_RD(prAdapter, u4Addr, &u4Val); + + u4Val &= ~u4Mask; + u4Val |= (ucGroup << u4Shft) & u4Mask; + + HAL_MCR_WR(prAdapter, u4Addr, u4Val); +} + +uint32_t mt6885HalDmashdlGetRsvCount(struct ADAPTER *prAdapter, uint8_t ucGroup) +{ + uint32_t u4Addr; + uint32_t u4Val = 0; + uint32_t rsv_cnt = 0; + + u4Addr = WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_ADDR + (ucGroup << 2); + + HAL_MCR_RD(prAdapter, u4Addr, &u4Val); + + rsv_cnt = (u4Val & WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_G0_RSV_CNT_MASK) >> + WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_G0_RSV_CNT_SHFT; + + DBGLOG(HAL, INFO, "\tDMASHDL Status_RD_GP%d(0x%08x): 0x%08x\n", + ucGroup, u4Addr, u4Val); + DBGLOG(HAL, TRACE, "\trsv_cnt = 0x%03x\n", rsv_cnt); + return rsv_cnt; +} + +uint32_t mt6885HalDmashdlGetSrcCount(struct ADAPTER *prAdapter, uint8_t ucGroup) +{ + uint32_t u4Addr; + uint32_t u4Val = 0; + uint32_t src_cnt = 0; + + u4Addr = WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_ADDR + (ucGroup << 2); + + HAL_MCR_RD(prAdapter, u4Addr, &u4Val); + + src_cnt = (u4Val & WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_G0_SRC_CNT_MASK) >> + WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_G0_SRC_CNT_SHFT; + + DBGLOG(HAL, TRACE, "\tsrc_cnt = 0x%03x\n", src_cnt); + return src_cnt; +} + +void mt6885HalDmashdlGetPKTCount(struct ADAPTER *prAdapter, uint8_t ucGroup) +{ + uint32_t u4Addr; + uint32_t u4Val = 0; + uint32_t pktin_cnt = 0; + uint32_t ask_cnt = 0; + + if ((ucGroup & 0x1) == 0) + u4Addr = WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT0_ADDR + + (ucGroup << 1); + else + u4Addr = WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT0_ADDR + + ((ucGroup-1) << 1); + + HAL_MCR_RD(prAdapter, u4Addr, &u4Val); + DBGLOG(HAL, INFO, "\tDMASHDL RD_group_pkt_cnt_%d(0x%08x): 0x%08x\n", + ucGroup / 2, u4Addr, u4Val); + if ((ucGroup & 0x1) == 0) { + pktin_cnt = GET_EVEN_GROUP_PKT_IN_CNT(u4Val); + ask_cnt = GET_EVEN_GROUP_ASK_CNT(u4Val); + } else { + pktin_cnt = GET_ODD_GROUP_PKT_IN_CNT(u4Val); + ask_cnt = GET_ODD_GROUP_ASK_CNT(u4Val); + } + DBGLOG(HAL, INFO, "\tpktin_cnt = 0x%02x, ask_cnt = 0x%02x", + pktin_cnt, ask_cnt); +} + +void mt6885DmashdlInit(struct ADAPTER *prAdapter) +{ + uint32_t idx; + + mt6885HalDmashdlSetPlePktMaxPage(prAdapter, + rMT6885DmashdlCfg.u2PktPleMaxPage); + + for (idx = 0; idx < ENUM_MT6885_DMASHDL_GROUP_NUM; idx++) { + mt6885HalDmashdlSetRefill(prAdapter, idx, + rMT6885DmashdlCfg.afgRefillEn[idx]); + + mt6885HalDmashdlSetMaxQuota(prAdapter, idx, + rMT6885DmashdlCfg.au2MaxQuota[idx]); + + mt6885HalDmashdlSetMinQuota(prAdapter, idx, + rMT6885DmashdlCfg.au2MinQuota[idx]); + } + + for (idx = 0; idx < 32; idx++) + mt6885HalDmashdlSetQueueMapping(prAdapter, idx, + rMT6885DmashdlCfg.aucQueue2Group[idx]); + + for (idx = 0; idx < 16; idx++) + mt6885HalDmashdlSetUserDefinedPriority(prAdapter, idx, + rMT6885DmashdlCfg.aucPriority2Group[idx]); + + mt6885HalDmashdlSetSlotArbiter(prAdapter, + rMT6885DmashdlCfg.fgSlotArbiterEn); +} + +#endif /* defined(_HIF_PCIE) || defined(_HIF_AXI) */ +#endif /* SOC3_0*/ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/soc3_0/soc3_0.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/soc3_0/soc3_0.c new file mode 100644 index 0000000000000000000000000000000000000000..7d11ecefd07f3b2b466d9ad9b0c55283849b7e68 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/chips/soc3_0/soc3_0.c @@ -0,0 +1,4832 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/*! \file soc3_0.c +* \brief Internal driver stack will export +* the required procedures here for GLUE Layer. +* +* This file contains all routines which are exported + from MediaTek 802.11 Wireless LAN driver stack to GLUE Layer. +*/ + +#ifdef SOC3_0 + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ +#define CFG_SUPPORT_VCODE_VDFS 1 + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +#include "coda/soc3_0/wf_wfdma_host_dma0.h" +#include "coda/soc3_0/wf_wfdma_host_dma1.h" + +#if (CFG_SUPPORT_CONNINFRA == 1) +#include "coda/soc3_0/conn_infra_cfg.h" +#endif + +#include "precomp.h" +#include "gl_rst.h" +#include "soc3_0.h" +#include "hal_dmashdl_soc3_0.h" +#include +#include +#include +#include +#if (CFG_SUPPORT_VCODE_VDFS == 1) +#include +#endif /*#ifndef CFG_BUILD_X86_PLATFORM*/ + +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH +#include "fw_log_wifi.h" +#endif /* CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH */ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +#define CONN_MCU_CONFG_BASE 0x88000000 +#define CONN_MCU_CONFG_COM_REG0_ADDR (CONN_MCU_CONFG_BASE + 0x200) + +#define PATCH_SEMAPHORE_COMM_REG 0 +#define PATCH_SEMAPHORE_COMM_REG_PATCH_DONE 1 /* bit0 is for patch. */ + +#define SW_WORKAROUND_FOR_WFDMA_ISSUE_HWITS00009838 1 + +#define SOC3_0_FILE_NAME_TOTAL 8 +#define SOC3_0_FILE_NAME_MAX 64 +/* this is workaround for AXE, do not sync back to trunk*/ + +#if (CFG_SUPPORT_CONNINFRA == 1) +static struct sub_drv_ops_cb g_conninfra_wf_cb; +#endif + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +#if (CFG_POWER_ON_DOWNLOAD_EMI_ROM_PATCH == 1) +static uint8_t *soc3_0_apucFwName[] = { + (uint8_t *) CFG_FW_FILENAME "_MT", + NULL +}; + +static uint8_t *soc3_0_apucCr4FwName[] = { + (uint8_t *) CFG_CR4_FW_FILENAME "_MT", + NULL +}; +#endif + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ +#if (CFG_SUPPORT_PRE_ON_PHY_ACTION == 1) + +#if CFG_MTK_ANDROID_EMI +u_int8_t *gEmiCalResult; +u_int32_t gEmiCalSize; +u_int32_t gEmiCalOffset; +bool gEmiCalUseEmiData; +#endif + +struct wireless_dev *grWdev; + +#endif /* (CFG_SUPPORT_PRE_ON_PHY_ACTION == 1) */ + +#if (CFG_SUPPORT_VCODE_VDFS == 1) +static struct pm_qos_request wifi_req; +#endif + +bool gCoAntVFE28En = FALSE; + +uint8_t *apucsoc3_0FwName[] = { + (uint8_t *) CFG_FW_FILENAME "_soc3_0", + NULL +}; + +struct ECO_INFO soc3_0_eco_table[] = { + /* HW version, ROM version, Factory version */ + {0x00, 0x00, 0xA, 0x1}, /* E1 */ + {0x00, 0x00, 0x0, 0x0} /* End of table */ +}; + +#if defined(_HIF_PCIE) +struct PCIE_CHIP_CR_MAPPING soc3_0_bus2chip_cr_mapping[] = { + /* chip addr, bus addr, range */ + {0x54000000, 0x02000, 0x1000}, /* WFDMA PCIE0 MCU DMA0 */ + {0x55000000, 0x03000, 0x1000}, /* WFDMA PCIE0 MCU DMA1 */ + {0x56000000, 0x04000, 0x1000}, /* WFDMA reserved */ + {0x57000000, 0x05000, 0x1000}, /* WFDMA MCU wrap CR */ + {0x58000000, 0x06000, 0x1000}, /* WFDMA PCIE1 MCU DMA0 (MEM_DMA) */ + {0x59000000, 0x07000, 0x1000}, /* WFDMA PCIE1 MCU DMA1 */ + {0x820c0000, 0x08000, 0x4000}, /* WF_UMAC_TOP (PLE) */ + {0x820c8000, 0x0c000, 0x2000}, /* WF_UMAC_TOP (PSE) */ + {0x820cc000, 0x0e000, 0x2000}, /* WF_UMAC_TOP (PP) */ + {0x820e0000, 0x20000, 0x0400}, /* WF_LMAC_TOP BN0 (WF_CFG) */ + {0x820e1000, 0x20400, 0x0200}, /* WF_LMAC_TOP BN0 (WF_TRB) */ + {0x820e2000, 0x20800, 0x0400}, /* WF_LMAC_TOP BN0 (WF_AGG) */ + {0x820e3000, 0x20c00, 0x0400}, /* WF_LMAC_TOP BN0 (WF_ARB) */ + {0x820e4000, 0x21000, 0x0400}, /* WF_LMAC_TOP BN0 (WF_TMAC) */ + {0x820e5000, 0x21400, 0x0800}, /* WF_LMAC_TOP BN0 (WF_RMAC) */ + {0x820ce000, 0x21c00, 0x0200}, /* WF_LMAC_TOP (WF_SEC) */ + {0x820e7000, 0x21e00, 0x0200}, /* WF_LMAC_TOP BN0 (WF_DMA) */ + {0x820cf000, 0x22000, 0x1000}, /* WF_LMAC_TOP (WF_PF) */ + {0x820e9000, 0x23400, 0x0200}, /* WF_LMAC_TOP BN0 (WF_WTBLOFF) */ + {0x820ea000, 0x24000, 0x0200}, /* WF_LMAC_TOP BN0 (WF_ETBF) */ + {0x820eb000, 0x24200, 0x0400}, /* WF_LMAC_TOP BN0 (WF_LPON) */ + {0x820ec000, 0x24600, 0x0200}, /* WF_LMAC_TOP BN0 (WF_INT) */ + {0x820ed000, 0x24800, 0x0800}, /* WF_LMAC_TOP BN0 (WF_MIB) */ + {0x820ca000, 0x26000, 0x2000}, /* WF_LMAC_TOP BN0 (WF_MUCOP) */ + {0x820d0000, 0x30000, 0x10000}, /* WF_LMAC_TOP (WF_WTBLON) */ + {0x40000000, 0x70000, 0x10000}, /* WF_UMAC_SYSRAM */ + {0x00400000, 0x80000, 0x10000}, /* WF_MCU_SYSRAM */ + {0x00410000, 0x90000, 0x10000}, /* WF_MCU_SYSRAM (configure register) */ + {0x820f0000, 0xa0000, 0x0400}, /* WF_LMAC_TOP BN1 (WF_CFG) */ + {0x820f1000, 0xa0600, 0x0200}, /* WF_LMAC_TOP BN1 (WF_TRB) */ + {0x820f2000, 0xa0800, 0x0400}, /* WF_LMAC_TOP BN1 (WF_AGG) */ + {0x820f3000, 0xa0c00, 0x0400}, /* WF_LMAC_TOP BN1 (WF_ARB) */ + {0x820f4000, 0xa1000, 0x0400}, /* WF_LMAC_TOP BN1 (WF_TMAC) */ + {0x820f5000, 0xa1400, 0x0800}, /* WF_LMAC_TOP BN1 (WF_RMAC) */ + {0x820f7000, 0xa1e00, 0x0200}, /* WF_LMAC_TOP BN1 (WF_DMA) */ + {0x820f9000, 0xa3400, 0x0200}, /* WF_LMAC_TOP BN1 (WF_WTBLOFF) */ + {0x820fa000, 0xa4000, 0x0200}, /* WF_LMAC_TOP BN1 (WF_ETBF) */ + {0x820fb000, 0xa4200, 0x0400}, /* WF_LMAC_TOP BN1 (WF_LPON) */ + {0x820fc000, 0xa4600, 0x0200}, /* WF_LMAC_TOP BN1 (WF_INT) */ + {0x820fd000, 0xa4800, 0x0800}, /* WF_LMAC_TOP BN1 (WF_MIB) */ + {0x820c4000, 0xa8000, 0x4000}, /* WF_LMAC_TOP (WF_UWTBL) */ + {0x820b0000, 0xae000, 0x1000}, /* [APB2] WFSYS_ON */ + {0x80020000, 0xb0000, 0x10000}, /* WF_TOP_MISC_OFF */ + {0x81020000, 0xc0000, 0x10000}, /* WF_TOP_MISC_ON */ + {0x7c500000, 0x50000, 0x10000}, /* CONN_INFRA, dyn mem map */ + {0x7c020000, 0xd0000, 0x10000}, /* CONN_INFRA, wfdma */ + {0x7c060000, 0xe0000, 0x10000}, /* CONN_INFRA, conn_host_csr_top */ + {0x7c000000, 0xf0000, 0x10000}, /* CONN_INFRA */ + {0x0, 0x0, 0x0} /* End */ +}; +#elif defined(_HIF_AXI) +struct PCIE_CHIP_CR_MAPPING soc3_0_bus2chip_cr_mapping[] = { + /* chip addr, bus addr, range */ + {0x54000000, 0x402000, 0x1000}, /* WFDMA PCIE0 MCU DMA0 */ + {0x55000000, 0x403000, 0x1000}, /* WFDMA PCIE0 MCU DMA1 */ + {0x56000000, 0x404000, 0x1000}, /* WFDMA reserved */ + {0x57000000, 0x405000, 0x1000}, /* WFDMA MCU wrap CR */ + {0x58000000, 0x406000, 0x1000}, /* WFDMA PCIE1 MCU DMA0 (MEM_DMA) */ + {0x59000000, 0x407000, 0x1000}, /* WFDMA PCIE1 MCU DMA1 */ + {0x820c0000, 0x408000, 0x4000}, /* WF_UMAC_TOP (PLE) */ + {0x820c8000, 0x40c000, 0x2000}, /* WF_UMAC_TOP (PSE) */ + {0x820cc000, 0x40e000, 0x2000}, /* WF_UMAC_TOP (PP) */ + {0x820e0000, 0x420000, 0x0400}, /* WF_LMAC_TOP BN0 (WF_CFG) */ + {0x820e1000, 0x420400, 0x0200}, /* WF_LMAC_TOP BN0 (WF_TRB) */ + {0x820e2000, 0x420800, 0x0400}, /* WF_LMAC_TOP BN0 (WF_AGG) */ + {0x820e3000, 0x420c00, 0x0400}, /* WF_LMAC_TOP BN0 (WF_ARB) */ + {0x820e4000, 0x421000, 0x0400}, /* WF_LMAC_TOP BN0 (WF_TMAC) */ + {0x820e5000, 0x421400, 0x0800}, /* WF_LMAC_TOP BN0 (WF_RMAC) */ + {0x820ce000, 0x421c00, 0x0200}, /* WF_LMAC_TOP (WF_SEC) */ + {0x820e7000, 0x421e00, 0x0200}, /* WF_LMAC_TOP BN0 (WF_DMA) */ + {0x820cf000, 0x422000, 0x1000}, /* WF_LMAC_TOP (WF_PF) */ + {0x820e9000, 0x423400, 0x0200}, /* WF_LMAC_TOP BN0 (WF_WTBLOFF) */ + {0x820ea000, 0x424000, 0x0200}, /* WF_LMAC_TOP BN0 (WF_ETBF) */ + {0x820eb000, 0x424200, 0x0400}, /* WF_LMAC_TOP BN0 (WF_LPON) */ + {0x820ec000, 0x424600, 0x0200}, /* WF_LMAC_TOP BN0 (WF_INT) */ + {0x820ed000, 0x424800, 0x0800}, /* WF_LMAC_TOP BN0 (WF_MIB) */ + {0x820ca000, 0x426000, 0x2000}, /* WF_LMAC_TOP BN0 (WF_MUCOP) */ + {0x820d0000, 0x430000, 0x10000}, /* WF_LMAC_TOP (WF_WTBLON) */ + {0x40000000, 0x470000, 0x10000}, /* WF_UMAC_SYSRAM */ + {0x00400000, 0x480000, 0x10000}, /* WF_MCU_SYSRAM */ + {0x00410000, 0x490000, 0x10000}, /* WF_MCU_SYSRAM (config register) */ + {0x820f0000, 0x4a0000, 0x0400}, /* WF_LMAC_TOP BN1 (WF_CFG) */ + {0x820f1000, 0x4a0600, 0x0200}, /* WF_LMAC_TOP BN1 (WF_TRB) */ + {0x820f2000, 0x4a0800, 0x0400}, /* WF_LMAC_TOP BN1 (WF_AGG) */ + {0x820f3000, 0x4a0c00, 0x0400}, /* WF_LMAC_TOP BN1 (WF_ARB) */ + {0x820f4000, 0x4a1000, 0x0400}, /* WF_LMAC_TOP BN1 (WF_TMAC) */ + {0x820f5000, 0x4a1400, 0x0800}, /* WF_LMAC_TOP BN1 (WF_RMAC) */ + {0x820f7000, 0x4a1e00, 0x0200}, /* WF_LMAC_TOP BN1 (WF_DMA) */ + {0x820f9000, 0x4a3400, 0x0200}, /* WF_LMAC_TOP BN1 (WF_WTBLOFF) */ + {0x820fa000, 0x4a4000, 0x0200}, /* WF_LMAC_TOP BN1 (WF_ETBF) */ + {0x820fb000, 0x4a4200, 0x0400}, /* WF_LMAC_TOP BN1 (WF_LPON) */ + {0x820fc000, 0x4a4600, 0x0200}, /* WF_LMAC_TOP BN1 (WF_INT) */ + {0x820fd000, 0x4a4800, 0x0800}, /* WF_LMAC_TOP BN1 (WF_MIB) */ + {0x820c4000, 0x4a8000, 0x4000}, /* WF_LMAC_TOP (WF_UWTBL) */ + {0x820b0000, 0x4ae000, 0x1000}, /* [APB2] WFSYS_ON */ + {0x80020000, 0x4b0000, 0x10000}, /* WF_TOP_MISC_OFF */ + {0x81020000, 0x4c0000, 0x10000}, /* WF_TOP_MISC_ON */ + {0x7c500000, 0x500000, 0x10000}, /* CONN_INFRA, dyn mem map */ + {0x7c020000, 0x20000, 0x10000}, /* CONN_INFRA, wfdma */ + {0x7c060000, 0x60000, 0x10000}, /* CONN_INFRA, conn_host_csr_top */ + {0x7c000000, 0x00000, 0x10000}, /* CONN_INFRA, conn_infra_on */ + {0x0, 0x0, 0x0} /* End */ +}; +#endif + +static bool soc3_0WfdmaAllocRxRing( + struct GLUE_INFO *prGlueInfo, + bool fgAllocMem) +{ + if (!halWpdmaAllocRxRing(prGlueInfo, WFDMA0_RX_RING_IDX_2, + RX_RING1_SIZE, RXD_SIZE, RX_BUFFER_AGGRESIZE, + fgAllocMem)) { + DBGLOG(HAL, ERROR, "AllocWfdmaRxRing fail\n"); + return false; + } + if (!halWpdmaAllocRxRing(prGlueInfo, WFDMA0_RX_RING_IDX_3, + RX_RING1_SIZE, RXD_SIZE, RX_BUFFER_AGGRESIZE, + fgAllocMem)) { + DBGLOG(HAL, ERROR, "AllocWfdmaRxRing fail\n"); + return false; + } + if (!halWpdmaAllocRxRing(prGlueInfo, WFDMA1_RX_RING_IDX_0, + RX_RING1_SIZE, RXD_SIZE, RX_BUFFER_AGGRESIZE, + fgAllocMem)) { + DBGLOG(HAL, ERROR, "AllocWfdmaRxRing fail\n"); + return false; + } + return true; +} + +static void soc3_0asicConnac2xInterruptSettings( + struct ADAPTER *prAdapter, + IN u_int8_t enable) +{ + union soc3_0_WPDMA_INT_MASK IntMask; + ASSERT(prAdapter); + + if (enable) { + IntMask.word = 0; + + IntMask.field_wfdma0_ena.wfdma0_rx_done_0 = 1; + IntMask.field_wfdma0_ena.wfdma0_rx_done_1 = 1; + IntMask.field_wfdma0_ena.wfdma0_rx_done_2 = 1; + IntMask.field_wfdma0_ena.wfdma0_rx_done_3 = 1; + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR, IntMask.word); + + IntMask.word = 0; + + IntMask.field_wfdma1_ena.wfdma1_tx_done_0 = 1; + IntMask.field_wfdma1_ena.wfdma1_tx_done_1 = 1; + IntMask.field_wfdma1_ena.wfdma1_tx_done_16 = 1; + IntMask.field_wfdma1_ena.wfdma1_tx_done_17 = 1; + IntMask.field_wfdma1_ena.wfdma1_rx_done_0 = 1; + IntMask.field_wfdma1_ena.wfdma1_mcu2host_sw_int_en = 1; + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_ADDR, IntMask.word); + } else { + + IntMask.word = 0; + IntMask.field_wfdma0_ena.wfdma0_rx_done_0 = 1; + IntMask.field_wfdma0_ena.wfdma0_rx_done_1 = 1; + IntMask.field_wfdma0_ena.wfdma0_rx_done_2 = 1; + IntMask.field_wfdma0_ena.wfdma0_rx_done_3 = 1; + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR, IntMask.word); + + IntMask.word = 0; + IntMask.field_wfdma1_ena.wfdma1_tx_done_0 = 1; + IntMask.field_wfdma1_ena.wfdma1_tx_done_1 = 1; + IntMask.field_wfdma1_ena.wfdma1_tx_done_16 = 1; + IntMask.field_wfdma1_ena.wfdma1_tx_done_17 = 1; + IntMask.field_wfdma1_ena.wfdma1_rx_done_0 = 1; + IntMask.field_wfdma1_ena.wfdma1_mcu2host_sw_int_en = 1; + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_ADDR, IntMask.word); + } + +} + +static void soc3_0asicConnac2xWfdmaControl( + struct GLUE_INFO *prGlueInfo, + u_int8_t ucDmaIdx, + u_int8_t enable) +{ + struct ADAPTER *prAdapter = prGlueInfo->prAdapter; + union WPDMA_GLO_CFG_STRUCT GloCfg; + uint32_t u4DmaCfgCr; + uint32_t u4DmaRstDtxPtrCr; + uint32_t u4DmaRstDrxPtrCr; + + ASSERT(ucDmaIdx < CONNAC2X_WFDMA_COUNT); + u4DmaCfgCr = asicConnac2xWfdmaCfgAddrGet(prGlueInfo, ucDmaIdx); + u4DmaRstDtxPtrCr = + asicConnac2xWfdmaIntRstDtxPtrAddrGet(prGlueInfo, ucDmaIdx); + u4DmaRstDrxPtrCr = + asicConnac2xWfdmaIntRstDrxPtrAddrGet(prGlueInfo, ucDmaIdx); + + HAL_MCR_RD(prAdapter, u4DmaCfgCr, &GloCfg.word); + if (enable == TRUE) { + GloCfg.field_conn2x.pdma_bt_size = 3; + GloCfg.field_conn2x.tx_wb_ddone = 1; + GloCfg.field_conn2x.fifo_little_endian = 1; + GloCfg.field_conn2x.clk_gate_dis = 1; + GloCfg.field_conn2x.omit_tx_info = 1; + if (ucDmaIdx == 1) + GloCfg.field_conn2x.omit_rx_info = 1; + GloCfg.field_conn2x.csr_disp_base_ptr_chain_en = 1; + GloCfg.field_conn2x.omit_rx_info_pfet2 = 1; + } else { + GloCfg.field_conn2x.tx_dma_en = 0; + GloCfg.field_conn2x.rx_dma_en = 0; + GloCfg.field_conn2x.csr_disp_base_ptr_chain_en = 0; + GloCfg.field_conn2x.omit_tx_info = 0; + GloCfg.field_conn2x.omit_rx_info = 0; + GloCfg.field_conn2x.omit_rx_info_pfet2 = 0; + } + HAL_MCR_WR(prAdapter, u4DmaCfgCr, GloCfg.word); + + if (!enable) { + asicConnac2xWfdmaWaitIdle(prGlueInfo, ucDmaIdx, 100, 1000); + /* Reset DMA Index */ + HAL_MCR_WR(prAdapter, u4DmaRstDtxPtrCr, 0xFFFFFFFF); + HAL_MCR_WR(prAdapter, u4DmaRstDrxPtrCr, 0xFFFFFFFF); + } +} + +void soc3_0asicConnac2xWpdmaConfig( + struct GLUE_INFO *prGlueInfo, + u_int8_t enable, + bool fgResetHif) +{ + struct ADAPTER *prAdapter = prGlueInfo->prAdapter; + union WPDMA_GLO_CFG_STRUCT GloCfg[CONNAC2X_WFDMA_COUNT] = {0}; + uint32_t u4DmaCfgCr = 0; + uint32_t idx = 0; + struct mt66xx_chip_info *chip_info = prAdapter->chip_info; + + for (idx = 0; idx < CONNAC2X_WFDMA_COUNT; idx++) { + if (!chip_info->is_support_wfdma1 && idx) + break; + soc3_0asicConnac2xWfdmaControl(prGlueInfo, idx, enable); + u4DmaCfgCr = asicConnac2xWfdmaCfgAddrGet(prGlueInfo, idx); + HAL_MCR_RD(prAdapter, u4DmaCfgCr, &GloCfg[idx].word); + } + + /* set interrupt Mask */ + soc3_0asicConnac2xInterruptSettings(prAdapter, enable); + + if (enable) { + for (idx = 0; idx < CONNAC2X_WFDMA_COUNT; idx++) { + if (!chip_info->is_support_wfdma1 && idx) + break; + u4DmaCfgCr = + asicConnac2xWfdmaCfgAddrGet(prGlueInfo, idx); + GloCfg[idx].field_conn2x.tx_dma_en = 1; + GloCfg[idx].field_conn2x.rx_dma_en = 1; + HAL_MCR_WR(prAdapter, u4DmaCfgCr, GloCfg[idx].word); + } + } +} + +void soc3_0ReadExtIntStatus( + struct ADAPTER *prAdapter, + uint32_t *pu4IntStatus) +{ + uint32_t u4RegValue = 0; + uint32_t ap_write_value = 0; + struct GL_HIF_INFO *prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + struct BUS_INFO *prBusInfo = prAdapter->chip_info->bus_info; + + *pu4IntStatus = 0; + + HAL_MCR_RD(prAdapter, + CONNAC2X_WPDMA_EXT_INT_STA( + prBusInfo->host_ext_conn_hif_wrap_base), + &u4RegValue); + + if (HAL_IS_CONNAC2X_EXT_RX_DONE_INTR(u4RegValue, + prBusInfo->host_int_rxdone_bits)) { + *pu4IntStatus |= WHISR_RX0_DONE_INT; + ap_write_value |= (u4RegValue & + prBusInfo->host_int_rxdone_bits); + } + + if (HAL_IS_CONNAC2X_EXT_TX_DONE_INTR(u4RegValue, + prBusInfo->host_int_txdone_bits)) { + ap_write_value |= (u4RegValue & + prBusInfo->host_int_txdone_bits); + *pu4IntStatus |= WHISR_TX_DONE_INT; + } + + if (u4RegValue & CONNAC_MCU_SW_INT) { + *pu4IntStatus |= WHISR_D2H_SW_INT; + ap_write_value |= (u4RegValue & CONNAC_MCU_SW_INT); + } + + prHifInfo->u4IntStatus = u4RegValue; + + /* clear interrupt */ + HAL_MCR_WR(prAdapter, + CONNAC2X_WPDMA_EXT_INT_STA( + prBusInfo->host_ext_conn_hif_wrap_base), + ap_write_value); + +} + +void soc3_0asicConnac2xProcessTxInterrupt(IN struct ADAPTER *prAdapter) +{ + struct GL_HIF_INFO *prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + union WPDMA_INT_STA_STRUCT rIntrStatus; + + rIntrStatus = (union WPDMA_INT_STA_STRUCT)prHifInfo->u4IntStatus; + if (rIntrStatus.field_conn2x_ext.wfdma1_tx_done_16) + halWpdmaProcessCmdDmaDone(prAdapter->prGlueInfo, + TX_RING_FWDL_IDX_3); + + if (rIntrStatus.field_conn2x_ext.wfdma1_tx_done_17) + halWpdmaProcessCmdDmaDone(prAdapter->prGlueInfo, + TX_RING_CMD_IDX_2); + + if (rIntrStatus.field_conn2x_ext.wfdma1_tx_done_0) { + halWpdmaProcessDataDmaDone(prAdapter->prGlueInfo, + TX_RING_DATA0_IDX_0); + + kalSetTxEvent2Hif(prAdapter->prGlueInfo); + } + + if (rIntrStatus.field_conn2x_ext.wfdma1_tx_done_1) { + halWpdmaProcessDataDmaDone(prAdapter->prGlueInfo, + TX_RING_DATA1_IDX_1); + + kalSetTxEvent2Hif(prAdapter->prGlueInfo); + } + +} + +void soc3_0asicConnac2xProcessRxInterrupt( + struct ADAPTER *prAdapter) +{ + struct GL_HIF_INFO *prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + union WPDMA_INT_STA_STRUCT rIntrStatus; + + rIntrStatus = (union WPDMA_INT_STA_STRUCT)prHifInfo->u4IntStatus; + if (rIntrStatus.field_conn2x_ext.wfdma1_rx_done_0 || + (prAdapter->u4NoMoreRfb & BIT(WFDMA1_RX_RING_IDX_0))) + halRxReceiveRFBs(prAdapter, WFDMA1_RX_RING_IDX_0, FALSE); + + if (rIntrStatus.field_conn2x_ext.wfdma0_rx_done_0 || + (prAdapter->u4NoMoreRfb & BIT(RX_RING_DATA_IDX_0))) + halRxReceiveRFBs(prAdapter, RX_RING_DATA_IDX_0, TRUE); + + if (rIntrStatus.field_conn2x_ext.wfdma0_rx_done_1 || + (prAdapter->u4NoMoreRfb & BIT(RX_RING_EVT_IDX_1))) + halRxReceiveRFBs(prAdapter, RX_RING_EVT_IDX_1, TRUE); + + if (rIntrStatus.field_conn2x_ext.wfdma0_rx_done_2 || + (prAdapter->u4NoMoreRfb & BIT(WFDMA0_RX_RING_IDX_2))) + halRxReceiveRFBs(prAdapter, WFDMA0_RX_RING_IDX_2, TRUE); + + if (rIntrStatus.field_conn2x_ext.wfdma0_rx_done_3 || + (prAdapter->u4NoMoreRfb & BIT(WFDMA0_RX_RING_IDX_3))) + halRxReceiveRFBs(prAdapter, WFDMA0_RX_RING_IDX_3, TRUE); +} + +static void soc3_0SetMDRXRingPriorityInterrupt(struct ADAPTER *prAdapter) +{ + u_int32_t val = 0; + + HAL_MCR_RD(prAdapter, + WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_ADDR, &val); + val |= BITS(4, 7); + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_ADDR, val); + HAL_MCR_RD(prAdapter, + WF_WFDMA_HOST_DMA1_WPDMA_INT_RX_PRI_SEL_ADDR, &val); + val |= BIT(1); + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA1_WPDMA_INT_RX_PRI_SEL_ADDR, val); +} + +void soc3_0asicConnac2xWfdmaManualPrefetch( + struct GLUE_INFO *prGlueInfo) +{ + struct ADAPTER *prAdapter = prGlueInfo->prAdapter; + u_int32_t val = 0; + + HAL_MCR_RD(prAdapter, WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR, &val); + /* disable prefetch offset calculation auto-mode */ + val &= + ~WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN_MASK; + HAL_MCR_WR(prAdapter, WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR, val); + + HAL_MCR_RD(prAdapter, WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR, &val); + /* disable prefetch offset calculation auto-mode */ + val &= + ~WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN_MASK; + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR, val); + + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_EXT_CTRL_ADDR, 0x00000004); + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_EXT_CTRL_ADDR, 0x00400004); + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_EXT_CTRL_ADDR, 0x00800004); + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_EXT_CTRL_ADDR, 0x00c00004); + + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_EXT_CTRL_ADDR, 0x01000004); + + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_EXT_CTRL_ADDR, 0x01400004); + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_EXT_CTRL_ADDR, 0x01800004); + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_EXT_CTRL_ADDR, 0x01c00004); + + /* HIF_DMA1_TX*/ + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_EXT_CTRL_ADDR, 0x02400004); + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_EXT_CTRL_ADDR, 0x02800004); +#if (SW_WORKAROUND_FOR_WFDMA_ISSUE_HWITS00009838 == 1) + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_EXT_CTRL_ADDR, 0x02c00004); +#endif + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_EXT_CTRL_ADDR, 0x03000004); + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_EXT_CTRL_ADDR, 0x03400004); +#if (SW_WORKAROUND_FOR_WFDMA_ISSUE_HWITS00009838 == 1) + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_EXT_CTRL_ADDR, 0x03800004); +#endif + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_EXT_CTRL_ADDR, 0x03c00004); + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_EXT_CTRL_ADDR, 0x04000004); + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_EXT_CTRL_ADDR, 0x04400004); +#if (SW_WORKAROUND_FOR_WFDMA_ISSUE_HWITS00009838 == 1) + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_EXT_CTRL_ADDR, 0x04800004); +#endif + + /* HIF_DMA1_RX*/ + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_EXT_CTRL_ADDR, 0x04C00004); + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_EXT_CTRL_ADDR, 0x05000004); + +#if (SW_WORKAROUND_FOR_WFDMA_ISSUE_HWITS00009838 == 1) + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_EXT_CTRL_ADDR, 0x05400004); +#endif + + soc3_0SetMDRXRingPriorityInterrupt(prAdapter); + + /* reset dma idx */ + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_ADDR, 0xFFFFFFFF); + HAL_MCR_WR(prAdapter, + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR, 0xFFFFFFFF); + +#if defined(_HIF_AXI) + /*Bypass BID check*/ + soc3_0_WfdmaAxiCtrl(prAdapter); +#endif + +} + +void soc3_0_WfdmaAxiCtrl( + struct ADAPTER *prAdapter) +{ + uint32_t u4Val = 0; + + HAL_MCR_RD(prAdapter, WFDMA_AXI0_R2A_CTRL_0, &u4Val); + u4Val |= BID_CHK_BYP_EN_MASK; + HAL_MCR_WR(prAdapter, WFDMA_AXI0_R2A_CTRL_0, u4Val); + +} + +void soc3_0_ConstructPatchName(struct GLUE_INFO *prGlueInfo, + uint8_t **apucName, uint8_t *pucNameIdx) +{ + int ret = 0; + uint8_t aucFlavor[2] = {0}; + + kalGetFwFlavor(&aucFlavor[0]); + + ret = kalSnprintf(apucName[(*pucNameIdx)], + SOC3_0_FILE_NAME_MAX, + "soc3_0_patch_wmmcu_%u%s_%x_hdr.bin", + CFG_WIFI_IP_SET, + aucFlavor, + wlanGetEcoVersion(prGlueInfo->prAdapter)); + + if (ret < 0 || ret >= CFG_FW_NAME_MAX_LEN) + DBGLOG(INIT, ERROR, "kalSnprintf failed, ret: %d\n", ret); +} + +struct BUS_INFO soc3_0_bus_info = { +#if defined(_HIF_PCIE) || defined(_HIF_AXI) + .top_cfg_base = SOC3_0_TOP_CFG_BASE, + + /* host_dma0 for TXP */ + .host_dma0_base = CONNAC2X_HOST_WPDMA_0_BASE, + /* host_dma1 for TXD and host cmd to WX_CPU */ + .host_dma1_base = CONNAC2X_HOST_WPDMA_1_BASE, + .host_ext_conn_hif_wrap_base = CONNAC2X_HOST_EXT_CONN_HIF_WRAP, + .host_int_status_addr = + CONNAC2X_WPDMA_EXT_INT_STA(CONNAC2X_HOST_EXT_CONN_HIF_WRAP), + + .host_int_txdone_bits = (CONNAC2X_EXT_WFDMA1_TX_DONE_INT0 + | CONNAC2X_EXT_WFDMA1_TX_DONE_INT1 + | CONNAC2X_EXT_WFDMA1_TX_DONE_INT2 + | CONNAC2X_EXT_WFDMA1_TX_DONE_INT3 + | CONNAC2X_EXT_WFDMA1_TX_DONE_INT4 + | CONNAC2X_EXT_WFDMA1_TX_DONE_INT5 + | CONNAC2X_EXT_WFDMA1_TX_DONE_INT6 + | CONNAC2X_EXT_WFDMA1_TX_DONE_INT16 + | CONNAC2X_EXT_WFDMA1_TX_DONE_INT17), + .host_int_rxdone_bits = (CONNAC2X_EXT_WFDMA1_RX_DONE_INT0 + | CONNAC2X_EXT_WFDMA0_RX_DONE_INT0 + | CONNAC2X_EXT_WFDMA0_RX_DONE_INT1 + | CONNAC2X_EXT_WFDMA0_RX_DONE_INT2 + | CONNAC2X_EXT_WFDMA0_RX_DONE_INT3 + ), + + .host_tx_ring_base = + CONNAC2X_TX_RING_BASE(CONNAC2X_HOST_WPDMA_1_BASE), + .host_tx_ring_ext_ctrl_base = + CONNAC2X_TX_RING_EXT_CTRL_BASE(CONNAC2X_HOST_WPDMA_1_BASE), + .host_tx_ring_cidx_addr = + CONNAC2X_TX_RING_CIDX(CONNAC2X_HOST_WPDMA_1_BASE), + .host_tx_ring_didx_addr = + CONNAC2X_TX_RING_DIDX(CONNAC2X_HOST_WPDMA_1_BASE), + .host_tx_ring_cnt_addr = + CONNAC2X_TX_RING_CNT(CONNAC2X_HOST_WPDMA_1_BASE), + + .host_rx_ring_base = + CONNAC2X_RX_RING_BASE(CONNAC2X_HOST_WPDMA_0_BASE), + .host_rx_ring_ext_ctrl_base = + CONNAC2X_RX_RING_EXT_CTRL_BASE(CONNAC2X_HOST_WPDMA_0_BASE), + .host_rx_ring_cidx_addr = + CONNAC2X_RX_RING_CIDX(CONNAC2X_HOST_WPDMA_0_BASE), + .host_rx_ring_didx_addr = + CONNAC2X_RX_RING_DIDX(CONNAC2X_HOST_WPDMA_0_BASE), + .host_rx_ring_cnt_addr = + CONNAC2X_RX_RING_CNT(CONNAC2X_HOST_WPDMA_0_BASE), + + .host_wfdma1_rx_ring_base = + CONNAC2X_WFDMA1_RX_RING_BASE(CONNAC2X_HOST_WPDMA_1_BASE), + .host_wfdma1_rx_ring_cidx_addr = + CONNAC2X_WFDMA1_RX_RING_CIDX(CONNAC2X_HOST_WPDMA_1_BASE), + .host_wfdma1_rx_ring_didx_addr = + CONNAC2X_WFDMA1_RX_RING_DIDX(CONNAC2X_HOST_WPDMA_1_BASE), + .host_wfdma1_rx_ring_cnt_addr = + CONNAC2X_WFDMA1_RX_RING_CNT(CONNAC2X_HOST_WPDMA_1_BASE), + .host_wfdma1_rx_ring_ext_ctrl_base = + CONNAC2X_WFDMA1_RX_RING_EXT_CTRL_BASE( + CONNAC2X_HOST_WPDMA_1_BASE), + + .bus2chip = soc3_0_bus2chip_cr_mapping, +#if defined(_HIF_PCIE) + .max_static_map_addr = 0x000f0000, +#elif defined(_HIF_AXI) + .max_static_map_addr = 0x00700000, +#endif + .tx_ring_fwdl_idx = CONNAC2X_FWDL_TX_RING_IDX, + .tx_ring_cmd_idx = CONNAC2X_CMD_TX_RING_IDX, + .tx_ring0_data_idx = 0, + .tx_ring1_data_idx = 1, + .fw_own_clear_addr = CONNAC2X_BN0_IRQ_STAT_ADDR, + .fw_own_clear_bit = PCIE_LPCR_FW_CLR_OWN, + .fgCheckDriverOwnInt = FALSE, + .u4DmaMask = 32, + .pdmaSetup = soc3_0asicConnac2xWpdmaConfig, + .enableInterrupt = asicConnac2xEnablePlatformIRQ, + .disableInterrupt = asicConnac2xDisablePlatformIRQ, + + .processTxInterrupt = soc3_0asicConnac2xProcessTxInterrupt, + .processRxInterrupt = soc3_0asicConnac2xProcessRxInterrupt, + .tx_ring_ext_ctrl = asicConnac2xWfdmaTxRingExtCtrl, + .rx_ring_ext_ctrl = asicConnac2xWfdmaRxRingExtCtrl, + /* null wfdmaManualPrefetch if want to disable manual mode */ + .wfdmaManualPrefetch = soc3_0asicConnac2xWfdmaManualPrefetch, + .lowPowerOwnRead = asicConnac2xLowPowerOwnRead, + .lowPowerOwnSet = asicConnac2xLowPowerOwnSet, + .lowPowerOwnClear = asicConnac2xLowPowerOwnClear, + .wakeUpWiFi = asicWakeUpWiFi, + .processSoftwareInterrupt = asicConnac2xProcessSoftwareInterrupt, + .softwareInterruptMcu = asicConnac2xSoftwareInterruptMcu, + .hifRst = asicConnac2xHifRst, + + .initPcieInt = NULL, + .devReadIntStatus = soc3_0ReadExtIntStatus, + .DmaShdlInit = mt6885DmashdlInit, + .wfdmaAllocRxRing = soc3_0WfdmaAllocRxRing, +#endif /*_HIF_PCIE || _HIF_AXI */ +}; + +#if CFG_ENABLE_FW_DOWNLOAD +struct FWDL_OPS_T soc3_0_fw_dl_ops = { +#if (CFG_POWER_ON_DOWNLOAD_EMI_ROM_PATCH == 1) + .constructFirmwarePrio = soc3_0_ConstructFirmwarePrio, +#else + .constructFirmwarePrio = NULL, +#endif + .constructPatchName = soc3_0_ConstructPatchName, + .downloadPatch = wlanDownloadPatch, + .downloadFirmware = wlanConnacFormatDownload, +#if (CFG_DOWNLOAD_DYN_MEMORY_MAP == 1) + .downloadByDynMemMap = soc3_0_DownloadByDynMemMap, +#else + .downloadByDynMemMap = NULL, +#endif + .getFwInfo = wlanGetConnacFwInfo, + .getFwDlInfo = asicGetFwDlInfo, +#if (CFG_SUPPORT_PRE_ON_PHY_ACTION == 1) + .phyAction = soc3_0_wlanPhyAction, +#else + .phyAction = NULL, +#endif +}; +#endif /* CFG_ENABLE_FW_DOWNLOAD */ + +struct TX_DESC_OPS_T soc3_0_TxDescOps = { + .fillNicAppend = fillNicTxDescAppend, + .fillHifAppend = fillTxDescAppendByHostV2, + .fillTxByteCount = fillConnac2xTxDescTxByteCount, +}; + +struct RX_DESC_OPS_T soc3_0_RxDescOps = { +}; + +struct CHIP_DBG_OPS soc3_0_debug_ops = { + .showPdmaInfo = soc3_0_show_wfdma_info, + .showPseInfo = soc3_0_show_pse_info, + .showPleInfo = soc3_0_show_ple_info, + .showTxdInfo = connac2x_show_txd_Info, + .showWtblInfo = connac2x_show_wtbl_info, + .showUmacFwtblInfo = connac2x_show_umac_wtbl_info, + .showCsrInfo = NULL, + .showDmaschInfo = soc3_0_show_dmashdl_info, + .dumpMacInfo = soc3_0_dump_mac_info, + .showHifInfo = NULL, + .printHifDbgInfo = NULL, + .show_rx_rate_info = connac2x_show_rx_rate_info, + .show_rx_rssi_info = connac2x_show_rx_rssi_info, + .show_stat_info = connac2x_show_stat_info, +#ifdef CFG_SUPPORT_LINK_QUALITY_MONITOR + .get_rx_rate_info = connac2x_get_rx_rate_info +#endif +}; + +#if CFG_SUPPORT_QA_TOOL +struct ATE_OPS_T soc3_0_AteOps = { + /*ICapStart phase out , wlan_service instead*/ + .setICapStart = connacSetICapStart, + /*ICapStatus phase out , wlan_service instead*/ + .getICapStatus = connacGetICapStatus, + /*CapIQData phase out , wlan_service instead*/ + .getICapIQData = connacGetICapIQData, + .getRbistDataDumpEvent = nicExtEventICapIQData, + .icapRiseVcoreClockRate = soc3_0_icapRiseVcoreClockRate, + .icapDownVcoreClockRate = soc3_0_icapDownVcoreClockRate +}; +#endif + + +/* Litien code refine to support multi chip */ +struct mt66xx_chip_info mt66xx_chip_info_soc3_0 = { + .bus_info = &soc3_0_bus_info, +#if CFG_ENABLE_FW_DOWNLOAD + .fw_dl_ops = &soc3_0_fw_dl_ops, +#endif /* CFG_ENABLE_FW_DOWNLOAD */ +#if CFG_SUPPORT_QA_TOOL + .prAteOps = &soc3_0_AteOps, +#endif /*CFG_SUPPORT_QA_TOOL*/ + .prDebugOps = &soc3_0_debug_ops, + .prTxDescOps = &soc3_0_TxDescOps, + .prRxDescOps = &soc3_0_RxDescOps, + .chip_id = SOC3_0_CHIP_ID, + .should_verify_chip_id = FALSE, + .sw_sync0 = SOC3_0_SW_SYNC0, + .sw_ready_bits = WIFI_FUNC_NO_CR4_READY_BITS, + .sw_ready_bit_offset = SOC3_0_SW_SYNC0_RDY_OFFSET, + .patch_addr = SOC3_0_PATCH_START_ADDR, + .is_support_cr4 = FALSE, + .is_support_wacpu = FALSE, + .txd_append_size = SOC3_0_TX_DESC_APPEND_LENGTH, + .rxd_size = SOC3_0_RX_DESC_LENGTH, + .init_evt_rxd_size = SOC3_0_RX_DESC_LENGTH, + .pse_header_length = CONNAC2X_NIC_TX_PSE_HEADER_LENGTH, + .init_event_size = CONNAC2X_RX_INIT_EVENT_LENGTH, + .eco_info = soc3_0_eco_table, + .isNicCapV1 = FALSE, + .top_hcr = CONNAC2X_TOP_HCR, + .top_hvr = CONNAC2X_TOP_HVR, + .top_fvr = CONNAC2X_TOP_FVR, + .arb_ac_mode_addr = SOC3_0_ARB_AC_MODE_ADDR, + .custom_oid_interface_version = MTK_CUSTOM_OID_INTERFACE_VERSION, + .em_interface_version = MTK_EM_INTERFACE_VERSION, + .asicCapInit = asicConnac2xCapInit, +#if CFG_ENABLE_FW_DOWNLOAD + .asicEnableFWDownload = NULL, +#endif /* CFG_ENABLE_FW_DOWNLOAD */ + .asicGetChipID = asicGetChipID, + .downloadBufferBin = NULL, + .is_support_hw_amsdu = TRUE, + .is_support_asic_lp = TRUE, + .is_support_wfdma1 = TRUE, + .get_rxv_from_rxrpt = TRUE, + .is_support_nvram_fragment = TRUE, + .asicWfdmaReInit = asicConnac2xWfdmaReInit, + .asicWfdmaReInit_handshakeInit = asicConnac2xWfdmaDummyCrWrite, + .group5_size = sizeof(struct HW_MAC_RX_STS_GROUP_5), + .u4LmacWtblDUAddr = CONNAC2X_WIFI_LWTBL_BASE, + .u4UmacWtblDUAddr = CONNAC2X_WIFI_UWTBL_BASE, + .wmmcupwron = hifWmmcuPwrOn, + .wmmcupwroff = hifWmmcuPwrOff, +#if (CFG_POWER_ON_DOWNLOAD_EMI_ROM_PATCH == 1) + .pwrondownload = soc3_0_wlanPowerOnDownload, +#else + .pwrondownload = NULL, +#endif + .triggerfwassert = soc3_0_Trigger_fw_assert, + .dumpwfsyscpupcr = soc3_0_DumpWfsyscpupcr, + + .coantSetWiFi = wlanCoAntWiFi, + .coantSetMD = wlanCoAntMD, + .coantVFE28En = wlanCoAntVFE28En, + .coantVFE28Dis = wlanCoAntVFE28Dis, +#if (CFG_SUPPORT_CONNINFRA == 1) + .coexpccifon = wlanConnacPccifon, + .coexpccifoff = wlanConnacPccifoff, + .trigger_wholechiprst = soc3_0_Trigger_whole_chip_rst, + .sw_interrupt_handler = soc3_0_Sw_interrupt_handler, + .conninra_cb_register = soc3_0_Conninfra_cb_register, +#endif +#if (CFG_SUPPORT_PRE_ON_PHY_ACTION == 1) + .getCalResult = soc3_0_wlanGetCalResult, + .calDebugCmd = soc3_0_wlanCalDebugCmd, +#endif + .checkbushang = soc3_0_CheckBusHang, + .dumpBusHangCr = soc3_0_DumpBusHangCr, + .cmd_max_pkt_size = CFG_TX_MAX_PKT_SIZE, /* size 1600 */ +}; + +struct mt66xx_hif_driver_data mt66xx_driver_data_soc3_0 = { + .chip_info = &mt66xx_chip_info_soc3_0, +}; + +#if (CFG_DOWNLOAD_DYN_MEMORY_MAP == 1) +uint32_t soc3_0_DownloadByDynMemMap(IN struct ADAPTER *prAdapter, + IN uint32_t u4Addr, IN uint32_t u4Len, + IN uint8_t *pucStartPtr, IN enum ENUM_IMG_DL_IDX_T eDlIdx) +{ +#if 0 + uint32_t u4Val = 0; + uint32_t u4Idx = 0; + uint32_t u4NonZeroMemCnt = 0; +#endif +#if defined(_HIF_AXI) + struct GL_HIF_INFO *prHifInfo = &prAdapter->prGlueInfo->rHifInfo; +#endif + +#if defined(_HIF_PCIE) + struct GL_HIF_INFO *prHifInfo = &prAdapter->prGlueInfo->rHifInfo; +#endif + + if ((eDlIdx == IMG_DL_IDX_PATCH) || (eDlIdx == IMG_DL_IDX_N9_FW)) { +/*#pragma message("wlanDownloadSectionByDynMemMap()::SOC3_0")*/ +#if defined(_HIF_AXI) + /* AXI workable version by bytes of u4Len in one movement */ + /* for PCIe WLAN drv, use 0x7C000000 based; + * for AXI, also use 0x7C000000 based + */ + HAL_MCR_WR(prAdapter, + CONN_INFRA_CFG_AP2WF_REMAP_1_ADDR, + u4Addr); + +#if 0 + if (eDlIdx == IMG_DL_IDX_PATCH) { + do { + u4Val = 0; + + kalMemCopy( + (void *)&u4Val, + (void *)( + prHifInfo->CSRBaseAddress+ + 0x500000+(u4Idx * 4)), + 4); + + if (u4Val != 0) + u4NonZeroMemCnt++; + } while (u4Idx++ < 20); + + if (u4NonZeroMemCnt != 0) { + DBGLOG(INIT, WARN, + "[MJ]ROM patch exists(%d)!\n", + u4NonZeroMemCnt); + + return WLAN_STATUS_NOT_ACCEPTED; + } + } +#endif + + memcpy_toio((void *)(prHifInfo->CSRBaseAddress+0x500000), + (void *)pucStartPtr, u4Len); +#endif + +#if defined(_HIF_PCIE) + HAL_MCR_RD(prAdapter, + CONN_INFRA_CFG_PCIE2AP_REMAP_2_ADDR, &u4Val); + + DBGLOG(INIT, WARN, "[MJ]ORIG(0x%08x) = 0x%08x\n", + CONN_INFRA_CFG_PCIE2AP_REMAP_2_ADDR, u4Val); + + /* + * 0x18=0x7C + * 0x18001120[31:0] = 0x00100000 + * 0x18500000 (AP) is 0x00100000(MCU) + * 0x18001198[31:16] = 0x1850 + * 0x18001198 = 0x1850|Value[15:0] + + u4Val = ((~BITS(31,16) & u4Val) | ((0x1850) << 16)); + */ + + /* this hard code is verified with DE for SOC3_0 */ + u4Val = CONN_INFRA_CFG_PCIE2AP_REMAP_2_ADDR_DE_HARDCODE; + + HAL_MCR_WR(prAdapter, + CONN_INFRA_CFG_PCIE2AP_REMAP_2_ADDR, u4Val); + + HAL_MCR_RD(prAdapter, + CONN_INFRA_CFG_PCIE2AP_REMAP_2_ADDR, &u4Val); + + DBGLOG(INIT, WARN, "[MJ]NEW(0x%08x) = 0x%08x\n", + CONN_INFRA_CFG_PCIE2AP_REMAP_2_ADDR, u4Val); + +#if 1 + /* PCIe workable version by bytes of u4Len in one movement */ + /* for PCIe WLAN drv, use 0x7C000000 based; + * for AXI, use 0x18000000 based + */ + HAL_MCR_WR(prAdapter, + CONN_INFRA_CFG_AP2WF_REMAP_1_ADDR, + u4Addr); + +#if 0 + if (eDlIdx == IMG_DL_IDX_PATCH) { + do { + u4Val = 0; + + HAL_MCR_RD(prAdapter, + (CONN_INFRA_CFG_AP2WF_BUS_ADDR + + (u4Idx * 4)), &u4Val); + + if (u4Val != 0) + u4NonZeroMemCnt++; + } while (u4Idx++ < 20); + + if (u4NonZeroMemCnt != 0) { + DBGLOG(INIT, WARN, + "[MJ]ROM patch exists(%d)!\n", + u4NonZeroMemCnt); + + return WLAN_STATUS_NOT_ACCEPTED; + } + } +#endif + + /* because + * soc3_0_bus2chip_cr_mapping = + * {0x7c500000, 0x50000, 0x10000} + */ + kalMemCopy((void *)(prHifInfo->CSRBaseAddress+0x50000), + (void *)pucStartPtr, u4Len); +#else + /* PCIe workable version by 4 bytes in one movement */ + /* for PCIe WLAN drv, use 0x7C000000 based; + * for AXI, use 0x18000000 based + */ + HAL_MCR_WR(prAdapter, + CONN_INFRA_CFG_AP2WF_REMAP_1_ADDR, + u4Addr); + + for (u4Offset = 0; u4Len > 0; u4Offset += u4RemapSize) { + if (u4Len > 4) + u4RemapSize = 4; + else + u4RemapSize = u4Len; + + u4Len -= u4RemapSize; + + HAL_MCR_WR(prAdapter, + (CONN_INFRA_CFG_AP2WF_BUS_ADDR + u4Offset), + (uint32_t) + (*(uint32_t *)((uint8_t *)pucStartPtr + u4Offset))); + + HAL_MCR_RD(prAdapter, + (CONN_INFRA_CFG_AP2WF_BUS_ADDR + u4Offset), &u4Val); + + /* You can uncomment it to see what is downloaded + *if (u4Idx++ < 20) { + *DBGLOG(INIT, WARN, "[MJ]0x%08x(%08x) = 0x%08x\n", + *(0x7C500000 + u4Offset), u4Val, + *(uint32_t)(*(uint32_t *) + *((uint8_t *)pucStartPtr + u4Offset))); + *} + */ + } +#endif +#endif /* _HIF_PCIE */ + } else { + return WLAN_STATUS_NOT_SUPPORTED; + } + + return WLAN_STATUS_SUCCESS; +} +#endif +void soc3_0_DumpWfsyscpupcr(struct ADAPTER *prAdapter) +{ +#define CPUPCR_LOG_NUM 5 +#define CPUPCR_BUF_SZ 50 + + uint32_t i = 0; + uint32_t var_pc = 0; + uint32_t var_lp = 0; + uint64_t log_sec = 0; + uint64_t log_nsec = 0; + char log_buf_pc[CPUPCR_LOG_NUM][CPUPCR_BUF_SZ]; + char log_buf_lp[CPUPCR_LOG_NUM][CPUPCR_BUF_SZ]; + + if (prAdapter == NULL) + return; + + for (i = 0; i < CPUPCR_LOG_NUM; i++) { + log_sec = local_clock(); + log_nsec = do_div(log_sec, 1000000000)/1000; + HAL_MCR_RD(prAdapter, WFSYS_CPUPCR_ADDR, &var_pc); + HAL_MCR_RD(prAdapter, WFSYS_LP_ADDR, &var_lp); + + kalSnprintf(log_buf_pc[i], CPUPCR_BUF_SZ, "%llu.%06llu/0x%08x;", + log_sec, + log_nsec, + var_pc); + + kalSnprintf(log_buf_lp[i], CPUPCR_BUF_SZ, "%llu.%06llu/0x%08x;", + log_sec, + log_nsec, + var_lp); + } + + DBGLOG(HAL, INFO, "wm pc=%s%s%s%s%s\n", + log_buf_pc[0], + log_buf_pc[1], + log_buf_pc[2], + log_buf_pc[3], + log_buf_pc[4]); + + DBGLOG(HAL, INFO, "wm lp=%s%s%s%s%s\n", + log_buf_lp[0], + log_buf_lp[1], + log_buf_lp[2], + log_buf_lp[3], + log_buf_lp[4]); +} + +void soc3_0_CrRead(struct ADAPTER *prAdapter, size_t addr, unsigned int *val) +{ + if (prAdapter == NULL) + wf_ioremap_read(addr, val); + else + HAL_MCR_RD(prAdapter, (addr|0x64000000), val); +} + +void soc3_0_CrWrite(struct ADAPTER *prAdapter, + phys_addr_t addr, unsigned int val) +{ + if (prAdapter == NULL) + wf_ioremap_write(addr, val); + else + HAL_MCR_WR(prAdapter, (addr|0x64000000), val); +} + +void soc3_0_DumpWfsysdebugflag(void) +{ + uint32_t i = 0, u4Value = 0; + uint32_t RegValue = 0x000F0001; + + for (i = 0; i < 15; i++) { + wf_ioremap_write(0x18060128, RegValue); + wf_ioremap_read(0x18060148, &u4Value); + DBGLOG(HAL, INFO, + "Bus hang dump: 0x18060148 = 0x%08x after 0x%08x\n", + u4Value, RegValue); + RegValue -= 0x10000; + } + RegValue = 0x00030002; + for (i = 0; i < 3; i++) { + wf_ioremap_write(0x18060128, RegValue); + wf_ioremap_read(0x18060148, &u4Value); + DBGLOG(HAL, INFO, + "Bus hang dump: 0x18060148 = 0x%08x after 0x%08x\n", + u4Value, RegValue); + RegValue -= 0x10000; + } + RegValue = 0x00040003; + for (i = 0; i < 4; i++) { + wf_ioremap_write(0x18060128, RegValue); + wf_ioremap_read(0x18060148, &u4Value); + DBGLOG(HAL, INFO, + "Bus hang dump: 0x18060148 = 0x%08x after 0x%08x\n", + u4Value, RegValue); + RegValue -= 0x10000; + } + +} + +void soc3_0_DumpWfsysInfo(void) +{ + int value = 0; + int value_2 = 0; + int i; + + for (i = 0; i < 5; i++) { + wf_ioremap_read(0x18060204, &value); + wf_ioremap_read(0x18060208, &value_2); + DBGLOG(HAL, INFO, + "MCU PC: 0x%08x, MCU LP: 0x%08x\n", value, value_2); + } +} +int soc3_0_Trigger_fw_assert(void) +{ + int ret = 0; + int value = 0; + uint32_t waitRet = 0; +#if (CFG_SUPPORT_CONNINFRA == 1) + if (get_wifi_process_status() == 1) { + DBGLOG(HAL, ERROR, + "Wi-Fi on/off process is ongoing, ignore assert request.\n"); + fgIsResetting = FALSE; + update_driver_reset_status(fgIsResetting); + return 0; + } +#endif + soc3_0_CheckBusHang(NULL, FALSE); + if (g_IsWfsysBusHang == TRUE) { + DBGLOG(HAL, INFO, + "Already trigger conninfra whole chip reset.\n"); + return 0; + } + DBGLOG(HAL, INFO, "Trigger fw assert start.\n"); + wf_ioremap_read(WF_TRIGGER_AP2CONN_EINT, &value); + value &= 0xFFFFFF7F; + ret = wf_ioremap_write(WF_TRIGGER_AP2CONN_EINT, value); + waitRet = wait_for_completion_timeout(&g_triggerComp, + MSEC_TO_JIFFIES(WIFI_TRIGGER_ASSERT_TIMEOUT)); + if (waitRet > 0) { + /* Case 1: No timeout. */ + soc3_0_DumpWfsysInfo(); + DBGLOG(INIT, INFO, "Trigger assert successfully.\n"); + } else { + /* Case 2: timeout */ + DBGLOG(INIT, ERROR, + "Trigger assert more than 2 seconds, need to trigger rst self\n"); + soc3_0_DumpWfsysInfo(); + soc3_0_DumpWfsysdebugflag(); + g_IsTriggerTimeout = TRUE; + } +#if (CFG_SUPPORT_CONNINFRA == 1) + kalSetRstEvent(); +#endif + wf_ioremap_read(WF_TRIGGER_AP2CONN_EINT, &value); + value |= 0x80; + ret = wf_ioremap_write(WF_TRIGGER_AP2CONN_EINT, value); + + return ret; +} + +void soc3_0_CheckBusHangUT(void) +{ +#define BUS_HANG_UT_WAIT_COUNT 30 + + struct ADAPTER *prAdapter = NULL; + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t count = 0; + uint32_t u4Value = 0; + uint32_t RegValue = 0; + + prGlueInfo = (struct GLUE_INFO *)wiphy_priv(wlanGetWiphy()); + prAdapter = prGlueInfo->prAdapter; + + HAL_MCR_RD(prAdapter, 0x7c00162c, &u4Value); + RegValue = u4Value | BIT(0); + HAL_MCR_WR(prAdapter, 0x7c00162c, RegValue); + + while (count < BUS_HANG_UT_WAIT_COUNT) { + HAL_MCR_RD(prAdapter, 0x7c00162c, &u4Value); + DBGLOG(HAL, INFO, "%s: 0x7c00162c = 0x%08x\n", + __func__, u4Value); + + if ((u4Value&BIT(3)) == BIT(3)) { + DBGLOG(HAL, ERROR, "%s: 0x7c00162c = 0x%08x\n", + __func__, u4Value); + break; + } + count++; + } + + /* Trigger Hang */ + HAL_MCR_RD(prAdapter, 0x7c060000, &u4Value); +} + +static void soc3_0_DumpMemory32(uint32_t *pu4StartAddr, + uint32_t u4Count, char *info) +{ +#define ONE_LINE_MAX_COUNT 16 +#define TMP_BUF_SZ 20 + uint32_t i, endCount; + char buf[ONE_LINE_MAX_COUNT*10]; + char tmp[TMP_BUF_SZ] = {'\0'}; + + ASSERT(pu4StartAddr); + + LOG_FUNC("[Host_CSR] %s, Count(%d)\n", info, u4Count); + + while (u4Count > 0) { + + kalSnprintf(buf, TMP_BUF_SZ, "%08x", pu4StartAddr[0]); + + if (u4Count > ONE_LINE_MAX_COUNT) + endCount = ONE_LINE_MAX_COUNT; + else + endCount = u4Count; + + for (i = 1; i < endCount; i++) { + kalSnprintf(tmp, TMP_BUF_SZ, " %08x", pu4StartAddr[i]); + strncat(buf, tmp, strlen(tmp)); + } + + LOG_FUNC("%s\n", buf); + + if (u4Count > ONE_LINE_MAX_COUNT) { + u4Count -= ONE_LINE_MAX_COUNT; + pu4StartAddr += ONE_LINE_MAX_COUNT; + } else + u4Count = 0; + } +} + +static uint32_t soc3_0_DumpHwDebugFlagSub(struct ADAPTER *prAdapter, + uint32_t RegValue) +{ + uint32_t u4Cr; + uint32_t u4Value = 0; + + u4Cr = 0x1806009C; + soc3_0_CrWrite(prAdapter, u4Cr, RegValue); + + u4Cr = 0x1806021C; + soc3_0_CrRead(prAdapter, u4Cr, &u4Value); + + return u4Value; +} + +static void soc3_0_DumpHwDebugFlag(struct ADAPTER *prAdapter) +{ +#define HANG_HW_FLAG_NUM 7 + + uint32_t u4Cr; + uint32_t RegValue = 0; + uint32_t log[HANG_HW_FLAG_NUM]; + + DBGLOG(HAL, LOUD, + "Host_CSR - dump all HW Debug flag"); + + u4Cr = 0x18060094; + RegValue = 0x00139CE7; + soc3_0_CrWrite(prAdapter, u4Cr, RegValue); + + log[0] = soc3_0_DumpHwDebugFlagSub(prAdapter, 0x366CD932); + log[1] = soc3_0_DumpHwDebugFlagSub(prAdapter, 0x36AD5A34); + log[2] = soc3_0_DumpHwDebugFlagSub(prAdapter, 0x36EDDB36); + log[3] = soc3_0_DumpHwDebugFlagSub(prAdapter, 0x3972E54A); + log[4] = soc3_0_DumpHwDebugFlagSub(prAdapter, 0x39B3664C); + log[5] = soc3_0_DumpHwDebugFlagSub(prAdapter, 0x7C387060); + log[6] = soc3_0_DumpHwDebugFlagSub(prAdapter, 0x7C78F162); + + soc3_0_DumpMemory32(log, HANG_HW_FLAG_NUM, "HW Debug flag"); +} + +static void soc3_0_DumpPcLrLog(struct ADAPTER *prAdapter) +{ +#define HANG_PC_LOG_NUM 32 + uint32_t u4Cr, u4Index, i; + uint32_t u4Value = 0; + uint32_t RegValue = 0; + uint32_t log[HANG_PC_LOG_NUM]; + + DBGLOG(HAL, LOUD, + "Host_CSR - dump PC log / LR log"); + + memset(log, 0, HANG_PC_LOG_NUM); + + /* PC log + * dbg_pc_log_sel Write 0x1806_0090 [7:2] 6'h20 + * choose 33th pc log buffer to read current pc log buffer index + * read pc from host CR Read 0x1806_0204 [21:17] + * read current pc log buffer index + * dbg_pc_log_sel Write 0x1806_0090 [7:2] index + * set pc log buffer index to read pc log + * read pc from host CR Read 0x1806_0204 [31:0] + * read pc log of the specific index + */ + + u4Cr = 0x18060090; + soc3_0_CrRead(prAdapter, u4Cr, &u4Value); + RegValue = (0x20<<2) | (u4Value&BITS(0, 1)) | (u4Value&BITS(8, 31)); + soc3_0_CrWrite(prAdapter, u4Cr, RegValue); + + u4Cr = 0x18060204; + soc3_0_CrRead(prAdapter, u4Cr, &u4Value); + u4Index = (u4Value&BITS(17, 21)) >> 17; + + for (i = 0; i < HANG_PC_LOG_NUM; i++) { + + u4Index++; + + if (u4Index == HANG_PC_LOG_NUM) + u4Index = 0; + + u4Cr = 0x18060090; + soc3_0_CrRead(prAdapter, u4Cr, &u4Value); + RegValue = (u4Index<<2) | (u4Value&BITS(0, 1)) | + (u4Value&BITS(8, 31)); + soc3_0_CrWrite(prAdapter, u4Cr, RegValue); + + u4Cr = 0x18060204; + soc3_0_CrRead(prAdapter, u4Cr, &log[i]); + } + + /* restore */ + u4Cr = 0x18060090; + soc3_0_CrRead(prAdapter, u4Cr, &u4Value); + RegValue = (0x3F<<2) | (u4Value&BITS(0, 1)) | (u4Value&BITS(8, 31)); + soc3_0_CrWrite(prAdapter, u4Cr, RegValue); + + soc3_0_DumpMemory32(log, HANG_PC_LOG_NUM, "PC log"); + + /* GPR log */ + + u4Cr = 0x18060090; + soc3_0_CrRead(prAdapter, u4Cr, &u4Value); + RegValue = (0x20<<8) | (u4Value&BITS(0, 7)) | (u4Value&BITS(14, 31)); + soc3_0_CrWrite(prAdapter, u4Cr, RegValue); + + u4Cr = 0x18060208; + soc3_0_CrRead(prAdapter, u4Cr, &u4Value); + u4Index = (u4Value&BITS(17, 21)) >> 17; + + for (i = 0; i < HANG_PC_LOG_NUM; i++) { + + u4Index++; + + if (u4Index == HANG_PC_LOG_NUM) + u4Index = 0; + + u4Cr = 0x18060090; + soc3_0_CrRead(prAdapter, u4Cr, &u4Value); + RegValue = (u4Index<<8) | (u4Value&BITS(0, 7)) | + (u4Value&BITS(14, 31)); + soc3_0_CrWrite(prAdapter, u4Cr, RegValue); + + u4Cr = 0x18060208; + soc3_0_CrRead(prAdapter, u4Cr, &log[i]); + } + + /* restore */ + u4Cr = 0x18060090; + soc3_0_CrRead(prAdapter, u4Cr, &u4Value); + RegValue = (0x3F<<8) | (u4Value&BITS(0, 7)) | (u4Value&BITS(14, 31)); + soc3_0_CrWrite(prAdapter, u4Cr, RegValue); + + soc3_0_DumpMemory32(log, HANG_PC_LOG_NUM, "GPR log"); +} + +static void soc3_0_DumpN10CoreReg(struct ADAPTER *prAdapter) +{ +#define HANG_N10_CORE_LOG_NUM 38 + uint32_t u4Cr, i; + uint32_t u4Value = 0; + uint32_t RegValue = 0; + uint32_t log[HANG_N10_CORE_LOG_NUM]; + + DBGLOG(HAL, LOUD, + "Host_CSR - read N10 core register"); + + memset(log, 0, HANG_N10_CORE_LOG_NUM); + +/* +* [31:26]: gpr_index_sel (set different sets of gpr) = 0 +* [13:8]: gpr buffer index setting +* (set as 0x3F to select the current selected GPR) +*/ + u4Cr = 0x18060090; + soc3_0_CrRead(prAdapter, u4Cr, &u4Value); + + u4Value = (0x3F<<8) | (u4Value&BITS(0, 7)) | (u4Value&BITS(14, 31)); + + for (i = 0; i < HANG_N10_CORE_LOG_NUM; i++) { + + RegValue = (i<<26) | (u4Value&BITS(0, 25)); + + u4Cr = 0x18060090; + soc3_0_CrWrite(prAdapter, u4Cr, RegValue); + + u4Cr = 0x18060208; + soc3_0_CrRead(prAdapter, u4Cr, &log[i]); + } + + /* restore */ + u4Cr = 0x18060090; + RegValue = (30<<26) | (u4Value&BITS(0, 25)); + soc3_0_CrWrite(prAdapter, u4Cr, RegValue); + + soc3_0_DumpMemory32(log, HANG_N10_CORE_LOG_NUM, "N10 core register"); +} + +static void soc3_0_DumpOtherCr(struct ADAPTER *prAdapter) +{ +#define HANG_MAIL_BOX_LOG_NUM 2 +#define HANG_DUMMY_CR_LOG_NUM 4 +#define HANG_OTHER_LOG_TOTAL (HANG_MAIL_BOX_LOG_NUM+HANG_DUMMY_CR_LOG_NUM) + + uint32_t u4Cr, i; + uint32_t log[HANG_OTHER_LOG_TOTAL]; + + DBGLOG(HAL, LOUD, + "Host_CSR - mailbox and other CRs"); + + memset(log, 0, HANG_OTHER_LOG_TOTAL); + + u4Cr = 0x18060260; + for (i = 0; i < HANG_MAIL_BOX_LOG_NUM; i++) { + soc3_0_CrRead(prAdapter, u4Cr, &log[i]); + u4Cr += 0x04; + } + + u4Cr = 0x180602f0; + for (i = HANG_MAIL_BOX_LOG_NUM; i < HANG_OTHER_LOG_TOTAL; i++) { + soc3_0_CrRead(prAdapter, u4Cr, &log[i]); + u4Cr += 0x04; + } + + soc3_0_DumpMemory32(log, HANG_OTHER_LOG_TOTAL, "mailbox and other CRs"); +} + +static void soc3_0_DumpSpecifiedWfTop(struct ADAPTER *prAdapter) +{ +#define HANG_TOP_LOG_NUM 2 + + uint32_t u4Cr; + uint32_t u4Value = 0; + uint32_t RegValue = 0; + uint32_t log[HANG_TOP_LOG_NUM]; + + DBGLOG(HAL, LOUD, + "Host_CSR - specified WF TOP monflg on"); + + memset(log, 0, HANG_TOP_LOG_NUM); + +/* 0x1806009C[28]=1 write enable wf_mcu_misc */ + + u4Cr = 0x1806009C; + soc3_0_CrRead(prAdapter, u4Cr, &u4Value); + RegValue = u4Value | BIT(28); + soc3_0_CrWrite(prAdapter, u4Cr, RegValue); + +/* 0x1806009C[27:0]=0xC387060 write select {FLAG_4[9:2],FLAG_27[9:2]} */ + + u4Cr = 0x1806009C; + soc3_0_CrRead(prAdapter, u4Cr, &u4Value); + RegValue = 0xC387060 | (u4Value&BITS(28, 31)); + soc3_0_CrWrite(prAdapter, u4Cr, RegValue); + +/* 0x18060094[20]=1 write enable wf_monflg_on */ + + u4Cr = 0x18060094; + soc3_0_CrRead(prAdapter, u4Cr, &u4Value); + RegValue = u4Value | BIT(20); + soc3_0_CrWrite(prAdapter, u4Cr, RegValue); + +/* 0x18060094[19:0]=0x39CE7 write select wf_mcusys_dbg */ + + u4Cr = 0x18060094; + soc3_0_CrRead(prAdapter, u4Cr, &u4Value); + RegValue = 0x39CE7 | (u4Value&BITS(20, 31)); + soc3_0_CrWrite(prAdapter, u4Cr, RegValue); + +/* 0x1806_021c[31:0] Read get {FLAG_4[9:2],FLAG_27[9:2]} */ + + u4Cr = 0x1806021c; + soc3_0_CrRead(prAdapter, u4Cr, &log[0]); + +/* 0x1806009C[27:0]=0xC78F162 write select {FlAG_23[7:0],FlAG_6[9:2]} */ + + u4Cr = 0x1806009C; + soc3_0_CrRead(prAdapter, u4Cr, &u4Value); + RegValue = 0xC78F162 | (u4Value&BITS(28, 31)); + soc3_0_CrWrite(prAdapter, u4Cr, RegValue); + + +/* 0x1806_021c[31:0] Read get {FlAG_23[7:0],FlAG_6[9:2]} */ + + u4Cr = 0x1806021c; + soc3_0_CrRead(prAdapter, u4Cr, &log[1]); + + soc3_0_DumpMemory32(log, HANG_TOP_LOG_NUM, + "specified WF TOP monflg on"); +} + + +/* check wsys bus hang or not */ +/* return = TRUE (bus is hang), FALSE (bus is not hang) */ +/* write 0x18060128 = 0x000B0001 */ +/* read and check 0x18060148 bit[9:8] */ +/* if [9:8]=2'b00 (wsys not hang), others is hang */ + +static int IsWsysBusHang(struct ADAPTER *prAdapter) +{ + uint32_t u4Value = 0; + uint32_t u4WriteDebugValue; + + u4WriteDebugValue = 0x000B0001; + soc3_0_CrWrite(prAdapter, 0x18060128, u4WriteDebugValue); + soc3_0_CrRead(prAdapter, 0x18060148, &u4Value); + + u4Value &= BITS(8, 9); + return u4Value; +} /* soc3_0_IsWsysBusHang */ + +#if 0 +/* PP CR: 0x820CCXXX remap to Base + 0x40e000 */ +static void DumpPPDebugCr(struct ADAPTER *prAdapter) +{ + uint32_t ReadRegValue[4]; + uint32_t u4Value[4]; + + /* 0x820CC0F0 : PP DBG_CTRL */ + ReadRegValue[0] = 0x820CC0F0; + HAL_MCR_RD(prAdapter, ReadRegValue[0], &u4Value[0]); + + /* 0x820CC0F8 : PP DBG_CS0 */ + ReadRegValue[1] = 0x820CC0F8; + HAL_MCR_RD(prAdapter, ReadRegValue[1], &u4Value[1]); + + /* 0x820CC0FC : PP DBG_CS1 */ + ReadRegValue[2] = 0x820CC0FC; + HAL_MCR_RD(prAdapter, ReadRegValue[2], &u4Value[2]); + + /* 0x820CC100 : PP DBG_CS2 */ + ReadRegValue[3] = 0x820CC100; + HAL_MCR_RD(prAdapter, ReadRegValue[3], &u4Value[3]); + + DBGLOG(HAL, INFO, + "PP[0x%08x]=0x%08x,[0x%08x]=0x%08x,[0x%08x]=0x%08x,[0x%08x]=0x%08x,", + ReadRegValue[0], u4Value[0], + ReadRegValue[1], u4Value[1], + ReadRegValue[2], u4Value[2], + ReadRegValue[3], u4Value[3]); +} + +/* PP CR: 0x820CCXXX remap to Base + 0x40e000 */ +static void DumpPPDebugCr_without_adapter(void) +{ + uint32_t ReadRegValue[4]; + uint32_t u4Value[4]; + + /* 0x820CC0F0 : PP DBG_CTRL */ + ReadRegValue[0] = 0x1840E0F0; + wf_ioremap_read(ReadRegValue[0], &u4Value[0]); + + /* 0x820CC0F8 : PP DBG_CS0 */ + ReadRegValue[1] = 0x1840E0F8; + wf_ioremap_read(ReadRegValue[1], &u4Value[1]); + + /* 0x820CC0FC : PP DBG_CS1 */ + ReadRegValue[2] = 0x1840E0FC; + wf_ioremap_read(ReadRegValue[2], &u4Value[2]); + + /* 0x820CC100 : PP DBG_CS2 */ + ReadRegValue[3] = 0x1840E100; + wf_ioremap_read(ReadRegValue[3], &u4Value[3]); + + DBGLOG(HAL, INFO, + "PP[0x%08x]=0x%08x,[0x%08x]=0x%08x,[0x%08x]=0x%08x,[0x%08x]=0x%08x,", + ReadRegValue[0], u4Value[0], + ReadRegValue[1], u4Value[1], + ReadRegValue[2], u4Value[2], + ReadRegValue[3], u4Value[3]); +} +#endif + +/* need to dump AXI Master related CR 0x1802750C ~ 0x18027530*/ +static void DumpAXIMasterDebugCr(struct ADAPTER *prAdapter) +{ +#define AXI_MASTER_DUMP_CR_START 0x1802750C +#define AXI_MASTER_DUMP_CR_NUM 9 + + uint32_t ReadRegValue = 0; + uint32_t u4Value[AXI_MASTER_DUMP_CR_NUM] = {0}; + uint32_t i; + + ReadRegValue = AXI_MASTER_DUMP_CR_START; + for (i = 0 ; i < AXI_MASTER_DUMP_CR_NUM; i++) { + ReadRegValue += 4; + soc3_0_CrRead(prAdapter, ReadRegValue, &u4Value[i]); + } + + soc3_0_DumpMemory32(u4Value, + AXI_MASTER_DUMP_CR_NUM, + "HW AXI BUS debug CR start[0x1802750C]"); + +} /* soc3_0_DumpAXIMasterDebugCr */ + +/* Dump Flow : */ +/* 1) dump WFDMA / AXI Master CR */ +/* 2) check wsys bus is hang */ +/* - if not hang dump WM WFDMA & PP CR */ +void soc3_0_DumpWFDMACr(struct ADAPTER *prAdapter) +{ + /* Dump Host side WFDMACR */ + bool bShowWFDMA_type = FALSE; + int32_t ret = 0; + + if (prAdapter == NULL) + soc3_0_show_wfdma_info_by_type_without_adapter(bShowWFDMA_type); + else + soc3_0_show_wfdma_info_by_type(prAdapter, bShowWFDMA_type); + + DumpAXIMasterDebugCr(prAdapter); + + ret = IsWsysBusHang(prAdapter); + /* ret =0 is readable, wsys not bus hang */ + #if 0 /* TODO */ + if (ret == 0) { + bShowWFDMA_type = TRUE; + if (prAdapter == NULL) { + soc3_0_show_wfdma_info_by_type_without_adapter( + bShowWFDMA_type); + + DumpPPDebugCr_without_adapter(); + } else { + soc3_0_show_wfdma_info_by_type(prAdapter, + bShowWFDMA_type); + + DumpPPDebugCr(prAdapter); + } + } else { + DBGLOG(HAL, INFO, + "Wifi bus hang(0x%08x), can't dump wsys CR\n", ret); + } + #endif + +} /* soc3_0_DumpWFDMAHostCr */ + +static void soc3_0_DumpHostCr(struct ADAPTER *prAdapter) +{ + soc3_0_DumpWfsyscpupcr(prAdapter); /* first dump */ + soc3_0_DumpPcLrLog(prAdapter); + soc3_0_DumpN10CoreReg(prAdapter); + soc3_0_DumpOtherCr(prAdapter); + soc3_0_DumpHwDebugFlag(prAdapter); + soc3_0_DumpSpecifiedWfTop(prAdapter); + soc3_0_DumpWFDMACr(prAdapter); +} /* soc3_0_DumpHostCr */ + +void soc3_0_DumpBusHangCr(struct ADAPTER *prAdapter) +{ + conninfra_is_bus_hang(); + soc3_0_DumpHostCr(prAdapter); +} + +int soc3_0_CheckBusHang(void *adapter, uint8_t ucWfResetEnable) +{ + int ret = 1; + int conninfra_read_ret = 0; + int conninfra_hang_ret = 0; + uint8_t conninfra_reset = FALSE; + uint32_t u4Cr = 0; + uint32_t u4Value = 0; + uint32_t RegValue = 0; + struct ADAPTER *prAdapter = (struct ADAPTER *) adapter; + + if (prAdapter == NULL) + DBGLOG(HAL, INFO, "prAdapter NULL\n"); + + do { +/* +* 1. Check "AP2CONN_INFRA ON step is ok" +* & Check "AP2CONN_INFRA OFF step is ok" +*/ + conninfra_read_ret = conninfra_reg_readable(); + + if (!conninfra_read_ret) { + DBGLOG(HAL, ERROR, + "conninfra_reg_readable fail(%d)\n", + conninfra_read_ret); + + conninfra_hang_ret = conninfra_is_bus_hang(); + + if (conninfra_hang_ret > 0) { + conninfra_reset = TRUE; + + DBGLOG(HAL, ERROR, + "conninfra_is_bus_hang, Chip reset\n"); + } else { + /* + * not readable, but no_hang or rst_ongoing + * => no reset and return fail + */ + ucWfResetEnable = FALSE; + } + + break; + } + + if ((prAdapter != NULL) && (prAdapter->fgIsFwDownloaded)) { +/* +* 2. Check MCU wake up and setting mux sel done CR (mailbox) +* - 0x1806_0260[31] should be 1'b1 (FW view 0x8900_0100[31]) +*/ + + u4Cr = 0x18060260; + soc3_0_CrRead(prAdapter, u4Cr, &u4Value); + + if ((u4Value&BIT(31)) != BIT(31)) { + DBGLOG(HAL, ERROR, + "Bus hang check: 0x%08x = 0x%08x\n", + u4Cr, u4Value); + break; + } + +/* +* 3. Check wf_mcusys bus hang irq status (need set debug ctrl enable first, +* ref sheet "Debug ctrl setting") +* - if(bus hang), then +* a) WF MCU: wf_mcusys_vdnr_timeout_irq_b, FW: Trigger subssy reset / +* Whole Chip Reset(conn2ap hang) +* b) Driver dump CRs of sheet "Debug ctrl setting" +* +* Write Address : 0x1806_009c[6:0] , Data : 0x60 default 0x00 +* Write Address : 0x1806_009c[28] , Data : 0x1 default 0x0 +* (wf_mcu_dbg enable) +* Write Address : 0x1806_0094[4:0] , Data : 0x7 default 0x0 +* (switch monflg mux) +* Write Address : 0x1806_0094[20] , Data : 0x1 default 0x1 +* (enable wf monflg debug) +* Read Address : 0x1806_021c[0] shoulde be 1'b0 +*/ + + u4Cr = 0x1806009c; + soc3_0_CrRead(prAdapter, u4Cr, &u4Value); + RegValue = (u4Value&BITS(7, 31)) | 0x60; + RegValue = RegValue | BIT(28); + soc3_0_CrWrite(prAdapter, u4Cr, RegValue); + + u4Cr = 0x18060094; + soc3_0_CrRead(prAdapter, u4Cr, &u4Value); + RegValue = (u4Value&BITS(5, 31)) | 0x7; + RegValue = RegValue | BIT(20); + soc3_0_CrWrite(prAdapter, u4Cr, RegValue); + + u4Cr = 0x1806021c; + soc3_0_CrRead(prAdapter, u4Cr, &u4Value); + + if ((u4Value&BIT(0)) == BIT(0)) { + DBGLOG(HAL, ERROR, + "Bus hang check: 0x%08x = 0x%08x\n", + u4Cr, u4Value); + + u4Cr = 0x1806009c; + soc3_0_CrRead(prAdapter, u4Cr, &u4Value); + DBGLOG(HAL, ERROR, + "Bus hang check: 0x%08x = 0x%08x\n", + u4Cr, u4Value); + + u4Cr = 0x18060094; + soc3_0_CrRead(prAdapter, u4Cr, &u4Value); + DBGLOG(HAL, ERROR, + "Bus hang check: 0x%08x = 0x%08x\n", + u4Cr, u4Value); + break; + } + } else { + DBGLOG(HAL, INFO, + "Before fgIsFwDownloaded\n"); + } + +/* +* 4. Check conn2wf sleep protect +* - 0x1800_1620[3] (sleep protect enable ready), should be 1'b0 +*/ + u4Cr = 0x18001620; + soc3_0_CrRead(prAdapter, u4Cr, &u4Value); + + if ((u4Value&BIT(3)) == BIT(3)) { + DBGLOG(HAL, ERROR, + "Bus hang check: 0x%08x = 0x%08x\n", + u4Cr, u4Value); + + u4Cr = 0x18060010; + soc3_0_CrRead(prAdapter, u4Cr, &u4Value); + + DBGLOG(HAL, ERROR, + "Bus hang check: 0x%08x = 0x%08x\n", + u4Cr, u4Value); + + u4Cr = 0x180600f0; + soc3_0_CrRead(prAdapter, u4Cr, &u4Value); + + DBGLOG(HAL, ERROR, + "Bus hang check: 0x%08x = 0x%08x\n", + u4Cr, u4Value); + break; + } + +/* +* 5. check wfsys bus clock +* - 0x1806_0000[15] , 1: means bus no clock, 0: ok +*/ + u4Cr = 0x18060000; + soc3_0_CrRead(prAdapter, u4Cr, &u4Value); + + if ((u4Value&BIT(15)) == BIT(15)) { + DBGLOG(HAL, ERROR, + "Bus hang check: 0x%08x = 0x%08x\n", + u4Cr, u4Value); + break; + } + + DBGLOG(HAL, INFO, + "Bus hang check: Done\n"); + + ret = 0; + } while (FALSE); + + if (ret > 0) { + + /* check again for dump log */ + conninfra_is_bus_hang(); + + if ((conninfra_hang_ret != CONNINFRA_ERR_RST_ONGOING) && + (conninfra_hang_ret != CONNINFRA_INFRA_BUS_HANG) && + (conninfra_hang_ret != + CONNINFRA_AP2CONN_RX_SLP_PROT_ERR) && + (conninfra_hang_ret != + CONNINFRA_AP2CONN_TX_SLP_PROT_ERR) && + (conninfra_hang_ret != CONNINFRA_AP2CONN_CLK_ERR)) + soc3_0_DumpHostCr(prAdapter); + + if (conninfra_reset) { + g_IsWfsysBusHang = TRUE; + conninfra_trigger_whole_chip_rst(CONNDRV_TYPE_WIFI, + "bus hang"); + } else if (ucWfResetEnable) { + g_IsWfsysBusHang = TRUE; + conninfra_trigger_whole_chip_rst(CONNDRV_TYPE_WIFI, + "wifi bus hang"); + } + } + + return ret; +} + +void soc3_0_DumpBusHangdebuglog(void) +{ + uint32_t u4Value = 0; + uint32_t RegValue; + + RegValue = 0x00020002; + wf_ioremap_write(0x18060128, RegValue); + wf_ioremap_read(0x18060148, &u4Value); + DBGLOG(HAL, INFO, + "dump: 0x18060148 = 0x%08x after 0x%08x\n", + u4Value, RegValue); + wf_ioremap_read(0x18001a00, &u4Value); + DBGLOG(HAL, INFO, + "dump: 0x18001a00 = 0x%08x\n", u4Value); + wf_ioremap_read(0x1800c00c, &u4Value); + DBGLOG(HAL, INFO, + "dump: 0x1800c00c = 0x%08x\n", u4Value); + +} +void soc3_0_DumpPwrStatedebuglog(void) +{ + uint32_t u4Value = 0; + + wf_ioremap_read(0x18070400, &u4Value); + DBGLOG(HAL, INFO, + "dump: 0x18070400 = 0x%08x\n", u4Value); + wf_ioremap_read(0x18071400, &u4Value); + DBGLOG(HAL, INFO, + "dump: 0x18071400 = 0x%08x\n", u4Value); + wf_ioremap_read(0x18072400, &u4Value); + DBGLOG(HAL, INFO, + "dump: 0x18072400 = 0x%08x\n", u4Value); + wf_ioremap_read(0x18073400, &u4Value); + DBGLOG(HAL, INFO, + "dump: 0x18073400 = 0x%08x\n", u4Value); + wf_ioremap_read(0x180602cc, &u4Value); + DBGLOG(HAL, INFO, + "dump: 0x180602cc = 0x%08x\n", u4Value); + wf_ioremap_read(0x18000110, &u4Value); + DBGLOG(HAL, INFO, + "dump: 0x18000110 = 0x%08x\n", u4Value); + wf_ioremap_read(0x184c0880, &u4Value); + DBGLOG(HAL, INFO, + "dump: 0x184c0880 = 0x%08x\n", u4Value); + wf_ioremap_read(0x184c08d0, &u4Value); + DBGLOG(HAL, INFO, + "dump: 0x184c08d0 = 0x%08x\n", u4Value); +} + +int wf_pwr_on_consys_mcu(void) +{ + int check; + int value = 0; + int ret = 0; + int conninfra_hang_ret = 0; + unsigned int polling_count; + + DBGLOG(INIT, INFO, "wmmcu power-on start.\n"); + /* Wakeup conn_infra off write 0x180601A4[0] = 1'b1 */ + wf_ioremap_read(CONN_INFRA_WAKEUP_WF_ADDR, &value); + value |= 0x00000001; + wf_ioremap_write(CONN_INFRA_WAKEUP_WF_ADDR, value); + + /* Check AP2CONN slpprot ready + * (polling "10 times" and each polling interval is "1ms") + * Address: 0x1806_0184[5] + * Data: 1'b0 + * Action: polling + */ + wf_ioremap_read(CONN_INFRA_ON2OFF_SLP_PROT_ACK_ADDR, &value); + check = 0; + polling_count = 0; + while ((value & 0x00000020) != 0) { + if (polling_count > 10) { + check = -1; + ret = -1; + break; + } + udelay(1000); + wf_ioremap_read(CONN_INFRA_ON2OFF_SLP_PROT_ACK_ADDR, &value); + polling_count++; + } + if (check != 0) { + DBGLOG(INIT, ERROR, "Polling AP2CONN slpprot ready fail.\n"); + return ret; + } + + /* Check CONNSYS version ID + * (polling "10 times" and each polling interval is "1ms") + * Address: 0x1800_1000[31:0] + * Data: 0x2001_0000 + * Action: polling + */ + wf_ioremap_read(CONN_HW_VER_ADDR, &value); + check = 0; + polling_count = 0; + while (value != kalGetConnsysVerId()) { + if (polling_count > 10) { + check = -1; + ret = -1; + break; + } + udelay(1000); + wf_ioremap_read(CONN_HW_VER_ADDR, &value); + polling_count++; + } + if (check != 0) { + DBGLOG(INIT, ERROR, "Polling CONNSYS version ID fail.\n"); + return ret; + } + soc3_0_DumpBusHangdebuglog(); + + /* Assert CONNSYS WM CPU SW reset write 0x18000010[0] = 1'b0*/ + wf_ioremap_read(WFSYS_CPU_SW_RST_B_ADDR, &value); + value &= 0xFFFFFFFE; + wf_ioremap_write(WFSYS_CPU_SW_RST_B_ADDR, value); + + /* bus clock ctrl */ + conninfra_bus_clock_ctrl(CONNDRV_TYPE_WIFI, CONNINFRA_BUS_CLOCK_ALL, 1); + /* Turn on wfsys_top_on + * 0x18000000[31:16] = 0x57460000, + * 0x18000000[7] = 1'b1 + */ + wf_ioremap_read(WFSYS_ON_TOP_PWR_CTL_ADDR, &value); + value &= 0x0000FF7F; + value |= 0x57460080; + wf_ioremap_write(WFSYS_ON_TOP_PWR_CTL_ADDR, value); + /* Polling wfsys_rgu_off_hreset_rst_b + * (polling "10 times" and each polling interval is "0.5ms") + * Address: 0x1806_02CC[2] (TOP_DBG_DUMMY_3_CONNSYS_PWR_STATUS[2]) + * Data: 1'b1 + * Action: polling + */ + + wf_ioremap_read(TOP_DBG_DUMMY_3_CONNSYS_PWR_STATUS_ADDR, &value); + check = 0; + polling_count = 0; + while ((value & 0x00000004) == 0) { + if (polling_count > 10) { + check = -1; + ret = -1; + break; + } + udelay(500); + wf_ioremap_read(TOP_DBG_DUMMY_3_CONNSYS_PWR_STATUS_ADDR, + &value); + polling_count++; + } + if (check != 0) { + DBGLOG(INIT, ERROR, + "Polling wfsys rgu off fail. (0x%x)\n", + value); + return ret; + } + + if (!conninfra_reg_readable()) { + DBGLOG(HAL, ERROR, + "conninfra_reg_readable fail\n"); + + conninfra_hang_ret = conninfra_is_bus_hang(); + + if (conninfra_hang_ret > 0) { + + DBGLOG(HAL, ERROR, + "conninfra_is_bus_hang, Chip reset\n"); + } + return -1; + } + /* Turn off "conn_infra to wfsys"/ wfsys to conn_infra" bus + * sleep protect 0x18001620[0] = 1'b0 + */ + wf_ioremap_read(CONN_INFRA_WF_SLP_CTRL_R_ADDR, &value); + value &= 0xFFFFFFFE; + wf_ioremap_write(CONN_INFRA_WF_SLP_CTRL_R_ADDR, value); + /* Polling WF_SLP_CTRL ready + * (polling "100 times" and each polling interval is "0.5ms") + * Address: 0x1800_1620[3] (CONN_INFRA_WF_SLP_CTRL_R_OFFSET[3]) + * Data: 1'b0 + * Action: polling + */ + wf_ioremap_read(CONN_INFRA_WF_SLP_CTRL_R_ADDR, &value); + check = 0; + polling_count = 0; + while ((value & 0x00000008) != 0) { + if (polling_count > 100) { + check = -1; + ret = -1; + break; + } + udelay(500); + wf_ioremap_read(CONN_INFRA_WF_SLP_CTRL_R_ADDR, &value); + polling_count++; + DBGLOG(INIT, ERROR, "WF_SLP_CTRL (0x%x) (%d)\n", + value, + polling_count); + } + if (check != 0) { + DBGLOG(INIT, ERROR, + "Polling WFSYS TO CONNINFRA SLEEP PROTECT fail. (0x%x)\n", + value); + return ret; + } + /* Turn off "wf_dma to conn_infra" bus sleep protect + * 0x18001624[0] = 1'b0 + */ + wf_ioremap_read(CONN_INFRA_WFDMA_SLP_CTRL_R_ADDR, &value); + value &= 0xFFFFFFFE; + wf_ioremap_write(CONN_INFRA_WFDMA_SLP_CTRL_R_ADDR, value); + /* Polling wfsys_rgu_off_hreset_rst_b + * (polling "100 times" and each polling interval is "0.5ms") + * Address: 0x1800_1624[3] (CONN_INFRA_WFDMA_SLP_CTRL_R_OFFSET[3]) + * Data: 1'b0 + * Action: polling + */ + wf_ioremap_read(CONN_INFRA_WFDMA_SLP_CTRL_R_ADDR, &value); + check = 0; + polling_count = 0; + while ((value & 0x00000008) != 0) { + if (polling_count > 100) { + check = -1; + ret = -1; + break; + } + udelay(500); + wf_ioremap_read(CONN_INFRA_WFDMA_SLP_CTRL_R_ADDR, &value); + polling_count++; + DBGLOG(INIT, ERROR, "WFDMA_SLP_CTRL (0x%x) (%d)\n", + value, + polling_count); + } + if (check != 0) { + DBGLOG(INIT, ERROR, + "Polling WFDMA TO CONNINFRA SLEEP PROTECT RDY fail. (0x%x)\n", + value); + return ret; + } + + /*WF_VDNR_EN_ADDR 0x1800_E06C[0] =1'b1*/ + wf_ioremap_read(WF_VDNR_EN_ADDR, &value); + value |= 0x00000001; + wf_ioremap_write(WF_VDNR_EN_ADDR, value); + + /* Check WFSYS version ID (Polling) */ + wf_ioremap_read(WFSYS_VERSION_ID_ADDR, &value); + check = 0; + polling_count = 0; + while (value != WFSYS_VERSION_ID) { + if (polling_count > 10) { + check = -1; + ret = -1; + break; + } + udelay(500); + wf_ioremap_read(WFSYS_VERSION_ID_ADDR, &value); + polling_count++; + } + if (check != 0) { + DBGLOG(INIT, ERROR, "Polling CONNSYS version ID fail.\n"); + return ret; + } + + /* Setup CONNSYS firmware in EMI */ +#if (CFG_POWER_ON_DOWNLOAD_EMI_ROM_PATCH == 1) + soc3_0_wlanPowerOnInit(ENUM_WLAN_POWER_ON_DOWNLOAD_EMI); +#endif + + /* Default value update 2: EMI entry address */ + wf_ioremap_write(CONN_CFG_AP2WF_REMAP_1_ADDR, CONN_MCU_CONFG_HS_BASE); + wf_ioremap_write(WF_DYNAMIC_BASE+MCU_EMI_ENTRY_OFFSET, 0x00000000); + wf_ioremap_write(WF_DYNAMIC_BASE+WF_EMI_ENTRY_OFFSET, 0x00000000); + + /* Reset WFSYS semaphore 0x18000018[0] = 1'b0 */ + wf_ioremap_read(WFSYS_SW_RST_B_ADDR, &value); + value &= 0xFFFFFFFE; + wf_ioremap_write(WFSYS_SW_RST_B_ADDR, value); + + /* De-assert WFSYS CPU SW reset 0x18000010[0] = 1'b1 */ + wf_ioremap_read(WFSYS_CPU_SW_RST_B_ADDR, &value); + value |= 0x00000001; + wf_ioremap_write(WFSYS_CPU_SW_RST_B_ADDR, value); + + /* Check CONNSYS power-on completion + * Polling "100 times" and each polling interval is "0.5ms" + * Polling 0x81021604[31:0] = 0x00001D1E + */ + wf_ioremap_read(WF_ROM_CODE_INDEX_ADDR, &value); + check = 0; + polling_count = 0; + while (value != CONNSYS_ROM_DONE_CHECK) { + if (polling_count > 100) { + check = -1; + ret = -1; + break; + } + udelay(1000); + wf_ioremap_read(WF_ROM_CODE_INDEX_ADDR, &value); + polling_count++; + } + if (check != 0) { + soc3_0_DumpWfsysInfo(); + soc3_0_DumpPwrStatedebuglog(); + soc3_0_DumpWfsysdebugflag(); + DBGLOG(INIT, ERROR, + "Check CONNSYS power-on completion fail.\n"); + return ret; + } + + conninfra_config_setup(); + + /* bus clock ctrl */ + conninfra_bus_clock_ctrl(CONNDRV_TYPE_WIFI, CONNINFRA_BUS_CLOCK_ALL, 0); + + /* Disable conn_infra off domain force on 0x180601A4[0] = 1'b0 */ + wf_ioremap_read(CONN_INFRA_WAKEUP_WF_ADDR, &value); + value &= 0xFFFFFFFE; + wf_ioremap_write(CONN_INFRA_WAKEUP_WF_ADDR, value); + DBGLOG(INIT, INFO, "wmmcu power-on done.\n"); + return ret; +} + +int wf_pwr_off_consys_mcu(void) +{ + int check; + int value = 0; + int ret = 0; + int conninfra_hang_ret = 0; + int polling_count; + + DBGLOG(INIT, INFO, "wmmcu power-off start.\n"); + /* Wakeup conn_infra off write 0x180601A4[0] = 1'b1 */ + wf_ioremap_read(CONN_INFRA_WAKEUP_WF_ADDR, &value); + value |= 0x00000001; + wf_ioremap_write(CONN_INFRA_WAKEUP_WF_ADDR, value); + + /* Check AP2CONN slpprot ready + * (polling "10 times" and each polling interval is "1ms") + * Address: 0x1806_0184[5] + * Data: 1'b0 + * Action: polling + */ + wf_ioremap_read(CONN_INFRA_ON2OFF_SLP_PROT_ACK_ADDR, &value); + check = 0; + polling_count = 0; + while ((value & 0x00000020) != 0) { + if (polling_count > 10) { + check = -1; + ret = -1; + break; + } + udelay(1000); + wf_ioremap_read(CONN_INFRA_ON2OFF_SLP_PROT_ACK_ADDR, &value); + polling_count++; + } + if (check != 0) { + DBGLOG(INIT, ERROR, "Polling AP2CONN slpprot ready fail.\n"); + return ret; + } + + if (!conninfra_reg_readable()) { + DBGLOG(HAL, ERROR, + "conninfra_reg_readable fail\n"); + + conninfra_hang_ret = conninfra_is_bus_hang(); + + if (conninfra_hang_ret > 0) { + + DBGLOG(HAL, ERROR, + "conninfra_is_bus_hang, Chip reset\n"); + } + return -1; + } + + /* Check CONNSYS version ID + * (polling "10 times" and each polling interval is "1ms") + * Address: 0x1800_1000[31:0] + * Data: 0x2001_0000 + * Action: polling + */ + wf_ioremap_read(CONN_HW_VER_ADDR, &value); + check = 0; + polling_count = 0; + while (value != kalGetConnsysVerId()) { + if (polling_count > 10) { + check = -1; + ret = -1; + break; + } + udelay(1000); + wf_ioremap_read(CONN_HW_VER_ADDR, &value); + polling_count++; + } + if (check != 0) { + DBGLOG(INIT, ERROR, "Polling CONNSYS version ID fail.\n"); + return ret; + } + /* Turn on "conn_infra to wfsys"/ wfsys to conn_infra" bus sleep protect + * 0x18001620[0] = 1'b1 + */ + wf_ioremap_read(CONN_INFRA_WF_SLP_CTRL_R_ADDR, &value); + value |= 0x00000001; + wf_ioremap_write(CONN_INFRA_WF_SLP_CTRL_R_ADDR, value); + + /* Polling WF_SLP_CTRL ready + * (polling "100 times" and each polling interval is "0.5ms") + * Address: 0x1800_1620[3] (CONN_INFRA_WF_SLP_CTRL_R_OFFSET[3]) + * Data: 1'b1 + * Action: polling + */ + wf_ioremap_read(CONN_INFRA_WF_SLP_CTRL_R_ADDR, &value); + check = 0; + polling_count = 0; + while ((value & 0x00000008) == 0) { + if (polling_count > 100) { + check = -1; + ret = -1; + break; + } + udelay(500); + wf_ioremap_read(CONN_INFRA_WF_SLP_CTRL_R_ADDR, &value); + polling_count++; + DBGLOG(INIT, ERROR, "WF_SLP_CTRL (0x%x) (%d)\n", + value, + polling_count); + } + if (check != 0) { + DBGLOG(INIT, ERROR, + "Polling WFSYS TO CONNINFRA SLEEP PROTECT fail. (0x%x)\n", + value); + soc3_0_DumpWfsysInfo(); + soc3_0_DumpWfsysdebugflag(); + } + /* Turn off "wf_dma to conn_infra" bus sleep protect + * 0x18001624[0] = 1'b1 + */ + wf_ioremap_read(CONN_INFRA_WFDMA_SLP_CTRL_R_ADDR, &value); + value |= 0x00000001; + wf_ioremap_write(CONN_INFRA_WFDMA_SLP_CTRL_R_ADDR, value); + + /* Polling wfsys_rgu_off_hreset_rst_b + * (polling "100 times" and each polling interval is "0.5ms") + * Address: 0x1800_1624[3] (CONN_INFRA_WFDMA_SLP_CTRL_R_OFFSET[3]) + * Data: 1'b1 + * Action: polling + */ + wf_ioremap_read(CONN_INFRA_WFDMA_SLP_CTRL_R_ADDR, &value); + check = 0; + polling_count = 0; + while ((value & 0x00000008) == 0) { + if (polling_count > 100) { + check = -1; + ret = -1; + break; + } + udelay(500); + wf_ioremap_read(CONN_INFRA_WFDMA_SLP_CTRL_R_ADDR, &value); + polling_count++; + DBGLOG(INIT, ERROR, "WFDMA_SLP_CTRL (0x%x) (%d)\n", + value, + polling_count); + } + if (check != 0) { + DBGLOG(INIT, ERROR, + "Polling WFDMA TO CONNINFRA SLEEP PROTECT RDY fail. (0x%x)\n", + value); + soc3_0_DumpWfsysInfo(); + soc3_0_DumpWfsysdebugflag(); + } + /* bus clock ctrl */ + conninfra_bus_clock_ctrl(CONNDRV_TYPE_WIFI, CONNINFRA_BUS_CLOCK_ALL, 0); + + /* Turn off wfsys_top_on + * 0x18000000[31:16] = 0x57460000, + * 0x18000000[7] = 1'b0 + */ + wf_ioremap_read(WFSYS_ON_TOP_PWR_CTL_ADDR, &value); + value &= 0x0000FF7F; + value |= 0x57460000; + wf_ioremap_write(WFSYS_ON_TOP_PWR_CTL_ADDR, value); + /* Polling wfsys_rgu_off_hreset_rst_b + * (polling "10 times" and each polling interval is "0.5ms") + * Address: 0x1806_02CC[2] (TOP_DBG_DUMMY_3_CONNSYS_PWR_STATUS[2]) + * Data: 1'b0 + * Action: polling + */ + + wf_ioremap_read(TOP_DBG_DUMMY_3_CONNSYS_PWR_STATUS_ADDR, &value); + check = 0; + polling_count = 0; + while ((value & 0x00000004) != 0) { + if (polling_count > 10) { + check = -1; + ret = -1; + break; + } + udelay(500); + wf_ioremap_read(TOP_DBG_DUMMY_3_CONNSYS_PWR_STATUS_ADDR, + &value); + polling_count++; + } + if (check != 0) { + DBGLOG(INIT, ERROR, + "Polling wfsys rgu off fail. (0x%x)\n", + value); + return ret; + } + /* Toggle WFSYS EMI request 0x18001c14[0] = 1'b1 -> 1'b0 */ + wf_ioremap_read(CONN_INFRA_WFSYS_EMI_REQ_ADDR, &value); + value |= 0x00000001; + wf_ioremap_write(CONN_INFRA_WFSYS_EMI_REQ_ADDR, value); + value &= 0xFFFFFFFE; + wf_ioremap_write(CONN_INFRA_WFSYS_EMI_REQ_ADDR, value); + + /* Reset WFSYS semaphore 0x18000018[0] = 1'b0 */ + wf_ioremap_read(WFSYS_SW_RST_B_ADDR, &value); + value &= 0xFFFFFFFE; + wf_ioremap_write(WFSYS_SW_RST_B_ADDR, value); + + /*Disable A-die top_ck_en (use common API)(clear driver & FW resource)*/ + conninfra_adie_top_ck_en_off(CONNSYS_ADIE_CTL_FW_WIFI); + + soc3_0_DumpBusHangdebuglog(); + /* Disable conn_infra off domain force on 0x180601A4[0] = 1'b0 */ + wf_ioremap_read(CONN_INFRA_WAKEUP_WF_ADDR, &value); + value &= 0xFFFFFFFE; + wf_ioremap_write(CONN_INFRA_WAKEUP_WF_ADDR, value); + return ret; +} + +int hifWmmcuPwrOn(void) +{ + int ret = 0; + uint32_t u4Value = 0; + +#if (CFG_SUPPORT_CONNINFRA == 1) + /* conninfra power on */ + if (!kalIsWholeChipResetting()) { + ret = conninfra_pwr_on(CONNDRV_TYPE_WIFI); + if (ret == CONNINFRA_ERR_RST_ONGOING) { + DBGLOG(INIT, ERROR, + "Conninfra is doing whole chip reset.\n"); + return ret; + } + if (ret != 0) { + DBGLOG(INIT, ERROR, + "Conninfra pwr on fail.\n"); + return ret; + } + } +#endif + /* wf driver power on */ + ret = wf_pwr_on_consys_mcu(); + if (ret != 0) + return ret; + + /* set FW own after power on consys mcu to + * keep Driver/FW/HW state sync + */ + wf_ioremap_read(CONN_HOST_CSR_TOP_BASE_ADDR + 0x0010, + &u4Value); + + if ((u4Value & BIT(2)) != BIT(2)) { + DBGLOG(INIT, INFO, "0x%08x = 0x%08x, Set FW Own\n", + CONN_HOST_CSR_TOP_BASE_ADDR + 0x0010, + u4Value); + + wf_ioremap_write(CONN_HOST_CSR_TOP_BASE_ADDR + 0x0010, + PCIE_LPCR_HOST_SET_OWN); + } + + DBGLOG(INIT, INFO, + "hifWmmcuPwrOn done\n"); + + return ret; +} + +void wlanCoAntVFE28En(IN struct ADAPTER *prAdapter) +{ + struct WIFI_CFG_PARAM_STRUCT *prNvramSettings; + struct REG_INFO *prRegInfo; + u_int8_t fgCoAnt; + + if (g_NvramFsm != NVRAM_STATE_READY) { + DBGLOG(INIT, INFO, "CoAntVFE28 NVRAM Not ready\n"); + return; + } + + ASSERT(prAdapter); + prRegInfo = &prAdapter->prGlueInfo->rRegInfo; + ASSERT(prRegInfo); + prNvramSettings = prRegInfo->prNvramSettings; + ASSERT(prNvramSettings); + + fgCoAnt = prNvramSettings->ucSupportCoAnt; + + if (fgCoAnt) { + if (gCoAntVFE28En == FALSE) { +#if (KERNEL_VERSION(4, 15, 0) <= CFG80211_VERSION_CODE) + regmap_write(g_regmap, + MT6359_LDO_VFE28_OP_EN_SET, 0x1 << 8); + regmap_write(g_regmap, + MT6359_LDO_VFE28_OP_CFG_CLR, 0x1 << 8); +#else + KERNEL_pmic_ldo_vfe28_lp(8, 0, 1, 0); +#endif + DBGLOG(INIT, INFO, "CoAntVFE28 PMIC Enable\n"); + gCoAntVFE28En = TRUE; + } else { + DBGLOG(INIT, INFO, "CoAntVFE28 PMIC Already Enable\n"); + } + } else { + DBGLOG(INIT, INFO, "Not Support CoAnt Enable\n"); + } +} + +void wlanCoAntVFE28Dis(void) +{ + if (gCoAntVFE28En == TRUE) { +#if (KERNEL_VERSION(4, 15, 0) <= CFG80211_VERSION_CODE) + regmap_write(g_regmap, MT6359_LDO_VFE28_OP_EN_CLR, 0x1 << 8); + regmap_write(g_regmap, MT6359_LDO_VFE28_OP_CFG_CLR, 0x1 << 8); + regmap_write(g_regmap, MT6359_LDO_VFE28_OP_CFG_CLR, 0x1 << 8); +#else + KERNEL_pmic_ldo_vfe28_lp(8, 0, 0, 0); +#endif + DBGLOG(INIT, INFO, "CoAntVFE28 PMIC Disable\n"); + gCoAntVFE28En = FALSE; + } else { + DBGLOG(INIT, INFO, "CoAntVFE28 PMIC Already Disable\n"); + } +} + +void wlanCoAntWiFi(void) +{ + uint32_t u4GPIO10 = 0x0; + + wf_ioremap_read(0x100053a0, &u4GPIO10); + u4GPIO10 |= 0x20000; + wf_ioremap_write(0x100053a0, u4GPIO10); + +} + +void wlanCoAntMD(void) +{ + uint32_t u4GPIO10 = 0x0; + + wf_ioremap_read(0x100053a0, &u4GPIO10); + u4GPIO10 |= 0x10000; + wf_ioremap_write(0x100053a0, u4GPIO10); + +} + + +#if (CFG_SUPPORT_CONNINFRA == 1) +int wlanConnacPccifon(void) +{ + int ret = 0; + + /*reset WiFi power on status to MD*/ + wf_ioremap_write(0x10003314, 0x00); + /*set WiFi power on status to MD*/ + wf_ioremap_write(0x10003314, 0x01); + /* + *Ccif4 (ccif_md2conn_wf): + *write cg gate 0x1000_10C0[28] & [29] (write 1 set) + *write cg gate 0x1000_10C4[28] & [29] (write 1 clear) + *Connsys/AP is used bit 28,md is used bit 29 + *default value is 0,clk enable + *Set cg must set both bit[28] [29], and clk turn off + *Clr cg set either bit[28][29], and clk turn on + + *Enable PCCIF4 clock + *HW auto control, so no need to turn on or turn off + *wf_ioremap_read(0x100010c4, ®); + *reg |= BIT(28); + *ret = wf_ioremap_write(0x100010c4,reg); + */ + return ret; +} + +int wlanConnacPccifoff(void) +{ + int ret = 0; + + /*reset WiFi power on status to MD*/ + ret = wf_ioremap_write(0x10003314, 0x00); + /*reset WiFi power on status to MD*/ + ret = wf_ioremap_write(0x1024c014, 0x0ff); + + /* + *Ccif4 (ccif_md2conn_wf): + *write cg gate 0x1000_10C0[28] & [29] (write 1 set) + *write cg gate 0x1000_10C4[28] & [29] (write 1 clear) + *Connsys/AP is used bit 28, md is used bit 29 + *default value is 0, clk enable + *Set cg must set both bit[28] [29], and clk turn off + *Clr cg set either bit[28][29], and clk turn on + + *Disable PCCIF4 clock + *HW auto control, so no need to turn on or turn off + *wf_ioremap_read(0x100010c0, ®); + *reg |= BIT(28); + *ret = wf_ioremap_write(0x100010c0,reg); + */ + return ret; +} +#endif + +int hifWmmcuPwrOff(void) +{ + int ret = 0; + /* wf driver power off */ + ret = wf_pwr_off_consys_mcu(); + if (ret != 0) + return ret; +#if (CFG_SUPPORT_CONNINFRA == 1) + /* + * conninfra power off sequence + * conninfra will do conninfra power off self during whole chip reset. + */ + if (!kalIsWholeChipResetting()) { + ret = conninfra_pwr_off(CONNDRV_TYPE_WIFI); + if (ret != 0) + return ret; + } +#endif + return ret; +} +#if (CFG_SUPPORT_CONNINFRA == 1) +int soc3_0_Trigger_whole_chip_rst(char *reason) +{ + return conninfra_trigger_whole_chip_rst(CONNDRV_TYPE_WIFI, reason); +} +void soc3_0_Sw_interrupt_handler(struct ADAPTER *prAdapter) +{ + int value = 0; + struct GL_HIF_INFO *prHifInfo = NULL; + + ASSERT(prAdapter); + prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + + if (!conninfra_reg_readable_no_lock()) { + DBGLOG(HAL, ERROR, + "conninfra_reg_readable fail\n"); + disable_irq_nosync(prHifInfo->u4IrqId_1); +#if (CFG_ANDORID_CONNINFRA_COREDUMP_SUPPORT == 1) + g_eWfRstSource = WF_RST_SOURCE_FW; +#endif + DBGLOG(HAL, ERROR, + "FW trigger assert(0x%x).\n", value); + fgIsResetting = TRUE; + update_driver_reset_status(fgIsResetting); + kalSetRstEvent(); + return; + } + HAL_MCR_WR(prAdapter, + CONN_INFRA_CFG_AP2WF_REMAP_1_ADDR, + CONN_MCU_CONFG_HS_BASE); + HAL_MCR_RD(prAdapter, + (CONN_INFRA_CFG_AP2WF_BUS_ADDR + 0xc0), + &value); + + DBGLOG(HAL, TRACE, "SW INT happened!!!!!(0x%x)\n", value); + HAL_MCR_WR(prAdapter, + (CONN_INFRA_CFG_AP2WF_BUS_ADDR + 0xc8), + value); + +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH + if (value & BIT(0)) + fw_log_wifi_irq_handler(); +#endif + + if (value & BIT(1)) { + if (kalIsResetting()) { +#if (CFG_ANDORID_CONNINFRA_COREDUMP_SUPPORT == 1) + g_eWfRstSource = WF_RST_SOURCE_DRIVER; +#endif + DBGLOG(HAL, ERROR, + "Wi-Fi Driver trigger, need do complete(0x%x).\n", + value); + complete(&g_triggerComp); + } else { + if (get_wifi_process_status() == 1) { + DBGLOG(HAL, ERROR, + "Wi-Fi on/off process is ongoing, ignore interrupt(0x%x).\n", + value); + return; + } +#if (CFG_ANDORID_CONNINFRA_COREDUMP_SUPPORT == 1) + g_eWfRstSource = WF_RST_SOURCE_FW; +#endif + DBGLOG(HAL, ERROR, + "FW trigger assert(0x%x).\n", value); + fgIsResetting = TRUE; + update_driver_reset_status(fgIsResetting); + kalSetRstEvent(); + } + } + if (value & BIT(2)) { + if (get_wifi_process_status() == 1) { + DBGLOG(HAL, ERROR, + "Wi-Fi on/off process is ongoing, ignore interrupt(0x%x).\n", + value); + return; + } +#if (CFG_ANDORID_CONNINFRA_COREDUMP_SUPPORT == 1) + g_eWfRstSource = WF_RST_SOURCE_FW; +#endif + DBGLOG(HAL, ERROR, + "FW trigger whole chip reset(0x%x).\n", value); + fgIsResetting = TRUE; + update_driver_reset_status(fgIsResetting); + g_IsWfsysBusHang = TRUE; + kalSetRstEvent(); + } + if (value & BIT(3)) { + if (get_wifi_process_status() == 1) { + DBGLOG(HAL, ERROR, + "Wi-Fi on/off process is ongoing, ignore interrupt(0x%x).\n", + value); + return; + } +#if (CFG_ANDORID_CONNINFRA_COREDUMP_SUPPORT == 1) + g_eWfRstSource = WF_RST_SOURCE_FW; +#endif + g_fgRstRecover = TRUE; + fgIsResetting = TRUE; + update_driver_reset_status(fgIsResetting); + kalSetRstEvent(); + } +} + +void soc3_0_Conninfra_cb_register(void) +{ + g_conninfra_wf_cb.rst_cb.pre_whole_chip_rst = + glRstwlanPreWholeChipReset; + g_conninfra_wf_cb.rst_cb.post_whole_chip_rst = + glRstwlanPostWholeChipReset; + +#if (CFG_SUPPORT_PRE_ON_PHY_ACTION == 1) + /* Register conninfra call back */ + g_conninfra_wf_cb.pre_cal_cb.pwr_on_cb = soc3_0_wlanPreCalPwrOn; + g_conninfra_wf_cb.pre_cal_cb.do_cal_cb = soc3_0_wlanPreCal; + update_pre_cal_status(0); +#endif /* (CFG_SUPPORT_PRE_ON_PHY_ACTION == 1) */ + + conninfra_sub_drv_ops_register(CONNDRV_TYPE_WIFI, + &g_conninfra_wf_cb); +} +#endif +void soc3_0_icapRiseVcoreClockRate(void) +{ + + + int value = 0; + + /*2 update Clork Rate*/ + /*0x1000123C[20]=1,218Mhz*/ + wf_ioremap_read(WF_CONN_INFA_BUS_CLOCK_RATE, &value); + value |= 0x00010000; + wf_ioremap_write(WF_CONN_INFA_BUS_CLOCK_RATE, value); +#if (CFG_SUPPORT_VCODE_VDFS == 1) + /*Enable VCore to 0.725*/ + + /*init*/ + if (!pm_qos_request_active(&wifi_req)) + pm_qos_add_request(&wifi_req, PM_QOS_VCORE_OPP, + PM_QOS_VCORE_OPP_DEFAULT_VALUE); + + /*update Vcore*/ + pm_qos_update_request(&wifi_req, 0); + + DBGLOG(HAL, STATE, "icapRiseVcoreClockRate done\n"); +#else + DBGLOG(HAL, STATE, "icapRiseVcoreClockRate skip\n"); +#endif /*#ifndef CFG_BUILD_X86_PLATFORM*/ +} + +void soc3_0_icapDownVcoreClockRate(void) +{ + + + int value = 0; + + /*2 update Clork Rate*/ + /*0x1000123C[20]=0,156Mhz*/ + wf_ioremap_read(WF_CONN_INFA_BUS_CLOCK_RATE, &value); + value &= ~(0x00010000); + wf_ioremap_write(WF_CONN_INFA_BUS_CLOCK_RATE, value); +#if (CFG_SUPPORT_VCODE_VDFS == 1) + + /*init*/ + if (!pm_qos_request_active(&wifi_req)) + pm_qos_add_request(&wifi_req, PM_QOS_VCORE_OPP, + PM_QOS_VCORE_OPP_DEFAULT_VALUE); + + /*restore to default Vcore*/ + pm_qos_update_request(&wifi_req, + PM_QOS_VCORE_OPP_DEFAULT_VALUE); + + /*disable VCore to normal setting*/ + DBGLOG(HAL, STATE, "icapDownVcoreClockRate done!\n"); +#else + DBGLOG(HAL, STATE, "icapDownVcoreClockRate skip\n"); + +#endif /*#ifndef CFG_BUILD_X86_PLATFORM*/ + +} + +#if (CFG_POWER_ON_DOWNLOAD_EMI_ROM_PATCH == 1) +#pragma message("SOC3_0::CFG_POWER_ON_DOWNLOAD_EMI_ROM_PATCH == 1") +void soc3_0_ConstructFirmwarePrio(struct GLUE_INFO *prGlueInfo, + uint8_t **apucNameTable, uint8_t **apucName, + uint8_t *pucNameIdx, uint8_t ucMaxNameIdx) +{ + int ret = 0; + uint8_t ucIdx = 0; + uint8_t aucFlavor[2] = {0}; + + kalGetFwFlavor(&aucFlavor[0]); + + for (ucIdx = 0; apucsoc3_0FwName[ucIdx]; ucIdx++) { + if ((*pucNameIdx + 3) >= ucMaxNameIdx) { + /* the table is not large enough */ + DBGLOG(INIT, ERROR, + "kalFirmwareImageMapping >> file name array is not enough.\n"); + ASSERT(0); + continue; + } + + /* Type 1. WIFI_RAM_CODE_soc1_0_1_1 */ + ret = kalSnprintf(*(apucName + (*pucNameIdx)), + CFG_FW_NAME_MAX_LEN, "%s_%u%s_%u", + apucsoc3_0FwName[ucIdx], + CFG_WIFI_IP_SET, + aucFlavor, + wlanGetEcoVersion( + prGlueInfo->prAdapter)); + if (ret >= 0 && ret < CFG_FW_NAME_MAX_LEN) + (*pucNameIdx) += 1; + else + DBGLOG(INIT, ERROR, + "[%u] kalSnprintf failed, ret: %d\n", + __LINE__, ret); + + /* Type 2. WIFI_RAM_CODE_soc1_0_1_1.bin */ + ret = kalSnprintf(*(apucName + (*pucNameIdx)), + CFG_FW_NAME_MAX_LEN, "%s_%u%s_%u.bin", + apucsoc3_0FwName[ucIdx], + CFG_WIFI_IP_SET, + aucFlavor, + wlanGetEcoVersion( + prGlueInfo->prAdapter)); + if (ret >= 0 && ret < CFG_FW_NAME_MAX_LEN) + (*pucNameIdx) += 1; + else + DBGLOG(INIT, ERROR, + "[%u] kalSnprintf failed, ret: %d\n", + __LINE__, ret); + + /* Type 3. WIFI_RAM_CODE_soc1_0 */ + ret = kalSnprintf(*(apucName + (*pucNameIdx)), + CFG_FW_NAME_MAX_LEN, "%s", + apucsoc3_0FwName[ucIdx]); + if (ret >= 0 && ret < CFG_FW_NAME_MAX_LEN) + (*pucNameIdx) += 1; + else + DBGLOG(INIT, ERROR, + "[%u] kalSnprintf failed, ret: %d\n", + __LINE__, ret); + + /* Type 4. WIFI_RAM_CODE_soc1_0.bin */ + ret = kalSnprintf(*(apucName + (*pucNameIdx)), + CFG_FW_NAME_MAX_LEN, "%s.bin", + apucsoc3_0FwName[ucIdx]); + if (ret >= 0 && ret < CFG_FW_NAME_MAX_LEN) + (*pucNameIdx) += 1; + else + DBGLOG(INIT, ERROR, + "[%u] kalSnprintf failed, ret: %d\n", + __LINE__, ret); + } +} + +void * +soc3_0_kalFirmwareImageMapping( + IN struct GLUE_INFO *prGlueInfo, + OUT void **ppvMapFileBuf, + OUT uint32_t *pu4FileLength, + IN enum ENUM_IMG_DL_IDX_T eDlIdx) +{ + uint8_t **apucNameTable = NULL; + uint8_t *apucName[SOC3_0_FILE_NAME_TOTAL + + 1]; /* extra +1, for the purpose of + * detecting the end of the array + */ + uint8_t idx = 0, max_idx, + aucNameBody[SOC3_0_FILE_NAME_TOTAL][SOC3_0_FILE_NAME_MAX], + sub_idx = 0; + struct mt66xx_chip_info *prChipInfo = + prGlueInfo->prAdapter->chip_info; + /* uint32_t chip_id = prChipInfo->chip_id; */ + uint8_t aucFlavor[2] = {0}; + + DEBUGFUNC("kalFirmwareImageMapping"); + + ASSERT(prGlueInfo); + ASSERT(ppvMapFileBuf); + ASSERT(pu4FileLength); + + *ppvMapFileBuf = NULL; + *pu4FileLength = 0; + kalGetFwFlavor(&aucFlavor[0]); + + do { + /* <0.0> Get FW name prefix table */ + switch (eDlIdx) { + case IMG_DL_IDX_N9_FW: + apucNameTable = soc3_0_apucFwName; + break; + + case IMG_DL_IDX_CR4_FW: + apucNameTable = soc3_0_apucCr4FwName; + break; + + case IMG_DL_IDX_PATCH: + break; + + case IMG_DL_IDX_MCU_ROM_EMI: + break; + + case IMG_DL_IDX_WIFI_ROM_EMI: + break; + + default: + ASSERT(0); + break; + } + + /* <0.2> Construct FW name */ + memset(apucName, 0, sizeof(apucName)); + + /* magic number 1: reservation for detection + * of the end of the array + */ + max_idx = (sizeof(apucName) / sizeof(uint8_t *)) - 1; + + idx = 0; + apucName[idx] = (uint8_t *)(aucNameBody + idx); + + if (eDlIdx == IMG_DL_IDX_PATCH) { + /* construct the file name for patch */ + /* soc3_0_patch_wmmcu_1_1_hdr.bin */ + if (prChipInfo->fw_dl_ops->constructPatchName) + prChipInfo->fw_dl_ops->constructPatchName( + prGlueInfo, apucName, &idx); + else + kalSnprintf(apucName[idx], SOC3_0_FILE_NAME_MAX, + "soc3_0_patch_wmmcu_1_%x_hdr.bin", + wlanGetEcoVersion( + prGlueInfo->prAdapter)); + idx += 1; + } else if (eDlIdx == IMG_DL_IDX_MCU_ROM_EMI) { + /* construct the file name for MCU ROM EMI */ + /* soc3_0_ram_wmmcu_1_1_hdr.bin */ + kalSnprintf(apucName[idx], SOC3_0_FILE_NAME_MAX, + "soc3_0_ram_wmmcu_%u%s_%x_hdr.bin", + CFG_WIFI_IP_SET, + aucFlavor, + wlanGetEcoVersion( + prGlueInfo->prAdapter)); + + idx += 1; + } else if (eDlIdx == IMG_DL_IDX_WIFI_ROM_EMI) { + /* construct the file name for WiFi ROM EMI */ + /* soc3_0_ram_wifi_1_1_hdr.bin */ + kalSnprintf(apucName[idx], SOC3_0_FILE_NAME_MAX, + "soc3_0_ram_wifi_%u%s_%x_hdr.bin", + CFG_WIFI_IP_SET, + aucFlavor, + wlanGetEcoVersion( + prGlueInfo->prAdapter)); + + idx += 1; + } else { + for (sub_idx = 0; sub_idx < max_idx; sub_idx++) + apucName[sub_idx] = + (uint8_t *)(aucNameBody + sub_idx); + + if (prChipInfo->fw_dl_ops->constructFirmwarePrio) + prChipInfo->fw_dl_ops->constructFirmwarePrio( + prGlueInfo, apucNameTable, apucName, + &idx, max_idx); + else + kalConstructDefaultFirmwarePrio( + prGlueInfo, apucNameTable, apucName, + &idx, max_idx); + } + + /* let the last pointer point to NULL + * so that we can detect the end of the array in + * kalFirmwareOpen(). + */ + apucName[idx] = NULL; + + apucNameTable = apucName; + + /* <1> Open firmware */ + if (kalFirmwareOpen(prGlueInfo, + apucNameTable) != WLAN_STATUS_SUCCESS) + break; + { + uint32_t u4FwSize = 0; + void *prFwBuffer = NULL; + /* <2> Query firmare size */ + kalFirmwareSize(prGlueInfo, &u4FwSize); + /* <3> Use vmalloc for allocating large memory trunk */ + prFwBuffer = vmalloc(ALIGN_4(u4FwSize)); + /* <4> Load image binary into buffer */ + if (kalFirmwareLoad(prGlueInfo, prFwBuffer, 0, + &u4FwSize) != WLAN_STATUS_SUCCESS) { + vfree(prFwBuffer); + kalFirmwareClose(prGlueInfo); + break; + } + /* <5> write back info */ + *pu4FileLength = u4FwSize; + *ppvMapFileBuf = prFwBuffer; + + return prFwBuffer; + } + } while (FALSE); + + return NULL; +} + +uint32_t soc3_0_wlanImageSectionDownloadStage( + IN struct ADAPTER *prAdapter, IN void *pvFwImageMapFile, + IN uint32_t u4FwImageFileLength, IN uint8_t ucSectionNumber, + IN enum ENUM_IMG_DL_IDX_T eDlIdx) +{ + uint32_t u4SecIdx, u4Offset = 0; + uint32_t u4Addr, u4Len, u4DataMode = 0; + u_int8_t fgIsEMIDownload = FALSE; + u_int8_t fgIsNotDownload = FALSE; + uint32_t u4Status = WLAN_STATUS_SUCCESS; + struct mt66xx_chip_info *prChipInfo = prAdapter->chip_info; + struct patch_dl_target target; + struct PATCH_FORMAT_T *prPatchHeader; + struct ROM_EMI_HEADER *prRomEmiHeader; + struct FWDL_OPS_T *prFwDlOps; + + prFwDlOps = prChipInfo->fw_dl_ops; + + /* 3a. parse file header for decision of + * divided firmware download or not + */ + if (eDlIdx == IMG_DL_IDX_PATCH) { + prPatchHeader = pvFwImageMapFile; + if (prPatchHeader->u4PatchVersion == PATCH_VERSION_MAGIC_NUM) { + wlanImageSectionGetPatchInfoV2(prAdapter, + pvFwImageMapFile, + u4FwImageFileLength, + &u4DataMode, + &target); + DBGLOG(INIT, INFO, + "FormatV2 num_of_regoin[%d] datamode[0x%08x]\n", + target.num_of_region, u4DataMode); + } else { + wlanImageSectionGetPatchInfo(prAdapter, + pvFwImageMapFile, + u4FwImageFileLength, + &u4Offset, &u4Addr, + &u4Len, &u4DataMode); + DBGLOG(INIT, INFO, + "FormatV1 DL Offset[%u] addr[0x%08x] len[%u] datamode[0x%08x]\n", + u4Offset, u4Addr, u4Len, u4DataMode); + } + + if (prPatchHeader->u4PatchVersion == PATCH_VERSION_MAGIC_NUM) + u4Status = wlanDownloadSectionV2(prAdapter, + u4DataMode, eDlIdx, &target); + else +/* For dynamic memory map::Begin */ +#if (CFG_DOWNLOAD_DYN_MEMORY_MAP == 1) + u4Status = prFwDlOps->downloadByDynMemMap( + prAdapter, u4Addr, u4Len, + pvFwImageMapFile + + u4Offset, + eDlIdx); +#else + u4Status = wlanDownloadSection( + prAdapter, + u4Addr, + u4Len, + u4DataMode, + pvFwImageMapFile + + u4Offset, + eDlIdx); +#endif +/* For dynamic memory map::End */ +#if (CFG_SUPPORT_CONNINFRA == 1) + /* Set datecode to EMI */ + wlanDownloadEMISection(prAdapter, + WMMCU_ROM_PATCH_DATE_ADDR, + DATE_CODE_SIZE, prPatchHeader->aucBuildDate); +#endif + + } else if ((eDlIdx == IMG_DL_IDX_MCU_ROM_EMI) || + (eDlIdx == IMG_DL_IDX_WIFI_ROM_EMI)) { + prRomEmiHeader = (struct ROM_EMI_HEADER *)pvFwImageMapFile; + + DBGLOG(INIT, INFO, + "DL %s ROM EMI %s\n", + (eDlIdx == IMG_DL_IDX_MCU_ROM_EMI) ? + "MCU":"WiFi", + (char *)prRomEmiHeader->ucDateTime); + + u4Addr = prRomEmiHeader->u4PatchAddr; + + u4Len = u4FwImageFileLength - sizeof(struct ROM_EMI_HEADER); + + u4Offset = sizeof(struct ROM_EMI_HEADER); + + u4Status = wlanDownloadEMISection(prAdapter, + u4Addr, u4Len, + pvFwImageMapFile + u4Offset); +#if (CFG_SUPPORT_CONNINFRA == 1) + /* Set datecode to EMI */ + if (eDlIdx == IMG_DL_IDX_MCU_ROM_EMI) + wlanDownloadEMISection(prAdapter, + WMMCU_MCU_ROM_EMI_DATE_ADDR, + DATE_CODE_SIZE, prRomEmiHeader->ucDateTime); + else + wlanDownloadEMISection(prAdapter, + WMMCU_WIFI_ROM_EMI_DATE_ADDR, + DATE_CODE_SIZE, prRomEmiHeader->ucDateTime); +#endif + } else { + for (u4SecIdx = 0; u4SecIdx < ucSectionNumber; + u4SecIdx++, u4Offset += u4Len) { + prChipInfo->fw_dl_ops->getFwInfo(prAdapter, u4SecIdx, + eDlIdx, &u4Addr, + &u4Len, &u4DataMode, &fgIsEMIDownload, + &fgIsNotDownload); + + DBGLOG(INIT, INFO, + "DL Offset[%u] addr[0x%08x] len[%u] datamode[0x%08x]\n", + u4Offset, u4Addr, u4Len, u4DataMode); + + if (fgIsNotDownload) + continue; + else if (fgIsEMIDownload) + u4Status = wlanDownloadEMISection(prAdapter, + u4Addr, u4Len, + pvFwImageMapFile + u4Offset); +/* For dynamic memory map:: Begin */ +#if (CFG_DOWNLOAD_DYN_MEMORY_MAP == 1) + else if ((u4DataMode & + DOWNLOAD_CONFIG_ENCRYPTION_MODE) == 0) { + /* Non-encrypted F/W region, + * use dynamic memory mapping for download + */ + u4Status = prFwDlOps->downloadByDynMemMap( + prAdapter, + u4Addr, + u4Len, + pvFwImageMapFile + u4Offset, + eDlIdx); + } +#endif +/* For dynamic memory map:: End */ + else + u4Status = wlanDownloadSection(prAdapter, + u4Addr, u4Len, + u4DataMode, + pvFwImageMapFile + u4Offset, eDlIdx); + + /* escape from loop if any pending error occurs */ + if (u4Status == WLAN_STATUS_FAILURE) + break; + } + } + + return u4Status; +} + +/* WiFi power on download MCU/WiFi ROM EMI + ROM patch */ +/*----------------------------------------------------------------------------*/ +/*! + * \brief Wlan power on download function. This function prepare the job + * during power on stage: + * [1]Download MCU + WiFi ROM EMI + * [2]Download ROM patch + * + * \retval 0 Success + * \retval negative value Failed + */ +/*----------------------------------------------------------------------------*/ +uint32_t soc3_0_wlanPowerOnDownload( + IN struct ADAPTER *prAdapter, + IN uint8_t ucDownloadItem) +{ + uint32_t u4FwSize = 0; + void *prFwBuffer = NULL; + uint32_t u4Status; +#if CFG_SUPPORT_COMPRESSION_FW_OPTION + uint8_t ucIsCompressed; +#endif + if (!prAdapter) + return WLAN_STATUS_FAILURE; + + + DBGLOG_LIMITED(INIT, INFO, + "Power on download start(%d)\n", ucDownloadItem); + + switch (ucDownloadItem) { + case ENUM_WLAN_POWER_ON_DOWNLOAD_EMI: + /* Download MCU ROM EMI*/ + soc3_0_kalFirmwareImageMapping(prAdapter->prGlueInfo, + &prFwBuffer, &u4FwSize, IMG_DL_IDX_MCU_ROM_EMI); + + if (prFwBuffer == NULL) { + DBGLOG(INIT, WARN, "FW[%u] load error!\n", + IMG_DL_IDX_MCU_ROM_EMI); + return WLAN_STATUS_FAILURE; + } + + u4Status = soc3_0_wlanImageSectionDownloadStage( + prAdapter, prFwBuffer, u4FwSize, 1, + IMG_DL_IDX_MCU_ROM_EMI); + + kalFirmwareImageUnmapping( + prAdapter->prGlueInfo, NULL, prFwBuffer); + + DBGLOG_LIMITED(INIT, INFO, "Power on download mcu ROM EMI %s\n", + (u4Status == WLAN_STATUS_SUCCESS) ? "pass" : "failed"); + + /* Download WiFi ROM EMI*/ + if (u4Status == WLAN_STATUS_SUCCESS) { + soc3_0_kalFirmwareImageMapping(prAdapter->prGlueInfo, + &prFwBuffer, &u4FwSize, + IMG_DL_IDX_WIFI_ROM_EMI); + + if (prFwBuffer == NULL) { + DBGLOG(INIT, WARN, "FW[%u] load error!\n", + IMG_DL_IDX_WIFI_ROM_EMI); + return WLAN_STATUS_FAILURE; + } + + u4Status = soc3_0_wlanImageSectionDownloadStage( + prAdapter, prFwBuffer, u4FwSize, 1, + IMG_DL_IDX_WIFI_ROM_EMI); + + kalFirmwareImageUnmapping( + prAdapter->prGlueInfo, NULL, prFwBuffer); + + DBGLOG_LIMITED(INIT, INFO, + "Power on download WiFi ROM EMI %s\n", + (u4Status == WLAN_STATUS_SUCCESS) + ? "pass" : "failed"); + } + + break; + + case ENUM_WLAN_POWER_ON_DOWNLOAD_ROM_PATCH: + prAdapter->rVerInfo.fgPatchIsDlByDrv = FALSE; + + soc3_0_kalFirmwareImageMapping(prAdapter->prGlueInfo, + &prFwBuffer, &u4FwSize, IMG_DL_IDX_PATCH); + + if (prFwBuffer == NULL) { + DBGLOG(INIT, WARN, "FW[%u] load error!\n", + IMG_DL_IDX_PATCH); + return WLAN_STATUS_FAILURE; + } + +#if (CFG_ROM_PATCH_NO_SEM_CTRL == 0) +#pragma message("ROM code supports SEM-CTRL for ROM patch download") + if (wlanPatchIsDownloaded(prAdapter)) { + kalFirmwareImageUnmapping(prAdapter->prGlueInfo, NULL, + prFwBuffer); + DBGLOG_LIMITED(INIT, INFO, + "No need to download patch\n"); + return WLAN_STATUS_SUCCESS; + } +#else +#pragma message("ROM code supports no SEM-CTRL for ROM patch download") +#endif + + /* Patch DL */ +#if CFG_SUPPORT_COMPRESSION_FW_OPTION + u4Status = wlanCompressedImageSectionDownloadStage( + prAdapter, prFwBuffer, u4FwSize, 1, + IMG_DL_IDX_PATCH, &ucIsCompressed, NULL); +#else + u4Status = soc3_0_wlanImageSectionDownloadStage( + prAdapter, prFwBuffer, u4FwSize, 1, IMG_DL_IDX_PATCH); +#endif + +/* Dynamic memory map::Begin */ +#if (CFG_DOWNLOAD_DYN_MEMORY_MAP == 1) + if (u4Status == WLAN_STATUS_SUCCESS) + wlanPatchDynMemMapSendComplete(prAdapter); + else if (u4Status == WLAN_STATUS_NOT_ACCEPTED) + u4Status = WLAN_STATUS_SUCCESS; /* already download*/ +#else + wlanPatchSendComplete(prAdapter); +#endif +/* Dynamic memory map::End */ + + kalFirmwareImageUnmapping( + prAdapter->prGlueInfo, NULL, prFwBuffer); + + prAdapter->rVerInfo.fgPatchIsDlByDrv = TRUE; + + break; + + default: + return WLAN_STATUS_NOT_SUPPORTED; + } + + DBGLOG_LIMITED(INIT, INFO, "Power on download end[%d].\n", u4Status); + + return u4Status; +} + +/* WiFi power on init for MCU/WiFi ROM EMI + ROM patch download */ +/*----------------------------------------------------------------------------*/ +/*! + * \brief Wlan power on init function. This function do the job in the + * power on stage, they are: + * [1]Download MCU + WiFi ROM EMI + * [2]Download ROM patch + * + * It is to simulate wlanProbe() with the minimum effort to complete + * ROM EMI + ROM patch download. + * + * \retval 0 Success + * \retval negative value Failed + */ +/*----------------------------------------------------------------------------*/ +int32_t soc3_0_wlanPowerOnInit( + enum ENUM_WLAN_POWER_ON_DOWNLOAD eDownloadItem) +{ +/* +* pvData data passed by bus driver init function +* _HIF_EHPI: NULL +* _HIF_SDIO: sdio bus driver handle +* see hifAxiProbe() for more detail... +* pfWlanProbe((void *)prPlatDev, +* (void *)prPlatDev->id_entry->driver_data) +*/ + void *pvData; + void *pvDriverData = (void *)&mt66xx_driver_data_soc3_0; + + int32_t i4Status = 0; + enum ENUM_POWER_ON_INIT_FAIL_REASON { + BUS_INIT_FAIL = 0, + NET_CREATE_FAIL, + BUS_SET_IRQ_FAIL, + ALLOC_ADAPTER_MEM_FAIL, + DRIVER_OWN_FAIL, + INIT_ADAPTER_FAIL, + INIT_HIFINFO_FAIL, + ROM_PATCH_DOWNLOAD_FAIL, + POWER_ON_INIT_DONE, + FAIL_REASON_NUM + } eFailReason; + uint32_t i = 0; + int32_t i4DevIdx = 0; + struct wireless_dev *prWdev = NULL; + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + struct mt66xx_chip_info *prChipInfo; + struct FWDL_OPS_T *prFwDlOps; + + DBGLOG(INIT, INFO, "wlanPowerOnInit::begin\n"); + + eFailReason = FAIL_REASON_NUM; + + do { + prChipInfo = ((struct mt66xx_hif_driver_data *)pvDriverData) + ->chip_info; + pvData = (void *)prChipInfo->pdev; + + if (eDownloadItem == ENUM_WLAN_POWER_ON_DOWNLOAD_EMI) { + if (fgSimplifyResetFlow) { + prGlueInfo = (struct GLUE_INFO *) + wiphy_priv(wlanGetWiphy()); + prAdapter = prGlueInfo->prAdapter; + + if (prChipInfo->pwrondownload) { + DBGLOG_LIMITED(INIT, INFO, + "[Wi-Fi PWR On] EMI download Start\n"); + + if (prChipInfo->pwrondownload( + prAdapter, eDownloadItem) + != WLAN_STATUS_SUCCESS) + i4Status = + -ROM_PATCH_DOWNLOAD_FAIL; + + DBGLOG_LIMITED(INIT, INFO, + "[Wi-Fi PWR On] EMI download End\n"); + } + } else { + prWdev = wlanNetCreate(pvData, pvDriverData); + + if (prWdev == NULL) { + DBGLOG(INIT, ERROR, + "[Wi-Fi PWR On] No memory for dev and its private\n"); + + i4Status = -NET_CREATE_FAIL; + } else { + /* Set the ioaddr to HIF Info */ + prGlueInfo = (struct GLUE_INFO *) + wiphy_priv(prWdev->wiphy); + + prAdapter = prGlueInfo->prAdapter; + + if (prChipInfo->pwrondownload) { + DBGLOG_LIMITED(INIT, INFO, + "[Wi-Fi PWR On] EMI download Start\n"); + + if (prChipInfo->pwrondownload( + prAdapter, eDownloadItem) + != WLAN_STATUS_SUCCESS) { + i4Status = + -ROM_PATCH_DOWNLOAD_FAIL; + } + + DBGLOG_LIMITED(INIT, INFO, + "[Wi-Fi PWR On] EMI download End\n"); + } + + wlanWakeLockUninit(prGlueInfo); + } + + wlanNetDestroy(prWdev); + } + + return i4Status; + } + + /* [1]Copy from wlanProbe()::Begin */ + /* Initialize the IO port of the interface */ + /* GeorgeKuo: pData has different meaning for _HIF_XXX: + * _HIF_EHPI: pointer to memory base variable, which will be + * initialized by glBusInit(). + * _HIF_SDIO: bus driver handle + */ + + /* Remember to call glBusRelease() in wlanPowerOnDeinit() */ + if (glBusInit(pvData) == FALSE) { + DBGLOG(INIT, ERROR, + "[Wi-Fi PWR On] glBusInit() fail\n"); + + i4Status = -EIO; + + eFailReason = BUS_INIT_FAIL; + + break; + } + +#if (CFG_SUPPORT_TRACE_TC4 == 1) + wlanDebugTC4Init(); +#endif + + /* Create network device, Adapter, KalInfo, + * prDevHandler(netdev) + */ + prWdev = wlanNetCreate(pvData, pvDriverData); + + if (prWdev == NULL) { + DBGLOG(INIT, ERROR, + "[Wi-Fi PWR On] No memory for dev and its private\n"); + + i4Status = -ENOMEM; + + eFailReason = NET_CREATE_FAIL; + + break; + } + + /* Set the ioaddr to HIF Info */ + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(prWdev->wiphy); + + /* Should we need this??? to be conti... */ + gPrDev = prGlueInfo->prDevHandler; + + /* Setup IRQ */ + i4Status = glBusSetIrq(prWdev->netdev, NULL, prGlueInfo); + + if (i4Status != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, ERROR, "[Wi-Fi PWR On] Set IRQ error\n"); + + eFailReason = BUS_SET_IRQ_FAIL; + + break; + } + + prGlueInfo->i4DevIdx = i4DevIdx; + + prAdapter = prGlueInfo->prAdapter; + /* [1]Copy from wlanProbe()::End */ + + /* [2]Copy from wlanProbe()->wlanOnPreAdapterStart()::Begin */ + /* Init Chip Capability */ + prChipInfo = prAdapter->chip_info; + + if (prChipInfo->asicCapInit) + prChipInfo->asicCapInit(prAdapter); + + /* Trigger the action of switching Pwr state to drv_own */ + prAdapter->fgIsFwOwn = TRUE; + + nicpmWakeUpWiFi(prAdapter); + /* [2]Copy from wlanProbe()->wlanOnPreAdapterStart()::End */ + + /* [3]Copy from + * wlanProbe() + * ->wlanAdapterStart() + * ->wlanOnPreAllocAdapterMem()::Begin + */ +#if 0 /* Sample's gen4m code base doesn't support */ + prAdapter->u4HifDbgFlag = 0; + prAdapter->u4HifChkFlag = 0; + prAdapter->u4NoMoreRfb = 0; +#endif + + prAdapter->u4OwnFailedCount = 0; + prAdapter->u4OwnFailedLogCount = 0; + + /* Additional with chip reset optimize*/ + prAdapter->ucCmdSeqNum = 0; + prAdapter->u4PwrCtrlBlockCnt = 0; + + QUEUE_INITIALIZE(&(prAdapter->rPendingCmdQueue)); +#if CFG_SUPPORT_MULTITHREAD + QUEUE_INITIALIZE(&prAdapter->rTxCmdQueue); + QUEUE_INITIALIZE(&prAdapter->rTxCmdDoneQueue); +#if CFG_FIX_2_TX_PORT + QUEUE_INITIALIZE(&prAdapter->rTxP0Queue); + QUEUE_INITIALIZE(&prAdapter->rTxP1Queue); +#else + for (i = 0; i < TX_PORT_NUM; i++) + QUEUE_INITIALIZE(&prAdapter->rTxPQueue[i]); +#endif + QUEUE_INITIALIZE(&prAdapter->rRxQueue); + QUEUE_INITIALIZE(&prAdapter->rTxDataDoneQueue); +#endif + + /* reset fgIsBusAccessFailed */ + fgIsBusAccessFailed = FALSE; + + /* Allocate mandatory resource for TX/RX */ + if (nicAllocateAdapterMemory(prAdapter) + != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, ERROR, + "[Wi-Fi PWR On] nicAllocateAdapterMemory Error!\n"); + + i4Status = -ENOMEM; + + eFailReason = ALLOC_ADAPTER_MEM_FAIL; +/* +*#if CFG_ENABLE_KEYWORD_EXCEPTION_MECHANISM & 0 +* mtk_wcn_wmt_assert_keyword(WMTDRV_TYPE_WIFI, +* "[Wi-Fi PWR On] nicAllocateAdapterMemory Error!"); +*#endif +*/ + break; + } + + /* should we need this? to be conti... */ + prAdapter->u4OsPacketFilter = PARAM_PACKET_FILTER_SUPPORTED; + + /* WLAN driver acquire LP own */ + DBGLOG(INIT, TRACE, "[Wi-Fi PWR On] Acquiring LP-OWN\n"); + + ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); + + DBGLOG(INIT, TRACE, "[Wi-Fi PWR On] Acquiring LP-OWN-end\n"); + + if (prAdapter->fgIsFwOwn == TRUE) { + DBGLOG(INIT, ERROR, + "[Wi-Fi PWR On] nicpmSetDriverOwn() failed!\n"); + + eFailReason = DRIVER_OWN_FAIL; +/* +*#if CFG_ENABLE_KEYWORD_EXCEPTION_MECHANISM & 0 +* mtk_wcn_wmt_assert_keyword(WMTDRV_TYPE_WIFI, +* "[Wi-Fi PWR On] nicpmSetDriverOwn() failed!"); +*#endif +*/ + break; + } + + /* Initialize the Adapter: + * verify chipset ID, HIF init... + * the code snippet just do the copy thing + */ + if (nicInitializeAdapter(prAdapter) != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, ERROR, + "[Wi-Fi PWR On] nicInitializeAdapter failed!\n"); + + eFailReason = INIT_ADAPTER_FAIL; + + break; + } + + /* Do the post NIC init adapter: + * copy only the mandatory task + * in wlanOnPostNicInitAdapter(prAdapter, FALSE)::Begin + */ + nicInitSystemService(prAdapter, FALSE); + + /* Initialize Tx */ + nicTxInitialize(prAdapter); + + /* Initialize Rx */ + nicRxInitialize(prAdapter); + /* Do the post NIC init adapter: + * copy only the mandatory task + * in wlanOnPostNicInitAdapter(prAdapter, FALSE)::End + */ + + /* HIF SW info initialize */ + if (!halHifSwInfoInit(prAdapter)) { + DBGLOG(INIT, ERROR, + "[Wi-Fi PWR On] halHifSwInfoInit failed!\n"); + + eFailReason = INIT_HIFINFO_FAIL; + + break; + } + + /* Enable HIF cut-through to N9 mode */ + HAL_ENABLE_FWDL(prAdapter, TRUE); + + wlanSetChipEcoInfo(prAdapter); + + /* should we open it, to be conti */ + /* wlanOnPostInitHifInfo(prAdapter); */ + + /* Disable interrupt, download is done by polling mode only */ + nicDisableInterrupt(prAdapter); + + /* Initialize Tx Resource to fw download state */ + nicTxInitResetResource(prAdapter); + + /* MCU ROM EMI + + * WiFi ROM EMI + ROM patch download goes over here::Begin + */ + /* assiggned in wlanNetCreate() */ + prChipInfo = prAdapter->chip_info; + + /* It is configured in mt66xx_chip_info_connac2x2.fw_dl_ops */ + prFwDlOps = prChipInfo->fw_dl_ops; + + /* No need to check F/W ready bit, + * since we are downloading MCU ROM EMI + * + WiFi ROM EMI + ROM patch + */ + /* + *DBGLOG(INIT, INFO, + * "wlanDownloadFW:: Check ready_bits(=0x%x)\n", + * prChipInfo->sw_ready_bits); + * + *HAL_WIFI_FUNC_READY_CHECK(prAdapter, + * prChipInfo->sw_ready_bits, &fgReady); + */ + + if (prChipInfo->pwrondownload) { + HAL_ENABLE_FWDL(prAdapter, TRUE); + + DBGLOG_LIMITED(INIT, INFO, + "[Wi-Fi PWR On] download Start\n"); + + if (prChipInfo->pwrondownload(prAdapter, eDownloadItem) + != WLAN_STATUS_SUCCESS) { + eFailReason = ROM_PATCH_DOWNLOAD_FAIL; + + HAL_ENABLE_FWDL(prAdapter, FALSE); + + break; + } + + DBGLOG_LIMITED(INIT, INFO, + "[Wi-Fi PWR On] download End\n"); + + HAL_ENABLE_FWDL(prAdapter, FALSE); + } + /* MCU ROM EMI + WiFi ROM EMI + * + ROM patch download goes over here::End + */ + + eFailReason = POWER_ON_INIT_DONE; + /* [3]Copy from wlanProbe() + * ->wlanAdapterStart() + * ->wlanOnPreAllocAdapterMem()::End + */ + } while (FALSE); + + switch (eFailReason) { + case BUS_INIT_FAIL: + break; + + case NET_CREATE_FAIL: +#if (CFG_SUPPORT_TRACE_TC4 == 1) + wlanDebugTC4Uninit(); /* Uninit for TC4 debug */ +#endif + + /* We should call this, although nothing is inside */ + glBusRelease(pvData); + + break; + + case BUS_SET_IRQ_FAIL: +#if (CFG_SUPPORT_TRACE_TC4 == 1) + wlanDebugTC4Uninit(); /* Uninit for TC4 debug */ +#endif + + /* We should call this, although nothing is inside */ + glBusRelease(pvData); + + wlanWakeLockUninit(prGlueInfo); + + wlanNetDestroy(prWdev); + + break; + + case ALLOC_ADAPTER_MEM_FAIL: + case DRIVER_OWN_FAIL: + case INIT_ADAPTER_FAIL: + /* Should we set Onwership to F/W for advanced debug??? + * to be conti... + */ + /* nicpmSetFWOwn(prAdapter, FALSE); */ + + glBusFreeIrq(prWdev->netdev, + *((struct GLUE_INFO **)netdev_priv(prWdev->netdev))); + +#if (CFG_SUPPORT_TRACE_TC4 == 1) + wlanDebugTC4Uninit(); /* Uninit for TC4 debug */ +#endif + + /* We should call this, although nothing is inside */ + glBusRelease(pvData); + + wlanWakeLockUninit(prGlueInfo); + + wlanNetDestroy(prWdev); + + break; + + case INIT_HIFINFO_FAIL: + nicRxUninitialize(prAdapter); + + nicTxRelease(prAdapter, FALSE); + + /* System Service Uninitialization */ + nicUninitSystemService(prAdapter); + + /* Should we set Onwership to F/W for advanced debug??? + * to be conti... + */ + /* nicpmSetFWOwn(prAdapter, FALSE); */ + + glBusFreeIrq(prWdev->netdev, + *((struct GLUE_INFO **)netdev_priv(prWdev->netdev))); + +#if (CFG_SUPPORT_TRACE_TC4 == 1) + wlanDebugTC4Uninit(); /* Uninit for TC4 debug */ +#endif + + /* We should call this, although nothing is inside */ + glBusRelease(pvData); + + wlanWakeLockUninit(prGlueInfo); + + wlanNetDestroy(prWdev); + + break; + + case ROM_PATCH_DOWNLOAD_FAIL: + case POWER_ON_INIT_DONE: + HAL_ENABLE_FWDL(prAdapter, FALSE); + + nicRxUninitialize(prAdapter); + + nicTxRelease(prAdapter, FALSE); + + /* System Service Uninitialization */ + nicUninitSystemService(prAdapter); + + /* Should we set Onwership to F/W for advanced debug??? + * to be conti... + */ + /* nicpmSetFWOwn(prAdapter, FALSE); */ + + glBusFreeIrq(prWdev->netdev, + *((struct GLUE_INFO **)netdev_priv(prWdev->netdev))); + +#if (CFG_SUPPORT_TRACE_TC4 == 1) + wlanDebugTC4Uninit(); /* Uninit for TC4 debug */ +#endif + + /* We should call this, although nothing is inside */ + glBusRelease(pvData); + + wlanWakeLockUninit(prGlueInfo); + + wlanNetDestroy(prWdev); + + break; + + default: + break; + } + + DBGLOG(INIT, INFO, "wlanPowerOnInit::end\n"); + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Wlan power on deinit function. This function revert whatever + * has been altered in the + * power on stage to restore to the most original state. + * + * \param[in] void + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +/* +*static void wlanPowerOnDeinit(void) +*{ +* +*} +*/ +#endif + +#if (CFG_SUPPORT_PRE_ON_PHY_ACTION == 1) +uint32_t soc3_0_wlanAccessCalibrationEMI( + struct INIT_EVENT_PHY_ACTION_RSP *pCalEvent, + uint8_t backupEMI) +{ + uint32_t u4Status = WLAN_STATUS_FAILURE; + +#if CFG_MTK_ANDROID_EMI + uint8_t __iomem *pucEmiBaseAddr = NULL; + + if (!gConEmiPhyBaseFinal) { + DBGLOG(INIT, ERROR, + "gConEmiPhyBaseFinal invalid\n"); + return u4Status; + } + + request_mem_region(gConEmiPhyBaseFinal, gConEmiSizeFinal, "WIFI-EMI"); + kalSetEmiMpuProtection(gConEmiPhyBaseFinal, false); + pucEmiBaseAddr = + ioremap_nocache(gConEmiPhyBaseFinal, gConEmiSizeFinal); + DBGLOG(INIT, INFO, + "backupEMI(%d),gConEmiPhyBaseFinal(0x%x),gConEmiSizeFinal(0x%X),pucEmiBaseAddr(0x%x)\n", + backupEMI, gConEmiPhyBaseFinal, gConEmiSizeFinal, + pucEmiBaseAddr); + + do { + if (!pucEmiBaseAddr) { + DBGLOG(INIT, ERROR, "ioremap_nocache failed\n"); + break; + } + + if (backupEMI == TRUE) { + if (gEmiCalResult != NULL) { + kalMemFree(gEmiCalResult, + VIR_MEM_TYPE, + gEmiCalSize); + gEmiCalResult = NULL; + } + + gEmiCalOffset = pCalEvent->u4EmiAddress & + WIFI_EMI_ADDR_MASK; + gEmiCalSize = pCalEvent->u4EmiLength; + + if (gEmiCalSize == 0) { + DBGLOG(INIT, ERROR, "gEmiCalSize 0\n"); + break; + } + + gEmiCalResult = kalMemAlloc(gEmiCalSize, VIR_MEM_TYPE); + + if (gEmiCalResult == NULL) { + DBGLOG(INIT, ERROR, + "gEmiCalResult kalMemAlloc NULL\n"); + break; + } + + memcpy_fromio(gEmiCalResult, + (pucEmiBaseAddr + gEmiCalOffset), + gEmiCalSize); + + u4Status = WLAN_STATUS_SUCCESS; + break; + } + + /* else, put calibration data to EMI */ + + if (gEmiCalResult == NULL) { + DBGLOG(INIT, ERROR, "gEmiCalResult NULL\n"); + break; + } + + if (gEmiCalUseEmiData == TRUE) { + DBGLOG(INIT, INFO, "No Write back to EMI\n"); + break; + } + + memcpy_toio((pucEmiBaseAddr + gEmiCalOffset), + gEmiCalResult, + gEmiCalSize); + + u4Status = WLAN_STATUS_SUCCESS; + } while (FALSE); + + kalSetEmiMpuProtection(gConEmiPhyBaseFinal, true); + iounmap(pucEmiBaseAddr); + release_mem_region(gConEmiPhyBaseFinal, gConEmiSizeFinal); +#endif /* CFG_MTK_ANDROID_EMI */ + return u4Status; +} + +uint32_t soc3_0_wlanRcvPhyActionRsp(struct ADAPTER *prAdapter, + uint8_t ucCmdSeqNum) +{ + struct mt66xx_chip_info *prChipInfo; + uint8_t *aucBuffer; + uint32_t u4EventSize; + struct INIT_WIFI_EVENT *prInitEvent; + struct HAL_PHY_ACTION_TLV_HEADER *prPhyTlvHeader; + struct HAL_PHY_ACTION_TLV *prPhyTlv; + struct INIT_EVENT_PHY_ACTION_RSP *prPhyEvent; + uint32_t u4RxPktLength; + uint32_t u4Status = WLAN_STATUS_FAILURE; + uint8_t ucPortIdx = IMG_DL_STATUS_PORT_IDX; + + ASSERT(prAdapter); + prChipInfo = prAdapter->chip_info; + + u4EventSize = prChipInfo->rxd_size + + prChipInfo->init_event_size + + sizeof(struct HAL_PHY_ACTION_TLV_HEADER) + + sizeof(struct HAL_PHY_ACTION_TLV) + + sizeof(struct INIT_EVENT_PHY_ACTION_RSP); + aucBuffer = kalMemAlloc(u4EventSize, PHY_MEM_TYPE); + if (aucBuffer == NULL) { + DBGLOG(INIT, ERROR, "kalMemAlloc failed\n"); + return WLAN_STATUS_FAILURE; + } + + do { + if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE + || fgIsBusAccessFailed == TRUE) { + DBGLOG(INIT, ERROR, "kalIsCardRemoved failed\n"); + break; + } + + if (nicRxWaitResponse(prAdapter, ucPortIdx, + aucBuffer, u4EventSize, + &u4RxPktLength) != + WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, ERROR, "nicRxWaitResponse failed\n"); + break; + } + + prInitEvent = (struct INIT_WIFI_EVENT *) + (aucBuffer + prChipInfo->rxd_size); + + /* EID / SeqNum check */ + if (prInitEvent->ucEID != INIT_EVENT_ID_PHY_ACTION) { + DBGLOG(INIT, ERROR, + "INIT_EVENT_ID_PHY_ACTION failed\n"); + break; + } + + if (prInitEvent->ucSeqNum != ucCmdSeqNum) { + DBGLOG(INIT, ERROR, "ucCmdSeqNum failed\n"); + break; + } + + prPhyTlvHeader = (struct HAL_PHY_ACTION_TLV_HEADER *) + prInitEvent->aucBuffer; + + if (prPhyTlvHeader->u4MagicNum != HAL_PHY_ACTION_MAGIC_NUM) { + DBGLOG(INIT, ERROR, + "HAL_PHY_ACTION_MAGIC_NUM failed\n"); + break; + } + + prPhyTlv = + (struct HAL_PHY_ACTION_TLV *)prPhyTlvHeader->aucBuffer; + + prPhyEvent = (struct INIT_EVENT_PHY_ACTION_RSP *) + prPhyTlv->aucBuffer; + + if (prPhyTlv->u2Tag == HAL_PHY_ACTION_TAG_CAL) { + + DBGLOG(INIT, INFO, + "HAL_PHY_ACTION_TAG_CAL ucEvent[0x%x]status[0x%x]emiAddr[0x%x]emiLen[0x%x]\n", + prPhyEvent->ucEvent, + prPhyEvent->ucStatus, + prPhyEvent->u4EmiAddress, + prPhyEvent->u4EmiLength); + + if ((prPhyEvent->ucEvent == + HAL_PHY_ACTION_CAL_FORCE_CAL_RSP && + prPhyEvent->ucStatus == + HAL_PHY_ACTION_STATUS_SUCCESS) || + (prPhyEvent->ucEvent == + HAL_PHY_ACTION_CAL_USE_BACKUP_RSP && + prPhyEvent->ucStatus == + HAL_PHY_ACTION_STATUS_RECAL)) { + + /* read from EMI, backup in driver */ + soc3_0_wlanAccessCalibrationEMI(prPhyEvent, + TRUE); + } + + u4Status = WLAN_STATUS_SUCCESS; + } else if (prPhyTlv->u2Tag == HAL_PHY_ACTION_TAG_FEM) { + + DBGLOG(INIT, INFO, + "HAL_PHY_ACTION_TAG_FEM status[0x%x]\n", + prPhyEvent->ucStatus); + + u4Status = WLAN_STATUS_SUCCESS; + } + } while (FALSE); + + kalMemFree(aucBuffer, PHY_MEM_TYPE, u4EventSize); + return u4Status; +} + +void soc3_0_wlanGetEpaElnaFromNvram( + uint8_t **pu1DataPointer, + uint32_t *pu4DataLen) +{ +#define MAX_NVRAM_READY_COUNT 10 + + /* ePA /eLNA */ + uint8_t index; + uint8_t u1TypeID; + uint8_t u1LenLSB; + uint8_t u1LenMSB; + uint32_t u4NvramStartOffset = 0, u4NvramOffset = 0; + uint8_t *pu1Addr; + struct WIFI_NVRAM_TAG_FORMAT *prTagDataCurr; + int retryCount = 0; + + while (g_NvramFsm != NVRAM_STATE_READY) { + kalMsleep(100); + retryCount++; + + if (retryCount > MAX_NVRAM_READY_COUNT) { + DBGLOG(INIT, WARN, "g_NvramFsm != NVRAM_STATE_READY\n"); + return; + } + } + + /* Get NVRAM Start Addr */ + pu1Addr = (uint8_t *)(struct WIFI_CFG_PARAM_STRUCT *)&g_aucNvram[0]; + + /* Shift to NVRAM Tag */ + u4NvramOffset = OFFSET_OF(struct WIFI_CFG_PARAM_STRUCT, ucTypeID0); + prTagDataCurr = + (struct WIFI_NVRAM_TAG_FORMAT *)(pu1Addr + + u4NvramOffset); + + /* Shift to NVRAM Tag 7 - 9, r2G4Cmm, r5GCmm , rSys*/ + for (index = 0; index <= 10; index++) { + u1TypeID = prTagDataCurr->u1NvramTypeID; + u1LenLSB = prTagDataCurr->u1NvramTypeLenLsb; + u1LenMSB = prTagDataCurr->u1NvramTypeLenMsb; + + /*sanity check*/ + if ((u1TypeID == 0) && + (u1LenLSB == 0) && (u1LenMSB == 0)) { + DBGLOG(INIT, WARN, "TVL is Null\n"); + break; + } + + /*check Type ID is exist on NVRAM*/ + if (u1TypeID == 7) { + u4NvramStartOffset = u4NvramOffset; + DBGLOG(INIT, TRACE, + "NVRAM tag(%d) exist! current idx:%d, ofst %x\n", + u1TypeID, index, u4NvramStartOffset); + } + + if (u1TypeID == 10) + break; + + u4NvramOffset += sizeof(struct WIFI_NVRAM_TAG_FORMAT); + u4NvramOffset += (u1LenMSB << 8) | (u1LenLSB); + + /*get the nex TLV format*/ + prTagDataCurr = (struct WIFI_NVRAM_TAG_FORMAT *) + (pu1Addr + u4NvramOffset); + + + DBGLOG(INIT, TRACE, + "(%d)CurOfs[0x%08X]:Next(%d)Len:%d\n", + index, + u4NvramOffset, + u1TypeID, + (u1LenMSB << 8) | (u1LenLSB)); + + } + + *pu1DataPointer = pu1Addr + u4NvramStartOffset; + *pu4DataLen = u4NvramOffset - u4NvramStartOffset; + + DBGLOG_MEM8(INIT, TRACE, *pu1DataPointer, *pu4DataLen); + DBGLOG(INIT, TRACE, + "NVRAM datapointer %x tag7 ofst %x tag7-9 Len %x\n", + *pu1DataPointer, u4NvramStartOffset, *pu4DataLen); + +} + +uint32_t soc3_0_wlanSendPhyAction(struct ADAPTER *prAdapter, + uint16_t u2Tag, + uint8_t ucCalCmd) +{ + struct CMD_INFO *prCmdInfo; + uint8_t ucTC, ucCmdSeqNum; + uint32_t u4CmdSize; + uint32_t u4Status = WLAN_STATUS_SUCCESS; + struct mt66xx_chip_info *prChipInfo; + struct HAL_PHY_ACTION_TLV_HEADER *prPhyTlvHeader; + struct HAL_PHY_ACTION_TLV *prPhyTlv; + struct INIT_CMD_PHY_ACTION_CAL *prPhyCal; + + uint8_t *u1EpaELnaDataPointer = NULL; + uint32_t u4EpaELnaDataSize = 0; + + uint32_t u4Cr = 0; + uint32_t u4Value = 0; + + DBGLOG(INIT, INFO, "SendPhyAction begin\n"); + + ASSERT(prAdapter); + prChipInfo = prAdapter->chip_info; + + soc3_0_wlanGetEpaElnaFromNvram(&u1EpaELnaDataPointer, + &u4EpaELnaDataSize); + + if (u1EpaELnaDataPointer == NULL) { + DBGLOG(INIT, ERROR, "Get u1EpaELnaDataPointer failed\n"); + return WLAN_STATUS_FAILURE; + } + + /* 1. Allocate CMD Info Packet and its Buffer. */ + if (u2Tag == HAL_PHY_ACTION_TAG_FEM) { + u4CmdSize = sizeof(struct HAL_PHY_ACTION_TLV_HEADER) + + sizeof(struct HAL_PHY_ACTION_TLV) + + u4EpaELnaDataSize; + } else { + u4CmdSize = sizeof(struct HAL_PHY_ACTION_TLV_HEADER) + + sizeof(struct HAL_PHY_ACTION_TLV) + + sizeof(struct INIT_CMD_PHY_ACTION_CAL); + } + + if (ucCalCmd == HAL_PHY_ACTION_CAL_FORCE_CAL_REQ) { + u4CmdSize += sizeof(struct HAL_PHY_ACTION_TLV); + u4CmdSize += u4EpaELnaDataSize; + } + + prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, + sizeof(struct INIT_HIF_TX_HEADER) + + sizeof(struct INIT_HIF_TX_HEADER_PENDING_FOR_HW_32BYTES) + + u4CmdSize); + + if (!prCmdInfo) { + DBGLOG(INIT, ERROR, "cmdBufAllocateCmdInfo failed\n"); + return WLAN_STATUS_FAILURE; + } + + prCmdInfo->u2InfoBufLen = sizeof(struct INIT_HIF_TX_HEADER) + + sizeof(struct INIT_HIF_TX_HEADER_PENDING_FOR_HW_32BYTES) + + u4CmdSize; + +#if (CFG_USE_TC4_RESOURCE_FOR_INIT_CMD == 1) + /* 2. Always use TC4 (TC4 as CPU) */ + ucTC = TC4_INDEX; +#else + /* 2. Use TC0's resource to send patch finish command. + * Only TC0 is allowed because SDIO HW always reports + * MCU's TXQ_CNT at TXQ0_CNT in CR4 architecutre) + */ + ucTC = TC0_INDEX; +#endif + + NIC_FILL_CMD_TX_HDR(prAdapter, + prCmdInfo->pucInfoBuffer, + prCmdInfo->u2InfoBufLen, + INIT_CMD_ID_PHY_ACTION, + INIT_CMD_PACKET_TYPE_ID, + &ucCmdSeqNum, + FALSE, + (void **)&prPhyTlvHeader, + TRUE, 0, S2D_INDEX_CMD_H2N); + + /*process TLV Header Part1 */ + prPhyTlvHeader->u4MagicNum = HAL_PHY_ACTION_MAGIC_NUM; + prPhyTlvHeader->ucVersion = HAL_PHY_ACTION_VERSION; + + if (u2Tag == HAL_PHY_ACTION_TAG_FEM) { + /*process TLV Header Part2 */ + prPhyTlvHeader->ucTagNums = 1; + prPhyTlvHeader->u2BufLength = + sizeof(struct HAL_PHY_ACTION_TLV) + + u4EpaELnaDataSize; + + /*process TLV Content*/ + prPhyTlv = + (struct HAL_PHY_ACTION_TLV *)prPhyTlvHeader->aucBuffer; + prPhyTlv->u2Tag = u2Tag; + prPhyTlv->u2BufLength = u4EpaELnaDataSize; + kalMemCopy(prPhyTlv->aucBuffer, + u1EpaELnaDataPointer, u4EpaELnaDataSize); + + } else if (ucCalCmd == HAL_PHY_ACTION_CAL_FORCE_CAL_REQ) { + /*process TLV Header Part2 */ + prPhyTlvHeader->ucTagNums = 2; /* Add HAL_PHY_ACTION_TAG_FEM */ + prPhyTlvHeader->u2BufLength = + sizeof(struct HAL_PHY_ACTION_TLV) + + u4EpaELnaDataSize + sizeof(struct HAL_PHY_ACTION_TLV) + + sizeof(struct INIT_CMD_PHY_ACTION_CAL); + + /*process TLV Content*/ + /*TAG HAL_PHY_ACTION_TAG_CAL*/ + prPhyTlv = + (struct HAL_PHY_ACTION_TLV *)prPhyTlvHeader->aucBuffer; + prPhyTlv->u2Tag = HAL_PHY_ACTION_TAG_CAL; + prPhyTlv->u2BufLength = sizeof(struct INIT_CMD_PHY_ACTION_CAL); + prPhyCal = + (struct INIT_CMD_PHY_ACTION_CAL *)prPhyTlv->aucBuffer; + prPhyCal->ucCmd = ucCalCmd; + + /*TAG HAL_PHY_ACTION_TAG_FEM*/ + prPhyTlv = + (struct HAL_PHY_ACTION_TLV *) + (prPhyTlvHeader->aucBuffer + + sizeof(struct HAL_PHY_ACTION_TLV) + + sizeof(struct INIT_CMD_PHY_ACTION_CAL)); + prPhyTlv->u2Tag = HAL_PHY_ACTION_TAG_FEM; + prPhyTlv->u2BufLength = u4EpaELnaDataSize; + kalMemCopy(prPhyTlv->aucBuffer, + u1EpaELnaDataPointer, u4EpaELnaDataSize); + + } else { + /*process TLV Header Part2 */ + prPhyTlvHeader->ucTagNums = 1; + prPhyTlvHeader->u2BufLength = + sizeof(struct HAL_PHY_ACTION_TLV) + + sizeof(struct INIT_CMD_PHY_ACTION_CAL); + + /*process TLV Content*/ + prPhyTlv = + (struct HAL_PHY_ACTION_TLV *)prPhyTlvHeader->aucBuffer; + prPhyTlv->u2Tag = u2Tag; + prPhyTlv->u2BufLength = sizeof(struct INIT_CMD_PHY_ACTION_CAL); + prPhyCal = + (struct INIT_CMD_PHY_ACTION_CAL *)prPhyTlv->aucBuffer; + prPhyCal->ucCmd = ucCalCmd; + } + + DBGLOG_MEM8(INIT, TRACE, prPhyTlvHeader, u4CmdSize); + + /* 5. Seend WIFI start command */ + while (1) { + + /* 5.1 Acquire TX Resource */ + if (nicTxAcquireResource(prAdapter, ucTC, + nicTxGetPageCount(prAdapter, + prCmdInfo->u2InfoBufLen, TRUE), + TRUE) == WLAN_STATUS_RESOURCES) { + if (nicTxPollingResource(prAdapter, + ucTC) != WLAN_STATUS_SUCCESS) { + u4Status = WLAN_STATUS_FAILURE; + DBGLOG(INIT, ERROR, + "nicTxPollingResource failed\n"); + goto exit; + } + continue; + } + + /* 5.2 Send CMD Info Packet */ + if (nicTxInitCmd(prAdapter, prCmdInfo, + prChipInfo->u2TxInitCmdPort) != + WLAN_STATUS_SUCCESS) { + u4Status = WLAN_STATUS_FAILURE; + DBGLOG(INIT, ERROR, + "nicTxInitCmd failed\n"); + goto exit; + } + + break; + }; + + u4Status = soc3_0_wlanRcvPhyActionRsp(prAdapter, ucCmdSeqNum); + + /* Debug FW Own */ + u4Cr = 0x180600f0; + soc3_0_CrRead(prAdapter, u4Cr, &u4Value); + + if (u4Status != WLAN_STATUS_SUCCESS) + DBGLOG(INIT, WARN, + "SendPhyAction failed: 0x%08x = 0x%08x\n", + u4Cr, u4Value); + else + DBGLOG(INIT, INFO, + "SendPhyAction success: 0x%08x = 0x%08x\n", + u4Cr, u4Value); + +exit: + /* 6. Free CMD Info Packet. */ + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + + return u4Status; +} + +uint32_t soc3_0_wlanPhyAction(IN struct ADAPTER *prAdapter) +{ + uint32_t u4Status = WLAN_STATUS_SUCCESS; + + /* Setup calibration data from backup file */ + if (soc3_0_wlanAccessCalibrationEMI(NULL, FALSE) == + WLAN_STATUS_SUCCESS) + u4Status = soc3_0_wlanSendPhyAction(prAdapter, + HAL_PHY_ACTION_TAG_CAL, + HAL_PHY_ACTION_CAL_USE_BACKUP_REQ); + else + u4Status = soc3_0_wlanSendPhyAction(prAdapter, + HAL_PHY_ACTION_TAG_CAL, + HAL_PHY_ACTION_CAL_FORCE_CAL_REQ); + + return u4Status; +} + +int soc3_0_wlanPreCalPwrOn(void) +{ +#define MAX_PRE_ON_COUNT 5 + + int retryCount = 0; + uint32_t u4Value = 0; + void *pvData = NULL; + void *pvDriverData = NULL; + + enum ENUM_POWER_ON_INIT_FAIL_REASON { + NET_CREATE_FAIL, + BUS_SET_IRQ_FAIL, + ALLOC_ADAPTER_MEM_FAIL, + DRIVER_OWN_FAIL, + INIT_ADAPTER_FAIL, + INIT_HIFINFO_FAIL, + ROM_PATCH_DOWNLOAD_FAIL, + POWER_ON_INIT_DONE + } eFailReason; + uint32_t i = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + struct mt66xx_chip_info *prChipInfo; + + if (get_wifi_process_status() || + get_wifi_powered_status()) + return CONNINFRA_CB_RET_CAL_FAIL_POWER_OFF; + + update_pre_cal_status(1); + + while (g_u4WlanInitFlag == 0) { + DBGLOG(INIT, WARN, + "g_u4WlanInitFlag(%d) retryCount(%d)", + g_u4WlanInitFlag, + retryCount); + + kalMsleep(100); + retryCount++; + + if (retryCount > MAX_PRE_ON_COUNT) { + update_pre_cal_status(0); + return CONNINFRA_CB_RET_CAL_FAIL_POWER_OFF; + } + } + + /* wf driver power on */ + if (wf_pwr_on_consys_mcu() != 0) { + update_pre_cal_status(0); + return CONNINFRA_CB_RET_CAL_FAIL_POWER_OFF; + } + + /* Download patch and send PHY action */ + do { + retryCount = 0; + while (g_prPlatDev == NULL) { + DBGLOG(INIT, WARN, + "g_prPlatDev(0x%x) retryCount(%d)", + g_prPlatDev, + retryCount); + + kalMsleep(100); + retryCount++; + + if (retryCount > MAX_PRE_ON_COUNT) { + update_pre_cal_status(0); + return CONNINFRA_CB_RET_CAL_FAIL_POWER_OFF; + } + } + + pvDriverData = (void *)&mt66xx_driver_data_soc3_0; + prChipInfo = ((struct mt66xx_hif_driver_data *) + pvDriverData)->chip_info; + pvData = (void *)prChipInfo->pdev; + +#if (CFG_SUPPORT_TRACE_TC4 == 1) + wlanDebugTC4Init(); +#endif + + /* Create network device, Adapter, KalInfo, + * prDevHandler(netdev) + */ + grWdev = wlanNetCreate(pvData, pvDriverData); + + if (grWdev == NULL) { + DBGLOG(INIT, ERROR, "wlanNetCreate Error\n"); + eFailReason = NET_CREATE_FAIL; + break; + } + + /* Set the ioaddr to HIF Info */ + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(grWdev->wiphy); + + /* Should we need this??? to be conti... */ + gPrDev = prGlueInfo->prDevHandler; + + /* Setup IRQ */ + if (glBusSetIrq(grWdev->netdev, NULL, prGlueInfo) + != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, ERROR, "glBusSetIrq error\n"); + eFailReason = BUS_SET_IRQ_FAIL; + break; + } + + prGlueInfo->i4DevIdx = 0; + prAdapter = prGlueInfo->prAdapter; + prChipInfo = prAdapter->chip_info; + + if (prChipInfo->asicCapInit != NULL) + prChipInfo->asicCapInit(prAdapter); + + nicpmWakeUpWiFi(prAdapter); + + prAdapter->u4OwnFailedCount = 0; + prAdapter->u4OwnFailedLogCount = 0; + + /* Additional with chip reset optimize*/ + prAdapter->ucCmdSeqNum = 0; + + QUEUE_INITIALIZE(&(prAdapter->rPendingCmdQueue)); +#if CFG_SUPPORT_MULTITHREAD + QUEUE_INITIALIZE(&prAdapter->rTxCmdQueue); + QUEUE_INITIALIZE(&prAdapter->rTxCmdDoneQueue); +#if CFG_FIX_2_TX_PORT + QUEUE_INITIALIZE(&prAdapter->rTxP0Queue); + QUEUE_INITIALIZE(&prAdapter->rTxP1Queue); +#else + for (i = 0; i < TX_PORT_NUM; i++) + QUEUE_INITIALIZE(&prAdapter->rTxPQueue[i]); +#endif + QUEUE_INITIALIZE(&prAdapter->rRxQueue); + QUEUE_INITIALIZE(&prAdapter->rTxDataDoneQueue); +#endif + + /* reset fgIsBusAccessFailed */ + fgIsBusAccessFailed = FALSE; + + /* Allocate mandatory resource for TX/RX */ + if (nicAllocateAdapterMemory(prAdapter) != + WLAN_STATUS_SUCCESS) { + + DBGLOG(INIT, ERROR, + "nicAllocateAdapterMemory Error!\n"); + eFailReason = ALLOC_ADAPTER_MEM_FAIL; + break; + } + + /* should we need this? to be conti... */ + prAdapter->u4OsPacketFilter = PARAM_PACKET_FILTER_SUPPORTED; + + /* Initialize the Adapter: + * verify chipset ID, HIF init... + * the code snippet just do the copy thing + */ + if (nicInitializeAdapter(prAdapter) != WLAN_STATUS_SUCCESS) { + + DBGLOG(INIT, ERROR, + "nicInitializeAdapter failed!\n"); + eFailReason = INIT_ADAPTER_FAIL; + break; + } + + nicInitSystemService(prAdapter, FALSE); + + /* Initialize Tx */ + nicTxInitialize(prAdapter); + + /* Initialize Rx */ + nicRxInitialize(prAdapter); + + /* HIF SW info initialize */ + if (!halHifSwInfoInit(prAdapter)) { + + DBGLOG(INIT, ERROR, + "halHifSwInfoInit failed!\n"); + eFailReason = INIT_HIFINFO_FAIL; + break; + } + + /* Enable HIF cut-through to N9 mode */ + HAL_ENABLE_FWDL(prAdapter, TRUE); + + /* Disable interrupt, download is done by polling mode only */ + nicDisableInterrupt(prAdapter); + + /* Initialize Tx Resource to fw download state */ + nicTxInitResetResource(prAdapter); + + if (prChipInfo->pwrondownload) { + if (prChipInfo->pwrondownload(prAdapter, + ENUM_WLAN_POWER_ON_DOWNLOAD_ROM_PATCH) + != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, ERROR, + "pwrondownload failed!\n"); + eFailReason = ROM_PATCH_DOWNLOAD_FAIL; + break; + } + } + + soc3_0_wlanSendPhyAction(prAdapter, + HAL_PHY_ACTION_TAG_FEM, + 0); + + eFailReason = POWER_ON_INIT_DONE; + } while (FALSE); + + switch (eFailReason) { + case NET_CREATE_FAIL: +#if (CFG_SUPPORT_TRACE_TC4 == 1) + wlanDebugTC4Uninit(); /* Uninit for TC4 debug */ +#endif + break; + + case BUS_SET_IRQ_FAIL: +#if (CFG_SUPPORT_TRACE_TC4 == 1) + wlanDebugTC4Uninit(); /* Uninit for TC4 debug */ +#endif + wlanWakeLockUninit(prGlueInfo); + wlanNetDestroy(grWdev); + break; + + case ALLOC_ADAPTER_MEM_FAIL: + case DRIVER_OWN_FAIL: + case INIT_ADAPTER_FAIL: + glBusFreeIrq(grWdev->netdev, + *((struct GLUE_INFO **) netdev_priv(grWdev->netdev))); + +#if (CFG_SUPPORT_TRACE_TC4 == 1) + wlanDebugTC4Uninit(); /* Uninit for TC4 debug */ +#endif + + wlanWakeLockUninit(prGlueInfo); + + if (eFailReason != ALLOC_ADAPTER_MEM_FAIL) + nicReleaseAdapterMemory(prAdapter); + + wlanNetDestroy(grWdev); + break; + + case INIT_HIFINFO_FAIL: + nicRxUninitialize(prAdapter); + nicTxRelease(prAdapter, FALSE); + + /* System Service Uninitialization */ + nicUninitSystemService(prAdapter); + + glBusFreeIrq(grWdev->netdev, + *((struct GLUE_INFO **)netdev_priv(grWdev->netdev))); + +#if (CFG_SUPPORT_TRACE_TC4 == 1) + wlanDebugTC4Uninit(); /* Uninit for TC4 debug */ +#endif + + wlanWakeLockUninit(prGlueInfo); + nicReleaseAdapterMemory(prAdapter); + wlanNetDestroy(grWdev); + break; + + case ROM_PATCH_DOWNLOAD_FAIL: + HAL_ENABLE_FWDL(prAdapter, FALSE); + halHifSwInfoUnInit(prGlueInfo); + nicRxUninitialize(prAdapter); + nicTxRelease(prAdapter, FALSE); + + /* System Service Uninitialization */ + nicUninitSystemService(prAdapter); + + glBusFreeIrq(grWdev->netdev, + *((struct GLUE_INFO **)netdev_priv(grWdev->netdev))); + +#if (CFG_SUPPORT_TRACE_TC4 == 1) + wlanDebugTC4Uninit(); /* Uninit for TC4 debug */ +#endif + + wlanWakeLockUninit(prGlueInfo); + nicReleaseAdapterMemory(prAdapter); + wlanNetDestroy(grWdev); + break; + + case POWER_ON_INIT_DONE: + /* pre-cal release resouce */ + break; + } + + DBGLOG(INIT, INFO, + "soc3_0_wlanPreCalPwrOn end(%d)\n", + eFailReason); + + if (eFailReason != POWER_ON_INIT_DONE) { + + /* set FW own after power on consys mcu to + * keep Driver/FW/HW state sync + */ + wf_ioremap_read(CONN_HOST_CSR_TOP_BASE_ADDR + 0x0010, + &u4Value); + + if ((u4Value & BIT(2)) != BIT(2)) { + DBGLOG(INIT, INFO, "0x%08x = 0x%08x, Set FW Own\n", + CONN_HOST_CSR_TOP_BASE_ADDR + 0x0010, + u4Value); + + wf_ioremap_write(CONN_HOST_CSR_TOP_BASE_ADDR + 0x0010, + PCIE_LPCR_HOST_SET_OWN); + } + + update_pre_cal_status(0); + return CONNINFRA_CB_RET_CAL_FAIL_POWER_OFF; + } + + return CONNINFRA_CB_RET_CAL_PASS_POWER_OFF; +} + +int soc3_0_wlanPreCal(void) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + uint32_t u4Value = 0; + + if (get_pre_cal_status() == 0) + return CONNINFRA_CB_RET_CAL_FAIL_POWER_OFF; + + if (g_u4WlanInitFlag == 0) { + DBGLOG(INIT, WARN, + "g_u4WlanInitFlag(%d)", + g_u4WlanInitFlag); + + update_pre_cal_status(0); + return CONNINFRA_CB_RET_CAL_FAIL_POWER_OFF; + } + + DBGLOG(INIT, INFO, "PreCal begin\n"); + + /* Set the ioaddr to HIF Info */ + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(grWdev->wiphy); + prAdapter = prGlueInfo->prAdapter; + nicpmWakeUpWiFi(prAdapter); + + /* Disable interrupt, download is done by polling mode only */ + nicDisableInterrupt(prAdapter); + + soc3_0_wlanSendPhyAction(prAdapter, + HAL_PHY_ACTION_TAG_CAL, + HAL_PHY_ACTION_CAL_FORCE_CAL_REQ); + + HAL_ENABLE_FWDL(prAdapter, FALSE); + halHifSwInfoUnInit(prGlueInfo); + nicRxUninitialize(prAdapter); + nicTxRelease(prAdapter, FALSE); + + /* System Service Uninitialization */ + nicUninitSystemService(prAdapter); + + glBusFreeIrq(grWdev->netdev, + *((struct GLUE_INFO **)netdev_priv(grWdev->netdev))); + +#if (CFG_SUPPORT_TRACE_TC4 == 1) + wlanDebugTC4Uninit(); /* Uninit for TC4 debug */ +#endif + + wlanWakeLockUninit(prGlueInfo); + nicReleaseAdapterMemory(prAdapter); + wlanNetDestroy(grWdev); + + /* set FW own after power on consys mcu to + * keep Driver/FW/HW state sync + */ + wf_ioremap_read(CONN_HOST_CSR_TOP_BASE_ADDR + 0x0010, + &u4Value); + + if ((u4Value & BIT(2)) != BIT(2)) { + DBGLOG(INIT, INFO, "0x%08x = 0x%08x, Set FW Own\n", + CONN_HOST_CSR_TOP_BASE_ADDR + 0x0010, + u4Value); + + wf_ioremap_write(CONN_HOST_CSR_TOP_BASE_ADDR + 0x0010, + PCIE_LPCR_HOST_SET_OWN); + } + + wf_pwr_off_consys_mcu(); + + DBGLOG(INIT, INFO, "PreCal end\n"); + + update_pre_cal_status(0); + + return CONNINFRA_CB_RET_CAL_PASS_POWER_OFF; +} + +uint8_t *soc3_0_wlanGetCalResult(uint32_t *prCalSize) +{ + *prCalSize = gEmiCalSize; + + return gEmiCalResult; +} + +void soc3_0_wlanCalDebugCmd(uint32_t cmd, uint32_t para) +{ + switch (cmd) { + case 0: + if (gEmiCalResult != NULL) { + kalMemFree(gEmiCalResult, + VIR_MEM_TYPE, + gEmiCalSize); + gEmiCalResult = NULL; + } + break; + + case 1: + if (para == 1) + gEmiCalUseEmiData = TRUE; + else + gEmiCalUseEmiData = FALSE; + break; + } + + DBGLOG(RFTEST, INFO, "gEmiCalResult(0x%x), gEmiCalUseEmiData(%d)\n", + gEmiCalResult, gEmiCalUseEmiData); +} + +#endif /* (CFG_SUPPORT_PRE_ON_PHY_ACTION == 1) */ + +#endif /* soc3_0 */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/common/debug.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/common/debug.c new file mode 100644 index 0000000000000000000000000000000000000000..d69e4bcfd34b0c7798346d87d50b261ca42b35f8 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/common/debug.c @@ -0,0 +1,916 @@ +#include "precomp.h" + + +#if (CFG_SUPPORT_STATISTICS == 1) + +#define WAKE_MAX_CMD_EVENT_NUM 20 +#define WAKE_STR_BUFFER_LEN (60 + 20 * WAKE_MAX_CMD_EVENT_NUM) + +struct WAKE_CMD_T { + uint8_t ucCmdId; + uint8_t ucFlagIsUesd; + uint16_t u2Cnt; +}; + +struct WAKE_EVENT_T { + uint8_t ucEventId; + uint8_t ucFlagIsUesd; + uint16_t u2Cnt; +}; + +struct WAKE_INFO_T { + struct WAKE_CMD_T arCmd[WAKE_MAX_CMD_EVENT_NUM]; + uint8_t ucCmdCnt; + uint32_t u4TotalCmd; + + struct WAKE_EVENT_T arEvent[WAKE_MAX_CMD_EVENT_NUM]; + uint8_t ucEventCnt; + uint32_t u4TotalEvent; + + uint32_t au4TxDataCnt[WLAN_WAKE_MAX_NUM]; + uint32_t u4TxCnt; + uint32_t au4RxDataCnt[WLAN_WAKE_MAX_NUM]; + uint32_t u4RxCnt; +}; + +static struct WAKE_INFO_T *gprWakeInfoStatics; +static uint8_t aucStr[WAKE_STR_BUFFER_LEN]; +#endif + +#if (CFG_SUPPORT_TRACE_TC4 == 1) +struct COMMAND { + uint8_t ucCID; + u_int8_t fgSetQuery; + u_int8_t fgNeedResp; + uint8_t ucCmdSeqNum; +}; + +struct SECURITY_FRAME { + uint16_t u2EthType; + uint16_t u2Reserved; +}; + +struct MGMT_FRAME { + uint16_t u2FrameCtl; + uint16_t u2DurationID; +}; + +struct TC_RES_RELEASE_ENTRY { + uint64_t u8RelaseTime; + uint32_t u4RelCID; + uint32_t u4Tc4RelCnt; + uint32_t u4AvailableTc4; +}; + +struct CMD_TRACE_ENTRY { + uint64_t u8TxTime; + enum COMMAND_TYPE eCmdType; + union { + struct COMMAND rCmd; + struct SECURITY_FRAME rSecFrame; + struct MGMT_FRAME rMgmtFrame; + } u; +}; + +#define TC_RELEASE_TRACE_BUF_MAX_NUM 100 +#define TXED_CMD_TRACE_BUF_MAX_NUM 100 + +static struct TC_RES_RELEASE_ENTRY *gprTcReleaseTraceBuffer; +static struct CMD_TRACE_ENTRY *gprCmdTraceEntry; +void wlanDebugTC4Init(void) +{ + /* debug for command/tc4 resource begin */ + gprTcReleaseTraceBuffer = + kalMemAlloc(TC_RELEASE_TRACE_BUF_MAX_NUM * sizeof( + struct TC_RES_RELEASE_ENTRY), PHY_MEM_TYPE); + kalMemZero(gprTcReleaseTraceBuffer, + TC_RELEASE_TRACE_BUF_MAX_NUM * sizeof(struct + TC_RES_RELEASE_ENTRY)); + gprCmdTraceEntry = kalMemAlloc(TXED_CMD_TRACE_BUF_MAX_NUM * + sizeof(struct CMD_TRACE_ENTRY), + PHY_MEM_TYPE); + kalMemZero(gprCmdTraceEntry, + TXED_CMD_TRACE_BUF_MAX_NUM * sizeof(struct + CMD_TRACE_ENTRY)); + /* debug for command/tc4 resource end */ +} + +void wlanDebugTC4Uninit(void) +{ + /* debug for command/tc4 resource begin */ + kalMemFree(gprTcReleaseTraceBuffer, PHY_MEM_TYPE, + TC_RELEASE_TRACE_BUF_MAX_NUM * sizeof(struct + TC_RES_RELEASE_ENTRY)); + kalMemFree(gprCmdTraceEntry, PHY_MEM_TYPE, + TXED_CMD_TRACE_BUF_MAX_NUM * sizeof(struct + CMD_TRACE_ENTRY)); + /* debug for command/tc4 resource end */ +} + +void wlanTraceTxCmd(struct CMD_INFO *prCmd) +{ + static uint16_t u2CurEntry; + struct CMD_TRACE_ENTRY *prCurCmd = + &gprCmdTraceEntry[u2CurEntry]; + + prCurCmd->u8TxTime = sched_clock(); + prCurCmd->eCmdType = prCmd->eCmdType; + if (prCmd->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME) { + struct WLAN_MAC_MGMT_HEADER *prMgmt = (struct + WLAN_MAC_MGMT_HEADER *)prCmd->prMsduInfo->prPacket; + + prCurCmd->u.rMgmtFrame.u2FrameCtl = prMgmt->u2FrameCtrl; + prCurCmd->u.rMgmtFrame.u2DurationID = prMgmt->u2Duration; + } else if (prCmd->eCmdType == COMMAND_TYPE_SECURITY_FRAME || + prCmd->eCmdType == COMMAND_TYPE_DATA_FRAME) { + uint8_t *pucPkt = (uint8_t *)((struct sk_buff *) + prCmd->prPacket)->data; + + prCurCmd->u.rSecFrame.u2EthType = + (pucPkt[ETH_TYPE_LEN_OFFSET] << 8) | + (pucPkt[ETH_TYPE_LEN_OFFSET + 1]); + } else { + prCurCmd->u.rCmd.ucCID = prCmd->ucCID; + prCurCmd->u.rCmd.ucCmdSeqNum = prCmd->ucCmdSeqNum; + prCurCmd->u.rCmd.fgNeedResp = prCmd->fgNeedResp; + prCurCmd->u.rCmd.fgSetQuery = prCmd->fgSetQuery; + } + u2CurEntry++; + if (u2CurEntry == TC_RELEASE_TRACE_BUF_MAX_NUM) + u2CurEntry = 0; +} + +void wlanTraceReleaseTcRes(struct ADAPTER *prAdapter, + uint32_t u4TxRlsCnt, uint32_t u4Available) +{ + static uint16_t u2CurEntry; + struct TC_RES_RELEASE_ENTRY *prCurBuf = + &gprTcReleaseTraceBuffer[u2CurEntry]; + + prCurBuf->u8RelaseTime = sched_clock(); + prCurBuf->u4Tc4RelCnt = u4TxRlsCnt; + prCurBuf->u4AvailableTc4 = u4Available; + u2CurEntry++; + if (u2CurEntry == TXED_CMD_TRACE_BUF_MAX_NUM) + u2CurEntry = 0; +} + +void wlanDumpTcResAndTxedCmd(uint8_t *pucBuf, + uint32_t maxLen) +{ + uint16_t i = 0; + struct TC_RES_RELEASE_ENTRY *prTcRel = + gprTcReleaseTraceBuffer; + struct CMD_TRACE_ENTRY *prCmd = gprCmdTraceEntry; + + if (pucBuf) { + int bufLen = 0; + + for (; i < TXED_CMD_TRACE_BUF_MAX_NUM / 2; i++) { + bufLen = snprintf(pucBuf, maxLen, + "%d: Time %llu, Type %d, Content %08x; %d: Time %llu, Type %d, Content %08x\n", + i * 2, prCmd[i * 2].u8TxTime, + prCmd[i * 2].eCmdType, + *(uint32_t *) + (&prCmd[i * 2].u.rCmd.ucCID), + i * 2 + 1, + prCmd[i * 2 + 1].u8TxTime, + prCmd[i * 2 + 1].eCmdType, + *(uint32_t *) + (&prCmd[i * 2 + 1].u.rCmd.ucCID)); + if (bufLen <= 0) + break; + pucBuf += bufLen; + maxLen -= bufLen; + } + for (i = 0; i < TC_RELEASE_TRACE_BUF_MAX_NUM / 2; i++) { + bufLen = snprintf(pucBuf, maxLen, + "%d: Time %llu, Tc4Cnt %d, Free %d, CID %08x; %d: Time %llu, Tc4Cnt %d, Free %d CID %08x\n", + i * 2, prTcRel[i * 2].u8RelaseTime, + prTcRel[i * 2].u4Tc4RelCnt, + prTcRel[i * 2].u4AvailableTc4, + prTcRel[i * 2].u4RelCID, + i * 2 + 1, + prTcRel[i * 2 + 1].u8RelaseTime, + prTcRel[i * 2 + 1].u4Tc4RelCnt, + prTcRel[i * 2 + 1].u4AvailableTc4, + prTcRel[i * 2 + 1].u4RelCID); + if (bufLen <= 0) + break; + pucBuf += bufLen; + maxLen -= bufLen; + } + } else { + for (; i < TXED_CMD_TRACE_BUF_MAX_NUM / 4; i++) { + LOG_FUNC( + "%d: Time %llu, Type %d, Content %08x; %d: Time %llu, Type %d, Content %08x; ", + i * 4, prCmd[i * 4].u8TxTime, + prCmd[i * 4].eCmdType, + *(uint32_t *)(&prCmd[i * 4].u.rCmd.ucCID), + i * 4 + 1, prCmd[i * 4 + 1].u8TxTime, + prCmd[i * 4 + 1].eCmdType, + *(uint32_t *)(&prCmd[i * 4 + 1].u.rCmd.ucCID)); + LOG_FUNC( + "%d: Time %llu, Type %d, Content %08x; %d: Time %llu, Type %d, Content %08x\n", + i * 4 + 2, prCmd[i * 4 + 2].u8TxTime, + prCmd[i * 4 + 2].eCmdType, + *(uint32_t *)(&prCmd[i * 4 + 2].u.rCmd.ucCID), + i * 4 + 3, prCmd[i * 4 + 3].u8TxTime, + prCmd[i * 4 + 3].eCmdType, + *(uint32_t *)(&prCmd[i * 4 + 3].u.rCmd.ucCID)); + } + for (i = 0; i < TC_RELEASE_TRACE_BUF_MAX_NUM / 4; i++) { + LOG_FUNC( + "%d: Time %llu, Tc4Cnt %d, Free %d, CID %08x; %d: Time %llu, Tc4Cnt %d, Free %d, CID %08x;", + i * 4, prTcRel[i * 4].u8RelaseTime, + prTcRel[i * 4].u4Tc4RelCnt, + prTcRel[i * 4].u4AvailableTc4, + prTcRel[i * 4].u4RelCID, + i * 4 + 1, prTcRel[i * 4 + 1].u8RelaseTime, + prTcRel[i * 4 + 1].u4Tc4RelCnt, + prTcRel[i * 4 + 1].u4AvailableTc4, + prTcRel[i * 4 + 1].u4RelCID); + LOG_FUNC( + "%d: Time %llu, Tc4Cnt %d, Free %d, CID %08x; %d: Time %llu, Tc4Cnt %d, Free %d, CID %08x\n", + i * 4 + 2, prTcRel[i * 4 + 2].u8RelaseTime, + prTcRel[i * 4 + 2].u4Tc4RelCnt, + prTcRel[i * 4 + 2].u4AvailableTc4, + prTcRel[i * 4 + 2].u4RelCID, + i * 4 + 3, prTcRel[i * 4 + 3].u8RelaseTime, + prTcRel[i * 4 + 3].u4Tc4RelCnt, + prTcRel[i * 4 + 3].u4AvailableTc4, + prTcRel[i * 4 + 3].u4RelCID); + } + } +} +#endif + + +#if (CFG_SUPPORT_STATISTICS == 1) + +void wlanWakeStaticsInit(void) +{ + gprWakeInfoStatics = + kalMemAlloc(WAKE_MAX_CMD_EVENT_NUM * sizeof( + struct WAKE_INFO_T), PHY_MEM_TYPE); + if (gprWakeInfoStatics != NULL) + kalMemZero(gprWakeInfoStatics, + WAKE_MAX_CMD_EVENT_NUM * sizeof(struct + WAKE_INFO_T)); +} + +void wlanWakeStaticsUninit(void) +{ + if (gprWakeInfoStatics != NULL) + kalMemFree(gprWakeInfoStatics, PHY_MEM_TYPE, + WAKE_MAX_CMD_EVENT_NUM * sizeof(struct WAKE_INFO_T)); +} + +uint32_t wlanWakeLogCmd(uint8_t ucCmdId) +{ + int i = 0; + int j = 0; + + if ((gprWakeInfoStatics == NULL) || (wlan_fb_power_down != TRUE)) + return 1; + + for (i = 0; i < WAKE_MAX_CMD_EVENT_NUM; i++) { + if ((gprWakeInfoStatics->arCmd[i].ucFlagIsUesd == TRUE) + && (gprWakeInfoStatics->arCmd[i].ucCmdId == ucCmdId)) { + /*old item ++*/ + gprWakeInfoStatics->arCmd[i].u2Cnt++; + gprWakeInfoStatics->u4TotalCmd++; + break; + } + } + + if (i >= WAKE_MAX_CMD_EVENT_NUM) { + /*add new item*/ + for (j = 0; j < WAKE_MAX_CMD_EVENT_NUM; j++) { + if (gprWakeInfoStatics->arCmd[j].ucFlagIsUesd != TRUE) { + gprWakeInfoStatics->ucCmdCnt++; + gprWakeInfoStatics->arCmd[j].ucCmdId = ucCmdId; + gprWakeInfoStatics->arCmd[j].u2Cnt++; + gprWakeInfoStatics->u4TotalCmd++; + gprWakeInfoStatics->arCmd[j].ucFlagIsUesd + = TRUE; + break; + } + } + + if (j >= WAKE_MAX_CMD_EVENT_NUM) { + DBGLOG_LIMITED(OID, WARN, + "Wake cmd over flow %d-0x%02x\n", + WAKE_MAX_CMD_EVENT_NUM, ucCmdId); + } + } + return 0; +} + +uint32_t wlanWakeLogEvent(uint8_t ucEventId) +{ + int i = 0; + int j = 0; + + if ((gprWakeInfoStatics == NULL) || (wlan_fb_power_down != TRUE)) + return 1; + + for (i = 0; i < WAKE_MAX_CMD_EVENT_NUM; i++) { + if ((gprWakeInfoStatics->arEvent[i].ucFlagIsUesd == TRUE) + && + (gprWakeInfoStatics->arEvent[i].ucEventId == ucEventId)) { + /*old item ++*/ + gprWakeInfoStatics->arEvent[i].u2Cnt++; + gprWakeInfoStatics->u4TotalEvent++; + break; + } + } + + if (i >= WAKE_MAX_CMD_EVENT_NUM) { + /*add new item*/ + for (j = 0; j < WAKE_MAX_CMD_EVENT_NUM; j++) { + if (gprWakeInfoStatics->arEvent[j].ucFlagIsUesd + != TRUE) { + gprWakeInfoStatics->ucEventCnt++; + gprWakeInfoStatics->arEvent[j].ucEventId + = ucEventId; + gprWakeInfoStatics->arEvent[j].u2Cnt++; + gprWakeInfoStatics->u4TotalEvent++; + gprWakeInfoStatics->arEvent[j].ucFlagIsUesd + = TRUE; + break; + } + } + + if (j >= WAKE_MAX_CMD_EVENT_NUM) { + DBGLOG(OID, WARN, + "Wake event over flow %d-0x%02x\n", + WAKE_MAX_CMD_EVENT_NUM, ucEventId); + } + } + return 0; +} + +void wlanLogTxData(enum WAKE_DATA_TYPE dataType) +{ + if ((gprWakeInfoStatics != NULL) && (wlan_fb_power_down == TRUE)) { + gprWakeInfoStatics->au4TxDataCnt[dataType]++; + gprWakeInfoStatics->u4TxCnt++; + } +} + +void wlanLogRxData(enum WAKE_DATA_TYPE dataType) +{ + if ((gprWakeInfoStatics != NULL) && (wlan_fb_power_down == TRUE)) { + gprWakeInfoStatics->au4RxDataCnt[dataType]++; + gprWakeInfoStatics->u4RxCnt++; + } +} + +static void wlanWakeStaticsClear(void) +{ + if (gprWakeInfoStatics != NULL) { + kalMemZero(gprWakeInfoStatics, + WAKE_MAX_CMD_EVENT_NUM * sizeof(struct + WAKE_INFO_T)); + } +} + +uint32_t wlanWakeDumpRes(void) +{ + uint8_t i = 0; + uint8_t flag = 0; + char *pos = NULL; + char *end = NULL; + int ret = 0; + + if ((gprWakeInfoStatics == NULL) + || (wlan_fb_power_down != TRUE)) { + wlanWakeStaticsClear(); + return 1; + } + + /*Log Style: one line log or human friendly log.*/ +#if 1 + kalMemZero(&aucStr[0], sizeof(uint8_t)*WAKE_STR_BUFFER_LEN); + pos = &aucStr[0]; + end = &aucStr[0] + WAKE_STR_BUFFER_LEN - 1; + + if (gprWakeInfoStatics->ucCmdCnt > 0) { + flag = 1; + ret = snprintf(pos, (end - pos + 1), "CMD(%u:%u)= ", + gprWakeInfoStatics->ucCmdCnt, + gprWakeInfoStatics->u4TotalCmd); + if (ret < 0 || ret >= (end - pos + 1)) + return 1; + pos += ret; + + for (i = 0; i < gprWakeInfoStatics->ucCmdCnt; i++) { + ret = snprintf(pos, (end - pos + 1), "0x%02x-%d ", + gprWakeInfoStatics->arCmd[i].ucCmdId, + gprWakeInfoStatics->arCmd[i].u2Cnt); + if (ret < 0 || ret >= (end - pos + 1)) + return 1; + pos += ret; + } + } + + if (gprWakeInfoStatics->ucEventCnt > 0) { + flag = 1; + ret = snprintf(pos, (end - pos + 1), "EVENT(%u:%u)= ", + gprWakeInfoStatics->ucEventCnt, + gprWakeInfoStatics->u4TotalEvent); + if (ret < 0 || ret >= (end - pos + 1)) + return 1; + pos += ret; + + for (i = 0; i < gprWakeInfoStatics->ucEventCnt; i++) { + ret = snprintf(pos, (end - pos + 1), "0x%02x-%d ", + gprWakeInfoStatics->arEvent[i].ucEventId, + gprWakeInfoStatics->arEvent[i].u2Cnt); + if (ret < 0 || ret >= (end - pos + 1)) + return 1; + pos += ret; + } + } + + if (gprWakeInfoStatics->u4TxCnt > 0) { + flag = 1; + ret = snprintf(pos, (end - pos + 1), + "TX(%u)=%u-%u-%u-%u-%u-%u ", + gprWakeInfoStatics->u4TxCnt, + gprWakeInfoStatics->au4TxDataCnt[WLAN_WAKE_ARP], + gprWakeInfoStatics->au4TxDataCnt[WLAN_WAKE_IPV4], + gprWakeInfoStatics->au4TxDataCnt[WLAN_WAKE_IPV6], + gprWakeInfoStatics->au4TxDataCnt[WLAN_WAKE_1X], + gprWakeInfoStatics->au4TxDataCnt[WLAN_WAKE_TDLS], + gprWakeInfoStatics->au4TxDataCnt[WLAN_WAKE_OTHER]); + + if (ret < 0 || ret >= (end - pos + 1)) + return 1; + pos += ret; + } + + if (gprWakeInfoStatics->u4RxCnt > 0) { + flag = 1; + ret = snprintf(pos, (end - pos + 1), + "RX(%u)=%u-%u-%u-%u-%u-%u ", + gprWakeInfoStatics->u4RxCnt, + gprWakeInfoStatics->au4RxDataCnt[WLAN_WAKE_ARP], + gprWakeInfoStatics->au4RxDataCnt[WLAN_WAKE_IPV4], + gprWakeInfoStatics->au4RxDataCnt[WLAN_WAKE_IPV6], + gprWakeInfoStatics->au4RxDataCnt[WLAN_WAKE_1X], + gprWakeInfoStatics->au4RxDataCnt[WLAN_WAKE_TDLS], + gprWakeInfoStatics->au4RxDataCnt[WLAN_WAKE_OTHER]); + if (ret < 0 || ret >= (end - pos + 1)) + return 1; + pos += ret; + } + + if (flag != 0) + DBGLOG(OID, INFO, "[WLAN-LP] %s\n", (char *)&aucStr[0]); +#else + /*1.dump cmd*/ + if (gprWakeInfoStatics->ucCmdCnt > 0) { + kalMemZero(&aucStr[0], sizeof(uint8_t)*WAKE_STR_BUFFER_LEN); + pos = &aucStr[0]; + end = &aucStr[0] + WAKE_STR_BUFFER_LEN - 1; + for (i = 0; i < gprWakeInfoStatics->ucCmdCnt; i++) { + + ret = snprintf(pos, end - pos, " 0x%02x ", + gprWakeInfoStatics->arCmd[i].ucCmdId); + if (ret < 0 || ret >= end - pos) + return 1; + pos += ret; + } + DBGLOG(OID, INFO, "[LP-CMD-ID-%u][%s]\n", + gprWakeInfoStatics->ucCmdCnt, (char *)&aucStr[0]); + + kalMemZero(&aucStr[0], sizeof(uint8_t)*WAKE_STR_BUFFER_LEN); + pos = &aucStr[0]; + end = &aucStr[0] + WAKE_STR_BUFFER_LEN - 1; + for (i = 0; i < gprWakeInfoStatics->ucCmdCnt; i++) { + + ret = snprintf(pos, end - pos, " %u ", + gprWakeInfoStatics->arCmd[i].u2Cnt); + if (ret < 0 || ret >= end - pos) + return 1; + pos += ret; + } + DBGLOG(OID, INFO, "[LP-CMD-CNT-%u][%s]\n", + gprWakeInfoStatics->u4TotalCmd, (char *)&aucStr[0]); + } + + /*2.dump event*/ + if (gprWakeInfoStatics->ucCmdCnt > 0) { + + kalMemZero(&aucStr[0], sizeof(uint8_t)*WAKE_STR_BUFFER_LEN); + pos = &aucStr[0]; + end = &aucStr[0] + WAKE_STR_BUFFER_LEN - 1; + for (i = 0; i < gprWakeInfoStatics->ucEventCnt; i++) { + + ret = snprintf(pos, end - pos, " 0x%02x ", + gprWakeInfoStatics->arEvent[i].ucEventId); + if (ret < 0 || ret >= end - pos) + return 1; + pos += ret; + } + DBGLOG(OID, INFO, "[LP-EVENT-ID-%u][%s]\n", + gprWakeInfoStatics->ucEventCnt, (char *)&aucStr[0]); + + kalMemZero(&aucStr[0], sizeof(uint8_t)*WAKE_STR_BUFFER_LEN); + pos = &aucStr[0]; + end = &aucStr[0] + WAKE_STR_BUFFER_LEN - 1; + for (i = 0; i < gprWakeInfoStatics->ucEventCnt; i++) { + + ret = snprintf(pos, end - pos, " %u ", + gprWakeInfoStatics->arEvent[i].u2Cnt); + if (ret < 0 || ret >= end - pos) { + end[-1] = '\0'; + return 1; + } + pos += ret; + } + DBGLOG(OID, INFO, "[LP-EVENT-CNT-%u][%s]\n", + gprWakeInfoStatics->u4TotalEvent, (char *)&aucStr[0]); + } + + /*3.dump tx/rx data*/ + if (gprWakeInfoStatics->u4TxCnt > 0) { + DBGLOG(OID, INFO, "[LP-EVENT-TX-%u][%u-%u-%u-%u-%u-%u]\n", + gprWakeInfoStatics->u4TxCnt, + gprWakeInfoStatics->au4TxDataCnt[WLAN_WAKE_ARP], + gprWakeInfoStatics->au4TxDataCnt[WLAN_WAKE_IPV4], + gprWakeInfoStatics->au4TxDataCnt[WLAN_WAKE_IPV6], + gprWakeInfoStatics->au4TxDataCnt[WLAN_WAKE_1X], + gprWakeInfoStatics->au4TxDataCnt[WLAN_WAKE_TDLS], + gprWakeInfoStatics->au4TxDataCnt[WLAN_WAKE_OTHER]); + } + + if (gprWakeInfoStatics->u4RxCnt > 0) { + DBGLOG(OID, INFO, "[LP-EVENT-RX-%u][%u-%u-%u-%u-%u-%u]\n", + gprWakeInfoStatics->u4RxCnt, + gprWakeInfoStatics->au4RxDataCnt[WLAN_WAKE_ARP], + gprWakeInfoStatics->au4RxDataCnt[WLAN_WAKE_IPV4], + gprWakeInfoStatics->au4RxDataCnt[WLAN_WAKE_IPV6], + gprWakeInfoStatics->au4RxDataCnt[WLAN_WAKE_1X], + gprWakeInfoStatics->au4RxDataCnt[WLAN_WAKE_TDLS], + gprWakeInfoStatics->au4RxDataCnt[WLAN_WAKE_OTHER]); + } +#endif + wlanWakeStaticsClear(); + return 0; +} + +#endif + +uint32_t wlanSetDriverDbgLevel(IN uint32_t u4DbgIdx, IN uint32_t u4DbgMask) +{ + uint32_t u4Idx; + uint32_t fgStatus = WLAN_STATUS_SUCCESS; + + if (u4DbgIdx == DBG_ALL_MODULE_IDX) { + for (u4Idx = 0; u4Idx < DBG_MODULE_NUM; u4Idx++) + aucDebugModule[u4Idx] = (uint8_t) u4DbgMask; + LOG_FUNC("Set ALL DBG module log level to [0x%02x]\n", + u4DbgMask); + } else if (u4DbgIdx < DBG_MODULE_NUM) { + aucDebugModule[u4DbgIdx] = (uint8_t) u4DbgMask; + LOG_FUNC("Set DBG module[%u] log level to [0x%02x]\n", + u4DbgIdx, u4DbgMask); + } else { + fgStatus = WLAN_STATUS_FAILURE; + } + + if (fgStatus == WLAN_STATUS_SUCCESS) + wlanDriverDbgLevelSync(); + + return fgStatus; +} + +uint32_t wlanGetDriverDbgLevel(IN uint32_t u4DbgIdx, OUT uint32_t *pu4DbgMask) +{ + if (u4DbgIdx < DBG_MODULE_NUM) { + *pu4DbgMask = aucDebugModule[u4DbgIdx]; + return WLAN_STATUS_SUCCESS; + } + + return WLAN_STATUS_FAILURE; +} + +uint32_t wlanDbgLevelUiSupport(IN struct ADAPTER *prAdapter, uint32_t u4Version, + uint32_t ucModule) +{ + uint32_t u4Enable = ENUM_WIFI_LOG_LEVEL_SUPPORT_DISABLE; + + switch (u4Version) { + case ENUM_WIFI_LOG_LEVEL_VERSION_V1: + switch (ucModule) { + case ENUM_WIFI_LOG_MODULE_DRIVER: + u4Enable = ENUM_WIFI_LOG_LEVEL_SUPPORT_ENABLE; + break; + case ENUM_WIFI_LOG_MODULE_FW: + u4Enable = ENUM_WIFI_LOG_LEVEL_SUPPORT_ENABLE; + break; + } + break; + default: + break; + } + + return u4Enable; +} + +uint32_t wlanDbgGetLogLevelImpl(IN struct ADAPTER *prAdapter, + uint32_t u4Version, uint32_t ucModule) +{ + uint32_t u4Level = ENUM_WIFI_LOG_LEVEL_DEFAULT; + + switch (u4Version) { + case ENUM_WIFI_LOG_LEVEL_VERSION_V1: + wlanDbgGetGlobalLogLevel(ucModule, &u4Level); + break; + default: + break; + } + + return u4Level; +} + +void wlanDbgSetLogLevelImpl(IN struct ADAPTER *prAdapter, + uint32_t u4Version, uint32_t u4Module, uint32_t u4level) +{ + uint32_t u4DriverLevel = ENUM_WIFI_LOG_LEVEL_DEFAULT; + uint32_t u4FwLevel = ENUM_WIFI_LOG_LEVEL_DEFAULT; + + if (u4level >= ENUM_WIFI_LOG_LEVEL_NUM) + return; + + switch (u4Version) { + case ENUM_WIFI_LOG_LEVEL_VERSION_V1: + wlanDbgSetGlobalLogLevel(u4Module, u4level); + switch (u4Module) { + case ENUM_WIFI_LOG_MODULE_DRIVER: + { + uint32_t u4DriverLogMask; + + if (u4level == ENUM_WIFI_LOG_LEVEL_DEFAULT) + u4DriverLogMask = DBG_LOG_LEVEL_DEFAULT; + else if (u4level == ENUM_WIFI_LOG_LEVEL_MORE) + u4DriverLogMask = DBG_LOG_LEVEL_MORE; + else + u4DriverLogMask = DBG_LOG_LEVEL_EXTREME; + + wlanSetDriverDbgLevel(DBG_ALL_MODULE_IDX, + (u4DriverLogMask & DBG_CLASS_MASK)); + } + break; + case ENUM_WIFI_LOG_MODULE_FW: + { + struct CMD_EVENT_LOG_UI_INFO cmd; + + kalMemZero(&cmd, + sizeof(struct CMD_EVENT_LOG_UI_INFO)); + cmd.ucVersion = u4Version; + cmd.ucLogLevel = u4level; + + wlanSendSetQueryCmd(prAdapter, + CMD_ID_LOG_UI_INFO, + TRUE, + FALSE, + FALSE, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_EVENT_LOG_UI_INFO), + (uint8_t *)&cmd, + NULL, + 0); + } + break; + default: + break; + } + break; + default: + break; + } + + wlanDbgGetGlobalLogLevel(ENUM_WIFI_LOG_MODULE_DRIVER, &u4DriverLevel); + wlanDbgGetGlobalLogLevel(ENUM_WIFI_LOG_MODULE_FW, &u4FwLevel); +#if KERNEL_VERSION(4, 14, 0) >= LINUX_VERSION_CODE +#if (CFG_BUILT_IN_DRIVER == 0) && (CFG_MTK_ANDROID_WMT == 1) + /* + * The function definition of get_logtoomuch_enable() and + * set_logtoomuch_enable of Android O0 or lower version are different + * from that of Android O1 or higher version. Wlan driver supports .ko + * module from Android O1. Use CFG_BUILT_IN_DRIVER to distinguish + * Android version higher than O1 instead. + */ + if ((u4DriverLevel > ENUM_WIFI_LOG_LEVEL_DEFAULT || + u4FwLevel > ENUM_WIFI_LOG_LEVEL_DEFAULT) && + get_logtoomuch_enable()) { + DBGLOG(OID, TRACE, + "Disable printk to much. driver: %d, fw: %d\n", + u4DriverLevel, + u4FwLevel); + set_logtoomuch_enable(0); + } +#endif +#endif /* KERNEL_VERSION(4, 14, 0) >= LINUX_VERSION_CODE */ +} + +u_int8_t wlanDbgGetGlobalLogLevel(uint32_t u4Module, uint32_t *pu4Level) +{ + if (u4Module != ENUM_WIFI_LOG_MODULE_DRIVER && + u4Module != ENUM_WIFI_LOG_MODULE_FW) + return FALSE; + + *pu4Level = au4LogLevel[u4Module]; + return TRUE; +} + +u_int8_t wlanDbgSetGlobalLogLevel(uint32_t u4Module, uint32_t u4Level) +{ + if (u4Module != ENUM_WIFI_LOG_MODULE_DRIVER && + u4Module != ENUM_WIFI_LOG_MODULE_FW) + return FALSE; + + au4LogLevel[u4Module] = u4Level; + return TRUE; +} + +void wlanDriverDbgLevelSync(void) +{ + uint8_t i = 0; + uint32_t u4Mask = DBG_CLASS_MASK; + uint32_t u4DriverLogLevel = ENUM_WIFI_LOG_LEVEL_DEFAULT; + + /* get the lowest level as module's level */ + for (i = 0; i < DBG_MODULE_NUM; i++) + u4Mask &= aucDebugModule[i]; + + if ((u4Mask & DBG_LOG_LEVEL_EXTREME) == DBG_LOG_LEVEL_EXTREME) + u4DriverLogLevel = ENUM_WIFI_LOG_LEVEL_EXTREME; + else if ((u4Mask & DBG_LOG_LEVEL_MORE) == DBG_LOG_LEVEL_MORE) + u4DriverLogLevel = ENUM_WIFI_LOG_LEVEL_MORE; + else + u4DriverLogLevel = ENUM_WIFI_LOG_LEVEL_DEFAULT; + + wlanDbgSetGlobalLogLevel(ENUM_WIFI_LOG_MODULE_DRIVER, u4DriverLogLevel); +} + +static void +firmwareHexDump(const uint8_t *pucPreFix, + int32_t i4PreFixType, + int32_t i4RowSize, int32_t i4GroupSize, + const void *pvBuf, size_t len, u_int8_t fgAscii) +{ +#define OLD_KBUILD_MODNAME KBUILD_MODNAME +#undef KBUILD_MODNAME +#define KBUILD_MODNAME "wlan_mt6632_fw" + + const uint8_t *pucPtr = pvBuf; + int32_t i, i4LineLen, i4Remaining = len; + uint8_t ucLineBuf[32 * 3 + 2 + 32 + 1]; + + if (i4RowSize != 16 && i4RowSize != 32) + i4RowSize = 16; + + for (i = 0; i < len; i += i4RowSize) { + i4LineLen = min(i4Remaining, i4RowSize); + i4Remaining -= i4RowSize; + + /* use kernel API */ + hex_dump_to_buffer(pucPtr + i, i4LineLen, i4RowSize, + i4GroupSize, + ucLineBuf, sizeof(ucLineBuf), fgAscii); + + switch (i4PreFixType) { + case DUMP_PREFIX_ADDRESS: + pr_info("%s%p: %s\n", + pucPreFix, pucPtr + i, ucLineBuf); + break; + case DUMP_PREFIX_OFFSET: + pr_info("%s%.8x: %s\n", pucPreFix, i, ucLineBuf); + break; + default: + pr_info("%s%s\n", pucPreFix, ucLineBuf); + break; + } + } +#undef KBUILD_MODNAME +#define KBUILD_MODNAME OLD_KBUILD_MODNAME +} + +void wlanPrintFwLog(uint8_t *pucLogContent, + uint16_t u2MsgSize, uint8_t ucMsgType, + const uint8_t *pucFmt, ...) +{ +#define OLD_KBUILD_MODNAME KBUILD_MODNAME +#define OLD_LOG_FUNC LOG_FUNC +#undef KBUILD_MODNAME +#undef LOG_FUNC +#define KBUILD_MODNAME "wlan_mt6632_fw" +#define LOG_FUNC pr_info +#define DBG_LOG_BUF_SIZE 128 + + int8_t aucLogBuffer[DBG_LOG_BUF_SIZE]; + int32_t err; + va_list args; + + if (u2MsgSize > DEBUG_MSG_SIZE_MAX - 1) { + LOG_FUNC("Firmware Log Size(%d) is too large, type %d\n", + u2MsgSize, ucMsgType); + return; + } + switch (ucMsgType) { + case DEBUG_MSG_TYPE_ASCII: { + uint8_t *pucChr; + + pucLogContent[u2MsgSize] = '\0'; + + /* skip newline */ + pucChr = kalStrChr(pucLogContent, '\0'); + if (*(pucChr - 1) == '\n') + *(pucChr - 1) = '\0'; + + LOG_FUNC("%s\n", pucLogContent); + } + break; + case DEBUG_MSG_TYPE_DRIVER: + /* Only 128 Bytes is available to print in driver */ + va_start(args, pucFmt); + err = vsnprintf(aucLogBuffer, sizeof(aucLogBuffer) - 1, pucFmt, + args); + va_end(args); + aucLogBuffer[DBG_LOG_BUF_SIZE - 1] = '\0'; + if (err >= 0) + LOG_FUNC("%s\n", aucLogBuffer); + break; + case DEBUG_MSG_TYPE_MEM8: + firmwareHexDump("fw data:", DUMP_PREFIX_ADDRESS, + 16, 1, pucLogContent, u2MsgSize, true); + break; + default: + firmwareHexDump("fw data:", DUMP_PREFIX_ADDRESS, + 16, 4, pucLogContent, u2MsgSize, true); + break; + } + +#undef KBUILD_MODNAME +#undef LOG_FUNC +#define KBUILD_MODNAME OLD_KBUILD_MODNAME +#define LOG_FUNC OLD_LOG_FUNC +#undef OLD_KBUILD_MODNAME +#undef OLD_LOG_FUNC +} + +/* Begin: Functions used to breakdown packet jitter, for test case VoE 5.7 */ +static void wlanSetBE32(uint32_t u4Val, uint8_t *pucBuf) +{ + uint8_t *littleEn = (uint8_t *)&u4Val; + + pucBuf[0] = littleEn[3]; + pucBuf[1] = littleEn[2]; + pucBuf[2] = littleEn[1]; + pucBuf[3] = littleEn[0]; +} + +void wlanFillTimestamp(struct ADAPTER *prAdapter, void *pvPacket, + uint8_t ucPhase) +{ + struct sk_buff *skb = (struct sk_buff *)pvPacket; + uint8_t *pucEth = NULL; + uint32_t u4Length = 0; + uint8_t *pucUdp = NULL; + struct timeval tval; + + if (!prAdapter || !prAdapter->rDebugInfo.fgVoE5_7Test || !skb) + return; + pucEth = skb->data; + u4Length = skb->len; + if (u4Length < 200 || + ((pucEth[ETH_TYPE_LEN_OFFSET] << 8) | + (pucEth[ETH_TYPE_LEN_OFFSET + 1])) != ETH_P_IPV4) + return; + if (pucEth[ETH_HLEN+9] != IP_PRO_UDP) + return; + pucUdp = &pucEth[ETH_HLEN+28]; + if (kalStrnCmp(pucUdp, "1345678", 7)) + return; + do_gettimeofday(&tval); + switch (ucPhase) { + case PHASE_XMIT_RCV: /* xmit */ + pucUdp += 20; + break; + case PHASE_ENQ_QM: /* enq */ + pucUdp += 28; + break; + case PHASE_HIF_TX: /* tx */ + pucUdp += 36; + break; + } + wlanSetBE32(tval.tv_sec, pucUdp); + wlanSetBE32(tval.tv_usec, pucUdp+4); +} +/* End: Functions used to breakdown packet jitter, for test case VoE 5.7 */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/common/dump.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/common/dump.c new file mode 100644 index 0000000000000000000000000000000000000000..3d45a210bbc5b8dcf5206086cd4cf1a5a7c2db31 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/common/dump.c @@ -0,0 +1,461 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: common/dump.c + */ + +/*! \file "dump.c" + * \brief Provide memory dump function for debugging. + * + * Provide memory dump function for debugging. + */ + + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to dump a segment of memory in bytes. + * + * \param[in] pucStartAddr Pointer to the starting address of the memory + * to be dumped. + * \param[in] u4Length Length of the memory to be dumped. + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void dumpMemory8(IN uint8_t *pucStartAddr, + IN uint32_t u4Length) +{ + ASSERT(pucStartAddr); + + LOG_FUNC("DUMP8 ADDRESS: %p, Length: %d\n", pucStartAddr, + u4Length); + +#define case16 "(%p) %02x %02x %02x %02x %02x %02x %02x %02x" \ + " - %02x %02x %02x %02x %02x %02x %02x %02x\n" + +#define case07 "(%p) %02x %02x %02x %02x %02x %02x %02x\n" + +#define case08 "(%p) %02x %02x %02x %02x %02x %02x %02x %02x\n" + +#define case09 "(%p) %02x %02x %02x %02x %02x %02x %02x %02x" \ + " - %02x\n" + +#define case10 "(%p) %02x %02x %02x %02x %02x %02x %02x %02x" \ + " - %02x %02x\n" + +#define case11 "(%p) %02x %02x %02x %02x %02x %02x %02x %02x" \ + " - %02x %02x %02x\n" + +#define case12 "(%p) %02x %02x %02x %02x %02x %02x %02x %02x" \ + " - %02x %02x %02x %02x\n" + +#define case13 "(%p) %02x %02x %02x %02x %02x %02x %02x %02x" \ + " - %02x %02x %02x %02x %02x\n" + +#define case14 "(%p) %02x %02x %02x %02x %02x %02x %02x %02x" \ + " - %02x %02x %02x %02x %02x %02x\n" + +#define case15 "(%p) %02x %02x %02x %02x %02x %02x %02x %02x" \ + " - %02x %02x %02x %02x %02x %02x %02x\n" + + while (u4Length > 0) { + if (u4Length >= 16) { + LOG_FUNC + (case16, + pucStartAddr, pucStartAddr[0], pucStartAddr[1], + pucStartAddr[2], pucStartAddr[3], pucStartAddr[4], + pucStartAddr[5], pucStartAddr[6], pucStartAddr[7], + pucStartAddr[8], pucStartAddr[9], pucStartAddr[10], + pucStartAddr[11], pucStartAddr[12], + pucStartAddr[13], pucStartAddr[14], + pucStartAddr[15]); + u4Length -= 16; + pucStartAddr += 16; + } else { + switch (u4Length) { + case 1: + LOG_FUNC("(%p) %02x\n", pucStartAddr, + pucStartAddr[0]); + break; + case 2: + LOG_FUNC("(%p) %02x %02x\n", pucStartAddr, + pucStartAddr[0], pucStartAddr[1]); + break; + case 3: + LOG_FUNC("(%p) %02x %02x %02x\n", + pucStartAddr, pucStartAddr[0], + pucStartAddr[1], pucStartAddr[2]); + break; + case 4: + LOG_FUNC("(%p) %02x %02x %02x %02x\n", + pucStartAddr, + pucStartAddr[0], pucStartAddr[1], + pucStartAddr[2], pucStartAddr[3]); + break; + case 5: + LOG_FUNC("(%p) %02x %02x %02x %02x %02x\n", + pucStartAddr, + pucStartAddr[0], pucStartAddr[1], + pucStartAddr[2], pucStartAddr[3], + pucStartAddr[4]); + break; + case 6: + LOG_FUNC + ("(%p) %02x %02x %02x %02x %02x %02x\n", + pucStartAddr, pucStartAddr[0], + pucStartAddr[1], pucStartAddr[2], + pucStartAddr[3], pucStartAddr[4], + pucStartAddr[5]); + break; + case 7: + LOG_FUNC + (case07, + pucStartAddr, pucStartAddr[0], + pucStartAddr[1], pucStartAddr[2], + pucStartAddr[3], pucStartAddr[4], + pucStartAddr[5], pucStartAddr[6]); + break; + case 8: + LOG_FUNC + (case08, + pucStartAddr, pucStartAddr[0], + pucStartAddr[1], pucStartAddr[2], + pucStartAddr[3], pucStartAddr[4], + pucStartAddr[5], pucStartAddr[6], + pucStartAddr[7]); + break; + case 9: + LOG_FUNC + (case09, + pucStartAddr, pucStartAddr[0], + pucStartAddr[1], pucStartAddr[2], + pucStartAddr[3], pucStartAddr[4], + pucStartAddr[5], pucStartAddr[6], + pucStartAddr[7], pucStartAddr[8]); + break; + case 10: + LOG_FUNC + (case10, + pucStartAddr, pucStartAddr[0], + pucStartAddr[1], pucStartAddr[2], + pucStartAddr[3], pucStartAddr[4], + pucStartAddr[5], pucStartAddr[6], + pucStartAddr[7], pucStartAddr[8], + pucStartAddr[9]); + break; + case 11: + LOG_FUNC + (case11, + pucStartAddr, pucStartAddr[0], + pucStartAddr[1], pucStartAddr[2], + pucStartAddr[3], pucStartAddr[4], + pucStartAddr[5], pucStartAddr[6], + pucStartAddr[7], pucStartAddr[8], + pucStartAddr[9], pucStartAddr[10]); + break; + case 12: + LOG_FUNC + (case12, + pucStartAddr, pucStartAddr[0], + pucStartAddr[1], pucStartAddr[2], + pucStartAddr[3], pucStartAddr[4], + pucStartAddr[5], pucStartAddr[6], + pucStartAddr[7], pucStartAddr[8], + pucStartAddr[9], pucStartAddr[10], + pucStartAddr[11]); + break; + case 13: + LOG_FUNC + (case13, + pucStartAddr, pucStartAddr[0], + pucStartAddr[1], pucStartAddr[2], + pucStartAddr[3], pucStartAddr[4], + pucStartAddr[5], pucStartAddr[6], + pucStartAddr[7], pucStartAddr[8], + pucStartAddr[9], pucStartAddr[10], + pucStartAddr[11], pucStartAddr[12]); + break; + case 14: + LOG_FUNC + (case14, + pucStartAddr, pucStartAddr[0], + pucStartAddr[1], pucStartAddr[2], + pucStartAddr[3], pucStartAddr[4], + pucStartAddr[5], pucStartAddr[6], + pucStartAddr[7], pucStartAddr[8], + pucStartAddr[9], pucStartAddr[10], + pucStartAddr[11], pucStartAddr[12], + pucStartAddr[13]); + break; + case 15: + default: + LOG_FUNC + (case15, + pucStartAddr, pucStartAddr[0], + pucStartAddr[1], pucStartAddr[2], + pucStartAddr[3], pucStartAddr[4], + pucStartAddr[5], pucStartAddr[6], + pucStartAddr[7], pucStartAddr[8], + pucStartAddr[9], pucStartAddr[10], + pucStartAddr[11], pucStartAddr[12], + pucStartAddr[13], pucStartAddr[14]); + break; + } + u4Length = 0; + } + } +} /* end of dumpMemory8() */ + + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to dump a segment of memory in double words. + * + * \param[in] pucStartAddr Pointer to the starting address of the memory + * to be dumped. + * \param[in] u4Length Length of the memory to be dumped. + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void dumpMemory32(IN uint32_t *pu4StartAddr, + IN uint32_t u4Length) +{ + uint8_t *pucAddr; + + ASSERT(pu4StartAddr); + + LOG_FUNC("DUMP32 ADDRESS: %p, Length: %d\n", pu4StartAddr, + u4Length); + + if (IS_NOT_ALIGN_4((unsigned long)pu4StartAddr)) { + uint32_t u4ProtrudeLen = + sizeof(uint32_t) - ((unsigned long)pu4StartAddr % 4); + + u4ProtrudeLen = + ((u4Length < u4ProtrudeLen) ? u4Length : u4ProtrudeLen); + LOG_FUNC("pu4StartAddr is not at DW boundary.\n"); + pucAddr = (uint8_t *) &pu4StartAddr[0]; + + switch (u4ProtrudeLen) { + case 1: + LOG_FUNC("(%p) %02x------\n", pu4StartAddr, pucAddr[0]); + break; + case 2: + LOG_FUNC("(%p) %02x%02x----\n", pu4StartAddr, + pucAddr[1], pucAddr[0]); + break; + case 3: + LOG_FUNC("(%p) %02x%02x%02x--\n", pu4StartAddr, + pucAddr[2], pucAddr[1], pucAddr[0]); + break; + default: + break; + } + + u4Length -= u4ProtrudeLen; + pu4StartAddr = (uint32_t *) + ((unsigned long)pu4StartAddr + u4ProtrudeLen); + } + + while (u4Length > 0) { + if (u4Length >= 16) { + LOG_FUNC("(%p) %08x %08x %08x %08x\n", + pu4StartAddr, + pu4StartAddr[0], pu4StartAddr[1], + pu4StartAddr[2], pu4StartAddr[3]); + pu4StartAddr += 4; + u4Length -= 16; + } else { + switch (u4Length) { + case 1: + pucAddr = (uint8_t *) &pu4StartAddr[0]; + LOG_FUNC("(%p) ------%02x\n", + pu4StartAddr, pucAddr[0]); + break; + case 2: + pucAddr = (uint8_t *) &pu4StartAddr[0]; + LOG_FUNC("(%p) ----%02x%02x\n", pu4StartAddr, + pucAddr[1], pucAddr[0]); + break; + case 3: + pucAddr = (uint8_t *) &pu4StartAddr[0]; + LOG_FUNC("(%p) --%02x%02x%02x\n", pu4StartAddr, + pucAddr[2], pucAddr[1], pucAddr[0]); + break; + case 4: + LOG_FUNC("(%p) %08x\n", pu4StartAddr, + pu4StartAddr[0]); + break; + case 5: + pucAddr = (uint8_t *) &pu4StartAddr[1]; + LOG_FUNC("(%p) %08x ------%02x\n", pu4StartAddr, + pu4StartAddr[0], pucAddr[0]); + break; + case 6: + pucAddr = (uint8_t *) &pu4StartAddr[1]; + LOG_FUNC("(%p) %08x ----%02x%02x\n", + pu4StartAddr, pu4StartAddr[0], + pucAddr[1], pucAddr[0]); + break; + case 7: + pucAddr = (uint8_t *) &pu4StartAddr[1]; + LOG_FUNC("(%p) %08x --%02x%02x%02x\n", + pu4StartAddr, pu4StartAddr[0], + pucAddr[2], pucAddr[1], pucAddr[0]); + break; + case 8: + LOG_FUNC("(%p) %08x %08x\n", pu4StartAddr, + pu4StartAddr[0], pu4StartAddr[1]); + break; + case 9: + pucAddr = (uint8_t *) &pu4StartAddr[2]; + LOG_FUNC("(%p) %08x %08x ------%02x\n", + pu4StartAddr, pu4StartAddr[0], + pu4StartAddr[1], pucAddr[0]); + break; + case 10: + pucAddr = (uint8_t *) &pu4StartAddr[2]; + LOG_FUNC("(%p) %08x %08x ----%02x%02x\n", + pu4StartAddr, pu4StartAddr[0], + pu4StartAddr[1], pucAddr[1], + pucAddr[0]); + break; + case 11: + pucAddr = (uint8_t *) &pu4StartAddr[2]; + LOG_FUNC("(%p) %08x %08x --%02x%02x%02x\n", + pu4StartAddr, + pu4StartAddr[0], pu4StartAddr[1], + pucAddr[2], pucAddr[1], pucAddr[0]); + break; + case 12: + LOG_FUNC("(%p) %08x %08x %08x\n", + pu4StartAddr, + pu4StartAddr[0], pu4StartAddr[1], + pu4StartAddr[2]); + break; + case 13: + pucAddr = (uint8_t *) &pu4StartAddr[3]; + LOG_FUNC("(%p) %08x %08x %08x ------%02x\n", + pu4StartAddr, + pu4StartAddr[0], pu4StartAddr[1], + pu4StartAddr[2], pucAddr[0]); + break; + case 14: + pucAddr = (uint8_t *) &pu4StartAddr[3]; + LOG_FUNC("(%p) %08x %08x %08x ----%02x%02x\n", + pu4StartAddr, + pu4StartAddr[0], pu4StartAddr[1], + pu4StartAddr[2], + pucAddr[1], pucAddr[0]); + break; + case 15: + default: + pucAddr = (uint8_t *) &pu4StartAddr[3]; + LOG_FUNC("(%p) %08x %08x %08x --%02x%02x%02x\n", + pu4StartAddr, + pu4StartAddr[0], pu4StartAddr[1], + pu4StartAddr[2], + pucAddr[2], pucAddr[1], pucAddr[0]); + break; + } + u4Length = 0; + } + } +} /* end of dumpMemory32() */ + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/common/wlan_bow.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/common/wlan_bow.c new file mode 100644 index 0000000000000000000000000000000000000000..503f30f37405383e3f9d454e2d01077d1634a5c8 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/common/wlan_bow.c @@ -0,0 +1,3222 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* +** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/common/wlan_bow.c#1 +*/ + +/*! \file wlan_bow.c +* \brief This file contains the 802.11 PAL commands processing routines for +* MediaTek Inc. 802.11 Wireless LAN Adapters. +*/ + +/****************************************************************************** +* C O M P I L E R F L A G S +******************************************************************************* +*/ + +/****************************************************************************** +* E X T E R N A L R E F E R E N C E S +******************************************************************************* +*/ +#include "precomp.h" + +#if CFG_ENABLE_BT_OVER_WIFI + +/****************************************************************************** +* C O N S T A N T S +******************************************************************************* +*/ + +/****************************************************************************** +* D A T A T Y P E S +******************************************************************************* +*/ + +/****************************************************************************** +* P U B L I C D A T A +******************************************************************************* +*/ + +#if 1 /* Marked for MT6630 */ +static uint32_t g_u4LinkCount; +static uint32_t g_u4Beaconing; +static struct BOW_TABLE arBowTable[CFG_BOW_PHYSICAL_LINK_NUM]; +#endif + +/****************************************************************************** +* P R I V A T E D A T A +******************************************************************************* +*/ + +const struct BOW_CMD arBowCmdTable[] = { + {BOW_CMD_ID_GET_MAC_STATUS, bowCmdGetMacStatus}, + {BOW_CMD_ID_SETUP_CONNECTION, bowCmdSetupConnection}, + {BOW_CMD_ID_DESTROY_CONNECTION, bowCmdDestroyConnection}, + {BOW_CMD_ID_SET_PTK, bowCmdSetPTK}, + {BOW_CMD_ID_READ_RSSI, bowCmdReadRSSI}, + {BOW_CMD_ID_READ_LINK_QUALITY, bowCmdReadLinkQuality}, + {BOW_CMD_ID_SHORT_RANGE_MODE, bowCmdShortRangeMode}, + {BOW_CMD_ID_GET_CHANNEL_LIST, bowCmdGetChannelList}, +}; + +/****************************************************************************** +* M A C R O S +******************************************************************************* +*/ + +/****************************************************************************** +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************* +*/ + +/****************************************************************************** +* F U N C T I O N S +******************************************************************************* +*/ + +#if 1 /* Marked for MT6630 */ +/*----------------------------------------------------------------------------*/ +/*! +* \brief command packet generation utility +* +* \param[in] prAdapter Pointer to the Adapter structure. +* \param[in] ucCID Command ID +* \param[in] fgSetQuery Set or Query +* \param[in] fgNeedResp Need for response +* \param[in] pfCmdDoneHandler Function pointer when command is done +* \param[in] u4SetQueryInfoLen The length of the set/query buffer +* \param[in] pucInfoBuffer Pointer to set/query buffer +* +* +* \retval WLAN_STATUS_PENDING +* \retval WLAN_STATUS_FAILURE +*/ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSendSetQueryBowCmd(IN struct ADAPTER *prAdapter, + IN uint8_t ucCID, + IN uint8_t ucBssIdx, + IN u_int8_t fgSetQuery, + IN u_int8_t fgNeedResp, + IN PFN_CMD_DONE_HANDLER pfCmdDoneHandler, + IN PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler, + IN uint32_t u4SetQueryInfoLen, IN uint8_t *pucInfoBuffer, IN uint8_t ucSeqNumber) +{ + struct GLUE_INFO *prGlueInfo; + struct CMD_INFO *prCmdInfo; + u_int8_t *pWifiCmdBufAddr; + struct mt66xx_chip_info *prChipInfo; + uint16_t cmd_size; + + ASSERT(prAdapter); + + prGlueInfo = prAdapter->prGlueInfo; + prChipInfo = prAdapter->chip_info; + ASSERT(prGlueInfo); + + DBGLOG(REQ, TRACE, "Command ID = 0x%08X\n", ucCID); + + cmd_size = prChipInfo->u2CmdTxHdrSize + u4SetQueryInfoLen; + prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, cmd_size); + + if (!prCmdInfo) { + DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); + return WLAN_STATUS_FAILURE; + } + + /* Setup common CMD Info Packet */ + prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; + prCmdInfo->u2InfoBufLen = cmd_size; + prCmdInfo->pfCmdDoneHandler = pfCmdDoneHandler; + prCmdInfo->pfCmdTimeoutHandler = pfCmdTimeoutHandler; + prCmdInfo->fgIsOid = FALSE; + prCmdInfo->ucCID = ucCID; + prCmdInfo->fgSetQuery = fgSetQuery; + prCmdInfo->fgNeedResp = fgNeedResp; + prCmdInfo->u4SetInfoLen = u4SetQueryInfoLen; + prCmdInfo->pvInformationBuffer = NULL; + prCmdInfo->u4InformationBufferLength = 0; + prCmdInfo->u4PrivateData = (uint32_t) ucSeqNumber; + + /* Setup WIFI_CMD (no payload) */ + NIC_FILL_CMD_TX_HDR(prAdapter, + prCmdInfo->pucInfoBuffer, + prCmdInfo->u2InfoBufLen, + prCmdInfo->ucCID, + CMD_PACKET_TYPE_ID, + &prCmdInfo->ucCmdSeqNum, + prCmdInfo->fgSetQuery, + &pWifiCmdBufAddr, FALSE, 0, S2D_INDEX_CMD_H2N); + + if (u4SetQueryInfoLen > 0 && pucInfoBuffer != NULL) + kalMemCopy(pWifiCmdBufAddr, pucInfoBuffer, u4SetQueryInfoLen); + /* insert into prCmdQueue */ + kalEnqueueCommand(prGlueInfo, (struct QUE_ENTRY *) prCmdInfo); + + /* wakeup txServiceThread later */ + GLUE_SET_EVENT(prGlueInfo); + return WLAN_STATUS_PENDING; +} + +#endif /* Marked for MT6630 */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This routine is called to dispatch command coming from 802.11 PAL +* +* \param[in] prAdapter Pointer to the Adapter structure. +* \param[in] prCmd Pointer to the buffer that holds the command +* +* \retval WLAN_STATUS_SUCCESS +* \retval WLAN_STATUS_INVALID_LENGTH +*/ +/*----------------------------------------------------------------------------*/ +uint32_t wlanbowHandleCommand(IN struct ADAPTER *prAdapter, IN struct BT_OVER_WIFI_COMMAND *prCmd) +{ +#if 1 /* Marked for MT6630 */ + uint32_t retval = WLAN_STATUS_FAILURE; + uint16_t i; + + ASSERT(prAdapter); + + for (i = 0; i < sizeof(arBowCmdTable) / sizeof(struct BOW_CMD); i++) { + if ((arBowCmdTable[i].uCmdID == prCmd->rHeader.ucCommandId) && arBowCmdTable[i].pfCmdHandle) { + retval = arBowCmdTable[i].pfCmdHandle(prAdapter, prCmd); + break; + } + } + + return retval; + +#else + return 0; +#endif +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This is command handler for BOW_CMD_ID_GET_MAC_STATUS +* coming from 802.11 PAL +* +* \param[in] prAdapter Pointer to the Adapter structure. +* \param[in] prCmd Pointer to the buffer that holds the command +* +* \retval WLAN_STATUS_SUCCESS +* \retval WLAN_STATUS_INVALID_LENGTH +*/ +/*----------------------------------------------------------------------------*/ +uint32_t bowCmdGetMacStatus(IN struct ADAPTER *prAdapter, IN struct BT_OVER_WIFI_COMMAND *prCmd) +{ +#if 1 /* Marked for MT6630 */ + struct BT_OVER_WIFI_EVENT *prEvent; + struct BOW_MAC_STATUS *prMacStatus; + uint8_t idx = 0; + uint8_t ucPrimaryChannel; + enum ENUM_BAND eBand; + enum ENUM_CHNL_EXT eBssSCO; + uint8_t ucNumOfChannel = 0; /* MAX_BOW_NUMBER_OF_CHANNEL; */ + + struct RF_CHANNEL_INFO aucChannelList[MAX_BOW_NUMBER_OF_CHANNEL]; + + ASSERT(prAdapter); + + /* 3 <1> If LinkCount != 0 -> OK (optional) */ + + eBand = BAND_2G4; + eBssSCO = CHNL_EXT_SCN; + + /* fill event header */ + prEvent = (struct BT_OVER_WIFI_EVENT *) kalMemAlloc((sizeof(struct BT_OVER_WIFI_EVENT) + sizeof(struct BOW_MAC_STATUS)), VIR_MEM_TYPE); + + prEvent->rHeader.ucEventId = BOW_EVENT_ID_MAC_STATUS; + prEvent->rHeader.ucSeqNumber = prCmd->rHeader.ucSeqNumber; + prEvent->rHeader.u2PayloadLength = sizeof(struct BOW_MAC_STATUS); + + /* fill event body */ + prMacStatus = (struct BOW_MAC_STATUS *) (prEvent->aucPayload); + kalMemZero(prMacStatus, sizeof(struct BOW_MAC_STATUS)); + + /* 3 <2> Call CNM to decide if BOW available. */ + if (cnmBowIsPermitted(prAdapter)) + prMacStatus->ucAvailability = TRUE; + else + prMacStatus->ucAvailability = FALSE; + + memcpy(prMacStatus->aucMacAddr, prAdapter->rWifiVar.aucDeviceAddress, PARAM_MAC_ADDR_LEN); + + if (cnmPreferredChannel(prAdapter, &eBand, &ucPrimaryChannel, &eBssSCO)) { + DBGLOG(BOW, EVENT, "bowCmdGetMacStatus, Get preferred channel.\n"); + + prMacStatus->ucNumOfChannel = 1; + prMacStatus->arChannelList[0].ucChannelBand = eBand; + prMacStatus->arChannelList[0].ucChannelNum = ucPrimaryChannel; + } else { + DBGLOG(BOW, EVENT, + "bowCmdGetMacStatus, Get channel list. Current number of channel, %d.\n", ucNumOfChannel); + + rlmDomainGetChnlList(prAdapter, BAND_2G4, FALSE, MAX_BOW_NUMBER_OF_CHANNEL_2G4, + &ucNumOfChannel, aucChannelList); + + if (ucNumOfChannel > 0) { + for (idx = 0; idx < ucNumOfChannel /*MAX_BOW_NUMBER_OF_CHANNEL_2G4 */; + idx++) { + prMacStatus->arChannelList[idx].ucChannelBand = aucChannelList[idx].eBand; + prMacStatus->arChannelList[idx].ucChannelNum = aucChannelList[idx].ucChannelNum; + } + + prMacStatus->ucNumOfChannel = ucNumOfChannel; + } + + rlmDomainGetChnlList(prAdapter, BAND_5G, FALSE, + MAX_BOW_NUMBER_OF_CHANNEL_5G, &ucNumOfChannel, aucChannelList); + + if (ucNumOfChannel > 0) { + for (idx = 0; idx < ucNumOfChannel /*MAX_BOW_NUMBER_OF_CHANNEL_5G */; + idx++) { + prMacStatus->arChannelList[prMacStatus->ucNumOfChannel + + idx].ucChannelBand = aucChannelList[idx].eBand; + prMacStatus->arChannelList[prMacStatus->ucNumOfChannel + + idx].ucChannelNum = aucChannelList[idx].ucChannelNum; + } + + prMacStatus->ucNumOfChannel = prMacStatus->ucNumOfChannel + ucNumOfChannel; + + } + } + + DBGLOG(BOW, EVENT, + "ucNumOfChannel,eBand,aucChannelList,%x,%x,%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x.\n", + ucNumOfChannel, aucChannelList[0].eBand, aucChannelList[0].ucChannelNum, + aucChannelList[1].ucChannelNum, aucChannelList[2].ucChannelNum, + aucChannelList[3].ucChannelNum, aucChannelList[4].ucChannelNum, + aucChannelList[5].ucChannelNum, aucChannelList[6].ucChannelNum, + aucChannelList[7].ucChannelNum, aucChannelList[8].ucChannelNum, + aucChannelList[9].ucChannelNum, aucChannelList[10].ucChannelNum, + aucChannelList[11].ucChannelNum, aucChannelList[12].ucChannelNum, + aucChannelList[13].ucChannelNum, aucChannelList[14].ucChannelNum, + aucChannelList[15].ucChannelNum, aucChannelList[16].ucChannelNum, aucChannelList[17].ucChannelNum); + + DBGLOG(BOW, EVENT, + "prMacStatus->ucNumOfChannel, eBand, %x, %x.\n", + prMacStatus->ucNumOfChannel, prMacStatus->arChannelList[0].ucChannelBand); + DBGLOG(BOW, EVENT, + "prMacStatus->arChannelList, %x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x.\n", + prMacStatus->arChannelList[0].ucChannelNum, + prMacStatus->arChannelList[1].ucChannelNum, + prMacStatus->arChannelList[2].ucChannelNum, + prMacStatus->arChannelList[3].ucChannelNum, + prMacStatus->arChannelList[4].ucChannelNum, + prMacStatus->arChannelList[5].ucChannelNum, + prMacStatus->arChannelList[6].ucChannelNum, + prMacStatus->arChannelList[7].ucChannelNum, + prMacStatus->arChannelList[8].ucChannelNum, + prMacStatus->arChannelList[9].ucChannelNum, + prMacStatus->arChannelList[10].ucChannelNum, + prMacStatus->arChannelList[11].ucChannelNum, + prMacStatus->arChannelList[12].ucChannelNum, + prMacStatus->arChannelList[13].ucChannelNum, + prMacStatus->arChannelList[14].ucChannelNum, + prMacStatus->arChannelList[15].ucChannelNum, + prMacStatus->arChannelList[16].ucChannelNum, prMacStatus->arChannelList[17].ucChannelNum); + + DBGLOG(BOW, EVENT, "prMacStatus->ucNumOfChannel, %x.\n", prMacStatus->ucNumOfChannel); + DBGLOG(BOW, EVENT, + "prMacStatus->arChannelList[0].ucChannelBand, %x.\n", prMacStatus->arChannelList[0].ucChannelBand); + DBGLOG(BOW, EVENT, + "prMacStatus->arChannelList[0].ucChannelNum, %x.\n", prMacStatus->arChannelList[0].ucChannelNum); + DBGLOG(BOW, EVENT, "prMacStatus->ucAvailability, %x.\n", prMacStatus->ucAvailability); + DBGLOG(BOW, EVENT, "prMacStatus->aucMacAddr, %x:%x:%x:%x:%x:%x.\n", + prMacStatus->aucMacAddr[0], + prMacStatus->aucMacAddr[1], + prMacStatus->aucMacAddr[2], + prMacStatus->aucMacAddr[3], prMacStatus->aucMacAddr[4], prMacStatus->aucMacAddr[5]); + + kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); + + kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(struct BT_OVER_WIFI_EVENT) + sizeof(struct BOW_MAC_STATUS))); + + return WLAN_STATUS_SUCCESS; + +#else + return 0; +#endif +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This is command handler for BOW_CMD_ID_SETUP_CONNECTION +* coming from 802.11 PAL +* +* \param[in] prAdapter Pointer to the Adapter structure. +* \param[in] prCmd Pointer to the buffer that holds the command +* +* \retval WLAN_STATUS_SUCCESS +* \retval WLAN_STATUS_INVALID_LENGTH +*/ +/*----------------------------------------------------------------------------*/ +uint32_t bowCmdSetupConnection(IN struct ADAPTER *prAdapter, IN struct BT_OVER_WIFI_COMMAND *prCmd) +{ +#if 1 /* Marked for MT6630 */ + struct BOW_SETUP_CONNECTION *prBowSetupConnection; + struct CMD_BT_OVER_WIFI rCmdBtOverWifi; + struct BOW_FSM_INFO *prBowFsmInfo; + struct BOW_TABLE rBowTable; + + uint8_t ucBowTableIdx = 0; + + ASSERT(prAdapter); + + prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); + prBowSetupConnection = (struct BOW_SETUP_CONNECTION *) &(prCmd->aucPayload[0]); + + /* parameter size check */ + if (prCmd->rHeader.u2PayloadLength != sizeof(struct BOW_SETUP_CONNECTION)) { + wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_INVALID); + return WLAN_STATUS_INVALID_LENGTH; + } + /* 3 <1> If ucLinkCount >= 4 -> Fail. */ + if (g_u4LinkCount >= CFG_BOW_PHYSICAL_LINK_NUM) { + wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); + return WLAN_STATUS_NOT_ACCEPTED; + } + /* 3 <2> Call CNM, check if BOW is available. */ + if (!cnmBowIsPermitted(prAdapter)) { + wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); + return WLAN_STATUS_NOT_ACCEPTED; + } + /* 3 <3> Lookup BOW Table, if Peer MAC address exist and valid -> Fail. */ + if (bowCheckBowTableIfVaild(prAdapter, prBowSetupConnection->aucPeerAddress)) { + wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); + return WLAN_STATUS_NOT_ACCEPTED; + } + + if (EQUAL_MAC_ADDR(prBowSetupConnection->aucPeerAddress, prAdapter->rWifiVar.aucDeviceAddress)) { + wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_INVALID); + return WLAN_STATUS_NOT_ACCEPTED; + } + + /* fill CMD_BT_OVER_WIFI */ + rCmdBtOverWifi.ucAction = BOW_SETUP_CMD; + rCmdBtOverWifi.ucChannelNum = prBowSetupConnection->ucChannelNum; + COPY_MAC_ADDR(rCmdBtOverWifi.rPeerAddr, prBowSetupConnection->aucPeerAddress); + rCmdBtOverWifi.u2BeaconInterval = prBowSetupConnection->u2BeaconInterval; + rCmdBtOverWifi.ucTimeoutDiscovery = prBowSetupConnection->ucTimeoutDiscovery; + rCmdBtOverWifi.ucTimeoutInactivity = prBowSetupConnection->ucTimeoutInactivity; + rCmdBtOverWifi.ucRole = prBowSetupConnection->ucRole; + rCmdBtOverWifi.PAL_Capabilities = prBowSetupConnection->ucPAL_Capabilities; + rCmdBtOverWifi.cMaxTxPower = prBowSetupConnection->cMaxTxPower; + + if (prBowSetupConnection->ucChannelNum > 14) + rCmdBtOverWifi.ucChannelBand = BAND_5G; + else + rCmdBtOverWifi.ucChannelBand = BAND_2G4; + + COPY_MAC_ADDR(prBowFsmInfo->aucPeerAddress, prBowSetupConnection->aucPeerAddress); + +#if CFG_BOW_PHYSICAL_LINK_NUM > 1 + /*Channel check for supporting multiple physical link */ + if (g_u4LinkCount > 0) { + if (prBowSetupConnection->ucChannelNum != prBowFsmInfo->ucPrimaryChannel) { + wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); + return WLAN_STATUS_NOT_ACCEPTED; + } + } +#endif + + prBowFsmInfo->ucPrimaryChannel = prBowSetupConnection->ucChannelNum; + prBowFsmInfo->eBand = rCmdBtOverWifi.ucChannelBand; + prBowFsmInfo->u2BeaconInterval = prBowSetupConnection->u2BeaconInterval; + prBowFsmInfo->ucRole = prBowSetupConnection->ucRole; + + if (prBowSetupConnection->ucPAL_Capabilities > 0) + prBowFsmInfo->fgSupportQoS = TRUE; + + DBGLOG(BOW, EVENT, "bowCmdSetupConnection.\n"); + DBGLOG(BOW, EVENT, "rCmdBtOverWifi Channel Number - 0x%x.\n", rCmdBtOverWifi.ucChannelNum); + DBGLOG(BOW, EVENT, + "rCmdBtOverWifi Peer address - %x:%x:%x:%x:%x:%x.\n", rCmdBtOverWifi.rPeerAddr[0], + rCmdBtOverWifi.rPeerAddr[1], rCmdBtOverWifi.rPeerAddr[2], + rCmdBtOverWifi.rPeerAddr[3], rCmdBtOverWifi.rPeerAddr[4], rCmdBtOverWifi.rPeerAddr[5]); + DBGLOG(BOW, EVENT, "rCmdBtOverWifi Beacon interval - 0x%x.\n", rCmdBtOverWifi.u2BeaconInterval); + DBGLOG(BOW, EVENT, "rCmdBtOverWifi Timeout activity - 0x%x.\n", rCmdBtOverWifi.ucTimeoutDiscovery); + DBGLOG(BOW, EVENT, "rCmdBtOverWifi Timeout inactivity - 0x%x.\n", rCmdBtOverWifi.ucTimeoutInactivity); + DBGLOG(BOW, EVENT, "rCmdBtOverWifi Role - 0x%x.\n", rCmdBtOverWifi.ucRole); + DBGLOG(BOW, EVENT, "rCmdBtOverWifi PAL capability - 0x%x.\n", rCmdBtOverWifi.PAL_Capabilities); + DBGLOG(BOW, EVENT, "rCmdBtOverWifi Max Tx power - 0x%x.\n", rCmdBtOverWifi.cMaxTxPower); + + /* 3 <4> Get a free BOW entry, mark as Valid, fill in Peer MAC address, LinkCount += 1, state == Starting. */ + if (!bowGetBowTableFreeEntry(prAdapter, &ucBowTableIdx)) { + wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); + return WLAN_STATUS_NOT_ACCEPTED; + } + + prBowFsmInfo->prTargetBssDesc = NULL; + + COPY_MAC_ADDR(rBowTable.aucPeerAddress, prBowSetupConnection->aucPeerAddress); + /* owTable.eState = BOW_DEVICE_STATE_ACQUIRING_CHANNEL; */ + rBowTable.fgIsValid = TRUE; + rBowTable.eState = BOW_DEVICE_STATE_NUM; /* Just initiate */ + rBowTable.ucAcquireID = prBowFsmInfo->ucSeqNumOfChReq; + /* rBowTable.ucRole = prBowSetupConnection->ucRole; */ + /* rBowTable.ucChannelNum = prBowSetupConnection->ucChannelNum; */ + bowSetBowTableContent(prAdapter, ucBowTableIdx, &rBowTable); + + kalSetBowRole(prAdapter->prGlueInfo, rCmdBtOverWifi.ucRole, prBowSetupConnection->aucPeerAddress); + + GLUE_INC_REF_CNT(g_u4LinkCount); + + DBGLOG(BOW, EVENT, "bowStarting, g_u4LinkCount, %x.\n", g_u4LinkCount); + + if (g_u4LinkCount == 1) { + DBGLOG(BOW, EVENT, "bowStarting, cnmTimerInitTimer.\n"); + DBGLOG(BOW, EVENT, "prBowFsmInfo->u2BeaconInterval, %d.\n", prBowFsmInfo->u2BeaconInterval); + + cnmTimerInitTimer(prAdapter, + &prBowFsmInfo->rStartingBeaconTimer, + (PFN_MGMT_TIMEOUT_FUNC) bowSendBeacon, (unsigned long) NULL); + + cnmTimerInitTimer(prAdapter, + &prBowFsmInfo->rChGrantedTimer, + (PFN_MGMT_TIMEOUT_FUNC) bowChGrantedTimeout, (unsigned long) NULL); + + /* Reset Global Variable */ + g_u4Beaconing = 0; + + DBGLOG(BOW, EVENT, "bowCmdSetupConnection, g_u4LinkCount, %x.\n", g_u4LinkCount); + DBGLOG(BOW, EVENT, "kalInitBowDevice, bow0\n"); + +#if CFG_BOW_SEPARATE_DATA_PATH + kalInitBowDevice(prAdapter->prGlueInfo, BOWDEVNAME); +#endif + + /*Active BoW Network */ + SET_NET_ACTIVE(prAdapter, prBowFsmInfo->ucBssIndex); + SET_NET_PWR_STATE_ACTIVE(prAdapter, prBowFsmInfo->ucBssIndex); + nicActivateNetwork(prAdapter, prBowFsmInfo->ucBssIndex); + + } + + if (rCmdBtOverWifi.ucRole == BOW_INITIATOR) { + bowSetBowTableState(prAdapter, prBowSetupConnection->aucPeerAddress, + BOW_DEVICE_STATE_ACQUIRING_CHANNEL); + bowRequestCh(prAdapter); + } else { + bowSetBowTableState(prAdapter, prBowSetupConnection->aucPeerAddress, BOW_DEVICE_STATE_SCANNING); + bowResponderScan(prAdapter); + } + + wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_SUCCESS); + + return WLAN_STATUS_SUCCESS; + +#else + return 0; +#endif +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This is command handler for BOW_CMD_ID_DESTROY_CONNECTION +* coming from 802.11 PAL +* +* \param[in] prAdapter Pointer to the Adapter structure. +* \param[in] prCmd Pointer to the buffer that holds the command +* +* \retval WLAN_STATUS_SUCCESS +* \retval WLAN_STATUS_INVALID_LENGTH +*/ +/*----------------------------------------------------------------------------*/ +uint32_t bowCmdDestroyConnection(IN struct ADAPTER *prAdapter, IN struct BT_OVER_WIFI_COMMAND *prCmd) +{ +#if 1 /* Marked for MT6630 */ + struct BOW_DESTROY_CONNECTION *prBowDestroyConnection; + struct CMD_BT_OVER_WIFI rCmdBtOverWifi; + struct BOW_FSM_INFO *prBowFsmInfo; + + uint8_t ucIdx; + + ASSERT(prAdapter); + + prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); + + /* 3 <1> If LinkCount == 0 ->Fail (Optional) */ + if (g_u4LinkCount == 0) { + wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); + return WLAN_STATUS_NOT_ACCEPTED; + } + /* parameter size check */ + if (prCmd->rHeader.u2PayloadLength != sizeof(struct BOW_DESTROY_CONNECTION)) { + wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); + return WLAN_STATUS_INVALID_LENGTH; + } + /* 3 <2> Lookup BOW table, check if is not exist (Valid and Peer MAC address) -> Fail */ + prBowDestroyConnection = (struct BOW_DESTROY_CONNECTION *) &(prCmd->aucPayload[0]); + + if (!bowCheckBowTableIfVaild(prAdapter, prBowDestroyConnection->aucPeerAddress)) { + DBGLOG(BOW, EVENT, "bowCmdDestroyConnection, bowCheckIfVaild, not accepted.\n"); + return WLAN_STATUS_NOT_ACCEPTED; + } + + DBGLOG(BOW, EVENT, + "bowCmdDestroyConnection, destroy Peer address - %x:%x:%x:%x:%x:%x.\n", + prBowDestroyConnection->aucPeerAddress[0], + prBowDestroyConnection->aucPeerAddress[1], + prBowDestroyConnection->aucPeerAddress[2], + prBowDestroyConnection->aucPeerAddress[3], + prBowDestroyConnection->aucPeerAddress[4], prBowDestroyConnection->aucPeerAddress[5]); + + /* fill CMD_BT_OVER_WIFI */ + rCmdBtOverWifi.ucAction = 2; + COPY_MAC_ADDR(rCmdBtOverWifi.rPeerAddr, prBowDestroyConnection->aucPeerAddress); + COPY_MAC_ADDR(prBowFsmInfo->aucPeerAddress, prBowDestroyConnection->aucPeerAddress); + + DBGLOG(BOW, EVENT, + "bowCmdDestroyConnection, rCmdBtOverWifi.rPeerAddr - %x:%x:%x:%x:%x:%x.\n", + rCmdBtOverWifi.rPeerAddr[0], rCmdBtOverWifi.rPeerAddr[1], + rCmdBtOverWifi.rPeerAddr[2], rCmdBtOverWifi.rPeerAddr[3], + rCmdBtOverWifi.rPeerAddr[4], rCmdBtOverWifi.rPeerAddr[5]); + + for (ucIdx = 0; ucIdx < 11; ucIdx++) { + DBGLOG(BOW, EVENT, + "BoW receiving PAL packet delta time vs packet number -- %d ms vs %x.\n", + ucIdx, g_arBowRevPalPacketTime[ucIdx]); + } + + wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_SUCCESS); + + return wlanoidSendSetQueryBowCmd(prAdapter, + CMD_ID_CMD_BT_OVER_WIFI, + prBowFsmInfo->ucBssIndex, + TRUE, + FALSE, + wlanbowCmdEventLinkDisconnected, + wlanbowCmdTimeoutHandler, + sizeof(struct CMD_BT_OVER_WIFI), + (uint8_t *)&rCmdBtOverWifi, prCmd->rHeader.ucSeqNumber); + +#else + return 0; +#endif +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This is command handler for BOW_CMD_ID_SET_PTK +* coming from 802.11 PAL +* +* \param[in] prAdapter Pointer to the Adapter structure. +* \param[in] prCmd Pointer to the buffer that holds the command +* +* \retval WLAN_STATUS_SUCCESS +* \retval WLAN_STATUS_INVALID_LENGTH +*/ +/*----------------------------------------------------------------------------*/ +uint32_t bowCmdSetPTK(IN struct ADAPTER *prAdapter, IN struct BT_OVER_WIFI_COMMAND *prCmd) +{ +#if 1 /* Marked for MT6630 */ + struct BOW_SET_PTK *prBowSetPTK; + struct CMD_802_11_KEY rCmdKey; + struct BOW_FSM_INFO *prBowFsmInfo; + struct STA_RECORD *prStaRec = NULL; + + ASSERT(prAdapter); + + prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); + + /* parameter size check */ + if (prCmd->rHeader.u2PayloadLength != sizeof(struct BOW_SET_PTK)) + return WLAN_STATUS_INVALID_LENGTH; + + prBowSetPTK = (struct BOW_SET_PTK *) &(prCmd->aucPayload[0]); + + DBGLOG(BOW, EVENT, "prBowSetPTK->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", + prBowSetPTK->aucPeerAddress[0], + prBowSetPTK->aucPeerAddress[1], + prBowSetPTK->aucPeerAddress[2], + prBowSetPTK->aucPeerAddress[3], prBowSetPTK->aucPeerAddress[4], prBowSetPTK->aucPeerAddress[5]); + + DBGLOG(BOW, EVENT, + "rCmdKey.ucIsAuthenticator, %x.\n", kalGetBowRole(prAdapter->prGlueInfo, prBowSetPTK->aucPeerAddress)); + + if (!bowCheckBowTableIfVaild(prAdapter, prBowSetPTK->aucPeerAddress)) { + wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); + + return WLAN_STATUS_NOT_ACCEPTED; + } + + if (bowGetBowTableState(prAdapter, prBowSetPTK->aucPeerAddress) != BOW_DEVICE_STATE_CONNECTED) { + wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_FAILURE); + + return WLAN_STATUS_NOT_ACCEPTED; + } + /* fill CMD_802_11_KEY */ + rCmdKey.ucAddRemove = 1; /* add */ + rCmdKey.ucTxKey = 1; + rCmdKey.ucKeyType = 1; + rCmdKey.ucIsAuthenticator = kalGetBowRole(prAdapter->prGlueInfo, prBowSetPTK->aucPeerAddress); + COPY_MAC_ADDR(rCmdKey.aucPeerAddr, prBowSetPTK->aucPeerAddress); + rCmdKey.ucBssIdx = prBowFsmInfo->ucBssIndex; /* BT Over Wi-Fi */ + rCmdKey.ucAlgorithmId = CIPHER_SUITE_CCMP; /* AES */ + rCmdKey.ucKeyId = 0; + rCmdKey.ucKeyLen = 16; /* AES = 128bit */ + kalMemCopy(rCmdKey.aucKeyMaterial, prBowSetPTK->aucTemporalKey, 16); + + /* BT Over Wi-Fi */ + prStaRec = cnmGetStaRecByAddress(prAdapter, prBowFsmInfo->ucBssIndex, prBowSetPTK->aucPeerAddress); + rCmdKey.ucWlanIndex = prStaRec->ucWlanIndex; + + DBGLOG(BOW, EVENT, + "prBowSetPTK->aucTemporalKey, %x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x.\n", + prBowSetPTK->aucTemporalKey[0], prBowSetPTK->aucTemporalKey[1], + prBowSetPTK->aucTemporalKey[2], prBowSetPTK->aucTemporalKey[3], + prBowSetPTK->aucTemporalKey[4], prBowSetPTK->aucTemporalKey[5], + prBowSetPTK->aucTemporalKey[6], prBowSetPTK->aucTemporalKey[7], + prBowSetPTK->aucTemporalKey[8], prBowSetPTK->aucTemporalKey[9], + prBowSetPTK->aucTemporalKey[10], prBowSetPTK->aucTemporalKey[11], + prBowSetPTK->aucTemporalKey[12], prBowSetPTK->aucTemporalKey[13], + prBowSetPTK->aucTemporalKey[14], prBowSetPTK->aucTemporalKey[15]); + + DBGLOG(BOW, EVENT, + "rCmdKey.aucKeyMaterial, %x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x.\n", + rCmdKey.aucKeyMaterial[0], rCmdKey.aucKeyMaterial[1], rCmdKey.aucKeyMaterial[2], + rCmdKey.aucKeyMaterial[3], rCmdKey.aucKeyMaterial[4], rCmdKey.aucKeyMaterial[5], + rCmdKey.aucKeyMaterial[6], rCmdKey.aucKeyMaterial[7], rCmdKey.aucKeyMaterial[8], + rCmdKey.aucKeyMaterial[9], rCmdKey.aucKeyMaterial[10], rCmdKey.aucKeyMaterial[11], + rCmdKey.aucKeyMaterial[12], rCmdKey.aucKeyMaterial[13], rCmdKey.aucKeyMaterial[14], + rCmdKey.aucKeyMaterial[15]); + + return wlanoidSendSetQueryBowCmd(prAdapter, + CMD_ID_ADD_REMOVE_KEY, + prBowFsmInfo->ucBssIndex, + TRUE, + FALSE, + wlanbowCmdEventSetCommon, + wlanbowCmdTimeoutHandler, + sizeof(struct CMD_802_11_KEY), (uint8_t *)&rCmdKey, prCmd->rHeader.ucSeqNumber); +#else + return 0; +#endif +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This is command handler for BOW_CMD_ID_READ_RSSI +* coming from 802.11 PAL +* +* \param[in] prAdapter Pointer to the Adapter structure. +* \param[in] prCmd Pointer to the buffer that holds the command +* +* \retval WLAN_STATUS_SUCCESS +* \retval WLAN_STATUS_INVALID_LENGTH +*/ +/*----------------------------------------------------------------------------*/ +uint32_t bowCmdReadRSSI(IN struct ADAPTER *prAdapter, IN struct BT_OVER_WIFI_COMMAND *prCmd) +{ +#if 1 /* Marked for MT6630 */ + struct BOW_READ_RSSI *prBowReadRSSI; + struct BOW_FSM_INFO *prBowFsmInfo; + + ASSERT(prAdapter); + + if (prAdapter->fgIsEnableLpdvt) + return WLAN_STATUS_NOT_SUPPORTED; + + prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); + + /* parameter size check */ + if (prCmd->rHeader.u2PayloadLength != sizeof(struct BOW_READ_RSSI)) + return WLAN_STATUS_INVALID_LENGTH; + + prBowReadRSSI = (struct BOW_READ_RSSI *) &(prCmd->aucPayload[0]); + + return wlanoidSendSetQueryBowCmd(prAdapter, + CMD_ID_GET_LINK_QUALITY, + prBowFsmInfo->ucBssIndex, + FALSE, + TRUE, + wlanbowCmdEventReadRssi, + wlanbowCmdTimeoutHandler, 0, NULL, prCmd->rHeader.ucSeqNumber); + +#else + return 0; +#endif +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This is command handler for BOW_CMD_ID_READ_LINK_QUALITY +* coming from 802.11 PAL +* +* \param[in] prAdapter Pointer to the Adapter structure. +* \param[in] prCmd Pointer to the buffer that holds the command +* +* \retval WLAN_STATUS_SUCCESS +* \retval WLAN_STATUS_INVALID_LENGTH +*/ +/*----------------------------------------------------------------------------*/ +uint32_t bowCmdReadLinkQuality(IN struct ADAPTER *prAdapter, IN struct BT_OVER_WIFI_COMMAND *prCmd) +{ +#if 1 /* Marked for MT6630 */ + struct BOW_READ_LINK_QUALITY *prBowReadLinkQuality; + struct BOW_FSM_INFO *prBowFsmInfo; + + ASSERT(prAdapter); + + if (prAdapter->fgIsEnableLpdvt) + return WLAN_STATUS_NOT_SUPPORTED; + + prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); + + /* parameter size check */ + if (prCmd->rHeader.u2PayloadLength != sizeof(struct BOW_READ_LINK_QUALITY *)) + return WLAN_STATUS_INVALID_LENGTH; + + prBowReadLinkQuality = (struct BOW_READ_LINK_QUALITY *) &(prCmd->aucPayload[0]); + + return wlanoidSendSetQueryBowCmd(prAdapter, + CMD_ID_GET_LINK_QUALITY, + prBowFsmInfo->ucBssIndex, + FALSE, + TRUE, + wlanbowCmdEventReadLinkQuality, + wlanbowCmdTimeoutHandler, 0, NULL, prCmd->rHeader.ucSeqNumber); + +#else + return 0; +#endif +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This is command handler for BOW_CMD_ID_SHORT_RANGE_MODE +* coming from 802.11 PAL +* +* \param[in] prAdapter Pointer to the Adapter structure. +* \param[in] prCmd Pointer to the buffer that holds the command +* +* \retval WLAN_STATUS_SUCCESS +* \retval WLAN_STATUS_INVALID_LENGTH +*/ +/*----------------------------------------------------------------------------*/ +uint32_t bowCmdShortRangeMode(IN struct ADAPTER *prAdapter, IN struct BT_OVER_WIFI_COMMAND *prCmd) +{ +#if 1 /* Marked for MT6630 */ + struct BOW_SHORT_RANGE_MODE *prBowShortRangeMode; + struct CMD_TX_PWR rTxPwrParam; + + ASSERT(prAdapter); + + DBGLOG(BOW, EVENT, "bowCmdShortRangeMode.\n"); + + prBowShortRangeMode = (struct BOW_SHORT_RANGE_MODE *) &(prCmd->aucPayload[0]); + + /* parameter size check */ + if (prCmd->rHeader.u2PayloadLength != sizeof(struct BOW_SHORT_RANGE_MODE)) { + wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); + return WLAN_STATUS_INVALID_LENGTH; + } + + if (!bowCheckBowTableIfVaild(prAdapter, prBowShortRangeMode->aucPeerAddress)) { + wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); + return WLAN_STATUS_NOT_ACCEPTED; + } + + if (bowGetBowTableState(prAdapter, prBowShortRangeMode->aucPeerAddress) != BOW_DEVICE_STATE_CONNECTED) { + wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_FAILURE); + return WLAN_STATUS_NOT_ACCEPTED; + } + + DBGLOG(BOW, EVENT, "prBowShortRangeMode->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", + prBowShortRangeMode->aucPeerAddress[0], + prBowShortRangeMode->aucPeerAddress[1], + prBowShortRangeMode->aucPeerAddress[2], + prBowShortRangeMode->aucPeerAddress[3], + prBowShortRangeMode->aucPeerAddress[4], prBowShortRangeMode->aucPeerAddress[5]); + + rTxPwrParam.cTxPwr2G4Cck = (prBowShortRangeMode->cTxPower << 1); + + rTxPwrParam.cTxPwr2G4OFDM_BPSK = (prBowShortRangeMode->cTxPower << 1); + rTxPwrParam.cTxPwr2G4OFDM_QPSK = (prBowShortRangeMode->cTxPower << 1); + rTxPwrParam.cTxPwr2G4OFDM_16QAM = (prBowShortRangeMode->cTxPower << 1); + + rTxPwrParam.cTxPwr2G4OFDM_48Mbps = (prBowShortRangeMode->cTxPower << 1); + rTxPwrParam.cTxPwr2G4OFDM_54Mbps = (prBowShortRangeMode->cTxPower << 1); + + rTxPwrParam.cTxPwr2G4HT20_BPSK = (prBowShortRangeMode->cTxPower << 1); + rTxPwrParam.cTxPwr2G4HT20_QPSK = (prBowShortRangeMode->cTxPower << 1); + rTxPwrParam.cTxPwr2G4HT20_16QAM = (prBowShortRangeMode->cTxPower << 1); + rTxPwrParam.cTxPwr2G4HT20_MCS5 = (prBowShortRangeMode->cTxPower << 1); + rTxPwrParam.cTxPwr2G4HT20_MCS6 = (prBowShortRangeMode->cTxPower << 1); + rTxPwrParam.cTxPwr2G4HT20_MCS7 = (prBowShortRangeMode->cTxPower << 1); + + rTxPwrParam.cTxPwr2G4HT40_BPSK = (prBowShortRangeMode->cTxPower << 1); + rTxPwrParam.cTxPwr2G4HT40_QPSK = (prBowShortRangeMode->cTxPower << 1); + rTxPwrParam.cTxPwr2G4HT40_16QAM = (prBowShortRangeMode->cTxPower << 1); + rTxPwrParam.cTxPwr2G4HT40_MCS5 = (prBowShortRangeMode->cTxPower << 1); + rTxPwrParam.cTxPwr2G4HT40_MCS6 = (prBowShortRangeMode->cTxPower << 1); + rTxPwrParam.cTxPwr2G4HT40_MCS7 = (prBowShortRangeMode->cTxPower << 1); + + rTxPwrParam.cTxPwr5GOFDM_BPSK = (prBowShortRangeMode->cTxPower << 1); + rTxPwrParam.cTxPwr5GOFDM_QPSK = (prBowShortRangeMode->cTxPower << 1); + rTxPwrParam.cTxPwr5GOFDM_16QAM = (prBowShortRangeMode->cTxPower << 1); + rTxPwrParam.cTxPwr5GOFDM_48Mbps = (prBowShortRangeMode->cTxPower << 1); + rTxPwrParam.cTxPwr5GOFDM_54Mbps = (prBowShortRangeMode->cTxPower << 1); + + rTxPwrParam.cTxPwr5GHT20_BPSK = (prBowShortRangeMode->cTxPower << 1); + rTxPwrParam.cTxPwr5GHT20_QPSK = (prBowShortRangeMode->cTxPower << 1); + rTxPwrParam.cTxPwr5GHT20_16QAM = (prBowShortRangeMode->cTxPower << 1); + rTxPwrParam.cTxPwr5GHT20_MCS5 = (prBowShortRangeMode->cTxPower << 1); + rTxPwrParam.cTxPwr5GHT20_MCS6 = (prBowShortRangeMode->cTxPower << 1); + rTxPwrParam.cTxPwr5GHT20_MCS7 = (prBowShortRangeMode->cTxPower << 1); + rTxPwrParam.cTxPwr5GHT40_BPSK = (prBowShortRangeMode->cTxPower << 1); + rTxPwrParam.cTxPwr5GHT40_QPSK = (prBowShortRangeMode->cTxPower << 1); + rTxPwrParam.cTxPwr5GHT40_16QAM = (prBowShortRangeMode->cTxPower << 1); + rTxPwrParam.cTxPwr5GHT40_MCS5 = (prBowShortRangeMode->cTxPower << 1); + rTxPwrParam.cTxPwr5GHT40_MCS6 = (prBowShortRangeMode->cTxPower << 1); + rTxPwrParam.cTxPwr5GHT40_MCS7 = (prBowShortRangeMode->cTxPower << 1); + + if (nicUpdateTxPower(prAdapter, &rTxPwrParam) == WLAN_STATUS_SUCCESS) { + DBGLOG(BOW, EVENT, "bowCmdShortRangeMode, %x.\n", WLAN_STATUS_SUCCESS); + wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_SUCCESS); + return WLAN_STATUS_SUCCESS; + } + wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_FAILURE); + return WLAN_STATUS_FAILURE; + +#else + return 0; +#endif +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This is command handler for BOW_CMD_ID_GET_CHANNEL_LIST +* coming from 802.11 PAL +* +* \param[in] prAdapter Pointer to the Adapter structure. +* \param[in] prCmd Pointer to the buffer that holds the command +* +* \retval WLAN_STATUS_SUCCESS +* \retval WLAN_STATUS_INVALID_LENGTH +*/ +/*----------------------------------------------------------------------------*/ +uint32_t bowCmdGetChannelList(IN struct ADAPTER *prAdapter, IN struct BT_OVER_WIFI_COMMAND *prCmd) +{ + ASSERT(prAdapter); + + /* not supported yet */ + return WLAN_STATUS_FAILURE; +} + +#if 1 /* Marked for MT6630 */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This is generic command done handler +* +* \param[in] prAdapter Pointer to the Adapter structure. +* \param[in] prCmdInfo Pointer to the buffer that holds the command info +* \param[in] pucEventBuf Pointer to the set buffer OR event buffer +* +* \retval none +*/ +/*----------------------------------------------------------------------------*/ +void wlanbowCmdEventSetStatus(IN struct ADAPTER *prAdapter, IN struct BT_OVER_WIFI_COMMAND *prCmd, IN uint8_t ucEventBuf) +{ + struct BT_OVER_WIFI_EVENT *prEvent; + struct BOW_COMMAND_STATUS *prBowCmdStatus; + + ASSERT(prAdapter); + + /* fill event header */ + prEvent = (struct BT_OVER_WIFI_EVENT *) kalMemAlloc((sizeof(struct BT_OVER_WIFI_EVENT) + sizeof(struct BOW_COMMAND_STATUS)), VIR_MEM_TYPE); + prEvent->rHeader.ucEventId = BOW_EVENT_ID_COMMAND_STATUS; + prEvent->rHeader.ucSeqNumber = prCmd->rHeader.ucSeqNumber; + prEvent->rHeader.u2PayloadLength = sizeof(struct BOW_COMMAND_STATUS); + + /* fill event body */ + prBowCmdStatus = (struct BOW_COMMAND_STATUS *) (prEvent->aucPayload); + kalMemZero(prBowCmdStatus, sizeof(struct BOW_COMMAND_STATUS)); + + prBowCmdStatus->ucStatus = ucEventBuf; + + kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); + + kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(struct BT_OVER_WIFI_EVENT) + sizeof(struct BOW_COMMAND_STATUS))); +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This is generic command done handler +* +* \param[in] prAdapter Pointer to the Adapter structure. +* \param[in] prCmdInfo Pointer to the buffer that holds the command info +* \param[in] pucEventBuf Pointer to the set buffer OR event buffer +* +* \retval none +*/ +/*----------------------------------------------------------------------------*/ +void wlanbowCmdEventSetCommon(IN struct ADAPTER *prAdapter, IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf) +{ + struct BT_OVER_WIFI_EVENT *prEvent; + struct BOW_COMMAND_STATUS *prBowCmdStatus; + + ASSERT(prAdapter); + + /* fill event header */ + prEvent = (struct BT_OVER_WIFI_EVENT *) kalMemAlloc((sizeof(struct BT_OVER_WIFI_EVENT) + sizeof(struct BOW_COMMAND_STATUS)), VIR_MEM_TYPE); + prEvent->rHeader.ucEventId = BOW_EVENT_ID_COMMAND_STATUS; + prEvent->rHeader.ucSeqNumber = (uint8_t) prCmdInfo->u4PrivateData; + prEvent->rHeader.u2PayloadLength = sizeof(struct BOW_COMMAND_STATUS); + + /* fill event body */ + prBowCmdStatus = (struct BOW_COMMAND_STATUS *) (prEvent->aucPayload); + kalMemZero(prBowCmdStatus, sizeof(struct BOW_COMMAND_STATUS)); + + prBowCmdStatus->ucStatus = BOWCMD_STATUS_SUCCESS; + + kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); + + kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(struct BT_OVER_WIFI_EVENT) + sizeof(struct BOW_COMMAND_STATUS))); +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief command done handler for CMD_ID_CMD_BT_OVER_WIFI +* +* \param[in] prAdapter Pointer to the Adapter structure. +* \param[in] prCmdInfo Pointer to the buffer that holds the command info +* \param[in] pucEventBuf Pointer to the set buffer OR event buffer +* +* \retval none +*/ +/*----------------------------------------------------------------------------*/ +void wlanbowCmdEventLinkConnected(IN struct ADAPTER *prAdapter, IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf) +{ + struct BT_OVER_WIFI_EVENT *prEvent; + struct BOW_LINK_CONNECTED *prBowLinkConnected; + struct BOW_FSM_INFO *prBowFsmInfo; + struct BSS_INFO *prBssInfo; + + ASSERT(prAdapter); + + prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prBowFsmInfo->ucBssIndex); + + /* fill event header */ + prEvent = (struct BT_OVER_WIFI_EVENT *) kalMemAlloc((sizeof(struct BT_OVER_WIFI_EVENT) + sizeof(struct BOW_LINK_CONNECTED)), VIR_MEM_TYPE); + prEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_CONNECTED; + prEvent->rHeader.ucSeqNumber = (uint8_t) prCmdInfo->u4PrivateData; + prEvent->rHeader.u2PayloadLength = sizeof(struct BOW_LINK_CONNECTED); + + /* fill event body */ + prBowLinkConnected = (struct BOW_LINK_CONNECTED *) (prEvent->aucPayload); + kalMemZero(prBowLinkConnected, sizeof(struct BOW_LINK_CONNECTED)); + prBowLinkConnected->rChannel.ucChannelNum = prBssInfo->ucPrimaryChannel; + prBowLinkConnected->rChannel.ucChannelBand = prBssInfo->eBand; + COPY_MAC_ADDR(prBowLinkConnected->aucPeerAddress, prBowFsmInfo->aucPeerAddress); + + DBGLOG(BOW, EVENT, "prEvent->rHeader.ucEventId, 0x%x\n", prEvent->rHeader.ucEventId); + DBGLOG(BOW, EVENT, "prEvent->rHeader.ucSeqNumber, 0x%x\n", prEvent->rHeader.ucSeqNumber); + DBGLOG(BOW, EVENT, "prEvent->rHeader.u2PayloadLength, 0x%x\n", prEvent->rHeader.u2PayloadLength); + DBGLOG(BOW, EVENT, + "prBowLinkConnected->rChannel.ucChannelNum, 0x%x\n", prBowLinkConnected->rChannel.ucChannelNum); + DBGLOG(BOW, EVENT, + "prBowLinkConnected->rChannel.ucChannelBand, 0x%x\n", prBowLinkConnected->rChannel.ucChannelBand); + DBGLOG(BOW, EVENT, + "wlanbowCmdEventLinkConnected, prBowFsmInfo->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", + prBowFsmInfo->aucPeerAddress[0], prBowFsmInfo->aucPeerAddress[1], + prBowFsmInfo->aucPeerAddress[2], prBowFsmInfo->aucPeerAddress[3], + prBowFsmInfo->aucPeerAddress[4], prBowFsmInfo->aucPeerAddress[5]); + DBGLOG(BOW, EVENT, + "wlanbowCmdEventLinkConnected, prBowLinkConnected->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", + prBowLinkConnected->aucPeerAddress[0], prBowLinkConnected->aucPeerAddress[1], + prBowLinkConnected->aucPeerAddress[2], prBowLinkConnected->aucPeerAddress[3], + prBowLinkConnected->aucPeerAddress[4], prBowLinkConnected->aucPeerAddress[5]); + DBGLOG(BOW, EVENT, "wlanbowCmdEventLinkConnected, g_u4LinkCount, %x.\n", g_u4LinkCount); + + /*Indicate Event to PAL */ + kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); + kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(struct BT_OVER_WIFI_EVENT) + sizeof(struct BOW_LINK_CONNECTED))); + + /*Release channel if granted */ + if (prBowFsmInfo->fgIsChannelGranted) { + cnmTimerStopTimer(prAdapter, &prBowFsmInfo->rChGrantedTimer); + /* bowReleaseCh(prAdapter); */ + /*Requested, not granted yet */ + } else if (prBowFsmInfo->fgIsChannelRequested) { + prBowFsmInfo->fgIsChannelRequested = FALSE; + } + + /* set to connected status */ + bowSetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress, BOW_DEVICE_STATE_CONNECTED); + +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief command done handler for CMD_ID_CMD_BT_OVER_WIFI +* +* \param[in] prAdapter Pointer to the Adapter structure. +* \param[in] prCmdInfo Pointer to the buffer that holds the command info +* \param[in] pucEventBuf Pointer to the set buffer OR event buffer +* +* \retval none +*/ +/*----------------------------------------------------------------------------*/ +void wlanbowCmdEventLinkDisconnected(IN struct ADAPTER *prAdapter, IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf) +{ + struct BT_OVER_WIFI_EVENT *prEvent; + struct BOW_LINK_DISCONNECTED *prBowLinkDisconnected; + struct BOW_FSM_INFO *prBowFsmInfo; + struct BOW_TABLE rBowTable; + uint8_t ucBowTableIdx; + enum ENUM_BOW_DEVICE_STATE eFsmState; + u_int8_t fgSendDeauth = FALSE; + + ASSERT(prAdapter); + + prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); + eFsmState = bowGetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress); + + if (eFsmState == BOW_DEVICE_STATE_DISCONNECTED) { + /*do nothing */ + return; + } + /*Cancel scan */ + else if (eFsmState == BOW_DEVICE_STATE_SCANNING && !(prBowFsmInfo->fgIsChannelRequested)) { + bowResponderCancelScan(prAdapter, FALSE); + bowSetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress, BOW_DEVICE_STATE_DISCONNECTING); + return; + } + /* fill event header */ + prEvent = (struct BT_OVER_WIFI_EVENT *) kalMemAlloc((sizeof(struct BT_OVER_WIFI_EVENT) + sizeof(struct BOW_LINK_DISCONNECTED)), VIR_MEM_TYPE); + prEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_DISCONNECTED; + if ((prCmdInfo->u4PrivateData)) + prEvent->rHeader.ucSeqNumber = (uint8_t) prCmdInfo->u4PrivateData; + else + prEvent->rHeader.ucSeqNumber = 0; + + prEvent->rHeader.u2PayloadLength = sizeof(struct BOW_LINK_DISCONNECTED); + + /* fill event body */ + prBowLinkDisconnected = (struct BOW_LINK_DISCONNECTED *) (prEvent->aucPayload); + kalMemZero(prBowLinkDisconnected, sizeof(struct BOW_LINK_DISCONNECTED)); + prBowLinkDisconnected->ucReason = 0x0; + COPY_MAC_ADDR(prBowLinkDisconnected->aucPeerAddress, prBowFsmInfo->aucPeerAddress); + + DBGLOG(BOW, EVENT, "prEvent->rHeader.ucEventId, 0x%x\n", prEvent->rHeader.ucEventId); + DBGLOG(BOW, EVENT, "prEvent->rHeader.ucSeqNumber, 0x%x\n", prEvent->rHeader.ucSeqNumber); + DBGLOG(BOW, EVENT, "prEvent->rHeader.u2PayloadLength, 0x%x\n", prEvent->rHeader.u2PayloadLength); + + DBGLOG(BOW, EVENT, + "wlanbowCmdEventLinkDisconnected, prBowFsmInfo->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", + prBowFsmInfo->aucPeerAddress[0], prBowFsmInfo->aucPeerAddress[1], + prBowFsmInfo->aucPeerAddress[2], prBowFsmInfo->aucPeerAddress[3], + prBowFsmInfo->aucPeerAddress[4], prBowFsmInfo->aucPeerAddress[5]); + + DBGLOG(BOW, EVENT, + "wlanbowCmdEventLinkDisconnected, prBowLinkDisconnected->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", + prBowLinkDisconnected->aucPeerAddress[0], prBowLinkDisconnected->aucPeerAddress[1], + prBowLinkDisconnected->aucPeerAddress[2], prBowLinkDisconnected->aucPeerAddress[3], + prBowLinkDisconnected->aucPeerAddress[4], prBowLinkDisconnected->aucPeerAddress[5]); + + DBGLOG(BOW, EVENT, "wlanbowCmdEventLinkDisconnected, g_u4LinkCount, %x.\n", g_u4LinkCount); + + /*Indicate BoW event to PAL */ +#if 0 + kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); + kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(struct BT_OVER_WIFI_EVENT) + sizeof(struct BOW_LINK_DISCONNECTED))); +#endif + + /* set to disconnected status */ + prBowFsmInfo->prTargetStaRec = + cnmGetStaRecByAddress(prAdapter, prBowFsmInfo->ucBssIndex, prBowLinkDisconnected->aucPeerAddress); + + /*Release channel if granted */ + if (prBowFsmInfo->fgIsChannelGranted) { + cnmTimerStopTimer(prAdapter, &prBowFsmInfo->rChGrantedTimer); + bowReleaseCh(prAdapter); + /*Requested, not granted yet */ + } else if (prBowFsmInfo->fgIsChannelRequested) { + prBowFsmInfo->fgIsChannelRequested = FALSE; + /* bowReleaseCh(prAdapter); */ + } +#if 1 + /*Send Deauth to connected peer */ + if (eFsmState == BOW_DEVICE_STATE_CONNECTED && (prBowFsmInfo->prTargetStaRec->ucStaState == STA_STATE_3)) { + fgSendDeauth = TRUE; + DBGLOG(BOW, EVENT, + "wlanbowCmdEventLinkDisconnected, bowGetBowTableState, %x.\n", + bowGetBowTableState(prAdapter, prBowLinkDisconnected->aucPeerAddress)); + authSendDeauthFrame(prAdapter, NULL, prBowFsmInfo->prTargetStaRec, + (struct SW_RFB *) NULL, REASON_CODE_DEAUTH_LEAVING_BSS, + (PFN_TX_DONE_HANDLER) bowDisconnectLink); + } +#endif + +#if 0 + /* 3 <3>Stop this link; flush Tx; + * send deAuthentication -> abort. SAA, AAA. need to check BOW table state == Connected. + */ + if (prAdapter->prGlueInfo->i4TxPendingFrameNum > 0) + kalFlushPendingTxPackets(prAdapter->prGlueInfo); + + /* flush pending security frames */ + if (prAdapter->prGlueInfo->i4TxPendingSecurityFrameNum > 0) + kalClearSecurityFrames(prAdapter->prGlueInfo); +#endif + + /*Update BoW table */ + bowGetBowTableEntryByPeerAddress(prAdapter, prBowLinkDisconnected->aucPeerAddress, &ucBowTableIdx); + rBowTable.fgIsValid = FALSE; + rBowTable.eState = BOW_DEVICE_STATE_DISCONNECTED; + rBowTable.ucAcquireID = 0; /* Just initiate */ + bowSetBowTableContent(prAdapter, ucBowTableIdx, &rBowTable); + + /*Indicate BoW event to PAL */ + kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); + kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(struct BT_OVER_WIFI_EVENT) + sizeof(struct BOW_LINK_DISCONNECTED))); + + /*Decrease link count */ + GLUE_DEC_REF_CNT(g_u4LinkCount); + + /*If no need to send deauth, DO disconnect now */ + /*If need to send deauth, DO disconnect at deauth Tx done */ + if (!fgSendDeauth) + bowDisconnectLink(prAdapter, NULL, TX_RESULT_SUCCESS); +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief command done handler for CMD_ID_CMD_BT_OVER_WIFI +* +* \param[in] prAdapter Pointer to the Adapter structure. +* \param[in] prCmdInfo Pointer to the buffer that holds the command info +* \param[in] pucEventBuf Pointer to the set buffer OR event buffer +* +* \retval none +*/ +/*----------------------------------------------------------------------------*/ +void wlanbowCmdEventSetSetupConnection(IN struct ADAPTER *prAdapter, IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf) +{ + struct BT_OVER_WIFI_EVENT *prEvent; + struct BOW_COMMAND_STATUS *prBowCmdStatus; + struct WIFI_CMD *prWifiCmd; + struct CMD_BT_OVER_WIFI *prCmdBtOverWifi; + struct BOW_FSM_INFO *prBowFsmInfo; + + ASSERT(prAdapter); + + prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); + + /* restore original command for rPeerAddr */ + prWifiCmd = (struct WIFI_CMD *) (prCmdInfo->pucInfoBuffer); + prCmdBtOverWifi = (struct CMD_BT_OVER_WIFI *) (prWifiCmd->aucBuffer); + + /* fill event header */ + prEvent = (struct BT_OVER_WIFI_EVENT *) kalMemAlloc((sizeof(struct BT_OVER_WIFI_EVENT) + sizeof(struct BOW_COMMAND_STATUS)), VIR_MEM_TYPE); + prEvent->rHeader.ucEventId = BOW_EVENT_ID_COMMAND_STATUS; + prEvent->rHeader.ucSeqNumber = (uint8_t) prCmdInfo->u4PrivateData; + prEvent->rHeader.u2PayloadLength = sizeof(struct BOW_COMMAND_STATUS); + + /* fill event body */ + prBowCmdStatus = (struct BOW_COMMAND_STATUS *) (prEvent->aucPayload); + kalMemZero(prBowCmdStatus, sizeof(struct BOW_COMMAND_STATUS)); + prBowCmdStatus->ucStatus = BOWCMD_STATUS_SUCCESS; + + /*Indicate BoW event to PAL */ + kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); + kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(struct BT_OVER_WIFI_EVENT) + sizeof(struct BOW_COMMAND_STATUS))); + + /* set to starting status */ + kalSetBowState(prAdapter->prGlueInfo, BOW_DEVICE_STATE_STARTING, prCmdBtOverWifi->rPeerAddr); +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This is the command done handler for BOW_CMD_ID_READ_LINK_QUALITY +* +* \param[in] prAdapter Pointer to the Adapter structure. +* \param[in] prCmdInfo Pointer to the buffer that holds the command info +* \param[in] pucEventBuf Pointer to the set buffer OR event buffer +* +* \retval none +*/ +/*----------------------------------------------------------------------------*/ +void wlanbowCmdEventReadLinkQuality(IN struct ADAPTER *prAdapter, IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf) +{ + struct LINK_QUALITY *prLinkQuality; + struct BT_OVER_WIFI_EVENT *prEvent; + struct BOW_LINK_QUALITY *prBowLinkQuality; + + ASSERT(prAdapter); + + prLinkQuality = (struct LINK_QUALITY *) pucEventBuf; + + /* fill event header */ + prEvent = (struct BT_OVER_WIFI_EVENT *) kalMemAlloc((sizeof(struct BT_OVER_WIFI_EVENT) + sizeof(struct BOW_LINK_QUALITY)), VIR_MEM_TYPE); + prEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_QUALITY; + prEvent->rHeader.ucSeqNumber = (uint8_t) prCmdInfo->u4PrivateData; + prEvent->rHeader.u2PayloadLength = sizeof(struct BOW_LINK_QUALITY); + + /* fill event body */ + prBowLinkQuality = (struct BOW_LINK_QUALITY *) (prEvent->aucPayload); + kalMemZero(prBowLinkQuality, sizeof(struct BOW_LINK_QUALITY)); + prBowLinkQuality->ucLinkQuality = (uint8_t) prLinkQuality->cLinkQuality; + + kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); + + kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(struct BT_OVER_WIFI_EVENT) + sizeof(struct BOW_LINK_QUALITY))); +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This is the command done handler for BOW_CMD_ID_READ_RSSI +* +* \param[in] prAdapter Pointer to the Adapter structure. +* \param[in] prCmdInfo Pointer to the buffer that holds the command info +* \param[in] pucEventBuf Pointer to the set buffer OR event buffer +* +* \retval none +*/ +/*----------------------------------------------------------------------------*/ +void wlanbowCmdEventReadRssi(IN struct ADAPTER *prAdapter, IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf) +{ + struct LINK_QUALITY *prLinkQuality; + struct BT_OVER_WIFI_EVENT *prEvent; + struct BOW_RSSI *prBowRssi; + + ASSERT(prAdapter); + + prLinkQuality = (struct LINK_QUALITY *) pucEventBuf; + + /* fill event header */ + prEvent = (struct BT_OVER_WIFI_EVENT *) kalMemAlloc((sizeof(struct BT_OVER_WIFI_EVENT) + sizeof(struct BOW_LINK_QUALITY)), VIR_MEM_TYPE); + prEvent->rHeader.ucEventId = BOW_EVENT_ID_RSSI; + prEvent->rHeader.ucSeqNumber = (uint8_t) prCmdInfo->u4PrivateData; + prEvent->rHeader.u2PayloadLength = sizeof(struct BOW_RSSI); + + /* fill event body */ + prBowRssi = (struct BOW_RSSI *) (prEvent->aucPayload); + kalMemZero(prBowRssi, sizeof(struct BOW_RSSI)); + prBowRssi->cRssi = (int8_t) prLinkQuality->cRssi; + + kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); + + kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(struct BT_OVER_WIFI_EVENT) + sizeof(struct BOW_LINK_QUALITY))); + +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This is the default command timeout handler +* +* \param[in] prAdapter Pointer to the Adapter structure. +* \param[in] prCmdInfo Pointer to the buffer that holds the command info +* +* \retval none +*/ +/*----------------------------------------------------------------------------*/ +void wlanbowCmdTimeoutHandler(IN struct ADAPTER *prAdapter, IN struct CMD_INFO *prCmdInfo) +{ + struct BT_OVER_WIFI_EVENT *prEvent; + struct BOW_COMMAND_STATUS *prBowCmdStatus; + + ASSERT(prAdapter); + + /* fill event header */ + prEvent = (struct BT_OVER_WIFI_EVENT *) kalMemAlloc((sizeof(struct BT_OVER_WIFI_EVENT) + sizeof(struct BOW_COMMAND_STATUS)), VIR_MEM_TYPE); + prEvent->rHeader.ucEventId = BOW_EVENT_ID_COMMAND_STATUS; + prEvent->rHeader.ucSeqNumber = (uint8_t) prCmdInfo->u4PrivateData; + prEvent->rHeader.u2PayloadLength = sizeof(struct BOW_COMMAND_STATUS); + + /* fill event body */ + prBowCmdStatus = (struct BOW_COMMAND_STATUS *) (prEvent->aucPayload); + kalMemZero(prBowCmdStatus, sizeof(struct BOW_COMMAND_STATUS)); + + prBowCmdStatus->ucStatus = BOWCMD_STATUS_TIMEOUT; /* timeout */ + + kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); + + kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(struct BT_OVER_WIFI_EVENT) + sizeof(struct BOW_COMMAND_STATUS))); + +} + +/* Bruce, 20140224 */ +uint8_t bowInit(IN struct ADAPTER *prAdapter) +{ + struct BSS_INFO *prBowBssInfo; + struct BOW_FSM_INFO *prBowFsmInfo; + + ASSERT(prAdapter); + + prBowBssInfo = cnmGetBssInfoAndInit(prAdapter, NETWORK_TYPE_BOW, TRUE); + + /*Initiate BSS_INFO_T - common part -move from bowstarting */ + BSS_INFO_INIT(prAdapter, prBowBssInfo); + + prBowBssInfo->eCurrentOPMode = OP_MODE_BOW; + + prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); + prBowFsmInfo->ucBssIndex = prBowBssInfo->ucBssIndex; + + /* Setup Own MAC & BSSID */ + COPY_MAC_ADDR(prBowBssInfo->aucOwnMacAddr, prAdapter->rWifiVar.aucDeviceAddress); + COPY_MAC_ADDR(prBowBssInfo->aucBSSID, prAdapter->rWifiVar.aucDeviceAddress); + + return prBowBssInfo->ucBssIndex; +} + +/* Bruce, 20140224 */ +void bowUninit(IN struct ADAPTER *prAdapter) +{ + struct BSS_INFO *prBowBssInfo; + struct BOW_FSM_INFO *prBowFsmInfo; + + prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); + prBowBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prBowFsmInfo->ucBssIndex); + + cnmFreeBssInfo(prAdapter, prBowBssInfo); +} + +void bowStopping(IN struct ADAPTER *prAdapter) +{ + struct BOW_FSM_INFO *prBowFsmInfo; + struct BSS_INFO *prBowBssInfo; + + ASSERT(prAdapter); + + prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); + prBowBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prBowFsmInfo->ucBssIndex); + + DBGLOG(BOW, EVENT, "bowStoping.\n"); + DBGLOG(BOW, EVENT, "bowStoping, SSID %s.\n", prBowBssInfo->aucSSID); + DBGLOG(BOW, EVENT, "bowStoping, prBowBssInfo->aucBSSID, %x:%x:%x:%x:%x:%x.\n", + prBowBssInfo->aucBSSID[0], + prBowBssInfo->aucBSSID[1], + prBowBssInfo->aucBSSID[2], + prBowBssInfo->aucBSSID[3], prBowBssInfo->aucBSSID[4], prBowBssInfo->aucBSSID[5]); + DBGLOG(BOW, EVENT, "bowStoping, prBssInfo->aucOwnMacAddr, %x:%x:%x:%x:%x:%x.\n", + prBowBssInfo->aucOwnMacAddr[0], + prBowBssInfo->aucOwnMacAddr[1], + prBowBssInfo->aucOwnMacAddr[2], + prBowBssInfo->aucOwnMacAddr[3], prBowBssInfo->aucOwnMacAddr[4], prBowBssInfo->aucOwnMacAddr[5]); + DBGLOG(BOW, EVENT, + "bowStoping, prAdapter->rWifiVar.aucDeviceAddress, %x:%x:%x:%x:%x:%x.\n", + prAdapter->rWifiVar.aucDeviceAddress[0], prAdapter->rWifiVar.aucDeviceAddress[1], + prAdapter->rWifiVar.aucDeviceAddress[2], prAdapter->rWifiVar.aucDeviceAddress[3], + prAdapter->rWifiVar.aucDeviceAddress[4], prAdapter->rWifiVar.aucDeviceAddress[5]); + DBGLOG(BOW, EVENT, "bowStopping, g_u4LinkCount, %x.\n", g_u4LinkCount); + DBGLOG(BOW, EVENT, + "prBowFsmInfo->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", + prBowFsmInfo->aucPeerAddress[0], prBowFsmInfo->aucPeerAddress[1], + prBowFsmInfo->aucPeerAddress[2], prBowFsmInfo->aucPeerAddress[3], + prBowFsmInfo->aucPeerAddress[4], prBowFsmInfo->aucPeerAddress[5]); + DBGLOG(BOW, EVENT, "BoW Stoping,[%d,%d]\n", g_u4LinkCount, g_u4Beaconing); + + if (g_u4LinkCount == 0) { + /*Stop beaconing */ + GLUE_DEC_REF_CNT(g_u4Beaconing); + + /*Deactive BoW network */ + /* prBowBssInfo->fgIsNetActive = FALSE; */ + /* prBowBssInfo->fgIsBeaconActivated = FALSE; */ + nicPmIndicateBssAbort(prAdapter, prBowBssInfo->ucBssIndex); + bowChangeMediaState(prBowBssInfo, MEDIA_STATE_DISCONNECTED); + nicUpdateBss(prAdapter, prBowBssInfo->ucBssIndex); + /*temp solution for FW hal_pwr_mgt.c#3037 ASSERT */ + nicDeactivateNetwork(prAdapter, prBowBssInfo->ucBssIndex); + SET_NET_PWR_STATE_IDLE(prAdapter, prBowBssInfo->ucBssIndex); + UNSET_NET_ACTIVE(prAdapter, prBowBssInfo->ucBssIndex); + + } + +} + +void bowStarting(IN struct ADAPTER *prAdapter) +{ + struct BOW_FSM_INFO *prBowFsmInfo; + struct BSS_INFO *prBssInfo = (struct BSS_INFO *) NULL; + + ASSERT(prAdapter); + + prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); + + if (g_u4LinkCount == 1) { + DBGLOG(BOW, EVENT, "BoW Starting.\n"); + DBGLOG(BOW, EVENT, "BoW channel granted.\n"); + + /* 3 <1> Update BSS_INFO_T per Network Basis */ + /* 4 <1.1> Setup Operation Mode */ + + /* Bruce, 20140224 */ + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prBowFsmInfo->ucBssIndex); + + /* 4 <1.2> Setup SSID */ + prBssInfo->ucSSIDLen = BOW_SSID_LEN; + bowAssignSsid(prBssInfo->aucSSID, prBssInfo->aucOwnMacAddr); + + DBGLOG(BOW, EVENT, "SSID %s.\n", prBssInfo->aucSSID); + DBGLOG(BOW, EVENT, "prBssInfo->aucBSSID, %x:%x:%x:%x:%x:%x.\n", + prBssInfo->aucBSSID[0], + prBssInfo->aucBSSID[1], + prBssInfo->aucBSSID[2], prBssInfo->aucBSSID[3], prBssInfo->aucBSSID[4], prBssInfo->aucBSSID[5]); + DBGLOG(BOW, EVENT, "prBssInfo->aucOwnMacAddr, %x:%x:%x:%x:%x:%x.\n", + prBssInfo->aucOwnMacAddr[0], + prBssInfo->aucOwnMacAddr[1], + prBssInfo->aucOwnMacAddr[2], + prBssInfo->aucOwnMacAddr[3], prBssInfo->aucOwnMacAddr[4], prBssInfo->aucOwnMacAddr[5]); + DBGLOG(BOW, EVENT, "prAdapter->rWifiVar.aucDeviceAddress, %x:%x:%x:%x:%x:%x.\n", + prAdapter->rWifiVar.aucDeviceAddress[0], + prAdapter->rWifiVar.aucDeviceAddress[1], + prAdapter->rWifiVar.aucDeviceAddress[2], + prAdapter->rWifiVar.aucDeviceAddress[3], + prAdapter->rWifiVar.aucDeviceAddress[4], prAdapter->rWifiVar.aucDeviceAddress[5]); + + /* 4 <1.3> Clear current AP's STA_RECORD_T and current AID */ + prBssInfo->prStaRecOfAP = (struct STA_RECORD *) NULL; + prBssInfo->u2AssocId = 0; + + /* 4 <1.4> Setup Channel, Band and Phy Attributes */ + prBssInfo->ucPrimaryChannel = prBowFsmInfo->ucPrimaryChannel; + if (prBowFsmInfo->eBand == BAND_2G4) + prBssInfo->eBand = BAND_2G4; + else + prBssInfo->eBand = BAND_5G; + +#if CFG_BOW_SUPPORT_11N + /* Depend on eBand */ + prBssInfo->ucPhyTypeSet = prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11BGN; + /* Depend on eCurrentOPMode and ucPhyTypeSet */ + prBssInfo->ucConfigAdHocAPMode = AP_MODE_MIXED_11BG; + + prBssInfo->ucNonHTBasicPhyType = (uint8_t) + rNonHTApModeAttributes[prBssInfo->ucConfigAdHocAPMode].ePhyTypeIndex; + prBssInfo->u2BSSBasicRateSet = rNonHTApModeAttributes[prBssInfo->ucConfigAdHocAPMode].u2BSSBasicRateSet; + + prBssInfo->u2OperationalRateSet = + rNonHTPhyAttributes[prBssInfo->ucNonHTBasicPhyType].u2SupportedRateSet; + + rateGetDataRatesFromRateSet(prBssInfo->u2OperationalRateSet, + prBssInfo->u2BSSBasicRateSet, + prBssInfo->aucAllSupportedRates, &prBssInfo->ucAllSupportedRatesLen); + +#else + if (prBssInfo->eBand == BAND_2G4) { + /* Depend on eBand */ + prBssInfo->ucPhyTypeSet = PHY_TYPE_SET_802_11BG; + /* Depend on eCurrentOPMode and ucPhyTypeSet */ + prBssInfo->ucConfigAdHocAPMode = AP_MODE_MIXED_11BG; + + /* RATE_SET_ERP; */ + prBssInfo->u2BSSBasicRateSet = BASIC_RATE_SET_ERP; + prBssInfo->u2OperationalRateSet = RATE_SET_ERP; + prBssInfo->ucNonHTBasicPhyType = PHY_TYPE_ERP_INDEX; + } else { + /* Depend on eBand */ + /* prBssInfo->ucPhyTypeSet = PHY_TYPE_SET_802_11BG; */ + /* Depend on eCurrentOPMode and ucPhyTypeSet */ + /* prBssInfo->ucConfigAdHocAPMode = AP_MODE_MIXED_11BG; */ + /* Depend on eBand */ + prBssInfo->ucPhyTypeSet = PHY_TYPE_SET_802_11A; + /* Depend on eCurrentOPMode and ucPhyTypeSet */ + prBssInfo->ucConfigAdHocAPMode = AP_MODE_11A; + + /* RATE_SET_ERP; */ + /* prBssInfo->u2BSSBasicRateSet = BASIC_RATE_SET_ERP; */ + /* prBssInfo->u2OperationalRateSet = RATE_SET_ERP; */ + + /* RATE_SET_ERP; */ + prBssInfo->u2BSSBasicRateSet = BASIC_RATE_SET_OFDM; + prBssInfo->u2OperationalRateSet = RATE_SET_OFDM; + prBssInfo->ucNonHTBasicPhyType = PHY_TYPE_OFDM_INDEX; + } + +#endif + prBssInfo->fgErpProtectMode = FALSE; + + /* 4 <1.5> Setup MIB for current BSS */ + prBssInfo->u2BeaconInterval = prBowFsmInfo->u2BeaconInterval; + prBssInfo->ucDTIMPeriod = DOT11_DTIM_PERIOD_DEFAULT; + prBssInfo->u2ATIMWindow = 0; + prBssInfo->ucBeaconTimeoutCount = 0; + if (prBowFsmInfo->fgSupportQoS) { + prAdapter->rWifiVar.ucQoS = TRUE; + prBssInfo->fgIsQBSS = TRUE; + } + + /* 3 <2> Update BSS_INFO_T common part */ +#if CFG_SUPPORT_AAA + bssInitForAP(prAdapter, prBssInfo, TRUE); + nicQmUpdateWmmParms(prAdapter, prBssInfo->ucBssIndex); +#endif /* CFG_SUPPORT_AAA */ + prBssInfo->fgIsNetActive = TRUE; + prBssInfo->fgIsBeaconActivated = TRUE; + + /* 3 <3> Set MAC HW */ + + DBGLOG(BOW, EVENT, + "prBowFsmInfo->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", + prBowFsmInfo->aucPeerAddress[0], prBowFsmInfo->aucPeerAddress[1], + prBowFsmInfo->aucPeerAddress[2], prBowFsmInfo->aucPeerAddress[3], + prBowFsmInfo->aucPeerAddress[4], prBowFsmInfo->aucPeerAddress[5]); + + /* 4 <3.1> use command packets to inform firmware */ + rlmBssInitForAPandIbss(prAdapter, prBssInfo); + nicUpdateBss(prAdapter, prBssInfo->ucBssIndex); + + /* 4 <3.2> Update AdHoc PM parameter */ + nicPmIndicateBssCreated(prAdapter, prBssInfo->ucBssIndex); + + /* 4 <3.1> Reset HW TSF Update Mode and Beacon Mode */ + + /* 4 <3.2> Setup BSSID */ + /* TODO: rxmSetRxFilterBSSID0 */ +/* rxmSetRxFilterBSSID0(prBssInfo->ucHwBssidId, prBssInfo->aucBSSID); */ + + /* 4 <3.3> Setup RX Filter to accept Probe Request */ + /* TODO: f get/set RX filter. */ + +#if 0 + { + uint32_t u4RxFilter; + + if (halMacRxGetRxFilters(&u4RxFilter) == HAL_STATUS_SUCCESS) { + + u4RxFilter &= ~BIT(RXFILTER_DROP_PROBE_REQ); + + halMacRxSetRxFilters(u4RxFilter); + } + } +#endif + } + + /*Update BoW Table */ + bowSetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress, BOW_DEVICE_STATE_STARTING); + + DBGLOG(BOW, EVENT, "BoW Starting,[%d,%d]\n", g_u4LinkCount, g_u4Beaconing); + DBGLOG(BOW, EVENT, "bowStarting, g_u4LinkCount, %x.\n", g_u4LinkCount); + + /*Start beaconing */ + if (g_u4Beaconing < 1) { + GLUE_INC_REF_CNT(g_u4Beaconing); + bssSendBeaconProbeResponse(prAdapter, prBssInfo->ucBssIndex, NULL, 0); + cnmTimerStartTimer(prAdapter, &prBowFsmInfo->rStartingBeaconTimer, prBowFsmInfo->u2BeaconInterval); + } +#if 0 + /*Responder: Start to scan Initiator */ + if (prBowFsmInfo->ucRole == BOW_RESPONDER) { + DBGLOG(BOW, EVENT, "bowStarting responder, start scan result searching.\n"); + cnmTimerStopTimer(prAdapter, &prBowFsmInfo->rChGrantedTimer); + bowReleaseCh(prAdapter); + bowResponderScan(prAdapter); + } + /*Initiator: Request channel, wait for responder */ + /* else + * bowRequestCh(prAdapter); + */ +#endif + + /* wlanBindBssIdxToNetInterface(prAdapter->prGlueInfo, NET_DEV_BOW_IDX, prBssInfo->ucBssIndex); */ + +} + +void bowAssignSsid(IN uint8_t *pucSsid, IN uint8_t *puOwnMacAddr) +{ + uint8_t i; + uint8_t aucSSID[] = BOW_WILDCARD_SSID; + + kalMemCopy(pucSsid, aucSSID, BOW_WILDCARD_SSID_LEN); + + for (i = 0; i < 6; i++) { + pucSsid[(3 * i) + 3] = 0x2D; + if ((*(puOwnMacAddr + i) >> 4) < 0xA) + *(pucSsid + (3 * i) + 4) = (*(puOwnMacAddr + i) >> 4) + 0x30; + else + *(pucSsid + (3 * i) + 4) = (*(puOwnMacAddr + i) >> 4) + 0x57; + + if ((*(puOwnMacAddr + i) & 0x0F) < 0xA) + pucSsid[(3 * i) + 5] = (*(puOwnMacAddr + i) & 0x0F) + 0x30; + else + pucSsid[(3 * i) + 5] = (*(puOwnMacAddr + i) & 0x0F) + 0x57; + } + +} + +#endif /* Marked for MT6630 */ + +/*----------------------------------------------------------------------------*/ +/*! +* @brief This function will validate the Rx Probe Request Frame and then return +* result to BSS to indicate if need to send the corresponding Probe Response +* Frame if the specified conditions were matched. +* +* @param[in] prAdapter Pointer to the Adapter structure. +* @param[in] prSwRfb Pointer to SW RFB data structure. +* @param[out] pu4ControlFlags Control flags for replying the Probe Response +* +* @retval TRUE Reply the Probe Response +* @retval FALSE Don't reply the Probe Response +*/ +/*----------------------------------------------------------------------------*/ +u_int8_t bowValidateProbeReq(IN struct ADAPTER *prAdapter, IN struct SW_RFB *prSwRfb, OUT uint32_t *pu4ControlFlags) +{ +#if 1 /* Marked for MT6630 */ + + struct WLAN_MAC_MGMT_HEADER *prMgtHdr; + struct BOW_FSM_INFO *prBowFsmInfo; + struct BSS_INFO *prBssInfo; + struct IE_SSID *prIeSsid = (struct IE_SSID *) NULL; + uint8_t *pucIE; + uint16_t u2IELength; + uint16_t u2Offset = 0; + u_int8_t fgReplyProbeResp = FALSE; + + ASSERT(prSwRfb); + ASSERT(pu4ControlFlags); + + prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prBowFsmInfo->ucBssIndex); + +#if 0 + DBGLOG(BOW, EVENT, "bowValidateProbeReq.\n"); +#endif + + /* 4 <1> Parse Probe Req IE and Get IE ptr (SSID, Supported Rate IE, ...) */ + prMgtHdr = (struct WLAN_MAC_MGMT_HEADER *) prSwRfb->pvHeader; + + u2IELength = prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen; + pucIE = (uint8_t *) (((unsigned long) prSwRfb->pvHeader) + prSwRfb->u2HeaderLen); + + IE_FOR_EACH(pucIE, u2IELength, u2Offset) { + if (IE_ID(pucIE) == ELEM_ID_SSID) { + if ((!prIeSsid) && (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) + prIeSsid = (struct IE_SSID *) pucIE; + break; + } + } /* end of IE_FOR_EACH */ + + IE_FOR_EACH(pucIE, u2IELength, u2Offset) { + if (IE_ID(pucIE) == ELEM_ID_SSID) { + if ((!prIeSsid) && (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) + prIeSsid = (struct IE_SSID *) pucIE; + break; + } + } /* end of IE_FOR_EACH */ + + /* 4 <2> Check network conditions */ + /*If BoW AP is beaconing */ + if (prBssInfo->eCurrentOPMode == OP_MODE_BOW && g_u4Beaconing > 0) { + + /*Check the probe requset sender is our peer */ + if (bowCheckBowTableIfVaild(prAdapter, prMgtHdr->aucSrcAddr)) + fgReplyProbeResp = TRUE; + /*Check the probe request target SSID is our SSID */ + else if ((prIeSsid) && + EQUAL_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, prIeSsid->aucSSID, prIeSsid->ucLength)) + fgReplyProbeResp = TRUE; + else + fgReplyProbeResp = FALSE; + } + + return fgReplyProbeResp; +#else + return 0; +#endif +} + +#if 1 /* Marked for MT6630 */ + +/*----------------------------------------------------------------------------*/ +/*! +* @brief This function will indicate an Event of "Media Disconnect" to HOST +* +* @param[in] u4Param Unused timer parameter +* +* @return (none) +*/ +/*----------------------------------------------------------------------------*/ +void bowSendBeacon(IN struct ADAPTER *prAdapter, IN unsigned long ulParamPtr) +{ + struct BOW_FSM_INFO *prBowFsmInfo; + + prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); + + if ((g_u4Beaconing != 0) && (g_u4LinkCount > 0) + && (g_u4LinkCount < CFG_BOW_PHYSICAL_LINK_NUM)) { + /* Send beacon */ + bssSendBeaconProbeResponse(prAdapter, prBowFsmInfo->ucBssIndex, NULL, 0); + cnmTimerStartTimer(prAdapter, &prBowFsmInfo->rStartingBeaconTimer, prBowFsmInfo->u2BeaconInterval); + } else { + DBGLOG(BOW, EVENT, "BoW Send Beacon,[%d,%d]\n", g_u4LinkCount, g_u4Beaconing); + } +} + +/*----------------------------------------------------------------------------*/ +/*! +* @brief This function will indicate an Event of "Media Disconnect" to HOST +* +* @param[in] u4Param Unused timer parameter +* +* @return (none) +*/ +/*----------------------------------------------------------------------------*/ +void bowResponderScan(IN struct ADAPTER *prAdapter) +{ + struct BOW_FSM_INFO *prBowFsmInfo; + struct MSG_SCN_SCAN_REQ *prScanReqMsg; + struct BSS_INFO *prBssInfo; + + ASSERT(prAdapter); + + prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prBowFsmInfo->ucBssIndex); + + DBGLOG(BOW, EVENT, "bowResponderScan.\n"); + DBGLOG(BOW, EVENT, "BOW SCAN [REQ:%d]\n", prBowFsmInfo->ucSeqNumOfScanReq + 1); + + prScanReqMsg = (struct MSG_SCN_SCAN_REQ *) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(struct MSG_SCN_SCAN_REQ)); + + if (!prScanReqMsg) { + ASSERT(0); /* Can't trigger SCAN FSM */ + return; + } + + /*Fill scan message */ + prScanReqMsg->rMsgHdr.eMsgId = MID_BOW_SCN_SCAN_REQ; + prScanReqMsg->ucSeqNum = ++prBowFsmInfo->ucSeqNumOfScanReq; + prScanReqMsg->ucBssIndex = prBowFsmInfo->ucBssIndex; + prScanReqMsg->eScanType = SCAN_TYPE_ACTIVE_SCAN; + prScanReqMsg->ucSSIDType = SCAN_REQ_SSID_SPECIFIED; + prScanReqMsg->ucSSIDLength = BOW_SSID_LEN; + bowAssignSsid(prScanReqMsg->aucSSID, prBowFsmInfo->aucPeerAddress); + prScanReqMsg->ucChannelListNum = 1; + + if (prBowFsmInfo->eBand == BAND_2G4) { + prScanReqMsg->eScanChannel = SCAN_CHANNEL_SPECIFIED; + prScanReqMsg->arChnlInfoList[0].eBand = BAND_2G4; + } else { + prScanReqMsg->eScanChannel = SCAN_CHANNEL_5G; + prScanReqMsg->arChnlInfoList[0].eBand = BAND_5G; + } + + prScanReqMsg->arChnlInfoList[0].ucChannelNum = prBowFsmInfo->ucPrimaryChannel; + prScanReqMsg->u2IELen = 0; + + /*Send scan message */ + mboxSendMsg(prAdapter, MBOX_ID_0, (struct MSG_HDR *) prScanReqMsg, MSG_SEND_METHOD_BUF); + + /*Change state to SCANNING */ + bowSetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress, BOW_DEVICE_STATE_SCANNING); + + /* prBowFsmInfo->fgTryScan = FALSE; *//* Will enable background sleep for infrastructure */ + +} + +#endif /* Marked for MT6630 */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief +* +* \param[in] +* +* \return none +*/ +/*----------------------------------------------------------------------------*/ +void bowResponderScanDone(IN struct ADAPTER *prAdapter, IN struct MSG_HDR *prMsgHdr) +{ +#if 1 /* Marked for MT6630 */ + struct MSG_SCN_SCAN_DONE *prScanDoneMsg; + struct BOW_FSM_INFO *prBowFsmInfo; + struct BSS_DESC *prBssDesc; + uint8_t ucSeqNumOfCompMsg; + struct CONNECTION_SETTINGS *prConnSettings; + enum ENUM_BOW_DEVICE_STATE eFsmState; + enum ENUM_SCAN_STATUS eScanStatus; + + ASSERT(prAdapter); + ASSERT(prMsgHdr); + + prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); + prConnSettings = + aisGetConnSettings(prAdapter, AIS_DEFAULT_INDEX); + prScanDoneMsg = (struct MSG_SCN_SCAN_DONE *) prMsgHdr; + eFsmState = bowGetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress); + + ucSeqNumOfCompMsg = prScanDoneMsg->ucSeqNum; + eScanStatus = prScanDoneMsg->eScanStatus; + + cnmMemFree(prAdapter, prMsgHdr); + + DBGLOG(BOW, EVENT, "bowResponderScanDone.\n"); + DBGLOG(BOW, EVENT, "BOW SCAN [DONE:%d]\n", ucSeqNumOfCompMsg); + + if (eScanStatus == SCAN_STATUS_CANCELLED) { + DBGLOG(BOW, EVENT, "BOW SCAN [CANCELLED:%d]\n", ucSeqNumOfCompMsg); + if (eFsmState == BOW_DEVICE_STATE_DISCONNECTING) { + wlanoidSendSetQueryBowCmd(prAdapter, + CMD_ID_CMD_BT_OVER_WIFI, + prBowFsmInfo->ucBssIndex, + TRUE, + FALSE, + wlanbowCmdEventLinkDisconnected, + wlanbowCmdTimeoutHandler, 0, NULL, 0); + } + return; + } else if (eFsmState == BOW_DEVICE_STATE_DISCONNECTED) { + /* bowDisconnectLink(prAdapter, NULL, TX_RESULT_SUCCESS); */ + return; + } else if (ucSeqNumOfCompMsg != prBowFsmInfo->ucSeqNumOfScanReq) { + DBGLOG(BOW, EVENT, "Sequence no. of BOW Responder scan done is not matched.\n"); + return; + } + prConnSettings->fgIsScanReqIssued = FALSE; + prBssDesc = scanSearchBssDescByBssid(prAdapter, prBowFsmInfo->aucPeerAddress); + DBGLOG(BOW, EVENT, "End scan result searching.\n"); + DBGLOG(BOW, EVENT, "prBowFsmInfo->aucPeerAddress: [" MACSTR "]\n", MAC2STR(prBowFsmInfo->aucPeerAddress)); + + /*Initiator is FOUND */ + if (prBssDesc != NULL) { /* (prBssDesc->aucBSSID != NULL)) */ + DBGLOG(BOW, EVENT, + "Search Bow Peer address - %x:%x:%x:%x:%x:%x.\n", + prBssDesc->aucBSSID[0], prBssDesc->aucBSSID[1], + prBssDesc->aucBSSID[2], prBssDesc->aucBSSID[3], prBssDesc->aucBSSID[4], prBssDesc->aucBSSID[5]); + DBGLOG(BOW, EVENT, "Starting to join initiator.\n"); + + /*Set target BssDesc */ + prBowFsmInfo->prTargetBssDesc = prBssDesc; + /*Request channel to do JOIN */ + bowSetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress, BOW_DEVICE_STATE_ACQUIRING_CHANNEL); + bowRequestCh(prAdapter); + } + /*Initiator is NOT FOUND */ + else { + /*Scan again, until PAL timeout */ + bowResponderScan(prAdapter); +#if 0 + wlanoidSendSetQueryBowCmd(prAdapter, + CMD_ID_CMD_BT_OVER_WIFI, + TRUE, + FALSE, wlanbowCmdEventLinkDisconnected, wlanbowCmdTimeoutHandler, 0, NULL, 0); +#endif + } + + return; +#endif /* Marked for MT6630 */ +} + +#if 1 /* Marked for MT6630 */ + +/*----------------------------------------------------------------------------*/ +/*! +* @brief Function for cancelling scan request. There is another option to extend channel privilige +* for another purpose. +* +* @param fgIsChannelExtention - Keep the channel previlege, but can cancel scan timer. +* +* @return (none) +*/ +/*----------------------------------------------------------------------------*/ +void bowResponderCancelScan(IN struct ADAPTER *prAdapter, IN u_int8_t fgIsChannelExtention) +{ + + struct MSG_SCN_SCAN_CANCEL *prScanCancel = (struct MSG_SCN_SCAN_CANCEL *) NULL; + struct BOW_FSM_INFO *prBowFsmInfo = (struct BOW_FSM_INFO *) NULL; + + DEBUGFUNC("bowResponderCancelScan()"); + + do { + ASSERT(prAdapter); + + prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); + + if (TRUE) { + DBGLOG(BOW, EVENT, "BOW SCAN [CANCEL:%d]\n", prBowFsmInfo->ucSeqNumOfScanReq); + + /* There is a channel privilege on hand. */ + + DBGLOG(BOW, TRACE, "BOW Cancel Scan\n"); + + prScanCancel = + (struct MSG_SCN_SCAN_CANCEL *) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(struct MSG_SCN_SCAN_CANCEL)); + if (!prScanCancel) { + /* Buffer not enough, can not cancel scan request. */ + DBGLOG(BOW, TRACE, "Buffer not enough, can not cancel scan.\n"); + ASSERT(FALSE); + break; + } + + prScanCancel->rMsgHdr.eMsgId = MID_BOW_SCN_SCAN_CANCEL; + prScanCancel->ucBssIndex = prBowFsmInfo->ucBssIndex; + prScanCancel->ucSeqNum = prBowFsmInfo->ucSeqNumOfScanReq; +#if CFG_ENABLE_WIFI_DIRECT + prScanCancel->fgIsChannelExt = fgIsChannelExtention; +#endif + mboxSendMsg(prAdapter, MBOX_ID_0, (struct MSG_HDR *) prScanCancel, MSG_SEND_METHOD_BUF); + + } + + } while (FALSE); + +} /* bowResponderCancelScan */ + +/*----------------------------------------------------------------------------*/ +/*! +* @brief Initialization of JOIN STATE +* +* @param[in] prBssDesc The pointer of BSS_DESC_T which is the BSS we will try to join with. +* +* @return (none) +*/ +/*----------------------------------------------------------------------------*/ +void bowResponderJoin(IN struct ADAPTER *prAdapter, IN struct BSS_DESC *prBssDesc) +{ + struct BOW_FSM_INFO *prBowFsmInfo; + struct BSS_INFO *prBssInfo; + struct CONNECTION_SETTINGS *prConnSettings; + struct STA_RECORD *prStaRec; + struct MSG_SAA_FSM_START *prJoinReqMsg; + + ASSERT(prBssDesc); + ASSERT(prAdapter); + + DBGLOG(BOW, EVENT, "Starting bowResponderJoin.\n"); + + prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prBowFsmInfo->ucBssIndex); + prConnSettings = aisGetConnSettings(prAdapter, AIS_DEFAULT_INDEX); + + /* 4 <1> We are going to connect to this BSS. */ + prBssDesc->fgIsConnecting |= BIT(prBowFsmInfo->ucBssIndex); + bowSetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress, BOW_DEVICE_STATE_CONNECTING); + + /* 4 <2> Setup corresponding STA_RECORD_T */ + /*Support First JOIN and retry */ + prStaRec = bssCreateStaRecFromBssDesc(prAdapter, STA_TYPE_BOW_AP, prBssInfo->ucBssIndex, prBssDesc); + + prBowFsmInfo->prTargetStaRec = prStaRec; + + /* 4 <3> Update ucAvailableAuthTypes which we can choice during SAA */ + prStaRec->fgIsReAssoc = FALSE; + prBowFsmInfo->ucAvailableAuthTypes = (uint8_t) AUTH_TYPE_OPEN_SYSTEM; + prStaRec->ucTxAuthAssocRetryLimit = TX_AUTH_ASSOCI_RETRY_LIMIT; + + /* 4 <4> Use an appropriate Authentication Algorithm Number among the ucAvailableAuthTypes */ + if (prBowFsmInfo->ucAvailableAuthTypes & (uint8_t) AUTH_TYPE_OPEN_SYSTEM) { + + DBGLOG(BOW, LOUD, "JOIN INIT: Try to do Authentication with AuthType == OPEN_SYSTEM.\n"); + prBowFsmInfo->ucAvailableAuthTypes &= ~(uint8_t) AUTH_TYPE_OPEN_SYSTEM; + + prStaRec->ucAuthAlgNum = (uint8_t) AUTH_ALGORITHM_NUM_OPEN_SYSTEM; + } else { + ASSERT(0); + } + + /* 4 <4.1> sync. to firmware domain */ + cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); + + /* 4 <5> Overwrite Connection Setting for eConnectionPolicy */ + if (prBssDesc->ucSSIDLen) { + COPY_SSID(prConnSettings->aucSSID, prConnSettings->ucSSIDLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen); + DBGLOG(BOW, EVENT, "bowResponderJoin, SSID %s.\n", prBssDesc->aucSSID); + DBGLOG(BOW, EVENT, "bowResponderJoin, SSID %s.\n", prConnSettings->aucSSID); + } + /* 4 <6> Send a Msg to trigger SAA to start JOIN process. */ + prJoinReqMsg = (struct MSG_SAA_FSM_START *) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(struct MSG_SAA_FSM_START)); + if (!prJoinReqMsg) { + + ASSERT(0); /* Can't trigger SAA FSM */ + return; + } + + prJoinReqMsg->rMsgHdr.eMsgId = MID_BOW_SAA_FSM_START; + prJoinReqMsg->ucSeqNum = ++prBowFsmInfo->ucSeqNumOfReqMsg; + prJoinReqMsg->prStaRec = prStaRec; + + prBssInfo->prStaRecOfAP = prStaRec; + + DBGLOG(BOW, EVENT, "prStaRec->eStaType, %x.\n", prStaRec->eStaType); + DBGLOG(BOW, EVENT, "BoW trigger SAA [" MACSTR "]\n", MAC2STR(prStaRec->aucMacAddr)); + + mboxSendMsg(prAdapter, MBOX_ID_0, (struct MSG_HDR *) prJoinReqMsg, MSG_SEND_METHOD_BUF); + +} + +#endif /* Marked for MT6630 */ + +/*----------------------------------------------------------------------------*/ +/*! +* @brief This function will handle the Join Complete Event from SAA FSM for BOW FSM +* +* @param[in] prMsgHdr Message of Join Complete of SAA FSM. +* +* @return (none) +*/ +/*----------------------------------------------------------------------------*/ +void bowFsmRunEventJoinComplete(IN struct ADAPTER *prAdapter, IN struct MSG_HDR *prMsgHdr) +{ +#if 1 /* Marked for MT6630 */ + + struct MSG_SAA_FSM_COMP *prJoinCompMsg; + struct BOW_FSM_INFO *prBowFsmInfo; + struct STA_RECORD *prStaRec; + struct SW_RFB *prAssocRspSwRfb; + struct WLAN_ASSOC_RSP_FRAME *prAssocRspFrame = (struct WLAN_ASSOC_RSP_FRAME *) NULL; + uint16_t u2IELength; + uint8_t *pucIE; + struct BSS_INFO *prBowBssInfo; + + ASSERT(prAdapter); + ASSERT(prMsgHdr); + + prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); + prBowBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prBowFsmInfo->ucBssIndex); + prJoinCompMsg = (struct MSG_SAA_FSM_COMP *) prMsgHdr; + prStaRec = prJoinCompMsg->prStaRec; + + DBGLOG(BOW, EVENT, "Start bowfsmRunEventJoinComplete.\n"); + DBGLOG(BOW, EVENT, "bowfsmRunEventJoinComplete ptr check\n"); + DBGLOG(BOW, EVENT, "prMsgHdr %x\n", prMsgHdr); + DBGLOG(BOW, EVENT, "prAdapter %x\n", prAdapter); + DBGLOG(BOW, EVENT, "prBowFsmInfo %x\n", prBowFsmInfo); + DBGLOG(BOW, EVENT, "prStaRec %x\n", prStaRec); + + ASSERT(prStaRec); + ASSERT(prBowFsmInfo); + + /* Check SEQ NUM */ + if (prJoinCompMsg->ucSeqNum == prBowFsmInfo->ucSeqNumOfReqMsg) { + COPY_MAC_ADDR(prBowFsmInfo->aucPeerAddress, prStaRec->aucMacAddr); + + /* 4 <1> JOIN was successful */ + if (prJoinCompMsg->rJoinStatus == WLAN_STATUS_SUCCESS) { + prAssocRspSwRfb = prJoinCompMsg->prSwRfb; + prAssocRspFrame = (struct WLAN_ASSOC_RSP_FRAME *) prAssocRspSwRfb->pvHeader; + + u2IELength = + (uint16_t) ((prAssocRspSwRfb->u2PacketLen - + prAssocRspSwRfb->u2HeaderLen) - + (OFFSET_OF(struct WLAN_ASSOC_RSP_FRAME, aucInfoElem[0]) - WLAN_MAC_MGMT_HEADER_LEN)); + pucIE = prAssocRspFrame->aucInfoElem; + + prStaRec->eStaType = STA_TYPE_BOW_AP; + prStaRec->u2DesiredNonHTRateSet &= prBowBssInfo->u2OperationalRateSet; + prStaRec->ucDesiredPhyTypeSet = prStaRec->ucPhyTypeSet & prBowBssInfo->ucPhyTypeSet; +#if CFG_BOW_RATE_LIMITATION + /* 4 <1.2>Update Rate Set */ + /*Limit Rate Set to 24M, 48M, 54M */ + prStaRec->u2DesiredNonHTRateSet &= (RATE_SET_BIT_24M | RATE_SET_BIT_48M | RATE_SET_BIT_54M); + /*If peer cannot support the above rate set, fix on the available highest rate */ + if (prStaRec->u2DesiredNonHTRateSet == 0) { + uint8_t ucHighestRateIndex; + + if (rateGetHighestRateIndexFromRateSet + (prBowBssInfo->u2OperationalRateSet, &ucHighestRateIndex)) { + prStaRec->u2DesiredNonHTRateSet = BIT(ucHighestRateIndex); + } + } +#endif + + /* 4 <1.1> Change FW's Media State immediately. */ + bowChangeMediaState(prBowBssInfo, + MEDIA_STATE_CONNECTED); + + mqmProcessAssocRsp(prAdapter, prAssocRspSwRfb, pucIE, u2IELength); + + /* 4 <1.2> Update HT information and set channel */ + /* Record HT related parameters in rStaRec and rBssInfo + * Note: it shall be called before nicUpdateBss() + */ +#if CFG_BOW_SUPPORT_11N + rlmProcessAssocRsp(prAdapter, prAssocRspSwRfb, pucIE, u2IELength); +#endif + + /* 4 <1.3> Update BSS_INFO_T */ + nicUpdateBss(prAdapter, prBowBssInfo->ucBssIndex); + DBGLOG(BOW, EVENT, "Finish bowUpdateBssInfoForJOIN.\n"); + + /* 4 <1.4> Activate current AP's STA_RECORD_T in Driver. */ + cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); + + DBGLOG(BOW, EVENT, "bowFsmRunEventJoinComplete, qmActivateStaRec.\n"); + + /* 4 <1.7> Set the Next State of BOW FSM */ + wlanoidSendSetQueryBowCmd(prAdapter, + CMD_ID_CMD_BT_OVER_WIFI, + prBowFsmInfo->ucBssIndex, + TRUE, + FALSE, + wlanbowCmdEventLinkConnected, wlanbowCmdTimeoutHandler, 0, NULL, 0); + } + /* 4 <2> JOIN was not successful */ + else { + /*Retry */ + bowResponderJoin(prAdapter, prBowFsmInfo->prTargetBssDesc); +#if 0 + wlanoidSendSetQueryBowCmd(prAdapter, + CMD_ID_CMD_BT_OVER_WIFI, + TRUE, + FALSE, + wlanbowCmdEventLinkDisconnected, + wlanbowCmdTimeoutHandler, 0, NULL, 0); +#endif + DBGLOG(BOW, EVENT, "Start bowfsmRunEventJoinComplete -- Join failed.\n"); + DBGLOG(BOW, EVENT, "BoW trigger SAA REJOIN\n"); + } + } + + cnmMemFree(prAdapter, prMsgHdr); + +#endif /* Marked for MT6630 */ +} + +#if 1 /* Marked for MT6630 */ + +/*----------------------------------------------------------------------------*/ +/*! +* @brief This function will indicate the Media State to HOST +* +* @param[in] eConnectionState Current Media State +* @param[in] fgDelayIndication Set TRUE for postponing the Disconnect Indication. +* +* @return (none) +*/ +/*----------------------------------------------------------------------------*/ +void +bowIndicationOfMediaStateToHost(IN struct ADAPTER *prAdapter, + IN enum ENUM_PARAM_MEDIA_STATE eConnectionState, IN u_int8_t fgDelayIndication) +{ + struct EVENT_CONNECTION_STATUS rEventConnStatus; + struct CONNECTION_SETTINGS *prConnSettings; + struct BSS_INFO *prBssInfo; + struct BOW_FSM_INFO *prBowFsmInfo; + + prConnSettings = aisGetConnSettings(prAdapter, AIS_DEFAULT_INDEX); + + prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prBowFsmInfo->ucBssIndex); + + /* NOTE(Kevin): Move following line to bowChangeMediaState() macro per CM's request. */ + /* prBowBssInfo->eConnectionState = eConnectionState; */ + + /* For indicating the Disconnect Event only if current media state is + * disconnected and we didn't do indication yet. + */ + if (prBssInfo->eConnectionState == MEDIA_STATE_DISCONNECTED) { + if (prBssInfo->eConnectionStateIndicated == eConnectionState) + return; + } + + if (!fgDelayIndication) { + /* 4 <0> Cancel Delay Timer */ + cnmTimerStopTimer(prAdapter, &prBowFsmInfo->rIndicationOfDisconnectTimer); + + /* 4 <1> Fill EVENT_CONNECTION_STATUS */ + rEventConnStatus.ucMediaStatus = (uint8_t) eConnectionState; + + if (eConnectionState == MEDIA_STATE_CONNECTED) { + rEventConnStatus.ucReasonOfDisconnect = DISCONNECT_REASON_CODE_RESERVED; + + if (prBssInfo->eCurrentOPMode == OP_MODE_BOW) { + rEventConnStatus.ucInfraMode = (uint8_t) NET_TYPE_INFRA; + rEventConnStatus.u2AID = prBssInfo->u2AssocId; + rEventConnStatus.u2ATIMWindow = 0; + } else if (prBssInfo->eCurrentOPMode == OP_MODE_IBSS) { + rEventConnStatus.ucInfraMode = (uint8_t) NET_TYPE_IBSS; + rEventConnStatus.u2AID = 0; + rEventConnStatus.u2ATIMWindow = prBssInfo->u2ATIMWindow; + } else { + ASSERT(0); + } + + COPY_SSID(rEventConnStatus.aucSsid, + rEventConnStatus.ucSsidLen, prConnSettings->aucSSID, prConnSettings->ucSSIDLen); + + COPY_MAC_ADDR(rEventConnStatus.aucBssid, prBssInfo->aucBSSID); + + rEventConnStatus.u2BeaconPeriod = prBssInfo->u2BeaconInterval; + rEventConnStatus.u4FreqInKHz = nicChannelNum2Freq(prBssInfo->ucPrimaryChannel); + + switch (prBssInfo->ucNonHTBasicPhyType) { + case PHY_TYPE_HR_DSSS_INDEX: + rEventConnStatus.ucNetworkType = (uint8_t) PARAM_NETWORK_TYPE_DS; + break; + + case PHY_TYPE_ERP_INDEX: + rEventConnStatus.ucNetworkType = (uint8_t) PARAM_NETWORK_TYPE_OFDM24; + break; + + case PHY_TYPE_OFDM_INDEX: + rEventConnStatus.ucNetworkType = (uint8_t) PARAM_NETWORK_TYPE_OFDM5; + break; + + default: + ASSERT(0); + rEventConnStatus.ucNetworkType = (uint8_t) PARAM_NETWORK_TYPE_DS; + break; + } + } else { + + rEventConnStatus.ucReasonOfDisconnect = prBssInfo->ucReasonOfDisconnect; + + } + + /* 4 <2> Indication */ + nicMediaStateChange(prAdapter, prBssInfo->ucBssIndex, &rEventConnStatus); + prBssInfo->eConnectionStateIndicated = eConnectionState; + } else { + /* NOTE: Only delay the Indication of Disconnect Event */ + ASSERT(eConnectionState == MEDIA_STATE_DISCONNECTED); + + DBGLOG(BOW, INFO, "Postpone the indication of Disconnect for %d seconds\n", + prConnSettings->ucDelayTimeOfDisconnectEvent); + + cnmTimerStartTimer(prAdapter, + &prBowFsmInfo->rIndicationOfDisconnectTimer, + SEC_TO_MSEC(prConnSettings->ucDelayTimeOfDisconnectEvent)); + } + +} + +#endif /* Marked for MT6630 */ + +/*----------------------------------------------------------------------------*/ +/*! +* @brief This function will indicate the Event of Tx Fail of AAA Module. +* +* @param[in] prAdapter Pointer to the Adapter structure. +* @param[in] prStaRec Pointer to the STA_RECORD_T +* +* @return (none) +*/ +/*----------------------------------------------------------------------------*/ +void bowRunEventAAATxFail(IN struct ADAPTER *prAdapter, IN struct STA_RECORD *prStaRec) +{ +#if 1 /* Marked for MT6630 */ + struct BSS_INFO *prBssInfo; + struct BOW_FSM_INFO *prBowFsmInfo; + + ASSERT(prAdapter); + ASSERT(prStaRec); + + DBGLOG(BOW, EVENT, "bowRunEventAAATxFail , bssRemoveStaRecFromClientList.\n"); + DBGLOG(BOW, EVENT, "BoW AAA TxFail, target state %d\n", prStaRec->ucStaState + 1); + + prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prBowFsmInfo->ucBssIndex); + bssRemoveClient(prAdapter, prBssInfo, prStaRec); + + return; +#endif +} + +/*----------------------------------------------------------------------------*/ +/*! +* @brief This function will indicate the Event of Successful Completion of AAA Module. +* +* @param[in] prAdapter Pointer to the Adapter structure. +* @param[in] prStaRec Pointer to the STA_RECORD_T +* +* @return (none) +*/ +/*----------------------------------------------------------------------------*/ +uint32_t bowRunEventAAAComplete(IN struct ADAPTER *prAdapter, IN struct STA_RECORD *prStaRec) +{ +#if 1 /* Marked for MT6630 */ + struct BSS_INFO *prBssInfo; + struct BOW_FSM_INFO *prBowFsmInfo; + + ASSERT(prStaRec); + + prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prBowFsmInfo->ucBssIndex); + + DBGLOG(BOW, STATE, "bowRunEventAAAComplete, cnmStaRecChangeState, STA_STATE_3.\n"); + DBGLOG(BOW, EVENT, "BoW AAA complete [" MACSTR "]\n", MAC2STR(prStaRec->aucMacAddr)); + + /*Update BssInfo to connected */ + bowChangeMediaState(prBssInfo, MEDIA_STATE_CONNECTED); + nicUpdateBss(prAdapter, prBowFsmInfo->ucBssIndex); + + /*Update StaRec to State3 */ + cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); + + /*Connected */ + wlanoidSendSetQueryBowCmd(prAdapter, + CMD_ID_CMD_BT_OVER_WIFI, + prBowFsmInfo->ucBssIndex, + TRUE, FALSE, wlanbowCmdEventLinkConnected, wlanbowCmdTimeoutHandler, 0, NULL, 0); + + return WLAN_STATUS_SUCCESS; + +#else + return 0; +#endif +} + +/*----------------------------------------------------------------------------*/ +/*! +* @brief This function will handle RxDeauth +* +* @param[in] prAdapter Pointer to the Adapter structure. +* @param[in] prStaRec Pointer to the STA_RECORD_T +* +* @return (none) +*/ +/*----------------------------------------------------------------------------*/ + +uint32_t bowRunEventRxDeAuth(IN struct ADAPTER *prAdapter, IN struct STA_RECORD *prStaRec, IN struct SW_RFB *prSwRfb) +{ +#if 1 /* Marked for MT6630 */ + struct BSS_INFO *prBowBssInfo; + struct BOW_FSM_INFO *prBowFsmInfo; + enum ENUM_BOW_DEVICE_STATE eFsmState; + + ASSERT(prAdapter); + + prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); + prBowBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prBowFsmInfo->ucBssIndex); + + if (!IS_STA_BOW_TYPE(prStaRec)) + return WLAN_STATUS_NOT_ACCEPTED; + + eFsmState = bowGetBowTableState(prAdapter, prStaRec->aucMacAddr); + + if (eFsmState == BOW_DEVICE_STATE_DISCONNECTED) { + /*do nothing */ + return WLAN_STATUS_NOT_ACCEPTED; + } + + if (prStaRec->ucStaState > STA_STATE_1) { + + if (prStaRec->ucStaState == STA_STATE_3) { + /* P_MSG_AIS_ABORT_T prAisAbortMsg; */ + + /* NOTE(Kevin): Change state immediately to avoid starvation of + * MSG buffer because of too many deauth frames before changing + * the STA state. + */ + cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); + } + + COPY_MAC_ADDR(prBowFsmInfo->aucPeerAddress, prStaRec->aucMacAddr); + + wlanoidSendSetQueryBowCmd(prAdapter, + CMD_ID_CMD_BT_OVER_WIFI, + prBowFsmInfo->ucBssIndex, + TRUE, + FALSE, wlanbowCmdEventLinkDisconnected, wlanbowCmdTimeoutHandler, 0, NULL, 0); + + return WLAN_STATUS_SUCCESS; + } + + return WLAN_STATUS_NOT_ACCEPTED; + +#else + return 0; +#endif +} + +#if 1 /* Marked for MT6630 */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function handle BoW Link disconnect. +* +* \param[in] pMsduInfo Pointer to the Msdu Info +* \param[in] rStatus The Tx done status +* +* \return - +* +* \note after receive deauth frame, callback function call this +*/ +/*----------------------------------------------------------------------------*/ +void bowDisconnectLink(IN struct ADAPTER *prAdapter, IN struct MSDU_INFO *prMsduInfo, IN enum ENUM_TX_RESULT_CODE rTxDoneStatus) +{ + struct BOW_FSM_INFO *prBowFsmInfo; + struct STA_RECORD *prStaRec; + + ASSERT(prAdapter); + + prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); + + /*Free target StaRec */ + if (prMsduInfo) + prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); + else + prStaRec = prBowFsmInfo->prTargetStaRec; + + if (prStaRec) { + /* cnmStaRecFree(prAdapter, prStaRec); */ + cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); + } + kalPrint("bowDisconnectLink\n"); + /*No one connected */ + if (g_u4LinkCount == 0 && g_u4Beaconing != 0) { + cnmTimerStopTimer(prAdapter, &prBowFsmInfo->rStartingBeaconTimer); + bowStopping(prAdapter); + kalPrint("bowStopping\n"); + /*Restore TxPower from Short range mode */ +#if CFG_SUPPORT_NVRAM && 0 + if (kalIsConfigurationExist(prAdapter->prGlueInfo) == TRUE) + wlanLoadManufactureData(prAdapter, kalGetConfiguration(prAdapter->prGlueInfo)); + else + DBGLOG(REQ, WARN, "%s: load manufacture data fail\n", __func__); + +#endif + /*Uninit BoW Interface */ +#if CFG_BOW_SEPARATE_DATA_PATH + kalUninitBowDevice(prAdapter->prGlueInfo); +#endif + } +} + +#endif /* Marked for MT6630 */ + +/*----------------------------------------------------------------------------*/ +/*! +* @brief This function will validate the Rx Assoc Req Frame and then return +* the status code to AAA to indicate if need to perform following actions +* when the specified conditions were matched. +* +* @param[in] prAdapter Pointer to the Adapter structure. +* @param[in] prSwRfb Pointer to SW RFB data structure. +* @param[out] pu2StatusCode The Status Code of Validation Result +* +* @retval TRUE Reply the Assoc Resp +* @retval FALSE Don't reply the Assoc Resp +*/ +/*----------------------------------------------------------------------------*/ +u_int8_t bowValidateAssocReq(IN struct ADAPTER *prAdapter, IN struct SW_RFB *prSwRfb, OUT uint16_t *pu2StatusCode) +{ +#if 1 /* Marked for MT6630 */ + + u_int8_t fgReplyAssocResp = FALSE; + struct BSS_INFO *prBowBssInfo; + struct STA_RECORD *prStaRec = (struct STA_RECORD *) NULL; + struct BOW_FSM_INFO *prBowFsmInfo; + struct WLAN_ASSOC_REQ_FRAME *prAssocReqFrame = (struct WLAN_ASSOC_REQ_FRAME *) NULL; + OS_SYSTIME rCurrentTime; + static OS_SYSTIME rLastRejectAssocTime; + + ASSERT(prAdapter); + + prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); + prBowBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prBowFsmInfo->ucBssIndex); + + prAssocReqFrame = (struct WLAN_ASSOC_REQ_FRAME *) prSwRfb->pvHeader; + *pu2StatusCode = STATUS_CODE_REQ_DECLINED; + + DBGLOG(BOW, EVENT, + "bowValidateAssocReq, prBowFsmInfo->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", + prBowFsmInfo->aucPeerAddress[0], prBowFsmInfo->aucPeerAddress[1], + prBowFsmInfo->aucPeerAddress[2], prBowFsmInfo->aucPeerAddress[3], + prBowFsmInfo->aucPeerAddress[4], prBowFsmInfo->aucPeerAddress[5]); + DBGLOG(BOW, EVENT, + "bowValidateAssocReq, prAssocReqFrame->aucSrcAddr, %x:%x:%x:%x:%x:%x.\n", + prAssocReqFrame->aucSrcAddr[0], prAssocReqFrame->aucSrcAddr[1], + prAssocReqFrame->aucSrcAddr[2], prAssocReqFrame->aucSrcAddr[3], + prAssocReqFrame->aucSrcAddr[4], prAssocReqFrame->aucSrcAddr[5]); + + /*Assoc Accept */ + while (EQUAL_MAC_ADDR(prAssocReqFrame->aucSrcAddr, prBowFsmInfo->aucPeerAddress)) { + DBGLOG(BOW, EVENT, "bowValidateAssocReq, return wlanbowCmdEventLinkConnected.\n"); + + /*Update StaRec */ + prStaRec = cnmGetStaRecByAddress(prAdapter, prBowFsmInfo->ucBssIndex, prAssocReqFrame->aucSrcAddr); + prStaRec->eStaType = STA_TYPE_BOW_CLIENT; + prStaRec->u2DesiredNonHTRateSet &= prBowBssInfo->u2OperationalRateSet; + prStaRec->ucDesiredPhyTypeSet = prStaRec->ucPhyTypeSet & prBowBssInfo->ucPhyTypeSet; + +#if CFG_BOW_RATE_LIMITATION + /*Limit Rate Set to 24M, 48M, 54M */ + prStaRec->u2DesiredNonHTRateSet &= (RATE_SET_BIT_24M | RATE_SET_BIT_48M | RATE_SET_BIT_54M); + /*If peer cannot support the above rate set, fix on the available highest rate */ + if (prStaRec->u2DesiredNonHTRateSet == 0) { + uint8_t ucHighestRateIndex; + + if (rateGetHighestRateIndexFromRateSet(prBowBssInfo->u2OperationalRateSet, &ucHighestRateIndex)) + prStaRec->u2DesiredNonHTRateSet = BIT(ucHighestRateIndex); + else { + /*If no available rate is found, DECLINE the association */ + *pu2StatusCode = STATUS_CODE_ASSOC_DENIED_RATE_NOT_SUPPORTED; + break; + } + } +#endif + + /*Update BssInfo to FW */ + bowChangeMediaState(prBowBssInfo, MEDIA_STATE_CONNECTED); + nicUpdateBss(prAdapter, prStaRec->ucBssIndex); + + /*reply successful */ + *pu2StatusCode = STATUS_CODE_SUCCESSFUL; + fgReplyAssocResp = TRUE; + break; + } + + /*Reject Assoc */ + if (*pu2StatusCode != STATUS_CODE_SUCCESSFUL) { + /*Reply Assoc with reject every 5s */ + rCurrentTime = kalGetTimeTick(); + if (CHECK_FOR_TIMEOUT(rCurrentTime, rLastRejectAssocTime, MSEC_TO_SYSTIME(5000)) || + rLastRejectAssocTime == 0) { + fgReplyAssocResp = TRUE; + rLastRejectAssocTime = rCurrentTime; + } + } + + return fgReplyAssocResp; + +#else + return 0; +#endif +} + +/*----------------------------------------------------------------------------*/ +/*! +* @brief This function will validate the Rx Auth Frame and then return +* the status code to AAA to indicate if need to perform following actions +* when the specified conditions were matched. +* +* @param[in] prAdapter Pointer to the Adapter structure. +* @param[in] prSwRfb Pointer to SW RFB data structure. +* @param[in] pprStaRec Pointer to pointer of STA_RECORD_T structure. +* @param[out] pu2StatusCode The Status Code of Validation Result +* +* @retval TRUE Reply the Auth +* @retval FALSE Don't reply the Auth +*/ +/*----------------------------------------------------------------------------*/ +u_int8_t +bowValidateAuth(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, IN struct STA_RECORD **pprStaRec, OUT uint16_t *pu2StatusCode) +{ +#if 1 /* Marked for MT6630 */ + u_int8_t fgReplyAuth = FALSE; + struct BSS_INFO *prBowBssInfo; + struct STA_RECORD *prStaRec = (struct STA_RECORD *) NULL; + struct BOW_FSM_INFO *prBowFsmInfo; + struct WLAN_AUTH_FRAME *prAuthFrame = (struct WLAN_AUTH_FRAME *) NULL; + OS_SYSTIME rCurrentTime; + static OS_SYSTIME rLastRejectAuthTime; + + /* TODO(Kevin): Call BoW functions to check .. + * 1. Check we are BoW now. + * 2. Check we can accept connection from thsi peer + * 3. Check Black List here. + */ + + prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); + prBowBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prBowFsmInfo->ucBssIndex); + + prAuthFrame = (struct WLAN_AUTH_FRAME *) prSwRfb->pvHeader; + + DBGLOG(BOW, EVENT, "bowValidateAuth, prBowFsmInfo->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", + prBowFsmInfo->aucPeerAddress[0], + prBowFsmInfo->aucPeerAddress[1], + prBowFsmInfo->aucPeerAddress[2], + prBowFsmInfo->aucPeerAddress[3], prBowFsmInfo->aucPeerAddress[4], prBowFsmInfo->aucPeerAddress[5]); + DBGLOG(BOW, EVENT, "bowValidateAuth, prAuthFrame->aucSrcAddr, %x:%x:%x:%x:%x:%x.\n", + prAuthFrame->aucSrcAddr[0], + prAuthFrame->aucSrcAddr[1], + prAuthFrame->aucSrcAddr[2], + prAuthFrame->aucSrcAddr[3], prAuthFrame->aucSrcAddr[4], prAuthFrame->aucSrcAddr[5]); + + prStaRec = cnmGetStaRecByAddress(prAdapter, prBowFsmInfo->ucBssIndex, prAuthFrame->aucSrcAddr); + if (!prStaRec) { + DBGLOG(BOW, EVENT, "bowValidateAuth, cnmStaRecAlloc.\n"); + prStaRec = cnmStaRecAlloc(prAdapter, + STA_TYPE_BOW_CLIENT, prBowFsmInfo->ucBssIndex, prAuthFrame->aucSrcAddr); + + /* TODO(Kevin): Error handling of allocation of struct STA_RECORD for + * exhausted case and do removal of unused struct STA_RECORD. + */ + ASSERT(prStaRec); + COPY_MAC_ADDR(prStaRec->aucMacAddr, prAuthFrame->aucSrcAddr); + prSwRfb->ucStaRecIdx = prStaRec->ucIndex; + prBowBssInfo->prStaRecOfAP = prStaRec; + + /* NOTE(Kevin): Better to change state here, not at TX Done */ + cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); + DBGLOG(BOW, EVENT, "bowValidateAuth, cnmStaRecChangeState.\n"); + } else { + prSwRfb->ucStaRecIdx = prStaRec->ucIndex; + DBGLOG(BOW, EVENT, "bowValidateAuth, prStaRec->ucIndex, %x.\n", prStaRec->ucIndex); + bssRemoveClient(prAdapter, prBowBssInfo, prStaRec); + } + + if (EQUAL_MAC_ADDR(prAuthFrame->aucSrcAddr, prBowFsmInfo->aucPeerAddress)) { + DBGLOG(BOW, EVENT, "bowValidateAuth, prStaRec->eStaType, %x.\n", prStaRec->eStaType); + DBGLOG(BOW, EVENT, "bowValidateAuth, prStaRec->ucBssIndex, %x.\n", prStaRec->ucBssIndex); + + /* Update Station Record - Status/Reason Code */ + prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL; + prStaRec->ucJoinFailureCount = 0; + *pprStaRec = prStaRec; + *pu2StatusCode = STATUS_CODE_SUCCESSFUL; + fgReplyAuth = TRUE; + } else { + cnmStaRecFree(prAdapter, prStaRec); + *pu2StatusCode = STATUS_CODE_REQ_DECLINED; + + /*Reply auth with reject every 5s */ + rCurrentTime = kalGetTimeTick(); + if (CHECK_FOR_TIMEOUT(rCurrentTime, rLastRejectAuthTime, MSEC_TO_SYSTIME(5000)) || + rLastRejectAuthTime == 0) { + fgReplyAuth = TRUE; + rLastRejectAuthTime = rCurrentTime; + } + } + + DBGLOG(BOW, EVENT, "bowValidateAuth, fgReplyAuth, %x.\n", fgReplyAuth); + return fgReplyAuth; + +#else + return 0; +#endif +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function is invoked when CNM granted channel privilege +* +* \param[in] prAdapter Pointer of ADAPTER_T +* +* \return none +*/ +/*----------------------------------------------------------------------------*/ +void bowRunEventChGrant(IN struct ADAPTER *prAdapter, IN struct MSG_HDR *prMsgHdr) +{ +#if 1 /* Marked for MT6630 */ + struct BSS_INFO *prBowBssInfo; + struct BOW_FSM_INFO *prBowFsmInfo; + struct MSG_CH_GRANT *prMsgChGrant; + uint8_t ucTokenID; + uint32_t u4GrantInterval; + enum ENUM_BOW_DEVICE_STATE eFsmState; + + ASSERT(prAdapter); + ASSERT(prMsgHdr); + + prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); + prBowBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prBowFsmInfo->ucBssIndex); + prMsgChGrant = (struct MSG_CH_GRANT *) prMsgHdr; + ucTokenID = prMsgChGrant->ucTokenID; + u4GrantInterval = prMsgChGrant->u4GrantInterval; + + /* 1. free message */ + cnmMemFree(prAdapter, prMsgHdr); + prBowFsmInfo->fgIsChannelGranted = TRUE; + + DBGLOG(BOW, EVENT, "Entering bowRunEventChGrant.\n"); + + eFsmState = bowGetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress); + + /*Release channel */ + if ((!prBowFsmInfo->fgIsChannelRequested) || + (prBowFsmInfo->ucSeqNumOfChReq != ucTokenID) || + (eFsmState == BOW_DEVICE_STATE_DISCONNECTED) || (eFsmState == BOW_DEVICE_STATE_DISCONNECTING)) { + DBGLOG(BOW, EVENT, "BoW Channel [GIVE UP:%d]\n", ucTokenID); + DBGLOG(BOW, EVENT, "[Requested:%d][ucSeqNumOfChReq:%d][eFsmState:%d]\n", + prBowFsmInfo->fgIsChannelRequested, prBowFsmInfo->ucSeqNumOfChReq, eFsmState); + bowReleaseCh(prAdapter); + return; + } + + /* 2. channel privilege has been approved */ + prBowFsmInfo->u4ChGrantedInterval = u4GrantInterval; + +#if 0 + cnmTimerStartTimer(prAdapter, + &prBowFsmInfo->rChGrantedTimer, + prBowFsmInfo->u4ChGrantedInterval - BOW_JOIN_CH_GRANT_THRESHOLD); +#else + cnmTimerStartTimer(prAdapter, + &prBowFsmInfo->rChGrantedTimer, BOW_JOIN_CH_REQUEST_INTERVAL - BOW_JOIN_CH_GRANT_THRESHOLD); +#endif + + /* 3.2 set local variable to indicate join timer is ticking */ + + DBGLOG(BOW, EVENT, "BoW Channel [GRANTED:%d].\n", ucTokenID); + + if (eFsmState == BOW_DEVICE_STATE_ACQUIRING_CHANNEL) { + bowStarting(prAdapter); + bowReleaseCh(prAdapter); + if (prBowFsmInfo->ucRole == BOW_RESPONDER) + bowResponderJoin(prAdapter, prBowFsmInfo->prTargetBssDesc); + } else { + /*update bssinfo */ + nicUpdateBss(prAdapter, prBowFsmInfo->ucBssIndex); + bowReleaseCh(prAdapter); + } + + return; +#endif /* Marked for MT6630 */ +} /* end of aisFsmRunEventChGrant() */ + +#if 1 /* Marked for MT6630 */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function is to inform CNM for channel privilege requesting +* has been released +* +* \param[in] prAdapter Pointer of ADAPTER_T +* +* \return none +*/ +/*----------------------------------------------------------------------------*/ +void bowRequestCh(IN struct ADAPTER *prAdapter) +{ + struct BOW_FSM_INFO *prBowFsmInfo; + struct MSG_CH_REQ *prMsgChReq; + + ASSERT(prAdapter); + + prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); + + if (prBowFsmInfo->fgIsChannelGranted == FALSE) { + + DBGLOG(BOW, EVENT, "BoW channel [REQUEST:%d], %d, %d.\n", + prBowFsmInfo->ucSeqNumOfChReq + 1, prBowFsmInfo->ucPrimaryChannel, prBowFsmInfo->eBand); + + prMsgChReq = (struct MSG_CH_REQ *) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(struct MSG_CH_REQ)); + + if (!prMsgChReq) { + ASSERT(0); /* Can't indicate CNM for channel acquiring */ + return; + } + + prMsgChReq->rMsgHdr.eMsgId = MID_MNY_CNM_CH_REQ; + prMsgChReq->ucBssIndex = prBowFsmInfo->ucBssIndex; + prMsgChReq->ucTokenID = ++prBowFsmInfo->ucSeqNumOfChReq; + prMsgChReq->eReqType = CH_REQ_TYPE_JOIN; +#if 0 + prMsgChReq->u4MaxInterval = BOW_JOIN_CH_REQUEST_INTERVAL; +#else + prMsgChReq->u4MaxInterval = 1; +#endif + /* prBowFsmInfo->prTargetBssDesc->ucChannelNum; */ + prMsgChReq->ucPrimaryChannel = prBowFsmInfo->ucPrimaryChannel; + /* prBowFsmInfo->prTargetBssDesc->eSco; */ + prMsgChReq->eRfSco = CHNL_EXT_SCN; + /* prBowFsmInfo->prTargetBssDesc->eBand; */ + prMsgChReq->eRfBand = prBowFsmInfo->eBand; + + /* FIXME : where to call cnmGetDbdcCapability in BOW? */ + /*prMsgChReq->eDBDCBand = (prAdapter->aprBssInfo[prMsgChReq->ucBssIndex])->eDBDCBand;*/ + prMsgChReq->eDBDCBand = ENUM_BAND_AUTO; + + /* To do: check if 80/160MHz bandwidth is needed here */ + prMsgChReq->eRfChannelWidth = 0; + prMsgChReq->ucRfCenterFreqSeg1 = 0; + prMsgChReq->ucRfCenterFreqSeg2 = 0; + + prBowFsmInfo->fgIsChannelRequested = TRUE; + + mboxSendMsg(prAdapter, MBOX_ID_0, (struct MSG_HDR *) prMsgChReq, MSG_SEND_METHOD_BUF); + } +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function is to inform BOW that channel privilege is granted +* has been released +* +* \param[in] prAdapter Pointer of ADAPTER_T +* +* \return none +*/ +/*----------------------------------------------------------------------------*/ +void bowReleaseCh(IN struct ADAPTER *prAdapter) +{ + struct BOW_FSM_INFO *prBowFsmInfo; + struct MSG_CH_ABORT *prMsgChAbort; + + ASSERT(prAdapter); + + prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); + + if (prBowFsmInfo->fgIsChannelGranted != FALSE || prBowFsmInfo->fgIsChannelRequested != FALSE) { + DBGLOG(BOW, EVENT, + "BoW channel [RELEASE:%d] %d, %d.\n", prBowFsmInfo->ucSeqNumOfChReq, + prBowFsmInfo->ucPrimaryChannel, prBowFsmInfo->eBand); + + prBowFsmInfo->fgIsChannelRequested = FALSE; + prBowFsmInfo->fgIsChannelGranted = FALSE; + + /* 1. return channel privilege to CNM immediately */ + prMsgChAbort = (struct MSG_CH_ABORT *) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(struct MSG_CH_ABORT)); + if (!prMsgChAbort) { + ASSERT(0); /* Can't release Channel to CNM */ + return; + } + + prMsgChAbort->rMsgHdr.eMsgId = MID_MNY_CNM_CH_ABORT; + prMsgChAbort->ucBssIndex = prBowFsmInfo->ucBssIndex; + prMsgChAbort->ucTokenID = prBowFsmInfo->ucSeqNumOfChReq; + + /* FIXME : where to call cnmGetDbdcCapability in BOW? */ + /*prMsgChAbort->eDBDCBand = (prAdapter->aprBssInfo[prMsgChAbort->ucBssIndex])->eDBDCBand;*/ + prMsgChAbort->eDBDCBand = ENUM_BAND_AUTO; + + mboxSendMsg(prAdapter, MBOX_ID_0, (struct MSG_HDR *) prMsgChAbort, MSG_SEND_METHOD_BUF); + } + +} /* end of aisFsmReleaseCh() */ + +/*----------------------------------------------------------------------------*/ +/*! +* @brief This function will indicate an Event of "Media Disconnect" to HOST +* +* @param[in] u4Param Unused timer parameter +* +* @return (none) +*/ +/*----------------------------------------------------------------------------*/ +void bowChGrantedTimeout(IN struct ADAPTER *prAdapter, IN unsigned long ulParamPtr) +{ + struct BOW_FSM_INFO *prBowFsmInfo; + enum ENUM_BOW_DEVICE_STATE eFsmState; + + ASSERT(prAdapter); + + prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); + + DBGLOG(BOW, EVENT, "BoW Channel [TIMEOUT]\n"); + +#if 1 + /* bowReleaseCh(prAdapter); */ + eFsmState = bowGetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress); + + /*If connecting is not completed, request CH again */ + if ((eFsmState == BOW_DEVICE_STATE_CONNECTING) || (eFsmState == BOW_DEVICE_STATE_STARTING)) + bowRequestCh(prAdapter); +#endif +} + +#endif /* Marked for MT6630 */ + +u_int8_t bowNotifyAllLinkDisconnected(IN struct ADAPTER *prAdapter) +{ +#if 1 /* Marked for MT6630 */ + + uint8_t ucBowTableIdx = 0; + struct CMD_INFO rCmdInfo; + struct BOW_FSM_INFO *prBowFsmInfo; + + ASSERT(prAdapter); + + prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); + + kalMemZero(&rCmdInfo, sizeof(struct CMD_INFO)); + + while (ucBowTableIdx < CFG_BOW_PHYSICAL_LINK_NUM) { + if (arBowTable[ucBowTableIdx].fgIsValid) { + COPY_MAC_ADDR(prAdapter->rWifiVar.rBowFsmInfo.aucPeerAddress, + arBowTable[ucBowTableIdx].aucPeerAddress); + DBGLOG(BOW, EVENT, + "bowNotifyAllLinkDisconnected, arBowTable[%x].aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", + ucBowTableIdx, arBowTable[ucBowTableIdx].aucPeerAddress[0], + arBowTable[ucBowTableIdx].aucPeerAddress[1], + arBowTable[ucBowTableIdx].aucPeerAddress[2], + arBowTable[ucBowTableIdx].aucPeerAddress[3], + arBowTable[ucBowTableIdx].aucPeerAddress[4], + arBowTable[ucBowTableIdx].aucPeerAddress[5]); + DBGLOG(BOW, EVENT, + "bowNotifyAllLinkDisconnected, arBowTable[%x].fgIsValid, %x.\n", + ucBowTableIdx, arBowTable[ucBowTableIdx].fgIsValid); +#if 1 + wlanoidSendSetQueryBowCmd(prAdapter, + CMD_ID_CMD_BT_OVER_WIFI, + prBowFsmInfo->ucBssIndex, + TRUE, + FALSE, + wlanbowCmdEventLinkDisconnected, + wlanbowCmdTimeoutHandler, 0, NULL, 0); +#else + wlanbowCmdEventLinkDisconnected(prAdapter, &rCmdInfo, NULL); +#endif + } + + ucBowTableIdx += 1; + } + + return TRUE; + +#else + return 0; +#endif +} + +#if 1 /* Marked for MT6630 */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief to retrieve Bluetooth-over-Wi-Fi state from glue layer +* +* \param[in] +* prGlueInfo +* rPeerAddr +* \return +* ENUM_BOW_DEVICE_STATE +*/ +/*----------------------------------------------------------------------------*/ + +u_int8_t bowCheckBowTableIfVaild(IN struct ADAPTER *prAdapter, IN uint8_t aucPeerAddress[6]) +{ + uint8_t idx; + + KAL_SPIN_LOCK_DECLARATION(); + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); + + for (idx = 0; idx < CFG_BOW_PHYSICAL_LINK_NUM; idx++) { + if (arBowTable[idx].fgIsValid && EQUAL_MAC_ADDR(arBowTable[idx].aucPeerAddress, aucPeerAddress)) { + + DBGLOG(BOW, EVENT, + "kalCheckBowifVaild, aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", idx, + aucPeerAddress[0], aucPeerAddress[1], aucPeerAddress[2], + aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5]); + + DBGLOG(BOW, EVENT, + "kalCheckBowifVaild, arBowTable[idx].aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", + idx, arBowTable[idx].aucPeerAddress[0], + arBowTable[idx].aucPeerAddress[1], + arBowTable[idx].aucPeerAddress[2], + arBowTable[idx].aucPeerAddress[3], + arBowTable[idx].aucPeerAddress[4], arBowTable[idx].aucPeerAddress[5]); + + DBGLOG(BOW, EVENT, + "kalCheckBowifVaild, arBowTable[idx].fgIsValid, %x, %x.\n", idx, + arBowTable[idx].fgIsValid); + + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); + return TRUE; + } + } + + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); + return FALSE; +} + +u_int8_t bowGetBowTableContent(IN struct ADAPTER *prAdapter, IN uint8_t ucBowTableIdx, OUT struct BOW_TABLE *prBowTable) +{ + KAL_SPIN_LOCK_DECLARATION(); + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); + + if (arBowTable[ucBowTableIdx].fgIsValid) { + + DBGLOG(BOW, EVENT, + "bowGetBowTableContent, arBowTable[idx].fgIsValid, %x, %x.\n", + ucBowTableIdx, arBowTable[ucBowTableIdx].fgIsValid); + DBGLOG(BOW, EVENT, "GET State [%d]\n", arBowTable[ucBowTableIdx].eState); + prBowTable = &(arBowTable[ucBowTableIdx]); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); + + return TRUE; + } + + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); + + return FALSE; +} + +u_int8_t bowSetBowTableContent(IN struct ADAPTER *prAdapter, IN uint8_t ucBowTableIdx, IN struct BOW_TABLE *prBowTable) +{ + KAL_SPIN_LOCK_DECLARATION(); + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); + + COPY_MAC_ADDR(arBowTable[ucBowTableIdx].aucPeerAddress, prBowTable->aucPeerAddress); + arBowTable[ucBowTableIdx].eState = prBowTable->eState; + arBowTable[ucBowTableIdx].fgIsValid = prBowTable->fgIsValid; + arBowTable[ucBowTableIdx].ucAcquireID = prBowTable->ucAcquireID; + + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); + + kalSetBowState(prAdapter->prGlueInfo, prBowTable->eState, prBowTable->aucPeerAddress); + /* kalSetBowRole(prAdapter->prGlueInfo, prBowTable->ucRole, prBowTable->aucPeerAddress); */ + + DBGLOG(BOW, EVENT, "SET State [%d]\n", arBowTable[ucBowTableIdx].eState); + DBGLOG(BOW, EVENT, + "kalCheckBowifVaild, arBowTable[ucBowTableIdx].fgIsValid, %x, %x.\n", ucBowTableIdx, + arBowTable[ucBowTableIdx].fgIsValid); + + return TRUE; + +} + +u_int8_t +bowGetBowTableEntryByPeerAddress(IN struct ADAPTER *prAdapter, IN uint8_t aucPeerAddress[6], OUT uint8_t *pucBowTableIdx) +{ + uint8_t idx; + + KAL_SPIN_LOCK_DECLARATION(); + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); + + for (idx = 0; idx < CFG_BOW_PHYSICAL_LINK_NUM; idx++) { + if (arBowTable[idx].fgIsValid && EQUAL_MAC_ADDR(arBowTable[idx].aucPeerAddress, aucPeerAddress)) { + + DBGLOG(BOW, EVENT, + "kalCheckBowifVaild, aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", idx, + aucPeerAddress[0], aucPeerAddress[1], aucPeerAddress[2], + aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5]); + DBGLOG(BOW, EVENT, + "kalCheckBowifVaild, arBowTable[idx].aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", + idx, arBowTable[idx].aucPeerAddress[0], + arBowTable[idx].aucPeerAddress[1], + arBowTable[idx].aucPeerAddress[2], + arBowTable[idx].aucPeerAddress[3], + arBowTable[idx].aucPeerAddress[4], arBowTable[idx].aucPeerAddress[5]); + DBGLOG(BOW, EVENT, + "kalCheckBowifVaild, arBowTable[idx].fgIsValid, %x, %x.\n", idx, + arBowTable[idx].fgIsValid); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); + + *pucBowTableIdx = idx; + + return TRUE; + } + } + + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); + + return FALSE; +} + +u_int8_t bowGetBowTableFreeEntry(IN struct ADAPTER *prAdapter, OUT uint8_t *pucBowTableIdx) +{ + uint8_t idx; + + KAL_SPIN_LOCK_DECLARATION(); + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); + + for (idx = 0; idx < CFG_BOW_PHYSICAL_LINK_NUM; idx++) { + if (!arBowTable[idx].fgIsValid) { + DBGLOG(BOW, EVENT, + "bowGetBowTableFreeEntry, arBowTable[idx].fgIsValid, %x, %x.\n", + idx, arBowTable[idx].fgIsValid); + *pucBowTableIdx = idx; + arBowTable[idx].fgIsValid = TRUE; + + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); + + return TRUE; + } + } + + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); + + return FALSE; +} + +enum ENUM_BOW_DEVICE_STATE bowGetBowTableState(IN struct ADAPTER *prAdapter, IN uint8_t aucPeerAddress[6]) +{ + uint8_t idx; + + KAL_SPIN_LOCK_DECLARATION(); + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); + + for (idx = 0; idx < CFG_BOW_PHYSICAL_LINK_NUM; idx++) { + if (arBowTable[idx].fgIsValid && EQUAL_MAC_ADDR(arBowTable[idx].aucPeerAddress, aucPeerAddress)) { + DBGLOG(BOW, EVENT, + "bowGetState, aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", idx, + aucPeerAddress[0], aucPeerAddress[1], aucPeerAddress[2], + aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5]); + DBGLOG(BOW, EVENT, + "bowGetState, arBowTable[idx].aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", + idx, arBowTable[idx].aucPeerAddress[0], + arBowTable[idx].aucPeerAddress[1], + arBowTable[idx].aucPeerAddress[2], + arBowTable[idx].aucPeerAddress[3], + arBowTable[idx].aucPeerAddress[4], arBowTable[idx].aucPeerAddress[5]); + DBGLOG(BOW, EVENT, + "bowGetState, arBowTable[idx].fgIsValid, %x, %x.\n", idx, arBowTable[idx].fgIsValid); + DBGLOG(BOW, EVENT, + "bowGetState, arBowTable[idx].eState;, %x, %x.\n", idx, arBowTable[idx].eState); + DBGLOG(BOW, EVENT, "GET State [%d]\n", arBowTable[idx].eState); + + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); + + return arBowTable[idx].eState; + } + } + + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); + + return BOW_DEVICE_STATE_DISCONNECTED; +} + +u_int8_t bowSetBowTableState(IN struct ADAPTER *prAdapter, IN uint8_t aucPeerAddress[6], IN enum ENUM_BOW_DEVICE_STATE eState) +{ + uint8_t ucBowTableIdx; + + if (bowGetBowTableEntryByPeerAddress(prAdapter, aucPeerAddress, &ucBowTableIdx)) { + KAL_SPIN_LOCK_DECLARATION(); + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); + + arBowTable[ucBowTableIdx].eState = eState; + DBGLOG(BOW, EVENT, "SET State [%d]\n", eState); + + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); + + kalSetBowState(prAdapter->prGlueInfo, eState, aucPeerAddress); + return TRUE; + } + return FALSE; +} + +#endif + +#endif /* Marked for MT6630 */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/common/wlan_he.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/common/wlan_he.c new file mode 100644 index 0000000000000000000000000000000000000000..8666c1b9e5e507fa9f77d36b0a4a00b30d8e85c0 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/common/wlan_he.c @@ -0,0 +1,104 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/*! \file wlan_he.c +* \brief This file contains the HE(802.11ax) processing routines for +* MediaTek Inc. 802.11 Wireless LAN Adapters. +*/ + +/****************************************************************************** +* C O M P I L E R F L A G S +******************************************************************************* +*/ + +/****************************************************************************** +* E X T E R N A L R E F E R E N C E S +******************************************************************************* +*/ +#include "precomp.h" + +#if (CFG_SUPPORT_802_11AX == 1) +/****************************************************************************** +* C O N S T A N T S +******************************************************************************* +*/ + +/****************************************************************************** +* D A T A T Y P E S +******************************************************************************* +*/ + +/****************************************************************************** +* P U B L I C D A T A +******************************************************************************* +*/ + +/****************************************************************************** +* P R I V A T E D A T A +******************************************************************************* +*/ + +/****************************************************************************** +* M A C R O S +******************************************************************************* +*/ + +/****************************************************************************** +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************* +*/ + +/****************************************************************************** +* F U N C T I O N S +******************************************************************************* +*/ +#endif /* CFG_SUPPORT_802_11AX == 1 */ + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/common/wlan_lib.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/common/wlan_lib.c new file mode 100644 index 0000000000000000000000000000000000000000..d90aed8b565596461005ea8429e5d98a83eb3022 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/common/wlan_lib.c @@ -0,0 +1,12431 @@ +/******************************************************************************* + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ +/*! \file wlan_lib.c + * \brief Internal driver stack will export the required procedures here for + * GLUE Layer. + * + * This file contains all routines which are exported from MediaTek 802.11 + * Wireless LAN driver stack to GLUE Layer. + */ + + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" +#include "mgmt/ais_fsm.h" +#if CFG_MTK_MCIF_WIFI_SUPPORT +#include "mddp.h" +#endif + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +/* 6.1.1.2 Interpretation of priority parameter in MAC service primitives */ +/* Static convert the Priority Parameter/TID(User Priority/TS Identifier) to + * Traffic Class + */ +const uint8_t aucPriorityParam2TC[] = { + TC1_INDEX, + TC0_INDEX, + TC0_INDEX, + TC1_INDEX, + TC2_INDEX, + TC2_INDEX, + TC3_INDEX, + TC3_INDEX +}; + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +struct CODE_MAPPING { + uint32_t u4RegisterValue; + int32_t u4TxpowerOffset; +}; + +struct NVRAM_TAG_FRAGMENT_GROUP { + uint8_t u1StartTagID; + uint8_t u1EndTagID; +}; + +struct NVRAM_FRAGMENT_RANGE { + uint32_t startOfs; + uint32_t endOfs; +}; + + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ +u_int8_t fgIsBusAccessFailed = FALSE; + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ +/* data rate mapping table for CCK */ +struct cckDataRateMappingTable_t { + uint32_t rate[4]; +} g_rCckDataRateMappingTable = { + {10, 20, 55, 110} +}; +/* data rate mapping table for OFDM */ +struct ofdmDataRateMappingTable_t { + uint32_t rate[8]; +} g_rOfdmDataRateMappingTable = { + {60, 90, 120, 180, 240, 360, 480, 540} +}; +/* data rate mapping table for 802.11n and 802.11ac */ +struct dataRateMappingTable_t { + struct nsts_t { + struct bw_t { + struct sgi_t { + uint32_t rate[10]; + } sgi[2]; + } bw[4]; + } nsts[3]; +} g_rDataRateMappingTable = { +{ { { { { /* 20MHz */ + { /* no SGI */ + {65, 130, 195, 260, 390, 520, 585, 650, 780, 867} + }, + { /* SGI */ + {72, 144, 217, 289, 433, 578, 650, 722, 867, 963} + } +} }, +{ + { /* 40MHz */ + { /* no SGI */ + {135, 270, 405, 540, 810, 1080, 1215, 1350, 1620, 1800} + }, + { /* SGI */ + {150, 300, 450, 600, 900, 1200, 1350, 1500, 1800, 2000} + } +} }, +{ + { /* 80MHz */ + { /* no SGI */ + {293, 585, 878, 1170, 1755, 2340, 2633, 2925, 3510, 3900} + }, + { /* SGI */ + {325, 650, 975, 1300, 1950, 2600, 2925, 3250, 3900, 4333} + } +} }, +{ + { /* 160MHz */ + { /* no SGI */ + {585, 1170, 1755, 2340, 3510, 4680, 5265, 5850, 7020, 7800} + }, + { /* SGI */ + {650, 1300, 1950, 2600, 3900, 5200, 5850, 6500, 7800, 8667} + } +} } } }, +{ { { + { /* 20MHz */ + { /* no SGI */ + {130, 260, 390, 520, 780, 1040, 1170, 1300, 1560, 1733} + }, + { /* SGI */ + {144, 289, 433, 578, 867, 1156, 1303, 1444, 1733, 1927} + } +} }, +{ + { /* 40MHz */ + { /* no SGI */ + {270, 540, 810, 1080, 1620, 2160, 2430, 2700, 3240, 3600} + }, + { /* SGI */ + {300, 600, 900, 1200, 1800, 2400, 2700, 3000, 3600, 4000} + } +} }, +{ + { /* 80MHz */ + { /* no SGI */ + {585, 1170, 1755, 2340, 3510, 4680, 5265, 5850, 7020, 7800} + }, + { /* SGI */ + {650, 1300, 1950, 2600, 3900, 5200, 5850, 6500, 7800, 8667} + } +} }, +{ + { /* 160MHz */ + { /* no SGI */ + {1170, 2340, 3510, 4680, 7020, 9360, 10530, 11700, 14040, 15600} + }, + { /* SGI */ + {1300, 2600, 3900, 5200, 7800, 10400, 11700, 13000, 15600, 17333} + } +} } } }, +{ { { + { /* 20MHz */ + { /* no SGI */ + {195, 390, 585, 780, 1170, 1560, 1755, 1950, 2340, 2600} + }, + { /* SGI */ + {217, 433, 650, 867, 1300, 1733, 1950, 2167, 2600, 2889} + } +} }, +{ + { /* 40MHz */ + { /* no SGI */ + {405, 810, 1215, 1620, 2430, 3240, 3645, 4050, 4860, 5400} + }, + { /* SGI */ + {450, 900, 1350, 1800, 2700, 3600, 4050, 4500, 5400, 6000} + } +} }, +{ + { /* 80MHz */ + { /* no SGI */ + {878, 1755, 2633, 3510, 5265, 7020, 0, 8775, 10530, 11700} + }, + { /* SGI */ + {975, 1950, 2925, 3900, 5850, 7800, 0, 9750, 11700, 13000} + } +} }, +{ + { /* 160MHz */ + { /* no SGI */ + {1755, 3510, 5265, 7020, 10530, 14040, 15795, 17550, 21060, 23400} + }, + { /* SGI */ + {1950, 3900, 5850, 7800, 11700, 15600, 17550, 19500, 23400, 26000} + } +} } } } } +}; + +/* data rate mapping table for ax */ +struct axDataRateMappingTable_t { + struct axNsts_t { + struct axBw_t { + struct axGi_t { + uint32_t rate[12]; + } gi[3]; + } bw[4]; + } nsts[4]; +} g_rAxDataRateMappingTable = { +{ { { { { /* 20MHz */ + { /* HE GI 0.8 */ + {86, 172, 258, 344, 516, 688, 774, 860, 1032, 1147, 1290, 1434} + }, + { /* HE GI 1.6 */ + {81, 163, 244, 325, 488, 650, 731, 813, 975, 1083, 1219, 1354} + }, + { /* HE GI 3.2 */ + {73, 146, 219, 293, 439, 585, 658, 731, 878, 975, 1097, 1219} + } +} }, +{ + { /* 40MHz */ + { /* HE GI 0.8 */ + {172, 344, 516, 688, 1032, 1376, 1549, 1721, 2065, 2294, 2581, 2868} + }, + { /* HE GI 1.6 */ + {163, 325, 488, 650, 975, 1300, 1463, 1625, 1950, 2167, 2438, 2708} + }, + { /* HE GI 3.2 */ + {146, 293, 439, 585, 878, 1170, 1316, 1463, 1755, 1950, 2194, 2438} + } +} }, +{ + { /* 80MHz */ + { /* HE GI 0.8 */ + {360, 721, 1081, 1441, 2162, 2882, 3243, 3603, 4324, 4804, 5404, 6005} + }, + { /* HE GI 1.6 */ + {340, 681, 1021, 1361, 2042, 2722, 3063, 3403, 4083, 4537, 5104, 5671} + }, + { /* HE GI 3.2 */ + {306, 613, 919, 1225, 1838, 2450, 2756, 3063, 3675, 4083, 4594, 5104} + } +} }, +{ + { /* 160MHz */ + { /* HE GI 0.8 */ + {721, 1441, 2162, 2882, 4324, 5765, 6485, 7206, 8647, 9608, 10809, + 12010} + }, + { /* HE GI 1.6 */ + {681, 1361, 2042, 2722, 4083, 5444, 6125, 6806, 8167, 9074, 10208, + 11343} + }, + { /* HE GI 3.2 */ + {613, 1225, 1838, 2450, 3675, 4900, 5513, 6125, 7350, 8167, 9188, 10208} + } +} } } }, +{ { { + { /* 20MHz */ + { /* HE GI 0.8 */ + {172, 344, 516, 688, 1032, 1376, 1549, 1721, 2065, 2294, 2581, 2868} + }, + { /* HE GI 1.6 */ + {163, 352, 488, 650, 975, 1300, 1463, 1625, 1950, 2167, 2438, 2708} + }, + { /* HE GI 3.2 */ + {146, 293, 439, 585, 878, 1170, 1316, 1463, 1755, 1950, 2194, 2438} + } +} }, +{ + { /* 40MHz */ + { /* HE GI 0.8 */ + {344, 688, 1032, 1376, 2065, 2753, 3097, 3441, 4129, 4588, 5162, 5735} + }, + { /* HE GI 1.6 */ + {325, 650, 975, 1300, 1950, 2600, 2925, 3250, 3900, 4333, 4875, 5417} + }, + { /* HE GI 3.2 */ + {293, 585, 878, 1170, 1755, 2340, 2633, 2925, 3510, 3900, 4388, 4875} + } +} }, +{ + { /* 80MHz */ + { /* HE GI 0.8 */ + {721, 1441, 2162, 2882, 4324, 5765, 6485, 7206, 8647, 9608, 10809, + 12010} + }, + { /* HE GI 1.6 */ + {681, 1361, 2042, 2722, 4083, 5444, 6125, 6806, 8167, 9074, 10208, + 11343} + }, + { /* HE GI 3.2 */ + {613, 1225, 1838, 2450, 3675, 4900, 5513, 6125, 7350, 8167, 9188, 10208} + } +} }, +{ + { /* 160MHz */ + { /* HE GI 0.8 */ + {1441, 2882, 4324, 5765, 8647, 11529, 12971, 14412, 17294, 19216, 21618, + 24020} + }, + { /* HE GI 1.6 */ + {1361, 2722, 4083, 5444, 8167, 10889, 12250, 13611, 16333, 18148, 20417, + 22685} + }, + { /* HE GI 3.2 */ + {1225, 2450, 3675, 4900, 7350, 9800, 11025, 12250, 14700, 16333, 18375, + 20417} + } +} } } }, +{ { { + { /* 20MHz */ + { /* HE GI 0.8 */ + {258, 516, 774, 1032, 1549, 2065, 2323, 2581, 3097, 3441, 3871, 4301} + }, + { /* HE GI 1.6 */ + {244, 488, 721, 975, 1463, 1950, 2194, 2438, 2925, 3250, 3656, 4063} + }, + { /* HE GI 3.2 */ + {219, 439, 658, 878, 1316, 1755, 1974, 2194, 2633, 2925, 3291, 3656} + } +} }, +{ + { /* 40MHz */ + { /* HE GI 0.8 */ + {516, 1032, 1549, 2065, 3097, 4129, 4646, 5162, 6194, 6882, 7743, 8603} + }, + { /* HE GI 1.6 */ + {488, 975, 1463, 1950, 2925, 3900, 4388, 4875, 5850, 6500, 7313, 8125} + }, + { /* HE GI 3.2 */ + {439, 878, 1316, 1755, 2633, 3510, 3949, 4388, 5265, 5850, 6581, 7313} + } +} }, +{ + { /* 80MHz */ + { /* HE GI 0.8 */ + {1081, 2162, 3243, 4324, 6485, 8647, 9728, 10809, 12971, 14412, 16213, + 18015} + }, + { /* HE GI 1.6 */ + {1021, 2042, 3063, 4083, 6125, 8167, 9188, 10208, 12250, 13611, 15313, + 17014} + }, + { /* HE GI 3.2 */ + {919, 1838, 2756, 3675, 5513, 7350, 8269, 9188, 11025, 12250, 13781, + 15313} + } +} }, +{ + { /* 160MHz */ + { /* HE GI 0.8 */ + {2162, 4324, 6485, 8647, 12971, 17294, 19456, 21618, 25941, 28824, + 32426, 36029} + }, + { /* HE GI 1.6 */ + {1042, 4083, 6125, 8167, 12250, 16333, 18375, 20417, 24500, 27222, + 30625, 34028} + }, + { /* HE GI 3.2 */ + {1838, 3675, 5513, 7350, 11025, 14700, 16538, 18375, 22050, 24500, + 27563, 30625} + } +} } } }, +{ { { + { /* 20MHz */ + { /* HE GI 0.8 */ + {344, 688, 1032, 1376, 2065, 2753, 3097, 3441, 4129, 4588, 5162, 5735} + }, + { /* HE GI 1.6 */ + {325, 650, 975, 1300, 1950, 2600, 2925, 3250, 3900, 4333, 4875, 5417} + }, + { /* HE GI 3.2 */ + {293, 585, 878, 1170, 1755, 2340, 2633, 2925, 3510, 3900, 4388, 4875} + } +} }, +{ + { /* 40MHz */ + { /* HE GI 0.8 */ + {688, 1376, 2065, 2753, 4129, 5506, 6194, 6882, 8259, 9176, 10324, + 11471} + }, + { /* HE GI 1.6 */ + {650, 1300, 1950, 2600, 3900, 5200, 5850, 6500, 7800, 8667, 9750, 10833} + }, + { /* HE GI 3.2 */ + {585, 1170, 1755, 2340, 3510, 4680, 5265, 5850, 7020, 7800, 8775, 9750} + } +} }, +{ + { /* 80MHz */ + { /* HE GI 0.8 */ + {1441, 2882, 4324, 5765, 8647, 11529, 12971, 14412, 17294, 19216, 21618, + 24020} + }, + { /* HE GI 1.6 */ + {1361, 2722, 4083, 5444, 8167, 10889, 12250, 13611, 16333, 18148, 20417, + 22685} + }, + { /* HE GI 3.2 */ + {1225, 2450, 3675, 4900, 7350, 9800, 11025, 12250, 14700, 16333, 18375, + 20417} + } +} }, +{ + { /* 160MHz */ + { /* HE GI 0.8 */ + {2882, 5765, 8647, 11529, 17294, 23059, 25941, 28824, 34588, 38431, + 43235, 48039} + }, + { /* HE GI 1.6 */ + {2722, 5444, 8167, 10889, 16333, 21778, 24500, 27222, 32667, 36296, + 40833, 45370} + }, + { /* HE GI 3.2 */ + {2450, 4900, 7350, 9800, 14700, 19600, 22050, 24500, 29400, 32667, + 36750, 40833} + } +} } } } } +}; + +struct PARAM_CUSTOM_KEY_CFG_STRUCT g_rEmCfgBk[WLAN_CFG_REC_ENTRY_NUM_MAX]; + + +struct PARAM_CUSTOM_KEY_CFG_STRUCT g_rDefaulteSetting[] = { + /*format : + *: { + * "firmware config parameter", + * "firmware config value", + * "Operation:default 0" + * } + */ + {"AdapScan", "0x0", WLAN_CFG_DEFAULT}, +#if CFG_SUPPORT_IOT_AP_BLACKLIST + /*Fill Iot AP blacklist here*/ +#endif +#if CFG_TC3_FEATURE + {"ScreenOnBeaconTimeoutCount", "20"}, + {"ScreenOffBeaconTimeoutCount", "10"}, + {"AgingPeriod", "0x19"}, + {"DropPacketsIPV4Low", "0x1"}, + {"DropPacketsIPV6Low", "0x1"}, + {"Sta2gBw", "1"}, +#endif +}; + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ +#define SIGNED_EXTEND(n, _sValue) \ + (((_sValue) & BIT((n)-1)) ? ((_sValue) | BITS(n, 31)) : \ + ((_sValue) & ~BITS(n, 31))) + +/* TODO: Check */ +/* OID set handlers without the need to access HW register */ +PFN_OID_HANDLER_FUNC apfnOidSetHandlerWOHwAccess[] = { + wlanoidSetChannel, + wlanoidSetBeaconInterval, + wlanoidSetAtimWindow, + wlanoidSetFrequency, +}; + +/* TODO: Check */ +/* OID query handlers without the need to access HW register */ +PFN_OID_HANDLER_FUNC apfnOidQueryHandlerWOHwAccess[] = { + wlanoidQueryBssid, + wlanoidQuerySsid, + wlanoidQueryInfrastructureMode, + wlanoidQueryAuthMode, + wlanoidQueryEncryptionStatus, + wlanoidQueryNetworkTypeInUse, + wlanoidQueryBssidList, + wlanoidQueryAcpiDevicePowerState, + wlanoidQuerySupportedRates, + wlanoidQueryDesiredRates, + wlanoidQuery802dot11PowerSaveProfile, + wlanoidQueryBeaconInterval, + wlanoidQueryAtimWindow, + wlanoidQueryFrequency, +}; + +/* OID set handlers allowed in RF test mode */ +PFN_OID_HANDLER_FUNC apfnOidSetHandlerAllowedInRFTest[] = { + wlanoidRftestSetTestMode, + wlanoidRftestSetAbortTestMode, + wlanoidRftestSetAutoTest, + wlanoidSetMcrWrite, + wlanoidSetEepromWrite +}; + +/* OID query handlers allowed in RF test mode */ +PFN_OID_HANDLER_FUNC apfnOidQueryHandlerAllowedInRFTest[] = { + wlanoidRftestQueryAutoTest, + wlanoidQueryMcrRead, + wlanoidQueryEepromRead +} + +; + +PFN_OID_HANDLER_FUNC apfnOidWOTimeoutCheck[] = { + wlanoidRftestSetTestMode, + wlanoidRftestSetAbortTestMode, + wlanoidSetAcpiDevicePowerState, +}; + +#define TX_RATE_MODE_CCK 0 +#define TX_RATE_MODE_OFDM 1 +#define TX_RATE_MODE_HTMIX 2 +#define TX_RATE_MODE_HTGF 3 +#define TX_RATE_MODE_VHT 4 +#define NVRAM_TAG_HDR_SIZE 3 /*ID+Len MSB+Len LSB*/ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +/*----------------------------------------------------------------------------*/ +/*! + * \brief This is a private routine, which is used to check if HW access is + * needed for the OID query/ set handlers. + * + * \param[IN] pfnOidHandler Pointer to the OID handler. + * \param[IN] fgSetInfo It is a Set information handler. + * + * \retval TRUE This function needs HW access + * \retval FALSE This function does not need HW access + */ +/*----------------------------------------------------------------------------*/ +u_int8_t wlanIsHandlerNeedHwAccess(IN PFN_OID_HANDLER_FUNC + pfnOidHandler, IN u_int8_t fgSetInfo) +{ + PFN_OID_HANDLER_FUNC *apfnOidHandlerWOHwAccess; + uint32_t i; + uint32_t u4NumOfElem; + + if (fgSetInfo) { + apfnOidHandlerWOHwAccess = apfnOidSetHandlerWOHwAccess; + u4NumOfElem = sizeof(apfnOidSetHandlerWOHwAccess) / sizeof( + PFN_OID_HANDLER_FUNC); + } else { + apfnOidHandlerWOHwAccess = apfnOidQueryHandlerWOHwAccess; + u4NumOfElem = sizeof(apfnOidQueryHandlerWOHwAccess) / + sizeof(PFN_OID_HANDLER_FUNC); + } + + for (i = 0; i < u4NumOfElem; i++) { + if (apfnOidHandlerWOHwAccess[i] == pfnOidHandler) + return FALSE; + } + + return TRUE; +} /* wlanIsHandlerNeedHwAccess */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set flag for later handling card + * ejected event. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * + * \return (none) + * + * \note When surprised removal happens, Glue layer should invoke this + * function to notify WPDD not to do any hw access. + */ +/*----------------------------------------------------------------------------*/ +void wlanCardEjected(IN struct ADAPTER *prAdapter) +{ + DEBUGFUNC("wlanCardEjected"); + /* INITLOG(("\n")); */ + + ASSERT(prAdapter); + + /* mark that the card is being ejected, NDIS will shut us down soon */ + nicTxRelease(prAdapter, FALSE); + +} /* wlanCardEjected */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to check driver ready state + * + * \param[in] prGlueInfo Pointer to the GlueInfo structure. + * + * \retval TRUE Driver is ready for kernel access + * \retval FALSE Driver is not ready + */ +/*----------------------------------------------------------------------------*/ +u_int8_t wlanIsDriverReady(IN struct GLUE_INFO *prGlueInfo) +{ + return prGlueInfo && prGlueInfo->u4ReadyFlag && !kalIsResetting(); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Create adapter object + * + * \param prAdapter This routine is call to allocate the driver software + * objects. If fails, return NULL. + * \retval NULL If it fails, NULL is returned. + * \retval NOT NULL If the adapter was initialized successfully. + */ +/*----------------------------------------------------------------------------*/ +struct ADAPTER *wlanAdapterCreate(IN struct GLUE_INFO + *prGlueInfo) +{ + struct ADAPTER *prAdpater = (struct ADAPTER *) NULL; + + DEBUGFUNC("wlanAdapterCreate"); + + do { + prAdpater = (struct ADAPTER *) kalMemAlloc(sizeof( + struct ADAPTER), VIR_MEM_TYPE); + + if (!prAdpater) { + DBGLOG(INIT, ERROR, + "Allocate ADAPTER memory ==> FAILED\n"); + break; + } +#if QM_TEST_MODE + g_rQM.prAdapter = prAdpater; +#endif + kalMemZero(prAdpater, sizeof(struct ADAPTER)); + prAdpater->prGlueInfo = prGlueInfo; + + } while (FALSE); + + return prAdpater; +} /* wlanAdapterCreate */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Destroy adapter object + * + * \param prAdapter This routine is call to destroy the driver software objects. + * If fails, return NULL. + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void wlanAdapterDestroy(IN struct ADAPTER *prAdapter) +{ + if (!prAdapter) + return; + + scanLogCacheFlushAll(prAdapter, + &(prAdapter->rWifiVar.rScanInfo.rScanLogCache), + LOG_SCAN_D2D); + + kalMemFree(prAdapter, VIR_MEM_TYPE, sizeof(struct ADAPTER)); +} + +void wlanOnPreAllocAdapterMem(IN struct ADAPTER *prAdapter, + IN const u_int8_t bAtResetFlow) +{ + uint32_t i = 0; + + DBGLOG(INIT, TRACE, "start.\n"); + + if (!bAtResetFlow) { + /* 4 <0> Reset variables in ADAPTER_T */ + /* prAdapter->fgIsFwOwn = TRUE; */ + prAdapter->fgIsEnterD3ReqIssued = FALSE; + prAdapter->ucHwBssIdNum = BSS_DEFAULT_NUM; + prAdapter->ucWmmSetNum = BSS_DEFAULT_NUM; + prAdapter->ucP2PDevBssIdx = BSS_DEFAULT_NUM; + prAdapter->ucWtblEntryNum = WTBL_SIZE; + prAdapter->ucTxDefaultWlanIndex = prAdapter->ucWtblEntryNum - 1; + + prAdapter->u4HifDbgFlag = 0; + prAdapter->u4HifChkFlag = 0; + prAdapter->u4NoMoreRfb = 0; + + /* Initialize rWlanInfo */ + kalMemSet(&(prAdapter->rWlanInfo), 0, + sizeof(struct WLAN_INFO)); + + /* Initialize aprBssInfo[]. + * Important: index shall be same + * when mapping between aprBssInfo[] + * and arBssInfoPool[].rP2pDevInfo + * is indexed to final one. + */ + for (i = 0; i < MAX_BSSID_NUM; i++) + prAdapter->aprBssInfo[i] = + &prAdapter->rWifiVar.arBssInfoPool[i]; + prAdapter->aprBssInfo[prAdapter->ucP2PDevBssIdx] = + &prAdapter->rWifiVar.rP2pDevInfo; + } else { + /* need to reset these values after the reset flow */ + prAdapter->u4NoMoreRfb = 0; + } + + prAdapter->u4OwnFailedCount = 0; + prAdapter->u4OwnFailedLogCount = 0; + prAdapter->ucCmdSeqNum = 0; + prAdapter->u4PwrCtrlBlockCnt = 0; + + if (bAtResetFlow) { + for (i = 0; i < (prAdapter->ucHwBssIdNum + 1); i++) + UNSET_NET_ACTIVE(prAdapter, i); + } + + QUEUE_INITIALIZE(&(prAdapter->rPendingCmdQueue)); +#if CFG_SUPPORT_MULTITHREAD + QUEUE_INITIALIZE(&prAdapter->rTxCmdQueue); + QUEUE_INITIALIZE(&prAdapter->rTxCmdDoneQueue); +#if CFG_FIX_2_TX_PORT + QUEUE_INITIALIZE(&prAdapter->rTxP0Queue); + QUEUE_INITIALIZE(&prAdapter->rTxP1Queue); +#else + for (i = 0; i < TX_PORT_NUM; i++) + QUEUE_INITIALIZE(&prAdapter->rTxPQueue[i]); +#endif + QUEUE_INITIALIZE(&prAdapter->rRxQueue); + QUEUE_INITIALIZE(&prAdapter->rTxDataDoneQueue); +#endif + + /* 4 <0.1> reset fgIsBusAccessFailed */ + fgIsBusAccessFailed = FALSE; +} + +void wlanOnPostNicInitAdapter(IN struct ADAPTER *prAdapter, + IN struct REG_INFO *prRegInfo, + IN const u_int8_t bAtResetFlow) +{ + DBGLOG(INIT, TRACE, "start.\n"); + + /* 4 <2.1> Initialize System Service (MGMT Memory pool and + * STA_REC) + */ + nicInitSystemService(prAdapter, bAtResetFlow); + + if (!bAtResetFlow) { + + /* 4 <2.2> Initialize Feature Options */ + wlanInitFeatureOption(prAdapter); +#if CFG_SUPPORT_MTK_SYNERGY +#if 0 /* u2FeatureReserved is 0 on 6765 */ + if (kalIsConfigurationExist(prAdapter->prGlueInfo) == TRUE) { + if (prRegInfo->prNvramSettings->u2FeatureReserved & + BIT(MTK_FEATURE_2G_256QAM_DISABLED)) + prAdapter->rWifiVar.aucMtkFeature[0] &= + ~(MTK_SYNERGY_CAP_SUPPORT_24G_MCS89); + } +#endif +#endif + + /* 4 <2.3> Overwrite debug level settings */ + wlanCfgSetDebugLevel(prAdapter); + + /* 4 <3> Initialize Tx */ + nicTxInitialize(prAdapter); + } /* end of bAtResetFlow == FALSE */ + + /* 4 <4> Initialize Rx */ + nicRxInitialize(prAdapter); +} + +#if CFG_SUPPORT_NCHO + +uint32_t wlanNchoSetFWEnable(IN struct ADAPTER *prAdapter, IN uint8_t fgEnable) +{ + char cmd[NCHO_CMD_MAX_LENGTH] = { 0 }; + uint32_t status = WLAN_STATUS_FAILURE; + + kalSnprintf(cmd, sizeof(cmd), "%s %d", + FW_CFG_KEY_NCHO_ENABLE, fgEnable); + status = wlanFwCfgParse(prAdapter, cmd); + if (status != WLAN_STATUS_SUCCESS) + DBGLOG(INIT, WARN, "set disable fail %d\n", status); + return status; +} + +uint32_t wlanNchoSetFWRssiTrigger(IN struct ADAPTER *prAdapter, + IN int32_t i4RoamTriggerRssi) +{ + char cmd[NCHO_CMD_MAX_LENGTH] = { 0 }; + uint32_t status = WLAN_STATUS_FAILURE; + + kalSnprintf(cmd, sizeof(cmd), "%s %d", + FW_CFG_KEY_NCHO_ROAM_RCPI, dBm_TO_RCPI(i4RoamTriggerRssi)); + status = wlanFwCfgParse(prAdapter, cmd); + if (status != WLAN_STATUS_SUCCESS) + DBGLOG(INIT, WARN, "set roam rcpi fail %d\n", status); + return status; +} + +uint32_t wlanNchoSetFWScanPeriod(IN struct ADAPTER *prAdapter, + IN uint32_t u4RoamScanPeriod) +{ + char cmd[NCHO_CMD_MAX_LENGTH] = { 0 }; + uint32_t status = WLAN_STATUS_FAILURE; + + kalSnprintf(cmd, sizeof(cmd), "%s %d", + FW_CFG_KEY_NCHO_SCAN_PERIOD, u4RoamScanPeriod); + status = wlanFwCfgParse(prAdapter, cmd); + if (status != WLAN_STATUS_SUCCESS) + DBGLOG(INIT, WARN, "set scan period fail %d\n", status); + return status; +} + +void wlanNchoInit(IN struct ADAPTER *prAdapter, IN uint8_t fgFwSync) +{ + uint8_t sync = fgFwSync && prAdapter->rNchoInfo.fgNCHOEnabled; + + /* NCHO Initialization */ + prAdapter->rNchoInfo.fgNCHOEnabled = 0; + prAdapter->rNchoInfo.eBand = NCHO_BAND_AUTO; + prAdapter->rNchoInfo.fgChGranted = FALSE; + prAdapter->rNchoInfo.fgIsSendingAF = FALSE; + prAdapter->rNchoInfo.u4RoamScanControl = 0; + prAdapter->rNchoInfo.rRoamScnChnl.ucChannelListNum = 0; + prAdapter->rNchoInfo.rAddRoamScnChnl.ucChannelListNum = 0; + prAdapter->rNchoInfo.eDFSScnMode = NCHO_DFS_SCN_ENABLE1; + prAdapter->rNchoInfo.i4RoamTrigger = -75; + prAdapter->rNchoInfo.i4RoamDelta = 10; + prAdapter->rNchoInfo.u4RoamScanPeriod = ROAMING_DISCOVER_TIMEOUT_SEC; + prAdapter->rNchoInfo.u4ScanChannelTime = 50; + prAdapter->rNchoInfo.u4ScanHomeTime = 120; + prAdapter->rNchoInfo.u4ScanHomeawayTime = 120; + prAdapter->rNchoInfo.u4ScanNProbes = 2; + prAdapter->rNchoInfo.u4WesMode = 0; + prAdapter->rAddRoamScnChnl.ucChannelListNum = 0; + + /* sync with FW to let FW reset params */ + if (sync) + wlanNchoSetFWEnable(prAdapter, 0); +} + +#endif + +void wlanOnPostFirmwareReady(IN struct ADAPTER *prAdapter, + IN struct REG_INFO *prRegInfo) +{ + DBGLOG(INIT, TRACE, "start.\n"); + /* OID timeout timer initialize */ + cnmTimerInitTimer(prAdapter, + &prAdapter->rOidTimeoutTimer, + (PFN_MGMT_TIMEOUT_FUNC) wlanReleasePendingOid, + (unsigned long) NULL); + + prAdapter->ucOidTimeoutCount = 0; + + prAdapter->fgIsChipNoAck = FALSE; + + /* Return Indicated Rfb list timer */ + cnmTimerInitTimer(prAdapter, + &prAdapter->rPacketDelaySetupTimer, + (PFN_MGMT_TIMEOUT_FUNC) + wlanReturnPacketDelaySetupTimeout, + (unsigned long) NULL); + + /* Power state initialization */ + prAdapter->fgWiFiInSleepyState = FALSE; + prAdapter->rAcpiState = ACPI_STATE_D0; + +#if 0 + /* Online scan option */ + if (prRegInfo->fgDisOnlineScan == 0) + prAdapter->fgEnOnlineScan = TRUE; + else + prAdapter->fgEnOnlineScan = FALSE; + + /* Beacon lost detection option */ + if (prRegInfo->fgDisBcnLostDetection != 0) + prAdapter->fgDisBcnLostDetection = TRUE; +#else + if (prAdapter->rWifiVar.fgDisOnlineScan == 0) + prAdapter->fgEnOnlineScan = TRUE; + else + prAdapter->fgEnOnlineScan = FALSE; + + /* Beacon lost detection option */ + if (prAdapter->rWifiVar.fgDisBcnLostDetection != 0) + prAdapter->fgDisBcnLostDetection = TRUE; +#endif + + /* Load compile time constant */ + prAdapter->rWlanInfo.u2BeaconPeriod = + CFG_INIT_ADHOC_BEACON_INTERVAL; + prAdapter->rWlanInfo.u2AtimWindow = + CFG_INIT_ADHOC_ATIM_WINDOW; + +#if 1 /* set PM parameters */ + prAdapter->u4PsCurrentMeasureEn = + prRegInfo->u4PsCurrentMeasureEn; +#if 0 + prAdapter->fgEnArpFilter = prRegInfo->fgEnArpFilter; + prAdapter->u4UapsdAcBmp = prRegInfo->u4UapsdAcBmp; + prAdapter->u4MaxSpLen = prRegInfo->u4MaxSpLen; +#else + prAdapter->fgEnArpFilter = + prAdapter->rWifiVar.fgEnArpFilter; + prAdapter->u4UapsdAcBmp = prAdapter->rWifiVar.u4UapsdAcBmp; + prAdapter->u4MaxSpLen = prAdapter->rWifiVar.u4MaxSpLen; +#endif + DBGLOG(INIT, TRACE, + "[1] fgEnArpFilter:0x%x, u4UapsdAcBmp:0x%x, u4MaxSpLen:0x%x", + prAdapter->fgEnArpFilter, prAdapter->u4UapsdAcBmp, + prAdapter->u4MaxSpLen); + + prAdapter->fgEnCtiaPowerMode = FALSE; + +#endif + /* QA_TOOL and ICAP info struct */ + prAdapter->rIcapInfo.eIcapState = ICAP_STATE_INIT; + prAdapter->rIcapInfo.u2DumpIndex = 0; + prAdapter->rIcapInfo.u4CapNode = 0; + + /* MGMT Initialization */ + nicInitMGMT(prAdapter, prRegInfo); + +#if CFG_SUPPORT_NCHO + wlanNchoInit(prAdapter, FALSE); +#endif + + /* Enable WZC Disassociation */ + prAdapter->rWifiVar.fgSupportWZCDisassociation = TRUE; + + /* Apply Rate Setting */ + if ((enum ENUM_REGISTRY_FIXED_RATE) (prRegInfo->u4FixedRate) + < FIXED_RATE_NUM) + prAdapter->rWifiVar.eRateSetting = + (enum ENUM_REGISTRY_FIXED_RATE) + (prRegInfo->u4FixedRate); + else + prAdapter->rWifiVar.eRateSetting = FIXED_RATE_NONE; + + if (prAdapter->rWifiVar.eRateSetting == FIXED_RATE_NONE) { + /* Enable Auto (Long/Short) Preamble */ + prAdapter->rWifiVar.ePreambleType = PREAMBLE_TYPE_AUTO; + } else if ((prAdapter->rWifiVar.eRateSetting >= + FIXED_RATE_MCS0_20M_400NS && + prAdapter->rWifiVar.eRateSetting <= + FIXED_RATE_MCS7_20M_400NS) + || (prAdapter->rWifiVar.eRateSetting >= + FIXED_RATE_MCS0_40M_400NS && + prAdapter->rWifiVar.eRateSetting <= + FIXED_RATE_MCS32_400NS)) { + /* Force Short Preamble */ + prAdapter->rWifiVar.ePreambleType = PREAMBLE_TYPE_SHORT; + } else { + /* Force Long Preamble */ + prAdapter->rWifiVar.ePreambleType = PREAMBLE_TYPE_LONG; + } + + /* Disable Hidden SSID Join */ + prAdapter->rWifiVar.fgEnableJoinToHiddenSSID = FALSE; + + /* Enable Short Slot Time */ + prAdapter->rWifiVar.fgIsShortSlotTimeOptionEnable = TRUE; + + /* configure available PHY type set */ + nicSetAvailablePhyTypeSet(prAdapter); + +#if 0 /* Marked for MT6630 */ +#if 1 /* set PM parameters */ + { +#if CFG_SUPPORT_PWR_MGT + prAdapter->u4PowerMode = prRegInfo->u4PowerMode; +#if CFG_ENABLE_WIFI_DIRECT + prAdapter->rWlanInfo. + arPowerSaveMode[NETWORK_TYPE_P2P_INDEX].ucNetTypeIndex + = NETWORK_TYPE_P2P_INDEX; + prAdapter->rWlanInfo. + arPowerSaveMode[NETWORK_TYPE_P2P_INDEX].ucPsProfile + = ENUM_PSP_FAST_SWITCH; +#endif +#else + prAdapter->u4PowerMode = ENUM_PSP_CONTINUOUS_ACTIVE; +#endif + + nicConfigPowerSaveProfile(prAdapter, + prAdapter->prAisBssInfo->ucBssIndex, + prAdapter->u4PowerMode, FALSE); + } + +#endif +#endif + +#if CFG_SUPPORT_DYNAMIC_PWR_LIMIT + /* dynamic tx power control initialization */ + /* note: call this API before loading NVRAM */ + txPwrCtrlInit(prAdapter); +#endif + + /* Check hardware 5g band support */ + if (prAdapter->fgIsHw5GBandDisabled) + prAdapter->fgEnable5GBand = FALSE; + else + prAdapter->fgEnable5GBand = TRUE; + +#if CFG_SUPPORT_NVRAM + /* load manufacture data */ + if (kalIsConfigurationExist(prAdapter->prGlueInfo) == TRUE) + wlanLoadManufactureData(prAdapter, prRegInfo); + else + DBGLOG(INIT, WARN, "%s: load manufacture data fail\n", + __func__); +#endif + +#if 0 + /* Update Auto rate parameters in FW */ + nicRlmArUpdateParms(prAdapter, prRegInfo->u4ArSysParam0, + prRegInfo->u4ArSysParam1, + prRegInfo->u4ArSysParam2, + prRegInfo->u4ArSysParam3); +#endif + + /* Default QM RX BA timeout */ + prAdapter->u4QmRxBaMissTimeout = + QM_RX_BA_ENTRY_MISS_TIMEOUT_MS; + +#if CFG_SUPPORT_LOWLATENCY_MODE + wlanAdapterStartForLowLatency(prAdapter); +#endif /* CFG_SUPPORT_LOWLATENCY_MODE */ +#if CFG_SUPPORT_DYNAMIC_PWR_LIMIT + /* dynamic tx power control load configuration */ + /* note: call this API after loading NVRAM */ + txPwrCtrlLoadConfig(prAdapter); +#endif +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Initialize the adapter. The sequence is + * 1. Disable interrupt + * 2. Read adapter configuration from EEPROM and registry, verify chip + * ID. + * 3. Create NIC Tx/Rx resource. + * 4. Initialize the chip + * 5. Initialize the protocol + * 6. Enable Interrupt + * + * \param prAdapter Pointer of Adapter Data Structure + * + * \retval WLAN_STATUS_SUCCESS: Success + * \retval WLAN_STATUS_FAILURE: Failed + */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanAdapterStart(IN struct ADAPTER *prAdapter, + IN struct REG_INFO *prRegInfo, + IN const u_int8_t bAtResetFlow) +{ + uint32_t u4Status = WLAN_STATUS_SUCCESS; + enum ENUM_ADAPTER_START_FAIL_REASON { + ALLOC_ADAPTER_MEM_FAIL, + DRIVER_OWN_FAIL, + INIT_ADAPTER_FAIL, + INIT_HIFINFO_FAIL, + SET_CHIP_ECO_INFO_FAIL, + RAM_CODE_DOWNLOAD_FAIL, + WAIT_FIRMWARE_READY_FAIL, + FAIL_REASON_MAX + } eFailReason; + + ASSERT(prAdapter); + + DEBUGFUNC("wlanAdapterStart"); + + eFailReason = FAIL_REASON_MAX; + + wlanOnPreAllocAdapterMem(prAdapter, bAtResetFlow); + + do { + if (!bAtResetFlow) { + u4Status = nicAllocateAdapterMemory(prAdapter); + if (u4Status != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, ERROR, + "nicAllocateAdapterMemory Error!\n"); + u4Status = WLAN_STATUS_FAILURE; + eFailReason = ALLOC_ADAPTER_MEM_FAIL; +#if CFG_ENABLE_KEYWORD_EXCEPTION_MECHANISM + mtk_wcn_wmt_assert_keyword(WMTDRV_TYPE_WIFI, + "[Wi-Fi On] nicAllocateAdapterMemory Error!"); +#endif + break; + } + + prAdapter->u4OsPacketFilter + = PARAM_PACKET_FILTER_SUPPORTED; + } + /* set FALSE after wifi init flow or reset (not reinit WFDMA) */ + prAdapter->fgIsFwDownloaded = FALSE; + + DBGLOG(INIT, INFO, + "wlanAdapterStart(): Acquiring LP-OWN\n"); + ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); + DBGLOG(INIT, INFO, + "wlanAdapterStart(): Acquiring LP-OWN-end\n"); + +#if (CFG_ENABLE_FULL_PM == 0) + nicpmSetDriverOwn(prAdapter); +#endif + + if (prAdapter->fgIsFwOwn == TRUE) { + DBGLOG(INIT, ERROR, "nicpmSetDriverOwn() failed!\n"); + u4Status = WLAN_STATUS_FAILURE; + eFailReason = DRIVER_OWN_FAIL; +#if CFG_ENABLE_KEYWORD_EXCEPTION_MECHANISM + mtk_wcn_wmt_assert_keyword(WMTDRV_TYPE_WIFI, + "[Wi-Fi On] nicpmSetDriverOwn() failed!"); +#endif + break; + } + +#if CFG_MTK_MCIF_WIFI_SUPPORT + setMddpSupportRegister(prAdapter); +#endif + + if (!bAtResetFlow) { + /* 4 <1> Initialize the Adapter */ + u4Status = nicInitializeAdapter(prAdapter); + if (u4Status != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, ERROR, + "nicInitializeAdapter failed!\n"); + u4Status = WLAN_STATUS_FAILURE; + eFailReason = INIT_ADAPTER_FAIL; + break; + } + } + + wlanOnPostNicInitAdapter(prAdapter, prRegInfo, bAtResetFlow); + + /* 4 <5> HIF SW info initialize */ + if (!halHifSwInfoInit(prAdapter)) { + DBGLOG(INIT, ERROR, "halHifSwInfoInit failed!\n"); + u4Status = WLAN_STATUS_FAILURE; + eFailReason = INIT_HIFINFO_FAIL; + break; + } + + /* 4 <6> Enable HIF cut-through to N9 mode, not visiting CR4 */ + HAL_ENABLE_FWDL(prAdapter, TRUE); + + /* 4 <7> Get ECO Version */ + if (wlanSetChipEcoInfo(prAdapter) != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, ERROR, "wlanSetChipEcoInfo failed!\n"); + u4Status = WLAN_STATUS_FAILURE; + eFailReason = SET_CHIP_ECO_INFO_FAIL; + break; + } + + /* recheck Asic capability depends on ECO version */ + wlanCheckAsicCap(prAdapter); + +#if CFG_ENABLE_FW_DOWNLOAD + /* 4 <8> FW/patch download */ + + /* 1. disable interrupt, download is done by polling mode only + */ + nicDisableInterrupt(prAdapter); + + /* 2. Initialize Tx Resource to fw download state */ + nicTxInitResetResource(prAdapter); + + u4Status = wlanDownloadFW(prAdapter); + if (u4Status != WLAN_STATUS_SUCCESS) { + eFailReason = RAM_CODE_DOWNLOAD_FAIL; +#if CFG_ENABLE_KEYWORD_EXCEPTION_MECHANISM + mtk_wcn_wmt_assert_keyword(WMTDRV_TYPE_WIFI, + "[Wi-Fi On] [Ram code download fail!]"); +#endif + break; + } +#endif + + DBGLOG(INIT, INFO, "Waiting for Ready bit..\n"); + + /* 4 <9> check Wi-Fi FW asserts ready bit */ + u4Status = wlanCheckWifiFunc(prAdapter, TRUE); + + if (u4Status == WLAN_STATUS_SUCCESS) { +#if defined(_HIF_SDIO) + uint32_t *pu4WHISR = NULL; + uint16_t au2TxCount[16]; + + pu4WHISR = (uint32_t *)kalMemAlloc(sizeof(uint32_t), + PHY_MEM_TYPE); + if (!pu4WHISR) { + DBGLOG(INIT, ERROR, + "Allocate pu4WHISR fail\n"); + u4Status = WLAN_STATUS_FAILURE; + break; + } + /* 1. reset interrupt status */ + HAL_READ_INTR_STATUS(prAdapter, sizeof(uint32_t), + (uint8_t *)pu4WHISR); + if (HAL_IS_TX_DONE_INTR(*pu4WHISR)) + HAL_READ_TX_RELEASED_COUNT(prAdapter, + au2TxCount); + + if (pu4WHISR) + kalMemFree(pu4WHISR, PHY_MEM_TYPE, + sizeof(uint32_t)); +#endif + /* Set FW download success flag */ + prAdapter->fgIsFwDownloaded = TRUE; + + /* 2. query & reset TX Resource for normal operation */ + wlanQueryNicResourceInformation(prAdapter); + +#if (CFG_SUPPORT_NIC_CAPABILITY == 1) + if (!bAtResetFlow) { + /* 2.9 Workaround for Capability + *CMD packet lost issue + */ + wlanSendDummyCmd(prAdapter, TRUE); + + /* 3. query for NIC capability */ + if (prAdapter->chip_info->isNicCapV1) + wlanQueryNicCapability(prAdapter); + + /* 4. query for NIC capability V2 */ + u4Status = wlanQueryNicCapabilityV2(prAdapter); + if (u4Status != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, WARN, + "wlanQueryNicCapabilityV2 failed.\n"); + RECLAIM_POWER_CONTROL_TO_PM( + prAdapter, FALSE); + eFailReason = WAIT_FIRMWARE_READY_FAIL; + break; + } + + /* 5. reset TX Resource for normal operation + * based on the information reported from + * CMD_NicCapabilityV2 + */ + wlanUpdateNicResourceInformation(prAdapter); + + wlanPrintVersion(prAdapter); + } +#endif + + /* 6. update basic configuration */ + wlanUpdateBasicConfig(prAdapter); + + if (!bAtResetFlow) { + uint32_t u4Idx = 0; + + /* 7. Override network address */ + wlanUpdateNetworkAddress(prAdapter); + + /* 8. Apply Network Address */ + nicApplyNetworkAddress(prAdapter); + + /* 9. indicate disconnection + * as default status + */ + for (u4Idx = 0; u4Idx < KAL_AIS_NUM; u4Idx++) + kalIndicateStatusAndComplete( + prAdapter->prGlueInfo, + WLAN_STATUS_MEDIA_DISCONNECT, + NULL, 0, + u4Idx); + } + } + + RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); + + if (u4Status != WLAN_STATUS_SUCCESS) { + eFailReason = WAIT_FIRMWARE_READY_FAIL; + break; + } + + if (!bAtResetFlow) + wlanOnPostFirmwareReady(prAdapter, prRegInfo); + else { +#if CFG_SUPPORT_NVRAM + /* load manufacture data */ + if (kalIsConfigurationExist(prAdapter->prGlueInfo) + == TRUE) + wlanLoadManufactureData(prAdapter, prRegInfo); + else + DBGLOG(INIT, WARN, + "%s: load manufacture data fail\n", __func__); +#endif + } + } while (FALSE); + + if (u4Status == WLAN_STATUS_SUCCESS) { + + /* restore to hardware default */ + HAL_SET_INTR_STATUS_READ_CLEAR(prAdapter); + HAL_SET_MAILBOX_READ_CLEAR(prAdapter, FALSE); + + /* Enable interrupt */ + nicEnableInterrupt(prAdapter); + /* init SER module */ + nicSerInit(prAdapter); + } else { + prAdapter->u4HifDbgFlag |= DEG_HIF_DEFAULT_DUMP; + halPrintHifDbgInfo(prAdapter); + DBGLOG(INIT, WARN, "Fail reason: %d\n", eFailReason); + + /* Don't do error handling in chip reset flow, leave it to + * coming wlanRemove for full clean + */ + if (!bAtResetFlow) { + /* release allocated memory */ + switch (eFailReason) { + case WAIT_FIRMWARE_READY_FAIL: + case RAM_CODE_DOWNLOAD_FAIL: + case SET_CHIP_ECO_INFO_FAIL: + case INIT_HIFINFO_FAIL: + nicRxUninitialize(prAdapter); + nicTxRelease(prAdapter, FALSE); + /* System Service Uninitialization */ + nicUninitSystemService(prAdapter); + /* fallthrough */ + case INIT_ADAPTER_FAIL: + /* fallthrough */ + case DRIVER_OWN_FAIL: + nicReleaseAdapterMemory(prAdapter); + break; + case ALLOC_ADAPTER_MEM_FAIL: + default: + break; + } + } + } + + if (prAdapter->chip_info->checkbushang) + prAdapter->chip_info->checkbushang((void *) prAdapter, TRUE); + + return u4Status; +} /* wlanAdapterStart */ + +void wlanOffClearAllQueues(IN struct ADAPTER *prAdapter) +{ + DBGLOG(INIT, INFO, "wlanOffClearAllQueues(): start.\n"); + + /* Release all CMD/MGMT/SEC frame in command queue */ + kalClearCommandQueue(prAdapter->prGlueInfo); + + /* Release all CMD in pending command queue */ + wlanClearPendingCommandQueue(prAdapter); + +#if CFG_SUPPORT_MULTITHREAD + + /* Flush all items in queues for multi-thread */ + wlanClearTxCommandQueue(prAdapter); + + wlanClearTxCommandDoneQueue(prAdapter); + + wlanClearDataQueue(prAdapter); + + wlanClearRxToOsQueue(prAdapter); + +#endif +} + +void wlanOffUninitNicModule(IN struct ADAPTER *prAdapter, + IN const u_int8_t bAtResetFlow) +{ + DBGLOG(INIT, INFO, "wlanOffUninitNicModule(): start.\n"); + nicRxUninitialize(prAdapter); + + nicTxRelease(prAdapter, FALSE); + + if (!bAtResetFlow) { + /* MGMT - unitialization */ + nicUninitMGMT(prAdapter); + + /* System Service Uninitialization */ + nicUninitSystemService(prAdapter); +#if CFG_SUPPORT_DYNAMIC_PWR_LIMIT + /* dynamic tx power control uninitialization */ + txPwrCtrlUninit(prAdapter); +#endif + nicReleaseAdapterMemory(prAdapter); + +#if defined(_HIF_SPI) + /* Note: restore the SPI Mode Select from 32 bit to default */ + nicRestoreSpiDefMode(prAdapter); +#endif + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Uninitialize the adapter + * + * \param prAdapter Pointer of Adapter Data Structure + * + * \retval WLAN_STATUS_SUCCESS: Success + * \retval WLAN_STATUS_FAILURE: Failed + */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanAdapterStop(IN struct ADAPTER *prAdapter, + IN const u_int8_t bAtResetFlow) +{ + uint32_t u4Status = WLAN_STATUS_SUCCESS; + + ASSERT(prAdapter); + + wlanOffClearAllQueues(prAdapter); + + /* Hif power off wifi */ + if (prAdapter->rAcpiState == ACPI_STATE_D0 && + !wlanIsChipNoAck(prAdapter) + && !kalIsCardRemoved(prAdapter->prGlueInfo)) { + wlanPowerOffWifi(prAdapter); + } + + halHifSwInfoUnInit(prAdapter->prGlueInfo); + wlanOffUninitNicModule(prAdapter, bAtResetFlow); + + return u4Status; +} /* wlanAdapterStop */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is called by ISR (interrupt). + * + * \param prAdapter Pointer of Adapter Data Structure + * + * \retval TRUE: NIC's interrupt + * \retval FALSE: Not NIC's interrupt + */ +/*----------------------------------------------------------------------------*/ +u_int8_t wlanISR(IN struct ADAPTER *prAdapter, + IN u_int8_t fgGlobalIntrCtrl) +{ + ASSERT(prAdapter); + + if (fgGlobalIntrCtrl) { + nicDisableInterrupt(prAdapter); + + /* wlanIST(prAdapter); */ + } + + return TRUE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is called by IST (task_let). + * + * \param prAdapter Pointer of Adapter Data Structure + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void wlanIST(IN struct ADAPTER *prAdapter, bool fgEnInt) +{ + uint32_t u4Status = WLAN_STATUS_SUCCESS; + + ASSERT(prAdapter); + + ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); + + if (prAdapter->fgIsFwOwn == FALSE) { + u4Status = nicProcessIST(prAdapter); + if (u4Status != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, INFO, "Fail: nicProcessIST! status [%x]\n", + u4Status); + } +#if defined(CONFIG_ANDROID) && (CFG_ENABLE_WAKE_LOCK) + if (KAL_WAKE_LOCK_ACTIVE(prAdapter, + prAdapter->prGlueInfo->rIntrWakeLock)) + KAL_WAKE_UNLOCK(prAdapter, + prAdapter->prGlueInfo->rIntrWakeLock); +#endif + } + + if (fgEnInt) + nicEnableInterrupt(prAdapter); + + RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); + + +} + +void wlanClearPendingInterrupt(IN struct ADAPTER *prAdapter) +{ + uint32_t i; + + i = 0; + while (i < CFG_IST_LOOP_COUNT + && nicProcessIST(prAdapter) != WLAN_STATUS_NOT_INDICATING) { + i++; + }; +} + +void wlanCheckAsicCap(IN struct ADAPTER *prAdapter) +{ + struct mt66xx_chip_info *prChipInfo; + + ASSERT(prAdapter); + + prChipInfo = prAdapter->chip_info; + + if (prChipInfo->wlanCheckAsicCap) + prChipInfo->wlanCheckAsicCap(prAdapter); +} + +uint32_t wlanCheckWifiFunc(IN struct ADAPTER *prAdapter, + IN u_int8_t fgRdyChk) +{ + u_int8_t fgResult, fgTimeout; + uint32_t u4Result = 0, u4Status, u4StartTime, u4CurTime; + const uint32_t ready_bits = + prAdapter->chip_info->sw_ready_bits; + + u4StartTime = kalGetTimeTick(); + fgTimeout = FALSE; + +#if defined(_HIF_USB) + if (prAdapter->prGlueInfo->rHifInfo.state == + USB_STATE_LINK_DOWN) + return WLAN_STATUS_FAILURE; +#endif + + while (TRUE) { + DBGLOG_LIMITED(INIT, TRACE, + "Check ready_bits(=0x%x)\n", ready_bits); + if (fgRdyChk) + HAL_WIFI_FUNC_READY_CHECK(prAdapter, + ready_bits /* WIFI_FUNC_READY_BITS */, + &fgResult); + else { + HAL_WIFI_FUNC_OFF_CHECK(prAdapter, + ready_bits /* WIFI_FUNC_READY_BITS */, + &fgResult); +#if defined(_HIF_USB) || defined(_HIF_SDIO) + if (nicProcessIST(prAdapter) != + WLAN_STATUS_NOT_INDICATING) + DBGLOG_LIMITED(INIT, INFO, + "Handle pending interrupt\n"); +#endif /* _HIF_USB or _HIF_SDIO */ + } + u4CurTime = kalGetTimeTick(); + + if (CHECK_FOR_TIMEOUT(u4CurTime, u4StartTime, + CFG_RESPONSE_POLLING_TIMEOUT * + CFG_RESPONSE_POLLING_DELAY)) { + + fgTimeout = TRUE; + } + + if (fgResult) { + if (fgRdyChk) + DBGLOG_LIMITED(INIT, INFO, + "Ready bit asserted\n"); + else + DBGLOG_LIMITED(INIT, INFO, + "Wi-Fi power off done!\n"); + + u4Status = WLAN_STATUS_SUCCESS; + + break; + } else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE + || fgIsBusAccessFailed == TRUE) { + u4Status = WLAN_STATUS_FAILURE; + + break; + } else if (fgTimeout) { + HAL_WIFI_FUNC_GET_STATUS(prAdapter, u4Result); + DBGLOG(INIT, ERROR, + "Waiting for %s: Timeout, Status=0x%08x\n", + fgRdyChk ? "ready bit" : "power off", u4Result); +#if CFG_ENABLE_KEYWORD_EXCEPTION_MECHANISM + mtk_wcn_wmt_assert_keyword(WMTDRV_TYPE_WIFI, + "[Wi-Fi] [Read WCIR_WLAN_READY fail!]"); +#else + GL_RESET_TRIGGER(prAdapter, RST_FLAG_DO_CORE_DUMP | + RST_FLAG_PREVENT_POWER_OFF); +#endif + u4Status = WLAN_STATUS_FAILURE; + break; + } + kalMsleep(CFG_RESPONSE_POLLING_DELAY); + + } + + return u4Status; +} + +uint32_t wlanPowerOffWifi(IN struct ADAPTER *prAdapter) +{ + uint32_t rStatus; + /* Hif power off wifi */ + rStatus = halHifPowerOffWifi(prAdapter); + prAdapter->fgIsCr4FwDownloaded = FALSE; + + return rStatus; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function will check command queue to find out if any could be + * dequeued and/or send to HIF to MT6620 + * + * \param prAdapter Pointer of Adapter Data Structure + * \param prCmdQue Pointer of Command Queue (in Glue Layer) + * + * \retval WLAN_STATUS_SUCCESS + */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanProcessCommandQueue(IN struct ADAPTER + *prAdapter, IN struct QUE *prCmdQue) +{ + uint32_t rStatus; + struct QUE rTempCmdQue, rMergeCmdQue, rStandInCmdQue; + struct QUE *prTempCmdQue, *prMergeCmdQue, *prStandInCmdQue; + struct QUE_ENTRY *prQueueEntry; + struct CMD_INFO *prCmdInfo; + struct MSDU_INFO *prMsduInfo; + enum ENUM_FRAME_ACTION eFrameAction = FRAME_ACTION_DROP_PKT; + + KAL_SPIN_LOCK_DECLARATION(); + + ASSERT(prAdapter); + ASSERT(prCmdQue); + + prTempCmdQue = &rTempCmdQue; + prMergeCmdQue = &rMergeCmdQue; + prStandInCmdQue = &rStandInCmdQue; + + QUEUE_INITIALIZE(prTempCmdQue); + QUEUE_INITIALIZE(prMergeCmdQue); + QUEUE_INITIALIZE(prStandInCmdQue); + + /* 4 <1> Move whole list of CMD_INFO to temp queue */ + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_QUE); + QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_QUE); + + /* 4 <2> Dequeue from head and check it is able to be sent */ + QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, + struct QUE_ENTRY *); + while (prQueueEntry) { + prCmdInfo = (struct CMD_INFO *) prQueueEntry; + switch (prCmdInfo->eCmdType) { + case COMMAND_TYPE_GENERAL_IOCTL: + case COMMAND_TYPE_NETWORK_IOCTL: + /* command packet will be always sent */ + eFrameAction = FRAME_ACTION_TX_PKT; + break; + + case COMMAND_TYPE_SECURITY_FRAME: + case COMMAND_TYPE_DATA_FRAME: + /* inquire with QM */ + prMsduInfo = prCmdInfo->prMsduInfo; + + eFrameAction = qmGetFrameAction(prAdapter, + prMsduInfo->ucBssIndex, + prMsduInfo->ucStaRecIndex, + NULL, FRAME_TYPE_802_1X, + prCmdInfo->u2InfoBufLen); + break; + + case COMMAND_TYPE_MANAGEMENT_FRAME: + /* inquire with QM */ + prMsduInfo = prCmdInfo->prMsduInfo; + + eFrameAction = qmGetFrameAction(prAdapter, + prMsduInfo->ucBssIndex, + prMsduInfo->ucStaRecIndex, + prMsduInfo, FRAME_TYPE_MMPDU, + prMsduInfo->u2FrameLength); + break; + + default: + ASSERT(0); + break; + } +#if (CFG_SUPPORT_STATISTICS == 1) + wlanWakeLogCmd(prCmdInfo->ucCID); +#endif + /* 4 <3> handling upon dequeue result */ + if (eFrameAction == FRAME_ACTION_DROP_PKT) { + DBGLOG(INIT, INFO, + "DROP CMD TYPE[%u] ID[0x%02X] SEQ[%u]\n", + prCmdInfo->eCmdType, prCmdInfo->ucCID, + prCmdInfo->ucCmdSeqNum); + wlanReleaseCommand(prAdapter, prCmdInfo, + TX_RESULT_DROPPED_IN_DRIVER); + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + } else if (eFrameAction == FRAME_ACTION_QUEUE_PKT) { + DBGLOG(INIT, TRACE, + "QUE back CMD TYPE[%u] ID[0x%02X] SEQ[%u]\n", + prCmdInfo->eCmdType, prCmdInfo->ucCID, + prCmdInfo->ucCmdSeqNum); + + QUEUE_INSERT_TAIL(prMergeCmdQue, prQueueEntry); + } else if (eFrameAction == FRAME_ACTION_TX_PKT) { + /* 4 <4> Send the command */ +#if CFG_SUPPORT_MULTITHREAD + rStatus = wlanSendCommandMthread(prAdapter, prCmdInfo); + + if (rStatus == WLAN_STATUS_RESOURCES) { + /* no more TC4 resource for further + * transmission + */ + DBGLOG(INIT, WARN, + "NO Res CMD TYPE[%u] ID[0x%02X] SEQ[%u]\n", + prCmdInfo->eCmdType, prCmdInfo->ucCID, + prCmdInfo->ucCmdSeqNum); + + prAdapter->u4HifDbgFlag |= DEG_HIF_ALL; + kalSetHifDbgEvent(prAdapter->prGlueInfo); + + QUEUE_INSERT_TAIL(prMergeCmdQue, prQueueEntry); + + /* + * We reserve one TC4 resource for CMD + * specially, only break checking the left tx + * request if no resource for true CMD. + */ + if ((prCmdInfo->eCmdType != + COMMAND_TYPE_SECURITY_FRAME) && + (prCmdInfo->eCmdType != + COMMAND_TYPE_MANAGEMENT_FRAME) && + (prCmdInfo->eCmdType != + COMMAND_TYPE_DATA_FRAME)) + break; + } else if (rStatus == WLAN_STATUS_PENDING) { + /* Do nothing */ + } else if (rStatus == WLAN_STATUS_SUCCESS) { + /* Do nothing */ + } else { + struct CMD_INFO *prCmdInfo = (struct CMD_INFO *) + prQueueEntry; + + if (prCmdInfo->fgIsOid) { + kalOidComplete(prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, + prCmdInfo->u4SetInfoLen, + rStatus); + } + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + } + +#else + rStatus = wlanSendCommand(prAdapter, prCmdInfo); + + if (rStatus == WLAN_STATUS_RESOURCES) { + /* no more TC4 resource for further + * transmission + */ + + DBGLOG(INIT, WARN, + "NO Resource for CMD TYPE[%u] ID[0x%02X] SEQ[%u]\n", + prCmdInfo->eCmdType, prCmdInfo->ucCID, + prCmdInfo->ucCmdSeqNum); + + QUEUE_INSERT_TAIL(prMergeCmdQue, prQueueEntry); + break; + } else if (rStatus == WLAN_STATUS_PENDING) { + /* command packet which needs further handling + * upon response + */ + KAL_ACQUIRE_SPIN_LOCK(prAdapter, + SPIN_LOCK_CMD_PENDING); + QUEUE_INSERT_TAIL( + &(prAdapter->rPendingCmdQueue), + prQueueEntry); + KAL_RELEASE_SPIN_LOCK(prAdapter, + SPIN_LOCK_CMD_PENDING); + } else { + struct CMD_INFO *prCmdInfo = (struct CMD_INFO *) + prQueueEntry; + + if (rStatus == WLAN_STATUS_SUCCESS) { + if (prCmdInfo->pfCmdDoneHandler) { + prCmdInfo->pfCmdDoneHandler( + prAdapter, prCmdInfo, + prCmdInfo->pucInfoBuffer); + } + } else { + if (prCmdInfo->fgIsOid) { + kalOidComplete( + prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, + prCmdInfo->u4SetInfoLen, + rStatus); + } + } + + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + } +#endif + } else { + ASSERT(0); + } + + QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, + struct QUE_ENTRY *); + } + + /* 4 <3> Merge back to original queue */ + /* 4 <3.1> Merge prMergeCmdQue & prTempCmdQue */ + QUEUE_CONCATENATE_QUEUES(prMergeCmdQue, prTempCmdQue); + + /* 4 <3.2> Move prCmdQue to prStandInQue, due to prCmdQue might differ + * due to incoming 802.1X frames + */ + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_QUE); + QUEUE_MOVE_ALL(prStandInCmdQue, prCmdQue); + + /* 4 <3.3> concatenate prStandInQue to prMergeCmdQue */ + QUEUE_CONCATENATE_QUEUES(prMergeCmdQue, prStandInCmdQue); + + /* 4 <3.4> then move prMergeCmdQue to prCmdQue */ + QUEUE_MOVE_ALL(prCmdQue, prMergeCmdQue); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_QUE); + +#if CFG_SUPPORT_MULTITHREAD + kalSetTxCmdEvent2Hif(prAdapter->prGlueInfo); +#endif + + return WLAN_STATUS_SUCCESS; +} /* end of wlanProcessCommandQueue() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function will take CMD_INFO_T which carry some information of + * incoming OID and notify the NIC_TX to send CMD. + * + * \param prAdapter Pointer of Adapter Data Structure + * \param prCmdInfo Pointer of P_CMD_INFO_T + * + * \retval WLAN_STATUS_SUCCESS : CMD was written to HIF and be freed(CMD Done) + * immediately. + * \retval WLAN_STATUS_RESOURCE : No resource for current command, need to wait + * for previous + * frame finishing their transmission. + * \retval WLAN_STATUS_FAILURE : Get failure while access HIF or been + * rejected. + */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanSendCommand(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo) +{ + struct TX_CTRL *prTxCtrl; + uint8_t ucTC; /* "Traffic Class" SW(Driver) resource + * classification + */ + uint32_t rStatus = WLAN_STATUS_SUCCESS; + + ASSERT(prAdapter); + ASSERT(prCmdInfo); + prTxCtrl = &prAdapter->rTxCtrl; + + do { + /* <0> card removal check */ + if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE + || fgIsBusAccessFailed == TRUE) { + rStatus = WLAN_STATUS_FAILURE; + break; + } + + /* <1.1> Assign Traffic Class(TC) */ + ucTC = nicTxGetCmdResourceType(prCmdInfo); + + /* <1.2> Check if pending packet or resource was exhausted */ + rStatus = nicTxAcquireResource(prAdapter, ucTC, + nicTxGetCmdPageCount(prAdapter, prCmdInfo), + TRUE); + if (rStatus == WLAN_STATUS_RESOURCES) { + DBGLOG(INIT, INFO, "NO Resource:%d\n", ucTC); + break; + } + GLUE_INC_REF_CNT(prAdapter->rHifStats.u4CmdInCount); + /* <1.3> Forward CMD_INFO_T to NIC Layer */ + rStatus = nicTxCmd(prAdapter, prCmdInfo, ucTC); + + /* <1.4> Set Pending in response to Query Command/Need Response + */ + if (rStatus == WLAN_STATUS_SUCCESS) { + if ((!prCmdInfo->fgSetQuery) || (prCmdInfo->fgNeedResp)) + rStatus = WLAN_STATUS_PENDING; + } + + } while (FALSE); + + return rStatus; +} /* end of wlanSendCommand() */ + +#if CFG_SUPPORT_MULTITHREAD + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function will take CMD_INFO_T which carry some information of + * incoming OID and notify the NIC_TX to send CMD. + * + * \param prAdapter Pointer of Adapter Data Structure + * \param prCmdInfo Pointer of P_CMD_INFO_T + * + * \retval WLAN_STATUS_SUCCESS : CMD was written to HIF and be freed(CMD Done) + * immediately. + * \retval WLAN_STATUS_RESOURCE : No resource for current command, need to wait + * for previous + * frame finishing their transmission. + * \retval WLAN_STATUS_FAILURE : Get failure while access HIF or been + * rejected. + */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanSendCommandMthread(IN struct ADAPTER + *prAdapter, IN struct CMD_INFO *prCmdInfo) +{ + struct TX_CTRL *prTxCtrl; + uint8_t ucTC; /* "Traffic Class" SW(Driver) resource + * classification + */ + uint32_t rStatus = WLAN_STATUS_SUCCESS; + + struct QUE rTempCmdQue; + struct QUE *prTempCmdQue; + +#if CFG_DBG_MGT_BUF + struct MEM_TRACK *prMemTrack = NULL; +#endif + + KAL_SPIN_LOCK_DECLARATION(); + + ASSERT(prAdapter); + ASSERT(prCmdInfo); + prTxCtrl = &prAdapter->rTxCtrl; + +#if CFG_DBG_MGT_BUF + if (prCmdInfo->pucInfoBuffer && + !IS_FROM_BUF(prAdapter, prCmdInfo->pucInfoBuffer)) + prMemTrack = + (struct MEM_TRACK *) + ((uint8_t *)prCmdInfo->pucInfoBuffer - + sizeof(struct MEM_TRACK)); +#endif + + prTempCmdQue = &rTempCmdQue; + QUEUE_INITIALIZE(prTempCmdQue); + + do { + /* <0> card removal check */ + if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE + || fgIsBusAccessFailed == TRUE) { + rStatus = WLAN_STATUS_FAILURE; + break; + } + /* <1> Normal case of sending CMD Packet */ + /* <1.1> Assign Traffic Class(TC) */ + ucTC = nicTxGetCmdResourceType(prCmdInfo); + + /* <1.2> Check if pending packet or resource was exhausted */ + rStatus = nicTxAcquireResource(prAdapter, ucTC, + nicTxGetCmdPageCount(prAdapter, prCmdInfo), + TRUE); + if (rStatus == WLAN_STATUS_RESOURCES) { +#if 0 + DBGLOG(INIT, WARN, + "%s: NO Resource for CMD TYPE[%u] ID[0x%02X] SEQ[%u] TC[%u]\n", + __func__, prCmdInfo->eCmdType, prCmdInfo->ucCID, + prCmdInfo->ucCmdSeqNum, ucTC); +#endif + break; + } + + /* Process to pending command queue firest */ + if ((!prCmdInfo->fgSetQuery) || (prCmdInfo->fgNeedResp)) { + /* command packet which needs further handling upon + * response + */ + /* + * KAL_ACQUIRE_SPIN_LOCK(prAdapter, + * SPIN_LOCK_CMD_PENDING); + * QUEUE_INSERT_TAIL(&(prAdapter->rPendingCmdQueue), + * (struct QUE_ENTRY *)prCmdInfo); + * KAL_RELEASE_SPIN_LOCK(prAdapter, + * SPIN_LOCK_CMD_PENDING); + */ + } + +#if CFG_DBG_MGT_BUF + if (prMemTrack) { + prMemTrack->u2CmdIdAndWhere &= 0x00FF; + prMemTrack->u2CmdIdAndWhere |= 0x0100; + } +#endif + + QUEUE_INSERT_TAIL(prTempCmdQue, + (struct QUE_ENTRY *) prCmdInfo); + + /* <1.4> Set Pending in response to Query Command/Need Response + */ + if (rStatus == WLAN_STATUS_SUCCESS) { + if ((!prCmdInfo->fgSetQuery) || + (prCmdInfo->fgNeedResp) || + (prCmdInfo->eCmdType == + COMMAND_TYPE_SECURITY_FRAME || + prCmdInfo->eCmdType == + COMMAND_TYPE_DATA_FRAME)) { + rStatus = WLAN_STATUS_PENDING; + } + } + } while (FALSE); + + GLUE_ADD_REF_CNT(prTempCmdQue->u4NumElem, + prAdapter->rHifStats.u4CmdInCount); + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_CMD_QUE); + QUEUE_CONCATENATE_QUEUES(&(prAdapter->rTxCmdQueue), + prTempCmdQue); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_CMD_QUE); + + return rStatus; +} /* end of wlanSendCommandMthread() */ + +void wlanTxCmdDoneCb(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo) +{ + KAL_SPIN_LOCK_DECLARATION(); + + if ((!prCmdInfo->fgSetQuery) || (prCmdInfo->fgNeedResp)) { + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); + QUEUE_INSERT_TAIL(&prAdapter->rPendingCmdQueue, + (struct QUE_ENTRY *) prCmdInfo); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); + } +} + +uint32_t wlanTxCmdMthread(IN struct ADAPTER *prAdapter) +{ + struct QUE rTempCmdQue; + struct QUE *prTempCmdQue; + struct QUE rTempCmdDoneQue; + struct QUE *prTempCmdDoneQue; + struct QUE_ENTRY *prQueueEntry; + struct CMD_INFO *prCmdInfo; + /* P_CMD_ACCESS_REG prCmdAccessReg; + * P_CMD_ACCESS_REG prEventAccessReg; + * UINT_32 u4Address; + */ + uint32_t u4TxDoneQueueSize; +#if CFG_DBG_MGT_BUF + struct MEM_TRACK *prMemTrack = NULL; +#endif + + KAL_SPIN_LOCK_DECLARATION(); + + ASSERT(prAdapter); + + if (halIsHifStateSuspend(prAdapter)) { + DBGLOG(TX, WARN, "Suspend TxCmdMthread\n"); + return WLAN_STATUS_SUCCESS; + } + + prTempCmdQue = &rTempCmdQue; + QUEUE_INITIALIZE(prTempCmdQue); + + prTempCmdDoneQue = &rTempCmdDoneQue; + QUEUE_INITIALIZE(prTempCmdDoneQue); + + KAL_ACQUIRE_MUTEX(prAdapter, MUTEX_TX_CMD_CLEAR); + + /* TX Command Queue */ + /* 4 <1> Move whole list of CMD_INFO to temp queue */ + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_CMD_QUE); + QUEUE_MOVE_ALL(prTempCmdQue, &prAdapter->rTxCmdQueue); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_CMD_QUE); + + /* 4 <2> Dequeue from head and check it is able to be sent */ + QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, + struct QUE_ENTRY *); + while (prQueueEntry) { + prCmdInfo = (struct CMD_INFO *) prQueueEntry; + prCmdInfo->pfHifTxCmdDoneCb = wlanTxCmdDoneCb; +#if CFG_DBG_MGT_BUF + if (prCmdInfo->pucInfoBuffer && + !IS_FROM_BUF(prAdapter, + prCmdInfo->pucInfoBuffer)) + prMemTrack = + (struct MEM_TRACK *) + ((uint8_t *)prCmdInfo->pucInfoBuffer - + sizeof(struct MEM_TRACK)); +#endif + + if ((!prCmdInfo->fgSetQuery) || (prCmdInfo->fgNeedResp)) { +#if CFG_DBG_MGT_BUF + if (prMemTrack) { + prMemTrack->u2CmdIdAndWhere &= 0x00FF; + prMemTrack->u2CmdIdAndWhere |= 0x0200; + } +#endif + } else { +#if CFG_DBG_MGT_BUF + if (prMemTrack) { + prMemTrack->u2CmdIdAndWhere &= 0x00FF; + prMemTrack->u2CmdIdAndWhere |= 0x0300; + } +#endif + QUEUE_INSERT_TAIL(prTempCmdDoneQue, prQueueEntry); + } + + if (nicTxCmd(prAdapter, prCmdInfo, TC4_INDEX) + != WLAN_STATUS_SUCCESS) + DBGLOG(INIT, WARN, "nicTxCmd returns error\n"); + + /* DBGLOG(INIT, INFO, "==> TX CMD QID: %d (Q:%d)\n", + * prCmdInfo->ucCID, prTempCmdQue->u4NumElem)); + */ + + GLUE_DEC_REF_CNT(prAdapter->prGlueInfo->i4TxPendingCmdNum); + QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, + struct QUE_ENTRY *); + } + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_CMD_DONE_QUE); + QUEUE_CONCATENATE_QUEUES(&prAdapter->rTxCmdDoneQueue, + prTempCmdDoneQue); + u4TxDoneQueueSize = prAdapter->rTxCmdDoneQueue.u4NumElem; + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_CMD_DONE_QUE); + + KAL_RELEASE_MUTEX(prAdapter, MUTEX_TX_CMD_CLEAR); + + /* call tx thread to work */ + if (u4TxDoneQueueSize > 0) + kalSetTxCmdDoneEvent(prAdapter->prGlueInfo); + + return WLAN_STATUS_SUCCESS; +} + +uint32_t wlanTxCmdDoneMthread(IN struct ADAPTER *prAdapter) +{ + struct QUE rTempCmdQue; + struct QUE *prTempCmdQue; + struct QUE_ENTRY *prQueueEntry; + struct CMD_INFO *prCmdInfo; + + KAL_SPIN_LOCK_DECLARATION(); + + ASSERT(prAdapter); + + if (halIsHifStateSuspend(prAdapter)) { + DBGLOG(TX, WARN, "Suspend TxCmdDoneMthread\n"); + return WLAN_STATUS_SUCCESS; + } + + prTempCmdQue = &rTempCmdQue; + QUEUE_INITIALIZE(prTempCmdQue); + + /* 4 <1> Move whole list of CMD_INFO to temp queue */ + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_CMD_DONE_QUE); + QUEUE_MOVE_ALL(prTempCmdQue, &prAdapter->rTxCmdDoneQueue); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_CMD_DONE_QUE); + + /* 4 <2> Dequeue from head and check it is able to be sent */ + QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, + struct QUE_ENTRY *); + while (prQueueEntry) { + prCmdInfo = (struct CMD_INFO *) prQueueEntry; + + if (prCmdInfo->pfCmdDoneHandler) + prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, + prCmdInfo->pucInfoBuffer); + /* Not pending cmd, free it after TX succeed! */ + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + + QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, + struct QUE_ENTRY *); + } + + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used to clear all commands in TX command queue + * \param prAdapter Pointer of Adapter Data Structure + * + * \retval none + */ +/*----------------------------------------------------------------------------*/ +void wlanClearTxCommandQueue(IN struct ADAPTER *prAdapter) +{ + struct QUE rTempCmdQue; + struct QUE *prTempCmdQue = &rTempCmdQue; + struct QUE_ENTRY *prQueueEntry = (struct QUE_ENTRY *) NULL; + struct CMD_INFO *prCmdInfo = (struct CMD_INFO *) NULL; + + KAL_SPIN_LOCK_DECLARATION(); + QUEUE_INITIALIZE(prTempCmdQue); + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_CMD_QUE); + QUEUE_MOVE_ALL(prTempCmdQue, &prAdapter->rTxCmdQueue); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_CMD_QUE); + + QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, + struct QUE_ENTRY *); + while (prQueueEntry) { + prCmdInfo = (struct CMD_INFO *) prQueueEntry; + + if (prCmdInfo->pfCmdTimeoutHandler) + prCmdInfo->pfCmdTimeoutHandler(prAdapter, prCmdInfo); + else + wlanReleaseCommand(prAdapter, prCmdInfo, + TX_RESULT_QUEUE_CLEARANCE); + + /* Release Tx resource for CMD which resource is allocated but + * not used + */ + nicTxReleaseResource_PSE(prAdapter, + nicTxGetCmdResourceType(prCmdInfo), + nicTxGetCmdPageCount(prAdapter, prCmdInfo), TRUE); + + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + + QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, + struct QUE_ENTRY *); + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used to clear OID commands in TX command queue + * \param prAdapter Pointer of Adapter Data Structure + * + * \retval none + */ +/*----------------------------------------------------------------------------*/ +void wlanClearTxOidCommand(IN struct ADAPTER *prAdapter) +{ + struct QUE rTempCmdQue; + struct QUE *prTempCmdQue = &rTempCmdQue; + struct QUE_ENTRY *prQueueEntry = (struct QUE_ENTRY *) NULL; + struct CMD_INFO *prCmdInfo = (struct CMD_INFO *) NULL; + + KAL_SPIN_LOCK_DECLARATION(); + QUEUE_INITIALIZE(prTempCmdQue); + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_CMD_QUE); + + QUEUE_MOVE_ALL(prTempCmdQue, &prAdapter->rTxCmdQueue); + + QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, + struct QUE_ENTRY *); + + while (prQueueEntry) { + prCmdInfo = (struct CMD_INFO *) prQueueEntry; + + if (prCmdInfo->fgIsOid) { + + if (prCmdInfo->pfCmdTimeoutHandler) + prCmdInfo->pfCmdTimeoutHandler(prAdapter, + prCmdInfo); + else + wlanReleaseCommand(prAdapter, prCmdInfo, + TX_RESULT_QUEUE_CLEARANCE); + + /* Release Tx resource for CMD which resource is + * allocated but not used + */ + nicTxReleaseResource_PSE(prAdapter, + nicTxGetCmdResourceType(prCmdInfo), + nicTxGetCmdPageCount(prAdapter, prCmdInfo), + TRUE); + + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + + } else { + QUEUE_INSERT_TAIL(&prAdapter->rTxCmdQueue, + prQueueEntry); + } + + QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, + struct QUE_ENTRY *); + } + + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_CMD_QUE); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used to clear all commands in TX command done queue + * \param prAdapter Pointer of Adapter Data Structure + * + * \retval none + */ +/*----------------------------------------------------------------------------*/ +void wlanClearTxCommandDoneQueue(IN struct ADAPTER + *prAdapter) +{ + struct QUE rTempCmdDoneQue; + struct QUE *prTempCmdDoneQue = &rTempCmdDoneQue; + struct QUE_ENTRY *prQueueEntry = (struct QUE_ENTRY *) NULL; + struct CMD_INFO *prCmdInfo = (struct CMD_INFO *) NULL; + + KAL_SPIN_LOCK_DECLARATION(); + QUEUE_INITIALIZE(prTempCmdDoneQue); + + /* 4 <1> Move whole list of CMD_INFO to temp queue */ + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_CMD_DONE_QUE); + QUEUE_MOVE_ALL(prTempCmdDoneQue, + &prAdapter->rTxCmdDoneQueue); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_CMD_DONE_QUE); + + /* 4 <2> Dequeue from head and check it is able to be sent */ + QUEUE_REMOVE_HEAD(prTempCmdDoneQue, prQueueEntry, + struct QUE_ENTRY *); + while (prQueueEntry) { + prCmdInfo = (struct CMD_INFO *) prQueueEntry; + + if (prCmdInfo->pfCmdDoneHandler) + prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, + prCmdInfo->pucInfoBuffer); + /* Not pending cmd, free it after TX succeed! */ + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + + QUEUE_REMOVE_HEAD(prTempCmdDoneQue, prQueueEntry, + struct QUE_ENTRY *); + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used to clear all buffer in port 0/1 queue + * \param prAdapter Pointer of Adapter Data Structure + * + * \retval none + */ +/*----------------------------------------------------------------------------*/ +void wlanClearDataQueue(IN struct ADAPTER *prAdapter) +{ + if (HAL_IS_TX_DIRECT()) + nicTxDirectClearHifQ(prAdapter); + else { +#if CFG_FIX_2_TX_PORT + struct QUE qDataPort0, qDataPort1; + struct QUE *prDataPort0, *prDataPort1; + struct MSDU_INFO *prMsduInfo; + + KAL_SPIN_LOCK_DECLARATION(); + + prDataPort0 = &qDataPort0; + prDataPort1 = &qDataPort1; + + QUEUE_INITIALIZE(prDataPort0); + QUEUE_INITIALIZE(prDataPort1); + + /* <1> Move whole list of CMD_INFO to temp queue */ + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_PORT_QUE); + QUEUE_MOVE_ALL(prDataPort0, &prAdapter->rTxP0Queue); + QUEUE_MOVE_ALL(prDataPort1, &prAdapter->rTxP1Queue); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_PORT_QUE); + + /* <2> Release Tx resource */ + nicTxReleaseMsduResource(prAdapter, + (struct MSDU_INFO *) QUEUE_GET_HEAD(prDataPort0)); + nicTxReleaseMsduResource(prAdapter, + (struct MSDU_INFO *) QUEUE_GET_HEAD(prDataPort1)); + + /* <3> Return sk buffer */ + nicTxReturnMsduInfo(prAdapter, (struct MSDU_INFO *) + QUEUE_GET_HEAD(prDataPort0)); + nicTxReturnMsduInfo(prAdapter, (struct MSDU_INFO *) + QUEUE_GET_HEAD(prDataPort1)); + + /* <4> Clear pending MSDU info in data done queue */ + KAL_ACQUIRE_MUTEX(prAdapter, MUTEX_TX_DATA_DONE_QUE); + while (QUEUE_IS_NOT_EMPTY(&prAdapter->rTxDataDoneQueue)) { + QUEUE_REMOVE_HEAD(&prAdapter->rTxDataDoneQueue, + prMsduInfo, struct MSDU_INFO *); + if (prMsduInfo == NULL) { + DBGLOG(TX, WARN, "prMsduInfo is NULL\n"); + break; + } + nicTxFreePacket(prAdapter, prMsduInfo, FALSE); + nicTxReturnMsduInfo(prAdapter, prMsduInfo); + } + KAL_RELEASE_MUTEX(prAdapter, MUTEX_TX_DATA_DONE_QUE); +#else + + struct QUE qDataPort[TX_PORT_NUM]; + struct QUE *prDataPort[TX_PORT_NUM]; + struct MSDU_INFO *prMsduInfo; + int32_t i; + + KAL_SPIN_LOCK_DECLARATION(); + + for (i = 0; i < TX_PORT_NUM; i++) { + prDataPort[i] = &qDataPort[i]; + QUEUE_INITIALIZE(prDataPort[i]); + } + + /* <1> Move whole list of CMD_INFO to temp queue */ + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_PORT_QUE); + for (i = 0; i < TX_PORT_NUM; i++) { + QUEUE_MOVE_ALL(prDataPort[i], &prAdapter->rTxPQueue[i]); + kalTraceEvent("Move TxPQueue%d %d", i, + prDataPort[i]->u4NumElem); + } + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_PORT_QUE); + + /* <2> Return sk buffer */ + for (i = 0; i < TX_PORT_NUM; i++) { + nicTxReleaseMsduResource(prAdapter, (struct MSDU_INFO *) + QUEUE_GET_HEAD(prDataPort[i])); + nicTxReturnMsduInfo(prAdapter, (struct MSDU_INFO *) + QUEUE_GET_HEAD(prDataPort[i])); + } + + /* <3> Clear pending MSDU info in data done queue */ + KAL_ACQUIRE_MUTEX(prAdapter, MUTEX_TX_DATA_DONE_QUE); + while (QUEUE_IS_NOT_EMPTY(&prAdapter->rTxDataDoneQueue)) { + QUEUE_REMOVE_HEAD(&prAdapter->rTxDataDoneQueue, + prMsduInfo, struct MSDU_INFO *); + + nicTxFreePacket(prAdapter, prMsduInfo, FALSE); + nicTxReturnMsduInfo(prAdapter, prMsduInfo); + } + KAL_RELEASE_MUTEX(prAdapter, MUTEX_TX_DATA_DONE_QUE); +#endif + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used to clear all buffer in port 0/1 queue + * \param prAdapter Pointer of Adapter Data Structure + * + * \retval none + */ +/*----------------------------------------------------------------------------*/ +void wlanClearRxToOsQueue(IN struct ADAPTER *prAdapter) +{ + struct QUE rTempRxQue; + struct QUE *prTempRxQue = &rTempRxQue; + struct QUE_ENTRY *prQueueEntry = (struct QUE_ENTRY *) NULL; + + KAL_SPIN_LOCK_DECLARATION(); + QUEUE_INITIALIZE(prTempRxQue); + + /* 4 <1> Move whole list of CMD_INFO to temp queue */ + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_TO_OS_QUE); + QUEUE_MOVE_ALL(prTempRxQue, &prAdapter->rRxQueue); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_TO_OS_QUE); + + /* 4 <2> Remove all skbuf */ + QUEUE_REMOVE_HEAD(prTempRxQue, prQueueEntry, + struct QUE_ENTRY *); + while (prQueueEntry) { + kalRxIndicateOnePkt(prAdapter->prGlueInfo, + (void *) GLUE_GET_PKT_DESCRIPTOR(prQueueEntry)); + QUEUE_REMOVE_HEAD(prTempRxQue, prQueueEntry, + struct QUE_ENTRY *); + } + +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used to clear all commands in pending command queue + * \param prAdapter Pointer of Adapter Data Structure + * + * \retval none + */ +/*----------------------------------------------------------------------------*/ +void wlanClearPendingCommandQueue(IN struct ADAPTER *prAdapter) +{ + struct QUE rTempCmdQue; + struct QUE *prTempCmdQue = &rTempCmdQue; + struct QUE_ENTRY *prQueueEntry = (struct QUE_ENTRY *) NULL; + struct CMD_INFO *prCmdInfo = (struct CMD_INFO *) NULL; + + KAL_SPIN_LOCK_DECLARATION(); + QUEUE_INITIALIZE(prTempCmdQue); + + ASSERT(prAdapter); + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); + QUEUE_MOVE_ALL(prTempCmdQue, &prAdapter->rPendingCmdQueue); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); + + QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, + struct QUE_ENTRY *); + while (prQueueEntry) { + prCmdInfo = (struct CMD_INFO *) prQueueEntry; + + if (prCmdInfo->pfCmdTimeoutHandler) + prCmdInfo->pfCmdTimeoutHandler(prAdapter, prCmdInfo); + else + wlanReleaseCommand(prAdapter, prCmdInfo, + TX_RESULT_QUEUE_CLEARANCE); + + nicTxCancelSendingCmd(prAdapter, prCmdInfo); + + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + + QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, + struct QUE_ENTRY *); + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function will release thd CMD_INFO upon its attribution + * + * \param prAdapter Pointer of Adapter Data Structure + * \param prCmdInfo Pointer of CMD_INFO_T + * \param rTxDoneStatus Tx done status + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void wlanReleaseCommand(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, + IN enum ENUM_TX_RESULT_CODE rTxDoneStatus) +{ + struct TX_CTRL *prTxCtrl; + struct MSDU_INFO *prMsduInfo; + + ASSERT(prAdapter); + ASSERT(prCmdInfo); + + prTxCtrl = &prAdapter->rTxCtrl; + + switch (prCmdInfo->eCmdType) { + case COMMAND_TYPE_GENERAL_IOCTL: + case COMMAND_TYPE_NETWORK_IOCTL: + DBGLOG(INIT, INFO, + "Free CMD: ID[0x%x] SeqNum[%u] OID[%u]\n", + prCmdInfo->ucCID, prCmdInfo->ucCmdSeqNum, + prCmdInfo->fgIsOid); + + if (prCmdInfo->fgIsOid) { + kalOidComplete(prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, + prCmdInfo->u4SetInfoLen, + WLAN_STATUS_FAILURE); + } + break; + + case COMMAND_TYPE_SECURITY_FRAME: + case COMMAND_TYPE_MANAGEMENT_FRAME: + case COMMAND_TYPE_DATA_FRAME: + prMsduInfo = prCmdInfo->prMsduInfo; + + if (prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME || + prCmdInfo->eCmdType == COMMAND_TYPE_DATA_FRAME) { + kalSecurityFrameSendComplete(prAdapter->prGlueInfo, + prCmdInfo->prPacket, + WLAN_STATUS_FAILURE); + /* Avoid skb multiple free */ + prMsduInfo->prPacket = NULL; + } + + DBGLOG(INIT, INFO, + "Free %s Frame: B[%u]W:P[%u:%u]TS[%u]STA[%u]RSP[%u]CS[%u]\n", + prCmdInfo->eCmdType == + COMMAND_TYPE_MANAGEMENT_FRAME ? "MGMT" : "DATA/SEC", + prMsduInfo->ucBssIndex, + prMsduInfo->ucWlanIndex, + prMsduInfo->ucPID, + prMsduInfo->ucTxSeqNum, + prMsduInfo->ucStaRecIndex, + prMsduInfo->pfTxDoneHandler ? TRUE : FALSE, + prCmdInfo->ucCmdSeqNum); + + /* invoke callbacks */ + if (prMsduInfo->pfTxDoneHandler != NULL) + prMsduInfo->pfTxDoneHandler(prAdapter, prMsduInfo, + rTxDoneStatus); + + if (prCmdInfo->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME) + GLUE_DEC_REF_CNT(prTxCtrl->i4TxMgmtPendingNum); + + cnmMgtPktFree(prAdapter, prMsduInfo); + break; + + default: + ASSERT(0); + break; + } + +} /* end of wlanReleaseCommand() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function will search the CMD Queue to look for the pending OID + * and compelete it immediately when system request a reset. + * + * \param prAdapter ointer of Adapter Data Structure + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void wlanReleasePendingOid(IN struct ADAPTER *prAdapter, + IN unsigned long ulParamPtr) +{ + struct QUE *prCmdQue; + struct QUE rTempCmdQue; + struct QUE *prTempCmdQue = &rTempCmdQue; + struct QUE_ENTRY *prQueueEntry = (struct QUE_ENTRY *) NULL; + struct CMD_INFO *prCmdInfo = (struct CMD_INFO *) NULL; + + KAL_SPIN_LOCK_DECLARATION(); + + DEBUGFUNC("wlanReleasePendingOid"); + + ASSERT(prAdapter); + + do { + if (ulParamPtr == 1) + break; + + if (prAdapter->ucOidTimeoutCount >= + WLAN_OID_NO_ACK_THRESHOLD) { + if (!prAdapter->fgIsChipNoAck) { + DBGLOG(INIT, WARN, + "No response from chip for %u times, set NoAck flag!\n", + prAdapter->ucOidTimeoutCount); +#if 0 + glSetRstReason(RST_OID_TIMEOUT); + GL_RESET_TRIGGER(prAdapter, + RST_FLAG_CHIP_RESET); +#endif + } + + if (prAdapter->ucOidTimeoutCount >= + WLAN_OID_NO_ACK_THRESHOLD) { + if (!prAdapter->fgIsChipNoAck) { + DBGLOG(INIT, WARN, + "No response from chip for %u times, set NoAck flag!\n", + prAdapter->ucOidTimeoutCount); + } + + prAdapter->fgIsChipNoAck = TRUE; + } + + prAdapter->u4HifDbgFlag |= DEG_HIF_ALL; + kalSetHifDbgEvent(prAdapter->prGlueInfo); + } + } while (FALSE); + + do { +#if CFG_SUPPORT_MULTITHREAD + KAL_ACQUIRE_MUTEX(prAdapter, MUTEX_TX_CMD_CLEAR); +#endif + /* 1: Clear pending OID in glue layer command queue */ + kalOidCmdClearance(prAdapter->prGlueInfo); + +#if CFG_SUPPORT_MULTITHREAD + /* Clear pending OID in main_thread to hif_thread command queue + */ + wlanClearTxOidCommand(prAdapter); +#endif + + /* 2: Clear Pending OID in prAdapter->rPendingCmdQueue */ + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); + + prCmdQue = &prAdapter->rPendingCmdQueue; + QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); + + QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, + struct QUE_ENTRY *); + while (prQueueEntry) { + prCmdInfo = (struct CMD_INFO *) prQueueEntry; + + if (prCmdInfo->fgIsOid) { + DBGLOG(OID, INFO, + "Clear pending OID CMD ID[0x%02X] SEQ[%u] buf[0x%p]\n", + prCmdInfo->ucCID, prCmdInfo->ucCmdSeqNum, + prCmdInfo->pucInfoBuffer); + + if (prCmdInfo->pfCmdTimeoutHandler) { + prCmdInfo->pfCmdTimeoutHandler( + prAdapter, prCmdInfo); + } else { + kalOidComplete(prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, + 0, WLAN_STATUS_FAILURE); + } + + KAL_RELEASE_SPIN_LOCK(prAdapter, + SPIN_LOCK_CMD_PENDING); + nicTxCancelSendingCmd(prAdapter, prCmdInfo); + KAL_ACQUIRE_SPIN_LOCK(prAdapter, + SPIN_LOCK_CMD_PENDING); + + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + } else { + QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); + } + + QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, + struct QUE_ENTRY *); + } + + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); + + /* 3: Clear pending OID queued in pvOidEntry with REQ_FLAG_OID + * set + */ + kalOidClearance(prAdapter->prGlueInfo); + +#if CFG_SUPPORT_MULTITHREAD + KAL_RELEASE_MUTEX(prAdapter, MUTEX_TX_CMD_CLEAR); +#endif + } while (FALSE); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function will search the CMD Queue to look for the pending + * CMD/OID for specific + * NETWORK TYPE and compelete it immediately when system request a reset. + * + * \param prAdapter ointer of Adapter Data Structure + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void wlanReleasePendingCMDbyBssIdx(IN struct ADAPTER + *prAdapter, IN uint8_t ucBssIndex) +{ +#if 0 + struct QUE *prCmdQue; + struct QUE rTempCmdQue; + struct QUE *prTempCmdQue = &rTempCmdQue; + struct QUE_ENTRY *prQueueEntry = (struct QUE_ENTRY *) NULL; + struct CMD_INFO *prCmdInfo = (struct CMD_INFO *) NULL; + + KAL_SPIN_LOCK_DECLARATION(); + + ASSERT(prAdapter); + + do { + /* 1: Clear Pending OID in prAdapter->rPendingCmdQueue */ + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); + + prCmdQue = &prAdapter->rPendingCmdQueue; + QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); + + QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, + struct QUE_ENTRY *); + while (prQueueEntry) { + prCmdInfo = (struct CMD_INFO *) prQueueEntry; + + DBGLOG(P2P, TRACE, "Pending CMD for BSS:%d\n", + prCmdInfo->ucBssIndex); + + if (prCmdInfo->ucBssIndex == ucBssIndex) { + if (prCmdInfo->pfCmdTimeoutHandler) { + prCmdInfo->pfCmdTimeoutHandler( + prAdapter, prCmdInfo); + } else if (prCmdInfo->fgIsOid) { + kalOidComplete(prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, + 0, WLAN_STATUS_FAILURE); + } + + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + } else { + QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); + } + + QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, + struct QUE_ENTRY *); + } + + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); + + } while (FALSE); +#endif + + +} /* wlanReleasePendingCMDbyBssIdx */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Return the indicated packet buffer and reallocate one to the RFB + * + * \param prAdapter Pointer of Adapter Data Structure + * \param pvPacket Pointer of returned packet + * + * \retval WLAN_STATUS_SUCCESS: Success + * \retval WLAN_STATUS_FAILURE: Failed + */ +/*----------------------------------------------------------------------------*/ +void wlanReturnPacketDelaySetupTimeout(IN struct ADAPTER + *prAdapter, IN unsigned long ulParamPtr) +{ + struct RX_CTRL *prRxCtrl; + struct SW_RFB *prSwRfb = NULL; + + KAL_SPIN_LOCK_DECLARATION(); + uint32_t status = WLAN_STATUS_SUCCESS; + struct QUE *prQueList; + + ASSERT(prAdapter); + + prRxCtrl = &prAdapter->rRxCtrl; + ASSERT(prRxCtrl); + + prQueList = &prRxCtrl->rIndicatedRfbList; + DBGLOG(RX, WARN, "%s: IndicatedRfbList num = %u\n", + __func__, prQueList->u4NumElem); + + while (QUEUE_IS_NOT_EMPTY(&prRxCtrl->rIndicatedRfbList)) { + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_FREE_QUE); + QUEUE_REMOVE_HEAD(&prRxCtrl->rIndicatedRfbList, prSwRfb, + struct SW_RFB *); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_FREE_QUE); + + if (prSwRfb) { + status = nicRxSetupRFB(prAdapter, prSwRfb); + nicRxReturnRFB(prAdapter, prSwRfb); + } else { + log_dbg(RX, WARN, "prSwRfb == NULL\n"); + break; + } + + if (status != WLAN_STATUS_SUCCESS) + break; + } + + if (status != WLAN_STATUS_SUCCESS) { + DBGLOG(RX, WARN, "Restart ReturnIndicatedRfb Timer (%u)\n", + RX_RETURN_INDICATED_RFB_TIMEOUT_SEC); + /* restart timer */ + cnmTimerStartTimer(prAdapter, + &prAdapter->rPacketDelaySetupTimer, + SEC_TO_MSEC(RX_RETURN_INDICATED_RFB_TIMEOUT_SEC)); + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Return the packet buffer and reallocate one to the RFB + * + * \param prAdapter Pointer of Adapter Data Structure + * \param pvPacket Pointer of returned packet + * + * \retval WLAN_STATUS_SUCCESS: Success + * \retval WLAN_STATUS_FAILURE: Failed + */ +/*----------------------------------------------------------------------------*/ +void wlanReturnPacket(IN struct ADAPTER *prAdapter, + IN void *pvPacket) +{ + struct RX_CTRL *prRxCtrl; + struct SW_RFB *prSwRfb = NULL; + + KAL_SPIN_LOCK_DECLARATION(); + + DEBUGFUNC("wlanReturnPacket"); + + ASSERT(prAdapter); + + prRxCtrl = &prAdapter->rRxCtrl; + ASSERT(prRxCtrl); + + if (pvPacket) { + kalPacketFree(prAdapter->prGlueInfo, pvPacket); + RX_ADD_CNT(prRxCtrl, RX_DATA_RETURNED_COUNT, 1); +#if CFG_NATIVE_802_11 + if (GLUE_TEST_FLAG(prAdapter->prGlueInfo, GLUE_FLAG_HALT)) { + /*Todo:: nothing */ + /*Todo:: nothing */ + } +#endif + } + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_FREE_QUE); + QUEUE_REMOVE_HEAD(&prRxCtrl->rIndicatedRfbList, prSwRfb, + struct SW_RFB *); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_FREE_QUE); + if (!prSwRfb) { + DBGLOG(RX, WARN, "No free SwRfb!\n"); + return; + } + + if (nicRxSetupRFB(prAdapter, prSwRfb)) { + DBGLOG(RX, WARN, + "Cannot allocate packet buffer for SwRfb!\n"); + if (!timerPendingTimer( + &prAdapter->rPacketDelaySetupTimer)) { + DBGLOG(RX, WARN, + "Start ReturnIndicatedRfb Timer (%u)\n", + RX_RETURN_INDICATED_RFB_TIMEOUT_SEC); + cnmTimerStartTimer(prAdapter, + &prAdapter->rPacketDelaySetupTimer, + SEC_TO_MSEC(RX_RETURN_INDICATED_RFB_TIMEOUT_SEC)); + } + } + nicRxReturnRFB(prAdapter, prSwRfb); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is a required function that returns information about + * the capabilities and status of the driver and/or its network adapter. + * + * \param[IN] prAdapter Pointer to the Adapter structure. + * \param[IN] pfnOidQryHandler Function pointer for the OID query handler. + * \param[IN] pvInfoBuf Points to a buffer for return the query + * information. + * \param[IN] u4QueryBufferLen Specifies the number of bytes at pvInfoBuf. + * \param[OUT] pu4QueryInfoLen Points to the number of bytes it written or is + * needed. + * + * \retval WLAN_STATUS_xxx Different WLAN_STATUS code returned by different + * handlers. + * + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanQueryInformation(IN struct ADAPTER *prAdapter, + IN PFN_OID_HANDLER_FUNC pfnOidQryHandler, + IN void *pvInfoBuf, IN uint32_t u4InfoBufLen, + OUT uint32_t *pu4QryInfoLen) +{ + uint32_t status = WLAN_STATUS_FAILURE; + + ASSERT(prAdapter); + ASSERT(pu4QryInfoLen); + + /* ignore any OID request after connected, under PS current measurement + * mode + */ + if (prAdapter->u4PsCurrentMeasureEn && + aisGetConnectedBssInfo(prAdapter)) { + /* note: return WLAN_STATUS_FAILURE or + * WLAN_STATUS_SUCCESS for blocking OIDs during current + * measurement ?? + */ + return WLAN_STATUS_SUCCESS; + } +#if 1 + /* most OID handler will just queue a command packet */ + status = pfnOidQryHandler(prAdapter, pvInfoBuf, + u4InfoBufLen, pu4QryInfoLen); +#else + if (wlanIsHandlerNeedHwAccess(pfnOidQryHandler, FALSE)) { + ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); + + /* Reset sleepy state */ + if (prAdapter->fgWiFiInSleepyState == TRUE) + prAdapter->fgWiFiInSleepyState = FALSE; + + status = pfnOidQryHandler(prAdapter, pvInfoBuf, + u4InfoBufLen, pu4QryInfoLen); + + RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); + } else + status = pfnOidQryHandler(prAdapter, pvInfoBuf, + u4InfoBufLen, pu4QryInfoLen); +#endif + + return status; + +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is a required function that allows bound protocol + * drivers, or NDIS, to request changes in the state information that + * the miniport maintains for particular object identifiers, such as + * changes in multicast addresses. + * + * \param[IN] prAdapter Pointer to the Glue info structure. + * \param[IN] pfnOidSetHandler Points to the OID set handlers. + * \param[IN] pvInfoBuf Points to a buffer containing the OID-specific data + * for the set. + * \param[IN] u4InfoBufLen Specifies the number of bytes at prSetBuffer. + * \param[OUT] pu4SetInfoLen Points to the number of bytes it read or is needed. + * + * \retval WLAN_STATUS_xxx Different WLAN_STATUS code returned by different + * handlers. + * + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanSetInformation(IN struct ADAPTER *prAdapter, + IN PFN_OID_HANDLER_FUNC pfnOidSetHandler, + IN void *pvInfoBuf, IN uint32_t u4InfoBufLen, + OUT uint32_t *pu4SetInfoLen) +{ + uint32_t status = WLAN_STATUS_FAILURE; + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + /* ignore any OID request after connected, under PS current measurement + * mode + */ + if (prAdapter->u4PsCurrentMeasureEn && + aisGetConnectedBssInfo(prAdapter)) { + /* note: return WLAN_STATUS_FAILURE or WLAN_STATUS_SUCCESS + * for blocking OIDs during current measurement ?? + */ + return WLAN_STATUS_SUCCESS; + } +#if 1 + /* most OID handler will just queue a command packet + * for power state transition OIDs, handler will acquire power control + * by itself + */ + status = pfnOidSetHandler(prAdapter, pvInfoBuf, + u4InfoBufLen, pu4SetInfoLen); +#else + if (wlanIsHandlerNeedHwAccess(pfnOidSetHandler, TRUE)) { + ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); + + /* Reset sleepy state */ + if (prAdapter->fgWiFiInSleepyState == TRUE) + prAdapter->fgWiFiInSleepyState = FALSE; + + status = pfnOidSetHandler(prAdapter, pvInfoBuf, + u4InfoBufLen, pu4SetInfoLen); + + RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); + } else { + status = pfnOidSetHandler(prAdapter, pvInfoBuf, + u4InfoBufLen, pu4SetInfoLen); + } +#endif + + return status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is called to set RX filter to Promiscuous Mode. + * + * \param[IN] prAdapter Pointer to the Adapter structure. + * \param[IN] fgEnablePromiscuousMode Enable/ disable RX Promiscuous Mode. + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void wlanSetPromiscuousMode(IN struct ADAPTER *prAdapter, + IN u_int8_t fgEnablePromiscuousMode) +{ + ASSERT(prAdapter); + +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is called to set RX filter to allow to receive + * broadcast address packets. + * + * \param[IN] prAdapter Pointer to the Adapter structure. + * \param[IN] fgEnableBroadcast Enable/ disable broadcast packet to be received. + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void wlanRxSetBroadcast(IN struct ADAPTER *prAdapter, + IN u_int8_t fgEnableBroadcast) +{ + ASSERT(prAdapter); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is called to send out CMD_ID_DUMMY command packet + * + * \param[IN] prAdapter Pointer to the Adapter structure. + * + * \return WLAN_STATUS_SUCCESS + * \return WLAN_STATUS_FAILURE + */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanSendDummyCmd(IN struct ADAPTER *prAdapter, + IN u_int8_t fgIsReqTxRsrc) +{ + uint32_t status = WLAN_STATUS_SUCCESS; + struct GLUE_INFO *prGlueInfo; + struct CMD_INFO *prCmdInfo; + struct mt66xx_chip_info *prChipInfo; + + ASSERT(prAdapter); + + prGlueInfo = prAdapter->prGlueInfo; + prChipInfo = prAdapter->chip_info; + + prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, + prChipInfo->u2CmdTxHdrSize); + if (!prCmdInfo) { + DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); + return WLAN_STATUS_FAILURE; + } + + prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; + prCmdInfo->u2InfoBufLen = (uint16_t) prChipInfo->u2CmdTxHdrSize; + prCmdInfo->pfCmdDoneHandler = NULL; + prCmdInfo->pfCmdTimeoutHandler = NULL; + prCmdInfo->fgIsOid = TRUE; + prCmdInfo->ucCID = CMD_ID_DUMMY_RSV; + prCmdInfo->fgSetQuery = TRUE; + prCmdInfo->fgNeedResp = FALSE; + prCmdInfo->ucCmdSeqNum = 0; + prCmdInfo->u4SetInfoLen = 0; + + NIC_FILL_CMD_TX_HDR(prAdapter, + prCmdInfo->pucInfoBuffer, + prCmdInfo->u2InfoBufLen, + prCmdInfo->ucCID, + CMD_PACKET_TYPE_ID, + &prCmdInfo->ucCmdSeqNum, + prCmdInfo->fgSetQuery, NULL, FALSE, 0, S2D_INDEX_CMD_H2N); + + if (fgIsReqTxRsrc) { + if (wlanSendCommand(prAdapter, + prCmdInfo) != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, ERROR, + "Fail to transmit CMD_ID_DUMMY command\n"); + status = WLAN_STATUS_FAILURE; + } + } else { + if (nicTxCmd(prAdapter, prCmdInfo, + TC4_INDEX) != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, ERROR, + "Fail to transmit CMD_ID_DUMMY command\n"); + status = WLAN_STATUS_FAILURE; + } + } + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + + return status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is called to send out CMD_NIC_POWER_CTRL command packet + * + * \param[IN] prAdapter Pointer to the Adapter structure. + * \param[IN] ucPowerMode refer to CMD/EVENT document + * + * \return WLAN_STATUS_SUCCESS + * \return WLAN_STATUS_FAILURE + */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanSendNicPowerCtrlCmd(IN struct ADAPTER + *prAdapter, IN uint8_t ucPowerMode) +{ + uint32_t status = WLAN_STATUS_SUCCESS; + struct GLUE_INFO *prGlueInfo; + struct CMD_INFO *prCmdInfo; + uint8_t ucTC; + struct CMD_NIC_POWER_CTRL *pNicPwrCtrl; + struct mt66xx_chip_info *prChipInfo; + uint16_t cmd_size; + + ASSERT(prAdapter); + + prGlueInfo = prAdapter->prGlueInfo; + prChipInfo = prAdapter->chip_info; + + /* 1. Prepare CMD */ + cmd_size = + prChipInfo->u2CmdTxHdrSize + sizeof(struct CMD_NIC_POWER_CTRL); + prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, cmd_size); + if (!prCmdInfo) { + DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); +#if CFG_ENABLE_KEYWORD_EXCEPTION_MECHANISM + mtk_wcn_wmt_assert_keyword(WMTDRV_TYPE_WIFI, + "[Wi-Fi Off] Allocate CMD_INFO_T ==> FAILED."); +#endif + return WLAN_STATUS_FAILURE; + } + + /* 2.2 Setup common CMD Info Packet */ + prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; + prCmdInfo->u2InfoBufLen = cmd_size; + prCmdInfo->pfCmdDoneHandler = NULL; + prCmdInfo->pfCmdTimeoutHandler = NULL; + prCmdInfo->fgIsOid = TRUE; + prCmdInfo->ucCID = CMD_ID_NIC_POWER_CTRL; + prCmdInfo->fgSetQuery = TRUE; + prCmdInfo->fgNeedResp = FALSE; + prCmdInfo->u4SetInfoLen = sizeof(struct CMD_NIC_POWER_CTRL); + + /* 2.3 Setup WIFI_CMD_T */ + NIC_FILL_CMD_TX_HDR(prAdapter, + prCmdInfo->pucInfoBuffer, + prCmdInfo->u2InfoBufLen, prCmdInfo->ucCID, + CMD_PACKET_TYPE_ID, + &prCmdInfo->ucCmdSeqNum, + prCmdInfo->fgSetQuery, + &pNicPwrCtrl, FALSE, 0, S2D_INDEX_CMD_H2N); + + kalMemZero(pNicPwrCtrl, sizeof(struct CMD_NIC_POWER_CTRL)); + pNicPwrCtrl->ucPowerMode = ucPowerMode; + + /* 3. Issue CMD for entering specific power mode */ + ucTC = TC4_INDEX; + + while (1) { + /* 3.0 Removal check */ + if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE + || fgIsBusAccessFailed == TRUE) { + status = WLAN_STATUS_FAILURE; + break; + } + /* 3.1 Acquire TX Resource */ + if (nicTxAcquireResource(prAdapter, ucTC, + nicTxGetCmdPageCount(prAdapter, prCmdInfo), TRUE) + == WLAN_STATUS_RESOURCES) { + if (nicTxPollingResource(prAdapter, ucTC) != + WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, ERROR, + "Fail to get TX resource return within timeout\n"); + status = WLAN_STATUS_FAILURE; + prAdapter->fgIsChipNoAck = TRUE; + break; + } + continue; + } + break; + }; + + /* 3.2 Send CMD Info Packet */ + if (nicTxCmd(prAdapter, prCmdInfo, + ucTC) != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, ERROR, + "Fail to transmit CMD_NIC_POWER_CTRL command\n"); +#if CFG_ENABLE_KEYWORD_EXCEPTION_MECHANISM + mtk_wcn_wmt_assert_keyword(WMTDRV_TYPE_WIFI, + "[Wi-Fi Off] Fail to transmit CMD_NIC_POWER_CTRL command"); +#endif + status = WLAN_STATUS_FAILURE; + } + + /* 4. Free CMD Info Packet. */ + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + + /* 5. Add flag */ + if (ucPowerMode == 1) + prAdapter->fgIsEnterD3ReqIssued = TRUE; + + return status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is called to check if it is RF test mode and + * the OID is allowed to be called or not + * + * \param[IN] prAdapter Pointer to the Adapter structure. + * \param[IN] fgEnableBroadcast Enable/ disable broadcast packet to be received. + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +u_int8_t wlanIsHandlerAllowedInRFTest(IN PFN_OID_HANDLER_FUNC pfnOidHandler, + IN u_int8_t fgSetInfo) +{ + PFN_OID_HANDLER_FUNC *apfnOidHandlerAllowedInRFTest; + uint32_t i; + uint32_t u4NumOfElem; + + if (fgSetInfo) { + apfnOidHandlerAllowedInRFTest = + apfnOidSetHandlerAllowedInRFTest; + u4NumOfElem = sizeof(apfnOidSetHandlerAllowedInRFTest) / + sizeof(PFN_OID_HANDLER_FUNC); + } else { + apfnOidHandlerAllowedInRFTest = + apfnOidQueryHandlerAllowedInRFTest; + u4NumOfElem = sizeof(apfnOidQueryHandlerAllowedInRFTest) / + sizeof(PFN_OID_HANDLER_FUNC); + } + + for (i = 0; i < u4NumOfElem; i++) { + if (apfnOidHandlerAllowedInRFTest[i] == pfnOidHandler) + return TRUE; + } + + return FALSE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called to get the chip information + * + * @param prAdapter Pointer to the Adapter structure. + * + * @return + */ +/*----------------------------------------------------------------------------*/ + +uint32_t wlanSetChipEcoInfo(IN struct ADAPTER *prAdapter) +{ + uint32_t hw_version = 0, sw_version = 0; + struct mt66xx_chip_info *prChipInfo = prAdapter->chip_info; + uint32_t chip_id = prChipInfo->chip_id; + /* WLAN_STATUS status; */ + uint32_t u4Status = WLAN_STATUS_SUCCESS; + + DEBUGFUNC("wlanSetChipEcoInfo.\n"); + + if (wlanAccessRegister(prAdapter, + prChipInfo->top_hvr, &hw_version, 0, 0) != + WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, ERROR, + "wlanSetChipEcoInfo >> get TOP_HVR failed.\n"); + u4Status = WLAN_STATUS_FAILURE; + } else if (wlanAccessRegister(prAdapter, + prChipInfo->top_fvr, &sw_version, 0, 0) != + WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, ERROR, + "wlanSetChipEcoInfo >> get TOP_FVR failed.\n"); + u4Status = WLAN_STATUS_FAILURE; + } else { + /* success */ + nicSetChipHwVer((uint8_t)(GET_HW_VER(hw_version) & 0xFF)); + nicSetChipFactoryVer((uint8_t)((GET_HW_VER(hw_version) >> 8) & + 0xF)); + nicSetChipSwVer((uint8_t)GET_FW_VER(sw_version)); + + /* Assign current chip version */ + prAdapter->chip_info->eco_ver = nicGetChipEcoVer(prAdapter); + } + + DBGLOG(INIT, INFO, + "Chip ID[%04X] Version[E%u] HW[0x%08x] SW[0x%08x]\n", + chip_id, prAdapter->chip_info->eco_ver, hw_version, + sw_version); + + return u4Status; +} + +#if (CFG_ENABLE_FW_DOWNLOAD == 1) +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called to read/write a certain N9 + * register by inband command in blocking mode in ROM code stage + * + * @param prAdapter Pointer to the Adapter structure. + * u4DestAddr Address of destination address + * u4ImgSecSize Length of the firmware block + * fgReset should be set to TRUE if this is the 1st configuration + * + * @return WLAN_STATUS_SUCCESS + * WLAN_STATUS_FAILURE + */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanAccessRegister(IN struct ADAPTER *prAdapter, + IN uint32_t u4Addr, IN uint32_t *pru4Result, + IN uint32_t u4Data, + IN uint8_t ucSetQuery) +{ + struct mt66xx_chip_info *prChipInfo; + struct CMD_INFO *prCmdInfo; + struct INIT_WIFI_EVENT *prInitEvent; + struct INIT_CMD_ACCESS_REG *prInitCmdAccessReg; + struct INIT_EVENT_ACCESS_REG *prInitEventAccessReg; + uint8_t ucTC, ucCmdSeqNum; + uint16_t cmd_size; + uint8_t *aucBuffer; + uint32_t u4EventSize; + uint32_t u4Status = WLAN_STATUS_SUCCESS; + + ASSERT(prAdapter); + prChipInfo = prAdapter->chip_info; + + DEBUGFUNC("wlanAccessRegister"); + + /* 1. Allocate CMD Info Packet and its Buffer. */ + cmd_size = sizeof(struct INIT_HIF_TX_HEADER) + + sizeof(struct INIT_HIF_TX_HEADER_PENDING_FOR_HW_32BYTES) + + sizeof(struct INIT_CMD_ACCESS_REG); + prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, cmd_size); + + if (!prCmdInfo) { + DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); + return WLAN_STATUS_FAILURE; + } + + u4EventSize = prChipInfo->init_evt_rxd_size + + prChipInfo->init_event_size + + sizeof(struct INIT_EVENT_ACCESS_REG); + aucBuffer = kalMemAlloc(u4EventSize, PHY_MEM_TYPE); + if (!aucBuffer) { + log_dbg(INIT, ERROR, "memory not enough for aucBuffer\n"); + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + return WLAN_STATUS_FAILURE; + } + + prCmdInfo->u2InfoBufLen = cmd_size; + +#if (CFG_USE_TC4_RESOURCE_FOR_INIT_CMD == 1) + /* 2. Use TC4's resource to download image. (TC4 as CPU) */ + ucTC = TC4_INDEX; +#else + /* 2. Use TC0's resource to download image. + * Only TC0 is allowed because SDIO HW always reports + * MCU's TXQ_CNT at TXQ0_CNT in CR4 architecutre) + */ + ucTC = TC0_INDEX; +#endif + + NIC_FILL_CMD_TX_HDR(prAdapter, + prCmdInfo->pucInfoBuffer, + prCmdInfo->u2InfoBufLen, + INIT_CMD_ID_ACCESS_REG, + INIT_CMD_PACKET_TYPE_ID, + &ucCmdSeqNum, + FALSE, + (void **)&prInitCmdAccessReg, + TRUE, 0, S2D_INDEX_CMD_H2N); + + /* 5. Setup CMD_ACCESS_REG */ + prInitCmdAccessReg->ucSetQuery = ucSetQuery; + prInitCmdAccessReg->u4Address = u4Addr; + prInitCmdAccessReg->u4Data = u4Data; + + /* 6. Send CMD_ACCESS_REG command */ + while (1) { + /* 6.1 Acquire TX Resource */ + if (nicTxAcquireResource + (prAdapter, ucTC, nicTxGetPageCount(prAdapter, + prCmdInfo->u2InfoBufLen, TRUE), TRUE) + == WLAN_STATUS_RESOURCES) { + if (nicTxPollingResource(prAdapter, + ucTC) != WLAN_STATUS_SUCCESS) { + u4Status = WLAN_STATUS_FAILURE; + DBGLOG(INIT, ERROR, + "Fail to get TX resource return within timeout\n"); + goto exit; + } + continue; + } + + /* 6.2 Send CMD Info Packet */ + if (nicTxInitCmd(prAdapter, prCmdInfo, + prChipInfo->u2TxInitCmdPort) != WLAN_STATUS_SUCCESS) { + u4Status = WLAN_STATUS_FAILURE; + DBGLOG(INIT, ERROR, + "Fail to transmit image download command\n"); + goto exit; + } + + break; + }; + + /* 7. Wait for INIT_EVENT_ID_CMD_RESULT */ + u4Status = wlanAccessRegisterStatus(prAdapter, ucCmdSeqNum, ucSetQuery, + aucBuffer, u4EventSize); + if (ucSetQuery == 0) { + prInitEvent = (struct INIT_WIFI_EVENT *) + (aucBuffer + prChipInfo->init_evt_rxd_size); + prInitEventAccessReg = (struct INIT_EVENT_ACCESS_REG *) + prInitEvent->aucBuffer; + + if (!prInitEventAccessReg) { + DBGLOG(INIT, ERROR, + "prInitEventAccessReg == NULL\n"); + u4Status = WLAN_STATUS_FAILURE; + goto exit; + } + + if (prInitEventAccessReg->u4Address != u4Addr) { + DBGLOG(INIT, ERROR, + "Event reports address incorrect. 0x%08x, 0x%08x.\n", + u4Addr, prInitEventAccessReg->u4Address); + u4Status = WLAN_STATUS_FAILURE; + } + *pru4Result = prInitEventAccessReg->u4Data; + } + +exit: + /* 8. Free CMD Info Packet. */ + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + + kalMemFree(aucBuffer, PHY_MEM_TYPE, u4EventSize); + + return u4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! +* @brief This function is called to get the response of INIT_CMD_ACCESS_REG +* +* @param prAdapter Pointer to the Adapter structure. +* ucCmdSeqNum Sequence number of previous firmware scatter +* ucSetQuery Read or write +* prEvent the pointer of buffer to store the response +* +* @return WLAN_STATUS_SUCCESS +* WLAN_STATUS_FAILURE +*/ +/*----------------------------------------------------------------------------*/ +uint32_t wlanAccessRegisterStatus(IN struct ADAPTER *prAdapter, + IN uint8_t ucCmdSeqNum, + IN uint8_t ucSetQuery, IN void *prEvent, + IN uint32_t u4EventLen) +{ + struct mt66xx_chip_info *prChipInfo; + struct INIT_WIFI_EVENT *prInitEvent; + uint32_t u4RxPktLength; + uint32_t u4Status = WLAN_STATUS_SUCCESS; + uint8_t ucPortIdx = IMG_DL_STATUS_PORT_IDX; + + ASSERT(prAdapter); + prChipInfo = prAdapter->chip_info; + + do { + if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE + || fgIsBusAccessFailed == TRUE) { + u4Status = WLAN_STATUS_FAILURE; + } else if (nicRxWaitResponse(prAdapter, ucPortIdx, prEvent, + u4EventLen, &u4RxPktLength) != WLAN_STATUS_SUCCESS) { + GL_RESET_TRIGGER(prAdapter, + RST_FLAG_DO_CORE_DUMP | + RST_FLAG_PREVENT_POWER_OFF); + u4Status = WLAN_STATUS_FAILURE; + } else { + prInitEvent = (struct INIT_WIFI_EVENT *) + (prEvent + prChipInfo->init_evt_rxd_size); + + /* EID / SeqNum check */ + if (((prInitEvent->ucEID != INIT_EVENT_ID_CMD_RESULT) && + (ucSetQuery == 1)) || + ((prInitEvent->ucEID != INIT_EVENT_ID_ACCESS_REG) + && (ucSetQuery == 0))) { + GL_RESET_TRIGGER(prAdapter, + RST_FLAG_DO_CORE_DUMP | + RST_FLAG_PREVENT_POWER_OFF); + u4Status = WLAN_STATUS_FAILURE; + DBGLOG(INIT, ERROR, + "wlanAccessRegisterStatus: incorrect ucEID. ucSetQuery = 0x%x\n", + ucSetQuery); + } else if (prInitEvent->ucSeqNum != ucCmdSeqNum) { + u4Status = WLAN_STATUS_FAILURE; + GL_RESET_TRIGGER(prAdapter, + RST_FLAG_DO_CORE_DUMP | + RST_FLAG_PREVENT_POWER_OFF); + DBGLOG(INIT, ERROR, + "wlanAccessRegisterStatus: incorrect ucCmdSeqNum. = 0x%x\n", + ucCmdSeqNum); + } else { + } + } + } while (FALSE); + + return u4Status; +} +#endif /* CFG_ENABLE_FW_DOWNLOAD == 1 */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called to process queued RX packets + * + * @param prAdapter Pointer to the Adapter structure. + * prSwRfbListHead Pointer to head of RX packets link list + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanProcessQueuedSwRfb(IN struct ADAPTER + *prAdapter, IN struct SW_RFB *prSwRfbListHead) +{ + struct SW_RFB *prSwRfb, *prNextSwRfb; + struct TX_CTRL *prTxCtrl; + struct RX_CTRL *prRxCtrl; + struct STA_RECORD *prStaRec; + + ASSERT(prAdapter); + ASSERT(prSwRfbListHead); + + prTxCtrl = &prAdapter->rTxCtrl; + prRxCtrl = &prAdapter->rRxCtrl; + + prSwRfb = prSwRfbListHead; + + do { + /* save next first */ + prNextSwRfb = (struct SW_RFB *) QUEUE_GET_NEXT_ENTRY(( + struct QUE_ENTRY *) prSwRfb); + + switch (prSwRfb->eDst) { + case RX_PKT_DESTINATION_HOST: + prStaRec = cnmGetStaRecByIndex(prAdapter, + prSwRfb->ucStaRecIdx); + if (prStaRec && IS_STA_IN_AIS(prStaRec)) { +#if ARP_MONITER_ENABLE + qmHandleRxArpPackets(prAdapter, prSwRfb); +#endif + } + + nicRxProcessPktWithoutReorder(prAdapter, prSwRfb); + break; + + case RX_PKT_DESTINATION_FORWARD: + nicRxProcessForwardPkt(prAdapter, prSwRfb); + break; + + case RX_PKT_DESTINATION_HOST_WITH_FORWARD: + nicRxProcessGOBroadcastPkt(prAdapter, prSwRfb); + break; + + case RX_PKT_DESTINATION_NULL: + nicRxReturnRFB(prAdapter, prSwRfb); + break; + + default: + break; + } + +#if CFG_HIF_RX_STARVATION_WARNING + prRxCtrl->u4DequeuedCnt++; +#endif + prSwRfb = prNextSwRfb; + } while (prSwRfb); + + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called to purge queued TX packets + * by indicating failure to OS and returned to free list + * + * @param prAdapter Pointer to the Adapter structure. + * prMsduInfoListHead Pointer to head of TX packets link list + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanProcessQueuedMsduInfo(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfoListHead) +{ + ASSERT(prAdapter); + ASSERT(prMsduInfoListHead); + + nicTxFreeMsduInfoPacket(prAdapter, prMsduInfoListHead); + nicTxReturnMsduInfo(prAdapter, prMsduInfoListHead); + + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called to check if the OID handler needs timeout + * + * @param prAdapter Pointer to the Adapter structure. + * pfnOidHandler Pointer to the OID handler + * + * @return TRUE + * FALSE + */ +/*----------------------------------------------------------------------------*/ +u_int8_t wlanoidTimeoutCheck(IN struct ADAPTER *prAdapter, + IN PFN_OID_HANDLER_FUNC pfnOidHandler) +{ + PFN_OID_HANDLER_FUNC *apfnOidHandlerWOTimeoutCheck; + uint32_t i; + uint32_t u4NumOfElem; + uint32_t u4OidTimeout; + + apfnOidHandlerWOTimeoutCheck = apfnOidWOTimeoutCheck; + u4NumOfElem = sizeof(apfnOidWOTimeoutCheck) / sizeof( + PFN_OID_HANDLER_FUNC); + + for (i = 0; i < u4NumOfElem; i++) { + if (apfnOidHandlerWOTimeoutCheck[i] == pfnOidHandler) + return FALSE; + } + + /* Decrease OID timeout threshold if chip NoAck/resetting */ + if (wlanIsChipNoAck(prAdapter)) { + u4OidTimeout = WLAN_OID_TIMEOUT_THRESHOLD_IN_RESETTING; + DBGLOG(INIT, INFO, + "Decrease OID timeout to %ums due to NoACK/CHIP-RESET\n", + u4OidTimeout); + } else { + u4OidTimeout = WLAN_OID_TIMEOUT_THRESHOLD; + } + + /* Set OID timer for timeout check */ + cnmTimerStartTimer(prAdapter, + &(prAdapter->rOidTimeoutTimer), u4OidTimeout); + + return TRUE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called to clear any pending OID timeout check + * + * @param prAdapter Pointer to the Adapter structure. + * + * @return none + */ +/*----------------------------------------------------------------------------*/ +void wlanoidClearTimeoutCheck(IN struct ADAPTER *prAdapter) +{ + ASSERT(prAdapter); + + cnmTimerStopTimer(prAdapter, &(prAdapter->rOidTimeoutTimer)); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called to override network address + * if NVRAM has a valid value + * + * @param prAdapter Pointer to the Adapter structure. + * + * @return WLAN_STATUS_FAILURE The request could not be processed + * WLAN_STATUS_PENDING The request has been queued for later + * processing + * WLAN_STATUS_SUCCESS The request has been processed + */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanUpdateNetworkAddress(IN struct ADAPTER + *prAdapter) +{ + const uint8_t aucZeroMacAddr[] = NULL_MAC_ADDR; + uint8_t rMacAddr[PARAM_MAC_ADDR_LEN]; + uint32_t u4SysTime; + + DEBUGFUNC("wlanUpdateNetworkAddress"); + + ASSERT(prAdapter); + + if (kalRetrieveNetworkAddress(prAdapter->prGlueInfo, rMacAddr) == FALSE + || IS_BMCAST_MAC_ADDR(rMacAddr) + || EQUAL_MAC_ADDR(aucZeroMacAddr, rMacAddr)) { + /* eFUSE has a valid address, don't do anything */ + if (prAdapter->fgIsEmbbededMacAddrValid == TRUE) { +#if CFG_SHOW_MACADDR_SOURCE + DBGLOG(INIT, INFO, "Using embedded MAC address"); +#endif + return WLAN_STATUS_SUCCESS; + } +#if CFG_SHOW_MACADDR_SOURCE + DBGLOG(INIT, INFO, + "Using dynamically generated MAC address"); +#endif + /* dynamic generate */ + u4SysTime = (uint32_t) kalGetTimeTick(); + + rMacAddr[0] = 0x00; + rMacAddr[1] = 0x08; + rMacAddr[2] = 0x22; + + kalMemCopy(&rMacAddr[3], &u4SysTime, 3); + + } else { +#if CFG_SHOW_MACADDR_SOURCE + DBGLOG(INIT, INFO, "Using host-supplied MAC address"); +#endif + } + +#if WLAN_INCLUDE_SYS + sysMacAddrOverride(rMacAddr); +#endif + + COPY_MAC_ADDR(prAdapter->rWifiVar.aucMacAddress, rMacAddr); + + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called to update basic configuration into firmware + * domain + * + * @param prAdapter Pointer to the Adapter structure. + * + * @return WLAN_STATUS_FAILURE The request could not be processed + * WLAN_STATUS_PENDING The request has been queued for later + * processing + * WLAN_STATUS_SUCCESS The request has been processed + */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanUpdateBasicConfig(IN struct ADAPTER *prAdapter) +{ + struct CMD_INFO *prCmdInfo; + struct CMD_BASIC_CONFIG *prCmdBasicConfig; + uint32_t rResult; + struct WIFI_VAR *prWifiVar = &prAdapter->rWifiVar; + struct mt66xx_chip_info *prChipInfo; + uint16_t cmd_size; + + DEBUGFUNC("wlanUpdateBasicConfig"); + + ASSERT(prAdapter); + prChipInfo = prAdapter->chip_info; + + cmd_size = prChipInfo->u2CmdTxHdrSize + sizeof(struct CMD_BASIC_CONFIG); + prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, cmd_size); + + if (!prCmdInfo) { + DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); + return WLAN_STATUS_FAILURE; + } + + /* compose CMD_BUILD_CONNECTION cmd pkt */ + prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; + prCmdInfo->u2InfoBufLen = cmd_size; + prCmdInfo->pfCmdDoneHandler = NULL; + prCmdInfo->pfCmdTimeoutHandler = NULL; + prCmdInfo->fgIsOid = FALSE; + prCmdInfo->ucCID = CMD_ID_BASIC_CONFIG; + prCmdInfo->fgSetQuery = TRUE; + prCmdInfo->fgNeedResp = FALSE; + prCmdInfo->u4SetInfoLen = sizeof(struct CMD_BASIC_CONFIG); + + /* Setup WIFI_CMD_T */ + NIC_FILL_CMD_TX_HDR(prAdapter, + prCmdInfo->pucInfoBuffer, + prCmdInfo->u2InfoBufLen, + prCmdInfo->ucCID, + CMD_PACKET_TYPE_ID, + &prCmdInfo->ucCmdSeqNum, + prCmdInfo->fgSetQuery, + &prCmdBasicConfig, FALSE, 0, S2D_INDEX_CMD_H2N); + + /* configure CMD_BASIC_CONFIG */ + kalMemZero(prCmdBasicConfig, + sizeof(struct CMD_BASIC_CONFIG)); + prCmdBasicConfig->ucNative80211 = 0; + prCmdBasicConfig->rCsumOffload.u2RxChecksum = 0; + prCmdBasicConfig->rCsumOffload.u2TxChecksum = 0; + prCmdBasicConfig->ucCtrlFlagAssertPath = + prWifiVar->ucCtrlFlagAssertPath; + prCmdBasicConfig->ucCtrlFlagDebugLevel = + prWifiVar->ucCtrlFlagDebugLevel; + +#if CFG_TCP_IP_CHKSUM_OFFLOAD + if (prAdapter->fgIsSupportCsumOffload) { + if (prAdapter->u4CSUMFlags & CSUM_OFFLOAD_EN_TX_TCP) + prCmdBasicConfig->rCsumOffload.u2TxChecksum |= BIT(2); + + if (prAdapter->u4CSUMFlags & CSUM_OFFLOAD_EN_TX_UDP) + prCmdBasicConfig->rCsumOffload.u2TxChecksum |= BIT(1); + + if (prAdapter->u4CSUMFlags & CSUM_OFFLOAD_EN_TX_IP) + prCmdBasicConfig->rCsumOffload.u2TxChecksum |= BIT(0); + + if (prAdapter->u4CSUMFlags & CSUM_OFFLOAD_EN_RX_TCP) + prCmdBasicConfig->rCsumOffload.u2RxChecksum |= BIT(2); + + if (prAdapter->u4CSUMFlags & CSUM_OFFLOAD_EN_RX_UDP) + prCmdBasicConfig->rCsumOffload.u2RxChecksum |= BIT(1); + + if (prAdapter->u4CSUMFlags & (CSUM_OFFLOAD_EN_RX_IPv4 | + CSUM_OFFLOAD_EN_RX_IPv6)) + prCmdBasicConfig->rCsumOffload.u2RxChecksum |= BIT(0); + } +#endif + + rResult = wlanSendCommand(prAdapter, prCmdInfo); + + if (rResult != WLAN_STATUS_SUCCESS) { + kalEnqueueCommand(prAdapter->prGlueInfo, + (struct QUE_ENTRY *) prCmdInfo); + + return WLAN_STATUS_PENDING; + } + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + + return WLAN_STATUS_SUCCESS; + +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called to check if the device is in RF test mode + * + * @param pfnOidHandler Pointer to the OID handler + * + * @return TRUE + * FALSE + */ +/*----------------------------------------------------------------------------*/ +u_int8_t wlanQueryTestMode(IN struct ADAPTER *prAdapter) +{ + ASSERT(prAdapter); + + return prAdapter->fgTestMode; +} + +u_int8_t wlanProcessTxFrame(IN struct ADAPTER *prAdapter, + IN void *prPacket) +{ + uint32_t u4SysTime; + uint8_t ucMacHeaderLen; + struct TX_PACKET_INFO rTxPacketInfo; + struct mt66xx_chip_info *prChipInfo; + + ASSERT(prAdapter); + ASSERT(prPacket); + prChipInfo = prAdapter->chip_info; + + if (kalQoSFrameClassifierAndPacketInfo( + prAdapter->prGlueInfo, prPacket, &rTxPacketInfo)) { + + /* Save the value of Priority Parameter */ + GLUE_SET_PKT_TID(prPacket, rTxPacketInfo.ucPriorityParam); + + if (rTxPacketInfo.u2Flag) { + if (rTxPacketInfo.u2Flag & BIT(ENUM_PKT_1X)) { + struct STA_RECORD *prStaRec; + + DBGLOG(RSN, INFO, "T1X len=%d\n", + rTxPacketInfo.u4PacketLen); + + prStaRec = cnmGetStaRecByAddress(prAdapter, + GLUE_GET_PKT_BSS_IDX(prPacket), + rTxPacketInfo.aucEthDestAddr); + + GLUE_SET_PKT_FLAG(prPacket, ENUM_PKT_1X); + /* + * if (secIsProtected1xFrame(prAdapter, + * prStaRec) && + * !kalIs24Of4Packet(prPacket)) + * GLUE_SET_PKT_FLAG(prPacket, + * ENUM_PKT_PROTECTED_1X); + */ + } + + if (rTxPacketInfo.u2Flag & + BIT(ENUM_PKT_NON_PROTECTED_1X)) + GLUE_SET_PKT_FLAG(prPacket, + ENUM_PKT_NON_PROTECTED_1X); + + if (rTxPacketInfo.u2Flag & BIT(ENUM_PKT_802_3)) + GLUE_SET_PKT_FLAG(prPacket, ENUM_PKT_802_3); + + if (rTxPacketInfo.u2Flag & BIT(ENUM_PKT_VLAN_EXIST) + && FEAT_SUP_LLC_VLAN_TX(prChipInfo)) + GLUE_SET_PKT_FLAG(prPacket, + ENUM_PKT_VLAN_EXIST); + + if (rTxPacketInfo.u2Flag & BIT(ENUM_PKT_DHCP)) + GLUE_SET_PKT_FLAG(prPacket, ENUM_PKT_DHCP); + + if (rTxPacketInfo.u2Flag & BIT(ENUM_PKT_ARP)) + GLUE_SET_PKT_FLAG(prPacket, ENUM_PKT_ARP); + + if (rTxPacketInfo.u2Flag & BIT(ENUM_PKT_ICMP)) + GLUE_SET_PKT_FLAG(prPacket, ENUM_PKT_ICMP); + + if (rTxPacketInfo.u2Flag & BIT(ENUM_PKT_TDLS)) + GLUE_SET_PKT_FLAG(prPacket, ENUM_PKT_TDLS); + + if (rTxPacketInfo.u2Flag & BIT(ENUM_PKT_DNS)) + GLUE_SET_PKT_FLAG(prPacket, ENUM_PKT_DNS); + + } + + ucMacHeaderLen = ETHER_HEADER_LEN; + + /* Save the value of Header Length */ + GLUE_SET_PKT_HEADER_LEN(prPacket, ucMacHeaderLen); + + /* Save the value of Frame Length */ + GLUE_SET_PKT_FRAME_LEN(prPacket, + (uint16_t) rTxPacketInfo.u4PacketLen); + + /* Save the value of Arrival Time */ + u4SysTime = (OS_SYSTIME) kalGetTimeTick(); + GLUE_SET_PKT_ARRIVAL_TIME(prPacket, u4SysTime); + + return TRUE; + } + + return FALSE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called to identify 802.1x and Bluetooth-over-Wi-Fi + * security frames, and queued into command queue for strict ordering + * due to 802.1x frames before add-key OIDs are not to be encrypted + * + * @param prAdapter Pointer of Adapter Data Structure + * @param prPacket Pointer of native packet + * + * @return TRUE + * FALSE + */ +/*----------------------------------------------------------------------------*/ +u_int8_t wlanProcessSecurityFrame(IN struct ADAPTER + *prAdapter, IN void *prPacket) +{ + struct CMD_INFO *prCmdInfo; + struct STA_RECORD *prStaRec; + uint8_t ucBssIndex; + uint32_t u4PacketLen; + uint8_t aucEthDestAddr[PARAM_MAC_ADDR_LEN]; + struct MSDU_INFO *prMsduInfo; + uint8_t ucStaRecIndex; + + ASSERT(prAdapter); + ASSERT(prPacket); + + prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, 0); + + /* Get MSDU_INFO for TxDone */ + prMsduInfo = cnmPktAlloc(prAdapter, 0); + + u4PacketLen = (uint32_t) GLUE_GET_PKT_FRAME_LEN(prPacket); + + if (prCmdInfo && prMsduInfo) { + ucBssIndex = GLUE_GET_PKT_BSS_IDX(prPacket); + + kalGetEthDestAddr(prAdapter->prGlueInfo, prPacket, + aucEthDestAddr); + + prStaRec = cnmGetStaRecByAddress(prAdapter, ucBssIndex, + aucEthDestAddr); + + prCmdInfo->eCmdType = COMMAND_TYPE_SECURITY_FRAME; + prCmdInfo->u2InfoBufLen = (uint16_t) u4PacketLen; + prCmdInfo->prPacket = prPacket; + prCmdInfo->prMsduInfo = prMsduInfo; + prCmdInfo->pfCmdDoneHandler = wlanSecurityFrameTxDone; + prCmdInfo->pfCmdTimeoutHandler = + wlanSecurityAndCmdDataFrameTxTimeout; + prCmdInfo->fgIsOid = FALSE; + prCmdInfo->fgSetQuery = TRUE; + prCmdInfo->fgNeedResp = FALSE; + + if (prStaRec) + ucStaRecIndex = prStaRec->ucIndex; + else + ucStaRecIndex = STA_REC_INDEX_NOT_FOUND; + + /* Fill-up MSDU_INFO */ + nicTxSetDataPacket(prAdapter, prMsduInfo, ucBssIndex, + ucStaRecIndex, 0, u4PacketLen, + nicTxDummyTxDone, MSDU_RATE_MODE_AUTO, + TX_PACKET_OS, 0, FALSE, TRUE); + + prMsduInfo->prPacket = prPacket; + /* No Tx descriptor template for MMPDU */ + prMsduInfo->fgIsTXDTemplateValid = FALSE; + + if (GLUE_TEST_PKT_FLAG(prPacket, ENUM_PKT_PROTECTED_1X)) + nicTxConfigPktOption(prMsduInfo, + MSDU_OPT_PROTECTED_FRAME, TRUE); +#if CFG_SUPPORT_MULTITHREAD + nicTxComposeSecurityFrameDesc(prAdapter, prCmdInfo, + prMsduInfo->aucTxDescBuffer, NULL); +#endif + + kalEnqueueCommand(prAdapter->prGlueInfo, + (struct QUE_ENTRY *) prCmdInfo); + + GLUE_SET_EVENT(prAdapter->prGlueInfo); + + return TRUE; + } + DBGLOG(RSN, INFO, + "Failed to alloc CMD/MGMT INFO for 1X frame!!\n"); + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + cnmPktFree(prAdapter, prMsduInfo); + + + return FALSE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called to send data frame via firmware and queued + * into command queue + * + * @param prAdapter Pointer of Adapter Data Structure + * @param prPacket Pointer of native packet + * + * @return TRUE + * FALSE + */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanProcessCmdDataFrame(IN struct ADAPTER + *prAdapter, IN void *prPacket) +{ + struct CMD_INFO *prCmdInfo; + struct MSDU_INFO *prMsduInfo; + + ASSERT(prAdapter); + ASSERT(prPacket); + + /* Allocate command buffer */ + prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, 0); + if (!prCmdInfo) { + DBGLOG_LIMITED(TX, INFO, + "Failed to alloc CMD buffer for data frame!!\n"); + return WLAN_STATUS_RESOURCES; + } + + /* Get MSDU_INFO buffer */ + prMsduInfo = cnmPktAlloc(prAdapter, 0); + if (!prMsduInfo) { + DBGLOG_LIMITED(TX, INFO, + "Failed to alloc MSDU Info for data frame!!\n"); + + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + return WLAN_STATUS_RESOURCES; + } + + /* Fill-up MSDU_INFO and TxD*/ + if (!nicTxFillMsduInfo(prAdapter, prMsduInfo, prPacket) || + !nicTxProcessCmdDataPacket(prAdapter, prMsduInfo)) { + + kalSendComplete(prAdapter->prGlueInfo, prPacket, + WLAN_STATUS_INVALID_PACKET); + + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + cnmPktFree(prAdapter, prMsduInfo); + + return WLAN_STATUS_INVALID_PACKET; + } + + /* Prepare command and enqueue */ + prCmdInfo->eCmdType = COMMAND_TYPE_DATA_FRAME; + prCmdInfo->u2InfoBufLen = prMsduInfo->u2FrameLength; + prCmdInfo->pucInfoBuffer = NULL; + prCmdInfo->prPacket = prMsduInfo->prPacket; + prCmdInfo->prMsduInfo = prMsduInfo; + prCmdInfo->pfCmdDoneHandler = wlanCmdDataFrameTxDone; + prCmdInfo->pfCmdTimeoutHandler = wlanSecurityAndCmdDataFrameTxTimeout; + prCmdInfo->fgIsOid = FALSE; + prCmdInfo->fgSetQuery = TRUE; + prCmdInfo->fgNeedResp = FALSE; + prCmdInfo->ucCmdSeqNum = prMsduInfo->ucTxSeqNum; + + DBGLOG(TX, INFO, + "DPP EN-Q MSDU[0x%p] SEQ[%u] BSS[%u] STA[%u] Len[%u]to CMD Q\n", + prMsduInfo, + prMsduInfo->ucTxSeqNum, + prMsduInfo->ucBssIndex, + prMsduInfo->ucStaRecIndex, + prMsduInfo->u2FrameLength); + + kalEnqueueCommand(prAdapter->prGlueInfo, + (struct QUE_ENTRY *) prCmdInfo); + + GLUE_SET_EVENT(prAdapter->prGlueInfo); + + return WLAN_STATUS_SUCCESS; +} + + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called when 802.1x or Bluetooth-over-Wi-Fi + * security frames has been sent to firmware + * + * @param prAdapter Pointer of Adapter Data Structure + * @param prCmdInfo Pointer of CMD_INFO_T + * @param pucEventBuf meaningless, only for API compatibility + * + * @return none + */ +/*----------------------------------------------------------------------------*/ +void wlanSecurityFrameTxDone(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, + IN uint8_t *pucEventBuf) +{ + struct MSDU_INFO *prMsduInfo = prCmdInfo->prMsduInfo; + + ASSERT(prAdapter); + ASSERT(prCmdInfo); + + if (GET_BSS_INFO_BY_INDEX(prAdapter, + prMsduInfo->ucBssIndex)->eNetworkType == + NETWORK_TYPE_AIS + && + aisGetAisSpecBssInfo(prAdapter, + prMsduInfo->ucBssIndex)->fgCounterMeasure) { + struct STA_RECORD *prSta = cnmGetStaRecByIndex(prAdapter, + prMsduInfo->ucBssIndex); + + if (prSta) { + kalMsleep(10); + if (authSendDeauthFrame(prAdapter, + GET_BSS_INFO_BY_INDEX(prAdapter, + prMsduInfo->ucBssIndex), prSta, + (struct SW_RFB *) NULL, + REASON_CODE_MIC_FAILURE, + (PFN_TX_DONE_HANDLER) NULL + /* secFsmEventDeauthTxDone left upper + * layer handle the 60 timer + */ + ) != WLAN_STATUS_SUCCESS) { + ASSERT(FALSE); + } + /* secFsmEventEapolTxDone(prAdapter, prSta, + * TX_RESULT_SUCCESS); + */ + } + } + + kalSecurityFrameSendComplete(prAdapter->prGlueInfo, + prCmdInfo->prPacket, WLAN_STATUS_SUCCESS); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called when command data frame has been + * sent to firmware + * + * @param prAdapter Pointer of Adapter Data Structure + * @param prCmdInfo Pointer of CMD_INFO_T + * @param pucEventBuf meaningless, only for API compatibility + * + * @return none + */ +/*----------------------------------------------------------------------------*/ +void wlanCmdDataFrameTxDone(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, + IN uint8_t *pucEventBuf) +{ + + ASSERT(prAdapter); + ASSERT(prCmdInfo); + + kalSecurityFrameSendComplete(prAdapter->prGlueInfo, + prCmdInfo->prPacket, WLAN_STATUS_SUCCESS); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called when 802.1x or Bluetooth-over-Wi-Fi + * security frames has failed sending to firmware + * + * @param prAdapter Pointer of Adapter Data Structure + * @param prCmdInfo Pointer of CMD_INFO_T + * + * @return none + */ +/*----------------------------------------------------------------------------*/ +void wlanSecurityAndCmdDataFrameTxTimeout(IN struct ADAPTER + *prAdapter, IN struct CMD_INFO *prCmdInfo) +{ + ASSERT(prAdapter); + ASSERT(prCmdInfo); + + kalSecurityFrameSendComplete(prAdapter->prGlueInfo, + prCmdInfo->prPacket, WLAN_STATUS_FAILURE); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called before AIS is starting a new scan + * + * @param prAdapter Pointer of Adapter Data Structure + * + * @return none + */ +/*----------------------------------------------------------------------------*/ +void wlanClearScanningResult(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) +{ + u_int8_t fgKeepCurrOne = FALSE; + uint32_t i; + struct WLAN_INFO *prWlanInfo; + struct PARAM_BSSID_EX *prCurrBssid; + + ASSERT(prAdapter); + prWlanInfo = &(prAdapter->rWlanInfo); + + prCurrBssid = aisGetCurrBssId(prAdapter, + ucBssIndex); + + /* clear scanning result */ + if (kalGetMediaStateIndicated(prAdapter->prGlueInfo, + ucBssIndex) == + MEDIA_STATE_CONNECTED) { + + for (i = 0; i < prWlanInfo->u4ScanResultNum; i++) { + + if (EQUAL_MAC_ADDR( + prCurrBssid->arMacAddress, + prWlanInfo->arScanResult[i].arMacAddress)) { + fgKeepCurrOne = TRUE; + + if (i != 0) { + /* copy structure */ + kalMemCopy( + &(prWlanInfo->arScanResult[0]), + &(prWlanInfo->arScanResult[i]), + OFFSET_OF(struct PARAM_BSSID_EX, + aucIEs)); + } + + if (prWlanInfo->arScanResult[i].u4IELength > 0) { + if (prWlanInfo->apucScanResultIEs[i] != + &(prWlanInfo->aucScanIEBuf[0])) { + + /* move IEs to head */ + kalMemCopy(prWlanInfo->aucScanIEBuf, + prWlanInfo->apucScanResultIEs[i], + prWlanInfo->arScanResult[i] + .u4IELength); + } + + /* modify IE pointer */ + prWlanInfo->apucScanResultIEs[0] = + &(prWlanInfo->aucScanIEBuf[0]); + + } else { + prWlanInfo->apucScanResultIEs[0] = NULL; + } + + break; + } /* if */ + } /* for */ + } + + if (fgKeepCurrOne == TRUE) { + prWlanInfo->u4ScanResultNum = 1; + prWlanInfo->u4ScanIEBufferUsage = + ALIGN_4(prWlanInfo->arScanResult[0].u4IELength); + } else { + prWlanInfo->u4ScanResultNum = 0; + prWlanInfo->u4ScanIEBufferUsage = 0; + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called when AIS received a beacon timeout event + * + * @param prAdapter Pointer of Adapter Data Structure + * @param arBSSID MAC address of the specified BSS + * + * @return none + */ +/*----------------------------------------------------------------------------*/ +void wlanClearBssInScanningResult(IN struct ADAPTER + *prAdapter, IN uint8_t *arBSSID) +{ + uint32_t i, j, u4IELength = 0, u4IEMoveLength; + uint8_t *pucIEPtr; + struct WLAN_INFO *prWlanInfo; + + ASSERT(prAdapter); + prWlanInfo = &(prAdapter->rWlanInfo); + + /* clear scanning result */ + i = 0; + while (1) { + if (i >= prWlanInfo->u4ScanResultNum) + break; + + if (EQUAL_MAC_ADDR(arBSSID, + prWlanInfo->arScanResult[i].arMacAddress)) { + /* backup current IE length */ + u4IELength = + ALIGN_4(prWlanInfo->arScanResult[i].u4IELength); + pucIEPtr = prWlanInfo->apucScanResultIEs[i]; + + /* removed from middle */ + for (j = i + 1; j < prWlanInfo->u4ScanResultNum; j++) { + kalMemCopy(&(prWlanInfo->arScanResult[j - 1]), + &(prWlanInfo->arScanResult[j]), + OFFSET_OF(struct PARAM_BSSID_EX, + aucIEs)); + + prWlanInfo->apucScanResultIEs[j - 1] = + prWlanInfo->apucScanResultIEs[j]; + } + + prWlanInfo->u4ScanResultNum--; + + /* remove IE buffer if needed := move rest of IE buffer + */ + if (u4IELength > 0) { + u4IEMoveLength = prWlanInfo->u4ScanIEBufferUsage + - (((unsigned long) pucIEPtr) + + u4IELength + - ((unsigned long) + (&(prWlanInfo->aucScanIEBuf[0])))); + + kalMemCopy(pucIEPtr, + (uint8_t *) (((unsigned long) + pucIEPtr) + u4IELength), + u4IEMoveLength); + + prWlanInfo->u4ScanIEBufferUsage -= + u4IELength; + + /* correction of pointers to IE buffer */ + for (j = 0; j < prWlanInfo->u4ScanResultNum; + j++) { + if (prWlanInfo->apucScanResultIEs[j] > + pucIEPtr) { + prWlanInfo->apucScanResultIEs[j] = + (uint8_t *)((unsigned long) + (prWlanInfo->apucScanResultIEs[j]) - + u4IELength); + } + } + } + } + + i++; + } +} + +#if CFG_TEST_WIFI_DIRECT_GO +void wlanEnableP2pFunction(IN struct ADAPTER *prAdapter) +{ +#if 0 + P_MSG_P2P_FUNCTION_SWITCH_T prMsgFuncSwitch = + (P_MSG_P2P_FUNCTION_SWITCH_T) NULL; + + prMsgFuncSwitch = + (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(prAdapter, + RAM_TYPE_MSG, sizeof(MSG_P2P_FUNCTION_SWITCH_T)); + if (!prMsgFuncSwitch) { + ASSERT(FALSE); + return; + } + + prMsgFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH; + prMsgFuncSwitch->fgIsFuncOn = TRUE; + + mboxSendMsg(prAdapter, MBOX_ID_0, + (struct MSG_HDR *) prMsgFuncSwitch, MSG_SEND_METHOD_BUF); +#endif + +} + +void wlanEnableATGO(IN struct ADAPTER *prAdapter) +{ + + struct MSG_P2P_CONNECTION_REQUEST *prMsgConnReq = + (struct MSG_P2P_CONNECTION_REQUEST *) NULL; + uint8_t aucTargetDeviceID[MAC_ADDR_LEN] = { 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF }; + + prMsgConnReq = + (struct MSG_P2P_CONNECTION_REQUEST *) cnmMemAlloc(prAdapter, + RAM_TYPE_MSG, sizeof(struct MSG_P2P_CONNECTION_REQUEST)); + if (!prMsgConnReq) { + ASSERT(FALSE); + return; + } + + prMsgConnReq->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_REQ; + + /*=====Param Modified for test=====*/ + COPY_MAC_ADDR(prMsgConnReq->aucDeviceID, aucTargetDeviceID); + prMsgConnReq->fgIsTobeGO = TRUE; + prMsgConnReq->fgIsPersistentGroup = FALSE; + + /*=====Param Modified for test=====*/ + + mboxSendMsg(prAdapter, MBOX_ID_0, + (struct MSG_HDR *) prMsgConnReq, MSG_SEND_METHOD_BUF); + +} +#endif + +void wlanPrintVersion(IN struct ADAPTER *prAdapter) +{ + uint8_t aucBuf[512]; + + kalMemZero(aucBuf, 512); + +#if CFG_ENABLE_FW_DOWNLOAD + fwDlGetFwdlInfo(prAdapter, aucBuf, 512); +#endif + DBGLOG(SW4, INFO, "%s", aucBuf); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called to retrieve NIC capability from firmware + * + * @param prAdapter Pointer of Adapter Data Structure + * + * @return WLAN_STATUS_SUCCESS + * WLAN_STATUS_FAILURE + */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanQueryNicCapability(IN struct ADAPTER + *prAdapter) +{ + struct mt66xx_chip_info *prChipInfo; + uint8_t aucZeroMacAddr[] = NULL_MAC_ADDR; + struct CMD_INFO *prCmdInfo; + uint32_t u4RxPktLength; + uint8_t *aucBuffer; + uint32_t u4EventSize; + struct WIFI_EVENT *prEvent; + struct EVENT_NIC_CAPABILITY *prEventNicCapability; + uint16_t cmd_size; + + ASSERT(prAdapter); + prChipInfo = prAdapter->chip_info; + + DEBUGFUNC("wlanQueryNicCapability"); + + /* 1. Allocate CMD Info Packet and its Buffer */ + cmd_size = prChipInfo->u2CmdTxHdrSize + + sizeof(struct EVENT_NIC_CAPABILITY); + prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, cmd_size); + if (!prCmdInfo) { + DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); + return WLAN_STATUS_FAILURE; + } + + u4EventSize = prChipInfo->rxd_size + prChipInfo->event_hdr_size + + sizeof(struct EVENT_NIC_CAPABILITY); + aucBuffer = kalMemAlloc(u4EventSize, PHY_MEM_TYPE); + if (!aucBuffer) { + DBGLOG(INIT, ERROR, "Not enough memory for aucBuffer\n"); + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + return WLAN_STATUS_FAILURE; + } + + /* compose CMD_BUILD_CONNECTION cmd pkt */ + prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; + prCmdInfo->u2InfoBufLen = cmd_size; + prCmdInfo->pfCmdDoneHandler = NULL; + prCmdInfo->fgIsOid = FALSE; + prCmdInfo->ucCID = CMD_ID_GET_NIC_CAPABILITY; + prCmdInfo->fgSetQuery = FALSE; + prCmdInfo->fgNeedResp = TRUE; + prCmdInfo->u4SetInfoLen = 0; + + /* Setup WIFI_CMD_T */ + NIC_FILL_CMD_TX_HDR(prAdapter, + prCmdInfo->pucInfoBuffer, + prCmdInfo->u2InfoBufLen, + prCmdInfo->ucCID, + CMD_PACKET_TYPE_ID, + &prCmdInfo->ucCmdSeqNum, + prCmdInfo->fgSetQuery, + NULL, FALSE, 0, S2D_INDEX_CMD_H2N); + + wlanSendCommand(prAdapter, prCmdInfo); + + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + + while (TRUE) { + if (nicRxWaitResponse(prAdapter, 1, aucBuffer, u4EventSize, + &u4RxPktLength) != WLAN_STATUS_SUCCESS) { + + DBGLOG(INIT, WARN, "%s: wait for event failed!\n", + __func__); + kalMemFree(aucBuffer, PHY_MEM_TYPE, u4EventSize); + return WLAN_STATUS_FAILURE; + } + /* header checking .. */ + if (NIC_RX_GET_U2_SW_PKT_TYPE(aucBuffer) + != prChipInfo->u2RxSwPktEvent) { + DBGLOG(INIT, WARN, + "%s: skip unexpected Rx pkt type[0x%04x]\n", + __func__, NIC_RX_GET_U2_SW_PKT_TYPE(aucBuffer)); + continue; + } + + prEvent = (struct WIFI_EVENT *) + (aucBuffer + prChipInfo->rxd_size); + prEventNicCapability = + (struct EVENT_NIC_CAPABILITY *)prEvent->aucBuffer; + + if (prEvent->ucEID != EVENT_ID_NIC_CAPABILITY) { + DBGLOG(INIT, WARN, + "%s: skip unexpected event ID[0x%02x]\n", + __func__, prEvent->ucEID); + continue; + } else { + break; + } + } + + prEventNicCapability = (struct EVENT_NIC_CAPABILITY *) ( + prEvent->aucBuffer); + + prAdapter->rVerInfo.u2FwProductID = + prEventNicCapability->u2ProductID; + kalMemCopy(prAdapter->rVerInfo.aucFwBranchInfo, + prEventNicCapability->aucBranchInfo, 4); + prAdapter->rVerInfo.u2FwOwnVersion = + prEventNicCapability->u2FwVersion; + prAdapter->rVerInfo.ucFwBuildNumber = + prEventNicCapability->ucFwBuildNumber; + kalMemCopy(prAdapter->rVerInfo.aucFwDateCode, + prEventNicCapability->aucDateCode, 16); + prAdapter->rVerInfo.u2FwPeerVersion = + prEventNicCapability->u2DriverVersion; + prAdapter->fgIsHw5GBandDisabled = + (u_int8_t)prEventNicCapability->ucHw5GBandDisabled; + prAdapter->fgIsEepromUsed = + (u_int8_t)prEventNicCapability->ucEepromUsed; + prAdapter->fgIsEmbbededMacAddrValid = + (u_int8_t)(!IS_BMCAST_MAC_ADDR( + prEventNicCapability->aucMacAddr) && + !EQUAL_MAC_ADDR(aucZeroMacAddr, + prEventNicCapability->aucMacAddr)); + + COPY_MAC_ADDR(prAdapter->rWifiVar.aucPermanentAddress, + prEventNicCapability->aucMacAddr); + COPY_MAC_ADDR(prAdapter->rWifiVar.aucMacAddress, + prEventNicCapability->aucMacAddr); + + prAdapter->rWifiVar.ucStaVht &= + (!(prEventNicCapability->ucHwNotSupportAC)); + prAdapter->rWifiVar.ucApVht &= + (!(prEventNicCapability->ucHwNotSupportAC)); + prAdapter->rWifiVar.ucP2pGoVht &= + (!(prEventNicCapability->ucHwNotSupportAC)); + prAdapter->rWifiVar.ucP2pGcVht &= + (!(prEventNicCapability->ucHwNotSupportAC)); + prAdapter->rWifiVar.ucHwNotSupportAC = + prEventNicCapability->ucHwNotSupportAC; + + prAdapter->u4FwCompileFlag0 = + prEventNicCapability->u4CompileFlag0; + prAdapter->u4FwCompileFlag1 = + prEventNicCapability->u4CompileFlag1; + prAdapter->u4FwFeatureFlag0 = + prEventNicCapability->u4FeatureFlag0; + prAdapter->u4FwFeatureFlag1 = + prEventNicCapability->u4FeatureFlag1; + + if (prEventNicCapability->ucHwSetNss1x1) + prAdapter->rWifiVar.ucNSS = 1; + +#if CFG_SUPPORT_DBDC + if (prEventNicCapability->ucHwNotSupportDBDC) + prAdapter->rWifiVar.eDbdcMode = ENUM_DBDC_MODE_DISABLED; +#endif + if (prEventNicCapability->ucHwBssIdNum > 0 + && prEventNicCapability->ucHwBssIdNum <= MAX_BSSID_NUM) { + prAdapter->ucHwBssIdNum = + prEventNicCapability->ucHwBssIdNum; + prAdapter->ucP2PDevBssIdx = prAdapter->ucHwBssIdNum; + /* v1 event does not report WmmSetNum, + * Assume it is the same as HwBssNum + */ + prAdapter->ucWmmSetNum = + prEventNicCapability->ucHwBssIdNum; + prAdapter->aprBssInfo[prAdapter->ucP2PDevBssIdx] = + &prAdapter->rWifiVar.rP2pDevInfo; + } + +#if CFG_ENABLE_CAL_LOG + DBGLOG(INIT, TRACE, + "RF CAL FAIL = (%d),BB CAL FAIL = (%d)\n", + prEventNicCapability->ucRfCalFail, + prEventNicCapability->ucBbCalFail); +#endif + kalMemFree(aucBuffer, PHY_MEM_TYPE, u4EventSize); + + return WLAN_STATUS_SUCCESS; +} + +#if TXPWR_USE_PDSLOPE + +/*----------------------------------------------------------------------------*/ +/*! + * @brief + * + * @param prAdapter Pointer of Adapter Data Structure + * + * @return WLAN_STATUS_SUCCESS + * WLAN_STATUS_FAILURE + */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanQueryPdMcr(IN struct ADAPTER *prAdapter, + struct PARAM_MCR_RW_STRUCT *prMcrRdInfo) +{ + struct mt66xx_chip_info *prChipInfo; + struct CMD_INFO *prCmdInfo; + uint32_t u4RxPktLength; + uint8_t *aucBuffer; + uint32_t u4EventSize; + struct WIFI_EVENT *prEvent; + struct CMD_ACCESS_REG *prCmdMcrQuery; + uint16_t u2PacketType; + uint16_t cmd_size; + + ASSERT(prAdapter); + prChipInfo = prAdapter->chip_info; + + /* 1. Allocate CMD Info Packet and its Buffer */ + cmd_size = prChipInfo->u2CmdTxHdrSize + sizeof(struct CMD_ACCESS_REG); + prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, cmd_size); + + if (!prCmdInfo) { + DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); + return WLAN_STATUS_FAILURE; + } + + u4EventSize = prChipInfo->rxd_size + prChipInfo->event_hdr_size + + struct CMD_ACCESS_REG; + aucBuffer = kalMemAlloc(u4EventSize, PHY_MEM_TYPE); + + /* compose CMD_BUILD_CONNECTION cmd pkt */ + prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; + prCmdInfo->u2InfoBufLen = cmd_size; + prCmdInfo->pfCmdDoneHandler = NULL; + prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; + prCmdInfo->fgIsOid = FALSE; + prCmdInfo->ucCID = CMD_ID_ACCESS_REG; + prCmdInfo->fgSetQuery = FALSE; + prCmdInfo->fgNeedResp = TRUE; + prCmdInfo->u4SetInfoLen = sizeof(struct CMD_ACCESS_REG); + + /* Setup WIFI_CMD_T */ + NIC_FILL_CMD_TX_HDR( + prAdapter, + prCmdInfo->pucInfoBuffer, + prCmdInfo->u2InfoBufLen, + prCmdInfo->ucCID, + CMD_PACKET_TYPE_ID, + &prCmdInfo->ucCmdSeqNum, + prCmdInfo->fgSetQuery, + &prCmdMcrQuery, FALSE, 0, S2D_INDEX_CMD_H2N); + kalMemCopy(prCmdMcrQuery, prMcrRdInfo, + sizeof(struct CMD_ACCESS_REG)); + + wlanSendCommand(prAdapter, prCmdInfo); + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + + if (nicRxWaitResponse(prAdapter, 1, aucBuffer, u4EventSize, + &u4RxPktLength) != WLAN_STATUS_SUCCESS) { + kalMemFree(aucBuffer, PHY_MEM_TYPE, u4EventSize); + return WLAN_STATUS_FAILURE; + } + /* header checking .. */ + u2PacketType = NIC_RX_GET_PKT_TYPE(aucBuffer); + if (u2PacketType != RX_PKT_TYPE_SW_DEFINED) { + kalMemFree(aucBuffer, PHY_MEM_TYPE, u4EventSize); + return WLAN_STATUS_FAILURE; + } + + prEvent = (struct WIFI_EVENT *) + (aucBuffer + prChipInfo->rxd_size); + if (prEvent->ucEID != EVENT_ID_ACCESS_REG) { + kalMemFree(aucBuffer, PHY_MEM_TYPE, u4EventSize); + return WLAN_STATUS_FAILURE; + } + + prCmdMcrQuery = (struct CMD_ACCESS_REG *) ( + prEvent->aucBuffer); + prMcrRdInfo->u4McrOffset = prCmdMcrQuery->u4Address; + prMcrRdInfo->u4McrData = prCmdMcrQuery->u4Data; + + kalMemFree(aucBuffer, PHY_MEM_TYPE, u4EventSize); + + return WLAN_STATUS_SUCCESS; +} + +static int32_t wlanIntRound(int32_t au4Input) +{ + + if (au4Input >= 0) { + if ((au4Input % 10) == 5) { + au4Input = au4Input + 5; + return au4Input; + } + } + + if (au4Input < 0) { + if ((au4Input % 10) == -5) { + au4Input = au4Input - 5; + return au4Input; + } + } + + return au4Input; +} + +static int32_t wlanCal6628EfuseForm(IN struct ADAPTER + *prAdapter, int32_t au4Input) +{ + + struct PARAM_MCR_RW_STRUCT rMcrRdInfo; + int32_t au4PdSlope, au4TxPwrOffset, au4TxPwrOffset_Round; + int8_t auTxPwrOffset_Round; + + rMcrRdInfo.u4McrOffset = 0x60205c68; + rMcrRdInfo.u4McrData = 0; + au4TxPwrOffset = au4Input; + wlanQueryPdMcr(prAdapter, &rMcrRdInfo); + + au4PdSlope = (rMcrRdInfo.u4McrData) & BITS(0, 6); + au4TxPwrOffset_Round = wlanIntRound((au4TxPwrOffset * + au4PdSlope)) / 10; + + au4TxPwrOffset_Round = -au4TxPwrOffset_Round; + + if (au4TxPwrOffset_Round < -128) + au4TxPwrOffset_Round = 128; + else if (au4TxPwrOffset_Round < 0) + au4TxPwrOffset_Round += 256; + else if (au4TxPwrOffset_Round > 127) + au4TxPwrOffset_Round = 127; + + auTxPwrOffset_Round = (uint8_t) au4TxPwrOffset_Round; + + return au4TxPwrOffset_Round; +} + +#endif + +#define NVRAM_OFS(elment) OFFSET_OF(struct WIFI_CFG_PARAM_STRUCT, elment) + +uint32_t wlanGetMiniTxPower(IN struct ADAPTER *prAdapter, + IN enum ENUM_BAND eBand, + IN enum ENUM_PHY_MODE_TYPE ePhyMode, + OUT int8_t *pTxPwr) +{ +#ifdef SOC3_0 + struct REG_INFO *prRegInfo; + struct WIFI_CFG_PARAM_STRUCT *prNvramSettings; + uint8_t *pu1Addr; + int8_t bandIdx = 0; + + int8_t minTxPwr = 0x7F; + int8_t nvTxPwr = 0; + uint32_t rateIdx = 0; + uint32_t startOfs = 0; + uint32_t endOfs = 0; + + struct NVRAM_FRAGMENT_RANGE arRange[2][PHY_MODE_TYPE_NUM] = { + /*BAND2G4*/ + { + /*CCK*/ + {NVRAM_OFS(r2G4Pwr.uc2G4TxPwrCck1M), + NVRAM_OFS(r2G4Pwr.uc2G4TxPwrCck11M)}, + /*OFDM*/ + {NVRAM_OFS(r2G4Pwr.uc2G4TxPwrOfdm6M), + NVRAM_OFS(r2G4Pwr.uc2G4TxPwrOfdm54M)}, + /*HT20*/ + {NVRAM_OFS(r2G4Pwr.uc2G4TxPwrHt20Mcs0), + NVRAM_OFS(r2G4Pwr.uc2G4TxPwrHt20Mcs7)}, + /*HT40*/ + {NVRAM_OFS(r2G4Pwr.uc2G4TxPwrHt40Mcs0), + NVRAM_OFS(r2G4Pwr.uc2G4TxPwrHt40Mcs32)}, + /*VHT20*/ + {NVRAM_OFS(r2G4Pwr.uc2G4TxPwrVht20Mcs0), + NVRAM_OFS(r2G4Pwr.uc2G4TxPwrVht20Mcs9)}, + /*VHT40*/ + {NVRAM_OFS(r2G4Pwr.uc2G4TxPwrVht40Mcs0), + NVRAM_OFS(r2G4Pwr.uc2G4TxPwrVht40Mcs9)}, + /*VHT80*/ + {0, 0}, + /*SU20*/ + {NVRAM_OFS(r2G4Pwr.uc2G4TxPwrRU242Mcs0), + NVRAM_OFS(r2G4Pwr.uc2G4TxPwrRU242Mcs11)}, + /*SU40*/ + {NVRAM_OFS(r2G4Pwr.uc2G4TxPwrRU484Mcs0), + NVRAM_OFS(r2G4Pwr.uc2G4TxPwrRU484Mcs11)}, + /*SU80*/ + {0, 0}, + /*RU26*/ + {NVRAM_OFS(r2G4Pwr.uc2G4TxPwrRU26Mcs0), + NVRAM_OFS(r2G4Pwr.uc2G4TxPwrRU26Mcs11)}, + /*RU52*/ + {NVRAM_OFS(r2G4Pwr.uc2G4TxPwrRU52Mcs0), + NVRAM_OFS(r2G4Pwr.uc2G4TxPwrRU52Mcs11)}, + /*RU106*/ + {NVRAM_OFS(r2G4Pwr.uc2G4TxPwrRU106Mcs0), + NVRAM_OFS(r2G4Pwr.uc2G4TxPwrRU106Mcs11)}, + /*RU242*/ + {NVRAM_OFS(r2G4Pwr.uc2G4TxPwrRU242Mcs0), + NVRAM_OFS(r2G4Pwr.uc2G4TxPwrRU242Mcs11)}, + /*RU484*/ + {NVRAM_OFS(r2G4Pwr.uc2G4TxPwrRU484Mcs0), + NVRAM_OFS(r2G4Pwr.uc2G4TxPwrRU484Mcs11)}, + /*RU996*/ + {0, 0}, + }, + /*BAND5G*/ + { + /*CCK*/ + {0, 0}, + /*OFDM*/ + {NVRAM_OFS(r5GPwr.uc5GTxPwrOfdm6M), + NVRAM_OFS(r5GPwr.uc5GTxPwrOfdm54M)}, + /*HT20*/ + {NVRAM_OFS(r5GPwr.uc5GTxPwrHt20Mcs0), + NVRAM_OFS(r5GPwr.uc5GTxPwrHt20Mcs7)}, + /*HT40*/ + {NVRAM_OFS(r5GPwr.uc5GTxPwrHt40Mcs0), + NVRAM_OFS(r5GPwr.uc5GTxPwrHt40Mcs32)}, + /*VHT20*/ + {NVRAM_OFS(r5GPwr.uc5GTxPwrVht20Mcs0), + NVRAM_OFS(r5GPwr.uc5GTxPwrVht20Mcs9)}, + /*VHT40*/ + {NVRAM_OFS(r5GPwr.uc5GTxPwrVht40Mcs0), + NVRAM_OFS(r5GPwr.uc5GTxPwrVht40Mcs9)}, + /*VHT80*/ + {NVRAM_OFS(r5GPwr.uc5GTxPwrVht80Mcs0), + NVRAM_OFS(r5GPwr.uc5GTxPwrVht80Mcs9)}, + /*SU20*/ + {NVRAM_OFS(r5GPwr.uc5GTxPwrRU242Mcs0), + NVRAM_OFS(r5GPwr.uc5GTxPwrRU242Mcs11)}, + /*SU40*/ + {NVRAM_OFS(r5GPwr.uc5GTxPwrRU484Mcs0), + NVRAM_OFS(r5GPwr.uc5GTxPwrRU484Mcs11)}, + /*SU80*/ + {NVRAM_OFS(r5GPwr.uc5GTxPwrRU996Mcs0), + NVRAM_OFS(r5GPwr.uc5GTxPwrRU996Mcs11)}, + /*RU26*/ + {NVRAM_OFS(r5GPwr.uc5GTxPwrRU26Mcs0), + NVRAM_OFS(r5GPwr.uc5GTxPwrRU26Mcs11)}, + /*RU52*/ + {NVRAM_OFS(r5GPwr.uc5GTxPwrRU52Mcs0), + NVRAM_OFS(r5GPwr.uc5GTxPwrRU52Mcs11)}, + /*RU106*/ + {NVRAM_OFS(r5GPwr.uc5GTxPwrRU106Mcs0), + NVRAM_OFS(r5GPwr.uc5GTxPwrRU106Mcs11)}, + /*RU242*/ + {NVRAM_OFS(r5GPwr.uc5GTxPwrRU242Mcs0), + NVRAM_OFS(r5GPwr.uc5GTxPwrRU242Mcs11)}, + /*RU484*/ + {NVRAM_OFS(r5GPwr.uc5GTxPwrRU484Mcs0), + NVRAM_OFS(r5GPwr.uc5GTxPwrRU484Mcs11)}, + /*RU996*/ + {NVRAM_OFS(r5GPwr.uc5GTxPwrRU996Mcs0), + NVRAM_OFS(r5GPwr.uc5GTxPwrRU996Mcs11)}, + } + }; + + ASSERT(prAdapter); + prRegInfo = &prAdapter->prGlueInfo->rRegInfo; + + ASSERT(prRegInfo); + prNvramSettings = prRegInfo->prNvramSettings; + ASSERT(prNvramSettings); + + if (prAdapter->prGlueInfo->fgNvramAvailable == FALSE) { + DBGLOG(INIT, WARN, "check Nvram fail\n"); + return WLAN_STATUS_NOT_ACCEPTED; + } + + if (eBand == BAND_2G4) + bandIdx = 0; + else if (eBand == BAND_5G) + bandIdx = 1; + else { + DBGLOG(INIT, WARN, "check Band fail(%d)\n", + eBand); + return WLAN_STATUS_NOT_ACCEPTED; + } + if (ePhyMode >= PHY_MODE_TYPE_NUM || ePhyMode < 0) { + DBGLOG(INIT, WARN, "check phy mode fail(%d)\n", + ePhyMode); + return WLAN_STATUS_NOT_ACCEPTED; + } + + startOfs = arRange[bandIdx][ePhyMode].startOfs; + endOfs = arRange[bandIdx][ePhyMode].endOfs; + + + /*NVRAM start addreess :0*/ + pu1Addr = (uint8_t *)&prNvramSettings->u2Part1OwnVersion; + + for (rateIdx = startOfs; rateIdx <= endOfs; rateIdx++) { + nvTxPwr = *(pu1Addr + rateIdx); + + if (nvTxPwr < minTxPwr) + minTxPwr = nvTxPwr; + } + + /*NVRAM resolution is S6.1 format*/ + *pTxPwr = minTxPwr >> 1; + + DBGLOG(INIT, INFO, "Band[%s],PhyMode[%d],get mini txpwr=%d\n", + (eBand == BAND_2G4)?"2G4":"5G", + ePhyMode, + *pTxPwr); + + return WLAN_STATUS_SUCCESS; +#else + DBGLOG(INIT, WARN, "Not supported!"); + return WLAN_STATUS_NOT_SUPPORTED; +#endif +} + + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called to load manufacture data from NVRAM + * if available and valid + * + * @param prAdapter Pointer of Adapter Data Structure + * @param prRegInfo Pointer of REG_INFO_T + * + * @return WLAN_STATUS_SUCCESS + * WLAN_STATUS_FAILURE + */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanLoadManufactureData(IN struct ADAPTER + *prAdapter, IN struct REG_INFO *prRegInfo) +{ + +#if CFG_SUPPORT_RDD_TEST_MODE + struct CMD_RDD_CH rRddParam; +#endif + uint8_t i = 0; + uint8_t index; + uint8_t *pu1Addr; + uint8_t u1TypeID; + uint8_t u1LenLSB; + uint8_t u1LenMSB; + uint8_t fgSupportFragment = FALSE; + uint32_t u4NvramStartOffset = 0, u4NvramOffset = 0; + uint32_t u4NvramFragmentSize = 0; + struct CMD_NVRAM_FRAGMENT *prCmdNvramFragment; + struct WIFI_NVRAM_TAG_FORMAT *prTagDataCurr; + struct NVRAM_TAG_FRAGMENT_GROUP arNvramTagGroup[] = { + {0, 2}, /*for tag0, tag1,tag2*/ + {3, 3}, /*for tag3*/ + {4, 4}, /*for tag4*/ + {5, 5}, /*for tag5*/ + {6, 6}, /*for tag6*/ + {7, 11}, /*for tag7 ~ tag11*/ + }; + + struct CMD_NVRAM_SETTING *prCmdNvramSettings; + + if (prRegInfo == NULL) { + DBGLOG(INIT, ERROR, "prRegInfo = NULL"); + return WLAN_STATUS_FAILURE; + } + ASSERT(prAdapter); + + fgSupportFragment = prAdapter->chip_info->is_support_nvram_fragment; + + + /* 1. Version Check */ + if (prAdapter->prGlueInfo->fgNvramAvailable == TRUE) { + prAdapter->rVerInfo.u2Part1CfgOwnVersion = + prRegInfo->prNvramSettings->u2Part1OwnVersion; + prAdapter->rVerInfo.u2Part1CfgPeerVersion = + prRegInfo->prNvramSettings->u2Part1PeerVersion; + prAdapter->rVerInfo.u2Part2CfgOwnVersion = 0; + /* prRegInfo->prNvramSettings->u2Part2OwnVersion; */ + prAdapter->rVerInfo.u2Part2CfgPeerVersion = 0; + /* prRegInfo->prNvramSettings->u2Part2PeerVersion; */ + } + + /* 3. Check if needs to support 5GHz */ + if (prRegInfo->ucEnable5GBand) { + /* check if it is disabled by hardware */ + if (prAdapter->fgIsHw5GBandDisabled + || prRegInfo->ucSupport5GBand == 0) + prAdapter->fgEnable5GBand = FALSE; + else + prAdapter->fgEnable5GBand = TRUE; + } else + prAdapter->fgEnable5GBand = FALSE; + + /* 5. Get 16-bits Country Code and Bandwidth */ + prAdapter->rWifiVar.u2CountryCode = + (((uint16_t) prRegInfo->au2CountryCode[0]) << 8) | ((( + uint16_t) prRegInfo->au2CountryCode[1]) & BITS(0, 7)); + + /* 6. Set domain and channel information to chip */ + rlmDomainSendCmd(prAdapter); + + /* Update supported channel list in channel table */ + wlanUpdateChannelTable(prAdapter->prGlueInfo); + + /* 9. Send the full Parameters of NVRAM to FW */ + + /*NVRAM Parameter fragment, if NVRAM length is over 2048 bytes*/ + /*Driver will split NVRAM by TLV Group ,each TX CMD is 1564 bytes*/ + if (fgSupportFragment) { + prCmdNvramFragment = (struct CMD_NVRAM_FRAGMENT *)kalMemAlloc( + sizeof(struct CMD_NVRAM_FRAGMENT), + VIR_MEM_TYPE); + if (prCmdNvramFragment == NULL) { + DBGLOG(INIT, ERROR, + "prCmdNvramFragment allocate fail\n"); + return WLAN_STATUS_FAILURE; + } + + u4NvramStartOffset = 0; + pu1Addr = (uint8_t *) + &prRegInfo->prNvramSettings->u2Part1OwnVersion; + + prTagDataCurr = + (struct WIFI_NVRAM_TAG_FORMAT *)(pu1Addr + + OFFSET_OF(struct WIFI_CFG_PARAM_STRUCT, ucTypeID0)); + u1TypeID = prTagDataCurr->u1NvramTypeID; + u1LenLSB = prTagDataCurr->u1NvramTypeLenLsb; + u1LenMSB = prTagDataCurr->u1NvramTypeLenMsb; + u4NvramOffset += + OFFSET_OF(struct WIFI_CFG_PARAM_STRUCT, ucTypeID0); + + DBGLOG(INIT, TRACE, + "NVRAM-Frag Startofs[0x%08X]ID[%d][0x%08X]Len:%d\n" + , u4NvramStartOffset + , u1TypeID + , u4NvramOffset + , (u1LenMSB << 8) | (u1LenLSB)); + + for (i = 0 ; i < (sizeof(arNvramTagGroup) / + sizeof(struct NVRAM_TAG_FRAGMENT_GROUP)); i++) { + + kalMemZero(prCmdNvramFragment, + sizeof(struct CMD_NVRAM_FRAGMENT)); + + for (index = arNvramTagGroup[i].u1StartTagID; + index <= arNvramTagGroup[i].u1EndTagID; + index++) { + /*sanity check*/ + if ((u1TypeID == 0) && + (u1LenLSB == 0) && (u1LenMSB == 0)) { + DBGLOG(INIT, WARN, "TVL is Null\n"); + break; + } + /*check Type ID is exist on NVRAM*/ + if (u1TypeID != index) { + DBGLOG(INIT, ERROR, + "NVRAM tag(%d) isn't exist! current idx:%d\n", + u1TypeID, index); + continue; + } + + u4NvramOffset += NVRAM_TAG_HDR_SIZE; + u4NvramOffset += (u1LenMSB << 8) | (u1LenLSB); + + /*get the nex TLV format*/ + prTagDataCurr = (struct WIFI_NVRAM_TAG_FORMAT *) + (pu1Addr + u4NvramOffset); + + u1TypeID = prTagDataCurr->u1NvramTypeID; + u1LenLSB = prTagDataCurr->u1NvramTypeLenLsb; + u1LenMSB = prTagDataCurr->u1NvramTypeLenMsb; + + DBGLOG(INIT, TRACE, + "(%d,%d)CurOfs[0x%08X]:Next(%d)Len:%d\n", + i, index, + u4NvramOffset, + u1TypeID, + (u1LenMSB << 8) | (u1LenLSB)); + + } + u4NvramFragmentSize = u4NvramOffset-u4NvramStartOffset; + + DBGLOG(INIT, TRACE, + "NVRAM Fragement(%d)Startofs[0x%08X]Len:%d\n", + i, u4NvramStartOffset, u4NvramFragmentSize); + + kalMemCopy(prCmdNvramFragment, + (pu1Addr + u4NvramStartOffset), + u4NvramFragmentSize); + + wlanSendSetQueryCmd(prAdapter, + CMD_ID_SET_NVRAM_SETTINGS, + TRUE, + FALSE, + FALSE, NULL, NULL, + sizeof(struct CMD_NVRAM_FRAGMENT), + (uint8_t *) prCmdNvramFragment, NULL, 0); + + /*update the next Fragment group start offset*/ + u4NvramStartOffset = u4NvramOffset; + + } + + kalMemFree(prCmdNvramFragment, VIR_MEM_TYPE, + sizeof(struct CMD_NVRAM_FRAGMENT)); + + } else { + + prCmdNvramSettings = (struct CMD_NVRAM_SETTING *)kalMemAlloc( + sizeof(struct CMD_NVRAM_SETTING), + VIR_MEM_TYPE); + + kalMemCopy(&prCmdNvramSettings->rNvramSettings, + &prRegInfo->prNvramSettings->u2Part1OwnVersion, + sizeof(struct CMD_NVRAM_SETTING)); + ASSERT(sizeof(struct WIFI_CFG_PARAM_STRUCT) == 2048); + wlanSendSetQueryCmd(prAdapter, + CMD_ID_SET_NVRAM_SETTINGS, + TRUE, + FALSE, + FALSE, NULL, NULL, + sizeof(*prCmdNvramSettings), + (uint8_t *) prCmdNvramSettings, NULL, 0); + kalMemFree(prCmdNvramSettings, VIR_MEM_TYPE, + sizeof(struct CMD_NVRAM_SETTING)); + } + + + wlanNvramSetState(NVRAM_STATE_SEND_TO_FW); + + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called to check + * Media Stream Mode is set to non-default value or not, + * and clear to default value if above criteria is met + * + * @param prAdapter Pointer of Adapter Data Structure + * + * @return TRUE + * The media stream mode was non-default value and has been reset + * FALSE + * The media stream mode is default value + */ +/*----------------------------------------------------------------------------*/ +u_int8_t wlanResetMediaStreamMode(IN struct ADAPTER + *prAdapter) +{ + ASSERT(prAdapter); + + if (prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode != 0) { + prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode = 0; + + return TRUE; + } else { + return FALSE; + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called to check if any pending timer has expired + * + * @param prAdapter Pointer of Adapter Data Structure + * + * @return WLAN_STATUS_SUCCESS + */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanTimerTimeoutCheck(IN struct ADAPTER *prAdapter) +{ + ASSERT(prAdapter); + + cnmTimerDoTimeOutCheck(prAdapter); + + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called to check if any pending mailbox message + * to be handled + * + * @param prAdapter Pointer of Adapter Data Structure + * + * @return WLAN_STATUS_SUCCESS + */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanProcessMboxMessage(IN struct ADAPTER + *prAdapter) +{ + uint32_t i; + + ASSERT(prAdapter); + + for (i = 0; i < MBOX_ID_TOTAL_NUM; i++) + mboxRcvAllMsg(prAdapter, (enum ENUM_MBOX_ID) i); + + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called to enqueue a single TX packet into CORE + * + * @param prAdapter Pointer of Adapter Data Structure + * prNativePacket Pointer of Native Packet + * + * @return WLAN_STATUS_SUCCESS + * WLAN_STATUS_RESOURCES + * WLAN_STATUS_INVALID_PACKET + */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanEnqueueTxPacket(IN struct ADAPTER *prAdapter, + IN void *prNativePacket) +{ + struct TX_CTRL *prTxCtrl; + struct MSDU_INFO *prMsduInfo; + + ASSERT(prAdapter); + + prTxCtrl = &prAdapter->rTxCtrl; + + prMsduInfo = cnmPktAlloc(prAdapter, 0); + + if (!prMsduInfo) + return WLAN_STATUS_RESOURCES; + + if (nicTxFillMsduInfo(prAdapter, prMsduInfo, + prNativePacket)) { + /* prMsduInfo->eSrc = TX_PACKET_OS; */ + + /* Tx profiling */ + wlanTxProfilingTagMsdu(prAdapter, prMsduInfo, + TX_PROF_TAG_DRV_ENQUE); + + /* enqueue to QM */ + nicTxEnqueueMsdu(prAdapter, prMsduInfo); + + return WLAN_STATUS_SUCCESS; + } + kalSendComplete(prAdapter->prGlueInfo, prNativePacket, + WLAN_STATUS_INVALID_PACKET); + + nicTxReturnMsduInfo(prAdapter, prMsduInfo); + + return WLAN_STATUS_INVALID_PACKET; + +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called to flush pending TX packets in CORE + * + * @param prAdapter Pointer of Adapter Data Structure + * + * @return WLAN_STATUS_SUCCESS + */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanFlushTxPendingPackets(IN struct ADAPTER *prAdapter) +{ + ASSERT(prAdapter); + + return nicTxFlush(prAdapter); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief this function sends pending MSDU_INFO_T to MT6620 + * + * @param prAdapter Pointer to the Adapter structure. + * @param pfgHwAccess Pointer for tracking LP-OWN status + * + * @retval WLAN_STATUS_SUCCESS Reset is done successfully. + */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanTxPendingPackets(IN struct ADAPTER *prAdapter, + IN OUT u_int8_t *pfgHwAccess) +{ + struct TX_CTRL *prTxCtrl; + struct MSDU_INFO *prMsduInfo; + + KAL_SPIN_LOCK_DECLARATION(); + + ASSERT(prAdapter); + prTxCtrl = &prAdapter->rTxCtrl; + +#if !CFG_SUPPORT_MULTITHREAD + ASSERT(pfgHwAccess); +#endif + + /* <1> dequeue packet by txDequeuTxPackets() */ +#if CFG_SUPPORT_MULTITHREAD + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); + prMsduInfo = qmDequeueTxPacketsMthread(prAdapter, + &prTxCtrl->rTc); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); +#else + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); + prMsduInfo = qmDequeueTxPackets(prAdapter, &prTxCtrl->rTc); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); +#endif + if (prMsduInfo != NULL) { + if (kalIsCardRemoved(prAdapter->prGlueInfo) == FALSE) { +#if !CFG_SUPPORT_MULTITHREAD + /* <2> Acquire LP-OWN if necessary */ + if (*pfgHwAccess == FALSE) { + *pfgHwAccess = TRUE; + + wlanAcquirePowerControl(prAdapter); + } +#endif + /* <3> send packets */ +#if CFG_SUPPORT_MULTITHREAD + nicTxMsduInfoListMthread(prAdapter, prMsduInfo); +#else + nicTxMsduInfoList(prAdapter, prMsduInfo); +#endif + /* <4> update TC by txAdjustTcQuotas() */ + nicTxAdjustTcq(prAdapter); + } else + wlanProcessQueuedMsduInfo(prAdapter, prMsduInfo); + } + + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called to acquire power control from firmware + * + * @param prAdapter Pointer of Adapter Data Structure + * + * @return WLAN_STATUS_SUCCESS + */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanAcquirePowerControl(IN struct ADAPTER *prAdapter) +{ + ASSERT(prAdapter); + + /* DBGLOG(INIT, INFO, ("Acquire Power Ctrl\n")); */ + + ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); + + /* Reset sleepy state */ + if (prAdapter->fgWiFiInSleepyState == TRUE) + prAdapter->fgWiFiInSleepyState = FALSE; + + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called to release power control to firmware + * + * @param prAdapter Pointer of Adapter Data Structure + * + * @return WLAN_STATUS_SUCCESS + */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanReleasePowerControl(IN struct ADAPTER *prAdapter) +{ + ASSERT(prAdapter); + + /* DBGLOG(INIT, INFO, ("Release Power Ctrl\n")); */ + + RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); + + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called to report currently pending TX frames count + * (command packets are not included) + * + * @param prAdapter Pointer of Adapter Data Structure + * + * @return number of pending TX frames + */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanGetTxPendingFrameCount(IN struct ADAPTER *prAdapter) +{ + struct TX_CTRL *prTxCtrl; + uint32_t u4Num; + + ASSERT(prAdapter); + prTxCtrl = &prAdapter->rTxCtrl; + + u4Num = kalGetTxPendingFrameCount(prAdapter->prGlueInfo) + + (uint32_t) GLUE_GET_REF_CNT( + prTxCtrl->i4PendingFwdFrameCount); + + return u4Num; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is to report current ACPI state + * + * @param prAdapter Pointer of Adapter Data Structure + * + * @return ACPI_STATE_D0 Normal Operation Mode + * ACPI_STATE_D3 Suspend Mode + */ +/*----------------------------------------------------------------------------*/ +enum ENUM_ACPI_STATE wlanGetAcpiState(IN struct ADAPTER *prAdapter) +{ + ASSERT(prAdapter); + + return prAdapter->rAcpiState; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is to update current ACPI state only + * + * @param prAdapter Pointer of Adapter Data Structure + * @param ePowerState ACPI_STATE_D0 Normal Operation Mode + * ACPI_STATE_D3 Suspend Mode + * + * @return none + */ +/*----------------------------------------------------------------------------*/ +void wlanSetAcpiState(IN struct ADAPTER *prAdapter, + IN enum ENUM_ACPI_STATE ePowerState) +{ + ASSERT(prAdapter); + ASSERT(ePowerState <= ACPI_STATE_D3); + + prAdapter->rAcpiState = ePowerState; + +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is to query ECO version from HIFSYS CR + * + * @param prAdapter Pointer of Adapter Data Structure + * + * @return zero Unable to retrieve ECO version information + * non-zero ECO version (1-based) + */ +/*----------------------------------------------------------------------------*/ +uint8_t wlanGetEcoVersion(IN struct ADAPTER *prAdapter) +{ + uint8_t ucEcoVersion; + + ASSERT(prAdapter); + +#if CFG_MULTI_ECOVER_SUPPORT + ucEcoVersion = nicGetChipEcoVer(prAdapter); + DBGLOG(INIT, TRACE, "%s: %u\n", __func__, ucEcoVersion); + return ucEcoVersion; +#else + if (nicVerifyChipID(prAdapter) == TRUE) + return prAdapter->ucRevID + 1; + else + return 0; +#endif +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is to + * set preferred band configuration corresponding to network type + * + * @param prAdapter Pointer of Adapter Data Structure + * @param eBand Given band + * @param ucBssIndex BSS Info Index + * + * @return none + */ +/*----------------------------------------------------------------------------*/ +void wlanSetPreferBandByNetwork(IN struct ADAPTER *prAdapter, + IN enum ENUM_BAND eBand, IN uint8_t ucBssIndex) +{ + ASSERT(prAdapter); + ASSERT(eBand <= BAND_NUM); + ASSERT(ucBssIndex <= prAdapter->ucHwBssIdNum); + + + /* 1. set prefer band according to network type */ + prAdapter->aePreferBand[ucBssIndex] = eBand; + + /* 2. remove buffered BSS descriptors correspondingly */ + if (eBand == BAND_2G4) + scanRemoveBssDescByBandAndNetwork(prAdapter, BAND_5G, + ucBssIndex); + else if (eBand == BAND_5G) + scanRemoveBssDescByBandAndNetwork(prAdapter, BAND_2G4, + ucBssIndex); + +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is to + * get channel information corresponding to specified network type + * + * @param prAdapter Pointer of Adapter Data Structure + * @param ucBssIndex BSS Info Index + * + * @return channel number + */ +/*----------------------------------------------------------------------------*/ +uint8_t wlanGetChannelNumberByNetwork(IN struct ADAPTER + *prAdapter, IN uint8_t ucBssIndex) +{ + struct BSS_INFO *prBssInfo; + + ASSERT(prAdapter); + ASSERT(ucBssIndex <= prAdapter->ucHwBssIdNum); + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + + return prBssInfo->ucPrimaryChannel; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is to + * check unconfigured system properties and generate related message on + * scan list to notify users + * + * @param prAdapter Pointer of Adapter Data Structure + * + * @return WLAN_STATUS_SUCCESS + */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanCheckSystemConfiguration(IN struct ADAPTER + *prAdapter) +{ +#if (CFG_NVRAM_EXISTENCE_CHECK == 1) || (CFG_SW_NVRAM_VERSION_CHECK == 1) + const uint8_t aucZeroMacAddr[] = NULL_MAC_ADDR; + u_int8_t fgIsConfExist = TRUE; + u_int8_t fgGenErrMsg = FALSE; + struct REG_INFO *prRegInfo = NULL; +#if 0 + const uint8_t aucBCAddr[] = BC_MAC_ADDR; + struct WLAN_BEACON_FRAME *prBeacon = NULL; + struct IE_SSID *prSsid = NULL; + uint32_t u4ErrCode = 0; + uint8_t aucErrMsg[32]; + struct PARAM_SSID rSsid; + struct PARAM_802_11_CONFIG rConfiguration; + uint8_t rSupportedRates[PARAM_MAX_LEN_RATES_EX]; +#endif +#endif + + DEBUGFUNC("wlanCheckSystemConfiguration"); + + ASSERT(prAdapter); + +#if (CFG_NVRAM_EXISTENCE_CHECK == 1) + if (kalIsConfigurationExist(prAdapter->prGlueInfo) == + FALSE) { + fgIsConfExist = FALSE; + fgGenErrMsg = TRUE; + } +#endif + +#if (CFG_SW_NVRAM_VERSION_CHECK == 1) + prRegInfo = kalGetConfiguration(prAdapter->prGlueInfo); + + if (prRegInfo == NULL) { + DBGLOG(INIT, ERROR, "prRegInfo = NULL"); + return WLAN_STATUS_FAILURE; + } + +#if (CFG_SUPPORT_PWR_LIMIT_COUNTRY == 1) + if (fgIsConfExist == TRUE + && (prAdapter->rVerInfo.u2Part1CfgPeerVersion > + CFG_DRV_OWN_VERSION + || prAdapter->rVerInfo.u2Part2CfgPeerVersion > + CFG_DRV_OWN_VERSION + || prAdapter->rVerInfo.u2Part1CfgOwnVersion < + CFG_DRV_PEER_VERSION + || prAdapter->rVerInfo.u2Part2CfgOwnVersion < + CFG_DRV_PEER_VERSION/* NVRAM */ + || prAdapter->rVerInfo.u2FwPeerVersion > CFG_DRV_OWN_VERSION + || prAdapter->rVerInfo.u2FwOwnVersion < CFG_DRV_PEER_VERSION + || (prAdapter->fgIsEmbbededMacAddrValid == FALSE && + (IS_BMCAST_MAC_ADDR(prRegInfo->aucMacAddr) + || EQUAL_MAC_ADDR(aucZeroMacAddr, prRegInfo->aucMacAddr))) + || prAdapter->fgIsPowerLimitTableValid == FALSE)) + fgGenErrMsg = TRUE; +#else + if (fgIsConfExist == TRUE + && (prAdapter->rVerInfo.u2Part1CfgPeerVersion > + CFG_DRV_OWN_VERSION + || prAdapter->rVerInfo.u2Part2CfgPeerVersion > + CFG_DRV_OWN_VERSION + || prAdapter->rVerInfo.u2Part1CfgOwnVersion < + CFG_DRV_PEER_VERSION + || prAdapter->rVerInfo.u2Part2CfgOwnVersion < + CFG_DRV_PEER_VERSION/* NVRAM */ + || prAdapter->rVerInfo.u2FwPeerVersion > CFG_DRV_OWN_VERSION + || prAdapter->rVerInfo.u2FwOwnVersion < CFG_DRV_PEER_VERSION + || (prAdapter->fgIsEmbbededMacAddrValid == FALSE && + (IS_BMCAST_MAC_ADDR(prRegInfo->aucMacAddr) + || EQUAL_MAC_ADDR(aucZeroMacAddr, prRegInfo->aucMacAddr))) + )) + fgGenErrMsg = TRUE; +#endif +#endif +#if 0/* remove NVRAM WARNING in scan result */ + if (fgGenErrMsg == TRUE) { + prBeacon = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, + sizeof(struct WLAN_BEACON_FRAME) + + sizeof(struct IE_SSID)); + + /* initialization */ + kalMemZero(prBeacon, sizeof(struct WLAN_BEACON_FRAME) + + sizeof(struct IE_SSID)); + + /* prBeacon initialization */ + prBeacon->u2FrameCtrl = MAC_FRAME_BEACON; + COPY_MAC_ADDR(prBeacon->aucDestAddr, aucBCAddr); + COPY_MAC_ADDR(prBeacon->aucSrcAddr, aucZeroMacAddr); + COPY_MAC_ADDR(prBeacon->aucBSSID, aucZeroMacAddr); + prBeacon->u2BeaconInterval = 100; + prBeacon->u2CapInfo = CAP_INFO_ESS; + + /* prSSID initialization */ + prSsid = (struct IE_SSID *) (&prBeacon->aucInfoElem[0]); + prSsid->ucId = ELEM_ID_SSID; + + /* rConfiguration initialization */ + rConfiguration.u4Length = sizeof(struct + PARAM_802_11_CONFIG); + rConfiguration.u4BeaconPeriod = 100; + rConfiguration.u4ATIMWindow = 1; + rConfiguration.u4DSConfig = 2412; + rConfiguration.rFHConfig.u4Length = sizeof( + struct PARAM_802_11_CONFIG_FH); + + /* rSupportedRates initialization */ + kalMemZero(rSupportedRates, + (sizeof(uint8_t) * PARAM_MAX_LEN_RATES_EX)); + } +#if (CFG_NVRAM_EXISTENCE_CHECK == 1) +#define NVRAM_ERR_MSG "NVRAM WARNING: Err = 0x01" + if (kalIsConfigurationExist(prAdapter->prGlueInfo) == + FALSE) { + COPY_SSID(prSsid->aucSSID, prSsid->ucLength, NVRAM_ERR_MSG, + (uint8_t) (strlen(NVRAM_ERR_MSG))); + + kalIndicateBssInfo(prAdapter->prGlueInfo, + (uint8_t *) prBeacon, + OFFSET_OF(struct WLAN_BEACON_FRAME, + aucInfoElem) + OFFSET_OF( + struct IE_SSID, aucSSID) + + prSsid->ucLength, 1, 0); + + COPY_SSID(rSsid.aucSsid, rSsid.u4SsidLen, NVRAM_ERR_MSG, + strlen(NVRAM_ERR_MSG)); + nicAddScanResult(prAdapter, + prBeacon->aucBSSID, + &rSsid, + 0, + 0, + PARAM_NETWORK_TYPE_FH, + &rConfiguration, + NET_TYPE_INFRA, + rSupportedRates, + OFFSET_OF(struct WLAN_BEACON_FRAME, + aucInfoElem) + OFFSET_OF( + struct IE_SSID, aucSSID) + + prSsid->ucLength - + WLAN_MAC_MGMT_HEADER_LEN, + (uint8_t *) ((unsigned long) (prBeacon) + + WLAN_MAC_MGMT_HEADER_LEN)); + } +#endif + +#if (CFG_SW_NVRAM_VERSION_CHECK == 1) +#define VER_ERR_MSG "NVRAM WARNING: Err = 0x%02X" + if (fgIsConfExist == TRUE) { + if ((prAdapter->rVerInfo.u2Part1CfgPeerVersion > + CFG_DRV_OWN_VERSION + || prAdapter->rVerInfo.u2Part2CfgPeerVersion > + CFG_DRV_OWN_VERSION + || prAdapter->rVerInfo.u2Part1CfgOwnVersion < + CFG_DRV_PEER_VERSION + || prAdapter->rVerInfo.u2Part2CfgOwnVersion < + CFG_DRV_PEER_VERSION /* NVRAM */ + || prAdapter->rVerInfo.u2FwPeerVersion > + CFG_DRV_OWN_VERSION + || prAdapter->rVerInfo.u2FwOwnVersion < + CFG_DRV_PEER_VERSION)) + u4ErrCode |= NVRAM_ERROR_VERSION_MISMATCH; + + if (prAdapter->fgIsEmbbededMacAddrValid == FALSE + && (IS_BMCAST_MAC_ADDR(prRegInfo->aucMacAddr) + || EQUAL_MAC_ADDR(aucZeroMacAddr, + prRegInfo->aucMacAddr))) { + u4ErrCode |= NVRAM_ERROR_INVALID_MAC_ADDR; + } +#if CFG_SUPPORT_PWR_LIMIT_COUNTRY + if (prAdapter->fgIsPowerLimitTableValid == FALSE) + u4ErrCode |= NVRAM_POWER_LIMIT_TABLE_INVALID; +#endif + if (u4ErrCode != 0) { + sprintf(aucErrMsg, VER_ERR_MSG, + (unsigned int)u4ErrCode); + COPY_SSID(prSsid->aucSSID, prSsid->ucLength, aucErrMsg, + (uint8_t) (strlen(aucErrMsg))); + + kalIndicateBssInfo(prAdapter->prGlueInfo, + (uint8_t *) prBeacon, + OFFSET_OF(struct WLAN_BEACON_FRAME, + aucInfoElem) + OFFSET_OF( + struct IE_SSID, aucSSID) + + prSsid->ucLength, 1, 0); + + COPY_SSID(rSsid.aucSsid, rSsid.u4SsidLen, NVRAM_ERR_MSG, + strlen(NVRAM_ERR_MSG)); + nicAddScanResult(prAdapter, prBeacon->aucBSSID, &rSsid, + 0, 0, PARAM_NETWORK_TYPE_FH, + &rConfiguration, NET_TYPE_INFRA, + rSupportedRates, + OFFSET_OF(struct WLAN_BEACON_FRAME, + aucInfoElem) + + OFFSET_OF(struct IE_SSID, + aucSSID) + prSsid->ucLength - + WLAN_MAC_MGMT_HEADER_LEN, + (uint8_t *) ((unsigned long) (prBeacon) + + WLAN_MAC_MGMT_HEADER_LEN)); + } + } +#endif + + if (fgGenErrMsg == TRUE) + cnmMemFree(prAdapter, prBeacon); +#endif + return WLAN_STATUS_SUCCESS; +} + +uint32_t +wlanoidQueryBssStatistics(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) +{ + struct PARAM_GET_BSS_STATISTICS *prQueryBssStatistics; + struct BSS_INFO *prBssInfo; + struct STA_RECORD *prStaRec; + uint32_t rResult = WLAN_STATUS_FAILURE; + uint8_t ucBssIndex; + enum ENUM_WMM_ACI eAci; + + DEBUGFUNC("wlanoidQueryBssStatistics"); + + do { + ASSERT(pvQueryBuffer); + + /* 4 1. Sanity test */ + if ((prAdapter == NULL) || (pu4QueryInfoLen == NULL)) + break; + + if ((u4QueryBufferLen) && (pvQueryBuffer == NULL)) + break; + + if (u4QueryBufferLen < + sizeof(struct PARAM_GET_BSS_STATISTICS *)) { + *pu4QueryInfoLen = + sizeof(struct PARAM_GET_BSS_STATISTICS *); + rResult = WLAN_STATUS_BUFFER_TOO_SHORT; + break; + } + + prQueryBssStatistics = (struct PARAM_GET_BSS_STATISTICS *) + pvQueryBuffer; + *pu4QueryInfoLen = sizeof(struct PARAM_GET_BSS_STATISTICS); + + ucBssIndex = prQueryBssStatistics->ucBssIndex; + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + + if (prBssInfo) { /*AIS*/ + if (prBssInfo->eCurrentOPMode == + OP_MODE_INFRASTRUCTURE) { + struct WIFI_WMM_AC_STAT *prQueryLss = NULL; + struct WIFI_WMM_AC_STAT *prStaLss = NULL; + struct WIFI_WMM_AC_STAT *prBssLss = NULL; + + prQueryLss = prQueryBssStatistics->arLinkStatistics; + prBssLss = prBssInfo->arLinkStatistics; + prStaRec = prBssInfo->prStaRecOfAP; + if (prStaRec) { + prStaLss = prStaRec->arLinkStatistics; + for (eAci = 0; + eAci < WMM_AC_INDEX_NUM; eAci++) { + prQueryLss[eAci].u4TxMsdu = + prStaLss[eAci].u4TxMsdu; + prQueryLss[eAci].u4RxMsdu = + prStaLss[eAci].u4RxMsdu; + prQueryLss[eAci].u4TxDropMsdu = + prStaLss[eAci].u4TxDropMsdu + + prBssLss[eAci].u4TxDropMsdu; + prQueryLss[eAci].u4TxFailMsdu = + prStaLss[eAci].u4TxFailMsdu; + prQueryLss[eAci].u4TxRetryMsdu = + prStaLss[eAci].u4TxRetryMsdu; + } + } + } + rResult = WLAN_STATUS_SUCCESS; + + /*P2P */ + /* TODO */ + + /*BOW*/ + /* TODO */ + } + + } while (FALSE); + + return rResult; + +} + +void wlanDumpBssStatistics(IN struct ADAPTER *prAdapter, + uint8_t ucBssIdx) +{ + struct BSS_INFO *prBssInfo; + struct STA_RECORD *prStaRec; + enum ENUM_WMM_ACI eAci; + struct WIFI_WMM_AC_STAT arLLStats[WMM_AC_INDEX_NUM]; + uint8_t ucIdx; + + if (ucBssIdx > prAdapter->ucHwBssIdNum) { + DBGLOG(SW4, INFO, "Invalid BssInfo index[%u], skip dump!\n", + ucBssIdx); + return; + } + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIdx); + if (!prBssInfo) { + DBGLOG(SW4, INFO, "Invalid BssInfo index[%u], skip dump!\n", + ucBssIdx); + return; + } + /* <1> fill per-BSS statistics */ +#if 0 + /*AIS*/ if (prBssInfo->eCurrentOPMode == + OP_MODE_INFRASTRUCTURE) { + prStaRec = prBssInfo->prStaRecOfAP; + if (prStaRec) { + for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { + prBssInfo->arLinkStatistics[eAci].u4TxMsdu + = prStaRec->arLinkStatistics[eAci] + .u4TxMsdu; + prBssInfo->arLinkStatistics[eAci].u4RxMsdu + = prStaRec->arLinkStatistics[eAci] + .u4RxMsdu; + prBssInfo->arLinkStatistics[eAci].u4TxDropMsdu + += prStaRec->arLinkStatistics[eAci] + .u4TxDropMsdu; + prBssInfo->arLinkStatistics[eAci].u4TxFailMsdu + = prStaRec->arLinkStatistics[eAci] + .u4TxFailMsdu; + prBssInfo->arLinkStatistics[eAci].u4TxRetryMsdu + = prStaRec->arLinkStatistics[eAci] + .u4TxRetryMsdu; + } + } + } +#else + for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { + arLLStats[eAci].u4TxMsdu = + prBssInfo->arLinkStatistics[eAci].u4TxMsdu; + arLLStats[eAci].u4RxMsdu = + prBssInfo->arLinkStatistics[eAci].u4RxMsdu; + arLLStats[eAci].u4TxDropMsdu = + prBssInfo->arLinkStatistics[eAci].u4TxDropMsdu; + arLLStats[eAci].u4TxFailMsdu = + prBssInfo->arLinkStatistics[eAci].u4TxFailMsdu; + arLLStats[eAci].u4TxRetryMsdu = + prBssInfo->arLinkStatistics[eAci].u4TxRetryMsdu; + } + + for (ucIdx = 0; ucIdx < CFG_STA_REC_NUM; ucIdx++) { + prStaRec = cnmGetStaRecByIndex(prAdapter, ucIdx); + if (!prStaRec) + continue; + if (prStaRec->ucBssIndex != ucBssIdx) + continue; + /* now the valid sta_rec is valid */ + for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { + arLLStats[eAci].u4TxMsdu += + prStaRec->arLinkStatistics[eAci].u4TxMsdu; + arLLStats[eAci].u4RxMsdu += + prStaRec->arLinkStatistics[eAci].u4RxMsdu; + arLLStats[eAci].u4TxDropMsdu += + prStaRec->arLinkStatistics[eAci].u4TxDropMsdu; + arLLStats[eAci].u4TxFailMsdu += + prStaRec->arLinkStatistics[eAci].u4TxFailMsdu; + arLLStats[eAci].u4TxRetryMsdu += + prStaRec->arLinkStatistics[eAci].u4TxRetryMsdu; + } + } +#endif + + /* <2>Dump BSS statistics */ + for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { + DBGLOG(SW4, INFO, + "LLS BSS[%u] %s: T[%06u] R[%06u] T_D[%06u] T_F[%06u]\n", + prBssInfo->ucBssIndex, apucACI2Str[eAci], + arLLStats[eAci].u4TxMsdu, + arLLStats[eAci].u4RxMsdu, arLLStats[eAci].u4TxDropMsdu, + arLLStats[eAci].u4TxFailMsdu); + } +} + +void wlanDumpAllBssStatistics(IN struct ADAPTER *prAdapter) +{ + struct BSS_INFO *prBssInfo; + /* ENUM_WMM_ACI_T eAci; */ + uint32_t ucIdx; + + /* wlanUpdateAllBssStatistics(prAdapter); */ + + for (ucIdx = 0; ucIdx < prAdapter->ucHwBssIdNum; ucIdx++) { + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucIdx); + if (!IS_BSS_ACTIVE(prBssInfo)) { + DBGLOG(SW4, TRACE, + "Invalid BssInfo index[%u], skip dump!\n", + ucIdx); + continue; + } + + wlanDumpBssStatistics(prAdapter, ucIdx); + } +} + +uint32_t +wlanoidQueryStaStatistics(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) +{ + return wlanQueryStaStatistics(prAdapter, pvQueryBuffer, + u4QueryBufferLen, pu4QueryInfoLen, TRUE); +} + +uint32_t +wlanQueryStaStatistics(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen, + u_int8_t fgIsOid) +{ + uint32_t rResult = WLAN_STATUS_FAILURE; + struct STA_RECORD *prStaRec, *prTempStaRec; + struct PARAM_GET_STA_STATISTICS *prQueryStaStatistics; + uint8_t ucStaRecIdx; + struct QUE_MGT *prQM; + struct CMD_GET_STA_STATISTICS rQueryCmdStaStatistics; + uint8_t ucIdx; + enum ENUM_WMM_ACI eAci; + + DEBUGFUNC("wlanoidQueryStaStatistics"); + + if (prAdapter == NULL) + return WLAN_STATUS_FAILURE; + prQM = &prAdapter->rQM; + + if (prAdapter->fgIsEnableLpdvt) + return WLAN_STATUS_NOT_SUPPORTED; + + do { + ASSERT(pvQueryBuffer); + + /* 4 1. Sanity test */ + if (pu4QueryInfoLen == NULL) + break; + + if ((u4QueryBufferLen) && (pvQueryBuffer == NULL)) + break; + + if (u4QueryBufferLen < + sizeof(struct PARAM_GET_STA_STATISTICS)) { + *pu4QueryInfoLen = + sizeof(struct PARAM_GET_STA_STATISTICS); + rResult = WLAN_STATUS_BUFFER_TOO_SHORT; + break; + } + + prQueryStaStatistics = (struct PARAM_GET_STA_STATISTICS *) + pvQueryBuffer; + *pu4QueryInfoLen = sizeof(struct PARAM_GET_STA_STATISTICS); + + /* 4 5. Get driver global QM counter */ +#if QM_ADAPTIVE_TC_RESOURCE_CTRL + for (ucIdx = TC0_INDEX; ucIdx <= TC3_INDEX; ucIdx++) { + prQueryStaStatistics->au4TcAverageQueLen[ucIdx] = + prQM->au4AverageQueLen[ucIdx]; + prQueryStaStatistics->au4TcCurrentQueLen[ucIdx] = + prQM->au4CurrentTcResource[ucIdx]; + } +#endif + + /* 4 2. Get StaRec by MAC address */ + prStaRec = NULL; + + for (ucStaRecIdx = 0; ucStaRecIdx < CFG_STA_REC_NUM; + ucStaRecIdx++) { + prTempStaRec = &(prAdapter->arStaRec[ucStaRecIdx]); + if (prTempStaRec->fgIsValid && + prTempStaRec->fgIsInUse) { + if (EQUAL_MAC_ADDR(prTempStaRec->aucMacAddr, + prQueryStaStatistics->aucMacAddr)) { + prStaRec = prTempStaRec; + break; + } + } + } + + if (!prStaRec) { + rResult = WLAN_STATUS_INVALID_DATA; + break; + } + + prQueryStaStatistics->u4Flag |= BIT(0); + +#if CFG_ENABLE_PER_STA_STATISTICS + /* 4 3. Get driver statistics */ + prQueryStaStatistics->u4TxTotalCount = + prStaRec->u4TotalTxPktsNumber; + prQueryStaStatistics->u4RxTotalCount = + prStaRec->u4TotalRxPktsNumber; + prQueryStaStatistics->u4TxExceedThresholdCount = + prStaRec->u4ThresholdCounter; + prQueryStaStatistics->u4TxMaxTime = + prStaRec->u4MaxTxPktsTime; + prQueryStaStatistics->u4TxMaxHifTime = + prStaRec->u4MaxTxPktsHifTime; + + if (prStaRec->u4TotalTxPktsNumber) { + prQueryStaStatistics->u4TxAverageProcessTime = + (prStaRec->u4TotalTxPktsTime / + prStaRec->u4TotalTxPktsNumber); + prQueryStaStatistics->u4TxAverageHifTime = + prStaRec->u4TotalTxPktsHifTxTime / + prStaRec->u4TotalTxPktsNumber; + } else + prQueryStaStatistics->u4TxAverageProcessTime = 0; + + /*link layer statistics */ + for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { + prQueryStaStatistics->arLinkStatistics[eAci].u4TxMsdu = + prStaRec->arLinkStatistics[eAci].u4TxMsdu; + prQueryStaStatistics->arLinkStatistics[eAci].u4RxMsdu = + prStaRec->arLinkStatistics[eAci].u4RxMsdu; + prQueryStaStatistics->arLinkStatistics[ + eAci].u4TxDropMsdu = + prStaRec->arLinkStatistics[eAci].u4TxDropMsdu; + } + + for (ucIdx = TC0_INDEX; ucIdx <= TC3_INDEX; ucIdx++) { + prQueryStaStatistics->au4TcResourceEmptyCount[ucIdx] = + prQM->au4QmTcResourceEmptyCounter[ + prStaRec->ucBssIndex][ucIdx]; + /* Reset */ + prQM->au4QmTcResourceEmptyCounter[ + prStaRec->ucBssIndex][ucIdx] = 0; + prQueryStaStatistics->au4TcResourceBackCount[ucIdx] = + prQM->au4QmTcResourceBackCounter[ucIdx]; + prQM->au4QmTcResourceBackCounter[ucIdx] = 0; + prQueryStaStatistics->au4DequeueNoTcResource[ucIdx] + = prQM->au4DequeueNoTcResourceCounter[ucIdx]; + prQM->au4DequeueNoTcResourceCounter[ucIdx] = 0; + prQueryStaStatistics->au4TcResourceUsedPageCount[ucIdx] + = prQM->au4QmTcUsedPageCounter[ucIdx]; + prQM->au4QmTcUsedPageCounter[ucIdx] = 0; + prQueryStaStatistics->au4TcResourceWantedPageCount[ + ucIdx] = prQM->au4QmTcWantedPageCounter[ucIdx]; + prQM->au4QmTcWantedPageCounter[ucIdx] = 0; + } + + prQueryStaStatistics->u4EnqueueCounter = + prQM->u4EnqueueCounter; + prQueryStaStatistics->u4EnqueueStaCounter = + prStaRec->u4EnqueueCounter; + + prQueryStaStatistics->u4DequeueCounter = + prQM->u4DequeueCounter; + prQueryStaStatistics->u4DequeueStaCounter = + prStaRec->u4DeqeueuCounter; + + prQueryStaStatistics->IsrCnt = + prAdapter->prGlueInfo->IsrCnt; + prQueryStaStatistics->IsrPassCnt = + prAdapter->prGlueInfo->IsrPassCnt; + prQueryStaStatistics->TaskIsrCnt = + prAdapter->prGlueInfo->TaskIsrCnt; + + prQueryStaStatistics->IsrAbnormalCnt = + prAdapter->prGlueInfo->IsrAbnormalCnt; + prQueryStaStatistics->IsrSoftWareCnt = + prAdapter->prGlueInfo->IsrSoftWareCnt; + prQueryStaStatistics->IsrRxCnt = + prAdapter->prGlueInfo->IsrRxCnt; + prQueryStaStatistics->IsrTxCnt = + prAdapter->prGlueInfo->IsrTxCnt; + + /* 4 4.1 Reset statistics */ + if (prQueryStaStatistics->ucReadClear) { + prStaRec->u4ThresholdCounter = 0; + prStaRec->u4TotalTxPktsNumber = 0; + prStaRec->u4TotalTxPktsHifTxTime = 0; + + prStaRec->u4TotalTxPktsTime = 0; + prStaRec->u4TotalRxPktsNumber = 0; + prStaRec->u4MaxTxPktsTime = 0; + prStaRec->u4MaxTxPktsHifTime = 0; + prQM->u4EnqueueCounter = 0; + prQM->u4DequeueCounter = 0; + prStaRec->u4EnqueueCounter = 0; + prStaRec->u4DeqeueuCounter = 0; + + prAdapter->prGlueInfo->IsrCnt = 0; + prAdapter->prGlueInfo->IsrPassCnt = 0; + prAdapter->prGlueInfo->TaskIsrCnt = 0; + + prAdapter->prGlueInfo->IsrAbnormalCnt = 0; + prAdapter->prGlueInfo->IsrSoftWareCnt = 0; + prAdapter->prGlueInfo->IsrRxCnt = 0; + prAdapter->prGlueInfo->IsrTxCnt = 0; + } + /*link layer statistics */ + if (prQueryStaStatistics->ucLlsReadClear) { + for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { + prStaRec->arLinkStatistics[eAci].u4TxMsdu = 0; + prStaRec->arLinkStatistics[eAci].u4RxMsdu = 0; + prStaRec->arLinkStatistics[eAci].u4TxDropMsdu + = 0; + } + } +#endif + + for (ucIdx = TC0_INDEX; ucIdx <= TC3_INDEX; ucIdx++) + prQueryStaStatistics->au4TcQueLen[ucIdx] = + prStaRec->aprTargetQueue[ucIdx]->u4NumElem; + + rResult = WLAN_STATUS_SUCCESS; + + /* 4 6. Ensure FW supports get station link status */ + rQueryCmdStaStatistics.ucIndex = prStaRec->ucIndex; + COPY_MAC_ADDR(rQueryCmdStaStatistics.aucMacAddr, + prQueryStaStatistics->aucMacAddr); + rQueryCmdStaStatistics.ucReadClear = + prQueryStaStatistics->ucReadClear; + rQueryCmdStaStatistics.ucLlsReadClear = + prQueryStaStatistics->ucLlsReadClear; + rQueryCmdStaStatistics.ucResetCounter = + prQueryStaStatistics->ucResetCounter; + + rResult = wlanSendSetQueryCmd(prAdapter, + CMD_ID_GET_STA_STATISTICS, + FALSE, + TRUE, + fgIsOid, + nicCmdEventQueryStaStatistics, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_GET_STA_STATISTICS), + (uint8_t *)&rQueryCmdStaStatistics, + pvQueryBuffer, u4QueryBufferLen); + + if ((!fgIsOid) && (rResult == WLAN_STATUS_PENDING)) + rResult = WLAN_STATUS_SUCCESS; + + prQueryStaStatistics->u4Flag |= BIT(1); + + } while (FALSE); + + return rResult; +} /* wlanoidQueryP2pVersion */ + +uint32_t +wlanQueryStatistics(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen, IN uint8_t fgIsOid) +{ + struct PARAM_802_11_STATISTICS_STRUCT rStatistics; + + DEBUGFUNC("wlanQueryStatistics"); + + ASSERT(prAdapter); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + ASSERT(pu4QueryInfoLen); + + *pu4QueryInfoLen = sizeof(struct PARAM_802_11_STATISTICS_STRUCT); + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, WARN, + "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", + prAdapter->rAcpiState, prAdapter->fgIsRadioOff); + *pu4QueryInfoLen = sizeof(uint32_t); + return WLAN_STATUS_ADAPTER_NOT_READY; + } else if (u4QueryBufferLen < sizeof(struct + PARAM_802_11_STATISTICS_STRUCT)) { + DBGLOG(REQ, WARN, "Too short length %u\n", + u4QueryBufferLen); + return WLAN_STATUS_INVALID_LENGTH; + } +#if CFG_ENABLE_STATISTICS_BUFFERING + if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { + struct PARAM_802_11_STATISTICS_STRUCT *prStatistics; + + *pu4QueryInfoLen = sizeof(struct + PARAM_802_11_STATISTICS_STRUCT); + prStatistics = (struct PARAM_802_11_STATISTICS_STRUCT *) + pvQueryBuffer; + + prStatistics->u4Length = sizeof(struct + PARAM_802_11_STATISTICS_STRUCT); + prStatistics->rTransmittedFragmentCount = + prAdapter->rStatStruct.rTransmittedFragmentCount; + prStatistics->rMulticastTransmittedFrameCount = + prAdapter->rStatStruct.rMulticastTransmittedFrameCount; + prStatistics->rFailedCount = + prAdapter->rStatStruct.rFailedCount; + prStatistics->rRetryCount = + prAdapter->rStatStruct.rRetryCount; + prStatistics->rMultipleRetryCount = + prAdapter->rStatStruct.rMultipleRetryCount; + prStatistics->rRTSSuccessCount = + prAdapter->rStatStruct.rRTSSuccessCount; + prStatistics->rRTSFailureCount = + prAdapter->rStatStruct.rRTSFailureCount; + prStatistics->rACKFailureCount = + prAdapter->rStatStruct.rACKFailureCount; + prStatistics->rFrameDuplicateCount = + prAdapter->rStatStruct.rFrameDuplicateCount; + prStatistics->rReceivedFragmentCount = + prAdapter->rStatStruct.rReceivedFragmentCount; + prStatistics->rMulticastReceivedFrameCount = + prAdapter->rStatStruct.rMulticastReceivedFrameCount; + prStatistics->rFCSErrorCount = + prAdapter->rStatStruct.rFCSErrorCount; + prStatistics->rTKIPLocalMICFailures.QuadPart = 0; + prStatistics->rTKIPICVErrors.QuadPart = 0; + prStatistics->rTKIPCounterMeasuresInvoked.QuadPart = 0; + prStatistics->rTKIPReplays.QuadPart = 0; + prStatistics->rCCMPFormatErrors.QuadPart = 0; + prStatistics->rCCMPReplays.QuadPart = 0; + prStatistics->rCCMPDecryptErrors.QuadPart = 0; + prStatistics->rFourWayHandshakeFailures.QuadPart = 0; + prStatistics->rWEPUndecryptableCount.QuadPart = 0; + prStatistics->rWEPICVErrorCount.QuadPart = 0; + prStatistics->rDecryptSuccessCount.QuadPart = 0; + prStatistics->rDecryptFailureCount.QuadPart = 0; + + return WLAN_STATUS_SUCCESS; + } +#endif + + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_GET_STATISTICS, + FALSE, + TRUE, + fgIsOid, + nicCmdEventQueryStatistics, + nicOidCmdTimeoutCommon, + sizeof(struct PARAM_802_11_STATISTICS_STRUCT), + (uint8_t *)&rStatistics, + pvQueryBuffer, u4QueryBufferLen); + +} /* wlanQueryStatistics */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is to query Nic resource information + * + * @param prAdapter Pointer of Adapter Data Structure + * + * @return WLAN_STATUS_SUCCESS + */ +/*----------------------------------------------------------------------------*/ +void wlanQueryNicResourceInformation(IN struct ADAPTER *prAdapter) +{ + /* 3 1. Get Nic resource information from FW */ + + /* 3 2. Setup resource parameter */ + + /* 3 3. Reset Tx resource */ + nicTxResetResource(prAdapter); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is to query Nic resource information + * + * @param prAdapter Pointer of Adapter Data Structure + * + * @return WLAN_STATUS_SUCCESS + */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanQueryNicCapabilityV2(IN struct ADAPTER *prAdapter) +{ + struct CMD_INFO *prCmdInfo; + uint32_t u4RxPktLength; + uint8_t *prEventBuff; + struct WIFI_EVENT *prEvent; + struct mt66xx_chip_info *prChipInfo; + uint32_t chip_id; + uint32_t u4Time; + + ASSERT(prAdapter); + prChipInfo = prAdapter->chip_info; + chip_id = prChipInfo->chip_id; + + ASSERT(prAdapter); + + /* Get Nic resource information from FW */ + if (!prChipInfo->isNicCapV1 + || (prAdapter->u4FwFeatureFlag0 & + FEATURE_FLAG0_NIC_CAPABILITY_V2)) { + + DBGLOG(INIT, INFO, "Support NIC_CAPABILITY_V2 feature\n"); + + /* + * send NIC_CAPABILITY_V2 query cmd + */ + + /* 1. Allocate CMD Info Packet and its Buffer */ + prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, + prChipInfo->u2CmdTxHdrSize); + if (!prCmdInfo) { + DBGLOG(INIT, ERROR, + "Allocate CMD_INFO_T ==> FAILED.\n"); + return WLAN_STATUS_FAILURE; + } + + /* compose CMD_BUILD_CONNECTION cmd pkt */ + prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; + prCmdInfo->u2InfoBufLen = prChipInfo->u2CmdTxHdrSize; + prCmdInfo->pfCmdDoneHandler = NULL; + prCmdInfo->fgIsOid = FALSE; + prCmdInfo->ucCID = CMD_ID_GET_NIC_CAPABILITY_V2; + prCmdInfo->fgSetQuery = FALSE; + prCmdInfo->fgNeedResp = TRUE; + prCmdInfo->u4SetInfoLen = 0; + + /* Setup WIFI_CMD_T */ + NIC_FILL_CMD_TX_HDR( + prAdapter, + prCmdInfo->pucInfoBuffer, + prCmdInfo->u2InfoBufLen, + prCmdInfo->ucCID, + CMD_PACKET_TYPE_ID, + &prCmdInfo->ucCmdSeqNum, + prCmdInfo->fgSetQuery, + NULL, FALSE, 0, S2D_INDEX_CMD_H2N); + + wlanSendCommand(prAdapter, prCmdInfo); + + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + + /* + * receive nic_capability_v2 event + */ + + /* allocate event buffer */ + prEventBuff = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, + CFG_RX_MAX_PKT_SIZE); + if (!prEventBuff) { + DBGLOG(INIT, WARN, "%s: event buffer alloc failed!\n", + __func__); + return WLAN_STATUS_FAILURE; + } + + /* get event */ + u4Time = kalGetTimeTick(); + while (TRUE) { + if (nicRxWaitResponse(prAdapter, + 1, + prEventBuff, + CFG_RX_MAX_PKT_SIZE, + &u4RxPktLength) + != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, WARN, + "%s: wait for event failed!\n", + __func__); + + /* free event buffer */ + cnmMemFree(prAdapter, prEventBuff); + + return WLAN_STATUS_FAILURE; + } + + if (CHECK_FOR_TIMEOUT(kalGetTimeTick(), u4Time, + MSEC_TO_SYSTIME(3000))) { + DBGLOG(HAL, ERROR, + "Query nic capability timeout\n"); + return WLAN_STATUS_FAILURE; + } + + /* header checking .. */ + if ((NIC_RX_GET_U2_SW_PKT_TYPE(prEventBuff) & + prChipInfo->u2RxSwPktBitMap) != + prChipInfo->u2RxSwPktEvent) { + DBGLOG(INIT, WARN, + "%s: skip unexpected Rx pkt type[0x%04x]\n", + __func__, + NIC_RX_GET_U2_SW_PKT_TYPE(prEventBuff)); + + continue; + } + + prEvent = (struct WIFI_EVENT *) + (prEventBuff + prChipInfo->rxd_size); + if (prEvent->ucEID != EVENT_ID_NIC_CAPABILITY_V2) { + DBGLOG(INIT, WARN, + "%s: skip unexpected event ID[0x%02x]\n", + __func__, prEvent->ucEID); + + continue; + } else { + /* hit */ + break; + } + + } + + /* + * parsing elemens + */ + + nicCmdEventQueryNicCapabilityV2(prAdapter, + prEvent->aucBuffer); + + /* + * free event buffer + */ + cnmMemFree(prAdapter, prEventBuff); + } + + /* Fill capability for different Chip version */ + if (chip_id == HQA_CHIP_ID_6632) { + /* 6632 only */ + prAdapter->fgIsSupportBufferBinSize16Byte = TRUE; + prAdapter->fgIsSupportDelayCal = FALSE; + prAdapter->fgIsSupportGetFreeEfuseBlockCount = FALSE; + prAdapter->fgIsSupportQAAccessEfuse = FALSE; + prAdapter->fgIsSupportPowerOnSendBufferModeCMD = FALSE; + prAdapter->fgIsSupportGetTxPower = FALSE; + } else { + prAdapter->fgIsSupportBufferBinSize16Byte = FALSE; + prAdapter->fgIsSupportDelayCal = TRUE; + prAdapter->fgIsSupportGetFreeEfuseBlockCount = TRUE; + prAdapter->fgIsSupportQAAccessEfuse = TRUE; + prAdapter->fgIsSupportPowerOnSendBufferModeCMD = TRUE; + prAdapter->fgIsSupportGetTxPower = TRUE; + } + + return WLAN_STATUS_SUCCESS; +} + +void wlanSetNicResourceParameters(IN struct ADAPTER + *prAdapter) +{ + uint8_t string[128], idx; + uint32_t u4share; + uint32_t u4MaxPageCntPerFrame = + prAdapter->rTxCtrl.u4MaxPageCntPerFrame; + struct WIFI_VAR *prWifiVar = &prAdapter->rWifiVar; +#if QM_ADAPTIVE_TC_RESOURCE_CTRL + struct QUE_MGT *prQM = &prAdapter->rQM; +#endif + + /* + * Use the settings in config file first, + * else, use the settings reported from firmware. + */ + + + /* + * 1. assign free page count for each TC + */ + + /* 1 1. update free page count in TC control: MCU and LMAC */ + prWifiVar->au4TcPageCount[TC4_INDEX] = + prAdapter->nicTxReousrce.u4CmdTotalResource * + u4MaxPageCntPerFrame; /* MCU */ + + u4share = prAdapter->nicTxReousrce.u4DataTotalResource / + (TC_NUM - 1); /* LMAC. Except TC_4, which is MCU */ + for (idx = TC0_INDEX; idx < TC_NUM; idx++) { + if (idx != TC4_INDEX) + prWifiVar->au4TcPageCount[idx] = u4share * + u4MaxPageCntPerFrame; + } + + /* 1 2. if there is remaings, give them to TC_3, which is VO */ + prWifiVar->au4TcPageCount[TC3_INDEX] += + (prAdapter->nicTxReousrce.u4DataTotalResource % + (TC_NUM - 1)) * u4MaxPageCntPerFrame; + +#if QM_ADAPTIVE_TC_RESOURCE_CTRL + /* + * 2. assign guaranteed page count for each TC + */ + + /* 2 1. update guaranteed page count in QM */ + for (idx = 0; idx < TC_NUM; idx++) + prQM->au4GuaranteedTcResource[idx] = + prWifiVar->au4TcPageCount[idx]; +#endif + + +#if CFG_SUPPORT_CFG_FILE + /* + * 3. Use the settings in config file first, + * else, use the settings reported from firmware. + */ + + /* 3 1. update for free page count */ + for (idx = 0; idx < TC_NUM; idx++) { + + /* construct prefix: Tc0Page, Tc1Page... */ + memset(string, 0, sizeof(string) / sizeof(uint8_t)); + kalSnprintf(string, sizeof(string) / sizeof(uint8_t), + "Tc%xPage", idx); + + /* update the final value */ + prWifiVar->au4TcPageCount[idx] = + (uint32_t) wlanCfgGetUint32(prAdapter, string, + prWifiVar->au4TcPageCount[idx]); + } + +#if QM_ADAPTIVE_TC_RESOURCE_CTRL + /* 3 2. update for guaranteed page count */ + for (idx = 0; idx < TC_NUM; idx++) { + + /* construct prefix: Tc0Grt, Tc1Grt... */ + memset(string, 0, sizeof(string) / sizeof(uint8_t)); + kalSnprintf(string, sizeof(string) / sizeof(uint8_t), + "Tc%xGrt", idx); + + /* update the final value */ + prQM->au4GuaranteedTcResource[idx] = + (uint32_t) wlanCfgGetUint32(prAdapter, string, + prQM->au4GuaranteedTcResource[idx]); + } +#endif /* end of #if QM_ADAPTIVE_TC_RESOURCE_CTRL */ + +#endif /* end of #if CFG_SUPPORT_CFG_FILE */ +} + + +#if CFG_SUPPORT_IOT_AP_BLACKLIST +void wlanCfgDumpIotApRule(IN struct ADAPTER *prAdapter) +{ + uint8_t ucRuleIdx; + struct WLAN_IOT_AP_RULE_T *prIotApRule; + + ASSERT(prAdapter); + for (ucRuleIdx = 0; ucRuleIdx < CFG_IOT_AP_RULE_MAX_CNT; ucRuleIdx++) { + prIotApRule = &prAdapter->rIotApRule[ucRuleIdx]; + if (!prIotApRule->u2MatchFlag) + continue; + DBGLOG(INIT, TRACE, "IOTAP%d is valid rule\n", ucRuleIdx); + DBGLOG(INIT, TRACE, "IOTAP%d Flag:0x%X Ver:0x%X\n", + ucRuleIdx, prIotApRule->u2MatchFlag, + prIotApRule->ucVersion); + DBGLOG(INIT, TRACE, "IOTAP%d OUI:%02X:%02X:%02X\n", + ucRuleIdx, + prIotApRule->aVendorOui[0], + prIotApRule->aVendorOui[1], + prIotApRule->aVendorOui[2]); + DBGLOG(INIT, TRACE, "IOTAP%d Data:"MACSTR" Mask:"MACSTR"\n", + ucRuleIdx, MAC2STR(prIotApRule->aVendorData), + MAC2STR(prIotApRule->aVendorDataMask)); + DBGLOG(INIT, TRACE, "IOTAP%d aBssid:"MACSTR" Mask:"MACSTR"\n", + ucRuleIdx, MAC2STR(prIotApRule->aBssid), + MAC2STR(prIotApRule->aBssidMask)); + DBGLOG(INIT, TRACE, "IOTAP%d NSS:%X HT:%X Band:%X Act:%X\n", + ucRuleIdx, prIotApRule->ucNss, + prIotApRule->ucHtType, + prIotApRule->ucBand, + prIotApRule->ucAction); + } +} + + +void wlanCfgLoadIotApRule(IN struct ADAPTER *prAdapter) +{ + uint8_t ucCnt; + uint8_t *pOffset; + uint8_t *pCurTok; + uint8_t ucTokId; + uint8_t *pNexTok; + uint8_t ucStatus; + uint8_t aucCfgKey[WLAN_CFG_KEY_LEN_MAX]; + uint8_t aucCfgVal[WLAN_CFG_VALUE_LEN_MAX]; + struct WLAN_IOT_AP_RULE_T *prIotApRule = NULL; + int8_t aucEleSize[] = { + sizeof(prIotApRule->ucVersion), + sizeof(prIotApRule->aVendorOui), + sizeof(prIotApRule->aVendorData), + sizeof(prIotApRule->aVendorDataMask), + sizeof(prIotApRule->aBssid), + sizeof(prIotApRule->aBssidMask), + sizeof(prIotApRule->ucNss), + sizeof(prIotApRule->ucHtType), + sizeof(prIotApRule->ucBand), + sizeof(prIotApRule->ucAction) + }; + + ASSERT(prAdapter); + ASSERT(prAdapter->rIotApRule); + + DBGLOG(INIT, INFO, "IOTAP: Start Parsing Rules\n"); + for (ucCnt = 0; ucCnt < CFG_IOT_AP_RULE_MAX_CNT; ucCnt++) { + prIotApRule = &prAdapter->rIotApRule[ucCnt]; + kalMemSet(prIotApRule, '\0', sizeof(struct WLAN_IOT_AP_RULE_T)); + kalMemSet(aucCfgVal, '\0', WLAN_CFG_VALUE_LEN_MAX); + kalMemSet(aucCfgKey, '\0', WLAN_CFG_KEY_LEN_MAX); + pOffset = (uint8_t *)prIotApRule + + OFFSET_OF(struct WLAN_IOT_AP_RULE_T, ucVersion); + pCurTok = &aucCfgVal[0]; + pNexTok = &aucCfgVal[0]; + kalSprintf(aucCfgKey, "IOTAP%d", ucCnt); + ucStatus = wlanCfgGet(prAdapter, aucCfgKey, aucCfgVal, NULL, 0); + /*Skip empty rule*/ + if (ucStatus != WLAN_STATUS_SUCCESS) + continue; + + /*Rule String Check*/ + ucStatus = 0; + while (*pCurTok != '\0') { + if (*pCurTok == ':') + ucStatus++; + else if (wlanHexToNum(*pCurTok) == -1) { + ucStatus = -EINVAL; + break; + } + pCurTok++; + } + if (ucStatus != WLAN_IOT_AP_FG_MAX-1) { + DBGLOG(INIT, INFO, + "Invalid rule IOTAP%d with status %d\n", + ucCnt, ucStatus); + continue; + } + + for (ucTokId = 0; ucTokId < WLAN_IOT_AP_FG_MAX; ucTokId++) { + pCurTok = kalStrSep((char **)&pNexTok, ":"); + if (pCurTok) + ucStatus = wlanHexToArrayR(pCurTok, pOffset, + aucEleSize[ucTokId]); + else { + DBGLOG(INIT, TRACE, + "Invalid Tok IOTAP%d\n", ucCnt); + continue; + } + DBGLOG(INIT, TRACE, + "IOTAP%d tok:%d Str:%s status:%d len:%d flag:0x%x\n", + ucCnt, ucTokId, pCurTok, ucStatus, + aucEleSize[ucTokId], prIotApRule->u2MatchFlag); + + if (ucStatus) { + prIotApRule->u2MatchFlag |= BIT(ucTokId); + /*Record vendor data length*/ + if (ucTokId == WLAN_IOT_AP_FG_DATA) + prIotApRule->ucDataLen = ucStatus; + if (ucTokId == WLAN_IOT_AP_FG_DATA_MASK) + prIotApRule->ucDataMaskLen = ucStatus; + } + pOffset += aucEleSize[ucTokId]; + } + /*Rule Check*/ + if (prIotApRule->ucDataMaskLen && + prIotApRule->ucDataMaskLen != prIotApRule->ucDataLen) + prIotApRule->u2MatchFlag = 0; + if (prIotApRule->ucAction >= WLAN_IOT_AP_ACT_MAX) + prIotApRule->u2MatchFlag = 0; + if (prIotApRule->u2MatchFlag == 0) + DBGLOG(INIT, INFO, "Invalid Rule IOTAP%d\n", ucCnt); + } + +} +#endif + + + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is to re-assign tx resource based on firmware's report + * + * @param prAdapter Pointer of Adapter Data Structure + * + * @return WLAN_STATUS_SUCCESS + */ +/*----------------------------------------------------------------------------*/ +void wlanUpdateNicResourceInformation(IN struct ADAPTER + *prAdapter) +{ + /* + * 3 1. Query TX resource + */ + + /* information is not got from firmware, use default value */ + if (prAdapter->fgIsNicTxReousrceValid != TRUE) + return; + + /* 3 2. Setup resource parameters */ + if (prAdapter->nicTxReousrce.txResourceInit) + prAdapter->nicTxReousrce.txResourceInit(prAdapter); + else + wlanSetNicResourceParameters(prAdapter);/* 6632, 7668 ways*/ + + /* 3 3. Reset Tx resource */ + nicTxResetResource(prAdapter); + +#if QM_ADAPTIVE_TC_RESOURCE_CTRL + /* 3 4. Reset QM resource */ + qmResetTcControlResource( + prAdapter); /*CHIAHSUAN, TBD, NO PLE YET*/ +#endif + + halTxResourceResetHwTQCounter(prAdapter); +} + + +#if 0 +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is to SET network interface index for a network + * interface. + * A network interface is a TX/RX data port hooked to OS. + * + * @param prGlueInfo Pointer of prGlueInfo Data Structure + * @param ucNetInterfaceIndex Index of network interface + * @param ucBssIndex Index of BSS + * + * @return VOID + */ +/*----------------------------------------------------------------------------*/ +void wlanBindNetInterface(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucNetInterfaceIndex, + IN void *pvNetInterface) +{ + struct NET_INTERFACE_INFO *prNetIfInfo; + + prNetIfInfo = + &prGlueInfo->arNetInterfaceInfo[ucNetInterfaceIndex]; + + prNetIfInfo->pvNetInterface = pvNetInterface; +} +#endif +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is to SET BSS index for a network interface. + * A network interface is a TX/RX data port hooked to OS. + * + * @param prGlueInfo Pointer of prGlueInfo Data Structure + * @param ucNetInterfaceIndex Index of network interface + * @param ucBssIndex Index of BSS + * + * @return VOID + */ +/*----------------------------------------------------------------------------*/ +void wlanBindBssIdxToNetInterface(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucBssIndex, + IN void *pvNetInterface) +{ + struct NET_INTERFACE_INFO *prNetIfInfo; + + if (ucBssIndex >= prGlueInfo->prAdapter->ucHwBssIdNum) { + DBGLOG(INIT, ERROR, + "Array index out of bound, ucBssIndex=%u\n", ucBssIndex); + return; + } + + DBGLOG(INIT, LOUD, + "ucBssIndex = %d, pvNetInterface = %p\n", + ucBssIndex, pvNetInterface); + + prNetIfInfo = &prGlueInfo->arNetInterfaceInfo[ucBssIndex]; + + prNetIfInfo->ucBssIndex = ucBssIndex; + prNetIfInfo->pvNetInterface = pvNetInterface; + /* prGlueInfo->aprBssIdxToNetInterfaceInfo[ucBssIndex] = prNetIfInfo; */ +} + +#if 0 +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is to GET BSS index for a network interface. + * A network interface is a TX/RX data port hooked to OS. + * + * @param prGlueInfo Pointer of prGlueInfo Data Structure + * @param ucNetInterfaceIndex Index of network interface + * + * @return UINT_8 Index of BSS + */ +/*----------------------------------------------------------------------------*/ +uint8_t wlanGetBssIdxByNetInterface(IN struct GLUE_INFO + *prGlueInfo, IN void *pvNetInterface) +{ + uint8_t ucIdx = 0; + + ASSERT(prGlueInfo); + + for (ucIdx = 0; ucIdx < prGlueInfo->prAdapter->ucHwBssIdNum; + ucIdx++) { + if (prGlueInfo->arNetInterfaceInfo[ucIdx].pvNetInterface == + pvNetInterface) + break; + } + + return ucIdx; +} +#endif +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is to GET network interface for a BSS. + * A network interface is a TX/RX data port hooked to OS. + * + * @param prGlueInfo Pointer of prGlueInfo Data Structure + * @param ucBssIndex Index of BSS + * + * @return PVOID pointer of network interface structure + */ +/*----------------------------------------------------------------------------*/ +void *wlanGetNetInterfaceByBssIdx(IN struct GLUE_INFO + *prGlueInfo, IN uint8_t ucBssIndex) +{ + return prGlueInfo->arNetInterfaceInfo[ucBssIndex].pvNetInterface; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is to initialize WLAN feature options + * + * @param prAdapter Pointer of ADAPTER_T + * + * @return none + */ +/*----------------------------------------------------------------------------*/ +void wlanInitFeatureOption(IN struct ADAPTER *prAdapter) +{ + struct WIFI_VAR *prWifiVar = &prAdapter->rWifiVar; +#if QM_ADAPTIVE_TC_RESOURCE_CTRL + struct QUE_MGT *prQM = &prAdapter->rQM; +#endif + uint32_t u4TxHifRes = 0, u4Idx = 0; + uint32_t u4PlatformBoostCpuTh = 1; + + /* Feature options will be filled by config file */ + + prWifiVar->fgEnDefaultIotApRule = (uint8_t) wlanCfgGetUint32(prAdapter, + "EnDefaultIotApRule", + FEATURE_ENABLED); + + prWifiVar->ucQoS = (uint8_t) wlanCfgGetUint32(prAdapter, "Qos", + FEATURE_ENABLED); + + prWifiVar->ucStaHt = (uint8_t) wlanCfgGetUint32(prAdapter, "StaHT", + FEATURE_ENABLED); + prWifiVar->ucStaVht = (uint8_t) wlanCfgGetUint32(prAdapter, "StaVHT", + FEATURE_ENABLED); + +#if (CFG_SUPPORT_802_11AX == 1) + if (fgEfuseCtrlAxOn == 1) { + prWifiVar->ucStaHe = (uint8_t) + wlanCfgGetUint32(prAdapter, "StaHE", FEATURE_ENABLED); + prWifiVar->ucApHe = (uint8_t) + wlanCfgGetUint32(prAdapter, "ApHE", FEATURE_ENABLED); + prWifiVar->ucP2pGoHe = (uint8_t) + wlanCfgGetUint32(prAdapter, "P2pGoHE", + FEATURE_DISABLED); + prWifiVar->ucP2pGcHe = (uint8_t) + wlanCfgGetUint32(prAdapter, "P2pGcHE", + FEATURE_DISABLED); + + prWifiVar->ucApSelAxWeight = (uint8_t) + wlanCfgGetUint32(prAdapter, "ApSelAxWeight", AX_SEL_DEF_WEIGHT); + + prWifiVar->ucApSelAxScoreDiv = (uint8_t) + wlanCfgGetUint32(prAdapter, "ApSelAxScoreDiv", + AX_SEL_DEF_DIVIDER); + } +#endif + + prWifiVar->ucApHt = (uint8_t) wlanCfgGetUint32(prAdapter, "ApHT", + FEATURE_ENABLED); +#if CFG_TC1_FEATURE + prWifiVar->ucApVht = (uint8_t) wlanCfgGetUint32(prAdapter, "ApVHT", + FEATURE_FORCE_ENABLED); +#else + prWifiVar->ucApVht = (uint8_t) wlanCfgGetUint32(prAdapter, "ApVHT", + FEATURE_ENABLED); +#endif + + prWifiVar->ucP2pGoHt = (uint8_t) wlanCfgGetUint32(prAdapter, "P2pGoHT", + FEATURE_ENABLED); + prWifiVar->ucP2pGoVht = (uint8_t) wlanCfgGetUint32(prAdapter, + "P2pGoVHT", FEATURE_ENABLED); + + prWifiVar->ucP2pGcHt = (uint8_t) wlanCfgGetUint32(prAdapter, "P2pGcHT", + FEATURE_ENABLED); + prWifiVar->ucP2pGcVht = (uint8_t) wlanCfgGetUint32(prAdapter, + "P2pGcVHT", FEATURE_ENABLED); + + prWifiVar->ucAmpduRx = (uint8_t) wlanCfgGetUint32(prAdapter, "AmpduRx", + FEATURE_ENABLED); + prWifiVar->ucAmpduTx = (uint8_t) wlanCfgGetUint32(prAdapter, "AmpduTx", + FEATURE_ENABLED); + + prWifiVar->ucAmsduInAmpduRx = (uint8_t) wlanCfgGetUint32(prAdapter, + "AmsduInAmpduRx", FEATURE_ENABLED); + prWifiVar->ucAmsduInAmpduTx = (uint8_t) wlanCfgGetUint32(prAdapter, + "AmsduInAmpduTx", FEATURE_ENABLED); + prWifiVar->ucHtAmsduInAmpduRx = (uint8_t) wlanCfgGetUint32(prAdapter, + "HtAmsduInAmpduRx", FEATURE_ENABLED); + prWifiVar->ucHtAmsduInAmpduTx = (uint8_t) wlanCfgGetUint32(prAdapter, + "HtAmsduInAmpduTx", FEATURE_ENABLED); + prWifiVar->ucVhtAmsduInAmpduRx = (uint8_t) wlanCfgGetUint32(prAdapter, + "VhtAmsduInAmpduRx", FEATURE_ENABLED); + prWifiVar->ucVhtAmsduInAmpduTx = (uint8_t) wlanCfgGetUint32(prAdapter, + "VhtAmsduInAmpduTx", FEATURE_ENABLED); + + prWifiVar->ucTspec = (uint8_t) wlanCfgGetUint32(prAdapter, "Tspec", + FEATURE_DISABLED); + + prWifiVar->ucUapsd = (uint8_t) wlanCfgGetUint32(prAdapter, "Uapsd", + FEATURE_ENABLED); + prWifiVar->ucStaUapsd = (uint8_t) wlanCfgGetUint32(prAdapter, + "StaUapsd", FEATURE_DISABLED); + prWifiVar->ucApUapsd = (uint8_t) wlanCfgGetUint32(prAdapter, + "ApUapsd", FEATURE_DISABLED); + prWifiVar->ucP2pUapsd = (uint8_t) wlanCfgGetUint32(prAdapter, + "P2pUapsd", FEATURE_ENABLED); +#if (CFG_ENABLE_WIFI_DIRECT && CFG_MTK_ANDROID_WMT) + prWifiVar->u4RegP2pIfAtProbe = (uint8_t) wlanCfgGetUint32(prAdapter, + "RegP2pIfAtProbe", FEATURE_ENABLED); +#else + prWifiVar->u4RegP2pIfAtProbe = (uint8_t) wlanCfgGetUint32(prAdapter, + "RegP2pIfAtProbe", FEATURE_DISABLED); +#endif + prWifiVar->ucP2pShareMacAddr = (uint8_t) wlanCfgGetUint32(prAdapter, + "P2pShareMacAddr", FEATURE_DISABLED); + + prWifiVar->ucTxShortGI = (uint8_t) wlanCfgGetUint32(prAdapter, "SgiTx", + FEATURE_ENABLED); + prWifiVar->ucRxShortGI = (uint8_t) wlanCfgGetUint32(prAdapter, "SgiRx", + FEATURE_ENABLED); + + prWifiVar->ucTxLdpc = (uint8_t) wlanCfgGetUint32(prAdapter, "LdpcTx", + FEATURE_ENABLED); + prWifiVar->ucRxLdpc = (uint8_t) wlanCfgGetUint32(prAdapter, "LdpcRx", + FEATURE_ENABLED); + + prWifiVar->ucTxStbc = (uint8_t) wlanCfgGetUint32(prAdapter, "StbcTx", + FEATURE_ENABLED); + prWifiVar->ucRxStbc = (uint8_t) wlanCfgGetUint32(prAdapter, "StbcRx", + FEATURE_ENABLED); + prWifiVar->ucRxStbcNss = (uint8_t) wlanCfgGetUint32(prAdapter, + "StbcRxNss", 1); + + prWifiVar->ucTxGf = (uint8_t) wlanCfgGetUint32(prAdapter, "GfTx", + FEATURE_ENABLED); + prWifiVar->ucRxGf = (uint8_t) wlanCfgGetUint32(prAdapter, "GfRx", + FEATURE_ENABLED); + + prWifiVar->ucMCS32 = (uint8_t) wlanCfgGetUint32(prAdapter, "MCS32", + FEATURE_ENABLED); + +#if (CFG_SUPPORT_802_11AX == 1) + if (fgEfuseCtrlAxOn == 1) { + prWifiVar->ucHeAmsduInAmpduRx = (uint8_t) wlanCfgGetUint32(prAdapter, + "HeAmsduInAmpduRx", FEATURE_ENABLED); + prWifiVar->ucHeAmsduInAmpduTx = (uint8_t) wlanCfgGetUint32(prAdapter, + "HeAmsduInAmpduTx", FEATURE_ENABLED); + prWifiVar->ucTrigMacPadDur = (uint8_t) wlanCfgGetUint32(prAdapter, + "TrigMacPadDur", HE_CAP_TRIGGER_PAD_DURATION_16); + } +#endif + +#if (CFG_SUPPORT_TWT == 1) + prWifiVar->ucTWTRequester = (uint8_t) + wlanCfgGetUint32(prAdapter, "TWTRequester", FEATURE_ENABLED); + prWifiVar->ucTWTResponder = (uint8_t) + wlanCfgGetUint32(prAdapter, "TWTResponder", FEATURE_DISABLED); + prWifiVar->ucTWTStaBandBitmap = (uint8_t) + wlanCfgGetUint32(prAdapter, + "TWTStaBandBitmap", + BAND_2G4|BAND_5G); +#endif + + prWifiVar->ucSigTaRts = (uint8_t) wlanCfgGetUint32(prAdapter, + "SigTaRts", FEATURE_DISABLED); + prWifiVar->ucDynBwRts = (uint8_t) wlanCfgGetUint32(prAdapter, + "DynBwRts", FEATURE_DISABLED); + prWifiVar->ucTxopPsTx = (uint8_t) wlanCfgGetUint32(prAdapter, + "TxopPsTx", FEATURE_DISABLED); + + prWifiVar->ucStaHtBfee = (uint8_t) wlanCfgGetUint32(prAdapter, + "StaHTBfee", FEATURE_DISABLED); + prWifiVar->ucStaVhtBfee = (uint8_t) wlanCfgGetUint32(prAdapter, + "StaVHTBfee", FEATURE_ENABLED); + prWifiVar->ucStaVhtMuBfee = (uint8_t)wlanCfgGetUint32(prAdapter, + "StaVHTMuBfee", FEATURE_ENABLED); + prWifiVar->ucStaHtBfer = (uint8_t) wlanCfgGetUint32(prAdapter, + "StaHTBfer", FEATURE_DISABLED); + prWifiVar->ucStaVhtBfer = (uint8_t) wlanCfgGetUint32(prAdapter, + "StaVHTBfer", FEATURE_DISABLED); + +#if (CFG_SUPPORT_802_11AX == 1) + if (fgEfuseCtrlAxOn == 1) { + prWifiVar->ucStaHeBfee = (uint8_t) wlanCfgGetUint32(prAdapter, + "StaHEBfee", FEATURE_ENABLED); + } +#endif + + /* 0: disabled + * 1: Tx done event to driver + * 2: Tx status to FW only + */ + prWifiVar->ucDataTxDone = (uint8_t) wlanCfgGetUint32( + prAdapter, "DataTxDone", 0); + prWifiVar->ucDataTxRateMode = (uint8_t) wlanCfgGetUint32( + prAdapter, "DataTxRateMode", + DATA_RATE_MODE_AUTO); + prWifiVar->u4DataTxRateCode = wlanCfgGetUint32( + prAdapter, "DataTxRateCode", 0x0); + + prWifiVar->ucApWpsMode = (uint8_t) wlanCfgGetUint32( + prAdapter, "ApWpsMode", 0); + DBGLOG(INIT, TRACE, "ucApWpsMode = %u\n", prWifiVar->ucApWpsMode); + + prWifiVar->ucThreadScheduling = (uint8_t) wlanCfgGetUint32( + prAdapter, "ThreadSched", 0); + prWifiVar->ucThreadPriority = (uint8_t) wlanCfgGetUint32( + prAdapter, "ThreadPriority", + WLAN_THREAD_TASK_PRIORITY); + prWifiVar->cThreadNice = (int8_t) wlanCfgGetInt32( + prAdapter, "ThreadNice", + WLAN_THREAD_TASK_NICE); + + prAdapter->rQM.u4MaxForwardBufferCount = (uint32_t) wlanCfgGetUint32( + prAdapter, "ApForwardBufferCnt", + QM_FWD_PKT_QUE_THRESHOLD); + + /* AP channel setting + * 0: auto + */ + prWifiVar->ucApChannel = (uint8_t) wlanCfgGetUint32( + prAdapter, "ApChannel", 0); + + /* + * 0: SCN + * 1: SCA + * 2: RES + * 3: SCB + */ + prWifiVar->ucApSco = (uint8_t) wlanCfgGetUint32( + prAdapter, "ApSco", 0); + prWifiVar->ucP2pGoSco = (uint8_t) wlanCfgGetUint32( + prAdapter, "P2pGoSco", 0); + + /* Max bandwidth setting + * 0: 20Mhz + * 1: 40Mhz + * 2: 80Mhz + * 3: 160Mhz + * 4: 80+80Mhz + * Note: For VHT STA, BW 80Mhz is a must! + */ + prWifiVar->ucStaBandwidth = (uint8_t) wlanCfgGetUint32( + prAdapter, "StaBw", MAX_BW_160MHZ); + prWifiVar->ucSta2gBandwidth = (uint8_t) wlanCfgGetUint32( + prAdapter, "Sta2gBw", MAX_BW_20MHZ); + prWifiVar->ucSta5gBandwidth = (uint8_t) wlanCfgGetUint32( + prAdapter, "Sta5gBw", MAX_BW_80MHZ); + /* GC,GO */ + prWifiVar->ucP2p2gBandwidth = (uint8_t) wlanCfgGetUint32( + prAdapter, "P2p2gBw", MAX_BW_20MHZ); + prWifiVar->ucP2p5gBandwidth = (uint8_t) wlanCfgGetUint32( + prAdapter, "P2p5gBw", MAX_BW_80MHZ); + prWifiVar->ucApBandwidth = (uint8_t) wlanCfgGetUint32( + prAdapter, "ApBw", MAX_BW_160MHZ); + prWifiVar->ucAp2gBandwidth = (uint8_t) wlanCfgGetUint32( + prAdapter, "Ap2gBw", MAX_BW_20MHZ); + prWifiVar->ucAp5gBandwidth = (uint8_t) wlanCfgGetUint32( + prAdapter, "Ap5gBw", MAX_BW_80MHZ); + prWifiVar->ucApChnlDefFromCfg = (uint8_t) wlanCfgGetUint32( + prAdapter, "ApChnlDefFromCfg", FEATURE_ENABLED); + prWifiVar->ucApAllowHtVhtTkip = (uint8_t) wlanCfgGetUint32( + prAdapter, "ApAllowHtVhtTkip", + FEATURE_DISABLED); + + prWifiVar->ucNSS = (uint8_t) wlanCfgGetUint32 + (prAdapter, "Nss", 2); +#ifdef CFG_FORCE_AP1NSS + prWifiVar->ucAp5gNSS = (uint8_t)wlanCfgGetUint32 + (prAdapter, "Ap5gNss", 1); + prWifiVar->ucAp2gNSS = (uint8_t) wlanCfgGetUint32 + (prAdapter, "Ap2gNss", 1); +#else + prWifiVar->ucAp5gNSS = (uint8_t)wlanCfgGetUint32 + (prAdapter, "Ap5gNss", 2); + prWifiVar->ucAp2gNSS = (uint8_t) wlanCfgGetUint32 + (prAdapter, "Ap2gNss", 2); +#endif + prWifiVar->ucGo5gNSS = (uint8_t) wlanCfgGetUint32 + (prAdapter, "Go5gNss", 2); + prWifiVar->ucGo2gNSS = (uint8_t) wlanCfgGetUint32 + (prAdapter, "Go2gNss", 2); + + /* Max Rx MPDU length setting + * 0: 3k + * 1: 8k + * 2: 11k + */ + prWifiVar->ucRxMaxMpduLen = (uint8_t) wlanCfgGetUint32( + prAdapter, "RxMaxMpduLen", + VHT_CAP_INFO_MAX_MPDU_LEN_3K); + /* Max Tx AMSDU in AMPDU length *in BYTES* */ + prWifiVar->u4TxMaxAmsduInAmpduLen = wlanCfgGetUint32( + prAdapter, "TxMaxAmsduInAmpduLen", + 8192); + + prWifiVar->ucTcRestrict = (uint8_t) wlanCfgGetUint32( + prAdapter, "TcRestrict", 0xFF); + /* Max Tx dequeue limit: 0 => auto */ + prWifiVar->u4MaxTxDeQLimit = (uint32_t) wlanCfgGetUint32( + prAdapter, "MaxTxDeQLimit", 0x0); + prWifiVar->ucAlwaysResetUsedRes = (uint32_t) wlanCfgGetUint32( + prAdapter, "AlwaysResetUsedRes", 0x0); + +#if CFG_SUPPORT_MTK_SYNERGY + prWifiVar->ucMtkOui = (uint8_t) wlanCfgGetUint32( + prAdapter, "MtkOui", FEATURE_ENABLED); + prWifiVar->u4MtkOuiCap = (uint32_t) wlanCfgGetUint32( + prAdapter, "MtkOuiCap", 0); + prWifiVar->aucMtkFeature[0] = 0xff; + prWifiVar->aucMtkFeature[1] = 0xff; + prWifiVar->aucMtkFeature[2] = 0xff; + prWifiVar->aucMtkFeature[3] = 0xff; + prWifiVar->ucGbandProbe256QAM = (uint8_t) wlanCfgGetUint32( + prAdapter, "Probe256QAM", + FEATURE_ENABLED); +#endif +#if CFG_SUPPORT_VHT_IE_IN_2G + prWifiVar->ucVhtIeIn2g = (uint8_t) wlanCfgGetUint32( + prAdapter, "VhtIeIn2G", FEATURE_ENABLED); +#endif + prWifiVar->ucCmdRsvResource = (uint8_t) wlanCfgGetUint32( + prAdapter, "TxCmdRsv", + QM_CMD_RESERVED_THRESHOLD); + prWifiVar->u4MgmtQueueDelayTimeout = + (uint32_t) wlanCfgGetUint32(prAdapter, "TxMgmtQueTO", + QM_MGMT_QUEUED_TIMEOUT); /* ms */ + + /* Performance related */ + prWifiVar->u4HifIstLoopCount = (uint32_t) wlanCfgGetUint32( + prAdapter, "IstLoop", + CFG_IST_LOOP_COUNT); + prWifiVar->u4Rx2OsLoopCount = (uint32_t) wlanCfgGetUint32( + prAdapter, "Rx2OsLoop", 4); + prWifiVar->u4HifTxloopCount = (uint32_t) wlanCfgGetUint32( + prAdapter, "HifTxLoop", 1); + prWifiVar->u4TxFromOsLoopCount = (uint32_t) wlanCfgGetUint32( + prAdapter, "OsTxLoop", 1); + prWifiVar->u4TxRxLoopCount = (uint32_t) wlanCfgGetUint32( + prAdapter, "Rx2ReorderLoop", 1); + prWifiVar->u4TxIntThCount = (uint32_t) wlanCfgGetUint32( + prAdapter, "IstTxTh", + HIF_IST_TX_THRESHOLD); + + prWifiVar->u4NetifStopTh = (uint32_t) wlanCfgGetUint32( + prAdapter, "NetifStopTh", + CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD); + prWifiVar->u4NetifStartTh = (uint32_t) wlanCfgGetUint32( + prAdapter, "NetifStartTh", + CFG_TX_START_NETIF_PER_QUEUE_THRESHOLD); + prWifiVar->ucTxBaSize = (uint8_t) wlanCfgGetUint32( + prAdapter, "TxBaSize", 64); + prWifiVar->ucRxHtBaSize = (uint8_t) wlanCfgGetUint32( + prAdapter, "RxHtBaSize", 64); + prWifiVar->ucRxVhtBaSize = (uint8_t) wlanCfgGetUint32( + prAdapter, "RxVhtBaSize", 64); +#if (CFG_SUPPORT_802_11AX == 1) + if (fgEfuseCtrlAxOn == 1) { + prWifiVar->u2RxHeBaSize = (uint8_t) + wlanCfgGetUint32(prAdapter, "RxHeBaSize", 256); + prWifiVar->u2TxHeBaSize = (uint8_t) + wlanCfgGetUint32(prAdapter, "TxHeBaSize", 256); + } +#endif + +#if CFG_SUPPORT_SMART_GEAR + prWifiVar->ucSGCfg = (uint8_t) wlanCfgGetUint32( + prAdapter, "SGCfg", FEATURE_ENABLED); + /* 2.4G default is WF0 when enable SG SISO mode*/ + prWifiVar->ucSG24GFavorANT = (uint8_t) wlanCfgGetUint32( + prAdapter, "SG24GFavorANT", + FEATURE_DISABLED); + /* 5G default is WF1 when enable SG SISO mode*/ + prWifiVar->ucSG5GFavorANT = (uint8_t) wlanCfgGetUint32( + prAdapter, "SG5GFavorANT", + FEATURE_ENABLED); +#endif + /* Tx Buffer Management */ + prWifiVar->ucExtraTxDone = (uint32_t) wlanCfgGetUint32( + prAdapter, "ExtraTxDone", 1); + prWifiVar->ucTxDbg = (uint32_t) wlanCfgGetUint32(prAdapter, "TxDbg", 0); + + kalMemZero(prWifiVar->au4TcPageCount, + sizeof(prWifiVar->au4TcPageCount)); + + prWifiVar->au4TcPageCount[TC0_INDEX] = (uint32_t) wlanCfgGetUint32( + prAdapter, "Tc0Page", + NIC_TX_PAGE_COUNT_TC0); + prWifiVar->au4TcPageCount[TC1_INDEX] = (uint32_t) wlanCfgGetUint32( + prAdapter, "Tc1Page", + NIC_TX_PAGE_COUNT_TC1); + prWifiVar->au4TcPageCount[TC2_INDEX] = (uint32_t) wlanCfgGetUint32( + prAdapter, "Tc2Page", + NIC_TX_PAGE_COUNT_TC2); + prWifiVar->au4TcPageCount[TC3_INDEX] = (uint32_t) wlanCfgGetUint32( + prAdapter, "Tc3Page", + NIC_TX_PAGE_COUNT_TC3); + prWifiVar->au4TcPageCount[TC4_INDEX] = (uint32_t) wlanCfgGetUint32( + prAdapter, "Tc4Page", + NIC_TX_PAGE_COUNT_TC4); + prWifiVar->ucTxMsduQueue = (uint32_t) wlanCfgGetUint32( + prAdapter, "NicTxMsduQueue", 0); + + prWifiVar->ucTxMsduQueueInit = prWifiVar->ucTxMsduQueue; + + /* 1 resource for AC_BK(TC0_INDEX), AC_BE(TC1_INDEX) */ + /* 2 resource for AC_VI(TC2_INDEX) */ + /* 4 resource for AC_VO(TC3_INDEX) */ + /* 1 resource for MGMT(TC4_INDEX) & TC_NUM */ + u4TxHifRes = (uint32_t) wlanCfgGetUint32( + prAdapter, "TxHifResCtl", 0x00114211); + prWifiVar->u4TxHifRes = u4TxHifRes; + for (u4Idx = 0; u4Idx < TX_PORT_NUM && u4TxHifRes; u4Idx++) { + prAdapter->au4TxHifResCtl[u4Idx] = u4TxHifRes & BITS(0, 3); + u4TxHifRes = u4TxHifRes >> 4; + } + +#if QM_ADAPTIVE_TC_RESOURCE_CTRL + prQM->au4MinReservedTcResource[TC0_INDEX] = (uint32_t) wlanCfgGetUint32( + prAdapter, "Tc0MinRsv", + QM_MIN_RESERVED_TC0_RESOURCE); + prQM->au4MinReservedTcResource[TC1_INDEX] = (uint32_t) wlanCfgGetUint32( + prAdapter, "Tc1MinRsv", + QM_MIN_RESERVED_TC1_RESOURCE); + prQM->au4MinReservedTcResource[TC2_INDEX] = (uint32_t) wlanCfgGetUint32( + prAdapter, "Tc2MinRsv", + QM_MIN_RESERVED_TC2_RESOURCE); + prQM->au4MinReservedTcResource[TC3_INDEX] = (uint32_t) wlanCfgGetUint32( + prAdapter, "Tc3MinRsv", + QM_MIN_RESERVED_TC3_RESOURCE); + prQM->au4MinReservedTcResource[TC4_INDEX] = (uint32_t) wlanCfgGetUint32( + prAdapter, "Tc4MinRsv", + QM_MIN_RESERVED_TC4_RESOURCE); + + prQM->au4GuaranteedTcResource[TC0_INDEX] = (uint32_t) wlanCfgGetUint32( + prAdapter, "Tc0Grt", + QM_GUARANTEED_TC0_RESOURCE); + prQM->au4GuaranteedTcResource[TC1_INDEX] = + (uint32_t) wlanCfgGetUint32(prAdapter, "Tc1Grt", + QM_GUARANTEED_TC1_RESOURCE); + prQM->au4GuaranteedTcResource[TC2_INDEX] = + (uint32_t) wlanCfgGetUint32(prAdapter, "Tc2Grt", + QM_GUARANTEED_TC2_RESOURCE); + prQM->au4GuaranteedTcResource[TC3_INDEX] = (uint32_t) wlanCfgGetUint32( + prAdapter, "Tc3Grt", + QM_GUARANTEED_TC3_RESOURCE); + prQM->au4GuaranteedTcResource[TC4_INDEX] = (uint32_t) wlanCfgGetUint32( + prAdapter, "Tc4Grt", + QM_GUARANTEED_TC4_RESOURCE); + + prQM->u4TimeToAdjustTcResource = (uint32_t) wlanCfgGetUint32( + prAdapter, "TcAdjustTime", + QM_INIT_TIME_TO_ADJUST_TC_RSC); + prQM->u4TimeToUpdateQueLen = (uint32_t) wlanCfgGetUint32( + prAdapter, "QueLenUpdateTime", + QM_INIT_TIME_TO_UPDATE_QUE_LEN); + prQM->u4QueLenMovingAverage = (uint32_t) wlanCfgGetUint32( + prAdapter, "QueLenMovingAvg", + QM_QUE_LEN_MOVING_AVE_FACTOR); + prQM->u4ExtraReservedTcResource = (uint32_t) wlanCfgGetUint32( + prAdapter, "TcExtraRsv", + QM_EXTRA_RESERVED_RESOURCE_WHEN_BUSY); +#endif + + /* Stats log */ + prWifiVar->u4StatsLogTimeout = (uint32_t) wlanCfgGetUint32( + prAdapter, "StatsLogTO", + WLAN_TX_STATS_LOG_TIMEOUT); + prWifiVar->u4StatsLogDuration = (uint32_t) wlanCfgGetUint32( + prAdapter, "StatsLogDur", + WLAN_TX_STATS_LOG_DURATION); + + prWifiVar->ucDhcpTxDone = (uint8_t) wlanCfgGetUint32( + prAdapter, "DhcpTxDone", 1); + prWifiVar->ucArpTxDone = (uint8_t) wlanCfgGetUint32( + prAdapter, "ArpTxDone", 1); + + prWifiVar->ucMacAddrOverride = (uint8_t) wlanCfgGetInt32( + prAdapter, "MacOverride", 0); + if (wlanCfgGet(prAdapter, "MacAddr", prWifiVar->aucMacAddrStr, + "00:0c:e7:66:32:e1", 0)) + DBGLOG(INIT, TRACE, "get MacAddr fail, use defaul\n"); + + prWifiVar->ucCtiaMode = (uint8_t) wlanCfgGetUint32( + prAdapter, "CtiaMode", 0); + + /* Combine ucTpTestMode and ucSigmaTestMode in one flag */ + /* ucTpTestMode == 0, for normal driver */ + /* ucTpTestMode == 1, for pure throughput test mode (ex: RvR) */ + /* ucTpTestMode == 2, for sigma TGn/TGac/PMF */ + /* ucTpTestMode == 3, for sigma WMM PS */ + prWifiVar->ucTpTestMode = (uint8_t) wlanCfgGetUint32( + prAdapter, "TpTestMode", 0); + +#if 0 + prWifiVar->ucSigmaTestMode = (uint8_t) wlanCfgGetUint32( + prAdapter, "SigmaTestMode", 0); +#endif + +#if CFG_SUPPORT_DBDC + prWifiVar->eDbdcMode = (uint8_t) wlanCfgGetUint32( + prAdapter, "DbdcMode", + ENUM_DBDC_MODE_DYNAMIC); +#endif /*CFG_SUPPORT_DBDC*/ +#if (CFG_EFUSE_BUFFER_MODE_DELAY_CAL == 1) + prWifiVar->ucEfuseBufferModeCal = (uint8_t) wlanCfgGetUint32( + prAdapter, "EfuseBufferModeCal", 0); +#endif + prWifiVar->ucCalTimingCtrl = (uint8_t) wlanCfgGetUint32( + prAdapter, "CalTimingCtrl", + 0 /* power on full cal */); + prWifiVar->ucWow = (uint8_t) wlanCfgGetUint32( + prAdapter, "Wow", FEATURE_DISABLED); + prWifiVar->ucOffload = (uint8_t) wlanCfgGetUint32( + prAdapter, "Offload", FEATURE_DISABLED); + prWifiVar->ucAdvPws = (uint8_t) wlanCfgGetUint32( + prAdapter, "AdvPws", FEATURE_ENABLED); + prWifiVar->ucWowOnMdtim = (uint8_t) wlanCfgGetUint32( + prAdapter, "WowOnMdtim", 1); + prWifiVar->ucWowOffMdtim = (uint8_t) wlanCfgGetUint32( + prAdapter, "WowOffMdtim", 3); + +#if CFG_WOW_SUPPORT + prAdapter->rWowCtrl.fgWowEnable = (uint8_t) wlanCfgGetUint32( + prAdapter, "WowEnable", + FEATURE_ENABLED); + prAdapter->rWowCtrl.ucScenarioId = (uint8_t) wlanCfgGetUint32( + prAdapter, "WowScenarioId", 0); + prAdapter->rWowCtrl.ucBlockCount = (uint8_t) wlanCfgGetUint32( + prAdapter, "WowPinCnt", 1); + prAdapter->rWowCtrl.astWakeHif[0].ucWakeupHif = + (uint8_t) wlanCfgGetUint32( + prAdapter, "WowHif", + ENUM_HIF_TYPE_GPIO); + prAdapter->rWowCtrl.astWakeHif[0].ucGpioPin = + (uint8_t) wlanCfgGetUint32(prAdapter, "WowGpioPin", 0xFF); + prAdapter->rWowCtrl.astWakeHif[0].ucTriggerLvl = + (uint8_t) wlanCfgGetUint32(prAdapter, "WowTriigerLevel", 3); + prAdapter->rWowCtrl.astWakeHif[0].u4GpioInterval = + wlanCfgGetUint32(prAdapter, "GpioInterval", 0); +#endif + + /* SW Test Mode: Mainly used for Sigma */ + prWifiVar->u4SwTestMode = (uint8_t) wlanCfgGetUint32( + prAdapter, "SwTestMode", + ENUM_SW_TEST_MODE_NONE); + prWifiVar->ucCtrlFlagAssertPath = (uint8_t) wlanCfgGetUint32( + prAdapter, "AssertPath", + DBG_ASSERT_PATH_DEFAULT); + prWifiVar->ucCtrlFlagDebugLevel = (uint8_t) wlanCfgGetUint32( + prAdapter, "AssertLevel", + DBG_ASSERT_CTRL_LEVEL_DEFAULT); + prWifiVar->u4ScanCtrl = (uint8_t) wlanCfgGetUint32( + prAdapter, "ScanCtrl", + SCN_CTRL_DEFAULT_SCAN_CTRL); + prWifiVar->ucScanChannelListenTime = (uint8_t) wlanCfgGetUint32( + prAdapter, "ScnChListenTime", 0); + + /* Wake lock related configuration */ + prWifiVar->u4WakeLockRxTimeout = wlanCfgGetUint32( + prAdapter, "WakeLockRxTO", + WAKE_LOCK_RX_TIMEOUT); + prWifiVar->u4WakeLockThreadWakeup = wlanCfgGetUint32( + prAdapter, "WakeLockThreadTO", + WAKE_LOCK_THREAD_WAKEUP_TIMEOUT); + + prWifiVar->ucSmartRTS = (uint8_t) wlanCfgGetUint32( + prAdapter, "SmartRTS", 0); + prWifiVar->ePowerMode = (enum PARAM_POWER_MODE) wlanCfgGetUint32( + prAdapter, "PowerSave", + Param_PowerModeMax); + +#if 1 + /* add more cfg from RegInfo */ + prWifiVar->u4UapsdAcBmp = (uint32_t) wlanCfgGetUint32( + prAdapter, "UapsdAcBmp", 0); + prWifiVar->u4MaxSpLen = (uint32_t) wlanCfgGetUint32( + prAdapter, "MaxSpLen", 0); + prWifiVar->fgDisOnlineScan = (uint32_t) wlanCfgGetUint32( + prAdapter, "DisOnlineScan", 0); + prWifiVar->fgDisBcnLostDetection = (uint32_t) wlanCfgGetUint32( + prAdapter, "DisBcnLostDetection", 0); + prWifiVar->fgDisRoaming = (uint32_t) wlanCfgGetUint32( + prAdapter, "DisRoaming", 0); + prWifiVar->u4AisRoamingNumber = (uint32_t) wlanCfgGetUint32( + prAdapter, "AisRoamingNumber", + KAL_AIS_NUM); + prWifiVar->fgEnArpFilter = (uint32_t) wlanCfgGetUint32( + prAdapter, "EnArpFilter", + FEATURE_ENABLED); +#endif + + /* Driver Flow Control Dequeue Quota. Now is only used by DBDC */ + prWifiVar->uDeQuePercentEnable = + (uint8_t) wlanCfgGetUint32(prAdapter, "DeQuePercentEnable", 1); + prWifiVar->u4DeQuePercentVHT80Nss1 = + (uint32_t) wlanCfgGetUint32(prAdapter, "DeQuePercentVHT80NSS1", + QM_DEQUE_PERCENT_VHT80_NSS1); + prWifiVar->u4DeQuePercentVHT40Nss1 = + (uint32_t) wlanCfgGetUint32(prAdapter, "DeQuePercentVHT40NSS1", + QM_DEQUE_PERCENT_VHT40_NSS1); + prWifiVar->u4DeQuePercentVHT20Nss1 = + (uint32_t) wlanCfgGetUint32(prAdapter, "DeQuePercentVHT20NSS1", + QM_DEQUE_PERCENT_VHT20_NSS1); + prWifiVar->u4DeQuePercentHT40Nss1 = + (uint32_t) wlanCfgGetUint32(prAdapter, "DeQuePercentHT40NSS1", + QM_DEQUE_PERCENT_HT40_NSS1); + prWifiVar->u4DeQuePercentHT20Nss1 = + (uint32_t) wlanCfgGetUint32(prAdapter, "DeQuePercentHT20NSS1", + QM_DEQUE_PERCENT_HT20_NSS1); + + /* Support TDLS 5.5.4.2 optional case */ + prWifiVar->fgTdlsBufferSTASleep = (u_int8_t) wlanCfgGetUint32(prAdapter, + "TdlsBufferSTASleep", FEATURE_DISABLED); + /* Support USB Whole chip reset recover */ + prWifiVar->fgChipResetRecover = (u_int8_t) wlanCfgGetUint32(prAdapter, + "ChipResetRecover", FEATURE_DISABLED); + + prWifiVar->u4PerfMonUpdatePeriod = + (uint32_t) wlanCfgGetUint32(prAdapter, "PerfMonPeriod", + PERF_MON_UPDATE_INTERVAL); + + prWifiVar->u4PerfMonTpTh[0] = + (uint32_t) wlanCfgGetUint32(prAdapter, "PerfMonLv1", 20); + prWifiVar->u4PerfMonTpTh[1] = + (uint32_t) wlanCfgGetUint32(prAdapter, "PerfMonLv2", 50); + prWifiVar->u4PerfMonTpTh[2] = + (uint32_t) wlanCfgGetUint32(prAdapter, "PerfMonLv3", 100); + prWifiVar->u4PerfMonTpTh[3] = + (uint32_t) wlanCfgGetUint32(prAdapter, "PerfMonLv4", 180); + prWifiVar->u4PerfMonTpTh[4] = + (uint32_t) wlanCfgGetUint32(prAdapter, "PerfMonLv5", 250); + prWifiVar->u4PerfMonTpTh[5] = + (uint32_t) wlanCfgGetUint32(prAdapter, "PerfMonLv6", 300); + prWifiVar->u4PerfMonTpTh[6] = + (uint32_t) wlanCfgGetUint32(prAdapter, "PerfMonLv7", 400); + prWifiVar->u4PerfMonTpTh[7] = + (uint32_t) wlanCfgGetUint32(prAdapter, "PerfMonLv8", 500); + prWifiVar->u4PerfMonTpTh[8] = + (uint32_t) wlanCfgGetUint32(prAdapter, "PerfMonLv9", 600); + prWifiVar->u4PerfMonTpTh[9] = + (uint32_t) wlanCfgGetUint32(prAdapter, "PerfMonLv10", 700); + + u4PlatformBoostCpuTh = kalGetCpuBoostThreshold(); + prWifiVar->u4BoostCpuTh = + (uint32_t) wlanCfgGetUint32(prAdapter, "BoostCpuTh", + u4PlatformBoostCpuTh); + + prWifiVar->u4PerfMonPendingTh = (uint8_t)wlanCfgGetUint32(prAdapter, + "PerfMonPendingTh", 80); + + prWifiVar->u4PerfMonUsedTh = (uint8_t)wlanCfgGetUint32(prAdapter, + "PerfMonUsedTh", 80); + + /* for SER */ + prWifiVar->fgEnableSer = (uint8_t)wlanCfgGetUint32(prAdapter, + "SerEnable", FEATURE_ENABLED); + + prWifiVar->fgRstRecover = (uint8_t) wlanCfgGetUint32(prAdapter, + "RstRecover", FEATURE_DISABLED); + /* + * For Certification purpose,forcibly set + * "Compressed Steering Number of Beamformer Antennas Supported" to our + * own capability. + */ + prWifiVar->fgForceSTSNum = (uint8_t)wlanCfgGetUint32( + prAdapter, "ForceSTSNum", 0); +#if CFG_SUPPORT_IDC_CH_SWITCH + prWifiVar->ucChannelSwtichColdownTime = (uint8_t) wlanCfgGetUint32( + prAdapter, "CSACdTime", 60);/*Second*/ + prWifiVar->fgCrossBandSwitchEn = (uint8_t) wlanCfgGetUint32( + prAdapter, "SapCrossBandSwitchEn", 0); +#endif +#if CFG_SUPPORT_PERF_IND + prWifiVar->fgPerfIndicatorEn = (uint8_t) wlanCfgGetUint32( + prAdapter, "PerfIndicatorEn", 1); +#endif +#if CFG_SUPPORT_SPE_IDX_CONTROL + prWifiVar->ucSpeIdxCtrl = (uint8_t) wlanCfgGetUint32( + prAdapter, "SpeIdxCtrl", 2); +#endif + +#if CFG_SUPPORT_LOWLATENCY_MODE + prWifiVar->ucLowLatencyModeScan = (uint32_t) wlanCfgGetUint32( + prAdapter, "LowLatencyModeScan", FEATURE_ENABLED); + prWifiVar->ucLowLatencyModeReOrder = (uint32_t) wlanCfgGetUint32( + prAdapter, "LowLatencyModeReOrder", FEATURE_ENABLED); + prWifiVar->ucLowLatencyModePower = (uint32_t) wlanCfgGetUint32( + prAdapter, "LowLatencyModePower", FEATURE_DISABLED); + prWifiVar->ucLowLatencyPacketPriority = (uint32_t) wlanCfgGetUint32( + prAdapter, "LowLatencyPacketPriority", BITS(0, 1)); + prWifiVar->ucLowLatencyCmdData = (uint8_t) wlanCfgGetUint32( + prAdapter, "LowLatencyCmdData", FEATURE_ENABLED); + prWifiVar->ucLowLatencyCmdDataAllPacket = (uint8_t) wlanCfgGetUint32( + prAdapter, "LowLatencyCmdDataAllPacket", FEATURE_DISABLED); +#endif /* CFG_SUPPORT_LOWLATENCY_MODE */ + +#if CFG_SUPPORT_SPE_IDX_CONTROL + prWifiVar->ucSpeIdxCtrl = (uint8_t) wlanCfgGetUint32( + prAdapter, "SpeIdxCtrl", 2); +#endif + + prWifiVar->u4MTU = wlanCfgGetUint32(prAdapter, "MTU", 0); + +#if CFG_SUPPORT_RX_GRO + prWifiVar->ucGROFlushTimeout = (uint32_t) wlanCfgGetUint32( + prAdapter, "GROFlushTimeout", 1); + prWifiVar->ucGROEnableTput = (uint32_t) wlanCfgGetUint32( + prAdapter, "GROEnableTput", 6250000); +#endif + prWifiVar->ucMsduReportTimeout = + (uint8_t) wlanCfgGetUint32(prAdapter, + "MsduReportTimeout", NIC_MSDU_REPORT_DUMP_TIMEOUT); + +#if CFG_SUPPORT_DATA_STALL + prWifiVar->u4PerHighThreshole = (uint32_t) wlanCfgGetUint32( + prAdapter, "PerHighThreshole", + EVENT_PER_HIGH_THRESHOLD); + prWifiVar->u4TxLowRateThreshole = (uint32_t) wlanCfgGetUint32( + prAdapter, "TxLowRateThreshole", + EVENT_TX_LOW_RATE_THRESHOLD); + prWifiVar->u4RxLowRateThreshole = (uint32_t) wlanCfgGetUint32( + prAdapter, "RxLowRateThreshole", + EVENT_RX_LOW_RATE_THRESHOLD); + prWifiVar->u4ReportEventInterval = (uint32_t) wlanCfgGetUint32( + prAdapter, "ReportEventInterval", + REPORT_EVENT_INTERVAL); + prWifiVar->u4TrafficThreshold = (uint32_t) wlanCfgGetUint32( + prAdapter, "TrafficThreshold", + TRAFFIC_RHRESHOLD); +#endif + +#if CFG_SUPPORT_HE_ER + prWifiVar->u4ExtendedRange = (uint32_t) wlanCfgGetUint32( + prAdapter, "ExtendedRange", + FEATURE_ENABLED); +#endif + +#if (CFG_SUPPORT_P2PGO_ACS == 1) + prWifiVar->ucP2pGoACS = (uint32_t) wlanCfgGetUint32( + prAdapter, "P2pGoACSEnable", + FEATURE_DISABLED); + DBGLOG(INIT, TRACE, + "P2pGoACSEnable Setting:ACS Enable[%d]\n", + prAdapter->rWifiVar.ucP2pGoACS); + +#endif + + prWifiVar->fgReuseRSNIE = (uint32_t) wlanCfgGetUint32( + prAdapter, "ReuseRSNIE", + FEATURE_DISABLED); + +#if CFG_MTK_MCIF_WIFI_SUPPORT + wlanCfgSetUint32(prAdapter, "MddpSupport", FEATURE_ENABLED); +#endif + + prWifiVar->u4DiscoverTimeout = (uint32_t) wlanCfgGetUint32( + prAdapter, "DiscoverTimeout", ROAMING_DISCOVER_TIMEOUT_SEC); + + prWifiVar->u4InactiveTimeout = (uint32_t) wlanCfgGetUint32( + prAdapter, "InactiveTimeout", ROAMING_INACTIVE_TIMEOUT_SEC); + +#if ARP_MONITER_ENABLE + prWifiVar->uArpMonitorNumber = (uint32_t) wlanCfgGetUint32( + prAdapter, "ArpMonitorNumber", 20); + prWifiVar->uArpMonitorRxPktNum = (uint32_t) wlanCfgGetUint32( + prAdapter, "ArpMonitorRxPktNum", 0); +#endif /* ARP_MONITER_ENABLE */ +} + +void wlanCfgSetSwCtrl(IN struct ADAPTER *prAdapter) +{ + uint32_t i = 0; + int8_t aucKey[WLAN_CFG_VALUE_LEN_MAX]; + int8_t aucValue[WLAN_CFG_VALUE_LEN_MAX]; + + const int8_t acDelim[] = " "; + int8_t *pcPtr = NULL; + int8_t *pcDupValue = NULL; + uint32_t au4Values[2] = {}; + uint32_t u4TokenCount = 0; + uint32_t u4BufLen = 0; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + struct GLUE_INFO *prGlueInfo = prAdapter->prGlueInfo; + struct PARAM_CUSTOM_SW_CTRL_STRUCT rSwCtrlInfo; + int32_t u4Ret = 0; + + for (i = 0; i < WLAN_CFG_SET_SW_CTRL_LEN_MAX; i++) { + kalMemZero(aucValue, WLAN_CFG_VALUE_LEN_MAX); + kalMemZero(aucKey, WLAN_CFG_VALUE_LEN_MAX); + kalSprintf(aucKey, "SwCtrl%d", i); + + /* get nothing */ + if (wlanCfgGet(prAdapter, aucKey, aucValue, "", + 0) != WLAN_STATUS_SUCCESS) + continue; + if (!kalStrCmp(aucValue, "")) + continue; + + pcDupValue = aucValue; + u4TokenCount = 0; + + while ((pcPtr = kalStrSep((char **)(&pcDupValue), acDelim)) + != NULL) { + + if (!kalStrCmp(pcPtr, "")) + continue; + + /* au4Values[u4TokenCount] = kalStrtoul(pcPtr, NULL, 0); + */ + u4Ret = kalkStrtou32(pcPtr, 0, + &(au4Values[u4TokenCount])); + if (u4Ret) + DBGLOG(INIT, LOUD, + "parse au4Values error u4Ret=%d\n", + u4Ret); + u4TokenCount++; + + /* Only need 2 tokens */ + if (u4TokenCount >= 2) + break; + } + + if (u4TokenCount != 2) + continue; + + rSwCtrlInfo.u4Id = au4Values[0]; + rSwCtrlInfo.u4Data = au4Values[1]; + + rStatus = kalIoctl(prGlueInfo, wlanoidSetSwCtrlWrite, + &rSwCtrlInfo, sizeof(rSwCtrlInfo), + FALSE, FALSE, TRUE, &u4BufLen); + + } +} + +void wlanCfgSetChip(IN struct ADAPTER *prAdapter) +{ + uint32_t i = 0; + int8_t aucKey[WLAN_CFG_VALUE_LEN_MAX]; + int8_t aucValue[WLAN_CFG_VALUE_LEN_MAX]; + + uint32_t u4BufLen = 0; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + struct GLUE_INFO *prGlueInfo = prAdapter->prGlueInfo; + struct PARAM_CUSTOM_CHIP_CONFIG_STRUCT rChipConfigInfo; + + for (i = 0; i < WLAN_CFG_SET_CHIP_LEN_MAX; i++) { + kalMemZero(aucValue, WLAN_CFG_VALUE_LEN_MAX); + kalMemZero(aucKey, WLAN_CFG_VALUE_LEN_MAX); + kalSnprintf(aucKey, sizeof(aucKey), "SetChip%d", i); + + /* get nothing */ + if (wlanCfgGet(prAdapter, aucKey, aucValue, "", + 0) != WLAN_STATUS_SUCCESS) + continue; + if (!kalStrCmp(aucValue, "")) + continue; + + kalMemZero(&rChipConfigInfo, sizeof(rChipConfigInfo)); + + rChipConfigInfo.ucType = CHIP_CONFIG_TYPE_WO_RESPONSE; + rChipConfigInfo.u2MsgSize = kalStrnLen(aucValue, + WLAN_CFG_VALUE_LEN_MAX); + kalStrnCpy(rChipConfigInfo.aucCmd, aucValue, + CHIP_CONFIG_RESP_SIZE); + + rStatus = kalIoctl(prGlueInfo, wlanoidSetChipConfig, + &rChipConfigInfo, sizeof(rChipConfigInfo), + FALSE, FALSE, TRUE, &u4BufLen); + } +} + +#if (CFG_SUPPORT_CONNINFRA == 1) +/* Send kernel time to FW */ +void wlanCfgSetChipSyncTime(IN struct ADAPTER *prAdapter) +{ + struct timeval time; + unsigned int second, usecond; + + int8_t aucKey[WLAN_CFG_VALUE_LEN_MAX]; + int8_t aucValue[WLAN_CFG_VALUE_LEN_MAX]; + + uint32_t u4BufLen = 0; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + struct GLUE_INFO *prGlueInfo = prAdapter->prGlueInfo; + struct PARAM_CUSTOM_CHIP_CONFIG_STRUCT rChipConfigInfo; + + do_gettimeofday(&time); + second = (unsigned int)time.tv_sec; /* UTC time second unit */ + usecond = (unsigned int)time.tv_usec; /* UTC time microsecond unit */ + + kalMemZero(aucValue, WLAN_CFG_VALUE_LEN_MAX); + kalMemZero(aucKey, WLAN_CFG_VALUE_LEN_MAX); + kalSnprintf(aucKey, sizeof(aucKey), "SetChip"); + kalSnprintf(aucValue, sizeof(aucValue), + "SyncTime %u %u", second, usecond); + + DBGLOG(INIT, INFO, + "Sync kernel time, key=%s, value=%s", + aucKey, aucValue); + + kalMemZero(&rChipConfigInfo, sizeof(rChipConfigInfo)); + + rChipConfigInfo.ucType = CHIP_CONFIG_TYPE_WO_RESPONSE; + rChipConfigInfo.u2MsgSize = kalStrnLen(aucValue, + WLAN_CFG_VALUE_LEN_MAX); + kalStrnCpy(rChipConfigInfo.aucCmd, aucValue, + CHIP_CONFIG_RESP_SIZE); + + rStatus = kalIoctl(prGlueInfo, wlanoidSetChipConfig, + &rChipConfigInfo, sizeof(rChipConfigInfo), + FALSE, FALSE, TRUE, &u4BufLen); +} +#endif /* CFG_SUPPORT_CONNINFRA */ + +void wlanCfgSetDebugLevel(IN struct ADAPTER *prAdapter) +{ + uint32_t i = 0; + int8_t aucKey[WLAN_CFG_VALUE_LEN_MAX]; + int8_t aucValue[WLAN_CFG_VALUE_LEN_MAX]; + const int8_t acDelim[] = " "; + int8_t *pcDupValue; + int8_t *pcPtr = NULL; + + uint32_t au4Values[2] = {0}; + uint32_t u4TokenCount = 0; + uint32_t u4DbgIdx = 0; + uint32_t u4DbgMask = 0; + int32_t u4Ret = 0; + + for (i = 0; i < WLAN_CFG_SET_DEBUG_LEVEL_LEN_MAX; i++) { + kalMemZero(aucValue, WLAN_CFG_VALUE_LEN_MAX); + kalMemZero(aucKey, WLAN_CFG_VALUE_LEN_MAX); + kalSprintf(aucKey, "DbgLevel%d", i); + + /* get nothing */ + if (wlanCfgGet(prAdapter, aucKey, aucValue, "", + 0) != WLAN_STATUS_SUCCESS) + continue; + if (!kalStrCmp(aucValue, "")) + continue; + + pcDupValue = aucValue; + u4TokenCount = 0; + + while ((pcPtr = kalStrSep((char **)(&pcDupValue), + acDelim)) != NULL) { + + if (!kalStrCmp(pcPtr, "")) + continue; + + /* au4Values[u4TokenCount] = + * kalStrtoul(pcPtr, NULL, 0); + */ + u4Ret = kalkStrtou32(pcPtr, 0, + &(au4Values[u4TokenCount])); + if (u4Ret) + DBGLOG(INIT, LOUD, + "parse au4Values error u4Ret=%d\n", + u4Ret); + u4TokenCount++; + + /* Only need 2 tokens */ + if (u4TokenCount >= 2) + break; + } + + if (u4TokenCount != 2) + continue; + + u4DbgIdx = au4Values[0]; + u4DbgMask = au4Values[1]; + + /* DBG level special control */ + if (u4DbgIdx == 0xFFFFFFFF) { + wlanSetDriverDbgLevel(DBG_ALL_MODULE_IDX, u4DbgMask); + DBGLOG(INIT, INFO, + "Set ALL DBG module log level to [0x%02x]!", + (uint8_t) u4DbgMask); + } else if (u4DbgIdx == 0xFFFFFFFE) { + wlanDebugInit(); + DBGLOG(INIT, INFO, + "Reset ALL DBG module log level to DEFAULT!"); + } else if (u4DbgIdx < DBG_MODULE_NUM) { + wlanSetDriverDbgLevel(u4DbgIdx, u4DbgMask); + DBGLOG(INIT, INFO, + "Set DBG module[%u] log level to [0x%02x]!", + u4DbgIdx, (uint8_t) u4DbgMask); + } + } +} + +void wlanCfgSetCountryCode(IN struct ADAPTER *prAdapter) +{ + int8_t aucValue[WLAN_CFG_VALUE_LEN_MAX]; + + /* Apply COUNTRY Config */ + if (wlanCfgGet(prAdapter, "Country", aucValue, "", + 0) == WLAN_STATUS_SUCCESS) { + prAdapter->rWifiVar.u2CountryCode = + (((uint16_t) aucValue[0]) << 8) | + ((uint16_t) aucValue[1]); + + DBGLOG(INIT, TRACE, "u2CountryCode=0x%04x\n", + prAdapter->rWifiVar.u2CountryCode); + + if (regd_is_single_sku_en()) { + rlmDomainOidSetCountry(prAdapter, aucValue, 2); + return; + } + + /* Force to re-search country code in regulatory domains */ + prAdapter->prDomainInfo = NULL; + rlmDomainSendCmd(prAdapter); + + /* Update supported channel list in channel table based on + * current country domain + */ + wlanUpdateChannelTable(prAdapter->prGlueInfo); + } +} + +#if CFG_SUPPORT_CFG_FILE + +struct WLAN_CFG_ENTRY *wlanCfgGetEntry(IN struct ADAPTER *prAdapter, + const int8_t *pucKey, + uint32_t u4Flags) +{ + + struct WLAN_CFG_ENTRY *prWlanCfgEntry; + struct WLAN_CFG *prWlanCfg = NULL; + struct WLAN_CFG_REC *prWlanCfgRec = NULL; + struct WLAN_CFG *prWlanCfgEm = NULL; + uint32_t i, u32MaxNum; + + if (u4Flags == WLAN_CFG_REC) { + prWlanCfgRec = prAdapter->prWlanCfgRec; + u32MaxNum = WLAN_CFG_REC_ENTRY_NUM_MAX; + ASSERT(prWlanCfgRec); + } else if (u4Flags == WLAN_CFG_EM) { + prWlanCfgEm = prAdapter->prWlanCfgEm; + u32MaxNum = WLAN_CFG_REC_ENTRY_NUM_MAX; + ASSERT(prWlanCfgEm); + } else { + prWlanCfg = prAdapter->prWlanCfg; + u32MaxNum = WLAN_CFG_ENTRY_NUM_MAX; + ASSERT(prWlanCfg); + } + + + ASSERT(pucKey); + + prWlanCfgEntry = NULL; + + for (i = 0; i < u32MaxNum; i++) { + if (u4Flags == WLAN_CFG_REC) + prWlanCfgEntry = &prWlanCfgRec->arWlanCfgBuf[i]; + else if (u4Flags == WLAN_CFG_EM) + prWlanCfgEntry = &prWlanCfgEm->arWlanCfgBuf[i]; + else + prWlanCfgEntry = &prWlanCfg->arWlanCfgBuf[i]; + + if (prWlanCfgEntry->aucKey[0] != '\0') { + if (kalStrnCmp(pucKey, prWlanCfgEntry->aucKey, + WLAN_CFG_KEY_LEN_MAX - 1) == 0) + return prWlanCfgEntry; + } + } + + return NULL; + +} + +uint32_t wlanCfgGetTotalCfgNum( + IN struct ADAPTER *prAdapter, uint32_t flag) +{ + uint32_t i = 0; + struct WLAN_CFG_ENTRY *prWlanCfgEntry; + uint32_t count = 0; + + for (i = 0; i < WLAN_CFG_REC_ENTRY_NUM_MAX; i++) { + prWlanCfgEntry = wlanCfgGetEntryByIndex(prAdapter, i, flag); + + if ((!prWlanCfgEntry) || (prWlanCfgEntry->aucKey[0] == '\0')) + break; + + count++; + } + return count; +} + + +struct WLAN_CFG_ENTRY *wlanCfgGetEntryByIndex( + IN struct ADAPTER *prAdapter, const uint8_t ucIdx, + uint32_t flag) +{ + + struct WLAN_CFG_ENTRY *prWlanCfgEntry; + struct WLAN_CFG *prWlanCfg; + struct WLAN_CFG_REC *prWlanCfgRec; + struct WLAN_CFG *prWlanCfgEm; + + + prWlanCfg = prAdapter->prWlanCfg; + prWlanCfgRec = prAdapter->prWlanCfgRec; + prWlanCfgEm = prAdapter->prWlanCfgEm; + + ASSERT(prWlanCfg); + ASSERT(prWlanCfgRec); + ASSERT(prWlanCfgEm); + + + prWlanCfgEntry = NULL; + + if (flag == WLAN_CFG_REC) + prWlanCfgEntry = &prWlanCfgRec->arWlanCfgBuf[ucIdx]; + else if (flag == WLAN_CFG_EM) + prWlanCfgEntry = &prWlanCfgEm->arWlanCfgBuf[ucIdx]; + else + prWlanCfgEntry = &prWlanCfg->arWlanCfgBuf[ucIdx]; + + if (prWlanCfgEntry->aucKey[0] != '\0') { + DBGLOG(INIT, LOUD, "get Index(%d) saved key %s\n", ucIdx, + prWlanCfgEntry->aucKey); + return prWlanCfgEntry; + } + + DBGLOG(INIT, TRACE, + "wifi config there is no entry at index(%d)\n", ucIdx); + return NULL; + +} + + + +uint32_t wlanCfgGet(IN struct ADAPTER *prAdapter, + const int8_t *pucKey, int8_t *pucValue, int8_t *pucValueDef, + uint32_t u4Flags) +{ + + struct WLAN_CFG_ENTRY *prWlanCfgEntry; + + ASSERT(pucValue); + + /* Find the exist */ + prWlanCfgEntry = wlanCfgGetEntry(prAdapter, pucKey, u4Flags); + + if (prWlanCfgEntry) { + kalStrnCpy(pucValue, prWlanCfgEntry->aucValue, + WLAN_CFG_VALUE_LEN_MAX - 1); + return WLAN_STATUS_SUCCESS; + } + if (pucValueDef) + kalStrnCpy(pucValue, pucValueDef, + WLAN_CFG_VALUE_LEN_MAX - 1); + return WLAN_STATUS_FAILURE; + + +} + +void wlanCfgRecordValue(IN struct ADAPTER *prAdapter, + const int8_t *pucKey, uint32_t u4Value) +{ + struct WLAN_CFG_ENTRY *prWlanCfgEntry; + uint8_t aucBuf[WLAN_CFG_VALUE_LEN_MAX]; + + prWlanCfgEntry = wlanCfgGetEntry(prAdapter, pucKey, WLAN_CFG_REC); + + kalMemZero(aucBuf, sizeof(aucBuf)); + + kalSnprintf(aucBuf, WLAN_CFG_VALUE_LEN_MAX, "0x%x", + (unsigned int)u4Value); + + wlanCfgSet(prAdapter, pucKey, aucBuf, WLAN_CFG_REC); +} + + + +uint32_t wlanCfgGetUint32(IN struct ADAPTER *prAdapter, + const int8_t *pucKey, uint32_t u4ValueDef) +{ + struct WLAN_CFG_ENTRY *prWlanCfgEntry; + struct WLAN_CFG *prWlanCfg; + uint32_t u4Value; + int32_t u4Ret; + + prWlanCfg = prAdapter->prWlanCfg; + + ASSERT(prWlanCfg); + + u4Value = u4ValueDef; + /* Find the exist */ + prWlanCfgEntry = wlanCfgGetEntry(prAdapter, pucKey, WLAN_CFG_DEFAULT); + + if (prWlanCfgEntry) { + /* u4Ret = kalStrtoul(prWlanCfgEntry->aucValue, NULL, 0); */ + u4Ret = kalkStrtou32(prWlanCfgEntry->aucValue, 0, &u4Value); + if (u4Ret) + DBGLOG(INIT, LOUD, "parse aucValue error u4Ret=%d\n", + u4Ret); + } + + wlanCfgRecordValue(prAdapter, pucKey, u4Value); + + return u4Value; +} + +int32_t wlanCfgGetInt32(IN struct ADAPTER *prAdapter, + const int8_t *pucKey, int32_t i4ValueDef) +{ + struct WLAN_CFG_ENTRY *prWlanCfgEntry; + struct WLAN_CFG *prWlanCfg; + int32_t i4Value = 0; + int32_t i4Ret = 0; + + prWlanCfg = prAdapter->prWlanCfg; + + ASSERT(prWlanCfg); + + i4Value = i4ValueDef; + /* Find the exist */ + prWlanCfgEntry = wlanCfgGetEntry(prAdapter, pucKey, WLAN_CFG_DEFAULT); + + if (prWlanCfgEntry) { + /* i4Ret = kalStrtol(prWlanCfgEntry->aucValue, NULL, 0); */ + i4Ret = kalkStrtos32(prWlanCfgEntry->aucValue, 0, &i4Value); + if (i4Ret) + DBGLOG(INIT, LOUD, "parse aucValue error i4Ret=%d\n", + i4Ret); + } + + wlanCfgRecordValue(prAdapter, pucKey, (uint32_t)i4Value); + + return i4Value; +} + +uint32_t wlanCfgSet(IN struct ADAPTER *prAdapter, + const int8_t *pucKey, int8_t *pucValue, uint32_t u4Flags) +{ + + struct WLAN_CFG_ENTRY *prWlanCfgEntry; + struct WLAN_CFG *prWlanCfg = NULL; + struct WLAN_CFG *prWlanCfgEm = NULL; + struct WLAN_CFG_REC *prWlanCfgRec = NULL; + uint32_t u4EntryIndex; + uint32_t i; + uint8_t ucExist; + + + ASSERT(pucKey); + + DBGLOG(INIT, LOUD, "[%s]:[%s] OP:%d\n", pucKey, pucValue, u4Flags); + + /* Find the exist */ + ucExist = 0; + if (u4Flags == WLAN_CFG_REC) { + prWlanCfgEntry = + wlanCfgGetEntry(prAdapter, pucKey, WLAN_CFG_REC); + prWlanCfgRec = prAdapter->prWlanCfgRec; + ASSERT(prWlanCfgRec); + } else if (u4Flags == WLAN_CFG_EM) { + prWlanCfgEntry = + wlanCfgGetEntry(prAdapter, pucKey, WLAN_CFG_EM); + prWlanCfgEm = prAdapter->prWlanCfgEm; + ASSERT(prWlanCfgEm); + } else { + prWlanCfgEntry = + wlanCfgGetEntry(prAdapter, pucKey, WLAN_CFG_DEFAULT); + prWlanCfg = prAdapter->prWlanCfg; + ASSERT(prWlanCfg); + } + + if (!prWlanCfgEntry) { + /* Find the empty */ + for (i = 0; i < WLAN_CFG_ENTRY_NUM_MAX; i++) { + if (u4Flags == WLAN_CFG_REC) + prWlanCfgEntry = &prWlanCfgRec->arWlanCfgBuf[i]; + else if (u4Flags == WLAN_CFG_EM) + prWlanCfgEntry = &prWlanCfgEm->arWlanCfgBuf[i]; + else + prWlanCfgEntry = &prWlanCfg->arWlanCfgBuf[i]; + + if (prWlanCfgEntry->aucKey[0] == '\0') + break; + } + + u4EntryIndex = i; + if (u4EntryIndex < WLAN_CFG_ENTRY_NUM_MAX) { + if (u4Flags == WLAN_CFG_REC) + prWlanCfgEntry = + &prWlanCfgRec->arWlanCfgBuf[u4EntryIndex]; + else if (u4Flags == WLAN_CFG_EM) + prWlanCfgEntry = + &prWlanCfgEm->arWlanCfgBuf[u4EntryIndex]; + else + prWlanCfgEntry = + &prWlanCfg->arWlanCfgBuf[u4EntryIndex]; + kalMemZero(prWlanCfgEntry, + sizeof(struct WLAN_CFG_ENTRY)); + } else { + prWlanCfgEntry = NULL; + DBGLOG(INIT, ERROR, + "wifi config there is no empty entry\n"); + } + } /* !prWlanCfgEntry */ + else + ucExist = 1; + + if (prWlanCfgEntry) { + if (ucExist == 0) { + kalStrnCpy(prWlanCfgEntry->aucKey, pucKey, + WLAN_CFG_KEY_LEN_MAX - 1); + prWlanCfgEntry->aucKey[WLAN_CFG_KEY_LEN_MAX - 1] = '\0'; + } + if (pucValue && pucValue[0] != '\0') { + kalStrnCpy(prWlanCfgEntry->aucValue, pucValue, + WLAN_CFG_VALUE_LEN_MAX - 1); + prWlanCfgEntry->aucValue[WLAN_CFG_VALUE_LEN_MAX - 1] = + '\0'; + + if (ucExist) { + if (prWlanCfgEntry->pfSetCb) + prWlanCfgEntry->pfSetCb(prAdapter, + prWlanCfgEntry->aucKey, + prWlanCfgEntry->aucValue, + prWlanCfgEntry->pPrivate, 0); + } + } else { + /* Call the pfSetCb if value is empty ? */ + /* remove the entry if value is empty */ + kalMemZero(prWlanCfgEntry, + sizeof(struct WLAN_CFG_ENTRY)); + } + + } + /* prWlanCfgEntry */ + if (prWlanCfgEntry) { + return WLAN_STATUS_SUCCESS; + } + if (pucKey) + DBGLOG(INIT, ERROR, "Set wifi config error key \'%s\'\n", + pucKey); + + if (pucValue) + DBGLOG(INIT, ERROR, "Set wifi config error value \'%s\'\n", + pucValue); + + return WLAN_STATUS_FAILURE; + + +} + +uint32_t +wlanCfgSetCb(IN struct ADAPTER *prAdapter, + const int8_t *pucKey, WLAN_CFG_SET_CB pfSetCb, + void *pPrivate, uint32_t u4Flags) +{ + + struct WLAN_CFG_ENTRY *prWlanCfgEntry; + struct WLAN_CFG *prWlanCfg; + + prWlanCfg = prAdapter->prWlanCfg; + ASSERT(prWlanCfg); + + /* Find the exist */ + prWlanCfgEntry = wlanCfgGetEntry(prAdapter, pucKey, FALSE); + + if (prWlanCfgEntry) { + prWlanCfgEntry->pfSetCb = pfSetCb; + prWlanCfgEntry->pPrivate = pPrivate; + } + + if (prWlanCfgEntry) + return WLAN_STATUS_SUCCESS; + else + return WLAN_STATUS_FAILURE; + +} + +uint32_t wlanCfgSetUint32(IN struct ADAPTER *prAdapter, + const int8_t *pucKey, uint32_t u4Value) +{ + + struct WLAN_CFG *prWlanCfg; + uint8_t aucBuf[WLAN_CFG_VALUE_LEN_MAX]; + + prWlanCfg = prAdapter->prWlanCfg; + + ASSERT(prWlanCfg); + + kalMemZero(aucBuf, sizeof(aucBuf)); + + kalSnprintf(aucBuf, WLAN_CFG_VALUE_LEN_MAX, "0x%x", + (unsigned int)u4Value); + + return wlanCfgSet(prAdapter, pucKey, aucBuf, WLAN_CFG_DEFAULT); +} + +enum { + STATE_EOF = 0, + STATE_TEXT = 1, + STATE_NEWLINE = 2 +}; + +struct WLAN_CFG_PARSE_STATE_S { + int8_t *ptr; + int8_t *text; +#if CFG_SUPPORT_EASY_DEBUG + uint32_t textsize; +#endif + int32_t nexttoken; + uint32_t maxSize; +}; + +int32_t wlanCfgFindNextToken(struct WLAN_CFG_PARSE_STATE_S + *state) +{ + int8_t *x = state->ptr; + int8_t *s; + + if (state->nexttoken) { + int32_t t = state->nexttoken; + + state->nexttoken = 0; + return t; + } + + for (;;) { + switch (*x) { + case 0: + state->ptr = x; + return STATE_EOF; + case '\n': + x++; + state->ptr = x; + return STATE_NEWLINE; + case ' ': + case ',': + /*case ':': should not including : , mac addr would be fail*/ + case '\t': + case '\r': + x++; + continue; + case '#': + while (*x && (*x != '\n')) + x++; + if (*x == '\n') { + state->ptr = x + 1; + return STATE_NEWLINE; + } + state->ptr = x; + return STATE_EOF; + + default: + goto text; + } + } + +textdone: + state->ptr = x; + *s = 0; + return STATE_TEXT; +text: + state->text = s = x; +textresume: + for (;;) { + switch (*x) { + case 0: + goto textdone; + case ' ': + case ',': + /* case ':': */ + case '\t': + case '\r': + x++; + goto textdone; + case '\n': + state->nexttoken = STATE_NEWLINE; + x++; + goto textdone; + case '"': + x++; + for (;;) { + switch (*x) { + case 0: + /* unterminated quoted thing */ + state->ptr = x; + return STATE_EOF; + case '"': + x++; + goto textresume; + default: + *s++ = *x++; + } + } + break; + case '\\': + x++; + switch (*x) { + case 0: + goto textdone; + case 'n': + *s++ = '\n'; + break; + case 'r': + *s++ = '\r'; + break; + case 't': + *s++ = '\t'; + break; + case '\\': + *s++ = '\\'; + break; + case '\r': + /* \ -> line continuation */ + if (x[1] != '\n') { + x++; + continue; + } + case '\n': + /* \ -> line continuation */ + x++; + /* eat any extra whitespace */ + while ((*x == ' ') || (*x == '\t')) + x++; + continue; + default: + /* unknown escape -- just copy */ + *s++ = *x++; + } + continue; + default: + *s++ = *x++; +#if CFG_SUPPORT_EASY_DEBUG + state->textsize++; +#endif + } + } + return STATE_EOF; +} + +uint32_t wlanCfgParseArgument(int8_t *cmdLine, + int32_t *argc, int8_t *argv[]) +{ + struct WLAN_CFG_PARSE_STATE_S state; + int8_t **args; + int32_t nargs; + + if (cmdLine == NULL || argc == NULL || argv == NULL) { + DBGLOG(INIT, ERROR, "parameter is NULL: %p, %p, %p\n", + cmdLine, argc, argv); + return WLAN_STATUS_FAILURE; + } + args = argv; + nargs = 0; + state.ptr = cmdLine; + state.nexttoken = 0; + state.maxSize = 0; +#if CFG_SUPPORT_EASY_DEBUG + state.textsize = 0; +#endif + + if (kalStrnLen(cmdLine, 512) >= 512) { + DBGLOG(INIT, ERROR, "cmdLine >= 512\n"); + return WLAN_STATUS_FAILURE; + } + + for (;;) { + switch (wlanCfgFindNextToken(&state)) { + case STATE_EOF: + goto exit; + case STATE_NEWLINE: + goto exit; + case STATE_TEXT: + if (nargs < WLAN_CFG_ARGV_MAX) + args[nargs++] = state.text; + break; + } + } + +exit: + *argc = nargs; + return WLAN_STATUS_SUCCESS; +} + +#if CFG_WOW_SUPPORT +uint32_t wlanCfgParseArgumentLong(int8_t *cmdLine, + int32_t *argc, int8_t *argv[]) +{ + struct WLAN_CFG_PARSE_STATE_S state; + int8_t **args; + int32_t nargs; + + if (cmdLine == NULL || argc == NULL || argv == NULL) { + DBGLOG(INIT, ERROR, "parameter is NULL: %p, %p, %p\n", + cmdLine, argc, argv); + return WLAN_STATUS_FAILURE; + } + args = argv; + nargs = 0; + state.ptr = cmdLine; + state.nexttoken = 0; + state.maxSize = 0; +#if CFG_SUPPORT_EASY_DEBUG + state.textsize = 0; +#endif + + if (kalStrnLen(cmdLine, 512) >= 512) { + DBGLOG(INIT, ERROR, "cmdLine >= 512\n"); + return WLAN_STATUS_FAILURE; + } + + for (;;) { + switch (wlanCfgFindNextToken(&state)) { + case STATE_EOF: + goto exit; + case STATE_NEWLINE: + goto exit; + case STATE_TEXT: + if (nargs < WLAN_CFG_ARGV_MAX_LONG) + args[nargs++] = state.text; + break; + } + } + +exit: + *argc = nargs; + return WLAN_STATUS_SUCCESS; +} +#endif + +uint32_t +wlanCfgParseAddEntry(IN struct ADAPTER *prAdapter, + uint8_t *pucKeyHead, uint8_t *pucKeyTail, + uint8_t *pucValueHead, uint8_t *pucValueTail) +{ + + uint8_t aucKey[WLAN_CFG_KEY_LEN_MAX]; + uint8_t aucValue[WLAN_CFG_VALUE_LEN_MAX]; + uint32_t u4Len; + + kalMemZero(aucKey, sizeof(aucKey)); + kalMemZero(aucValue, sizeof(aucValue)); + + if ((pucKeyHead == NULL) + || (pucValueHead == NULL) + ) + return WLAN_STATUS_FAILURE; + + if (pucKeyTail) { + if (pucKeyHead > pucKeyTail) + return WLAN_STATUS_FAILURE; + u4Len = pucKeyTail - pucKeyHead + 1; + } else + u4Len = kalStrnLen(pucKeyHead, WLAN_CFG_KEY_LEN_MAX - 1); + + if (u4Len >= WLAN_CFG_KEY_LEN_MAX) + u4Len = WLAN_CFG_KEY_LEN_MAX - 1; + + kalStrnCpy(aucKey, pucKeyHead, u4Len); + + if (pucValueTail) { + if (pucValueHead > pucValueTail) + return WLAN_STATUS_FAILURE; + u4Len = pucValueTail - pucValueHead + 1; + } else + u4Len = kalStrnLen(pucValueHead, + WLAN_CFG_VALUE_LEN_MAX - 1); + + if (u4Len >= WLAN_CFG_VALUE_LEN_MAX) + u4Len = WLAN_CFG_VALUE_LEN_MAX - 1; + + kalStrnCpy(aucValue, pucValueHead, u4Len); + + return wlanCfgSet(prAdapter, aucKey, aucValue, WLAN_CFG_DEFAULT); +} + +enum { + WAIT_KEY_HEAD = 0, + WAIT_KEY_TAIL, + WAIT_VALUE_HEAD, + WAIT_VALUE_TAIL, + WAIT_COMMENT_TAIL +}; + +#if CFG_SUPPORT_EASY_DEBUG + +uint32_t wlanCfgParseToFW(int8_t **args, int8_t *args_size, + uint8_t nargs, int8_t *buffer, uint8_t times) +{ + uint8_t *data = NULL; + char ch; + int32_t i = 0, j = 0; + uint32_t bufferindex = 0, base = 0; + uint32_t sum = 0, startOffset = 0; + struct CMD_FORMAT_V1 cmd_v1; + + memset(&cmd_v1, 0, sizeof(struct CMD_FORMAT_V1)); + +#if 0 + cmd_v1.itemType = kalAtoi(*args[ED_ITEMTYPE_SITE]); +#else + cmd_v1.itemType = ITEM_TYPE_DEC; +#endif + if (buffer == NULL || + args_size[ED_STRING_SITE] == 0 || + args_size[ED_VALUE_SITE] == 0 || + (cmd_v1.itemType < ITEM_TYPE_DEC + || cmd_v1.itemType > ITEM_TYPE_STR)) { + DBGLOG(INIT, ERROR, "cfg args wrong\n"); + return WLAN_STATUS_FAILURE; + } + + cmd_v1.itemStringLength = args_size[ED_STRING_SITE]; + strncpy(cmd_v1.itemString, args[ED_STRING_SITE], + cmd_v1.itemStringLength); + DBGLOG(INIT, INFO, "itemString:"); + for (i = 0; i < cmd_v1.itemStringLength; i++) + DBGLOG(INIT, INFO, "%c", cmd_v1.itemString[i]); + DBGLOG(INIT, INFO, "\n"); + + DBGLOG(INIT, INFO, "cmd_v1.itemType = %d\n", + cmd_v1.itemType); + if (cmd_v1.itemType == ITEM_TYPE_DEC + || cmd_v1.itemType == ITEM_TYPE_HEX) { + data = args[ED_VALUE_SITE]; + + switch (cmd_v1.itemType) { + case ITEM_TYPE_DEC: + base = 10; + startOffset = 0; + break; + case ITEM_TYPE_HEX: + ch = *data; + if (args_size[ED_VALUE_SITE] < 3 || ch != '0') { + DBGLOG(INIT, WARN, + "Hex args must have prefix '0x'\n"); + return WLAN_STATUS_FAILURE; + } + + data++; + ch = *data; + if (ch != 'x' && ch != 'X') { + DBGLOG(INIT, WARN, + "Hex args must have prefix '0x'\n"); + return WLAN_STATUS_FAILURE; + } + data++; + base = 16; + startOffset = 2; + break; + } + + for (j = args_size[ED_VALUE_SITE] - 1 - startOffset; j >= 0; + j--) { + sum = sum * base + kalAtoi(*data); + DBGLOG(INIT, WARN, "size:%d data[%d]=%u, sum=%u\n", + args_size[ED_VALUE_SITE], j, + kalAtoi(*data), sum); + + data++; + } + + bufferindex = 0; + do { + cmd_v1.itemValue[bufferindex++] = sum & 0xFF; + sum = sum >> 8; + } while (sum > 0); + cmd_v1.itemValueLength = bufferindex; + } else if (cmd_v1.itemType == ITEM_TYPE_STR) { + cmd_v1.itemValueLength = args_size[ED_VALUE_SITE]; + strncpy(cmd_v1.itemValue, args[ED_VALUE_SITE], + cmd_v1.itemValueLength); + } + + DBGLOG(INIT, INFO, "Length = %d itemValue:", + cmd_v1.itemValueLength); + for (i = cmd_v1.itemValueLength - 1; i >= 0; i--) + DBGLOG(INIT, ERROR, "%d,", cmd_v1.itemValue[i]); + DBGLOG(INIT, INFO, "\n"); + memcpy(((struct CMD_FORMAT_V1 *)buffer) + times, &cmd_v1, + sizeof(struct CMD_FORMAT_V1)); + + return WLAN_STATUS_SUCCESS; +} + + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is to send WLAN feature options to firmware + * + * @param prAdapter Pointer of ADAPTER_T + * + * @return none + */ +/*----------------------------------------------------------------------------*/ +void wlanFeatureToFw(IN struct ADAPTER *prAdapter, uint32_t u4Flag) +{ + + struct WLAN_CFG_ENTRY *prWlanCfgEntry; + uint32_t i; + struct CMD_HEADER rCmdV1Header; + uint32_t rStatus; + struct CMD_FORMAT_V1 rCmd_v1; + uint8_t ucTimes = 0; + + + + rCmdV1Header.cmdType = CMD_TYPE_SET; + rCmdV1Header.cmdVersion = CMD_VER_1; + rCmdV1Header.cmdBufferLen = 0; + rCmdV1Header.itemNum = 0; + + kalMemSet(rCmdV1Header.buffer, 0, MAX_CMD_BUFFER_LENGTH); + kalMemSet(&rCmd_v1, 0, sizeof(struct CMD_FORMAT_V1)); + + + prWlanCfgEntry = NULL; + + for (i = 0; i < WLAN_CFG_ENTRY_NUM_MAX; i++) { + + prWlanCfgEntry = wlanCfgGetEntryByIndex(prAdapter, i, u4Flag); + + if (prWlanCfgEntry) { + + rCmd_v1.itemType = ITEM_TYPE_STR; + + + /*send string format to firmware */ + rCmd_v1.itemStringLength = kalStrLen( + prWlanCfgEntry->aucKey); + if (rCmd_v1.itemStringLength > MAX_CMD_NAME_MAX_LENGTH) + continue; + kalMemZero(rCmd_v1.itemString, MAX_CMD_NAME_MAX_LENGTH); + kalMemCopy(rCmd_v1.itemString, prWlanCfgEntry->aucKey, + rCmd_v1.itemStringLength); + + + rCmd_v1.itemValueLength = kalStrLen( + prWlanCfgEntry->aucValue); + if (rCmd_v1.itemValueLength > MAX_CMD_VALUE_MAX_LENGTH) + continue; + kalMemZero(rCmd_v1.itemValue, MAX_CMD_VALUE_MAX_LENGTH); + kalMemCopy(rCmd_v1.itemValue, prWlanCfgEntry->aucValue, + rCmd_v1.itemValueLength); + + + + DBGLOG(INIT, TRACE, + "Send key word (%s) WITH (%s) to firmware\n", + rCmd_v1.itemString, rCmd_v1.itemValue); + + kalMemCopy(((struct CMD_FORMAT_V1 *)rCmdV1Header.buffer) + + ucTimes, + &rCmd_v1, sizeof(struct CMD_FORMAT_V1)); + + + ucTimes++; + rCmdV1Header.cmdBufferLen += + sizeof(struct CMD_FORMAT_V1); + rCmdV1Header.itemNum += ucTimes; + + if (ucTimes == MAX_CMD_ITEM_MAX) { + /* Send to FW */ + rCmdV1Header.itemNum = ucTimes; + + rStatus = wlanSendSetQueryCmd( + /* prAdapter */ + prAdapter, + /* 0x70 */ + CMD_ID_GET_SET_CUSTOMER_CFG, + /* fgSetQuery */ + TRUE, + /* fgNeedResp */ + FALSE, + /* fgIsOid */ + FALSE, + /* pfCmdDoneHandler*/ + NULL, + /* pfCmdTimeoutHandler */ + NULL, + /* u4SetQueryInfoLen */ + sizeof(struct CMD_HEADER), + /* pucInfoBuffer */ + (uint8_t *)&rCmdV1Header, + /* pvSetQueryBuffer */ + NULL, + /* u4SetQueryBufferLen */ + 0); + + if (rStatus == WLAN_STATUS_FAILURE) + DBGLOG(INIT, INFO, + "[Fail]kalIoctl wifiSefCFG fail 0x%x\n", + rStatus); + + DBGLOG(INIT, TRACE, + "kalIoctl wifiSefCFG num:%d\n", ucTimes); + kalMemSet(rCmdV1Header.buffer, 0, + MAX_CMD_BUFFER_LENGTH); + rCmdV1Header.cmdBufferLen = 0; + ucTimes = 0; + } + + + } else { + break; + } + } + + + if (ucTimes != 0) { + /* Send to FW */ + rCmdV1Header.itemNum = ucTimes; + + rStatus = wlanSendSetQueryCmd( + prAdapter, /* prAdapter */ + CMD_ID_GET_SET_CUSTOMER_CFG, /* 0x70 */ + TRUE, /* fgSetQuery */ + FALSE, /* fgNeedResp */ + FALSE, /* fgIsOid */ + NULL, /* pfCmdDoneHandler*/ + NULL, /* pfCmdTimeoutHandler */ + sizeof(struct CMD_HEADER), /* u4SetQueryInfoLen */ + (uint8_t *)&rCmdV1Header,/* pucInfoBuffer */ + NULL, /* pvSetQueryBuffer */ + 0); /* u4SetQueryBufferLen */ + + if (rStatus == WLAN_STATUS_FAILURE) + DBGLOG(INIT, INFO, + "[Fail]kalIoctl wifiSefCFG fail 0x%x\n", + rStatus); + + DBGLOG(INIT, TRACE, + "cmdV1Header.itemNum:%d, kalIoctl wifiSefCFG num:%d\n", + rCmdV1Header.itemNum, + ucTimes); + kalMemSet(rCmdV1Header.buffer, 0, MAX_CMD_BUFFER_LENGTH); + rCmdV1Header.cmdBufferLen = 0; + ucTimes = 0; + } + +#if CFG_SUPPORT_SMART_GEAR + /*Send Event, Notify Fwks*/ + #if CFG_SUPPORT_DATA_STALL + if (prAdapter->rWifiVar.ucSGCfg == 0x00) { + enum ENUM_VENDOR_DRIVER_EVENT eEvent = EVENT_SG_DISABLE; + + KAL_REPORT_ERROR_EVENT(prAdapter, + eEvent, (uint16_t)sizeof(u_int8_t), + 0, + TRUE); + } + #endif /* CFG_SUPPORT_DATA_STALL */ +#endif + +} + +uint32_t wlanCfgParse(IN struct ADAPTER *prAdapter, + uint8_t *pucConfigBuf, uint32_t u4ConfigBufLen, + u_int8_t isFwConfig) +{ + struct WLAN_CFG_PARSE_STATE_S state; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX]; + int8_t **ppcArgs; + int32_t i4Nargs; + int8_t arcArgv_size[WLAN_CFG_ARGV_MAX]; + uint8_t ucTimes = 0; + uint32_t rStatus = WLAN_STATUS_FAILURE; + struct CMD_HEADER rCmdV1Header; + int8_t ucTmp[WLAN_CFG_VALUE_LEN_MAX]; + uint8_t i; + + uint8_t *pucCurrBuf = ucTmp; + uint32_t u4CurrSize = ARRAY_SIZE(ucTmp); + uint32_t u4RetSize = 0; + + rCmdV1Header.cmdType = CMD_TYPE_SET; + rCmdV1Header.cmdVersion = CMD_VER_1; + rCmdV1Header.cmdBufferLen = 0; + kalMemSet(rCmdV1Header.buffer, 0, MAX_CMD_BUFFER_LENGTH); + + if (pucConfigBuf == NULL) { + DBGLOG(INIT, ERROR, "pucConfigBuf is NULL\n"); + return WLAN_STATUS_FAILURE; + } + if (kalStrnLen(pucConfigBuf, 4000) >= 4000) { + DBGLOG(INIT, ERROR, "pucConfigBuf >= 4000\n"); + return WLAN_STATUS_FAILURE; + } + if (u4ConfigBufLen == 0) + return WLAN_STATUS_FAILURE; + + ppcArgs = apcArgv; + i4Nargs = 0; + state.ptr = pucConfigBuf; + state.nexttoken = 0; + state.textsize = 0; + state.maxSize = u4ConfigBufLen; + DBGLOG(INIT, INFO, "wlanCfgParse()\n"); + + for (;;) { + switch (wlanCfgFindNextToken(&state)) { + case STATE_EOF: + if (i4Nargs < 2) + goto exit; + + DBGLOG(INIT, INFO, "STATE_EOF\n"); + + /* 3 parmeter mode transforation */ + if (i4Nargs == 3 && !isFwConfig && + arcArgv_size[0] == 1) { + + /* parsing and transfer the format + * Format 1:Dec 2.Hex 3.String + */ + + kalMemZero(ucTmp, WLAN_CFG_VALUE_LEN_MAX); + pucCurrBuf = ucTmp; + u4CurrSize = ARRAY_SIZE(ucTmp); + + if ((*ppcArgs[0] == '2') && + (*(ppcArgs[2]) != '0') && + (*(ppcArgs[2] + 1) != 'x')) { + DBGLOG(INIT, WARN, + "config file got a hex format\n" + ); + kalSnprintf(pucCurrBuf, u4CurrSize, + "0x%s", ppcArgs[2]); + } else { + kalSnprintf(pucCurrBuf, u4CurrSize, + "%s", ppcArgs[2]); + } + DBGLOG(INIT, WARN, + "[3 parameter mode][%s],[%s],[%s]\n", + ppcArgs[0], ppcArgs[1], ucTmp); + wlanCfgParseAddEntry(prAdapter, ppcArgs[1], + NULL, ucTmp, NULL); + kalMemSet(arcArgv_size, 0, WLAN_CFG_ARGV_MAX); + kalMemSet(apcArgv, 0, + WLAN_CFG_ARGV_MAX * sizeof(int8_t *)); + i4Nargs = 0; + goto exit; + + } + + wlanCfgParseAddEntry(prAdapter, ppcArgs[0], NULL, + ppcArgs[1], NULL); + + if (isFwConfig) { + uint32_t ret; + + ret = wlanCfgParseToFW(ppcArgs, arcArgv_size, + i4Nargs, + rCmdV1Header.buffer, + ucTimes); + if (ret == WLAN_STATUS_SUCCESS) { + ucTimes++; + rCmdV1Header.cmdBufferLen += + sizeof(struct CMD_FORMAT_V1); + } + } + + goto exit; + + + case STATE_NEWLINE: + if (i4Nargs < 2) + break; + + DBGLOG(INIT, INFO, "STATE_NEWLINE\n"); +#if 1 + /* 3 parmeter mode transforation */ + if (i4Nargs == 3 && !isFwConfig && + arcArgv_size[0] == 1) { + /* parsing and transfer the format + * Format 1:Dec 2.Hex 3.String + */ + kalMemZero(ucTmp, WLAN_CFG_VALUE_LEN_MAX); + pucCurrBuf = ucTmp; + u4CurrSize = ARRAY_SIZE(ucTmp); + + if ((*ppcArgs[0] == '2') && + (*(ppcArgs[2]) != '0') && + (*(ppcArgs[2] + 1) != 'x')) { + DBGLOG(INIT, WARN, + "config file got a hex format\n"); + kalSnprintf(pucCurrBuf, u4CurrSize, + "0x%s", ppcArgs[2]); + + } else { + kalSnprintf(pucCurrBuf, u4CurrSize, + "%s", ppcArgs[2]); + } + + + DBGLOG(INIT, WARN, + "[3 parameter mode][%s],[%s],[%s]\n", + ppcArgs[0], ppcArgs[1], ucTmp); + wlanCfgParseAddEntry(prAdapter, ppcArgs[1], + NULL, ucTmp, NULL); + kalMemSet(arcArgv_size, 0, WLAN_CFG_ARGV_MAX); + kalMemSet(apcArgv, 0, + WLAN_CFG_ARGV_MAX * sizeof(int8_t *)); + i4Nargs = 0; + break; + + } +#if 1 + /*combine the argument to save in temp*/ + pucCurrBuf = ucTmp; + u4CurrSize = ARRAY_SIZE(ucTmp); + + kalMemZero(ucTmp, WLAN_CFG_VALUE_LEN_MAX); + + if (i4Nargs == 2) { + /* no space for it, driver can't accept space in + * the end of the line + */ + /* ToDo: skip the space when parsing */ + kalSnprintf(pucCurrBuf, u4CurrSize, "%s", + ppcArgs[1]); + } else { + for (i = 1; i < i4Nargs; i++) { + if (u4CurrSize <= 1) { + DBGLOG(INIT, ERROR, + "write to pucCurrBuf out of bound, i=%d\n", + i); + break; + } + u4RetSize = kalScnprintf(pucCurrBuf, + u4CurrSize, "%s ", + ppcArgs[i]); + pucCurrBuf += u4RetSize; + u4CurrSize -= u4RetSize; + } + } + + DBGLOG(INIT, WARN, + "Save to driver temp buffer as [%s]\n", + ucTmp); + wlanCfgParseAddEntry(prAdapter, ppcArgs[0], NULL, ucTmp, + NULL); +#else + wlanCfgParseAddEntry(prAdapter, ppcArgs[0], NULL, + ppcArgs[1], NULL); +#endif + + if (isFwConfig) { + + uint32_t ret; + + ret = wlanCfgParseToFW(ppcArgs, arcArgv_size, + i4Nargs, rCmdV1Header.buffer, ucTimes); + if (ret == WLAN_STATUS_SUCCESS) { + ucTimes++; + rCmdV1Header.cmdBufferLen += + sizeof(struct CMD_FORMAT_V1); + } + + if (ucTimes == MAX_CMD_ITEM_MAX) { + /* Send to FW */ + rCmdV1Header.itemNum = ucTimes; + rStatus = wlanSendSetQueryCmd( + /* prAdapter */ + prAdapter, + /* 0x70 */ + CMD_ID_GET_SET_CUSTOMER_CFG, + /* fgSetQuery */ + TRUE, + /* fgNeedResp */ + FALSE, + /* fgIsOid */ + FALSE, + /* pfCmdDoneHandler*/ + NULL, + /* pfCmdTimeoutHandler */ + NULL, + /* u4SetQueryInfoLen */ + sizeof(struct CMD_HEADER), + /* pucInfoBuffer */ + (uint8_t *) &rCmdV1Header, + /* pvSetQueryBuffer */ + NULL, + /* u4SetQueryBufferLen */ + 0); + + if (rStatus == WLAN_STATUS_FAILURE) + DBGLOG(INIT, INFO, + "kalIoctl wifiSefCFG fail 0x%x\n", + rStatus); + DBGLOG(INIT, INFO, + "kalIoctl wifiSefCFG num:%d X\n", + ucTimes); + kalMemSet(rCmdV1Header.buffer, 0, + MAX_CMD_BUFFER_LENGTH); + rCmdV1Header.cmdBufferLen = 0; + ucTimes = 0; + } + + } + +#endif + kalMemSet(arcArgv_size, 0, WLAN_CFG_ARGV_MAX); + kalMemSet(apcArgv, 0, + WLAN_CFG_ARGV_MAX * sizeof(int8_t *)); + i4Nargs = 0; + break; + + case STATE_TEXT: + if (i4Nargs >= 0 && i4Nargs < WLAN_CFG_ARGV_MAX) { + ppcArgs[i4Nargs++] = state.text; + arcArgv_size[i4Nargs - 1] = state.textsize; + state.textsize = 0; + DBGLOG(INIT, INFO, + " nargs= %d STATE_TEXT = %s, SIZE = %d\n", + i4Nargs - 1, ppcArgs[i4Nargs - 1], + arcArgv_size[i4Nargs - 1]); + } + break; + } + } + +exit: + if (ucTimes != 0 && isFwConfig) { + /* Send to FW */ + rCmdV1Header.itemNum = ucTimes; + + DBGLOG(INIT, INFO, "cmdV1Header.itemNum:%d\n", + rCmdV1Header.itemNum); + rStatus = wlanSendSetQueryCmd( + prAdapter, /* prAdapter */ + CMD_ID_GET_SET_CUSTOMER_CFG, /* 0x70 */ + TRUE, /* fgSetQuery */ + FALSE, /* fgNeedResp */ + FALSE, /* fgIsOid */ + NULL, /* pfCmdDoneHandler*/ + NULL, /* pfCmdTimeoutHandler */ + sizeof(struct CMD_HEADER), /* u4SetQueryInfoLen */ + (uint8_t *) &rCmdV1Header, /* pucInfoBuffer */ + NULL, /* pvSetQueryBuffer */ + 0 /* u4SetQueryBufferLen */ + ); + + if (rStatus == WLAN_STATUS_FAILURE) + DBGLOG(INIT, WARN, "kalIoctl wifiSefCFG fail 0x%x\n", + rStatus); + + DBGLOG(INIT, WARN, "kalIoctl wifiSefCFG num:%d X\n", + ucTimes); + kalMemSet(rCmdV1Header.buffer, 0, MAX_CMD_BUFFER_LENGTH); + rCmdV1Header.cmdBufferLen = 0; + ucTimes = 0; + } + return WLAN_STATUS_SUCCESS; +} + +#else +uint32_t wlanCfgParse(IN struct ADAPTER *prAdapter, + uint8_t *pucConfigBuf, uint32_t u4ConfigBufLen) +{ + + struct WLAN_CFG_PARSE_STATE_S state; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX]; + int8_t **args; + int32_t nargs; + + if (pucConfigBuf == NULL) { + DBGLOG(INIT, ERROR, "pucConfigBuf is NULL\n"); + return WLAN_STATUS_FAILURE; + } + if (kalStrnLen(pucConfigBuf, 4000) >= 4000) { + DBGLOG(INIT, ERROR, "pucConfigBuf >= 4000\n"); + return WLAN_STATUS_FAILURE; + } + if (u4ConfigBufLen == 0) + return WLAN_STATUS_FAILURE; + args = apcArgv; + nargs = 0; + state.ptr = pucConfigBuf; + state.nexttoken = 0; + state.maxSize = u4ConfigBufLen; + + for (;;) { + switch (wlanCfgFindNextToken(&state)) { + case STATE_EOF: + if (nargs > 1) + wlanCfgParseAddEntry(prAdapter, args[0], NULL, + args[1], NULL); + goto exit; + case STATE_NEWLINE: + if (nargs > 1) + wlanCfgParseAddEntry(prAdapter, args[0], NULL, + args[1], NULL); + /*args[0] is parameter, args[1] is the value*/ + nargs = 0; + break; + case STATE_TEXT: + if (nargs < WLAN_CFG_ARGV_MAX) + args[nargs++] = state.text; + break; + } + } + +exit: + return WLAN_STATUS_SUCCESS; + +#if 0 + /* Old version */ + uint32_t i; + uint8_t c; + uint8_t *pbuf; + uint8_t ucState; + uint8_t *pucKeyTail = NULL; + uint8_t *pucKeyHead = NULL; + uint8_t *pucValueHead = NULL; + uint8_t *pucValueTail = NULL; + + ucState = WAIT_KEY_HEAD; + pbuf = pucConfigBuf; + + for (i = 0; i < u4ConfigBufLen; i++) { + c = pbuf[i]; + if (c == '\r' || c == '\n') { + + if (ucState == WAIT_VALUE_TAIL) { + /* Entry found */ + if (pucValueHead) + wlanCfgParseAddEntry(prAdapter, + pucKeyHead, pucKeyTail, + pucValueHead, pucValueTail); + } + ucState = WAIT_KEY_HEAD; + pucKeyTail = NULL; + pucKeyHead = NULL; + pucValueHead = NULL; + pucValueTail = NULL; + + } else if (c == '=') { + if (ucState == WAIT_KEY_TAIL) { + pucKeyTail = &pbuf[i - 1]; + ucState = WAIT_VALUE_HEAD; + } + } else if (c == ' ' || c == '\t') { + if (ucState == WAIT_KEY_TAIL) { + pucKeyTail = &pbuf[i - 1]; + ucState = WAIT_VALUE_HEAD; + } + } else { + + if (c == '#') { + /* comments */ + if (ucState == WAIT_KEY_HEAD) + ucState = WAIT_COMMENT_TAIL; + else if (ucState == WAIT_VALUE_TAIL) + pucValueTail = &pbuf[i]; + + } else { + if (ucState == WAIT_KEY_HEAD) { + pucKeyHead = &pbuf[i]; + pucKeyTail = &pbuf[i]; + ucState = WAIT_KEY_TAIL; + } else if (ucState == WAIT_VALUE_HEAD) { + pucValueHead = &pbuf[i]; + pucValueTail = &pbuf[i]; + ucState = WAIT_VALUE_TAIL; + } else if (ucState == WAIT_VALUE_TAIL) + pucValueTail = &pbuf[i]; + } + } + + } /* for */ + + if (ucState == WAIT_VALUE_TAIL) { + /* Entry found */ + if (pucValueTail) + wlanCfgParseAddEntry(prAdapter, pucKeyHead, pucKeyTail, + pucValueHead, pucValueTail); + } +#endif + + return WLAN_STATUS_SUCCESS; +} +#endif + + +uint32_t wlanCfgInit(IN struct ADAPTER *prAdapter, + uint8_t *pucConfigBuf, uint32_t u4ConfigBufLen, + uint32_t u4Flags) +{ + struct WLAN_CFG *prWlanCfg; + struct WLAN_CFG_REC *prWlanCfgRec; + struct WLAN_CFG *prWlanCfgEm; + + /* P_WLAN_CFG_ENTRY_T prWlanCfgEntry; */ + prAdapter->prWlanCfg = &prAdapter->rWlanCfg; + prWlanCfg = prAdapter->prWlanCfg; + + prAdapter->prWlanCfgRec = &prAdapter->rWlanCfgRec; + prWlanCfgRec = prAdapter->prWlanCfgRec; + + prAdapter->prWlanCfgEm = &prAdapter->rWlanCfgEm; + prWlanCfgEm = prAdapter->prWlanCfgEm; + + kalMemZero(prWlanCfg, sizeof(struct WLAN_CFG)); + ASSERT(prWlanCfg); + + kalMemZero(prWlanCfgEm, sizeof(struct WLAN_CFG)); + ASSERT(prWlanCfgEm); + + prWlanCfg->u4WlanCfgEntryNumMax = WLAN_CFG_ENTRY_NUM_MAX; + prWlanCfg->u4WlanCfgKeyLenMax = WLAN_CFG_KEY_LEN_MAX; + prWlanCfg->u4WlanCfgValueLenMax = WLAN_CFG_VALUE_LEN_MAX; + + prWlanCfgRec->u4WlanCfgEntryNumMax = + WLAN_CFG_REC_ENTRY_NUM_MAX; + prWlanCfgRec->u4WlanCfgKeyLenMax = + WLAN_CFG_KEY_LEN_MAX; + prWlanCfgRec->u4WlanCfgValueLenMax = + WLAN_CFG_VALUE_LEN_MAX; + + prWlanCfgEm->u4WlanCfgEntryNumMax = WLAN_CFG_ENTRY_NUM_MAX; + prWlanCfgEm->u4WlanCfgKeyLenMax = WLAN_CFG_KEY_LEN_MAX; + prWlanCfgEm->u4WlanCfgValueLenMax = WLAN_CFG_VALUE_LEN_MAX; + + + DBGLOG(INIT, INFO, "Init wifi config len %u max entry %u\n", + u4ConfigBufLen, prWlanCfg->u4WlanCfgEntryNumMax); +#if DBG + /* self test */ + wlanCfgSet(prAdapter, "ConfigValid", "0x123", WLAN_CFG_DEFAULT); + if (wlanCfgGetUint32(prAdapter, "ConfigValid", WLAN_CFG_DEFAULT) + != 0x123) + DBGLOG(INIT, INFO, "wifi config error %u\n", __LINE__); + + wlanCfgSet(prAdapter, "ConfigValid", "1", WLAN_CFG_DEFAULT); + if (wlanCfgGetUint32(prAdapter, "ConfigValid", WLAN_CFG_DEFAULT) != 1) + DBGLOG(INIT, INFO, "wifi config error %u\n", __LINE__); + +#endif + /*load default value because kalMemZero in this function*/ + wlanLoadDefaultCustomerSetting(prAdapter); + + /* Parse the pucConfigBuf */ + if (pucConfigBuf && (u4ConfigBufLen > 0)) +#if CFG_SUPPORT_EASY_DEBUG + wlanCfgParse(prAdapter, pucConfigBuf, u4ConfigBufLen, + FALSE); +#else + wlanCfgParse(prAdapter, pucConfigBuf, u4ConfigBufLen); +#endif + return WLAN_STATUS_SUCCESS; +} + +#endif /* CFG_SUPPORT_CFG_FILE */ + +int32_t wlanHexToNum(int8_t c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + return -1; +} + +int32_t wlanHexToByte(int8_t *hex) +{ + int32_t a, b; + + a = wlanHexToNum(*hex++); + if (a < 0) + return -1; + b = wlanHexToNum(*hex++); + if (b < 0) + return -1; + return (a << 4) | b; +} + +int32_t wlanHexToArray(int8_t *hexString, int8_t *hexArray, uint8_t arrayLen) +{ + int8_t index = 0; + uint8_t converted = 0; + int strLen = strlen(hexString); + int8_t result; + + for (index = strLen-1; + converted < min(arrayLen*2, strLen); index--) { + if ((strLen-converted) >= 2) { + index--; + result = wlanHexToByte(hexString+index); + converted += 2; + } else { + result = wlanHexToNum(*(hexString+index)); + converted++; + } + if (result == -1) + return 0; + hexArray[(converted-1)/2] = result; + } + return converted; +} + +int32_t wlanHexToArrayR(int8_t *hexString, int8_t *hexArray, uint8_t arrayLen) +{ + int8_t converted = 0; + int len = strlen(hexString)/2; + int8_t result; + + len = arrayLen < len ? arrayLen : len; + if (*(hexString+1) == '\0') { + result = wlanHexToNum(*(hexString)); + if (result != -1) { + hexArray[converted] = result; + converted++; + } + } else { + for (converted = 0; converted < len; converted++) { + result = wlanHexToByte(hexString + converted*2); + hexArray[converted] = result; + } + } + return converted; +} + + + +int32_t wlanHwAddrToBin(int8_t *txt, uint8_t *addr) +{ + int32_t i; + int8_t *pos = txt; + + for (i = 0; i < 6; i++) { + int32_t a, b; + + while (*pos == ':' || *pos == '.' || *pos == '-') + pos++; + + a = wlanHexToNum(*pos++); + if (a < 0) + return -1; + b = wlanHexToNum(*pos++); + if (b < 0) + return -1; + *addr++ = (a << 4) | b; + } + + return pos - txt; +} + +u_int8_t wlanIsChipNoAck(IN struct ADAPTER *prAdapter) +{ + u_int8_t fgIsNoAck; + + fgIsNoAck = prAdapter->fgIsChipNoAck +#if CFG_CHIP_RESET_SUPPORT + || kalIsResetting() +#endif + || fgIsBusAccessFailed; + + return fgIsNoAck; +} + +u_int8_t wlanIsChipRstRecEnabled(IN struct ADAPTER + *prAdapter) +{ + return prAdapter->rWifiVar.fgChipResetRecover; +} + +u_int8_t wlanIsChipAssert(IN struct ADAPTER *prAdapter) +{ + return prAdapter->rWifiVar.fgChipResetRecover + && prAdapter->fgIsChipAssert; +} + +void wlanChipRstPreAct(IN struct ADAPTER *prAdapter) +{ + struct BSS_INFO *prBssInfo = (struct BSS_INFO *) NULL; + int32_t i4BssIdx; + uint32_t u4ClientCount = 0; + struct STA_RECORD *prCurrStaRec = (struct STA_RECORD *) + NULL; + struct STA_RECORD *prNextCurrStaRec = (struct STA_RECORD *) + NULL; + struct LINK *prClientList; + struct GLUE_INFO *prGlueInfo = prAdapter->prGlueInfo; + + KAL_ACQUIRE_MUTEX(prAdapter, MUTEX_CHIP_RST); + if (prAdapter->fgIsChipAssert) { + KAL_RELEASE_MUTEX(prAdapter, MUTEX_CHIP_RST); + return; + } + prAdapter->fgIsChipAssert = TRUE; + KAL_RELEASE_MUTEX(prAdapter, MUTEX_CHIP_RST); + + for (i4BssIdx = 0; i4BssIdx < prAdapter->ucHwBssIdNum; + i4BssIdx++) { + prBssInfo = prAdapter->aprBssInfo[i4BssIdx]; + + if (!prBssInfo->fgIsInUse) + continue; + + if (prBssInfo->eNetworkType == NETWORK_TYPE_AIS) { + + if (kalGetMediaStateIndicated(prGlueInfo, + i4BssIdx) == + MEDIA_STATE_CONNECTED) + kalIndicateStatusAndComplete(prGlueInfo, + WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0, + i4BssIdx); + } else if (prBssInfo->eNetworkType == NETWORK_TYPE_P2P) { + if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) { + u4ClientCount = bssGetClientCount(prAdapter, + prBssInfo); + if (u4ClientCount == 0) + continue; + + prClientList = &prBssInfo->rStaRecOfClientList; + LINK_FOR_EACH_ENTRY_SAFE(prCurrStaRec, + prNextCurrStaRec, prClientList, + rLinkEntry, struct STA_RECORD) { + if (!prCurrStaRec) + break; + kalP2PGOStationUpdate( + prAdapter->prGlueInfo, + (uint8_t) prBssInfo->u4PrivateData, + prCurrStaRec, FALSE); + LINK_REMOVE_KNOWN_ENTRY(prClientList, + &prCurrStaRec->rLinkEntry); + } + } else if (prBssInfo->eCurrentOPMode == + OP_MODE_INFRASTRUCTURE) { + if (prBssInfo->prStaRecOfAP == NULL) + continue; +#if CFG_WPS_DISCONNECT || (KERNEL_VERSION(4, 4, 0) <= CFG80211_VERSION_CODE) + kalP2PGCIndicateConnectionStatus(prGlueInfo, + (uint8_t) prBssInfo->u4PrivateData, + NULL, NULL, 0, 0, + WLAN_STATUS_MEDIA_DISCONNECT); +#else + kalP2PGCIndicateConnectionStatus(prGlueInfo, + (uint8_t) prBssInfo->u4PrivateData, + NULL, NULL, 0, 0); +#endif + prBssInfo->prStaRecOfAP = NULL; + + } + } + } +} + +#if CFG_ENABLE_PER_STA_STATISTICS +void wlanTxLifetimeUpdateStaStats(IN struct ADAPTER + *prAdapter, IN struct MSDU_INFO *prMsduInfo) +{ + struct STA_RECORD *prStaRec; + uint32_t u4DeltaTime; + uint32_t u4DeltaHifTxTime; + struct PKT_PROFILE *prPktProfile = &prMsduInfo->rPktProfile; +#if 0 + struct QUE_MGT *prQM = &prAdapter->rQM; + uint32_t u4PktPrintPeriod = 0; +#endif + + prStaRec = cnmGetStaRecByIndex(prAdapter, + prMsduInfo->ucStaRecIndex); + + if (prStaRec) { + u4DeltaTime = (uint32_t) (prPktProfile->rHifTxDoneTimestamp - + prPktProfile->rHardXmitArrivalTimestamp); + u4DeltaHifTxTime = (uint32_t) ( + prPktProfile->rHifTxDoneTimestamp - + prPktProfile->rDequeueTimestamp); + + /* Update StaRec statistics */ + prStaRec->u4TotalTxPktsNumber++; + prStaRec->u4TotalTxPktsTime += u4DeltaTime; + prStaRec->u4TotalTxPktsHifTxTime += u4DeltaHifTxTime; + + if (u4DeltaTime > prStaRec->u4MaxTxPktsTime) + prStaRec->u4MaxTxPktsTime = u4DeltaTime; + + if (u4DeltaHifTxTime > prStaRec->u4MaxTxPktsHifTime) + prStaRec->u4MaxTxPktsHifTime = u4DeltaHifTxTime; + + if (u4DeltaTime >= NIC_TX_TIME_THRESHOLD) + prStaRec->u4ThresholdCounter++; + +#if 0 + if (u4PktPrintPeriod && + (prStaRec->u4TotalTxPktsNumber >= u4PktPrintPeriod)) { + DBGLOG(TX, INFO, "[%u]N[%u]A[%u]M[%u]T[%u]E[%4u]\n", + prStaRec->ucIndex, + prStaRec->u4TotalTxPktsNumber, + prStaRec->u4TotalTxPktsTime, + prStaRec->u4MaxTxPktsTime, + prStaRec->u4ThresholdCounter, + prQM->au4QmTcResourceEmptyCounter[ + prStaRec->ucBssIndex][TC2_INDEX]); + + prStaRec->u4TotalTxPktsNumber = 0; + prStaRec->u4TotalTxPktsTime = 0; + prStaRec->u4MaxTxPktsTime = 0; + prStaRec->u4ThresholdCounter = 0; + prQM->au4QmTcResourceEmptyCounter[ + prStaRec->ucBssIndex][TC2_INDEX] = 0; + } +#endif + } +} +#endif + +u_int8_t wlanTxLifetimeIsProfilingEnabled( + IN struct ADAPTER *prAdapter) +{ + u_int8_t fgEnabled = TRUE; +#if CFG_SUPPORT_WFD + struct WFD_CFG_SETTINGS *prWfdCfgSettings = + (struct WFD_CFG_SETTINGS *) NULL; + + prWfdCfgSettings = + &prAdapter->rWifiVar.rWfdConfigureSettings; + + if (prWfdCfgSettings->ucWfdEnable > 0) + fgEnabled = TRUE; +#endif + + return fgEnabled; +} + +u_int8_t wlanTxLifetimeIsTargetMsdu(IN struct ADAPTER + *prAdapter, IN struct MSDU_INFO *prMsduInfo) +{ + u_int8_t fgResult = TRUE; + +#if 0 + switch (prMsduInfo->ucTID) { + /* BK */ + case 1: + case 2: + + /* BE */ + case 0: + case 3: + fgResult = FALSE; + break; + /* VI */ + case 4: + case 5: + + /* VO */ + case 6: + case 7: + fgResult = TRUE; + break; + default: + break; + } +#endif + return fgResult; +} + +void wlanTxLifetimeTagPacket(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN enum ENUM_TX_PROFILING_TAG eTag) +{ + struct PKT_PROFILE *prPktProfile = &prMsduInfo->rPktProfile; + + if (!wlanTxLifetimeIsProfilingEnabled(prAdapter)) + return; + + switch (eTag) { + case TX_PROF_TAG_OS_TO_DRV: + /* arrival time is tagged in wlanProcessTxFrame */ + break; + + case TX_PROF_TAG_DRV_ENQUE: + /* Reset packet profile */ + prPktProfile->fgIsValid = FALSE; + if (wlanTxLifetimeIsTargetMsdu(prAdapter, prMsduInfo)) { + /* Enable packet lifetime profiling */ + prPktProfile->fgIsValid = TRUE; + + /* Packet arrival time at kernel Hard Xmit */ + prPktProfile->rHardXmitArrivalTimestamp = + GLUE_GET_PKT_ARRIVAL_TIME(prMsduInfo->prPacket); + + /* Packet enqueue time */ + prPktProfile->rEnqueueTimestamp = (OS_SYSTIME) + kalGetTimeTick(); + } + break; + + case TX_PROF_TAG_DRV_DEQUE: + if (prPktProfile->fgIsValid) + prPktProfile->rDequeueTimestamp = (OS_SYSTIME) + kalGetTimeTick(); + break; + + case TX_PROF_TAG_DRV_TX_DONE: + if (prPktProfile->fgIsValid) { + prPktProfile->rHifTxDoneTimestamp = (OS_SYSTIME) + kalGetTimeTick(); +#if CFG_ENABLE_PER_STA_STATISTICS + wlanTxLifetimeUpdateStaStats(prAdapter, prMsduInfo); +#endif + } + break; + default: + break; + } +} + +void wlanTxProfilingTagPacket(IN struct ADAPTER *prAdapter, + IN void *prPacket, + IN enum ENUM_TX_PROFILING_TAG eTag) +{ + if (!prPacket) + return; + +#if CFG_MET_PACKET_TRACE_SUPPORT + kalMetTagPacket(prAdapter->prGlueInfo, prPacket, eTag); +#endif + + switch (eTag) { + case TX_PROF_TAG_OS_TO_DRV: + kalTraceEvent("Xmit ipid=0x%04x seq=%d", + GLUE_GET_PKT_IP_ID(prPacket), + GLUE_GET_PKT_SEQ_NO(prPacket)); + DBGLOG(TX, TEMP, "Xmit ipid=%d seq=%d\n", + GLUE_GET_PKT_IP_ID(prPacket), + GLUE_GET_PKT_SEQ_NO(prPacket)); + break; + case TX_PROF_TAG_DRV_ENQUE: + kalTraceEvent("Enq ipid=0x%04x seq=%d", + GLUE_GET_PKT_IP_ID(prPacket), + GLUE_GET_PKT_SEQ_NO(prPacket)); + DBGLOG(TX, TEMP, "Enq ipid=%d seq=%d\n", + GLUE_GET_PKT_IP_ID(prPacket), + GLUE_GET_PKT_SEQ_NO(prPacket)); + break; + case TX_PROF_TAG_DRV_FREE: + kalTraceEvent("Cmpl ipid=0x%04x seq=%d", + GLUE_GET_PKT_IP_ID(prPacket), + GLUE_GET_PKT_SEQ_NO(prPacket)); + DBGLOG(TX, TEMP, "Cmpl ipid=%d seq=%d\n", + GLUE_GET_PKT_IP_ID(prPacket), + GLUE_GET_PKT_SEQ_NO(prPacket)); + break; + default: + break; + } +} + +void wlanTxProfilingTagMsdu(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN enum ENUM_TX_PROFILING_TAG eTag) +{ + wlanTxLifetimeTagPacket(prAdapter, prMsduInfo, eTag); + + if (prMsduInfo->eSrc == TX_PACKET_OS) { + /* only profile packets from OS */ + wlanTxProfilingTagPacket(prAdapter, prMsduInfo->prPacket, eTag); + } +} + +void wlanUpdateTxStatistics(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN u_int8_t fgTxDrop) +{ + struct STA_RECORD *prStaRec; + struct BSS_INFO *prBssInfo; + enum ENUM_WMM_ACI eAci = WMM_AC_BE_INDEX; + struct QUE_MGT *prQM = &prAdapter->rQM; + OS_SYSTIME rCurTime; + + eAci = aucTid2ACI[prMsduInfo->ucUserPriority]; + + prStaRec = cnmGetStaRecByIndex(prAdapter, + prMsduInfo->ucStaRecIndex); + + if (eAci >= 0 && eAci < WMM_AC_INDEX_NUM) { + if (prStaRec) { + if (fgTxDrop) + prStaRec->arLinkStatistics[eAci].u4TxDropMsdu++; + else + prStaRec->arLinkStatistics[eAci].u4TxMsdu++; + } else { + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prMsduInfo->ucBssIndex); + + if (fgTxDrop) + prBssInfo->arLinkStatistics[eAci]. + u4TxDropMsdu++; + else + prBssInfo->arLinkStatistics[eAci].u4TxMsdu++; + } + } + + /* Trigger FW stats log every 20s */ + rCurTime = (OS_SYSTIME) kalGetTimeTick(); + + DBGLOG(INIT, LOUD, "CUR[%u] LAST[%u] TO[%u]\n", rCurTime, + prQM->rLastTxPktDumpTime, + CHECK_FOR_TIMEOUT(rCurTime, prQM->rLastTxPktDumpTime, + MSEC_TO_SYSTIME( + prAdapter->rWifiVar.u4StatsLogTimeout))); + + if (CHECK_FOR_TIMEOUT(rCurTime, prQM->rLastTxPktDumpTime, + MSEC_TO_SYSTIME( + prAdapter->rWifiVar.u4StatsLogTimeout))) { + + wlanTriggerStatsLog(prAdapter, + prAdapter->rWifiVar.u4StatsLogDuration); + wlanDumpAllBssStatistics(prAdapter); + + prQM->rLastTxPktDumpTime = rCurTime; + } +} + +void wlanUpdateRxStatistics(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb) +{ + struct STA_RECORD *prStaRec; + enum ENUM_WMM_ACI eAci = WMM_AC_BE_INDEX; + + eAci = aucTid2ACI[prSwRfb->ucTid]; + + prStaRec = cnmGetStaRecByIndex(prAdapter, + prSwRfb->ucStaRecIdx); + if (prStaRec && eAci >= 0 && eAci < WMM_AC_INDEX_NUM) + prStaRec->arLinkStatistics[eAci].u4RxMsdu++; +} + +uint32_t wlanTriggerStatsLog(IN struct ADAPTER *prAdapter, + IN uint32_t u4DurationInMs) +{ + struct CMD_STATS_LOG rStatsLogCmd; + uint32_t rResult; + + if (prAdapter->fgIsEnableLpdvt) + return WLAN_STATUS_NOT_SUPPORTED; + + kalMemZero(&rStatsLogCmd, sizeof(struct CMD_STATS_LOG)); + + rStatsLogCmd.u4DurationInMs = u4DurationInMs; + + rResult = wlanSendSetQueryCmd(prAdapter, CMD_ID_STATS_LOG, TRUE, FALSE, + FALSE, nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_STATS_LOG), + (uint8_t *) &rStatsLogCmd, NULL, 0); + + return rResult; +} + +uint32_t +wlanPktTxDone(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN enum ENUM_TX_RESULT_CODE rTxDoneStatus) +{ + OS_SYSTIME rCurrent = kalGetTimeTick(); + struct PKT_PROFILE *prPktProfile = &prMsduInfo->rPktProfile; + + uint8_t *apucPktType[ENUM_PKT_FLAG_NUM] = { + (uint8_t *) DISP_STRING("INVALID"), + (uint8_t *) DISP_STRING("802_3"), + (uint8_t *) DISP_STRING("1X"), + (uint8_t *) DISP_STRING("PROTECTED_1X"), + (uint8_t *) DISP_STRING("NON_PROTECTED_1X"), + (uint8_t *) DISP_STRING("VLAN_EXIST"), + (uint8_t *) DISP_STRING("DHCP"), + (uint8_t *) DISP_STRING("ARP"), + (uint8_t *) DISP_STRING("ICMP"), + (uint8_t *) DISP_STRING("TDLS"), + (uint8_t *) DISP_STRING("DNS") + }; + if (prMsduInfo->ucPktType >= ENUM_PKT_FLAG_NUM) + prMsduInfo->ucPktType = 0; + + if (prPktProfile->fgIsValid && + ((prMsduInfo->ucPktType == ENUM_PKT_ARP) || + (prMsduInfo->ucPktType == ENUM_PKT_DHCP))) { + if (rCurrent - prPktProfile->rHardXmitArrivalTimestamp > 2000) { + DBGLOG(TX, INFO, + "valid %d; ArriveDrv %u, Enq %u, Deq %u, LeaveDrv %u, TxDone %u\n", + prPktProfile->fgIsValid, + prPktProfile->rHardXmitArrivalTimestamp, + prPktProfile->rEnqueueTimestamp, + prPktProfile->rDequeueTimestamp, + prPktProfile->rHifTxDoneTimestamp, rCurrent); + + if (prMsduInfo->ucPktType == ENUM_PKT_ARP) + prAdapter->prGlueInfo->fgTxDoneDelayIsARP = + TRUE; + prAdapter->prGlueInfo->u4ArriveDrvTick = + prPktProfile->rHardXmitArrivalTimestamp; + prAdapter->prGlueInfo->u4EnQueTick = + prPktProfile->rEnqueueTimestamp; + prAdapter->prGlueInfo->u4DeQueTick = + prPktProfile->rDequeueTimestamp; + prAdapter->prGlueInfo->u4LeaveDrvTick = + prPktProfile->rHifTxDoneTimestamp; + prAdapter->prGlueInfo->u4CurrTick = rCurrent; + prAdapter->prGlueInfo->u8CurrTime = sched_clock(); + } + } + + DBGLOG_LIMITED(TX, INFO, + "TX DONE, Type[%s] Tag[0x%08x] WIDX:PID[%u:%u] Status[%u], SeqNo: %d\n", + apucPktType[prMsduInfo->ucPktType], prMsduInfo->u4TxDoneTag, + prMsduInfo->ucWlanIndex, prMsduInfo->ucPID, rTxDoneStatus, + prMsduInfo->ucTxSeqNum); + + if (prMsduInfo->ucPktType == ENUM_PKT_1X) + p2pRoleFsmNotifyEapolTxStatus(prAdapter, + prMsduInfo->ucBssIndex, + prMsduInfo->eEapolKeyType, + rTxDoneStatus); + +#if CFG_SUPPORT_TDLS + if (prMsduInfo->ucPktType == ENUM_PKT_TDLS) + TdlsHandleTxDoneStatus(prAdapter, rTxDoneStatus); +#endif /* CFG_SUPPORT_TDLS */ + + return WLAN_STATUS_SUCCESS; +} + +#if CFG_ASSERT_DUMP +void wlanCorDumpTimerInit(IN struct ADAPTER *prAdapter, + u_int8_t fgIsResetN9) +{ + if (fgIsResetN9) { + cnmTimerInitTimer(prAdapter, + &prAdapter->rN9CorDumpTimer, + (PFN_MGMT_TIMEOUT_FUNC) wlanN9CorDumpTimeOut, + (unsigned long) NULL); + + } else { + cnmTimerInitTimer(prAdapter, + &prAdapter->rCr4CorDumpTimer, + (PFN_MGMT_TIMEOUT_FUNC) wlanCr4CorDumpTimeOut, + (unsigned long) NULL); + } +} + +void wlanCorDumpTimerReset(IN struct ADAPTER *prAdapter, + u_int8_t fgIsResetN9) +{ + + if (prAdapter->fgN9AssertDumpOngoing + || prAdapter->fgCr4AssertDumpOngoing) { + + if (fgIsResetN9) { + cnmTimerStopTimer(prAdapter, + &prAdapter->rN9CorDumpTimer); + cnmTimerStartTimer(prAdapter, + &prAdapter->rN9CorDumpTimer, 5000); + } else { + cnmTimerStopTimer(prAdapter, + &prAdapter->rCr4CorDumpTimer); + cnmTimerStartTimer(prAdapter, + &prAdapter->rCr4CorDumpTimer, 5000); + } + } else { + DBGLOG(INIT, INFO, + "Cr4, N9 CorDump Is not ongoing, ignore timer reset\n"); + } +} + +void wlanN9CorDumpTimeOut(IN struct ADAPTER *prAdapter, + IN unsigned long ulParamPtr) +{ + + if (prAdapter->fgN9CorDumpFileOpend) { + DBGLOG(INIT, INFO, "\n[DUMP_N9]====N9 ASSERT_END====\n"); + prAdapter->fgN9AssertDumpOngoing = FALSE; + kalCloseCorDumpFile(TRUE); + prAdapter->fgN9CorDumpFileOpend = FALSE; + } + + /* Trigger RESET */ + glSetRstReason(RST_FW_ASSERT); + GL_RESET_TRIGGER(prAdapter, RST_FLAG_CHIP_RESET); + +} + +void wlanCr4CorDumpTimeOut(IN struct ADAPTER *prAdapter, + IN unsigned long ulParamPtr) +{ + + if (prAdapter->fgCr4CorDumpFileOpend) { + DBGLOG(INIT, INFO, "\n[DUMP_Cr4]====Cr4 ASSERT_END====\n"); + prAdapter->fgCr4AssertDumpOngoing = FALSE; + kalCloseCorDumpFile(FALSE); + prAdapter->fgCr4CorDumpFileOpend = FALSE; + } + + /* Trigger RESET */ + glSetRstReason(RST_FW_ASSERT); + GL_RESET_TRIGGER(prAdapter, RST_FLAG_CHIP_RESET); +} +#endif + +u_int8_t +wlanGetWlanIdxByAddress(IN struct ADAPTER *prAdapter, + IN uint8_t *pucAddr, OUT uint8_t *pucIndex) +{ + uint8_t ucStaRecIdx; + struct STA_RECORD *prTempStaRec; + + for (ucStaRecIdx = 0; ucStaRecIdx < CFG_STA_REC_NUM; + ucStaRecIdx++) { + prTempStaRec = &(prAdapter->arStaRec[ucStaRecIdx]); + if (pucAddr) { + if (prTempStaRec->fgIsInUse && + EQUAL_MAC_ADDR(prTempStaRec->aucMacAddr, + pucAddr)) { + *pucIndex = prTempStaRec->ucWlanIndex; + return TRUE; + } + } else { + if (prTempStaRec->fgIsInUse + && prTempStaRec->ucStaState == STA_STATE_3) { + *pucIndex = prTempStaRec->ucWlanIndex; + return TRUE; + } + } + } + return FALSE; +} + + +uint8_t * +wlanGetStaAddrByWlanIdx(IN struct ADAPTER *prAdapter, + IN uint8_t ucIndex) +{ + struct WLAN_TABLE *prWtbl; + + ASSERT(prAdapter); + prWtbl = prAdapter->rWifiVar.arWtbl; + if (ucIndex < WTBL_SIZE) { + if (prWtbl[ucIndex].ucUsed && prWtbl[ucIndex].ucPairwise) + return &prWtbl[ucIndex].aucMacAddr[0]; + } + return NULL; +} + +void +wlanNotifyFwSuspend(struct GLUE_INFO *prGlueInfo, + struct net_device *prDev, u_int8_t fgSuspend) +{ + uint32_t rStatus; + uint32_t u4SetInfoLen; + struct NETDEV_PRIVATE_GLUE_INFO *prNetDevPrivate = + (struct NETDEV_PRIVATE_GLUE_INFO *) NULL; + struct CMD_SUSPEND_MODE_SETTING rSuspendCmd; + + prNetDevPrivate = (struct NETDEV_PRIVATE_GLUE_INFO *) + netdev_priv(prDev); + + if (prNetDevPrivate->prGlueInfo != prGlueInfo) + DBGLOG(REQ, WARN, "%s: unexpected prGlueInfo(0x%p)!\n", + __func__, prNetDevPrivate->prGlueInfo); + + rSuspendCmd.ucBssIndex = prNetDevPrivate->ucBssIdx; + rSuspendCmd.ucEnableSuspendMode = fgSuspend; + + if (prGlueInfo->prAdapter->rWifiVar.ucWow + && prGlueInfo->prAdapter->rWowCtrl.fgWowEnable) { + /* cfg enable + wow enable => Wow On mdtim*/ + rSuspendCmd.ucMdtim = + prGlueInfo->prAdapter->rWifiVar.ucWowOnMdtim; + DBGLOG(REQ, INFO, "mdtim [1]\n"); + } else if (prGlueInfo->prAdapter->rWifiVar.ucWow + && !prGlueInfo->prAdapter->rWowCtrl.fgWowEnable) { + if (prGlueInfo->prAdapter->rWifiVar.ucAdvPws) { + /* cfg enable + wow disable + adv pws enable + * => Wow Off mdtim + */ + rSuspendCmd.ucMdtim = + prGlueInfo->prAdapter->rWifiVar.ucWowOffMdtim; + DBGLOG(REQ, INFO, "mdtim [2]\n"); + } + } else if (!prGlueInfo->prAdapter->rWifiVar.ucWow) { + if (prGlueInfo->prAdapter->rWifiVar.ucAdvPws) { + /* cfg disable + adv pws enable => MT6632 case + * => Wow Off mdtim + */ + rSuspendCmd.ucMdtim = + prGlueInfo->prAdapter->rWifiVar.ucWowOffMdtim; + DBGLOG(REQ, INFO, "mdtim [3]\n"); + } + } + + /* When FW receive command, it check connection state to decide apply + * setting or not + */ + + rStatus = kalIoctl(prGlueInfo, + wlanoidNotifyFwSuspend, + (void *)&rSuspendCmd, + sizeof(rSuspendCmd), + FALSE, + FALSE, + TRUE, + &u4SetInfoLen); + + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(REQ, INFO, "wlanNotifyFwSuspend fail\n"); +} + +uint32_t +wlanGetStaIdxByWlanIdx(IN struct ADAPTER *prAdapter, + IN uint8_t ucIndex, OUT uint8_t *pucStaIdx) +{ + struct WLAN_TABLE *prWtbl; + + ASSERT(prAdapter); + prWtbl = prAdapter->rWifiVar.arWtbl; + + if (ucIndex < WTBL_SIZE) { + if (prWtbl[ucIndex].ucUsed && prWtbl[ucIndex].ucPairwise) { + *pucStaIdx = prWtbl[ucIndex].ucStaIndex; + return WLAN_STATUS_SUCCESS; + } + } + return WLAN_STATUS_FAILURE; +} + +struct wiphy *wlanGetWiphy(void) +{ + if (gprWdev[0]) + return gprWdev[0]->wiphy; + + return NULL; +} + +struct net_device *wlanGetNetDev(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucBssIndex) +{ + if (!prGlueInfo) + return NULL; + + /* AIS */ + if (ucBssIndex < KAL_AIS_NUM && gprWdev[ucBssIndex]) + return gprWdev[ucBssIndex]->netdev; + + /* P2P */ + if (ucBssIndex < BSS_DEFAULT_NUM) { + struct BSS_INFO *prBssInfo = (struct BSS_INFO *) NULL; + struct GL_P2P_INFO *prGlueP2pInfo = + (struct GL_P2P_INFO *) NULL; + + prBssInfo = + GET_BSS_INFO_BY_INDEX(prGlueInfo->prAdapter, + ucBssIndex); + + if (prBssInfo && IS_BSS_P2P(prBssInfo)) { + prGlueP2pInfo = + prGlueInfo->prP2PInfo[prBssInfo->u4PrivateData]; + + if (prGlueP2pInfo) { + if ((prGlueP2pInfo->aprRoleHandler != NULL) && + (prGlueP2pInfo->aprRoleHandler != + prGlueP2pInfo->prDevHandler)) + return prGlueP2pInfo->aprRoleHandler; + else + return prGlueP2pInfo->prDevHandler; + } + } + } + + return NULL; +} + +uint8_t wlanGetBssIdx(struct net_device *ndev) +{ + if (ndev) { + struct NETDEV_PRIVATE_GLUE_INFO *prNetDevPrivate + = (struct NETDEV_PRIVATE_GLUE_INFO *) + netdev_priv(ndev); + + DBGLOG(REQ, LOUD, + "ucBssIndex = %d, ndev(%p)\n", + prNetDevPrivate->ucBssIdx, + ndev); + + return prNetDevPrivate->ucBssIdx; + } + + DBGLOG(REQ, LOUD, + "ucBssIndex = 0xff, ndev(%p)\n", + ndev); + + return 0xff; +} + +u_int8_t wlanIsAisDev(struct net_device *prDev) +{ + uint32_t u4Idx = 0; + + for (u4Idx = 0; u4Idx < KAL_AIS_NUM; u4Idx++) + if (prDev == gprWdev[u4Idx]->netdev) + return TRUE; + + return FALSE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to query LTE safe channels. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * \param[out] pvQueryBuffer A pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufferLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the call + * failed due to invalid length of the query + * buffer, returns the amount of storage needed. + * + * \retval WLAN_STATUS_PENDING + * \retval WLAN_STATUS_FAILURE + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanQueryLteSafeChannel(IN struct ADAPTER *prAdapter, + IN uint8_t ucRoleIndex) +{ + uint32_t rResult = WLAN_STATUS_FAILURE; + struct CMD_GET_LTE_SAFE_CHN rQuery_LTE_SAFE_CHN; + struct PARAM_GET_CHN_INFO *prQueryLteChn; + + DBGLOG(P2P, TRACE, "[ACS] Get safe LTE Channels\n"); + + do { + if (!prAdapter) + break; + + prQueryLteChn = kalMemAlloc(sizeof(struct PARAM_GET_CHN_INFO), + VIR_MEM_TYPE); + if (!prQueryLteChn) + break; + + kalMemZero(prQueryLteChn, sizeof(struct PARAM_GET_CHN_INFO)); + prQueryLteChn->ucRoleIndex = ucRoleIndex; + + /* Get LTE safe channel list */ + wlanSendSetQueryCmd(prAdapter, + CMD_ID_GET_LTE_CHN, + FALSE, + TRUE, + FALSE, /* Query ID */ + nicCmdEventQueryLteSafeChn, /* The handler to receive + * firmware notification + */ + nicOidCmdTimeoutCommon, + sizeof(struct CMD_GET_LTE_SAFE_CHN), + (uint8_t *)&rQuery_LTE_SAFE_CHN, + prQueryLteChn, + 0); + rResult = WLAN_STATUS_SUCCESS; + } while (FALSE); + + return rResult; +} /* wlanoidQueryLteSafeChannel */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Add dirtiness to neighbor channels of a BSS to estimate channel + * quality. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] prBssDesc Pointer to the BSS description. + * \param[in] u4Dirtiness Expected dirtiness value. + * \param[in] ucCentralChannel Central channel of the given BSS. + * \param[in] ucCoveredRange With ucCoveredRange and ucCentralChannel, + * all the affected channels can be enumerated. + */ +/*----------------------------------------------------------------------------*/ +static void +wlanAddDirtinessToAffectedChannels(struct ADAPTER *prAdapter, + struct BSS_DESC *prBssDesc, + uint32_t u4Dirtiness, + uint8_t ucCentralChannel, + uint8_t ucCoveredRange) +{ + uint8_t ucIdx, ucStart, ucEnd; + u_int8_t bIs5GChl = ucCentralChannel > 14; + uint8_t ucLeftNeighborChannel, ucRightNeighborChannel, + ucLeftNeighborChannel2 = 0, ucRightNeighborChannel2 = 0, + ucLeftestCoveredChannel, ucRightestCoveredChannel; + struct PARAM_GET_CHN_INFO *prGetChnLoad = & + (prAdapter->rWifiVar.rChnLoadInfo); + + ucLeftestCoveredChannel = ucCentralChannel > ucCoveredRange + ? + ucCentralChannel - ucCoveredRange : 1; + + ucLeftNeighborChannel = ucLeftestCoveredChannel ? + ucLeftestCoveredChannel - 1 : 0; + + /* align leftest covered ch and left neighbor ch to valid 5g ch */ + if (bIs5GChl) { + ucLeftestCoveredChannel += 2; + ucLeftNeighborChannel -= 1; + } else { + /* we select the nearest 2 ch to the leftest covered ch as left + * neighbor chs + */ + ucLeftNeighborChannel2 = ucLeftNeighborChannel > 1 ? + ucLeftNeighborChannel - 1 : 0; + } + + /* handle corner cases of 5g ch*/ + if (ucLeftestCoveredChannel > 14 + && ucLeftestCoveredChannel <= 36) { + ucLeftestCoveredChannel = 36; + ucLeftNeighborChannel = 0; + } else if (ucLeftestCoveredChannel > 64 + && ucLeftestCoveredChannel <= 100) { + ucLeftestCoveredChannel = 100; + ucLeftNeighborChannel = 0; + } else if (ucLeftestCoveredChannel > 144 && + ucLeftestCoveredChannel <= 149) { + ucLeftestCoveredChannel = 149; + ucLeftNeighborChannel = 0; + } + + /* + * because ch 14 is 12MHz away to ch13, we must shift the leftest + * covered ch and left neighbor ch when central ch is ch 14 + */ + if (ucCentralChannel == 14) { + ucLeftestCoveredChannel = 13; + ucLeftNeighborChannel = 12; + ucLeftNeighborChannel2 = 11; + } + + ucRightestCoveredChannel = ucCentralChannel + + ucCoveredRange; + ucRightNeighborChannel = ucRightestCoveredChannel + 1; + + /* align rightest covered ch and right neighbor ch to valid 5g ch */ + if (bIs5GChl) { + ucRightestCoveredChannel -= 2; + ucRightNeighborChannel += 1; + } else { + /* we select the nearest 2 ch to the rightest covered ch as + * right neighbor ch + */ + ucRightNeighborChannel2 = ucRightNeighborChannel < 13 ? + ucRightNeighborChannel + 1 : 0; + } + + /* handle corner cases */ + if (ucRightestCoveredChannel >= 14 + && ucRightestCoveredChannel < 36) { + if (ucRightestCoveredChannel == 14) { + ucRightestCoveredChannel = 13; + ucRightNeighborChannel = 14; + } else { + ucRightestCoveredChannel = 14; + ucRightNeighborChannel = 0; + } + + ucRightNeighborChannel2 = 0; + } else if (ucRightestCoveredChannel >= 64 + && ucRightestCoveredChannel < 100) { + ucRightestCoveredChannel = 64; + ucRightNeighborChannel = 0; + } else if (ucRightestCoveredChannel >= 144 && + ucRightestCoveredChannel < 149) { + ucRightestCoveredChannel = 144; + ucRightNeighborChannel = 0; + } else if (ucRightestCoveredChannel >= 165) { + ucRightestCoveredChannel = 165; + ucRightNeighborChannel = 0; + } + + log_dbg(SCN, TEMP, "central ch %u\n", ucCentralChannel); + + ucStart = wlanGetChannelIndex(ucLeftestCoveredChannel); + ucEnd = wlanGetChannelIndex(ucRightestCoveredChannel); + if (ucStart >= MAX_CHN_NUM || ucEnd >= MAX_CHN_NUM) { + DBGLOG(SCN, ERROR, "Invalid ch idx of start %u, or end %u\n", + ucStart, ucEnd); + return; + } + + for (ucIdx = ucStart; ucIdx <= ucEnd; ucIdx++) { + prGetChnLoad->rEachChnLoad[ucIdx].u4Dirtiness += + u4Dirtiness; + log_dbg(SCN, TEMP, "Add dirtiness %d, to covered ch %d\n", + u4Dirtiness, + prGetChnLoad->rEachChnLoad[ucIdx].ucChannel); + } + + if (ucLeftNeighborChannel != 0) { + ucIdx = wlanGetChannelIndex(ucLeftNeighborChannel); + + if (ucIdx < MAX_CHN_NUM) { + prGetChnLoad->rEachChnLoad[ucIdx].u4Dirtiness += + (u4Dirtiness >> 1); + log_dbg(SCN, TEMP, + "Add dirtiness %d, to neighbor ch %d\n", + u4Dirtiness >> 1, + prGetChnLoad->rEachChnLoad[ucIdx].ucChannel); + } + } + + if (ucRightNeighborChannel != 0) { + ucIdx = wlanGetChannelIndex(ucRightNeighborChannel); + if (ucIdx < MAX_CHN_NUM) { + prGetChnLoad->rEachChnLoad[ucIdx].u4Dirtiness += + (u4Dirtiness >> 1); + log_dbg(SCN, TEMP, + "Add dirtiness %d, to neighbor ch %d\n", + u4Dirtiness >> 1, + prGetChnLoad->rEachChnLoad[ucIdx].ucChannel); + } + } + + if (bIs5GChl) + return; + + /* Only necesaary for 2.5G */ + if (ucLeftNeighborChannel2 != 0) { + ucIdx = wlanGetChannelIndex(ucLeftNeighborChannel2); + if (ucIdx < MAX_CHN_NUM) { + prGetChnLoad->rEachChnLoad[ucIdx].u4Dirtiness += + (u4Dirtiness >> 1); + log_dbg(SCN, TEMP, + "Add dirtiness %d, to neighbor ch %d\n", + u4Dirtiness >> 1, + prGetChnLoad->rEachChnLoad[ucIdx].ucChannel); + } + } + + if (ucRightNeighborChannel2 != 0) { + ucIdx = wlanGetChannelIndex(ucRightNeighborChannel2); + if (ucIdx < MAX_CHN_NUM) { + prGetChnLoad->rEachChnLoad[ucIdx].u4Dirtiness += + (u4Dirtiness >> 1); + log_dbg(SCN, TEMP, + "Add dirtiness %d, to neighbor ch %d\n", + u4Dirtiness >> 1, + prGetChnLoad->rEachChnLoad[ucIdx].ucChannel); + } + } + +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief For a scanned BSS, add dirtiness to the channels 1)around its primary + * channels and 2) in its working BW to represent the quality degrade. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] prBssDesc Pointer to the BSS description. + * \param[in] u4Dirtiness Expected dirtiness value. + * \param[in] bIsIndexOne True means index 1, False means index 2. + */ +/*----------------------------------------------------------------------------*/ +static void +wlanCalculateChannelDirtiness(IN struct ADAPTER *prAdapter, + struct BSS_DESC *prBssDesc, uint32_t u4Dirtiness, + u_int8_t bIsIndexOne) +{ + uint8_t ucCoveredRange = 0, ucCentralChannel = 0, + ucCentralChannel2 = 0; + + if (bIsIndexOne) { + DBGLOG(SCN, TEMP, "Process dirtiness index 1\n"); + ucCentralChannel = prBssDesc->ucChannelNum; + ucCoveredRange = 2; + } else { + DBGLOG(SCN, TEMP, "Process dirtiness index 2, "); + switch (prBssDesc->eChannelWidth) { + case CW_20_40MHZ: + if (prBssDesc->eSco == CHNL_EXT_SCA) { + DBGLOG(SCN, TEMP, "BW40\n"); + ucCentralChannel = prBssDesc->ucChannelNum + 2; + ucCoveredRange = 4; + } else if (prBssDesc->eSco == CHNL_EXT_SCB) { + DBGLOG(SCN, TEMP, "BW40\n"); + ucCentralChannel = prBssDesc->ucChannelNum - 2; + ucCoveredRange = 4; + } else { + DBGLOG(SCN, TEMP, "BW20\n"); + ucCentralChannel = prBssDesc->ucChannelNum; + ucCoveredRange = 2; + } + break; + case CW_80MHZ: + DBGLOG(SCN, TEMP, "BW80\n"); + ucCentralChannel = prBssDesc->ucCenterFreqS1; + ucCoveredRange = 8; + break; + case CW_160MHZ: + DBGLOG(SCN, TEMP, "BW160\n"); + ucCentralChannel = prBssDesc->ucCenterFreqS1; + ucCoveredRange = 16; + break; + case CW_80P80MHZ: + DBGLOG(SCN, TEMP, "BW8080\n"); + ucCentralChannel = prBssDesc->ucCenterFreqS1; + ucCentralChannel2 = prBssDesc->ucCenterFreqS2; + ucCoveredRange = 8; + break; + default: + ucCentralChannel = prBssDesc->ucChannelNum; + ucCoveredRange = 2; + break; + }; + } + + wlanAddDirtinessToAffectedChannels(prAdapter, prBssDesc, + u4Dirtiness, + ucCentralChannel, ucCoveredRange); + + /* 80 + 80 secondary 80 case */ + if (bIsIndexOne || ucCentralChannel2 == 0) + return; + + wlanAddDirtinessToAffectedChannels(prAdapter, prBssDesc, + u4Dirtiness, + ucCentralChannel2, ucCoveredRange); +} + +void +wlanInitChnLoadInfoChannelList(IN struct ADAPTER *prAdapter) +{ + uint8_t ucIdx = 0; + struct PARAM_GET_CHN_INFO *prGetChnLoad = & + (prAdapter->rWifiVar.rChnLoadInfo); + + for (ucIdx = 0; ucIdx < MAX_CHN_NUM; ucIdx++) + prGetChnLoad->rEachChnLoad[ucIdx].ucChannel = + wlanGetChannelNumFromIndex(ucIdx); +} + +uint32_t +wlanCalculateAllChannelDirtiness(IN struct ADAPTER + *prAdapter) +{ + uint32_t rResult = WLAN_STATUS_SUCCESS; + int32_t i4Rssi = 0; + struct BSS_DESC *prBssDesc = NULL; + uint32_t u4Dirtiness = 0; + struct LINK *prBSSDescList = + &(prAdapter->rWifiVar.rScanInfo.rBSSDescList); + + LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, + struct BSS_DESC) { + i4Rssi = RCPI_TO_dBm(prBssDesc->ucRCPI); + + if (i4Rssi >= ACS_AP_RSSI_LEVEL_HIGH) + u4Dirtiness = ACS_DIRTINESS_LEVEL_HIGH; + else if (i4Rssi >= ACS_AP_RSSI_LEVEL_LOW) + u4Dirtiness = ACS_DIRTINESS_LEVEL_MID; + else + u4Dirtiness = ACS_DIRTINESS_LEVEL_LOW; + + DBGLOG(SCN, TEMP, "Found an AP(%s), primary ch %d\n", + prBssDesc->aucSSID, prBssDesc->ucChannelNum); + + /* dirtiness index1 */ + wlanCalculateChannelDirtiness(prAdapter, prBssDesc, + u4Dirtiness, TRUE); + + /* dirtiness index2 */ + wlanCalculateChannelDirtiness(prAdapter, prBssDesc, + u4Dirtiness >> 1, FALSE); + } + + return rResult; +} + +uint8_t +wlanGetChannelIndex(IN uint8_t channel) +{ + uint8_t ucIdx = MAX_CHN_NUM - 1; + + if (channel <= 14) + ucIdx = channel - 1; + else if (channel >= 36 && channel <= 64) + ucIdx = 14 + (channel - 36) / 4; + else if (channel >= 100 && channel <= 144) + ucIdx = 14 + 8 + (channel - 100) / 4; + else if (channel >= 149 && channel <= 165) + ucIdx = 14 + 8 + 12 + (channel - 149) / 4; + + return ucIdx; +} + +/*---------------------------------------------------------------------*/ +/*! + * \brief Get ch index by the given ch num; the reverse function of + * wlanGetChannelIndex + * + * \param[in] ucIdx Channel index + * \param[out] ucChannel Channel number + */ +/*---------------------------------------------------------------------*/ + +uint8_t +wlanGetChannelNumFromIndex(IN uint8_t ucIdx) +{ + uint8_t ucChannel = 0; + + if (ucIdx >= 34) + ucChannel = ((ucIdx - 34) << 2) + 149; + else if (ucIdx >= 22) + ucChannel = ((ucIdx - 22) << 2) + 100; + else if (ucIdx >= 14) + ucChannel = ((ucIdx - 14) << 2) + 36; + else + ucChannel = ucIdx + 1; + + return ucChannel; +} + +void +wlanSortChannel(IN struct ADAPTER *prAdapter, +IN enum ENUM_CHNL_SORT_POLICY ucSortType) +{ + struct PARAM_GET_CHN_INFO *prChnLoadInfo = & + (prAdapter->rWifiVar.rChnLoadInfo); + int8_t ucIdx = 0, ucRoot = 0, ucChild = 0; +#if (CFG_SUPPORT_P2PGO_ACS == 1) + uint8_t i = 0, ucBandIdx = 0, ucNumOfChannel = 0, uc2gChNum = 0; + struct RF_CHANNEL_INFO aucChannelList[MAX_CHN_NUM] = { { 0 } }; +#endif + struct PARAM_CHN_RANK_INFO rChnRankInfo; + /* prepare unsorted ch rank list */ +#if (CFG_SUPPORT_P2PGO_ACS == 1) + if (ucSortType == CHNL_SORT_POLICY_BY_CH_DOMAIN) { + for (ucBandIdx = BAND_2G4; ucBandIdx <= BAND_5G; ucBandIdx++) { + rlmDomainGetChnlList(prAdapter, + ucBandIdx, + TRUE, + MAX_CHN_NUM, + &ucNumOfChannel, + aucChannelList); + DBGLOG(SCN, TRACE, "[ACS]Band=%d, Channel Number=%d\n", + ucBandIdx, + ucNumOfChannel); + for (i = 0; i < ucNumOfChannel; i++) { + ucIdx = + wlanGetChannelIndex( + aucChannelList[i].ucChannelNum); + prChnLoadInfo-> + rChnRankList[uc2gChNum+i].ucChannel = + prChnLoadInfo-> + rEachChnLoad[ucIdx].ucChannel; + prChnLoadInfo-> + rChnRankList[uc2gChNum+i].u4Dirtiness = + prChnLoadInfo-> + rEachChnLoad[ucIdx].u4Dirtiness; + DBGLOG(SCN, TRACE, "[ACS]Ch=%d eIdx=%d,Cidx[%d]", + aucChannelList[i].ucChannelNum, + ucIdx, + uc2gChNum+i); + DBGLOG(SCN, TRACE, "[ACS]ChR[%d],eCh[%d]\n", + prChnLoadInfo-> + rChnRankList[uc2gChNum+i].ucChannel, + prChnLoadInfo-> + rEachChnLoad[ucIdx].ucChannel); + } + uc2gChNum = uc2gChNum+ucNumOfChannel; + } + /*Set the reset idx to invalid value*/ + for (i = uc2gChNum; i < MAX_CHN_NUM; i++) { + prChnLoadInfo-> + rChnRankList[i].u4Dirtiness = 0xFFFFFFFF; + prChnLoadInfo-> + rChnRankList[i].ucChannel = 0xFF; + DBGLOG(SCN, TRACE, "uc2gChNum=%d,[ACS]Chn=%d,D=%x\n", + uc2gChNum, + prChnLoadInfo-> + rChnRankList[i].ucChannel, + prChnLoadInfo-> + rChnRankList[i].u4Dirtiness); + } + } else +#endif + { + for (ucIdx = 0; ucIdx < MAX_CHN_NUM; ++ucIdx) { + prChnLoadInfo-> + rChnRankList[ucIdx].ucChannel = + prChnLoadInfo-> + rEachChnLoad[ucIdx].ucChannel; + prChnLoadInfo-> + rChnRankList[ucIdx].u4Dirtiness = + prChnLoadInfo-> + rEachChnLoad[ucIdx].u4Dirtiness; + } + } + /* heapify ch rank list */ + for (ucIdx = MAX_CHN_NUM / 2 - 1; ucIdx >= 0; --ucIdx) { + for (ucRoot = ucIdx; ucRoot * 2 + 1 < MAX_CHN_NUM; + ucRoot = ucChild) { + ucChild = ucRoot * 2 + 1; + /* Coverity check*/ + if (ucChild < 0 || ucChild >= MAX_CHN_NUM || + ucRoot < 0 || ucRoot >= MAX_CHN_NUM) + break; + if (ucChild < MAX_CHN_NUM - 1 && prChnLoadInfo-> + rChnRankList[ucChild + 1].u4Dirtiness > + prChnLoadInfo->rChnRankList[ucChild].u4Dirtiness) + ucChild += 1; + if (prChnLoadInfo->rChnRankList[ucChild].u4Dirtiness <= + prChnLoadInfo->rChnRankList[ucRoot].u4Dirtiness) + break; + DBGLOG(SCN, TRACE, "[ACS]root Chn=%d,D=%x\n", + prChnLoadInfo-> + rChnRankList[ucRoot].ucChannel, + prChnLoadInfo-> + rChnRankList[ucRoot].u4Dirtiness); + DBGLOG(SCN, TRACE, "[ACS]child Chn=%d,D=%x\n", + prChnLoadInfo-> + rChnRankList[ucChild].ucChannel, + prChnLoadInfo-> + rChnRankList[ucChild].u4Dirtiness); + kalMemCopy(&rChnRankInfo, + &(prChnLoadInfo->rChnRankList[ucChild]), + sizeof(struct PARAM_CHN_RANK_INFO)); + kalMemCopy(&prChnLoadInfo->rChnRankList[ucChild], + &prChnLoadInfo->rChnRankList[ucRoot], + sizeof(struct PARAM_CHN_RANK_INFO)); + kalMemCopy(&prChnLoadInfo->rChnRankList[ucRoot], + &rChnRankInfo, + sizeof(struct PARAM_CHN_RANK_INFO)); + DBGLOG(SCN, TRACE, + "[ACS]After root uChn=%d,D=%x\n", + prChnLoadInfo-> + rChnRankList[ucRoot].ucChannel, + prChnLoadInfo-> + rChnRankList[ucRoot].u4Dirtiness); + DBGLOG(SCN, TRACE, + "[ACS]AFter child Chn=%d,D=%x\n", + prChnLoadInfo-> + rChnRankList[ucChild].ucChannel, + prChnLoadInfo-> + rChnRankList[ucChild].u4Dirtiness); + } + } + /* sort ch rank list */ + for (ucIdx = MAX_CHN_NUM - 1; ucIdx > 0; ucIdx--) { + rChnRankInfo = prChnLoadInfo->rChnRankList[0]; + prChnLoadInfo->rChnRankList[0] = + prChnLoadInfo->rChnRankList[ucIdx]; + prChnLoadInfo->rChnRankList[ucIdx] = rChnRankInfo; + for (ucRoot = 0; ucRoot * 2 + 1 < ucIdx; ucRoot = ucChild) { + ucChild = ucRoot * 2 + 1; + /* Coverity check*/ + if (ucChild < 0 || ucChild >= MAX_CHN_NUM || + ucRoot < 0 || ucRoot >= MAX_CHN_NUM) + break; + if (ucChild < ucIdx - 1 && prChnLoadInfo-> + rChnRankList[ucChild + 1].u4Dirtiness > + prChnLoadInfo->rChnRankList[ucChild].u4Dirtiness) + ucChild += 1; + if (prChnLoadInfo->rChnRankList[ucChild].u4Dirtiness <= + prChnLoadInfo->rChnRankList[ucRoot].u4Dirtiness) + break; + DBGLOG(SCN, TRACE, + "[ACS]root ChNum=%d D=%x", + prChnLoadInfo-> + rChnRankList[ucRoot].ucChannel, + prChnLoadInfo-> + rChnRankList[ucRoot].u4Dirtiness); + DBGLOG(SCN, TRACE, "[ACS]child ChNum=%d D=%x\n", + prChnLoadInfo-> + rChnRankList[ucChild].ucChannel, + prChnLoadInfo-> + rChnRankList[ucChild].u4Dirtiness); + kalMemCopy(&rChnRankInfo, + &(prChnLoadInfo->rChnRankList[ucChild]), + sizeof(struct PARAM_CHN_RANK_INFO)); + kalMemCopy(&prChnLoadInfo->rChnRankList[ucChild], + &prChnLoadInfo->rChnRankList[ucRoot], + sizeof(struct PARAM_CHN_RANK_INFO)); + kalMemCopy(&prChnLoadInfo->rChnRankList[ucRoot], + &rChnRankInfo, + sizeof(struct PARAM_CHN_RANK_INFO)); + DBGLOG(SCN, TRACE, + "[ACS]New root ChNum=%d D=%x", + prChnLoadInfo-> + rChnRankList[ucRoot].ucChannel, + prChnLoadInfo-> + rChnRankList[ucRoot].u4Dirtiness); + + DBGLOG(SCN, TRACE, + "[ACS]New child ChNum=%d D=%x", + prChnLoadInfo-> + rChnRankList[ucChild].ucChannel, + prChnLoadInfo-> + rChnRankList[ucChild].u4Dirtiness); + } + } + + for (ucIdx = 0; ucIdx < MAX_CHN_NUM; ++ucIdx) { + DBGLOG(SCN, TRACE, "[ACS]channel=%d,dirtiness=%d\n", + prChnLoadInfo->rChnRankList[ucIdx].ucChannel, + prChnLoadInfo->rChnRankList[ucIdx].u4Dirtiness); + } + +} + +#if ((CFG_SISO_SW_DEVELOP == 1) || (CFG_SUPPORT_SPE_IDX_CONTROL == 1)) +uint8_t +wlanGetAntPathType(IN struct ADAPTER *prAdapter, + IN enum ENUM_WF_PATH_FAVOR_T eWfPathFavor) +{ + uint8_t ucFianlWfPathType = eWfPathFavor; +#if (CFG_SUPPORT_SPE_IDX_CONTROL == 1) + uint8_t ucNss = prAdapter->rWifiVar.ucNSS; + uint8_t ucSpeIdxCtrl = prAdapter->rWifiVar.ucSpeIdxCtrl; + + if (ucNss <= 2) { + if (ucSpeIdxCtrl == 0) + ucFianlWfPathType = ENUM_WF_0_ONE_STREAM_PATH_FAVOR; + else if (ucSpeIdxCtrl == 1) + ucFianlWfPathType = ENUM_WF_1_ONE_STREAM_PATH_FAVOR; + else if (ucSpeIdxCtrl == 2) { + if (ucNss > 1) + ucFianlWfPathType = + ENUM_WF_0_1_DUP_STREAM_PATH_FAVOR; + else + ucFianlWfPathType = ENUM_WF_NON_FAVOR; + } else + ucFianlWfPathType = ENUM_WF_NON_FAVOR; + } +#endif + return ucFianlWfPathType; +} + +uint8_t +wlanAntPathFavorSelect(IN struct ADAPTER *prAdapter, + IN enum ENUM_WF_PATH_FAVOR_T eWfPathFavor) +{ + uint8_t ucRetValSpeIdx = 0x18; +#if (CFG_SUPPORT_SPE_IDX_CONTROL == 1) + uint8_t ucNss = prAdapter->rWifiVar.ucNSS; + + if (ucNss <= 2) { + if ((eWfPathFavor == ENUM_WF_NON_FAVOR) || + (eWfPathFavor == ENUM_WF_0_ONE_STREAM_PATH_FAVOR) || + (eWfPathFavor == ENUM_WF_0_1_TWO_STREAM_PATH_FAVOR)) + ucRetValSpeIdx = ANTENNA_WF0; + else if (eWfPathFavor == ENUM_WF_0_1_DUP_STREAM_PATH_FAVOR) + ucRetValSpeIdx = 0x18; + else if (eWfPathFavor == ENUM_WF_1_ONE_STREAM_PATH_FAVOR) + ucRetValSpeIdx = ANTENNA_WF1; + else + ucRetValSpeIdx = ANTENNA_WF0; + } +#endif + return ucRetValSpeIdx; +} +#endif + +uint8_t +wlanGetSpeIdx(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN enum ENUM_WF_PATH_FAVOR_T eWfPathFavor) +{ + uint8_t ucRetValSpeIdx = 0; +#if ((CFG_SISO_SW_DEVELOP == 1) || (CFG_SUPPORT_SPE_IDX_CONTROL == 1)) + struct BSS_INFO *prBssInfo; + enum ENUM_BAND eBand = BAND_NULL; + + if (ucBssIndex > prAdapter->ucHwBssIdNum) { + DBGLOG(SW4, INFO, "Invalid BssInfo index[%u], skip dump!\n", + ucBssIndex); + return ucRetValSpeIdx; + } + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + /* + * if DBDC enable return 0, else depend 2.4G/5G & support WF path + * retrun accurate value + */ + if (!prAdapter->rWifiVar.fgDbDcModeEn) { + if (prBssInfo->fgIsGranted) + eBand = prBssInfo->eBandGranted; + else + eBand = prBssInfo->eBand; + + if (eBand == BAND_2G4) { + if (IS_WIFI_2G4_SISO(prAdapter)) { + if (IS_WIFI_2G4_WF0_SUPPORT(prAdapter)) + ucRetValSpeIdx = ANTENNA_WF0; + else + ucRetValSpeIdx = ANTENNA_WF1; + } else { + if (IS_WIFI_SMART_GEAR_SUPPORT_WF0_SISO( + prAdapter)) + ucRetValSpeIdx = ANTENNA_WF0; + else if (IS_WIFI_SMART_GEAR_SUPPORT_WF1_SISO( + prAdapter)) + ucRetValSpeIdx = ANTENNA_WF1; + else + ucRetValSpeIdx = wlanAntPathFavorSelect( + prAdapter, eWfPathFavor); + } + } else if (eBand == BAND_5G) { + if (IS_WIFI_5G_SISO(prAdapter)) { + if (IS_WIFI_5G_WF0_SUPPORT(prAdapter)) + ucRetValSpeIdx = ANTENNA_WF0; + else + ucRetValSpeIdx = ANTENNA_WF1; + } else { + if (IS_WIFI_SMART_GEAR_SUPPORT_WF0_SISO( + prAdapter)) + ucRetValSpeIdx = ANTENNA_WF0; + else if (IS_WIFI_SMART_GEAR_SUPPORT_WF1_SISO( + prAdapter)) + ucRetValSpeIdx = ANTENNA_WF1; + else + ucRetValSpeIdx = wlanAntPathFavorSelect( + prAdapter, eWfPathFavor); + } + } else + ucRetValSpeIdx = wlanAntPathFavorSelect(prAdapter, + eWfPathFavor); + } + DBGLOG(INIT, INFO, "SpeIdx:%d,D:%d,G=%d,B=%d,Bss=%d\n", + ucRetValSpeIdx, prAdapter->rWifiVar.fgDbDcModeEn, + prBssInfo->fgIsGranted, eBand, ucBssIndex); +#endif + return ucRetValSpeIdx; +} + +uint8_t +wlanGetSupportNss(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) +{ + struct BSS_INFO *prBssInfo; + struct AIS_FSM_INFO *prAisFsmInfo; +#if CFG_SUPPORT_IOT_AP_BLACKLIST + struct BSS_DESC *prBssDesc; +#endif + + uint8_t ucRetValNss = prAdapter->rWifiVar.ucNSS; +#if CFG_SISO_SW_DEVELOP + enum ENUM_BAND eBand = BAND_NULL; +#endif + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + if (IS_BSS_APGO(prBssInfo)) { + if (p2pFuncIsAPMode( + prAdapter->rWifiVar.prP2PConnSettings + [prBssInfo->u4PrivateData])) { + if (prBssInfo->eBand == BAND_2G4) + ucRetValNss = prAdapter->rWifiVar.ucAp2gNSS; + else if (prBssInfo->eBand == BAND_5G) + ucRetValNss = prAdapter->rWifiVar.ucAp5gNSS; + } else { + if (prBssInfo->eBand == BAND_2G4) + ucRetValNss = prAdapter->rWifiVar.ucGo2gNSS; + else if (prBssInfo->eBand == BAND_5G) + ucRetValNss = prAdapter->rWifiVar.ucGo5gNSS; + } + } +#if CFG_SUPPORT_IOT_AP_BLACKLIST + else if (IS_BSS_AIS(prBssInfo) && prAisFsmInfo != NULL) { + prBssDesc = prAisFsmInfo->prTargetBssDesc; + if (prBssDesc != NULL && + bssGetIotApAction(prAdapter, + prBssDesc) == WLAN_IOT_AP_DBDC_1SS) { + DBGLOG(SW4, INFO, "Use 1x1 due to DBDC blacklist\n"); + ucRetValNss = 1; + } else if (prAdapter->rWifiVar.fgSta1NSS) { + DBGLOG(SW4, INFO, "Use 1x1 due to FWK cmd\n"); + ucRetValNss = 1; + } + } +#endif + + if (ucRetValNss > prAdapter->rWifiVar.ucNSS) + ucRetValNss = prAdapter->rWifiVar.ucNSS; + +#if CFG_SISO_SW_DEVELOP + if (ucBssIndex > prAdapter->ucHwBssIdNum) { + DBGLOG(SW4, INFO, "Invalid BssInfo index[%u], skip dump!\n", + ucBssIndex); + return ucRetValNss; + } + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + /* + * depend 2.4G/5G support SISO/MIMO + * retrun accurate value + */ + if (prBssInfo->fgIsGranted) + eBand = prBssInfo->eBandGranted; + else + eBand = prBssInfo->eBand; + + if ((eBand == BAND_2G4) && IS_WIFI_2G4_SISO(prAdapter)) + ucRetValNss = 1; + else if ((eBand == BAND_5G) && IS_WIFI_5G_SISO(prAdapter)) + ucRetValNss = 1; + DBGLOG(INIT, TRACE, "Nss=%d,G=%d,B=%d,Bss=%d\n", + ucRetValNss, prBssInfo->fgIsGranted, eBand, ucBssIndex); +#endif + + return ucRetValNss; +} + +#if CFG_SUPPORT_LOWLATENCY_MODE +/*----------------------------------------------------------------------------*/ +/*! + * \brief This is a private routine, which is used to initialize the variables + * for low latency mode. + * + * \param prAdapter Pointer of Adapter Data Structure + * + * \retval WLAN_STATUS_SUCCESS: Success + * \retval WLAN_STATUS_FAILURE: Failed + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanAdapterStartForLowLatency(IN struct ADAPTER *prAdapter) +{ + uint32_t u4Status = WLAN_STATUS_SUCCESS; + + /* Default disable low latency mode */ + prAdapter->fgEnLowLatencyMode = FALSE; + + /* Default enable scan */ + prAdapter->fgEnCfg80211Scan = TRUE; + + /* Default disable duplicate detect */ + prAdapter->fgEnTxDupDetect = FALSE; + prAdapter->fgTxDupCertificate = FALSE; + + return u4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This is a private routine, which is used to initialize the variables + * for low latency mode. + * + * \param prAdapter Pointer of Adapter Data Structure + * + * \retval WLAN_STATUS_SUCCESS: Success + * \retval WLAN_STATUS_FAILURE: Failed + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanProbeSuccessForLowLatency(IN struct ADAPTER *prAdapter) +{ + DBGLOG(INIT, INFO, "LowLatency(ProbeOn)\n"); + + /* Reset certificate flag and query capability from firmware */ + prAdapter->fgTxDupCertificate = FALSE; + wlanSetLowLatencyCommand(prAdapter, + FALSE, + prAdapter->fgEnTxDupDetect, + TRUE); + + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This is a private routine, which is used to initialize the variables + * for low latency mode. + * + * \param prAdapter Pointer of Adapter Data Structure + * + * \retval WLAN_STATUS_SUCCESS: Success + * \retval WLAN_STATUS_FAILURE: Failed + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanConnectedForLowLatency(IN struct ADAPTER *prAdapter) +{ + uint32_t u4Events; + + /* Query setting from wifi adaptor module */ + u4Events = get_low_latency_mode(); + + /* Set low latency mode */ + DBGLOG(AIS, INFO, "LowLatency(Connected) event:0x%x\n", u4Events); + wlanSetLowLatencyMode(prAdapter, u4Events); + + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set enable/disable low latency mode to FW + * + * \param[in] prAdapter A pointer to the Adapter structure. + * + * \retval WLAN_STATUS_SUCCESS + */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanSetLowLatencyCommand( + IN struct ADAPTER *prAdapter, + IN u_int8_t fgEnLowLatencyMode, + IN u_int8_t fgEnTxDupDetect, + IN u_int8_t fgTxDupCertQuery) +{ + struct CMD_LOW_LATENCY_MODE_HEADER rModeHeader; + + rModeHeader.ucVersion = LOW_LATENCY_MODE_CMD_V2; + rModeHeader.ucType = 0; + rModeHeader.ucMagicCode = LOW_LATENCY_MODE_MAGIC_CODE; + rModeHeader.ucBufferLen = sizeof(struct LOW_LATENCY_MODE_SETTING); + rModeHeader.rSetting.fgEnable = fgEnLowLatencyMode; + rModeHeader.rSetting.fgTxDupDetect = fgEnTxDupDetect; + rModeHeader.rSetting.fgTxDupCertQuery = fgTxDupCertQuery; + + DBGLOG(AIS, INFO, + "Send Dpp Cmd to FW:en=%d, dup_Det=%d, CertQuery=%d\n", + fgEnLowLatencyMode, fgEnTxDupDetect, fgTxDupCertQuery); + + wlanSendSetQueryCmd(prAdapter, /* prAdapter */ + CMD_ID_SET_LOW_LATENCY_MODE, /* ucCID */ + TRUE, /* fgSetQuery */ + FALSE, /* fgNeedResp */ + TRUE, /* fgIsOid */ + NULL, /* pfCmdDoneHandler */ + NULL, /* pfCmdTimeoutHandler */ + sizeof(struct CMD_LOW_LATENCY_MODE_HEADER), + (uint8_t *)&rModeHeader, /* pucInfoBuffer */ + NULL, /* pvSetQueryBuffer */ + 0 /* u4SetQueryBufferLen */ + ); + + return WLAN_STATUS_SUCCESS; +} + + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to enable/disable low latency mode + * \param[in] prAdapter A pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the + * OID-specific data to be set. + * \param[in] u4SetBufferLen The number of bytes the set buffer. + * \param[out] pu4SetInfoLen Points to the number of bytes it read or is + * needed + * \retval WLAN_STATUS_SUCCESS + */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanSetLowLatencyMode( + IN struct ADAPTER *prAdapter, + IN uint32_t u4Events) +{ + u_int8_t fgEnMode = FALSE; /* Low Latency Mode */ + u_int8_t fgEnScan = FALSE; /* Scan management */ + u_int8_t fgEnPM = FALSE; /* Power management */ + u_int8_t fgEnTxDupDetect = FALSE; /* Tx Dup Detect */ + uint32_t u4PowerFlag; + struct PARAM_POWER_MODE_ rPowerMode; + struct WIFI_VAR *prWifiVar = NULL; + struct BSS_INFO *prAisBssInfo; + uint8_t ucBssIndex = AIS_DEFAULT_INDEX; + + DEBUGFUNC("wlanSetLowLatencyMode"); + + ASSERT(prAdapter); + + prAisBssInfo = + aisGetAisBssInfo(prAdapter, ucBssIndex); + if (!prAisBssInfo) { + DBGLOG(OID, ERROR, "prAisBssInfo = NULL\n"); + return WLAN_STATUS_FAILURE; + } + + /* Initialize */ + prWifiVar = &prAdapter->rWifiVar; + DBGLOG(OID, INFO, + "LowLatency(gaming/DPP) event - gas:0x%x, net:0x%x, whitelist:0x%x, txdup:0x%x, scan=%u, reorder=%u, power=%u, cmd data=%u\n", + (u4Events & GED_EVENT_GAS), + (u4Events & GED_EVENT_NETWORK), + (u4Events & GED_EVENT_DOPT_WIFI_SCAN), + (u4Events & GED_EVENT_TX_DUP_DETECT), + (uint32_t)prWifiVar->ucLowLatencyModeScan, + (uint32_t)prWifiVar->ucLowLatencyModeReOrder, + (uint32_t)prWifiVar->ucLowLatencyModePower, + (uint32_t)prWifiVar->ucLowLatencyCmdData); + + rPowerMode.ucBssIdx = prAisBssInfo->ucBssIndex; + u4PowerFlag = prAdapter->rWlanInfo.u4PowerSaveFlag[rPowerMode.ucBssIdx]; + + /* Enable/disable low latency mode decision: + * + * Enable if it's GAS and network event + * and the Glue media state is connected. + */ + if ((u4Events & GED_EVENT_GAS) != 0 + && (u4Events & GED_EVENT_NETWORK) != 0 + && MEDIA_STATE_CONNECTED + == kalGetMediaStateIndicated(prAdapter->prGlueInfo, + prAisBssInfo->ucBssIndex)) + fgEnMode = TRUE; /* It will enable low latency mode */ + + /* Enable/disable scan management decision: + * + * Enable if it will enable low latency mode. + * Or, enable if it is a white list event. + */ + if (fgEnMode != TRUE || (u4Events & GED_EVENT_DOPT_WIFI_SCAN) != 0) + fgEnScan = TRUE; /* It will enable scan management */ + + /* Enable/disable power management decision: + */ + if (BIT(PS_CALLER_GPU) & u4PowerFlag) + fgEnPM = TRUE; + else + fgEnPM = FALSE; + + /* Debug log for the actions */ + if (fgEnMode != prAdapter->fgEnLowLatencyMode + || fgEnScan != prAdapter->fgEnCfg80211Scan + || fgEnPM != fgEnMode) { + DBGLOG(OID, INFO, + "LowLatency(gaming/DPP) change (m:%d,s:%d,PM:%d,F:0x%x)\n", + fgEnMode, fgEnScan, fgEnPM, u4PowerFlag); + } + + /* Scan management: + * + * Disable/enable scan + */ + if ((prWifiVar->ucLowLatencyModeScan == FEATURE_ENABLED) && + (fgEnScan != prAdapter->fgEnCfg80211Scan)) + prAdapter->fgEnCfg80211Scan = fgEnScan; + + if ((prWifiVar->ucLowLatencyModeReOrder == FEATURE_ENABLED) && + (fgEnMode != prAdapter->fgEnLowLatencyMode)) { + prAdapter->fgEnLowLatencyMode = fgEnMode; + + /* Queue management: + * + * Change QM RX BA timeout if the gaming mode state changed + */ + if (fgEnMode) { + prAdapter->u4QmRxBaMissTimeout + = QM_RX_BA_ENTRY_MISS_TIMEOUT_MS_SHORT; + } else { + prAdapter->u4QmRxBaMissTimeout + = QM_RX_BA_ENTRY_MISS_TIMEOUT_MS; + } + } + + /* Power management: + * + * Set power saving mode profile to FW + * + * Do if 1. the power saving caller including GPU + * and 2. it will disable low latency mode. + * Or, do if 1. the power saving caller is not including GPU + * and 2. it will enable low latency mode. + */ + if ((prWifiVar->ucLowLatencyModePower == FEATURE_ENABLED) && + (fgEnPM != fgEnMode)) { + if (fgEnMode == TRUE) + rPowerMode.ePowerMode = Param_PowerModeCAM; + else + rPowerMode.ePowerMode = Param_PowerModeFast_PSP; + + nicConfigPowerSaveProfile(prAdapter, rPowerMode.ucBssIdx, + rPowerMode.ePowerMode, FALSE, PS_CALLER_GPU); + + #if CFG_SUPPORT_SMART_GEAR + wlandioSetSGStatus(prAdapter, + fgEnMode, 0x00, 0x00); + DBGLOG(OID, INFO, + "[SG] SmartGear (%d) for gaming mode\n", + fgEnMode); + #endif + + } + + DBGLOG(OID, INFO, + "LowLatency(gaming) fgEnMode=[%d]\n", fgEnMode); + + /* Force RTS to protect game packet */ + wlanSetForceRTS(prAdapter, fgEnMode); + + /* Tx Duplicate Detect management: + * + * Disable/enable tx duplicate detect + */ + if ((u4Events & GED_EVENT_TX_DUP_DETECT) != 0) + fgEnTxDupDetect = TRUE; + + DBGLOG(OID, INFO, + "EnTxDupDetect: Orig:[%d], New:[%d], CmdData:[%d], Cert:[%d]\n", + prAdapter->fgEnTxDupDetect, + fgEnTxDupDetect, + prAdapter->rWifiVar.ucLowLatencyCmdData, + prAdapter->fgTxDupCertificate); + + if (prAdapter->fgEnTxDupDetect != fgEnTxDupDetect) { + + prAdapter->fgEnTxDupDetect = fgEnTxDupDetect; + +#if CFG_TCP_IP_CHKSUM_OFFLOAD + if (prAdapter->fgIsSupportCsumOffload) { + if (prAdapter->fgEnTxDupDetect) { + /* Disable csum offload for command data */ + prAdapter->prGlueInfo-> + prDevHandler->features &= + ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); + } else { + /* Enable csum offload for cut-through data */ + prAdapter->prGlueInfo-> + prDevHandler->features |= + (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); + } + } + DBGLOG(OID, INFO, "Checksum offload: [%llu]\n", + prAdapter->prGlueInfo->prDevHandler->features); +#endif + /* Send command to firmware */ + wlanSetLowLatencyCommand(prAdapter, + prAdapter->fgEnLowLatencyMode, + prAdapter->fgEnTxDupDetect, + FALSE); + } + + return WLAN_STATUS_SUCCESS; +} + +#endif /* CFG_SUPPORT_LOWLATENCY_MODE */ + +#if CFG_SUPPORT_EASY_DEBUG + +void wlanCfgFwSetParam(uint8_t *fwBuffer, char *cmdStr, char *value, int num, + int type) +{ + struct CMD_FORMAT_V1 *cmd = (struct CMD_FORMAT_V1 *)fwBuffer + num; + + kalMemSet(cmd, 0, sizeof(struct CMD_FORMAT_V1)); + cmd->itemType = type; + + cmd->itemStringLength = strlen(cmdStr); + if (cmd->itemStringLength > MAX_CMD_NAME_MAX_LENGTH) + cmd->itemStringLength = MAX_CMD_NAME_MAX_LENGTH; + + /* here will not ensure the end will be '\0' */ + kalMemCopy(cmd->itemString, cmdStr, cmd->itemStringLength); + + cmd->itemValueLength = strlen(value); + if (cmd->itemValueLength > MAX_CMD_VALUE_MAX_LENGTH) + cmd->itemValueLength = MAX_CMD_VALUE_MAX_LENGTH; + + /* here will not ensure the end will be '\0' */ + kalMemCopy(cmd->itemValue, value, cmd->itemValueLength); +} + +uint32_t wlanCfgSetGetFw(IN struct ADAPTER *prAdapter, const char *fwBuffer, + int cmdNum, enum CMD_TYPE cmdType) +{ + struct CMD_HEADER *pcmdV1Header = NULL; + + pcmdV1Header = (struct CMD_HEADER *) + kalMemAlloc(sizeof(struct CMD_HEADER), VIR_MEM_TYPE); + + if (pcmdV1Header == NULL) + return WLAN_STATUS_FAILURE; + + kalMemSet(pcmdV1Header->buffer, 0, MAX_CMD_BUFFER_LENGTH); + pcmdV1Header->cmdType = cmdType; + pcmdV1Header->cmdVersion = CMD_VER_1_EXT; + pcmdV1Header->itemNum = cmdNum; + pcmdV1Header->cmdBufferLen = cmdNum * sizeof(struct CMD_FORMAT_V1); + kalMemCopy(pcmdV1Header->buffer, fwBuffer, pcmdV1Header->cmdBufferLen); + + wlanSendSetQueryCmd(prAdapter, CMD_ID_GET_SET_CUSTOMER_CFG, + TRUE, FALSE, FALSE, + NULL, NULL, + sizeof(struct CMD_HEADER), + (uint8_t *) pcmdV1Header, + NULL, 0); + kalMemFree(pcmdV1Header, VIR_MEM_TYPE, sizeof(struct CMD_HEADER)); + return WLAN_STATUS_SUCCESS; +} + +uint32_t wlanFwCfgParse(IN struct ADAPTER *prAdapter, uint8_t *pucConfigBuf) +{ + /* here return a list should be better */ + char *saveptr1, *saveptr2; + char *cfgItems = pucConfigBuf; + uint8_t cmdNum = 0; + + uint8_t *cmdBuffer = kalMemAlloc(MAX_CMD_BUFFER_LENGTH, VIR_MEM_TYPE); + + if (cmdBuffer == 0) { + DBGLOG(INIT, INFO, "omega, cmd buffer return fail!"); + return WLAN_STATUS_FAILURE; + } + kalMemSet(cmdBuffer, 0, MAX_CMD_BUFFER_LENGTH); + + while (1) { + char *keyStr = NULL; + char *valueStr = NULL; + char *cfgEntry = kalStrtokR(cfgItems, "\n\r", &saveptr1); + + if (!cfgEntry) { + if (cmdNum) + wlanCfgSetGetFw(prAdapter, cmdBuffer, cmdNum, + CMD_TYPE_SET); + + if (cmdBuffer) + kalMemFree(cmdBuffer, VIR_MEM_TYPE, + MAX_CMD_BUFFER_LENGTH); + + return WLAN_STATUS_SUCCESS; + } + cfgItems = NULL; + + keyStr = kalStrtokR(cfgEntry, " \t", &saveptr2); + valueStr = kalStrtokR(NULL, "\0", &saveptr2); + + /* maybe a blank line, but with some tab or whitespace */ + if (!keyStr) + continue; + + /* here take '#' at the beginning of line as comment */ + if (keyStr[0] == '#') + continue; + + /* remove the \t " " at the beginning of the valueStr */ + while (valueStr && (*valueStr == '\t' || *valueStr == ' ')) + valueStr++; + + if (keyStr && valueStr) { + wlanCfgFwSetParam(cmdBuffer, keyStr, valueStr, cmdNum, + 1); + cmdNum++; + if (cmdNum == MAX_CMD_ITEM_MAX) { + wlanCfgSetGetFw(prAdapter, cmdBuffer, + MAX_CMD_ITEM_MAX, CMD_TYPE_SET); + kalMemSet(cmdBuffer, 0, MAX_CMD_BUFFER_LENGTH); + cmdNum = 0; + } + } else { + /* here will not to try send the cmd has been parsed, + * but not sent yet + */ + if (cmdBuffer) + kalMemFree(cmdBuffer, VIR_MEM_TYPE, + MAX_CMD_BUFFER_LENGTH); + return WLAN_STATUS_FAILURE; + } + } +} +#endif /* CFG_SUPPORT_EASY_DEBUG */ + +int32_t wlanGetFileContent(struct ADAPTER *prAdapter, + const uint8_t *pcFileName, uint8_t *pucBuf, + uint32_t u4MaxFileLen, uint32_t *pu4ReadFileLen, u_int8_t bReqFw) +{ + if (bReqFw) + return kalRequestFirmware(pcFileName, pucBuf, + u4MaxFileLen, pu4ReadFileLen, + prAdapter->prGlueInfo->prDev); + + return kalReadToFile(pcFileName, pucBuf, + u4MaxFileLen, pu4ReadFileLen); +} + +void wlanReleasePendingCmdById(struct ADAPTER *prAdapter, uint8_t ucCid) +{ + struct QUE *prCmdQue; + struct QUE rTempCmdQue; + struct QUE *prTempCmdQue = &rTempCmdQue; + struct QUE_ENTRY *prQueueEntry = (struct QUE_ENTRY *) NULL; + struct CMD_INFO *prCmdInfo = (struct CMD_INFO *) NULL; + + KAL_SPIN_LOCK_DECLARATION(); + + ASSERT(prAdapter); + DBGLOG(OID, INFO, "Remove pending Cmd: CID %d\n", ucCid); + + /* 1: Clear Pending OID in prAdapter->rPendingCmdQueue */ + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); + + prCmdQue = &prAdapter->rPendingCmdQueue; + QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); + + QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, struct QUE_ENTRY *); + while (prQueueEntry) { + prCmdInfo = (struct CMD_INFO *) prQueueEntry; + if (prCmdInfo->ucCID != ucCid) { + QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); + continue; + } + + if (prCmdInfo->pfCmdTimeoutHandler) { + prCmdInfo->pfCmdTimeoutHandler(prAdapter, prCmdInfo); + } else if (prCmdInfo->fgIsOid) { + kalOidComplete(prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, 0, + WLAN_STATUS_FAILURE); + } + + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, + struct QUE_ENTRY *); + } + + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); +} + +/* Translate Decimals string to Hex +** The result will be put in a 2bytes variable. +** Integer part will occupy the left most 3 bits, and decimal part is in the +** left 13 bits +** Integer part can be parsed by kstrtou16, decimal part should be translated by +** mutiplying +** 16 and then pick integer part. +** For example +*/ +uint32_t wlanDecimalStr2Hexadecimals(uint8_t *pucDecimalStr, uint16_t *pu2Out) +{ + uint8_t aucDecimalStr[32] = {0}; + uint8_t *pucDecimalPart = NULL; + uint8_t *tmp = NULL; + uint32_t u4Result = 0; + uint32_t u4Ret = 0; + uint32_t u4Degree = 0; + uint32_t u4Remain = 0; + uint8_t ucAccuracy = 4; /* Hex decimals accuarcy is 4 bytes */ + uint32_t u4Base = 1; + + if (!pu2Out || !pucDecimalStr) + return 1; + + while (*pucDecimalStr == '0') + pucDecimalStr++; + kalStrnCpy(aucDecimalStr, pucDecimalStr, sizeof(aucDecimalStr) - 1); + aucDecimalStr[31] = 0; + pucDecimalPart = strchr(aucDecimalStr, '.'); + if (!pucDecimalPart) { + DBGLOG(INIT, INFO, "No decimal part, ori str %s\n", + pucDecimalStr); + goto integer_part; + } + *pucDecimalPart++ = 0; + /* get decimal degree */ + tmp = pucDecimalPart + strlen(pucDecimalPart); + do { + if (tmp == pucDecimalPart) { + DBGLOG(INIT, INFO, + "Decimal part are all 0, ori str %s\n", + pucDecimalStr); + goto integer_part; + } + tmp--; + } while (*tmp == '0'); + + *(++tmp) = 0; + u4Degree = (uint32_t)(tmp - pucDecimalPart); + /* if decimal part is not 0, translate it to hexadecimal decimals */ + /* Power(10, degree) */ + for (; u4Remain < u4Degree; u4Remain++) + u4Base *= 10; + + while (*pucDecimalPart == '0') + pucDecimalPart++; + + u4Ret = kalkStrtou32(pucDecimalPart, 0, &u4Remain); + if (u4Ret) { + DBGLOG(INIT, ERROR, "Parse decimal str %s error, degree %u\n", + pucDecimalPart, u4Degree); + return u4Ret; + } + + do { + u4Remain *= 16; + u4Result |= (u4Remain / u4Base) << ((ucAccuracy-1) * 4); + u4Remain %= u4Base; + ucAccuracy--; + } while (u4Remain && ucAccuracy > 0); + /* Each Hex Decimal byte was left shift more than 3 bits, so need + ** right shift 3 bits at last + ** For example, mmmnnnnnnnnnnnnn. + ** mmm is integer part, n represents decimals part. + ** the left most 4 n are shift 9 bits. But in for loop, we shift 12 bits + **/ + u4Result >>= 3; + u4Remain = 0; + +integer_part: + u4Ret = kalkStrtou32(aucDecimalStr, 0, &u4Remain); + u4Result |= u4Remain << 13; + + if (u4Ret) + DBGLOG(INIT, ERROR, "Parse integer str %s error\n", + aucDecimalStr); + else { + *pu2Out = u4Result & 0xffff; + DBGLOG(INIT, TRACE, "Result 0x%04x\n", *pu2Out); + } + return u4Ret; +} + +uint64_t wlanGetSupportedFeatureSet(IN struct GLUE_INFO *prGlueInfo) +{ + uint64_t u8FeatureSet = WIFI_HAL_FEATURE_SET; + struct REG_INFO *prRegInfo; + + prRegInfo = &(prGlueInfo->rRegInfo); + if ((prRegInfo != NULL) && (prRegInfo->ucSupport5GBand)) + u8FeatureSet |= WIFI_FEATURE_INFRA_5G; + + return u8FeatureSet; +} + +/*----------------------------------------------------------------------------*/ +/*! +* @brief This function is a wrapper to send power-saving mode command +* when AIS enter wow, and send WOW command +* Also let GC/GO/AP enter deactivate state to enter TOP sleep +* +* @param prGlueInfo Pointer of prGlueInfo Data Structure +* +* @return VOID +*/ +/*----------------------------------------------------------------------------*/ +void wlanSuspendPmHandle(struct GLUE_INFO *prGlueInfo) +{ +#if CFG_WOW_SUPPORT + /* 1) wifi cfg "Wow" is true */ + /* 2) wow is enable */ + /* 3) WIfI connected => execute WOW flow */ + if (prGlueInfo->prAdapter->rWifiVar.ucWow && + prGlueInfo->prAdapter->rWowCtrl.fgWowEnable) { + if (kalGetMediaStateIndicated(prGlueInfo, + AIS_DEFAULT_INDEX) == + MEDIA_STATE_CONNECTED) { + DBGLOG(HAL, EVENT, "enter WOW flow\n"); + kalWowProcess(prGlueInfo, TRUE); + } + + /* else: do nothing, and FW enter LMAC sleep */ + } +#endif +} + +/*----------------------------------------------------------------------------*/ +/*! +* @brief This function is to restore power-saving mode command when leave wow +* But ignore GC/GO/AP role +* +* @param prGlueInfo Pointer of prGlueInfo Data Structure +* +* @return VOID +*/ +/*----------------------------------------------------------------------------*/ +void wlanResumePmHandle(struct GLUE_INFO *prGlueInfo) +{ +#if CFG_WOW_SUPPORT + if (prGlueInfo->prAdapter->rWifiVar.ucWow) { + DBGLOG(HAL, EVENT, "leave WOW flow\n"); + kalWowProcess(prGlueInfo, FALSE); + } +#endif +} + +static uint32_t wlanHwRateOfdmNum(uint16_t ofdm_idx) +{ + switch (ofdm_idx) { + case 11: /* 6M */ + return g_rOfdmDataRateMappingTable.rate[0]; + case 15: /* 9M */ + return g_rOfdmDataRateMappingTable.rate[1]; + case 10: /* 12M */ + return g_rOfdmDataRateMappingTable.rate[2]; + case 14: /* 18M */ + return g_rOfdmDataRateMappingTable.rate[3]; + case 9: /* 24M */ + return g_rOfdmDataRateMappingTable.rate[4]; + case 13: /* 36M */ + return g_rOfdmDataRateMappingTable.rate[5]; + case 8: /* 48M */ + return g_rOfdmDataRateMappingTable.rate[6]; + case 12: /* 54M */ + return g_rOfdmDataRateMappingTable.rate[7]; + default: + return 0; + } +} + +int wlanQueryRateByTable(uint32_t txmode, uint32_t rate, + uint32_t frmode, uint32_t sgi, uint32_t nsts, + uint32_t *pu4CurRate, uint32_t *pu4MaxRate) +{ + uint32_t u4CurRate, u4MaxRate; + uint8_t ucMaxSize; + + if (txmode == TX_RATE_MODE_CCK) { /* 11B */ + ucMaxSize = ARRAY_SIZE(g_rCckDataRateMappingTable.rate); + /* short preamble */ + if ((rate >= 5) && (rate <= 7)) + rate -= 4; + if (rate >= ucMaxSize) { + DBGLOG(SW4, ERROR, "rate error for CCK: %u\n", rate); + return -1; + } + u4CurRate = g_rCckDataRateMappingTable.rate[rate]; + u4MaxRate = g_rCckDataRateMappingTable.rate[ucMaxSize - 1]; + } else if (txmode == TX_RATE_MODE_OFDM) { /* 11G */ + u4CurRate = wlanHwRateOfdmNum(rate); + if (u4CurRate == 0) { + DBGLOG(SW4, ERROR, "rate error for OFDM\n"); + return -1; + } + ucMaxSize = ARRAY_SIZE(g_rOfdmDataRateMappingTable.rate); + u4MaxRate = g_rOfdmDataRateMappingTable.rate[ucMaxSize - 1]; + } else if ((txmode == TX_RATE_MODE_HTMIX) || + (txmode == TX_RATE_MODE_HTGF)) { /* 11N */ + if (rate >= 8 && rate <= 15) { + rate -= 8; + } else if (rate >= 16 && rate <= 23) { + rate -= 16; + } else if (rate < 0 || rate > 23) { + DBGLOG(SW4, ERROR, "rate error for 11N: %u\n", + rate); + return -1; + } + if (frmode > 1) { + DBGLOG(SW4, ERROR, + "frmode error for 11N: %u\n", + frmode); + return -1; + } + u4CurRate = g_rDataRateMappingTable.nsts[nsts - 1].bw[frmode] + .sgi[sgi].rate[rate]; + ucMaxSize = 8; + u4MaxRate = g_rDataRateMappingTable.nsts[nsts - 1].bw[frmode] + .sgi[sgi].rate[ucMaxSize - 1]; + } else if (txmode == TX_RATE_MODE_HE_SU) { /* AX */ + if ((nsts == 0) || (nsts >= 5)) { + DBGLOG(SW4, ERROR, "nsts error: %u\n", nsts); + return -1; + } + if (frmode > 3) { + DBGLOG(SW4, ERROR, + "frmode error for 11AX: %u\n", + frmode); + return -1; + } + u4CurRate = g_rAxDataRateMappingTable.nsts[nsts - 1] + .bw[frmode].gi[sgi].rate[rate]; + ucMaxSize = ARRAY_SIZE(g_rAxDataRateMappingTable.nsts[nsts - 1] + .bw[frmode].gi[sgi].rate); + u4MaxRate = g_rAxDataRateMappingTable.nsts[nsts - 1] + .bw[frmode].gi[sgi].rate[ucMaxSize - 1]; + } else { /* 11AC */ + if ((nsts == 0) || (nsts >= 4)) { + DBGLOG(SW4, ERROR, "nsts error: %u\n", nsts); + return -1; + } + if (frmode > 3) { + DBGLOG(SW4, ERROR, + "frmode error for 11AC: %u\n", + frmode); + return -1; + } + u4CurRate = g_rDataRateMappingTable.nsts[nsts - 1] + .bw[frmode].sgi[sgi].rate[rate]; + ucMaxSize = ARRAY_SIZE(g_rDataRateMappingTable.nsts[nsts - 1] + .bw[frmode].sgi[sgi].rate); + u4MaxRate = g_rDataRateMappingTable.nsts[nsts - 1] + .bw[frmode].sgi[sgi].rate[ucMaxSize - 1]; + } + *pu4CurRate = u4CurRate; + *pu4MaxRate = u4MaxRate; + return 0; +} + +#if defined(CFG_REPORT_MAX_TX_RATE) && (CFG_REPORT_MAX_TX_RATE == 1) +int wlanGetMaxTxRate(IN struct ADAPTER *prAdapter, + IN void *prBssPtr, IN struct STA_RECORD *prStaRec, + OUT uint32_t *pu4CurRate, OUT uint32_t *pu4MaxRate) +{ + struct BSS_INFO *prBssInfo; + uint8_t ucPhyType, ucTxMode = 0, ucMcsIdx = 0, ucSgi = 0; + uint8_t ucBw = 0, ucAPBwPermitted = 0, ucNss = 0, ucApNss = 0; + uint8_t ucOffset = (MAX_BW_80MHZ - CW_80MHZ); + struct BSS_DESC *prBssDesc = NULL; + + *pu4CurRate = 0; + *pu4MaxRate = 0; + prBssInfo = (struct BSS_INFO *) prBssPtr; + + /* get tx mode and MCS index */ + ucPhyType = prBssInfo->ucPhyTypeSet; + + DBGLOG(SW4, TRACE, + "ucPhyType: 0x%x\n", + ucPhyType); + +#if (CFG_SUPPORT_802_11AX == 1) + if (ucPhyType & PHY_TYPE_SET_802_11AX) + ucTxMode = TX_RATE_MODE_HE_SU; + else +#endif + if (ucPhyType & PHY_TYPE_SET_802_11AC) + ucTxMode = TX_RATE_MODE_VHT; + else if (ucPhyType & PHY_TYPE_SET_802_11N) + ucTxMode = TX_RATE_MODE_HTMIX; + else if (ucPhyType & PHY_TYPE_SET_802_11G) { + ucTxMode = TX_RATE_MODE_OFDM; + ucMcsIdx = 12; + } else if (ucPhyType & PHY_TYPE_SET_802_11A) { + ucTxMode = TX_RATE_MODE_OFDM; + ucMcsIdx = 12; + } else if (ucPhyType & PHY_TYPE_SET_802_11B) + ucTxMode = TX_RATE_MODE_CCK; + else { + DBGLOG(SW4, ERROR, + "unknown wifi type, prBssInfo->ucPhyTypeSet: %u\n", + ucPhyType); + goto errhandle; + } + + /* get bandwidth */ + ucBw = cnmGetBssMaxBw(prAdapter, prBssInfo->ucBssIndex); + prBssDesc = aisGetTargetBssDesc(prAdapter, prBssInfo->ucBssIndex); + if (prBssDesc) { + ucAPBwPermitted = MAX_BW_160MHZ; + if (prBssDesc->eChannelWidth == CW_20_40MHZ) { + if ((prBssDesc->eSco == CHNL_EXT_SCA) + || (prBssDesc->eSco == CHNL_EXT_SCB)) + ucAPBwPermitted = MAX_BW_40MHZ; + else + ucAPBwPermitted = MAX_BW_20MHZ; + } else { + ucAPBwPermitted = prBssDesc->eChannelWidth + ucOffset; + } + if ((ucAPBwPermitted < MAX_BW_20MHZ) || + (ucAPBwPermitted > MAX_BW_80_80_MHZ)) { + DBGLOG(SW4, ERROR, + "unknown band width: %u\n", ucAPBwPermitted); + goto errhandle; + } else if (ucAPBwPermitted == MAX_BW_80_80_MHZ) + ucAPBwPermitted = MAX_BW_160MHZ; + } else { + DBGLOG(SW4, ERROR, "prBssDesc is null\n"); + goto errhandle; + } + if (ucAPBwPermitted < ucBw) + ucBw = ucAPBwPermitted; + + /* get Short GI Tx capability */ + if ((prStaRec->u2HtCapInfo & HT_CAP_INFO_SHORT_GI_20M) == + HT_CAP_INFO_SHORT_GI_20M) { + DBGLOG(RLM, TRACE, "HT_CAP_INFO_SHORT_GI_20M\n"); + ucSgi = 1; + } + if ((prStaRec->u2HtCapInfo & HT_CAP_INFO_SHORT_GI_40M) == + HT_CAP_INFO_SHORT_GI_40M) { + DBGLOG(RLM, TRACE, "HT_CAP_INFO_SHORT_GI_40M\n"); + ucSgi = 1; + } +#if CFG_SUPPORT_802_11AC + if ((prStaRec->u4VhtCapInfo & VHT_CAP_INFO_SHORT_GI_80) == + VHT_CAP_INFO_SHORT_GI_80) { + DBGLOG(RLM, TRACE, "VHT_CAP_INFO_SHORT_GI_80\n"); + ucSgi = 1; + } + if ((prStaRec->u4VhtCapInfo & VHT_CAP_INFO_SHORT_GI_160_80P80) == + VHT_CAP_INFO_SHORT_GI_160_80P80) { + DBGLOG(RLM, TRACE, "VHT_CAP_INFO_SHORT_GI_160_80P80\n"); + ucSgi = 1; + } +#endif + + if (ucTxMode == TX_RATE_MODE_HE_SU) { + DBGLOG(SW4, TRACE, "TX_RATE_MODE_HE_SU\n"); + ucSgi = 0; + } + + /* get antenna number */ + ucNss = wlanGetSupportNss(prAdapter, prBssInfo->ucBssIndex); + if (prBssDesc) { + ucApNss = bssGetRxNss(prAdapter, prBssDesc); + if (ucApNss > 0 && ucApNss < ucNss) + ucNss = ucApNss; + } + if ((ucNss < 1) && (ucNss > 3)) { + DBGLOG(RLM, ERROR, "error ucNss: %u\n", ucNss); + goto errhandle; + } + + DBGLOG(SW4, TRACE, + "txmode=[%u], mcs idx=[%u], bandwidth=[%u], sgi=[%u], nsts=[%u]\n", + ucTxMode, ucMcsIdx, ucBw, ucSgi, ucNss + ); + + if (wlanQueryRateByTable(ucTxMode, ucMcsIdx, ucBw, ucSgi, + ucNss, pu4CurRate, pu4MaxRate) < 0) + goto errhandle; + + DBGLOG(SW4, TRACE, + "*pu4CurRate=[%u], *pu4MaxRate=[%u]\n", + *pu4CurRate, *pu4MaxRate); + + return 0; + +errhandle: + DBGLOG(SW4, ERROR, + "txmode=[%u], mcs idx=[%u], bandwidth=[%u], sgi=[%u], nsts=[%u]\n", + ucTxMode, ucMcsIdx, ucBw, ucSgi, ucNss); + return -1; +} +#endif /* CFG_REPORT_MAX_TX_RATE */ + +#ifdef CFG_SUPPORT_LINK_QUALITY_MONITOR +int wlanGetRxRate(IN struct GLUE_INFO *prGlueInfo, + OUT uint32_t *pu4CurRate, OUT uint32_t *pu4MaxRate) +{ + struct ADAPTER *prAdapter; + uint32_t rxmode = 0, rate = 0, frmode = 0, sgi = 0, nss = 0; + uint32_t u4RxVector0 = 0, u4RxVector1 = 0; + int rv; + struct CHIP_DBG_OPS *prChipDbg; + + *pu4CurRate = 0; + *pu4MaxRate = 0; + prAdapter = prGlueInfo->prAdapter; + + prChipDbg = prAdapter->chip_info->prDebugOps; + if (prChipDbg && prChipDbg->get_rx_rate_info) { + rv = prChipDbg->get_rx_rate_info( + prAdapter, + &rate, + &nss, + &rxmode, + &frmode, + &sgi); + + if (rv < 0) + goto errhandle; + } + + rv = wlanQueryRateByTable(rxmode, rate, frmode, sgi, nss, + pu4CurRate, pu4MaxRate); + if (rv < 0) + goto errhandle; + + return 0; + +errhandle: + DBGLOG(SW4, TRACE, + "u4RxVector0=[%x], u4RxVector1=[%x], rxmode=[%u], rate=[%u], frmode=[%u], sgi=[%u], nss=[%u]\n", + u4RxVector0, u4RxVector1, rxmode, rate, frmode, sgi, nss + ); + return -1; +} + +uint32_t wlanLinkQualityMonitor(struct GLUE_INFO *prGlueInfo, bool bFgIsOid) +{ + struct ADAPTER *prAdapter; + struct WIFI_LINK_QUALITY_INFO *prLinkQualityInfo = NULL; + struct PARAM_GET_STA_STATISTICS *prQueryStaStatistics; + struct PARAM_802_11_STATISTICS_STRUCT *prStat; + uint32_t u4BufLen = 0; + uint8_t arBssid[PARAM_MAC_ADDR_LEN]; + uint32_t u4Status = WLAN_STATUS_FAILURE; + uint8_t ucBssIndex = AIS_DEFAULT_INDEX; + + if (kalGetMediaStateIndicated(prGlueInfo, + ucBssIndex) != + MEDIA_STATE_CONNECTED) { + /* not connected */ + DBGLOG(SW4, ERROR, "not yet connected\n"); + return u4Status; + } + + prAdapter = prGlueInfo->prAdapter; + if (prAdapter == NULL) { + DBGLOG(SW4, ERROR, "prAdapter is null\n"); + return u4Status; + } + + /* Completely record the Link quality and store the current time */ + prAdapter->u4LastLinkQuality = kalGetTimeTick(); + DBGLOG(NIC, TRACE, "LastLinkQuality:%u\n", + prAdapter->u4LastLinkQuality); + + kalMemZero(arBssid, MAC_ADDR_LEN); + SET_IOCTL_BSSIDX(prGlueInfo->prAdapter, ucBssIndex); + wlanQueryInformation(prAdapter, wlanoidQueryBssid, + &arBssid[0], sizeof(arBssid), &u4BufLen); + + /* send cmd to firmware */ + prQueryStaStatistics = &(prAdapter->rQueryStaStatistics); + prStat = &(prAdapter->rStat); + kalMemZero(prQueryStaStatistics, + sizeof(struct PARAM_GET_STA_STATISTICS)); + kalMemZero(prStat, sizeof(struct PARAM_802_11_STATISTICS_STRUCT)); + COPY_MAC_ADDR(prQueryStaStatistics->aucMacAddr, arBssid); + prQueryStaStatistics->ucReadClear = TRUE; + u4Status = wlanQueryStaStatistics(prAdapter, + prQueryStaStatistics, + sizeof(struct PARAM_GET_STA_STATISTICS), + &(prAdapter->u4BufLen), + FALSE); + u4Status = wlanQueryStatistics(prAdapter, + prStat, + sizeof(struct PARAM_802_11_STATISTICS_STRUCT), + &(prAdapter->u4BufLen), + FALSE); + + if (bFgIsOid == FALSE) + u4Status = WLAN_STATUS_SUCCESS; + + if ((bFgIsOid == TRUE) || (prAdapter->u4LastLinkQuality <= 0)) + return u4Status; + + prLinkQualityInfo = &(prAdapter->rLinkQualityInfo); + +#if CFG_SUPPORT_DATA_STALL + wlanCustomMonitorFunction(prAdapter, prLinkQualityInfo, ucBssIndex); +#endif + + DBGLOG(SW4, INFO, + "Link Quality: Tx(rate:%u, total:%lu, retry:%lu, fail:%lu, RTS fail:%lu, ACK fail:%lu), Rx(rate:%u, total:%lu, dup:%u, error:%lu), PER(%u), Congestion(idle slot:%lu, diff:%lu, AwakeDur:%u)\n", + prLinkQualityInfo->u4CurTxRate, /* current tx link speed */ + prLinkQualityInfo->u8TxTotalCount, /* tx total packages */ + prLinkQualityInfo->u8TxRetryCount, /* tx retry count */ + prLinkQualityInfo->u8TxFailCount, /* tx fail count */ + prLinkQualityInfo->u8TxRtsFailCount, /* tx RTS fail count */ + prLinkQualityInfo->u8TxAckFailCount, /* tx ACK fail count */ + prLinkQualityInfo->u4CurRxRate, /* current rx link speed */ + prLinkQualityInfo->u8RxTotalCount, /* rx total packages */ + prLinkQualityInfo->u4RxDupCount, /* rx duplicate package count */ + prLinkQualityInfo->u8RxErrCount, /* rx fcs fail count */ + prLinkQualityInfo->u4CurTxPer, /* current Tx PER */ + /* congestion stats */ + prLinkQualityInfo->u8IdleSlotCount, /* idle slot */ + prLinkQualityInfo->u8DiffIdleSlotCount, /* idle slot diff */ + prLinkQualityInfo->u4HwMacAwakeDuration + ); + + return u4Status; +} + +void wlanFinishCollectingLinkQuality(struct GLUE_INFO *prGlueInfo) +{ + struct ADAPTER *prAdapter; + struct WIFI_LINK_QUALITY_INFO *prLinkQualityInfo = NULL; + uint32_t u4CurRxRate, u4MaxRxRate; + uint64_t u8TxFailCntDif, u8TxTotalCntDif; + + prAdapter = prGlueInfo->prAdapter; + if (prAdapter == NULL) { + DBGLOG(SW4, ERROR, "prAdapter is null\n"); + return; + } + + /* prepare to set/get statistics from BSSInfo's rLinkQualityInfo */ + prLinkQualityInfo = &(prAdapter->rLinkQualityInfo); + + /* Calculate current tx PER */ + u8TxTotalCntDif = (prLinkQualityInfo->u8TxTotalCount > + prLinkQualityInfo->u8LastTxTotalCount) ? + (prLinkQualityInfo->u8TxTotalCount - + prLinkQualityInfo->u8LastTxTotalCount) : 0; + u8TxFailCntDif = (prLinkQualityInfo->u8TxFailCount > + prLinkQualityInfo->u8LastTxFailCount) ? + (prLinkQualityInfo->u8TxFailCount - + prLinkQualityInfo->u8LastTxFailCount) : 0; + if (u8TxTotalCntDif >= u8TxFailCntDif) + prLinkQualityInfo->u4CurTxPer = (u8TxTotalCntDif == 0) ? 0 : + ((uint32_t)(u8TxFailCntDif * 100) / + (uint32_t)u8TxTotalCntDif); + else + prLinkQualityInfo->u4CurTxPer = 0; + + /* Calculate idle slot diff */ + if (prLinkQualityInfo->u8IdleSlotCount < + prLinkQualityInfo->u8LastIdleSlotCount) { + prLinkQualityInfo->u8DiffIdleSlotCount = 0; + DBGLOG(NIC, WARN, "idle slot is error\n"); + } else + prLinkQualityInfo->u8DiffIdleSlotCount = + prLinkQualityInfo->u8IdleSlotCount - + prLinkQualityInfo->u8LastIdleSlotCount; + + /* get current rx rate */ + if (wlanGetRxRate(prGlueInfo, &u4CurRxRate, &u4MaxRxRate) < 0) + prLinkQualityInfo->u4CurRxRate = 0; + else + prLinkQualityInfo->u4CurRxRate = u4CurRxRate; + + prLinkQualityInfo->u8LastTxTotalCount = + prLinkQualityInfo->u8TxTotalCount; + prLinkQualityInfo->u8LastTxFailCount = + prLinkQualityInfo->u8TxFailCount; + prLinkQualityInfo->u8LastIdleSlotCount = + prLinkQualityInfo->u8IdleSlotCount; +} +#endif /* CFG_SUPPORT_LINK_QUALITY_MONITOR */ + +#if CFG_SUPPORT_DATA_STALL +void wlanCustomMonitorFunction(struct ADAPTER *prAdapter, + struct WIFI_LINK_QUALITY_INFO *prLinkQualityInfo, uint8_t ucBssIdx) +{ + uint64_t u8TxTotalCntDif; + + u8TxTotalCntDif = (prLinkQualityInfo->u8TxTotalCount > + prLinkQualityInfo->u8LastTxTotalCount) ? + (prLinkQualityInfo->u8TxTotalCount - + prLinkQualityInfo->u8LastTxTotalCount) : 0; + + /* Add custom monitor here */ + if (u8TxTotalCntDif >= prAdapter->rWifiVar.u4TrafficThreshold) { + if (prLinkQualityInfo->u4CurTxRate < + prAdapter->rWifiVar.u4TxLowRateThreshole) + KAL_REPORT_ERROR_EVENT(prAdapter, + EVENT_TX_LOW_RATE, + (uint16_t)sizeof(uint32_t), + ucBssIdx, + FALSE); + else if (prLinkQualityInfo->u4CurRxRate < + prAdapter->rWifiVar.u4RxLowRateThreshole) + KAL_REPORT_ERROR_EVENT(prAdapter, + EVENT_RX_LOW_RATE, + (uint16_t)sizeof(uint32_t), + ucBssIdx, + FALSE); + else if (prLinkQualityInfo->u4CurTxPer > + prAdapter->rWifiVar.u4PerHighThreshole) + KAL_REPORT_ERROR_EVENT(prAdapter, + EVENT_PER_HIGH, + (uint16_t)sizeof(uint32_t), + ucBssIdx, + FALSE); + } +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set enable/disable force RTS mode to FW + * + * \param[in] prAdapter A pointer to the Adapter structure. + * + * \retval WLAN_STATUS_SUCCESS + */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanSetForceRTS( + IN struct ADAPTER *prAdapter, + IN u_int8_t fgEnForceRTS) +{ + struct CMD_SET_FORCE_RTS rForceRts; + + rForceRts.ucForceRtsEn = fgEnForceRTS; + rForceRts.ucRtsPktNum = 0; + DBGLOG(REQ, INFO, "fgEnForceRTS = %d\n", + fgEnForceRTS); + wlanSendSetQueryCmd(prAdapter, /* prAdapter */ + CMD_ID_SET_FORCE_RTS, /* ucCID */ + TRUE, /* fgSetQuery */ + FALSE, /* fgNeedResp */ + FALSE, /* fgIsOid */ + NULL, /* pfCmdDoneHandler */ + NULL, /* pfCmdTimeoutHandler */ + sizeof(struct CMD_SET_FORCE_RTS), + (uint8_t *)&rForceRts, /* pucInfoBuffer */ + NULL, /* pvSetQueryBuffer */ + 0 /* u4SetQueryBufferLen */ + ); + + return WLAN_STATUS_SUCCESS; +} + +void +wlanLoadDefaultCustomerSetting(IN struct ADAPTER * + prAdapter) +{ + + uint8_t ucItemNum, i; + + /* default setting*/ + ucItemNum = (sizeof(g_rDefaulteSetting) / sizeof( + struct PARAM_CUSTOM_KEY_CFG_STRUCT)); + + DBGLOG(INIT, STATE, "Default firmware setting %d item\n", + ucItemNum); + + + for (i = 0; i < ucItemNum; i++) { + wlanCfgSet(prAdapter, + g_rDefaulteSetting[i].aucKey, + g_rDefaulteSetting[i].aucValue, + g_rDefaulteSetting[i].u4Flag); + DBGLOG(INIT, TRACE, "%s with %s\n", + g_rDefaulteSetting[i].aucKey, + g_rDefaulteSetting[i].aucValue); + } + + +#if 1 + /*If need to re-parsing , included wlanInitFeatureOption*/ + wlanInitFeatureOption(prAdapter); +#endif +} +/*wlan on*/ +void +wlanResoreEmCfgSetting(IN struct ADAPTER * + prAdapter) +{ + uint32_t i; + + for (i = 0; i < WLAN_CFG_ENTRY_NUM_MAX; i++) { + + if (g_rEmCfgBk[i].aucKey[0] == '\0') + continue; + + wlanCfgSet(prAdapter, g_rEmCfgBk[i].aucKey, + g_rEmCfgBk[i].aucValue, WLAN_CFG_EM); + + DBGLOG(INIT, STATE, + "cfg restore:(%s,%s) op:%d\n", + g_rEmCfgBk[i].aucKey, + g_rEmCfgBk[i].aucValue, + g_rEmCfgBk[i].u4Flag); + + } + +} + +/*wlan off*/ +void +wlanBackupEmCfgSetting(IN struct ADAPTER * + prAdapter) +{ + uint32_t i; + struct WLAN_CFG_ENTRY *prWlanCfgEntry = NULL; + + kalMemZero(&g_rEmCfgBk, sizeof(g_rEmCfgBk)); + + for (i = 0; i < WLAN_CFG_ENTRY_NUM_MAX; i++) { + prWlanCfgEntry = + wlanCfgGetEntryByIndex(prAdapter, i, WLAN_CFG_EM); + + if ((!prWlanCfgEntry) || (prWlanCfgEntry->aucKey[0] == '\0')) + break; + + + kalStrnCpy(g_rEmCfgBk[i].aucKey, prWlanCfgEntry->aucKey, + WLAN_CFG_KEY_LEN_MAX - 1); + prWlanCfgEntry->aucKey[WLAN_CFG_KEY_LEN_MAX - 1] = '\0'; + + kalStrnCpy(g_rEmCfgBk[i].aucValue, prWlanCfgEntry->aucValue, + WLAN_CFG_VALUE_LEN_MAX - 1); + prWlanCfgEntry->aucValue[WLAN_CFG_VALUE_LEN_MAX - 1] = '\0'; + + + g_rEmCfgBk[i].u4Flag = WLAN_CFG_EM; + + DBGLOG(INIT, STATE, + "cfg backup:(%s,%s) op:%d\n", + g_rEmCfgBk[i].aucKey, + g_rEmCfgBk[i].aucValue, + g_rEmCfgBk[i].u4Flag); + + } + + +} + +void +wlanCleanAllEmCfgSetting(IN struct ADAPTER * + prAdapter) +{ + uint32_t i; + struct WLAN_CFG_ENTRY *prWlanCfgEntry = NULL; + + for (i = 0; i < WLAN_CFG_ENTRY_NUM_MAX; i++) { + prWlanCfgEntry = + wlanCfgGetEntryByIndex(prAdapter, i, WLAN_CFG_EM); + + if ((!prWlanCfgEntry) || (prWlanCfgEntry->aucKey[0] == '\0')) + break; + + DBGLOG(INIT, STATE, + "cfg clean:(%s,%s) op:%d\n", + prWlanCfgEntry->aucKey, + prWlanCfgEntry->aucValue, + prWlanCfgEntry->u4Flags); + + kalMemZero(prWlanCfgEntry, sizeof(struct WLAN_CFG_ENTRY)); + + } +} + +u_int8_t wlanWfdEnabled(struct ADAPTER *prAdapter) +{ +#if CFG_SUPPORT_WFD + if (prAdapter) + return prAdapter->rWifiVar.rWfdConfigureSettings.ucWfdEnable; +#endif + return FALSE; +} + +int wlanChipConfig(struct ADAPTER *prAdapter, + char *pcCommand, int i4TotalLen) +{ + uint32_t rStatus = WLAN_STATUS_SUCCESS; + int32_t i4BytesWritten = 0; + uint32_t u4BufLen = 0; + uint32_t u2MsgSize = 0; + uint32_t u4CmdLen = 0; + struct PARAM_CUSTOM_CHIP_CONFIG_STRUCT rChipConfigInfo = {0}; + + if (prAdapter == NULL) { + DBGLOG(REQ, ERROR, "prAdapter null"); + return -1; + } + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + + u4CmdLen = kalStrnLen(pcCommand, i4TotalLen); + + rChipConfigInfo.ucType = CHIP_CONFIG_TYPE_ASCII; + rChipConfigInfo.u2MsgSize = u4CmdLen; + kalStrnCpy(rChipConfigInfo.aucCmd, pcCommand, + CHIP_CONFIG_RESP_SIZE - 1); + rChipConfigInfo.aucCmd[CHIP_CONFIG_RESP_SIZE - 1] = '\0'; + rStatus = kalIoctl(prAdapter->prGlueInfo, wlanoidQueryChipConfig, + &rChipConfigInfo, sizeof(rChipConfigInfo), + TRUE, TRUE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, ERROR, "%s: kalIoctl ret=%d\n", __func__, + rStatus); + return -1; + } + rChipConfigInfo.aucCmd[CHIP_CONFIG_RESP_SIZE - 1] = '\0'; + + /* Check respType */ + u2MsgSize = rChipConfigInfo.u2MsgSize; + DBGLOG(REQ, INFO, "%s: RespTyep %u\n", __func__, + rChipConfigInfo.ucRespType); + DBGLOG(REQ, INFO, "%s: u2MsgSize %u\n", __func__, + rChipConfigInfo.u2MsgSize); + + if (rChipConfigInfo.ucRespType != CHIP_CONFIG_TYPE_ASCII) { + DBGLOG(REQ, WARN, "only return as ASCII"); + return -1; + } + if (u2MsgSize > sizeof(rChipConfigInfo.aucCmd)) { + DBGLOG(REQ, INFO, "%s: u2MsgSize error ret=%u\n", + __func__, rChipConfigInfo.u2MsgSize); + return -1; + } + i4BytesWritten = snprintf(pcCommand, i4TotalLen, "%s", + rChipConfigInfo.aucCmd); + return i4BytesWritten; +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/common/wlan_oid.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/common/wlan_oid.c new file mode 100644 index 0000000000000000000000000000000000000000..5d8915da97dcc5f9bfca5ae7fa7e21ad983f1b4a --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/common/wlan_oid.c @@ -0,0 +1,16565 @@ +/******************************************************************************* + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/common + * /wlan_oid.c#11 + */ + +/*! \file wlanoid.c + * \brief This file contains the WLAN OID processing routines of Windows + * driver for MediaTek Inc. 802.11 Wireless LAN Adapters. + */ + + +/****************************************************************************** + * C O M P I L E R F L A G S + ****************************************************************************** + */ + +/****************************************************************************** + * E X T E R N A L R E F E R E N C E S + ****************************************************************************** + */ +#include "precomp.h" +#include "mgmt/rsn.h" +#include "debug.h" + +/****************************************************************************** + * C O N S T A N T S + ****************************************************************************** + */ + +/****************************************************************************** + * D A T A T Y P E S + ****************************************************************************** + */ + +/****************************************************************************** + * P U B L I C D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * P R I V A T E D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * M A C R O S + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N D E C L A R A T I O N S + ****************************************************************************** + */ +#if DBG && 0 +static void SetRCID(u_int8_t fgOneTb3, u_int8_t *fgRCID); +#endif + +#if CFG_SLT_SUPPORT +static void SetTestChannel(uint8_t *pucPrimaryChannel); +#endif + +/****************************************************************************** + * F U N C T I O N S + ****************************************************************************** + */ +static void setApUapsdEnable(struct ADAPTER *prAdapter, + u_int8_t enable) +{ + struct PARAM_CUSTOM_UAPSD_PARAM_STRUCT rUapsdParams; + uint32_t u4SetInfoLen = 0; + uint8_t ucBssIdx; + + /* FIX ME: Add p2p role index selection */ + if (p2pFuncRoleToBssIdx( + prAdapter, 0, &ucBssIdx) != WLAN_STATUS_SUCCESS) + return; + + DBGLOG(OID, INFO, "setApUapsdEnable: %d, ucBssIdx: %d\n", + enable, ucBssIdx); + + rUapsdParams.ucBssIdx = ucBssIdx; + + if (enable) { + prAdapter->rWifiVar.ucApUapsd = TRUE; + rUapsdParams.fgEnAPSD = 1; + rUapsdParams.fgEnAPSD_AcBe = 1; + rUapsdParams.fgEnAPSD_AcBk = 1; + rUapsdParams.fgEnAPSD_AcVi = 1; + rUapsdParams.fgEnAPSD_AcVo = 1; + /* default: 0, do not limit delivery pkt number */ + rUapsdParams.ucMaxSpLen = 0; + } else { + prAdapter->rWifiVar.ucApUapsd = FALSE; + rUapsdParams.fgEnAPSD = 0; + rUapsdParams.fgEnAPSD_AcBe = 0; + rUapsdParams.fgEnAPSD_AcBk = 0; + rUapsdParams.fgEnAPSD_AcVi = 0; + rUapsdParams.fgEnAPSD_AcVo = 0; + /* default: 0, do not limit delivery pkt number */ + rUapsdParams.ucMaxSpLen = 0; + } + wlanoidSetUApsdParam(prAdapter, + &rUapsdParams, + sizeof(struct PARAM_CUSTOM_UAPSD_PARAM_STRUCT), + &u4SetInfoLen); +} + +#if CFG_ENABLE_STATISTICS_BUFFERING +static u_int8_t IsBufferedStatisticsUsable( + struct ADAPTER *prAdapter) +{ + ASSERT(prAdapter); + + if (prAdapter->fgIsStatValid == TRUE && + (kalGetTimeTick() - prAdapter->rStatUpdateTime) <= + CFG_STATISTICS_VALID_CYCLE) + return TRUE; + else + return FALSE; +} +#endif + +#if DBG && 0 +static void SetRCID(u_int8_t fgOneTb3, u_int8_t *fgRCID) +{ + if (fgOneTb3) + *fgRCID = 0; + else + *fgRCID = 1; +} +#endif + +#if CFG_SLT_SUPPORT +static void SetTestChannel(uint8_t *pucPrimaryChannel) +{ + if (*pucPrimaryChannel < 5) + *pucPrimaryChannel = 8; + else if (*pucPrimaryChannel > 10) + *pucPrimaryChannel = 3; +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to query the supported physical layer network + * type that can be used by the driver. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[out] pvQueryBuffer A pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufferLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the call + * failed due to invalid length of the query buffer, + * returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryNetworkTypesSupported(IN struct ADAPTER + *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) +{ + uint32_t u4NumItem = 0; + enum ENUM_PARAM_NETWORK_TYPE + eSupportedNetworks[PARAM_NETWORK_TYPE_NUM]; + struct PARAM_NETWORK_TYPE_LIST *prSupported; + + /* The array of all physical layer network subtypes that the driver + * supports. + */ + + DEBUGFUNC("wlanoidQueryNetworkTypesSupported"); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + /* Init. */ + for (u4NumItem = 0; u4NumItem < PARAM_NETWORK_TYPE_NUM; + u4NumItem++) + eSupportedNetworks[u4NumItem] = 0; + + u4NumItem = 0; + + eSupportedNetworks[u4NumItem] = PARAM_NETWORK_TYPE_DS; + u4NumItem++; + + eSupportedNetworks[u4NumItem] = PARAM_NETWORK_TYPE_OFDM24; + u4NumItem++; + + *pu4QueryInfoLen = + (uint32_t) OFFSET_OF(struct PARAM_NETWORK_TYPE_LIST, + eNetworkType) + + (u4NumItem * sizeof(enum ENUM_PARAM_NETWORK_TYPE)); + + if (u4QueryBufferLen < *pu4QueryInfoLen) + return WLAN_STATUS_INVALID_LENGTH; + + prSupported = (struct PARAM_NETWORK_TYPE_LIST *) + pvQueryBuffer; + prSupported->NumberOfItems = u4NumItem; + kalMemCopy(prSupported->eNetworkType, eSupportedNetworks, + u4NumItem * sizeof(enum ENUM_PARAM_NETWORK_TYPE)); + + DBGLOG(REQ, TRACE, "NDIS supported network type list: %u\n", + prSupported->NumberOfItems); + DBGLOG_MEM8(REQ, INFO, prSupported, *pu4QueryInfoLen); + + return WLAN_STATUS_SUCCESS; +} /* wlanoidQueryNetworkTypesSupported */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to query the current physical layer network + * type used by the driver. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[out] pvQueryBuffer A pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufferLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the + * call failed due to invalid length of the query + * buffer, returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_BUFFER_TOO_SHORT + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryNetworkTypeInUse(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) +{ + /* TODO: need to check the OID handler content again!! */ + + enum ENUM_PARAM_NETWORK_TYPE rCurrentNetworkTypeInUse = + PARAM_NETWORK_TYPE_OFDM24; + uint8_t ucBssIndex = AIS_DEFAULT_INDEX; + + DEBUGFUNC("wlanoidQueryNetworkTypeInUse"); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + if (u4QueryBufferLen < sizeof(enum + ENUM_PARAM_NETWORK_TYPE)) { + *pu4QueryInfoLen = sizeof(enum ENUM_PARAM_NETWORK_TYPE); + return WLAN_STATUS_BUFFER_TOO_SHORT; + } + + if (kalGetMediaStateIndicated(prAdapter->prGlueInfo, + ucBssIndex) == + MEDIA_STATE_CONNECTED) + rCurrentNetworkTypeInUse = (enum ENUM_PARAM_NETWORK_TYPE) ( + prAdapter->rWlanInfo.ucNetworkType[ucBssIndex]); + else + rCurrentNetworkTypeInUse = (enum ENUM_PARAM_NETWORK_TYPE) ( + prAdapter->rWlanInfo.ucNetworkTypeInUse); + + *(enum ENUM_PARAM_NETWORK_TYPE *) pvQueryBuffer = + rCurrentNetworkTypeInUse; + *pu4QueryInfoLen = sizeof(enum ENUM_PARAM_NETWORK_TYPE); + + DBGLOG(REQ, TRACE, "Network type in use: %d\n", + rCurrentNetworkTypeInUse); + + return WLAN_STATUS_SUCCESS; +} /* wlanoidQueryNetworkTypeInUse */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set the physical layer network type used + * by the driver. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns the + * amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS The given network type is supported and accepted. + * \retval WLAN_STATUS_INVALID_DATA The given network type is not in the + * supported list. + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetNetworkTypeInUse(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + /* TODO: need to check the OID handler content again!! */ + + enum ENUM_PARAM_NETWORK_TYPE eNewNetworkType; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + + DEBUGFUNC("wlanoidSetNetworkTypeInUse"); + + ASSERT(prAdapter); + ASSERT(pvSetBuffer); + ASSERT(pu4SetInfoLen); + + if (u4SetBufferLen < sizeof(enum ENUM_PARAM_NETWORK_TYPE)) { + *pu4SetInfoLen = sizeof(enum ENUM_PARAM_NETWORK_TYPE); + return WLAN_STATUS_INVALID_LENGTH; + } + + eNewNetworkType = *(enum ENUM_PARAM_NETWORK_TYPE *) + pvSetBuffer; + *pu4SetInfoLen = sizeof(enum ENUM_PARAM_NETWORK_TYPE); + + DBGLOG(REQ, INFO, "New network type: %d mode\n", + eNewNetworkType); + + switch (eNewNetworkType) { + + case PARAM_NETWORK_TYPE_DS: + prAdapter->rWlanInfo.ucNetworkTypeInUse = + (uint8_t) PARAM_NETWORK_TYPE_DS; + break; + + case PARAM_NETWORK_TYPE_OFDM5: + prAdapter->rWlanInfo.ucNetworkTypeInUse = + (uint8_t) PARAM_NETWORK_TYPE_OFDM5; + break; + + case PARAM_NETWORK_TYPE_OFDM24: + prAdapter->rWlanInfo.ucNetworkTypeInUse = + (uint8_t) PARAM_NETWORK_TYPE_OFDM24; + break; + + case PARAM_NETWORK_TYPE_AUTOMODE: + prAdapter->rWlanInfo.ucNetworkTypeInUse = + (uint8_t) PARAM_NETWORK_TYPE_AUTOMODE; + break; + + case PARAM_NETWORK_TYPE_FH: + DBGLOG(REQ, INFO, "Not support network type: %d\n", + eNewNetworkType); + rStatus = WLAN_STATUS_NOT_SUPPORTED; + break; + + default: + DBGLOG(REQ, INFO, "Unknown network type: %d\n", + eNewNetworkType); + rStatus = WLAN_STATUS_INVALID_DATA; + break; + } + + /* Verify if we support the new network type. */ + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(REQ, WARN, "Unknown network type: %d\n", + eNewNetworkType); + + return rStatus; +} /* wlanoidSetNetworkTypeInUse */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to query the current BSSID. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[out] pvQueryBuffer A pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufferLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the call + * failed due to invalid length of the query buffer, + * returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_ADAPTER_NOT_READY + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryBssid(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) +{ + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint8_t ucBssIndex = 0; + struct PARAM_BSSID_EX *prCurrBssid; + + DEBUGFUNC("wlanoidQueryBssid"); + + ASSERT(prAdapter); + + if (u4QueryBufferLen < MAC_ADDR_LEN) { + ASSERT(pu4QueryInfoLen); + *pu4QueryInfoLen = MAC_ADDR_LEN; + return WLAN_STATUS_BUFFER_TOO_SHORT; + } + + ASSERT(u4QueryBufferLen >= MAC_ADDR_LEN); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + ASSERT(pu4QueryInfoLen); + + ucBssIndex = GET_IOCTL_BSSIDX(prAdapter); + + prCurrBssid = aisGetCurrBssId(prAdapter, + ucBssIndex); + + if (kalGetMediaStateIndicated(prAdapter->prGlueInfo, + ucBssIndex) == + MEDIA_STATE_CONNECTED) + kalMemCopy(pvQueryBuffer, + prCurrBssid->arMacAddress, + MAC_ADDR_LEN); + else if (aisGetOPMode(prAdapter, ucBssIndex) == + NET_TYPE_IBSS) { + uint8_t aucTemp[PARAM_MAC_ADDR_LEN]; /*!< BSSID */ + + COPY_MAC_ADDR(aucTemp, + prCurrBssid->arMacAddress); + aucTemp[0] &= ~BIT(0); + aucTemp[1] |= BIT(1); + COPY_MAC_ADDR(pvQueryBuffer, aucTemp); + } else + rStatus = WLAN_STATUS_ADAPTER_NOT_READY; + + *pu4QueryInfoLen = MAC_ADDR_LEN; + return rStatus; +} /* wlanoidQueryBssid */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to query the list of all BSSIDs detected by + * the driver. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[out] pvQueryBuffer A pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufferLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the call + * failed due to invalid length of the query buffer, + * returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + * \retval WLAN_STATUS_ADAPTER_NOT_READY + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryBssidList(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) +{ + struct GLUE_INFO *prGlueInfo; + uint32_t i, u4BssidListExLen; + struct PARAM_BSSID_LIST_EX *prList; + struct PARAM_BSSID_EX *prBssidEx; + uint8_t *cp; + + DEBUGFUNC("wlanoidQueryBssidList"); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + + if (u4QueryBufferLen) { + ASSERT(pvQueryBuffer); + + if (!pvQueryBuffer) + return WLAN_STATUS_INVALID_DATA; + } + + prGlueInfo = prAdapter->prGlueInfo; + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, WARN, + "Fail in qeury BSSID list! (Adapter not ready). ACPI=D%d, Radio=%d\n", + prAdapter->rAcpiState, prAdapter->fgIsRadioOff); + return WLAN_STATUS_ADAPTER_NOT_READY; + } + + u4BssidListExLen = 0; + + if (prAdapter->fgIsRadioOff == FALSE) { + for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) + u4BssidListExLen += ALIGN_4( + prAdapter->rWlanInfo.arScanResult[i].u4Length); + } + + if (u4BssidListExLen) + u4BssidListExLen += 4; /* u4NumberOfItems. */ + else + u4BssidListExLen = sizeof(struct PARAM_BSSID_LIST_EX); + + *pu4QueryInfoLen = u4BssidListExLen; + + if (u4QueryBufferLen < *pu4QueryInfoLen) + return WLAN_STATUS_INVALID_LENGTH; + + /* Clear the buffer */ + kalMemZero(pvQueryBuffer, u4BssidListExLen); + + prList = (struct PARAM_BSSID_LIST_EX *) pvQueryBuffer; + cp = (uint8_t *) &prList->arBssid[0]; + + if (prAdapter->fgIsRadioOff == FALSE + && prAdapter->rWlanInfo.u4ScanResultNum > 0) { + /* fill up for each entry */ + for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { + prBssidEx = (struct PARAM_BSSID_EX *) cp; + + /* copy structure */ + kalMemCopy(prBssidEx, + &(prAdapter->rWlanInfo.arScanResult[i]), + OFFSET_OF(struct PARAM_BSSID_EX, aucIEs)); + + /* For WHQL test, Rssi should be + * in range -10 ~ -200 dBm + */ + if (prBssidEx->rRssi > PARAM_WHQL_RSSI_MAX_DBM) + prBssidEx->rRssi = PARAM_WHQL_RSSI_MAX_DBM; + + if (prAdapter->rWlanInfo.arScanResult[i].u4IELength + > 0) { + /* copy IEs */ + kalMemCopy(prBssidEx->aucIEs, + prAdapter->rWlanInfo.apucScanResultIEs[i], + prAdapter->rWlanInfo.arScanResult[i] + .u4IELength); + } + /* 4-bytes alignement */ + prBssidEx->u4Length = ALIGN_4(prBssidEx->u4Length); + + cp += prBssidEx->u4Length; + prList->u4NumberOfItems++; + } + } + + return WLAN_STATUS_SUCCESS; +} /* wlanoidQueryBssidList */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to request the driver to perform + * scanning. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_ADAPTER_NOT_READY + * \retval WLAN_STATUS_FAILURE + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetBssidListScan(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + struct PARAM_SSID *prSsid; + struct PARAM_SSID rSsid; + uint8_t ucBssIndex = 0; + + DEBUGFUNC("wlanoidSetBssidListScan()"); + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(OID, WARN, + "Fail in set BSSID list scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", + prAdapter->rAcpiState, prAdapter->fgIsRadioOff); + return WLAN_STATUS_ADAPTER_NOT_READY; + } else if (prAdapter->fgTestMode) { + DBGLOG(OID, WARN, "didn't support Scan in test mode\n"); + return WLAN_STATUS_FAILURE; + } + + ASSERT(pu4SetInfoLen); + + ucBssIndex = GET_IOCTL_BSSIDX(prAdapter); + + DBGLOG(REQ, LOUD, "ucBssIndex %d\n", ucBssIndex); + + *pu4SetInfoLen = 0; + + if (prAdapter->fgIsRadioOff) { + DBGLOG(OID, WARN, + "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", + prAdapter->rAcpiState, prAdapter->fgIsRadioOff); + return WLAN_STATUS_SUCCESS; + } + + if (pvSetBuffer != NULL && u4SetBufferLen != 0) { + COPY_SSID(rSsid.aucSsid, rSsid.u4SsidLen, pvSetBuffer, + u4SetBufferLen); + prSsid = &rSsid; + } else { + prSsid = NULL; + } + +#if CFG_SUPPORT_RDD_TEST_MODE + if (prAdapter->prGlueInfo->prRegInfo->u4RddTestMode) { + if (prAdapter->fgEnOnlineScan && prAdapter->ucRddStatus) { + if (kalGetMediaStateIndicated(prAdapter->prGlueInfo, + ucBssIndex) + != MEDIA_STATE_CONNECTED) + aisFsmScanRequest(prAdapter, prSsid, NULL, 0, + ucBssIndex); + else + return WLAN_STATUS_FAILURE; + } else + return WLAN_STATUS_FAILURE; + } else +#endif + { + if (prAdapter->fgEnOnlineScan == TRUE) + aisFsmScanRequest(prAdapter, prSsid, NULL, 0, + ucBssIndex); + else if (kalGetMediaStateIndicated(prAdapter->prGlueInfo, + ucBssIndex) != + MEDIA_STATE_CONNECTED) + aisFsmScanRequest(prAdapter, prSsid, NULL, 0, + ucBssIndex); + else + return WLAN_STATUS_FAILURE; + } + + return WLAN_STATUS_SUCCESS; +} /* wlanoidSetBssidListScan */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to request the driver to perform + * scanning with attaching information elements(IEs) specified from user + * space + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_ADAPTER_NOT_READY + * \retval WLAN_STATUS_FAILURE + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetBssidListScanExt(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + struct PARAM_SCAN_REQUEST_EXT *prScanRequest; + struct PARAM_SSID *prSsid; + uint8_t *pucIe; + uint32_t u4IeLength; + uint8_t ucBssIndex = 0; + + DEBUGFUNC("wlanoidSetBssidListScanExt()"); + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(OID, WARN, + "Fail in set BSSID list scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", + prAdapter->rAcpiState, prAdapter->fgIsRadioOff); + return WLAN_STATUS_ADAPTER_NOT_READY; + } else if (prAdapter->fgTestMode) { + DBGLOG(OID, WARN, "didn't support Scan in test mode\n"); + return WLAN_STATUS_FAILURE; + } + + ASSERT(pu4SetInfoLen); + *pu4SetInfoLen = 0; + + if (u4SetBufferLen != sizeof(struct PARAM_SCAN_REQUEST_EXT)) + return WLAN_STATUS_INVALID_LENGTH; + + if (prAdapter->fgIsRadioOff) { + DBGLOG(OID, WARN, + "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", + prAdapter->rAcpiState, prAdapter->fgIsRadioOff); + return WLAN_STATUS_SUCCESS; + } + DBGLOG(OID, TRACE, "ScanEX\n"); + if (pvSetBuffer != NULL && u4SetBufferLen != 0) { + prScanRequest = (struct PARAM_SCAN_REQUEST_EXT *) + pvSetBuffer; + prSsid = &(prScanRequest->rSsid); + pucIe = prScanRequest->pucIE; + u4IeLength = prScanRequest->u4IELength; + ucBssIndex = prScanRequest->ucBssIndex; + } else { + prScanRequest = NULL; + prSsid = NULL; + pucIe = NULL; + u4IeLength = 0; + } + +#if CFG_SUPPORT_RDD_TEST_MODE + if (prAdapter->prGlueInfo->prRegInfo->u4RddTestMode) { + if (prAdapter->fgEnOnlineScan && prAdapter->ucRddStatus) { + if (kalGetMediaStateIndicated(prAdapter->prGlueInfo, + ucBssIndex) + != MEDIA_STATE_CONNECTED) + aisFsmScanRequest(prAdapter, prSsid, + pucIe, u4IeLength, + ucBssIndex); + else + return WLAN_STATUS_FAILURE; + } else + return WLAN_STATUS_FAILURE; + } else +#endif + { + if (prAdapter->fgEnOnlineScan == TRUE) + aisFsmScanRequest(prAdapter, prSsid, pucIe, u4IeLength, + ucBssIndex); + else if (kalGetMediaStateIndicated(prAdapter->prGlueInfo, + ucBssIndex) != + MEDIA_STATE_CONNECTED) + aisFsmScanRequest(prAdapter, prSsid, pucIe, u4IeLength, + ucBssIndex); + else + return WLAN_STATUS_FAILURE; + } + + return WLAN_STATUS_SUCCESS; +} /* wlanoidSetBssidListScanWithIE */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to request the driver to perform + * scanning with attaching information elements(IEs) specified from user + * space and multiple SSID + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_ADAPTER_NOT_READY + * \retval WLAN_STATUS_FAILURE + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetBssidListScanAdv(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + struct PARAM_SCAN_REQUEST_ADV *prScanRequest; + uint8_t ucBssIndex = 0; + + DEBUGFUNC("wlanoidSetBssidListScanAdv()"); + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(OID, WARN, + "Fail in set BSSID list scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", + prAdapter->rAcpiState, prAdapter->fgIsRadioOff); + return WLAN_STATUS_ADAPTER_NOT_READY; + } else if (prAdapter->fgTestMode) { + DBGLOG(OID, WARN, "didn't support Scan in test mode\n"); + return WLAN_STATUS_FAILURE; + } + + ASSERT(pu4SetInfoLen); + *pu4SetInfoLen = 0; + + if (u4SetBufferLen != sizeof(struct PARAM_SCAN_REQUEST_ADV)) + return WLAN_STATUS_INVALID_LENGTH; + else if (pvSetBuffer == NULL) + return WLAN_STATUS_INVALID_DATA; + + if (prAdapter->fgIsRadioOff) { + DBGLOG(OID, WARN, + "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", + prAdapter->rAcpiState, prAdapter->fgIsRadioOff); + return WLAN_STATUS_SUCCESS; + } + + prScanRequest = (struct PARAM_SCAN_REQUEST_ADV *) pvSetBuffer; + ucBssIndex = prScanRequest->ucBssIndex; +#if CFG_SUPPORT_RDD_TEST_MODE + if (prAdapter->prGlueInfo->prRegInfo->u4RddTestMode) { + if (prAdapter->fgEnOnlineScan && prAdapter->ucRddStatus) { + if (kalGetMediaStateIndicated(prAdapter->prGlueInfo, + ucBssIndex) + != MEDIA_STATE_CONNECTED) { + aisFsmScanRequestAdv(prAdapter, prScanRequest); + } else + return WLAN_STATUS_FAILURE; + } else + return WLAN_STATUS_FAILURE; + } else +#endif + { + if (prAdapter->fgEnOnlineScan == TRUE) { + aisFsmScanRequestAdv(prAdapter, prScanRequest); + } else if (kalGetMediaStateIndicated(prAdapter->prGlueInfo, + ucBssIndex) + != MEDIA_STATE_CONNECTED) { + aisFsmScanRequestAdv(prAdapter, prScanRequest); + } else + return WLAN_STATUS_FAILURE; + } + cnmTimerStartTimer(prAdapter, + aisGetScanDoneTimer(prAdapter, ucBssIndex), + SEC_TO_MSEC(AIS_SCN_DONE_TIMEOUT_SEC)); + return WLAN_STATUS_SUCCESS; +} /* wlanoidSetBssidListScanAdv */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine will initiate the join procedure to attempt to associate + * with the specified BSSID. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + * \retval WLAN_STATUS_INVALID_DATA + * \retval WLAN_STATUS_ADAPTER_NOT_READY + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetBssid(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + struct GLUE_INFO *prGlueInfo; + uint8_t *pAddr; + uint32_t i; + int32_t i4Idx = -1; + struct MSG_AIS_ABORT *prAisAbortMsg; + uint8_t ucReasonOfDisconnect; + struct CONNECTION_SETTINGS *prConnSettings; + struct PARAM_BSSID_EX *prCurrBssid; + uint8_t ucBssIndex = 0; + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + ucBssIndex = GET_IOCTL_BSSIDX(prAdapter); + + DBGLOG(REQ, LOUD, "ucBssIndex %d\n", ucBssIndex); + + prConnSettings = + aisGetConnSettings(prAdapter, ucBssIndex); + + prCurrBssid = aisGetCurrBssId(prAdapter, + ucBssIndex); + + *pu4SetInfoLen = MAC_ADDR_LEN; + if (u4SetBufferLen != MAC_ADDR_LEN) { + *pu4SetInfoLen = MAC_ADDR_LEN; + return WLAN_STATUS_INVALID_LENGTH; + } else if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, WARN, + "Fail in set ssid! (Adapter not ready). ACPI=D%d, Radio=%d\n", + prAdapter->rAcpiState, prAdapter->fgIsRadioOff); + return WLAN_STATUS_ADAPTER_NOT_READY; + } + + prGlueInfo = prAdapter->prGlueInfo; + pAddr = (uint8_t *) pvSetBuffer; + + /* re-association check */ + if (kalGetMediaStateIndicated(prGlueInfo, ucBssIndex) == + MEDIA_STATE_CONNECTED) { + if (EQUAL_MAC_ADDR( + prCurrBssid->arMacAddress, pAddr)) { + kalSetMediaStateIndicated(prGlueInfo, + MEDIA_STATE_TO_BE_INDICATED, + ucBssIndex); + ucReasonOfDisconnect = + DISCONNECT_REASON_CODE_REASSOCIATION; + } else { + kalIndicateStatusAndComplete(prGlueInfo, + WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0, + ucBssIndex); + ucReasonOfDisconnect = + DISCONNECT_REASON_CODE_NEW_CONNECTION; + } + } else { + ucReasonOfDisconnect = + DISCONNECT_REASON_CODE_NEW_CONNECTION; + } + + /* check if any scanned result matchs with the BSSID */ + for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { + if (EQUAL_MAC_ADDR( + prAdapter->rWlanInfo.arScanResult[i].arMacAddress, pAddr)) { + i4Idx = (int32_t) i; + break; + } + } + + /* prepare message to AIS */ + if (prConnSettings->eOPMode == + NET_TYPE_IBSS + || prConnSettings->eOPMode == + NET_TYPE_DEDICATED_IBSS) { + /* IBSS *//* beacon period */ + prConnSettings->u2BeaconPeriod = + prAdapter->rWlanInfo.u2BeaconPeriod; + prConnSettings->u2AtimWindow = + prAdapter->rWlanInfo.u2AtimWindow; + } + + /* Set Connection Request Issued Flag */ + prConnSettings->eConnectionPolicy = + CONNECT_BY_BSSID; + + /* Send AIS Abort Message */ + prAisAbortMsg = (struct MSG_AIS_ABORT *) cnmMemAlloc( + prAdapter, RAM_TYPE_MSG, sizeof(struct MSG_AIS_ABORT)); + if (!prAisAbortMsg) { + DBGLOG(REQ, ERROR, "Fail in allocating AisAbortMsg.\n"); + return WLAN_STATUS_FAILURE; + } + + prAisAbortMsg->rMsgHdr.eMsgId = MID_OID_AIS_FSM_JOIN_REQ; + prAisAbortMsg->ucReasonOfDisconnect = ucReasonOfDisconnect; + + /* Update the information to CONNECTION_SETTINGS_T */ + prConnSettings->ucSSIDLen = 0; + prConnSettings->aucSSID[0] = '\0'; + COPY_MAC_ADDR(prConnSettings->aucBSSID, pAddr); + + if (EQUAL_MAC_ADDR(prCurrBssid->arMacAddress, pAddr)) + prAisAbortMsg->fgDelayIndication = TRUE; + else + prAisAbortMsg->fgDelayIndication = FALSE; + prAisAbortMsg->ucBssIndex = ucBssIndex; + mboxSendMsg(prAdapter, MBOX_ID_0, + (struct MSG_HDR *) prAisAbortMsg, MSG_SEND_METHOD_BUF); + + return WLAN_STATUS_SUCCESS; +} /* end of wlanoidSetBssid() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine will initiate the join procedure to attempt + * to associate with the new SSID. If the previous scanning + * result is aged, we will scan the channels at first. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_DATA + * \retval WLAN_STATUS_ADAPTER_NOT_READY + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetSsid(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + struct GLUE_INFO *prGlueInfo; + struct PARAM_SSID *pParamSsid; + uint32_t i; + int32_t i4Idx = -1, i4MaxRSSI = INT_MIN; + struct MSG_AIS_ABORT *prAisAbortMsg; + u_int8_t fgIsValidSsid = TRUE; + struct CONNECTION_SETTINGS *prConnSettings; + struct PARAM_BSSID_EX *prCurrBssid; + uint8_t ucBssIndex = 0; + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + /* MSDN: + * Powering on the radio if the radio is powered off through a setting + * of OID_802_11_DISASSOCIATE + */ + if (prAdapter->fgIsRadioOff == TRUE) + prAdapter->fgIsRadioOff = FALSE; + + if (u4SetBufferLen < sizeof(struct PARAM_SSID) + || u4SetBufferLen > sizeof(struct PARAM_SSID)) + return WLAN_STATUS_INVALID_LENGTH; + else if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, WARN, + "Fail in set ssid! (Adapter not ready). ACPI=D%d, Radio=%d\n", + prAdapter->rAcpiState, prAdapter->fgIsRadioOff); + return WLAN_STATUS_ADAPTER_NOT_READY; + } + + pParamSsid = (struct PARAM_SSID *) pvSetBuffer; + + if (pParamSsid->u4SsidLen > 32) + return WLAN_STATUS_INVALID_LENGTH; + + prGlueInfo = prAdapter->prGlueInfo; + + ucBssIndex = GET_IOCTL_BSSIDX(prAdapter); + + prConnSettings = + aisGetConnSettings(prAdapter, ucBssIndex); + prCurrBssid = aisGetCurrBssId(prAdapter, + ucBssIndex); + + /* prepare for CMD_BUILD_CONNECTION & CMD_GET_CONNECTION_STATUS */ + /* re-association check */ + if (kalGetMediaStateIndicated(prGlueInfo, ucBssIndex) == + MEDIA_STATE_CONNECTED) { + if (EQUAL_SSID(prCurrBssid->rSsid.aucSsid, + prCurrBssid->rSsid.u4SsidLen, + pParamSsid->aucSsid, pParamSsid->u4SsidLen)) { + kalSetMediaStateIndicated(prGlueInfo, + MEDIA_STATE_TO_BE_INDICATED, + ucBssIndex); + } else + kalIndicateStatusAndComplete(prGlueInfo, + WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0, + ucBssIndex); + } + /* check if any scanned result matchs with the SSID */ + for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { + uint8_t *aucSsid = + prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid; + uint8_t ucSsidLength = (uint8_t) + prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen; + int32_t i4RSSI = prAdapter->rWlanInfo.arScanResult[i].rRssi; + + if (EQUAL_SSID(aucSsid, ucSsidLength, pParamSsid->aucSsid, + pParamSsid->u4SsidLen) && + i4RSSI >= i4MaxRSSI) { + i4Idx = (int32_t) i; + i4MaxRSSI = i4RSSI; + } + } + + /* prepare message to AIS */ + if (prConnSettings->eOPMode == + NET_TYPE_IBSS + || prConnSettings->eOPMode == + NET_TYPE_DEDICATED_IBSS) { + /* IBSS *//* beacon period */ + prConnSettings->u2BeaconPeriod = + prAdapter->rWlanInfo.u2BeaconPeriod; + prConnSettings->u2AtimWindow = + prAdapter->rWlanInfo.u2AtimWindow; + } + + if (prAdapter->rWifiVar.fgSupportWZCDisassociation) { + if (pParamSsid->u4SsidLen == ELEM_MAX_LEN_SSID) { + fgIsValidSsid = FALSE; + + for (i = 0; i < ELEM_MAX_LEN_SSID; i++) { + if (!((pParamSsid->aucSsid[i] > 0) + && (pParamSsid->aucSsid[i] <= 0x1F))) { + fgIsValidSsid = TRUE; + break; + } + } + } + } + + /* Set Connection Request Issued Flag */ + if (fgIsValidSsid) { + if (pParamSsid->u4SsidLen) + prConnSettings->eConnectionPolicy = + CONNECT_BY_SSID_BEST_RSSI; + else + /* wildcard SSID */ + prConnSettings->eConnectionPolicy = + CONNECT_BY_SSID_ANY; + } + + /* Send AIS Abort Message */ + prAisAbortMsg = (struct MSG_AIS_ABORT *) cnmMemAlloc( + prAdapter, RAM_TYPE_MSG, sizeof(struct MSG_AIS_ABORT)); + if (!prAisAbortMsg) { + DBGLOG(REQ, ERROR, "Fail in allocating AisAbortMsg.\n"); + return WLAN_STATUS_FAILURE; + } + + prAisAbortMsg->rMsgHdr.eMsgId = MID_OID_AIS_FSM_JOIN_REQ; + prAisAbortMsg->ucReasonOfDisconnect = + DISCONNECT_REASON_CODE_NEW_CONNECTION; + COPY_SSID(prConnSettings->aucSSID, + prConnSettings->ucSSIDLen, + pParamSsid->aucSsid, (uint8_t) pParamSsid->u4SsidLen); + + if (EQUAL_SSID( + prCurrBssid->rSsid.aucSsid, + prCurrBssid->rSsid.u4SsidLen, + pParamSsid->aucSsid, pParamSsid->u4SsidLen)) { + prAisAbortMsg->fgDelayIndication = TRUE; + } else { + /* Update the information to CONNECTION_SETTINGS_T */ + prAisAbortMsg->fgDelayIndication = FALSE; + } + + prAisAbortMsg->ucBssIndex = ucBssIndex; + + DBGLOG(SCN, INFO, "ucBssIndex %d, SSID %s\n", + ucBssIndex, + HIDE(prConnSettings->aucSSID)); + + mboxSendMsg(prAdapter, MBOX_ID_0, + (struct MSG_HDR *) prAisAbortMsg, MSG_SEND_METHOD_BUF); + + return WLAN_STATUS_SUCCESS; + +} /* end of wlanoidSetSsid() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine will initiate the join procedure to attempt + * to associate with the new BSS, base on given SSID, BSSID, and + * freqency. + * If the target connecting BSS is in the same ESS as current connected + * BSS, roaming will be performed. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_DATA + * \retval WLAN_STATUS_ADAPTER_NOT_READY + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetConnect(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + struct GLUE_INFO *prGlueInfo; + struct PARAM_CONNECT *pParamConn; + struct CONNECTION_SETTINGS *prConnSettings; + uint32_t i; + struct MSG_AIS_ABORT *prAisAbortMsg; + u_int8_t fgIsValidSsid = TRUE; + u_int8_t fgEqualSsid = FALSE; + u_int8_t fgEqualBssid = FALSE; + const uint8_t aucZeroMacAddr[] = NULL_MAC_ADDR; + uint8_t ucBssIndex = 0; + struct PARAM_BSSID_EX *prCurrBssid; + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + /* MSDN: + * Powering on the radio if the radio is powered off through a setting + * of OID_802_11_DISASSOCIATE + */ + if (prAdapter->fgIsRadioOff == TRUE) + prAdapter->fgIsRadioOff = FALSE; + + if (u4SetBufferLen != sizeof(struct PARAM_CONNECT)) + return WLAN_STATUS_INVALID_LENGTH; + else if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, WARN, + "Fail in set ssid! (Adapter not ready). ACPI=D%d, Radio=%d\n", + prAdapter->rAcpiState, prAdapter->fgIsRadioOff); + return WLAN_STATUS_ADAPTER_NOT_READY; + } + prAisAbortMsg = (struct MSG_AIS_ABORT *) cnmMemAlloc( + prAdapter, RAM_TYPE_MSG, sizeof(struct MSG_AIS_ABORT)); + if (!prAisAbortMsg) { + DBGLOG(REQ, ERROR, "Fail in allocating AisAbortMsg.\n"); + return WLAN_STATUS_FAILURE; + } + prAisAbortMsg->rMsgHdr.eMsgId = MID_OID_AIS_FSM_JOIN_REQ; + + pParamConn = (struct PARAM_CONNECT *) pvSetBuffer; + + ucBssIndex = pParamConn->ucBssIdx; + + prConnSettings = aisGetConnSettings(prAdapter, ucBssIndex); + prCurrBssid = aisGetCurrBssId(prAdapter, + ucBssIndex); + + if (pParamConn->u4SsidLen > 32) { + cnmMemFree(prAdapter, prAisAbortMsg); + DBGLOG(OID, WARN, "SsidLen [%d] is invalid!\n", + pParamConn->u4SsidLen); + return WLAN_STATUS_INVALID_LENGTH; + } else if (!pParamConn->pucBssid && !pParamConn->pucSsid) { + cnmMemFree(prAdapter, prAisAbortMsg); + DBGLOG(OID, WARN, "Bssid or ssid is invalid!\n"); + return WLAN_STATUS_INVALID_LENGTH; + } + + prGlueInfo = prAdapter->prGlueInfo; + kalMemZero(prConnSettings->aucSSID, + sizeof(prConnSettings->aucSSID)); + prConnSettings->ucSSIDLen = 0; + kalMemZero(prConnSettings->aucBSSID, + sizeof(prConnSettings->aucBSSID)); + kalMemZero(prConnSettings->aucBSSIDHint, + sizeof(prConnSettings->aucBSSIDHint)); + prConnSettings->eConnectionPolicy = CONNECT_BY_SSID_ANY; + prConnSettings->fgIsConnByBssidIssued = FALSE; + + if (pParamConn->pucSsid) { + prConnSettings->eConnectionPolicy = + CONNECT_BY_SSID_BEST_RSSI; + COPY_SSID(prConnSettings->aucSSID, + prConnSettings->ucSSIDLen, pParamConn->pucSsid, + (uint8_t) pParamConn->u4SsidLen); + if (EQUAL_SSID(prCurrBssid->rSsid.aucSsid, + prCurrBssid->rSsid.u4SsidLen, + pParamConn->pucSsid, pParamConn->u4SsidLen)) + fgEqualSsid = TRUE; + } + if (pParamConn->pucBssid) { + if (!EQUAL_MAC_ADDR(aucZeroMacAddr, pParamConn->pucBssid) + && IS_UCAST_MAC_ADDR(pParamConn->pucBssid)) { + prConnSettings->eConnectionPolicy = CONNECT_BY_BSSID; + prConnSettings->fgIsConnByBssidIssued = TRUE; + COPY_MAC_ADDR(prConnSettings->aucBSSID, + pParamConn->pucBssid); + if (EQUAL_MAC_ADDR( + prCurrBssid->arMacAddress, + pParamConn->pucBssid)) + fgEqualBssid = TRUE; + } else + DBGLOG(INIT, INFO, "wrong bssid " MACSTR "to connect\n", + MAC2STR(pParamConn->pucBssid)); + } else if (pParamConn->pucBssidHint) { + if (!EQUAL_MAC_ADDR(aucZeroMacAddr, pParamConn->pucBssidHint) + && IS_UCAST_MAC_ADDR(pParamConn->pucBssidHint)) { + if (ucBssIndex < + prAdapter->rWifiVar.u4AisRoamingNumber) { + prConnSettings->eConnectionPolicy = + CONNECT_BY_BSSID_HINT; + COPY_MAC_ADDR(prConnSettings->aucBSSIDHint, + pParamConn->pucBssidHint); +#if CFG_TC3_FEATURE + if (EQUAL_MAC_ADDR( + prCurrBssid->arMacAddress, + pParamConn->pucBssidHint)) + fgEqualBssid = TRUE; +#endif + + } else { + prConnSettings->eConnectionPolicy = + CONNECT_BY_BSSID; + prConnSettings->fgIsConnByBssidIssued = TRUE; + COPY_MAC_ADDR(prConnSettings->aucBSSID, + pParamConn->pucBssidHint); + if (EQUAL_MAC_ADDR( + prCurrBssid->arMacAddress, + pParamConn->pucBssidHint)) + fgEqualBssid = TRUE; + DBGLOG(INIT, INFO, + "Force to use bssid (%d)", ucBssIndex); + } + } + } else + DBGLOG(INIT, INFO, "No Bssid set\n"); + prConnSettings->u4FreqInKHz = pParamConn->u4CenterFreq; + + /* prepare for CMD_BUILD_CONNECTION & CMD_GET_CONNECTION_STATUS */ + /* re-association check */ + if (kalGetMediaStateIndicated(prGlueInfo, + ucBssIndex) == + MEDIA_STATE_CONNECTED) { + if (fgEqualSsid) { + prAisAbortMsg->ucReasonOfDisconnect = + DISCONNECT_REASON_CODE_ROAMING; + if (fgEqualBssid) { + kalSetMediaStateIndicated(prGlueInfo, + MEDIA_STATE_TO_BE_INDICATED, + ucBssIndex); + prAisAbortMsg->ucReasonOfDisconnect = + DISCONNECT_REASON_CODE_REASSOCIATION; + } + } else { + DBGLOG(INIT, INFO, "DisBySsid\n"); + kalIndicateStatusAndComplete(prGlueInfo, + WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0, + ucBssIndex); + prAisAbortMsg->ucReasonOfDisconnect = + DISCONNECT_REASON_CODE_NEW_CONNECTION; + cnmMemFree(prAdapter, prAisAbortMsg); + /* reject this connect to avoid to install key fail */ + return WLAN_STATUS_FAILURE; + } + } else + prAisAbortMsg->ucReasonOfDisconnect = + DISCONNECT_REASON_CODE_NEW_CONNECTION; +#if 0 + /* check if any scanned result matchs with the SSID */ + for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { + uint8_t *aucSsid = + prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid; + uint8_t ucSsidLength = (uint8_t) + prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen; + int32_t i4RSSI = prAdapter->rWlanInfo.arScanResult[i].rRssi; + + if (EQUAL_SSID(aucSsid, ucSsidLength, pParamConn->pucSsid, + pParamConn->u4SsidLen) && + i4RSSI >= i4MaxRSSI) { + i4Idx = (int32_t) i; + i4MaxRSSI = i4RSSI; + } + if (EQUAL_MAC_ADDR( + prAdapter->rWlanInfo.arScanResult[i].arMacAddress, pAddr)) { + i4Idx = (int32_t) i; + break; + } + } +#endif + /* prepare message to AIS */ + if (prConnSettings->eOPMode == NET_TYPE_IBSS + || prConnSettings->eOPMode == NET_TYPE_DEDICATED_IBSS) { + /* IBSS *//* beacon period */ + prConnSettings->u2BeaconPeriod = + prAdapter->rWlanInfo.u2BeaconPeriod; + prConnSettings->u2AtimWindow = + prAdapter->rWlanInfo.u2AtimWindow; + } + + if (prAdapter->rWifiVar.fgSupportWZCDisassociation) { + if (pParamConn->u4SsidLen == ELEM_MAX_LEN_SSID) { + fgIsValidSsid = FALSE; + + if (pParamConn->pucSsid) { + for (i = 0; i < ELEM_MAX_LEN_SSID; i++) { + if (!((pParamConn->pucSsid[i] > 0) && + (pParamConn->pucSsid[i] <= 0x1F))) { + fgIsValidSsid = TRUE; + break; + } + } + } else { + DBGLOG(INIT, ERROR, + "pParamConn->pucSsid is NULL\n"); + } + } + } + + /* Check former assocIE to prevent memory leakage in situations like + * upper layer requests connection without disconnecting first, ... + */ + if (prConnSettings->assocIeLen > 0) { + kalMemFree(prConnSettings->pucAssocIEs, VIR_MEM_TYPE, + prConnSettings->assocIeLen); + prConnSettings->assocIeLen = 0; + } + + if (pParamConn->u4IesLen > 0) { + prConnSettings->assocIeLen = pParamConn->u4IesLen; + prConnSettings->pucAssocIEs = + kalMemAlloc(prConnSettings->assocIeLen, VIR_MEM_TYPE); + if (prConnSettings->pucAssocIEs) { + kalMemCopy(prConnSettings->pucAssocIEs, + pParamConn->pucIEs, prConnSettings->assocIeLen); + } else { + DBGLOG(INIT, INFO, + "allocate memory for prConnSettings->pucAssocIEs failed!\n"); + prConnSettings->assocIeLen = 0; + } + } + + if (fgEqualSsid || fgEqualBssid) + prAisAbortMsg->fgDelayIndication = TRUE; + else + /* Update the information to CONNECTION_SETTINGS_T */ + prAisAbortMsg->fgDelayIndication = FALSE; + prAisAbortMsg->ucBssIndex = ucBssIndex; + mboxSendMsg(prAdapter, MBOX_ID_0, + (struct MSG_HDR *) prAisAbortMsg, MSG_SEND_METHOD_BUF); + + DBGLOG(INIT, INFO, + "ucBssIndex %d, ssid %s, bssid " MACSTR + ", bssid_hint " MACSTR ", conn policy %d, disc reason %d\n", + ucBssIndex, + HIDE(prConnSettings->aucSSID), + MAC2STR(prConnSettings->aucBSSID), + MAC2STR(prConnSettings->aucBSSIDHint), + prConnSettings->eConnectionPolicy, + prAisAbortMsg->ucReasonOfDisconnect); + return WLAN_STATUS_SUCCESS; +} /* end of wlanoidSetConnect */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to query the currently associated SSID. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvQueryBuffer Pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufferLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the call + * failed due to invalid length of the query buffer, + * returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQuerySsid(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) +{ + struct PARAM_SSID *prAssociatedSsid; + struct PARAM_BSSID_EX *prCurrBssid; + uint8_t ucBssIndex = 0; + + DEBUGFUNC("wlanoidQuerySsid"); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + ucBssIndex = GET_IOCTL_BSSIDX(prAdapter); + + *pu4QueryInfoLen = sizeof(struct PARAM_SSID); + + /* Check for query buffer length */ + if (u4QueryBufferLen < *pu4QueryInfoLen) { + DBGLOG(REQ, WARN, "Invalid length %u\n", u4QueryBufferLen); + return WLAN_STATUS_INVALID_LENGTH; + } + + prAssociatedSsid = (struct PARAM_SSID *) pvQueryBuffer; + + kalMemZero(prAssociatedSsid->aucSsid, + sizeof(prAssociatedSsid->aucSsid)); + + prCurrBssid = aisGetCurrBssId(prAdapter, + ucBssIndex); + + if (kalGetMediaStateIndicated(prAdapter->prGlueInfo, + ucBssIndex) == + MEDIA_STATE_CONNECTED) { + prAssociatedSsid->u4SsidLen = + prCurrBssid->rSsid.u4SsidLen; + + if (prAssociatedSsid->u4SsidLen) { + kalMemCopy(prAssociatedSsid->aucSsid, + prCurrBssid->rSsid.aucSsid, + prAssociatedSsid->u4SsidLen); + } + } else { + prAssociatedSsid->u4SsidLen = 0; + + DBGLOG(REQ, TRACE, "Null SSID\n"); + } + + return WLAN_STATUS_SUCCESS; +} /* wlanoidQuerySsid */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to query the current 802.11 network type. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvQueryBuffer Pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufferLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the call + * failed due to invalid length of the query buffer, + * returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_BUFFER_TOO_SHORT + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryInfrastructureMode(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) +{ + struct CONNECTION_SETTINGS *prConnSettings; + uint8_t ucBssIndex = AIS_DEFAULT_INDEX; + + DEBUGFUNC("wlanoidQueryInfrastructureMode"); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + + prConnSettings = + aisGetConnSettings(prAdapter, ucBssIndex); + + *pu4QueryInfoLen = sizeof(enum ENUM_PARAM_OP_MODE); + + if (u4QueryBufferLen < sizeof(enum ENUM_PARAM_OP_MODE)) + return WLAN_STATUS_BUFFER_TOO_SHORT; + + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + *(enum ENUM_PARAM_OP_MODE *) pvQueryBuffer = + prConnSettings->eOPMode; + + /* + ** According to OID_802_11_INFRASTRUCTURE_MODE + ** If there is no prior OID_802_11_INFRASTRUCTURE_MODE, + ** NDIS_STATUS_ADAPTER_NOT_READY shall be returned. + */ +#if DBG + switch (*(enum ENUM_PARAM_OP_MODE *) pvQueryBuffer) { + case NET_TYPE_IBSS: + DBGLOG(REQ, INFO, "IBSS mode\n"); + break; + case NET_TYPE_INFRA: + DBGLOG(REQ, INFO, "Infrastructure mode\n"); + break; + default: + DBGLOG(REQ, INFO, "Automatic mode\n"); + } +#endif + + return WLAN_STATUS_SUCCESS; +} /* wlanoidQueryInfrastructureMode */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set mode to infrastructure or + * IBSS, or automatic switch between the two. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed due to invalid + * length of the set buffer, returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_DATA + * \retval WLAN_STATUS_ADAPTER_NOT_READY + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetInfrastructureMode(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + struct GLUE_INFO *prGlueInfo; + struct PARAM_OP_MODE *pOpMode; + enum ENUM_PARAM_OP_MODE eOpMode; + /* P_WLAN_TABLE_T prWlanTable; */ +#if CFG_SUPPORT_802_11W + struct AIS_SPECIFIC_BSS_INFO *prAisSpecBssInfo; +#endif + /* UINT_8 i; */ + struct CONNECTION_SETTINGS *prConnSettings; + struct BSS_INFO *prAisBssInfo; + uint8_t ucBssIndex = 0; + + DEBUGFUNC("wlanoidSetInfrastructureMode"); + + ASSERT(prAdapter); + ASSERT(pvSetBuffer); + ASSERT(pu4SetInfoLen); + + prGlueInfo = prAdapter->prGlueInfo; + + if (u4SetBufferLen < sizeof(struct PARAM_OP_MODE)) + return WLAN_STATUS_BUFFER_TOO_SHORT; + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, WARN, + "Fail in set infrastructure mode! (Adapter not ready). ACPI=D%d, Radio=%d\n", + prAdapter->rAcpiState, prAdapter->fgIsRadioOff); + return WLAN_STATUS_ADAPTER_NOT_READY; + } + + pOpMode = (struct PARAM_OP_MODE *) pvSetBuffer; + + ucBssIndex = pOpMode->ucBssIdx; + prAisSpecBssInfo = + aisGetAisSpecBssInfo(prAdapter, ucBssIndex); + prConnSettings = + aisGetConnSettings(prAdapter, ucBssIndex); + prAisBssInfo = + aisGetAisBssInfo(prAdapter, ucBssIndex); + + eOpMode = pOpMode->eOpMode; + /* Verify the new infrastructure mode. */ + if (eOpMode >= NET_TYPE_NUM) { + DBGLOG(REQ, TRACE, "Invalid mode value %d\n", eOpMode); + return WLAN_STATUS_INVALID_DATA; + } + + /* check if possible to switch to AdHoc mode */ + if (eOpMode == NET_TYPE_IBSS + || eOpMode == NET_TYPE_DEDICATED_IBSS) { + if (cnmAisIbssIsPermitted(prAdapter) == FALSE) { + DBGLOG(REQ, TRACE, "Mode value %d unallowed\n", + eOpMode); + return WLAN_STATUS_FAILURE; + } + } + + /* Save the new infrastructure mode setting. */ + prConnSettings->eOPMode = eOpMode; + + prConnSettings->fgWapiMode = FALSE; + +#if CFG_SUPPORT_802_11W + prAisSpecBssInfo->fgMgmtProtection = + FALSE; + prAisSpecBssInfo->fgBipKeyInstalled = + FALSE; +#endif + +#if 0 /* STA record remove at AIS_ABORT nicUpdateBss and DISCONNECT */ + for (i = 0; i < prAdapter->ucHwBssIdNum; i++) { + prBssInfo = prAdapter->aprBssInfo[i]; + if (prBssInfo->eNetworkType == NETWORK_TYPE_AIS) + cnmStaFreeAllStaByNetwork(prAdapter, + prBssInfo->ucBssIndex, 0); + } +#endif + + /* Clean up the Tx key flag */ + if (prAisBssInfo != NULL) { + prAisBssInfo->fgBcDefaultKeyExist = FALSE; + prAisBssInfo->ucBcDefaultKeyIdx = 0xFF; + } + + /* prWlanTable = prAdapter->rWifiVar.arWtbl; */ + /* prWlanTable[prAisBssInfo->ucBMCWlanIndex].ucKeyId = 0; */ + + DBGLOG(RSN, LOUD, "ucBssIndex %d\n", ucBssIndex); + + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_INFRASTRUCTURE, + TRUE, + FALSE, + TRUE, + nicCmdEventSetCommon, nicOidCmdTimeoutCommon, + 0, NULL, pvSetBuffer, u4SetBufferLen); +} /* wlanoidSetInfrastructureMode */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to query the current 802.11 authentication + * mode. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[out] pvQueryBuffer A pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufferLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the call + * failed due to invalid length of the query buffer, + * returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_BUFFER_TOO_SHORT + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryAuthMode(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) +{ + uint8_t ucBssIndex = AIS_DEFAULT_INDEX; + + DEBUGFUNC("wlanoidQueryAuthMode"); + + ASSERT(prAdapter); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + ASSERT(pu4QueryInfoLen); + + *pu4QueryInfoLen = sizeof(enum ENUM_PARAM_AUTH_MODE); + + if (u4QueryBufferLen < sizeof(enum ENUM_PARAM_AUTH_MODE)) + return WLAN_STATUS_BUFFER_TOO_SHORT; + + *(enum ENUM_PARAM_AUTH_MODE *) pvQueryBuffer = + aisGetAuthMode(prAdapter, ucBssIndex); + +#if DBG + switch (*(enum ENUM_PARAM_AUTH_MODE *) pvQueryBuffer) { + case AUTH_MODE_OPEN: + DBGLOG(REQ, INFO, "Current auth mode: Open\n"); + break; + + case AUTH_MODE_SHARED: + DBGLOG(REQ, INFO, "Current auth mode: Shared\n"); + break; + + case AUTH_MODE_AUTO_SWITCH: + DBGLOG(REQ, INFO, "Current auth mode: Auto-switch\n"); + break; + + case AUTH_MODE_WPA: + DBGLOG(REQ, INFO, "Current auth mode: WPA\n"); + break; + + case AUTH_MODE_WPA_PSK: + DBGLOG(REQ, INFO, "Current auth mode: WPA PSK\n"); + break; + + case AUTH_MODE_WPA_NONE: + DBGLOG(REQ, INFO, "Current auth mode: WPA None\n"); + break; + + case AUTH_MODE_WPA2: + DBGLOG(REQ, INFO, "Current auth mode: WPA2\n"); + break; + + case AUTH_MODE_WPA2_PSK: + DBGLOG(REQ, INFO, "Current auth mode: WPA2 PSK\n"); + break; + + default: + DBGLOG(REQ, INFO, "Current auth mode: %d\n", + *(enum ENUM_PARAM_AUTH_MODE *) pvQueryBuffer); + break; + } +#endif + return WLAN_STATUS_SUCCESS; +} /* wlanoidQueryAuthMode */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set the IEEE 802.11 authentication mode + * to the driver. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_DATA + * \retval WLAN_STATUS_INVALID_LENGTH + * \retval WLAN_STATUS_ADAPTER_NOT_READY + * \retval WLAN_STATUS_NOT_ACCEPTED + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetAuthMode(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + struct GLUE_INFO *prGlueInfo; + /* UINT_32 i, u4AkmSuite; */ + /* P_DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY prEntry; */ + struct CONNECTION_SETTINGS *prConnSettings; + uint8_t ucBssIndex = 0; + + DEBUGFUNC("wlanoidSetAuthMode"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + ASSERT(pvSetBuffer); + + prGlueInfo = prAdapter->prGlueInfo; + + ucBssIndex = GET_IOCTL_BSSIDX(prAdapter); + + DBGLOG(REQ, LOUD, "ucBssIndex %d\n", ucBssIndex); + + prConnSettings = + aisGetConnSettings(prAdapter, ucBssIndex); + + *pu4SetInfoLen = sizeof(enum ENUM_PARAM_AUTH_MODE); + + if (u4SetBufferLen < sizeof(enum ENUM_PARAM_AUTH_MODE)) + return WLAN_STATUS_INVALID_LENGTH; + + /* RF Test */ + /* if (IS_ARB_IN_RFTEST_STATE(prAdapter)) { */ + /* return WLAN_STATUS_SUCCESS; */ + /* } */ + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, WARN, + "Fail in set Authentication mode! (Adapter not ready). ACPI=D%d, Radio=%d\n", + prAdapter->rAcpiState, prAdapter->fgIsRadioOff); + return WLAN_STATUS_ADAPTER_NOT_READY; + } + + /* Check if the new authentication mode is valid. */ + if (*(enum ENUM_PARAM_AUTH_MODE *) pvSetBuffer >= + AUTH_MODE_NUM) { + DBGLOG(REQ, TRACE, "Invalid auth mode %d\n", + *(enum ENUM_PARAM_AUTH_MODE *) pvSetBuffer); + return WLAN_STATUS_INVALID_DATA; + } + + switch (*(enum ENUM_PARAM_AUTH_MODE *) pvSetBuffer) { + case AUTH_MODE_WPA_OSEN: + case AUTH_MODE_WPA: + case AUTH_MODE_WPA_PSK: + case AUTH_MODE_WPA2: + case AUTH_MODE_WPA2_PSK: + case AUTH_MODE_WPA2_FT: + case AUTH_MODE_WPA2_FT_PSK: + case AUTH_MODE_WPA3_SAE: + case AUTH_MODE_WPA3_OWE: + /* infrastructure mode only */ + if (prConnSettings->eOPMode != + NET_TYPE_INFRA) + return WLAN_STATUS_NOT_ACCEPTED; + break; + + case AUTH_MODE_WPA_NONE: + /* ad hoc mode only */ + if (prConnSettings->eOPMode != + NET_TYPE_IBSS) + return WLAN_STATUS_NOT_ACCEPTED; + break; + + default: + break; + } + + /* Save the new authentication mode. */ + prConnSettings->eAuthMode = * + (enum ENUM_PARAM_AUTH_MODE *) pvSetBuffer; + +#if 1 /* DBG */ + switch (prConnSettings->eAuthMode) { + case AUTH_MODE_OPEN: + DBGLOG(RSN, TRACE, "New auth mode: open\n"); + break; + + case AUTH_MODE_SHARED: + DBGLOG(RSN, TRACE, "New auth mode: shared\n"); + break; + + case AUTH_MODE_AUTO_SWITCH: + DBGLOG(RSN, TRACE, "New auth mode: auto-switch\n"); + break; + + case AUTH_MODE_WPA: + DBGLOG(RSN, TRACE, "New auth mode: WPA\n"); + break; + + case AUTH_MODE_WPA_PSK: + DBGLOG(RSN, TRACE, "New auth mode: WPA PSK\n"); + break; + + case AUTH_MODE_WPA_NONE: + DBGLOG(RSN, TRACE, "New auth mode: WPA None\n"); + break; + + case AUTH_MODE_WPA2: + DBGLOG(RSN, TRACE, "New auth mode: WPA2\n"); + break; + + case AUTH_MODE_WPA2_PSK: + DBGLOG(RSN, TRACE, "New auth mode: WPA2 PSK\n"); + break; + + case AUTH_MODE_WPA3_SAE: + DBGLOG(RSN, INFO, "New auth mode: SAE\n"); + break; + + default: + DBGLOG(RSN, TRACE, "New auth mode: unknown (%d)\n", + prConnSettings->eAuthMode); + } +#endif + +#if 0 + if (prConnSettings->eAuthMode >= + AUTH_MODE_WPA) { + switch (prConnSettings->eAuthMode) { + case AUTH_MODE_WPA: + u4AkmSuite = WPA_AKM_SUITE_802_1X; + break; + + case AUTH_MODE_WPA_PSK: + u4AkmSuite = WPA_AKM_SUITE_PSK; + break; + + case AUTH_MODE_WPA_NONE: + u4AkmSuite = WPA_AKM_SUITE_NONE; + break; + + case AUTH_MODE_WPA2: + u4AkmSuite = RSN_AKM_SUITE_802_1X; + break; + + case AUTH_MODE_WPA2_PSK: + u4AkmSuite = RSN_AKM_SUITE_PSK; + break; + + default: + u4AkmSuite = 0; + } + } else { + u4AkmSuite = 0; + } + + /* Enable the specific AKM suite only. */ + for (i = 0; i < MAX_NUM_SUPPORTED_AKM_SUITES; i++) { + prEntry = &prAdapter->rMib + .dot11RSNAConfigAuthenticationSuitesTable[i]; + + if (prEntry->dot11RSNAConfigAuthenticationSuite == + u4AkmSuite) + prEntry->dot11RSNAConfigAuthenticationSuiteEnabled = + TRUE; + else + prEntry->dot11RSNAConfigAuthenticationSuiteEnabled = + FALSE; +#if CFG_SUPPORT_802_11W + if (kalGetMfpSetting(prAdapter->prGlueInfo) != + RSN_AUTH_MFP_DISABLED) { + if ((u4AkmSuite == RSN_AKM_SUITE_PSK) && + prEntry->dot11RSNAConfigAuthenticationSuite == + RSN_AKM_SUITE_PSK_SHA256) { + DBGLOG(RSN, TRACE, + "Enable RSN_AKM_SUITE_PSK_SHA256 AKM support\n"); + prEntry-> + dot11RSNAConfigAuthenticationSuiteEnabled = + TRUE; + + } + if ((u4AkmSuite == RSN_AKM_SUITE_802_1X) && + prEntry->dot11RSNAConfigAuthenticationSuite == + RSN_AKM_SUITE_802_1X_SHA256) { + DBGLOG(RSN, TRACE, + "Enable RSN_AKM_SUITE_802_1X_SHA256 AKM support\n"); + prEntry-> + dot11RSNAConfigAuthenticationSuiteEnabled = + TRUE; + } + } +#endif + } +#endif + + return WLAN_STATUS_SUCCESS; + +} /* wlanoidSetAuthMode */ + +uint32_t +wlanoidSetAuthorized(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + + struct BSS_INFO *prAisBssInfo; + struct AIS_FSM_INFO *prAisFsmInfo = (struct AIS_FSM_INFO *) NULL; + uint8_t ucBssIndex = 0; + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + ASSERT(pvSetBuffer); + + if (u4SetBufferLen < MAC_ADDR_LEN) + return WLAN_STATUS_INVALID_LENGTH; + + ucBssIndex = GET_IOCTL_BSSIDX(prAdapter); + DBGLOG(REQ, LOUD, "ucBssIndex %d\n", ucBssIndex); + + prAisBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + if (prAisBssInfo == NULL) + return WLAN_STATUS_FAILURE; + + if (IS_BSS_AIS(prAisBssInfo) && + prAisBssInfo->prStaRecOfAP && EQUAL_MAC_ADDR( + prAisBssInfo->prStaRecOfAP->aucMacAddr, pvSetBuffer)) { + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + + if (!timerPendingTimer(&prAisFsmInfo->rJoinTimeoutTimer)) { + DBGLOG(QM, ERROR, "No channel occupation\n"); + } else { + DBGLOG(QM, INFO, "Authorized, stop join timer.\n"); + cnmTimerStopTimer(prAdapter, + &prAisFsmInfo->rJoinTimeoutTimer); + aisFsmRunEventJoinTimeout(prAdapter, ucBssIndex); + } + } else { + return WLAN_STATUS_NOT_SUPPORTED; + } + + return WLAN_STATUS_SUCCESS; +} + +#if 0 +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to query the current 802.11 privacy filter + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[out] pvQueryBuffer A pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufferLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the call + * failed due to invalid length of the query buffer, + * returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_BUFFER_TOO_SHORT + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryPrivacyFilter(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) +{ + DEBUGFUNC("wlanoidQueryPrivacyFilter"); + + ASSERT(prAdapter); + + ASSERT(pvQueryBuffer); + ASSERT(pu4QueryInfoLen); + + *pu4QueryInfoLen = sizeof(enum ENUM_PARAM_PRIVACY_FILTER); + + if (u4QueryBufferLen < sizeof(enum + ENUM_PARAM_PRIVACY_FILTER)) + return WLAN_STATUS_BUFFER_TOO_SHORT; + + *(enum ENUM_PARAM_PRIVACY_FILTER *) pvQueryBuffer = + prAdapter->rWlanInfo.ePrivacyFilter; + +#if DBG + switch (*(enum ENUM_PARAM_PRIVACY_FILTER *) pvQueryBuffer) { + case PRIVACY_FILTER_ACCEPT_ALL: + DBGLOG(REQ, INFO, "Current privacy mode: open mode\n"); + break; + + case PRIVACY_FILTER_8021xWEP: + DBGLOG(REQ, INFO, "Current privacy mode: filtering mode\n"); + break; + + default: + DBGLOG(REQ, INFO, "Current auth mode: %d\n", + *(enum ENUM_PARAM_AUTH_MODE *) pvQueryBuffer); + } +#endif + return WLAN_STATUS_SUCCESS; +} /* wlanoidQueryPrivacyFilter */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set the IEEE 802.11 privacy filter + * to the driver. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_DATA + * \retval WLAN_STATUS_INVALID_LENGTH + * \retval WLAN_STATUS_ADAPTER_NOT_READY + * \retval WLAN_STATUS_NOT_ACCEPTED + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetPrivacyFilter(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + struct GLUE_INFO *prGlueInfo; + + DEBUGFUNC("wlanoidSetPrivacyFilter"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + ASSERT(pvSetBuffer); + + prGlueInfo = prAdapter->prGlueInfo; + + *pu4SetInfoLen = sizeof(enum ENUM_PARAM_PRIVACY_FILTER); + + if (u4SetBufferLen < sizeof(enum ENUM_PARAM_PRIVACY_FILTER)) + return WLAN_STATUS_INVALID_LENGTH; + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, WARN, + "Fail in set Authentication mode! (Adapter not ready). ACPI=D%d, Radio=%d\n", + prAdapter->rAcpiState, prAdapter->fgIsRadioOff); + return WLAN_STATUS_ADAPTER_NOT_READY; + } + + /* Check if the new authentication mode is valid. */ + if (*(enum ENUM_PARAM_PRIVACY_FILTER *) pvSetBuffer >= + PRIVACY_FILTER_NUM) { + DBGLOG(REQ, TRACE, "Invalid privacy filter %d\n", + *(enum ENUM_PARAM_PRIVACY_FILTER *) pvSetBuffer); + return WLAN_STATUS_INVALID_DATA; + } + + switch (*(enum ENUM_PARAM_PRIVACY_FILTER *) pvSetBuffer) { + default: + break; + } + + /* Save the new authentication mode. */ + prAdapter->rWlanInfo.ePrivacyFilter = + *(enum ENUM_PARAM_PRIVACY_FILTER) pvSetBuffer; + + return WLAN_STATUS_SUCCESS; + +} /* wlanoidSetPrivacyFilter */ +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to reload the available default settings for + * the specified type field. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_ADAPTER_NOT_READY + * \retval WLAN_STATUS_INVALID_DATA + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetReloadDefaults(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + uint32_t rStatus = WLAN_STATUS_SUCCESS; + enum ENUM_PARAM_NETWORK_TYPE eNetworkType; + uint32_t u4Len; + struct mt66xx_chip_info *prChipInfo; + uint16_t cmd_size; + struct CONNECTION_SETTINGS *prConnSettings; + uint8_t ucBssIndex = AIS_DEFAULT_INDEX; + + DEBUGFUNC("wlanoidSetReloadDefaults"); + + ASSERT(prAdapter); + prChipInfo = prAdapter->chip_info; + + ASSERT(pu4SetInfoLen); + + prConnSettings = + aisGetConnSettings(prAdapter, ucBssIndex); + + *pu4SetInfoLen = sizeof(enum ENUM_RELOAD_DEFAULTS); + + /* if (IS_ARB_IN_RFTEST_STATE(prAdapter)) { */ + /* return WLAN_STATUS_SUCCESS; */ + /* } */ + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, WARN, + "Fail in set Reload default! (Adapter not ready). ACPI=D%d, Radio=%d\n", + prAdapter->rAcpiState, prAdapter->fgIsRadioOff); + return WLAN_STATUS_ADAPTER_NOT_READY; + } + + ASSERT(pvSetBuffer); + /* Verify the available reload options and reload the settings. */ + switch (*(enum ENUM_RELOAD_DEFAULTS *) pvSetBuffer) { + case ENUM_RELOAD_WEP_KEYS: + /* Reload available default WEP keys from the permanent + * storage. + */ + prConnSettings->eAuthMode = + AUTH_MODE_OPEN; + /* ENUM_ENCRYPTION_DISABLED; */ + prConnSettings->eEncStatus = + ENUM_ENCRYPTION1_KEY_ABSENT; + { + struct GLUE_INFO *prGlueInfo; + struct CMD_INFO *prCmdInfo; + struct CMD_802_11_KEY *prCmdKey; + uint8_t aucBCAddr[] = BC_MAC_ADDR; + + prGlueInfo = prAdapter->prGlueInfo; + cmd_size = prChipInfo->u2CmdTxHdrSize + + sizeof(struct CMD_802_11_KEY); + prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, cmd_size); + if (!prCmdInfo) { + DBGLOG(INIT, ERROR, + "Allocate CMD_INFO_T ==> FAILED.\n"); + return WLAN_STATUS_FAILURE; + } + + /* compose CMD_802_11_KEY cmd pkt */ + prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; + prCmdInfo->u2InfoBufLen = cmd_size; + prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; + prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; + prCmdInfo->fgIsOid = TRUE; + prCmdInfo->ucCID = CMD_ID_ADD_REMOVE_KEY; + prCmdInfo->fgSetQuery = TRUE; + prCmdInfo->fgNeedResp = FALSE; + prCmdInfo->u4SetInfoLen = + sizeof(struct PARAM_REMOVE_KEY); + prCmdInfo->pvInformationBuffer = pvSetBuffer; + prCmdInfo->u4InformationBufferLength = u4SetBufferLen; + + /* Setup WIFI_CMD_T */ + NIC_FILL_CMD_TX_HDR(prAdapter, + prCmdInfo->pucInfoBuffer, + prCmdInfo->u2InfoBufLen, + prCmdInfo->ucCID, + CMD_PACKET_TYPE_ID, + &prCmdInfo->ucCmdSeqNum, + prCmdInfo->fgSetQuery, + &prCmdKey, FALSE, 0, S2D_INDEX_CMD_H2N); + + kalMemZero((uint8_t *) prCmdKey, + sizeof(struct CMD_802_11_KEY)); + + prCmdKey->ucAddRemove = 0; /* Remove */ + prCmdKey->ucKeyId = + 0; /* (UINT_8)(prRemovedKey->u4KeyIndex & + * 0x000000ff); + */ + kalMemCopy(prCmdKey->aucPeerAddr, aucBCAddr, + MAC_ADDR_LEN); + + ASSERT(prCmdKey->ucKeyId < MAX_KEY_NUM); + + prCmdKey->ucKeyType = 0; + + /* insert into prCmdQueue */ + kalEnqueueCommand(prGlueInfo, + (struct QUE_ENTRY *) prCmdInfo); + + /* wakeup txServiceThread later */ + GLUE_SET_EVENT(prGlueInfo); + + return WLAN_STATUS_PENDING; + } + + break; + + default: + DBGLOG(REQ, TRACE, "Invalid reload option %d\n", + *(enum ENUM_RELOAD_DEFAULTS *) pvSetBuffer); + rStatus = WLAN_STATUS_INVALID_DATA; + } + + /* OID_802_11_RELOAD_DEFAULTS requiest to reset to auto mode */ + eNetworkType = PARAM_NETWORK_TYPE_AUTOMODE; + wlanoidSetNetworkTypeInUse(prAdapter, &eNetworkType, + sizeof(eNetworkType), &u4Len); + + return rStatus; +} /* wlanoidSetReloadDefaults */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set a WEP key to the driver. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be + * set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + * \retval WLAN_STATUS_INVALID_DATA + * \retval WLAN_STATUS_ADAPTER_NOT_READY + * \retval WLAN_STATUS_BUFFER_TOO_SHORT + */ +/*----------------------------------------------------------------------------*/ +#ifdef LINUX +uint8_t keyBuffer[sizeof(struct PARAM_KEY) + + 16 /* LEGACY_KEY_MAX_LEN */]; +uint8_t aucBCAddr[] = BC_MAC_ADDR; +#endif +uint32_t +wlanoidSetAddWep(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ +#ifndef LINUX + uint8_t keyBuffer[sizeof(struct PARAM_KEY) + + 16 /* LEGACY_KEY_MAX_LEN */]; + uint8_t aucBCAddr[] = BC_MAC_ADDR; +#endif + struct PARAM_WEP *prNewWepKey; + struct PARAM_KEY *prParamKey = (struct PARAM_KEY *) + keyBuffer; + uint32_t u4KeyId, u4SetLen; + uint8_t ucBssIndex = 0; + + DEBUGFUNC("wlanoidSetAddWep"); + + ASSERT(prAdapter); + + ucBssIndex = GET_IOCTL_BSSIDX(prAdapter); + + DBGLOG(REQ, LOUD, "ucBssIndex %d\n", ucBssIndex); + + *pu4SetInfoLen = OFFSET_OF(struct PARAM_WEP, + aucKeyMaterial); + + if (u4SetBufferLen < OFFSET_OF(struct PARAM_WEP, + aucKeyMaterial)) { + ASSERT(pu4SetInfoLen); + return WLAN_STATUS_BUFFER_TOO_SHORT; + } + + ASSERT(pvSetBuffer); + ASSERT(pu4SetInfoLen); + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, WARN, + "Fail in set add WEP! (Adapter not ready). ACPI=D%d, Radio=%d\n", + prAdapter->rAcpiState, prAdapter->fgIsRadioOff); + return WLAN_STATUS_ADAPTER_NOT_READY; + } + + prNewWepKey = (struct PARAM_WEP *) pvSetBuffer; + + /* Verify the total buffer for minimum length. */ + if (u4SetBufferLen < OFFSET_OF(struct PARAM_WEP, + aucKeyMaterial) + prNewWepKey->u4KeyLength) { + DBGLOG(REQ, WARN, + "Invalid total buffer length (%d) than minimum length (%d)\n", + (uint8_t) u4SetBufferLen, + (uint8_t) OFFSET_OF(struct PARAM_WEP, aucKeyMaterial)); + + *pu4SetInfoLen = OFFSET_OF(struct PARAM_WEP, + aucKeyMaterial); + return WLAN_STATUS_INVALID_DATA; + } + + /* Verify the key structure length. */ + if (prNewWepKey->u4Length > u4SetBufferLen) { + DBGLOG(REQ, WARN, + "Invalid key structure length (%d) greater than total buffer length (%d)\n", + (uint8_t) prNewWepKey->u4Length, + (uint8_t) u4SetBufferLen); + + *pu4SetInfoLen = u4SetBufferLen; + return WLAN_STATUS_INVALID_DATA; + } + + /* Verify the key material length for maximum key material length:16 */ + if (prNewWepKey->u4KeyLength > + 16 /* LEGACY_KEY_MAX_LEN */) { + DBGLOG(REQ, WARN, + "Invalid key material length (%d) greater than maximum key material length (16)\n", + (uint8_t) prNewWepKey->u4KeyLength); + + *pu4SetInfoLen = u4SetBufferLen; + return WLAN_STATUS_INVALID_DATA; + } + + *pu4SetInfoLen = u4SetBufferLen; + + u4KeyId = prNewWepKey->u4KeyIndex & BITS(0, + 29) /* WEP_KEY_ID_FIELD */; + + /* Verify whether key index is valid or not, current version + * driver support only 4 global WEP keys setting by this OID + */ + if (u4KeyId > MAX_KEY_NUM - 1) { + DBGLOG(REQ, ERROR, "Error, invalid WEP key ID: %d\n", + (uint8_t) u4KeyId); + return WLAN_STATUS_INVALID_DATA; + } + + prParamKey->u4KeyIndex = u4KeyId; + + /* Transmit key */ + if (prNewWepKey->u4KeyIndex & IS_TRANSMIT_KEY) + prParamKey->u4KeyIndex |= IS_TRANSMIT_KEY; + + /* Per client key */ + if (prNewWepKey->u4KeyIndex & IS_UNICAST_KEY) + prParamKey->u4KeyIndex |= IS_UNICAST_KEY; + + prParamKey->u4KeyLength = prNewWepKey->u4KeyLength; + + kalMemCopy(prParamKey->arBSSID, aucBCAddr, MAC_ADDR_LEN); + + kalMemCopy(prParamKey->aucKeyMaterial, + prNewWepKey->aucKeyMaterial, prNewWepKey->u4KeyLength); + + prParamKey->ucBssIdx = ucBssIndex; + + if (prParamKey->u4KeyLength == WEP_40_LEN) + prParamKey->ucCipher = CIPHER_SUITE_WEP40; + else if (prParamKey->u4KeyLength == WEP_104_LEN) + prParamKey->ucCipher = CIPHER_SUITE_WEP104; + else if (prParamKey->u4KeyLength == WEP_128_LEN) + prParamKey->ucCipher = CIPHER_SUITE_WEP128; + + prParamKey->u4Length = OFFSET_OF( + struct PARAM_KEY, aucKeyMaterial) + prNewWepKey->u4KeyLength; + + wlanoidSetAddKey(prAdapter, (void *) prParamKey, + prParamKey->u4Length, &u4SetLen); + + return WLAN_STATUS_PENDING; +} /* wlanoidSetAddWep */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to request the driver to remove the WEP key + * at the specified key index. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_DATA + * \retval WLAN_STATUS_INVALID_LENGTH + * \retval WLAN_STATUS_ADAPTER_NOT_READY + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetRemoveWep(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + uint32_t u4KeyId, u4SetLen; + struct PARAM_REMOVE_KEY rRemoveKey; + uint8_t aucBCAddr[] = BC_MAC_ADDR; + uint8_t ucBssIndex = 0; + + DEBUGFUNC("wlanoidSetRemoveWep"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + ucBssIndex = GET_IOCTL_BSSIDX(prAdapter); + + DBGLOG(REQ, LOUD, "ucBssIndex %d\n", ucBssIndex); + + *pu4SetInfoLen = sizeof(uint32_t); + + if (u4SetBufferLen < sizeof(uint32_t)) + return WLAN_STATUS_INVALID_LENGTH; + + ASSERT(pvSetBuffer); + u4KeyId = *(uint32_t *) pvSetBuffer; + + /* Dump PARAM_WEP content. */ + DBGLOG(REQ, INFO, "Set: Dump PARAM_KEY_INDEX content\n"); + DBGLOG(REQ, INFO, "Index : %u\n", u4KeyId); + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, WARN, + "Fail in set remove WEP! (Adapter not ready). ACPI=D%d, Radio=%d\n", + prAdapter->rAcpiState, prAdapter->fgIsRadioOff); + return WLAN_STATUS_ADAPTER_NOT_READY; + } + + if (u4KeyId & IS_TRANSMIT_KEY) { + /* Bit 31 should not be set */ + DBGLOG(REQ, ERROR, "Invalid WEP key index: %u\n", u4KeyId); + return WLAN_STATUS_INVALID_DATA; + } + + u4KeyId &= BITS(0, 7); + + /* Verify whether key index is valid or not. Current version + * driver support only 4 global WEP keys. + */ + if (u4KeyId > MAX_KEY_NUM - 1) { + DBGLOG(REQ, ERROR, "invalid WEP key ID %u\n", u4KeyId); + return WLAN_STATUS_INVALID_DATA; + } + + rRemoveKey.u4Length = sizeof(struct PARAM_REMOVE_KEY); + rRemoveKey.u4KeyIndex = *(uint32_t *) pvSetBuffer; + rRemoveKey.ucBssIdx = ucBssIndex; + kalMemCopy(rRemoveKey.arBSSID, aucBCAddr, MAC_ADDR_LEN); + + wlanoidSetRemoveKey(prAdapter, (void *)&rRemoveKey, + sizeof(struct PARAM_REMOVE_KEY), &u4SetLen); + + return WLAN_STATUS_PENDING; +} /* wlanoidSetRemoveWep */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set a key to the driver. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_ADAPTER_NOT_READY + * \retval WLAN_STATUS_INVALID_LENGTH + * \retval WLAN_STATUS_INVALID_DATA + * + * \note The setting buffer PARAM_KEY_T, which is set by NDIS, is unpacked. + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetAddKey(IN struct ADAPTER *prAdapter, IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, OUT uint32_t *pu4SetInfoLen) +{ + struct GLUE_INFO *prGlueInfo; + struct CMD_INFO *prCmdInfo; + struct PARAM_KEY *prNewKey; + struct CMD_802_11_KEY *prCmdKey; + struct BSS_INFO *prBssInfo; + struct AIS_SPECIFIC_BSS_INFO *prAisSpecBssInfo; + struct STA_RECORD *prStaRec = NULL; + u_int8_t fgNoHandshakeSec = FALSE; + struct mt66xx_chip_info *prChipInfo; + uint16_t cmd_size; +#if CFG_SUPPORT_TDLS + struct STA_RECORD *prTmpStaRec; +#endif + + DBGLOG_LIMITED(RSN, TRACE, "wlanoidSetAddKey\n"); + DBGLOG(REQ, LOUD, "\n"); + ASSERT(prAdapter); + ASSERT(pvSetBuffer); + ASSERT(pu4SetInfoLen); + prChipInfo = prAdapter->chip_info; + + DBGLOG_LIMITED(RSN, TRACE, "wlanoidSetAddKey\n"); + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(RSN, WARN, + "Fail in set add key! (Adapter not ready). ACPI=D%d, Radio=%d\n", + prAdapter->rAcpiState, prAdapter->fgIsRadioOff); + return WLAN_STATUS_ADAPTER_NOT_READY; + } + prNewKey = (struct PARAM_KEY *) pvSetBuffer; + /* Verify the key structure length. */ + if (prNewKey->u4Length > u4SetBufferLen) { + DBGLOG_LIMITED(RSN, WARN, + "Invalid key structure length (%d) greater than total buffer length (%d)\n", + (uint8_t) prNewKey->u4Length, (uint8_t) u4SetBufferLen); + *pu4SetInfoLen = u4SetBufferLen; + return WLAN_STATUS_INVALID_LENGTH; + } + /* Verify the key material length for key material buffer */ + if (prNewKey->u4KeyLength > prNewKey->u4Length - + OFFSET_OF(struct PARAM_KEY, aucKeyMaterial)) { + DBGLOG_LIMITED(RSN, WARN, "Invalid key material length (%d)\n", + (uint8_t) prNewKey->u4KeyLength); + *pu4SetInfoLen = u4SetBufferLen; + return WLAN_STATUS_INVALID_DATA; + } + /* Exception check */ + if (prNewKey->u4KeyIndex & 0x0fffff00) + return WLAN_STATUS_INVALID_DATA; + /* Exception check, pairwise key must with transmit bit enabled */ + if ((prNewKey->u4KeyIndex & BITS(30, 31)) == IS_UNICAST_KEY) + return WLAN_STATUS_INVALID_DATA; + if (!(prNewKey->u4KeyLength == WEP_40_LEN || + prNewKey->u4KeyLength == WEP_104_LEN || + prNewKey->u4KeyLength == CCMP_KEY_LEN || + prNewKey->u4KeyLength == TKIP_KEY_LEN)) { + return WLAN_STATUS_INVALID_DATA; + } + /* Exception check, pairwise key must with transmit bit enabled */ + if ((prNewKey->u4KeyIndex & BITS(30, 31)) == BITS(30, 31)) { + if (/* ((prNewKey->u4KeyIndex & 0xff) != 0) || */ + ((prNewKey->arBSSID[0] == 0xff) && + (prNewKey->arBSSID[1] == 0xff) && + (prNewKey->arBSSID[2] == 0xff) && + (prNewKey->arBSSID[3] == 0xff) && + (prNewKey->arBSSID[4] == 0xff) && + (prNewKey->arBSSID[5] == 0xff))) { + return WLAN_STATUS_INVALID_DATA; + } + } + *pu4SetInfoLen = u4SetBufferLen; + + /* Dump PARAM_KEY content. */ + DBGLOG_LIMITED(RSN, TRACE, + "Set: Dump PARAM_KEY content, Len: 0x%08x, BSSID: " + MACSTR + ", KeyIdx: 0x%08x, KeyLen: 0x%08x, Cipher: %d, Material:\n", + prNewKey->u4Length, MAC2STR(prNewKey->arBSSID), + prNewKey->u4KeyIndex, prNewKey->u4KeyLength, + prNewKey->ucCipher); + DBGLOG_MEM8(RSN, TRACE, prNewKey->aucKeyMaterial, + prNewKey->u4KeyLength); + DBGLOG(RSN, TRACE, "Key RSC:\n"); + DBGLOG_MEM8(RSN, TRACE, &prNewKey->rKeyRSC, sizeof(uint64_t)); + + prGlueInfo = prAdapter->prGlueInfo; + prAisSpecBssInfo = + aisGetAisSpecBssInfo(prAdapter, prNewKey->ucBssIdx); + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prNewKey->ucBssIdx); + if (!prBssInfo) { + DBGLOG_LIMITED(REQ, INFO, "BSS Info not exist !!\n"); + return WLAN_STATUS_SUCCESS; + } + /* Tx Rx KeyType addr + * STA, GC: + * case1: 1 1 0 BC addr (no sta record of AP at this moment) WEP, + * notice: tx at default key setting WEP key now save to BSS_INFO + * case2: 0 1 0 BSSID (sta record of AP) RSN BC key + * case3: 1 1 1 AP addr (sta record of AP) RSN STA key + * + * GO: + * case1: 1 1 0 BSSID (no sta record) WEP -- Not support + * case2: 1 0 0 BSSID (no sta record) RSN BC key + * case3: 1 1 1 STA addr STA key + */ + if (prNewKey->ucCipher == CIPHER_SUITE_WEP40 || + prNewKey->ucCipher == CIPHER_SUITE_WEP104 || + prNewKey->ucCipher == CIPHER_SUITE_WEP128) { + /* check if the key no need handshake, then save to bss wep key + * for global usage + */ + fgNoHandshakeSec = TRUE; + } + if (fgNoHandshakeSec) { +#if DBG + if (IS_BSS_AIS(prBssInfo)) { + if (aisGetAuthMode(prAdapter, prNewKey->ucBssIdx) + >= AUTH_MODE_WPA && + aisGetAuthMode(prAdapter, prNewKey->ucBssIdx) != + AUTH_MODE_WPA_NONE) { + DBGLOG_LIMITED(RSN, WARN, + "Set wep at not open/shared setting\n"); + return WLAN_STATUS_SUCCESS; + } + } +#endif + } + if ((prNewKey->u4KeyIndex & IS_UNICAST_KEY) == IS_UNICAST_KEY) { + prStaRec = cnmGetStaRecByAddress(prAdapter, + prBssInfo->ucBssIndex, prNewKey->arBSSID); + if (!prStaRec) { /* Already disconnected ? */ + DBGLOG_LIMITED(REQ, INFO, + "[wlan] Not set the peer key while disconnect\n"); + return WLAN_STATUS_SUCCESS; + } +#if CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION + /* clear fragment cache when rekey */ + nicRxClearFrag(prAdapter, prStaRec); +#endif /* CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION */ + } + cmd_size = prChipInfo->u2CmdTxHdrSize + sizeof(struct CMD_802_11_KEY); + prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, cmd_size); + if (!prCmdInfo) { + DBGLOG_LIMITED(INIT, ERROR, + "Allocate CMD_INFO_T ==> FAILED.\n"); + return WLAN_STATUS_FAILURE; + } + + /* compose CMD_802_11_KEY cmd pkt */ + prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; + prCmdInfo->u2InfoBufLen = cmd_size; +#if CFG_SUPPORT_REPLAY_DETECTION + prCmdInfo->pfCmdDoneHandler = nicCmdEventSetAddKey; + prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutSetAddKey; +#else + prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; + prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; +#endif + prCmdInfo->fgIsOid = TRUE; + prCmdInfo->ucCID = CMD_ID_ADD_REMOVE_KEY; + prCmdInfo->fgSetQuery = TRUE; + prCmdInfo->fgNeedResp = FALSE; + prCmdInfo->u4SetInfoLen = u4SetBufferLen; + prCmdInfo->pvInformationBuffer = pvSetBuffer; + prCmdInfo->u4InformationBufferLength = u4SetBufferLen; + /* Setup WIFI_CMD_T */ + NIC_FILL_CMD_TX_HDR(prAdapter, + prCmdInfo->pucInfoBuffer, + prCmdInfo->u2InfoBufLen, + prCmdInfo->ucCID, + CMD_PACKET_TYPE_ID, + &prCmdInfo->ucCmdSeqNum, + prCmdInfo->fgSetQuery, &prCmdKey, FALSE, 0, S2D_INDEX_CMD_H2N); + kalMemZero(prCmdKey, sizeof(struct CMD_802_11_KEY)); + prCmdKey->ucAddRemove = 1; /* Add */ + prCmdKey->ucTxKey = + ((prNewKey->u4KeyIndex & IS_TRANSMIT_KEY) == IS_TRANSMIT_KEY) + ? 1 : 0; + prCmdKey->ucKeyType = + ((prNewKey->u4KeyIndex & IS_UNICAST_KEY) == IS_UNICAST_KEY) + ? 1 : 0; + prCmdKey->ucIsAuthenticator = + ((prNewKey->u4KeyIndex & IS_AUTHENTICATOR) == IS_AUTHENTICATOR) + ? 1 : 0; + /* Copy the addr of the key */ + if ((prNewKey->u4KeyIndex & IS_UNICAST_KEY) == IS_UNICAST_KEY) { + if (prStaRec) { + /* Overwrite the fgNoHandshakeSec in case */ + fgNoHandshakeSec = FALSE; /* Legacy 802.1x wep case ? */ + /* ASSERT(FALSE); */ + } + } else { + if (!IS_BSS_ACTIVE(prBssInfo)) + DBGLOG_LIMITED(REQ, INFO, + "[wlan] BSS info (%d) not active yet!", + prNewKey->ucBssIdx); + } + prCmdKey->ucBssIdx = prBssInfo->ucBssIndex; + prCmdKey->ucKeyId = (uint8_t) (prNewKey->u4KeyIndex & 0xff); + /* Note: the key length may not correct for WPA-None */ + prCmdKey->ucKeyLen = (uint8_t) prNewKey->u4KeyLength; + kalMemCopy(prCmdKey->aucKeyMaterial, + (uint8_t *)prNewKey->aucKeyMaterial, prCmdKey->ucKeyLen); + if (prNewKey->ucCipher) { + prCmdKey->ucAlgorithmId = prNewKey->ucCipher; + if (IS_BSS_AIS(prBssInfo)) { +#if CFG_SUPPORT_802_11W + if (prCmdKey->ucAlgorithmId == CIPHER_SUITE_BIP) { + if (prCmdKey->ucKeyId >= 4) { + struct AIS_SPECIFIC_BSS_INFO + *prAisSpecBssInfo; + + prAisSpecBssInfo = + aisGetAisSpecBssInfo(prAdapter, + prNewKey->ucBssIdx); + prAisSpecBssInfo->fgBipKeyInstalled = + TRUE; + } + } +#endif + if (prCmdKey->ucAlgorithmId == CIPHER_SUITE_TKIP) { + /* Todo:: Support AP mode defragment */ + /* for pairwise key only */ + if ((prNewKey->u4KeyIndex & BITS(30, 31)) == + ((IS_UNICAST_KEY) | (IS_TRANSMIT_KEY))) { + kalMemCopy( + prAisSpecBssInfo->aucRxMicKey, + &prCmdKey->aucKeyMaterial[16], + MIC_KEY_LEN); + kalMemCopy( + prAisSpecBssInfo->aucTxMicKey, + &prCmdKey->aucKeyMaterial[24], + MIC_KEY_LEN); + } + } + } else { +#if CFG_SUPPORT_802_11W + /* AP PMF */ + if ((prCmdKey->ucKeyId >= 4 && prCmdKey->ucKeyId <= 5) + && (prCmdKey->ucAlgorithmId == CIPHER_SUITE_BIP)) { + DBGLOG_LIMITED(RSN, INFO, "AP mode set BIP\n"); + prBssInfo->rApPmfCfg.fgBipKeyInstalled = TRUE; + } +#endif + } + } else { /* Legacy windows NDIS no cipher info */ +#if 0 + if (prNewKey->u4KeyLength == 5) { + prCmdKey->ucAlgorithmId = CIPHER_SUITE_WEP40; + } else if (prNewKey->u4KeyLength == 13) { + prCmdKey->ucAlgorithmId = CIPHER_SUITE_WEP104; + } else if (prNewKey->u4KeyLength == 16) { + if (prAdapter->rWifiVar.rConnSettings.eAuthMode < + AUTH_MODE_WPA) + prCmdKey->ucAlgorithmId = CIPHER_SUITE_WEP128; + else { + if (IS_BSS_AIS(prBssInfo)) { +#if CFG_SUPPORT_802_11W + if (prCmdKey->ucKeyId >= 4) { + struct AIS_SPECIFIC_BSS_INFO + *prAisSpecBssInfo; + + prCmdKey->ucAlgorithmId = + CIPHER_SUITE_BIP; + prAisSpecBssInfo = + &prAdapter->rWifiVar + .rAisSpecificBssInfo; + prAisSpecBssInfo + ->fgBipKeyInstalled = + TRUE; + } else +#endif + { + prCmdKey->ucAlgorithmId = CIPHER_SUITE_CCMP; + if (rsnCheckPmkidCandicate(prAdapter)) { + DBGLOG(RSN, TRACE, + "Add key: Prepare a timer to indicate candidate PMKID\n"); + cnmTimerStopTimer(prAdapter, + &prAisSpecBssInfo + ->rPreauthenticationTimer); + cnmTimerStartTimer(prAdapter, + &prAisSpecBssInfo + ->rPreauthenticationTimer, + SEC_TO_MSEC( + WAIT_TIME_IND_PMKID_CANDICATE_SEC)); + } + } + } + } + } else if (prNewKey->u4KeyLength == 32) { + if (IS_BSS_AIS(prBssInfo)) { + if (prAdapter->rWifiVar.rConnSettings.eAuthMode + == AUTH_MODE_WPA_NONE) { + if (prAdapter->rWifiVar.rConnSettings + .eEncStatus == + ENUM_ENCRYPTION2_ENABLED) { + prCmdKey->ucAlgorithmId = + CIPHER_SUITE_TKIP; + } else if (prAdapter->rWifiVar + .rConnSettings.eEncStatus == + ENUM_ENCRYPTION3_ENABLED) { + prCmdKey->ucAlgorithmId = + CIPHER_SUITE_CCMP; + prCmdKey->ucKeyLen = + CCMP_KEY_LEN; + } + } else { + prCmdKey->ucAlgorithmId = + CIPHER_SUITE_TKIP; + kalMemCopy( + prAdapter->rWifiVar + .rAisSpecificBssInfo + .aucRxMicKey, + &prCmdKey->aucKeyMaterial[16], + MIC_KEY_LEN); + kalMemCopy( + prAdapter->rWifiVar + .rAisSpecificBssInfo + .aucTxMicKey, + &prCmdKey->aucKeyMaterial[24], + MIC_KEY_LEN); + if (0 /* Todo::GCMP & GCMP-BIP ? */) { + if (rsnCheckPmkidCandicate(prAdapter)) { + DBGLOG(RSN, TRACE, + "Add key: Prepare a timer to indicate candidate PMKID\n"); + cnmTimerStopTimer(prAdapter, + &prAisSpecBssInfo-> + rPreauthenticationTimer); + cnmTimerStartTimer(prAdapter, + &prAisSpecBssInfo-> + rPreauthenticationTimer, + SEC_TO_MSEC( + WAIT_TIME_IND_PMKID_CANDICATE_SEC)); + } + } else { + prCmdKey->ucAlgorithmId = CIPHER_SUITE_TKIP; + } + } +} +#endif + } + { +#if CFG_SUPPORT_TDLS + prTmpStaRec = cnmGetStaRecByAddress(prAdapter, + prBssInfo->ucBssIndex, prNewKey->arBSSID); + if (prTmpStaRec) { + if (IS_DLS_STA(prTmpStaRec)) { + prStaRec = prTmpStaRec; + + /*128 ,TODO GCMP 256 */ + prCmdKey->ucAlgorithmId = CIPHER_SUITE_CCMP; + + kalMemCopy(prCmdKey->aucPeerAddr, + prStaRec->aucMacAddr, MAC_ADDR_LEN); + } + } +#endif + +#if CFG_SUPPORT_802_11W + /* AP PMF */ + if (prCmdKey->ucAlgorithmId == CIPHER_SUITE_BIP) { + if (prCmdKey->ucIsAuthenticator) { + DBGLOG_LIMITED(RSN, INFO, + "Authenticator BIP bssid:%d\n", + prBssInfo->ucBssIndex); + + prCmdKey->ucWlanIndex = + secPrivacySeekForBcEntry(prAdapter, + prBssInfo->ucBssIndex, + prBssInfo->aucOwnMacAddr, + STA_REC_INDEX_NOT_FOUND, + prCmdKey->ucAlgorithmId, + prCmdKey->ucKeyId); + } else { + if (prBssInfo->prStaRecOfAP) { + prCmdKey->ucWlanIndex = + secPrivacySeekForBcEntry(prAdapter, + prBssInfo->ucBssIndex, + prBssInfo->prStaRecOfAP + ->aucMacAddr, + prBssInfo->prStaRecOfAP + ->ucIndex, + prCmdKey->ucAlgorithmId, + prCmdKey->ucKeyId); + } + } + + DBGLOG_LIMITED(RSN, INFO, "BIP BC wtbl index:%d\n", + prCmdKey->ucWlanIndex); + } else +#endif + if (1) { + if (prStaRec) { + if (prCmdKey->ucKeyType) { /* RSN STA */ + struct WLAN_TABLE *prWtbl; + + prWtbl = prAdapter->rWifiVar.arWtbl; + prWtbl[prStaRec->ucWlanIndex].ucKeyId = + prCmdKey->ucKeyId; + prCmdKey->ucWlanIndex = + prStaRec->ucWlanIndex; + + /* wait for CMD Done ? */ + prStaRec->fgTransmitKeyExist = TRUE; + + kalMemCopy(prCmdKey->aucPeerAddr, + prNewKey->arBSSID, + MAC_ADDR_LEN); +#if CFG_SUPPORT_802_11W + /* AP PMF */ + DBGLOG_LIMITED(RSN, INFO, + "Assign client PMF flag = %d\n", + prStaRec->rPmfCfg.fgApplyPmf); + prCmdKey->ucMgmtProtection = + prStaRec->rPmfCfg.fgApplyPmf; +#endif + } else { + ASSERT(FALSE); + } + } else { /* Overwrite the old one for AP and STA WEP */ + if (prBssInfo->prStaRecOfAP) { + DBGLOG_LIMITED(RSN, INFO, "AP REC\n"); + prCmdKey->ucWlanIndex = + secPrivacySeekForBcEntry( + prAdapter, + prBssInfo->ucBssIndex, + prBssInfo->prStaRecOfAP + ->aucMacAddr, + prBssInfo->prStaRecOfAP + ->ucIndex, + prCmdKey->ucAlgorithmId, + prCmdKey->ucKeyId); + kalMemCopy(prCmdKey->aucPeerAddr, + prBssInfo->prStaRecOfAP + ->aucMacAddr, + MAC_ADDR_LEN); + } else { + DBGLOG_LIMITED(RSN, INFO, + "!AP && !STA REC\n"); + prCmdKey->ucWlanIndex = + secPrivacySeekForBcEntry( + prAdapter, + prBssInfo->ucBssIndex, + prBssInfo->aucOwnMacAddr, + STA_REC_INDEX_NOT_FOUND, + prCmdKey->ucAlgorithmId, + prCmdKey->ucKeyId); + kalMemCopy(prCmdKey->aucPeerAddr, + prBssInfo->aucOwnMacAddr, + MAC_ADDR_LEN); + } + if (prCmdKey->ucKeyId >= MAX_KEY_NUM) { + DBGLOG_LIMITED(RSN, ERROR, + "prCmdKey->ucKeyId [%u] overrun\n", + prCmdKey->ucKeyId); + return WLAN_STATUS_FAILURE; + } + if (fgNoHandshakeSec) { + /* WEP: STA and AP */ + prBssInfo->wepkeyWlanIdx = + prCmdKey->ucWlanIndex; + prBssInfo->wepkeyUsed[ + prCmdKey->ucKeyId] = TRUE; + } else if (!prBssInfo->prStaRecOfAP) { + /* AP WPA/RSN */ + prBssInfo->ucBMCWlanIndexS[ + prCmdKey->ucKeyId] = + prCmdKey->ucWlanIndex; + prBssInfo->ucBMCWlanIndexSUsed[ + prCmdKey->ucKeyId] = TRUE; + } else { + /* STA WPA/RSN, should not have tx but + * no sta record + */ + prBssInfo->ucBMCWlanIndexS[ + prCmdKey->ucKeyId] = + prCmdKey->ucWlanIndex; + prBssInfo->ucBMCWlanIndexSUsed[ + prCmdKey->ucKeyId] = TRUE; + DBGLOG_LIMITED(RSN, INFO, + "BMCWlanIndex kid = %d, index = %d\n", + prCmdKey->ucKeyId, + prCmdKey->ucWlanIndex); + } + if (prCmdKey->ucTxKey) { /* */ + prBssInfo->fgBcDefaultKeyExist = TRUE; + prBssInfo->ucBcDefaultKeyIdx = + prCmdKey->ucKeyId; + } + } + } + } +#if 1 + DBGLOG_LIMITED(RSN, INFO, "Add key to wlanIdx %d,BSS=%d," MACSTR + "Tx=%d,type=%d,Auth=%d,cipher=%d,keyid=%d,keylen=%d\n", + prCmdKey->ucWlanIndex, prCmdKey->ucBssIdx, + MAC2STR(prCmdKey->aucPeerAddr), prCmdKey->ucTxKey, + prCmdKey->ucKeyType, prCmdKey->ucIsAuthenticator, + prCmdKey->ucAlgorithmId, prCmdKey->ucKeyId, + prCmdKey->ucKeyLen); + DBGLOG_MEM8(RSN, INFO, prCmdKey->aucKeyMaterial, prCmdKey->ucKeyLen); + if (prCmdKey->ucKeyId < MAX_KEY_NUM) { + DBGLOG_LIMITED(RSN, INFO, "wepkeyUsed=%d,wepkeyWlanIdx=%d\n", + prBssInfo->wepkeyUsed[prCmdKey->ucKeyId], + prBssInfo->wepkeyWlanIdx); + + DBGLOG_LIMITED(RSN, INFO, + "ucBMCWlanIndexSUsed=%d,ucBMCWlanIndexS=%d\n", + prBssInfo->ucBMCWlanIndexSUsed[prCmdKey->ucKeyId], + prBssInfo->ucBMCWlanIndexS[prCmdKey->ucKeyId]); + } +#endif + prAisSpecBssInfo->ucKeyAlgorithmId = prCmdKey->ucAlgorithmId; + /* insert into prCmdQueue */ + kalEnqueueCommand(prGlueInfo, (struct QUE_ENTRY *) prCmdInfo); + /* wakeup txServiceThread later */ + GLUE_SET_EVENT(prGlueInfo); + return WLAN_STATUS_PENDING; +} /* wlanoidSetAddKey */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to request the driver to remove the key at + * the specified key index. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_DATA + * \retval WLAN_STATUS_INVALID_LENGTH + * \retval WLAN_STATUS_ADAPTER_NOT_READY + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetRemoveKey(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + DEBUGFUNC("wlanoidSetRemoveKey"); + + return wlanSetRemoveKey(prAdapter, pvSetBuffer, u4SetBufferLen, + pu4SetInfoLen, TRUE); +} /* wlanoidSetRemoveKey */ + +uint32_t +wlanSetRemoveKey(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen, IN uint8_t fgIsOid) { + struct GLUE_INFO *prGlueInfo; + struct CMD_INFO *prCmdInfo; + struct PARAM_REMOVE_KEY *prRemovedKey; + struct CMD_802_11_KEY *prCmdKey; + struct WLAN_TABLE *prWlanTable; + struct STA_RECORD *prStaRec = NULL; + struct BSS_INFO *prBssInfo; + /* UINT_8 i = 0; */ + u_int8_t fgRemoveWepKey = FALSE; + uint32_t ucRemoveBCKeyAtIdx = WTBL_RESERVED_ENTRY; + uint32_t u4KeyIndex; + struct mt66xx_chip_info *prChipInfo; + uint16_t cmd_size; + + DEBUGFUNC("wlanSetRemoveKey"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + prChipInfo = prAdapter->chip_info; + + *pu4SetInfoLen = sizeof(struct PARAM_REMOVE_KEY); + + if (u4SetBufferLen < sizeof(struct PARAM_REMOVE_KEY)) + return WLAN_STATUS_INVALID_LENGTH; + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, WARN, + "Fail in set remove key! (Adapter not ready). ACPI=D%d, Radio=%d\n", + prAdapter->rAcpiState, prAdapter->fgIsRadioOff); + return WLAN_STATUS_ADAPTER_NOT_READY; + } + + ASSERT(pvSetBuffer); + prRemovedKey = (struct PARAM_REMOVE_KEY *) pvSetBuffer; + + prGlueInfo = prAdapter->prGlueInfo; + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prRemovedKey->ucBssIdx); + ASSERT(prBssInfo); + + u4KeyIndex = prRemovedKey->u4KeyIndex & 0x000000FF; +#if CFG_SUPPORT_802_11W + ASSERT(u4KeyIndex < MAX_KEY_NUM + 2); +#else + /* ASSERT(prCmdKey->ucKeyId < MAX_KEY_NUM); */ +#endif + + if (u4KeyIndex >= 4) { + DBGLOG(RSN, INFO, "Remove bip key Index : 0x%08x\n", + u4KeyIndex); + return WLAN_STATUS_SUCCESS; + } + + /* Clean up the Tx key flag */ + if (prRemovedKey->u4KeyIndex & IS_UNICAST_KEY) { + prStaRec = cnmGetStaRecByAddress(prAdapter, + prRemovedKey->ucBssIdx, prRemovedKey->arBSSID); + if (!prStaRec) + return WLAN_STATUS_SUCCESS; + } else { + if (u4KeyIndex == prBssInfo->ucBcDefaultKeyIdx) + prBssInfo->fgBcDefaultKeyExist = FALSE; + } + + if (!prStaRec) { + if (prBssInfo->wepkeyUsed[u4KeyIndex] == TRUE) + fgRemoveWepKey = TRUE; + + if (fgRemoveWepKey) { + DBGLOG(RSN, INFO, "Remove wep key id = %d", u4KeyIndex); + prBssInfo->wepkeyUsed[u4KeyIndex] = FALSE; + if (prBssInfo->fgBcDefaultKeyExist && + prBssInfo->ucBcDefaultKeyIdx == u4KeyIndex) { + prBssInfo->fgBcDefaultKeyExist = FALSE; + prBssInfo->ucBcDefaultKeyIdx = 0xff; + } + ASSERT(prBssInfo->wepkeyWlanIdx < WTBL_SIZE); + ucRemoveBCKeyAtIdx = prBssInfo->wepkeyWlanIdx; + secPrivacyFreeForEntry(prAdapter, + prBssInfo->wepkeyWlanIdx); + prBssInfo->wepkeyWlanIdx = WTBL_RESERVED_ENTRY; + } else { + DBGLOG(RSN, INFO, "Remove group key id = %d", + u4KeyIndex); + + if (prBssInfo->ucBMCWlanIndexSUsed[u4KeyIndex]) { + if (prBssInfo->fgBcDefaultKeyExist && + prBssInfo->ucBcDefaultKeyIdx == + u4KeyIndex) { + prBssInfo->fgBcDefaultKeyExist = FALSE; + prBssInfo->ucBcDefaultKeyIdx = 0xff; + } + if (u4KeyIndex != 0) + ASSERT(prBssInfo->ucBMCWlanIndexS[ + u4KeyIndex] < WTBL_SIZE); + ucRemoveBCKeyAtIdx = + prBssInfo->ucBMCWlanIndexS[u4KeyIndex]; + + secPrivacyFreeForEntry(prAdapter, + prBssInfo->ucBMCWlanIndexS[u4KeyIndex]); + prBssInfo->ucBMCWlanIndexSUsed[u4KeyIndex] + = FALSE; + prBssInfo->ucBMCWlanIndexS[u4KeyIndex] + = WTBL_RESERVED_ENTRY; + } + } + + if (ucRemoveBCKeyAtIdx >= WTBL_SIZE) + return WLAN_STATUS_SUCCESS; + } + + cmd_size = prChipInfo->u2CmdTxHdrSize + sizeof(struct CMD_802_11_KEY); + prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, cmd_size); + /* Dump PARAM_REMOVE_KEY content. */ + DBGLOG(RSN, INFO, "PARAM_REMOVE_KEY: BSSID(" MACSTR + "), BSS_INDEX (%d), Length(0x%08x), Key Index(0x%08x, %d) ucRemoveBCKeyAtIdx = %d\n", + MAC2STR(prRemovedKey->arBSSID), + prRemovedKey->ucBssIdx, + prRemovedKey->u4Length, prRemovedKey->u4KeyIndex, u4KeyIndex, + ucRemoveBCKeyAtIdx); + + if (!prCmdInfo) { + DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); + return WLAN_STATUS_FAILURE; + } + + prWlanTable = prAdapter->rWifiVar.arWtbl; + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prRemovedKey->ucBssIdx); + + /* compose CMD_802_11_KEY cmd pkt */ + prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; + /* prCmdInfo->ucBssIndex = prRemovedKey->ucBssIdx; */ + prCmdInfo->u2InfoBufLen = cmd_size; + prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; + prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; + prCmdInfo->fgIsOid = fgIsOid; + prCmdInfo->ucCID = CMD_ID_ADD_REMOVE_KEY; + prCmdInfo->fgSetQuery = TRUE; + prCmdInfo->fgNeedResp = FALSE; + /* prCmdInfo->fgDriverDomainMCR = FALSE; */ + prCmdInfo->u4SetInfoLen = sizeof(struct PARAM_REMOVE_KEY); + prCmdInfo->pvInformationBuffer = pvSetBuffer; + prCmdInfo->u4InformationBufferLength = u4SetBufferLen; + + /* Setup WIFI_CMD_T */ + NIC_FILL_CMD_TX_HDR(prAdapter, + prCmdInfo->pucInfoBuffer, + prCmdInfo->u2InfoBufLen, + prCmdInfo->ucCID, + CMD_PACKET_TYPE_ID, + &prCmdInfo->ucCmdSeqNum, + prCmdInfo->fgSetQuery, &prCmdKey, FALSE, 0, S2D_INDEX_CMD_H2N); + + kalMemZero((uint8_t *) prCmdKey, + sizeof(struct CMD_802_11_KEY)); + + prCmdKey->ucAddRemove = 0; /* Remove */ + prCmdKey->ucKeyId = (uint8_t) u4KeyIndex; + kalMemCopy(prCmdKey->aucPeerAddr, + (uint8_t *) prRemovedKey->arBSSID, MAC_ADDR_LEN); + prCmdKey->ucBssIdx = prRemovedKey->ucBssIdx; + + if (prStaRec) { + prCmdKey->ucKeyType = 1; + prCmdKey->ucWlanIndex = prStaRec->ucWlanIndex; + prStaRec->fgTransmitKeyExist = FALSE; + } else if (ucRemoveBCKeyAtIdx < WTBL_SIZE) { + prCmdKey->ucWlanIndex = ucRemoveBCKeyAtIdx; + } else { + ASSERT(FALSE); + } + + /* insert into prCmdQueue */ + kalEnqueueCommand(prGlueInfo, + (struct QUE_ENTRY *) prCmdInfo); + + /* wakeup txServiceThread later */ + GLUE_SET_EVENT(prGlueInfo); + + return WLAN_STATUS_PENDING; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set the default key + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_ADAPTER_NOT_READY + * \retval WLAN_STATUS_INVALID_LENGTH + * \retval WLAN_STATUS_INVALID_DATA + * + * \note The setting buffer PARAM_KEY_T, which is set by NDIS, is unpacked. + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetDefaultKey(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct GLUE_INFO *prGlueInfo; + struct CMD_INFO *prCmdInfo; + struct PARAM_DEFAULT_KEY *prDefaultKey; + struct CMD_DEFAULT_KEY *prCmdDefaultKey; + struct BSS_INFO *prBssInfo; + u_int8_t fgSetWepKey = FALSE; + uint8_t ucWlanIndex = WTBL_RESERVED_ENTRY; + struct mt66xx_chip_info *prChipInfo; + uint16_t cmd_size; + + DEBUGFUNC("wlanoidSetDefaultKey"); + + ASSERT(prAdapter); + ASSERT(pvSetBuffer); + ASSERT(pu4SetInfoLen); + prChipInfo = prAdapter->chip_info; + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, WARN, + "Fail in set add key! (Adapter not ready). ACPI=D%d, Radio=%d\n", + prAdapter->rAcpiState, prAdapter->fgIsRadioOff); + return WLAN_STATUS_ADAPTER_NOT_READY; + } + + prDefaultKey = (struct PARAM_DEFAULT_KEY *) pvSetBuffer; + + *pu4SetInfoLen = u4SetBufferLen; + + /* Dump PARAM_DEFAULT_KEY_T content. */ + DBGLOG(RSN, INFO, + "ucBssIndex %d, Key Index : %d, Unicast Key : %d, Multicast Key : %d\n", + prDefaultKey->ucBssIdx, + prDefaultKey->ucKeyID, prDefaultKey->ucUnicast, + prDefaultKey->ucMulticast); + + /* prWlanTable = prAdapter->rWifiVar.arWtbl; */ + prGlueInfo = prAdapter->prGlueInfo; + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prDefaultKey->ucBssIdx); + + DBGLOG(RSN, INFO, "WlanIdx = %d\n", + prBssInfo->wepkeyWlanIdx); + + if (prDefaultKey->ucMulticast) { + ASSERT(prBssInfo); + if (prBssInfo->prStaRecOfAP) { /* Actually GC not have wep */ + if (prBssInfo->wepkeyUsed[prDefaultKey->ucKeyID]) { + prBssInfo->ucBcDefaultKeyIdx = + prDefaultKey->ucKeyID; + prBssInfo->fgBcDefaultKeyExist = TRUE; + ucWlanIndex = prBssInfo->wepkeyWlanIdx; + } else { + if (prDefaultKey->ucUnicast) { + DBGLOG(RSN, ERROR, + "Set STA Unicast default key"); + return WLAN_STATUS_SUCCESS; + } + ASSERT(FALSE); + } + } else { /* For AP mode only */ + + if (prBssInfo->wepkeyUsed[prDefaultKey->ucKeyID] + == TRUE) + fgSetWepKey = TRUE; + + if (fgSetWepKey) { + ucWlanIndex = prBssInfo->wepkeyWlanIdx; + } else { + if (!prBssInfo->ucBMCWlanIndexSUsed[ + prDefaultKey->ucKeyID]) { + DBGLOG(RSN, ERROR, + "Set AP wep default but key not exist!"); + return WLAN_STATUS_SUCCESS; + } + ucWlanIndex = prBssInfo->ucBMCWlanIndexS[ + prDefaultKey->ucKeyID]; + } + prBssInfo->ucBcDefaultKeyIdx = prDefaultKey->ucKeyID; + prBssInfo->fgBcDefaultKeyExist = TRUE; + } + if (ucWlanIndex > WTBL_SIZE) { + DBGLOG(RSN, ERROR, "ucWlanIndex = %d, wepUsed = %d\n", + ucWlanIndex, + prBssInfo->wepkeyUsed[prDefaultKey->ucKeyID]); + return WLAN_STATUS_FAILURE; + } + + } else { + DBGLOG(RSN, ERROR, + "Check the case set unicast default key!"); + ASSERT(FALSE); + } + + cmd_size = prChipInfo->u2CmdTxHdrSize + sizeof(struct CMD_DEFAULT_KEY); + prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, cmd_size); + if (!prCmdInfo) { + DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); + return WLAN_STATUS_FAILURE; + } + + /* compose CMD_802_11_KEY cmd pkt */ + prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; + prCmdInfo->u2InfoBufLen = cmd_size; + prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; + prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; + prCmdInfo->fgIsOid = TRUE; + prCmdInfo->ucCID = CMD_ID_DEFAULT_KEY_ID; + prCmdInfo->fgSetQuery = TRUE; + prCmdInfo->fgNeedResp = FALSE; + prCmdInfo->u4SetInfoLen = u4SetBufferLen; + prCmdInfo->pvInformationBuffer = pvSetBuffer; + prCmdInfo->u4InformationBufferLength = u4SetBufferLen; + + /* Setup WIFI_CMD_T */ + NIC_FILL_CMD_TX_HDR(prAdapter, + prCmdInfo->pucInfoBuffer, + prCmdInfo->u2InfoBufLen, + prCmdInfo->ucCID, + CMD_PACKET_TYPE_ID, + &prCmdInfo->ucCmdSeqNum, + prCmdInfo->fgSetQuery, + &prCmdDefaultKey, FALSE, 0, S2D_INDEX_CMD_H2N); + kalMemZero(prCmdDefaultKey, sizeof(struct CMD_DEFAULT_KEY)); + + prCmdDefaultKey->ucBssIdx = prDefaultKey->ucBssIdx; + prCmdDefaultKey->ucKeyId = prDefaultKey->ucKeyID; + prCmdDefaultKey->ucWlanIndex = ucWlanIndex; + prCmdDefaultKey->ucMulticast = prDefaultKey->ucMulticast; + + DBGLOG(RSN, INFO, + "CMD_ID_DEFAULT_KEY_ID (%d) with wlan idx = %d\n", + prDefaultKey->ucKeyID, ucWlanIndex); + + /* insert into prCmdQueue */ + kalEnqueueCommand(prGlueInfo, + (struct QUE_ENTRY *) prCmdInfo); + + /* wakeup txServiceThread later */ + GLUE_SET_EVENT(prGlueInfo); + + return WLAN_STATUS_PENDING; +} /* wlanoidSetDefaultKey */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to query the current encryption status. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[out] pvQueryBuffer A pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufferLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the call + * failed due to invalid length of the query buffer, + * returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryEncryptionStatus(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + u_int8_t fgTransmitKeyAvailable = TRUE; + enum ENUM_WEP_STATUS eEncStatus = 0; + struct CONNECTION_SETTINGS *prConnSettings; + struct BSS_INFO *prAisBssInfo; + uint8_t ucBssIndex = AIS_DEFAULT_INDEX; + + DEBUGFUNC("wlanoidQueryEncryptionStatus"); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + prConnSettings = + aisGetConnSettings(prAdapter, ucBssIndex); + prAisBssInfo = + aisGetAisBssInfo(prAdapter, ucBssIndex); + + *pu4QueryInfoLen = sizeof(enum ENUM_WEP_STATUS); + + fgTransmitKeyAvailable = + prAisBssInfo->fgBcDefaultKeyExist; + + switch (prConnSettings->eEncStatus) { + case ENUM_ENCRYPTION4_ENABLED: + if (fgTransmitKeyAvailable) + eEncStatus = ENUM_ENCRYPTION4_ENABLED; + else + eEncStatus = ENUM_ENCRYPTION4_KEY_ABSENT; + break; + + case ENUM_ENCRYPTION3_ENABLED: + if (fgTransmitKeyAvailable) + eEncStatus = ENUM_ENCRYPTION3_ENABLED; + else + eEncStatus = ENUM_ENCRYPTION3_KEY_ABSENT; + break; + + case ENUM_ENCRYPTION2_ENABLED: + if (fgTransmitKeyAvailable) { + eEncStatus = ENUM_ENCRYPTION2_ENABLED; + break; + } + eEncStatus = ENUM_ENCRYPTION2_KEY_ABSENT; + break; + + case ENUM_ENCRYPTION1_ENABLED: + if (fgTransmitKeyAvailable) + eEncStatus = ENUM_ENCRYPTION1_ENABLED; + else + eEncStatus = ENUM_ENCRYPTION1_KEY_ABSENT; + break; + + case ENUM_ENCRYPTION_DISABLED: + eEncStatus = ENUM_ENCRYPTION_DISABLED; + break; + + default: + DBGLOG(REQ, ERROR, "Unknown Encryption Status Setting:%d\n", + prConnSettings->eEncStatus); + } + +#if DBG + DBGLOG(REQ, INFO, + "Encryption status: %d Return:%d\n", + prConnSettings->eEncStatus, eEncStatus); +#endif + + *(enum ENUM_WEP_STATUS *) pvQueryBuffer = eEncStatus; + + return WLAN_STATUS_SUCCESS; +} /* wlanoidQueryEncryptionStatus */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set the encryption status to the driver. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_ADAPTER_NOT_READY + * \retval WLAN_STATUS_NOT_SUPPORTED + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetEncryptionStatus(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct GLUE_INFO *prGlueInfo; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + enum ENUM_WEP_STATUS eEewEncrypt; + struct CONNECTION_SETTINGS *prConnSettings; + uint8_t ucBssIndex = 0; + + DEBUGFUNC("wlanoidSetEncryptionStatus"); + + ASSERT(prAdapter); + ASSERT(pvSetBuffer); + ASSERT(pu4SetInfoLen); + + prGlueInfo = prAdapter->prGlueInfo; + + ucBssIndex = GET_IOCTL_BSSIDX(prAdapter); + + DBGLOG(REQ, LOUD, "ucBssIndex %d\n", ucBssIndex); + + prConnSettings = + aisGetConnSettings(prAdapter, ucBssIndex); + + *pu4SetInfoLen = sizeof(enum ENUM_WEP_STATUS); + + /* if (IS_ARB_IN_RFTEST_STATE(prAdapter)) { */ + /* return WLAN_STATUS_SUCCESS; */ + /* } */ + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, WARN, + "Fail in set encryption status! (Adapter not ready). ACPI=D%d, Radio=%d\n", + prAdapter->rAcpiState, prAdapter->fgIsRadioOff); + return WLAN_STATUS_ADAPTER_NOT_READY; + } + + eEewEncrypt = *(enum ENUM_WEP_STATUS *) pvSetBuffer; + DBGLOG(REQ, INFO, "ENCRYPTION_STATUS %d\n", eEewEncrypt); + + switch (eEewEncrypt) { + case ENUM_ENCRYPTION_DISABLED: /* Disable WEP, TKIP, AES */ + DBGLOG(RSN, INFO, "Disable Encryption\n"); + secSetCipherSuite(prAdapter, + CIPHER_FLAG_WEP40 | CIPHER_FLAG_WEP104 | + CIPHER_FLAG_WEP128, + ucBssIndex); + break; + + case ENUM_ENCRYPTION1_ENABLED: /* Enable WEP. Disable TKIP, AES */ + DBGLOG(RSN, INFO, "Enable Encryption1\n"); + secSetCipherSuite(prAdapter, + CIPHER_FLAG_WEP40 | CIPHER_FLAG_WEP104 | + CIPHER_FLAG_WEP128, + ucBssIndex); + break; + + case ENUM_ENCRYPTION2_ENABLED: /* Enable WEP, TKIP. Disable AES */ + secSetCipherSuite(prAdapter, + CIPHER_FLAG_WEP40 | CIPHER_FLAG_WEP104 | + CIPHER_FLAG_WEP128 | CIPHER_FLAG_TKIP, + ucBssIndex); + DBGLOG(RSN, INFO, "Enable Encryption2\n"); + break; + + case ENUM_ENCRYPTION3_ENABLED: /* Enable WEP, TKIP, AES */ + secSetCipherSuite(prAdapter, + CIPHER_FLAG_WEP40 | + CIPHER_FLAG_WEP104 | CIPHER_FLAG_WEP128 | + CIPHER_FLAG_TKIP | CIPHER_FLAG_CCMP, + ucBssIndex); + DBGLOG(RSN, INFO, "Enable Encryption3\n"); + break; + + case ENUM_ENCRYPTION4_ENABLED: /* Eanble GCMP256 */ + secSetCipherSuite(prAdapter, + CIPHER_FLAG_CCMP | CIPHER_FLAG_GCMP256, + ucBssIndex); + DBGLOG(RSN, INFO, "Enable Encryption4\n"); + break; + + default: + DBGLOG(RSN, INFO, "Unacceptible encryption status: %d\n", + *(enum ENUM_WEP_STATUS *) pvSetBuffer); + + rStatus = WLAN_STATUS_NOT_SUPPORTED; + } + + if (rStatus == WLAN_STATUS_SUCCESS) { + /* Save the new encryption status. */ + prConnSettings->eEncStatus = * + (enum ENUM_WEP_STATUS *) pvSetBuffer; + } + + return rStatus; +} /* wlanoidSetEncryptionStatus */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to query the driver's WPA2 status. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[out] pvQueryBuffer A pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufferLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the call + * failed due to invalid length of the query buffer, + * returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryCapability(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + struct PARAM_CAPABILITY *prCap; + struct PARAM_AUTH_ENCRYPTION + *prAuthenticationEncryptionSupported; + + DEBUGFUNC("wlanoidQueryCapability"); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + *pu4QueryInfoLen = 4 * sizeof(uint32_t) + 14 * sizeof( + struct PARAM_AUTH_ENCRYPTION); + + if (u4QueryBufferLen < *pu4QueryInfoLen) + return WLAN_STATUS_INVALID_LENGTH; + + prCap = (struct PARAM_CAPABILITY *) pvQueryBuffer; + + prCap->u4Length = *pu4QueryInfoLen; + prCap->u4Version = 2; /* WPA2 */ + prCap->u4NoOfAuthEncryptPairsSupported = 15; + + prAuthenticationEncryptionSupported = + &prCap->arAuthenticationEncryptionSupported[0]; + + /* fill 14 entries of supported settings */ + prAuthenticationEncryptionSupported[0].eAuthModeSupported = + AUTH_MODE_OPEN; + + prAuthenticationEncryptionSupported[0].eEncryptStatusSupported + = ENUM_ENCRYPTION_DISABLED; + + prAuthenticationEncryptionSupported[1].eAuthModeSupported = + AUTH_MODE_OPEN; + prAuthenticationEncryptionSupported[1].eEncryptStatusSupported + = ENUM_ENCRYPTION1_ENABLED; + + prAuthenticationEncryptionSupported[2].eAuthModeSupported = + AUTH_MODE_SHARED; + prAuthenticationEncryptionSupported[2].eEncryptStatusSupported + = ENUM_ENCRYPTION_DISABLED; + + prAuthenticationEncryptionSupported[3].eAuthModeSupported = + AUTH_MODE_SHARED; + prAuthenticationEncryptionSupported[3].eEncryptStatusSupported + = ENUM_ENCRYPTION1_ENABLED; + + prAuthenticationEncryptionSupported[4].eAuthModeSupported = + AUTH_MODE_WPA; + prAuthenticationEncryptionSupported[4].eEncryptStatusSupported + = ENUM_ENCRYPTION2_ENABLED; + + prAuthenticationEncryptionSupported[5].eAuthModeSupported = + AUTH_MODE_WPA; + prAuthenticationEncryptionSupported[5].eEncryptStatusSupported + = ENUM_ENCRYPTION3_ENABLED; + + prAuthenticationEncryptionSupported[6].eAuthModeSupported = + AUTH_MODE_WPA_PSK; + prAuthenticationEncryptionSupported[6].eEncryptStatusSupported + = ENUM_ENCRYPTION2_ENABLED; + + prAuthenticationEncryptionSupported[7].eAuthModeSupported = + AUTH_MODE_WPA_PSK; + prAuthenticationEncryptionSupported[7].eEncryptStatusSupported + = ENUM_ENCRYPTION3_ENABLED; + + prAuthenticationEncryptionSupported[8].eAuthModeSupported = + AUTH_MODE_WPA_NONE; + prAuthenticationEncryptionSupported[8].eEncryptStatusSupported + = ENUM_ENCRYPTION2_ENABLED; + + prAuthenticationEncryptionSupported[9].eAuthModeSupported = + AUTH_MODE_WPA_NONE; + prAuthenticationEncryptionSupported[9].eEncryptStatusSupported + = ENUM_ENCRYPTION3_ENABLED; + + prAuthenticationEncryptionSupported[10].eAuthModeSupported = + AUTH_MODE_WPA2; + prAuthenticationEncryptionSupported[10].eEncryptStatusSupported + = ENUM_ENCRYPTION2_ENABLED; + + prAuthenticationEncryptionSupported[11].eAuthModeSupported = + AUTH_MODE_WPA2; + prAuthenticationEncryptionSupported[11].eEncryptStatusSupported + = ENUM_ENCRYPTION3_ENABLED; + + prAuthenticationEncryptionSupported[12].eAuthModeSupported = + AUTH_MODE_WPA2_PSK; + prAuthenticationEncryptionSupported[12].eEncryptStatusSupported + = ENUM_ENCRYPTION2_ENABLED; + + prAuthenticationEncryptionSupported[13].eAuthModeSupported = + AUTH_MODE_WPA2_PSK; + prAuthenticationEncryptionSupported[13].eEncryptStatusSupported + = ENUM_ENCRYPTION3_ENABLED; + + prAuthenticationEncryptionSupported[14].eAuthModeSupported + = AUTH_MODE_WPA2_PSK; + prAuthenticationEncryptionSupported[14].eEncryptStatusSupported + = ENUM_ENCRYPTION4_ENABLED; + + return WLAN_STATUS_SUCCESS; + +} /* wlanoidQueryCapability */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set the PMKID to the PMK cache in the + * driver. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval status + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetPmkid(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + struct PARAM_PMKID *prPmkid; + + DBGLOG(REQ, INFO, "wlanoidSetPmkid\n"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + ASSERT(pvSetBuffer); + + *pu4SetInfoLen = u4SetBufferLen; + prPmkid = (struct PARAM_PMKID *) pvSetBuffer; + if (u4SetBufferLen < sizeof(struct PARAM_PMKID)) + return WLAN_STATUS_INVALID_DATA; + return rsnSetPmkid(prAdapter, prPmkid); +} /* wlanoidSetPmkid */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to delete the PMKID in the PMK cache. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval status + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidDelPmkid(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + struct PARAM_PMKID *prPmkid; + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + ASSERT(pvSetBuffer); + + *pu4SetInfoLen = u4SetBufferLen; + prPmkid = (struct PARAM_PMKID *) pvSetBuffer; + + if (u4SetBufferLen < sizeof(struct PARAM_PMKID)) + return WLAN_STATUS_INVALID_DATA; + return rsnDelPmkid(prAdapter, prPmkid); +} /* wlanoidDelPmkid */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to delete all the PMKIDs in the PMK cache. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval status + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidFlushPmkid(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + uint8_t ucBssIndex = 0; + + ASSERT(prAdapter); + + ucBssIndex = GET_IOCTL_BSSIDX(prAdapter); + + return rsnFlushPmkid(prAdapter, ucBssIndex); +} /* wlanoidFlushPmkid */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to query the set of supported data rates that + * the radio is capable of running + * + * \param[in] prAdapter Pointer to the Adapter structure + * \param[out] pvQueryBuffer A pointer to the buffer that holds the result of + * the query + * \param[in] u4QueryBufferLen The length of the query buffer + * \param[out] pu4QueryInfoLen If the call is successful, returns the number + * of bytes written into the query buffer. If the + * call failed due to invalid length of the query + * buffer, returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQuerySupportedRates(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + uint8_t eRate[PARAM_MAX_LEN_RATES] = { + /* BSSBasicRateSet for 802.11n Non-HT rates */ + 0x8C, /* 6M */ + 0x92, /* 9M */ + 0x98, /* 12M */ + 0xA4, /* 18M */ + 0xB0, /* 24M */ + 0xC8, /* 36M */ + 0xE0, /* 48M */ + 0xEC /* 54M */ + }; + + DEBUGFUNC("wlanoidQuerySupportedRates"); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + *pu4QueryInfoLen = (sizeof(uint8_t) * + PARAM_MAX_LEN_RATES_EX); + + if (u4QueryBufferLen < *pu4QueryInfoLen) { + DBGLOG(REQ, WARN, "Invalid length %u\n", u4QueryBufferLen); + return WLAN_STATUS_INVALID_LENGTH; + } + + kalMemCopy(pvQueryBuffer, (void *) &eRate, + (sizeof(uint8_t) * PARAM_MAX_LEN_RATES)); + + return WLAN_STATUS_SUCCESS; +} /* end of wlanoidQuerySupportedRates() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to query current desired rates. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvQueryBuffer Pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufferLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number + * of bytes written into the query buffer. If the + * call failed due to invalid length of the query + * buffer, returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryDesiredRates(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + DEBUGFUNC("wlanoidQueryDesiredRates"); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + *pu4QueryInfoLen = (sizeof(uint8_t) * + PARAM_MAX_LEN_RATES_EX); + + if (u4QueryBufferLen < *pu4QueryInfoLen) { + DBGLOG(REQ, WARN, "Invalid length %u\n", u4QueryBufferLen); + return WLAN_STATUS_INVALID_LENGTH; + } + + kalMemCopy(pvQueryBuffer, + (void *) &(prAdapter->rWlanInfo.eDesiredRates), + (sizeof(uint8_t) * PARAM_MAX_LEN_RATES)); + + return WLAN_STATUS_SUCCESS; + +} /* end of wlanoidQueryDesiredRates() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to Set the desired rates. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer Pointer to the buffer that holds the data to be + * set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + * \retval WLAN_STATUS_INVALID_DATA + * \retval WLAN_STATUS_ADAPTER_NOT_READY + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetDesiredRates(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + uint32_t i; + + DEBUGFUNC("wlanoidSetDesiredRates"); + + ASSERT(prAdapter); + ASSERT(pvSetBuffer); + ASSERT(pu4SetInfoLen); + + if (u4SetBufferLen < (sizeof(uint8_t) * + PARAM_MAX_LEN_RATES)) { + DBGLOG(REQ, WARN, "Invalid length %u\n", u4SetBufferLen); + return WLAN_STATUS_INVALID_LENGTH; + } + + *pu4SetInfoLen = (sizeof(uint8_t) * PARAM_MAX_LEN_RATES); + + if (u4SetBufferLen < (sizeof(uint8_t) * + PARAM_MAX_LEN_RATES)) + return WLAN_STATUS_INVALID_LENGTH; + + kalMemCopy((void *) &(prAdapter->rWlanInfo.eDesiredRates), + pvSetBuffer, (sizeof(uint8_t) * PARAM_MAX_LEN_RATES)); + + prAdapter->rWlanInfo.eLinkAttr.ucDesiredRateLen = + PARAM_MAX_LEN_RATES; + for (i = 0; i < PARAM_MAX_LEN_RATES; i++) + prAdapter->rWlanInfo.eLinkAttr.u2DesiredRate[i] = + (uint16_t) (prAdapter->rWlanInfo.eDesiredRates[i]); + + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_LINK_ATTRIB, + TRUE, + FALSE, + TRUE, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_LINK_ATTRIB), + (uint8_t *) &(prAdapter->rWlanInfo.eLinkAttr), + pvSetBuffer, + u4SetBufferLen); + +} /* end of wlanoidSetDesiredRates() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to query the maximum frame size in bytes, + * not including the header. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[out] pvQueryBuffer A pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufferLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the + * call failed due to invalid length of the query + * buffer, returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryMaxFrameSize(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + DEBUGFUNC("wlanoidQueryMaxFrameSize"); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + if (u4QueryBufferLen < sizeof(uint32_t)) { + *pu4QueryInfoLen = sizeof(uint32_t); + return WLAN_STATUS_INVALID_LENGTH; + } + + *(uint32_t *) pvQueryBuffer = ETHERNET_MAX_PKT_SZ - + ETHERNET_HEADER_SZ; + *pu4QueryInfoLen = sizeof(uint32_t); + + return WLAN_STATUS_SUCCESS; +} /* wlanoidQueryMaxFrameSize */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to query the maximum total packet length + * in bytes. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[out] pvQueryBuffer A pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufferLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the call + * failed due to invalid length of the query buffer, + * returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryMaxTotalSize(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + DEBUGFUNC("wlanoidQueryMaxTotalSize"); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + if (u4QueryBufferLen < sizeof(uint32_t)) { + *pu4QueryInfoLen = sizeof(uint32_t); + return WLAN_STATUS_INVALID_LENGTH; + } + + *(uint32_t *) pvQueryBuffer = ETHERNET_MAX_PKT_SZ; + *pu4QueryInfoLen = sizeof(uint32_t); + + return WLAN_STATUS_SUCCESS; +} /* wlanoidQueryMaxTotalSize */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to query the vendor ID of the NIC. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[out] pvQueryBuffer A pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufferLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the call + * failed due to invalid length of the query buffer, + * returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryVendorId(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { +#if DBG + uint8_t *cp; +#endif + DEBUGFUNC("wlanoidQueryVendorId"); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + if (u4QueryBufferLen < sizeof(uint32_t)) { + *pu4QueryInfoLen = sizeof(uint32_t); + return WLAN_STATUS_INVALID_LENGTH; + } + + kalMemCopy(pvQueryBuffer, prAdapter->aucMacAddress, 3); + *((uint8_t *) pvQueryBuffer + 3) = 1; + *pu4QueryInfoLen = sizeof(uint32_t); + +#if DBG + cp = (uint8_t *) pvQueryBuffer; + DBGLOG(REQ, LOUD, "Vendor ID=%02x-%02x-%02x-%02x\n", cp[0], + cp[1], cp[2], cp[3]); +#endif + + return WLAN_STATUS_SUCCESS; +} /* wlanoidQueryVendorId */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to query the current RSSI value. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvQueryBuffer Pointer to the buffer that holds the result of the + * query. + * \param[in] u4QueryBufferLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the call failed due to invalid + * length of the query buffer, returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_BUFFER_TOO_SHORT + * \retval WLAN_STATUS_ADAPTER_NOT_READY + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryRssi(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + uint8_t ucBssIndex = AIS_DEFAULT_INDEX; + struct PARAM_LINK_SPEED_EX *prLinkSpeed; + struct LINK_SPEED_EX_ *prLq; + + DEBUGFUNC("wlanoidQueryRssi"); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + + ucBssIndex = GET_IOCTL_BSSIDX(prAdapter); + if (!IS_BSS_INDEX_AIS(prAdapter, ucBssIndex)) + return WLAN_STATUS_NOT_SUPPORTED; + + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + if (prAdapter->fgIsEnableLpdvt) + return WLAN_STATUS_NOT_SUPPORTED; + + *pu4QueryInfoLen = sizeof(struct PARAM_LINK_SPEED_EX); + prLq = &prAdapter->rLinkQuality.rLq[ucBssIndex]; + /* Check for query buffer length */ + if (u4QueryBufferLen < *pu4QueryInfoLen) { + DBGLOG(REQ, WARN, "Too short length %u\n", + u4QueryBufferLen); + return WLAN_STATUS_BUFFER_TOO_SHORT; + } + + if (kalGetMediaStateIndicated(prAdapter->prGlueInfo, + ucBssIndex) == + MEDIA_STATE_DISCONNECTED) { + return WLAN_STATUS_ADAPTER_NOT_READY; + } else if (prLq->fgIsLinkQualityValid == TRUE && + (kalGetTimeTick() - prLq->rLinkQualityUpdateTime) <= + CFG_LINK_QUALITY_VALID_PERIOD) { + prLinkSpeed = (struct PARAM_LINK_SPEED_EX *) pvQueryBuffer; + + prLinkSpeed->rLq[ucBssIndex]. + u2LinkSpeed = prLq->u2LinkSpeed * 5000; + prLinkSpeed->rLq[ucBssIndex].cRssi = prLq->cRssi; + + DBGLOG(REQ, TRACE, "ucBssIdx = %d, rate = %u, signal = %d\n", + ucBssIndex, + prLinkSpeed->rLq[ucBssIndex].u2LinkSpeed, + prLinkSpeed->rLq[ucBssIndex].cRssi); + return WLAN_STATUS_SUCCESS; + } +#ifdef LINUX + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_GET_LINK_QUALITY, + FALSE, + TRUE, + TRUE, + nicCmdEventQueryLinkQuality, + nicOidCmdTimeoutCommon, + *pu4QueryInfoLen, pvQueryBuffer, + pvQueryBuffer, + u4QueryBufferLen); +#else + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_GET_LINK_QUALITY, + FALSE, + TRUE, + TRUE, + nicCmdEventQueryLinkQuality, + nicOidCmdTimeoutCommon, 0, NULL, + pvQueryBuffer, + u4QueryBufferLen); + +#endif +} /* end of wlanoidQueryRssi() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to query the current RSSI trigger value. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvQueryBuffer Pointer to the buffer that holds the result of the + * query. + * \param[in] u4QueryBufferLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the call failed due to invalid + * length of the query buffer, returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_BUFFER_TOO_SHORT + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryRssiTrigger(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + DEBUGFUNC("wlanoidQueryRssiTrigger"); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + if (prAdapter->rWlanInfo.eRssiTriggerType == + ENUM_RSSI_TRIGGER_NONE) + return WLAN_STATUS_ADAPTER_NOT_READY; + + *pu4QueryInfoLen = sizeof(int32_t); + + /* Check for query buffer length */ + if (u4QueryBufferLen < *pu4QueryInfoLen) { + DBGLOG(REQ, WARN, "Too short length %u\n", + u4QueryBufferLen); + return WLAN_STATUS_BUFFER_TOO_SHORT; + } + + *(int32_t *) pvQueryBuffer = + prAdapter->rWlanInfo.rRssiTriggerValue; + DBGLOG(REQ, INFO, "RSSI trigger: %d dBm\n", + *(int32_t *) pvQueryBuffer); + + return WLAN_STATUS_SUCCESS; +} /* wlanoidQueryRssiTrigger */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set a trigger value of the RSSI event. + * + * \param[in] prAdapter Pointer to the Adapter structure + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns the + * amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetRssiTrigger(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + int32_t rRssiTriggerValue; + uint8_t ucBssIndex = AIS_DEFAULT_INDEX; + + DEBUGFUNC("wlanoidSetRssiTrigger"); + + ASSERT(prAdapter); + ASSERT(pvSetBuffer); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(int32_t); + rRssiTriggerValue = *(int32_t *) pvSetBuffer; + + if (rRssiTriggerValue > PARAM_WHQL_RSSI_MAX_DBM + || rRssiTriggerValue < PARAM_WHQL_RSSI_MIN_DBM) + return + /* Save the RSSI trigger value to the Adapter structure + */ + prAdapter->rWlanInfo.rRssiTriggerValue = + rRssiTriggerValue; + + /* If the RSSI trigger value is equal to the current RSSI value, the + * indication triggers immediately. We need to indicate the protocol + * that an RSSI status indication event triggers. + */ + if (rRssiTriggerValue == (int32_t) ( + prAdapter->rLinkQuality.rLq[ucBssIndex].cRssi)) { + prAdapter->rWlanInfo.eRssiTriggerType = + ENUM_RSSI_TRIGGER_TRIGGERED; + + kalIndicateStatusAndComplete(prAdapter->prGlueInfo, + WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, + (void *) &prAdapter->rWlanInfo.rRssiTriggerValue, + sizeof(int32_t), + ucBssIndex); + } else if (rRssiTriggerValue < (int32_t) ( + prAdapter->rLinkQuality.rLq[ucBssIndex].cRssi)) + prAdapter->rWlanInfo.eRssiTriggerType = + ENUM_RSSI_TRIGGER_GREATER; + else if (rRssiTriggerValue > (int32_t) ( + prAdapter->rLinkQuality.rLq[ucBssIndex].cRssi)) + prAdapter->rWlanInfo.eRssiTriggerType = + ENUM_RSSI_TRIGGER_LESS; + + return WLAN_STATUS_SUCCESS; +} /* wlanoidSetRssiTrigger */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set a suggested value for the number of + * bytes of received packet data that will be indicated to the protocol + * driver. We just accept the set and ignore this value. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetCurrentLookahead(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + DEBUGFUNC("wlanoidSetCurrentLookahead"); + + ASSERT(prAdapter); + ASSERT(pvSetBuffer); + ASSERT(pu4SetInfoLen); + + if (u4SetBufferLen < sizeof(uint32_t)) { + *pu4SetInfoLen = sizeof(uint32_t); + return WLAN_STATUS_INVALID_LENGTH; + } + + *pu4SetInfoLen = sizeof(uint32_t); + return WLAN_STATUS_SUCCESS; +} /* wlanoidSetCurrentLookahead */ + +/*----------------------------------------------------------------------------*/ +/*! \brief This routine is called to query the current 802.11 statistics. + * + * \param[in] pvAdapter Pointer to the Adapter structure + * \param[in] pvQueryBuf A pointer to the buffer that holds the result of the + * query buffer + * \param[in] u4QueryBufLen The length of the query buffer + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the call + * failed due to invalid length of the query buffer, + * returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryStatistics(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + DEBUGFUNC("wlanoidQueryStatistics"); + DBGLOG(REQ, LOUD, "\n"); + + return wlanQueryStatistics(prAdapter, pvQueryBuffer, u4QueryBufferLen, + pu4QueryInfoLen, TRUE); +} /* wlanoidQueryStatistics */ + +uint32_t +wlanoidQueryBugReport(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + DEBUGFUNC("wlanoidQueryBugReport"); + + ASSERT(prAdapter); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + ASSERT(pu4QueryInfoLen); + + *pu4QueryInfoLen = sizeof(struct EVENT_BUG_REPORT); + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(OID, WARN, + "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", + prAdapter->rAcpiState, prAdapter->fgIsRadioOff); + *pu4QueryInfoLen = sizeof(uint32_t); + return WLAN_STATUS_ADAPTER_NOT_READY; + } else if (u4QueryBufferLen < sizeof(struct + EVENT_BUG_REPORT)) { + DBGLOG(OID, WARN, "Too short length %u\n", + u4QueryBufferLen); + return WLAN_STATUS_INVALID_LENGTH; + } + + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_GET_BUG_REPORT, + FALSE, + TRUE, + TRUE, + nicCmdEventQueryBugReport, + nicOidCmdTimeoutCommon, + 0, NULL, pvQueryBuffer, u4QueryBufferLen); +} /* wlanoidQueryBugReport */ + +/*----------------------------------------------------------------------------*/ +/*! \brief This routine is called to query current media streaming status. + * + * \param[in] pvAdapter Pointer to the Adapter structure + * \param[in] pvQueryBuf A pointer to the buffer that holds the result of the + * query buffer + * \param[in] u4QueryBufLen The length of the query buffer + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the call + * failed due to invalid length of the query buffer, + * returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryMediaStreamMode(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + DEBUGFUNC("wlanoidQueryMediaStreamMode"); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + *pu4QueryInfoLen = sizeof(enum ENUM_MEDIA_STREAM_MODE); + + if (u4QueryBufferLen < *pu4QueryInfoLen) { + DBGLOG(REQ, WARN, "Invalid length %u\n", u4QueryBufferLen); + return WLAN_STATUS_INVALID_LENGTH; + } + + *(enum ENUM_MEDIA_STREAM_MODE *) pvQueryBuffer = + prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode == 0 ? + ENUM_MEDIA_STREAM_OFF : ENUM_MEDIA_STREAM_ON; + + return WLAN_STATUS_SUCCESS; + +} /* wlanoidQueryMediaStreamMode */ + +/*----------------------------------------------------------------------------*/ +/*! \brief This routine is called to enter media streaming mode or exit media + * streaming mode + * + * \param[in] pvAdapter Pointer to the Adapter structure + * \param[in] pvQueryBuf A pointer to the buffer that holds the result of the + * query buffer + * \param[in] u4QueryBufLen The length of the query buffer + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the call + * failed due to invalid length of the query buffer, + * returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetMediaStreamMode(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + enum ENUM_MEDIA_STREAM_MODE eStreamMode; + + DEBUGFUNC("wlanoidSetMediaStreamMode"); + + ASSERT(prAdapter); + ASSERT(pvSetBuffer); + ASSERT(pu4SetInfoLen); + + if (u4SetBufferLen < sizeof(enum ENUM_MEDIA_STREAM_MODE)) { + DBGLOG(REQ, WARN, "Invalid length %u\n", u4SetBufferLen); + return WLAN_STATUS_INVALID_LENGTH; + } + + *pu4SetInfoLen = sizeof(enum ENUM_MEDIA_STREAM_MODE); + + eStreamMode = *(enum ENUM_MEDIA_STREAM_MODE *) pvSetBuffer; + + if (eStreamMode == ENUM_MEDIA_STREAM_OFF) + prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode = 0; + else + prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode = 1; + + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_LINK_ATTRIB, + TRUE, + FALSE, + TRUE, + nicCmdEventSetMediaStreamMode, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_LINK_ATTRIB), + (uint8_t *) &(prAdapter->rWlanInfo.eLinkAttr), + pvSetBuffer, u4SetBufferLen); +} /* wlanoidSetMediaStreamMode */ + +/*----------------------------------------------------------------------------*/ +/*! \brief This routine is called to query the permanent MAC address of the + * NIC. + * + * \param[in] pvAdapter Pointer to the Adapter structure + * \param[in] pvQueryBuf A pointer to the buffer that holds the result of the + * query buffer + * \param[in] u4QueryBufLen The length of the query buffer + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the call + * failed due to invalid length of the query buffer, + * returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryPermanentAddr(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + DEBUGFUNC("wlanoidQueryPermanentAddr"); + DBGLOG(INIT, LOUD, "\n"); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + if (u4QueryBufferLen < MAC_ADDR_LEN) + return WLAN_STATUS_BUFFER_TOO_SHORT; + + COPY_MAC_ADDR(pvQueryBuffer, + prAdapter->rWifiVar.aucPermanentAddress); + *pu4QueryInfoLen = MAC_ADDR_LEN; + + return WLAN_STATUS_SUCCESS; +} /* wlanoidQueryPermanentAddr */ + +/*----------------------------------------------------------------------------*/ +/*! \brief This routine is called to query the MAC address the NIC is + * currently using. + * + * \param[in] pvAdapter Pointer to the Adapter structure + * \param[in] pvQueryBuf A pointer to the buffer that holds the result of the + * query buffer + * \param[in] u4QueryBufLen The length of the query buffer + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the call + * failed due to invalid length of the query buffer, + * returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_BUFFER_TOO_SHORT + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryCurrentAddr(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + DEBUGFUNC("wlanoidQueryCurrentAddr"); + DBGLOG(INIT, LOUD, "\n"); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + if (u4QueryBufferLen < MAC_ADDR_LEN) + return WLAN_STATUS_BUFFER_TOO_SHORT; + + COPY_MAC_ADDR(pvQueryBuffer, + prAdapter->rWifiVar.aucMacAddress); + *pu4QueryInfoLen = MAC_ADDR_LEN; + + return WLAN_STATUS_SUCCESS; +} /* wlanoidQueryCurrentAddr */ + +/*----------------------------------------------------------------------------*/ +/*! \brief This routine is called to query NIC link speed. + * + * \param[in] pvAdapter Pointer to the Adapter structure + * \param[in] pvQueryBuf A pointer to the buffer that holds the result of the + * query buffer + * \param[in] u4QueryBufLen The length of the query buffer + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the call + * failed due to invalid length of the query buffer, + * returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_BUFFER_TOO_SHORT + * + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryLinkSpeed(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + DEBUGFUNC("wlanoidQueryLinkSpeed"); + + return wlanQueryLinkSpeed(prAdapter, pvQueryBuffer, u4QueryBufferLen, + pu4QueryInfoLen, TRUE); +} + +uint32_t +wlanQueryLinkSpeed(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen, IN uint8_t fgIsOid) +{ + uint8_t ucBssIndex = AIS_DEFAULT_INDEX; + struct LINK_SPEED_EX_ *prLq; + + DEBUGFUNC("wlanQueryLinkSpeed"); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + if (prAdapter->fgIsEnableLpdvt) + return WLAN_STATUS_NOT_SUPPORTED; + + *pu4QueryInfoLen = sizeof(uint32_t); + + if (u4QueryBufferLen < sizeof(uint32_t)) + return WLAN_STATUS_BUFFER_TOO_SHORT; + + prLq = &prAdapter->rLinkQuality.rLq[ucBssIndex]; + if (kalGetMediaStateIndicated(prAdapter->prGlueInfo, + ucBssIndex) != + MEDIA_STATE_CONNECTED) { + return WLAN_STATUS_ADAPTER_NOT_READY; + } else if (prLq->fgIsLinkRateValid == TRUE && + (kalGetTimeTick() - prLq->rLinkRateUpdateTime) <= + CFG_LINK_QUALITY_VALID_PERIOD) { + /* change to unit of 100bps */ + *(uint32_t *) pvQueryBuffer = + prLq->u2LinkSpeed * 5000; + return WLAN_STATUS_SUCCESS; + } else { + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_GET_LINK_QUALITY, + FALSE, + TRUE, + fgIsOid, + nicCmdEventQueryLinkSpeed, + nicOidCmdTimeoutCommon, 0, NULL, + pvQueryBuffer, u4QueryBufferLen); + } +} /* end of wlanoidQueryLinkSpeed() */ + +uint32_t +wlanoidQueryLinkSpeedEx(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) +{ + uint8_t ucBssIndex = AIS_DEFAULT_INDEX; + OS_SYSTIME rUpdateDeltaTime; + struct PARAM_LINK_SPEED_EX *pu4LinkSpeed; + struct LINK_SPEED_EX_ *prLq; + DEBUGFUNC("wlanoidQueryLinkSpeedEx"); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + if (prAdapter->fgIsEnableLpdvt) + return WLAN_STATUS_NOT_SUPPORTED; + + *pu4QueryInfoLen = sizeof(struct PARAM_LINK_SPEED_EX); + + if (u4QueryBufferLen < sizeof(struct PARAM_LINK_SPEED_EX)) + return WLAN_STATUS_BUFFER_TOO_SHORT; + + ucBssIndex = GET_IOCTL_BSSIDX(prAdapter); + prLq = &prAdapter->rLinkQuality.rLq[ucBssIndex]; + rUpdateDeltaTime = kalGetTimeTick() - prLq->rLinkRateUpdateTime; + if (IS_BSS_INDEX_AIS(prAdapter, ucBssIndex) && + prLq->fgIsLinkRateValid == TRUE && + rUpdateDeltaTime <= CFG_LINK_QUALITY_VALID_PERIOD) { + pu4LinkSpeed = (struct PARAM_LINK_SPEED_EX *) (pvQueryBuffer); + pu4LinkSpeed->rLq[ucBssIndex].cRssi = prLq->cRssi; + pu4LinkSpeed->rLq[ucBssIndex].u2LinkSpeed = prLq->u2LinkSpeed; + + /* change to unit of 100bps */ + pu4LinkSpeed->rLq[ucBssIndex].u2LinkSpeed *= 5000; + return WLAN_STATUS_SUCCESS; + } else { + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_GET_LINK_QUALITY, + FALSE, + TRUE, + TRUE, + nicCmdEventQueryLinkSpeedEx, + nicOidCmdTimeoutCommon, 0, NULL, + pvQueryBuffer, u4QueryBufferLen); + } +} + +#if defined(CFG_REPORT_MAX_TX_RATE) && (CFG_REPORT_MAX_TX_RATE == 1) +uint32_t +wlanoidQueryMaxLinkSpeed(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) +{ + uint32_t u4CurRate = 0, u4MaxRate = 0; + uint32_t rv = WLAN_STATUS_FAILURE; + uint8_t ucBssIndex; + struct STA_RECORD *prStaRecOfAP; + struct BSS_INFO *prBssInfo; + struct PARAM_LINK_SPEED_EX *prLinkSpeed; + + DEBUGFUNC("wlanoidQueryMaxLinkSpeed"); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + if (prAdapter->fgIsEnableLpdvt) + return WLAN_STATUS_NOT_SUPPORTED; + + *pu4QueryInfoLen = sizeof(uint32_t); + + if (u4QueryBufferLen < sizeof(uint32_t)) + return WLAN_STATUS_BUFFER_TOO_SHORT; + + ucBssIndex = GET_IOCTL_BSSIDX(prAdapter); + prStaRecOfAP = aisGetStaRecOfAP(prAdapter, ucBssIndex); + prBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + prLinkSpeed = (struct PARAM_LINK_SPEED_EX *)pvQueryBuffer; + + if (kalGetMediaStateIndicated(prAdapter->prGlueInfo, ucBssIndex) != + MEDIA_STATE_CONNECTED || prStaRecOfAP == NULL) { + rv = WLAN_STATUS_ADAPTER_NOT_READY; + } else { + if (wlanGetMaxTxRate(prAdapter, prBssInfo, prStaRecOfAP, + &u4CurRate, &u4MaxRate) >= 0) { + u4MaxRate = u4MaxRate * 1000; + prLinkSpeed->rLq[ucBssIndex].u2LinkSpeed = u4MaxRate; + rv = WLAN_STATUS_SUCCESS; + } + } + return rv; +} +#endif /* CFG_REPORT_MAX_TX_RATE */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief extend command packet generation utility +* +* \param[in] prAdapter Pointer to the Adapter structure. +* \param[in] ucCID Command ID +* \param[in] ucExtCID Extend command ID +* \param[in] fgSetQuery Set or Query +* \param[in] fgNeedResp Need for response +* \param[in] pfCmdDoneHandler Function pointer when command is done +* \param[in] u4SetQueryInfoLen The length of the set/query buffer +* \param[in] pucInfoBuffer Pointer to set/query buffer +* +* +* \retval WLAN_STATUS_PENDING +* \retval WLAN_STATUS_FAILURE +*/ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanSendSetQueryExtCmd( + struct ADAPTER *prAdapter, + uint8_t ucCID, + uint8_t ucExtCID, + u_int8_t fgSetQuery, + u_int8_t fgNeedResp, + u_int8_t fgIsOid, + PFN_CMD_DONE_HANDLER pfCmdDoneHandler, + PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler, + uint32_t u4SetQueryInfoLen, + uint8_t *pucInfoBuffer, + void *pvSetQueryBuffer, + uint32_t u4SetQueryBufferLen) +{ + struct GLUE_INFO *prGlueInfo; + struct CMD_INFO *prCmdInfo; + uint8_t *pucCmdBuf; + struct mt66xx_chip_info *prChipInfo; + uint16_t cmd_size; + + prGlueInfo = prAdapter->prGlueInfo; + prChipInfo = prAdapter->chip_info; + cmd_size = prChipInfo->u2CmdTxHdrSize + u4SetQueryInfoLen; + prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, cmd_size); + + DEBUGFUNC("wlanSendSetQueryCmd"); + + if (!prCmdInfo) { + DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T FAILED ID[0x%x]\n", + ucCID); + return WLAN_STATUS_FAILURE; + } + + /* Setup common CMD Info Packet */ + prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; + prCmdInfo->u2InfoBufLen = cmd_size; + prCmdInfo->pfCmdDoneHandler = pfCmdDoneHandler; + prCmdInfo->pfCmdTimeoutHandler = pfCmdTimeoutHandler; + prCmdInfo->fgIsOid = fgIsOid; + prCmdInfo->ucCID = ucCID; + prCmdInfo->fgSetQuery = fgSetQuery; + prCmdInfo->fgNeedResp = fgNeedResp; + prCmdInfo->u4SetInfoLen = u4SetQueryInfoLen; + prCmdInfo->pvInformationBuffer = pvSetQueryBuffer; + prCmdInfo->u4InformationBufferLength = u4SetQueryBufferLen; + + /* Setup WIFI_CMD_T (no payload) */ + NIC_FILL_CMD_TX_HDR(prAdapter, + prCmdInfo->pucInfoBuffer, + prCmdInfo->u2InfoBufLen, + prCmdInfo->ucCID, + CMD_PACKET_TYPE_ID, + &prCmdInfo->ucCmdSeqNum, + prCmdInfo->fgSetQuery, + &pucCmdBuf, FALSE, ucExtCID, S2D_INDEX_CMD_H2N); + if (u4SetQueryInfoLen > 0 && pucInfoBuffer != NULL) + kalMemCopy(pucCmdBuf, pucInfoBuffer, u4SetQueryInfoLen); + + /* insert into prCmdQueue */ + kalEnqueueCommand(prGlueInfo, (struct QUE_ENTRY *) prCmdInfo); + + /* wakeup txServiceThread later */ + GLUE_SET_EVENT(prGlueInfo); + return WLAN_STATUS_PENDING; +} + +#if CFG_SUPPORT_QA_TOOL +#if CFG_SUPPORT_BUFFER_MODE +uint32_t +wlanoidSetEfusBufferMode(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct PARAM_CUSTOM_EFUSE_BUFFER_MODE + *prSetEfuseBufModeInfo; + struct CMD_EFUSE_BUFFER_MODE *prCmdSetEfuseBufModeInfo = + NULL; + PFN_CMD_DONE_HANDLER pfCmdDoneHandler; + uint32_t u4EfuseContentSize, u4QueryInfoLen; + u_int8_t fgSetQuery, fgNeedResp; + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + + DEBUGFUNC("wlanoidSetEfusBufferMode"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + ASSERT(pvSetBuffer); + + /* get the buffer mode info */ + prSetEfuseBufModeInfo = + (struct PARAM_CUSTOM_EFUSE_BUFFER_MODE *) pvSetBuffer; + + /* copy command header */ + prCmdSetEfuseBufModeInfo = (struct CMD_EFUSE_BUFFER_MODE *) + kalMemAlloc(sizeof(struct CMD_EFUSE_BUFFER_MODE), + VIR_MEM_TYPE); + if (prCmdSetEfuseBufModeInfo == NULL) + return WLAN_STATUS_FAILURE; + kalMemZero(prCmdSetEfuseBufModeInfo, + sizeof(struct CMD_EFUSE_BUFFER_MODE)); + prCmdSetEfuseBufModeInfo->ucSourceMode = + prSetEfuseBufModeInfo->ucSourceMode; + prCmdSetEfuseBufModeInfo->ucCount = + prSetEfuseBufModeInfo->ucCount; + prCmdSetEfuseBufModeInfo->ucCmdType = + prSetEfuseBufModeInfo->ucCmdType; + prCmdSetEfuseBufModeInfo->ucReserved = + prSetEfuseBufModeInfo->ucReserved; + + /* decide content size and SetQuery / NeedResp flag */ + if (prAdapter->fgIsSupportBufferBinSize16Byte == TRUE) { + u4EfuseContentSize = sizeof(struct BIN_CONTENT) * + EFUSE_CONTENT_SIZE; + pfCmdDoneHandler = nicCmdEventSetCommon; + fgSetQuery = TRUE; + fgNeedResp = FALSE; + } else { +#if (CFG_FW_Report_Efuse_Address == 1) + u4EfuseContentSize = (prAdapter->u4EfuseEndAddress) - + (prAdapter->u4EfuseStartAddress) + 1; +#else + u4EfuseContentSize = EFUSE_CONTENT_BUFFER_SIZE; +#endif + pfCmdDoneHandler = NULL; + fgSetQuery = FALSE; + fgNeedResp = TRUE; + } + + u4QueryInfoLen = OFFSET_OF(struct CMD_EFUSE_BUFFER_MODE, + aBinContent) + u4EfuseContentSize; + + if (u4SetBufferLen < u4QueryInfoLen) { + kalMemFree(prCmdSetEfuseBufModeInfo, VIR_MEM_TYPE, + sizeof(struct CMD_EFUSE_BUFFER_MODE)); + return WLAN_STATUS_INVALID_LENGTH; + } + + *pu4SetInfoLen = u4QueryInfoLen; + kalMemCopy(prCmdSetEfuseBufModeInfo->aBinContent, + prSetEfuseBufModeInfo->aBinContent, + u4EfuseContentSize); + + rWlanStatus = wlanSendSetQueryExtCmd(prAdapter, + CMD_ID_LAYER_0_EXT_MAGIC_NUM, + EXT_CMD_ID_EFUSE_BUFFER_MODE, + fgSetQuery, + fgNeedResp, + TRUE, + pfCmdDoneHandler, + nicOidCmdTimeoutCommon, + u4QueryInfoLen, + (uint8_t *) (prCmdSetEfuseBufModeInfo), + pvSetBuffer, u4SetBufferLen); + + kalMemFree(prCmdSetEfuseBufModeInfo, VIR_MEM_TYPE, + sizeof(struct CMD_EFUSE_BUFFER_MODE)); + + return rWlanStatus; +} + +uint32_t +wlanoidConnacSetEfusBufferMode(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct PARAM_CUSTOM_EFUSE_BUFFER_MODE_CONNAC_T + *prSetEfuseBufModeInfo; + struct CMD_EFUSE_BUFFER_MODE_CONNAC_T + *prCmdSetEfuseBufModeInfo = NULL; + uint32_t u4EfuseContentSize, u4QueryInfoLen; + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + + DEBUGFUNC("wlanoidSetEfusBufferMode"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + ASSERT(pvSetBuffer); + + DBGLOG(OID, INFO, "u4SetBufferLen = %d\n", u4SetBufferLen); + /* get the buffer mode info */ + prSetEfuseBufModeInfo = + (struct PARAM_CUSTOM_EFUSE_BUFFER_MODE_CONNAC_T *) pvSetBuffer; + + /* copy command header */ + prCmdSetEfuseBufModeInfo = (struct CMD_EFUSE_BUFFER_MODE_CONNAC_T *) + kalMemAlloc(sizeof(struct CMD_EFUSE_BUFFER_MODE_CONNAC_T), + VIR_MEM_TYPE); + if (prCmdSetEfuseBufModeInfo == NULL) + return WLAN_STATUS_FAILURE; + kalMemZero(prCmdSetEfuseBufModeInfo, + sizeof(struct CMD_EFUSE_BUFFER_MODE_CONNAC_T)); + prCmdSetEfuseBufModeInfo->ucSourceMode = + prSetEfuseBufModeInfo->ucSourceMode; + prCmdSetEfuseBufModeInfo->ucContentFormat = + prSetEfuseBufModeInfo->ucContentFormat; + prCmdSetEfuseBufModeInfo->u2Count = + prSetEfuseBufModeInfo->u2Count; + + u4EfuseContentSize = prCmdSetEfuseBufModeInfo->u2Count; + + u4QueryInfoLen = OFFSET_OF(struct + CMD_EFUSE_BUFFER_MODE_CONNAC_T, + aBinContent) + u4EfuseContentSize; + + if (u4SetBufferLen < u4QueryInfoLen) { + kalMemFree(prCmdSetEfuseBufModeInfo, VIR_MEM_TYPE, + sizeof(struct CMD_EFUSE_BUFFER_MODE_CONNAC_T)); + return WLAN_STATUS_INVALID_LENGTH; + } + + *pu4SetInfoLen = u4QueryInfoLen; + kalMemCopy(prCmdSetEfuseBufModeInfo->aBinContent, + prSetEfuseBufModeInfo->aBinContent, + u4EfuseContentSize); + + rWlanStatus = wlanSendSetQueryExtCmd(prAdapter, + CMD_ID_LAYER_0_EXT_MAGIC_NUM, + EXT_CMD_ID_EFUSE_BUFFER_MODE, + FALSE, + TRUE, + TRUE, + NULL, + nicOidCmdTimeoutCommon, + u4QueryInfoLen, + (uint8_t *) (prCmdSetEfuseBufModeInfo), + pvSetBuffer, u4SetBufferLen); + + kalMemFree(prCmdSetEfuseBufModeInfo, VIR_MEM_TYPE, + sizeof(struct CMD_EFUSE_BUFFER_MODE_CONNAC_T)); + + return rWlanStatus; +} + +/*#if (CFG_EEPROM_PAGE_ACCESS == 1)*/ +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to read efuse content. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * \param[out] pvQueryBuf A pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the call + * failed due to invalid length of the query buffer, + * returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryProcessAccessEfuseRead(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct PARAM_CUSTOM_ACCESS_EFUSE *prSetAccessEfuseInfo; + struct CMD_ACCESS_EFUSE rCmdSetAccessEfuse; + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + + DEBUGFUNC("wlanoidQueryProcessAccessEfuseRead"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(struct PARAM_CUSTOM_ACCESS_EFUSE); + + if (u4SetBufferLen < sizeof(struct + PARAM_CUSTOM_ACCESS_EFUSE)) + return WLAN_STATUS_INVALID_LENGTH; + + ASSERT(pvSetBuffer); + + prSetAccessEfuseInfo = (struct PARAM_CUSTOM_ACCESS_EFUSE *) + pvSetBuffer; + + kalMemSet(&rCmdSetAccessEfuse, 0, + sizeof(struct CMD_ACCESS_EFUSE)); + + rCmdSetAccessEfuse.u4Address = + prSetAccessEfuseInfo->u4Address; + rCmdSetAccessEfuse.u4Valid = prSetAccessEfuseInfo->u4Valid; + + + DBGLOG(INIT, INFO, + "MT6632 : wlanoidQueryProcessAccessEfuseRead, address=%d\n", + rCmdSetAccessEfuse.u4Address); + + kalMemCopy(rCmdSetAccessEfuse.aucData, + prSetAccessEfuseInfo->aucData, + sizeof(uint8_t) * 16); + + rWlanStatus = wlanSendSetQueryExtCmd(prAdapter, + CMD_ID_LAYER_0_EXT_MAGIC_NUM, + EXT_CMD_ID_EFUSE_ACCESS, + FALSE, /* Query Bit: True->write False->read */ + TRUE, + TRUE, + NULL, /* No Tx done function wait until fw ack */ + nicOidCmdTimeoutCommon, + sizeof(struct CMD_ACCESS_EFUSE), + (uint8_t *) (&rCmdSetAccessEfuse), pvSetBuffer, + u4SetBufferLen); + + return rWlanStatus; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to write efuse content. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * \param[out] pvQueryBuf A pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the call + * failed due to invalid length of the query buffer, + * returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryProcessAccessEfuseWrite(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct PARAM_CUSTOM_ACCESS_EFUSE *prSetAccessEfuseInfo; + struct CMD_ACCESS_EFUSE rCmdSetAccessEfuse; + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + + DEBUGFUNC("wlanoidQueryProcessAccessEfuseWrite"); + DBGLOG(INIT, INFO, + "MT6632 : wlanoidQueryProcessAccessEfuseWrite\n"); + + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(struct PARAM_CUSTOM_ACCESS_EFUSE); + + if (u4SetBufferLen < sizeof(struct + PARAM_CUSTOM_ACCESS_EFUSE)) + return WLAN_STATUS_INVALID_LENGTH; + + ASSERT(pvSetBuffer); + + prSetAccessEfuseInfo = (struct PARAM_CUSTOM_ACCESS_EFUSE *) + pvSetBuffer; + + kalMemSet(&rCmdSetAccessEfuse, 0, + sizeof(struct CMD_ACCESS_EFUSE)); + + rCmdSetAccessEfuse.u4Address = + prSetAccessEfuseInfo->u4Address; + rCmdSetAccessEfuse.u4Valid = prSetAccessEfuseInfo->u4Valid; + + DBGLOG(INIT, INFO, + "MT6632 : wlanoidQueryProcessAccessEfuseWrite, address=%d\n", + rCmdSetAccessEfuse.u4Address); + + + kalMemCopy(rCmdSetAccessEfuse.aucData, + prSetAccessEfuseInfo->aucData, + sizeof(uint8_t) * 16); + + rWlanStatus = wlanSendSetQueryExtCmd(prAdapter, + CMD_ID_LAYER_0_EXT_MAGIC_NUM, + EXT_CMD_ID_EFUSE_ACCESS, + TRUE, /* Query Bit: True->write False->read*/ + TRUE, + TRUE, + NULL, /* No Tx done function wait until fw ack */ + nicOidCmdTimeoutCommon, + sizeof(struct CMD_ACCESS_EFUSE), + (uint8_t *) (&rCmdSetAccessEfuse), pvSetBuffer, + u4SetBufferLen); + + return rWlanStatus; +} + + + + +uint32_t +wlanoidQueryEfuseFreeBlock(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct PARAM_CUSTOM_EFUSE_FREE_BLOCK + *prGetEfuseFreeBlockInfo; + struct CMD_EFUSE_FREE_BLOCK rCmdGetEfuseFreeBlock; + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + + DEBUGFUNC("wlanoidQueryEfuseFreeBlock"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(struct + PARAM_CUSTOM_EFUSE_FREE_BLOCK); + + if (u4SetBufferLen < sizeof(struct + PARAM_CUSTOM_EFUSE_FREE_BLOCK)) + return WLAN_STATUS_INVALID_LENGTH; + + ASSERT(pvSetBuffer); + + prGetEfuseFreeBlockInfo = (struct + PARAM_CUSTOM_EFUSE_FREE_BLOCK *) pvSetBuffer; + + kalMemSet(&rCmdGetEfuseFreeBlock, 0, + sizeof(struct CMD_EFUSE_FREE_BLOCK)); + + + rWlanStatus = wlanSendSetQueryExtCmd(prAdapter, + CMD_ID_LAYER_0_EXT_MAGIC_NUM, + EXT_CMD_ID_EFUSE_FREE_BLOCK, + FALSE, /* Query Bit: True->write False->read */ + TRUE, + TRUE, + NULL, /* No Tx done function wait until fw ack */ + nicOidCmdTimeoutCommon, + sizeof(struct CMD_EFUSE_FREE_BLOCK), + (uint8_t *) (&rCmdGetEfuseFreeBlock), pvSetBuffer, + u4SetBufferLen); + + return rWlanStatus; +} + +uint32_t +wlanoidQueryGetTxPower(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct PARAM_CUSTOM_GET_TX_POWER *prGetTxPowerInfo; + struct CMD_GET_TX_POWER rCmdGetTxPower; + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + + DEBUGFUNC("wlanoidQueryGetTxPower"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(struct PARAM_CUSTOM_GET_TX_POWER *); + + if (u4SetBufferLen < sizeof(struct PARAM_CUSTOM_GET_TX_POWER + *)) + return WLAN_STATUS_INVALID_LENGTH; + + ASSERT(pvSetBuffer); + + prGetTxPowerInfo = (struct PARAM_CUSTOM_GET_TX_POWER *) + pvSetBuffer; + + kalMemSet(&rCmdGetTxPower, 0, + sizeof(struct CMD_GET_TX_POWER)); + + rCmdGetTxPower.ucTxPwrType = EXT_EVENT_TARGET_TX_POWER; + rCmdGetTxPower.ucCenterChannel = + prGetTxPowerInfo->ucCenterChannel; + rCmdGetTxPower.ucDbdcIdx = prGetTxPowerInfo->ucDbdcIdx; + rCmdGetTxPower.ucBand = prGetTxPowerInfo->ucBand; + + + rWlanStatus = wlanSendSetQueryExtCmd(prAdapter, + CMD_ID_LAYER_0_EXT_MAGIC_NUM, + EXT_CMD_ID_GET_TX_POWER, + FALSE, /* Query Bit: True->write False->read*/ + TRUE, + TRUE, + NULL, /* No Tx done function wait until fw ack */ + nicOidCmdTimeoutCommon, + sizeof(struct CMD_GET_TX_POWER), + (uint8_t *) (&rCmdGetTxPower), + pvSetBuffer, u4SetBufferLen); + + return rWlanStatus; +} + + +/*#endif*/ + +#endif /* CFG_SUPPORT_BUFFER_MODE */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to query RX statistics. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * \param[out] pvQueryBuf A pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the call + * failed due to invalid length of the query buffer, + * returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryRxStatistics(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + struct PARAM_CUSTOM_ACCESS_RX_STAT *prRxStatistics; + struct CMD_ACCESS_RX_STAT *prCmdAccessRxStat; + struct CMD_ACCESS_RX_STAT rCmdAccessRxStat; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + /* UINT_32 u4MemSize = PARAM_MEM_DUMP_MAX_SIZE; */ + uint32_t u4SeqNum = 0; + uint32_t u4TotalNum = 0; + + prCmdAccessRxStat = &rCmdAccessRxStat; + + DEBUGFUNC("wlanoidQueryRxStatistics"); + DBGLOG(INIT, LOUD, "\n"); + + DBGLOG(INIT, ERROR, "MT6632 : wlanoidQueryRxStatistics\n"); + + prRxStatistics = (struct PARAM_CUSTOM_ACCESS_RX_STAT *) + pvQueryBuffer; + + *pu4QueryInfoLen = 8 + prRxStatistics->u4TotalNum; + + u4SeqNum = prRxStatistics->u4SeqNum; + u4TotalNum = prRxStatistics->u4TotalNum; + + do { + prCmdAccessRxStat->u4SeqNum = u4SeqNum; + prCmdAccessRxStat->u4TotalNum = u4TotalNum; + + rStatus = wlanSendSetQueryCmd(prAdapter, + CMD_ID_ACCESS_RX_STAT, + FALSE, + TRUE, + TRUE, + nicCmdEventQueryRxStatistics, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_ACCESS_RX_STAT), + (uint8_t *) prCmdAccessRxStat, pvQueryBuffer, + u4QueryBufferLen); + } while (FALSE); + + return rStatus; +} + +#if CFG_SUPPORT_TX_BF + +uint32_t +wlanoidStaRecUpdate(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct CMD_STAREC_UPDATE *prStaRecUpdateInfo; + struct STAREC_COMMON *prStaRecCmm; + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + + DEBUGFUNC("wlanoidStaRecUpdate"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(struct STAREC_COMMON); + if (u4SetBufferLen < sizeof(struct STAREC_COMMON)) + return WLAN_STATUS_INVALID_LENGTH; + + ASSERT(pvSetBuffer); + + prStaRecUpdateInfo = + (struct CMD_STAREC_UPDATE *) cnmMemAlloc(prAdapter, + RAM_TYPE_MSG, (CMD_STAREC_UPDATE_HDR_SIZE + + u4SetBufferLen)); + if (!prStaRecUpdateInfo) { + DBGLOG(INIT, ERROR, + "Allocate P_CMD_DEV_INFO_UPDATE_T ==> FAILED.\n"); + return WLAN_STATUS_FAILURE; + } + + /* fix me: configurable ucBssIndex */ + prStaRecCmm = (struct STAREC_COMMON *) pvSetBuffer; + prStaRecUpdateInfo->ucBssIndex = 0; + prStaRecUpdateInfo->ucWlanIdx = prStaRecCmm->u2Reserve1; + prStaRecUpdateInfo->u2TotalElementNum = 1; + kalMemCopy(prStaRecUpdateInfo->aucBuffer, pvSetBuffer, + u4SetBufferLen); + + rWlanStatus = wlanSendSetQueryExtCmd(prAdapter, + CMD_ID_LAYER_0_EXT_MAGIC_NUM, + EXT_CMD_ID_STAREC_UPDATE, + TRUE, + FALSE, + TRUE, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + (CMD_STAREC_UPDATE_HDR_SIZE + u4SetBufferLen), + (uint8_t *) prStaRecUpdateInfo, NULL, 0); + + cnmMemFree(prAdapter, prStaRecUpdateInfo); + + return rWlanStatus; +} + +uint32_t +wlanoidStaRecBFUpdate(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct CMD_STAREC_UPDATE *prStaRecUpdateInfo; + struct CMD_STAREC_BF *prStaRecBF; + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + + DEBUGFUNC("wlanoidStaRecBFUpdate"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(struct CMD_STAREC_BF); + if (u4SetBufferLen < sizeof(struct CMD_STAREC_BF)) + return WLAN_STATUS_INVALID_LENGTH; + + ASSERT(pvSetBuffer); + + prStaRecUpdateInfo = + (struct CMD_STAREC_UPDATE *) cnmMemAlloc(prAdapter, + RAM_TYPE_MSG, (CMD_STAREC_UPDATE_HDR_SIZE + + u4SetBufferLen)); + if (!prStaRecUpdateInfo) { + DBGLOG(INIT, ERROR, + "Allocate P_CMD_DEV_INFO_UPDATE_T ==> FAILED.\n"); + return WLAN_STATUS_FAILURE; + } + + /* fix me: configurable ucBssIndex */ + prStaRecBF = (struct CMD_STAREC_BF *) pvSetBuffer; + prStaRecUpdateInfo->ucBssIndex = prStaRecBF->ucReserved[0]; + prStaRecUpdateInfo->ucWlanIdx = prStaRecBF->ucReserved[1]; + prStaRecUpdateInfo->u2TotalElementNum = 1; + kalMemCopy(prStaRecUpdateInfo->aucBuffer, pvSetBuffer, + u4SetBufferLen); + + rWlanStatus = wlanSendSetQueryExtCmd(prAdapter, + CMD_ID_LAYER_0_EXT_MAGIC_NUM, + EXT_CMD_ID_STAREC_UPDATE, + TRUE, + FALSE, + TRUE, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + (CMD_STAREC_UPDATE_HDR_SIZE + u4SetBufferLen), + (uint8_t *) prStaRecUpdateInfo, NULL, 0); + + cnmMemFree(prAdapter, prStaRecUpdateInfo); + + return rWlanStatus; +} + +uint32_t +wlanoidBssInfoBasic(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct CMD_BSS_INFO_UPDATE *prBssInfoUpdateBasic; + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + struct BSSINFO_BASIC *prBssinfoBasic = NULL; + + DEBUGFUNC("wlanoidManualAssoc"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(struct BSSINFO_BASIC); + if (u4SetBufferLen < sizeof(struct BSSINFO_BASIC)) + return WLAN_STATUS_INVALID_LENGTH; + + ASSERT(pvSetBuffer); + + prBssInfoUpdateBasic = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, + (CMD_BSSINFO_UPDATE_HDR_SIZE + u4SetBufferLen)); + if (!prBssInfoUpdateBasic) { + DBGLOG(INIT, ERROR, + "Allocate P_CMD_DEV_INFO_UPDATE_T ==> FAILED.\n"); + return WLAN_STATUS_FAILURE; + } + + if (pvSetBuffer == NULL) { + prBssInfoUpdateBasic->ucBssIndex = 0; + DBGLOG(RFTEST, INFO, + "prBssInfoUpdateBasic->ucBssIndex=0(default)\n"); + } else { + prBssinfoBasic = + (struct BSSINFO_BASIC *)(pvSetBuffer); + prBssInfoUpdateBasic->ucBssIndex = + prBssinfoBasic->ucBcMcWlanidx; + DBGLOG(RFTEST, INFO, + "prBssInfoUpdateBasic->ucBssIndex =%d\n", + prBssInfoUpdateBasic->ucBssIndex); + } + prBssInfoUpdateBasic->u2TotalElementNum = 1; + kalMemCopy(prBssInfoUpdateBasic->aucBuffer, pvSetBuffer, + u4SetBufferLen); + + rWlanStatus = wlanSendSetQueryExtCmd(prAdapter, + CMD_ID_LAYER_0_EXT_MAGIC_NUM, + EXT_CMD_ID_BSSINFO_UPDATE, + TRUE, + FALSE, + TRUE, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + (CMD_BSSINFO_UPDATE_HDR_SIZE + u4SetBufferLen), + (uint8_t *) prBssInfoUpdateBasic, NULL, 0); + + cnmMemFree(prAdapter, prBssInfoUpdateBasic); + + return rWlanStatus; +} + +uint32_t +wlanoidDevInfoActive(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct CMD_DEV_INFO_UPDATE *prDevInfoUpdateActive; + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + struct CMD_DEVINFO_ACTIVE *prCmdDevinfoActive = NULL; + + DEBUGFUNC("wlanoidManualAssoc"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(struct CMD_DEVINFO_ACTIVE); + if (u4SetBufferLen < sizeof(struct CMD_DEVINFO_ACTIVE)) + return WLAN_STATUS_INVALID_LENGTH; + + ASSERT(pvSetBuffer); + + prDevInfoUpdateActive = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, + (CMD_DEVINFO_UPDATE_HDR_SIZE + u4SetBufferLen)); + if (!prDevInfoUpdateActive) { + DBGLOG(INIT, ERROR, + "Allocate P_CMD_DEV_INFO_UPDATE_T ==> FAILED.\n"); + return WLAN_STATUS_FAILURE; + } + + /* fix me: configurable ucOwnMacIdx */ + if (pvSetBuffer == NULL) { + prDevInfoUpdateActive->ucOwnMacIdx = 0; + DBGLOG(RFTEST, INFO, + "prDevInfoUpdateActive->ucOwnMacIdx = 0(default)\n"); + } else { + prCmdDevinfoActive = + (struct CMD_DEVINFO_ACTIVE *)pvSetBuffer; + prDevInfoUpdateActive->ucOwnMacIdx = + prCmdDevinfoActive->aucReserve[0]; + DBGLOG(RFTEST, INFO, + "prDevInfoUpdateActive->ucOwnMacIdx = %d\n", + prDevInfoUpdateActive->ucOwnMacIdx); + } + prDevInfoUpdateActive->ucAppendCmdTLV = 0; + prDevInfoUpdateActive->u2TotalElementNum = 1; + kalMemCopy(prDevInfoUpdateActive->aucBuffer, pvSetBuffer, + u4SetBufferLen); + + rWlanStatus = wlanSendSetQueryExtCmd(prAdapter, + CMD_ID_LAYER_0_EXT_MAGIC_NUM, + EXT_CMD_ID_DEVINFO_UPDATE, + TRUE, + FALSE, + TRUE, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + (CMD_DEVINFO_UPDATE_HDR_SIZE + u4SetBufferLen), + (uint8_t *) prDevInfoUpdateActive, NULL, 0); + + cnmMemFree(prAdapter, prDevInfoUpdateActive); + + return rWlanStatus; +} + +uint32_t +wlanoidManualAssoc(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct CMD_STAREC_UPDATE *prStaRecManualAssoc; + struct CMD_MANUAL_ASSOC_STRUCT *prManualAssoc; + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + + DEBUGFUNC("wlanoidManualAssoc"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(struct CMD_STAREC_UPDATE); + if (u4SetBufferLen < sizeof(struct CMD_STAREC_UPDATE)) + return WLAN_STATUS_INVALID_LENGTH; + + ASSERT(pvSetBuffer); + + prStaRecManualAssoc = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, + (CMD_STAREC_UPDATE_HDR_SIZE + u4SetBufferLen)); + if (!prStaRecManualAssoc) { + DBGLOG(INIT, ERROR, + "Allocate P_CMD_STAREC_UPDATE_T ==> FAILED.\n"); + return WLAN_STATUS_FAILURE; + } + + prManualAssoc = (struct CMD_MANUAL_ASSOC_STRUCT *) + pvSetBuffer; + prStaRecManualAssoc->ucWlanIdx = prManualAssoc->ucWtbl; + prStaRecManualAssoc->ucBssIndex = prManualAssoc->ucOwnmac; + prStaRecManualAssoc->u2TotalElementNum = 1; + kalMemCopy(prStaRecManualAssoc->aucBuffer, pvSetBuffer, + u4SetBufferLen); + + rWlanStatus = wlanSendSetQueryExtCmd(prAdapter, + CMD_ID_LAYER_0_EXT_MAGIC_NUM, + EXT_CMD_ID_STAREC_UPDATE, + TRUE, + FALSE, + TRUE, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + (CMD_STAREC_UPDATE_HDR_SIZE + u4SetBufferLen), + (uint8_t *) prStaRecManualAssoc, NULL, 0); + + cnmMemFree(prAdapter, prStaRecManualAssoc); + + return rWlanStatus; +} + +struct TXBF_CMD_DONE_HANDLER { + uint32_t u4TxBfCmdId; + void (*pFunc)(struct ADAPTER *, struct CMD_INFO *, + uint8_t *); +}; + +struct TXBF_CMD_DONE_HANDLER rTxBfCmdDoneHandler[] = { + {BF_SOUNDING_OFF, nicCmdEventSetCommon}, + {BF_SOUNDING_ON, nicCmdEventSetCommon}, + {BF_DATA_PACKET_APPLY, nicCmdEventSetCommon}, + {BF_PFMU_MEM_ALLOCATE, nicCmdEventSetCommon}, + {BF_PFMU_MEM_RELEASE, nicCmdEventSetCommon}, + {BF_PFMU_TAG_READ, nicCmdEventPfmuTagRead}, + {BF_PFMU_TAG_WRITE, nicCmdEventSetCommon}, + {BF_PROFILE_READ, nicCmdEventPfmuDataRead}, + {BF_PROFILE_WRITE, nicCmdEventSetCommon}, + {BF_PN_READ, nicCmdEventSetCommon}, + {BF_PN_WRITE, nicCmdEventSetCommon}, + {BF_PFMU_MEM_ALLOC_MAP_READ, nicCmdEventSetCommon}, +#if CFG_SUPPORT_TX_BF_FPGA + {BF_PFMU_SW_TAG_WRITE, nicCmdEventSetCommon} +#endif +}; + +uint32_t +wlanoidTxBfAction(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + union PARAM_CUSTOM_TXBF_ACTION_STRUCT *prTxBfActionInfo; + union CMD_TXBF_ACTION rCmdTxBfActionInfo; + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + u_int8_t fgSetQuery, fgNeedResp; + uint32_t u4TxBfCmdId; + uint8_t ucIdx; + + DEBUGFUNC("wlanoidTxBfAction"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(union + PARAM_CUSTOM_TXBF_ACTION_STRUCT); + + if (u4SetBufferLen < sizeof(union + PARAM_CUSTOM_TXBF_ACTION_STRUCT)) + return WLAN_STATUS_INVALID_LENGTH; + + ASSERT(pvSetBuffer); + + prTxBfActionInfo = (union PARAM_CUSTOM_TXBF_ACTION_STRUCT *) + pvSetBuffer; + + memcpy(&rCmdTxBfActionInfo, prTxBfActionInfo, + sizeof(union CMD_TXBF_ACTION)); + + u4TxBfCmdId = + rCmdTxBfActionInfo.rProfileTagRead.ucTxBfCategory; + if (TXBF_CMD_NEED_TO_RESPONSE(u4TxBfCmdId) == + 0) { /* don't need response */ + fgSetQuery = TRUE; + fgNeedResp = FALSE; + } else { + fgSetQuery = FALSE; + fgNeedResp = TRUE; + } + + for (ucIdx = 0; ucIdx < ARRAY_SIZE(rTxBfCmdDoneHandler); + ucIdx++) { + if (u4TxBfCmdId == rTxBfCmdDoneHandler[ucIdx].u4TxBfCmdId) + break; + } + + if (ucIdx == ARRAY_SIZE(rTxBfCmdDoneHandler)) { + DBGLOG(RFTEST, ERROR, + "ucIdx [%d] overrun of rTxBfCmdDoneHandler\n", ucIdx); + return WLAN_STATUS_NOT_SUPPORTED; + } + + rWlanStatus = wlanSendSetQueryExtCmd(prAdapter, + CMD_ID_LAYER_0_EXT_MAGIC_NUM, + EXT_CMD_ID_BF_ACTION, + fgSetQuery, + fgNeedResp, + TRUE, + rTxBfCmdDoneHandler[ucIdx].pFunc, + nicOidCmdTimeoutCommon, + sizeof(union CMD_TXBF_ACTION), + (uint8_t *) &rCmdTxBfActionInfo, + pvSetBuffer, + u4SetBufferLen); + + return rWlanStatus; +} + +#if CFG_SUPPORT_MU_MIMO +uint32_t +wlanoidMuMimoAction(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct PARAM_CUSTOM_MUMIMO_ACTION_STRUCT + *prMuMimoActionInfo; + union CMD_MUMIMO_ACTION rCmdMuMimoActionInfo; + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + u_int8_t fgSetQuery, fgNeedResp; + uint32_t u4MuMimoCmdId; + void (*pFunc)(struct ADAPTER *, struct CMD_INFO *, + uint8_t *); + + DEBUGFUNC("wlanoidMuMimoAction"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(struct + PARAM_CUSTOM_MUMIMO_ACTION_STRUCT); + + if (u4SetBufferLen < sizeof(struct + PARAM_CUSTOM_MUMIMO_ACTION_STRUCT)) + return WLAN_STATUS_INVALID_LENGTH; + + ASSERT(pvSetBuffer); + + prMuMimoActionInfo = (struct + PARAM_CUSTOM_MUMIMO_ACTION_STRUCT *) pvSetBuffer; + + memcpy(&rCmdMuMimoActionInfo, prMuMimoActionInfo, + sizeof(union CMD_MUMIMO_ACTION)); + + u4MuMimoCmdId = rCmdMuMimoActionInfo.ucMuMimoCategory; + if (MU_CMD_NEED_TO_RESPONSE(u4MuMimoCmdId) == 0) { + fgSetQuery = TRUE; + fgNeedResp = FALSE; + } else { + fgSetQuery = FALSE; + fgNeedResp = TRUE; + } + + pFunc = nicCmdEventSetCommon; + if (u4MuMimoCmdId == MU_HQA_GET_QD) + pFunc = nicCmdEventGetQd; + else if (u4MuMimoCmdId == MU_HQA_GET_CALC_LQ) + pFunc = nicCmdEventGetCalcLq; + else if (u4MuMimoCmdId == MU_GET_CALC_INIT_MCS) + pFunc = nicCmdEventGetCalcInitMcs; + + rWlanStatus = wlanSendSetQueryExtCmd(prAdapter, + CMD_ID_LAYER_0_EXT_MAGIC_NUM, + EXT_CMD_ID_MU_CTRL, + fgSetQuery, + fgNeedResp, + TRUE, + pFunc, + nicOidCmdTimeoutCommon, + sizeof(union CMD_MUMIMO_ACTION), + (uint8_t *) &rCmdMuMimoActionInfo, + pvSetBuffer, + u4SetBufferLen); + + return rWlanStatus; +} +#endif /* CFG_SUPPORT_MU_MIMO */ +#endif /* CFG_SUPPORT_TX_BF */ +#endif /* CFG_SUPPORT_QA_TOOL */ + +#if CFG_SUPPORT_CAL_RESULT_BACKUP_TO_HOST +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to Trigger FW Cal for Backup Cal Data to Host + * Side. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetCalBackup(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + struct PARAM_CAL_BACKUP_STRUCT_V2 *prCalBackupDataV2Info; + + DBGLOG(RFTEST, INFO, "%s\n", __func__); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(struct PARAM_CAL_BACKUP_STRUCT_V2); + + if (u4SetBufferLen < sizeof(struct + PARAM_CAL_BACKUP_STRUCT_V2)) + return WLAN_STATUS_INVALID_LENGTH; + + ASSERT(pvSetBuffer); + + prCalBackupDataV2Info = (struct PARAM_CAL_BACKUP_STRUCT_V2 + *) pvSetBuffer; + + if (prCalBackupDataV2Info->ucReason == 1 + && prCalBackupDataV2Info->ucAction == 2) { + /* Trigger All Cal Function */ + return wlanoidSendCalBackupV2Cmd(prAdapter, pvSetBuffer, + u4SetBufferLen); + } else if (prCalBackupDataV2Info->ucReason == 4 + && prCalBackupDataV2Info->ucAction == 6) { + /* For Debug Use, Tell FW Print Cal Data (Rom or Ram) */ + return wlanoidSendCalBackupV2Cmd(prAdapter, pvSetBuffer, + u4SetBufferLen); + } else if (prCalBackupDataV2Info->ucReason == 3 + && prCalBackupDataV2Info->ucAction == 5) { + /* Send Cal Data to FW */ + if (prCalBackupDataV2Info->ucRomRam == 0) + prCalBackupDataV2Info->u4RemainLength = + g_rBackupCalDataAllV2.u4ValidRomCalDataLength; + else if (prCalBackupDataV2Info->ucRomRam == 1) + prCalBackupDataV2Info->u4RemainLength = + g_rBackupCalDataAllV2.u4ValidRamCalDataLength; + + return wlanoidSendCalBackupV2Cmd(prAdapter, pvSetBuffer, + u4SetBufferLen); + } + + return rWlanStatus; +} + +uint32_t wlanoidSendCalBackupV2Cmd(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen) { + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + struct PARAM_CAL_BACKUP_STRUCT_V2 *prCalBackupDataV2Info; + struct CMD_CAL_BACKUP_STRUCT_V2 *prCmdCalBackupDataV2; + uint8_t ucReason, ucAction, ucNeedResp, ucFragNum, ucRomRam; + uint32_t u4DumpMaxSize = PARAM_CAL_DATA_DUMP_MAX_SIZE; + uint32_t u4RemainLength, u4CurrAddr, u4CurrLen; + + DBGLOG(RFTEST, INFO, "%s\n", __func__); + + prCmdCalBackupDataV2 = (struct CMD_CAL_BACKUP_STRUCT_V2 *) + kalMemAlloc(sizeof(struct CMD_CAL_BACKUP_STRUCT_V2), + VIR_MEM_TYPE); + + prCalBackupDataV2Info = (struct PARAM_CAL_BACKUP_STRUCT_V2 *) + pvQueryBuffer; + + ucReason = prCalBackupDataV2Info->ucReason; + ucAction = prCalBackupDataV2Info->ucAction; + ucNeedResp = prCalBackupDataV2Info->ucNeedResp; + ucRomRam = prCalBackupDataV2Info->ucRomRam; + + if (ucAction == 2) { + /* Trigger All Cal Function */ + prCmdCalBackupDataV2->ucReason = ucReason; + prCmdCalBackupDataV2->ucAction = ucAction; + prCmdCalBackupDataV2->ucNeedResp = ucNeedResp; + prCmdCalBackupDataV2->ucFragNum = + prCalBackupDataV2Info->ucFragNum; + prCmdCalBackupDataV2->ucRomRam = ucRomRam; + prCmdCalBackupDataV2->u4ThermalValue = + prCalBackupDataV2Info->u4ThermalValue; + prCmdCalBackupDataV2->u4Address = + prCalBackupDataV2Info->u4Address; + prCmdCalBackupDataV2->u4Length = + prCalBackupDataV2Info->u4Length; + prCmdCalBackupDataV2->u4RemainLength = + prCalBackupDataV2Info->u4RemainLength; +#if CFG_SUPPORT_CAL_RESULT_BACKUP_TO_HOST_DBGLOG + DBGLOG(RFTEST, INFO, + "=========== Driver Send Query CMD#0 or CMD#1 (Info) ===========\n"); + DBGLOG(RFTEST, INFO, "Reason = %d\n", + prCmdCalBackupDataV2->ucReason); + DBGLOG(RFTEST, INFO, "Action = %d\n", + prCmdCalBackupDataV2->ucAction); + DBGLOG(RFTEST, INFO, "NeedResp = %d\n", + prCmdCalBackupDataV2->ucNeedResp); + DBGLOG(RFTEST, INFO, "FragNum = %d\n", + prCmdCalBackupDataV2->ucFragNum); + DBGLOG(RFTEST, INFO, "RomRam = %d\n", + prCmdCalBackupDataV2->ucRomRam); + DBGLOG(RFTEST, INFO, "ThermalValue = %d\n", + prCmdCalBackupDataV2->u4ThermalValue); + DBGLOG(RFTEST, INFO, "Address = 0x%08x\n", + prCmdCalBackupDataV2->u4Address); + DBGLOG(RFTEST, INFO, "Length = %d\n", + prCmdCalBackupDataV2->u4Length); + DBGLOG(RFTEST, INFO, "RemainLength = %d\n", + prCmdCalBackupDataV2->u4RemainLength); + DBGLOG(RFTEST, INFO, + "================================================================\n"); +#endif + + rWlanStatus = wlanSendSetQueryCmd(prAdapter, + CMD_ID_CAL_BACKUP_IN_HOST_V2, + TRUE, + FALSE, + TRUE, + nicCmdEventSetCommon, + NULL, + sizeof(struct CMD_CAL_BACKUP_STRUCT_V2), + (uint8_t *) prCmdCalBackupDataV2, + pvQueryBuffer, + u4QueryBufferLen); + + kalMemFree(prCmdCalBackupDataV2, VIR_MEM_TYPE, + sizeof(struct CMD_CAL_BACKUP_STRUCT_V2)); + } else if (ucAction == 0 || ucAction == 1 + || ucAction == 6) { + /* Query CMD#0 and CMD#1. */ + /* For Thermal Value and Total Cal Data Length. */ + prCmdCalBackupDataV2->ucReason = ucReason; + prCmdCalBackupDataV2->ucAction = ucAction; + prCmdCalBackupDataV2->ucNeedResp = ucNeedResp; + prCmdCalBackupDataV2->ucFragNum = + prCalBackupDataV2Info->ucFragNum; + prCmdCalBackupDataV2->ucRomRam = ucRomRam; + prCmdCalBackupDataV2->u4ThermalValue = + prCalBackupDataV2Info->u4ThermalValue; + prCmdCalBackupDataV2->u4Address = + prCalBackupDataV2Info->u4Address; + prCmdCalBackupDataV2->u4Length = + prCalBackupDataV2Info->u4Length; + prCmdCalBackupDataV2->u4RemainLength = + prCalBackupDataV2Info->u4RemainLength; +#if CFG_SUPPORT_CAL_RESULT_BACKUP_TO_HOST_DBGLOG + DBGLOG(RFTEST, INFO, + "=========== Driver Send Query CMD#0 or CMD#1 (Info) ===========\n"); + DBGLOG(RFTEST, INFO, "Reason = %d\n", + prCmdCalBackupDataV2->ucReason); + DBGLOG(RFTEST, INFO, "Action = %d\n", + prCmdCalBackupDataV2->ucAction); + DBGLOG(RFTEST, INFO, "NeedResp = %d\n", + prCmdCalBackupDataV2->ucNeedResp); + DBGLOG(RFTEST, INFO, "FragNum = %d\n", + prCmdCalBackupDataV2->ucFragNum); + DBGLOG(RFTEST, INFO, "RomRam = %d\n", + prCmdCalBackupDataV2->ucRomRam); + DBGLOG(RFTEST, INFO, "ThermalValue = %d\n", + prCmdCalBackupDataV2->u4ThermalValue); + DBGLOG(RFTEST, INFO, "Address = 0x%08x\n", + prCmdCalBackupDataV2->u4Address); + DBGLOG(RFTEST, INFO, "Length = %d\n", + prCmdCalBackupDataV2->u4Length); + DBGLOG(RFTEST, INFO, "RemainLength = %d\n", + prCmdCalBackupDataV2->u4RemainLength); + DBGLOG(RFTEST, INFO, + "================================================================\n"); +#endif + rWlanStatus = wlanSendSetQueryCmd(prAdapter, + CMD_ID_CAL_BACKUP_IN_HOST_V2, + FALSE, + TRUE, + FALSE, + nicCmdEventQueryCalBackupV2, + NULL, + sizeof(struct CMD_CAL_BACKUP_STRUCT_V2), + (uint8_t *) prCmdCalBackupDataV2, + pvQueryBuffer, + u4QueryBufferLen); + + kalMemFree(prCmdCalBackupDataV2, VIR_MEM_TYPE, + sizeof(struct CMD_CAL_BACKUP_STRUCT_V2)); + } else if (ucAction == 4) { + /* Query All Cal Data from FW (Rom or Ram). */ + u4RemainLength = prCalBackupDataV2Info->u4RemainLength; + u4CurrAddr = prCalBackupDataV2Info->u4Address + + prCalBackupDataV2Info->u4Length; + ucFragNum = prCalBackupDataV2Info->ucFragNum + 1; + + if (u4RemainLength > u4DumpMaxSize) { + u4CurrLen = u4DumpMaxSize; + u4RemainLength -= u4DumpMaxSize; + } else { + u4CurrLen = u4RemainLength; + u4RemainLength = 0; + } + + prCmdCalBackupDataV2->ucReason = ucReason; + prCmdCalBackupDataV2->ucAction = ucAction; + prCmdCalBackupDataV2->ucNeedResp = ucNeedResp; + prCmdCalBackupDataV2->ucFragNum = ucFragNum; + prCmdCalBackupDataV2->ucRomRam = ucRomRam; + prCmdCalBackupDataV2->u4ThermalValue = + prCalBackupDataV2Info->u4ThermalValue; + prCmdCalBackupDataV2->u4Address = u4CurrAddr; + prCmdCalBackupDataV2->u4Length = u4CurrLen; + prCmdCalBackupDataV2->u4RemainLength = u4RemainLength; +#if CFG_SUPPORT_CAL_RESULT_BACKUP_TO_HOST_DBGLOG + DBGLOG(RFTEST, INFO, + "========= Driver Send Query All Cal Data from FW (Info) =========\n"); + DBGLOG(RFTEST, INFO, "Reason = %d\n", + prCmdCalBackupDataV2->ucReason); + DBGLOG(RFTEST, INFO, "Action = %d\n", + prCmdCalBackupDataV2->ucAction); + DBGLOG(RFTEST, INFO, "NeedResp = %d\n", + prCmdCalBackupDataV2->ucNeedResp); + DBGLOG(RFTEST, INFO, "FragNum = %d\n", + prCmdCalBackupDataV2->ucFragNum); + DBGLOG(RFTEST, INFO, "RomRam = %d\n", + prCmdCalBackupDataV2->ucRomRam); + DBGLOG(RFTEST, INFO, "ThermalValue = %d\n", + prCmdCalBackupDataV2->u4ThermalValue); + DBGLOG(RFTEST, INFO, "Address = 0x%08x\n", + prCmdCalBackupDataV2->u4Address); + DBGLOG(RFTEST, INFO, "Length = %d\n", + prCmdCalBackupDataV2->u4Length); + DBGLOG(RFTEST, INFO, "RemainLength = %d\n", + prCmdCalBackupDataV2->u4RemainLength); + DBGLOG(RFTEST, INFO, + "=================================================================\n"); +#endif + rWlanStatus = wlanSendSetQueryCmd(prAdapter, + CMD_ID_CAL_BACKUP_IN_HOST_V2, + FALSE, + TRUE, + FALSE, + nicCmdEventQueryCalBackupV2, + NULL, + sizeof(struct CMD_CAL_BACKUP_STRUCT_V2), + (uint8_t *) prCmdCalBackupDataV2, + pvQueryBuffer, + u4QueryBufferLen); + + kalMemFree(prCmdCalBackupDataV2, VIR_MEM_TYPE, + sizeof(struct CMD_CAL_BACKUP_STRUCT_V2)); + } else if (ucAction == 5) { + /* Send All Cal Data to FW (Rom or Ram). */ + u4RemainLength = prCalBackupDataV2Info->u4RemainLength; + u4CurrAddr = prCalBackupDataV2Info->u4Address + + prCalBackupDataV2Info->u4Length; + ucFragNum = prCalBackupDataV2Info->ucFragNum + 1; + + if (u4RemainLength > u4DumpMaxSize) { + u4CurrLen = u4DumpMaxSize; + u4RemainLength -= u4DumpMaxSize; + } else { + u4CurrLen = u4RemainLength; + u4RemainLength = 0; + } + + prCmdCalBackupDataV2->ucReason = ucReason; + prCmdCalBackupDataV2->ucAction = ucAction; + prCmdCalBackupDataV2->ucNeedResp = ucNeedResp; + prCmdCalBackupDataV2->ucFragNum = ucFragNum; + prCmdCalBackupDataV2->ucRomRam = ucRomRam; + prCmdCalBackupDataV2->u4ThermalValue = + prCalBackupDataV2Info->u4ThermalValue; + prCmdCalBackupDataV2->u4Address = u4CurrAddr; + prCmdCalBackupDataV2->u4Length = u4CurrLen; + prCmdCalBackupDataV2->u4RemainLength = u4RemainLength; +#if CFG_SUPPORT_CAL_RESULT_BACKUP_TO_HOST_DBGLOG + DBGLOG(RFTEST, INFO, + "========= Driver Send All Cal Data to FW (Info) =========\n"); + DBGLOG(RFTEST, INFO, "Reason = %d\n", + prCmdCalBackupDataV2->ucReason); + DBGLOG(RFTEST, INFO, "Action = %d\n", + prCmdCalBackupDataV2->ucAction); + DBGLOG(RFTEST, INFO, "NeedResp = %d\n", + prCmdCalBackupDataV2->ucNeedResp); + DBGLOG(RFTEST, INFO, "FragNum = %d\n", + prCmdCalBackupDataV2->ucFragNum); + DBGLOG(RFTEST, INFO, "RomRam = %d\n", + prCmdCalBackupDataV2->ucRomRam); + DBGLOG(RFTEST, INFO, "ThermalValue = %d\n", + prCmdCalBackupDataV2->u4ThermalValue); + DBGLOG(RFTEST, INFO, "Address = 0x%08x\n", + prCmdCalBackupDataV2->u4Address); + DBGLOG(RFTEST, INFO, "Length = %d\n", + prCmdCalBackupDataV2->u4Length); + DBGLOG(RFTEST, INFO, "RemainLength = %d\n", + prCmdCalBackupDataV2->u4RemainLength); +#endif + /* Copy Cal Data From Driver to FW */ + if (prCmdCalBackupDataV2->ucRomRam == 0) + kalMemCopy( + (uint8_t *)(prCmdCalBackupDataV2->au4Buffer), + (uint8_t *)(g_rBackupCalDataAllV2.au4RomCalData) + + prCmdCalBackupDataV2->u4Address, + prCmdCalBackupDataV2->u4Length); + else if (prCmdCalBackupDataV2->ucRomRam == 1) + kalMemCopy( + (uint8_t *)(prCmdCalBackupDataV2->au4Buffer), + (uint8_t *)(g_rBackupCalDataAllV2.au4RamCalData) + + prCmdCalBackupDataV2->u4Address, + prCmdCalBackupDataV2->u4Length); +#if CFG_SUPPORT_CAL_RESULT_BACKUP_TO_HOST_DBGLOG + DBGLOG(RFTEST, INFO, + "Check some of elements (0x%08x), (0x%08x), (0x%08x), (0x%08x), (0x%08x)\n", + prCmdCalBackupDataV2->au4Buffer[0], + prCmdCalBackupDataV2->au4Buffer[1], + prCmdCalBackupDataV2->au4Buffer[2], + prCmdCalBackupDataV2->au4Buffer[3], + prCmdCalBackupDataV2->au4Buffer[4]); + DBGLOG(RFTEST, INFO, + "Check some of elements (0x%08x), (0x%08x), (0x%08x), (0x%08x), (0x%08x)\n", + prCmdCalBackupDataV2->au4Buffer[( + prCmdCalBackupDataV2->u4Length + / sizeof(uint32_t)) - 5], + prCmdCalBackupDataV2->au4Buffer[( + prCmdCalBackupDataV2->u4Length + / sizeof(uint32_t)) - 4], + prCmdCalBackupDataV2->au4Buffer[( + prCmdCalBackupDataV2->u4Length + / sizeof(uint32_t)) - 3], + prCmdCalBackupDataV2->au4Buffer[( + prCmdCalBackupDataV2->u4Length + / sizeof(uint32_t)) - 2], + prCmdCalBackupDataV2->au4Buffer[( + prCmdCalBackupDataV2->u4Length + / sizeof(uint32_t)) - 1]); + + DBGLOG(RFTEST, INFO, + "=================================================================\n"); +#endif + rWlanStatus = wlanSendSetQueryCmd(prAdapter, + CMD_ID_CAL_BACKUP_IN_HOST_V2, + FALSE, + TRUE, + FALSE, + nicCmdEventQueryCalBackupV2, + NULL, + sizeof(struct CMD_CAL_BACKUP_STRUCT_V2), + (uint8_t *) prCmdCalBackupDataV2, + pvQueryBuffer, + u4QueryBufferLen); + + kalMemFree(prCmdCalBackupDataV2, VIR_MEM_TYPE, + sizeof(struct CMD_CAL_BACKUP_STRUCT_V2)); + } + + return rWlanStatus; +} + +uint32_t +wlanoidQueryCalBackupV2(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + struct PARAM_CAL_BACKUP_STRUCT_V2 *prCalBackupDataV2Info; + + DBGLOG(RFTEST, INFO, "%s\n", __func__); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + *pu4QueryInfoLen = sizeof(struct CMD_CAL_BACKUP_STRUCT_V2); + + prCalBackupDataV2Info = (struct PARAM_CAL_BACKUP_STRUCT_V2 + *) pvQueryBuffer; + + if (prCalBackupDataV2Info->ucReason == 0 + && prCalBackupDataV2Info->ucAction == 0) { + /* Get Thermal Temp from FW */ + return wlanoidSendCalBackupV2Cmd(prAdapter, pvQueryBuffer, + u4QueryBufferLen); + } else if (prCalBackupDataV2Info->ucReason == 0 + && prCalBackupDataV2Info->ucAction == 1) { + /* Get Cal Data Size from FW */ + return wlanoidSendCalBackupV2Cmd(prAdapter, pvQueryBuffer, + u4QueryBufferLen); + } else if (prCalBackupDataV2Info->ucReason == 2 + && prCalBackupDataV2Info->ucAction == 4) { + /* Get Cal Data from FW */ + if (prCalBackupDataV2Info->ucRomRam == 0) + prCalBackupDataV2Info->u4RemainLength = + g_rBackupCalDataAllV2.u4ValidRomCalDataLength; + else if (prCalBackupDataV2Info->ucRomRam == 1) + prCalBackupDataV2Info->u4RemainLength = + g_rBackupCalDataAllV2.u4ValidRamCalDataLength; + + return wlanoidSendCalBackupV2Cmd(prAdapter, pvQueryBuffer, + u4QueryBufferLen); + } else { + return rWlanStatus; + } +} +#endif + + +#if CFG_SUPPORT_SMART_GEAR +uint32_t +wlandioSetSGStatus(IN struct ADAPTER *prAdapter, + IN uint8_t ucSGEnable, + IN uint8_t ucSGSpcCmd, + IN uint8_t ucNSS) +{ + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + struct CMD_SMART_GEAR_PARAM *prCmdSGStatus; + + prCmdSGStatus = (struct CMD_SMART_GEAR_PARAM *)cnmMemAlloc(prAdapter, + RAM_TYPE_MSG, + sizeof(struct CMD_SMART_GEAR_PARAM)); + + if (!prCmdSGStatus) { + DBGLOG(SW4, ERROR, + "[SG]cnmMemAlloc for wlandioSetSGStatus failed!\n"); + return WLAN_STATUS_NOT_ACCEPTED; + } + + prCmdSGStatus->ucSGEnable = ucSGEnable; + prCmdSGStatus->ucSGSpcCmd = ucSGSpcCmd; + + prCmdSGStatus->ucSGCfg = 0xFF; + + if (ucSGSpcCmd == 0xFF) { + prCmdSGStatus->ucSGCfg = prAdapter->rWifiVar.ucSGCfg; + prCmdSGStatus->ucNSSCap = ucNSS; + prCmdSGStatus->ucSG24GFavorANT = + prAdapter->rWifiVar.ucSG24GFavorANT; + prCmdSGStatus->ucSG5GFavorANT = + prAdapter->rWifiVar.ucSG5GFavorANT; + } + + DBGLOG(SW4, INFO, + "[SG]Status[%d][%d][%d][%d][%d]\n", + prCmdSGStatus->ucSGEnable, prCmdSGStatus->ucSGSpcCmd, + prCmdSGStatus->ucNSSCap, prCmdSGStatus->ucSG24GFavorANT, + prCmdSGStatus->ucSG5GFavorANT); + + wlanSendSetQueryCmd(prAdapter, + CMD_ID_SG_PARAM, + TRUE, + FALSE, + FALSE, + NULL, + NULL, + sizeof(*prCmdSGStatus), + (uint8_t *) prCmdSGStatus, NULL, 0); + + cnmMemFree(prAdapter, prCmdSGStatus); + return rWlanStatus; + +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to query MCR value. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * \param[out] pvQueryBuf A pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the call + * failed due to invalid length of the query buffer, + * returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryMcrRead(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + struct PARAM_CUSTOM_MCR_RW_STRUCT *prMcrRdInfo; + struct CMD_ACCESS_REG rCmdAccessReg; + struct mt66xx_chip_info *prChipInfo = NULL; + + DEBUGFUNC("wlanoidQueryMcrRead"); + DBGLOG(INIT, LOUD, "\n"); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + prChipInfo = prAdapter->chip_info; + ASSERT(prChipInfo); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + *pu4QueryInfoLen = sizeof(struct + PARAM_CUSTOM_MCR_RW_STRUCT); + + if (u4QueryBufferLen < sizeof(struct + PARAM_CUSTOM_MCR_RW_STRUCT)) + return WLAN_STATUS_INVALID_LENGTH; + + prMcrRdInfo = (struct PARAM_CUSTOM_MCR_RW_STRUCT *) + pvQueryBuffer; + + /* 0x9000 - 0x9EFF reserved for FW */ +#if CFG_SUPPORT_SWCR + if ((prMcrRdInfo->u4McrOffset >> 16) == 0x9F00) { + swCrReadWriteCmd(prAdapter, SWCR_READ, + (uint16_t) (prMcrRdInfo->u4McrOffset & BITS(0, 15)), + &prMcrRdInfo->u4McrData); + return WLAN_STATUS_SUCCESS; + } +#endif /* CFG_SUPPORT_SWCR */ + + /* Check if access F/W Domain MCR (due to WiFiSYS is placed from + * 0x6000-0000 + */ + if (prMcrRdInfo->u4McrOffset & 0xFFFF0000) { + /* fill command */ + rCmdAccessReg.u4Address = prMcrRdInfo->u4McrOffset; + rCmdAccessReg.u4Data = 0; + + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_ACCESS_REG, + FALSE, + TRUE, + TRUE, + nicCmdEventQueryMcrRead, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_ACCESS_REG), + (uint8_t *) &rCmdAccessReg, + pvQueryBuffer, + u4QueryBufferLen); + } else { + if (prMcrRdInfo->u4McrOffset == 0 && + prChipInfo->asicGetChipID) { + prMcrRdInfo->u4McrData = + prChipInfo->asicGetChipID(prAdapter); + log_dbg(INIT, INFO, + "Get Chip ID [0x%08x] from FW\n", + prMcrRdInfo->u4McrData); + } else { + + HAL_MCR_RD(prAdapter, + /* address is in DWORD unit */ + (prMcrRdInfo->u4McrOffset & BITS(2, 31)), + &prMcrRdInfo->u4McrData); + + DBGLOG(INIT, TRACE, + "MCR Read: Offset = %#08x, Data = %#08x\n", + prMcrRdInfo->u4McrOffset, + prMcrRdInfo->u4McrData); + } + return WLAN_STATUS_SUCCESS; + } +} /* end of wlanoidQueryMcrRead() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to write MCR and enable specific function. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetMcrWrite(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct PARAM_CUSTOM_MCR_RW_STRUCT *prMcrWrInfo; + struct CMD_ACCESS_REG rCmdAccessReg; + +#if CFG_STRESS_TEST_SUPPORT + struct AIS_FSM_INFO *prAisFsmInfo; + struct BSS_INFO *prBssInfo = + aisGetAisBssInfo(prAdapter, AIS_DEFAULT_INDEX); + struct STA_RECORD *prStaRec = prBssInfo->prStaRecOfAP; + uint32_t u4McrOffset, u4McrData; +#endif + + DEBUGFUNC("wlanoidSetMcrWrite"); + DBGLOG(INIT, LOUD, "\n"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(struct PARAM_CUSTOM_MCR_RW_STRUCT); + + if (u4SetBufferLen < sizeof(struct + PARAM_CUSTOM_MCR_RW_STRUCT)) + return WLAN_STATUS_INVALID_LENGTH; + + ASSERT(pvSetBuffer); + + prMcrWrInfo = (struct PARAM_CUSTOM_MCR_RW_STRUCT *) + pvSetBuffer; + + /* 0x9000 - 0x9EFF reserved for FW */ + /* 0xFFFE reserved for FW */ + + /* -- Puff Stress Test Begin */ +#if CFG_STRESS_TEST_SUPPORT + + /* 0xFFFFFFFE for Control Rate */ + if (prMcrWrInfo->u4McrOffset == 0xFFFFFFFE) { + if (prMcrWrInfo->u4McrData < FIXED_RATE_NUM + && prMcrWrInfo->u4McrData > 0) + prAdapter->rWifiVar.eRateSetting = + (enum ENUM_REGISTRY_FIXED_RATE) + (prMcrWrInfo->u4McrData); + cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); + cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); + DEBUGFUNC("[Stress Test]Complete Rate is Changed...\n"); + DBGLOG(INIT, TRACE, + "[Stress Test] Rate is Changed to index %d...\n", + prAdapter->rWifiVar.eRateSetting); + } + /* 0xFFFFFFFD for Switch Channel */ + else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFFD) { + if (prMcrWrInfo->u4McrData <= 11 + && prMcrWrInfo->u4McrData >= 1) + prBssInfo->ucPrimaryChannel = prMcrWrInfo->u4McrData; + nicUpdateBss(prAdapter, prBssInfo->ucNetTypeIndex); + DBGLOG(INIT, TRACE, + "[Stress Test] Channel is switched to %d ...\n", + prBssInfo->ucPrimaryChannel); + + return WLAN_STATUS_SUCCESS; + } + /* 0xFFFFFFFFC for Control RF Band and SCO */ + else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFFC) { + /* Band */ + if (prMcrWrInfo->u4McrData & 0x80000000) { + /* prBssInfo->eBand = BAND_5G; + * prBssInfo->ucPrimaryChannel = 52; // Bond to Channel 52 + */ + } else { + prBssInfo->eBand = BAND_2G4; + prBssInfo->ucPrimaryChannel = 8; /* Bond to Channel 6 */ + } + + /* Bandwidth */ + if (prMcrWrInfo->u4McrData & 0x00010000) { + prStaRec->u2HtCapInfo |= HT_CAP_INFO_SUP_CHNL_WIDTH; + prStaRec->ucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; + + if (prMcrWrInfo->u4McrData == 0x00010002) { + prBssInfo->eBssSCO = CHNL_EXT_SCB; /* U20 */ + prBssInfo->ucPrimaryChannel += 2; + } else if (prMcrWrInfo->u4McrData == 0x00010001) { + prBssInfo->eBssSCO = CHNL_EXT_SCA; /* L20 */ + prBssInfo->ucPrimaryChannel -= 2; + } else { + prBssInfo->eBssSCO = CHNL_EXT_SCA; /* 40 */ + } + } + + rlmBssInitForAPandIbss(prAdapter, prBssInfo); + } + /* 0xFFFFFFFB for HT Capability */ + else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFFB) { + /* Enable HT Capability */ + if (prMcrWrInfo->u4McrData & 0x00000001) { + prStaRec->u2HtCapInfo |= HT_CAP_INFO_HT_GF; + DEBUGFUNC("[Stress Test]Enable HT capability...\n"); + } else { + prStaRec->u2HtCapInfo &= (~HT_CAP_INFO_HT_GF); + DEBUGFUNC("[Stress Test]Disable HT capability...\n"); + } + cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); + cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); + } + /* 0xFFFFFFFA for Enable Random Rx Reset */ + else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFFA) { + rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; + rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; + + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_RANDOM_RX_RESET_EN, + TRUE, + FALSE, + TRUE, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_ACCESS_REG), + (uint8_t *) &rCmdAccessReg, + pvSetBuffer, u4SetBufferLen); + } + /* 0xFFFFFFF9 for Disable Random Rx Reset */ + else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFF9) { + rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; + rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; + + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_RANDOM_RX_RESET_DE, + TRUE, + FALSE, + TRUE, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_ACCESS_REG), + (uint8_t *) &rCmdAccessReg, + pvSetBuffer, u4SetBufferLen); + } + /* 0xFFFFFFF8 for Enable SAPP */ + else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFF8) { + rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; + rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; + + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_SAPP_EN, + TRUE, + FALSE, + TRUE, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_ACCESS_REG), + (uint8_t *) &rCmdAccessReg, + pvSetBuffer, u4SetBufferLen); + } + /* 0xFFFFFFF7 for Disable SAPP */ + else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFF7) { + rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; + rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; + + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_SAPP_DE, + TRUE, + FALSE, + TRUE, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_ACCESS_REG), + (uint8_t *) &rCmdAccessReg, + pvSetBuffer, u4SetBufferLen); + } + + else +#endif + /* -- Puff Stress Test End */ + + /* Check if access F/W Domain MCR */ + if (prMcrWrInfo->u4McrOffset & 0xFFFF0000) { + + /* 0x9000 - 0x9EFF reserved for FW */ +#if CFG_SUPPORT_SWCR + if ((prMcrWrInfo->u4McrOffset >> 16) == 0x9F00) { + swCrReadWriteCmd(prAdapter, SWCR_WRITE, + (uint16_t)(prMcrWrInfo->u4McrOffset & + BITS(0, 15)), + &prMcrWrInfo->u4McrData); + return WLAN_STATUS_SUCCESS; + } +#endif /* CFG_SUPPORT_SWCR */ + +#if 1 + /* low power test special command */ + if (prMcrWrInfo->u4McrOffset == 0x11111110) { + uint32_t rStatus = WLAN_STATUS_SUCCESS; + /* DbgPrint("Enter test mode\n"); */ + prAdapter->fgTestMode = TRUE; + return rStatus; + } + if (prMcrWrInfo->u4McrOffset == 0x11111111) { + /* DbgPrint("nicpmSetAcpiPowerD3\n"); */ + + nicpmSetAcpiPowerD3(prAdapter); + kalDevSetPowerState(prAdapter->prGlueInfo, + (uint32_t) ParamDeviceStateD3); + return WLAN_STATUS_SUCCESS; + } + if (prMcrWrInfo->u4McrOffset == 0x11111112) { + + /* DbgPrint("LP enter sleep\n"); */ + + /* fill command */ + rCmdAccessReg.u4Address = + prMcrWrInfo->u4McrOffset; + rCmdAccessReg.u4Data = + prMcrWrInfo->u4McrData; + + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_ACCESS_REG, + TRUE, + FALSE, + TRUE, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_ACCESS_REG), + (uint8_t *) &rCmdAccessReg, + pvSetBuffer, u4SetBufferLen); + } +#endif + +#if 1 + /* low power test special command */ + if (prMcrWrInfo->u4McrOffset == 0x11111110) { + uint32_t rStatus = WLAN_STATUS_SUCCESS; + /* DbgPrint("Enter test mode\n"); */ + prAdapter->fgTestMode = TRUE; + return rStatus; + } + if (prMcrWrInfo->u4McrOffset == 0x11111111) { + /* DbgPrint("nicpmSetAcpiPowerD3\n"); */ + + nicpmSetAcpiPowerD3(prAdapter); + kalDevSetPowerState(prAdapter->prGlueInfo, + (uint32_t) ParamDeviceStateD3); + return WLAN_STATUS_SUCCESS; + } + if (prMcrWrInfo->u4McrOffset == 0x11111112) { + + /* DbgPrint("LP enter sleep\n"); */ + + /* fill command */ + rCmdAccessReg.u4Address = + prMcrWrInfo->u4McrOffset; + rCmdAccessReg.u4Data = + prMcrWrInfo->u4McrData; + + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_ACCESS_REG, + TRUE, + FALSE, + TRUE, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_ACCESS_REG), + (uint8_t *) &rCmdAccessReg, + pvSetBuffer, u4SetBufferLen); + } +#endif + +#if CFG_SUPPORT_SDIO_READ_WRITE_PATTERN + if (prMcrWrInfo->u4McrOffset == 0x22220000) { + /* read test mode */ + kalSetSdioTestPattern(prAdapter->prGlueInfo, + TRUE, TRUE); + + return WLAN_STATUS_SUCCESS; + } + + if (prMcrWrInfo->u4McrOffset == 0x22220001) { + /* write test mode */ + kalSetSdioTestPattern(prAdapter->prGlueInfo, + TRUE, FALSE); + + return WLAN_STATUS_SUCCESS; + } + + if (prMcrWrInfo->u4McrOffset == 0x22220002) { + /* leave from test mode */ + kalSetSdioTestPattern(prAdapter->prGlueInfo, + FALSE, FALSE); + + return WLAN_STATUS_SUCCESS; + } +#endif + + /* fill command */ + rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; + rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; + + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_ACCESS_REG, + TRUE, + FALSE, + TRUE, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_ACCESS_REG), + (uint8_t *) &rCmdAccessReg, + pvSetBuffer, u4SetBufferLen); + } else { + HAL_MCR_WR(prAdapter, (prMcrWrInfo->u4McrOffset & + BITS(2, 31)), /* address is in DWORD unit */ + prMcrWrInfo->u4McrData); + + DBGLOG(INIT, TRACE, + "MCR Write: Offset = %#08x, Data = %#08x\n", + prMcrWrInfo->u4McrOffset, + prMcrWrInfo->u4McrData); + + return WLAN_STATUS_SUCCESS; + } +} /* wlanoidSetMcrWrite */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to query driver MCR value. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * \param[out] pvQueryBuf A pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the call + * failed due to invalid length of the query buffer, + * returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryDrvMcrRead(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + struct PARAM_CUSTOM_MCR_RW_STRUCT *prMcrRdInfo; + /* CMD_ACCESS_REG rCmdAccessReg; */ + + DEBUGFUNC("wlanoidQueryMcrRead"); + DBGLOG(INIT, LOUD, "\n"); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + *pu4QueryInfoLen = sizeof(struct + PARAM_CUSTOM_MCR_RW_STRUCT); + + if (u4QueryBufferLen < sizeof(struct + PARAM_CUSTOM_MCR_RW_STRUCT)) + return WLAN_STATUS_INVALID_LENGTH; + + prMcrRdInfo = (struct PARAM_CUSTOM_MCR_RW_STRUCT *) + pvQueryBuffer; + + ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); + HAL_MCR_RD(prAdapter, (prMcrRdInfo->u4McrOffset & BITS(2, + 31)), &prMcrRdInfo->u4McrData); + RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); + + DBGLOG(INIT, TRACE, + "DRV MCR Read: Offset = %#08x, Data = %#08x\n", + prMcrRdInfo->u4McrOffset, prMcrRdInfo->u4McrData); + + return WLAN_STATUS_SUCCESS; + +} /* end of wlanoidQueryMcrRead() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to write MCR and enable specific function. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetDrvMcrWrite(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct PARAM_CUSTOM_MCR_RW_STRUCT *prMcrWrInfo; + /* CMD_ACCESS_REG rCmdAccessReg; */ + + DEBUGFUNC("wlanoidSetMcrWrite"); + DBGLOG(INIT, LOUD, "\n"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(struct PARAM_CUSTOM_MCR_RW_STRUCT); + + if (u4SetBufferLen < sizeof(struct + PARAM_CUSTOM_MCR_RW_STRUCT)) + return WLAN_STATUS_INVALID_LENGTH; + + ASSERT(pvSetBuffer); + + prMcrWrInfo = (struct PARAM_CUSTOM_MCR_RW_STRUCT *) + pvSetBuffer; + + ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); + HAL_MCR_WR(prAdapter, (prMcrWrInfo->u4McrOffset & BITS(2, + 31)), prMcrWrInfo->u4McrData); + + DBGLOG(INIT, TRACE, + "DRV MCR Write: Offset = %#08x, Data = %#08x\n", + prMcrWrInfo->u4McrOffset, prMcrWrInfo->u4McrData); + + return WLAN_STATUS_SUCCESS; +} /* wlanoidSetMcrWrite */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to query SW CTRL + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * \param[out] pvQueryBuf A pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the call + * failed due to invalid length of the query buffer, + * returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQuerySwCtrlRead(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + struct PARAM_CUSTOM_SW_CTRL_STRUCT *prSwCtrlInfo; + uint32_t rWlanStatus; + uint16_t u2Id, u2SubId; + uint32_t u4Data; + + struct CMD_SW_DBG_CTRL rCmdSwCtrl; + + DEBUGFUNC("wlanoidQuerySwCtrlRead"); + DBGLOG(INIT, LOUD, "\n"); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + *pu4QueryInfoLen = sizeof(struct + PARAM_CUSTOM_SW_CTRL_STRUCT); + + if (u4QueryBufferLen < sizeof(struct + PARAM_CUSTOM_SW_CTRL_STRUCT)) + return WLAN_STATUS_INVALID_LENGTH; + + prSwCtrlInfo = (struct PARAM_CUSTOM_SW_CTRL_STRUCT *) + pvQueryBuffer; + + u2Id = (uint16_t) (prSwCtrlInfo->u4Id >> 16); + u2SubId = (uint16_t) (prSwCtrlInfo->u4Id & BITS(0, 15)); + u4Data = 0; + rWlanStatus = WLAN_STATUS_SUCCESS; + + switch (u2Id) { + /* 0x9000 - 0x9EFF reserved for FW */ + /* 0xFFFE reserved for FW */ + +#if CFG_SUPPORT_SWCR + case 0x9F00: + swCrReadWriteCmd(prAdapter, SWCR_READ /* Read */, + (uint16_t) u2SubId, &u4Data); + break; +#endif /* CFG_SUPPORT_SWCR */ + + case 0xFFFF: { + u4Data = 0x5AA56620; + } + break; + + case 0xBABA: + switch ((u2SubId >> 8) & BITS(0, 7)) { + case 0x00: + /* Dump Tx resource and queue status */ + qmDumpQueueStatus(prAdapter, NULL, 0); + cnmDumpMemoryStatus(prAdapter, NULL, 0); + break; + + case 0x01: + /* Dump StaRec info by index */ + cnmDumpStaRec(prAdapter, + (uint8_t) (u2SubId & BITS(0, 7))); + break; + + case 0x02: + /* Dump BSS info by index */ + bssDumpBssInfo(prAdapter, + (uint8_t) (u2SubId & BITS(0, 7))); + break; + + case 0x03: + /*Dump BSS statistics by index */ + wlanDumpBssStatistics(prAdapter, + (uint8_t) (u2SubId & BITS(0, 7))); + break; + + case 0x04: + halDumpHifStatus(prAdapter, NULL, 0); + break; + + default: + break; + } + + u4Data = 0xBABABABA; + break; + + case 0x9000: + default: { + rCmdSwCtrl.u4Id = prSwCtrlInfo->u4Id; + rCmdSwCtrl.u4Data = 0; + rWlanStatus = wlanSendSetQueryCmd(prAdapter, + CMD_ID_SW_DBG_CTRL, + FALSE, + TRUE, + TRUE, + nicCmdEventQuerySwCtrlRead, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_SW_DBG_CTRL), + (uint8_t *) &rCmdSwCtrl, + pvQueryBuffer, u4QueryBufferLen); + return rWlanStatus; + } + } /* switch(u2Id) */ + + prSwCtrlInfo->u4Data = u4Data; + + return rWlanStatus; + +} + +/* end of wlanoidQuerySwCtrlRead() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to write SW CTRL + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetSwCtrlWrite(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct PARAM_CUSTOM_SW_CTRL_STRUCT *prSwCtrlInfo; + struct CMD_SW_DBG_CTRL rCmdSwCtrl; + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + uint16_t u2Id, u2SubId; + uint32_t u4Data; + uint8_t ucOpRxNss, ucOpTxNss; + uint8_t ucChannelWidth; + uint8_t ucBssIndex = AIS_DEFAULT_INDEX; + + DEBUGFUNC("wlanoidSetSwCtrlWrite"); + DBGLOG(INIT, LOUD, "\n"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(struct PARAM_CUSTOM_SW_CTRL_STRUCT); + + if (u4SetBufferLen < sizeof(struct + PARAM_CUSTOM_SW_CTRL_STRUCT)) + return WLAN_STATUS_INVALID_LENGTH; + + ASSERT(pvSetBuffer); + + prSwCtrlInfo = (struct PARAM_CUSTOM_SW_CTRL_STRUCT *) + pvSetBuffer; + + u2Id = (uint16_t) (prSwCtrlInfo->u4Id >> 16); + u2SubId = (uint16_t) (prSwCtrlInfo->u4Id & BITS(0, 15)); + u4Data = prSwCtrlInfo->u4Data; + + switch (u2Id) { + + /* 0x9000 - 0x9EFF reserved for FW */ + /* 0xFFFE reserved for FW */ + +#if CFG_SUPPORT_SWCR + case 0x9F00: + swCrReadWriteCmd(prAdapter, SWCR_WRITE, (uint16_t) u2SubId, + &u4Data); + break; +#endif /* CFG_SUPPORT_SWCR */ + + case 0x2222: + ucOpRxNss = (uint8_t)(u4Data & BITS(0, 3)); + ucOpTxNss = (uint8_t)((u4Data & BITS(4, 7)) >> 4); + ucChannelWidth = (uint8_t)((u4Data & BITS(8, 11)) >> 8); + ucBssIndex = (uint8_t) u2SubId; + + if ((u2SubId & BITS(8, 15)) != 0) { /* Debug OP change + * parameters + */ + DBGLOG(RLM, INFO, + "[UT_OP] BSS[%d] IsBwChange[%d] BW[%d] IsRxNssChange[%d] RxNss[%d]", + ucBssIndex, + prAdapter->aprBssInfo[ucBssIndex]-> + fgIsOpChangeChannelWidth, + prAdapter->aprBssInfo[ucBssIndex]-> + ucOpChangeChannelWidth, + prAdapter->aprBssInfo[ucBssIndex]-> + fgIsOpChangeRxNss, + prAdapter->aprBssInfo[ucBssIndex]-> + ucOpChangeRxNss + ); + DBGLOG(RLM, INFO, + " IsTxNssChange[%d] TxNss[%d]\n", + prAdapter->aprBssInfo[ucBssIndex]-> + fgIsOpChangeTxNss, + prAdapter->aprBssInfo[ucBssIndex]-> + ucOpChangeTxNss + ); + + DBGLOG(RLM, INFO, + "[UT_OP] current OP mode: w[%d] s1[%d] s2[%d] sco[%d] RxNss[%d] TxNss[%d]\n", + prAdapter->aprBssInfo[ucBssIndex]-> + ucVhtChannelWidth, + prAdapter->aprBssInfo[ucBssIndex]-> + ucVhtChannelFrequencyS1, + prAdapter->aprBssInfo[ucBssIndex]-> + ucVhtChannelFrequencyS2, + prAdapter->aprBssInfo[ucBssIndex]-> + eBssSCO, + prAdapter->aprBssInfo[ucBssIndex]-> + ucOpRxNss, + prAdapter->aprBssInfo[ucBssIndex]-> + ucOpTxNss); + } else { + /* ucChannelWidth 0:20MHz, 1:40MHz, 2:80MHz, 3:160MHz + * 4:80+80MHz + */ + DBGLOG(RLM, INFO, + "[UT_OP] Change BSS[%d] OpMode to BW[%d] RxNss[%d] TxNss[%d]\n", + ucBssIndex, ucChannelWidth, + ucOpRxNss, ucOpTxNss); + rlmChangeOperationMode( + prAdapter, ucBssIndex, ucChannelWidth, + ucOpRxNss, ucOpTxNss, + #if CFG_SUPPORT_SMART_GEAR + 0x00, + #endif + rlmDummyChangeOpHandler); + } + break; + + case 0x1000: + if (u2SubId == 0x8000) { + /* CTIA power save mode setting (code: 0x10008000) */ + prAdapter->u4CtiaPowerMode = u4Data; + prAdapter->fgEnCtiaPowerMode = TRUE; + + /* */ + { + enum PARAM_POWER_MODE ePowerMode; + + if (prAdapter->u4CtiaPowerMode == 0) + /* force to keep in CAM mode */ + ePowerMode = Param_PowerModeCAM; + else if (prAdapter->u4CtiaPowerMode == 1) + ePowerMode = Param_PowerModeMAX_PSP; + else + ePowerMode = Param_PowerModeFast_PSP; + + rWlanStatus = nicConfigPowerSaveProfile( + prAdapter, + ucBssIndex, + ePowerMode, TRUE, PS_CALLER_SW_WRITE); + } + } + break; + case 0x1001: + if (u2SubId == 0x0) + prAdapter->fgEnOnlineScan = (u_int8_t) u4Data; + else if (u2SubId == 0x1) + prAdapter->fgDisBcnLostDetection = (u_int8_t) u4Data; + else if (u2SubId == 0x2) + prAdapter->rWifiVar.ucUapsd = (u_int8_t) u4Data; + else if (u2SubId == 0x3) { + prAdapter->u4UapsdAcBmp = u4Data & BITS(0, 15); + GET_BSS_INFO_BY_INDEX(prAdapter, + u4Data >> 16)->rPmProfSetupInfo.ucBmpDeliveryAC = + (uint8_t) prAdapter->u4UapsdAcBmp; + GET_BSS_INFO_BY_INDEX(prAdapter, + u4Data >> 16)->rPmProfSetupInfo.ucBmpTriggerAC = + (uint8_t) prAdapter->u4UapsdAcBmp; + } else if (u2SubId == 0x4) + prAdapter->fgDisStaAgingTimeoutDetection = + (u_int8_t) u4Data; + else if (u2SubId == 0x5) + prAdapter->rWifiVar.uc2G4BandwidthMode = + (uint8_t) u4Data; + else if (u2SubId == 0x0100) { + if (u4Data == 2) + prAdapter->rWifiVar.ucRxGf = FEATURE_DISABLED; + else + prAdapter->rWifiVar.ucRxGf = FEATURE_ENABLED; + } else if (u2SubId == 0x0101) + prAdapter->rWifiVar.ucRxShortGI = (uint8_t) u4Data; + else if (u2SubId == 0x0103) { /* AP Mode WMMPS */ + DBGLOG(OID, INFO, + "ApUapsd 0x10010103 cmd received: %d\n", + u4Data); + setApUapsdEnable(prAdapter, (u_int8_t) u4Data); + } else if (u2SubId == 0x0110) { + prAdapter->fgIsEnableLpdvt = (u_int8_t) u4Data; + prAdapter->fgEnOnlineScan = (u_int8_t) u4Data; + DBGLOG(INIT, INFO, "--- Enable LPDVT [%d] ---\n", + prAdapter->fgIsEnableLpdvt); + } + + break; + +#if CFG_SUPPORT_SWCR + case 0x1002: +#if CFG_RX_PKTS_DUMP + if (u2SubId == 0x0) { + if (u4Data) + u4Data = BIT(HIF_RX_PKT_TYPE_MANAGEMENT); + swCrFrameCheckEnable(prAdapter, u4Data); + } +#endif + if (u2SubId == 0x1) { + u_int8_t fgIsEnable; + uint8_t ucType; + uint32_t u4Timeout; + + fgIsEnable = (u_int8_t) (u4Data & 0xff); + ucType = 0; /* ((u4Data>>4) & 0xf); */ + u4Timeout = ((u4Data >> 8) & 0xff); + swCrDebugCheckEnable(prAdapter, fgIsEnable, ucType, + u4Timeout); + } + break; +#endif + case 0x1003: /* for debug switches */ + switch (u2SubId) { + case 1: + DBGLOG(OID, INFO, + "Enable VoE 5.7 Packet Jitter test\n"); + prAdapter->rDebugInfo.fgVoE5_7Test = !!u4Data; + break; + case 0x0002: + { + struct CMD_TX_AMPDU rTxAmpdu; + uint32_t rStatus; + + rTxAmpdu.fgEnable = !!u4Data; + + rStatus = wlanSendSetQueryCmd( + prAdapter, CMD_ID_TX_AMPDU, TRUE, FALSE, FALSE, + NULL, NULL, sizeof(struct CMD_TX_AMPDU), + (uint8_t *)&rTxAmpdu, NULL, 0); + DBGLOG(OID, INFO, "disable tx ampdu status %u\n", + rStatus); + break; + } + default: + break; + } + break; + +#if CFG_SUPPORT_802_11W + case 0x2000: + DBGLOG(RSN, INFO, "802.11w test 0x%x\n", u2SubId); + if (u2SubId == 0x0) + rsnStartSaQuery(prAdapter, ucBssIndex); + if (u2SubId == 0x1) + rsnStopSaQuery(prAdapter, ucBssIndex); + if (u2SubId == 0x2) + rsnSaQueryRequest(prAdapter, NULL); + if (u2SubId == 0x3) { + struct BSS_INFO *prBssInfo = + aisGetAisBssInfo(prAdapter, ucBssIndex); + + authSendDeauthFrame(prAdapter, prBssInfo, + prBssInfo->prStaRecOfAP, NULL, 7, NULL); + } + /* wext_set_mode */ + /* + * if (u2SubId == 0x3) { + * prAdapter->prGlueInfo->rWpaInfo.u4Mfp = + * RSN_AUTH_MFP_DISABLED; + * } + * if (u2SubId == 0x4) { + * //prAdapter->rWifiVar.rAisSpecificBssInfo + * // .fgMgmtProtection = TRUE; + * prAdapter->prGlueInfo->rWpaInfo.u4Mfp = + * RSN_AUTH_MFP_OPTIONAL; + * } + * if (u2SubId == 0x5) { + * //prAdapter->rWifiVar.rAisSpecificBssInfo + * // .fgMgmtProtection = TRUE; + * prAdapter->prGlueInfo->rWpaInfo.u4Mfp = + * RSN_AUTH_MFP_REQUIRED; + * } + */ + break; +#endif + case 0xFFFF: { + /* CMD_ACCESS_REG rCmdAccessReg; */ +#if 1 /* CFG_MT6573_SMT_TEST */ + if (u2SubId == 0x0123) { + + DBGLOG(HAL, INFO, "set smt fixed rate: %u\n", u4Data); + + if ((enum ENUM_REGISTRY_FIXED_RATE) (u4Data) < + FIXED_RATE_NUM) + prAdapter->rWifiVar.eRateSetting = + (enum ENUM_REGISTRY_FIXED_RATE)(u4Data); + else + prAdapter->rWifiVar.eRateSetting = + FIXED_RATE_NONE; + + if (prAdapter->rWifiVar.eRateSetting == FIXED_RATE_NONE) + /* Enable Auto (Long/Short) Preamble */ + prAdapter->rWifiVar.ePreambleType = + PREAMBLE_TYPE_AUTO; + else if ((prAdapter->rWifiVar.eRateSetting >= + FIXED_RATE_MCS0_20M_400NS && + prAdapter->rWifiVar.eRateSetting <= + FIXED_RATE_MCS7_20M_400NS) + || (prAdapter->rWifiVar.eRateSetting >= + FIXED_RATE_MCS0_40M_400NS && + prAdapter->rWifiVar.eRateSetting <= + FIXED_RATE_MCS32_400NS)) + /* Force Short Preamble */ + prAdapter->rWifiVar.ePreambleType = + PREAMBLE_TYPE_SHORT; + else + /* Force Long Preamble */ + prAdapter->rWifiVar.ePreambleType = + PREAMBLE_TYPE_LONG; + + /* abort to re-connect */ +#if 1 + kalIndicateStatusAndComplete(prAdapter->prGlueInfo, + WLAN_STATUS_MEDIA_DISCONNECT, + NULL, 0, + ucBssIndex); +#else + aisBssBeaconTimeout(prAdapter); +#endif + + return WLAN_STATUS_SUCCESS; + + } else if (u2SubId == 0x1234) { + /* 1. Disable On-Lin Scan */ + /* 3. Disable FIFO FULL no ack */ + /* 4. Disable Roaming */ + /* Disalbe auto tx power */ + /* 2. Keep at CAM mode */ + /* 5. Disable Beacon Timeout Detection */ + rWlanStatus = nicEnterCtiaMode(prAdapter, TRUE, TRUE); + } else if (u2SubId == 0x1235) { + /* 1. Enaable On-Lin Scan */ + /* 3. Enable FIFO FULL no ack */ + /* 4. Enable Roaming */ + /* Enable auto tx power */ + /* 2. Keep at Fast PS */ + /* 5. Enable Beacon Timeout Detection */ + rWlanStatus = nicEnterCtiaMode(prAdapter, FALSE, TRUE); + } else if (u2SubId == 0x1260) { + /* Disable On-Line Scan */ + rWlanStatus = nicEnterCtiaModeOfScan(prAdapter, + TRUE, TRUE); + } else if (u2SubId == 0x1261) { + /* Enable On-Line Scan */ + rWlanStatus = nicEnterCtiaModeOfScan(prAdapter, + FALSE, TRUE); + } else if (u2SubId == 0x1262) { + /* Disable Roaming */ + rWlanStatus = nicEnterCtiaModeOfRoaming(prAdapter, + TRUE, TRUE); + } else if (u2SubId == 0x1263) { + /* Enable Roaming */ + rWlanStatus = nicEnterCtiaModeOfRoaming(prAdapter, + FALSE, TRUE); + } else if (u2SubId == 0x1264) { + /* Keep at CAM mode */ + rWlanStatus = nicEnterCtiaModeOfCAM(prAdapter, + TRUE, TRUE); + } else if (u2SubId == 0x1265) { + /* Keep at Fast PS */ + rWlanStatus = nicEnterCtiaModeOfCAM(prAdapter, + FALSE, TRUE); + } else if (u2SubId == 0x1266) { + /* Disable Beacon Timeout Detection */ + rWlanStatus = nicEnterCtiaModeOfBCNTimeout(prAdapter, + TRUE, TRUE); + } else if (u2SubId == 0x1267) { + /* Enable Beacon Timeout Detection */ + rWlanStatus = nicEnterCtiaModeOfBCNTimeout(prAdapter, + FALSE, TRUE); + } else if (u2SubId == 0x1268) { + /* Disalbe auto tx power */ + rWlanStatus = nicEnterCtiaModeOfAutoTxPower(prAdapter, + TRUE, TRUE); + } else if (u2SubId == 0x1269) { + /* Enable auto tx power */ + rWlanStatus = nicEnterCtiaModeOfAutoTxPower(prAdapter, + FALSE, TRUE); + } else if (u2SubId == 0x1270) { + /* Disalbe FIFO FULL no ack */ + rWlanStatus = nicEnterCtiaModeOfFIFOFullNoAck(prAdapter, + TRUE, TRUE); + } else if (u2SubId == 0x1271) { + /* Enable FIFO FULL no ack */ + rWlanStatus = nicEnterCtiaModeOfFIFOFullNoAck(prAdapter, + FALSE, TRUE); + } +#endif +#if CFG_MTK_STAGE_SCAN + else if (u2SubId == 0x1250) + prAdapter->aePreferBand[KAL_NETWORK_TYPE_AIS_INDEX] = + BAND_NULL; + else if (u2SubId == 0x1251) + prAdapter->aePreferBand[KAL_NETWORK_TYPE_AIS_INDEX] = + BAND_2G4; + else if (u2SubId == 0x1252) { + if (prAdapter->fgEnable5GBand) + prAdapter->aePreferBand + [KAL_NETWORK_TYPE_AIS_INDEX] = BAND_5G; + else + /* Skip this setting if 5G band is disabled */ + DBGLOG(SCN, INFO, + "Skip 5G stage scan request due to 5G is disabled\n"); + } +#endif + } + break; + + case 0x9000: + default: { + rCmdSwCtrl.u4Id = prSwCtrlInfo->u4Id; + rCmdSwCtrl.u4Data = prSwCtrlInfo->u4Data; + rWlanStatus = wlanSendSetQueryCmd(prAdapter, + CMD_ID_SW_DBG_CTRL, + TRUE, + FALSE, + TRUE, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_SW_DBG_CTRL), + (uint8_t *) &rCmdSwCtrl, + pvSetBuffer, u4SetBufferLen); + } + } /* switch(u2Id) */ + + return rWlanStatus; +} /* wlanoidSetSwCtrlWrite */ + +uint32_t +wlanoidQueryChipConfig(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + struct PARAM_CUSTOM_CHIP_CONFIG_STRUCT *prChipConfigInfo; + struct CMD_CHIP_CONFIG rCmdChipConfig; + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + + DEBUGFUNC("wlanoidQuerySwCtrlRead"); + DBGLOG(INIT, LOUD, "\n"); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + *pu4QueryInfoLen = sizeof(struct + PARAM_CUSTOM_CHIP_CONFIG_STRUCT); + + if (u4QueryBufferLen < sizeof(struct + PARAM_CUSTOM_CHIP_CONFIG_STRUCT)) + return WLAN_STATUS_INVALID_LENGTH; + + prChipConfigInfo = (struct PARAM_CUSTOM_CHIP_CONFIG_STRUCT + *) pvQueryBuffer; + kalMemZero(&rCmdChipConfig, sizeof(rCmdChipConfig)); + + rCmdChipConfig.u2Id = prChipConfigInfo->u2Id; + rCmdChipConfig.ucType = prChipConfigInfo->ucType; + rCmdChipConfig.ucRespType = prChipConfigInfo->ucRespType; + rCmdChipConfig.u2MsgSize = prChipConfigInfo->u2MsgSize; + if (rCmdChipConfig.u2MsgSize > CHIP_CONFIG_RESP_SIZE) { + DBGLOG(REQ, INFO, + "Chip config Msg Size %u is not valid (query)\n", + rCmdChipConfig.u2MsgSize); + rCmdChipConfig.u2MsgSize = CHIP_CONFIG_RESP_SIZE; + } + kalMemCopy(rCmdChipConfig.aucCmd, prChipConfigInfo->aucCmd, + rCmdChipConfig.u2MsgSize); + + rWlanStatus = wlanSendSetQueryCmd(prAdapter, + CMD_ID_CHIP_CONFIG, FALSE, TRUE, TRUE, + /*nicCmdEventQuerySwCtrlRead, */ + nicCmdEventQueryChipConfig, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_CHIP_CONFIG), + (uint8_t *) &rCmdChipConfig, + pvQueryBuffer, + u4QueryBufferLen); + + return rWlanStatus; + +} + +/* end of wlanoidQueryChipConfig() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set chip + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetChipConfig(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct PARAM_CUSTOM_CHIP_CONFIG_STRUCT *prChipConfigInfo; + struct CMD_CHIP_CONFIG rCmdChipConfig; + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + + DATA_STRUCT_INSPECTING_ASSERT( + sizeof(prChipConfigInfo->aucCmd) == CHIP_CONFIG_RESP_SIZE); + DEBUGFUNC("wlanoidSetChipConfig"); + DBGLOG(INIT, LOUD, "\n"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(struct + PARAM_CUSTOM_CHIP_CONFIG_STRUCT); + + if (u4SetBufferLen < sizeof(struct + PARAM_CUSTOM_CHIP_CONFIG_STRUCT)) + return WLAN_STATUS_INVALID_LENGTH; + + ASSERT(pvSetBuffer); + + prChipConfigInfo = (struct PARAM_CUSTOM_CHIP_CONFIG_STRUCT + *) pvSetBuffer; + kalMemZero(&rCmdChipConfig, sizeof(rCmdChipConfig)); + + rCmdChipConfig.u2Id = prChipConfigInfo->u2Id; + rCmdChipConfig.ucType = prChipConfigInfo->ucType; + rCmdChipConfig.ucRespType = prChipConfigInfo->ucRespType; + rCmdChipConfig.u2MsgSize = prChipConfigInfo->u2MsgSize; + if (rCmdChipConfig.u2MsgSize > CHIP_CONFIG_RESP_SIZE) { + DBGLOG(REQ, INFO, + "Chip config Msg Size %u is not valid (set)\n", + rCmdChipConfig.u2MsgSize); + rCmdChipConfig.u2MsgSize = CHIP_CONFIG_RESP_SIZE; + } + kalMemCopy(rCmdChipConfig.aucCmd, prChipConfigInfo->aucCmd, + rCmdChipConfig.u2MsgSize); + + rWlanStatus = wlanSendSetQueryCmd(prAdapter, + CMD_ID_CHIP_CONFIG, + TRUE, + FALSE, + TRUE, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_CHIP_CONFIG), + (uint8_t *) &rCmdChipConfig, + pvSetBuffer, u4SetBufferLen); + + return rWlanStatus; +} /* wlanoidSetChipConfig */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set cfg and callback + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetKeyCfg(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + struct PARAM_CUSTOM_KEY_CFG_STRUCT *prKeyCfgInfo; + + DEBUGFUNC("wlanoidSetKeyCfg"); + DBGLOG(INIT, LOUD, "\n"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(struct PARAM_CUSTOM_KEY_CFG_STRUCT); + + if (u4SetBufferLen < sizeof(struct + PARAM_CUSTOM_KEY_CFG_STRUCT)) + return WLAN_STATUS_INVALID_LENGTH; + + ASSERT(pvSetBuffer); + prKeyCfgInfo = (struct PARAM_CUSTOM_KEY_CFG_STRUCT *) + pvSetBuffer; + + if (kalMemCmp(prKeyCfgInfo->aucKey, "reload", 6) == 0) + wlanGetConfig(prAdapter); /* Reload config file */ + else + wlanCfgSet(prAdapter, prKeyCfgInfo->aucKey, + prKeyCfgInfo->aucValue, prKeyCfgInfo->u4Flag); + + wlanInitFeatureOption(prAdapter); + + DBGLOG(REQ, TRACE, + "StaVHT [%u], ApVHT [%u], GoVHT [%u], GcVHT [%u]\n", + prAdapter->rWifiVar.ucStaVht, + prAdapter->rWifiVar.ucApVht, + prAdapter->rWifiVar.ucP2pGoVht, + prAdapter->rWifiVar.ucP2pGcVht); + + DBGLOG(REQ, TRACE, "Nss [%u], Dbdc [%u]\n", + prAdapter->rWifiVar.ucNSS, + prAdapter->rWifiVar.eDbdcMode); + + DBGLOG(REQ, TRACE, + "TxLdpc [%u], RxLdpc [%u], StbcTx [%u], StbcRx [%u]\n", + prAdapter->rWifiVar.ucTxLdpc, + prAdapter->rWifiVar.ucRxLdpc, + prAdapter->rWifiVar.ucTxStbc, + prAdapter->rWifiVar.ucRxStbc); +#if CFG_SUPPORT_EASY_DEBUG + wlanFeatureToFw(prAdapter, prKeyCfgInfo->u4Flag); +#endif + + return rWlanStatus; +} + +/* wlanoidSetSwCtrlWrite */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to query EEPROM value. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * \param[out] pvQueryBuf A pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the call + * failed due to invalid length of the query buffer, + * returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_FAILURE + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryEepromRead(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + struct PARAM_CUSTOM_EEPROM_RW_STRUCT *prEepromRwInfo; + struct CMD_ACCESS_EEPROM rCmdAccessEeprom; + + DEBUGFUNC("wlanoidQueryEepromRead"); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + *pu4QueryInfoLen = sizeof(struct + PARAM_CUSTOM_EEPROM_RW_STRUCT); + + if (u4QueryBufferLen < sizeof(struct + PARAM_CUSTOM_EEPROM_RW_STRUCT)) + return WLAN_STATUS_INVALID_LENGTH; + + prEepromRwInfo = (struct PARAM_CUSTOM_EEPROM_RW_STRUCT *) + pvQueryBuffer; + + kalMemZero(&rCmdAccessEeprom, + sizeof(struct CMD_ACCESS_EEPROM)); + rCmdAccessEeprom.u2Offset = prEepromRwInfo->info.rEeprom.ucEepromIndex; + + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_ACCESS_EEPROM, + FALSE, + TRUE, + TRUE, + nicCmdEventQueryEepromRead, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_ACCESS_EEPROM), + (uint8_t *) &rCmdAccessEeprom, pvQueryBuffer, + u4QueryBufferLen); + +} /* wlanoidQueryEepromRead */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to write EEPROM value. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_FAILURE + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetEepromWrite(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct PARAM_CUSTOM_EEPROM_RW_STRUCT *prEepromRwInfo; + struct CMD_ACCESS_EEPROM rCmdAccessEeprom; + + DEBUGFUNC("wlanoidSetEepromWrite"); + DBGLOG(INIT, LOUD, "\n"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(struct + PARAM_CUSTOM_EEPROM_RW_STRUCT); + + if (u4SetBufferLen < sizeof(struct + PARAM_CUSTOM_EEPROM_RW_STRUCT)) + return WLAN_STATUS_INVALID_LENGTH; + + ASSERT(pvSetBuffer); + + prEepromRwInfo = (struct PARAM_CUSTOM_EEPROM_RW_STRUCT *) + pvSetBuffer; + + kalMemZero(&rCmdAccessEeprom, + sizeof(struct CMD_ACCESS_EEPROM)); + rCmdAccessEeprom.u2Offset = prEepromRwInfo->info.rEeprom.ucEepromIndex; + rCmdAccessEeprom.u2Data = prEepromRwInfo->info.rEeprom.u2EepromData; + + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_ACCESS_EEPROM, + TRUE, + FALSE, + TRUE, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_ACCESS_EEPROM), + (uint8_t *) &rCmdAccessEeprom, pvSetBuffer, + u4SetBufferLen); + +} /* wlanoidSetEepromWrite */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to query current the OID interface version, + * which is the interface between the application and driver. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvQueryBuffer Pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufferLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number + * of bytes written into the query buffer. If the + * call failed due to invalid length of the query + * buffer, returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryOidInterfaceVersion(IN struct ADAPTER * + prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + DEBUGFUNC("wlanoidQueryOidInterfaceVersion"); + + ASSERT(prAdapter); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + ASSERT(pu4QueryInfoLen); + + *(uint32_t *) pvQueryBuffer = + prAdapter->chip_info->custom_oid_interface_version; + *pu4QueryInfoLen = sizeof(uint32_t); + + DBGLOG(REQ, WARN, "Custom OID interface version: %#08X\n", + *(uint32_t *) pvQueryBuffer); + + return WLAN_STATUS_SUCCESS; +} /* wlanoidQueryOidInterfaceVersion */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to query current Multicast Address List. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvQueryBuffer Pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufferLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number + * of bytes written into the query buffer. If the + * call failed due to invalid length of the query + * buffer, returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_BUFFER_TOO_SHORT + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryMulticastList(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { +#ifndef LINUX + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_MAC_MCAST_ADDR, + FALSE, + TRUE, + TRUE, + nicCmdEventQueryMcastAddr, + nicOidCmdTimeoutCommon, 0, + NULL, pvQueryBuffer, + u4QueryBufferLen); +#else + return WLAN_STATUS_SUCCESS; +#endif +} /* end of wlanoidQueryMulticastList() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set Multicast Address List. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer Pointer to the buffer that holds the data to be + * set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + * \retval WLAN_STATUS_ADAPTER_NOT_READY + * \retval WLAN_STATUS_MULTICAST_FULL + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetMulticastList(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct CMD_MAC_MCAST_ADDR rCmdMacMcastAddr; + uint8_t ucBssIndex = 0; + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + /* The data must be a multiple of the Ethernet address size. */ + if ((u4SetBufferLen % MAC_ADDR_LEN)) { + DBGLOG(REQ, WARN, "Invalid MC list length %u\n", + u4SetBufferLen); + + *pu4SetInfoLen = (((u4SetBufferLen + MAC_ADDR_LEN) - 1) / + MAC_ADDR_LEN) * MAC_ADDR_LEN; + + return WLAN_STATUS_INVALID_LENGTH; + } + + ucBssIndex = GET_IOCTL_BSSIDX(prAdapter); + + *pu4SetInfoLen = u4SetBufferLen; + + /* Verify if we can support so many multicast addresses. */ + if (u4SetBufferLen > MAX_NUM_GROUP_ADDR * MAC_ADDR_LEN) { + DBGLOG(REQ, WARN, "Too many MC addresses\n"); + + return WLAN_STATUS_MULTICAST_FULL; + } + + /* NOTE(Kevin): Windows may set u4SetBufferLen == 0 && + * pvSetBuffer == NULL to clear exist Multicast List. + */ + if (u4SetBufferLen) + ASSERT(pvSetBuffer); + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, WARN, + "Fail in set multicast list! (Adapter not ready). ACPI=D%d, Radio=%d\n", + prAdapter->rAcpiState, prAdapter->fgIsRadioOff); + return WLAN_STATUS_ADAPTER_NOT_READY; + } + + kalMemZero(&rCmdMacMcastAddr, sizeof(rCmdMacMcastAddr)); + rCmdMacMcastAddr.u4NumOfGroupAddr = u4SetBufferLen / + MAC_ADDR_LEN; + rCmdMacMcastAddr.ucBssIndex = + ucBssIndex; + kalMemCopy(rCmdMacMcastAddr.arAddress, pvSetBuffer, + u4SetBufferLen); + DBGLOG(OID, INFO, + "MCAST white list: total=%d MAC0="MACSTR" MAC1="MACSTR + " MAC2="MACSTR" MAC3="MACSTR" MAC4="MACSTR"\n", + rCmdMacMcastAddr.u4NumOfGroupAddr, + MAC2STR(rCmdMacMcastAddr.arAddress[0]), + MAC2STR(rCmdMacMcastAddr.arAddress[1]), + MAC2STR(rCmdMacMcastAddr.arAddress[2]), + MAC2STR(rCmdMacMcastAddr.arAddress[3]), + MAC2STR(rCmdMacMcastAddr.arAddress[4])); + + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_MAC_MCAST_ADDR, + TRUE, + FALSE, + TRUE, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_MAC_MCAST_ADDR), + (uint8_t *) &rCmdMacMcastAddr, + pvSetBuffer, u4SetBufferLen); +} /* end of wlanoidSetMulticastList() */ + +uint32_t +wlanoidRssiMonitor(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + struct PARAM_RSSI_MONITOR_T rRssi; + int8_t orig_max_rssi_value; + int8_t orig_min_rssi_value; + uint32_t rStatus1 = WLAN_STATUS_SUCCESS; + uint32_t rStatus2; + uint8_t ucBssIndex = AIS_DEFAULT_INDEX; + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + *pu4QueryInfoLen = sizeof(struct PARAM_RSSI_MONITOR_T); + + /* Check for query buffer length */ + if (u4QueryBufferLen < *pu4QueryInfoLen) { + DBGLOG(OID, WARN, "Too short length %u\n", + u4QueryBufferLen); + return WLAN_STATUS_BUFFER_TOO_SHORT; + } + + kalMemZero(&rRssi, sizeof(struct PARAM_RSSI_MONITOR_T)); + + orig_max_rssi_value = rRssi.max_rssi_value; + orig_min_rssi_value = rRssi.min_rssi_value; + + kalMemCopy(&rRssi, pvQueryBuffer, + sizeof(struct PARAM_RSSI_MONITOR_T)); + + if (kalGetMediaStateIndicated(prAdapter->prGlueInfo, + ucBssIndex) == + MEDIA_STATE_DISCONNECTED) { + DBGLOG(OID, TRACE, + "Set RSSI monitor when disconnected, enable=%d\n", + rRssi.enable); + if (rRssi.enable) + return WLAN_STATUS_ADAPTER_NOT_READY; + rStatus1 = WLAN_STATUS_ADAPTER_NOT_READY; + } + + if (!rRssi.enable) { + rRssi.max_rssi_value = 0; + rRssi.min_rssi_value = 0; + } + + DBGLOG(OID, TRACE, + "enable=%d, max_rssi_value=%d, min_rssi_value=%d, orig_max_rssi_value=%d, orig_min_rssi_value=%d\n", + rRssi.enable, rRssi.max_rssi_value, rRssi.min_rssi_value, + orig_max_rssi_value, orig_min_rssi_value); + + /* + * If status == WLAN_STATUS_ADAPTER_NOT_READY + * driver needs to info FW to stop mointor but set oid flag to false + * to prevent from multiple complete + */ + rStatus2 = wlanSendSetQueryCmd(prAdapter, + CMD_ID_RSSI_MONITOR, + TRUE, + FALSE, + (rStatus1 != WLAN_STATUS_ADAPTER_NOT_READY), + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(struct PARAM_RSSI_MONITOR_T), + (uint8_t *)&rRssi, NULL, 0); + + return (rStatus1 == WLAN_STATUS_ADAPTER_NOT_READY) ? + rStatus1 : rStatus2; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set Packet Filter. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer Pointer to the buffer that holds the data to be + * set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + * \retval WLAN_STATUS_NOT_SUPPORTED + * \retval WLAN_STATUS_ADAPTER_NOT_READY + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetCurrentPacketFilter(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + uint32_t u4NewPacketFilter; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t rResult = WLAN_STATUS_FAILURE; + struct CMD_RX_PACKET_FILTER rSetRxPacketFilter; + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + if (u4SetBufferLen < sizeof(uint32_t)) { + *pu4SetInfoLen = sizeof(uint32_t); + return WLAN_STATUS_INVALID_LENGTH; + } + ASSERT(pvSetBuffer); + + /* Set the new packet filter. */ + u4NewPacketFilter = *(uint32_t *) pvSetBuffer; + + DBGLOG(REQ, TRACE, "New packet filter: %#08x\n", + u4NewPacketFilter); + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, WARN, + "Fail in set current packet filter! (Adapter not ready). ACPI=D%d, Radio=%d\n", + prAdapter->rAcpiState, prAdapter->fgIsRadioOff); + return WLAN_STATUS_ADAPTER_NOT_READY; + } + + do { + /* Verify the bits of the new packet filter. If any bits are + * set that we don't support, leave. + */ + if (u4NewPacketFilter & ~(PARAM_PACKET_FILTER_SUPPORTED)) { + rStatus = WLAN_STATUS_NOT_SUPPORTED; + DBGLOG(REQ, WARN, "some flags we don't support\n"); + break; + } +#if DBG + /* Need to enable or disable promiscuous support depending on + * the new filter. + */ + if (u4NewPacketFilter & PARAM_PACKET_FILTER_PROMISCUOUS) + DBGLOG(REQ, INFO, "Enable promiscuous mode\n"); + else + DBGLOG(REQ, INFO, "Disable promiscuous mode\n"); + + if (u4NewPacketFilter & PARAM_PACKET_FILTER_ALL_MULTICAST) + DBGLOG(REQ, INFO, "Enable all-multicast mode\n"); + else if (u4NewPacketFilter & PARAM_PACKET_FILTER_MULTICAST) + DBGLOG(REQ, INFO, "Enable multicast\n"); + else + DBGLOG(REQ, INFO, "Disable multicast\n"); + + if (u4NewPacketFilter & PARAM_PACKET_FILTER_BROADCAST) + DBGLOG(REQ, INFO, "Enable Broadcast\n"); + else + DBGLOG(REQ, INFO, "Disable Broadcast\n"); +#endif + + prAdapter->fgAllMulicastFilter = FALSE; + if (u4NewPacketFilter & PARAM_PACKET_FILTER_ALL_MULTICAST) + prAdapter->fgAllMulicastFilter = TRUE; + } while (FALSE); + + if (rStatus == WLAN_STATUS_SUCCESS) { + /* Store the packet filter */ + + prAdapter->u4OsPacketFilter &= PARAM_PACKET_FILTER_P2P_MASK; + prAdapter->u4OsPacketFilter |= u4NewPacketFilter; + + rSetRxPacketFilter.u4RxPacketFilter = + prAdapter->u4OsPacketFilter; + rResult = wlanoidSetPacketFilter(prAdapter, + &rSetRxPacketFilter, + TRUE, pvSetBuffer, + u4SetBufferLen); + DBGLOG(OID, TRACE, "[MC debug] u4OsPacketFilter=0x%x\n", + prAdapter->u4OsPacketFilter); + return rResult; + } else { + return rStatus; + } +} /* wlanoidSetCurrentPacketFilter */ + +uint32_t wlanoidSetPacketFilter(struct ADAPTER *prAdapter, + void *pvPacketFiltr, + u_int8_t fgIsOid, void *pvSetBuffer, + uint32_t u4SetBufferLen) { + struct CMD_RX_PACKET_FILTER *prSetRxPacketFilter = NULL; + + prSetRxPacketFilter = (struct CMD_RX_PACKET_FILTER *) + pvPacketFiltr; +#if CFG_SUPPORT_DROP_ALL_MC_PACKET + if (prAdapter->prGlueInfo->fgIsInSuspendMode) + prSetRxPacketFilter->u4RxPacketFilter &= + ~(PARAM_PACKET_FILTER_MULTICAST | + PARAM_PACKET_FILTER_ALL_MULTICAST); +#else + if (prAdapter->prGlueInfo->fgIsInSuspendMode) { + prSetRxPacketFilter->u4RxPacketFilter &= + ~(PARAM_PACKET_FILTER_ALL_MULTICAST); + prSetRxPacketFilter->u4RxPacketFilter |= + (PARAM_PACKET_FILTER_MULTICAST); + } +#endif + DBGLOG(OID, TRACE, + "[MC debug] u4PacketFilter=%x, IsSuspend=%d\n", + prSetRxPacketFilter->u4RxPacketFilter, + prAdapter->prGlueInfo->fgIsInSuspendMode); + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_SET_RX_FILTER, + TRUE, + FALSE, + fgIsOid, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_RX_PACKET_FILTER), + (uint8_t *)prSetRxPacketFilter, + pvSetBuffer, u4SetBufferLen); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to query current packet filter. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvQueryBuffer Pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufferLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number + * of bytes written into the query buffer. If the + * call failed due to invalid length of the query + * buffer, returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryCurrentPacketFilter(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + DEBUGFUNC("wlanoidQueryCurrentPacketFilter"); + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + + *pu4QueryInfoLen = sizeof(uint32_t); + + if (u4QueryBufferLen >= sizeof(uint32_t)) { + ASSERT(pvQueryBuffer); + *(uint32_t *) pvQueryBuffer = prAdapter->u4OsPacketFilter; + } + + return WLAN_STATUS_SUCCESS; +} /* wlanoidQueryCurrentPacketFilter */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to query ACPI device power state. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvQueryBuffer Pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufferLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number + * of bytes written into the query buffer. If the + * call failed due to invalid length of the query + * buffer, returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryAcpiDevicePowerState(IN struct ADAPTER * + prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { +#if DBG + enum PARAM_DEVICE_POWER_STATE *prPowerState; +#endif + + DEBUGFUNC("wlanoidQueryAcpiDevicePowerState"); + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + *pu4QueryInfoLen = sizeof(enum PARAM_DEVICE_POWER_STATE); + +#if DBG + prPowerState = (enum PARAM_DEVICE_POWER_STATE *) + pvQueryBuffer; + switch (*prPowerState) { + case ParamDeviceStateD0: + DBGLOG(REQ, INFO, "Query Power State: D0\n"); + break; + case ParamDeviceStateD1: + DBGLOG(REQ, INFO, "Query Power State: D1\n"); + break; + case ParamDeviceStateD2: + DBGLOG(REQ, INFO, "Query Power State: D2\n"); + break; + case ParamDeviceStateD3: + DBGLOG(REQ, INFO, "Query Power State: D3\n"); + break; + default: + break; + } +#endif + + /* Since we will disconnect the newwork, therefore we do not + * need to check queue empty + */ + *(enum PARAM_DEVICE_POWER_STATE *) pvQueryBuffer = + ParamDeviceStateD3; + /* WARNLOG(("Ready to transition to D3\n")); */ + return WLAN_STATUS_SUCCESS; + +} /* pwrmgtQueryPower */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set ACPI device power state. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetAcpiDevicePowerState(IN struct ADAPTER * + prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + enum PARAM_DEVICE_POWER_STATE *prPowerState; + u_int8_t fgRetValue = TRUE; + + DEBUGFUNC("wlanoidSetAcpiDevicePowerState"); + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(enum PARAM_DEVICE_POWER_STATE); + + ASSERT(pvSetBuffer); + prPowerState = (enum PARAM_DEVICE_POWER_STATE *) + pvSetBuffer; + switch (*prPowerState) { + case ParamDeviceStateD0: + DBGLOG(REQ, INFO, "Set Power State: D0\n"); + kalDevSetPowerState(prAdapter->prGlueInfo, + (uint32_t) ParamDeviceStateD0); + fgRetValue = nicpmSetAcpiPowerD0(prAdapter); + break; + case ParamDeviceStateD1: + DBGLOG(REQ, INFO, "Set Power State: D1\n"); + /* no break here */ + case ParamDeviceStateD2: + DBGLOG(REQ, INFO, "Set Power State: D2\n"); + /* no break here */ + case ParamDeviceStateD3: + DBGLOG(REQ, INFO, "Set Power State: D3\n"); + fgRetValue = nicpmSetAcpiPowerD3(prAdapter); + kalDevSetPowerState(prAdapter->prGlueInfo, + (uint32_t) ParamDeviceStateD3); + break; + default: + break; + } + + if (fgRetValue == TRUE) + return WLAN_STATUS_SUCCESS; + else + return WLAN_STATUS_FAILURE; +} /* end of wlanoidSetAcpiDevicePowerState() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to query the current fragmentation threshold. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * \param[out] pvQueryBuffer A pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufferLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the call + * failed due to invalid length of the query buffer, + * returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_BUFFER_TOO_SHORT + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryFragThreshold(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + DEBUGFUNC("wlanoidQueryFragThreshold"); + + ASSERT(prAdapter); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + ASSERT(pu4QueryInfoLen); + + DBGLOG(REQ, LOUD, "\n"); + +#if CFG_TX_FRAGMENT + + return WLAN_STATUS_SUCCESS; + +#else + + return WLAN_STATUS_NOT_SUPPORTED; +#endif /* CFG_TX_FRAGMENT */ + +} /* end of wlanoidQueryFragThreshold() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set a new fragmentation threshold to the + * driver. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_DATA + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetFragThreshold(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { +#if CFG_TX_FRAGMENT + return WLAN_STATUS_SUCCESS; +#else + return WLAN_STATUS_NOT_SUPPORTED; +#endif /* CFG_TX_FRAGMENT */ + +} /* end of wlanoidSetFragThreshold() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to query the current RTS threshold. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * \param[out] pvQueryBuffer A pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufferLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the call + * failed due to invalid length of the query buffer, + * returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_BUFFER_TOO_SHORT + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryRtsThreshold(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + DEBUGFUNC("wlanoidQueryRtsThreshold"); + + ASSERT(prAdapter); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + ASSERT(pu4QueryInfoLen); + + DBGLOG(REQ, LOUD, "\n"); + + if (u4QueryBufferLen < sizeof(uint32_t)) { + *pu4QueryInfoLen = sizeof(uint32_t); + return WLAN_STATUS_BUFFER_TOO_SHORT; + } + + *((uint32_t *) pvQueryBuffer) = + prAdapter->rWlanInfo.eRtsThreshold; + + return WLAN_STATUS_SUCCESS; + +} /* wlanoidQueryRtsThreshold */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set a new RTS threshold to the driver. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_DATA + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetRtsThreshold(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + uint32_t *prRtsThreshold; + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(uint32_t); + if (u4SetBufferLen < sizeof(uint32_t)) { + DBGLOG(REQ, WARN, "Invalid length %u\n", u4SetBufferLen); + return WLAN_STATUS_INVALID_LENGTH; + } + + prRtsThreshold = (uint32_t *) pvSetBuffer; + *prRtsThreshold = prAdapter->rWlanInfo.eRtsThreshold; + + return WLAN_STATUS_SUCCESS; + +} /* wlanoidSetRtsThreshold */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used to turn radio off. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_ADAPTER_NOT_READY + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetDisassociate(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct MSG_AIS_ABORT *prAisAbortMsg; + uint32_t u4DisconnectReason; + struct CONNECTION_SETTINGS *prConnSettings; + uint8_t ucBssIndex = 0; + struct AIS_FSM_INFO *prAisFsmInfo = NULL; + + DEBUGFUNC("wlanoidSetDisassociate"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + ucBssIndex = GET_IOCTL_BSSIDX(prAdapter); + + *pu4SetInfoLen = 0; + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, WARN, + "Fail in set disassociate! (Adapter not ready). ACPI=D%d, Radio=%d\n", + prAdapter->rAcpiState, prAdapter->fgIsRadioOff); + return WLAN_STATUS_ADAPTER_NOT_READY; + } + + DBGLOG(REQ, LOUD, "ucBssIndex %d\n", ucBssIndex); + + prConnSettings = + aisGetConnSettings(prAdapter, ucBssIndex); + + /* Send AIS Abort Message */ + prAisAbortMsg = (struct MSG_AIS_ABORT *) cnmMemAlloc( + prAdapter, RAM_TYPE_MSG, + sizeof(struct MSG_AIS_ABORT)); + if (!prAisAbortMsg) { + DBGLOG(REQ, ERROR, "Fail in creating AisAbortMsg.\n"); + return WLAN_STATUS_FAILURE; + } + + prAisAbortMsg->rMsgHdr.eMsgId = MID_OID_AIS_FSM_JOIN_REQ; + if (pvSetBuffer == NULL) + prAisAbortMsg->ucReasonOfDisconnect = + DISCONNECT_REASON_CODE_LOCALLY; + else { + u4DisconnectReason = *((uint32_t *)pvSetBuffer); + prAisAbortMsg->ucReasonOfDisconnect = + u4DisconnectReason; + } + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + if (prAisFsmInfo->eCurrentState == AIS_STATE_SCAN || + prAisFsmInfo->eCurrentState == AIS_STATE_ONLINE_SCAN) + prAisFsmInfo->fgIsScanOidAborted = TRUE; + + prAisAbortMsg->fgDelayIndication = FALSE; + prAisAbortMsg->ucBssIndex = ucBssIndex; + mboxSendMsg(prAdapter, MBOX_ID_0, + (struct MSG_HDR *) prAisAbortMsg, MSG_SEND_METHOD_BUF); + + /* indicate for disconnection */ + if (kalGetMediaStateIndicated(prAdapter->prGlueInfo, + ucBssIndex) == + MEDIA_STATE_CONNECTED) + kalIndicateStatusAndComplete(prAdapter->prGlueInfo, + WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY, NULL, + 0, ucBssIndex); +#if !defined(LINUX) + prAdapter->fgIsRadioOff = TRUE; +#endif + + return WLAN_STATUS_SUCCESS; +} /* wlanoidSetDisassociate */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used to query the power save profile. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[out] pvQueryBuf A pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the call + * failed due to invalid length of the query buffer, + * returns the amount of storage needed. + * + * \return WLAN_STATUS_SUCCESS + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQuery802dot11PowerSaveProfile(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + uint8_t ucBssIndex = AIS_DEFAULT_INDEX; + + DEBUGFUNC("wlanoidQuery802dot11PowerSaveProfile"); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + + if (u4QueryBufferLen != 0) { + ASSERT(pvQueryBuffer); + + /* *(PPARAM_POWER_MODE) pvQueryBuffer = (PARAM_POWER_MODE) + * (prAdapter->rWlanInfo.ePowerSaveMode.ucPsProfile); + */ + *(enum PARAM_POWER_MODE *) pvQueryBuffer = + (enum PARAM_POWER_MODE) ( + prAdapter->rWlanInfo.arPowerSaveMode[ + ucBssIndex].ucPsProfile); + *pu4QueryInfoLen = sizeof(enum PARAM_POWER_MODE); + + /* hack for CTIA power mode setting function */ + if (prAdapter->fgEnCtiaPowerMode) { + /* set to non-zero value (to prevent MMI query 0, */ + /* before it intends to set 0, which will skip its + * following state machine) + */ + *(enum PARAM_POWER_MODE *) pvQueryBuffer = + (enum PARAM_POWER_MODE) 2; + } + } + + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used to set the power save profile. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSet802dot11PowerSaveProfile(IN struct ADAPTER * + prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + uint32_t status; + struct PARAM_POWER_MODE_ *prPowerMode; + struct BSS_INFO *prBssInfo; + + const uint8_t *apucPsMode[Param_PowerModeMax] = { + (uint8_t *) "CAM", + (uint8_t *) "MAX PS", + (uint8_t *) "FAST PS" + }; + + DEBUGFUNC("wlanoidSet802dot11PowerSaveProfile"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(struct PARAM_POWER_MODE_); + prPowerMode = (struct PARAM_POWER_MODE_ *) pvSetBuffer; + + if (u4SetBufferLen < sizeof(struct PARAM_POWER_MODE_)) { + DBGLOG(REQ, WARN, + "Set power mode error: Invalid length %u\n", + u4SetBufferLen); + return WLAN_STATUS_INVALID_LENGTH; + } else if (prPowerMode->ePowerMode >= Param_PowerModeMax) { + DBGLOG(REQ, WARN, + "Set power mode error: Invalid power mode(%u)\n", + prPowerMode->ePowerMode); + return WLAN_STATUS_INVALID_DATA; + } else if (prPowerMode->ucBssIdx >= + prAdapter->ucHwBssIdNum) { + DBGLOG(REQ, WARN, + "Set power mode error: Invalid BSS index(%u)\n", + prPowerMode->ucBssIdx); + return WLAN_STATUS_INVALID_DATA; + } + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prPowerMode->ucBssIdx); + + if (prAdapter->fgEnCtiaPowerMode) { + if (prPowerMode->ePowerMode != Param_PowerModeCAM) { + /* User setting to PS mode (Param_PowerModeMAX_PSP or + * Param_PowerModeFast_PSP) + */ + + if (prAdapter->u4CtiaPowerMode == 0) + /* force to keep in CAM mode */ + prPowerMode->ePowerMode = Param_PowerModeCAM; + else if (prAdapter->u4CtiaPowerMode == 1) + prPowerMode->ePowerMode = + Param_PowerModeMAX_PSP; + else if (prAdapter->u4CtiaPowerMode == 2) + prPowerMode->ePowerMode = + Param_PowerModeFast_PSP; + } + } + + /* only CAM mode allowed when TP/Sigma on */ + if ((prAdapter->rWifiVar.ucTpTestMode == + ENUM_TP_TEST_MODE_THROUGHPUT) || + (prAdapter->rWifiVar.ucTpTestMode == + ENUM_TP_TEST_MODE_SIGMA_AC_N_PMF)) + prPowerMode->ePowerMode = Param_PowerModeCAM; + else if (prAdapter->rWifiVar.ePowerMode != + Param_PowerModeMax) + prPowerMode->ePowerMode = prAdapter->rWifiVar.ePowerMode; + + /* for WMM PS Sigma certification, keep WiFi in ps mode continuously */ + /* force PS == Param_PowerModeMAX_PSP */ + if ((prAdapter->rWifiVar.ucTpTestMode == + ENUM_TP_TEST_MODE_SIGMA_WMM_PS) && + (prPowerMode->ePowerMode >= Param_PowerModeMAX_PSP)) + prPowerMode->ePowerMode = Param_PowerModeMAX_PSP; + + status = nicConfigPowerSaveProfile(prAdapter, prPowerMode->ucBssIdx, + prPowerMode->ePowerMode, + TRUE, PS_CALLER_COMMON); + + if (prBssInfo->eNetworkType < 0 || + prBssInfo->eNetworkType >= NETWORK_TYPE_NUM) { + DBGLOG(INIT, WARN, + "Invalid eNetworkType: %d\n", + prBssInfo->eNetworkType); + } else if (prPowerMode->ePowerMode >= 0 && + prPowerMode->ePowerMode < Param_PowerModeMax) { + DBGLOG(INIT, TRACE, + "Set %s Network BSS(%u) PS mode to %s (%d)\n", + apucNetworkType[prBssInfo->eNetworkType], + prPowerMode->ucBssIdx, + apucPsMode[prPowerMode->ePowerMode], + prPowerMode->ePowerMode); + } else { + DBGLOG(INIT, TRACE, + "Invalid PS mode setting (%d) for %s Network BSS(%u)\n", + prPowerMode->ePowerMode, + apucNetworkType[prBssInfo->eNetworkType], + prPowerMode->ucBssIdx); + } + + return status; + +} /* end of wlanoidSetAcpiDevicePowerStateMode() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to query current status of AdHoc Mode. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvQueryBuffer Pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufferLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number + * of bytes written into the query buffer. If the + * call failed due to invalid length of the query + * buffer, returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_BUFFER_TOO_SHORT + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryAdHocMode(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + return WLAN_STATUS_SUCCESS; +} /* end of wlanoidQueryAdHocMode() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set AdHoc Mode. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer Pointer to the buffer that holds the data to be + * set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + * \retval WLAN_STATUS_INVALID_DATA + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetAdHocMode(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + return WLAN_STATUS_SUCCESS; +} /* end of wlanoidSetAdHocMode() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to query RF frequency. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvQueryBuffer Pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufferLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number + * of bytes written into the query buffer. If the + * call failed due to invalid length of the query + * buffer, returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_BUFFER_TOO_SHORT + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryFrequency(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + struct CONNECTION_SETTINGS *prConnSettings; + struct BSS_INFO *prAisBssInfo; + uint8_t ucBssIndex = AIS_DEFAULT_INDEX; + + DEBUGFUNC("wlanoidQueryFrequency"); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + if (u4QueryBufferLen < sizeof(uint32_t)) + return WLAN_STATUS_BUFFER_TOO_SHORT; + + prConnSettings = + aisGetConnSettings(prAdapter, ucBssIndex); + prAisBssInfo = + aisGetAisBssInfo(prAdapter, ucBssIndex); + + if (prConnSettings->eOPMode == + NET_TYPE_INFRA) { + if (kalGetMediaStateIndicated(prAdapter->prGlueInfo, + ucBssIndex) == + MEDIA_STATE_CONNECTED) + *(uint32_t *) pvQueryBuffer = nicChannelNum2Freq( + prAisBssInfo->ucPrimaryChannel); + else + *(uint32_t *) pvQueryBuffer = 0; + } else + *(uint32_t *) pvQueryBuffer = nicChannelNum2Freq( + prConnSettings->ucAdHocChannelNum); + + return WLAN_STATUS_SUCCESS; +} /* end of wlanoidQueryFrequency() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set RF frequency by User Settings. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvQueryBuffer Pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufferLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number + * of bytes written into the query buffer. If the + * call failed due to invalid length of the query + * buffer, returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + * \retval WLAN_STATUS_INVALID_DATA + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetFrequency(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct CONNECTION_SETTINGS *prConnSettings; + uint32_t *pu4FreqInKHz; + uint8_t ucBssIndex = 0; + + DEBUGFUNC("wlanoidSetFrequency"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + ucBssIndex = GET_IOCTL_BSSIDX(prAdapter); + + DBGLOG(REQ, LOUD, "ucBssIndex %d\n", ucBssIndex); + + prConnSettings = + aisGetConnSettings(prAdapter, ucBssIndex); + + *pu4SetInfoLen = sizeof(uint32_t); + + if (u4SetBufferLen < sizeof(uint32_t)) + return WLAN_STATUS_INVALID_LENGTH; + + ASSERT(pvSetBuffer); + pu4FreqInKHz = (uint32_t *) pvSetBuffer; + + prConnSettings->ucAdHocChannelNum = + (uint8_t) nicFreq2ChannelNum(*pu4FreqInKHz); + prConnSettings->eAdHocBand = *pu4FreqInKHz + < 5000000 ? BAND_2G4 : BAND_5G; + + return WLAN_STATUS_SUCCESS; +} /* end of wlanoidSetFrequency() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set 802.11 channel of the radio frequency. + * This is a proprietary function call to Lunux currently. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + * \retval WLAN_STATUS_INVALID_DATA + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetChannel(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + ASSERT(0); /* // */ + + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to query the Beacon Interval from User + * Settings. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvQueryBuffer Pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufferLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number + * of bytes written into the query buffer. If the + * call failed due to invalid length of the query + * buffer, returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_BUFFER_TOO_SHORT + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryBeaconInterval(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + struct CONNECTION_SETTINGS *prConnSettings; + struct PARAM_BSSID_EX *prCurrBssid; + uint8_t ucBssIndex = AIS_DEFAULT_INDEX; + + DEBUGFUNC("wlanoidQueryBeaconInterval"); + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + prConnSettings = + aisGetConnSettings(prAdapter, ucBssIndex); + + prCurrBssid = aisGetCurrBssId(prAdapter, + ucBssIndex); + + *pu4QueryInfoLen = sizeof(uint32_t); + + if (u4QueryBufferLen < sizeof(uint32_t)) + return WLAN_STATUS_BUFFER_TOO_SHORT; + + if (kalGetMediaStateIndicated(prAdapter->prGlueInfo, + ucBssIndex) == + MEDIA_STATE_CONNECTED) { + if (prConnSettings->eOPMode == NET_TYPE_INFRA) + *(uint32_t *) pvQueryBuffer = + prCurrBssid->rConfiguration + .u4BeaconPeriod; + else + *(uint32_t *) pvQueryBuffer = + (uint32_t)prAdapter->rWlanInfo.u2BeaconPeriod; + } else { + if (prConnSettings->eOPMode == + NET_TYPE_INFRA) + *(uint32_t *) pvQueryBuffer = 0; + else + *(uint32_t *) pvQueryBuffer = + (uint32_t)prAdapter->rWlanInfo.u2BeaconPeriod; + } + + return WLAN_STATUS_SUCCESS; +} /* end of wlanoidQueryBeaconInterval() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set the Beacon Interval to User Settings. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer Pointer to the buffer that holds the data to be + * set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + * \retval WLAN_STATUS_INVALID_DATA + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetBeaconInterval(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + uint32_t *pu4BeaconInterval; + + DEBUGFUNC("wlanoidSetBeaconInterval"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(uint32_t); + if (u4SetBufferLen < sizeof(uint32_t)) + return WLAN_STATUS_INVALID_LENGTH; + + ASSERT(pvSetBuffer); + pu4BeaconInterval = (uint32_t *) pvSetBuffer; + + if ((*pu4BeaconInterval < DOT11_BEACON_PERIOD_MIN) + || (*pu4BeaconInterval > DOT11_BEACON_PERIOD_MAX)) { + DBGLOG(REQ, TRACE, "Invalid Beacon Interval = %u\n", + *pu4BeaconInterval); + return WLAN_STATUS_INVALID_DATA; + } + + prAdapter->rWlanInfo.u2BeaconPeriod = (uint16_t) * + pu4BeaconInterval; + + DBGLOG(REQ, INFO, "Set beacon interval: %d\n", + prAdapter->rWlanInfo.u2BeaconPeriod); + + return WLAN_STATUS_SUCCESS; +} /* end of wlanoidSetBeaconInterval() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to query the ATIM window from User Settings. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvQueryBuffer Pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufferLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number + * of bytes written into the query buffer. If the + * call failed due to invalid length of the query + * buffer, returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_BUFFER_TOO_SHORT + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryAtimWindow(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + struct CONNECTION_SETTINGS *prConnSettings; + uint8_t ucBssIndex = AIS_DEFAULT_INDEX; + + DEBUGFUNC("wlanoidQueryAtimWindow"); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + prConnSettings = + aisGetConnSettings(prAdapter, ucBssIndex); + + *pu4QueryInfoLen = sizeof(uint32_t); + + if (u4QueryBufferLen < sizeof(uint32_t)) + return WLAN_STATUS_BUFFER_TOO_SHORT; + + if (prConnSettings->eOPMode == NET_TYPE_INFRA) + *(uint32_t *) pvQueryBuffer = 0; + else + *(uint32_t *) pvQueryBuffer = (uint32_t) + prAdapter->rWlanInfo.u2AtimWindow; + + return WLAN_STATUS_SUCCESS; + +} /* end of wlanoidQueryAtimWindow() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set the ATIM window to User Settings. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer Pointer to the buffer that holds the data to be + * set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + * \retval WLAN_STATUS_INVALID_DATA + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetAtimWindow(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + uint32_t *pu4AtimWindow; + + DEBUGFUNC("wlanoidSetAtimWindow"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(uint32_t); + + if (u4SetBufferLen < sizeof(uint32_t)) + return WLAN_STATUS_INVALID_LENGTH; + + ASSERT(pvSetBuffer); + pu4AtimWindow = (uint32_t *) pvSetBuffer; + + prAdapter->rWlanInfo.u2AtimWindow = (uint16_t) * + pu4AtimWindow; + + return WLAN_STATUS_SUCCESS; +} /* end of wlanoidSetAtimWindow() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to Set the MAC address which is currently used + * by the NIC. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer Pointer to the buffer that holds the data to be + * set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + * \retval WLAN_STATUS_INVALID_DATA + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetCurrentAddr(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + ASSERT(0); /* // */ + + return WLAN_STATUS_SUCCESS; +} /* end of wlanoidSetCurrentAddr() */ + +#if CFG_TCP_IP_CHKSUM_OFFLOAD +/*----------------------------------------------------------------------------*/ +/*! + * \brief Setting the checksum offload function. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer Pointer to the buffer that holds the data to be + * set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + * \retval WLAN_STATUS_ADAPTER_NOT_READY + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetCSUMOffload(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + uint32_t u4CSUMFlags; + struct CMD_BASIC_CONFIG rCmdBasicConfig; + struct WIFI_VAR *prWifiVar = &prAdapter->rWifiVar; + + DEBUGFUNC("wlanoidSetCSUMOffload"); + DBGLOG(INIT, LOUD, "\n"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(uint32_t); + + if (u4SetBufferLen < sizeof(uint32_t)) + return WLAN_STATUS_INVALID_LENGTH; + + ASSERT(pvSetBuffer); + u4CSUMFlags = *(uint32_t *) pvSetBuffer; + + kalMemZero(&rCmdBasicConfig, + sizeof(struct CMD_BASIC_CONFIG)); + + rCmdBasicConfig.ucNative80211 = 0; /* @FIXME: for Vista */ + + if (u4CSUMFlags & CSUM_OFFLOAD_EN_TX_TCP) + rCmdBasicConfig.rCsumOffload.u2TxChecksum |= BIT(2); + + if (u4CSUMFlags & CSUM_OFFLOAD_EN_TX_UDP) + rCmdBasicConfig.rCsumOffload.u2TxChecksum |= BIT(1); + + if (u4CSUMFlags & CSUM_OFFLOAD_EN_TX_IP) + rCmdBasicConfig.rCsumOffload.u2TxChecksum |= BIT(0); + + if (u4CSUMFlags & CSUM_OFFLOAD_EN_RX_TCP) + rCmdBasicConfig.rCsumOffload.u2RxChecksum |= BIT(2); + + if (u4CSUMFlags & CSUM_OFFLOAD_EN_RX_UDP) + rCmdBasicConfig.rCsumOffload.u2RxChecksum |= BIT(1); + + if (u4CSUMFlags & (CSUM_OFFLOAD_EN_RX_IPv4 | + CSUM_OFFLOAD_EN_RX_IPv6)) + rCmdBasicConfig.rCsumOffload.u2RxChecksum |= BIT(0); + + prAdapter->u4CSUMFlags = u4CSUMFlags; + rCmdBasicConfig.ucCtrlFlagAssertPath = + prWifiVar->ucCtrlFlagAssertPath; + rCmdBasicConfig.ucCtrlFlagDebugLevel = + prWifiVar->ucCtrlFlagDebugLevel; + + wlanSendSetQueryCmd(prAdapter, + CMD_ID_BASIC_CONFIG, + TRUE, + FALSE, + TRUE, + NULL, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_BASIC_CONFIG), + (uint8_t *) &rCmdBasicConfig, + pvSetBuffer, u4SetBufferLen); + + return WLAN_STATUS_SUCCESS; +} +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Setting the IP address for pattern search function. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \return WLAN_STATUS_SUCCESS + * \return WLAN_STATUS_ADAPTER_NOT_READY + * \return WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetNetworkAddress(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t i, u4IPv4AddrIdx; + struct CMD_SET_NETWORK_ADDRESS_LIST + *prCmdNetworkAddressList; + struct PARAM_NETWORK_ADDRESS_LIST *prNetworkAddressList = + (struct PARAM_NETWORK_ADDRESS_LIST *) pvSetBuffer; + struct PARAM_NETWORK_ADDRESS *prNetworkAddress; + uint32_t u4IPv4AddrCount, u4CmdSize; +#if CFG_ENABLE_GTK_FRAME_FILTER + uint32_t u4IpV4AddrListSize; + struct BSS_INFO *prBssInfo; +#endif + + DEBUGFUNC("wlanoidSetNetworkAddress"); + DBGLOG(INIT, LOUD, "\n"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = 4; + + if (u4SetBufferLen < OFFSET_OF(struct + PARAM_NETWORK_ADDRESS_LIST, arAddress)) + return WLAN_STATUS_INVALID_DATA; + + *pu4SetInfoLen = 0; + u4IPv4AddrCount = 0; + + /* 4 <1.1> Get IPv4 address count */ + /* We only suppot IPv4 address setting */ + prNetworkAddress = prNetworkAddressList->arAddress; + for (i = 0; i < prNetworkAddressList->u4AddressCount; i++) { + if ((prNetworkAddress->u2AddressType == + PARAM_PROTOCOL_ID_TCP_IP) && + (prNetworkAddress->u2AddressLength == IPV4_ADDR_LEN)) { + u4IPv4AddrCount++; + } + + prNetworkAddress = (struct PARAM_NETWORK_ADDRESS *) + ((unsigned long) prNetworkAddress + + (unsigned long) (prNetworkAddress->u2AddressLength*2 + + OFFSET_OF(struct PARAM_NETWORK_ADDRESS, aucAddress))); + } + + /* 4 <2> Calculate command buffer size */ + /* construct payload of command packet */ + if (u4IPv4AddrCount == 0) + u4CmdSize = sizeof(struct CMD_SET_NETWORK_ADDRESS_LIST); + else + u4CmdSize = + OFFSET_OF(struct CMD_SET_NETWORK_ADDRESS_LIST, + arNetAddress) + + (sizeof(struct CMD_IPV4_NETWORK_ADDRESS) * + u4IPv4AddrCount); + + /* 4 <3> Allocate command buffer */ + prCmdNetworkAddressList = (struct CMD_SET_NETWORK_ADDRESS_LIST *) + kalMemAlloc(u4CmdSize, VIR_MEM_TYPE); + + if (prCmdNetworkAddressList == NULL) + return WLAN_STATUS_FAILURE; + + kalMemZero(prCmdNetworkAddressList, u4CmdSize); + prCmdNetworkAddressList->ucVersion = 1; +#if CFG_ENABLE_GTK_FRAME_FILTER + u4IpV4AddrListSize = + OFFSET_OF(struct IPV4_NETWORK_ADDRESS_LIST, arNetAddr) + + (u4IPv4AddrCount * + sizeof(struct CMD_IPV4_NETWORK_ADDRESS)); + prBssInfo = aisGetAisBssInfo(prAdapter, + prNetworkAddressList->ucBssIdx); + if (prBssInfo->prIpV4NetAddrList) + FREE_IPV4_NETWORK_ADDR_LIST(prBssInfo->prIpV4NetAddrList); + prBssInfo->prIpV4NetAddrList = + (struct IPV4_NETWORK_ADDRESS_LIST *) + kalMemAlloc(u4IpV4AddrListSize, + VIR_MEM_TYPE); + prBssInfo->prIpV4NetAddrList->ucAddrCount = + (uint8_t) u4IPv4AddrCount; +#endif + + /* 4 <4> Fill P_CMD_SET_NETWORK_ADDRESS_LIST */ + prCmdNetworkAddressList->ucBssIndex = + prNetworkAddressList->ucBssIdx; + + /* only to set IP address to FW once ARP filter is enabled */ + if (prAdapter->fgEnArpFilter) { + prCmdNetworkAddressList->ucAddressCount = + (uint8_t) u4IPv4AddrCount; + prNetworkAddress = prNetworkAddressList->arAddress; + + /* DBGLOG(INIT, INFO, ("%s: u4IPv4AddrCount (%lu)\n", + * __FUNCTION__, u4IPv4AddrCount)); + */ + + for (i = 0, u4IPv4AddrIdx = 0; + i < prNetworkAddressList->u4AddressCount; i++) { + if (prNetworkAddress->u2AddressType == + PARAM_PROTOCOL_ID_TCP_IP && + prNetworkAddress->u2AddressLength == + IPV4_ADDR_LEN) { + + kalMemCopy(prCmdNetworkAddressList-> + arNetAddress[u4IPv4AddrIdx].aucIpAddr, + prNetworkAddress->aucAddress, + sizeof(uint32_t)); + kalMemCopy(prCmdNetworkAddressList-> + arNetAddress[u4IPv4AddrIdx].aucIpMask, + prNetworkAddress-> + aucAddress+sizeof(uint32_t), + sizeof(uint32_t)); +#if CFG_ENABLE_GTK_FRAME_FILTER + kalMemCopy(prBssInfo->prIpV4NetAddrList-> + arNetAddr[u4IPv4AddrIdx].aucIpAddr, + prNetworkAddress->aucAddress, + sizeof(uint32_t)); +#endif + + DBGLOG(OID, INFO, + "%s:IPv4 Addr[%u]["IPV4STR"]Mask["IPV4STR"]\n", + __func__, + u4IPv4AddrIdx, + IPV4TOSTR(prNetworkAddress->aucAddress), + IPV4TOSTR(prNetworkAddress-> + aucAddress+sizeof(uint32_t))); + + u4IPv4AddrIdx++; + } + + prNetworkAddress = (struct PARAM_NETWORK_ADDRESS *) + ((unsigned long)prNetworkAddress + + (unsigned long)(prNetworkAddress-> + u2AddressLength*2 + + OFFSET_OF(struct PARAM_NETWORK_ADDRESS, + aucAddress))); + } + + } else { + prCmdNetworkAddressList->ucAddressCount = 0; + } + + DBGLOG(OID, INFO, + "%s: Set %u IPv4 address for BSS[%d] ver[%d]\n", __func__, + u4IPv4AddrCount, + prCmdNetworkAddressList->ucBssIndex, + prCmdNetworkAddressList->ucVersion); + + /* 4 <5> Send command */ + rStatus = wlanSendSetQueryCmd(prAdapter, + CMD_ID_SET_IP_ADDRESS, + TRUE, + FALSE, + TRUE, + nicCmdEventSetIpAddress, + nicOidCmdTimeoutCommon, + u4CmdSize, + (uint8_t *) prCmdNetworkAddressList, + pvSetBuffer, + u4SetBufferLen); + + kalMemFree(prCmdNetworkAddressList, VIR_MEM_TYPE, + u4CmdSize); + return rStatus; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Set driver to switch into RF test mode + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set, + * should be NULL + * \param[in] u4SetBufferLen The length of the set buffer, should be 0 + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \return WLAN_STATUS_SUCCESS + * \return WLAN_STATUS_ADAPTER_NOT_READY + * \return WLAN_STATUS_INVALID_DATA + * \return WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidRftestSetTestMode(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + uint32_t rStatus; + struct CMD_TEST_CTRL rCmdTestCtrl; + + DEBUGFUNC("wlanoidRftestSetTestMode"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = 0; + + if (u4SetBufferLen == 0) { + if (prAdapter->fgTestMode == FALSE) { + /* switch to RF Test mode */ + rCmdTestCtrl.ucAction = 0; /* Switch mode */ + rCmdTestCtrl.u.u4OpMode = 1; /* RF test mode */ + + rStatus = wlanSendSetQueryCmd(prAdapter, + CMD_ID_TEST_CTRL, + TRUE, + FALSE, + TRUE, + nicCmdEventEnterRfTest, + nicOidCmdEnterRFTestTimeout, + sizeof(struct CMD_TEST_CTRL), + (uint8_t *) &rCmdTestCtrl, + pvSetBuffer, u4SetBufferLen); + } else { + /* already in test mode .. */ + rStatus = WLAN_STATUS_SUCCESS; + } + } else { + rStatus = WLAN_STATUS_INVALID_DATA; + } + + return rStatus; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Set driver to switch into RF test ICAP mode + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set, + * should be NULL + * \param[in] u4SetBufferLen The length of the set buffer, should be 0 + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \return WLAN_STATUS_SUCCESS + * \return WLAN_STATUS_ADAPTER_NOT_READY + * \return WLAN_STATUS_INVALID_DATA + * \return WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidRftestSetTestIcapMode(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + uint32_t rStatus; + struct CMD_TEST_CTRL rCmdTestCtrl; + struct ICAP_INFO_T *prIcapInfo = NULL; + + DEBUGFUNC("wlanoidRftestSetTestIcapMode"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + prIcapInfo = &prAdapter->rIcapInfo; + ASSERT(prIcapInfo); + + *pu4SetInfoLen = 0; + + if (u4SetBufferLen == 0) { + if (prIcapInfo->eIcapState == ICAP_STATE_INIT) { + /* switch to RF Test mode */ + rCmdTestCtrl.ucAction = 0; /* Switch mode */ + rCmdTestCtrl.u.u4OpMode = 2; /* ICAP mode */ + + rStatus = wlanSendSetQueryCmd(prAdapter, + CMD_ID_TEST_CTRL, + TRUE, + FALSE, + TRUE, + nicCmdEventEnterRfTest, + nicOidCmdEnterRFTestTimeout, + sizeof(struct CMD_TEST_CTRL), + (uint8_t *) &rCmdTestCtrl, + pvSetBuffer, u4SetBufferLen); + } else { + /* already in ICAP mode .. */ + DBGLOG(RFTEST, WARN, + "Switch ICAP FAil in State(%d)\n", + prIcapInfo->eIcapState); + rStatus = WLAN_STATUS_SUCCESS; + } + } else { + rStatus = WLAN_STATUS_INVALID_DATA; + } + + return rStatus; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Set driver to switch into normal operation mode from RF test mode + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set + * should be NULL + * \param[in] u4SetBufferLen The length of the set buffer, should be 0 + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \return WLAN_STATUS_SUCCESS + * \return WLAN_STATUS_ADAPTER_NOT_READY + * \return WLAN_STATUS_INVALID_DATA + * \return WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidRftestSetAbortTestMode(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + uint32_t rStatus; + struct CMD_TEST_CTRL rCmdTestCtrl; + + DEBUGFUNC("wlanoidRftestSetAbortTestMode"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = 0; + + if (u4SetBufferLen == 0) { + if (prAdapter->fgTestMode == TRUE) { + /* switch to normal mode */ + rCmdTestCtrl.ucAction = 0; /* Switch mode */ + rCmdTestCtrl.u.u4OpMode = 0; /* normal mode */ + + rStatus = wlanSendSetQueryCmd(prAdapter, + CMD_ID_TEST_CTRL, + TRUE, + FALSE, + TRUE, + nicCmdEventLeaveRfTest, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_TEST_CTRL), + (uint8_t *) &rCmdTestCtrl, + pvSetBuffer, u4SetBufferLen); + } else { + /* already in normal mode .. */ + rStatus = WLAN_STATUS_SUCCESS; + } + } else { + rStatus = WLAN_STATUS_INVALID_DATA; + } + + return rStatus; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief query for RF test parameter + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvQueryBuffer Pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufferLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number + * of bytes written into the query buffer. If the + * call failed due to invalid length of the query + * buffer, returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_BUFFER_TOO_SHORT + * \retval WLAN_STATUS_NOT_SUPPORTED + * \retval WLAN_STATUS_NOT_ACCEPTED + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidRftestQueryAutoTest(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + struct PARAM_MTK_WIFI_TEST_STRUCT *prRfATInfo; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + + DEBUGFUNC("wlanoidRftestQueryAutoTest"); + + ASSERT(prAdapter); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + ASSERT(pu4QueryInfoLen); + + *pu4QueryInfoLen = sizeof(struct + PARAM_MTK_WIFI_TEST_STRUCT); + +#if 0 /* PeiHsuan Temp Remove this check for workaround Gen2/Gen3 EM Mode + * Modification + */ + if (u4QueryBufferLen != sizeof(struct PARAM_MTK_WIFI_TEST_STRUCT)) { + DBGLOG(REQ, ERROR, "Invalid data. QueryBufferLen: %ld.\n", + u4QueryBufferLen); + return WLAN_STATUS_INVALID_LENGTH; + } +#endif + + prRfATInfo = (struct PARAM_MTK_WIFI_TEST_STRUCT *) + pvQueryBuffer; + + DBGLOG(RFTEST, INFO, + "Get AT_CMD BufferLen = %d, AT Index = %d, Data = %d\n", + u4QueryBufferLen, + prRfATInfo->u4FuncIndex, + prRfATInfo->u4FuncData); + + rStatus = rftestQueryATInfo(prAdapter, + prRfATInfo->u4FuncIndex, + prRfATInfo->u4FuncData, + pvQueryBuffer, u4QueryBufferLen); + + return rStatus; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Set RF test parameter + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \return WLAN_STATUS_SUCCESS + * \return WLAN_STATUS_ADAPTER_NOT_READY + * \return WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidRftestSetAutoTest(IN struct ADAPTER *prAdapter, + OUT void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct PARAM_MTK_WIFI_TEST_STRUCT *prRfATInfo; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + + DEBUGFUNC("wlanoidRftestSetAutoTest"); + + ASSERT(prAdapter); + ASSERT(pvSetBuffer); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(struct PARAM_MTK_WIFI_TEST_STRUCT); + +#if 0 /* PeiHsuan Temp Remove this check for workaround Gen2/Gen3 EM Mode + * Modification + */ + if (u4SetBufferLen != sizeof(struct + PARAM_MTK_WIFI_TEST_STRUCT)) { + DBGLOG(REQ, ERROR, "Invalid data. SetBufferLen: %ld.\n", + u4SetBufferLen); + return WLAN_STATUS_INVALID_LENGTH; + } +#endif + + prRfATInfo = (struct PARAM_MTK_WIFI_TEST_STRUCT *) + pvSetBuffer; + + DBGLOG(RFTEST, INFO, + "Set AT_CMD BufferLen = %d, AT Index = %d, Data = %d\n", + u4SetBufferLen, + prRfATInfo->u4FuncIndex, + prRfATInfo->u4FuncData); + + rStatus = rftestSetATInfo(prAdapter, + prRfATInfo->u4FuncIndex, prRfATInfo->u4FuncData); + + return rStatus; +} + +/* RF test OID set handler */ +uint32_t rftestSetATInfo(IN struct ADAPTER *prAdapter, + uint32_t u4FuncIndex, uint32_t u4FuncData) { + struct GLUE_INFO *prGlueInfo; + struct CMD_INFO *prCmdInfo; + struct CMD_TEST_CTRL *pCmdTestCtrl; + struct mt66xx_chip_info *prChipInfo; + uint16_t cmd_size; + + ASSERT(prAdapter); + + prChipInfo = prAdapter->chip_info; + prGlueInfo = prAdapter->prGlueInfo; + cmd_size = prChipInfo->u2CmdTxHdrSize + sizeof(struct CMD_TEST_CTRL); + prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, cmd_size); + if (!prCmdInfo) { + DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); + return WLAN_STATUS_FAILURE; + } + + /* Setup common CMD Info Packet */ + prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; + prCmdInfo->u2InfoBufLen = cmd_size; + prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; + prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; + prCmdInfo->fgIsOid = TRUE; + prCmdInfo->ucCID = CMD_ID_TEST_CTRL; + prCmdInfo->fgSetQuery = TRUE; + prCmdInfo->fgNeedResp = FALSE; + prCmdInfo->u4SetInfoLen = sizeof(struct CMD_TEST_CTRL); + prCmdInfo->pvInformationBuffer = NULL; + prCmdInfo->u4InformationBufferLength = 0; + + /* Setup WIFI_CMD_T (payload = CMD_TEST_CTRL_T) */ + NIC_FILL_CMD_TX_HDR(prAdapter, + prCmdInfo->pucInfoBuffer, + prCmdInfo->u2InfoBufLen, + prCmdInfo->ucCID, + CMD_PACKET_TYPE_ID, + &prCmdInfo->ucCmdSeqNum, + prCmdInfo->fgSetQuery, + &pCmdTestCtrl, FALSE, 0, S2D_INDEX_CMD_H2N); + pCmdTestCtrl->ucAction = 1; /* Set ATInfo */ + pCmdTestCtrl->u.rRfATInfo.u4FuncIndex = u4FuncIndex; + pCmdTestCtrl->u.rRfATInfo.u4FuncData = u4FuncData; + + if ((u4FuncIndex == RF_AT_FUNCID_COMMAND) + && (u4FuncData == RF_AT_COMMAND_ICAP)) + prAdapter->rIcapInfo.eIcapState = ICAP_STATE_START; + + /* ICAP dump name Reset */ + if ((u4FuncIndex == RF_AT_FUNCID_COMMAND) + && (u4FuncData == RF_AT_COMMAND_RESET_DUMP_NAME)) + prAdapter->rIcapInfo.u2DumpIndex = 0; + + /* insert into prCmdQueue */ + kalEnqueueCommand(prGlueInfo, + (struct QUE_ENTRY *) prCmdInfo); + + /* wakeup txServiceThread later */ + GLUE_SET_EVENT(prAdapter->prGlueInfo); + + return WLAN_STATUS_PENDING; +} + +uint32_t wlanoidExtRfTestICapStart(IN struct ADAPTER *prAdapter, + OUT void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct CMD_TEST_CTRL_EXT_T rCmdTestCtrl; + struct RBIST_CAP_START_T *prCmdICapInfo; + struct PARAM_MTK_WIFI_TEST_STRUCT_EXT_T *prRfATInfo; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + + DEBUGFUNC("wlanoidExtRfTestICapStart"); + + ASSERT(prAdapter); + ASSERT(pvSetBuffer); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(struct + PARAM_MTK_WIFI_TEST_STRUCT_EXT_T); + + prRfATInfo = (struct PARAM_MTK_WIFI_TEST_STRUCT_EXT_T *) + pvSetBuffer; + + DBGLOG(RFTEST, INFO, + "Set AT_CMD BufferLen = %d, AT Index = %d\n", + u4SetBufferLen, + prRfATInfo->u4FuncIndex); + + rCmdTestCtrl.ucAction = ACTION_IN_RFTEST; + rCmdTestCtrl.u.rRfATInfo.u4FuncIndex = + SET_ICAP_CAPTURE_START; + + prCmdICapInfo = &(rCmdTestCtrl.u.rRfATInfo.Data.rICapInfo); + kalMemCopy(prCmdICapInfo, &(prRfATInfo->Data.rICapInfo), + sizeof(struct RBIST_CAP_START_T)); + + if (prCmdICapInfo->u4Trigger == TRUE) + prAdapter->rIcapInfo.eIcapState = ICAP_STATE_START; + else + /* ICAP STOP, reset state to INIT state*/ + prAdapter->rIcapInfo.eIcapState = ICAP_STATE_INIT; + + rStatus = wlanSendSetQueryExtCmd(prAdapter, + CMD_ID_LAYER_0_EXT_MAGIC_NUM, + EXT_CMD_ID_RF_TEST, + TRUE, /* Query Bit: True->write False->read */ + FALSE,/*fgNeedRsp*/ + TRUE, /*fgIsOid*/ + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_TEST_CTRL_EXT_T), + (uint8_t *)&rCmdTestCtrl, pvSetBuffer, + u4SetBufferLen); + return rStatus; +} + +uint32_t wlanoidExtRfTestICapStatus(IN struct ADAPTER *prAdapter, + OUT void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct CMD_TEST_CTRL_EXT_T rCmdTestCtrl; + struct RBIST_CAP_START_T *prCmdICapInfo; + struct PARAM_MTK_WIFI_TEST_STRUCT_EXT_T *prRfATInfo; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + + DEBUGFUNC("wlanoidExtRfTestICapStatus"); + + ASSERT(prAdapter); + ASSERT(pvSetBuffer); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(struct + PARAM_MTK_WIFI_TEST_STRUCT_EXT_T); + + prRfATInfo = (struct PARAM_MTK_WIFI_TEST_STRUCT_EXT_T *) + pvSetBuffer; + + DBGLOG(RFTEST, INFO, + "Set AT_CMD BufferLen = %d, AT Index = %d\n", + u4SetBufferLen, + prRfATInfo->u4FuncIndex); + + rCmdTestCtrl.ucAction = ACTION_IN_RFTEST; + rCmdTestCtrl.u.rRfATInfo.u4FuncIndex = + GET_ICAP_CAPTURE_STATUS; + + + prAdapter->rIcapInfo.eIcapState = ICAP_STATE_QUERY_STATUS; + + + prCmdICapInfo = &(rCmdTestCtrl.u.rRfATInfo.Data.rICapInfo); + kalMemCopy(prCmdICapInfo, &(prRfATInfo->Data.rICapInfo), + sizeof(struct RBIST_CAP_START_T)); + + rStatus = wlanSendSetQueryExtCmd(prAdapter, + CMD_ID_LAYER_0_EXT_MAGIC_NUM, + EXT_CMD_ID_RF_TEST, + FALSE, /* Query Bit: True->write False->read */ + TRUE, + TRUE, + NULL, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_TEST_CTRL_EXT_T), + (uint8_t *)(&rCmdTestCtrl), pvSetBuffer, + u4SetBufferLen); + return rStatus; +} + +void wlanoidRfTestICapRawDataProc(IN struct ADAPTER * + prAdapter, uint32_t u4CapStartAddr, + uint32_t u4TotalBufferSize) { + struct CMD_TEST_CTRL_EXT_T rCmdTestCtrl; + struct PARAM_MTK_WIFI_TEST_STRUCT_EXT_T *prRfATInfo; + uint32_t u4SetBufferLen = 0; + void *pvSetBuffer = NULL; + int32_t rStatus; + + ASSERT(prAdapter); + + prRfATInfo = &(rCmdTestCtrl.u.rRfATInfo); + + rCmdTestCtrl.ucAction = ACTION_IN_RFTEST; + prRfATInfo->u4FuncIndex = GET_ICAP_RAW_DATA; + prRfATInfo->Data.rICapDump.u4Address = u4CapStartAddr; + prRfATInfo->Data.rICapDump.u4AddrOffset = 0x04; + prRfATInfo->Data.rICapDump.u4Bank = 1; + prRfATInfo->Data.rICapDump.u4BankSize = u4TotalBufferSize; + + rStatus = wlanSendSetQueryExtCmd(prAdapter, + CMD_ID_LAYER_0_EXT_MAGIC_NUM, + EXT_CMD_ID_RF_TEST, + FALSE, /* Query Bit: True->write False->read */ + TRUE, + FALSE, /*fgIsOid = FALSE, main thread trigger*/ + NULL, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_TEST_CTRL_EXT_T), + (uint8_t *)(&rCmdTestCtrl), + pvSetBuffer, u4SetBufferLen); + +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief wifi driver response IQ data for QA agent + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] ucCID Command ID + * \param[in] fgSetQuery Set or Query + * \param[in] fgNeedResp Need for response + * \param[in] pfCmdDoneHandler Function pointer when command is done + * \param[in] u4SetQueryInfoLen The length of the set/query buffer + * \param[in] pucInfoBuffer Pointer to set/query buffer + * + * + * \retval WLAN_STATUS_PENDING + * \retval WLAN_STATUS_FAILURE + */ +/*----------------------------------------------------------------------------*/ + +uint32_t wlanoidRfTestICapGetIQData(IN struct ADAPTER *prAdapter, + OUT void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + uint32_t rStatus = WLAN_STATUS_SUCCESS; + struct _RBIST_IQ_DATA_T *prIQArray = NULL; + struct ICAP_INFO_T *prICapInfo = NULL; + struct RBIST_DUMP_IQ_T *prRbistDump = NULL; + int32_t i = 0; + uint32_t u4MaxIQDataCount = 0; + uint32_t u4DumpIndex = 0; + uint32_t u4Value, u4DataLen = 0; + uint32_t u4WFNum = 0, u4IQType = 0; + uint8_t *pData; + + ASSERT(prAdapter); + ASSERT(pvSetBuffer); + ASSERT(pu4SetInfoLen); + + prICapInfo = &prAdapter->rIcapInfo; + prIQArray = prICapInfo->prIQArray; + prRbistDump = (struct RBIST_DUMP_IQ_T *)pvSetBuffer; + u4WFNum = prRbistDump->u4WfNum; + u4IQType = prRbistDump->u4IQType; + pData = prRbistDump->pucIcapData; + + u4DumpIndex = prICapInfo->au4ICapDumpIndex[u4WFNum][u4IQType]; + + prICapInfo->eIcapState = ICAP_STATE_QA_TOOL_CAPTURE; + + + + /* 1. Maximum 1KB = ICAP_EVENT_DATA_SAMPLE (256) slots */ + u4MaxIQDataCount = prICapInfo->u4IQArrayIndex - u4DumpIndex; + if (u4MaxIQDataCount > ICAP_EVENT_DATA_SAMPLE) + u4MaxIQDataCount = ICAP_EVENT_DATA_SAMPLE; + + /* 2. update IQ Sample Count*/ + prRbistDump->u4IcapCnt = u4MaxIQDataCount; + + /* 3. Copy to buffer */ + for (i = 0; i < u4MaxIQDataCount; i++) { + u4Value = prIQArray[u4DumpIndex++].u4IQArray[u4WFNum][u4IQType]; + kalMemCopy(pData + u4DataLen, (uint8_t *) &u4Value, + sizeof(u4Value)); + u4DataLen += sizeof(u4Value); + } + + /* 4. update response IQ data length */ + prRbistDump->u4IcapDataLen = u4DataLen; + + + prICapInfo->au4ICapDumpIndex[u4WFNum][u4IQType] = u4DumpIndex; + + DBGLOG(RFTEST, INFO, "CurrICapDumpIndex[WF%d][%c]=%d,IQCnt=%d,len=%d\n", + u4WFNum, + (u4IQType == CAP_I_TYPE) ? + 'I' : 'Q', + u4DumpIndex, + u4MaxIQDataCount, + u4DataLen); + + return rStatus; +} +uint32_t +rftestQueryATInfo(IN struct ADAPTER *prAdapter, + uint32_t u4FuncIndex, uint32_t u4FuncData, + OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen) { + struct GLUE_INFO *prGlueInfo; + struct CMD_INFO *prCmdInfo; + struct CMD_TEST_CTRL *pCmdTestCtrl; + union EVENT_TEST_STATUS *prTestStatus; + struct mt66xx_chip_info *prChipInfo; + uint16_t cmd_size; + + ASSERT(prAdapter); + + prGlueInfo = prAdapter->prGlueInfo; + prChipInfo = prAdapter->chip_info; + + if (u4FuncIndex == RF_AT_FUNCID_FW_INFO) { + /* driver implementation */ + prTestStatus = (union EVENT_TEST_STATUS *) pvQueryBuffer; + + prTestStatus->rATInfo.u4FuncData = + (prAdapter->chip_info->em_interface_version << 16) | + (prAdapter->rVerInfo.u2FwOwnVersion); + + DBGLOG(RFTEST, INFO, "RF_AT_FUNCID_FW_INFO=0x%x\n", + prTestStatus->rATInfo.u4FuncData); + + u4QueryBufferLen = sizeof(union EVENT_TEST_STATUS); + + return WLAN_STATUS_SUCCESS; + } else if (u4FuncIndex == RF_AT_FUNCID_DRV_INFO) { + /* driver implementation */ + prTestStatus = (union EVENT_TEST_STATUS *) pvQueryBuffer; + + prTestStatus->rATInfo.u4FuncData = CFG_DRV_OWN_VERSION; + u4QueryBufferLen = sizeof(union EVENT_TEST_STATUS); + + return WLAN_STATUS_SUCCESS; + } else if (u4FuncIndex == + RF_AT_FUNCID_QUERY_ICAP_DUMP_FILE) { + /* driver implementation */ + prTestStatus = (union EVENT_TEST_STATUS *) pvQueryBuffer; + + prTestStatus->rATInfo.u4FuncData = + prAdapter->rIcapInfo.u2DumpIndex; + u4QueryBufferLen = sizeof(union EVENT_TEST_STATUS); + + return WLAN_STATUS_SUCCESS; + } + + cmd_size = prChipInfo->u2CmdTxHdrSize + sizeof(struct CMD_TEST_CTRL); + prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, cmd_size); + if (!prCmdInfo) { + DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); + return WLAN_STATUS_FAILURE; + } + + /* Setup common CMD Info Packet */ + prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; + prCmdInfo->u2InfoBufLen = cmd_size; + prCmdInfo->pfCmdDoneHandler = nicCmdEventQueryRfTestATInfo; + prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; + prCmdInfo->fgIsOid = TRUE; + prCmdInfo->ucCID = CMD_ID_TEST_CTRL; + prCmdInfo->fgSetQuery = FALSE; + prCmdInfo->fgNeedResp = TRUE; + prCmdInfo->u4SetInfoLen = sizeof(struct CMD_TEST_CTRL); + prCmdInfo->pvInformationBuffer = pvQueryBuffer; + prCmdInfo->u4InformationBufferLength = u4QueryBufferLen; + + /* Setup WIFI_CMD_T (payload = CMD_TEST_CTRL_T) */ + NIC_FILL_CMD_TX_HDR(prAdapter, + prCmdInfo->pucInfoBuffer, + prCmdInfo->u2InfoBufLen, + prCmdInfo->ucCID, + CMD_PACKET_TYPE_ID, + &prCmdInfo->ucCmdSeqNum, + prCmdInfo->fgSetQuery, + &pCmdTestCtrl, FALSE, 0, S2D_INDEX_CMD_H2N); + pCmdTestCtrl->ucAction = 2; /* Get ATInfo */ + pCmdTestCtrl->u.rRfATInfo.u4FuncIndex = u4FuncIndex; + pCmdTestCtrl->u.rRfATInfo.u4FuncData = u4FuncData; + + /* insert into prCmdQueue */ + kalEnqueueCommand(prGlueInfo, + (struct QUE_ENTRY *) prCmdInfo); + + /* wakeup txServiceThread later */ + GLUE_SET_EVENT(prAdapter->prGlueInfo); + + return WLAN_STATUS_PENDING; + +} + +uint32_t rftestSetFrequency(IN struct ADAPTER *prAdapter, + IN uint32_t u4FreqInKHz, + IN uint32_t *pu4SetInfoLen) { + struct CMD_TEST_CTRL rCmdTestCtrl; + + ASSERT(prAdapter); + + rCmdTestCtrl.ucAction = 5; /* Set Channel Frequency */ + rCmdTestCtrl.u.u4ChannelFreq = u4FreqInKHz; + + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_TEST_CTRL, + TRUE, + FALSE, + TRUE, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_TEST_CTRL), + (uint8_t *) &rCmdTestCtrl, NULL, 0); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief command packet generation utility + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] ucCID Command ID + * \param[in] fgSetQuery Set or Query + * \param[in] fgNeedResp Need for response + * \param[in] pfCmdDoneHandler Function pointer when command is done + * \param[in] u4SetQueryInfoLen The length of the set/query buffer + * \param[in] pucInfoBuffer Pointer to set/query buffer + * + * + * \retval WLAN_STATUS_PENDING + * \retval WLAN_STATUS_FAILURE + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanSendSetQueryCmd(IN struct ADAPTER *prAdapter, + uint8_t ucCID, + u_int8_t fgSetQuery, + u_int8_t fgNeedResp, + u_int8_t fgIsOid, + PFN_CMD_DONE_HANDLER pfCmdDoneHandler, + PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler, + uint32_t u4SetQueryInfoLen, + uint8_t *pucInfoBuffer, OUT void *pvSetQueryBuffer, + IN uint32_t u4SetQueryBufferLen) { + struct GLUE_INFO *prGlueInfo; + struct CMD_INFO *prCmdInfo; + uint8_t *pucCmfBuf; + struct mt66xx_chip_info *prChipInfo; + uint16_t cmd_size; + + if (kalIsResetting()) { + DBGLOG(INIT, WARN, "Chip resetting, skip\n"); + return WLAN_STATUS_FAILURE; + } + + prGlueInfo = prAdapter->prGlueInfo; + prChipInfo = prAdapter->chip_info; + cmd_size = prChipInfo->u2CmdTxHdrSize + u4SetQueryInfoLen; + prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, cmd_size); + DEBUGFUNC("wlanSendSetQueryCmd"); + + if (!prCmdInfo) { + DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T FAILED ID[0x%x]\n", + ucCID); + return WLAN_STATUS_FAILURE; + } + + /* Setup common CMD Info Packet */ + prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; + prCmdInfo->u2InfoBufLen = cmd_size; + prCmdInfo->pfCmdDoneHandler = pfCmdDoneHandler; + prCmdInfo->pfCmdTimeoutHandler = pfCmdTimeoutHandler; + prCmdInfo->fgIsOid = fgIsOid; + prCmdInfo->ucCID = ucCID; + prCmdInfo->fgSetQuery = fgSetQuery; + prCmdInfo->fgNeedResp = fgNeedResp; + prCmdInfo->u4SetInfoLen = u4SetQueryInfoLen; + prCmdInfo->pvInformationBuffer = pvSetQueryBuffer; + prCmdInfo->u4InformationBufferLength = u4SetQueryBufferLen; + + /* Setup WIFI_CMD_T (no payload) */ + NIC_FILL_CMD_TX_HDR(prAdapter, + prCmdInfo->pucInfoBuffer, + prCmdInfo->u2InfoBufLen, + prCmdInfo->ucCID, + CMD_PACKET_TYPE_ID, + &prCmdInfo->ucCmdSeqNum, + prCmdInfo->fgSetQuery, + &pucCmfBuf, FALSE, 0, S2D_INDEX_CMD_H2N); + if (u4SetQueryInfoLen > 0 && pucInfoBuffer != NULL) + kalMemCopy(pucCmfBuf, pucInfoBuffer, + u4SetQueryInfoLen); + /* insert into prCmdQueue */ + kalEnqueueCommand(prGlueInfo, + (struct QUE_ENTRY *) prCmdInfo); + + /* wakeup txServiceThread later */ + GLUE_SET_EVENT(prGlueInfo); + return WLAN_STATUS_PENDING; +} + +#if CFG_SUPPORT_WAPI +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called by WAPI ui to set wapi mode, which is needed to + * info the the driver to operation at WAPI mode while driver initialize. + * + * \param[in] prAdapter Pointer to the Adapter structure + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set + * \param[in] u4SetBufferLen The length of the set buffer + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed due to invalid length of + * the set buffer, returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. + * \retval WLAN_STATUS_INVALID_LENGTH + * + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetWapiMode(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + DEBUGFUNC("wlanoidSetWapiMode"); + DBGLOG(REQ, LOUD, "\r\n"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + ASSERT(pvSetBuffer); + + /* Todo:: For support WAPI and Wi-Fi at same driver, use the set wapi + * assoc ie at the check point + * The Adapter Connection setting fgUseWapi will cleat whil oid + * set mode (infra), + * And set fgUseWapi True while set wapi assoc ie + * policay selection, add key all depend on this flag, + * The fgUseWapi may remove later + */ + if (*(uint32_t *) pvSetBuffer) + prAdapter->fgUseWapi = TRUE; + else + prAdapter->fgUseWapi = FALSE; + +#if 0 + prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, + (CMD_HDR_SIZE + 4)); + + if (!prCmdInfo) { + DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); + return WLAN_STATUS_FAILURE; + } + /* increase command sequence number */ + ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); + + /* compose CMD_BUILD_CONNECTION cmd pkt */ + prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; + prCmdInfo->ucBssIndex = AIS_DEFAULT_INDEX; + prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + 4; + prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; + prCmdInfo->pfCmdTimeoutHandler = NULL; + prCmdInfo->fgIsOid = TRUE; + prCmdInfo->ucCID = CMD_ID_WAPI_MODE; + prCmdInfo->fgSetQuery = TRUE; + prCmdInfo->fgNeedResp = FALSE; + prCmdInfo->fgDriverDomainMCR = FALSE; + prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; + prCmdInfo->u4SetInfoLen = u4SetBufferLen; + prCmdInfo->pvInformationBuffer = pvSetBuffer; + prCmdInfo->u4InformationBufferLength = u4SetBufferLen; + + /* Setup WIFI_CMD_T */ + prWifiCmd = (struct WIFI_CMD *) (prCmdInfo->pucInfoBuffer); + prWifiCmd->u2TxByteCount = prCmdInfo->u2InfoBufLen; + prWifiCmd->u2PQ_ID = CMD_PQ_ID; + prWifiCmd->ucPktTypeID = CMD_PACKET_TYPE_ID; + prWifiCmd->ucCID = prCmdInfo->ucCID; + prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; + prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; + + cp = (uint8_t *) (prWifiCmd->aucBuffer); + + kalMemCopy(cp, (uint8_t *) pvSetBuffer, 4); + + /* insert into prCmdQueue */ + kalEnqueueCommand(prGlueInfo, + (struct QUE_ENTRY *) prCmdInfo); + + /* wakeup txServiceThread later */ + GLUE_SET_EVENT(prGlueInfo); + + return WLAN_STATUS_PENDING; +#else + return WLAN_STATUS_SUCCESS; +#endif +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called by WAPI to set the assoc info, which is needed + * to add to Association request frame while join WAPI AP. + * + * \param[in] prAdapter Pointer to the Adapter structure + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set + * \param[in] u4SetBufferLen The length of the set buffer + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed due to invalid length of + * the set buffer, returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. + * \retval WLAN_STATUS_INVALID_LENGTH + * + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetWapiAssocInfo(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct WAPI_INFO_ELEM *prWapiInfo; + struct CONNECTION_SETTINGS *prConnSettings; + uint8_t ucBssIndex = 0; + + ASSERT(prAdapter); + ASSERT(pvSetBuffer); + ASSERT(pu4SetInfoLen); + + DEBUGFUNC("wlanoidSetWapiAssocInfo"); + + ucBssIndex = GET_IOCTL_BSSIDX(prAdapter); + + DBGLOG(REQ, LOUD, "ucBssIndex %d\n", ucBssIndex); + + prConnSettings = + aisGetConnSettings(prAdapter, ucBssIndex); + + prConnSettings->fgWapiMode = FALSE; + + if (u4SetBufferLen < 20 /* From EID to Group cipher */) + return WLAN_STATUS_INVALID_LENGTH; + + if (!wextSrchDesiredWAPIIE((uint8_t *) pvSetBuffer, + u4SetBufferLen, (uint8_t **) &prWapiInfo)) + return WLAN_STATUS_INVALID_LENGTH; + + if (!prWapiInfo || prWapiInfo->ucLength < 18) + return WLAN_STATUS_INVALID_LENGTH; + + /* Skip Version check */ + + /*Cipher suite count check, only one of each for now*/ + if (prWapiInfo->u2AKMSuiteCount > 1 || + prWapiInfo->u2PairSuiteCount > 1) + return WLAN_STATUS_INVALID_LENGTH; + + DBGLOG(SEC, TRACE, + "WAPI: Assoc Info auth mgt suite [%d]: %02x-%02x-%02x-%02x\n", + prWapiInfo->u2AKMSuiteCount, + (uint8_t) (prWapiInfo->u4AKMSuite & 0x000000FF), + (uint8_t) ((prWapiInfo->u4AKMSuite >> 8) & 0x000000FF), + (uint8_t) ((prWapiInfo->u4AKMSuite >> 16) & 0x000000FF), + (uint8_t) ((prWapiInfo->u4AKMSuite >> 24) & 0x000000FF)); + + if (prWapiInfo->u4AKMSuite != WAPI_AKM_SUITE_802_1X + && prWapiInfo->u4AKMSuite != WAPI_AKM_SUITE_PSK) + return WLAN_STATUS_NOT_SUPPORTED; + + DBGLOG(SEC, TRACE, + "WAPI: Assoc Info pairwise cipher suite [%d]: %02x-%02x-%02x-%02x\n", + prWapiInfo->u2PairSuiteCount, + (uint8_t) (prWapiInfo->u4PairSuite & 0x000000FF), + (uint8_t) ((prWapiInfo->u4PairSuite >> 8) & 0x000000FF), + (uint8_t) ((prWapiInfo->u4PairSuite >> 16) & 0x000000FF), + (uint8_t) ((prWapiInfo->u4PairSuite >> 24) & 0x000000FF)); + + if (prWapiInfo->u4PairSuite != WAPI_CIPHER_SUITE_WPI) + return WLAN_STATUS_NOT_SUPPORTED; + + DBGLOG(SEC, TRACE, + "WAPI: Assoc Info group cipher suite : %02x-%02x-%02x-%02x\n", + (uint8_t) (prWapiInfo->u4GroupSuite & 0x000000FF), + (uint8_t) ((prWapiInfo->u4GroupSuite >> 8) & 0x000000FF), + (uint8_t) ((prWapiInfo->u4GroupSuite >> 16) & 0x000000FF), + (uint8_t) ((prWapiInfo->u4GroupSuite >> 24) & 0x000000FF)); + + if (prWapiInfo->u4GroupSuite != WAPI_CIPHER_SUITE_WPI) + return WLAN_STATUS_NOT_SUPPORTED; + + prConnSettings->u4WapiSelectedAKMSuite + = prWapiInfo->u4AKMSuite; + prConnSettings->u4WapiSelectedPairwiseCipher + = prWapiInfo->u4PairSuite; + prConnSettings->u4WapiSelectedGroupCipher + = prWapiInfo->u4GroupSuite; + + prConnSettings->fgWapiMode = TRUE; + + return WLAN_STATUS_SUCCESS; + +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set the wpi key to the driver. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_ADAPTER_NOT_READY + * \retval WLAN_STATUS_INVALID_LENGTH + * \retval WLAN_STATUS_INVALID_DATA + * + * \note The setting buffer P_PARAM_WPI_KEY, which is set by NDIS, is unpacked. + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetWapiKey(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct GLUE_INFO *prGlueInfo; + struct CMD_INFO *prCmdInfo; + struct PARAM_WPI_KEY *prNewKey; + struct CMD_802_11_KEY *prCmdKey; + uint8_t *pc; + struct STA_RECORD *prStaRec; + struct BSS_INFO *prBssInfo; + struct mt66xx_chip_info *prChipInfo; + uint16_t cmd_size; + uint8_t ucBssIndex = 0; + + DEBUGFUNC("wlanoidSetWapiKey"); + + ASSERT(prAdapter); + ASSERT(pvSetBuffer); + ASSERT(pu4SetInfoLen); + prChipInfo = prAdapter->chip_info; + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, WARN, + "Fail in set add key! (Adapter not ready). ACPI=D%d, Radio=%d\r\n", + prAdapter->rAcpiState, prAdapter->fgIsRadioOff); + return WLAN_STATUS_ADAPTER_NOT_READY; + } + + prNewKey = (struct PARAM_WPI_KEY *) pvSetBuffer; + + ucBssIndex = prNewKey->ucBssIdx; + DBGLOG(REQ, LOUD, "ucBssIndex %d\n", ucBssIndex); + + DBGLOG_MEM8(REQ, TRACE, (uint8_t *) pvSetBuffer, 560); + pc = (uint8_t *) pvSetBuffer; + + *pu4SetInfoLen = u4SetBufferLen; + + /* Todo:: WAPI AP mode !!!!! */ + prBssInfo = + aisGetAisBssInfo(prAdapter, ucBssIndex); + + prNewKey->ucKeyID = prNewKey->ucKeyID & BIT(0); + + /* Dump P_PARAM_WPI_KEY_T content. */ + DBGLOG(REQ, TRACE, + "Set: Dump P_PARAM_WPI_KEY_T content\r\n"); + DBGLOG(REQ, TRACE, "TYPE : %d\r\n", + prNewKey->eKeyType); + DBGLOG(REQ, TRACE, "Direction : %d\r\n", + prNewKey->eDirection); + DBGLOG(REQ, TRACE, "KeyID : %d\r\n", prNewKey->ucKeyID); + DBGLOG(REQ, TRACE, "AddressIndex:\r\n"); + DBGLOG_MEM8(REQ, TRACE, prNewKey->aucAddrIndex, 12); + prNewKey->u4LenWPIEK = 16; + + DBGLOG_MEM8(REQ, TRACE, (uint8_t *) prNewKey->aucWPIEK, + (uint8_t) prNewKey->u4LenWPIEK); + prNewKey->u4LenWPICK = 16; + + DBGLOG(REQ, TRACE, "CK Key(%d):\r\n", + (uint8_t) prNewKey->u4LenWPICK); + DBGLOG_MEM8(REQ, TRACE, (uint8_t *) prNewKey->aucWPICK, + (uint8_t) prNewKey->u4LenWPICK); + DBGLOG(REQ, TRACE, "PN:\r\n"); + if (prNewKey->eKeyType == 0) { + prNewKey->aucPN[0] = 0x5c; + prNewKey->aucPN[1] = 0x36; + prNewKey->aucPN[2] = 0x5c; + prNewKey->aucPN[3] = 0x36; + prNewKey->aucPN[4] = 0x5c; + prNewKey->aucPN[5] = 0x36; + prNewKey->aucPN[6] = 0x5c; + prNewKey->aucPN[7] = 0x36; + prNewKey->aucPN[8] = 0x5c; + prNewKey->aucPN[9] = 0x36; + prNewKey->aucPN[10] = 0x5c; + prNewKey->aucPN[11] = 0x36; + prNewKey->aucPN[12] = 0x5c; + prNewKey->aucPN[13] = 0x36; + prNewKey->aucPN[14] = 0x5c; + prNewKey->aucPN[15] = 0x36; + } + + DBGLOG_MEM8(REQ, TRACE, (uint8_t *) prNewKey->aucPN, 16); + + prGlueInfo = prAdapter->prGlueInfo; + + cmd_size = prChipInfo->u2CmdTxHdrSize + u4SetBufferLen; + prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, cmd_size); + if (!prCmdInfo) { + DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); + return WLAN_STATUS_FAILURE; + } + + /* compose CMD_ID_ADD_REMOVE_KEY cmd pkt */ + prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; + prCmdInfo->u2InfoBufLen = cmd_size; + prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; + prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; + prCmdInfo->fgIsOid = TRUE; + prCmdInfo->ucCID = CMD_ID_ADD_REMOVE_KEY; + prCmdInfo->fgSetQuery = TRUE; + prCmdInfo->fgNeedResp = FALSE; + prCmdInfo->u4SetInfoLen = u4SetBufferLen; + prCmdInfo->pvInformationBuffer = pvSetBuffer; + prCmdInfo->u4InformationBufferLength = u4SetBufferLen; + + /* Setup WIFI_CMD_T */ + NIC_FILL_CMD_TX_HDR(prAdapter, + prCmdInfo->pucInfoBuffer, + prCmdInfo->u2InfoBufLen, + prCmdInfo->ucCID, + CMD_PACKET_TYPE_ID, + &prCmdInfo->ucCmdSeqNum, + prCmdInfo->fgSetQuery, &prCmdKey, FALSE, 0, S2D_INDEX_CMD_H2N); + + kalMemZero(prCmdKey, sizeof(struct CMD_802_11_KEY)); + + prCmdKey->ucAddRemove = 1; /* Add */ + + if (prNewKey->eKeyType == ENUM_WPI_PAIRWISE_KEY) { + prCmdKey->ucTxKey = 1; + prCmdKey->ucKeyType = 1; + } + kalMemCopy(prCmdKey->aucPeerAddr, + (uint8_t *) prNewKey->aucAddrIndex, MAC_ADDR_LEN); + if ((prCmdKey->aucPeerAddr[0] & prCmdKey->aucPeerAddr[1] & + prCmdKey->aucPeerAddr[2] & + prCmdKey->aucPeerAddr[3] & prCmdKey->aucPeerAddr[4] & + prCmdKey->aucPeerAddr[5]) == 0xFF) { + prStaRec = cnmGetStaRecByAddress(prAdapter, + prBssInfo->ucBssIndex, prBssInfo->aucBSSID); + ASSERT(prStaRec); /* AIS RSN Group key, addr is BC addr */ + kalMemCopy(prCmdKey->aucPeerAddr, prStaRec->aucMacAddr, + MAC_ADDR_LEN); + } else { + prStaRec = cnmGetStaRecByAddress(prAdapter, + prBssInfo->ucBssIndex, prCmdKey->aucPeerAddr); + } + + prCmdKey->ucBssIdx = + prBssInfo->ucBssIndex; /* AIS */ + + prCmdKey->ucKeyId = prNewKey->ucKeyID; + + prCmdKey->ucKeyLen = 32; + + prCmdKey->ucAlgorithmId = CIPHER_SUITE_WPI; + + kalMemCopy(prCmdKey->aucKeyMaterial, + (uint8_t *) prNewKey->aucWPIEK, 16); + + kalMemCopy(prCmdKey->aucKeyMaterial + 16, + (uint8_t *) prNewKey->aucWPICK, 16); + + kalMemCopy(prCmdKey->aucKeyRsc, (uint8_t *) prNewKey->aucPN, + 16); + + if (prCmdKey->ucTxKey) { + if (prStaRec) { + if (prCmdKey->ucKeyType) { /* AIS RSN STA */ + prCmdKey->ucWlanIndex = prStaRec->ucWlanIndex; + prStaRec->fgTransmitKeyExist = + TRUE; /* wait for CMD Done ? */ + } else { + ASSERT(FALSE); + } + } +#if 0 + if (fgAddTxBcKey || !prStaRec) { + + if ((prCmdKey->aucPeerAddr[0] + & prCmdKey->aucPeerAddr[1] + & prCmdKey->aucPeerAddr[2] + & prCmdKey->aucPeerAddr[3] + & prCmdKey->aucPeerAddr[4] + & prCmdKey->aucPeerAddr[5]) == 0xFF) { + prCmdKey->ucWlanIndex = + 255; /* AIS WEP Tx key */ + } else { /* Exist this case ? */ + ASSERT(FALSE); + /* prCmdKey->ucWlanIndex = */ + /* secPrivacySeekForBcEntry(prAdapter, */ + /* prBssInfo->ucBssIndex, */ + /* NETWORK_TYPE_AIS, */ + /* prCmdKey->aucPeerAddr, */ + /* prCmdKey->ucAlgorithmId, */ + /* prCmdKey->ucKeyId, */ + } + + prBssInfo->fgBcDefaultKeyExist = TRUE; + prBssInfo->ucBMCWlanIndex = + prCmdKey->ucWlanIndex; /* Saved for AIS WEP */ + prBssInfo->ucTxBcDefaultIdx = prCmdKey->ucKeyId; + } +#endif + } else { + /* Including IBSS RSN Rx BC key ? */ + if ((prCmdKey->aucPeerAddr[0] & prCmdKey->aucPeerAddr[1] & + prCmdKey->aucPeerAddr[2] & prCmdKey->aucPeerAddr[3] & + prCmdKey->aucPeerAddr[4] & prCmdKey->aucPeerAddr[5]) == + 0xFF) { + prCmdKey->ucWlanIndex = + WTBL_RESERVED_ENTRY; /* AIS WEP, should not have + * this case!! + */ + } else { + if (prStaRec) { /* AIS RSN Group key but addr is BSSID + */ + /* ASSERT(prStaRec->ucBMCWlanIndex < WTBL_SIZE) + */ + prCmdKey->ucWlanIndex = + secPrivacySeekForBcEntry(prAdapter, + prStaRec->ucBssIndex, + prStaRec->aucMacAddr, + prStaRec->ucIndex, + prCmdKey->ucAlgorithmId, + prCmdKey->ucKeyId); + prStaRec->ucWlanIndex = prCmdKey->ucWlanIndex; + } else { /* Exist this case ? */ + ASSERT(FALSE); + /* prCmdKey->ucWlanIndex = */ + /* secPrivacySeekForBcEntry(prAdapter, */ + /* prBssInfo->ucBssIndex, */ + /* NETWORK_TYPE_AIS, */ + /* prCmdKey->aucPeerAddr, */ + /* prCmdKey->ucAlgorithmId, */ + /* prCmdKey->ucKeyId, */ + } + } + } + + /* insert into prCmdQueue */ + kalEnqueueCommand(prGlueInfo, + (struct QUE_ENTRY *) prCmdInfo); + + /* wakeup txServiceThread later */ + GLUE_SET_EVENT(prGlueInfo); + + return WLAN_STATUS_PENDING; +} /* wlanoidSetAddKey */ +#endif + +#if CFG_ENABLE_WAKEUP_ON_LAN +uint32_t +wlanoidSetAddWakeupPattern(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct PARAM_PM_PACKET_PATTERN *prPacketPattern; + + DEBUGFUNC("wlanoidSetAddWakeupPattern"); + DBGLOG(REQ, LOUD, "\r\n"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(struct PARAM_PM_PACKET_PATTERN); + + if (u4SetBufferLen < sizeof(struct PARAM_PM_PACKET_PATTERN)) + return WLAN_STATUS_INVALID_LENGTH; + + ASSERT(pvSetBuffer); + + prPacketPattern = (struct PARAM_PM_PACKET_PATTERN *) + pvSetBuffer; + + /* FIXME: Send the struct to firmware */ + + return WLAN_STATUS_FAILURE; +} + +uint32_t +wlanoidSetRemoveWakeupPattern(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct PARAM_PM_PACKET_PATTERN *prPacketPattern; + + DEBUGFUNC("wlanoidSetAddWakeupPattern"); + DBGLOG(REQ, LOUD, "\r\n"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(struct PARAM_PM_PACKET_PATTERN); + + if (u4SetBufferLen < sizeof(struct PARAM_PM_PACKET_PATTERN)) + return WLAN_STATUS_INVALID_LENGTH; + + ASSERT(pvSetBuffer); + + prPacketPattern = (struct PARAM_PM_PACKET_PATTERN *) + pvSetBuffer; + + /* FIXME: Send the struct to firmware */ + + return WLAN_STATUS_FAILURE; +} + +uint32_t +wlanoidQueryEnableWakeup(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + uint32_t *pu4WakeupEventEnable; + + DEBUGFUNC("wlanoidQueryEnableWakeup"); + DBGLOG(REQ, LOUD, "\r\n"); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + *pu4QueryInfoLen = sizeof(uint32_t); + + if (u4QueryBufferLen < sizeof(uint32_t)) + return WLAN_STATUS_BUFFER_TOO_SHORT; + + pu4WakeupEventEnable = (uint32_t *) pvQueryBuffer; + + *pu4WakeupEventEnable = prAdapter->u4WakeupEventEnable; + + return WLAN_STATUS_SUCCESS; +} + +uint32_t +wlanoidSetEnableWakeup(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + uint32_t *pu4WakeupEventEnable; + + DEBUGFUNC("wlanoidSetEnableWakup"); + DBGLOG(REQ, LOUD, "\r\n"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(uint32_t); + + if (u4SetBufferLen < sizeof(uint32_t)) + return WLAN_STATUS_INVALID_LENGTH; + + ASSERT(pvSetBuffer); + + pu4WakeupEventEnable = (uint32_t *) pvSetBuffer; + prAdapter->u4WakeupEventEnable = *pu4WakeupEventEnable; + + /* FIXME: Send Command Event for setting + * wakeup-pattern / Magic Packet to firmware + */ + + return WLAN_STATUS_FAILURE; +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to configure PS related settings for WMM-PS + * test. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetWiFiWmmPsTest(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct PARAM_CUSTOM_WMM_PS_TEST_STRUCT *prWmmPsTestInfo; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + struct CMD_SET_WMM_PS_TEST_STRUCT rSetWmmPsTestParam; + uint16_t u2CmdBufLen; + struct PM_PROFILE_SETUP_INFO *prPmProfSetupInfo; + struct BSS_INFO *prBssInfo; + + DEBUGFUNC("wlanoidSetWiFiWmmPsTest"); + + ASSERT(prAdapter); + ASSERT(pvSetBuffer); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(struct + PARAM_CUSTOM_WMM_PS_TEST_STRUCT); + + prWmmPsTestInfo = (struct PARAM_CUSTOM_WMM_PS_TEST_STRUCT *) + pvSetBuffer; + + rSetWmmPsTestParam.ucBssIndex = + prWmmPsTestInfo->ucBssIdx; + rSetWmmPsTestParam.bmfgApsdEnAc = + prWmmPsTestInfo->bmfgApsdEnAc; + rSetWmmPsTestParam.ucIsEnterPsAtOnce = + prWmmPsTestInfo->ucIsEnterPsAtOnce; + rSetWmmPsTestParam.ucIsDisableUcTrigger = + prWmmPsTestInfo->ucIsDisableUcTrigger; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + rSetWmmPsTestParam.ucBssIndex); + prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; + prPmProfSetupInfo->ucBmpDeliveryAC = + (rSetWmmPsTestParam.bmfgApsdEnAc >> 4) & BITS(0, 3); + prPmProfSetupInfo->ucBmpTriggerAC = + rSetWmmPsTestParam.bmfgApsdEnAc & BITS(0, 3); + + u2CmdBufLen = sizeof(struct CMD_SET_WMM_PS_TEST_STRUCT); + +#if 0 + /* it will apply the disable trig or not immediately */ + if (prPmInfo->ucWmmPsDisableUcPoll + && prPmInfo->ucWmmPsConnWithTrig) + NIC_PM_WMM_PS_DISABLE_UC_TRIG(prAdapter, TRUE); + else + NIC_PM_WMM_PS_DISABLE_UC_TRIG(prAdapter, FALSE); +#endif + + rStatus = wlanSendSetQueryCmd(prAdapter, + CMD_ID_SET_WMM_PS_TEST_PARMS, + TRUE, FALSE, TRUE, + nicCmdEventSetCommon,/* TODO? */ + nicCmdTimeoutCommon, u2CmdBufLen, + (uint8_t *) &rSetWmmPsTestParam, NULL, 0); + + return rStatus; +} /* wlanoidSetWiFiWmmPsTest */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to configure enable/disable TX A-MPDU feature. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetTxAmpdu(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + uint32_t rStatus = WLAN_STATUS_SUCCESS; + struct CMD_TX_AMPDU rTxAmpdu; + uint16_t u2CmdBufLen; + u_int8_t *pfgEnable; + + DEBUGFUNC("wlanoidSetTxAmpdu"); + + ASSERT(prAdapter); + ASSERT(pvSetBuffer); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(u_int8_t); + + pfgEnable = (u_int8_t *) pvSetBuffer; + + rTxAmpdu.fgEnable = *pfgEnable; + + u2CmdBufLen = sizeof(struct CMD_TX_AMPDU); + + rStatus = wlanSendSetQueryCmd(prAdapter, CMD_ID_TX_AMPDU, + TRUE, FALSE, TRUE, NULL, NULL, + u2CmdBufLen, + (uint8_t *) &rTxAmpdu, NULL, 0); + + return rStatus; +} /* wlanoidSetTxAmpdu */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to configure reject/accept ADDBA Request. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetAddbaReject(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + uint32_t rStatus = WLAN_STATUS_SUCCESS; + struct CMD_ADDBA_REJECT rAddbaReject; + uint16_t u2CmdBufLen; + u_int8_t *pfgEnable; + + DEBUGFUNC("wlanoidSetAddbaReject"); + + ASSERT(prAdapter); + ASSERT(pvSetBuffer); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(u_int8_t); + + pfgEnable = (u_int8_t *) pvSetBuffer; + + rAddbaReject.fgEnable = *pfgEnable; + + u2CmdBufLen = sizeof(struct CMD_ADDBA_REJECT); + + rStatus = wlanSendSetQueryCmd(prAdapter, CMD_ID_ADDBA_REJECT, + TRUE, FALSE, TRUE, NULL, NULL, + u2CmdBufLen, + (uint8_t *) &rAddbaReject, NULL, 0); + + return rStatus; +} /* wlanoidSetAddbaReject */ + +#if CFG_SLT_SUPPORT + +uint32_t +wlanoidQuerySLTStatus(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + struct PARAM_MTK_SLT_TEST_STRUCT *prMtkSltInfo = + (struct PARAM_MTK_SLT_TEST_STRUCT *) NULL; + struct SLT_INFO *prSltInfo = (struct SLT_INFO *) NULL; + + DEBUGFUNC("wlanoidQuerySLTStatus"); + DBGLOG(REQ, LOUD, "\r\n"); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + + *pu4QueryInfoLen = sizeof(struct PARAM_MTK_SLT_TEST_STRUCT); + + if (u4QueryBufferLen < sizeof(struct + PARAM_MTK_SLT_TEST_STRUCT)) + return WLAN_STATUS_INVALID_LENGTH; + + ASSERT(pvQueryBuffer); + + prMtkSltInfo = (struct PARAM_MTK_SLT_TEST_STRUCT *) + pvQueryBuffer; + + prSltInfo = &(prAdapter->rWifiVar.rSltInfo); + + switch (prMtkSltInfo->rSltFuncIdx) { + case ENUM_MTK_SLT_FUNC_LP_SET: { + struct PARAM_MTK_SLT_LP_TEST_STRUCT *prLpSetting = + (struct PARAM_MTK_SLT_LP_TEST_STRUCT *) NULL; + + ASSERT(prMtkSltInfo->u4FuncInfoLen == sizeof( + struct PARAM_MTK_SLT_LP_TEST_STRUCT)); + + prLpSetting = (struct PARAM_MTK_SLT_LP_TEST_STRUCT *) + &prMtkSltInfo->unFuncInfoContent; + + prLpSetting->u4BcnRcvNum = prSltInfo->u4BeaconReceiveCnt; + } + break; + default: + /* TBD... */ + break; + } + + return rWlanStatus; +} /* wlanoidQuerySLTStatus */ + +uint32_t +wlanoidUpdateSLTMode(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + struct PARAM_MTK_SLT_TEST_STRUCT *prMtkSltInfo = + (struct PARAM_MTK_SLT_TEST_STRUCT *) NULL; + struct SLT_INFO *prSltInfo = (struct SLT_INFO *) NULL; + struct BSS_DESC *prBssDesc = (struct BSS_DESC *) NULL; + struct STA_RECORD *prStaRec = (struct STA_RECORD *) NULL; + struct BSS_INFO *prBssInfo = (struct BSS_INFO *) NULL; + uint8_t ucBssIndex = AIS_DEFAULT_INDEX; + + /* 1. Action: Update or Initial Set + * 2. Role. + * 3. Target MAC address. + * 4. RF BW & Rate Settings + */ + + DEBUGFUNC("wlanoidUpdateSLTMode"); + DBGLOG(REQ, LOUD, "\r\n"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(struct PARAM_MTK_SLT_TEST_STRUCT); + + if (u4SetBufferLen < sizeof(struct + PARAM_MTK_SLT_TEST_STRUCT)) + return WLAN_STATUS_INVALID_LENGTH; + + ASSERT(pvSetBuffer); + + prMtkSltInfo = (struct PARAM_MTK_SLT_TEST_STRUCT *) + pvSetBuffer; + + prSltInfo = &(prAdapter->rWifiVar.rSltInfo); + prBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + + switch (prMtkSltInfo->rSltFuncIdx) { + case ENUM_MTK_SLT_FUNC_INITIAL: { /* Initialize */ + struct PARAM_MTK_SLT_INITIAL_STRUCT *prMtkSltInit = + (struct PARAM_MTK_SLT_INITIAL_STRUCT *) NULL; + + ASSERT(prMtkSltInfo->u4FuncInfoLen == sizeof( + struct PARAM_MTK_SLT_INITIAL_STRUCT)); + + prMtkSltInit = (struct PARAM_MTK_SLT_INITIAL_STRUCT *) + &prMtkSltInfo->unFuncInfoContent; + + if (prSltInfo->prPseudoStaRec != NULL) { + /* The driver has been initialized. */ + prSltInfo->prPseudoStaRec = NULL; + } + + prSltInfo->prPseudoBssDesc = scanSearchExistingBssDesc( + prAdapter, BSS_TYPE_IBSS, + prMtkSltInit->aucTargetMacAddr, + prMtkSltInit->aucTargetMacAddr); + + prSltInfo->u2SiteID = prMtkSltInit->u2SiteID; + + /* Bandwidth 2.4G: Channel 1~14 + * Bandwidth 5G: *36, 40, 44, 48, 52, 56, 60, 64, + * *100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, + * 149, 153, *157, 161, + * 184, 188, 192, 196, 200, 204, 208, 212, *216 + */ + prSltInfo->ucChannel2G4 = 1 + (prSltInfo->u2SiteID % 4) * 5; + + switch (prSltInfo->ucChannel2G4) { + case 1: + prSltInfo->ucChannel5G = 36; + break; + case 6: + prSltInfo->ucChannel5G = 52; + break; + case 11: + prSltInfo->ucChannel5G = 104; + break; + case 16: + prSltInfo->ucChannel2G4 = 14; + prSltInfo->ucChannel5G = 161; + break; + default: + ASSERT(FALSE); + } + + if (prSltInfo->prPseudoBssDesc == NULL) { + do { + prSltInfo->prPseudoBssDesc = + scanAllocateBssDesc(prAdapter); + + if (prSltInfo->prPseudoBssDesc == NULL) { + rWlanStatus = WLAN_STATUS_FAILURE; + break; + } + prBssDesc = prSltInfo->prPseudoBssDesc; + + } while (FALSE); + } else { + prBssDesc = prSltInfo->prPseudoBssDesc; + } + + if (prBssDesc) { + prBssDesc->eBSSType = BSS_TYPE_IBSS; + + COPY_MAC_ADDR(prBssDesc->aucSrcAddr, + prMtkSltInit->aucTargetMacAddr); + COPY_MAC_ADDR(prBssDesc->aucBSSID, + prBssInfo->aucOwnMacAddr); + + prBssDesc->u2BeaconInterval = 100; + prBssDesc->u2ATIMWindow = 0; + prBssDesc->ucDTIMPeriod = 1; + + prBssDesc->u2IELength = 0; + + prBssDesc->fgIsERPPresent = TRUE; + prBssDesc->fgIsHTPresent = TRUE; + + prBssDesc->u2OperationalRateSet = BIT(RATE_36M_INDEX); + prBssDesc->u2BSSBasicRateSet = BIT(RATE_36M_INDEX); + prBssDesc->fgIsUnknownBssBasicRate = FALSE; + + prBssDesc->fgIsLargerTSF = TRUE; + + prBssDesc->eBand = BAND_2G4; + + prBssDesc->ucChannelNum = prSltInfo->ucChannel2G4; + + prBssDesc->ucPhyTypeSet = PHY_TYPE_SET_802_11ABGN; + + GET_CURRENT_SYSTIME(&prBssDesc->rUpdateTime); + } + } + break; + case ENUM_MTK_SLT_FUNC_RATE_SET: /* Update RF Settings. */ + if (prSltInfo->prPseudoStaRec == NULL) { + rWlanStatus = WLAN_STATUS_FAILURE; + } else { + struct PARAM_MTK_SLT_TR_TEST_STRUCT *prTRSetting = + (struct PARAM_MTK_SLT_TR_TEST_STRUCT *) NULL; + + ASSERT(prMtkSltInfo->u4FuncInfoLen == sizeof( + struct PARAM_MTK_SLT_TR_TEST_STRUCT)); + + prStaRec = prSltInfo->prPseudoStaRec; + prTRSetting = (struct PARAM_MTK_SLT_TR_TEST_STRUCT *) + &prMtkSltInfo->unFuncInfoContent; + + if (prTRSetting->rNetworkType == + PARAM_NETWORK_TYPE_OFDM5) { + prBssInfo->eBand = BAND_5G; + prBssInfo->ucPrimaryChannel = + prSltInfo->ucChannel5G; + } + if (prTRSetting->rNetworkType == + PARAM_NETWORK_TYPE_OFDM24) { + prBssInfo->eBand = BAND_2G4; + prBssInfo->ucPrimaryChannel = + prSltInfo->ucChannel2G4; + } + + if ((prTRSetting->u4FixedRate & FIXED_BW_DL40) != 0) { + /* RF 40 */ + /* It would controls RFBW capability in WTBL. */ + prStaRec->u2HtCapInfo |= + HT_CAP_INFO_SUP_CHNL_WIDTH; + /* This controls RF BW, RF BW would be 40 + * only if + * 1. PHY_TYPE_BIT_HT is TRUE. + * 2. SCO is SCA/SCB. + */ + prStaRec->ucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; + + /* U20/L20 Control. */ + switch (prTRSetting->u4FixedRate & 0xC000) { + case FIXED_EXT_CHNL_U20: + prBssInfo->eBssSCO = + CHNL_EXT_SCB; /* +2 */ + if (prTRSetting->rNetworkType == + PARAM_NETWORK_TYPE_OFDM5) { + prBssInfo->ucPrimaryChannel + += 2; + } else { + /* For channel 1, testing L20 at + * channel 8. AOSP + */ + SetTestChannel( + &prBssInfo->ucPrimaryChannel); + } + break; + case FIXED_EXT_CHNL_L20: + default: /* 40M */ + prBssInfo->eBssSCO = + CHNL_EXT_SCA; /* -2 */ + if (prTRSetting->rNetworkType == + PARAM_NETWORK_TYPE_OFDM5) { + prBssInfo->ucPrimaryChannel + -= 2; + } else { + /* For channel 11 / 14. testing + * U20 at channel 3. AOSP + */ + SetTestChannel( + &prBssInfo->ucPrimaryChannel); + } + break; + } + } else { + /* RF 20 */ + prStaRec->u2HtCapInfo &= + ~HT_CAP_INFO_SUP_CHNL_WIDTH; + prBssInfo->eBssSCO = CHNL_EXT_SCN; + } + + prBssInfo->fgErpProtectMode = FALSE; + prBssInfo->eHtProtectMode = HT_PROTECT_MODE_NONE; + prBssInfo->eGfOperationMode = GF_MODE_NORMAL; + + nicUpdateBss(prAdapter, prBssInfo->ucNetTypeIndex); + + prStaRec->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_20M | + HT_CAP_INFO_SHORT_GI_40M); + + switch (prTRSetting->u4FixedRate & 0xFF) { + case RATE_OFDM_54M: + prStaRec->u2DesiredNonHTRateSet = + BIT(RATE_54M_SW_INDEX); + break; + case RATE_OFDM_48M: + prStaRec->u2DesiredNonHTRateSet = + BIT(RATE_48M_SW_INDEX); + break; + case RATE_OFDM_36M: + prStaRec->u2DesiredNonHTRateSet = + BIT(RATE_36M_SW_INDEX); + break; + case RATE_OFDM_24M: + prStaRec->u2DesiredNonHTRateSet = + BIT(RATE_24M_SW_INDEX); + break; + case RATE_OFDM_6M: + prStaRec->u2DesiredNonHTRateSet = + BIT(RATE_6M_SW_INDEX); + break; + case RATE_CCK_11M_LONG: + prStaRec->u2DesiredNonHTRateSet = + BIT(RATE_11M_SW_INDEX); + break; + case RATE_CCK_1M_LONG: + prStaRec->u2DesiredNonHTRateSet = + BIT(RATE_1M_SW_INDEX); + break; + case RATE_GF_MCS_0: + prStaRec->u2DesiredNonHTRateSet = + BIT(RATE_HT_PHY_SW_INDEX); + prStaRec->u2HtCapInfo |= HT_CAP_INFO_HT_GF; + break; + case RATE_MM_MCS_7: + prStaRec->u2DesiredNonHTRateSet = + BIT(RATE_HT_PHY_SW_INDEX); + prStaRec->u2HtCapInfo &= ~HT_CAP_INFO_HT_GF; +#if 0 /* Only for Current Measurement Mode. */ + prStaRec->u2HtCapInfo |= + (HT_CAP_INFO_SHORT_GI_20M | + HT_CAP_INFO_SHORT_GI_40M); +#endif + break; + case RATE_GF_MCS_7: + prStaRec->u2DesiredNonHTRateSet = + BIT(RATE_HT_PHY_SW_INDEX); + prStaRec->u2HtCapInfo |= HT_CAP_INFO_HT_GF; + break; + default: + prStaRec->u2DesiredNonHTRateSet = + BIT(RATE_36M_SW_INDEX); + break; + } + + cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); + + cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); + + } + break; + case ENUM_MTK_SLT_FUNC_LP_SET: { /* Reset LP Test Result. */ + struct PARAM_MTK_SLT_LP_TEST_STRUCT *prLpSetting = + (struct PARAM_MTK_SLT_LP_TEST_STRUCT *) NULL; + + ASSERT(prMtkSltInfo->u4FuncInfoLen == sizeof( + struct PARAM_MTK_SLT_LP_TEST_STRUCT)); + + prLpSetting = (struct PARAM_MTK_SLT_LP_TEST_STRUCT *) + &prMtkSltInfo->unFuncInfoContent; + + if (prSltInfo->prPseudoBssDesc == NULL) { + /* Please initial SLT Mode first. */ + break; + } + prBssDesc = prSltInfo->prPseudoBssDesc; + + switch (prLpSetting->rLpTestMode) { + case ENUM_MTK_LP_TEST_NORMAL: + /* In normal mode, we would use target MAC address to be + * the BSSID. + */ + COPY_MAC_ADDR(prBssDesc->aucBSSID, + prBssInfo->aucOwnMacAddr); + prSltInfo->fgIsDUT = FALSE; + break; + case ENUM_MTK_LP_TEST_GOLDEN_SAMPLE: + /* 1. Lower AIFS of BCN queue. + * 2. Fixed Random Number tobe 0. + */ + prSltInfo->fgIsDUT = FALSE; + /* In LP test mode, we would use MAC address of Golden + * Sample to be the BSSID. + */ + COPY_MAC_ADDR(prBssDesc->aucBSSID, + prBssInfo->aucOwnMacAddr); + break; + case ENUM_MTK_LP_TEST_DUT: + /* 1. Enter Sleep Mode. + * 2. Fix random number a large value & enlarge AIFN of + * BCN queue. + */ + COPY_MAC_ADDR(prBssDesc->aucBSSID, + prBssDesc->aucSrcAddr); + prSltInfo->u4BeaconReceiveCnt = 0; + prSltInfo->fgIsDUT = TRUE; + break; + } + + } + + break; + default: + break; + } + + return WLAN_STATUS_FAILURE; + + return rWlanStatus; +} /* wlanoidUpdateSLTMode */ +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to query NVRAM value. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * \param[out] pvQueryBuf A pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the call + * failed due to invalid length of the query buffer, + * returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_FAILURE + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryNvramRead(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + struct PARAM_CUSTOM_EEPROM_RW_STRUCT *rNvRwInfo; + uint16_t u2Data; + u_int8_t fgStatus; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4Ofs = 0; + + DEBUGFUNC("wlanoidQueryNvramRead"); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + *pu4QueryInfoLen = sizeof(struct + PARAM_CUSTOM_EEPROM_RW_STRUCT); + + if (u4QueryBufferLen < sizeof(struct + PARAM_CUSTOM_EEPROM_RW_STRUCT)) + return WLAN_STATUS_INVALID_LENGTH; + + rNvRwInfo = (struct PARAM_CUSTOM_EEPROM_RW_STRUCT *) + pvQueryBuffer; + + if (rNvRwInfo->ucMethod == + PARAM_EEPROM_READ_METHOD_READ) { + u4Ofs = rNvRwInfo->info.rEeprom.ucEepromIndex << 1; + fgStatus = kalCfgDataRead16(prAdapter->prGlueInfo, + u4Ofs, /* change to byte offset */ + &u2Data); + if (fgStatus) { + rNvRwInfo->info.rEeprom.u2EepromData = u2Data; + DBGLOG(REQ, INFO, + "NVRAM Read: index=%#X, data=%#02X\r\n", + rNvRwInfo->info.rEeprom.ucEepromIndex, + u2Data); + } else { + DBGLOG(REQ, ERROR, "NVRAM Read Failed: index=%#x.\r\n", + rNvRwInfo->info.rEeprom.ucEepromIndex); + rStatus = WLAN_STATUS_FAILURE; + } + } else if (rNvRwInfo->ucMethod == + PARAM_EEPROM_READ_METHOD_GETSIZE) { + rNvRwInfo->info.rEeprom.u2EepromData = + MAX_CFG_FILE_WIFI_REC_SIZE; + DBGLOG(REQ, INFO, "EEPROM size =%d\r\n", + rNvRwInfo->info.rEeprom.u2EepromData); + } else if (rNvRwInfo->ucMethod == + PARAM_EEPROM_READ_NVRAM) { + u4Ofs = rNvRwInfo->info.rNvram.u2NvIndex; + fgStatus = kalCfgDataRead16(prAdapter->prGlueInfo, + u4Ofs, + &u2Data); + + if (fgStatus) { + rNvRwInfo->info.rNvram.u2NvData = u2Data & 0x00FF; + DBGLOG(REQ, INFO, + "index=%#X, data=%#02X\r\n", + rNvRwInfo->info.rNvram.u2NvIndex, + rNvRwInfo->info.rNvram.u2NvData); + } else { + DBGLOG(REQ, ERROR, "NVRAM Read Failed: index=%#x.\r\n", + rNvRwInfo->info.rNvram.u2NvIndex); + rStatus = WLAN_STATUS_FAILURE; + } + + } + + *pu4QueryInfoLen = sizeof(struct + PARAM_CUSTOM_EEPROM_RW_STRUCT); + + return rStatus; +} /* wlanoidQueryNvramRead */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to write NVRAM value. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_FAILURE + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetNvramWrite(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct PARAM_CUSTOM_EEPROM_RW_STRUCT *rNvRwInfo; + u_int8_t fgStatus = FALSE; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + + DEBUGFUNC("wlanoidSetNvramWrite"); + DBGLOG(INIT, LOUD, "\n"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(struct + PARAM_CUSTOM_EEPROM_RW_STRUCT); + + if (u4SetBufferLen < sizeof(struct + PARAM_CUSTOM_EEPROM_RW_STRUCT)) + return WLAN_STATUS_INVALID_LENGTH; + + ASSERT(pvSetBuffer); + + rNvRwInfo = (struct PARAM_CUSTOM_EEPROM_RW_STRUCT *) + pvSetBuffer; + + if (rNvRwInfo->ucMethod == PARAM_EEPROM_WRITE_NVRAM) + fgStatus = kalCfgDataWrite8(prAdapter->prGlueInfo, + rNvRwInfo->info.rNvram.u2NvIndex, + rNvRwInfo->info.rNvram.u2NvData & 0x00FF); + + DBGLOG(REQ, INFO, "status(%d),index=%#X, data=%#02X\n", + fgStatus, + rNvRwInfo->info.rNvram.u2NvIndex, + rNvRwInfo->info.rNvram.u2NvData); + + /*update nvram to firmware*/ + if (fgStatus == TRUE) + wlanLoadManufactureData(prAdapter, + kalGetConfiguration(prAdapter->prGlueInfo)); + else + fgStatus = kalCfgDataWrite16(prAdapter->prGlueInfo, + rNvRwInfo->info.rEeprom.ucEepromIndex << + 1, /* change to byte offset */ + rNvRwInfo->info.rEeprom.u2EepromData); + + if (fgStatus == FALSE) { + DBGLOG(REQ, ERROR, "NVRAM Write Failed.\r\n"); + rStatus = WLAN_STATUS_FAILURE; + } + + return rStatus; +} /* wlanoidSetNvramWrite */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to get the config data source type. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_FAILURE + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryCfgSrcType(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + ASSERT(prAdapter); + + *pu4QueryInfoLen = sizeof(enum ENUM_CFG_SRC_TYPE); + + if (kalIsConfigurationExist(prAdapter->prGlueInfo) == TRUE) + *(enum ENUM_CFG_SRC_TYPE *) pvQueryBuffer = + CFG_SRC_TYPE_NVRAM; + else + *(enum ENUM_CFG_SRC_TYPE *) pvQueryBuffer = + CFG_SRC_TYPE_EEPROM; + + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to get the config data source type. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_FAILURE + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryEepromType(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + ASSERT(prAdapter); + + *pu4QueryInfoLen = sizeof(enum ENUM_EEPROM_TYPE *); + +#if CFG_SUPPORT_NIC_CAPABILITY + if (prAdapter->fgIsEepromUsed == TRUE) + *(enum ENUM_EEPROM_TYPE *) pvQueryBuffer = + EEPROM_TYPE_PRESENT; + else + *(enum ENUM_EEPROM_TYPE *) pvQueryBuffer = EEPROM_TYPE_NO; +#else + *(enum ENUM_EEPROM_TYPE *) pvQueryBuffer = EEPROM_TYPE_NO; +#endif + + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to get the config data source type. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_FAILURE + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetCountryCode(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + uint8_t *pucCountry; + + ASSERT(prAdapter); + ASSERT(pvSetBuffer); + + if (regd_is_single_sku_en()) { + rlmDomainOidSetCountry(prAdapter, pvSetBuffer, + u4SetBufferLen); + *pu4SetInfoLen = u4SetBufferLen; + return WLAN_STATUS_SUCCESS; + } + + ASSERT(u4SetBufferLen == 2); + + *pu4SetInfoLen = 2; + + pucCountry = pvSetBuffer; + + prAdapter->rWifiVar.u2CountryCode = + (((uint16_t) pucCountry[0]) << 8) | ((uint16_t) pucCountry[1]); + + /* Force to re-search country code in regulatory domains */ + prAdapter->prDomainInfo = NULL; + rlmDomainSendCmd(prAdapter); + + /* Update supported channel list in channel table based on current + * country domain + */ + wlanUpdateChannelTable(prAdapter->prGlueInfo); + +#if CFG_SUPPORT_SAP_DFS_CHANNEL + if (aisGetConnectedBssInfo(prAdapter)) { + struct BSS_INFO *prAisBssInfo = + aisGetConnectedBssInfo(prAdapter); + + if (prAisBssInfo == NULL) { + return WLAN_STATUS_FAILURE; + } + + /* restore DFS channels table */ + wlanUpdateDfsChannelTable(prAdapter->prGlueInfo, + -1, /* p2p role index */ + prAisBssInfo->ucPrimaryChannel, /* primary channel */ + 0, /* bandwidth */ + 0, /* sco */ + 0 /* center frequency */); + } +#endif + + return WLAN_STATUS_SUCCESS; +} + +uint32_t +wlanoidSetScanMacOui(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + struct PARAM_BSS_MAC_OUI *prParamMacOui; + struct BSS_INFO *prBssInfo; + + ASSERT(prAdapter); + ASSERT(prAdapter->prGlueInfo); + ASSERT(pvSetBuffer); + ASSERT(u4SetBufferLen == sizeof(struct PARAM_BSS_MAC_OUI)); + + prParamMacOui = (struct PARAM_BSS_MAC_OUI *)pvSetBuffer; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prParamMacOui->ucBssIndex); + if (!prBssInfo) { + log_dbg(REQ, ERROR, "Invalid bss info (ind=%u)\n", + prParamMacOui->ucBssIndex); + return WLAN_STATUS_FAILURE; + } + + kalMemCopy(prBssInfo->ucScanOui, prParamMacOui->ucMacOui, MAC_OUI_LEN); + prBssInfo->fgIsScanOuiSet = TRUE; + *pu4SetInfoLen = MAC_OUI_LEN; + + return WLAN_STATUS_SUCCESS; +} + +#if 0 +uint32_t +wlanoidSetNoaParam(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct PARAM_CUSTOM_NOA_PARAM_STRUCT *prNoaParam; + struct CMD_CUSTOM_NOA_PARAM_STRUCT rCmdNoaParam; + + DEBUGFUNC("wlanoidSetNoaParam"); + DBGLOG(INIT, LOUD, "\n"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(struct + PARAM_CUSTOM_NOA_PARAM_STRUCT); + + if (u4SetBufferLen < sizeof(struct + PARAM_CUSTOM_NOA_PARAM_STRUCT)) + return WLAN_STATUS_INVALID_LENGTH; + + ASSERT(pvSetBuffer); + + prNoaParam = (struct PARAM_CUSTOM_NOA_PARAM_STRUCT *) + pvSetBuffer; + + kalMemZero(&rCmdNoaParam, + sizeof(struct CMD_CUSTOM_NOA_PARAM_STRUCT)); + rCmdNoaParam.u4NoaDurationMs = prNoaParam->u4NoaDurationMs; + rCmdNoaParam.u4NoaIntervalMs = prNoaParam->u4NoaIntervalMs; + rCmdNoaParam.u4NoaCount = prNoaParam->u4NoaCount; + + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_SET_NOA_PARAM, + TRUE, + FALSE, + TRUE, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_CUSTOM_NOA_PARAM_STRUCT), + (uint8_t *) &rCmdNoaParam, pvSetBuffer, + u4SetBufferLen); +} + +uint32_t +wlanoidSetOppPsParam(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct PARAM_CUSTOM_OPPPS_PARAM_STRUCT *prOppPsParam; + struct CMD_CUSTOM_OPPPS_PARAM_STRUCT rCmdOppPsParam; + + DEBUGFUNC("wlanoidSetOppPsParam"); + DBGLOG(INIT, LOUD, "\n"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(struct + PARAM_CUSTOM_OPPPS_PARAM_STRUCT); + + if (u4SetBufferLen < sizeof(struct + PARAM_CUSTOM_OPPPS_PARAM_STRUCT)) + return WLAN_STATUS_INVALID_LENGTH; + + ASSERT(pvSetBuffer); + + prOppPsParam = (struct PARAM_CUSTOM_OPPPS_PARAM_STRUCT *) + pvSetBuffer; + + kalMemZero(&rCmdOppPsParam, + sizeof(struct CMD_CUSTOM_OPPPS_PARAM_STRUCT)); + rCmdOppPsParam.u4CTwindowMs = prOppPsParam->u4CTwindowMs; + + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_SET_OPPPS_PARAM, + TRUE, + FALSE, + TRUE, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_CUSTOM_OPPPS_PARAM_STRUCT), + (uint8_t *) &rCmdOppPsParam, pvSetBuffer, + u4SetBufferLen); +} + +uint32_t +wlanoidSetUApsdParam(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct PARAM_CUSTOM_UAPSD_PARAM_STRUCT *prUapsdParam; + struct CMD_CUSTOM_UAPSD_PARAM_STRUCT rCmdUapsdParam; + struct PM_PROFILE_SETUP_INFO *prPmProfSetupInfo; + struct BSS_INFO *prBssInfo; + + DEBUGFUNC("wlanoidSetUApsdParam"); + DBGLOG(INIT, LOUD, "\n"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(struct + PARAM_CUSTOM_UAPSD_PARAM_STRUCT); + + if (u4SetBufferLen < sizeof(struct + PARAM_CUSTOM_UAPSD_PARAM_STRUCT)) + return WLAN_STATUS_INVALID_LENGTH; + + ASSERT(pvSetBuffer); + + prBssInfo = & + (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); + prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; + + prUapsdParam = (struct PARAM_CUSTOM_UAPSD_PARAM_STRUCT *) + pvSetBuffer; + + kalMemZero(&rCmdUapsdParam, + sizeof(struct CMD_CUSTOM_OPPPS_PARAM_STRUCT)); + rCmdUapsdParam.fgEnAPSD = prUapsdParam->fgEnAPSD; + prAdapter->rWifiVar.fgSupportUAPSD = prUapsdParam->fgEnAPSD; + + rCmdUapsdParam.fgEnAPSD_AcBe = prUapsdParam->fgEnAPSD_AcBe; + rCmdUapsdParam.fgEnAPSD_AcBk = prUapsdParam->fgEnAPSD_AcBk; + rCmdUapsdParam.fgEnAPSD_AcVo = prUapsdParam->fgEnAPSD_AcVo; + rCmdUapsdParam.fgEnAPSD_AcVi = prUapsdParam->fgEnAPSD_AcVi; + prPmProfSetupInfo->ucBmpDeliveryAC = + ((prUapsdParam->fgEnAPSD_AcBe << 0) | + (prUapsdParam->fgEnAPSD_AcBk << 1) | + (prUapsdParam->fgEnAPSD_AcVi << 2) | + (prUapsdParam->fgEnAPSD_AcVo << 3)); + prPmProfSetupInfo->ucBmpTriggerAC = + ((prUapsdParam->fgEnAPSD_AcBe << 0) | + (prUapsdParam->fgEnAPSD_AcBk << 1) | + (prUapsdParam->fgEnAPSD_AcVi << 2) | + (prUapsdParam->fgEnAPSD_AcVo << 3)); + + rCmdUapsdParam.ucMaxSpLen = prUapsdParam->ucMaxSpLen; + prPmProfSetupInfo->ucUapsdSp = prUapsdParam->ucMaxSpLen; + + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_SET_UAPSD_PARAM, + TRUE, + FALSE, + TRUE, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_CUSTOM_OPPPS_PARAM_STRUCT), + (uint8_t *)&rCmdUapsdParam, pvSetBuffer, + u4SetBufferLen); +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set BT profile or BT information and the + * driver will set the built-in PTA configuration into chip. + * + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetBT(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + + struct PTA_IPC *prPtaIpc; + + DEBUGFUNC("wlanoidSetBT.\n"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(struct PTA_IPC); + if (u4SetBufferLen != sizeof(struct PTA_IPC)) { + /* WARNLOG(("Invalid length %ld\n", u4SetBufferLen)); */ + return WLAN_STATUS_INVALID_LENGTH; + } + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, WARN, + "Fail to set BT profile because of ACPI_D3\n"); + return WLAN_STATUS_ADAPTER_NOT_READY; + } + + ASSERT(pvSetBuffer); + prPtaIpc = (struct PTA_IPC *) pvSetBuffer; + +#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS && CFG_SUPPORT_BCM_BWCS_DEBUG + DBGLOG(INIT, INFO, + "BCM BWCS CMD: BWCS CMD = %02x%02x%02x%02x\n", + prPtaIpc->u.aucBTPParams[0], prPtaIpc->u.aucBTPParams[1], + prPtaIpc->u.aucBTPParams[2], prPtaIpc->u.aucBTPParams[3]); + + DBGLOG(INIT, INFO, + "BCM BWCS CMD: aucBTPParams[0]=%02x, aucBTPParams[1]=%02x, aucBTPParams[2]=%02x, aucBTPParams[3]=%02x.\n", + prPtaIpc->u.aucBTPParams[0], prPtaIpc->u.aucBTPParams[1], + prPtaIpc->u.aucBTPParams[2], prPtaIpc->u.aucBTPParams[3]); + +#endif + + wlanSendSetQueryCmd(prAdapter, CMD_ID_SET_BWCS, TRUE, FALSE, FALSE, + NULL, NULL, sizeof(struct PTA_IPC), + (uint8_t *) prPtaIpc, NULL, 0); + + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to query current BT profile and BTCR values + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvQueryBuffer Pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufferLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number + * of bytes written into the query buffer. If the + * call failed due to invalid length of the query + * buffer, returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryBT(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + /* P_PARAM_PTA_IPC_T prPtaIpc; */ + /* UINT_32 u4QueryBuffLen; */ + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + *pu4QueryInfoLen = sizeof(struct PTA_IPC); + + /* Check for query buffer length */ + if (u4QueryBufferLen != sizeof(struct PTA_IPC)) { + DBGLOG(REQ, WARN, "Invalid length %u\n", u4QueryBufferLen); + return WLAN_STATUS_INVALID_LENGTH; + } + + ASSERT(pvQueryBuffer); + /* prPtaIpc = (P_PTA_IPC_T)pvQueryBuffer; */ + /* prPtaIpc->ucCmd = BT_CMD_PROFILE; */ + /* prPtaIpc->ucLen = sizeof(prPtaIpc->u); */ + /* nicPtaGetProfile(prAdapter, (PUINT_8)&prPtaIpc->u, &u4QueryBuffLen); + */ + + return WLAN_STATUS_SUCCESS; +} + +#if 0 +uint32_t +wlanoidQueryBtSingleAntenna(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + P_PTA_INFO_T prPtaInfo; + uint32_t *pu4SingleAntenna; + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + *pu4QueryInfoLen = sizeof(uint32_t); + + /* Check for query buffer length */ + if (u4QueryBufferLen != sizeof(uint32_t)) { + DBGLOG(REQ, WARN, "Invalid length %lu\n", u4QueryBufferLen); + return WLAN_STATUS_INVALID_LENGTH; + } + + ASSERT(pvQueryBuffer); + + prPtaInfo = &prAdapter->rPtaInfo; + pu4SingleAntenna = (uint32_t *) pvQueryBuffer; + + if (prPtaInfo->fgSingleAntenna) { + /* DBGLOG(INIT, INFO, (KERN_WARNING DRV_NAME + * "Q Single Ant = 1\r\n")); + */ + *pu4SingleAntenna = 1; + } else { + /* DBGLOG(INIT, INFO, (KERN_WARNING DRV_NAME + * "Q Single Ant = 0\r\n")); + */ + *pu4SingleAntenna = 0; + } + + return WLAN_STATUS_SUCCESS; +} + +uint32_t +wlanoidSetBtSingleAntenna(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + + uint32_t *pu4SingleAntenna; + uint32_t u4SingleAntenna; + P_PTA_INFO_T prPtaInfo; + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + prPtaInfo = &prAdapter->rPtaInfo; + + *pu4SetInfoLen = sizeof(uint32_t); + if (u4SetBufferLen != sizeof(uint32_t)) + return WLAN_STATUS_INVALID_LENGTH; + + if (IS_ARB_IN_RFTEST_STATE(prAdapter)) + return WLAN_STATUS_SUCCESS; + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, WARN, + "Fail to set antenna because of ACPI_D3\n"); + return WLAN_STATUS_ADAPTER_NOT_READY; + } + + ASSERT(pvSetBuffer); + pu4SingleAntenna = (uint32_t *) pvSetBuffer; + u4SingleAntenna = *pu4SingleAntenna; + + if (u4SingleAntenna == 0) { + /* DBGLOG(INIT, INFO, (KERN_WARNING DRV_NAME + * "Set Single Ant = 0\r\n")); + */ + prPtaInfo->fgSingleAntenna = FALSE; + } else { + /* DBGLOG(INIT, INFO, (KERN_WARNING DRV_NAME + * "Set Single Ant = 1\r\n")); + */ + prPtaInfo->fgSingleAntenna = TRUE; + } + ptaFsmRunEventSetConfig(prAdapter, &prPtaInfo->rPtaParam); + + return WLAN_STATUS_SUCCESS; +} + +#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS +uint32_t +wlanoidQueryPta(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + P_PTA_INFO_T prPtaInfo; + uint32_t *pu4Pta; + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + *pu4QueryInfoLen = sizeof(uint32_t); + + /* Check for query buffer length */ + if (u4QueryBufferLen != sizeof(uint32_t)) { + DBGLOG(REQ, WARN, "Invalid length %lu\n", u4QueryBufferLen); + return WLAN_STATUS_INVALID_LENGTH; + } + + ASSERT(pvQueryBuffer); + + prPtaInfo = &prAdapter->rPtaInfo; + pu4Pta = (uint32_t *) pvQueryBuffer; + + if (prPtaInfo->fgEnabled) { + /* DBGLOG(INIT, INFO, (KERN_WARNING DRV_NAME"PTA = 1\r\n")); */ + *pu4Pta = 1; + } else { + /* DBGLOG(INIT, INFO, (KERN_WARNING DRV_NAME"PTA = 0\r\n")); */ + *pu4Pta = 0; + } + + return WLAN_STATUS_SUCCESS; +} + +uint32_t +wlanoidSetPta(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + uint32_t *pu4PtaCtrl; + uint32_t u4PtaCtrl; + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(uint32_t); + if (u4SetBufferLen != sizeof(uint32_t)) + return WLAN_STATUS_INVALID_LENGTH; + + if (IS_ARB_IN_RFTEST_STATE(prAdapter)) + return WLAN_STATUS_SUCCESS; + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, WARN, + "Fail to set BT setting because of ACPI_D3\n"); + return WLAN_STATUS_ADAPTER_NOT_READY; + } + + ASSERT(pvSetBuffer); + pu4PtaCtrl = (uint32_t *) pvSetBuffer; + u4PtaCtrl = *pu4PtaCtrl; + + if (u4PtaCtrl == 0) { + /* DBGLOG(INIT, INFO, (KERN_WARNING DRV_NAME"Set Pta= 0\r\n")); + */ + nicPtaSetFunc(prAdapter, FALSE); + } else { + /* DBGLOG(INIT, INFO, (KERN_WARNING DRV_NAME"Set Pta= 1\r\n")); + */ + nicPtaSetFunc(prAdapter, TRUE); + } + + return WLAN_STATUS_SUCCESS; +} +#endif + +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set Tx power profile. + * + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetTxPower(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct SET_TXPWR_CTRL *pTxPwr = (struct SET_TXPWR_CTRL *) + pvSetBuffer; + struct SET_TXPWR_CTRL *prCmd; + uint32_t i; + uint32_t rStatus; + + DEBUGFUNC("wlanoidSetTxPower"); + DBGLOG(REQ, LOUD, "\r\n"); + + prCmd = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, + sizeof(struct SET_TXPWR_CTRL)); + + if (!prCmd) { + DBGLOG(REQ, ERROR, "prCmd not available\n"); + return WLAN_STATUS_FAILURE; + } + kalMemZero(prCmd, sizeof(struct SET_TXPWR_CTRL)); + prCmd->c2GLegacyStaPwrOffset = + pTxPwr->c2GLegacyStaPwrOffset; + prCmd->c2GHotspotPwrOffset = pTxPwr->c2GHotspotPwrOffset; + prCmd->c2GP2pPwrOffset = pTxPwr->c2GP2pPwrOffset; + prCmd->c2GBowPwrOffset = pTxPwr->c2GBowPwrOffset; + prCmd->c5GLegacyStaPwrOffset = + pTxPwr->c5GLegacyStaPwrOffset; + prCmd->c5GHotspotPwrOffset = pTxPwr->c5GHotspotPwrOffset; + prCmd->c5GP2pPwrOffset = pTxPwr->c5GP2pPwrOffset; + prCmd->c5GBowPwrOffset = pTxPwr->c5GBowPwrOffset; + prCmd->ucConcurrencePolicy = pTxPwr->ucConcurrencePolicy; + for (i = 0; i < 14; i++) + prCmd->acTxPwrLimit2G[i] = pTxPwr->acTxPwrLimit2G[i]; + + for (i = 0; i < 4; i++) + prCmd->acTxPwrLimit5G[i] = pTxPwr->acTxPwrLimit5G[i]; + + ASSERT(prAdapter); + ASSERT(pvSetBuffer); + +#if 0 + DBGLOG(INIT, INFO, "c2GLegacyStaPwrOffset=%d\n", + pTxPwr->c2GLegacyStaPwrOffset); + DBGLOG(INIT, INFO, "c2GHotspotPwrOffset=%d\n", + pTxPwr->c2GHotspotPwrOffset); + DBGLOG(INIT, INFO, "c2GP2pPwrOffset=%d\n", + pTxPwr->c2GP2pPwrOffset); + DBGLOG(INIT, INFO, "c2GBowPwrOffset=%d\n", + pTxPwr->c2GBowPwrOffset); + DBGLOG(INIT, INFO, "c5GLegacyStaPwrOffset=%d\n", + pTxPwr->c5GLegacyStaPwrOffset); + DBGLOG(INIT, INFO, "c5GHotspotPwrOffset=%d\n", + pTxPwr->c5GHotspotPwrOffset); + DBGLOG(INIT, INFO, "c5GP2pPwrOffset=%d\n", + pTxPwr->c5GP2pPwrOffset); + DBGLOG(INIT, INFO, "c5GBowPwrOffset=%d\n", + pTxPwr->c5GBowPwrOffset); + DBGLOG(INIT, INFO, "ucConcurrencePolicy=%d\n", + pTxPwr->ucConcurrencePolicy); + + for (i = 0; i < 14; i++) + DBGLOG(INIT, INFO, "acTxPwrLimit2G[%d]=%d\n", i, + pTxPwr->acTxPwrLimit2G[i]); + + for (i = 0; i < 4; i++) + DBGLOG(INIT, INFO, "acTxPwrLimit5G[%d]=%d\n", i, + pTxPwr->acTxPwrLimit5G[i]); +#endif + + rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ + CMD_ID_SET_TXPWR_CTRL, /* ucCID */ + TRUE, /* fgSetQuery */ + FALSE, /* fgNeedResp */ + TRUE, /* fgIsOid */ + nicCmdEventSetCommon, nicOidCmdTimeoutCommon, + sizeof(struct SET_TXPWR_CTRL), /* u4SetQueryInfoLen */ + (uint8_t *) prCmd, /* pucInfoBuffer */ + NULL, /* pvSetQueryBuffer */ + 0 /* u4SetQueryBufferLen */ + ); + + /* ASSERT(rStatus == WLAN_STATUS_PENDING); */ + cnmMemFree(prAdapter, prCmd); + + return rStatus; + +} + +uint32_t wlanSendMemDumpCmd(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen) { + struct PARAM_CUSTOM_MEM_DUMP_STRUCT *prMemDumpInfo; + struct CMD_DUMP_MEM *prCmdDumpMem; + struct CMD_DUMP_MEM rCmdDumpMem; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4MemSize = PARAM_MEM_DUMP_MAX_SIZE; + + uint32_t u4RemainLeng = 0; + uint32_t u4CurAddr = 0; + uint8_t ucFragNum = 0; + + prCmdDumpMem = &rCmdDumpMem; + prMemDumpInfo = (struct PARAM_CUSTOM_MEM_DUMP_STRUCT *) + pvQueryBuffer; + + u4RemainLeng = prMemDumpInfo->u4RemainLength; + u4CurAddr = prMemDumpInfo->u4Address + + prMemDumpInfo->u4Length; + ucFragNum = prMemDumpInfo->ucFragNum + 1; + + /* Query. If request length is larger than max length, do it as ping + * pong. Send a command and wait for a event. Send next command while + * the event is received. + */ + do { + uint32_t u4CurLeng = 0; + + if (u4RemainLeng > u4MemSize) { + u4CurLeng = u4MemSize; + u4RemainLeng -= u4MemSize; + } else { + u4CurLeng = u4RemainLeng; + u4RemainLeng = 0; + } + + prCmdDumpMem->u4Address = u4CurAddr; + prCmdDumpMem->u4Length = u4CurLeng; + prCmdDumpMem->u4RemainLength = u4RemainLeng; + prCmdDumpMem->ucFragNum = ucFragNum; +#if CFG_SUPPORT_QA_TOOL + prCmdDumpMem->u4IcapContent = prMemDumpInfo->u4IcapContent; +#endif /* CFG_SUPPORT_QA_TOOL */ + + DBGLOG(REQ, TRACE, "[%d] 0x%X, len %u, remain len %u\n", + ucFragNum, prCmdDumpMem->u4Address, + prCmdDumpMem->u4Length, prCmdDumpMem->u4RemainLength); + + rStatus = wlanSendSetQueryCmd(prAdapter, + CMD_ID_DUMP_MEM, + FALSE, + TRUE, + TRUE, + nicCmdEventQueryMemDump, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_DUMP_MEM), + (uint8_t *) prCmdDumpMem, + pvQueryBuffer, u4QueryBufferLen); + + } while (FALSE); + + return rStatus; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to dump memory. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * \param[out] pvQueryBuf A pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the call + * failed due to invalid length of the query buffer, + * returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryMemDump(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + struct PARAM_CUSTOM_MEM_DUMP_STRUCT *prMemDumpInfo; + + DEBUGFUNC("wlanoidQueryMemDump"); + DBGLOG(INIT, LOUD, "\n"); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + *pu4QueryInfoLen = sizeof(uint32_t); + + prMemDumpInfo = (struct PARAM_CUSTOM_MEM_DUMP_STRUCT *) + pvQueryBuffer; + DBGLOG(REQ, TRACE, "Dump 0x%X, len %u\n", + prMemDumpInfo->u4Address, prMemDumpInfo->u4Length); + + prMemDumpInfo->u4RemainLength = prMemDumpInfo->u4Length; + prMemDumpInfo->u4Length = 0; + prMemDumpInfo->ucFragNum = 0; + + return wlanSendMemDumpCmd(prAdapter, pvQueryBuffer, + u4QueryBufferLen); + +} /* end of wlanoidQueryMcrRead() */ + +#if CFG_ENABLE_WIFI_DIRECT +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used to set the p2p mode. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetP2pMode(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + uint32_t status = WLAN_STATUS_SUCCESS; + struct PARAM_CUSTOM_P2P_SET_STRUCT *prSetP2P = + (struct PARAM_CUSTOM_P2P_SET_STRUCT *) NULL; + /* P_MSG_P2P_NETDEV_REGISTER_T prP2pNetdevRegMsg = + * P_MSG_P2P_NETDEV_REGISTER_T)NULL; + */ + DEBUGFUNC("wlanoidSetP2pMode"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(struct PARAM_CUSTOM_P2P_SET_STRUCT); + if (u4SetBufferLen < sizeof(struct + PARAM_CUSTOM_P2P_SET_STRUCT)) { + DBGLOG(REQ, WARN, "Invalid length %u\n", u4SetBufferLen); + return WLAN_STATUS_INVALID_LENGTH; + } + + prSetP2P = (struct PARAM_CUSTOM_P2P_SET_STRUCT *) + pvSetBuffer; + + DBGLOG(P2P, TRACE, "Set P2P enable[%d] mode[%d]\n", + prSetP2P->u4Enable, prSetP2P->u4Mode); + + /* + * enable = 1, mode = 0 => init P2P network + * enable = 1, mode = 1 => init Soft AP network + * enable = 0 => uninit P2P/AP network + * enable = 1, mode = 2 => init dual Soft AP network + * enable = 1, mode = 3 => init AP+P2P network + */ + + + DBGLOG(P2P, TRACE, "P2P Compile as (%d)p2p-like interface\n", + KAL_P2P_NUM); + + if (prSetP2P->u4Mode >= RUNNING_P2P_MODE_NUM) { + DBGLOG(P2P, ERROR, "P2P interface mode(%d) is wrong\n", + prSetP2P->u4Mode); + ASSERT(0); + } + + if (prSetP2P->u4Enable) { + p2pSetMode(prSetP2P->u4Mode); + + if (p2pLaunch(prAdapter->prGlueInfo)) { + /* ToDo:: ASSERT */ + ASSERT(prAdapter->fgIsP2PRegistered); + if (prAdapter->rWifiVar.ucApUapsd + && (prSetP2P->u4Mode != RUNNING_P2P_MODE)) { + DBGLOG(OID, INFO, + "wlanoidSetP2pMode Default enable ApUapsd\n"); + setApUapsdEnable(prAdapter, TRUE); + } + prAdapter->u4P2pMode = prSetP2P->u4Mode; + } else { + DBGLOG(P2P, ERROR, "P2P Launch Failed\n"); + status = WLAN_STATUS_FAILURE; + } + + } else { + if (prAdapter->fgIsP2PRegistered) + p2pRemove(prAdapter->prGlueInfo); + + } + +#if 0 + prP2pNetdevRegMsg = (struct MSG_P2P_NETDEV_REGISTER *) + cnmMemAlloc(prAdapter, RAM_TYPE_MSG, + (sizeof(struct MSG_P2P_NETDEV_REGISTER))); + + if (prP2pNetdevRegMsg == NULL) { + ASSERT(FALSE); + status = WLAN_STATUS_RESOURCES; + return status; + } + + prP2pNetdevRegMsg->rMsgHdr.eMsgId = + MID_MNY_P2P_NET_DEV_REGISTER; + prP2pNetdevRegMsg->fgIsEnable = (prSetP2P->u4Enable == 1) ? + TRUE : FALSE; + prP2pNetdevRegMsg->ucMode = (uint8_t) prSetP2P->u4Mode; + + mboxSendMsg(prAdapter, MBOX_ID_0, + (struct MSG_HDR *) prP2pNetdevRegMsg, MSG_SEND_METHOD_BUF); +#endif + + return status; + +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set the GTK rekey data + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_BUFFER_TOO_SHORT + * \retval WLAN_STATUS_INVALID_DATA + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetGtkRekeyData(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct GLUE_INFO *prGlueInfo; + struct CMD_INFO *prCmdInfo; + uint8_t *pucCmdBuf; + struct mt66xx_chip_info *prChipInfo; + uint16_t cmd_size; + + DBGLOG(REQ, INFO, "wlanoidSetGtkRekeyData\n"); + + ASSERT(prAdapter); + ASSERT(pvSetBuffer); + ASSERT(pu4SetInfoLen); + prChipInfo = prAdapter->chip_info; + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(RSN, WARN, + "Fail in set rekey! (Adapter not ready). ACPI=D%d, Radio=%d\n", + prAdapter->rAcpiState, prAdapter->fgIsRadioOff); + return WLAN_STATUS_ADAPTER_NOT_READY; + } + + *pu4SetInfoLen = u4SetBufferLen; + + prGlueInfo = prAdapter->prGlueInfo; + cmd_size = prChipInfo->u2CmdTxHdrSize + + sizeof(struct PARAM_GTK_REKEY_DATA); + prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, cmd_size); + if (!prCmdInfo) { + DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); + return WLAN_STATUS_FAILURE; + } + + /* compose PARAM_GTK_REKEY_DATA cmd pkt */ + prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; + prCmdInfo->u2InfoBufLen = cmd_size; + prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; + prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; + prCmdInfo->fgIsOid = TRUE; + prCmdInfo->ucCID = CMD_ID_SET_GTK_REKEY_DATA; + prCmdInfo->fgSetQuery = TRUE; + prCmdInfo->fgNeedResp = FALSE; + prCmdInfo->u4SetInfoLen = u4SetBufferLen; + prCmdInfo->pvInformationBuffer = pvSetBuffer; + prCmdInfo->u4InformationBufferLength = u4SetBufferLen; + + /* Setup WIFI_CMD_T */ + NIC_FILL_CMD_TX_HDR(prAdapter, + prCmdInfo->pucInfoBuffer, + prCmdInfo->u2InfoBufLen, + prCmdInfo->ucCID, + CMD_PACKET_TYPE_ID, + &prCmdInfo->ucCmdSeqNum, + prCmdInfo->fgSetQuery, + &pucCmdBuf, FALSE, 0, S2D_INDEX_CMD_H2N); + + kalMemCopy(pucCmdBuf, (uint8_t *) pvSetBuffer, + u4SetBufferLen); + + /* insert into prCmdQueue */ + kalEnqueueCommand(prGlueInfo, + (struct QUE_ENTRY *) prCmdInfo); + + /* wakeup txServiceThread later */ + GLUE_SET_EVENT(prGlueInfo); + + return WLAN_STATUS_PENDING; + +} /* wlanoidSetGtkRekeyData */ + +#if CFG_SUPPORT_SCHED_SCAN +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to request starting of schedule scan + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_ADAPTER_NOT_READY + * \retval WLAN_STATUS_INVALID_LENGTH + * \retval WLAN_STATUS_INVALID_DATA + * + * \note The setting buffer PARAM_SCHED_SCAN_REQUEST_EXT_T + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetStartSchedScan(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + struct PARAM_SCHED_SCAN_REQUEST *prSchedScanRequest = + (struct PARAM_SCHED_SCAN_REQUEST *) pvSetBuffer; + uint8_t ucBssIndex; + + if (pvSetBuffer == NULL) + return WLAN_STATUS_INVALID_DATA; + + ucBssIndex = prSchedScanRequest->ucBssIndex; + + DEBUGFUNC("wlanoidSetStartSchedScan()"); + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, WARN, + "Fail in set scheduled scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", + prAdapter->rAcpiState, prAdapter->fgIsRadioOff); + return WLAN_STATUS_ADAPTER_NOT_READY; + } + + ASSERT(pu4SetInfoLen); + *pu4SetInfoLen = 0; + + if (u4SetBufferLen != sizeof(struct + PARAM_SCHED_SCAN_REQUEST)) + return WLAN_STATUS_INVALID_LENGTH; + else if (kalGetMediaStateIndicated(prAdapter->prGlueInfo, + ucBssIndex) == + MEDIA_STATE_CONNECTED + && prAdapter->fgEnOnlineScan == FALSE) + return WLAN_STATUS_FAILURE; + + if (prAdapter->fgIsRadioOff) { + DBGLOG(REQ, WARN, + "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", + prAdapter->rAcpiState, prAdapter->fgIsRadioOff); + goto success; + } + + if (!scnFsmSchedScanRequest(prAdapter, prSchedScanRequest)) { + DBGLOG(REQ, WARN, "scnFsmSchedScanRequest failure !!\n"); + return WLAN_STATUS_FAILURE; + } + +success: + prAdapter->prGlueInfo->prSchedScanRequest = prSchedScanRequest; + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to request termination of schedule scan + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_ADAPTER_NOT_READY + * \retval WLAN_STATUS_INVALID_LENGTH + * \retval WLAN_STATUS_INVALID_DATA + * + * \note The setting buffer PARAM_SCHED_SCAN_REQUEST_EXT_T + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetStopSchedScan(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + uint32_t ret; + struct PARAM_SCHED_SCAN_REQUEST *prSchedScanRequest = + prAdapter->prGlueInfo->prSchedScanRequest; + + ASSERT(prAdapter); + + /* ask SCN module to stop scan request */ + if (scnFsmSchedScanStopRequest(prAdapter) == TRUE) { + kalMemFree(prSchedScanRequest->pucChannels, + VIR_MEM_TYPE, prSchedScanRequest->ucChnlNum); + kalMemFree(prSchedScanRequest->pucIE, + VIR_MEM_TYPE, + prGlueInfo->prSchedScanRequest->u4IELength); + kalMemFree(prSchedScanRequest, + VIR_MEM_TYPE, + sizeof(struct PARAM_SCHED_SCAN_REQUEST)); + prAdapter->prGlueInfo->prSchedScanRequest = NULL; + ret = WLAN_STATUS_SUCCESS; + } else { + DBGLOG(REQ, WARN, "scnFsmSchedScanStopRequest failed.\n"); + ret = WLAN_STATUS_RESOURCES; + } + return ret; +} +#endif /* CFG_SUPPORT_SCHED_SCAN */ + +#if CFG_M0VE_BA_TO_DRIVER +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to reset BA scoreboard. + * + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanoidResetBAScoreboard(IN struct ADAPTER * + prAdapter, IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen) { + uint32_t rStatus; + + DEBUGFUNC("wlanoidResetBAScoreboard"); + DBGLOG(REQ, WARN, "[Puff]wlanoidResetBAScoreboard\n"); + + ASSERT(prAdapter); + ASSERT(pvSetBuffer); + + rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ + CMD_ID_RESET_BA_SCOREBOARD, /* ucCID */ + TRUE, /* fgSetQuery */ + FALSE, /* fgNeedResp */ + TRUE, /* fgIsOid */ + NULL, /* pfCmdDoneHandler */ + NULL, /* pfCmdTimeoutHandler */ + u4SetBufferLen, /* u4SetQueryInfoLen */ + (uint8_t *) pvSetBuffer, /* pucInfoBuffer */ + NULL, /* pvSetQueryBuffer */ + 0 /* u4SetQueryBufferLen */ + ); + + /* ASSERT(rStatus == WLAN_STATUS_PENDING); */ + + return rStatus; + +} + +#endif + +#if CFG_SUPPORT_BATCH_SCAN + +#define CMD_WLS_BATCHING "WLS_BATCHING" + +#define BATCHING_SET "SET" +#define BATCHING_GET "GET" +#define BATCHING_STOP "STOP" + +#define PARAM_SCANFREQ "SCANFREQ" +#define PARAM_MSCAN "MSCAN" +#define PARAM_BESTN "BESTN" +#define PARAM_CHANNEL "CHANNEL" +#define PARAM_RTT "RTT" + +uint32_t +batchSetCmd(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4WritenLen) { + struct CHANNEL_INFO *prRfChannelInfo; + struct CMD_BATCH_REQ rCmdBatchReq; + + uint32_t rStatus = WLAN_STATUS_SUCCESS; + int8_t *head, *p, *p2; + uint32_t tokens; + int32_t scanfreq, mscan, bestn, rtt; + char *pcTemp; + /* CHAR c_scanfreq[4], c_mscan[4], c_bestn[4], c_rtt[4], c_channel[100]; + */ + /* INT_32 ch_type; */ + uint32_t u4Value = 0; + int32_t i4Ret = 0; + + DBGLOG(SCN, TRACE, "[BATCH] command=%s, len=%u\n", + (char *)pvSetBuffer, u4SetBufferLen); + + if (!pu4WritenLen) + return -EINVAL; + *pu4WritenLen = 0; + + if (u4SetBufferLen < kalStrLen(CMD_WLS_BATCHING)) { + DBGLOG(SCN, TRACE, "[BATCH] invalid len %d\n", + u4SetBufferLen); + return -EINVAL; + } + + head = pvSetBuffer + kalStrLen(CMD_WLS_BATCHING) + 1; + kalMemSet(&rCmdBatchReq, 0, sizeof(struct CMD_BATCH_REQ)); + + if (!kalStrnCmp(head, BATCHING_SET, + kalStrLen(BATCHING_SET))) { + + DBGLOG(SCN, TRACE, "XXX Start Batch Scan XXX\n"); + + head += kalStrLen(BATCHING_SET) + 1; + + /* SCANFREQ, MSCAN, BESTN */ + tokens = sscanf(head, "SCANFREQ=%d MSCAN=%d BESTN=%d", + &scanfreq, &mscan, &bestn); + if (tokens != 3) { + DBGLOG(SCN, TRACE, + "[BATCH] Parse fail: tokens=%d, SCANFREQ=%d MSCAN=%d BESTN=%d\n", + tokens, scanfreq, mscan, bestn); + return -EINVAL; + } + /* RTT */ + p = kalStrStr(head, PARAM_RTT); + if (!p) { + DBGLOG(SCN, TRACE, "[BATCH] Parse RTT fail. head=%s\n", + head); + return -EINVAL; + } + tokens = sscanf(p, "RTT=%d", &rtt); + if (tokens != 1) { + DBGLOG(SCN, TRACE, + "[BATCH] Parse fail: tokens=%d, rtt=%d\n", + tokens, rtt); + return -EINVAL; + } + /* CHANNEL */ + p = kalStrStr(head, PARAM_CHANNEL); + if (!p) { + DBGLOG(SCN, TRACE, "[BATCH] Parse CHANNEL fail(1)\n"); + return -EINVAL; + } + head = p; + p = kalStrChr(head, '>'); + if (!p) { + DBGLOG(SCN, TRACE, "[BATCH] Parse CHANNEL fail(2)\n"); + return -EINVAL; + } + /* else { + * p = '.'; // remove '>' because sscanf can not parse <%s> + * } + */ + /* tokens = sscanf(head, "CHANNEL=<%s", c_channel); + * if (tokens != 1) { + * DBGLOG(SCN, TRACE, "[BATCH] Parse fail: tokens=%d, + * CHANNEL=<%s>\n", tokens, c_channel); + * return -EINVAL; + * } + */ + rCmdBatchReq.ucChannelType = SCAN_CHANNEL_SPECIFIED; + rCmdBatchReq.ucChannelListNum = 0; + prRfChannelInfo = &rCmdBatchReq.arChannelList[0]; + p = head + kalStrLen(PARAM_CHANNEL) + 2; /* c_channel; */ + pcTemp = (char *)p; + while ((p2 = kalStrSep(&pcTemp, ",")) != NULL) { + if (p2 == NULL || *p2 == 0) + break; + if (*p2 == '\0') + continue; + if (*p2 == 'A') { + rCmdBatchReq.ucChannelType = + rCmdBatchReq.ucChannelType == + SCAN_CHANNEL_2G4 ? + SCAN_CHANNEL_FULL : SCAN_CHANNEL_5G; + } else if (*p2 == 'B') { + rCmdBatchReq.ucChannelType = + rCmdBatchReq.ucChannelType == + SCAN_CHANNEL_5G ? + SCAN_CHANNEL_FULL : SCAN_CHANNEL_2G4; + } else { + + /* Translate Freq from MHz to channel number. */ + /* prRfChannelInfo->ucChannelNum = + * kalStrtol(p2, NULL, 0); + */ + i4Ret = kalkStrtou32(p2, 0, &u4Value); + if (i4Ret) + DBGLOG(SCN, TRACE, + "parse ucChannelNum error i4Ret=%d\n", + i4Ret); + prRfChannelInfo->ucChannelNum = + (uint8_t) u4Value; + DBGLOG(SCN, TRACE, + "Scanning Channel:%d, freq: %d\n", + prRfChannelInfo->ucChannelNum, + nicChannelNum2Freq( + prRfChannelInfo->ucChannelNum)); + prRfChannelInfo->ucBand = + prRfChannelInfo->ucChannelNum < 15 + ? BAND_2G4 : BAND_5G; + + rCmdBatchReq.ucChannelListNum++; + if (rCmdBatchReq.ucChannelListNum >= 32) + break; + prRfChannelInfo++; + } + } + + /* set channel for test */ +#if 0 + rCmdBatchReq.ucChannelType = + 4; /* SCAN_CHANNEL_SPECIFIED; */ + rCmdBatchReq.ucChannelListNum = 0; + prRfChannelInfo = &rCmdBatchReq.arChannelList[0]; + for (i = 1; i <= 14; i++) { + + /* filter out some */ + if (i == 1 || i == 5 || i == 11) + continue; + + /* Translate Freq from MHz to channel number. */ + prRfChannelInfo->ucChannelNum = i; + DBGLOG(SCN, TRACE, "Scanning Channel:%d, freq: %d\n", + prRfChannelInfo->ucChannelNum, + nicChannelNum2Freq( + prRfChannelInfo->ucChannelNum)); + prRfChannelInfo->ucBand = BAND_2G4; + + rCmdBatchReq.ucChannelListNum++; + prRfChannelInfo++; + } +#endif +#if 0 + rCmdBatchReq.ucChannelType = 0; /* SCAN_CHANNEL_FULL; */ +#endif + + rCmdBatchReq.u4Scanfreq = scanfreq; + rCmdBatchReq.ucMScan = mscan > CFG_BATCH_MAX_MSCAN ? + CFG_BATCH_MAX_MSCAN : mscan; + rCmdBatchReq.ucBestn = bestn; + rCmdBatchReq.ucRtt = rtt; + DBGLOG(SCN, TRACE, + "[BATCH] SCANFREQ=%d MSCAN=%d BESTN=%d RTT=%d\n", + rCmdBatchReq.u4Scanfreq, rCmdBatchReq.ucMScan, + rCmdBatchReq.ucBestn, rCmdBatchReq.ucRtt); + + if (rCmdBatchReq.ucChannelType != SCAN_CHANNEL_SPECIFIED) { + DBGLOG(SCN, TRACE, "[BATCH] CHANNELS = %s\n", + rCmdBatchReq.ucChannelType == SCAN_CHANNEL_FULL ? + "FULL" : rCmdBatchReq.ucChannelType == + SCAN_CHANNEL_2G4 ? "2.4G all" : "5G all"); + } else { + DBGLOG(SCN, TRACE, "[BATCH] CHANNEL list\n"); + prRfChannelInfo = &rCmdBatchReq.arChannelList[0]; + for (tokens = 0; tokens < rCmdBatchReq.ucChannelListNum; + tokens++) { + DBGLOG(SCN, TRACE, "[BATCH] %s, %d\n", + prRfChannelInfo->ucBand + == BAND_2G4 ? "2.4G" : "5G", + prRfChannelInfo->ucChannelNum); + prRfChannelInfo++; + } + } + + rCmdBatchReq.ucSeqNum = 1; + rCmdBatchReq.ucNetTypeIndex = KAL_NETWORK_TYPE_AIS_INDEX; + rCmdBatchReq.ucCmd = SCAN_BATCH_REQ_START; + + *pu4WritenLen = kalSnprintf(pvSetBuffer, 3, "%d", + rCmdBatchReq.ucMScan); + + } else if (!kalStrnCmp(head, BATCHING_STOP, + kalStrLen(BATCHING_STOP))) { + + DBGLOG(SCN, TRACE, "XXX Stop Batch Scan XXX\n"); + + rCmdBatchReq.ucSeqNum = 1; + rCmdBatchReq.ucNetTypeIndex = KAL_NETWORK_TYPE_AIS_INDEX; + rCmdBatchReq.ucCmd = SCAN_BATCH_REQ_STOP; + } else { + return -EINVAL; + } + + rStatus = wlanSendSetQueryCmd(prAdapter, CMD_ID_SET_BATCH_REQ, + TRUE, FALSE, TRUE, NULL, NULL, + sizeof(struct CMD_BATCH_REQ), + (uint8_t *) &rCmdBatchReq, NULL, 0); + + /* kalMemSet(pvSetBuffer, 0, u4SetBufferLen); */ + /* rStatus = kalSnprintf(pvSetBuffer, 2, "%s", "OK"); */ + + /* exit: */ + return rStatus; +} + +uint32_t +batchGetCmd(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + struct CMD_BATCH_REQ rCmdBatchReq; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + struct EVENT_BATCH_RESULT *prEventBatchResult; + /* UINT_32 i; */ + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + prEventBatchResult = (struct EVENT_BATCH_RESULT *) + pvQueryBuffer; + + DBGLOG(SCN, TRACE, "XXX Get Batch Scan Result (%d) XXX\n", + prEventBatchResult->ucScanCount); + + *pu4QueryInfoLen = sizeof(struct EVENT_BATCH_RESULT); + + rCmdBatchReq.ucSeqNum = 2; + rCmdBatchReq.ucCmd = SCAN_BATCH_REQ_RESULT; + rCmdBatchReq.ucMScan = + prEventBatchResult->ucScanCount; /* Get which round result */ + + rStatus = wlanSendSetQueryCmd(prAdapter, + CMD_ID_SET_BATCH_REQ, + FALSE, + TRUE, + TRUE, + nicCmdEventBatchScanResult, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_BATCH_REQ), + (uint8_t *) &rCmdBatchReq, + (void *) pvQueryBuffer, + u4QueryBufferLen); + + return rStatus; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] prAdapter Pointer to the Adapter structure + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set + * \param[in] u4SetBufferLen The length of the set buffer + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed due to invalid length of + * the set buffer, returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. + * \retval WLAN_STATUS_INVALID_LENGTH + * + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetBatchScanReq(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + return batchSetCmd(prAdapter, pvSetBuffer, u4SetBufferLen, + pu4SetInfoLen); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * \param[out] pvQueryBuffer A pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufferLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the call + * failed due to invalid length of the query buffer, + * returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryBatchScanResult(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + return batchGetCmd(prAdapter, pvQueryBuffer, + u4QueryBufferLen, pu4QueryInfoLen); + +} /* end of wlanoidQueryBatchScanResult() */ + +#endif /* CFG_SUPPORT_BATCH_SCAN */ + +#if CFG_SUPPORT_PASSPOINT +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called by HS2.0 to set the assoc info, which is needed + * to add to Association request frame while join HS2.0 AP. + * + * \param[in] prAdapter Pointer to the Adapter structure + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set + * \param[in] u4SetBufferLen The length of the set buffer + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed due to invalid length of + * the set buffer, returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. + * \retval WLAN_STATUS_INVALID_LENGTH + * + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetHS20Info(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct IE_HS20_INDICATION *prHS20IndicationIe; + struct HS20_INFO *prHS20Info; + uint8_t ucBssIndex = 0; + + ASSERT(prAdapter); + ASSERT(pvSetBuffer); + ASSERT(pu4SetInfoLen); + + DEBUGFUNC("wlanoidSetHS20AssocInfo"); + DBGLOG(OID, LOUD, "\r\n"); + + if (u4SetBufferLen == 0) + return WLAN_STATUS_INVALID_LENGTH; + + ucBssIndex = GET_IOCTL_BSSIDX(prAdapter); + + prHS20Info = aisGetHS20Info(prAdapter, ucBssIndex); + + *pu4SetInfoLen = u4SetBufferLen; + + prHS20IndicationIe = (struct IE_HS20_INDICATION *) + pvSetBuffer; + + prHS20Info->ucHotspotConfig = + prHS20IndicationIe->ucHotspotConfig; + prHS20Info->fgConnectHS20AP = TRUE; + + DBGLOG(SEC, TRACE, "HS20 IE sz %u\n", u4SetBufferLen); + + return WLAN_STATUS_SUCCESS; + +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set_bssid_pool + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer Pointer to the buffer that holds the data to be + * set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + * \retval WLAN_STATUS_ADAPTER_NOT_READY + * \retval WLAN_STATUS_MULTICAST_FULL + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetHS20BssidPool(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + uint8_t ucBssIndex = 0; + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + if (u4SetBufferLen) + ASSERT(pvSetBuffer); + + if (u4SetBufferLen < sizeof(struct + PARAM_HS20_SET_BSSID_POOL)) { + *pu4SetInfoLen = sizeof(struct PARAM_HS20_SET_BSSID_POOL); + return WLAN_STATUS_BUFFER_TOO_SHORT; + } + + ucBssIndex = GET_IOCTL_BSSIDX(prAdapter); + + DBGLOG(REQ, LOUD, "ucBssIndex %d\n", ucBssIndex); + + rWlanStatus = hs20SetBssidPool(prAdapter, pvSetBuffer, + ucBssIndex); + + return rWlanStatus; +} /* end of wlanoidSendHS20GASRequest() */ + +#endif /* CFG_SUPPORT_PASSPOINT */ + +#if CFG_SUPPORT_SNIFFER +uint32_t +wlanoidSetMonitor(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct PARAM_CUSTOM_MONITOR_SET_STRUCT *prMonitorSetInfo; + struct CMD_MONITOR_SET_INFO rCmdMonitorSetInfo; + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + + DEBUGFUNC("wlanoidSetMonitor"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(struct + PARAM_CUSTOM_MONITOR_SET_STRUCT); + + if (u4SetBufferLen < sizeof(struct + PARAM_CUSTOM_MONITOR_SET_STRUCT)) + return WLAN_STATUS_INVALID_LENGTH; + + ASSERT(pvSetBuffer); + + prMonitorSetInfo = (struct PARAM_CUSTOM_MONITOR_SET_STRUCT + *) pvSetBuffer; + + rCmdMonitorSetInfo.ucEnable = prMonitorSetInfo->ucEnable; + rCmdMonitorSetInfo.ucBand = prMonitorSetInfo->ucBand; + rCmdMonitorSetInfo.ucPriChannel = + prMonitorSetInfo->ucPriChannel; + rCmdMonitorSetInfo.ucSco = prMonitorSetInfo->ucSco; + rCmdMonitorSetInfo.ucChannelWidth = + prMonitorSetInfo->ucChannelWidth; + rCmdMonitorSetInfo.ucChannelS1 = + prMonitorSetInfo->ucChannelS1; + rCmdMonitorSetInfo.ucChannelS2 = + prMonitorSetInfo->ucChannelS2; + + rWlanStatus = wlanSendSetQueryCmd(prAdapter, + CMD_ID_SET_MONITOR, + TRUE, + FALSE, + TRUE, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_MONITOR_SET_INFO), + (uint8_t *) &rCmdMonitorSetInfo, + pvSetBuffer, + u4SetBufferLen); + + return rWlanStatus; +} +#endif + +#if CFG_SUPPORT_MSP +uint32_t +wlanoidQueryWlanInfo(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + DEBUGFUNC("wlanoidQueryWlanInfo"); + + return wlanQueryWlanInfo(prAdapter, pvQueryBuffer, u4QueryBufferLen, + pu4QueryInfoLen, TRUE); +} + +uint32_t +wlanQueryWlanInfo(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen, + IN uint8_t fgIsOid) { + struct PARAM_HW_WLAN_INFO *prHwWlanInfo; + + DEBUGFUNC("wlanQueryWlanInfo"); + DBGLOG(REQ, LOUD, "\n"); + + ASSERT(prAdapter); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + ASSERT(pu4QueryInfoLen); + + *pu4QueryInfoLen = sizeof(struct PARAM_HW_WLAN_INFO); + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, WARN, + "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", + prAdapter->rAcpiState, prAdapter->fgIsRadioOff); + *pu4QueryInfoLen = sizeof(uint32_t); + return WLAN_STATUS_ADAPTER_NOT_READY; + } else if (u4QueryBufferLen < sizeof(struct PARAM_HW_WLAN_INFO)) { + DBGLOG(REQ, WARN, "Too short length %u\n", + u4QueryBufferLen); + return WLAN_STATUS_INVALID_LENGTH; + } + + prHwWlanInfo = (struct PARAM_HW_WLAN_INFO *)pvQueryBuffer; + DBGLOG(RSN, INFO, + "MT6632 : wlanoidQueryWlanInfo index = %d\n", + prHwWlanInfo->u4Index); + + /* *pu4QueryInfoLen = 8 + prRxStatistics->u4TotalNum; */ + + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_WTBL_INFO, + FALSE, + TRUE, + fgIsOid, + nicCmdEventQueryWlanInfo, + nicOidCmdTimeoutCommon, + sizeof(struct PARAM_HW_WLAN_INFO), + (uint8_t *)prHwWlanInfo, + pvQueryBuffer, u4QueryBufferLen); + +} /* wlanoidQueryWlanInfo */ + +uint32_t +wlanoidQueryMibInfo(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + DEBUGFUNC("wlanoidQueryMibInfo"); + + return wlanQueryMibInfo(prAdapter, pvQueryBuffer, u4QueryBufferLen, + pu4QueryInfoLen, TRUE); +} + +uint32_t +wlanQueryMibInfo(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen, + IN uint8_t fgIsOid) +{ + struct PARAM_HW_MIB_INFO *prHwMibInfo; + + DEBUGFUNC("wlanoidQueryMibInfo"); + DBGLOG(REQ, LOUD, "\n"); + + ASSERT(prAdapter); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + ASSERT(pu4QueryInfoLen); + + *pu4QueryInfoLen = sizeof(struct PARAM_HW_MIB_INFO); + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, WARN, + "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", + prAdapter->rAcpiState, prAdapter->fgIsRadioOff); + *pu4QueryInfoLen = sizeof(uint32_t); + return WLAN_STATUS_ADAPTER_NOT_READY; + } else if (u4QueryBufferLen < sizeof(struct + PARAM_HW_MIB_INFO)) { + DBGLOG(REQ, WARN, "Too short length %u\n", + u4QueryBufferLen); + return WLAN_STATUS_INVALID_LENGTH; + } + + prHwMibInfo = (struct PARAM_HW_MIB_INFO *)pvQueryBuffer; + DBGLOG(RSN, INFO, + "MT6632 : wlanoidQueryMibInfo index = %d\n", + prHwMibInfo->u4Index); + + /* *pu4QueryInfoLen = 8 + prRxStatistics->u4TotalNum; */ + + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_MIB_INFO, + FALSE, + TRUE, + fgIsOid, + nicCmdEventQueryMibInfo, + nicOidCmdTimeoutCommon, + sizeof(struct PARAM_HW_MIB_INFO), + (uint8_t *)prHwMibInfo, + pvQueryBuffer, u4QueryBufferLen); + +} /* wlanoidQueryMibInfo */ +#endif + + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set FW log to Host. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer Pointer to the buffer that holds the data to be + * set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + * \retval WLAN_STATUS_NOT_SUPPORTED + * \retval WLAN_STATUS_ADAPTER_NOT_READY + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetFwLog2Host( + IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct CMD_FW_LOG_2_HOST_CTRL *prFwLog2HostCtrl; + + DEBUGFUNC("wlanoidSetFwLog2Host"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(struct CMD_FW_LOG_2_HOST_CTRL); + + if (u4SetBufferLen) + ASSERT(pvSetBuffer); + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, WARN, + "Fail in set FW log to Host! (Adapter not ready). ACPI=D%d, Radio=%d\n", + prAdapter->rAcpiState, prAdapter->fgIsRadioOff); + return WLAN_STATUS_ADAPTER_NOT_READY; + } else if (u4SetBufferLen < sizeof(struct + CMD_FW_LOG_2_HOST_CTRL)) { + DBGLOG(REQ, WARN, "Too short length %d\n", u4SetBufferLen); + return WLAN_STATUS_INVALID_LENGTH; + } + + prFwLog2HostCtrl = (struct CMD_FW_LOG_2_HOST_CTRL *) + pvSetBuffer; + + DBGLOG(REQ, INFO, "McuDest %d, LogType %d\n", + prFwLog2HostCtrl->ucMcuDest, + prFwLog2HostCtrl->ucFwLog2HostCtrl); + + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_FW_LOG_2_HOST, + TRUE, + FALSE, + TRUE, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_FW_LOG_2_HOST_CTRL), + (uint8_t *)prFwLog2HostCtrl, + pvSetBuffer, u4SetBufferLen); +} + +uint32_t +wlanoidNotifyFwSuspend( + IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct CMD_SUSPEND_MODE_SETTING *prSuspendCmd; + + if (!prAdapter || !pvSetBuffer) + return WLAN_STATUS_INVALID_DATA; + + prSuspendCmd = (struct CMD_SUSPEND_MODE_SETTING *) + pvSetBuffer; + + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_SET_SUSPEND_MODE, + TRUE, + FALSE, + TRUE, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_SUSPEND_MODE_SETTING), + (uint8_t *)prSuspendCmd, + NULL, + 0); +} + +uint32_t +wlanoidQueryCnm( + IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + struct PARAM_GET_CNM_T *prCnmInfo = NULL; + + DEBUGFUNC("wlanoidQueryCnm"); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + if (prAdapter->fgIsEnableLpdvt) + return WLAN_STATUS_NOT_SUPPORTED; + + *pu4QueryInfoLen = sizeof(struct PARAM_GET_CNM_T); + + if (u4QueryBufferLen < sizeof(struct PARAM_GET_CNM_T)) + return WLAN_STATUS_BUFFER_TOO_SHORT; + + prCnmInfo = (struct PARAM_GET_CNM_T *)pvQueryBuffer; + + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_GET_CNM, + FALSE, + TRUE, + TRUE, + nicCmdEventQueryCnmInfo, + nicOidCmdTimeoutCommon, + sizeof(struct PARAM_GET_CNM_T), + (uint8_t *)prCnmInfo, + pvQueryBuffer, u4QueryBufferLen); +} + +uint32_t +wlanoidPacketKeepAlive(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + uint32_t rStatus = WLAN_STATUS_SUCCESS; + struct PARAM_PACKET_KEEPALIVE_T *prPacket; + + DEBUGFUNC("wlanoidPacketKeepAlive"); + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + if (u4SetBufferLen) + ASSERT(pvSetBuffer); + + *pu4SetInfoLen = sizeof(struct PARAM_PACKET_KEEPALIVE_T); + + /* Check for query buffer length */ + if (u4SetBufferLen < *pu4SetInfoLen) { + DBGLOG(OID, WARN, "Too short length %u\n", u4SetBufferLen); + return WLAN_STATUS_BUFFER_TOO_SHORT; + } + + prPacket = (struct PARAM_PACKET_KEEPALIVE_T *) + kalMemAlloc(sizeof(struct PARAM_PACKET_KEEPALIVE_T), + VIR_MEM_TYPE); + if (!prPacket) { + DBGLOG(OID, ERROR, + "Can not alloc memory for struct PARAM_PACKET_KEEPALIVE_T\n"); + return -ENOMEM; + } + kalMemCopy(prPacket, pvSetBuffer, + sizeof(struct PARAM_PACKET_KEEPALIVE_T)); + + DBGLOG(OID, INFO, "enable=%d, index=%d\r\n", + prPacket->enable, prPacket->index); + + rStatus = wlanSendSetQueryCmd(prAdapter, + CMD_ID_WFC_KEEP_ALIVE, + TRUE, + FALSE, + TRUE, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(struct PARAM_PACKET_KEEPALIVE_T), + (uint8_t *)prPacket, NULL, 0); + kalMemFree(prPacket, VIR_MEM_TYPE, + sizeof(struct PARAM_PACKET_KEEPALIVE_T)); + return rStatus; +} + +#if CFG_SUPPORT_DBDC +uint32_t +wlanoidSetDbdcEnable( + IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + uint8_t ucDBDCEnable; + + if (!prAdapter || !pvSetBuffer) + return WLAN_STATUS_INVALID_DATA; + + /* Be careful. + * We only use the test cmd "set_dbdc" to enable DBDC HW + * wo/ OP Mode Change. Besides, it may also confuse original + * DBDC FSM. + */ + kalMemCopy(&ucDBDCEnable, pvSetBuffer, 1); + cnmUpdateDbdcSetting(prAdapter, ucDBDCEnable); + + return WLAN_STATUS_SUCCESS; +} +#endif /*#if CFG_SUPPORT_DBDC*/ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set tx target power base. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * \param[out] pvQueryBuf A pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the call + * failed due to invalid length of the query buffer, + * returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQuerySetTxTargetPower(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct PARAM_CUSTOM_SET_TX_TARGET_POWER + *prSetTxTargetPowerInfo; + struct CMD_SET_TX_TARGET_POWER rCmdSetTxTargetPower; + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + + DEBUGFUNC("wlanoidQuerySetTxTargetPower"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(struct + PARAM_CUSTOM_SET_TX_TARGET_POWER *); + + if (u4SetBufferLen < sizeof(struct + PARAM_CUSTOM_SET_TX_TARGET_POWER *)) + return WLAN_STATUS_INVALID_LENGTH; + + ASSERT(pvSetBuffer); + + prSetTxTargetPowerInfo = + (struct PARAM_CUSTOM_SET_TX_TARGET_POWER *) pvSetBuffer; + + kalMemSet(&rCmdSetTxTargetPower, 0, + sizeof(struct CMD_SET_TX_TARGET_POWER)); + + rCmdSetTxTargetPower.ucTxTargetPwr = + prSetTxTargetPowerInfo->ucTxTargetPwr; + + DBGLOG(INIT, INFO, + "MT6632 : wlanoidQuerySetTxTargetPower =%x dbm\n", + rCmdSetTxTargetPower.ucTxTargetPwr); + + rWlanStatus = wlanSendSetQueryCmd(prAdapter, + CMD_ID_SET_TX_PWR, + TRUE, /* fgSetQuery Bit: True->write False->read */ + FALSE, /* fgNeedResp */ + TRUE, /* fgIsOid*/ + nicCmdEventSetCommon, /* REF: wlanoidSetDbdcEnable */ + nicOidCmdTimeoutCommon, + sizeof(struct CMD_ACCESS_EFUSE), + (uint8_t *) (&rCmdSetTxTargetPower), pvSetBuffer, + u4SetBufferLen); + + return rWlanStatus; +} + +#if (CFG_SUPPORT_DFS_MASTER == 1) +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set rdd report. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * \param[out] pvQueryBuf A pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the call + * failed due to invalid length of the query buffer, + * returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQuerySetRddReport(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct PARAM_CUSTOM_SET_RDD_REPORT *prSetRddReport; + struct CMD_RDD_ON_OFF_CTRL *prCmdRddOnOffCtrl; + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + + DEBUGFUNC("wlanoidQuerySetRddReport"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(struct PARAM_CUSTOM_SET_RDD_REPORT + *); + + ASSERT(pvSetBuffer); + + prSetRddReport = (struct PARAM_CUSTOM_SET_RDD_REPORT *) + pvSetBuffer; + + prCmdRddOnOffCtrl = (struct CMD_RDD_ON_OFF_CTRL *) + cnmMemAlloc(prAdapter, RAM_TYPE_MSG, + sizeof(*prCmdRddOnOffCtrl)); + + ASSERT(prCmdRddOnOffCtrl); + if (prCmdRddOnOffCtrl == NULL) { + DBGLOG(INIT, ERROR, "prCmdRddOnOffCtrl is NULL"); + return WLAN_STATUS_FAILURE; + } + + prCmdRddOnOffCtrl->ucDfsCtrl = RDD_RADAR_EMULATE; + + prCmdRddOnOffCtrl->ucRddIdx = prSetRddReport->ucDbdcIdx; + + if (prCmdRddOnOffCtrl->ucRddIdx) + prCmdRddOnOffCtrl->ucRddRxSel = RDD_IN_SEL_1; + else + prCmdRddOnOffCtrl->ucRddRxSel = RDD_IN_SEL_0; + + DBGLOG(INIT, INFO, + "MT6632 : wlanoidQuerySetRddReport - DFS ctrl: %.d, RDD index: %d\n", + prCmdRddOnOffCtrl->ucDfsCtrl, prCmdRddOnOffCtrl->ucRddIdx); + + rWlanStatus = wlanSendSetQueryCmd(prAdapter, + CMD_ID_RDD_ON_OFF_CTRL, + TRUE, /* fgSetQuery Bit: True->write False->read */ + FALSE, /* fgNeedResp */ + TRUE, /* fgIsOid*/ + nicCmdEventSetCommon, /* REF: wlanoidSetDbdcEnable */ + nicOidCmdTimeoutCommon, + sizeof(*prCmdRddOnOffCtrl), + (uint8_t *) (prCmdRddOnOffCtrl), pvSetBuffer, + u4SetBufferLen); + + cnmMemFree(prAdapter, prCmdRddOnOffCtrl); + + return rWlanStatus; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set rdd report. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * \param[out] pvQueryBuf A pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the call + * failed due to invalid length of the query buffer, + * returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQuerySetRadarDetectMode(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct PARAM_CUSTOM_SET_RADAR_DETECT_MODE + *prSetRadarDetectMode; + struct CMD_RDD_ON_OFF_CTRL *prCmdRddOnOffCtrl; + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + + DEBUGFUNC("wlanoidQuerySetRadarDetectMode"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = + sizeof(struct PARAM_CUSTOM_SET_RADAR_DETECT_MODE *); + + ASSERT(pvSetBuffer); + + prSetRadarDetectMode = + (struct PARAM_CUSTOM_SET_RADAR_DETECT_MODE *) pvSetBuffer; + + prCmdRddOnOffCtrl = (struct CMD_RDD_ON_OFF_CTRL *)cnmMemAlloc( + prAdapter, RAM_TYPE_MSG, + sizeof(*prCmdRddOnOffCtrl)); + + ASSERT(prCmdRddOnOffCtrl); + if (prCmdRddOnOffCtrl == NULL) { + DBGLOG(INIT, ERROR, "prCmdRddOnOffCtrl is NULL"); + return WLAN_STATUS_FAILURE; + } + + prCmdRddOnOffCtrl->ucDfsCtrl = RDD_DET_MODE; + + prCmdRddOnOffCtrl->ucSetVal = + prSetRadarDetectMode->ucRadarDetectMode; + + DBGLOG(INIT, INFO, + "MT6632 : wlanoidQuerySetRadarDetectMode - DFS ctrl: %.d, Radar Detect Mode: %d\n", + prCmdRddOnOffCtrl->ucDfsCtrl, prCmdRddOnOffCtrl->ucSetVal); + + rWlanStatus = wlanSendSetQueryCmd(prAdapter, + CMD_ID_RDD_ON_OFF_CTRL, + TRUE, /* fgSetQuery Bit: True->write False->read */ + FALSE, /* fgNeedResp */ + TRUE, /* fgIsOid*/ + nicCmdEventSetCommon, /* REF: wlanoidSetDbdcEnable */ + nicOidCmdTimeoutCommon, + sizeof(*prCmdRddOnOffCtrl), + (uint8_t *) (prCmdRddOnOffCtrl), + pvSetBuffer, + u4SetBufferLen); + + cnmMemFree(prAdapter, prCmdRddOnOffCtrl); + + return rWlanStatus; +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used to turn radio off. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_ADAPTER_NOT_READY + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidLinkDown(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + uint8_t ucBssIndex = AIS_DEFAULT_INDEX; + + DEBUGFUNC("wlanoidSetDisassociate"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = 0; + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, WARN, + "Fail in set link down! (Adapter not ready). ACPI=D%d, Radio=%d\n", + prAdapter->rAcpiState, prAdapter->fgIsRadioOff); + return WLAN_STATUS_ADAPTER_NOT_READY; + } + + aisBssLinkDown(prAdapter, ucBssIndex); + + return WLAN_STATUS_SUCCESS; +} /* wlanoidSetDisassociate */ + +#if CFG_SUPPORT_NCHO + +uint32_t +wlanoidSetNchoHeader(struct CMD_HEADER *prCmdHeader, + struct CMD_FORMAT_V1 *pr_cmd_v1, + char *pStr, uint32_t u4Len) { + prCmdHeader->cmdVersion = CMD_VER_1_EXT; + prCmdHeader->cmdType = CMD_TYPE_QUERY; + prCmdHeader->itemNum = 1; + prCmdHeader->cmdBufferLen = sizeof(struct CMD_FORMAT_V1); + kalMemSet(prCmdHeader->buffer, 0, MAX_CMD_BUFFER_LENGTH); + + if (!prCmdHeader || !pStr || u4Len == 0) + return WLAN_STATUS_FAILURE; + + pr_cmd_v1->itemStringLength = u4Len; + kalMemCopy(pr_cmd_v1->itemString, pStr, u4Len); + + return WLAN_STATUS_SUCCESS; +} + +uint32_t +wlanoidSetNchoRoamTrigger(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + int32_t *pi4Param = NULL; + uint32_t rStatus = WLAN_STATUS_FAILURE; + + DEBUGFUNC("wlanoidSetNchoRoamTrigger"); + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + ASSERT(pvSetBuffer); + + *pu4SetInfoLen = sizeof(int32_t); + + if (u4SetBufferLen < sizeof(int32_t)) + return WLAN_STATUS_INVALID_LENGTH; + + if (prAdapter->rNchoInfo.fgNCHOEnabled == FALSE) + return WLAN_STATUS_INVALID_DATA; + + pi4Param = (int32_t *) pvSetBuffer; + if (*pi4Param < RCPI_LOW_BOUND + || *pi4Param > RCPI_HIGH_BOUND) { + DBGLOG(INIT, ERROR, "NCHO roam trigger invalid %d\n", + *pi4Param); + return WLAN_STATUS_INVALID_DATA; + } + + rStatus = wlanNchoSetFWRssiTrigger(prAdapter, *pi4Param); + if (rStatus == WLAN_STATUS_SUCCESS) { + prAdapter->rNchoInfo.i4RoamTrigger = *pi4Param; + DBGLOG(INIT, TRACE, "NCHO roam trigger is %d\n", + prAdapter->rNchoInfo.i4RoamTrigger); + } + + return rStatus; +} + +uint32_t +wlanoidQueryNchoRoamTrigger(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + uint32_t rStatus = WLAN_STATUS_FAILURE; + struct CMD_HEADER cmdV1Header; + struct CMD_HEADER *prCmdV1Header = (struct CMD_HEADER *) + pvQueryBuffer; + struct CMD_FORMAT_V1 *prCmdV1 = NULL; + + DEBUGFUNC("wlanoidQueryNchoRoamTrigger"); + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + *pu4QueryInfoLen = sizeof(struct CMD_HEADER); + + if (u4QueryBufferLen < sizeof(struct CMD_HEADER)) + return WLAN_STATUS_BUFFER_TOO_SHORT; + + if (prAdapter->rNchoInfo.fgNCHOEnabled == FALSE) + return WLAN_STATUS_INVALID_DATA; + + prCmdV1 = (struct CMD_FORMAT_V1 *) prCmdV1Header->buffer; + rStatus = wlanoidSetNchoHeader(prCmdV1Header, + prCmdV1, + FW_CFG_KEY_NCHO_ROAM_RCPI, + kalStrLen(FW_CFG_KEY_NCHO_ROAM_RCPI)); + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, ERROR, "NCHO no enough memory\n"); + return rStatus; + } + kalMemCopy(&cmdV1Header, prCmdV1Header, + sizeof(struct CMD_HEADER)); + rStatus = wlanSendSetQueryCmd( + prAdapter, + CMD_ID_GET_SET_CUSTOMER_CFG, + FALSE, + TRUE, + TRUE, + nicCmdEventQueryCfgRead, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_HEADER), + (uint8_t *)&cmdV1Header, + pvQueryBuffer, + u4QueryBufferLen); + return rStatus; +} + +uint32_t +wlanoidSetNchoRoamDelta(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + int32_t *pi4Param = NULL; + uint32_t rStatus = WLAN_STATUS_FAILURE; + + DEBUGFUNC("wlanoidSetNchoRoamDelta"); + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + ASSERT(pvSetBuffer); + + *pu4SetInfoLen = sizeof(int32_t); + + if (u4SetBufferLen < sizeof(int32_t)) + return WLAN_STATUS_INVALID_LENGTH; + + if (prAdapter->rNchoInfo.fgNCHOEnabled == FALSE) + return WLAN_STATUS_INVALID_DATA; + + pi4Param = (int32_t *) pvSetBuffer; + if (*pi4Param > 100) { + DBGLOG(INIT, ERROR, "NCHO roam delta invalid %d\n", + *pi4Param); + return WLAN_STATUS_INVALID_DATA; + } + + prAdapter->rNchoInfo.i4RoamDelta = *pi4Param; + DBGLOG(INIT, TRACE, "NCHO roam delta is %d\n", *pi4Param); + rStatus = WLAN_STATUS_SUCCESS; + + return rStatus; +} + +uint32_t +wlanoidQueryNchoRoamDelta(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + int32_t *pParam = NULL; + + DEBUGFUNC("wlanoidQueryNchoRoamDelta"); + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + if (u4QueryBufferLen < sizeof(int32_t)) + return WLAN_STATUS_BUFFER_TOO_SHORT; + + if (prAdapter->rNchoInfo.fgNCHOEnabled == FALSE) + return WLAN_STATUS_INVALID_DATA; + + pParam = (int32_t *) pvQueryBuffer; + *pParam = prAdapter->rNchoInfo.i4RoamDelta; + DBGLOG(INIT, TRACE, "NCHO roam delta is %d\n", *pParam); + + return WLAN_STATUS_SUCCESS; +} + +uint32_t +wlanoidSetNchoRoamScnPeriod(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + uint32_t *pParam = NULL; + uint32_t rStatus = WLAN_STATUS_FAILURE; + + DEBUGFUNC("wlanoidSetNchoRoamScnPeriod"); + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + ASSERT(pvSetBuffer); + + *pu4SetInfoLen = sizeof(uint32_t); + + if (u4SetBufferLen < sizeof(uint32_t)) + return WLAN_STATUS_INVALID_LENGTH; + + if (prAdapter->rNchoInfo.fgNCHOEnabled == FALSE) + return WLAN_STATUS_INVALID_DATA; + + pParam = (uint32_t *) pvSetBuffer; + rStatus = wlanNchoSetFWScanPeriod(prAdapter, *pParam); + if (rStatus == WLAN_STATUS_SUCCESS) { + prAdapter->rNchoInfo.u4RoamScanPeriod = *pParam; + DBGLOG(INIT, TRACE, "NCHO roam scan period is %d\n", *pParam); + } + + return rStatus; +} + +uint32_t +wlanoidQueryNchoRoamScnPeriod(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) +{ + uint32_t rStatus = WLAN_STATUS_FAILURE; + struct CMD_HEADER cmdV1Header; + struct CMD_HEADER *prCmdV1Header = (struct CMD_HEADER *)pvQueryBuffer; + struct CMD_FORMAT_V1 *prCmdV1 = NULL; + + DEBUGFUNC("wlanoidQueryNchoRoamScnPeriod"); + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + if (u4QueryBufferLen < sizeof(uint32_t)) + return WLAN_STATUS_BUFFER_TOO_SHORT; + + if (prAdapter->rNchoInfo.fgNCHOEnabled == FALSE) + return WLAN_STATUS_INVALID_DATA; + + prCmdV1 = (struct CMD_FORMAT_V1 *) prCmdV1Header->buffer; + rStatus = wlanoidSetNchoHeader(prCmdV1Header, + prCmdV1, + FW_CFG_KEY_NCHO_SCAN_PERIOD, + kalStrLen(FW_CFG_KEY_NCHO_SCAN_PERIOD)); + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, ERROR, "NCHO no enough memory\n"); + return rStatus; + } + kalMemCopy(&cmdV1Header, prCmdV1Header, sizeof(struct CMD_HEADER)); + rStatus = wlanSendSetQueryCmd( + prAdapter, + CMD_ID_GET_SET_CUSTOMER_CFG, + FALSE, + TRUE, + TRUE, + nicCmdEventQueryCfgRead, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_HEADER), + (uint8_t *)&cmdV1Header, + pvQueryBuffer, + u4QueryBufferLen); + return rStatus; +} + +uint32_t +wlanoidSetNchoRoamScnChnl(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + struct CFG_NCHO_SCAN_CHNL *prRoamScnChnl = NULL; + + DEBUGFUNC("wlanoidSetNchoRoamScnChnl"); + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + ASSERT(pvSetBuffer); + + *pu4SetInfoLen = sizeof(struct CFG_NCHO_SCAN_CHNL); + + if (u4SetBufferLen < sizeof(struct CFG_NCHO_SCAN_CHNL)) + return WLAN_STATUS_INVALID_LENGTH; + + if (prAdapter->rNchoInfo.fgNCHOEnabled == FALSE) + return WLAN_STATUS_INVALID_DATA; + + prRoamScnChnl = (struct CFG_NCHO_SCAN_CHNL *) pvSetBuffer; + + kalMemCopy(&prAdapter->rNchoInfo.rRoamScnChnl, + prRoamScnChnl, *pu4SetInfoLen); + DBGLOG(INIT, TRACE, + "NCHO set roam scan channel num is %d\n", + prRoamScnChnl->ucChannelListNum); + + prAdapter->rNchoInfo.u4RoamScanControl = 1; + + return WLAN_STATUS_SUCCESS; +} + +uint32_t +wlanoidAddNchoRoamScnChnl(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + struct CFG_NCHO_SCAN_CHNL *prRoamScnChnl = NULL; + + DEBUGFUNC("wlanoidSetNchoRoamScnChnl"); + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + ASSERT(pvSetBuffer); + + *pu4SetInfoLen = sizeof(struct CFG_NCHO_SCAN_CHNL); + + if (u4SetBufferLen < sizeof(struct CFG_NCHO_SCAN_CHNL)) + return WLAN_STATUS_INVALID_LENGTH; + + if (prAdapter->rNchoInfo.fgNCHOEnabled == FALSE) + return WLAN_STATUS_INVALID_DATA; + + prRoamScnChnl = (struct CFG_NCHO_SCAN_CHNL *) pvSetBuffer; + + kalMemCopy(&prAdapter->rNchoInfo.rAddRoamScnChnl, + prRoamScnChnl, *pu4SetInfoLen); + DBGLOG(INIT, TRACE, + "NCHO set roam scan channel num is %d\n", + prRoamScnChnl->ucChannelListNum); + + return WLAN_STATUS_SUCCESS; +} + +uint32_t +wlanoidQueryNchoRoamScnChnl(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) +{ + struct CFG_NCHO_SCAN_CHNL *prRoamScnChnl = NULL; + struct CFG_NCHO_SCAN_CHNL *chnl; + + DEBUGFUNC("wlanoidQueryNchoRoamScnChnl"); + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + if (u4QueryBufferLen < sizeof(struct CFG_NCHO_SCAN_CHNL)) + return WLAN_STATUS_BUFFER_TOO_SHORT; + + if (prAdapter->rNchoInfo.fgNCHOEnabled == FALSE) + return WLAN_STATUS_INVALID_DATA; + + prRoamScnChnl = (struct CFG_NCHO_SCAN_CHNL *) pvQueryBuffer; + + if (prAdapter->rNchoInfo.u4RoamScanControl) + chnl = &prAdapter->rNchoInfo.rRoamScnChnl; + else + chnl = &prAdapter->rNchoInfo.rAddRoamScnChnl; + + kalMemCopy(prRoamScnChnl, chnl, u4QueryBufferLen); + DBGLOG(INIT, TRACE, "NCHO roam scan channel num is %d, ctrl %d\n", + prRoamScnChnl->ucChannelListNum, + prAdapter->rNchoInfo.u4RoamScanControl); + + return WLAN_STATUS_SUCCESS; +} + +uint32_t +wlanoidSetNchoRoamScnCtrl(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + uint32_t *pParam = NULL; + uint32_t rStatus = WLAN_STATUS_FAILURE; + + DEBUGFUNC("wlanoidSetNchoRoamScnChnl"); + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + ASSERT(pvSetBuffer); + + *pu4SetInfoLen = sizeof(uint32_t); + + if (u4SetBufferLen < sizeof(uint32_t)) + return WLAN_STATUS_INVALID_LENGTH; + + pParam = (uint32_t *) pvSetBuffer; + if (*pParam != TRUE && *pParam != FALSE) { + DBGLOG(INIT, ERROR, "NCHO roam scan control invalid %d\n", + *pParam); + return WLAN_STATUS_INVALID_DATA; + } + + prAdapter->rNchoInfo.u4RoamScanControl = *pParam; + DBGLOG(INIT, TRACE, "NCHO roam scan control is %d\n", + *pParam); + rStatus = WLAN_STATUS_SUCCESS; + + return rStatus; +} + +uint32_t +wlanoidQueryNchoRoamScnCtrl(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + uint32_t *pParam = NULL; + + DEBUGFUNC("wlanoidQueryNchoRoamScnCtrl"); + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + if (u4QueryBufferLen < sizeof(uint32_t)) + return WLAN_STATUS_BUFFER_TOO_SHORT; + + if (prAdapter->rNchoInfo.fgNCHOEnabled == FALSE) + return WLAN_STATUS_INVALID_DATA; + + pParam = (uint32_t *) pvQueryBuffer; + *pParam = prAdapter->rNchoInfo.u4RoamScanControl; + DBGLOG(INIT, TRACE, "NCHO roam scan control is %d\n", + *pParam); + + return WLAN_STATUS_SUCCESS; +} + +uint32_t +wlanoidSetNchoScnChnlTime(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + uint32_t *pParam = NULL; + char acCmd[NCHO_CMD_MAX_LENGTH] = {0}; + uint32_t rStatus = WLAN_STATUS_FAILURE; + + DEBUGFUNC("wlanoidSetNchoScnChnlTime"); + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + ASSERT(pvSetBuffer); + + *pu4SetInfoLen = sizeof(uint32_t); + + if (u4SetBufferLen < sizeof(uint32_t)) + return WLAN_STATUS_INVALID_LENGTH; + + pParam = (uint32_t *) pvSetBuffer; + if (*pParam < 10 && *pParam > 1000) { + DBGLOG(INIT, ERROR, "NCHO scan channel time invalid %d\n", + *pParam); + return WLAN_STATUS_INVALID_DATA; + } + + kalSprintf(acCmd, "%s %d", FW_CFG_KEY_NCHO_SCN_CHANNEL_TIME, + *pParam); + rStatus = wlanFwCfgParse(prAdapter, acCmd); + if (rStatus == WLAN_STATUS_SUCCESS) { + prAdapter->rNchoInfo.u4ScanChannelTime = *pParam; + DBGLOG(INIT, TRACE, "NCHO scan channel time is %d\n", + *pParam); + } + + return rStatus; +} + +uint32_t +wlanoidQueryNchoScnChnlTime(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + uint32_t rStatus = WLAN_STATUS_FAILURE; + struct CMD_HEADER cmdV1Header; + struct CMD_HEADER *prCmdV1Header = (struct CMD_HEADER *) + pvQueryBuffer; + struct CMD_FORMAT_V1 *prCmdV1 = NULL; + + DEBUGFUNC("wlanoidQueryNchoScnChnlTime"); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + *pu4QueryInfoLen = sizeof(struct CMD_HEADER); + + if (u4QueryBufferLen < sizeof(struct CMD_HEADER)) + return WLAN_STATUS_BUFFER_TOO_SHORT; + + if (prAdapter->rNchoInfo.fgNCHOEnabled == FALSE) + return WLAN_STATUS_INVALID_DATA; + + prCmdV1 = (struct CMD_FORMAT_V1 *) prCmdV1Header->buffer; + rStatus = wlanoidSetNchoHeader(prCmdV1Header, prCmdV1, + FW_CFG_KEY_NCHO_SCN_CHANNEL_TIME, + kalStrLen(FW_CFG_KEY_NCHO_SCN_CHANNEL_TIME)); + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, ERROR, "NCHO no enough memory\n"); + return rStatus; + } + kalMemCopy(&cmdV1Header, prCmdV1Header, + sizeof(struct CMD_HEADER)); + rStatus = wlanSendSetQueryCmd( + prAdapter, + CMD_ID_GET_SET_CUSTOMER_CFG, + FALSE, + TRUE, + TRUE, + nicCmdEventQueryCfgRead, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_HEADER), + (uint8_t *)&cmdV1Header, + pvQueryBuffer, + u4QueryBufferLen); + return rStatus; +} + +uint32_t +wlanoidSetNchoScnHomeTime(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + uint32_t *pParam = NULL; + char acCmd[NCHO_CMD_MAX_LENGTH] = {0}; + uint32_t rStatus = WLAN_STATUS_FAILURE; + + DEBUGFUNC("wlanoidSetNchoScnHomeTime"); + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + ASSERT(pvSetBuffer); + + *pu4SetInfoLen = sizeof(uint32_t); + + if (u4SetBufferLen < sizeof(uint32_t)) + return WLAN_STATUS_INVALID_LENGTH; + + pParam = (uint32_t *) pvSetBuffer; + if (*pParam < 10 && *pParam > 1000) { + DBGLOG(INIT, ERROR, "NCHO scan home time invalid %d\n", + *pParam); + return WLAN_STATUS_INVALID_DATA; + } + + kalSprintf(acCmd, "%s %d", FW_CFG_KEY_NCHO_SCN_HOME_TIME, + *pParam); + DBGLOG(REQ, TRACE, "NCHO cmd is %s\n", acCmd); + rStatus = wlanFwCfgParse(prAdapter, acCmd); + if (rStatus == WLAN_STATUS_SUCCESS) { + prAdapter->rNchoInfo.u4ScanHomeTime = *pParam; + DBGLOG(INIT, TRACE, "NCHO scan home time is %d\n", *pParam); + } + + return rStatus; +} + +uint32_t +wlanoidQueryNchoScnHomeTime(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + uint32_t rStatus = WLAN_STATUS_FAILURE; + struct CMD_HEADER cmdV1Header; + struct CMD_HEADER *prCmdV1Header = (struct CMD_HEADER *) + pvQueryBuffer; + struct CMD_FORMAT_V1 *prCmdV1 = NULL; + + DEBUGFUNC("wlanoidQueryNchoScnHomeTime"); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + *pu4QueryInfoLen = sizeof(struct CMD_HEADER); + + if (u4QueryBufferLen < sizeof(struct CMD_HEADER)) + return WLAN_STATUS_BUFFER_TOO_SHORT; + + if (prAdapter->rNchoInfo.fgNCHOEnabled == FALSE) + return WLAN_STATUS_INVALID_DATA; + + prCmdV1 = (struct CMD_FORMAT_V1 *) prCmdV1Header->buffer; + rStatus = wlanoidSetNchoHeader(prCmdV1Header, prCmdV1, + FW_CFG_KEY_NCHO_SCN_HOME_TIME, + kalStrLen(FW_CFG_KEY_NCHO_SCN_HOME_TIME)); + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, ERROR, "NCHO no enough memory\n"); + return rStatus; + } + kalMemCopy(&cmdV1Header, prCmdV1Header, + sizeof(struct CMD_HEADER)); + rStatus = wlanSendSetQueryCmd( + prAdapter, + CMD_ID_GET_SET_CUSTOMER_CFG, + FALSE, + TRUE, + TRUE, + nicCmdEventQueryCfgRead, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_HEADER), + (uint8_t *)&cmdV1Header, + pvQueryBuffer, + u4QueryBufferLen); + return rStatus; +} + +uint32_t +wlanoidSetNchoScnHomeAwayTime(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + uint32_t *pParam = NULL; + char acCmd[NCHO_CMD_MAX_LENGTH] = {0}; + uint32_t rStatus = WLAN_STATUS_FAILURE; + + DEBUGFUNC("wlanoidSetNchoScnHomeAwayTime"); + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + ASSERT(pvSetBuffer); + + *pu4SetInfoLen = sizeof(uint32_t); + + if (u4SetBufferLen < sizeof(uint32_t)) + return WLAN_STATUS_INVALID_LENGTH; + + pParam = (uint32_t *) pvSetBuffer; + if (*pParam < 10 && *pParam > 1000) { + DBGLOG(INIT, ERROR, "NCHO scan home away time invalid %d\n", + *pParam); + return WLAN_STATUS_INVALID_DATA; + } + + + kalSprintf(acCmd, "%s %d", + FW_CFG_KEY_NCHO_SCN_HOME_AWAY_TIME, *pParam); + DBGLOG(REQ, TRACE, "NCHO cmd is %s\n", acCmd); + rStatus = wlanFwCfgParse(prAdapter, acCmd); + if (rStatus == WLAN_STATUS_SUCCESS) { + prAdapter->rNchoInfo.u4ScanHomeawayTime = *pParam; + DBGLOG(INIT, TRACE, "NCHO scan home away is %d\n", *pParam); + } + + return rStatus; +} + +uint32_t +wlanoidQueryNchoScnHomeAwayTime(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + uint32_t rStatus = WLAN_STATUS_FAILURE; + struct CMD_HEADER cmdV1Header; + struct CMD_HEADER *prCmdV1Header = (struct CMD_HEADER *) + pvQueryBuffer; + struct CMD_FORMAT_V1 *prCmdV1 = NULL; + + DEBUGFUNC("wlanoidQueryNchoScnHomeTime"); + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + *pu4QueryInfoLen = sizeof(struct CMD_HEADER); + + if (u4QueryBufferLen < sizeof(struct CMD_HEADER)) + return WLAN_STATUS_BUFFER_TOO_SHORT; + + if (prAdapter->rNchoInfo.fgNCHOEnabled == FALSE) + return WLAN_STATUS_INVALID_DATA; + + prCmdV1 = (struct CMD_FORMAT_V1 *) prCmdV1Header->buffer; + rStatus = wlanoidSetNchoHeader(prCmdV1Header, prCmdV1, + FW_CFG_KEY_NCHO_SCN_HOME_AWAY_TIME, + kalStrLen(FW_CFG_KEY_NCHO_SCN_HOME_AWAY_TIME)); + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, ERROR, "NCHO no enough memory\n"); + return rStatus; + } + kalMemCopy(&cmdV1Header, prCmdV1Header, + sizeof(struct CMD_HEADER)); + rStatus = wlanSendSetQueryCmd( + prAdapter, + CMD_ID_GET_SET_CUSTOMER_CFG, + FALSE, + TRUE, + TRUE, + nicCmdEventQueryCfgRead, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_HEADER), + (uint8_t *)&cmdV1Header, + pvQueryBuffer, + u4QueryBufferLen); + return rStatus; +} + +uint32_t +wlanoidSetNchoScnNprobes(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + uint32_t *pParam = NULL; + char acCmd[NCHO_CMD_MAX_LENGTH] = {0}; + uint32_t rStatus = WLAN_STATUS_FAILURE; + + DEBUGFUNC("wlanoidSetNchoScnNprobes"); + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + ASSERT(pvSetBuffer); + + *pu4SetInfoLen = sizeof(uint32_t); + + if (u4SetBufferLen < sizeof(uint32_t)) + return WLAN_STATUS_INVALID_LENGTH; + + pParam = (uint32_t *) pvSetBuffer; + if (*pParam > 16) { + DBGLOG(INIT, ERROR, "NCHO scan Nprobes invalid %d\n", + *pParam); + return WLAN_STATUS_INVALID_DATA; + } + + + kalSprintf(acCmd, "%s %d", FW_CFG_KEY_NCHO_SCN_NPROBES, + *pParam); + rStatus = wlanFwCfgParse(prAdapter, acCmd); + if (rStatus == WLAN_STATUS_SUCCESS) { + prAdapter->rNchoInfo.u4ScanNProbes = *pParam; + DBGLOG(INIT, TRACE, "NCHO Nprobes is %d\n", *pParam); + } + return rStatus; +} + +uint32_t +wlanoidQueryNchoScnNprobes(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + uint32_t rStatus = WLAN_STATUS_FAILURE; + struct CMD_HEADER cmdV1Header; + struct CMD_HEADER *prCmdV1Header = (struct CMD_HEADER *) + pvQueryBuffer; + struct CMD_FORMAT_V1 *prCmdV1 = NULL; + + DEBUGFUNC("wlanoidQueryNchoScnNprobes"); + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + *pu4QueryInfoLen = sizeof(struct CMD_HEADER); + + if (u4QueryBufferLen < sizeof(struct CMD_HEADER)) + return WLAN_STATUS_BUFFER_TOO_SHORT; + + if (prAdapter->rNchoInfo.fgNCHOEnabled == FALSE) + return WLAN_STATUS_INVALID_DATA; + + prCmdV1 = (struct CMD_FORMAT_V1 *) prCmdV1Header->buffer; + rStatus = wlanoidSetNchoHeader(prCmdV1Header, + prCmdV1, + FW_CFG_KEY_NCHO_SCN_NPROBES, + kalStrLen(FW_CFG_KEY_NCHO_SCN_NPROBES)); + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, ERROR, "NCHO no enough memory\n"); + return rStatus; + } + kalMemCopy(&cmdV1Header, prCmdV1Header, + sizeof(struct CMD_HEADER)); + rStatus = wlanSendSetQueryCmd( + prAdapter, + CMD_ID_GET_SET_CUSTOMER_CFG, + FALSE, + TRUE, + TRUE, + nicCmdEventQueryCfgRead, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_HEADER), + (uint8_t *)&cmdV1Header, + pvQueryBuffer, + u4QueryBufferLen); + return rStatus; +} + +uint32_t +wlanoidGetNchoReassocInfo(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + uint32_t rStatus = WLAN_STATUS_FAILURE; + struct BSS_DESC *prBssDesc = NULL; + struct PARAM_CONNECT *prParamConn; + + DEBUGFUNC("wlanoidGetNchoReassocInfo"); + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + ASSERT(pvQueryBuffer); + + prParamConn = (struct PARAM_CONNECT *)pvQueryBuffer; + if (prAdapter->rNchoInfo.fgNCHOEnabled == TRUE) { + prBssDesc = scanSearchBssDescByBssid(prAdapter, + prParamConn->pucBssid); + if (prBssDesc != NULL) { + prParamConn->u4SsidLen = prBssDesc->ucSSIDLen; + COPY_SSID(prParamConn->pucSsid, + prParamConn->u4SsidLen, + prBssDesc->aucSSID, + prBssDesc->ucSSIDLen); + rStatus = WLAN_STATUS_SUCCESS; + } + } + return rStatus; +} + +uint32_t +wlanoidSendNchoActionFrameStart(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + uint32_t rStatus = WLAN_STATUS_FAILURE; + struct NCHO_INFO *prNchoInfo = NULL; + struct NCHO_ACTION_FRAME_PARAMS *prParamActionFrame = NULL; + + DEBUGFUNC("wlanoidSendNchoActionFrameStart"); + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + ASSERT(pvSetBuffer); + + + prNchoInfo = &prAdapter->rNchoInfo; + prParamActionFrame = (struct NCHO_ACTION_FRAME_PARAMS *)pvSetBuffer; + prNchoInfo->fgIsSendingAF = TRUE; + prNchoInfo->fgChGranted = FALSE; + COPY_MAC_ADDR(prNchoInfo->rParamActionFrame.aucBssid, + prParamActionFrame->aucBssid); + prNchoInfo->rParamActionFrame.i4channel = prParamActionFrame->i4channel; + prNchoInfo->rParamActionFrame.i4DwellTime = + prParamActionFrame->i4DwellTime; + prNchoInfo->rParamActionFrame.i4len = prParamActionFrame->i4len; + kalMemCopy(prNchoInfo->rParamActionFrame.aucData, + prParamActionFrame->aucData, + prParamActionFrame->i4len); + DBGLOG(INIT, TRACE, "NCHO send ncho action frame start\n"); + rStatus = WLAN_STATUS_SUCCESS; + + return rStatus; +} + +uint32_t +wlanoidSendNchoActionFrameEnd(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + uint32_t rStatus = WLAN_STATUS_FAILURE; + + DEBUGFUNC("wlanoidSendNchoActionFrameEnd"); + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + ASSERT(pvSetBuffer); + + prAdapter->rNchoInfo.fgIsSendingAF = FALSE; + prAdapter->rNchoInfo.fgChGranted = TRUE; + DBGLOG(INIT, TRACE, "NCHO send action frame end\n"); + rStatus = WLAN_STATUS_SUCCESS; + + return rStatus; +} + +uint32_t +wlanoidSetNchoWesMode(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + uint32_t *pParam = NULL; + uint32_t rStatus = WLAN_STATUS_FAILURE; + + DEBUGFUNC("wlanoidSetNchoWesMode"); + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + ASSERT(pvSetBuffer); + + *pu4SetInfoLen = sizeof(uint32_t); + + if (u4SetBufferLen < sizeof(uint32_t)) + return WLAN_STATUS_INVALID_LENGTH; + + pParam = (uint32_t *) pvSetBuffer; + if (*pParam != TRUE && *pParam != FALSE) { + DBGLOG(INIT, ERROR, "NCHO wes mode invalid %d\n", *pParam); + return WLAN_STATUS_INVALID_DATA; + } + + + prAdapter->rNchoInfo.u4WesMode = *pParam; + DBGLOG(INIT, TRACE, "NCHO WES mode is %d\n", *pParam); + rStatus = WLAN_STATUS_SUCCESS; + + return rStatus; +} + +uint32_t +wlanoidQueryNchoWesMode(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + uint32_t *pParam = NULL; + + DEBUGFUNC("wlanoidQueryNchoWesMode"); + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + if (u4QueryBufferLen < sizeof(uint32_t)) + return WLAN_STATUS_BUFFER_TOO_SHORT; + + if (prAdapter->rNchoInfo.fgNCHOEnabled == FALSE) + return WLAN_STATUS_INVALID_DATA; + + pParam = (uint32_t *) pvQueryBuffer; + *pParam = prAdapter->rNchoInfo.u4WesMode; + DBGLOG(INIT, TRACE, "NCHO Wes mode is %d\n", *pParam); + + return WLAN_STATUS_SUCCESS; +} + +uint32_t +wlanoidSetNchoBand(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + uint32_t *pParam = NULL; + uint32_t rStatus = WLAN_STATUS_FAILURE; + + DEBUGFUNC("wlanoidSetNchoBand"); + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + ASSERT(pvSetBuffer); + + *pu4SetInfoLen = sizeof(uint32_t); + + if (u4SetBufferLen < sizeof(uint32_t)) + return WLAN_STATUS_INVALID_LENGTH; + + pParam = (uint32_t *) pvSetBuffer; + + switch (*pParam) { + case NCHO_BAND_AUTO: + prAdapter->aePreferBand[NETWORK_TYPE_AIS] = BAND_NULL; + prAdapter->rNchoInfo.eBand = NCHO_BAND_AUTO; + rStatus = WLAN_STATUS_SUCCESS; + break; + case NCHO_BAND_2G4: + prAdapter->aePreferBand[NETWORK_TYPE_AIS] = BAND_2G4; + prAdapter->rNchoInfo.eBand = NCHO_BAND_2G4; + rStatus = WLAN_STATUS_SUCCESS; + break; + case NCHO_BAND_5G: + prAdapter->aePreferBand[NETWORK_TYPE_AIS] = BAND_5G; + prAdapter->rNchoInfo.eBand = NCHO_BAND_5G; + rStatus = WLAN_STATUS_SUCCESS; + break; + default: + DBGLOG(INIT, ERROR, "NCHO wes mode invalid %d\n", *pParam); + rStatus = WLAN_STATUS_INVALID_DATA; + break; + } + + DBGLOG(INIT, INFO, "NCHO enabled:%d ,band:%d,status:%d\n" + , prAdapter->rNchoInfo.fgNCHOEnabled, *pParam, rStatus); + + + return rStatus; +} + +uint32_t +wlanoidQueryNchoBand(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + uint32_t *pParam = NULL; + + DEBUGFUNC("wlanoidQueryNchoBand"); + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + if (u4QueryBufferLen < sizeof(uint32_t)) + return WLAN_STATUS_BUFFER_TOO_SHORT; + + if (prAdapter->rNchoInfo.fgNCHOEnabled == FALSE) + return WLAN_STATUS_INVALID_DATA; + + pParam = (uint32_t *) pvQueryBuffer; + *pParam = prAdapter->rNchoInfo.eBand; + DBGLOG(INIT, TRACE, "NCHO band is %d\n", *pParam); + + return WLAN_STATUS_SUCCESS; +} + +uint32_t +wlanoidSetNchoDfsScnMode(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + uint32_t *pParam = NULL; + char acCmd[NCHO_CMD_MAX_LENGTH] = {0}; + uint32_t rStatus = WLAN_STATUS_FAILURE; + + DEBUGFUNC("wlanoidSetNchoDfsScnMode"); + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + ASSERT(pvSetBuffer); + + *pu4SetInfoLen = sizeof(uint32_t); + + if (u4SetBufferLen < sizeof(uint32_t)) + return WLAN_STATUS_INVALID_LENGTH; + + pParam = (uint32_t *) pvSetBuffer; + if (*pParam >= NCHO_DFS_SCN_NUM) { + DBGLOG(INIT, ERROR, "NCHO DFS scan mode invalid %d\n", + *pParam); + return WLAN_STATUS_INVALID_DATA; + } + + + kalSprintf(acCmd, "%s %d", FW_CFG_KEY_NCHO_SCAN_DFS_MODE, + *pParam); + rStatus = wlanFwCfgParse(prAdapter, acCmd); + if (rStatus == WLAN_STATUS_SUCCESS) { + prAdapter->rNchoInfo.eDFSScnMode = *pParam; + DBGLOG(INIT, TRACE, "NCHO DFS scan mode is %d\n", *pParam); + } + + return rStatus; +} + +uint32_t +wlanoidQueryNchoDfsScnMode(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + uint32_t rStatus = WLAN_STATUS_FAILURE; + struct CMD_HEADER cmdV1Header; + struct CMD_HEADER *prCmdV1Header = (struct CMD_HEADER *) + pvQueryBuffer; + struct CMD_FORMAT_V1 *prCmdV1 = NULL; + + DEBUGFUNC("wlanoidQueryNchoDfsScnMode"); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + *pu4QueryInfoLen = sizeof(struct CMD_HEADER); + + if (u4QueryBufferLen < sizeof(struct CMD_HEADER)) + return WLAN_STATUS_BUFFER_TOO_SHORT; + + if (prAdapter->rNchoInfo.fgNCHOEnabled == FALSE) + return WLAN_STATUS_INVALID_DATA; + + prCmdV1 = (struct CMD_FORMAT_V1 *) prCmdV1Header->buffer; + rStatus = wlanoidSetNchoHeader(prCmdV1Header, prCmdV1, + FW_CFG_KEY_NCHO_SCAN_DFS_MODE, + kalStrLen(FW_CFG_KEY_NCHO_SCAN_DFS_MODE)); + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, ERROR, "NCHO no enough memory\n"); + return rStatus; + } + kalMemCopy(&cmdV1Header, prCmdV1Header, + sizeof(struct CMD_HEADER)); + rStatus = wlanSendSetQueryCmd( + prAdapter, + CMD_ID_GET_SET_CUSTOMER_CFG, + FALSE, + TRUE, + TRUE, + nicCmdEventQueryCfgRead, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_HEADER), + (uint8_t *)&cmdV1Header, + pvQueryBuffer, + u4QueryBufferLen); + return rStatus; +} + +uint32_t +wlanoidSetNchoEnable(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + uint32_t *pParam = NULL; + uint32_t rStatus = WLAN_STATUS_FAILURE; + + DEBUGFUNC("wlanoidSetNchoEnable"); + DBGLOG(OID, LOUD, "\n"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + ASSERT(pvSetBuffer); + + *pu4SetInfoLen = sizeof(uint32_t); + + if (u4SetBufferLen < sizeof(uint32_t)) + return WLAN_STATUS_INVALID_LENGTH; + + pParam = (uint32_t *) pvSetBuffer; + if (*pParam != 0 && *pParam != 1) { + DBGLOG(INIT, ERROR, "NCHO DFS scan mode invalid %d\n", + *pParam); + return WLAN_STATUS_INVALID_DATA; + } + + rStatus = wlanNchoSetFWEnable(prAdapter, *pParam); + if (rStatus == WLAN_STATUS_SUCCESS) { + wlanNchoInit(prAdapter, FALSE); + prAdapter->rNchoInfo.fgNCHOEnabled = *pParam; + DBGLOG(INIT, INFO, "NCHO enable is %d\n", *pParam); + } + + return rStatus; +} + +uint32_t +wlanoidQueryNchoEnable(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + uint32_t rStatus = WLAN_STATUS_FAILURE; + struct CMD_HEADER cmdV1Header; + struct CMD_HEADER *prCmdV1Header = (struct CMD_HEADER *) + pvQueryBuffer; + struct CMD_FORMAT_V1 *prCmdV1 = NULL; + + DEBUGFUNC("wlanoidQueryNchoRoamTrigger"); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + *pu4QueryInfoLen = sizeof(struct CMD_HEADER); + + if (u4QueryBufferLen < sizeof(struct CMD_HEADER)) + return WLAN_STATUS_BUFFER_TOO_SHORT; + + prCmdV1 = (struct CMD_FORMAT_V1 *) prCmdV1Header->buffer; + rStatus = wlanoidSetNchoHeader(prCmdV1Header, + prCmdV1, + FW_CFG_KEY_NCHO_ENABLE, + kalStrLen(FW_CFG_KEY_NCHO_ENABLE)); + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, ERROR, "NCHO no enough memory\n"); + return rStatus; + } + kalMemCopy(&cmdV1Header, prCmdV1Header, + sizeof(struct CMD_HEADER)); + rStatus = wlanSendSetQueryCmd( + prAdapter, + CMD_ID_GET_SET_CUSTOMER_CFG, + FALSE, + TRUE, + TRUE, + nicCmdEventQueryCfgRead, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_HEADER), + (uint8_t *)&cmdV1Header, + pvQueryBuffer, + u4QueryBufferLen); + return rStatus; +} +#endif /* CFG_SUPPORT_NCHO */ + +#if CFG_SUPPORT_EASY_DEBUG +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set fw cfg info + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer Pointer to the buffer that holds the data to be + * set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_INVALID_DATA + * \retval WLAN_STATUS_SUCCESS + */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanoidSetFwParam(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + ASSERT(prAdapter); + + if (!pvSetBuffer || !u4SetBufferLen) { + DBGLOG(OID, ERROR, "Buffer is NULL\n"); + return WLAN_STATUS_INVALID_DATA; + } + DBGLOG(OID, INFO, "Fw Params: %s\n", (uint8_t *)pvSetBuffer); + return wlanFwCfgParse(prAdapter, (uint8_t *)pvSetBuffer); +} +#endif /* CFG_SUPPORT_EASY_DEBUG */ + +uint32_t +wlanoidAddRoamScnChnl(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + struct CFG_SCAN_CHNL *prRoamScnChnl = NULL; + + *pu4SetInfoLen = sizeof(struct CFG_SCAN_CHNL); + + if (u4SetBufferLen < sizeof(struct CFG_SCAN_CHNL)) + return WLAN_STATUS_INVALID_LENGTH; + + prRoamScnChnl = (struct CFG_SCAN_CHNL *) pvSetBuffer; + + kalMemCopy(&prAdapter->rAddRoamScnChnl, prRoamScnChnl, *pu4SetInfoLen); + DBGLOG(INIT, TRACE, "set roam scan channel num is %d\n", + prRoamScnChnl->ucChannelListNum); + + return WLAN_STATUS_SUCCESS; +} + +uint32_t +wlanoidAbortScan(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + + struct AIS_FSM_INFO *prAisFsmInfo = NULL; + uint8_t ucBssIndex = 0; + + ucBssIndex = GET_IOCTL_BSSIDX(prAdapter); + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + if (prAisFsmInfo->eCurrentState == AIS_STATE_SCAN || + prAisFsmInfo->eCurrentState == AIS_STATE_ONLINE_SCAN) { + DBGLOG(OID, INFO, "ucBssIndex = %d\n", ucBssIndex); + prAisFsmInfo->fgIsScanOidAborted = TRUE; + aisFsmStateAbort_SCAN(prAdapter, ucBssIndex); + } + return WLAN_STATUS_SUCCESS; +} + +uint32_t +wlanoidDisableTdlsPs(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct CMD_TDLS_PS_T rTdlsPs; + + if (!prAdapter || !pvSetBuffer) + return WLAN_STATUS_INVALID_DATA; + + rTdlsPs.ucIsEnablePs = *(uint8_t *)pvSetBuffer - '0'; + DBGLOG(OID, INFO, "enable tdls ps %d\n", + rTdlsPs.ucIsEnablePs); + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_TDLS_PS, + TRUE, + FALSE, + TRUE, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(rTdlsPs), + (uint8_t *)&rTdlsPs, + NULL, + 0); +} + +uint32_t wlanoidSetSer(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + uint32_t u4CmdId; + + /* check SER is supported or not */ + if (prAdapter->rWifiVar.fgEnableSer == FALSE) + return WLAN_STATUS_NOT_SUPPORTED; +#if defined(_HIF_USB) + if (prAdapter->chip_info->u4SerUsbMcuEventAddr == 0) + return WLAN_STATUS_NOT_SUPPORTED; + +#endif + + if (u4SetBufferLen) + ASSERT(pvSetBuffer); + + if (u4SetBufferLen != sizeof(uint32_t)) + return WLAN_STATUS_INVALID_LENGTH; + + u4CmdId = *((uint32_t *)pvSetBuffer); + + DBGLOG(OID, INFO, "Set SER CMD[%d]\n", u4CmdId); + + switch (u4CmdId) { + case SER_USER_CMD_DISABLE: + wlanoidSerExtCmd(prAdapter, SER_ACTION_SET, + SER_SET_DISABLE, 0); + break; + + case SER_USER_CMD_ENABLE: + wlanoidSerExtCmd(prAdapter, SER_ACTION_SET, SER_SET_ENABLE, 0); + break; + + case SER_USER_CMD_ENABLE_MASK_TRACKING_ONLY: + wlanoidSerExtCmd(prAdapter, SER_ACTION_SET_ENABLE_MASK, + SER_ENABLE_TRACKING, 0); + break; + + case SER_USER_CMD_ENABLE_MASK_L1_RECOVER_ONLY: + wlanoidSerExtCmd(prAdapter, SER_ACTION_SET_ENABLE_MASK, + SER_ENABLE_TRACKING | SER_ENABLE_L1_RECOVER, + 0); + break; + + case SER_USER_CMD_ENABLE_MASK_L2_RECOVER_ONLY: + wlanoidSerExtCmd(prAdapter, SER_ACTION_SET_ENABLE_MASK, + SER_ENABLE_TRACKING | SER_ENABLE_L2_RECOVER, + 0); + break; + + case SER_USER_CMD_ENABLE_MASK_L3_RX_ABORT_ONLY: + wlanoidSerExtCmd(prAdapter, SER_ACTION_SET_ENABLE_MASK, + SER_ENABLE_TRACKING | SER_ENABLE_L3_RX_ABORT, + 0); + break; + + case SER_USER_CMD_ENABLE_MASK_L3_TX_ABORT_ONLY: + wlanoidSerExtCmd(prAdapter, SER_ACTION_SET_ENABLE_MASK, + SER_ENABLE_TRACKING | SER_ENABLE_L3_TX_ABORT, + 0); + break; + + case SER_USER_CMD_ENABLE_MASK_L3_TX_DISABLE_ONLY: + wlanoidSerExtCmd(prAdapter, SER_ACTION_SET_ENABLE_MASK, + SER_ENABLE_TRACKING | + SER_ENABLE_L3_TX_DISABLE, 0); + break; + + case SER_USER_CMD_ENABLE_MASK_L3_BFRECOVER_ONLY: + wlanoidSerExtCmd(prAdapter, SER_ACTION_SET_ENABLE_MASK, + SER_ENABLE_TRACKING | + SER_ENABLE_L3_BF_RECOVER, 0); + break; + + case SER_USER_CMD_ENABLE_MASK_RECOVER_ALL: + wlanoidSerExtCmd(prAdapter, SER_ACTION_SET_ENABLE_MASK, + (SER_ENABLE_TRACKING | + SER_ENABLE_L1_RECOVER | + SER_ENABLE_L2_RECOVER | + SER_ENABLE_L3_RX_ABORT | + SER_ENABLE_L3_TX_ABORT | + SER_ENABLE_L3_TX_DISABLE | + SER_ENABLE_L3_BF_RECOVER), 0); + break; + + case SER_USER_CMD_L0_RECOVER: + wlanoidSerExtCmd(prAdapter, SER_ACTION_RECOVER, + SER_SET_L0_RECOVER, 0); + break; + + case SER_USER_CMD_L1_RECOVER: + wlanoidSerExtCmd(prAdapter, SER_ACTION_RECOVER, + SER_SET_L1_RECOVER, 0); + break; + + case SER_USER_CMD_L2_BN0_RECOVER: + wlanoidSerExtCmd(prAdapter, SER_ACTION_RECOVER, + SER_SET_L2_RECOVER, ENUM_BAND_0); + break; + + case SER_USER_CMD_L2_BN1_RECOVER: + wlanoidSerExtCmd(prAdapter, SER_ACTION_RECOVER, + SER_SET_L2_RECOVER, ENUM_BAND_1); + break; + + case SER_USER_CMD_L3_RX0_ABORT: + wlanoidSerExtCmd(prAdapter, SER_ACTION_RECOVER, + SER_SET_L3_RX_ABORT, ENUM_BAND_0); + break; + + case SER_USER_CMD_L3_RX1_ABORT: + wlanoidSerExtCmd(prAdapter, SER_ACTION_RECOVER, + SER_SET_L3_RX_ABORT, ENUM_BAND_1); + break; + + case SER_USER_CMD_L3_TX0_ABORT: + wlanoidSerExtCmd(prAdapter, SER_ACTION_RECOVER, + SER_SET_L3_TX_ABORT, ENUM_BAND_0); + break; + + case SER_USER_CMD_L3_TX1_ABORT: + wlanoidSerExtCmd(prAdapter, SER_ACTION_RECOVER, + SER_SET_L3_TX_ABORT, ENUM_BAND_1); + break; + + case SER_USER_CMD_L3_TX0_DISABLE: + wlanoidSerExtCmd(prAdapter, SER_ACTION_RECOVER, + SER_SET_L3_TX_DISABLE, ENUM_BAND_0); + break; + + case SER_USER_CMD_L3_TX1_DISABLE: + wlanoidSerExtCmd(prAdapter, SER_ACTION_RECOVER, + SER_SET_L3_TX_DISABLE, ENUM_BAND_1); + break; + + case SER_USER_CMD_L3_BF_RECOVER: + wlanoidSerExtCmd(prAdapter, SER_ACTION_RECOVER, + SER_SET_L3_BF_RECOVER, 0); + break; + + default: + DBGLOG(OID, ERROR, "Error SER CMD\n"); + } + + return WLAN_STATUS_SUCCESS; +} + +uint32_t wlanoidSerExtCmd(IN struct ADAPTER *prAdapter, uint8_t ucAction, + uint8_t ucSerSet, uint8_t ucDbdcIdx) { + struct EXT_CMD_SER_T rCmdSer = {0}; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + + rCmdSer.ucAction = ucAction; + rCmdSer.ucSerSet = ucSerSet; + rCmdSer.ucDbdcIdx = ucDbdcIdx; + + rStatus = wlanSendSetQueryExtCmd(prAdapter, + CMD_ID_LAYER_0_EXT_MAGIC_NUM, + EXT_CMD_ID_SER, + TRUE, + FALSE, + TRUE, + NULL, + nicOidCmdTimeoutCommon, + sizeof(struct EXT_CMD_SER_T), + (uint8_t *)&rCmdSer, NULL, 0); + return rStatus; +} + +#if (CFG_SUPPORT_TXPOWER_INFO == 1) +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set rdd report. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * \param[out] pvQueryBuf A pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the call + * failed due to invalid length of the query buffer, + * returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryTxPowerInfo(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + struct PARAM_TXPOWER_ALL_RATE_POWER_INFO_T *prTxPowerInfo = + NULL; + struct CMD_TX_POWER_SHOW_INFO_T rCmdTxPowerShowInfo; + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + + if (!prAdapter) + return WLAN_STATUS_FAILURE; + if (!pvQueryBuffer) + return WLAN_STATUS_FAILURE; + if (!pu4QueryInfoLen) + return WLAN_STATUS_FAILURE; + + if (u4QueryBufferLen < + sizeof(struct PARAM_TXPOWER_ALL_RATE_POWER_INFO_T)) { + *pu4QueryInfoLen = sizeof(struct + PARAM_TXPOWER_ALL_RATE_POWER_INFO_T); + return WLAN_STATUS_BUFFER_TOO_SHORT; + } + + *pu4QueryInfoLen = sizeof(struct + PARAM_TXPOWER_ALL_RATE_POWER_INFO_T); + + prTxPowerInfo = (struct PARAM_TXPOWER_ALL_RATE_POWER_INFO_T + *) pvQueryBuffer; + + kalMemSet(&rCmdTxPowerShowInfo, 0, + sizeof(struct CMD_TX_POWER_SHOW_INFO_T)); + + rCmdTxPowerShowInfo.ucPowerCtrlFormatId = + TX_POWER_SHOW_INFO; + rCmdTxPowerShowInfo.ucTxPowerInfoCatg = + prTxPowerInfo->ucTxPowerCategory; + rCmdTxPowerShowInfo.ucBandIdx = prTxPowerInfo->ucBandIdx; + + rWlanStatus = wlanSendSetQueryExtCmd(prAdapter, + CMD_ID_LAYER_0_EXT_MAGIC_NUM, + EXT_CMD_ID_TX_POWER_FEATURE_CTRL, + FALSE, /* Query Bit: True->write False->read */ + TRUE, + TRUE, + nicCmdEventQueryTxPowerInfo, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_TX_POWER_SHOW_INFO_T), + (uint8_t *) (&rCmdTxPowerShowInfo), + pvQueryBuffer, + u4QueryBufferLen); + + return rWlanStatus; +} +#endif +uint32_t +wlanoidSetTxPowerByRateManual(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + + struct PARAM_TXPOWER_BY_RATE_SET_T *prPwrParam; + struct CMD_POWER_RATE_TXPOWER_CTRL_T rCmdPwrCtl; + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + + if (!prAdapter) + return WLAN_STATUS_FAILURE; + if (!pvSetBuffer) + return WLAN_STATUS_FAILURE; + + prPwrParam = (struct PARAM_TXPOWER_BY_RATE_SET_T + *) pvSetBuffer; + + kalMemSet(&rCmdPwrCtl, 0, + sizeof(struct CMD_POWER_RATE_TXPOWER_CTRL_T)); + + rCmdPwrCtl.u1PowerCtrlFormatId = TX_RATE_POWER_CTRL; + rCmdPwrCtl.u1PhyMode = prPwrParam->u1PhyMode; + rCmdPwrCtl.u1TxRate = prPwrParam->u1TxRate; + rCmdPwrCtl.u1BW = prPwrParam->u1BW; + rCmdPwrCtl.i1TxPower = prPwrParam->i1TxPower; + + rWlanStatus = wlanSendSetQueryExtCmd(prAdapter, + CMD_ID_LAYER_0_EXT_MAGIC_NUM, + EXT_CMD_ID_TX_POWER_FEATURE_CTRL, + TRUE, /* Query Bit: True->write False->read */ + FALSE, + TRUE, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(rCmdPwrCtl), + (uint8_t *) (&rCmdPwrCtl), + NULL, + 0); + + return rWlanStatus; +} + +#if CFG_SUPPORT_MBO +uint32_t +wlanoidBssDisallowedList(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct WIFI_VAR *prWifiVar = NULL; + + + if (!prAdapter || !u4SetBufferLen || !pvSetBuffer || + u4SetBufferLen != sizeof(struct PARAM_BSS_DISALLOWED_LIST)) + return WLAN_STATUS_NOT_ACCEPTED; + + prWifiVar = &prAdapter->rWifiVar; + kalMemCopy(&prWifiVar->rBssDisallowedList, pvSetBuffer, u4SetBufferLen); + DBGLOG(OID, INFO, "Set disallowed list size: %d\n", + prWifiVar->rBssDisallowedList.u4NumBssDisallowed); + return WLAN_STATUS_SUCCESS; +} +#endif + +uint32_t +wlanoidSetDrvRoamingPolicy(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + uint32_t u4RoamingPoily = 0; + struct ROAMING_INFO *prRoamingFsmInfo; + struct CONNECTION_SETTINGS *prConnSettings; + uint32_t u4CurConPolicy; + uint8_t ucBssIndex = 0; + + ASSERT(prAdapter); + ASSERT(pvSetBuffer); + + ucBssIndex = GET_IOCTL_BSSIDX(prAdapter); + + u4RoamingPoily = *(uint32_t *)pvSetBuffer; + + prRoamingFsmInfo = + aisGetRoamingInfo(prAdapter, ucBssIndex); + + prConnSettings = (struct CONNECTION_SETTINGS *) + aisGetConnSettings(prAdapter, ucBssIndex); + u4CurConPolicy = prConnSettings->eConnectionPolicy; + + if (u4RoamingPoily == 1) { + if (((aisGetCurrState(prAdapter, ucBssIndex) == + AIS_STATE_NORMAL_TR) + || (aisGetCurrState(prAdapter, ucBssIndex) == + AIS_STATE_ONLINE_SCAN)) + && (prRoamingFsmInfo->eCurrentState == ROAMING_STATE_IDLE)) + prConnSettings->eConnectionPolicy = CONNECT_BY_SSID_BEST_RSSI; + roamingFsmRunEventStart(prAdapter, ucBssIndex); + } else { + if (prRoamingFsmInfo->eCurrentState != ROAMING_STATE_IDLE) + roamingFsmRunEventAbort(prAdapter, ucBssIndex); + } + prRoamingFsmInfo->fgDrvRoamingAllow = (u_int8_t) + u4RoamingPoily; + + DBGLOG(REQ, INFO, + "wlanoidSetDrvRoamingPolicy, RoamingPoily= %d, conn policy= [%d] -> [%d]\n", + u4RoamingPoily, u4CurConPolicy, + prConnSettings->eConnectionPolicy); + + return WLAN_STATUS_SUCCESS; +} + +uint32_t wlanoidUpdateFtIes(struct ADAPTER *prAdapter, void *pvSetBuffer, + uint32_t u4SetBufferLen, uint32_t *pu4SetInfoLen) +{ + struct FT_IES *prFtIes = NULL; + uint32_t u4IeLen = 0; + uint8_t *pucIEStart = NULL; + struct cfg80211_update_ft_ies_params *ftie = NULL; + struct STA_RECORD *prStaRec = NULL; + struct MSG_SAA_FT_CONTINUE *prFtContinueMsg = NULL; + uint8_t ucBssIndex = 0; + + if (!pvSetBuffer || u4SetBufferLen == 0) { + DBGLOG(OID, ERROR, + "FT: pvSetBuffer is Null %d, Buffer Len %u\n", + !pvSetBuffer, u4SetBufferLen); + return WLAN_STATUS_INVALID_DATA; + } + + ucBssIndex = GET_IOCTL_BSSIDX(prAdapter); + + prStaRec = aisGetTargetStaRec(prAdapter, ucBssIndex); + ftie = (struct cfg80211_update_ft_ies_params *)pvSetBuffer; + prFtIes = aisGetFtIe(prAdapter, ucBssIndex); + if (ftie->ie_len == 0) { + DBGLOG(OID, WARN, "FT: FT Ies length is 0\n"); + return WLAN_STATUS_SUCCESS; + } + if (prFtIes->u4IeLength != ftie->ie_len) { + kalMemFree(prFtIes->pucIEBuf, VIR_MEM_TYPE, + prFtIes->u4IeLength); + prFtIes->pucIEBuf = kalMemAlloc(ftie->ie_len, VIR_MEM_TYPE); + prFtIes->u4IeLength = ftie->ie_len; + } + + if (!prFtIes->pucIEBuf) { + DBGLOG(OID, ERROR, + "FT: prFtIes->pucIEBuf memory allocation failed, ft ie_len=%u\n", + ftie->ie_len); + return WLAN_STATUS_FAILURE; + } + + pucIEStart = prFtIes->pucIEBuf; + u4IeLen = prFtIes->u4IeLength; + prFtIes->u2MDID = ftie->md; + prFtIes->prFTIE = NULL; + prFtIes->prMDIE = NULL; + prFtIes->prRsnIE = NULL; + prFtIes->prTIE = NULL; + if (u4IeLen) + kalMemCopy(pucIEStart, ftie->ie, u4IeLen); + while (u4IeLen >= 2) { + uint32_t u4InfoElemLen = IE_SIZE(pucIEStart); + + if (u4InfoElemLen > u4IeLen) + break; + switch (pucIEStart[0]) { + case ELEM_ID_MOBILITY_DOMAIN: + prFtIes->prMDIE = + (struct IE_MOBILITY_DOMAIN *)pucIEStart; + break; + case ELEM_ID_FAST_TRANSITION: + prFtIes->prFTIE = + (struct IE_FAST_TRANSITION *)pucIEStart; + break; + case ELEM_ID_RESOURCE_INFO_CONTAINER: + break; + case ELEM_ID_TIMEOUT_INTERVAL: + prFtIes->prTIE = + (struct IE_TIMEOUT_INTERVAL *)pucIEStart; + break; + case ELEM_ID_RSN: + prFtIes->prRsnIE = (struct RSN_INFO_ELEM *)pucIEStart; + break; + } + u4IeLen -= u4InfoElemLen; + pucIEStart += u4InfoElemLen; + } + DBGLOG(OID, INFO, + "FT: MdId %d IesLen %u, MDIE %d FTIE %d RSN %d TIE %d\n", + ftie->md, prFtIes->u4IeLength, !!prFtIes->prMDIE, + !!prFtIes->prFTIE, !!prFtIes->prRsnIE, !!prFtIes->prTIE); + /* check if SAA is waiting to send Reassoc req */ + if (!prStaRec || prStaRec->ucAuthTranNum != AUTH_TRANSACTION_SEQ_2 || + !prStaRec->fgIsReAssoc || prStaRec->ucStaState != STA_STATE_1) + return WLAN_STATUS_SUCCESS; + + prFtContinueMsg = (struct MSG_SAA_FT_CONTINUE *)cnmMemAlloc( + prAdapter, RAM_TYPE_MSG, sizeof(struct MSG_SAA_FT_CONTINUE)); + if (!prFtContinueMsg) { + DBGLOG(OID, WARN, "FT: failed to allocate Join Req Msg\n"); + return WLAN_STATUS_FAILURE; + } + prFtContinueMsg->rMsgHdr.eMsgId = MID_OID_SAA_FSM_CONTINUE; + prFtContinueMsg->prStaRec = prStaRec; + /* ToDo: for Resource Request Protocol, we need to check if RIC request + ** is included. + */ + if (prFtIes->prMDIE && (prFtIes->prMDIE->ucBitMap & BIT(1))) + prFtContinueMsg->fgFTRicRequest = TRUE; + else + prFtContinueMsg->fgFTRicRequest = FALSE; + DBGLOG(OID, INFO, "FT: continue to do auth/assoc, Ft Request %d\n", + prFtContinueMsg->fgFTRicRequest); + mboxSendMsg(prAdapter, MBOX_ID_0, (struct MSG_HDR *)prFtContinueMsg, + MSG_SEND_METHOD_BUF); + return WLAN_STATUS_SUCCESS; +} + +uint32_t wlanoidSendNeighborRequest(struct ADAPTER *prAdapter, + void *pvSetBuffer, uint32_t u4SetBufferLen, + uint32_t *pu4SetInfoLen) +{ + struct SUB_ELEMENT_LIST *prSSIDIE = NULL; + struct BSS_INFO *prAisBssInfo = NULL; + uint8_t ucSSIDIELen = 0; + uint8_t *pucSSID = (uint8_t *)pvSetBuffer; + uint8_t ucBssIndex = 0; + + if (!prAdapter) + return WLAN_STATUS_INVALID_DATA; + + ucBssIndex = GET_IOCTL_BSSIDX(prAdapter); + + prAisBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + if (!prAisBssInfo) + return WLAN_STATUS_INVALID_DATA; + if (prAisBssInfo->eConnectionState != MEDIA_STATE_CONNECTED) { + DBGLOG(OID, ERROR, "didn't connected any Access Point\n"); + return WLAN_STATUS_FAILURE; + } + if (u4SetBufferLen == 0 || !pucSSID) { + rrmTxNeighborReportRequest(prAdapter, + prAisBssInfo->prStaRecOfAP, NULL); + return WLAN_STATUS_SUCCESS; + } + + ucSSIDIELen = (uint8_t)(u4SetBufferLen + sizeof(*prSSIDIE)); + prSSIDIE = kalMemAlloc(ucSSIDIELen, PHY_MEM_TYPE); + if (!prSSIDIE) { + DBGLOG(OID, ERROR, "No Memory\n"); + return WLAN_STATUS_FAILURE; + } + prSSIDIE->prNext = NULL; + prSSIDIE->rSubIE.ucSubID = ELEM_ID_SSID; + prSSIDIE->rSubIE.ucLength = (uint8_t)u4SetBufferLen; + kalMemCopy(&prSSIDIE->rSubIE.aucOptInfo[0], pucSSID, + (uint8_t)u4SetBufferLen); + DBGLOG(OID, INFO, "Send Neighbor Request, SSID=%s\n", HIDE(pucSSID)); + rrmTxNeighborReportRequest(prAdapter, prAisBssInfo->prStaRecOfAP, + prSSIDIE); + kalMemFree(prSSIDIE, PHY_MEM_TYPE, ucSSIDIELen); + return WLAN_STATUS_SUCCESS; +} + +uint32_t wlanoidSync11kCapabilities(struct ADAPTER *prAdapter, + void *pvSetBuffer, uint32_t u4SetBufferLen, + uint32_t *pu4SetInfoLen) +{ + struct CMD_SET_RRM_CAPABILITY rCmdRrmCapa; + + kalMemZero(&rCmdRrmCapa, sizeof(rCmdRrmCapa)); + rCmdRrmCapa.ucCmdVer = 0x1; + rCmdRrmCapa.ucRrmEnable = 1; + rrmFillRrmCapa(&rCmdRrmCapa.ucCapabilities[0]); + rCmdRrmCapa.ucBssIndex = GET_IOCTL_BSSIDX(prAdapter); + wlanSendSetQueryCmd(prAdapter, + CMD_ID_SET_RRM_CAPABILITY, + TRUE, + FALSE, + TRUE, + NULL, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_SET_RRM_CAPABILITY), + (uint8_t *)&rCmdRrmCapa, + pvSetBuffer, u4SetBufferLen); + return WLAN_STATUS_SUCCESS; +} + +uint32_t wlanoidSendBTMQuery(struct ADAPTER *prAdapter, void *pvSetBuffer, + uint32_t u4SetBufferLen, uint32_t *pu4SetInfoLen) +{ + struct STA_RECORD *prStaRec = NULL; + struct BSS_TRANSITION_MGT_PARAM_T *prBtmMgt = NULL; + struct BSS_INFO *prAisBssInfo; + uint8_t ucBssIndex = 0; + int32_t u4Ret = 0; + + ucBssIndex = GET_IOCTL_BSSIDX(prAdapter); + + prAisBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + + if (!prAisBssInfo || + prAisBssInfo->eConnectionState != + MEDIA_STATE_CONNECTED) { + DBGLOG(OID, INFO, "Not connected yet\n"); + return WLAN_STATUS_FAILURE; + } + prStaRec = prAisBssInfo->prStaRecOfAP; + if (!prStaRec || !prStaRec->fgSupportBTM) { + DBGLOG(OID, INFO, + "Target BSS(%p) didn't support Bss Transition Management\n", + prStaRec); + return WLAN_STATUS_FAILURE; + } + prBtmMgt = aisGetBTMParam(prAdapter, ucBssIndex); + prBtmMgt->ucDialogToken = wnmGetBtmToken(); + if (pvSetBuffer) { + u4Ret = kalkStrtou8(pvSetBuffer, 0, &prBtmMgt->ucQueryReason); + if (u4Ret) + DBGLOG(OID, WARN, "parse reason u4Ret=%d\n", u4Ret); + } else { + prBtmMgt->ucQueryReason = BSS_TRANSITION_LOW_RSSI; + } + DBGLOG(OID, INFO, "Send BssTransitionManagementQuery, Reason %d\n", + prBtmMgt->ucQueryReason); + wnmSendBTMQueryFrame(prAdapter, prStaRec); + return WLAN_STATUS_SUCCESS; +} + +uint32_t wlanoidTspecOperation(struct ADAPTER *prAdapter, void *pvBuffer, + uint32_t u4BufferLen, uint32_t *pu4InfoLen) +{ + struct PARAM_QOS_TSPEC *prTspecParam = NULL; + struct MSG_TS_OPERATE *prMsgTsOperate = NULL; + uint8_t *pucCmd = (uint8_t *)pvBuffer; + uint8_t *pucSavedPtr = NULL; + uint8_t *pucItem = NULL; + uint32_t u4Ret = 1; + uint8_t ucApsdSetting = 2; /* 0: legacy; 1: u-apsd; 2: not set yet */ + uint8_t ucBssIndex = 0; + enum TSPEC_OP_CODE eTsOp; + struct BSS_INFO *prAisBssInfo; + +#if !CFG_SUPPORT_WMM_AC + DBGLOG(OID, INFO, "WMM AC is not supported\n"); + return WLAN_STATUS_FAILURE; +#endif + + ucBssIndex = GET_IOCTL_BSSIDX(prAdapter); + + if (kalStrniCmp(pucCmd, "dumpts", 6) == 0) { + *pu4InfoLen = kalSnprintf(pucCmd, u4BufferLen, "%s", + "\nAll Active Tspecs:\n"); + u4BufferLen -= *pu4InfoLen; + pucCmd += *pu4InfoLen; + *pu4InfoLen += + wmmDumpActiveTspecs(prAdapter, pucCmd, u4BufferLen, + ucBssIndex); + return WLAN_STATUS_SUCCESS; + } + + if (kalStrniCmp(pucCmd, "addts", 5) == 0) + eTsOp = TX_ADDTS_REQ; + else if (kalStrniCmp(pucCmd, "delts", 5) == 0) + eTsOp = TX_DELTS_REQ; + else { + DBGLOG(OID, INFO, "wrong operation %s\n", pucCmd); + return WLAN_STATUS_FAILURE; + } + /* addts token n,tid n,dir n,psb n,up n,fixed n,size n,maxsize + ** n,maxsrvint n, minsrvint n, + ** inact n, suspension n, srvstarttime n, minrate n,meanrate n,peakrate + ** n,burst n,delaybound n, + ** phyrate n,SBA n,mediumtime n + */ + prMsgTsOperate = (struct MSG_TS_OPERATE *)cnmMemAlloc( + prAdapter, RAM_TYPE_MSG, sizeof(struct MSG_TS_OPERATE)); + if (!prMsgTsOperate) + return WLAN_STATUS_FAILURE; + + kalMemZero(prMsgTsOperate, sizeof(struct MSG_TS_OPERATE)); + prMsgTsOperate->rMsgHdr.eMsgId = MID_OID_WMM_TSPEC_OPERATE; + prMsgTsOperate->eOpCode = eTsOp; + prTspecParam = &prMsgTsOperate->rTspecParam; + pucCmd += 6; + pucItem = (uint8_t *)kalStrtokR(pucCmd, ",", &pucSavedPtr); + while (pucItem) { + if (kalStrniCmp(pucItem, "token ", 6) == 0) + u4Ret = kalkStrtou8(pucItem + 6, 0, + &prTspecParam->ucDialogToken); + else if (kalStrniCmp(pucItem, "tid ", 4) == 0) { + u4Ret = kalkStrtou8(pucItem + 4, 0, + &prMsgTsOperate->ucTid); + prTspecParam->rTsInfo.ucTid = prMsgTsOperate->ucTid; + } else if (kalStrniCmp(pucItem, "dir ", 4) == 0) + u4Ret = kalkStrtou8(pucItem + 4, 0, + &prTspecParam->rTsInfo.ucDirection); + else if (kalStrniCmp(pucItem, "psb ", 4) == 0) + u4Ret = kalkStrtou8(pucItem+4, 0, &ucApsdSetting); + else if (kalStrniCmp(pucItem, "up ", 3) == 0) + u4Ret = kalkStrtou8(pucItem + 3, 0, + &prTspecParam->rTsInfo.ucuserPriority); + else if (kalStrniCmp(pucItem, "size ", 5) == 0) { + uint16_t u2Size = 0; + + u4Ret = kalkStrtou16(pucItem+5, 0, &u2Size); + prTspecParam->u2NominalMSDUSize |= u2Size; + } else if (kalStrniCmp(pucItem, "fixed ", 6) == 0) { + uint8_t ucFixed = 0; + + u4Ret = kalkStrtou8(pucItem+6, 0, &ucFixed); + if (ucFixed) + prTspecParam->u2NominalMSDUSize |= BIT(15); + } else if (kalStrniCmp(pucItem, "maxsize ", 8) == 0) + u4Ret = kalkStrtou16(pucItem + 8, 0, + &prTspecParam->u2MaxMSDUsize); + else if (kalStrniCmp(pucItem, "maxsrvint ", 10) == 0) + u4Ret = kalkStrtou32(pucItem + 10, 0, + &prTspecParam->u4MaxSvcIntv); + else if (kalStrniCmp(pucItem, "minsrvint ", 10) == 0) + u4Ret = kalkStrtou32(pucItem + 10, 0, + &prTspecParam->u4MinSvcIntv); + else if (kalStrniCmp(pucItem, "inact ", 6) == 0) + u4Ret = kalkStrtou32(pucItem + 6, 0, + &prTspecParam->u4InactIntv); + else if (kalStrniCmp(pucItem, "suspension ", 11) == 0) + u4Ret = kalkStrtou32(pucItem + 11, 0, + &prTspecParam->u4SpsIntv); + else if (kalStrniCmp(pucItem, "srvstarttime ", 13) == 0) + u4Ret = kalkStrtou32(pucItem + 13, 0, + &prTspecParam->u4SvcStartTime); + else if (kalStrniCmp(pucItem, "minrate ", 8) == 0) + u4Ret = kalkStrtou32(pucItem + 8, 0, + &prTspecParam->u4MinDataRate); + else if (kalStrniCmp(pucItem, "meanrate ", 9) == 0) + u4Ret = kalkStrtou32(pucItem + 9, 0, + &prTspecParam->u4MeanDataRate); + else if (kalStrniCmp(pucItem, "peakrate ", 9) == 0) + u4Ret = kalkStrtou32(pucItem + 9, 0, + &prTspecParam->u4PeakDataRate); + else if (kalStrniCmp(pucItem, "burst ", 6) == 0) + u4Ret = kalkStrtou32(pucItem + 6, 0, + &prTspecParam->u4MaxBurstSize); + else if (kalStrniCmp(pucItem, "delaybound ", 11) == 0) + u4Ret = kalkStrtou32(pucItem + 11, 0, + &prTspecParam->u4DelayBound); + else if (kalStrniCmp(pucItem, "phyrate ", 8) == 0) + u4Ret = kalkStrtou32(pucItem + 8, 0, + &prTspecParam->u4MinPHYRate); + else if (kalStrniCmp(pucItem, "sba ", 4) == 0) + u4Ret = wlanDecimalStr2Hexadecimals( + pucItem + 4, &prTspecParam->u2Sba); + else if (kalStrniCmp(pucItem, "mediumtime ", 11) == 0) + u4Ret = kalkStrtou16(pucItem + 11, 0, + &prTspecParam->u2MediumTime); + + if (u4Ret) { + DBGLOG(OID, ERROR, "Parse %s error\n", pucItem); + cnmMemFree(prAdapter, prMsgTsOperate); + return WLAN_STATUS_FAILURE; + } + pucItem = + (uint8_t *)kalStrtokR(NULL, ",", &pucSavedPtr); + } + /* if APSD is not set in addts request, use global wmmps settings */ + prAisBssInfo = + aisGetAisBssInfo(prAdapter, ucBssIndex); + if (!prAisBssInfo) + DBGLOG(OID, ERROR, "AisBssInfo is NULL!\n"); + else if (ucApsdSetting == 2) { + struct PM_PROFILE_SETUP_INFO *prPmProf = NULL; + enum ENUM_ACI eAc = + aucUp2ACIMap[prTspecParam->rTsInfo.ucuserPriority]; + + prPmProf = &prAisBssInfo->rPmProfSetupInfo; + switch (prTspecParam->rTsInfo.ucDirection) { + case UPLINK_TS: /* UpLink*/ + if (prPmProf->ucBmpTriggerAC & BIT(eAc)) + prTspecParam->rTsInfo.ucApsd = 1; + break; + case DOWNLINK_TS:/* DownLink */ + if (prPmProf->ucBmpDeliveryAC & BIT(eAc)) + prTspecParam->rTsInfo.ucApsd = 1; + break; + case BI_DIR_TS: /* Bi-directional */ + if ((prPmProf->ucBmpTriggerAC & BIT(eAc)) && + (prPmProf->ucBmpDeliveryAC & BIT(eAc))) + prTspecParam->rTsInfo.ucApsd = 1; + break; + } + } else + prTspecParam->rTsInfo.ucApsd = ucApsdSetting; + *(--pucCmd) = 0; + pucCmd -= 5; + DBGLOG(OID, INFO, + "%d: %s %d %d %d %d %d %d %d %u %u %u %u %u %u %u %u %u %u %u 0x%04x %d\n", + ucBssIndex, + pucCmd, prTspecParam->ucDialogToken, prTspecParam->rTsInfo.ucTid, + prTspecParam->rTsInfo.ucDirection, prTspecParam->rTsInfo.ucApsd, + prTspecParam->rTsInfo.ucuserPriority, + prTspecParam->u2NominalMSDUSize, prTspecParam->u2MaxMSDUsize, + prTspecParam->u4MaxSvcIntv, prTspecParam->u4MinSvcIntv, + prTspecParam->u4InactIntv, prTspecParam->u4SpsIntv, + prTspecParam->u4SvcStartTime, prTspecParam->u4MinDataRate, + prTspecParam->u4MeanDataRate, prTspecParam->u4PeakDataRate, + prTspecParam->u4MaxBurstSize, prTspecParam->u4DelayBound, + prTspecParam->u4MinPHYRate, prTspecParam->u2Sba, + prTspecParam->u2MediumTime); + prMsgTsOperate->ucBssIdx = ucBssIndex; + mboxSendMsg(prAdapter, MBOX_ID_0, (struct MSG_HDR *)prMsgTsOperate, + MSG_SEND_METHOD_BUF); + return WLAN_STATUS_SUCCESS; +} + +/* It's a Integretion Test function for RadioMeasurement. If you found errors +** during doing Radio Measurement, +** you can run this IT function with iwpriv wlan0 driver \"RM-IT +** xx,xx,xx, xx\" +** xx,xx,xx,xx is the RM request frame data +*/ +uint32_t wlanoidPktProcessIT(struct ADAPTER *prAdapter, void *pvBuffer, + uint32_t u4BufferLen, uint32_t *pu4InfoLen) +{ + struct SW_RFB rSwRfb; + static uint8_t aucPacket[200] = {0,}; + uint8_t *pucSavedPtr = (int8_t *)pvBuffer; + uint8_t *pucItem = NULL; + uint8_t j = 0; + int8_t i = 0; + uint8_t ucByte; + u_int8_t fgBTMReq = FALSE; + void (*process_func)(struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb); + uint8_t ucBssIndex = 0; + + ucBssIndex = GET_IOCTL_BSSIDX(prAdapter); + + if (!pvBuffer) { + DBGLOG(OID, ERROR, "pvBuffer is NULL\n"); + return WLAN_STATUS_FAILURE; + } + + if (!kalStrniCmp(pucSavedPtr, "RM-IT", 5)) { + process_func = rrmProcessRadioMeasurementRequest; + pucSavedPtr += 5; + } else if (!kalStrniCmp(pucSavedPtr, "BTM-IT", 6)) { + process_func = wnmRecvBTMRequest; + pucSavedPtr += 6; + fgBTMReq = TRUE; + } else if (!kalStrniCmp(pucSavedPtr, "BT-IT", 5)) { + DBGLOG(OID, INFO, "Simulate beacon timeout!!!\n"); + aisBssBeaconTimeout(prAdapter, ucBssIndex); + return WLAN_STATUS_SUCCESS; + } else { + pucSavedPtr[10] = 0; + DBGLOG(OID, ERROR, "IT type %s is not supported\n", + pucSavedPtr); + return WLAN_STATUS_NOT_SUPPORTED; + } + kalMemZero(aucPacket, sizeof(aucPacket)); + pucItem = kalStrtokR(pucSavedPtr, ",", &pucSavedPtr); + while (pucItem) { + ucByte = *pucItem; + i = 0; + while (ucByte) { + if (i > 1) { + DBGLOG(OID, ERROR, + "more than 2 char for one byte\n"); + return WLAN_STATUS_FAILURE; + } else if (i == 1) + aucPacket[j] <<= 4; + if (ucByte >= '0' && ucByte <= '9') + aucPacket[j] |= ucByte - '0'; + else if (ucByte >= 'a' && ucByte <= 'f') + aucPacket[j] |= ucByte - 'a' + 10; + else if (ucByte >= 'A' && ucByte <= 'F') + aucPacket[j] |= ucByte - 'A' + 10; + else { + DBGLOG(OID, ERROR, "not a hex char %c\n", + ucByte); + return WLAN_STATUS_FAILURE; + } + ucByte = *(++pucItem); + i++; + } + j++; + pucItem = kalStrtokR(NULL, ",", &pucSavedPtr); + } + DBGLOG(OID, INFO, "Dump IT packet, len %d\n", j); + dumpMemory8(aucPacket, j); + if (j < WLAN_MAC_MGMT_HEADER_LEN) { + DBGLOG(OID, ERROR, "packet length %d less than mac header 24\n", + j); + return WLAN_STATUS_FAILURE; + } + kalMemZero(&rSwRfb, sizeof(rSwRfb)); + rSwRfb.pvHeader = (void *)&aucPacket[0]; + rSwRfb.u2PacketLen = j; + rSwRfb.u2HeaderLen = WLAN_MAC_MGMT_HEADER_LEN; + rSwRfb.ucStaRecIdx = KAL_NETWORK_TYPE_AIS_INDEX; + if (fgBTMReq) { + struct HW_MAC_RX_DESC rRxStatus; + + rRxStatus.ucChanFreq = 6; + rSwRfb.ucChnlNum = HAL_RX_STATUS_GET_CHNL_NUM(&rRxStatus); + rSwRfb.prRxStatus = (void *)&rRxStatus; + rSwRfb.ucChanFreq = 6; + wnmWNMAction(prAdapter, &rSwRfb); + } else { + process_func(prAdapter, &rSwRfb); + } + + return WLAN_STATUS_SUCCESS; +} + +/* Firmware Integration Test functions +** This function receives commands that are input by a firmware IT test script +** By using IT test script, RD no need to run IT with a real Access Point +** For example: iwpriv wlan0 driver \"Fw-Event Roaming ....\" +*/ +uint32_t wlanoidFwEventIT(struct ADAPTER *prAdapter, void *pvBuffer, + uint32_t u4BufferLen, uint32_t *pu4InfoLen) +{ + uint8_t *pucCmd = (int8_t *)pvBuffer; + uint8_t ucBssIndex = 0; + + ucBssIndex = GET_IOCTL_BSSIDX(prAdapter); + + /* Firmware roaming Integration Test case */ + if (!kalStrniCmp(pucCmd, "Roaming", 7)) { + struct CMD_ROAMING_TRANSIT rTransit = {0}; + struct BSS_DESC *prBssDesc = + aisGetTargetBssDesc(prAdapter, ucBssIndex); + + if (prBssDesc) + rTransit.u2Data = prBssDesc->ucRCPI; + rTransit.u2Event = ROAMING_EVENT_DISCOVERY; + rTransit.eReason = ROAMING_REASON_POOR_RCPI; + rTransit.ucBssidx = ucBssIndex; + roamingFsmRunEventDiscovery(prAdapter, &rTransit); + } else { + DBGLOG(OID, ERROR, "Not supported Fw Event IT type %s\n", + pucCmd); + return WLAN_STATUS_FAILURE; + } + return WLAN_STATUS_SUCCESS; +} + +uint32_t wlanoidDumpUapsdSetting(struct ADAPTER *prAdapter, void *pvBuffer, + uint32_t u4BufferLen, uint32_t *pu4InfoLen) +{ + uint8_t *pucCmd = (uint8_t *)pvBuffer; + uint8_t ucFinalSetting = 0; + uint8_t ucStaticSetting = 0; + struct PM_PROFILE_SETUP_INFO *prPmProf = NULL; + struct BSS_INFO *prAisBssInfo; + uint8_t ucBssIndex = 0; + + if (!pvBuffer) { + DBGLOG(OID, ERROR, "pvBuffer is NULL\n"); + return WLAN_STATUS_FAILURE; + } + + ucBssIndex = GET_IOCTL_BSSIDX(prAdapter); + + prAisBssInfo = + aisGetAisBssInfo(prAdapter, ucBssIndex); + + if (!prAisBssInfo) + return WLAN_STATUS_FAILURE; + prPmProf = &prAisBssInfo->rPmProfSetupInfo; + ucStaticSetting = + (prPmProf->ucBmpDeliveryAC << 4) | prPmProf->ucBmpTriggerAC; + ucFinalSetting = wmmCalculateUapsdSetting(prAdapter, ucBssIndex); + *pu4InfoLen = kalSnprintf( + pucCmd, u4BufferLen, + "\nStatic Uapsd Setting:0x%02x\nFinal Uapsd Setting:0x%02x", + ucStaticSetting, ucFinalSetting); + return WLAN_STATUS_SUCCESS; +} + +#if CFG_SUPPORT_OSHARE +uint32_t +wlanoidSetOshareMode(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + if (!prAdapter || !pvSetBuffer) + return WLAN_STATUS_INVALID_DATA; + + DBGLOG(OID, TRACE, "wlanoidSetOshareMode\n"); + + return wlanSendSetQueryCmd(prAdapter, /* prAdapter */ + CMD_ID_SET_OSHARE_MODE, /* ucCID */ + TRUE, /* fgSetQuery */ + FALSE, /* fgNeedResp */ + TRUE, /* fgIsOid */ + nicCmdEventSetCommon, /* pfCmdDoneHandler*/ + nicOidCmdTimeoutCommon, /* pfCmdTimeoutHandler */ + u4SetBufferLen, /* u4SetQueryInfoLen */ + (uint8_t *) pvSetBuffer,/* pucInfoBuffer */ + NULL, /* pvSetQueryBuffer */ + 0); /* u4SetQueryBufferLen */ +} +#endif + +uint32_t +wlanoidQueryWifiLogLevelSupport(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + struct PARAM_WIFI_LOG_LEVEL_UI *pparam; + + ASSERT(prAdapter); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + ASSERT(pu4QueryInfoLen); + + pparam = (struct PARAM_WIFI_LOG_LEVEL_UI *) pvQueryBuffer; + pparam->u4Enable = wlanDbgLevelUiSupport(prAdapter, + pparam->u4Version, pparam->u4Module); + + DBGLOG(OID, INFO, "version: %d, module: %d, enable: %d\n", + pparam->u4Version, + pparam->u4Module, + pparam->u4Enable); + + *pu4QueryInfoLen = sizeof(struct PARAM_WIFI_LOG_LEVEL_UI); + + return WLAN_STATUS_SUCCESS; +} + +uint32_t +wlanoidQueryWifiLogLevel(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) { + struct PARAM_WIFI_LOG_LEVEL *pparam; + + ASSERT(prAdapter); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + ASSERT(pu4QueryInfoLen); + + pparam = (struct PARAM_WIFI_LOG_LEVEL *) pvQueryBuffer; + pparam->u4Level = wlanDbgGetLogLevelImpl(prAdapter, + pparam->u4Version, + pparam->u4Module); + + DBGLOG(OID, INFO, "version: %d, module: %d, level: %d\n", + pparam->u4Version, + pparam->u4Module, + pparam->u4Level); + + *pu4QueryInfoLen = sizeof(struct PARAM_WIFI_LOG_LEVEL_UI); + + return WLAN_STATUS_SUCCESS; +} + +uint32_t +wlanoidSetWifiLogLevel(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) { + struct PARAM_WIFI_LOG_LEVEL *pparam; + + ASSERT(prAdapter); + if (u4SetBufferLen) + ASSERT(pvSetBuffer); + ASSERT(pu4SetInfoLen); + + pparam = (struct PARAM_WIFI_LOG_LEVEL *) pvSetBuffer; + + DBGLOG(OID, INFO, "version: %d, module: %d, level: %d\n", + pparam->u4Version, + pparam->u4Module, + pparam->u4Level); + + wlanDbgSetLogLevelImpl(prAdapter, + pparam->u4Version, + pparam->u4Module, + pparam->u4Level); + + return WLAN_STATUS_SUCCESS; +} + +uint32_t wlanoidSetDrvSer(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + ASSERT(prAdapter); + + prAdapter->u4HifChkFlag |= HIF_DRV_SER; + kalSetHifDbgEvent(prAdapter->prGlueInfo); + + return 0; +} + +uint32_t wlanoidSetAmsduNum(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + struct mt66xx_chip_info *prChipInfo = NULL; + + ASSERT(prAdapter); + if (u4SetBufferLen) + ASSERT(pvSetBuffer); + ASSERT(pu4SetInfoLen); + + prChipInfo = prAdapter->chip_info; + prChipInfo->ucMaxSwAmsduNum = (uint8_t)*((uint32_t *)pvSetBuffer); + DBGLOG(OID, INFO, "Set SW AMSDU Num: %d\n", + prChipInfo->ucMaxSwAmsduNum); + return 0; +} + +uint32_t wlanoidSetAmsduSize(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + struct mt66xx_chip_info *prChipInfo = NULL; + struct WIFI_VAR *prWifiVar = NULL; + + ASSERT(prAdapter); + if (u4SetBufferLen) + ASSERT(pvSetBuffer); + ASSERT(pu4SetInfoLen); + + prChipInfo = prAdapter->chip_info; + prWifiVar = &prAdapter->rWifiVar; + prWifiVar->u4TxMaxAmsduInAmpduLen = *((uint32_t *)pvSetBuffer); + DBGLOG(OID, INFO, "Set SW AMSDU max Size: %d\n", + prWifiVar->u4TxMaxAmsduInAmpduLen); + return 0; +} + +uint32_t +wlanoidShowPdmaInfo(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + prAdapter->u4HifDbgFlag |= DEG_HIF_PDMA; + kalSetHifDbgEvent(prAdapter->prGlueInfo); + + return 0; +} + +uint32_t +wlanoidShowPseInfo(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + prAdapter->u4HifDbgFlag |= DEG_HIF_PSE; + kalSetHifDbgEvent(prAdapter->prGlueInfo); + + return 0; +} + +uint32_t +wlanoidShowPleInfo(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + prAdapter->u4HifDbgFlag |= DEG_HIF_PLE; + kalSetHifDbgEvent(prAdapter->prGlueInfo); + + return 0; +} + +uint32_t +wlanoidShowCsrInfo(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + prAdapter->u4HifDbgFlag |= DEG_HIF_HOST_CSR; + kalSetHifDbgEvent(prAdapter->prGlueInfo); + + return 0; +} + +uint32_t +wlanoidShowDmaschInfo(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + prAdapter->u4HifDbgFlag |= DEG_HIF_DMASCH; + kalSetHifDbgEvent(prAdapter->prGlueInfo); + + return 0; +} + +#if CFG_SUPPORT_LOWLATENCY_MODE +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to enable/disable low latency mode from oid + * + * \param[in] prAdapter A pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the + * OID-specific data to be set. + * \param[in] u4SetBufferLen The number of bytes the set buffer. + * \param[out] pu4SetInfoLen Points to the number of bytes it read or is + * needed + * \retval WLAN_STATUS_SUCCESS + */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanoidSetLowLatencyMode( + IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + uint32_t u4Events; + struct BSS_INFO *prAisBssInfo; + uint8_t ucBssIndex = AIS_DEFAULT_INDEX; + + DEBUGFUNC("wlanoidSetLowLatencyMode"); + + ASSERT(prAdapter); + ASSERT(pvSetBuffer); + if (u4SetBufferLen != sizeof(uint32_t)) { + *pu4SetInfoLen = sizeof(uint32_t); + return WLAN_STATUS_INVALID_LENGTH; + } + ASSERT(pu4SetInfoLen); + + prAisBssInfo = + aisGetAisBssInfo(prAdapter, ucBssIndex); + if (!prAisBssInfo) { + DBGLOG(OID, ERROR, "prAisBssInfo = NULL\n"); + *pu4SetInfoLen = 0; + return WLAN_STATUS_FAILURE; + } + + /* Initialize */ + kalMemCopy(&u4Events, pvSetBuffer, u4SetBufferLen); + + /* Set low latency mode */ + DBGLOG(OID, INFO, "DPP LowLatencySet(from oid set) event:0x%x\n", + u4Events); + wlanSetLowLatencyMode(prAdapter, u4Events); + + *pu4SetInfoLen = 0; /* We do not need to read */ + + return WLAN_STATUS_SUCCESS; +} + +#endif /* CFG_SUPPORT_LOWLATENCY_MODE */ + +uint32_t wlanoidGetWifiType(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + struct PARAM_GET_WIFI_TYPE *prParamGetWifiType; + struct NETDEV_PRIVATE_GLUE_INFO *prNetDevPrivate; + struct BSS_INFO *prBssInfo = NULL; + uint8_t ucBssIdx; + uint8_t ucPhyType; + uint8_t ucMaxCopySize; + uint8_t *pNameBuf; + *pu4SetInfoLen = 0; + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(OID, ERROR, + "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", + prAdapter->rAcpiState, prAdapter->fgIsRadioOff); + return WLAN_STATUS_ADAPTER_NOT_READY; + } + prParamGetWifiType = (struct PARAM_GET_WIFI_TYPE *)pvSetBuffer; + prNetDevPrivate = (struct NETDEV_PRIVATE_GLUE_INFO *) + netdev_priv(prParamGetWifiType->prNetDev); + ucBssIdx = prNetDevPrivate->ucBssIdx; + DBGLOG(OID, INFO, "bss index=%d\n", ucBssIdx); + kalMemZero(prParamGetWifiType->arWifiTypeName, + sizeof(prParamGetWifiType->arWifiTypeName)); + pNameBuf = &prParamGetWifiType->arWifiTypeName[0]; + ucMaxCopySize = sizeof(prParamGetWifiType->arWifiTypeName) - 1; + if (ucBssIdx > prAdapter->ucHwBssIdNum) { + DBGLOG(OID, ERROR, "invalid bss index: %u\n", ucBssIdx); + return WLAN_STATUS_INVALID_DATA; + } + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIdx); + if ((!prBssInfo) || (!IS_BSS_ACTIVE(prBssInfo))) { + DBGLOG(OID, ERROR, "invalid BssInfo: %p, %u\n", + prBssInfo, ucBssIdx); + return WLAN_STATUS_INVALID_DATA; + } + ucPhyType = prBssInfo->ucPhyTypeSet; + if (ucPhyType & PHY_TYPE_SET_802_11AC) + kalStrnCpy(pNameBuf, "11AC", ucMaxCopySize); + else if (ucPhyType & PHY_TYPE_SET_802_11N) + kalStrnCpy(pNameBuf, "11N", ucMaxCopySize); + else if (ucPhyType & PHY_TYPE_SET_802_11G) + kalStrnCpy(pNameBuf, "11G", ucMaxCopySize); + else if (ucPhyType & PHY_TYPE_SET_802_11A) + kalStrnCpy(pNameBuf, "11A", ucMaxCopySize); + else if (ucPhyType & PHY_TYPE_SET_802_11B) + kalStrnCpy(pNameBuf, "11B", ucMaxCopySize); + else + DBGLOG(OID, INFO, + "unknown wifi type, prBssInfo->ucPhyTypeSet: %u\n", + ucPhyType); + *pu4SetInfoLen = kalStrLen(pNameBuf); + DBGLOG(OID, INFO, "wifi type=[%s](%d), phyType=%u\n", + pNameBuf, *pu4SetInfoLen, ucPhyType); + return WLAN_STATUS_SUCCESS; +} + +#ifdef CFG_SUPPORT_LINK_QUALITY_MONITOR +uint32_t wlanoidGetLinkQualityInfo(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + struct PARAM_GET_LINK_QUALITY_INFO *prParam; + struct WIFI_LINK_QUALITY_INFO *prSrcLinkQualityInfo = NULL; + struct WIFI_LINK_QUALITY_INFO *prDstLinkQualityInfo = NULL; + + prParam = (struct PARAM_GET_LINK_QUALITY_INFO *)pvSetBuffer; + prSrcLinkQualityInfo = &(prAdapter->rLinkQualityInfo); + prDstLinkQualityInfo = prParam->prLinkQualityInfo; + kalMemCopy(prDstLinkQualityInfo, prSrcLinkQualityInfo, + sizeof(struct WIFI_LINK_QUALITY_INFO)); + + return WLAN_STATUS_SUCCESS; +} +#endif /* CFG_SUPPORT_LINK_QUALITY_MONITOR */ + +#if CFG_SUPPORT_ANT_SWAP +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to query antenna swap capablity + * + * \param[in] prAdapter A pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the + * OID-specific data to be set. + * \param[in] u4SetBufferLen The number of bytes the set buffer. + * \param[out] pu4SetInfoLen Points to the number of bytes it read or is + * needed + * \retval WLAN_STATUS_SUCCESS + */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanoidQueryAntennaSwap(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) + +{ + uint32_t *puSupportSwpAntenn = 0; + + if (!prAdapter) { + DBGLOG(REQ, ERROR, "prAdapter is NULL\n"); + return WLAN_STATUS_ADAPTER_NOT_READY; + } + + if (!pu4QueryInfoLen) { + DBGLOG(REQ, ERROR, "pu4QueryInfoLen is NULL\n"); + return WLAN_STATUS_INVALID_DATA; + } + + *pu4QueryInfoLen = sizeof(uint32_t); + + /* Check for query buffer length */ + if (u4QueryBufferLen != sizeof(uint32_t)) { + DBGLOG(REQ, WARN, "Invalid length %lu\n", u4QueryBufferLen); + return WLAN_STATUS_INVALID_LENGTH; + } + + ASSERT(pvQueryBuffer); + + puSupportSwpAntenn = (uint32_t *) pvQueryBuffer; + + *puSupportSwpAntenn = !!(prAdapter->fgIsSupportAntSwp); + DBGLOG(REQ, WARN, "*puSupportSwpAntenn : %lu\n", + *puSupportSwpAntenn); + return WLAN_STATUS_SUCCESS; +} +#endif /* CFG_SUPPORT_ANT_SWAP */ + +#if CFG_SUPPORT_DYNAMIC_PWR_LIMIT +/* dynamic tx power control oid function */ +uint32_t wlanoidTxPowerControl(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + struct PARAM_TX_PWR_CTRL_IOCTL *prPwrCtrlParam; + struct TX_PWR_CTRL_ELEMENT *oldElement; + u_int8_t fgApplied; + + if (!pvSetBuffer) + return WLAN_STATUS_INVALID_DATA; + + prPwrCtrlParam = (struct PARAM_TX_PWR_CTRL_IOCTL *)pvSetBuffer; + if ((prPwrCtrlParam == NULL) || (prPwrCtrlParam->name == NULL)) { + DBGLOG(OID, ERROR, "prPwrCtrlParam is NULL\n"); + return WLAN_STATUS_FAILURE; + } + + fgApplied = prPwrCtrlParam->fgApplied; + + oldElement = txPwrCtrlFindElement(prAdapter, + prPwrCtrlParam->name, 0, TRUE, + PWR_CTRL_TYPE_DYNAMIC_LIST); + if (oldElement != NULL) + oldElement->fgApplied = FALSE; + + if (fgApplied == TRUE) { + oldElement = txPwrCtrlFindElement(prAdapter, + prPwrCtrlParam->name, prPwrCtrlParam->index, + FALSE, PWR_CTRL_TYPE_DYNAMIC_LIST); + if (oldElement != NULL) { + if (prPwrCtrlParam->newSetting != NULL) { + struct TX_PWR_CTRL_ELEMENT *newElement; + + newElement = txPwrCtrlStringToStruct( + prPwrCtrlParam->newSetting, TRUE); + if (newElement == NULL) { + DBGLOG(OID, ERROR, + "parse new setting fail, <%s>\n", + prPwrCtrlParam->newSetting); + return WLAN_STATUS_FAILURE; + } + + kalMemCopy(newElement->name, oldElement->name, + MAX_TX_PWR_CTRL_ELEMENT_NAME_SIZE); + newElement->index = oldElement->index; + newElement->eCtrlType = oldElement->eCtrlType; + txPwrCtrlDeleteElement(prAdapter, + newElement->name, newElement->index, + PWR_CTRL_TYPE_DYNAMIC_LIST); + oldElement = newElement; + txPwrCtrlAddElement(prAdapter, oldElement); + } + oldElement->fgApplied = TRUE; + } + } + + if (oldElement != NULL) + rlmDomainSendPwrLimitCmd(prAdapter); + + return WLAN_STATUS_SUCCESS; +} +#endif + +uint32_t +wlanoidExternalAuthDone(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + struct STA_RECORD *prStaRec; + uint8_t ucBssIndex = 0; + struct PARAM_EXTERNAL_AUTH *params; + struct MSG_SAA_EXTERNAL_AUTH_DONE *prExternalAuthMsg = NULL; + + params = (struct PARAM_EXTERNAL_AUTH *) pvSetBuffer; + ucBssIndex = params->ucBssIdx; + if (!IS_BSS_INDEX_VALID(ucBssIndex)) { + DBGLOG(REQ, ERROR, + "SAE-confirm failed with invalid BssIdx in ndev\n"); + return WLAN_STATUS_INVALID_DATA; + } + + prExternalAuthMsg = (struct MSG_SAA_EXTERNAL_AUTH_DONE *)cnmMemAlloc( + prAdapter, RAM_TYPE_MSG, + sizeof(struct MSG_SAA_EXTERNAL_AUTH_DONE)); + if (!prExternalAuthMsg) { + DBGLOG(OID, WARN, + "SAE-confirm failed to allocate Msg\n"); + return WLAN_STATUS_RESOURCES; + } + + prStaRec = cnmGetStaRecByAddress(prAdapter, ucBssIndex, params->bssid); + if (!prStaRec) { + DBGLOG(REQ, WARN, "SAE-confirm failed with bssid:" MACSTR "\n", + MAC2STR(params->bssid)); + return WLAN_STATUS_INVALID_DATA; + } + + prExternalAuthMsg->rMsgHdr.eMsgId = MID_OID_SAA_FSM_EXTERNAL_AUTH; + prExternalAuthMsg->prStaRec = prStaRec; + prExternalAuthMsg->status = params->status; + + mboxSendMsg(prAdapter, MBOX_ID_0, (struct MSG_HDR *)prExternalAuthMsg, + MSG_SEND_METHOD_BUF); + + return WLAN_STATUS_SUCCESS; +} + +uint32_t +wlanoidIndicateBssInfo(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + struct GLUE_INFO *prGlueInfo; + struct BSS_DESC **pprBssDesc = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint8_t i = 0; + + DEBUGFUNC("wlanoidIndicateBssInfo"); + + ASSERT(prAdapter); + + prGlueInfo = prAdapter->prGlueInfo; + pprBssDesc = &prAdapter->rWifiVar.rScanInfo.rSchedScanParam. + aprPendingBssDescToInd[0]; + + for (; i < SCN_SSID_MATCH_MAX_NUM; i++) { + if (pprBssDesc[i] == NULL) + break; + if (pprBssDesc[i]->u2RawLength == 0) + continue; + kalIndicateBssInfo(prGlueInfo, + (uint8_t *) pprBssDesc[i]->aucRawBuf, + pprBssDesc[i]->u2RawLength, + pprBssDesc[i]->ucChannelNum, + RCPI_TO_dBm(pprBssDesc[i]->ucRCPI)); + } + DBGLOG(SCN, INFO, "pending %d sched scan results\n", i); + if (i > 0) + kalMemZero(&pprBssDesc[0], i * sizeof(struct BSS_DESC *)); + + return rStatus; +} /* wlanoidIndicateBssInfo */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/common/wlan_p2p.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/common/wlan_p2p.c new file mode 100644 index 0000000000000000000000000000000000000000..70d1d8b4629c5c1f903c4383712646f8f51fbf19 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/common/wlan_p2p.c @@ -0,0 +1,1744 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/common/wlan_p2p.c#8 + */ + +/*! \file wlan_bow.c + * \brief This file contains the Wi-Fi Direct commands processing routines + * for MediaTek Inc. 802.11 Wireless LAN Adapters. + */ + + +/****************************************************************************** + * C O M P I L E R F L A G S + ****************************************************************************** + */ + +/****************************************************************************** + * E X T E R N A L R E F E R E N C E S + ****************************************************************************** + */ +#include "precomp.h" + +/****************************************************************************** + * C O N S T A N T S + ******************************************************************************* + */ + +/****************************************************************************** + * D A T A T Y P E S + ******************************************************************************* + */ + +/****************************************************************************** + * P U B L I C D A T A + ******************************************************************************* + */ + +/****************************************************************************** + * P R I V A T E D A T A + ******************************************************************************* + */ + +/****************************************************************************** + * M A C R O S + ******************************************************************************* + */ + +/****************************************************************************** + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/****************************************************************************** + * F U N C T I O N S + ****************************************************************************** + */ +/*---------------------------------------------------------------------------*/ +/*! + * \brief command packet generation utility + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] ucCID Command ID + * \param[in] fgSetQuery Set or Query + * \param[in] fgNeedResp Need for response + * \param[in] pfCmdDoneHandler Function pointer when command is done + * \param[in] u4SetQueryInfoLen The length of the set/query buffer + * \param[in] pucInfoBuffer Pointer to set/query buffer + * + * + * \retval WLAN_STATUS_PENDING + * \retval WLAN_STATUS_FAILURE + */ +/*---------------------------------------------------------------------------*/ +uint32_t +wlanoidSendSetQueryP2PCmd(IN struct ADAPTER *prAdapter, + IN uint8_t ucCID, + IN uint8_t ucBssIdx, + IN u_int8_t fgSetQuery, + IN u_int8_t fgNeedResp, + IN u_int8_t fgIsOid, + IN PFN_CMD_DONE_HANDLER pfCmdDoneHandler, + IN PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler, + IN uint32_t u4SetQueryInfoLen, + IN uint8_t *pucInfoBuffer, + OUT void *pvSetQueryBuffer, + IN uint32_t u4SetQueryBufferLen) +{ + struct GLUE_INFO *prGlueInfo; + struct CMD_INFO *prCmdInfo; + uint8_t *pucCmdBuf; + struct mt66xx_chip_info *prChipInfo; + + ASSERT(prAdapter); + + prGlueInfo = prAdapter->prGlueInfo; + ASSERT(prGlueInfo); + prChipInfo = prAdapter->chip_info; + + DEBUGFUNC("wlanoidSendSetQueryP2PCmd"); + DBGLOG(REQ, TRACE, "Command ID = 0x%08X\n", ucCID); + + prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, + (prChipInfo->u2CmdTxHdrSize + u4SetQueryInfoLen)); + + if (!prCmdInfo) { + DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); + return WLAN_STATUS_FAILURE; + } + + /* Setup common CMD Info Packet */ + prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; + prCmdInfo->u2InfoBufLen = + (uint16_t) (prChipInfo->u2CmdTxHdrSize + u4SetQueryInfoLen); + prCmdInfo->pfCmdDoneHandler = pfCmdDoneHandler; + prCmdInfo->pfCmdTimeoutHandler = pfCmdTimeoutHandler; + prCmdInfo->fgIsOid = fgIsOid; + prCmdInfo->ucCID = ucCID; + prCmdInfo->fgSetQuery = fgSetQuery; + prCmdInfo->fgNeedResp = fgNeedResp; + prCmdInfo->u4SetInfoLen = u4SetQueryInfoLen; + prCmdInfo->pvInformationBuffer = pvSetQueryBuffer; + prCmdInfo->u4InformationBufferLength = u4SetQueryBufferLen; + + /* Setup WIFI_CMD_T (no payload) */ + NIC_FILL_CMD_TX_HDR(prAdapter, + prCmdInfo->pucInfoBuffer, + prCmdInfo->u2InfoBufLen, + prCmdInfo->ucCID, + CMD_PACKET_TYPE_ID, + &prCmdInfo->ucCmdSeqNum, + prCmdInfo->fgSetQuery, &pucCmdBuf, FALSE, 0, S2D_INDEX_CMD_H2N); + + if (u4SetQueryInfoLen > 0 && pucInfoBuffer != NULL) + kalMemCopy(pucCmdBuf, + pucInfoBuffer, u4SetQueryInfoLen); + /* insert into prCmdQueue */ + kalEnqueueCommand(prGlueInfo, (struct QUE_ENTRY *) prCmdInfo); + + /* wakeup txServiceThread later */ + GLUE_SET_EVENT(prGlueInfo); + return WLAN_STATUS_PENDING; +} + +/*---------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set a key to Wi-Fi Direct driver + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_ADAPTER_NOT_READY + * \retval WLAN_STATUS_INVALID_LENGTH + * \retval WLAN_STATUS_INVALID_DATA + */ +/*---------------------------------------------------------------------------*/ +#if 0 +uint32_t +wlanoidSetAddP2PKey(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + struct CMD_802_11_KEY rCmdKey; + struct PARAM_KEY *prNewKey; + struct BSS_INFO *prBssInfo = (struct BSS_INFO *) NULL; + struct STA_RECORD *prStaRec = (struct STA_RECORD *) NULL; + + DEBUGFUNC("wlanoidSetAddP2PKey"); + DBGLOG(REQ, INFO, "\n"); + + ASSERT(prAdapter); + ASSERT(pvSetBuffer); + ASSERT(pu4SetInfoLen); + + prNewKey = (struct PARAM_KEY *) pvSetBuffer; + + /* Verify the key structure length. */ + if (prNewKey->u4Length > u4SetBufferLen) { + log_dbg(REQ, WARN, + "Invalid key structure length (%d) greater than total buffer length (%d)\n", + (uint8_t) prNewKey->u4Length, (uint8_t) u4SetBufferLen); + + *pu4SetInfoLen = u4SetBufferLen; + return WLAN_STATUS_INVALID_LENGTH; + } + /* Verify the key material length for key material buffer */ + else if (prNewKey->u4KeyLength > + prNewKey->u4Length - + OFFSET_OF(struct PARAM_KEY, aucKeyMaterial)) { + log_dbg(REQ, WARN, + "Invalid key material length (%d)\n", + (uint8_t) prNewKey->u4KeyLength); + *pu4SetInfoLen = u4SetBufferLen; + return WLAN_STATUS_INVALID_DATA; + } + /* Exception check */ + else if (prNewKey->u4KeyIndex & 0x0fffff00) + return WLAN_STATUS_INVALID_DATA; + /* Exception check, pairwise key must with transmit bit enabled */ + else if ((prNewKey->u4KeyIndex & BITS(30, 31)) == IS_UNICAST_KEY) { + return WLAN_STATUS_INVALID_DATA; + } else if (!(prNewKey->u4KeyLength == CCMP_KEY_LEN) + && !(prNewKey->u4KeyLength == TKIP_KEY_LEN)) { + return WLAN_STATUS_INVALID_DATA; + } + /* Exception check, pairwise key must with transmit bit enabled */ + else if ((prNewKey->u4KeyIndex & BITS(30, 31)) == BITS(30, 31)) { + if (((prNewKey->u4KeyIndex & 0xff) != 0) || + ((prNewKey->arBSSID[0] == 0xff) && + (prNewKey->arBSSID[1] == 0xff) && + (prNewKey->arBSSID[2] == 0xff) && + (prNewKey->arBSSID[3] == 0xff) && + (prNewKey->arBSSID[4] == 0xff) && + (prNewKey->arBSSID[5] == 0xff))) { + return WLAN_STATUS_INVALID_DATA; + } + } + + *pu4SetInfoLen = u4SetBufferLen; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prNewKey->ucBssIdx); + ASSERT(prBssInfo); +#if 0 + if (prBssInfo->ucBMCWlanIndex >= WTBL_SIZE) { + prBssInfo->ucBMCWlanIndex = + secPrivacySeekForBcEntry(prAdapter, + prBssInfo->ucBssIndex, prBssInfo->aucBSSID, + 0xff, CIPHER_SUITE_NONE, 0xff); + } +#endif + /* fill CMD_802_11_KEY */ + kalMemZero(&rCmdKey, sizeof(struct CMD_802_11_KEY)); + rCmdKey.ucAddRemove = 1; /* add */ + rCmdKey.ucTxKey = + ((prNewKey->u4KeyIndex & IS_TRANSMIT_KEY) == IS_TRANSMIT_KEY) + ? 1 : 0; + rCmdKey.ucKeyType = + ((prNewKey->u4KeyIndex & IS_UNICAST_KEY) == IS_UNICAST_KEY) + ? 1 : 0; +#if 0 + /* group client */ + if (prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) { +#else + /* group client */ + if (kalP2PGetRole(prAdapter->prGlueInfo) == 1) { +#endif + + rCmdKey.ucIsAuthenticator = 0; + } else { /* group owner */ + rCmdKey.ucIsAuthenticator = 1; + /* Force to set GO/AP Tx */ + rCmdKey.ucTxKey = 1; + } + + COPY_MAC_ADDR(rCmdKey.aucPeerAddr, prNewKey->arBSSID); + rCmdKey.ucBssIdx = prNewKey->ucBssIdx; + if (prNewKey->u4KeyLength == CCMP_KEY_LEN) + rCmdKey.ucAlgorithmId = CIPHER_SUITE_CCMP; /* AES */ + else if (prNewKey->u4KeyLength == TKIP_KEY_LEN) + rCmdKey.ucAlgorithmId = CIPHER_SUITE_TKIP; /* TKIP */ + else if (prNewKey->u4KeyLength == WEP_40_LEN) + rCmdKey.ucAlgorithmId = CIPHER_SUITE_WEP40; /* WEP 40 */ + else if (prNewKey->u4KeyLength == WEP_104_LEN) + rCmdKey.ucAlgorithmId = CIPHER_SUITE_WEP104; /* WEP 104 */ + else + ASSERT(FALSE); + rCmdKey.ucKeyId = (uint8_t) (prNewKey->u4KeyIndex & 0xff); + rCmdKey.ucKeyLen = (uint8_t) prNewKey->u4KeyLength; + kalMemCopy(rCmdKey.aucKeyMaterial, + (uint8_t *) prNewKey->aucKeyMaterial, rCmdKey.ucKeyLen); + + if ((rCmdKey.aucPeerAddr[0] & + rCmdKey.aucPeerAddr[1] & rCmdKey.aucPeerAddr[2] & + rCmdKey.aucPeerAddr[3] & rCmdKey.aucPeerAddr[4] & + rCmdKey.aucPeerAddr[5]) == 0xFF) { + kalMemCopy(rCmdKey.aucPeerAddr, + prBssInfo->aucBSSID, MAC_ADDR_LEN); + if (!rCmdKey.ucIsAuthenticator) { + prStaRec = cnmGetStaRecByAddress(prAdapter, + rCmdKey.ucBssIdx, rCmdKey.aucPeerAddr); + if (!prStaRec) + ASSERT(FALSE); + } + } else { + prStaRec = cnmGetStaRecByAddress(prAdapter, + rCmdKey.ucBssIdx, rCmdKey.aucPeerAddr); + } + + if (rCmdKey.ucTxKey) { + if (prStaRec) { + if (rCmdKey.ucKeyType) { /* RSN STA */ + ASSERT(prStaRec->ucWlanIndex < WTBL_SIZE); + rCmdKey.ucWlanIndex = prStaRec->ucWlanIndex; + /* wait for CMD Done ? */ + prStaRec->fgTransmitKeyExist = TRUE; + } else { + ASSERT(FALSE); + } + } else { + if (prBssInfo) { /* GO/AP Tx BC */ + ASSERT(prBssInfo->ucBMCWlanIndex < WTBL_SIZE); + rCmdKey.ucWlanIndex = prBssInfo->ucBMCWlanIndex; + prBssInfo->fgBcDefaultKeyExist = TRUE; + prBssInfo->ucTxDefaultKeyID = rCmdKey.ucKeyId; + } else { + /* GC WEP Tx key ? */ + rCmdKey.ucWlanIndex = 255; + ASSERT(FALSE); + } + } + } else { + if (((rCmdKey.aucPeerAddr[0] & rCmdKey.aucPeerAddr[1] & + rCmdKey.aucPeerAddr[2] & rCmdKey.aucPeerAddr[3] & + rCmdKey.aucPeerAddr[4] & + rCmdKey.aucPeerAddr[5]) == 0xFF) || + ((rCmdKey.aucPeerAddr[0] | rCmdKey.aucPeerAddr[1] | + rCmdKey.aucPeerAddr[2] | rCmdKey.aucPeerAddr[3] | + rCmdKey.aucPeerAddr[4] | rCmdKey.aucPeerAddr[5]) == 0x00)) { + rCmdKey.ucWlanIndex = 255; /* GC WEP ? */ + ASSERT(FALSE); + } else { + if (prStaRec) { /* GC Rx RSN Group key */ + rCmdKey.ucWlanIndex = + secPrivacySeekForBcEntry(prAdapter, + prStaRec->ucBssIndex, + prStaRec->aucMacAddr, + prStaRec->ucIndex, + rCmdKey.ucAlgorithmId, + rCmdKey.ucKeyId); + prStaRec->ucBMCWlanIndex = rCmdKey.ucWlanIndex; + ASSERT(prStaRec->ucBMCWlanIndex < WTBL_SIZE); + } else { /* Exist this case ? */ + ASSERT(FALSE); + } + } + } + + return wlanoidSendSetQueryP2PCmd(prAdapter, + CMD_ID_ADD_REMOVE_KEY, + prNewKey->ucBssIdx, + TRUE, + FALSE, + TRUE, + nicCmdEventSetCommon, + NULL, + sizeof(struct CMD_802_11_KEY), + (uint8_t *)&rCmdKey, + pvSetBuffer, + u4SetBufferLen); +} + +/*---------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to request Wi-Fi Direct driver to remove keys + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_DATA + * \retval WLAN_STATUS_INVALID_LENGTH + * \retval WLAN_STATUS_INVALID_DATA + */ +/*---------------------------------------------------------------------------*/ +uint32_t +wlanoidSetRemoveP2PKey(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + struct CMD_802_11_KEY rCmdKey; + struct PARAM_REMOVE_KEY *prRemovedKey; + struct BSS_INFO *prBssInfo = (struct BSS_INFO *) NULL; + struct STA_RECORD *prStaRec = (struct STA_RECORD *) NULL; + + DEBUGFUNC("wlanoidSetRemoveP2PKey"); + ASSERT(prAdapter); + + if (u4SetBufferLen < sizeof(struct PARAM_REMOVE_KEY)) + return WLAN_STATUS_INVALID_LENGTH; + + ASSERT(pvSetBuffer); + prRemovedKey = (struct PARAM_REMOVE_KEY *) pvSetBuffer; + + /* Check bit 31: this bit should always 0 */ + if (prRemovedKey->u4KeyIndex & IS_TRANSMIT_KEY) { + /* Bit 31 should not be set */ + DBGLOG(REQ, ERROR, "invalid key index: 0x%08lx\n", + prRemovedKey->u4KeyIndex); + return WLAN_STATUS_INVALID_DATA; + } + + /* Check bits 8 ~ 29 should always be 0 */ + if (prRemovedKey->u4KeyIndex & BITS(8, 29)) { + /* Bit 31 should not be set */ + DBGLOG(REQ, ERROR, "invalid key index: 0x%08lx\n", + prRemovedKey->u4KeyIndex); + return WLAN_STATUS_INVALID_DATA; + } + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prRemovedKey->ucBssIdx); + + kalMemZero((uint8_t *)&rCmdKey, sizeof(struct CMD_802_11_KEY)); + + rCmdKey.ucAddRemove = 0; /* remove */ + /* group client */ + if (prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) { + rCmdKey.ucIsAuthenticator = 0; + } else { /* group owner */ + rCmdKey.ucIsAuthenticator = 1; + } + kalMemCopy(rCmdKey.aucPeerAddr, + (uint8_t *) prRemovedKey->arBSSID, MAC_ADDR_LEN); + rCmdKey.ucBssIdx = prRemovedKey->ucBssIdx; + rCmdKey.ucKeyId = (uint8_t) (prRemovedKey->u4KeyIndex & 0x000000ff); + + /* Clean up the Tx key flag */ + prStaRec = cnmGetStaRecByAddress(prAdapter, + prRemovedKey->ucBssIdx, prRemovedKey->arBSSID); + + /* mark for MR1 to avoid remove-key, + * but remove the wlan_tbl0 at the same time + */ + if (1 /*prRemovedKey->u4KeyIndex & IS_UNICAST_KEY */) { + if (prStaRec) { + rCmdKey.ucKeyType = 1; + rCmdKey.ucWlanIndex = prStaRec->ucWlanIndex; + prStaRec->fgTransmitKeyExist = FALSE; + } else if (rCmdKey.ucIsAuthenticator) + prBssInfo->fgBcDefaultKeyExist = FALSE; + } else { + if (rCmdKey.ucIsAuthenticator) + prBssInfo->fgBcDefaultKeyExist = FALSE; + } + + if (!prStaRec) { + if (prAdapter->rWifiVar.rConnSettings.eAuthMode < AUTH_MODE_WPA + && prAdapter->rWifiVar.rConnSettings.eEncStatus + != ENUM_ENCRYPTION_DISABLED) { + rCmdKey.ucWlanIndex = prBssInfo->ucBMCWlanIndex; + } else { + rCmdKey.ucWlanIndex = WTBL_RESERVED_ENTRY; + return WLAN_STATUS_SUCCESS; + } + } + + /* mark for MR1 to avoid remove-key, + * but remove the wlan_tbl0 at the same time + */ + /* secPrivacyFreeForEntry(prAdapter, rCmdKey.ucWlanIndex); */ + + return wlanoidSendSetQueryP2PCmd(prAdapter, + CMD_ID_ADD_REMOVE_KEY, + prRemovedKey->ucBssIdx, + TRUE, + FALSE, + TRUE, + nicCmdEventSetCommon, + NULL, + sizeof(struct CMD_802_11_KEY), + (uint8_t *)&rCmdKey, + pvSetBuffer, + u4SetBufferLen); +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Setting the IP address for pattern search function. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \return WLAN_STATUS_SUCCESS + * \return WLAN_STATUS_ADAPTER_NOT_READY + * \return WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetP2pNetworkAddress(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t i, j; + struct CMD_SET_NETWORK_ADDRESS_LIST *prCmdNWAddrList; + struct PARAM_NETWORK_ADDRESS_LIST *prNWAddrList = + (struct PARAM_NETWORK_ADDRESS_LIST *) pvSetBuffer; + struct PARAM_NETWORK_ADDRESS *prNWAddress; + struct PARAM_NETWORK_ADDRESS_IP *prNetAddrIp; + uint32_t u4IpAddressCount, u4CmdSize; + + DEBUGFUNC("wlanoidSetP2pNetworkAddress"); + DBGLOG(INIT, TRACE, "\n"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = 4; + + if (u4SetBufferLen < sizeof(struct PARAM_NETWORK_ADDRESS_LIST)) + return WLAN_STATUS_INVALID_DATA; + + *pu4SetInfoLen = 0; + u4IpAddressCount = 0; + + prNWAddress = prNWAddrList->arAddress; + for (i = 0; i < prNWAddrList->u4AddressCount; i++) { + if (prNWAddress->u2AddressType + == PARAM_PROTOCOL_ID_TCP_IP && + prNWAddress->u2AddressLength + == sizeof(struct PARAM_NETWORK_ADDRESS_IP)) { + u4IpAddressCount++; + } + + prNWAddress = (struct PARAM_NETWORK_ADDRESS *) + ((unsigned long) prNWAddress + + (unsigned long) (prNWAddress->u2AddressLength + + OFFSET_OF(struct PARAM_NETWORK_ADDRESS, aucAddress))); + } + + /* construct payload of command packet */ + u4CmdSize = + OFFSET_OF(struct CMD_SET_NETWORK_ADDRESS_LIST, arNetAddress) + + sizeof(struct CMD_IPV4_NETWORK_ADDRESS) * u4IpAddressCount; + + prCmdNWAddrList = (struct CMD_SET_NETWORK_ADDRESS_LIST *) + kalMemAlloc(u4CmdSize, VIR_MEM_TYPE); + + if (prCmdNWAddrList == NULL) + return WLAN_STATUS_FAILURE; + + /* fill P_CMD_SET_NETWORK_ADDRESS_LIST */ + prCmdNWAddrList->ucBssIndex = prNWAddrList->ucBssIdx; + prCmdNWAddrList->ucAddressCount = (uint8_t) u4IpAddressCount; + prNWAddress = prNWAddrList->arAddress; + for (i = 0, j = 0; i < prNWAddrList->u4AddressCount; i++) { + if (prNWAddress->u2AddressType + == PARAM_PROTOCOL_ID_TCP_IP && + prNWAddress->u2AddressLength + == sizeof(struct PARAM_NETWORK_ADDRESS_IP)) { + prNetAddrIp = (struct PARAM_NETWORK_ADDRESS_IP *) + prNWAddress->aucAddress; + + kalMemCopy( + prCmdNWAddrList->arNetAddress[j].aucIpAddr, + &(prNetAddrIp->in_addr), sizeof(uint32_t)); + + j++; + } + + prNWAddress = (struct PARAM_NETWORK_ADDRESS *) + ((unsigned long) prNWAddress + + (unsigned long) (prNWAddress->u2AddressLength + + OFFSET_OF(struct PARAM_NETWORK_ADDRESS, aucAddress))); + } + + rStatus = wlanSendSetQueryCmd(prAdapter, + CMD_ID_SET_IP_ADDRESS, + TRUE, + FALSE, + TRUE, + nicCmdEventSetIpAddress, + nicOidCmdTimeoutCommon, + u4CmdSize, + (uint8_t *) prCmdNWAddrList, + pvSetBuffer, + u4SetBufferLen); + + kalMemFree(prCmdNWAddrList, VIR_MEM_TYPE, u4CmdSize); + return rStatus; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used to query the power save profile. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[out] pvQueryBuf A pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the call + * failed due to invalid length of the query buffer, + * returns the amount of storage needed. + * + * \return WLAN_STATUS_SUCCESS + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryP2pPowerSaveProfile(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) +{ + DEBUGFUNC("wlanoidQueryP2pPowerSaveProfile"); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + + if (u4QueryBufferLen != 0) { + ASSERT(pvQueryBuffer); + /* TODO: FIXME */ + /* *(enum PARAM_POWER_MODE *) pvQueryBuffer = + * (enum PARAM_POWER_MODE) + *(prAdapter->rWlanInfo. + * arPowerSaveMode[prAdapter->ucP2PDevBssIdx].ucPsProfile); + */ + /* *pu4QueryInfoLen = sizeof(PARAM_POWER_MODE); */ + } + + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used to set the power save profile. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetP2pPowerSaveProfile(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + uint32_t status; + enum PARAM_POWER_MODE ePowerMode; + + DEBUGFUNC("wlanoidSetP2pPowerSaveProfile"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(enum PARAM_POWER_MODE); + if (u4SetBufferLen < sizeof(enum PARAM_POWER_MODE)) { + DBGLOG(REQ, WARN, "Invalid length %u\n", u4SetBufferLen); + return WLAN_STATUS_INVALID_LENGTH; + } else if (*(enum PARAM_POWER_MODE *) + pvSetBuffer >= Param_PowerModeMax) { + DBGLOG(REQ, WARN, "Invalid power mode %d\n", + *(enum PARAM_POWER_MODE *) pvSetBuffer); + return WLAN_STATUS_INVALID_DATA; + } + + ePowerMode = *(enum PARAM_POWER_MODE *) pvSetBuffer; + + if (prAdapter->fgEnCtiaPowerMode) { + if (ePowerMode == Param_PowerModeCAM) { + /*Todo:: Nothing */ + /*Todo:: Nothing */ + } else { + /* User setting to PS mode + *(Param_PowerModeMAX_PSP or Param_PowerModeFast_PSP) + */ + + if (prAdapter->u4CtiaPowerMode == 0) { + /* force to keep in CAM mode */ + ePowerMode = Param_PowerModeCAM; + } else if (prAdapter->u4CtiaPowerMode == 1) { + ePowerMode = Param_PowerModeMAX_PSP; + } else if (prAdapter->u4CtiaPowerMode == 2) { + ePowerMode = Param_PowerModeFast_PSP; + } + } + } + + /* TODO: FIXME */ + status = nicConfigPowerSaveProfile(prAdapter, prAdapter->ucP2PDevBssIdx, + ePowerMode, TRUE, PS_CALLER_P2P); + return status; +} /* end of wlanoidSetP2pPowerSaveProfile() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used to set the power save profile. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetP2pSetNetworkAddress(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t i, j; + struct CMD_SET_NETWORK_ADDRESS_LIST *prCmdNWAddrList; + struct PARAM_NETWORK_ADDRESS_LIST *prNWAddrList = + (struct PARAM_NETWORK_ADDRESS_LIST *) pvSetBuffer; + struct PARAM_NETWORK_ADDRESS *prNWAddress; + struct PARAM_NETWORK_ADDRESS_IP *prNetAddrIp; + uint32_t u4IpAddressCount, u4CmdSize; + uint8_t *pucBuf = (uint8_t *) pvSetBuffer; + + DEBUGFUNC("wlanoidSetP2pSetNetworkAddress"); + DBGLOG(INIT, TRACE, "\n"); + DBGLOG(INIT, INFO, "wlanoidSetP2pSetNetworkAddress (%d)\n", + (int16_t) u4SetBufferLen); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = 4; + + if (u4SetBufferLen < sizeof(struct PARAM_NETWORK_ADDRESS_LIST)) + return WLAN_STATUS_INVALID_DATA; + + *pu4SetInfoLen = 0; + u4IpAddressCount = 0; + + prNWAddress = prNWAddrList->arAddress; + for (i = 0; i < prNWAddrList->u4AddressCount; i++) { + if (prNWAddress->u2AddressType + == PARAM_PROTOCOL_ID_TCP_IP && + prNWAddress->u2AddressLength + == sizeof(struct PARAM_NETWORK_ADDRESS_IP)) { + u4IpAddressCount++; + } + + prNWAddress = (struct PARAM_NETWORK_ADDRESS *) + ((unsigned long) prNWAddress + + (unsigned long) (prNWAddress->u2AddressLength + + OFFSET_OF(struct PARAM_NETWORK_ADDRESS, aucAddress))); + } + + /* construct payload of command packet */ + u4CmdSize = + OFFSET_OF(struct CMD_SET_NETWORK_ADDRESS_LIST, arNetAddress) + + sizeof(struct CMD_IPV4_NETWORK_ADDRESS) * u4IpAddressCount; + + if (u4IpAddressCount == 0) + u4CmdSize = sizeof(struct CMD_SET_NETWORK_ADDRESS_LIST); + + prCmdNWAddrList = (struct CMD_SET_NETWORK_ADDRESS_LIST *) + kalMemAlloc(u4CmdSize, VIR_MEM_TYPE); + + if (prCmdNWAddrList == NULL) + return WLAN_STATUS_FAILURE; + + /* fill P_CMD_SET_NETWORK_ADDRESS_LIST */ + prCmdNWAddrList->ucBssIndex = prNWAddrList->ucBssIdx; + + /* only to set IP address to FW once ARP filter is enabled */ + if (prAdapter->fgEnArpFilter) { + prCmdNWAddrList->ucAddressCount = + (uint8_t) u4IpAddressCount; + prNWAddress = prNWAddrList->arAddress; + + DBGLOG(INIT, INFO, "u4IpAddressCount (%u)\n", + (int32_t) u4IpAddressCount); + + for (i = 0, j = 0; i < prNWAddrList->u4AddressCount; i++) { + if (prNWAddress->u2AddressType + == PARAM_PROTOCOL_ID_TCP_IP && + prNWAddress->u2AddressLength + == sizeof(struct PARAM_NETWORK_ADDRESS_IP)) { + + prNetAddrIp = + (struct PARAM_NETWORK_ADDRESS_IP *) + prNWAddress->aucAddress; + + kalMemCopy( + prCmdNWAddrList->arNetAddress[j] + .aucIpAddr, + &(prNetAddrIp->in_addr), + sizeof(uint32_t)); + + j++; + + pucBuf = (uint8_t *) &prNetAddrIp->in_addr; + DBGLOG(INIT, INFO, + "prNetAddrIp->in_addr:%d:%d:%d:%d\n", + (uint8_t) pucBuf[0], + (uint8_t) pucBuf[1], + (uint8_t) pucBuf[2], + (uint8_t) pucBuf[3]); + } + + prNWAddress = (struct PARAM_NETWORK_ADDRESS *) + ((unsigned long) prNWAddress + + (unsigned long) (prNWAddress->u2AddressLength + + OFFSET_OF(struct PARAM_NETWORK_ADDRESS, + aucAddress))); + } + + } else { + prCmdNWAddrList->ucAddressCount = 0; + } + + rStatus = wlanSendSetQueryCmd(prAdapter, + CMD_ID_SET_IP_ADDRESS, + TRUE, + FALSE, + TRUE, + nicCmdEventSetIpAddress, + nicOidCmdTimeoutCommon, + u4CmdSize, + (uint8_t *) prCmdNWAddrList, + pvSetBuffer, + u4SetBufferLen); + + kalMemFree(prCmdNWAddrList, VIR_MEM_TYPE, u4CmdSize); + return rStatus; +} /* end of wlanoidSetP2pSetNetworkAddress() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set Multicast Address List. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer Pointer to the buffer + * that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + * \retval WLAN_STATUS_ADAPTER_NOT_READY + * \retval WLAN_STATUS_MULTICAST_FULL + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetP2PMulticastList(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + struct CMD_MAC_MCAST_ADDR rCmdMacMcastAddr; + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + /* The data must be a multiple of the Ethernet address size. */ + if ((u4SetBufferLen % MAC_ADDR_LEN)) { + DBGLOG(REQ, WARN, "Invalid MC list length %u\n", + u4SetBufferLen); + + *pu4SetInfoLen = + (((u4SetBufferLen + MAC_ADDR_LEN) - 1) + / MAC_ADDR_LEN) * MAC_ADDR_LEN; + + return WLAN_STATUS_INVALID_LENGTH; + } + + *pu4SetInfoLen = u4SetBufferLen; + + /* Verify if we can support so many multicast addresses. */ + if (u4SetBufferLen > MAX_NUM_GROUP_ADDR * MAC_ADDR_LEN) { + DBGLOG(REQ, WARN, "Too many MC addresses\n"); + + return WLAN_STATUS_MULTICAST_FULL; + } + + /* NOTE(Kevin): Windows may set u4SetBufferLen == 0 && + * pvSetBuffer == NULL to clear exist Multicast List. + */ + if (u4SetBufferLen) + ASSERT(pvSetBuffer); + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, WARN, + "Fail in set multicast list! (Adapter not ready). ACPI=D%d, Radio=%d\n", + prAdapter->rAcpiState, prAdapter->fgIsRadioOff); + return WLAN_STATUS_ADAPTER_NOT_READY; + } + + rCmdMacMcastAddr.u4NumOfGroupAddr = u4SetBufferLen / MAC_ADDR_LEN; + /* TODO: */ + rCmdMacMcastAddr.ucBssIndex = prAdapter->ucP2PDevBssIdx; + kalMemCopy(rCmdMacMcastAddr.arAddress, pvSetBuffer, u4SetBufferLen); + + return wlanoidSendSetQueryP2PCmd(prAdapter, + CMD_ID_MAC_MCAST_ADDR, + prAdapter->ucP2PDevBssIdx, + /* TODO: */ + /* This CMD response is no need + * to complete the OID. + * Or the event would unsync. + */ + TRUE, FALSE, FALSE, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_MAC_MCAST_ADDR), + (uint8_t *) &rCmdMacMcastAddr, + pvSetBuffer, + u4SetBufferLen); + +} /* end of wlanoidSetP2PMulticastList() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to send GAS frame + * for P2P Service Discovery Request + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + * \retval WLAN_STATUS_ADAPTER_NOT_READY + * \retval WLAN_STATUS_MULTICAST_FULL + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSendP2PSDRequest(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + if (u4SetBufferLen) + ASSERT(pvSetBuffer); + + if (u4SetBufferLen < sizeof(struct PARAM_P2P_SEND_SD_REQUEST)) { + *pu4SetInfoLen = sizeof(struct PARAM_P2P_SEND_SD_REQUEST); + return WLAN_STATUS_BUFFER_TOO_SHORT; + } +/* rWlanStatus = p2pFsmRunEventSDRequest(prAdapter + * , (P_PARAM_P2P_SEND_SD_REQUEST)pvSetBuffer); + */ + + return rWlanStatus; +} /* end of wlanoidSendP2PSDRequest() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to send GAS frame + * for P2P Service Discovery Response + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + * \retval WLAN_STATUS_ADAPTER_NOT_READY + * \retval WLAN_STATUS_MULTICAST_FULL + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSendP2PSDResponse(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + if (u4SetBufferLen) + ASSERT(pvSetBuffer); + + if (u4SetBufferLen < sizeof(struct PARAM_P2P_SEND_SD_RESPONSE)) { + *pu4SetInfoLen = sizeof(struct PARAM_P2P_SEND_SD_RESPONSE); + return WLAN_STATUS_BUFFER_TOO_SHORT; + } +/* rWlanStatus = p2pFsmRunEventSDResponse(prAdapter + * , (P_PARAM_P2P_SEND_SD_RESPONSE)pvSetBuffer); + */ + + return rWlanStatus; +} /* end of wlanoidGetP2PSDRequest() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to get GAS frame + * for P2P Service Discovery Request + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[out] pvQueryBuffer A pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufferLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, + * returns the number of + * bytes written into the query buffer. If the call + * failed due to invalid length of the query buffer, + * returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + * \retval WLAN_STATUS_ADAPTER_NOT_READY + * \retval WLAN_STATUS_MULTICAST_FULL + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidGetP2PSDRequest(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) +{ + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; +/* PUINT_8 pucChannelNum = NULL; */ +/* UINT_8 ucChannelNum = 0, ucSeqNum = 0; */ + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + if (u4QueryBufferLen < sizeof(struct PARAM_P2P_GET_SD_REQUEST)) { + *pu4QueryInfoLen = sizeof(struct PARAM_P2P_GET_SD_REQUEST); + return WLAN_STATUS_BUFFER_TOO_SHORT; + } + + DBGLOG(P2P, TRACE, "Get Service Discovery Request\n"); + + *pu4QueryInfoLen = 0; + return rWlanStatus; +} /* end of wlanoidGetP2PSDRequest() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to get GAS frame + * for P2P Service Discovery Response + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[out] pvQueryBuffer A pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufferLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the call + * failed due to invalid length of the query buffer, + * returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + * \retval WLAN_STATUS_ADAPTER_NOT_READY + * \retval WLAN_STATUS_MULTICAST_FULL + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidGetP2PSDResponse(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) +{ + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + /* UINT_8 ucSeqNum = 0, */ + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + if (u4QueryBufferLen < sizeof(struct PARAM_P2P_GET_SD_RESPONSE)) { + *pu4QueryInfoLen = sizeof(struct PARAM_P2P_GET_SD_RESPONSE); + return WLAN_STATUS_BUFFER_TOO_SHORT; + } + + DBGLOG(P2P, TRACE, "Get Service Discovery Response\n"); + + *pu4QueryInfoLen = 0; + return rWlanStatus; +} /* end of wlanoidGetP2PSDResponse() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to terminate P2P Service Discovery Phase + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + * \retval WLAN_STATUS_ADAPTER_NOT_READY + * \retval WLAN_STATUS_MULTICAST_FULL + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetP2PTerminateSDPhase(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + struct PARAM_P2P_TERMINATE_SD_PHASE *prP2pTerminateSD = + (struct PARAM_P2P_TERMINATE_SD_PHASE *) NULL; + uint8_t aucNullAddr[] = NULL_MAC_ADDR; + + do { + if ((prAdapter == NULL) || (pu4SetInfoLen == NULL)) + break; + + if ((u4SetBufferLen) && (pvSetBuffer == NULL)) + break; + + if (u4SetBufferLen + < sizeof(struct PARAM_P2P_TERMINATE_SD_PHASE)) { + + *pu4SetInfoLen = + sizeof(struct PARAM_P2P_TERMINATE_SD_PHASE); + rWlanStatus = WLAN_STATUS_BUFFER_TOO_SHORT; + break; + } + + prP2pTerminateSD = + (struct PARAM_P2P_TERMINATE_SD_PHASE *) pvSetBuffer; + + if (EQUAL_MAC_ADDR(prP2pTerminateSD->rPeerAddr, aucNullAddr)) { + DBGLOG(P2P, TRACE, "Service Discovery Version 2.0\n"); +/* p2pFuncSetVersionNumOfSD(prAdapter, 2); */ + } + /* rWlanStatus = p2pFsmRunEventSDAbort(prAdapter); */ + + } while (FALSE); + + return rWlanStatus; +} /* end of wlanoidSetP2PTerminateSDPhase() */ + +#if CFG_SUPPORT_ANTI_PIRACY +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + * \retval WLAN_STATUS_ADAPTER_NOT_READY + * \retval WLAN_STATUS_MULTICAST_FULL + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetSecCheckRequest(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + if (u4SetBufferLen) + ASSERT(pvSetBuffer); + +#if 0 /* Comment it because CMD_ID_SEC_CHECK is not defined */ + return wlanoidSendSetQueryP2PCmd(prAdapter, + CMD_ID_SEC_CHECK, + prAdapter->ucP2PDevBssIdx, + FALSE, + TRUE, + TRUE, + NULL, + nicOidCmdTimeoutCommon, + u4SetBufferLen, + (uint8_t *) pvSetBuffer, + pvSetBuffer, + u4SetBufferLen); +#else + return WLAN_STATUS_NOT_SUPPORTED; +#endif +} /* end of wlanoidSetSecCheckRequest() */ + +#if 0 +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[out] pvQueryBuffer A pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufferLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. + * If the call failed due to invalid length + * of the query buffer, + * returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + * \retval WLAN_STATUS_ADAPTER_NOT_READY + * \retval WLAN_STATUS_MULTICAST_FULL + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidGetSecCheckResponse(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) +{ + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + /* P_WLAN_MAC_HEADER_T prWlanHdr = (P_WLAN_MAC_HEADER_T)NULL; */ + struct GLUE_INFO *prGlueInfo; + + prGlueInfo = prAdapter->prGlueInfo; + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + if (u4QueryBufferLen > 256) + u4QueryBufferLen = 256; + + *pu4QueryInfoLen = u4QueryBufferLen; + +#if DBG + DBGLOG_MEM8(SEC, LOUD, + prGlueInfo->prP2PInfo[0]->aucSecCheckRsp, + u4QueryBufferLen); +#endif + kalMemCopy((uint8_t *) + (pvQueryBuffer + + OFFSET_OF(struct iw_p2p_transport_struct, aucBuffer)), + prGlueInfo->prP2PInfo[0]->aucSecCheckRsp, + u4QueryBufferLen); + + return rWlanStatus; +} /* end of wlanoidGetSecCheckResponse() */ +#endif +#endif + +uint32_t +wlanoidSetNoaParam(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + struct PARAM_CUSTOM_NOA_PARAM_STRUCT *prNoaParam; + struct CMD_CUSTOM_NOA_PARAM_STRUCT rCmdNoaParam; + + DEBUGFUNC("wlanoidSetNoaParam"); + DBGLOG(INIT, TRACE, "\n"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(struct PARAM_CUSTOM_NOA_PARAM_STRUCT); + + if (u4SetBufferLen < sizeof(struct PARAM_CUSTOM_NOA_PARAM_STRUCT)) + return WLAN_STATUS_INVALID_LENGTH; + + ASSERT(pvSetBuffer); + + prNoaParam = (struct PARAM_CUSTOM_NOA_PARAM_STRUCT *) pvSetBuffer; + + kalMemZero(&rCmdNoaParam, sizeof(struct CMD_CUSTOM_NOA_PARAM_STRUCT)); + rCmdNoaParam.u4NoaDurationMs = prNoaParam->u4NoaDurationMs; + rCmdNoaParam.u4NoaIntervalMs = prNoaParam->u4NoaIntervalMs; + rCmdNoaParam.u4NoaCount = prNoaParam->u4NoaCount; + rCmdNoaParam.ucBssIdx = prNoaParam->ucBssIdx; + +#if 0 + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_SET_NOA_PARAM, + TRUE, + FALSE, + TRUE, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_CUSTOM_NOA_PARAM_STRUCT), + (uint8_t *) &rCmdNoaParam, + pvSetBuffer, + u4SetBufferLen); +#else + return wlanoidSendSetQueryP2PCmd(prAdapter, + CMD_ID_SET_NOA_PARAM, + prNoaParam->ucBssIdx, + TRUE, + FALSE, + TRUE, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_CUSTOM_NOA_PARAM_STRUCT), + (uint8_t *) &rCmdNoaParam, + pvSetBuffer, + u4SetBufferLen); + +#endif + +} + +uint32_t +wlanoidSetOppPsParam(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + struct PARAM_CUSTOM_OPPPS_PARAM_STRUCT *prOppPsParam; + struct CMD_CUSTOM_OPPPS_PARAM_STRUCT rCmdOppPsParam; + + DEBUGFUNC("wlanoidSetOppPsParam"); + DBGLOG(INIT, TRACE, "\n"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(struct PARAM_CUSTOM_OPPPS_PARAM_STRUCT); + + if (u4SetBufferLen < sizeof(struct PARAM_CUSTOM_OPPPS_PARAM_STRUCT)) + return WLAN_STATUS_INVALID_LENGTH; + + ASSERT(pvSetBuffer); + + prOppPsParam = (struct PARAM_CUSTOM_OPPPS_PARAM_STRUCT *) pvSetBuffer; + + kalMemZero(&rCmdOppPsParam, + sizeof(struct CMD_CUSTOM_OPPPS_PARAM_STRUCT)); + rCmdOppPsParam.u4CTwindowMs = prOppPsParam->u4CTwindowMs; + rCmdOppPsParam.ucBssIdx = prOppPsParam->ucBssIdx; + +#if 0 + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_SET_OPPPS_PARAM, + TRUE, + FALSE, + TRUE, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_CUSTOM_OPPPS_PARAM_STRUCT), + (uint8_t *) &rCmdOppPsParam, + pvSetBuffer, + u4SetBufferLen); +#else + return wlanoidSendSetQueryP2PCmd(prAdapter, + CMD_ID_SET_OPPPS_PARAM, + prOppPsParam->ucBssIdx, + TRUE, + FALSE, + TRUE, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_CUSTOM_OPPPS_PARAM_STRUCT), + (uint8_t *) &rCmdOppPsParam, + pvSetBuffer, + u4SetBufferLen); + +#endif + +} + +uint32_t +wlanoidSetUApsdParam(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + struct PARAM_CUSTOM_UAPSD_PARAM_STRUCT *prUapsdParam; + struct CMD_CUSTOM_UAPSD_PARAM_STRUCT rCmdUapsdParam; + struct PM_PROFILE_SETUP_INFO *prPmProfSetupInfo; + struct BSS_INFO *prBssInfo; + u_int8_t fgIsOid = TRUE; + + DEBUGFUNC("wlanoidSetUApsdParam"); + DBGLOG(INIT, TRACE, "\n"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(struct PARAM_CUSTOM_UAPSD_PARAM_STRUCT); + + if (u4SetBufferLen < sizeof(struct PARAM_CUSTOM_UAPSD_PARAM_STRUCT)) + return WLAN_STATUS_INVALID_LENGTH; + + ASSERT(pvSetBuffer); + + prUapsdParam = (struct PARAM_CUSTOM_UAPSD_PARAM_STRUCT *) pvSetBuffer; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prUapsdParam->ucBssIdx); + prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; + + kalMemZero(&rCmdUapsdParam, + sizeof(struct CMD_CUSTOM_UAPSD_PARAM_STRUCT)); + + rCmdUapsdParam.fgEnAPSD = prUapsdParam->fgEnAPSD; + + rCmdUapsdParam.fgEnAPSD_AcBe = prUapsdParam->fgEnAPSD_AcBe; + rCmdUapsdParam.fgEnAPSD_AcBk = prUapsdParam->fgEnAPSD_AcBk; + rCmdUapsdParam.fgEnAPSD_AcVo = prUapsdParam->fgEnAPSD_AcVo; + rCmdUapsdParam.fgEnAPSD_AcVi = prUapsdParam->fgEnAPSD_AcVi; + + prPmProfSetupInfo->ucBmpDeliveryAC = + ((prUapsdParam->fgEnAPSD_AcBe << 0) | + (prUapsdParam->fgEnAPSD_AcBk << 1) | + (prUapsdParam->fgEnAPSD_AcVi << 2) | + (prUapsdParam->fgEnAPSD_AcVo << 3)); + + prPmProfSetupInfo->ucBmpTriggerAC = + ((prUapsdParam->fgEnAPSD_AcBe << 0) | + (prUapsdParam->fgEnAPSD_AcBk << 1) | + (prUapsdParam->fgEnAPSD_AcVi << 2) | + (prUapsdParam->fgEnAPSD_AcVo << 3)); + + rCmdUapsdParam.ucMaxSpLen = prUapsdParam->ucMaxSpLen; + prPmProfSetupInfo->ucUapsdSp = prUapsdParam->ucMaxSpLen; + + if (prAdapter->prGlueInfo) + fgIsOid = (prAdapter->prGlueInfo->u4TxThreadPid + != KAL_GET_CURRENT_THREAD_ID()); + +#if 0 + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_SET_UAPSD_PARAM, + TRUE, + FALSE, + TRUE, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_CUSTOM_UAPSD_PARAM_STRUCT), + (uint8_t *) &rCmdUapsdParam, + pvSetBuffer, + u4SetBufferLen); +#else + return wlanoidSendSetQueryP2PCmd(prAdapter, + CMD_ID_SET_UAPSD_PARAM, + prBssInfo->ucBssIndex, + TRUE, + FALSE, + fgIsOid, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_CUSTOM_UAPSD_PARAM_STRUCT), + (uint8_t *) &rCmdUapsdParam, + pvSetBuffer, + u4SetBufferLen); + +#endif +} + +uint32_t +wlanoidQueryP2pVersion(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) +{ + uint32_t rResult = WLAN_STATUS_FAILURE; +/* PUINT_8 pucVersionNum = (PUINT_8)pvQueryBuffer; */ + + do { + if ((prAdapter == NULL) || (pu4QueryInfoLen == NULL)) + break; + + if ((u4QueryBufferLen) && (pvQueryBuffer == NULL)) + break; + + if (u4QueryBufferLen < sizeof(uint8_t)) { + *pu4QueryInfoLen = sizeof(uint8_t); + rResult = WLAN_STATUS_BUFFER_TOO_SHORT; + break; + } + + } while (FALSE); + + return rResult; +} /* wlanoidQueryP2pVersion */ + +#if CFG_SUPPORT_HOTSPOT_WPS_MANAGER + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used to set the WPS mode. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetP2pWPSmode(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + uint32_t status; + uint32_t u4IsWPSmode = 0; + int i = 0; + + DEBUGFUNC("wlanoidSetP2pWPSmode"); + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + if (pvSetBuffer) + u4IsWPSmode = *(uint32_t *) pvSetBuffer; + else + u4IsWPSmode = 0; + + /* set all Role to the same value */ + for (i = 0; i < KAL_P2P_NUM; i++) + if (u4IsWPSmode) + prAdapter->rWifiVar.prP2PConnSettings[i]->fgIsWPSMode + = 1; + else + prAdapter->rWifiVar.prP2PConnSettings[i]->fgIsWPSMode + = 0; + + status = nicUpdateBss(prAdapter, prAdapter->ucP2PDevBssIdx); + + return status; +} /* end of wlanoidSetP2pWPSmode() */ + +#endif + +uint32_t +wlanoidSetP2pSupplicantVersion(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + uint32_t rResult = WLAN_STATUS_FAILURE; + uint8_t ucVersionNum; + + do { + if ((prAdapter == NULL) || (pu4SetInfoLen == NULL)) { + + rResult = WLAN_STATUS_INVALID_DATA; + break; + } + + if ((u4SetBufferLen) && (pvSetBuffer == NULL)) { + rResult = WLAN_STATUS_INVALID_DATA; + break; + } + + *pu4SetInfoLen = sizeof(uint8_t); + + if (u4SetBufferLen < sizeof(uint8_t)) { + rResult = WLAN_STATUS_INVALID_LENGTH; + break; + } + + ucVersionNum = *((uint8_t *) pvSetBuffer); + + rResult = WLAN_STATUS_SUCCESS; + } while (FALSE); + + return rResult; +} /* wlanoidSetP2pSupplicantVersion */ + +#if CFG_SUPPORT_P2P_RSSI_QUERY +uint32_t +wlanoidQueryP2pRssi(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) +{ + DEBUGFUNC("wlanoidQueryP2pRssi"); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) + ASSERT(pvQueryBuffer); + + if (prAdapter->fgIsEnableLpdvt) + return WLAN_STATUS_NOT_SUPPORTED; + + *pu4QueryInfoLen = sizeof(int32_t); + + /* Check for query buffer length */ + if (u4QueryBufferLen < *pu4QueryInfoLen) { + DBGLOG(REQ, WARN, "Too short length %ld\n", u4QueryBufferLen); + return WLAN_STATUS_BUFFER_TOO_SHORT; + } + + if (prAdapter->fgIsP2pLinkQualityValid == TRUE + && (kalGetTimeTick() - prAdapter->rP2pLinkQualityUpdateTime) + <= CFG_LINK_QUALITY_VALID_PERIOD) { + + int32_t rRssi; + + /* ranged from (-128 ~ 30) in unit of dBm */ + rRssi = (int32_t) prAdapter->rP2pLinkQuality.cRssi; + + if (rRssi > PARAM_WHQL_RSSI_MAX_DBM) + rRssi = PARAM_WHQL_RSSI_MAX_DBM; + else if (rRssi < PARAM_WHQL_RSSI_MIN_DBM) + rRssi = PARAM_WHQL_RSSI_MIN_DBM; + + kalMemCopy(pvQueryBuffer, &rRssi, sizeof(int32_t)); + return WLAN_STATUS_SUCCESS; + } +#ifdef LINUX + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_GET_LINK_QUALITY, + FALSE, + TRUE, + TRUE, + nicCmdEventQueryLinkQuality, + nicOidCmdTimeoutCommon, + *pu4QueryInfoLen, + pvQueryBuffer, + pvQueryBuffer, + u4QueryBufferLen); +#else + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_GET_LINK_QUALITY, + FALSE, + TRUE, + TRUE, + nicCmdEventQueryLinkQuality, + nicOidCmdTimeoutCommon, + 0, + NULL, + pvQueryBuffer, + u4QueryBufferLen); + +#endif +} /* wlanoidQueryP2pRssi */ +#endif + +uint32_t +wlanoidAbortP2pScan(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) +{ + uint8_t ucBssIdx; + + ASSERT(prAdapter); + + ucBssIdx = *((uint8_t *) pvQueryBuffer); + + if (ucBssIdx == prAdapter->ucP2PDevBssIdx) + p2pDevFsmRunEventScanAbort(prAdapter, ucBssIdx); + else + p2pRoleFsmRunEventScanAbort(prAdapter, ucBssIdx); + + return WLAN_STATUS_SUCCESS; +} + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/dvt/dvt_common.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/dvt/dvt_common.c new file mode 100644 index 0000000000000000000000000000000000000000..c1e73809f3a7344fad2fa5e78f6bc8b79a718c6a --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/dvt/dvt_common.c @@ -0,0 +1,1196 @@ +/******************************************************************************* + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ + +/* + ** Id: include/dvt_common.c + */ + +/*! \file dvt_common.c + * \brief This file contains the declairations of sys dvt command + */ + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ +struct AUTOMATION_DVT automation_dvt; +struct TXS_FREE_LIST_POOL TxsFreeEntrylist; + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#if CFG_SUPPORT_WIFI_SYSDVT +/* +* This routine is used to init TXS pool for DVT +*/ +void TxsPoolInit(void) +{ + if (TxsFreeEntrylist.txs_list_cnt == 0) { + spin_lock_init(&TxsFreeEntrylist.Lock); + INIT_LIST_HEAD(&TxsFreeEntrylist.pool_head.List); + INIT_LIST_HEAD(&TxsFreeEntrylist.head.mList); + } + + TxsFreeEntrylist.txs_list_cnt++; +} + +/* +* This routine is used to uninit TXS pool for DVT +*/ +void TxsPoolUnInit(void) +{ + struct list_head *prCur, *prNext; + + TxsFreeEntrylist.txs_list_cnt--; + + if (TxsFreeEntrylist.txs_list_cnt == 0) { + struct TXS_LIST_POOL *pEntry = NULL; + + list_for_each_safe(prCur, prNext, + &TxsFreeEntrylist.pool_head.List) { + pEntry = + list_entry(prCur, struct TXS_LIST_POOL, List); + list_del_init(&pEntry->List); + list_del(prCur); + if (pEntry == NULL) + DBGLOG(REQ, LOUD, "pEntry null\n"); + kfree(pEntry); + } + } +} + +/* +* This routine is used to test TXS function. +* init TXS DVT structure and start to test +*/ +bool TxsInit(void) +{ + uint32_t i; + struct TXS_LIST *list = &automation_dvt.txs.txs_list; + + if (automation_dvt.txs.isinit) + return TRUE; + + automation_dvt.txs.isinit = FALSE; + automation_dvt.txs.total_req = 0; + automation_dvt.txs.total_rsp = 0; + automation_dvt.txs.stop_send_test = TRUE; + automation_dvt.txs.test_type = 0; + automation_dvt.txs.pid = 1; + + spin_lock_init(&list->lock); + + for (i = 0; i < PID_SIZE; i++) { + INIT_LIST_HEAD(&list->pHead[i].mList); + automation_dvt.txs.check_item[i].time_stamp = 0; + } + + list->Num = 0; + TxsPoolInit(); + + if (list_empty(&TxsFreeEntrylist.pool_head.List)) { + struct TXS_LIST_POOL *Pool = NULL; + struct TXS_LIST_POOL *pFreepool = NULL; + struct TXS_LIST_ENTRY *pEntry = NULL; + struct TXS_LIST_ENTRY *newEntry = NULL; + + Pool = kmalloc(sizeof(struct TXS_LIST_POOL), GFP_ATOMIC); + pFreepool = &TxsFreeEntrylist.pool_head; + list_add(&Pool->List, &pFreepool->List); + pEntry = &TxsFreeEntrylist.head; + + for (i = 0; i < TXS_LIST_ELEM_NUM; i++) { + newEntry = &Pool->Entry[i]; + list_add(&newEntry->mList, &pEntry->mList); + } + } + + list->pFreeEntrylist = &TxsFreeEntrylist; + automation_dvt.txs.isinit = TRUE; + return TRUE; +} + +/* +* This routine is used to test TXS function. +* destroy TXS DVT structure +*/ +bool TxsExit(void) +{ + uint32_t i = 0; + unsigned long IrqFlags = 0; + uint16_t wait_cnt = 0; + struct TXS_LIST *list = &automation_dvt.txs.txs_list; + + automation_dvt.txs.isinit = FALSE; + automation_dvt.txs.total_req = 0; + automation_dvt.txs.total_rsp = 0; + automation_dvt.txs.stop_send_test = TRUE; + automation_dvt.txs.test_type = 0; + automation_dvt.txs.pid = 1; + + while (automation_dvt.txs.txs_list.Num > 0) { + DBGLOG(REQ, LOUD, "wait entry to be deleted\n"); + kalMsleep(100);/* OS_WAIT(10); */ + wait_cnt++; + + if (wait_cnt > 100) + break; + } + + spin_lock_irqsave(&list->lock, IrqFlags); + + for (i = 0; i < PID_SIZE; i++) { + INIT_LIST_HEAD(&list->pHead[i].mList); + automation_dvt.txs.check_item[i].time_stamp = 0; + } + + spin_unlock_irqrestore(&list->lock, IrqFlags); + list->Num = 0; + TxsPoolUnInit(); + DBGLOG(REQ, LOUD, "TxsPoolUnInit done\n"); + + return TRUE; +} + +/* +* This routine is used to initial DVT of automation. +*/ +bool AutomationInit(struct ADAPTER *pAd, int32_t auto_type) +{ + bool ret; + + ret = TRUE; + if (!pAd) + return FALSE; + + DBGLOG(REQ, LOUD, "In AutomationInit\n"); + + if (pAd->auto_dvt == NULL) { + kalMemZero(&automation_dvt, sizeof(struct AUTOMATION_DVT)); + pAd->auto_dvt = &automation_dvt; + DBGLOG(REQ, LOUD, "AutomationInit\n"); + } + + switch (auto_type) { + case TXS: + ret = TxsInit(); + break; + case RXV: + break; +#if (CFG_SUPPORT_DMASHDL_SYSDVT) + case DMASHDL: + break; +#endif + case CSO: + break; + case SKIP_CH: + break; + } + + return ret; +} + +struct TXS_LIST_ENTRY *GetTxsEntryFromFreeList(void) +{ + struct TXS_LIST_ENTRY *pEntry = NULL; + struct TXS_LIST_ENTRY *pheadEntry = NULL; + struct TXS_FREE_LIST_POOL *pFreeEntrylist = NULL; + unsigned long IrqFlags = 0; + uint32_t i; + + pFreeEntrylist = + automation_dvt.txs.txs_list.pFreeEntrylist; + if (pFreeEntrylist == NULL) + return NULL; + + spin_lock_irqsave(&pFreeEntrylist->Lock, IrqFlags); + + if (list_empty(&pFreeEntrylist->head.mList)) { + struct TXS_LIST_POOL *Pool = NULL; + struct TXS_LIST_POOL *pFreepool = NULL; + + DBGLOG(REQ, LOUD, "allocated new pool\n"); + Pool = kmalloc(sizeof(struct TXS_LIST_POOL), GFP_ATOMIC); + pFreepool = &pFreeEntrylist->pool_head; + list_add(&Pool->List, &pFreepool->List); + pheadEntry = &pFreeEntrylist->head; + + for (i = 0; i < TXS_LIST_ELEM_NUM; i++) { + pEntry = &Pool->Entry[i]; + list_add(&pEntry->mList, &pheadEntry->mList); + } + pFreeEntrylist->entry_number += TXS_LIST_ELEM_NUM; + } + + pheadEntry = &pFreeEntrylist->head; + if (!list_empty(&pheadEntry->mList)) { + pEntry = list_entry(&pheadEntry->mList, + struct TXS_LIST_ENTRY, mList); + list_del(&pEntry->mList); + } + + if (pEntry != NULL) + pFreeEntrylist->entry_number -= 1; + + spin_unlock_irqrestore(&pFreeEntrylist->Lock, IrqFlags); + return pEntry; +} + +/* +* This routine is used to test TXS function. +* Send RTS +*/ +int SendRTS( + struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + PFN_TX_DONE_HANDLER pfTxDoneHandler) +{ + struct MSDU_INFO *prMsduInfo; + struct _FRAME_RTS *prTxFrame; + struct BSS_INFO *prBssInfo; + uint16_t u2EstimatedFrameLen; + unsigned long duration = 0; + + ASSERT(prAdapter); + ASSERT(prStaRec); + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex); + + ASSERT(prBssInfo); + + /* Calculate MSDU buffer length */ + u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + + sizeof(struct _FRAME_RTS); + + /* Alloc MSDU_INFO */ + prMsduInfo = (struct MSDU_INFO *)cnmMgtPktAlloc(prAdapter, + u2EstimatedFrameLen); + + if (!prMsduInfo) { + DBGLOG(REQ, WARN, + "No MSDU_INFO_T for sending dvt RTS Frame.\n"); + return -1; + } + + kalMemZero(prMsduInfo->prPacket, u2EstimatedFrameLen); + + prTxFrame = prMsduInfo->prPacket; + + /* Fill frame ctrl */ + prTxFrame->u2FrameCtrl = MAC_FRAME_RTS; + duration = 192 + (uint16_t)((sizeof(struct _FRAME_RTS)<<4)/2); + if (((sizeof(struct _FRAME_RTS)) << 4)%2) + duration++; + prTxFrame->u2Duration = 16 + (uint16_t)duration; + COPY_MAC_ADDR(prTxFrame->aucDestAddr, prStaRec->aucMacAddr); + COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); + + /* Update information of MSDU_INFO_T */ + TX_SET_MMPDU(prAdapter, + prMsduInfo, + prBssInfo->ucBssIndex, + prStaRec->ucIndex, + 16, sizeof(struct _FRAME_RTS), + pfTxDoneHandler, MSDU_RATE_MODE_AUTO); + + /* Enqueue the frame to send this control frame */ + nicTxEnqueueMsdu(prAdapter, prMsduInfo); + DBGLOG(REQ, INFO, "RTS - Send RTS\n"); + return WLAN_STATUS_SUCCESS; +} + +/* +* This routine is used to test TXS function. +* Send BA packet +*/ +int SendBA( + struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + PFN_TX_DONE_HANDLER pfTxDoneHandler) +{ + struct MSDU_INFO *prMsduInfo; + struct _FRAME_BA *prTxFrame; + struct BSS_INFO *prBssInfo; + uint16_t u2EstimatedFrameLen; + + ASSERT(prAdapter); + ASSERT(prStaRec); + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex); + + ASSERT(prBssInfo); + + /* Calculate MSDU buffer length */ + u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + + sizeof(struct _FRAME_BA); + + /* Alloc MSDU_INFO */ + prMsduInfo = (struct MSDU_INFO *) + cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); + + if (!prMsduInfo) { + DBGLOG(REQ, WARN, + "No MSDU_INFO_T for sending dvt RTS Frame.\n"); + return -1; + } + + kalMemZero(prMsduInfo->prPacket, u2EstimatedFrameLen); + + prTxFrame = prMsduInfo->prPacket; + + /* Fill frame ctrl */ + prTxFrame->u2FrameCtrl = MAC_FRAME_BLOCK_ACK; + + COPY_MAC_ADDR(prTxFrame->aucDestAddr, prStaRec->aucMacAddr); + COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); + + /* Compose the frame body's frame */ + prTxFrame->BarControl.ACKPolicy = 1; + prTxFrame->BarControl.Compressed = 1; + /* prTxFrame->StartingSeq.field.StartSeq = pBAEntry->LastIndSeq; */ + + /* Update information of MSDU_INFO_T */ + TX_SET_MMPDU(prAdapter, + prMsduInfo, + prBssInfo->ucBssIndex, + prStaRec->ucIndex, + 16, sizeof(struct _FRAME_BA), + pfTxDoneHandler, MSDU_RATE_MODE_AUTO); + + /* Enqueue the frame to send this control frame */ + nicTxEnqueueMsdu(prAdapter, prMsduInfo); + DBGLOG(REQ, INFO, "BA - Send BA\n"); + return WLAN_STATUS_SUCCESS; +} + +bool send_add_txs_queue(uint8_t pid, uint8_t wlan_idx) +{ + struct TXS_LIST *list = &automation_dvt.txs.txs_list; + uint32_t idx = 0; + unsigned long IrqFlags = 0; + struct TXS_LIST_ENTRY *pEntry; + struct TXS_LIST_ENTRY *pheadEntry; + + automation_dvt.txs.total_req++; + + if (!list || !automation_dvt.txs.isinit) { + DBGLOG(REQ, WARN, "txs_list doesnot init\n"); + return FALSE; + } + + spin_lock_irqsave(&list->lock, IrqFlags); + + pEntry = GetTxsEntryFromFreeList(); + + if (!pEntry) { + spin_unlock_irqrestore(&list->lock, IrqFlags); + DBGLOG(REQ, LOUD, "pEntry is null!!!\n"); + return FALSE; + } + + idx = automation_dvt.txs.pid % PID_SIZE; + pheadEntry = &list->pHead[idx]; + pEntry->wlan_idx = wlan_idx; + list_add(&pEntry->mList, &pheadEntry->mList); + list->Num++; + automation_dvt.txs.pid++; + + spin_unlock_irqrestore(&list->lock, IrqFlags); + + return TRUE; +} + +bool receive_del_txs_queue( + uint32_t sn, + uint8_t pid, + uint8_t wlan_idx, + uint32_t time_stamp) +{ + struct TXS_LIST *list = &automation_dvt.txs.txs_list; + unsigned long IrqFlags = 0; + unsigned long IrqFlags2 = 0; + struct TXS_FREE_LIST_POOL *pFreeEntrylist = NULL; + struct TXS_LIST_ENTRY *pheadEntry = NULL; + struct TXS_LIST_ENTRY *pEntry = NULL; + + automation_dvt.txs.total_rsp++; + + if (!list || !automation_dvt.txs.isinit) { + DBGLOG(REQ, LOUD, "txs_list doesnot init\n"); + return FALSE; + } + + pFreeEntrylist = list->pFreeEntrylist; + spin_lock_irqsave(&list->lock, IrqFlags); + + list_for_each_entry(pEntry, &list->pHead[pid].mList, mList) { + if (pEntry->wlan_idx == wlan_idx) { + if (automation_dvt.txs.check_item[pid].time_stamp + == time_stamp) + automation_dvt.txs.duplicate_txs = TRUE; + + automation_dvt.txs.check_item[pid].time_stamp = + time_stamp; + list_del_init(&pEntry->mList); + list->Num--; + spin_lock_irqsave(&pFreeEntrylist->Lock, IrqFlags2); + pheadEntry = &pFreeEntrylist->head; + list_add_tail(&pEntry->mList, &pheadEntry->mList); + pFreeEntrylist->entry_number += 1; + spin_unlock_irqrestore(&pFreeEntrylist->Lock, + IrqFlags2); + break; + } + } + spin_unlock_irqrestore(&list->lock, IrqFlags); + return pEntry; +} + +/* +* This routine is used to test TXS function. +* Send specific type of packet and check if TXS is back +*/ +int priv_driver_txs_test( + IN struct net_device *prNetDev, + IN char *pcCommand, + IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + struct STA_RECORD *prStaRec = NULL; + uint32_t u4WCID; + uint8_t ucStaIdx; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int32_t i4Recv = 0; + int32_t txs_test_type; + int32_t txs_test_format; + int8_t *this_char = NULL; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX]; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **)netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + this_char = kalStrStr(*apcArgv, "="); + if (!this_char) + return -1; + this_char++; + + DBGLOG(REQ, LOUD, "string = %s\n", this_char); + + i4Recv = sscanf(this_char, "%d-%d-%d", + &(txs_test_type), &(txs_test_format), &(u4WCID)); + + DBGLOG(REQ, LOUD, "txs_test_type=%d, txs_test_format=%d, u4WCID=%d\n", + txs_test_type, txs_test_format, u4WCID); + + if (!AutomationInit(prAdapter, TXS)) { + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "AutomationInit Fail!\n"); + return i4BytesWritten; + } + + automation_dvt.txs.duplicate_txs = FALSE; + + switch (txs_test_type) { + case TXS_INIT: + TxsExit(); + break; + + case TXS_COUNT_TEST: + automation_dvt.txs.stop_send_test = FALSE; + automation_dvt.txs.test_type = TXS_COUNT_TEST; + automation_dvt.txs.format = txs_test_format; + break; + + case TXS_BAR_TEST: + automation_dvt.txs.stop_send_test = FALSE; + automation_dvt.txs.test_type = TXS_BAR_TEST; + automation_dvt.txs.format = txs_test_format; + /* SendRefreshBAR(pAd, pEntry); */ + break; + + case TXS_DEAUTH_TEST: + automation_dvt.txs.stop_send_test = FALSE; + automation_dvt.txs.test_type = TXS_DEAUTH_TEST; + automation_dvt.txs.format = txs_test_format; + /* aisFsmSteps(prAdapter, AIS_STATE_DISCONNECTING); */ + authSendDeauthFrame(prAdapter, + prAdapter->prAisBssInfo, + prAdapter->prAisBssInfo->prStaRecOfAP, + (struct SW_RFB *) NULL, + REASON_CODE_DEAUTH_LEAVING_BSS, + aisDeauthXmitComplete); + break; + + case TXS_RTS_TEST: + automation_dvt.txs.stop_send_test = FALSE; + automation_dvt.txs.test_type = TXS_RTS_TEST; + automation_dvt.txs.format = txs_test_format; + if (wlanGetStaIdxByWlanIdx(prAdapter, u4WCID, &ucStaIdx) == + WLAN_STATUS_SUCCESS) { + prStaRec = &prAdapter->arStaRec[ucStaIdx]; + } else { + DBGLOG(REQ, LOUD, + "automation wlanGetStaIdxByWlanIdx failed\n"); + } + SendRTS(prAdapter, prStaRec, AutomationTxDone); + break; + + case TXS_BA_TEST: + automation_dvt.txs.stop_send_test = FALSE; + automation_dvt.txs.test_type = TXS_BA_TEST; + automation_dvt.txs.format = txs_test_format; + + if (wlanGetStaIdxByWlanIdx(prAdapter, u4WCID, &ucStaIdx) == + WLAN_STATUS_SUCCESS) { + prStaRec = &prAdapter->arStaRec[ucStaIdx]; + } else { + DBGLOG(REQ, LOUD, + "Automation wlanGetStaIdxByWlanIdx failed\n"); + } + + SendBA(prAdapter, prStaRec, AutomationTxDone); + break; + + case TXS_DUMP_DATA: + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "automation_dvt.txs.test_type=%u\n", + automation_dvt.txs.test_type); + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "automation_dvt.txs.format=%u\n", + automation_dvt.txs.format); + break; + } + + return i4BytesWritten; +} + +/* +* This routine is used to test TXS function. +* Check TXS test result +*/ +int priv_driver_txs_test_result( + IN struct net_device *prNetDev, + IN char *pcCommand, + IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + uint32_t txs_test_result = 0, wait_cnt = 0; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int32_t i4Recv = 0; + int8_t *this_char = NULL; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX]; + struct TXS_LIST *list = NULL; + + + list = &automation_dvt.txs.txs_list; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **)netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + this_char = kalStrStr(*apcArgv, "="); + if (!this_char) + return -1; + this_char++; + + DBGLOG(REQ, LOUD, "string = %s\n", this_char); + + i4Recv = kalkStrtos32(this_char, 0, &(txs_test_result)); + DBGLOG(REQ, LOUD, "txs_test_result = %d\n", txs_test_result); + + if (!AutomationInit(prAdapter, TXS)) { + DBGLOG(REQ, LOUD, "AutomationInit Fail!\n"); + return FALSE; + } + + automation_dvt.txs.stop_send_test = TRUE; + DBGLOG(REQ, LOUD, "wait entry to be deleted txs.total_req/rsp=%d %d\n", + automation_dvt.txs.total_req, automation_dvt.txs.total_rsp); + + if (txs_test_result == 1) { + while (automation_dvt.txs.total_req != + automation_dvt.txs.total_rsp) { + kalMsleep(100);/* OS_WAIT(10); */ + wait_cnt++; + if (wait_cnt > 100) + break; + } + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "txs.total_req %u\n", automation_dvt.txs.total_req); + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "txs.total_rsp %u\n", automation_dvt.txs.total_rsp); + + if (automation_dvt.txs.total_req == automation_dvt.txs.total_rsp + && (automation_dvt.txs.total_req != 0)) { + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "TXS_COUNT_TEST------> PASS\n"); + } else { + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "TXS_COUNT_TEST------> ERROR\n"); + } + } else if (txs_test_result == 2) { + while (list->Num > 0) { + DBGLOG(REQ, LOUD, "wait entry to be deleted\n"); + kalMsleep(100);/* OS_WAIT(10);*/ + wait_cnt++; + if (wait_cnt > 100) + break; + } + + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "txs.total_req %u\n", automation_dvt.txs.total_req); + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "txs.total_rsp %u\n", automation_dvt.txs.total_rsp); + + if (list->Num == 0) { + if ((automation_dvt.txs.duplicate_txs == FALSE) && + (automation_dvt.txs.total_req != 0)) { + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "Correct Frame Test------> PASS\n"); + } else { + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "Correct Frame Test------> FAIL duplicate txs"); + } + } else { + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "Correct Frame Test------> FAIL txs_q->Num = (%d)\n", + list->Num); + } + } + return i4BytesWritten; +} + +/* +* return 0 : No Need Test +* 1: Check Data frame +* 2: Check management and control frame +*/ +int is_frame_test(struct ADAPTER *pAd, uint8_t send_received) +{ + if (!pAd || (pAd->auto_dvt == NULL)) + return 0; + + if (send_received == 0 && automation_dvt.txs.stop_send_test == TRUE) + return 0; + + switch (automation_dvt.txs.test_type) { + case TXS_COUNT_TEST: + return 1; + case TXS_BAR_TEST: + case TXS_DEAUTH_TEST: + case TXS_RTS_TEST: + case TXS_BA_TEST: + return 2; + + default: + return 0; + } +} + +uint32_t AutomationTxDone(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN enum ENUM_TX_RESULT_CODE rTxDoneStatus) +{ + DBGLOG(REQ, LOUD, "AutomationTxDone!\n"); + if (rTxDoneStatus) + DBGLOG(REQ, LOUD, + "EVENT-TX DONE [status: %d][seq: %d]: Current Time = %d\n", + rTxDoneStatus, prMsduInfo->ucTxSeqNum, + kalGetTimeTick()); + return WLAN_STATUS_SUCCESS; +} + + +/* +* This routine is used to test RXV function. +* step1. AP fixed rate and ping to STA +* step2. STA iwpriv cmd with RXV_TEST=enable-TxMode-BW-MCS-SGI-STBC-LDPC +* step3. STA RXV_RESULT=1, check whether RX packets received from AP +* matched with specific rate +*/ +int priv_driver_rxv_test( + IN struct net_device *prNetDev, + IN char *pcCommand, + IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int32_t i4Recv = 0; + uint32_t u4Enable = 0; + int8_t *this_char = NULL; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX]; + uint32_t u4Mode = 0, u4Bw = 0, u4Mcs = 0; + uint32_t u4SGI = 0, u4STBC = 0, u4LDPC = 0; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **)netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + this_char = kalStrStr(*apcArgv, "="); + if (!this_char) + return -1; + this_char++; + + DBGLOG(REQ, LOUD, "string = %s\n", this_char); + + i4Recv = sscanf(this_char, "%d-%d-%d-%d-%d-%d-%d", &(u4Enable), + &(u4Mode), &(u4Bw), &(u4Mcs), + &(u4SGI), &(u4STBC), &(u4LDPC)); + DBGLOG(RX, LOUD, + "%s():Enable = %d, Mode = %d, BW = %d, MCS = %d\n" + "\t\t\t\tSGI = %d, STBC = %d, LDPC = %d\n", + __func__, u4Enable, u4Mode, u4Bw, u4Mcs, + u4SGI, u4STBC, u4LDPC); + + if (!AutomationInit(prAdapter, RXV)) { + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "AutomationInit Fail!\n"); + return i4BytesWritten; + } + + if (u4Mode == TX_RATE_MODE_OFDM) { + switch (u4Mcs) { + case 0: + u4Mcs = 11; + break; + case 1: + u4Mcs = 15; + break; + case 2: + u4Mcs = 10; + break; + case 3: + u4Mcs = 14; + break; + case 4: + u4Mcs = 9; + break; + case 5: + u4Mcs = 13; + break; + case 6: + u4Mcs = 8; + break; + case 7: + u4Mcs = 12; + break; + default: + DBGLOG(RX, ERROR, + "[%s]OFDM mode but wrong MCS!\n", __func__); + break; + } + } + + automation_dvt.rxv.rxv_test_result = TRUE; + automation_dvt.rxv.enable = u4Enable; + automation_dvt.rxv.rx_count = 0; + + /* expected packets */ + automation_dvt.rxv.rx_mode = u4Mode; + automation_dvt.rxv.rx_bw = u4Bw; + automation_dvt.rxv.rx_rate = u4Mcs; + automation_dvt.rxv.rx_sgi = u4SGI; + automation_dvt.rxv.rx_stbc = u4STBC; + automation_dvt.rxv.rx_ldpc = u4LDPC; + + return i4BytesWritten; +} + +/* +* This routine is used to judge result of RXV DVT. +*/ +int priv_driver_rxv_test_result( + IN struct net_device *prNetDev, + IN char *pcCommand, + IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX]; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **)netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "RXV Test------> rx_count(%d)\n", + automation_dvt.rxv.rx_count); + + if (automation_dvt.rxv.rxv_test_result == TRUE && + automation_dvt.rxv.rx_count != 0) { + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "RXV Test------> PASS\n"); + } else { + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "RXV Test------> FAIL\n"); + } + + automation_dvt.rxv.enable = 0; + + return i4BytesWritten; +} + +#if (CFG_SUPPORT_CONNAC2X == 1) +/* +* This routine is used to test RXV function. +* It will check RXV of incoming packets if match pre-setting from iwpriv +* Note. This is FALCON RXV format +*/ +void connac2x_rxv_correct_test( + IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb) +{ + uint32_t prxv1, crxv1; + uint32_t txmode, rate, frmode, sgi, nsts, ldpc, stbc; + + automation_dvt.rxv.rx_count++; + + /* P-RXV1 */ + prxv1 = ((struct HW_MAC_RX_STS_GROUP_3_V2 *) + prSwRfb->prRxStatusGroup3)->u4RxVector[0]; + rate = (prxv1 & CONNAC2X_RX_VT_RX_RATE_MASK) + >> CONNAC2X_RX_VT_RX_RATE_OFFSET; + nsts = (prxv1 & CONNAC2X_RX_VT_NSTS_MASK) + >> CONNAC2X_RX_VT_NSTS_OFFSET; + ldpc = prxv1 & CONNAC2X_RX_VT_LDPC; + /* C-RXV1 */ + crxv1 = prSwRfb->prRxStatusGroup5->u4RxVector[0]; + stbc = (crxv1 & CONNAC2X_RX_VT_STBC_MASK) + >> CONNAC2X_RX_VT_STBC_OFFSET; + txmode = (crxv1 & CONNAC2X_RX_VT_RX_MODE_MASK) + >> CONNAC2X_RX_VT_RX_MODE_OFFSET; + frmode = (crxv1 & CONNAC2X_RX_VT_FR_MODE_MASK) + >> CONNAC2X_RX_VT_FR_MODE_OFFSET; + sgi = (crxv1 & CONNAC2X_RX_VT_SHORT_GI_MASK) + >> CONNAC2X_RX_VT_SHORT_GI_OFFSET; + + if (txmode != automation_dvt.rxv.rx_mode) { + automation_dvt.rxv.rxv_test_result = FALSE; + DBGLOG(RX, ERROR, "[%s]Receive TxMode=%d, Check RxMode=%d\n", + __func__, txmode, automation_dvt.rxv.rx_mode); + } + if (rate != automation_dvt.rxv.rx_rate) { + automation_dvt.rxv.rxv_test_result = FALSE; + DBGLOG(RX, ERROR, "[%s]Receive TxRate=%d, Check RxRate=%d\n", + __func__, rate, automation_dvt.rxv.rx_rate); + } + if (frmode != automation_dvt.rxv.rx_bw) { + automation_dvt.rxv.rxv_test_result = FALSE; + DBGLOG(RX, ERROR, "[%s]Receive BW=%d, Check BW=%d\n", + __func__, frmode, automation_dvt.rxv.rx_bw); + } + if (sgi != automation_dvt.rxv.rx_sgi) { + automation_dvt.rxv.rxv_test_result = FALSE; + DBGLOG(RX, ERROR, "[%s]Receive Sgi=%d, Check Sgi=%d\n", + __func__, sgi, automation_dvt.rxv.rx_sgi); + } + if (stbc != automation_dvt.rxv.rx_stbc) { + automation_dvt.rxv.rxv_test_result = FALSE; + DBGLOG(RX, ERROR, "[%s]Receive Stbc=%d, Check Stbc=%d\n", + __func__, stbc, automation_dvt.rxv.rx_stbc); + } + if (ldpc != automation_dvt.rxv.rx_ldpc) { + automation_dvt.rxv.rxv_test_result = FALSE; + DBGLOG(RX, ERROR, "[%s]Receive Ldpc=%d, Check Ldpc=%d\n", + __func__, ldpc, automation_dvt.rxv.rx_ldpc); + } + + DBGLOG(RX, INFO, + "\n================ RXV Automation end ================\n"); +} +#endif + +#if CFG_TCP_IP_CHKSUM_OFFLOAD +/* +* This routine is used to test CSO function. +* Set 0xffff at checksum filed when cso_ctrl is enabled(15 for all TX case) +* Checksum should be recalculated by HW CSO function. +* step1. iwpriv cmd with CSO_TEST=15 (set CRC of tx packet to 0xffff) +* step2. run TX traffic +* step3. Passed if throughput is normal +*/ +int priv_driver_cso_test( + IN struct net_device *prNetDev, + IN char *pcCommand, + IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int32_t i4Recv = 0; + uint8_t ucCsoCtrl = 0; + int8_t *this_char = NULL; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX]; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **)netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + this_char = kalStrStr(*apcArgv, "="); + if (!this_char) + return -1; + this_char++; + + DBGLOG(REQ, LOUD, "string = %s\n", this_char); + + i4Recv = kalkStrtou8(this_char, 0, &(ucCsoCtrl)); + DBGLOG(RX, LOUD, "cso_ctrl = %u\n", ucCsoCtrl); + + if (!AutomationInit(prAdapter, CSO)) { + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "AutomationInit Fail!\n"); + return i4BytesWritten; + } + + /* CSO_TEST=15 for all TX test case */ + /* CSO_TX_IPV4 = BIT(0), */ + /* CSO_TX_IPV6 = BIT(1), */ + /* CSO_TX_TCP = BIT(2), */ + /* CSO_TX_UDP = BIT(3), */ + automation_dvt.cso_ctrl = ucCsoCtrl; + + return i4BytesWritten; +} +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ + +/* +* This routine is used to test HW feature +* Set a value to allow how many packets be transmitting +*/ +int priv_driver_set_tx_test( + IN struct net_device *prNetDev, IN char *pcCommand, + IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX]; + uint32_t u4Ret, u4Parse; + struct ADAPTER *prAdapter = NULL; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **)netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + if (i4Argc == 2) { + u4Ret = kalkStrtou32(apcArgv[1], 0, &u4Parse); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse apcArgv error u4Ret=%d\n", + u4Ret); + + prAdapter->u2TxTest = (uint16_t) u4Parse; + DBGLOG(REQ, LOUD, "prAdapter->u2TxTest = %d\n", + prAdapter->u2TxTest); + } else { + DBGLOG(REQ, ERROR, "iwpriv wlanXX driver TX_TEST xxxx\n"); + } + + prAdapter->u2TxTestCount = 0; + return i4BytesWritten; +} + +/* +* This routine is used to test HE Trigger Data +* Assign specific AC of Data to verify HW behavior when receive Trigger frame +*/ +int priv_driver_set_tx_test_ac( + IN struct net_device *prNetDev, IN char *pcCommand, + IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX]; + uint32_t u4Ret, u4Parse; + struct ADAPTER *prAdapter = NULL; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **)netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + if (i4Argc == 2) { + u4Ret = kalkStrtou32(apcArgv[1], 0, &u4Parse); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse apcArgv error u4Ret=%d\n", + u4Ret); + + prAdapter->ucTxTestUP = (uint8_t) u4Parse; + DBGLOG(REQ, LOUD, "prAdapter->ucTxTestUP = %d\n", + prAdapter->ucTxTestUP); + } else { + DBGLOG(REQ, ERROR, "iwpriv wlanXX driver TX_TEST_AC xx\n"); + } + + return i4BytesWritten; +} + +/* +* This routine is used to skip legal channel sanity check. +* During FPGA stage, could get wrong frequency information +* from RXD. Ignore this error +*/ +int priv_driver_skip_legal_ch_check( + IN struct net_device *prNetDev, + IN char *pcCommand, + IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int32_t i4Recv = 0; + uint32_t u4Enable = 0; + int8_t *this_char = NULL; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX]; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **)netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + this_char = kalStrStr(*apcArgv, "="); + if (!this_char) + return -1; + this_char++; + + DBGLOG(REQ, LOUD, "string = %s\n", this_char); + + i4Recv = kalkStrtos32(this_char, 0, &(u4Enable)); + DBGLOG(RX, LOUD, "skip_legal_ch_enable = %d\n", u4Enable); + + if (!AutomationInit(prAdapter, SKIP_CH)) { + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "AutomationInit Fail!\n"); + return i4BytesWritten; + } + + automation_dvt.skip_legal_ch_enable = u4Enable; + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "skip_legal_ch_enable = %d\n", u4Enable); + return i4BytesWritten; +} + +#endif /* CFG_SUPPORT_WIFI_SYSDVT */ + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/dvt/dvt_dmashdl.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/dvt/dvt_dmashdl.c new file mode 100644 index 0000000000000000000000000000000000000000..f04e83d7e6d7162f9846257029da53f485cd0371 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/dvt/dvt_dmashdl.c @@ -0,0 +1,1133 @@ +/* + *************************************************************************** + * Ralink Tech Inc. + * 4F, No. 2 Technology 5th Rd. + * Science-based Industrial Park + * Hsin-chu, Taiwan, R.O.C. + * + * (c) Copyright 2002, Ralink Technology, Inc. + * + * All rights reserved. Ralink's source code is an unpublished work and the + * use of a copyright notice does not imply otherwise. This source code + * contains confidential trade secret material of Ralink Tech. Any attemp + * or participation in deciphering, decoding, reverse engineering or in any + * way altering the source code is stricitly prohibited, unless the prior + * written consent of Ralink Technology, Inc. is obtained. + *************************************************************************** + + Module Name: + dvt_dmashdl.c + + Abstract: + For DMA sheduler DVT. + Please refer to DVT plan of DMA SCHEDULER for details + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Kai 2019/01/28 develop this for MT7915 USB(WA) +*/ +#include "precomp.h" + +#if (CFG_SUPPORT_DMASHDL_SYSDVT) +/* +* This routine is used to test return page rule +*/ +void dmashdl_dvt_item_6( + struct GLUE_INFO *prGlueInfo, + struct DMASHDL_DVT_CMD_T *tDvtCmd) +{ + uint32_t value; + struct ADAPTER *prAdapter = NULL; +#if (CFG_SUPPORT_CONNAC2X == 1) + struct mt66xx_chip_info *prChipInfo; +#endif + prAdapter = prGlueInfo->prAdapter; + + if (tDvtCmd->ucSubItemNo == DMASHDL_DVT_SUBITEM_1) { + if (!AutomationInit(prAdapter, DMASHDL)) + return; + + /* reset all setting and count */ + HIF_RESET_SW_LOGIC(prGlueInfo); + + /* mapping all queue to Group 0~4 */ + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_ADDR, + 0x44443210); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_ADDR, + 0x44444444); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_ADDR, + 0x44444444); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_ADDR, + 0x44444444); + + /* set quota, max quota 0x4, min quota 0x2*/ + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_ADDR, + 0x00040002); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_GROUP1_CONTROL_ADDR, + 0x00040002); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_GROUP2_CONTROL_ADDR, + 0x00040002); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_GROUP3_CONTROL_ADDR, + 0x00040002); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_GROUP4_CONTROL_ADDR, + 0x00040002); + + /* enable refill */ + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR, + 0xffe00000); + + /* maximux page */ + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_ADDR, + 0x10); + + /* enable WA CPU mode */ + kalDevRegRead(prGlueInfo, + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR, + &value); + value = value | + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_WACPU_MODE_EN_MASK; + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR, + value); + +#if (CFG_SUPPORT_CONNAC2X == 1) + /* inform WACPU test item */ + prChipInfo = prAdapter->chip_info; + if (prChipInfo->is_support_wacpu) + CmdExtDmaShdlDvt2WA(prAdapter, + tDvtCmd->ucItemNo, + tDvtCmd->ucSubItemNo); +#endif /* CFG_SUPPORT_CONNAC2X */ + + /* Step 1. init RSV & SRC */ + HIF_ADD_RSV_CNT(prGlueInfo, 0, 0x2); + HIF_ADD_SRC_CNT(prGlueInfo, 0, 0x3); + HIF_ADD_SRC_CNT(prGlueInfo, 1, 0x4); + HIF_ADD_RSV_CNT(prGlueInfo, 2, 0x1); + HIF_ADD_SRC_CNT(prGlueInfo, 2, 0x2); + HIF_ADD_SRC_CNT(prGlueInfo, 3, 0x2); + HIF_ADD_SRC_CNT(prGlueInfo, 4, 0x2); + HIF_CPU_RTN_CNT(prGlueInfo, 4, 0x2); + + DMASHDL_DVT_SET_ITEM(prAdapter, DMASHDL_DVT_ITEM_6); + } else if (tDvtCmd->ucSubItemNo == DMASHDL_DVT_SUBITEM_2) { + /* step 2. return 3 free pages to Group 0 */ + HIF_SUB_SRC_CNT(prGlueInfo, 0, 0x3); + HIF_ADD_RSV_CNT(prGlueInfo, 0, 0x3); + } +} + +/* +* This routine is used to test FFA refill +*/ +void dmashdl_dvt_item_5( + struct GLUE_INFO *prGlueInfo, + struct DMASHDL_DVT_CMD_T *tDvtCmd) +{ + uint32_t value; + struct ADAPTER *prAdapter = NULL; +#if (CFG_SUPPORT_CONNAC2X == 1) + struct mt66xx_chip_info *prChipInfo; +#endif + prAdapter = prGlueInfo->prAdapter; + + if (!AutomationInit(prAdapter, DMASHDL)) + return; + + /* reset all setting and count */ + HIF_RESET_SW_LOGIC(prGlueInfo); + + /* mapping all queue to Group 0~4 */ + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_ADDR, + 0x44443210); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_ADDR, + 0x44444444); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_ADDR, + 0x44444444); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_ADDR, + 0x44444444); + + if (tDvtCmd->ucSubItemNo == DMASHDL_DVT_SUBITEM_2) { + /* set quota, min quota 0x5 for Group 0 & 1 */ + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_ADDR, + 0x0fff0005); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_GROUP1_CONTROL_ADDR, + 0x0fff0005); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_GROUP2_CONTROL_ADDR, + 0x0fff0001); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_GROUP3_CONTROL_ADDR, + 0x0fff0002); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_GROUP4_CONTROL_ADDR, + 0x0fff0001); + } else { + /* set quota, min quota 0x5 for Group1*/ + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_ADDR, + 0x0fff0001); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_GROUP1_CONTROL_ADDR, + 0x0fff0005); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_GROUP2_CONTROL_ADDR, + 0x0fff0001); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_GROUP3_CONTROL_ADDR, + 0x0fff0001); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_GROUP4_CONTROL_ADDR, + 0x0fff0001); + } + + /* enable refill */ + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR, + 0xffe00000); + + /* maximux page */ + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_ADDR, + 0x10); + + /* enable WA CPU mode */ + kalDevRegRead(prGlueInfo, + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR, + &value); + value = value | + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_WACPU_MODE_EN_MASK; + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR, + value); + +#if (CFG_SUPPORT_CONNAC2X == 1) + /* inform WACPU test item */ + prChipInfo = prAdapter->chip_info; + if (prChipInfo->is_support_wacpu) + CmdExtDmaShdlDvt2WA(prAdapter, + tDvtCmd->ucItemNo, + tDvtCmd->ucSubItemNo); +#endif /* CFG_SUPPORT_CONNAC2X */ + + /* init quota */ + HIF_ADD_RSV_CNT(prGlueInfo, 0, 0x13); + + /* maximux page, start to move packet */ + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_ADDR, + 0x1); + + DMASHDL_DVT_RESET(prAdapter); + DMASHDL_DVT_SET_SUBITEM(prAdapter, tDvtCmd->ucSubItemNo); + DMASHDL_DVT_SET_ITEM(prAdapter, DMASHDL_DVT_ITEM_5); + + /* start to send ping packets to each group */ +} + +/* +* This routine is used to test slot priority +*/ +void dmashdl_dvt_item_4( + struct GLUE_INFO *prGlueInfo, + struct DMASHDL_DVT_CMD_T *tDvtCmd) +{ + uint32_t value; + struct ADAPTER *prAdapter = NULL; +#if (CFG_SUPPORT_CONNAC2X == 1) + struct mt66xx_chip_info *prChipInfo; +#endif + prAdapter = prGlueInfo->prAdapter; + + if (tDvtCmd->ucSubItemNo == DMASHDL_DVT_SUBITEM_1) { + if (!AutomationInit(prAdapter, DMASHDL)) + return; + + /* reset all setting and count */ + HIF_RESET_SW_LOGIC(prGlueInfo); + + /* mapping all queue to Group 0~4 */ + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_ADDR, + 0x44443210); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_ADDR, + 0x44444444); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_ADDR, + 0x44444444); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_ADDR, + 0x44444444); + + /* set quota, max quota 0x8, min quota 0x2*/ + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_ADDR, + 0x0fff0001); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_GROUP1_CONTROL_ADDR, + 0x0fff0001); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_GROUP2_CONTROL_ADDR, + 0x0fff0001); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_GROUP3_CONTROL_ADDR, + 0x0fff0001); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_GROUP4_CONTROL_ADDR, + 0x0fff0001); + + /* enable refill */ + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR, + 0xffe00000); + + /* disable joint ASK RR */ + kalDevRegRead(prGlueInfo, + WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_ADDR, + &value); + value = (value & +~WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_CR_HIF_GUP_ACT_MAP_MASK); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_ADDR, + value); + + /* disable SRC_CNT_PRI_EN & */ + /* pre-define each slot group strict order(enable as default) */ + kalDevRegRead(prGlueInfo, + WF_HIF_DMASHDL_TOP_PAGE_SETTING_ADDR, + &value); + value = (value & +~WF_HIF_DMASHDL_TOP_PAGE_SETTING_SRC_CNT_PRI_EN_MASK) | +WF_HIF_DMASHDL_TOP_PAGE_SETTING_GROUP_SEQUENCE_ORDER_TYPE_MASK; + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_PAGE_SETTING_ADDR, + value); + + /* maximux page */ + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_ADDR, + 0x10); + + /* enable WA CPU mode */ + kalDevRegRead(prGlueInfo, + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR, + &value); + value = value | +WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_WACPU_MODE_EN_MASK; + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR, + value); + +#if (CFG_SUPPORT_CONNAC2X == 1) + /* inform WACPU test item */ + prChipInfo = prAdapter->chip_info; + if (prChipInfo->is_support_wacpu) + CmdExtDmaShdlDvt2WA(prAdapter, + tDvtCmd->ucItemNo, + tDvtCmd->ucSubItemNo); +#endif /* CFG_SUPPORT_CONNAC2X */ + + /* init quota */ + HIF_ADD_RSV_CNT(prGlueInfo, 0, 0x13); + + DMASHDL_DVT_RESET(prAdapter); + DMASHDL_DVT_SET_ITEM(prAdapter, DMASHDL_DVT_ITEM_4); + + /* start to send ping packets to each group */ + } else if (tDvtCmd->ucSubItemNo == DMASHDL_DVT_SUBITEM_2) { + /* maximux page, start to move packet */ + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_ADDR, + 0x1); + } +} + +/* +* This routine is used to test group priority +*/ +void dmashdl_dvt_item_3( + struct GLUE_INFO *prGlueInfo, + struct DMASHDL_DVT_CMD_T *tDvtCmd) +{ + uint32_t value; + struct ADAPTER *prAdapter = NULL; +#if (CFG_SUPPORT_CONNAC2X == 1) + struct mt66xx_chip_info *prChipInfo; +#endif + prAdapter = prGlueInfo->prAdapter; + + if (tDvtCmd->ucSubItemNo == DMASHDL_DVT_SUBITEM_1) { + if (!AutomationInit(prAdapter, DMASHDL)) + return; + + /* reset all setting and count */ + HIF_RESET_SW_LOGIC(prGlueInfo); + + /* mapping all queue to Group 0~4 */ + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_ADDR, + 0x44443210); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_ADDR, + 0x44444444); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_ADDR, + 0x44444444); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_ADDR, + 0x44444444); + + /* set quota, max quota 0x8, min quota 0x2*/ + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_ADDR, + 0x0fff0001); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_GROUP1_CONTROL_ADDR, + 0x0fff0001); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_GROUP2_CONTROL_ADDR, + 0x0fff0001); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_GROUP3_CONTROL_ADDR, + 0x0fff0001); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_GROUP4_CONTROL_ADDR, + 0x0fff0001); + + /* enable refill */ + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR, + 0xffe00000); + + /* disable joint ASK RR */ + kalDevRegRead(prGlueInfo, + WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_ADDR, + &value); + value = value & +~WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_CR_HIF_GUP_ACT_MAP_MASK; + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_ADDR, + value); + +/* disable SRC_CNT_PRI_EN & user program group sequence order type */ + kalDevRegRead(prGlueInfo, + WF_HIF_DMASHDL_TOP_PAGE_SETTING_ADDR, + &value); + value = value & +~WF_HIF_DMASHDL_TOP_PAGE_SETTING_SRC_CNT_PRI_EN_MASK & +~WF_HIF_DMASHDL_TOP_PAGE_SETTING_GROUP_SEQUENCE_ORDER_TYPE_MASK; + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_PAGE_SETTING_ADDR, + value); + + /* group priority */ + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_ADDR, + 0x76540123); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_ADDR, + 0xfedcba98); + + /* maximux page */ + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_ADDR, + 0x10); + + /* enable WA CPU mode */ + kalDevRegRead(prGlueInfo, + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR, + &value); + value = value | + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_WACPU_MODE_EN_MASK; + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR, + value); + +#if (CFG_SUPPORT_CONNAC2X == 1) + /* inform WACPU test item */ + prChipInfo = prAdapter->chip_info; + if (prChipInfo->is_support_wacpu) + CmdExtDmaShdlDvt2WA(prAdapter, + tDvtCmd->ucItemNo, + tDvtCmd->ucSubItemNo); +#endif /* CFG_SUPPORT_CONNAC2X */ + + /* init quota */ + HIF_ADD_RSV_CNT(prGlueInfo, 0, 0x13); + + DMASHDL_DVT_RESET(prAdapter); + DMASHDL_DVT_SET_ITEM(prAdapter, DMASHDL_DVT_ITEM_3); + + /* start to send ping packets to each group */ + } else if (tDvtCmd->ucSubItemNo == DMASHDL_DVT_SUBITEM_2) { + /* maximux page, start to move packet */ + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_ADDR, + 0x1); + } +} + +/* +* This routine is used to run stress test +*/ +void dmashdl_dvt_item_2( + struct GLUE_INFO *prGlueInfo, + struct DMASHDL_DVT_CMD_T *tDvtCmd) +{ + uint32_t value; +#if (CFG_SUPPORT_CONNAC2X == 1) + struct mt66xx_chip_info *prChipInfo; +#endif + struct ADAPTER *prAdapter = prGlueInfo->prAdapter; + + if (!AutomationInit(prAdapter, DMASHDL)) + return; + + /* reset all setting and count */ + HIF_RESET_SW_LOGIC(prGlueInfo); + + /* mapping all queue to Group 0~4 */ + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_ADDR, + 0x21043210); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_ADDR, + 0x04321043); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_ADDR, + 0x32104321); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_ADDR, + 0x10432104); + + /* set quota, max quota 0x8, min quota 0x2*/ + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_ADDR, + 0x00080002); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_GROUP1_CONTROL_ADDR, + 0x00080002); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_GROUP2_CONTROL_ADDR, + 0x00080002); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_GROUP3_CONTROL_ADDR, + 0x00080002); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_GROUP4_CONTROL_ADDR, + 0x00080002); + + /* enable refill */ + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR, + 0xffe00000); + + /* maximux page */ + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_ADDR, + 0x10); + + /* enable WA CPU mode */ + kalDevRegRead(prGlueInfo, + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR, + &value); + value = value | + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_WACPU_MODE_EN_MASK; + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR, + value); + +#if (CFG_SUPPORT_CONNAC2X == 1) + /* inform WACPU test item */ + prChipInfo = prAdapter->chip_info; + if (prChipInfo->is_support_wacpu) + CmdExtDmaShdlDvt2WA(prAdapter, + tDvtCmd->ucItemNo, + tDvtCmd->ucSubItemNo); +#endif /* CFG_SUPPORT_CONNAC2X */ + + /* init quota */ + HIF_ADD_RSV_CNT(prGlueInfo, 0, 0x13); + + /* maximux page, start to move packet */ + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_ADDR, + 0x1); + + DMASHDL_DVT_RESET(prAdapter); + DMASHDL_DVT_SET_ITEM(prAdapter, DMASHDL_DVT_ITEM_2); + + /* start to send ping packets to each group */ +} + +/* +* This routine is used to test flow_control for Group 0 ~ 4 +*/ +void dmashdl_dvt_item_1( + struct GLUE_INFO *prGlueInfo, + struct DMASHDL_DVT_CMD_T *tDvtCmd) +{ + uint32_t value; + struct ADAPTER *prAdapter = NULL; +#if (CFG_SUPPORT_CONNAC2X == 1) + struct mt66xx_chip_info *prChipInfo; +#endif + prAdapter = prGlueInfo->prAdapter; + + if (!AutomationInit(prAdapter, DMASHDL)) + return; + + /* reset all setting and count */ + HIF_RESET_SW_LOGIC(prGlueInfo); + + /* mapping all queue to Group 0~4 */ + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_ADDR, + 0x21043210); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_ADDR, + 0x04321043); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_ADDR, + 0x32104321); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_ADDR, + 0x10432104); + + /* set quota, max quota 0xfff, min quota 0x4*/ + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_ADDR, + 0x0fff0004); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_GROUP1_CONTROL_ADDR, + 0x0fff0004); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_GROUP2_CONTROL_ADDR, + 0x0fff0004); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_GROUP3_CONTROL_ADDR, + 0x0fff0004); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_GROUP4_CONTROL_ADDR, + 0x0fff0004); + + /* disable refill */ + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR, + 0x0); + + /* maximux page */ + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_ADDR, + 0x10); + + /* enable WA CPU mode */ + kalDevRegRead(prGlueInfo, + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR, + &value); + value = value | + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_WACPU_MODE_EN_MASK; + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR, + value); + + /* tell WA CPU don't return pages */ +#if (CFG_SUPPORT_CONNAC2X == 1) + /* inform WACPU test item */ + prChipInfo = prAdapter->chip_info; + if (prChipInfo->is_support_wacpu) + CmdExtDmaShdlDvt2WA(prAdapter, + tDvtCmd->ucItemNo, + tDvtCmd->ucSubItemNo); +#endif /* CFG_SUPPORT_CONNAC2X */ + + /* init quota */ + HIF_ADD_RSV_CNT(prGlueInfo, 0, 0x4); + HIF_ADD_RSV_CNT(prGlueInfo, 1, 0x4); + HIF_ADD_RSV_CNT(prGlueInfo, 2, 0x4); + HIF_ADD_RSV_CNT(prGlueInfo, 3, 0x4); + HIF_ADD_RSV_CNT(prGlueInfo, 4, 0x4); + + /* maximux page, start to move packet */ + /* SubItem 1 set max page=1, SubItem 2 set max page=2 */ + if (tDvtCmd->ucSubItemNo == DMASHDL_DVT_SUBITEM_2) + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_ADDR, 0x2); + else + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_ADDR, 0x1); + + DMASHDL_DVT_RESET(prAdapter); + DMASHDL_DVT_SET_SUBITEM(prAdapter, tDvtCmd->ucSubItemNo); + DMASHDL_DVT_SET_ITEM(prAdapter, DMASHDL_DVT_ITEM_1); + /* start to send ping packets to each group */ + +} + +/* +* This routine is reset DMASHDL setting +*/ +void dmashdl_dvt_reset_default( + struct GLUE_INFO *prGlueInfo) +{ + uint32_t value; + + /* reset all setting and count */ + HIF_RESET_SW_LOGIC(prGlueInfo); + + /* mapping all queue to Group 0~4 */ + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_ADDR, + 0x44443210); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_ADDR, + 0x44444444); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_ADDR, + 0x44444444); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_ADDR, + 0x44444444); + + /* set quota, max quota 0xfff, min quota 0x1*/ + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_ADDR, + 0x0fff0001); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_GROUP1_CONTROL_ADDR, + 0x0fff0001); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_GROUP2_CONTROL_ADDR, + 0x0fff0001); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_GROUP3_CONTROL_ADDR, + 0x0fff0001); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_GROUP4_CONTROL_ADDR, + 0x0fff0001); + + /* enable refill */ + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR, + 0xffe00000); + + /* group priority */ + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_ADDR, + 0x76540123); + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_ADDR, + 0xfedcba98); + + /* maximux page */ + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_ADDR, + 0x1); + + /* As default */ + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_PAGE_SETTING_ADDR, + 0x3f1000); + + /* enable WA CPU mode */ + kalDevRegRead(prGlueInfo, + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR, + &value); + value = value | + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_WACPU_MODE_EN_MASK; + kalDevRegWrite(prGlueInfo, + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR, + value); + + /* init quota */ + HIF_ADD_RSV_CNT(prGlueInfo, 0, 0x13); +} + +/* +* This routine is used to check result. +*/ +int dmashdl_dvt_check_pass( + struct GLUE_INFO *prGlueInfo) +{ + uint32_t addr, free, status[16]; + uint32_t rsvcnt, rsvcnt2, srccnt, freecnt, ffacnt; + uint8_t ucItemNo, ucSubItemNo; + uint8_t i = 0; + uint8_t result = 1; + struct ADAPTER *pAd = NULL; + + pAd = prGlueInfo->prAdapter; + + /* get DVT item */ + ucItemNo = DMASHDL_DVT_GET_ITEM(pAd); + ucSubItemNo = DMASHDL_DVT_GET_SUBITEM(pAd); + + /* get free page & FFA page */ + kalDevRegRead(prGlueInfo, WF_HIF_DMASHDL_TOP_STATUS_RD_ADDR, &free); + + /* fetch status of group0 ~ 15 to array */ + for (i = 0; i < ARRAY_SIZE(status); i++) { + addr = WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_ADDR + i*4; + kalDevRegRead(prGlueInfo, addr, &status[i]); + } + + /* check different CR for different DVT item */ + switch (ucItemNo) { + case DMASHDL_DVT_ITEM_1: + for (i = 0; i < 5; i++) { + rsvcnt = (status[i] & + WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_G0_RSV_CNT_MASK) >> + WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_G0_RSV_CNT_SHFT; + srccnt = (status[i] & + WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_G0_SRC_CNT_MASK) >> + WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_G0_SRC_CNT_SHFT; + + /* Item 1-1 */ + /* check Group0~5 RSV count == 0 && SRC count == 4 */ + if (ucSubItemNo == DMASHDL_DVT_SUBITEM_1) { + if (rsvcnt != 0 || srccnt != 4) { + result = 0; + break; + } + } else if (ucSubItemNo == DMASHDL_DVT_SUBITEM_2) { + /* Item 1-2 */ + /* check Group0~5 rsv_cnt == 1 && src_cnt == 3 */ + if (rsvcnt != 1 || srccnt != 3) { + result = 0; + break; + } + } + } + + break; + case DMASHDL_DVT_ITEM_2: + /* DVT Item 2 */ + /* check Group1(BE) RSV count == 2 & SRC count == 0 */ + /* check Free page == 0x13) & FFA == 0x9 */ + rsvcnt = (status[1] & + WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_G0_RSV_CNT_MASK) >> + WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_G0_RSV_CNT_SHFT; + srccnt = (status[1] & + WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_G0_SRC_CNT_MASK) >> + WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_G0_SRC_CNT_SHFT; + freecnt = (free & + WF_HIF_DMASHDL_TOP_STATUS_RD_FREE_PAGE_CNT_MASK) >> + WF_HIF_DMASHDL_TOP_STATUS_RD_FREE_PAGE_CNT_SHFT; + ffacnt = (free & + WF_HIF_DMASHDL_TOP_STATUS_RD_FFA_CNT_MASK) >> + WF_HIF_DMASHDL_TOP_STATUS_RD_FFA_CNT_SHFT; + if (rsvcnt != 2 || srccnt != 0 || + freecnt != 0x13 || ffacnt != 0x9) + result = 0; + + break; + case DMASHDL_DVT_ITEM_3: + DBGLOG(REQ, INFO, + "Check packet's queue id in sequence on WA\n"); + break; + case DMASHDL_DVT_ITEM_4: + DBGLOG(REQ, INFO, + "Check packet's queue id in sequence on WA\n"); + break; + case DMASHDL_DVT_ITEM_5: + /* Item 5-1 */ + /* check Group1 rsv_cnt == 5, src_cnt == 5 */ + if (ucSubItemNo == DMASHDL_DVT_SUBITEM_1) { + rsvcnt = (status[1] & + WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_G0_RSV_CNT_MASK) >> + WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_G0_RSV_CNT_SHFT; + srccnt = (status[1] & + WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_G0_SRC_CNT_MASK) >> + WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_G0_SRC_CNT_SHFT; + + if (rsvcnt != 5 || srccnt != 5) + result = 0; + } else if (ucSubItemNo == DMASHDL_DVT_SUBITEM_2) { + /* Item 5-2 */ + /* check Group0 rsv_cnt > Group1 rsv_cnt */ + rsvcnt = (status[0] & + WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_G0_RSV_CNT_MASK) >> + WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_G0_RSV_CNT_SHFT; + rsvcnt2 = (status[1] & + WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_G0_RSV_CNT_MASK) >> + WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_G0_RSV_CNT_SHFT; + + if (rsvcnt < rsvcnt2) { + /* failed when Group0's rescnt is less than Group1's */ + result = 0; + } + } + + break; + case DMASHDL_DVT_ITEM_6: + /* check Group0 ~ Group4 */ + /* group 0: rsv_cnt == 2, src_cnt == 0 */ + /* group 1: rsv_cnt == 0, src_cnt == 4 */ + /* group 2: rsv_cnt == 2, src_cnt == 2 */ + /* group 3: rsv_cnt == 2, src_cnt == 2 */ + /* group 4: rsv_cnt == 2, src_cnt == 0 */ + for (i = 0; i < 5; i++) { + rsvcnt = (status[i] & + WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_G0_RSV_CNT_MASK) >> + WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_G0_RSV_CNT_SHFT; + srccnt = (status[i] & + WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_G0_SRC_CNT_MASK) >> + WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_G0_SRC_CNT_SHFT; + + if (i == 0) { + if (rsvcnt != 2 || srccnt != 0) { + result = 0; + break; + } + } else if (i == 1) { + if (rsvcnt != 0 || srccnt != 4) { + result = 0; + break; + } + } else if (i == 2) { + if (rsvcnt != 2 || srccnt != 2) { + result = 0; + break; + } + } else if (i == 3) { + if (rsvcnt != 2 || srccnt != 2) { + result = 0; + break; + } + } else if (i == 4) { + if (rsvcnt != 2 || srccnt != 0) { + result = 0; + break; + } + } + } + + break; + default: + DBGLOG(REQ, INFO, "[DMASHDL] no support this test item\n"); + } + + return result; +} + +/* +* This routine is used to end of DMASHDL DVT and check result. +* iwpriv wlan0 driver "DMASHDL_DVT_ITEM 0" +* echo "DVT PASS" if result is passed +*/ +int dmashdl_dvt_result( + IN struct net_device *prNetDev, + IN char *pcCommand, + IN int i4TotalLen, + struct DMASHDL_DVT_CMD_T *tDvtCmd) +{ + struct ADAPTER *prAdapter = NULL; +#if (CFG_SUPPORT_CONNAC2X == 1) + struct mt66xx_chip_info *prChipInfo; +#endif + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4BytesWritten = 0; + int32_t idx = 0; + uint8_t dvt_item; + uint8_t *dvt_ping_nums; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **)netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + if (dmashdl_dvt_check_pass(prGlueInfo) == 1) + DBGLOG(REQ, INFO, "DVT PASS\n"); + priv_driver_show_dmashdl_allcr(prNetDev, pcCommand, i4TotalLen); + +#if (CFG_SUPPORT_CONNAC2X == 1) + prChipInfo = prAdapter->chip_info; + /* inform WACPU, this is DVT case */ + if (prChipInfo->is_support_wacpu) + CmdExtDmaShdlDvt2WA(prAdapter, + tDvtCmd->ucItemNo, + tDvtCmd->ucSubItemNo); +#endif /* CFG_SUPPORT_CONNAC2X */ + + if (prAdapter->auto_dvt) { + dvt_item = prAdapter->auto_dvt->dmashdl.dvt_item; + if (dvt_item == DMASHDL_DVT_ITEM_1 + || dvt_item == DMASHDL_DVT_ITEM_2 + || dvt_item == DMASHDL_DVT_ITEM_3 + || dvt_item == DMASHDL_DVT_ITEM_4) { + dvt_ping_nums = + &(prAdapter->auto_dvt->dmashdl.dvt_ping_nums[0]); + for (idx = 0; idx < 32; idx++) + DBGLOG(REQ, INFO, + "Ping nums %u\n", dvt_ping_nums[idx]); + } + } + /* Reset DMASHDL DVT structure after result got */ + DMASHDL_DVT_RESET(prAdapter); + /* Reset DMASHDL setting to default */ + dmashdl_dvt_reset_default(prGlueInfo); + + return i4BytesWritten; +} + +int8_t cmd_atoi(uint8_t ch) +{ + if (ch >= 'a' && ch <= 'f') + return ch - 87; + else if (ch >= 'A' && ch <= 'F') + return ch - 55; + else if (ch >= '0' && ch <= '9') + return ch - 48; + + return 0; +} + +/* +* This routine is used to run DMASHDL DVT items. +* iwpriv wlan0 driver "DMASHDL_DVT_ITEM item subitem" +* For example, run item 1-2: +* iwpriv wlan0 driver "DMASHDL_DVT_ITEM 1 2" +* ping 10.10.10.1 -c 25 (Do some test) +* iwpriv wlan0 driver "DMASHDL_DVT_ITEM 0" +* PS. Item 0 is stop DVT and then check result +*/ +int priv_driver_dmashdl_dvt_item( + IN struct net_device *prNetDev, + IN char *pcCommand, + IN int i4TotalLen) +{ + struct ADAPTER *prAdapter = NULL; + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX]; + struct DMASHDL_DVT_CMD_T tDvtCmd; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **)netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + DBGLOG(REQ, INFO, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + tDvtCmd.ucItemNo = cmd_atoi(apcArgv[1][0]); + tDvtCmd.ucArgNo = i4Argc - 2; + if (tDvtCmd.ucArgNo) + tDvtCmd.ucSubItemNo = cmd_atoi(apcArgv[2][0]); + else + tDvtCmd.ucSubItemNo = 0; + + DBGLOG(REQ, INFO, "[Item Num]=%u\n", tDvtCmd.ucItemNo); + + switch (tDvtCmd.ucItemNo) { + case DMASHDL_DVT_RESULT: + dmashdl_dvt_result(prNetDev, pcCommand, i4TotalLen, &tDvtCmd); + break; + case DMASHDL_DVT_ITEM_1: + dmashdl_dvt_item_1(prGlueInfo, &tDvtCmd); + break; + case DMASHDL_DVT_ITEM_2: + dmashdl_dvt_item_2(prGlueInfo, &tDvtCmd); + break; + case DMASHDL_DVT_ITEM_3: + dmashdl_dvt_item_3(prGlueInfo, &tDvtCmd); + break; + case DMASHDL_DVT_ITEM_4: + dmashdl_dvt_item_4(prGlueInfo, &tDvtCmd); + break; + case DMASHDL_DVT_ITEM_5: + dmashdl_dvt_item_5(prGlueInfo, &tDvtCmd); + break; + case DMASHDL_DVT_ITEM_6: + dmashdl_dvt_item_6(prGlueInfo, &tDvtCmd); + break; + default: + DBGLOG(REQ, INFO, "[DMASHDL] no support this test item\n"); + } + return i4BytesWritten; +} + +/* +* This routine is used to dump related CRs about DMASHDL. +* iwpriv wlan0 driver "DMASHDL_DUMP_MEM" +*/ +int priv_driver_show_dmashdl_allcr( + IN struct net_device *prNetDev, + IN char *pcCommand, + IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t addr, value; + int32_t i4BytesWritten = 0; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **)netdev_priv(prNetDev)); + + for (addr = WF_HIF_DMASHDL_TOP_WACPU_REFILL_ADDR; + addr <= WF_HIF_DMASHDL_TOP_GROUP15_CONTROL_ADDR; + addr += 4) { + kalDevRegRead(prGlueInfo, addr, &value); + DBGLOG(REQ, INFO, + "[DMASHDL] Addr[0x%08X], value=0x%08X\n", addr, value); + } + + DBGLOG(REQ, INFO, "[DMASHDL] Queue Mapping\n"); + for (addr = WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_ADDR; + addr <= WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_ADDR; + addr += 4) { + kalDevRegRead(prGlueInfo, addr, &value); + DBGLOG(REQ, INFO, + "[DMASHDL] Addr[0x%08X], value=0x%08X\n", addr, value); + } + + kalDevRegRead(prGlueInfo, WF_HIF_DMASHDL_TOP_STATUS_RD_ADDR, &value); + DBGLOG(REQ, INFO, + "[DMASHDL] Status RD[0x%08X] value = 0x%08X\n", + WF_HIF_DMASHDL_TOP_STATUS_RD_ADDR, value); + DBGLOG(REQ, INFO, "[DMASHDL] Status RD GP\n"); + for (addr = WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_ADDR; + addr <= WF_HIF_DMASHDL_TOP_STATUS_RD_GP15_ADDR; + addr += 4) { + kalDevRegRead(prGlueInfo, addr, &value); + DBGLOG(REQ, INFO, + "[DMASHDL] Addr[0x%08X], value=0x%08X\n", addr, value); + } + DBGLOG(REQ, INFO, "[DMASHDL] Status RD GP PKT cnt\n"); + for (addr = WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT0_ADDR; + addr <= WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT7_ADDR; + addr += 4) { + kalDevRegRead(prGlueInfo, addr, &value); + DBGLOG(REQ, INFO, + "[DMASHDL] Addr[0x%08X], value=0x%08X\n", addr, value); + } + + return i4BytesWritten; +} +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/CFG_Wifi_File.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/CFG_Wifi_File.h new file mode 100644 index 0000000000000000000000000000000000000000..1407ec87924422ee3ef0d23f9403066deca2acbe --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/CFG_Wifi_File.h @@ -0,0 +1,595 @@ +/******************************************************************************* + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include + * /CFG_Wifi_File.h#1 + */ + +/*! \file CFG_Wifi_File.h + * \brief Collection of NVRAM structure used for YuSu project + * + * In this file we collect all compiler flags and detail the driver behavior + * if enable/disable such switch or adjust numeric parameters. + */ + +#ifndef _CFG_WIFI_FILE_H +#define _CFG_WIFI_FILE_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "gl_typedef.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ +/* Connac define */ +struct WIFI_NVRAM_2G4_TX_POWER_T { + uint8_t uc2G4TxPwrCck1M; + uint8_t uc2G4TxPwrCck2M; + uint8_t uc2G4TxPwrCck5M; + uint8_t uc2G4TxPwrCck11M; + uint8_t uc2G4TxPwrOfdm6M; + uint8_t uc2G4TxPwrOfdm9M; + uint8_t uc2G4TxPwrOfdm12M; + uint8_t uc2G4TxPwrOfdm18M; + uint8_t uc2G4TxPwrOfdm24M; + uint8_t uc2G4TxPwrOfdm36M; + uint8_t uc2G4TxPwrOfdm48M; + uint8_t uc2G4TxPwrOfdm54M; + uint8_t uc2G4TxPwrHt20Mcs0; + uint8_t uc2G4TxPwrHt20Mcs1; + uint8_t uc2G4TxPwrHt20Mcs2; + uint8_t uc2G4TxPwrHt20Mcs3; + uint8_t uc2G4TxPwrHt20Mcs4; + uint8_t uc2G4TxPwrHt20Mcs5; + uint8_t uc2G4TxPwrHt20Mcs6; + uint8_t uc2G4TxPwrHt20Mcs7; + uint8_t uc2G4TxPwrHt40Mcs0; + uint8_t uc2G4TxPwrHt40Mcs1; + uint8_t uc2G4TxPwrHt40Mcs2; + uint8_t uc2G4TxPwrHt40Mcs3; + uint8_t uc2G4TxPwrHt40Mcs4; + uint8_t uc2G4TxPwrHt40Mcs5; + uint8_t uc2G4TxPwrHt40Mcs6; + uint8_t uc2G4TxPwrHt40Mcs7; + uint8_t uc2G4TxPwrHt40Mcs32; + uint8_t uc2G4TxPwrVht20Mcs0; + uint8_t uc2G4TxPwrVht20Mcs1; + uint8_t uc2G4TxPwrVht20Mcs2; + uint8_t uc2G4TxPwrVht20Mcs3; + uint8_t uc2G4TxPwrVht20Mcs4; + uint8_t uc2G4TxPwrVht20Mcs5; + uint8_t uc2G4TxPwrVht20Mcs6; + uint8_t uc2G4TxPwrVht20Mcs7; + uint8_t uc2G4TxPwrVht20Mcs8; + uint8_t uc2G4TxPwrVht20Mcs9; + uint8_t uc2G4TxPwrVht40Mcs0; + uint8_t uc2G4TxPwrVht40Mcs1; + uint8_t uc2G4TxPwrVht40Mcs2; + uint8_t uc2G4TxPwrVht40Mcs3; + uint8_t uc2G4TxPwrVht40Mcs4; + uint8_t uc2G4TxPwrVht40Mcs5; + uint8_t uc2G4TxPwrVht40Mcs6; + uint8_t uc2G4TxPwrVht40Mcs7; + uint8_t uc2G4TxPwrVht40Mcs8; + uint8_t uc2G4TxPwrVht40Mcs9; + uint8_t uc2G4TxPwrRU26Mcs0; + uint8_t uc2G4TxPwrRU26Mcs1; + uint8_t uc2G4TxPwrRU26Mcs2; + uint8_t uc2G4TxPwrRU26Mcs3; + uint8_t uc2G4TxPwrRU26Mcs4; + uint8_t uc2G4TxPwrRU26Mcs5; + uint8_t uc2G4TxPwrRU26Mcs6; + uint8_t uc2G4TxPwrRU26Mcs7; + uint8_t uc2G4TxPwrRU26Mcs8; + uint8_t uc2G4TxPwrRU26Mcs9; + uint8_t uc2G4TxPwrRU26Mcs10; + uint8_t uc2G4TxPwrRU26Mcs11; + + uint8_t uc2G4TxPwrRU52Mcs0; + uint8_t uc2G4TxPwrRU52Mcs1; + uint8_t uc2G4TxPwrRU52Mcs2; + uint8_t uc2G4TxPwrRU52Mcs3; + uint8_t uc2G4TxPwrRU52Mcs4; + uint8_t uc2G4TxPwrRU52Mcs5; + uint8_t uc2G4TxPwrRU52Mcs6; + uint8_t uc2G4TxPwrRU52Mcs7; + uint8_t uc2G4TxPwrRU52Mcs8; + uint8_t uc2G4TxPwrRU52Mcs9; + uint8_t uc2G4TxPwrRU52Mcs10; + uint8_t uc2G4TxPwrRU52Mcs11; + + uint8_t uc2G4TxPwrRU106Mcs0; + uint8_t uc2G4TxPwrRU106Mcs1; + uint8_t uc2G4TxPwrRU106Mcs2; + uint8_t uc2G4TxPwrRU106Mcs3; + uint8_t uc2G4TxPwrRU106Mcs4; + uint8_t uc2G4TxPwrRU106Mcs5; + uint8_t uc2G4TxPwrRU106Mcs6; + uint8_t uc2G4TxPwrRU106Mcs7; + uint8_t uc2G4TxPwrRU106Mcs8; + uint8_t uc2G4TxPwrRU106Mcs9; + uint8_t uc2G4TxPwrRU106Mcs10; + uint8_t uc2G4TxPwrRU106Mcs11; + + uint8_t uc2G4TxPwrRU242Mcs0; + uint8_t uc2G4TxPwrRU242Mcs1; + uint8_t uc2G4TxPwrRU242Mcs2; + uint8_t uc2G4TxPwrRU242Mcs3; + uint8_t uc2G4TxPwrRU242Mcs4; + uint8_t uc2G4TxPwrRU242Mcs5; + uint8_t uc2G4TxPwrRU242Mcs6; + uint8_t uc2G4TxPwrRU242Mcs7; + uint8_t uc2G4TxPwrRU242Mcs8; + uint8_t uc2G4TxPwrRU242Mcs9; + uint8_t uc2G4TxPwrRU242Mcs10; + uint8_t uc2G4TxPwrRU242Mcs11; + + uint8_t uc2G4TxPwrRU484Mcs0; + uint8_t uc2G4TxPwrRU484Mcs1; + uint8_t uc2G4TxPwrRU484Mcs2; + uint8_t uc2G4TxPwrRU484Mcs3; + uint8_t uc2G4TxPwrRU484Mcs4; + uint8_t uc2G4TxPwrRU484Mcs5; + uint8_t uc2G4TxPwrRU484Mcs6; + uint8_t uc2G4TxPwrRU484Mcs7; + uint8_t uc2G4TxPwrRU484Mcs8; + uint8_t uc2G4TxPwrRU484Mcs9; + uint8_t uc2G4TxPwrRU484Mcs10; + uint8_t uc2G4TxPwrRU484Mcs11; + + uint8_t uc2G4TxPwrLGBW40DuplucateMode; + +}; + +struct WIFI_NVRAM_5G_TX_POWER_T { + uint8_t uc5GTxPwrOfdm6M; + uint8_t uc5GTxPwrOfdm9M; + uint8_t uc5GTxPwrOfdm12M; + uint8_t uc5GTxPwrOfdm18M; + uint8_t uc5GTxPwrOfdm24M; + uint8_t uc5GTxPwrOfdm36M; + uint8_t uc5GTxPwrOfdm48M; + uint8_t uc5GTxPwrOfdm54M; + uint8_t uc5GTxPwrHt20Mcs0; + uint8_t uc5GTxPwrHt20Mcs1; + uint8_t uc5GTxPwrHt20Mcs2; + uint8_t uc5GTxPwrHt20Mcs3; + uint8_t uc5GTxPwrHt20Mcs4; + uint8_t uc5GTxPwrHt20Mcs5; + uint8_t uc5GTxPwrHt20Mcs6; + uint8_t uc5GTxPwrHt20Mcs7; + uint8_t uc5GTxPwrHt40Mcs0; + uint8_t uc5GTxPwrHt40Mcs1; + uint8_t uc5GTxPwrHt40Mcs2; + uint8_t uc5GTxPwrHt40Mcs3; + uint8_t uc5GTxPwrHt40Mcs4; + uint8_t uc5GTxPwrHt40Mcs5; + uint8_t uc5GTxPwrHt40Mcs6; + uint8_t uc5GTxPwrHt40Mcs7; + uint8_t uc5GTxPwrHt40Mcs32; + + uint8_t uc5GTxPwrVht20Mcs0; + uint8_t uc5GTxPwrVht20Mcs1; + uint8_t uc5GTxPwrVht20Mcs2; + uint8_t uc5GTxPwrVht20Mcs3; + uint8_t uc5GTxPwrVht20Mcs4; + uint8_t uc5GTxPwrVht20Mcs5; + uint8_t uc5GTxPwrVht20Mcs6; + uint8_t uc5GTxPwrVht20Mcs7; + uint8_t uc5GTxPwrVht20Mcs8; + uint8_t uc5GTxPwrVht20Mcs9; + uint8_t uc5GTxPwrVht40Mcs0; + uint8_t uc5GTxPwrVht40Mcs1; + uint8_t uc5GTxPwrVht40Mcs2; + uint8_t uc5GTxPwrVht40Mcs3; + uint8_t uc5GTxPwrVht40Mcs4; + uint8_t uc5GTxPwrVht40Mcs5; + uint8_t uc5GTxPwrVht40Mcs6; + uint8_t uc5GTxPwrVht40Mcs7; + uint8_t uc5GTxPwrVht40Mcs8; + uint8_t uc5GTxPwrVht40Mcs9; + uint8_t uc5GTxPwrVht80Mcs0; + uint8_t uc5GTxPwrVht80Mcs1; + uint8_t uc5GTxPwrVht80Mcs2; + uint8_t uc5GTxPwrVht80Mcs3; + uint8_t uc5GTxPwrVht80Mcs4; + uint8_t uc5GTxPwrVht80Mcs5; + uint8_t uc5GTxPwrVht80Mcs6; + uint8_t uc5GTxPwrVht80Mcs7; + uint8_t uc5GTxPwrVht80Mcs8; + uint8_t uc5GTxPwrVht80Mcs9; + uint8_t uc5GTxPwrVht160Mcs0; + uint8_t uc5GTxPwrVht160Mcs1; + uint8_t uc5GTxPwrVht160Mcs2; + uint8_t uc5GTxPwrVht160Mcs3; + uint8_t uc5GTxPwrVht160Mcs4; + uint8_t uc5GTxPwrVht160Mcs5; + uint8_t uc5GTxPwrVht160Mcs6; + uint8_t uc5GTxPwrVht160Mcs7; + uint8_t uc5GTxPwrVht160Mcs8; + uint8_t uc5GTxPwrVht160Mcs9; + + uint8_t uc5GTxPwrRU26Mcs0; + uint8_t uc5GTxPwrRU26Mcs1; + uint8_t uc5GTxPwrRU26Mcs2; + uint8_t uc5GTxPwrRU26Mcs3; + uint8_t uc5GTxPwrRU26Mcs4; + uint8_t uc5GTxPwrRU26Mcs5; + uint8_t uc5GTxPwrRU26Mcs6; + uint8_t uc5GTxPwrRU26Mcs7; + uint8_t uc5GTxPwrRU26Mcs8; + uint8_t uc5GTxPwrRU26Mcs9; + uint8_t uc5GTxPwrRU26Mcs10; + uint8_t uc5GTxPwrRU26Mcs11; + + uint8_t uc5GTxPwrRU52Mcs0; + uint8_t uc5GTxPwrRU52Mcs1; + uint8_t uc5GTxPwrRU52Mcs2; + uint8_t uc5GTxPwrRU52Mcs3; + uint8_t uc5GTxPwrRU52Mcs4; + uint8_t uc5GTxPwrRU52Mcs5; + uint8_t uc5GTxPwrRU52Mcs6; + uint8_t uc5GTxPwrRU52Mcs7; + uint8_t uc5GTxPwrRU52Mcs8; + uint8_t uc5GTxPwrRU52Mcs9; + uint8_t uc5GTxPwrRU52Mcs10; + uint8_t uc5GTxPwrRU52Mcs11; + + uint8_t uc5GTxPwrRU106Mcs0; + uint8_t uc5GTxPwrRU106Mcs1; + uint8_t uc5GTxPwrRU106Mcs2; + uint8_t uc5GTxPwrRU106Mcs3; + uint8_t uc5GTxPwrRU106Mcs4; + uint8_t uc5GTxPwrRU106Mcs5; + uint8_t uc5GTxPwrRU106Mcs6; + uint8_t uc5GTxPwrRU106Mcs7; + uint8_t uc5GTxPwrRU106Mcs8; + uint8_t uc5GTxPwrRU106Mcs9; + uint8_t uc5GTxPwrRU106Mcs10; + uint8_t uc5GTxPwrRU106Mcs11; + + uint8_t uc5GTxPwrRU242Mcs0; + uint8_t uc5GTxPwrRU242Mcs1; + uint8_t uc5GTxPwrRU242Mcs2; + uint8_t uc5GTxPwrRU242Mcs3; + uint8_t uc5GTxPwrRU242Mcs4; + uint8_t uc5GTxPwrRU242Mcs5; + uint8_t uc5GTxPwrRU242Mcs6; + uint8_t uc5GTxPwrRU242Mcs7; + uint8_t uc5GTxPwrRU242Mcs8; + uint8_t uc5GTxPwrRU242Mcs9; + uint8_t uc5GTxPwrRU242Mcs10; + uint8_t uc5GTxPwrRU242Mcs11; + + uint8_t uc5GTxPwrRU484Mcs0; + uint8_t uc5GTxPwrRU484Mcs1; + uint8_t uc5GTxPwrRU484Mcs2; + uint8_t uc5GTxPwrRU484Mcs3; + uint8_t uc5GTxPwrRU484Mcs4; + uint8_t uc5GTxPwrRU484Mcs5; + uint8_t uc5GTxPwrRU484Mcs6; + uint8_t uc5GTxPwrRU484Mcs7; + uint8_t uc5GTxPwrRU484Mcs8; + uint8_t uc5GTxPwrRU484Mcs9; + uint8_t uc5GTxPwrRU484Mcs10; + uint8_t uc5GTxPwrRU484Mcs11; + + uint8_t uc5GTxPwrRU996Mcs0; + uint8_t uc5GTxPwrRU996Mcs1; + uint8_t uc5GTxPwrRU996Mcs2; + uint8_t uc5GTxPwrRU996Mcs3; + uint8_t uc5GTxPwrRU996Mcs4; + uint8_t uc5GTxPwrRU996Mcs5; + uint8_t uc5GTxPwrRU996Mcs6; + uint8_t uc5GTxPwrRU996Mcs7; + uint8_t uc5GTxPwrRU996Mcs8; + uint8_t uc5GTxPwrRU996Mcs9; + uint8_t uc5GTxPwrRU996Mcs10; + uint8_t uc5GTxPwrRU996Mcs11; + + uint8_t uc5GTxPwrLGBW40DuplucateMode; + uint8_t uc5GTxPwrLGBW80DuplucateMode; + uint8_t uc5GTxPwrLGBW1600DuplucateMode; + uint8_t uc5GBw5MTxPwrDelta; + uint8_t uc5GBw10MTxPwrDelta; +}; + +/* end Connac TX Power define */ + +/* duplicated from nic_cmd_event.h to avoid header dependency */ +struct TX_PWR_PARAM { + int8_t cTxPwr2G4Cck; /* signed, in unit of 0.5dBm */ + int8_t cTxPwr2G4Dsss; /* signed, in unit of 0.5dBm */ + int8_t acReserved[2]; + + int8_t cTxPwr2G4OFDM_BPSK; + int8_t cTxPwr2G4OFDM_QPSK; + int8_t cTxPwr2G4OFDM_16QAM; + int8_t cTxPwr2G4OFDM_Reserved; + int8_t cTxPwr2G4OFDM_48Mbps; + int8_t cTxPwr2G4OFDM_54Mbps; + + int8_t cTxPwr2G4HT20_BPSK; + int8_t cTxPwr2G4HT20_QPSK; + int8_t cTxPwr2G4HT20_16QAM; + int8_t cTxPwr2G4HT20_MCS5; + int8_t cTxPwr2G4HT20_MCS6; + int8_t cTxPwr2G4HT20_MCS7; + + int8_t cTxPwr2G4HT40_BPSK; + int8_t cTxPwr2G4HT40_QPSK; + int8_t cTxPwr2G4HT40_16QAM; + int8_t cTxPwr2G4HT40_MCS5; + int8_t cTxPwr2G4HT40_MCS6; + int8_t cTxPwr2G4HT40_MCS7; + + int8_t cTxPwr5GOFDM_BPSK; + int8_t cTxPwr5GOFDM_QPSK; + int8_t cTxPwr5GOFDM_16QAM; + int8_t cTxPwr5GOFDM_Reserved; + int8_t cTxPwr5GOFDM_48Mbps; + int8_t cTxPwr5GOFDM_54Mbps; + + int8_t cTxPwr5GHT20_BPSK; + int8_t cTxPwr5GHT20_QPSK; + int8_t cTxPwr5GHT20_16QAM; + int8_t cTxPwr5GHT20_MCS5; + int8_t cTxPwr5GHT20_MCS6; + int8_t cTxPwr5GHT20_MCS7; + + int8_t cTxPwr5GHT40_BPSK; + int8_t cTxPwr5GHT40_QPSK; + int8_t cTxPwr5GHT40_16QAM; + int8_t cTxPwr5GHT40_MCS5; + int8_t cTxPwr5GHT40_MCS6; + int8_t cTxPwr5GHT40_MCS7; +}; + +struct TX_AC_PWR { + int8_t c11AcTxPwr_BPSK; + int8_t c11AcTxPwr_QPSK; + int8_t c11AcTxPwr_16QAM; + int8_t c11AcTxPwr_MCS5_MCS6; + int8_t c11AcTxPwr_MCS7; + int8_t c11AcTxPwr_MCS8; + int8_t c11AcTxPwr_MCS9; + int8_t c11AcTxPwrVht40_OFFSET; + int8_t c11AcTxPwrVht80_OFFSET; + int8_t c11AcTxPwrVht160_OFFSET; + int8_t acReverse[2]; +}; + +struct RSSI_PATH_COMPASATION { + int8_t c2GRssiCompensation; + int8_t c5GRssiCompensation; +}; + +struct PWR_5G_OFFSET { + int8_t cOffsetBand0; /* 4.915-4.980G */ + int8_t cOffsetBand1; /* 5.000-5.080G */ + int8_t cOffsetBand2; /* 5.160-5.180G */ + int8_t cOffsetBand3; /* 5.200-5.280G */ + int8_t cOffsetBand4; /* 5.300-5.340G */ + int8_t cOffsetBand5; /* 5.500-5.580G */ + int8_t cOffsetBand6; /* 5.600-5.680G */ + int8_t cOffsetBand7; /* 5.700-5.825G */ +}; + +struct PWR_PARAM { + uint32_t au4Data[28]; + uint32_t u4RefValue1; + uint32_t u4RefValue2; +}; + +struct AC_PWR_SETTING_STRUCT { + uint8_t c11AcTxPwr_BPSK; + uint8_t c11AcTxPwr_QPSK; + uint8_t c11AcTxPwr_16QAM; + uint8_t c11AcTxPwr_MCS5_MCS6; + uint8_t c11AcTxPwr_MCS7; + uint8_t c11AcTxPwr_MCS8; + uint8_t c11AcTxPwr_MCS9; + uint8_t c11AcTxPwr_Reserved; + uint8_t c11AcTxPwrVht40_OFFSET; + uint8_t c11AcTxPwrVht80_OFFSET; + uint8_t c11AcTxPwrVht160_OFFSET; +}; + +struct BANDEDGE_5G { + uint8_t uc5GBandEdgePwrUsed; + uint8_t c5GBandEdgeMaxPwrOFDM20; + uint8_t c5GBandEdgeMaxPwrOFDM40; + uint8_t c5GBandEdgeMaxPwrOFDM80; + +}; + +struct NEW_EFUSE_MAPPING2NVRAM { + uint8_t ucReverse1[8]; + uint16_t u2Signature; + struct BANDEDGE_5G r5GBandEdgePwr; + uint8_t ucReverse2[14]; + + /* 0x50 */ + uint8_t aucChOffset[3]; + uint8_t ucChannelOffsetVaild; + uint8_t acAllChannelOffset; + uint8_t aucChOffset3[11]; + + /* 0x60 */ + uint8_t auc5GChOffset[8]; + uint8_t uc5GChannelOffsetVaild; + uint8_t aucChOffset4[7]; + + /* 0x70 */ + struct AC_PWR_SETTING_STRUCT r11AcTxPwr; + uint8_t uc11AcTxPwrValid; + + uint8_t ucReverse4[20]; + + /* 0x90 */ + struct AC_PWR_SETTING_STRUCT r11AcTxPwr2G; + uint8_t uc11AcTxPwrValid2G; + + uint8_t ucReverse5[40]; +}; + +struct WIFI_NVRAM_CONTROL_T { + uint8_t ucControl; /*0: disable, 1: enable*/ + uint8_t ucTotalSizeLSB; + uint8_t ucTotalSizeMSB; +}; + + +struct WIFI_CFG_PARAM_STRUCT { + /* NVRAM offset[0] ~ offset[255] */ + uint16_t u2Part1OwnVersion; + uint16_t u2Part1PeerVersion; + uint8_t aucMacAddress[6]; + uint8_t aucCountryCode[2]; + uint8_t aucOldTxPwr0[185]; + + uint8_t ucSupport5GBand; + uint8_t aucOldTxPwr1[4]; + + uint8_t ucRegChannelListMap; + uint8_t ucRegChannelListIndex; + uint8_t aucRegSubbandInfo[36]; + uint8_t ucEnable5GBand; /* move from 256+ offset to here */ + uint8_t ucNeedCheckLDO; + uint8_t ucDefaultTestMode; + uint8_t ucSupportCoAnt; + uint8_t aucReserved0[4]; + uint8_t ucAFCCapId; + uint8_t aucReserved2[7]; + /* NVRAM offset[256] ~ offset[255] */ + /* uint8_t aucReserved0[256 - 241]; */ + + uint8_t ucTypeID0; + uint8_t ucTypeLen0LSB; + uint8_t ucTypeLen0MSB; + struct WIFI_NVRAM_CONTROL_T rCtrl; + uint8_t ucTypeID1; + uint8_t ucTypeLen1LSB; + uint8_t ucTypeLen1MSB; + struct WIFI_NVRAM_2G4_TX_POWER_T r2G4Pwr; + uint8_t ucTypeID2; + uint8_t ucTypeLen2LSB; + uint8_t ucTypeLen2MSB; + struct WIFI_NVRAM_5G_TX_POWER_T r5GPwr; + uint8_t aucReserved1[1528]; +}; + +struct WIFI_NVRAM_TAG_FORMAT { + uint8_t u1NvramTypeID; + uint8_t u1NvramTypeLenLsb; + uint8_t u1NvramTypeLenMsb; +}; +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ +#ifndef DATA_STRUCT_INSPECTING_ASSERT +#define DATA_STRUCT_INSPECTING_ASSERT(expr) \ + {switch (0) {case 0: case (expr): default:; } } +#endif + +#define MAX_CFG_FILE_WIFI_REC_SIZE (1024*8) + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +#ifndef _lint +/* We don't have to call following function to inspect the data structure. + * It will check automatically while at compile time. + * We'll need this to guarantee the same member order in different structures + * to simply handling effort in some functions. + */ +static __KAL_INLINE__ void nvramOffsetCheck(void) +{ + DATA_STRUCT_INSPECTING_ASSERT( + OFFSET_OF(struct WIFI_CFG_PARAM_STRUCT, ucTypeID0) == 256); + DATA_STRUCT_INSPECTING_ASSERT( + sizeof(struct WIFI_CFG_PARAM_STRUCT) == 2048); +} +#endif + +#endif /* _CFG_WIFI_FILE_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/cmm_asic_connac.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/cmm_asic_connac.h new file mode 100644 index 0000000000000000000000000000000000000000..8e037c8a68eebe9885ba19588718d02dbd24d086 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/cmm_asic_connac.h @@ -0,0 +1,184 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/ + * MT6620_WIFI_DRIVER_V2_3/include/chips/connac.h#1 + */ + +/*! \file connac.h + * \brief This file contains the info of CONNAC + */ + +#ifndef _CMM_ASIC_CONNAC_H +#define _CMM_ASIC_CONNAC_H + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#define CONNAC_CHIP_IP_VERSION (0x10020300) +#define CONNAC_CHIP_IP_CONFIG (0x1) +#define USB_HIF_TXD_LEN 4 +#define NIC_TX_PSE_HEADER_LENGTH 4 + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +void asicCapInit(IN struct ADAPTER *prAdapter); +uint32_t asicGetFwDlInfo(struct ADAPTER *prAdapter, + char *pcBuf, int i4TotalLen); +void asicEnableFWDownload(IN struct ADAPTER *prAdapter, + IN u_int8_t fgEnable); +uint32_t asicGetChipID(struct ADAPTER *prAdapter); +void fillNicTxDescAppend(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + OUT uint8_t *prTxDescBuffer); +void fillNicTxDescAppendWithCR4(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + OUT uint8_t *prTxDescBuffer); +void fillTxDescAppendByHost(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, IN uint16_t u4MsduId, + IN phys_addr_t rDmaAddr, IN uint32_t u4Idx, IN u_int8_t fgIsLast, + OUT uint8_t *pucBuffer); +void fillTxDescAppendByHostV2(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, IN uint16_t u4MsduId, + IN phys_addr_t rDmaAddr, IN uint32_t u4Idx, IN u_int8_t fgIsLast, + OUT uint8_t *pucBuffer); +void fillTxDescAppendByCR4(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, IN uint16_t u4MsduId, + IN phys_addr_t rDmaAddr, IN uint32_t u4Idx, IN u_int8_t fgIsLast, + OUT uint8_t *pucBuffer); +void fillTxDescTxByteCount(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + void *prTxDesc); +void fillTxDescTxByteCountWithCR4(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + void *prTxDesc); + +#if defined(_HIF_PCIE) || defined(_HIF_AXI) +/* DMS Scheduler Init */ +void asicPcieDmaShdlInit(IN struct ADAPTER *prAdapter); +void asicPdmaLoopBackConfig(struct GLUE_INFO *prGlueInfo, u_int8_t fgEnable); +void asicPdmaIntMaskConfig(struct GLUE_INFO *prGlueInfo, u_int8_t fgEnable); +void asicPdmaConfig(struct GLUE_INFO *prGlueInfo, u_int8_t fgEnable, + bool fgResetHif); +uint32_t asicUpdatTxRingMaxQuota(IN struct ADAPTER *prAdapter, + IN uint16_t u2Port, IN uint32_t u4MaxQuota); +void asicEnableInterrupt(IN struct ADAPTER *prAdapter); +void asicDisableInterrupt(IN struct ADAPTER *prAdapter); +void asicLowPowerOwnRead(IN struct ADAPTER *prAdapter, OUT u_int8_t *pfgResult); +void asicLowPowerOwnSet(IN struct ADAPTER *prAdapter, OUT u_int8_t *pfgResult); +void asicLowPowerOwnClear(IN struct ADAPTER *prAdapter, + OUT u_int8_t *pfgResult); +void asicLowPowerOwnClearPCIe(IN struct ADAPTER *prAdapter, + OUT u_int8_t *pfgResult); +void asicWakeUpWiFi(IN struct ADAPTER *prAdapter); +bool asicIsValidRegAccess(IN struct ADAPTER *prAdapter, IN uint32_t u4Register); +void asicGetMailboxStatus(IN struct ADAPTER *prAdapter, OUT uint32_t *pu4Val); +void asicSetDummyReg(struct GLUE_INFO *prGlueInfo); +void asicCheckDummyReg(struct GLUE_INFO *prGlueInfo); +void asicPdmaTxRingExtCtrl( + struct GLUE_INFO *prGlueInfo, + struct RTMP_TX_RING *tx_ring, + uint32_t index); +void asicPdmaRxRingExtCtrl( + struct GLUE_INFO *prGlueInfo, + struct RTMP_RX_RING *rx_ring, + uint32_t index); +#endif /* _HIF_PCIE */ + +#if defined(_HIF_USB) +/* DMS Scheduler Init */ +void asicUsbDmaShdlInit(IN struct ADAPTER *prAdapter); +void asicUdmaTxTimeoutEnable(IN struct ADAPTER *prAdapter); +u_int8_t asicUsbSuspend(IN struct ADAPTER *prAdapter, + IN struct GLUE_INFO *prGlueInfo); +uint8_t asicUsbEventEpDetected(IN struct ADAPTER *prAdapter); +void asicUdmaRxFlush(IN struct ADAPTER *prAdapter, IN u_int8_t bEnable); +void asicPdmaHifReset(IN struct ADAPTER *prAdapter, IN u_int8_t bRelease); +void fillUsbHifTxDesc(IN uint8_t **pDest, IN uint16_t *pInfoBufLen); +#endif /* _HIF_USB */ +void asicFillInitCmdTxd( + struct ADAPTER *prAdapter, + struct WIFI_CMD_INFO *prCmdInfo, + uint16_t *pu2BufInfoLen, + u_int8_t *pucSeqNum, + void **pCmdBuf); +void asicFillCmdTxd( + struct ADAPTER *prAdapter, + struct WIFI_CMD_INFO *prCmdInfo, + u_int8_t *pucSeqNum, + void **pCmdBuf); +void asicInitTxdHook( + struct TX_DESC_OPS_T *prTxDescOps); +void asicInitRxdHook( + struct RX_DESC_OPS_T *prRxDescOps); +#if (CFG_SUPPORT_MSP == 1) +void asicRxProcessRxvforMSP( + IN struct ADAPTER *prAdapter, + IN OUT struct SW_RFB *prRetSwRfb); +#endif /* CFG_SUPPORT_MSP == 1 */ +uint8_t asicRxGetRcpiValueFromRxv( + IN uint8_t ucRcpiMode, + IN struct SW_RFB *prSwRfb); +#if (CFG_SUPPORT_PERF_IND == 1) +void asicRxPerfIndProcessRXV(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, + IN uint8_t ucBssIndex); +#endif + +#if (CFG_CHIP_RESET_SUPPORT == 1) && (CFG_WMT_RESET_API_SUPPORT == 0) +u_int8_t conn1_rst_L0_notify_step2(void); +#endif +#endif /* _CMM_ASIC_CONNAC_H */ + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/cmm_asic_connac2x.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/cmm_asic_connac2x.h new file mode 100644 index 0000000000000000000000000000000000000000..398ea6f6edb5a4eff3dd66552fcf311dece4628d --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/cmm_asic_connac2x.h @@ -0,0 +1,1232 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/*! \file cmm_asic_connac2x.h +* \brief This file contains the info of CONNAC2X +*/ + +#ifndef _CMM_ASIC_CONNAC2X_H +#define _CMM_ASIC_CONNAC2X_H + +#if (CFG_SUPPORT_CONNAC2X == 1) + +#define CONN_INFRA_REMAPPING_OFFSET 0x64000000 +#define CONNAC2X_WFDMA_DISP_MAX_CNT_MASK 0x000000FF +#define CONNAC2X_WFDMA_DISP_BASE_PTR_MASK 0xFFFF0000 + +#define CONNAC2X_MCU_WPDMA_0_BASE 0x54000000 +#define CONNAC2X_MCU_WPDMA_1_BASE 0x55000000 +#define CONNAC2X_HOST_WPDMA_0_BASE 0x7c024000 +#define CONNAC2X_HOST_WPDMA_1_BASE 0x7c025000 +#define CONNAC2X_HOST_DMASHDL 0x7c026000 + +#define CONNAC2X_WPDMA_GLO_CFG(__BASE) ((__BASE) + 0x0208) +#define CONNAC2X_WPDMA_GLO_CFG_EXT0(__BASE) ((__BASE) + 0x02B0) +#define CONNAC2X_TX_RING_EXT_CTRL_BASE(__BASE) ((__BASE) + 0x0600) +#define CONNAC2X_TX_RING_DISP_MAX_CNT 4 +#define CONNAC2X_RX_RING_DISP_MAX_CNT 4 + +#define CONNAC2X_RX_RING_CIDX(__BASE) ((__BASE) + 0x0508) +#define CONNAC2X_HOST_DMASHDL_SW_CONTROL(__BASE) ((__BASE) + 0x0004) + +/* OMIT_TX_INFO[28]*/ +#define CONNAC2X_WPDMA1_GLO_CFG_OMIT_TX_INFO 0x10000000 +/* OMIT_RX_INFO[27]*/ +#define CONNAC2X_WPDMA1_GLO_CFG_OMIT_RX_INFO 0x08000000 +/* OMIT_RX_INFO_PFET2[21]*/ +#define CONNAC2X_WPDMA1_GLO_CFG_OMIT_RX_INFO_PFET2 0x00200000 +/* FW_DWLD_Bypass_dmashdl[9] */ +#define CONNAC2X_WPDMA1_GLO_CFG_FW_DWLD_Bypass_dmashdl 0x00000200 +/* RX_DMA_BUSY[3] */ +#define CONNAC2X_WPDMA1_GLO_CFG_RX_DMA_BUSY 0x00000008 +/* RX_DMA_EN[2] */ +#define CONNAC2X_WPDMA1_GLO_CFG_RX_DMA_EN 0x00000004 +/* TX_DMA_BUSY[1] */ +#define CONNAC2X_WPDMA1_GLO_CFG_TX_DMA_BUSY 0x00000002 +/* TX_DMA_EN[0] */ +#define CONNAC2X_WPDMA1_GLO_CFG_TX_DMA_EN 0x00000001 +/* TX_DMASHDL_ENABLE[6] */ +#define CONNAC2X_WPDMA1_GLO_CFG_EXT0_TX_DMASHDL_EN 0x00000040 +/* DMASHDL_BYPASS[28] */ +#define CONNAC2X_HIF_DMASHDL_BYPASS_EN 0x10000000 + +#define CONNAC2X_NIC_TX_PSE_HEADER_LENGTH 8 +#define CONNAC2X_RX_INIT_EVENT_LENGTH 8 + +#define CONNAC2X_WFDMA_DUMMY_CR (CONNAC2X_MCU_WPDMA_0_BASE + 0x120) +#define CONNAC2X_WFDMA_NEED_REINIT_BIT BIT(1) + +#if defined(_HIF_PCIE) || defined(_HIF_AXI) +#define CONNAC2X_CONN_HIF_ON_ADDR_REMAP23 0x7010 +#define CONNAC2X_HOST_EXT_CONN_HIF_WRAP 0x7c027000 +#define CONNAC2X_MCU_INT_CONN_HIF_WRAP 0x57000000 +#define CONNAC2X_WFDMA_COUNT 2 + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ +#define CONNAC2X_WPDMA_EXT_INT_STA(__BASE) ((__BASE) + 0x0010) +#define CONNAC2X_WPDMA_EXT_INT_MASK(__BASE) ((__BASE) + 0x0014) +#define CONNAC2X_WPDMA_HIF_RST(__BASE) ((__BASE) + 0x0100) +#define CONNAC2X_WPDMA_HOST2MCU_SW_INT_SET(__BASE) ((__BASE) + 0x0108) +#define CONNAC2X_WPDMA_MCU2HOST_SW_INT_STA(__BASE) ((__BASE) + 0x01F0) +#define CONNAC2X_WPDMA_MCU2HOST_SW_INT_MASK(__BASE) ((__BASE) + 0x01F4) +#define CONNAC2X_WPDMA_INT_STA(__BASE) ((__BASE) + 0x0200) +#define CONNAC2X_WPDMA_INT_MASK(__BASE) ((__BASE) + 0x0204) +#define CONNAC2X_WPDMA_RST_DTX_PTR(__BASE) ((__BASE) + 0x020C) +#define CONNAC2X_WPDMA_RST_DRX_PTR(__BASE) ((__BASE) + 0x0280) + + +#define CONNAC2X_TX_RING_BASE(__BASE) ((__BASE) + 0x0300) +#define CONNAC2X_TX_RING_PTR(__BASE) ((__BASE) + 0x0300) +#define CONNAC2X_TX_RING_CNT(__BASE) ((__BASE) + 0x0304) +#define CONNAC2X_TX_RING_CIDX(__BASE) ((__BASE) + 0x0308) +#define CONNAC2X_TX_RING_DIDX(__BASE) ((__BASE) + 0x030C) + +#define CONNAC2X_RX_RING_BASE(__BASE) ((__BASE) + 0x0500) +#define CONNAC2X_RX_RING_PTR(__BASE) ((__BASE) + 0x0500) +#define CONNAC2X_RX_RING_CNT(__BASE) ((__BASE) + 0x0504) +#define CONNAC2X_RX_RING_DIDX(__BASE) ((__BASE) + 0x050C) +#define CONNAC2X_RX_RING_EXT_CTRL_BASE(__BASE) ((__BASE) + 0x0680) + +#define CONNAC2X_WFDMA1_RX_RING_BASE(__BASE) ((__BASE) + 0x0500) +#define CONNAC2X_WFDMA1_RX_RING_PTR(__BASE) ((__BASE) + 0x0500) +#define CONNAC2X_WFDMA1_RX_RING_CNT(__BASE) ((__BASE) + 0x0504) +#define CONNAC2X_WFDMA1_RX_RING_CIDX(__BASE) ((__BASE) + 0x0508) +#define CONNAC2X_WFDMA1_RX_RING_DIDX(__BASE) ((__BASE) + 0x050C) +#define CONNAC2X_WFDMA1_RX_RING_EXT_CTRL_BASE(__BASE) ((__BASE) + 0x0680) + +#define CONNAC2X_FWDL_TX_RING_IDX 16 +#define CONNAC2X_CMD_TX_RING_IDX 17 /* Direct to WM */ +#define CONNAC2X_DATA0_TXD_IDX 18 /* Band_0 TXD to WA */ +#define CONNAC2X_DATA1_TXD_IDX 19 /* Band_1 TXD to WA */ +#define CONNAC2X_CMD_TX_WA_RING_IDX 20 /* WA relay to WM */ + + +/* WPDMA_INT_STA (0x50000000+0x200) */ +#define CONNAC2X_WFDMA_TX_DONE_INT17 BIT(27) +#define CONNAC2X_WFDMA_TX_DONE_INT16 BIT(26) +#define CONNAC2X_WFDMA_RX_DONE_INT5 BIT(23) +#define CONNAC2X_WFDMA_RX_DONE_INT4 BIT(22) +#define CONNAC2X_TX_COHERENT_INT BIT(21) +#define CONNAC2X_RX_COHERENT_INT BIT(20) +#define CONNAC2X_WFDMA_TX_DONE_INT6 BIT(10) +#define CONNAC2X_WFDMA_TX_DONE_INT5 BIT(9) +#define CONNAC2X_WFDMA_TX_DONE_INT4 BIT(8) +#define CONNAC2X_WFDMA_TX_DONE_INT3 BIT(7) +#define CONNAC2X_WFDMA_TX_DONE_INT2 BIT(6) +#define CONNAC2X_WFDMA_TX_DONE_INT1 BIT(5) +#define CONNAC2X_WFDMA_TX_DONE_INT0 BIT(4) +#define CONNAC2X_WFDMA_RX_DONE_INT3 BIT(3) +#define CONNAC2X_WFDMA_RX_DONE_INT2 BIT(2) +#define CONNAC2X_WFDMA_RX_DONE_INT1 BIT(1) +#define CONNAC2X_WFDMA_RX_DONE_INT0 BIT(0) + +/* EXT WPDMA_INT_STA (0x53000000+0x10) */ +#define CONNAC2X_EXT_WFDMA1_TX_DONE_INT19 BIT(31) +#define CONNAC2X_EXT_WFDMA1_TX_DONE_INT18 BIT(30) +#define CONNAC2X_EXT_WFDMA1_TX_DONE_INT17 BIT(27) +#define CONNAC2X_EXT_WFDMA1_TX_DONE_INT16 BIT(26) +#define CONNAC2X_EXT_WFDMA0_TX_COHERENT_INT BIT(23) +#define CONNAC2X_EXT_WFDMA0_RX_COHERENT_INT BIT(22) +#define CONNAC2X_EXT_WFDMA1_TX_COHERENT_INT BIT(21) +#define CONNAC2X_EXT_WFDMA1_RX_COHERENT_INT BIT(20) +#define CONNAC2X_EXT_WFDMA0_RX_DONE_INT3 BIT(19) +#define CONNAC2X_EXT_WFDMA0_RX_DONE_INT2 BIT(18) +#define CONNAC2X_EXT_WFDMA0_RX_DONE_INT1 BIT(17) +#define CONNAC2X_EXT_WFDMA0_RX_DONE_INT0 BIT(16) +#define CONNAC2X_EXT_WFDMA1_TX_DONE_INT20 BIT(15) +#define CONNAC2X_EXT_WFDMA1_TX_DONE_INT6 BIT(10) +#define CONNAC2X_EXT_WFDMA1_TX_DONE_INT5 BIT(9) +#define CONNAC2X_EXT_WFDMA1_TX_DONE_INT4 BIT(8) +#define CONNAC2X_EXT_WFDMA1_TX_DONE_INT3 BIT(7) +#define CONNAC2X_EXT_WFDMA1_TX_DONE_INT2 BIT(6) +#define CONNAC2X_EXT_WFDMA1_TX_DONE_INT1 BIT(5) +#define CONNAC2X_EXT_WFDMA1_TX_DONE_INT0 BIT(4) +#define CONNAC2X_EXT_WFDMA1_RX_DONE_INT2 BIT(2) +#define CONNAC2X_EXT_WFDMA1_RX_DONE_INT1 BIT(1) +#define CONNAC2X_EXT_WFDMA1_RX_DONE_INT0 BIT(0) + + +#define CONNAC2X_HOST_CSR_TOP_BASE (0x7c060000) +#define CONNAC2X_BN0_LPCTL_ADDR (CONNAC2X_HOST_CSR_TOP_BASE + 0x10) +#define CONNAC2X_BN0_IRQ_STAT_ADDR (CONNAC2X_HOST_CSR_TOP_BASE + 0x14) +#define CONNAC2X_BN0_IRQ_ENA_ADDR (CONNAC2X_HOST_CSR_TOP_BASE + 0x18) + +#endif /* _HIF_PCIE || _HIF_AXI */ + +#if defined(_HIF_USB) +#define CONNAC2X_UDMA_BASE 0x74000000 +#define CONNAC2X_UDMA_TX_QSEL (CONNAC2X_UDMA_BASE + 0x08) /* 0008 */ +#define CONNAC2X_UDMA_RESET (CONNAC2X_UDMA_BASE + 0x14) /* 0014 */ +#define CONNAC2X_UDMA_WLCFG_1 (CONNAC2X_UDMA_BASE + 0x0C) /* 000c */ +#define CONNAC2X_UDMA_WLCFG_0 (CONNAC2X_UDMA_BASE + 0x18) /* 0018 */ + +#define CONNAC2X_UDMA_WLCFG_0_WL_TX_BUSY_MASK (0x1 << 31) +#define CONNAC2X_UDMA_WLCFG_0_WL_TX_EN(p) (((p) & 0x1) << 23) +#define CONNAC2X_UDMA_WLCFG_0_WL_RX_EN(p) (((p) & 0x1) << 22) +#define CONNAC2X_UDMA_WLCFG_0_TICK_1US_EN_MASK (0x1 << 20) +#define CONNAC2X_UDMA_WLCFG_0_TICK_1US_EN(p) (((p) & 0x1) << 20) +#define CONNAC2X_UDMA_WLCFG_0_WL_RX_FLUSH_MASK (0x1 << 19) +#define CONNAC2X_UDMA_WLCFG_0_WL_RX_MPSZ_PAD0(p) (((p) & 0x1) << 18) +#define CONNAC2X_UDMA_WLCFG_0_WL_TX_TMOUT_FUNC_EN_MASK (0x1 << 16) +#define CONNAC2X_UDMA_WLCFG_1_WL_TX_TMOUT_LMT_MASK (0xFFFFF << 8) +#define CONNAC2X_UDMA_WLCFG_1_WL_TX_TMOUT_LMT(p) (((p) & 0xFFFFF) << 8) + +#define CONNAC2X_UDMA_TX_TIMEOUT_LIMIT (50000) + +#define CONNAC2X_WFDMA_HOST_CONFIG_ADDR 0x7c027030 +/* + * 0: command packet forward to TX ring 17 (WMCPU) + * 1: forward to TX ring 20 (WACPU) + */ +#define CONNAC2X_WFDMA_HOST_CONFIG_USB_CMDPKT_DST_MASK (0x1 << 7) +#define CONNAC2X_WFDMA_HOST_CONFIG_USB_CMDPKT_DST(p) (((p) & 0x1) << 7) +#define CONNAC2X_USB_CMDPKT2WM 0 +#define CONNAC2X_USB_CMDPKT2WA 1 + +#define CONNAC2X_WFDMA_HOST_CONFIG_USB_RXEVT_EP4_EN (0x1 << 6) + +#define CONNAC2X_LEN_USB_RX_PADDING_CSO (4) /*HW design spec */ +#endif /* _HIF_USB */ + +/*------------------------------------------------------------------------*/ +/* Rx descriptor field related information */ +/*------------------------------------------------------------------------*/ +/* DW 0 */ +#define CONNAC2X_RXD_RX_BYTE_COUNT_MASK BITS(0, 15) +#define CONNAC2X_RXD_RX_BYTE_COUNT_OFFSET 0 + +#define CONNAC2X_RXD_PKT_TYPE_MASK BITS(27, 31) +#define CONNAC2X_RXD_PKT_TYPE_OFFSET 27 + +#define HAL_CONNAC2X_RXD_GET_PKT_TYPE(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->u2DW0 &\ + CONNAC2X_RXD_PKT_TYPE_MASK) >> CONNAC2X_RXD_PKT_TYPE_OFFSET) + +/*------------------------------------------------------------------------------ + * MACRO for WTBL INFO GET + *------------------------------------------------------------------------------ + */ + +/* CONNAC2X */ +#define CONNAC2X_WIFI_LWTBL_BASE 0x820d4000 +#define CONNAC2X_WIFI_LWTBL_GROUP_MASK 0x00000007 /* GROUP[2..0] */ +#define CONNAC2X_WIFI_LWTBL_GROUP_SHFT 0 + +#define CONNAC2X_WIFI_UWTBL_BASE 0x820c4000 +#define CONNAC2X_WIFI_UWTBL_TARGET_MASK 0x80000000 /* TARGET[31] */ +#define CONNAC2X_WIFI_UWTBL_TARGET_SHFT 31 +#define CONNAC2X_WIFI_UWTBL_GROUP_MASK 0x0000000F /* GROUP[3..0] */ +#define CONNAC2X_WIFI_UWTBL_GROUP_SHFT 0 + + +/* UWTBL DW 5 */ +#define CONNAC2X_WTBL_KEY_LINK_DW_KEY_LOC0_MASK BITS(0, 10) +#define CONNAC2X_WTBL_KEY_LINK_DW_KEY_LOC0_OFFSET 0 + +#define CONNAC2X_WTBL_KEY_LINK_DW_KEY_LOC1_MASK BITS(16, 26) +#define CONNAC2X_WTBL_KEY_LINK_DW_KEY_LOC1_OFFSET 16 + + + +#define CONNAC2X_LWTBL_CONFIG(_pAd, _lmacWtblDUAddr, _wlanIdx) \ + HAL_MCR_WR(_pAd, _lmacWtblDUAddr, \ + ((_wlanIdx >> 7) & CONNAC2X_WIFI_LWTBL_GROUP_MASK) \ + << CONNAC2X_WIFI_LWTBL_GROUP_SHFT) + +#define CONNAC2X_LWTBL_IDX2BASE(_lmacWtblDUAddr, _wlanIdx, _DW) \ + ((_lmacWtblDUAddr & 0xFFFF0000) | 0x8000 | \ + ((_wlanIdx & 0x7F) << 8) | (_DW & 0x3F) << 2) + +#define CONNAC2X_UWTBL_CONFIG(_pAd, _umacWtblDUAddr, _wlanIdx) \ + HAL_MCR_WR(_pAd, _umacWtblDUAddr, \ + ((_wlanIdx >> 7) & CONNAC2X_WIFI_UWTBL_GROUP_MASK) \ + << CONNAC2X_WIFI_UWTBL_GROUP_SHFT) + +#define CONNAC2X_UWTBL_IDX2BASE(_umacWtblDUAddr, _wlanIdx, _DW) \ + ((_umacWtblDUAddr & 0XFFFFC000) | 0x2000 | \ + ((_wlanIdx & 0x7F) << 6) | (_DW & 0xF) << 2) + +#define CONNAC2X_KEYTBL_CONFIG(_pAd, _umacWtblDUAddr, _key_loc) \ + HAL_MCR_WR(_pAd, _umacWtblDUAddr, \ + (CONNAC2X_WIFI_UWTBL_TARGET_MASK | \ + (((_key_loc >> 7) & CONNAC2X_WIFI_UWTBL_GROUP_MASK) \ + << CONNAC2X_WIFI_UWTBL_GROUP_SHFT))) + +#define CONNAC2X_KEYTBL_IDX2BASE(_umacWtblDUAddr, _key_loc, _DW) \ + ((_umacWtblDUAddr & 0XFFFFC000) | 0x2000 | \ + ((_key_loc & 0x7F) << 6) | (_DW & 0xF) << 2) + +/*------------------------------------------------------------------------------ + * MACRO for decision of RXV source (RXD or RX_RPT) + *------------------------------------------------------------------------------ + */ +#define CONNAC2X_RXV_FROM_RX_RPT(_prAdapter) \ + ((_prAdapter)->chip_info->get_rxv_from_rxrpt) + +/*------------------------------------------------------------------------------ + * MACRO for CONNAC2X RXVECTOR Parsing + *------------------------------------------------------------------------------ + */ +/* P-RXVector, 1st Cycle */ +#define CONNAC2X_RX_VT_RX_RATE_MASK BITS(0, 6) +#define CONNAC2X_RX_VT_RX_RATE_OFFSET 0 +#define CONNAC2X_RX_VT_NSTS_MASK BITS(7, 9) +#define CONNAC2X_RX_VT_NSTS_OFFSET 7 +#define CONNAC2X_RX_VT_LDPC BIT(11) + +/* C-RXC Vector, 1st Cycle */ +#define CONNAC2X_RX_VT_STBC_MASK BITS(0, 1) +#define CONNAC2X_RX_VT_STBC_OFFSET 0 +#define CONNAC2X_RX_VT_RX_MODE_MASK BITS(4, 7) +#define CONNAC2X_RX_VT_RX_MODE_OFFSET 4 +#define CONNAC2X_RX_VT_FR_MODE_MASK BITS(8, 10) +#define CONNAC2X_RX_VT_FR_MODE_OFFSET 8 +#define CONNAC2X_RX_VT_SHORT_GI_MASK BITS(13, 14) +#define CONNAC2X_RX_VT_SHORT_GI_OFFSET 13 +#define CONNAC2X_RX_VT_GROUP_ID_MASK BITS(22, 27) +#define CONNAC2X_RX_VT_GROUP_ID_OFFSET 22 + +/* C-RXC Vector, 4th Cycle */ +#define CONNAC2X_RX_VT_RCPI0_MASK BITS(0, 7) +#define CONNAC2X_RX_VT_RCPI0_OFFSET 0 +#define CONNAC2X_RX_VT_RCPI1_MASK BITS(8, 15) +#define CONNAC2X_RX_VT_RCPI1_OFFSET 8 +#define CONNAC2X_RX_VT_RCPI2_MASK BITS(16, 23) +#define CONNAC2X_RX_VT_RCPI2_OFFSET 16 +#define CONNAC2X_RX_VT_RCPI3_MASK BITS(24, 31) +#define CONNAC2X_RX_VT_RCPI3_OFFSET 24 + +#define CONNAC2X_HAL_RX_VECTOR_GET_RX_VECTOR(_prHwRxVector, _ucIdx) \ + ((_prHwRxVector)->u4RxVector[_ucIdx]) + +#define CONNAC2X_HAL_RXV_GET_RCPI0_RXRPT(_RxvDw6) \ + (((_RxvDw6) & CONNAC2X_RX_VT_RCPI0_MASK) >> CONNAC2X_RX_VT_RCPI0_OFFSET) + +#define CONNAC2X_HAL_RXV_GET_RCPI1_RXRPT(_RxvDw6) \ + (((_RxvDw6) & CONNAC2X_RX_VT_RCPI1_MASK) >> CONNAC2X_RX_VT_RCPI1_OFFSET) + +#define CONNAC2X_HAL_RXV_GET_RCPI2_RXRPT(_RxvDw6) \ + (((_RxvDw6) & CONNAC2X_RX_VT_RCPI2_MASK) >> CONNAC2X_RX_VT_RCPI2_OFFSET) + +#define CONNAC2X_HAL_RXV_GET_RCPI3_RXRPT(_RxvDw6) \ + (((_RxvDw6) & CONNAC2X_RX_VT_RCPI3_MASK) >> CONNAC2X_RX_VT_RCPI3_OFFSET) + +#define CONNAC2X_HAL_RXV_GET_NUM_RX_RXRPT(_RxvDw2) \ + (((_RxvDw2) & CONNAC2X_RX_VT_NUM_RX_MASK) >> \ + CONNAC2X_RX_VT_NUM_RX_OFFSET) + + +#if defined(_HIF_PCIE) || defined(_HIF_AXI) +#define HAL_IS_CONNAC2X_EXT_TX_DONE_INTR(u4IntrStatus, __u4IntrBits) \ + ((u4IntrStatus & (__u4IntrBits)) ? TRUE : FALSE) + +#define HAL_IS_CONNAC2X_EXT_RX_DONE_INTR(u4IntrStatus, __u4IntrBits) \ + ((u4IntrStatus & (__u4IntrBits)) ? TRUE : FALSE) +#endif /* defined(_HIF_PCIE) || defined(_HIF_AXI) */ + + +/*------------------------------------------------------------------------------ + * MACRO for CONNAC2X WTBL TX RATE + *------------------------------------------------------------------------------ + */ +#define CONNAC2X_HW_TX_RATE_TO_MODE(_x) (((_x) & (0xf << 6)) >> 6) +#define CONNAC2X_HW_TX_RATE_TO_NSS(_x) (((_x) & (0x7 << 10)) >> 10) +#define CONNAC2X_HW_TX_RATE_TO_STBC(_x) (((_x) & (0x1 << 13)) >> 13) + +/*------------------------------------------------------------------------------ + * MACRO for CONNAC2X TXV + *------------------------------------------------------------------------------ + */ +#define CONNAC2X_TXV_GET_TX_RATE(_x) ((_x)->u4TxV[2] & 0x7f) +#define CONNAC2X_TXV_GET_TX_LDPC(_x) (((_x)->u4TxV[2] & (0x1 << 7)) >> 7) +#define CONNAC2X_TXV_GET_TX_STBC(_x) (((_x)->u4TxV[0] & (0x3 << 6)) >> 6) +#define CONNAC2X_TXV_GET_TX_FRMODE(_x) (((_x)->u4TxV[0] & (0x7 << 8)) >> 8) +#define CONNAC2X_TXV_GET_TX_MODE(_x) (((_x)->u4TxV[0] & (0xf << 12)) >> 12) +#define CONNAC2X_TXV_GET_TX_NSTS(_x) (((_x)->u4TxV[2] & (0x7 << 8)) >> 8) +#define CONNAC2X_TXV_GET_TX_PWR(_x) (((_x)->u4TxV[0] & (0xff << 16)) >> 16) +#define CONNAC2X_TXV_GET_TX_SGI(_x) (((_x)->u4TxV[1] & (0x3 << 26)) >> 26) + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +struct CONNAC2X_WIFI_CMD { + struct HW_MAC_CONNAC2X_TX_DESC rWifiCmdTxD; + + uint16_t u2Length; + uint16_t u2PqId; + + uint8_t ucCID; + uint8_t ucPktTypeID; /* Must be 0x20 (CMD Packet) */ + uint8_t ucSetQuery; + uint8_t ucSeqNum; + + /* padding fields, hw may auto modify this field */ + uint8_t ucD2B0Rev; + uint8_t ucExtenCID; /* Extend CID */ + uint8_t ucS2DIndex; /* Index for Src to Dst in CMD usage */ + uint8_t ucExtCmdOption; /* Extend CID option */ + + uint8_t ucCmdVersion; + uint8_t ucReserved2[3]; + uint32_t au4Reserved3[4]; /* padding fields */ + + uint8_t aucBuffer[0]; +}; + +union WTBL_LMAC_DW0 { + struct { + uint32_t addr_4:8; + uint32_t addr_5:8; + uint32_t muar_idx:6; + uint32_t rc_a1:1; + uint32_t kid:2; + uint32_t rc_id:1; + uint32_t fd:1; + uint32_t td:1; + uint32_t rv:1; + uint32_t rc_a2:1; + uint32_t wpi_flg:1; + uint32_t pad:1; + } field; + uint32_t word; +}; + +union WTBL_LMAC_DW1 { + struct { + uint32_t addr_0; + } field; + uint32_t word; +}; + +enum WTBL_LMAC_CIPHER_SUIT { + WTBL_CIPHER_NONE = 0, + WTBL_CIPHER_WEP_40 = 1, + WTBL_CIPHER_TKIP_MIC = 2, + WTBL_CIPHER_TKIP_NO_MIC = 3, + WTBL_CIPHER_CCMP_128_PMF = 4, + WTBL_CIPHER_WEP_104 = 5, + WTBL_CIPHER_BIP_CMAC_128 = 6, + WTBL_CIPHER_WEP_128 = 7, + WTBL_CIPHER_WPI_128 = 8, + WTBL_CIPHER_CCMP_128_CCX = 9, + WTBL_CIPHER_CCMP_256 = 10, + WTBL_CIPHER_GCMP_128 = 11, + WTBL_CIPHER_GCMP_256 = 12, + WTBL_CIPHER_GCMP_WPI_128 = 13, +}; + +union WTBL_LMAC_DW2 { + struct { + uint32_t aid12:12; + uint32_t gid_su:1; + uint32_t spp_en:1; + uint32_t wpi_even:1; + uint32_t aad_om:1; + uint32_t cipher_suit:5; + uint32_t cipher_suit_igtk:2; + uint32_t rsvd:1; + uint32_t sw:1; + uint32_t ul:1; + uint32_t tx_ps:1; + uint32_t qos:1; + uint32_t ht:1; + uint32_t vht:1; + uint32_t he:1; + uint32_t mesh:1; + } field; + uint32_t word; +}; + +union WTBL_LMAC_DW3 { + struct { + uint32_t wmm_q:2; + uint32_t rxd_dup_mode:2; + uint32_t vlan_2e_th:1; + uint32_t pad:3; + uint32_t pfmu_index:8; + uint32_t bf_rsvd:8; + uint32_t ribf:1; + uint32_t bf_rsvd2:4; + uint32_t tebf:1; + uint32_t tebf_vht:1; + uint32_t tebf_he:1; + } field; + + struct { + uint32_t wmm_q:2; + uint32_t rxd_dup_mode:2; + uint32_t vlan_2e_th:1; + uint32_t beam_chg:1; + uint32_t ba_mode:2; + uint32_t pfmu_index:8; + uint32_t ulpf_index:8; + uint32_t ribf:1; + uint32_t ulpf:1; + uint32_t ign_fbk:1; + uint32_t bf_rsvd2:2; + uint32_t tebf:1; + uint32_t tebf_vht:1; + uint32_t tebf_he:1; + } field_v2; + uint32_t word; +}; + +union WTBL_LMAC_DW4 { + struct { + uint32_t ant_id_sts0:3; + uint32_t ant_id_sts1:3; + uint32_t ant_id_sts2:3; + uint32_t ant_id_sts3:3; + uint32_t ant_id_sts4:3; + uint32_t ant_id_sts5:3; + uint32_t ant_id_sts6:3; + uint32_t ant_id_sts7:3; + uint32_t cascad:1; + uint32_t ldpc_ht:1; + uint32_t ldpc_vht:1; + uint32_t ldpc_he:1; + uint32_t dis_rhtr:1; + uint32_t all_ack:1; + uint32_t drop:1; + uint32_t ack_en:1; + } field; + uint32_t word; +}; + +union WTBL_LMAC_DW5 { + struct { + uint32_t af:3; + uint32_t af_he:2; + uint32_t rts:1; + uint32_t smps:1; + uint32_t dyn_bw:1; + uint32_t mmss:3; + uint32_t usr:1; + uint32_t sr_r:2; + uint32_t beam_chg:1; + uint32_t sr_abort:1; + uint32_t tx_power_offset:6; + uint32_t mpdu_size:2; + uint32_t pe:2; + uint32_t doppl:1; + uint32_t txop_ps_cap:1; + uint32_t du_i_psm:1; + uint32_t i_psm:1; + uint32_t psm:1; + uint32_t skip_tx:1; + } field; + + struct { + uint32_t af:3; + uint32_t af_he:2; + uint32_t rts:1; + uint32_t smps:1; + uint32_t dyn_bw:1; + uint32_t mmss:3; + uint32_t usr:1; + uint32_t sr_r:3; + uint32_t sr_abort:1; + uint32_t tx_power_offset:6; + uint32_t mpdu_size:2; + uint32_t pe:2; + uint32_t doppl:1; + uint32_t txop_ps_cap:1; + uint32_t du_i_psm:1; + uint32_t i_psm:1; + uint32_t psm:1; + uint32_t skip_tx:1; + } field_v2; + uint32_t word; +}; + +union WTBL_LMAC_DW6 { + struct { + uint32_t ba_win_size_tid0:4; + uint32_t ba_win_size_tid1:4; + uint32_t ba_win_size_tid2:4; + uint32_t ba_win_size_tid3:4; + uint32_t ba_win_size_tid4:4; + uint32_t ba_win_size_tid5:4; + uint32_t ba_win_size_tid6:4; + uint32_t ba_win_size_tid7:4; + } field; + uint32_t word; +}; + +union WTBL_LMAC_DW7 { + struct { + uint32_t cb_rn:3; + uint32_t dbnss_en:1; + uint32_t bafen:1; + uint32_t rdg_ba:1; + uint32_t r:1; + uint32_t spe_idx:5; + uint32_t g2:1; + uint32_t g4:1; + uint32_t g8:1; + uint32_t g16:1; + uint32_t g2_ltf:2; + uint32_t g4_ltf:2; + uint32_t g8_ltf:2; + uint32_t g16_ltf:2; + uint32_t g2_he:2; + uint32_t g4_he:2; + uint32_t g8_he:2; + uint32_t g16_he:2; + } field; + uint32_t word; +}; + +union WTBL_LMAC_DW8 { + struct { + uint32_t rts_fail_cnt_ac0:5; + uint32_t rts_fail_cnt_ac1:5; + uint32_t rts_fail_cnt_ac2:5; + uint32_t rts_fail_cnt_ac3:5; + uint32_t partial_aid:9; + uint32_t pad:2; + uint32_t chk_per:1; + } field; + uint32_t word; +}; + +union WTBL_LMAC_DW9 { + struct { + uint32_t rx_avg_mpdu_size:14; + uint32_t pad:4; + uint32_t pritx_dcm:1; + uint32_t pritx_er160:1; + uint32_t pritx_ersu:1; + uint32_t fcap:2; + uint32_t mpdu_fail_cnt:3; + uint32_t mpdu_ok_cnt:3; + uint32_t rate_idx:3; + } field; + + struct { + uint32_t rx_avg_mpdu_size:14; + uint32_t pad:2; + uint32_t pritx_sw_mode:1; + uint32_t pritx_plr:1; + uint32_t pritx_dcm:1; + uint32_t pritx_er160:1; + uint32_t pritx_ersu:1; + uint32_t fcap:2; + uint32_t mpdu_fail_cnt:3; + uint32_t mpdu_ok_cnt:3; + uint32_t rate_idx:3; + } field_v2; + uint32_t word; +}; + +union WTBL_LMAC_DW10 { + struct { + uint32_t rate1:14; + uint32_t pad:2; + uint32_t rate2:14; + uint32_t pad2:2; + } field; + uint32_t word; +}; + +union WTBL_LMAC_DW11 { + struct { + uint32_t rate3:14; + uint32_t pad:2; + uint32_t rate4:14; + uint32_t pad2:2; + } field; + uint32_t word; +}; + +union WTBL_LMAC_DW12 { + struct { + uint32_t rate5:14; + uint32_t pad:2; + uint32_t rate6:14; + uint32_t pad2:2; + } field; + uint32_t word; +}; + +union WTBL_LMAC_DW13 { + struct { + uint32_t rate7:14; + uint32_t pad:2; + uint32_t rate8:14; + uint32_t pad2:2; + } field; + uint32_t word; +}; + +union WTBL_LMAC_DW14 { + struct { + uint32_t rate_1_tx_cnt:16; + uint32_t rate_1_fail_cnt:16; + } field; + uint32_t word; +}; + +union WTBL_LMAC_DW15 { + struct { + uint32_t rate_2_ok_cnt:16; + uint32_t rate_3_ok_cnt:16; + } field; + uint32_t word; +}; + +union WTBL_LMAC_DW16 { + struct { + uint32_t current_bw_tx_cnt:16; + uint32_t current_bw_fail_cnt:16; + } field; + uint32_t word; +}; + +union WTBL_LMAC_DW17 { + struct { + uint32_t other_bw_tx_cnt:16; + uint32_t other_bw_fail_cnt:16; + } field; + uint32_t word; +}; + +union WTBL_LMAC_DW18 { + struct { + uint32_t rts_ok_cnt:16; + uint32_t rts_fail_cnt:16; + } field; + uint32_t word; +}; + +union WTBL_LMAC_DW19 { + struct { + uint32_t data_retry_cnt:16; + uint32_t mgnt_retry_cnt:16; + } field; + uint32_t word; +}; + +union WTBL_LMAC_DW20 { + uint32_t word; +}; + +union WTBL_LMAC_DW21 { + uint32_t word; +}; + +union WTBL_LMAC_DW22 { + uint32_t word; +}; + +union WTBL_LMAC_DW23 { + uint32_t word; +}; + +union WTBL_LMAC_DW24 { + uint32_t word; +}; + +union WTBL_LMAC_DW25 { + uint32_t word; +}; + +union WTBL_LMAC_DW26 { + uint32_t word; +}; + +union WTBL_LMAC_DW27 { + uint32_t word; +}; + +union WTBL_LMAC_DW28 { + struct { + uint32_t usr_rssi:9; + uint32_t usr_snr:6; + uint32_t pad:1; + uint32_t rapid_reaction_rate:11; + uint32_t pad2:3; + uint32_t ht_amsdu:1; + uint32_t amsdu_cros_lg:1; + } field; + + struct { + uint32_t om_info:12; + uint32_t rxd_dup_om_chg:1; + uint32_t pad:19; + } field_v2; + uint32_t word; +}; + +union WTBL_LMAC_DW29 { + struct { + uint32_t resp_rcpi_0:8; + uint32_t resp_rcpi_1:8; + uint32_t resp_rcpi_2:8; + uint32_t resp_rcpi_3:8; + } field; + + struct { + uint32_t usr_rssi:9; + uint32_t usr_snr:6; + uint32_t pad:1; + uint32_t rapid_reaction_rate:11; + uint32_t pad2:3; + uint32_t ht_amsdu:1; + uint32_t amsdu_cros_lg:1; + } field_2; + uint32_t word; +}; + +union WTBL_LMAC_DW30 { + struct { + uint32_t resp_rcpi_4:8; + uint32_t resp_rcpi_5:8; + uint32_t resp_rcpi_6:8; + uint32_t resp_rcpi_7:8; + } field; + + struct { + uint32_t resp_rcpi_0:8; + uint32_t resp_rcpi_1:8; + uint32_t resp_rcpi_2:8; + uint32_t resp_rcpi_3:8; + } field_v2; + uint32_t word; +}; + +union WTBL_LMAC_DW31 { + struct { + uint32_t snr_rx0:6; + uint32_t snr_rx1:6; + uint32_t snr_rx2:6; + uint32_t snr_rx3:6; + uint32_t pad:8; + } field; + uint32_t word; +}; + +union WTBL_LMAC_DW32 { + struct { + uint32_t snr_rx4:6; + uint32_t snr_rx5:6; + uint32_t snr_rx6:6; + uint32_t snr_rx7:6; + uint32_t pad:8; + } field; + uint32_t word; +}; + +struct wtbl_rx_stat { + union WTBL_LMAC_DW28 wtbl_d28; + union WTBL_LMAC_DW29 wtbl_d29; + union WTBL_LMAC_DW30 wtbl_d30; + union WTBL_LMAC_DW31 wtbl_d31; + union WTBL_LMAC_DW32 wtbl_d32; +}; + +struct wtbl_adm_ctrl { + union WTBL_LMAC_DW20 wtbl_d20; + union WTBL_LMAC_DW21 wtbl_d21; + union WTBL_LMAC_DW22 wtbl_d22; + union WTBL_LMAC_DW23 wtbl_d23; + union WTBL_LMAC_DW24 wtbl_d24; + union WTBL_LMAC_DW25 wtbl_d25; + union WTBL_LMAC_DW26 wtbl_d26; + union WTBL_LMAC_DW27 wtbl_d27; +}; + +struct wtbl_ppdu_cnt { + union WTBL_LMAC_DW19 wtbl_d19; +}; + +struct wtbl_auto_rate_cnt { + union WTBL_LMAC_DW14 wtbl_d14; + union WTBL_LMAC_DW15 wtbl_d15; + union WTBL_LMAC_DW16 wtbl_d16; + union WTBL_LMAC_DW17 wtbl_d17; + union WTBL_LMAC_DW18 wtbl_d18; +}; + +struct wtbl_auto_rate_tb { + union WTBL_LMAC_DW10 wtbl_d10; + union WTBL_LMAC_DW11 wtbl_d11; + union WTBL_LMAC_DW12 wtbl_d12; + union WTBL_LMAC_DW13 wtbl_d13; +}; + +struct wtbl_tx_rx_cap { + union WTBL_LMAC_DW2 wtbl_d2; + union WTBL_LMAC_DW3 wtbl_d3; + union WTBL_LMAC_DW4 wtbl_d4; + union WTBL_LMAC_DW5 wtbl_d5; + union WTBL_LMAC_DW6 wtbl_d6; + union WTBL_LMAC_DW7 wtbl_d7; + union WTBL_LMAC_DW8 wtbl_d8; + union WTBL_LMAC_DW9 wtbl_d9; +}; + +struct wtbl_basic_info { + union WTBL_LMAC_DW0 wtbl_d0; + union WTBL_LMAC_DW1 wtbl_d1; +}; + +struct fwtbl_lmac_struct { + struct wtbl_basic_info peer_basic_info; + struct wtbl_tx_rx_cap trx_cap; + struct wtbl_auto_rate_tb auto_rate_tb; + struct wtbl_auto_rate_cnt auto_rate_counters; + struct wtbl_ppdu_cnt ppdu_counters; + struct wtbl_adm_ctrl adm_ctrl; + struct wtbl_rx_stat rx_stat; +}; + +union WTBL_UMAC_DW0 { + struct { + uint32_t pn0; + } field; + uint32_t word; +}; + +union WTBL_UMAC_DW1 { + struct { + uint32_t pn1:16; + uint32_t com_sn:12; + uint32_t pad:4; + } field; + uint32_t word; +}; + +union WTBL_UMAC_DW2 { + struct { + uint32_t ac0_sn:12; + uint32_t ac1_sn:12; + uint32_t ac2_sn:8; + } field; + uint32_t word; +}; + +union WTBL_UMAC_DW3 { + struct { + uint32_t ac2_sn:4; + uint32_t ac3_sn:12; + uint32_t ac4_sn:12; + uint32_t ac5_sn:4; + } field; + uint32_t word; +}; + +union WTBL_UMAC_DW4 { + struct { + uint32_t ac5_sn:8; + uint32_t ac6_sn:12; + uint32_t ac7_sn:12; + } field; + uint32_t word; +}; + +union WTBL_UMAC_DW5 { + struct { + uint32_t key_loc0:11; + uint32_t pad:5; + uint32_t key_loc1:11; + uint32_t qos:1; + uint32_t ht:1; + uint32_t pad2:3; + } field; + uint32_t word; +}; + +union WTBL_UMAC_DW6 { + struct { + uint32_t hw_amsdu_cfg:10; + uint32_t pad:22; + } field; + uint32_t word; +}; + +union WTBL_UMAC_DW7 { + struct { + uint32_t pad:32; + } field; + uint32_t word; +}; + +struct wtbl_key_tb { + union WTBL_UMAC_DW7 wtbl_d7; +}; + +struct wtbl_keylink_amsdu { + union WTBL_UMAC_DW5 wtbl_d5; + union WTBL_UMAC_DW6 wtbl_d6; +}; + +struct wtbl_serial_num { + union WTBL_UMAC_DW0 wtbl_d0; + union WTBL_UMAC_DW1 wtbl_d1; + union WTBL_UMAC_DW2 wtbl_d2; + union WTBL_UMAC_DW3 wtbl_d3; + union WTBL_UMAC_DW4 wtbl_d4; +}; + +struct fwtbl_umac_struct { + struct wtbl_serial_num serial_no; + struct wtbl_keylink_amsdu klink_amsdu; + struct wtbl_key_tb key_tb; +}; + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +void asicConnac2xCapInit( + struct ADAPTER *prAdapter); +void asicConnac2xFillInitCmdTxd( + struct ADAPTER *prAdapter, + struct WIFI_CMD_INFO *prCmdInfo, + uint16_t *pu2BufInfoLen, + uint8_t *pucSeqNum, + void **pCmdBuf); +void asicConnac2xFillCmdTxd( + struct ADAPTER *prAdapter, + struct WIFI_CMD_INFO *prCmdInfo, + uint8_t *pucSeqNum, + void **pCmdBuf); + +#if defined(_HIF_PCIE) || defined(_HIF_AXI) +uint32_t asicConnac2xWfdmaCfgAddrGet( + struct GLUE_INFO *prGlueInfo, + u_int8_t ucDmaIdx); +uint32_t asicConnac2xWfdmaIntRstDtxPtrAddrGet( + struct GLUE_INFO *prGlueInfo, + u_int8_t ucDmaIdx); +uint32_t asicConnac2xWfdmaIntRstDrxPtrAddrGet( + struct GLUE_INFO *prGlueInfo, + u_int8_t ucDmaIdx); +uint32_t asicConnac2xWfdmaHifRstAddrGet( + struct GLUE_INFO *prGlueInfo, + u_int8_t ucDmaIdx); +void asicConnac2xWpdmaConfig( + struct GLUE_INFO *prGlueInfo, + uint8_t enable, + bool fgResetHif); +uint8_t asicConnac2xWfdmaWaitIdle( + struct GLUE_INFO *prGlueInfo, + uint8_t index, + uint32_t round, + uint32_t wait_us); +void asicConnac2xWfdmaTxRingExtCtrl( + struct GLUE_INFO *prGlueInfo, + struct RTMP_TX_RING *tx_ring, + uint32_t index); +void asicConnac2xWfdmaRxRingExtCtrl( + struct GLUE_INFO *prGlueInfo, + struct RTMP_RX_RING *rx_ring, + uint32_t index); +void asicConnac2xWfdmaManualPrefetch( + struct GLUE_INFO *prGlueInfo); +void asicConnac2xEnablePlatformIRQ( + struct ADAPTER *prAdapter); +void asicConnac2xDisablePlatformIRQ( + struct ADAPTER *prAdapter); +void asicConnac2xEnableExtInterrupt( + struct ADAPTER *prAdapter); +void asicConnac2xDisableExtInterrupt( + struct ADAPTER *prAdapter); +void asicConnac2xProcessTxInterrupt( + struct ADAPTER *prAdapter); +void asicConnac2xLowPowerOwnRead( + struct ADAPTER *prAdapter, + uint8_t *pfgResult); +void asicConnac2xLowPowerOwnSet( + struct ADAPTER *prAdapter, + uint8_t *pfgResult); +void asicConnac2xLowPowerOwnClear( + struct ADAPTER *prAdapter, + uint8_t *pfgResult); +void asicConnac2xProcessSoftwareInterrupt( + struct ADAPTER *prAdapter); +void asicConnac2xSoftwareInterruptMcu( + struct ADAPTER *prAdapter, u_int32_t intrBitMask); +void asicConnac2xHifRst( + struct GLUE_INFO *prGlueInfo); +void asicConnac2xReadExtIntStatus( + struct ADAPTER *prAdapter, + uint32_t *pu4IntStatus); +void asicConnac2xProcessRxInterrupt( + struct ADAPTER *prAdapter); +#endif /* _HIF_PCIE */ + +#if defined(_HIF_USB) +void asicConnac2xWfdmaInitForUSB( + struct ADAPTER *prAdapter, + struct mt66xx_chip_info *prChipInfo); +uint8_t asicConnac2xUsbEventEpDetected( + struct ADAPTER *prAdapter); +void asicConnac2xEnableUsbCmdTxRing( + struct ADAPTER *prAdapter, + u_int8_t ucDstRing); +#if CFG_ENABLE_FW_DOWNLOAD +void asicConnac2xEnableUsbFWDL( + struct ADAPTER *prAdapter, + u_int8_t fgEnable); +#endif /* CFG_ENABLE_FW_DOWNLOAD */ +u_int8_t asicConnac2xUsbResume(IN struct ADAPTER *prAdapter, + IN struct GLUE_INFO *prGlueInfo); +void asicConnac2xUdmaRxFlush( + struct ADAPTER *prAdapter, + u_int8_t bEnable); +uint16_t asicConnac2xUsbRxByteCount( + struct ADAPTER *prAdapter, + struct BUS_INFO *prBusInfo, + uint8_t *pRXD); +#endif /* _HIF_USB */ + +void fillConnac2xTxDescTxByteCount( + struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo, + void *prTxDesc); +void fillConnac2xTxDescAppendWithWaCpu( + struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo, + uint8_t *prTxDescBuffer); +void fillConnac2xTxDescAppendByWaCpu( + struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo, + uint16_t u4MsduId, + dma_addr_t rDmaAddr, + uint32_t u4Idx, + u_int8_t fgIsLast, + uint8_t *pucBuffer); +void fillTxDescTxByteCountWithWaCpu( + struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo, + void *prTxDesc); +void asicConnac2xInitTxdHook( + struct TX_DESC_OPS_T *prTxDescOps); +void asicConnac2xInitRxdHook( + struct RX_DESC_OPS_T *prRxDescOps); +#if (CFG_SUPPORT_MSP == 1) +void asicConnac2xRxProcessRxvforMSP(IN struct ADAPTER *prAdapter, + IN OUT struct SW_RFB *prRetSwRfb); +#endif /* CFG_SUPPORT_MSP == 1 */ +uint8_t asicConnac2xRxGetRcpiValueFromRxv( + IN uint8_t ucRcpiMode, + IN struct SW_RFB *prSwRfb); +#if (CFG_SUPPORT_PERF_IND == 1) +void asicConnac2xRxPerfIndProcessRXV(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, + IN uint8_t ucBssIndex); +#endif +void asicConnac2xWfdmaReInit( + struct ADAPTER *prAdapter); +void asicConnac2xWfdmaDummyCrWrite( + struct ADAPTER *prAdapter); + +#if (CFG_CHIP_RESET_SUPPORT == 1) && (CFG_WMT_RESET_API_SUPPORT == 0) +u_int8_t conn2_rst_L0_notify_step2(void); +#endif + +/******************************************************************************* +* D E B U G F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +uint32_t asic_connac2x_show_raw_wtbl_info( + struct GLUE_INFO *prGlueInfo, + int8_t *pcCommand, + int32_t i4TotalLen, + int32_t i4Argc, + int32_t idx); + +uint32_t dump_key_table( + struct GLUE_INFO *prGlueInfo, + int8_t *pcCommand, + int32_t i4TotalLen, + int16_t key_loc0, + int16_t key_loc1); + +char *asic_connac2x_hw_rate_ofdm_str( + u_int16_t ofdm_idx); + +char *asic_connac2x_fwtbl_hw_rate_str( + uint8_t mode, + uint16_t rate_idx); + +uint32_t asic_connac2x_show_txd_info( + struct ADAPTER *prAdapter, + int8_t *pcCommand, + int32_t i4TotalLen, + int32_t i4Argc, + int32_t idx); +uint32_t asic_connac2x_show_umac_wtbl_info( + struct ADAPTER *prAdapter, + int8_t *pcCommand, + int32_t i4TotalLen, + int32_t i4Argc, + int32_t idx); +u_int32_t asic_connac2x_show_rx_rate_info( + struct ADAPTER *prAdapter, + char *pcCommand, + int32_t i4TotalLen, + uint8_t ucStaIdx); +u_int32_t asic_connac2x_show_rx_rssi_info( + struct ADAPTER *prAdapter, + char *pcCommand, + int32_t i4TotalLen, + uint8_t ucStaIdx); +#endif /* CFG_SUPPORT_CONNAC2X == 1 */ +#endif /* _CMM_ASIC_CONNAC2X_H */ + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/mt7915/wf_cr_sw_def.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/mt7915/wf_cr_sw_def.h new file mode 100644 index 0000000000000000000000000000000000000000..135f260de081c57b19590213535a5fe5ccce0194 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/mt7915/wf_cr_sw_def.h @@ -0,0 +1,119 @@ +/* [File] : wf_cr_sw_def.h */ +/* [Copyright] : Copyright (C) 2018 Mediatek Incorportion. All rights reserved. +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +#ifndef _WF_CR_SW_DEF_H +#define _WF_CR_SW_DEF_H + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + + +/****************************************************************************** +* +* MCU_SYSRAM SW CR Definitions +* +****************************************************************************** +*/ +#define WF_SW_DEF_CR_BASE 0x0041F200 + +#define WF_SW_DEF_CR_WACPU_STAT_ADDR \ + (WF_SW_DEF_CR_BASE + 0x000) /* F200 */ +#define WF_SW_DEF_CR_WACPU_SLEEP_STAT_ADDR \ + (WF_SW_DEF_CR_BASE + 0x004) /* F204 */ +#define WF_SW_DEF_CR_WM2WA_ACTION_ADDR \ + (WF_SW_DEF_CR_BASE + 0x008) /* F208 */ +#define WF_SW_DEF_CR_WA2WM_ACTION_ADDR \ + (WF_SW_DEF_CR_BASE + 0x00C) /* F20C */ +#define WF_SW_DEF_CR_LP_DBG0_ADDR \ + (WF_SW_DEF_CR_BASE + 0x010) /* F210 */ +#define WF_SW_DEF_CR_LP_DBG1_ADDR \ + (WF_SW_DEF_CR_BASE + 0x014) /* F214 */ +#define WF_SW_DEF_CR_SER_STATUS_ADDR \ + (WF_SW_DEF_CR_BASE + 0x040) /* F240 */ +#define WF_SW_DEF_CR_PLE_STATUS_ADDR \ + (WF_SW_DEF_CR_BASE + 0x044) /* F244 */ +#define WF_SW_DEF_CR_PLE1_STATUS_ADDR \ + (WF_SW_DEF_CR_BASE + 0x048) /* F248 */ +#define WF_SW_DEF_CR_PLE_AMSDU_STATUS_ADDR \ + (WF_SW_DEF_CR_BASE + 0x04C) /* F24C */ +#define WF_SW_DEF_CR_PSE_STATUS_ADDR \ + (WF_SW_DEF_CR_BASE + 0x050) /* F250 */ +#define WF_SW_DEF_CR_PSE1_STATUS_ADDR \ + (WF_SW_DEF_CR_BASE + 0x054) /* F254 */ +#define WF_SW_DEF_CR_LAMC_WISR6_BN0_STATUS_ADDR \ + (WF_SW_DEF_CR_BASE + 0x058) /* F258 */ +#define WF_SW_DEF_CR_LAMC_WISR6_BN1_STATUS_ADDR \ + (WF_SW_DEF_CR_BASE + 0x05C) /* F25C */ +#define WF_SW_DEF_CR_LAMC_WISR7_BN0_STATUS_ADDR \ + (WF_SW_DEF_CR_BASE + 0x060) /* F260 */ +#define WF_SW_DEF_CR_LAMC_WISR7_BN1_STATUS_ADDR \ + (WF_SW_DEF_CR_BASE + 0x064) /* F264 */ +#define WF_SW_DEF_CR_USB_MCU_EVENT_ADD \ + (WF_SW_DEF_CR_BASE + 0x070) /* F270 */ +#define WF_SW_DEF_CR_USB_HOST_ACK_ADDR \ + (WF_SW_DEF_CR_BASE + 0x074) /* F274 */ + +/* +* ---WF_SW_DEF_CR_WACPU_SLEEP_STAT_ADDR (0x0041F200 + 0x004)--- +* SLEEP_STATUS[0] - (RW) 0: Awake, 1: sleep +* GATING_STATUS[1] - (RW) 0:Idle, 1: Gating +* RESERVED5[31..2] - (RO) Reserved bits +*/ +#define WF_SW_DEF_CR_WACPU_SLEEP_STAT_SLEEP_ADDR \ + WF_SW_DEF_CR_WACPU_SLEEP_STAT_ADDR +#define WF_SW_DEF_CR_WACPU_SLEEP_STAT_SLEEP_MASK 0x00000001 +#define WF_SW_DEF_CR_WACPU_SLEEP_STAT_SLEEP_SHFT 0 +#define WF_SW_DEF_CR_WACPU_SLEEP_STAT_GATING_ADDR \ + WF_SW_DEF_CR_WACPU_SLEEP_STAT_ADDR +#define WF_SW_DEF_CR_WACPU_SLEEP_STAT_GATING_MASK 0x00000002 +#define WF_SW_DEF_CR_WACPU_SLEEP_STAT_GATING_SHFT 1 + + +#endif /* _WF_CR_SW_DEF_H */ + + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/mt7915/wf_ple_top.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/mt7915/wf_ple_top.h new file mode 100644 index 0000000000000000000000000000000000000000..9529400319ebfbea37a8b46dab860e8eec18435a --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/mt7915/wf_ple_top.h @@ -0,0 +1,8757 @@ +/* [File] : wf_ple_top.h */ +/* [Revision time] : Mon Mar 18 15:00:44 2019 */ +/* [Description] : This file is auto generated by CODA */ +/* [Copyright] : Copyright (C) 2019 Mediatek Incorportion. All rights */ +/* reserved. */ + +#ifndef __WF_PLE_TOP_REGS_H__ +#define __WF_PLE_TOP_REGS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* ************************************************************************** */ +/* */ +/* WF_PLE_TOP CR Definitions */ +/* */ +/* ************************************************************************** */ + +#define WF_PLE_TOP_BASE 0x820C0000 + +#define WF_PLE_TOP_GC_ADDR (WF_PLE_TOP_BASE + 0x00) /* 0000 */ +#define WF_PLE_TOP_PBUF_CTRL_ADDR (WF_PLE_TOP_BASE + 0x14) /* 0014 */ +#define WF_PLE_TOP_TIMEOUT_CTRL_ADDR (WF_PLE_TOP_BASE + 0x1c) /* 001C */ +#define WF_PLE_TOP_INT_N9_EN_MASK_ADDR (WF_PLE_TOP_BASE + 0x20) /* 0020 */ +#define WF_PLE_TOP_INT_N9_STS_ADDR (WF_PLE_TOP_BASE + 0x24) /* 0024 */ +#define WF_PLE_TOP_INT_N9_ERR_STS_ADDR (WF_PLE_TOP_BASE + 0x28) /* 0028 */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_ADDR (WF_PLE_TOP_BASE + 0x2C) /* 002C */ +#define WF_PLE_TOP_HOST_REPORT0_ADDR (WF_PLE_TOP_BASE + 0x30) /* 0030 */ +#define WF_PLE_TOP_HOST_REPORT1_ADDR (WF_PLE_TOP_BASE + 0x34) /* 0034 */ +#define WF_PLE_TOP_HOST_REPORT2_ADDR (WF_PLE_TOP_BASE + 0x38) /* 0038 */ +#define WF_PLE_TOP_BLK_MODE_RATE_LMT_ADDR (WF_PLE_TOP_BASE + 0x3c) /* 003C */ +#define WF_PLE_TOP_C_GET_FID_0_ADDR (WF_PLE_TOP_BASE + 0x40) /* 0040 */ +#define WF_PLE_TOP_C_GET_FID_1_ADDR (WF_PLE_TOP_BASE + 0x44) /* 0044 */ +#define WF_PLE_TOP_RELEASE_CTRL_0_ADDR (WF_PLE_TOP_BASE + 0x50) /* 0050 */ +#define WF_PLE_TOP_RELEASE_CTRL_1_ADDR (WF_PLE_TOP_BASE + 0x54) /* 0054 */ +#define WF_PLE_TOP_RELEASE_CTRL_2_ADDR (WF_PLE_TOP_BASE + 0x58) /* 0058 */ +#define WF_PLE_TOP_RELEASE_CTRL_3_ADDR (WF_PLE_TOP_BASE + 0x5c) /* 005C */ +#define WF_PLE_TOP_C_EN_QUEUE_0_ADDR (WF_PLE_TOP_BASE + 0x60) /* 0060 */ +#define WF_PLE_TOP_C_EN_QUEUE_1_ADDR (WF_PLE_TOP_BASE + 0x64) /* 0064 */ +#define WF_PLE_TOP_C_EN_QUEUE_2_ADDR (WF_PLE_TOP_BASE + 0x68) /* 0068 */ +#define WF_PLE_TOP_C_DE_QUEUE_0_ADDR (WF_PLE_TOP_BASE + 0x80) /* 0080 */ +#define WF_PLE_TOP_C_DE_QUEUE_1_ADDR (WF_PLE_TOP_BASE + 0x84) /* 0084 */ +#define WF_PLE_TOP_C_DE_QUEUE_2_ADDR (WF_PLE_TOP_BASE + 0x88) /* 0088 */ +#define WF_PLE_TOP_C_DE_QUEUE_3_ADDR (WF_PLE_TOP_BASE + 0x8c) /* 008C */ +#define WF_PLE_TOP_C_DE_QUEUE_4_ADDR (WF_PLE_TOP_BASE + 0x90) /* 0090 */ +#define WF_PLE_TOP_ALLOCATE_0_ADDR (WF_PLE_TOP_BASE + 0xA0) /* 00A0 */ +#define WF_PLE_TOP_ALLOCATE_1_ADDR (WF_PLE_TOP_BASE + 0xA4) /* 00A4 */ +#define WF_PLE_TOP_ALLOCATE_2_ADDR (WF_PLE_TOP_BASE + 0xA8) /* 00A8 */ +#define WF_PLE_TOP_QUEUE_EMPTY_ADDR (WF_PLE_TOP_BASE + 0xB0) /* 00B0 */ +#define WF_PLE_TOP_FREEPG_START_END_ADDR (WF_PLE_TOP_BASE + 0xc0) /* 00C0 */ +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_ADDR (WF_PLE_TOP_BASE + 0xc4)/* 00C4 */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR (WF_PLE_TOP_BASE + 0xd8) /* 00D8 */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR (WF_PLE_TOP_BASE + 0xdc) /* 00DC */ +#define WF_PLE_TOP_TO_N9_INT_ADDR (WF_PLE_TOP_BASE + 0xf0) /* 00F0 */ +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_ADDR (WF_PLE_TOP_BASE + 0xf4)/* 00F4 */ +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_ADDR (WF_PLE_TOP_BASE + 0xf8) /* 00F8 */ +#define WF_PLE_TOP_FREEPG_CNT_ADDR (WF_PLE_TOP_BASE + 0x100) /* 0100 */ +#define WF_PLE_TOP_FREEPG_HEAD_TAIL_ADDR (WF_PLE_TOP_BASE + 0x104) /* 0104 */ +#define WF_PLE_TOP_PG_HIF_GROUP_ADDR (WF_PLE_TOP_BASE + 0x110) /* 0110 */ +#define WF_PLE_TOP_HIF_PG_INFO_ADDR (WF_PLE_TOP_BASE + 0x114) /* 0114 */ +#define WF_PLE_TOP_PG_HIF_WMTXD_GROUP_ADDR (WF_PLE_TOP_BASE + 0x118) /* 0118 \ + */ +#define WF_PLE_TOP_HIF_WMTXD_PG_INFO_ADDR (WF_PLE_TOP_BASE + 0x11C)/* 011C */ +#define WF_PLE_TOP_PG_HIF_TXCMD_GROUP_ADDR (WF_PLE_TOP_BASE + 0x120) /* 0120 \ + */ +#define WF_PLE_TOP_HIF_TXCMD_PG_INFO_ADDR (WF_PLE_TOP_BASE + 0x124)/* 0124 */ +#define WF_PLE_TOP_TWT_TX_CTRL0_ADDR (WF_PLE_TOP_BASE + 0x130) /* 0130 */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_ADDR (WF_PLE_TOP_BASE + 0x140) /* 0140 */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_1_ADDR (WF_PLE_TOP_BASE + 0x144) /* 0144 */ +#define WF_PLE_TOP_PG_CPU_GROUP_ADDR (WF_PLE_TOP_BASE + 0x150) /* 0150 */ +#define WF_PLE_TOP_CPU_PG_INFO_ADDR (WF_PLE_TOP_BASE + 0x154) /* 0154 */ +#define WF_PLE_TOP_PLE_LOG_0_ADDR (WF_PLE_TOP_BASE + 0x170) /* 0170 */ +#define WF_PLE_TOP_PLE_LOG_1_ADDR (WF_PLE_TOP_BASE + 0x174) /* 0174 */ +#define WF_PLE_TOP_PLE_LOG_2_ADDR (WF_PLE_TOP_BASE + 0x178) /* 0178 */ +#define WF_PLE_TOP_PLE_LOG_3_ADDR (WF_PLE_TOP_BASE + 0x17c) /* 017C */ +#define WF_PLE_TOP_WMMAC_PGCNT_0_ADDR (WF_PLE_TOP_BASE + 0x180) /* 0180 */ +#define WF_PLE_TOP_WMMAC_PGCNT_1_ADDR (WF_PLE_TOP_BASE + 0x184) /* 0184 */ +#define WF_PLE_TOP_WMMAC_PGCNT_2_ADDR (WF_PLE_TOP_BASE + 0x188) /* 0188 */ +#define WF_PLE_TOP_WMMAC_PGCNT_3_ADDR (WF_PLE_TOP_BASE + 0x18c) /* 018C */ +#define WF_PLE_TOP_WMMAC_PGCNT_4_ADDR (WF_PLE_TOP_BASE + 0x190) /* 0190 */ +#define WF_PLE_TOP_WMMAC_PGCNT_5_ADDR (WF_PLE_TOP_BASE + 0x194) /* 0194 */ +#define WF_PLE_TOP_WMMAC_PGCNT_6_ADDR (WF_PLE_TOP_BASE + 0x198) /* 0198 */ +#define WF_PLE_TOP_WMMAC_PGCNT_7_ADDR (WF_PLE_TOP_BASE + 0x19c) /* 019C */ +#define WF_PLE_TOP_RL_BUF_CTRL_0_ADDR (WF_PLE_TOP_BASE + 0x1A0) /* 01A0 */ +#define WF_PLE_TOP_RL_BUF_CTRL_1_ADDR (WF_PLE_TOP_BASE + 0x1A4) /* 01A4 */ +#define WF_PLE_TOP_FL_QUE_CTRL_0_ADDR (WF_PLE_TOP_BASE + 0x1B0) /* 01B0 */ +#define WF_PLE_TOP_FL_QUE_CTRL_1_ADDR (WF_PLE_TOP_BASE + 0x1B4) /* 01B4 */ +#define WF_PLE_TOP_FL_QUE_CTRL_2_ADDR (WF_PLE_TOP_BASE + 0x1B8) /* 01B8 */ +#define WF_PLE_TOP_FL_QUE_CTRL_3_ADDR (WF_PLE_TOP_BASE + 0x1BC) /* 01BC */ +#define WF_PLE_TOP_PL_QUE_CTRL_0_ADDR (WF_PLE_TOP_BASE + 0x1C0) /* 01C0 */ +#define WF_PLE_TOP_PLE_DELAY_TX_CTRL_ADDR (WF_PLE_TOP_BASE + 0x1d0)/* 01D0 */ +#define WF_PLE_TOP_PLE_STATION_REDIR_CTRL_ADDR \ +(WF_PLE_TOP_BASE + 0x1d4) /* 01D4 */ +#define WF_PLE_TOP_MACTX_LENGTH_LIMIT_ADDR (WF_PLE_TOP_BASE + 0x1ec) /* 01EC \ + */ +#define WF_PLE_TOP_HIF_ENQ_PKT_NUM_ADDR (WF_PLE_TOP_BASE + 0x1f0) /* 01F0 */ +#define WF_PLE_TOP_CPU_ENQ_PKT_NUM_ADDR (WF_PLE_TOP_BASE + 0x1f4) /* 01F4 */ +#define WF_PLE_TOP_RLS_MSDU_PKT_NUM_ADDR (WF_PLE_TOP_BASE + 0x1f8) /* 01F8 */ +#define WF_PLE_TOP_HOST_REPORT_NUM_ADDR (WF_PLE_TOP_BASE + 0x1fc) /* 01FC */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR (WF_PLE_TOP_BASE + 0x220) /* 0220 */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_ADDR (WF_PLE_TOP_BASE + 0x224) /* 0224 */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR \ +(WF_PLE_TOP_BASE + 0x228) /* 0228 */ +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_ADDR \ +(WF_PLE_TOP_BASE + 0x22c) /* 022C */ +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_ADDR (WF_PLE_TOP_BASE + 0x230) /* 0230 */ +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_ADDR (WF_PLE_TOP_BASE + 0x234) /* 0234 */ +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_ADDR (WF_PLE_TOP_BASE + 0x238) /* 0238\ + */ +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_ADDR \ +(WF_PLE_TOP_BASE + 0x23c) /* 023C */ +#define WF_PLE_TOP_UMAC_DBG_CTRL_ADDR (WF_PLE_TOP_BASE + 0x240) /* 0240 */ +#define WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_ADDR (WF_PLE_TOP_BASE + 0x244)/* 0244\ + */ +#define WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_ADDR (WF_PLE_TOP_BASE + 0x248)/* 0248\ + */ +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_ADDR (WF_PLE_TOP_BASE + 0x24C) /* 024C */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR (WF_PLE_TOP_BASE + 0x250) /* 0250 */ +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_1_ADDR (WF_PLE_TOP_BASE + 0x258)/* 0258\ + */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_ADDR (WF_PLE_TOP_BASE + 0x25C) /* 025C */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL9_ADDR (WF_PLE_TOP_BASE + 0x260)/* 0260\ + */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL10_ADDR (WF_PLE_TOP_BASE + 0x264) /* 0264\ + */ +#define WF_PLE_TOP_FUNC_ACT_CNT_0_ADDR (WF_PLE_TOP_BASE + 0x280) /* 0280 */ +#define WF_PLE_TOP_FUNC_ACT_CNT_1_ADDR (WF_PLE_TOP_BASE + 0x284) /* 0284 */ +#define WF_PLE_TOP_PORT_SER_CTRL_ADDR (WF_PLE_TOP_BASE + 0x2A0) /* 02A0 */ +#define WF_PLE_TOP_MACTX_SER_CTRL_ADDR (WF_PLE_TOP_BASE + 0x2A4) /* 02A4 */ +#define WF_PLE_TOP_DRR_SER_CTRL_ADDR (WF_PLE_TOP_BASE + 0x2A8) /* 02A8 */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL5_ADDR (WF_PLE_TOP_BASE + 0x2c0)/* 02C0\ + */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL6_ADDR (WF_PLE_TOP_BASE + 0x2c4)/* 02C4\ + */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL7_ADDR (WF_PLE_TOP_BASE + 0x2c8)/* 02C8\ + */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL8_ADDR (WF_PLE_TOP_BASE + 0x2cc)/* 02CC\ + */ +#define WF_PLE_TOP_SRAM_MBIST_BACKGROUND_ADDR \ +(WF_PLE_TOP_BASE + 0x2d0) /* 02D0 */ +#define WF_PLE_TOP_SRAM_MBIST_BSEL_ADDR (WF_PLE_TOP_BASE + 0x2d4) /* 02D4 */ +#define WF_PLE_TOP_SRAM_MBIST_DONE_ADDR (WF_PLE_TOP_BASE + 0x2d8) /* 02D8 */ +#define WF_PLE_TOP_SRAM_MBIST_FAIL_ADDR (WF_PLE_TOP_BASE + 0x2dc) /* 02DC */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR (WF_PLE_TOP_BASE + 0x2e0) /* 02E0 */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL1_ADDR (WF_PLE_TOP_BASE + 0x2e4) /* 02E4 \ + */ +#define WF_PLE_TOP_BSS_DBDC_CTRL_ADDR (WF_PLE_TOP_BASE + 0x2ec) /* 02EC */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL2_ADDR (WF_PLE_TOP_BASE + 0x2f0) /* 02F0 \ + */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL3_ADDR (WF_PLE_TOP_BASE + 0x2f4) /* 02F4 \ + */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL4_ADDR (WF_PLE_TOP_BASE + 0x2f8) /* 02F8 \ + */ +#define WF_PLE_TOP_SRAM_AWT_HDEN_CTRL_ADDR (WF_PLE_TOP_BASE + 0x2fc) /* 02FC \ + */ +#define WF_PLE_TOP_PREDL_CTRL_ADDR (WF_PLE_TOP_BASE + 0x300) /* 0300 */ +#define WF_PLE_TOP_PREDL_CTRL1_ADDR (WF_PLE_TOP_BASE + 0x304) /* 0304 */ +#define WF_PLE_TOP_PREDL_BN0_LEN0_ADDR (WF_PLE_TOP_BASE + 0x330) /* 0330 */ +#define WF_PLE_TOP_PREDL_BN0_LEN1_ADDR (WF_PLE_TOP_BASE + 0x334) /* 0334 */ +#define WF_PLE_TOP_PREDL_BN1_LEN0_ADDR (WF_PLE_TOP_BASE + 0x338) /* 0338 */ +#define WF_PLE_TOP_PREDL_BN1_LEN1_ADDR (WF_PLE_TOP_BASE + 0x33c) /* 033C */ +#define WF_PLE_TOP_DRR_TABLE_WDATA0_ADDR (WF_PLE_TOP_BASE + 0x340) /* 0340 */ +#define WF_PLE_TOP_DRR_TABLE_WDATA1_ADDR (WF_PLE_TOP_BASE + 0x344) /* 0344 */ +#define WF_PLE_TOP_DRR_TABLE_WDATA2_ADDR (WF_PLE_TOP_BASE + 0x348) /* 0348 */ +#define WF_PLE_TOP_DRR_TABLE_WDATA3_ADDR (WF_PLE_TOP_BASE + 0x34c) /* 034C */ +#define WF_PLE_TOP_DRR_TABLE_RDATA0_ADDR (WF_PLE_TOP_BASE + 0x350) /* 0350 */ +#define WF_PLE_TOP_DRR_TABLE_RDATA1_ADDR (WF_PLE_TOP_BASE + 0x354) /* 0354 */ +#define WF_PLE_TOP_DRR_TABLE_RDATA2_ADDR (WF_PLE_TOP_BASE + 0x358) /* 0358 */ +#define WF_PLE_TOP_DRR_TABLE_RDATA3_ADDR (WF_PLE_TOP_BASE + 0x35c) /* 035C */ +#define WF_PLE_TOP_ERLY_TRM_CTRL0_ADDR (WF_PLE_TOP_BASE + 0x360) /* 0360 */ +#define WF_PLE_TOP_ERLY_TRM_CTRL1_ADDR (WF_PLE_TOP_BASE + 0x364) /* 0364 */ +#define WF_PLE_TOP_VOW_CONTROL_ADDR (WF_PLE_TOP_BASE + 0x370) /* 0370 */ +#define WF_PLE_TOP_AIRTIME_DRR_SIZE_ADDR (WF_PLE_TOP_BASE + 0x374) /* 0374 */ +#define WF_PLE_TOP_CHECK_BW_TIME_TOKEN__ADDR \ +(WF_PLE_TOP_BASE + 0x378) /* 0378 */ +#define WF_PLE_TOP_CHECK_BW_LENGTH_TOKEN__ADDR \ +(WF_PLE_TOP_BASE + 0x37c) /* 037C */ +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_ADDR \ +(WF_PLE_TOP_BASE + 0x380) /* 0380 */ +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_ADDR \ +(WF_PLE_TOP_BASE + 0x384) /* 0384 */ +#define WF_PLE_TOP_DRR_TABLE_CTRL_ADDR (WF_PLE_TOP_BASE + 0x388) /* 0388 */ +#define WF_PLE_TOP_VOW_CTRL1_ADDR (WF_PLE_TOP_BASE + 0x38C) /* 038C */ +#define WF_PLE_TOP_DRR_CHNL_EMPTY_ADDR (WF_PLE_TOP_BASE + 0x390) /* 0390 */ +#define WF_PLE_TOP_DRR_SPL_CTRL_ADDR (WF_PLE_TOP_BASE + 0x394) /* 0394 */ +#define WF_PLE_TOP_DRR_SPL_CTRL_1_ADDR (WF_PLE_TOP_BASE + 0x398) /* 0398 */ +#define WF_PLE_TOP_VOW_DBG_SEL_ADDR (WF_PLE_TOP_BASE + 0x3A0) /* 03A0 */ +#define WF_PLE_TOP_AIRTIME_DBG_INFO0_ADDR (WF_PLE_TOP_BASE + 0x3A4) /* 03A4 */ +#define WF_PLE_TOP_AIRTIME_DBG_INFO1_ADDR (WF_PLE_TOP_BASE + 0x3A8) /* 03A8 */ +#define WF_PLE_TOP_BW_DBG_INFO_ADDR (WF_PLE_TOP_BASE + 0x3AC) /* 03AC */ +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING0_ADDR \ +(WF_PLE_TOP_BASE + 0x3B0) /* 03B0 */ +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING1_ADDR \ +(WF_PLE_TOP_BASE + 0x3B4) /* 03B4 */ +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING2_ADDR \ +(WF_PLE_TOP_BASE + 0x3B8) /* 03B8 */ +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING3_ADDR \ +(WF_PLE_TOP_BASE + 0x3bc) /* 03BC */ +#define WF_PLE_TOP_DRR_SW_CTRL_ADDR (WF_PLE_TOP_BASE + 0x3C8) /* 03C8 */ +#define WF_PLE_TOP_DRR_HW_SRCHCMD_FULL_ADDR (WF_PLE_TOP_BASE + 0x3CC) /* 03CC\ + */ +#define WF_PLE_TOP_STATION_PAUSE0_ADDR (WF_PLE_TOP_BASE + 0x400) /* 0400 */ +#define WF_PLE_TOP_STATION_PAUSE1_ADDR (WF_PLE_TOP_BASE + 0x404) /* 0404 */ +#define WF_PLE_TOP_STATION_PAUSE2_ADDR (WF_PLE_TOP_BASE + 0x408) /* 0408 */ +#define WF_PLE_TOP_STATION_PAUSE3_ADDR (WF_PLE_TOP_BASE + 0x40c) /* 040C */ +#define WF_PLE_TOP_STATION_PAUSE4_ADDR (WF_PLE_TOP_BASE + 0x410) /* 0410 */ +#define WF_PLE_TOP_STATION_PAUSE5_ADDR (WF_PLE_TOP_BASE + 0x414) /* 0414 */ +#define WF_PLE_TOP_STATION_PAUSE6_ADDR (WF_PLE_TOP_BASE + 0x418) /* 0418 */ +#define WF_PLE_TOP_STATION_PAUSE7_ADDR (WF_PLE_TOP_BASE + 0x41c) /* 041C */ +#define WF_PLE_TOP_STATION_PAUSE8_ADDR (WF_PLE_TOP_BASE + 0x420) /* 0420 */ +#define WF_PLE_TOP_DIS_STA_MAP0_ADDR (WF_PLE_TOP_BASE + 0x440) /* 0440 */ +#define WF_PLE_TOP_DIS_STA_MAP1_ADDR (WF_PLE_TOP_BASE + 0x444) /* 0444 */ +#define WF_PLE_TOP_DIS_STA_MAP2_ADDR (WF_PLE_TOP_BASE + 0x448) /* 0448 */ +#define WF_PLE_TOP_DIS_STA_MAP3_ADDR (WF_PLE_TOP_BASE + 0x44c) /* 044C */ +#define WF_PLE_TOP_DIS_STA_MAP4_ADDR (WF_PLE_TOP_BASE + 0x450) /* 0450 */ +#define WF_PLE_TOP_DIS_STA_MAP5_ADDR (WF_PLE_TOP_BASE + 0x454) /* 0454 */ +#define WF_PLE_TOP_DIS_STA_MAP6_ADDR (WF_PLE_TOP_BASE + 0x458) /* 0458 */ +#define WF_PLE_TOP_DIS_STA_MAP7_ADDR (WF_PLE_TOP_BASE + 0x45c) /* 045C */ +#define WF_PLE_TOP_DIS_STA_MAP8_ADDR (WF_PLE_TOP_BASE + 0x460) /* 0460 */ +#define WF_PLE_TOP_STATION_REDIR0_ADDR (WF_PLE_TOP_BASE + 0x480) /* 0480 */ +#define WF_PLE_TOP_STATION_REDIR1_ADDR (WF_PLE_TOP_BASE + 0x484) /* 0484 */ +#define WF_PLE_TOP_STATION_REDIR2_ADDR (WF_PLE_TOP_BASE + 0x488) /* 0488 */ +#define WF_PLE_TOP_STATION_REDIR3_ADDR (WF_PLE_TOP_BASE + 0x48c) /* 048C */ +#define WF_PLE_TOP_STATION_REDIR4_ADDR (WF_PLE_TOP_BASE + 0x490) /* 0490 */ +#define WF_PLE_TOP_STATION_REDIR5_ADDR (WF_PLE_TOP_BASE + 0x494) /* 0494 */ +#define WF_PLE_TOP_STATION_REDIR6_ADDR (WF_PLE_TOP_BASE + 0x498) /* 0498 */ +#define WF_PLE_TOP_STATION_REDIR7_ADDR (WF_PLE_TOP_BASE + 0x49c) /* 049C */ +#define WF_PLE_TOP_STATION_REDIR8_ADDR (WF_PLE_TOP_BASE + 0x4a0) /* 04A0 */ +#define WF_PLE_TOP_TWT_STA_MAP0_ADDR (WF_PLE_TOP_BASE + 0x4c0) /* 04C0 */ +#define WF_PLE_TOP_TWT_STA_MAP1_ADDR (WF_PLE_TOP_BASE + 0x4c4) /* 04C4 */ +#define WF_PLE_TOP_TWT_STA_MAP2_ADDR (WF_PLE_TOP_BASE + 0x4c8) /* 04C8 */ +#define WF_PLE_TOP_TWT_STA_MAP3_ADDR (WF_PLE_TOP_BASE + 0x4cc) /* 04CC */ +#define WF_PLE_TOP_TWT_STA_MAP4_ADDR (WF_PLE_TOP_BASE + 0x4d0) /* 04D0 */ +#define WF_PLE_TOP_TWT_STA_MAP5_ADDR (WF_PLE_TOP_BASE + 0x4d4) /* 04D4 */ +#define WF_PLE_TOP_TWT_STA_MAP6_ADDR (WF_PLE_TOP_BASE + 0x4d8) /* 04D8 */ +#define WF_PLE_TOP_TWT_STA_MAP7_ADDR (WF_PLE_TOP_BASE + 0x4dc) /* 04DC */ +#define WF_PLE_TOP_TWT_STA_MAP8_ADDR (WF_PLE_TOP_BASE + 0x4e0) /* 04E0 */ +#define WF_PLE_TOP_AC0_QUEUE_EMPTY0_ADDR (WF_PLE_TOP_BASE + 0x500) /* 0500 */ +#define WF_PLE_TOP_AC0_QUEUE_EMPTY1_ADDR (WF_PLE_TOP_BASE + 0x504) /* 0504 */ +#define WF_PLE_TOP_AC0_QUEUE_EMPTY2_ADDR (WF_PLE_TOP_BASE + 0x508) /* 0508 */ +#define WF_PLE_TOP_AC0_QUEUE_EMPTY3_ADDR (WF_PLE_TOP_BASE + 0x50c) /* 050C */ +#define WF_PLE_TOP_AC0_QUEUE_EMPTY4_ADDR (WF_PLE_TOP_BASE + 0x510) /* 0510 */ +#define WF_PLE_TOP_AC0_QUEUE_EMPTY5_ADDR (WF_PLE_TOP_BASE + 0x514) /* 0514 */ +#define WF_PLE_TOP_AC0_QUEUE_EMPTY6_ADDR (WF_PLE_TOP_BASE + 0x518) /* 0518 */ +#define WF_PLE_TOP_AC0_QUEUE_EMPTY7_ADDR (WF_PLE_TOP_BASE + 0x51c) /* 051C */ +#define WF_PLE_TOP_AC0_QUEUE_EMPTY8_ADDR (WF_PLE_TOP_BASE + 0x520) /* 0520 */ +#define WF_PLE_TOP_AC1_QUEUE_EMPTY0_ADDR (WF_PLE_TOP_BASE + 0x540) /* 0540 */ +#define WF_PLE_TOP_AC1_QUEUE_EMPTY1_ADDR (WF_PLE_TOP_BASE + 0x544) /* 0544 */ +#define WF_PLE_TOP_AC1_QUEUE_EMPTY2_ADDR (WF_PLE_TOP_BASE + 0x548) /* 0548 */ +#define WF_PLE_TOP_AC1_QUEUE_EMPTY3_ADDR (WF_PLE_TOP_BASE + 0x54c) /* 054C */ +#define WF_PLE_TOP_AC1_QUEUE_EMPTY4_ADDR (WF_PLE_TOP_BASE + 0x550) /* 0550 */ +#define WF_PLE_TOP_AC1_QUEUE_EMPTY5_ADDR (WF_PLE_TOP_BASE + 0x554) /* 0554 */ +#define WF_PLE_TOP_AC1_QUEUE_EMPTY6_ADDR (WF_PLE_TOP_BASE + 0x558) /* 0558 */ +#define WF_PLE_TOP_AC1_QUEUE_EMPTY7_ADDR (WF_PLE_TOP_BASE + 0x55c) /* 055C */ +#define WF_PLE_TOP_AC1_QUEUE_EMPTY8_ADDR (WF_PLE_TOP_BASE + 0x560) /* 0560 */ +#define WF_PLE_TOP_AC2_QUEUE_EMPTY0_ADDR (WF_PLE_TOP_BASE + 0x580) /* 0580 */ +#define WF_PLE_TOP_AC2_QUEUE_EMPTY1_ADDR (WF_PLE_TOP_BASE + 0x584) /* 0584 */ +#define WF_PLE_TOP_AC2_QUEUE_EMPTY2_ADDR (WF_PLE_TOP_BASE + 0x588) /* 0588 */ +#define WF_PLE_TOP_AC2_QUEUE_EMPTY3_ADDR (WF_PLE_TOP_BASE + 0x58c) /* 058C */ +#define WF_PLE_TOP_AC2_QUEUE_EMPTY4_ADDR (WF_PLE_TOP_BASE + 0x590) /* 0590 */ +#define WF_PLE_TOP_AC2_QUEUE_EMPTY5_ADDR (WF_PLE_TOP_BASE + 0x594) /* 0594 */ +#define WF_PLE_TOP_AC2_QUEUE_EMPTY6_ADDR (WF_PLE_TOP_BASE + 0x598) /* 0598 */ +#define WF_PLE_TOP_AC2_QUEUE_EMPTY7_ADDR (WF_PLE_TOP_BASE + 0x59c) /* 059C */ +#define WF_PLE_TOP_AC2_QUEUE_EMPTY8_ADDR (WF_PLE_TOP_BASE + 0x5a0) /* 05A0 */ +#define WF_PLE_TOP_AC3_QUEUE_EMPTY0_ADDR (WF_PLE_TOP_BASE + 0x5c0) /* 05C0 */ +#define WF_PLE_TOP_AC3_QUEUE_EMPTY1_ADDR (WF_PLE_TOP_BASE + 0x5c4) /* 05C4 */ +#define WF_PLE_TOP_AC3_QUEUE_EMPTY2_ADDR (WF_PLE_TOP_BASE + 0x5c8) /* 05C8 */ +#define WF_PLE_TOP_AC3_QUEUE_EMPTY3_ADDR (WF_PLE_TOP_BASE + 0x5cc) /* 05CC */ +#define WF_PLE_TOP_AC3_QUEUE_EMPTY4_ADDR (WF_PLE_TOP_BASE + 0x5d0) /* 05D0 */ +#define WF_PLE_TOP_AC3_QUEUE_EMPTY5_ADDR (WF_PLE_TOP_BASE + 0x5d4) /* 05D4 */ +#define WF_PLE_TOP_AC3_QUEUE_EMPTY6_ADDR (WF_PLE_TOP_BASE + 0x5d8) /* 05D8 */ +#define WF_PLE_TOP_AC3_QUEUE_EMPTY7_ADDR (WF_PLE_TOP_BASE + 0x5dc) /* 05DC */ +#define WF_PLE_TOP_AC3_QUEUE_EMPTY8_ADDR (WF_PLE_TOP_BASE + 0x5e0) /* 05E0 */ +#define WF_PLE_TOP_DRR_TABLE_WDATA4_ADDR (WF_PLE_TOP_BASE + 0x680) /* 0680 */ +#define WF_PLE_TOP_DRR_TABLE_WDATA5_ADDR (WF_PLE_TOP_BASE + 0x684) /* 0684 */ +#define WF_PLE_TOP_DRR_TABLE_WDATA6_ADDR (WF_PLE_TOP_BASE + 0x688) /* 0688 */ +#define WF_PLE_TOP_DRR_TABLE_WDATA7_ADDR (WF_PLE_TOP_BASE + 0x68c) /* 068C */ +#define WF_PLE_TOP_DRR_TABLE_RDATA4_ADDR (WF_PLE_TOP_BASE + 0x690) /* 0690 */ +#define WF_PLE_TOP_DRR_TABLE_RDATA5_ADDR (WF_PLE_TOP_BASE + 0x694) /* 0694 */ +#define WF_PLE_TOP_DRR_TABLE_RDATA6_ADDR (WF_PLE_TOP_BASE + 0x698) /* 0698 */ +#define WF_PLE_TOP_DRR_TABLE_RDATA7_ADDR (WF_PLE_TOP_BASE + 0x69c) /* 069C */ +#define WF_PLE_TOP_TWT_STA_TABLE0_ADDR (WF_PLE_TOP_BASE + 0x6a0) /* 06A0 */ +#define WF_PLE_TOP_TWT_STA_TABLE1_ADDR (WF_PLE_TOP_BASE + 0x6a4) /* 06A4 */ +#define WF_PLE_TOP_TWT_STA_TABLE2_ADDR (WF_PLE_TOP_BASE + 0x6a8) /* 06A8 */ +#define WF_PLE_TOP_TWT_STA_TABLE3_ADDR (WF_PLE_TOP_BASE + 0x6ac) /* 06AC */ +#define WF_PLE_TOP_TWT_SW_CTRL_ADDR (WF_PLE_TOP_BASE + 0x6b0) /* 06B0 */ +#define WF_PLE_TOP_TWT_DBG_ADDR (WF_PLE_TOP_BASE + 0x6b4) /* 06B4 */ +#define WF_PLE_TOP_TWT_HW_SRCHCMD_FULL_ADDR (WF_PLE_TOP_BASE + 0x6b8) /* 06B8\ + */ +#define WF_PLE_TOP_SPL_GEN_CTRL_ADDR (WF_PLE_TOP_BASE + 0x700) /* 0700 */ +#define WF_PLE_TOP_AMSDU_GC_ADDR (WF_PLE_TOP_BASE + 0x1000) /* 1000 */ +#define WF_PLE_TOP_AMSDU_TXD_COMP_MAP_0_ADDR \ +(WF_PLE_TOP_BASE + 0x1004) /* 1004 */ +#define WF_PLE_TOP_AMSDU_TXD_COMP_MAP_1_ADDR \ +(WF_PLE_TOP_BASE + 0x1008) /* 1008 */ +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_ADDR \ +(WF_PLE_TOP_BASE + 0x1028) /* 1028 */ +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_ADDR \ +(WF_PLE_TOP_BASE + 0x102C) /* 102C */ +#define WF_PLE_TOP_AMSDU_PEEK_CR_00_ADDR (WF_PLE_TOP_BASE + 0x10d0) /* 10D0 */ +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_ADDR (WF_PLE_TOP_BASE + 0x10d4) /* 10D4 */ +#define WF_PLE_TOP_AMSDU_PACK_1_MSDU_CNT_ADDR \ +(WF_PLE_TOP_BASE + 0x10e0) /* 10E0 */ +#define WF_PLE_TOP_AMSDU_PACK_2_MSDU_CNT_ADDR \ +(WF_PLE_TOP_BASE + 0x10e4) /* 10E4 */ +#define WF_PLE_TOP_AMSDU_PACK_3_MSDU_CNT_ADDR \ +(WF_PLE_TOP_BASE + 0x10e8) /* 10E8 */ +#define WF_PLE_TOP_AMSDU_PACK_4_MSDU_CNT_ADDR \ +(WF_PLE_TOP_BASE + 0x10ec) /* 10EC */ +#define WF_PLE_TOP_AMSDU_PACK_5_MSDU_CNT_ADDR \ +(WF_PLE_TOP_BASE + 0x10f0) /* 10F0 */ +#define WF_PLE_TOP_AMSDU_PACK_6_MSDU_CNT_ADDR \ +(WF_PLE_TOP_BASE + 0x10f4) /* 10F4 */ +#define WF_PLE_TOP_AMSDU_PACK_7_MSDU_CNT_ADDR \ +(WF_PLE_TOP_BASE + 0x10f8) /* 10F8 */ +#define WF_PLE_TOP_AMSDU_PACK_8_MSDU_CNT_ADDR \ +(WF_PLE_TOP_BASE + 0x10fc) /* 10FC */ +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY0_ADDR \ +(WF_PLE_TOP_BASE + 0x1100) /* 1100 */ +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY1_ADDR \ +(WF_PLE_TOP_BASE + 0x1104) /* 1104 */ +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY2_ADDR \ +(WF_PLE_TOP_BASE + 0x1108) /* 1108 */ +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY3_ADDR \ +(WF_PLE_TOP_BASE + 0x110C) /* 110C */ +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY4_ADDR \ +(WF_PLE_TOP_BASE + 0x1110) /* 1110 */ +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY5_ADDR \ +(WF_PLE_TOP_BASE + 0x1114) /* 1114 */ +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY6_ADDR \ +(WF_PLE_TOP_BASE + 0x1118) /* 1118 */ +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY7_ADDR \ +(WF_PLE_TOP_BASE + 0x111c) /* 111C */ +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY8_ADDR \ +(WF_PLE_TOP_BASE + 0x1120) /* 1120 */ +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY0_ADDR \ +(WF_PLE_TOP_BASE + 0x1140) /* 1140 */ +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY1_ADDR \ +(WF_PLE_TOP_BASE + 0x1144) /* 1144 */ +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY2_ADDR \ +(WF_PLE_TOP_BASE + 0x1148) /* 1148 */ +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY3_ADDR \ +(WF_PLE_TOP_BASE + 0x114C) /* 114C */ +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY4_ADDR \ +(WF_PLE_TOP_BASE + 0x1150) /* 1150 */ +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY5_ADDR \ +(WF_PLE_TOP_BASE + 0x1154) /* 1154 */ +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY6_ADDR \ +(WF_PLE_TOP_BASE + 0x1158) /* 1158 */ +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY7_ADDR \ +(WF_PLE_TOP_BASE + 0x115c) /* 115C */ +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY8_ADDR \ +(WF_PLE_TOP_BASE + 0x1160) /* 1160 */ +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY0_ADDR \ +(WF_PLE_TOP_BASE + 0x1180) /* 1180 */ +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY1_ADDR \ +(WF_PLE_TOP_BASE + 0x1184) /* 1184 */ +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY2_ADDR \ +(WF_PLE_TOP_BASE + 0x1188) /* 1188 */ +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY3_ADDR \ +(WF_PLE_TOP_BASE + 0x118C) /* 118C */ +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY4_ADDR \ +(WF_PLE_TOP_BASE + 0x1190) /* 1190 */ +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY5_ADDR \ +(WF_PLE_TOP_BASE + 0x1194) /* 1194 */ +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY6_ADDR \ +(WF_PLE_TOP_BASE + 0x1198) /* 1198 */ +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY7_ADDR \ +(WF_PLE_TOP_BASE + 0x119c) /* 119C */ +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY8_ADDR \ +(WF_PLE_TOP_BASE + 0x11a0) /* 11A0 */ +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY0_ADDR \ +(WF_PLE_TOP_BASE + 0x11C0) /* 11C0 */ +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY1_ADDR \ +(WF_PLE_TOP_BASE + 0x11C4) /* 11C4 */ +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY2_ADDR \ +(WF_PLE_TOP_BASE + 0x11C8) /* 11C8 */ +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY3_ADDR \ +(WF_PLE_TOP_BASE + 0x11CC) /* 11CC */ +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY4_ADDR \ +(WF_PLE_TOP_BASE + 0x11D0) /* 11D0 */ +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY5_ADDR \ +(WF_PLE_TOP_BASE + 0x11D4) /* 11D4 */ +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY6_ADDR \ +(WF_PLE_TOP_BASE + 0x11d8) /* 11D8 */ +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY7_ADDR \ +(WF_PLE_TOP_BASE + 0x11dc) /* 11DC */ +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY8_ADDR \ +(WF_PLE_TOP_BASE + 0x11e0) /* 11E0 */ +#define WF_PLE_TOP_CFG_DBDC_CTRL0_ADDR (WF_PLE_TOP_BASE + 0x2008) /* 2008 */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_ADDR \ +(WF_PLE_TOP_BASE + 0x2480) /* 2480 */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_1_ADDR \ +(WF_PLE_TOP_BASE + 0x2484) /* 2484 */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_2_ADDR \ +(WF_PLE_TOP_BASE + 0x2488) /* 2488 */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_3_ADDR \ +(WF_PLE_TOP_BASE + 0x248c) /* 248C */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_4_ADDR \ +(WF_PLE_TOP_BASE + 0x2490) /* 2490 */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_ADDR \ +(WF_PLE_TOP_BASE + 0x2494) /* 2494 */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_6_ADDR \ +(WF_PLE_TOP_BASE + 0x2498) /* 2498 */ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_ADDR \ +(WF_PLE_TOP_BASE + 0x25c0) /* 25C0 */ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_1_ADDR \ +(WF_PLE_TOP_BASE + 0x25c4) /* 25C4 */ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_2_ADDR \ +(WF_PLE_TOP_BASE + 0x25c8) /* 25C8 */ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_3_ADDR \ +(WF_PLE_TOP_BASE + 0x25cc) /* 25CC */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_ADDR \ +(WF_PLE_TOP_BASE + 0x25e0) /* 25E0 */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_1_ADDR \ +(WF_PLE_TOP_BASE + 0x25e4) /* 25E4 */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_2_ADDR \ +(WF_PLE_TOP_BASE + 0x25e8) /* 25E8 */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_3_ADDR \ +(WF_PLE_TOP_BASE + 0x25ec) /* 25EC */ +#define WF_PLE_TOP_SYSRAM_MBIST_CTRL_ADDR (WF_PLE_TOP_BASE + 0x3004)/* 3004\ + */ +#define WF_PLE_TOP_SYSRAM_MBIST_DEBUG_ADDR (WF_PLE_TOP_BASE + 0x3008) /* 3008\ + */ +#define WF_PLE_TOP_SYSRAM_MBIST_MODE_ADDR (WF_PLE_TOP_BASE + 0x300C)/* 300C\ + */ +#define WF_PLE_TOP_SYSRAM_MBIST_HOLDB_ADDR (WF_PLE_TOP_BASE + 0x3010) /* 3010\ + */ +#define WF_PLE_TOP_SYSRAM_MBIST_DONE_ADDR (WF_PLE_TOP_BASE + 0x3014)/* 3014\ + */ +#define WF_PLE_TOP_SYSRAM_MBIST_FAIL_ADDR (WF_PLE_TOP_BASE + 0x3018)/* 3018\ + */ +#define WF_PLE_TOP_SYSRAM_MBIST_SLEEP_TEST_ADDR \ +(WF_PLE_TOP_BASE + 0x301C) /* 301C */ +#define WF_PLE_TOP_SYSRAM_MBIST_SLEEP_INV_ADDR \ +(WF_PLE_TOP_BASE + 0x3020) /* 3020 */ +#define WF_PLE_TOP_SYSRAM_MBIST_SLEEP_W_ADDR \ +(WF_PLE_TOP_BASE + 0x3024) /* 3024 */ +#define WF_PLE_TOP_SYSRAM_MBIST_SLEEP_R_ADDR \ +(WF_PLE_TOP_BASE + 0x3028) /* 3028 */ +#define WF_PLE_TOP_SYSRAM_AWT_HDEN_ADDR (WF_PLE_TOP_BASE + 0x302C) /* 302C */ +#define WF_PLE_TOP_SYSRAM_DBG_SEL_ADDR (WF_PLE_TOP_BASE + 0x3030)/* 3030 */ +#define WF_PLE_TOP_SYSRAM_DELSEL_ADDR (WF_PLE_TOP_BASE + 0x3070) /* 3070 */ +#define WF_PLE_TOP_SYSRAM_DELSEL_1_ADDR (WF_PLE_TOP_BASE + 0x3074) /* 3074 */ +#define WF_PLE_TOP_SYSRAM_DELSEL_2_ADDR (WF_PLE_TOP_BASE + 0x3078) /* 3078 */ +#define WF_PLE_TOP_SYSRAM_DELSEL_3_ADDR (WF_PLE_TOP_BASE + 0x307C) /* 307C */ +#define WF_PLE_TOP_SYSRAM_OUTRAN_ERR_FLAG_ADDR \ +(WF_PLE_TOP_BASE + 0x3080) /* 3080 */ + +/* +* ---GC (0x820C0000 + 0x00)--- +* ALL_RESET[0] - (RW) Resets PLE logic and register +* LOGIC_RESET[1] - (RW) Resets PLE logic circuit +* INIT_DONE[2] - (RO) PLE control SRAM initialization +indicator +* UMAC_CFG_LOGIC_RESET[3] - (RW) Resets PF/MDP/SEC/UWTBL logic circuit +* RESERVED4[15..4] - (RO) Reserved bits +* SRAM_MBIST_G1_RESET[16] - (RW) Reset control of group 1 SRAM MBIST +* SRAM_MBIST_G2_RESET[17] - (RW) Reset control of group 2 SRAM MBIST +* DIS_PLE_DYN_CKG[18] - (RW) Disable control of wf_ple_top dynamic +* clock gating function +* RESERVED19[31..19] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_GC_DIS_PLE_DYN_CKG_ADDR WF_PLE_TOP_GC_ADDR +#define WF_PLE_TOP_GC_DIS_PLE_DYN_CKG_MASK 0x00040000 /* DIS_PLE_DYN_CKG[18] \ + */ +#define WF_PLE_TOP_GC_DIS_PLE_DYN_CKG_SHFT 18 +#define WF_PLE_TOP_GC_SRAM_MBIST_G2_RESET_ADDR WF_PLE_TOP_GC_ADDR +#define WF_PLE_TOP_GC_SRAM_MBIST_G2_RESET_MASK \ +0x00020000 /* SRAM_MBIST_G2_RESET[17] */ +#define WF_PLE_TOP_GC_SRAM_MBIST_G2_RESET_SHFT 17 +#define WF_PLE_TOP_GC_SRAM_MBIST_G1_RESET_ADDR WF_PLE_TOP_GC_ADDR +#define WF_PLE_TOP_GC_SRAM_MBIST_G1_RESET_MASK \ +0x00010000 /* SRAM_MBIST_G1_RESET[16] */ +#define WF_PLE_TOP_GC_SRAM_MBIST_G1_RESET_SHFT 16 +#define WF_PLE_TOP_GC_UMAC_CFG_LOGIC_RESET_ADDR WF_PLE_TOP_GC_ADDR +#define WF_PLE_TOP_GC_UMAC_CFG_LOGIC_RESET_MASK \ +0x00000008 /* UMAC_CFG_LOGIC_RESET[3] */ +#define WF_PLE_TOP_GC_UMAC_CFG_LOGIC_RESET_SHFT 3 +#define WF_PLE_TOP_GC_INIT_DONE_ADDR WF_PLE_TOP_GC_ADDR +#define WF_PLE_TOP_GC_INIT_DONE_MASK 0x00000004 /* INIT_DONE[2] */ +#define WF_PLE_TOP_GC_INIT_DONE_SHFT 2 +#define WF_PLE_TOP_GC_LOGIC_RESET_ADDR WF_PLE_TOP_GC_ADDR +#define WF_PLE_TOP_GC_LOGIC_RESET_MASK 0x00000002 /* LOGIC_RESET[1] */ +#define WF_PLE_TOP_GC_LOGIC_RESET_SHFT 1 +#define WF_PLE_TOP_GC_ALL_RESET_ADDR WF_PLE_TOP_GC_ADDR +#define WF_PLE_TOP_GC_ALL_RESET_MASK 0x00000001 /* ALL_RESET[0] */ +#define WF_PLE_TOP_GC_ALL_RESET_SHFT 0 + +/* +* ---PBUF_CTRL (0x820C0000 + 0x14)--- +* TOTAL_PAGE_NUM[11..0] - (RW) Total page number +* Set the total page before release PLE logic +* reset, and must not be changed after release logic reset. +* RESERVED12[16..12] - (RO) Reserved bits +* PBUF_OFFSET[25..17] - (RW) Packet buffer offset +* Set up the buffer offset before releasing +* PLE logic reset; it should not be changed after logic reset is released. +* RESERVED26[30..26] - (RO) Reserved bits +* PAGE_SIZE_CFG[31] - (RW) Configures page size +* Set up the page size before releasing PLE +* logic reset; it should not be changed after logic reset is released. +*/ +#define WF_PLE_TOP_PBUF_CTRL_PAGE_SIZE_CFG_ADDR WF_PLE_TOP_PBUF_CTRL_ADDR +#define WF_PLE_TOP_PBUF_CTRL_PAGE_SIZE_CFG_MASK \ +0x80000000 /* PAGE_SIZE_CFG[31] */ +#define WF_PLE_TOP_PBUF_CTRL_PAGE_SIZE_CFG_SHFT 31 +#define WF_PLE_TOP_PBUF_CTRL_PBUF_OFFSET_ADDR WF_PLE_TOP_PBUF_CTRL_ADDR +#define WF_PLE_TOP_PBUF_CTRL_PBUF_OFFSET_MASK \ +0x03FE0000 /* PBUF_OFFSET[25..17] */ +#define WF_PLE_TOP_PBUF_CTRL_PBUF_OFFSET_SHFT 17 +#define WF_PLE_TOP_PBUF_CTRL_TOTAL_PAGE_NUM_ADDR WF_PLE_TOP_PBUF_CTRL_ADDR +#define WF_PLE_TOP_PBUF_CTRL_TOTAL_PAGE_NUM_MASK \ +0x00000FFF /* TOTAL_PAGE_NUM[11..0] */ +#define WF_PLE_TOP_PBUF_CTRL_TOTAL_PAGE_NUM_SHFT 0 + +/* +* ---TIMEOUT_CTRL (0x820C0000 + 0x1c)--- +* RESERVED0[7..0] - (RO) Reserved bits +* HOST_REPORT_TO_CTRL[15..8] - (RW) HOST report timeout control register +* APB_WD_TO_CTRL[23..16] - (RW) APB pready watch dog timeout control +register +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_TIMEOUT_CTRL_APB_WD_TO_CTRL_ADDR WF_PLE_TOP_TIMEOUT_CTRL_ADDR +#define WF_PLE_TOP_TIMEOUT_CTRL_APB_WD_TO_CTRL_MASK \ +0x00FF0000 /* APB_WD_TO_CTRL[23..16] */ +#define WF_PLE_TOP_TIMEOUT_CTRL_APB_WD_TO_CTRL_SHFT 16 +#define WF_PLE_TOP_TIMEOUT_CTRL_HOST_REPORT_TO_CTRL_ADDR \ +WF_PLE_TOP_TIMEOUT_CTRL_ADDR +#define WF_PLE_TOP_TIMEOUT_CTRL_HOST_REPORT_TO_CTRL_MASK \ +0x0000FF00 /* HOST_REPORT_TO_CTRL[15..8] */ +#define WF_PLE_TOP_TIMEOUT_CTRL_HOST_REPORT_TO_CTRL_SHFT 8 + +/* +* ---INT_N9_EN_MASK (0x820C0000 + 0x20)--- +* EN_CPU_Q0_NE[0] - (RW) Enable control of interrupt for CPU +* queue 0 not empty +* EN_CPU_Q1_NE[1] - (RW) Enable control of interrupt for CPU +* queue 1 not empty +* EN_CPU_Q2_NE[2] - (RW) Enable control of interrupt for CPU +* queue 2 not empty +* EN_CPU_Q3_NE[3] - (RW) Enable control of interrupt for CPU +* queue 3 not empty +* RESERVED4[15..4] - (RO) Reserved bits +* EN_TOGGLE_INT[16] - (RW) Enable control of interrupt for data +* toggle of N9 toggle register (0xf0) +* EN_SPL_CMD_FIFO_FULL_INT[17] - (RW) Enable control of interrupt for SPL CMD +* FIFO full +* EN_UMAC_SYSRAM_OUTRAN_ERROR_INT[18] - (RW) Enable control of interrupt for +* UMAC SYSRAM out range error +* RESERVED19[19] - (RO) Reserved bits +* EN_AC_NONEMPTY_INT[20] - (RW) Enable control of AC queue empty fail +interrupt +* EN_AC_EMPTY_INT[21] - (RW) Enable control of AC queue empty raise +interrupt +* EN_AC_ENQ_LMAC_INT[22] - (RW) Enable control of AC enqueue interrupt +* RESERVED23[23] - (RO) Reserved bits +* EN_DBDC0_NONEMPTY_INT[24] - (RW) Enable control of DBDC0 queue empty fail +interrupt +* EN_DBDC0_EMPTY_INT[25] - (RW) Enable control of DBDC0 queue empty +* raise interrupt +* EN_DBDC0_ENQ_LMAC_INT[26] - (RW) Enable control of DBDC0 enqueue +interrupt +* RESERVED27[27] - (RO) Reserved bits +* EN_DBDC1_NONEMPTY_INT[28] - (RW) Enable control of DBDC1 queue empty fail +interrupt +* EN_DBDC1_EMPTY_INT[29] - (RW) Enable control of DBDC1 queue empty +* raise interrupt +* EN_DBDC1_ENQ_LMAC_INT[30] - (RW) Enable control of DBDC1 enqueue +interrupt +* RESERVED31[31] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC1_ENQ_LMAC_INT_ADDR \ +WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC1_ENQ_LMAC_INT_MASK \ +0x40000000 /* EN_DBDC1_ENQ_LMAC_INT[30] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC1_ENQ_LMAC_INT_SHFT 30 +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC1_EMPTY_INT_ADDR \ +WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC1_EMPTY_INT_MASK \ +0x20000000 /* EN_DBDC1_EMPTY_INT[29] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC1_EMPTY_INT_SHFT 29 +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC1_NONEMPTY_INT_ADDR \ +WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC1_NONEMPTY_INT_MASK \ +0x10000000 /* EN_DBDC1_NONEMPTY_INT[28] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC1_NONEMPTY_INT_SHFT 28 +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC0_ENQ_LMAC_INT_ADDR \ +WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC0_ENQ_LMAC_INT_MASK \ +0x04000000 /* EN_DBDC0_ENQ_LMAC_INT[26] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC0_ENQ_LMAC_INT_SHFT 26 +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC0_EMPTY_INT_ADDR \ +WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC0_EMPTY_INT_MASK \ +0x02000000 /* EN_DBDC0_EMPTY_INT[25] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC0_EMPTY_INT_SHFT 25 +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC0_NONEMPTY_INT_ADDR \ +WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC0_NONEMPTY_INT_MASK \ +0x01000000 /* EN_DBDC0_NONEMPTY_INT[24] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC0_NONEMPTY_INT_SHFT 24 +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_AC_ENQ_LMAC_INT_ADDR \ +WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_AC_ENQ_LMAC_INT_MASK \ +0x00400000 /* EN_AC_ENQ_LMAC_INT[22] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_AC_ENQ_LMAC_INT_SHFT 22 +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_AC_EMPTY_INT_ADDR \ +WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_AC_EMPTY_INT_MASK \ +0x00200000 /* EN_AC_EMPTY_INT[21] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_AC_EMPTY_INT_SHFT 21 +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_AC_NONEMPTY_INT_ADDR \ +WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_AC_NONEMPTY_INT_MASK \ +0x00100000 /* EN_AC_NONEMPTY_INT[20] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_AC_NONEMPTY_INT_SHFT 20 +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_UMAC_SYSRAM_OUTRAN_ERROR_INT_ADDR \ +WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_UMAC_SYSRAM_OUTRAN_ERROR_INT_MASK \ +0x00040000 /* EN_UMAC_SYSRAM_OUTRAN_ERROR_INT[18] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_UMAC_SYSRAM_OUTRAN_ERROR_INT_SHFT 18 +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_SPL_CMD_FIFO_FULL_INT_ADDR \ +WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_SPL_CMD_FIFO_FULL_INT_MASK \ +0x00020000 /* EN_SPL_CMD_FIFO_FULL_INT[17] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_SPL_CMD_FIFO_FULL_INT_SHFT 17 +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_TOGGLE_INT_ADDR \ +WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_TOGGLE_INT_MASK \ +0x00010000 /* EN_TOGGLE_INT[16] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_TOGGLE_INT_SHFT 16 +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_CPU_Q3_NE_ADDR \ +WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_CPU_Q3_NE_MASK \ +0x00000008 /* EN_CPU_Q3_NE[3] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_CPU_Q3_NE_SHFT 3 +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_CPU_Q2_NE_ADDR \ +WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_CPU_Q2_NE_MASK \ +0x00000004 /* EN_CPU_Q2_NE[2] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_CPU_Q2_NE_SHFT 2 +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_CPU_Q1_NE_ADDR \ +WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_CPU_Q1_NE_MASK \ +0x00000002 /* EN_CPU_Q1_NE[1] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_CPU_Q1_NE_SHFT 1 +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_CPU_Q0_NE_ADDR \ +WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_CPU_Q0_NE_MASK \ +0x00000001 /* EN_CPU_Q0_NE[0] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_CPU_Q0_NE_SHFT 0 + +/* +* ---INT_N9_STS (0x820C0000 + 0x24)--- +* CPU_Q0_NE[0] - (W1C) CPU queue 0 not empty interrupt status +* CPU_Q1_NE[1] - (W1C) CPU queue 1 not empty interrupt status +* CPU_Q2_NE[2] - (W1C) CPU queue 2 not empty interrupt status +* CPU_Q3_NE[3] - (W1C) CPU queue 3 not empty interrupt status +* RESERVED4[12..4] - (RO) Reserved bits +* ERROR_INT[13] - (RO) Error condition interrupt status, define +* by 0x28 +* ERROR_INT_1[14] - (RO) Error condition interrupt status 1, +* define by 0xd8 +* AMSDU_ERROR_INT[15] - (RO) HW AMSDU Error condition interrupt +* status, define by 0x1028 +* DATA_TOGGLE[16] - (W1C) Interrupt status of data toggle of N9 +* toggle register (0xf0) +* SPL_CMD_FIFO_FULL[17] - (W1C) Interrupt status of SPL CMD FIFO full +* UMAC_SYSRAM_OUTRAN_ERROR_INT[18] - (W1C) Interrupt status of UMAC SYSRAM out +* range error +* RESERVED19[19] - (RO) Reserved bits +* AC_NONEMPTY_INT[20] - (W1C) AC queue empty fail interrupt status +* AC_EMPTY_INT[21] - (W1C) AC queue empty raise interrupt status +* AC_ENQ_LMAC_INT[22] - (W1C) AC enqueue interrupt status +* RESERVED23[23] - (RO) Reserved bits +* DBDC0_NONEMPTY_INT[24] - (W1C) DBDC0 queue empty fail interrupt status +* DBDC0_EMPTY_INT[25] - (W1C) DBDC0 queue empty raise interrupt +status +* DBDC0_ENQ_LMAC_INT[26] - (W1C) DBDC0 enqueue interrupt status +* RESERVED27[27] - (RO) Reserved bits +* DBDC1_NONEMPTY_INT[28] - (W1C) DBDC1 queue empty fail interrupt status +* DBDC1_EMPTY_INT[29] - (W1C) DBDC1 queue empty raise interrupt +status +* DBDC1_ENQ_LMAC_INT[30] - (W1C) DBDC1 enqueue interrupt status +* RESERVED31[31] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_INT_N9_STS_DBDC1_ENQ_LMAC_INT_ADDR WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_DBDC1_ENQ_LMAC_INT_MASK \ +0x40000000 /* DBDC1_ENQ_LMAC_INT[30] */ +#define WF_PLE_TOP_INT_N9_STS_DBDC1_ENQ_LMAC_INT_SHFT 30 +#define WF_PLE_TOP_INT_N9_STS_DBDC1_EMPTY_INT_ADDR WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_DBDC1_EMPTY_INT_MASK \ +0x20000000 /* DBDC1_EMPTY_INT[29] */ +#define WF_PLE_TOP_INT_N9_STS_DBDC1_EMPTY_INT_SHFT 29 +#define WF_PLE_TOP_INT_N9_STS_DBDC1_NONEMPTY_INT_ADDR WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_DBDC1_NONEMPTY_INT_MASK \ +0x10000000 /* DBDC1_NONEMPTY_INT[28] */ +#define WF_PLE_TOP_INT_N9_STS_DBDC1_NONEMPTY_INT_SHFT 28 +#define WF_PLE_TOP_INT_N9_STS_DBDC0_ENQ_LMAC_INT_ADDR WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_DBDC0_ENQ_LMAC_INT_MASK \ +0x04000000 /* DBDC0_ENQ_LMAC_INT[26] */ +#define WF_PLE_TOP_INT_N9_STS_DBDC0_ENQ_LMAC_INT_SHFT 26 +#define WF_PLE_TOP_INT_N9_STS_DBDC0_EMPTY_INT_ADDR WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_DBDC0_EMPTY_INT_MASK \ +0x02000000 /* DBDC0_EMPTY_INT[25] */ +#define WF_PLE_TOP_INT_N9_STS_DBDC0_EMPTY_INT_SHFT 25 +#define WF_PLE_TOP_INT_N9_STS_DBDC0_NONEMPTY_INT_ADDR WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_DBDC0_NONEMPTY_INT_MASK \ +0x01000000 /* DBDC0_NONEMPTY_INT[24] */ +#define WF_PLE_TOP_INT_N9_STS_DBDC0_NONEMPTY_INT_SHFT 24 +#define WF_PLE_TOP_INT_N9_STS_AC_ENQ_LMAC_INT_ADDR WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_AC_ENQ_LMAC_INT_MASK \ +0x00400000 /* AC_ENQ_LMAC_INT[22] */ +#define WF_PLE_TOP_INT_N9_STS_AC_ENQ_LMAC_INT_SHFT 22 +#define WF_PLE_TOP_INT_N9_STS_AC_EMPTY_INT_ADDR WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_AC_EMPTY_INT_MASK \ +0x00200000 /* AC_EMPTY_INT[21] */ +#define WF_PLE_TOP_INT_N9_STS_AC_EMPTY_INT_SHFT 21 +#define WF_PLE_TOP_INT_N9_STS_AC_NONEMPTY_INT_ADDR WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_AC_NONEMPTY_INT_MASK \ +0x00100000 /* AC_NONEMPTY_INT[20] */ +#define WF_PLE_TOP_INT_N9_STS_AC_NONEMPTY_INT_SHFT 20 +#define WF_PLE_TOP_INT_N9_STS_UMAC_SYSRAM_OUTRAN_ERROR_INT_ADDR \ +WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_UMAC_SYSRAM_OUTRAN_ERROR_INT_MASK \ +0x00040000 /* UMAC_SYSRAM_OUTRAN_ERROR_INT[18] */ +#define WF_PLE_TOP_INT_N9_STS_UMAC_SYSRAM_OUTRAN_ERROR_INT_SHFT 18 +#define WF_PLE_TOP_INT_N9_STS_SPL_CMD_FIFO_FULL_ADDR WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_SPL_CMD_FIFO_FULL_MASK \ +0x00020000 /* SPL_CMD_FIFO_FULL[17] */ +#define WF_PLE_TOP_INT_N9_STS_SPL_CMD_FIFO_FULL_SHFT 17 +#define WF_PLE_TOP_INT_N9_STS_DATA_TOGGLE_ADDR WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_DATA_TOGGLE_MASK 0x00010000 /* DATA_TOGGLE[16] \ + */ +#define WF_PLE_TOP_INT_N9_STS_DATA_TOGGLE_SHFT 16 +#define WF_PLE_TOP_INT_N9_STS_AMSDU_ERROR_INT_ADDR WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_AMSDU_ERROR_INT_MASK \ +0x00008000 /* AMSDU_ERROR_INT[15] */ +#define WF_PLE_TOP_INT_N9_STS_AMSDU_ERROR_INT_SHFT 15 +#define WF_PLE_TOP_INT_N9_STS_ERROR_INT_1_ADDR WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_ERROR_INT_1_MASK 0x00004000 /* ERROR_INT_1[14] \ + */ +#define WF_PLE_TOP_INT_N9_STS_ERROR_INT_1_SHFT 14 +#define WF_PLE_TOP_INT_N9_STS_ERROR_INT_ADDR WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_ERROR_INT_MASK 0x00002000 /* ERROR_INT[13] */ +#define WF_PLE_TOP_INT_N9_STS_ERROR_INT_SHFT 13 +#define WF_PLE_TOP_INT_N9_STS_CPU_Q3_NE_ADDR WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_CPU_Q3_NE_MASK 0x00000008 /* CPU_Q3_NE[3] */ +#define WF_PLE_TOP_INT_N9_STS_CPU_Q3_NE_SHFT 3 +#define WF_PLE_TOP_INT_N9_STS_CPU_Q2_NE_ADDR WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_CPU_Q2_NE_MASK 0x00000004 /* CPU_Q2_NE[2] */ +#define WF_PLE_TOP_INT_N9_STS_CPU_Q2_NE_SHFT 2 +#define WF_PLE_TOP_INT_N9_STS_CPU_Q1_NE_ADDR WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_CPU_Q1_NE_MASK 0x00000002 /* CPU_Q1_NE[1] */ +#define WF_PLE_TOP_INT_N9_STS_CPU_Q1_NE_SHFT 1 +#define WF_PLE_TOP_INT_N9_STS_CPU_Q0_NE_ADDR WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_CPU_Q0_NE_MASK 0x00000001 /* CPU_Q0_NE[0] */ +#define WF_PLE_TOP_INT_N9_STS_CPU_Q0_NE_SHFT 0 + +/* +* ---INT_N9_ERR_STS (0x820C0000 + 0x28)--- +* Q_CMD_ERR_P0[0] - (W1C) Queue command error interrupt status of +* port 0. Avoid unclear error flag, please clear flag when logic reset. +* Q_CMD_ERR_P1[1] - (W1C) Queue command error interrupt status of +* port 1. Avoid unclear error flag, please clear flag when logic reset. +* Q_CMD_ERR_P2[2] - (W1C) Queue command error interrupt status of +* port 2. Avoid unclear error flag, please clear flag when logic reset. +* PAGE_UDF_P0[3] - (W1C) Page underflow interrupt status of port +* 0. Avoid unclear error flag, please clear flag when logic reset. +* PAGE_UDF_P1[4] - (W1C) Page underflow interrupt status of port +* 1. Avoid unclear error flag, please clear flag when logic reset. +* PAGE_UDF_P2[5] - (W1C) Page underflow interrupt status of port +* 2. Avoid unclear error flag, please clear flag when logic reset. +* DOUBLE_RLS_ERR[6] - (W1C) Double release error interrupt. Avoid +* unclear error flag, please clear flag when logic reset. +* MDP_D_OPER_ERR[7] - (W1C) MDP data operation error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* MDP_HANG_ERR[8] - (W1C) MDP FSM Hang error interrupt. Avoid +* unclear error flag, please clear flag when logic reset. +* RESERVED9[9] - (RO) Reserved bits +* DATA_OPER_ERR_P0[10] - (W1C) Data operation error of port 0. Avoid +* unclear error flag, please clear flag when logic reset. +* DATA_OPER_ERR_P1[11] - (W1C) Data operation error of port 1. Avoid +* unclear error flag, please clear flag when logic reset. +* DATA_OPER_ERR_P2[12] - (W1C) Data operation error of port 2. Avoid +* unclear error flag, please clear flag when logic reset. +* FL_HANG_ERR[13] - (W1C) Frame link FSM hang error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* PL_HANG_ERR[14] - (W1C) Page link FSM hang error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* HIF_HANG_ERR[15] - (W1C) HIF port FSM hang error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* CPU_HANG_ERR[16] - (W1C) CPU port FSM hang error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* LMAC_HANG_ERR[17] - (W1C) LMAC port FSM hang error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* FREE_HEAD_TAIL_ERR[18] - (W1C) Free head/tail error interrupt. Avoid +* unclear error flag, please clear flag when logic reset. +* QSTRUCT_ERR[19] - (W1C) Queue struct data error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* BN0_MACTX_HANG_ERR[20] - (W1C) BN0 MACTX Ctrl FSM Hang error +* interrupt. Avoid unclear error flag, please clear flag when logic reset. +* BN1_MACTX_HANG_ERR[21] - (W1C) BN1 MACTX Ctrl FSM Hang error +* interrupt. Avoid unclear error flag, please clear flag when logic reset. +* BN0_TXCMD_HANG_ERR[22] - (W1C) BN0 TXCMD Ctrl FSM Hang error +* interrupt. Avoid unclear error flag, please clear flag when logic reset. +* BN1_TXCMD_HANG_ERR[23] - (W1C) BN1 TXCMD Ctrl FSM Hang error +* interrupt. Avoid unclear error flag, please clear flag when logic reset. +* DRR_SRCH_DBDC0_ERR[24] - (W1C) DRR DBDC0 sta serach error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* DRR_SRCH_DBDC1_ERR[25] - (W1C) DRR DBDC1 sta serach error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* DRR_FL_ERR[26] - (W1C) DRR forward link access error +* interrupt. Avoid unclear error flag, please clear flag when logic reset. +* DRR_BL_ERR[27] - (W1C) DRR backward link access error +* interrupt. Avoid unclear error flag, please clear flag when logic reset. +* DRR_RL_ERR[28] - (W1C) DRR relay link access error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* DRR_CHRG_STA_ERR[29] - (W1C) DRR charge wlanid error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* DRR_STA_WLANID_ERR[30] - (W1C) DRR wlanid error interrupt. Avoid +* unclear error flag, please clear flag when logic reset. +* DRR_STA_WMMID_ERR[31] - (W1C) DRR wmmid error interrupt. Avoid +* unclear error flag, please clear flag when logic reset. +*/ +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_STA_WMMID_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_STA_WMMID_ERR_MASK \ +0x80000000 /* DRR_STA_WMMID_ERR[31] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_STA_WMMID_ERR_SHFT 31 +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_STA_WLANID_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_STA_WLANID_ERR_MASK \ +0x40000000 /* DRR_STA_WLANID_ERR[30] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_STA_WLANID_ERR_SHFT 30 +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_CHRG_STA_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_CHRG_STA_ERR_MASK \ +0x20000000 /* DRR_CHRG_STA_ERR[29] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_CHRG_STA_ERR_SHFT 29 +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_RL_ERR_ADDR WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_RL_ERR_MASK \ +0x10000000 /* DRR_RL_ERR[28] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_RL_ERR_SHFT 28 +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_BL_ERR_ADDR WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_BL_ERR_MASK \ +0x08000000 /* DRR_BL_ERR[27] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_BL_ERR_SHFT 27 +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_FL_ERR_ADDR WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_FL_ERR_MASK \ +0x04000000 /* DRR_FL_ERR[26] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_FL_ERR_SHFT 26 +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_SRCH_DBDC1_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_SRCH_DBDC1_ERR_MASK \ +0x02000000 /* DRR_SRCH_DBDC1_ERR[25] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_SRCH_DBDC1_ERR_SHFT 25 +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_SRCH_DBDC0_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_SRCH_DBDC0_ERR_MASK \ +0x01000000 /* DRR_SRCH_DBDC0_ERR[24] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_SRCH_DBDC0_ERR_SHFT 24 +#define WF_PLE_TOP_INT_N9_ERR_STS_BN1_TXCMD_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_BN1_TXCMD_HANG_ERR_MASK \ +0x00800000 /* BN1_TXCMD_HANG_ERR[23] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_BN1_TXCMD_HANG_ERR_SHFT 23 +#define WF_PLE_TOP_INT_N9_ERR_STS_BN0_TXCMD_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_BN0_TXCMD_HANG_ERR_MASK \ +0x00400000 /* BN0_TXCMD_HANG_ERR[22] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_BN0_TXCMD_HANG_ERR_SHFT 22 +#define WF_PLE_TOP_INT_N9_ERR_STS_BN1_MACTX_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_BN1_MACTX_HANG_ERR_MASK \ +0x00200000 /* BN1_MACTX_HANG_ERR[21] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_BN1_MACTX_HANG_ERR_SHFT 21 +#define WF_PLE_TOP_INT_N9_ERR_STS_BN0_MACTX_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_BN0_MACTX_HANG_ERR_MASK \ +0x00100000 /* BN0_MACTX_HANG_ERR[20] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_BN0_MACTX_HANG_ERR_SHFT 20 +#define WF_PLE_TOP_INT_N9_ERR_STS_QSTRUCT_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_QSTRUCT_ERR_MASK \ +0x00080000 /* QSTRUCT_ERR[19] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_QSTRUCT_ERR_SHFT 19 +#define WF_PLE_TOP_INT_N9_ERR_STS_FREE_HEAD_TAIL_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_FREE_HEAD_TAIL_ERR_MASK \ +0x00040000 /* FREE_HEAD_TAIL_ERR[18] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_FREE_HEAD_TAIL_ERR_SHFT 18 +#define WF_PLE_TOP_INT_N9_ERR_STS_LMAC_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_LMAC_HANG_ERR_MASK \ +0x00020000 /* LMAC_HANG_ERR[17] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_LMAC_HANG_ERR_SHFT 17 +#define WF_PLE_TOP_INT_N9_ERR_STS_CPU_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_CPU_HANG_ERR_MASK \ +0x00010000 /* CPU_HANG_ERR[16] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_CPU_HANG_ERR_SHFT 16 +#define WF_PLE_TOP_INT_N9_ERR_STS_HIF_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_HIF_HANG_ERR_MASK \ +0x00008000 /* HIF_HANG_ERR[15] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_HIF_HANG_ERR_SHFT 15 +#define WF_PLE_TOP_INT_N9_ERR_STS_PL_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_PL_HANG_ERR_MASK \ +0x00004000 /* PL_HANG_ERR[14] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_PL_HANG_ERR_SHFT 14 +#define WF_PLE_TOP_INT_N9_ERR_STS_FL_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_FL_HANG_ERR_MASK \ +0x00002000 /* FL_HANG_ERR[13] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_FL_HANG_ERR_SHFT 13 +#define WF_PLE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P2_ADDR \ +WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P2_MASK \ +0x00001000 /* DATA_OPER_ERR_P2[12] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P2_SHFT 12 +#define WF_PLE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P1_ADDR \ +WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P1_MASK \ +0x00000800 /* DATA_OPER_ERR_P1[11] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P1_SHFT 11 +#define WF_PLE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P0_ADDR \ +WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P0_MASK \ +0x00000400 /* DATA_OPER_ERR_P0[10] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P0_SHFT 10 +#define WF_PLE_TOP_INT_N9_ERR_STS_MDP_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_MDP_HANG_ERR_MASK \ +0x00000100 /* MDP_HANG_ERR[8] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_MDP_HANG_ERR_SHFT 8 +#define WF_PLE_TOP_INT_N9_ERR_STS_MDP_D_OPER_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_MDP_D_OPER_ERR_MASK \ +0x00000080 /* MDP_D_OPER_ERR[7] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_MDP_D_OPER_ERR_SHFT 7 +#define WF_PLE_TOP_INT_N9_ERR_STS_DOUBLE_RLS_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_DOUBLE_RLS_ERR_MASK \ +0x00000040 /* DOUBLE_RLS_ERR[6] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_DOUBLE_RLS_ERR_SHFT 6 +#define WF_PLE_TOP_INT_N9_ERR_STS_PAGE_UDF_P2_ADDR \ +WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_PAGE_UDF_P2_MASK \ +0x00000020 /* PAGE_UDF_P2[5] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_PAGE_UDF_P2_SHFT 5 +#define WF_PLE_TOP_INT_N9_ERR_STS_PAGE_UDF_P1_ADDR \ +WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_PAGE_UDF_P1_MASK \ +0x00000010 /* PAGE_UDF_P1[4] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_PAGE_UDF_P1_SHFT 4 +#define WF_PLE_TOP_INT_N9_ERR_STS_PAGE_UDF_P0_ADDR \ +WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_PAGE_UDF_P0_MASK \ +0x00000008 /* PAGE_UDF_P0[3] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_PAGE_UDF_P0_SHFT 3 +#define WF_PLE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P2_ADDR \ +WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P2_MASK \ +0x00000004 /* Q_CMD_ERR_P2[2] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P2_SHFT 2 +#define WF_PLE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P1_ADDR \ +WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P1_MASK \ +0x00000002 /* Q_CMD_ERR_P1[1] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P1_SHFT 1 +#define WF_PLE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P0_ADDR \ +WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P0_MASK \ +0x00000001 /* Q_CMD_ERR_P0[0] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P0_SHFT 0 + +/* +* ---INT_N9_ERR_MASK (0x820C0000 + 0x2C)--- +* EN_Q_CMD_ERR_P0[0] - (RW) Enables queue command error interrupt +* status of port 0 +* EN_Q_CMD_ERR_P1[1] - (RW) Enables queue command error interrupt +* status of port 1 +* EN_Q_CMD_ERR_P2[2] - (RW) Enables queue command error interrupt +* status of port 2 +* EN_PAGE_UDF_P0[3] - (RW) Enables page underflow interrupt status +* of port 0 +* EN_PAGE_UDF_P1[4] - (RW) Enables page underflow interrupt status +* of port 1 +* EN_PAGE_UDF_P2[5] - (RW) Enables page underflow interrupt status +* of port 2 +* EN_DOUBLE_RLS_ERR[6] - (RW) Enable double release error interrupt. +* EN_MDP_D_OPER_ERR[7] - (RW) Enable MDP data operation error +interrupt. +* EN_MDP_HANG_ERR[8] - (RW) Enable MDP FSM hang error interrupt. +* RESERVED9[9] - (RO) Reserved bits +* EN_DATA_OPER_ERR_P0[10] - (RW) Enables data operation error of port 0 +* EN_DATA_OPER_ERR_P1[11] - (RW) Enables data operation error of port 1 +* EN_DATA_OPER_ERR_P2[12] - (RW) Enables data operation error of port 2 +* EN_FL_HANG_ERR[13] - (RW) Enables frame link FSM hang error +interrupt +* EN_PL_HANG_ERR[14] - (RW) Enables page link FSM hang error +interrupt +* EN_HIF_HANG_ERR[15] - (RW) Enables HIF port FSM hang error +interrupt +* EN_CPU_HANG_ERR[16] - (RW) Enables CPU port FSM hang error +interrupt +* EN_LMAC_HANG_ERR[17] - (RW) Enables LMAC port FSM hang error +interrupt +* EN_FREE_HEAD_TAIL_ERR[18] - (RW) Enable free head/tail error interrupt. +* EN_QSTRUCT_ERR[19] - (RW) Enable queue struct data error +interrupt. +* EN_BN0_MACTX_HANG_ERR[20] - (RW) Enable BN0 MACTX Ctrl FSM Hang error +interrupt. +* EN_BN1_MACTX_HANG_ERR[21] - (RW) Enable BN1 MACTX Ctrl FSM Hang error +interrupt. +* EN_BN0_TXCMD_HANG_ERR[22] - (RW) Enable BN0 TXCMD Ctrl FSM Hang error +interrupt. +* EN_BN1_TXCMD_HANG_ERR[23] - (RW) Enable BN1 TXCMD Ctrl FSM Hang error +interrupt. +* EN_DRR_SRCH_DBDC0_ERR[24] - (RW) Enable DRR DBDC0 sta search error +interrupt. +* EN_DRR_SRCH_DBDC1_ERR[25] - (RW) Enable DRR DBDC1 sta search error +interrupt. +* EN_DRR_FL_ERR[26] - (RW) Enable DRR forward link access error +interrupt. +* EN_DRR_BL_ERR[27] - (RW) Enable DRR backward link access error +interrupt. +* EN_DRR_RL_ERR[28] - (RW) Enable DRR relay link access error +interrupt. +* EN_DRR_CHRG_STA_ERR[29] - (RW) Enable DRR wlanid error when charge +interrupt. +* EN_DRR_STA_WLANID_ERR[30] - (RW) Enable DRR wlanid error when add/remove +* sta interrupt. +* EN_DRR_STA_WMMID_ERR[31] - (RW) Enable DRR wmmid error when add/remove +* sta interrupt. +*/ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_STA_WMMID_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_STA_WMMID_ERR_MASK \ +0x80000000 /* EN_DRR_STA_WMMID_ERR[31] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_STA_WMMID_ERR_SHFT 31 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_STA_WLANID_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_STA_WLANID_ERR_MASK \ +0x40000000 /* EN_DRR_STA_WLANID_ERR[30] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_STA_WLANID_ERR_SHFT 30 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_CHRG_STA_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_CHRG_STA_ERR_MASK \ +0x20000000 /* EN_DRR_CHRG_STA_ERR[29] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_CHRG_STA_ERR_SHFT 29 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_RL_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_RL_ERR_MASK \ +0x10000000 /* EN_DRR_RL_ERR[28] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_RL_ERR_SHFT 28 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_BL_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_BL_ERR_MASK \ +0x08000000 /* EN_DRR_BL_ERR[27] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_BL_ERR_SHFT 27 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_FL_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_FL_ERR_MASK \ +0x04000000 /* EN_DRR_FL_ERR[26] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_FL_ERR_SHFT 26 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_SRCH_DBDC1_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_SRCH_DBDC1_ERR_MASK \ +0x02000000 /* EN_DRR_SRCH_DBDC1_ERR[25] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_SRCH_DBDC1_ERR_SHFT 25 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_SRCH_DBDC0_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_SRCH_DBDC0_ERR_MASK \ +0x01000000 /* EN_DRR_SRCH_DBDC0_ERR[24] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_SRCH_DBDC0_ERR_SHFT 24 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_BN1_TXCMD_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_BN1_TXCMD_HANG_ERR_MASK \ +0x00800000 /* EN_BN1_TXCMD_HANG_ERR[23] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_BN1_TXCMD_HANG_ERR_SHFT 23 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_BN0_TXCMD_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_BN0_TXCMD_HANG_ERR_MASK \ +0x00400000 /* EN_BN0_TXCMD_HANG_ERR[22] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_BN0_TXCMD_HANG_ERR_SHFT 22 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_BN1_MACTX_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_BN1_MACTX_HANG_ERR_MASK \ +0x00200000 /* EN_BN1_MACTX_HANG_ERR[21] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_BN1_MACTX_HANG_ERR_SHFT 21 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_BN0_MACTX_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_BN0_MACTX_HANG_ERR_MASK \ +0x00100000 /* EN_BN0_MACTX_HANG_ERR[20] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_BN0_MACTX_HANG_ERR_SHFT 20 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_QSTRUCT_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_QSTRUCT_ERR_MASK \ +0x00080000 /* EN_QSTRUCT_ERR[19] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_QSTRUCT_ERR_SHFT 19 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_FREE_HEAD_TAIL_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_FREE_HEAD_TAIL_ERR_MASK \ +0x00040000 /* EN_FREE_HEAD_TAIL_ERR[18] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_FREE_HEAD_TAIL_ERR_SHFT 18 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_LMAC_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_LMAC_HANG_ERR_MASK \ +0x00020000 /* EN_LMAC_HANG_ERR[17] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_LMAC_HANG_ERR_SHFT 17 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_CPU_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_CPU_HANG_ERR_MASK \ +0x00010000 /* EN_CPU_HANG_ERR[16] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_CPU_HANG_ERR_SHFT 16 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_HIF_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_HIF_HANG_ERR_MASK \ +0x00008000 /* EN_HIF_HANG_ERR[15] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_HIF_HANG_ERR_SHFT 15 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_PL_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_PL_HANG_ERR_MASK \ +0x00004000 /* EN_PL_HANG_ERR[14] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_PL_HANG_ERR_SHFT 14 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_FL_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_FL_HANG_ERR_MASK \ +0x00002000 /* EN_FL_HANG_ERR[13] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_FL_HANG_ERR_SHFT 13 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P2_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P2_MASK \ +0x00001000 /* EN_DATA_OPER_ERR_P2[12] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P2_SHFT 12 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P1_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P1_MASK \ +0x00000800 /* EN_DATA_OPER_ERR_P1[11] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P1_SHFT 11 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P0_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P0_MASK \ +0x00000400 /* EN_DATA_OPER_ERR_P0[10] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P0_SHFT 10 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_MDP_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_MDP_HANG_ERR_MASK \ +0x00000100 /* EN_MDP_HANG_ERR[8] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_MDP_HANG_ERR_SHFT 8 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_MDP_D_OPER_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_MDP_D_OPER_ERR_MASK \ +0x00000080 /* EN_MDP_D_OPER_ERR[7] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_MDP_D_OPER_ERR_SHFT 7 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DOUBLE_RLS_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DOUBLE_RLS_ERR_MASK \ +0x00000040 /* EN_DOUBLE_RLS_ERR[6] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DOUBLE_RLS_ERR_SHFT 6 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P2_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P2_MASK \ +0x00000020 /* EN_PAGE_UDF_P2[5] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P2_SHFT 5 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P1_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P1_MASK \ +0x00000010 /* EN_PAGE_UDF_P1[4] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P1_SHFT 4 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P0_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P0_MASK \ +0x00000008 /* EN_PAGE_UDF_P0[3] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P0_SHFT 3 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P2_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P2_MASK \ +0x00000004 /* EN_Q_CMD_ERR_P2[2] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P2_SHFT 2 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P1_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P1_MASK \ +0x00000002 /* EN_Q_CMD_ERR_P1[1] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P1_SHFT 1 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P0_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P0_MASK \ +0x00000001 /* EN_Q_CMD_ERR_P0[0] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P0_SHFT 0 + +/* +* ---HOST_REPORT0 (0x820C0000 + 0x30)--- +* RESERVED0[0] - (RO) Reserved bits +* DIS_HOST_RPT[1] - (RW) Disables host report function +* HOST_RPT_VER0_EN[2] - (RW) Enable control for host report roll back +* to Version 2(MT7915 E1 used). +* HOST_RPT_TX_LATENCY[3] - (RW) Enable host report TX latency +* WMCPU_MSDU_ID_NUM[5..4] - (RW) Configuration of WMCPU MSDU ID usage. +* RESERVED6[7..6] - (RO) Reserved bits +* HOST_RPT_PACK_TH[15..8] - (RW) The buffer threshold for packing host +* report. The buffer size less then the MSDU numbers of a MPDU, would let +MSDU_ID +lose. +* HOST_RPT_QID[22..16] - (RW) PSE Queue ID control for host report. +* HOST_RPT_PID[23] - (RW) PSE Port ID control for host report. +* WMCPU_RPT_QID[30..24] - (RW) PSE Queue ID control for WMCPU report. +* WMCPU_RPT_PID[31] - (RW) PSE Port ID control for WMCPU report. +*/ +#define WF_PLE_TOP_HOST_REPORT0_WMCPU_RPT_PID_ADDR WF_PLE_TOP_HOST_REPORT0_ADDR +#define WF_PLE_TOP_HOST_REPORT0_WMCPU_RPT_PID_MASK \ +0x80000000 /* WMCPU_RPT_PID[31] */ +#define WF_PLE_TOP_HOST_REPORT0_WMCPU_RPT_PID_SHFT 31 +#define WF_PLE_TOP_HOST_REPORT0_WMCPU_RPT_QID_ADDR WF_PLE_TOP_HOST_REPORT0_ADDR +#define WF_PLE_TOP_HOST_REPORT0_WMCPU_RPT_QID_MASK \ +0x7F000000 /* WMCPU_RPT_QID[30..24] */ +#define WF_PLE_TOP_HOST_REPORT0_WMCPU_RPT_QID_SHFT 24 +#define WF_PLE_TOP_HOST_REPORT0_HOST_RPT_PID_ADDR WF_PLE_TOP_HOST_REPORT0_ADDR +#define WF_PLE_TOP_HOST_REPORT0_HOST_RPT_PID_MASK \ +0x00800000 /* HOST_RPT_PID[23] */ +#define WF_PLE_TOP_HOST_REPORT0_HOST_RPT_PID_SHFT 23 +#define WF_PLE_TOP_HOST_REPORT0_HOST_RPT_QID_ADDR WF_PLE_TOP_HOST_REPORT0_ADDR +#define WF_PLE_TOP_HOST_REPORT0_HOST_RPT_QID_MASK \ +0x007F0000 /* HOST_RPT_QID[22..16] */ +#define WF_PLE_TOP_HOST_REPORT0_HOST_RPT_QID_SHFT 16 +#define WF_PLE_TOP_HOST_REPORT0_HOST_RPT_PACK_TH_ADDR \ +WF_PLE_TOP_HOST_REPORT0_ADDR +#define WF_PLE_TOP_HOST_REPORT0_HOST_RPT_PACK_TH_MASK \ +0x0000FF00 /* HOST_RPT_PACK_TH[15..8] */ +#define WF_PLE_TOP_HOST_REPORT0_HOST_RPT_PACK_TH_SHFT 8 +#define WF_PLE_TOP_HOST_REPORT0_WMCPU_MSDU_ID_NUM_ADDR \ +WF_PLE_TOP_HOST_REPORT0_ADDR +#define WF_PLE_TOP_HOST_REPORT0_WMCPU_MSDU_ID_NUM_MASK \ +0x00000030 /* WMCPU_MSDU_ID_NUM[5..4] */ +#define WF_PLE_TOP_HOST_REPORT0_WMCPU_MSDU_ID_NUM_SHFT 4 +#define WF_PLE_TOP_HOST_REPORT0_HOST_RPT_TX_LATENCY_ADDR \ +WF_PLE_TOP_HOST_REPORT0_ADDR +#define WF_PLE_TOP_HOST_REPORT0_HOST_RPT_TX_LATENCY_MASK \ +0x00000008 /* HOST_RPT_TX_LATENCY[3] */ +#define WF_PLE_TOP_HOST_REPORT0_HOST_RPT_TX_LATENCY_SHFT 3 +#define WF_PLE_TOP_HOST_REPORT0_HOST_RPT_VER0_EN_ADDR \ +WF_PLE_TOP_HOST_REPORT0_ADDR +#define WF_PLE_TOP_HOST_REPORT0_HOST_RPT_VER0_EN_MASK \ +0x00000004 /* HOST_RPT_VER0_EN[2] */ +#define WF_PLE_TOP_HOST_REPORT0_HOST_RPT_VER0_EN_SHFT 2 +#define WF_PLE_TOP_HOST_REPORT0_DIS_HOST_RPT_ADDR WF_PLE_TOP_HOST_REPORT0_ADDR +#define WF_PLE_TOP_HOST_REPORT0_DIS_HOST_RPT_MASK \ +0x00000002 /* DIS_HOST_RPT[1] */ +#define WF_PLE_TOP_HOST_REPORT0_DIS_HOST_RPT_SHFT 1 + +/* +* ---HOST_REPORT1 (0x820C0000 + 0x34)--- +* SPL_RPT_QID[6..0] - (RW) PSE Queue ID control for SPL report. +* SPL_RPT_PID[7] - (RW) PSE Port ID control for SPL report. +* MD_RPT_QID[14..8] - (RW) PSE Queue ID control for MD CPU host +report. +* MD_RPT_PID[15] - (RW) PSE Port ID control for MD CPU host +report. +* HOST_RPT_PG_SIZE[19..16] - (RW) Setting of host report used PSE page +size. +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_HOST_REPORT1_HOST_RPT_PG_SIZE_ADDR \ +WF_PLE_TOP_HOST_REPORT1_ADDR +#define WF_PLE_TOP_HOST_REPORT1_HOST_RPT_PG_SIZE_MASK \ +0x000F0000 /* HOST_RPT_PG_SIZE[19..16] */ +#define WF_PLE_TOP_HOST_REPORT1_HOST_RPT_PG_SIZE_SHFT 16 +#define WF_PLE_TOP_HOST_REPORT1_MD_RPT_PID_ADDR WF_PLE_TOP_HOST_REPORT1_ADDR +#define WF_PLE_TOP_HOST_REPORT1_MD_RPT_PID_MASK 0x00008000 /* MD_RPT_PID[15] \ + */ +#define WF_PLE_TOP_HOST_REPORT1_MD_RPT_PID_SHFT 15 +#define WF_PLE_TOP_HOST_REPORT1_MD_RPT_QID_ADDR WF_PLE_TOP_HOST_REPORT1_ADDR +#define WF_PLE_TOP_HOST_REPORT1_MD_RPT_QID_MASK \ +0x00007F00 /* MD_RPT_QID[14..8] */ +#define WF_PLE_TOP_HOST_REPORT1_MD_RPT_QID_SHFT 8 +#define WF_PLE_TOP_HOST_REPORT1_SPL_RPT_PID_ADDR WF_PLE_TOP_HOST_REPORT1_ADDR +#define WF_PLE_TOP_HOST_REPORT1_SPL_RPT_PID_MASK 0x00000080 /* SPL_RPT_PID[7]\ + */ +#define WF_PLE_TOP_HOST_REPORT1_SPL_RPT_PID_SHFT 7 +#define WF_PLE_TOP_HOST_REPORT1_SPL_RPT_QID_ADDR WF_PLE_TOP_HOST_REPORT1_ADDR +#define WF_PLE_TOP_HOST_REPORT1_SPL_RPT_QID_MASK \ +0x0000007F /* SPL_RPT_QID[6..0] */ +#define WF_PLE_TOP_HOST_REPORT1_SPL_RPT_QID_SHFT 0 + +/* +* ---HOST_REPORT2 (0x820C0000 + 0x38)--- +* BN1_HOST_RPT_QID[6..0] - (RW) PSE Queue ID control for BN1 Host +report. +* BN1_HOST_RPT_PID[7] - (RW) PSE Port ID control for BN1 Host report. +* BN1_MD_RPT_QID[14..8] - (RW) PSE Queue ID control for BN1 MD CPU host +report. +* BN1_MD_RPT_PID[15] - (RW) PSE Port ID control for BN1 MD CPU host +report. +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_HOST_REPORT2_BN1_MD_RPT_PID_ADDR WF_PLE_TOP_HOST_REPORT2_ADDR +#define WF_PLE_TOP_HOST_REPORT2_BN1_MD_RPT_PID_MASK \ +0x00008000 /* BN1_MD_RPT_PID[15] */ +#define WF_PLE_TOP_HOST_REPORT2_BN1_MD_RPT_PID_SHFT 15 +#define WF_PLE_TOP_HOST_REPORT2_BN1_MD_RPT_QID_ADDR WF_PLE_TOP_HOST_REPORT2_ADDR +#define WF_PLE_TOP_HOST_REPORT2_BN1_MD_RPT_QID_MASK \ +0x00007F00 /* BN1_MD_RPT_QID[14..8] */ +#define WF_PLE_TOP_HOST_REPORT2_BN1_MD_RPT_QID_SHFT 8 +#define WF_PLE_TOP_HOST_REPORT2_BN1_HOST_RPT_PID_ADDR \ +WF_PLE_TOP_HOST_REPORT2_ADDR +#define WF_PLE_TOP_HOST_REPORT2_BN1_HOST_RPT_PID_MASK \ +0x00000080 /* BN1_HOST_RPT_PID[7] */ +#define WF_PLE_TOP_HOST_REPORT2_BN1_HOST_RPT_PID_SHFT 7 +#define WF_PLE_TOP_HOST_REPORT2_BN1_HOST_RPT_QID_ADDR \ +WF_PLE_TOP_HOST_REPORT2_ADDR +#define WF_PLE_TOP_HOST_REPORT2_BN1_HOST_RPT_QID_MASK \ +0x0000007F /* BN1_HOST_RPT_QID[6..0] */ +#define WF_PLE_TOP_HOST_REPORT2_BN1_HOST_RPT_QID_SHFT 0 + +/* +* ---BLK_MODE_RATE_LMT (0x820C0000 + 0x3c)--- +* BN0_MACTX_BLK_RATE_LMT[15..0] - (RW) TX Rate limitaion of CutThrough data +* block mode. The rate less then the limitation would turn on block mode. +* BN1_MACTX_BLK_RATE_LMT[31..16] - (RW) TX Rate limitaion of CutThrough data +* block mode. The rate less then the limitation would turn on block mode. +*/ +#define WF_PLE_TOP_BLK_MODE_RATE_LMT_BN1_MACTX_BLK_RATE_LMT_ADDR \ +WF_PLE_TOP_BLK_MODE_RATE_LMT_ADDR +#define WF_PLE_TOP_BLK_MODE_RATE_LMT_BN1_MACTX_BLK_RATE_LMT_MASK \ +0xFFFF0000 /* BN1_MACTX_BLK_RATE_LMT[31..16] */ +#define WF_PLE_TOP_BLK_MODE_RATE_LMT_BN1_MACTX_BLK_RATE_LMT_SHFT 16 +#define WF_PLE_TOP_BLK_MODE_RATE_LMT_BN0_MACTX_BLK_RATE_LMT_ADDR \ +WF_PLE_TOP_BLK_MODE_RATE_LMT_ADDR +#define WF_PLE_TOP_BLK_MODE_RATE_LMT_BN0_MACTX_BLK_RATE_LMT_MASK \ +0x0000FFFF /* BN0_MACTX_BLK_RATE_LMT[15..0] */ +#define WF_PLE_TOP_BLK_MODE_RATE_LMT_BN0_MACTX_BLK_RATE_LMT_SHFT 0 + +/* +* ---C_GET_FID_0 (0x820C0000 + 0x40)--- +* GET_SRC_WLANID[9..0] - (RW) Source WLAN ID for get frame ID. +* RESERVED10[11..10] - (RO) Reserved bits +* GET_SRC_TGID[12] - (RW) Source TX Group ID for get frame ID. +* RESERVED13[13] - (RO) Reserved bits +* GET_SRC_PID[15..14] - (RW) Source port ID for get frame ID. +* GET_FRAME_TYPE[19..16] - (RW) GET_SUB_TYPE +* RESERVED20[23..20] - (RO) Reserved bits +* GET_SRC_QID[30..24] - (RW) Source Queue ID for get frame ID. +* EXECUTE[31] - (A0) Executes command +*/ +#define WF_PLE_TOP_C_GET_FID_0_EXECUTE_ADDR WF_PLE_TOP_C_GET_FID_0_ADDR +#define WF_PLE_TOP_C_GET_FID_0_EXECUTE_MASK 0x80000000 /* EXECUTE[31] */ +#define WF_PLE_TOP_C_GET_FID_0_EXECUTE_SHFT 31 +#define WF_PLE_TOP_C_GET_FID_0_GET_SRC_QID_ADDR WF_PLE_TOP_C_GET_FID_0_ADDR +#define WF_PLE_TOP_C_GET_FID_0_GET_SRC_QID_MASK \ +0x7F000000 /* GET_SRC_QID[30..24] */ +#define WF_PLE_TOP_C_GET_FID_0_GET_SRC_QID_SHFT 24 +#define WF_PLE_TOP_C_GET_FID_0_GET_FRAME_TYPE_ADDR WF_PLE_TOP_C_GET_FID_0_ADDR +#define WF_PLE_TOP_C_GET_FID_0_GET_FRAME_TYPE_MASK \ +0x000F0000 /* GET_FRAME_TYPE[19..16] */ +#define WF_PLE_TOP_C_GET_FID_0_GET_FRAME_TYPE_SHFT 16 +#define WF_PLE_TOP_C_GET_FID_0_GET_SRC_PID_ADDR WF_PLE_TOP_C_GET_FID_0_ADDR +#define WF_PLE_TOP_C_GET_FID_0_GET_SRC_PID_MASK \ +0x0000C000 /* GET_SRC_PID[15..14] */ +#define WF_PLE_TOP_C_GET_FID_0_GET_SRC_PID_SHFT 14 +#define WF_PLE_TOP_C_GET_FID_0_GET_SRC_TGID_ADDR WF_PLE_TOP_C_GET_FID_0_ADDR +#define WF_PLE_TOP_C_GET_FID_0_GET_SRC_TGID_MASK \ +0x00001000 /* GET_SRC_TGID[12] */ +#define WF_PLE_TOP_C_GET_FID_0_GET_SRC_TGID_SHFT 12 +#define WF_PLE_TOP_C_GET_FID_0_GET_SRC_WLANID_ADDR WF_PLE_TOP_C_GET_FID_0_ADDR +#define WF_PLE_TOP_C_GET_FID_0_GET_SRC_WLANID_MASK \ +0x000003FF /* GET_SRC_WLANID[9..0] */ +#define WF_PLE_TOP_C_GET_FID_0_GET_SRC_WLANID_SHFT 0 + +/* +* ---C_GET_FID_1 (0x820C0000 + 0x44)--- +* GET_RETURN_FID[11..0] - (RO) Return frame ID +* RESERVED12[14..12] - (RO) Reserved bits +* END[15] - (RO) Return frame ID is end FID. +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_C_GET_FID_1_END_ADDR WF_PLE_TOP_C_GET_FID_1_ADDR +#define WF_PLE_TOP_C_GET_FID_1_END_MASK 0x00008000 /* END[15] */ +#define WF_PLE_TOP_C_GET_FID_1_END_SHFT 15 +#define WF_PLE_TOP_C_GET_FID_1_GET_RETURN_FID_ADDR WF_PLE_TOP_C_GET_FID_1_ADDR +#define WF_PLE_TOP_C_GET_FID_1_GET_RETURN_FID_MASK \ +0x00000FFF /* GET_RETURN_FID[11..0] */ +#define WF_PLE_TOP_C_GET_FID_1_GET_RETURN_FID_SHFT 0 + +/* +* ---RELEASE_CTRL_0 (0x820C0000 + 0x50)--- +* NOR_RLS_QID[6..0] - (RW) Normal TX packet release DST QID +* RESERVED7[7] - (RO) Reserved bits +* NOR_RLS_PID[9..8] - (RW) Normal TX packet release DST PID +* RESERVED10[15..10] - (RO) Reserved bits +* DROP_RLS_QID[22..16] - (RW) Drop packet release DST QID +* RESERVED23[23] - (RO) Reserved bits +* DROP_RLS_PID[25..24] - (RW) Drop packet release DST PID +* RESERVED26[31..26] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_RELEASE_CTRL_0_DROP_RLS_PID_ADDR \ +WF_PLE_TOP_RELEASE_CTRL_0_ADDR +#define WF_PLE_TOP_RELEASE_CTRL_0_DROP_RLS_PID_MASK \ +0x03000000 /* DROP_RLS_PID[25..24] */ +#define WF_PLE_TOP_RELEASE_CTRL_0_DROP_RLS_PID_SHFT 24 +#define WF_PLE_TOP_RELEASE_CTRL_0_DROP_RLS_QID_ADDR \ +WF_PLE_TOP_RELEASE_CTRL_0_ADDR +#define WF_PLE_TOP_RELEASE_CTRL_0_DROP_RLS_QID_MASK \ +0x007F0000 /* DROP_RLS_QID[22..16] */ +#define WF_PLE_TOP_RELEASE_CTRL_0_DROP_RLS_QID_SHFT 16 +#define WF_PLE_TOP_RELEASE_CTRL_0_NOR_RLS_PID_ADDR \ +WF_PLE_TOP_RELEASE_CTRL_0_ADDR +#define WF_PLE_TOP_RELEASE_CTRL_0_NOR_RLS_PID_MASK \ +0x00000300 /* NOR_RLS_PID[9..8] */ +#define WF_PLE_TOP_RELEASE_CTRL_0_NOR_RLS_PID_SHFT 8 +#define WF_PLE_TOP_RELEASE_CTRL_0_NOR_RLS_QID_ADDR \ +WF_PLE_TOP_RELEASE_CTRL_0_ADDR +#define WF_PLE_TOP_RELEASE_CTRL_0_NOR_RLS_QID_MASK \ +0x0000007F /* NOR_RLS_QID[6..0] */ +#define WF_PLE_TOP_RELEASE_CTRL_0_NOR_RLS_QID_SHFT 0 + +/* +* ---RELEASE_CTRL_1 (0x820C0000 + 0x54)--- +* BCN0_RLS_QID[6..0] - (RW) Beacon 0 packet release DST QID +* RESERVED7[7] - (RO) Reserved bits +* BCN0_RLS_PID[9..8] - (RW) Beacon 0 packet release DST PID +* RESERVED10[15..10] - (RO) Reserved bits +* BCN1_RLS_QID[22..16] - (RW) Beacon 1 packet release DST QID +* RESERVED23[23] - (RO) Reserved bits +* BCN1_RLS_PID[25..24] - (RW) Beacon 1 packet release DST PID +* RESERVED26[31..26] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_RELEASE_CTRL_1_BCN1_RLS_PID_ADDR \ +WF_PLE_TOP_RELEASE_CTRL_1_ADDR +#define WF_PLE_TOP_RELEASE_CTRL_1_BCN1_RLS_PID_MASK \ +0x03000000 /* BCN1_RLS_PID[25..24] */ +#define WF_PLE_TOP_RELEASE_CTRL_1_BCN1_RLS_PID_SHFT 24 +#define WF_PLE_TOP_RELEASE_CTRL_1_BCN1_RLS_QID_ADDR \ +WF_PLE_TOP_RELEASE_CTRL_1_ADDR +#define WF_PLE_TOP_RELEASE_CTRL_1_BCN1_RLS_QID_MASK \ +0x007F0000 /* BCN1_RLS_QID[22..16] */ +#define WF_PLE_TOP_RELEASE_CTRL_1_BCN1_RLS_QID_SHFT 16 +#define WF_PLE_TOP_RELEASE_CTRL_1_BCN0_RLS_PID_ADDR \ +WF_PLE_TOP_RELEASE_CTRL_1_ADDR +#define WF_PLE_TOP_RELEASE_CTRL_1_BCN0_RLS_PID_MASK \ +0x00000300 /* BCN0_RLS_PID[9..8] */ +#define WF_PLE_TOP_RELEASE_CTRL_1_BCN0_RLS_PID_SHFT 8 +#define WF_PLE_TOP_RELEASE_CTRL_1_BCN0_RLS_QID_ADDR \ +WF_PLE_TOP_RELEASE_CTRL_1_ADDR +#define WF_PLE_TOP_RELEASE_CTRL_1_BCN0_RLS_QID_MASK \ +0x0000007F /* BCN0_RLS_QID[6..0] */ +#define WF_PLE_TOP_RELEASE_CTRL_1_BCN0_RLS_QID_SHFT 0 + +/* +* ---RELEASE_CTRL_2 (0x820C0000 + 0x58)--- +* TXCMD0_RLS_QID[6..0] - (RW) TXCMD 0 packet release DST QID +* RESERVED7[7] - (RO) Reserved bits +* TXCMD0_RLS_PID[9..8] - (RW) TXCMD 0 packet release DST PID +* RESERVED10[15..10] - (RO) Reserved bits +* TXCMD1_RLS_QID[22..16] - (RW) TXCDM 1 packet release DST QID +* RESERVED23[23] - (RO) Reserved bits +* TXCMD1_RLS_PID[25..24] - (RW) TXCMD 1 packet release DST PID +* RESERVED26[31..26] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_RELEASE_CTRL_2_TXCMD1_RLS_PID_ADDR \ +WF_PLE_TOP_RELEASE_CTRL_2_ADDR +#define WF_PLE_TOP_RELEASE_CTRL_2_TXCMD1_RLS_PID_MASK \ +0x03000000 /* TXCMD1_RLS_PID[25..24] */ +#define WF_PLE_TOP_RELEASE_CTRL_2_TXCMD1_RLS_PID_SHFT 24 +#define WF_PLE_TOP_RELEASE_CTRL_2_TXCMD1_RLS_QID_ADDR \ +WF_PLE_TOP_RELEASE_CTRL_2_ADDR +#define WF_PLE_TOP_RELEASE_CTRL_2_TXCMD1_RLS_QID_MASK \ +0x007F0000 /* TXCMD1_RLS_QID[22..16] */ +#define WF_PLE_TOP_RELEASE_CTRL_2_TXCMD1_RLS_QID_SHFT 16 +#define WF_PLE_TOP_RELEASE_CTRL_2_TXCMD0_RLS_PID_ADDR \ +WF_PLE_TOP_RELEASE_CTRL_2_ADDR +#define WF_PLE_TOP_RELEASE_CTRL_2_TXCMD0_RLS_PID_MASK \ +0x00000300 /* TXCMD0_RLS_PID[9..8] */ +#define WF_PLE_TOP_RELEASE_CTRL_2_TXCMD0_RLS_PID_SHFT 8 +#define WF_PLE_TOP_RELEASE_CTRL_2_TXCMD0_RLS_QID_ADDR \ +WF_PLE_TOP_RELEASE_CTRL_2_ADDR +#define WF_PLE_TOP_RELEASE_CTRL_2_TXCMD0_RLS_QID_MASK \ +0x0000007F /* TXCMD0_RLS_QID[6..0] */ +#define WF_PLE_TOP_RELEASE_CTRL_2_TXCMD0_RLS_QID_SHFT 0 + +/* +* ---RELEASE_CTRL_3 (0x820C0000 + 0x5c)--- +* RLS_FREE_DONE_PG_SIZE[3..0] - (RW) Page size configuration of Free done +* event(host report). +* RESERVED4[31..4] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_RELEASE_CTRL_3_RLS_FREE_DONE_PG_SIZE_ADDR \ +WF_PLE_TOP_RELEASE_CTRL_3_ADDR +#define WF_PLE_TOP_RELEASE_CTRL_3_RLS_FREE_DONE_PG_SIZE_MASK \ +0x0000000F /* RLS_FREE_DONE_PG_SIZE[3..0] */ +#define WF_PLE_TOP_RELEASE_CTRL_3_RLS_FREE_DONE_PG_SIZE_SHFT 0 + +/* +* ---C_EN_QUEUE_0 (0x820C0000 + 0x60)--- +* DST_WLANID[9..0] - (RW) Destination WLANID for enqueue +* RESERVED10[11..10] - (RO) Reserved bits +* DST_TGID[12] - (RW) Destination TX Group ID for enqueue +* RESERVED13[13] - (RO) Reserved bits +* DST_PID[15..14] - (RW) Destination port ID for enqueue +* SUB_TYPE[19..16] - (RW) Sub-type of enqueue command +* RESERVED20[22..20] - (RO) Reserved bits +* DELAY_ENQ[23] - (RW) Delay enqueue +* ENQ_DST_QID[30..24] - (RW) Destination queue ID for enqueue +* EXECUTE[31] - (A0) Executes command +*/ +#define WF_PLE_TOP_C_EN_QUEUE_0_EXECUTE_ADDR WF_PLE_TOP_C_EN_QUEUE_0_ADDR +#define WF_PLE_TOP_C_EN_QUEUE_0_EXECUTE_MASK 0x80000000 /* EXECUTE[31] */ +#define WF_PLE_TOP_C_EN_QUEUE_0_EXECUTE_SHFT 31 +#define WF_PLE_TOP_C_EN_QUEUE_0_ENQ_DST_QID_ADDR WF_PLE_TOP_C_EN_QUEUE_0_ADDR +#define WF_PLE_TOP_C_EN_QUEUE_0_ENQ_DST_QID_MASK \ +0x7F000000 /* ENQ_DST_QID[30..24] */ +#define WF_PLE_TOP_C_EN_QUEUE_0_ENQ_DST_QID_SHFT 24 +#define WF_PLE_TOP_C_EN_QUEUE_0_DELAY_ENQ_ADDR WF_PLE_TOP_C_EN_QUEUE_0_ADDR +#define WF_PLE_TOP_C_EN_QUEUE_0_DELAY_ENQ_MASK 0x00800000 /* DELAY_ENQ[23] */ +#define WF_PLE_TOP_C_EN_QUEUE_0_DELAY_ENQ_SHFT 23 +#define WF_PLE_TOP_C_EN_QUEUE_0_SUB_TYPE_ADDR WF_PLE_TOP_C_EN_QUEUE_0_ADDR +#define WF_PLE_TOP_C_EN_QUEUE_0_SUB_TYPE_MASK 0x000F0000 /* SUB_TYPE[19..16] \ + */ +#define WF_PLE_TOP_C_EN_QUEUE_0_SUB_TYPE_SHFT 16 +#define WF_PLE_TOP_C_EN_QUEUE_0_DST_PID_ADDR WF_PLE_TOP_C_EN_QUEUE_0_ADDR +#define WF_PLE_TOP_C_EN_QUEUE_0_DST_PID_MASK 0x0000C000 /* DST_PID[15..14] */ +#define WF_PLE_TOP_C_EN_QUEUE_0_DST_PID_SHFT 14 +#define WF_PLE_TOP_C_EN_QUEUE_0_DST_TGID_ADDR WF_PLE_TOP_C_EN_QUEUE_0_ADDR +#define WF_PLE_TOP_C_EN_QUEUE_0_DST_TGID_MASK 0x00001000 /* DST_TGID[12] */ +#define WF_PLE_TOP_C_EN_QUEUE_0_DST_TGID_SHFT 12 +#define WF_PLE_TOP_C_EN_QUEUE_0_DST_WLANID_ADDR WF_PLE_TOP_C_EN_QUEUE_0_ADDR +#define WF_PLE_TOP_C_EN_QUEUE_0_DST_WLANID_MASK \ +0x000003FF /* DST_WLANID[9..0] */ +#define WF_PLE_TOP_C_EN_QUEUE_0_DST_WLANID_SHFT 0 + +/* +* ---C_EN_QUEUE_1 (0x820C0000 + 0x64)--- +* CUR_LIST_FID_START[11..0] - (RW) Start frame ID of enqueue operation +* list, enqueue FID of enqueue operation +* RESERVED12[15..12] - (RO) Reserved bits +* CUR_LIST_FID_END[27..16] - (RW) End frame ID of enqueue operation list +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_C_EN_QUEUE_1_CUR_LIST_FID_END_ADDR \ +WF_PLE_TOP_C_EN_QUEUE_1_ADDR +#define WF_PLE_TOP_C_EN_QUEUE_1_CUR_LIST_FID_END_MASK \ +0x0FFF0000 /* CUR_LIST_FID_END[27..16] */ +#define WF_PLE_TOP_C_EN_QUEUE_1_CUR_LIST_FID_END_SHFT 16 +#define WF_PLE_TOP_C_EN_QUEUE_1_CUR_LIST_FID_START_ADDR \ +WF_PLE_TOP_C_EN_QUEUE_1_ADDR +#define WF_PLE_TOP_C_EN_QUEUE_1_CUR_LIST_FID_START_MASK \ +0x00000FFF /* CUR_LIST_FID_START[11..0] */ +#define WF_PLE_TOP_C_EN_QUEUE_1_CUR_LIST_FID_START_SHFT 0 + +/* +* ---C_EN_QUEUE_2 (0x820C0000 + 0x68)--- +* TARGET_FID[11..0] - (RW) Target reference FID for enqueue +operation +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_C_EN_QUEUE_2_TARGET_FID_ADDR WF_PLE_TOP_C_EN_QUEUE_2_ADDR +#define WF_PLE_TOP_C_EN_QUEUE_2_TARGET_FID_MASK \ +0x00000FFF /* TARGET_FID[11..0] */ +#define WF_PLE_TOP_C_EN_QUEUE_2_TARGET_FID_SHFT 0 + +/* +* ---C_DE_QUEUE_0 (0x820C0000 + 0x80)--- +* SRC_WLANID[9..0] - (RW) Source WLAN ID for dequeue command +* RESERVED10[11..10] - (RO) Reserved bits +* SRC_TGID[12] - (RW) Source TX Group ID for dequeue command +* RESERVED13[13] - (RO) Reserved bits +* SRC_PID[15..14] - (RW) Source port ID for dequeue command +* DEQ_SUB_TYPE[19..16] - (RW) Dequeue subtype of dequeue command +* ENQ_SUB_TYPE[22..20] - (RW) Enqueue subtype of enqueue command +* Only valid in Deq&Enq type. +* ENQ_VLD[23] - (RW) Deq&Enq command valid +* SRC_QID[30..24] - (RW) Source queue ID for dequeue command +* EXECUTE[31] - (A0) Executes dequeue command +*/ +#define WF_PLE_TOP_C_DE_QUEUE_0_EXECUTE_ADDR WF_PLE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_0_EXECUTE_MASK 0x80000000 /* EXECUTE[31] */ +#define WF_PLE_TOP_C_DE_QUEUE_0_EXECUTE_SHFT 31 +#define WF_PLE_TOP_C_DE_QUEUE_0_SRC_QID_ADDR WF_PLE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_0_SRC_QID_MASK 0x7F000000 /* SRC_QID[30..24] */ +#define WF_PLE_TOP_C_DE_QUEUE_0_SRC_QID_SHFT 24 +#define WF_PLE_TOP_C_DE_QUEUE_0_ENQ_VLD_ADDR WF_PLE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_0_ENQ_VLD_MASK 0x00800000 /* ENQ_VLD[23] */ +#define WF_PLE_TOP_C_DE_QUEUE_0_ENQ_VLD_SHFT 23 +#define WF_PLE_TOP_C_DE_QUEUE_0_ENQ_SUB_TYPE_ADDR WF_PLE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_0_ENQ_SUB_TYPE_MASK \ +0x00700000 /* ENQ_SUB_TYPE[22..20] */ +#define WF_PLE_TOP_C_DE_QUEUE_0_ENQ_SUB_TYPE_SHFT 20 +#define WF_PLE_TOP_C_DE_QUEUE_0_DEQ_SUB_TYPE_ADDR WF_PLE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_0_DEQ_SUB_TYPE_MASK \ +0x000F0000 /* DEQ_SUB_TYPE[19..16] */ +#define WF_PLE_TOP_C_DE_QUEUE_0_DEQ_SUB_TYPE_SHFT 16 +#define WF_PLE_TOP_C_DE_QUEUE_0_SRC_PID_ADDR WF_PLE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_0_SRC_PID_MASK 0x0000C000 /* SRC_PID[15..14] */ +#define WF_PLE_TOP_C_DE_QUEUE_0_SRC_PID_SHFT 14 +#define WF_PLE_TOP_C_DE_QUEUE_0_SRC_TGID_ADDR WF_PLE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_0_SRC_TGID_MASK 0x00001000 /* SRC_TGID[12] */ +#define WF_PLE_TOP_C_DE_QUEUE_0_SRC_TGID_SHFT 12 +#define WF_PLE_TOP_C_DE_QUEUE_0_SRC_WLANID_ADDR WF_PLE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_0_SRC_WLANID_MASK \ +0x000003FF /* SRC_WLANID[9..0] */ +#define WF_PLE_TOP_C_DE_QUEUE_0_SRC_WLANID_SHFT 0 + +/* +* ---C_DE_QUEUE_1 (0x820C0000 + 0x84)--- +* CUR_LIST_FID_START[11..0] - (RW) Start frame ID of dequeue operation +* list, enqueue start FID of enqueue operation +* Only valid in Deq&Enq type. +* RESERVED12[15..12] - (RO) Reserved bits +* CUR_LIST_FID_END[27..16] - (RW) End framd ID of dequeue operation list, +* enqueue end FID of enqueue operation +* Only valid in Deq&Enq type. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_C_DE_QUEUE_1_CUR_LIST_FID_END_ADDR \ +WF_PLE_TOP_C_DE_QUEUE_1_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_1_CUR_LIST_FID_END_MASK \ +0x0FFF0000 /* CUR_LIST_FID_END[27..16] */ +#define WF_PLE_TOP_C_DE_QUEUE_1_CUR_LIST_FID_END_SHFT 16 +#define WF_PLE_TOP_C_DE_QUEUE_1_CUR_LIST_FID_START_ADDR \ +WF_PLE_TOP_C_DE_QUEUE_1_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_1_CUR_LIST_FID_START_MASK \ +0x00000FFF /* CUR_LIST_FID_START[11..0] */ +#define WF_PLE_TOP_C_DE_QUEUE_1_CUR_LIST_FID_START_SHFT 0 + +/* +* ---C_DE_QUEUE_2 (0x820C0000 + 0x88)--- +* DEQ_ENQ_DST_WLANID[9..0] - (RW) Destination WLAN ID for enqueue command +* Only valid in Deq&Enq type. +* RESERVED10[11..10] - (RO) Reserved bits +* DEQ_ENQ_DST_TGID[12] - (RW) Destination TX Group ID for enqueue +command +* Only valid in Deq&Enq type. +* RESERVED13[13] - (RO) Reserved bits +* DEQ_ENQ_DST_PID[15..14] - (RW) Destination port ID for enqueue command +* OInly valid in Deq&Enq type. +* RESERVED16[23..16] - (RO) Reserved bits +* DEQ_ENQ_DST_QID[30..24] - (RW) Destination queue ID for enqueue command +* Only valid in Deq&Enq type. +* RESERVED31[31] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_QID_ADDR \ +WF_PLE_TOP_C_DE_QUEUE_2_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_QID_MASK \ +0x7F000000 /* DEQ_ENQ_DST_QID[30..24] */ +#define WF_PLE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_QID_SHFT 24 +#define WF_PLE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_PID_ADDR \ +WF_PLE_TOP_C_DE_QUEUE_2_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_PID_MASK \ +0x0000C000 /* DEQ_ENQ_DST_PID[15..14] */ +#define WF_PLE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_PID_SHFT 14 +#define WF_PLE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_TGID_ADDR \ +WF_PLE_TOP_C_DE_QUEUE_2_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_TGID_MASK \ +0x00001000 /* DEQ_ENQ_DST_TGID[12] */ +#define WF_PLE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_TGID_SHFT 12 +#define WF_PLE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_WLANID_ADDR \ +WF_PLE_TOP_C_DE_QUEUE_2_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_WLANID_MASK \ +0x000003FF /* DEQ_ENQ_DST_WLANID[9..0] */ +#define WF_PLE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_WLANID_SHFT 0 + +/* +* ---C_DE_QUEUE_3 (0x820C0000 + 0x8c)--- +* DEQ_HEAD_FID[11..0] - (RO) Head FID got from dequeue command +* RESERVED12[14..12] - (RO) Reserved bits +* DEQ_EMPTY[15] - (RO) Queue empty after dequeue command is +executed +* DEQ_TAIL_FID[27..16] - (RO) Last FID got from dequeue command +* RESERVED28[30..28] - (RO) Reserved bits +* BUSY[31] - (RO) Dequeue execute busy +*/ +#define WF_PLE_TOP_C_DE_QUEUE_3_BUSY_ADDR WF_PLE_TOP_C_DE_QUEUE_3_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_3_BUSY_MASK 0x80000000 /* BUSY[31] */ +#define WF_PLE_TOP_C_DE_QUEUE_3_BUSY_SHFT 31 +#define WF_PLE_TOP_C_DE_QUEUE_3_DEQ_TAIL_FID_ADDR WF_PLE_TOP_C_DE_QUEUE_3_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_3_DEQ_TAIL_FID_MASK \ +0x0FFF0000 /* DEQ_TAIL_FID[27..16] */ +#define WF_PLE_TOP_C_DE_QUEUE_3_DEQ_TAIL_FID_SHFT 16 +#define WF_PLE_TOP_C_DE_QUEUE_3_DEQ_EMPTY_ADDR WF_PLE_TOP_C_DE_QUEUE_3_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_3_DEQ_EMPTY_MASK 0x00008000 /* DEQ_EMPTY[15] */ +#define WF_PLE_TOP_C_DE_QUEUE_3_DEQ_EMPTY_SHFT 15 +#define WF_PLE_TOP_C_DE_QUEUE_3_DEQ_HEAD_FID_ADDR WF_PLE_TOP_C_DE_QUEUE_3_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_3_DEQ_HEAD_FID_MASK \ +0x00000FFF /* DEQ_HEAD_FID[11..0] */ +#define WF_PLE_TOP_C_DE_QUEUE_3_DEQ_HEAD_FID_SHFT 0 + +/* +* ---C_DE_QUEUE_4 (0x820C0000 + 0x90)--- +* DEQ_ENQ_REF_FID[11..0] - (RW) Reference frame ID for enqueue command +* Only valid in Deq&Enq type. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_C_DE_QUEUE_4_DEQ_ENQ_REF_FID_ADDR \ +WF_PLE_TOP_C_DE_QUEUE_4_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_4_DEQ_ENQ_REF_FID_MASK \ +0x00000FFF /* DEQ_ENQ_REF_FID[11..0] */ +#define WF_PLE_TOP_C_DE_QUEUE_4_DEQ_ENQ_REF_FID_SHFT 0 + +/* +* ---ALLOCATE_0 (0x820C0000 + 0xA0)--- +* ALLOCATE_FRAME_LENGTH[13..0] - (RW) Allocate frame length +* Unit: DW (4 bytes) +* RESERVED14[15..14] - (RO) Reserved bits +* ALLOCATE_QID[20..16] - (RW) QID used for allocate buffer +* RESERVED21[30..21] - (RO) Reserved bits +* EXECUTE[31] - (A0) Executes allocate buffer command +*/ +#define WF_PLE_TOP_ALLOCATE_0_EXECUTE_ADDR WF_PLE_TOP_ALLOCATE_0_ADDR +#define WF_PLE_TOP_ALLOCATE_0_EXECUTE_MASK 0x80000000 /* EXECUTE[31] */ +#define WF_PLE_TOP_ALLOCATE_0_EXECUTE_SHFT 31 +#define WF_PLE_TOP_ALLOCATE_0_ALLOCATE_QID_ADDR WF_PLE_TOP_ALLOCATE_0_ADDR +#define WF_PLE_TOP_ALLOCATE_0_ALLOCATE_QID_MASK \ +0x001F0000 /* ALLOCATE_QID[20..16] */ +#define WF_PLE_TOP_ALLOCATE_0_ALLOCATE_QID_SHFT 16 +#define WF_PLE_TOP_ALLOCATE_0_ALLOCATE_FRAME_LENGTH_ADDR \ +WF_PLE_TOP_ALLOCATE_0_ADDR +#define WF_PLE_TOP_ALLOCATE_0_ALLOCATE_FRAME_LENGTH_MASK \ +0x00003FFF /* ALLOCATE_FRAME_LENGTH[13..0] */ +#define WF_PLE_TOP_ALLOCATE_0_ALLOCATE_FRAME_LENGTH_SHFT 0 + +/* +* ---ALLOCATE_1 (0x820C0000 + 0xA4)--- +* ALLOCATE_FID[11..0] - (RO) Return frame ID for allocate buffer +command +* RESERVED12[30..12] - (RO) Reserved bits +* EXECUTE[31] - (RO) Execute status of allocate buffer +command +*/ +#define WF_PLE_TOP_ALLOCATE_1_EXECUTE_ADDR WF_PLE_TOP_ALLOCATE_1_ADDR +#define WF_PLE_TOP_ALLOCATE_1_EXECUTE_MASK 0x80000000 /* EXECUTE[31] */ +#define WF_PLE_TOP_ALLOCATE_1_EXECUTE_SHFT 31 +#define WF_PLE_TOP_ALLOCATE_1_ALLOCATE_FID_ADDR WF_PLE_TOP_ALLOCATE_1_ADDR +#define WF_PLE_TOP_ALLOCATE_1_ALLOCATE_FID_MASK \ +0x00000FFF /* ALLOCATE_FID[11..0] */ +#define WF_PLE_TOP_ALLOCATE_1_ALLOCATE_FID_SHFT 0 + +/* +* ---ALLOCATE_2 (0x820C0000 + 0xA8)--- +* CPU_TXBYTE_COUNT[15..0] - (RW) TX data byte count +* This value should be the same as the first +* two bytes of TXD in PLE. +* CPU_MSDU_ID0_bit15_8[23..16] - (RW) MSDU_ID0 Bit15-Bit8 +* This value should be the same as the +* DW8[15:8] of TXD in PLE. +* CPU_PKT_FT[25..24] - (RW) TXD's PKT_FT +* This value should be the same as the +* DW0[24:23] of TXD in PLE. +* RESERVED26[31..26] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_ALLOCATE_2_CPU_PKT_FT_ADDR WF_PLE_TOP_ALLOCATE_2_ADDR +#define WF_PLE_TOP_ALLOCATE_2_CPU_PKT_FT_MASK \ +0x03000000 /* CPU_PKT_FT[25..24] */ +#define WF_PLE_TOP_ALLOCATE_2_CPU_PKT_FT_SHFT 24 +#define WF_PLE_TOP_ALLOCATE_2_CPU_MSDU_ID0_bit15_8_ADDR \ +WF_PLE_TOP_ALLOCATE_2_ADDR +#define WF_PLE_TOP_ALLOCATE_2_CPU_MSDU_ID0_bit15_8_MASK \ +0x00FF0000 /* CPU_MSDU_ID0_bit15_8[23..16] */ +#define WF_PLE_TOP_ALLOCATE_2_CPU_MSDU_ID0_bit15_8_SHFT 16 +#define WF_PLE_TOP_ALLOCATE_2_CPU_TXBYTE_COUNT_ADDR WF_PLE_TOP_ALLOCATE_2_ADDR +#define WF_PLE_TOP_ALLOCATE_2_CPU_TXBYTE_COUNT_MASK \ +0x0000FFFF /* CPU_TXBYTE_COUNT[15..0] */ +#define WF_PLE_TOP_ALLOCATE_2_CPU_TXBYTE_COUNT_SHFT 0 + +/* +* ---QUEUE_EMPTY (0x820C0000 + 0xB0)--- +* CPU_Q0_EMPTY[0] - (RO) CPU queue 0 empty status +* CPU_Q1_EMPTY[1] - (RO) CPU queue 1 empty status +* CPU_Q2_EMPTY[2] - (RO) CPU queue 2 empty status +* CPU_Q3_EMPTY[3] - (RO) CPU queue 3 empty status +* RESERVED4[7..4] - (RO) Reserved bits +* ALTX_0_EMPTY[8] - (RO) ALTX queue 0 empty status +* BMC_0_EMPTY[9] - (RO) BMC queue 0 empty status +* BCN_0_EMPTY[10] - (RO) BCN queue 0 empty status +* PSMP_0_EMPTY[11] - (RO) PSMP queue 0 empty status +* ALTX_1_EMPTY[12] - (RO) ALTX queue 1 empty status +* BMC_1_EMPTY[13] - (RO) BMC queue 1 empty status +* BCN_1_EMPTY[14] - (RO) BCN queue 1 empty status +* PSMP_1_EMPTY[15] - (RO) PSMP queue 1 empty status +* NAF_EMPTY[16] - (RO) NAF queue empty status +* NBCN_EMPTY[17] - (RO) NBCN queue empty status +* RESERVED18[19..18] - (RO) Reserved bits +* FIX_FID_EMPTY[20] - (RO) FIX_FID queue empty status +* RESERVED21[23..21] - (RO) Reserved bits +* ALL_AC_EMPTY[24] - (RO) All AC queue empty status +* RESERVED25[29..25] - (RO) Reserved bits +* RLS2_Q_EMTPY[30] - (RO) Release 2 queue empty status +* RLS_Q_EMTPY[31] - (RO) Release queue empty status +*/ +#define WF_PLE_TOP_QUEUE_EMPTY_RLS_Q_EMTPY_ADDR WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_RLS_Q_EMTPY_MASK 0x80000000 /* RLS_Q_EMTPY[31]\ + */ +#define WF_PLE_TOP_QUEUE_EMPTY_RLS_Q_EMTPY_SHFT 31 +#define WF_PLE_TOP_QUEUE_EMPTY_RLS2_Q_EMTPY_ADDR WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_RLS2_Q_EMTPY_MASK \ +0x40000000 /* RLS2_Q_EMTPY[30] */ +#define WF_PLE_TOP_QUEUE_EMPTY_RLS2_Q_EMTPY_SHFT 30 +#define WF_PLE_TOP_QUEUE_EMPTY_ALL_AC_EMPTY_ADDR WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_ALL_AC_EMPTY_MASK \ +0x01000000 /* ALL_AC_EMPTY[24] */ +#define WF_PLE_TOP_QUEUE_EMPTY_ALL_AC_EMPTY_SHFT 24 +#define WF_PLE_TOP_QUEUE_EMPTY_FIX_FID_EMPTY_ADDR WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_FIX_FID_EMPTY_MASK \ +0x00100000 /* FIX_FID_EMPTY[20] */ +#define WF_PLE_TOP_QUEUE_EMPTY_FIX_FID_EMPTY_SHFT 20 +#define WF_PLE_TOP_QUEUE_EMPTY_NBCN_EMPTY_ADDR WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_NBCN_EMPTY_MASK 0x00020000 /* NBCN_EMPTY[17] */ +#define WF_PLE_TOP_QUEUE_EMPTY_NBCN_EMPTY_SHFT 17 +#define WF_PLE_TOP_QUEUE_EMPTY_NAF_EMPTY_ADDR WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_NAF_EMPTY_MASK 0x00010000 /* NAF_EMPTY[16] */ +#define WF_PLE_TOP_QUEUE_EMPTY_NAF_EMPTY_SHFT 16 +#define WF_PLE_TOP_QUEUE_EMPTY_PSMP_1_EMPTY_ADDR WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_PSMP_1_EMPTY_MASK \ +0x00008000 /* PSMP_1_EMPTY[15] */ +#define WF_PLE_TOP_QUEUE_EMPTY_PSMP_1_EMPTY_SHFT 15 +#define WF_PLE_TOP_QUEUE_EMPTY_BCN_1_EMPTY_ADDR WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_BCN_1_EMPTY_MASK 0x00004000 /* BCN_1_EMPTY[14]\ + */ +#define WF_PLE_TOP_QUEUE_EMPTY_BCN_1_EMPTY_SHFT 14 +#define WF_PLE_TOP_QUEUE_EMPTY_BMC_1_EMPTY_ADDR WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_BMC_1_EMPTY_MASK 0x00002000 /* BMC_1_EMPTY[13]\ + */ +#define WF_PLE_TOP_QUEUE_EMPTY_BMC_1_EMPTY_SHFT 13 +#define WF_PLE_TOP_QUEUE_EMPTY_ALTX_1_EMPTY_ADDR WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_ALTX_1_EMPTY_MASK \ +0x00001000 /* ALTX_1_EMPTY[12] */ +#define WF_PLE_TOP_QUEUE_EMPTY_ALTX_1_EMPTY_SHFT 12 +#define WF_PLE_TOP_QUEUE_EMPTY_PSMP_0_EMPTY_ADDR WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_PSMP_0_EMPTY_MASK \ +0x00000800 /* PSMP_0_EMPTY[11] */ +#define WF_PLE_TOP_QUEUE_EMPTY_PSMP_0_EMPTY_SHFT 11 +#define WF_PLE_TOP_QUEUE_EMPTY_BCN_0_EMPTY_ADDR WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_BCN_0_EMPTY_MASK 0x00000400 /* BCN_0_EMPTY[10]\ + */ +#define WF_PLE_TOP_QUEUE_EMPTY_BCN_0_EMPTY_SHFT 10 +#define WF_PLE_TOP_QUEUE_EMPTY_BMC_0_EMPTY_ADDR WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_BMC_0_EMPTY_MASK 0x00000200 /* BMC_0_EMPTY[9] \ + */ +#define WF_PLE_TOP_QUEUE_EMPTY_BMC_0_EMPTY_SHFT 9 +#define WF_PLE_TOP_QUEUE_EMPTY_ALTX_0_EMPTY_ADDR WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_ALTX_0_EMPTY_MASK \ +0x00000100 /* ALTX_0_EMPTY[8] */ +#define WF_PLE_TOP_QUEUE_EMPTY_ALTX_0_EMPTY_SHFT 8 +#define WF_PLE_TOP_QUEUE_EMPTY_CPU_Q3_EMPTY_ADDR WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_CPU_Q3_EMPTY_MASK \ +0x00000008 /* CPU_Q3_EMPTY[3] */ +#define WF_PLE_TOP_QUEUE_EMPTY_CPU_Q3_EMPTY_SHFT 3 +#define WF_PLE_TOP_QUEUE_EMPTY_CPU_Q2_EMPTY_ADDR WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_CPU_Q2_EMPTY_MASK \ +0x00000004 /* CPU_Q2_EMPTY[2] */ +#define WF_PLE_TOP_QUEUE_EMPTY_CPU_Q2_EMPTY_SHFT 2 +#define WF_PLE_TOP_QUEUE_EMPTY_CPU_Q1_EMPTY_ADDR WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_CPU_Q1_EMPTY_MASK \ +0x00000002 /* CPU_Q1_EMPTY[1] */ +#define WF_PLE_TOP_QUEUE_EMPTY_CPU_Q1_EMPTY_SHFT 1 +#define WF_PLE_TOP_QUEUE_EMPTY_CPU_Q0_EMPTY_ADDR WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_CPU_Q0_EMPTY_MASK \ +0x00000001 /* CPU_Q0_EMPTY[0] */ +#define WF_PLE_TOP_QUEUE_EMPTY_CPU_Q0_EMPTY_SHFT 0 + +/* +* ---FREEPG_START_END (0x820C0000 + 0xc0)--- +* FREEPG_START[11..0] - (RW) Start page for free page list +* Set start page before release PLE logic +* reset, and must not be changed after release logic reset. +* RESERVED12[15..12] - (RO) Reserved bits +* FREEPG_END[27..16] - (RW) End page for free page list +* Set end page before release PLE logic +* reset, and must not be changed after release logic reset. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_FREEPG_START_END_FREEPG_END_ADDR \ +WF_PLE_TOP_FREEPG_START_END_ADDR +#define WF_PLE_TOP_FREEPG_START_END_FREEPG_END_MASK \ +0x0FFF0000 /* FREEPG_END[27..16] */ +#define WF_PLE_TOP_FREEPG_START_END_FREEPG_END_SHFT 16 +#define WF_PLE_TOP_FREEPG_START_END_FREEPG_START_ADDR \ +WF_PLE_TOP_FREEPG_START_END_ADDR +#define WF_PLE_TOP_FREEPG_START_END_FREEPG_START_MASK \ +0x00000FFF /* FREEPG_START[11..0] */ +#define WF_PLE_TOP_FREEPG_START_END_FREEPG_START_SHFT 0 + +/* +* ---PLE_MODULE_CKG_DIS (0x820C0000 + 0xc4)--- +* DIS_FL_DYN_CKG[0] - (RW) Disable control of PLE frame link module +* dynamic clock gating function +* DIS_PL_DYN_CKG[1] - (RW) Disable control of PLE page link module +* dynamic clock gating function +* DIS_CPU_PORT_DYN_CKG[2] - (RW) Disable control of PLE CPU port module +* dynamic clock gating function +* DIS_HIF_PORT_DYN_CKG[3] - (RW) Disable control of PLE HIF port module +* dynamic clock gating function +* DIS_WF_PORT_DYN_CKG[4] - (RW) Disable control of PLE LMAC module +* dynamic clock gating function +* DIS_RLS_DYN_CKG[5] - (RW) Disable control of PLE release module +* dynamic clock gating function +* DIS_RL_DYN_CKG[6] - (RW) Disable control of PLE relay information +* module dynamic clock gating function +* DIS_MACTX_DYN_CKG[7] - (RW) Disable control of PLE MACTX module +* dynamic clock gating function +* DIS_PSEPORT_DYN_CKG[8] - (RW) Disable control of PLE PSE port module +* dynamic clock gating function +* DIS_CSR_DYN_CKG[9] - (RW) Disable control of PLE CR module dynamic +* clock gating function +* DIS_CPU_WRAP_DYN_CKG[10] - (RW) Disable control of PLE CPU_WRAP module +* dynamic clock gating function +* DIS_DBG_DYN_CKG[11] - (RW) Disable control of PLE debug module +* dynamic clock gating function +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_DBG_DYN_CKG_ADDR \ +WF_PLE_TOP_PLE_MODULE_CKG_DIS_ADDR +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_DBG_DYN_CKG_MASK \ +0x00000800 /* DIS_DBG_DYN_CKG[11] */ +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_DBG_DYN_CKG_SHFT 11 +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_CPU_WRAP_DYN_CKG_ADDR \ +WF_PLE_TOP_PLE_MODULE_CKG_DIS_ADDR +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_CPU_WRAP_DYN_CKG_MASK \ +0x00000400 /* DIS_CPU_WRAP_DYN_CKG[10] */ +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_CPU_WRAP_DYN_CKG_SHFT 10 +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_CSR_DYN_CKG_ADDR \ +WF_PLE_TOP_PLE_MODULE_CKG_DIS_ADDR +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_CSR_DYN_CKG_MASK \ +0x00000200 /* DIS_CSR_DYN_CKG[9] */ +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_CSR_DYN_CKG_SHFT 9 +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_PSEPORT_DYN_CKG_ADDR \ +WF_PLE_TOP_PLE_MODULE_CKG_DIS_ADDR +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_PSEPORT_DYN_CKG_MASK \ +0x00000100 /* DIS_PSEPORT_DYN_CKG[8] */ +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_PSEPORT_DYN_CKG_SHFT 8 +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_MACTX_DYN_CKG_ADDR \ +WF_PLE_TOP_PLE_MODULE_CKG_DIS_ADDR +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_MACTX_DYN_CKG_MASK \ +0x00000080 /* DIS_MACTX_DYN_CKG[7] */ +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_MACTX_DYN_CKG_SHFT 7 +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_RL_DYN_CKG_ADDR \ +WF_PLE_TOP_PLE_MODULE_CKG_DIS_ADDR +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_RL_DYN_CKG_MASK \ +0x00000040 /* DIS_RL_DYN_CKG[6] */ +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_RL_DYN_CKG_SHFT 6 +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_RLS_DYN_CKG_ADDR \ +WF_PLE_TOP_PLE_MODULE_CKG_DIS_ADDR +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_RLS_DYN_CKG_MASK \ +0x00000020 /* DIS_RLS_DYN_CKG[5] */ +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_RLS_DYN_CKG_SHFT 5 +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_WF_PORT_DYN_CKG_ADDR \ +WF_PLE_TOP_PLE_MODULE_CKG_DIS_ADDR +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_WF_PORT_DYN_CKG_MASK \ +0x00000010 /* DIS_WF_PORT_DYN_CKG[4] */ +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_WF_PORT_DYN_CKG_SHFT 4 +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_HIF_PORT_DYN_CKG_ADDR \ +WF_PLE_TOP_PLE_MODULE_CKG_DIS_ADDR +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_HIF_PORT_DYN_CKG_MASK \ +0x00000008 /* DIS_HIF_PORT_DYN_CKG[3] */ +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_HIF_PORT_DYN_CKG_SHFT 3 +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_CPU_PORT_DYN_CKG_ADDR \ +WF_PLE_TOP_PLE_MODULE_CKG_DIS_ADDR +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_CPU_PORT_DYN_CKG_MASK \ +0x00000004 /* DIS_CPU_PORT_DYN_CKG[2] */ +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_CPU_PORT_DYN_CKG_SHFT 2 +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_PL_DYN_CKG_ADDR \ +WF_PLE_TOP_PLE_MODULE_CKG_DIS_ADDR +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_PL_DYN_CKG_MASK \ +0x00000002 /* DIS_PL_DYN_CKG[1] */ +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_PL_DYN_CKG_SHFT 1 +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_FL_DYN_CKG_ADDR \ +WF_PLE_TOP_PLE_MODULE_CKG_DIS_ADDR +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_FL_DYN_CKG_MASK \ +0x00000001 /* DIS_FL_DYN_CKG[0] */ +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_FL_DYN_CKG_SHFT 0 + +/* +* ---INT_N9_ERR_STS_1 (0x820C0000 + 0xd8)--- +* BN0_MDP_TDP_HANG_ERR[0] - (W1C) BN0 MDP TDP FSM hang error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* MDP_RDP_HANG_ERR[1] - (W1C) MDP RDP FSM hang error interrupt. Avoid +* unclear error flag, please clear flag when logic reset. +* BN0_MDP_TIOC_HANG_ERR[2] - (W1C) BN0 MDP TIOC FSM hang error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* BN0_MDP_RIOC_HANG_ERR[3] - (W1C) BN0 MDP RIOC FSM hang error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* PF_HANG_ERR[4] - (W1C) PF FSM hang error interrupt. Avoid +* unclear error flag, please clear flag when logic reset. +* SEC0_HANG_ERR[5] - (W1C) SEC 0 FSM hang error interrupt. Avoid +* unclear error flag, please clear flag when logic reset. +* SEC1_HANG_ERR[6] - (W1C) SEC 1 FSM hang error interrupt. Avoid +* unclear error flag, please clear flag when logic reset. +* BN1_MDP_TDP_HANG_ERR[7] - (W1C) BN1 MDP TDP FSM hang error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* BN1_MDP_TIOC_HANG_ERR[8] - (W1C) BN1 MDP TIOC FSM hang error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* BN1_MDP_RIOC_HANG_ERR[9] - (W1C) BN1 MDP RIOC FSM hang error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* RESERVED10[11..10] - (RO) Reserved bits +* BN0_RPEDL_ARB_HANG_ERR[12] - (W1C) BN0 PREDL ARB hang error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* BN0_PREDL_TXCMD_HANG_ERR[13] - (W1C) BN0 PREDL TXCDM FSM hang error +* interrupt. Avoid unclear error flag, please clear flag when logic reset. +* BN1_RPEDL_ARB_HANG_ERR[14] - (W1C) BN1 PREDL ARB hang error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* BN1_PREDL_TXCMD_HANG_ERR[15] - (W1C) BN1 PREDL TXCDM FSM hang error +* interrupt. Avoid unclear error flag, please clear flag when logic reset. +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_PREDL_TXCMD_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_PREDL_TXCMD_HANG_ERR_MASK \ +0x00008000 /* BN1_PREDL_TXCMD_HANG_ERR[15] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_PREDL_TXCMD_HANG_ERR_SHFT 15 +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_RPEDL_ARB_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_RPEDL_ARB_HANG_ERR_MASK \ +0x00004000 /* BN1_RPEDL_ARB_HANG_ERR[14] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_RPEDL_ARB_HANG_ERR_SHFT 14 +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_PREDL_TXCMD_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_PREDL_TXCMD_HANG_ERR_MASK \ +0x00002000 /* BN0_PREDL_TXCMD_HANG_ERR[13] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_PREDL_TXCMD_HANG_ERR_SHFT 13 +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_RPEDL_ARB_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_RPEDL_ARB_HANG_ERR_MASK \ +0x00001000 /* BN0_RPEDL_ARB_HANG_ERR[12] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_RPEDL_ARB_HANG_ERR_SHFT 12 +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_MDP_RIOC_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_MDP_RIOC_HANG_ERR_MASK \ +0x00000200 /* BN1_MDP_RIOC_HANG_ERR[9] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_MDP_RIOC_HANG_ERR_SHFT 9 +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_MDP_TIOC_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_MDP_TIOC_HANG_ERR_MASK \ +0x00000100 /* BN1_MDP_TIOC_HANG_ERR[8] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_MDP_TIOC_HANG_ERR_SHFT 8 +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_MDP_TDP_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_MDP_TDP_HANG_ERR_MASK \ +0x00000080 /* BN1_MDP_TDP_HANG_ERR[7] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_MDP_TDP_HANG_ERR_SHFT 7 +#define WF_PLE_TOP_INT_N9_ERR_STS_1_SEC1_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_1_SEC1_HANG_ERR_MASK \ +0x00000040 /* SEC1_HANG_ERR[6] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_SEC1_HANG_ERR_SHFT 6 +#define WF_PLE_TOP_INT_N9_ERR_STS_1_SEC0_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_1_SEC0_HANG_ERR_MASK \ +0x00000020 /* SEC0_HANG_ERR[5] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_SEC0_HANG_ERR_SHFT 5 +#define WF_PLE_TOP_INT_N9_ERR_STS_1_PF_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_1_PF_HANG_ERR_MASK \ +0x00000010 /* PF_HANG_ERR[4] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_PF_HANG_ERR_SHFT 4 +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_MDP_RIOC_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_MDP_RIOC_HANG_ERR_MASK \ +0x00000008 /* BN0_MDP_RIOC_HANG_ERR[3] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_MDP_RIOC_HANG_ERR_SHFT 3 +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_MDP_TIOC_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_MDP_TIOC_HANG_ERR_MASK \ +0x00000004 /* BN0_MDP_TIOC_HANG_ERR[2] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_MDP_TIOC_HANG_ERR_SHFT 2 +#define WF_PLE_TOP_INT_N9_ERR_STS_1_MDP_RDP_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_1_MDP_RDP_HANG_ERR_MASK \ +0x00000002 /* MDP_RDP_HANG_ERR[1] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_MDP_RDP_HANG_ERR_SHFT 1 +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_MDP_TDP_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_MDP_TDP_HANG_ERR_MASK \ +0x00000001 /* BN0_MDP_TDP_HANG_ERR[0] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_MDP_TDP_HANG_ERR_SHFT 0 + +/* +* ---INT_N9_ERR_MASK_1 (0x820C0000 + 0xdc)--- +* EN_BN0_MDP_TDP_HANG_ERR[0] - (RW) Enables Band0 MDP TDP FSM hang error +interrupt +* EN_MDP_RDP_HANG_ERR[1] - (RW) Enables MDP RDP FSM hang error interrupt +* EN_BN0_MDP_TIOC_HANG_ERR[2] - (RW) Enables Band0 MDP TIOC FSM hang error +interrupt +* EN_BN0_MDP_RIOC_HANG_ERR[3] - (RW) Enables Band0 MDP RIOC FSM hang error +interrupt +* EN_PF_HANG_ERR[4] - (RW) Enables PF FSM hang error interrupt +* EN_SEC0_HANG_ERR[5] - (RW) Enables SEC 0 FSM hang error interrupt +* EN_SEC1_HANG_ERR[6] - (RW) Enables SEC 1 FSM hang error interrupt +* EN_BN1_MDP_TDP_HANG_ERR[7] - (RW) Enables Band1 MDP TDP FSM hang error +interrupt +* EN_BN1_MDP_TIOC_HANG_ERR[8] - (RW) Enables Band1 MDP TIOC FSM hang error +interrupt +* EN_BN1_MDP_RIOC_HANG_ERR[9] - (RW) Enables Band1 MDP RIOC FSM hang error +interrupt +* RESERVED10[11..10] - (RO) Reserved bits +* EN_BN0_PREDL_ARB_HANG_ERR[12] - (RW) Enables Band0 PREDL ARB FSM hang error +interrupt +* EN_BN0_PREDL_TXCMD_HANG_ERR[13] - (RW) Enables Band0 PREDL TXCMD parser FSM +* hang error interrupt +* EN_BN1_PREDL_ARB_HANG_ERR[14] - (RW) Enables Band1 PREDL ARB FSM hang error +interrupt +* EN_BN1_PREDL_TXCMD_HANG_ERR[15] - (RW) Enables Band1 PREDL TXCMD parser FSM +* hang error interrupt +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_PREDL_TXCMD_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_PREDL_TXCMD_HANG_ERR_MASK \ +0x00008000 /* EN_BN1_PREDL_TXCMD_HANG_ERR[15] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_PREDL_TXCMD_HANG_ERR_SHFT 15 +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_PREDL_ARB_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_PREDL_ARB_HANG_ERR_MASK \ +0x00004000 /* EN_BN1_PREDL_ARB_HANG_ERR[14] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_PREDL_ARB_HANG_ERR_SHFT 14 +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_PREDL_TXCMD_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_PREDL_TXCMD_HANG_ERR_MASK \ +0x00002000 /* EN_BN0_PREDL_TXCMD_HANG_ERR[13] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_PREDL_TXCMD_HANG_ERR_SHFT 13 +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_PREDL_ARB_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_PREDL_ARB_HANG_ERR_MASK \ +0x00001000 /* EN_BN0_PREDL_ARB_HANG_ERR[12] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_PREDL_ARB_HANG_ERR_SHFT 12 +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_MDP_RIOC_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_MDP_RIOC_HANG_ERR_MASK \ +0x00000200 /* EN_BN1_MDP_RIOC_HANG_ERR[9] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_MDP_RIOC_HANG_ERR_SHFT 9 +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_MDP_TIOC_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_MDP_TIOC_HANG_ERR_MASK \ +0x00000100 /* EN_BN1_MDP_TIOC_HANG_ERR[8] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_MDP_TIOC_HANG_ERR_SHFT 8 +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_MDP_TDP_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_MDP_TDP_HANG_ERR_MASK \ +0x00000080 /* EN_BN1_MDP_TDP_HANG_ERR[7] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_MDP_TDP_HANG_ERR_SHFT 7 +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_SEC1_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_SEC1_HANG_ERR_MASK \ +0x00000040 /* EN_SEC1_HANG_ERR[6] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_SEC1_HANG_ERR_SHFT 6 +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_SEC0_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_SEC0_HANG_ERR_MASK \ +0x00000020 /* EN_SEC0_HANG_ERR[5] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_SEC0_HANG_ERR_SHFT 5 +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_PF_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_PF_HANG_ERR_MASK \ +0x00000010 /* EN_PF_HANG_ERR[4] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_PF_HANG_ERR_SHFT 4 +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_MDP_RIOC_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_MDP_RIOC_HANG_ERR_MASK \ +0x00000008 /* EN_BN0_MDP_RIOC_HANG_ERR[3] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_MDP_RIOC_HANG_ERR_SHFT 3 +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_MDP_TIOC_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_MDP_TIOC_HANG_ERR_MASK \ +0x00000004 /* EN_BN0_MDP_TIOC_HANG_ERR[2] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_MDP_TIOC_HANG_ERR_SHFT 2 +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_MDP_RDP_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_MDP_RDP_HANG_ERR_MASK \ +0x00000002 /* EN_MDP_RDP_HANG_ERR[1] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_MDP_RDP_HANG_ERR_SHFT 1 +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_MDP_TDP_HANG_ERR_ADDR \ +WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_MDP_TDP_HANG_ERR_MASK \ +0x00000001 /* EN_BN0_MDP_TDP_HANG_ERR[0] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_MDP_TDP_HANG_ERR_SHFT 0 + +/* +* ---TO_N9_INT (0x820C0000 + 0xf0)--- +* CR4_CMD[30..0] - (RW) Command for N9 +* TOGGLE[31] - (RW) When this bit is toggled, HW will send +* interrupt to N9. +*/ +#define WF_PLE_TOP_TO_N9_INT_TOGGLE_ADDR WF_PLE_TOP_TO_N9_INT_ADDR +#define WF_PLE_TOP_TO_N9_INT_TOGGLE_MASK 0x80000000 /* TOGGLE[31] */ +#define WF_PLE_TOP_TO_N9_INT_TOGGLE_SHFT 31 +#define WF_PLE_TOP_TO_N9_INT_CR4_CMD_ADDR WF_PLE_TOP_TO_N9_INT_ADDR +#define WF_PLE_TOP_TO_N9_INT_CR4_CMD_MASK 0x7FFFFFFF /* CR4_CMD[30..0] */ +#define WF_PLE_TOP_TO_N9_INT_CR4_CMD_SHFT 0 + +/* +* ---N9_BSS_PS_INT_MASK (0x820C0000 + 0xf4)--- +* EN_BSSID0_NONEMPTY_INT[0] - (RW) Enable control of BSSID0 queue empty +fall +* EN_BSSID1_NONEMPTY_INT[1] - (RW) Enable control of BSSID1 queue empty +fall +* EN_BSSID2_NONEMPTY_INT[2] - (RW) Enable control of BSSID2 queue empty +fall +* EN_BSSID3_NONEMPTY_INT[3] - (RW) Enable control of BSSID3 queue empty +fall +* RESERVED4[7..4] - (RO) Reserved bits +* EN_BSSID0_EMPTY_INT[8] - (RW) Enable control of BSSID0 queue empty +raise +* EN_BSSID1_EMPTY_INT[9] - (RW) Enable control of BSSID1 queue empty +raise +* EN_BSSID2_EMPTY_INT[10] - (RW) Enable control of BSSID2 queue empty +raise +* EN_BSSID3_EMPTY_INT[11] - (RW) Enable control of BSSID3 queue empty +raise +* RESERVED12[15..12] - (RO) Reserved bits +* EN_BSSID0_ENQ_LMAC_INT[16] - (RW) Enable control of BSSID0 enqueue +interrupt +* EN_BSSID1_ENQ_LMAC_INT[17] - (RW) Enable control of BSSID1 enqueue +interrupt +* EN_BSSID2_ENQ_LMAC_INT[18] - (RW) Enable control of BSSID2 enqueue +interrupt +* EN_BSSID3_ENQ_LMAC_INT[19] - (RW) Enable control of BSSID3 enqueue +interrupt +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID3_ENQ_LMAC_INT_ADDR \ +WF_PLE_TOP_N9_BSS_PS_INT_MASK_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID3_ENQ_LMAC_INT_MASK \ +0x00080000 /* EN_BSSID3_ENQ_LMAC_INT[19] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID3_ENQ_LMAC_INT_SHFT 19 +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID2_ENQ_LMAC_INT_ADDR \ +WF_PLE_TOP_N9_BSS_PS_INT_MASK_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID2_ENQ_LMAC_INT_MASK \ +0x00040000 /* EN_BSSID2_ENQ_LMAC_INT[18] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID2_ENQ_LMAC_INT_SHFT 18 +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID1_ENQ_LMAC_INT_ADDR \ +WF_PLE_TOP_N9_BSS_PS_INT_MASK_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID1_ENQ_LMAC_INT_MASK \ +0x00020000 /* EN_BSSID1_ENQ_LMAC_INT[17] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID1_ENQ_LMAC_INT_SHFT 17 +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID0_ENQ_LMAC_INT_ADDR \ +WF_PLE_TOP_N9_BSS_PS_INT_MASK_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID0_ENQ_LMAC_INT_MASK \ +0x00010000 /* EN_BSSID0_ENQ_LMAC_INT[16] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID0_ENQ_LMAC_INT_SHFT 16 +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID3_EMPTY_INT_ADDR \ +WF_PLE_TOP_N9_BSS_PS_INT_MASK_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID3_EMPTY_INT_MASK \ +0x00000800 /* EN_BSSID3_EMPTY_INT[11] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID3_EMPTY_INT_SHFT 11 +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID2_EMPTY_INT_ADDR \ +WF_PLE_TOP_N9_BSS_PS_INT_MASK_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID2_EMPTY_INT_MASK \ +0x00000400 /* EN_BSSID2_EMPTY_INT[10] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID2_EMPTY_INT_SHFT 10 +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID1_EMPTY_INT_ADDR \ +WF_PLE_TOP_N9_BSS_PS_INT_MASK_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID1_EMPTY_INT_MASK \ +0x00000200 /* EN_BSSID1_EMPTY_INT[9] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID1_EMPTY_INT_SHFT 9 +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID0_EMPTY_INT_ADDR \ +WF_PLE_TOP_N9_BSS_PS_INT_MASK_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID0_EMPTY_INT_MASK \ +0x00000100 /* EN_BSSID0_EMPTY_INT[8] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID0_EMPTY_INT_SHFT 8 +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID3_NONEMPTY_INT_ADDR \ +WF_PLE_TOP_N9_BSS_PS_INT_MASK_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID3_NONEMPTY_INT_MASK \ +0x00000008 /* EN_BSSID3_NONEMPTY_INT[3] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID3_NONEMPTY_INT_SHFT 3 +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID2_NONEMPTY_INT_ADDR \ +WF_PLE_TOP_N9_BSS_PS_INT_MASK_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID2_NONEMPTY_INT_MASK \ +0x00000004 /* EN_BSSID2_NONEMPTY_INT[2] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID2_NONEMPTY_INT_SHFT 2 +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID1_NONEMPTY_INT_ADDR \ +WF_PLE_TOP_N9_BSS_PS_INT_MASK_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID1_NONEMPTY_INT_MASK \ +0x00000002 /* EN_BSSID1_NONEMPTY_INT[1] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID1_NONEMPTY_INT_SHFT 1 +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID0_NONEMPTY_INT_ADDR \ +WF_PLE_TOP_N9_BSS_PS_INT_MASK_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID0_NONEMPTY_INT_MASK \ +0x00000001 /* EN_BSSID0_NONEMPTY_INT[0] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID0_NONEMPTY_INT_SHFT 0 + +/* +* ---N9_BSS_PS_INT_STS (0x820C0000 + 0xf8)--- +* BSSID0_NONEMPTY_INT[0] - (W1C) BSSID0 queue empty fall interrupt +status +* BSSID1_NONEMPTY_INT[1] - (W1C) BSSID1 queue empty fall interrupt +status +* BSSID2_NONEMPTY_INT[2] - (W1C) BSSID2 queue empty fall interrupt +status +* BSSID3_NONEMPTY_INT[3] - (W1C) BSSID3 queue empty fall interrupt +status +* RESERVED4[7..4] - (RO) Reserved bits +* BSSID0_EMPTY_INT[8] - (W1C) BSSID0 queue empty raise interrupt +status +* BSSID1_EMPTY_INT[9] - (W1C) BSSID1 queue empty raise interrupt +status +* BSSID2_EMPTY_INT[10] - (W1C) BSSID2 queue empty raise interrupt +status +* BSSID3_EMPTY_INT[11] - (W1C) BSSID3 queue empty raise interrupt +status +* RESERVED12[15..12] - (RO) Reserved bits +* BSSID0_ENQ_LMAC_INT[16] - (W1C) BSSID0 enqueue interrupt status +* BSSID1_ENQ_LMAC_INT[17] - (W1C) BSSID1 enqueue interrupt status +* BSSID2_ENQ_LMAC_INT[18] - (W1C) BSSID2 enqueue interrupt status +* BSSID3_ENQ_LMAC_INT[19] - (W1C) BSSID3 enqueue interrupt status +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID3_ENQ_LMAC_INT_ADDR \ +WF_PLE_TOP_N9_BSS_PS_INT_STS_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID3_ENQ_LMAC_INT_MASK \ +0x00080000 /* BSSID3_ENQ_LMAC_INT[19] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID3_ENQ_LMAC_INT_SHFT 19 +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID2_ENQ_LMAC_INT_ADDR \ +WF_PLE_TOP_N9_BSS_PS_INT_STS_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID2_ENQ_LMAC_INT_MASK \ +0x00040000 /* BSSID2_ENQ_LMAC_INT[18] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID2_ENQ_LMAC_INT_SHFT 18 +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID1_ENQ_LMAC_INT_ADDR \ +WF_PLE_TOP_N9_BSS_PS_INT_STS_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID1_ENQ_LMAC_INT_MASK \ +0x00020000 /* BSSID1_ENQ_LMAC_INT[17] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID1_ENQ_LMAC_INT_SHFT 17 +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID0_ENQ_LMAC_INT_ADDR \ +WF_PLE_TOP_N9_BSS_PS_INT_STS_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID0_ENQ_LMAC_INT_MASK \ +0x00010000 /* BSSID0_ENQ_LMAC_INT[16] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID0_ENQ_LMAC_INT_SHFT 16 +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID3_EMPTY_INT_ADDR \ +WF_PLE_TOP_N9_BSS_PS_INT_STS_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID3_EMPTY_INT_MASK \ +0x00000800 /* BSSID3_EMPTY_INT[11] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID3_EMPTY_INT_SHFT 11 +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID2_EMPTY_INT_ADDR \ +WF_PLE_TOP_N9_BSS_PS_INT_STS_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID2_EMPTY_INT_MASK \ +0x00000400 /* BSSID2_EMPTY_INT[10] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID2_EMPTY_INT_SHFT 10 +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID1_EMPTY_INT_ADDR \ +WF_PLE_TOP_N9_BSS_PS_INT_STS_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID1_EMPTY_INT_MASK \ +0x00000200 /* BSSID1_EMPTY_INT[9] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID1_EMPTY_INT_SHFT 9 +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID0_EMPTY_INT_ADDR \ +WF_PLE_TOP_N9_BSS_PS_INT_STS_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID0_EMPTY_INT_MASK \ +0x00000100 /* BSSID0_EMPTY_INT[8] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID0_EMPTY_INT_SHFT 8 +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID3_NONEMPTY_INT_ADDR \ +WF_PLE_TOP_N9_BSS_PS_INT_STS_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID3_NONEMPTY_INT_MASK \ +0x00000008 /* BSSID3_NONEMPTY_INT[3] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID3_NONEMPTY_INT_SHFT 3 +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID2_NONEMPTY_INT_ADDR \ +WF_PLE_TOP_N9_BSS_PS_INT_STS_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID2_NONEMPTY_INT_MASK \ +0x00000004 /* BSSID2_NONEMPTY_INT[2] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID2_NONEMPTY_INT_SHFT 2 +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID1_NONEMPTY_INT_ADDR \ +WF_PLE_TOP_N9_BSS_PS_INT_STS_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID1_NONEMPTY_INT_MASK \ +0x00000002 /* BSSID1_NONEMPTY_INT[1] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID1_NONEMPTY_INT_SHFT 1 +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID0_NONEMPTY_INT_ADDR \ +WF_PLE_TOP_N9_BSS_PS_INT_STS_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID0_NONEMPTY_INT_MASK \ +0x00000001 /* BSSID0_NONEMPTY_INT[0] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID0_NONEMPTY_INT_SHFT 0 + +/* +* ---FREEPG_CNT (0x820C0000 + 0x100)--- +* FREEPG_CNT[11..0] - (RO) Total page number of free +* RESERVED12[15..12] - (RO) Reserved bits +* FFA_CNT[27..16] - (RO) Free page numbers of free for all +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_FREEPG_CNT_FFA_CNT_ADDR WF_PLE_TOP_FREEPG_CNT_ADDR +#define WF_PLE_TOP_FREEPG_CNT_FFA_CNT_MASK 0x0FFF0000 /* FFA_CNT[27..16] */ +#define WF_PLE_TOP_FREEPG_CNT_FFA_CNT_SHFT 16 +#define WF_PLE_TOP_FREEPG_CNT_FREEPG_CNT_ADDR WF_PLE_TOP_FREEPG_CNT_ADDR +#define WF_PLE_TOP_FREEPG_CNT_FREEPG_CNT_MASK 0x00000FFF /* FREEPG_CNT[11..0]\ + */ +#define WF_PLE_TOP_FREEPG_CNT_FREEPG_CNT_SHFT 0 + +/* +* ---FREEPG_HEAD_TAIL (0x820C0000 + 0x104)--- +* FREEPG_HEAD[11..0] - (RO) Head page of free page list +* RESERVED12[15..12] - (RO) Reserved bits +* FREEPG_TAIL[27..16] - (RO) Tail page of free page list +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_FREEPG_HEAD_TAIL_FREEPG_TAIL_ADDR \ +WF_PLE_TOP_FREEPG_HEAD_TAIL_ADDR +#define WF_PLE_TOP_FREEPG_HEAD_TAIL_FREEPG_TAIL_MASK \ +0x0FFF0000 /* FREEPG_TAIL[27..16] */ +#define WF_PLE_TOP_FREEPG_HEAD_TAIL_FREEPG_TAIL_SHFT 16 +#define WF_PLE_TOP_FREEPG_HEAD_TAIL_FREEPG_HEAD_ADDR \ +WF_PLE_TOP_FREEPG_HEAD_TAIL_ADDR +#define WF_PLE_TOP_FREEPG_HEAD_TAIL_FREEPG_HEAD_MASK \ +0x00000FFF /* FREEPG_HEAD[11..0] */ +#define WF_PLE_TOP_FREEPG_HEAD_TAIL_FREEPG_HEAD_SHFT 0 + +/* +* ---PG_HIF_GROUP (0x820C0000 + 0x110)--- +* HIF_MIN_QUOTA[11..0] - (RW) Min. quota of HIF group +* Set the quota before release PLE logic +* reset ,and must not be changed after release logic reset. +* RESERVED12[15..12] - (RO) Reserved bits +* HIF_MAX_QUOTA[27..16] - (RW) Max. quota of HIF group +* Set up the quota before releasing PLE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_PG_HIF_GROUP_HIF_MAX_QUOTA_ADDR WF_PLE_TOP_PG_HIF_GROUP_ADDR +#define WF_PLE_TOP_PG_HIF_GROUP_HIF_MAX_QUOTA_MASK \ +0x0FFF0000 /* HIF_MAX_QUOTA[27..16] */ +#define WF_PLE_TOP_PG_HIF_GROUP_HIF_MAX_QUOTA_SHFT 16 +#define WF_PLE_TOP_PG_HIF_GROUP_HIF_MIN_QUOTA_ADDR WF_PLE_TOP_PG_HIF_GROUP_ADDR +#define WF_PLE_TOP_PG_HIF_GROUP_HIF_MIN_QUOTA_MASK \ +0x00000FFF /* HIF_MIN_QUOTA[11..0] */ +#define WF_PLE_TOP_PG_HIF_GROUP_HIF_MIN_QUOTA_SHFT 0 + +/* +* ---HIF_PG_INFO (0x820C0000 + 0x114)--- +* HIF_RSV_CNT[11..0] - (RO) Reserved pages of HIF group +* RESERVED12[15..12] - (RO) Reserved bits +* HIF_SRC_CNT[27..16] - (RO) Used pages of HIF group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_HIF_PG_INFO_HIF_SRC_CNT_ADDR WF_PLE_TOP_HIF_PG_INFO_ADDR +#define WF_PLE_TOP_HIF_PG_INFO_HIF_SRC_CNT_MASK \ +0x0FFF0000 /* HIF_SRC_CNT[27..16] */ +#define WF_PLE_TOP_HIF_PG_INFO_HIF_SRC_CNT_SHFT 16 +#define WF_PLE_TOP_HIF_PG_INFO_HIF_RSV_CNT_ADDR WF_PLE_TOP_HIF_PG_INFO_ADDR +#define WF_PLE_TOP_HIF_PG_INFO_HIF_RSV_CNT_MASK \ +0x00000FFF /* HIF_RSV_CNT[11..0] */ +#define WF_PLE_TOP_HIF_PG_INFO_HIF_RSV_CNT_SHFT 0 + +/* +* ---PG_HIF_WMTXD_GROUP (0x820C0000 + 0x118)--- +* HIF_WMTXD_MIN_QUOTA[11..0] - (RW) Min. quota of HIF WMCPU TXD group +* Set the quota before release PLE logic +* reset ,and must not be changed after release logic reset. +* RESERVED12[15..12] - (RO) Reserved bits +* HIF_WMTXD_MAX_QUOTA[27..16] - (RW) Max. quota of HIF WMCPU TXD group +* Set up the quota before releasing PLE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_PG_HIF_WMTXD_GROUP_HIF_WMTXD_MAX_QUOTA_ADDR \ +WF_PLE_TOP_PG_HIF_WMTXD_GROUP_ADDR +#define WF_PLE_TOP_PG_HIF_WMTXD_GROUP_HIF_WMTXD_MAX_QUOTA_MASK \ +0x0FFF0000 /* HIF_WMTXD_MAX_QUOTA[27..16] */ +#define WF_PLE_TOP_PG_HIF_WMTXD_GROUP_HIF_WMTXD_MAX_QUOTA_SHFT 16 +#define WF_PLE_TOP_PG_HIF_WMTXD_GROUP_HIF_WMTXD_MIN_QUOTA_ADDR \ +WF_PLE_TOP_PG_HIF_WMTXD_GROUP_ADDR +#define WF_PLE_TOP_PG_HIF_WMTXD_GROUP_HIF_WMTXD_MIN_QUOTA_MASK \ +0x00000FFF /* HIF_WMTXD_MIN_QUOTA[11..0] */ +#define WF_PLE_TOP_PG_HIF_WMTXD_GROUP_HIF_WMTXD_MIN_QUOTA_SHFT 0 + +/* +* ---HIF_WMTXD_PG_INFO (0x820C0000 + 0x11C)--- +* HIF_WMTXD_RSV_CNT[11..0] - (RO) Reserved pages of HIF WMCPU TXD group +* RESERVED12[15..12] - (RO) Reserved bits +* HIF_WMTXD_SRC_CNT[27..16] - (RO) Used pages of HIF WMCPU TXD group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_HIF_WMTXD_PG_INFO_HIF_WMTXD_SRC_CNT_ADDR \ +WF_PLE_TOP_HIF_WMTXD_PG_INFO_ADDR +#define WF_PLE_TOP_HIF_WMTXD_PG_INFO_HIF_WMTXD_SRC_CNT_MASK \ +0x0FFF0000 /* HIF_WMTXD_SRC_CNT[27..16] */ +#define WF_PLE_TOP_HIF_WMTXD_PG_INFO_HIF_WMTXD_SRC_CNT_SHFT 16 +#define WF_PLE_TOP_HIF_WMTXD_PG_INFO_HIF_WMTXD_RSV_CNT_ADDR \ +WF_PLE_TOP_HIF_WMTXD_PG_INFO_ADDR +#define WF_PLE_TOP_HIF_WMTXD_PG_INFO_HIF_WMTXD_RSV_CNT_MASK \ +0x00000FFF /* HIF_WMTXD_RSV_CNT[11..0] */ +#define WF_PLE_TOP_HIF_WMTXD_PG_INFO_HIF_WMTXD_RSV_CNT_SHFT 0 + +/* +* ---PG_HIF_TXCMD_GROUP (0x820C0000 + 0x120)--- +* HIF_TXCMD_MIN_QUOTA[11..0] - (RW) Min. quota of HIF TXCMD group +* Set the quota before release PLE logic +* reset ,and must not be changed after release logic reset. +* RESERVED12[15..12] - (RO) Reserved bits +* HIF_TXCMD_MAX_QUOTA[27..16] - (RW) Max. quota of HIF TXCMD group +* Set up the quota before releasing PLE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_PG_HIF_TXCMD_GROUP_HIF_TXCMD_MAX_QUOTA_ADDR \ +WF_PLE_TOP_PG_HIF_TXCMD_GROUP_ADDR +#define WF_PLE_TOP_PG_HIF_TXCMD_GROUP_HIF_TXCMD_MAX_QUOTA_MASK \ +0x0FFF0000 /* HIF_TXCMD_MAX_QUOTA[27..16] */ +#define WF_PLE_TOP_PG_HIF_TXCMD_GROUP_HIF_TXCMD_MAX_QUOTA_SHFT 16 +#define WF_PLE_TOP_PG_HIF_TXCMD_GROUP_HIF_TXCMD_MIN_QUOTA_ADDR \ +WF_PLE_TOP_PG_HIF_TXCMD_GROUP_ADDR +#define WF_PLE_TOP_PG_HIF_TXCMD_GROUP_HIF_TXCMD_MIN_QUOTA_MASK \ +0x00000FFF /* HIF_TXCMD_MIN_QUOTA[11..0] */ +#define WF_PLE_TOP_PG_HIF_TXCMD_GROUP_HIF_TXCMD_MIN_QUOTA_SHFT 0 + +/* +* ---HIF_TXCMD_PG_INFO (0x820C0000 + 0x124)--- +* HIF_TXCMD_RSV_CNT[11..0] - (RO) Reserved pages of HIF TXCMD group +* RESERVED12[15..12] - (RO) Reserved bits +* HIF_TXCMD_SRC_CNT[27..16] - (RO) Used pages of HIF TXCMD group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_HIF_TXCMD_PG_INFO_HIF_TXCMD_SRC_CNT_ADDR \ +WF_PLE_TOP_HIF_TXCMD_PG_INFO_ADDR +#define WF_PLE_TOP_HIF_TXCMD_PG_INFO_HIF_TXCMD_SRC_CNT_MASK \ +0x0FFF0000 /* HIF_TXCMD_SRC_CNT[27..16] */ +#define WF_PLE_TOP_HIF_TXCMD_PG_INFO_HIF_TXCMD_SRC_CNT_SHFT 16 +#define WF_PLE_TOP_HIF_TXCMD_PG_INFO_HIF_TXCMD_RSV_CNT_ADDR \ +WF_PLE_TOP_HIF_TXCMD_PG_INFO_ADDR +#define WF_PLE_TOP_HIF_TXCMD_PG_INFO_HIF_TXCMD_RSV_CNT_MASK \ +0x00000FFF /* HIF_TXCMD_RSV_CNT[11..0] */ +#define WF_PLE_TOP_HIF_TXCMD_PG_INFO_HIF_TXCMD_RSV_CNT_SHFT 0 + +/* +* ---TWT_TX_CTRL0 (0x820C0000 + 0x130)--- +* en_twt_stop_tx_ctrl_0[0] - (RW) Enable TWT non-active period TX control +function. +* en_twt_stop_tx_ctrl_1[1] - (RW) Enable TWT non-active period TX control +function. +* en_twt_stop_tx_ctrl_2[2] - (RW) Enable TWT non-active period TX control +function. +* en_twt_stop_tx_ctrl_3[3] - (RW) Enable TWT non-active period TX control +function. +* RESERVED4[31..4] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_TWT_TX_CTRL0_en_twt_stop_tx_ctrl_3_ADDR \ +WF_PLE_TOP_TWT_TX_CTRL0_ADDR +#define WF_PLE_TOP_TWT_TX_CTRL0_en_twt_stop_tx_ctrl_3_MASK \ +0x00000008 /* en_twt_stop_tx_ctrl_3[3] */ +#define WF_PLE_TOP_TWT_TX_CTRL0_en_twt_stop_tx_ctrl_3_SHFT 3 +#define WF_PLE_TOP_TWT_TX_CTRL0_en_twt_stop_tx_ctrl_2_ADDR \ +WF_PLE_TOP_TWT_TX_CTRL0_ADDR +#define WF_PLE_TOP_TWT_TX_CTRL0_en_twt_stop_tx_ctrl_2_MASK \ +0x00000004 /* en_twt_stop_tx_ctrl_2[2] */ +#define WF_PLE_TOP_TWT_TX_CTRL0_en_twt_stop_tx_ctrl_2_SHFT 2 +#define WF_PLE_TOP_TWT_TX_CTRL0_en_twt_stop_tx_ctrl_1_ADDR \ +WF_PLE_TOP_TWT_TX_CTRL0_ADDR +#define WF_PLE_TOP_TWT_TX_CTRL0_en_twt_stop_tx_ctrl_1_MASK \ +0x00000002 /* en_twt_stop_tx_ctrl_1[1] */ +#define WF_PLE_TOP_TWT_TX_CTRL0_en_twt_stop_tx_ctrl_1_SHFT 1 +#define WF_PLE_TOP_TWT_TX_CTRL0_en_twt_stop_tx_ctrl_0_ADDR \ +WF_PLE_TOP_TWT_TX_CTRL0_ADDR +#define WF_PLE_TOP_TWT_TX_CTRL0_en_twt_stop_tx_ctrl_0_MASK \ +0x00000001 /* en_twt_stop_tx_ctrl_0[0] */ +#define WF_PLE_TOP_TWT_TX_CTRL0_en_twt_stop_tx_ctrl_0_SHFT 0 + +/* +* ---PLE_FUNC_CTRL_0 (0x820C0000 + 0x140)--- +* MACTX_REQ_DEASSERT[0] - (RW) Enable of DeAsser MACTX REQ.(Normal +* operation must be zero.) +* MACTX_ABORT_DEASSERT[1] - (RW) Enable of DeAsser MACTX ABORT.(Normal +* operation must be zero.) +* MPDU_DONE_CNT_IN_NO_TX_REQ[2] - (RW) MPDU done mode for LMAC no TX request +* MPDU_DONE_CNT_IN_NO_ADD[3] - (RW) MPDU done mode for LMAC no add +* ACK_LMAC_NO_FID_ADD[4] - (RW) MACTX ack mode for LMAC no add any fid +* for TX +* RESERVED5[5] - (RO) Reserved bits +* DIS_STA_RLS_TO_1F[6] - (RW) Release port setting of disable STA +function +* RESERVED7[7] - (RO) Reserved bits +* MACTX_REQ_ASSERT[8] - (RW) Enable of Asser MACTX REQ.(Normal +* operation must be zero.) +* MACTX_ABORT_ASSERT[9] - (RW) Enable of Asser MACTX ABORT.(Normal +* operation must be zero.) +* RESERVED10[21..10] - (RO) Reserved bits +* DIS_AUTORATE_TXP_REQ[22] - (RW) Disable auto rate TXP request function +* LATER_PKT_PRE_CUT_1US[23] - (RW) Pre cut 1us air time for later packet. +* TXP_REQ_CNTDOWN_TH[27..24] - (RW) Threshold of air time count down for TXP +request +* TXP_REQ_HSPEED_DL_NUM[29..28] - (RW) Packet number of high speed TXP request +* issue, by pre-cut more micro-second +* TXP_REQ_HSPEED_CUT_US[31..30] - (RW) Number of pre-cut micro-second for high +* speed packet +*/ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_TXP_REQ_HSPEED_CUT_US_ADDR \ +WF_PLE_TOP_PLE_FUNC_CTRL_0_ADDR +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_TXP_REQ_HSPEED_CUT_US_MASK \ +0xC0000000 /* TXP_REQ_HSPEED_CUT_US[31..30] */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_TXP_REQ_HSPEED_CUT_US_SHFT 30 +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_TXP_REQ_HSPEED_DL_NUM_ADDR \ +WF_PLE_TOP_PLE_FUNC_CTRL_0_ADDR +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_TXP_REQ_HSPEED_DL_NUM_MASK \ +0x30000000 /* TXP_REQ_HSPEED_DL_NUM[29..28] */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_TXP_REQ_HSPEED_DL_NUM_SHFT 28 +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_TXP_REQ_CNTDOWN_TH_ADDR \ +WF_PLE_TOP_PLE_FUNC_CTRL_0_ADDR +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_TXP_REQ_CNTDOWN_TH_MASK \ +0x0F000000 /* TXP_REQ_CNTDOWN_TH[27..24] */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_TXP_REQ_CNTDOWN_TH_SHFT 24 +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_LATER_PKT_PRE_CUT_1US_ADDR \ +WF_PLE_TOP_PLE_FUNC_CTRL_0_ADDR +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_LATER_PKT_PRE_CUT_1US_MASK \ +0x00800000 /* LATER_PKT_PRE_CUT_1US[23] */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_LATER_PKT_PRE_CUT_1US_SHFT 23 +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_DIS_AUTORATE_TXP_REQ_ADDR \ +WF_PLE_TOP_PLE_FUNC_CTRL_0_ADDR +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_DIS_AUTORATE_TXP_REQ_MASK \ +0x00400000 /* DIS_AUTORATE_TXP_REQ[22] */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_DIS_AUTORATE_TXP_REQ_SHFT 22 +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MACTX_ABORT_ASSERT_ADDR \ +WF_PLE_TOP_PLE_FUNC_CTRL_0_ADDR +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MACTX_ABORT_ASSERT_MASK \ +0x00000200 /* MACTX_ABORT_ASSERT[9] */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MACTX_ABORT_ASSERT_SHFT 9 +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MACTX_REQ_ASSERT_ADDR \ +WF_PLE_TOP_PLE_FUNC_CTRL_0_ADDR +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MACTX_REQ_ASSERT_MASK \ +0x00000100 /* MACTX_REQ_ASSERT[8] */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MACTX_REQ_ASSERT_SHFT 8 +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_DIS_STA_RLS_TO_1F_ADDR \ +WF_PLE_TOP_PLE_FUNC_CTRL_0_ADDR +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_DIS_STA_RLS_TO_1F_MASK \ +0x00000040 /* DIS_STA_RLS_TO_1F[6] */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_DIS_STA_RLS_TO_1F_SHFT 6 +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_ACK_LMAC_NO_FID_ADD_ADDR \ +WF_PLE_TOP_PLE_FUNC_CTRL_0_ADDR +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_ACK_LMAC_NO_FID_ADD_MASK \ +0x00000010 /* ACK_LMAC_NO_FID_ADD[4] */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_ACK_LMAC_NO_FID_ADD_SHFT 4 +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MPDU_DONE_CNT_IN_NO_ADD_ADDR \ +WF_PLE_TOP_PLE_FUNC_CTRL_0_ADDR +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MPDU_DONE_CNT_IN_NO_ADD_MASK \ +0x00000008 /* MPDU_DONE_CNT_IN_NO_ADD[3] */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MPDU_DONE_CNT_IN_NO_ADD_SHFT 3 +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MPDU_DONE_CNT_IN_NO_TX_REQ_ADDR \ +WF_PLE_TOP_PLE_FUNC_CTRL_0_ADDR +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MPDU_DONE_CNT_IN_NO_TX_REQ_MASK \ +0x00000004 /* MPDU_DONE_CNT_IN_NO_TX_REQ[2] */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MPDU_DONE_CNT_IN_NO_TX_REQ_SHFT 2 +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MACTX_ABORT_DEASSERT_ADDR \ +WF_PLE_TOP_PLE_FUNC_CTRL_0_ADDR +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MACTX_ABORT_DEASSERT_MASK \ +0x00000002 /* MACTX_ABORT_DEASSERT[1] */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MACTX_ABORT_DEASSERT_SHFT 1 +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MACTX_REQ_DEASSERT_ADDR \ +WF_PLE_TOP_PLE_FUNC_CTRL_0_ADDR +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MACTX_REQ_DEASSERT_MASK \ +0x00000001 /* MACTX_REQ_DEASSERT[0] */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MACTX_REQ_DEASSERT_SHFT 0 + +/* +* ---PLE_FUNC_CTRL_1 (0x820C0000 + 0x144)--- +* RESERVED0[21..0] - (RO) Reserved bits +* PREDL_REQ_NORMAL_PRI[22] - (RW) Pre-download TXP request priority +control +* RESERVED23[31..23] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_PLE_FUNC_CTRL_1_PREDL_REQ_NORMAL_PRI_ADDR \ +WF_PLE_TOP_PLE_FUNC_CTRL_1_ADDR +#define WF_PLE_TOP_PLE_FUNC_CTRL_1_PREDL_REQ_NORMAL_PRI_MASK \ +0x00400000 /* PREDL_REQ_NORMAL_PRI[22] */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_1_PREDL_REQ_NORMAL_PRI_SHFT 22 + +/* +* ---PG_CPU_GROUP (0x820C0000 + 0x150)--- +* CPU_MIN_QUOTA[11..0] - (RW) Min. quota of CPU group +* Set up the quota before releasing PLE logic +* reset; it should not be changed after logic reset is released. +* RESERVED12[15..12] - (RO) Reserved bits +* CPU_MAX_QUOTA[27..16] - (RW) Max. quota of CPU group +* Set up the quota before releasing PLE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_PG_CPU_GROUP_CPU_MAX_QUOTA_ADDR WF_PLE_TOP_PG_CPU_GROUP_ADDR +#define WF_PLE_TOP_PG_CPU_GROUP_CPU_MAX_QUOTA_MASK \ +0x0FFF0000 /* CPU_MAX_QUOTA[27..16] */ +#define WF_PLE_TOP_PG_CPU_GROUP_CPU_MAX_QUOTA_SHFT 16 +#define WF_PLE_TOP_PG_CPU_GROUP_CPU_MIN_QUOTA_ADDR WF_PLE_TOP_PG_CPU_GROUP_ADDR +#define WF_PLE_TOP_PG_CPU_GROUP_CPU_MIN_QUOTA_MASK \ +0x00000FFF /* CPU_MIN_QUOTA[11..0] */ +#define WF_PLE_TOP_PG_CPU_GROUP_CPU_MIN_QUOTA_SHFT 0 + +/* +* ---CPU_PG_INFO (0x820C0000 + 0x154)--- +* CPU_RSV_CNT[11..0] - (RO) Reserved pages of CPU group +* RESERVED12[15..12] - (RO) Reserved bits +* CPU_SRC_CNT[27..16] - (RO) Used pages of CPU group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_CPU_PG_INFO_CPU_SRC_CNT_ADDR WF_PLE_TOP_CPU_PG_INFO_ADDR +#define WF_PLE_TOP_CPU_PG_INFO_CPU_SRC_CNT_MASK \ +0x0FFF0000 /* CPU_SRC_CNT[27..16] */ +#define WF_PLE_TOP_CPU_PG_INFO_CPU_SRC_CNT_SHFT 16 +#define WF_PLE_TOP_CPU_PG_INFO_CPU_RSV_CNT_ADDR WF_PLE_TOP_CPU_PG_INFO_ADDR +#define WF_PLE_TOP_CPU_PG_INFO_CPU_RSV_CNT_MASK \ +0x00000FFF /* CPU_RSV_CNT[11..0] */ +#define WF_PLE_TOP_CPU_PG_INFO_CPU_RSV_CNT_SHFT 0 + +/* +* ---PLE_LOG_0 (0x820C0000 + 0x170)--- +* PLE_LOG_0[31..0] - (RW) Log message for SW +*/ +#define WF_PLE_TOP_PLE_LOG_0_PLE_LOG_0_ADDR WF_PLE_TOP_PLE_LOG_0_ADDR +#define WF_PLE_TOP_PLE_LOG_0_PLE_LOG_0_MASK 0xFFFFFFFF /* PLE_LOG_0[31..0] */ +#define WF_PLE_TOP_PLE_LOG_0_PLE_LOG_0_SHFT 0 + +/* +* ---PLE_LOG_1 (0x820C0000 + 0x174)--- +* PLE_LOG_1[31..0] - (RW) Log message for SW +*/ +#define WF_PLE_TOP_PLE_LOG_1_PLE_LOG_1_ADDR WF_PLE_TOP_PLE_LOG_1_ADDR +#define WF_PLE_TOP_PLE_LOG_1_PLE_LOG_1_MASK 0xFFFFFFFF /* PLE_LOG_1[31..0] */ +#define WF_PLE_TOP_PLE_LOG_1_PLE_LOG_1_SHFT 0 + +/* +* ---PLE_LOG_2 (0x820C0000 + 0x178)--- +* PLE_LOG_2[31..0] - (RW) Log message for SW +*/ +#define WF_PLE_TOP_PLE_LOG_2_PLE_LOG_2_ADDR WF_PLE_TOP_PLE_LOG_2_ADDR +#define WF_PLE_TOP_PLE_LOG_2_PLE_LOG_2_MASK 0xFFFFFFFF /* PLE_LOG_2[31..0] */ +#define WF_PLE_TOP_PLE_LOG_2_PLE_LOG_2_SHFT 0 + +/* +* ---PLE_LOG_3 (0x820C0000 + 0x17c)--- +* PLE_LOG_3[31..0] - (RW) Log message for SW +*/ +#define WF_PLE_TOP_PLE_LOG_3_PLE_LOG_3_ADDR WF_PLE_TOP_PLE_LOG_3_ADDR +#define WF_PLE_TOP_PLE_LOG_3_PLE_LOG_3_MASK 0xFFFFFFFF /* PLE_LOG_3[31..0] */ +#define WF_PLE_TOP_PLE_LOG_3_PLE_LOG_3_SHFT 0 + +/* +* ---WMMAC_PGCNT_0 (0x820C0000 + 0x180)--- +* WMMAC_00_PGCNT[11..0] - (RO) WMMAC 00 used page count +* RESERVED12[15..12] - (RO) Reserved bits +* WMMAC_01_PGCNT[27..16] - (RO) WMMAC 01 used page count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_WMMAC_PGCNT_0_WMMAC_01_PGCNT_ADDR \ +WF_PLE_TOP_WMMAC_PGCNT_0_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_0_WMMAC_01_PGCNT_MASK \ +0x0FFF0000 /* WMMAC_01_PGCNT[27..16] */ +#define WF_PLE_TOP_WMMAC_PGCNT_0_WMMAC_01_PGCNT_SHFT 16 +#define WF_PLE_TOP_WMMAC_PGCNT_0_WMMAC_00_PGCNT_ADDR \ +WF_PLE_TOP_WMMAC_PGCNT_0_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_0_WMMAC_00_PGCNT_MASK \ +0x00000FFF /* WMMAC_00_PGCNT[11..0] */ +#define WF_PLE_TOP_WMMAC_PGCNT_0_WMMAC_00_PGCNT_SHFT 0 + +/* +* ---WMMAC_PGCNT_1 (0x820C0000 + 0x184)--- +* WMMAC_02_PGCNT[11..0] - (RO) WMMAC 02 used page count +* RESERVED12[15..12] - (RO) Reserved bits +* WMMAC_03_PGCNT[27..16] - (RO) WMMAC 03 used page count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_WMMAC_PGCNT_1_WMMAC_03_PGCNT_ADDR \ +WF_PLE_TOP_WMMAC_PGCNT_1_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_1_WMMAC_03_PGCNT_MASK \ +0x0FFF0000 /* WMMAC_03_PGCNT[27..16] */ +#define WF_PLE_TOP_WMMAC_PGCNT_1_WMMAC_03_PGCNT_SHFT 16 +#define WF_PLE_TOP_WMMAC_PGCNT_1_WMMAC_02_PGCNT_ADDR \ +WF_PLE_TOP_WMMAC_PGCNT_1_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_1_WMMAC_02_PGCNT_MASK \ +0x00000FFF /* WMMAC_02_PGCNT[11..0] */ +#define WF_PLE_TOP_WMMAC_PGCNT_1_WMMAC_02_PGCNT_SHFT 0 + +/* +* ---WMMAC_PGCNT_2 (0x820C0000 + 0x188)--- +* WMMAC_10_PGCNT[11..0] - (RO) WMMAC 10 used page count +* RESERVED12[15..12] - (RO) Reserved bits +* WMMAC_11_PGCNT[27..16] - (RO) WMMAC 11 used page count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_WMMAC_PGCNT_2_WMMAC_11_PGCNT_ADDR \ +WF_PLE_TOP_WMMAC_PGCNT_2_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_2_WMMAC_11_PGCNT_MASK \ +0x0FFF0000 /* WMMAC_11_PGCNT[27..16] */ +#define WF_PLE_TOP_WMMAC_PGCNT_2_WMMAC_11_PGCNT_SHFT 16 +#define WF_PLE_TOP_WMMAC_PGCNT_2_WMMAC_10_PGCNT_ADDR \ +WF_PLE_TOP_WMMAC_PGCNT_2_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_2_WMMAC_10_PGCNT_MASK \ +0x00000FFF /* WMMAC_10_PGCNT[11..0] */ +#define WF_PLE_TOP_WMMAC_PGCNT_2_WMMAC_10_PGCNT_SHFT 0 + +/* +* ---WMMAC_PGCNT_3 (0x820C0000 + 0x18c)--- +* WMMAC_12_PGCNT[11..0] - (RO) WMMAC 12 used page count +* RESERVED12[15..12] - (RO) Reserved bits +* WMMAC_13_PGCNT[27..16] - (RO) WMMAC 13 used page count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_WMMAC_PGCNT_3_WMMAC_13_PGCNT_ADDR \ +WF_PLE_TOP_WMMAC_PGCNT_3_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_3_WMMAC_13_PGCNT_MASK \ +0x0FFF0000 /* WMMAC_13_PGCNT[27..16] */ +#define WF_PLE_TOP_WMMAC_PGCNT_3_WMMAC_13_PGCNT_SHFT 16 +#define WF_PLE_TOP_WMMAC_PGCNT_3_WMMAC_12_PGCNT_ADDR \ +WF_PLE_TOP_WMMAC_PGCNT_3_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_3_WMMAC_12_PGCNT_MASK \ +0x00000FFF /* WMMAC_12_PGCNT[11..0] */ +#define WF_PLE_TOP_WMMAC_PGCNT_3_WMMAC_12_PGCNT_SHFT 0 + +/* +* ---WMMAC_PGCNT_4 (0x820C0000 + 0x190)--- +* WMMAC_20_PGCNT[11..0] - (RO) WMMAC 20 used page count +* RESERVED12[15..12] - (RO) Reserved bits +* WMMAC_21_PGCNT[27..16] - (RO) WMMAC 21 used page count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_WMMAC_PGCNT_4_WMMAC_21_PGCNT_ADDR \ +WF_PLE_TOP_WMMAC_PGCNT_4_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_4_WMMAC_21_PGCNT_MASK \ +0x0FFF0000 /* WMMAC_21_PGCNT[27..16] */ +#define WF_PLE_TOP_WMMAC_PGCNT_4_WMMAC_21_PGCNT_SHFT 16 +#define WF_PLE_TOP_WMMAC_PGCNT_4_WMMAC_20_PGCNT_ADDR \ +WF_PLE_TOP_WMMAC_PGCNT_4_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_4_WMMAC_20_PGCNT_MASK \ +0x00000FFF /* WMMAC_20_PGCNT[11..0] */ +#define WF_PLE_TOP_WMMAC_PGCNT_4_WMMAC_20_PGCNT_SHFT 0 + +/* +* ---WMMAC_PGCNT_5 (0x820C0000 + 0x194)--- +* WMMAC_22_PGCNT[11..0] - (RO) WMMAC 22 used page count +* RESERVED12[15..12] - (RO) Reserved bits +* WMMAC_23_PGCNT[27..16] - (RO) WMMAC 23 used page count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_WMMAC_PGCNT_5_WMMAC_23_PGCNT_ADDR \ +WF_PLE_TOP_WMMAC_PGCNT_5_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_5_WMMAC_23_PGCNT_MASK \ +0x0FFF0000 /* WMMAC_23_PGCNT[27..16] */ +#define WF_PLE_TOP_WMMAC_PGCNT_5_WMMAC_23_PGCNT_SHFT 16 +#define WF_PLE_TOP_WMMAC_PGCNT_5_WMMAC_22_PGCNT_ADDR \ +WF_PLE_TOP_WMMAC_PGCNT_5_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_5_WMMAC_22_PGCNT_MASK \ +0x00000FFF /* WMMAC_22_PGCNT[11..0] */ +#define WF_PLE_TOP_WMMAC_PGCNT_5_WMMAC_22_PGCNT_SHFT 0 + +/* +* ---WMMAC_PGCNT_6 (0x820C0000 + 0x198)--- +* WMMAC_30_PGCNT[11..0] - (RO) WMMAC 30 used page count +* RESERVED12[15..12] - (RO) Reserved bits +* WMMAC_31_PGCNT[27..16] - (RO) WMMAC 31 used page count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_WMMAC_PGCNT_6_WMMAC_31_PGCNT_ADDR \ +WF_PLE_TOP_WMMAC_PGCNT_6_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_6_WMMAC_31_PGCNT_MASK \ +0x0FFF0000 /* WMMAC_31_PGCNT[27..16] */ +#define WF_PLE_TOP_WMMAC_PGCNT_6_WMMAC_31_PGCNT_SHFT 16 +#define WF_PLE_TOP_WMMAC_PGCNT_6_WMMAC_30_PGCNT_ADDR \ +WF_PLE_TOP_WMMAC_PGCNT_6_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_6_WMMAC_30_PGCNT_MASK \ +0x00000FFF /* WMMAC_30_PGCNT[11..0] */ +#define WF_PLE_TOP_WMMAC_PGCNT_6_WMMAC_30_PGCNT_SHFT 0 + +/* +* ---WMMAC_PGCNT_7 (0x820C0000 + 0x19c)--- +* WMMAC_32_PGCNT[11..0] - (RO) WMMAC 32 used page count +* RESERVED12[15..12] - (RO) Reserved bits +* WMMAC_33_PGCNT[27..16] - (RO) WMMAC 33 used page count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_WMMAC_PGCNT_7_WMMAC_33_PGCNT_ADDR \ +WF_PLE_TOP_WMMAC_PGCNT_7_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_7_WMMAC_33_PGCNT_MASK \ +0x0FFF0000 /* WMMAC_33_PGCNT[27..16] */ +#define WF_PLE_TOP_WMMAC_PGCNT_7_WMMAC_33_PGCNT_SHFT 16 +#define WF_PLE_TOP_WMMAC_PGCNT_7_WMMAC_32_PGCNT_ADDR \ +WF_PLE_TOP_WMMAC_PGCNT_7_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_7_WMMAC_32_PGCNT_MASK \ +0x00000FFF /* WMMAC_32_PGCNT[11..0] */ +#define WF_PLE_TOP_WMMAC_PGCNT_7_WMMAC_32_PGCNT_SHFT 0 + +/* +* ---RL_BUF_CTRL_0 (0x820C0000 + 0x1A0)--- +* RELAY_BUF_ADDR[11..0] - (RW) Read address of relay buffer +* RESERVED12[30..12] - (RO) Reserved bits +* EXECUTE[31] - (A0) Executes relay buffer read command +*/ +#define WF_PLE_TOP_RL_BUF_CTRL_0_EXECUTE_ADDR WF_PLE_TOP_RL_BUF_CTRL_0_ADDR +#define WF_PLE_TOP_RL_BUF_CTRL_0_EXECUTE_MASK 0x80000000 /* EXECUTE[31] */ +#define WF_PLE_TOP_RL_BUF_CTRL_0_EXECUTE_SHFT 31 +#define WF_PLE_TOP_RL_BUF_CTRL_0_RELAY_BUF_ADDR_ADDR \ +WF_PLE_TOP_RL_BUF_CTRL_0_ADDR +#define WF_PLE_TOP_RL_BUF_CTRL_0_RELAY_BUF_ADDR_MASK \ +0x00000FFF /* RELAY_BUF_ADDR[11..0] */ +#define WF_PLE_TOP_RL_BUF_CTRL_0_RELAY_BUF_ADDR_SHFT 0 + +/* +* ---RL_BUF_CTRL_1 (0x820C0000 + 0x1A4)--- +* PAGE_NUM_0[0] - (RO) Page number[0] of packet +* PKT_LEN[11..1] - (RO) Length of the packet with head page +* being the relay buffer address +* Unit: 32 bytes +* PKT_TAIL_PAGE[23..12] - (RO) Tail page of the packet with head page +* being the relay buffer address +* RESV_GRP_ID[24] - (RO) Group ID of reserved page used by FID +* RESERVED25[25] - (RO) Reserved bits +* PAGE_NUM_1[27..26] - (RO) Page number[2:1] of packet +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_RL_BUF_CTRL_1_PAGE_NUM_1_ADDR WF_PLE_TOP_RL_BUF_CTRL_1_ADDR +#define WF_PLE_TOP_RL_BUF_CTRL_1_PAGE_NUM_1_MASK \ +0x0C000000 /* PAGE_NUM_1[27..26] */ +#define WF_PLE_TOP_RL_BUF_CTRL_1_PAGE_NUM_1_SHFT 26 +#define WF_PLE_TOP_RL_BUF_CTRL_1_RESV_GRP_ID_ADDR WF_PLE_TOP_RL_BUF_CTRL_1_ADDR +#define WF_PLE_TOP_RL_BUF_CTRL_1_RESV_GRP_ID_MASK \ +0x01000000 /* RESV_GRP_ID[24] */ +#define WF_PLE_TOP_RL_BUF_CTRL_1_RESV_GRP_ID_SHFT 24 +#define WF_PLE_TOP_RL_BUF_CTRL_1_PKT_TAIL_PAGE_ADDR \ +WF_PLE_TOP_RL_BUF_CTRL_1_ADDR +#define WF_PLE_TOP_RL_BUF_CTRL_1_PKT_TAIL_PAGE_MASK \ +0x00FFF000 /* PKT_TAIL_PAGE[23..12] */ +#define WF_PLE_TOP_RL_BUF_CTRL_1_PKT_TAIL_PAGE_SHFT 12 +#define WF_PLE_TOP_RL_BUF_CTRL_1_PKT_LEN_ADDR WF_PLE_TOP_RL_BUF_CTRL_1_ADDR +#define WF_PLE_TOP_RL_BUF_CTRL_1_PKT_LEN_MASK 0x00000FFE /* PKT_LEN[11..1] */ +#define WF_PLE_TOP_RL_BUF_CTRL_1_PKT_LEN_SHFT 1 +#define WF_PLE_TOP_RL_BUF_CTRL_1_PAGE_NUM_0_ADDR WF_PLE_TOP_RL_BUF_CTRL_1_ADDR +#define WF_PLE_TOP_RL_BUF_CTRL_1_PAGE_NUM_0_MASK 0x00000001 /* PAGE_NUM_0[0] \ + */ +#define WF_PLE_TOP_RL_BUF_CTRL_1_PAGE_NUM_0_SHFT 0 + +/* +* ---FL_QUE_CTRL_0 (0x820C0000 + 0x1B0)--- +* Q_BUF_WLANID[9..0] - (RW) Address of queue structure buffer +WLANID. +* Q_BUF_PID[11..10] - (RW) Address of queue structure buffer PID +* FL_BUFFER_ADDR[23..12] - (RW) Frame address of read previous +* frame/next frame +* Q_BUF_QID[30..24] - (RW) Address of queue structure buffer QID +* EXECUTE[31] - (A0) Executes frame link and queue structure +* buffer read command +*/ +#define WF_PLE_TOP_FL_QUE_CTRL_0_EXECUTE_ADDR WF_PLE_TOP_FL_QUE_CTRL_0_ADDR +#define WF_PLE_TOP_FL_QUE_CTRL_0_EXECUTE_MASK 0x80000000 /* EXECUTE[31] */ +#define WF_PLE_TOP_FL_QUE_CTRL_0_EXECUTE_SHFT 31 +#define WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_QID_ADDR WF_PLE_TOP_FL_QUE_CTRL_0_ADDR +#define WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_QID_MASK \ +0x7F000000 /* Q_BUF_QID[30..24] */ +#define WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_QID_SHFT 24 +#define WF_PLE_TOP_FL_QUE_CTRL_0_FL_BUFFER_ADDR_ADDR \ +WF_PLE_TOP_FL_QUE_CTRL_0_ADDR +#define WF_PLE_TOP_FL_QUE_CTRL_0_FL_BUFFER_ADDR_MASK \ +0x00FFF000 /* FL_BUFFER_ADDR[23..12] */ +#define WF_PLE_TOP_FL_QUE_CTRL_0_FL_BUFFER_ADDR_SHFT 12 +#define WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_PID_ADDR WF_PLE_TOP_FL_QUE_CTRL_0_ADDR +#define WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_PID_MASK \ +0x00000C00 /* Q_BUF_PID[11..10] */ +#define WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_PID_SHFT 10 +#define WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_WLANID_ADDR WF_PLE_TOP_FL_QUE_CTRL_0_ADDR +#define WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_WLANID_MASK \ +0x000003FF /* Q_BUF_WLANID[9..0] */ +#define WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_WLANID_SHFT 0 + +/* +* ---FL_QUE_CTRL_1 (0x820C0000 + 0x1B4)--- +* NEXT_FID[11..0] - (RO) Next frame ID of FL_BUFFER_ADDR +* RESERVED12[15..12] - (RO) Reserved bits +* PREV_FID[27..16] - (RO) Previous frame ID of FL_BUFFER_ADDR +* RESERVED28[30..28] - (RO) Reserved bits +* Q_BUF_TGID[31] - (RW) Address of queue structure buffer TGID +*/ +#define WF_PLE_TOP_FL_QUE_CTRL_1_Q_BUF_TGID_ADDR WF_PLE_TOP_FL_QUE_CTRL_1_ADDR +#define WF_PLE_TOP_FL_QUE_CTRL_1_Q_BUF_TGID_MASK 0x80000000 /* Q_BUF_TGID[31]\ + */ +#define WF_PLE_TOP_FL_QUE_CTRL_1_Q_BUF_TGID_SHFT 31 +#define WF_PLE_TOP_FL_QUE_CTRL_1_PREV_FID_ADDR WF_PLE_TOP_FL_QUE_CTRL_1_ADDR +#define WF_PLE_TOP_FL_QUE_CTRL_1_PREV_FID_MASK 0x0FFF0000 /* PREV_FID[27..16]\ + */ +#define WF_PLE_TOP_FL_QUE_CTRL_1_PREV_FID_SHFT 16 +#define WF_PLE_TOP_FL_QUE_CTRL_1_NEXT_FID_ADDR WF_PLE_TOP_FL_QUE_CTRL_1_ADDR +#define WF_PLE_TOP_FL_QUE_CTRL_1_NEXT_FID_MASK 0x00000FFF /* NEXT_FID[11..0] \ + */ +#define WF_PLE_TOP_FL_QUE_CTRL_1_NEXT_FID_SHFT 0 + +/* +* ---FL_QUE_CTRL_2 (0x820C0000 + 0x1B8)--- +* QUEUE_HEAD_FID[11..0] - (RO) Head frame ID of the quest queue setting +* in 0x01b0[15:0] +* RESERVED12[15..12] - (RO) Reserved bits +* QUEUE_TAIL_FID[27..16] - (RO) Tail frame ID of the quest queue setting +* in 0x01b0[15:0] +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_TAIL_FID_ADDR \ +WF_PLE_TOP_FL_QUE_CTRL_2_ADDR +#define WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_TAIL_FID_MASK \ +0x0FFF0000 /* QUEUE_TAIL_FID[27..16] */ +#define WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_TAIL_FID_SHFT 16 +#define WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_HEAD_FID_ADDR \ +WF_PLE_TOP_FL_QUE_CTRL_2_ADDR +#define WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_HEAD_FID_MASK \ +0x00000FFF /* QUEUE_HEAD_FID[11..0] */ +#define WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_HEAD_FID_SHFT 0 + +/* +* ---FL_QUE_CTRL_3 (0x820C0000 + 0x1BC)--- +* QUEUE_PKT_NUM[11..0] - (RO) Total packet number of the queue +* setting in 0x1b0[15:0] +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_FL_QUE_CTRL_3_QUEUE_PKT_NUM_ADDR \ +WF_PLE_TOP_FL_QUE_CTRL_3_ADDR +#define WF_PLE_TOP_FL_QUE_CTRL_3_QUEUE_PKT_NUM_MASK \ +0x00000FFF /* QUEUE_PKT_NUM[11..0] */ +#define WF_PLE_TOP_FL_QUE_CTRL_3_QUEUE_PKT_NUM_SHFT 0 + +/* +* ---PL_QUE_CTRL_0 (0x820C0000 + 0x1C0)--- +* NEXT_PAGE[11..0] - (RO) Next page of PL_BUFFER_ADDR +* RESERVED12[15..12] - (RO) Reserved bits +* PL_BUFFER_ADDR[27..16] - (RW) Page address of read next page +* RESERVED28[30..28] - (RO) Reserved bits +* EXECUTE[31] - (A0) Executes page link buffer read command +*/ +#define WF_PLE_TOP_PL_QUE_CTRL_0_EXECUTE_ADDR WF_PLE_TOP_PL_QUE_CTRL_0_ADDR +#define WF_PLE_TOP_PL_QUE_CTRL_0_EXECUTE_MASK 0x80000000 /* EXECUTE[31] */ +#define WF_PLE_TOP_PL_QUE_CTRL_0_EXECUTE_SHFT 31 +#define WF_PLE_TOP_PL_QUE_CTRL_0_PL_BUFFER_ADDR_ADDR \ +WF_PLE_TOP_PL_QUE_CTRL_0_ADDR +#define WF_PLE_TOP_PL_QUE_CTRL_0_PL_BUFFER_ADDR_MASK \ +0x0FFF0000 /* PL_BUFFER_ADDR[27..16] */ +#define WF_PLE_TOP_PL_QUE_CTRL_0_PL_BUFFER_ADDR_SHFT 16 +#define WF_PLE_TOP_PL_QUE_CTRL_0_NEXT_PAGE_ADDR WF_PLE_TOP_PL_QUE_CTRL_0_ADDR +#define WF_PLE_TOP_PL_QUE_CTRL_0_NEXT_PAGE_MASK \ +0x00000FFF /* NEXT_PAGE[11..0] */ +#define WF_PLE_TOP_PL_QUE_CTRL_0_NEXT_PAGE_SHFT 0 + +/* +* ---PLE_DELAY_TX_CTRL (0x820C0000 + 0x1d0)--- +* DELAY_TX_PAGE_TH[11..0] - (RW) Delay TX function is used to delay TXD +* be LMAC used. If the total pages of TXD large than page threshold, the delay +TX +* would be released. LMAC would use TXD to TX. +* RESERVED12[15..12] - (RO) Reserved bits +* DELAY_TX_TIMEOUT_TH[23..16] - (RW) Delay TX function is used to delay TXD +* be LMAC used. IF no more enqueue event in the time out threshold, the delay TX +* would be released. LMAC can use TXD to TX. (unit is 32us). +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_PLE_DELAY_TX_CTRL_DELAY_TX_TIMEOUT_TH_ADDR \ +WF_PLE_TOP_PLE_DELAY_TX_CTRL_ADDR +#define WF_PLE_TOP_PLE_DELAY_TX_CTRL_DELAY_TX_TIMEOUT_TH_MASK \ +0x00FF0000 /* DELAY_TX_TIMEOUT_TH[23..16] */ +#define WF_PLE_TOP_PLE_DELAY_TX_CTRL_DELAY_TX_TIMEOUT_TH_SHFT 16 +#define WF_PLE_TOP_PLE_DELAY_TX_CTRL_DELAY_TX_PAGE_TH_ADDR \ +WF_PLE_TOP_PLE_DELAY_TX_CTRL_ADDR +#define WF_PLE_TOP_PLE_DELAY_TX_CTRL_DELAY_TX_PAGE_TH_MASK \ +0x00000FFF /* DELAY_TX_PAGE_TH[11..0] */ +#define WF_PLE_TOP_PLE_DELAY_TX_CTRL_DELAY_TX_PAGE_TH_SHFT 0 + +/* +* ---PLE_STATION_REDIR_CTRL (0x820C0000 + 0x1d4)--- +* STA_REDIR_QID[4..0] - (RW) Destitaion queue for Redirection +function. +* RESERVED5[5] - (RO) Reserved bits +* STA_REDIR_PID[7..6] - (RW) Destitaion port for Redirection +function. +* STA_REDIR_PASUE_TXD[8] - (RW) Pause TXD download for avoid race +* condition, when station redirection function turn off. +* RESERVED9[31..9] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_PLE_STATION_REDIR_CTRL_STA_REDIR_PASUE_TXD_ADDR \ +WF_PLE_TOP_PLE_STATION_REDIR_CTRL_ADDR +#define WF_PLE_TOP_PLE_STATION_REDIR_CTRL_STA_REDIR_PASUE_TXD_MASK \ +0x00000100 /* STA_REDIR_PASUE_TXD[8] */ +#define WF_PLE_TOP_PLE_STATION_REDIR_CTRL_STA_REDIR_PASUE_TXD_SHFT 8 +#define WF_PLE_TOP_PLE_STATION_REDIR_CTRL_STA_REDIR_PID_ADDR \ +WF_PLE_TOP_PLE_STATION_REDIR_CTRL_ADDR +#define WF_PLE_TOP_PLE_STATION_REDIR_CTRL_STA_REDIR_PID_MASK \ +0x000000C0 /* STA_REDIR_PID[7..6] */ +#define WF_PLE_TOP_PLE_STATION_REDIR_CTRL_STA_REDIR_PID_SHFT 6 +#define WF_PLE_TOP_PLE_STATION_REDIR_CTRL_STA_REDIR_QID_ADDR \ +WF_PLE_TOP_PLE_STATION_REDIR_CTRL_ADDR +#define WF_PLE_TOP_PLE_STATION_REDIR_CTRL_STA_REDIR_QID_MASK \ +0x0000001F /* STA_REDIR_QID[4..0] */ +#define WF_PLE_TOP_PLE_STATION_REDIR_CTRL_STA_REDIR_QID_SHFT 0 + +/* +* ---MACTX_LENGTH_LIMIT (0x820C0000 + 0x1ec)--- +* MACTX_LENGTH_LIMIT_BAND0[15..0] - (RW) MACTX download length limit of band0 +* MACTX_LENGTH_LIMIT_BAND1[31..16] - (RW) MACTX download length limit of band1 +*/ +#define WF_PLE_TOP_MACTX_LENGTH_LIMIT_MACTX_LENGTH_LIMIT_BAND1_ADDR \ +WF_PLE_TOP_MACTX_LENGTH_LIMIT_ADDR +#define WF_PLE_TOP_MACTX_LENGTH_LIMIT_MACTX_LENGTH_LIMIT_BAND1_MASK \ +0xFFFF0000 /* MACTX_LENGTH_LIMIT_BAND1[31..16] */ +#define WF_PLE_TOP_MACTX_LENGTH_LIMIT_MACTX_LENGTH_LIMIT_BAND1_SHFT 16 +#define WF_PLE_TOP_MACTX_LENGTH_LIMIT_MACTX_LENGTH_LIMIT_BAND0_ADDR \ +WF_PLE_TOP_MACTX_LENGTH_LIMIT_ADDR +#define WF_PLE_TOP_MACTX_LENGTH_LIMIT_MACTX_LENGTH_LIMIT_BAND0_MASK \ +0x0000FFFF /* MACTX_LENGTH_LIMIT_BAND0[15..0] */ +#define WF_PLE_TOP_MACTX_LENGTH_LIMIT_MACTX_LENGTH_LIMIT_BAND0_SHFT 0 + +/* +* ---HIF_ENQ_PKT_NUM (0x820C0000 + 0x1f0)--- +* HIF_ENQ_CPU_PKT_NUM[15..0] - (RO) Packet number of HIF enqueue to CPU, +* just keep in 16bits. +* HIF_ENQ_LMAC_PKT_NUM[31..16] - (RO) Packet number of HIF enqueue to LMAC, +* just keep in 16 bits +*/ +#define WF_PLE_TOP_HIF_ENQ_PKT_NUM_HIF_ENQ_LMAC_PKT_NUM_ADDR \ +WF_PLE_TOP_HIF_ENQ_PKT_NUM_ADDR +#define WF_PLE_TOP_HIF_ENQ_PKT_NUM_HIF_ENQ_LMAC_PKT_NUM_MASK \ +0xFFFF0000 /* HIF_ENQ_LMAC_PKT_NUM[31..16] */ +#define WF_PLE_TOP_HIF_ENQ_PKT_NUM_HIF_ENQ_LMAC_PKT_NUM_SHFT 16 +#define WF_PLE_TOP_HIF_ENQ_PKT_NUM_HIF_ENQ_CPU_PKT_NUM_ADDR \ +WF_PLE_TOP_HIF_ENQ_PKT_NUM_ADDR +#define WF_PLE_TOP_HIF_ENQ_PKT_NUM_HIF_ENQ_CPU_PKT_NUM_MASK \ +0x0000FFFF /* HIF_ENQ_CPU_PKT_NUM[15..0] */ +#define WF_PLE_TOP_HIF_ENQ_PKT_NUM_HIF_ENQ_CPU_PKT_NUM_SHFT 0 + +/* +* ---CPU_ENQ_PKT_NUM (0x820C0000 + 0x1f4)--- +* CPU_ENQ_LMAC_PKT_NUM[15..0] - (RO) Packet number of CPU enqueue to LMAC, +* just keep in 16 bits. +* RESV[31..16] - (RO) Reserved +*/ +#define WF_PLE_TOP_CPU_ENQ_PKT_NUM_RESV_ADDR WF_PLE_TOP_CPU_ENQ_PKT_NUM_ADDR +#define WF_PLE_TOP_CPU_ENQ_PKT_NUM_RESV_MASK 0xFFFF0000 /* RESV[31..16] */ +#define WF_PLE_TOP_CPU_ENQ_PKT_NUM_RESV_SHFT 16 +#define WF_PLE_TOP_CPU_ENQ_PKT_NUM_CPU_ENQ_LMAC_PKT_NUM_ADDR \ +WF_PLE_TOP_CPU_ENQ_PKT_NUM_ADDR +#define WF_PLE_TOP_CPU_ENQ_PKT_NUM_CPU_ENQ_LMAC_PKT_NUM_MASK \ +0x0000FFFF /* CPU_ENQ_LMAC_PKT_NUM[15..0] */ +#define WF_PLE_TOP_CPU_ENQ_PKT_NUM_CPU_ENQ_LMAC_PKT_NUM_SHFT 0 + +/* +* ---RLS_MSDU_PKT_NUM (0x820C0000 + 0x1f8)--- +* RSL_RPT_TXD_NUM[15..0] - (RO) TXD number of host report function +* RSL_MSDUID_NUM[31..16] - (RO) Release MSDU_ID number of host report +function +*/ +#define WF_PLE_TOP_RLS_MSDU_PKT_NUM_RSL_MSDUID_NUM_ADDR \ +WF_PLE_TOP_RLS_MSDU_PKT_NUM_ADDR +#define WF_PLE_TOP_RLS_MSDU_PKT_NUM_RSL_MSDUID_NUM_MASK \ +0xFFFF0000 /* RSL_MSDUID_NUM[31..16] */ +#define WF_PLE_TOP_RLS_MSDU_PKT_NUM_RSL_MSDUID_NUM_SHFT 16 +#define WF_PLE_TOP_RLS_MSDU_PKT_NUM_RSL_RPT_TXD_NUM_ADDR \ +WF_PLE_TOP_RLS_MSDU_PKT_NUM_ADDR +#define WF_PLE_TOP_RLS_MSDU_PKT_NUM_RSL_RPT_TXD_NUM_MASK \ +0x0000FFFF /* RSL_RPT_TXD_NUM[15..0] */ +#define WF_PLE_TOP_RLS_MSDU_PKT_NUM_RSL_RPT_TXD_NUM_SHFT 0 + +/* +* ---HOST_REPORT_NUM (0x820C0000 + 0x1fc)--- +* RSL_TXD_NUM[15..0] - (RO) All TXD number of release function, +* include the no host report(not CT) TXD packets. +* HOST_REPORT_NUM[31..16] - (RO) Host report number that be the PSE +* packets carry release MSDU_ID information +*/ +#define WF_PLE_TOP_HOST_REPORT_NUM_HOST_REPORT_NUM_ADDR \ +WF_PLE_TOP_HOST_REPORT_NUM_ADDR +#define WF_PLE_TOP_HOST_REPORT_NUM_HOST_REPORT_NUM_MASK \ +0xFFFF0000 /* HOST_REPORT_NUM[31..16] */ +#define WF_PLE_TOP_HOST_REPORT_NUM_HOST_REPORT_NUM_SHFT 16 +#define WF_PLE_TOP_HOST_REPORT_NUM_RSL_TXD_NUM_ADDR \ +WF_PLE_TOP_HOST_REPORT_NUM_ADDR +#define WF_PLE_TOP_HOST_REPORT_NUM_RSL_TXD_NUM_MASK \ +0x0000FFFF /* RSL_TXD_NUM[15..0] */ +#define WF_PLE_TOP_HOST_REPORT_NUM_RSL_TXD_NUM_SHFT 0 + +/* +* ---TXD_QUEUE_EMPTY (0x820C0000 + 0x220)--- +* AC00_EMPTY[0] - (RO) WMM0 AC0 queue empty status +* AC01_EMPTY[1] - (RO) WMM0 AC1 queue empty status +* AC02_EMPTY[2] - (RO) WMM0 AC2 queue empty status +* AC03_EMPTY[3] - (RO) WMM0 AC3 queue empty status +* AC10_EMPTY[4] - (RO) WMM1 AC0 queue empty status +* AC11_EMPTY[5] - (RO) WMM1 AC1 queue empty status +* AC12_EMPTY[6] - (RO) WMM1 AC2 queue empty status +* AC13_EMPTY[7] - (RO) WMM1 AC3 queue empty status +* AC20_EMPTY[8] - (RO) WMM2 AC0 queue empty status +* AC21_EMPTY[9] - (RO) WMM2 AC1 queue empty status +* AC22_EMPTY[10] - (RO) WMM2 AC2 queue empty status +* AC23_EMPTY[11] - (RO) WMM2 AC3 queue empty status +* AC30_EMPTY[12] - (RO) WMM3 AC0 queue empty status +* AC31_EMPTY[13] - (RO) WMM3 AC1 queue empty status +* AC32_EMPTY[14] - (RO) WMM3 AC2 queue empty status +* AC33_EMPTY[15] - (RO) WMM3 AC3 queue empty status +* ALTX_0_EMPTY[16] - (RO) ALTX queue 0 empty status +* BMC_0_EMPTY[17] - (RO) BMC queue 0 empty status +* BCN_0_EMPTY[18] - (RO) BCN queue 0 empty status +* PSMP_0_EMPTY[19] - (RO) PSMP queue 0 empty status +* ALTX_1_EMPTY[20] - (RO) ALTX queue 1 empty status +* BMC_1_EMPTY[21] - (RO) BMC queue 1 empty status +* BCN_1_EMPTY[22] - (RO) BCN queue 1 empty status +* PSMP_1_EMPTY[23] - (RO) PSMP queue 1 empty status +* NAF_EMPTY[24] - (RO) NAF queue empty status +* NBCN_EMPTY[25] - (RO) NBCN queue empty status +* RESERVED26[31..26] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_NBCN_EMPTY_ADDR \ +WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_NBCN_EMPTY_MASK \ +0x02000000 /* NBCN_EMPTY[25] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_NBCN_EMPTY_SHFT 25 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_NAF_EMPTY_ADDR \ +WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_NAF_EMPTY_MASK 0x01000000 /* NAF_EMPTY[24]\ + */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_NAF_EMPTY_SHFT 24 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_PSMP_1_EMPTY_ADDR \ +WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_PSMP_1_EMPTY_MASK \ +0x00800000 /* PSMP_1_EMPTY[23] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_PSMP_1_EMPTY_SHFT 23 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_BCN_1_EMPTY_ADDR \ +WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_BCN_1_EMPTY_MASK \ +0x00400000 /* BCN_1_EMPTY[22] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_BCN_1_EMPTY_SHFT 22 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_BMC_1_EMPTY_ADDR \ +WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_BMC_1_EMPTY_MASK \ +0x00200000 /* BMC_1_EMPTY[21] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_BMC_1_EMPTY_SHFT 21 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_ALTX_1_EMPTY_ADDR \ +WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_ALTX_1_EMPTY_MASK \ +0x00100000 /* ALTX_1_EMPTY[20] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_ALTX_1_EMPTY_SHFT 20 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_PSMP_0_EMPTY_ADDR \ +WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_PSMP_0_EMPTY_MASK \ +0x00080000 /* PSMP_0_EMPTY[19] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_PSMP_0_EMPTY_SHFT 19 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_BCN_0_EMPTY_ADDR \ +WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_BCN_0_EMPTY_MASK \ +0x00040000 /* BCN_0_EMPTY[18] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_BCN_0_EMPTY_SHFT 18 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_BMC_0_EMPTY_ADDR \ +WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_BMC_0_EMPTY_MASK \ +0x00020000 /* BMC_0_EMPTY[17] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_BMC_0_EMPTY_SHFT 17 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_ALTX_0_EMPTY_ADDR \ +WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_ALTX_0_EMPTY_MASK \ +0x00010000 /* ALTX_0_EMPTY[16] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_ALTX_0_EMPTY_SHFT 16 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC33_EMPTY_ADDR \ +WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC33_EMPTY_MASK \ +0x00008000 /* AC33_EMPTY[15] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC33_EMPTY_SHFT 15 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC32_EMPTY_ADDR \ +WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC32_EMPTY_MASK \ +0x00004000 /* AC32_EMPTY[14] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC32_EMPTY_SHFT 14 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC31_EMPTY_ADDR \ +WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC31_EMPTY_MASK \ +0x00002000 /* AC31_EMPTY[13] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC31_EMPTY_SHFT 13 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC30_EMPTY_ADDR \ +WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC30_EMPTY_MASK \ +0x00001000 /* AC30_EMPTY[12] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC30_EMPTY_SHFT 12 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC23_EMPTY_ADDR \ +WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC23_EMPTY_MASK \ +0x00000800 /* AC23_EMPTY[11] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC23_EMPTY_SHFT 11 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC22_EMPTY_ADDR \ +WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC22_EMPTY_MASK \ +0x00000400 /* AC22_EMPTY[10] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC22_EMPTY_SHFT 10 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC21_EMPTY_ADDR \ +WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC21_EMPTY_MASK \ +0x00000200 /* AC21_EMPTY[9] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC21_EMPTY_SHFT 9 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC20_EMPTY_ADDR \ +WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC20_EMPTY_MASK \ +0x00000100 /* AC20_EMPTY[8] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC20_EMPTY_SHFT 8 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC13_EMPTY_ADDR \ +WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC13_EMPTY_MASK \ +0x00000080 /* AC13_EMPTY[7] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC13_EMPTY_SHFT 7 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC12_EMPTY_ADDR \ +WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC12_EMPTY_MASK \ +0x00000040 /* AC12_EMPTY[6] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC12_EMPTY_SHFT 6 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC11_EMPTY_ADDR \ +WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC11_EMPTY_MASK \ +0x00000020 /* AC11_EMPTY[5] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC11_EMPTY_SHFT 5 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC10_EMPTY_ADDR \ +WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC10_EMPTY_MASK \ +0x00000010 /* AC10_EMPTY[4] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC10_EMPTY_SHFT 4 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC03_EMPTY_ADDR \ +WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC03_EMPTY_MASK \ +0x00000008 /* AC03_EMPTY[3] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC03_EMPTY_SHFT 3 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC02_EMPTY_ADDR \ +WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC02_EMPTY_MASK \ +0x00000004 /* AC02_EMPTY[2] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC02_EMPTY_SHFT 2 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC01_EMPTY_ADDR \ +WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC01_EMPTY_MASK \ +0x00000002 /* AC01_EMPTY[1] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC01_EMPTY_SHFT 1 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC00_EMPTY_ADDR \ +WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC00_EMPTY_MASK \ +0x00000001 /* AC00_EMPTY[0] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC00_EMPTY_SHFT 0 + +/* +* ---TXS_BUF_PAUSE (0x820C0000 + 0x224)--- +* EN_PAUSE_AC00_QUEUE[0] - (RW) Pause control of WMM0 AC0 queue. +* EN_PAUSE_AC01_QUEUE[1] - (RW) Pause control of WMM0 AC1 queue. +* EN_PAUSE_AC02_QUEUE[2] - (RW) Pause control of WMM0 AC2 queue. +* EN_PAUSE_AC03_QUEUE[3] - (RW) Pause control of WMM0 AC3 queue. +* EN_PAUSE_AC10_QUEUE[4] - (RW) Pause control of WMM1 AC0 queue. +* EN_PAUSE_AC11_QUEUE[5] - (RW) Pause control of WMM1 AC1 queue. +* EN_PAUSE_AC12_QUEUE[6] - (RW) Pause control of WMM1 AC2 queue. +* EN_PAUSE_AC13_QUEUE[7] - (RW) Pause control of WMM1 AC3 queue. +* EN_PAUSE_AC20_QUEUE[8] - (RW) Pause control of WMM2 AC0 queue. +* EN_PAUSE_AC21_QUEUE[9] - (RW) Pause control of WMM2 AC1 queue. +* EN_PAUSE_AC22_QUEUE[10] - (RW) Pause control of WMM2 AC2 queue. +* EN_PAUSE_AC23_QUEUE[11] - (RW) Pause control of WMM2 AC3 queue. +* EN_PAUSE_AC30_QUEUE[12] - (RW) Pause control of WMM3 AC0 queue. +* EN_PAUSE_AC31_QUEUE[13] - (RW) Pause control of WMM3 AC1 queue. +* EN_PAUSE_AC32_QUEUE[14] - (RW) Pause control of WMM3 AC2 queue. +* EN_PAUSE_AC33_QUEUE[15] - (RW) Pause control of WMM3 AC3 queue. +* EN_PAUSE_ALTX_0_QUEUE[16] - (RW) Pause control of ALTX queue 0. +* EN_PAUSE_BMC_0_QUEUE[17] - (RW) Pause control of BMC queue 0. +* EN_PAUSE_BCN_0_QUEUE[18] - (RW) Pause control of BCN queue 0. +* EN_PAUSE_PSMP_0_QUEUE[19] - (RW) Pause control of PSMP queue 0. +* EN_PAUSE_ALTX_1_QUEUE[20] - (RW) Pause control of ALTX queue 1. +* EN_PAUSE_BMC_1_QUEUE[21] - (RW) Pause control of BMC queue 1. +* EN_PAUSE_BCN_1_QUEUE[22] - (RW) Pause control of BCN queue 1. +* EN_PAUSE_PSMP_1_QUEUE[23] - (RW) Pause control of PSMP queue 1. +* EN_PAUSE_NAF_QUEUE[24] - (RW) Pause control of NAF queue. +* EN_PAUSE_NBCN_QUEUE[25] - (RW) Pause control of NBCN queue. +* RESERVED26[30..26] - (RO) Reserved bits +* PSE_TXS_BUF_VALID[31] - (RO) PSE TXS buffer status. +*/ +#define WF_PLE_TOP_TXS_BUF_PAUSE_PSE_TXS_BUF_VALID_ADDR \ +WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_PSE_TXS_BUF_VALID_MASK \ +0x80000000 /* PSE_TXS_BUF_VALID[31] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_PSE_TXS_BUF_VALID_SHFT 31 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_NBCN_QUEUE_ADDR \ +WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_NBCN_QUEUE_MASK \ +0x02000000 /* EN_PAUSE_NBCN_QUEUE[25] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_NBCN_QUEUE_SHFT 25 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_NAF_QUEUE_ADDR \ +WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_NAF_QUEUE_MASK \ +0x01000000 /* EN_PAUSE_NAF_QUEUE[24] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_NAF_QUEUE_SHFT 24 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_PSMP_1_QUEUE_ADDR \ +WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_PSMP_1_QUEUE_MASK \ +0x00800000 /* EN_PAUSE_PSMP_1_QUEUE[23] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_PSMP_1_QUEUE_SHFT 23 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_BCN_1_QUEUE_ADDR \ +WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_BCN_1_QUEUE_MASK \ +0x00400000 /* EN_PAUSE_BCN_1_QUEUE[22] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_BCN_1_QUEUE_SHFT 22 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_BMC_1_QUEUE_ADDR \ +WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_BMC_1_QUEUE_MASK \ +0x00200000 /* EN_PAUSE_BMC_1_QUEUE[21] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_BMC_1_QUEUE_SHFT 21 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_ALTX_1_QUEUE_ADDR \ +WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_ALTX_1_QUEUE_MASK \ +0x00100000 /* EN_PAUSE_ALTX_1_QUEUE[20] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_ALTX_1_QUEUE_SHFT 20 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_PSMP_0_QUEUE_ADDR \ +WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_PSMP_0_QUEUE_MASK \ +0x00080000 /* EN_PAUSE_PSMP_0_QUEUE[19] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_PSMP_0_QUEUE_SHFT 19 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_BCN_0_QUEUE_ADDR \ +WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_BCN_0_QUEUE_MASK \ +0x00040000 /* EN_PAUSE_BCN_0_QUEUE[18] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_BCN_0_QUEUE_SHFT 18 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_BMC_0_QUEUE_ADDR \ +WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_BMC_0_QUEUE_MASK \ +0x00020000 /* EN_PAUSE_BMC_0_QUEUE[17] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_BMC_0_QUEUE_SHFT 17 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_ALTX_0_QUEUE_ADDR \ +WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_ALTX_0_QUEUE_MASK \ +0x00010000 /* EN_PAUSE_ALTX_0_QUEUE[16] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_ALTX_0_QUEUE_SHFT 16 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC33_QUEUE_ADDR \ +WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC33_QUEUE_MASK \ +0x00008000 /* EN_PAUSE_AC33_QUEUE[15] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC33_QUEUE_SHFT 15 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC32_QUEUE_ADDR \ +WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC32_QUEUE_MASK \ +0x00004000 /* EN_PAUSE_AC32_QUEUE[14] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC32_QUEUE_SHFT 14 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC31_QUEUE_ADDR \ +WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC31_QUEUE_MASK \ +0x00002000 /* EN_PAUSE_AC31_QUEUE[13] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC31_QUEUE_SHFT 13 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC30_QUEUE_ADDR \ +WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC30_QUEUE_MASK \ +0x00001000 /* EN_PAUSE_AC30_QUEUE[12] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC30_QUEUE_SHFT 12 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC23_QUEUE_ADDR \ +WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC23_QUEUE_MASK \ +0x00000800 /* EN_PAUSE_AC23_QUEUE[11] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC23_QUEUE_SHFT 11 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC22_QUEUE_ADDR \ +WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC22_QUEUE_MASK \ +0x00000400 /* EN_PAUSE_AC22_QUEUE[10] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC22_QUEUE_SHFT 10 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC21_QUEUE_ADDR \ +WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC21_QUEUE_MASK \ +0x00000200 /* EN_PAUSE_AC21_QUEUE[9] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC21_QUEUE_SHFT 9 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC20_QUEUE_ADDR \ +WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC20_QUEUE_MASK \ +0x00000100 /* EN_PAUSE_AC20_QUEUE[8] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC20_QUEUE_SHFT 8 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC13_QUEUE_ADDR \ +WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC13_QUEUE_MASK \ +0x00000080 /* EN_PAUSE_AC13_QUEUE[7] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC13_QUEUE_SHFT 7 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC12_QUEUE_ADDR \ +WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC12_QUEUE_MASK \ +0x00000040 /* EN_PAUSE_AC12_QUEUE[6] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC12_QUEUE_SHFT 6 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC11_QUEUE_ADDR \ +WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC11_QUEUE_MASK \ +0x00000020 /* EN_PAUSE_AC11_QUEUE[5] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC11_QUEUE_SHFT 5 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC10_QUEUE_ADDR \ +WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC10_QUEUE_MASK \ +0x00000010 /* EN_PAUSE_AC10_QUEUE[4] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC10_QUEUE_SHFT 4 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC03_QUEUE_ADDR \ +WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC03_QUEUE_MASK \ +0x00000008 /* EN_PAUSE_AC03_QUEUE[3] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC03_QUEUE_SHFT 3 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC02_QUEUE_ADDR \ +WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC02_QUEUE_MASK \ +0x00000004 /* EN_PAUSE_AC02_QUEUE[2] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC02_QUEUE_SHFT 2 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC01_QUEUE_ADDR \ +WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC01_QUEUE_MASK \ +0x00000002 /* EN_PAUSE_AC01_QUEUE[1] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC01_QUEUE_SHFT 1 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC00_QUEUE_ADDR \ +WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC00_QUEUE_MASK \ +0x00000001 /* EN_PAUSE_AC00_QUEUE[0] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC00_QUEUE_SHFT 0 + +/* +* ---NATIVE_TXD_QUEUE_EMPTY (0x820C0000 + 0x228)--- +* AC00_EMPTY[0] - (RO) WMM0 AC0 queue empty status +* AC01_EMPTY[1] - (RO) WMM0 AC1 queue empty status +* AC02_EMPTY[2] - (RO) WMM0 AC2 queue empty status +* AC03_EMPTY[3] - (RO) WMM0 AC3 queue empty status +* AC10_EMPTY[4] - (RO) WMM1 AC0 queue empty status +* AC11_EMPTY[5] - (RO) WMM1 AC1 queue empty status +* AC12_EMPTY[6] - (RO) WMM1 AC2 queue empty status +* AC13_EMPTY[7] - (RO) WMM1 AC3 queue empty status +* AC20_EMPTY[8] - (RO) WMM2 AC0 queue empty status +* AC21_EMPTY[9] - (RO) WMM2 AC1 queue empty status +* AC22_EMPTY[10] - (RO) WMM2 AC2 queue empty status +* AC23_EMPTY[11] - (RO) WMM2 AC3 queue empty status +* AC30_EMPTY[12] - (RO) WMM3 AC0 queue empty status +* AC31_EMPTY[13] - (RO) WMM3 AC1 queue empty status +* AC32_EMPTY[14] - (RO) WMM3 AC2 queue empty status +* AC33_EMPTY[15] - (RO) WMM3 AC3 queue empty status +* ALTX_0_EMPTY[16] - (RO) ALTX queue 0 empty status +* BMC_0_EMPTY[17] - (RO) BMC queue 0 empty status +* BCN_0_EMPTY[18] - (RO) BCN queue 0 empty status +* PSMP_0_EMPTY[19] - (RO) PSMP queue 0 empty status +* ALTX_1_EMPTY[20] - (RO) ALTX queue 1 empty status +* BMC_1_EMPTY[21] - (RO) BMC queue 1 empty status +* BCN_1_EMPTY[22] - (RO) BCN queue 1 empty status +* PSMP_1_EMPTY[23] - (RO) PSMP queue 1 empty status +* NAF_EMPTY[24] - (RO) NAF queue empty status +* NBCN_EMPTY[25] - (RO) NBCN queue empty status +* RESERVED26[31..26] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_NBCN_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_NBCN_EMPTY_MASK \ +0x02000000 /* NBCN_EMPTY[25] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_NBCN_EMPTY_SHFT 25 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_NAF_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_NAF_EMPTY_MASK \ +0x01000000 /* NAF_EMPTY[24] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_NAF_EMPTY_SHFT 24 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_PSMP_1_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_PSMP_1_EMPTY_MASK \ +0x00800000 /* PSMP_1_EMPTY[23] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_PSMP_1_EMPTY_SHFT 23 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_BCN_1_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_BCN_1_EMPTY_MASK \ +0x00400000 /* BCN_1_EMPTY[22] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_BCN_1_EMPTY_SHFT 22 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_BMC_1_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_BMC_1_EMPTY_MASK \ +0x00200000 /* BMC_1_EMPTY[21] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_BMC_1_EMPTY_SHFT 21 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ALTX_1_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ALTX_1_EMPTY_MASK \ +0x00100000 /* ALTX_1_EMPTY[20] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ALTX_1_EMPTY_SHFT 20 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_PSMP_0_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_PSMP_0_EMPTY_MASK \ +0x00080000 /* PSMP_0_EMPTY[19] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_PSMP_0_EMPTY_SHFT 19 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_BCN_0_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_BCN_0_EMPTY_MASK \ +0x00040000 /* BCN_0_EMPTY[18] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_BCN_0_EMPTY_SHFT 18 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_BMC_0_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_BMC_0_EMPTY_MASK \ +0x00020000 /* BMC_0_EMPTY[17] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_BMC_0_EMPTY_SHFT 17 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ALTX_0_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ALTX_0_EMPTY_MASK \ +0x00010000 /* ALTX_0_EMPTY[16] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ALTX_0_EMPTY_SHFT 16 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC33_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC33_EMPTY_MASK \ +0x00008000 /* AC33_EMPTY[15] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC33_EMPTY_SHFT 15 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC32_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC32_EMPTY_MASK \ +0x00004000 /* AC32_EMPTY[14] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC32_EMPTY_SHFT 14 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC31_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC31_EMPTY_MASK \ +0x00002000 /* AC31_EMPTY[13] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC31_EMPTY_SHFT 13 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC30_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC30_EMPTY_MASK \ +0x00001000 /* AC30_EMPTY[12] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC30_EMPTY_SHFT 12 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC23_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC23_EMPTY_MASK \ +0x00000800 /* AC23_EMPTY[11] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC23_EMPTY_SHFT 11 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC22_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC22_EMPTY_MASK \ +0x00000400 /* AC22_EMPTY[10] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC22_EMPTY_SHFT 10 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC21_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC21_EMPTY_MASK \ +0x00000200 /* AC21_EMPTY[9] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC21_EMPTY_SHFT 9 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC20_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC20_EMPTY_MASK \ +0x00000100 /* AC20_EMPTY[8] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC20_EMPTY_SHFT 8 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC13_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC13_EMPTY_MASK \ +0x00000080 /* AC13_EMPTY[7] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC13_EMPTY_SHFT 7 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC12_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC12_EMPTY_MASK \ +0x00000040 /* AC12_EMPTY[6] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC12_EMPTY_SHFT 6 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC11_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC11_EMPTY_MASK \ +0x00000020 /* AC11_EMPTY[5] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC11_EMPTY_SHFT 5 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC10_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC10_EMPTY_MASK \ +0x00000010 /* AC10_EMPTY[4] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC10_EMPTY_SHFT 4 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC03_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC03_EMPTY_MASK \ +0x00000008 /* AC03_EMPTY[3] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC03_EMPTY_SHFT 3 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC02_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC02_EMPTY_MASK \ +0x00000004 /* AC02_EMPTY[2] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC02_EMPTY_SHFT 2 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC01_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC01_EMPTY_MASK \ +0x00000002 /* AC01_EMPTY[1] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC01_EMPTY_SHFT 1 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC00_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC00_EMPTY_MASK \ +0x00000001 /* AC00_EMPTY[0] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC00_EMPTY_SHFT 0 + +/* +* ---NATIVE_TXCMD_QUEUE_EMPTY (0x820C0000 + 0x22c)--- +* AC00_TXCMD_EMPTY[0] - (RO) WMM0 AC0 TXCMD queue empty status +* AC01_TXCMD_EMPTY[1] - (RO) WMM0 AC1 TXCMD queue empty status +* AC02_TXCMD_EMPTY[2] - (RO) WMM0 AC2 TXCMD queue empty status +* AC03_TXCMD_EMPTY[3] - (RO) WMM0 AC3 TXCMD queue empty status +* AC10_TXCMD_EMPTY[4] - (RO) WMM1 AC0 TXCMD queue empty status +* AC11_TXCMD_EMPTY[5] - (RO) WMM1 AC1 TXCMD queue empty status +* AC12_TXCMD_EMPTY[6] - (RO) WMM1 AC2 TXCMD queue empty status +* AC13_TXCMD_EMPTY[7] - (RO) WMM1 AC3 TXCMD queue empty status +* AC20_TXCMD_EMPTY[8] - (RO) WMM2 AC0 TXCMD queue empty status +* AC21_TXCMD_EMPTY[9] - (RO) WMM2 AC1 TXCMD queue empty status +* AC22_TXCMD_EMPTY[10] - (RO) WMM2 AC2 TXCMD queue empty status +* AC23_TXCMD_EMPTY[11] - (RO) WMM2 AC3 TXCMD queue empty status +* AC30_TXCMD_EMPTY[12] - (RO) WMM3 AC0 TXCMD queue empty status +* AC31_TXCMD_EMPTY[13] - (RO) WMM3 AC1 TXCMD queue empty status +* AC32_TXCMD_EMPTY[14] - (RO) WMM3 AC2 TXCMD queue empty status +* AC33_TXCMD_EMPTY[15] - (RO) WMM3 AC3 TXCMD queue empty status +* ALTXCMD_0_EMPTY[16] - (RO) ALTXCMD 0 queue empty status +* TF_0_EMPTY[17] - (RO) TF 0 queue empty status +* TWT_TSF_TF_0_EMPTY[18] - (RO) TWT TSF-TF 0 queue empty status +* TWT_DL_0_EMPTY[19] - (RO) TWT DL 0 queue empty status +* TWT_UL_0_EMPTY[20] - (RO) TWT UL 0 queue empty status +* ALTXCMD_1_EMPTY[21] - (RO) ALTXCMD 1 queue empty status +* TF_1_EMPTY[22] - (RO) TF 1 queue empty status +* TWT_TSF_TF_1_EMPTY[23] - (RO) TWT TSF-TF 1 queue empty status +* TWT_DL_1_EMPTY[24] - (RO) TWT DL 1 queue empty status +* TWT_UL_1_EMPTY[25] - (RO) TWT UL 1 queue empty status +* RESERVED26[31..26] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_TWT_UL_1_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_TWT_UL_1_EMPTY_MASK \ +0x02000000 /* TWT_UL_1_EMPTY[25] */ +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_TWT_UL_1_EMPTY_SHFT 25 +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_TWT_DL_1_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_TWT_DL_1_EMPTY_MASK \ +0x01000000 /* TWT_DL_1_EMPTY[24] */ +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_TWT_DL_1_EMPTY_SHFT 24 +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_TWT_TSF_TF_1_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_TWT_TSF_TF_1_EMPTY_MASK \ +0x00800000 /* TWT_TSF_TF_1_EMPTY[23] */ +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_TWT_TSF_TF_1_EMPTY_SHFT 23 +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_TF_1_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_TF_1_EMPTY_MASK \ +0x00400000 /* TF_1_EMPTY[22] */ +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_TF_1_EMPTY_SHFT 22 +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_ALTXCMD_1_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_ALTXCMD_1_EMPTY_MASK \ +0x00200000 /* ALTXCMD_1_EMPTY[21] */ +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_ALTXCMD_1_EMPTY_SHFT 21 +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_TWT_UL_0_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_TWT_UL_0_EMPTY_MASK \ +0x00100000 /* TWT_UL_0_EMPTY[20] */ +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_TWT_UL_0_EMPTY_SHFT 20 +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_TWT_DL_0_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_TWT_DL_0_EMPTY_MASK \ +0x00080000 /* TWT_DL_0_EMPTY[19] */ +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_TWT_DL_0_EMPTY_SHFT 19 +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_TWT_TSF_TF_0_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_TWT_TSF_TF_0_EMPTY_MASK \ +0x00040000 /* TWT_TSF_TF_0_EMPTY[18] */ +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_TWT_TSF_TF_0_EMPTY_SHFT 18 +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_TF_0_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_TF_0_EMPTY_MASK \ +0x00020000 /* TF_0_EMPTY[17] */ +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_TF_0_EMPTY_SHFT 17 +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_ALTXCMD_0_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_ALTXCMD_0_EMPTY_MASK \ +0x00010000 /* ALTXCMD_0_EMPTY[16] */ +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_ALTXCMD_0_EMPTY_SHFT 16 +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC33_TXCMD_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC33_TXCMD_EMPTY_MASK \ +0x00008000 /* AC33_TXCMD_EMPTY[15] */ +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC33_TXCMD_EMPTY_SHFT 15 +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC32_TXCMD_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC32_TXCMD_EMPTY_MASK \ +0x00004000 /* AC32_TXCMD_EMPTY[14] */ +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC32_TXCMD_EMPTY_SHFT 14 +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC31_TXCMD_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC31_TXCMD_EMPTY_MASK \ +0x00002000 /* AC31_TXCMD_EMPTY[13] */ +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC31_TXCMD_EMPTY_SHFT 13 +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC30_TXCMD_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC30_TXCMD_EMPTY_MASK \ +0x00001000 /* AC30_TXCMD_EMPTY[12] */ +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC30_TXCMD_EMPTY_SHFT 12 +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC23_TXCMD_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC23_TXCMD_EMPTY_MASK \ +0x00000800 /* AC23_TXCMD_EMPTY[11] */ +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC23_TXCMD_EMPTY_SHFT 11 +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC22_TXCMD_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC22_TXCMD_EMPTY_MASK \ +0x00000400 /* AC22_TXCMD_EMPTY[10] */ +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC22_TXCMD_EMPTY_SHFT 10 +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC21_TXCMD_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC21_TXCMD_EMPTY_MASK \ +0x00000200 /* AC21_TXCMD_EMPTY[9] */ +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC21_TXCMD_EMPTY_SHFT 9 +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC20_TXCMD_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC20_TXCMD_EMPTY_MASK \ +0x00000100 /* AC20_TXCMD_EMPTY[8] */ +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC20_TXCMD_EMPTY_SHFT 8 +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC13_TXCMD_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC13_TXCMD_EMPTY_MASK \ +0x00000080 /* AC13_TXCMD_EMPTY[7] */ +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC13_TXCMD_EMPTY_SHFT 7 +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC12_TXCMD_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC12_TXCMD_EMPTY_MASK \ +0x00000040 /* AC12_TXCMD_EMPTY[6] */ +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC12_TXCMD_EMPTY_SHFT 6 +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC11_TXCMD_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC11_TXCMD_EMPTY_MASK \ +0x00000020 /* AC11_TXCMD_EMPTY[5] */ +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC11_TXCMD_EMPTY_SHFT 5 +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC10_TXCMD_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC10_TXCMD_EMPTY_MASK \ +0x00000010 /* AC10_TXCMD_EMPTY[4] */ +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC10_TXCMD_EMPTY_SHFT 4 +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC03_TXCMD_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC03_TXCMD_EMPTY_MASK \ +0x00000008 /* AC03_TXCMD_EMPTY[3] */ +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC03_TXCMD_EMPTY_SHFT 3 +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC02_TXCMD_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC02_TXCMD_EMPTY_MASK \ +0x00000004 /* AC02_TXCMD_EMPTY[2] */ +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC02_TXCMD_EMPTY_SHFT 2 +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC01_TXCMD_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC01_TXCMD_EMPTY_MASK \ +0x00000002 /* AC01_TXCMD_EMPTY[1] */ +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC01_TXCMD_EMPTY_SHFT 1 +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC00_TXCMD_EMPTY_ADDR \ +WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC00_TXCMD_EMPTY_MASK \ +0x00000001 /* AC00_TXCMD_EMPTY[0] */ +#define WF_PLE_TOP_NATIVE_TXCMD_QUEUE_EMPTY_AC00_TXCMD_EMPTY_SHFT 0 + +/* +* ---TXCMD_QUEUE_EMPTY (0x820C0000 + 0x230)--- +* AC00_TXCMD_EMPTY[0] - (RO) WMM0 AC0 TXCMD queue empty status +* AC01_TXCMD_EMPTY[1] - (RO) WMM0 AC1 TXCMD queue empty status +* AC02_TXCMD_EMPTY[2] - (RO) WMM0 AC2 TXCMD queue empty status +* AC03_TXCMD_EMPTY[3] - (RO) WMM0 AC3 TXCMD queue empty status +* AC10_TXCMD_EMPTY[4] - (RO) WMM1 AC0 TXCMD queue empty status +* AC11_TXCMD_EMPTY[5] - (RO) WMM1 AC1 TXCMD queue empty status +* AC12_TXCMD_EMPTY[6] - (RO) WMM1 AC2 TXCMD queue empty status +* AC13_TXCMD_EMPTY[7] - (RO) WMM1 AC3 TXCMD queue empty status +* AC20_TXCMD_EMPTY[8] - (RO) WMM2 AC0 TXCMD queue empty status +* AC21_TXCMD_EMPTY[9] - (RO) WMM2 AC1 TXCMD queue empty status +* AC22_TXCMD_EMPTY[10] - (RO) WMM2 AC2 TXCMD queue empty status +* AC23_TXCMD_EMPTY[11] - (RO) WMM2 AC3 TXCMD queue empty status +* AC30_TXCMD_EMPTY[12] - (RO) WMM3 AC0 TXCMD queue empty status +* AC31_TXCMD_EMPTY[13] - (RO) WMM3 AC1 TXCMD queue empty status +* AC32_TXCMD_EMPTY[14] - (RO) WMM3 AC2 TXCMD queue empty status +* AC33_TXCMD_EMPTY[15] - (RO) WMM3 AC3 TXCMD queue empty status +* ALTXCMD_0_EMPTY[16] - (RO) ALTXCMD 0 queue empty status +* TF_0_EMPTY[17] - (RO) TF 0 queue empty status +* TWT_TSF_TF_0_EMPTY[18] - (RO) TWT TSF-TF 0 queue empty status +* TWT_DL_0_EMPTY[19] - (RO) TWT DL 0 queue empty status +* TWT_UL_0_EMPTY[20] - (RO) TWT UL 0 queue empty status +* ALTXCMD_1_EMPTY[21] - (RO) ALTXCMD 1 queue empty status +* TF_1_EMPTY[22] - (RO) TF 1 queue empty status +* TWT_TSF_TF_1_EMPTY[23] - (RO) TWT TSF-TF 1 queue empty status +* TWT_DL_1_EMPTY[24] - (RO) TWT DL 1 queue empty status +* TWT_UL_1_EMPTY[25] - (RO) TWT UL 1 queue empty status +* RESERVED26[31..26] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_TWT_UL_1_EMPTY_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_TWT_UL_1_EMPTY_MASK \ +0x02000000 /* TWT_UL_1_EMPTY[25] */ +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_TWT_UL_1_EMPTY_SHFT 25 +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_TWT_DL_1_EMPTY_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_TWT_DL_1_EMPTY_MASK \ +0x01000000 /* TWT_DL_1_EMPTY[24] */ +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_TWT_DL_1_EMPTY_SHFT 24 +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_TWT_TSF_TF_1_EMPTY_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_TWT_TSF_TF_1_EMPTY_MASK \ +0x00800000 /* TWT_TSF_TF_1_EMPTY[23] */ +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_TWT_TSF_TF_1_EMPTY_SHFT 23 +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_TF_1_EMPTY_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_TF_1_EMPTY_MASK \ +0x00400000 /* TF_1_EMPTY[22] */ +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_TF_1_EMPTY_SHFT 22 +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_ALTXCMD_1_EMPTY_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_ALTXCMD_1_EMPTY_MASK \ +0x00200000 /* ALTXCMD_1_EMPTY[21] */ +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_ALTXCMD_1_EMPTY_SHFT 21 +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_TWT_UL_0_EMPTY_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_TWT_UL_0_EMPTY_MASK \ +0x00100000 /* TWT_UL_0_EMPTY[20] */ +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_TWT_UL_0_EMPTY_SHFT 20 +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_TWT_DL_0_EMPTY_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_TWT_DL_0_EMPTY_MASK \ +0x00080000 /* TWT_DL_0_EMPTY[19] */ +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_TWT_DL_0_EMPTY_SHFT 19 +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_TWT_TSF_TF_0_EMPTY_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_TWT_TSF_TF_0_EMPTY_MASK \ +0x00040000 /* TWT_TSF_TF_0_EMPTY[18] */ +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_TWT_TSF_TF_0_EMPTY_SHFT 18 +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_TF_0_EMPTY_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_TF_0_EMPTY_MASK \ +0x00020000 /* TF_0_EMPTY[17] */ +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_TF_0_EMPTY_SHFT 17 +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_ALTXCMD_0_EMPTY_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_ALTXCMD_0_EMPTY_MASK \ +0x00010000 /* ALTXCMD_0_EMPTY[16] */ +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_ALTXCMD_0_EMPTY_SHFT 16 +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC33_TXCMD_EMPTY_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC33_TXCMD_EMPTY_MASK \ +0x00008000 /* AC33_TXCMD_EMPTY[15] */ +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC33_TXCMD_EMPTY_SHFT 15 +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC32_TXCMD_EMPTY_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC32_TXCMD_EMPTY_MASK \ +0x00004000 /* AC32_TXCMD_EMPTY[14] */ +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC32_TXCMD_EMPTY_SHFT 14 +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC31_TXCMD_EMPTY_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC31_TXCMD_EMPTY_MASK \ +0x00002000 /* AC31_TXCMD_EMPTY[13] */ +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC31_TXCMD_EMPTY_SHFT 13 +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC30_TXCMD_EMPTY_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC30_TXCMD_EMPTY_MASK \ +0x00001000 /* AC30_TXCMD_EMPTY[12] */ +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC30_TXCMD_EMPTY_SHFT 12 +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC23_TXCMD_EMPTY_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC23_TXCMD_EMPTY_MASK \ +0x00000800 /* AC23_TXCMD_EMPTY[11] */ +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC23_TXCMD_EMPTY_SHFT 11 +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC22_TXCMD_EMPTY_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC22_TXCMD_EMPTY_MASK \ +0x00000400 /* AC22_TXCMD_EMPTY[10] */ +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC22_TXCMD_EMPTY_SHFT 10 +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC21_TXCMD_EMPTY_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC21_TXCMD_EMPTY_MASK \ +0x00000200 /* AC21_TXCMD_EMPTY[9] */ +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC21_TXCMD_EMPTY_SHFT 9 +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC20_TXCMD_EMPTY_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC20_TXCMD_EMPTY_MASK \ +0x00000100 /* AC20_TXCMD_EMPTY[8] */ +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC20_TXCMD_EMPTY_SHFT 8 +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC13_TXCMD_EMPTY_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC13_TXCMD_EMPTY_MASK \ +0x00000080 /* AC13_TXCMD_EMPTY[7] */ +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC13_TXCMD_EMPTY_SHFT 7 +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC12_TXCMD_EMPTY_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC12_TXCMD_EMPTY_MASK \ +0x00000040 /* AC12_TXCMD_EMPTY[6] */ +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC12_TXCMD_EMPTY_SHFT 6 +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC11_TXCMD_EMPTY_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC11_TXCMD_EMPTY_MASK \ +0x00000020 /* AC11_TXCMD_EMPTY[5] */ +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC11_TXCMD_EMPTY_SHFT 5 +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC10_TXCMD_EMPTY_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC10_TXCMD_EMPTY_MASK \ +0x00000010 /* AC10_TXCMD_EMPTY[4] */ +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC10_TXCMD_EMPTY_SHFT 4 +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC03_TXCMD_EMPTY_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC03_TXCMD_EMPTY_MASK \ +0x00000008 /* AC03_TXCMD_EMPTY[3] */ +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC03_TXCMD_EMPTY_SHFT 3 +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC02_TXCMD_EMPTY_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC02_TXCMD_EMPTY_MASK \ +0x00000004 /* AC02_TXCMD_EMPTY[2] */ +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC02_TXCMD_EMPTY_SHFT 2 +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC01_TXCMD_EMPTY_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC01_TXCMD_EMPTY_MASK \ +0x00000002 /* AC01_TXCMD_EMPTY[1] */ +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC01_TXCMD_EMPTY_SHFT 1 +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC00_TXCMD_EMPTY_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC00_TXCMD_EMPTY_MASK \ +0x00000001 /* AC00_TXCMD_EMPTY[0] */ +#define WF_PLE_TOP_TXCMD_QUEUE_EMPTY_AC00_TXCMD_EMPTY_SHFT 0 + +/* +* ---TXCMD_QUEUE_PAUSE (0x820C0000 + 0x234)--- +* EN_PAUSE_AC00_QUEUE[0] - (RW) Pause control of WMM0 AC0 TXCMD queue. +* EN_PAUSE_AC01_QUEUE[1] - (RW) Pause control of WMM0 AC1 TXCMD queue. +* EN_PAUSE_AC02_QUEUE[2] - (RW) Pause control of WMM0 AC2 TXCMD queue. +* EN_PAUSE_AC03_QUEUE[3] - (RW) Pause control of WMM0 AC3 TXCMD queue. +* EN_PAUSE_AC10_QUEUE[4] - (RW) Pause control of WMM1 AC0 TXCMD queue. +* EN_PAUSE_AC11_QUEUE[5] - (RW) Pause control of WMM1 AC1 TXCMD queue. +* EN_PAUSE_AC12_QUEUE[6] - (RW) Pause control of WMM1 AC2 TXCMD queue. +* EN_PAUSE_AC13_QUEUE[7] - (RW) Pause control of WMM1 AC3 TXCMD queue. +* EN_PAUSE_AC20_QUEUE[8] - (RW) Pause control of WMM2 AC0 TXCMD queue. +* EN_PAUSE_AC21_QUEUE[9] - (RW) Pause control of WMM2 AC1 TXCMD queue. +* EN_PAUSE_AC22_QUEUE[10] - (RW) Pause control of WMM2 AC2 TXCMD queue. +* EN_PAUSE_AC23_QUEUE[11] - (RW) Pause control of WMM2 AC3 TXCMD queue. +* EN_PAUSE_AC30_QUEUE[12] - (RW) Pause control of WMM3 AC0 TXCMD queue. +* EN_PAUSE_AC31_QUEUE[13] - (RW) Pause control of WMM3 AC1 TXCMD queue. +* EN_PAUSE_AC32_QUEUE[14] - (RW) Pause control of WMM3 AC2 TXCMD queue. +* EN_PAUSE_AC33_QUEUE[15] - (RW) Pause control of WMM3 AC3 TXCMD queue. +* EN_PAUSE_ALTXCMD_0_QUEUE[16] - (RW) Pause control of ALTXCMD 0 queue. +* EN_PAUSE_TF_0_QUEUE[17] - (RW) Pause control of TF 0 TXCDM queue . +* EN_PAUSE_TWT_TSF_TF_0_QUEUE[18] - (RW) Pause control of TWT TSF TF 0 TXCMD +queue. +* EN_PAUSE_TWT_DL_0_QUEUE[19] - (RW) Pause control of TWT DL 0 TXCMD queue. +* EN_PAUSE_TWT_UL_0_QUEUE[20] - (RW) Pause control of TWT UL 0 TXCMD queue. +* EN_PAUSE_ALTXCMD_1_QUEUE[21] - (RW) Pause control of ALTXCMD 1 queue. +* EN_PAUSE_TF_1_QUEUE[22] - (RW) Pause control of TF 1 TXCDM queue . +* EN_PAUSE_TWT_TSF_TF_1_QUEUE[23] - (RW) Pause control of TWT TSF TF 1 TXCMD +queue. +* EN_PAUSE_TWT_DL_1_QUEUE[24] - (RW) Pause control of TWT DL 1 TXCMD queue. +* EN_PAUSE_TWT_UL_1_QUEUE[25] - (RW) Pause control of TWT UL 1 TXCMD queue. +* RESERVED26[31..26] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_TWT_UL_1_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_TWT_UL_1_QUEUE_MASK \ +0x02000000 /* EN_PAUSE_TWT_UL_1_QUEUE[25] */ +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_TWT_UL_1_QUEUE_SHFT 25 +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_TWT_DL_1_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_TWT_DL_1_QUEUE_MASK \ +0x01000000 /* EN_PAUSE_TWT_DL_1_QUEUE[24] */ +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_TWT_DL_1_QUEUE_SHFT 24 +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_TWT_TSF_TF_1_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_TWT_TSF_TF_1_QUEUE_MASK \ +0x00800000 /* EN_PAUSE_TWT_TSF_TF_1_QUEUE[23] */ +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_TWT_TSF_TF_1_QUEUE_SHFT 23 +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_TF_1_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_TF_1_QUEUE_MASK \ +0x00400000 /* EN_PAUSE_TF_1_QUEUE[22] */ +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_TF_1_QUEUE_SHFT 22 +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_ALTXCMD_1_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_ALTXCMD_1_QUEUE_MASK \ +0x00200000 /* EN_PAUSE_ALTXCMD_1_QUEUE[21] */ +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_ALTXCMD_1_QUEUE_SHFT 21 +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_TWT_UL_0_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_TWT_UL_0_QUEUE_MASK \ +0x00100000 /* EN_PAUSE_TWT_UL_0_QUEUE[20] */ +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_TWT_UL_0_QUEUE_SHFT 20 +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_TWT_DL_0_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_TWT_DL_0_QUEUE_MASK \ +0x00080000 /* EN_PAUSE_TWT_DL_0_QUEUE[19] */ +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_TWT_DL_0_QUEUE_SHFT 19 +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_TWT_TSF_TF_0_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_TWT_TSF_TF_0_QUEUE_MASK \ +0x00040000 /* EN_PAUSE_TWT_TSF_TF_0_QUEUE[18] */ +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_TWT_TSF_TF_0_QUEUE_SHFT 18 +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_TF_0_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_TF_0_QUEUE_MASK \ +0x00020000 /* EN_PAUSE_TF_0_QUEUE[17] */ +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_TF_0_QUEUE_SHFT 17 +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_ALTXCMD_0_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_ALTXCMD_0_QUEUE_MASK \ +0x00010000 /* EN_PAUSE_ALTXCMD_0_QUEUE[16] */ +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_ALTXCMD_0_QUEUE_SHFT 16 +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC33_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC33_QUEUE_MASK \ +0x00008000 /* EN_PAUSE_AC33_QUEUE[15] */ +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC33_QUEUE_SHFT 15 +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC32_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC32_QUEUE_MASK \ +0x00004000 /* EN_PAUSE_AC32_QUEUE[14] */ +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC32_QUEUE_SHFT 14 +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC31_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC31_QUEUE_MASK \ +0x00002000 /* EN_PAUSE_AC31_QUEUE[13] */ +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC31_QUEUE_SHFT 13 +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC30_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC30_QUEUE_MASK \ +0x00001000 /* EN_PAUSE_AC30_QUEUE[12] */ +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC30_QUEUE_SHFT 12 +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC23_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC23_QUEUE_MASK \ +0x00000800 /* EN_PAUSE_AC23_QUEUE[11] */ +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC23_QUEUE_SHFT 11 +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC22_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC22_QUEUE_MASK \ +0x00000400 /* EN_PAUSE_AC22_QUEUE[10] */ +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC22_QUEUE_SHFT 10 +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC21_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC21_QUEUE_MASK \ +0x00000200 /* EN_PAUSE_AC21_QUEUE[9] */ +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC21_QUEUE_SHFT 9 +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC20_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC20_QUEUE_MASK \ +0x00000100 /* EN_PAUSE_AC20_QUEUE[8] */ +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC20_QUEUE_SHFT 8 +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC13_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC13_QUEUE_MASK \ +0x00000080 /* EN_PAUSE_AC13_QUEUE[7] */ +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC13_QUEUE_SHFT 7 +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC12_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC12_QUEUE_MASK \ +0x00000040 /* EN_PAUSE_AC12_QUEUE[6] */ +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC12_QUEUE_SHFT 6 +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC11_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC11_QUEUE_MASK \ +0x00000020 /* EN_PAUSE_AC11_QUEUE[5] */ +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC11_QUEUE_SHFT 5 +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC10_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC10_QUEUE_MASK \ +0x00000010 /* EN_PAUSE_AC10_QUEUE[4] */ +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC10_QUEUE_SHFT 4 +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC03_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC03_QUEUE_MASK \ +0x00000008 /* EN_PAUSE_AC03_QUEUE[3] */ +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC03_QUEUE_SHFT 3 +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC02_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC02_QUEUE_MASK \ +0x00000004 /* EN_PAUSE_AC02_QUEUE[2] */ +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC02_QUEUE_SHFT 2 +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC01_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC01_QUEUE_MASK \ +0x00000002 /* EN_PAUSE_AC01_QUEUE[1] */ +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC01_QUEUE_SHFT 1 +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC00_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_QUEUE_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC00_QUEUE_MASK \ +0x00000001 /* EN_PAUSE_AC00_QUEUE[0] */ +#define WF_PLE_TOP_TXCMD_QUEUE_PAUSE_EN_PAUSE_AC00_QUEUE_SHFT 0 + +/* +* ---TXCMD_TXS_BUF_PAUSE (0x820C0000 + 0x238)--- +* EN_PAUSE_AC00_QUEUE[0] - (RW) Pause control of WMM0 AC0 TXCMD queue. +* EN_PAUSE_AC01_QUEUE[1] - (RW) Pause control of WMM0 AC1 TXCMD queue. +* EN_PAUSE_AC02_QUEUE[2] - (RW) Pause control of WMM0 AC2 TXCMD queue. +* EN_PAUSE_AC03_QUEUE[3] - (RW) Pause control of WMM0 AC3 TXCMD queue. +* EN_PAUSE_AC10_QUEUE[4] - (RW) Pause control of WMM1 AC0 TXCMD queue. +* EN_PAUSE_AC11_QUEUE[5] - (RW) Pause control of WMM1 AC1 TXCMD queue. +* EN_PAUSE_AC12_QUEUE[6] - (RW) Pause control of WMM1 AC2 TXCMD queue. +* EN_PAUSE_AC13_QUEUE[7] - (RW) Pause control of WMM1 AC3 TXCMD queue. +* EN_PAUSE_AC20_QUEUE[8] - (RW) Pause control of WMM2 AC0 TXCMD queue. +* EN_PAUSE_AC21_QUEUE[9] - (RW) Pause control of WMM2 AC1 TXCMD queue. +* EN_PAUSE_AC22_QUEUE[10] - (RW) Pause control of WMM2 AC2 TXCMD queue. +* EN_PAUSE_AC23_QUEUE[11] - (RW) Pause control of WMM2 AC3 TXCMD queue. +* EN_PAUSE_AC30_QUEUE[12] - (RW) Pause control of WMM3 AC0 TXCMD queue. +* EN_PAUSE_AC31_QUEUE[13] - (RW) Pause control of WMM3 AC1 TXCMD queue. +* EN_PAUSE_AC32_QUEUE[14] - (RW) Pause control of WMM3 AC2 TXCMD queue. +* EN_PAUSE_AC33_QUEUE[15] - (RW) Pause control of WMM3 AC3 TXCMD queue. +* EN_PAUSE_ALTXCMD_0_QUEUE[16] - (RW) Pause control of ALTXCMD 0 queue. +* EN_PAUSE_TF_0_QUEUE[17] - (RW) Pause control of TF 0 TXCDM queue . +* EN_PAUSE_TWT_TSF_TF_0_QUEUE[18] - (RW) Pause control of TWT TSF TF 0 TXCMD +queue. +* EN_PAUSE_TWT_DL_0_QUEUE[19] - (RW) Pause control of TWT DL 0 TXCMD queue. +* EN_PAUSE_TWT_UL_0_QUEUE[20] - (RW) Pause control of TWT UL 0 TXCMD queue. +* EN_PAUSE_ALTXCMD_1_QUEUE[21] - (RW) Pause control of ALTXCMD 1 queue. +* EN_PAUSE_TF_1_QUEUE[22] - (RW) Pause control of TF 1 TXCDM queue . +* EN_PAUSE_TWT_TSF_TF_1_QUEUE[23] - (RW) Pause control of TWT TSF TF 1 TXCMD +queue. +* EN_PAUSE_TWT_DL_1_QUEUE[24] - (RW) Pause control of TWT DL 1 TXCMD queue. +* EN_PAUSE_TWT_UL_1_QUEUE[25] - (RW) Pause control of TWT UL 1 TXCMD queue. +* RESERVED26[31..26] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_TWT_UL_1_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_TWT_UL_1_QUEUE_MASK \ +0x02000000 /* EN_PAUSE_TWT_UL_1_QUEUE[25] */ +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_TWT_UL_1_QUEUE_SHFT 25 +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_TWT_DL_1_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_TWT_DL_1_QUEUE_MASK \ +0x01000000 /* EN_PAUSE_TWT_DL_1_QUEUE[24] */ +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_TWT_DL_1_QUEUE_SHFT 24 +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_TWT_TSF_TF_1_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_TWT_TSF_TF_1_QUEUE_MASK \ +0x00800000 /* EN_PAUSE_TWT_TSF_TF_1_QUEUE[23] */ +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_TWT_TSF_TF_1_QUEUE_SHFT 23 +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_TF_1_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_TF_1_QUEUE_MASK \ +0x00400000 /* EN_PAUSE_TF_1_QUEUE[22] */ +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_TF_1_QUEUE_SHFT 22 +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_ALTXCMD_1_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_ALTXCMD_1_QUEUE_MASK \ +0x00200000 /* EN_PAUSE_ALTXCMD_1_QUEUE[21] */ +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_ALTXCMD_1_QUEUE_SHFT 21 +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_TWT_UL_0_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_TWT_UL_0_QUEUE_MASK \ +0x00100000 /* EN_PAUSE_TWT_UL_0_QUEUE[20] */ +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_TWT_UL_0_QUEUE_SHFT 20 +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_TWT_DL_0_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_TWT_DL_0_QUEUE_MASK \ +0x00080000 /* EN_PAUSE_TWT_DL_0_QUEUE[19] */ +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_TWT_DL_0_QUEUE_SHFT 19 +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_TWT_TSF_TF_0_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_TWT_TSF_TF_0_QUEUE_MASK \ +0x00040000 /* EN_PAUSE_TWT_TSF_TF_0_QUEUE[18] */ +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_TWT_TSF_TF_0_QUEUE_SHFT 18 +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_TF_0_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_TF_0_QUEUE_MASK \ +0x00020000 /* EN_PAUSE_TF_0_QUEUE[17] */ +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_TF_0_QUEUE_SHFT 17 +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_ALTXCMD_0_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_ALTXCMD_0_QUEUE_MASK \ +0x00010000 /* EN_PAUSE_ALTXCMD_0_QUEUE[16] */ +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_ALTXCMD_0_QUEUE_SHFT 16 +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC33_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC33_QUEUE_MASK \ +0x00008000 /* EN_PAUSE_AC33_QUEUE[15] */ +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC33_QUEUE_SHFT 15 +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC32_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC32_QUEUE_MASK \ +0x00004000 /* EN_PAUSE_AC32_QUEUE[14] */ +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC32_QUEUE_SHFT 14 +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC31_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC31_QUEUE_MASK \ +0x00002000 /* EN_PAUSE_AC31_QUEUE[13] */ +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC31_QUEUE_SHFT 13 +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC30_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC30_QUEUE_MASK \ +0x00001000 /* EN_PAUSE_AC30_QUEUE[12] */ +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC30_QUEUE_SHFT 12 +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC23_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC23_QUEUE_MASK \ +0x00000800 /* EN_PAUSE_AC23_QUEUE[11] */ +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC23_QUEUE_SHFT 11 +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC22_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC22_QUEUE_MASK \ +0x00000400 /* EN_PAUSE_AC22_QUEUE[10] */ +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC22_QUEUE_SHFT 10 +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC21_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC21_QUEUE_MASK \ +0x00000200 /* EN_PAUSE_AC21_QUEUE[9] */ +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC21_QUEUE_SHFT 9 +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC20_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC20_QUEUE_MASK \ +0x00000100 /* EN_PAUSE_AC20_QUEUE[8] */ +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC20_QUEUE_SHFT 8 +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC13_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC13_QUEUE_MASK \ +0x00000080 /* EN_PAUSE_AC13_QUEUE[7] */ +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC13_QUEUE_SHFT 7 +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC12_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC12_QUEUE_MASK \ +0x00000040 /* EN_PAUSE_AC12_QUEUE[6] */ +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC12_QUEUE_SHFT 6 +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC11_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC11_QUEUE_MASK \ +0x00000020 /* EN_PAUSE_AC11_QUEUE[5] */ +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC11_QUEUE_SHFT 5 +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC10_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC10_QUEUE_MASK \ +0x00000010 /* EN_PAUSE_AC10_QUEUE[4] */ +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC10_QUEUE_SHFT 4 +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC03_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC03_QUEUE_MASK \ +0x00000008 /* EN_PAUSE_AC03_QUEUE[3] */ +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC03_QUEUE_SHFT 3 +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC02_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC02_QUEUE_MASK \ +0x00000004 /* EN_PAUSE_AC02_QUEUE[2] */ +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC02_QUEUE_SHFT 2 +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC01_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC01_QUEUE_MASK \ +0x00000002 /* EN_PAUSE_AC01_QUEUE[1] */ +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC01_QUEUE_SHFT 1 +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC00_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC00_QUEUE_MASK \ +0x00000001 /* EN_PAUSE_AC00_QUEUE[0] */ +#define WF_PLE_TOP_TXCMD_TXS_BUF_PAUSE_EN_PAUSE_AC00_QUEUE_SHFT 0 + +/* +* ---TXCMD_TXCMD_BUF_PAUSE (0x820C0000 + 0x23c)--- +* EN_PAUSE_AC00_QUEUE[0] - (RW) Pause control of WMM0 AC0 TXCMD queue. +* EN_PAUSE_AC01_QUEUE[1] - (RW) Pause control of WMM0 AC1 TXCMD queue. +* EN_PAUSE_AC02_QUEUE[2] - (RW) Pause control of WMM0 AC2 TXCMD queue. +* EN_PAUSE_AC03_QUEUE[3] - (RW) Pause control of WMM0 AC3 TXCMD queue. +* EN_PAUSE_AC10_QUEUE[4] - (RW) Pause control of WMM1 AC0 TXCMD queue. +* EN_PAUSE_AC11_QUEUE[5] - (RW) Pause control of WMM1 AC1 TXCMD queue. +* EN_PAUSE_AC12_QUEUE[6] - (RW) Pause control of WMM1 AC2 TXCMD queue. +* EN_PAUSE_AC13_QUEUE[7] - (RW) Pause control of WMM1 AC3 TXCMD queue. +* EN_PAUSE_AC20_QUEUE[8] - (RW) Pause control of WMM2 AC0 TXCMD queue. +* EN_PAUSE_AC21_QUEUE[9] - (RW) Pause control of WMM2 AC1 TXCMD queue. +* EN_PAUSE_AC22_QUEUE[10] - (RW) Pause control of WMM2 AC2 TXCMD queue. +* EN_PAUSE_AC23_QUEUE[11] - (RW) Pause control of WMM2 AC3 TXCMD queue. +* EN_PAUSE_AC30_QUEUE[12] - (RW) Pause control of WMM3 AC0 TXCMD queue. +* EN_PAUSE_AC31_QUEUE[13] - (RW) Pause control of WMM3 AC1 TXCMD queue. +* EN_PAUSE_AC32_QUEUE[14] - (RW) Pause control of WMM3 AC2 TXCMD queue. +* EN_PAUSE_AC33_QUEUE[15] - (RW) Pause control of WMM3 AC3 TXCMD queue. +* EN_PAUSE_ALTXCMD_0_QUEUE[16] - (RW) Pause control of ALTXCMD 0 queue. +* EN_PAUSE_TF_0_QUEUE[17] - (RW) Pause control of TF 0 TXCDM queue . +* EN_PAUSE_TWT_TSF_TF_0_QUEUE[18] - (RW) Pause control of TWT TSF TF 0 TXCMD +queue. +* EN_PAUSE_TWT_DL_0_QUEUE[19] - (RW) Pause control of TWT DL 0 TXCMD queue. +* EN_PAUSE_TWT_UL_0_QUEUE[20] - (RW) Pause control of TWT UL 0 TXCMD queue. +* EN_PAUSE_ALTXCMD_1_QUEUE[21] - (RW) Pause control of ALTXCMD 1 queue. +* EN_PAUSE_TF_1_QUEUE[22] - (RW) Pause control of TF 1 TXCDM queue . +* EN_PAUSE_TWT_TSF_TF_1_QUEUE[23] - (RW) Pause control of TWT TSF TF 1 TXCMD +queue. +* EN_PAUSE_TWT_DL_1_QUEUE[24] - (RW) Pause control of TWT DL 1 TXCMD queue. +* EN_PAUSE_TWT_UL_1_QUEUE[25] - (RW) Pause control of TWT UL 1 TXCMD queue. +* RESERVED26[31..26] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_TWT_UL_1_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_TWT_UL_1_QUEUE_MASK \ +0x02000000 /* EN_PAUSE_TWT_UL_1_QUEUE[25] */ +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_TWT_UL_1_QUEUE_SHFT 25 +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_TWT_DL_1_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_TWT_DL_1_QUEUE_MASK \ +0x01000000 /* EN_PAUSE_TWT_DL_1_QUEUE[24] */ +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_TWT_DL_1_QUEUE_SHFT 24 +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_TWT_TSF_TF_1_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_TWT_TSF_TF_1_QUEUE_MASK \ +0x00800000 /* EN_PAUSE_TWT_TSF_TF_1_QUEUE[23] */ +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_TWT_TSF_TF_1_QUEUE_SHFT 23 +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_TF_1_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_TF_1_QUEUE_MASK \ +0x00400000 /* EN_PAUSE_TF_1_QUEUE[22] */ +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_TF_1_QUEUE_SHFT 22 +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_ALTXCMD_1_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_ALTXCMD_1_QUEUE_MASK \ +0x00200000 /* EN_PAUSE_ALTXCMD_1_QUEUE[21] */ +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_ALTXCMD_1_QUEUE_SHFT 21 +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_TWT_UL_0_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_TWT_UL_0_QUEUE_MASK \ +0x00100000 /* EN_PAUSE_TWT_UL_0_QUEUE[20] */ +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_TWT_UL_0_QUEUE_SHFT 20 +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_TWT_DL_0_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_TWT_DL_0_QUEUE_MASK \ +0x00080000 /* EN_PAUSE_TWT_DL_0_QUEUE[19] */ +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_TWT_DL_0_QUEUE_SHFT 19 +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_TWT_TSF_TF_0_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_TWT_TSF_TF_0_QUEUE_MASK \ +0x00040000 /* EN_PAUSE_TWT_TSF_TF_0_QUEUE[18] */ +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_TWT_TSF_TF_0_QUEUE_SHFT 18 +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_TF_0_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_TF_0_QUEUE_MASK \ +0x00020000 /* EN_PAUSE_TF_0_QUEUE[17] */ +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_TF_0_QUEUE_SHFT 17 +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_ALTXCMD_0_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_ALTXCMD_0_QUEUE_MASK \ +0x00010000 /* EN_PAUSE_ALTXCMD_0_QUEUE[16] */ +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_ALTXCMD_0_QUEUE_SHFT 16 +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC33_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC33_QUEUE_MASK \ +0x00008000 /* EN_PAUSE_AC33_QUEUE[15] */ +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC33_QUEUE_SHFT 15 +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC32_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC32_QUEUE_MASK \ +0x00004000 /* EN_PAUSE_AC32_QUEUE[14] */ +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC32_QUEUE_SHFT 14 +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC31_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC31_QUEUE_MASK \ +0x00002000 /* EN_PAUSE_AC31_QUEUE[13] */ +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC31_QUEUE_SHFT 13 +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC30_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC30_QUEUE_MASK \ +0x00001000 /* EN_PAUSE_AC30_QUEUE[12] */ +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC30_QUEUE_SHFT 12 +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC23_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC23_QUEUE_MASK \ +0x00000800 /* EN_PAUSE_AC23_QUEUE[11] */ +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC23_QUEUE_SHFT 11 +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC22_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC22_QUEUE_MASK \ +0x00000400 /* EN_PAUSE_AC22_QUEUE[10] */ +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC22_QUEUE_SHFT 10 +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC21_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC21_QUEUE_MASK \ +0x00000200 /* EN_PAUSE_AC21_QUEUE[9] */ +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC21_QUEUE_SHFT 9 +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC20_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC20_QUEUE_MASK \ +0x00000100 /* EN_PAUSE_AC20_QUEUE[8] */ +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC20_QUEUE_SHFT 8 +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC13_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC13_QUEUE_MASK \ +0x00000080 /* EN_PAUSE_AC13_QUEUE[7] */ +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC13_QUEUE_SHFT 7 +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC12_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC12_QUEUE_MASK \ +0x00000040 /* EN_PAUSE_AC12_QUEUE[6] */ +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC12_QUEUE_SHFT 6 +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC11_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC11_QUEUE_MASK \ +0x00000020 /* EN_PAUSE_AC11_QUEUE[5] */ +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC11_QUEUE_SHFT 5 +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC10_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC10_QUEUE_MASK \ +0x00000010 /* EN_PAUSE_AC10_QUEUE[4] */ +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC10_QUEUE_SHFT 4 +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC03_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC03_QUEUE_MASK \ +0x00000008 /* EN_PAUSE_AC03_QUEUE[3] */ +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC03_QUEUE_SHFT 3 +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC02_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC02_QUEUE_MASK \ +0x00000004 /* EN_PAUSE_AC02_QUEUE[2] */ +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC02_QUEUE_SHFT 2 +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC01_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC01_QUEUE_MASK \ +0x00000002 /* EN_PAUSE_AC01_QUEUE[1] */ +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC01_QUEUE_SHFT 1 +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC00_QUEUE_ADDR \ +WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC00_QUEUE_MASK \ +0x00000001 /* EN_PAUSE_AC00_QUEUE[0] */ +#define WF_PLE_TOP_TXCMD_TXCMD_BUF_PAUSE_EN_PAUSE_AC00_QUEUE_SHFT 0 + +/* +* ---UMAC_DBG_CTRL (0x820C0000 + 0x240)--- +* UMAC_DBG_FUNC_SEL[3..0] - (RW) Selects UMAC debug mode +* RESERVED4[7..4] - (RO) Reserved bits +* PLE_DBG_FLAG_A_NIB_EN[11..8] - (RW) Enable control of PLE debug flag A +nibble +* PLE_DBG_FLAG_B_NIB_EN[15..12] - (RW) Enable control of PLE debug flag B +nibble +* PSE_DBG_FLAG_A_NIB_EN[19..16] - (RW) Enable control of PSE debug flag A +nibble +* PSE_DBG_FLAG_B_NIB_EN[23..20] - (RW) Enable control of PSE debug flag B +nibble +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_UMAC_DBG_CTRL_PSE_DBG_FLAG_B_NIB_EN_ADDR \ +WF_PLE_TOP_UMAC_DBG_CTRL_ADDR +#define WF_PLE_TOP_UMAC_DBG_CTRL_PSE_DBG_FLAG_B_NIB_EN_MASK \ +0x00F00000 /* PSE_DBG_FLAG_B_NIB_EN[23..20] */ +#define WF_PLE_TOP_UMAC_DBG_CTRL_PSE_DBG_FLAG_B_NIB_EN_SHFT 20 +#define WF_PLE_TOP_UMAC_DBG_CTRL_PSE_DBG_FLAG_A_NIB_EN_ADDR \ +WF_PLE_TOP_UMAC_DBG_CTRL_ADDR +#define WF_PLE_TOP_UMAC_DBG_CTRL_PSE_DBG_FLAG_A_NIB_EN_MASK \ +0x000F0000 /* PSE_DBG_FLAG_A_NIB_EN[19..16] */ +#define WF_PLE_TOP_UMAC_DBG_CTRL_PSE_DBG_FLAG_A_NIB_EN_SHFT 16 +#define WF_PLE_TOP_UMAC_DBG_CTRL_PLE_DBG_FLAG_B_NIB_EN_ADDR \ +WF_PLE_TOP_UMAC_DBG_CTRL_ADDR +#define WF_PLE_TOP_UMAC_DBG_CTRL_PLE_DBG_FLAG_B_NIB_EN_MASK \ +0x0000F000 /* PLE_DBG_FLAG_B_NIB_EN[15..12] */ +#define WF_PLE_TOP_UMAC_DBG_CTRL_PLE_DBG_FLAG_B_NIB_EN_SHFT 12 +#define WF_PLE_TOP_UMAC_DBG_CTRL_PLE_DBG_FLAG_A_NIB_EN_ADDR \ +WF_PLE_TOP_UMAC_DBG_CTRL_ADDR +#define WF_PLE_TOP_UMAC_DBG_CTRL_PLE_DBG_FLAG_A_NIB_EN_MASK \ +0x00000F00 /* PLE_DBG_FLAG_A_NIB_EN[11..8] */ +#define WF_PLE_TOP_UMAC_DBG_CTRL_PLE_DBG_FLAG_A_NIB_EN_SHFT 8 +#define WF_PLE_TOP_UMAC_DBG_CTRL_UMAC_DBG_FUNC_SEL_ADDR \ +WF_PLE_TOP_UMAC_DBG_CTRL_ADDR +#define WF_PLE_TOP_UMAC_DBG_CTRL_UMAC_DBG_FUNC_SEL_MASK \ +0x0000000F /* UMAC_DBG_FUNC_SEL[3..0] */ +#define WF_PLE_TOP_UMAC_DBG_CTRL_UMAC_DBG_FUNC_SEL_SHFT 0 + +/* +* ---PLE_DBG_A_BYTE_SEL (0x820C0000 + 0x244)--- +* PLE_DBG_FLAG_A_BYTE0_SEL[7..0] - (RW) Debug flag selection of PLE debug A +* byte 0 +* PLE_DBG_FLAG_A_BYTE1_SEL[15..8] - (RW) Debug flag selection of PLE debug A +* byte 1 +* PLE_DBG_FLAG_A_BYTE2_SEL[23..16] - (RW) Debug flag selection of PLE debug A +* byte 2 +* PLE_DBG_FLAG_A_BYTE3_SEL[31..24] - (RW) Debug flag selection of PLE debug A +* byte 3 +*/ +#define WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_PLE_DBG_FLAG_A_BYTE3_SEL_ADDR \ +WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_ADDR +#define WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_PLE_DBG_FLAG_A_BYTE3_SEL_MASK \ +0xFF000000 /* PLE_DBG_FLAG_A_BYTE3_SEL[31..24] */ +#define WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_PLE_DBG_FLAG_A_BYTE3_SEL_SHFT 24 +#define WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_PLE_DBG_FLAG_A_BYTE2_SEL_ADDR \ +WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_ADDR +#define WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_PLE_DBG_FLAG_A_BYTE2_SEL_MASK \ +0x00FF0000 /* PLE_DBG_FLAG_A_BYTE2_SEL[23..16] */ +#define WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_PLE_DBG_FLAG_A_BYTE2_SEL_SHFT 16 +#define WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_PLE_DBG_FLAG_A_BYTE1_SEL_ADDR \ +WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_ADDR +#define WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_PLE_DBG_FLAG_A_BYTE1_SEL_MASK \ +0x0000FF00 /* PLE_DBG_FLAG_A_BYTE1_SEL[15..8] */ +#define WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_PLE_DBG_FLAG_A_BYTE1_SEL_SHFT 8 +#define WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_PLE_DBG_FLAG_A_BYTE0_SEL_ADDR \ +WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_ADDR +#define WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_PLE_DBG_FLAG_A_BYTE0_SEL_MASK \ +0x000000FF /* PLE_DBG_FLAG_A_BYTE0_SEL[7..0] */ +#define WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_PLE_DBG_FLAG_A_BYTE0_SEL_SHFT 0 + +/* +* ---PLE_DBG_B_BYTE_SEL (0x820C0000 + 0x248)--- +* PLE_DBG_FLAG_B_BYTE0_SEL[7..0] - (RW) Debug flag selection of PLE debug B +* byte 0 +* PLE_DBG_FLAG_B_BYTE1_SEL[15..8] - (RW) Debug flag selection of PLE debug B +* byte 1 +* PLE_DBG_FLAG_B_BYTE2_SEL[23..16] - (RW) Debug flag selection of PLE debug B +* byte 2 +* PLE_DBG_FLAG_B_BYTE3_SEL[31..24] - (RW) Debug flag selection of PLE debug B +* byte 3 +*/ +#define WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_PLE_DBG_FLAG_B_BYTE3_SEL_ADDR \ +WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_ADDR +#define WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_PLE_DBG_FLAG_B_BYTE3_SEL_MASK \ +0xFF000000 /* PLE_DBG_FLAG_B_BYTE3_SEL[31..24] */ +#define WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_PLE_DBG_FLAG_B_BYTE3_SEL_SHFT 24 +#define WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_PLE_DBG_FLAG_B_BYTE2_SEL_ADDR \ +WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_ADDR +#define WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_PLE_DBG_FLAG_B_BYTE2_SEL_MASK \ +0x00FF0000 /* PLE_DBG_FLAG_B_BYTE2_SEL[23..16] */ +#define WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_PLE_DBG_FLAG_B_BYTE2_SEL_SHFT 16 +#define WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_PLE_DBG_FLAG_B_BYTE1_SEL_ADDR \ +WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_ADDR +#define WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_PLE_DBG_FLAG_B_BYTE1_SEL_MASK \ +0x0000FF00 /* PLE_DBG_FLAG_B_BYTE1_SEL[15..8] */ +#define WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_PLE_DBG_FLAG_B_BYTE1_SEL_SHFT 8 +#define WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_PLE_DBG_FLAG_B_BYTE0_SEL_ADDR \ +WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_ADDR +#define WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_PLE_DBG_FLAG_B_BYTE0_SEL_MASK \ +0x000000FF /* PLE_DBG_FLAG_B_BYTE0_SEL[7..0] */ +#define WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_PLE_DBG_FLAG_B_BYTE0_SEL_SHFT 0 + +/* +* ---FSM_IDLE_WD_CTRL (0x820C0000 + 0x24C)--- +* FL_IDLE_WD_TO_TH[7..0] - (RW) Watchdog timeout threshold for frame +* link FSM not returning to IDLE +* PL_IDLE_WD_TO_TH[15..8] - (RW) Watchdog timeout threshold for page link +* FSM not returning to IDLE +* PORT_IDLE_WD_TO_TH[23..16] - (RW) Watchdog timeout threshold for port oper +* FSM not returning to IDLE +* (Including HIF/CPU/LMAC port) +* MACTX_IDLE_WD_TO_TH[31..24] - (RW) Watchdog timeout threshold for MACTX FSM +* not returning to IDLE +*/ +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_MACTX_IDLE_WD_TO_TH_ADDR \ +WF_PLE_TOP_FSM_IDLE_WD_CTRL_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_MACTX_IDLE_WD_TO_TH_MASK \ +0xFF000000 /* MACTX_IDLE_WD_TO_TH[31..24] */ +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_MACTX_IDLE_WD_TO_TH_SHFT 24 +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_PORT_IDLE_WD_TO_TH_ADDR \ +WF_PLE_TOP_FSM_IDLE_WD_CTRL_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_PORT_IDLE_WD_TO_TH_MASK \ +0x00FF0000 /* PORT_IDLE_WD_TO_TH[23..16] */ +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_PORT_IDLE_WD_TO_TH_SHFT 16 +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_PL_IDLE_WD_TO_TH_ADDR \ +WF_PLE_TOP_FSM_IDLE_WD_CTRL_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_PL_IDLE_WD_TO_TH_MASK \ +0x0000FF00 /* PL_IDLE_WD_TO_TH[15..8] */ +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_PL_IDLE_WD_TO_TH_SHFT 8 +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_FL_IDLE_WD_TO_TH_ADDR \ +WF_PLE_TOP_FSM_IDLE_WD_CTRL_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_FL_IDLE_WD_TO_TH_MASK \ +0x000000FF /* FL_IDLE_WD_TO_TH[7..0] */ +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_FL_IDLE_WD_TO_TH_SHFT 0 + +/* +* ---FSM_IDLE_WD_EN (0x820C0000 + 0x250)--- +* EN_FL_IDLE_WD_TO[0] - (RW) Enables watchdog for frame link FSM not +* returning to IDLE +* EN_PL_IDLE_WD_TO[1] - (RW) Enables watchdog for page link FSM not +* returning to IDLE +* EN_CPU_PORT_IDLE_WD_TO[2] - (RW) Enables watchdog for CPU port oper FSM +* not returning to IDLE +* EN_HIF_PORT_IDLE_WD_TO[3] - (RW) Enables watchdog for HIF port oper FSM +* not returning to IDLE +* EN_LMAC_PORT_IDLE_WD_TO[4] - (RW) Enables watchdog for LMAC port oper FSM +* not returning to IDLE +* EN_AMSDU_PORT_IDLE_WD_TO[5] - (RW) Enables watchdog for AMSDU port FSM not +* returning to IDLE +* EN_HW_AMSDU_IDLE_WD_TO[6] - (RW) Enables watchdog for HW AMSDU FSM not +* returning to IDLE +* RESERVED7[7] - (RO) Reserved bits +* EN_MACTX0_IDLE_WD_TO[8] - (RW) Enables watchdog for MACTX 0 FSM not +* returning to IDLE +* EN_MACTX2_IDLE_WD_TO[9] - (RW) Enables watchdog for MACTX 1 FSM not +* returning to IDLE +* EN_MACTX1_IDLE_WD_TO[10] - (RW) Enables watchdog for MACTX 2 FSM not +* returning to IDLE +* EN_MACTX3_IDLE_WD_TO[11] - (RW) Enables watchdog for MACTX 3 FSM not +* returning to IDLE +* EN_MDP_IDLE_WD_TO[12] - (RW) Enables watchdog for MDP port oper FSM +* not returning to IDLE +* EN_PREDL_ARB_IDLE_WD_TO[13] - (RW) Enables watchdog for Predl arbitrator +* FSM not returning to IDLE +* EN_PREDL_TXCMD_IDLE_WD_TO[14] - (RW) Enables watchdog for Predl TXCMD parser +* FSM not returning to IDLE +* RESERVED15[31..15] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_PREDL_TXCMD_IDLE_WD_TO_ADDR \ +WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_PREDL_TXCMD_IDLE_WD_TO_MASK \ +0x00004000 /* EN_PREDL_TXCMD_IDLE_WD_TO[14] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_PREDL_TXCMD_IDLE_WD_TO_SHFT 14 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_PREDL_ARB_IDLE_WD_TO_ADDR \ +WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_PREDL_ARB_IDLE_WD_TO_MASK \ +0x00002000 /* EN_PREDL_ARB_IDLE_WD_TO[13] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_PREDL_ARB_IDLE_WD_TO_SHFT 13 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MDP_IDLE_WD_TO_ADDR \ +WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MDP_IDLE_WD_TO_MASK \ +0x00001000 /* EN_MDP_IDLE_WD_TO[12] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MDP_IDLE_WD_TO_SHFT 12 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MACTX3_IDLE_WD_TO_ADDR \ +WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MACTX3_IDLE_WD_TO_MASK \ +0x00000800 /* EN_MACTX3_IDLE_WD_TO[11] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MACTX3_IDLE_WD_TO_SHFT 11 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MACTX1_IDLE_WD_TO_ADDR \ +WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MACTX1_IDLE_WD_TO_MASK \ +0x00000400 /* EN_MACTX1_IDLE_WD_TO[10] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MACTX1_IDLE_WD_TO_SHFT 10 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MACTX2_IDLE_WD_TO_ADDR \ +WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MACTX2_IDLE_WD_TO_MASK \ +0x00000200 /* EN_MACTX2_IDLE_WD_TO[9] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MACTX2_IDLE_WD_TO_SHFT 9 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MACTX0_IDLE_WD_TO_ADDR \ +WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MACTX0_IDLE_WD_TO_MASK \ +0x00000100 /* EN_MACTX0_IDLE_WD_TO[8] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MACTX0_IDLE_WD_TO_SHFT 8 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_HW_AMSDU_IDLE_WD_TO_ADDR \ +WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_HW_AMSDU_IDLE_WD_TO_MASK \ +0x00000040 /* EN_HW_AMSDU_IDLE_WD_TO[6] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_HW_AMSDU_IDLE_WD_TO_SHFT 6 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_AMSDU_PORT_IDLE_WD_TO_ADDR \ +WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_AMSDU_PORT_IDLE_WD_TO_MASK \ +0x00000020 /* EN_AMSDU_PORT_IDLE_WD_TO[5] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_AMSDU_PORT_IDLE_WD_TO_SHFT 5 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_LMAC_PORT_IDLE_WD_TO_ADDR \ +WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_LMAC_PORT_IDLE_WD_TO_MASK \ +0x00000010 /* EN_LMAC_PORT_IDLE_WD_TO[4] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_LMAC_PORT_IDLE_WD_TO_SHFT 4 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_HIF_PORT_IDLE_WD_TO_ADDR \ +WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_HIF_PORT_IDLE_WD_TO_MASK \ +0x00000008 /* EN_HIF_PORT_IDLE_WD_TO[3] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_HIF_PORT_IDLE_WD_TO_SHFT 3 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_CPU_PORT_IDLE_WD_TO_ADDR \ +WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_CPU_PORT_IDLE_WD_TO_MASK \ +0x00000004 /* EN_CPU_PORT_IDLE_WD_TO[2] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_CPU_PORT_IDLE_WD_TO_SHFT 2 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_PL_IDLE_WD_TO_ADDR \ +WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_PL_IDLE_WD_TO_MASK \ +0x00000002 /* EN_PL_IDLE_WD_TO[1] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_PL_IDLE_WD_TO_SHFT 1 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_FL_IDLE_WD_TO_ADDR \ +WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_FL_IDLE_WD_TO_MASK \ +0x00000001 /* EN_FL_IDLE_WD_TO[0] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_FL_IDLE_WD_TO_SHFT 0 + +/* +* ---FSM_IDLE_WD_CTRL_1 (0x820C0000 + 0x258)--- +* MDP_IDLE_WD_TO_TH[7..0] - (RW) Watchdog timeout threshold for MDP FSM +* not returning to IDLE +* (Including MDP TDP/RDP/TIOC/RIOC) +* PF_IDLE_WD_TO_TH[15..8] - (RW) Watchdog timeout threshold for PF FSM +* not returning to IDLE +* SEC_IDLE_WD_TO_TH[23..16] - (RW) Watchdog timeout threshold for SEC FSM +* not returning to IDLE +* (Including SEC0/SEC1) +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_1_SEC_IDLE_WD_TO_TH_ADDR \ +WF_PLE_TOP_FSM_IDLE_WD_CTRL_1_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_1_SEC_IDLE_WD_TO_TH_MASK \ +0x00FF0000 /* SEC_IDLE_WD_TO_TH[23..16] */ +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_1_SEC_IDLE_WD_TO_TH_SHFT 16 +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_1_PF_IDLE_WD_TO_TH_ADDR \ +WF_PLE_TOP_FSM_IDLE_WD_CTRL_1_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_1_PF_IDLE_WD_TO_TH_MASK \ +0x0000FF00 /* PF_IDLE_WD_TO_TH[15..8] */ +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_1_PF_IDLE_WD_TO_TH_SHFT 8 +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_1_MDP_IDLE_WD_TO_TH_ADDR \ +WF_PLE_TOP_FSM_IDLE_WD_CTRL_1_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_1_MDP_IDLE_WD_TO_TH_MASK \ +0x000000FF /* MDP_IDLE_WD_TO_TH[7..0] */ +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_1_MDP_IDLE_WD_TO_TH_SHFT 0 + +/* +* ---FSM_IDLE_WD_EN_1 (0x820C0000 + 0x25C)--- +* EN_BN0_MDP_TDP_IDLE_WD_TO[0] - (RW) Enables watchdog for Band0 MDP TDP FSM +* not returning to IDLE +* EN_MDP_RDP_IDLE_WD_TO[1] - (RW) Enables watchdog for MDP RDP FSM not +* returning to IDLE +* EN_BN0_MDP_TIOC_IDLE_WD_TO[2] - (RW) Enables watchdog for Band0 MDP TIOC FSM +* not returning to IDLE +* EN_BN0_MDP_RIOC_IDLE_WD_TO[3] - (RW) Enables watchdog for Band0 MDP RIOC FSM +* not returning to IDLE +* EN_PF_IDLE_WD_TO[4] - (RW) Enables watchdog for PF FSM not +* returning to IDLE +* EN_SEC0_IDLE_WD_TO[5] - (RW) Enables watchdog for SEC0 FSM not +* returning to IDLE +* EN_SEC1_IDLE_WD_TO[6] - (RW) Enables watchdog for SEC1 FSM not +* returning to IDLE +* EN_BN1_MDP_TDP_IDLE_WD_TO[7] - (RW) Enables watchdog for Band1 MDP TDP FSM +* not returning to IDLE +* EN_BN1_MDP_TIOC_IDLE_WD_TO[8] - (RW) Enables watchdog for Band1 MDP TIOC FSM +* not returning to IDLE +* EN_BN1_MDP_RIOC_IDLE_WD_TO[9] - (RW) Enables watchdog for Band1 MDP RIOC FSM +* not returning to IDLE +* RESERVED10[31..10] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN1_MDP_RIOC_IDLE_WD_TO_ADDR \ +WF_PLE_TOP_FSM_IDLE_WD_EN_1_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN1_MDP_RIOC_IDLE_WD_TO_MASK \ +0x00000200 /* EN_BN1_MDP_RIOC_IDLE_WD_TO[9] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN1_MDP_RIOC_IDLE_WD_TO_SHFT 9 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN1_MDP_TIOC_IDLE_WD_TO_ADDR \ +WF_PLE_TOP_FSM_IDLE_WD_EN_1_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN1_MDP_TIOC_IDLE_WD_TO_MASK \ +0x00000100 /* EN_BN1_MDP_TIOC_IDLE_WD_TO[8] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN1_MDP_TIOC_IDLE_WD_TO_SHFT 8 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN1_MDP_TDP_IDLE_WD_TO_ADDR \ +WF_PLE_TOP_FSM_IDLE_WD_EN_1_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN1_MDP_TDP_IDLE_WD_TO_MASK \ +0x00000080 /* EN_BN1_MDP_TDP_IDLE_WD_TO[7] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN1_MDP_TDP_IDLE_WD_TO_SHFT 7 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_SEC1_IDLE_WD_TO_ADDR \ +WF_PLE_TOP_FSM_IDLE_WD_EN_1_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_SEC1_IDLE_WD_TO_MASK \ +0x00000040 /* EN_SEC1_IDLE_WD_TO[6] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_SEC1_IDLE_WD_TO_SHFT 6 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_SEC0_IDLE_WD_TO_ADDR \ +WF_PLE_TOP_FSM_IDLE_WD_EN_1_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_SEC0_IDLE_WD_TO_MASK \ +0x00000020 /* EN_SEC0_IDLE_WD_TO[5] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_SEC0_IDLE_WD_TO_SHFT 5 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_PF_IDLE_WD_TO_ADDR \ +WF_PLE_TOP_FSM_IDLE_WD_EN_1_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_PF_IDLE_WD_TO_MASK \ +0x00000010 /* EN_PF_IDLE_WD_TO[4] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_PF_IDLE_WD_TO_SHFT 4 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN0_MDP_RIOC_IDLE_WD_TO_ADDR \ +WF_PLE_TOP_FSM_IDLE_WD_EN_1_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN0_MDP_RIOC_IDLE_WD_TO_MASK \ +0x00000008 /* EN_BN0_MDP_RIOC_IDLE_WD_TO[3] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN0_MDP_RIOC_IDLE_WD_TO_SHFT 3 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN0_MDP_TIOC_IDLE_WD_TO_ADDR \ +WF_PLE_TOP_FSM_IDLE_WD_EN_1_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN0_MDP_TIOC_IDLE_WD_TO_MASK \ +0x00000004 /* EN_BN0_MDP_TIOC_IDLE_WD_TO[2] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN0_MDP_TIOC_IDLE_WD_TO_SHFT 2 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_MDP_RDP_IDLE_WD_TO_ADDR \ +WF_PLE_TOP_FSM_IDLE_WD_EN_1_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_MDP_RDP_IDLE_WD_TO_MASK \ +0x00000002 /* EN_MDP_RDP_IDLE_WD_TO[1] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_MDP_RDP_IDLE_WD_TO_SHFT 1 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN0_MDP_TDP_IDLE_WD_TO_ADDR \ +WF_PLE_TOP_FSM_IDLE_WD_EN_1_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN0_MDP_TDP_IDLE_WD_TO_MASK \ +0x00000001 /* EN_BN0_MDP_TDP_IDLE_WD_TO[0] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN0_MDP_TDP_IDLE_WD_TO_SHFT 0 + +/* +* ---SRAM_MBIST_DELSEL9 (0x820C0000 + 0x260)--- +* SRAM9_MBIST_DELSEL[31..0] - (RW) MBIST delsel setting of SRAM9 +*/ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL9_SRAM9_MBIST_DELSEL_ADDR \ +WF_PLE_TOP_SRAM_MBIST_DELSEL9_ADDR +#define WF_PLE_TOP_SRAM_MBIST_DELSEL9_SRAM9_MBIST_DELSEL_MASK \ +0xFFFFFFFF /* SRAM9_MBIST_DELSEL[31..0] */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL9_SRAM9_MBIST_DELSEL_SHFT 0 + +/* +* ---SRAM_MBIST_DELSEL10 (0x820C0000 + 0x264)--- +* SRAM10_MBIST_DELSEL[31..0] - (RW) MBIST delsel setting of SRAM10 +*/ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL10_SRAM10_MBIST_DELSEL_ADDR \ +WF_PLE_TOP_SRAM_MBIST_DELSEL10_ADDR +#define WF_PLE_TOP_SRAM_MBIST_DELSEL10_SRAM10_MBIST_DELSEL_MASK \ +0xFFFFFFFF /* SRAM10_MBIST_DELSEL[31..0] */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL10_SRAM10_MBIST_DELSEL_SHFT 0 + +/* +* ---FUNC_ACT_CNT_0 (0x820C0000 + 0x280)--- +* RESERVED0[15..0] - (RO) Reserved bits +* SPL_GEN_NUM[31..16] - (RO) Counter of SPL report generation. +*/ +#define WF_PLE_TOP_FUNC_ACT_CNT_0_SPL_GEN_NUM_ADDR \ +WF_PLE_TOP_FUNC_ACT_CNT_0_ADDR +#define WF_PLE_TOP_FUNC_ACT_CNT_0_SPL_GEN_NUM_MASK \ +0xFFFF0000 /* SPL_GEN_NUM[31..16] */ +#define WF_PLE_TOP_FUNC_ACT_CNT_0_SPL_GEN_NUM_SHFT 16 + +/* +* ---FUNC_ACT_CNT_1 (0x820C0000 + 0x284)--- +* MACTX0_ACT_CNT[3..0] - (RO) Counter of MACTX0 TX active. +* MACTX0_NOR_END_CNT[7..4] - (RO) Counter of MACTX0 TX normal end. +* MACTX0_ABORT_CNT[11..8] - (RO) Counter of MACTX0 TX abort. +* RESERVED12[15..12] - (RO) Reserved bits +* TXCMD0_ADD_FID_CNT[19..16] - (RO) Counter of TXCMD0 TX add FID. +* TXCMD0_NOR_END_CNT[23..20] - (RO) Counter of TXCMD0 TX normal end. +* TXCMD0_ABORT_CNT[27..24] - (RO) Counter of TXCMD0 TX abort. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_FUNC_ACT_CNT_1_TXCMD0_ABORT_CNT_ADDR \ +WF_PLE_TOP_FUNC_ACT_CNT_1_ADDR +#define WF_PLE_TOP_FUNC_ACT_CNT_1_TXCMD0_ABORT_CNT_MASK \ +0x0F000000 /* TXCMD0_ABORT_CNT[27..24] */ +#define WF_PLE_TOP_FUNC_ACT_CNT_1_TXCMD0_ABORT_CNT_SHFT 24 +#define WF_PLE_TOP_FUNC_ACT_CNT_1_TXCMD0_NOR_END_CNT_ADDR \ +WF_PLE_TOP_FUNC_ACT_CNT_1_ADDR +#define WF_PLE_TOP_FUNC_ACT_CNT_1_TXCMD0_NOR_END_CNT_MASK \ +0x00F00000 /* TXCMD0_NOR_END_CNT[23..20] */ +#define WF_PLE_TOP_FUNC_ACT_CNT_1_TXCMD0_NOR_END_CNT_SHFT 20 +#define WF_PLE_TOP_FUNC_ACT_CNT_1_TXCMD0_ADD_FID_CNT_ADDR \ +WF_PLE_TOP_FUNC_ACT_CNT_1_ADDR +#define WF_PLE_TOP_FUNC_ACT_CNT_1_TXCMD0_ADD_FID_CNT_MASK \ +0x000F0000 /* TXCMD0_ADD_FID_CNT[19..16] */ +#define WF_PLE_TOP_FUNC_ACT_CNT_1_TXCMD0_ADD_FID_CNT_SHFT 16 +#define WF_PLE_TOP_FUNC_ACT_CNT_1_MACTX0_ABORT_CNT_ADDR \ +WF_PLE_TOP_FUNC_ACT_CNT_1_ADDR +#define WF_PLE_TOP_FUNC_ACT_CNT_1_MACTX0_ABORT_CNT_MASK \ +0x00000F00 /* MACTX0_ABORT_CNT[11..8] */ +#define WF_PLE_TOP_FUNC_ACT_CNT_1_MACTX0_ABORT_CNT_SHFT 8 +#define WF_PLE_TOP_FUNC_ACT_CNT_1_MACTX0_NOR_END_CNT_ADDR \ +WF_PLE_TOP_FUNC_ACT_CNT_1_ADDR +#define WF_PLE_TOP_FUNC_ACT_CNT_1_MACTX0_NOR_END_CNT_MASK \ +0x000000F0 /* MACTX0_NOR_END_CNT[7..4] */ +#define WF_PLE_TOP_FUNC_ACT_CNT_1_MACTX0_NOR_END_CNT_SHFT 4 +#define WF_PLE_TOP_FUNC_ACT_CNT_1_MACTX0_ACT_CNT_ADDR \ +WF_PLE_TOP_FUNC_ACT_CNT_1_ADDR +#define WF_PLE_TOP_FUNC_ACT_CNT_1_MACTX0_ACT_CNT_MASK \ +0x0000000F /* MACTX0_ACT_CNT[3..0] */ +#define WF_PLE_TOP_FUNC_ACT_CNT_1_MACTX0_ACT_CNT_SHFT 0 + +/* +* ---PORT_SER_CTRL (0x820C0000 + 0x2A0)--- +* EN_HIF_PORT_ALLOC_BLOCKING[0] - (RW) Enable HIF/AMSDU port allocate +* operation blocking. +* EN_CPU_PORT_ALLOC_BLOCKING[1] - (RW) Enable CPU port allocate operation +blocking. +* EN_WF_PORT_ALLOC_BLOCKING[2] - (RW) Enable LMAC port allocate operation +blocking. +* RESERVED3[7..3] - (RO) Reserved bits +* EN_HIF_PORT_D_OPR_BLOCKING[8] - (RW) Enable HIF/AMSDU/MDP/PREDL port data +* operation blocking. +* EN_CPU_PORT_D_OPR_BLOCKING[9] - (RW) Enable CPU port data operation +blocking. +* EN_WF_PORT_D_OPR_BLOCKING[10] - (RW) Enable LMAC port data operation +blocking. +* RESERVED11[15..11] - (RO) Reserved bits +* EN_HIF_PORT_Q_OPR_BLOCKING[16] - (RW) Enable HIF/AMSDU port queue operation +blocking. +* EN_CPU_PORT_Q_OPR_BLOCKING[17] - (RW) Enable CPU port queue operation +blocking. +* EN_WF_PORT_Q_OPR_BLOCKING[18] - (RW) Enable LMAC port queue operation +blocking. +* RESERVED19[31..19] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_PORT_SER_CTRL_EN_WF_PORT_Q_OPR_BLOCKING_ADDR \ +WF_PLE_TOP_PORT_SER_CTRL_ADDR +#define WF_PLE_TOP_PORT_SER_CTRL_EN_WF_PORT_Q_OPR_BLOCKING_MASK \ +0x00040000 /* EN_WF_PORT_Q_OPR_BLOCKING[18] */ +#define WF_PLE_TOP_PORT_SER_CTRL_EN_WF_PORT_Q_OPR_BLOCKING_SHFT 18 +#define WF_PLE_TOP_PORT_SER_CTRL_EN_CPU_PORT_Q_OPR_BLOCKING_ADDR \ +WF_PLE_TOP_PORT_SER_CTRL_ADDR +#define WF_PLE_TOP_PORT_SER_CTRL_EN_CPU_PORT_Q_OPR_BLOCKING_MASK \ +0x00020000 /* EN_CPU_PORT_Q_OPR_BLOCKING[17] */ +#define WF_PLE_TOP_PORT_SER_CTRL_EN_CPU_PORT_Q_OPR_BLOCKING_SHFT 17 +#define WF_PLE_TOP_PORT_SER_CTRL_EN_HIF_PORT_Q_OPR_BLOCKING_ADDR \ +WF_PLE_TOP_PORT_SER_CTRL_ADDR +#define WF_PLE_TOP_PORT_SER_CTRL_EN_HIF_PORT_Q_OPR_BLOCKING_MASK \ +0x00010000 /* EN_HIF_PORT_Q_OPR_BLOCKING[16] */ +#define WF_PLE_TOP_PORT_SER_CTRL_EN_HIF_PORT_Q_OPR_BLOCKING_SHFT 16 +#define WF_PLE_TOP_PORT_SER_CTRL_EN_WF_PORT_D_OPR_BLOCKING_ADDR \ +WF_PLE_TOP_PORT_SER_CTRL_ADDR +#define WF_PLE_TOP_PORT_SER_CTRL_EN_WF_PORT_D_OPR_BLOCKING_MASK \ +0x00000400 /* EN_WF_PORT_D_OPR_BLOCKING[10] */ +#define WF_PLE_TOP_PORT_SER_CTRL_EN_WF_PORT_D_OPR_BLOCKING_SHFT 10 +#define WF_PLE_TOP_PORT_SER_CTRL_EN_CPU_PORT_D_OPR_BLOCKING_ADDR \ +WF_PLE_TOP_PORT_SER_CTRL_ADDR +#define WF_PLE_TOP_PORT_SER_CTRL_EN_CPU_PORT_D_OPR_BLOCKING_MASK \ +0x00000200 /* EN_CPU_PORT_D_OPR_BLOCKING[9] */ +#define WF_PLE_TOP_PORT_SER_CTRL_EN_CPU_PORT_D_OPR_BLOCKING_SHFT 9 +#define WF_PLE_TOP_PORT_SER_CTRL_EN_HIF_PORT_D_OPR_BLOCKING_ADDR \ +WF_PLE_TOP_PORT_SER_CTRL_ADDR +#define WF_PLE_TOP_PORT_SER_CTRL_EN_HIF_PORT_D_OPR_BLOCKING_MASK \ +0x00000100 /* EN_HIF_PORT_D_OPR_BLOCKING[8] */ +#define WF_PLE_TOP_PORT_SER_CTRL_EN_HIF_PORT_D_OPR_BLOCKING_SHFT 8 +#define WF_PLE_TOP_PORT_SER_CTRL_EN_WF_PORT_ALLOC_BLOCKING_ADDR \ +WF_PLE_TOP_PORT_SER_CTRL_ADDR +#define WF_PLE_TOP_PORT_SER_CTRL_EN_WF_PORT_ALLOC_BLOCKING_MASK \ +0x00000004 /* EN_WF_PORT_ALLOC_BLOCKING[2] */ +#define WF_PLE_TOP_PORT_SER_CTRL_EN_WF_PORT_ALLOC_BLOCKING_SHFT 2 +#define WF_PLE_TOP_PORT_SER_CTRL_EN_CPU_PORT_ALLOC_BLOCKING_ADDR \ +WF_PLE_TOP_PORT_SER_CTRL_ADDR +#define WF_PLE_TOP_PORT_SER_CTRL_EN_CPU_PORT_ALLOC_BLOCKING_MASK \ +0x00000002 /* EN_CPU_PORT_ALLOC_BLOCKING[1] */ +#define WF_PLE_TOP_PORT_SER_CTRL_EN_CPU_PORT_ALLOC_BLOCKING_SHFT 1 +#define WF_PLE_TOP_PORT_SER_CTRL_EN_HIF_PORT_ALLOC_BLOCKING_ADDR \ +WF_PLE_TOP_PORT_SER_CTRL_ADDR +#define WF_PLE_TOP_PORT_SER_CTRL_EN_HIF_PORT_ALLOC_BLOCKING_MASK \ +0x00000001 /* EN_HIF_PORT_ALLOC_BLOCKING[0] */ +#define WF_PLE_TOP_PORT_SER_CTRL_EN_HIF_PORT_ALLOC_BLOCKING_SHFT 0 + +/* +* ---MACTX_SER_CTRL (0x820C0000 + 0x2A4)--- +* EN_MACTX_G0_BLOCKING[0] - (RW) Enable MACTX group 0 operation +blocking. +* RESERVED1[7..1] - (RO) Reserved bits +* EN_MACTX_G1_BLOCKING[8] - (RW) Enable MACTX group 1 operation +blocking. +* RESERVED9[15..9] - (RO) Reserved bits +* EN_MACTX_G2_BLOCKING[16] - (RW) Enable MACTX group 2 operation blocking. +* RESERVED17[23..17] - (RO) Reserved bits +* EN_MACTX_G3_BLOCKING[24] - (RW) Enable MACTX group 3 operation blocking. +* RESERVED25[31..25] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_MACTX_SER_CTRL_EN_MACTX_G3_BLOCKING_ADDR \ +WF_PLE_TOP_MACTX_SER_CTRL_ADDR +#define WF_PLE_TOP_MACTX_SER_CTRL_EN_MACTX_G3_BLOCKING_MASK \ +0x01000000 /* EN_MACTX_G3_BLOCKING[24] */ +#define WF_PLE_TOP_MACTX_SER_CTRL_EN_MACTX_G3_BLOCKING_SHFT 24 +#define WF_PLE_TOP_MACTX_SER_CTRL_EN_MACTX_G2_BLOCKING_ADDR \ +WF_PLE_TOP_MACTX_SER_CTRL_ADDR +#define WF_PLE_TOP_MACTX_SER_CTRL_EN_MACTX_G2_BLOCKING_MASK \ +0x00010000 /* EN_MACTX_G2_BLOCKING[16] */ +#define WF_PLE_TOP_MACTX_SER_CTRL_EN_MACTX_G2_BLOCKING_SHFT 16 +#define WF_PLE_TOP_MACTX_SER_CTRL_EN_MACTX_G1_BLOCKING_ADDR \ +WF_PLE_TOP_MACTX_SER_CTRL_ADDR +#define WF_PLE_TOP_MACTX_SER_CTRL_EN_MACTX_G1_BLOCKING_MASK \ +0x00000100 /* EN_MACTX_G1_BLOCKING[8] */ +#define WF_PLE_TOP_MACTX_SER_CTRL_EN_MACTX_G1_BLOCKING_SHFT 8 +#define WF_PLE_TOP_MACTX_SER_CTRL_EN_MACTX_G0_BLOCKING_ADDR \ +WF_PLE_TOP_MACTX_SER_CTRL_ADDR +#define WF_PLE_TOP_MACTX_SER_CTRL_EN_MACTX_G0_BLOCKING_MASK \ +0x00000001 /* EN_MACTX_G0_BLOCKING[0] */ +#define WF_PLE_TOP_MACTX_SER_CTRL_EN_MACTX_G0_BLOCKING_SHFT 0 + +/* +* ---DRR_SER_CTRL (0x820C0000 + 0x2A8)--- +* EN_DRR_CHARGE_BLOCKING[0] - (RW) Enable DRR charge operation blocking. +* RESERVED1[3..1] - (RO) Reserved bits +* EN_DRR_SRCH_0_BLOCKING[4] - (RW) Enable DRR search 0 operation blocking. +* EN_DRR_SRCH_1_BLOCKING[5] - (RW) Enable DRR search 1 operation blocking. +* RESERVED6[7..6] - (RO) Reserved bits +* EN_DRR_RDG_0_BLOCKING[8] - (RW) Enable DRR RDG 0 operation blocking. +* EN_DRR_RDG_1_BLOCKING[9] - (RW) Enable DRR RDG 1 operation blocking. +* RESERVED10[31..10] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_RDG_1_BLOCKING_ADDR \ +WF_PLE_TOP_DRR_SER_CTRL_ADDR +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_RDG_1_BLOCKING_MASK \ +0x00000200 /* EN_DRR_RDG_1_BLOCKING[9] */ +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_RDG_1_BLOCKING_SHFT 9 +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_RDG_0_BLOCKING_ADDR \ +WF_PLE_TOP_DRR_SER_CTRL_ADDR +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_RDG_0_BLOCKING_MASK \ +0x00000100 /* EN_DRR_RDG_0_BLOCKING[8] */ +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_RDG_0_BLOCKING_SHFT 8 +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_SRCH_1_BLOCKING_ADDR \ +WF_PLE_TOP_DRR_SER_CTRL_ADDR +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_SRCH_1_BLOCKING_MASK \ +0x00000020 /* EN_DRR_SRCH_1_BLOCKING[5] */ +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_SRCH_1_BLOCKING_SHFT 5 +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_SRCH_0_BLOCKING_ADDR \ +WF_PLE_TOP_DRR_SER_CTRL_ADDR +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_SRCH_0_BLOCKING_MASK \ +0x00000010 /* EN_DRR_SRCH_0_BLOCKING[4] */ +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_SRCH_0_BLOCKING_SHFT 4 +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_CHARGE_BLOCKING_ADDR \ +WF_PLE_TOP_DRR_SER_CTRL_ADDR +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_CHARGE_BLOCKING_MASK \ +0x00000001 /* EN_DRR_CHARGE_BLOCKING[0] */ +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_CHARGE_BLOCKING_SHFT 0 + +/* +* ---SRAM_MBIST_DELSEL5 (0x820C0000 + 0x2c0)--- +* SRAM5_MBIST_DELSEL[31..0] - (RW) MBIST delsel setting of SRAM5 +*/ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL5_SRAM5_MBIST_DELSEL_ADDR \ +WF_PLE_TOP_SRAM_MBIST_DELSEL5_ADDR +#define WF_PLE_TOP_SRAM_MBIST_DELSEL5_SRAM5_MBIST_DELSEL_MASK \ +0xFFFFFFFF /* SRAM5_MBIST_DELSEL[31..0] */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL5_SRAM5_MBIST_DELSEL_SHFT 0 + +/* +* ---SRAM_MBIST_DELSEL6 (0x820C0000 + 0x2c4)--- +* SRAM6_MBIST_DELSEL[31..0] - (RW) MBIST delsel setting of SRAM6 +*/ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL6_SRAM6_MBIST_DELSEL_ADDR \ +WF_PLE_TOP_SRAM_MBIST_DELSEL6_ADDR +#define WF_PLE_TOP_SRAM_MBIST_DELSEL6_SRAM6_MBIST_DELSEL_MASK \ +0xFFFFFFFF /* SRAM6_MBIST_DELSEL[31..0] */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL6_SRAM6_MBIST_DELSEL_SHFT 0 + +/* +* ---SRAM_MBIST_DELSEL7 (0x820C0000 + 0x2c8)--- +* SRAM7_MBIST_DELSEL[31..0] - (RW) MBIST delsel setting of SRAM7 +*/ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL7_SRAM7_MBIST_DELSEL_ADDR \ +WF_PLE_TOP_SRAM_MBIST_DELSEL7_ADDR +#define WF_PLE_TOP_SRAM_MBIST_DELSEL7_SRAM7_MBIST_DELSEL_MASK \ +0xFFFFFFFF /* SRAM7_MBIST_DELSEL[31..0] */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL7_SRAM7_MBIST_DELSEL_SHFT 0 + +/* +* ---SRAM_MBIST_DELSEL8 (0x820C0000 + 0x2cc)--- +* SRAM8_MBIST_DELSEL[31..0] - (RW) MBIST delsel setting of SRAM8 +*/ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL8_SRAM8_MBIST_DELSEL_ADDR \ +WF_PLE_TOP_SRAM_MBIST_DELSEL8_ADDR +#define WF_PLE_TOP_SRAM_MBIST_DELSEL8_SRAM8_MBIST_DELSEL_MASK \ +0xFFFFFFFF /* SRAM8_MBIST_DELSEL[31..0] */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL8_SRAM8_MBIST_DELSEL_SHFT 0 + +/* +* ---SRAM_MBIST_BACKGROUND (0x820C0000 + 0x2d0)--- +* MBIST_BACKGROUND[15..0] - (RW) bsel setting for PLE SRAM MBIST circuit +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_SRAM_MBIST_BACKGROUND_MBIST_BACKGROUND_ADDR \ +WF_PLE_TOP_SRAM_MBIST_BACKGROUND_ADDR +#define WF_PLE_TOP_SRAM_MBIST_BACKGROUND_MBIST_BACKGROUND_MASK \ +0x0000FFFF /* MBIST_BACKGROUND[15..0] */ +#define WF_PLE_TOP_SRAM_MBIST_BACKGROUND_MBIST_BACKGROUND_SHFT 0 + +/* +* ---SRAM_MBIST_BSEL (0x820C0000 + 0x2d4)--- +* MBIST_BSEL[15..0] - (RW) The bsel setting for PLE SRAM MBIST +circuit. +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_SRAM_MBIST_BSEL_MBIST_BSEL_ADDR \ +WF_PLE_TOP_SRAM_MBIST_BSEL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_BSEL_MBIST_BSEL_MASK \ +0x0000FFFF /* MBIST_BSEL[15..0] */ +#define WF_PLE_TOP_SRAM_MBIST_BSEL_MBIST_BSEL_SHFT 0 + +/* +* ---SRAM_MBIST_DONE (0x820C0000 + 0x2d8)--- +* G1_MBIST_DONE[0] - (RO) Working status of PLE G1 SRAM MBIST +circuit +* G2_MBIST_DONE[1] - (RO) Working status of PLE G2 SRAM MBIST +circuit +* RESERVED2[31..2] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_SRAM_MBIST_DONE_G2_MBIST_DONE_ADDR \ +WF_PLE_TOP_SRAM_MBIST_DONE_ADDR +#define WF_PLE_TOP_SRAM_MBIST_DONE_G2_MBIST_DONE_MASK \ +0x00000002 /* G2_MBIST_DONE[1] */ +#define WF_PLE_TOP_SRAM_MBIST_DONE_G2_MBIST_DONE_SHFT 1 +#define WF_PLE_TOP_SRAM_MBIST_DONE_G1_MBIST_DONE_ADDR \ +WF_PLE_TOP_SRAM_MBIST_DONE_ADDR +#define WF_PLE_TOP_SRAM_MBIST_DONE_G1_MBIST_DONE_MASK \ +0x00000001 /* G1_MBIST_DONE[0] */ +#define WF_PLE_TOP_SRAM_MBIST_DONE_G1_MBIST_DONE_SHFT 0 + +/* +* ---SRAM_MBIST_FAIL (0x820C0000 + 0x2dc)--- +* G1_SRAM0_MBIST_FAIL[0] - (RO) MBIST check result of group 1 SRAM0 +* G1_SRAM1_MBIST_FAIL[1] - (RO) MBIST check result of group 1 SRAM1 +* G1_SRAM2_MBIST_FAIL[2] - (RO) MBIST check result of group 1 SRAM2 +* G1_SRAM3_MBIST_FAIL[3] - (RO) MBIST check result of group 1 SRAM3 +* G2_SRAM0_MBIST_FAIL[4] - (RO) MBIST check result of group 2 SRAM0 +* G2_SRAM1_MBIST_FAIL[5] - (RO) MBIST check result of group 2 SRAM1 +* G2_SRAM2_MBIST_FAIL[6] - (RO) MBIST check result of group 2 SRAM2 +* G2_SRAM3_MBIST_FAIL[7] - (RO) MBIST check result of group 2 SRAM3 +* G2_SRAM4_MBIST_FAIL[8] - (RO) MBIST check result of group 2 SRAM4 +* G2_SRAM5_MBIST_FAIL[9] - (RO) MBIST check result of group 2 SRAM5 +* RESERVED10[31..10] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM5_MBIST_FAIL_ADDR \ +WF_PLE_TOP_SRAM_MBIST_FAIL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM5_MBIST_FAIL_MASK \ +0x00000200 /* G2_SRAM5_MBIST_FAIL[9] */ +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM5_MBIST_FAIL_SHFT 9 +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM4_MBIST_FAIL_ADDR \ +WF_PLE_TOP_SRAM_MBIST_FAIL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM4_MBIST_FAIL_MASK \ +0x00000100 /* G2_SRAM4_MBIST_FAIL[8] */ +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM4_MBIST_FAIL_SHFT 8 +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM3_MBIST_FAIL_ADDR \ +WF_PLE_TOP_SRAM_MBIST_FAIL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM3_MBIST_FAIL_MASK \ +0x00000080 /* G2_SRAM3_MBIST_FAIL[7] */ +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM3_MBIST_FAIL_SHFT 7 +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM2_MBIST_FAIL_ADDR \ +WF_PLE_TOP_SRAM_MBIST_FAIL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM2_MBIST_FAIL_MASK \ +0x00000040 /* G2_SRAM2_MBIST_FAIL[6] */ +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM2_MBIST_FAIL_SHFT 6 +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM1_MBIST_FAIL_ADDR \ +WF_PLE_TOP_SRAM_MBIST_FAIL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM1_MBIST_FAIL_MASK \ +0x00000020 /* G2_SRAM1_MBIST_FAIL[5] */ +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM1_MBIST_FAIL_SHFT 5 +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM0_MBIST_FAIL_ADDR \ +WF_PLE_TOP_SRAM_MBIST_FAIL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM0_MBIST_FAIL_MASK \ +0x00000010 /* G2_SRAM0_MBIST_FAIL[4] */ +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM0_MBIST_FAIL_SHFT 4 +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G1_SRAM3_MBIST_FAIL_ADDR \ +WF_PLE_TOP_SRAM_MBIST_FAIL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G1_SRAM3_MBIST_FAIL_MASK \ +0x00000008 /* G1_SRAM3_MBIST_FAIL[3] */ +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G1_SRAM3_MBIST_FAIL_SHFT 3 +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G1_SRAM2_MBIST_FAIL_ADDR \ +WF_PLE_TOP_SRAM_MBIST_FAIL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G1_SRAM2_MBIST_FAIL_MASK \ +0x00000004 /* G1_SRAM2_MBIST_FAIL[2] */ +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G1_SRAM2_MBIST_FAIL_SHFT 2 +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G1_SRAM1_MBIST_FAIL_ADDR \ +WF_PLE_TOP_SRAM_MBIST_FAIL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G1_SRAM1_MBIST_FAIL_MASK \ +0x00000002 /* G1_SRAM1_MBIST_FAIL[1] */ +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G1_SRAM1_MBIST_FAIL_SHFT 1 +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G1_SRAM0_MBIST_FAIL_ADDR \ +WF_PLE_TOP_SRAM_MBIST_FAIL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G1_SRAM0_MBIST_FAIL_MASK \ +0x00000001 /* G1_SRAM0_MBIST_FAIL[0] */ +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G1_SRAM0_MBIST_FAIL_SHFT 0 + +/* +* ---SRAM_MBIST_CTRL (0x820C0000 + 0x2e0)--- +* G1_MBIST_MODE[0] - (RW) Control register for mbist_mode of group +* 1 MBIST +* G2_MBIST_MODE[1] - (RW) Control register for mbist_mode of group +* 2 MBIST +* RESERVED2[3..2] - (RO) Reserved bits +* G1_MBIST_HOLDB[4] - (RW) Control register for mbist_holdb of +* group 1 MBIST +* G2_MBIST_HOLDB[5] - (RW) Control register for mbist_holdb of +* group 2 MBIST +* RESERVED6[7..6] - (RO) Reserved bits +* G1_MBIST_DEBUG[8] - (RW) Control register for mbist_debug of +* group 1 MBIST +* G2_MBIST_DEBUG[9] - (RW) Control register for mbist_debug of +* group 2 MBIST +* G1_MBIST_USE_DEFAULT_DELSEL[10] - (RW) Control register for default DELSEL +* value of group 1 memory +* G2_MBIST_USE_DEFAULT_DELSEL[11] - (RW) Control register for default DELSEL +* value of group 2 memory +* MBIST_DIAG_SEL[16..12] - (RW) Selection register for +mbist_diag_scan_out +* RESERVED17[19..17] - (RO) Reserved bits +* UMAC_MBIST_DIAG_SEL[20] - (RW) Selection register for UMAC +* mbist_diag_scan_out (PLE or PSE) +* RESERVED21[23..21] - (RO) Reserved bits +* G1_MBIST_SLEEP_TEST[24] - (RW) Control register for sleep_test of group +* 1 MBIST +* G1_MBIST_SLEEP_INV[25] - (RW) Control register for sleep_inv of group +* 1 MBIST +* G1_MBIST_SLEEP_W[26] - (RW) Control register for sleep_w of group 1 +MBIST +* G1_MBIST_SLEEP_R[27] - (RW) Control register for sleep_r of group 1 +MBIST +* G2_MBIST_SLEEP_TEST[28] - (RW) Control register for sleep_test of group +* 2 MBIST +* G2_MBIST_SLEEP_INV[29] - (RW) Control register for sleep_inv of group +* 2 MBIST +* G2_MBIST_SLEEP_W[30] - (RW) Control register for sleep_w of group 2 +MBIST +* G2_MBIST_SLEEP_R[31] - (RW) Control register for sleep_r of group 2 +MBIST +*/ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_SLEEP_R_ADDR \ +WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_SLEEP_R_MASK \ +0x80000000 /* G2_MBIST_SLEEP_R[31] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_SLEEP_R_SHFT 31 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_SLEEP_W_ADDR \ +WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_SLEEP_W_MASK \ +0x40000000 /* G2_MBIST_SLEEP_W[30] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_SLEEP_W_SHFT 30 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_SLEEP_INV_ADDR \ +WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_SLEEP_INV_MASK \ +0x20000000 /* G2_MBIST_SLEEP_INV[29] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_SLEEP_INV_SHFT 29 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_SLEEP_TEST_ADDR \ +WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_SLEEP_TEST_MASK \ +0x10000000 /* G2_MBIST_SLEEP_TEST[28] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_SLEEP_TEST_SHFT 28 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_SLEEP_R_ADDR \ +WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_SLEEP_R_MASK \ +0x08000000 /* G1_MBIST_SLEEP_R[27] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_SLEEP_R_SHFT 27 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_SLEEP_W_ADDR \ +WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_SLEEP_W_MASK \ +0x04000000 /* G1_MBIST_SLEEP_W[26] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_SLEEP_W_SHFT 26 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_SLEEP_INV_ADDR \ +WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_SLEEP_INV_MASK \ +0x02000000 /* G1_MBIST_SLEEP_INV[25] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_SLEEP_INV_SHFT 25 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_SLEEP_TEST_ADDR \ +WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_SLEEP_TEST_MASK \ +0x01000000 /* G1_MBIST_SLEEP_TEST[24] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_SLEEP_TEST_SHFT 24 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_UMAC_MBIST_DIAG_SEL_ADDR \ +WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_UMAC_MBIST_DIAG_SEL_MASK \ +0x00100000 /* UMAC_MBIST_DIAG_SEL[20] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_UMAC_MBIST_DIAG_SEL_SHFT 20 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_MBIST_DIAG_SEL_ADDR \ +WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_MBIST_DIAG_SEL_MASK \ +0x0001F000 /* MBIST_DIAG_SEL[16..12] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_MBIST_DIAG_SEL_SHFT 12 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_USE_DEFAULT_DELSEL_ADDR \ +WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_USE_DEFAULT_DELSEL_MASK \ +0x00000800 /* G2_MBIST_USE_DEFAULT_DELSEL[11] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_USE_DEFAULT_DELSEL_SHFT 11 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_USE_DEFAULT_DELSEL_ADDR \ +WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_USE_DEFAULT_DELSEL_MASK \ +0x00000400 /* G1_MBIST_USE_DEFAULT_DELSEL[10] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_USE_DEFAULT_DELSEL_SHFT 10 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_DEBUG_ADDR \ +WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_DEBUG_MASK \ +0x00000200 /* G2_MBIST_DEBUG[9] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_DEBUG_SHFT 9 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_DEBUG_ADDR \ +WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_DEBUG_MASK \ +0x00000100 /* G1_MBIST_DEBUG[8] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_DEBUG_SHFT 8 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_HOLDB_ADDR \ +WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_HOLDB_MASK \ +0x00000020 /* G2_MBIST_HOLDB[5] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_HOLDB_SHFT 5 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_HOLDB_ADDR \ +WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_HOLDB_MASK \ +0x00000010 /* G1_MBIST_HOLDB[4] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_HOLDB_SHFT 4 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_MODE_ADDR \ +WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_MODE_MASK \ +0x00000002 /* G2_MBIST_MODE[1] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_MODE_SHFT 1 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_MODE_ADDR \ +WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_MODE_MASK \ +0x00000001 /* G1_MBIST_MODE[0] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_MODE_SHFT 0 + +/* +* ---SRAM_MBIST_DELSEL1 (0x820C0000 + 0x2e4)--- +* SRAM1_MBIST_DELSEL[31..0] - (RW) MBIST delsel setting of SRAM1 +*/ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL1_SRAM1_MBIST_DELSEL_ADDR \ +WF_PLE_TOP_SRAM_MBIST_DELSEL1_ADDR +#define WF_PLE_TOP_SRAM_MBIST_DELSEL1_SRAM1_MBIST_DELSEL_MASK \ +0xFFFFFFFF /* SRAM1_MBIST_DELSEL[31..0] */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL1_SRAM1_MBIST_DELSEL_SHFT 0 + +/* +* ---BSS_DBDC_CTRL (0x820C0000 + 0x2ec)--- +* BSS_BAND_SEL[15..0] - (RW) Select band of each BSS +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_BSS_DBDC_CTRL_BSS_BAND_SEL_ADDR WF_PLE_TOP_BSS_DBDC_CTRL_ADDR +#define WF_PLE_TOP_BSS_DBDC_CTRL_BSS_BAND_SEL_MASK \ +0x0000FFFF /* BSS_BAND_SEL[15..0] */ +#define WF_PLE_TOP_BSS_DBDC_CTRL_BSS_BAND_SEL_SHFT 0 + +/* +* ---SRAM_MBIST_DELSEL2 (0x820C0000 + 0x2f0)--- +* SRAM2_MBIST_DELSEL[31..0] - (RW) MBIST delsel setting of SRAM2 +*/ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL2_SRAM2_MBIST_DELSEL_ADDR \ +WF_PLE_TOP_SRAM_MBIST_DELSEL2_ADDR +#define WF_PLE_TOP_SRAM_MBIST_DELSEL2_SRAM2_MBIST_DELSEL_MASK \ +0xFFFFFFFF /* SRAM2_MBIST_DELSEL[31..0] */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL2_SRAM2_MBIST_DELSEL_SHFT 0 + +/* +* ---SRAM_MBIST_DELSEL3 (0x820C0000 + 0x2f4)--- +* SRAM3_MBIST_DELSEL[31..0] - (RW) MBIST delsel setting of SRAM3 +*/ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL3_SRAM3_MBIST_DELSEL_ADDR \ +WF_PLE_TOP_SRAM_MBIST_DELSEL3_ADDR +#define WF_PLE_TOP_SRAM_MBIST_DELSEL3_SRAM3_MBIST_DELSEL_MASK \ +0xFFFFFFFF /* SRAM3_MBIST_DELSEL[31..0] */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL3_SRAM3_MBIST_DELSEL_SHFT 0 + +/* +* ---SRAM_MBIST_DELSEL4 (0x820C0000 + 0x2f8)--- +* SRAM4_MBIST_DELSEL[31..0] - (RW) MBIST delsel setting of SRAM4 +*/ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL4_SRAM4_MBIST_DELSEL_ADDR \ +WF_PLE_TOP_SRAM_MBIST_DELSEL4_ADDR +#define WF_PLE_TOP_SRAM_MBIST_DELSEL4_SRAM4_MBIST_DELSEL_MASK \ +0xFFFFFFFF /* SRAM4_MBIST_DELSEL[31..0] */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL4_SRAM4_MBIST_DELSEL_SHFT 0 + +/* +* ---SRAM_AWT_HDEN_CTRL (0x820C0000 + 0x2fc)--- +* SRAM_AWT_CTRL[13..0] - (RW) AWT setting of SRAMS +* RESERVED14[15..14] - (RO) Reserved bits +* SRAM_HDEN_CTRL[29..16] - (RW) HDEN setting of SRAMS +* RESERVED30[31..30] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_SRAM_AWT_HDEN_CTRL_SRAM_HDEN_CTRL_ADDR \ +WF_PLE_TOP_SRAM_AWT_HDEN_CTRL_ADDR +#define WF_PLE_TOP_SRAM_AWT_HDEN_CTRL_SRAM_HDEN_CTRL_MASK \ +0x3FFF0000 /* SRAM_HDEN_CTRL[29..16] */ +#define WF_PLE_TOP_SRAM_AWT_HDEN_CTRL_SRAM_HDEN_CTRL_SHFT 16 +#define WF_PLE_TOP_SRAM_AWT_HDEN_CTRL_SRAM_AWT_CTRL_ADDR \ +WF_PLE_TOP_SRAM_AWT_HDEN_CTRL_ADDR +#define WF_PLE_TOP_SRAM_AWT_HDEN_CTRL_SRAM_AWT_CTRL_MASK \ +0x00003FFF /* SRAM_AWT_CTRL[13..0] */ +#define WF_PLE_TOP_SRAM_AWT_HDEN_CTRL_SRAM_AWT_CTRL_SHFT 0 + +/* +* ---PREDL_CTRL (0x820C0000 + 0x300)--- +* EN_PREDL[0] - (RW) Enable control of pre-download function +* RESERVED1[15..1] - (RO) Reserved bits +* BN0_PREDL_CLEAN_QID[22..16] - (RW) QID for clean BN0 PREDL buffer command. +* BN0_PREDL_CLEAN_EXECUTE[23] - (A0) Executes clean BN0 PREDL buffer command. +* BN1_PREDL_CLEAN_QID[30..24] - (RW) QID for clean BN1 PREDL buffer command. +* BN1_PREDL_CLEAN_EXECUTE[31] - (A0) Executes clean BN1 PREDL buffer command. +*/ +#define WF_PLE_TOP_PREDL_CTRL_BN1_PREDL_CLEAN_EXECUTE_ADDR \ +WF_PLE_TOP_PREDL_CTRL_ADDR +#define WF_PLE_TOP_PREDL_CTRL_BN1_PREDL_CLEAN_EXECUTE_MASK \ +0x80000000 /* BN1_PREDL_CLEAN_EXECUTE[31] */ +#define WF_PLE_TOP_PREDL_CTRL_BN1_PREDL_CLEAN_EXECUTE_SHFT 31 +#define WF_PLE_TOP_PREDL_CTRL_BN1_PREDL_CLEAN_QID_ADDR \ +WF_PLE_TOP_PREDL_CTRL_ADDR +#define WF_PLE_TOP_PREDL_CTRL_BN1_PREDL_CLEAN_QID_MASK \ +0x7F000000 /* BN1_PREDL_CLEAN_QID[30..24] */ +#define WF_PLE_TOP_PREDL_CTRL_BN1_PREDL_CLEAN_QID_SHFT 24 +#define WF_PLE_TOP_PREDL_CTRL_BN0_PREDL_CLEAN_EXECUTE_ADDR \ +WF_PLE_TOP_PREDL_CTRL_ADDR +#define WF_PLE_TOP_PREDL_CTRL_BN0_PREDL_CLEAN_EXECUTE_MASK \ +0x00800000 /* BN0_PREDL_CLEAN_EXECUTE[23] */ +#define WF_PLE_TOP_PREDL_CTRL_BN0_PREDL_CLEAN_EXECUTE_SHFT 23 +#define WF_PLE_TOP_PREDL_CTRL_BN0_PREDL_CLEAN_QID_ADDR \ +WF_PLE_TOP_PREDL_CTRL_ADDR +#define WF_PLE_TOP_PREDL_CTRL_BN0_PREDL_CLEAN_QID_MASK \ +0x007F0000 /* BN0_PREDL_CLEAN_QID[22..16] */ +#define WF_PLE_TOP_PREDL_CTRL_BN0_PREDL_CLEAN_QID_SHFT 16 +#define WF_PLE_TOP_PREDL_CTRL_EN_PREDL_ADDR WF_PLE_TOP_PREDL_CTRL_ADDR +#define WF_PLE_TOP_PREDL_CTRL_EN_PREDL_MASK 0x00000001 /* EN_PREDL[0] */ +#define WF_PLE_TOP_PREDL_CTRL_EN_PREDL_SHFT 0 + +/* +* ---PREDL_CTRL1 (0x820C0000 + 0x304)--- +* PREDL_WMMAC_ENABLE[25..0] - (RW) Enable control of pre-download function +* per queue control. +* RESERVED26[31..26] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_PREDL_CTRL1_PREDL_WMMAC_ENABLE_ADDR \ +WF_PLE_TOP_PREDL_CTRL1_ADDR +#define WF_PLE_TOP_PREDL_CTRL1_PREDL_WMMAC_ENABLE_MASK \ +0x03FFFFFF /* PREDL_WMMAC_ENABLE[25..0] */ +#define WF_PLE_TOP_PREDL_CTRL1_PREDL_WMMAC_ENABLE_SHFT 0 + +/* +* ---PREDL_BN0_LEN0 (0x820C0000 + 0x330)--- +* BUF_SIZE[15..0] - (RW) Pre-Download Per TXCMD buffer size +limit. +* BUF_SIZE_OF_TXOP[31..16] - (RW) Pre-Download Per TXCMD buffer size limit +* under TXOP. +*/ +#define WF_PLE_TOP_PREDL_BN0_LEN0_BUF_SIZE_OF_TXOP_ADDR \ +WF_PLE_TOP_PREDL_BN0_LEN0_ADDR +#define WF_PLE_TOP_PREDL_BN0_LEN0_BUF_SIZE_OF_TXOP_MASK \ +0xFFFF0000 /* BUF_SIZE_OF_TXOP[31..16] */ +#define WF_PLE_TOP_PREDL_BN0_LEN0_BUF_SIZE_OF_TXOP_SHFT 16 +#define WF_PLE_TOP_PREDL_BN0_LEN0_BUF_SIZE_ADDR WF_PLE_TOP_PREDL_BN0_LEN0_ADDR +#define WF_PLE_TOP_PREDL_BN0_LEN0_BUF_SIZE_MASK 0x0000FFFF /* BUF_SIZE[15..0]\ + */ +#define WF_PLE_TOP_PREDL_BN0_LEN0_BUF_SIZE_SHFT 0 + +/* +* ---PREDL_BN0_LEN1 (0x820C0000 + 0x334)--- +* STA_NUM[5..0] - (RW) Pre-Download Per TXCMD station number +limit. +* RESERVED6[7..6] - (RO) Reserved bits +* PKT_LIMIT[13..8] - (RW) Pre-Download Per TXCMD packet number +limit. +* RESERVED14[15..14] - (RO) Reserved bits +* TOTAL_BUF_SIZE[31..16] - (RW) Pre-Download total buffer size limit. +*/ +#define WF_PLE_TOP_PREDL_BN0_LEN1_TOTAL_BUF_SIZE_ADDR \ +WF_PLE_TOP_PREDL_BN0_LEN1_ADDR +#define WF_PLE_TOP_PREDL_BN0_LEN1_TOTAL_BUF_SIZE_MASK \ +0xFFFF0000 /* TOTAL_BUF_SIZE[31..16] */ +#define WF_PLE_TOP_PREDL_BN0_LEN1_TOTAL_BUF_SIZE_SHFT 16 +#define WF_PLE_TOP_PREDL_BN0_LEN1_PKT_LIMIT_ADDR WF_PLE_TOP_PREDL_BN0_LEN1_ADDR +#define WF_PLE_TOP_PREDL_BN0_LEN1_PKT_LIMIT_MASK \ +0x00003F00 /* PKT_LIMIT[13..8] */ +#define WF_PLE_TOP_PREDL_BN0_LEN1_PKT_LIMIT_SHFT 8 +#define WF_PLE_TOP_PREDL_BN0_LEN1_STA_NUM_ADDR WF_PLE_TOP_PREDL_BN0_LEN1_ADDR +#define WF_PLE_TOP_PREDL_BN0_LEN1_STA_NUM_MASK 0x0000003F /* STA_NUM[5..0] */ +#define WF_PLE_TOP_PREDL_BN0_LEN1_STA_NUM_SHFT 0 + +/* +* ---PREDL_BN1_LEN0 (0x820C0000 + 0x338)--- +* BUF_SIZE[15..0] - (RW) Pre-Download Per TXCMD buffer size +limit. +* BUF_SIZE_OF_TXOP[31..16] - (RW) Pre-Download Per TXCMD buffer size limit +* under TXOP. +*/ +#define WF_PLE_TOP_PREDL_BN1_LEN0_BUF_SIZE_OF_TXOP_ADDR \ +WF_PLE_TOP_PREDL_BN1_LEN0_ADDR +#define WF_PLE_TOP_PREDL_BN1_LEN0_BUF_SIZE_OF_TXOP_MASK \ +0xFFFF0000 /* BUF_SIZE_OF_TXOP[31..16] */ +#define WF_PLE_TOP_PREDL_BN1_LEN0_BUF_SIZE_OF_TXOP_SHFT 16 +#define WF_PLE_TOP_PREDL_BN1_LEN0_BUF_SIZE_ADDR WF_PLE_TOP_PREDL_BN1_LEN0_ADDR +#define WF_PLE_TOP_PREDL_BN1_LEN0_BUF_SIZE_MASK 0x0000FFFF /* BUF_SIZE[15..0]\ + */ +#define WF_PLE_TOP_PREDL_BN1_LEN0_BUF_SIZE_SHFT 0 + +/* +* ---PREDL_BN1_LEN1 (0x820C0000 + 0x33c)--- +* STA_NUM[5..0] - (RW) Pre-Download Per TXCMD station number +limit. +* RESERVED6[7..6] - (RO) Reserved bits +* PKT_LIMIT[13..8] - (RW) Pre-Download Per TXCMD packet number +limit. +* RESERVED14[15..14] - (RO) Reserved bits +* TOTAL_BUF_SIZE[31..16] - (RW) Pre-Download total buffer size limit. +*/ +#define WF_PLE_TOP_PREDL_BN1_LEN1_TOTAL_BUF_SIZE_ADDR \ +WF_PLE_TOP_PREDL_BN1_LEN1_ADDR +#define WF_PLE_TOP_PREDL_BN1_LEN1_TOTAL_BUF_SIZE_MASK \ +0xFFFF0000 /* TOTAL_BUF_SIZE[31..16] */ +#define WF_PLE_TOP_PREDL_BN1_LEN1_TOTAL_BUF_SIZE_SHFT 16 +#define WF_PLE_TOP_PREDL_BN1_LEN1_PKT_LIMIT_ADDR WF_PLE_TOP_PREDL_BN1_LEN1_ADDR +#define WF_PLE_TOP_PREDL_BN1_LEN1_PKT_LIMIT_MASK \ +0x00003F00 /* PKT_LIMIT[13..8] */ +#define WF_PLE_TOP_PREDL_BN1_LEN1_PKT_LIMIT_SHFT 8 +#define WF_PLE_TOP_PREDL_BN1_LEN1_STA_NUM_ADDR WF_PLE_TOP_PREDL_BN1_LEN1_ADDR +#define WF_PLE_TOP_PREDL_BN1_LEN1_STA_NUM_MASK 0x0000003F /* STA_NUM[5..0] */ +#define WF_PLE_TOP_PREDL_BN1_LEN1_STA_NUM_SHFT 0 + +/* +* ---DRR_TABLE_WDATA0 (0x820C0000 + 0x340)--- +* DRR_TABLE_WDATA[31..0] - (RW) DRRwdata[31:0] for reading/writing DRR +table +* Mode 0x2?: DRR station mode +* WData[15:0]: Sta setting +* WData[127:16]: Reserved +* Mode 0x4?: BSS mode +* See SRAM layout. +* Mode 0x8?: Charge mode +* WData [15:0]: Charge length (unit: +byte) +* WData [31:16]: Charge time 9 unit +1.024us +* WData[127:32]: Reserved +*/ +#define WF_PLE_TOP_DRR_TABLE_WDATA0_DRR_TABLE_WDATA_ADDR \ +WF_PLE_TOP_DRR_TABLE_WDATA0_ADDR +#define WF_PLE_TOP_DRR_TABLE_WDATA0_DRR_TABLE_WDATA_MASK \ +0xFFFFFFFF /* DRR_TABLE_WDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_WDATA0_DRR_TABLE_WDATA_SHFT 0 + +/* +* ---DRR_TABLE_WDATA1 (0x820C0000 + 0x344)--- +* DRR_TABLE_WDATA[31..0] - (RW) DRR wdata[63:32] for reading/writing DRR +table +*/ +#define WF_PLE_TOP_DRR_TABLE_WDATA1_DRR_TABLE_WDATA_ADDR \ +WF_PLE_TOP_DRR_TABLE_WDATA1_ADDR +#define WF_PLE_TOP_DRR_TABLE_WDATA1_DRR_TABLE_WDATA_MASK \ +0xFFFFFFFF /* DRR_TABLE_WDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_WDATA1_DRR_TABLE_WDATA_SHFT 0 + +/* +* ---DRR_TABLE_WDATA2 (0x820C0000 + 0x348)--- +* DRR_TABLE_WDATA[31..0] - (RW) DRR wdata[95:64] for reading/writing DRR +table +*/ +#define WF_PLE_TOP_DRR_TABLE_WDATA2_DRR_TABLE_WDATA_ADDR \ +WF_PLE_TOP_DRR_TABLE_WDATA2_ADDR +#define WF_PLE_TOP_DRR_TABLE_WDATA2_DRR_TABLE_WDATA_MASK \ +0xFFFFFFFF /* DRR_TABLE_WDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_WDATA2_DRR_TABLE_WDATA_SHFT 0 + +/* +* ---DRR_TABLE_WDATA3 (0x820C0000 + 0x34c)--- +* DRR_TABLE_WDATA[31..0] - (RW) DRR wdata[127:96] for reading/writing +* DRR table +*/ +#define WF_PLE_TOP_DRR_TABLE_WDATA3_DRR_TABLE_WDATA_ADDR \ +WF_PLE_TOP_DRR_TABLE_WDATA3_ADDR +#define WF_PLE_TOP_DRR_TABLE_WDATA3_DRR_TABLE_WDATA_MASK \ +0xFFFFFFFF /* DRR_TABLE_WDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_WDATA3_DRR_TABLE_WDATA_SHFT 0 + +/* +* ---DRR_TABLE_RDATA0 (0x820C0000 + 0x350)--- +* DRR_TABLE_RDATA[31..0] - (RW) DRR rdata[31:0] for reading/writing DRR +table +*/ +#define WF_PLE_TOP_DRR_TABLE_RDATA0_DRR_TABLE_RDATA_ADDR \ +WF_PLE_TOP_DRR_TABLE_RDATA0_ADDR +#define WF_PLE_TOP_DRR_TABLE_RDATA0_DRR_TABLE_RDATA_MASK \ +0xFFFFFFFF /* DRR_TABLE_RDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_RDATA0_DRR_TABLE_RDATA_SHFT 0 + +/* +* ---DRR_TABLE_RDATA1 (0x820C0000 + 0x354)--- +* DRR_TABLE_RDATA[31..0] - (RW) DRR rdata[63:32] for reading/writing DRR +table +*/ +#define WF_PLE_TOP_DRR_TABLE_RDATA1_DRR_TABLE_RDATA_ADDR \ +WF_PLE_TOP_DRR_TABLE_RDATA1_ADDR +#define WF_PLE_TOP_DRR_TABLE_RDATA1_DRR_TABLE_RDATA_MASK \ +0xFFFFFFFF /* DRR_TABLE_RDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_RDATA1_DRR_TABLE_RDATA_SHFT 0 + +/* +* ---DRR_TABLE_RDATA2 (0x820C0000 + 0x358)--- +* DRR_TABLE_RDATA[31..0] - (RW) DRR rdata[95:64] for reading/writing DRR +table +*/ +#define WF_PLE_TOP_DRR_TABLE_RDATA2_DRR_TABLE_RDATA_ADDR \ +WF_PLE_TOP_DRR_TABLE_RDATA2_ADDR +#define WF_PLE_TOP_DRR_TABLE_RDATA2_DRR_TABLE_RDATA_MASK \ +0xFFFFFFFF /* DRR_TABLE_RDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_RDATA2_DRR_TABLE_RDATA_SHFT 0 + +/* +* ---DRR_TABLE_RDATA3 (0x820C0000 + 0x35c)--- +* DRR_TABLE_RDATA[31..0] - (RW) DRR rdata[127:96] for reading/writing +* DRR table +*/ +#define WF_PLE_TOP_DRR_TABLE_RDATA3_DRR_TABLE_RDATA_ADDR \ +WF_PLE_TOP_DRR_TABLE_RDATA3_ADDR +#define WF_PLE_TOP_DRR_TABLE_RDATA3_DRR_TABLE_RDATA_MASK \ +0xFFFFFFFF /* DRR_TABLE_RDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_RDATA3_DRR_TABLE_RDATA_SHFT 0 + +/* +* ---ERLY_TRM_CTRL0 (0x820C0000 + 0x360)--- +* ERLY_TRM_EN[0] - (RW) Enable control of early terminate +function +* RESERVED1[7..1] - (RO) Reserved bits +* ERLY_TRM_MPDU_TH_0[15..8] - (RW) MPDU number Threshold for TX Bit Rate <= +97.5Mbps +* ERLY_TRM_MPDU_TH_1[23..16] - (RW) MPDU number Threshold for 97.5Mbps < TX +* Bit Rate <= 195Mbps +* ERLY_TRM_MPDU_TH_2[31..24] - (RW) MPDU number Threshold for TX Bit Rate <= +97.5Mbps +*/ +#define WF_PLE_TOP_ERLY_TRM_CTRL0_ERLY_TRM_MPDU_TH_2_ADDR \ +WF_PLE_TOP_ERLY_TRM_CTRL0_ADDR +#define WF_PLE_TOP_ERLY_TRM_CTRL0_ERLY_TRM_MPDU_TH_2_MASK \ +0xFF000000 /* ERLY_TRM_MPDU_TH_2[31..24] */ +#define WF_PLE_TOP_ERLY_TRM_CTRL0_ERLY_TRM_MPDU_TH_2_SHFT 24 +#define WF_PLE_TOP_ERLY_TRM_CTRL0_ERLY_TRM_MPDU_TH_1_ADDR \ +WF_PLE_TOP_ERLY_TRM_CTRL0_ADDR +#define WF_PLE_TOP_ERLY_TRM_CTRL0_ERLY_TRM_MPDU_TH_1_MASK \ +0x00FF0000 /* ERLY_TRM_MPDU_TH_1[23..16] */ +#define WF_PLE_TOP_ERLY_TRM_CTRL0_ERLY_TRM_MPDU_TH_1_SHFT 16 +#define WF_PLE_TOP_ERLY_TRM_CTRL0_ERLY_TRM_MPDU_TH_0_ADDR \ +WF_PLE_TOP_ERLY_TRM_CTRL0_ADDR +#define WF_PLE_TOP_ERLY_TRM_CTRL0_ERLY_TRM_MPDU_TH_0_MASK \ +0x0000FF00 /* ERLY_TRM_MPDU_TH_0[15..8] */ +#define WF_PLE_TOP_ERLY_TRM_CTRL0_ERLY_TRM_MPDU_TH_0_SHFT 8 +#define WF_PLE_TOP_ERLY_TRM_CTRL0_ERLY_TRM_EN_ADDR \ +WF_PLE_TOP_ERLY_TRM_CTRL0_ADDR +#define WF_PLE_TOP_ERLY_TRM_CTRL0_ERLY_TRM_EN_MASK \ +0x00000001 /* ERLY_TRM_EN[0] */ +#define WF_PLE_TOP_ERLY_TRM_CTRL0_ERLY_TRM_EN_SHFT 0 + +/* +* ---ERLY_TRM_CTRL1 (0x820C0000 + 0x364)--- +* ERLY_TRM_MPDU_TH_3[7..0] - (RW) MPDU number Threshold for 325Mbps < TX +* Bit Rate <= 433Mbps +* ERLY_TRM_MPDU_TH_4[15..8] - (RW) MPDU number Threshold for 433Mbps < TX +* Bit Rate <= 866.7Mbps +* ERLY_TRM_MPDU_TH_5[23..16] - (RW) MPDU number Threshold for 866.7Mbps < TX +* Bit Rate <= 1300Mbps +* ERLY_TRM_MPDU_TH_6[31..24] - (RW) MPDU number Threshold for TX Bit Rate <= +97.5Mbps +*/ +#define WF_PLE_TOP_ERLY_TRM_CTRL1_ERLY_TRM_MPDU_TH_6_ADDR \ +WF_PLE_TOP_ERLY_TRM_CTRL1_ADDR +#define WF_PLE_TOP_ERLY_TRM_CTRL1_ERLY_TRM_MPDU_TH_6_MASK \ +0xFF000000 /* ERLY_TRM_MPDU_TH_6[31..24] */ +#define WF_PLE_TOP_ERLY_TRM_CTRL1_ERLY_TRM_MPDU_TH_6_SHFT 24 +#define WF_PLE_TOP_ERLY_TRM_CTRL1_ERLY_TRM_MPDU_TH_5_ADDR \ +WF_PLE_TOP_ERLY_TRM_CTRL1_ADDR +#define WF_PLE_TOP_ERLY_TRM_CTRL1_ERLY_TRM_MPDU_TH_5_MASK \ +0x00FF0000 /* ERLY_TRM_MPDU_TH_5[23..16] */ +#define WF_PLE_TOP_ERLY_TRM_CTRL1_ERLY_TRM_MPDU_TH_5_SHFT 16 +#define WF_PLE_TOP_ERLY_TRM_CTRL1_ERLY_TRM_MPDU_TH_4_ADDR \ +WF_PLE_TOP_ERLY_TRM_CTRL1_ADDR +#define WF_PLE_TOP_ERLY_TRM_CTRL1_ERLY_TRM_MPDU_TH_4_MASK \ +0x0000FF00 /* ERLY_TRM_MPDU_TH_4[15..8] */ +#define WF_PLE_TOP_ERLY_TRM_CTRL1_ERLY_TRM_MPDU_TH_4_SHFT 8 +#define WF_PLE_TOP_ERLY_TRM_CTRL1_ERLY_TRM_MPDU_TH_3_ADDR \ +WF_PLE_TOP_ERLY_TRM_CTRL1_ADDR +#define WF_PLE_TOP_ERLY_TRM_CTRL1_ERLY_TRM_MPDU_TH_3_MASK \ +0x000000FF /* ERLY_TRM_MPDU_TH_3[7..0] */ +#define WF_PLE_TOP_ERLY_TRM_CTRL1_ERLY_TRM_MPDU_TH_3_SHFT 0 + +/* +* ---VOW_CONTROL (0x820C0000 + 0x370)--- +* PER_BSS_BW_CONTROL_ENABLE[15..0] - (RW) BW control of BSSID +* REFILL_PERIOD[18..16] - (RW) Period of token refill function +* RESERVED19[19] - (RO) Reserved bits +* DBDC1_SEARCH_RULE[20] - (RW) Priority for HW search if internal +* collision occurs +* DBDC0_SEARCH_RULE[21] - (RW) Priority for HW search if internal +* collision occcurs +* RESERVED22[25..22] - (RO) Reserved bits +* DRR_LOGIC_RESET[26] - (RW) DRR logic reset control +* DIS_WTBL_PS_IGNORE[27] - (RW) Disable control of the function that STA +* with WTBL PS ignore in TXQ busy +* ENABLE_TXOP_NO_CHANGE_BSS_GROUP[28] - (RW) HW cannot change BW group In TXOP +burst. +* ENABLE_AIRTIME_FAIRNESS[29] - (RW) When airtime function is disabled, HW +* will change station without checking station qouta. +* ENABLE_TOKEN_REFILL[30] - (RW) Enable control of token refill function +* ENABLE_BW_CONTROL[31] - (RW) HW will check if there are tokens in BW +* bucket before TX. +*/ +#define WF_PLE_TOP_VOW_CONTROL_ENABLE_BW_CONTROL_ADDR \ +WF_PLE_TOP_VOW_CONTROL_ADDR +#define WF_PLE_TOP_VOW_CONTROL_ENABLE_BW_CONTROL_MASK \ +0x80000000 /* ENABLE_BW_CONTROL[31] */ +#define WF_PLE_TOP_VOW_CONTROL_ENABLE_BW_CONTROL_SHFT 31 +#define WF_PLE_TOP_VOW_CONTROL_ENABLE_TOKEN_REFILL_ADDR \ +WF_PLE_TOP_VOW_CONTROL_ADDR +#define WF_PLE_TOP_VOW_CONTROL_ENABLE_TOKEN_REFILL_MASK \ +0x40000000 /* ENABLE_TOKEN_REFILL[30] */ +#define WF_PLE_TOP_VOW_CONTROL_ENABLE_TOKEN_REFILL_SHFT 30 +#define WF_PLE_TOP_VOW_CONTROL_ENABLE_AIRTIME_FAIRNESS_ADDR \ +WF_PLE_TOP_VOW_CONTROL_ADDR +#define WF_PLE_TOP_VOW_CONTROL_ENABLE_AIRTIME_FAIRNESS_MASK \ +0x20000000 /* ENABLE_AIRTIME_FAIRNESS[29] */ +#define WF_PLE_TOP_VOW_CONTROL_ENABLE_AIRTIME_FAIRNESS_SHFT 29 +#define WF_PLE_TOP_VOW_CONTROL_ENABLE_TXOP_NO_CHANGE_BSS_GROUP_ADDR \ +WF_PLE_TOP_VOW_CONTROL_ADDR +#define WF_PLE_TOP_VOW_CONTROL_ENABLE_TXOP_NO_CHANGE_BSS_GROUP_MASK \ +0x10000000 /* ENABLE_TXOP_NO_CHANGE_BSS_GROUP[28] */ +#define WF_PLE_TOP_VOW_CONTROL_ENABLE_TXOP_NO_CHANGE_BSS_GROUP_SHFT 28 +#define WF_PLE_TOP_VOW_CONTROL_DIS_WTBL_PS_IGNORE_ADDR \ +WF_PLE_TOP_VOW_CONTROL_ADDR +#define WF_PLE_TOP_VOW_CONTROL_DIS_WTBL_PS_IGNORE_MASK \ +0x08000000 /* DIS_WTBL_PS_IGNORE[27] */ +#define WF_PLE_TOP_VOW_CONTROL_DIS_WTBL_PS_IGNORE_SHFT 27 +#define WF_PLE_TOP_VOW_CONTROL_DRR_LOGIC_RESET_ADDR WF_PLE_TOP_VOW_CONTROL_ADDR +#define WF_PLE_TOP_VOW_CONTROL_DRR_LOGIC_RESET_MASK \ +0x04000000 /* DRR_LOGIC_RESET[26] */ +#define WF_PLE_TOP_VOW_CONTROL_DRR_LOGIC_RESET_SHFT 26 +#define WF_PLE_TOP_VOW_CONTROL_DBDC0_SEARCH_RULE_ADDR \ +WF_PLE_TOP_VOW_CONTROL_ADDR +#define WF_PLE_TOP_VOW_CONTROL_DBDC0_SEARCH_RULE_MASK \ +0x00200000 /* DBDC0_SEARCH_RULE[21] */ +#define WF_PLE_TOP_VOW_CONTROL_DBDC0_SEARCH_RULE_SHFT 21 +#define WF_PLE_TOP_VOW_CONTROL_DBDC1_SEARCH_RULE_ADDR \ +WF_PLE_TOP_VOW_CONTROL_ADDR +#define WF_PLE_TOP_VOW_CONTROL_DBDC1_SEARCH_RULE_MASK \ +0x00100000 /* DBDC1_SEARCH_RULE[20] */ +#define WF_PLE_TOP_VOW_CONTROL_DBDC1_SEARCH_RULE_SHFT 20 +#define WF_PLE_TOP_VOW_CONTROL_REFILL_PERIOD_ADDR WF_PLE_TOP_VOW_CONTROL_ADDR +#define WF_PLE_TOP_VOW_CONTROL_REFILL_PERIOD_MASK \ +0x00070000 /* REFILL_PERIOD[18..16] */ +#define WF_PLE_TOP_VOW_CONTROL_REFILL_PERIOD_SHFT 16 +#define WF_PLE_TOP_VOW_CONTROL_PER_BSS_BW_CONTROL_ENABLE_ADDR \ +WF_PLE_TOP_VOW_CONTROL_ADDR +#define WF_PLE_TOP_VOW_CONTROL_PER_BSS_BW_CONTROL_ENABLE_MASK \ +0x0000FFFF /* PER_BSS_BW_CONTROL_ENABLE[15..0] */ +#define WF_PLE_TOP_VOW_CONTROL_PER_BSS_BW_CONTROL_ENABLE_SHFT 0 + +/* +* ---AIRTIME_DRR_SIZE (0x820C0000 + 0x374)--- +* AIRTIME_DEFICIT_BOUNDARY[7..0] - (RW) Limits airtime DRR's maximum deficit +* Unit: 256us +* RESERVED2[15..8] - (RW) xxx +* BW_DEFICIT_BOUNDARY[23..16] - (RW) Limits BW DRR's maximum deficit +* Unit: 256us +* DRR_TXCNT_SIZE[31..24] - (RW) Tx count mode charge time setting +* Unit: 256us +*/ +#define WF_PLE_TOP_AIRTIME_DRR_SIZE_DRR_TXCNT_SIZE_ADDR \ +WF_PLE_TOP_AIRTIME_DRR_SIZE_ADDR +#define WF_PLE_TOP_AIRTIME_DRR_SIZE_DRR_TXCNT_SIZE_MASK \ +0xFF000000 /* DRR_TXCNT_SIZE[31..24] */ +#define WF_PLE_TOP_AIRTIME_DRR_SIZE_DRR_TXCNT_SIZE_SHFT 24 +#define WF_PLE_TOP_AIRTIME_DRR_SIZE_BW_DEFICIT_BOUNDARY_ADDR \ +WF_PLE_TOP_AIRTIME_DRR_SIZE_ADDR +#define WF_PLE_TOP_AIRTIME_DRR_SIZE_BW_DEFICIT_BOUNDARY_MASK \ +0x00FF0000 /* BW_DEFICIT_BOUNDARY[23..16] */ +#define WF_PLE_TOP_AIRTIME_DRR_SIZE_BW_DEFICIT_BOUNDARY_SHFT 16 +#define WF_PLE_TOP_AIRTIME_DRR_SIZE_RESERVED2_ADDR \ +WF_PLE_TOP_AIRTIME_DRR_SIZE_ADDR +#define WF_PLE_TOP_AIRTIME_DRR_SIZE_RESERVED2_MASK \ +0x0000FF00 /* RESERVED2[15..8] */ +#define WF_PLE_TOP_AIRTIME_DRR_SIZE_RESERVED2_SHFT 8 +#define WF_PLE_TOP_AIRTIME_DRR_SIZE_AIRTIME_DEFICIT_BOUNDARY_ADDR \ +WF_PLE_TOP_AIRTIME_DRR_SIZE_ADDR +#define WF_PLE_TOP_AIRTIME_DRR_SIZE_AIRTIME_DEFICIT_BOUNDARY_MASK \ +0x000000FF /* AIRTIME_DEFICIT_BOUNDARY[7..0] */ +#define WF_PLE_TOP_AIRTIME_DRR_SIZE_AIRTIME_DEFICIT_BOUNDARY_SHFT 0 + +/* +* ---CHECK_BW_TIME_TOKEN_ (0x820C0000 + 0x378)--- +* DISABLE_BW_TIME_CHECK[15..0] - (RW) HW will ignore time token status. +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_CHECK_BW_TIME_TOKEN__DISABLE_BW_TIME_CHECK_ADDR \ +WF_PLE_TOP_CHECK_BW_TIME_TOKEN__ADDR +#define WF_PLE_TOP_CHECK_BW_TIME_TOKEN__DISABLE_BW_TIME_CHECK_MASK \ +0x0000FFFF /* DISABLE_BW_TIME_CHECK[15..0] */ +#define WF_PLE_TOP_CHECK_BW_TIME_TOKEN__DISABLE_BW_TIME_CHECK_SHFT 0 + +/* +* ---CHECK_BW_LENGTH_TOKEN_ (0x820C0000 + 0x37c)--- +* DISABLE_BW_LENGTH_CHECK[15..0] - (RW) HW will ignore time token status. +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_CHECK_BW_LENGTH_TOKEN__DISABLE_BW_LENGTH_CHECK_ADDR \ +WF_PLE_TOP_CHECK_BW_LENGTH_TOKEN__ADDR +#define WF_PLE_TOP_CHECK_BW_LENGTH_TOKEN__DISABLE_BW_LENGTH_CHECK_MASK \ +0x0000FFFF /* DISABLE_BW_LENGTH_CHECK[15..0] */ +#define WF_PLE_TOP_CHECK_BW_LENGTH_TOKEN__DISABLE_BW_LENGTH_CHECK_SHFT 0 + +/* +* ---AIRTIME_QUANTUM_SETTING0 (0x820C0000 + 0x380)--- +* AIRTIME_QUANTUM0[7..0] - (RW) Airtime quantum 0 +* AIRTIME_QUANTUM1[15..8] - (RW) Airtime quantum 1 +* AIRTIME_QUANTUM2[23..16] - (RW) Airtime quantum 2 +* AIRTIME_QUANTUM3[31..24] - (RW) Airtime quantum 3 +*/ +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_AIRTIME_QUANTUM3_ADDR \ +WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_ADDR +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_AIRTIME_QUANTUM3_MASK \ +0xFF000000 /* AIRTIME_QUANTUM3[31..24] */ +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_AIRTIME_QUANTUM3_SHFT 24 +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_AIRTIME_QUANTUM2_ADDR \ +WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_ADDR +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_AIRTIME_QUANTUM2_MASK \ +0x00FF0000 /* AIRTIME_QUANTUM2[23..16] */ +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_AIRTIME_QUANTUM2_SHFT 16 +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_AIRTIME_QUANTUM1_ADDR \ +WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_ADDR +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_AIRTIME_QUANTUM1_MASK \ +0x0000FF00 /* AIRTIME_QUANTUM1[15..8] */ +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_AIRTIME_QUANTUM1_SHFT 8 +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_AIRTIME_QUANTUM0_ADDR \ +WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_ADDR +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_AIRTIME_QUANTUM0_MASK \ +0x000000FF /* AIRTIME_QUANTUM0[7..0] */ +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_AIRTIME_QUANTUM0_SHFT 0 + +/* +* ---AIRTIME_QUANTUM_SETTING1 (0x820C0000 + 0x384)--- +* AIRTIME_QUANTUM4[7..0] - (RW) Airtime quantum 4 +* AIRTIME_QUANTUM5[15..8] - (RW) Airtime quantum 5 +* AIRTIME_QUANTUM6[23..16] - (RW) Airtime quantum 6 +* AIRTIME_QUANTUM7[31..24] - (RW) Airtime quantum 7 +*/ +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_AIRTIME_QUANTUM7_ADDR \ +WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_ADDR +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_AIRTIME_QUANTUM7_MASK \ +0xFF000000 /* AIRTIME_QUANTUM7[31..24] */ +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_AIRTIME_QUANTUM7_SHFT 24 +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_AIRTIME_QUANTUM6_ADDR \ +WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_ADDR +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_AIRTIME_QUANTUM6_MASK \ +0x00FF0000 /* AIRTIME_QUANTUM6[23..16] */ +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_AIRTIME_QUANTUM6_SHFT 16 +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_AIRTIME_QUANTUM5_ADDR \ +WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_ADDR +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_AIRTIME_QUANTUM5_MASK \ +0x0000FF00 /* AIRTIME_QUANTUM5[15..8] */ +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_AIRTIME_QUANTUM5_SHFT 8 +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_AIRTIME_QUANTUM4_ADDR \ +WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_ADDR +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_AIRTIME_QUANTUM4_MASK \ +0x000000FF /* AIRTIME_QUANTUM4[7..0] */ +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_AIRTIME_QUANTUM4_SHFT 0 + +/* +* ---DRR_TABLE_CTRL (0x820C0000 + 0x388)--- +* INDEX[11..0] - (RW) Operation index +* Mode 0x00: DRR STA link, STA relay +* Bit[1:0]: qid +* Bit[10:2]: Station ID +//-- +* Mode 0x20: addr[6:0] mean station ID +* Mode 0x21: addr[6:0] mean station ID +* Mode 0x22: SRAM idx (debug mode) +* Mode 0x23: SRAM idx (debug mode) +* 0~35: STA bitmap +* 36~51: STA setting +//-- +* Mode 0x40: addr[3:0] = bssid, +* Mode 0x41: addr[3:0] = bssid, +* Mode 0x42: addr[3:0] = bssid, +* Mode 0x43: addr[3:0] = bssid, +* Mode 0x44: SRAM idx (debug mode) +* Mode 0x45: SRAM idx (debug mode) +* 0~15: BSS bitmap +* 16~31: BSS setting +* 32~47: Token status +//-- +* Mode 0x81~0x83: addr[3:0] = BSS group ID +* Bit[0]: Charge bw_token +* Bit[1]: Charge bw DRR +* Mode 0x84: addr[7:0] = station ID, +* addr[11:8]= qid +* Bit[2]: Charge airtime DRR +* Bit[3]: Charge is ADD mode +* WRITE_MASK[15..12] - (RW) DRR table will not be updated if mask +* write bits are enabled. +* MODE[23..16] - (RW) Operation mode for DRR table +* WRITE_MASK_2[27..24] - (RW) DRR table will not be updated if mask +* write bits are enabled. +* RESERVED28[30..28] - (RO) Reserved bits +* EXECUTE[31] - (RW) Excutes SW command to read/write DRR +table +*/ +#define WF_PLE_TOP_DRR_TABLE_CTRL_EXECUTE_ADDR WF_PLE_TOP_DRR_TABLE_CTRL_ADDR +#define WF_PLE_TOP_DRR_TABLE_CTRL_EXECUTE_MASK 0x80000000 /* EXECUTE[31] */ +#define WF_PLE_TOP_DRR_TABLE_CTRL_EXECUTE_SHFT 31 +#define WF_PLE_TOP_DRR_TABLE_CTRL_WRITE_MASK_2_ADDR \ +WF_PLE_TOP_DRR_TABLE_CTRL_ADDR +#define WF_PLE_TOP_DRR_TABLE_CTRL_WRITE_MASK_2_MASK \ +0x0F000000 /* WRITE_MASK_2[27..24] */ +#define WF_PLE_TOP_DRR_TABLE_CTRL_WRITE_MASK_2_SHFT 24 +#define WF_PLE_TOP_DRR_TABLE_CTRL_MODE_ADDR WF_PLE_TOP_DRR_TABLE_CTRL_ADDR +#define WF_PLE_TOP_DRR_TABLE_CTRL_MODE_MASK 0x00FF0000 /* MODE[23..16] */ +#define WF_PLE_TOP_DRR_TABLE_CTRL_MODE_SHFT 16 +#define WF_PLE_TOP_DRR_TABLE_CTRL_WRITE_MASK_ADDR WF_PLE_TOP_DRR_TABLE_CTRL_ADDR +#define WF_PLE_TOP_DRR_TABLE_CTRL_WRITE_MASK_MASK \ +0x0000F000 /* WRITE_MASK[15..12] */ +#define WF_PLE_TOP_DRR_TABLE_CTRL_WRITE_MASK_SHFT 12 +#define WF_PLE_TOP_DRR_TABLE_CTRL_INDEX_ADDR WF_PLE_TOP_DRR_TABLE_CTRL_ADDR +#define WF_PLE_TOP_DRR_TABLE_CTRL_INDEX_MASK 0x00000FFF /* INDEX[11..0] */ +#define WF_PLE_TOP_DRR_TABLE_CTRL_INDEX_SHFT 0 + +/* +* ---VOW_CTRL1 (0x820C0000 + 0x38C)--- +* RESERVED0[0] - (RO) Reserved bits +* EN_BSSID_CHECK[1] - (RW) Enable control of check BSSID's trap +* state in search station +* EN_LOCK_STA[2] - (RW) Lock mode for RTS retry same sta until +* RTS drop +* EN_KEEP_QTM[3] - (RW) Not reset remain Tx time when sta has +* new packet +* EN_TXCNT_MODE[4] - (RW) Tx count weighted round robin control +* EN_TXED_MODE[5] - (RW) Txed bitmap control +* EN_RXSCH_MODE[6] - (RW) Rx scheduling with rx earlyend bitmap +control +* EN_BWRF_SRCH[7] - (RW) Bandwidth refill search control +* DIS_BSSID0_TRAP_IGNORE[8] - (RW) Disable control of the function that STA +* with BSSID0 trap ignore in TXQ busy +* DIS_BSSID1_TRAP_IGNORE[9] - (RW) Disable control of the function that STA +* with BSSID1 trap ignore in TXQ busy +* DIS_BSSID2_TRAP_IGNORE[10] - (RW) Disable control of the function that STA +* with BSSID2 trap ignore in TXQ busy +* DIS_BSSID3_TRAP_IGNORE[11] - (RW) Disable control of the function that STA +* with BSSID3 trap ignore in TXQ busy +* DIS_KEEP_TRGT_BSS[12] - (RW) Disable control of keeping BSS as target +* station when SPL search +* SPL_SW_BSR_STALINK[13] - (RW) SW add/remove uplink station control +* SPL_RUNN_EN[14] - (RW) Over run 1 station search control +* RESERVED15[31..15] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_VOW_CTRL1_SPL_RUNN_EN_ADDR WF_PLE_TOP_VOW_CTRL1_ADDR +#define WF_PLE_TOP_VOW_CTRL1_SPL_RUNN_EN_MASK 0x00004000 /* SPL_RUNN_EN[14] */ +#define WF_PLE_TOP_VOW_CTRL1_SPL_RUNN_EN_SHFT 14 +#define WF_PLE_TOP_VOW_CTRL1_SPL_SW_BSR_STALINK_ADDR WF_PLE_TOP_VOW_CTRL1_ADDR +#define WF_PLE_TOP_VOW_CTRL1_SPL_SW_BSR_STALINK_MASK \ +0x00002000 /* SPL_SW_BSR_STALINK[13] */ +#define WF_PLE_TOP_VOW_CTRL1_SPL_SW_BSR_STALINK_SHFT 13 +#define WF_PLE_TOP_VOW_CTRL1_DIS_KEEP_TRGT_BSS_ADDR WF_PLE_TOP_VOW_CTRL1_ADDR +#define WF_PLE_TOP_VOW_CTRL1_DIS_KEEP_TRGT_BSS_MASK \ +0x00001000 /* DIS_KEEP_TRGT_BSS[12] */ +#define WF_PLE_TOP_VOW_CTRL1_DIS_KEEP_TRGT_BSS_SHFT 12 +#define WF_PLE_TOP_VOW_CTRL1_DIS_BSSID3_TRAP_IGNORE_ADDR \ +WF_PLE_TOP_VOW_CTRL1_ADDR +#define WF_PLE_TOP_VOW_CTRL1_DIS_BSSID3_TRAP_IGNORE_MASK \ +0x00000800 /* DIS_BSSID3_TRAP_IGNORE[11] */ +#define WF_PLE_TOP_VOW_CTRL1_DIS_BSSID3_TRAP_IGNORE_SHFT 11 +#define WF_PLE_TOP_VOW_CTRL1_DIS_BSSID2_TRAP_IGNORE_ADDR \ +WF_PLE_TOP_VOW_CTRL1_ADDR +#define WF_PLE_TOP_VOW_CTRL1_DIS_BSSID2_TRAP_IGNORE_MASK \ +0x00000400 /* DIS_BSSID2_TRAP_IGNORE[10] */ +#define WF_PLE_TOP_VOW_CTRL1_DIS_BSSID2_TRAP_IGNORE_SHFT 10 +#define WF_PLE_TOP_VOW_CTRL1_DIS_BSSID1_TRAP_IGNORE_ADDR \ +WF_PLE_TOP_VOW_CTRL1_ADDR +#define WF_PLE_TOP_VOW_CTRL1_DIS_BSSID1_TRAP_IGNORE_MASK \ +0x00000200 /* DIS_BSSID1_TRAP_IGNORE[9] */ +#define WF_PLE_TOP_VOW_CTRL1_DIS_BSSID1_TRAP_IGNORE_SHFT 9 +#define WF_PLE_TOP_VOW_CTRL1_DIS_BSSID0_TRAP_IGNORE_ADDR \ +WF_PLE_TOP_VOW_CTRL1_ADDR +#define WF_PLE_TOP_VOW_CTRL1_DIS_BSSID0_TRAP_IGNORE_MASK \ +0x00000100 /* DIS_BSSID0_TRAP_IGNORE[8] */ +#define WF_PLE_TOP_VOW_CTRL1_DIS_BSSID0_TRAP_IGNORE_SHFT 8 +#define WF_PLE_TOP_VOW_CTRL1_EN_BWRF_SRCH_ADDR WF_PLE_TOP_VOW_CTRL1_ADDR +#define WF_PLE_TOP_VOW_CTRL1_EN_BWRF_SRCH_MASK 0x00000080 /* EN_BWRF_SRCH[7] \ + */ +#define WF_PLE_TOP_VOW_CTRL1_EN_BWRF_SRCH_SHFT 7 +#define WF_PLE_TOP_VOW_CTRL1_EN_RXSCH_MODE_ADDR WF_PLE_TOP_VOW_CTRL1_ADDR +#define WF_PLE_TOP_VOW_CTRL1_EN_RXSCH_MODE_MASK \ +0x00000040 /* EN_RXSCH_MODE[6] */ +#define WF_PLE_TOP_VOW_CTRL1_EN_RXSCH_MODE_SHFT 6 +#define WF_PLE_TOP_VOW_CTRL1_EN_TXED_MODE_ADDR WF_PLE_TOP_VOW_CTRL1_ADDR +#define WF_PLE_TOP_VOW_CTRL1_EN_TXED_MODE_MASK 0x00000020 /* EN_TXED_MODE[5] \ + */ +#define WF_PLE_TOP_VOW_CTRL1_EN_TXED_MODE_SHFT 5 +#define WF_PLE_TOP_VOW_CTRL1_EN_TXCNT_MODE_ADDR WF_PLE_TOP_VOW_CTRL1_ADDR +#define WF_PLE_TOP_VOW_CTRL1_EN_TXCNT_MODE_MASK \ +0x00000010 /* EN_TXCNT_MODE[4] */ +#define WF_PLE_TOP_VOW_CTRL1_EN_TXCNT_MODE_SHFT 4 +#define WF_PLE_TOP_VOW_CTRL1_EN_KEEP_QTM_ADDR WF_PLE_TOP_VOW_CTRL1_ADDR +#define WF_PLE_TOP_VOW_CTRL1_EN_KEEP_QTM_MASK 0x00000008 /* EN_KEEP_QTM[3] */ +#define WF_PLE_TOP_VOW_CTRL1_EN_KEEP_QTM_SHFT 3 +#define WF_PLE_TOP_VOW_CTRL1_EN_LOCK_STA_ADDR WF_PLE_TOP_VOW_CTRL1_ADDR +#define WF_PLE_TOP_VOW_CTRL1_EN_LOCK_STA_MASK 0x00000004 /* EN_LOCK_STA[2] */ +#define WF_PLE_TOP_VOW_CTRL1_EN_LOCK_STA_SHFT 2 +#define WF_PLE_TOP_VOW_CTRL1_EN_BSSID_CHECK_ADDR WF_PLE_TOP_VOW_CTRL1_ADDR +#define WF_PLE_TOP_VOW_CTRL1_EN_BSSID_CHECK_MASK \ +0x00000002 /* EN_BSSID_CHECK[1] */ +#define WF_PLE_TOP_VOW_CTRL1_EN_BSSID_CHECK_SHFT 1 + +/* +* ---DRR_CHNL_EMPTY (0x820C0000 + 0x390)--- +* WMM_STA_DL_EMPTY[15..0] - (RO) Indicate emptiness of 16 DL station link +* WMM_STA_UL_EMPTY[31..16] - (RO) Indicate emptiness of 16 UL station link +*/ +#define WF_PLE_TOP_DRR_CHNL_EMPTY_WMM_STA_UL_EMPTY_ADDR \ +WF_PLE_TOP_DRR_CHNL_EMPTY_ADDR +#define WF_PLE_TOP_DRR_CHNL_EMPTY_WMM_STA_UL_EMPTY_MASK \ +0xFFFF0000 /* WMM_STA_UL_EMPTY[31..16] */ +#define WF_PLE_TOP_DRR_CHNL_EMPTY_WMM_STA_UL_EMPTY_SHFT 16 +#define WF_PLE_TOP_DRR_CHNL_EMPTY_WMM_STA_DL_EMPTY_ADDR \ +WF_PLE_TOP_DRR_CHNL_EMPTY_ADDR +#define WF_PLE_TOP_DRR_CHNL_EMPTY_WMM_STA_DL_EMPTY_MASK \ +0x0000FFFF /* WMM_STA_DL_EMPTY[15..0] */ +#define WF_PLE_TOP_DRR_CHNL_EMPTY_WMM_STA_DL_EMPTY_SHFT 0 + +/* +* ---DRR_SPL_CTRL (0x820C0000 + 0x394)--- +* SPL_EM2NEM_SRCH_DL_EN[15..0] - (RW) DL empty-to-nonempty search event +* trigger control +* SUBRND_TIMES[19..16] - (RW) Subround times setting to trigger round +end +* EN_SBTG_RNDEND[20] - (RW) Enable control of round ends by subround +times +* EN_QLEN_TH[21] - (RW) Enable control of queue length +* constraint to select station +* EN_ARB_CUT_IN[22] - (RW) Enable control of SPL search interrupt +* in TXD/TXCMD concurrent mode +* EN_SPL_MERGE[23] - (RW) Enable SPL merge mode with DL and UL +* station list +* SPL_STA_NUM[31..24] - (RW) SPL station number. Must equal to or +* larger than 1 +*/ +#define WF_PLE_TOP_DRR_SPL_CTRL_SPL_STA_NUM_ADDR WF_PLE_TOP_DRR_SPL_CTRL_ADDR +#define WF_PLE_TOP_DRR_SPL_CTRL_SPL_STA_NUM_MASK \ +0xFF000000 /* SPL_STA_NUM[31..24] */ +#define WF_PLE_TOP_DRR_SPL_CTRL_SPL_STA_NUM_SHFT 24 +#define WF_PLE_TOP_DRR_SPL_CTRL_EN_SPL_MERGE_ADDR WF_PLE_TOP_DRR_SPL_CTRL_ADDR +#define WF_PLE_TOP_DRR_SPL_CTRL_EN_SPL_MERGE_MASK \ +0x00800000 /* EN_SPL_MERGE[23] */ +#define WF_PLE_TOP_DRR_SPL_CTRL_EN_SPL_MERGE_SHFT 23 +#define WF_PLE_TOP_DRR_SPL_CTRL_EN_ARB_CUT_IN_ADDR WF_PLE_TOP_DRR_SPL_CTRL_ADDR +#define WF_PLE_TOP_DRR_SPL_CTRL_EN_ARB_CUT_IN_MASK \ +0x00400000 /* EN_ARB_CUT_IN[22] */ +#define WF_PLE_TOP_DRR_SPL_CTRL_EN_ARB_CUT_IN_SHFT 22 +#define WF_PLE_TOP_DRR_SPL_CTRL_EN_QLEN_TH_ADDR WF_PLE_TOP_DRR_SPL_CTRL_ADDR +#define WF_PLE_TOP_DRR_SPL_CTRL_EN_QLEN_TH_MASK 0x00200000 /* EN_QLEN_TH[21] \ + */ +#define WF_PLE_TOP_DRR_SPL_CTRL_EN_QLEN_TH_SHFT 21 +#define WF_PLE_TOP_DRR_SPL_CTRL_EN_SBTG_RNDEND_ADDR WF_PLE_TOP_DRR_SPL_CTRL_ADDR +#define WF_PLE_TOP_DRR_SPL_CTRL_EN_SBTG_RNDEND_MASK \ +0x00100000 /* EN_SBTG_RNDEND[20] */ +#define WF_PLE_TOP_DRR_SPL_CTRL_EN_SBTG_RNDEND_SHFT 20 +#define WF_PLE_TOP_DRR_SPL_CTRL_SUBRND_TIMES_ADDR WF_PLE_TOP_DRR_SPL_CTRL_ADDR +#define WF_PLE_TOP_DRR_SPL_CTRL_SUBRND_TIMES_MASK \ +0x000F0000 /* SUBRND_TIMES[19..16] */ +#define WF_PLE_TOP_DRR_SPL_CTRL_SUBRND_TIMES_SHFT 16 +#define WF_PLE_TOP_DRR_SPL_CTRL_SPL_EM2NEM_SRCH_DL_EN_ADDR \ +WF_PLE_TOP_DRR_SPL_CTRL_ADDR +#define WF_PLE_TOP_DRR_SPL_CTRL_SPL_EM2NEM_SRCH_DL_EN_MASK \ +0x0000FFFF /* SPL_EM2NEM_SRCH_DL_EN[15..0] */ +#define WF_PLE_TOP_DRR_SPL_CTRL_SPL_EM2NEM_SRCH_DL_EN_SHFT 0 + +/* +* ---DRR_SPL_CTRL_1 (0x820C0000 + 0x398)--- +* SPL_EM2NEM_SRCH_UL_EN[15..0] - (RW) UL empty-to-nonempty search event +* trigger control +* EN_BWRF_FILTER[16] - (RW) BW refill mode SPL with NE=1 STA_CNT=0 +* filter enable control +* EN_BWCHRG_ORIG[17] - (RW) BW charge original scheme enable control +* RESERVED18[19..18] - (RO) Reserved bits +* EN_PS_CHG_SPL_GEN[20] - (RW) PS change SPL generation control. +* EN_PS_CHG_CHK_AC_EMPTY[21] - (RW) Enable control of STA AC queue empty +* check for PS change SPL generation. +* EN_PS_CHG_CHK_TXCMD_EMPTY[22] - (RW) Enable control of TXCMD queue empty +* check for PS change SPL generation. +* EN_PS_CHG_SPL_MERGE[23] - (RW) Enable PS change SPL merge mode with DL +* and UL station list. +* EN_PS_CHG_SPL_KEEP_PAUSE[24] - (RW) Enable control for PLE Station pause in +* PS change SPL generation. +* RESERVED25[31..25] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_DRR_SPL_CTRL_1_EN_PS_CHG_SPL_KEEP_PAUSE_ADDR \ +WF_PLE_TOP_DRR_SPL_CTRL_1_ADDR +#define WF_PLE_TOP_DRR_SPL_CTRL_1_EN_PS_CHG_SPL_KEEP_PAUSE_MASK \ +0x01000000 /* EN_PS_CHG_SPL_KEEP_PAUSE[24] */ +#define WF_PLE_TOP_DRR_SPL_CTRL_1_EN_PS_CHG_SPL_KEEP_PAUSE_SHFT 24 +#define WF_PLE_TOP_DRR_SPL_CTRL_1_EN_PS_CHG_SPL_MERGE_ADDR \ +WF_PLE_TOP_DRR_SPL_CTRL_1_ADDR +#define WF_PLE_TOP_DRR_SPL_CTRL_1_EN_PS_CHG_SPL_MERGE_MASK \ +0x00800000 /* EN_PS_CHG_SPL_MERGE[23] */ +#define WF_PLE_TOP_DRR_SPL_CTRL_1_EN_PS_CHG_SPL_MERGE_SHFT 23 +#define WF_PLE_TOP_DRR_SPL_CTRL_1_EN_PS_CHG_CHK_TXCMD_EMPTY_ADDR \ +WF_PLE_TOP_DRR_SPL_CTRL_1_ADDR +#define WF_PLE_TOP_DRR_SPL_CTRL_1_EN_PS_CHG_CHK_TXCMD_EMPTY_MASK \ +0x00400000 /* EN_PS_CHG_CHK_TXCMD_EMPTY[22] */ +#define WF_PLE_TOP_DRR_SPL_CTRL_1_EN_PS_CHG_CHK_TXCMD_EMPTY_SHFT 22 +#define WF_PLE_TOP_DRR_SPL_CTRL_1_EN_PS_CHG_CHK_AC_EMPTY_ADDR \ +WF_PLE_TOP_DRR_SPL_CTRL_1_ADDR +#define WF_PLE_TOP_DRR_SPL_CTRL_1_EN_PS_CHG_CHK_AC_EMPTY_MASK \ +0x00200000 /* EN_PS_CHG_CHK_AC_EMPTY[21] */ +#define WF_PLE_TOP_DRR_SPL_CTRL_1_EN_PS_CHG_CHK_AC_EMPTY_SHFT 21 +#define WF_PLE_TOP_DRR_SPL_CTRL_1_EN_PS_CHG_SPL_GEN_ADDR \ +WF_PLE_TOP_DRR_SPL_CTRL_1_ADDR +#define WF_PLE_TOP_DRR_SPL_CTRL_1_EN_PS_CHG_SPL_GEN_MASK \ +0x00100000 /* EN_PS_CHG_SPL_GEN[20] */ +#define WF_PLE_TOP_DRR_SPL_CTRL_1_EN_PS_CHG_SPL_GEN_SHFT 20 +#define WF_PLE_TOP_DRR_SPL_CTRL_1_EN_BWCHRG_ORIG_ADDR \ +WF_PLE_TOP_DRR_SPL_CTRL_1_ADDR +#define WF_PLE_TOP_DRR_SPL_CTRL_1_EN_BWCHRG_ORIG_MASK \ +0x00020000 /* EN_BWCHRG_ORIG[17] */ +#define WF_PLE_TOP_DRR_SPL_CTRL_1_EN_BWCHRG_ORIG_SHFT 17 +#define WF_PLE_TOP_DRR_SPL_CTRL_1_EN_BWRF_FILTER_ADDR \ +WF_PLE_TOP_DRR_SPL_CTRL_1_ADDR +#define WF_PLE_TOP_DRR_SPL_CTRL_1_EN_BWRF_FILTER_MASK \ +0x00010000 /* EN_BWRF_FILTER[16] */ +#define WF_PLE_TOP_DRR_SPL_CTRL_1_EN_BWRF_FILTER_SHFT 16 +#define WF_PLE_TOP_DRR_SPL_CTRL_1_SPL_EM2NEM_SRCH_UL_EN_ADDR \ +WF_PLE_TOP_DRR_SPL_CTRL_1_ADDR +#define WF_PLE_TOP_DRR_SPL_CTRL_1_SPL_EM2NEM_SRCH_UL_EN_MASK \ +0x0000FFFF /* SPL_EM2NEM_SRCH_UL_EN[15..0] */ +#define WF_PLE_TOP_DRR_SPL_CTRL_1_SPL_EM2NEM_SRCH_UL_EN_SHFT 0 + +/* +* ---VOW_DBG_SEL (0x820C0000 + 0x3A0)--- +* AIRTIME_DEBUG_SEL[15..0] - (RW) Selects airtime debug +* BW_DEBUG_SEL[31..16] - (RW) Selects BW control debug +*/ +#define WF_PLE_TOP_VOW_DBG_SEL_BW_DEBUG_SEL_ADDR WF_PLE_TOP_VOW_DBG_SEL_ADDR +#define WF_PLE_TOP_VOW_DBG_SEL_BW_DEBUG_SEL_MASK \ +0xFFFF0000 /* BW_DEBUG_SEL[31..16] */ +#define WF_PLE_TOP_VOW_DBG_SEL_BW_DEBUG_SEL_SHFT 16 +#define WF_PLE_TOP_VOW_DBG_SEL_AIRTIME_DEBUG_SEL_ADDR \ +WF_PLE_TOP_VOW_DBG_SEL_ADDR +#define WF_PLE_TOP_VOW_DBG_SEL_AIRTIME_DEBUG_SEL_MASK \ +0x0000FFFF /* AIRTIME_DEBUG_SEL[15..0] */ +#define WF_PLE_TOP_VOW_DBG_SEL_AIRTIME_DEBUG_SEL_SHFT 0 + +/* +* ---AIRTIME_DBG_INFO0 (0x820C0000 + 0x3A4)--- +* AIRTIME_DBG_INFO0[31..0] - (RO) Station link head/tail +*/ +#define WF_PLE_TOP_AIRTIME_DBG_INFO0_AIRTIME_DBG_INFO0_ADDR \ +WF_PLE_TOP_AIRTIME_DBG_INFO0_ADDR +#define WF_PLE_TOP_AIRTIME_DBG_INFO0_AIRTIME_DBG_INFO0_MASK \ +0xFFFFFFFF /* AIRTIME_DBG_INFO0[31..0] */ +#define WF_PLE_TOP_AIRTIME_DBG_INFO0_AIRTIME_DBG_INFO0_SHFT 0 + +/* +* ---AIRTIME_DBG_INFO1 (0x820C0000 + 0x3A8)--- +* AIRTIME_DBG_INFO1[31..0] - (RO) Station link head/tail +*/ +#define WF_PLE_TOP_AIRTIME_DBG_INFO1_AIRTIME_DBG_INFO1_ADDR \ +WF_PLE_TOP_AIRTIME_DBG_INFO1_ADDR +#define WF_PLE_TOP_AIRTIME_DBG_INFO1_AIRTIME_DBG_INFO1_MASK \ +0xFFFFFFFF /* AIRTIME_DBG_INFO1[31..0] */ +#define WF_PLE_TOP_AIRTIME_DBG_INFO1_AIRTIME_DBG_INFO1_SHFT 0 + +/* +* ---BW_DBG_INFO (0x820C0000 + 0x3AC)--- +* BW_DBG_INFO1[31..0] - (RO) BSS link head/tail +*/ +#define WF_PLE_TOP_BW_DBG_INFO_BW_DBG_INFO1_ADDR WF_PLE_TOP_BW_DBG_INFO_ADDR +#define WF_PLE_TOP_BW_DBG_INFO_BW_DBG_INFO1_MASK \ +0xFFFFFFFF /* BW_DBG_INFO1[31..0] */ +#define WF_PLE_TOP_BW_DBG_INFO_BW_DBG_INFO1_SHFT 0 + +/* +* ---BW_GROUP_QUANTUM_SETTING0 (0x820C0000 + 0x3B0)--- +* BW_GROUP0_QUANTUM[7..0] - (RW) BW_GROUP0 quantum(BW control only) +* BW_GROUP1_QUANTUM[15..8] - (RW) BW_GROUP1 quantum(BW control only) +* BW_GROUP2_QUANTUM[23..16] - (RW) BW_GROUP2 quantum(BW control only) +* BW_GROUP3_QUANTUM[31..24] - (RW) BW_GROUP3 quantum(BW control only) +*/ +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING0_BW_GROUP3_QUANTUM_ADDR \ +WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING0_ADDR +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING0_BW_GROUP3_QUANTUM_MASK \ +0xFF000000 /* BW_GROUP3_QUANTUM[31..24] */ +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING0_BW_GROUP3_QUANTUM_SHFT 24 +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING0_BW_GROUP2_QUANTUM_ADDR \ +WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING0_ADDR +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING0_BW_GROUP2_QUANTUM_MASK \ +0x00FF0000 /* BW_GROUP2_QUANTUM[23..16] */ +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING0_BW_GROUP2_QUANTUM_SHFT 16 +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING0_BW_GROUP1_QUANTUM_ADDR \ +WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING0_ADDR +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING0_BW_GROUP1_QUANTUM_MASK \ +0x0000FF00 /* BW_GROUP1_QUANTUM[15..8] */ +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING0_BW_GROUP1_QUANTUM_SHFT 8 +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING0_BW_GROUP0_QUANTUM_ADDR \ +WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING0_ADDR +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING0_BW_GROUP0_QUANTUM_MASK \ +0x000000FF /* BW_GROUP0_QUANTUM[7..0] */ +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING0_BW_GROUP0_QUANTUM_SHFT 0 + +/* +* ---BW_GROUP_QUANTUM_SETTING1 (0x820C0000 + 0x3B4)--- +* BW_GROUP4_QUANTUM[7..0] - (RW) BW_GROUP4 quantum(BW control only) +* BW_GROUP5_QUANTUM[15..8] - (RW) BW_GROUP5 quantum(BW control only) +* BW_GROUP6_QUANTUM[23..16] - (RW) BW_GROUP6 quantum(BW control only) +* BW_GROUP7_QUANTUM[31..24] - (RW) BW_GROUP7 quantum(BW control only) +*/ +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING1_BW_GROUP7_QUANTUM_ADDR \ +WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING1_ADDR +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING1_BW_GROUP7_QUANTUM_MASK \ +0xFF000000 /* BW_GROUP7_QUANTUM[31..24] */ +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING1_BW_GROUP7_QUANTUM_SHFT 24 +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING1_BW_GROUP6_QUANTUM_ADDR \ +WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING1_ADDR +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING1_BW_GROUP6_QUANTUM_MASK \ +0x00FF0000 /* BW_GROUP6_QUANTUM[23..16] */ +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING1_BW_GROUP6_QUANTUM_SHFT 16 +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING1_BW_GROUP5_QUANTUM_ADDR \ +WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING1_ADDR +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING1_BW_GROUP5_QUANTUM_MASK \ +0x0000FF00 /* BW_GROUP5_QUANTUM[15..8] */ +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING1_BW_GROUP5_QUANTUM_SHFT 8 +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING1_BW_GROUP4_QUANTUM_ADDR \ +WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING1_ADDR +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING1_BW_GROUP4_QUANTUM_MASK \ +0x000000FF /* BW_GROUP4_QUANTUM[7..0] */ +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING1_BW_GROUP4_QUANTUM_SHFT 0 + +/* +* ---BW_GROUP_QUANTUM_SETTING2 (0x820C0000 + 0x3B8)--- +* BW_GROUP8_QUANTUM[7..0] - (RW) BW_GROUP8 quantum(BW control only) +* BW_GROUP9_QUANTUM[15..8] - (RW) BW_GROUP9 quantum(BW control only) +* BW_GROUP10_QUANTUM[23..16] - (RW) BW_GROUP10 quantum(BW control only) +* BW_GROUP11_QUANTUM[31..24] - (RW) BW_GROUP11 quantum(BW control only) +*/ +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING2_BW_GROUP11_QUANTUM_ADDR \ +WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING2_ADDR +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING2_BW_GROUP11_QUANTUM_MASK \ +0xFF000000 /* BW_GROUP11_QUANTUM[31..24] */ +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING2_BW_GROUP11_QUANTUM_SHFT 24 +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING2_BW_GROUP10_QUANTUM_ADDR \ +WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING2_ADDR +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING2_BW_GROUP10_QUANTUM_MASK \ +0x00FF0000 /* BW_GROUP10_QUANTUM[23..16] */ +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING2_BW_GROUP10_QUANTUM_SHFT 16 +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING2_BW_GROUP9_QUANTUM_ADDR \ +WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING2_ADDR +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING2_BW_GROUP9_QUANTUM_MASK \ +0x0000FF00 /* BW_GROUP9_QUANTUM[15..8] */ +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING2_BW_GROUP9_QUANTUM_SHFT 8 +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING2_BW_GROUP8_QUANTUM_ADDR \ +WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING2_ADDR +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING2_BW_GROUP8_QUANTUM_MASK \ +0x000000FF /* BW_GROUP8_QUANTUM[7..0] */ +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING2_BW_GROUP8_QUANTUM_SHFT 0 + +/* +* ---BW_GROUP_QUANTUM_SETTING3 (0x820C0000 + 0x3bc)--- +* BW_GROUP12_QUANTUM[7..0] - (RW) BW_GROUP12 quantum(BW control only) +* BW_GROUP13_QUANTUM[15..8] - (RW) BW_GROUP13 quantum(BW control only) +* BW_GROUP14_QUANTUM[23..16] - (RW) BW_GROUP14 quantum(BW control only) +* BW_GROUP15_QUANTUM[31..24] - (RW) BW_GROUP15 quantum(BW control only) +*/ +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING3_BW_GROUP15_QUANTUM_ADDR \ +WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING3_ADDR +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING3_BW_GROUP15_QUANTUM_MASK \ +0xFF000000 /* BW_GROUP15_QUANTUM[31..24] */ +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING3_BW_GROUP15_QUANTUM_SHFT 24 +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING3_BW_GROUP14_QUANTUM_ADDR \ +WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING3_ADDR +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING3_BW_GROUP14_QUANTUM_MASK \ +0x00FF0000 /* BW_GROUP14_QUANTUM[23..16] */ +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING3_BW_GROUP14_QUANTUM_SHFT 16 +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING3_BW_GROUP13_QUANTUM_ADDR \ +WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING3_ADDR +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING3_BW_GROUP13_QUANTUM_MASK \ +0x0000FF00 /* BW_GROUP13_QUANTUM[15..8] */ +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING3_BW_GROUP13_QUANTUM_SHFT 8 +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING3_BW_GROUP12_QUANTUM_ADDR \ +WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING3_ADDR +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING3_BW_GROUP12_QUANTUM_MASK \ +0x000000FF /* BW_GROUP12_QUANTUM[7..0] */ +#define WF_PLE_TOP_BW_GROUP_QUANTUM_SETTING3_BW_GROUP12_QUANTUM_SHFT 0 + +/* +* ---DRR_SW_CTRL (0x820C0000 + 0x3C8)--- +* INDEX[15..0] - (RW) Operation index +* Mode 0x00: Bit[15:12]: QID, Bit[9:0]: wlan +ID +* Mode 0x01: Bit[15:12]: QID, Bit[9:0]: wlan +ID +* Mode 0x10: Bit[3:0]: QID +* Mode 0x11: Bit[3:0]: QID +* MODE[23..16] - (RW) IO software command mode +* RESERVED24[29..24] - (RO) Reserved bits +* SRCH_CMD_DROP[30] - (W1C) IO search command drop flag due to +* command FIFO full +* EXECUTE[31] - (RW) Executes SW command to trigger search +* event and add/remove station +*/ +#define WF_PLE_TOP_DRR_SW_CTRL_EXECUTE_ADDR WF_PLE_TOP_DRR_SW_CTRL_ADDR +#define WF_PLE_TOP_DRR_SW_CTRL_EXECUTE_MASK 0x80000000 /* EXECUTE[31] */ +#define WF_PLE_TOP_DRR_SW_CTRL_EXECUTE_SHFT 31 +#define WF_PLE_TOP_DRR_SW_CTRL_SRCH_CMD_DROP_ADDR WF_PLE_TOP_DRR_SW_CTRL_ADDR +#define WF_PLE_TOP_DRR_SW_CTRL_SRCH_CMD_DROP_MASK \ +0x40000000 /* SRCH_CMD_DROP[30] */ +#define WF_PLE_TOP_DRR_SW_CTRL_SRCH_CMD_DROP_SHFT 30 +#define WF_PLE_TOP_DRR_SW_CTRL_MODE_ADDR WF_PLE_TOP_DRR_SW_CTRL_ADDR +#define WF_PLE_TOP_DRR_SW_CTRL_MODE_MASK 0x00FF0000 /* MODE[23..16] */ +#define WF_PLE_TOP_DRR_SW_CTRL_MODE_SHFT 16 +#define WF_PLE_TOP_DRR_SW_CTRL_INDEX_ADDR WF_PLE_TOP_DRR_SW_CTRL_ADDR +#define WF_PLE_TOP_DRR_SW_CTRL_INDEX_MASK 0x0000FFFF /* INDEX[15..0] */ +#define WF_PLE_TOP_DRR_SW_CTRL_INDEX_SHFT 0 + +/* +* ---DRR_HW_SRCHCMD_FULL (0x820C0000 + 0x3CC)--- +* CMD_FULL_CHNL_DL[15..0] - (RW) Hardware search command full flag of 16 +* backoff channel of downlink +* CMD_FULL_CHNL_UL[31..16] - (RW) Hardware search command full flag of 16 +* backoff channel of uplink +*/ +#define WF_PLE_TOP_DRR_HW_SRCHCMD_FULL_CMD_FULL_CHNL_UL_ADDR \ +WF_PLE_TOP_DRR_HW_SRCHCMD_FULL_ADDR +#define WF_PLE_TOP_DRR_HW_SRCHCMD_FULL_CMD_FULL_CHNL_UL_MASK \ +0xFFFF0000 /* CMD_FULL_CHNL_UL[31..16] */ +#define WF_PLE_TOP_DRR_HW_SRCHCMD_FULL_CMD_FULL_CHNL_UL_SHFT 16 +#define WF_PLE_TOP_DRR_HW_SRCHCMD_FULL_CMD_FULL_CHNL_DL_ADDR \ +WF_PLE_TOP_DRR_HW_SRCHCMD_FULL_ADDR +#define WF_PLE_TOP_DRR_HW_SRCHCMD_FULL_CMD_FULL_CHNL_DL_MASK \ +0x0000FFFF /* CMD_FULL_CHNL_DL[15..0] */ +#define WF_PLE_TOP_DRR_HW_SRCHCMD_FULL_CMD_FULL_CHNL_DL_SHFT 0 + +/* +* ---STATION_PAUSE0 (0x820C0000 + 0x400)--- +* STATION_PAUSE_0[31..0] - (RW) SW can stop station TX by this setting +* for STA0~STA31. +*/ +#define WF_PLE_TOP_STATION_PAUSE0_STATION_PAUSE_0_ADDR \ +WF_PLE_TOP_STATION_PAUSE0_ADDR +#define WF_PLE_TOP_STATION_PAUSE0_STATION_PAUSE_0_MASK \ +0xFFFFFFFF /* STATION_PAUSE_0[31..0] */ +#define WF_PLE_TOP_STATION_PAUSE0_STATION_PAUSE_0_SHFT 0 + +/* +* ---STATION_PAUSE1 (0x820C0000 + 0x404)--- +* STATION_PAUSE_1[31..0] - (RW) SW can stop station TX by this setting +* for STA32~STA63. +*/ +#define WF_PLE_TOP_STATION_PAUSE1_STATION_PAUSE_1_ADDR \ +WF_PLE_TOP_STATION_PAUSE1_ADDR +#define WF_PLE_TOP_STATION_PAUSE1_STATION_PAUSE_1_MASK \ +0xFFFFFFFF /* STATION_PAUSE_1[31..0] */ +#define WF_PLE_TOP_STATION_PAUSE1_STATION_PAUSE_1_SHFT 0 + +/* +* ---STATION_PAUSE2 (0x820C0000 + 0x408)--- +* STATION_PAUSE_2[31..0] - (RW) SW can stop station TX by this setting +* for STA64~STA95. +*/ +#define WF_PLE_TOP_STATION_PAUSE2_STATION_PAUSE_2_ADDR \ +WF_PLE_TOP_STATION_PAUSE2_ADDR +#define WF_PLE_TOP_STATION_PAUSE2_STATION_PAUSE_2_MASK \ +0xFFFFFFFF /* STATION_PAUSE_2[31..0] */ +#define WF_PLE_TOP_STATION_PAUSE2_STATION_PAUSE_2_SHFT 0 + +/* +* ---STATION_PAUSE3 (0x820C0000 + 0x40c)--- +* STATION_PAUSE_3[31..0] - (RW) SW can stop station TX by this setting +* for STA96~STA127. +*/ +#define WF_PLE_TOP_STATION_PAUSE3_STATION_PAUSE_3_ADDR \ +WF_PLE_TOP_STATION_PAUSE3_ADDR +#define WF_PLE_TOP_STATION_PAUSE3_STATION_PAUSE_3_MASK \ +0xFFFFFFFF /* STATION_PAUSE_3[31..0] */ +#define WF_PLE_TOP_STATION_PAUSE3_STATION_PAUSE_3_SHFT 0 + +/* +* ---STATION_PAUSE4 (0x820C0000 + 0x410)--- +* STATION_PAUSE_4_0[7..0] - (RW) SW can stop station TX by this setting +* for STA128~STA135. +* STATION_PAUSE_4_1[15..8] - (RW) SW can stop station TX by this setting +* for STA136~STA143. +* STATION_PAUSE_4_2[31..16] - (RW) SW can stop station TX by this setting +* for STA144~STA159. +*/ +#define WF_PLE_TOP_STATION_PAUSE4_STATION_PAUSE_4_2_ADDR \ +WF_PLE_TOP_STATION_PAUSE4_ADDR +#define WF_PLE_TOP_STATION_PAUSE4_STATION_PAUSE_4_2_MASK \ +0xFFFF0000 /* STATION_PAUSE_4_2[31..16] */ +#define WF_PLE_TOP_STATION_PAUSE4_STATION_PAUSE_4_2_SHFT 16 +#define WF_PLE_TOP_STATION_PAUSE4_STATION_PAUSE_4_1_ADDR \ +WF_PLE_TOP_STATION_PAUSE4_ADDR +#define WF_PLE_TOP_STATION_PAUSE4_STATION_PAUSE_4_1_MASK \ +0x0000FF00 /* STATION_PAUSE_4_1[15..8] */ +#define WF_PLE_TOP_STATION_PAUSE4_STATION_PAUSE_4_1_SHFT 8 +#define WF_PLE_TOP_STATION_PAUSE4_STATION_PAUSE_4_0_ADDR \ +WF_PLE_TOP_STATION_PAUSE4_ADDR +#define WF_PLE_TOP_STATION_PAUSE4_STATION_PAUSE_4_0_MASK \ +0x000000FF /* STATION_PAUSE_4_0[7..0] */ +#define WF_PLE_TOP_STATION_PAUSE4_STATION_PAUSE_4_0_SHFT 0 + +/* +* ---STATION_PAUSE5 (0x820C0000 + 0x414)--- +* STATION_PAUSE_5[31..0] - (RW) SW can stop station TX by this setting +* for STA160~STA191. +*/ +#define WF_PLE_TOP_STATION_PAUSE5_STATION_PAUSE_5_ADDR \ +WF_PLE_TOP_STATION_PAUSE5_ADDR +#define WF_PLE_TOP_STATION_PAUSE5_STATION_PAUSE_5_MASK \ +0xFFFFFFFF /* STATION_PAUSE_5[31..0] */ +#define WF_PLE_TOP_STATION_PAUSE5_STATION_PAUSE_5_SHFT 0 + +/* +* ---STATION_PAUSE6 (0x820C0000 + 0x418)--- +* STATION_PAUSE_6[31..0] - (RW) SW can stop station TX by this setting +* for STA192~STA223. +*/ +#define WF_PLE_TOP_STATION_PAUSE6_STATION_PAUSE_6_ADDR \ +WF_PLE_TOP_STATION_PAUSE6_ADDR +#define WF_PLE_TOP_STATION_PAUSE6_STATION_PAUSE_6_MASK \ +0xFFFFFFFF /* STATION_PAUSE_6[31..0] */ +#define WF_PLE_TOP_STATION_PAUSE6_STATION_PAUSE_6_SHFT 0 + +/* +* ---STATION_PAUSE7 (0x820C0000 + 0x41c)--- +* STATION_PAUSE_7[31..0] - (RW) SW can stop station TX by this setting +* for STA224~STA255. +*/ +#define WF_PLE_TOP_STATION_PAUSE7_STATION_PAUSE_7_ADDR \ +WF_PLE_TOP_STATION_PAUSE7_ADDR +#define WF_PLE_TOP_STATION_PAUSE7_STATION_PAUSE_7_MASK \ +0xFFFFFFFF /* STATION_PAUSE_7[31..0] */ +#define WF_PLE_TOP_STATION_PAUSE7_STATION_PAUSE_7_SHFT 0 + +/* +* ---STATION_PAUSE8 (0x820C0000 + 0x420)--- +* STATION_PAUSE_8[31..0] - (RW) SW can stop station TX by this setting +* for STA256~STA287. +*/ +#define WF_PLE_TOP_STATION_PAUSE8_STATION_PAUSE_8_ADDR \ +WF_PLE_TOP_STATION_PAUSE8_ADDR +#define WF_PLE_TOP_STATION_PAUSE8_STATION_PAUSE_8_MASK \ +0xFFFFFFFF /* STATION_PAUSE_8[31..0] */ +#define WF_PLE_TOP_STATION_PAUSE8_STATION_PAUSE_8_SHFT 0 + +/* +* ---DIS_STA_MAP0 (0x820C0000 + 0x440)--- +* DIS_STA_MAP_0[31..0] - (RW) Disable map for STA 0~31 TX +*/ +#define WF_PLE_TOP_DIS_STA_MAP0_DIS_STA_MAP_0_ADDR WF_PLE_TOP_DIS_STA_MAP0_ADDR +#define WF_PLE_TOP_DIS_STA_MAP0_DIS_STA_MAP_0_MASK \ +0xFFFFFFFF /* DIS_STA_MAP_0[31..0] */ +#define WF_PLE_TOP_DIS_STA_MAP0_DIS_STA_MAP_0_SHFT 0 + +/* +* ---DIS_STA_MAP1 (0x820C0000 + 0x444)--- +* DIS_STA_MAP_1[31..0] - (RW) Disable map for STA 32~63 TX +*/ +#define WF_PLE_TOP_DIS_STA_MAP1_DIS_STA_MAP_1_ADDR WF_PLE_TOP_DIS_STA_MAP1_ADDR +#define WF_PLE_TOP_DIS_STA_MAP1_DIS_STA_MAP_1_MASK \ +0xFFFFFFFF /* DIS_STA_MAP_1[31..0] */ +#define WF_PLE_TOP_DIS_STA_MAP1_DIS_STA_MAP_1_SHFT 0 + +/* +* ---DIS_STA_MAP2 (0x820C0000 + 0x448)--- +* DIS_STA_MAP_2[31..0] - (RW) Disable map for STA 64~95 TX +*/ +#define WF_PLE_TOP_DIS_STA_MAP2_DIS_STA_MAP_2_ADDR WF_PLE_TOP_DIS_STA_MAP2_ADDR +#define WF_PLE_TOP_DIS_STA_MAP2_DIS_STA_MAP_2_MASK \ +0xFFFFFFFF /* DIS_STA_MAP_2[31..0] */ +#define WF_PLE_TOP_DIS_STA_MAP2_DIS_STA_MAP_2_SHFT 0 + +/* +* ---DIS_STA_MAP3 (0x820C0000 + 0x44c)--- +* DIS_STA_MAP_3[31..0] - (RW) Disable map for STA 96~127 TX +*/ +#define WF_PLE_TOP_DIS_STA_MAP3_DIS_STA_MAP_3_ADDR WF_PLE_TOP_DIS_STA_MAP3_ADDR +#define WF_PLE_TOP_DIS_STA_MAP3_DIS_STA_MAP_3_MASK \ +0xFFFFFFFF /* DIS_STA_MAP_3[31..0] */ +#define WF_PLE_TOP_DIS_STA_MAP3_DIS_STA_MAP_3_SHFT 0 + +/* +* ---DIS_STA_MAP4 (0x820C0000 + 0x450)--- +* DIS_STA_MAP_4_0[7..0] - (RW) Disable map for STA 128~135 TX +* DIS_STA_MAP_4_1[15..8] - (RW) Disable map for STA 136~143 TX +* DIS_STA_MAP_4_2[31..16] - (RW) Disable map for STA 144~159 TX +*/ +#define WF_PLE_TOP_DIS_STA_MAP4_DIS_STA_MAP_4_2_ADDR \ +WF_PLE_TOP_DIS_STA_MAP4_ADDR +#define WF_PLE_TOP_DIS_STA_MAP4_DIS_STA_MAP_4_2_MASK \ +0xFFFF0000 /* DIS_STA_MAP_4_2[31..16] */ +#define WF_PLE_TOP_DIS_STA_MAP4_DIS_STA_MAP_4_2_SHFT 16 +#define WF_PLE_TOP_DIS_STA_MAP4_DIS_STA_MAP_4_1_ADDR \ +WF_PLE_TOP_DIS_STA_MAP4_ADDR +#define WF_PLE_TOP_DIS_STA_MAP4_DIS_STA_MAP_4_1_MASK \ +0x0000FF00 /* DIS_STA_MAP_4_1[15..8] */ +#define WF_PLE_TOP_DIS_STA_MAP4_DIS_STA_MAP_4_1_SHFT 8 +#define WF_PLE_TOP_DIS_STA_MAP4_DIS_STA_MAP_4_0_ADDR \ +WF_PLE_TOP_DIS_STA_MAP4_ADDR +#define WF_PLE_TOP_DIS_STA_MAP4_DIS_STA_MAP_4_0_MASK \ +0x000000FF /* DIS_STA_MAP_4_0[7..0] */ +#define WF_PLE_TOP_DIS_STA_MAP4_DIS_STA_MAP_4_0_SHFT 0 + +/* +* ---DIS_STA_MAP5 (0x820C0000 + 0x454)--- +* DIS_STA_MAP_5[31..0] - (RW) Disable map for STA 160~191 TX +*/ +#define WF_PLE_TOP_DIS_STA_MAP5_DIS_STA_MAP_5_ADDR WF_PLE_TOP_DIS_STA_MAP5_ADDR +#define WF_PLE_TOP_DIS_STA_MAP5_DIS_STA_MAP_5_MASK \ +0xFFFFFFFF /* DIS_STA_MAP_5[31..0] */ +#define WF_PLE_TOP_DIS_STA_MAP5_DIS_STA_MAP_5_SHFT 0 + +/* +* ---DIS_STA_MAP6 (0x820C0000 + 0x458)--- +* DIS_STA_MAP_6[31..0] - (RW) Disable map for STA 192~223 TX +*/ +#define WF_PLE_TOP_DIS_STA_MAP6_DIS_STA_MAP_6_ADDR WF_PLE_TOP_DIS_STA_MAP6_ADDR +#define WF_PLE_TOP_DIS_STA_MAP6_DIS_STA_MAP_6_MASK \ +0xFFFFFFFF /* DIS_STA_MAP_6[31..0] */ +#define WF_PLE_TOP_DIS_STA_MAP6_DIS_STA_MAP_6_SHFT 0 + +/* +* ---DIS_STA_MAP7 (0x820C0000 + 0x45c)--- +* DIS_STA_MAP_7[31..0] - (RW) Disable map for STA 224~255 TX +*/ +#define WF_PLE_TOP_DIS_STA_MAP7_DIS_STA_MAP_7_ADDR WF_PLE_TOP_DIS_STA_MAP7_ADDR +#define WF_PLE_TOP_DIS_STA_MAP7_DIS_STA_MAP_7_MASK \ +0xFFFFFFFF /* DIS_STA_MAP_7[31..0] */ +#define WF_PLE_TOP_DIS_STA_MAP7_DIS_STA_MAP_7_SHFT 0 + +/* +* ---DIS_STA_MAP8 (0x820C0000 + 0x460)--- +* DIS_STA_MAP_8[31..0] - (RW) Disable map for STA 256~287 TX +*/ +#define WF_PLE_TOP_DIS_STA_MAP8_DIS_STA_MAP_8_ADDR WF_PLE_TOP_DIS_STA_MAP8_ADDR +#define WF_PLE_TOP_DIS_STA_MAP8_DIS_STA_MAP_8_MASK \ +0xFFFFFFFF /* DIS_STA_MAP_8[31..0] */ +#define WF_PLE_TOP_DIS_STA_MAP8_DIS_STA_MAP_8_SHFT 0 + +/* +* ---STATION_REDIR0 (0x820C0000 + 0x480)--- +* STATION_REDIR_0[31..0] - (RW) SW can redirection to designed +* port/queue by this setting for STA0~STA31. +*/ +#define WF_PLE_TOP_STATION_REDIR0_STATION_REDIR_0_ADDR \ +WF_PLE_TOP_STATION_REDIR0_ADDR +#define WF_PLE_TOP_STATION_REDIR0_STATION_REDIR_0_MASK \ +0xFFFFFFFF /* STATION_REDIR_0[31..0] */ +#define WF_PLE_TOP_STATION_REDIR0_STATION_REDIR_0_SHFT 0 + +/* +* ---STATION_REDIR1 (0x820C0000 + 0x484)--- +* STATION_REDIR_1[31..0] - (RW) SW can redirection to designed +* port/queue by this setting for STA32~STA63. +*/ +#define WF_PLE_TOP_STATION_REDIR1_STATION_REDIR_1_ADDR \ +WF_PLE_TOP_STATION_REDIR1_ADDR +#define WF_PLE_TOP_STATION_REDIR1_STATION_REDIR_1_MASK \ +0xFFFFFFFF /* STATION_REDIR_1[31..0] */ +#define WF_PLE_TOP_STATION_REDIR1_STATION_REDIR_1_SHFT 0 + +/* +* ---STATION_REDIR2 (0x820C0000 + 0x488)--- +* STATION_REDIR_2[31..0] - (RW) SW can redirection to designed +* port/queue by this setting for STA64~STA95. +*/ +#define WF_PLE_TOP_STATION_REDIR2_STATION_REDIR_2_ADDR \ +WF_PLE_TOP_STATION_REDIR2_ADDR +#define WF_PLE_TOP_STATION_REDIR2_STATION_REDIR_2_MASK \ +0xFFFFFFFF /* STATION_REDIR_2[31..0] */ +#define WF_PLE_TOP_STATION_REDIR2_STATION_REDIR_2_SHFT 0 + +/* +* ---STATION_REDIR3 (0x820C0000 + 0x48c)--- +* STATION_REDIR_3[31..0] - (RW) SW can redirection to designed +* port/queue by this setting for STA96~STA127. +*/ +#define WF_PLE_TOP_STATION_REDIR3_STATION_REDIR_3_ADDR \ +WF_PLE_TOP_STATION_REDIR3_ADDR +#define WF_PLE_TOP_STATION_REDIR3_STATION_REDIR_3_MASK \ +0xFFFFFFFF /* STATION_REDIR_3[31..0] */ +#define WF_PLE_TOP_STATION_REDIR3_STATION_REDIR_3_SHFT 0 + +/* +* ---STATION_REDIR4 (0x820C0000 + 0x490)--- +* STATION_REDIR_4_0[7..0] - (RW) SW can redirection to designed +* port/queue by this setting for STA128~STA135. +* STATION_REDIR_4_1[15..8] - (RW) SW can redirection to designed +* port/queue by this setting for STA136~STA143. +* STATION_REDIR_4_2[31..16] - (RW) SW can redirection to designed +* port/queue by this setting for STA144~STA159. +*/ +#define WF_PLE_TOP_STATION_REDIR4_STATION_REDIR_4_2_ADDR \ +WF_PLE_TOP_STATION_REDIR4_ADDR +#define WF_PLE_TOP_STATION_REDIR4_STATION_REDIR_4_2_MASK \ +0xFFFF0000 /* STATION_REDIR_4_2[31..16] */ +#define WF_PLE_TOP_STATION_REDIR4_STATION_REDIR_4_2_SHFT 16 +#define WF_PLE_TOP_STATION_REDIR4_STATION_REDIR_4_1_ADDR \ +WF_PLE_TOP_STATION_REDIR4_ADDR +#define WF_PLE_TOP_STATION_REDIR4_STATION_REDIR_4_1_MASK \ +0x0000FF00 /* STATION_REDIR_4_1[15..8] */ +#define WF_PLE_TOP_STATION_REDIR4_STATION_REDIR_4_1_SHFT 8 +#define WF_PLE_TOP_STATION_REDIR4_STATION_REDIR_4_0_ADDR \ +WF_PLE_TOP_STATION_REDIR4_ADDR +#define WF_PLE_TOP_STATION_REDIR4_STATION_REDIR_4_0_MASK \ +0x000000FF /* STATION_REDIR_4_0[7..0] */ +#define WF_PLE_TOP_STATION_REDIR4_STATION_REDIR_4_0_SHFT 0 + +/* +* ---STATION_REDIR5 (0x820C0000 + 0x494)--- +* STATION_REDIR_5[31..0] - (RW) SW can redirection to designed +* port/queue by this setting STA160~STA191. +*/ +#define WF_PLE_TOP_STATION_REDIR5_STATION_REDIR_5_ADDR \ +WF_PLE_TOP_STATION_REDIR5_ADDR +#define WF_PLE_TOP_STATION_REDIR5_STATION_REDIR_5_MASK \ +0xFFFFFFFF /* STATION_REDIR_5[31..0] */ +#define WF_PLE_TOP_STATION_REDIR5_STATION_REDIR_5_SHFT 0 + +/* +* ---STATION_REDIR6 (0x820C0000 + 0x498)--- +* STATION_REDIR_6[31..0] - (RW) SW can redirection to designed +* port/queue by this setting STA192~STA223. +*/ +#define WF_PLE_TOP_STATION_REDIR6_STATION_REDIR_6_ADDR \ +WF_PLE_TOP_STATION_REDIR6_ADDR +#define WF_PLE_TOP_STATION_REDIR6_STATION_REDIR_6_MASK \ +0xFFFFFFFF /* STATION_REDIR_6[31..0] */ +#define WF_PLE_TOP_STATION_REDIR6_STATION_REDIR_6_SHFT 0 + +/* +* ---STATION_REDIR7 (0x820C0000 + 0x49c)--- +* STATION_REDIR_7[31..0] - (RW) SW can redirection to designed +* port/queue by this setting STA224~STA255. +*/ +#define WF_PLE_TOP_STATION_REDIR7_STATION_REDIR_7_ADDR \ +WF_PLE_TOP_STATION_REDIR7_ADDR +#define WF_PLE_TOP_STATION_REDIR7_STATION_REDIR_7_MASK \ +0xFFFFFFFF /* STATION_REDIR_7[31..0] */ +#define WF_PLE_TOP_STATION_REDIR7_STATION_REDIR_7_SHFT 0 + +/* +* ---STATION_REDIR8 (0x820C0000 + 0x4a0)--- +* STATION_REDIR8[31..0] - (RW) SW can redirection to designed +* port/queue by this setting STA256~STA287. +*/ +#define WF_PLE_TOP_STATION_REDIR8_STATION_REDIR8_ADDR \ +WF_PLE_TOP_STATION_REDIR8_ADDR +#define WF_PLE_TOP_STATION_REDIR8_STATION_REDIR8_MASK \ +0xFFFFFFFF /* STATION_REDIR8[31..0] */ +#define WF_PLE_TOP_STATION_REDIR8_STATION_REDIR8_SHFT 0 + +/* +* ---TWT_STA_MAP0 (0x820C0000 + 0x4c0)--- +* TWT_STA_MAP_0[31..0] - (RW) TWT map for STA 0~31 TX +*/ +#define WF_PLE_TOP_TWT_STA_MAP0_TWT_STA_MAP_0_ADDR WF_PLE_TOP_TWT_STA_MAP0_ADDR +#define WF_PLE_TOP_TWT_STA_MAP0_TWT_STA_MAP_0_MASK \ +0xFFFFFFFF /* TWT_STA_MAP_0[31..0] */ +#define WF_PLE_TOP_TWT_STA_MAP0_TWT_STA_MAP_0_SHFT 0 + +/* +* ---TWT_STA_MAP1 (0x820C0000 + 0x4c4)--- +* TWT_STA_MAP_1[31..0] - (RW) TWT map for STA 32~63 TX +*/ +#define WF_PLE_TOP_TWT_STA_MAP1_TWT_STA_MAP_1_ADDR WF_PLE_TOP_TWT_STA_MAP1_ADDR +#define WF_PLE_TOP_TWT_STA_MAP1_TWT_STA_MAP_1_MASK \ +0xFFFFFFFF /* TWT_STA_MAP_1[31..0] */ +#define WF_PLE_TOP_TWT_STA_MAP1_TWT_STA_MAP_1_SHFT 0 + +/* +* ---TWT_STA_MAP2 (0x820C0000 + 0x4c8)--- +* TWT_STA_MAP_2[31..0] - (RW) TWT map for STA 64~95 TX +*/ +#define WF_PLE_TOP_TWT_STA_MAP2_TWT_STA_MAP_2_ADDR WF_PLE_TOP_TWT_STA_MAP2_ADDR +#define WF_PLE_TOP_TWT_STA_MAP2_TWT_STA_MAP_2_MASK \ +0xFFFFFFFF /* TWT_STA_MAP_2[31..0] */ +#define WF_PLE_TOP_TWT_STA_MAP2_TWT_STA_MAP_2_SHFT 0 + +/* +* ---TWT_STA_MAP3 (0x820C0000 + 0x4cc)--- +* TWT_STA_MAP_3[31..0] - (RW) TWT map for STA 96~127 TX +*/ +#define WF_PLE_TOP_TWT_STA_MAP3_TWT_STA_MAP_3_ADDR WF_PLE_TOP_TWT_STA_MAP3_ADDR +#define WF_PLE_TOP_TWT_STA_MAP3_TWT_STA_MAP_3_MASK \ +0xFFFFFFFF /* TWT_STA_MAP_3[31..0] */ +#define WF_PLE_TOP_TWT_STA_MAP3_TWT_STA_MAP_3_SHFT 0 + +/* +* ---TWT_STA_MAP4 (0x820C0000 + 0x4d0)--- +* TWT_STA_MAP_4_0[7..0] - (RW) TWT map for STA 128~135 TX +* TWT_STA_MAP_4_1[15..8] - (RW) TWT map for STA 136~143 TX +* TWT_STA_MAP_4_2[31..16] - (RW) TWT map for STA 144~159 TX +*/ +#define WF_PLE_TOP_TWT_STA_MAP4_TWT_STA_MAP_4_2_ADDR \ +WF_PLE_TOP_TWT_STA_MAP4_ADDR +#define WF_PLE_TOP_TWT_STA_MAP4_TWT_STA_MAP_4_2_MASK \ +0xFFFF0000 /* TWT_STA_MAP_4_2[31..16] */ +#define WF_PLE_TOP_TWT_STA_MAP4_TWT_STA_MAP_4_2_SHFT 16 +#define WF_PLE_TOP_TWT_STA_MAP4_TWT_STA_MAP_4_1_ADDR \ +WF_PLE_TOP_TWT_STA_MAP4_ADDR +#define WF_PLE_TOP_TWT_STA_MAP4_TWT_STA_MAP_4_1_MASK \ +0x0000FF00 /* TWT_STA_MAP_4_1[15..8] */ +#define WF_PLE_TOP_TWT_STA_MAP4_TWT_STA_MAP_4_1_SHFT 8 +#define WF_PLE_TOP_TWT_STA_MAP4_TWT_STA_MAP_4_0_ADDR \ +WF_PLE_TOP_TWT_STA_MAP4_ADDR +#define WF_PLE_TOP_TWT_STA_MAP4_TWT_STA_MAP_4_0_MASK \ +0x000000FF /* TWT_STA_MAP_4_0[7..0] */ +#define WF_PLE_TOP_TWT_STA_MAP4_TWT_STA_MAP_4_0_SHFT 0 + +/* +* ---TWT_STA_MAP5 (0x820C0000 + 0x4d4)--- +* TWT_STA_MAP_5[31..0] - (RW) TWT map for STA 160~191 TX +*/ +#define WF_PLE_TOP_TWT_STA_MAP5_TWT_STA_MAP_5_ADDR WF_PLE_TOP_TWT_STA_MAP5_ADDR +#define WF_PLE_TOP_TWT_STA_MAP5_TWT_STA_MAP_5_MASK \ +0xFFFFFFFF /* TWT_STA_MAP_5[31..0] */ +#define WF_PLE_TOP_TWT_STA_MAP5_TWT_STA_MAP_5_SHFT 0 + +/* +* ---TWT_STA_MAP6 (0x820C0000 + 0x4d8)--- +* TWT_STA_MAP_6[31..0] - (RW) TWT map for STA 192~223 TX +*/ +#define WF_PLE_TOP_TWT_STA_MAP6_TWT_STA_MAP_6_ADDR WF_PLE_TOP_TWT_STA_MAP6_ADDR +#define WF_PLE_TOP_TWT_STA_MAP6_TWT_STA_MAP_6_MASK \ +0xFFFFFFFF /* TWT_STA_MAP_6[31..0] */ +#define WF_PLE_TOP_TWT_STA_MAP6_TWT_STA_MAP_6_SHFT 0 + +/* +* ---TWT_STA_MAP7 (0x820C0000 + 0x4dc)--- +* TWT_STA_MAP_7[31..0] - (RW) TWT map for STA 224~255 TX +*/ +#define WF_PLE_TOP_TWT_STA_MAP7_TWT_STA_MAP_7_ADDR WF_PLE_TOP_TWT_STA_MAP7_ADDR +#define WF_PLE_TOP_TWT_STA_MAP7_TWT_STA_MAP_7_MASK \ +0xFFFFFFFF /* TWT_STA_MAP_7[31..0] */ +#define WF_PLE_TOP_TWT_STA_MAP7_TWT_STA_MAP_7_SHFT 0 + +/* +* ---TWT_STA_MAP8 (0x820C0000 + 0x4e0)--- +* TWT_STA_MAP_8[31..0] - (RW) TWT map for STA 256~287 TX +*/ +#define WF_PLE_TOP_TWT_STA_MAP8_TWT_STA_MAP_8_ADDR WF_PLE_TOP_TWT_STA_MAP8_ADDR +#define WF_PLE_TOP_TWT_STA_MAP8_TWT_STA_MAP_8_MASK \ +0xFFFFFFFF /* TWT_STA_MAP_8[31..0] */ +#define WF_PLE_TOP_TWT_STA_MAP8_TWT_STA_MAP_8_SHFT 0 + +/* +* ---AC0_QUEUE_EMPTY0 (0x820C0000 + 0x500)--- +* AC0_QUEUE_EMPTY_0[31..0] - (RO) Empty flag for STA 0~31 AC0 queue +*/ +#define WF_PLE_TOP_AC0_QUEUE_EMPTY0_AC0_QUEUE_EMPTY_0_ADDR \ +WF_PLE_TOP_AC0_QUEUE_EMPTY0_ADDR +#define WF_PLE_TOP_AC0_QUEUE_EMPTY0_AC0_QUEUE_EMPTY_0_MASK \ +0xFFFFFFFF /* AC0_QUEUE_EMPTY_0[31..0] */ +#define WF_PLE_TOP_AC0_QUEUE_EMPTY0_AC0_QUEUE_EMPTY_0_SHFT 0 + +/* +* ---AC0_QUEUE_EMPTY1 (0x820C0000 + 0x504)--- +* AC0_QUEUE_EMPTY_1[31..0] - (RO) Empty flag for STA 32~63 AC0 queue +*/ +#define WF_PLE_TOP_AC0_QUEUE_EMPTY1_AC0_QUEUE_EMPTY_1_ADDR \ +WF_PLE_TOP_AC0_QUEUE_EMPTY1_ADDR +#define WF_PLE_TOP_AC0_QUEUE_EMPTY1_AC0_QUEUE_EMPTY_1_MASK \ +0xFFFFFFFF /* AC0_QUEUE_EMPTY_1[31..0] */ +#define WF_PLE_TOP_AC0_QUEUE_EMPTY1_AC0_QUEUE_EMPTY_1_SHFT 0 + +/* +* ---AC0_QUEUE_EMPTY2 (0x820C0000 + 0x508)--- +* AC0_QUEUE_EMPTY_2[31..0] - (RO) Empty flag for STA 64~95 AC0 queue +*/ +#define WF_PLE_TOP_AC0_QUEUE_EMPTY2_AC0_QUEUE_EMPTY_2_ADDR \ +WF_PLE_TOP_AC0_QUEUE_EMPTY2_ADDR +#define WF_PLE_TOP_AC0_QUEUE_EMPTY2_AC0_QUEUE_EMPTY_2_MASK \ +0xFFFFFFFF /* AC0_QUEUE_EMPTY_2[31..0] */ +#define WF_PLE_TOP_AC0_QUEUE_EMPTY2_AC0_QUEUE_EMPTY_2_SHFT 0 + +/* +* ---AC0_QUEUE_EMPTY3 (0x820C0000 + 0x50c)--- +* AC0_QUEUE_EMPTY_3[31..0] - (RO) Empty flag for STA 96~127 AC0 queue +*/ +#define WF_PLE_TOP_AC0_QUEUE_EMPTY3_AC0_QUEUE_EMPTY_3_ADDR \ +WF_PLE_TOP_AC0_QUEUE_EMPTY3_ADDR +#define WF_PLE_TOP_AC0_QUEUE_EMPTY3_AC0_QUEUE_EMPTY_3_MASK \ +0xFFFFFFFF /* AC0_QUEUE_EMPTY_3[31..0] */ +#define WF_PLE_TOP_AC0_QUEUE_EMPTY3_AC0_QUEUE_EMPTY_3_SHFT 0 + +/* +* ---AC0_QUEUE_EMPTY4 (0x820C0000 + 0x510)--- +* AC0_QUEUE_EMPTY_4_0[7..0] - (RO) Empty flag for STA 128~135 AC0 queue +* AC0_QUEUE_EMPTY_4_1[15..8] - (RO) Empty flag for STA 136~143 AC0 queue +* AC0_QUEUE_EMPTY_4_2[31..16] - (RO) Empty flag for STA 144~159 AC0 queue +*/ +#define WF_PLE_TOP_AC0_QUEUE_EMPTY4_AC0_QUEUE_EMPTY_4_2_ADDR \ +WF_PLE_TOP_AC0_QUEUE_EMPTY4_ADDR +#define WF_PLE_TOP_AC0_QUEUE_EMPTY4_AC0_QUEUE_EMPTY_4_2_MASK \ +0xFFFF0000 /* AC0_QUEUE_EMPTY_4_2[31..16] */ +#define WF_PLE_TOP_AC0_QUEUE_EMPTY4_AC0_QUEUE_EMPTY_4_2_SHFT 16 +#define WF_PLE_TOP_AC0_QUEUE_EMPTY4_AC0_QUEUE_EMPTY_4_1_ADDR \ +WF_PLE_TOP_AC0_QUEUE_EMPTY4_ADDR +#define WF_PLE_TOP_AC0_QUEUE_EMPTY4_AC0_QUEUE_EMPTY_4_1_MASK \ +0x0000FF00 /* AC0_QUEUE_EMPTY_4_1[15..8] */ +#define WF_PLE_TOP_AC0_QUEUE_EMPTY4_AC0_QUEUE_EMPTY_4_1_SHFT 8 +#define WF_PLE_TOP_AC0_QUEUE_EMPTY4_AC0_QUEUE_EMPTY_4_0_ADDR \ +WF_PLE_TOP_AC0_QUEUE_EMPTY4_ADDR +#define WF_PLE_TOP_AC0_QUEUE_EMPTY4_AC0_QUEUE_EMPTY_4_0_MASK \ +0x000000FF /* AC0_QUEUE_EMPTY_4_0[7..0] */ +#define WF_PLE_TOP_AC0_QUEUE_EMPTY4_AC0_QUEUE_EMPTY_4_0_SHFT 0 + +/* +* ---AC0_QUEUE_EMPTY5 (0x820C0000 + 0x514)--- +* AC0_QUEUE_EMPTY_5[31..0] - (RO) Empty flag for STA 160~191 AC0 queue +*/ +#define WF_PLE_TOP_AC0_QUEUE_EMPTY5_AC0_QUEUE_EMPTY_5_ADDR \ +WF_PLE_TOP_AC0_QUEUE_EMPTY5_ADDR +#define WF_PLE_TOP_AC0_QUEUE_EMPTY5_AC0_QUEUE_EMPTY_5_MASK \ +0xFFFFFFFF /* AC0_QUEUE_EMPTY_5[31..0] */ +#define WF_PLE_TOP_AC0_QUEUE_EMPTY5_AC0_QUEUE_EMPTY_5_SHFT 0 + +/* +* ---AC0_QUEUE_EMPTY6 (0x820C0000 + 0x518)--- +* AC0_QUEUE_EMPTY_6[31..0] - (RO) Empty flag for STA 192~223 AC0 queue +*/ +#define WF_PLE_TOP_AC0_QUEUE_EMPTY6_AC0_QUEUE_EMPTY_6_ADDR \ +WF_PLE_TOP_AC0_QUEUE_EMPTY6_ADDR +#define WF_PLE_TOP_AC0_QUEUE_EMPTY6_AC0_QUEUE_EMPTY_6_MASK \ +0xFFFFFFFF /* AC0_QUEUE_EMPTY_6[31..0] */ +#define WF_PLE_TOP_AC0_QUEUE_EMPTY6_AC0_QUEUE_EMPTY_6_SHFT 0 + +/* +* ---AC0_QUEUE_EMPTY7 (0x820C0000 + 0x51c)--- +* AC0_QUEUE_EMPTY_7[31..0] - (RO) Empty flag for STA 224~255 AC0 queue +*/ +#define WF_PLE_TOP_AC0_QUEUE_EMPTY7_AC0_QUEUE_EMPTY_7_ADDR \ +WF_PLE_TOP_AC0_QUEUE_EMPTY7_ADDR +#define WF_PLE_TOP_AC0_QUEUE_EMPTY7_AC0_QUEUE_EMPTY_7_MASK \ +0xFFFFFFFF /* AC0_QUEUE_EMPTY_7[31..0] */ +#define WF_PLE_TOP_AC0_QUEUE_EMPTY7_AC0_QUEUE_EMPTY_7_SHFT 0 + +/* +* ---AC0_QUEUE_EMPTY8 (0x820C0000 + 0x520)--- +* AC0_QUEUE_EMPTY_8[31..0] - (RO) Empty flag for STA 256~287 AC0 queue +*/ +#define WF_PLE_TOP_AC0_QUEUE_EMPTY8_AC0_QUEUE_EMPTY_8_ADDR \ +WF_PLE_TOP_AC0_QUEUE_EMPTY8_ADDR +#define WF_PLE_TOP_AC0_QUEUE_EMPTY8_AC0_QUEUE_EMPTY_8_MASK \ +0xFFFFFFFF /* AC0_QUEUE_EMPTY_8[31..0] */ +#define WF_PLE_TOP_AC0_QUEUE_EMPTY8_AC0_QUEUE_EMPTY_8_SHFT 0 + +/* +* ---AC1_QUEUE_EMPTY0 (0x820C0000 + 0x540)--- +* AC1_QUEUE_EMPTY_0[31..0] - (RO) Empty flag for STA 0~31 AC1 queue +*/ +#define WF_PLE_TOP_AC1_QUEUE_EMPTY0_AC1_QUEUE_EMPTY_0_ADDR \ +WF_PLE_TOP_AC1_QUEUE_EMPTY0_ADDR +#define WF_PLE_TOP_AC1_QUEUE_EMPTY0_AC1_QUEUE_EMPTY_0_MASK \ +0xFFFFFFFF /* AC1_QUEUE_EMPTY_0[31..0] */ +#define WF_PLE_TOP_AC1_QUEUE_EMPTY0_AC1_QUEUE_EMPTY_0_SHFT 0 + +/* +* ---AC1_QUEUE_EMPTY1 (0x820C0000 + 0x544)--- +* AC1_QUEUE_EMPTY_1[31..0] - (RO) Empty flag for STA 32~63 AC1 queue +*/ +#define WF_PLE_TOP_AC1_QUEUE_EMPTY1_AC1_QUEUE_EMPTY_1_ADDR \ +WF_PLE_TOP_AC1_QUEUE_EMPTY1_ADDR +#define WF_PLE_TOP_AC1_QUEUE_EMPTY1_AC1_QUEUE_EMPTY_1_MASK \ +0xFFFFFFFF /* AC1_QUEUE_EMPTY_1[31..0] */ +#define WF_PLE_TOP_AC1_QUEUE_EMPTY1_AC1_QUEUE_EMPTY_1_SHFT 0 + +/* +* ---AC1_QUEUE_EMPTY2 (0x820C0000 + 0x548)--- +* AC1_QUEUE_EMPTY_2[31..0] - (RO) Empty flag for STA 64~95 AC1 queue +*/ +#define WF_PLE_TOP_AC1_QUEUE_EMPTY2_AC1_QUEUE_EMPTY_2_ADDR \ +WF_PLE_TOP_AC1_QUEUE_EMPTY2_ADDR +#define WF_PLE_TOP_AC1_QUEUE_EMPTY2_AC1_QUEUE_EMPTY_2_MASK \ +0xFFFFFFFF /* AC1_QUEUE_EMPTY_2[31..0] */ +#define WF_PLE_TOP_AC1_QUEUE_EMPTY2_AC1_QUEUE_EMPTY_2_SHFT 0 + +/* +* ---AC1_QUEUE_EMPTY3 (0x820C0000 + 0x54c)--- +* AC1_QUEUE_EMPTY_3[31..0] - (RO) Empty flag for STA 96~127 AC1 queue +*/ +#define WF_PLE_TOP_AC1_QUEUE_EMPTY3_AC1_QUEUE_EMPTY_3_ADDR \ +WF_PLE_TOP_AC1_QUEUE_EMPTY3_ADDR +#define WF_PLE_TOP_AC1_QUEUE_EMPTY3_AC1_QUEUE_EMPTY_3_MASK \ +0xFFFFFFFF /* AC1_QUEUE_EMPTY_3[31..0] */ +#define WF_PLE_TOP_AC1_QUEUE_EMPTY3_AC1_QUEUE_EMPTY_3_SHFT 0 + +/* +* ---AC1_QUEUE_EMPTY4 (0x820C0000 + 0x550)--- +* AC1_QUEUE_EMPTY_4_0[7..0] - (RO) Empty flag for STA 128~135 AC1 queue +* AC1_QUEUE_EMPTY_4_1[15..8] - (RO) Empty flag for STA 136~143 AC1 queue +* AC1_QUEUE_EMPTY_4_2[31..16] - (RO) Empty flag for STA 144~159 AC1 queue +*/ +#define WF_PLE_TOP_AC1_QUEUE_EMPTY4_AC1_QUEUE_EMPTY_4_2_ADDR \ +WF_PLE_TOP_AC1_QUEUE_EMPTY4_ADDR +#define WF_PLE_TOP_AC1_QUEUE_EMPTY4_AC1_QUEUE_EMPTY_4_2_MASK \ +0xFFFF0000 /* AC1_QUEUE_EMPTY_4_2[31..16] */ +#define WF_PLE_TOP_AC1_QUEUE_EMPTY4_AC1_QUEUE_EMPTY_4_2_SHFT 16 +#define WF_PLE_TOP_AC1_QUEUE_EMPTY4_AC1_QUEUE_EMPTY_4_1_ADDR \ +WF_PLE_TOP_AC1_QUEUE_EMPTY4_ADDR +#define WF_PLE_TOP_AC1_QUEUE_EMPTY4_AC1_QUEUE_EMPTY_4_1_MASK \ +0x0000FF00 /* AC1_QUEUE_EMPTY_4_1[15..8] */ +#define WF_PLE_TOP_AC1_QUEUE_EMPTY4_AC1_QUEUE_EMPTY_4_1_SHFT 8 +#define WF_PLE_TOP_AC1_QUEUE_EMPTY4_AC1_QUEUE_EMPTY_4_0_ADDR \ +WF_PLE_TOP_AC1_QUEUE_EMPTY4_ADDR +#define WF_PLE_TOP_AC1_QUEUE_EMPTY4_AC1_QUEUE_EMPTY_4_0_MASK \ +0x000000FF /* AC1_QUEUE_EMPTY_4_0[7..0] */ +#define WF_PLE_TOP_AC1_QUEUE_EMPTY4_AC1_QUEUE_EMPTY_4_0_SHFT 0 + +/* +* ---AC1_QUEUE_EMPTY5 (0x820C0000 + 0x554)--- +* AC1_QUEUE_EMPTY_5[31..0] - (RO) Empty flag for STA 160~191 AC1 queue +*/ +#define WF_PLE_TOP_AC1_QUEUE_EMPTY5_AC1_QUEUE_EMPTY_5_ADDR \ +WF_PLE_TOP_AC1_QUEUE_EMPTY5_ADDR +#define WF_PLE_TOP_AC1_QUEUE_EMPTY5_AC1_QUEUE_EMPTY_5_MASK \ +0xFFFFFFFF /* AC1_QUEUE_EMPTY_5[31..0] */ +#define WF_PLE_TOP_AC1_QUEUE_EMPTY5_AC1_QUEUE_EMPTY_5_SHFT 0 + +/* +* ---AC1_QUEUE_EMPTY6 (0x820C0000 + 0x558)--- +* AC1_QUEUE_EMPTY_6[31..0] - (RO) Empty flag for STA 192~223 AC1 queue +*/ +#define WF_PLE_TOP_AC1_QUEUE_EMPTY6_AC1_QUEUE_EMPTY_6_ADDR \ +WF_PLE_TOP_AC1_QUEUE_EMPTY6_ADDR +#define WF_PLE_TOP_AC1_QUEUE_EMPTY6_AC1_QUEUE_EMPTY_6_MASK \ +0xFFFFFFFF /* AC1_QUEUE_EMPTY_6[31..0] */ +#define WF_PLE_TOP_AC1_QUEUE_EMPTY6_AC1_QUEUE_EMPTY_6_SHFT 0 + +/* +* ---AC1_QUEUE_EMPTY7 (0x820C0000 + 0x55c)--- +* AC1_QUEUE_EMPTY_7[31..0] - (RO) Empty flag for STA 224~255 AC1 queue +*/ +#define WF_PLE_TOP_AC1_QUEUE_EMPTY7_AC1_QUEUE_EMPTY_7_ADDR \ +WF_PLE_TOP_AC1_QUEUE_EMPTY7_ADDR +#define WF_PLE_TOP_AC1_QUEUE_EMPTY7_AC1_QUEUE_EMPTY_7_MASK \ +0xFFFFFFFF /* AC1_QUEUE_EMPTY_7[31..0] */ +#define WF_PLE_TOP_AC1_QUEUE_EMPTY7_AC1_QUEUE_EMPTY_7_SHFT 0 + +/* +* ---AC1_QUEUE_EMPTY8 (0x820C0000 + 0x560)--- +* AC1_QUEUE_EMPTY_8[31..0] - (RO) Empty flag for STA 256~287 AC1 queue +*/ +#define WF_PLE_TOP_AC1_QUEUE_EMPTY8_AC1_QUEUE_EMPTY_8_ADDR \ +WF_PLE_TOP_AC1_QUEUE_EMPTY8_ADDR +#define WF_PLE_TOP_AC1_QUEUE_EMPTY8_AC1_QUEUE_EMPTY_8_MASK \ +0xFFFFFFFF /* AC1_QUEUE_EMPTY_8[31..0] */ +#define WF_PLE_TOP_AC1_QUEUE_EMPTY8_AC1_QUEUE_EMPTY_8_SHFT 0 + +/* +* ---AC2_QUEUE_EMPTY0 (0x820C0000 + 0x580)--- +* AC2_QUEUE_EMPTY_0[31..0] - (RO) Empty flag for STA 0~31 AC2 queue +*/ +#define WF_PLE_TOP_AC2_QUEUE_EMPTY0_AC2_QUEUE_EMPTY_0_ADDR \ +WF_PLE_TOP_AC2_QUEUE_EMPTY0_ADDR +#define WF_PLE_TOP_AC2_QUEUE_EMPTY0_AC2_QUEUE_EMPTY_0_MASK \ +0xFFFFFFFF /* AC2_QUEUE_EMPTY_0[31..0] */ +#define WF_PLE_TOP_AC2_QUEUE_EMPTY0_AC2_QUEUE_EMPTY_0_SHFT 0 + +/* +* ---AC2_QUEUE_EMPTY1 (0x820C0000 + 0x584)--- +* AC2_QUEUE_EMPTY_1[31..0] - (RO) Empty flag for STA 32~63 AC2 queue +*/ +#define WF_PLE_TOP_AC2_QUEUE_EMPTY1_AC2_QUEUE_EMPTY_1_ADDR \ +WF_PLE_TOP_AC2_QUEUE_EMPTY1_ADDR +#define WF_PLE_TOP_AC2_QUEUE_EMPTY1_AC2_QUEUE_EMPTY_1_MASK \ +0xFFFFFFFF /* AC2_QUEUE_EMPTY_1[31..0] */ +#define WF_PLE_TOP_AC2_QUEUE_EMPTY1_AC2_QUEUE_EMPTY_1_SHFT 0 + +/* +* ---AC2_QUEUE_EMPTY2 (0x820C0000 + 0x588)--- +* AC2_QUEUE_EMPTY_2[31..0] - (RO) Empty flag for STA 64~95 AC2 queue +*/ +#define WF_PLE_TOP_AC2_QUEUE_EMPTY2_AC2_QUEUE_EMPTY_2_ADDR \ +WF_PLE_TOP_AC2_QUEUE_EMPTY2_ADDR +#define WF_PLE_TOP_AC2_QUEUE_EMPTY2_AC2_QUEUE_EMPTY_2_MASK \ +0xFFFFFFFF /* AC2_QUEUE_EMPTY_2[31..0] */ +#define WF_PLE_TOP_AC2_QUEUE_EMPTY2_AC2_QUEUE_EMPTY_2_SHFT 0 + +/* +* ---AC2_QUEUE_EMPTY3 (0x820C0000 + 0x58c)--- +* AC2_QUEUE_EMPTY_3[31..0] - (RO) Empty flag for STA 96~127 AC2 queue +*/ +#define WF_PLE_TOP_AC2_QUEUE_EMPTY3_AC2_QUEUE_EMPTY_3_ADDR \ +WF_PLE_TOP_AC2_QUEUE_EMPTY3_ADDR +#define WF_PLE_TOP_AC2_QUEUE_EMPTY3_AC2_QUEUE_EMPTY_3_MASK \ +0xFFFFFFFF /* AC2_QUEUE_EMPTY_3[31..0] */ +#define WF_PLE_TOP_AC2_QUEUE_EMPTY3_AC2_QUEUE_EMPTY_3_SHFT 0 + +/* +* ---AC2_QUEUE_EMPTY4 (0x820C0000 + 0x590)--- +* AC2_QUEUE_EMPTY_4_0[7..0] - (RO) Empty flag for STA 128~135 AC2 queue +* AC2_QUEUE_EMPTY_4_1[15..8] - (RO) Empty flag for STA 136~143 AC2 queue +* AC2_QUEUE_EMPTY_4_2[31..16] - (RO) Empty flag for STA 144~159 AC2 queue +*/ +#define WF_PLE_TOP_AC2_QUEUE_EMPTY4_AC2_QUEUE_EMPTY_4_2_ADDR \ +WF_PLE_TOP_AC2_QUEUE_EMPTY4_ADDR +#define WF_PLE_TOP_AC2_QUEUE_EMPTY4_AC2_QUEUE_EMPTY_4_2_MASK \ +0xFFFF0000 /* AC2_QUEUE_EMPTY_4_2[31..16] */ +#define WF_PLE_TOP_AC2_QUEUE_EMPTY4_AC2_QUEUE_EMPTY_4_2_SHFT 16 +#define WF_PLE_TOP_AC2_QUEUE_EMPTY4_AC2_QUEUE_EMPTY_4_1_ADDR \ +WF_PLE_TOP_AC2_QUEUE_EMPTY4_ADDR +#define WF_PLE_TOP_AC2_QUEUE_EMPTY4_AC2_QUEUE_EMPTY_4_1_MASK \ +0x0000FF00 /* AC2_QUEUE_EMPTY_4_1[15..8] */ +#define WF_PLE_TOP_AC2_QUEUE_EMPTY4_AC2_QUEUE_EMPTY_4_1_SHFT 8 +#define WF_PLE_TOP_AC2_QUEUE_EMPTY4_AC2_QUEUE_EMPTY_4_0_ADDR \ +WF_PLE_TOP_AC2_QUEUE_EMPTY4_ADDR +#define WF_PLE_TOP_AC2_QUEUE_EMPTY4_AC2_QUEUE_EMPTY_4_0_MASK \ +0x000000FF /* AC2_QUEUE_EMPTY_4_0[7..0] */ +#define WF_PLE_TOP_AC2_QUEUE_EMPTY4_AC2_QUEUE_EMPTY_4_0_SHFT 0 + +/* +* ---AC2_QUEUE_EMPTY5 (0x820C0000 + 0x594)--- +* AC2_QUEUE_EMPTY_5[31..0] - (RO) Empty flag for STA 160~191 AC2 queue +*/ +#define WF_PLE_TOP_AC2_QUEUE_EMPTY5_AC2_QUEUE_EMPTY_5_ADDR \ +WF_PLE_TOP_AC2_QUEUE_EMPTY5_ADDR +#define WF_PLE_TOP_AC2_QUEUE_EMPTY5_AC2_QUEUE_EMPTY_5_MASK \ +0xFFFFFFFF /* AC2_QUEUE_EMPTY_5[31..0] */ +#define WF_PLE_TOP_AC2_QUEUE_EMPTY5_AC2_QUEUE_EMPTY_5_SHFT 0 + +/* +* ---AC2_QUEUE_EMPTY6 (0x820C0000 + 0x598)--- +* AC2_QUEUE_EMPTY_6[31..0] - (RO) Empty flag for STA 192~223 AC2 queue +*/ +#define WF_PLE_TOP_AC2_QUEUE_EMPTY6_AC2_QUEUE_EMPTY_6_ADDR \ +WF_PLE_TOP_AC2_QUEUE_EMPTY6_ADDR +#define WF_PLE_TOP_AC2_QUEUE_EMPTY6_AC2_QUEUE_EMPTY_6_MASK \ +0xFFFFFFFF /* AC2_QUEUE_EMPTY_6[31..0] */ +#define WF_PLE_TOP_AC2_QUEUE_EMPTY6_AC2_QUEUE_EMPTY_6_SHFT 0 + +/* +* ---AC2_QUEUE_EMPTY7 (0x820C0000 + 0x59c)--- +* AC2_QUEUE_EMPTY_7[31..0] - (RO) Empty flag for STA 224~255 AC2 queue +*/ +#define WF_PLE_TOP_AC2_QUEUE_EMPTY7_AC2_QUEUE_EMPTY_7_ADDR \ +WF_PLE_TOP_AC2_QUEUE_EMPTY7_ADDR +#define WF_PLE_TOP_AC2_QUEUE_EMPTY7_AC2_QUEUE_EMPTY_7_MASK \ +0xFFFFFFFF /* AC2_QUEUE_EMPTY_7[31..0] */ +#define WF_PLE_TOP_AC2_QUEUE_EMPTY7_AC2_QUEUE_EMPTY_7_SHFT 0 + +/* +* ---AC2_QUEUE_EMPTY8 (0x820C0000 + 0x5a0)--- +* AC2_QUEUE_EMPTY_8[31..0] - (RO) Empty flag for STA 256~287 AC2 queue +*/ +#define WF_PLE_TOP_AC2_QUEUE_EMPTY8_AC2_QUEUE_EMPTY_8_ADDR \ +WF_PLE_TOP_AC2_QUEUE_EMPTY8_ADDR +#define WF_PLE_TOP_AC2_QUEUE_EMPTY8_AC2_QUEUE_EMPTY_8_MASK \ +0xFFFFFFFF /* AC2_QUEUE_EMPTY_8[31..0] */ +#define WF_PLE_TOP_AC2_QUEUE_EMPTY8_AC2_QUEUE_EMPTY_8_SHFT 0 + +/* +* ---AC3_QUEUE_EMPTY0 (0x820C0000 + 0x5c0)--- +* AC3_QUEUE_EMPTY_0[31..0] - (RO) Empty flag for STA 0~31 AC3 queue +*/ +#define WF_PLE_TOP_AC3_QUEUE_EMPTY0_AC3_QUEUE_EMPTY_0_ADDR \ +WF_PLE_TOP_AC3_QUEUE_EMPTY0_ADDR +#define WF_PLE_TOP_AC3_QUEUE_EMPTY0_AC3_QUEUE_EMPTY_0_MASK \ +0xFFFFFFFF /* AC3_QUEUE_EMPTY_0[31..0] */ +#define WF_PLE_TOP_AC3_QUEUE_EMPTY0_AC3_QUEUE_EMPTY_0_SHFT 0 + +/* +* ---AC3_QUEUE_EMPTY1 (0x820C0000 + 0x5c4)--- +* AC3_QUEUE_EMPTY_1[31..0] - (RO) Empty flag for STA 32~63 AC3 queue +*/ +#define WF_PLE_TOP_AC3_QUEUE_EMPTY1_AC3_QUEUE_EMPTY_1_ADDR \ +WF_PLE_TOP_AC3_QUEUE_EMPTY1_ADDR +#define WF_PLE_TOP_AC3_QUEUE_EMPTY1_AC3_QUEUE_EMPTY_1_MASK \ +0xFFFFFFFF /* AC3_QUEUE_EMPTY_1[31..0] */ +#define WF_PLE_TOP_AC3_QUEUE_EMPTY1_AC3_QUEUE_EMPTY_1_SHFT 0 + +/* +* ---AC3_QUEUE_EMPTY2 (0x820C0000 + 0x5c8)--- +* AC3_QUEUE_EMPTY_2[31..0] - (RO) Empty flag for STA 64~95 AC3 queue +*/ +#define WF_PLE_TOP_AC3_QUEUE_EMPTY2_AC3_QUEUE_EMPTY_2_ADDR \ +WF_PLE_TOP_AC3_QUEUE_EMPTY2_ADDR +#define WF_PLE_TOP_AC3_QUEUE_EMPTY2_AC3_QUEUE_EMPTY_2_MASK \ +0xFFFFFFFF /* AC3_QUEUE_EMPTY_2[31..0] */ +#define WF_PLE_TOP_AC3_QUEUE_EMPTY2_AC3_QUEUE_EMPTY_2_SHFT 0 + +/* +* ---AC3_QUEUE_EMPTY3 (0x820C0000 + 0x5cc)--- +* AC3_QUEUE_EMPTY_3[31..0] - (RO) Empty flag for STA 96~127 AC3 queue +*/ +#define WF_PLE_TOP_AC3_QUEUE_EMPTY3_AC3_QUEUE_EMPTY_3_ADDR \ +WF_PLE_TOP_AC3_QUEUE_EMPTY3_ADDR +#define WF_PLE_TOP_AC3_QUEUE_EMPTY3_AC3_QUEUE_EMPTY_3_MASK \ +0xFFFFFFFF /* AC3_QUEUE_EMPTY_3[31..0] */ +#define WF_PLE_TOP_AC3_QUEUE_EMPTY3_AC3_QUEUE_EMPTY_3_SHFT 0 + +/* +* ---AC3_QUEUE_EMPTY4 (0x820C0000 + 0x5d0)--- +* AC3_QUEUE_EMPTY_4_0[7..0] - (RO) Empty flag for STA 128~135 AC3 queue +* AC3_QUEUE_EMPTY_4_1[15..8] - (RO) Empty flag for STA 136~143 AC3 queue +* AC3_QUEUE_EMPTY_4_2[31..16] - (RO) Empty flag for STA 144~159 AC3 queue +*/ +#define WF_PLE_TOP_AC3_QUEUE_EMPTY4_AC3_QUEUE_EMPTY_4_2_ADDR \ +WF_PLE_TOP_AC3_QUEUE_EMPTY4_ADDR +#define WF_PLE_TOP_AC3_QUEUE_EMPTY4_AC3_QUEUE_EMPTY_4_2_MASK \ +0xFFFF0000 /* AC3_QUEUE_EMPTY_4_2[31..16] */ +#define WF_PLE_TOP_AC3_QUEUE_EMPTY4_AC3_QUEUE_EMPTY_4_2_SHFT 16 +#define WF_PLE_TOP_AC3_QUEUE_EMPTY4_AC3_QUEUE_EMPTY_4_1_ADDR \ +WF_PLE_TOP_AC3_QUEUE_EMPTY4_ADDR +#define WF_PLE_TOP_AC3_QUEUE_EMPTY4_AC3_QUEUE_EMPTY_4_1_MASK \ +0x0000FF00 /* AC3_QUEUE_EMPTY_4_1[15..8] */ +#define WF_PLE_TOP_AC3_QUEUE_EMPTY4_AC3_QUEUE_EMPTY_4_1_SHFT 8 +#define WF_PLE_TOP_AC3_QUEUE_EMPTY4_AC3_QUEUE_EMPTY_4_0_ADDR \ +WF_PLE_TOP_AC3_QUEUE_EMPTY4_ADDR +#define WF_PLE_TOP_AC3_QUEUE_EMPTY4_AC3_QUEUE_EMPTY_4_0_MASK \ +0x000000FF /* AC3_QUEUE_EMPTY_4_0[7..0] */ +#define WF_PLE_TOP_AC3_QUEUE_EMPTY4_AC3_QUEUE_EMPTY_4_0_SHFT 0 + +/* +* ---AC3_QUEUE_EMPTY5 (0x820C0000 + 0x5d4)--- +* AC3_QUEUE_EMPTY_5[31..0] - (RO) Empty flag for STA 160~191 AC3 queue +*/ +#define WF_PLE_TOP_AC3_QUEUE_EMPTY5_AC3_QUEUE_EMPTY_5_ADDR \ +WF_PLE_TOP_AC3_QUEUE_EMPTY5_ADDR +#define WF_PLE_TOP_AC3_QUEUE_EMPTY5_AC3_QUEUE_EMPTY_5_MASK \ +0xFFFFFFFF /* AC3_QUEUE_EMPTY_5[31..0] */ +#define WF_PLE_TOP_AC3_QUEUE_EMPTY5_AC3_QUEUE_EMPTY_5_SHFT 0 + +/* +* ---AC3_QUEUE_EMPTY6 (0x820C0000 + 0x5d8)--- +* AC3_QUEUE_EMPTY_6[31..0] - (RO) Empty flag for STA 192~223 AC3 queue +*/ +#define WF_PLE_TOP_AC3_QUEUE_EMPTY6_AC3_QUEUE_EMPTY_6_ADDR \ +WF_PLE_TOP_AC3_QUEUE_EMPTY6_ADDR +#define WF_PLE_TOP_AC3_QUEUE_EMPTY6_AC3_QUEUE_EMPTY_6_MASK \ +0xFFFFFFFF /* AC3_QUEUE_EMPTY_6[31..0] */ +#define WF_PLE_TOP_AC3_QUEUE_EMPTY6_AC3_QUEUE_EMPTY_6_SHFT 0 + +/* +* ---AC3_QUEUE_EMPTY7 (0x820C0000 + 0x5dc)--- +* AC3_QUEUE_EMPTY_7[31..0] - (RO) Empty flag for STA 224~255 AC3 queue +*/ +#define WF_PLE_TOP_AC3_QUEUE_EMPTY7_AC3_QUEUE_EMPTY_7_ADDR \ +WF_PLE_TOP_AC3_QUEUE_EMPTY7_ADDR +#define WF_PLE_TOP_AC3_QUEUE_EMPTY7_AC3_QUEUE_EMPTY_7_MASK \ +0xFFFFFFFF /* AC3_QUEUE_EMPTY_7[31..0] */ +#define WF_PLE_TOP_AC3_QUEUE_EMPTY7_AC3_QUEUE_EMPTY_7_SHFT 0 + +/* +* ---AC3_QUEUE_EMPTY8 (0x820C0000 + 0x5e0)--- +* AC3_QUEUE_EMPTY_8[31..0] - (RO) Empty flag for STA 256~287 AC3 queue +*/ +#define WF_PLE_TOP_AC3_QUEUE_EMPTY8_AC3_QUEUE_EMPTY_8_ADDR \ +WF_PLE_TOP_AC3_QUEUE_EMPTY8_ADDR +#define WF_PLE_TOP_AC3_QUEUE_EMPTY8_AC3_QUEUE_EMPTY_8_MASK \ +0xFFFFFFFF /* AC3_QUEUE_EMPTY_8[31..0] */ +#define WF_PLE_TOP_AC3_QUEUE_EMPTY8_AC3_QUEUE_EMPTY_8_SHFT 0 + +/* +* ---DRR_TABLE_WDATA4 (0x820C0000 + 0x680)--- +* DRR_TABLE_WDATA[31..0] - (RW) DRRwdata[159:128] for reading/writing +* DRR table +* Mode 0x4?: BSS mode +* See SRAM layout. +*/ +#define WF_PLE_TOP_DRR_TABLE_WDATA4_DRR_TABLE_WDATA_ADDR \ +WF_PLE_TOP_DRR_TABLE_WDATA4_ADDR +#define WF_PLE_TOP_DRR_TABLE_WDATA4_DRR_TABLE_WDATA_MASK \ +0xFFFFFFFF /* DRR_TABLE_WDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_WDATA4_DRR_TABLE_WDATA_SHFT 0 + +/* +* ---DRR_TABLE_WDATA5 (0x820C0000 + 0x684)--- +* DRR_TABLE_WDATA[31..0] - (RW) DRR wdata[191:160] for reading/writing +* DRR table +*/ +#define WF_PLE_TOP_DRR_TABLE_WDATA5_DRR_TABLE_WDATA_ADDR \ +WF_PLE_TOP_DRR_TABLE_WDATA5_ADDR +#define WF_PLE_TOP_DRR_TABLE_WDATA5_DRR_TABLE_WDATA_MASK \ +0xFFFFFFFF /* DRR_TABLE_WDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_WDATA5_DRR_TABLE_WDATA_SHFT 0 + +/* +* ---DRR_TABLE_WDATA6 (0x820C0000 + 0x688)--- +* DRR_TABLE_WDATA[31..0] - (RW) DRR wdata[223:192] for reading/writing +* DRR table +*/ +#define WF_PLE_TOP_DRR_TABLE_WDATA6_DRR_TABLE_WDATA_ADDR \ +WF_PLE_TOP_DRR_TABLE_WDATA6_ADDR +#define WF_PLE_TOP_DRR_TABLE_WDATA6_DRR_TABLE_WDATA_MASK \ +0xFFFFFFFF /* DRR_TABLE_WDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_WDATA6_DRR_TABLE_WDATA_SHFT 0 + +/* +* ---DRR_TABLE_WDATA7 (0x820C0000 + 0x68c)--- +* DRR_TABLE_WDATA[31..0] - (RW) DRR wdata[255:224] for reading/writing +* DRR table +*/ +#define WF_PLE_TOP_DRR_TABLE_WDATA7_DRR_TABLE_WDATA_ADDR \ +WF_PLE_TOP_DRR_TABLE_WDATA7_ADDR +#define WF_PLE_TOP_DRR_TABLE_WDATA7_DRR_TABLE_WDATA_MASK \ +0xFFFFFFFF /* DRR_TABLE_WDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_WDATA7_DRR_TABLE_WDATA_SHFT 0 + +/* +* ---DRR_TABLE_RDATA4 (0x820C0000 + 0x690)--- +* DRR_TABLE_RDATA[31..0] - (RW) DRR rdata[159:128] for reading/writing +* DRR table +*/ +#define WF_PLE_TOP_DRR_TABLE_RDATA4_DRR_TABLE_RDATA_ADDR \ +WF_PLE_TOP_DRR_TABLE_RDATA4_ADDR +#define WF_PLE_TOP_DRR_TABLE_RDATA4_DRR_TABLE_RDATA_MASK \ +0xFFFFFFFF /* DRR_TABLE_RDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_RDATA4_DRR_TABLE_RDATA_SHFT 0 + +/* +* ---DRR_TABLE_RDATA5 (0x820C0000 + 0x694)--- +* DRR_TABLE_RDATA[31..0] - (RW) DRR rdata[191:160] for reading/writing +* DRR table +*/ +#define WF_PLE_TOP_DRR_TABLE_RDATA5_DRR_TABLE_RDATA_ADDR \ +WF_PLE_TOP_DRR_TABLE_RDATA5_ADDR +#define WF_PLE_TOP_DRR_TABLE_RDATA5_DRR_TABLE_RDATA_MASK \ +0xFFFFFFFF /* DRR_TABLE_RDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_RDATA5_DRR_TABLE_RDATA_SHFT 0 + +/* +* ---DRR_TABLE_RDATA6 (0x820C0000 + 0x698)--- +* DRR_TABLE_RDATA[31..0] - (RW) DRR rdata[223:192] for reading/writing +* DRR table +*/ +#define WF_PLE_TOP_DRR_TABLE_RDATA6_DRR_TABLE_RDATA_ADDR \ +WF_PLE_TOP_DRR_TABLE_RDATA6_ADDR +#define WF_PLE_TOP_DRR_TABLE_RDATA6_DRR_TABLE_RDATA_MASK \ +0xFFFFFFFF /* DRR_TABLE_RDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_RDATA6_DRR_TABLE_RDATA_SHFT 0 + +/* +* ---DRR_TABLE_RDATA7 (0x820C0000 + 0x69c)--- +* DRR_TABLE_RDATA[31..0] - (RW) DRR rdata[255:224] for reading/writing +* DRR table +*/ +#define WF_PLE_TOP_DRR_TABLE_RDATA7_DRR_TABLE_RDATA_ADDR \ +WF_PLE_TOP_DRR_TABLE_RDATA7_ADDR +#define WF_PLE_TOP_DRR_TABLE_RDATA7_DRR_TABLE_RDATA_MASK \ +0xFFFFFFFF /* DRR_TABLE_RDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_RDATA7_DRR_TABLE_RDATA_SHFT 0 + +/* +* ---TWT_STA_TABLE0 (0x820C0000 + 0x6a0)--- +* TWT_STA_0[9..0] - (RW) TWT station 0 WLAN ID +* RESERVED10[15..10] - (RO) Reserved bits +* TWT_STA_1[25..16] - (RW) TWT station 1 WLAN ID +* RESERVED26[31..26] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_TWT_STA_TABLE0_TWT_STA_1_ADDR WF_PLE_TOP_TWT_STA_TABLE0_ADDR +#define WF_PLE_TOP_TWT_STA_TABLE0_TWT_STA_1_MASK \ +0x03FF0000 /* TWT_STA_1[25..16] */ +#define WF_PLE_TOP_TWT_STA_TABLE0_TWT_STA_1_SHFT 16 +#define WF_PLE_TOP_TWT_STA_TABLE0_TWT_STA_0_ADDR WF_PLE_TOP_TWT_STA_TABLE0_ADDR +#define WF_PLE_TOP_TWT_STA_TABLE0_TWT_STA_0_MASK \ +0x000003FF /* TWT_STA_0[9..0] */ +#define WF_PLE_TOP_TWT_STA_TABLE0_TWT_STA_0_SHFT 0 + +/* +* ---TWT_STA_TABLE1 (0x820C0000 + 0x6a4)--- +* TWT_STA_2[9..0] - (RW) TWT station 2 WLAN ID +* RESERVED10[15..10] - (RO) Reserved bits +* TWT_STA_3[25..16] - (RW) TWT station 3 WLAN ID +* RESERVED26[31..26] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_TWT_STA_TABLE1_TWT_STA_3_ADDR WF_PLE_TOP_TWT_STA_TABLE1_ADDR +#define WF_PLE_TOP_TWT_STA_TABLE1_TWT_STA_3_MASK \ +0x03FF0000 /* TWT_STA_3[25..16] */ +#define WF_PLE_TOP_TWT_STA_TABLE1_TWT_STA_3_SHFT 16 +#define WF_PLE_TOP_TWT_STA_TABLE1_TWT_STA_2_ADDR WF_PLE_TOP_TWT_STA_TABLE1_ADDR +#define WF_PLE_TOP_TWT_STA_TABLE1_TWT_STA_2_MASK \ +0x000003FF /* TWT_STA_2[9..0] */ +#define WF_PLE_TOP_TWT_STA_TABLE1_TWT_STA_2_SHFT 0 + +/* +* ---TWT_STA_TABLE2 (0x820C0000 + 0x6a8)--- +* TWT_STA_4[9..0] - (RW) TWT station 4 WLAN ID +* RESERVED10[15..10] - (RO) Reserved bits +* TWT_STA_5[25..16] - (RW) TWT station 5 WLAN ID +* RESERVED26[31..26] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_TWT_STA_TABLE2_TWT_STA_5_ADDR WF_PLE_TOP_TWT_STA_TABLE2_ADDR +#define WF_PLE_TOP_TWT_STA_TABLE2_TWT_STA_5_MASK \ +0x03FF0000 /* TWT_STA_5[25..16] */ +#define WF_PLE_TOP_TWT_STA_TABLE2_TWT_STA_5_SHFT 16 +#define WF_PLE_TOP_TWT_STA_TABLE2_TWT_STA_4_ADDR WF_PLE_TOP_TWT_STA_TABLE2_ADDR +#define WF_PLE_TOP_TWT_STA_TABLE2_TWT_STA_4_MASK \ +0x000003FF /* TWT_STA_4[9..0] */ +#define WF_PLE_TOP_TWT_STA_TABLE2_TWT_STA_4_SHFT 0 + +/* +* ---TWT_STA_TABLE3 (0x820C0000 + 0x6ac)--- +* TWT_STA_6[9..0] - (RW) TWT station 6 WLAN ID +* RESERVED10[15..10] - (RO) Reserved bits +* TWT_STA_7[25..16] - (RW) TWT station 7 WLAN ID +* RESERVED26[31..26] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_TWT_STA_TABLE3_TWT_STA_7_ADDR WF_PLE_TOP_TWT_STA_TABLE3_ADDR +#define WF_PLE_TOP_TWT_STA_TABLE3_TWT_STA_7_MASK \ +0x03FF0000 /* TWT_STA_7[25..16] */ +#define WF_PLE_TOP_TWT_STA_TABLE3_TWT_STA_7_SHFT 16 +#define WF_PLE_TOP_TWT_STA_TABLE3_TWT_STA_6_ADDR WF_PLE_TOP_TWT_STA_TABLE3_ADDR +#define WF_PLE_TOP_TWT_STA_TABLE3_TWT_STA_6_MASK \ +0x000003FF /* TWT_STA_6[9..0] */ +#define WF_PLE_TOP_TWT_STA_TABLE3_TWT_STA_6_SHFT 0 + +/* +* ---TWT_SW_CTRL (0x820C0000 + 0x6b0)--- +* INDEX[15..0] - (RW) Operation index +* Mode 0x00/0x01/0x08/0x09: Bit[3:0]: station +number +* Mode 0x10/0x11: Bit[3:0]: table index +* MODE[23..16] - (RW) IO software command mode +* RESERVED24[29..24] - (RO) Reserved bits +* SRCH_CMD_DROP[30] - (W1C) IO search command drop flag due to +* command FIFO full +* EXECUTE[31] - (RW) Executes SW command to trigger TWT +* search event and add/remove TWT station +*/ +#define WF_PLE_TOP_TWT_SW_CTRL_EXECUTE_ADDR WF_PLE_TOP_TWT_SW_CTRL_ADDR +#define WF_PLE_TOP_TWT_SW_CTRL_EXECUTE_MASK 0x80000000 /* EXECUTE[31] */ +#define WF_PLE_TOP_TWT_SW_CTRL_EXECUTE_SHFT 31 +#define WF_PLE_TOP_TWT_SW_CTRL_SRCH_CMD_DROP_ADDR WF_PLE_TOP_TWT_SW_CTRL_ADDR +#define WF_PLE_TOP_TWT_SW_CTRL_SRCH_CMD_DROP_MASK \ +0x40000000 /* SRCH_CMD_DROP[30] */ +#define WF_PLE_TOP_TWT_SW_CTRL_SRCH_CMD_DROP_SHFT 30 +#define WF_PLE_TOP_TWT_SW_CTRL_MODE_ADDR WF_PLE_TOP_TWT_SW_CTRL_ADDR +#define WF_PLE_TOP_TWT_SW_CTRL_MODE_MASK 0x00FF0000 /* MODE[23..16] */ +#define WF_PLE_TOP_TWT_SW_CTRL_MODE_SHFT 16 +#define WF_PLE_TOP_TWT_SW_CTRL_INDEX_ADDR WF_PLE_TOP_TWT_SW_CTRL_ADDR +#define WF_PLE_TOP_TWT_SW_CTRL_INDEX_MASK 0x0000FFFF /* INDEX[15..0] */ +#define WF_PLE_TOP_TWT_SW_CTRL_INDEX_SHFT 0 + +/* +* ---TWT_DBG (0x820C0000 + 0x6b4)--- +* TABLE_IDX_SEL[2..0] - (RW) Station index selection +* UL_TABLE_SEL[3] - (RW) Downlink/uplink station table selection +* RESERVED4[15..4] - (RO) Reserved bits +* TABLE_WLAN_ID[25..16] - (RO) Station WLAN ID in station table +* RESERVED26[27..26] - (RO) Reserved bits +* STA_CNT[31..28] - (RO) Valid station count in station table +*/ +#define WF_PLE_TOP_TWT_DBG_STA_CNT_ADDR WF_PLE_TOP_TWT_DBG_ADDR +#define WF_PLE_TOP_TWT_DBG_STA_CNT_MASK 0xF0000000 /* STA_CNT[31..28] */ +#define WF_PLE_TOP_TWT_DBG_STA_CNT_SHFT 28 +#define WF_PLE_TOP_TWT_DBG_TABLE_WLAN_ID_ADDR WF_PLE_TOP_TWT_DBG_ADDR +#define WF_PLE_TOP_TWT_DBG_TABLE_WLAN_ID_MASK \ +0x03FF0000 /* TABLE_WLAN_ID[25..16] */ +#define WF_PLE_TOP_TWT_DBG_TABLE_WLAN_ID_SHFT 16 +#define WF_PLE_TOP_TWT_DBG_UL_TABLE_SEL_ADDR WF_PLE_TOP_TWT_DBG_ADDR +#define WF_PLE_TOP_TWT_DBG_UL_TABLE_SEL_MASK 0x00000008 /* UL_TABLE_SEL[3] */ +#define WF_PLE_TOP_TWT_DBG_UL_TABLE_SEL_SHFT 3 +#define WF_PLE_TOP_TWT_DBG_TABLE_IDX_SEL_ADDR WF_PLE_TOP_TWT_DBG_ADDR +#define WF_PLE_TOP_TWT_DBG_TABLE_IDX_SEL_MASK \ +0x00000007 /* TABLE_IDX_SEL[2..0] */ +#define WF_PLE_TOP_TWT_DBG_TABLE_IDX_SEL_SHFT 0 + +/* +* ---TWT_HW_SRCHCMD_FULL (0x820C0000 + 0x6b8)--- +* TWT_SRCH_DL_FULL[0] - (RW) TWT hardware downlink search command +* full flag +* TWT_SRCH_UL_FULL[1] - (RW) TWT hardware uplink search command full +flag +* RESERVED2[31..2] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_TWT_HW_SRCHCMD_FULL_TWT_SRCH_UL_FULL_ADDR \ +WF_PLE_TOP_TWT_HW_SRCHCMD_FULL_ADDR +#define WF_PLE_TOP_TWT_HW_SRCHCMD_FULL_TWT_SRCH_UL_FULL_MASK \ +0x00000002 /* TWT_SRCH_UL_FULL[1] */ +#define WF_PLE_TOP_TWT_HW_SRCHCMD_FULL_TWT_SRCH_UL_FULL_SHFT 1 +#define WF_PLE_TOP_TWT_HW_SRCHCMD_FULL_TWT_SRCH_DL_FULL_ADDR \ +WF_PLE_TOP_TWT_HW_SRCHCMD_FULL_ADDR +#define WF_PLE_TOP_TWT_HW_SRCHCMD_FULL_TWT_SRCH_DL_FULL_MASK \ +0x00000001 /* TWT_SRCH_DL_FULL[0] */ +#define WF_PLE_TOP_TWT_HW_SRCHCMD_FULL_TWT_SRCH_DL_FULL_SHFT 0 + +/* +* ---SPL_GEN_CTRL (0x820C0000 + 0x700)--- +* EN_PLE_SPL[0] - (RW) Enable control of PLE generate SPL +* report function. +* RESERVED1[7..1] - (RO) Reserved bits +* RPT_TWT_IN_AC_SPL[8] - (RW) Enable control of TWT station in WMMAC +* SPL report. +* RESERVED9[31..9] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_SPL_GEN_CTRL_RPT_TWT_IN_AC_SPL_ADDR \ +WF_PLE_TOP_SPL_GEN_CTRL_ADDR +#define WF_PLE_TOP_SPL_GEN_CTRL_RPT_TWT_IN_AC_SPL_MASK \ +0x00000100 /* RPT_TWT_IN_AC_SPL[8] */ +#define WF_PLE_TOP_SPL_GEN_CTRL_RPT_TWT_IN_AC_SPL_SHFT 8 +#define WF_PLE_TOP_SPL_GEN_CTRL_EN_PLE_SPL_ADDR WF_PLE_TOP_SPL_GEN_CTRL_ADDR +#define WF_PLE_TOP_SPL_GEN_CTRL_EN_PLE_SPL_MASK 0x00000001 /* EN_PLE_SPL[0] */ +#define WF_PLE_TOP_SPL_GEN_CTRL_EN_PLE_SPL_SHFT 0 + +/* +* ---AMSDU_GC (0x820C0000 + 0x1000)--- +* EN_HW_AMSDU[0] - (RW) Enable control of HW AMSDU function. +* RESERVED1[7..1] - (RO) Reserved bits +* DIS_AMSDU_Q_EMPTY_FLUSH[8] - (RW) Disable control of HW AMSDU queue empty +* trigger packet flush function. +* DIS_LMAC_TX_NO_FULL_FLUSH[9] - (RW) Disable control of LMAC TX no get full +* packet trigger packet flush function. +* DIS_SFD_KEEP_SAME_PAGE[10] - (RW) Disable control of keep same page number +* of StoreForward packet function. +* RESERVED11[31..11] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_AMSDU_GC_DIS_SFD_KEEP_SAME_PAGE_ADDR WF_PLE_TOP_AMSDU_GC_ADDR +#define WF_PLE_TOP_AMSDU_GC_DIS_SFD_KEEP_SAME_PAGE_MASK \ +0x00000400 /* DIS_SFD_KEEP_SAME_PAGE[10] */ +#define WF_PLE_TOP_AMSDU_GC_DIS_SFD_KEEP_SAME_PAGE_SHFT 10 +#define WF_PLE_TOP_AMSDU_GC_DIS_LMAC_TX_NO_FULL_FLUSH_ADDR \ +WF_PLE_TOP_AMSDU_GC_ADDR +#define WF_PLE_TOP_AMSDU_GC_DIS_LMAC_TX_NO_FULL_FLUSH_MASK \ +0x00000200 /* DIS_LMAC_TX_NO_FULL_FLUSH[9] */ +#define WF_PLE_TOP_AMSDU_GC_DIS_LMAC_TX_NO_FULL_FLUSH_SHFT 9 +#define WF_PLE_TOP_AMSDU_GC_DIS_AMSDU_Q_EMPTY_FLUSH_ADDR \ +WF_PLE_TOP_AMSDU_GC_ADDR +#define WF_PLE_TOP_AMSDU_GC_DIS_AMSDU_Q_EMPTY_FLUSH_MASK \ +0x00000100 /* DIS_AMSDU_Q_EMPTY_FLUSH[8] */ +#define WF_PLE_TOP_AMSDU_GC_DIS_AMSDU_Q_EMPTY_FLUSH_SHFT 8 +#define WF_PLE_TOP_AMSDU_GC_EN_HW_AMSDU_ADDR WF_PLE_TOP_AMSDU_GC_ADDR +#define WF_PLE_TOP_AMSDU_GC_EN_HW_AMSDU_MASK 0x00000001 /* EN_HW_AMSDU[0] */ +#define WF_PLE_TOP_AMSDU_GC_EN_HW_AMSDU_SHFT 0 + +/* +* ---AMSDU_TXD_COMP_MAP_0 (0x820C0000 + 0x1004)--- +* TXDIN_TRIGGER_TH[11..0] - (RW) The TXD merge trigger threshold. +* RESERVED12[15..12] - (RO) Reserved bits +* TXD_COMPARE_NEED_MAP[31..16] - (RW) The compare bitmap for merging TXD. +*/ +#define WF_PLE_TOP_AMSDU_TXD_COMP_MAP_0_TXD_COMPARE_NEED_MAP_ADDR \ +WF_PLE_TOP_AMSDU_TXD_COMP_MAP_0_ADDR +#define WF_PLE_TOP_AMSDU_TXD_COMP_MAP_0_TXD_COMPARE_NEED_MAP_MASK \ +0xFFFF0000 /* TXD_COMPARE_NEED_MAP[31..16] */ +#define WF_PLE_TOP_AMSDU_TXD_COMP_MAP_0_TXD_COMPARE_NEED_MAP_SHFT 16 +#define WF_PLE_TOP_AMSDU_TXD_COMP_MAP_0_TXDIN_TRIGGER_TH_ADDR \ +WF_PLE_TOP_AMSDU_TXD_COMP_MAP_0_ADDR +#define WF_PLE_TOP_AMSDU_TXD_COMP_MAP_0_TXDIN_TRIGGER_TH_MASK \ +0x00000FFF /* TXDIN_TRIGGER_TH[11..0] */ +#define WF_PLE_TOP_AMSDU_TXD_COMP_MAP_0_TXDIN_TRIGGER_TH_SHFT 0 + +/* +* ---AMSDU_TXD_COMP_MAP_1 (0x820C0000 + 0x1008)--- +* TXD_COMPARE_NEED_MAP[31..0] - (RW) The compare bitmap for merging TXD. +*/ +#define WF_PLE_TOP_AMSDU_TXD_COMP_MAP_1_TXD_COMPARE_NEED_MAP_ADDR \ +WF_PLE_TOP_AMSDU_TXD_COMP_MAP_1_ADDR +#define WF_PLE_TOP_AMSDU_TXD_COMP_MAP_1_TXD_COMPARE_NEED_MAP_MASK \ +0xFFFFFFFF /* TXD_COMPARE_NEED_MAP[31..0] */ +#define WF_PLE_TOP_AMSDU_TXD_COMP_MAP_1_TXD_COMPARE_NEED_MAP_SHFT 0 + +/* +* ---AMSDU_INT_N9_ERR_STS (0x820C0000 + 0x1028)--- +* AMSDU_Q_CMD_ERR[0] - (W1C) Queue command error interrupt status of +* port AMSDU. Avoid unclear error flag, please clear flag when logic reset. +* RESERVED1[3..1] - (RO) Reserved bits +* AMSDU_PAGE_UDF[4] - (W1C) Page underflow interrupt status of port +* AMSDU. Avoid unclear error flag, please clear flag when logic reset. +* RESERVED5[11..5] - (RO) Reserved bits +* AMSDU_DATA_OPER_ERR[12] - (W1C) Data operation error of port AMSDU. +* Avoid unclear error flag, please clear flag when logic reset. +* RESERVED13[15..13] - (RO) Reserved bits +* AMSDU_PORT_HANG_ERR[16] - (W1C) AMSDU port FSM hang error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* AMSDU_CTRL_HANG_ERR[17] - (W1C) AMSDU FSM hang error interrupt. Avoid +* unclear error flag, please clear flag when logic reset. +* RESERVED18[31..18] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_CTRL_HANG_ERR_ADDR \ +WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_CTRL_HANG_ERR_MASK \ +0x00020000 /* AMSDU_CTRL_HANG_ERR[17] */ +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_CTRL_HANG_ERR_SHFT 17 +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_PORT_HANG_ERR_ADDR \ +WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_PORT_HANG_ERR_MASK \ +0x00010000 /* AMSDU_PORT_HANG_ERR[16] */ +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_PORT_HANG_ERR_SHFT 16 +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_DATA_OPER_ERR_ADDR \ +WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_DATA_OPER_ERR_MASK \ +0x00001000 /* AMSDU_DATA_OPER_ERR[12] */ +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_DATA_OPER_ERR_SHFT 12 +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_PAGE_UDF_ADDR \ +WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_PAGE_UDF_MASK \ +0x00000010 /* AMSDU_PAGE_UDF[4] */ +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_PAGE_UDF_SHFT 4 +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_Q_CMD_ERR_ADDR \ +WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_Q_CMD_ERR_MASK \ +0x00000001 /* AMSDU_Q_CMD_ERR[0] */ +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_Q_CMD_ERR_SHFT 0 + +/* +* ---AMSDU_INT_N9_ERR_MASK (0x820C0000 + 0x102C)--- +* EN_AMSDU_Q_CMD_ERR[0] - (RW) Enables queue command error interrupt +* status of port AMSDU +* RESERVED1[3..1] - (RO) Reserved bits +* EN_AMSDU_PAGE_UDF[4] - (RW) Enables page underflow interrupt status +* of port AMSDU +* RESERVED5[11..5] - (RO) Reserved bits +* EN_AMSDU_DATA_OPER_ERR[12] - (RW) Enables data operation error of port +AMSDU +* RESERVED13[15..13] - (RO) Reserved bits +* EN_AMSDU_PORT_HANG_ERR[16] - (RW) Enables AMSDU port FSM hang error +interrupt +* EN_AMSDU_CTRL_HANG_ERR[17] - (RW) Enables AMSDU CTRL FSM hang error +interrupt +* RESERVED18[31..18] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_CTRL_HANG_ERR_ADDR \ +WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_CTRL_HANG_ERR_MASK \ +0x00020000 /* EN_AMSDU_CTRL_HANG_ERR[17] */ +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_CTRL_HANG_ERR_SHFT 17 +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_PORT_HANG_ERR_ADDR \ +WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_PORT_HANG_ERR_MASK \ +0x00010000 /* EN_AMSDU_PORT_HANG_ERR[16] */ +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_PORT_HANG_ERR_SHFT 16 +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_DATA_OPER_ERR_ADDR \ +WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_DATA_OPER_ERR_MASK \ +0x00001000 /* EN_AMSDU_DATA_OPER_ERR[12] */ +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_DATA_OPER_ERR_SHFT 12 +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_PAGE_UDF_ADDR \ +WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_PAGE_UDF_MASK \ +0x00000010 /* EN_AMSDU_PAGE_UDF[4] */ +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_PAGE_UDF_SHFT 4 +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_Q_CMD_ERR_ADDR \ +WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_Q_CMD_ERR_MASK \ +0x00000001 /* EN_AMSDU_Q_CMD_ERR[0] */ +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_Q_CMD_ERR_SHFT 0 + +/* +* ---AMSDU_PEEK_CR_00 (0x820C0000 + 0x10d0)--- +* AMSDU_DOP_CS[3..0] - (RO) AMSDU Data operation current state. +* RESERVED4[7..4] - (RO) Reserved bits +* AMSDU_CS[12..8] - (RO) AMSDU Merge Engine current state. +* RESERVED13[15..13] - (RO) Reserved bits +* AMSDU_Q_EMPTY_CS[17..16] - (RO) AMSDU Queue Empty Search Engine current +state. +* RESERVED18[23..18] - (RO) Reserved bits +* AMSDU_ARB_CS[26..24] - (RO) AMSDU Request Arbitration Current state. +* RESERVED27[31..27] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_AMSDU_PEEK_CR_00_AMSDU_ARB_CS_ADDR \ +WF_PLE_TOP_AMSDU_PEEK_CR_00_ADDR +#define WF_PLE_TOP_AMSDU_PEEK_CR_00_AMSDU_ARB_CS_MASK \ +0x07000000 /* AMSDU_ARB_CS[26..24] */ +#define WF_PLE_TOP_AMSDU_PEEK_CR_00_AMSDU_ARB_CS_SHFT 24 +#define WF_PLE_TOP_AMSDU_PEEK_CR_00_AMSDU_Q_EMPTY_CS_ADDR \ +WF_PLE_TOP_AMSDU_PEEK_CR_00_ADDR +#define WF_PLE_TOP_AMSDU_PEEK_CR_00_AMSDU_Q_EMPTY_CS_MASK \ +0x00030000 /* AMSDU_Q_EMPTY_CS[17..16] */ +#define WF_PLE_TOP_AMSDU_PEEK_CR_00_AMSDU_Q_EMPTY_CS_SHFT 16 +#define WF_PLE_TOP_AMSDU_PEEK_CR_00_AMSDU_CS_ADDR \ +WF_PLE_TOP_AMSDU_PEEK_CR_00_ADDR +#define WF_PLE_TOP_AMSDU_PEEK_CR_00_AMSDU_CS_MASK \ +0x00001F00 /* AMSDU_CS[12..8] */ +#define WF_PLE_TOP_AMSDU_PEEK_CR_00_AMSDU_CS_SHFT 8 +#define WF_PLE_TOP_AMSDU_PEEK_CR_00_AMSDU_DOP_CS_ADDR \ +WF_PLE_TOP_AMSDU_PEEK_CR_00_ADDR +#define WF_PLE_TOP_AMSDU_PEEK_CR_00_AMSDU_DOP_CS_MASK \ +0x0000000F /* AMSDU_DOP_CS[3..0] */ +#define WF_PLE_TOP_AMSDU_PEEK_CR_00_AMSDU_DOP_CS_SHFT 0 + +/* +* ---AMSDU_PEEK_CR_01 (0x820C0000 + 0x10d4)--- +* AMSDU_DOP_PBUF_CS[2..0] - (RO) PLE AMSDU port - Data operation PBUF +* current state. +* RESERVED3[3] - (RO) Reserved bits +* AMSDU_DOP_CACHE_CS[5..4] - (RO) PLE AMSDU port - Data operation CACHE +* current state. +* RESERVED6[7..6] - (RO) Reserved bits +* AMSDU_QOP_Q_OPER_CS[11..8] - (RO) PLE AMSDU port - Queue operation current +state. +* AMSDU_QOP_RL_OCP_CS[13..12] - (RO) PLE AMSDU port - Queue operation RL +* current state. +* RESERVED14[15..14] - (RO) Reserved bits +* AMSDU_QOP_PL_OCP_CS[17..16] - (RO) PLE AMSDU port - Queue operation PL +* current state. +* RESERVED18[19..18] - (RO) Reserved bits +* AMSDU_QOP_ALLOCATE_CS[22..20] - (RO) PLE AMSDU port - Queue operation +* allocate current state. +* RESERVED23[31..23] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_QOP_ALLOCATE_CS_ADDR \ +WF_PLE_TOP_AMSDU_PEEK_CR_01_ADDR +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_QOP_ALLOCATE_CS_MASK \ +0x00700000 /* AMSDU_QOP_ALLOCATE_CS[22..20] */ +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_QOP_ALLOCATE_CS_SHFT 20 +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_QOP_PL_OCP_CS_ADDR \ +WF_PLE_TOP_AMSDU_PEEK_CR_01_ADDR +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_QOP_PL_OCP_CS_MASK \ +0x00030000 /* AMSDU_QOP_PL_OCP_CS[17..16] */ +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_QOP_PL_OCP_CS_SHFT 16 +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_QOP_RL_OCP_CS_ADDR \ +WF_PLE_TOP_AMSDU_PEEK_CR_01_ADDR +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_QOP_RL_OCP_CS_MASK \ +0x00003000 /* AMSDU_QOP_RL_OCP_CS[13..12] */ +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_QOP_RL_OCP_CS_SHFT 12 +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_QOP_Q_OPER_CS_ADDR \ +WF_PLE_TOP_AMSDU_PEEK_CR_01_ADDR +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_QOP_Q_OPER_CS_MASK \ +0x00000F00 /* AMSDU_QOP_Q_OPER_CS[11..8] */ +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_QOP_Q_OPER_CS_SHFT 8 +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_DOP_CACHE_CS_ADDR \ +WF_PLE_TOP_AMSDU_PEEK_CR_01_ADDR +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_DOP_CACHE_CS_MASK \ +0x00000030 /* AMSDU_DOP_CACHE_CS[5..4] */ +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_DOP_CACHE_CS_SHFT 4 +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_DOP_PBUF_CS_ADDR \ +WF_PLE_TOP_AMSDU_PEEK_CR_01_ADDR +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_DOP_PBUF_CS_MASK \ +0x00000007 /* AMSDU_DOP_PBUF_CS[2..0] */ +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_DOP_PBUF_CS_SHFT 0 + +/* +* ---AMSDU_PACK_1_MSDU_CNT (0x820C0000 + 0x10e0)--- +* pack_1_msdu_cnt[15..0] - (RC) AMSDU pack count of 1 MSDU in TXD. +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_AMSDU_PACK_1_MSDU_CNT_pack_1_msdu_cnt_ADDR \ +WF_PLE_TOP_AMSDU_PACK_1_MSDU_CNT_ADDR +#define WF_PLE_TOP_AMSDU_PACK_1_MSDU_CNT_pack_1_msdu_cnt_MASK \ +0x0000FFFF /* pack_1_msdu_cnt[15..0] */ +#define WF_PLE_TOP_AMSDU_PACK_1_MSDU_CNT_pack_1_msdu_cnt_SHFT 0 + +/* +* ---AMSDU_PACK_2_MSDU_CNT (0x820C0000 + 0x10e4)--- +* pack_2_msdu_cnt[15..0] - (RC) AMSDU pack count of 2 MSDU in TXD. +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_AMSDU_PACK_2_MSDU_CNT_pack_2_msdu_cnt_ADDR \ +WF_PLE_TOP_AMSDU_PACK_2_MSDU_CNT_ADDR +#define WF_PLE_TOP_AMSDU_PACK_2_MSDU_CNT_pack_2_msdu_cnt_MASK \ +0x0000FFFF /* pack_2_msdu_cnt[15..0] */ +#define WF_PLE_TOP_AMSDU_PACK_2_MSDU_CNT_pack_2_msdu_cnt_SHFT 0 + +/* +* ---AMSDU_PACK_3_MSDU_CNT (0x820C0000 + 0x10e8)--- +* pack_3_msdu_cnt[15..0] - (RC) AMSDU pack count of 3 MSDU in TXD. +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_AMSDU_PACK_3_MSDU_CNT_pack_3_msdu_cnt_ADDR \ +WF_PLE_TOP_AMSDU_PACK_3_MSDU_CNT_ADDR +#define WF_PLE_TOP_AMSDU_PACK_3_MSDU_CNT_pack_3_msdu_cnt_MASK \ +0x0000FFFF /* pack_3_msdu_cnt[15..0] */ +#define WF_PLE_TOP_AMSDU_PACK_3_MSDU_CNT_pack_3_msdu_cnt_SHFT 0 + +/* +* ---AMSDU_PACK_4_MSDU_CNT (0x820C0000 + 0x10ec)--- +* pack_4_msdu_cnt[15..0] - (RC) AMSDU pack count of 4 MSDU in TXD. +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_AMSDU_PACK_4_MSDU_CNT_pack_4_msdu_cnt_ADDR \ +WF_PLE_TOP_AMSDU_PACK_4_MSDU_CNT_ADDR +#define WF_PLE_TOP_AMSDU_PACK_4_MSDU_CNT_pack_4_msdu_cnt_MASK \ +0x0000FFFF /* pack_4_msdu_cnt[15..0] */ +#define WF_PLE_TOP_AMSDU_PACK_4_MSDU_CNT_pack_4_msdu_cnt_SHFT 0 + +/* +* ---AMSDU_PACK_5_MSDU_CNT (0x820C0000 + 0x10f0)--- +* pack_5_msdu_cnt[15..0] - (RC) AMSDU pack count of 5 MSDU in TXD. +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_AMSDU_PACK_5_MSDU_CNT_pack_5_msdu_cnt_ADDR \ +WF_PLE_TOP_AMSDU_PACK_5_MSDU_CNT_ADDR +#define WF_PLE_TOP_AMSDU_PACK_5_MSDU_CNT_pack_5_msdu_cnt_MASK \ +0x0000FFFF /* pack_5_msdu_cnt[15..0] */ +#define WF_PLE_TOP_AMSDU_PACK_5_MSDU_CNT_pack_5_msdu_cnt_SHFT 0 + +/* +* ---AMSDU_PACK_6_MSDU_CNT (0x820C0000 + 0x10f4)--- +* pack_6_msdu_cnt[15..0] - (RC) AMSDU pack count of 4 MSDU in TXD. +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_AMSDU_PACK_6_MSDU_CNT_pack_6_msdu_cnt_ADDR \ +WF_PLE_TOP_AMSDU_PACK_6_MSDU_CNT_ADDR +#define WF_PLE_TOP_AMSDU_PACK_6_MSDU_CNT_pack_6_msdu_cnt_MASK \ +0x0000FFFF /* pack_6_msdu_cnt[15..0] */ +#define WF_PLE_TOP_AMSDU_PACK_6_MSDU_CNT_pack_6_msdu_cnt_SHFT 0 + +/* +* ---AMSDU_PACK_7_MSDU_CNT (0x820C0000 + 0x10f8)--- +* pack_7_msdu_cnt[15..0] - (RC) AMSDU pack count of 7 MSDU in TXD. +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_AMSDU_PACK_7_MSDU_CNT_pack_7_msdu_cnt_ADDR \ +WF_PLE_TOP_AMSDU_PACK_7_MSDU_CNT_ADDR +#define WF_PLE_TOP_AMSDU_PACK_7_MSDU_CNT_pack_7_msdu_cnt_MASK \ +0x0000FFFF /* pack_7_msdu_cnt[15..0] */ +#define WF_PLE_TOP_AMSDU_PACK_7_MSDU_CNT_pack_7_msdu_cnt_SHFT 0 + +/* +* ---AMSDU_PACK_8_MSDU_CNT (0x820C0000 + 0x10fc)--- +* pack_8_msdu_cnt[15..0] - (RC) AMSDU pack count of 8 MSDU in TXD. +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_AMSDU_PACK_8_MSDU_CNT_pack_8_msdu_cnt_ADDR \ +WF_PLE_TOP_AMSDU_PACK_8_MSDU_CNT_ADDR +#define WF_PLE_TOP_AMSDU_PACK_8_MSDU_CNT_pack_8_msdu_cnt_MASK \ +0x0000FFFF /* pack_8_msdu_cnt[15..0] */ +#define WF_PLE_TOP_AMSDU_PACK_8_MSDU_CNT_pack_8_msdu_cnt_SHFT 0 + +/* +* ---AMSDU_AC0_QUEUE_EMPTY0 (0x820C0000 + 0x1100)--- +* AMSDU_QUEUE_EMPTY_FLAG_31_0[31..0] - (RO) AC0 queue empty flag for +* station31~station0 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY0_AMSDU_QUEUE_EMPTY_FLAG_31_0_ADDR \ +WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY0_ADDR +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY0_AMSDU_QUEUE_EMPTY_FLAG_31_0_MASK \ +0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_31_0[31..0] */ +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY0_AMSDU_QUEUE_EMPTY_FLAG_31_0_SHFT 0 + +/* +* ---AMSDU_AC0_QUEUE_EMPTY1 (0x820C0000 + 0x1104)--- +* AMSDU_QUEUE_EMPTY_FLAG_63_32[31..0] - (RO) AC0 queue empty flag for +* station63~station32 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY1_AMSDU_QUEUE_EMPTY_FLAG_63_32_ADDR \ +WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY1_ADDR +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY1_AMSDU_QUEUE_EMPTY_FLAG_63_32_MASK \ +0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_63_32[31..0] */ +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY1_AMSDU_QUEUE_EMPTY_FLAG_63_32_SHFT 0 + +/* +* ---AMSDU_AC0_QUEUE_EMPTY2 (0x820C0000 + 0x1108)--- +* AMSDU_QUEUE_EMPTY_FLAG_95_64[31..0] - (RO) AC0 queue empty flag for +* station95~station64 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY2_AMSDU_QUEUE_EMPTY_FLAG_95_64_ADDR \ +WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY2_ADDR +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY2_AMSDU_QUEUE_EMPTY_FLAG_95_64_MASK \ +0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_95_64[31..0] */ +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY2_AMSDU_QUEUE_EMPTY_FLAG_95_64_SHFT 0 + +/* +* ---AMSDU_AC0_QUEUE_EMPTY3 (0x820C0000 + 0x110C)--- +* AMSDU_QUEUE_EMPTY_FLAG_127_96[31..0] - (RO) AC0 queue empty flag for +* station127~station96 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY3_AMSDU_QUEUE_EMPTY_FLAG_127_96_ADDR \ +WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY3_ADDR +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY3_AMSDU_QUEUE_EMPTY_FLAG_127_96_MASK \ +0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_127_96[31..0] */ +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY3_AMSDU_QUEUE_EMPTY_FLAG_127_96_SHFT 0 + +/* +* ---AMSDU_AC0_QUEUE_EMPTY4 (0x820C0000 + 0x1110)--- +* AMSDU_QUEUE_EMPTY_FLAG_135_128[7..0] - (RO) AC0 queue empty flag for +* station135~station128 in HW AMSDU engine. +* AMSDU_QUEUE_EMPTY_FLAG_143_136[15..8] - (RO) AC0 queue empty flag for +* station143~station136 in HW AMSDU engine. +* AMSDU_QUEUE_EMPTY_FLAG_159_144[31..16] - (RO) AC0 queue empty flag for +* station159~station144 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY4_AMSDU_QUEUE_EMPTY_FLAG_159_144_ADDR\ +WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY4_ADDR +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY4_AMSDU_QUEUE_EMPTY_FLAG_159_144_MASK\ +0xFFFF0000 /* AMSDU_QUEUE_EMPTY_FLAG_159_144[31..16] */ +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY4_AMSDU_QUEUE_EMPTY_FLAG_159_144_SHFT 16 +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY4_AMSDU_QUEUE_EMPTY_FLAG_143_136_ADDR\ +WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY4_ADDR +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY4_AMSDU_QUEUE_EMPTY_FLAG_143_136_MASK\ +0x0000FF00 /* AMSDU_QUEUE_EMPTY_FLAG_143_136[15..8] */ +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY4_AMSDU_QUEUE_EMPTY_FLAG_143_136_SHFT 8 +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY4_AMSDU_QUEUE_EMPTY_FLAG_135_128_ADDR\ +WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY4_ADDR +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY4_AMSDU_QUEUE_EMPTY_FLAG_135_128_MASK\ +0x000000FF /* AMSDU_QUEUE_EMPTY_FLAG_135_128[7..0] */ +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY4_AMSDU_QUEUE_EMPTY_FLAG_135_128_SHFT 0 + +/* +* ---AMSDU_AC0_QUEUE_EMPTY5 (0x820C0000 + 0x1114)--- +* AMSDU_QUEUE_EMPTY_FLAG_191_160[31..0] - (RO) AC0 queue empty flag for +* station191~station160 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY5_AMSDU_QUEUE_EMPTY_FLAG_191_160_ADDR\ +WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY5_ADDR +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY5_AMSDU_QUEUE_EMPTY_FLAG_191_160_MASK\ +0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_191_160[31..0] */ +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY5_AMSDU_QUEUE_EMPTY_FLAG_191_160_SHFT 0 + +/* +* ---AMSDU_AC0_QUEUE_EMPTY6 (0x820C0000 + 0x1118)--- +* AMSDU_QUEUE_EMPTY_FLAG_223_192[31..0] - (RO) AC0 queue empty flag for +* station223~station192 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY6_AMSDU_QUEUE_EMPTY_FLAG_223_192_ADDR\ +WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY6_ADDR +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY6_AMSDU_QUEUE_EMPTY_FLAG_223_192_MASK\ +0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_223_192[31..0] */ +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY6_AMSDU_QUEUE_EMPTY_FLAG_223_192_SHFT 0 + +/* +* ---AMSDU_AC0_QUEUE_EMPTY7 (0x820C0000 + 0x111c)--- +* AMSDU_QUEUE_EMPTY_FLAG_255_224[31..0] - (RO) AC0 queue empty flag for +* station255~station224 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY7_AMSDU_QUEUE_EMPTY_FLAG_255_224_ADDR\ +WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY7_ADDR +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY7_AMSDU_QUEUE_EMPTY_FLAG_255_224_MASK\ +0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_255_224[31..0] */ +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY7_AMSDU_QUEUE_EMPTY_FLAG_255_224_SHFT 0 + +/* +* ---AMSDU_AC0_QUEUE_EMPTY8 (0x820C0000 + 0x1120)--- +* AMSDU_QUEUE_EMPTY_FLAG_287_256[31..0] - (RO) AC0 queue empty flag for +* station287~station256 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY8_AMSDU_QUEUE_EMPTY_FLAG_287_256_ADDR\ +WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY8_ADDR +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY8_AMSDU_QUEUE_EMPTY_FLAG_287_256_MASK\ +0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_287_256[31..0] */ +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY8_AMSDU_QUEUE_EMPTY_FLAG_287_256_SHFT 0 + +/* +* ---AMSDU_AC1_QUEUE_EMPTY0 (0x820C0000 + 0x1140)--- +* AMSDU_QUEUE_EMPTY_FLAG_31_0[31..0] - (RO) AC1 queue empty flag for +* station31~station0 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY0_AMSDU_QUEUE_EMPTY_FLAG_31_0_ADDR \ +WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY0_ADDR +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY0_AMSDU_QUEUE_EMPTY_FLAG_31_0_MASK \ +0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_31_0[31..0] */ +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY0_AMSDU_QUEUE_EMPTY_FLAG_31_0_SHFT 0 + +/* +* ---AMSDU_AC1_QUEUE_EMPTY1 (0x820C0000 + 0x1144)--- +* AMSDU_QUEUE_EMPTY_FLAG_63_32[31..0] - (RO) AC1 queue empty flag for +* station63~station32 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY1_AMSDU_QUEUE_EMPTY_FLAG_63_32_ADDR \ +WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY1_ADDR +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY1_AMSDU_QUEUE_EMPTY_FLAG_63_32_MASK \ +0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_63_32[31..0] */ +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY1_AMSDU_QUEUE_EMPTY_FLAG_63_32_SHFT 0 + +/* +* ---AMSDU_AC1_QUEUE_EMPTY2 (0x820C0000 + 0x1148)--- +* AMSDU_QUEUE_EMPTY_FLAG_95_64[31..0] - (RO) AC1 queue empty flag for +* station95~station64 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY2_AMSDU_QUEUE_EMPTY_FLAG_95_64_ADDR \ +WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY2_ADDR +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY2_AMSDU_QUEUE_EMPTY_FLAG_95_64_MASK \ +0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_95_64[31..0] */ +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY2_AMSDU_QUEUE_EMPTY_FLAG_95_64_SHFT 0 + +/* +* ---AMSDU_AC1_QUEUE_EMPTY3 (0x820C0000 + 0x114C)--- +* AMSDU_QUEUE_EMPTY_FLAG_127_96[31..0] - (RO) AC1 queue empty flag for +* station127~station96 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY3_AMSDU_QUEUE_EMPTY_FLAG_127_96_ADDR \ +WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY3_ADDR +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY3_AMSDU_QUEUE_EMPTY_FLAG_127_96_MASK \ +0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_127_96[31..0] */ +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY3_AMSDU_QUEUE_EMPTY_FLAG_127_96_SHFT 0 + +/* +* ---AMSDU_AC1_QUEUE_EMPTY4 (0x820C0000 + 0x1150)--- +* AMSDU_QUEUE_EMPTY_FLAG_135_128[7..0] - (RO) AC1 queue empty flag for +* station135~station128 in HW AMSDU engine. +* AMSDU_QUEUE_EMPTY_FLAG_143_136[15..8] - (RO) AC1 queue empty flag for +* station143~station136 in HW AMSDU engine. +* AMSDU_QUEUE_EMPTY_FLAG_159_144[31..16] - (RO) AC1 queue empty flag for +* station159~station144 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY4_AMSDU_QUEUE_EMPTY_FLAG_159_144_ADDR\ +WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY4_ADDR +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY4_AMSDU_QUEUE_EMPTY_FLAG_159_144_MASK\ +0xFFFF0000 /* AMSDU_QUEUE_EMPTY_FLAG_159_144[31..16] */ +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY4_AMSDU_QUEUE_EMPTY_FLAG_159_144_SHFT 16 +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY4_AMSDU_QUEUE_EMPTY_FLAG_143_136_ADDR\ +WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY4_ADDR +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY4_AMSDU_QUEUE_EMPTY_FLAG_143_136_MASK\ +0x0000FF00 /* AMSDU_QUEUE_EMPTY_FLAG_143_136[15..8] */ +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY4_AMSDU_QUEUE_EMPTY_FLAG_143_136_SHFT 8 +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY4_AMSDU_QUEUE_EMPTY_FLAG_135_128_ADDR\ +WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY4_ADDR +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY4_AMSDU_QUEUE_EMPTY_FLAG_135_128_MASK\ +0x000000FF /* AMSDU_QUEUE_EMPTY_FLAG_135_128[7..0] */ +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY4_AMSDU_QUEUE_EMPTY_FLAG_135_128_SHFT 0 + +/* +* ---AMSDU_AC1_QUEUE_EMPTY5 (0x820C0000 + 0x1154)--- +* AMSDU_QUEUE_EMPTY_FLAG_191_160[31..0] - (RO) AC1 queue empty flag for +* station191~station160 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY5_AMSDU_QUEUE_EMPTY_FLAG_191_160_ADDR\ +WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY5_ADDR +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY5_AMSDU_QUEUE_EMPTY_FLAG_191_160_MASK\ +0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_191_160[31..0] */ +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY5_AMSDU_QUEUE_EMPTY_FLAG_191_160_SHFT 0 + +/* +* ---AMSDU_AC1_QUEUE_EMPTY6 (0x820C0000 + 0x1158)--- +* AMSDU_QUEUE_EMPTY_FLAG_223_192[31..0] - (RO) AC1 queue empty flag for +* station223~station192 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY6_AMSDU_QUEUE_EMPTY_FLAG_223_192_ADDR\ +WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY6_ADDR +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY6_AMSDU_QUEUE_EMPTY_FLAG_223_192_MASK\ +0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_223_192[31..0] */ +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY6_AMSDU_QUEUE_EMPTY_FLAG_223_192_SHFT 0 + +/* +* ---AMSDU_AC1_QUEUE_EMPTY7 (0x820C0000 + 0x115c)--- +* AMSDU_QUEUE_EMPTY_FLAG_255_224[31..0] - (RO) AC1 queue empty flag for +* station255~station224 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY7_AMSDU_QUEUE_EMPTY_FLAG_255_224_ADDR\ +WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY7_ADDR +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY7_AMSDU_QUEUE_EMPTY_FLAG_255_224_MASK\ +0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_255_224[31..0] */ +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY7_AMSDU_QUEUE_EMPTY_FLAG_255_224_SHFT 0 + +/* +* ---AMSDU_AC1_QUEUE_EMPTY8 (0x820C0000 + 0x1160)--- +* AMSDU_QUEUE_EMPTY_FLAG_287_256[31..0] - (RO) AC1 queue empty flag for +* station287~station256 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY8_AMSDU_QUEUE_EMPTY_FLAG_287_256_ADDR\ +WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY8_ADDR +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY8_AMSDU_QUEUE_EMPTY_FLAG_287_256_MASK\ +0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_287_256[31..0] */ +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY8_AMSDU_QUEUE_EMPTY_FLAG_287_256_SHFT 0 + +/* +* ---AMSDU_AC2_QUEUE_EMPTY0 (0x820C0000 + 0x1180)--- +* AMSDU_QUEUE_EMPTY_FLAG_31_0[31..0] - (RO) AC2 queue empty flag for +* station31~station0 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY0_AMSDU_QUEUE_EMPTY_FLAG_31_0_ADDR \ +WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY0_ADDR +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY0_AMSDU_QUEUE_EMPTY_FLAG_31_0_MASK \ +0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_31_0[31..0] */ +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY0_AMSDU_QUEUE_EMPTY_FLAG_31_0_SHFT 0 + +/* +* ---AMSDU_AC2_QUEUE_EMPTY1 (0x820C0000 + 0x1184)--- +* AMSDU_QUEUE_EMPTY_FLAG_63_32[31..0] - (RO) AC2 queue empty flag for +* station63~station32 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY1_AMSDU_QUEUE_EMPTY_FLAG_63_32_ADDR \ +WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY1_ADDR +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY1_AMSDU_QUEUE_EMPTY_FLAG_63_32_MASK \ +0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_63_32[31..0] */ +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY1_AMSDU_QUEUE_EMPTY_FLAG_63_32_SHFT 0 + +/* +* ---AMSDU_AC2_QUEUE_EMPTY2 (0x820C0000 + 0x1188)--- +* AMSDU_QUEUE_EMPTY_FLAG_95_64[31..0] - (RO) AC2 queue empty flag for +* station95~station64 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY2_AMSDU_QUEUE_EMPTY_FLAG_95_64_ADDR \ +WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY2_ADDR +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY2_AMSDU_QUEUE_EMPTY_FLAG_95_64_MASK \ +0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_95_64[31..0] */ +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY2_AMSDU_QUEUE_EMPTY_FLAG_95_64_SHFT 0 + +/* +* ---AMSDU_AC2_QUEUE_EMPTY3 (0x820C0000 + 0x118C)--- +* AMSDU_QUEUE_EMPTY_FLAG_127_96[31..0] - (RO) AC2 queue empty flag for +* station127~station96 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY3_AMSDU_QUEUE_EMPTY_FLAG_127_96_ADDR \ +WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY3_ADDR +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY3_AMSDU_QUEUE_EMPTY_FLAG_127_96_MASK \ +0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_127_96[31..0] */ +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY3_AMSDU_QUEUE_EMPTY_FLAG_127_96_SHFT 0 + +/* +* ---AMSDU_AC2_QUEUE_EMPTY4 (0x820C0000 + 0x1190)--- +* AMSDU_QUEUE_EMPTY_FLAG_135_128[7..0] - (RO) AC2 queue empty flag for +* station135~station128 in HW AMSDU engine. +* AMSDU_QUEUE_EMPTY_FLAG_143_136[15..8] - (RO) AC2 queue empty flag for +* station143~station136 in HW AMSDU engine. +* AMSDU_QUEUE_EMPTY_FLAG_159_144[31..16] - (RO) AC2 queue empty flag for +* station159~station144 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY4_AMSDU_QUEUE_EMPTY_FLAG_159_144_ADDR\ +WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY4_ADDR +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY4_AMSDU_QUEUE_EMPTY_FLAG_159_144_MASK\ +0xFFFF0000 /* AMSDU_QUEUE_EMPTY_FLAG_159_144[31..16] */ +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY4_AMSDU_QUEUE_EMPTY_FLAG_159_144_SHFT 16 +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY4_AMSDU_QUEUE_EMPTY_FLAG_143_136_ADDR\ +WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY4_ADDR +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY4_AMSDU_QUEUE_EMPTY_FLAG_143_136_MASK\ +0x0000FF00 /* AMSDU_QUEUE_EMPTY_FLAG_143_136[15..8] */ +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY4_AMSDU_QUEUE_EMPTY_FLAG_143_136_SHFT 8 +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY4_AMSDU_QUEUE_EMPTY_FLAG_135_128_ADDR\ +WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY4_ADDR +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY4_AMSDU_QUEUE_EMPTY_FLAG_135_128_MASK\ +0x000000FF /* AMSDU_QUEUE_EMPTY_FLAG_135_128[7..0] */ +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY4_AMSDU_QUEUE_EMPTY_FLAG_135_128_SHFT 0 + +/* +* ---AMSDU_AC2_QUEUE_EMPTY5 (0x820C0000 + 0x1194)--- +* AMSDU_QUEUE_EMPTY_FLAG_191_160[31..0] - (RO) AC2 queue empty flag for +* station191~station160 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY5_AMSDU_QUEUE_EMPTY_FLAG_191_160_ADDR\ +WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY5_ADDR +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY5_AMSDU_QUEUE_EMPTY_FLAG_191_160_MASK\ +0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_191_160[31..0] */ +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY5_AMSDU_QUEUE_EMPTY_FLAG_191_160_SHFT 0 + +/* +* ---AMSDU_AC2_QUEUE_EMPTY6 (0x820C0000 + 0x1198)--- +* AMSDU_QUEUE_EMPTY_FLAG_223_192[31..0] - (RO) AC2 queue empty flag for +* station223~station192 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY6_AMSDU_QUEUE_EMPTY_FLAG_223_192_ADDR\ +WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY6_ADDR +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY6_AMSDU_QUEUE_EMPTY_FLAG_223_192_MASK\ +0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_223_192[31..0] */ +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY6_AMSDU_QUEUE_EMPTY_FLAG_223_192_SHFT 0 + +/* +* ---AMSDU_AC2_QUEUE_EMPTY7 (0x820C0000 + 0x119c)--- +* AMSDU_QUEUE_EMPTY_FLAG_255_224[31..0] - (RO) AC2 queue empty flag for +* station255~station224 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY7_AMSDU_QUEUE_EMPTY_FLAG_255_224_ADDR\ +WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY7_ADDR +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY7_AMSDU_QUEUE_EMPTY_FLAG_255_224_MASK\ +0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_255_224[31..0] */ +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY7_AMSDU_QUEUE_EMPTY_FLAG_255_224_SHFT 0 + +/* +* ---AMSDU_AC2_QUEUE_EMPTY8 (0x820C0000 + 0x11a0)--- +* AMSDU_QUEUE_EMPTY_FLAG_287_256[31..0] - (RO) AC2 queue empty flag for +* station287~station256 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY8_AMSDU_QUEUE_EMPTY_FLAG_287_256_ADDR\ +WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY8_ADDR +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY8_AMSDU_QUEUE_EMPTY_FLAG_287_256_MASK\ +0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_287_256[31..0] */ +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY8_AMSDU_QUEUE_EMPTY_FLAG_287_256_SHFT 0 + +/* +* ---AMSDU_AC3_QUEUE_EMPTY0 (0x820C0000 + 0x11C0)--- +* AMSDU_QUEUE_EMPTY_FLAG_31_0[31..0] - (RO) AC3 queue empty flag for +* station31~station0 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY0_AMSDU_QUEUE_EMPTY_FLAG_31_0_ADDR \ +WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY0_ADDR +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY0_AMSDU_QUEUE_EMPTY_FLAG_31_0_MASK \ +0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_31_0[31..0] */ +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY0_AMSDU_QUEUE_EMPTY_FLAG_31_0_SHFT 0 + +/* +* ---AMSDU_AC3_QUEUE_EMPTY1 (0x820C0000 + 0x11C4)--- +* AMSDU_QUEUE_EMPTY_FLAG_63_32[31..0] - (RO) AC3 queue empty flag for +* station63~station32 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY1_AMSDU_QUEUE_EMPTY_FLAG_63_32_ADDR \ +WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY1_ADDR +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY1_AMSDU_QUEUE_EMPTY_FLAG_63_32_MASK \ +0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_63_32[31..0] */ +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY1_AMSDU_QUEUE_EMPTY_FLAG_63_32_SHFT 0 + +/* +* ---AMSDU_AC3_QUEUE_EMPTY2 (0x820C0000 + 0x11C8)--- +* AMSDU_QUEUE_EMPTY_FLAG_95_64[31..0] - (RO) AC3 queue empty flag for +* station95~station64 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY2_AMSDU_QUEUE_EMPTY_FLAG_95_64_ADDR \ +WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY2_ADDR +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY2_AMSDU_QUEUE_EMPTY_FLAG_95_64_MASK \ +0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_95_64[31..0] */ +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY2_AMSDU_QUEUE_EMPTY_FLAG_95_64_SHFT 0 + +/* +* ---AMSDU_AC3_QUEUE_EMPTY3 (0x820C0000 + 0x11CC)--- +* AMSDU_QUEUE_EMPTY_FLAG_127_96[31..0] - (RO) AC3 queue empty flag for +* station127~station96 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY3_AMSDU_QUEUE_EMPTY_FLAG_127_96_ADDR \ +WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY3_ADDR +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY3_AMSDU_QUEUE_EMPTY_FLAG_127_96_MASK \ +0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_127_96[31..0] */ +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY3_AMSDU_QUEUE_EMPTY_FLAG_127_96_SHFT 0 + +/* +* ---AMSDU_AC3_QUEUE_EMPTY4 (0x820C0000 + 0x11D0)--- +* AMSDU_QUEUE_EMPTY_FLAG_135_128[7..0] - (RO) AC3 queue empty flag for +* station135~station128 in HW AMSDU engine. +* AMSDU_QUEUE_EMPTY_FLAG_143_136[15..8] - (RO) AC3 queue empty flag for +* station143~station136 in HW AMSDU engine. +* AMSDU_QUEUE_EMPTY_FLAG_159_144[31..16] - (RO) AC3 queue empty flag for +* station159~station144 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY4_AMSDU_QUEUE_EMPTY_FLAG_159_144_ADDR\ +WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY4_ADDR +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY4_AMSDU_QUEUE_EMPTY_FLAG_159_144_MASK\ +0xFFFF0000 /* AMSDU_QUEUE_EMPTY_FLAG_159_144[31..16] */ +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY4_AMSDU_QUEUE_EMPTY_FLAG_159_144_SHFT 16 +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY4_AMSDU_QUEUE_EMPTY_FLAG_143_136_ADDR\ +WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY4_ADDR +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY4_AMSDU_QUEUE_EMPTY_FLAG_143_136_MASK\ +0x0000FF00 /* AMSDU_QUEUE_EMPTY_FLAG_143_136[15..8] */ +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY4_AMSDU_QUEUE_EMPTY_FLAG_143_136_SHFT 8 +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY4_AMSDU_QUEUE_EMPTY_FLAG_135_128_ADDR\ +WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY4_ADDR +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY4_AMSDU_QUEUE_EMPTY_FLAG_135_128_MASK\ +0x000000FF /* AMSDU_QUEUE_EMPTY_FLAG_135_128[7..0] */ +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY4_AMSDU_QUEUE_EMPTY_FLAG_135_128_SHFT 0 + +/* +* ---AMSDU_AC3_QUEUE_EMPTY5 (0x820C0000 + 0x11D4)--- +* AMSDU_QUEUE_EMPTY_FLAG_191_160[31..0] - (RO) AC3 queue empty flag for +* station191~station160 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY5_AMSDU_QUEUE_EMPTY_FLAG_191_160_ADDR\ +WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY5_ADDR +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY5_AMSDU_QUEUE_EMPTY_FLAG_191_160_MASK\ +0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_191_160[31..0] */ +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY5_AMSDU_QUEUE_EMPTY_FLAG_191_160_SHFT 0 + +/* +* ---AMSDU_AC3_QUEUE_EMPTY6 (0x820C0000 + 0x11d8)--- +* AMSDU_QUEUE_EMPTY_FLAG_223_192[31..0] - (RO) AC3 queue empty flag for +* station223~station192 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY6_AMSDU_QUEUE_EMPTY_FLAG_223_192_ADDR\ +WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY6_ADDR +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY6_AMSDU_QUEUE_EMPTY_FLAG_223_192_MASK\ +0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_223_192[31..0] */ +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY6_AMSDU_QUEUE_EMPTY_FLAG_223_192_SHFT 0 + +/* +* ---AMSDU_AC3_QUEUE_EMPTY7 (0x820C0000 + 0x11dc)--- +* AMSDU_QUEUE_EMPTY_FLAG_255_224[31..0] - (RO) AC3 queue empty flag for +* station255~station224 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY7_AMSDU_QUEUE_EMPTY_FLAG_255_224_ADDR\ +WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY7_ADDR +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY7_AMSDU_QUEUE_EMPTY_FLAG_255_224_MASK\ +0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_255_224[31..0] */ +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY7_AMSDU_QUEUE_EMPTY_FLAG_255_224_SHFT 0 + +/* +* ---AMSDU_AC3_QUEUE_EMPTY8 (0x820C0000 + 0x11e0)--- +* AMSDU_QUEUE_EMPTY_FLAG_287_256[31..0] - (RO) AC3 queue empty flag for +* station287~station256 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY8_AMSDU_QUEUE_EMPTY_FLAG_287_256_ADDR\ +WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY8_ADDR +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY8_AMSDU_QUEUE_EMPTY_FLAG_287_256_MASK\ +0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_287_256[31..0] */ +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY8_AMSDU_QUEUE_EMPTY_FLAG_287_256_SHFT 0 + +/* +* ---CFG_DBDC_CTRL0 (0x820C0000 + 0x2008)--- +* RESERVED0[7..0] - (RO) Reserved bits +* WMM_0TO3_BAND_SEL[11..8] - (RW) Selects WMM0~WMM3 band +* RESERVED12[15..12] - (RO) Reserved bits +* NAN_BAND_SEL[16] - (RW) Selects NAN band +* FUNCQ_BAND_SEL[17] - (RW) Selects Functional Queue band +* TGID 0 & TGID1 always selec to different +band +* RESERVED18[30..18] - (RO) Reserved bits +* DBDC_EN[31] - (RW) Enables DBDC +*/ +#define WF_PLE_TOP_CFG_DBDC_CTRL0_DBDC_EN_ADDR WF_PLE_TOP_CFG_DBDC_CTRL0_ADDR +#define WF_PLE_TOP_CFG_DBDC_CTRL0_DBDC_EN_MASK 0x80000000 /* DBDC_EN[31] */ +#define WF_PLE_TOP_CFG_DBDC_CTRL0_DBDC_EN_SHFT 31 +#define WF_PLE_TOP_CFG_DBDC_CTRL0_FUNCQ_BAND_SEL_ADDR \ +WF_PLE_TOP_CFG_DBDC_CTRL0_ADDR +#define WF_PLE_TOP_CFG_DBDC_CTRL0_FUNCQ_BAND_SEL_MASK \ +0x00020000 /* FUNCQ_BAND_SEL[17] */ +#define WF_PLE_TOP_CFG_DBDC_CTRL0_FUNCQ_BAND_SEL_SHFT 17 +#define WF_PLE_TOP_CFG_DBDC_CTRL0_NAN_BAND_SEL_ADDR \ +WF_PLE_TOP_CFG_DBDC_CTRL0_ADDR +#define WF_PLE_TOP_CFG_DBDC_CTRL0_NAN_BAND_SEL_MASK \ +0x00010000 /* NAN_BAND_SEL[16] */ +#define WF_PLE_TOP_CFG_DBDC_CTRL0_NAN_BAND_SEL_SHFT 16 +#define WF_PLE_TOP_CFG_DBDC_CTRL0_WMM_0TO3_BAND_SEL_ADDR \ +WF_PLE_TOP_CFG_DBDC_CTRL0_ADDR +#define WF_PLE_TOP_CFG_DBDC_CTRL0_WMM_0TO3_BAND_SEL_MASK \ +0x00000F00 /* WMM_0TO3_BAND_SEL[11..8] */ +#define WF_PLE_TOP_CFG_DBDC_CTRL0_WMM_0TO3_BAND_SEL_SHFT 8 + +/* +* ---CFG_UWTBL_MBIST_CTRL_0 (0x820C0000 + 0x2480)--- +* UWTBL_MBIST_MODE[0] - (RW) Control register for mbist_mode of UWTBL +MBIST +* UWTBL_MBIST_HOLDB[1] - (RW) Control register for mbist_holdb of +* UWTBL MBIST +* UWTBL_MBIST_DEBUG[2] - (RW) Control register for mbist_debug of +* UWTBL MBIST +* UWTBL_MBIST_USE_DEFAULT_DELSEL[3] - (RW) Control register for default DELSEL +* value of UWTBL memory +* UWTBL_MBIST_SLEEP_TEST[4] - (RW) Control register for sleep_test of UWTBL +MBIST +* UWTBL_MBIST_SLEEP_INV[5] - (RW) Control register for sleep_inv of UWTBL +MBIST +* UWTBL_MBIST_SLEEP_W[6] - (RW) Control register for sleep_w of UWTBL +MBIST +* UWTBL_MBIST_SLEEP_R[7] - (RW) Control register for sleep_r of UWTBL +MBIST +* UWTBL_MBIST_DONE[8] - (RO) Working status of UWTBL SRAM MBIST +circuit +* RESERVED9[15..9] - (RO) Reserved bits +* UWTBL_MBIST_FAIL[21..16] - (RO) MBIST check result of UWTBL SRAM +* RESERVED22[31..22] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_FAIL_ADDR \ +WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_FAIL_MASK \ +0x003F0000 /* UWTBL_MBIST_FAIL[21..16] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_FAIL_SHFT 16 +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_DONE_ADDR \ +WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_DONE_MASK \ +0x00000100 /* UWTBL_MBIST_DONE[8] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_DONE_SHFT 8 +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_SLEEP_R_ADDR \ +WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_SLEEP_R_MASK \ +0x00000080 /* UWTBL_MBIST_SLEEP_R[7] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_SLEEP_R_SHFT 7 +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_SLEEP_W_ADDR \ +WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_SLEEP_W_MASK \ +0x00000040 /* UWTBL_MBIST_SLEEP_W[6] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_SLEEP_W_SHFT 6 +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_SLEEP_INV_ADDR \ +WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_SLEEP_INV_MASK \ +0x00000020 /* UWTBL_MBIST_SLEEP_INV[5] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_SLEEP_INV_SHFT 5 +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_SLEEP_TEST_ADDR \ +WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_SLEEP_TEST_MASK \ +0x00000010 /* UWTBL_MBIST_SLEEP_TEST[4] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_SLEEP_TEST_SHFT 4 +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_USE_DEFAULT_DELSEL_ADDR\ +WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_USE_DEFAULT_DELSEL_MASK\ +0x00000008 /* UWTBL_MBIST_USE_DEFAULT_DELSEL[3] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_USE_DEFAULT_DELSEL_SHFT 3 +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_DEBUG_ADDR \ +WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_DEBUG_MASK \ +0x00000004 /* UWTBL_MBIST_DEBUG[2] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_DEBUG_SHFT 2 +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_HOLDB_ADDR \ +WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_HOLDB_MASK \ +0x00000002 /* UWTBL_MBIST_HOLDB[1] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_HOLDB_SHFT 1 +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_MODE_ADDR \ +WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_MODE_MASK \ +0x00000001 /* UWTBL_MBIST_MODE[0] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_MODE_SHFT 0 + +/* +* ---CFG_UWTBL_MBIST_CTRL_1 (0x820C0000 + 0x2484)--- +* UWTBL_MBIST_HDEN[5..0] - (RW) Control register for mbist UWTBL HDEN +* RESERVED6[15..6] - (RO) Reserved bits +* UWTBL_MBIST_AWT[21..16] - (RW) Control register for mbist UWTBL AWT +* RESERVED22[31..22] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_1_UWTBL_MBIST_AWT_ADDR \ +WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_1_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_1_UWTBL_MBIST_AWT_MASK \ +0x003F0000 /* UWTBL_MBIST_AWT[21..16] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_1_UWTBL_MBIST_AWT_SHFT 16 +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_1_UWTBL_MBIST_HDEN_ADDR \ +WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_1_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_1_UWTBL_MBIST_HDEN_MASK \ +0x0000003F /* UWTBL_MBIST_HDEN[5..0] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_1_UWTBL_MBIST_HDEN_SHFT 0 + +/* +* ---CFG_UWTBL_MBIST_CTRL_2 (0x820C0000 + 0x2488)--- +* UWTBL_BACKGROUND[15..0] - (RW) The MBIST background control register +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_2_UWTBL_BACKGROUND_ADDR \ +WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_2_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_2_UWTBL_BACKGROUND_MASK \ +0x0000FFFF /* UWTBL_BACKGROUND[15..0] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_2_UWTBL_BACKGROUND_SHFT 0 + +/* +* ---CFG_UWTBL_MBIST_CTRL_3 (0x820C0000 + 0x248c)--- +* UWTBL_DELSEL_0[31..0] - (RW) UWTBL DELSEL 0 +*/ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_3_UWTBL_DELSEL_0_ADDR \ +WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_3_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_3_UWTBL_DELSEL_0_MASK \ +0xFFFFFFFF /* UWTBL_DELSEL_0[31..0] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_3_UWTBL_DELSEL_0_SHFT 0 + +/* +* ---CFG_UWTBL_MBIST_CTRL_4 (0x820C0000 + 0x2490)--- +* UWTBL_DELSEL_1[31..0] - (RW) UWTBL DELSEL 1 +*/ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_4_UWTBL_DELSEL_1_ADDR \ +WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_4_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_4_UWTBL_DELSEL_1_MASK \ +0xFFFFFFFF /* UWTBL_DELSEL_1[31..0] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_4_UWTBL_DELSEL_1_SHFT 0 + +/* +* ---CFG_UWTBL_MBIST_CTRL_5 (0x820C0000 + 0x2494)--- +* UWTBL_FUSE[6..0] - (RW) UWTBL FUSE +* RESERVED7[7] - (RO) Reserved bits +* UWTBL_PRE_FUSE[14..8] - (RO) UWTBL MBIST Pre Fuse +* RESERVED15[15] - (RO) Reserved bits +* UWTBL_MBIST_REPAIR_OK[21..16] - (RO) MBIST Repair OK +* RESERVED22[23..22] - (RO) Reserved bits +* UWTBL_MBIST_REPAIR_FAIL[29..24] - (RO) MBIST Repair Fail +* RESERVED30[31..30] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_UWTBL_MBIST_REPAIR_FAIL_ADDR \ +WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_UWTBL_MBIST_REPAIR_FAIL_MASK \ +0x3F000000 /* UWTBL_MBIST_REPAIR_FAIL[29..24] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_UWTBL_MBIST_REPAIR_FAIL_SHFT 24 +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_UWTBL_MBIST_REPAIR_OK_ADDR \ +WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_UWTBL_MBIST_REPAIR_OK_MASK \ +0x003F0000 /* UWTBL_MBIST_REPAIR_OK[21..16] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_UWTBL_MBIST_REPAIR_OK_SHFT 16 +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_UWTBL_PRE_FUSE_ADDR \ +WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_UWTBL_PRE_FUSE_MASK \ +0x00007F00 /* UWTBL_PRE_FUSE[14..8] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_UWTBL_PRE_FUSE_SHFT 8 +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_UWTBL_FUSE_ADDR \ +WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_UWTBL_FUSE_MASK \ +0x0000007F /* UWTBL_FUSE[6..0] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_UWTBL_FUSE_SHFT 0 + +/* +* ---CFG_UWTBL_MBIST_CTRL_6 (0x820C0000 + 0x2498)--- +* UWTBL_DELSEL_2[31..0] - (RW) UWTBL DELSEL 2 +*/ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_6_UWTBL_DELSEL_2_ADDR \ +WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_6_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_6_UWTBL_DELSEL_2_MASK \ +0xFFFFFFFF /* UWTBL_DELSEL_2[31..0] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_6_UWTBL_DELSEL_2_SHFT 0 + +/* +* ---CFG_SEC_MBIST_CTRL_0 (0x820C0000 + 0x25c0)--- +* SEC_MBIST_MODE[0] - (RW) Control register for mbist_mode of SEC +MBIST +* SEC_MBIST_HOLDB[1] - (RW) Control register for mbist_holdb of SEC +MBIST +* SEC_MBIST_DEBUG[2] - (RW) Control register for mbist_debug of SEC +MBIST +* SEC_MBIST_USE_DEFAULT_DELSEL[3] - (RW) Control register for default DELSEL +* value of SEC memory +* RESERVED4[7..4] - (RO) Reserved bits +* SEC_MBIST_DONE[8] - (RO) Working status of SEC SRAM MBIST circuit +* RESERVED9[15..9] - (RO) Reserved bits +* SEC_MBIST_FAIL[17..16] - (RO) MBIST check result of SEC SRAM +* RESERVED18[31..18] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_FAIL_ADDR \ +WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_FAIL_MASK \ +0x00030000 /* SEC_MBIST_FAIL[17..16] */ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_FAIL_SHFT 16 +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_DONE_ADDR \ +WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_DONE_MASK \ +0x00000100 /* SEC_MBIST_DONE[8] */ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_DONE_SHFT 8 +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_USE_DEFAULT_DELSEL_ADDR \ +WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_USE_DEFAULT_DELSEL_MASK \ +0x00000008 /* SEC_MBIST_USE_DEFAULT_DELSEL[3] */ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_USE_DEFAULT_DELSEL_SHFT 3 +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_DEBUG_ADDR \ +WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_DEBUG_MASK \ +0x00000004 /* SEC_MBIST_DEBUG[2] */ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_DEBUG_SHFT 2 +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_HOLDB_ADDR \ +WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_HOLDB_MASK \ +0x00000002 /* SEC_MBIST_HOLDB[1] */ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_HOLDB_SHFT 1 +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_MODE_ADDR \ +WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_MODE_MASK \ +0x00000001 /* SEC_MBIST_MODE[0] */ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_MODE_SHFT 0 + +/* +* ---CFG_SEC_MBIST_CTRL_1 (0x820C0000 + 0x25c4)--- +* SEC_MBIST_HDEN[0] - (RW) Control register for mbist SEC HDEN +* RESERVED1[15..1] - (RO) Reserved bits +* SEC_MBIST_AWT[16] - (RW) Control register for mbist SEC AWT +* RESERVED17[31..17] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_1_SEC_MBIST_AWT_ADDR \ +WF_PLE_TOP_CFG_SEC_MBIST_CTRL_1_ADDR +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_1_SEC_MBIST_AWT_MASK \ +0x00010000 /* SEC_MBIST_AWT[16] */ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_1_SEC_MBIST_AWT_SHFT 16 +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_1_SEC_MBIST_HDEN_ADDR \ +WF_PLE_TOP_CFG_SEC_MBIST_CTRL_1_ADDR +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_1_SEC_MBIST_HDEN_MASK \ +0x00000001 /* SEC_MBIST_HDEN[0] */ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_1_SEC_MBIST_HDEN_SHFT 0 + +/* +* ---CFG_SEC_MBIST_CTRL_2 (0x820C0000 + 0x25c8)--- +* SEC_BACKGROUND[15..0] - (RW) The MBIST background control register +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_2_SEC_BACKGROUND_ADDR \ +WF_PLE_TOP_CFG_SEC_MBIST_CTRL_2_ADDR +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_2_SEC_BACKGROUND_MASK \ +0x0000FFFF /* SEC_BACKGROUND[15..0] */ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_2_SEC_BACKGROUND_SHFT 0 + +/* +* ---CFG_SEC_MBIST_CTRL_3 (0x820C0000 + 0x25cc)--- +* SEC_DELSEL_0[31..0] - (RW) SEC DELSEL 0 +*/ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_3_SEC_DELSEL_0_ADDR \ +WF_PLE_TOP_CFG_SEC_MBIST_CTRL_3_ADDR +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_3_SEC_DELSEL_0_MASK \ +0xFFFFFFFF /* SEC_DELSEL_0[31..0] */ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_3_SEC_DELSEL_0_SHFT 0 + +/* +* ---CFG_PF_MBIST_CTRL_0 (0x820C0000 + 0x25e0)--- +* PF_MBIST_MODE[0] - (RW) Control register for mbist_mode of PF +MBIST +* PF_MBIST_HOLDB[1] - (RW) Control register for mbist_holdb of PF +MBIST +* PF_MBIST_DEBUG[2] - (RW) Control register for mbist_debug of PF +MBIST +* PF_MBIST_USE_DEFAULT_DELSEL[3] - (RW) Control register for default DELSEL +* value of PF memory +* PF_MBIST_SLEEP_TEST[4] - (RW) Control register for sleep_test of PF +MBIST +* PF_MBIST_SLEEP_INV[5] - (RW) Control register for sleep_inv of PF +MBIST +* PF_MBIST_SLEEP_W[6] - (RW) Control register for sleep_w of PF MBIST +* PF_MBIST_SLEEP_R[7] - (RW) Control register for sleep_r of PF MBIST +* PF_MBIST_DONE[8] - (RO) Working status of PF SRAM MBIST circuit +* RESERVED9[11..9] - (RO) Reserved bits +* PF_MBIST_FAIL[31..12] - (RO) MBIST check result of PF SRAM +*/ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_FAIL_ADDR \ +WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_FAIL_MASK \ +0xFFFFF000 /* PF_MBIST_FAIL[31..12] */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_FAIL_SHFT 12 +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_DONE_ADDR \ +WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_DONE_MASK \ +0x00000100 /* PF_MBIST_DONE[8] */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_DONE_SHFT 8 +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_SLEEP_R_ADDR \ +WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_SLEEP_R_MASK \ +0x00000080 /* PF_MBIST_SLEEP_R[7] */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_SLEEP_R_SHFT 7 +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_SLEEP_W_ADDR \ +WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_SLEEP_W_MASK \ +0x00000040 /* PF_MBIST_SLEEP_W[6] */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_SLEEP_W_SHFT 6 +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_SLEEP_INV_ADDR \ +WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_SLEEP_INV_MASK \ +0x00000020 /* PF_MBIST_SLEEP_INV[5] */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_SLEEP_INV_SHFT 5 +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_SLEEP_TEST_ADDR \ +WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_SLEEP_TEST_MASK \ +0x00000010 /* PF_MBIST_SLEEP_TEST[4] */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_SLEEP_TEST_SHFT 4 +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_USE_DEFAULT_DELSEL_ADDR \ +WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_USE_DEFAULT_DELSEL_MASK \ +0x00000008 /* PF_MBIST_USE_DEFAULT_DELSEL[3] */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_USE_DEFAULT_DELSEL_SHFT 3 +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_DEBUG_ADDR \ +WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_DEBUG_MASK \ +0x00000004 /* PF_MBIST_DEBUG[2] */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_DEBUG_SHFT 2 +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_HOLDB_ADDR \ +WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_HOLDB_MASK \ +0x00000002 /* PF_MBIST_HOLDB[1] */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_HOLDB_SHFT 1 +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_MODE_ADDR \ +WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_MODE_MASK \ +0x00000001 /* PF_MBIST_MODE[0] */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_MODE_SHFT 0 + +/* +* ---CFG_PF_MBIST_CTRL_1 (0x820C0000 + 0x25e4)--- +* PF_MBIST_HDEN[9..0] - (RW) Control register for mbist PF HDEN +* RESERVED10[11..10] - (RO) Reserved bits +* PF_MBIST_AWT[31..12] - (RW) Control register for mbist PF AWT +*/ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_1_PF_MBIST_AWT_ADDR \ +WF_PLE_TOP_CFG_PF_MBIST_CTRL_1_ADDR +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_1_PF_MBIST_AWT_MASK \ +0xFFFFF000 /* PF_MBIST_AWT[31..12] */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_1_PF_MBIST_AWT_SHFT 12 +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_1_PF_MBIST_HDEN_ADDR \ +WF_PLE_TOP_CFG_PF_MBIST_CTRL_1_ADDR +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_1_PF_MBIST_HDEN_MASK \ +0x000003FF /* PF_MBIST_HDEN[9..0] */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_1_PF_MBIST_HDEN_SHFT 0 + +/* +* ---CFG_PF_MBIST_CTRL_2 (0x820C0000 + 0x25e8)--- +* PF_BACKGROUND[15..0] - (RW) The MBIST background control register +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_2_PF_BACKGROUND_ADDR \ +WF_PLE_TOP_CFG_PF_MBIST_CTRL_2_ADDR +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_2_PF_BACKGROUND_MASK \ +0x0000FFFF /* PF_BACKGROUND[15..0] */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_2_PF_BACKGROUND_SHFT 0 + +/* +* ---CFG_PF_MBIST_CTRL_3 (0x820C0000 + 0x25ec)--- +* PF_DELSEL_0[31..0] - (RW) PF DELSEL 0 +*/ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_3_PF_DELSEL_0_ADDR \ +WF_PLE_TOP_CFG_PF_MBIST_CTRL_3_ADDR +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_3_PF_DELSEL_0_MASK \ +0xFFFFFFFF /* PF_DELSEL_0[31..0] */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_3_PF_DELSEL_0_SHFT 0 + +/* +* ---SYSRAM_MBIST_CTRL (0x820C0000 + 0x3004)--- +* MBIST_SW_RESET[0] - (RW) MBIST Software reset +* RESERVED1[7..1] - (RO) Reserved bits +* MBIST_BSEL[15..8] - (RW) Controls BSEL of SRAM MBIST circuit. +* MBIST_BACKGROUND[31..16] - (RW) The MBIST background control register +*/ +#define WF_PLE_TOP_SYSRAM_MBIST_CTRL_MBIST_BACKGROUND_ADDR \ +WF_PLE_TOP_SYSRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SYSRAM_MBIST_CTRL_MBIST_BACKGROUND_MASK \ +0xFFFF0000 /* MBIST_BACKGROUND[31..16] */ +#define WF_PLE_TOP_SYSRAM_MBIST_CTRL_MBIST_BACKGROUND_SHFT 16 +#define WF_PLE_TOP_SYSRAM_MBIST_CTRL_MBIST_BSEL_ADDR \ +WF_PLE_TOP_SYSRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SYSRAM_MBIST_CTRL_MBIST_BSEL_MASK \ +0x0000FF00 /* MBIST_BSEL[15..8] */ +#define WF_PLE_TOP_SYSRAM_MBIST_CTRL_MBIST_BSEL_SHFT 8 +#define WF_PLE_TOP_SYSRAM_MBIST_CTRL_MBIST_SW_RESET_ADDR \ +WF_PLE_TOP_SYSRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SYSRAM_MBIST_CTRL_MBIST_SW_RESET_MASK \ +0x00000001 /* MBIST_SW_RESET[0] */ +#define WF_PLE_TOP_SYSRAM_MBIST_CTRL_MBIST_SW_RESET_SHFT 0 + +/* +* ---SYSRAM_MBIST_DEBUG (0x820C0000 + 0x3008)--- +* SYSRAM_MBIST_DEBUG[15..0] - (RW) Control register for mbist_debug of +* SYSRAM MBIST +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_SYSRAM_MBIST_DEBUG_SYSRAM_MBIST_DEBUG_ADDR \ +WF_PLE_TOP_SYSRAM_MBIST_DEBUG_ADDR +#define WF_PLE_TOP_SYSRAM_MBIST_DEBUG_SYSRAM_MBIST_DEBUG_MASK \ +0x0000FFFF /* SYSRAM_MBIST_DEBUG[15..0] */ +#define WF_PLE_TOP_SYSRAM_MBIST_DEBUG_SYSRAM_MBIST_DEBUG_SHFT 0 + +/* +* ---SYSRAM_MBIST_MODE (0x820C0000 + 0x300C)--- +* SYSRAM_MBIST_MODE[15..0] - (RW) Control register for mbist_holdb of +* SYSRAM MBIST +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_SYSRAM_MBIST_MODE_SYSRAM_MBIST_MODE_ADDR \ +WF_PLE_TOP_SYSRAM_MBIST_MODE_ADDR +#define WF_PLE_TOP_SYSRAM_MBIST_MODE_SYSRAM_MBIST_MODE_MASK \ +0x0000FFFF /* SYSRAM_MBIST_MODE[15..0] */ +#define WF_PLE_TOP_SYSRAM_MBIST_MODE_SYSRAM_MBIST_MODE_SHFT 0 + +/* +* ---SYSRAM_MBIST_HOLDB (0x820C0000 + 0x3010)--- +* SYSRAM_MBIST_HOLDB[15..0] - (RW) Control register for mbist_holdb of +* sysram MBIST +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_SYSRAM_MBIST_HOLDB_SYSRAM_MBIST_HOLDB_ADDR \ +WF_PLE_TOP_SYSRAM_MBIST_HOLDB_ADDR +#define WF_PLE_TOP_SYSRAM_MBIST_HOLDB_SYSRAM_MBIST_HOLDB_MASK \ +0x0000FFFF /* SYSRAM_MBIST_HOLDB[15..0] */ +#define WF_PLE_TOP_SYSRAM_MBIST_HOLDB_SYSRAM_MBIST_HOLDB_SHFT 0 + +/* +* ---SYSRAM_MBIST_DONE (0x820C0000 + 0x3014)--- +* SYSRAM_MBIST_DONE[15..0] - (RO) Working status of SYSRAM MBIST 3 circuit +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_SYSRAM_MBIST_DONE_SYSRAM_MBIST_DONE_ADDR \ +WF_PLE_TOP_SYSRAM_MBIST_DONE_ADDR +#define WF_PLE_TOP_SYSRAM_MBIST_DONE_SYSRAM_MBIST_DONE_MASK \ +0x0000FFFF /* SYSRAM_MBIST_DONE[15..0] */ +#define WF_PLE_TOP_SYSRAM_MBIST_DONE_SYSRAM_MBIST_DONE_SHFT 0 + +/* +* ---SYSRAM_MBIST_FAIL (0x820C0000 + 0x3018)--- +* SYSRAM_MBIST_FAIL[31..0] - (RO) MBIST check result of SYSRAM cell 3 +*/ +#define WF_PLE_TOP_SYSRAM_MBIST_FAIL_SYSRAM_MBIST_FAIL_ADDR \ +WF_PLE_TOP_SYSRAM_MBIST_FAIL_ADDR +#define WF_PLE_TOP_SYSRAM_MBIST_FAIL_SYSRAM_MBIST_FAIL_MASK \ +0xFFFFFFFF /* SYSRAM_MBIST_FAIL[31..0] */ +#define WF_PLE_TOP_SYSRAM_MBIST_FAIL_SYSRAM_MBIST_FAIL_SHFT 0 + +/* +* ---SYSRAM_MBIST_SLEEP_TEST (0x820C0000 + 0x301C)--- +* SYSRAM_MBIST_SLEEP_TEST[15..0] - (RW) Control register for sleep_test of +* group 3 MBIST +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_SYSRAM_MBIST_SLEEP_TEST_SYSRAM_MBIST_SLEEP_TEST_ADDR \ +WF_PLE_TOP_SYSRAM_MBIST_SLEEP_TEST_ADDR +#define WF_PLE_TOP_SYSRAM_MBIST_SLEEP_TEST_SYSRAM_MBIST_SLEEP_TEST_MASK \ +0x0000FFFF /* SYSRAM_MBIST_SLEEP_TEST[15..0] */ +#define WF_PLE_TOP_SYSRAM_MBIST_SLEEP_TEST_SYSRAM_MBIST_SLEEP_TEST_SHFT 0 + +/* +* ---SYSRAM_MBIST_SLEEP_INV (0x820C0000 + 0x3020)--- +* SYSRAM_MBIST_SLEEP_INV[15..0] - (RW) Control register for sleep_inv of group +* 3 MBIST +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_SYSRAM_MBIST_SLEEP_INV_SYSRAM_MBIST_SLEEP_INV_ADDR \ +WF_PLE_TOP_SYSRAM_MBIST_SLEEP_INV_ADDR +#define WF_PLE_TOP_SYSRAM_MBIST_SLEEP_INV_SYSRAM_MBIST_SLEEP_INV_MASK \ +0x0000FFFF /* SYSRAM_MBIST_SLEEP_INV[15..0] */ +#define WF_PLE_TOP_SYSRAM_MBIST_SLEEP_INV_SYSRAM_MBIST_SLEEP_INV_SHFT 0 + +/* +* ---SYSRAM_MBIST_SLEEP_W (0x820C0000 + 0x3024)--- +* SYSRAM_MBIST_SLEEP_WRITE[15..0] - (RW) Control register for sleep_w of group +* 3 MBIST +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_SYSRAM_MBIST_SLEEP_W_SYSRAM_MBIST_SLEEP_WRITE_ADDR \ +WF_PLE_TOP_SYSRAM_MBIST_SLEEP_W_ADDR +#define WF_PLE_TOP_SYSRAM_MBIST_SLEEP_W_SYSRAM_MBIST_SLEEP_WRITE_MASK \ +0x0000FFFF /* SYSRAM_MBIST_SLEEP_WRITE[15..0] */ +#define WF_PLE_TOP_SYSRAM_MBIST_SLEEP_W_SYSRAM_MBIST_SLEEP_WRITE_SHFT 0 + +/* +* ---SYSRAM_MBIST_SLEEP_R (0x820C0000 + 0x3028)--- +* SYSRAM_MBIST_SLEEP_READ[15..0] - (RW) Control register for sleep_r of group +* 3 MBIST +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_SYSRAM_MBIST_SLEEP_R_SYSRAM_MBIST_SLEEP_READ_ADDR \ +WF_PLE_TOP_SYSRAM_MBIST_SLEEP_R_ADDR +#define WF_PLE_TOP_SYSRAM_MBIST_SLEEP_R_SYSRAM_MBIST_SLEEP_READ_MASK \ +0x0000FFFF /* SYSRAM_MBIST_SLEEP_READ[15..0] */ +#define WF_PLE_TOP_SYSRAM_MBIST_SLEEP_R_SYSRAM_MBIST_SLEEP_READ_SHFT 0 + +/* +* ---SYSRAM_AWT_HDEN (0x820C0000 + 0x302C)--- +* SYSRAM_MBIST_AWT[15..0] - (RW) Control register for mbist SYSRAM 3 AWT +* SYSRAM_MBIST_HDEN[31..16] - (RW) Control register for mbist SYSRAM 3 HDEN +*/ +#define WF_PLE_TOP_SYSRAM_AWT_HDEN_SYSRAM_MBIST_HDEN_ADDR \ +WF_PLE_TOP_SYSRAM_AWT_HDEN_ADDR +#define WF_PLE_TOP_SYSRAM_AWT_HDEN_SYSRAM_MBIST_HDEN_MASK \ +0xFFFF0000 /* SYSRAM_MBIST_HDEN[31..16] */ +#define WF_PLE_TOP_SYSRAM_AWT_HDEN_SYSRAM_MBIST_HDEN_SHFT 16 +#define WF_PLE_TOP_SYSRAM_AWT_HDEN_SYSRAM_MBIST_AWT_ADDR \ +WF_PLE_TOP_SYSRAM_AWT_HDEN_ADDR +#define WF_PLE_TOP_SYSRAM_AWT_HDEN_SYSRAM_MBIST_AWT_MASK \ +0x0000FFFF /* SYSRAM_MBIST_AWT[15..0] */ +#define WF_PLE_TOP_SYSRAM_AWT_HDEN_SYSRAM_MBIST_AWT_SHFT 0 + +/* +* ---SYSRAM_DBG_SEL (0x820C0000 + 0x3030)--- +* SYSRAM_DEBUG_SELECT_0[7..0] - (RW) Selects SYSRAM control debug 0 +* SYSRAM_DEBUG_SELECT_1[15..8] - (RW) Selects SYSRAM control debug 1 +* SYSRAM_DEBUG_SELECT_2[23..16] - (RW) Selects SYSRAM control debug 2 +* SYSRAM_DEBUG_SELECT_3[31..24] - (RW) Selects SYSRAM control debug 3 +*/ +#define WF_PLE_TOP_SYSRAM_DBG_SEL_SYSRAM_DEBUG_SELECT_3_ADDR \ +WF_PLE_TOP_SYSRAM_DBG_SEL_ADDR +#define WF_PLE_TOP_SYSRAM_DBG_SEL_SYSRAM_DEBUG_SELECT_3_MASK \ +0xFF000000 /* SYSRAM_DEBUG_SELECT_3[31..24] */ +#define WF_PLE_TOP_SYSRAM_DBG_SEL_SYSRAM_DEBUG_SELECT_3_SHFT 24 +#define WF_PLE_TOP_SYSRAM_DBG_SEL_SYSRAM_DEBUG_SELECT_2_ADDR \ +WF_PLE_TOP_SYSRAM_DBG_SEL_ADDR +#define WF_PLE_TOP_SYSRAM_DBG_SEL_SYSRAM_DEBUG_SELECT_2_MASK \ +0x00FF0000 /* SYSRAM_DEBUG_SELECT_2[23..16] */ +#define WF_PLE_TOP_SYSRAM_DBG_SEL_SYSRAM_DEBUG_SELECT_2_SHFT 16 +#define WF_PLE_TOP_SYSRAM_DBG_SEL_SYSRAM_DEBUG_SELECT_1_ADDR \ +WF_PLE_TOP_SYSRAM_DBG_SEL_ADDR +#define WF_PLE_TOP_SYSRAM_DBG_SEL_SYSRAM_DEBUG_SELECT_1_MASK \ +0x0000FF00 /* SYSRAM_DEBUG_SELECT_1[15..8] */ +#define WF_PLE_TOP_SYSRAM_DBG_SEL_SYSRAM_DEBUG_SELECT_1_SHFT 8 +#define WF_PLE_TOP_SYSRAM_DBG_SEL_SYSRAM_DEBUG_SELECT_0_ADDR \ +WF_PLE_TOP_SYSRAM_DBG_SEL_ADDR +#define WF_PLE_TOP_SYSRAM_DBG_SEL_SYSRAM_DEBUG_SELECT_0_MASK \ +0x000000FF /* SYSRAM_DEBUG_SELECT_0[7..0] */ +#define WF_PLE_TOP_SYSRAM_DBG_SEL_SYSRAM_DEBUG_SELECT_0_SHFT 0 + +/* +* ---SYSRAM_DELSEL (0x820C0000 + 0x3070)--- +* TYPE0_SYSRAM_DELSEL[31..0] - (RW) Type0 SYSRAM DELSEL bits +*/ +#define WF_PLE_TOP_SYSRAM_DELSEL_TYPE0_SYSRAM_DELSEL_ADDR \ +WF_PLE_TOP_SYSRAM_DELSEL_ADDR +#define WF_PLE_TOP_SYSRAM_DELSEL_TYPE0_SYSRAM_DELSEL_MASK \ +0xFFFFFFFF /* TYPE0_SYSRAM_DELSEL[31..0] */ +#define WF_PLE_TOP_SYSRAM_DELSEL_TYPE0_SYSRAM_DELSEL_SHFT 0 + +/* +* ---SYSRAM_DELSEL_1 (0x820C0000 + 0x3074)--- +* TYPE1_SYSRAM_DELSEL[31..0] - (RW) Type1 SYSRAM DELSEL bits +*/ +#define WF_PLE_TOP_SYSRAM_DELSEL_1_TYPE1_SYSRAM_DELSEL_ADDR \ +WF_PLE_TOP_SYSRAM_DELSEL_1_ADDR +#define WF_PLE_TOP_SYSRAM_DELSEL_1_TYPE1_SYSRAM_DELSEL_MASK \ +0xFFFFFFFF /* TYPE1_SYSRAM_DELSEL[31..0] */ +#define WF_PLE_TOP_SYSRAM_DELSEL_1_TYPE1_SYSRAM_DELSEL_SHFT 0 + +/* +* ---SYSRAM_DELSEL_2 (0x820C0000 + 0x3078)--- +* TYPE2_SYSRAM_DELSEL[31..0] - (RW) Type2 SYSRAM DELSEL bits +*/ +#define WF_PLE_TOP_SYSRAM_DELSEL_2_TYPE2_SYSRAM_DELSEL_ADDR \ +WF_PLE_TOP_SYSRAM_DELSEL_2_ADDR +#define WF_PLE_TOP_SYSRAM_DELSEL_2_TYPE2_SYSRAM_DELSEL_MASK \ +0xFFFFFFFF /* TYPE2_SYSRAM_DELSEL[31..0] */ +#define WF_PLE_TOP_SYSRAM_DELSEL_2_TYPE2_SYSRAM_DELSEL_SHFT 0 + +/* +* ---SYSRAM_DELSEL_3 (0x820C0000 + 0x307C)--- +* TYPE3_SYSRAM_DELSEL[31..0] - (RW) Type3 SYSRAM DELSEL bits +*/ +#define WF_PLE_TOP_SYSRAM_DELSEL_3_TYPE3_SYSRAM_DELSEL_ADDR \ +WF_PLE_TOP_SYSRAM_DELSEL_3_ADDR +#define WF_PLE_TOP_SYSRAM_DELSEL_3_TYPE3_SYSRAM_DELSEL_MASK \ +0xFFFFFFFF /* TYPE3_SYSRAM_DELSEL[31..0] */ +#define WF_PLE_TOP_SYSRAM_DELSEL_3_TYPE3_SYSRAM_DELSEL_SHFT 0 + +/* +* ---SYSRAM_OUTRAN_ERR_FLAG (0x820C0000 + 0x3080)--- +* SYSRAM_OUTRAN_ERR_FLAG[31..0] - (RO) Type3 SYSRAM DELSEL bits +*/ +#define WF_PLE_TOP_SYSRAM_OUTRAN_ERR_FLAG_SYSRAM_OUTRAN_ERR_FLAG_ADDR \ +WF_PLE_TOP_SYSRAM_OUTRAN_ERR_FLAG_ADDR +#define WF_PLE_TOP_SYSRAM_OUTRAN_ERR_FLAG_SYSRAM_OUTRAN_ERR_FLAG_MASK \ +0xFFFFFFFF /* SYSRAM_OUTRAN_ERR_FLAG[31..0] */ +#define WF_PLE_TOP_SYSRAM_OUTRAN_ERR_FLAG_SYSRAM_OUTRAN_ERR_FLAG_SHFT 0 + +#ifdef __cplusplus +} +#endif + +#endif /* __WF_PLE_TOP_REGS_H__ */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/mt7915/wf_pse_top.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/mt7915/wf_pse_top.h new file mode 100644 index 0000000000000000000000000000000000000000..668ee6364e84eded73ae89a4ca87b4fb8b7a403d --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/mt7915/wf_pse_top.h @@ -0,0 +1,3353 @@ +/* [File] : wf_pse_top.h */ +/* [Revision time] : Mon Mar 18 14:59:41 2019 */ +/* [Description] : This file is auto generated by CODA */ +/* [Copyright] : Copyright (C) 2019 Mediatek Incorportion. All rights */ +/* reserved. */ + +#ifndef __WF_PSE_TOP_REGS_H__ +#define __WF_PSE_TOP_REGS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* ************************************************************************** */ +/* */ +/* WF_PSE_TOP CR Definitions */ +/* */ +/* ************************************************************************** */ + +#define WF_PSE_TOP_BASE 0x820C8000 + +#define WF_PSE_TOP_GC_ADDR (WF_PSE_TOP_BASE + 0x00) /* 8000 */ +#define WF_PSE_TOP_PBUF_CTRL_ADDR (WF_PSE_TOP_BASE + 0x14) /* 8014 */ +#define WF_PSE_TOP_INT_N9_EN_MASK_ADDR (WF_PSE_TOP_BASE + 0x20) /* 8020 */ +#define WF_PSE_TOP_INT_N9_STS_ADDR (WF_PSE_TOP_BASE + 0x24) /* 8024 */ +#define WF_PSE_TOP_INT_N9_ERR_STS_ADDR (WF_PSE_TOP_BASE + 0x28) /* 8028 */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_ADDR (WF_PSE_TOP_BASE + 0x2C) /* 802C */ +#define WF_PSE_TOP_INT_N9_ERR1_STS_ADDR (WF_PSE_TOP_BASE + 0x30) /* 8030 */ +#define WF_PSE_TOP_INT_N9_ERR1_MASK_ADDR (WF_PSE_TOP_BASE + 0x34) /* 8034 */ +#define WF_PSE_TOP_C_GET_FID_0_ADDR (WF_PSE_TOP_BASE + 0x40) /* 8040 */ +#define WF_PSE_TOP_C_GET_FID_1_ADDR (WF_PSE_TOP_BASE + 0x44) /* 8044 */ +#define WF_PSE_TOP_C_EN_QUEUE_0_ADDR (WF_PSE_TOP_BASE + 0x60) /* 8060 */ +#define WF_PSE_TOP_C_EN_QUEUE_1_ADDR (WF_PSE_TOP_BASE + 0x64) /* 8064 */ +#define WF_PSE_TOP_C_EN_QUEUE_2_ADDR (WF_PSE_TOP_BASE + 0x68) /* 8068 */ +#define WF_PSE_TOP_C_DE_QUEUE_0_ADDR (WF_PSE_TOP_BASE + 0x80) /* 8080 */ +#define WF_PSE_TOP_C_DE_QUEUE_1_ADDR (WF_PSE_TOP_BASE + 0x84) /* 8084 */ +#define WF_PSE_TOP_C_DE_QUEUE_2_ADDR (WF_PSE_TOP_BASE + 0x88) /* 8088 */ +#define WF_PSE_TOP_C_DE_QUEUE_3_ADDR (WF_PSE_TOP_BASE + 0x8c) /* 808C */ +#define WF_PSE_TOP_C_DE_QUEUE_4_ADDR (WF_PSE_TOP_BASE + 0x90) /* 8090 */ +#define WF_PSE_TOP_ALLOCATE_0_ADDR (WF_PSE_TOP_BASE + 0xA0) /* 80A0 */ +#define WF_PSE_TOP_ALLOCATE_1_ADDR (WF_PSE_TOP_BASE + 0xA4) /* 80A4 */ +#define WF_PSE_TOP_QUEUE_EMPTY_ADDR (WF_PSE_TOP_BASE + 0xB0) /* 80B0 */ +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_ADDR (WF_PSE_TOP_BASE + 0xB4) /* 80B4 */ +#define WF_PSE_TOP_FREEPG_START_END_ADDR (WF_PSE_TOP_BASE + 0xC0) /* 80C0 */ +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_ADDR (WF_PSE_TOP_BASE + 0xc4) /* 80C4 */ +#define WF_PSE_TOP_TO_N9_INT_ADDR (WF_PSE_TOP_BASE + 0xf0) /* 80F0 */ +#define WF_PSE_TOP_FREEPG_CNT_ADDR (WF_PSE_TOP_BASE + 0x100) /* 8100 */ +#define WF_PSE_TOP_FREEPG_HEAD_TAIL_ADDR (WF_PSE_TOP_BASE + 0x104) /* 8104 */ +#define WF_PSE_TOP_GROUP_REFILL_CTRL_ADDR (WF_PSE_TOP_BASE + 0x108) /* 8108 */ +#define WF_PSE_TOP_PG_HIF0_GROUP_ADDR (WF_PSE_TOP_BASE + 0x110) /* 8110 */ +#define WF_PSE_TOP_HIF0_PG_INFO_ADDR (WF_PSE_TOP_BASE + 0x114) /* 8114 */ +#define WF_PSE_TOP_PG_HIF1_GROUP_ADDR (WF_PSE_TOP_BASE + 0x118) /* 8118 */ +#define WF_PSE_TOP_HIF1_PG_INFO_ADDR (WF_PSE_TOP_BASE + 0x11C) /* 811C */ +#define WF_PSE_TOP_PG_CPU_GROUP_ADDR (WF_PSE_TOP_BASE + 0x150) /* 8150 */ +#define WF_PSE_TOP_CPU_PG_INFO_ADDR (WF_PSE_TOP_BASE + 0x154) /* 8154 */ +#define WF_PSE_TOP_PG_PLE_GROUP_ADDR (WF_PSE_TOP_BASE + 0x160) /* 8160 */ +#define WF_PSE_TOP_PLE_PG_INFO_ADDR (WF_PSE_TOP_BASE + 0x164) /* 8164 */ +#define WF_PSE_TOP_PG_PLE1_GROUP_ADDR (WF_PSE_TOP_BASE + 0x168) /* 8168 */ +#define WF_PSE_TOP_PLE1_PG_INFO_ADDR (WF_PSE_TOP_BASE + 0x16C) /* 816C */ +#define WF_PSE_TOP_PG_LMAC0_GROUP_ADDR (WF_PSE_TOP_BASE + 0x170) /* 8170 */ +#define WF_PSE_TOP_LMAC0_PG_INFO_ADDR (WF_PSE_TOP_BASE + 0x174) /* 8174 */ +#define WF_PSE_TOP_PG_LMAC1_GROUP_ADDR (WF_PSE_TOP_BASE + 0x178) /* 8178 */ +#define WF_PSE_TOP_LMAC1_PG_INFO_ADDR (WF_PSE_TOP_BASE + 0x17C) /* 817C */ +#define WF_PSE_TOP_PG_LMAC2_GROUP_ADDR (WF_PSE_TOP_BASE + 0x180) /* 8180 */ +#define WF_PSE_TOP_LMAC2_PG_INFO_ADDR (WF_PSE_TOP_BASE + 0x184) /* 8184 */ +#define WF_PSE_TOP_PG_LMAC3_GROUP_ADDR (WF_PSE_TOP_BASE + 0x188) /* 8188 */ +#define WF_PSE_TOP_LMAC3_PG_INFO_ADDR (WF_PSE_TOP_BASE + 0x18C) /* 818C */ +#define WF_PSE_TOP_PG_MDP_GROUP_ADDR (WF_PSE_TOP_BASE + 0x198) /* 8198 */ +#define WF_PSE_TOP_MDP_PG_INFO_ADDR (WF_PSE_TOP_BASE + 0x19C) /* 819C */ +#define WF_PSE_TOP_RL_BUF_CTRL_0_ADDR (WF_PSE_TOP_BASE + 0x1A0) /* 81A0 */ +#define WF_PSE_TOP_RL_BUF_CTRL_1_ADDR (WF_PSE_TOP_BASE + 0x1A4) /* 81A4 */ +#define WF_PSE_TOP_FL_QUE_CTRL_0_ADDR (WF_PSE_TOP_BASE + 0x1B0) /* 81B0 */ +#define WF_PSE_TOP_FL_QUE_CTRL_1_ADDR (WF_PSE_TOP_BASE + 0x1B4) /* 81B4 */ +#define WF_PSE_TOP_FL_QUE_CTRL_2_ADDR (WF_PSE_TOP_BASE + 0x1B8) /* 81B8 */ +#define WF_PSE_TOP_FL_QUE_CTRL_3_ADDR (WF_PSE_TOP_BASE + 0x1BC) /* 81BC */ +#define WF_PSE_TOP_PL_QUE_CTRL_0_ADDR (WF_PSE_TOP_BASE + 0x1C0) /* 81C0 */ +#define WF_PSE_TOP_PSE_LP_CTRL_ADDR (WF_PSE_TOP_BASE + 0x1D0) /* 81D0 */ +#define WF_PSE_TOP_PSE_WFDMA_BUF_CTRL_ADDR (WF_PSE_TOP_BASE + 0x1E0)/* 81E0*/ +#define WF_PSE_TOP_PSE_CT_PRI_CTRL_ADDR (WF_PSE_TOP_BASE + 0x1EC) /* 81EC */ +#define WF_PSE_TOP_PLE_ENQ_PKT_NUM_ADDR (WF_PSE_TOP_BASE + 0x1F0) /* 81F0 */ +#define WF_PSE_TOP_CPU_ENQ_PKT_NUM_ADDR (WF_PSE_TOP_BASE + 0x1F4) /* 81F4 */ +#define WF_PSE_TOP_LMAC_ENQ_PKT_NUM_ADDR (WF_PSE_TOP_BASE + 0x1F8) /* 81F8 */ +#define WF_PSE_TOP_HIF_ENQ_PKT_NUM_ADDR (WF_PSE_TOP_BASE + 0x1FC) /* 81FC */ +#define WF_PSE_TOP_MDP_ENQ_PKT_NUM_ADDR (WF_PSE_TOP_BASE + 0x200) /* 8200 */ +#define WF_PSE_TOP_TIMEOUT_CTRL_ADDR (WF_PSE_TOP_BASE + 0x244) /* 8244 */ +#define WF_PSE_TOP_FSM_IDLE_WD_CTRL_ADDR (WF_PSE_TOP_BASE + 0x24C) /* 824C */ +#define WF_PSE_TOP_FSM_IDLE_WD_EN_ADDR (WF_PSE_TOP_BASE + 0x250) /* 8250 */ +#define WF_PSE_TOP_PSE_INTER_ERR_FLAG_ADDR (WF_PSE_TOP_BASE + 0x280)/* 8280*/ +#define WF_PSE_TOP_PSE_SER_CTRL_ADDR (WF_PSE_TOP_BASE + 0x2a0) /* 82A0 */ +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_ADDR (WF_PSE_TOP_BASE + 0x2b0) /* 82B0 */ +#define WF_PSE_TOP_PSE_MBIST_BSEL_ADDR (WF_PSE_TOP_BASE + 0x2b4) /* 82B4 */ +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_1_ADDR (WF_PSE_TOP_BASE + 0x2b8) /* 82B8\*/ +#define WF_PSE_TOP_SRAM_MBIST_BACKGROUND_ADDR \ +(WF_PSE_TOP_BASE + 0x2d0) /* 82D0 */ +#define WF_PSE_TOP_PSE_MISC_FUNC_CTRL_ADDR (WF_PSE_TOP_BASE + 0x2d4)/* 82D4*/ +#define WF_PSE_TOP_SRAM_MBIST_DONE_ADDR (WF_PSE_TOP_BASE + 0x2d8) /* 82D8 */ +#define WF_PSE_TOP_SRAM_MBIST_FAIL_ADDR (WF_PSE_TOP_BASE + 0x2dc) /* 82DC */ +#define WF_PSE_TOP_SRAM_MBIST_CTRL_ADDR (WF_PSE_TOP_BASE + 0x2e0) /* 82E0 */ +#define WF_PSE_TOP_SRAM_MBIST_DELSEL_ADDR (WF_PSE_TOP_BASE + 0x2e4) /* 82E4 */ +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_ADDR (WF_PSE_TOP_BASE + 0x2e8)/* 82E8*/ +#define WF_PSE_TOP_SRAM_MBIST_DELSEL_1_ADDR (WF_PSE_TOP_BASE + 0x2f0) /* 82F0\ + */ +#define WF_PSE_TOP_PSE_SEEK_CR_00_ADDR (WF_PSE_TOP_BASE + 0x3d0) /* 83D0 */ +#define WF_PSE_TOP_PSE_SEEK_CR_01_ADDR (WF_PSE_TOP_BASE + 0x3d4) /* 83D4 */ +#define WF_PSE_TOP_PSE_SEEK_CR_02_ADDR (WF_PSE_TOP_BASE + 0x3d8) /* 83D8 */ +#define WF_PSE_TOP_PSE_SEEK_CR_03_ADDR (WF_PSE_TOP_BASE + 0x3dc) /* 83DC */ +#define WF_PSE_TOP_PSE_SEEK_CR_04_ADDR (WF_PSE_TOP_BASE + 0x3e0) /* 83E0 */ +#define WF_PSE_TOP_PSE_SEEK_CR_05_ADDR (WF_PSE_TOP_BASE + 0x3e4) /* 83E4 */ +#define WF_PSE_TOP_PSE_SEEK_CR_06_ADDR (WF_PSE_TOP_BASE + 0x3e8) /* 83E8 */ +#define WF_PSE_TOP_PSE_SEEK_CR_07_ADDR (WF_PSE_TOP_BASE + 0x3ec) /* 83EC */ +#define WF_PSE_TOP_PSE_SEEK_CR_08_ADDR (WF_PSE_TOP_BASE + 0x3f0) /* 83F0 */ +#define WF_PSE_TOP_PSE_SEEK_CR_09_ADDR (WF_PSE_TOP_BASE + 0x3f4) /* 83F4 */ + +/* +* ---GC (0x820C8000 + 0x00)--- +* ALL_RESET[0] - (RW) Resets PSE logic and register +* LOGIC_RESET[1] - (RW) Resets PSE logic circuit +* INIT_DONE[2] - (RO) PSE control SRAM initialization +indicator +* RESERVED3[15..3] - (RO) Reserved bits +* SRAM_MBIST_RESET[16] - (RW) Reset control of SRAM MBIST (low active) +* RESERVED17[17] - (RO) Reserved bits +* DIS_PSE_DYN_CKG[18] - (RW) Disable control of wf_pse_top dynamic +* clock gating function +* RESERVED19[31..19] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_GC_DIS_PSE_DYN_CKG_ADDR WF_PSE_TOP_GC_ADDR +#define WF_PSE_TOP_GC_DIS_PSE_DYN_CKG_MASK 0x00040000 /* DIS_PSE_DYN_CKG[18] \ + */ +#define WF_PSE_TOP_GC_DIS_PSE_DYN_CKG_SHFT 18 +#define WF_PSE_TOP_GC_SRAM_MBIST_RESET_ADDR WF_PSE_TOP_GC_ADDR +#define WF_PSE_TOP_GC_SRAM_MBIST_RESET_MASK \ +0x00010000 /* SRAM_MBIST_RESET[16] */ +#define WF_PSE_TOP_GC_SRAM_MBIST_RESET_SHFT 16 +#define WF_PSE_TOP_GC_INIT_DONE_ADDR WF_PSE_TOP_GC_ADDR +#define WF_PSE_TOP_GC_INIT_DONE_MASK 0x00000004 /* INIT_DONE[2] */ +#define WF_PSE_TOP_GC_INIT_DONE_SHFT 2 +#define WF_PSE_TOP_GC_LOGIC_RESET_ADDR WF_PSE_TOP_GC_ADDR +#define WF_PSE_TOP_GC_LOGIC_RESET_MASK 0x00000002 /* LOGIC_RESET[1] */ +#define WF_PSE_TOP_GC_LOGIC_RESET_SHFT 1 +#define WF_PSE_TOP_GC_ALL_RESET_ADDR WF_PSE_TOP_GC_ADDR +#define WF_PSE_TOP_GC_ALL_RESET_MASK 0x00000001 /* ALL_RESET[0] */ +#define WF_PSE_TOP_GC_ALL_RESET_SHFT 0 + +/* +* ---PBUF_CTRL (0x820C8000 + 0x14)--- +* TOTAL_PAGE_NUM[11..0] - (RW) Total page numbers +* Set the total page before release PSE logic +* reset, and must not be changed after release logic reset. +* RESERVED12[16..12] - (RO) Reserved bits +* PBUF_OFFSET[25..17] - (RW) Packet buffer offset. +* Set the buffer offset before release PSE +* logic reset, and must not be changed after release logic reset. +* RESERVED26[30..26] - (RO) Reserved bits +* PAGE_SIZE_CFG[31] - (RW) Configures page size +* Set up the page size before releasing PSE +* logic reset; it should not be changed after logic reset is released. +*/ +#define WF_PSE_TOP_PBUF_CTRL_PAGE_SIZE_CFG_ADDR WF_PSE_TOP_PBUF_CTRL_ADDR +#define WF_PSE_TOP_PBUF_CTRL_PAGE_SIZE_CFG_MASK \ +0x80000000 /* PAGE_SIZE_CFG[31] */ +#define WF_PSE_TOP_PBUF_CTRL_PAGE_SIZE_CFG_SHFT 31 +#define WF_PSE_TOP_PBUF_CTRL_PBUF_OFFSET_ADDR WF_PSE_TOP_PBUF_CTRL_ADDR +#define WF_PSE_TOP_PBUF_CTRL_PBUF_OFFSET_MASK \ +0x03FE0000 /* PBUF_OFFSET[25..17] */ +#define WF_PSE_TOP_PBUF_CTRL_PBUF_OFFSET_SHFT 17 +#define WF_PSE_TOP_PBUF_CTRL_TOTAL_PAGE_NUM_ADDR WF_PSE_TOP_PBUF_CTRL_ADDR +#define WF_PSE_TOP_PBUF_CTRL_TOTAL_PAGE_NUM_MASK \ +0x00000FFF /* TOTAL_PAGE_NUM[11..0] */ +#define WF_PSE_TOP_PBUF_CTRL_TOTAL_PAGE_NUM_SHFT 0 + +/* +* ---INT_N9_EN_MASK (0x820C8000 + 0x20)--- +* EN_CPU_Q0_NE[0] - (RW) CPU queue 0 not empty interrupt +* EN_CPU_Q1_NE[1] - (RW) CPU queue 1 not empty interrupt +* EN_CPU_Q2_NE[2] - (RW) CPU queue 2 not empty interrupt +* EN_CPU_Q3_NE[3] - (RW) CPU queue 3 not empty interrupt +* RESERVED4[11..4] - (RO) Reserved bits +* EN_LMAC_ENQ[12] - (RW) Enables LMAC enq interrupt +* EN_ERROR_INT[13] - (RW) Error condition interrupt status +* RESERVED14[15..14] - (RO) Reserved bits +* EN_TOGGLE_INT[16] - (RW) Data toggle of CR4 toggle register +(0xe0) +* EN_LMAC_EMPTY_FALL[17] - (RW) LMAC Buffer empty fall edge detect +* EN_LMAC_EMPTY_RAISE[18] - (RW) LMAC Buffer empty raise edge detect +* EN_HIF_Q0_NE[19] - (RW) HIF queue 0 not empty interrupt +* EN_HIF_Q1_NE[20] - (RW) HIF queue 1 not empty interrupt +* EN_HIF_Q2_NE[21] - (RW) HIF queue 2 not empty interrupt +* EN_HIF_Q3_NE[22] - (RW) HIF queue 3 not empty interrupt +* EN_HIF_Q4_NE[23] - (RW) HIF queue 4 not empty interrupt +* EN_HIF_Q5_NE[24] - (RW) HIF queue 5 not empty interrupt +* EN_HIF_Q6_NE[25] - (RW) HIF queue 6 not empty interrupt +* EN_HIF_Q7_NE[26] - (RW) HIF queue 7 not empty interrupt +* EN_HIF_Q8_NE[27] - (RW) HIF queue 8 not empty interrupt +* EN_HIF_Q9_NE[28] - (RW) HIF queue 9 not empty interrupt +* EN_HIF_Q10_NE[29] - (RW) HIF queue 10 not empty interrupt +* EN_HIF_Q11_NE[30] - (RW) HIF queue 11 not empty interrupt +* RESERVED31[31] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q11_NE_ADDR \ +WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q11_NE_MASK \ +0x40000000 /* EN_HIF_Q11_NE[30] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q11_NE_SHFT 30 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q10_NE_ADDR \ +WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q10_NE_MASK \ +0x20000000 /* EN_HIF_Q10_NE[29] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q10_NE_SHFT 29 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q9_NE_ADDR \ +WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q9_NE_MASK \ +0x10000000 /* EN_HIF_Q9_NE[28] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q9_NE_SHFT 28 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q8_NE_ADDR \ +WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q8_NE_MASK \ +0x08000000 /* EN_HIF_Q8_NE[27] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q8_NE_SHFT 27 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q7_NE_ADDR \ +WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q7_NE_MASK \ +0x04000000 /* EN_HIF_Q7_NE[26] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q7_NE_SHFT 26 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q6_NE_ADDR \ +WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q6_NE_MASK \ +0x02000000 /* EN_HIF_Q6_NE[25] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q6_NE_SHFT 25 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q5_NE_ADDR \ +WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q5_NE_MASK \ +0x01000000 /* EN_HIF_Q5_NE[24] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q5_NE_SHFT 24 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q4_NE_ADDR \ +WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q4_NE_MASK \ +0x00800000 /* EN_HIF_Q4_NE[23] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q4_NE_SHFT 23 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q3_NE_ADDR \ +WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q3_NE_MASK \ +0x00400000 /* EN_HIF_Q3_NE[22] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q3_NE_SHFT 22 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q2_NE_ADDR \ +WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q2_NE_MASK \ +0x00200000 /* EN_HIF_Q2_NE[21] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q2_NE_SHFT 21 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q1_NE_ADDR \ +WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q1_NE_MASK \ +0x00100000 /* EN_HIF_Q1_NE[20] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q1_NE_SHFT 20 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q0_NE_ADDR \ +WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q0_NE_MASK \ +0x00080000 /* EN_HIF_Q0_NE[19] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q0_NE_SHFT 19 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_LMAC_EMPTY_RAISE_ADDR \ +WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_LMAC_EMPTY_RAISE_MASK \ +0x00040000 /* EN_LMAC_EMPTY_RAISE[18] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_LMAC_EMPTY_RAISE_SHFT 18 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_LMAC_EMPTY_FALL_ADDR \ +WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_LMAC_EMPTY_FALL_MASK \ +0x00020000 /* EN_LMAC_EMPTY_FALL[17] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_LMAC_EMPTY_FALL_SHFT 17 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_TOGGLE_INT_ADDR \ +WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_TOGGLE_INT_MASK \ +0x00010000 /* EN_TOGGLE_INT[16] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_TOGGLE_INT_SHFT 16 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_ERROR_INT_ADDR \ +WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_ERROR_INT_MASK \ +0x00002000 /* EN_ERROR_INT[13] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_ERROR_INT_SHFT 13 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_LMAC_ENQ_ADDR \ +WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_LMAC_ENQ_MASK \ +0x00001000 /* EN_LMAC_ENQ[12] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_LMAC_ENQ_SHFT 12 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_CPU_Q3_NE_ADDR \ +WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_CPU_Q3_NE_MASK \ +0x00000008 /* EN_CPU_Q3_NE[3] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_CPU_Q3_NE_SHFT 3 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_CPU_Q2_NE_ADDR \ +WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_CPU_Q2_NE_MASK \ +0x00000004 /* EN_CPU_Q2_NE[2] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_CPU_Q2_NE_SHFT 2 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_CPU_Q1_NE_ADDR \ +WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_CPU_Q1_NE_MASK \ +0x00000002 /* EN_CPU_Q1_NE[1] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_CPU_Q1_NE_SHFT 1 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_CPU_Q0_NE_ADDR \ +WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_CPU_Q0_NE_MASK \ +0x00000001 /* EN_CPU_Q0_NE[0] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_CPU_Q0_NE_SHFT 0 + +/* +* ---INT_N9_STS (0x820C8000 + 0x24)--- +* CPU_Q0_NE[0] - (W1C) CPU queue 0 not empty interrupt status +* CPU_Q1_NE[1] - (W1C) CPU queue 1 not empty interrupt status +* CPU_Q2_NE[2] - (W1C) CPU queue 2 not empty interrupt status +* CPU_Q3_NE[3] - (W1C) CPU queue 3 not empty interrupt status +* RESERVED4[11..4] - (RO) Reserved bits +* LMAC_ENQ[12] - (W1C) LMAC enq interrupt status +* ERROR_INT[13] - (RO) Error condition interrupt status +* ERROR_1_INT[14] - (RO) Error condition interrupt status +* RESERVED15[15] - (RO) Reserved bits +* DATA_TOGGLE[16] - (W1C) Data toggle of CR4 toggle register +(0xe0) +* LMAC_EMPTY_FALL[17] - (W1C) LMAC Buffer empty fall edge detect +* LMAC_EMPTY_RAISE[18] - (W1C) LMAC Buffer empty raise edge detect +* HIF_Q0_NE[19] - (W1C) HIF queue 0 not empty interrupt status +* HIF_Q1_NE[20] - (W1C) HIF queue 1 not empty interrupt status +* HIF_Q2_NE[21] - (W1C) HIF queue 2 not empty interrupt status +* HIF_Q3_NE[22] - (W1C) HIF queue 3 not empty interrupt status +* HIF_Q4_NE[23] - (W1C) HIF queue 4 not empty interrupt status +* HIF_Q5_NE[24] - (W1C) HIF queue 5 not empty interrupt status +* HIF_Q6_NE[25] - (W1C) HIF queue 6 not empty interrupt status +* HIF_Q7_NE[26] - (W1C) HIF queue 7 not empty interrupt status +* HIF_Q8_NE[27] - (W1C) HIF queue 8 not empty interrupt status +* HIF_Q9_NE[28] - (W1C) HIF queue 9 not empty interrupt status +* HIF_Q10_NE[29] - (W1C) HIF queue 10 not empty interrupt status +* HIF_Q11_NE[30] - (W1C) HIF queue 11 not empty interrupt status +* RESERVED31[31] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_INT_N9_STS_HIF_Q11_NE_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_HIF_Q11_NE_MASK 0x40000000 /* HIF_Q11_NE[30] */ +#define WF_PSE_TOP_INT_N9_STS_HIF_Q11_NE_SHFT 30 +#define WF_PSE_TOP_INT_N9_STS_HIF_Q10_NE_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_HIF_Q10_NE_MASK 0x20000000 /* HIF_Q10_NE[29] */ +#define WF_PSE_TOP_INT_N9_STS_HIF_Q10_NE_SHFT 29 +#define WF_PSE_TOP_INT_N9_STS_HIF_Q9_NE_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_HIF_Q9_NE_MASK 0x10000000 /* HIF_Q9_NE[28] */ +#define WF_PSE_TOP_INT_N9_STS_HIF_Q9_NE_SHFT 28 +#define WF_PSE_TOP_INT_N9_STS_HIF_Q8_NE_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_HIF_Q8_NE_MASK 0x08000000 /* HIF_Q8_NE[27] */ +#define WF_PSE_TOP_INT_N9_STS_HIF_Q8_NE_SHFT 27 +#define WF_PSE_TOP_INT_N9_STS_HIF_Q7_NE_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_HIF_Q7_NE_MASK 0x04000000 /* HIF_Q7_NE[26] */ +#define WF_PSE_TOP_INT_N9_STS_HIF_Q7_NE_SHFT 26 +#define WF_PSE_TOP_INT_N9_STS_HIF_Q6_NE_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_HIF_Q6_NE_MASK 0x02000000 /* HIF_Q6_NE[25] */ +#define WF_PSE_TOP_INT_N9_STS_HIF_Q6_NE_SHFT 25 +#define WF_PSE_TOP_INT_N9_STS_HIF_Q5_NE_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_HIF_Q5_NE_MASK 0x01000000 /* HIF_Q5_NE[24] */ +#define WF_PSE_TOP_INT_N9_STS_HIF_Q5_NE_SHFT 24 +#define WF_PSE_TOP_INT_N9_STS_HIF_Q4_NE_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_HIF_Q4_NE_MASK 0x00800000 /* HIF_Q4_NE[23] */ +#define WF_PSE_TOP_INT_N9_STS_HIF_Q4_NE_SHFT 23 +#define WF_PSE_TOP_INT_N9_STS_HIF_Q3_NE_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_HIF_Q3_NE_MASK 0x00400000 /* HIF_Q3_NE[22] */ +#define WF_PSE_TOP_INT_N9_STS_HIF_Q3_NE_SHFT 22 +#define WF_PSE_TOP_INT_N9_STS_HIF_Q2_NE_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_HIF_Q2_NE_MASK 0x00200000 /* HIF_Q2_NE[21] */ +#define WF_PSE_TOP_INT_N9_STS_HIF_Q2_NE_SHFT 21 +#define WF_PSE_TOP_INT_N9_STS_HIF_Q1_NE_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_HIF_Q1_NE_MASK 0x00100000 /* HIF_Q1_NE[20] */ +#define WF_PSE_TOP_INT_N9_STS_HIF_Q1_NE_SHFT 20 +#define WF_PSE_TOP_INT_N9_STS_HIF_Q0_NE_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_HIF_Q0_NE_MASK 0x00080000 /* HIF_Q0_NE[19] */ +#define WF_PSE_TOP_INT_N9_STS_HIF_Q0_NE_SHFT 19 +#define WF_PSE_TOP_INT_N9_STS_LMAC_EMPTY_RAISE_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_LMAC_EMPTY_RAISE_MASK \ +0x00040000 /* LMAC_EMPTY_RAISE[18] */ +#define WF_PSE_TOP_INT_N9_STS_LMAC_EMPTY_RAISE_SHFT 18 +#define WF_PSE_TOP_INT_N9_STS_LMAC_EMPTY_FALL_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_LMAC_EMPTY_FALL_MASK \ +0x00020000 /* LMAC_EMPTY_FALL[17] */ +#define WF_PSE_TOP_INT_N9_STS_LMAC_EMPTY_FALL_SHFT 17 +#define WF_PSE_TOP_INT_N9_STS_DATA_TOGGLE_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_DATA_TOGGLE_MASK 0x00010000 /* DATA_TOGGLE[16]*/ +#define WF_PSE_TOP_INT_N9_STS_DATA_TOGGLE_SHFT 16 +#define WF_PSE_TOP_INT_N9_STS_ERROR_1_INT_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_ERROR_1_INT_MASK 0x00004000 /* ERROR_1_INT[14]*/ +#define WF_PSE_TOP_INT_N9_STS_ERROR_1_INT_SHFT 14 +#define WF_PSE_TOP_INT_N9_STS_ERROR_INT_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_ERROR_INT_MASK 0x00002000 /* ERROR_INT[13] */ +#define WF_PSE_TOP_INT_N9_STS_ERROR_INT_SHFT 13 +#define WF_PSE_TOP_INT_N9_STS_LMAC_ENQ_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_LMAC_ENQ_MASK 0x00001000 /* LMAC_ENQ[12] */ +#define WF_PSE_TOP_INT_N9_STS_LMAC_ENQ_SHFT 12 +#define WF_PSE_TOP_INT_N9_STS_CPU_Q3_NE_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_CPU_Q3_NE_MASK 0x00000008 /* CPU_Q3_NE[3] */ +#define WF_PSE_TOP_INT_N9_STS_CPU_Q3_NE_SHFT 3 +#define WF_PSE_TOP_INT_N9_STS_CPU_Q2_NE_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_CPU_Q2_NE_MASK 0x00000004 /* CPU_Q2_NE[2] */ +#define WF_PSE_TOP_INT_N9_STS_CPU_Q2_NE_SHFT 2 +#define WF_PSE_TOP_INT_N9_STS_CPU_Q1_NE_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_CPU_Q1_NE_MASK 0x00000002 /* CPU_Q1_NE[1] */ +#define WF_PSE_TOP_INT_N9_STS_CPU_Q1_NE_SHFT 1 +#define WF_PSE_TOP_INT_N9_STS_CPU_Q0_NE_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_CPU_Q0_NE_MASK 0x00000001 /* CPU_Q0_NE[0] */ +#define WF_PSE_TOP_INT_N9_STS_CPU_Q0_NE_SHFT 0 + +/* +* ---INT_N9_ERR_STS (0x820C8000 + 0x28)--- +* Q_CMD_ERR_P0[0] - (W1C) Queue command error interrupt status of +* port 0. Avoid unclear error flag, please clear flag when logic reset. +* Q_CMD_ERR_P1[1] - (W1C) Queue command error interrupt status of +* port 1. Avoid unclear error flag, please clear flag when logic reset. +* Q_CMD_ERR_P2[2] - (W1C) Queue command error interrupt status of +* port 2. Avoid unclear error flag, please clear flag when logic reset. +* Q_CMD_ERR_P3[3] - (W1C) Queue command error interrupt status of +* port 3. Avoid unclear error flag, please clear flag when logic reset. +* Q_CMD_ERR_P4[4] - (W1C) Queue command error interrupt status of +* port 4. Avoid unclear error flag, please clear flag when logic reset. +* Q_CMD_ERR_P5[5] - (W1C) Queue command error interrupt status of +* port 5. Avoid unclear error flag, please clear flag when logic reset. +* Q_CMD_ERR_P6[6] - (W1C) Queue command error interrupt status of +* port 6. Avoid unclear error flag, please clear flag when logic reset. +* RESERVED7[7] - (RO) Reserved bits +* PAGE_UDF_P0[8] - (W1C) Page underflow interrupt status of port +* 0. Avoid unclear error flag, please clear flag when logic reset. +* PAGE_UDF_P1[9] - (W1C) Page underflow interrupt status of port +* 1. Avoid unclear error flag, please clear flag when logic reset. +* PAGE_UDF_P2[10] - (W1C) Page underflow interrupt status of port +* 2. Avoid unclear error flag, please clear flag when logic reset. +* PAGE_UDF_P3[11] - (W1C) Page underflow interrupt status of port +* 3. Avoid unclear error flag, please clear flag when logic reset. +* PAGE_UDF_P4[12] - (W1C) Page underflow interrupt status of port +* 4. Avoid unclear error flag, please clear flag when logic reset. +* PAGE_UDF_P5[13] - (W1C) Page underflow interrupt status of port +* 5. Avoid unclear error flag, please clear flag when logic reset. +* PAGE_UDF_P6[14] - (W1C) Page underflow interrupt status of port +* 6. Avoid unclear error flag, please clear flag when logic reset. +* RESERVED15[15] - (RO) Reserved bits +* QUEUE_OPER_ERR_P0[16] - (W1C) Queue operation error of port 0. Avoid +* unclear error flag, please clear flag when logic reset. +* QUEUE_OPER_ERR_P1[17] - (W1C) Queue operation error of port 1. Avoid +* unclear error flag, please clear flag when logic reset. +* QUEUE_OPER_ERR_P2[18] - (W1C) Queue operation error of port 2. Avoid +* unclear error flag, please clear flag when logic reset. +* QUEUE_OPER_ERR_P3[19] - (W1C) Queue operation error of port 3. Avoid +* unclear error flag, please clear flag when logic reset. +* QUEUE_OPER_ERR_P4[20] - (W1C) Queue operation error of port 4. Avoid +* unclear error flag, please clear flag when logic reset. +* QUEUE_OPER_ERR_P5[21] - (W1C) Queue operation error of port 5. Avoid +* unclear error flag, please clear flag when logic reset. +* QUEUE_OPER_ERR_P6[22] - (W1C) Queue operation error of port 6. Avoid +* unclear error flag, please clear flag when logic reset. +* RESERVED23[23] - (RO) Reserved bits +* DATA_OPER_ERR_P0[24] - (W1C) Data operation error of port 0. Avoid +* unclear error flag, please clear flag when logic reset. +* DATA_OPER_ERR_P1[25] - (W1C) Data operation error of port 1. Avoid +* unclear error flag, please clear flag when logic reset. +* DATA_OPER_ERR_P2[26] - (W1C) Data operation error of port 2. Avoid +* unclear error flag, please clear flag when logic reset. +* DATA_OPER_ERR_P3[27] - (W1C) Data operation error of port 3. Avoid +* unclear error flag, please clear flag when logic reset. +* DATA_OPER_ERR_P4[28] - (W1C) Data operation error of port 4. Avoid +* unclear error flag, please clear flag when logic reset. +* DATA_OPER_ERR_P5[29] - (W1C) Data operation error of port 5. Avoid +* unclear error flag, please clear flag when logic reset. +* DATA_OPER_ERR_P6[30] - (W1C) Data operation error of port 6. Avoid +* unclear error flag, please clear flag when logic reset. +* RESERVED31[31] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P6_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P6_MASK \ +0x40000000 /* DATA_OPER_ERR_P6[30] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P6_SHFT 30 +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P5_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P5_MASK \ +0x20000000 /* DATA_OPER_ERR_P5[29] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P5_SHFT 29 +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P4_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P4_MASK \ +0x10000000 /* DATA_OPER_ERR_P4[28] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P4_SHFT 28 +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P3_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P3_MASK \ +0x08000000 /* DATA_OPER_ERR_P3[27] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P3_SHFT 27 +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P2_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P2_MASK \ +0x04000000 /* DATA_OPER_ERR_P2[26] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P2_SHFT 26 +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P1_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P1_MASK \ +0x02000000 /* DATA_OPER_ERR_P1[25] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P1_SHFT 25 +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P0_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P0_MASK \ +0x01000000 /* DATA_OPER_ERR_P0[24] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P0_SHFT 24 +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P6_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P6_MASK \ +0x00400000 /* QUEUE_OPER_ERR_P6[22] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P6_SHFT 22 +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P5_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P5_MASK \ +0x00200000 /* QUEUE_OPER_ERR_P5[21] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P5_SHFT 21 +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P4_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P4_MASK \ +0x00100000 /* QUEUE_OPER_ERR_P4[20] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P4_SHFT 20 +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P3_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P3_MASK \ +0x00080000 /* QUEUE_OPER_ERR_P3[19] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P3_SHFT 19 +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P2_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P2_MASK \ +0x00040000 /* QUEUE_OPER_ERR_P2[18] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P2_SHFT 18 +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P1_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P1_MASK \ +0x00020000 /* QUEUE_OPER_ERR_P1[17] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P1_SHFT 17 +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P0_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P0_MASK \ +0x00010000 /* QUEUE_OPER_ERR_P0[16] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P0_SHFT 16 +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P6_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P6_MASK \ +0x00004000 /* PAGE_UDF_P6[14] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P6_SHFT 14 +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P5_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P5_MASK \ +0x00002000 /* PAGE_UDF_P5[13] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P5_SHFT 13 +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P4_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P4_MASK \ +0x00001000 /* PAGE_UDF_P4[12] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P4_SHFT 12 +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P3_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P3_MASK \ +0x00000800 /* PAGE_UDF_P3[11] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P3_SHFT 11 +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P2_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P2_MASK \ +0x00000400 /* PAGE_UDF_P2[10] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P2_SHFT 10 +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P1_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P1_MASK \ +0x00000200 /* PAGE_UDF_P1[9] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P1_SHFT 9 +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P0_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P0_MASK \ +0x00000100 /* PAGE_UDF_P0[8] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P0_SHFT 8 +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P6_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P6_MASK \ +0x00000040 /* Q_CMD_ERR_P6[6] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P6_SHFT 6 +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P5_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P5_MASK \ +0x00000020 /* Q_CMD_ERR_P5[5] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P5_SHFT 5 +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P4_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P4_MASK \ +0x00000010 /* Q_CMD_ERR_P4[4] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P4_SHFT 4 +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P3_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P3_MASK \ +0x00000008 /* Q_CMD_ERR_P3[3] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P3_SHFT 3 +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P2_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P2_MASK \ +0x00000004 /* Q_CMD_ERR_P2[2] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P2_SHFT 2 +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P1_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P1_MASK \ +0x00000002 /* Q_CMD_ERR_P1[1] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P1_SHFT 1 +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P0_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P0_MASK \ +0x00000001 /* Q_CMD_ERR_P0[0] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P0_SHFT 0 + +/* +* ---INT_N9_ERR_MASK (0x820C8000 + 0x2C)--- +* EN_Q_CMD_ERR_P0[0] - (RW) Enable Queue command error interrupt +* status of port 0. Avoid unclear error flag, please clear flag when logic +reset. +* EN_Q_CMD_ERR_P1[1] - (RW) Enable Queue command error interrupt +* status of port 1. Avoid unclear error flag, please clear flag when logic +reset. +* EN_Q_CMD_ERR_P2[2] - (RW) Enable Queue command error interrupt +* status of port 2. Avoid unclear error flag, please clear flag when logic +reset. +* EN_Q_CMD_ERR_P3[3] - (RW) Enable Queue command error interrupt +* status of port 3. Avoid unclear error flag, please clear flag when logic +reset. +* EN_Q_CMD_ERR_P4[4] - (RW) Enable Queue command error interrupt +* status of port 4. Avoid unclear error flag, please clear flag when logic +reset. +* EN_Q_CMD_ERR_P5[5] - (RW) Enable Queue command error interrupt +* status of port 5. Avoid unclear error flag, please clear flag when logic +reset. +* EN_Q_CMD_ERR_P6[6] - (RW) Enable Queue command error interrupt +* status of port 6. Avoid unclear error flag, please clear flag when logic +reset. +* RESERVED7[7] - (RO) Reserved bits +* EN_PAGE_UDF_P0[8] - (RW) Enable Page underflow interrupt status +* of port 0. Avoid unclear error flag, please clear flag when logic reset. +* EN_PAGE_UDF_P1[9] - (RW) Enable Page underflow interrupt status +* of port 1. Avoid unclear error flag, please clear flag when logic reset. +* EN_PAGE_UDF_P2[10] - (RW) Enable Page underflow interrupt status +* of port 2. Avoid unclear error flag, please clear flag when logic reset. +* EN_PAGE_UDF_P3[11] - (RW) Enable Page underflow interrupt status +* of port 3. Avoid unclear error flag, please clear flag when logic reset. +* EN_PAGE_UDF_P4[12] - (RW) Enable Page underflow interrupt status +* of port 4. Avoid unclear error flag, please clear flag when logic reset. +* EN_PAGE_UDF_P5[13] - (RW) Enable Page underflow interrupt status +* of port 5. Avoid unclear error flag, please clear flag when logic reset. +* EN_PAGE_UDF_P6[14] - (RW) Enable Page underflow interrupt status +* of port 6. Avoid unclear error flag, please clear flag when logic reset. +* RESERVED15[15] - (RO) Reserved bits +* EN_QUEUE_OPER_ERR_P0[16] - (RW) Enable Queue operation error of port 0. +* Avoid unclear error flag, please clear flag when logic reset. +* EN_QUEUE_OPER_ERR_P1[17] - (RW) Enable Queue operation error of port 1. +* Avoid unclear error flag, please clear flag when logic reset. +* EN_QUEUE_OPER_ERR_P2[18] - (RW) Enable Queue operation error of port 2. +* Avoid unclear error flag, please clear flag when logic reset. +* EN_QUEUE_OPER_ERR_P3[19] - (RW) Enable Queue operation error of port 3. +* Avoid unclear error flag, please clear flag when logic reset. +* EN_QUEUE_OPER_ERR_P4[20] - (RW) Enable Queue operation error of port 4. +* Avoid unclear error flag, please clear flag when logic reset. +* EN_QUEUE_OPER_ERR_P5[21] - (RW) Enable Queue operation error of port 5. +* Avoid unclear error flag, please clear flag when logic reset. +* EN_QUEUE_OPER_ERR_P6[22] - (RW) Enable Queue operation error of port 6. +* Avoid unclear error flag, please clear flag when logic reset. +* RESERVED23[23] - (RO) Reserved bits +* EN_DATA_OPER_ERR_P0[24] - (RW) Enable Data operation error of port 0. +* Avoid unclear error flag, please clear flag when logic reset. +* EN_DATA_OPER_ERR_P1[25] - (RW) Enable Data operation error of port 1. +* Avoid unclear error flag, please clear flag when logic reset. +* EN_DATA_OPER_ERR_P2[26] - (RW) Enable Data operation error of port 2. +* Avoid unclear error flag, please clear flag when logic reset. +* EN_DATA_OPER_ERR_P3[27] - (RW) Enable Data operation error of port 3. +* Avoid unclear error flag, please clear flag when logic reset. +* EN_DATA_OPER_ERR_P4[28] - (RW) Enable Data operation error of port 4. +* Avoid unclear error flag, please clear flag when logic reset. +* EN_DATA_OPER_ERR_P5[29] - (RW) Enable Data operation error of port 5. +* Avoid unclear error flag, please clear flag when logic reset. +* EN_DATA_OPER_EN_ERR_P6[30] - (RW) Enable Data operation error of port 6. +* Avoid unclear error flag, please clear flag when logic reset. +* RESERVED31[31] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_EN_ERR_P6_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_EN_ERR_P6_MASK \ +0x40000000 /* EN_DATA_OPER_EN_ERR_P6[30] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_EN_ERR_P6_SHFT 30 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P5_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P5_MASK \ +0x20000000 /* EN_DATA_OPER_ERR_P5[29] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P5_SHFT 29 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P4_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P4_MASK \ +0x10000000 /* EN_DATA_OPER_ERR_P4[28] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P4_SHFT 28 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P3_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P3_MASK \ +0x08000000 /* EN_DATA_OPER_ERR_P3[27] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P3_SHFT 27 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P2_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P2_MASK \ +0x04000000 /* EN_DATA_OPER_ERR_P2[26] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P2_SHFT 26 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P1_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P1_MASK \ +0x02000000 /* EN_DATA_OPER_ERR_P1[25] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P1_SHFT 25 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P0_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P0_MASK \ +0x01000000 /* EN_DATA_OPER_ERR_P0[24] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P0_SHFT 24 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P6_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P6_MASK \ +0x00400000 /* EN_QUEUE_OPER_ERR_P6[22] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P6_SHFT 22 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P5_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P5_MASK \ +0x00200000 /* EN_QUEUE_OPER_ERR_P5[21] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P5_SHFT 21 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P4_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P4_MASK \ +0x00100000 /* EN_QUEUE_OPER_ERR_P4[20] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P4_SHFT 20 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P3_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P3_MASK \ +0x00080000 /* EN_QUEUE_OPER_ERR_P3[19] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P3_SHFT 19 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P2_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P2_MASK \ +0x00040000 /* EN_QUEUE_OPER_ERR_P2[18] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P2_SHFT 18 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P1_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P1_MASK \ +0x00020000 /* EN_QUEUE_OPER_ERR_P1[17] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P1_SHFT 17 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P0_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P0_MASK \ +0x00010000 /* EN_QUEUE_OPER_ERR_P0[16] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P0_SHFT 16 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P6_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P6_MASK \ +0x00004000 /* EN_PAGE_UDF_P6[14] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P6_SHFT 14 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P5_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P5_MASK \ +0x00002000 /* EN_PAGE_UDF_P5[13] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P5_SHFT 13 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P4_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P4_MASK \ +0x00001000 /* EN_PAGE_UDF_P4[12] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P4_SHFT 12 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P3_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P3_MASK \ +0x00000800 /* EN_PAGE_UDF_P3[11] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P3_SHFT 11 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P2_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P2_MASK \ +0x00000400 /* EN_PAGE_UDF_P2[10] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P2_SHFT 10 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P1_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P1_MASK \ +0x00000200 /* EN_PAGE_UDF_P1[9] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P1_SHFT 9 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P0_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P0_MASK \ +0x00000100 /* EN_PAGE_UDF_P0[8] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P0_SHFT 8 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P6_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P6_MASK \ +0x00000040 /* EN_Q_CMD_ERR_P6[6] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P6_SHFT 6 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P5_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P5_MASK \ +0x00000020 /* EN_Q_CMD_ERR_P5[5] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P5_SHFT 5 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P4_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P4_MASK \ +0x00000010 /* EN_Q_CMD_ERR_P4[4] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P4_SHFT 4 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P3_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P3_MASK \ +0x00000008 /* EN_Q_CMD_ERR_P3[3] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P3_SHFT 3 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P2_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P2_MASK \ +0x00000004 /* EN_Q_CMD_ERR_P2[2] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P2_SHFT 2 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P1_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P1_MASK \ +0x00000002 /* EN_Q_CMD_ERR_P1[1] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P1_SHFT 1 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P0_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P0_MASK \ +0x00000001 /* EN_Q_CMD_ERR_P0[0] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P0_SHFT 0 + +/* +* ---INT_N9_ERR1_STS (0x820C8000 + 0x30)--- +* WDT_ERR_P0[0] - (W1C) Port state watch dog timeout error +* interrupt status of port 0. Avoid unclear error flag, please clear flag when +* logic reset. +* WDT_ERR_P1[1] - (W1C) Port state watch dog timeout error +* interrupt status of port 1. Avoid unclear error flag, please clear flag when +* logic reset. +* WDT_ERR_P2[2] - (W1C) Port state watch dog timeout error +* interrupt status of port 2. Avoid unclear error flag, please clear flag when +* logic reset. +* WDT_ERR_P3[3] - (W1C) Port state watch dog timeout error +* interrupt status of port 3. Avoid unclear error flag, please clear flag when +* logic reset. +* WDT_ERR_P4[4] - (W1C) Port state watch dog timeout error +* interrupt status of port 4. Avoid unclear error flag, please clear flag when +* logic reset. +* WDT_ERR_P5[5] - (W1C) Port state watch dog timeout error +* interrupt status of port 5. Avoid unclear error flag, please clear flag when +* logic reset. +* WDT_ERR_P6[6] - (W1C) Port state watch dog timeout error +* interrupt status of port 6. Avoid unclear error flag, please clear flag when +* logic reset. +* RESERVED7[7] - (RO) Reserved bits +* FL_HANG_ERR[8] - (W1C) Frame link FSM hang error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* PL_HANG_ERR[9] - (W1C) Page link FSM hang error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* DOUBLE_RLS_ERR[10] - (W1C) Double release error interrupt. Avoid +* unclear error flag, please clear flag when logic reset. +* FREE_HEAD_TAIL_ERR[11] - (W1C) Free head/tail error interrupt. Avoid +* unclear error flag, please clear flag when logic reset. +* FL_QSTRUCT_ERR[12] - (W1C) Frame Link queue NULL error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* RESERVED13[31..13] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_INT_N9_ERR1_STS_FL_QSTRUCT_ERR_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_STS_FL_QSTRUCT_ERR_MASK \ +0x00001000 /* FL_QSTRUCT_ERR[12] */ +#define WF_PSE_TOP_INT_N9_ERR1_STS_FL_QSTRUCT_ERR_SHFT 12 +#define WF_PSE_TOP_INT_N9_ERR1_STS_FREE_HEAD_TAIL_ERR_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_STS_FREE_HEAD_TAIL_ERR_MASK \ +0x00000800 /* FREE_HEAD_TAIL_ERR[11] */ +#define WF_PSE_TOP_INT_N9_ERR1_STS_FREE_HEAD_TAIL_ERR_SHFT 11 +#define WF_PSE_TOP_INT_N9_ERR1_STS_DOUBLE_RLS_ERR_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_STS_DOUBLE_RLS_ERR_MASK \ +0x00000400 /* DOUBLE_RLS_ERR[10] */ +#define WF_PSE_TOP_INT_N9_ERR1_STS_DOUBLE_RLS_ERR_SHFT 10 +#define WF_PSE_TOP_INT_N9_ERR1_STS_PL_HANG_ERR_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_STS_PL_HANG_ERR_MASK \ +0x00000200 /* PL_HANG_ERR[9] */ +#define WF_PSE_TOP_INT_N9_ERR1_STS_PL_HANG_ERR_SHFT 9 +#define WF_PSE_TOP_INT_N9_ERR1_STS_FL_HANG_ERR_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_STS_FL_HANG_ERR_MASK \ +0x00000100 /* FL_HANG_ERR[8] */ +#define WF_PSE_TOP_INT_N9_ERR1_STS_FL_HANG_ERR_SHFT 8 +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P6_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P6_MASK \ +0x00000040 /* WDT_ERR_P6[6] */ +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P6_SHFT 6 +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P5_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P5_MASK \ +0x00000020 /* WDT_ERR_P5[5] */ +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P5_SHFT 5 +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P4_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P4_MASK \ +0x00000010 /* WDT_ERR_P4[4] */ +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P4_SHFT 4 +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P3_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P3_MASK \ +0x00000008 /* WDT_ERR_P3[3] */ +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P3_SHFT 3 +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P2_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P2_MASK \ +0x00000004 /* WDT_ERR_P2[2] */ +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P2_SHFT 2 +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P1_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P1_MASK \ +0x00000002 /* WDT_ERR_P1[1] */ +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P1_SHFT 1 +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P0_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P0_MASK \ +0x00000001 /* WDT_ERR_P0[0] */ +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P0_SHFT 0 + +/* +* ---INT_N9_ERR1_MASK (0x820C8000 + 0x34)--- +* EN_WDT_ERR_P0[0] - (RW) Enable Port state watch dog timeout +* error interrupt status of port 0. Avoid unclear error flag, please clear flag +* when logic reset. +* EN_WDT_ERR_P1[1] - (RW) Enable Port state watch dog timeout +* error interrupt status of port 1. Avoid unclear error flag, please clear flag +* when logic reset. +* EN_WDT_ERR_P2[2] - (RW) Enable Port state watch dog timeout +* error interrupt status of port 2. Avoid unclear error flag, please clear flag +* when logic reset. +* EN_WDT_ERR_P3[3] - (RW) Enable Port state watch dog timeout +* error interrupt status of port 3. Avoid unclear error flag, please clear flag +* when logic reset. +* EN_WDT_ERR_P4[4] - (RW) Enable Port state watch dog timeout +* error interrupt status of port 4. Avoid unclear error flag, please clear flag +* when logic reset. +* EN_WDT_ERR_P5[5] - (RW) Enable Port state watch dog timeout +* error interrupt status of port 5. Avoid unclear error flag, please clear flag +* when logic reset. +* EN_WDT_ERR_P6[6] - (RW) Enable Port state watch dog timeout +* error interrupt status of port 6. Avoid unclear error flag, please clear flag +* when logic reset. +* RESERVED7[7] - (RO) Reserved bits +* EN_FL_HANG_ERR[8] - (RW) Enable Frame link FSM hang error +* interrupt. Avoid unclear error flag, please clear flag when logic reset. +* PL_HANGEN__ERR[9] - (RW) Enable Page link FSM hang error +* interrupt. Avoid unclear error flag, please clear flag when logic reset. +* EN_DOUBLE_RLS_ERR[10] - (RW) Enable Double release error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* EN_FREE_HEAD_TAIL_ERR[11] - (RW) Enable Free head/tail error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* EN_FL_QSTRTUT_ERR[12] - (RW) Enable Frame Link queue NULL error +* interrupt. Avoid unclear error flag, please clear flag when logic reset. +* RESERVED13[31..13] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_FL_QSTRTUT_ERR_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_FL_QSTRTUT_ERR_MASK \ +0x00001000 /* EN_FL_QSTRTUT_ERR[12] */ +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_FL_QSTRTUT_ERR_SHFT 12 +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_FREE_HEAD_TAIL_ERR_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_FREE_HEAD_TAIL_ERR_MASK \ +0x00000800 /* EN_FREE_HEAD_TAIL_ERR[11] */ +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_FREE_HEAD_TAIL_ERR_SHFT 11 +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_DOUBLE_RLS_ERR_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_DOUBLE_RLS_ERR_MASK \ +0x00000400 /* EN_DOUBLE_RLS_ERR[10] */ +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_DOUBLE_RLS_ERR_SHFT 10 +#define WF_PSE_TOP_INT_N9_ERR1_MASK_PL_HANGEN__ERR_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_MASK_PL_HANGEN__ERR_MASK \ +0x00000200 /* PL_HANGEN__ERR[9] */ +#define WF_PSE_TOP_INT_N9_ERR1_MASK_PL_HANGEN__ERR_SHFT 9 +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_FL_HANG_ERR_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_FL_HANG_ERR_MASK \ +0x00000100 /* EN_FL_HANG_ERR[8] */ +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_FL_HANG_ERR_SHFT 8 +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P6_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P6_MASK \ +0x00000040 /* EN_WDT_ERR_P6[6] */ +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P6_SHFT 6 +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P5_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P5_MASK \ +0x00000020 /* EN_WDT_ERR_P5[5] */ +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P5_SHFT 5 +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P4_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P4_MASK \ +0x00000010 /* EN_WDT_ERR_P4[4] */ +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P4_SHFT 4 +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P3_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P3_MASK \ +0x00000008 /* EN_WDT_ERR_P3[3] */ +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P3_SHFT 3 +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P2_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P2_MASK \ +0x00000004 /* EN_WDT_ERR_P2[2] */ +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P2_SHFT 2 +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P1_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P1_MASK \ +0x00000002 /* EN_WDT_ERR_P1[1] */ +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P1_SHFT 1 +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P0_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P0_MASK \ +0x00000001 /* EN_WDT_ERR_P0[0] */ +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P0_SHFT 0 + +/* +* ---C_GET_FID_0 (0x820C8000 + 0x40)--- +* QUEUE_FRAME_ID[15..0] - (RW) Frame ID for get command +* At GET_FRAME_TYPE = 2'h0/2'h1: +* QUEUE_FRAME_ID[15:14] = PID +* 2'h0: HIF port +* 2'h1: CPU port +* 2'h2: LMAC port +* QUEUE_FRAME_ID[9:0] = WLANID +* At GET_FRAME_TYPE = 2'h2/2'h3: +* QUEUE_FRAME_ID[11:0] = reference FID +* GET_FRAME_TYPE[19..16] - (RW) GET_SUB_TYPE +* RESERVED20[23..20] - (RO) Reserved bits +* GET_FRAME_QID[30..24] - (RW) Queue ID vlaue +* EXECUTE[31] - (A0) Executes command +*/ +#define WF_PSE_TOP_C_GET_FID_0_EXECUTE_ADDR WF_PSE_TOP_C_GET_FID_0_ADDR +#define WF_PSE_TOP_C_GET_FID_0_EXECUTE_MASK 0x80000000 /* EXECUTE[31] */ +#define WF_PSE_TOP_C_GET_FID_0_EXECUTE_SHFT 31 +#define WF_PSE_TOP_C_GET_FID_0_GET_FRAME_QID_ADDR WF_PSE_TOP_C_GET_FID_0_ADDR +#define WF_PSE_TOP_C_GET_FID_0_GET_FRAME_QID_MASK \ +0x7F000000 /* GET_FRAME_QID[30..24] */ +#define WF_PSE_TOP_C_GET_FID_0_GET_FRAME_QID_SHFT 24 +#define WF_PSE_TOP_C_GET_FID_0_GET_FRAME_TYPE_ADDR WF_PSE_TOP_C_GET_FID_0_ADDR +#define WF_PSE_TOP_C_GET_FID_0_GET_FRAME_TYPE_MASK \ +0x000F0000 /* GET_FRAME_TYPE[19..16] */ +#define WF_PSE_TOP_C_GET_FID_0_GET_FRAME_TYPE_SHFT 16 +#define WF_PSE_TOP_C_GET_FID_0_QUEUE_FRAME_ID_ADDR WF_PSE_TOP_C_GET_FID_0_ADDR +#define WF_PSE_TOP_C_GET_FID_0_QUEUE_FRAME_ID_MASK \ +0x0000FFFF /* QUEUE_FRAME_ID[15..0] */ +#define WF_PSE_TOP_C_GET_FID_0_QUEUE_FRAME_ID_SHFT 0 + +/* +* ---C_GET_FID_1 (0x820C8000 + 0x44)--- +* GET_RETURN_FID[11..0] - (RO) Return frame ID +* RESERVED12[14..12] - (RO) Reserved bits +* END[15] - (RO) Return frame ID is end FID +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_C_GET_FID_1_END_ADDR WF_PSE_TOP_C_GET_FID_1_ADDR +#define WF_PSE_TOP_C_GET_FID_1_END_MASK 0x00008000 /* END[15] */ +#define WF_PSE_TOP_C_GET_FID_1_END_SHFT 15 +#define WF_PSE_TOP_C_GET_FID_1_GET_RETURN_FID_ADDR WF_PSE_TOP_C_GET_FID_1_ADDR +#define WF_PSE_TOP_C_GET_FID_1_GET_RETURN_FID_MASK \ +0x00000FFF /* GET_RETURN_FID[11..0] */ +#define WF_PSE_TOP_C_GET_FID_1_GET_RETURN_FID_SHFT 0 + +/* +* ---C_EN_QUEUE_0 (0x820C8000 + 0x60)--- +* DST_WLANID[9..0] - (RW) Destination WLANID for enqueue +* RESERVED10[13..10] - (RO) Reserved bits +* DST_PID[15..14] - (RW) Destination port ID for enqueue +* SUB_TYPE[19..16] - (RW) Sub-type of enqueue command +* RESERVED20[22..20] - (RO) Reserved bits +* DELAY_ENQ[23] - (RW) Delays enqueue +* DST_QID[30..24] - (RW) Destination queue ID for enqueue +* EXECUTE[31] - (A0) Executes command +*/ +#define WF_PSE_TOP_C_EN_QUEUE_0_EXECUTE_ADDR WF_PSE_TOP_C_EN_QUEUE_0_ADDR +#define WF_PSE_TOP_C_EN_QUEUE_0_EXECUTE_MASK 0x80000000 /* EXECUTE[31] */ +#define WF_PSE_TOP_C_EN_QUEUE_0_EXECUTE_SHFT 31 +#define WF_PSE_TOP_C_EN_QUEUE_0_DST_QID_ADDR WF_PSE_TOP_C_EN_QUEUE_0_ADDR +#define WF_PSE_TOP_C_EN_QUEUE_0_DST_QID_MASK 0x7F000000 /* DST_QID[30..24] */ +#define WF_PSE_TOP_C_EN_QUEUE_0_DST_QID_SHFT 24 +#define WF_PSE_TOP_C_EN_QUEUE_0_DELAY_ENQ_ADDR WF_PSE_TOP_C_EN_QUEUE_0_ADDR +#define WF_PSE_TOP_C_EN_QUEUE_0_DELAY_ENQ_MASK 0x00800000 /* DELAY_ENQ[23] */ +#define WF_PSE_TOP_C_EN_QUEUE_0_DELAY_ENQ_SHFT 23 +#define WF_PSE_TOP_C_EN_QUEUE_0_SUB_TYPE_ADDR WF_PSE_TOP_C_EN_QUEUE_0_ADDR +#define WF_PSE_TOP_C_EN_QUEUE_0_SUB_TYPE_MASK 0x000F0000 /* SUB_TYPE[19..16] \ + */ +#define WF_PSE_TOP_C_EN_QUEUE_0_SUB_TYPE_SHFT 16 +#define WF_PSE_TOP_C_EN_QUEUE_0_DST_PID_ADDR WF_PSE_TOP_C_EN_QUEUE_0_ADDR +#define WF_PSE_TOP_C_EN_QUEUE_0_DST_PID_MASK 0x0000C000 /* DST_PID[15..14] */ +#define WF_PSE_TOP_C_EN_QUEUE_0_DST_PID_SHFT 14 +#define WF_PSE_TOP_C_EN_QUEUE_0_DST_WLANID_ADDR WF_PSE_TOP_C_EN_QUEUE_0_ADDR +#define WF_PSE_TOP_C_EN_QUEUE_0_DST_WLANID_MASK \ +0x000003FF /* DST_WLANID[9..0] */ +#define WF_PSE_TOP_C_EN_QUEUE_0_DST_WLANID_SHFT 0 + +/* +* ---C_EN_QUEUE_1 (0x820C8000 + 0x64)--- +* CUR_LIST_FID_START[11..0] - (RW) Start frame ID of enqueue operation +* list, enqueue FID of enqueue operation +* RESERVED12[15..12] - (RO) Reserved bits +* CUR_LIST_FID_END[27..16] - (RW) End frame ID of enqueue operation list +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_C_EN_QUEUE_1_CUR_LIST_FID_END_ADDR \ +WF_PSE_TOP_C_EN_QUEUE_1_ADDR +#define WF_PSE_TOP_C_EN_QUEUE_1_CUR_LIST_FID_END_MASK \ +0x0FFF0000 /* CUR_LIST_FID_END[27..16] */ +#define WF_PSE_TOP_C_EN_QUEUE_1_CUR_LIST_FID_END_SHFT 16 +#define WF_PSE_TOP_C_EN_QUEUE_1_CUR_LIST_FID_START_ADDR \ +WF_PSE_TOP_C_EN_QUEUE_1_ADDR +#define WF_PSE_TOP_C_EN_QUEUE_1_CUR_LIST_FID_START_MASK \ +0x00000FFF /* CUR_LIST_FID_START[11..0] */ +#define WF_PSE_TOP_C_EN_QUEUE_1_CUR_LIST_FID_START_SHFT 0 + +/* +* ---C_EN_QUEUE_2 (0x820C8000 + 0x68)--- +* TARGET_FID[11..0] - (RW) Target reference FID for enqueue +operation +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_C_EN_QUEUE_2_TARGET_FID_ADDR WF_PSE_TOP_C_EN_QUEUE_2_ADDR +#define WF_PSE_TOP_C_EN_QUEUE_2_TARGET_FID_MASK \ +0x00000FFF /* TARGET_FID[11..0] */ +#define WF_PSE_TOP_C_EN_QUEUE_2_TARGET_FID_SHFT 0 + +/* +* ---C_DE_QUEUE_0 (0x820C8000 + 0x80)--- +* SRC_WLANID[9..0] - (RW) Source WLAN ID for dequeue command +* RESERVED10[13..10] - (RO) Reserved bits +* SRC_PID[15..14] - (RW) Source port ID for dequeue command +* DEQ_SUB_TYPE[19..16] - (RW) Dequeue subtype of dequeue command +* ENQ_SUB_TYPE[22..20] - (RW) Enqueue subtype of enqueue command +* Only valid in Deq&Enq type. +* ENQ_VLD[23] - (RW) Deq&Enq command valid +* SRC_QID[30..24] - (RW) Source queue ID for dequeue command +* EXECUTE[31] - (A0) Executes dequeue command +*/ +#define WF_PSE_TOP_C_DE_QUEUE_0_EXECUTE_ADDR WF_PSE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_0_EXECUTE_MASK 0x80000000 /* EXECUTE[31] */ +#define WF_PSE_TOP_C_DE_QUEUE_0_EXECUTE_SHFT 31 +#define WF_PSE_TOP_C_DE_QUEUE_0_SRC_QID_ADDR WF_PSE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_0_SRC_QID_MASK 0x7F000000 /* SRC_QID[30..24] */ +#define WF_PSE_TOP_C_DE_QUEUE_0_SRC_QID_SHFT 24 +#define WF_PSE_TOP_C_DE_QUEUE_0_ENQ_VLD_ADDR WF_PSE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_0_ENQ_VLD_MASK 0x00800000 /* ENQ_VLD[23] */ +#define WF_PSE_TOP_C_DE_QUEUE_0_ENQ_VLD_SHFT 23 +#define WF_PSE_TOP_C_DE_QUEUE_0_ENQ_SUB_TYPE_ADDR WF_PSE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_0_ENQ_SUB_TYPE_MASK \ +0x00700000 /* ENQ_SUB_TYPE[22..20] */ +#define WF_PSE_TOP_C_DE_QUEUE_0_ENQ_SUB_TYPE_SHFT 20 +#define WF_PSE_TOP_C_DE_QUEUE_0_DEQ_SUB_TYPE_ADDR WF_PSE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_0_DEQ_SUB_TYPE_MASK \ +0x000F0000 /* DEQ_SUB_TYPE[19..16] */ +#define WF_PSE_TOP_C_DE_QUEUE_0_DEQ_SUB_TYPE_SHFT 16 +#define WF_PSE_TOP_C_DE_QUEUE_0_SRC_PID_ADDR WF_PSE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_0_SRC_PID_MASK 0x0000C000 /* SRC_PID[15..14] */ +#define WF_PSE_TOP_C_DE_QUEUE_0_SRC_PID_SHFT 14 +#define WF_PSE_TOP_C_DE_QUEUE_0_SRC_WLANID_ADDR WF_PSE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_0_SRC_WLANID_MASK \ +0x000003FF /* SRC_WLANID[9..0] */ +#define WF_PSE_TOP_C_DE_QUEUE_0_SRC_WLANID_SHFT 0 + +/* +* ---C_DE_QUEUE_1 (0x820C8000 + 0x84)--- +* CUR_LIST_FID_START[11..0] - (RW) Start frame ID of dequeue operation +* list, enqueue start FID of enqueue operation +* Only valid in Deq&Enq type. +* RESERVED12[15..12] - (RO) Reserved bits +* CUR_LIST_FID_END[27..16] - (RW) End framd ID of dequeue operation list, +* enqueue end FID of enqueue operation +* Only valid in Deq&Enq type. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_C_DE_QUEUE_1_CUR_LIST_FID_END_ADDR \ +WF_PSE_TOP_C_DE_QUEUE_1_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_1_CUR_LIST_FID_END_MASK \ +0x0FFF0000 /* CUR_LIST_FID_END[27..16] */ +#define WF_PSE_TOP_C_DE_QUEUE_1_CUR_LIST_FID_END_SHFT 16 +#define WF_PSE_TOP_C_DE_QUEUE_1_CUR_LIST_FID_START_ADDR \ +WF_PSE_TOP_C_DE_QUEUE_1_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_1_CUR_LIST_FID_START_MASK \ +0x00000FFF /* CUR_LIST_FID_START[11..0] */ +#define WF_PSE_TOP_C_DE_QUEUE_1_CUR_LIST_FID_START_SHFT 0 + +/* +* ---C_DE_QUEUE_2 (0x820C8000 + 0x88)--- +* DEQ_ENQ_DST_WLANID[9..0] - (RW) Destination WLAN ID for enqueue command +* Only valid in Deq&Enq type. +* RESERVED10[13..10] - (RO) Reserved bits +* DEQ_ENQ_DST_PID[15..14] - (RW) Destination port ID for dequeue command +* RESERVED16[23..16] - (RO) Reserved bits +* DEQ_ENQ_DST_QID[30..24] - (RW) Destination queue ID for enqueue command +* Only valid in Deq&Enq type. +* RESERVED31[31] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_QID_ADDR \ +WF_PSE_TOP_C_DE_QUEUE_2_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_QID_MASK \ +0x7F000000 /* DEQ_ENQ_DST_QID[30..24] */ +#define WF_PSE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_QID_SHFT 24 +#define WF_PSE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_PID_ADDR \ +WF_PSE_TOP_C_DE_QUEUE_2_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_PID_MASK \ +0x0000C000 /* DEQ_ENQ_DST_PID[15..14] */ +#define WF_PSE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_PID_SHFT 14 +#define WF_PSE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_WLANID_ADDR \ +WF_PSE_TOP_C_DE_QUEUE_2_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_WLANID_MASK \ +0x000003FF /* DEQ_ENQ_DST_WLANID[9..0] */ +#define WF_PSE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_WLANID_SHFT 0 + +/* +* ---C_DE_QUEUE_3 (0x820C8000 + 0x8c)--- +* DEQ_HEAD_FDI[11..0] - (RO) Head FID got from dequeue command +* RESERVED12[14..12] - (RO) Reserved bits +* DEQ_EMPTY[15] - (RO) Queue empty after dequeue command is +executed +* DEQ_TAIL_FID[27..16] - (RO) Last FID got from dequeue command +* RESERVED28[30..28] - (RO) Reserved bits +* BUSY[31] - (RO) Dequeue execute busy +*/ +#define WF_PSE_TOP_C_DE_QUEUE_3_BUSY_ADDR WF_PSE_TOP_C_DE_QUEUE_3_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_3_BUSY_MASK 0x80000000 /* BUSY[31] */ +#define WF_PSE_TOP_C_DE_QUEUE_3_BUSY_SHFT 31 +#define WF_PSE_TOP_C_DE_QUEUE_3_DEQ_TAIL_FID_ADDR WF_PSE_TOP_C_DE_QUEUE_3_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_3_DEQ_TAIL_FID_MASK \ +0x0FFF0000 /* DEQ_TAIL_FID[27..16] */ +#define WF_PSE_TOP_C_DE_QUEUE_3_DEQ_TAIL_FID_SHFT 16 +#define WF_PSE_TOP_C_DE_QUEUE_3_DEQ_EMPTY_ADDR WF_PSE_TOP_C_DE_QUEUE_3_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_3_DEQ_EMPTY_MASK 0x00008000 /* DEQ_EMPTY[15] */ +#define WF_PSE_TOP_C_DE_QUEUE_3_DEQ_EMPTY_SHFT 15 +#define WF_PSE_TOP_C_DE_QUEUE_3_DEQ_HEAD_FDI_ADDR WF_PSE_TOP_C_DE_QUEUE_3_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_3_DEQ_HEAD_FDI_MASK \ +0x00000FFF /* DEQ_HEAD_FDI[11..0] */ +#define WF_PSE_TOP_C_DE_QUEUE_3_DEQ_HEAD_FDI_SHFT 0 + +/* +* ---C_DE_QUEUE_4 (0x820C8000 + 0x90)--- +* DEQ_ENQ_REF_FID[11..0] - (RW) Reference frame ID for enqueue command +* Only valid in Deq&Enq type. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_C_DE_QUEUE_4_DEQ_ENQ_REF_FID_ADDR \ +WF_PSE_TOP_C_DE_QUEUE_4_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_4_DEQ_ENQ_REF_FID_MASK \ +0x00000FFF /* DEQ_ENQ_REF_FID[11..0] */ +#define WF_PSE_TOP_C_DE_QUEUE_4_DEQ_ENQ_REF_FID_SHFT 0 + +/* +* ---ALLOCATE_0 (0x820C8000 + 0xA0)--- +* ALLOCATE_FRAME_LENGTH[13..0] - (RW) Allocate frame length +* Unit: DW (4 bytes) +* RESERVED14[15..14] - (RO) Reserved bits +* ALLOCATE_QID[20..16] - (RW) QID used for allocate buffer +* RESERVED21[30..21] - (RO) Reserved bits +* EXECUTE[31] - (A0) Executes allocate buffer command +*/ +#define WF_PSE_TOP_ALLOCATE_0_EXECUTE_ADDR WF_PSE_TOP_ALLOCATE_0_ADDR +#define WF_PSE_TOP_ALLOCATE_0_EXECUTE_MASK 0x80000000 /* EXECUTE[31] */ +#define WF_PSE_TOP_ALLOCATE_0_EXECUTE_SHFT 31 +#define WF_PSE_TOP_ALLOCATE_0_ALLOCATE_QID_ADDR WF_PSE_TOP_ALLOCATE_0_ADDR +#define WF_PSE_TOP_ALLOCATE_0_ALLOCATE_QID_MASK \ +0x001F0000 /* ALLOCATE_QID[20..16] */ +#define WF_PSE_TOP_ALLOCATE_0_ALLOCATE_QID_SHFT 16 +#define WF_PSE_TOP_ALLOCATE_0_ALLOCATE_FRAME_LENGTH_ADDR \ +WF_PSE_TOP_ALLOCATE_0_ADDR +#define WF_PSE_TOP_ALLOCATE_0_ALLOCATE_FRAME_LENGTH_MASK \ +0x00003FFF /* ALLOCATE_FRAME_LENGTH[13..0] */ +#define WF_PSE_TOP_ALLOCATE_0_ALLOCATE_FRAME_LENGTH_SHFT 0 + +/* +* ---ALLOCATE_1 (0x820C8000 + 0xA4)--- +* ALLOCATE_FID[11..0] - (RO) Return frame ID for allocate buffer +command +* RESERVED12[30..12] - (RO) Reserved bits +* EXECUTE[31] - (RO) Execute status of allocate buffer +command +*/ +#define WF_PSE_TOP_ALLOCATE_1_EXECUTE_ADDR WF_PSE_TOP_ALLOCATE_1_ADDR +#define WF_PSE_TOP_ALLOCATE_1_EXECUTE_MASK 0x80000000 /* EXECUTE[31] */ +#define WF_PSE_TOP_ALLOCATE_1_EXECUTE_SHFT 31 +#define WF_PSE_TOP_ALLOCATE_1_ALLOCATE_FID_ADDR WF_PSE_TOP_ALLOCATE_1_ADDR +#define WF_PSE_TOP_ALLOCATE_1_ALLOCATE_FID_MASK \ +0x00000FFF /* ALLOCATE_FID[11..0] */ +#define WF_PSE_TOP_ALLOCATE_1_ALLOCATE_FID_SHFT 0 + +/* +* ---QUEUE_EMPTY (0x820C8000 + 0xB0)--- +* CPU_Q0_EMPTY[0] - (RO) CPU queue 0 empty status +* CPU_Q1_EMPTY[1] - (RO) CPU queue 1 empty status +* CPU_Q2_EMPTY[2] - (RO) CPU queue 2 empty status +* CPU_Q3_EMPTY[3] - (RO) CPU queue 3 empty status +* HIF_8_EMPTY[4] - (RO) HIF queue 8 empty status +* HIF_9_EMPTY[5] - (RO) HIF queue 9 empty status +* HIF_10_EMPTY[6] - (RO) HIF queue 10 empty status +* HIF_11_EMPTY[7] - (RO) HIF queue 11 empty status +* HIF_0_EMPTY[8] - (RO) HIF queue 0 empty status +* HIF_1_EMPTY[9] - (RO) HIF queue 1 empty status +* HIF_2_EMPTY[10] - (RO) HIF queue 2 empty status +* HIF_3_EMPTY[11] - (RO) HIF queue 3 empty status +* HIF_4_EMPTY[12] - (RO) HIF queue 4 empty status +* HIF_5_EMPTY[13] - (RO) HIF queue 5 empty status +* HIF_6_EMPTY[14] - (RO) HIF queue 6 empty status +* HIF_7_EMPTY[15] - (RO) HIF queue 7 empty status +* LMAC_TX_QUEUE_EMPTY[16] - (RO) LMAC TX queue empty status +* MDP_TX_QUEUE_EMPTY[17] - (RO) MDP TX queue empty status +* MDP_RX_QUEUE_EMPTY[18] - (RO) MDP RX queue empty status +* SEC_TX_QUEUE_EMPTY[19] - (RO) SEC TX queue empty status +* SEC_RX_QUEUE_EMPTY[20] - (RO) SEC RX queue empty status +* SFD_PARK_QUEUE_EMPTY[21] - (RO) SFD PARK queue empty status +* MDP_TXIOC_QUEUE_EMPTY[22] - (RO) MDP TXIOC queue empty status +* MDP_RXIOC_QUEUE_EMPTY[23] - (RO) MDP RXIOC queue empty status +* MDP_TX1_QUEUE_EMPTY[24] - (RO) MDP TX queue empty status for Band 1 +* SEC_TX1_QUEUE_EMPTY[25] - (RO) SEC TX queue empty status for Band 1 +* MDP_TXIOC1_QUEUE_EMPTY[26] - (RO) MDP TXIOC queue empty status for Band 1 +* MDP_RXIOC1_QUEUE_EMPTY[27] - (RO) MDP RXIOC queue empty status for Band 1 +* RESERVED28[30..28] - (RO) Reserved bits +* RLS_Q_EMTPY[31] - (RO) Release queue empty status +*/ +#define WF_PSE_TOP_QUEUE_EMPTY_RLS_Q_EMTPY_ADDR WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_RLS_Q_EMTPY_MASK 0x80000000 /* RLS_Q_EMTPY[31]\ + */ +#define WF_PSE_TOP_QUEUE_EMPTY_RLS_Q_EMTPY_SHFT 31 +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_RXIOC1_QUEUE_EMPTY_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_RXIOC1_QUEUE_EMPTY_MASK \ +0x08000000 /* MDP_RXIOC1_QUEUE_EMPTY[27] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_RXIOC1_QUEUE_EMPTY_SHFT 27 +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_TXIOC1_QUEUE_EMPTY_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_TXIOC1_QUEUE_EMPTY_MASK \ +0x04000000 /* MDP_TXIOC1_QUEUE_EMPTY[26] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_TXIOC1_QUEUE_EMPTY_SHFT 26 +#define WF_PSE_TOP_QUEUE_EMPTY_SEC_TX1_QUEUE_EMPTY_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_SEC_TX1_QUEUE_EMPTY_MASK \ +0x02000000 /* SEC_TX1_QUEUE_EMPTY[25] */ +#define WF_PSE_TOP_QUEUE_EMPTY_SEC_TX1_QUEUE_EMPTY_SHFT 25 +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_TX1_QUEUE_EMPTY_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_TX1_QUEUE_EMPTY_MASK \ +0x01000000 /* MDP_TX1_QUEUE_EMPTY[24] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_TX1_QUEUE_EMPTY_SHFT 24 +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_RXIOC_QUEUE_EMPTY_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_RXIOC_QUEUE_EMPTY_MASK \ +0x00800000 /* MDP_RXIOC_QUEUE_EMPTY[23] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_RXIOC_QUEUE_EMPTY_SHFT 23 +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_TXIOC_QUEUE_EMPTY_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_TXIOC_QUEUE_EMPTY_MASK \ +0x00400000 /* MDP_TXIOC_QUEUE_EMPTY[22] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_TXIOC_QUEUE_EMPTY_SHFT 22 +#define WF_PSE_TOP_QUEUE_EMPTY_SFD_PARK_QUEUE_EMPTY_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_SFD_PARK_QUEUE_EMPTY_MASK \ +0x00200000 /* SFD_PARK_QUEUE_EMPTY[21] */ +#define WF_PSE_TOP_QUEUE_EMPTY_SFD_PARK_QUEUE_EMPTY_SHFT 21 +#define WF_PSE_TOP_QUEUE_EMPTY_SEC_RX_QUEUE_EMPTY_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_SEC_RX_QUEUE_EMPTY_MASK \ +0x00100000 /* SEC_RX_QUEUE_EMPTY[20] */ +#define WF_PSE_TOP_QUEUE_EMPTY_SEC_RX_QUEUE_EMPTY_SHFT 20 +#define WF_PSE_TOP_QUEUE_EMPTY_SEC_TX_QUEUE_EMPTY_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_SEC_TX_QUEUE_EMPTY_MASK \ +0x00080000 /* SEC_TX_QUEUE_EMPTY[19] */ +#define WF_PSE_TOP_QUEUE_EMPTY_SEC_TX_QUEUE_EMPTY_SHFT 19 +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_RX_QUEUE_EMPTY_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_RX_QUEUE_EMPTY_MASK \ +0x00040000 /* MDP_RX_QUEUE_EMPTY[18] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_RX_QUEUE_EMPTY_SHFT 18 +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_TX_QUEUE_EMPTY_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_TX_QUEUE_EMPTY_MASK \ +0x00020000 /* MDP_TX_QUEUE_EMPTY[17] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_TX_QUEUE_EMPTY_SHFT 17 +#define WF_PSE_TOP_QUEUE_EMPTY_LMAC_TX_QUEUE_EMPTY_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_LMAC_TX_QUEUE_EMPTY_MASK \ +0x00010000 /* LMAC_TX_QUEUE_EMPTY[16] */ +#define WF_PSE_TOP_QUEUE_EMPTY_LMAC_TX_QUEUE_EMPTY_SHFT 16 +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_7_EMPTY_ADDR WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_7_EMPTY_MASK 0x00008000 /* HIF_7_EMPTY[15]*/ +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_7_EMPTY_SHFT 15 +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_6_EMPTY_ADDR WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_6_EMPTY_MASK 0x00004000 /* HIF_6_EMPTY[14]*/ +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_6_EMPTY_SHFT 14 +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_5_EMPTY_ADDR WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_5_EMPTY_MASK 0x00002000 /* HIF_5_EMPTY[13]*/ +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_5_EMPTY_SHFT 13 +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_4_EMPTY_ADDR WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_4_EMPTY_MASK 0x00001000 /* HIF_4_EMPTY[12]*/ +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_4_EMPTY_SHFT 12 +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_3_EMPTY_ADDR WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_3_EMPTY_MASK 0x00000800 /* HIF_3_EMPTY[11]*/ +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_3_EMPTY_SHFT 11 +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_2_EMPTY_ADDR WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_2_EMPTY_MASK 0x00000400 /* HIF_2_EMPTY[10]*/ +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_2_EMPTY_SHFT 10 +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_1_EMPTY_ADDR WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_1_EMPTY_MASK 0x00000200 /* HIF_1_EMPTY[9]*/ +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_1_EMPTY_SHFT 9 +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_0_EMPTY_ADDR WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_0_EMPTY_MASK 0x00000100 /* HIF_0_EMPTY[8]*/ +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_0_EMPTY_SHFT 8 +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_11_EMPTY_ADDR WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_11_EMPTY_MASK \ +0x00000080 /* HIF_11_EMPTY[7] */ +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_11_EMPTY_SHFT 7 +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_10_EMPTY_ADDR WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_10_EMPTY_MASK \ +0x00000040 /* HIF_10_EMPTY[6] */ +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_10_EMPTY_SHFT 6 +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_9_EMPTY_ADDR WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_9_EMPTY_MASK 0x00000020 /* HIF_9_EMPTY[5] \ + */ +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_9_EMPTY_SHFT 5 +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_8_EMPTY_ADDR WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_8_EMPTY_MASK 0x00000010 /* HIF_8_EMPTY[4] \ + */ +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_8_EMPTY_SHFT 4 +#define WF_PSE_TOP_QUEUE_EMPTY_CPU_Q3_EMPTY_ADDR WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_CPU_Q3_EMPTY_MASK \ +0x00000008 /* CPU_Q3_EMPTY[3] */ +#define WF_PSE_TOP_QUEUE_EMPTY_CPU_Q3_EMPTY_SHFT 3 +#define WF_PSE_TOP_QUEUE_EMPTY_CPU_Q2_EMPTY_ADDR WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_CPU_Q2_EMPTY_MASK \ +0x00000004 /* CPU_Q2_EMPTY[2] */ +#define WF_PSE_TOP_QUEUE_EMPTY_CPU_Q2_EMPTY_SHFT 2 +#define WF_PSE_TOP_QUEUE_EMPTY_CPU_Q1_EMPTY_ADDR WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_CPU_Q1_EMPTY_MASK \ +0x00000002 /* CPU_Q1_EMPTY[1] */ +#define WF_PSE_TOP_QUEUE_EMPTY_CPU_Q1_EMPTY_SHFT 1 +#define WF_PSE_TOP_QUEUE_EMPTY_CPU_Q0_EMPTY_ADDR WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_CPU_Q0_EMPTY_MASK \ +0x00000001 /* CPU_Q0_EMPTY[0] */ +#define WF_PSE_TOP_QUEUE_EMPTY_CPU_Q0_EMPTY_SHFT 0 + +/* +* ---QUEUE_EMPTY_MASK (0x820C8000 + 0xB4)--- +* RESERVED0[7..0] - (RO) Reserved bits +* HIF_0_EMPTY_MASK[8] - (RW) Mask control of HIF queue 0 empty status +* HIF_1_EMPTY_MASK[9] - (RW) Mask control of HIF queue 1 empty status +* HIF_2_EMPTY_MASK[10] - (RW) Mask control of HIF queue 2 empty status +* HIF_3_EMPTY_MASK[11] - (RW) Mask control of HIF queue 3 empty status +* HIF_4_EMPTY_MASK[12] - (RW) Mask control of HIF queue 4 empty status +* HIF_5_EMPTY_MASK[13] - (RW) Mask control of HIF queue 5 empty status +* HIF_6_EMPTY_MASK[14] - (RW) Mask control of HIF queue 6 empty status +* HIF_7_EMPTY_MASK[15] - (RW) Mask control of HIF queue 7 empty status +* HIF_8_EMPTY_MASK[16] - (RW) Mask control of HIF queue 8 empty status +* HIF_9_EMPTY_MASK[17] - (RW) Mask control of HIF queue 9 empty status +* HIF_10_EMPTY_MASK[18] - (RW) Mask control of HIF queue 10 empty +status +* HIF_11_EMPTY_MASK[19] - (RW) Mask control of HIF queue 11 empty +status +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_11_EMPTY_MASK_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_MASK_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_11_EMPTY_MASK_MASK \ +0x00080000 /* HIF_11_EMPTY_MASK[19] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_11_EMPTY_MASK_SHFT 19 +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_10_EMPTY_MASK_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_MASK_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_10_EMPTY_MASK_MASK \ +0x00040000 /* HIF_10_EMPTY_MASK[18] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_10_EMPTY_MASK_SHFT 18 +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_9_EMPTY_MASK_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_MASK_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_9_EMPTY_MASK_MASK \ +0x00020000 /* HIF_9_EMPTY_MASK[17] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_9_EMPTY_MASK_SHFT 17 +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_8_EMPTY_MASK_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_MASK_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_8_EMPTY_MASK_MASK \ +0x00010000 /* HIF_8_EMPTY_MASK[16] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_8_EMPTY_MASK_SHFT 16 +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_7_EMPTY_MASK_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_MASK_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_7_EMPTY_MASK_MASK \ +0x00008000 /* HIF_7_EMPTY_MASK[15] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_7_EMPTY_MASK_SHFT 15 +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_6_EMPTY_MASK_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_MASK_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_6_EMPTY_MASK_MASK \ +0x00004000 /* HIF_6_EMPTY_MASK[14] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_6_EMPTY_MASK_SHFT 14 +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_5_EMPTY_MASK_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_MASK_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_5_EMPTY_MASK_MASK \ +0x00002000 /* HIF_5_EMPTY_MASK[13] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_5_EMPTY_MASK_SHFT 13 +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_4_EMPTY_MASK_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_MASK_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_4_EMPTY_MASK_MASK \ +0x00001000 /* HIF_4_EMPTY_MASK[12] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_4_EMPTY_MASK_SHFT 12 +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_3_EMPTY_MASK_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_MASK_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_3_EMPTY_MASK_MASK \ +0x00000800 /* HIF_3_EMPTY_MASK[11] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_3_EMPTY_MASK_SHFT 11 +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_2_EMPTY_MASK_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_MASK_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_2_EMPTY_MASK_MASK \ +0x00000400 /* HIF_2_EMPTY_MASK[10] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_2_EMPTY_MASK_SHFT 10 +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_1_EMPTY_MASK_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_MASK_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_1_EMPTY_MASK_MASK \ +0x00000200 /* HIF_1_EMPTY_MASK[9] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_1_EMPTY_MASK_SHFT 9 +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_0_EMPTY_MASK_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_MASK_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_0_EMPTY_MASK_MASK \ +0x00000100 /* HIF_0_EMPTY_MASK[8] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_0_EMPTY_MASK_SHFT 8 + +/* +* ---FREEPG_START_END (0x820C8000 + 0xC0)--- +* FREEPG_START[11..0] - (RW) Start page setting of free pages +* RESERVED12[15..12] - (RO) Reserved bits +* FREEPG_END[27..16] - (RW) End page setting of free page +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_FREEPG_START_END_FREEPG_END_ADDR \ +WF_PSE_TOP_FREEPG_START_END_ADDR +#define WF_PSE_TOP_FREEPG_START_END_FREEPG_END_MASK \ +0x0FFF0000 /* FREEPG_END[27..16] */ +#define WF_PSE_TOP_FREEPG_START_END_FREEPG_END_SHFT 16 +#define WF_PSE_TOP_FREEPG_START_END_FREEPG_START_ADDR \ +WF_PSE_TOP_FREEPG_START_END_ADDR +#define WF_PSE_TOP_FREEPG_START_END_FREEPG_START_MASK \ +0x00000FFF /* FREEPG_START[11..0] */ +#define WF_PSE_TOP_FREEPG_START_END_FREEPG_START_SHFT 0 + +/* +* ---PSE_MODULE_CKG_DIS (0x820C8000 + 0xc4)--- +* DIS_FL_DYN_CKG[0] - (RW) Disable control of PSE frame link module +* dynamic clock gating function +* DIS_PL_DYN_CKG[1] - (RW) Disable control of PSE page link module +* dynamic clock gating function +* DIS_CPU_PORT_DYN_CKG[2] - (RW) Disable control of PSE CPU port module +* dynamic clock gating function +* DIS_HIF_PORT_DYN_CKG[3] - (RW) Disable control of PSE HIF port module +* dynamic clock gating function +* DIS_WF_PLE_PORT_DYN_CKG[4] - (RW) Disable control of PSE LMAC and PLE port +* module dynamic clock gating function +* DIS_RLS_DYN_CKG[5] - (RW) Disable control of PSE release module +* dynamic clock gating function +* DIS_RL_DYN_CKG[6] - (RW) Disable control of PSE relay information +* module dynamic clock gating function +* RESERVED7[8..7] - (RO) Reserved bits +* DIS_CSR_DYN_CKG[9] - (RW) Disable control of PSE CR module dynamic +* clock gating function +* DIS_CPU_WRAP_DYN_CKG[10] - (RW) Disable control of PSE CPU_WRAP module +* dynamic clock gating function +* DIS_DBG_DYN_CKG[11] - (RW) Disable control of PSE debug module +* dynamic clock gating function +* DIS_MDP_DYN_CKG[12] - (RW) Disable control of PSE MDP module +* dynamic clock gating function +* DIS_SEC_DYN_CKG[13] - (RW) Disable control of PSE SEC module +* dynamic clock gating function +* RESERVED14[31..14] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_SEC_DYN_CKG_ADDR \ +WF_PSE_TOP_PSE_MODULE_CKG_DIS_ADDR +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_SEC_DYN_CKG_MASK \ +0x00002000 /* DIS_SEC_DYN_CKG[13] */ +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_SEC_DYN_CKG_SHFT 13 +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_MDP_DYN_CKG_ADDR \ +WF_PSE_TOP_PSE_MODULE_CKG_DIS_ADDR +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_MDP_DYN_CKG_MASK \ +0x00001000 /* DIS_MDP_DYN_CKG[12] */ +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_MDP_DYN_CKG_SHFT 12 +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_DBG_DYN_CKG_ADDR \ +WF_PSE_TOP_PSE_MODULE_CKG_DIS_ADDR +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_DBG_DYN_CKG_MASK \ +0x00000800 /* DIS_DBG_DYN_CKG[11] */ +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_DBG_DYN_CKG_SHFT 11 +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_CPU_WRAP_DYN_CKG_ADDR \ +WF_PSE_TOP_PSE_MODULE_CKG_DIS_ADDR +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_CPU_WRAP_DYN_CKG_MASK \ +0x00000400 /* DIS_CPU_WRAP_DYN_CKG[10] */ +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_CPU_WRAP_DYN_CKG_SHFT 10 +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_CSR_DYN_CKG_ADDR \ +WF_PSE_TOP_PSE_MODULE_CKG_DIS_ADDR +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_CSR_DYN_CKG_MASK \ +0x00000200 /* DIS_CSR_DYN_CKG[9] */ +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_CSR_DYN_CKG_SHFT 9 +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_RL_DYN_CKG_ADDR \ +WF_PSE_TOP_PSE_MODULE_CKG_DIS_ADDR +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_RL_DYN_CKG_MASK \ +0x00000040 /* DIS_RL_DYN_CKG[6] */ +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_RL_DYN_CKG_SHFT 6 +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_RLS_DYN_CKG_ADDR \ +WF_PSE_TOP_PSE_MODULE_CKG_DIS_ADDR +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_RLS_DYN_CKG_MASK \ +0x00000020 /* DIS_RLS_DYN_CKG[5] */ +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_RLS_DYN_CKG_SHFT 5 +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_WF_PLE_PORT_DYN_CKG_ADDR \ +WF_PSE_TOP_PSE_MODULE_CKG_DIS_ADDR +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_WF_PLE_PORT_DYN_CKG_MASK \ +0x00000010 /* DIS_WF_PLE_PORT_DYN_CKG[4] */ +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_WF_PLE_PORT_DYN_CKG_SHFT 4 +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_HIF_PORT_DYN_CKG_ADDR \ +WF_PSE_TOP_PSE_MODULE_CKG_DIS_ADDR +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_HIF_PORT_DYN_CKG_MASK \ +0x00000008 /* DIS_HIF_PORT_DYN_CKG[3] */ +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_HIF_PORT_DYN_CKG_SHFT 3 +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_CPU_PORT_DYN_CKG_ADDR \ +WF_PSE_TOP_PSE_MODULE_CKG_DIS_ADDR +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_CPU_PORT_DYN_CKG_MASK \ +0x00000004 /* DIS_CPU_PORT_DYN_CKG[2] */ +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_CPU_PORT_DYN_CKG_SHFT 2 +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_PL_DYN_CKG_ADDR \ +WF_PSE_TOP_PSE_MODULE_CKG_DIS_ADDR +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_PL_DYN_CKG_MASK \ +0x00000002 /* DIS_PL_DYN_CKG[1] */ +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_PL_DYN_CKG_SHFT 1 +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_FL_DYN_CKG_ADDR \ +WF_PSE_TOP_PSE_MODULE_CKG_DIS_ADDR +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_FL_DYN_CKG_MASK \ +0x00000001 /* DIS_FL_DYN_CKG[0] */ +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_FL_DYN_CKG_SHFT 0 + +/* +* ---TO_N9_INT (0x820C8000 + 0xf0)--- +* CR4_CMD[30..0] - (RW) Command for N9 +* TOGGLE[31] - (RW) When this bit is toggled, HW will send +* interrupt to N9. +*/ +#define WF_PSE_TOP_TO_N9_INT_TOGGLE_ADDR WF_PSE_TOP_TO_N9_INT_ADDR +#define WF_PSE_TOP_TO_N9_INT_TOGGLE_MASK 0x80000000 /* TOGGLE[31] */ +#define WF_PSE_TOP_TO_N9_INT_TOGGLE_SHFT 31 +#define WF_PSE_TOP_TO_N9_INT_CR4_CMD_ADDR WF_PSE_TOP_TO_N9_INT_ADDR +#define WF_PSE_TOP_TO_N9_INT_CR4_CMD_MASK 0x7FFFFFFF /* CR4_CMD[30..0] */ +#define WF_PSE_TOP_TO_N9_INT_CR4_CMD_SHFT 0 + +/* +* ---FREEPG_CNT (0x820C8000 + 0x100)--- +* FREEPG_CNT[11..0] - (RO) Total page number of free +* RESERVED12[15..12] - (RO) Reserved bits +* FFA_CNT[27..16] - (RO) Free page numbers of free for all +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_FREEPG_CNT_FFA_CNT_ADDR WF_PSE_TOP_FREEPG_CNT_ADDR +#define WF_PSE_TOP_FREEPG_CNT_FFA_CNT_MASK 0x0FFF0000 /* FFA_CNT[27..16] */ +#define WF_PSE_TOP_FREEPG_CNT_FFA_CNT_SHFT 16 +#define WF_PSE_TOP_FREEPG_CNT_FREEPG_CNT_ADDR WF_PSE_TOP_FREEPG_CNT_ADDR +#define WF_PSE_TOP_FREEPG_CNT_FREEPG_CNT_MASK 0x00000FFF /* FREEPG_CNT[11..0]\ + */ +#define WF_PSE_TOP_FREEPG_CNT_FREEPG_CNT_SHFT 0 + +/* +* ---FREEPG_HEAD_TAIL (0x820C8000 + 0x104)--- +* FREEPG_HEAD[11..0] - (RO) Head page of free page list +* RESERVED12[15..12] - (RO) Reserved bits +* FREEPG_TAIL[27..16] - (RO) Tail page of free page list +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_FREEPG_HEAD_TAIL_FREEPG_TAIL_ADDR \ +WF_PSE_TOP_FREEPG_HEAD_TAIL_ADDR +#define WF_PSE_TOP_FREEPG_HEAD_TAIL_FREEPG_TAIL_MASK \ +0x0FFF0000 /* FREEPG_TAIL[27..16] */ +#define WF_PSE_TOP_FREEPG_HEAD_TAIL_FREEPG_TAIL_SHFT 16 +#define WF_PSE_TOP_FREEPG_HEAD_TAIL_FREEPG_HEAD_ADDR \ +WF_PSE_TOP_FREEPG_HEAD_TAIL_ADDR +#define WF_PSE_TOP_FREEPG_HEAD_TAIL_FREEPG_HEAD_MASK \ +0x00000FFF /* FREEPG_HEAD[11..0] */ +#define WF_PSE_TOP_FREEPG_HEAD_TAIL_FREEPG_HEAD_SHFT 0 + +/* +* ---GROUP_REFILL_CTRL (0x820C8000 + 0x108)--- +* GROUP_REFILL_PRI[8..0] - (RW) group refill priority control +* RESERVED9[15..9] - (RO) Reserved bits +* DIS_GROUP_REFILL[24..16] - (RW) group quota refill enable control +* RESERVED25[31..25] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_GROUP_REFILL_CTRL_DIS_GROUP_REFILL_ADDR \ +WF_PSE_TOP_GROUP_REFILL_CTRL_ADDR +#define WF_PSE_TOP_GROUP_REFILL_CTRL_DIS_GROUP_REFILL_MASK \ +0x01FF0000 /* DIS_GROUP_REFILL[24..16] */ +#define WF_PSE_TOP_GROUP_REFILL_CTRL_DIS_GROUP_REFILL_SHFT 16 +#define WF_PSE_TOP_GROUP_REFILL_CTRL_GROUP_REFILL_PRI_ADDR \ +WF_PSE_TOP_GROUP_REFILL_CTRL_ADDR +#define WF_PSE_TOP_GROUP_REFILL_CTRL_GROUP_REFILL_PRI_MASK \ +0x000001FF /* GROUP_REFILL_PRI[8..0] */ +#define WF_PSE_TOP_GROUP_REFILL_CTRL_GROUP_REFILL_PRI_SHFT 0 + +/* +* ---PG_HIF0_GROUP (0x820C8000 + 0x110)--- +* HIF0_MIN_QUOTA[11..0] - (RW) Min. quota of HIF 0 group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED12[15..12] - (RO) Reserved bits +* HIF0_MAX_QUOTA[27..16] - (RW) Max. quota of HIF 0 group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PG_HIF0_GROUP_HIF0_MAX_QUOTA_ADDR \ +WF_PSE_TOP_PG_HIF0_GROUP_ADDR +#define WF_PSE_TOP_PG_HIF0_GROUP_HIF0_MAX_QUOTA_MASK \ +0x0FFF0000 /* HIF0_MAX_QUOTA[27..16] */ +#define WF_PSE_TOP_PG_HIF0_GROUP_HIF0_MAX_QUOTA_SHFT 16 +#define WF_PSE_TOP_PG_HIF0_GROUP_HIF0_MIN_QUOTA_ADDR \ +WF_PSE_TOP_PG_HIF0_GROUP_ADDR +#define WF_PSE_TOP_PG_HIF0_GROUP_HIF0_MIN_QUOTA_MASK \ +0x00000FFF /* HIF0_MIN_QUOTA[11..0] */ +#define WF_PSE_TOP_PG_HIF0_GROUP_HIF0_MIN_QUOTA_SHFT 0 + +/* +* ---HIF0_PG_INFO (0x820C8000 + 0x114)--- +* HIF0_RSV_CNT[11..0] - (RO) Reserved pages of HIF 0 group +* RESERVED12[15..12] - (RO) Reserved bits +* HIF0_SRC_CNT[27..16] - (RO) Used pages of HIF 0 group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_HIF0_PG_INFO_HIF0_SRC_CNT_ADDR WF_PSE_TOP_HIF0_PG_INFO_ADDR +#define WF_PSE_TOP_HIF0_PG_INFO_HIF0_SRC_CNT_MASK \ +0x0FFF0000 /* HIF0_SRC_CNT[27..16] */ +#define WF_PSE_TOP_HIF0_PG_INFO_HIF0_SRC_CNT_SHFT 16 +#define WF_PSE_TOP_HIF0_PG_INFO_HIF0_RSV_CNT_ADDR WF_PSE_TOP_HIF0_PG_INFO_ADDR +#define WF_PSE_TOP_HIF0_PG_INFO_HIF0_RSV_CNT_MASK \ +0x00000FFF /* HIF0_RSV_CNT[11..0] */ +#define WF_PSE_TOP_HIF0_PG_INFO_HIF0_RSV_CNT_SHFT 0 + +/* +* ---PG_HIF1_GROUP (0x820C8000 + 0x118)--- +* HIF1_MIN_QUOTA[11..0] - (RW) Min. quota of HIF 1 group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED12[15..12] - (RO) Reserved bits +* HIF1_MAX_QUOTA[27..16] - (RW) Max. quota of HIF 1 group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PG_HIF1_GROUP_HIF1_MAX_QUOTA_ADDR \ +WF_PSE_TOP_PG_HIF1_GROUP_ADDR +#define WF_PSE_TOP_PG_HIF1_GROUP_HIF1_MAX_QUOTA_MASK \ +0x0FFF0000 /* HIF1_MAX_QUOTA[27..16] */ +#define WF_PSE_TOP_PG_HIF1_GROUP_HIF1_MAX_QUOTA_SHFT 16 +#define WF_PSE_TOP_PG_HIF1_GROUP_HIF1_MIN_QUOTA_ADDR \ +WF_PSE_TOP_PG_HIF1_GROUP_ADDR +#define WF_PSE_TOP_PG_HIF1_GROUP_HIF1_MIN_QUOTA_MASK \ +0x00000FFF /* HIF1_MIN_QUOTA[11..0] */ +#define WF_PSE_TOP_PG_HIF1_GROUP_HIF1_MIN_QUOTA_SHFT 0 + +/* +* ---HIF1_PG_INFO (0x820C8000 + 0x11C)--- +* HIF1_RSV_CNT[11..0] - (RO) Reserved pages of HIF 1 group +* RESERVED12[15..12] - (RO) Reserved bits +* HIF1_SRC_CNT[27..16] - (RO) Used pages of HIF 1 group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_HIF1_PG_INFO_HIF1_SRC_CNT_ADDR WF_PSE_TOP_HIF1_PG_INFO_ADDR +#define WF_PSE_TOP_HIF1_PG_INFO_HIF1_SRC_CNT_MASK \ +0x0FFF0000 /* HIF1_SRC_CNT[27..16] */ +#define WF_PSE_TOP_HIF1_PG_INFO_HIF1_SRC_CNT_SHFT 16 +#define WF_PSE_TOP_HIF1_PG_INFO_HIF1_RSV_CNT_ADDR WF_PSE_TOP_HIF1_PG_INFO_ADDR +#define WF_PSE_TOP_HIF1_PG_INFO_HIF1_RSV_CNT_MASK \ +0x00000FFF /* HIF1_RSV_CNT[11..0] */ +#define WF_PSE_TOP_HIF1_PG_INFO_HIF1_RSV_CNT_SHFT 0 + +/* +* ---PG_CPU_GROUP (0x820C8000 + 0x150)--- +* CPU_MIN_QUOTA[11..0] - (RW) Min. quota of CPU group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED12[15..12] - (RO) Reserved bits +* CPU_MAX_QUOTA[27..16] - (RW) Max. quota of CPU group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PG_CPU_GROUP_CPU_MAX_QUOTA_ADDR WF_PSE_TOP_PG_CPU_GROUP_ADDR +#define WF_PSE_TOP_PG_CPU_GROUP_CPU_MAX_QUOTA_MASK \ +0x0FFF0000 /* CPU_MAX_QUOTA[27..16] */ +#define WF_PSE_TOP_PG_CPU_GROUP_CPU_MAX_QUOTA_SHFT 16 +#define WF_PSE_TOP_PG_CPU_GROUP_CPU_MIN_QUOTA_ADDR WF_PSE_TOP_PG_CPU_GROUP_ADDR +#define WF_PSE_TOP_PG_CPU_GROUP_CPU_MIN_QUOTA_MASK \ +0x00000FFF /* CPU_MIN_QUOTA[11..0] */ +#define WF_PSE_TOP_PG_CPU_GROUP_CPU_MIN_QUOTA_SHFT 0 + +/* +* ---CPU_PG_INFO (0x820C8000 + 0x154)--- +* CPU_RSV_CNT[11..0] - (RO) Reserved pages of CPU group +* RESERVED12[15..12] - (RO) Reserved bits +* CPU_SRC_CNT[27..16] - (RO) Used pages of CPU group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_CPU_PG_INFO_CPU_SRC_CNT_ADDR WF_PSE_TOP_CPU_PG_INFO_ADDR +#define WF_PSE_TOP_CPU_PG_INFO_CPU_SRC_CNT_MASK \ +0x0FFF0000 /* CPU_SRC_CNT[27..16] */ +#define WF_PSE_TOP_CPU_PG_INFO_CPU_SRC_CNT_SHFT 16 +#define WF_PSE_TOP_CPU_PG_INFO_CPU_RSV_CNT_ADDR WF_PSE_TOP_CPU_PG_INFO_ADDR +#define WF_PSE_TOP_CPU_PG_INFO_CPU_RSV_CNT_MASK \ +0x00000FFF /* CPU_RSV_CNT[11..0] */ +#define WF_PSE_TOP_CPU_PG_INFO_CPU_RSV_CNT_SHFT 0 + +/* +* ---PG_PLE_GROUP (0x820C8000 + 0x160)--- +* PLE_MIN_QUOTA[11..0] - (RW) Min. quota of PLE group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED12[15..12] - (RO) Reserved bits +* PLE_MAX_QUOTA[27..16] - (RW) Max. quota of PLE group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PG_PLE_GROUP_PLE_MAX_QUOTA_ADDR WF_PSE_TOP_PG_PLE_GROUP_ADDR +#define WF_PSE_TOP_PG_PLE_GROUP_PLE_MAX_QUOTA_MASK \ +0x0FFF0000 /* PLE_MAX_QUOTA[27..16] */ +#define WF_PSE_TOP_PG_PLE_GROUP_PLE_MAX_QUOTA_SHFT 16 +#define WF_PSE_TOP_PG_PLE_GROUP_PLE_MIN_QUOTA_ADDR WF_PSE_TOP_PG_PLE_GROUP_ADDR +#define WF_PSE_TOP_PG_PLE_GROUP_PLE_MIN_QUOTA_MASK \ +0x00000FFF /* PLE_MIN_QUOTA[11..0] */ +#define WF_PSE_TOP_PG_PLE_GROUP_PLE_MIN_QUOTA_SHFT 0 + +/* +* ---PLE_PG_INFO (0x820C8000 + 0x164)--- +* PLE_RSV_CNT[11..0] - (RO) Reserved pages of PLE group +* RESERVED12[15..12] - (RO) Reserved bits +* PLE_SRC_CNT[27..16] - (RO) Used pages of PLE group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PLE_PG_INFO_PLE_SRC_CNT_ADDR WF_PSE_TOP_PLE_PG_INFO_ADDR +#define WF_PSE_TOP_PLE_PG_INFO_PLE_SRC_CNT_MASK \ +0x0FFF0000 /* PLE_SRC_CNT[27..16] */ +#define WF_PSE_TOP_PLE_PG_INFO_PLE_SRC_CNT_SHFT 16 +#define WF_PSE_TOP_PLE_PG_INFO_PLE_RSV_CNT_ADDR WF_PSE_TOP_PLE_PG_INFO_ADDR +#define WF_PSE_TOP_PLE_PG_INFO_PLE_RSV_CNT_MASK \ +0x00000FFF /* PLE_RSV_CNT[11..0] */ +#define WF_PSE_TOP_PLE_PG_INFO_PLE_RSV_CNT_SHFT 0 + +/* +* ---PG_PLE1_GROUP (0x820C8000 + 0x168)--- +* PLE_MIN_QUOTA[11..0] - (RW) Min. quota of PLE group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED12[15..12] - (RO) Reserved bits +* PLE_MAX_QUOTA[27..16] - (RW) Max. quota of PLE group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PG_PLE1_GROUP_PLE_MAX_QUOTA_ADDR \ +WF_PSE_TOP_PG_PLE1_GROUP_ADDR +#define WF_PSE_TOP_PG_PLE1_GROUP_PLE_MAX_QUOTA_MASK \ +0x0FFF0000 /* PLE_MAX_QUOTA[27..16] */ +#define WF_PSE_TOP_PG_PLE1_GROUP_PLE_MAX_QUOTA_SHFT 16 +#define WF_PSE_TOP_PG_PLE1_GROUP_PLE_MIN_QUOTA_ADDR \ +WF_PSE_TOP_PG_PLE1_GROUP_ADDR +#define WF_PSE_TOP_PG_PLE1_GROUP_PLE_MIN_QUOTA_MASK \ +0x00000FFF /* PLE_MIN_QUOTA[11..0] */ +#define WF_PSE_TOP_PG_PLE1_GROUP_PLE_MIN_QUOTA_SHFT 0 + +/* +* ---PLE1_PG_INFO (0x820C8000 + 0x16C)--- +* PLE_RSV_CNT[11..0] - (RO) Reserved pages of PLE group +* RESERVED12[15..12] - (RO) Reserved bits +* PLE_SRC_CNT[27..16] - (RO) Used pages of PLE group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PLE1_PG_INFO_PLE_SRC_CNT_ADDR WF_PSE_TOP_PLE1_PG_INFO_ADDR +#define WF_PSE_TOP_PLE1_PG_INFO_PLE_SRC_CNT_MASK \ +0x0FFF0000 /* PLE_SRC_CNT[27..16] */ +#define WF_PSE_TOP_PLE1_PG_INFO_PLE_SRC_CNT_SHFT 16 +#define WF_PSE_TOP_PLE1_PG_INFO_PLE_RSV_CNT_ADDR WF_PSE_TOP_PLE1_PG_INFO_ADDR +#define WF_PSE_TOP_PLE1_PG_INFO_PLE_RSV_CNT_MASK \ +0x00000FFF /* PLE_RSV_CNT[11..0] */ +#define WF_PSE_TOP_PLE1_PG_INFO_PLE_RSV_CNT_SHFT 0 + +/* +* ---PG_LMAC0_GROUP (0x820C8000 + 0x170)--- +* LMAC0_MIN_QUOTA[11..0] - (RW) Min. quota of LMAC 0 group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED12[15..12] - (RO) Reserved bits +* LMAC0_MAX_QUOTA[27..16] - (RW) Max. quota of LMAC 0 group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PG_LMAC0_GROUP_LMAC0_MAX_QUOTA_ADDR \ +WF_PSE_TOP_PG_LMAC0_GROUP_ADDR +#define WF_PSE_TOP_PG_LMAC0_GROUP_LMAC0_MAX_QUOTA_MASK \ +0x0FFF0000 /* LMAC0_MAX_QUOTA[27..16] */ +#define WF_PSE_TOP_PG_LMAC0_GROUP_LMAC0_MAX_QUOTA_SHFT 16 +#define WF_PSE_TOP_PG_LMAC0_GROUP_LMAC0_MIN_QUOTA_ADDR \ +WF_PSE_TOP_PG_LMAC0_GROUP_ADDR +#define WF_PSE_TOP_PG_LMAC0_GROUP_LMAC0_MIN_QUOTA_MASK \ +0x00000FFF /* LMAC0_MIN_QUOTA[11..0] */ +#define WF_PSE_TOP_PG_LMAC0_GROUP_LMAC0_MIN_QUOTA_SHFT 0 + +/* +* ---LMAC0_PG_INFO (0x820C8000 + 0x174)--- +* LMAC0_RSV_CNT[11..0] - (RO) Reserved pages of LMAC 0 group +* RESERVED12[15..12] - (RO) Reserved bits +* LMAC0_SRC_CNT[27..16] - (RO) Used pages of LMAC 0 group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_LMAC0_PG_INFO_LMAC0_SRC_CNT_ADDR \ +WF_PSE_TOP_LMAC0_PG_INFO_ADDR +#define WF_PSE_TOP_LMAC0_PG_INFO_LMAC0_SRC_CNT_MASK \ +0x0FFF0000 /* LMAC0_SRC_CNT[27..16] */ +#define WF_PSE_TOP_LMAC0_PG_INFO_LMAC0_SRC_CNT_SHFT 16 +#define WF_PSE_TOP_LMAC0_PG_INFO_LMAC0_RSV_CNT_ADDR \ +WF_PSE_TOP_LMAC0_PG_INFO_ADDR +#define WF_PSE_TOP_LMAC0_PG_INFO_LMAC0_RSV_CNT_MASK \ +0x00000FFF /* LMAC0_RSV_CNT[11..0] */ +#define WF_PSE_TOP_LMAC0_PG_INFO_LMAC0_RSV_CNT_SHFT 0 + +/* +* ---PG_LMAC1_GROUP (0x820C8000 + 0x178)--- +* LMAC1_MIN_QUOTA[11..0] - (RW) Min. quota of LMAC 1 group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED12[15..12] - (RO) Reserved bits +* LMAC1_MAX_QUOTA[27..16] - (RW) Max. quota of LMAC 1 group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PG_LMAC1_GROUP_LMAC1_MAX_QUOTA_ADDR \ +WF_PSE_TOP_PG_LMAC1_GROUP_ADDR +#define WF_PSE_TOP_PG_LMAC1_GROUP_LMAC1_MAX_QUOTA_MASK \ +0x0FFF0000 /* LMAC1_MAX_QUOTA[27..16] */ +#define WF_PSE_TOP_PG_LMAC1_GROUP_LMAC1_MAX_QUOTA_SHFT 16 +#define WF_PSE_TOP_PG_LMAC1_GROUP_LMAC1_MIN_QUOTA_ADDR \ +WF_PSE_TOP_PG_LMAC1_GROUP_ADDR +#define WF_PSE_TOP_PG_LMAC1_GROUP_LMAC1_MIN_QUOTA_MASK \ +0x00000FFF /* LMAC1_MIN_QUOTA[11..0] */ +#define WF_PSE_TOP_PG_LMAC1_GROUP_LMAC1_MIN_QUOTA_SHFT 0 + +/* +* ---LMAC1_PG_INFO (0x820C8000 + 0x17C)--- +* LMAC1_RSV_CNT[11..0] - (RO) Reserved pages of LMAC 1 group +* RESERVED12[15..12] - (RO) Reserved bits +* LMAC1_SRC_CNT[27..16] - (RO) Used pages of LMAC 1 group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_LMAC1_PG_INFO_LMAC1_SRC_CNT_ADDR \ +WF_PSE_TOP_LMAC1_PG_INFO_ADDR +#define WF_PSE_TOP_LMAC1_PG_INFO_LMAC1_SRC_CNT_MASK \ +0x0FFF0000 /* LMAC1_SRC_CNT[27..16] */ +#define WF_PSE_TOP_LMAC1_PG_INFO_LMAC1_SRC_CNT_SHFT 16 +#define WF_PSE_TOP_LMAC1_PG_INFO_LMAC1_RSV_CNT_ADDR \ +WF_PSE_TOP_LMAC1_PG_INFO_ADDR +#define WF_PSE_TOP_LMAC1_PG_INFO_LMAC1_RSV_CNT_MASK \ +0x00000FFF /* LMAC1_RSV_CNT[11..0] */ +#define WF_PSE_TOP_LMAC1_PG_INFO_LMAC1_RSV_CNT_SHFT 0 + +/* +* ---PG_LMAC2_GROUP (0x820C8000 + 0x180)--- +* LMAC2_MIN_QUOTA[11..0] - (RW) Min. quota of LMAC 2 group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED12[15..12] - (RO) Reserved bits +* LMAC2_MAX_QUOTA[27..16] - (RW) Max. quota of LMAC 2 group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PG_LMAC2_GROUP_LMAC2_MAX_QUOTA_ADDR \ +WF_PSE_TOP_PG_LMAC2_GROUP_ADDR +#define WF_PSE_TOP_PG_LMAC2_GROUP_LMAC2_MAX_QUOTA_MASK \ +0x0FFF0000 /* LMAC2_MAX_QUOTA[27..16] */ +#define WF_PSE_TOP_PG_LMAC2_GROUP_LMAC2_MAX_QUOTA_SHFT 16 +#define WF_PSE_TOP_PG_LMAC2_GROUP_LMAC2_MIN_QUOTA_ADDR \ +WF_PSE_TOP_PG_LMAC2_GROUP_ADDR +#define WF_PSE_TOP_PG_LMAC2_GROUP_LMAC2_MIN_QUOTA_MASK \ +0x00000FFF /* LMAC2_MIN_QUOTA[11..0] */ +#define WF_PSE_TOP_PG_LMAC2_GROUP_LMAC2_MIN_QUOTA_SHFT 0 + +/* +* ---LMAC2_PG_INFO (0x820C8000 + 0x184)--- +* LMAC2_RSV_CNT[11..0] - (RO) Reserved pages of LMAC 2 group +* RESERVED12[15..12] - (RO) Reserved bits +* LMAC2_SRC_CNT[27..16] - (RO) Used pages of LMAC 2 group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_LMAC2_PG_INFO_LMAC2_SRC_CNT_ADDR \ +WF_PSE_TOP_LMAC2_PG_INFO_ADDR +#define WF_PSE_TOP_LMAC2_PG_INFO_LMAC2_SRC_CNT_MASK \ +0x0FFF0000 /* LMAC2_SRC_CNT[27..16] */ +#define WF_PSE_TOP_LMAC2_PG_INFO_LMAC2_SRC_CNT_SHFT 16 +#define WF_PSE_TOP_LMAC2_PG_INFO_LMAC2_RSV_CNT_ADDR \ +WF_PSE_TOP_LMAC2_PG_INFO_ADDR +#define WF_PSE_TOP_LMAC2_PG_INFO_LMAC2_RSV_CNT_MASK \ +0x00000FFF /* LMAC2_RSV_CNT[11..0] */ +#define WF_PSE_TOP_LMAC2_PG_INFO_LMAC2_RSV_CNT_SHFT 0 + +/* +* ---PG_LMAC3_GROUP (0x820C8000 + 0x188)--- +* LMAC3_MIN_QUOTA[11..0] - (RW) Min. quota of LMAC 3 group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED12[15..12] - (RO) Reserved bits +* LMAC3_MAX_QUOTA[27..16] - (RW) Max. quota of LMAC 3 group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PG_LMAC3_GROUP_LMAC3_MAX_QUOTA_ADDR \ +WF_PSE_TOP_PG_LMAC3_GROUP_ADDR +#define WF_PSE_TOP_PG_LMAC3_GROUP_LMAC3_MAX_QUOTA_MASK \ +0x0FFF0000 /* LMAC3_MAX_QUOTA[27..16] */ +#define WF_PSE_TOP_PG_LMAC3_GROUP_LMAC3_MAX_QUOTA_SHFT 16 +#define WF_PSE_TOP_PG_LMAC3_GROUP_LMAC3_MIN_QUOTA_ADDR \ +WF_PSE_TOP_PG_LMAC3_GROUP_ADDR +#define WF_PSE_TOP_PG_LMAC3_GROUP_LMAC3_MIN_QUOTA_MASK \ +0x00000FFF /* LMAC3_MIN_QUOTA[11..0] */ +#define WF_PSE_TOP_PG_LMAC3_GROUP_LMAC3_MIN_QUOTA_SHFT 0 + +/* +* ---LMAC3_PG_INFO (0x820C8000 + 0x18C)--- +* LMAC3_RSV_CNT[11..0] - (RO) Reserved pages of LMAC 3 group +* RESERVED12[15..12] - (RO) Reserved bits +* LMAC3_SRC_CNT[27..16] - (RO) Used pages of LMAC 3 group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_LMAC3_PG_INFO_LMAC3_SRC_CNT_ADDR \ +WF_PSE_TOP_LMAC3_PG_INFO_ADDR +#define WF_PSE_TOP_LMAC3_PG_INFO_LMAC3_SRC_CNT_MASK \ +0x0FFF0000 /* LMAC3_SRC_CNT[27..16] */ +#define WF_PSE_TOP_LMAC3_PG_INFO_LMAC3_SRC_CNT_SHFT 16 +#define WF_PSE_TOP_LMAC3_PG_INFO_LMAC3_RSV_CNT_ADDR \ +WF_PSE_TOP_LMAC3_PG_INFO_ADDR +#define WF_PSE_TOP_LMAC3_PG_INFO_LMAC3_RSV_CNT_MASK \ +0x00000FFF /* LMAC3_RSV_CNT[11..0] */ +#define WF_PSE_TOP_LMAC3_PG_INFO_LMAC3_RSV_CNT_SHFT 0 + +/* +* ---PG_MDP_GROUP (0x820C8000 + 0x198)--- +* MDP_MIN_QUOTA[11..0] - (RW) Min. quota of MDP group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED12[15..12] - (RO) Reserved bits +* MDP_MAX_QUOTA[27..16] - (RW) Max. quota of MDP group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PG_MDP_GROUP_MDP_MAX_QUOTA_ADDR WF_PSE_TOP_PG_MDP_GROUP_ADDR +#define WF_PSE_TOP_PG_MDP_GROUP_MDP_MAX_QUOTA_MASK \ +0x0FFF0000 /* MDP_MAX_QUOTA[27..16] */ +#define WF_PSE_TOP_PG_MDP_GROUP_MDP_MAX_QUOTA_SHFT 16 +#define WF_PSE_TOP_PG_MDP_GROUP_MDP_MIN_QUOTA_ADDR WF_PSE_TOP_PG_MDP_GROUP_ADDR +#define WF_PSE_TOP_PG_MDP_GROUP_MDP_MIN_QUOTA_MASK \ +0x00000FFF /* MDP_MIN_QUOTA[11..0] */ +#define WF_PSE_TOP_PG_MDP_GROUP_MDP_MIN_QUOTA_SHFT 0 + +/* +* ---MDP_PG_INFO (0x820C8000 + 0x19C)--- +* MDP_RSV_CNT[11..0] - (RO) Reserved pages of MDP group +* RESERVED12[15..12] - (RO) Reserved bits +* MDP_SRC_CNT[27..16] - (RO) Used pages of MDP group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_MDP_PG_INFO_MDP_SRC_CNT_ADDR WF_PSE_TOP_MDP_PG_INFO_ADDR +#define WF_PSE_TOP_MDP_PG_INFO_MDP_SRC_CNT_MASK \ +0x0FFF0000 /* MDP_SRC_CNT[27..16] */ +#define WF_PSE_TOP_MDP_PG_INFO_MDP_SRC_CNT_SHFT 16 +#define WF_PSE_TOP_MDP_PG_INFO_MDP_RSV_CNT_ADDR WF_PSE_TOP_MDP_PG_INFO_ADDR +#define WF_PSE_TOP_MDP_PG_INFO_MDP_RSV_CNT_MASK \ +0x00000FFF /* MDP_RSV_CNT[11..0] */ +#define WF_PSE_TOP_MDP_PG_INFO_MDP_RSV_CNT_SHFT 0 + +/* +* ---RL_BUF_CTRL_0 (0x820C8000 + 0x1A0)--- +* RELAY_BUF_ADDR[11..0] - (RW) Read address of relay buffer +* RESERVED12[30..12] - (RO) Reserved bits +* EXECUTE[31] - (A0) Executes relay buffer read command +*/ +#define WF_PSE_TOP_RL_BUF_CTRL_0_EXECUTE_ADDR WF_PSE_TOP_RL_BUF_CTRL_0_ADDR +#define WF_PSE_TOP_RL_BUF_CTRL_0_EXECUTE_MASK 0x80000000 /* EXECUTE[31] */ +#define WF_PSE_TOP_RL_BUF_CTRL_0_EXECUTE_SHFT 31 +#define WF_PSE_TOP_RL_BUF_CTRL_0_RELAY_BUF_ADDR_ADDR \ +WF_PSE_TOP_RL_BUF_CTRL_0_ADDR +#define WF_PSE_TOP_RL_BUF_CTRL_0_RELAY_BUF_ADDR_MASK \ +0x00000FFF /* RELAY_BUF_ADDR[11..0] */ +#define WF_PSE_TOP_RL_BUF_CTRL_0_RELAY_BUF_ADDR_SHFT 0 + +/* +* ---RL_BUF_CTRL_1 (0x820C8000 + 0x1A4)--- +* PAGE_NUM[8..0] - (RO) Page number of packet +* RESERVED9[13..9] - (RO) Reserved bits +* PKT_TAIL_PAGE[25..14] - (RO) Tail page of the packet with head page +* being the relay buffer address +* RESERVED26[26] - (RO) Reserved bits +* RESV_GRP_ID[30..27] - (RO) Group ID of reserved page used by FID +* RESERVED31[31] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_RL_BUF_CTRL_1_RESV_GRP_ID_ADDR WF_PSE_TOP_RL_BUF_CTRL_1_ADDR +#define WF_PSE_TOP_RL_BUF_CTRL_1_RESV_GRP_ID_MASK \ +0x78000000 /* RESV_GRP_ID[30..27] */ +#define WF_PSE_TOP_RL_BUF_CTRL_1_RESV_GRP_ID_SHFT 27 +#define WF_PSE_TOP_RL_BUF_CTRL_1_PKT_TAIL_PAGE_ADDR \ +WF_PSE_TOP_RL_BUF_CTRL_1_ADDR +#define WF_PSE_TOP_RL_BUF_CTRL_1_PKT_TAIL_PAGE_MASK \ +0x03FFC000 /* PKT_TAIL_PAGE[25..14] */ +#define WF_PSE_TOP_RL_BUF_CTRL_1_PKT_TAIL_PAGE_SHFT 14 +#define WF_PSE_TOP_RL_BUF_CTRL_1_PAGE_NUM_ADDR WF_PSE_TOP_RL_BUF_CTRL_1_ADDR +#define WF_PSE_TOP_RL_BUF_CTRL_1_PAGE_NUM_MASK 0x000001FF /* PAGE_NUM[8..0] */ +#define WF_PSE_TOP_RL_BUF_CTRL_1_PAGE_NUM_SHFT 0 + +/* +* ---FL_QUE_CTRL_0 (0x820C8000 + 0x1B0)--- +* Q_BUF_WLANID[9..0] - (RW) Address of queue structure buffer +WLANID. +* Q_BUF_PID[11..10] - (RW) Address of queue structure buffer PID +* FL_BUFFER_ADDR[23..12] - (RW) Frame address of read previous +* frame/next frame +* Q_BUF_QID[30..24] - (RW) Address of queue structure buffer QID +* EXECUTE[31] - (A0) Executes frame link and queue structure +* buffer read command +*/ +#define WF_PSE_TOP_FL_QUE_CTRL_0_EXECUTE_ADDR WF_PSE_TOP_FL_QUE_CTRL_0_ADDR +#define WF_PSE_TOP_FL_QUE_CTRL_0_EXECUTE_MASK 0x80000000 /* EXECUTE[31] */ +#define WF_PSE_TOP_FL_QUE_CTRL_0_EXECUTE_SHFT 31 +#define WF_PSE_TOP_FL_QUE_CTRL_0_Q_BUF_QID_ADDR WF_PSE_TOP_FL_QUE_CTRL_0_ADDR +#define WF_PSE_TOP_FL_QUE_CTRL_0_Q_BUF_QID_MASK \ +0x7F000000 /* Q_BUF_QID[30..24] */ +#define WF_PSE_TOP_FL_QUE_CTRL_0_Q_BUF_QID_SHFT 24 +#define WF_PSE_TOP_FL_QUE_CTRL_0_FL_BUFFER_ADDR_ADDR \ +WF_PSE_TOP_FL_QUE_CTRL_0_ADDR +#define WF_PSE_TOP_FL_QUE_CTRL_0_FL_BUFFER_ADDR_MASK \ +0x00FFF000 /* FL_BUFFER_ADDR[23..12] */ +#define WF_PSE_TOP_FL_QUE_CTRL_0_FL_BUFFER_ADDR_SHFT 12 +#define WF_PSE_TOP_FL_QUE_CTRL_0_Q_BUF_PID_ADDR WF_PSE_TOP_FL_QUE_CTRL_0_ADDR +#define WF_PSE_TOP_FL_QUE_CTRL_0_Q_BUF_PID_MASK \ +0x00000C00 /* Q_BUF_PID[11..10] */ +#define WF_PSE_TOP_FL_QUE_CTRL_0_Q_BUF_PID_SHFT 10 +#define WF_PSE_TOP_FL_QUE_CTRL_0_Q_BUF_WLANID_ADDR WF_PSE_TOP_FL_QUE_CTRL_0_ADDR +#define WF_PSE_TOP_FL_QUE_CTRL_0_Q_BUF_WLANID_MASK \ +0x000003FF /* Q_BUF_WLANID[9..0] */ +#define WF_PSE_TOP_FL_QUE_CTRL_0_Q_BUF_WLANID_SHFT 0 + +/* +* ---FL_QUE_CTRL_1 (0x820C8000 + 0x1B4)--- +* NEXT_FID[11..0] - (RO) Next frame ID of FL_BUFFER_ADDR +* RESERVED12[15..12] - (RO) Reserved bits +* PREV_FID[27..16] - (RO) Previous frame ID of FL_BUFFER_ADDR +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_FL_QUE_CTRL_1_PREV_FID_ADDR WF_PSE_TOP_FL_QUE_CTRL_1_ADDR +#define WF_PSE_TOP_FL_QUE_CTRL_1_PREV_FID_MASK 0x0FFF0000 /* PREV_FID[27..16]\ + */ +#define WF_PSE_TOP_FL_QUE_CTRL_1_PREV_FID_SHFT 16 +#define WF_PSE_TOP_FL_QUE_CTRL_1_NEXT_FID_ADDR WF_PSE_TOP_FL_QUE_CTRL_1_ADDR +#define WF_PSE_TOP_FL_QUE_CTRL_1_NEXT_FID_MASK 0x00000FFF /* NEXT_FID[11..0] \ + */ +#define WF_PSE_TOP_FL_QUE_CTRL_1_NEXT_FID_SHFT 0 + +/* +* ---FL_QUE_CTRL_2 (0x820C8000 + 0x1B8)--- +* QUEUE_HEAD_FID[11..0] - (RO) Head frame ID of quest queue setting in +0x01b0[15:0] +* RESERVED12[15..12] - (RO) Reserved bits +* QUEUE_TAIL_FID[27..16] - (RO) Tail frame ID of quest queue setting in +0x01b0[15:0] +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_FL_QUE_CTRL_2_QUEUE_TAIL_FID_ADDR \ +WF_PSE_TOP_FL_QUE_CTRL_2_ADDR +#define WF_PSE_TOP_FL_QUE_CTRL_2_QUEUE_TAIL_FID_MASK \ +0x0FFF0000 /* QUEUE_TAIL_FID[27..16] */ +#define WF_PSE_TOP_FL_QUE_CTRL_2_QUEUE_TAIL_FID_SHFT 16 +#define WF_PSE_TOP_FL_QUE_CTRL_2_QUEUE_HEAD_FID_ADDR \ +WF_PSE_TOP_FL_QUE_CTRL_2_ADDR +#define WF_PSE_TOP_FL_QUE_CTRL_2_QUEUE_HEAD_FID_MASK \ +0x00000FFF /* QUEUE_HEAD_FID[11..0] */ +#define WF_PSE_TOP_FL_QUE_CTRL_2_QUEUE_HEAD_FID_SHFT 0 + +/* +* ---FL_QUE_CTRL_3 (0x820C8000 + 0x1BC)--- +* QUEUE_PKT_NUM[11..0] - (RO) Total packet number of queue setting in +0x1b0[15:0] +* QUEUE_PAGE_NUM[23..12] - (RO) Total page number of queue setting in +0x1b0[15:0] +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_FL_QUE_CTRL_3_QUEUE_PAGE_NUM_ADDR \ +WF_PSE_TOP_FL_QUE_CTRL_3_ADDR +#define WF_PSE_TOP_FL_QUE_CTRL_3_QUEUE_PAGE_NUM_MASK \ +0x00FFF000 /* QUEUE_PAGE_NUM[23..12] */ +#define WF_PSE_TOP_FL_QUE_CTRL_3_QUEUE_PAGE_NUM_SHFT 12 +#define WF_PSE_TOP_FL_QUE_CTRL_3_QUEUE_PKT_NUM_ADDR \ +WF_PSE_TOP_FL_QUE_CTRL_3_ADDR +#define WF_PSE_TOP_FL_QUE_CTRL_3_QUEUE_PKT_NUM_MASK \ +0x00000FFF /* QUEUE_PKT_NUM[11..0] */ +#define WF_PSE_TOP_FL_QUE_CTRL_3_QUEUE_PKT_NUM_SHFT 0 + +/* +* ---PL_QUE_CTRL_0 (0x820C8000 + 0x1C0)--- +* NEXT_PAGE[11..0] - (RO) Next page of the PL_BUFFER_ADDR +* RESERVED12[15..12] - (RO) Reserved bits +* PL_BUFFER_ADDR[27..16] - (RW) Page address of read next page +* RESERVED28[30..28] - (RO) Reserved bits +* EXECUTE[31] - (A0) Executes page link buffer read command +*/ +#define WF_PSE_TOP_PL_QUE_CTRL_0_EXECUTE_ADDR WF_PSE_TOP_PL_QUE_CTRL_0_ADDR +#define WF_PSE_TOP_PL_QUE_CTRL_0_EXECUTE_MASK 0x80000000 /* EXECUTE[31] */ +#define WF_PSE_TOP_PL_QUE_CTRL_0_EXECUTE_SHFT 31 +#define WF_PSE_TOP_PL_QUE_CTRL_0_PL_BUFFER_ADDR_ADDR \ +WF_PSE_TOP_PL_QUE_CTRL_0_ADDR +#define WF_PSE_TOP_PL_QUE_CTRL_0_PL_BUFFER_ADDR_MASK \ +0x0FFF0000 /* PL_BUFFER_ADDR[27..16] */ +#define WF_PSE_TOP_PL_QUE_CTRL_0_PL_BUFFER_ADDR_SHFT 16 +#define WF_PSE_TOP_PL_QUE_CTRL_0_NEXT_PAGE_ADDR WF_PSE_TOP_PL_QUE_CTRL_0_ADDR +#define WF_PSE_TOP_PL_QUE_CTRL_0_NEXT_PAGE_MASK \ +0x00000FFF /* NEXT_PAGE[11..0] */ +#define WF_PSE_TOP_PL_QUE_CTRL_0_NEXT_PAGE_SHFT 0 + +/* +* ---PSE_LP_CTRL (0x820C8000 + 0x1D0)--- +* RESERVED0[6..0] - (RO) Reserved bits +* PSE_LP_WAKEUP[7] - (RW) PSE Low Power Wakeup control +* PSE2HIF_PSSS_EN[8] - (RW) PSE Access HIF port control +* MCU_COALEASCE[9] - (RW) Coalease CPU ENQ and ENQ_DLY for HIF +port +* RESERVED10[31..10] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_LP_CTRL_MCU_COALEASCE_ADDR WF_PSE_TOP_PSE_LP_CTRL_ADDR +#define WF_PSE_TOP_PSE_LP_CTRL_MCU_COALEASCE_MASK \ +0x00000200 /* MCU_COALEASCE[9] */ +#define WF_PSE_TOP_PSE_LP_CTRL_MCU_COALEASCE_SHFT 9 +#define WF_PSE_TOP_PSE_LP_CTRL_PSE2HIF_PSSS_EN_ADDR WF_PSE_TOP_PSE_LP_CTRL_ADDR +#define WF_PSE_TOP_PSE_LP_CTRL_PSE2HIF_PSSS_EN_MASK \ +0x00000100 /* PSE2HIF_PSSS_EN[8] */ +#define WF_PSE_TOP_PSE_LP_CTRL_PSE2HIF_PSSS_EN_SHFT 8 +#define WF_PSE_TOP_PSE_LP_CTRL_PSE_LP_WAKEUP_ADDR WF_PSE_TOP_PSE_LP_CTRL_ADDR +#define WF_PSE_TOP_PSE_LP_CTRL_PSE_LP_WAKEUP_MASK \ +0x00000080 /* PSE_LP_WAKEUP[7] */ +#define WF_PSE_TOP_PSE_LP_CTRL_PSE_LP_WAKEUP_SHFT 7 + +/* +* ---PSE_WFDMA_BUF_CTRL (0x820C8000 + 0x1E0)--- +* WFDMA_TXS_BUF_VLD_TH[7..0] - (RW) TXS valid reserved page count threshold +* WFDMA_TXCMD_BUF_VLD_TH[15..8] - (RW) TXCMD valid reserved page count +threshold +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_WFDMA_BUF_CTRL_WFDMA_TXCMD_BUF_VLD_TH_ADDR \ +WF_PSE_TOP_PSE_WFDMA_BUF_CTRL_ADDR +#define WF_PSE_TOP_PSE_WFDMA_BUF_CTRL_WFDMA_TXCMD_BUF_VLD_TH_MASK \ +0x0000FF00 /* WFDMA_TXCMD_BUF_VLD_TH[15..8] */ +#define WF_PSE_TOP_PSE_WFDMA_BUF_CTRL_WFDMA_TXCMD_BUF_VLD_TH_SHFT 8 +#define WF_PSE_TOP_PSE_WFDMA_BUF_CTRL_WFDMA_TXS_BUF_VLD_TH_ADDR \ +WF_PSE_TOP_PSE_WFDMA_BUF_CTRL_ADDR +#define WF_PSE_TOP_PSE_WFDMA_BUF_CTRL_WFDMA_TXS_BUF_VLD_TH_MASK \ +0x000000FF /* WFDMA_TXS_BUF_VLD_TH[7..0] */ +#define WF_PSE_TOP_PSE_WFDMA_BUF_CTRL_WFDMA_TXS_BUF_VLD_TH_SHFT 0 + +/* +* ---PSE_CT_PRI_CTRL (0x820C8000 + 0x1EC)--- +* PSE_CT_PRI_LOW_LV[11..0] - (RW) Low trigger level of Group0 qouta +* RESERVED12[15..12] - (RO) Reserved bits +* PSE_CT_PRI_HI_LV[27..16] - (RW) High trigger level of Group0 qouta +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_CT_PRI_CTRL_PSE_CT_PRI_HI_LV_ADDR \ +WF_PSE_TOP_PSE_CT_PRI_CTRL_ADDR +#define WF_PSE_TOP_PSE_CT_PRI_CTRL_PSE_CT_PRI_HI_LV_MASK \ +0x0FFF0000 /* PSE_CT_PRI_HI_LV[27..16] */ +#define WF_PSE_TOP_PSE_CT_PRI_CTRL_PSE_CT_PRI_HI_LV_SHFT 16 +#define WF_PSE_TOP_PSE_CT_PRI_CTRL_PSE_CT_PRI_LOW_LV_ADDR \ +WF_PSE_TOP_PSE_CT_PRI_CTRL_ADDR +#define WF_PSE_TOP_PSE_CT_PRI_CTRL_PSE_CT_PRI_LOW_LV_MASK \ +0x00000FFF /* PSE_CT_PRI_LOW_LV[11..0] */ +#define WF_PSE_TOP_PSE_CT_PRI_CTRL_PSE_CT_PRI_LOW_LV_SHFT 0 + +/* +* ---PLE_ENQ_PKT_NUM (0x820C8000 + 0x1F0)--- +* PLE_ENQ_HIF_Q_PKT_NUM[15..0] - (RO) The packets numbers of PLE port enqueue +* to HIF queue. +* PLE_ENQ_HIF_Q_SEL[19..16] - (RW) Select HIF queue which is PLE port +* enqueue to. +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PLE_ENQ_PKT_NUM_PLE_ENQ_HIF_Q_SEL_ADDR \ +WF_PSE_TOP_PLE_ENQ_PKT_NUM_ADDR +#define WF_PSE_TOP_PLE_ENQ_PKT_NUM_PLE_ENQ_HIF_Q_SEL_MASK \ +0x000F0000 /* PLE_ENQ_HIF_Q_SEL[19..16] */ +#define WF_PSE_TOP_PLE_ENQ_PKT_NUM_PLE_ENQ_HIF_Q_SEL_SHFT 16 +#define WF_PSE_TOP_PLE_ENQ_PKT_NUM_PLE_ENQ_HIF_Q_PKT_NUM_ADDR \ +WF_PSE_TOP_PLE_ENQ_PKT_NUM_ADDR +#define WF_PSE_TOP_PLE_ENQ_PKT_NUM_PLE_ENQ_HIF_Q_PKT_NUM_MASK \ +0x0000FFFF /* PLE_ENQ_HIF_Q_PKT_NUM[15..0] */ +#define WF_PSE_TOP_PLE_ENQ_PKT_NUM_PLE_ENQ_HIF_Q_PKT_NUM_SHFT 0 + +/* +* ---CPU_ENQ_PKT_NUM (0x820C8000 + 0x1F4)--- +* CPU_ENQ_HIF_Q_PKT_NUM[15..0] - (RO) The packets numbers of CPU port enqueue +* to HIF queue. +* CPU_ENQ_HIF_Q_SEL[19..16] - (RW) Select HIF queue which is CPU port +* enqueue to. +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_CPU_ENQ_PKT_NUM_CPU_ENQ_HIF_Q_SEL_ADDR \ +WF_PSE_TOP_CPU_ENQ_PKT_NUM_ADDR +#define WF_PSE_TOP_CPU_ENQ_PKT_NUM_CPU_ENQ_HIF_Q_SEL_MASK \ +0x000F0000 /* CPU_ENQ_HIF_Q_SEL[19..16] */ +#define WF_PSE_TOP_CPU_ENQ_PKT_NUM_CPU_ENQ_HIF_Q_SEL_SHFT 16 +#define WF_PSE_TOP_CPU_ENQ_PKT_NUM_CPU_ENQ_HIF_Q_PKT_NUM_ADDR \ +WF_PSE_TOP_CPU_ENQ_PKT_NUM_ADDR +#define WF_PSE_TOP_CPU_ENQ_PKT_NUM_CPU_ENQ_HIF_Q_PKT_NUM_MASK \ +0x0000FFFF /* CPU_ENQ_HIF_Q_PKT_NUM[15..0] */ +#define WF_PSE_TOP_CPU_ENQ_PKT_NUM_CPU_ENQ_HIF_Q_PKT_NUM_SHFT 0 + +/* +* ---LMAC_ENQ_PKT_NUM (0x820C8000 + 0x1F8)--- +* LMAC_ENQ_HIF_Q_PKT_NUM[15..0] - (RO) The packets numbers of LMAC port +* enqueue to HIF queue. +* LMAC_ENQ_HIF_Q_SEL[19..16] - (RW) Select HIF queue which is LMAC port +* enqueue to. +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_LMAC_ENQ_PKT_NUM_LMAC_ENQ_HIF_Q_SEL_ADDR \ +WF_PSE_TOP_LMAC_ENQ_PKT_NUM_ADDR +#define WF_PSE_TOP_LMAC_ENQ_PKT_NUM_LMAC_ENQ_HIF_Q_SEL_MASK \ +0x000F0000 /* LMAC_ENQ_HIF_Q_SEL[19..16] */ +#define WF_PSE_TOP_LMAC_ENQ_PKT_NUM_LMAC_ENQ_HIF_Q_SEL_SHFT 16 +#define WF_PSE_TOP_LMAC_ENQ_PKT_NUM_LMAC_ENQ_HIF_Q_PKT_NUM_ADDR \ +WF_PSE_TOP_LMAC_ENQ_PKT_NUM_ADDR +#define WF_PSE_TOP_LMAC_ENQ_PKT_NUM_LMAC_ENQ_HIF_Q_PKT_NUM_MASK \ +0x0000FFFF /* LMAC_ENQ_HIF_Q_PKT_NUM[15..0] */ +#define WF_PSE_TOP_LMAC_ENQ_PKT_NUM_LMAC_ENQ_HIF_Q_PKT_NUM_SHFT 0 + +/* +* ---HIF_ENQ_PKT_NUM (0x820C8000 + 0x1FC)--- +* HIF_ENQ_MDP[15..0] - (RO) The packets numbers of HIF port enqueue +* to MDP TX queue. +* HIF_ENQ_CPU[31..16] - (RO) The packets numbers of HIF port enqueue +* to CPU queue +*/ +#define WF_PSE_TOP_HIF_ENQ_PKT_NUM_HIF_ENQ_CPU_ADDR \ +WF_PSE_TOP_HIF_ENQ_PKT_NUM_ADDR +#define WF_PSE_TOP_HIF_ENQ_PKT_NUM_HIF_ENQ_CPU_MASK \ +0xFFFF0000 /* HIF_ENQ_CPU[31..16] */ +#define WF_PSE_TOP_HIF_ENQ_PKT_NUM_HIF_ENQ_CPU_SHFT 16 +#define WF_PSE_TOP_HIF_ENQ_PKT_NUM_HIF_ENQ_MDP_ADDR \ +WF_PSE_TOP_HIF_ENQ_PKT_NUM_ADDR +#define WF_PSE_TOP_HIF_ENQ_PKT_NUM_HIF_ENQ_MDP_MASK \ +0x0000FFFF /* HIF_ENQ_MDP[15..0] */ +#define WF_PSE_TOP_HIF_ENQ_PKT_NUM_HIF_ENQ_MDP_SHFT 0 + +/* +* ---MDP_ENQ_PKT_NUM (0x820C8000 + 0x200)--- +* MDP_ENQ_HIF_Q_PKT_NUM[15..0] - (RO) The packets numbers of MDP port enqueue +* to HIF queue. +* MDP_ENQ_HIF_Q_SEL[31..16] - (RW) Select HIF queue which is MDP port +* enqueue to. +*/ +#define WF_PSE_TOP_MDP_ENQ_PKT_NUM_MDP_ENQ_HIF_Q_SEL_ADDR \ +WF_PSE_TOP_MDP_ENQ_PKT_NUM_ADDR +#define WF_PSE_TOP_MDP_ENQ_PKT_NUM_MDP_ENQ_HIF_Q_SEL_MASK \ +0xFFFF0000 /* MDP_ENQ_HIF_Q_SEL[31..16] */ +#define WF_PSE_TOP_MDP_ENQ_PKT_NUM_MDP_ENQ_HIF_Q_SEL_SHFT 16 +#define WF_PSE_TOP_MDP_ENQ_PKT_NUM_MDP_ENQ_HIF_Q_PKT_NUM_ADDR \ +WF_PSE_TOP_MDP_ENQ_PKT_NUM_ADDR +#define WF_PSE_TOP_MDP_ENQ_PKT_NUM_MDP_ENQ_HIF_Q_PKT_NUM_MASK \ +0x0000FFFF /* MDP_ENQ_HIF_Q_PKT_NUM[15..0] */ +#define WF_PSE_TOP_MDP_ENQ_PKT_NUM_MDP_ENQ_HIF_Q_PKT_NUM_SHFT 0 + +/* +* ---TIMEOUT_CTRL (0x820C8000 + 0x244)--- +* FL_WD_TO_CTRL[7..0] - (RW) FL watch dog timeput +* RESERVED8[15..8] - (RO) Reserved bits +* APB_WD_TO_CTRL[23..16] - (RW) APB pready watch dog timeout control +register. +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_TIMEOUT_CTRL_APB_WD_TO_CTRL_ADDR WF_PSE_TOP_TIMEOUT_CTRL_ADDR +#define WF_PSE_TOP_TIMEOUT_CTRL_APB_WD_TO_CTRL_MASK \ +0x00FF0000 /* APB_WD_TO_CTRL[23..16] */ +#define WF_PSE_TOP_TIMEOUT_CTRL_APB_WD_TO_CTRL_SHFT 16 +#define WF_PSE_TOP_TIMEOUT_CTRL_FL_WD_TO_CTRL_ADDR WF_PSE_TOP_TIMEOUT_CTRL_ADDR +#define WF_PSE_TOP_TIMEOUT_CTRL_FL_WD_TO_CTRL_MASK \ +0x000000FF /* FL_WD_TO_CTRL[7..0] */ +#define WF_PSE_TOP_TIMEOUT_CTRL_FL_WD_TO_CTRL_SHFT 0 + +/* +* ---FSM_IDLE_WD_CTRL (0x820C8000 + 0x24C)--- +* FL_IDLE_WD_TO_TH[7..0] - (RW) Watchdog timeout threshold for frame +* link FSM not returning to IDLE +* PL_IDLE_WD_TO_TH[15..8] - (RW) Watchdog timeout threshold for page link +* FSM not returning to IDLE +* PORT_IDLE_WD_TO_TH[23..16] - (RW) Watchdog timeout threshold for page link +* Port Link not returning to IDLE +* (Including HIF/CPU/LMAC port) +* MACTX_IDLE_WD_TO_TH[31..24] - (RW) Watchdog timeout threshold for port oper +* MACTX not returning to IDLE +*/ +#define WF_PSE_TOP_FSM_IDLE_WD_CTRL_MACTX_IDLE_WD_TO_TH_ADDR \ +WF_PSE_TOP_FSM_IDLE_WD_CTRL_ADDR +#define WF_PSE_TOP_FSM_IDLE_WD_CTRL_MACTX_IDLE_WD_TO_TH_MASK \ +0xFF000000 /* MACTX_IDLE_WD_TO_TH[31..24] */ +#define WF_PSE_TOP_FSM_IDLE_WD_CTRL_MACTX_IDLE_WD_TO_TH_SHFT 24 +#define WF_PSE_TOP_FSM_IDLE_WD_CTRL_PORT_IDLE_WD_TO_TH_ADDR \ +WF_PSE_TOP_FSM_IDLE_WD_CTRL_ADDR +#define WF_PSE_TOP_FSM_IDLE_WD_CTRL_PORT_IDLE_WD_TO_TH_MASK \ +0x00FF0000 /* PORT_IDLE_WD_TO_TH[23..16] */ +#define WF_PSE_TOP_FSM_IDLE_WD_CTRL_PORT_IDLE_WD_TO_TH_SHFT 16 +#define WF_PSE_TOP_FSM_IDLE_WD_CTRL_PL_IDLE_WD_TO_TH_ADDR \ +WF_PSE_TOP_FSM_IDLE_WD_CTRL_ADDR +#define WF_PSE_TOP_FSM_IDLE_WD_CTRL_PL_IDLE_WD_TO_TH_MASK \ +0x0000FF00 /* PL_IDLE_WD_TO_TH[15..8] */ +#define WF_PSE_TOP_FSM_IDLE_WD_CTRL_PL_IDLE_WD_TO_TH_SHFT 8 +#define WF_PSE_TOP_FSM_IDLE_WD_CTRL_FL_IDLE_WD_TO_TH_ADDR \ +WF_PSE_TOP_FSM_IDLE_WD_CTRL_ADDR +#define WF_PSE_TOP_FSM_IDLE_WD_CTRL_FL_IDLE_WD_TO_TH_MASK \ +0x000000FF /* FL_IDLE_WD_TO_TH[7..0] */ +#define WF_PSE_TOP_FSM_IDLE_WD_CTRL_FL_IDLE_WD_TO_TH_SHFT 0 + +/* +* ---FSM_IDLE_WD_EN (0x820C8000 + 0x250)--- +* EN_HIF_PORT_IDLE_WD_TO[0] - (RW) Enables watchdog for HIF port oper FSM +* not returning to IDLE +* EN_CPU_PORT_IDLE_WD_TO[1] - (RW) Enables watchdog for CPU port oper FSM +* not returning to IDLE +* EN_LMAC_PORT_IDLE_WD_TO[2] - (RW) Enables watchdog for LMAC port oper FSM +* not returning to IDLE +* EN_MDP_IDLE_WD_TO[3] - (RW) Enables watchdog for MDP port oper FSM +* not returning to IDLE +* EN_SEC_IDLE_WD_TO[4] - (RW) Enables watchdog for SEC port oper FSM +* not returning to IDLE +* EN_PLE_IDLE_WD_TO[5] - (RW) Enables watchdog for PLE port oper FSM +* not returning to IDLE +* EN_AMSDU_IDLE_WD_TO[6] - (RW) Enables watchdog for AMSDU port oper FSM +* not returning to IDLE +* RESERVED7[7] - (RO) Reserved bits +* EN_FL_IDLE_WD_TO[8] - (RW) Enables watchdog for frame link FSM not +* returning to IDLE +* EN_PL_IDLE_WD_TO[9] - (RW) Enables watchdog for page link FSM not +* returning to IDLE +* RESERVED10[31..10] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_PL_IDLE_WD_TO_ADDR \ +WF_PSE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_PL_IDLE_WD_TO_MASK \ +0x00000200 /* EN_PL_IDLE_WD_TO[9] */ +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_PL_IDLE_WD_TO_SHFT 9 +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_FL_IDLE_WD_TO_ADDR \ +WF_PSE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_FL_IDLE_WD_TO_MASK \ +0x00000100 /* EN_FL_IDLE_WD_TO[8] */ +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_FL_IDLE_WD_TO_SHFT 8 +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_AMSDU_IDLE_WD_TO_ADDR \ +WF_PSE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_AMSDU_IDLE_WD_TO_MASK \ +0x00000040 /* EN_AMSDU_IDLE_WD_TO[6] */ +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_AMSDU_IDLE_WD_TO_SHFT 6 +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_PLE_IDLE_WD_TO_ADDR \ +WF_PSE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_PLE_IDLE_WD_TO_MASK \ +0x00000020 /* EN_PLE_IDLE_WD_TO[5] */ +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_PLE_IDLE_WD_TO_SHFT 5 +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_SEC_IDLE_WD_TO_ADDR \ +WF_PSE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_SEC_IDLE_WD_TO_MASK \ +0x00000010 /* EN_SEC_IDLE_WD_TO[4] */ +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_SEC_IDLE_WD_TO_SHFT 4 +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_MDP_IDLE_WD_TO_ADDR \ +WF_PSE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_MDP_IDLE_WD_TO_MASK \ +0x00000008 /* EN_MDP_IDLE_WD_TO[3] */ +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_MDP_IDLE_WD_TO_SHFT 3 +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_LMAC_PORT_IDLE_WD_TO_ADDR \ +WF_PSE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_LMAC_PORT_IDLE_WD_TO_MASK \ +0x00000004 /* EN_LMAC_PORT_IDLE_WD_TO[2] */ +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_LMAC_PORT_IDLE_WD_TO_SHFT 2 +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_CPU_PORT_IDLE_WD_TO_ADDR \ +WF_PSE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_CPU_PORT_IDLE_WD_TO_MASK \ +0x00000002 /* EN_CPU_PORT_IDLE_WD_TO[1] */ +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_CPU_PORT_IDLE_WD_TO_SHFT 1 +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_HIF_PORT_IDLE_WD_TO_ADDR \ +WF_PSE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_HIF_PORT_IDLE_WD_TO_MASK \ +0x00000001 /* EN_HIF_PORT_IDLE_WD_TO[0] */ +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_HIF_PORT_IDLE_WD_TO_SHFT 0 + +/* +* ---PSE_INTER_ERR_FLAG (0x820C8000 + 0x280)--- +* DEQ_EMPTY_QUEUE[0] - (RO) DEQueue Empty Error Flag +* APB_WD_TO[1] - (RO) APB Write Data Timeout Error Flag +* FL_CTRL_WD_TO[2] - (RO) FL Write Data Timeout Error Flag +* RESERVED3[31..3] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_INTER_ERR_FLAG_FL_CTRL_WD_TO_ADDR \ +WF_PSE_TOP_PSE_INTER_ERR_FLAG_ADDR +#define WF_PSE_TOP_PSE_INTER_ERR_FLAG_FL_CTRL_WD_TO_MASK \ +0x00000004 /* FL_CTRL_WD_TO[2] */ +#define WF_PSE_TOP_PSE_INTER_ERR_FLAG_FL_CTRL_WD_TO_SHFT 2 +#define WF_PSE_TOP_PSE_INTER_ERR_FLAG_APB_WD_TO_ADDR \ +WF_PSE_TOP_PSE_INTER_ERR_FLAG_ADDR +#define WF_PSE_TOP_PSE_INTER_ERR_FLAG_APB_WD_TO_MASK \ +0x00000002 /* APB_WD_TO[1] */ +#define WF_PSE_TOP_PSE_INTER_ERR_FLAG_APB_WD_TO_SHFT 1 +#define WF_PSE_TOP_PSE_INTER_ERR_FLAG_DEQ_EMPTY_QUEUE_ADDR \ +WF_PSE_TOP_PSE_INTER_ERR_FLAG_ADDR +#define WF_PSE_TOP_PSE_INTER_ERR_FLAG_DEQ_EMPTY_QUEUE_MASK \ +0x00000001 /* DEQ_EMPTY_QUEUE[0] */ +#define WF_PSE_TOP_PSE_INTER_ERR_FLAG_DEQ_EMPTY_QUEUE_SHFT 0 + +/* +* ---PSE_SER_CTRL (0x820C8000 + 0x2a0)--- +* HIF_SER_PAUSE_ALLOCATE[0] - (RW) System Error Recover function for Pause +* HIFBuffer Allocation +* CPU_SER_PAUSE_ALLOCATE[1] - (RW) System Error Recover function for Pause +* CPU Buffer Allocation +* WF_SER_PAUSE_ALLOCATE[2] - (RW) System Error Recover function for Pause +* WF Buffer Allocation +* MDP_SER_PAUSE_ALLOCATE[3] - (RW) System Error Recover function for Pause +* MDP Buffer Allocation +* SEC_SER_PAUSE_ALLOCATE[4] - (RW) System Error Recover function for Pause +* SEC Buffer Allocation +* PLE_SER_PAUSE_ALLOCATE[5] - (RW) System Error Recover function for Pause +* PLE Buffer Allocation +* RESERVED6[7..6] - (RO) Reserved bits +* HIF_SER_PAUSE_DATA[8] - (RW) System Error Recover function for Pause +* HIF DATA opeartion. +* CPU_SER_PAUSE_DATA[9] - (RW) System Error Recover function for Pause +* CPU DATA opeartion. +* WF_SER_PAUSE_DATA[10] - (RW) System Error Recover function for Pause +* WF DATA opeartion. +* MDP_SER_PAUSE_DATA[11] - (RW) System Error Recover function for Pause +* MDP DATA opeartion. +* SEC_SER_PAUSE_DATA[12] - (RW) System Error Recover function for Pause +* SEC DATA opeartion. +* PLE_SER_PAUSE_DATA[13] - (RW) System Error Recover function for Pause +* PLE DATA opeartion. +* RESERVED14[15..14] - (RO) Reserved bits +* HIF_SER_PAUSE_QUEUE[16] - (RW) System Error Recover function for Pause +* HIF Queue opeartion. +* CPU_SER_PAUSE_QUEUE[17] - (RW) System Error Recover function for Pause +* CPU Queue opeartion. +* WF_SER_PAUSE_QUEUE[18] - (RW) System Error Recover function for Pause +* WF Queue opeartion. +* MDP_SER_PAUSE_QUEUE[19] - (RW) System Error Recover function for Pause +* MDP Queue opeartion. +* SEC_SER_PAUSE_QUEUE[20] - (RW) System Error Recover function for Pause +* SEC Queue opeartion. +* PLE_SER_PAUSE_QUEUE[21] - (RW) System Error Recover function for Pause +* PLE Queue opeartion. +* RESERVED22[31..22] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_SER_CTRL_PLE_SER_PAUSE_QUEUE_ADDR \ +WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_PLE_SER_PAUSE_QUEUE_MASK \ +0x00200000 /* PLE_SER_PAUSE_QUEUE[21] */ +#define WF_PSE_TOP_PSE_SER_CTRL_PLE_SER_PAUSE_QUEUE_SHFT 21 +#define WF_PSE_TOP_PSE_SER_CTRL_SEC_SER_PAUSE_QUEUE_ADDR \ +WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_SEC_SER_PAUSE_QUEUE_MASK \ +0x00100000 /* SEC_SER_PAUSE_QUEUE[20] */ +#define WF_PSE_TOP_PSE_SER_CTRL_SEC_SER_PAUSE_QUEUE_SHFT 20 +#define WF_PSE_TOP_PSE_SER_CTRL_MDP_SER_PAUSE_QUEUE_ADDR \ +WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_MDP_SER_PAUSE_QUEUE_MASK \ +0x00080000 /* MDP_SER_PAUSE_QUEUE[19] */ +#define WF_PSE_TOP_PSE_SER_CTRL_MDP_SER_PAUSE_QUEUE_SHFT 19 +#define WF_PSE_TOP_PSE_SER_CTRL_WF_SER_PAUSE_QUEUE_ADDR \ +WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_WF_SER_PAUSE_QUEUE_MASK \ +0x00040000 /* WF_SER_PAUSE_QUEUE[18] */ +#define WF_PSE_TOP_PSE_SER_CTRL_WF_SER_PAUSE_QUEUE_SHFT 18 +#define WF_PSE_TOP_PSE_SER_CTRL_CPU_SER_PAUSE_QUEUE_ADDR \ +WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_CPU_SER_PAUSE_QUEUE_MASK \ +0x00020000 /* CPU_SER_PAUSE_QUEUE[17] */ +#define WF_PSE_TOP_PSE_SER_CTRL_CPU_SER_PAUSE_QUEUE_SHFT 17 +#define WF_PSE_TOP_PSE_SER_CTRL_HIF_SER_PAUSE_QUEUE_ADDR \ +WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_HIF_SER_PAUSE_QUEUE_MASK \ +0x00010000 /* HIF_SER_PAUSE_QUEUE[16] */ +#define WF_PSE_TOP_PSE_SER_CTRL_HIF_SER_PAUSE_QUEUE_SHFT 16 +#define WF_PSE_TOP_PSE_SER_CTRL_PLE_SER_PAUSE_DATA_ADDR \ +WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_PLE_SER_PAUSE_DATA_MASK \ +0x00002000 /* PLE_SER_PAUSE_DATA[13] */ +#define WF_PSE_TOP_PSE_SER_CTRL_PLE_SER_PAUSE_DATA_SHFT 13 +#define WF_PSE_TOP_PSE_SER_CTRL_SEC_SER_PAUSE_DATA_ADDR \ +WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_SEC_SER_PAUSE_DATA_MASK \ +0x00001000 /* SEC_SER_PAUSE_DATA[12] */ +#define WF_PSE_TOP_PSE_SER_CTRL_SEC_SER_PAUSE_DATA_SHFT 12 +#define WF_PSE_TOP_PSE_SER_CTRL_MDP_SER_PAUSE_DATA_ADDR \ +WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_MDP_SER_PAUSE_DATA_MASK \ +0x00000800 /* MDP_SER_PAUSE_DATA[11] */ +#define WF_PSE_TOP_PSE_SER_CTRL_MDP_SER_PAUSE_DATA_SHFT 11 +#define WF_PSE_TOP_PSE_SER_CTRL_WF_SER_PAUSE_DATA_ADDR \ +WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_WF_SER_PAUSE_DATA_MASK \ +0x00000400 /* WF_SER_PAUSE_DATA[10] */ +#define WF_PSE_TOP_PSE_SER_CTRL_WF_SER_PAUSE_DATA_SHFT 10 +#define WF_PSE_TOP_PSE_SER_CTRL_CPU_SER_PAUSE_DATA_ADDR \ +WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_CPU_SER_PAUSE_DATA_MASK \ +0x00000200 /* CPU_SER_PAUSE_DATA[9] */ +#define WF_PSE_TOP_PSE_SER_CTRL_CPU_SER_PAUSE_DATA_SHFT 9 +#define WF_PSE_TOP_PSE_SER_CTRL_HIF_SER_PAUSE_DATA_ADDR \ +WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_HIF_SER_PAUSE_DATA_MASK \ +0x00000100 /* HIF_SER_PAUSE_DATA[8] */ +#define WF_PSE_TOP_PSE_SER_CTRL_HIF_SER_PAUSE_DATA_SHFT 8 +#define WF_PSE_TOP_PSE_SER_CTRL_PLE_SER_PAUSE_ALLOCATE_ADDR \ +WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_PLE_SER_PAUSE_ALLOCATE_MASK \ +0x00000020 /* PLE_SER_PAUSE_ALLOCATE[5] */ +#define WF_PSE_TOP_PSE_SER_CTRL_PLE_SER_PAUSE_ALLOCATE_SHFT 5 +#define WF_PSE_TOP_PSE_SER_CTRL_SEC_SER_PAUSE_ALLOCATE_ADDR \ +WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_SEC_SER_PAUSE_ALLOCATE_MASK \ +0x00000010 /* SEC_SER_PAUSE_ALLOCATE[4] */ +#define WF_PSE_TOP_PSE_SER_CTRL_SEC_SER_PAUSE_ALLOCATE_SHFT 4 +#define WF_PSE_TOP_PSE_SER_CTRL_MDP_SER_PAUSE_ALLOCATE_ADDR \ +WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_MDP_SER_PAUSE_ALLOCATE_MASK \ +0x00000008 /* MDP_SER_PAUSE_ALLOCATE[3] */ +#define WF_PSE_TOP_PSE_SER_CTRL_MDP_SER_PAUSE_ALLOCATE_SHFT 3 +#define WF_PSE_TOP_PSE_SER_CTRL_WF_SER_PAUSE_ALLOCATE_ADDR \ +WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_WF_SER_PAUSE_ALLOCATE_MASK \ +0x00000004 /* WF_SER_PAUSE_ALLOCATE[2] */ +#define WF_PSE_TOP_PSE_SER_CTRL_WF_SER_PAUSE_ALLOCATE_SHFT 2 +#define WF_PSE_TOP_PSE_SER_CTRL_CPU_SER_PAUSE_ALLOCATE_ADDR \ +WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_CPU_SER_PAUSE_ALLOCATE_MASK \ +0x00000002 /* CPU_SER_PAUSE_ALLOCATE[1] */ +#define WF_PSE_TOP_PSE_SER_CTRL_CPU_SER_PAUSE_ALLOCATE_SHFT 1 +#define WF_PSE_TOP_PSE_SER_CTRL_HIF_SER_PAUSE_ALLOCATE_ADDR \ +WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_HIF_SER_PAUSE_ALLOCATE_MASK \ +0x00000001 /* HIF_SER_PAUSE_ALLOCATE[0] */ +#define WF_PSE_TOP_PSE_SER_CTRL_HIF_SER_PAUSE_ALLOCATE_SHFT 0 + +/* +* ---PSE_MBIST_RP_FUSE (0x820C8000 + 0x2b0)--- +* WF_PSE_MBIST_RP_FAIL[3..0] - (RO) MBIST Repair FAIL report +* RESERVED4[7..4] - (RO) Reserved bits +* WF_PSE_MBIST_RP_OK[11..8] - (RO) MBIST Repair OK report +* RESERVED12[14..12] - (RO) Reserved bits +* REG_FUSE_SEL[15] - (RW) MBIST FUSE setting +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_REG_FUSE_SEL_ADDR \ +WF_PSE_TOP_PSE_MBIST_RP_FUSE_ADDR +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_REG_FUSE_SEL_MASK \ +0x00008000 /* REG_FUSE_SEL[15] */ +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_REG_FUSE_SEL_SHFT 15 +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_WF_PSE_MBIST_RP_OK_ADDR \ +WF_PSE_TOP_PSE_MBIST_RP_FUSE_ADDR +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_WF_PSE_MBIST_RP_OK_MASK \ +0x00000F00 /* WF_PSE_MBIST_RP_OK[11..8] */ +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_WF_PSE_MBIST_RP_OK_SHFT 8 +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_WF_PSE_MBIST_RP_FAIL_ADDR \ +WF_PSE_TOP_PSE_MBIST_RP_FUSE_ADDR +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_WF_PSE_MBIST_RP_FAIL_MASK \ +0x0000000F /* WF_PSE_MBIST_RP_FAIL[3..0] */ +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_WF_PSE_MBIST_RP_FAIL_SHFT 0 + +/* +* ---PSE_MBIST_BSEL (0x820C8000 + 0x2b4)--- +* WF_PSE_MBIST_BSEL[15..0] - (RW) Memory MBIST BSEL control +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_MBIST_BSEL_WF_PSE_MBIST_BSEL_ADDR \ +WF_PSE_TOP_PSE_MBIST_BSEL_ADDR +#define WF_PSE_TOP_PSE_MBIST_BSEL_WF_PSE_MBIST_BSEL_MASK \ +0x0000FFFF /* WF_PSE_MBIST_BSEL[15..0] */ +#define WF_PSE_TOP_PSE_MBIST_BSEL_WF_PSE_MBIST_BSEL_SHFT 0 + +/* +* ---PSE_MBIST_RP_FUSE_1 (0x820C8000 + 0x2b8)--- +* WF_UMAC_TOP_MBIST_PREFUSE_0[15..0] - (RW) MBIST PRE-FUSE setting +* WF_UMAC_TOP_MBIST_PREFUSE_D_0[31..16] - (RO) MBIST PRE-FUSE result +*/ +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_1_WF_UMAC_TOP_MBIST_PREFUSE_D_0_ADDR \ +WF_PSE_TOP_PSE_MBIST_RP_FUSE_1_ADDR +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_1_WF_UMAC_TOP_MBIST_PREFUSE_D_0_MASK \ +0xFFFF0000 /* WF_UMAC_TOP_MBIST_PREFUSE_D_0[31..16] */ +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_1_WF_UMAC_TOP_MBIST_PREFUSE_D_0_SHFT 16 +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_1_WF_UMAC_TOP_MBIST_PREFUSE_0_ADDR \ +WF_PSE_TOP_PSE_MBIST_RP_FUSE_1_ADDR +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_1_WF_UMAC_TOP_MBIST_PREFUSE_0_MASK \ +0x0000FFFF /* WF_UMAC_TOP_MBIST_PREFUSE_0[15..0] */ +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_1_WF_UMAC_TOP_MBIST_PREFUSE_0_SHFT 0 + +/* +* ---SRAM_MBIST_BACKGROUND (0x820C8000 + 0x2d0)--- +* MBIST_BACKGROUND[15..0] - (RW) Background setting for PSE SRAM MBIST +circuit +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_SRAM_MBIST_BACKGROUND_MBIST_BACKGROUND_ADDR \ +WF_PSE_TOP_SRAM_MBIST_BACKGROUND_ADDR +#define WF_PSE_TOP_SRAM_MBIST_BACKGROUND_MBIST_BACKGROUND_MASK \ +0x0000FFFF /* MBIST_BACKGROUND[15..0] */ +#define WF_PSE_TOP_SRAM_MBIST_BACKGROUND_MBIST_BACKGROUND_SHFT 0 + +/* +* ---PSE_MISC_FUNC_CTRL (0x820C8000 + 0x2d4)--- +* RESERVED0[7..0] - (RO) Reserved bits +* PSE_QUEUE_ACK_MODE[8] - (RW) Queue ACK mode control +* RESERVED9[29..9] - (RO) Reserved bits +* DIS_BYPASS_INVALID_FID[30] - (RW) Bypass invalid FID control +* DIS_BLOCK_MODE[31] - (RW) Block Mode Control +*/ +#define WF_PSE_TOP_PSE_MISC_FUNC_CTRL_DIS_BLOCK_MODE_ADDR \ +WF_PSE_TOP_PSE_MISC_FUNC_CTRL_ADDR +#define WF_PSE_TOP_PSE_MISC_FUNC_CTRL_DIS_BLOCK_MODE_MASK \ +0x80000000 /* DIS_BLOCK_MODE[31] */ +#define WF_PSE_TOP_PSE_MISC_FUNC_CTRL_DIS_BLOCK_MODE_SHFT 31 +#define WF_PSE_TOP_PSE_MISC_FUNC_CTRL_DIS_BYPASS_INVALID_FID_ADDR \ +WF_PSE_TOP_PSE_MISC_FUNC_CTRL_ADDR +#define WF_PSE_TOP_PSE_MISC_FUNC_CTRL_DIS_BYPASS_INVALID_FID_MASK \ +0x40000000 /* DIS_BYPASS_INVALID_FID[30] */ +#define WF_PSE_TOP_PSE_MISC_FUNC_CTRL_DIS_BYPASS_INVALID_FID_SHFT 30 +#define WF_PSE_TOP_PSE_MISC_FUNC_CTRL_PSE_QUEUE_ACK_MODE_ADDR \ +WF_PSE_TOP_PSE_MISC_FUNC_CTRL_ADDR +#define WF_PSE_TOP_PSE_MISC_FUNC_CTRL_PSE_QUEUE_ACK_MODE_MASK \ +0x00000100 /* PSE_QUEUE_ACK_MODE[8] */ +#define WF_PSE_TOP_PSE_MISC_FUNC_CTRL_PSE_QUEUE_ACK_MODE_SHFT 8 + +/* +* ---SRAM_MBIST_DONE (0x820C8000 + 0x2d8)--- +* MBIST_DONE[0] - (RO) Working status of PSE SRAM MBIST circuit +* RESERVED1[31..1] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_SRAM_MBIST_DONE_MBIST_DONE_ADDR \ +WF_PSE_TOP_SRAM_MBIST_DONE_ADDR +#define WF_PSE_TOP_SRAM_MBIST_DONE_MBIST_DONE_MASK \ +0x00000001 /* MBIST_DONE[0] */ +#define WF_PSE_TOP_SRAM_MBIST_DONE_MBIST_DONE_SHFT 0 + +/* +* ---SRAM_MBIST_FAIL (0x820C8000 + 0x2dc)--- +* FORDLINK_SRAM_MBIST_FAIL[0] - (RO) MBIST check result of forward link SRAM +* BACKLINK_SRAM_MBIST_FAIL[1] - (RO) MBIST check result of backward link SRAM +* PAGELINK_SRAM_MBIST_FAIL[2] - (RO) MBIST check result of PAGELINK SRAM +* RLINFO_SRAM_MBIST_FAIL[3] - (RO) MBIST check result of RLINFO SRAM +* RESERVED4[31..4] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_SRAM_MBIST_FAIL_RLINFO_SRAM_MBIST_FAIL_ADDR \ +WF_PSE_TOP_SRAM_MBIST_FAIL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_FAIL_RLINFO_SRAM_MBIST_FAIL_MASK \ +0x00000008 /* RLINFO_SRAM_MBIST_FAIL[3] */ +#define WF_PSE_TOP_SRAM_MBIST_FAIL_RLINFO_SRAM_MBIST_FAIL_SHFT 3 +#define WF_PSE_TOP_SRAM_MBIST_FAIL_PAGELINK_SRAM_MBIST_FAIL_ADDR \ +WF_PSE_TOP_SRAM_MBIST_FAIL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_FAIL_PAGELINK_SRAM_MBIST_FAIL_MASK \ +0x00000004 /* PAGELINK_SRAM_MBIST_FAIL[2] */ +#define WF_PSE_TOP_SRAM_MBIST_FAIL_PAGELINK_SRAM_MBIST_FAIL_SHFT 2 +#define WF_PSE_TOP_SRAM_MBIST_FAIL_BACKLINK_SRAM_MBIST_FAIL_ADDR \ +WF_PSE_TOP_SRAM_MBIST_FAIL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_FAIL_BACKLINK_SRAM_MBIST_FAIL_MASK \ +0x00000002 /* BACKLINK_SRAM_MBIST_FAIL[1] */ +#define WF_PSE_TOP_SRAM_MBIST_FAIL_BACKLINK_SRAM_MBIST_FAIL_SHFT 1 +#define WF_PSE_TOP_SRAM_MBIST_FAIL_FORDLINK_SRAM_MBIST_FAIL_ADDR \ +WF_PSE_TOP_SRAM_MBIST_FAIL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_FAIL_FORDLINK_SRAM_MBIST_FAIL_MASK \ +0x00000001 /* FORDLINK_SRAM_MBIST_FAIL[0] */ +#define WF_PSE_TOP_SRAM_MBIST_FAIL_FORDLINK_SRAM_MBIST_FAIL_SHFT 0 + +/* +* ---SRAM_MBIST_CTRL (0x820C8000 + 0x2e0)--- +* MBIST_MODE[0] - (RW) Control register for mbist_mode of MBIST +* RESERVED1[3..1] - (RO) Reserved bits +* MBIST_HOLDB[4] - (RW) Control register for mbist_holdb of +MBIST +* RESERVED5[7..5] - (RO) Reserved bits +* MBIST_DEBUG[8] - (RW) Control register for mbist_debug of +MBIST +* MBIST_RPRST_B[9] - (RW) MBIST Repair function Enable +* MBIST_USE_DEFAULT_DELSEL[10] - (RW) MBIST delay select control +* RESERVED11[15..11] - (RO) Reserved bits +* MBIST_DIAG_SEL[19..16] - (RW) Selection register for +mbist_diag_scan_out +* RESERVED20[23..20] - (RO) Reserved bits +* MBIST_SLEEP_TEST[24] - (RW) Control register for sleep_test of MBIST +* MBIST_SLEEP_INV[25] - (RW) Control register for sleep_inv of MBIST +* MBIST_SLEEP_W[26] - (RW) Control register for sleep_w of MBIST +* MBIST_SLEEP_R[27] - (RW) Control register for sleep_r of MBIST +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_SLEEP_R_ADDR \ +WF_PSE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_SLEEP_R_MASK \ +0x08000000 /* MBIST_SLEEP_R[27] */ +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_SLEEP_R_SHFT 27 +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_SLEEP_W_ADDR \ +WF_PSE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_SLEEP_W_MASK \ +0x04000000 /* MBIST_SLEEP_W[26] */ +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_SLEEP_W_SHFT 26 +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_SLEEP_INV_ADDR \ +WF_PSE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_SLEEP_INV_MASK \ +0x02000000 /* MBIST_SLEEP_INV[25] */ +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_SLEEP_INV_SHFT 25 +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_SLEEP_TEST_ADDR \ +WF_PSE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_SLEEP_TEST_MASK \ +0x01000000 /* MBIST_SLEEP_TEST[24] */ +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_SLEEP_TEST_SHFT 24 +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_DIAG_SEL_ADDR \ +WF_PSE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_DIAG_SEL_MASK \ +0x000F0000 /* MBIST_DIAG_SEL[19..16] */ +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_DIAG_SEL_SHFT 16 +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_USE_DEFAULT_DELSEL_ADDR \ +WF_PSE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_USE_DEFAULT_DELSEL_MASK \ +0x00000400 /* MBIST_USE_DEFAULT_DELSEL[10] */ +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_USE_DEFAULT_DELSEL_SHFT 10 +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_RPRST_B_ADDR \ +WF_PSE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_RPRST_B_MASK \ +0x00000200 /* MBIST_RPRST_B[9] */ +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_RPRST_B_SHFT 9 +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_DEBUG_ADDR \ +WF_PSE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_DEBUG_MASK \ +0x00000100 /* MBIST_DEBUG[8] */ +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_DEBUG_SHFT 8 +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_HOLDB_ADDR \ +WF_PSE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_HOLDB_MASK \ +0x00000010 /* MBIST_HOLDB[4] */ +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_HOLDB_SHFT 4 +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_MODE_ADDR \ +WF_PSE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_MODE_MASK \ +0x00000001 /* MBIST_MODE[0] */ +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_MODE_SHFT 0 + +/* +* ---SRAM_MBIST_DELSEL (0x820C8000 + 0x2e4)--- +* MBIST_DELSEL0_2[31..0] - (RW) Control register of delsel for PL SRAM +*/ +#define WF_PSE_TOP_SRAM_MBIST_DELSEL_MBIST_DELSEL0_2_ADDR \ +WF_PSE_TOP_SRAM_MBIST_DELSEL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_DELSEL_MBIST_DELSEL0_2_MASK \ +0xFFFFFFFF /* MBIST_DELSEL0_2[31..0] */ +#define WF_PSE_TOP_SRAM_MBIST_DELSEL_MBIST_DELSEL0_2_SHFT 0 + +/* +* ---SRAM_AWT_HDEN_CTRL (0x820C8000 + 0x2e8)--- +* FL_TBL_AWT1[0] - (RW) Memory AWT Control for FL_TBL1 +* FL_TBL_AWT2[1] - (RW) Memory AWT Control for FL_TBL2 +* PL_TBL_AWT[2] - (RW) Memory AWT Control for PL +* RLINFO_MEM_AWT[3] - (RW) Memory AWT Control for RL +* RESERVED4[15..4] - (RO) Reserved bits +* FL_TBL_HDEN1[16] - (RW) Memory HDEN Control for FL_TBL1 +* FL_TBL_HDEN2[17] - (RW) Memory HDEN Control for FL_TBL2 +* PL_TBL_HDEN[18] - (RW) Memory HDEN Control for PL +* RLINFO_MEM_HDEN[19] - (RW) Memory HDEN Control for RL +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_RLINFO_MEM_HDEN_ADDR \ +WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_ADDR +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_RLINFO_MEM_HDEN_MASK \ +0x00080000 /* RLINFO_MEM_HDEN[19] */ +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_RLINFO_MEM_HDEN_SHFT 19 +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_PL_TBL_HDEN_ADDR \ +WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_ADDR +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_PL_TBL_HDEN_MASK \ +0x00040000 /* PL_TBL_HDEN[18] */ +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_PL_TBL_HDEN_SHFT 18 +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_FL_TBL_HDEN2_ADDR \ +WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_ADDR +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_FL_TBL_HDEN2_MASK \ +0x00020000 /* FL_TBL_HDEN2[17] */ +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_FL_TBL_HDEN2_SHFT 17 +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_FL_TBL_HDEN1_ADDR \ +WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_ADDR +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_FL_TBL_HDEN1_MASK \ +0x00010000 /* FL_TBL_HDEN1[16] */ +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_FL_TBL_HDEN1_SHFT 16 +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_RLINFO_MEM_AWT_ADDR \ +WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_ADDR +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_RLINFO_MEM_AWT_MASK \ +0x00000008 /* RLINFO_MEM_AWT[3] */ +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_RLINFO_MEM_AWT_SHFT 3 +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_PL_TBL_AWT_ADDR \ +WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_ADDR +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_PL_TBL_AWT_MASK \ +0x00000004 /* PL_TBL_AWT[2] */ +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_PL_TBL_AWT_SHFT 2 +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_FL_TBL_AWT2_ADDR \ +WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_ADDR +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_FL_TBL_AWT2_MASK \ +0x00000002 /* FL_TBL_AWT2[1] */ +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_FL_TBL_AWT2_SHFT 1 +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_FL_TBL_AWT1_ADDR \ +WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_ADDR +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_FL_TBL_AWT1_MASK \ +0x00000001 /* FL_TBL_AWT1[0] */ +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_FL_TBL_AWT1_SHFT 0 + +/* +* ---SRAM_MBIST_DELSEL_1 (0x820C8000 + 0x2f0)--- +* MBIST_DELSEL3[31..0] - (RW) Control register of delsel for RLINFO +SRAM +*/ +#define WF_PSE_TOP_SRAM_MBIST_DELSEL_1_MBIST_DELSEL3_ADDR \ +WF_PSE_TOP_SRAM_MBIST_DELSEL_1_ADDR +#define WF_PSE_TOP_SRAM_MBIST_DELSEL_1_MBIST_DELSEL3_MASK \ +0xFFFFFFFF /* MBIST_DELSEL3[31..0] */ +#define WF_PSE_TOP_SRAM_MBIST_DELSEL_1_MBIST_DELSEL3_SHFT 0 + +/* +* ---PSE_SEEK_CR_00 (0x820C8000 + 0x3d0)--- +* PSE_FL_ARB_CS[2..0] - (RO) PSE debug state for FL_ARB_CS +* RESERVED3[3] - (RO) Reserved bits +* PSE_FL_CS[7..4] - (RO) PSE debug state for FL_CS +* PSE_ENQ_FL_CS[11..8] - (RO) PSE debug state for ENQ_FL_CS +* PSE_DEQ_FL_CS[15..12] - (RO) PSE debug state for DEQ_FL_CS +* PSE_ACC_LST_CS[18..16] - (RO) PSE debug state for ACC_LST_CS +* RESERVED19[31..19] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_ACC_LST_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_00_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_ACC_LST_CS_MASK \ +0x00070000 /* PSE_ACC_LST_CS[18..16] */ +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_ACC_LST_CS_SHFT 16 +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_DEQ_FL_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_00_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_DEQ_FL_CS_MASK \ +0x0000F000 /* PSE_DEQ_FL_CS[15..12] */ +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_DEQ_FL_CS_SHFT 12 +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_ENQ_FL_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_00_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_ENQ_FL_CS_MASK \ +0x00000F00 /* PSE_ENQ_FL_CS[11..8] */ +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_ENQ_FL_CS_SHFT 8 +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_FL_CS_ADDR WF_PSE_TOP_PSE_SEEK_CR_00_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_FL_CS_MASK \ +0x000000F0 /* PSE_FL_CS[7..4] */ +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_FL_CS_SHFT 4 +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_FL_ARB_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_00_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_FL_ARB_CS_MASK \ +0x00000007 /* PSE_FL_ARB_CS[2..0] */ +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_FL_ARB_CS_SHFT 0 + +/* +* ---PSE_SEEK_CR_01 (0x820C8000 + 0x3d4)--- +* PSE_PL_ARB_CS[2..0] - (RO) PSE debug state for PL_ARB_CS +* RESERVED3[3] - (RO) Reserved bits +* PSE_PL_INIT_CS[5..4] - (RO) PSE debug state for PL_INIT_CS +* RESERVED6[7..6] - (RO) Reserved bits +* PSE_PL_GNEXT_CS[8] - (RO) PSE debug state for PL_GNEXT_CS +* RESERVED9[11..9] - (RO) Reserved bits +* PSE_PL_GBUF_CS[14..12] - (RO) PSE debug state for PL_GBUF_CS +* RESERVED15[15] - (RO) Reserved bits +* PSE_PL_RLS_CS[17..16] - (RO) PSE debug state for PL_RLS_CS +* RESERVED18[19..18] - (RO) Reserved bits +* PSE_PL_REFILL_CS[22..20] - (RO) PSE debug state for PL_REFILL_CS +* RESERVED23[23] - (RO) Reserved bits +* PSE_RLS_CS[25..24] - (RO) PSE debug state for RLS_CS +* RESERVED26[31..26] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_RLS_CS_ADDR WF_PSE_TOP_PSE_SEEK_CR_01_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_RLS_CS_MASK \ +0x03000000 /* PSE_RLS_CS[25..24] */ +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_RLS_CS_SHFT 24 +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_REFILL_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_01_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_REFILL_CS_MASK \ +0x00700000 /* PSE_PL_REFILL_CS[22..20] */ +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_REFILL_CS_SHFT 20 +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_RLS_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_01_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_RLS_CS_MASK \ +0x00030000 /* PSE_PL_RLS_CS[17..16] */ +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_RLS_CS_SHFT 16 +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_GBUF_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_01_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_GBUF_CS_MASK \ +0x00007000 /* PSE_PL_GBUF_CS[14..12] */ +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_GBUF_CS_SHFT 12 +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_GNEXT_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_01_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_GNEXT_CS_MASK \ +0x00000100 /* PSE_PL_GNEXT_CS[8] */ +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_GNEXT_CS_SHFT 8 +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_INIT_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_01_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_INIT_CS_MASK \ +0x00000030 /* PSE_PL_INIT_CS[5..4] */ +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_INIT_CS_SHFT 4 +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_ARB_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_01_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_ARB_CS_MASK \ +0x00000007 /* PSE_PL_ARB_CS[2..0] */ +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_ARB_CS_SHFT 0 + +/* +* ---PSE_SEEK_CR_02 (0x820C8000 + 0x3d8)--- +* PSE_HIF_DOP_PBUF_CS[2..0] - (RO) PSE debug state for HIF_DOP_PBUF_CS +* RESERVED3[3] - (RO) Reserved bits +* PSE_HIF_DOP_CACHE_CS[5..4] - (RO) PSE debug state for HIF_DOP_CACHE_CS +* RESERVED6[7..6] - (RO) Reserved bits +* PSE_HIF_QOP_Q_OPER_CS[11..8] - (RO) PSE debug state for HIF_QOP_Q_OPER_CS +* PSE_HIF_QOP_RL_OCP_CS[13..12] - (RO) PSE debug state for HIF_QOP_RL_OCP_CS +* RESERVED14[15..14] - (RO) Reserved bits +* PSE_HIF_QOP_PL_OCP_CS[17..16] - (RO) PSE debug state for HIF_QOP_PL_OCP_CS +* RESERVED18[19..18] - (RO) Reserved bits +* PSE_HIF_QOP_ALLOCATE_CS[22..20] - (RO) PSE debug state for +HIF_QOP_ALLOCATE_CS +* RESERVED23[23] - (RO) Reserved bits +* PSE_HIF_RX_DOP_PBUF_CS[26..24] - (RO) PSE debug state for HIF_RX_DOP_PBUF_CS +* RESERVED27[27] - (RO) Reserved bits +* PSE_HIF_RX_DOP_CACHE_CS[29..28] - (RO) PSE debug state for +HIF_RX_DOP_CACHE_CS +* RESERVED30[31..30] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_RX_DOP_CACHE_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_02_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_RX_DOP_CACHE_CS_MASK \ +0x30000000 /* PSE_HIF_RX_DOP_CACHE_CS[29..28] */ +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_RX_DOP_CACHE_CS_SHFT 28 +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_RX_DOP_PBUF_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_02_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_RX_DOP_PBUF_CS_MASK \ +0x07000000 /* PSE_HIF_RX_DOP_PBUF_CS[26..24] */ +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_RX_DOP_PBUF_CS_SHFT 24 +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_QOP_ALLOCATE_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_02_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_QOP_ALLOCATE_CS_MASK \ +0x00700000 /* PSE_HIF_QOP_ALLOCATE_CS[22..20] */ +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_QOP_ALLOCATE_CS_SHFT 20 +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_QOP_PL_OCP_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_02_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_QOP_PL_OCP_CS_MASK \ +0x00030000 /* PSE_HIF_QOP_PL_OCP_CS[17..16] */ +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_QOP_PL_OCP_CS_SHFT 16 +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_QOP_RL_OCP_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_02_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_QOP_RL_OCP_CS_MASK \ +0x00003000 /* PSE_HIF_QOP_RL_OCP_CS[13..12] */ +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_QOP_RL_OCP_CS_SHFT 12 +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_QOP_Q_OPER_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_02_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_QOP_Q_OPER_CS_MASK \ +0x00000F00 /* PSE_HIF_QOP_Q_OPER_CS[11..8] */ +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_QOP_Q_OPER_CS_SHFT 8 +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_DOP_CACHE_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_02_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_DOP_CACHE_CS_MASK \ +0x00000030 /* PSE_HIF_DOP_CACHE_CS[5..4] */ +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_DOP_CACHE_CS_SHFT 4 +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_DOP_PBUF_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_02_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_DOP_PBUF_CS_MASK \ +0x00000007 /* PSE_HIF_DOP_PBUF_CS[2..0] */ +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_DOP_PBUF_CS_SHFT 0 + +/* +* ---PSE_SEEK_CR_03 (0x820C8000 + 0x3dc)--- +* PSE_CPU_DOP_PBUF_CS[2..0] - (RO) PSE debug state for CPU_DOP_PBUF_CS +* RESERVED3[3] - (RO) Reserved bits +* PSE_CPU_DOP_CACHE_CS[5..4] - (RO) PSE debug state for CPU_DOP_CACHE_CS +* RESERVED6[7..6] - (RO) Reserved bits +* PSE_CPU_QOP_Q_OPER_CS[11..8] - (RO) PSE debug state for CPU_QOP_Q_OPER_CS +* PSE_CPU_QOP_RL_OCP_CS[13..12] - (RO) PSE debug state for CPU_QOP_RL_OCP_CS +* RESERVED14[15..14] - (RO) Reserved bits +* PSE_CPU_QOP_PL_OCP_CS[17..16] - (RO) PSE debug state for CPU_QOP_PL_OCP_CS +* RESERVED18[19..18] - (RO) Reserved bits +* PSE_CPU_QOP_ALLOCATE_CS[22..20] - (RO) PSE debug state for +CPU_QOP_ALLOCATE_CS +* RESERVED23[31..23] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_QOP_ALLOCATE_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_03_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_QOP_ALLOCATE_CS_MASK \ +0x00700000 /* PSE_CPU_QOP_ALLOCATE_CS[22..20] */ +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_QOP_ALLOCATE_CS_SHFT 20 +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_QOP_PL_OCP_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_03_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_QOP_PL_OCP_CS_MASK \ +0x00030000 /* PSE_CPU_QOP_PL_OCP_CS[17..16] */ +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_QOP_PL_OCP_CS_SHFT 16 +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_QOP_RL_OCP_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_03_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_QOP_RL_OCP_CS_MASK \ +0x00003000 /* PSE_CPU_QOP_RL_OCP_CS[13..12] */ +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_QOP_RL_OCP_CS_SHFT 12 +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_QOP_Q_OPER_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_03_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_QOP_Q_OPER_CS_MASK \ +0x00000F00 /* PSE_CPU_QOP_Q_OPER_CS[11..8] */ +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_QOP_Q_OPER_CS_SHFT 8 +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_DOP_CACHE_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_03_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_DOP_CACHE_CS_MASK \ +0x00000030 /* PSE_CPU_DOP_CACHE_CS[5..4] */ +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_DOP_CACHE_CS_SHFT 4 +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_DOP_PBUF_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_03_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_DOP_PBUF_CS_MASK \ +0x00000007 /* PSE_CPU_DOP_PBUF_CS[2..0] */ +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_DOP_PBUF_CS_SHFT 0 + +/* +* ---PSE_SEEK_CR_04 (0x820C8000 + 0x3e0)--- +* PSE_WF_DOP_PBUF_CS[2..0] - (RO) PSE debug state for WF_DOP_PBUF_CS +* RESERVED3[3] - (RO) Reserved bits +* PSE_WF_DOP_CACHE_CS[5..4] - (RO) PSE debug state for WF_DOP_CACHE_CS +* RESERVED6[7..6] - (RO) Reserved bits +* PSE_WF_QOP_Q_OPER_CS[11..8] - (RO) PSE debug state for WF_QOP_Q_OPER_CS +* PSE_WF_QOP_RL_OCP_CS[13..12] - (RO) PSE debug state for WF_QOP_RL_OCP_CS +* RESERVED14[15..14] - (RO) Reserved bits +* PSE_WF_QOP_PL_OCP_CS[17..16] - (RO) PSE debug state for WF_QOP_PL_OCP_CS +* RESERVED18[19..18] - (RO) Reserved bits +* PSE_WF_QOP_ALLOCATE_CS[22..20] - (RO) PSE debug state for WF_QOP_ALLOCATE_CS +* RESERVED23[31..23] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_QOP_ALLOCATE_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_04_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_QOP_ALLOCATE_CS_MASK \ +0x00700000 /* PSE_WF_QOP_ALLOCATE_CS[22..20] */ +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_QOP_ALLOCATE_CS_SHFT 20 +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_QOP_PL_OCP_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_04_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_QOP_PL_OCP_CS_MASK \ +0x00030000 /* PSE_WF_QOP_PL_OCP_CS[17..16] */ +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_QOP_PL_OCP_CS_SHFT 16 +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_QOP_RL_OCP_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_04_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_QOP_RL_OCP_CS_MASK \ +0x00003000 /* PSE_WF_QOP_RL_OCP_CS[13..12] */ +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_QOP_RL_OCP_CS_SHFT 12 +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_QOP_Q_OPER_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_04_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_QOP_Q_OPER_CS_MASK \ +0x00000F00 /* PSE_WF_QOP_Q_OPER_CS[11..8] */ +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_QOP_Q_OPER_CS_SHFT 8 +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_DOP_CACHE_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_04_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_DOP_CACHE_CS_MASK \ +0x00000030 /* PSE_WF_DOP_CACHE_CS[5..4] */ +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_DOP_CACHE_CS_SHFT 4 +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_DOP_PBUF_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_04_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_DOP_PBUF_CS_MASK \ +0x00000007 /* PSE_WF_DOP_PBUF_CS[2..0] */ +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_DOP_PBUF_CS_SHFT 0 + +/* +* ---PSE_SEEK_CR_05 (0x820C8000 + 0x3e4)--- +* PSE_MDP_DOP_PBUF_CS[2..0] - (RO) PSE debug state for MDP_DOP_PBUF_CS +* RESERVED3[3] - (RO) Reserved bits +* PSE_MDP_DOP_CACHE_CS[5..4] - (RO) PSE debug state for MDP_DOP_CACHE_CS +* RESERVED6[7..6] - (RO) Reserved bits +* PSE_MDP_QOP_Q_OPER_CS[11..8] - (RO) PSE debug state for MDP_QOP_Q_OPER_CS +* PSE_MDP_QOP_RL_OCP_CS[13..12] - (RO) PSE debug state for MDP_QOP_RL_OCP_CS +* RESERVED14[15..14] - (RO) Reserved bits +* PSE_MDP_QOP_PL_OCP_CS[17..16] - (RO) PSE debug state for MDP_QOP_PL_OCP_CS +* RESERVED18[19..18] - (RO) Reserved bits +* PSE_MDP_QOP_ALLOCATE_CS[22..20] - (RO) PSE debug state for +MDP_QOP_ALLOCATE_CS +* RESERVED23[31..23] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_QOP_ALLOCATE_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_05_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_QOP_ALLOCATE_CS_MASK \ +0x00700000 /* PSE_MDP_QOP_ALLOCATE_CS[22..20] */ +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_QOP_ALLOCATE_CS_SHFT 20 +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_QOP_PL_OCP_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_05_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_QOP_PL_OCP_CS_MASK \ +0x00030000 /* PSE_MDP_QOP_PL_OCP_CS[17..16] */ +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_QOP_PL_OCP_CS_SHFT 16 +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_QOP_RL_OCP_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_05_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_QOP_RL_OCP_CS_MASK \ +0x00003000 /* PSE_MDP_QOP_RL_OCP_CS[13..12] */ +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_QOP_RL_OCP_CS_SHFT 12 +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_QOP_Q_OPER_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_05_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_QOP_Q_OPER_CS_MASK \ +0x00000F00 /* PSE_MDP_QOP_Q_OPER_CS[11..8] */ +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_QOP_Q_OPER_CS_SHFT 8 +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_DOP_CACHE_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_05_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_DOP_CACHE_CS_MASK \ +0x00000030 /* PSE_MDP_DOP_CACHE_CS[5..4] */ +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_DOP_CACHE_CS_SHFT 4 +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_DOP_PBUF_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_05_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_DOP_PBUF_CS_MASK \ +0x00000007 /* PSE_MDP_DOP_PBUF_CS[2..0] */ +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_DOP_PBUF_CS_SHFT 0 + +/* +* ---PSE_SEEK_CR_06 (0x820C8000 + 0x3e8)--- +* PSE_SEC_DOP_PBUF_CS[2..0] - (RO) PSE debug state for SEC_DOP_PBUF_CS +* RESERVED3[3] - (RO) Reserved bits +* PSE_SEC_DOP_CACHE_CS[5..4] - (RO) PSE debug state for SEC_DOP_CACHE_CS +* RESERVED6[7..6] - (RO) Reserved bits +* PSE_SEC_QOP_Q_OPER_CS[11..8] - (RO) PSE debug state for SEC_QOP_Q_OPER_CS +* PSE_SEC_QOP_RL_OCP_CS[13..12] - (RO) PSE debug state for SEC_QOP_RL_OCP_CS +* RESERVED14[15..14] - (RO) Reserved bits +* PSE_SEC_QOP_PL_OCP_CS[17..16] - (RO) PSE debug state for SEC_QOP_PL_OCP_CS +* RESERVED18[19..18] - (RO) Reserved bits +* PSE_SEC_QOP_ALLOCATE_CS[22..20] - (RO) PSE debug state for +SEC_QOP_ALLOCATE_CS +* RESERVED23[31..23] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_QOP_ALLOCATE_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_06_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_QOP_ALLOCATE_CS_MASK \ +0x00700000 /* PSE_SEC_QOP_ALLOCATE_CS[22..20] */ +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_QOP_ALLOCATE_CS_SHFT 20 +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_QOP_PL_OCP_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_06_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_QOP_PL_OCP_CS_MASK \ +0x00030000 /* PSE_SEC_QOP_PL_OCP_CS[17..16] */ +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_QOP_PL_OCP_CS_SHFT 16 +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_QOP_RL_OCP_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_06_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_QOP_RL_OCP_CS_MASK \ +0x00003000 /* PSE_SEC_QOP_RL_OCP_CS[13..12] */ +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_QOP_RL_OCP_CS_SHFT 12 +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_QOP_Q_OPER_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_06_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_QOP_Q_OPER_CS_MASK \ +0x00000F00 /* PSE_SEC_QOP_Q_OPER_CS[11..8] */ +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_QOP_Q_OPER_CS_SHFT 8 +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_DOP_CACHE_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_06_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_DOP_CACHE_CS_MASK \ +0x00000030 /* PSE_SEC_DOP_CACHE_CS[5..4] */ +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_DOP_CACHE_CS_SHFT 4 +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_DOP_PBUF_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_06_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_DOP_PBUF_CS_MASK \ +0x00000007 /* PSE_SEC_DOP_PBUF_CS[2..0] */ +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_DOP_PBUF_CS_SHFT 0 + +/* +* ---PSE_SEEK_CR_07 (0x820C8000 + 0x3ec)--- +* PSE_PLE_DOP_PBUF_CS[2..0] - (RO) PSE debug state for PLE_DOP_PBUF_CS +* RESERVED3[3] - (RO) Reserved bits +* PSE_PLE_DOP_CACHE_CS[5..4] - (RO) PSE debug state for PLE_DOP_CACHE_CS +* RESERVED6[7..6] - (RO) Reserved bits +* PSE_PLE_QOP_Q_OPER_CS[11..8] - (RO) PSE debug state for PLE_QOP_Q_OPER_CS +* PSE_PLE_QOP_RL_OCP_CS[13..12] - (RO) PSE debug state for PLE_QOP_RL_OCP_CS +* RESERVED14[15..14] - (RO) Reserved bits +* PSE_PLE_QOP_PL_OCP_CS[17..16] - (RO) PSE debug state for PLE_QOP_PL_OCP_CS +* RESERVED18[19..18] - (RO) Reserved bits +* PSE_PLE_QOP_ALLOCATE_CS[22..20] - (RO) PSE debug state for +PLE_QOP_ALLOCATE_CS +* RESERVED23[31..23] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_QOP_ALLOCATE_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_07_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_QOP_ALLOCATE_CS_MASK \ +0x00700000 /* PSE_PLE_QOP_ALLOCATE_CS[22..20] */ +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_QOP_ALLOCATE_CS_SHFT 20 +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_QOP_PL_OCP_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_07_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_QOP_PL_OCP_CS_MASK \ +0x00030000 /* PSE_PLE_QOP_PL_OCP_CS[17..16] */ +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_QOP_PL_OCP_CS_SHFT 16 +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_QOP_RL_OCP_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_07_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_QOP_RL_OCP_CS_MASK \ +0x00003000 /* PSE_PLE_QOP_RL_OCP_CS[13..12] */ +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_QOP_RL_OCP_CS_SHFT 12 +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_QOP_Q_OPER_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_07_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_QOP_Q_OPER_CS_MASK \ +0x00000F00 /* PSE_PLE_QOP_Q_OPER_CS[11..8] */ +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_QOP_Q_OPER_CS_SHFT 8 +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_DOP_CACHE_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_07_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_DOP_CACHE_CS_MASK \ +0x00000030 /* PSE_PLE_DOP_CACHE_CS[5..4] */ +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_DOP_CACHE_CS_SHFT 4 +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_DOP_PBUF_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_07_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_DOP_PBUF_CS_MASK \ +0x00000007 /* PSE_PLE_DOP_PBUF_CS[2..0] */ +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_DOP_PBUF_CS_SHFT 0 + +/* +* ---PSE_SEEK_CR_08 (0x820C8000 + 0x3f0)--- +* PSE_AMSDU_DOP_PBUF_CS[2..0] - (RO) PSE debug state for AMSDU_DOP_PBUF_CS +* RESERVED3[3] - (RO) Reserved bits +* PSE_AMSDU_DOP_CACHE_CS[5..4] - (RO) PSE debug state for AMSDU_DOP_CACHE_CS +* RESERVED6[7..6] - (RO) Reserved bits +* CPU_Q_OP_CS[11..8] - (RO) PSE debug state for CPI_Q_OP_CS +* ARB_REQ_CS[14..12] - (RO) PSE debug state for ARB_REQ_CS +* RESERVED15[15] - (RO) Reserved bits +* APB_REQ_CS[18..16] - (RO) PSE debug state for APB_REQ_CS +* RESERVED19[31..19] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_SEEK_CR_08_APB_REQ_CS_ADDR WF_PSE_TOP_PSE_SEEK_CR_08_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_08_APB_REQ_CS_MASK \ +0x00070000 /* APB_REQ_CS[18..16] */ +#define WF_PSE_TOP_PSE_SEEK_CR_08_APB_REQ_CS_SHFT 16 +#define WF_PSE_TOP_PSE_SEEK_CR_08_ARB_REQ_CS_ADDR WF_PSE_TOP_PSE_SEEK_CR_08_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_08_ARB_REQ_CS_MASK \ +0x00007000 /* ARB_REQ_CS[14..12] */ +#define WF_PSE_TOP_PSE_SEEK_CR_08_ARB_REQ_CS_SHFT 12 +#define WF_PSE_TOP_PSE_SEEK_CR_08_CPU_Q_OP_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_08_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_08_CPU_Q_OP_CS_MASK \ +0x00000F00 /* CPU_Q_OP_CS[11..8] */ +#define WF_PSE_TOP_PSE_SEEK_CR_08_CPU_Q_OP_CS_SHFT 8 +#define WF_PSE_TOP_PSE_SEEK_CR_08_PSE_AMSDU_DOP_CACHE_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_08_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_08_PSE_AMSDU_DOP_CACHE_CS_MASK \ +0x00000030 /* PSE_AMSDU_DOP_CACHE_CS[5..4] */ +#define WF_PSE_TOP_PSE_SEEK_CR_08_PSE_AMSDU_DOP_CACHE_CS_SHFT 4 +#define WF_PSE_TOP_PSE_SEEK_CR_08_PSE_AMSDU_DOP_PBUF_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_08_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_08_PSE_AMSDU_DOP_PBUF_CS_MASK \ +0x00000007 /* PSE_AMSDU_DOP_PBUF_CS[2..0] */ +#define WF_PSE_TOP_PSE_SEEK_CR_08_PSE_AMSDU_DOP_PBUF_CS_SHFT 0 + +/* +* ---PSE_SEEK_CR_09 (0x820C8000 + 0x3f4)--- +* RESERVED0[15..0] - (RO) Reserved bits +* DOUBLE_RLS_FID[27..16] - (RO) PSE double RLS FID PAGE +* RESERVED28[30..28] - (RO) Reserved bits +* DOUBLE_RLS_ERROR[31] - (RO) PSE double RLS error flag +*/ +#define WF_PSE_TOP_PSE_SEEK_CR_09_DOUBLE_RLS_ERROR_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_09_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_09_DOUBLE_RLS_ERROR_MASK \ +0x80000000 /* DOUBLE_RLS_ERROR[31] */ +#define WF_PSE_TOP_PSE_SEEK_CR_09_DOUBLE_RLS_ERROR_SHFT 31 +#define WF_PSE_TOP_PSE_SEEK_CR_09_DOUBLE_RLS_FID_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_09_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_09_DOUBLE_RLS_FID_MASK \ +0x0FFF0000 /* DOUBLE_RLS_FID[27..16] */ +#define WF_PSE_TOP_PSE_SEEK_CR_09_DOUBLE_RLS_FID_SHFT 16 + +#ifdef __cplusplus +} +#endif + +#endif /* __WF_PSE_TOP_REGS_H__ */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/mt7915/wf_wfdma_host_dma0.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/mt7915/wf_wfdma_host_dma0.h new file mode 100644 index 0000000000000000000000000000000000000000..1643cb4825ee4a9df41aaf4c078b9675cca2f01f --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/mt7915/wf_wfdma_host_dma0.h @@ -0,0 +1,6185 @@ +/* [File] : wf_wfdma_host_dma0.h */ +/* [Revision time] : Tue Jun 5 14:35:00 2018 */ +/* [Description] : This file is auto generated by CODA */ +/* [Copyright] : Copyright (C) 2018 Mediatek Incorportion. All rights reserved. +*/ + +#ifndef __WF_WFDMA_HOST_DMA0_REGS_H__ +#define __WF_WFDMA_HOST_DMA0_REGS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* ************************************************************************** */ +/* */ +/* WF_WFDMA_HOST_DMA0 CR Definitions */ +/* */ +/* ************************************************************************** */ + +#define WF_WFDMA_HOST_DMA0_BASE 0x7C024000 + +#define WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0XA0) /* 40A0 */ +#define WF_WFDMA_HOST_DMA0_HOST_IF_RX_DONE_STS_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0XA4) /* 40A4 */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_RST_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x100) /* 4100 */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_TOP_MISC_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x104) /* 4104 */ +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0X108) /* 4108 */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x10C) /* 410C */ +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0X110) /* 4110 */ +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0X114) /* 4114 */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DUMMY_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x120) /* 4120 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_DBG_IDX_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x124) /* 4124 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_DBG_PROBE_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x128) /* 4128 */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x12C) /* 412C */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_PROBE_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x130) /* 4130 */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DMASHDL_DBG_PROBE_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x134) /* 4134 */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x138) /* 4138 */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x13c) /* 413C */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_FIFO_TEST_MOD_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x140) /* 4140 */ +#define WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x1E8) /* 41E8 */ +#define WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x1EC) /* 41EC */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x1F0) /* 41F0 */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x1F4) /* 41F4 */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x1F8) /* 41F8 */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x1FC) /* 41FC */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x200) /* 4200 */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0X204) /* 4204 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x208) /* 4208 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x20C) /* 420C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_TX_Q_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x224) /* 4224 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x230) /* 4230 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_MISC_CFG_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x234) /* 4234 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x240) /* 4240 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH10_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x260) /* 4260 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH32_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x264) /* 4264 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH54_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x268) /* 4268 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH76_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x26C) /* 426C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x280) /* 4280 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x284) /* 4284 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_EXT_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x288) /* 4288 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x298) /* 4298 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_DBG0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x2A0) /* 42A0 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_DBG1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x2A4) /* 42A4 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_DBG0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x2A8) /* 42A8 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_DBG1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x2AC) /* 42AC */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x2B0) /* 42B0 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x2B4) /* 42B4 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x2B8) /* 42B8 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x2BC) /* 42BC */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x2C0) /* 42C0 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x2C4) /* 42C4 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x2C8) /* 42C8 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x2CC) /* 42CC */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x2D0) /* 42D0 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x2D4) /* 42D4 */ +#define WF_WFDMA_HOST_DMA0_HOST_PRI_INT_STA_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x2E0) /* 42E0 */ +#define WF_WFDMA_HOST_DMA0_HOST_PER_INT_ENA_STA_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x2E4) /* 42E4 */ +#define WF_WFDMA_HOST_DMA0_HOST_PER_DLY_INT_CFG_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x2E8) /* 42E8 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x2F0) /* 42F0 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x300) /* 4300 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x304) /* 4304 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x308) /* 4308 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x30c) /* 430C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x310) /* 4310 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x314) /* 4314 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x318) /* 4318 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x31c) /* 431C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x320) /* 4320 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x324) /* 4324 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x328) /* 4328 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x32c) /* 432C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x330) /* 4330 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x334) /* 4334 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x338) /* 4338 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x33c) /* 433C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x500) /* 4500 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x504) /* 4504 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x508) /* 4508 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x50c) /* 450C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x510) /* 4510 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x514) /* 4514 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x518) /* 4518 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x51c) /* 451C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x520) /* 4520 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x524) /* 4524 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x528) /* 4528 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x52C) /* 452C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x530) /* 4530 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x534) /* 4534 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x538) /* 4538 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x53C) /* 453C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x600) /* 4600 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x604) /* 4604 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x608) /* 4608 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x60C) /* 460C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x680) /* 4680 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x684) /* 4684 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x688) /* 4688 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x68C) /* 468C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_CFG_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x900) /* 4900 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x904) /* 4904 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x910) /* 4910 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x914) /* 4914 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x918) /* 4918 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA3_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x91C) /* 491C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x920) /* 4920 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x924) /* 4924 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x928) /* 4928 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA3_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x92C) /* 492C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x930) /* 4930 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x934) /* 4934 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x938) /* 4938 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT3_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x93C) /* 493C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT4_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x940) /* 4940 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT5_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x944) /* 4944 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x980) /* 4980 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x984) /* 4984 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x988) /* 4988 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x98C) /* 498C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA4_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x990) /* 4990 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xA00) /* 4A00 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xA04) /* 4A04 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xA08) /* 4A08 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xA10) /* 4A10 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xA14) /* 4A14 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xA18) /* 4A18 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xA20) /* 4A20 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xA24) /* 4A24 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xA28) /* 4A28 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xA30) /* 4A30 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xA34) /* 4A34 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xA38) /* 4A38 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xC00) /* 4C00 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xC04) /* 4C04 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xC08) /* 4C08 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xC10) /* 4C10 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xC14) /* 4C14 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xC18) /* 4C18 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xC20) /* 4C20 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xC24) /* 4C24 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xC28) /* 4C28 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xC30) /* 4C30 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xC34) /* 4C34 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xC38) /* 4C38 */ + + + + +/* +* ---HOST_IF_TX_DONE_STS (0x7C024000 + 0XA0)--- +* fifo_dfet_txdone_dat0_done_sts[0] - (W1C) USB DAT0 FIFO Tx status +* 0 : no tx done +* 1 : pdma fetch data from USB endpoint buffer +* fifo_dfet_txdone_dat1_done_sts[1] - (W1C) USB DAT1 FIFO Tx status +* 0 : no tx done +* 1 : pdma fetch data from USB endpoint buffer +* fifo_dfet_txdone_dat2_done_sts[2] - (W1C) USB DAT2 FIFO Tx status +* 0 : no tx done +* 1 : pdma fetch data from USB endpoint buffer +* fifo_dfet_txdone_dat3_done_sts[3] - (W1C) USB DAT3 FIFO Tx status +* 0 : no tx done +* 1 : pdma fetch data from USB endpoint buffer +* fifo_dfet_txdone_dat4_done_sts[4] - (W1C) USB DAT4 FIFO Tx status +* 0 : no tx done +* 1 : pdma fetch data from USB endpoint buffer +* fifo_dfet_txdone_cmd_done_sts[5] - (W1C) USB CMD FIFO Tx status +* 0 : no tx done +* 1 : pdma fetch data from USB endpoint buffer +* fifo_dfet_txdone_fwdl_done_sts[6] - (W1C) USB Firmware download FIFO Tx status +* 0 : no tx done +* 1 : pdma fetch data from USB endpoint buffer +* SDIO Mode (All SDIO Tx packet goto firmware download FIFO) +* 0 : no tx done +* 1 : pdma start to fetch data from SDIO buffer +* RESERVED7[31..7] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_fwdl_done_sts_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_ADDR +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_fwdl_done_sts_MASK \ + 0x00000040 /* fifo_dfet_txdone_fwdl_done_sts[6] */ +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_fwdl_done_sts_SHFT \ + 6 +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_cmd_done_sts_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_ADDR +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_cmd_done_sts_MASK \ + 0x00000020 /* fifo_dfet_txdone_cmd_done_sts[5] */ +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_cmd_done_sts_SHFT \ + 5 +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat4_done_sts_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_ADDR +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat4_done_sts_MASK \ + 0x00000010 /* fifo_dfet_txdone_dat4_done_sts[4] */ +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat4_done_sts_SHFT \ + 4 +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat3_done_sts_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_ADDR +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat3_done_sts_MASK \ + 0x00000008 /* fifo_dfet_txdone_dat3_done_sts[3] */ +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat3_done_sts_SHFT \ + 3 +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat2_done_sts_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_ADDR +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat2_done_sts_MASK \ + 0x00000004 /* fifo_dfet_txdone_dat2_done_sts[2] */ +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat2_done_sts_SHFT \ + 2 +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat1_done_sts_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_ADDR +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat1_done_sts_MASK \ + 0x00000002 /* fifo_dfet_txdone_dat1_done_sts[1] */ +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat1_done_sts_SHFT \ + 1 +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat0_done_sts_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_ADDR +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat0_done_sts_MASK \ + 0x00000001 /* fifo_dfet_txdone_dat0_done_sts[0] */ +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat0_done_sts_SHFT \ + 0 + +/* +* ---HOST_IF_RX_DONE_STS (0x7C024000 + 0XA4)--- +* rx0_packet_done_sts[0] - (W1C) USB/SDIO Rx0 packet done status +* 0 : no rx packet done +* 1 : rx packet send to host interface +* rx1_packet_done_sts[1] - (W1C) USB/SDIO Rx1 packet done status +* 0 : no rx packet done +* 1 : rx packet send to host interface +* Note : All SDIO Packet send to SIDO RX0 port +* RESERVED2[31..2] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_HOST_IF_RX_DONE_STS_rx1_packet_done_sts_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_IF_RX_DONE_STS_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_IF_RX_DONE_STS_rx1_packet_done_sts_MASK \ + 0x00000002 /* rx1_packet_done_sts[1] */ +#define WF_WFDMA_HOST_DMA0_HOST_IF_RX_DONE_STS_rx1_packet_done_sts_SHFT 1 +#define WF_WFDMA_HOST_DMA0_HOST_IF_RX_DONE_STS_rx0_packet_done_sts_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_IF_RX_DONE_STS_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_IF_RX_DONE_STS_rx0_packet_done_sts_MASK \ + 0x00000001 /* rx0_packet_done_sts[0] */ +#define WF_WFDMA_HOST_DMA0_HOST_IF_RX_DONE_STS_rx0_packet_done_sts_SHFT 0 + +/* +* ---CONN_HIF_RST (0x7C024000 + 0x100)--- +* RESERVED0[3..0] - (RO) Reserved bits +* conn_hif_logic_rst_n[4] - (RW) This conn_hif_logic_rst_n would reset wpdma +* logic partial control register, include Tx/Rx ring control. +* Also, conn_hif_logic_rst_n would reset wifi data path, include tx fifo, rx +* fifo, r2x_bridge, axi_mux and other other asynchronous bridge. +* (Note : conn_hif_logic_rst_n would not reset hif_dmashdl logic) +* dmashdl_all_rst_n[5] - (RW) This dmashdl_all_rst_n would reset +* hif_dmashdl_top, include logic and control register. +* RESERVED6[31..6] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_RST_dmashdl_all_rst_n_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_RST_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_RST_dmashdl_all_rst_n_MASK \ + 0x00000020 /* dmashdl_all_rst_n[5] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_RST_dmashdl_all_rst_n_SHFT 5 +#define WF_WFDMA_HOST_DMA0_CONN_HIF_RST_conn_hif_logic_rst_n_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_RST_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_RST_conn_hif_logic_rst_n_MASK \ + 0x00000010 /* conn_hif_logic_rst_n[4] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_RST_conn_hif_logic_rst_n_SHFT 4 + +/* +* ---CONN_HIF_TOP_MISC (0x7C024000 + 0x104)--- +* ahb_mux_2to1_ultra[1..0] - (RW) conn _hif ahb mux ultra +* ahb_mux_2to1_qos_en[2] - (RW) conn_hif ahb mux qos enable +* RESERVED3[4..3] - (RO) Reserved bits +* axi_cg_in_ck_bypass[5] - (RW) axi frequency bridge bus in clock gating bypass +* 0 : enable clock gating function +* 1 : bypass clock gating function +* axi_cg_out_ck_bypass[6] - (RW) axi frequency bridge bus out clock gating +bypass +* 0 : enable clock gating function +* 1 : bypass clock gating function +* RESERVED7[15..7] - (RO) Reserved bits +* pdma_rxring1_immint_en[16] - (RW) PDMA RX Ring 1 Immediate Interrupt Enable +* RESERVED17[31..17] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_TOP_MISC_pdma_rxring1_immint_en_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_TOP_MISC_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_TOP_MISC_pdma_rxring1_immint_en_MASK \ + 0x00010000 /* pdma_rxring1_immint_en[16] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_TOP_MISC_pdma_rxring1_immint_en_SHFT 16 +#define WF_WFDMA_HOST_DMA0_CONN_HIF_TOP_MISC_axi_cg_out_ck_bypass_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_TOP_MISC_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_TOP_MISC_axi_cg_out_ck_bypass_MASK \ + 0x00000040 /* axi_cg_out_ck_bypass[6] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_TOP_MISC_axi_cg_out_ck_bypass_SHFT 6 +#define WF_WFDMA_HOST_DMA0_CONN_HIF_TOP_MISC_axi_cg_in_ck_bypass_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_TOP_MISC_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_TOP_MISC_axi_cg_in_ck_bypass_MASK \ + 0x00000020 /* axi_cg_in_ck_bypass[5] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_TOP_MISC_axi_cg_in_ck_bypass_SHFT 5 +#define WF_WFDMA_HOST_DMA0_CONN_HIF_TOP_MISC_ahb_mux_2to1_qos_en_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_TOP_MISC_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_TOP_MISC_ahb_mux_2to1_qos_en_MASK \ + 0x00000004 /* ahb_mux_2to1_qos_en[2] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_TOP_MISC_ahb_mux_2to1_qos_en_SHFT 2 +#define WF_WFDMA_HOST_DMA0_CONN_HIF_TOP_MISC_ahb_mux_2to1_ultra_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_TOP_MISC_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_TOP_MISC_ahb_mux_2to1_ultra_MASK \ + 0x00000003 /* ahb_mux_2to1_ultra[1..0] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_TOP_MISC_ahb_mux_2to1_ultra_SHFT 0 + +/* +* ---HOST2MCU_SW_INT_SET (0x7C024000 + 0X108)--- +* host2mcu_sw_int_0_set[0] - (WO) Driver set this bit to generate MCU interrupt +* and 0x5000_0110[0] will be set to 1. +* host2mcu_sw_int_1_set[1] - (WO) Driver set this bit to generate MCU interrupt +* and 0x5000_0110[1] will be set to 1. +* host2mcu_sw_int_2_set[2] - (WO) Driver set this bit to generate MCU interrupt +* and 0x5000_0110[2] will be set to 1. +* host2mcu_sw_int_3_set[3] - (WO) Driver set [0x0_4108] bit[3] to generate MCU +* interrupt and 0x5000_0110[3] will be set to 1. +* host2mcu_sw_int_4_set[4] - (WO) Driver set [0x0_4108] bit[4] to generate MCU +* interrupt and 0x5000_0110[4] will be set to 1. +* host2mcu_sw_int_5_set[5] - (WO) Driver set [0x0_4108] bit[5] to generate MCU +* interrupt and 0x5000_0110[5] will be set to 1. +* host2mcu_sw_int_6_set[6] - (WO) Driver set [0x0_4108] bit[6] to generate MCU +* interrupt and 0x5000_0110[6] will be set to 1. +* host2mcu_sw_int_7_set[7] - (WO) Driver set [0x0_4108] bit[7] to generate MCU +* interrupt and 0x5000_0110[7] will be set to 1. +* RESERVED8[31..8] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_7_set_ADDR \ + WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_7_set_MASK \ + 0x00000080 /* host2mcu_sw_int_7_set[7] */ +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_7_set_SHFT 7 +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_6_set_ADDR \ + WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_6_set_MASK \ + 0x00000040 /* host2mcu_sw_int_6_set[6] */ +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_6_set_SHFT 6 +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_5_set_ADDR \ + WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_5_set_MASK \ + 0x00000020 /* host2mcu_sw_int_5_set[5] */ +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_5_set_SHFT 5 +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_4_set_ADDR \ + WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_4_set_MASK \ + 0x00000010 /* host2mcu_sw_int_4_set[4] */ +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_4_set_SHFT 4 +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_3_set_ADDR \ + WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_3_set_MASK \ + 0x00000008 /* host2mcu_sw_int_3_set[3] */ +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_3_set_SHFT 3 +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_2_set_ADDR \ + WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_2_set_MASK \ + 0x00000004 /* host2mcu_sw_int_2_set[2] */ +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_2_set_SHFT 2 +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_1_set_ADDR \ + WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_1_set_MASK \ + 0x00000002 /* host2mcu_sw_int_1_set[1] */ +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_1_set_SHFT 1 +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_0_set_ADDR \ + WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_0_set_MASK \ + 0x00000001 /* host2mcu_sw_int_0_set[0] */ +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_0_set_SHFT 0 + +/* +* ---MCU2HOST_SW_INT_SET (0x7C024000 + 0x10C)--- +* mcu2host_sw_int_set_0[0] - (WO) Internal CPU writes this register will trigger +* MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[0] to check interrupt status +* mcu2host_sw_int_set_1[1] - (WO) Internal CPU writes this register will trigger +* MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[1] to check interrupt status +* mcu2host_sw_int_set_2[2] - (WO) Internal CPU writes this register will trigger +* MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[2] to check interrupt status +* mcu2host_sw_int_set_3[3] - (WO) Internal CPU writes this register will trigger +* MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[3] to check interrupt status +* mcu2host_sw_int_set_4[4] - (WO) Internal CPU writes this register will trigger +* MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[4] to check interrupt status +* mcu2host_sw_int_set_5[5] - (WO) Internal CPU writes this register will trigger +* MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[5] to check interrupt status +* mcu2host_sw_int_set_6[6] - (WO) Internal CPU writes this register will trigger +* MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[6] to check interrupt status +* mcu2host_sw_int_set_7[7] - (WO) Internal CPU writes this register will trigger +* MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[7] to check interrupt status +* mcu2host_sw_int_set_8[8] - (WO) Internal CPU writes this register will trigger +* MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[0] to check interrupt status +* mcu2host_sw_int_set_9[9] - (WO) Internal CPU writes this register will trigger +* MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[1] to check interrupt status +* mcu2host_sw_int_set_10[10] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[2] to check interrupt status +* mcu2host_sw_int_set_11[11] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[3] to check interrupt status +* mcu2host_sw_int_set_12[12] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[4] to check interrupt status +* mcu2host_sw_int_set_13[13] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[5] to check interrupt status +* mcu2host_sw_int_set_14[14] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[6] to check interrupt status +* mcu2host_sw_int_set_15[15] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[7] to check interrupt status +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_15_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_15_MASK \ + 0x00008000 /* mcu2host_sw_int_set_15[15] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_15_SHFT 15 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_14_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_14_MASK \ + 0x00004000 /* mcu2host_sw_int_set_14[14] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_14_SHFT 14 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_13_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_13_MASK \ + 0x00002000 /* mcu2host_sw_int_set_13[13] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_13_SHFT 13 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_12_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_12_MASK \ + 0x00001000 /* mcu2host_sw_int_set_12[12] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_12_SHFT 12 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_11_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_11_MASK \ + 0x00000800 /* mcu2host_sw_int_set_11[11] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_11_SHFT 11 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_10_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_10_MASK \ + 0x00000400 /* mcu2host_sw_int_set_10[10] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_10_SHFT 10 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_9_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_9_MASK \ + 0x00000200 /* mcu2host_sw_int_set_9[9] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_9_SHFT 9 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_8_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_8_MASK \ + 0x00000100 /* mcu2host_sw_int_set_8[8] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_8_SHFT 8 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_7_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_7_MASK \ + 0x00000080 /* mcu2host_sw_int_set_7[7] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_7_SHFT 7 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_6_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_6_MASK \ + 0x00000040 /* mcu2host_sw_int_set_6[6] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_6_SHFT 6 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_5_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_5_MASK \ + 0x00000020 /* mcu2host_sw_int_set_5[5] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_5_SHFT 5 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_4_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_4_MASK \ + 0x00000010 /* mcu2host_sw_int_set_4[4] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_4_SHFT 4 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_3_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_3_MASK \ + 0x00000008 /* mcu2host_sw_int_set_3[3] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_3_SHFT 3 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_2_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_2_MASK \ + 0x00000004 /* mcu2host_sw_int_set_2[2] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_2_SHFT 2 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_1_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_1_MASK \ + 0x00000002 /* mcu2host_sw_int_set_1[1] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_1_SHFT 1 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_0_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_0_MASK \ + 0x00000001 /* mcu2host_sw_int_set_0[0] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_0_SHFT 0 + +/* +* ---MCU_INT_STA (0x7C024000 + 0X110)--- +* host2mcu_sw_int_sts[7..0] - (W1C) MCU interrupt status, write 1 to clear the +interrupt +* wpdma_tx_timeout_int_sts[8] - (W1C) WPDMA TX dma timeout interrupt stauts, +* write 1 to clear the interrupt +* wpdma_rx_timeout_int_sts[9] - (W1C) WPDMA RX dma timeout interrupt stauts, +* write 1 to clear the interrupt +* wifi_txfifo0_wr_ovf_int_sts[10] - (W1C) conn_hif txfifo erorr detec +* interruptt. It indicate tx-fifo memory write overflow. +* wifi_txfifo1_wr_ovf_int_sts[11] - (W1C) conn_hif txfifo erorr detec +* interruptt. It indicate tx-fifo memory write overflow. +* wifi_rxfifo_wr_ovf_int_sts[12] - (W1C) conn_hif rxfifo erorr detect interrupt. +* It indicate rx-fifo memory write overflow. +* wpdma_tx_dmad_mem_range_err_mcu_int_sts[13] - (W1C) WPDMA tx dma descriptor +* memory range error detection mcu interrupt status +* When user setup WPDMA_TX_DMAD_RNG (not equal to zero), design would check +* tx_dmad address. If address range not correct, it would alarm memory range +* error interrupt +* wpdma_rx_dmad_mem_range_err_mcu_int_sts[14] - (W1C) WPDMA rx dma descriptor +* memory range error detection mcu interrupt status +* When user setup WPDMA_RX_DMAD_RNG (not equal to zero), design would check +* rx_dmad address. If address range not correct, it would alarm memory range +* error interrupt +* wpdma_tx_payload_mem_range_err_mcu_int_sts[15] - (W1C) WPDMA tx payload memory +* range error detection mcu interrupt status +* When user setup WPDMA_TX_PLD_RNG (not equal to zero), design would check +* tx_dma payload address. If address range not correct, it would alarm memory +* range error interrupt +* wpdma_rx_payload_mem_range_err_mcu_int_sts[16] - (W1C) WPDMA rx payload memory +* range error detection mcu interrupt status +* When user setup WPDMA_RX_PLD_RNG (not equal to zero), design would check +* rx_dma payload address. If address range not correct, it would alarm memory +* range error interrupt +* RESERVED17[31..17] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_rx_payload_mem_range_err_mcu_int_sts_ADDR \ + WF_WFDMA_HOST_DMA0_MCU_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_rx_payload_mem_range_err_mcu_int_sts_MASK \ + 0x00010000 /* wpdma_rx_payload_mem_range_err_mcu_int_sts[16] */ +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_rx_payload_mem_range_err_mcu_int_sts_SHFT \ + 16 +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_tx_payload_mem_range_err_mcu_int_sts_ADDR \ + WF_WFDMA_HOST_DMA0_MCU_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_tx_payload_mem_range_err_mcu_int_sts_MASK \ + 0x00008000 /* wpdma_tx_payload_mem_range_err_mcu_int_sts[15] */ +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_tx_payload_mem_range_err_mcu_int_sts_SHFT \ + 15 +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_rx_dmad_mem_range_err_mcu_int_sts_ADDR \ + WF_WFDMA_HOST_DMA0_MCU_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_rx_dmad_mem_range_err_mcu_int_sts_MASK \ + 0x00004000 /* wpdma_rx_dmad_mem_range_err_mcu_int_sts[14] */ +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_rx_dmad_mem_range_err_mcu_int_sts_SHFT \ + 14 +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_tx_dmad_mem_range_err_mcu_int_sts_ADDR \ + WF_WFDMA_HOST_DMA0_MCU_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_tx_dmad_mem_range_err_mcu_int_sts_MASK \ + 0x00002000 /* wpdma_tx_dmad_mem_range_err_mcu_int_sts[13] */ +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_tx_dmad_mem_range_err_mcu_int_sts_SHFT \ + 13 +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wifi_rxfifo_wr_ovf_int_sts_ADDR \ + WF_WFDMA_HOST_DMA0_MCU_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wifi_rxfifo_wr_ovf_int_sts_MASK \ + 0x00001000 /* wifi_rxfifo_wr_ovf_int_sts[12] */ +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wifi_rxfifo_wr_ovf_int_sts_SHFT 12 +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wifi_txfifo1_wr_ovf_int_sts_ADDR \ + WF_WFDMA_HOST_DMA0_MCU_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wifi_txfifo1_wr_ovf_int_sts_MASK \ + 0x00000800 /* wifi_txfifo1_wr_ovf_int_sts[11] */ +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wifi_txfifo1_wr_ovf_int_sts_SHFT 11 +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wifi_txfifo0_wr_ovf_int_sts_ADDR \ + WF_WFDMA_HOST_DMA0_MCU_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wifi_txfifo0_wr_ovf_int_sts_MASK \ + 0x00000400 /* wifi_txfifo0_wr_ovf_int_sts[10] */ +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wifi_txfifo0_wr_ovf_int_sts_SHFT 10 +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_rx_timeout_int_sts_ADDR \ + WF_WFDMA_HOST_DMA0_MCU_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_rx_timeout_int_sts_MASK \ + 0x00000200 /* wpdma_rx_timeout_int_sts[9] */ +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_rx_timeout_int_sts_SHFT 9 +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_tx_timeout_int_sts_ADDR \ + WF_WFDMA_HOST_DMA0_MCU_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_tx_timeout_int_sts_MASK \ + 0x00000100 /* wpdma_tx_timeout_int_sts[8] */ +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_tx_timeout_int_sts_SHFT 8 +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_host2mcu_sw_int_sts_ADDR \ + WF_WFDMA_HOST_DMA0_MCU_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_host2mcu_sw_int_sts_MASK \ + 0x000000FF /* host2mcu_sw_int_sts[7..0] */ +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_host2mcu_sw_int_sts_SHFT 0 + +/* +* ---MCU_INT_ENA (0x7C024000 + 0X114)--- +* host2mcu_sw_int_ena[7..0] - (RW) host2mcu interrupt enable +* wpdma_tx_dma_timeout_int_ena[8] - (RW) WPDMA TX error detection interrupt +enable +* wpdma_rx_dma_timeout_int_ena[9] - (RW) WPDMA RX error detection interrupt +enable +* wifi_txfifo0_wr_ovf_int_ena[10] - (RW) conn_hif txfifo erorr detect interrupt +enable. +* wifi_txfifo1_wr_ovf_int_ena[11] - (RW) conn_hif txfifo erorr detect interrupt +enable. +* wifi_rxfifo_wr_ovf_int_ena[12] - (RW) conn_hif rxfifo erorr detect interrupt +enable. +* wpdma_tx_dmad_mem_range_err_mcu_int_ena[13] - (RW) WPDMA tx dma descriptor +* memory range error detection interrupt enable +* wpdma_rx_dmad_mem_range_err_mcu_int_ena[14] - (RW) WPDMA rx dma descriptor +* memory range error detection interrupt enable +* wpdma_tx_payload_mem_range_err_mcu_int_ena[15] - (RW) WPDMA tx payload memory +* range error detection interrupt enable +* wpdma_rx_payload_mem_range_err_mcu_int_ena[16] - (RW) WPDMA rx payload memory +* range error detection interrupt enable +* RESERVED17[31..17] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_rx_payload_mem_range_err_mcu_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_MCU_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_rx_payload_mem_range_err_mcu_int_ena_MASK \ + 0x00010000 /* wpdma_rx_payload_mem_range_err_mcu_int_ena[16] */ +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_rx_payload_mem_range_err_mcu_int_ena_SHFT \ + 16 +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_tx_payload_mem_range_err_mcu_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_MCU_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_tx_payload_mem_range_err_mcu_int_ena_MASK \ + 0x00008000 /* wpdma_tx_payload_mem_range_err_mcu_int_ena[15] */ +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_tx_payload_mem_range_err_mcu_int_ena_SHFT \ + 15 +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_rx_dmad_mem_range_err_mcu_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_MCU_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_rx_dmad_mem_range_err_mcu_int_ena_MASK \ + 0x00004000 /* wpdma_rx_dmad_mem_range_err_mcu_int_ena[14] */ +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_rx_dmad_mem_range_err_mcu_int_ena_SHFT \ + 14 +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_tx_dmad_mem_range_err_mcu_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_MCU_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_tx_dmad_mem_range_err_mcu_int_ena_MASK \ + 0x00002000 /* wpdma_tx_dmad_mem_range_err_mcu_int_ena[13] */ +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_tx_dmad_mem_range_err_mcu_int_ena_SHFT \ + 13 +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wifi_rxfifo_wr_ovf_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_MCU_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wifi_rxfifo_wr_ovf_int_ena_MASK \ + 0x00001000 /* wifi_rxfifo_wr_ovf_int_ena[12] */ +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wifi_rxfifo_wr_ovf_int_ena_SHFT 12 +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wifi_txfifo1_wr_ovf_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_MCU_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wifi_txfifo1_wr_ovf_int_ena_MASK \ + 0x00000800 /* wifi_txfifo1_wr_ovf_int_ena[11] */ +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wifi_txfifo1_wr_ovf_int_ena_SHFT 11 +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wifi_txfifo0_wr_ovf_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_MCU_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wifi_txfifo0_wr_ovf_int_ena_MASK \ + 0x00000400 /* wifi_txfifo0_wr_ovf_int_ena[10] */ +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wifi_txfifo0_wr_ovf_int_ena_SHFT 10 +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_rx_dma_timeout_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_MCU_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_rx_dma_timeout_int_ena_MASK \ + 0x00000200 /* wpdma_rx_dma_timeout_int_ena[9] */ +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_rx_dma_timeout_int_ena_SHFT 9 +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_tx_dma_timeout_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_MCU_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_tx_dma_timeout_int_ena_MASK \ + 0x00000100 /* wpdma_tx_dma_timeout_int_ena[8] */ +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_tx_dma_timeout_int_ena_SHFT 8 +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_host2mcu_sw_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_MCU_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_host2mcu_sw_int_ena_MASK \ + 0x000000FF /* host2mcu_sw_int_ena[7..0] */ +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_host2mcu_sw_int_ena_SHFT 0 + +/* +* ---CONN_HIF_DUMMY (0x7C024000 + 0x120)--- +* CONN_HIF_DUMMY[31..0] - (RW) Reserved CR, SE will use it for pcie calibration! +*/ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DUMMY_CONN_HIF_DUMMY_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_DUMMY_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DUMMY_CONN_HIF_DUMMY_MASK \ + 0xFFFFFFFF /* CONN_HIF_DUMMY[31..0] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DUMMY_CONN_HIF_DUMMY_SHFT 0 + +/* +* ---WPDMA_DBG_IDX (0x7C024000 + 0x124)--- +* PDMA_DBG_IDX[7..0] - (RW) PDMA debug index +* PDMA_DBG_Enable[8] - (RW) PDMA Debug Enable +* 0: PDMA_DBG_port would has no function +* 1 : PDMA DBG_IDX select PDMA debug flag index +* RESERVED9[31..9] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_DBG_IDX_PDMA_DBG_Enable_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_DBG_IDX_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_DBG_IDX_PDMA_DBG_Enable_MASK \ + 0x00000100 /* PDMA_DBG_Enable[8] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_DBG_IDX_PDMA_DBG_Enable_SHFT 8 +#define WF_WFDMA_HOST_DMA0_WPDMA_DBG_IDX_PDMA_DBG_IDX_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_DBG_IDX_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_DBG_IDX_PDMA_DBG_IDX_MASK \ + 0x000000FF /* PDMA_DBG_IDX[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_DBG_IDX_PDMA_DBG_IDX_SHFT 0 + +/* +* ---WPDMA_DBG_PROBE (0x7C024000 + 0x128)--- +* PDMA_DBG_PROBE[31..0] - (RO) PDMA Debug probe read +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_DBG_PROBE_PDMA_DBG_PROBE_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_DBG_PROBE_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_DBG_PROBE_PDMA_DBG_PROBE_MASK \ + 0xFFFFFFFF /* PDMA_DBG_PROBE[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_DBG_PROBE_PDMA_DBG_PROBE_SHFT 0 + +/* +* ---CONN_HIF_DBG_IDX (0x7C024000 + 0x12C)--- +* conn_hif_dbg_byt0_sel[2..0] - (RW) conn_hif_dbg_byt0_sel : Select +* conn_hif_dbg[7:0] from "pdma_dbg"/"hif_dmashdl_top" +* conn_hif_dbg_byt1_sel[5..3] - (RW) conn_hif_dbg_byt1_sel : Select +* conn_hif_dbg[15:8] from "pdma_dbg"/"hif_dmashdl_top" +* conn_hif_dbg_byt2_sel[8..6] - (RW) conn_hif_dbg_byt2_sel : Select +* conn_hif_dbg[23:16] from "pdma_dbg"/"hif_dmashdl_top" +* conn_hif_dbg_byt3_sel[11..9] - (RW) conn_hif_dbg_byt3_sel : Select +* conn_hif_dbg[31:24] from "pdma_dbg"/"hif_dmashdl_top" +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_conn_hif_dbg_byt3_sel_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_conn_hif_dbg_byt3_sel_MASK \ + 0x00000E00 /* conn_hif_dbg_byt3_sel[11..9] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_conn_hif_dbg_byt3_sel_SHFT 9 +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_conn_hif_dbg_byt2_sel_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_conn_hif_dbg_byt2_sel_MASK \ + 0x000001C0 /* conn_hif_dbg_byt2_sel[8..6] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_conn_hif_dbg_byt2_sel_SHFT 6 +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_conn_hif_dbg_byt1_sel_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_conn_hif_dbg_byt1_sel_MASK \ + 0x00000038 /* conn_hif_dbg_byt1_sel[5..3] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_conn_hif_dbg_byt1_sel_SHFT 3 +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_conn_hif_dbg_byt0_sel_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_conn_hif_dbg_byt0_sel_MASK \ + 0x00000007 /* conn_hif_dbg_byt0_sel[2..0] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_conn_hif_dbg_byt0_sel_SHFT 0 + +/* +* ---CONN_HIF_DBG_PROBE (0x7C024000 + 0x130)--- +* conn_hif_dbg_probe[31..0] - (RO) conn_hif_dbg_probe read +*/ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_PROBE_conn_hif_dbg_probe_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_PROBE_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_PROBE_conn_hif_dbg_probe_MASK \ + 0xFFFFFFFF /* conn_hif_dbg_probe[31..0] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_PROBE_conn_hif_dbg_probe_SHFT 0 + +/* +* ---CONN_HIF_DMASHDL_DBG_PROBE (0x7C024000 + 0x134)--- +* DMASHDL_DBG_PROBE[15..0] - (RO) conn_hif_dmashdl_dbg_probe read +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DMASHDL_DBG_PROBE_DMASHDL_DBG_PROBE_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_DMASHDL_DBG_PROBE_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DMASHDL_DBG_PROBE_DMASHDL_DBG_PROBE_MASK \ + 0x0000FFFF /* DMASHDL_DBG_PROBE[15..0] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DMASHDL_DBG_PROBE_DMASHDL_DBG_PROBE_SHFT 0 + +/* +* ---CONN_HIF_BUSY_STATUS (0x7C024000 + 0x138)--- +* conn_hif_txfifo0_busy[0] - (RO) conn_hif txfifo0 busy status +* 0 : txfifo empty +* 1 : txfifo non empty +* conn_hif_txfifo1_busy[1] - (RO) conn_hif txfifo1 busy status +* 0 : txfifo empty +* 1 : txfifo non empty +* conn_hif_rxfifo_busy[2] - (RO) conn_hif rxfifo busy status +* 0 : rxfifo empty +* 1 : rxfifo non empty +* RESERVED[30..3] - (RO) Reserved CR +* conn_hif_busy[31] - (RO) Over all conn_hif busy status, it was busy summation +* of bit[6] ~ bit[0] status +*/ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_conn_hif_busy_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_conn_hif_busy_MASK \ + 0x80000000 /* conn_hif_busy[31] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_conn_hif_busy_SHFT 31 +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_conn_hif_rxfifo_busy_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_conn_hif_rxfifo_busy_MASK \ + 0x00000004 /* conn_hif_rxfifo_busy[2] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_conn_hif_rxfifo_busy_SHFT 2 +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_conn_hif_txfifo1_busy_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_conn_hif_txfifo1_busy_MASK \ + 0x00000002 /* conn_hif_txfifo1_busy[1] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_conn_hif_txfifo1_busy_SHFT 1 +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_conn_hif_txfifo0_busy_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_conn_hif_txfifo0_busy_MASK \ + 0x00000001 /* conn_hif_txfifo0_busy[0] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_conn_hif_txfifo0_busy_SHFT 0 + +/* +* ---CONN_HIF_BUSY_ENA (0x7C024000 + 0x13c)--- +* conn_hif_txfifo0_busy_enable[0] - (RW) busy enable control +* 0: ignore busy status +* 1: conn_hif_busy would tack care busy status +* conn_hif_txfifo1_busy_enable[1] - (RW) busy enable control +* 0: ignore busy status +* 1: conn_hif_busy would tack care busy status +* conn_hif_rxfifo_busy_enable[2] - (RW) busy enable control +* 0: ignore busy status +* 1: conn_hif_busy would tack care busy status +* axi_mx4to1_w_busy_enable[3] - (RW) busy enable control +* 0: ignore busy status +* 1: conn_hif_busy would tack care busy status +* axi_mx4to1_r_busy_enable[4] - (RW) busy enable control +* 0: ignore busy status +* 1: conn_hif_busy would tack care busy status +* RESERVED[31..5] - (RW) Reserved CR +*/ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_axi_mx4to1_r_busy_enable_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_axi_mx4to1_r_busy_enable_MASK \ + 0x00000010 /* axi_mx4to1_r_busy_enable[4] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_axi_mx4to1_r_busy_enable_SHFT 4 +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_axi_mx4to1_w_busy_enable_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_axi_mx4to1_w_busy_enable_MASK \ + 0x00000008 /* axi_mx4to1_w_busy_enable[3] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_axi_mx4to1_w_busy_enable_SHFT 3 +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_conn_hif_rxfifo_busy_enable_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_conn_hif_rxfifo_busy_enable_MASK \ + 0x00000004 /* conn_hif_rxfifo_busy_enable[2] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_conn_hif_rxfifo_busy_enable_SHFT 2 +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_conn_hif_txfifo1_busy_enable_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_conn_hif_txfifo1_busy_enable_MASK \ + 0x00000002 /* conn_hif_txfifo1_busy_enable[1] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_conn_hif_txfifo1_busy_enable_SHFT 1 +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_conn_hif_txfifo0_busy_enable_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_conn_hif_txfifo0_busy_enable_MASK \ + 0x00000001 /* conn_hif_txfifo0_busy_enable[0] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_conn_hif_txfifo0_busy_enable_SHFT 0 + +/* +* ---CONN_HIF_FIFO_TEST_MOD (0x7C024000 + 0x140)--- +* csr_wfdma_loopback_en[0] - (RW) conn_hif fifo loopback enable +* NOTICE : when loopback, OMIT_TX_INFO and OMIT_RX_INFO sould be both set to +1'b1 +* csr_wfdma_loopback_qsel[2..1] - (RW) No USE for (conn_hif fifo loopback packet +* go into Rx-ring number) +* RESERVED3[31..3] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_FIFO_TEST_MOD_csr_wfdma_loopback_qsel_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_FIFO_TEST_MOD_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_FIFO_TEST_MOD_csr_wfdma_loopback_qsel_MASK \ + 0x00000006 /* csr_wfdma_loopback_qsel[2..1] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_FIFO_TEST_MOD_csr_wfdma_loopback_qsel_SHFT 1 +#define WF_WFDMA_HOST_DMA0_CONN_HIF_FIFO_TEST_MOD_csr_wfdma_loopback_en_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_FIFO_TEST_MOD_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_FIFO_TEST_MOD_csr_wfdma_loopback_en_MASK \ + 0x00000001 /* csr_wfdma_loopback_en[0] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_FIFO_TEST_MOD_csr_wfdma_loopback_en_SHFT 0 + +/* +* ---WPDMA2HOST_ERR_INT_STA (0x7C024000 + 0x1E8)--- +* wpdma_tx_timeout_int_sts[0] - (W1C) WPDMA TX error detection interrupt stauts, +* write 1 to clear the interrupt +* wpdma_rx_timeout_int_sts[1] - (W1C) WPDMA RX error detection interrupt stauts, +* write 1 to clear the interrupt +* wpdma_tx_dmad_mem_range_err_int_sts[2] - (W1C) WPDMA tx dma descriptor memory +* range error detection interrupt status +* When user setup WPDMA_TX_DMAD_RNG (not equal to zero), design would check +* tx_dmad address. If address range not correct, it would alarm memory range +* error interrupt +* wpdma_rx_dmad_mem_range_err_int_sts[3] - (W1C) WPDMA rx dma descriptor memory +* range error detection interrupt status +* When user setup WPDMA_RX_DMAD_RNG (not equal to zero), design would check +* rx_dmad address. If address range not correct, it would alarm memory range +* error interrupt +* wpdma_tx_payload_mem_range_err_int_sts[4] - (W1C) WPDMA tx payload memory +* range error detection interrupt status +* When user setup WPDMA_TX_PLD_RNG (not equal to zero), design would check +* tx_dma payload address. If address range not correct, it would alarm memory +* range error interrupt +* wpdma_rx_payload_mem_range_err_int_sts[5] - (W1C) WPDMA rx payload memory +* range error detection interrupt status +* When user setup WPDMA_RX_PLD_RNG (not equal to zero), design would check +* rx_dma payload address. If address range not correct, it would alarm memory +* range error interrupt +* wpdma_axi_bresp_error_int_sts[6] - (W1C) WPDMA AXI master bresp error +* detection interrupt status, check WPDMA_AXI_MST_DBG1 for error information +* wpdma_axi_rresp_error_int_sts[7] - (W1C) WPDMA AXI master rresp error +* detection interrupt status, check WPDMA_AXI_MST_DBG0 for error information +* m0_wr_axi_err_det_int_sts[8] - (W1C) WPDMA AXI write master for RX payload +* error detection interrupt status +* m1_wr_axi_err_det_int_sts[9] - (W1C) WPDMA AXI write master for RX DMAD error +* detection interrupt status +* m2_wr_axi_err_det_int_sts[10] - (W1C) WPDMA AXI write master for TX DMAD error +* detection interrupt status +* m0_rd_axi_err_det_int_sts[11] - (W1C) WPDMA AXI read master for DBDC0 TX +* payload error detection interrupt status +* m1_rd_axi_err_det_int_sts[12] - (W1C) WPDMA AXI read master for RX DMAD error +* detection interrupt status +* m2_rd_axi_err_det_int_sts[13] - (W1C) WPDMA AXI read master for TX DMAD error +* detection interrupt status +* m3_rd_axi_err_det_int_sts[14] - (W1C) WPDMA AXI read master for DBDC1 TX +* payload error detection interrupt status +* pf_sram_size_underflow_int_sts[15] - (RO) Prefetch sram overflow error +* interrupt status. This reflect configured prefetch sram is not enough for all +* TX and RX prefetch ring. Prefetch sram size should be greater than (DMAD size +* total of each RING's MAX_CNT) +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_pf_sram_size_underflow_int_sts_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_pf_sram_size_underflow_int_sts_MASK \ + 0x00008000 /* pf_sram_size_underflow_int_sts[15] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_pf_sram_size_underflow_int_sts_SHFT \ + 15 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_m3_rd_axi_err_det_int_sts_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_m3_rd_axi_err_det_int_sts_MASK \ + 0x00004000 /* m3_rd_axi_err_det_int_sts[14] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_m3_rd_axi_err_det_int_sts_SHFT \ + 14 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_m2_rd_axi_err_det_int_sts_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_m2_rd_axi_err_det_int_sts_MASK \ + 0x00002000 /* m2_rd_axi_err_det_int_sts[13] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_m2_rd_axi_err_det_int_sts_SHFT \ + 13 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_m1_rd_axi_err_det_int_sts_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_m1_rd_axi_err_det_int_sts_MASK \ + 0x00001000 /* m1_rd_axi_err_det_int_sts[12] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_m1_rd_axi_err_det_int_sts_SHFT \ + 12 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_m0_rd_axi_err_det_int_sts_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_m0_rd_axi_err_det_int_sts_MASK \ + 0x00000800 /* m0_rd_axi_err_det_int_sts[11] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_m0_rd_axi_err_det_int_sts_SHFT \ + 11 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_m2_wr_axi_err_det_int_sts_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_m2_wr_axi_err_det_int_sts_MASK \ + 0x00000400 /* m2_wr_axi_err_det_int_sts[10] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_m2_wr_axi_err_det_int_sts_SHFT \ + 10 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_m1_wr_axi_err_det_int_sts_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_m1_wr_axi_err_det_int_sts_MASK \ + 0x00000200 /* m1_wr_axi_err_det_int_sts[9] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_m1_wr_axi_err_det_int_sts_SHFT \ + 9 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_m0_wr_axi_err_det_int_sts_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_m0_wr_axi_err_det_int_sts_MASK \ + 0x00000100 /* m0_wr_axi_err_det_int_sts[8] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_m0_wr_axi_err_det_int_sts_SHFT \ + 8 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_wpdma_axi_rresp_error_int_sts_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_wpdma_axi_rresp_error_int_sts_MASK \ + 0x00000080 /* wpdma_axi_rresp_error_int_sts[7] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_wpdma_axi_rresp_error_int_sts_SHFT \ + 7 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_wpdma_axi_bresp_error_int_sts_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_wpdma_axi_bresp_error_int_sts_MASK \ + 0x00000040 /* wpdma_axi_bresp_error_int_sts[6] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_wpdma_axi_bresp_error_int_sts_SHFT \ + 6 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_wpdma_rx_payload_mem_range_err_int_st\ +s_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_wpdma_rx_payload_mem_range_err_int_st\ +s_MASK \ +0x00000020 /* wpdma_rx_payload_mem_range_err_int_sts[5] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_wpdma_rx_payload_mem_range_err_int_st\ +s_SHFT \ +5 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_wpdma_tx_payload_mem_range_err_int_st\ +s_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_wpdma_tx_payload_mem_range_err_int_st\ +s_MASK \ +0x00000010 /* wpdma_tx_payload_mem_range_err_int_sts[4] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_wpdma_tx_payload_mem_range_err_int_st\ +s_SHFT \ +4 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_wpdma_rx_dmad_mem_range_err_int_sts_A\ +DDR \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_wpdma_rx_dmad_mem_range_err_int_sts_M\ +ASK \ +0x00000008 /* wpdma_rx_dmad_mem_range_err_int_sts[3] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_wpdma_rx_dmad_mem_range_err_int_sts_S\ +HFT \ +3 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_wpdma_tx_dmad_mem_range_err_int_sts_A\ +DDR \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_wpdma_tx_dmad_mem_range_err_int_sts_M\ +ASK \ +0x00000004 /* wpdma_tx_dmad_mem_range_err_int_sts[2] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_wpdma_tx_dmad_mem_range_err_int_sts_S\ +HFT \ +2 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_wpdma_rx_timeout_int_sts_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_wpdma_rx_timeout_int_sts_MASK \ + 0x00000002 /* wpdma_rx_timeout_int_sts[1] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_wpdma_rx_timeout_int_sts_SHFT \ + 1 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_wpdma_tx_timeout_int_sts_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_wpdma_tx_timeout_int_sts_MASK \ + 0x00000001 /* wpdma_tx_timeout_int_sts[0] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_wpdma_tx_timeout_int_sts_SHFT \ + 0 + +/* +* ---WPDMA2HOST_ERR_INT_ENA (0x7C024000 + 0x1EC)--- +* wpdma_rx_timeout_int_ena[0] - (RW) WPDMA TX error detection interrupt enable +* wpdma_tx_timeout_int_ena[1] - (RW) WPDMA RX error detection interrupt enable +* wpdma_tx_dmad_mem_range_err_int_ena[2] - (RW) WPDMA tx dma descriptor memory +* range error detection interrupt enable +* wpdma_rx_dmad_mem_range_err_int_ena[3] - (RW) WPDMA rx dma descriptor memory +* range error detection interrupt enable +* wpdma_tx_payload_mem_range_err_int_ena[4] - (RW) WPDMA tx payload memory range +* error detection interrupt enable +* wpdma_rx_payload_mem_range_err_int_ena[5] - (RW) WPDMA rx payload memory range +* error detection interrupt enable +* wpdma_axi_bresp_error_int_ena[6] - (RW) WPDMA AXI master bresp error detection +* interrupt enable +* wpdma_axi_rresp_error_int_ena[7] - (RW) WPDMA AXI master rresp error detection +* interrupt enable +* m0_wr_axi_err_det_int_ena[8] - (RW) WPDMA AXI write master for RX payload +* error detection interrupt enable +* m1_wr_axi_err_det_int_ena[9] - (RW) WPDMA AXI write master for RX DMAD error +* detection interrupt enable +* m2_wr_axi_err_det_int_ena[10] - (RW) WPDMA AXI write master for TX DMAD error +* detection interrupt enable +* m0_rd_axi_err_det_int_ena[11] - (RW) WPDMA AXI read master for DBDC0 TX +* payload error detection interrupt enable +* m1_rd_axi_err_det_int_ena[12] - (RW) WPDMA AXI read master for RX DMAD error +* detection interrupt enable +* m2_rd_axi_err_det_int_ena[13] - (RW) WPDMA AXI read master for TX DMAD error +* detection interrupt enable +* m3_rd_axi_err_det_int_ena[14] - (RW) WPDMA AXI read master for DBDC1 TX +* payload error detection interrupt enable +* pf_sram_size_underflow_int_ena[15] - (RW) Prefetch sram overflow error +* interrupt enable +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_pf_sram_size_underflow_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_pf_sram_size_underflow_int_ena_MASK \ + 0x00008000 /* pf_sram_size_underflow_int_ena[15] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_pf_sram_size_underflow_int_ena_SHFT \ + 15 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_m3_rd_axi_err_det_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_m3_rd_axi_err_det_int_ena_MASK \ + 0x00004000 /* m3_rd_axi_err_det_int_ena[14] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_m3_rd_axi_err_det_int_ena_SHFT \ + 14 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_m2_rd_axi_err_det_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_m2_rd_axi_err_det_int_ena_MASK \ + 0x00002000 /* m2_rd_axi_err_det_int_ena[13] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_m2_rd_axi_err_det_int_ena_SHFT \ + 13 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_m1_rd_axi_err_det_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_m1_rd_axi_err_det_int_ena_MASK \ + 0x00001000 /* m1_rd_axi_err_det_int_ena[12] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_m1_rd_axi_err_det_int_ena_SHFT \ + 12 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_m0_rd_axi_err_det_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_m0_rd_axi_err_det_int_ena_MASK \ + 0x00000800 /* m0_rd_axi_err_det_int_ena[11] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_m0_rd_axi_err_det_int_ena_SHFT \ + 11 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_m2_wr_axi_err_det_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_m2_wr_axi_err_det_int_ena_MASK \ + 0x00000400 /* m2_wr_axi_err_det_int_ena[10] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_m2_wr_axi_err_det_int_ena_SHFT \ + 10 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_m1_wr_axi_err_det_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_m1_wr_axi_err_det_int_ena_MASK \ + 0x00000200 /* m1_wr_axi_err_det_int_ena[9] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_m1_wr_axi_err_det_int_ena_SHFT \ + 9 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_m0_wr_axi_err_det_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_m0_wr_axi_err_det_int_ena_MASK \ + 0x00000100 /* m0_wr_axi_err_det_int_ena[8] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_m0_wr_axi_err_det_int_ena_SHFT \ + 8 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_wpdma_axi_rresp_error_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_wpdma_axi_rresp_error_int_ena_MASK \ + 0x00000080 /* wpdma_axi_rresp_error_int_ena[7] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_wpdma_axi_rresp_error_int_ena_SHFT \ + 7 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_wpdma_axi_bresp_error_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_wpdma_axi_bresp_error_int_ena_MASK \ + 0x00000040 /* wpdma_axi_bresp_error_int_ena[6] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_wpdma_axi_bresp_error_int_ena_SHFT \ + 6 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_wpdma_rx_payload_mem_range_err_int_en\ +a_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_wpdma_rx_payload_mem_range_err_int_en\ +a_MASK \ +0x00000020 /* wpdma_rx_payload_mem_range_err_int_ena[5] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_wpdma_rx_payload_mem_range_err_int_en\ +a_SHFT \ +5 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_wpdma_tx_payload_mem_range_err_int_en\ +a_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_wpdma_tx_payload_mem_range_err_int_en\ +a_MASK \ +0x00000010 /* wpdma_tx_payload_mem_range_err_int_ena[4] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_wpdma_tx_payload_mem_range_err_int_en\ +a_SHFT \ +4 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_wpdma_rx_dmad_mem_range_err_int_ena_A\ +DDR \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_wpdma_rx_dmad_mem_range_err_int_ena_M\ +ASK \ +0x00000008 /* wpdma_rx_dmad_mem_range_err_int_ena[3] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_wpdma_rx_dmad_mem_range_err_int_ena_S\ +HFT \ +3 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_wpdma_tx_dmad_mem_range_err_int_ena_A\ +DDR \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_wpdma_tx_dmad_mem_range_err_int_ena_M\ +ASK \ +0x00000004 /* wpdma_tx_dmad_mem_range_err_int_ena[2] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_wpdma_tx_dmad_mem_range_err_int_ena_S\ +HFT \ +2 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_wpdma_tx_timeout_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_wpdma_tx_timeout_int_ena_MASK \ + 0x00000002 /* wpdma_tx_timeout_int_ena[1] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_wpdma_tx_timeout_int_ena_SHFT \ + 1 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_wpdma_rx_timeout_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_wpdma_rx_timeout_int_ena_MASK \ + 0x00000001 /* wpdma_rx_timeout_int_ena[0] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_wpdma_rx_timeout_int_ena_SHFT \ + 0 + +/* +* ---MCU2HOST_SW_INT_STA (0x7C024000 + 0x1F0)--- +* mcu2host_sw_int_0[0] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_1[1] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_2[2] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_3[3] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_4[4] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_5[5] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_6[6] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_7[7] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_8[8] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_9[9] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_10[10] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_11[11] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_12[12] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_13[13] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_14[14] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_15[15] - (W1C) mcu2host interrupt status +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_15_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_15_MASK \ + 0x00008000 /* mcu2host_sw_int_15[15] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_15_SHFT 15 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_14_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_14_MASK \ + 0x00004000 /* mcu2host_sw_int_14[14] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_14_SHFT 14 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_13_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_13_MASK \ + 0x00002000 /* mcu2host_sw_int_13[13] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_13_SHFT 13 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_12_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_12_MASK \ + 0x00001000 /* mcu2host_sw_int_12[12] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_12_SHFT 12 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_11_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_11_MASK \ + 0x00000800 /* mcu2host_sw_int_11[11] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_11_SHFT 11 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_10_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_10_MASK \ + 0x00000400 /* mcu2host_sw_int_10[10] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_10_SHFT 10 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_9_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_9_MASK \ + 0x00000200 /* mcu2host_sw_int_9[9] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_9_SHFT 9 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_8_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_8_MASK \ + 0x00000100 /* mcu2host_sw_int_8[8] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_8_SHFT 8 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_7_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_7_MASK \ + 0x00000080 /* mcu2host_sw_int_7[7] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_7_SHFT 7 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_6_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_6_MASK \ + 0x00000040 /* mcu2host_sw_int_6[6] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_6_SHFT 6 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_5_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_5_MASK \ + 0x00000020 /* mcu2host_sw_int_5[5] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_5_SHFT 5 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_4_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_4_MASK \ + 0x00000010 /* mcu2host_sw_int_4[4] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_4_SHFT 4 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_3_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_3_MASK \ + 0x00000008 /* mcu2host_sw_int_3[3] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_3_SHFT 3 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_2_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_2_MASK \ + 0x00000004 /* mcu2host_sw_int_2[2] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_2_SHFT 2 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_1_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_1_MASK \ + 0x00000002 /* mcu2host_sw_int_1[1] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_1_SHFT 1 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_0_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_0_MASK \ + 0x00000001 /* mcu2host_sw_int_0[0] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_0_SHFT 0 + +/* +* ---MCU2HOST_SW_INT_ENA (0x7C024000 + 0x1F4)--- +* mcu2host_int_ena_0[0] - (RW) MCU2HOST software interrupt interrupt enable +* mcu2host_int_ena_1[1] - (RW) MCU2HOST software interrupt interrupt enable +* mcu2host_int_ena_2[2] - (RW) MCU2HOST software interrupt interrupt enable +* mcu2host_int_ena_3[3] - (RW) MCU2HOST software interrupt interrupt enable +* mcu2host_int_ena_4[4] - (RW) MCU2HOST software interrupt interrupt enable +* mcu2host_int_ena_5[5] - (RW) MCU2HOST software interrupt interrupt enable +* mcu2host_int_ena_6[6] - (RW) MCU2HOST software interrupt interrupt enable +* mcu2host_int_ena_7[7] - (RW) MCU2HOST software interrupt interrupt enable +* mcu2host_int_ena_8[8] - (RW) MCU2HOST software interrupt interrupt enable +* mcu2host_int_ena_9[9] - (RW) MCU2HOST software interrupt interrupt enable +* mcu2host_int_ena_10[10] - (RW) MCU2HOST software interrupt interrupt enable +* mcu2host_int_ena_11[11] - (RW) MCU2HOST software interrupt interrupt enable +* mcu2host_int_ena_12[12] - (RW) MCU2HOST software interrupt interrupt enable +* mcu2host_int_ena_13[13] - (RW) MCU2HOST software interrupt interrupt enable +* mcu2host_int_ena_14[14] - (RW) MCU2HOST software interrupt interrupt enable +* mcu2host_int_ena_15[15] - (RW) MCU2HOST software interrupt interrupt enable +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_15_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_15_MASK \ + 0x00008000 /* mcu2host_int_ena_15[15] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_15_SHFT 15 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_14_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_14_MASK \ + 0x00004000 /* mcu2host_int_ena_14[14] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_14_SHFT 14 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_13_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_13_MASK \ + 0x00002000 /* mcu2host_int_ena_13[13] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_13_SHFT 13 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_12_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_12_MASK \ + 0x00001000 /* mcu2host_int_ena_12[12] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_12_SHFT 12 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_11_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_11_MASK \ + 0x00000800 /* mcu2host_int_ena_11[11] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_11_SHFT 11 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_10_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_10_MASK \ + 0x00000400 /* mcu2host_int_ena_10[10] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_10_SHFT 10 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_9_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_9_MASK \ + 0x00000200 /* mcu2host_int_ena_9[9] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_9_SHFT 9 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_8_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_8_MASK \ + 0x00000100 /* mcu2host_int_ena_8[8] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_8_SHFT 8 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_7_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_7_MASK \ + 0x00000080 /* mcu2host_int_ena_7[7] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_7_SHFT 7 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_6_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_6_MASK \ + 0x00000040 /* mcu2host_int_ena_6[6] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_6_SHFT 6 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_5_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_5_MASK \ + 0x00000020 /* mcu2host_int_ena_5[5] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_5_SHFT 5 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_4_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_4_MASK \ + 0x00000010 /* mcu2host_int_ena_4[4] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_4_SHFT 4 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_3_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_3_MASK \ + 0x00000008 /* mcu2host_int_ena_3[3] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_3_SHFT 3 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_2_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_2_MASK \ + 0x00000004 /* mcu2host_int_ena_2[2] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_2_SHFT 2 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_1_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_1_MASK \ + 0x00000002 /* mcu2host_int_ena_1[1] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_1_SHFT 1 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_0_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_0_MASK \ + 0x00000001 /* mcu2host_int_ena_0[0] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_0_SHFT 0 + +/* +* ---SUBSYS2HOST_INT_STA (0x7C024000 + 0x1F8)--- +* mac_int_sts_0[0] - (RO) MAC interrupt 0: TBTT interrupt(Check +* wf_int_wakeup_top/hwisr0 [0x820Fc03c]) +* 0 : no interrupt +* 1 : interrupt assert +* mac_int_sts_1[1] - (RO) MAC interrupt 1: Pre-TBTT interrupt(Check +* wf_int_wakeup_top/hwisr1 [0x820Fc044]) +* 0 : no interrupt +* 1 : interrupt assert +* mac_int_sts_2[2] - (RO) MAC interrupt 2: TX status interrupt(Check +* wf_int_wakeup_top/hwisr2 [0x820Fc04c]) +* 0 : no interrupt +* 1 : interrupt assert +* mac_int_sts_3[3] - (RO) MAC interrupt 3: Auto wakeup interrupt (Check +* wf_int_wakeup_top/hwisr3 [0x820Fc054]) +* 0 : no interrupt +* 1 : interrupt assert +* mac_int_sts_4[4] - (RO) MAC interrupt 4: GP timer interrupt (Check +* wf_int_wakeup_top/hwisr4 [0x820Fc05c]) +* 0 : no interrupt +* 1 : interrupt assert +* RESERVED5[7..5] - (RO) Reserved bits +* conn_hif_on_host_int_sts[8] - (RO) CONN_HIF_ON interrupt enable +* 0 : no conn_hif_on_host_int interrupt +* 1 : conn_hif_on_host_int interrupt assert. User should check conn_hif_on +* (host_csr) interrupt status and clear interrupt. +* conn2ap_sw_irq_sts[9] - (RO) MCUSYS conn2ap_sw_irq status (Check +* conn_mcu_config/EMI_CTL [0x80000150] bit[4:0]) +* 0 : no conn2ap_sw_irq interrupt. +* 1 : conn2ap_sw_irq interrupt assert. User should check mcusys_n9 interrupt +* status and clear interrupt. (conn_mcu_config/EMI_CTL [0x80000150] bit[4:0] != +0) +* RESERVED10[31..10] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_conn2ap_sw_irq_sts_ADDR \ + WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_conn2ap_sw_irq_sts_MASK \ + 0x00000200 /* conn2ap_sw_irq_sts[9] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_conn2ap_sw_irq_sts_SHFT 9 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_conn_hif_on_host_int_sts_ADDR \ + WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_conn_hif_on_host_int_sts_MASK \ + 0x00000100 /* conn_hif_on_host_int_sts[8] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_conn_hif_on_host_int_sts_SHFT 8 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_4_ADDR \ + WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_4_MASK \ + 0x00000010 /* mac_int_sts_4[4] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_4_SHFT 4 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_3_ADDR \ + WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_3_MASK \ + 0x00000008 /* mac_int_sts_3[3] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_3_SHFT 3 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_2_ADDR \ + WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_2_MASK \ + 0x00000004 /* mac_int_sts_2[2] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_2_SHFT 2 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_1_ADDR \ + WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_1_MASK \ + 0x00000002 /* mac_int_sts_1[1] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_1_SHFT 1 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_0_ADDR \ + WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_0_MASK \ + 0x00000001 /* mac_int_sts_0[0] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_0_SHFT 0 + +/* +* ---SUBSYS2HOST_INT_ENA (0x7C024000 + 0x1FC)--- +* mac_int_ena_0[0] - (RW) MAC interrupt enable +* mac_int_ena_1[1] - (RW) MAC interrupt enable +* mac_int_ena_2[2] - (RW) MAC interrupt enable +* mac_int_ena_3[3] - (RW) MAC interrupt enable +* mac_int_ena_4[4] - (RW) MAC interrupt enable +* RESERVED5[7..5] - (RO) Reserved bits +* conn_hif_on_host_int_ena[8] - (RW) CONN_HIF_ON interrupt enable +* conn2ap_sw_irq_ena[9] - (RW) MCUSYS conn2ap_sw_irq enable +* RESERVED10[31..10] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_conn2ap_sw_irq_ena_ADDR \ + WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_conn2ap_sw_irq_ena_MASK \ + 0x00000200 /* conn2ap_sw_irq_ena[9] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_conn2ap_sw_irq_ena_SHFT 9 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_conn_hif_on_host_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_conn_hif_on_host_int_ena_MASK \ + 0x00000100 /* conn_hif_on_host_int_ena[8] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_conn_hif_on_host_int_ena_SHFT 8 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_4_ADDR \ + WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_4_MASK \ + 0x00000010 /* mac_int_ena_4[4] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_4_SHFT 4 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_3_ADDR \ + WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_3_MASK \ + 0x00000008 /* mac_int_ena_3[3] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_3_SHFT 3 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_2_ADDR \ + WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_2_MASK \ + 0x00000004 /* mac_int_ena_2[2] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_2_SHFT 2 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_1_ADDR \ + WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_1_MASK \ + 0x00000002 /* mac_int_ena_1[1] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_1_SHFT 1 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_0_ADDR \ + WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_0_MASK \ + 0x00000001 /* mac_int_ena_0[0] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_0_SHFT 0 + +/* +* ---HOST_INT_STA (0x7C024000 + 0x200)--- +* rx_done_int_sts_0[0] - (W1C) RX Queue#0 packet receive interrupt +* Write 1 to clear the interrupt +* Read to get the raw interrupt status +* rx_done_int_sts_1[1] - (W1C) RX Queue#1 packet receive interrupt +* Write 1 to clear the interrupt +* Read to get the raw interrupt status +* rx_done_int_sts_2[2] - (W1C) RX Queue#2 packet receive interrupt +* Write 1 to clear the interrupt +* Read to get the raw interrupt status +* rx_done_int_sts_3[3] - (W1C) RX Queue#3 packet receive interrupt +* Write 1 to clear the interrupt +* Read to get the raw interrupt status +* tx_done_int_sts_0[4] - (W1C) TX Queue#0 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_1[5] - (W1C) TX Queue#1 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_2[6] - (W1C) TX Queue#2 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_3[7] - (W1C) TX Queue#3 packet transmit interrupt +* Write 1 to clear the interrupt +* RESERVED8[19..8] - (RO) Reserved bits +* rx_coherent_int_sts[20] - (W1C) RX_DMA finds data coherent event when checking +* ddone bit +* Write 1 to clear the interrupt +* Read to get the raw interrupt status +* tx_coherent_int_sts[21] - (W1C) TX_DMA finds data coherent event when checking +* ddone bit +* Write 1 to clear the interrupt +* Read to get the raw interrupt status +* RESERVED[23..22] - (RO) reserved, originally used for delayed interrupt of +* legacy TX/RX done +* wpdma2host_err_int_sts[24] - (RO) wpdma interrupt overall status +* User should should check WPDMA_ERR_INT_STA for each wpdma error interrupt +status +* Host could read [0x0_41E8] to check indivisual wpdma2host_error interrupt +status +* RESERVED25[27..25] - (RO) Reserved bits +* subsys_int_sts[28] - (RO) subsys interrupt overall status +* User should should check SUBSYS2HOST_INT_STA for each interrupt status +* Host could read [0x0_41F8] to check indivisual subsys hw interrupt status +* mcu2host_sw_int_sts[29] - (RO) subsys interrupt overall status +* User should should check SUBSYS2HOST_INT_STA for each interrupt status +* Host could read [0x0_41F8] to check indivisual subsys hw interrupt status +* RESERVED30[31..30] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_mcu2host_sw_int_sts_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_mcu2host_sw_int_sts_MASK \ + 0x20000000 /* mcu2host_sw_int_sts[29] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_mcu2host_sw_int_sts_SHFT 29 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_subsys_int_sts_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_subsys_int_sts_MASK \ + 0x10000000 /* subsys_int_sts[28] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_subsys_int_sts_SHFT 28 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_wpdma2host_err_int_sts_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_wpdma2host_err_int_sts_MASK \ + 0x01000000 /* wpdma2host_err_int_sts[24] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_wpdma2host_err_int_sts_SHFT 24 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_coherent_int_sts_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_coherent_int_sts_MASK \ + 0x00200000 /* tx_coherent_int_sts[21] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_coherent_int_sts_SHFT 21 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_coherent_int_sts_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_coherent_int_sts_MASK \ + 0x00100000 /* rx_coherent_int_sts[20] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_coherent_int_sts_SHFT 20 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_3_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_3_MASK \ + 0x00000080 /* tx_done_int_sts_3[7] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_3_SHFT 7 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_2_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_2_MASK \ + 0x00000040 /* tx_done_int_sts_2[6] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_2_SHFT 6 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_1_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_1_MASK \ + 0x00000020 /* tx_done_int_sts_1[5] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_1_SHFT 5 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_0_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_0_MASK \ + 0x00000010 /* tx_done_int_sts_0[4] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_0_SHFT 4 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_3_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_3_MASK \ + 0x00000008 /* rx_done_int_sts_3[3] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_3_SHFT 3 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_2_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_2_MASK \ + 0x00000004 /* rx_done_int_sts_2[2] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_2_SHFT 2 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_1_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_1_MASK \ + 0x00000002 /* rx_done_int_sts_1[1] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_1_SHFT 1 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_0_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_0_MASK \ + 0x00000001 /* rx_done_int_sts_0[0] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_0_SHFT 0 + +/* +* ---HOST_INT_ENA (0x7C024000 + 0X204)--- +* HOST_RX_DONE_INT_ENA0[0] - (RW) RX Queue#0 packet receive interrupt +* HOST_RX_DONE_INT_ENA1[1] - (RW) RX Queue#1 packet receive interrupt +* HOST_RX_DONE_INT_ENA2[2] - (RW) RX Queue#2 packet receive interrupt +* HOST_RX_DONE_INT_ENA3[3] - (RW) RX Queue#3 packet receive interrupt +* HOST_TX_DONE_INT_ENA0[4] - (RW) TX Queue#0 packet transmit interrupt +* HOST_TX_DONE_INT_ENA1[5] - (RW) TX Queue#1 packet transmit interrupt +* HOST_TX_DONE_INT_ENA2[6] - (RW) TX Queue#2 packet transmit interrupt +* HOST_TX_DONE_INT_ENA3[7] - (RW) TX Queue#3 packet transmit interrupt +* RESERVED8[19..8] - (RO) Reserved bits +* HOST_RX_COHERENT_EN[20] - (RW) Enable for RX_DMA data coherent interrupt +* HOST_TX_COHERENT_EN[21] - (RW) Enable for TX_DMA data coherent interrupt +* RESERVED[23..22] - (RO) reserved, originally used for delayed interrupt of +* legacy TX/RX done +* wpdma2host_err_int_ena[24] - (RW) Enable bit of wpdma2host_err_int +* RESERVED25[27..25] - (RO) Reserved bits +* subsys_int_ena[28] - (RW) Enable bit of subsys_int +* mcu2host_sw_int_ena[29] - (RW) Enable bit of mcu2host_sw_int +* RESERVED30[31..30] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_mcu2host_sw_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_mcu2host_sw_int_ena_MASK \ + 0x20000000 /* mcu2host_sw_int_ena[29] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_mcu2host_sw_int_ena_SHFT 29 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_subsys_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_subsys_int_ena_MASK \ + 0x10000000 /* subsys_int_ena[28] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_subsys_int_ena_SHFT 28 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_wpdma2host_err_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_wpdma2host_err_int_ena_MASK \ + 0x01000000 /* wpdma2host_err_int_ena[24] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_wpdma2host_err_int_ena_SHFT 24 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_COHERENT_EN_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_COHERENT_EN_MASK \ + 0x00200000 /* HOST_TX_COHERENT_EN[21] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_COHERENT_EN_SHFT 21 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_COHERENT_EN_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_COHERENT_EN_MASK \ + 0x00100000 /* HOST_RX_COHERENT_EN[20] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_COHERENT_EN_SHFT 20 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA3_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA3_MASK \ + 0x00000080 /* HOST_TX_DONE_INT_ENA3[7] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA3_SHFT 7 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA2_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA2_MASK \ + 0x00000040 /* HOST_TX_DONE_INT_ENA2[6] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA2_SHFT 6 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA1_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA1_MASK \ + 0x00000020 /* HOST_TX_DONE_INT_ENA1[5] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA1_SHFT 5 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA0_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA0_MASK \ + 0x00000010 /* HOST_TX_DONE_INT_ENA0[4] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA0_SHFT 4 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA3_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA3_MASK \ + 0x00000008 /* HOST_RX_DONE_INT_ENA3[3] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA3_SHFT 3 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA2_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA2_MASK \ + 0x00000004 /* HOST_RX_DONE_INT_ENA2[2] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA2_SHFT 2 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA1_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA1_MASK \ + 0x00000002 /* HOST_RX_DONE_INT_ENA1[1] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA1_SHFT 1 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA0_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA0_MASK \ + 0x00000001 /* HOST_RX_DONE_INT_ENA0[0] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA0_SHFT 0 + +/* +* ---WPDMA_GLO_CFG (0x7C024000 + 0x208)--- +* TX_DMA_EN[0] - (RW) TX_DMA Enable +* 1: Enable TX_DMA, MUST wait until all prefetch rings' +* MAX_CNT(WPDMA_T(R)X_RING*_EXT_CTRL) of DMA including neighbor DMA have been +* configured successfully +* 0: Disable TX_DMA +* TX_DMA_BUSY[1] - (RO) TX_DMA Busy indicator +* 1: TX_DMA is busy +* 0: TX_DMA is not busy +* RX_DMA_EN[2] - (RW) RX_DMA Enable +* 1: Enable RX_DMA, MUST wait until all prefetch rings' +* MAX_CNT(WPDMA_T(R)X_RING*_EXT_CTRL) of DMA including neighbor DMA have been +* configured successfully +* 0: Disable RX_DMA +* RX_DMA_BUSY[3] - (RO) RX_DMA Busy indicator +* 1: RX_DMA is busy +* 0: RX_DMA is not busy +* PDMA_BT_SIZE[5..4] - (RW) Define the burst size of WPDMA +* 2'h0 : 4 DWORD (16bytes) +* 2'h1 : 8 DWORD (32 bytes) +* 2'h2 : 16 DWORD (64 bytes) +* 2'h3 : 32 DWORD (128 bytes) +* TX_WB_DDONE[6] - (RW) 1'b1 : TX engine will wait to assert IRQ util whole TX +* dmad has been fully written into AXI bus which represents HOST memory, 1'b0 : +* TX engine will assert IRQ once TX dmad write-back request have been ACKed +* BIG_ENDIAN[7] - (RW) The endian mode selection. DMA applies the endian rule to +* convert payload and TX/RX information. DMA won't apply endian rule to register +* or descriptor. +* 1: big endian. +* 0: little endian. +* DMAD_32B_EN[8] - (RW) DMA Descriptor 32-byte Enable +* 0: The size of descriptors is set to 16-byte +* 1: The size of descriptors is set to 32-byte +* FW_DWLD_Bypass_dmashdl[9] - (RW) No USE for (APSOC/PCIE) +* For firmware download packet, driver shold using tx-ring16 to download packet +* and set this bit to bypass dmashdl resource control. +* After firmware download finish, driver should clear this bit. +* After all, tx-ring16 could be used for normal data operation. +(USB) +* For USB test_mode, user could set this bit to bypass dmashdl with all endpoint +* CSR_WFDMA_DUMMY_REG[10] - (RW) dummy CR for use if ECO needed +* CSR_AXI_BUFRDY_BYP[11] - (RW) to disable read data fifo available checking +* before issuing next AXI read request +* FIFO_LITTLE_ENDIAN[12] - (RW) Determines the endianness of the FIFO side +* 0: Big-endian +* 1: Little-endian +* CSR_RX_WB_DDONE[13] - (RW) 1'b1 : RX engine will wait to assert IRQ util whole +* RX dmad has been fully written into AXI bus which represents HOST memory, 1'b0 +* : RX engine will assert IRQ once RX dmad write-back request have been ACKed +* CSR_PP_HIF_TXP_ACTIVE_EN[14] - (RW) 1'b1 : enable legacy pp_hif_txp_active +* function to lock tx engine for favor TXP transmit requested directly from PP, +* other pdma TX rings request will be masked until pp_hif_txp_active is +deasserted +* 1'b0 : disable legacy pp_hif_txp_active function, use latest TX source QoS +* design to change throttler settings to favor TXP transmit! +* CSR_DISP_BASE_PTR_CHAIN_EN[15] - (RW) Enable prefet sram ring address +* arrangement by hardware chain structure(DMA#N TX ring group -> DMA#N RX ring +* group -> DMA#M TX ring group -> DMA#M RX ring group and son on). If not +* enabled, firmware need to program DISP_BASE_PTR of WPDMA_T(R)X_RING*_EXT_CTRL +instead!! +* CSR_LBK_RX_Q_SEL[17..16] - (RW) loopback data from TXFIFO will be direct to +* this RX ring when CSR_LBK_RX_Q_SEL_EN in loopback mode, valid bit-width is +* equal to RX_RING_WIDTH which can be calculated from WPDMA_INFO 0x284[15:8] +RX_RING_NUMBER +* RESERVED18[19..18] - (RO) Reserved bits +* CSR_LBK_RX_Q_SEL_EN[20] - (RW) Force configured CSR_LBK_RX_Q_SEL to receive +* loopback data from TXFIFO +* RESERVED21[23..21] - (RO) Reserved bits +* CSR_SW_RST[24] - (RO) SW reset all designs (To be tested for SER in the +future) +* FORCE_TX_EOF[25] - (RW) Force to send an eof after PDMA being reset (for +Packet_Processor) +* 0: Disabled +* 1: Enabled +* PDMA_ADDR_EXT_EN[26] - (RW) No Fnction for now!! For PDMA Address 32bits +* extension. When this design option was enable. PDMA would change Tx/Rx +* descriptor format for address extension. +* 0 : PDMA 32bits address +* 1 : PDMA Tx descirptor DW3 (TXINFO) would used to extend address +* PDMA Rx descirpt DW2 (Reserved) would used to extend address. +* OMIT_RX_INFO[27] - (RW) For loopback mode, set to 1'b1. +* For normal wifi data operation. User should not set this option and should +* keep 1'b0 because UMAC will always add extra QW for checksum after received +* packet's laster QW +* VERY IMPORTANT : for cpu_dma0/1 where CR resides in 0x5100_0xxx, OMIT_RX_INFO +* MUST be set to 1'b1 +* Omit rx_info of all RX packets +* 0: All the PX packets should end with a rx_info +* 1: All the PX packets should NOT end with a rx_info but an eof +* OMIT_TX_INFO[28] - (RW) For loopback mode, set to 1'b1. +* For normal wifi data operation. User should set this option to +* Omit tx_info of all TX packets because UMAC design not support TXINFO +* 0: The tx_info in DMAD will be sent at the beginning +* 1: The tx_info in DMAD will NOT be sent at the beginning +* BYTE_SWAP[29] - (RW) Byte Swapping for TX/RX DMAD +* 0: Not to swap (Endian of DMAD unchanged) +* 1: Swap (Endian of DMAD reversed) +* CLK_GATE_DIS[30] - (RW) PDMA Clock Gated Function Disable +* 0: normal function +* 1: disable clock gated function +* RX_2B_OFFSET[31] - (RW) RX PBF 2-byte Offset +* 1: Skip the first two bytes of the RX PBF +* 0: Not to skip the first two bytes of the RX PBF +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_RX_2B_OFFSET_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_RX_2B_OFFSET_MASK \ + 0x80000000 /* RX_2B_OFFSET[31] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_RX_2B_OFFSET_SHFT 31 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CLK_GATE_DIS_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CLK_GATE_DIS_MASK \ + 0x40000000 /* CLK_GATE_DIS[30] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CLK_GATE_DIS_SHFT 30 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_BYTE_SWAP_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_BYTE_SWAP_MASK \ + 0x20000000 /* BYTE_SWAP[29] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_BYTE_SWAP_SHFT 29 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_OMIT_TX_INFO_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_OMIT_TX_INFO_MASK \ + 0x10000000 /* OMIT_TX_INFO[28] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_OMIT_TX_INFO_SHFT 28 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_OMIT_RX_INFO_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_OMIT_RX_INFO_MASK \ + 0x08000000 /* OMIT_RX_INFO[27] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_OMIT_RX_INFO_SHFT 27 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_PDMA_ADDR_EXT_EN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_PDMA_ADDR_EXT_EN_MASK \ + 0x04000000 /* PDMA_ADDR_EXT_EN[26] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_PDMA_ADDR_EXT_EN_SHFT 26 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_FORCE_TX_EOF_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_FORCE_TX_EOF_MASK \ + 0x02000000 /* FORCE_TX_EOF[25] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_FORCE_TX_EOF_SHFT 25 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_SW_RST_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_SW_RST_MASK \ + 0x01000000 /* CSR_SW_RST[24] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_SW_RST_SHFT 24 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_LBK_RX_Q_SEL_EN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_LBK_RX_Q_SEL_EN_MASK \ + 0x00100000 /* CSR_LBK_RX_Q_SEL_EN[20] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_LBK_RX_Q_SEL_EN_SHFT 20 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_LBK_RX_Q_SEL_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_LBK_RX_Q_SEL_MASK \ + 0x00030000 /* CSR_LBK_RX_Q_SEL[17..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_LBK_RX_Q_SEL_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN_MASK \ + 0x00008000 /* CSR_DISP_BASE_PTR_CHAIN_EN[15] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN_SHFT 15 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_PP_HIF_TXP_ACTIVE_EN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_PP_HIF_TXP_ACTIVE_EN_MASK \ + 0x00004000 /* CSR_PP_HIF_TXP_ACTIVE_EN[14] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_PP_HIF_TXP_ACTIVE_EN_SHFT 14 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_RX_WB_DDONE_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_RX_WB_DDONE_MASK \ + 0x00002000 /* CSR_RX_WB_DDONE[13] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_RX_WB_DDONE_SHFT 13 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_FIFO_LITTLE_ENDIAN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_FIFO_LITTLE_ENDIAN_MASK \ + 0x00001000 /* FIFO_LITTLE_ENDIAN[12] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_FIFO_LITTLE_ENDIAN_SHFT 12 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_AXI_BUFRDY_BYP_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_AXI_BUFRDY_BYP_MASK \ + 0x00000800 /* CSR_AXI_BUFRDY_BYP[11] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_AXI_BUFRDY_BYP_SHFT 11 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_WFDMA_DUMMY_REG_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_WFDMA_DUMMY_REG_MASK \ + 0x00000400 /* CSR_WFDMA_DUMMY_REG[10] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_WFDMA_DUMMY_REG_SHFT 10 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_FW_DWLD_Bypass_dmashdl_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_FW_DWLD_Bypass_dmashdl_MASK \ + 0x00000200 /* FW_DWLD_Bypass_dmashdl[9] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_FW_DWLD_Bypass_dmashdl_SHFT 9 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_DMAD_32B_EN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_DMAD_32B_EN_MASK \ + 0x00000100 /* DMAD_32B_EN[8] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_DMAD_32B_EN_SHFT 8 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_BIG_ENDIAN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_BIG_ENDIAN_MASK \ + 0x00000080 /* BIG_ENDIAN[7] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_BIG_ENDIAN_SHFT 7 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_TX_WB_DDONE_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_TX_WB_DDONE_MASK \ + 0x00000040 /* TX_WB_DDONE[6] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_TX_WB_DDONE_SHFT 6 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_PDMA_BT_SIZE_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_PDMA_BT_SIZE_MASK \ + 0x00000030 /* PDMA_BT_SIZE[5..4] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_PDMA_BT_SIZE_SHFT 4 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_RX_DMA_BUSY_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_RX_DMA_BUSY_MASK \ + 0x00000008 /* RX_DMA_BUSY[3] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_RX_DMA_BUSY_SHFT 3 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_RX_DMA_EN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_RX_DMA_EN_MASK \ + 0x00000004 /* RX_DMA_EN[2] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_RX_DMA_EN_SHFT 2 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_TX_DMA_BUSY_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_TX_DMA_BUSY_MASK \ + 0x00000002 /* TX_DMA_BUSY[1] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_TX_DMA_BUSY_SHFT 1 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_TX_DMA_EN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_TX_DMA_EN_MASK \ + 0x00000001 /* TX_DMA_EN[0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_TX_DMA_EN_SHFT 0 + +/* +* ---WPDMA_RST_DTX_PTR (0x7C024000 + 0x20C)--- +* RST_DTX_IDX0[0] - (WO) Write 1 to reset to TX_DMATX_IDX0 to 0 +* RST_DTX_IDX1[1] - (WO) Write 1 to reset to TX_DMATX_IDX1 to 0 +* RST_DTX_IDX2[2] - (WO) Write 1 to reset to TX_DMATX_IDX2 to 0 +* RST_DTX_IDX3[3] - (WO) Write 1 to reset to TX_DMATX_IDX3 to 0 +* RESERVED[31..4] - (WO) Reserved +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX3_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX3_MASK \ + 0x00000008 /* RST_DTX_IDX3[3] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX3_SHFT 3 +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX2_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX2_MASK \ + 0x00000004 /* RST_DTX_IDX2[2] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX2_SHFT 2 +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX1_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX1_MASK \ + 0x00000002 /* RST_DTX_IDX1[1] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX1_SHFT 1 +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX0_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX0_MASK \ + 0x00000001 /* RST_DTX_IDX0[0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX0_SHFT 0 + +/* +* ---WPDMA_PAUSE_TX_Q (0x7C024000 + 0x224)--- +* TX_Q_PAUSE[3..0] - (RW) Pause signal for each TX ring (16 bits for 16 rings) +* Set 0: Normal function; Set 1: The corresponding TX ring is paused +* RESERVED4[31..4] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_TX_Q_TX_Q_PAUSE_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_TX_Q_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_TX_Q_TX_Q_PAUSE_MASK \ + 0x0000000F /* TX_Q_PAUSE[3..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_TX_Q_TX_Q_PAUSE_SHFT 0 + +/* +* ---WPDMA_TIMEOUT_CFG (0x7C024000 + 0x230)--- +* WPDMA_TX_TIMEOUT_TH[7..0] - (RW) xxx +* WPDMA_TX_TIMEOUT_TICK[14..8] - (RW) xxx +* WPDMA_TX_TIMEOUT_ENA[15] - (RW) xxx +* WPDMA_RX_TIMEOUT_TH[23..16] - (RW) xxx +* WPDMA_RX_TIMEOUT_TICK[30..24] - (RW) xxx +* WPDMA_RX_TIMEOUT_ENA[31] - (RW) xxx +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_ENA_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_ENA_MASK \ + 0x80000000 /* WPDMA_RX_TIMEOUT_ENA[31] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_ENA_SHFT 31 +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_TICK_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_TICK_MASK \ + 0x7F000000 /* WPDMA_RX_TIMEOUT_TICK[30..24] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_TICK_SHFT 24 +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_TH_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_TH_MASK \ + 0x00FF0000 /* WPDMA_RX_TIMEOUT_TH[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_TH_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_ENA_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_ENA_MASK \ + 0x00008000 /* WPDMA_TX_TIMEOUT_ENA[15] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_ENA_SHFT 15 +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_TICK_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_TICK_MASK \ + 0x00007F00 /* WPDMA_TX_TIMEOUT_TICK[14..8] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_TICK_SHFT 8 +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_TH_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_TH_MASK \ + 0x000000FF /* WPDMA_TX_TIMEOUT_TH[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_TH_SHFT 0 + +/* +* ---WPDMA_MISC_CFG (0x7C024000 + 0x234)--- +* WPDMA_TX_TIMEOUT_SEL[0] - (RW) xxx +* WPDMA_RX_TIMEOUT_SEL[1] - (RW) xxx +* WPDMA_RX_FREE_Q_TH[5..2] - (RW) When loopback, this will be used to generate +* correct tx_pause to avlid deadlock which caused from situration that tx_dma +* will start reading tx packet from memory without considering lack of RX dmad +* in prefetch sram and needing to read RX dmad from memory which tx dma is +* reading tx packet too and rready is deasserted due to txfifo full !! +* RX dmad in prefetch sram should be greater than RX_FREE_Q_TH for rx_dma to +* start writing received packet into memory!! +* RESERVED6[31..6] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_MISC_CFG_WPDMA_RX_FREE_Q_TH_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_MISC_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_MISC_CFG_WPDMA_RX_FREE_Q_TH_MASK \ + 0x0000003C /* WPDMA_RX_FREE_Q_TH[5..2] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_MISC_CFG_WPDMA_RX_FREE_Q_TH_SHFT 2 +#define WF_WFDMA_HOST_DMA0_WPDMA_MISC_CFG_WPDMA_RX_TIMEOUT_SEL_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_MISC_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_MISC_CFG_WPDMA_RX_TIMEOUT_SEL_MASK \ + 0x00000002 /* WPDMA_RX_TIMEOUT_SEL[1] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_MISC_CFG_WPDMA_RX_TIMEOUT_SEL_SHFT 1 +#define WF_WFDMA_HOST_DMA0_WPDMA_MISC_CFG_WPDMA_TX_TIMEOUT_SEL_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_MISC_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_MISC_CFG_WPDMA_TX_TIMEOUT_SEL_MASK \ + 0x00000001 /* WPDMA_TX_TIMEOUT_SEL[0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_MISC_CFG_WPDMA_TX_TIMEOUT_SEL_SHFT 0 + +/* +* ---WPDMA_TX_WRR_ARB_GBF0 (0x7C024000 + 0x240)--- +* WRR_REQ0_ARB_GBF[2..0] - (RW) WRR REQ#0 priority level, mapped to lumpped +* request from TX ring0~ring15 for host TXD +* WRR_REQ1_ARB_GBF[5..3] - (RW) WRR REQ#1 priority level, mapped to request from +* TX ring16 when dual tx fifo for host event packet +* WRR_REQ2_ARB_GBF[8..6] - (RW) WRR REQ#2 priority level, mapped to request from +* TX ring17 when dual tx fifo for host event packet +* WRR_REQ3_ARB_GBF[11..9] - (RW) WRR REQ#3 priority level, mapped to request +* from TX ring18 when dual tx fifo for host event packet +* WRR_REQ4_ARB_GBF[14..12] - (RW) WRR REQ#4 priority level, mapped to request +* from TX ring19 when dual tx fifo for host event packet +* RESERVED[31..15] - (RW) Reserved +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ4_ARB_GBF_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ4_ARB_GBF_MASK \ + 0x00007000 /* WRR_REQ4_ARB_GBF[14..12] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ4_ARB_GBF_SHFT 12 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ3_ARB_GBF_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ3_ARB_GBF_MASK \ + 0x00000E00 /* WRR_REQ3_ARB_GBF[11..9] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ3_ARB_GBF_SHFT 9 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ2_ARB_GBF_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ2_ARB_GBF_MASK \ + 0x000001C0 /* WRR_REQ2_ARB_GBF[8..6] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ2_ARB_GBF_SHFT 6 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ1_ARB_GBF_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ1_ARB_GBF_MASK \ + 0x00000038 /* WRR_REQ1_ARB_GBF[5..3] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ1_ARB_GBF_SHFT 3 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ0_ARB_GBF_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ0_ARB_GBF_MASK \ + 0x00000007 /* WRR_REQ0_ARB_GBF[2..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ0_ARB_GBF_SHFT 0 + +/* +* ---WPDMA_PAUSE_RX_Q_TH10 (0x7C024000 + 0x260)--- +* RX_DMAD_TH0[11..0] - (RW) RX Ring0 DMAD threshold to pause PP sending packet +* to RX FIFO +* pause_rx_q = (available RX DMAD counts) < +* RESERVED12[15..12] - (RO) Reserved bits +* RX_DMAD_TH1[27..16] - (RW) RX Ring1 DMAD threshold to pause PP sending packet +* to RX FIFO +* pause_rx_q = (available RX DMAD counts) < +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH10_RX_DMAD_TH1_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH10_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH10_RX_DMAD_TH1_MASK \ + 0x0FFF0000 /* RX_DMAD_TH1[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH10_RX_DMAD_TH1_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH10_RX_DMAD_TH0_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH10_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH10_RX_DMAD_TH0_MASK \ + 0x00000FFF /* RX_DMAD_TH0[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH10_RX_DMAD_TH0_SHFT 0 + +/* +* ---WPDMA_PAUSE_RX_Q_TH32 (0x7C024000 + 0x264)--- +* RX_DMAD_TH2[11..0] - (RW) RX Ring2 DMAD threshold to pause PP sending packet +* to RX FIFO +* pause_rx_q = (available RX DMAD counts) < +* RESERVED12[15..12] - (RO) Reserved bits +* RX_DMAD_TH3[27..16] - (RW) RX Ring3 DMAD threshold to pause PP sending packet +* to RX FIFO +* pause_rx_q = (available RX DMAD counts) < +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH32_RX_DMAD_TH3_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH32_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH32_RX_DMAD_TH3_MASK \ + 0x0FFF0000 /* RX_DMAD_TH3[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH32_RX_DMAD_TH3_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH32_RX_DMAD_TH2_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH32_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH32_RX_DMAD_TH2_MASK \ + 0x00000FFF /* RX_DMAD_TH2[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH32_RX_DMAD_TH2_SHFT 0 + +/* +* ---WPDMA_PAUSE_RX_Q_TH54 (0x7C024000 + 0x268)--- +* RX_DMAD_TH4[11..0] - (RW) RX Ring4 DMAD threshold to pause PP sending packet +* to RX FIFO +* pause_rx_q = (available RX DMAD counts) < +* RESERVED12[15..12] - (RO) Reserved bits +* RX_DMAD_TH5[27..16] - (RW) RX Ring5 DMAD threshold to pause PP sending packet +* to RX FIFO +* pause_rx_q = (available RX DMAD counts) < +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH54_RX_DMAD_TH5_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH54_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH54_RX_DMAD_TH5_MASK \ + 0x0FFF0000 /* RX_DMAD_TH5[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH54_RX_DMAD_TH5_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH54_RX_DMAD_TH4_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH54_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH54_RX_DMAD_TH4_MASK \ + 0x00000FFF /* RX_DMAD_TH4[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH54_RX_DMAD_TH4_SHFT 0 + +/* +* ---WPDMA_PAUSE_RX_Q_TH76 (0x7C024000 + 0x26C)--- +* RX_DMAD_TH6[11..0] - (RW) RX Ring6 DMAD threshold to pause PP sending packet +* to RX FIFO +* pause_rx_q = (available RX DMAD counts) < +* RESERVED12[15..12] - (RO) Reserved bits +* RX_DMAD_TH7[27..16] - (RW) RX Ring7 DMAD threshold to pause PP sending packet +* to RX FIFO +* pause_rx_q = (available RX DMAD counts) < +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH76_RX_DMAD_TH7_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH76_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH76_RX_DMAD_TH7_MASK \ + 0x0FFF0000 /* RX_DMAD_TH7[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH76_RX_DMAD_TH7_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH76_RX_DMAD_TH6_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH76_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH76_RX_DMAD_TH6_MASK \ + 0x00000FFF /* RX_DMAD_TH6[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH76_RX_DMAD_TH6_SHFT 0 + +/* +* ---WPDMA_RST_DRX_PTR (0x7C024000 + 0x280)--- +* RST_DRX_IDX0[0] - (WO) Write 1 to reset to RX_DMARX_IDX0 to 0 +* RST_DRX_IDX1[1] - (WO) Write 1 to reset to RX_DMARX_IDX1 to 0 +* RST_DRX_IDX2[2] - (WO) Write 1 to reset to RX_DMARX_IDX2 to 0 +* RST_DRX_IDX3[3] - (WO) Write 1 to reset to RX_DMARX_IDX3 to 0 +* RESERVED[31..4] - (WO) Reserved +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_RST_DRX_IDX3_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_RST_DRX_IDX3_MASK \ + 0x00000008 /* RST_DRX_IDX3[3] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_RST_DRX_IDX3_SHFT 3 +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_RST_DRX_IDX2_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_RST_DRX_IDX2_MASK \ + 0x00000004 /* RST_DRX_IDX2[2] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_RST_DRX_IDX2_SHFT 2 +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_RST_DRX_IDX1_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_RST_DRX_IDX1_MASK \ + 0x00000002 /* RST_DRX_IDX1[1] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_RST_DRX_IDX1_SHFT 1 +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_RST_DRX_IDX0_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_RST_DRX_IDX0_MASK \ + 0x00000001 /* RST_DRX_IDX0[0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_RST_DRX_IDX0_SHFT 0 + +/* +* ---WPDMA_INFO (0x7C024000 + 0x284)--- +* TX_RING_NUMBER[7..0] - (RO) TX_RING_NUMBER +* RX_RING_NUMBER[15..8] - (RO) RX_RING_NUMBER +* BASE_PTR_WIDTH[23..16] - (RO) {2'h0, 6'd32-'BASE_PTR_WIDTH[5:0]} +* INDEX_WIDTH[27..24] - (RO) RING_INDEX_WIDTH +* PDMA_PREFETCH_SRAM_SIZE[30..28] - (RO) PDMA prefetch sram size{3'h0 : 128 +* byte, 3'h1 : 256 byte, 3'h2 : 512 byte, 3'h3 : 1KB, 3'h4 : 2KB, 3'h5 : 4KB, +* 3'h6 : 8KB, 3'h7 : reserved}, be noticed that prefetch sram is shared outside +* with other DMAs, please check all DMAs' total prefetch ring number and max_cnt +* for each prefetch ring to make sure that total size of all configured prefetch +* dmad of all DMAs' prefetch ring should be less than PDMA_PREFETCH_SRAM_SIZE +* WFDMA_PDA_EXIST[31] - (RO) Only cpu_dma1 will support pda functions for +* firmware download and wfdma_pda_top resides in between cpu_dma0 and cpu_dma1! +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_WFDMA_PDA_EXIST_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_INFO_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_WFDMA_PDA_EXIST_MASK \ + 0x80000000 /* WFDMA_PDA_EXIST[31] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_WFDMA_PDA_EXIST_SHFT 31 +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_PDMA_PREFETCH_SRAM_SIZE_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_INFO_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_PDMA_PREFETCH_SRAM_SIZE_MASK \ + 0x70000000 /* PDMA_PREFETCH_SRAM_SIZE[30..28] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_PDMA_PREFETCH_SRAM_SIZE_SHFT 28 +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_INDEX_WIDTH_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_INFO_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_INDEX_WIDTH_MASK \ + 0x0F000000 /* INDEX_WIDTH[27..24] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_INDEX_WIDTH_SHFT 24 +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_BASE_PTR_WIDTH_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_INFO_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_BASE_PTR_WIDTH_MASK \ + 0x00FF0000 /* BASE_PTR_WIDTH[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_BASE_PTR_WIDTH_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_RX_RING_NUMBER_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_INFO_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_RX_RING_NUMBER_MASK \ + 0x0000FF00 /* RX_RING_NUMBER[15..8] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_RX_RING_NUMBER_SHFT 8 +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_TX_RING_NUMBER_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_INFO_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_TX_RING_NUMBER_MASK \ + 0x000000FF /* TX_RING_NUMBER[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_TX_RING_NUMBER_SHFT 0 + +/* +* ---WPDMA_INFO_EXT (0x7C024000 + 0x288)--- +* TX_EVENT_RING_NUMBER[7..0] - (RO) When TX_EVENT_RING_NUMBER equal 8'h0, it +* means that this DMA doesn't support dual TX fifo, thus in default it only +* support TX_RING_NUMBER of TX rings !! +* But when TX_EVENT_RING_NUMBER NOT equal 8'h0, this dma is configured as dual +* TX fifo and TX_RING[16+TX_EVENT_RING_NUM-1:16] are for getting HOST EVENT +* packet from HOST to WX_CPU!! +* TX_DMAD_RING_NUMBER[15..8] - (RO) When TX_EVENT_RING_NUMBER not equal to 8'h0, +* it means that this DMA support dual TX fifo and TX +* ring[TX_DMAD_RING_NUMBER-1:0] are for getting TXD from HOST to UMAC!! +* RESERVED[30..16] - (RO) Reserved +* TX_DMASHDL_EXIST[31] - (RO) TX_DMASHDL_EXIST +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_EXT_TX_DMASHDL_EXIST_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_INFO_EXT_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_EXT_TX_DMASHDL_EXIST_MASK \ + 0x80000000 /* TX_DMASHDL_EXIST[31] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_EXT_TX_DMASHDL_EXIST_SHFT 31 +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_EXT_TX_DMAD_RING_NUMBER_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_INFO_EXT_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_EXT_TX_DMAD_RING_NUMBER_MASK \ + 0x0000FF00 /* TX_DMAD_RING_NUMBER[15..8] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_EXT_TX_DMAD_RING_NUMBER_SHFT 8 +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_EXT_TX_EVENT_RING_NUMBER_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_INFO_EXT_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_EXT_TX_EVENT_RING_NUMBER_MASK \ + 0x000000FF /* TX_EVENT_RING_NUMBER[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_EXT_TX_EVENT_RING_NUMBER_SHFT 0 + +/* +* ---WPDMA_INT_RX_PRI_SEL (0x7C024000 + 0x298)--- +* WPDMA_INT_RX_RING0_PRI_SEL[0] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_RX_RING1_PRI_SEL[1] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_RX_RING2_PRI_SEL[2] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* RESERVED3[31..3] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING2_PRI_SEL_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING2_PRI_SEL_MASK \ + 0x00000004 /* WPDMA_INT_RX_RING2_PRI_SEL[2] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING2_PRI_SEL_SHFT \ + 2 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING1_PRI_SEL_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING1_PRI_SEL_MASK \ + 0x00000002 /* WPDMA_INT_RX_RING1_PRI_SEL[1] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING1_PRI_SEL_SHFT \ + 1 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING0_PRI_SEL_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING0_PRI_SEL_MASK \ + 0x00000001 /* WPDMA_INT_RX_RING0_PRI_SEL[0] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING0_PRI_SEL_SHFT \ + 0 + +/* +* ---WPDMA_TX_DBG0 (0x7C024000 + 0x2A0)--- +* WPDMA_TX_DBG0[31..0] - (RO) xxx +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_DBG0_WPDMA_TX_DBG0_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_DBG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_DBG0_WPDMA_TX_DBG0_MASK \ + 0xFFFFFFFF /* WPDMA_TX_DBG0[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_DBG0_WPDMA_TX_DBG0_SHFT 0 + +/* +* ---WPDMA_TX_DBG1 (0x7C024000 + 0x2A4)--- +* WPDMA_TX_DBG1[31..0] - (RO) xxx +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_DBG1_WPDMA_TX_DBG1_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_DBG1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_DBG1_WPDMA_TX_DBG1_MASK \ + 0xFFFFFFFF /* WPDMA_TX_DBG1[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_DBG1_WPDMA_TX_DBG1_SHFT 0 + +/* +* ---WPDMA_RX_DBG0 (0x7C024000 + 0x2A8)--- +* WPDMA_RX_DBG0[31..0] - (RO) xxx +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_DBG0_WPDMA_RX_DBG0_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_DBG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_DBG0_WPDMA_RX_DBG0_MASK \ + 0xFFFFFFFF /* WPDMA_RX_DBG0[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_DBG0_WPDMA_RX_DBG0_SHFT 0 + +/* +* ---WPDMA_RX_DBG1 (0x7C024000 + 0x2AC)--- +* WPDMA_RX_DBG1[31..0] - (RO) xxx +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_DBG1_WPDMA_RX_DBG1_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_DBG1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_DBG1_WPDMA_RX_DBG1_MASK \ + 0xFFFFFFFF /* WPDMA_RX_DBG1[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_DBG1_WPDMA_RX_DBG1_SHFT 0 + +/* +* ---WPDMA_GLO_CFG_EXT0 (0x7C024000 + 0x2B0)--- +* CSR_MAX_PREFETCH_CNT[1..0] - (RW) Max. dmad count per prefet request, 2'b00 : +* 1 entry, 2'b01 : 2 entries, 2'b10 : 4 entries, 2'b11 : 8 entries, Note : 1 +* entry(dmad size) is 16 bytes = 4 DWs = 2 QWs +* CSR_MEM_BST_SIZE[3..2] - (RW) Max. burst size per sram request. 00 : 16-byte, +* 01 : 32-byte, 10 : 64-byte, 11 : 128-byte +* CSR_MEM_ARB_LOCK_EN[4] - (RW) 1'b1 : Lock round-robin sram access arbiter +* until whole long burst request from dma FSM finish, 1'b0 : no lock sram +* arbiter, grant will be change per request due to round-robin +* CSR_RX_DMA_WBQ_EN[5] - (RW) 1'b1 : RX dmad will be posted-write and deal with +* next received packet immediately, 1'b0 : RX dmad will be written back +* immediately after received packet has been sent to host memory +* CSR_TX_DMASHDL_ENABLE[6] - (RW) 1'b1 : request DMASHDL before TX to select +* next TX ring, 1'b0 : disable DMASHDL and use round-robin arbiter to select +* next TX ring +* CSR_BRESP_ERROR_BYPASS_EN[7] - (RW) 1'b1 : Bypass AXI error bresp as a normal +* response. 1'b0 : Will not assert bready to error bresp(00 : OKAY, 01 : EXOKAY, +* 10 : SLVERR, 11 : DECERR) +* CSR_AXI_SLEEP_MODE[9..8] - (RW) 2'b00 : no sleep, normal TX/RX, 2b1* : sleep +* after AXI request, 2'b11 : force assertion of wvalid, rready and bready to +* finish all committed data phases, then sleep immediately +* RESERVED10[14..10] - (RO) Reserved bits +* CSR_Q_STATUS_IDX_BKRS_EN[15] - (RW) backup/restore enable bit for +* q_status(payload, prefetch and dispatch) index +* CSR_AXI_BST_SIZE[17..16] - (RW) AXI busrt length, 00 : 128-byte, 01 : 64-byte, +* 10 : 32-byte, 11 : 16-byte +* CSR_RX_DMAD_WB_MIRROR_EN[18] - (RW) Set to 1'b1 to split RX DMAD write-back +* into two AXI request which carries ddone bit (DW1[31], DW1[15]) for each iif +* external AXI dispatcher exist and need to do push-write behavior to make sure +* all datas from two PCIE have arrived HOST memory +* CSR_AXI_FAKE[19] - (RW) If set to 1'b1, all requests from DMA engine will not +* be sent to AXI INFRA, this try to fix AXI bus hang issue temporarily! +* CSR_DMAD_PREFETCH_THRESHOLD[21..20] - (RW) trigger dmad prefetch when +* available dmad cnt >= {1(2'b00), 2(2'b01), 4(2'b10), 8(2'b11)} +* CSR_BID_CHECK_BYPASS_EN[22] - (RW) If set to 1'b0, axi master will check +* matching between awid and bid before assert bready, if set to 1'b1, it will +* bypass this checking and assert bready for each bvalid even though bid doesn't +* match any awid ever issued! +* CSR_RX_INFO_WB_EN[23] - (RW) If set to 1'b0, only DW0 and DW1 will be written +* back into memory after received RX packet process finished, this will save bus +* bandwidth a little because DW2 and DW3 are useless for FW +* CSR_AXI_OUTSTANDING_NUM[27..24] - (RW) decide max. outstanding AXI requests, +* common for AXI read or write! +* CSR_AXI_ARUSER_LOCK_EN[28] - (RW) on/off customized lock ctrl design thru AXI +* aruser signal, this will influence TX QoS ctrl +* CSR_AXI_AWUSER_LOCK_EN[29] - (RW) on/off customized lock ctrl design thru AXI +* awuser signal when RX dmad write-back have to be separately written into +* memory due to external dispatcher exists! +* CSR_AXI_LOCK_EN[30] - (RW) Global lock enable to on/off AXI spec. lock(axlock) +* behavior and also will on/off customized lock ctrl design thru AXI awuser +signal +* CSR_AXI_CLKGATE_BYP[31] - (RW) To bypass functional CG enable which incduced +* from coding style for DC inserted CG cell in all AXI read/write master design +module +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_CLKGATE_BYP_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_CLKGATE_BYP_MASK \ + 0x80000000 /* CSR_AXI_CLKGATE_BYP[31] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_CLKGATE_BYP_SHFT 31 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_LOCK_EN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_LOCK_EN_MASK \ + 0x40000000 /* CSR_AXI_LOCK_EN[30] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_LOCK_EN_SHFT 30 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_AWUSER_LOCK_EN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_AWUSER_LOCK_EN_MASK \ + 0x20000000 /* CSR_AXI_AWUSER_LOCK_EN[29] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_AWUSER_LOCK_EN_SHFT 29 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_ARUSER_LOCK_EN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_ARUSER_LOCK_EN_MASK \ + 0x10000000 /* CSR_AXI_ARUSER_LOCK_EN[28] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_ARUSER_LOCK_EN_SHFT 28 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_OUTSTANDING_NUM_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_OUTSTANDING_NUM_MASK \ + 0x0F000000 /* CSR_AXI_OUTSTANDING_NUM[27..24] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_OUTSTANDING_NUM_SHFT 24 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_RX_INFO_WB_EN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_RX_INFO_WB_EN_MASK \ + 0x00800000 /* CSR_RX_INFO_WB_EN[23] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_RX_INFO_WB_EN_SHFT 23 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_BID_CHECK_BYPASS_EN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_BID_CHECK_BYPASS_EN_MASK \ + 0x00400000 /* CSR_BID_CHECK_BYPASS_EN[22] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_BID_CHECK_BYPASS_EN_SHFT 22 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_DMAD_PREFETCH_THRESHOLD_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_DMAD_PREFETCH_THRESHOLD_MASK \ + 0x00300000 /* CSR_DMAD_PREFETCH_THRESHOLD[21..20] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_DMAD_PREFETCH_THRESHOLD_SHFT \ + 20 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_FAKE_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_FAKE_MASK \ + 0x00080000 /* CSR_AXI_FAKE[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_FAKE_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_RX_DMAD_WB_MIRROR_EN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_RX_DMAD_WB_MIRROR_EN_MASK \ + 0x00040000 /* CSR_RX_DMAD_WB_MIRROR_EN[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_RX_DMAD_WB_MIRROR_EN_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_BST_SIZE_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_BST_SIZE_MASK \ + 0x00030000 /* CSR_AXI_BST_SIZE[17..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_BST_SIZE_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_Q_STATUS_IDX_BKRS_EN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_Q_STATUS_IDX_BKRS_EN_MASK \ + 0x00008000 /* CSR_Q_STATUS_IDX_BKRS_EN[15] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_Q_STATUS_IDX_BKRS_EN_SHFT 15 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_SLEEP_MODE_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_SLEEP_MODE_MASK \ + 0x00000300 /* CSR_AXI_SLEEP_MODE[9..8] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_SLEEP_MODE_SHFT 8 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_BRESP_ERROR_BYPASS_EN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_BRESP_ERROR_BYPASS_EN_MASK \ + 0x00000080 /* CSR_BRESP_ERROR_BYPASS_EN[7] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_BRESP_ERROR_BYPASS_EN_SHFT 7 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_TX_DMASHDL_ENABLE_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_TX_DMASHDL_ENABLE_MASK \ + 0x00000040 /* CSR_TX_DMASHDL_ENABLE[6] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_TX_DMASHDL_ENABLE_SHFT 6 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_RX_DMA_WBQ_EN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_RX_DMA_WBQ_EN_MASK \ + 0x00000020 /* CSR_RX_DMA_WBQ_EN[5] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_RX_DMA_WBQ_EN_SHFT 5 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_MEM_ARB_LOCK_EN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_MEM_ARB_LOCK_EN_MASK \ + 0x00000010 /* CSR_MEM_ARB_LOCK_EN[4] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_MEM_ARB_LOCK_EN_SHFT 4 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_MEM_BST_SIZE_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_MEM_BST_SIZE_MASK \ + 0x0000000C /* CSR_MEM_BST_SIZE[3..2] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_MEM_BST_SIZE_SHFT 2 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_MAX_PREFETCH_CNT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_MAX_PREFETCH_CNT_MASK \ + 0x00000003 /* CSR_MAX_PREFETCH_CNT[1..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_MAX_PREFETCH_CNT_SHFT 0 + +/* +* ---WPDMA_GLO_CFG_EXT1 (0x7C024000 + 0x2B4)--- +* CSR_TXFIFO0_RDY_THRESHOLD[7..0] - (RW) xxx +* CSR_TXFIFO1_RDY_THRESHOLD[15..8] - (RW) xxx +* CSR_TX_DISP_ARB_SCHEDULED_ACCESS_TIMER[23..16] - (RW) timer setting for +* SCHEDULED_ACCESS_TIME_ARB of csr_tx_disp_arb_mode +* CSR_TX_DISP_ARB_MODE[25..24] - (RW) 00 : FAIR_ARB, 01 : FIX_ARB, 10 : +* UNBALANCED_ARB, 11 : SCHEDULED_ACCESS_TIME_ARB +* CSR_FWDL_FLOW_CTRL_BYASS_EN[26] - (RW) To disable firmware download TX flow +* control of TX dma(host_dma1) when firmare download of RX dma(mcu_dma1) is in +* firmware download polling mode!! Remember to set to 1'b0 when firmware +* download ring is set back to normal ring usage which should be in flow control +* for correct behavior!! +* CSR_FWDL_FLOW_CTRL_BYASS_LS_QSEL_EN[27] - (RW) select firmware download TX +* ring(LSB/MSB ring) to bypass TX flow control when firmare download RX +* ring(LSB/MSB ring) of RX dma(mcu_dma1) is in firmware download polling mode!! +* RESERVED[31..28] - (RW) reserved +*/ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_FWDL_FLOW_CTRL_BYASS_LS_QSEL_EN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_FWDL_FLOW_CTRL_BYASS_LS_QSEL_EN_MASK \ + 0x08000000 /* CSR_FWDL_FLOW_CTRL_BYASS_LS_QSEL_EN[27] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_FWDL_FLOW_CTRL_BYASS_LS_QSEL_EN_SHFT \ + 27 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_FWDL_FLOW_CTRL_BYASS_EN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_FWDL_FLOW_CTRL_BYASS_EN_MASK \ + 0x04000000 /* CSR_FWDL_FLOW_CTRL_BYASS_EN[26] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_FWDL_FLOW_CTRL_BYASS_EN_SHFT \ + 26 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_TX_DISP_ARB_MODE_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_TX_DISP_ARB_MODE_MASK \ + 0x03000000 /* CSR_TX_DISP_ARB_MODE[25..24] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_TX_DISP_ARB_MODE_SHFT 24 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_TX_DISP_ARB_SCHEDULED_ACCESS_TIMER_AD\ +DR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_TX_DISP_ARB_SCHEDULED_ACCESS_TIMER_MA\ +SK \ +0x00FF0000 /* CSR_TX_DISP_ARB_SCHEDULED_ACCESS_TIMER[23..16] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_TX_DISP_ARB_SCHEDULED_ACCESS_TIMER_SH\ +FT \ +16 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_TXFIFO1_RDY_THRESHOLD_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_TXFIFO1_RDY_THRESHOLD_MASK \ + 0x0000FF00 /* CSR_TXFIFO1_RDY_THRESHOLD[15..8] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_TXFIFO1_RDY_THRESHOLD_SHFT 8 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_TXFIFO0_RDY_THRESHOLD_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_TXFIFO0_RDY_THRESHOLD_MASK \ + 0x000000FF /* CSR_TXFIFO0_RDY_THRESHOLD[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_TXFIFO0_RDY_THRESHOLD_SHFT 0 + +/* +* ---WPDMA_AXI_MST_DBG0 (0x7C024000 + 0x2B8)--- +* M0_AXI_RRESP_ERROR_RRESP[1..0] - (W1C) tx_pfet AXI rresp +* RESERVED2[3..2] - (RO) Reserved bits +* M0_AXI_RRESP_ERROR_RID[7..4] - (W1C) tx_pfet AXI rid +* M1_AXI_RRESP_ERROR_RRESP[9..8] - (W1C) pf_dfet_rx AXI rresp +* RESERVED10[11..10] - (RO) Reserved bits +* M1_AXI_RRESP_ERROR_RID[15..12] - (W1C) pf_dfet_rx AXI rid +* M2_AXI_RRESP_ERROR_RRESP[17..16] - (W1C) pf_dfet_tx AXI rresp +* RESERVED18[19..18] - (RO) Reserved bits +* M2_AXI_RRESP_ERROR_RID[23..20] - (W1C) pf_dfet_tx AXI rid +* M0_AXI_RRESP_ERROR[24] - (W1C) tx_pfet_tx AXI rresp_error +* M1_AXI_RRESP_ERROR[25] - (W1C) pf_dfet_rx AXI rresp_error +* M2_AXI_RRESP_ERROR[26] - (W1C) pf_dfet_tx AXI rresp_error +* RESERVED27[31..27] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG0_M2_AXI_RRESP_ERROR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG0_M2_AXI_RRESP_ERROR_MASK \ + 0x04000000 /* M2_AXI_RRESP_ERROR[26] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG0_M2_AXI_RRESP_ERROR_SHFT 26 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG0_M1_AXI_RRESP_ERROR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG0_M1_AXI_RRESP_ERROR_MASK \ + 0x02000000 /* M1_AXI_RRESP_ERROR[25] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG0_M1_AXI_RRESP_ERROR_SHFT 25 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG0_M0_AXI_RRESP_ERROR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG0_M0_AXI_RRESP_ERROR_MASK \ + 0x01000000 /* M0_AXI_RRESP_ERROR[24] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG0_M0_AXI_RRESP_ERROR_SHFT 24 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG0_M2_AXI_RRESP_ERROR_RID_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG0_M2_AXI_RRESP_ERROR_RID_MASK \ + 0x00F00000 /* M2_AXI_RRESP_ERROR_RID[23..20] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG0_M2_AXI_RRESP_ERROR_RID_SHFT 20 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG0_M2_AXI_RRESP_ERROR_RRESP_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG0_M2_AXI_RRESP_ERROR_RRESP_MASK \ + 0x00030000 /* M2_AXI_RRESP_ERROR_RRESP[17..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG0_M2_AXI_RRESP_ERROR_RRESP_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG0_M1_AXI_RRESP_ERROR_RID_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG0_M1_AXI_RRESP_ERROR_RID_MASK \ + 0x0000F000 /* M1_AXI_RRESP_ERROR_RID[15..12] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG0_M1_AXI_RRESP_ERROR_RID_SHFT 12 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG0_M1_AXI_RRESP_ERROR_RRESP_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG0_M1_AXI_RRESP_ERROR_RRESP_MASK \ + 0x00000300 /* M1_AXI_RRESP_ERROR_RRESP[9..8] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG0_M1_AXI_RRESP_ERROR_RRESP_SHFT 8 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG0_M0_AXI_RRESP_ERROR_RID_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG0_M0_AXI_RRESP_ERROR_RID_MASK \ + 0x000000F0 /* M0_AXI_RRESP_ERROR_RID[7..4] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG0_M0_AXI_RRESP_ERROR_RID_SHFT 4 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG0_M0_AXI_RRESP_ERROR_RRESP_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG0_M0_AXI_RRESP_ERROR_RRESP_MASK \ + 0x00000003 /* M0_AXI_RRESP_ERROR_RRESP[1..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG0_M0_AXI_RRESP_ERROR_RRESP_SHFT 0 + +/* +* ---WPDMA_AXI_MST_DBG1 (0x7C024000 + 0x2BC)--- +* M0_AXI_BRESP_ERROR_BRESP[1..0] - (W1C) rx_pfet AXI bresp +* RESERVED2[3..2] - (RO) Reserved bits +* M0_AXI_BRESP_ERROR_RID[7..4] - (W1C) rx_pfet AXI bid +* M1_AXI_BRESP_ERROR_BRESP[9..8] - (W1C) wb_dfet_rx AXI bresp +* RESERVED10[11..10] - (RO) Reserved bits +* M1_AXI_BRESP_ERROR_RID[15..12] - (W1C) wb_dfet_rx AXI bid +* M2_AXI_BRESP_ERROR_BRESP[17..16] - (W1C) wb_dfet_tx AXI bresp +* RESERVED18[19..18] - (RO) Reserved bits +* M2_AXI_BRESP_ERROR_RID[23..20] - (W1C) wb_dfet_tx AXI bid +* M0_AXI_BRESP_ERROR[24] - (W1C) tx_pfet_tx AXI bresp_error +* M1_AXI_BRESP_ERROR[25] - (W1C) pf_dfet_rx AXI bresp_error +* M2_AXI_BRESP_ERROR[26] - (W1C) pf_dfet_tx AXI bresp_error +* RESERVED27[31..27] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG1_M2_AXI_BRESP_ERROR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG1_M2_AXI_BRESP_ERROR_MASK \ + 0x04000000 /* M2_AXI_BRESP_ERROR[26] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG1_M2_AXI_BRESP_ERROR_SHFT 26 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG1_M1_AXI_BRESP_ERROR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG1_M1_AXI_BRESP_ERROR_MASK \ + 0x02000000 /* M1_AXI_BRESP_ERROR[25] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG1_M1_AXI_BRESP_ERROR_SHFT 25 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG1_M0_AXI_BRESP_ERROR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG1_M0_AXI_BRESP_ERROR_MASK \ + 0x01000000 /* M0_AXI_BRESP_ERROR[24] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG1_M0_AXI_BRESP_ERROR_SHFT 24 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG1_M2_AXI_BRESP_ERROR_RID_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG1_M2_AXI_BRESP_ERROR_RID_MASK \ + 0x00F00000 /* M2_AXI_BRESP_ERROR_RID[23..20] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG1_M2_AXI_BRESP_ERROR_RID_SHFT 20 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG1_M2_AXI_BRESP_ERROR_BRESP_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG1_M2_AXI_BRESP_ERROR_BRESP_MASK \ + 0x00030000 /* M2_AXI_BRESP_ERROR_BRESP[17..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG1_M2_AXI_BRESP_ERROR_BRESP_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG1_M1_AXI_BRESP_ERROR_RID_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG1_M1_AXI_BRESP_ERROR_RID_MASK \ + 0x0000F000 /* M1_AXI_BRESP_ERROR_RID[15..12] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG1_M1_AXI_BRESP_ERROR_RID_SHFT 12 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG1_M1_AXI_BRESP_ERROR_BRESP_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG1_M1_AXI_BRESP_ERROR_BRESP_MASK \ + 0x00000300 /* M1_AXI_BRESP_ERROR_BRESP[9..8] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG1_M1_AXI_BRESP_ERROR_BRESP_SHFT 8 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG1_M0_AXI_BRESP_ERROR_RID_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG1_M0_AXI_BRESP_ERROR_RID_MASK \ + 0x000000F0 /* M0_AXI_BRESP_ERROR_RID[7..4] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG1_M0_AXI_BRESP_ERROR_RID_SHFT 4 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG1_M0_AXI_BRESP_ERROR_BRESP_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG1_M0_AXI_BRESP_ERROR_BRESP_MASK \ + 0x00000003 /* M0_AXI_BRESP_ERROR_BRESP[1..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_DBG1_M0_AXI_BRESP_ERROR_BRESP_SHFT 0 + +/* +* ---WPDMA_TX_QOS_LMT_CFG0 (0x7C024000 + 0x2C0)--- +* CSR_TX_PLD_0_AXI_LIMITER_REQ[2..0] - (RW) QoS CR, Limiter Enable for packet +* traffice of type TX_PLD_0 +* CSR_TX_PLD_0_AXI_LIMITER_EN_REQ[3] - (RW) QoS CR, Limiter Enable for packet +* traffice of type TX_PLD_0 +* CSR_TX_PLD_0_AXI_LIMITER_PKT[6..4] - (RW) QoS CR, Limiter Enable for packet +* traffice of type TX_PLD_0 +* CSR_TX_PLD_0_AXI_LIMITER_EN_PKT[7] - (RW) QoS CR, Limiter Enable for packet +* traffice of type TX_PLD_0 +* CSR_TX_PLD_1_PLD_AXI_LIMITER_REQ[10..8] - (RW) QoS CR, Limiter Enable for +* request traffice of type TX_PLD_1_PLD +* CSR_TX_PLD_1_PLD_AXI_LIMITER_EN_REQ[11] - (RW) QoS CR, Limiter Enable for +* request traffice of type TX_PLD_1_PLD +* CSR_TX_PLD_1_PLD_AXI_LIMITER_PKT[14..12] - (RW) QoS CR, Limiter Enable for +* request traffice of type TX_PLD_1_PLD +* CSR_TX_PLD_1_PLD_AXI_LIMITER_EN_PKT[15] - (RW) QoS CR, Limiter Enable for +* request traffice of type TX_PLD_1_PLD +* CSR_RX_PLD_AXI_LIMITER_REQ[18..16] - (RW) QoS CR, Limiter Enable for request +* traffice of type RX_PLD +* CSR_RX_PLD_AXI_LIMITER_EN_REQ[19] - (RW) QoS CR, Limiter Enable for request +* traffice of type RX_PLD +* CSR_RX_PLD_AXI_LIMITER_PKT[22..20] - (RW) QoS CR, Limiter Enable for request +* traffice of type RX_PLD +* CSR_RX_PLD_AXI_LIMITER_EN_PKT[23] - (RW) QoS CR, Limiter Enable for request +* traffice of type RX_PLD +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_EN_PKT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_EN_PKT_MASK \ + 0x00800000 /* CSR_RX_PLD_AXI_LIMITER_EN_PKT[23] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_EN_PKT_SHFT \ + 23 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_PKT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_PKT_MASK \ + 0x00700000 /* CSR_RX_PLD_AXI_LIMITER_PKT[22..20] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_PKT_SHFT \ + 20 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_EN_REQ_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_EN_REQ_MASK \ + 0x00080000 /* CSR_RX_PLD_AXI_LIMITER_EN_REQ[19] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_EN_REQ_SHFT \ + 19 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_REQ_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_REQ_MASK \ + 0x00070000 /* CSR_RX_PLD_AXI_LIMITER_REQ[18..16] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_REQ_SHFT \ + 16 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_1_PLD_AXI_LIMITER_EN_PKT_AD\ +DR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_1_PLD_AXI_LIMITER_EN_PKT_MA\ +SK \ +0x00008000 /* CSR_TX_PLD_1_PLD_AXI_LIMITER_EN_PKT[15] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_1_PLD_AXI_LIMITER_EN_PKT_SH\ +FT \ +15 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_1_PLD_AXI_LIMITER_PKT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_1_PLD_AXI_LIMITER_PKT_MASK \ + 0x00007000 /* CSR_TX_PLD_1_PLD_AXI_LIMITER_PKT[14..12] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_1_PLD_AXI_LIMITER_PKT_SHFT \ + 12 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_1_PLD_AXI_LIMITER_EN_REQ_AD\ +DR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_1_PLD_AXI_LIMITER_EN_REQ_MA\ +SK \ +0x00000800 /* CSR_TX_PLD_1_PLD_AXI_LIMITER_EN_REQ[11] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_1_PLD_AXI_LIMITER_EN_REQ_SH\ +FT \ +11 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_1_PLD_AXI_LIMITER_REQ_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_1_PLD_AXI_LIMITER_REQ_MASK \ + 0x00000700 /* CSR_TX_PLD_1_PLD_AXI_LIMITER_REQ[10..8] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_1_PLD_AXI_LIMITER_REQ_SHFT \ + 8 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_0_AXI_LIMITER_EN_PKT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_0_AXI_LIMITER_EN_PKT_MASK \ + 0x00000080 /* CSR_TX_PLD_0_AXI_LIMITER_EN_PKT[7] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_0_AXI_LIMITER_EN_PKT_SHFT \ + 7 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_0_AXI_LIMITER_PKT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_0_AXI_LIMITER_PKT_MASK \ + 0x00000070 /* CSR_TX_PLD_0_AXI_LIMITER_PKT[6..4] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_0_AXI_LIMITER_PKT_SHFT \ + 4 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_0_AXI_LIMITER_EN_REQ_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_0_AXI_LIMITER_EN_REQ_MASK \ + 0x00000008 /* CSR_TX_PLD_0_AXI_LIMITER_EN_REQ[3] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_0_AXI_LIMITER_EN_REQ_SHFT \ + 3 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_0_AXI_LIMITER_REQ_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_0_AXI_LIMITER_REQ_MASK \ + 0x00000007 /* CSR_TX_PLD_0_AXI_LIMITER_REQ[2..0] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_0_AXI_LIMITER_REQ_SHFT \ + 0 + +/* +* ---WPDMA_TX_QOS_LMT_CFG1 (0x7C024000 + 0x2C4)--- +* CSR_AUX_TX_PLD_0_AXI_LIMITER_REQ[2..0] - (RW) QoS CR, Limiter value selected +* by PP dynamically +* RESERVED3[3] - (RO) Reserved bits +* CSR_AUX_TX_PLD_0_AXI_LIMITER_PKT[6..4] - (RW) QoS CR, Limiter value selected +* by PP dynamically +* RESERVED7[7] - (RO) Reserved bits +* CSR_AUX_TX_PLD_1_AXI_LIMITER_REQ[10..8] - (RW) QoS CR, Limiter value selected +* by PP dynamically +* RESERVED11[11] - (RO) Reserved bits +* CSR_AUX_TX_PLD_1_AXI_LIMITER_PKT[14..12] - (RW) QoS CR, Limiter value selected +* by PP dynamically +* RESERVED15[15] - (RO) Reserved bits +* CSR_AUX_RX_PLD_AXI_LIMITER_REQ[18..16] - (RW) QoS CR, Limiter value selected +* by PP dynamically +* RESERVED19[19] - (RO) Reserved bits +* CSR_AUX_RX_PLD_AXI_LIMITER_PKT[22..20] - (RW) QoS CR, Limiter value selected +* by PP dynamically +* RESERVED23[31..23] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_RX_PLD_AXI_LIMITER_PKT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_RX_PLD_AXI_LIMITER_PKT_MASK \ + 0x00700000 /* CSR_AUX_RX_PLD_AXI_LIMITER_PKT[22..20] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_RX_PLD_AXI_LIMITER_PKT_SHFT \ + 20 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_RX_PLD_AXI_LIMITER_REQ_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_RX_PLD_AXI_LIMITER_REQ_MASK \ + 0x00070000 /* CSR_AUX_RX_PLD_AXI_LIMITER_REQ[18..16] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_RX_PLD_AXI_LIMITER_REQ_SHFT \ + 16 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_TX_PLD_1_AXI_LIMITER_PKT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_TX_PLD_1_AXI_LIMITER_PKT_MASK \ + 0x00007000 /* CSR_AUX_TX_PLD_1_AXI_LIMITER_PKT[14..12] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_TX_PLD_1_AXI_LIMITER_PKT_SHFT \ + 12 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_TX_PLD_1_AXI_LIMITER_REQ_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_TX_PLD_1_AXI_LIMITER_REQ_MASK \ + 0x00000700 /* CSR_AUX_TX_PLD_1_AXI_LIMITER_REQ[10..8] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_TX_PLD_1_AXI_LIMITER_REQ_SHFT \ + 8 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_TX_PLD_0_AXI_LIMITER_PKT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_TX_PLD_0_AXI_LIMITER_PKT_MASK \ + 0x00000070 /* CSR_AUX_TX_PLD_0_AXI_LIMITER_PKT[6..4] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_TX_PLD_0_AXI_LIMITER_PKT_SHFT \ + 4 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_TX_PLD_0_AXI_LIMITER_REQ_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_TX_PLD_0_AXI_LIMITER_REQ_MASK \ + 0x00000007 /* CSR_AUX_TX_PLD_0_AXI_LIMITER_REQ[2..0] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_TX_PLD_0_AXI_LIMITER_REQ_SHFT \ + 0 + +/* +* ---WPDMA_TX_QOS_LMT_CFG2 (0x7C024000 + 0x2C8)--- +* CSR_RX_RD_DMAD_AXI_LIMITER_REQ[2..0] - (RW) QoS CR, Limiter Value for packet +* traffice of type RX_RD_DMAD +* CSR_RX_RD_DMAD_AXI_LIMITER_EN_REQ[3] - (RW) QoS CR, Limiter Enable for request +* traffice of type RX_RD_DMAD +* CSR_RX_RD_DMAD_AXI_LIMITER_PKT[6..4] - (RW) QoS CR, Limiter Value for packet +* traffice of type RX_RD_DMAD +* CSR_RX_RD_DMAD_AXI_LIMITER_EN_PKT[7] - (RW) QoS CR, Limiter Enable for packet +* traffice of type RX_RD_DMAD +* CSR_RX_WR_DMAD_AXI_LIMITER_REQ[10..8] - (RW) QoS CR, Limiter Value for packet +* traffice of type RX_WR_DMAD +* CSR_RX_WR_DMAD_AXI_LIMITER_EN_REQ[11] - (RW) QoS CR, Limiter Enable for +* request traffice of type RX_WR_DMAD +* CSR_RX_WR_DMAD_AXI_LIMITER_PKT[14..12] - (RW) QoS CR, Limiter Value for packet +* traffice of type RX_WR_DMAD +* CSR_RX_WR_DMAD_AXI_LIMITER_EN_PKT[15] - (RW) QoS CR, Limiter Enable for packet +* traffice of type RX_WR_DMAD +* CSR_TX_RD_DMAD_AXI_LIMITER_REQ[18..16] - (RW) QoS CR, Limiter Value for packet +* traffice of type TX_RD_DMAD +* CSR_TX_RD_DMAD_AXI_LIMITER_EN_REQ[19] - (RW) QoS CR, Limiter Enable for +* request traffice of type TX_RD_DMAD +* CSR_TX_RD_DMAD_AXI_LIMITER_PKT[22..20] - (RW) QoS CR, Limiter Value for packet +* traffice of type TX_RD_DMAD +* CSR_TX_RD_DMAD_AXI_LIMITER_EN_PKT[23] - (RW) QoS CR, Limiter Enable for packet +* traffice of type TX_RD_DMAD +* CSR_TX_WR_DMAD_AXI_LIMITER_REQ[26..24] - (RW) QoS CR, Limiter Value for packet +* traffice of type TX_WR_DMAD +* CSR_TX_WR_DMAD_AXI_LIMITER_EN_REQ[27] - (RW) QoS CR, Limiter Enable for +* request traffice of type TX_WR_DMAD +* CSR_TX_WR_DMAD_AXI_LIMITER_PKT[30..28] - (RW) QoS CR, Limiter Value for packet +* traffice of type TX_WR_DMAD +* CSR_TX_WR_DMAD_AXI_LIMITER_EN_PKT[31] - (RW) QoS CR, Limiter Enable for packet +* traffice of type TX_WR_DMAD +*/ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_EN_PKT_ADDR\ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_EN_PKT_MASK\ +0x80000000 /* CSR_TX_WR_DMAD_AXI_LIMITER_EN_PKT[31] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_EN_PKT_SHFT\ +31 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_PKT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_PKT_MASK \ + 0x70000000 /* CSR_TX_WR_DMAD_AXI_LIMITER_PKT[30..28] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_PKT_SHFT \ + 28 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_EN_REQ_ADDR\ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_EN_REQ_MASK\ +0x08000000 /* CSR_TX_WR_DMAD_AXI_LIMITER_EN_REQ[27] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_EN_REQ_SHFT\ +27 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_REQ_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_REQ_MASK \ + 0x07000000 /* CSR_TX_WR_DMAD_AXI_LIMITER_REQ[26..24] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_REQ_SHFT \ + 24 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_EN_PKT_ADDR\ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_EN_PKT_MASK\ +0x00800000 /* CSR_TX_RD_DMAD_AXI_LIMITER_EN_PKT[23] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_EN_PKT_SHFT\ +23 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_PKT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_PKT_MASK \ + 0x00700000 /* CSR_TX_RD_DMAD_AXI_LIMITER_PKT[22..20] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_PKT_SHFT \ + 20 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_EN_REQ_ADDR\ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_EN_REQ_MASK\ +0x00080000 /* CSR_TX_RD_DMAD_AXI_LIMITER_EN_REQ[19] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_EN_REQ_SHFT\ +19 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_REQ_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_REQ_MASK \ + 0x00070000 /* CSR_TX_RD_DMAD_AXI_LIMITER_REQ[18..16] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_REQ_SHFT \ + 16 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_EN_PKT_ADDR\ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_EN_PKT_MASK\ +0x00008000 /* CSR_RX_WR_DMAD_AXI_LIMITER_EN_PKT[15] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_EN_PKT_SHFT\ +15 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_PKT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_PKT_MASK \ + 0x00007000 /* CSR_RX_WR_DMAD_AXI_LIMITER_PKT[14..12] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_PKT_SHFT \ + 12 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_EN_REQ_ADDR\ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_EN_REQ_MASK\ +0x00000800 /* CSR_RX_WR_DMAD_AXI_LIMITER_EN_REQ[11] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_EN_REQ_SHFT\ +11 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_REQ_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_REQ_MASK \ + 0x00000700 /* CSR_RX_WR_DMAD_AXI_LIMITER_REQ[10..8] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_REQ_SHFT \ + 8 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_EN_PKT_ADDR\ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_EN_PKT_MASK\ +0x00000080 /* CSR_RX_RD_DMAD_AXI_LIMITER_EN_PKT[7] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_EN_PKT_SHFT\ +7 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_PKT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_PKT_MASK \ + 0x00000070 /* CSR_RX_RD_DMAD_AXI_LIMITER_PKT[6..4] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_PKT_SHFT \ + 4 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_EN_REQ_ADDR\ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_EN_REQ_MASK\ +0x00000008 /* CSR_RX_RD_DMAD_AXI_LIMITER_EN_REQ[3] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_EN_REQ_SHFT\ +3 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_REQ_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_REQ_MASK \ + 0x00000007 /* CSR_RX_RD_DMAD_AXI_LIMITER_REQ[2..0] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_REQ_SHFT \ + 0 + +/* +* ---WPDMA_TX_QOS_LMT_CFG3 (0x7C024000 + 0x2CC)--- +* CSR_AUX_RX_RD_DMAD_AXI_LIMITER_REQ[2..0] - (RW) QoS CR, Limiter value selected +* by PP dynamically +* RESERVED3[3] - (RO) Reserved bits +* CSR_AUX_RX_RD_DMAD_AXI_LIMITER_PKT[6..4] - (RW) QoS CR, Limiter value selected +* by PP dynamically +* RESERVED7[7] - (RO) Reserved bits +* CSR_AUX_RX_WR_DMAD_AXI_LIMITER_REQ[10..8] - (RW) QoS CR, Limiter value +* selected by PP dynamically +* RESERVED11[11] - (RO) Reserved bits +* CSR_AUX_RX_WR_DMAD_AXI_LIMITER_PKT[14..12] - (RW) QoS CR, Limiter value +* selected by PP dynamically +* RESERVED15[15] - (RO) Reserved bits +* CSR_AUX_TX_RD_DMAD_AXI_LIMITER_REQ[18..16] - (RW) QoS CR, Limiter value +* selected by PP dynamically +* RESERVED19[19] - (RO) Reserved bits +* CSR_AUX_TX_RD_DMAD_AXI_LIMITER_PKT[22..20] - (RW) QoS CR, Limiter value +* selected by PP dynamically +* RESERVED23[23] - (RO) Reserved bits +* CSR_AUX_TX_WR_DMAD_AXI_LIMITER_REQ[26..24] - (RW) QoS CR, Limiter value +* selected by PP dynamically +* RESERVED27[27] - (RO) Reserved bits +* CSR_AUX_TX_WR_DMAD_AXI_LIMITER_PKT[30..28] - (RW) QoS CR, Limiter value +* selected by PP dynamically +* RESERVED31[31] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_WR_DMAD_AXI_LIMITER_PKT_ADD\ +R \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_WR_DMAD_AXI_LIMITER_PKT_MAS\ +K \ +0x70000000 /* CSR_AUX_TX_WR_DMAD_AXI_LIMITER_PKT[30..28] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_WR_DMAD_AXI_LIMITER_PKT_SHF\ +T \ +28 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_WR_DMAD_AXI_LIMITER_REQ_ADD\ +R \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_WR_DMAD_AXI_LIMITER_REQ_MAS\ +K \ +0x07000000 /* CSR_AUX_TX_WR_DMAD_AXI_LIMITER_REQ[26..24] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_WR_DMAD_AXI_LIMITER_REQ_SHF\ +T \ +24 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_RD_DMAD_AXI_LIMITER_PKT_ADD\ +R \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_RD_DMAD_AXI_LIMITER_PKT_MAS\ +K \ +0x00700000 /* CSR_AUX_TX_RD_DMAD_AXI_LIMITER_PKT[22..20] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_RD_DMAD_AXI_LIMITER_PKT_SHF\ +T \ +20 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_RD_DMAD_AXI_LIMITER_REQ_ADD\ +R \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_RD_DMAD_AXI_LIMITER_REQ_MAS\ +K \ +0x00070000 /* CSR_AUX_TX_RD_DMAD_AXI_LIMITER_REQ[18..16] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_RD_DMAD_AXI_LIMITER_REQ_SHF\ +T \ +16 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_WR_DMAD_AXI_LIMITER_PKT_ADD\ +R \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_WR_DMAD_AXI_LIMITER_PKT_MAS\ +K \ +0x00007000 /* CSR_AUX_RX_WR_DMAD_AXI_LIMITER_PKT[14..12] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_WR_DMAD_AXI_LIMITER_PKT_SHF\ +T \ +12 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_WR_DMAD_AXI_LIMITER_REQ_ADD\ +R \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_WR_DMAD_AXI_LIMITER_REQ_MAS\ +K \ +0x00000700 /* CSR_AUX_RX_WR_DMAD_AXI_LIMITER_REQ[10..8] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_WR_DMAD_AXI_LIMITER_REQ_SHF\ +T \ +8 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_RD_DMAD_AXI_LIMITER_PKT_ADD\ +R \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_RD_DMAD_AXI_LIMITER_PKT_MAS\ +K \ +0x00000070 /* CSR_AUX_RX_RD_DMAD_AXI_LIMITER_PKT[6..4] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_RD_DMAD_AXI_LIMITER_PKT_SHF\ +T \ +4 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_RD_DMAD_AXI_LIMITER_REQ_ADD\ +R \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_RD_DMAD_AXI_LIMITER_REQ_MAS\ +K \ +0x00000007 /* CSR_AUX_RX_RD_DMAD_AXI_LIMITER_REQ[2..0] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_RD_DMAD_AXI_LIMITER_REQ_SHF\ +T \ +0 + +/* +* ---WPDMA_TX_QOS_QTM_CFG0 (0x7C024000 + 0x2D0)--- +* CSR_TXP0_FFA_QTM[3..0] - (RW) CSR_TXP0_FFA_QTM +* CSR_TXP0_RSVD_QTM[7..4] - (RW) CSR_TXP0_RSVD_QTM +* CSR_TXP1_FFA_QTM[11..8] - (RW) CSR_TXP1_FFA_QTM +* CSR_TXP1_RSVD_QTM[15..12] - (RW) CSR_TXP1_RSVD_QTM +* RESERVED16[23..16] - (RO) Reserved bits +* CSR_FFA_TOTAL_QTM[27..24] - (RW) CSR_FFA_TOTAL_QTM +* CSR_QOS_QTM_MODE[29..28] - (RW) 2'b01 : csr_rsvd_qtm_mode_only, 2'b10 : +* csr_ffa_qtm_mode_only, others : rsvd+ffa mode +* RESERVED30[31..30] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_QOS_QTM_MODE_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_QOS_QTM_MODE_MASK \ + 0x30000000 /* CSR_QOS_QTM_MODE[29..28] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_QOS_QTM_MODE_SHFT 28 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_FFA_TOTAL_QTM_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_FFA_TOTAL_QTM_MASK \ + 0x0F000000 /* CSR_FFA_TOTAL_QTM[27..24] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_FFA_TOTAL_QTM_SHFT 24 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_TXP1_RSVD_QTM_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_TXP1_RSVD_QTM_MASK \ + 0x0000F000 /* CSR_TXP1_RSVD_QTM[15..12] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_TXP1_RSVD_QTM_SHFT 12 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_TXP1_FFA_QTM_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_TXP1_FFA_QTM_MASK \ + 0x00000F00 /* CSR_TXP1_FFA_QTM[11..8] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_TXP1_FFA_QTM_SHFT 8 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_TXP0_RSVD_QTM_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_TXP0_RSVD_QTM_MASK \ + 0x000000F0 /* CSR_TXP0_RSVD_QTM[7..4] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_TXP0_RSVD_QTM_SHFT 4 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_TXP0_FFA_QTM_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_TXP0_FFA_QTM_MASK \ + 0x0000000F /* CSR_TXP0_FFA_QTM[3..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_TXP0_FFA_QTM_SHFT 0 + +/* +* ---WPDMA_TX_QOS_QTM_CFG1 (0x7C024000 + 0x2D4)--- +* CSR_DMAD_FFA_QTM[3..0] - (RW) CSR_DMAD_FFA_QTM +* CSR_DMAD_RSVD_QTM[7..4] - (RW) CSR_DMAD_RSVD_QTM +* CSR_TXD_FFA_QTM[11..8] - (RW) CSR_TXD_FFA_QTM +* CSR_TXD_RSVD_QTM[15..12] - (RW) CSR_TXD_RSVD_QTM +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_CSR_TXD_RSVD_QTM_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_CSR_TXD_RSVD_QTM_MASK \ + 0x0000F000 /* CSR_TXD_RSVD_QTM[15..12] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_CSR_TXD_RSVD_QTM_SHFT 12 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_CSR_TXD_FFA_QTM_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_CSR_TXD_FFA_QTM_MASK \ + 0x00000F00 /* CSR_TXD_FFA_QTM[11..8] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_CSR_TXD_FFA_QTM_SHFT 8 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_CSR_DMAD_RSVD_QTM_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_CSR_DMAD_RSVD_QTM_MASK \ + 0x000000F0 /* CSR_DMAD_RSVD_QTM[7..4] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_CSR_DMAD_RSVD_QTM_SHFT 4 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_CSR_DMAD_FFA_QTM_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_CSR_DMAD_FFA_QTM_MASK \ + 0x0000000F /* CSR_DMAD_FFA_QTM[3..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_CSR_DMAD_FFA_QTM_SHFT 0 + +/* +* ---HOST_PRI_INT_STA (0x7C024000 + 0x2E0)--- +* host_pri_int_sts_0[0] - (W1C) rx_done_int[0], configuration interrupt please +* refer to 0x2E0 WPDMA_PRI_DLY_INT_CFG0[15:0] +* host_pri_int_sts_1[1] - (W1C) rx_done_int[1], configuration interrupt please +* refer to 0x2E0 WPDMA_PRI_DLY_INT_CFG0[31:16] +* RESERVED2[31..2] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_HOST_PRI_INT_STA_host_pri_int_sts_1_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_PRI_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_PRI_INT_STA_host_pri_int_sts_1_MASK \ + 0x00000002 /* host_pri_int_sts_1[1] */ +#define WF_WFDMA_HOST_DMA0_HOST_PRI_INT_STA_host_pri_int_sts_1_SHFT 1 +#define WF_WFDMA_HOST_DMA0_HOST_PRI_INT_STA_host_pri_int_sts_0_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_PRI_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_PRI_INT_STA_host_pri_int_sts_0_MASK \ + 0x00000001 /* host_pri_int_sts_0[0] */ +#define WF_WFDMA_HOST_DMA0_HOST_PRI_INT_STA_host_pri_int_sts_0_SHFT 0 + +/* +* ---HOST_PER_INT_ENA_STA (0x7C024000 + 0x2E4)--- +* wpdma_per_int_sts[3..0] - (W1C) status bit for rx ring periodic delayed +* interrupt to tracking ring is full or not, start delayed interrupt timer when +* RX ring is not full from falling edge of full flag and reset when ring full +* flag is asserted +* RESERVED4[15..4] - (RO) Reserved bits +* wpdma_per_int_ena[19..16] - (RW) enable bit for rx ring periodic delayed +* interrupt to tracking ring is full or not, start delayed interrupt timer when +* RX ring is not full from falling edge of full flag and reset when ring full +* flag is asserted +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_HOST_PER_INT_ENA_STA_wpdma_per_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_PER_INT_ENA_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_PER_INT_ENA_STA_wpdma_per_int_ena_MASK \ + 0x000F0000 /* wpdma_per_int_ena[19..16] */ +#define WF_WFDMA_HOST_DMA0_HOST_PER_INT_ENA_STA_wpdma_per_int_ena_SHFT 16 +#define WF_WFDMA_HOST_DMA0_HOST_PER_INT_ENA_STA_wpdma_per_int_sts_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_PER_INT_ENA_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_PER_INT_ENA_STA_wpdma_per_int_sts_MASK \ + 0x0000000F /* wpdma_per_int_sts[3..0] */ +#define WF_WFDMA_HOST_DMA0_HOST_PER_INT_ENA_STA_wpdma_per_int_sts_SHFT 0 + +/* +* ---HOST_PER_DLY_INT_CFG (0x7C024000 + 0x2E8)--- +* wpdma_per_max_ptime[7..0] - (RW) Specified Max pending time for the internal +* RX ring full flag falling edge. When the pending time equal or greater +* PER_MAX_PTIME x 20us or the # of pended TX_DONE_INT equal or greater than +* TX_MAX_PINT (see above), an Final TX_DLY_INT is generated +* Set to 0 will disable pending interrupt time check +* wpdma_per_dly_int_en[11..8] - (RW) RX periodic Delayed Interrupt Enable +* 1: Enable RX periodic delayed interrupt mechanism +* 0: Disable RX periodic delayed interrupt mechanism +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_HOST_PER_DLY_INT_CFG_wpdma_per_dly_int_en_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_PER_DLY_INT_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_PER_DLY_INT_CFG_wpdma_per_dly_int_en_MASK \ + 0x00000F00 /* wpdma_per_dly_int_en[11..8] */ +#define WF_WFDMA_HOST_DMA0_HOST_PER_DLY_INT_CFG_wpdma_per_dly_int_en_SHFT 8 +#define WF_WFDMA_HOST_DMA0_HOST_PER_DLY_INT_CFG_wpdma_per_max_ptime_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_PER_DLY_INT_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_PER_DLY_INT_CFG_wpdma_per_max_ptime_MASK \ + 0x000000FF /* wpdma_per_max_ptime[7..0] */ +#define WF_WFDMA_HOST_DMA0_HOST_PER_DLY_INT_CFG_wpdma_per_max_ptime_SHFT 0 + +/* +* ---WPDMA_PRI_DLY_INT_CFG0 (0x7C024000 + 0x2F0)--- +* PRI0_MAX_PTIME[7..0] - (RW) Specified Max pending time for the internal +* PRI0_DONE_INT. When the pending time equal or greater PRI0_MAX_PTIME x 20us or +* the # of pended PRI0_DONE_INT equal or greater than PRI0_MAX_PINT (see above), +* an Final PRI0_DLY_INT is generated +* Set to 0 will disable pending interrupt time check +* PRI0_MAX_PINT[14..8] - (RW) Specified Max # of pended interrupts. +* When the # of pended interrupts equal or greater than the value specified here +* or interrupt pending time reach the limit (See below), a Final PRI0_DLY_INT is +generated. +* Set to 0 will disable pending interrupt count check +* PRI0_DLY_INT_EN[15] - (RW) Priority Delayed Interrupt Enable +* 1: Enable Priority delayed interrupt mechanism +* 0: Disable Priority delayed interrupt mechanism +* In AXE host_dma0, these PRI1_* settings are for rx_ring[1]_int, and PRI0_* +* settings are for rx_ring[0]_int +* In AXE host_dma1, these PRI1_* settings are for rx_ring[0]_int, and PRI0_* +* settings are for Ored-tx_ring[14:0]_int +* In AXE mcu_dma0 and mcu_dma1, there are no priority interrupt thus no this +* 0x2E0 CR!! +* PRI1_MAX_PTIME[23..16] - (RW) Specified Max pending time for the internal +* PRI1_DONE_INT. When the pending time equal or greater PRI1_MAX_PTIME x 20us or +* the # of pended PRI1_DONE_INT equal or greater than PRI1_MAX_PINT (see above), +* an Final PRI1_DLY_INT is generated +* Set to 0 will disable pending interrupt time check +* PRI1_MAX_PINT[30..24] - (RW) Specified Max # of pended interrupts. +* When the # of pended interrupts equal or greater than the value specified here +* or interrupt pending time reach the limit (See below), a Final PRI1_DLY_INT is +generated. +* Set to 0 will disable pending interrupt count check +* PRI1_DLY_INT_EN[31] - (RW) Priority Delayed Interrupt Enable +* 1: Enable Priority delayed interrupt mechanism +* 0: Disable Priority delayed interrupt mechanism +* In AXE host_dma0, these PRI1_* settings are for rx_ring[1]_int, and PRI0_* +* settings are for rx_ring[0]_int +* In AXE host_dma1, these PRI1_* settings are for rx_ring[0]_int, and PRI0_* +* settings are for Ored-tx_ring[14:0]_int +* In AXE mcu_dma0 and mcu_dma1, there are no priority interrupt thus no this +* 0x2E0 CR!! +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI1_DLY_INT_EN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI1_DLY_INT_EN_MASK \ + 0x80000000 /* PRI1_DLY_INT_EN[31] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI1_DLY_INT_EN_SHFT 31 +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI1_MAX_PINT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI1_MAX_PINT_MASK \ + 0x7F000000 /* PRI1_MAX_PINT[30..24] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI1_MAX_PINT_SHFT 24 +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI1_MAX_PTIME_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI1_MAX_PTIME_MASK \ + 0x00FF0000 /* PRI1_MAX_PTIME[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI1_MAX_PTIME_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI0_DLY_INT_EN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI0_DLY_INT_EN_MASK \ + 0x00008000 /* PRI0_DLY_INT_EN[15] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI0_DLY_INT_EN_SHFT 15 +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI0_MAX_PINT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI0_MAX_PINT_MASK \ + 0x00007F00 /* PRI0_MAX_PINT[14..8] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI0_MAX_PINT_SHFT 8 +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI0_MAX_PTIME_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI0_MAX_PTIME_MASK \ + 0x000000FF /* PRI0_MAX_PTIME[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI0_MAX_PTIME_SHFT 0 + +/* +* ---WPDMA_TX_RING0_CTRL0 (0x7C024000 + 0x300)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring0 (8-DWORD aligned +address) +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING0_CTRL1 (0x7C024000 + 0x304)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in TXD_Ring0. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of TX_Ring0 +* (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING0_CTRL2 (0x7C024000 + 0x308)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING0_CTRL3 (0x7C024000 + 0x30c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING1_CTRL0 (0x7C024000 + 0x310)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring1 (8-DWORD aligned +address) +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING1_CTRL1 (0x7C024000 + 0x314)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in TXD_Ring1. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of TX_Ring1 +* (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING1_CTRL2 (0x7C024000 + 0x318)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING1_CTRL3 (0x7C024000 + 0x31c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING2_CTRL0 (0x7C024000 + 0x320)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring2 (8-DWORD aligned +address) +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING2_CTRL1 (0x7C024000 + 0x324)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in TXD_Ring2. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of TX_Ring2 +* (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING2_CTRL2 (0x7C024000 + 0x328)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING2_CTRL3 (0x7C024000 + 0x32c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING3_CTRL0 (0x7C024000 + 0x330)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring3 (8-DWORD aligned +address) +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING3_CTRL1 (0x7C024000 + 0x334)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in TXD_Ring3. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of TX_Ring3 +* (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING3_CTRL2 (0x7C024000 + 0x338)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING3_CTRL3 (0x7C024000 + 0x33c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING0_CTRL0 (0x7C024000 + 0x500)--- +* BASE_PTR[31..0] - (RW) Point to the base address of RXD Ring #0 (GE ports). It +* should be a 8-DWORD aligned address +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_RX_RING0_CTRL1 (0x7C024000 + 0x504)--- +* MAX_CNT[11..0] - (RW) The maximum number of RXD count in RXD Ring #0. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of TX_Ring0 +* (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING0_CTRL2 (0x7C024000 + 0x508)--- +* CPU_IDX[11..0] - (RW) Point to the next RXD CPU wants to allocate to RXD Ring +#0. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING0_CTRL3 (0x7C024000 + 0x50c)--- +* DMA_IDX[11..0] - (RW) In normal operation, user dma_index would udated by +* hardware when moving rx packet done. User should not write dma_index. +* Point to the next RXD DMA wants to use in FDS Ring#0. It should be a 8-DWORD +* aligned address. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING1_CTRL0 (0x7C024000 + 0x510)--- +* BASE_PTR[31..0] - (RW) Point to the base address of RXD Ring #1 (GE ports). It +* should be a 8-DWORD aligned address +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_RX_RING1_CTRL1 (0x7C024000 + 0x514)--- +* MAX_CNT[11..0] - (RW) The maximum number of RXD count in RXD Ring #1. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of TX_Ring1 +* (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING1_CTRL2 (0x7C024000 + 0x518)--- +* CPU_IDX[11..0] - (RW) Point to the next RXD CPU wants to allocate to RXD Ring +#1. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING1_CTRL3 (0x7C024000 + 0x51c)--- +* DMA_IDX[11..0] - (RW) In normal operation, user dma_index would udated by +* hardware when moving rx packet done. User should not write dma_index. +* Point to the next RXD DMA wants to use in FDS Ring#1. It should be a 8-DWORD +* aligned address. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING2_CTRL0 (0x7C024000 + 0x520)--- +* BASE_PTR[31..0] - (RW) Point to the base address of RXD Ring #2 (GE ports). It +* should be a 8-DWORD aligned address +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_RX_RING2_CTRL1 (0x7C024000 + 0x524)--- +* MAX_CNT[11..0] - (RW) The maximum number of RXD count in RXD Ring #2. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of TX_Ring2 +* (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING2_CTRL2 (0x7C024000 + 0x528)--- +* CPU_IDX[11..0] - (RW) Point to the next RXD CPU wants to allocate to RXD Ring +#2. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING2_CTRL3 (0x7C024000 + 0x52C)--- +* DMA_IDX[11..0] - (RW) In normal operation, user dma_index would udated by +* hardware when moving rx packet done. User should not write dma_index. +* Point to the next RXD DMA wants to use in FDS Ring#2. It should be a 8-DWORD +* aligned address. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING3_CTRL0 (0x7C024000 + 0x530)--- +* BASE_PTR[31..0] - (RW) Point to the base address of RXD Ring #3 (GE ports). It +* should be a 8-DWORD aligned address +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_RX_RING3_CTRL1 (0x7C024000 + 0x534)--- +* MAX_CNT[11..0] - (RW) The maximum number of RXD count in RXD Ring #3. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of TX_Ring3 +* (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING3_CTRL2 (0x7C024000 + 0x538)--- +* CPU_IDX[11..0] - (RW) Point to the next RXD CPU wants to allocate to RXD Ring +#3. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING3_CTRL3 (0x7C024000 + 0x53C)--- +* DMA_IDX[11..0] - (RW) In normal operation, user dma_index would udated by +* hardware when moving rx packet done. User should not write dma_index. +* Point to the next RXD DMA wants to use in FDS Ring#3. It should be a 8-DWORD +* aligned address. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING0_EXT_CTRL (0x7C024000 + 0x600)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #0 Extension, to configure prefetch +* settings, like base_ptr means each prefetch ring's base address in internal +* prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING1_EXT_CTRL (0x7C024000 + 0x604)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #1 Extension, to configure prefetch +* settings, like base_ptr means each prefetch ring's base address in internal +* prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING2_EXT_CTRL (0x7C024000 + 0x608)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #2 Extension, to configure prefetch +* settings, like base_ptr means each prefetch ring's base address in internal +* prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING3_EXT_CTRL (0x7C024000 + 0x60C)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #3 Extension, to configure prefetch +* settings, like base_ptr means each prefetch ring's base address in internal +* prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING0_EXT_CTRL (0x7C024000 + 0x680)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) RXD Ring #0 Extension, to configure prefetch +* settings, like base_ptr means each prefetch ring's base address in internal +* prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING1_EXT_CTRL (0x7C024000 + 0x684)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) RXD Ring #1 Extension, to configure prefetch +* settings, like base_ptr means each prefetch ring's base address in internal +* prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING2_EXT_CTRL (0x7C024000 + 0x688)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) RXD Ring #2 Extension, to configure prefetch +* settings, like base_ptr means each prefetch ring's base address in internal +* prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING3_EXT_CTRL (0x7C024000 + 0x68C)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) RXD Ring #3 Extension, to configure prefetch +* settings, like base_ptr means each prefetch ring's base address in internal +* prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_AXI_MTR_PERF_CFG (0x7C024000 + 0x900)--- +* AXI_MTR_PERF_SEL_W_CH[2..0] - (RW) csr_axi_mtr_perf_sel_w_ch +* AXI_MTR_BW_W_RST[3] - (RW) csr_axi_mtr_bw_w_rst +* AXI_MTR_LAT_W_RST[4] - (RW) csr_axi_mtr_lat_w_rst +* RESERVED5[7..5] - (RO) Reserved bits +* AXI_MTR_PERF_SEL_R_CH[10..8] - (RW) csr_axi_mtr_perf_sel_r_ch +* AXI_MTR_BW_R_RST[11] - (RW) csr_axi_mtr_bw_r_rst +* AXI_MTR_LAT_R_RST[12] - (RW) csr_axi_mtr_lat_r_rst +* RESERVED13[30..13] - (RO) Reserved bits +* AXI_MTR_ENABLE[31] - (RW) csr_axi_mtr_enable +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_CFG_AXI_MTR_ENABLE_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_CFG_AXI_MTR_ENABLE_MASK \ + 0x80000000 /* AXI_MTR_ENABLE[31] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_CFG_AXI_MTR_ENABLE_SHFT 31 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_CFG_AXI_MTR_LAT_R_RST_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_CFG_AXI_MTR_LAT_R_RST_MASK \ + 0x00001000 /* AXI_MTR_LAT_R_RST[12] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_CFG_AXI_MTR_LAT_R_RST_SHFT 12 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_CFG_AXI_MTR_BW_R_RST_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_CFG_AXI_MTR_BW_R_RST_MASK \ + 0x00000800 /* AXI_MTR_BW_R_RST[11] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_CFG_AXI_MTR_BW_R_RST_SHFT 11 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_CFG_AXI_MTR_PERF_SEL_R_CH_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_CFG_AXI_MTR_PERF_SEL_R_CH_MASK \ + 0x00000700 /* AXI_MTR_PERF_SEL_R_CH[10..8] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_CFG_AXI_MTR_PERF_SEL_R_CH_SHFT 8 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_CFG_AXI_MTR_LAT_W_RST_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_CFG_AXI_MTR_LAT_W_RST_MASK \ + 0x00000010 /* AXI_MTR_LAT_W_RST[4] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_CFG_AXI_MTR_LAT_W_RST_SHFT 4 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_CFG_AXI_MTR_BW_W_RST_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_CFG_AXI_MTR_BW_W_RST_MASK \ + 0x00000008 /* AXI_MTR_BW_W_RST[3] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_CFG_AXI_MTR_BW_W_RST_SHFT 3 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_CFG_AXI_MTR_PERF_SEL_W_CH_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_CFG_AXI_MTR_PERF_SEL_W_CH_MASK \ + 0x00000007 /* AXI_MTR_PERF_SEL_W_CH[2..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_CFG_AXI_MTR_PERF_SEL_W_CH_SHFT 0 + +/* +* ---WPDMA_AXI_MTR_DBG_CFG (0x7C024000 + 0x904)--- +* AXI_MST_DBG_CH_SEL[2..0] - (RW) csr_axi_mst_dbg_ch_sel[2:0] +* RESERVED3[7..3] - (RO) Reserved bits +* MASTER0_AXI_AW_CH_COUNTER_SET[8] - (RW) master0 axi_aw_ch_counter_set +* MASTER0_AXI_W_CH_COUNTER_SET[9] - (RW) master0 axi_w_ch_counter_set +* MASTER0_AXI_B_CH_COUNTER_SET[10] - (RW) master0 axi_b_ch_counter_set +* MASTER0_AXI_AR_CH_COUNTER_SET[11] - (RW) master0 axi_ar_ch_counter_set +* MASTER0_AXI_R_CH_COUNTER_SET[12] - (RW) master0 axi_r_ch_counter_set +* MASTER1_AXI_AW_CH_COUNTER_SET[13] - (RW) master1 axi_aw_ch_counter_set +* MASTER1_AXI_W_CH_COUNTER_SET[14] - (RW) master1 axi_w_ch_counter_set +* MASTER1_AXI_B_CH_COUNTER_SET[15] - (RW) master1 axi_b_ch_counter_set +* MASTER1_AXI_AR_CH_COUNTER_SET[16] - (RW) master1 axi_ar_ch_counter_set +* MASTER1_AXI_R_CH_COUNTER_SET[17] - (RW) master1 axi_r_ch_counter_set +* MASTER2_AXI_AW_CH_COUNTER_SET[18] - (RW) master2 axi_aw_ch_counter_set +* MASTER2_AXI_W_CH_COUNTER_SET[19] - (RW) master2 axi_w_ch_counter_set +* MASTER2_AXI_B_CH_COUNTER_SET[20] - (RW) master2 axi_b_ch_counter_set +* MASTER2_AXI_AR_CH_COUNTER_SET[21] - (RW) master2 axi_ar_ch_counter_set +* MASTER2_AXI_R_CH_COUNTER_SET[22] - (RW) master2 axi_r_ch_counter_set +* RESERVED23[31..23] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER2_AXI_R_CH_COUNTER_SET_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER2_AXI_R_CH_COUNTER_SET_MASK \ + 0x00400000 /* MASTER2_AXI_R_CH_COUNTER_SET[22] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER2_AXI_R_CH_COUNTER_SET_SHFT \ + 22 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER2_AXI_AR_CH_COUNTER_SET_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER2_AXI_AR_CH_COUNTER_SET_MASK \ + 0x00200000 /* MASTER2_AXI_AR_CH_COUNTER_SET[21] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER2_AXI_AR_CH_COUNTER_SET_SHFT \ + 21 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER2_AXI_B_CH_COUNTER_SET_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER2_AXI_B_CH_COUNTER_SET_MASK \ + 0x00100000 /* MASTER2_AXI_B_CH_COUNTER_SET[20] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER2_AXI_B_CH_COUNTER_SET_SHFT \ + 20 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER2_AXI_W_CH_COUNTER_SET_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER2_AXI_W_CH_COUNTER_SET_MASK \ + 0x00080000 /* MASTER2_AXI_W_CH_COUNTER_SET[19] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER2_AXI_W_CH_COUNTER_SET_SHFT \ + 19 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER2_AXI_AW_CH_COUNTER_SET_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER2_AXI_AW_CH_COUNTER_SET_MASK \ + 0x00040000 /* MASTER2_AXI_AW_CH_COUNTER_SET[18] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER2_AXI_AW_CH_COUNTER_SET_SHFT \ + 18 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER1_AXI_R_CH_COUNTER_SET_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER1_AXI_R_CH_COUNTER_SET_MASK \ + 0x00020000 /* MASTER1_AXI_R_CH_COUNTER_SET[17] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER1_AXI_R_CH_COUNTER_SET_SHFT \ + 17 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER1_AXI_AR_CH_COUNTER_SET_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER1_AXI_AR_CH_COUNTER_SET_MASK \ + 0x00010000 /* MASTER1_AXI_AR_CH_COUNTER_SET[16] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER1_AXI_AR_CH_COUNTER_SET_SHFT \ + 16 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER1_AXI_B_CH_COUNTER_SET_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER1_AXI_B_CH_COUNTER_SET_MASK \ + 0x00008000 /* MASTER1_AXI_B_CH_COUNTER_SET[15] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER1_AXI_B_CH_COUNTER_SET_SHFT \ + 15 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER1_AXI_W_CH_COUNTER_SET_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER1_AXI_W_CH_COUNTER_SET_MASK \ + 0x00004000 /* MASTER1_AXI_W_CH_COUNTER_SET[14] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER1_AXI_W_CH_COUNTER_SET_SHFT \ + 14 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER1_AXI_AW_CH_COUNTER_SET_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER1_AXI_AW_CH_COUNTER_SET_MASK \ + 0x00002000 /* MASTER1_AXI_AW_CH_COUNTER_SET[13] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER1_AXI_AW_CH_COUNTER_SET_SHFT \ + 13 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER0_AXI_R_CH_COUNTER_SET_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER0_AXI_R_CH_COUNTER_SET_MASK \ + 0x00001000 /* MASTER0_AXI_R_CH_COUNTER_SET[12] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER0_AXI_R_CH_COUNTER_SET_SHFT \ + 12 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER0_AXI_AR_CH_COUNTER_SET_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER0_AXI_AR_CH_COUNTER_SET_MASK \ + 0x00000800 /* MASTER0_AXI_AR_CH_COUNTER_SET[11] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER0_AXI_AR_CH_COUNTER_SET_SHFT \ + 11 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER0_AXI_B_CH_COUNTER_SET_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER0_AXI_B_CH_COUNTER_SET_MASK \ + 0x00000400 /* MASTER0_AXI_B_CH_COUNTER_SET[10] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER0_AXI_B_CH_COUNTER_SET_SHFT \ + 10 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER0_AXI_W_CH_COUNTER_SET_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER0_AXI_W_CH_COUNTER_SET_MASK \ + 0x00000200 /* MASTER0_AXI_W_CH_COUNTER_SET[9] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER0_AXI_W_CH_COUNTER_SET_SHFT \ + 9 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER0_AXI_AW_CH_COUNTER_SET_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER0_AXI_AW_CH_COUNTER_SET_MASK \ + 0x00000100 /* MASTER0_AXI_AW_CH_COUNTER_SET[8] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_MASTER0_AXI_AW_CH_COUNTER_SET_SHFT \ + 8 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_AXI_MST_DBG_CH_SEL_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_AXI_MST_DBG_CH_SEL_MASK \ + 0x00000007 /* AXI_MST_DBG_CH_SEL[2..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_CFG_AXI_MST_DBG_CH_SEL_SHFT 0 + +/* +* ---WPDMA_AXI_MTR_PERF_W_STA0 (0x7C024000 + 0x910)--- +* WR_REQ_AVG_LAT[9..0] - (RO) req_avg_lat[9:0](long-term average) +* WR_REQ_PEAK_LAT[19..10] - (RO) req_peak_lat[9:0] +* WR_REQ_LAT[29..20] - (RO) req_lat[9:0](shot-term average) +* RESERVED[31..30] - (RO) tied constant +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA0_WR_REQ_LAT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA0_WR_REQ_LAT_MASK \ + 0x3FF00000 /* WR_REQ_LAT[29..20] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA0_WR_REQ_LAT_SHFT 20 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA0_WR_REQ_PEAK_LAT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA0_WR_REQ_PEAK_LAT_MASK \ + 0x000FFC00 /* WR_REQ_PEAK_LAT[19..10] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA0_WR_REQ_PEAK_LAT_SHFT 10 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA0_WR_REQ_AVG_LAT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA0_WR_REQ_AVG_LAT_MASK \ + 0x000003FF /* WR_REQ_AVG_LAT[9..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA0_WR_REQ_AVG_LAT_SHFT 0 + +/* +* ---WPDMA_AXI_MTR_PERF_W_STA1 (0x7C024000 + 0x914)--- +* WR_ACK_AVG_LAT[9..0] - (RO) ack_avg_lat[9:0](long-term average) +* WR_ACK_PEAK_LAT[19..10] - (RO) ack_peak_lat[9:0] +* WR_ACK_LAT[29..20] - (RO) ack_lat[9:0](shot-term average) +* RESERVED[31..30] - (RO) tied constant +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA1_WR_ACK_LAT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA1_WR_ACK_LAT_MASK \ + 0x3FF00000 /* WR_ACK_LAT[29..20] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA1_WR_ACK_LAT_SHFT 20 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA1_WR_ACK_PEAK_LAT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA1_WR_ACK_PEAK_LAT_MASK \ + 0x000FFC00 /* WR_ACK_PEAK_LAT[19..10] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA1_WR_ACK_PEAK_LAT_SHFT 10 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA1_WR_ACK_AVG_LAT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA1_WR_ACK_AVG_LAT_MASK \ + 0x000003FF /* WR_ACK_AVG_LAT[9..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA1_WR_ACK_AVG_LAT_SHFT 0 + +/* +* ---WPDMA_AXI_MTR_PERF_W_STA2 (0x7C024000 + 0x918)--- +* WR_BW[9..0] - (RO) bw[9:0](long-term average) +* WR_PEAK_BW[19..10] - (RO) peak_bw[9:0] +* WR_AVG_BW[29..20] - (RO) avg_bw[9:0](shot-term average) +* RESERVED[31..30] - (RO) tied constant +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA2_WR_AVG_BW_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA2_WR_AVG_BW_MASK \ + 0x3FF00000 /* WR_AVG_BW[29..20] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA2_WR_AVG_BW_SHFT 20 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA2_WR_PEAK_BW_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA2_WR_PEAK_BW_MASK \ + 0x000FFC00 /* WR_PEAK_BW[19..10] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA2_WR_PEAK_BW_SHFT 10 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA2_WR_BW_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA2_WR_BW_MASK \ + 0x000003FF /* WR_BW[9..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA2_WR_BW_SHFT 0 + +/* +* ---WPDMA_AXI_MTR_PERF_W_STA3 (0x7C024000 + 0x91C)--- +* WR_LAT[9..0] - (RO) lat[9:0](long-term average) +* WR_PEAK_LAT[19..10] - (RO) peak_lat[9:0] +* WR_AVG_LAT[29..20] - (RO) avg_lat[9:0](shot-term average) +* RESERVED[31..30] - (RO) tied constant +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA3_WR_AVG_LAT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA3_WR_AVG_LAT_MASK \ + 0x3FF00000 /* WR_AVG_LAT[29..20] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA3_WR_AVG_LAT_SHFT 20 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA3_WR_PEAK_LAT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA3_WR_PEAK_LAT_MASK \ + 0x000FFC00 /* WR_PEAK_LAT[19..10] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA3_WR_PEAK_LAT_SHFT 10 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA3_WR_LAT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA3_WR_LAT_MASK \ + 0x000003FF /* WR_LAT[9..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_W_STA3_WR_LAT_SHFT 0 + +/* +* ---WPDMA_AXI_MTR_PERF_R_STA0 (0x7C024000 + 0x920)--- +* RD_REQ_AVG_LAT[9..0] - (RO) req_avg_lat[9:0](long-term average) +* RD_REQ_PEAK_LAT[19..10] - (RO) req_peak_lat[9:0] +* RD_REQ_LAT[29..20] - (RO) req_lat[9:0](shot-term average) +* RESERVED[31..30] - (RO) tied constant +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA0_RD_REQ_LAT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA0_RD_REQ_LAT_MASK \ + 0x3FF00000 /* RD_REQ_LAT[29..20] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA0_RD_REQ_LAT_SHFT 20 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA0_RD_REQ_PEAK_LAT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA0_RD_REQ_PEAK_LAT_MASK \ + 0x000FFC00 /* RD_REQ_PEAK_LAT[19..10] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA0_RD_REQ_PEAK_LAT_SHFT 10 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA0_RD_REQ_AVG_LAT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA0_RD_REQ_AVG_LAT_MASK \ + 0x000003FF /* RD_REQ_AVG_LAT[9..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA0_RD_REQ_AVG_LAT_SHFT 0 + +/* +* ---WPDMA_AXI_MTR_PERF_R_STA1 (0x7C024000 + 0x924)--- +* RD_ACK_AVG_LAT[9..0] - (RO) ack_avg_lat[9:0](long-term average) +* RD_ACK_PEAK_LAT[19..10] - (RO) ack_peak_lat[9:0] +* RD_ACK_LAT[29..20] - (RO) ack_lat[9:0](shot-term average) +* RESERVED[31..30] - (RO) tied constant +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA1_RD_ACK_LAT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA1_RD_ACK_LAT_MASK \ + 0x3FF00000 /* RD_ACK_LAT[29..20] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA1_RD_ACK_LAT_SHFT 20 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA1_RD_ACK_PEAK_LAT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA1_RD_ACK_PEAK_LAT_MASK \ + 0x000FFC00 /* RD_ACK_PEAK_LAT[19..10] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA1_RD_ACK_PEAK_LAT_SHFT 10 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA1_RD_ACK_AVG_LAT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA1_RD_ACK_AVG_LAT_MASK \ + 0x000003FF /* RD_ACK_AVG_LAT[9..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA1_RD_ACK_AVG_LAT_SHFT 0 + +/* +* ---WPDMA_AXI_MTR_PERF_R_STA2 (0x7C024000 + 0x928)--- +* RD_BW[9..0] - (RO) bw[9:0](long-term average) +* RD_PEAK_BW[19..10] - (RO) peak_bw[9:0] +* RD_AVG_BW[29..20] - (RO) avg_bw[9:0](shot-term average) +* RESERVED[31..30] - (RO) tied constant +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA2_RD_AVG_BW_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA2_RD_AVG_BW_MASK \ + 0x3FF00000 /* RD_AVG_BW[29..20] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA2_RD_AVG_BW_SHFT 20 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA2_RD_PEAK_BW_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA2_RD_PEAK_BW_MASK \ + 0x000FFC00 /* RD_PEAK_BW[19..10] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA2_RD_PEAK_BW_SHFT 10 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA2_RD_BW_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA2_RD_BW_MASK \ + 0x000003FF /* RD_BW[9..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA2_RD_BW_SHFT 0 + +/* +* ---WPDMA_AXI_MTR_PERF_R_STA3 (0x7C024000 + 0x92C)--- +* RD_LAT[9..0] - (RO) lat[9:0](long-term average) +* RD_PEAK_LAT[19..10] - (RO) peak_lat[9:0] +* RD_AVG_LAT[29..20] - (RO) avg_lat[9:0](shot-term average) +* RESERVED[31..30] - (RO) tied constant +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA3_RD_AVG_LAT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA3_RD_AVG_LAT_MASK \ + 0x3FF00000 /* RD_AVG_LAT[29..20] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA3_RD_AVG_LAT_SHFT 20 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA3_RD_PEAK_LAT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA3_RD_PEAK_LAT_MASK \ + 0x000FFC00 /* RD_PEAK_LAT[19..10] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA3_RD_PEAK_LAT_SHFT 10 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA3_RD_LAT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA3_RD_LAT_MASK \ + 0x000003FF /* RD_LAT[9..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_PERF_R_STA3_RD_LAT_SHFT 0 + +/* +* ---WPDMA_AXI_MTR_DBG_OUT0 (0x7C024000 + 0x930)--- +* AXI_AW_CH_COUNTER[7..0] - (RO) axi_aw_ch_counter[7:0] +* AXI_W_CH_COUNTER[15..8] - (RO) axi_w_ch_counter[7:0] +* AXI_B_CH_COUNTER[23..16] - (RO) axi_b_ch_counter[7:0] +* AXI_AR_CH_COUNTER[31..24] - (RO) axi_ar_ch_counter[7:0] +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT0_AXI_AR_CH_COUNTER_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT0_AXI_AR_CH_COUNTER_MASK \ + 0xFF000000 /* AXI_AR_CH_COUNTER[31..24] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT0_AXI_AR_CH_COUNTER_SHFT 24 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT0_AXI_B_CH_COUNTER_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT0_AXI_B_CH_COUNTER_MASK \ + 0x00FF0000 /* AXI_B_CH_COUNTER[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT0_AXI_B_CH_COUNTER_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT0_AXI_W_CH_COUNTER_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT0_AXI_W_CH_COUNTER_MASK \ + 0x0000FF00 /* AXI_W_CH_COUNTER[15..8] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT0_AXI_W_CH_COUNTER_SHFT 8 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT0_AXI_AW_CH_COUNTER_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT0_AXI_AW_CH_COUNTER_MASK \ + 0x000000FF /* AXI_AW_CH_COUNTER[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT0_AXI_AW_CH_COUNTER_SHFT 0 + +/* +* ---WPDMA_AXI_MTR_DBG_OUT1 (0x7C024000 + 0x934)--- +* AXI_R_CH_COUNTER[7..0] - (RO) axi_r_ch_counter[7:0] +* AW_CURRENT_LEN[15..8] - (RO) aw_current_len[8:0] +* AR_CURRENT_LEN[23..16] - (RO) ar_current_len[8:0] +* RESERVED[31..24] - (RO) tied constant +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT1_AR_CURRENT_LEN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT1_AR_CURRENT_LEN_MASK \ + 0x00FF0000 /* AR_CURRENT_LEN[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT1_AR_CURRENT_LEN_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT1_AW_CURRENT_LEN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT1_AW_CURRENT_LEN_MASK \ + 0x0000FF00 /* AW_CURRENT_LEN[15..8] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT1_AW_CURRENT_LEN_SHFT 8 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT1_AXI_R_CH_COUNTER_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT1_AXI_R_CH_COUNTER_MASK \ + 0x000000FF /* AXI_R_CH_COUNTER[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT1_AXI_R_CH_COUNTER_SHFT 0 + +/* +* ---WPDMA_AXI_MTR_DBG_OUT2 (0x7C024000 + 0x938)--- +* AWVALID[0] - (RO) awvalid +* AWREADY[1] - (RO) awready +* WVALID[2] - (RO) wvalid +* WREADY[3] - (RO) wready +* BVALID[4] - (RO) bvalid +* BREADY[5] - (RO) bready +* ARVALID[6] - (RO) arvalid +* ARREADY[7] - (RO) arready +* RVALID[8] - (RO) rvalid +* RREADY[9] - (RO) rready +* RESERVED10[31..10] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT2_RREADY_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT2_RREADY_MASK \ + 0x00000200 /* RREADY[9] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT2_RREADY_SHFT 9 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT2_RVALID_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT2_RVALID_MASK \ + 0x00000100 /* RVALID[8] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT2_RVALID_SHFT 8 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT2_ARREADY_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT2_ARREADY_MASK \ + 0x00000080 /* ARREADY[7] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT2_ARREADY_SHFT 7 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT2_ARVALID_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT2_ARVALID_MASK \ + 0x00000040 /* ARVALID[6] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT2_ARVALID_SHFT 6 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT2_BREADY_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT2_BREADY_MASK \ + 0x00000020 /* BREADY[5] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT2_BREADY_SHFT 5 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT2_BVALID_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT2_BVALID_MASK \ + 0x00000010 /* BVALID[4] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT2_BVALID_SHFT 4 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT2_WREADY_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT2_WREADY_MASK \ + 0x00000008 /* WREADY[3] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT2_WREADY_SHFT 3 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT2_WVALID_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT2_WVALID_MASK \ + 0x00000004 /* WVALID[2] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT2_WVALID_SHFT 2 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT2_AWREADY_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT2_AWREADY_MASK \ + 0x00000002 /* AWREADY[1] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT2_AWREADY_SHFT 1 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT2_AWVALID_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT2_AWVALID_MASK \ + 0x00000001 /* AWVALID[0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT2_AWVALID_SHFT 0 + +/* +* ---WPDMA_AXI_MTR_DBG_OUT3 (0x7C024000 + 0x93C)--- +* AR_CURRENT_ADDRESS[31..0] - (RO) ar_current_address[31:0] +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT3_AR_CURRENT_ADDRESS_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT3_AR_CURRENT_ADDRESS_MASK \ + 0xFFFFFFFF /* AR_CURRENT_ADDRESS[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT3_AR_CURRENT_ADDRESS_SHFT 0 + +/* +* ---WPDMA_AXI_MTR_DBG_OUT4 (0x7C024000 + 0x940)--- +* AW_CURRENT_ADDRESS[31..0] - (RO) aw_current_address[31:0] +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT4_AW_CURRENT_ADDRESS_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT4_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT4_AW_CURRENT_ADDRESS_MASK \ + 0xFFFFFFFF /* AW_CURRENT_ADDRESS[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT4_AW_CURRENT_ADDRESS_SHFT 0 + +/* +* ---WPDMA_AXI_MTR_DBG_OUT5 (0x7C024000 + 0x944)--- +* AR_CURRENT_ADDRESS_EXT[3..0] - (RO) ar_current_address[35:32] +* RESERVED4[15..4] - (RO) Reserved bits +* AW_CURRENT_ADDRESS_EXT[19..16] - (RO) aw_current_address[35:32] +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT5_AW_CURRENT_ADDRESS_EXT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT5_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT5_AW_CURRENT_ADDRESS_EXT_MASK \ + 0x000F0000 /* AW_CURRENT_ADDRESS_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT5_AW_CURRENT_ADDRESS_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT5_AR_CURRENT_ADDRESS_EXT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT5_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT5_AR_CURRENT_ADDRESS_EXT_MASK \ + 0x0000000F /* AR_CURRENT_ADDRESS_EXT[3..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MTR_DBG_OUT5_AR_CURRENT_ADDRESS_EXT_SHFT 0 + +/* +* ---WPDMA_AXI_MST_SLEEP_STA0 (0x7C024000 + 0x980)--- +* tx_pfet_cmd_state_idle[0] - (RO) cmd_state_idle +* tx_pfet_ar_cs_idle[1] - (RO) ar_cs_idle +* tx_pfet_axi_dp_cs_idle[2] - (RO) axi_dp_cs_idle +* tx_pfet_ar_cs_sleep[3] - (RO) ar_cs_sleep +* tx_pfet_buf_empty_axi_outstanding[4] - (RO) buf_empty(axi_outstanding) +* tx_pfet_data_fifo_empty[5] - (RO) data_fifo_empty +* RESERVED6[7..6] - (RO) Reserved bits +* tx_pfet_dma_req_fifo_empty[8] - (RO) dma_req_fifo_empty +* tx_pfet_axi_req_fifo_empty[9] - (RO) axi_req_fifo_empty +* tx_pfet_axi_pkt_fifo_empty[10] - (RO) axi_pkt_fifo_empty +* RESERVED11[11] - (RO) Reserved bits +* tx_pfet_axi_outstanding_req[15..12] - (RO) current pipelined +* axi_outstanding_req number +* pf_dfet_rx_cmd_state_idle[16] - (RO) cmd_state_idle +* pf_dfet_rx_ar_cs_idle[17] - (RO) ar_cs_idle +* pf_dfet_rx_axi_dp_cs_idle[18] - (RO) axi_dp_cs_idle +* pf_dfet_rx_ar_cs_sleep[19] - (RO) ar_cs_sleep +* pf_dfet_rx_buf_empty_axi_outstanding[20] - (RO) buf_empty(axi_outstanding) +* RESERVED21[23..21] - (RO) Reserved bits +* pf_dfet_rx_dma_req_fifo_empty[24] - (RO) dma_req_fifo_empty +* pf_dfet_rx_axi_req_fifo_empty[25] - (RO) axi_req_fifo_empty +* pf_dfet_rx_axi_pkt_fifo_empty[26] - (RO) axi_pkt_fifo_empty +* RESERVED27[27] - (RO) Reserved bits +* pf_dfet_rx_axi_outstanding_req[31..28] - (RO) current pipelined +* axi_outstanding_req number +*/ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_axi_outstanding_req_ADDR\ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_axi_outstanding_req_MASK\ +0xF0000000 /* pf_dfet_rx_axi_outstanding_req[31..28] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_axi_outstanding_req_SHFT\ +28 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_axi_pkt_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_axi_pkt_fifo_empty_MASK \ + 0x04000000 /* pf_dfet_rx_axi_pkt_fifo_empty[26] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_axi_pkt_fifo_empty_SHFT \ + 26 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_axi_req_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_axi_req_fifo_empty_MASK \ + 0x02000000 /* pf_dfet_rx_axi_req_fifo_empty[25] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_axi_req_fifo_empty_SHFT \ + 25 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_dma_req_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_dma_req_fifo_empty_MASK \ + 0x01000000 /* pf_dfet_rx_dma_req_fifo_empty[24] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_dma_req_fifo_empty_SHFT \ + 24 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_buf_empty_axi_outstandin\ +g_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_buf_empty_axi_outstandin\ +g_MASK \ +0x00100000 /* pf_dfet_rx_buf_empty_axi_outstanding[20] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_buf_empty_axi_outstandin\ +g_SHFT \ +20 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_ar_cs_sleep_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_ar_cs_sleep_MASK \ + 0x00080000 /* pf_dfet_rx_ar_cs_sleep[19] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_ar_cs_sleep_SHFT \ + 19 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_axi_dp_cs_idle_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_axi_dp_cs_idle_MASK \ + 0x00040000 /* pf_dfet_rx_axi_dp_cs_idle[18] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_axi_dp_cs_idle_SHFT \ + 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_ar_cs_idle_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_ar_cs_idle_MASK \ + 0x00020000 /* pf_dfet_rx_ar_cs_idle[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_ar_cs_idle_SHFT \ + 17 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_cmd_state_idle_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_cmd_state_idle_MASK \ + 0x00010000 /* pf_dfet_rx_cmd_state_idle[16] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_cmd_state_idle_SHFT \ + 16 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_axi_outstanding_req_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_axi_outstanding_req_MASK \ + 0x0000F000 /* tx_pfet_axi_outstanding_req[15..12] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_axi_outstanding_req_SHFT \ + 12 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_axi_pkt_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_axi_pkt_fifo_empty_MASK \ + 0x00000400 /* tx_pfet_axi_pkt_fifo_empty[10] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_axi_pkt_fifo_empty_SHFT \ + 10 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_axi_req_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_axi_req_fifo_empty_MASK \ + 0x00000200 /* tx_pfet_axi_req_fifo_empty[9] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_axi_req_fifo_empty_SHFT \ + 9 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_dma_req_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_dma_req_fifo_empty_MASK \ + 0x00000100 /* tx_pfet_dma_req_fifo_empty[8] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_dma_req_fifo_empty_SHFT \ + 8 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_data_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_data_fifo_empty_MASK \ + 0x00000020 /* tx_pfet_data_fifo_empty[5] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_data_fifo_empty_SHFT \ + 5 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_buf_empty_axi_outstanding_A\ +DDR \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_buf_empty_axi_outstanding_M\ +ASK \ +0x00000010 /* tx_pfet_buf_empty_axi_outstanding[4] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_buf_empty_axi_outstanding_S\ +HFT \ +4 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_ar_cs_sleep_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_ar_cs_sleep_MASK \ + 0x00000008 /* tx_pfet_ar_cs_sleep[3] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_ar_cs_sleep_SHFT 3 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_axi_dp_cs_idle_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_axi_dp_cs_idle_MASK \ + 0x00000004 /* tx_pfet_axi_dp_cs_idle[2] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_axi_dp_cs_idle_SHFT \ + 2 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_ar_cs_idle_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_ar_cs_idle_MASK \ + 0x00000002 /* tx_pfet_ar_cs_idle[1] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_ar_cs_idle_SHFT 1 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_cmd_state_idle_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_cmd_state_idle_MASK \ + 0x00000001 /* tx_pfet_cmd_state_idle[0] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_cmd_state_idle_SHFT \ + 0 + +/* +* ---WPDMA_AXI_MST_SLEEP_STA1 (0x7C024000 + 0x984)--- +* pf_dfet_tx_cmd_state_idle[0] - (RO) cmd_state_idle +* pf_dfet_tx_ar_cs_idle[1] - (RO) ar_cs_idle +* pf_dfet_tx_axi_dp_cs_idle[2] - (RO) axi_dp_cs_idle +* pf_dfet_tx_ar_cs_sleep[3] - (RO) ar_cs_sleep +* pf_dfet_tx_buf_empty_axi_outstanding[4] - (RO) buf_empty(axi_outstanding) +* RESERVED5[7..5] - (RO) Reserved bits +* pf_dfet_tx_dma_req_fifo_empty[8] - (RO) dma_req_fifo_empty +* pf_dfet_tx_axi_req_fifo_empty[9] - (RO) axi_req_fifo_empty +* pf_dfet_tx_axi_pkt_fifo_empty[10] - (RO) axi_pkt_fifo_empty +* RESERVED11[11] - (RO) Reserved bits +* pf_dfet_tx_axi_outstanding_req[15..12] - (RO) current pipelined +* axi_outstanding_req number +* tx_pfet_cmd_state_idle[16] - (RO) cmd_state_idle +* tx_pfet_ar_cs_idle[17] - (RO) ar_cs_idle +* tx_pfet_axi_dp_cs_idle[18] - (RO) axi_dp_cs_idle +* tx_pfet_ar_cs_sleep[19] - (RO) ar_cs_sleep +* tx_pfet_buf_empty_axi_outstanding[20] - (RO) buf_empty(axi_outstanding) +* tx_pfet_data_fifo_empty[21] - (RO) data_fifo_empty +* RESERVED22[23..22] - (RO) Reserved bits +* tx_pfet_dma_req_fifo_empty[24] - (RO) dma_req_fifo_empty +* tx_pfet_axi_req_fifo_empty[25] - (RO) axi_req_fifo_empty +* tx_pfet_axi_pkt_fifo_empty[26] - (RO) axi_pkt_fifo_empty +* RESERVED27[27] - (RO) Reserved bits +* tx_pfet_axi_outstanding_req[31..28] - (RO) current pipelined +* axi_outstanding_req number +*/ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_tx_pfet_axi_outstanding_req_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_tx_pfet_axi_outstanding_req_MASK \ + 0xF0000000 /* tx_pfet_axi_outstanding_req[31..28] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_tx_pfet_axi_outstanding_req_SHFT \ + 28 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_tx_pfet_axi_pkt_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_tx_pfet_axi_pkt_fifo_empty_MASK \ + 0x04000000 /* tx_pfet_axi_pkt_fifo_empty[26] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_tx_pfet_axi_pkt_fifo_empty_SHFT \ + 26 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_tx_pfet_axi_req_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_tx_pfet_axi_req_fifo_empty_MASK \ + 0x02000000 /* tx_pfet_axi_req_fifo_empty[25] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_tx_pfet_axi_req_fifo_empty_SHFT \ + 25 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_tx_pfet_dma_req_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_tx_pfet_dma_req_fifo_empty_MASK \ + 0x01000000 /* tx_pfet_dma_req_fifo_empty[24] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_tx_pfet_dma_req_fifo_empty_SHFT \ + 24 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_tx_pfet_data_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_tx_pfet_data_fifo_empty_MASK \ + 0x00200000 /* tx_pfet_data_fifo_empty[21] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_tx_pfet_data_fifo_empty_SHFT \ + 21 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_tx_pfet_buf_empty_axi_outstanding_A\ +DDR \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_tx_pfet_buf_empty_axi_outstanding_M\ +ASK \ +0x00100000 /* tx_pfet_buf_empty_axi_outstanding[20] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_tx_pfet_buf_empty_axi_outstanding_S\ +HFT \ +20 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_tx_pfet_ar_cs_sleep_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_tx_pfet_ar_cs_sleep_MASK \ + 0x00080000 /* tx_pfet_ar_cs_sleep[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_tx_pfet_ar_cs_sleep_SHFT 19 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_tx_pfet_axi_dp_cs_idle_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_tx_pfet_axi_dp_cs_idle_MASK \ + 0x00040000 /* tx_pfet_axi_dp_cs_idle[18] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_tx_pfet_axi_dp_cs_idle_SHFT \ + 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_tx_pfet_ar_cs_idle_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_tx_pfet_ar_cs_idle_MASK \ + 0x00020000 /* tx_pfet_ar_cs_idle[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_tx_pfet_ar_cs_idle_SHFT 17 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_tx_pfet_cmd_state_idle_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_tx_pfet_cmd_state_idle_MASK \ + 0x00010000 /* tx_pfet_cmd_state_idle[16] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_tx_pfet_cmd_state_idle_SHFT \ + 16 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_axi_outstanding_req_ADDR\ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_axi_outstanding_req_MASK\ +0x0000F000 /* pf_dfet_tx_axi_outstanding_req[15..12] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_axi_outstanding_req_SHFT\ +12 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_axi_pkt_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_axi_pkt_fifo_empty_MASK \ + 0x00000400 /* pf_dfet_tx_axi_pkt_fifo_empty[10] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_axi_pkt_fifo_empty_SHFT \ + 10 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_axi_req_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_axi_req_fifo_empty_MASK \ + 0x00000200 /* pf_dfet_tx_axi_req_fifo_empty[9] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_axi_req_fifo_empty_SHFT \ + 9 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_dma_req_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_dma_req_fifo_empty_MASK \ + 0x00000100 /* pf_dfet_tx_dma_req_fifo_empty[8] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_dma_req_fifo_empty_SHFT \ + 8 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_buf_empty_axi_outstandin\ +g_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_buf_empty_axi_outstandin\ +g_MASK \ +0x00000010 /* pf_dfet_tx_buf_empty_axi_outstanding[4] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_buf_empty_axi_outstandin\ +g_SHFT \ +4 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_ar_cs_sleep_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_ar_cs_sleep_MASK \ + 0x00000008 /* pf_dfet_tx_ar_cs_sleep[3] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_ar_cs_sleep_SHFT \ + 3 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_axi_dp_cs_idle_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_axi_dp_cs_idle_MASK \ + 0x00000004 /* pf_dfet_tx_axi_dp_cs_idle[2] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_axi_dp_cs_idle_SHFT \ + 2 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_ar_cs_idle_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_ar_cs_idle_MASK \ + 0x00000002 /* pf_dfet_tx_ar_cs_idle[1] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_ar_cs_idle_SHFT 1 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_cmd_state_idle_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_cmd_state_idle_MASK \ + 0x00000001 /* pf_dfet_tx_cmd_state_idle[0] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_cmd_state_idle_SHFT \ + 0 + +/* +* ---WPDMA_AXI_MST_SLEEP_STA2 (0x7C024000 + 0x988)--- +* rx_pfet_cmd_state_idle[0] - (RO) cmd_state_idle +* rx_pfet_aw_cs_idle[1] - (RO) aw_cs_idle +* rx_pfet_axi_dp_cs_idle[2] - (RO) axi_dp_cs_idle +* rx_pfet_aw_cs_sleep[3] - (RO) aw_cs_sleep +* rx_pfet_buf_empty_axi_outstanding[4] - (RO) buf_empty(axi_outstanding) +* rx_pfet_data_fifo_empty[5] - (RO) data_fifo_empty +* rx_pfet_rx_axi_bid_fifo_empty[6] - (RO) axi_bid_fifo_empty +* RESERVED7[7] - (RO) Reserved bits +* rx_pfet_dma_req_fifo_empty[8] - (RO) dma_req_fifo_empty +* rx_pfet_axi_req_fifo_empty[9] - (RO) axi_req_fifo_empty +* rx_pfet_axi_pkt_fifo_empty[10] - (RO) axi_pkt_fifo_empty +* RESERVED11[11] - (RO) Reserved bits +* rx_pfet_axi_outstanding_req[15..12] - (RO) current pipelined +* axi_outstanding_req number +* wb_dfet_rx_cmd_state_idle[16] - (RO) cmd_state_idle +* wb_dfet_rx_aw_cs_idle[17] - (RO) aw_cs_idle +* wb_dfet_rx_axi_dp_cs_idle[18] - (RO) axi_dp_cs_idle +* wb_dfet_rx_aw_cs_sleep[19] - (RO) aw_cs_sleep +* wb_dfet_rx_buf_empty_axi_outstanding[20] - (RO) buf_empty(axi_outstanding) +* wb_dfet_rx_axi_data_fifo_empty[21] - (RO) axi_data_fifo_empty +* wb_dfet_rx_axi_bid_fifo_empty[22] - (RO) axi_bid_fifo_empty +* RESERVED23[23] - (RO) Reserved bits +* wb_dfet_rx_dma_req_fifo_empty[24] - (RO) dma_req_fifo_empty +* wb_dfet_rx_axi_req_fifo_empty[25] - (RO) axi_req_fifo_empty +* wb_dfet_rx_axi_pkt_fifo_empty[26] - (RO) axi_pkt_fifo_empty +* RESERVED27[27] - (RO) Reserved bits +* wb_dfet_rx_axi_outstanding_req[31..28] - (RO) current pipelined +* axi_outstanding_req number +*/ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_axi_outstanding_req_ADDR\ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_axi_outstanding_req_MASK\ +0xF0000000 /* wb_dfet_rx_axi_outstanding_req[31..28] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_axi_outstanding_req_SHFT\ +28 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_axi_pkt_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_axi_pkt_fifo_empty_MASK \ + 0x04000000 /* wb_dfet_rx_axi_pkt_fifo_empty[26] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_axi_pkt_fifo_empty_SHFT \ + 26 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_axi_req_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_axi_req_fifo_empty_MASK \ + 0x02000000 /* wb_dfet_rx_axi_req_fifo_empty[25] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_axi_req_fifo_empty_SHFT \ + 25 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_dma_req_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_dma_req_fifo_empty_MASK \ + 0x01000000 /* wb_dfet_rx_dma_req_fifo_empty[24] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_dma_req_fifo_empty_SHFT \ + 24 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_axi_bid_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_axi_bid_fifo_empty_MASK \ + 0x00400000 /* wb_dfet_rx_axi_bid_fifo_empty[22] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_axi_bid_fifo_empty_SHFT \ + 22 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_axi_data_fifo_empty_ADDR\ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_axi_data_fifo_empty_MASK\ +0x00200000 /* wb_dfet_rx_axi_data_fifo_empty[21] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_axi_data_fifo_empty_SHFT\ +21 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_buf_empty_axi_outstandin\ +g_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_buf_empty_axi_outstandin\ +g_MASK \ +0x00100000 /* wb_dfet_rx_buf_empty_axi_outstanding[20] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_buf_empty_axi_outstandin\ +g_SHFT \ +20 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_aw_cs_sleep_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_aw_cs_sleep_MASK \ + 0x00080000 /* wb_dfet_rx_aw_cs_sleep[19] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_aw_cs_sleep_SHFT \ + 19 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_axi_dp_cs_idle_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_axi_dp_cs_idle_MASK \ + 0x00040000 /* wb_dfet_rx_axi_dp_cs_idle[18] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_axi_dp_cs_idle_SHFT \ + 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_aw_cs_idle_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_aw_cs_idle_MASK \ + 0x00020000 /* wb_dfet_rx_aw_cs_idle[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_aw_cs_idle_SHFT \ + 17 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_cmd_state_idle_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_cmd_state_idle_MASK \ + 0x00010000 /* wb_dfet_rx_cmd_state_idle[16] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_cmd_state_idle_SHFT \ + 16 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_axi_outstanding_req_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_axi_outstanding_req_MASK \ + 0x0000F000 /* rx_pfet_axi_outstanding_req[15..12] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_axi_outstanding_req_SHFT \ + 12 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_axi_pkt_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_axi_pkt_fifo_empty_MASK \ + 0x00000400 /* rx_pfet_axi_pkt_fifo_empty[10] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_axi_pkt_fifo_empty_SHFT \ + 10 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_axi_req_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_axi_req_fifo_empty_MASK \ + 0x00000200 /* rx_pfet_axi_req_fifo_empty[9] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_axi_req_fifo_empty_SHFT \ + 9 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_dma_req_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_dma_req_fifo_empty_MASK \ + 0x00000100 /* rx_pfet_dma_req_fifo_empty[8] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_dma_req_fifo_empty_SHFT \ + 8 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_rx_axi_bid_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_rx_axi_bid_fifo_empty_MASK \ + 0x00000040 /* rx_pfet_rx_axi_bid_fifo_empty[6] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_rx_axi_bid_fifo_empty_SHFT \ + 6 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_data_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_data_fifo_empty_MASK \ + 0x00000020 /* rx_pfet_data_fifo_empty[5] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_data_fifo_empty_SHFT \ + 5 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_buf_empty_axi_outstanding_A\ +DDR \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_buf_empty_axi_outstanding_M\ +ASK \ +0x00000010 /* rx_pfet_buf_empty_axi_outstanding[4] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_buf_empty_axi_outstanding_S\ +HFT \ +4 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_aw_cs_sleep_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_aw_cs_sleep_MASK \ + 0x00000008 /* rx_pfet_aw_cs_sleep[3] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_aw_cs_sleep_SHFT 3 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_axi_dp_cs_idle_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_axi_dp_cs_idle_MASK \ + 0x00000004 /* rx_pfet_axi_dp_cs_idle[2] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_axi_dp_cs_idle_SHFT \ + 2 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_aw_cs_idle_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_aw_cs_idle_MASK \ + 0x00000002 /* rx_pfet_aw_cs_idle[1] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_aw_cs_idle_SHFT 1 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_cmd_state_idle_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_cmd_state_idle_MASK \ + 0x00000001 /* rx_pfet_cmd_state_idle[0] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_cmd_state_idle_SHFT \ + 0 + +/* +* ---WPDMA_AXI_MST_SLEEP_STA3 (0x7C024000 + 0x98C)--- +* wb_dfet_tx_cmd_state_idle[0] - (RO) cmd_state_idle +* wb_dfet_tx_aw_cs_idle[1] - (RO) aw_cs_idle +* wb_dfet_tx_axi_dp_cs_idle[2] - (RO) axi_dp_cs_idle +* wb_dfet_tx_aw_cs_sleep[3] - (RO) aw_cs_sleep +* wb_dfet_tx_buf_empty_axi_outstanding[4] - (RO) buf_empty(axi_outstanding) +* wb_dfet_tx_axi_data_fifo_empty[5] - (RO) axi_data_fifo_empty +* wb_dfet_rx_axi_bid_fifo_empty[6] - (RO) axi_bid_fifo_empty +* RESERVED7[7] - (RO) Reserved bits +* wb_dfet_tx_dma_req_fifo_empty[8] - (RO) dma_req_fifo_empty +* wb_dfet_tx_axi_req_fifo_empty[9] - (RO) axi_req_fifo_empty +* wb_dfet_tx_axi_pkt_fifo_empty[10] - (RO) axi_pkt_fifo_empty +* RESERVED11[11] - (RO) Reserved bits +* wb_dfet_tx_axi_outstanding_req[15..12] - (RO) current pipelined +* axi_outstanding_req number +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_axi_outstanding_req_ADDR\ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_axi_outstanding_req_MASK\ +0x0000F000 /* wb_dfet_tx_axi_outstanding_req[15..12] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_axi_outstanding_req_SHFT\ +12 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_axi_pkt_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_axi_pkt_fifo_empty_MASK \ + 0x00000400 /* wb_dfet_tx_axi_pkt_fifo_empty[10] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_axi_pkt_fifo_empty_SHFT \ + 10 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_axi_req_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_axi_req_fifo_empty_MASK \ + 0x00000200 /* wb_dfet_tx_axi_req_fifo_empty[9] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_axi_req_fifo_empty_SHFT \ + 9 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_dma_req_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_dma_req_fifo_empty_MASK \ + 0x00000100 /* wb_dfet_tx_dma_req_fifo_empty[8] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_dma_req_fifo_empty_SHFT \ + 8 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_rx_axi_bid_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_rx_axi_bid_fifo_empty_MASK \ + 0x00000040 /* wb_dfet_rx_axi_bid_fifo_empty[6] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_rx_axi_bid_fifo_empty_SHFT \ + 6 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_axi_data_fifo_empty_ADDR\ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_axi_data_fifo_empty_MASK\ +0x00000020 /* wb_dfet_tx_axi_data_fifo_empty[5] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_axi_data_fifo_empty_SHFT\ +5 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_buf_empty_axi_outstandin\ +g_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_buf_empty_axi_outstandin\ +g_MASK \ +0x00000010 /* wb_dfet_tx_buf_empty_axi_outstanding[4] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_buf_empty_axi_outstandin\ +g_SHFT \ +4 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_aw_cs_sleep_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_aw_cs_sleep_MASK \ + 0x00000008 /* wb_dfet_tx_aw_cs_sleep[3] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_aw_cs_sleep_SHFT \ + 3 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_axi_dp_cs_idle_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_axi_dp_cs_idle_MASK \ + 0x00000004 /* wb_dfet_tx_axi_dp_cs_idle[2] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_axi_dp_cs_idle_SHFT \ + 2 +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_aw_cs_idle_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_aw_cs_idle_MASK \ + 0x00000002 /* wb_dfet_tx_aw_cs_idle[1] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_aw_cs_idle_SHFT 1 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_cmd_state_idle_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_cmd_state_idle_MASK \ + 0x00000001 /* wb_dfet_tx_cmd_state_idle[0] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_cmd_state_idle_SHFT \ + 0 + +/* +* ---WPDMA_AXI_MST_SLEEP_STA4 (0x7C024000 + 0x990)--- +* RESERVED0[0] - (RO) Reserved bits +* rx_pfet_pld_rx_pfet_sleep_rdy[1] - (RO) pld_rx_pfet_sleep_rdy +* RESERVED2[30..2] - (RO) Reserved bits +* tx_pfet_pld_tx_pfet_sleep_rdy[31] - (RO) pld_tx_pfet_sleep_rdy +*/ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA4_tx_pfet_pld_tx_pfet_sleep_rdy_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA4_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA4_tx_pfet_pld_tx_pfet_sleep_rdy_MASK \ + 0x80000000 /* tx_pfet_pld_tx_pfet_sleep_rdy[31] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA4_tx_pfet_pld_tx_pfet_sleep_rdy_SHFT \ + 31 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA4_rx_pfet_pld_rx_pfet_sleep_rdy_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA4_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA4_rx_pfet_pld_rx_pfet_sleep_rdy_MASK \ + 0x00000002 /* rx_pfet_pld_rx_pfet_sleep_rdy[1] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_AXI_MST_SLEEP_STA4_rx_pfet_pld_rx_pfet_sleep_rdy_SHFT \ + 1 + +/* +* ---WPDMA_TX_RING0_BKRS_CTRL0 (0x7C024000 + 0xA00)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING0_BKRS_CTRL1 (0x7C024000 + 0xA04)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING0_BKRS_CTRL2 (0x7C024000 + 0xA08)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING1_BKRS_CTRL0 (0x7C024000 + 0xA10)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING1_BKRS_CTRL1 (0x7C024000 + 0xA14)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING1_BKRS_CTRL2 (0x7C024000 + 0xA18)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING2_BKRS_CTRL0 (0x7C024000 + 0xA20)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING2_BKRS_CTRL1 (0x7C024000 + 0xA24)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING2_BKRS_CTRL2 (0x7C024000 + 0xA28)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING3_BKRS_CTRL0 (0x7C024000 + 0xA30)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING3_BKRS_CTRL1 (0x7C024000 + 0xA34)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING3_BKRS_CTRL2 (0x7C024000 + 0xA38)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING0_BKRS_CTRL0 (0x7C024000 + 0xC00)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING0_BKRS_CTRL1 (0x7C024000 + 0xC04)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING0_BKRS_CTRL2 (0x7C024000 + 0xC08)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING1_BKRS_CTRL0 (0x7C024000 + 0xC10)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING1_BKRS_CTRL1 (0x7C024000 + 0xC14)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING1_BKRS_CTRL2 (0x7C024000 + 0xC18)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING2_BKRS_CTRL0 (0x7C024000 + 0xC20)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING2_BKRS_CTRL1 (0x7C024000 + 0xC24)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING2_BKRS_CTRL2 (0x7C024000 + 0xC28)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING3_BKRS_CTRL0 (0x7C024000 + 0xC30)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING3_BKRS_CTRL1 (0x7C024000 + 0xC34)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING3_BKRS_CTRL2 (0x7C024000 + 0xC38)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +#ifdef __cplusplus +} +#endif + +#endif /* __WF_WFDMA_HOST_DMA0_REGS_H__ */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/mt7915/wf_wfdma_host_dma1.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/mt7915/wf_wfdma_host_dma1.h new file mode 100644 index 0000000000000000000000000000000000000000..cfe344697eabedcad1b1e55d68cbb251b1cb18ef --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/mt7915/wf_wfdma_host_dma1.h @@ -0,0 +1,9727 @@ +/* [File] : wf_wfdma_host_dma1.h */ +/* [Revision time] : Tue Jun 5 14:32:37 2018 */ +/* [Description] : This file is auto generated by CODA */ +/* [Copyright] : Copyright (C) 2018 Mediatek Incorportion. All rights reserved. +*/ + +#ifndef __WF_WFDMA_HOST_DMA1_REGS_H__ +#define __WF_WFDMA_HOST_DMA1_REGS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* ************************************************************************** */ +/* */ +/* WF_WFDMA_HOST_DMA1 CR Definitions */ +/* */ +/* ************************************************************************** */ + +#define WF_WFDMA_HOST_DMA1_BASE 0x7C025000 + + +#define WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0XA0) /* 50A0 */ +#define WF_WFDMA_HOST_DMA1_HOST_IF_RX_DONE_STS_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0XA4) /* 50A4 */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_RST_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x100) /* 5100 */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_TOP_MISC_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x104) /* 5104 */ +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0X108) /* 5108 */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x10C) /* 510C */ +#define WF_WFDMA_HOST_DMA1_MCU_INT_STA_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0X110) /* 5110 */ +#define WF_WFDMA_HOST_DMA1_MCU_INT_ENA_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0X114) /* 5114 */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_EXT_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x118) /* 5118 */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_EXT_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0X11C) /* 511C */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DUMMY_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x120) /* 5120 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_DBG_IDX_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x124) /* 5124 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_DBG_PROBE_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x128) /* 5128 */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_IDX_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x12C) /* 512C */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_PROBE_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x130) /* 5130 */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DMASHDL_DBG_PROBE_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x134) /* 5134 */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_STATUS_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x138) /* 5138 */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_ENA_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x13c) /* 513C */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_FIFO_TEST_MOD_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x140) /* 5140 */ +#define WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x1E8) /* 51E8 */ +#define WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x1EC) /* 51EC */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x1F0) /* 51F0 */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x1F4) /* 51F4 */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x1F8) /* 51F8 */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x1FC) /* 51FC */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x200) /* 5200 */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0X204) /* 5204 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x208) /* 5208 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x20C) /* 520C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_TX_Q_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x224) /* 5224 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x230) /* 5230 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_MISC_CFG_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x234) /* 5234 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_WRR_ARB_GBF0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x240) /* 5240 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH10_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x260) /* 5260 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH32_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x264) /* 5264 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH54_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x268) /* 5268 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH76_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x26C) /* 526C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DRX_PTR_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x280) /* 5280 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x284) /* 5284 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_EXT_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x288) /* 5288 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_INT_RX_PRI_SEL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x298) /* 5298 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x29C) /* 529C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_DBG0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x2A0) /* 52A0 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_DBG1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x2A4) /* 52A4 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_DBG0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x2A8) /* 52A8 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_DBG1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x2AC) /* 52AC */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x2B0) /* 52B0 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x2B4) /* 52B4 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x2B8) /* 52B8 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x2BC) /* 52BC */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x2C0) /* 52C0 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x2C4) /* 52C4 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x2C8) /* 52C8 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x2CC) /* 52CC */ +#define WF_WFDMA_HOST_DMA1_HOST_PRI_INT_STA_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x2E0) /* 52E0 */ +#define WF_WFDMA_HOST_DMA1_HOST_PER_INT_ENA_STA_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x2E4) /* 52E4 */ +#define WF_WFDMA_HOST_DMA1_HOST_PER_DLY_INT_CFG_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x2E8) /* 52E8 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x2F0) /* 52F0 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x300) /* 5300 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x304) /* 5304 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x308) /* 5308 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x30c) /* 530C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x310) /* 5310 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x314) /* 5314 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x318) /* 5318 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x31c) /* 531C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x320) /* 5320 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x324) /* 5324 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x328) /* 5328 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x32c) /* 532C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x330) /* 5330 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x334) /* 5334 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x338) /* 5338 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x33c) /* 533C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x340) /* 5340 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x344) /* 5344 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x348) /* 5348 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x34c) /* 534C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x350) /* 5350 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x354) /* 5354 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x358) /* 5358 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x35c) /* 535C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x360) /* 5360 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x364) /* 5364 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x368) /* 5368 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x36c) /* 536C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x370) /* 5370 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x374) /* 5374 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x378) /* 5378 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x37c) /* 537C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x380) /* 5380 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x384) /* 5384 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x388) /* 5388 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x38c) /* 538C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x390) /* 5390 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x394) /* 5394 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x398) /* 5398 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x39c) /* 539C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3a0) /* 53A0 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3a4) /* 53A4 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3a8) /* 53A8 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3ac) /* 53AC */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3b0) /* 53B0 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3b4) /* 53B4 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3b8) /* 53B8 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3bc) /* 53BC */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3c0) /* 53C0 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3c4) /* 53C4 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3c8) /* 53C8 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3cc) /* 53CC */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3d0) /* 53D0 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3d4) /* 53D4 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3d8) /* 53D8 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3dc) /* 53DC */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3e0) /* 53E0 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3e4) /* 53E4 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3e8) /* 53E8 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3ec) /* 53EC */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3f0) /* 53F0 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3f4) /* 53F4 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3f8) /* 53F8 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3fc) /* 53FC */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x400) /* 5400 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x404) /* 5404 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x408) /* 5408 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x40c) /* 540C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x410) /* 5410 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x414) /* 5414 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x418) /* 5418 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x41c) /* 541C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x420) /* 5420 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x424) /* 5424 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x428) /* 5428 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x42c) /* 542C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x430) /* 5430 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x434) /* 5434 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x438) /* 5438 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x43c) /* 543C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x440) /* 5440 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x444) /* 5444 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x448) /* 5448 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x44c) /* 544C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x450) /* 5450 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x454) /* 5454 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x458) /* 5458 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x45c) /* 545C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x460) /* 5460 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x464) /* 5464 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x468) /* 5468 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x46c) /* 546C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x470) /* 5470 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x474) /* 5474 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x478) /* 5478 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x47c) /* 547C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x500) /* 5500 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x504) /* 5504 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x508) /* 5508 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x50c) /* 550C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x510) /* 5510 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x514) /* 5514 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x518) /* 5518 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x51c) /* 551C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x520) /* 5520 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x524) /* 5524 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x528) /* 5528 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x52C) /* 552C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x530) /* 5530 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x534) /* 5534 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x538) /* 5538 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x53C) /* 553C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x600) /* 5600 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x604) /* 5604 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x608) /* 5608 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x60C) /* 560C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x610) /* 5610 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x614) /* 5614 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x618) /* 5618 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x61C) /* 561C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x620) /* 5620 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x624) /* 5624 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x628) /* 5628 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x62C) /* 562C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x630) /* 5630 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x634) /* 5634 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x638) /* 5638 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x63C) /* 563C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x640) /* 5640 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x644) /* 5644 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x648) /* 5648 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x64C) /* 564C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x650) /* 5650 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x654) /* 5654 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x658) /* 5658 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x65C) /* 565C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x680) /* 5680 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x684) /* 5684 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x688) /* 5688 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x68C) /* 568C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_CFG_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x900) /* 5900 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x904) /* 5904 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x910) /* 5910 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x914) /* 5914 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x918) /* 5918 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x91C) /* 591C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x920) /* 5920 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x924) /* 5924 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x928) /* 5928 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x92C) /* 592C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x930) /* 5930 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x934) /* 5934 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x938) /* 5938 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x93C) /* 593C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT4_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x940) /* 5940 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT5_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x944) /* 5944 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x980) /* 5980 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x984) /* 5984 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x988) /* 5988 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x98C) /* 598C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA4_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x990) /* 5990 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA00) /* 5A00 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA04) /* 5A04 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA08) /* 5A08 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA10) /* 5A10 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA14) /* 5A14 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA18) /* 5A18 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA20) /* 5A20 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA24) /* 5A24 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA28) /* 5A28 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA30) /* 5A30 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA34) /* 5A34 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA38) /* 5A38 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA40) /* 5A40 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA44) /* 5A44 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA48) /* 5A48 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA50) /* 5A50 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA54) /* 5A54 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA58) /* 5A58 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA60) /* 5A60 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA64) /* 5A64 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA68) /* 5A68 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA70) /* 5A70 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA74) /* 5A74 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA78) /* 5A78 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA80) /* 5A80 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA84) /* 5A84 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA88) /* 5A88 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA90) /* 5A90 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA94) /* 5A94 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA98) /* 5A98 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xAA0) /* 5AA0 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xAA4) /* 5AA4 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xAA8) /* 5AA8 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xAB0) /* 5AB0 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xAB4) /* 5AB4 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xAB8) /* 5AB8 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xAC0) /* 5AC0 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xAC4) /* 5AC4 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xAC8) /* 5AC8 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xAD0) /* 5AD0 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xAD4) /* 5AD4 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xAD8) /* 5AD8 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xAE0) /* 5AE0 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xAE4) /* 5AE4 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xAE8) /* 5AE8 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xAF0) /* 5AF0 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xAF4) /* 5AF4 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xAF8) /* 5AF8 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING176_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xB00) /* 5B00 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING176_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xB04) /* 5B04 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING176_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xB08) /* 5B08 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xB10) /* 5B10 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xB14) /* 5B14 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xB18) /* 5B18 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xB20) /* 5B20 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xB24) /* 5B24 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xB28) /* 5B28 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xB30) /* 5B30 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xB34) /* 5B34 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xB38) /* 5B38 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xB40) /* 5B40 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xB44) /* 5B44 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xB48) /* 5B48 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xB50) /* 5B50 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xB54) /* 5B54 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xB58) /* 5B58 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xB60) /* 5B60 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xB64) /* 5B64 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xB68) /* 5B68 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xB70) /* 5B70 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xB74) /* 5B74 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xB78) /* 5B78 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xC00) /* 5C00 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xC04) /* 5C04 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xC08) /* 5C08 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xC10) /* 5C10 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xC14) /* 5C14 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xC18) /* 5C18 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xC20) /* 5C20 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xC24) /* 5C24 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xC28) /* 5C28 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xC30) /* 5C30 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xC34) /* 5C34 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xC38) /* 5C38 */ + + + + +/* +* ---HOST_IF_TX_DONE_STS (0x7C025000 + 0XA0)--- +* fifo_dfet_txdone_dat0_done_sts[0] - (W1C) USB DAT0 FIFO Tx status +* 0 : no tx done +* 1 : pdma fetch data from USB endpoint buffer +* fifo_dfet_txdone_dat1_done_sts[1] - (W1C) USB DAT1 FIFO Tx status +* 0 : no tx done +* 1 : pdma fetch data from USB endpoint buffer +* fifo_dfet_txdone_dat2_done_sts[2] - (W1C) USB DAT2 FIFO Tx status +* 0 : no tx done +* 1 : pdma fetch data from USB endpoint buffer +* fifo_dfet_txdone_dat3_done_sts[3] - (W1C) USB DAT3 FIFO Tx status +* 0 : no tx done +* 1 : pdma fetch data from USB endpoint buffer +* fifo_dfet_txdone_dat4_done_sts[4] - (W1C) USB DAT4 FIFO Tx status +* 0 : no tx done +* 1 : pdma fetch data from USB endpoint buffer +* fifo_dfet_txdone_cmd_done_sts[5] - (W1C) USB CMD FIFO Tx status +* 0 : no tx done +* 1 : pdma fetch data from USB endpoint buffer +* fifo_dfet_txdone_fwdl_done_sts[6] - (W1C) USB Firmware download FIFO Tx status +* 0 : no tx done +* 1 : pdma fetch data from USB endpoint buffer +* SDIO Mode (All SDIO Tx packet goto firmware download FIFO) +* 0 : no tx done +* 1 : pdma start to fetch data from SDIO buffer +* RESERVED7[31..7] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_fwdl_done_sts_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_ADDR +#define \ +WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_fwdl_done_sts_MASK \ + 0x00000040 /* fifo_dfet_txdone_fwdl_done_sts[6] */ +#define \ +WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_fwdl_done_sts_SHFT \ + 6 +#define \ +WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_cmd_done_sts_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_ADDR +#define \ +WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_cmd_done_sts_MASK \ + 0x00000020 /* fifo_dfet_txdone_cmd_done_sts[5] */ +#define \ +WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_cmd_done_sts_SHFT \ + 5 +#define \ +WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat4_done_sts_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_ADDR +#define \ +WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat4_done_sts_MASK \ + 0x00000010 /* fifo_dfet_txdone_dat4_done_sts[4] */ +#define \ +WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat4_done_sts_SHFT \ + 4 +#define \ +WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat3_done_sts_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_ADDR +#define \ +WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat3_done_sts_MASK \ + 0x00000008 /* fifo_dfet_txdone_dat3_done_sts[3] */ +#define \ +WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat3_done_sts_SHFT \ + 3 +#define \ +WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat2_done_sts_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_ADDR +#define \ +WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat2_done_sts_MASK \ + 0x00000004 /* fifo_dfet_txdone_dat2_done_sts[2] */ +#define \ +WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat2_done_sts_SHFT \ + 2 +#define \ +WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat1_done_sts_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_ADDR +#define \ +WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat1_done_sts_MASK \ + 0x00000002 /* fifo_dfet_txdone_dat1_done_sts[1] */ +#define \ +WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat1_done_sts_SHFT \ + 1 +#define \ +WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat0_done_sts_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_ADDR +#define \ +WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat0_done_sts_MASK \ + 0x00000001 /* fifo_dfet_txdone_dat0_done_sts[0] */ +#define \ +WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat0_done_sts_SHFT \ + 0 + +/* +* ---HOST_IF_RX_DONE_STS (0x7C025000 + 0XA4)--- +* rx0_packet_done_sts[0] - (W1C) USB/SDIO Rx0 packet done status +* 0 : no rx packet done +* 1 : rx packet send to host interface +* rx1_packet_done_sts[1] - (W1C) USB/SDIO Rx1 packet done status +* 0 : no rx packet done +* 1 : rx packet send to host interface +* Note : All SDIO Packet send to SIDO RX0 port +* RESERVED2[31..2] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_HOST_IF_RX_DONE_STS_rx1_packet_done_sts_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_IF_RX_DONE_STS_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_IF_RX_DONE_STS_rx1_packet_done_sts_MASK \ + 0x00000002 /* rx1_packet_done_sts[1] */ +#define WF_WFDMA_HOST_DMA1_HOST_IF_RX_DONE_STS_rx1_packet_done_sts_SHFT 1 +#define WF_WFDMA_HOST_DMA1_HOST_IF_RX_DONE_STS_rx0_packet_done_sts_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_IF_RX_DONE_STS_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_IF_RX_DONE_STS_rx0_packet_done_sts_MASK \ + 0x00000001 /* rx0_packet_done_sts[0] */ +#define WF_WFDMA_HOST_DMA1_HOST_IF_RX_DONE_STS_rx0_packet_done_sts_SHFT 0 + +/* +* ---CONN_HIF_RST (0x7C025000 + 0x100)--- +* RESERVED0[3..0] - (RO) Reserved bits +* conn_hif_logic_rst_n[4] - (RW) This conn_hif_logic_rst_n would reset wpdma +* logic partial control register, include Tx/Rx ring control. +* Also, conn_hif_logic_rst_n would reset wifi data path, include tx fifo, rx +* fifo, r2x_bridge, axi_mux and other other asynchronous bridge. +* (Note : conn_hif_logic_rst_n would not reset hif_dmashdl logic) +* dmashdl_all_rst_n[5] - (RW) This dmashdl_all_rst_n would reset +* hif_dmashdl_top, include logic and control register. +* RESERVED6[31..6] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_RST_dmashdl_all_rst_n_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_RST_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_RST_dmashdl_all_rst_n_MASK \ + 0x00000020 /* dmashdl_all_rst_n[5] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_RST_dmashdl_all_rst_n_SHFT 5 +#define WF_WFDMA_HOST_DMA1_CONN_HIF_RST_conn_hif_logic_rst_n_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_RST_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_RST_conn_hif_logic_rst_n_MASK \ + 0x00000010 /* conn_hif_logic_rst_n[4] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_RST_conn_hif_logic_rst_n_SHFT 4 + +/* +* ---CONN_HIF_TOP_MISC (0x7C025000 + 0x104)--- +* ahb_mux_2to1_ultra[1..0] - (RW) conn _hif ahb mux ultra +* ahb_mux_2to1_qos_en[2] - (RW) conn_hif ahb mux qos enable +* RESERVED3[4..3] - (RO) Reserved bits +* axi_cg_in_ck_bypass[5] - (RW) axi frequency bridge bus in clock gating bypass +* 0 : enable clock gating function +* 1 : bypass clock gating function +* axi_cg_out_ck_bypass[6] - (RW) axi frequency bridge bus out clock gating +bypass +* 0 : enable clock gating function +* 1 : bypass clock gating function +* RESERVED7[15..7] - (RO) Reserved bits +* pdma_rxring1_immint_en[16] - (RW) PDMA RX Ring 1 Immediate Interrupt Enable +* RESERVED17[31..17] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_TOP_MISC_pdma_rxring1_immint_en_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_TOP_MISC_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_TOP_MISC_pdma_rxring1_immint_en_MASK \ + 0x00010000 /* pdma_rxring1_immint_en[16] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_TOP_MISC_pdma_rxring1_immint_en_SHFT 16 +#define WF_WFDMA_HOST_DMA1_CONN_HIF_TOP_MISC_axi_cg_out_ck_bypass_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_TOP_MISC_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_TOP_MISC_axi_cg_out_ck_bypass_MASK \ + 0x00000040 /* axi_cg_out_ck_bypass[6] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_TOP_MISC_axi_cg_out_ck_bypass_SHFT 6 +#define WF_WFDMA_HOST_DMA1_CONN_HIF_TOP_MISC_axi_cg_in_ck_bypass_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_TOP_MISC_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_TOP_MISC_axi_cg_in_ck_bypass_MASK \ + 0x00000020 /* axi_cg_in_ck_bypass[5] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_TOP_MISC_axi_cg_in_ck_bypass_SHFT 5 +#define WF_WFDMA_HOST_DMA1_CONN_HIF_TOP_MISC_ahb_mux_2to1_qos_en_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_TOP_MISC_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_TOP_MISC_ahb_mux_2to1_qos_en_MASK \ + 0x00000004 /* ahb_mux_2to1_qos_en[2] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_TOP_MISC_ahb_mux_2to1_qos_en_SHFT 2 +#define WF_WFDMA_HOST_DMA1_CONN_HIF_TOP_MISC_ahb_mux_2to1_ultra_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_TOP_MISC_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_TOP_MISC_ahb_mux_2to1_ultra_MASK \ + 0x00000003 /* ahb_mux_2to1_ultra[1..0] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_TOP_MISC_ahb_mux_2to1_ultra_SHFT 0 + +/* +* ---HOST2MCU_SW_INT_SET (0x7C025000 + 0X108)--- +* host2mcu_sw_int_0_set[0] - (WO) Driver set this bit to generate MCU interrupt +* and 0x5000_0110[0] will be set to 1. +* host2mcu_sw_int_1_set[1] - (WO) Driver set this bit to generate MCU interrupt +* and 0x5000_0110[1] will be set to 1. +* host2mcu_sw_int_2_set[2] - (WO) Driver set this bit to generate MCU interrupt +* and 0x5000_0110[2] will be set to 1. +* host2mcu_sw_int_3_set[3] - (WO) Driver set [0x0_4108] bit[3] to generate MCU +* interrupt and 0x5000_0110[3] will be set to 1. +* host2mcu_sw_int_4_set[4] - (WO) Driver set [0x0_4108] bit[4] to generate MCU +* interrupt and 0x5000_0110[4] will be set to 1. +* host2mcu_sw_int_5_set[5] - (WO) Driver set [0x0_4108] bit[5] to generate MCU +* interrupt and 0x5000_0110[5] will be set to 1. +* host2mcu_sw_int_6_set[6] - (WO) Driver set [0x0_4108] bit[6] to generate MCU +* interrupt and 0x5000_0110[6] will be set to 1. +* host2mcu_sw_int_7_set[7] - (WO) Driver set [0x0_4108] bit[7] to generate MCU +* interrupt and 0x5000_0110[7] will be set to 1. +* RESERVED8[31..8] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_7_set_ADDR \ + WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_7_set_MASK \ + 0x00000080 /* host2mcu_sw_int_7_set[7] */ +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_7_set_SHFT 7 +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_6_set_ADDR \ + WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_6_set_MASK \ + 0x00000040 /* host2mcu_sw_int_6_set[6] */ +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_6_set_SHFT 6 +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_5_set_ADDR \ + WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_5_set_MASK \ + 0x00000020 /* host2mcu_sw_int_5_set[5] */ +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_5_set_SHFT 5 +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_4_set_ADDR \ + WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_4_set_MASK \ + 0x00000010 /* host2mcu_sw_int_4_set[4] */ +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_4_set_SHFT 4 +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_3_set_ADDR \ + WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_3_set_MASK \ + 0x00000008 /* host2mcu_sw_int_3_set[3] */ +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_3_set_SHFT 3 +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_2_set_ADDR \ + WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_2_set_MASK \ + 0x00000004 /* host2mcu_sw_int_2_set[2] */ +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_2_set_SHFT 2 +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_1_set_ADDR \ + WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_1_set_MASK \ + 0x00000002 /* host2mcu_sw_int_1_set[1] */ +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_1_set_SHFT 1 +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_0_set_ADDR \ + WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_0_set_MASK \ + 0x00000001 /* host2mcu_sw_int_0_set[0] */ +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_0_set_SHFT 0 + +/* +* ---MCU2HOST_SW_INT_SET (0x7C025000 + 0x10C)--- +* mcu2host_sw_int_set_0[0] - (WO) Internal CPU writes this register will trigger +* MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[0] to check interrupt status +* mcu2host_sw_int_set_1[1] - (WO) Internal CPU writes this register will trigger +* MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[1] to check interrupt status +* mcu2host_sw_int_set_2[2] - (WO) Internal CPU writes this register will trigger +* MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[2] to check interrupt status +* mcu2host_sw_int_set_3[3] - (WO) Internal CPU writes this register will trigger +* MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[3] to check interrupt status +* mcu2host_sw_int_set_4[4] - (WO) Internal CPU writes this register will trigger +* MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[4] to check interrupt status +* mcu2host_sw_int_set_5[5] - (WO) Internal CPU writes this register will trigger +* MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[5] to check interrupt status +* mcu2host_sw_int_set_6[6] - (WO) Internal CPU writes this register will trigger +* MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[6] to check interrupt status +* mcu2host_sw_int_set_7[7] - (WO) Internal CPU writes this register will trigger +* MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[7] to check interrupt status +* mcu2host_sw_int_set_8[8] - (WO) Internal CPU writes this register will trigger +* MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[0] to check interrupt status +* mcu2host_sw_int_set_9[9] - (WO) Internal CPU writes this register will trigger +* MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[1] to check interrupt status +* mcu2host_sw_int_set_10[10] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[2] to check interrupt status +* mcu2host_sw_int_set_11[11] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[3] to check interrupt status +* mcu2host_sw_int_set_12[12] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[4] to check interrupt status +* mcu2host_sw_int_set_13[13] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[5] to check interrupt status +* mcu2host_sw_int_set_14[14] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[6] to check interrupt status +* mcu2host_sw_int_set_15[15] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[7] to check interrupt status +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_15_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_15_MASK \ + 0x00008000 /* mcu2host_sw_int_set_15[15] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_15_SHFT 15 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_14_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_14_MASK \ + 0x00004000 /* mcu2host_sw_int_set_14[14] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_14_SHFT 14 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_13_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_13_MASK \ + 0x00002000 /* mcu2host_sw_int_set_13[13] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_13_SHFT 13 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_12_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_12_MASK \ + 0x00001000 /* mcu2host_sw_int_set_12[12] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_12_SHFT 12 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_11_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_11_MASK \ + 0x00000800 /* mcu2host_sw_int_set_11[11] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_11_SHFT 11 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_10_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_10_MASK \ + 0x00000400 /* mcu2host_sw_int_set_10[10] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_10_SHFT 10 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_9_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_9_MASK \ + 0x00000200 /* mcu2host_sw_int_set_9[9] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_9_SHFT 9 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_8_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_8_MASK \ + 0x00000100 /* mcu2host_sw_int_set_8[8] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_8_SHFT 8 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_7_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_7_MASK \ + 0x00000080 /* mcu2host_sw_int_set_7[7] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_7_SHFT 7 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_6_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_6_MASK \ + 0x00000040 /* mcu2host_sw_int_set_6[6] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_6_SHFT 6 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_5_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_5_MASK \ + 0x00000020 /* mcu2host_sw_int_set_5[5] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_5_SHFT 5 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_4_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_4_MASK \ + 0x00000010 /* mcu2host_sw_int_set_4[4] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_4_SHFT 4 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_3_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_3_MASK \ + 0x00000008 /* mcu2host_sw_int_set_3[3] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_3_SHFT 3 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_2_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_2_MASK \ + 0x00000004 /* mcu2host_sw_int_set_2[2] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_2_SHFT 2 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_1_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_1_MASK \ + 0x00000002 /* mcu2host_sw_int_set_1[1] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_1_SHFT 1 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_0_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_0_MASK \ + 0x00000001 /* mcu2host_sw_int_set_0[0] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_0_SHFT 0 + +/* +* ---MCU_INT_STA (0x7C025000 + 0X110)--- +* host2mcu_sw_int_sts[7..0] - (W1C) MCU interrupt status, write 1 to clear the +interrupt +* wpdma_tx_timeout_int_sts[8] - (W1C) WPDMA TX dma timeout interrupt stauts, +* write 1 to clear the interrupt +* wpdma_rx_timeout_int_sts[9] - (W1C) WPDMA RX dma timeout interrupt stauts, +* write 1 to clear the interrupt +* wifi_txfifo0_wr_ovf_int_sts[10] - (W1C) conn_hif txfifo erorr detec +* interruptt. It indicate tx-fifo memory write overflow. +* wifi_txfifo1_wr_ovf_int_sts[11] - (W1C) conn_hif txfifo erorr detec +* interruptt. It indicate tx-fifo memory write overflow. +* wifi_rxfifo_wr_ovf_int_sts[12] - (W1C) conn_hif rxfifo erorr detect interrupt. +* It indicate rx-fifo memory write overflow. +* wpdma_tx_dmad_mem_range_err_mcu_int_sts[13] - (W1C) WPDMA tx dma descriptor +* memory range error detection mcu interrupt status +* When user setup WPDMA_TX_DMAD_RNG (not equal to zero), design would check +* tx_dmad address. If address range not correct, it would alarm memory range +* error interrupt +* wpdma_rx_dmad_mem_range_err_mcu_int_sts[14] - (W1C) WPDMA rx dma descriptor +* memory range error detection mcu interrupt status +* When user setup WPDMA_RX_DMAD_RNG (not equal to zero), design would check +* rx_dmad address. If address range not correct, it would alarm memory range +* error interrupt +* wpdma_tx_payload_mem_range_err_mcu_int_sts[15] - (W1C) WPDMA tx payload memory +* range error detection mcu interrupt status +* When user setup WPDMA_TX_PLD_RNG (not equal to zero), design would check +* tx_dma payload address. If address range not correct, it would alarm memory +* range error interrupt +* wpdma_rx_payload_mem_range_err_mcu_int_sts[16] - (W1C) WPDMA rx payload memory +* range error detection mcu interrupt status +* When user setup WPDMA_RX_PLD_RNG (not equal to zero), design would check +* rx_dma payload address. If address range not correct, it would alarm memory +* range error interrupt +* RESERVED17[31..17] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_STA_wpdma_rx_payload_mem_range_err_mcu_int_sts_ADDR \ + WF_WFDMA_HOST_DMA1_MCU_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_STA_wpdma_rx_payload_mem_range_err_mcu_int_sts_MASK \ + 0x00010000 /* wpdma_rx_payload_mem_range_err_mcu_int_sts[16] */ +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_STA_wpdma_rx_payload_mem_range_err_mcu_int_sts_SHFT \ + 16 +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_STA_wpdma_tx_payload_mem_range_err_mcu_int_sts_ADDR \ + WF_WFDMA_HOST_DMA1_MCU_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_STA_wpdma_tx_payload_mem_range_err_mcu_int_sts_MASK \ + 0x00008000 /* wpdma_tx_payload_mem_range_err_mcu_int_sts[15] */ +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_STA_wpdma_tx_payload_mem_range_err_mcu_int_sts_SHFT \ + 15 +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_STA_wpdma_rx_dmad_mem_range_err_mcu_int_sts_ADDR \ + WF_WFDMA_HOST_DMA1_MCU_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_STA_wpdma_rx_dmad_mem_range_err_mcu_int_sts_MASK \ + 0x00004000 /* wpdma_rx_dmad_mem_range_err_mcu_int_sts[14] */ +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_STA_wpdma_rx_dmad_mem_range_err_mcu_int_sts_SHFT \ + 14 +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_STA_wpdma_tx_dmad_mem_range_err_mcu_int_sts_ADDR \ + WF_WFDMA_HOST_DMA1_MCU_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_STA_wpdma_tx_dmad_mem_range_err_mcu_int_sts_MASK \ + 0x00002000 /* wpdma_tx_dmad_mem_range_err_mcu_int_sts[13] */ +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_STA_wpdma_tx_dmad_mem_range_err_mcu_int_sts_SHFT \ + 13 +#define WF_WFDMA_HOST_DMA1_MCU_INT_STA_wifi_rxfifo_wr_ovf_int_sts_ADDR \ + WF_WFDMA_HOST_DMA1_MCU_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU_INT_STA_wifi_rxfifo_wr_ovf_int_sts_MASK \ + 0x00001000 /* wifi_rxfifo_wr_ovf_int_sts[12] */ +#define WF_WFDMA_HOST_DMA1_MCU_INT_STA_wifi_rxfifo_wr_ovf_int_sts_SHFT 12 +#define WF_WFDMA_HOST_DMA1_MCU_INT_STA_wifi_txfifo1_wr_ovf_int_sts_ADDR \ + WF_WFDMA_HOST_DMA1_MCU_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU_INT_STA_wifi_txfifo1_wr_ovf_int_sts_MASK \ + 0x00000800 /* wifi_txfifo1_wr_ovf_int_sts[11] */ +#define WF_WFDMA_HOST_DMA1_MCU_INT_STA_wifi_txfifo1_wr_ovf_int_sts_SHFT 11 +#define WF_WFDMA_HOST_DMA1_MCU_INT_STA_wifi_txfifo0_wr_ovf_int_sts_ADDR \ + WF_WFDMA_HOST_DMA1_MCU_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU_INT_STA_wifi_txfifo0_wr_ovf_int_sts_MASK \ + 0x00000400 /* wifi_txfifo0_wr_ovf_int_sts[10] */ +#define WF_WFDMA_HOST_DMA1_MCU_INT_STA_wifi_txfifo0_wr_ovf_int_sts_SHFT 10 +#define WF_WFDMA_HOST_DMA1_MCU_INT_STA_wpdma_rx_timeout_int_sts_ADDR \ + WF_WFDMA_HOST_DMA1_MCU_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU_INT_STA_wpdma_rx_timeout_int_sts_MASK \ + 0x00000200 /* wpdma_rx_timeout_int_sts[9] */ +#define WF_WFDMA_HOST_DMA1_MCU_INT_STA_wpdma_rx_timeout_int_sts_SHFT 9 +#define WF_WFDMA_HOST_DMA1_MCU_INT_STA_wpdma_tx_timeout_int_sts_ADDR \ + WF_WFDMA_HOST_DMA1_MCU_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU_INT_STA_wpdma_tx_timeout_int_sts_MASK \ + 0x00000100 /* wpdma_tx_timeout_int_sts[8] */ +#define WF_WFDMA_HOST_DMA1_MCU_INT_STA_wpdma_tx_timeout_int_sts_SHFT 8 +#define WF_WFDMA_HOST_DMA1_MCU_INT_STA_host2mcu_sw_int_sts_ADDR \ + WF_WFDMA_HOST_DMA1_MCU_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU_INT_STA_host2mcu_sw_int_sts_MASK \ + 0x000000FF /* host2mcu_sw_int_sts[7..0] */ +#define WF_WFDMA_HOST_DMA1_MCU_INT_STA_host2mcu_sw_int_sts_SHFT 0 + +/* +* ---MCU_INT_ENA (0x7C025000 + 0X114)--- +* host2mcu_sw_int_ena[7..0] - (RW) host2mcu interrupt enable +* wpdma_tx_dma_timeout_int_ena[8] - (RW) WPDMA TX error detection interrupt +enable +* wpdma_rx_dma_timeout_int_ena[9] - (RW) WPDMA RX error detection interrupt +enable +* wifi_txfifo0_wr_ovf_int_ena[10] - (RW) conn_hif txfifo erorr detect interrupt +enable. +* wifi_txfifo1_wr_ovf_int_ena[11] - (RW) conn_hif txfifo erorr detect interrupt +enable. +* wifi_rxfifo_wr_ovf_int_ena[12] - (RW) conn_hif rxfifo erorr detect interrupt +enable. +* wpdma_tx_dmad_mem_range_err_mcu_int_ena[13] - (RW) WPDMA tx dma descriptor +* memory range error detection interrupt enable +* wpdma_rx_dmad_mem_range_err_mcu_int_ena[14] - (RW) WPDMA rx dma descriptor +* memory range error detection interrupt enable +* wpdma_tx_payload_mem_range_err_mcu_int_ena[15] - (RW) WPDMA tx payload memory +* range error detection interrupt enable +* wpdma_rx_payload_mem_range_err_mcu_int_ena[16] - (RW) WPDMA rx payload memory +* range error detection interrupt enable +* RESERVED17[31..17] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wpdma_rx_payload_mem_range_err_mcu_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_MCU_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wpdma_rx_payload_mem_range_err_mcu_int_ena_MASK \ + 0x00010000 /* wpdma_rx_payload_mem_range_err_mcu_int_ena[16] */ +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wpdma_rx_payload_mem_range_err_mcu_int_ena_SHFT \ + 16 +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wpdma_tx_payload_mem_range_err_mcu_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_MCU_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wpdma_tx_payload_mem_range_err_mcu_int_ena_MASK \ + 0x00008000 /* wpdma_tx_payload_mem_range_err_mcu_int_ena[15] */ +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wpdma_tx_payload_mem_range_err_mcu_int_ena_SHFT \ + 15 +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wpdma_rx_dmad_mem_range_err_mcu_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_MCU_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wpdma_rx_dmad_mem_range_err_mcu_int_ena_MASK \ + 0x00004000 /* wpdma_rx_dmad_mem_range_err_mcu_int_ena[14] */ +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wpdma_rx_dmad_mem_range_err_mcu_int_ena_SHFT \ + 14 +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wpdma_tx_dmad_mem_range_err_mcu_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_MCU_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wpdma_tx_dmad_mem_range_err_mcu_int_ena_MASK \ + 0x00002000 /* wpdma_tx_dmad_mem_range_err_mcu_int_ena[13] */ +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wpdma_tx_dmad_mem_range_err_mcu_int_ena_SHFT \ + 13 +#define WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wifi_rxfifo_wr_ovf_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_MCU_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wifi_rxfifo_wr_ovf_int_ena_MASK \ + 0x00001000 /* wifi_rxfifo_wr_ovf_int_ena[12] */ +#define WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wifi_rxfifo_wr_ovf_int_ena_SHFT 12 +#define WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wifi_txfifo1_wr_ovf_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_MCU_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wifi_txfifo1_wr_ovf_int_ena_MASK \ + 0x00000800 /* wifi_txfifo1_wr_ovf_int_ena[11] */ +#define WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wifi_txfifo1_wr_ovf_int_ena_SHFT 11 +#define WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wifi_txfifo0_wr_ovf_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_MCU_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wifi_txfifo0_wr_ovf_int_ena_MASK \ + 0x00000400 /* wifi_txfifo0_wr_ovf_int_ena[10] */ +#define WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wifi_txfifo0_wr_ovf_int_ena_SHFT 10 +#define WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wpdma_rx_dma_timeout_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_MCU_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wpdma_rx_dma_timeout_int_ena_MASK \ + 0x00000200 /* wpdma_rx_dma_timeout_int_ena[9] */ +#define WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wpdma_rx_dma_timeout_int_ena_SHFT 9 +#define WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wpdma_tx_dma_timeout_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_MCU_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wpdma_tx_dma_timeout_int_ena_MASK \ + 0x00000100 /* wpdma_tx_dma_timeout_int_ena[8] */ +#define WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wpdma_tx_dma_timeout_int_ena_SHFT 8 +#define WF_WFDMA_HOST_DMA1_MCU_INT_ENA_host2mcu_sw_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_MCU_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU_INT_ENA_host2mcu_sw_int_ena_MASK \ + 0x000000FF /* host2mcu_sw_int_ena[7..0] */ +#define WF_WFDMA_HOST_DMA1_MCU_INT_ENA_host2mcu_sw_int_ena_SHFT 0 + +/* +* ---HOST_INT_STA_EXT (0x7C025000 + 0x118)--- +* RESERVED0[4..0] - (RO) Reserved bits +* tx_done_int_sts_21[5] - (W1C) TX Queue#21 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_22[6] - (W1C) TX Queue#22 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_23[7] - (W1C) TX Queue#23 packet transmit interrupt +* Write 1 to clear the interrupt +* RESERVED8[31..8] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_EXT_tx_done_int_sts_23_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_EXT_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_EXT_tx_done_int_sts_23_MASK \ + 0x00000080 /* tx_done_int_sts_23[7] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_EXT_tx_done_int_sts_23_SHFT 7 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_EXT_tx_done_int_sts_22_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_EXT_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_EXT_tx_done_int_sts_22_MASK \ + 0x00000040 /* tx_done_int_sts_22[6] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_EXT_tx_done_int_sts_22_SHFT 6 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_EXT_tx_done_int_sts_21_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_EXT_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_EXT_tx_done_int_sts_21_MASK \ + 0x00000020 /* tx_done_int_sts_21[5] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_EXT_tx_done_int_sts_21_SHFT 5 + +/* +* ---HOST_INT_ENA_EXT (0x7C025000 + 0X11C)--- +* RESERVED0[4..0] - (RO) Reserved bits +* HOST_TX_DONE_INT_ENA21[5] - (RW) TX Queue#21 packet transmit interrupt +* HOST_TX_DONE_INT_ENA22[6] - (RW) TX Queue#22 packet transmit interrupt +* HOST_TX_DONE_INT_ENA23[7] - (RW) TX Queue#23 packet transmit interrupt +* RESERVED8[31..8] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_EXT_HOST_TX_DONE_INT_ENA23_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_EXT_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_EXT_HOST_TX_DONE_INT_ENA23_MASK \ + 0x00000080 /* HOST_TX_DONE_INT_ENA23[7] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_EXT_HOST_TX_DONE_INT_ENA23_SHFT 7 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_EXT_HOST_TX_DONE_INT_ENA22_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_EXT_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_EXT_HOST_TX_DONE_INT_ENA22_MASK \ + 0x00000040 /* HOST_TX_DONE_INT_ENA22[6] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_EXT_HOST_TX_DONE_INT_ENA22_SHFT 6 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_EXT_HOST_TX_DONE_INT_ENA21_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_EXT_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_EXT_HOST_TX_DONE_INT_ENA21_MASK \ + 0x00000020 /* HOST_TX_DONE_INT_ENA21[5] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_EXT_HOST_TX_DONE_INT_ENA21_SHFT 5 + +/* +* ---CONN_HIF_DUMMY (0x7C025000 + 0x120)--- +* CONN_HIF_DUMMY[31..0] - (RW) Reserved CR, SE will use it for pcie calibration! +*/ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DUMMY_CONN_HIF_DUMMY_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_DUMMY_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DUMMY_CONN_HIF_DUMMY_MASK \ + 0xFFFFFFFF /* CONN_HIF_DUMMY[31..0] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DUMMY_CONN_HIF_DUMMY_SHFT 0 + +/* +* ---WPDMA_DBG_IDX (0x7C025000 + 0x124)--- +* PDMA_DBG_IDX[7..0] - (RW) PDMA debug index +* PDMA_DBG_Enable[8] - (RW) PDMA Debug Enable +* 0: PDMA_DBG_port would has no function +* 1 : PDMA DBG_IDX select PDMA debug flag index +* RESERVED9[31..9] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_DBG_IDX_PDMA_DBG_Enable_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_DBG_IDX_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_DBG_IDX_PDMA_DBG_Enable_MASK \ + 0x00000100 /* PDMA_DBG_Enable[8] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_DBG_IDX_PDMA_DBG_Enable_SHFT 8 +#define WF_WFDMA_HOST_DMA1_WPDMA_DBG_IDX_PDMA_DBG_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_DBG_IDX_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_DBG_IDX_PDMA_DBG_IDX_MASK \ + 0x000000FF /* PDMA_DBG_IDX[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_DBG_IDX_PDMA_DBG_IDX_SHFT 0 + +/* +* ---WPDMA_DBG_PROBE (0x7C025000 + 0x128)--- +* PDMA_DBG_PROBE[31..0] - (RO) PDMA Debug probe read +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_DBG_PROBE_PDMA_DBG_PROBE_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_DBG_PROBE_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_DBG_PROBE_PDMA_DBG_PROBE_MASK \ + 0xFFFFFFFF /* PDMA_DBG_PROBE[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_DBG_PROBE_PDMA_DBG_PROBE_SHFT 0 + +/* +* ---CONN_HIF_DBG_IDX (0x7C025000 + 0x12C)--- +* conn_hif_dbg_byt0_sel[2..0] - (RW) conn_hif_dbg_byt0_sel : Select +* conn_hif_dbg[7:0] from "pdma_dbg"/"hif_dmashdl_top" +* conn_hif_dbg_byt1_sel[5..3] - (RW) conn_hif_dbg_byt1_sel : Select +* conn_hif_dbg[15:8] from "pdma_dbg"/"hif_dmashdl_top" +* conn_hif_dbg_byt2_sel[8..6] - (RW) conn_hif_dbg_byt2_sel : Select +* conn_hif_dbg[23:16] from "pdma_dbg"/"hif_dmashdl_top" +* conn_hif_dbg_byt3_sel[11..9] - (RW) conn_hif_dbg_byt3_sel : Select +* conn_hif_dbg[31:24] from "pdma_dbg"/"hif_dmashdl_top" +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_IDX_conn_hif_dbg_byt3_sel_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_IDX_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_IDX_conn_hif_dbg_byt3_sel_MASK \ + 0x00000E00 /* conn_hif_dbg_byt3_sel[11..9] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_IDX_conn_hif_dbg_byt3_sel_SHFT 9 +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_IDX_conn_hif_dbg_byt2_sel_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_IDX_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_IDX_conn_hif_dbg_byt2_sel_MASK \ + 0x000001C0 /* conn_hif_dbg_byt2_sel[8..6] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_IDX_conn_hif_dbg_byt2_sel_SHFT 6 +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_IDX_conn_hif_dbg_byt1_sel_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_IDX_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_IDX_conn_hif_dbg_byt1_sel_MASK \ + 0x00000038 /* conn_hif_dbg_byt1_sel[5..3] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_IDX_conn_hif_dbg_byt1_sel_SHFT 3 +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_IDX_conn_hif_dbg_byt0_sel_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_IDX_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_IDX_conn_hif_dbg_byt0_sel_MASK \ + 0x00000007 /* conn_hif_dbg_byt0_sel[2..0] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_IDX_conn_hif_dbg_byt0_sel_SHFT 0 + +/* +* ---CONN_HIF_DBG_PROBE (0x7C025000 + 0x130)--- +* conn_hif_dbg_probe[31..0] - (RO) conn_hif_dbg_probe read +*/ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_PROBE_conn_hif_dbg_probe_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_PROBE_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_PROBE_conn_hif_dbg_probe_MASK \ + 0xFFFFFFFF /* conn_hif_dbg_probe[31..0] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_PROBE_conn_hif_dbg_probe_SHFT 0 + +/* +* ---CONN_HIF_DMASHDL_DBG_PROBE (0x7C025000 + 0x134)--- +* DMASHDL_DBG_PROBE[15..0] - (RO) conn_hif_dmashdl_dbg_probe read +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DMASHDL_DBG_PROBE_DMASHDL_DBG_PROBE_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_DMASHDL_DBG_PROBE_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DMASHDL_DBG_PROBE_DMASHDL_DBG_PROBE_MASK \ + 0x0000FFFF /* DMASHDL_DBG_PROBE[15..0] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DMASHDL_DBG_PROBE_DMASHDL_DBG_PROBE_SHFT 0 + +/* +* ---CONN_HIF_BUSY_STATUS (0x7C025000 + 0x138)--- +* conn_hif_txfifo0_busy[0] - (RO) conn_hif txfifo0 busy status +* 0 : txfifo empty +* 1 : txfifo non empty +* conn_hif_txfifo1_busy[1] - (RO) conn_hif txfifo1 busy status +* 0 : txfifo empty +* 1 : txfifo non empty +* conn_hif_rxfifo_busy[2] - (RO) conn_hif rxfifo busy status +* 0 : rxfifo empty +* 1 : rxfifo non empty +* RESERVED[30..3] - (RO) Reserved CR +* conn_hif_busy[31] - (RO) Over all conn_hif busy status, it was busy summation +* of bit[6] ~ bit[0] status +*/ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_STATUS_conn_hif_busy_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_STATUS_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_STATUS_conn_hif_busy_MASK \ + 0x80000000 /* conn_hif_busy[31] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_STATUS_conn_hif_busy_SHFT 31 +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_STATUS_conn_hif_rxfifo_busy_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_STATUS_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_STATUS_conn_hif_rxfifo_busy_MASK \ + 0x00000004 /* conn_hif_rxfifo_busy[2] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_STATUS_conn_hif_rxfifo_busy_SHFT 2 +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_STATUS_conn_hif_txfifo1_busy_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_STATUS_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_STATUS_conn_hif_txfifo1_busy_MASK \ + 0x00000002 /* conn_hif_txfifo1_busy[1] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_STATUS_conn_hif_txfifo1_busy_SHFT 1 +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_STATUS_conn_hif_txfifo0_busy_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_STATUS_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_STATUS_conn_hif_txfifo0_busy_MASK \ + 0x00000001 /* conn_hif_txfifo0_busy[0] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_STATUS_conn_hif_txfifo0_busy_SHFT 0 + +/* +* ---CONN_HIF_BUSY_ENA (0x7C025000 + 0x13c)--- +* conn_hif_txfifo0_busy_enable[0] - (RW) busy enable control +* 0: ignore busy status +* 1: conn_hif_busy would tack care busy status +* conn_hif_txfifo1_busy_enable[1] - (RW) busy enable control +* 0: ignore busy status +* 1: conn_hif_busy would tack care busy status +* conn_hif_rxfifo_busy_enable[2] - (RW) busy enable control +* 0: ignore busy status +* 1: conn_hif_busy would tack care busy status +* axi_mx4to1_w_busy_enable[3] - (RW) busy enable control +* 0: ignore busy status +* 1: conn_hif_busy would tack care busy status +* axi_mx4to1_r_busy_enable[4] - (RW) busy enable control +* 0: ignore busy status +* 1: conn_hif_busy would tack care busy status +* RESERVED[31..5] - (RW) Reserved CR +*/ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_ENA_axi_mx4to1_r_busy_enable_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_ENA_axi_mx4to1_r_busy_enable_MASK \ + 0x00000010 /* axi_mx4to1_r_busy_enable[4] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_ENA_axi_mx4to1_r_busy_enable_SHFT 4 +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_ENA_axi_mx4to1_w_busy_enable_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_ENA_axi_mx4to1_w_busy_enable_MASK \ + 0x00000008 /* axi_mx4to1_w_busy_enable[3] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_ENA_axi_mx4to1_w_busy_enable_SHFT 3 +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_ENA_conn_hif_rxfifo_busy_enable_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_ENA_conn_hif_rxfifo_busy_enable_MASK \ + 0x00000004 /* conn_hif_rxfifo_busy_enable[2] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_ENA_conn_hif_rxfifo_busy_enable_SHFT 2 +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_ENA_conn_hif_txfifo1_busy_enable_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_ENA_conn_hif_txfifo1_busy_enable_MASK \ + 0x00000002 /* conn_hif_txfifo1_busy_enable[1] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_ENA_conn_hif_txfifo1_busy_enable_SHFT 1 +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_ENA_conn_hif_txfifo0_busy_enable_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_ENA_conn_hif_txfifo0_busy_enable_MASK \ + 0x00000001 /* conn_hif_txfifo0_busy_enable[0] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_ENA_conn_hif_txfifo0_busy_enable_SHFT 0 + +/* +* ---CONN_HIF_FIFO_TEST_MOD (0x7C025000 + 0x140)--- +* csr_wfdma_loopback_en[0] - (RW) conn_hif fifo loopback enable +* NOTICE : when loopback, OMIT_TX_INFO and OMIT_RX_INFO sould be both set to +1'b1 +* csr_wfdma_loopback_qsel[2..1] - (RW) No USE for (conn_hif fifo loopback packet +* go into Rx-ring number) +* RESERVED3[31..3] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_FIFO_TEST_MOD_csr_wfdma_loopback_qsel_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_FIFO_TEST_MOD_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_FIFO_TEST_MOD_csr_wfdma_loopback_qsel_MASK \ + 0x00000006 /* csr_wfdma_loopback_qsel[2..1] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_FIFO_TEST_MOD_csr_wfdma_loopback_qsel_SHFT 1 +#define WF_WFDMA_HOST_DMA1_CONN_HIF_FIFO_TEST_MOD_csr_wfdma_loopback_en_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_FIFO_TEST_MOD_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_FIFO_TEST_MOD_csr_wfdma_loopback_en_MASK \ + 0x00000001 /* csr_wfdma_loopback_en[0] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_FIFO_TEST_MOD_csr_wfdma_loopback_en_SHFT 0 + +/* +* ---WPDMA2HOST_ERR_INT_STA (0x7C025000 + 0x1E8)--- +* wpdma_tx_timeout_int_sts[0] - (W1C) WPDMA TX error detection interrupt stauts, +* write 1 to clear the interrupt +* wpdma_rx_timeout_int_sts[1] - (W1C) WPDMA RX error detection interrupt stauts, +* write 1 to clear the interrupt +* wpdma_tx_dmad_mem_range_err_int_sts[2] - (W1C) WPDMA tx dma descriptor memory +* range error detection interrupt status +* When user setup WPDMA_TX_DMAD_RNG (not equal to zero), design would check +* tx_dmad address. If address range not correct, it would alarm memory range +* error interrupt +* wpdma_rx_dmad_mem_range_err_int_sts[3] - (W1C) WPDMA rx dma descriptor memory +* range error detection interrupt status +* When user setup WPDMA_RX_DMAD_RNG (not equal to zero), design would check +* rx_dmad address. If address range not correct, it would alarm memory range +* error interrupt +* wpdma_tx_payload_mem_range_err_int_sts[4] - (W1C) WPDMA tx payload memory +* range error detection interrupt status +* When user setup WPDMA_TX_PLD_RNG (not equal to zero), design would check +* tx_dma payload address. If address range not correct, it would alarm memory +* range error interrupt +* wpdma_rx_payload_mem_range_err_int_sts[5] - (W1C) WPDMA rx payload memory +* range error detection interrupt status +* When user setup WPDMA_RX_PLD_RNG (not equal to zero), design would check +* rx_dma payload address. If address range not correct, it would alarm memory +* range error interrupt +* wpdma_axi_bresp_error_int_sts[6] - (W1C) WPDMA AXI master bresp error +* detection interrupt status, check WPDMA_AXI_MST_DBG1 for error information +* wpdma_axi_rresp_error_int_sts[7] - (W1C) WPDMA AXI master rresp error +* detection interrupt status, check WPDMA_AXI_MST_DBG0 for error information +* m0_wr_axi_err_det_int_sts[8] - (W1C) WPDMA AXI write master for RX payload +* error detection interrupt status +* m1_wr_axi_err_det_int_sts[9] - (W1C) WPDMA AXI write master for RX DMAD error +* detection interrupt status +* m2_wr_axi_err_det_int_sts[10] - (W1C) WPDMA AXI write master for TX DMAD error +* detection interrupt status +* m0_rd_axi_err_det_int_sts[11] - (W1C) WPDMA AXI read master for TX payload +* error detection interrupt status +* m1_rd_axi_err_det_int_sts[12] - (W1C) WPDMA AXI read master for RX DMAD error +* detection interrupt status +* m2_rd_axi_err_det_int_sts[13] - (W1C) WPDMA AXI read master for TX DMAD error +* detection interrupt status +* RESERVED14[14] - (RO) Reserved bits +* pf_sram_size_underflow_int_sts[15] - (RO) Prefetch sram overflow error +* interrupt status. This reflect configured prefetch sram is not enough for all +* TX and RX prefetch ring. Prefetch sram size should be greater than (DMAD size +* total of each RING's MAX_CNT) +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_pf_sram_size_underflow_int_sts_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_pf_sram_size_underflow_int_sts_MASK \ + 0x00008000 /* pf_sram_size_underflow_int_sts[15] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_pf_sram_size_underflow_int_sts_SHFT \ + 15 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_m2_rd_axi_err_det_int_sts_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_m2_rd_axi_err_det_int_sts_MASK \ + 0x00002000 /* m2_rd_axi_err_det_int_sts[13] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_m2_rd_axi_err_det_int_sts_SHFT \ + 13 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_m1_rd_axi_err_det_int_sts_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_m1_rd_axi_err_det_int_sts_MASK \ + 0x00001000 /* m1_rd_axi_err_det_int_sts[12] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_m1_rd_axi_err_det_int_sts_SHFT \ + 12 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_m0_rd_axi_err_det_int_sts_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_m0_rd_axi_err_det_int_sts_MASK \ + 0x00000800 /* m0_rd_axi_err_det_int_sts[11] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_m0_rd_axi_err_det_int_sts_SHFT \ + 11 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_m2_wr_axi_err_det_int_sts_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_m2_wr_axi_err_det_int_sts_MASK \ + 0x00000400 /* m2_wr_axi_err_det_int_sts[10] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_m2_wr_axi_err_det_int_sts_SHFT \ + 10 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_m1_wr_axi_err_det_int_sts_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_m1_wr_axi_err_det_int_sts_MASK \ + 0x00000200 /* m1_wr_axi_err_det_int_sts[9] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_m1_wr_axi_err_det_int_sts_SHFT \ + 9 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_m0_wr_axi_err_det_int_sts_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_m0_wr_axi_err_det_int_sts_MASK \ + 0x00000100 /* m0_wr_axi_err_det_int_sts[8] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_m0_wr_axi_err_det_int_sts_SHFT \ + 8 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_wpdma_axi_rresp_error_int_sts_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_wpdma_axi_rresp_error_int_sts_MASK \ + 0x00000080 /* wpdma_axi_rresp_error_int_sts[7] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_wpdma_axi_rresp_error_int_sts_SHFT \ + 7 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_wpdma_axi_bresp_error_int_sts_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_wpdma_axi_bresp_error_int_sts_MASK \ + 0x00000040 /* wpdma_axi_bresp_error_int_sts[6] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_wpdma_axi_bresp_error_int_sts_SHFT \ + 6 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_wpdma_rx_payload_mem_range_err_int_st\ +s_ADDR \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_wpdma_rx_payload_mem_range_err_int_st\ +s_MASK \ +0x00000020 /* wpdma_rx_payload_mem_range_err_int_sts[5] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_wpdma_rx_payload_mem_range_err_int_st\ +s_SHFT \ +5 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_wpdma_tx_payload_mem_range_err_int_st\ +s_ADDR \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_wpdma_tx_payload_mem_range_err_int_st\ +s_MASK \ +0x00000010 /* wpdma_tx_payload_mem_range_err_int_sts[4] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_wpdma_tx_payload_mem_range_err_int_st\ +s_SHFT \ +4 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_wpdma_rx_dmad_mem_range_err_int_sts_A\ +DDR \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_wpdma_rx_dmad_mem_range_err_int_sts_M\ +ASK \ +0x00000008 /* wpdma_rx_dmad_mem_range_err_int_sts[3] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_wpdma_rx_dmad_mem_range_err_int_sts_S\ +HFT \ +3 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_wpdma_tx_dmad_mem_range_err_int_sts_A\ +DDR \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_wpdma_tx_dmad_mem_range_err_int_sts_M\ +ASK \ +0x00000004 /* wpdma_tx_dmad_mem_range_err_int_sts[2] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_wpdma_tx_dmad_mem_range_err_int_sts_S\ +HFT \ +2 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_wpdma_rx_timeout_int_sts_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_wpdma_rx_timeout_int_sts_MASK \ + 0x00000002 /* wpdma_rx_timeout_int_sts[1] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_wpdma_rx_timeout_int_sts_SHFT \ + 1 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_wpdma_tx_timeout_int_sts_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_wpdma_tx_timeout_int_sts_MASK \ + 0x00000001 /* wpdma_tx_timeout_int_sts[0] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_wpdma_tx_timeout_int_sts_SHFT \ + 0 + +/* +* ---WPDMA2HOST_ERR_INT_ENA (0x7C025000 + 0x1EC)--- +* wpdma_rx_timeout_int_ena[0] - (RW) WPDMA TX error detection interrupt enable +* wpdma_tx_timeout_int_ena[1] - (RW) WPDMA RX error detection interrupt enable +* wpdma_tx_dmad_mem_range_err_int_ena[2] - (RW) WPDMA tx dma descriptor memory +* range error detection interrupt enable +* wpdma_rx_dmad_mem_range_err_int_ena[3] - (RW) WPDMA rx dma descriptor memory +* range error detection interrupt enable +* wpdma_tx_payload_mem_range_err_int_ena[4] - (RW) WPDMA tx payload memory range +* error detection interrupt enable +* wpdma_rx_payload_mem_range_err_int_ena[5] - (RW) WPDMA rx payload memory range +* error detection interrupt enable +* wpdma_axi_bresp_error_int_ena[6] - (RW) WPDMA AXI master bresp error detection +* interrupt enable +* wpdma_axi_rresp_error_int_ena[7] - (RW) WPDMA AXI master rresp error detection +* interrupt enable +* m0_wr_axi_err_det_int_ena[8] - (RW) WPDMA AXI write master for RX payload +* error detection interrupt enable +* m1_wr_axi_err_det_int_ena[9] - (RW) WPDMA AXI write master for RX DMAD error +* detection interrupt enable +* m2_wr_axi_err_det_int_ena[10] - (RW) WPDMA AXI write master for TX DMAD error +* detection interrupt enable +* m0_rd_axi_err_det_int_ena[11] - (RW) WPDMA AXI read master for TX payload +* error detection interrupt enable +* m1_rd_axi_err_det_int_ena[12] - (RW) WPDMA AXI read master for RX DMAD error +* detection interrupt enable +* m2_rd_axi_err_det_int_ena[13] - (RW) WPDMA AXI read master for TX DMAD error +* detection interrupt enable +* RESERVED14[14] - (RO) Reserved bits +* pf_sram_size_underflow_int_ena[15] - (RW) Prefetch sram overflow error +* interrupt enable +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_pf_sram_size_underflow_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_pf_sram_size_underflow_int_ena_MASK \ + 0x00008000 /* pf_sram_size_underflow_int_ena[15] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_pf_sram_size_underflow_int_ena_SHFT \ + 15 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_m2_rd_axi_err_det_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_m2_rd_axi_err_det_int_ena_MASK \ + 0x00002000 /* m2_rd_axi_err_det_int_ena[13] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_m2_rd_axi_err_det_int_ena_SHFT \ + 13 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_m1_rd_axi_err_det_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_m1_rd_axi_err_det_int_ena_MASK \ + 0x00001000 /* m1_rd_axi_err_det_int_ena[12] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_m1_rd_axi_err_det_int_ena_SHFT \ + 12 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_m0_rd_axi_err_det_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_m0_rd_axi_err_det_int_ena_MASK \ + 0x00000800 /* m0_rd_axi_err_det_int_ena[11] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_m0_rd_axi_err_det_int_ena_SHFT \ + 11 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_m2_wr_axi_err_det_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_m2_wr_axi_err_det_int_ena_MASK \ + 0x00000400 /* m2_wr_axi_err_det_int_ena[10] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_m2_wr_axi_err_det_int_ena_SHFT \ + 10 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_m1_wr_axi_err_det_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_m1_wr_axi_err_det_int_ena_MASK \ + 0x00000200 /* m1_wr_axi_err_det_int_ena[9] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_m1_wr_axi_err_det_int_ena_SHFT \ + 9 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_m0_wr_axi_err_det_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_m0_wr_axi_err_det_int_ena_MASK \ + 0x00000100 /* m0_wr_axi_err_det_int_ena[8] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_m0_wr_axi_err_det_int_ena_SHFT \ + 8 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_wpdma_axi_rresp_error_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_wpdma_axi_rresp_error_int_ena_MASK \ + 0x00000080 /* wpdma_axi_rresp_error_int_ena[7] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_wpdma_axi_rresp_error_int_ena_SHFT \ + 7 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_wpdma_axi_bresp_error_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_wpdma_axi_bresp_error_int_ena_MASK \ + 0x00000040 /* wpdma_axi_bresp_error_int_ena[6] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_wpdma_axi_bresp_error_int_ena_SHFT \ + 6 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_wpdma_rx_payload_mem_range_err_int_en\ +a_ADDR \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_wpdma_rx_payload_mem_range_err_int_en\ +a_MASK \ +0x00000020 /* wpdma_rx_payload_mem_range_err_int_ena[5] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_wpdma_rx_payload_mem_range_err_int_en\ +a_SHFT \ +5 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_wpdma_tx_payload_mem_range_err_int_en\ +a_ADDR \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_wpdma_tx_payload_mem_range_err_int_en\ +a_MASK \ +0x00000010 /* wpdma_tx_payload_mem_range_err_int_ena[4] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_wpdma_tx_payload_mem_range_err_int_en\ +a_SHFT \ +4 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_wpdma_rx_dmad_mem_range_err_int_ena_A\ +DDR \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_wpdma_rx_dmad_mem_range_err_int_ena_M\ +ASK \ +0x00000008 /* wpdma_rx_dmad_mem_range_err_int_ena[3] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_wpdma_rx_dmad_mem_range_err_int_ena_S\ +HFT \ +3 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_wpdma_tx_dmad_mem_range_err_int_ena_A\ +DDR \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_wpdma_tx_dmad_mem_range_err_int_ena_M\ +ASK \ +0x00000004 /* wpdma_tx_dmad_mem_range_err_int_ena[2] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_wpdma_tx_dmad_mem_range_err_int_ena_S\ +HFT \ +2 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_wpdma_tx_timeout_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_wpdma_tx_timeout_int_ena_MASK \ + 0x00000002 /* wpdma_tx_timeout_int_ena[1] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_wpdma_tx_timeout_int_ena_SHFT \ + 1 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_wpdma_rx_timeout_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_wpdma_rx_timeout_int_ena_MASK \ + 0x00000001 /* wpdma_rx_timeout_int_ena[0] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_wpdma_rx_timeout_int_ena_SHFT \ + 0 + +/* +* ---MCU2HOST_SW_INT_STA (0x7C025000 + 0x1F0)--- +* mcu2host_sw_int_0[0] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_1[1] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_2[2] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_3[3] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_4[4] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_5[5] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_6[6] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_7[7] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_8[8] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_9[9] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_10[10] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_11[11] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_12[12] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_13[13] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_14[14] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_15[15] - (W1C) mcu2host interrupt status +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_15_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_15_MASK \ + 0x00008000 /* mcu2host_sw_int_15[15] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_15_SHFT 15 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_14_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_14_MASK \ + 0x00004000 /* mcu2host_sw_int_14[14] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_14_SHFT 14 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_13_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_13_MASK \ + 0x00002000 /* mcu2host_sw_int_13[13] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_13_SHFT 13 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_12_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_12_MASK \ + 0x00001000 /* mcu2host_sw_int_12[12] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_12_SHFT 12 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_11_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_11_MASK \ + 0x00000800 /* mcu2host_sw_int_11[11] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_11_SHFT 11 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_10_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_10_MASK \ + 0x00000400 /* mcu2host_sw_int_10[10] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_10_SHFT 10 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_9_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_9_MASK \ + 0x00000200 /* mcu2host_sw_int_9[9] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_9_SHFT 9 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_8_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_8_MASK \ + 0x00000100 /* mcu2host_sw_int_8[8] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_8_SHFT 8 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_7_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_7_MASK \ + 0x00000080 /* mcu2host_sw_int_7[7] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_7_SHFT 7 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_6_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_6_MASK \ + 0x00000040 /* mcu2host_sw_int_6[6] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_6_SHFT 6 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_5_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_5_MASK \ + 0x00000020 /* mcu2host_sw_int_5[5] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_5_SHFT 5 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_4_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_4_MASK \ + 0x00000010 /* mcu2host_sw_int_4[4] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_4_SHFT 4 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_3_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_3_MASK \ + 0x00000008 /* mcu2host_sw_int_3[3] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_3_SHFT 3 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_2_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_2_MASK \ + 0x00000004 /* mcu2host_sw_int_2[2] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_2_SHFT 2 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_1_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_1_MASK \ + 0x00000002 /* mcu2host_sw_int_1[1] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_1_SHFT 1 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_0_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_0_MASK \ + 0x00000001 /* mcu2host_sw_int_0[0] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_0_SHFT 0 + +/* +* ---MCU2HOST_SW_INT_ENA (0x7C025000 + 0x1F4)--- +* mcu2host_int_ena_0[0] - (RW) MCU2HOST software interrupt interrupt enable +* mcu2host_int_ena_1[1] - (RW) MCU2HOST software interrupt interrupt enable +* mcu2host_int_ena_2[2] - (RW) MCU2HOST software interrupt interrupt enable +* mcu2host_int_ena_3[3] - (RW) MCU2HOST software interrupt interrupt enable +* mcu2host_int_ena_4[4] - (RW) MCU2HOST software interrupt interrupt enable +* mcu2host_int_ena_5[5] - (RW) MCU2HOST software interrupt interrupt enable +* mcu2host_int_ena_6[6] - (RW) MCU2HOST software interrupt interrupt enable +* mcu2host_int_ena_7[7] - (RW) MCU2HOST software interrupt interrupt enable +* mcu2host_int_ena_8[8] - (RW) MCU2HOST software interrupt interrupt enable +* mcu2host_int_ena_9[9] - (RW) MCU2HOST software interrupt interrupt enable +* mcu2host_int_ena_10[10] - (RW) MCU2HOST software interrupt interrupt enable +* mcu2host_int_ena_11[11] - (RW) MCU2HOST software interrupt interrupt enable +* mcu2host_int_ena_12[12] - (RW) MCU2HOST software interrupt interrupt enable +* mcu2host_int_ena_13[13] - (RW) MCU2HOST software interrupt interrupt enable +* mcu2host_int_ena_14[14] - (RW) MCU2HOST software interrupt interrupt enable +* mcu2host_int_ena_15[15] - (RW) MCU2HOST software interrupt interrupt enable +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_15_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_15_MASK \ + 0x00008000 /* mcu2host_int_ena_15[15] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_15_SHFT 15 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_14_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_14_MASK \ + 0x00004000 /* mcu2host_int_ena_14[14] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_14_SHFT 14 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_13_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_13_MASK \ + 0x00002000 /* mcu2host_int_ena_13[13] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_13_SHFT 13 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_12_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_12_MASK \ + 0x00001000 /* mcu2host_int_ena_12[12] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_12_SHFT 12 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_11_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_11_MASK \ + 0x00000800 /* mcu2host_int_ena_11[11] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_11_SHFT 11 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_10_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_10_MASK \ + 0x00000400 /* mcu2host_int_ena_10[10] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_10_SHFT 10 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_9_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_9_MASK \ + 0x00000200 /* mcu2host_int_ena_9[9] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_9_SHFT 9 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_8_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_8_MASK \ + 0x00000100 /* mcu2host_int_ena_8[8] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_8_SHFT 8 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_7_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_7_MASK \ + 0x00000080 /* mcu2host_int_ena_7[7] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_7_SHFT 7 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_6_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_6_MASK \ + 0x00000040 /* mcu2host_int_ena_6[6] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_6_SHFT 6 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_5_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_5_MASK \ + 0x00000020 /* mcu2host_int_ena_5[5] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_5_SHFT 5 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_4_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_4_MASK \ + 0x00000010 /* mcu2host_int_ena_4[4] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_4_SHFT 4 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_3_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_3_MASK \ + 0x00000008 /* mcu2host_int_ena_3[3] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_3_SHFT 3 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_2_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_2_MASK \ + 0x00000004 /* mcu2host_int_ena_2[2] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_2_SHFT 2 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_1_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_1_MASK \ + 0x00000002 /* mcu2host_int_ena_1[1] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_1_SHFT 1 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_0_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_0_MASK \ + 0x00000001 /* mcu2host_int_ena_0[0] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_0_SHFT 0 + +/* +* ---SUBSYS2HOST_INT_STA (0x7C025000 + 0x1F8)--- +* mac_int_sts_0[0] - (RO) MAC interrupt 0: TBTT interrupt(Check +* wf_int_wakeup_top/hwisr0 [0x820Fc03c]) +* 0 : no interrupt +* 1 : interrupt assert +* mac_int_sts_1[1] - (RO) MAC interrupt 1: Pre-TBTT interrupt(Check +* wf_int_wakeup_top/hwisr1 [0x820Fc044]) +* 0 : no interrupt +* 1 : interrupt assert +* mac_int_sts_2[2] - (RO) MAC interrupt 2: TX status interrupt(Check +* wf_int_wakeup_top/hwisr2 [0x820Fc04c]) +* 0 : no interrupt +* 1 : interrupt assert +* mac_int_sts_3[3] - (RO) MAC interrupt 3: Auto wakeup interrupt (Check +* wf_int_wakeup_top/hwisr3 [0x820Fc054]) +* 0 : no interrupt +* 1 : interrupt assert +* mac_int_sts_4[4] - (RO) MAC interrupt 4: GP timer interrupt (Check +* wf_int_wakeup_top/hwisr4 [0x820Fc05c]) +* 0 : no interrupt +* 1 : interrupt assert +* RESERVED5[7..5] - (RO) Reserved bits +* conn_hif_on_host_int_sts[8] - (RO) CONN_HIF_ON interrupt enable +* 0 : no conn_hif_on_host_int interrupt +* 1 : conn_hif_on_host_int interrupt assert. User should check conn_hif_on +* (host_csr) interrupt status and clear interrupt. +* conn2ap_sw_irq_sts[9] - (RO) MCUSYS conn2ap_sw_irq status (Check +* conn_mcu_config/EMI_CTL [0x80000150] bit[4:0]) +* 0 : no conn2ap_sw_irq interrupt. +* 1 : conn2ap_sw_irq interrupt assert. User should check mcusys_n9 interrupt +* status and clear interrupt. (conn_mcu_config/EMI_CTL [0x80000150] bit[4:0] != +0) +* RESERVED10[31..10] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_conn2ap_sw_irq_sts_ADDR \ + WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_conn2ap_sw_irq_sts_MASK \ + 0x00000200 /* conn2ap_sw_irq_sts[9] */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_conn2ap_sw_irq_sts_SHFT 9 +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_conn_hif_on_host_int_sts_ADDR \ + WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_conn_hif_on_host_int_sts_MASK \ + 0x00000100 /* conn_hif_on_host_int_sts[8] */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_conn_hif_on_host_int_sts_SHFT 8 +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_4_ADDR \ + WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_4_MASK \ + 0x00000010 /* mac_int_sts_4[4] */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_4_SHFT 4 +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_3_ADDR \ + WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_3_MASK \ + 0x00000008 /* mac_int_sts_3[3] */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_3_SHFT 3 +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_2_ADDR \ + WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_2_MASK \ + 0x00000004 /* mac_int_sts_2[2] */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_2_SHFT 2 +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_1_ADDR \ + WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_1_MASK \ + 0x00000002 /* mac_int_sts_1[1] */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_1_SHFT 1 +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_0_ADDR \ + WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_0_MASK \ + 0x00000001 /* mac_int_sts_0[0] */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_0_SHFT 0 + +/* +* ---SUBSYS2HOST_INT_ENA (0x7C025000 + 0x1FC)--- +* mac_int_ena_0[0] - (RW) MAC interrupt enable +* mac_int_ena_1[1] - (RW) MAC interrupt enable +* mac_int_ena_2[2] - (RW) MAC interrupt enable +* mac_int_ena_3[3] - (RW) MAC interrupt enable +* mac_int_ena_4[4] - (RW) MAC interrupt enable +* RESERVED5[7..5] - (RO) Reserved bits +* conn_hif_on_host_int_ena[8] - (RW) CONN_HIF_ON interrupt enable +* conn2ap_sw_irq_ena[9] - (RW) MCUSYS conn2ap_sw_irq enable +* RESERVED10[31..10] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_conn2ap_sw_irq_ena_ADDR \ + WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_conn2ap_sw_irq_ena_MASK \ + 0x00000200 /* conn2ap_sw_irq_ena[9] */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_conn2ap_sw_irq_ena_SHFT 9 +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_conn_hif_on_host_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_conn_hif_on_host_int_ena_MASK \ + 0x00000100 /* conn_hif_on_host_int_ena[8] */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_conn_hif_on_host_int_ena_SHFT 8 +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_4_ADDR \ + WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_4_MASK \ + 0x00000010 /* mac_int_ena_4[4] */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_4_SHFT 4 +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_3_ADDR \ + WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_3_MASK \ + 0x00000008 /* mac_int_ena_3[3] */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_3_SHFT 3 +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_2_ADDR \ + WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_2_MASK \ + 0x00000004 /* mac_int_ena_2[2] */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_2_SHFT 2 +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_1_ADDR \ + WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_1_MASK \ + 0x00000002 /* mac_int_ena_1[1] */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_1_SHFT 1 +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_0_ADDR \ + WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_0_MASK \ + 0x00000001 /* mac_int_ena_0[0] */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_0_SHFT 0 + +/* +* ---HOST_INT_STA (0x7C025000 + 0x200)--- +* rx_done_int_sts_0[0] - (W1C) RX Queue#0 packet receive interrupt +* Write 1 to clear the interrupt +* Read to get the raw interrupt status +* rx_done_int_sts_1[1] - (W1C) RX Queue#1 packet receive interrupt +* Write 1 to clear the interrupt +* Read to get the raw interrupt status +* rx_done_int_sts_2[2] - (W1C) RX Queue#2 packet receive interrupt +* Write 1 to clear the interrupt +* Read to get the raw interrupt status +* rx_done_int_sts_3[3] - (W1C) RX Queue#3 packet receive interrupt +* Write 1 to clear the interrupt +* Read to get the raw interrupt status +* tx_done_int_sts_0[4] - (W1C) TX Queue#0 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_1[5] - (W1C) TX Queue#1 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_2[6] - (W1C) TX Queue#2 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_3[7] - (W1C) TX Queue#3 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_4[8] - (W1C) TX Queue#4 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_5[9] - (W1C) TX Queue#5 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_6[10] - (W1C) TX Queue#6 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_7[11] - (W1C) TX Queue#7 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_8[12] - (W1C) TX Queue#8 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_9[13] - (W1C) TX Queue#9 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_10[14] - (W1C) TX Queue#10 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_11[15] - (W1C) TX Queue#11 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_12[16] - (W1C) TX Queue#12 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_13[17] - (W1C) TX Queue#13 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_14[18] - (W1C) TX Queue#14 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_15[19] - (W1C) TX Queue#15 packet transmit interrupt +* Write 1 to clear the interrupt +* rx_coherent_int_sts[20] - (W1C) RX_DMA finds data coherent event when checking +* ddone bit +* Write 1 to clear the interrupt +* Read to get the raw interrupt status +* tx_coherent_int_sts[21] - (W1C) TX_DMA finds data coherent event when checking +* ddone bit +* Write 1 to clear the interrupt +* Read to get the raw interrupt status +* RESERVED[23..22] - (RO) reserved, originally used for delayed interrupt of +* legacy TX/RX done +* wpdma2host_err_int_sts[24] - (RO) wpdma interrupt overall status +* User should should check WPDMA_ERR_INT_STA for each wpdma error interrupt +status +* Host could read [0x0_41E8] to check indivisual wpdma2host_error interrupt +status +* tx_done_int_sts_20[25] - (W1C) TX Queue#20 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_16[26] - (W1C) TX Queue#16 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_17[27] - (W1C) TX Queue#17 packet transmit interrupt +* Write 1 to clear the interrupt +* subsys_int_sts[28] - (RO) subsys interrupt overall status +* User should should check SUBSYS2HOST_INT_STA for each interrupt status +* Host could read [0x0_41F8] to check indivisual subsys hw interrupt status +* mcu2host_sw_int_sts[29] - (RO) subsys interrupt overall status +* User should should check SUBSYS2HOST_INT_STA for each interrupt status +* Host could read [0x0_41F8] to check indivisual subsys hw interrupt status +* tx_done_int_sts_18[30] - (W1C) TX Queue#18 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_19[31] - (W1C) TX Queue#19 packet transmit interrupt +* Write 1 to clear the interrupt +*/ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_19_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_19_MASK \ + 0x80000000 /* tx_done_int_sts_19[31] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_19_SHFT 31 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_18_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_18_MASK \ + 0x40000000 /* tx_done_int_sts_18[30] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_18_SHFT 30 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_mcu2host_sw_int_sts_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_mcu2host_sw_int_sts_MASK \ + 0x20000000 /* mcu2host_sw_int_sts[29] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_mcu2host_sw_int_sts_SHFT 29 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_subsys_int_sts_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_subsys_int_sts_MASK \ + 0x10000000 /* subsys_int_sts[28] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_subsys_int_sts_SHFT 28 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_17_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_17_MASK \ + 0x08000000 /* tx_done_int_sts_17[27] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_17_SHFT 27 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_16_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_16_MASK \ + 0x04000000 /* tx_done_int_sts_16[26] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_16_SHFT 26 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_20_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_20_MASK \ + 0x02000000 /* tx_done_int_sts_20[25] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_20_SHFT 25 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_wpdma2host_err_int_sts_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_wpdma2host_err_int_sts_MASK \ + 0x01000000 /* wpdma2host_err_int_sts[24] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_wpdma2host_err_int_sts_SHFT 24 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_coherent_int_sts_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_coherent_int_sts_MASK \ + 0x00200000 /* tx_coherent_int_sts[21] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_coherent_int_sts_SHFT 21 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_rx_coherent_int_sts_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_rx_coherent_int_sts_MASK \ + 0x00100000 /* rx_coherent_int_sts[20] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_rx_coherent_int_sts_SHFT 20 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_15_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_15_MASK \ + 0x00080000 /* tx_done_int_sts_15[19] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_15_SHFT 19 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_14_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_14_MASK \ + 0x00040000 /* tx_done_int_sts_14[18] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_14_SHFT 18 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_13_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_13_MASK \ + 0x00020000 /* tx_done_int_sts_13[17] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_13_SHFT 17 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_12_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_12_MASK \ + 0x00010000 /* tx_done_int_sts_12[16] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_12_SHFT 16 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_11_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_11_MASK \ + 0x00008000 /* tx_done_int_sts_11[15] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_11_SHFT 15 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_10_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_10_MASK \ + 0x00004000 /* tx_done_int_sts_10[14] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_10_SHFT 14 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_9_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_9_MASK \ + 0x00002000 /* tx_done_int_sts_9[13] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_9_SHFT 13 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_8_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_8_MASK \ + 0x00001000 /* tx_done_int_sts_8[12] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_8_SHFT 12 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_7_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_7_MASK \ + 0x00000800 /* tx_done_int_sts_7[11] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_7_SHFT 11 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_6_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_6_MASK \ + 0x00000400 /* tx_done_int_sts_6[10] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_6_SHFT 10 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_5_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_5_MASK \ + 0x00000200 /* tx_done_int_sts_5[9] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_5_SHFT 9 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_4_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_4_MASK \ + 0x00000100 /* tx_done_int_sts_4[8] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_4_SHFT 8 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_3_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_3_MASK \ + 0x00000080 /* tx_done_int_sts_3[7] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_3_SHFT 7 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_2_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_2_MASK \ + 0x00000040 /* tx_done_int_sts_2[6] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_2_SHFT 6 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_1_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_1_MASK \ + 0x00000020 /* tx_done_int_sts_1[5] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_1_SHFT 5 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_0_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_0_MASK \ + 0x00000010 /* tx_done_int_sts_0[4] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_0_SHFT 4 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_rx_done_int_sts_3_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_rx_done_int_sts_3_MASK \ + 0x00000008 /* rx_done_int_sts_3[3] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_rx_done_int_sts_3_SHFT 3 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_rx_done_int_sts_2_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_rx_done_int_sts_2_MASK \ + 0x00000004 /* rx_done_int_sts_2[2] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_rx_done_int_sts_2_SHFT 2 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_rx_done_int_sts_1_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_rx_done_int_sts_1_MASK \ + 0x00000002 /* rx_done_int_sts_1[1] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_rx_done_int_sts_1_SHFT 1 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_rx_done_int_sts_0_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_rx_done_int_sts_0_MASK \ + 0x00000001 /* rx_done_int_sts_0[0] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_rx_done_int_sts_0_SHFT 0 + +/* +* ---HOST_INT_ENA (0x7C025000 + 0X204)--- +* HOST_RX_DONE_INT_ENA0[0] - (RW) RX Queue#0 packet receive interrupt +* HOST_RX_DONE_INT_ENA1[1] - (RW) RX Queue#1 packet receive interrupt +* HOST_RX_DONE_INT_ENA2[2] - (RW) RX Queue#2 packet receive interrupt +* HOST_RX_DONE_INT_ENA3[3] - (RW) RX Queue#3 packet receive interrupt +* HOST_TX_DONE_INT_ENA0[4] - (RW) TX Queue#0 packet transmit interrupt +* HOST_TX_DONE_INT_ENA1[5] - (RW) TX Queue#1 packet transmit interrupt +* HOST_TX_DONE_INT_ENA2[6] - (RW) TX Queue#2 packet transmit interrupt +* HOST_TX_DONE_INT_ENA3[7] - (RW) TX Queue#3 packet transmit interrupt +* HOST_TX_DONE_INT_ENA4[8] - (RW) TX Queue#4 packet transmit interrupt +* HOST_TX_DONE_INT_ENA5[9] - (RW) TX Queue#5 packet transmit interrupt +* HOST_TX_DONE_INT_ENA6[10] - (RW) TX Queue#6 packet transmit interrupt +* HOST_TX_DONE_INT_ENA7[11] - (RW) TX Queue#7 packet transmit interrupt +* HOST_TX_DONE_INT_ENA8[12] - (RW) TX Queue#8 packet transmit interrupt +* HOST_TX_DONE_INT_ENA9[13] - (RW) TX Queue#9 packet transmit interrupt +* HOST_TX_DONE_INT_ENA10[14] - (RW) TX Queue#10 packet transmit interrupt +* HOST_TX_DONE_INT_ENA11[15] - (RW) TX Queue#11 packet transmit interrupt +* HOST_TX_DONE_INT_ENA12[16] - (RW) TX Queue#12 packet transmit interrupt +* HOST_TX_DONE_INT_ENA13[17] - (RW) TX Queue#13 packet transmit interrupt +* HOST_TX_DONE_INT_ENA14[18] - (RW) TX Queue#14 packet transmit interrupt +* HOST_TX_DONE_INT_ENA15[19] - (RW) TX Queue#15 packet transmit interrupt +* HOST_RX_COHERENT_EN[20] - (RW) Enable for RX_DMA data coherent interrupt +* HOST_TX_COHERENT_EN[21] - (RW) Enable for TX_DMA data coherent interrupt +* RESERVED[23..22] - (RO) reserved, originally used for delayed interrupt of +* legacy TX/RX done +* wpdma2host_err_int_ena[24] - (RW) Enable bit of wpdma2host_err_int +* HOST_TX_DONE_INT_ENA20[25] - (RW) TX Queue#20 packet transmit interrupt +* HOST_TX_DONE_INT_ENA16[26] - (RW) TX Queue#16 packet transmit interrupt +* HOST_TX_DONE_INT_ENA17[27] - (RW) TX Queue#17 packet transmit interrupt +* subsys_int_ena[28] - (RW) Enable bit of subsys_int +* mcu2host_sw_int_ena[29] - (RW) Enable bit of mcu2host_sw_int +* HOST_TX_DONE_INT_ENA18[30] - (RW) TX Queue#18 packet transmit interrupt +* HOST_TX_DONE_INT_ENA19[31] - (RW) TX Queue#19 packet transmit interrupt +*/ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA19_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA19_MASK \ + 0x80000000 /* HOST_TX_DONE_INT_ENA19[31] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA19_SHFT 31 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA18_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA18_MASK \ + 0x40000000 /* HOST_TX_DONE_INT_ENA18[30] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA18_SHFT 30 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_mcu2host_sw_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_mcu2host_sw_int_ena_MASK \ + 0x20000000 /* mcu2host_sw_int_ena[29] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_mcu2host_sw_int_ena_SHFT 29 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_subsys_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_subsys_int_ena_MASK \ + 0x10000000 /* subsys_int_ena[28] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_subsys_int_ena_SHFT 28 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA17_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA17_MASK \ + 0x08000000 /* HOST_TX_DONE_INT_ENA17[27] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA17_SHFT 27 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA16_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA16_MASK \ + 0x04000000 /* HOST_TX_DONE_INT_ENA16[26] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA16_SHFT 26 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA20_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA20_MASK \ + 0x02000000 /* HOST_TX_DONE_INT_ENA20[25] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA20_SHFT 25 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_wpdma2host_err_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_wpdma2host_err_int_ena_MASK \ + 0x01000000 /* wpdma2host_err_int_ena[24] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_wpdma2host_err_int_ena_SHFT 24 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_COHERENT_EN_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_COHERENT_EN_MASK \ + 0x00200000 /* HOST_TX_COHERENT_EN[21] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_COHERENT_EN_SHFT 21 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_RX_COHERENT_EN_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_RX_COHERENT_EN_MASK \ + 0x00100000 /* HOST_RX_COHERENT_EN[20] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_RX_COHERENT_EN_SHFT 20 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA15_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA15_MASK \ + 0x00080000 /* HOST_TX_DONE_INT_ENA15[19] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA15_SHFT 19 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA14_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA14_MASK \ + 0x00040000 /* HOST_TX_DONE_INT_ENA14[18] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA14_SHFT 18 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA13_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA13_MASK \ + 0x00020000 /* HOST_TX_DONE_INT_ENA13[17] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA13_SHFT 17 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA12_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA12_MASK \ + 0x00010000 /* HOST_TX_DONE_INT_ENA12[16] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA12_SHFT 16 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA11_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA11_MASK \ + 0x00008000 /* HOST_TX_DONE_INT_ENA11[15] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA11_SHFT 15 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA10_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA10_MASK \ + 0x00004000 /* HOST_TX_DONE_INT_ENA10[14] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA10_SHFT 14 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA9_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA9_MASK \ + 0x00002000 /* HOST_TX_DONE_INT_ENA9[13] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA9_SHFT 13 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA8_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA8_MASK \ + 0x00001000 /* HOST_TX_DONE_INT_ENA8[12] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA8_SHFT 12 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA7_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA7_MASK \ + 0x00000800 /* HOST_TX_DONE_INT_ENA7[11] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA7_SHFT 11 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA6_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA6_MASK \ + 0x00000400 /* HOST_TX_DONE_INT_ENA6[10] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA6_SHFT 10 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA5_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA5_MASK \ + 0x00000200 /* HOST_TX_DONE_INT_ENA5[9] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA5_SHFT 9 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA4_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA4_MASK \ + 0x00000100 /* HOST_TX_DONE_INT_ENA4[8] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA4_SHFT 8 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA3_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA3_MASK \ + 0x00000080 /* HOST_TX_DONE_INT_ENA3[7] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA3_SHFT 7 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA2_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA2_MASK \ + 0x00000040 /* HOST_TX_DONE_INT_ENA2[6] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA2_SHFT 6 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA1_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA1_MASK \ + 0x00000020 /* HOST_TX_DONE_INT_ENA1[5] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA1_SHFT 5 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA0_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA0_MASK \ + 0x00000010 /* HOST_TX_DONE_INT_ENA0[4] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA0_SHFT 4 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_RX_DONE_INT_ENA3_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_RX_DONE_INT_ENA3_MASK \ + 0x00000008 /* HOST_RX_DONE_INT_ENA3[3] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_RX_DONE_INT_ENA3_SHFT 3 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_RX_DONE_INT_ENA2_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_RX_DONE_INT_ENA2_MASK \ + 0x00000004 /* HOST_RX_DONE_INT_ENA2[2] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_RX_DONE_INT_ENA2_SHFT 2 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_RX_DONE_INT_ENA1_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_RX_DONE_INT_ENA1_MASK \ + 0x00000002 /* HOST_RX_DONE_INT_ENA1[1] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_RX_DONE_INT_ENA1_SHFT 1 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_RX_DONE_INT_ENA0_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_RX_DONE_INT_ENA0_MASK \ + 0x00000001 /* HOST_RX_DONE_INT_ENA0[0] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_RX_DONE_INT_ENA0_SHFT 0 + +/* +* ---WPDMA_GLO_CFG (0x7C025000 + 0x208)--- +* TX_DMA_EN[0] - (RW) TX_DMA Enable +* 1: Enable TX_DMA, MUST wait until all prefetch rings' +* MAX_CNT(WPDMA_T(R)X_RING*_EXT_CTRL) of DMA including neighbor DMA have been +* configured successfully +* 0: Disable TX_DMA +* TX_DMA_BUSY[1] - (RO) TX_DMA Busy indicator +* 1: TX_DMA is busy +* 0: TX_DMA is not busy +* RX_DMA_EN[2] - (RW) RX_DMA Enable +* 1: Enable RX_DMA, MUST wait until all prefetch rings' +* MAX_CNT(WPDMA_T(R)X_RING*_EXT_CTRL) of DMA including neighbor DMA have been +* configured successfully +* 0: Disable RX_DMA +* RX_DMA_BUSY[3] - (RO) RX_DMA Busy indicator +* 1: RX_DMA is busy +* 0: RX_DMA is not busy +* PDMA_BT_SIZE[5..4] - (RW) Define the burst size of WPDMA +* 2'h0 : 4 DWORD (16bytes) +* 2'h1 : 8 DWORD (32 bytes) +* 2'h2 : 16 DWORD (64 bytes) +* 2'h3 : 32 DWORD (128 bytes) +* TX_WB_DDONE[6] - (RW) 1'b1 : TX engine will wait to assert IRQ util whole TX +* dmad has been fully written into AXI bus which represents HOST memory, 1'b0 : +* TX engine will assert IRQ once TX dmad write-back request have been ACKed +* BIG_ENDIAN[7] - (RW) The endian mode selection. DMA applies the endian rule to +* convert payload and TX/RX information. DMA won't apply endian rule to register +* or descriptor. +* 1: big endian. +* 0: little endian. +* DMAD_32B_EN[8] - (RW) DMA Descriptor 32-byte Enable +* 0: The size of descriptors is set to 16-byte +* 1: The size of descriptors is set to 32-byte +* FW_DWLD_Bypass_dmashdl[9] - (RW) No USE for (APSOC/PCIE) +* For firmware download packet, driver shold using tx-ring16 to download packet +* and set this bit to bypass dmashdl resource control. +* After firmware download finish, driver should clear this bit. +* After all, tx-ring16 could be used for normal data operation. +(USB) +* For USB test_mode, user could set this bit to bypass dmashdl with all endpoint +* CSR_WFDMA_DUMMY_REG[10] - (RW) dummy CR for use if ECO needed +* CSR_AXI_BUFRDY_BYP[11] - (RW) to disable read data fifo available checking +* before issuing next AXI read request +* FIFO_LITTLE_ENDIAN[12] - (RW) Determines the endianness of the FIFO side +* 0: Big-endian +* 1: Little-endian +* CSR_RX_WB_DDONE[13] - (RW) 1'b1 : RX engine will wait to assert IRQ util whole +* RX dmad has been fully written into AXI bus which represents HOST memory, 1'b0 +* : RX engine will assert IRQ once RX dmad write-back request have been ACKed +* CSR_PP_HIF_TXP_ACTIVE_EN[14] - (RW) 1'b1 : enable legacy pp_hif_txp_active +* function to lock tx engine for favor TXP transmit requested directly from PP, +* other pdma TX rings request will be masked until pp_hif_txp_active is +deasserted +* 1'b0 : disable legacy pp_hif_txp_active function, use latest TX source QoS +* design to change throttler settings to favor TXP transmit! +* CSR_DISP_BASE_PTR_CHAIN_EN[15] - (RW) Enable prefet sram ring address +* arrangement by hardware chain structure(DMA#N TX ring group -> DMA#N RX ring +* group -> DMA#M TX ring group -> DMA#M RX ring group and son on). If not +* enabled, firmware need to program DISP_BASE_PTR of WPDMA_T(R)X_RING*_EXT_CTRL +instead!! +* CSR_LBK_RX_Q_SEL[17..16] - (RW) loopback data from TXFIFO will be direct to +* this RX ring when CSR_LBK_RX_Q_SEL_EN in loopback mode, valid bit-width is +* equal to RX_RING_WIDTH which can be calculated from WPDMA_INFO 0x284[15:8] +RX_RING_NUMBER +* RESERVED18[19..18] - (RO) Reserved bits +* CSR_LBK_RX_Q_SEL_EN[20] - (RW) Force configured CSR_LBK_RX_Q_SEL to receive +* loopback data from TXFIFO +* RESERVED21[23..21] - (RO) Reserved bits +* CSR_SW_RST[24] - (RO) SW reset all designs (To be tested for SER in the +future) +* FORCE_TX_EOF[25] - (RW) Force to send an eof after PDMA being reset (for +Packet_Processor) +* 0: Disabled +* 1: Enabled +* PDMA_ADDR_EXT_EN[26] - (RW) No Fnction for now!! For PDMA Address 32bits +* extension. When this design option was enable. PDMA would change Tx/Rx +* descriptor format for address extension. +* 0 : PDMA 32bits address +* 1 : PDMA Tx descirptor DW3 (TXINFO) would used to extend address +* PDMA Rx descirpt DW2 (Reserved) would used to extend address. +* OMIT_RX_INFO[27] - (RW) For loopback mode, set to 1'b1. +* For normal wifi data operation. User should not set this option and should +* keep 1'b0 because UMAC will always add extra QW for checksum after received +* packet's laster QW +* VERY IMPORTANT : for cpu_dma0/1 where CR resides in 0x5100_0xxx, OMIT_RX_INFO +* MUST be set to 1'b1 +* Omit rx_info of all RX packets +* 0: All the PX packets should end with a rx_info +* 1: All the PX packets should NOT end with a rx_info but an eof +* OMIT_TX_INFO[28] - (RW) For loopback mode, set to 1'b1. +* For normal wifi data operation. User should set this option to +* Omit tx_info of all TX packets because UMAC design not support TXINFO +* 0: The tx_info in DMAD will be sent at the beginning +* 1: The tx_info in DMAD will NOT be sent at the beginning +* BYTE_SWAP[29] - (RW) Byte Swapping for TX/RX DMAD +* 0: Not to swap (Endian of DMAD unchanged) +* 1: Swap (Endian of DMAD reversed) +* CLK_GATE_DIS[30] - (RW) PDMA Clock Gated Function Disable +* 0: normal function +* 1: disable clock gated function +* RX_2B_OFFSET[31] - (RW) RX PBF 2-byte Offset +* 1: Skip the first two bytes of the RX PBF +* 0: Not to skip the first two bytes of the RX PBF +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_RX_2B_OFFSET_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_RX_2B_OFFSET_MASK \ + 0x80000000 /* RX_2B_OFFSET[31] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_RX_2B_OFFSET_SHFT 31 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CLK_GATE_DIS_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CLK_GATE_DIS_MASK \ + 0x40000000 /* CLK_GATE_DIS[30] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CLK_GATE_DIS_SHFT 30 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_BYTE_SWAP_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_BYTE_SWAP_MASK \ + 0x20000000 /* BYTE_SWAP[29] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_BYTE_SWAP_SHFT 29 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_OMIT_TX_INFO_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_OMIT_TX_INFO_MASK \ + 0x10000000 /* OMIT_TX_INFO[28] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_OMIT_TX_INFO_SHFT 28 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_OMIT_RX_INFO_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_OMIT_RX_INFO_MASK \ + 0x08000000 /* OMIT_RX_INFO[27] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_OMIT_RX_INFO_SHFT 27 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_PDMA_ADDR_EXT_EN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_PDMA_ADDR_EXT_EN_MASK \ + 0x04000000 /* PDMA_ADDR_EXT_EN[26] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_PDMA_ADDR_EXT_EN_SHFT 26 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_FORCE_TX_EOF_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_FORCE_TX_EOF_MASK \ + 0x02000000 /* FORCE_TX_EOF[25] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_FORCE_TX_EOF_SHFT 25 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_SW_RST_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_SW_RST_MASK \ + 0x01000000 /* CSR_SW_RST[24] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_SW_RST_SHFT 24 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_LBK_RX_Q_SEL_EN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_LBK_RX_Q_SEL_EN_MASK \ + 0x00100000 /* CSR_LBK_RX_Q_SEL_EN[20] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_LBK_RX_Q_SEL_EN_SHFT 20 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_LBK_RX_Q_SEL_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_LBK_RX_Q_SEL_MASK \ + 0x00030000 /* CSR_LBK_RX_Q_SEL[17..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_LBK_RX_Q_SEL_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN_MASK \ + 0x00008000 /* CSR_DISP_BASE_PTR_CHAIN_EN[15] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN_SHFT 15 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_PP_HIF_TXP_ACTIVE_EN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_PP_HIF_TXP_ACTIVE_EN_MASK \ + 0x00004000 /* CSR_PP_HIF_TXP_ACTIVE_EN[14] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_PP_HIF_TXP_ACTIVE_EN_SHFT 14 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_RX_WB_DDONE_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_RX_WB_DDONE_MASK \ + 0x00002000 /* CSR_RX_WB_DDONE[13] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_RX_WB_DDONE_SHFT 13 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_FIFO_LITTLE_ENDIAN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_FIFO_LITTLE_ENDIAN_MASK \ + 0x00001000 /* FIFO_LITTLE_ENDIAN[12] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_FIFO_LITTLE_ENDIAN_SHFT 12 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_AXI_BUFRDY_BYP_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_AXI_BUFRDY_BYP_MASK \ + 0x00000800 /* CSR_AXI_BUFRDY_BYP[11] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_AXI_BUFRDY_BYP_SHFT 11 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_WFDMA_DUMMY_REG_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_WFDMA_DUMMY_REG_MASK \ + 0x00000400 /* CSR_WFDMA_DUMMY_REG[10] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_WFDMA_DUMMY_REG_SHFT 10 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_FW_DWLD_Bypass_dmashdl_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_FW_DWLD_Bypass_dmashdl_MASK \ + 0x00000200 /* FW_DWLD_Bypass_dmashdl[9] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_FW_DWLD_Bypass_dmashdl_SHFT 9 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_DMAD_32B_EN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_DMAD_32B_EN_MASK \ + 0x00000100 /* DMAD_32B_EN[8] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_DMAD_32B_EN_SHFT 8 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_BIG_ENDIAN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_BIG_ENDIAN_MASK \ + 0x00000080 /* BIG_ENDIAN[7] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_BIG_ENDIAN_SHFT 7 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_TX_WB_DDONE_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_TX_WB_DDONE_MASK \ + 0x00000040 /* TX_WB_DDONE[6] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_TX_WB_DDONE_SHFT 6 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_PDMA_BT_SIZE_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_PDMA_BT_SIZE_MASK \ + 0x00000030 /* PDMA_BT_SIZE[5..4] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_PDMA_BT_SIZE_SHFT 4 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_RX_DMA_BUSY_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_RX_DMA_BUSY_MASK \ + 0x00000008 /* RX_DMA_BUSY[3] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_RX_DMA_BUSY_SHFT 3 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_RX_DMA_EN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_RX_DMA_EN_MASK \ + 0x00000004 /* RX_DMA_EN[2] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_RX_DMA_EN_SHFT 2 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_TX_DMA_BUSY_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_TX_DMA_BUSY_MASK \ + 0x00000002 /* TX_DMA_BUSY[1] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_TX_DMA_BUSY_SHFT 1 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_TX_DMA_EN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_TX_DMA_EN_MASK \ + 0x00000001 /* TX_DMA_EN[0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_TX_DMA_EN_SHFT 0 + +/* +* ---WPDMA_RST_DTX_PTR (0x7C025000 + 0x20C)--- +* RST_DTX_IDX0[0] - (WO) Write 1 to reset to TX_DMATX_IDX0 to 0 +* RST_DTX_IDX1[1] - (WO) Write 1 to reset to TX_DMATX_IDX1 to 0 +* RST_DTX_IDX2[2] - (WO) Write 1 to reset to TX_DMATX_IDX2 to 0 +* RST_DTX_IDX3[3] - (WO) Write 1 to reset to TX_DMATX_IDX3 to 0 +* RST_DTX_IDX4[4] - (WO) Write 1 to reset to TX_DMATX_IDX4 to 0 +* RST_DTX_IDX5[5] - (WO) Write 1 to reset to TX_DMATX_IDX5 to 0 +* RST_DTX_IDX6[6] - (WO) Write 1 to reset to TX_DMATX_IDX6 to 0 +* RST_DTX_IDX7[7] - (WO) Write 1 to reset to TX_DMATX_IDX7 to 0 +* RST_DTX_IDX8[8] - (WO) Write 1 to reset to TX_DMATX_IDX8 to 0 +* RST_DTX_IDX9[9] - (WO) Write 1 to reset to TX_DMATX_IDX9 to 0 +* RST_DTX_IDX10[10] - (WO) Write 1 to reset to TX_DMATX_IDX10 to 0 +* RST_DTX_IDX11[11] - (WO) Write 1 to reset to TX_DMATX_IDX11 to 0 +* RST_DTX_IDX12[12] - (WO) Write 1 to reset to TX_DMATX_IDX12 to 0 +* RST_DTX_IDX13[13] - (WO) Write 1 to reset to TX_DMATX_IDX13 to 0 +* RST_DTX_IDX14[14] - (WO) Write 1 to reset to TX_DMATX_IDX14 to 0 +* RST_DTX_IDX15[15] - (WO) Write 1 to reset to TX_DMATX_IDX15 to 0 +* RST_DTX_IDX16[16] - (WO) Write 1 to reset to TX_DMATX_IDX16 to 0 +* RST_DTX_IDX17[17] - (WO) Write 1 to reset to TX_DMATX_IDX17 to 0 +* RST_DTX_IDX18[18] - (WO) Write 1 to reset to TX_DMATX_IDX18 to 0 +* RST_DTX_IDX19[19] - (WO) Write 1 to reset to TX_DMATX_IDX19 to 0 +* RESERVED[31..20] - (WO) Reserved +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX19_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX19_MASK \ + 0x00080000 /* RST_DTX_IDX19[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX19_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX18_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX18_MASK \ + 0x00040000 /* RST_DTX_IDX18[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX18_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX17_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX17_MASK \ + 0x00020000 /* RST_DTX_IDX17[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX17_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX16_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX16_MASK \ + 0x00010000 /* RST_DTX_IDX16[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX16_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX15_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX15_MASK \ + 0x00008000 /* RST_DTX_IDX15[15] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX15_SHFT 15 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX14_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX14_MASK \ + 0x00004000 /* RST_DTX_IDX14[14] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX14_SHFT 14 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX13_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX13_MASK \ + 0x00002000 /* RST_DTX_IDX13[13] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX13_SHFT 13 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX12_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX12_MASK \ + 0x00001000 /* RST_DTX_IDX12[12] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX12_SHFT 12 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX11_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX11_MASK \ + 0x00000800 /* RST_DTX_IDX11[11] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX11_SHFT 11 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX10_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX10_MASK \ + 0x00000400 /* RST_DTX_IDX10[10] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX10_SHFT 10 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX9_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX9_MASK \ + 0x00000200 /* RST_DTX_IDX9[9] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX9_SHFT 9 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX8_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX8_MASK \ + 0x00000100 /* RST_DTX_IDX8[8] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX8_SHFT 8 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX7_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX7_MASK \ + 0x00000080 /* RST_DTX_IDX7[7] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX7_SHFT 7 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX6_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX6_MASK \ + 0x00000040 /* RST_DTX_IDX6[6] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX6_SHFT 6 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX5_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX5_MASK \ + 0x00000020 /* RST_DTX_IDX5[5] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX5_SHFT 5 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX4_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX4_MASK \ + 0x00000010 /* RST_DTX_IDX4[4] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX4_SHFT 4 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX3_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX3_MASK \ + 0x00000008 /* RST_DTX_IDX3[3] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX3_SHFT 3 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX2_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX2_MASK \ + 0x00000004 /* RST_DTX_IDX2[2] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX2_SHFT 2 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX1_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX1_MASK \ + 0x00000002 /* RST_DTX_IDX1[1] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX1_SHFT 1 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX0_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX0_MASK \ + 0x00000001 /* RST_DTX_IDX0[0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX0_SHFT 0 + +/* +* ---WPDMA_PAUSE_TX_Q (0x7C025000 + 0x224)--- +* TX_Q_PAUSE[31..0] - (RW) Pause signal for each TX ring (16 bits for 16 rings) +* Set 0: Normal function; Set 1: The corresponding TX ring is paused +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_TX_Q_TX_Q_PAUSE_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_TX_Q_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_TX_Q_TX_Q_PAUSE_MASK \ + 0xFFFFFFFF /* TX_Q_PAUSE[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_TX_Q_TX_Q_PAUSE_SHFT 0 + +/* +* ---WPDMA_TIMEOUT_CFG (0x7C025000 + 0x230)--- +* WPDMA_TX_TIMEOUT_TH[7..0] - (RW) xxx +* WPDMA_TX_TIMEOUT_TICK[14..8] - (RW) xxx +* WPDMA_TX_TIMEOUT_ENA[15] - (RW) xxx +* WPDMA_RX_TIMEOUT_TH[23..16] - (RW) xxx +* WPDMA_RX_TIMEOUT_TICK[30..24] - (RW) xxx +* WPDMA_RX_TIMEOUT_ENA[31] - (RW) xxx +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_ENA_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_ENA_MASK \ + 0x80000000 /* WPDMA_RX_TIMEOUT_ENA[31] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_ENA_SHFT 31 +#define WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_TICK_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_TICK_MASK \ + 0x7F000000 /* WPDMA_RX_TIMEOUT_TICK[30..24] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_TICK_SHFT 24 +#define WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_TH_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_TH_MASK \ + 0x00FF0000 /* WPDMA_RX_TIMEOUT_TH[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_TH_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_ENA_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_ENA_MASK \ + 0x00008000 /* WPDMA_TX_TIMEOUT_ENA[15] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_ENA_SHFT 15 +#define WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_TICK_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_TICK_MASK \ + 0x00007F00 /* WPDMA_TX_TIMEOUT_TICK[14..8] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_TICK_SHFT 8 +#define WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_TH_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_TH_MASK \ + 0x000000FF /* WPDMA_TX_TIMEOUT_TH[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_TH_SHFT 0 + +/* +* ---WPDMA_MISC_CFG (0x7C025000 + 0x234)--- +* WPDMA_TX_TIMEOUT_SEL[0] - (RW) xxx +* WPDMA_RX_TIMEOUT_SEL[1] - (RW) xxx +* WPDMA_RX_FREE_Q_TH[5..2] - (RW) When loopback, this will be used to generate +* correct tx_pause to avlid deadlock which caused from situration that tx_dma +* will start reading tx packet from memory without considering lack of RX dmad +* in prefetch sram and needing to read RX dmad from memory which tx dma is +* reading tx packet too and rready is deasserted due to txfifo full !! +* RX dmad in prefetch sram should be greater than RX_FREE_Q_TH for rx_dma to +* start writing received packet into memory!! +* RESERVED6[31..6] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_MISC_CFG_WPDMA_RX_FREE_Q_TH_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_MISC_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_MISC_CFG_WPDMA_RX_FREE_Q_TH_MASK \ + 0x0000003C /* WPDMA_RX_FREE_Q_TH[5..2] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_MISC_CFG_WPDMA_RX_FREE_Q_TH_SHFT 2 +#define WF_WFDMA_HOST_DMA1_WPDMA_MISC_CFG_WPDMA_RX_TIMEOUT_SEL_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_MISC_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_MISC_CFG_WPDMA_RX_TIMEOUT_SEL_MASK \ + 0x00000002 /* WPDMA_RX_TIMEOUT_SEL[1] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_MISC_CFG_WPDMA_RX_TIMEOUT_SEL_SHFT 1 +#define WF_WFDMA_HOST_DMA1_WPDMA_MISC_CFG_WPDMA_TX_TIMEOUT_SEL_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_MISC_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_MISC_CFG_WPDMA_TX_TIMEOUT_SEL_MASK \ + 0x00000001 /* WPDMA_TX_TIMEOUT_SEL[0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_MISC_CFG_WPDMA_TX_TIMEOUT_SEL_SHFT 0 + +/* +* ---WPDMA_TX_WRR_ARB_GBF0 (0x7C025000 + 0x240)--- +* WRR_REQ0_ARB_GBF[2..0] - (RW) WRR REQ#0 priority level, mapped to lumpped +* request from TX ring0~ring15 for host TXD +* WRR_REQ1_ARB_GBF[5..3] - (RW) WRR REQ#1 priority level, mapped to request from +* TX ring16 when dual tx fifo for host event packet +* WRR_REQ2_ARB_GBF[8..6] - (RW) WRR REQ#2 priority level, mapped to request from +* TX ring17 when dual tx fifo for host event packet +* WRR_REQ3_ARB_GBF[11..9] - (RW) WRR REQ#3 priority level, mapped to request +* from TX ring18 when dual tx fifo for host event packet +* WRR_REQ4_ARB_GBF[14..12] - (RW) WRR REQ#4 priority level, mapped to request +* from TX ring19 when dual tx fifo for host event packet +* RESERVED[31..15] - (RW) Reserved +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ4_ARB_GBF_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_WRR_ARB_GBF0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ4_ARB_GBF_MASK \ + 0x00007000 /* WRR_REQ4_ARB_GBF[14..12] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ4_ARB_GBF_SHFT 12 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ3_ARB_GBF_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_WRR_ARB_GBF0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ3_ARB_GBF_MASK \ + 0x00000E00 /* WRR_REQ3_ARB_GBF[11..9] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ3_ARB_GBF_SHFT 9 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ2_ARB_GBF_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_WRR_ARB_GBF0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ2_ARB_GBF_MASK \ + 0x000001C0 /* WRR_REQ2_ARB_GBF[8..6] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ2_ARB_GBF_SHFT 6 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ1_ARB_GBF_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_WRR_ARB_GBF0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ1_ARB_GBF_MASK \ + 0x00000038 /* WRR_REQ1_ARB_GBF[5..3] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ1_ARB_GBF_SHFT 3 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ0_ARB_GBF_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_WRR_ARB_GBF0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ0_ARB_GBF_MASK \ + 0x00000007 /* WRR_REQ0_ARB_GBF[2..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ0_ARB_GBF_SHFT 0 + +/* +* ---WPDMA_PAUSE_RX_Q_TH10 (0x7C025000 + 0x260)--- +* RX_DMAD_TH0[11..0] - (RW) RX Ring0 DMAD threshold to pause PP sending packet +* to RX FIFO +* pause_rx_q = (available RX DMAD counts) < +* RESERVED12[15..12] - (RO) Reserved bits +* RX_DMAD_TH1[27..16] - (RW) RX Ring1 DMAD threshold to pause PP sending packet +* to RX FIFO +* pause_rx_q = (available RX DMAD counts) < +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH10_RX_DMAD_TH1_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH10_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH10_RX_DMAD_TH1_MASK \ + 0x0FFF0000 /* RX_DMAD_TH1[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH10_RX_DMAD_TH1_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH10_RX_DMAD_TH0_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH10_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH10_RX_DMAD_TH0_MASK \ + 0x00000FFF /* RX_DMAD_TH0[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH10_RX_DMAD_TH0_SHFT 0 + +/* +* ---WPDMA_PAUSE_RX_Q_TH32 (0x7C025000 + 0x264)--- +* RX_DMAD_TH2[11..0] - (RW) RX Ring2 DMAD threshold to pause PP sending packet +* to RX FIFO +* pause_rx_q = (available RX DMAD counts) < +* RESERVED12[15..12] - (RO) Reserved bits +* RX_DMAD_TH3[27..16] - (RW) RX Ring3 DMAD threshold to pause PP sending packet +* to RX FIFO +* pause_rx_q = (available RX DMAD counts) < +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH32_RX_DMAD_TH3_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH32_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH32_RX_DMAD_TH3_MASK \ + 0x0FFF0000 /* RX_DMAD_TH3[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH32_RX_DMAD_TH3_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH32_RX_DMAD_TH2_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH32_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH32_RX_DMAD_TH2_MASK \ + 0x00000FFF /* RX_DMAD_TH2[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH32_RX_DMAD_TH2_SHFT 0 + +/* +* ---WPDMA_PAUSE_RX_Q_TH54 (0x7C025000 + 0x268)--- +* RX_DMAD_TH4[11..0] - (RW) RX Ring4 DMAD threshold to pause PP sending packet +* to RX FIFO +* pause_rx_q = (available RX DMAD counts) < +* RESERVED12[15..12] - (RO) Reserved bits +* RX_DMAD_TH5[27..16] - (RW) RX Ring5 DMAD threshold to pause PP sending packet +* to RX FIFO +* pause_rx_q = (available RX DMAD counts) < +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH54_RX_DMAD_TH5_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH54_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH54_RX_DMAD_TH5_MASK \ + 0x0FFF0000 /* RX_DMAD_TH5[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH54_RX_DMAD_TH5_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH54_RX_DMAD_TH4_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH54_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH54_RX_DMAD_TH4_MASK \ + 0x00000FFF /* RX_DMAD_TH4[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH54_RX_DMAD_TH4_SHFT 0 + +/* +* ---WPDMA_PAUSE_RX_Q_TH76 (0x7C025000 + 0x26C)--- +* RX_DMAD_TH6[11..0] - (RW) RX Ring6 DMAD threshold to pause PP sending packet +* to RX FIFO +* pause_rx_q = (available RX DMAD counts) < +* RESERVED12[15..12] - (RO) Reserved bits +* RX_DMAD_TH7[27..16] - (RW) RX Ring7 DMAD threshold to pause PP sending packet +* to RX FIFO +* pause_rx_q = (available RX DMAD counts) < +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH76_RX_DMAD_TH7_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH76_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH76_RX_DMAD_TH7_MASK \ + 0x0FFF0000 /* RX_DMAD_TH7[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH76_RX_DMAD_TH7_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH76_RX_DMAD_TH6_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH76_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH76_RX_DMAD_TH6_MASK \ + 0x00000FFF /* RX_DMAD_TH6[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH76_RX_DMAD_TH6_SHFT 0 + +/* +* ---WPDMA_RST_DRX_PTR (0x7C025000 + 0x280)--- +* RST_DRX_IDX0[0] - (WO) Write 1 to reset to RX_DMARX_IDX0 to 0 +* RST_DRX_IDX1[1] - (WO) Write 1 to reset to RX_DMARX_IDX1 to 0 +* RST_DRX_IDX2[2] - (WO) Write 1 to reset to RX_DMARX_IDX2 to 0 +* RST_DRX_IDX3[3] - (WO) Write 1 to reset to RX_DMARX_IDX3 to 0 +* RESERVED[31..4] - (WO) Reserved +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DRX_PTR_RST_DRX_IDX3_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DRX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DRX_PTR_RST_DRX_IDX3_MASK \ + 0x00000008 /* RST_DRX_IDX3[3] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DRX_PTR_RST_DRX_IDX3_SHFT 3 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DRX_PTR_RST_DRX_IDX2_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DRX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DRX_PTR_RST_DRX_IDX2_MASK \ + 0x00000004 /* RST_DRX_IDX2[2] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DRX_PTR_RST_DRX_IDX2_SHFT 2 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DRX_PTR_RST_DRX_IDX1_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DRX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DRX_PTR_RST_DRX_IDX1_MASK \ + 0x00000002 /* RST_DRX_IDX1[1] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DRX_PTR_RST_DRX_IDX1_SHFT 1 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DRX_PTR_RST_DRX_IDX0_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DRX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DRX_PTR_RST_DRX_IDX0_MASK \ + 0x00000001 /* RST_DRX_IDX0[0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DRX_PTR_RST_DRX_IDX0_SHFT 0 + +/* +* ---WPDMA_INFO (0x7C025000 + 0x284)--- +* TX_RING_NUMBER[7..0] - (RO) TX_RING_NUMBER +* RX_RING_NUMBER[15..8] - (RO) RX_RING_NUMBER +* BASE_PTR_WIDTH[23..16] - (RO) {2'h0, 6'd32-'BASE_PTR_WIDTH[5:0]} +* INDEX_WIDTH[27..24] - (RO) RING_INDEX_WIDTH +* PDMA_PREFETCH_SRAM_SIZE[30..28] - (RO) PDMA prefetch sram size{3'h0 : 128 +* byte, 3'h1 : 256 byte, 3'h2 : 512 byte, 3'h3 : 1KB, 3'h4 : 2KB, 3'h5 : 4KB, +* 3'h6 : 8KB, 3'h7 : reserved}, be noticed that prefetch sram is shared outside +* with other DMAs, please check all DMAs' total prefetch ring number and max_cnt +* for each prefetch ring to make sure that total size of all configured prefetch +* dmad of all DMAs' prefetch ring should be less than PDMA_PREFETCH_SRAM_SIZE +* WFDMA_PDA_EXIST[31] - (RO) Only cpu_dma1 will support pda functions for +* firmware download and wfdma_pda_top resides in between cpu_dma0 and cpu_dma1! +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_WFDMA_PDA_EXIST_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_INFO_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_WFDMA_PDA_EXIST_MASK \ + 0x80000000 /* WFDMA_PDA_EXIST[31] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_WFDMA_PDA_EXIST_SHFT 31 +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_PDMA_PREFETCH_SRAM_SIZE_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_INFO_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_PDMA_PREFETCH_SRAM_SIZE_MASK \ + 0x70000000 /* PDMA_PREFETCH_SRAM_SIZE[30..28] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_PDMA_PREFETCH_SRAM_SIZE_SHFT 28 +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_INDEX_WIDTH_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_INFO_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_INDEX_WIDTH_MASK \ + 0x0F000000 /* INDEX_WIDTH[27..24] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_INDEX_WIDTH_SHFT 24 +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_BASE_PTR_WIDTH_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_INFO_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_BASE_PTR_WIDTH_MASK \ + 0x00FF0000 /* BASE_PTR_WIDTH[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_BASE_PTR_WIDTH_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_RX_RING_NUMBER_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_INFO_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_RX_RING_NUMBER_MASK \ + 0x0000FF00 /* RX_RING_NUMBER[15..8] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_RX_RING_NUMBER_SHFT 8 +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_TX_RING_NUMBER_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_INFO_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_TX_RING_NUMBER_MASK \ + 0x000000FF /* TX_RING_NUMBER[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_TX_RING_NUMBER_SHFT 0 + +/* +* ---WPDMA_INFO_EXT (0x7C025000 + 0x288)--- +* TX_EVENT_RING_NUMBER[7..0] - (RO) When TX_EVENT_RING_NUMBER equal 8'h0, it +* means that this DMA doesn't support dual TX fifo, thus in default it only +* support TX_RING_NUMBER of TX rings !! +* But when TX_EVENT_RING_NUMBER NOT equal 8'h0, this dma is configured as dual +* TX fifo and TX_RING[16+TX_EVENT_RING_NUM-1:16] are for getting HOST EVENT +* packet from HOST to WX_CPU!! +* TX_DMAD_RING_NUMBER[15..8] - (RO) When TX_EVENT_RING_NUMBER not equal to 8'h0, +* it means that this DMA support dual TX fifo and TX +* ring[TX_DMAD_RING_NUMBER-1:0] are for getting TXD from HOST to UMAC!! +* RESERVED[30..16] - (RO) Reserved +* TX_DMASHDL_EXIST[31] - (RO) TX_DMASHDL_EXIST +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_EXT_TX_DMASHDL_EXIST_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_INFO_EXT_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_EXT_TX_DMASHDL_EXIST_MASK \ + 0x80000000 /* TX_DMASHDL_EXIST[31] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_EXT_TX_DMASHDL_EXIST_SHFT 31 +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_EXT_TX_DMAD_RING_NUMBER_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_INFO_EXT_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_EXT_TX_DMAD_RING_NUMBER_MASK \ + 0x0000FF00 /* TX_DMAD_RING_NUMBER[15..8] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_EXT_TX_DMAD_RING_NUMBER_SHFT 8 +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_EXT_TX_EVENT_RING_NUMBER_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_INFO_EXT_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_EXT_TX_EVENT_RING_NUMBER_MASK \ + 0x000000FF /* TX_EVENT_RING_NUMBER[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_EXT_TX_EVENT_RING_NUMBER_SHFT 0 + +/* +* ---WPDMA_INT_RX_PRI_SEL (0x7C025000 + 0x298)--- +* WPDMA_INT_RX_RING0_PRI_SEL[0] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_RX_RING1_PRI_SEL[1] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* RESERVED2[2] - (RO) Reserved bits +* WPDMA_INT_RX_RING3_PRI_SEL[3] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* RESERVED4[31..4] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING3_PRI_SEL_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_RX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING3_PRI_SEL_MASK \ + 0x00000008 /* WPDMA_INT_RX_RING3_PRI_SEL[3] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING3_PRI_SEL_SHFT \ + 3 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING1_PRI_SEL_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_RX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING1_PRI_SEL_MASK \ + 0x00000002 /* WPDMA_INT_RX_RING1_PRI_SEL[1] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING1_PRI_SEL_SHFT \ + 1 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING0_PRI_SEL_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_RX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING0_PRI_SEL_MASK \ + 0x00000001 /* WPDMA_INT_RX_RING0_PRI_SEL[0] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING0_PRI_SEL_SHFT \ + 0 + +/* +* ---WPDMA_INT_TX_PRI_SEL (0x7C025000 + 0x29C)--- +* WPDMA_INT_TX_RING0_PRI_SEL[0] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING1_PRI_SEL[1] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING2_PRI_SEL[2] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING3_PRI_SEL[3] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING4_PRI_SEL[4] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING5_PRI_SEL[5] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING6_PRI_SEL[6] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING7_PRI_SEL[7] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING8_PRI_SEL[8] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING9_PRI_SEL[9] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING10_PRI_SEL[10] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING11_PRI_SEL[11] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING12_PRI_SEL[12] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING13_PRI_SEL[13] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING14_PRI_SEL[14] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* RESERVED15[15] - (RO) Reserved bits +* WPDMA_INT_TX_RING16_PRI_SEL[16] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING17_PRI_SEL[17] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* RESERVED18[31..18] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING17_PRI_SEL_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING17_PRI_SEL_MASK \ + 0x00020000 /* WPDMA_INT_TX_RING17_PRI_SEL[17] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING17_PRI_SEL_SHFT \ + 17 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING16_PRI_SEL_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING16_PRI_SEL_MASK \ + 0x00010000 /* WPDMA_INT_TX_RING16_PRI_SEL[16] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING16_PRI_SEL_SHFT \ + 16 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING14_PRI_SEL_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING14_PRI_SEL_MASK \ + 0x00004000 /* WPDMA_INT_TX_RING14_PRI_SEL[14] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING14_PRI_SEL_SHFT \ + 14 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING13_PRI_SEL_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING13_PRI_SEL_MASK \ + 0x00002000 /* WPDMA_INT_TX_RING13_PRI_SEL[13] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING13_PRI_SEL_SHFT \ + 13 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING12_PRI_SEL_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING12_PRI_SEL_MASK \ + 0x00001000 /* WPDMA_INT_TX_RING12_PRI_SEL[12] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING12_PRI_SEL_SHFT \ + 12 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING11_PRI_SEL_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING11_PRI_SEL_MASK \ + 0x00000800 /* WPDMA_INT_TX_RING11_PRI_SEL[11] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING11_PRI_SEL_SHFT \ + 11 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING10_PRI_SEL_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING10_PRI_SEL_MASK \ + 0x00000400 /* WPDMA_INT_TX_RING10_PRI_SEL[10] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING10_PRI_SEL_SHFT \ + 10 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING9_PRI_SEL_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING9_PRI_SEL_MASK \ + 0x00000200 /* WPDMA_INT_TX_RING9_PRI_SEL[9] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING9_PRI_SEL_SHFT \ + 9 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING8_PRI_SEL_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING8_PRI_SEL_MASK \ + 0x00000100 /* WPDMA_INT_TX_RING8_PRI_SEL[8] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING8_PRI_SEL_SHFT \ + 8 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING7_PRI_SEL_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING7_PRI_SEL_MASK \ + 0x00000080 /* WPDMA_INT_TX_RING7_PRI_SEL[7] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING7_PRI_SEL_SHFT \ + 7 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING6_PRI_SEL_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING6_PRI_SEL_MASK \ + 0x00000040 /* WPDMA_INT_TX_RING6_PRI_SEL[6] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING6_PRI_SEL_SHFT \ + 6 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING5_PRI_SEL_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING5_PRI_SEL_MASK \ + 0x00000020 /* WPDMA_INT_TX_RING5_PRI_SEL[5] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING5_PRI_SEL_SHFT \ + 5 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING4_PRI_SEL_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING4_PRI_SEL_MASK \ + 0x00000010 /* WPDMA_INT_TX_RING4_PRI_SEL[4] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING4_PRI_SEL_SHFT \ + 4 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING3_PRI_SEL_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING3_PRI_SEL_MASK \ + 0x00000008 /* WPDMA_INT_TX_RING3_PRI_SEL[3] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING3_PRI_SEL_SHFT \ + 3 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING2_PRI_SEL_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING2_PRI_SEL_MASK \ + 0x00000004 /* WPDMA_INT_TX_RING2_PRI_SEL[2] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING2_PRI_SEL_SHFT \ + 2 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING1_PRI_SEL_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING1_PRI_SEL_MASK \ + 0x00000002 /* WPDMA_INT_TX_RING1_PRI_SEL[1] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING1_PRI_SEL_SHFT \ + 1 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING0_PRI_SEL_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING0_PRI_SEL_MASK \ + 0x00000001 /* WPDMA_INT_TX_RING0_PRI_SEL[0] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING0_PRI_SEL_SHFT \ + 0 + +/* +* ---WPDMA_TX_DBG0 (0x7C025000 + 0x2A0)--- +* WPDMA_TX_DBG0[31..0] - (RO) xxx +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_DBG0_WPDMA_TX_DBG0_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_DBG0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_DBG0_WPDMA_TX_DBG0_MASK \ + 0xFFFFFFFF /* WPDMA_TX_DBG0[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_DBG0_WPDMA_TX_DBG0_SHFT 0 + +/* +* ---WPDMA_TX_DBG1 (0x7C025000 + 0x2A4)--- +* WPDMA_TX_DBG1[31..0] - (RO) xxx +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_DBG1_WPDMA_TX_DBG1_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_DBG1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_DBG1_WPDMA_TX_DBG1_MASK \ + 0xFFFFFFFF /* WPDMA_TX_DBG1[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_DBG1_WPDMA_TX_DBG1_SHFT 0 + +/* +* ---WPDMA_RX_DBG0 (0x7C025000 + 0x2A8)--- +* WPDMA_RX_DBG0[31..0] - (RO) xxx +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_DBG0_WPDMA_RX_DBG0_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_DBG0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_DBG0_WPDMA_RX_DBG0_MASK \ + 0xFFFFFFFF /* WPDMA_RX_DBG0[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_DBG0_WPDMA_RX_DBG0_SHFT 0 + +/* +* ---WPDMA_RX_DBG1 (0x7C025000 + 0x2AC)--- +* WPDMA_RX_DBG1[31..0] - (RO) xxx +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_DBG1_WPDMA_RX_DBG1_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_DBG1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_DBG1_WPDMA_RX_DBG1_MASK \ + 0xFFFFFFFF /* WPDMA_RX_DBG1[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_DBG1_WPDMA_RX_DBG1_SHFT 0 + +/* +* ---WPDMA_GLO_CFG_EXT0 (0x7C025000 + 0x2B0)--- +* CSR_MAX_PREFETCH_CNT[1..0] - (RW) Max. dmad count per prefet request, 2'b00 : +* 1 entry, 2'b01 : 2 entries, 2'b10 : 4 entries, 2'b11 : 8 entries, Note : 1 +* entry(dmad size) is 16 bytes = 4 DWs = 2 QWs +* CSR_MEM_BST_SIZE[3..2] - (RW) Max. burst size per sram request. 00 : 16-byte, +* 01 : 32-byte, 10 : 64-byte, 11 : 128-byte +* CSR_MEM_ARB_LOCK_EN[4] - (RW) 1'b1 : Lock round-robin sram access arbiter +* until whole long burst request from dma FSM finish, 1'b0 : no lock sram +* arbiter, grant will be change per request due to round-robin +* CSR_RX_DMA_WBQ_EN[5] - (RW) 1'b1 : RX dmad will be posted-write and deal with +* next received packet immediately, 1'b0 : RX dmad will be written back +* immediately after received packet has been sent to host memory +* CSR_TX_DMASHDL_ENABLE[6] - (RW) 1'b1 : request DMASHDL before TX to select +* next TX ring, 1'b0 : disable DMASHDL and use round-robin arbiter to select +* next TX ring +* CSR_BRESP_ERROR_BYPASS_EN[7] - (RW) 1'b1 : Bypass AXI error bresp as a normal +* response. 1'b0 : Will not assert bready to error bresp(00 : OKAY, 01 : EXOKAY, +* 10 : SLVERR, 11 : DECERR) +* CSR_AXI_SLEEP_MODE[9..8] - (RW) 2'b00 : no sleep, normal TX/RX, 2b1* : sleep +* after AXI request, 2'b11 : force assertion of wvalid, rready and bready to +* finish all committed data phases, then sleep immediately +* RESERVED10[14..10] - (RO) Reserved bits +* CSR_Q_STATUS_IDX_BKRS_EN[15] - (RW) backup/restore enable bit for +* q_status(payload, prefetch and dispatch) index +* CSR_AXI_BST_SIZE[17..16] - (RW) AXI busrt length, 00 : 128-byte, 01 : 64-byte, +* 10 : 32-byte, 11 : 16-byte +* CSR_RX_DMAD_WB_MIRROR_EN[18] - (RW) Set to 1'b1 to split RX DMAD write-back +* into two AXI request which carries ddone bit (DW1[31], DW1[15]) for each iif +* external AXI dispatcher exist and need to do push-write behavior to make sure +* all datas from two PCIE have arrived HOST memory +* CSR_AXI_FAKE[19] - (RW) If set to 1'b1, all requests from DMA engine will not +* be sent to AXI INFRA, this try to fix AXI bus hang issue temporarily! +* CSR_DMAD_PREFETCH_THRESHOLD[21..20] - (RW) trigger dmad prefetch when +* available dmad cnt >= {1(2'b00), 2(2'b01), 4(2'b10), 8(2'b11)} +* CSR_BID_CHECK_BYPASS_EN[22] - (RW) If set to 1'b0, axi master will check +* matching between awid and bid before assert bready, if set to 1'b1, it will +* bypass this checking and assert bready for each bvalid even though bid doesn't +* match any awid ever issued! +* CSR_RX_INFO_WB_EN[23] - (RW) If set to 1'b0, only DW0 and DW1 will be written +* back into memory after received RX packet process finished, this will save bus +* bandwidth a little because DW2 and DW3 are useless for FW +* CSR_AXI_OUTSTANDING_NUM[27..24] - (RW) decide max. outstanding AXI requests, +* common for AXI read or write! +* CSR_AXI_ARUSER_LOCK_EN[28] - (RW) on/off customized lock ctrl design thru AXI +* aruser signal, this will influence TX QoS ctrl +* CSR_AXI_AWUSER_LOCK_EN[29] - (RW) on/off customized lock ctrl design thru AXI +* awuser signal when RX dmad write-back have to be separately written into +* memory due to external dispatcher exists! +* CSR_AXI_LOCK_EN[30] - (RW) Global lock enable to on/off AXI spec. lock(axlock) +* behavior and also will on/off customized lock ctrl design thru AXI awuser +signal +* CSR_AXI_CLKGATE_BYP[31] - (RW) To bypass functional CG enable which incduced +* from coding style for DC inserted CG cell in all AXI read/write master design +module +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_CLKGATE_BYP_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_CLKGATE_BYP_MASK \ + 0x80000000 /* CSR_AXI_CLKGATE_BYP[31] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_CLKGATE_BYP_SHFT 31 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_LOCK_EN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_LOCK_EN_MASK \ + 0x40000000 /* CSR_AXI_LOCK_EN[30] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_LOCK_EN_SHFT 30 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_AWUSER_LOCK_EN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_AWUSER_LOCK_EN_MASK \ + 0x20000000 /* CSR_AXI_AWUSER_LOCK_EN[29] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_AWUSER_LOCK_EN_SHFT 29 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_ARUSER_LOCK_EN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_ARUSER_LOCK_EN_MASK \ + 0x10000000 /* CSR_AXI_ARUSER_LOCK_EN[28] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_ARUSER_LOCK_EN_SHFT 28 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_OUTSTANDING_NUM_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_OUTSTANDING_NUM_MASK \ + 0x0F000000 /* CSR_AXI_OUTSTANDING_NUM[27..24] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_OUTSTANDING_NUM_SHFT 24 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_RX_INFO_WB_EN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_RX_INFO_WB_EN_MASK \ + 0x00800000 /* CSR_RX_INFO_WB_EN[23] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_RX_INFO_WB_EN_SHFT 23 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_BID_CHECK_BYPASS_EN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_BID_CHECK_BYPASS_EN_MASK \ + 0x00400000 /* CSR_BID_CHECK_BYPASS_EN[22] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_BID_CHECK_BYPASS_EN_SHFT 22 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_DMAD_PREFETCH_THRESHOLD_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_DMAD_PREFETCH_THRESHOLD_MASK \ + 0x00300000 /* CSR_DMAD_PREFETCH_THRESHOLD[21..20] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_DMAD_PREFETCH_THRESHOLD_SHFT \ + 20 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_FAKE_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_FAKE_MASK \ + 0x00080000 /* CSR_AXI_FAKE[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_FAKE_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_RX_DMAD_WB_MIRROR_EN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_RX_DMAD_WB_MIRROR_EN_MASK \ + 0x00040000 /* CSR_RX_DMAD_WB_MIRROR_EN[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_RX_DMAD_WB_MIRROR_EN_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_BST_SIZE_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_BST_SIZE_MASK \ + 0x00030000 /* CSR_AXI_BST_SIZE[17..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_BST_SIZE_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_Q_STATUS_IDX_BKRS_EN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_Q_STATUS_IDX_BKRS_EN_MASK \ + 0x00008000 /* CSR_Q_STATUS_IDX_BKRS_EN[15] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_Q_STATUS_IDX_BKRS_EN_SHFT 15 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_SLEEP_MODE_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_SLEEP_MODE_MASK \ + 0x00000300 /* CSR_AXI_SLEEP_MODE[9..8] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_SLEEP_MODE_SHFT 8 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_BRESP_ERROR_BYPASS_EN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_BRESP_ERROR_BYPASS_EN_MASK \ + 0x00000080 /* CSR_BRESP_ERROR_BYPASS_EN[7] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_BRESP_ERROR_BYPASS_EN_SHFT 7 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_TX_DMASHDL_ENABLE_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_TX_DMASHDL_ENABLE_MASK \ + 0x00000040 /* CSR_TX_DMASHDL_ENABLE[6] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_TX_DMASHDL_ENABLE_SHFT 6 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_RX_DMA_WBQ_EN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_RX_DMA_WBQ_EN_MASK \ + 0x00000020 /* CSR_RX_DMA_WBQ_EN[5] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_RX_DMA_WBQ_EN_SHFT 5 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_MEM_ARB_LOCK_EN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_MEM_ARB_LOCK_EN_MASK \ + 0x00000010 /* CSR_MEM_ARB_LOCK_EN[4] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_MEM_ARB_LOCK_EN_SHFT 4 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_MEM_BST_SIZE_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_MEM_BST_SIZE_MASK \ + 0x0000000C /* CSR_MEM_BST_SIZE[3..2] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_MEM_BST_SIZE_SHFT 2 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_MAX_PREFETCH_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_MAX_PREFETCH_CNT_MASK \ + 0x00000003 /* CSR_MAX_PREFETCH_CNT[1..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_MAX_PREFETCH_CNT_SHFT 0 + +/* +* ---WPDMA_GLO_CFG_EXT1 (0x7C025000 + 0x2B4)--- +* CSR_TXFIFO0_RDY_THRESHOLD[7..0] - (RW) xxx +* CSR_TXFIFO1_RDY_THRESHOLD[15..8] - (RW) xxx +* CSR_TX_DISP_ARB_SCHEDULED_ACCESS_TIMER[23..16] - (RW) timer setting for +* SCHEDULED_ACCESS_TIME_ARB of csr_tx_disp_arb_mode +* CSR_TX_DISP_ARB_MODE[25..24] - (RW) 00 : FAIR_ARB, 01 : FIX_ARB, 10 : +* UNBALANCED_ARB, 11 : SCHEDULED_ACCESS_TIME_ARB +* CSR_FWDL_FLOW_CTRL_BYASS_EN[26] - (RW) To disable firmware download TX flow +* control of TX dma(host_dma1) when firmare download of RX dma(mcu_dma1) is in +* firmware download polling mode!! Remember to set to 1'b0 when firmware +* download ring is set back to normal ring usage which should be in flow control +* for correct behavior!! +* CSR_FWDL_FLOW_CTRL_BYASS_LS_QSEL_EN[27] - (RW) select firmware download TX +* ring(LSB/MSB ring) to bypass TX flow control when firmare download RX +* ring(LSB/MSB ring) of RX dma(mcu_dma1) is in firmware download polling mode!! +* RESERVED[31..28] - (RW) reserved +*/ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_CSR_FWDL_FLOW_CTRL_BYASS_LS_QSEL_EN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_CSR_FWDL_FLOW_CTRL_BYASS_LS_QSEL_EN_MASK \ + 0x08000000 /* CSR_FWDL_FLOW_CTRL_BYASS_LS_QSEL_EN[27] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_CSR_FWDL_FLOW_CTRL_BYASS_LS_QSEL_EN_SHFT \ + 27 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_CSR_FWDL_FLOW_CTRL_BYASS_EN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_CSR_FWDL_FLOW_CTRL_BYASS_EN_MASK \ + 0x04000000 /* CSR_FWDL_FLOW_CTRL_BYASS_EN[26] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_CSR_FWDL_FLOW_CTRL_BYASS_EN_SHFT \ + 26 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_CSR_TX_DISP_ARB_MODE_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_CSR_TX_DISP_ARB_MODE_MASK \ + 0x03000000 /* CSR_TX_DISP_ARB_MODE[25..24] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_CSR_TX_DISP_ARB_MODE_SHFT 24 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_CSR_TX_DISP_ARB_SCHEDULED_ACCESS_TIMER_AD\ +DR \ +WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_CSR_TX_DISP_ARB_SCHEDULED_ACCESS_TIMER_MA\ +SK \ +0x00FF0000 /* CSR_TX_DISP_ARB_SCHEDULED_ACCESS_TIMER[23..16] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_CSR_TX_DISP_ARB_SCHEDULED_ACCESS_TIMER_SH\ +FT \ +16 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_CSR_TXFIFO1_RDY_THRESHOLD_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_CSR_TXFIFO1_RDY_THRESHOLD_MASK \ + 0x0000FF00 /* CSR_TXFIFO1_RDY_THRESHOLD[15..8] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_CSR_TXFIFO1_RDY_THRESHOLD_SHFT 8 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_CSR_TXFIFO0_RDY_THRESHOLD_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_CSR_TXFIFO0_RDY_THRESHOLD_MASK \ + 0x000000FF /* CSR_TXFIFO0_RDY_THRESHOLD[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_CSR_TXFIFO0_RDY_THRESHOLD_SHFT 0 + +/* +* ---WPDMA_AXI_MST_DBG0 (0x7C025000 + 0x2B8)--- +* M0_AXI_RRESP_ERROR_RRESP[1..0] - (W1C) tx_pfet AXI rresp +* RESERVED2[3..2] - (RO) Reserved bits +* M0_AXI_RRESP_ERROR_RID[7..4] - (W1C) tx_pfet AXI rid +* M1_AXI_RRESP_ERROR_RRESP[9..8] - (W1C) pf_dfet_rx AXI rresp +* RESERVED10[11..10] - (RO) Reserved bits +* M1_AXI_RRESP_ERROR_RID[15..12] - (W1C) pf_dfet_rx AXI rid +* M2_AXI_RRESP_ERROR_RRESP[17..16] - (W1C) pf_dfet_tx AXI rresp +* RESERVED18[19..18] - (RO) Reserved bits +* M2_AXI_RRESP_ERROR_RID[23..20] - (W1C) pf_dfet_tx AXI rid +* M0_AXI_RRESP_ERROR[24] - (W1C) tx_pfet_tx AXI rresp_error +* M1_AXI_RRESP_ERROR[25] - (W1C) pf_dfet_rx AXI rresp_error +* M2_AXI_RRESP_ERROR[26] - (W1C) pf_dfet_tx AXI rresp_error +* RESERVED27[31..27] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG0_M2_AXI_RRESP_ERROR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG0_M2_AXI_RRESP_ERROR_MASK \ + 0x04000000 /* M2_AXI_RRESP_ERROR[26] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG0_M2_AXI_RRESP_ERROR_SHFT 26 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG0_M1_AXI_RRESP_ERROR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG0_M1_AXI_RRESP_ERROR_MASK \ + 0x02000000 /* M1_AXI_RRESP_ERROR[25] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG0_M1_AXI_RRESP_ERROR_SHFT 25 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG0_M0_AXI_RRESP_ERROR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG0_M0_AXI_RRESP_ERROR_MASK \ + 0x01000000 /* M0_AXI_RRESP_ERROR[24] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG0_M0_AXI_RRESP_ERROR_SHFT 24 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG0_M2_AXI_RRESP_ERROR_RID_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG0_M2_AXI_RRESP_ERROR_RID_MASK \ + 0x00F00000 /* M2_AXI_RRESP_ERROR_RID[23..20] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG0_M2_AXI_RRESP_ERROR_RID_SHFT 20 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG0_M2_AXI_RRESP_ERROR_RRESP_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG0_M2_AXI_RRESP_ERROR_RRESP_MASK \ + 0x00030000 /* M2_AXI_RRESP_ERROR_RRESP[17..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG0_M2_AXI_RRESP_ERROR_RRESP_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG0_M1_AXI_RRESP_ERROR_RID_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG0_M1_AXI_RRESP_ERROR_RID_MASK \ + 0x0000F000 /* M1_AXI_RRESP_ERROR_RID[15..12] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG0_M1_AXI_RRESP_ERROR_RID_SHFT 12 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG0_M1_AXI_RRESP_ERROR_RRESP_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG0_M1_AXI_RRESP_ERROR_RRESP_MASK \ + 0x00000300 /* M1_AXI_RRESP_ERROR_RRESP[9..8] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG0_M1_AXI_RRESP_ERROR_RRESP_SHFT 8 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG0_M0_AXI_RRESP_ERROR_RID_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG0_M0_AXI_RRESP_ERROR_RID_MASK \ + 0x000000F0 /* M0_AXI_RRESP_ERROR_RID[7..4] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG0_M0_AXI_RRESP_ERROR_RID_SHFT 4 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG0_M0_AXI_RRESP_ERROR_RRESP_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG0_M0_AXI_RRESP_ERROR_RRESP_MASK \ + 0x00000003 /* M0_AXI_RRESP_ERROR_RRESP[1..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG0_M0_AXI_RRESP_ERROR_RRESP_SHFT 0 + +/* +* ---WPDMA_AXI_MST_DBG1 (0x7C025000 + 0x2BC)--- +* M0_AXI_BRESP_ERROR_BRESP[1..0] - (W1C) rx_pfet AXI bresp +* RESERVED2[3..2] - (RO) Reserved bits +* M0_AXI_BRESP_ERROR_RID[7..4] - (W1C) rx_pfet AXI bid +* M1_AXI_BRESP_ERROR_BRESP[9..8] - (W1C) wb_dfet_rx AXI bresp +* RESERVED10[11..10] - (RO) Reserved bits +* M1_AXI_BRESP_ERROR_RID[15..12] - (W1C) wb_dfet_rx AXI bid +* M2_AXI_BRESP_ERROR_BRESP[17..16] - (W1C) wb_dfet_tx AXI bresp +* RESERVED18[19..18] - (RO) Reserved bits +* M2_AXI_BRESP_ERROR_RID[23..20] - (W1C) wb_dfet_tx AXI bid +* M0_AXI_BRESP_ERROR[24] - (W1C) tx_pfet_tx AXI bresp_error +* M1_AXI_BRESP_ERROR[25] - (W1C) pf_dfet_rx AXI bresp_error +* M2_AXI_BRESP_ERROR[26] - (W1C) pf_dfet_tx AXI bresp_error +* RESERVED27[31..27] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG1_M2_AXI_BRESP_ERROR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG1_M2_AXI_BRESP_ERROR_MASK \ + 0x04000000 /* M2_AXI_BRESP_ERROR[26] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG1_M2_AXI_BRESP_ERROR_SHFT 26 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG1_M1_AXI_BRESP_ERROR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG1_M1_AXI_BRESP_ERROR_MASK \ + 0x02000000 /* M1_AXI_BRESP_ERROR[25] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG1_M1_AXI_BRESP_ERROR_SHFT 25 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG1_M0_AXI_BRESP_ERROR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG1_M0_AXI_BRESP_ERROR_MASK \ + 0x01000000 /* M0_AXI_BRESP_ERROR[24] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG1_M0_AXI_BRESP_ERROR_SHFT 24 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG1_M2_AXI_BRESP_ERROR_RID_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG1_M2_AXI_BRESP_ERROR_RID_MASK \ + 0x00F00000 /* M2_AXI_BRESP_ERROR_RID[23..20] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG1_M2_AXI_BRESP_ERROR_RID_SHFT 20 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG1_M2_AXI_BRESP_ERROR_BRESP_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG1_M2_AXI_BRESP_ERROR_BRESP_MASK \ + 0x00030000 /* M2_AXI_BRESP_ERROR_BRESP[17..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG1_M2_AXI_BRESP_ERROR_BRESP_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG1_M1_AXI_BRESP_ERROR_RID_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG1_M1_AXI_BRESP_ERROR_RID_MASK \ + 0x0000F000 /* M1_AXI_BRESP_ERROR_RID[15..12] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG1_M1_AXI_BRESP_ERROR_RID_SHFT 12 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG1_M1_AXI_BRESP_ERROR_BRESP_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG1_M1_AXI_BRESP_ERROR_BRESP_MASK \ + 0x00000300 /* M1_AXI_BRESP_ERROR_BRESP[9..8] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG1_M1_AXI_BRESP_ERROR_BRESP_SHFT 8 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG1_M0_AXI_BRESP_ERROR_RID_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG1_M0_AXI_BRESP_ERROR_RID_MASK \ + 0x000000F0 /* M0_AXI_BRESP_ERROR_RID[7..4] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG1_M0_AXI_BRESP_ERROR_RID_SHFT 4 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG1_M0_AXI_BRESP_ERROR_BRESP_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG1_M0_AXI_BRESP_ERROR_BRESP_MASK \ + 0x00000003 /* M0_AXI_BRESP_ERROR_BRESP[1..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_DBG1_M0_AXI_BRESP_ERROR_BRESP_SHFT 0 + +/* +* ---WPDMA_TX_QOS_LMT_CFG0 (0x7C025000 + 0x2C0)--- +* CSR_TX_PLD_AXI_LIMITER_REQ[2..0] - (RW) QoS CR, Limiter Enable for packet +* traffice of type TX_PLD +* CSR_TX_PLD_AXI_LIMITER_EN_REQ[3] - (RW) QoS CR, Limiter Enable for packet +* traffice of type TX_PLD +* CSR_TX_PLD_AXI_LIMITER_PKT[6..4] - (RW) QoS CR, Limiter Enable for packet +* traffice of type TX_PLD +* CSR_TX_PLD_AXI_LIMITER_EN_PKT[7] - (RW) QoS CR, Limiter Enable for packet +* traffice of type TX_PLD +* CSR_RX_PLD_AXI_LIMITER_REQ[10..8] - (RW) QoS CR, Limiter Enable for request +* traffice of type RX_PLD +* CSR_RX_PLD_AXI_LIMITER_EN_REQ[11] - (RW) QoS CR, Limiter Enable for request +* traffice of type RX_PLD +* CSR_RX_PLD_AXI_LIMITER_PKT[14..12] - (RW) QoS CR, Limiter Enable for request +* traffice of type RX_PLD +* CSR_RX_PLD_AXI_LIMITER_EN_PKT[15] - (RW) QoS CR, Limiter Enable for request +* traffice of type RX_PLD +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_EN_PKT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_EN_PKT_MASK \ + 0x00008000 /* CSR_RX_PLD_AXI_LIMITER_EN_PKT[15] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_EN_PKT_SHFT \ + 15 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_PKT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_PKT_MASK \ + 0x00007000 /* CSR_RX_PLD_AXI_LIMITER_PKT[14..12] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_PKT_SHFT \ + 12 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_EN_REQ_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_EN_REQ_MASK \ + 0x00000800 /* CSR_RX_PLD_AXI_LIMITER_EN_REQ[11] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_EN_REQ_SHFT \ + 11 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_REQ_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_REQ_MASK \ + 0x00000700 /* CSR_RX_PLD_AXI_LIMITER_REQ[10..8] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_REQ_SHFT \ + 8 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_AXI_LIMITER_EN_PKT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_AXI_LIMITER_EN_PKT_MASK \ + 0x00000080 /* CSR_TX_PLD_AXI_LIMITER_EN_PKT[7] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_AXI_LIMITER_EN_PKT_SHFT \ + 7 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_AXI_LIMITER_PKT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_AXI_LIMITER_PKT_MASK \ + 0x00000070 /* CSR_TX_PLD_AXI_LIMITER_PKT[6..4] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_AXI_LIMITER_PKT_SHFT \ + 4 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_AXI_LIMITER_EN_REQ_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_AXI_LIMITER_EN_REQ_MASK \ + 0x00000008 /* CSR_TX_PLD_AXI_LIMITER_EN_REQ[3] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_AXI_LIMITER_EN_REQ_SHFT \ + 3 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_AXI_LIMITER_REQ_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_AXI_LIMITER_REQ_MASK \ + 0x00000007 /* CSR_TX_PLD_AXI_LIMITER_REQ[2..0] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_AXI_LIMITER_REQ_SHFT \ + 0 + +/* +* ---WPDMA_TX_QOS_LMT_CFG1 (0x7C025000 + 0x2C4)--- +* CSR_AUX_TX_PLD_AXI_LIMITER_REQ[2..0] - (RW) QoS CR, Limiter value selected by +* PP dynamically +* RESERVED3[3] - (RO) Reserved bits +* CSR_AUX_TX_PLD_AXI_LIMITER_PKT[6..4] - (RW) QoS CR, Limiter value selected by +* PP dynamically +* RESERVED7[7] - (RO) Reserved bits +* CSR_AUX_RX_PLD_AXI_LIMITER_REQ[10..8] - (RW) QoS CR, Limiter value selected by +* PP dynamically +* RESERVED11[11] - (RO) Reserved bits +* CSR_AUX_RX_PLD_AXI_LIMITER_PKT[14..12] - (RW) QoS CR, Limiter value selected +* by PP dynamically +* RESERVED15[31..15] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_RX_PLD_AXI_LIMITER_PKT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG1_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_RX_PLD_AXI_LIMITER_PKT_MASK \ + 0x00007000 /* CSR_AUX_RX_PLD_AXI_LIMITER_PKT[14..12] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_RX_PLD_AXI_LIMITER_PKT_SHFT \ + 12 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_RX_PLD_AXI_LIMITER_REQ_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG1_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_RX_PLD_AXI_LIMITER_REQ_MASK \ + 0x00000700 /* CSR_AUX_RX_PLD_AXI_LIMITER_REQ[10..8] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_RX_PLD_AXI_LIMITER_REQ_SHFT \ + 8 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_TX_PLD_AXI_LIMITER_PKT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG1_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_TX_PLD_AXI_LIMITER_PKT_MASK \ + 0x00000070 /* CSR_AUX_TX_PLD_AXI_LIMITER_PKT[6..4] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_TX_PLD_AXI_LIMITER_PKT_SHFT \ + 4 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_TX_PLD_AXI_LIMITER_REQ_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG1_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_TX_PLD_AXI_LIMITER_REQ_MASK \ + 0x00000007 /* CSR_AUX_TX_PLD_AXI_LIMITER_REQ[2..0] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_TX_PLD_AXI_LIMITER_REQ_SHFT \ + 0 + +/* +* ---WPDMA_TX_QOS_LMT_CFG2 (0x7C025000 + 0x2C8)--- +* CSR_RX_RD_DMAD_AXI_LIMITER_REQ[2..0] - (RW) QoS CR, Limiter Value for packet +* traffice of type RX_RD_DMAD +* CSR_RX_RD_DMAD_AXI_LIMITER_EN_REQ[3] - (RW) QoS CR, Limiter Enable for request +* traffice of type RX_RD_DMAD +* CSR_RX_RD_DMAD_AXI_LIMITER_PKT[6..4] - (RW) QoS CR, Limiter Value for packet +* traffice of type RX_RD_DMAD +* CSR_RX_RD_DMAD_AXI_LIMITER_EN_PKT[7] - (RW) QoS CR, Limiter Enable for packet +* traffice of type RX_RD_DMAD +* CSR_RX_WR_DMAD_AXI_LIMITER_REQ[10..8] - (RW) QoS CR, Limiter Value for packet +* traffice of type RX_WR_DMAD +* CSR_RX_WR_DMAD_AXI_LIMITER_EN_REQ[11] - (RW) QoS CR, Limiter Enable for +* request traffice of type RX_WR_DMAD +* CSR_RX_WR_DMAD_AXI_LIMITER_PKT[14..12] - (RW) QoS CR, Limiter Value for packet +* traffice of type RX_WR_DMAD +* CSR_RX_WR_DMAD_AXI_LIMITER_EN_PKT[15] - (RW) QoS CR, Limiter Enable for packet +* traffice of type RX_WR_DMAD +* CSR_TX_RD_DMAD_AXI_LIMITER_REQ[18..16] - (RW) QoS CR, Limiter Value for packet +* traffice of type TX_RD_DMAD +* CSR_TX_RD_DMAD_AXI_LIMITER_EN_REQ[19] - (RW) QoS CR, Limiter Enable for +* request traffice of type TX_RD_DMAD +* CSR_TX_RD_DMAD_AXI_LIMITER_PKT[22..20] - (RW) QoS CR, Limiter Value for packet +* traffice of type TX_RD_DMAD +* CSR_TX_RD_DMAD_AXI_LIMITER_EN_PKT[23] - (RW) QoS CR, Limiter Enable for packet +* traffice of type TX_RD_DMAD +* CSR_TX_WR_DMAD_AXI_LIMITER_REQ[26..24] - (RW) QoS CR, Limiter Value for packet +* traffice of type TX_WR_DMAD +* CSR_TX_WR_DMAD_AXI_LIMITER_EN_REQ[27] - (RW) QoS CR, Limiter Enable for +* request traffice of type TX_WR_DMAD +* CSR_TX_WR_DMAD_AXI_LIMITER_PKT[30..28] - (RW) QoS CR, Limiter Value for packet +* traffice of type TX_WR_DMAD +* CSR_TX_WR_DMAD_AXI_LIMITER_EN_PKT[31] - (RW) QoS CR, Limiter Enable for packet +* traffice of type TX_WR_DMAD +*/ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_EN_PKT_ADDR\ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_EN_PKT_MASK\ +0x80000000 /* CSR_TX_WR_DMAD_AXI_LIMITER_EN_PKT[31] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_EN_PKT_SHFT\ +31 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_PKT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_PKT_MASK \ + 0x70000000 /* CSR_TX_WR_DMAD_AXI_LIMITER_PKT[30..28] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_PKT_SHFT \ + 28 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_EN_REQ_ADDR\ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_EN_REQ_MASK\ +0x08000000 /* CSR_TX_WR_DMAD_AXI_LIMITER_EN_REQ[27] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_EN_REQ_SHFT\ +27 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_REQ_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_REQ_MASK \ + 0x07000000 /* CSR_TX_WR_DMAD_AXI_LIMITER_REQ[26..24] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_REQ_SHFT \ + 24 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_EN_PKT_ADDR\ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_EN_PKT_MASK\ +0x00800000 /* CSR_TX_RD_DMAD_AXI_LIMITER_EN_PKT[23] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_EN_PKT_SHFT\ +23 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_PKT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_PKT_MASK \ + 0x00700000 /* CSR_TX_RD_DMAD_AXI_LIMITER_PKT[22..20] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_PKT_SHFT \ + 20 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_EN_REQ_ADDR\ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_EN_REQ_MASK\ +0x00080000 /* CSR_TX_RD_DMAD_AXI_LIMITER_EN_REQ[19] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_EN_REQ_SHFT\ +19 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_REQ_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_REQ_MASK \ + 0x00070000 /* CSR_TX_RD_DMAD_AXI_LIMITER_REQ[18..16] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_REQ_SHFT \ + 16 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_EN_PKT_ADDR\ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_EN_PKT_MASK\ +0x00008000 /* CSR_RX_WR_DMAD_AXI_LIMITER_EN_PKT[15] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_EN_PKT_SHFT\ +15 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_PKT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_PKT_MASK \ + 0x00007000 /* CSR_RX_WR_DMAD_AXI_LIMITER_PKT[14..12] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_PKT_SHFT \ + 12 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_EN_REQ_ADDR\ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_EN_REQ_MASK\ +0x00000800 /* CSR_RX_WR_DMAD_AXI_LIMITER_EN_REQ[11] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_EN_REQ_SHFT\ +11 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_REQ_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_REQ_MASK \ + 0x00000700 /* CSR_RX_WR_DMAD_AXI_LIMITER_REQ[10..8] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_REQ_SHFT \ + 8 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_EN_PKT_ADDR\ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_EN_PKT_MASK\ +0x00000080 /* CSR_RX_RD_DMAD_AXI_LIMITER_EN_PKT[7] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_EN_PKT_SHFT\ +7 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_PKT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_PKT_MASK \ + 0x00000070 /* CSR_RX_RD_DMAD_AXI_LIMITER_PKT[6..4] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_PKT_SHFT \ + 4 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_EN_REQ_ADDR\ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_EN_REQ_MASK\ +0x00000008 /* CSR_RX_RD_DMAD_AXI_LIMITER_EN_REQ[3] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_EN_REQ_SHFT\ +3 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_REQ_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_REQ_MASK \ + 0x00000007 /* CSR_RX_RD_DMAD_AXI_LIMITER_REQ[2..0] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_REQ_SHFT \ + 0 + +/* +* ---WPDMA_TX_QOS_LMT_CFG3 (0x7C025000 + 0x2CC)--- +* CSR_AUX_RX_RD_DMAD_AXI_LIMITER_REQ[2..0] - (RW) QoS CR, Limiter value selected +* by PP dynamically +* RESERVED3[3] - (RO) Reserved bits +* CSR_AUX_RX_RD_DMAD_AXI_LIMITER_PKT[6..4] - (RW) QoS CR, Limiter value selected +* by PP dynamically +* RESERVED7[7] - (RO) Reserved bits +* CSR_AUX_RX_WR_DMAD_AXI_LIMITER_REQ[10..8] - (RW) QoS CR, Limiter value +* selected by PP dynamically +* RESERVED11[11] - (RO) Reserved bits +* CSR_AUX_RX_WR_DMAD_AXI_LIMITER_PKT[14..12] - (RW) QoS CR, Limiter value +* selected by PP dynamically +* RESERVED15[15] - (RO) Reserved bits +* CSR_AUX_TX_RD_DMAD_AXI_LIMITER_REQ[18..16] - (RW) QoS CR, Limiter value +* selected by PP dynamically +* RESERVED19[19] - (RO) Reserved bits +* CSR_AUX_TX_RD_DMAD_AXI_LIMITER_PKT[22..20] - (RW) QoS CR, Limiter value +* selected by PP dynamically +* RESERVED23[23] - (RO) Reserved bits +* CSR_AUX_TX_WR_DMAD_AXI_LIMITER_REQ[26..24] - (RW) QoS CR, Limiter value +* selected by PP dynamically +* RESERVED27[27] - (RO) Reserved bits +* CSR_AUX_TX_WR_DMAD_AXI_LIMITER_PKT[30..28] - (RW) QoS CR, Limiter value +* selected by PP dynamically +* RESERVED31[31] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_WR_DMAD_AXI_LIMITER_PKT_ADD\ +R \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_WR_DMAD_AXI_LIMITER_PKT_MAS\ +K \ +0x70000000 /* CSR_AUX_TX_WR_DMAD_AXI_LIMITER_PKT[30..28] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_WR_DMAD_AXI_LIMITER_PKT_SHF\ +T \ +28 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_WR_DMAD_AXI_LIMITER_REQ_ADD\ +R \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_WR_DMAD_AXI_LIMITER_REQ_MAS\ +K \ +0x07000000 /* CSR_AUX_TX_WR_DMAD_AXI_LIMITER_REQ[26..24] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_WR_DMAD_AXI_LIMITER_REQ_SHF\ +T \ +24 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_RD_DMAD_AXI_LIMITER_PKT_ADD\ +R \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_RD_DMAD_AXI_LIMITER_PKT_MAS\ +K \ +0x00700000 /* CSR_AUX_TX_RD_DMAD_AXI_LIMITER_PKT[22..20] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_RD_DMAD_AXI_LIMITER_PKT_SHF\ +T \ +20 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_RD_DMAD_AXI_LIMITER_REQ_ADD\ +R \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_RD_DMAD_AXI_LIMITER_REQ_MAS\ +K \ +0x00070000 /* CSR_AUX_TX_RD_DMAD_AXI_LIMITER_REQ[18..16] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_RD_DMAD_AXI_LIMITER_REQ_SHF\ +T \ +16 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_WR_DMAD_AXI_LIMITER_PKT_ADD\ +R \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_WR_DMAD_AXI_LIMITER_PKT_MAS\ +K \ +0x00007000 /* CSR_AUX_RX_WR_DMAD_AXI_LIMITER_PKT[14..12] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_WR_DMAD_AXI_LIMITER_PKT_SHF\ +T \ +12 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_WR_DMAD_AXI_LIMITER_REQ_ADD\ +R \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_WR_DMAD_AXI_LIMITER_REQ_MAS\ +K \ +0x00000700 /* CSR_AUX_RX_WR_DMAD_AXI_LIMITER_REQ[10..8] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_WR_DMAD_AXI_LIMITER_REQ_SHF\ +T \ +8 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_RD_DMAD_AXI_LIMITER_PKT_ADD\ +R \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_RD_DMAD_AXI_LIMITER_PKT_MAS\ +K \ +0x00000070 /* CSR_AUX_RX_RD_DMAD_AXI_LIMITER_PKT[6..4] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_RD_DMAD_AXI_LIMITER_PKT_SHF\ +T \ +4 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_RD_DMAD_AXI_LIMITER_REQ_ADD\ +R \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_RD_DMAD_AXI_LIMITER_REQ_MAS\ +K \ +0x00000007 /* CSR_AUX_RX_RD_DMAD_AXI_LIMITER_REQ[2..0] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_RD_DMAD_AXI_LIMITER_REQ_SHF\ +T \ +0 + +/* +* ---HOST_PRI_INT_STA (0x7C025000 + 0x2E0)--- +* host_pri_int_sts_0[0] - (W1C) rx_done_int[0], configuration interrupt please +* refer to 0x2E0 WPDMA_PRI_DLY_INT_CFG0[15:0] +* host_pri_int_sts_1[1] - (W1C) rx_done_int[1], configuration interrupt please +* refer to 0x2E0 WPDMA_PRI_DLY_INT_CFG0[31:16] +* RESERVED2[31..2] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_HOST_PRI_INT_STA_host_pri_int_sts_1_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_PRI_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_PRI_INT_STA_host_pri_int_sts_1_MASK \ + 0x00000002 /* host_pri_int_sts_1[1] */ +#define WF_WFDMA_HOST_DMA1_HOST_PRI_INT_STA_host_pri_int_sts_1_SHFT 1 +#define WF_WFDMA_HOST_DMA1_HOST_PRI_INT_STA_host_pri_int_sts_0_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_PRI_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_PRI_INT_STA_host_pri_int_sts_0_MASK \ + 0x00000001 /* host_pri_int_sts_0[0] */ +#define WF_WFDMA_HOST_DMA1_HOST_PRI_INT_STA_host_pri_int_sts_0_SHFT 0 + +/* +* ---HOST_PER_INT_ENA_STA (0x7C025000 + 0x2E4)--- +* wpdma_per_int_sts[3..0] - (W1C) status bit for rx ring periodic delayed +* interrupt to tracking ring is full or not, start delayed interrupt timer when +* RX ring is not full from falling edge of full flag and reset when ring full +* flag is asserted +* RESERVED4[15..4] - (RO) Reserved bits +* wpdma_per_int_ena[19..16] - (RW) enable bit for rx ring periodic delayed +* interrupt to tracking ring is full or not, start delayed interrupt timer when +* RX ring is not full from falling edge of full flag and reset when ring full +* flag is asserted +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_HOST_PER_INT_ENA_STA_wpdma_per_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_PER_INT_ENA_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_PER_INT_ENA_STA_wpdma_per_int_ena_MASK \ + 0x000F0000 /* wpdma_per_int_ena[19..16] */ +#define WF_WFDMA_HOST_DMA1_HOST_PER_INT_ENA_STA_wpdma_per_int_ena_SHFT 16 +#define WF_WFDMA_HOST_DMA1_HOST_PER_INT_ENA_STA_wpdma_per_int_sts_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_PER_INT_ENA_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_PER_INT_ENA_STA_wpdma_per_int_sts_MASK \ + 0x0000000F /* wpdma_per_int_sts[3..0] */ +#define WF_WFDMA_HOST_DMA1_HOST_PER_INT_ENA_STA_wpdma_per_int_sts_SHFT 0 + +/* +* ---HOST_PER_DLY_INT_CFG (0x7C025000 + 0x2E8)--- +* wpdma_per_max_ptime[7..0] - (RW) Specified Max pending time for the internal +* RX ring full flag falling edge. When the pending time equal or greater +* PER_MAX_PTIME x 20us or the # of pended TX_DONE_INT equal or greater than +* TX_MAX_PINT (see above), an Final TX_DLY_INT is generated +* Set to 0 will disable pending interrupt time check +* wpdma_per_dly_int_en[11..8] - (RW) RX periodic Delayed Interrupt Enable +* 1: Enable RX periodic delayed interrupt mechanism +* 0: Disable RX periodic delayed interrupt mechanism +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_HOST_PER_DLY_INT_CFG_wpdma_per_dly_int_en_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_PER_DLY_INT_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_PER_DLY_INT_CFG_wpdma_per_dly_int_en_MASK \ + 0x00000F00 /* wpdma_per_dly_int_en[11..8] */ +#define WF_WFDMA_HOST_DMA1_HOST_PER_DLY_INT_CFG_wpdma_per_dly_int_en_SHFT 8 +#define WF_WFDMA_HOST_DMA1_HOST_PER_DLY_INT_CFG_wpdma_per_max_ptime_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_PER_DLY_INT_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_PER_DLY_INT_CFG_wpdma_per_max_ptime_MASK \ + 0x000000FF /* wpdma_per_max_ptime[7..0] */ +#define WF_WFDMA_HOST_DMA1_HOST_PER_DLY_INT_CFG_wpdma_per_max_ptime_SHFT 0 + +/* +* ---WPDMA_PRI_DLY_INT_CFG0 (0x7C025000 + 0x2F0)--- +* PRI0_MAX_PTIME[7..0] - (RW) Specified Max pending time for the internal +* PRI0_DONE_INT. When the pending time equal or greater PRI0_MAX_PTIME x 20us or +* the # of pended PRI0_DONE_INT equal or greater than PRI0_MAX_PINT (see above), +* an Final PRI0_DLY_INT is generated +* Set to 0 will disable pending interrupt time check +* PRI0_MAX_PINT[14..8] - (RW) Specified Max # of pended interrupts. +* When the # of pended interrupts equal or greater than the value specified here +* or interrupt pending time reach the limit (See below), a Final PRI0_DLY_INT is +generated. +* Set to 0 will disable pending interrupt count check +* PRI0_DLY_INT_EN[15] - (RW) Priority Delayed Interrupt Enable +* 1: Enable Priority delayed interrupt mechanism +* 0: Disable Priority delayed interrupt mechanism +* In AXE host_dma0, these PRI1_* settings are for rx_ring[1]_int, and PRI0_* +* settings are for rx_ring[0]_int +* In AXE host_dma1, these PRI1_* settings are for rx_ring[0]_int, and PRI0_* +* settings are for Ored-tx_ring[14:0]_int +* In AXE mcu_dma0 and mcu_dma1, there are no priority interrupt thus no this +* 0x2E0 CR!! +* PRI1_MAX_PTIME[23..16] - (RW) Specified Max pending time for the internal +* PRI1_DONE_INT. When the pending time equal or greater PRI1_MAX_PTIME x 20us or +* the # of pended PRI1_DONE_INT equal or greater than PRI1_MAX_PINT (see above), +* an Final PRI1_DLY_INT is generated +* Set to 0 will disable pending interrupt time check +* PRI1_MAX_PINT[30..24] - (RW) Specified Max # of pended interrupts. +* When the # of pended interrupts equal or greater than the value specified here +* or interrupt pending time reach the limit (See below), a Final PRI1_DLY_INT is +generated. +* Set to 0 will disable pending interrupt count check +* PRI1_DLY_INT_EN[31] - (RW) Priority Delayed Interrupt Enable +* 1: Enable Priority delayed interrupt mechanism +* 0: Disable Priority delayed interrupt mechanism +* In AXE host_dma0, these PRI1_* settings are for rx_ring[1]_int, and PRI0_* +* settings are for rx_ring[0]_int +* In AXE host_dma1, these PRI1_* settings are for rx_ring[0]_int, and PRI0_* +* settings are for Ored-tx_ring[14:0]_int +* In AXE mcu_dma0 and mcu_dma1, there are no priority interrupt thus no this +* 0x2E0 CR!! +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_PRI1_DLY_INT_EN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_PRI1_DLY_INT_EN_MASK \ + 0x80000000 /* PRI1_DLY_INT_EN[31] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_PRI1_DLY_INT_EN_SHFT 31 +#define WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_PRI1_MAX_PINT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_PRI1_MAX_PINT_MASK \ + 0x7F000000 /* PRI1_MAX_PINT[30..24] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_PRI1_MAX_PINT_SHFT 24 +#define WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_PRI1_MAX_PTIME_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_PRI1_MAX_PTIME_MASK \ + 0x00FF0000 /* PRI1_MAX_PTIME[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_PRI1_MAX_PTIME_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_PRI0_DLY_INT_EN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_PRI0_DLY_INT_EN_MASK \ + 0x00008000 /* PRI0_DLY_INT_EN[15] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_PRI0_DLY_INT_EN_SHFT 15 +#define WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_PRI0_MAX_PINT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_PRI0_MAX_PINT_MASK \ + 0x00007F00 /* PRI0_MAX_PINT[14..8] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_PRI0_MAX_PINT_SHFT 8 +#define WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_PRI0_MAX_PTIME_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_PRI0_MAX_PTIME_MASK \ + 0x000000FF /* PRI0_MAX_PTIME[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_PRI0_MAX_PTIME_SHFT 0 + +/* +* ---WPDMA_TX_RING0_CTRL0 (0x7C025000 + 0x300)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring0 (8-DWORD aligned +address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING0_CTRL1 (0x7C025000 + 0x304)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in TXD_Ring0. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of TX_Ring0 +* (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING0_CTRL2 (0x7C025000 + 0x308)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING0_CTRL3 (0x7C025000 + 0x30c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING1_CTRL0 (0x7C025000 + 0x310)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring1 (8-DWORD aligned +address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING1_CTRL1 (0x7C025000 + 0x314)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in TXD_Ring1. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of TX_Ring1 +* (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING1_CTRL2 (0x7C025000 + 0x318)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING1_CTRL3 (0x7C025000 + 0x31c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING2_CTRL0 (0x7C025000 + 0x320)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring2 (8-DWORD aligned +address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING2_CTRL1 (0x7C025000 + 0x324)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in TXD_Ring2. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of TX_Ring2 +* (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING2_CTRL2 (0x7C025000 + 0x328)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING2_CTRL3 (0x7C025000 + 0x32c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING3_CTRL0 (0x7C025000 + 0x330)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring3 (8-DWORD aligned +address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING3_CTRL1 (0x7C025000 + 0x334)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in TXD_Ring3. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of TX_Ring3 +* (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING3_CTRL2 (0x7C025000 + 0x338)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING3_CTRL3 (0x7C025000 + 0x33c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING4_CTRL0 (0x7C025000 + 0x340)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring4 (8-DWORD aligned +address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING4_CTRL1 (0x7C025000 + 0x344)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in TXD_Ring4. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of TX_Ring4 +* (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING4_CTRL2 (0x7C025000 + 0x348)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING4_CTRL3 (0x7C025000 + 0x34c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING5_CTRL0 (0x7C025000 + 0x350)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring5 (8-DWORD aligned +address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING5_CTRL1 (0x7C025000 + 0x354)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in TXD_Ring5. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of TX_Ring5 +* (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING5_CTRL2 (0x7C025000 + 0x358)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING5_CTRL3 (0x7C025000 + 0x35c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING6_CTRL0 (0x7C025000 + 0x360)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring6 (8-DWORD aligned +address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING6_CTRL1 (0x7C025000 + 0x364)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in TXD_Ring6. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of TX_Ring6 +* (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING6_CTRL2 (0x7C025000 + 0x368)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING6_CTRL3 (0x7C025000 + 0x36c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING7_CTRL0 (0x7C025000 + 0x370)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring7 (8-DWORD aligned +address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING7_CTRL1 (0x7C025000 + 0x374)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in TXD_Ring7. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of TX_Ring7 +* (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING7_CTRL2 (0x7C025000 + 0x378)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING7_CTRL3 (0x7C025000 + 0x37c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING8_CTRL0 (0x7C025000 + 0x380)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring8 (8-DWORD aligned +address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING8_CTRL1 (0x7C025000 + 0x384)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in TXD_Ring8. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of TX_Ring8 +* (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING8_CTRL2 (0x7C025000 + 0x388)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING8_CTRL3 (0x7C025000 + 0x38c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING9_CTRL0 (0x7C025000 + 0x390)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring9 (8-DWORD aligned +address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING9_CTRL1 (0x7C025000 + 0x394)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in TXD_Ring9. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of TX_Ring9 +* (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING9_CTRL2 (0x7C025000 + 0x398)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING9_CTRL3 (0x7C025000 + 0x39c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING10_CTRL0 (0x7C025000 + 0x3a0)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring10 (8-DWORD aligned +address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING10_CTRL1 (0x7C025000 + 0x3a4)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in TXD_Ring10. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of TX_Ring10 +* (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING10_CTRL2 (0x7C025000 + 0x3a8)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING10_CTRL3 (0x7C025000 + 0x3ac)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING11_CTRL0 (0x7C025000 + 0x3b0)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring11 (8-DWORD aligned +address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING11_CTRL1 (0x7C025000 + 0x3b4)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in TXD_Ring11. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of TX_Ring11 +* (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING11_CTRL2 (0x7C025000 + 0x3b8)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING11_CTRL3 (0x7C025000 + 0x3bc)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING12_CTRL0 (0x7C025000 + 0x3c0)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring12 (8-DWORD aligned +address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING12_CTRL1 (0x7C025000 + 0x3c4)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in TXD_Ring12. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of TX_Ring12 +* (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING12_CTRL2 (0x7C025000 + 0x3c8)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING12_CTRL3 (0x7C025000 + 0x3cc)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING13_CTRL0 (0x7C025000 + 0x3d0)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring13 (8-DWORD aligned +address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING13_CTRL1 (0x7C025000 + 0x3d4)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in TXD_Ring13. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of TX_Ring13 +* (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING13_CTRL2 (0x7C025000 + 0x3d8)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING13_CTRL3 (0x7C025000 + 0x3dc)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING14_CTRL0 (0x7C025000 + 0x3e0)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring14 (8-DWORD aligned +address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING14_CTRL1 (0x7C025000 + 0x3e4)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in TXD_Ring14. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of TX_Ring14 +* (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING14_CTRL2 (0x7C025000 + 0x3e8)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING14_CTRL3 (0x7C025000 + 0x3ec)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING15_CTRL0 (0x7C025000 + 0x3f0)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring15 (8-DWORD aligned +address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING15_CTRL1 (0x7C025000 + 0x3f4)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in TXD_Ring15. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of TX_Ring15 +* (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING15_CTRL2 (0x7C025000 + 0x3f8)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING15_CTRL3 (0x7C025000 + 0x3fc)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING16_CTRL0 (0x7C025000 + 0x400)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_RING16 (8-DWORD aligned +address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING16_CTRL1 (0x7C025000 + 0x404)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in TXD_RING16. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of TX_Ring16 +* (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING16_CTRL2 (0x7C025000 + 0x408)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING16_CTRL3 (0x7C025000 + 0x40c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING17_CTRL0 (0x7C025000 + 0x410)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring17 (8-DWORD aligned +address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING17_CTRL1 (0x7C025000 + 0x414)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in TXD_Ring17. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of TX_Ring17 +* (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING17_CTRL2 (0x7C025000 + 0x418)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING17_CTRL3 (0x7C025000 + 0x41c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING18_CTRL0 (0x7C025000 + 0x420)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring18 (8-DWORD aligned +address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING18_CTRL1 (0x7C025000 + 0x424)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in TXD_Ring18. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of TX_Ring18 +* (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING18_CTRL2 (0x7C025000 + 0x428)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING18_CTRL3 (0x7C025000 + 0x42c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING19_CTRL0 (0x7C025000 + 0x430)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring19 (8-DWORD aligned +address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING19_CTRL1 (0x7C025000 + 0x434)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in TXD_Ring19. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of TX_Ring19 +* (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING19_CTRL2 (0x7C025000 + 0x438)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING19_CTRL3 (0x7C025000 + 0x43c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING20_CTRL0 (0x7C025000 + 0x440)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring20 (8-DWORD aligned +address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING20_CTRL1 (0x7C025000 + 0x444)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in TXD_Ring0. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of TX_Ring20 +* (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING20_CTRL2 (0x7C025000 + 0x448)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING20_CTRL3 (0x7C025000 + 0x44c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING21_CTRL0 (0x7C025000 + 0x450)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring21 (8-DWORD aligned +address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING21_CTRL1 (0x7C025000 + 0x454)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in TXD_Ring1. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of TX_Ring21 +* (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING21_CTRL2 (0x7C025000 + 0x458)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING21_CTRL3 (0x7C025000 + 0x45c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING22_CTRL0 (0x7C025000 + 0x460)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring22 (8-DWORD aligned +address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING22_CTRL1 (0x7C025000 + 0x464)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in TXD_Ring2. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of TX_Ring22 +* (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING22_CTRL2 (0x7C025000 + 0x468)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING22_CTRL3 (0x7C025000 + 0x46c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING23_CTRL0 (0x7C025000 + 0x470)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring23 (8-DWORD aligned +address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING23_CTRL1 (0x7C025000 + 0x474)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in TXD_Ring3. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of TX_Ring23 +* (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING23_CTRL2 (0x7C025000 + 0x478)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING23_CTRL3 (0x7C025000 + 0x47c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING0_CTRL0 (0x7C025000 + 0x500)--- +* BASE_PTR[31..0] - (RW) Point to the base address of RXD Ring #0 (GE ports). It +* should be a 8-DWORD aligned address +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_RX_RING0_CTRL1 (0x7C025000 + 0x504)--- +* MAX_CNT[11..0] - (RW) The maximum number of RXD count in RXD Ring #0. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of RX_Ring0 +* (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING0_CTRL2 (0x7C025000 + 0x508)--- +* CPU_IDX[11..0] - (RW) Point to the next RXD CPU wants to allocate to RXD Ring +#0. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING0_CTRL3 (0x7C025000 + 0x50c)--- +* DMA_IDX[11..0] - (RW) In normal operation, user dma_index would udated by +* hardware when moving rx packet done. User should not write dma_index. +* Point to the next RXD DMA wants to use in FDS Ring#0. It should be a 8-DWORD +* aligned address. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING1_CTRL0 (0x7C025000 + 0x510)--- +* BASE_PTR[31..0] - (RW) Point to the base address of RXD Ring #1 (GE ports). It +* should be a 8-DWORD aligned address +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_RX_RING1_CTRL1 (0x7C025000 + 0x514)--- +* MAX_CNT[11..0] - (RW) The maximum number of RXD count in RXD Ring #1. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of RX_Ring1 +* (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING1_CTRL2 (0x7C025000 + 0x518)--- +* CPU_IDX[11..0] - (RW) Point to the next RXD CPU wants to allocate to RXD Ring +#1. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING1_CTRL3 (0x7C025000 + 0x51c)--- +* DMA_IDX[11..0] - (RW) In normal operation, user dma_index would udated by +* hardware when moving rx packet done. User should not write dma_index. +* Point to the next RXD DMA wants to use in FDS Ring#1. It should be a 8-DWORD +* aligned address. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING2_CTRL0 (0x7C025000 + 0x520)--- +* BASE_PTR[31..0] - (RW) Point to the base address of RXD Ring #2 (GE ports). It +* should be a 8-DWORD aligned address +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_RX_RING2_CTRL1 (0x7C025000 + 0x524)--- +* MAX_CNT[11..0] - (RW) The maximum number of RXD count in RXD Ring #2. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of RX_Ring2 +* (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING2_CTRL2 (0x7C025000 + 0x528)--- +* CPU_IDX[11..0] - (RW) Point to the next RXD CPU wants to allocate to RXD Ring +#2. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING2_CTRL3 (0x7C025000 + 0x52C)--- +* DMA_IDX[11..0] - (RW) In normal operation, user dma_index would udated by +* hardware when moving rx packet done. User should not write dma_index. +* Point to the next RXD DMA wants to use in FDS Ring#2. It should be a 8-DWORD +* aligned address. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING3_CTRL0 (0x7C025000 + 0x530)--- +* BASE_PTR[31..0] - (RW) Point to the base address of RXD Ring #3 (GE ports). It +* should be a 8-DWORD aligned address +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_RX_RING3_CTRL1 (0x7C025000 + 0x534)--- +* MAX_CNT[11..0] - (RW) The maximum number of RXD count in RXD Ring #3. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of RX_Ring3 +* (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING3_CTRL2 (0x7C025000 + 0x538)--- +* CPU_IDX[11..0] - (RW) Point to the next RXD CPU wants to allocate to RXD Ring +#3. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING3_CTRL3 (0x7C025000 + 0x53C)--- +* DMA_IDX[11..0] - (RW) In normal operation, user dma_index would udated by +* hardware when moving rx packet done. User should not write dma_index. +* Point to the next RXD DMA wants to use in FDS Ring#3. It should be a 8-DWORD +* aligned address. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING0_EXT_CTRL (0x7C025000 + 0x600)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #0 Extension, to configure prefetch +* settings, like base_ptr means each prefetch ring's base address in internal +* prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING1_EXT_CTRL (0x7C025000 + 0x604)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #1 Extension, to configure prefetch +* settings, like base_ptr means each prefetch ring's base address in internal +* prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING2_EXT_CTRL (0x7C025000 + 0x608)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #2 Extension, to configure prefetch +* settings, like base_ptr means each prefetch ring's base address in internal +* prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING3_EXT_CTRL (0x7C025000 + 0x60C)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #3 Extension, to configure prefetch +* settings, like base_ptr means each prefetch ring's base address in internal +* prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING4_EXT_CTRL (0x7C025000 + 0x610)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #4 Extension, to configure prefetch +* settings, like base_ptr means each prefetch ring's base address in internal +* prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING5_EXT_CTRL (0x7C025000 + 0x614)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #5 Extension, to configure prefetch +* settings, like base_ptr means each prefetch ring's base address in internal +* prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING6_EXT_CTRL (0x7C025000 + 0x618)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #6 Extension, to configure prefetch +* settings, like base_ptr means each prefetch ring's base address in internal +* prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING7_EXT_CTRL (0x7C025000 + 0x61C)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #7 Extension, to configure prefetch +* settings, like base_ptr means each prefetch ring's base address in internal +* prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING8_EXT_CTRL (0x7C025000 + 0x620)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #8 Extension, to configure prefetch +* settings, like base_ptr means each prefetch ring's base address in internal +* prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING9_EXT_CTRL (0x7C025000 + 0x624)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #9 Extension, to configure prefetch +* settings, like base_ptr means each prefetch ring's base address in internal +* prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING10_EXT_CTRL (0x7C025000 + 0x628)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #10 Extension, to configure prefetch +* settings, like base_ptr means each prefetch ring's base address in internal +* prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING11_EXT_CTRL (0x7C025000 + 0x62C)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #11 Extension, to configure prefetch +* settings, like base_ptr means each prefetch ring's base address in internal +* prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING12_EXT_CTRL (0x7C025000 + 0x630)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #12 Extension, to configure prefetch +* settings, like base_ptr means each prefetch ring's base address in internal +* prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING13_EXT_CTRL (0x7C025000 + 0x634)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #13 Extension, to configure prefetch +* settings, like base_ptr means each prefetch ring's base address in internal +* prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING14_EXT_CTRL (0x7C025000 + 0x638)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #14 Extension, to configure prefetch +* settings, like base_ptr means each prefetch ring's base address in internal +* prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING15_EXT_CTRL (0x7C025000 + 0x63C)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #15 Extension, to configure prefetch +* settings, like base_ptr means each prefetch ring's base address in internal +* prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING16_EXT_CTRL (0x7C025000 + 0x640)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #16 Extension, to configure prefetch +* settings, like base_ptr means each prefetch ring's base address in internal +* prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING17_EXT_CTRL (0x7C025000 + 0x644)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #17 Extension, to configure prefetch +* settings, like base_ptr means each prefetch ring's base address in internal +* prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING18_EXT_CTRL (0x7C025000 + 0x648)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #18 Extension, to configure prefetch +* settings, like base_ptr means each prefetch ring's base address in internal +* prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING19_EXT_CTRL (0x7C025000 + 0x64C)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #19 Extension, to configure prefetch +* settings, like base_ptr means each prefetch ring's base address in internal +* prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING20_EXT_CTRL (0x7C025000 + 0x650)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #20 Extension, to configure prefetch +* settings, like base_ptr means each prefetch ring's base address in internal +* prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING21_EXT_CTRL (0x7C025000 + 0x654)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #21 Extension, to configure prefetch +* settings, like base_ptr means each prefetch ring's base address in internal +* prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING22_EXT_CTRL (0x7C025000 + 0x658)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #22 Extension, to configure prefetch +* settings, like base_ptr means each prefetch ring's base address in internal +* prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING23_EXT_CTRL (0x7C025000 + 0x65C)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #23 Extension, to configure prefetch +* settings, like base_ptr means each prefetch ring's base address in internal +* prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING0_EXT_CTRL (0x7C025000 + 0x680)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) RXD Ring #0 Extension, to configure prefetch +* settings, like base_ptr means each prefetch ring's base address in internal +* prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING1_EXT_CTRL (0x7C025000 + 0x684)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) RXD Ring #1 Extension, to configure prefetch +* settings, like base_ptr means each prefetch ring's base address in internal +* prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING2_EXT_CTRL (0x7C025000 + 0x688)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) RXD Ring #2 Extension, to configure prefetch +* settings, like base_ptr means each prefetch ring's base address in internal +* prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING3_EXT_CTRL (0x7C025000 + 0x68C)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) RXD Ring #3 Extension, to configure prefetch +* settings, like base_ptr means each prefetch ring's base address in internal +* prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_AXI_MTR_PERF_CFG (0x7C025000 + 0x900)--- +* AXI_MTR_PERF_SEL_W_CH[2..0] - (RW) csr_axi_mtr_perf_sel_w_ch +* AXI_MTR_BW_W_RST[3] - (RW) csr_axi_mtr_bw_w_rst +* AXI_MTR_LAT_W_RST[4] - (RW) csr_axi_mtr_lat_w_rst +* RESERVED5[7..5] - (RO) Reserved bits +* AXI_MTR_PERF_SEL_R_CH[10..8] - (RW) csr_axi_mtr_perf_sel_r_ch +* AXI_MTR_BW_R_RST[11] - (RW) csr_axi_mtr_bw_r_rst +* AXI_MTR_LAT_R_RST[12] - (RW) csr_axi_mtr_lat_r_rst +* RESERVED13[30..13] - (RO) Reserved bits +* AXI_MTR_ENABLE[31] - (RW) csr_axi_mtr_enable +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_CFG_AXI_MTR_ENABLE_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_CFG_AXI_MTR_ENABLE_MASK \ + 0x80000000 /* AXI_MTR_ENABLE[31] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_CFG_AXI_MTR_ENABLE_SHFT 31 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_CFG_AXI_MTR_LAT_R_RST_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_CFG_AXI_MTR_LAT_R_RST_MASK \ + 0x00001000 /* AXI_MTR_LAT_R_RST[12] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_CFG_AXI_MTR_LAT_R_RST_SHFT 12 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_CFG_AXI_MTR_BW_R_RST_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_CFG_AXI_MTR_BW_R_RST_MASK \ + 0x00000800 /* AXI_MTR_BW_R_RST[11] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_CFG_AXI_MTR_BW_R_RST_SHFT 11 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_CFG_AXI_MTR_PERF_SEL_R_CH_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_CFG_AXI_MTR_PERF_SEL_R_CH_MASK \ + 0x00000700 /* AXI_MTR_PERF_SEL_R_CH[10..8] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_CFG_AXI_MTR_PERF_SEL_R_CH_SHFT 8 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_CFG_AXI_MTR_LAT_W_RST_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_CFG_AXI_MTR_LAT_W_RST_MASK \ + 0x00000010 /* AXI_MTR_LAT_W_RST[4] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_CFG_AXI_MTR_LAT_W_RST_SHFT 4 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_CFG_AXI_MTR_BW_W_RST_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_CFG_AXI_MTR_BW_W_RST_MASK \ + 0x00000008 /* AXI_MTR_BW_W_RST[3] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_CFG_AXI_MTR_BW_W_RST_SHFT 3 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_CFG_AXI_MTR_PERF_SEL_W_CH_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_CFG_AXI_MTR_PERF_SEL_W_CH_MASK \ + 0x00000007 /* AXI_MTR_PERF_SEL_W_CH[2..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_CFG_AXI_MTR_PERF_SEL_W_CH_SHFT 0 + +/* +* ---WPDMA_AXI_MTR_DBG_CFG (0x7C025000 + 0x904)--- +* AXI_MST_DBG_CH_SEL[2..0] - (RW) csr_axi_mst_dbg_ch_sel[2:0] +* RESERVED3[7..3] - (RO) Reserved bits +* MASTER0_AXI_AW_CH_COUNTER_SET[8] - (RW) master0 axi_aw_ch_counter_set +* MASTER0_AXI_W_CH_COUNTER_SET[9] - (RW) master0 axi_w_ch_counter_set +* MASTER0_AXI_B_CH_COUNTER_SET[10] - (RW) master0 axi_b_ch_counter_set +* MASTER0_AXI_AR_CH_COUNTER_SET[11] - (RW) master0 axi_ar_ch_counter_set +* MASTER0_AXI_R_CH_COUNTER_SET[12] - (RW) master0 axi_r_ch_counter_set +* MASTER1_AXI_AW_CH_COUNTER_SET[13] - (RW) master1 axi_aw_ch_counter_set +* MASTER1_AXI_W_CH_COUNTER_SET[14] - (RW) master1 axi_w_ch_counter_set +* MASTER1_AXI_B_CH_COUNTER_SET[15] - (RW) master1 axi_b_ch_counter_set +* MASTER1_AXI_AR_CH_COUNTER_SET[16] - (RW) master1 axi_ar_ch_counter_set +* MASTER1_AXI_R_CH_COUNTER_SET[17] - (RW) master1 axi_r_ch_counter_set +* MASTER2_AXI_AW_CH_COUNTER_SET[18] - (RW) master2 axi_aw_ch_counter_set +* MASTER2_AXI_W_CH_COUNTER_SET[19] - (RW) master2 axi_w_ch_counter_set +* MASTER2_AXI_B_CH_COUNTER_SET[20] - (RW) master2 axi_b_ch_counter_set +* MASTER2_AXI_AR_CH_COUNTER_SET[21] - (RW) master2 axi_ar_ch_counter_set +* MASTER2_AXI_R_CH_COUNTER_SET[22] - (RW) master2 axi_r_ch_counter_set +* MASTER3_AXI_AW_CH_COUNTER_SET[23] - (RW) master3 axi_aw_ch_counter_set +* MASTER3_AXI_W_CH_COUNTER_SET[24] - (RW) master3 axi_w_ch_counter_set +* MASTER3_AXI_B_CH_COUNTER_SET[25] - (RW) master3 axi_b_ch_counter_set +* MASTER3_AXI_AR_CH_COUNTER_SET[26] - (RW) master3 axi_ar_ch_counter_set +* MASTER3_AXI_R_CH_COUNTER_SET[27] - (RW) master3 axi_r_ch_counter_set +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER3_AXI_R_CH_COUNTER_SET_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER3_AXI_R_CH_COUNTER_SET_MASK \ + 0x08000000 /* MASTER3_AXI_R_CH_COUNTER_SET[27] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER3_AXI_R_CH_COUNTER_SET_SHFT \ + 27 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER3_AXI_AR_CH_COUNTER_SET_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER3_AXI_AR_CH_COUNTER_SET_MASK \ + 0x04000000 /* MASTER3_AXI_AR_CH_COUNTER_SET[26] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER3_AXI_AR_CH_COUNTER_SET_SHFT \ + 26 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER3_AXI_B_CH_COUNTER_SET_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER3_AXI_B_CH_COUNTER_SET_MASK \ + 0x02000000 /* MASTER3_AXI_B_CH_COUNTER_SET[25] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER3_AXI_B_CH_COUNTER_SET_SHFT \ + 25 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER3_AXI_W_CH_COUNTER_SET_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER3_AXI_W_CH_COUNTER_SET_MASK \ + 0x01000000 /* MASTER3_AXI_W_CH_COUNTER_SET[24] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER3_AXI_W_CH_COUNTER_SET_SHFT \ + 24 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER3_AXI_AW_CH_COUNTER_SET_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER3_AXI_AW_CH_COUNTER_SET_MASK \ + 0x00800000 /* MASTER3_AXI_AW_CH_COUNTER_SET[23] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER3_AXI_AW_CH_COUNTER_SET_SHFT \ + 23 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER2_AXI_R_CH_COUNTER_SET_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER2_AXI_R_CH_COUNTER_SET_MASK \ + 0x00400000 /* MASTER2_AXI_R_CH_COUNTER_SET[22] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER2_AXI_R_CH_COUNTER_SET_SHFT \ + 22 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER2_AXI_AR_CH_COUNTER_SET_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER2_AXI_AR_CH_COUNTER_SET_MASK \ + 0x00200000 /* MASTER2_AXI_AR_CH_COUNTER_SET[21] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER2_AXI_AR_CH_COUNTER_SET_SHFT \ + 21 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER2_AXI_B_CH_COUNTER_SET_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER2_AXI_B_CH_COUNTER_SET_MASK \ + 0x00100000 /* MASTER2_AXI_B_CH_COUNTER_SET[20] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER2_AXI_B_CH_COUNTER_SET_SHFT \ + 20 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER2_AXI_W_CH_COUNTER_SET_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER2_AXI_W_CH_COUNTER_SET_MASK \ + 0x00080000 /* MASTER2_AXI_W_CH_COUNTER_SET[19] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER2_AXI_W_CH_COUNTER_SET_SHFT \ + 19 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER2_AXI_AW_CH_COUNTER_SET_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER2_AXI_AW_CH_COUNTER_SET_MASK \ + 0x00040000 /* MASTER2_AXI_AW_CH_COUNTER_SET[18] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER2_AXI_AW_CH_COUNTER_SET_SHFT \ + 18 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER1_AXI_R_CH_COUNTER_SET_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER1_AXI_R_CH_COUNTER_SET_MASK \ + 0x00020000 /* MASTER1_AXI_R_CH_COUNTER_SET[17] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER1_AXI_R_CH_COUNTER_SET_SHFT \ + 17 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER1_AXI_AR_CH_COUNTER_SET_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER1_AXI_AR_CH_COUNTER_SET_MASK \ + 0x00010000 /* MASTER1_AXI_AR_CH_COUNTER_SET[16] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER1_AXI_AR_CH_COUNTER_SET_SHFT \ + 16 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER1_AXI_B_CH_COUNTER_SET_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER1_AXI_B_CH_COUNTER_SET_MASK \ + 0x00008000 /* MASTER1_AXI_B_CH_COUNTER_SET[15] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER1_AXI_B_CH_COUNTER_SET_SHFT \ + 15 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER1_AXI_W_CH_COUNTER_SET_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER1_AXI_W_CH_COUNTER_SET_MASK \ + 0x00004000 /* MASTER1_AXI_W_CH_COUNTER_SET[14] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER1_AXI_W_CH_COUNTER_SET_SHFT \ + 14 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER1_AXI_AW_CH_COUNTER_SET_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER1_AXI_AW_CH_COUNTER_SET_MASK \ + 0x00002000 /* MASTER1_AXI_AW_CH_COUNTER_SET[13] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER1_AXI_AW_CH_COUNTER_SET_SHFT \ + 13 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER0_AXI_R_CH_COUNTER_SET_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER0_AXI_R_CH_COUNTER_SET_MASK \ + 0x00001000 /* MASTER0_AXI_R_CH_COUNTER_SET[12] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER0_AXI_R_CH_COUNTER_SET_SHFT \ + 12 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER0_AXI_AR_CH_COUNTER_SET_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER0_AXI_AR_CH_COUNTER_SET_MASK \ + 0x00000800 /* MASTER0_AXI_AR_CH_COUNTER_SET[11] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER0_AXI_AR_CH_COUNTER_SET_SHFT \ + 11 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER0_AXI_B_CH_COUNTER_SET_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER0_AXI_B_CH_COUNTER_SET_MASK \ + 0x00000400 /* MASTER0_AXI_B_CH_COUNTER_SET[10] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER0_AXI_B_CH_COUNTER_SET_SHFT \ + 10 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER0_AXI_W_CH_COUNTER_SET_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER0_AXI_W_CH_COUNTER_SET_MASK \ + 0x00000200 /* MASTER0_AXI_W_CH_COUNTER_SET[9] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER0_AXI_W_CH_COUNTER_SET_SHFT \ + 9 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER0_AXI_AW_CH_COUNTER_SET_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER0_AXI_AW_CH_COUNTER_SET_MASK \ + 0x00000100 /* MASTER0_AXI_AW_CH_COUNTER_SET[8] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_MASTER0_AXI_AW_CH_COUNTER_SET_SHFT \ + 8 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_AXI_MST_DBG_CH_SEL_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_AXI_MST_DBG_CH_SEL_MASK \ + 0x00000007 /* AXI_MST_DBG_CH_SEL[2..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_CFG_AXI_MST_DBG_CH_SEL_SHFT 0 + +/* +* ---WPDMA_AXI_MTR_PERF_W_STA0 (0x7C025000 + 0x910)--- +* WR_REQ_AVG_LAT[9..0] - (RO) req_avg_lat[9:0](long-term average) +* WR_REQ_PEAK_LAT[19..10] - (RO) req_peak_lat[9:0] +* WR_REQ_LAT[29..20] - (RO) req_lat[9:0](shot-term average) +* RESERVED[31..30] - (RO) tied constant +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA0_WR_REQ_LAT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA0_WR_REQ_LAT_MASK \ + 0x3FF00000 /* WR_REQ_LAT[29..20] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA0_WR_REQ_LAT_SHFT 20 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA0_WR_REQ_PEAK_LAT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA0_WR_REQ_PEAK_LAT_MASK \ + 0x000FFC00 /* WR_REQ_PEAK_LAT[19..10] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA0_WR_REQ_PEAK_LAT_SHFT 10 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA0_WR_REQ_AVG_LAT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA0_WR_REQ_AVG_LAT_MASK \ + 0x000003FF /* WR_REQ_AVG_LAT[9..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA0_WR_REQ_AVG_LAT_SHFT 0 + +/* +* ---WPDMA_AXI_MTR_PERF_W_STA1 (0x7C025000 + 0x914)--- +* WR_ACK_AVG_LAT[9..0] - (RO) ack_avg_lat[9:0](long-term average) +* WR_ACK_PEAK_LAT[19..10] - (RO) ack_peak_lat[9:0] +* WR_ACK_LAT[29..20] - (RO) ack_lat[9:0](shot-term average) +* RESERVED[31..30] - (RO) tied constant +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA1_WR_ACK_LAT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA1_WR_ACK_LAT_MASK \ + 0x3FF00000 /* WR_ACK_LAT[29..20] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA1_WR_ACK_LAT_SHFT 20 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA1_WR_ACK_PEAK_LAT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA1_WR_ACK_PEAK_LAT_MASK \ + 0x000FFC00 /* WR_ACK_PEAK_LAT[19..10] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA1_WR_ACK_PEAK_LAT_SHFT 10 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA1_WR_ACK_AVG_LAT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA1_WR_ACK_AVG_LAT_MASK \ + 0x000003FF /* WR_ACK_AVG_LAT[9..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA1_WR_ACK_AVG_LAT_SHFT 0 + +/* +* ---WPDMA_AXI_MTR_PERF_W_STA2 (0x7C025000 + 0x918)--- +* WR_BW[9..0] - (RO) bw[9:0](long-term average) +* WR_PEAK_BW[19..10] - (RO) peak_bw[9:0] +* WR_AVG_BW[29..20] - (RO) avg_bw[9:0](shot-term average) +* RESERVED[31..30] - (RO) tied constant +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA2_WR_AVG_BW_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA2_WR_AVG_BW_MASK \ + 0x3FF00000 /* WR_AVG_BW[29..20] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA2_WR_AVG_BW_SHFT 20 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA2_WR_PEAK_BW_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA2_WR_PEAK_BW_MASK \ + 0x000FFC00 /* WR_PEAK_BW[19..10] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA2_WR_PEAK_BW_SHFT 10 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA2_WR_BW_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA2_WR_BW_MASK \ + 0x000003FF /* WR_BW[9..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA2_WR_BW_SHFT 0 + +/* +* ---WPDMA_AXI_MTR_PERF_W_STA3 (0x7C025000 + 0x91C)--- +* WR_LAT[9..0] - (RO) lat[9:0](long-term average) +* WR_PEAK_LAT[19..10] - (RO) peak_lat[9:0] +* WR_AVG_LAT[29..20] - (RO) avg_lat[9:0](shot-term average) +* RESERVED[31..30] - (RO) tied constant +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA3_WR_AVG_LAT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA3_WR_AVG_LAT_MASK \ + 0x3FF00000 /* WR_AVG_LAT[29..20] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA3_WR_AVG_LAT_SHFT 20 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA3_WR_PEAK_LAT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA3_WR_PEAK_LAT_MASK \ + 0x000FFC00 /* WR_PEAK_LAT[19..10] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA3_WR_PEAK_LAT_SHFT 10 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA3_WR_LAT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA3_WR_LAT_MASK \ + 0x000003FF /* WR_LAT[9..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_W_STA3_WR_LAT_SHFT 0 + +/* +* ---WPDMA_AXI_MTR_PERF_R_STA0 (0x7C025000 + 0x920)--- +* RD_REQ_AVG_LAT[9..0] - (RO) req_avg_lat[9:0](long-term average) +* RD_REQ_PEAK_LAT[19..10] - (RO) req_peak_lat[9:0] +* RD_REQ_LAT[29..20] - (RO) req_lat[9:0](shot-term average) +* RESERVED[31..30] - (RO) tied constant +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA0_RD_REQ_LAT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA0_RD_REQ_LAT_MASK \ + 0x3FF00000 /* RD_REQ_LAT[29..20] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA0_RD_REQ_LAT_SHFT 20 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA0_RD_REQ_PEAK_LAT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA0_RD_REQ_PEAK_LAT_MASK \ + 0x000FFC00 /* RD_REQ_PEAK_LAT[19..10] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA0_RD_REQ_PEAK_LAT_SHFT 10 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA0_RD_REQ_AVG_LAT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA0_RD_REQ_AVG_LAT_MASK \ + 0x000003FF /* RD_REQ_AVG_LAT[9..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA0_RD_REQ_AVG_LAT_SHFT 0 + +/* +* ---WPDMA_AXI_MTR_PERF_R_STA1 (0x7C025000 + 0x924)--- +* RD_ACK_AVG_LAT[9..0] - (RO) ack_avg_lat[9:0](long-term average) +* RD_ACK_PEAK_LAT[19..10] - (RO) ack_peak_lat[9:0] +* RD_ACK_LAT[29..20] - (RO) ack_lat[9:0](shot-term average) +* RESERVED[31..30] - (RO) tied constant +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA1_RD_ACK_LAT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA1_RD_ACK_LAT_MASK \ + 0x3FF00000 /* RD_ACK_LAT[29..20] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA1_RD_ACK_LAT_SHFT 20 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA1_RD_ACK_PEAK_LAT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA1_RD_ACK_PEAK_LAT_MASK \ + 0x000FFC00 /* RD_ACK_PEAK_LAT[19..10] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA1_RD_ACK_PEAK_LAT_SHFT 10 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA1_RD_ACK_AVG_LAT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA1_RD_ACK_AVG_LAT_MASK \ + 0x000003FF /* RD_ACK_AVG_LAT[9..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA1_RD_ACK_AVG_LAT_SHFT 0 + +/* +* ---WPDMA_AXI_MTR_PERF_R_STA2 (0x7C025000 + 0x928)--- +* RD_BW[9..0] - (RO) bw[9:0](long-term average) +* RD_PEAK_BW[19..10] - (RO) peak_bw[9:0] +* RD_AVG_BW[29..20] - (RO) avg_bw[9:0](shot-term average) +* RESERVED[31..30] - (RO) tied constant +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA2_RD_AVG_BW_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA2_RD_AVG_BW_MASK \ + 0x3FF00000 /* RD_AVG_BW[29..20] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA2_RD_AVG_BW_SHFT 20 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA2_RD_PEAK_BW_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA2_RD_PEAK_BW_MASK \ + 0x000FFC00 /* RD_PEAK_BW[19..10] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA2_RD_PEAK_BW_SHFT 10 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA2_RD_BW_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA2_RD_BW_MASK \ + 0x000003FF /* RD_BW[9..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA2_RD_BW_SHFT 0 + +/* +* ---WPDMA_AXI_MTR_PERF_R_STA3 (0x7C025000 + 0x92C)--- +* RD_LAT[9..0] - (RO) lat[9:0](long-term average) +* RD_PEAK_LAT[19..10] - (RO) peak_lat[9:0] +* RD_AVG_LAT[29..20] - (RO) avg_lat[9:0](shot-term average) +* RESERVED[31..30] - (RO) tied constant +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA3_RD_AVG_LAT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA3_RD_AVG_LAT_MASK \ + 0x3FF00000 /* RD_AVG_LAT[29..20] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA3_RD_AVG_LAT_SHFT 20 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA3_RD_PEAK_LAT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA3_RD_PEAK_LAT_MASK \ + 0x000FFC00 /* RD_PEAK_LAT[19..10] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA3_RD_PEAK_LAT_SHFT 10 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA3_RD_LAT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA3_RD_LAT_MASK \ + 0x000003FF /* RD_LAT[9..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_PERF_R_STA3_RD_LAT_SHFT 0 + +/* +* ---WPDMA_AXI_MTR_DBG_OUT0 (0x7C025000 + 0x930)--- +* AXI_AW_CH_COUNTER[7..0] - (RO) axi_aw_ch_counter[7:0] +* AXI_W_CH_COUNTER[15..8] - (RO) axi_w_ch_counter[7:0] +* AXI_B_CH_COUNTER[23..16] - (RO) axi_b_ch_counter[7:0] +* AXI_AR_CH_COUNTER[31..24] - (RO) axi_ar_ch_counter[7:0] +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT0_AXI_AR_CH_COUNTER_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT0_AXI_AR_CH_COUNTER_MASK \ + 0xFF000000 /* AXI_AR_CH_COUNTER[31..24] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT0_AXI_AR_CH_COUNTER_SHFT 24 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT0_AXI_B_CH_COUNTER_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT0_AXI_B_CH_COUNTER_MASK \ + 0x00FF0000 /* AXI_B_CH_COUNTER[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT0_AXI_B_CH_COUNTER_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT0_AXI_W_CH_COUNTER_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT0_AXI_W_CH_COUNTER_MASK \ + 0x0000FF00 /* AXI_W_CH_COUNTER[15..8] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT0_AXI_W_CH_COUNTER_SHFT 8 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT0_AXI_AW_CH_COUNTER_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT0_AXI_AW_CH_COUNTER_MASK \ + 0x000000FF /* AXI_AW_CH_COUNTER[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT0_AXI_AW_CH_COUNTER_SHFT 0 + +/* +* ---WPDMA_AXI_MTR_DBG_OUT1 (0x7C025000 + 0x934)--- +* AXI_R_CH_COUNTER[7..0] - (RO) axi_r_ch_counter[7:0] +* AW_CURRENT_LEN[15..8] - (RO) aw_current_len[8:0] +* AR_CURRENT_LEN[23..16] - (RO) ar_current_len[8:0] +* RESERVED[31..24] - (RO) tied constant +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT1_AR_CURRENT_LEN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT1_AR_CURRENT_LEN_MASK \ + 0x00FF0000 /* AR_CURRENT_LEN[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT1_AR_CURRENT_LEN_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT1_AW_CURRENT_LEN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT1_AW_CURRENT_LEN_MASK \ + 0x0000FF00 /* AW_CURRENT_LEN[15..8] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT1_AW_CURRENT_LEN_SHFT 8 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT1_AXI_R_CH_COUNTER_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT1_AXI_R_CH_COUNTER_MASK \ + 0x000000FF /* AXI_R_CH_COUNTER[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT1_AXI_R_CH_COUNTER_SHFT 0 + +/* +* ---WPDMA_AXI_MTR_DBG_OUT2 (0x7C025000 + 0x938)--- +* AWVALID[0] - (RO) awvalid +* AWREADY[1] - (RO) awready +* WVALID[2] - (RO) wvalid +* WREADY[3] - (RO) wready +* BVALID[4] - (RO) bvalid +* BREADY[5] - (RO) bready +* ARVALID[6] - (RO) arvalid +* ARREADY[7] - (RO) arready +* RVALID[8] - (RO) rvalid +* RREADY[9] - (RO) rready +* RESERVED10[31..10] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT2_RREADY_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT2_RREADY_MASK \ + 0x00000200 /* RREADY[9] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT2_RREADY_SHFT 9 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT2_RVALID_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT2_RVALID_MASK \ + 0x00000100 /* RVALID[8] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT2_RVALID_SHFT 8 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT2_ARREADY_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT2_ARREADY_MASK \ + 0x00000080 /* ARREADY[7] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT2_ARREADY_SHFT 7 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT2_ARVALID_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT2_ARVALID_MASK \ + 0x00000040 /* ARVALID[6] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT2_ARVALID_SHFT 6 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT2_BREADY_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT2_BREADY_MASK \ + 0x00000020 /* BREADY[5] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT2_BREADY_SHFT 5 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT2_BVALID_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT2_BVALID_MASK \ + 0x00000010 /* BVALID[4] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT2_BVALID_SHFT 4 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT2_WREADY_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT2_WREADY_MASK \ + 0x00000008 /* WREADY[3] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT2_WREADY_SHFT 3 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT2_WVALID_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT2_WVALID_MASK \ + 0x00000004 /* WVALID[2] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT2_WVALID_SHFT 2 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT2_AWREADY_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT2_AWREADY_MASK \ + 0x00000002 /* AWREADY[1] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT2_AWREADY_SHFT 1 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT2_AWVALID_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT2_AWVALID_MASK \ + 0x00000001 /* AWVALID[0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT2_AWVALID_SHFT 0 + +/* +* ---WPDMA_AXI_MTR_DBG_OUT3 (0x7C025000 + 0x93C)--- +* AR_CURRENT_ADDRESS[31..0] - (RO) ar_current_address[31:0] +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT3_AR_CURRENT_ADDRESS_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT3_AR_CURRENT_ADDRESS_MASK \ + 0xFFFFFFFF /* AR_CURRENT_ADDRESS[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT3_AR_CURRENT_ADDRESS_SHFT 0 + +/* +* ---WPDMA_AXI_MTR_DBG_OUT4 (0x7C025000 + 0x940)--- +* AW_CURRENT_ADDRESS[31..0] - (RO) aw_current_address[31:0] +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT4_AW_CURRENT_ADDRESS_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT4_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT4_AW_CURRENT_ADDRESS_MASK \ + 0xFFFFFFFF /* AW_CURRENT_ADDRESS[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT4_AW_CURRENT_ADDRESS_SHFT 0 + +/* +* ---WPDMA_AXI_MTR_DBG_OUT5 (0x7C025000 + 0x944)--- +* AR_CURRENT_ADDRESS_EXT[3..0] - (RO) ar_current_address[35:32] +* RESERVED4[15..4] - (RO) Reserved bits +* AW_CURRENT_ADDRESS_EXT[19..16] - (RO) aw_current_address[35:32] +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT5_AW_CURRENT_ADDRESS_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT5_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT5_AW_CURRENT_ADDRESS_EXT_MASK \ + 0x000F0000 /* AW_CURRENT_ADDRESS_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT5_AW_CURRENT_ADDRESS_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT5_AR_CURRENT_ADDRESS_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT5_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT5_AR_CURRENT_ADDRESS_EXT_MASK \ + 0x0000000F /* AR_CURRENT_ADDRESS_EXT[3..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MTR_DBG_OUT5_AR_CURRENT_ADDRESS_EXT_SHFT 0 + +/* +* ---WPDMA_AXI_MST_SLEEP_STA0 (0x7C025000 + 0x980)--- +* tx_pfet_cmd_state_idle[0] - (RO) cmd_state_idle +* tx_pfet_ar_cs_idle[1] - (RO) ar_cs_idle +* tx_pfet_axi_dp_cs_idle[2] - (RO) axi_dp_cs_idle +* tx_pfet_ar_cs_sleep[3] - (RO) ar_cs_sleep +* tx_pfet_buf_empty_axi_outstanding[4] - (RO) buf_empty(axi_outstanding) +* tx_pfet_data_fifo_empty[5] - (RO) data_fifo_empty +* RESERVED6[7..6] - (RO) Reserved bits +* tx_pfet_dma_req_fifo_empty[8] - (RO) dma_req_fifo_empty +* tx_pfet_axi_req_fifo_empty[9] - (RO) axi_req_fifo_empty +* tx_pfet_axi_pkt_fifo_empty[10] - (RO) axi_pkt_fifo_empty +* RESERVED11[11] - (RO) Reserved bits +* tx_pfet_axi_outstanding_req[15..12] - (RO) current pipelined +* axi_outstanding_req number +* pf_dfet_rx_cmd_state_idle[16] - (RO) cmd_state_idle +* pf_dfet_rx_ar_cs_idle[17] - (RO) ar_cs_idle +* pf_dfet_rx_axi_dp_cs_idle[18] - (RO) axi_dp_cs_idle +* pf_dfet_rx_ar_cs_sleep[19] - (RO) ar_cs_sleep +* pf_dfet_rx_buf_empty_axi_outstanding[20] - (RO) buf_empty(axi_outstanding) +* RESERVED21[23..21] - (RO) Reserved bits +* pf_dfet_rx_dma_req_fifo_empty[24] - (RO) dma_req_fifo_empty +* pf_dfet_rx_axi_req_fifo_empty[25] - (RO) axi_req_fifo_empty +* pf_dfet_rx_axi_pkt_fifo_empty[26] - (RO) axi_pkt_fifo_empty +* RESERVED27[27] - (RO) Reserved bits +* pf_dfet_rx_axi_outstanding_req[31..28] - (RO) current pipelined +* axi_outstanding_req number +*/ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_axi_outstanding_req_ADDR\ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_axi_outstanding_req_MASK\ +0xF0000000 /* pf_dfet_rx_axi_outstanding_req[31..28] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_axi_outstanding_req_SHFT\ +28 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_axi_pkt_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_axi_pkt_fifo_empty_MASK \ + 0x04000000 /* pf_dfet_rx_axi_pkt_fifo_empty[26] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_axi_pkt_fifo_empty_SHFT \ + 26 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_axi_req_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_axi_req_fifo_empty_MASK \ + 0x02000000 /* pf_dfet_rx_axi_req_fifo_empty[25] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_axi_req_fifo_empty_SHFT \ + 25 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_dma_req_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_dma_req_fifo_empty_MASK \ + 0x01000000 /* pf_dfet_rx_dma_req_fifo_empty[24] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_dma_req_fifo_empty_SHFT \ + 24 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_buf_empty_axi_outstandin\ +g_ADDR \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_buf_empty_axi_outstandin\ +g_MASK \ +0x00100000 /* pf_dfet_rx_buf_empty_axi_outstanding[20] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_buf_empty_axi_outstandin\ +g_SHFT \ +20 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_ar_cs_sleep_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_ar_cs_sleep_MASK \ + 0x00080000 /* pf_dfet_rx_ar_cs_sleep[19] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_ar_cs_sleep_SHFT \ + 19 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_axi_dp_cs_idle_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_axi_dp_cs_idle_MASK \ + 0x00040000 /* pf_dfet_rx_axi_dp_cs_idle[18] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_axi_dp_cs_idle_SHFT \ + 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_ar_cs_idle_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_ar_cs_idle_MASK \ + 0x00020000 /* pf_dfet_rx_ar_cs_idle[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_ar_cs_idle_SHFT \ + 17 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_cmd_state_idle_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_cmd_state_idle_MASK \ + 0x00010000 /* pf_dfet_rx_cmd_state_idle[16] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_pf_dfet_rx_cmd_state_idle_SHFT \ + 16 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_axi_outstanding_req_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_axi_outstanding_req_MASK \ + 0x0000F000 /* tx_pfet_axi_outstanding_req[15..12] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_axi_outstanding_req_SHFT \ + 12 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_axi_pkt_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_axi_pkt_fifo_empty_MASK \ + 0x00000400 /* tx_pfet_axi_pkt_fifo_empty[10] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_axi_pkt_fifo_empty_SHFT \ + 10 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_axi_req_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_axi_req_fifo_empty_MASK \ + 0x00000200 /* tx_pfet_axi_req_fifo_empty[9] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_axi_req_fifo_empty_SHFT \ + 9 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_dma_req_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_dma_req_fifo_empty_MASK \ + 0x00000100 /* tx_pfet_dma_req_fifo_empty[8] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_dma_req_fifo_empty_SHFT \ + 8 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_data_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_data_fifo_empty_MASK \ + 0x00000020 /* tx_pfet_data_fifo_empty[5] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_data_fifo_empty_SHFT \ + 5 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_buf_empty_axi_outstanding_A\ +DDR \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_buf_empty_axi_outstanding_M\ +ASK \ +0x00000010 /* tx_pfet_buf_empty_axi_outstanding[4] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_buf_empty_axi_outstanding_S\ +HFT \ +4 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_ar_cs_sleep_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_ar_cs_sleep_MASK \ + 0x00000008 /* tx_pfet_ar_cs_sleep[3] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_ar_cs_sleep_SHFT 3 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_axi_dp_cs_idle_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_axi_dp_cs_idle_MASK \ + 0x00000004 /* tx_pfet_axi_dp_cs_idle[2] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_axi_dp_cs_idle_SHFT \ + 2 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_ar_cs_idle_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_ar_cs_idle_MASK \ + 0x00000002 /* tx_pfet_ar_cs_idle[1] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_ar_cs_idle_SHFT 1 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_cmd_state_idle_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_cmd_state_idle_MASK \ + 0x00000001 /* tx_pfet_cmd_state_idle[0] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA0_tx_pfet_cmd_state_idle_SHFT \ + 0 + +/* +* ---WPDMA_AXI_MST_SLEEP_STA1 (0x7C025000 + 0x984)--- +* pf_dfet_tx_cmd_state_idle[0] - (RO) cmd_state_idle +* pf_dfet_tx_ar_cs_idle[1] - (RO) ar_cs_idle +* pf_dfet_tx_axi_dp_cs_idle[2] - (RO) axi_dp_cs_idle +* pf_dfet_tx_ar_cs_sleep[3] - (RO) ar_cs_sleep +* pf_dfet_tx_buf_empty_axi_outstanding[4] - (RO) buf_empty(axi_outstanding) +* RESERVED5[7..5] - (RO) Reserved bits +* pf_dfet_tx_dma_req_fifo_empty[8] - (RO) dma_req_fifo_empty +* pf_dfet_tx_axi_req_fifo_empty[9] - (RO) axi_req_fifo_empty +* pf_dfet_tx_axi_pkt_fifo_empty[10] - (RO) axi_pkt_fifo_empty +* RESERVED11[11] - (RO) Reserved bits +* pf_dfet_tx_axi_outstanding_req[15..12] - (RO) current pipelined +* axi_outstanding_req number +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_axi_outstanding_req_ADDR\ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA1_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_axi_outstanding_req_MASK\ +0x0000F000 /* pf_dfet_tx_axi_outstanding_req[15..12] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_axi_outstanding_req_SHFT\ +12 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_axi_pkt_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA1_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_axi_pkt_fifo_empty_MASK \ + 0x00000400 /* pf_dfet_tx_axi_pkt_fifo_empty[10] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_axi_pkt_fifo_empty_SHFT \ + 10 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_axi_req_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA1_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_axi_req_fifo_empty_MASK \ + 0x00000200 /* pf_dfet_tx_axi_req_fifo_empty[9] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_axi_req_fifo_empty_SHFT \ + 9 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_dma_req_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA1_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_dma_req_fifo_empty_MASK \ + 0x00000100 /* pf_dfet_tx_dma_req_fifo_empty[8] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_dma_req_fifo_empty_SHFT \ + 8 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_buf_empty_axi_outstandin\ +g_ADDR \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA1_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_buf_empty_axi_outstandin\ +g_MASK \ +0x00000010 /* pf_dfet_tx_buf_empty_axi_outstanding[4] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_buf_empty_axi_outstandin\ +g_SHFT \ +4 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_ar_cs_sleep_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA1_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_ar_cs_sleep_MASK \ + 0x00000008 /* pf_dfet_tx_ar_cs_sleep[3] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_ar_cs_sleep_SHFT \ + 3 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_axi_dp_cs_idle_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA1_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_axi_dp_cs_idle_MASK \ + 0x00000004 /* pf_dfet_tx_axi_dp_cs_idle[2] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_axi_dp_cs_idle_SHFT \ + 2 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_ar_cs_idle_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_ar_cs_idle_MASK \ + 0x00000002 /* pf_dfet_tx_ar_cs_idle[1] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_ar_cs_idle_SHFT 1 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_cmd_state_idle_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA1_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_cmd_state_idle_MASK \ + 0x00000001 /* pf_dfet_tx_cmd_state_idle[0] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA1_pf_dfet_tx_cmd_state_idle_SHFT \ + 0 + +/* +* ---WPDMA_AXI_MST_SLEEP_STA2 (0x7C025000 + 0x988)--- +* rx_pfet_cmd_state_idle[0] - (RO) cmd_state_idle +* rx_pfet_aw_cs_idle[1] - (RO) aw_cs_idle +* rx_pfet_axi_dp_cs_idle[2] - (RO) axi_dp_cs_idle +* rx_pfet_aw_cs_sleep[3] - (RO) aw_cs_sleep +* rx_pfet_buf_empty_axi_outstanding[4] - (RO) buf_empty(axi_outstanding) +* rx_pfet_data_fifo_empty[5] - (RO) data_fifo_empty +* rx_pfet_rx_axi_bid_fifo_empty[6] - (RO) axi_bid_fifo_empty +* RESERVED7[7] - (RO) Reserved bits +* rx_pfet_dma_req_fifo_empty[8] - (RO) dma_req_fifo_empty +* rx_pfet_axi_req_fifo_empty[9] - (RO) axi_req_fifo_empty +* rx_pfet_axi_pkt_fifo_empty[10] - (RO) axi_pkt_fifo_empty +* RESERVED11[11] - (RO) Reserved bits +* rx_pfet_axi_outstanding_req[15..12] - (RO) current pipelined +* axi_outstanding_req number +* wb_dfet_rx_cmd_state_idle[16] - (RO) cmd_state_idle +* wb_dfet_rx_aw_cs_idle[17] - (RO) aw_cs_idle +* wb_dfet_rx_axi_dp_cs_idle[18] - (RO) axi_dp_cs_idle +* wb_dfet_rx_aw_cs_sleep[19] - (RO) aw_cs_sleep +* wb_dfet_rx_buf_empty_axi_outstanding[20] - (RO) buf_empty(axi_outstanding) +* wb_dfet_rx_axi_data_fifo_empty[21] - (RO) axi_data_fifo_empty +* wb_dfet_rx_axi_bid_fifo_empty[22] - (RO) axi_bid_fifo_empty +* RESERVED23[23] - (RO) Reserved bits +* wb_dfet_rx_dma_req_fifo_empty[24] - (RO) dma_req_fifo_empty +* wb_dfet_rx_axi_req_fifo_empty[25] - (RO) axi_req_fifo_empty +* wb_dfet_rx_axi_pkt_fifo_empty[26] - (RO) axi_pkt_fifo_empty +* RESERVED27[27] - (RO) Reserved bits +* wb_dfet_rx_axi_outstanding_req[31..28] - (RO) current pipelined +* axi_outstanding_req number +*/ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_axi_outstanding_req_ADDR\ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_axi_outstanding_req_MASK\ +0xF0000000 /* wb_dfet_rx_axi_outstanding_req[31..28] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_axi_outstanding_req_SHFT\ +28 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_axi_pkt_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_axi_pkt_fifo_empty_MASK \ + 0x04000000 /* wb_dfet_rx_axi_pkt_fifo_empty[26] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_axi_pkt_fifo_empty_SHFT \ + 26 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_axi_req_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_axi_req_fifo_empty_MASK \ + 0x02000000 /* wb_dfet_rx_axi_req_fifo_empty[25] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_axi_req_fifo_empty_SHFT \ + 25 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_dma_req_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_dma_req_fifo_empty_MASK \ + 0x01000000 /* wb_dfet_rx_dma_req_fifo_empty[24] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_dma_req_fifo_empty_SHFT \ + 24 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_axi_bid_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_axi_bid_fifo_empty_MASK \ + 0x00400000 /* wb_dfet_rx_axi_bid_fifo_empty[22] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_axi_bid_fifo_empty_SHFT \ + 22 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_axi_data_fifo_empty_ADDR\ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_axi_data_fifo_empty_MASK\ +0x00200000 /* wb_dfet_rx_axi_data_fifo_empty[21] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_axi_data_fifo_empty_SHFT\ +21 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_buf_empty_axi_outstandin\ +g_ADDR \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_buf_empty_axi_outstandin\ +g_MASK \ +0x00100000 /* wb_dfet_rx_buf_empty_axi_outstanding[20] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_buf_empty_axi_outstandin\ +g_SHFT \ +20 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_aw_cs_sleep_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_aw_cs_sleep_MASK \ + 0x00080000 /* wb_dfet_rx_aw_cs_sleep[19] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_aw_cs_sleep_SHFT \ + 19 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_axi_dp_cs_idle_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_axi_dp_cs_idle_MASK \ + 0x00040000 /* wb_dfet_rx_axi_dp_cs_idle[18] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_axi_dp_cs_idle_SHFT \ + 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_aw_cs_idle_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_aw_cs_idle_MASK \ + 0x00020000 /* wb_dfet_rx_aw_cs_idle[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_aw_cs_idle_SHFT \ + 17 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_cmd_state_idle_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_cmd_state_idle_MASK \ + 0x00010000 /* wb_dfet_rx_cmd_state_idle[16] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_wb_dfet_rx_cmd_state_idle_SHFT \ + 16 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_axi_outstanding_req_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_axi_outstanding_req_MASK \ + 0x0000F000 /* rx_pfet_axi_outstanding_req[15..12] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_axi_outstanding_req_SHFT \ + 12 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_axi_pkt_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_axi_pkt_fifo_empty_MASK \ + 0x00000400 /* rx_pfet_axi_pkt_fifo_empty[10] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_axi_pkt_fifo_empty_SHFT \ + 10 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_axi_req_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_axi_req_fifo_empty_MASK \ + 0x00000200 /* rx_pfet_axi_req_fifo_empty[9] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_axi_req_fifo_empty_SHFT \ + 9 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_dma_req_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_dma_req_fifo_empty_MASK \ + 0x00000100 /* rx_pfet_dma_req_fifo_empty[8] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_dma_req_fifo_empty_SHFT \ + 8 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_rx_axi_bid_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_rx_axi_bid_fifo_empty_MASK \ + 0x00000040 /* rx_pfet_rx_axi_bid_fifo_empty[6] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_rx_axi_bid_fifo_empty_SHFT \ + 6 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_data_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_data_fifo_empty_MASK \ + 0x00000020 /* rx_pfet_data_fifo_empty[5] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_data_fifo_empty_SHFT \ + 5 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_buf_empty_axi_outstanding_A\ +DDR \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_buf_empty_axi_outstanding_M\ +ASK \ +0x00000010 /* rx_pfet_buf_empty_axi_outstanding[4] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_buf_empty_axi_outstanding_S\ +HFT \ +4 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_aw_cs_sleep_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_aw_cs_sleep_MASK \ + 0x00000008 /* rx_pfet_aw_cs_sleep[3] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_aw_cs_sleep_SHFT 3 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_axi_dp_cs_idle_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_axi_dp_cs_idle_MASK \ + 0x00000004 /* rx_pfet_axi_dp_cs_idle[2] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_axi_dp_cs_idle_SHFT \ + 2 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_aw_cs_idle_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_aw_cs_idle_MASK \ + 0x00000002 /* rx_pfet_aw_cs_idle[1] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_aw_cs_idle_SHFT 1 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_cmd_state_idle_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_cmd_state_idle_MASK \ + 0x00000001 /* rx_pfet_cmd_state_idle[0] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA2_rx_pfet_cmd_state_idle_SHFT \ + 0 + +/* +* ---WPDMA_AXI_MST_SLEEP_STA3 (0x7C025000 + 0x98C)--- +* wb_dfet_tx_cmd_state_idle[0] - (RO) cmd_state_idle +* wb_dfet_tx_aw_cs_idle[1] - (RO) aw_cs_idle +* wb_dfet_tx_axi_dp_cs_idle[2] - (RO) axi_dp_cs_idle +* wb_dfet_tx_aw_cs_sleep[3] - (RO) aw_cs_sleep +* wb_dfet_tx_buf_empty_axi_outstanding[4] - (RO) buf_empty(axi_outstanding) +* wb_dfet_tx_axi_data_fifo_empty[5] - (RO) axi_data_fifo_empty +* wb_dfet_rx_axi_bid_fifo_empty[6] - (RO) axi_bid_fifo_empty +* RESERVED7[7] - (RO) Reserved bits +* wb_dfet_tx_dma_req_fifo_empty[8] - (RO) dma_req_fifo_empty +* wb_dfet_tx_axi_req_fifo_empty[9] - (RO) axi_req_fifo_empty +* wb_dfet_tx_axi_pkt_fifo_empty[10] - (RO) axi_pkt_fifo_empty +* RESERVED11[11] - (RO) Reserved bits +* wb_dfet_tx_axi_outstanding_req[15..12] - (RO) current pipelined +* axi_outstanding_req number +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_axi_outstanding_req_ADDR\ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_axi_outstanding_req_MASK\ +0x0000F000 /* wb_dfet_tx_axi_outstanding_req[15..12] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_axi_outstanding_req_SHFT\ +12 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_axi_pkt_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_axi_pkt_fifo_empty_MASK \ + 0x00000400 /* wb_dfet_tx_axi_pkt_fifo_empty[10] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_axi_pkt_fifo_empty_SHFT \ + 10 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_axi_req_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_axi_req_fifo_empty_MASK \ + 0x00000200 /* wb_dfet_tx_axi_req_fifo_empty[9] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_axi_req_fifo_empty_SHFT \ + 9 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_dma_req_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_dma_req_fifo_empty_MASK \ + 0x00000100 /* wb_dfet_tx_dma_req_fifo_empty[8] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_dma_req_fifo_empty_SHFT \ + 8 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_rx_axi_bid_fifo_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_rx_axi_bid_fifo_empty_MASK \ + 0x00000040 /* wb_dfet_rx_axi_bid_fifo_empty[6] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_rx_axi_bid_fifo_empty_SHFT \ + 6 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_axi_data_fifo_empty_ADDR\ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_axi_data_fifo_empty_MASK\ +0x00000020 /* wb_dfet_tx_axi_data_fifo_empty[5] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_axi_data_fifo_empty_SHFT\ +5 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_buf_empty_axi_outstandin\ +g_ADDR \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_buf_empty_axi_outstandin\ +g_MASK \ +0x00000010 /* wb_dfet_tx_buf_empty_axi_outstanding[4] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_buf_empty_axi_outstandin\ +g_SHFT \ +4 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_aw_cs_sleep_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_aw_cs_sleep_MASK \ + 0x00000008 /* wb_dfet_tx_aw_cs_sleep[3] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_aw_cs_sleep_SHFT \ + 3 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_axi_dp_cs_idle_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_axi_dp_cs_idle_MASK \ + 0x00000004 /* wb_dfet_tx_axi_dp_cs_idle[2] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_axi_dp_cs_idle_SHFT \ + 2 +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_aw_cs_idle_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_aw_cs_idle_MASK \ + 0x00000002 /* wb_dfet_tx_aw_cs_idle[1] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_aw_cs_idle_SHFT 1 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_cmd_state_idle_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_cmd_state_idle_MASK \ + 0x00000001 /* wb_dfet_tx_cmd_state_idle[0] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA3_wb_dfet_tx_cmd_state_idle_SHFT \ + 0 + +/* +* ---WPDMA_AXI_MST_SLEEP_STA4 (0x7C025000 + 0x990)--- +* RESERVED0[0] - (RO) Reserved bits +* rx_pfet_pld_rx_pfet_sleep_rdy[1] - (RO) pld_rx_pfet_sleep_rdy +* RESERVED2[30..2] - (RO) Reserved bits +* tx_pfet_pld_tx_pfet_sleep_rdy[31] - (RO) pld_tx_pfet_sleep_rdy +*/ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA4_tx_pfet_pld_tx_pfet_sleep_rdy_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA4_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA4_tx_pfet_pld_tx_pfet_sleep_rdy_MASK \ + 0x80000000 /* tx_pfet_pld_tx_pfet_sleep_rdy[31] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA4_tx_pfet_pld_tx_pfet_sleep_rdy_SHFT \ + 31 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA4_rx_pfet_pld_rx_pfet_sleep_rdy_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA4_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA4_rx_pfet_pld_rx_pfet_sleep_rdy_MASK \ + 0x00000002 /* rx_pfet_pld_rx_pfet_sleep_rdy[1] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_AXI_MST_SLEEP_STA4_rx_pfet_pld_rx_pfet_sleep_rdy_SHFT \ + 1 + +/* +* ---WPDMA_TX_RING0_BKRS_CTRL0 (0x7C025000 + 0xA00)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING0_BKRS_CTRL1 (0x7C025000 + 0xA04)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING0_BKRS_CTRL2 (0x7C025000 + 0xA08)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING1_BKRS_CTRL0 (0x7C025000 + 0xA10)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING1_BKRS_CTRL1 (0x7C025000 + 0xA14)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING1_BKRS_CTRL2 (0x7C025000 + 0xA18)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING2_BKRS_CTRL0 (0x7C025000 + 0xA20)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING2_BKRS_CTRL1 (0x7C025000 + 0xA24)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING2_BKRS_CTRL2 (0x7C025000 + 0xA28)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING3_BKRS_CTRL0 (0x7C025000 + 0xA30)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING3_BKRS_CTRL1 (0x7C025000 + 0xA34)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING3_BKRS_CTRL2 (0x7C025000 + 0xA38)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING4_BKRS_CTRL0 (0x7C025000 + 0xA40)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING4_BKRS_CTRL1 (0x7C025000 + 0xA44)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING4_BKRS_CTRL2 (0x7C025000 + 0xA48)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING5_BKRS_CTRL0 (0x7C025000 + 0xA50)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING5_BKRS_CTRL1 (0x7C025000 + 0xA54)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING5_BKRS_CTRL2 (0x7C025000 + 0xA58)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING6_BKRS_CTRL0 (0x7C025000 + 0xA60)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING6_BKRS_CTRL1 (0x7C025000 + 0xA64)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING6_BKRS_CTRL2 (0x7C025000 + 0xA68)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING7_BKRS_CTRL0 (0x7C025000 + 0xA70)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING7_BKRS_CTRL1 (0x7C025000 + 0xA74)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING7_BKRS_CTRL2 (0x7C025000 + 0xA78)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING8_BKRS_CTRL0 (0x7C025000 + 0xA80)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING8_BKRS_CTRL1 (0x7C025000 + 0xA84)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING8_BKRS_CTRL2 (0x7C025000 + 0xA88)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING9_BKRS_CTRL0 (0x7C025000 + 0xA90)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING9_BKRS_CTRL1 (0x7C025000 + 0xA94)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING9_BKRS_CTRL2 (0x7C025000 + 0xA98)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING10_BKRS_CTRL0 (0x7C025000 + 0xAA0)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING10_BKRS_CTRL1 (0x7C025000 + 0xAA4)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING10_BKRS_CTRL2 (0x7C025000 + 0xAA8)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING11_BKRS_CTRL0 (0x7C025000 + 0xAB0)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING11_BKRS_CTRL1 (0x7C025000 + 0xAB4)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING11_BKRS_CTRL2 (0x7C025000 + 0xAB8)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING12_BKRS_CTRL0 (0x7C025000 + 0xAC0)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING12_BKRS_CTRL1 (0x7C025000 + 0xAC4)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING12_BKRS_CTRL2 (0x7C025000 + 0xAC8)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING13_BKRS_CTRL0 (0x7C025000 + 0xAD0)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING13_BKRS_CTRL1 (0x7C025000 + 0xAD4)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING13_BKRS_CTRL2 (0x7C025000 + 0xAD8)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING14_BKRS_CTRL0 (0x7C025000 + 0xAE0)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING14_BKRS_CTRL1 (0x7C025000 + 0xAE4)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING14_BKRS_CTRL2 (0x7C025000 + 0xAE8)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING15_BKRS_CTRL0 (0x7C025000 + 0xAF0)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING15_BKRS_CTRL1 (0x7C025000 + 0xAF4)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING15_BKRS_CTRL2 (0x7C025000 + 0xAF8)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING176_BKRS_CTRL0 (0x7C025000 + 0xB00)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING176_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING176_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING176_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING176_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING176_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING176_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING176_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING176_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING176_BKRS_CTRL1 (0x7C025000 + 0xB04)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING176_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING176_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING176_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING176_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING176_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING176_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING176_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING176_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING176_BKRS_CTRL2 (0x7C025000 + 0xB08)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING176_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING176_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING176_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING176_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING176_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING176_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING176_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING176_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING176_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING176_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING176_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING176_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING176_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING176_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING176_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING176_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING176_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING176_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING176_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING176_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING17_BKRS_CTRL0 (0x7C025000 + 0xB10)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING17_BKRS_CTRL1 (0x7C025000 + 0xB14)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING17_BKRS_CTRL2 (0x7C025000 + 0xB18)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING18_BKRS_CTRL0 (0x7C025000 + 0xB20)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING18_BKRS_CTRL1 (0x7C025000 + 0xB24)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING18_BKRS_CTRL2 (0x7C025000 + 0xB28)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING19_BKRS_CTRL0 (0x7C025000 + 0xB30)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING19_BKRS_CTRL1 (0x7C025000 + 0xB34)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING19_BKRS_CTRL2 (0x7C025000 + 0xB38)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING20_BKRS_CTRL0 (0x7C025000 + 0xB40)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING20_BKRS_CTRL1 (0x7C025000 + 0xB44)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING20_BKRS_CTRL2 (0x7C025000 + 0xB48)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING20_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING21_BKRS_CTRL0 (0x7C025000 + 0xB50)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING21_BKRS_CTRL1 (0x7C025000 + 0xB54)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING21_BKRS_CTRL2 (0x7C025000 + 0xB58)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING21_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING22_BKRS_CTRL0 (0x7C025000 + 0xB60)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING22_BKRS_CTRL1 (0x7C025000 + 0xB64)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING22_BKRS_CTRL2 (0x7C025000 + 0xB68)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING22_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING23_BKRS_CTRL0 (0x7C025000 + 0xB70)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING23_BKRS_CTRL1 (0x7C025000 + 0xB74)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING23_BKRS_CTRL2 (0x7C025000 + 0xB78)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING23_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING0_BKRS_CTRL0 (0x7C025000 + 0xC00)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING0_BKRS_CTRL1 (0x7C025000 + 0xC04)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING0_BKRS_CTRL2 (0x7C025000 + 0xC08)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING1_BKRS_CTRL0 (0x7C025000 + 0xC10)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING1_BKRS_CTRL1 (0x7C025000 + 0xC14)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING1_BKRS_CTRL2 (0x7C025000 + 0xC18)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING2_BKRS_CTRL0 (0x7C025000 + 0xC20)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING2_BKRS_CTRL1 (0x7C025000 + 0xC24)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING2_BKRS_CTRL2 (0x7C025000 + 0xC28)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING3_BKRS_CTRL0 (0x7C025000 + 0xC30)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING3_BKRS_CTRL1 (0x7C025000 + 0xC34)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING3_BKRS_CTRL2 (0x7C025000 + 0xC38)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +#ifdef __cplusplus +} +#endif + +#endif /* __WF_WFDMA_HOST_DMA1_REGS_H__ */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/mt7961/wf_cr_sw_def.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/mt7961/wf_cr_sw_def.h new file mode 100644 index 0000000000000000000000000000000000000000..8523ee383292e7fe38a0bed188b0ee3bc20fa896 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/mt7961/wf_cr_sw_def.h @@ -0,0 +1,93 @@ +/* [File] : wf_cr_sw_def.h */ +/* [Copyright] : Copyright (C) 2018 Mediatek Incorportion. All rights reserved. +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +#ifndef _WF_CR_SW_DEF_H +#define _WF_CR_SW_DEF_H + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + + +/****************************************************************************** +* +* MCU_SYSRAM SW CR Definitions +* +****************************************************************************** +*/ +#define WF_SW_DEF_CR_BASE 0x00400E00 + +#define WF_SW_DEF_CR_SER_STATUS_ADDR \ + (WF_SW_DEF_CR_BASE + 0x000) /* E00 */ +#define WF_SW_DEF_CR_PLE_STATUS_ADDR \ + (WF_SW_DEF_CR_BASE + 0x004) /* E04 */ +#define WF_SW_DEF_CR_PLE1_STATUS_ADDR \ + (WF_SW_DEF_CR_BASE + 0x008) /* E08 */ +#define WF_SW_DEF_CR_PLE_AMSDU_STATUS_ADDR \ + (WF_SW_DEF_CR_BASE + 0x00C) /* E0C */ +#define WF_SW_DEF_CR_PSE_STATUS_ADDR \ + (WF_SW_DEF_CR_BASE + 0x010) /* E10 */ +#define WF_SW_DEF_CR_PSE1_STATUS_ADDR \ + (WF_SW_DEF_CR_BASE + 0x014) /* E14 */ +#define WF_SW_DEF_CR_LAMC_WISR6_BN0_STATUS_ADDR \ + (WF_SW_DEF_CR_BASE + 0x018) /* E18 */ +#define WF_SW_DEF_CR_LAMC_WISR6_BN1_STATUS_ADDR \ + (WF_SW_DEF_CR_BASE + 0x01C) /* E1C */ +#define WF_SW_DEF_CR_LAMC_WISR7_BN0_STATUS_ADDR \ + (WF_SW_DEF_CR_BASE + 0x020) /* E20 */ +#define WF_SW_DEF_CR_LAMC_WISR7_BN1_STATUS_ADDR \ + (WF_SW_DEF_CR_BASE + 0x024) /* E24 */ +#define WF_SW_DEF_CR_USB_MCU_EVENT_ADD \ + (WF_SW_DEF_CR_BASE + 0x028) /* E28 */ +#define WF_SW_DEF_CR_USB_HOST_ACK_ADDR \ + (WF_SW_DEF_CR_BASE + 0x02C) /* E2C */ +#define WF_SW_DEF_CR_ICAP_SPECTRUM_MODE_ADDR \ + (WF_SW_DEF_CR_BASE + 0x030) /* E30 */ + +#endif /* _WF_CR_SW_DEF_H */ + + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/mt7961/wf_hif_dmashdl_top.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/mt7961/wf_hif_dmashdl_top.h new file mode 100644 index 0000000000000000000000000000000000000000..5dfea109fb3c40d892d4d1588b4d3c0333d7e085 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/mt7961/wf_hif_dmashdl_top.h @@ -0,0 +1,2356 @@ +/* [File] : wf_hif_dmashdl_top.h */ +/* [Revision time] : Mon Apr 29 11:37:41 2019 */ +/* [Description] : This file is auto generated by CODA */ +/* [Copyright] : Copyright (C) 2019 Mediatek Incorportion. All rights */ +/* reserved. */ + +#ifndef __WF_HIF_DMASHDL_TOP_REGS_H__ +#define __WF_HIF_DMASHDL_TOP_REGS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* ************************************************************************** */ +/* */ +/* WF_HIF_DMASHDL_TOP CR Definitions */ +/* */ +/* ************************************************************************** */ + +#define WF_HIF_DMASHDL_TOP_BASE 0x7C026000 + +#define WF_HIF_DMASHDL_TOP_WACPU_REFILL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x00) /* 6000 */ +#define WF_HIF_DMASHDL_TOP_SW_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x04) /* 6004 */ +#define WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x08) /* 6008 */ +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x0C) /* 600C */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x10) /* 6010 */ +#define WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x14) /* 6014 */ +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x18) /* 6018 */ +#define WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x1c) /* 601C */ +#define WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x20) /* 6020 */ +#define WF_HIF_DMASHDL_TOP_GROUP1_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x24) /* 6024 */ +#define WF_HIF_DMASHDL_TOP_GROUP2_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x28) /* 6028 */ +#define WF_HIF_DMASHDL_TOP_GROUP3_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x2C) /* 602C */ +#define WF_HIF_DMASHDL_TOP_GROUP4_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x30) /* 6030 */ +#define WF_HIF_DMASHDL_TOP_GROUP5_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x34) /* 6034 */ +#define WF_HIF_DMASHDL_TOP_GROUP6_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x38) /* 6038 */ +#define WF_HIF_DMASHDL_TOP_GROUP7_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x3C) /* 603C */ +#define WF_HIF_DMASHDL_TOP_GROUP8_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x40) /* 6040 */ +#define WF_HIF_DMASHDL_TOP_GROUP9_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x44) /* 6044 */ +#define WF_HIF_DMASHDL_TOP_GROUP10_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x48) /* 6048 */ +#define WF_HIF_DMASHDL_TOP_GROUP11_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x4C) /* 604C */ +#define WF_HIF_DMASHDL_TOP_GROUP12_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x50) /* 6050 */ +#define WF_HIF_DMASHDL_TOP_GROUP13_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x54) /* 6054 */ +#define WF_HIF_DMASHDL_TOP_GROUP14_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x58) /* 6058 */ +#define WF_HIF_DMASHDL_TOP_GROUP15_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x5C) /* 605C */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x60) /* 6060 */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x64) /* 6064 */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x68) /* 6068 */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x6c) /* 606C */ +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x70) /* 6070 */ +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x74) /* 6074 */ +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x78) /* 6078 */ +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x7C) /* 607C */ +#define WF_HIF_DMASHDL_TOP_SLOT_PERIOD_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x80) /* 6080 */ +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT00_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0xC0) /* 60C0 */ +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT01_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0xC4) /* 60C4 */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD02_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0xC8) /* 60C8 */ +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0xCC) /* 60CC */ +#define WF_HIF_DMASHDL_TOP_TX_PACKET_SIZE_PAGE_MAP_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0xD0) /* 60D0 */ +#define WF_HIF_DMASHDL_TOP_HIF_ASK_LONG_CHECK_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0xD4) /* 60D4 */ +#define WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0xD8) /* 60D8 */ +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0xDC) /* 60DC */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x100) /* 6100 */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD0_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x110) /* 6110 */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x140) /* 6140 */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP1_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x144) /* 6144 */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP2_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x148) /* 6148 */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP3_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x14c) /* 614C */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP4_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x150) /* 6150 */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP5_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x154) /* 6154 */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP6_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x158) /* 6158 */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP7_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x15C) /* 615C */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP8_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x160) /* 6160 */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP9_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x164) /* 6164 */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP10_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x168) /* 6168 */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP11_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x16c) /* 616C */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP12_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x170) /* 6170 */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP13_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x174) /* 6174 */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP14_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x178) /* 6178 */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP15_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x17C) /* 617C */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT0_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x180) /* 6180 */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT1_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x184) /* 6184 */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT2_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x188) /* 6188 */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT3_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x18c) /* 618C */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT4_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x190) /* 6190 */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT5_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x194) /* 6194 */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT6_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x198) /* 6198 */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT7_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x19c) /* 619C */ + +/* +* ---WACPU_REFILL (0x7C026000 + 0x00)--- +* WACPU_RETURN_PAGE_CNT[11..0] - (RW) WACPU refill page count +* RESERVED12[15..12] - (RO) Reserved bits +* WACPU_RETRUN_QID[20..16] - (RW) WACPU refill queue ID +* RESERVED21[23..21] - (RO) Reserved bits +* WACPU_RETRUN_MODE[25..24] - (RW) WACPU refill mode selection +* 2'b00 : Return mode +* 2'b01 : Add reservation mode(initial quota +setting) +* 2'b10 : Substrate source mode +* 2'b11 : Add source mode +* RESERVED26[30..26] - (RO) Reserved bits +* WACPU_EXCUTE[31] - (WO) Excute this CR action +*/ +#define WF_HIF_DMASHDL_TOP_WACPU_REFILL_WACPU_EXCUTE_ADDR \ + WF_HIF_DMASHDL_TOP_WACPU_REFILL_ADDR +#define WF_HIF_DMASHDL_TOP_WACPU_REFILL_WACPU_EXCUTE_MASK \ + 0x80000000 /* WACPU_EXCUTE[31] */ +#define WF_HIF_DMASHDL_TOP_WACPU_REFILL_WACPU_EXCUTE_SHFT 31 +#define WF_HIF_DMASHDL_TOP_WACPU_REFILL_WACPU_RETRUN_MODE_ADDR \ + WF_HIF_DMASHDL_TOP_WACPU_REFILL_ADDR +#define WF_HIF_DMASHDL_TOP_WACPU_REFILL_WACPU_RETRUN_MODE_MASK \ + 0x03000000 /* WACPU_RETRUN_MODE[25..24] */ +#define WF_HIF_DMASHDL_TOP_WACPU_REFILL_WACPU_RETRUN_MODE_SHFT 24 +#define WF_HIF_DMASHDL_TOP_WACPU_REFILL_WACPU_RETRUN_QID_ADDR \ + WF_HIF_DMASHDL_TOP_WACPU_REFILL_ADDR +#define WF_HIF_DMASHDL_TOP_WACPU_REFILL_WACPU_RETRUN_QID_MASK \ + 0x001F0000 /* WACPU_RETRUN_QID[20..16] */ +#define WF_HIF_DMASHDL_TOP_WACPU_REFILL_WACPU_RETRUN_QID_SHFT 16 +#define WF_HIF_DMASHDL_TOP_WACPU_REFILL_WACPU_RETURN_PAGE_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_WACPU_REFILL_ADDR +#define WF_HIF_DMASHDL_TOP_WACPU_REFILL_WACPU_RETURN_PAGE_CNT_MASK \ + 0x00000FFF /* WACPU_RETURN_PAGE_CNT[11..0] */ +#define WF_HIF_DMASHDL_TOP_WACPU_REFILL_WACPU_RETURN_PAGE_CNT_SHFT 0 + +/* +* ---SW_CONTROL (0x7C026000 + 0x04)--- +* SW_LOG_RESET[0] - (RW) SW reset logic function action +* RESERVED1[27..1] - (RO) Reserved bits +* DMASHDL_BYPASS[28] - (RW) DMASHDL host ask and quota control +* function bypass +* RESERVED29[31..29] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_SW_CONTROL_DMASHDL_BYPASS_ADDR \ + WF_HIF_DMASHDL_TOP_SW_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_SW_CONTROL_DMASHDL_BYPASS_MASK \ + 0x10000000 /* DMASHDL_BYPASS[28] */ +#define WF_HIF_DMASHDL_TOP_SW_CONTROL_DMASHDL_BYPASS_SHFT 28 +#define WF_HIF_DMASHDL_TOP_SW_CONTROL_SW_LOG_RESET_ADDR \ + WF_HIF_DMASHDL_TOP_SW_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_SW_CONTROL_SW_LOG_RESET_MASK \ + 0x00000001 /* SW_LOG_RESET[0] */ +#define WF_HIF_DMASHDL_TOP_SW_CONTROL_SW_LOG_RESET_SHFT 0 + +/* +* ---OPTIONAL_CONTROL (0x7C026000 + 0x08)--- +* CR_HIF_GUP_ACT_MAP[15..0] - (RW) Group active mapping to joint the hif +* ask round robin setting in hif_ack_cnt_th period. +* Bit 0: group 0 joint active setting (1: +* joint, 0: disjoint) +* Bit 1: group 1 joint active setting (1: +* joint, 0: disjoint) +* Bit 2: group 2 joint active setting (1: +* joint, 0: disjoint) +* Bit 3: group 3 joint active setting (1: +* joint, 0: disjoint) +* Bit 4: group 4 joint active setting (1: +* joint, 0: disjoint) +* Bit 5: group 5 joint active setting (1: +* joint, 0: disjoint) +* Bit 6: group 6 joint active setting (1: +* joint, 0: disjoint) +* Bit 7: group 7 joint active setting (1: +* joint, 0: disjoint) +* Bit 8: group 8 joint active setting (1: +* joint, 0: disjoint) +* Bit 9: group 9 joint active setting (1: +* joint, 0: disjoint) +...... +* Bit 15: group 15 joint active setting (1: +* joint, 0: disjoint) +* CR_HIF_ACK_CNT_TH[23..16] - (RW) Host ask success count threshold setting +* to reset initial for round robin period +* RESERVED24[27..24] - (RO) Reserved bits +* CR_HIF_ASK_RR_ENA[28] - (RW) HIF ask round robin like arbiter enable +* CR_HIF_ASK_MIN_RR_ENA[29] - (RW) Source count below minimum quota check +* enable by round robin like arbitration +* CR_PSEBF_BL_TH2_NOBMIN_RASIGN_ENA[30] - (RW) Assignment when all TXD groups +* great or equal minimum quota +* CR_PSEBF_BL_TH2_CHK_DISABLE[31] - (RW) Disable PSE buffer Threshold 2 check +* and assignment +*/ +#define WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_CR_PSEBF_BL_TH2_CHK_DISABLE_ADDR \ + WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_CR_PSEBF_BL_TH2_CHK_DISABLE_MASK \ + 0x80000000 /* CR_PSEBF_BL_TH2_CHK_DISABLE[31] */ +#define WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_CR_PSEBF_BL_TH2_CHK_DISABLE_SHFT 31 +#define \ +WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_CR_PSEBF_BL_TH2_NOBMIN_RASIGN_ENA_ADDR \ + \ + WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_ADDR +#define \ +WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_CR_PSEBF_BL_TH2_NOBMIN_RASIGN_ENA_MASK \ + \ + 0x40000000 /* CR_PSEBF_BL_TH2_NOBMIN_RASIGN_ENA[30] */ +#define \ +WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_CR_PSEBF_BL_TH2_NOBMIN_RASIGN_ENA_SHFT \ + \ + 30 +#define WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_CR_HIF_ASK_MIN_RR_ENA_ADDR \ + WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_CR_HIF_ASK_MIN_RR_ENA_MASK \ + 0x20000000 /* CR_HIF_ASK_MIN_RR_ENA[29] */ +#define WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_CR_HIF_ASK_MIN_RR_ENA_SHFT 29 +#define WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_CR_HIF_ASK_RR_ENA_ADDR \ + WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_CR_HIF_ASK_RR_ENA_MASK \ + 0x10000000 /* CR_HIF_ASK_RR_ENA[28] */ +#define WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_CR_HIF_ASK_RR_ENA_SHFT 28 +#define WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_CR_HIF_ACK_CNT_TH_ADDR \ + WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_CR_HIF_ACK_CNT_TH_MASK \ + 0x00FF0000 /* CR_HIF_ACK_CNT_TH[23..16] */ +#define WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_CR_HIF_ACK_CNT_TH_SHFT 16 +#define WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_CR_HIF_GUP_ACT_MAP_ADDR \ + WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_CR_HIF_GUP_ACT_MAP_MASK \ + 0x0000FFFF /* CR_HIF_GUP_ACT_MAP[15..0] */ +#define WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_CR_HIF_GUP_ACT_MAP_SHFT 0 + +/* +* ---PAGE_SETTING (0x7C026000 + 0x0C)--- +* PSE_ADD_BSIZE[9..0] - (RW) PSE(command) packet size add extra byte +count +* RESERVED10[11..10] - (RO) Reserved bits +* PP_OFFSET_ADD_ENA[12] - (RW) PSE(command) packet size add offset +* enable from packet processor +* RESERVED13[15..13] - (RO) Reserved bits +* GROUP_SEQUENCE_ORDER_TYPE[16] - (RW) User program group sequence type +control +* SLOT_TYPE_ARBITER_CONTROL[17] - (RW) Slot type arbiter control +* DUMMY_00[18] - (RW) Dummy_00 bit +* DUMMY_01[19] - (RW) Dummy_01 bit +* SRC_CNT_PRI_EN[20] - (RW) Source count below min quota first +* priority check enable +* QUP_ACL_SLOT_CG_EN[21] - (RW) Group ack then slot ID change function +enable +* RESERVED22[31..22] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_QUP_ACL_SLOT_CG_EN_ADDR \ + WF_HIF_DMASHDL_TOP_PAGE_SETTING_ADDR +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_QUP_ACL_SLOT_CG_EN_MASK \ + 0x00200000 /* QUP_ACL_SLOT_CG_EN[21] */ +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_QUP_ACL_SLOT_CG_EN_SHFT 21 +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_SRC_CNT_PRI_EN_ADDR \ + WF_HIF_DMASHDL_TOP_PAGE_SETTING_ADDR +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_SRC_CNT_PRI_EN_MASK \ + 0x00100000 /* SRC_CNT_PRI_EN[20] */ +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_SRC_CNT_PRI_EN_SHFT 20 +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_DUMMY_01_ADDR \ + WF_HIF_DMASHDL_TOP_PAGE_SETTING_ADDR +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_DUMMY_01_MASK \ + 0x00080000 /* DUMMY_01[19] */ +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_DUMMY_01_SHFT 19 +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_DUMMY_00_ADDR \ + WF_HIF_DMASHDL_TOP_PAGE_SETTING_ADDR +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_DUMMY_00_MASK \ + 0x00040000 /* DUMMY_00[18] */ +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_DUMMY_00_SHFT 18 +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_SLOT_TYPE_ARBITER_CONTROL_ADDR \ + WF_HIF_DMASHDL_TOP_PAGE_SETTING_ADDR +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_SLOT_TYPE_ARBITER_CONTROL_MASK \ + 0x00020000 /* SLOT_TYPE_ARBITER_CONTROL[17] */ +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_SLOT_TYPE_ARBITER_CONTROL_SHFT 17 +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_GROUP_SEQUENCE_ORDER_TYPE_ADDR \ + WF_HIF_DMASHDL_TOP_PAGE_SETTING_ADDR +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_GROUP_SEQUENCE_ORDER_TYPE_MASK \ + 0x00010000 /* GROUP_SEQUENCE_ORDER_TYPE[16] */ +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_GROUP_SEQUENCE_ORDER_TYPE_SHFT 16 +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_PP_OFFSET_ADD_ENA_ADDR \ + WF_HIF_DMASHDL_TOP_PAGE_SETTING_ADDR +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_PP_OFFSET_ADD_ENA_MASK \ + 0x00001000 /* PP_OFFSET_ADD_ENA[12] */ +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_PP_OFFSET_ADD_ENA_SHFT 12 +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_PSE_ADD_BSIZE_ADDR \ + WF_HIF_DMASHDL_TOP_PAGE_SETTING_ADDR +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_PSE_ADD_BSIZE_MASK \ + 0x000003FF /* PSE_ADD_BSIZE[9..0] */ +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_PSE_ADD_BSIZE_SHFT 0 + +/* +* ---REFILL_CONTROL (0x7C026000 + 0x10)--- +* GROUP0_REFILL_PRIORITY[0] - (RW) Group0 refill priority +* GROUP1_REFILL_PRIORITY[1] - (RW) Group1 refill priority +* GROUP2_REFILL_PRIORITY[2] - (RW) Group2 refill priority +* GROUP3_REFILL_PRIORITY[3] - (RW) Group3 refill priority +* GROUP4_REFILL_PRIORITY[4] - (RW) Group4 refill priority +* GROUP5_REFILL_PRIORITY[5] - (RW) Group5 refill priority +* GROUP6_REFILL_PRIORITY[6] - (RW) Group6 refill priority +* GROUP7_REFILL_PRIORITY[7] - (RW) Group7 refill priority +* GROUP8_REFILL_PRIORITY[8] - (RW) Group8 refill priority +* GROUP9_REFILL_PRIORITY[9] - (RW) Group9 refill priority +* GROUP10_REFILL_PRIORITY[10] - (RW) Group10 refill priority +* GROUP11_REFILL_PRIORITY[11] - (RW) Group11 refill priority +* GROUP12_REFILL_PRIORITY[12] - (RW) Group12 refill priority +* GROUP13_REFILL_PRIORITY[13] - (RW) Group13 refill priority +* GROUP14_REFILL_PRIORITY[14] - (RW) Group14 refill priority +* GROUP15_REFILL_PRIORITY[15] - (RW) Group15 refill priority +* GROUP0_REFILL_DISABLE[16] - (RW) Group0 refill control +* GROUP1_REFILL_DISABLE[17] - (RW) Group1 refill control +* GROUP2_REFILL_DISABLE[18] - (RW) Group2 refill control +* GROUP3_REFILL_DISABLE[19] - (RW) Group3 refill control +* GROUP4_REFILL_DISABLE[20] - (RW) Group4 refill control +* GROUP5_REFILL_DISABLE[21] - (RW) Group5 refill control +* GROUP6_REFILL_DISABLE[22] - (RW) Group6 refill control +* GROUP7_REFILL_DISABLE[23] - (RW) Group7 refill control +* GROUP8_REFILL_DISABLE[24] - (RW) Group8 refill control +* GROUP9_REFILL_DISABLE[25] - (RW) Group9 refill control +* GROUP10_REFILL_DISABLE[26] - (RW) Group10 refill control +* GROUP11_REFILL_DISABLE[27] - (RW) Group11 refill control +* GROUP12_REFILL_DISABLE[28] - (RW) Group12 refill control +* GROUP13_REFILL_DISABLE[29] - (RW) Group13 refill control +* GROUP14_REFILL_DISABLE[30] - (RW) Group14 refill control +* GROUP15_REFILL_DISABLE[31] - (RW) Group15 refill control +*/ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP15_REFILL_DISABLE_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP15_REFILL_DISABLE_MASK \ + 0x80000000 /* GROUP15_REFILL_DISABLE[31] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP15_REFILL_DISABLE_SHFT 31 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP14_REFILL_DISABLE_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP14_REFILL_DISABLE_MASK \ + 0x40000000 /* GROUP14_REFILL_DISABLE[30] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP14_REFILL_DISABLE_SHFT 30 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP13_REFILL_DISABLE_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP13_REFILL_DISABLE_MASK \ + 0x20000000 /* GROUP13_REFILL_DISABLE[29] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP13_REFILL_DISABLE_SHFT 29 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP12_REFILL_DISABLE_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP12_REFILL_DISABLE_MASK \ + 0x10000000 /* GROUP12_REFILL_DISABLE[28] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP12_REFILL_DISABLE_SHFT 28 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP11_REFILL_DISABLE_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP11_REFILL_DISABLE_MASK \ + 0x08000000 /* GROUP11_REFILL_DISABLE[27] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP11_REFILL_DISABLE_SHFT 27 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP10_REFILL_DISABLE_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP10_REFILL_DISABLE_MASK \ + 0x04000000 /* GROUP10_REFILL_DISABLE[26] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP10_REFILL_DISABLE_SHFT 26 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP9_REFILL_DISABLE_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP9_REFILL_DISABLE_MASK \ + 0x02000000 /* GROUP9_REFILL_DISABLE[25] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP9_REFILL_DISABLE_SHFT 25 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP8_REFILL_DISABLE_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP8_REFILL_DISABLE_MASK \ + 0x01000000 /* GROUP8_REFILL_DISABLE[24] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP8_REFILL_DISABLE_SHFT 24 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP7_REFILL_DISABLE_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP7_REFILL_DISABLE_MASK \ + 0x00800000 /* GROUP7_REFILL_DISABLE[23] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP7_REFILL_DISABLE_SHFT 23 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP6_REFILL_DISABLE_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP6_REFILL_DISABLE_MASK \ + 0x00400000 /* GROUP6_REFILL_DISABLE[22] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP6_REFILL_DISABLE_SHFT 22 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP5_REFILL_DISABLE_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP5_REFILL_DISABLE_MASK \ + 0x00200000 /* GROUP5_REFILL_DISABLE[21] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP5_REFILL_DISABLE_SHFT 21 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP4_REFILL_DISABLE_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP4_REFILL_DISABLE_MASK \ + 0x00100000 /* GROUP4_REFILL_DISABLE[20] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP4_REFILL_DISABLE_SHFT 20 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP3_REFILL_DISABLE_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP3_REFILL_DISABLE_MASK \ + 0x00080000 /* GROUP3_REFILL_DISABLE[19] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP3_REFILL_DISABLE_SHFT 19 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP2_REFILL_DISABLE_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP2_REFILL_DISABLE_MASK \ + 0x00040000 /* GROUP2_REFILL_DISABLE[18] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP2_REFILL_DISABLE_SHFT 18 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP1_REFILL_DISABLE_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP1_REFILL_DISABLE_MASK \ + 0x00020000 /* GROUP1_REFILL_DISABLE[17] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP1_REFILL_DISABLE_SHFT 17 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP0_REFILL_DISABLE_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP0_REFILL_DISABLE_MASK \ + 0x00010000 /* GROUP0_REFILL_DISABLE[16] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP0_REFILL_DISABLE_SHFT 16 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP15_REFILL_PRIORITY_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP15_REFILL_PRIORITY_MASK \ + 0x00008000 /* GROUP15_REFILL_PRIORITY[15] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP15_REFILL_PRIORITY_SHFT 15 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP14_REFILL_PRIORITY_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP14_REFILL_PRIORITY_MASK \ + 0x00004000 /* GROUP14_REFILL_PRIORITY[14] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP14_REFILL_PRIORITY_SHFT 14 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP13_REFILL_PRIORITY_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP13_REFILL_PRIORITY_MASK \ + 0x00002000 /* GROUP13_REFILL_PRIORITY[13] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP13_REFILL_PRIORITY_SHFT 13 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP12_REFILL_PRIORITY_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP12_REFILL_PRIORITY_MASK \ + 0x00001000 /* GROUP12_REFILL_PRIORITY[12] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP12_REFILL_PRIORITY_SHFT 12 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP11_REFILL_PRIORITY_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP11_REFILL_PRIORITY_MASK \ + 0x00000800 /* GROUP11_REFILL_PRIORITY[11] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP11_REFILL_PRIORITY_SHFT 11 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP10_REFILL_PRIORITY_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP10_REFILL_PRIORITY_MASK \ + 0x00000400 /* GROUP10_REFILL_PRIORITY[10] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP10_REFILL_PRIORITY_SHFT 10 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP9_REFILL_PRIORITY_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP9_REFILL_PRIORITY_MASK \ + 0x00000200 /* GROUP9_REFILL_PRIORITY[9] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP9_REFILL_PRIORITY_SHFT 9 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP8_REFILL_PRIORITY_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP8_REFILL_PRIORITY_MASK \ + 0x00000100 /* GROUP8_REFILL_PRIORITY[8] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP8_REFILL_PRIORITY_SHFT 8 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP7_REFILL_PRIORITY_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP7_REFILL_PRIORITY_MASK \ + 0x00000080 /* GROUP7_REFILL_PRIORITY[7] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP7_REFILL_PRIORITY_SHFT 7 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP6_REFILL_PRIORITY_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP6_REFILL_PRIORITY_MASK \ + 0x00000040 /* GROUP6_REFILL_PRIORITY[6] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP6_REFILL_PRIORITY_SHFT 6 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP5_REFILL_PRIORITY_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP5_REFILL_PRIORITY_MASK \ + 0x00000020 /* GROUP5_REFILL_PRIORITY[5] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP5_REFILL_PRIORITY_SHFT 5 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP4_REFILL_PRIORITY_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP4_REFILL_PRIORITY_MASK \ + 0x00000010 /* GROUP4_REFILL_PRIORITY[4] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP4_REFILL_PRIORITY_SHFT 4 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP3_REFILL_PRIORITY_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP3_REFILL_PRIORITY_MASK \ + 0x00000008 /* GROUP3_REFILL_PRIORITY[3] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP3_REFILL_PRIORITY_SHFT 3 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP2_REFILL_PRIORITY_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP2_REFILL_PRIORITY_MASK \ + 0x00000004 /* GROUP2_REFILL_PRIORITY[2] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP2_REFILL_PRIORITY_SHFT 2 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP1_REFILL_PRIORITY_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP1_REFILL_PRIORITY_MASK \ + 0x00000002 /* GROUP1_REFILL_PRIORITY[1] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP1_REFILL_PRIORITY_SHFT 1 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP0_REFILL_PRIORITY_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP0_REFILL_PRIORITY_MASK \ + 0x00000001 /* GROUP0_REFILL_PRIORITY[0] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP0_REFILL_PRIORITY_SHFT 0 + +/* +* ---PKT_IN_CNT_CTRL (0x7C026000 + 0x14)--- +* CNT1_RET_CNT_ENA[0] - (RW) Counter1 PLE/PSE return count enable +* CNT1_PKTIN_RET_CNT_ENA[1] - (RW) Counter1 pktin return count enable +* CNT1_PKTIN_CNT_ENA[2] - (RW) Counter1 pktin(ask) substrate count +enable +* CNT0_RET_CNT_ENA[3] - (RW) Counter0 PLE/PSE return count enable +* CNT0_PKTIN_RET_CNT_ENA[4] - (RW) Counter0 pktin return count enable +* CNT0_PKTIN_CNT_ENA[5] - (RW) Counter0 pktin(ask) substrate count +enable +* RESERVED6[31..6] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_CNT0_PKTIN_CNT_ENA_ADDR \ + WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_ADDR +#define WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_CNT0_PKTIN_CNT_ENA_MASK \ + 0x00000020 /* CNT0_PKTIN_CNT_ENA[5] */ +#define WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_CNT0_PKTIN_CNT_ENA_SHFT 5 +#define WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_CNT0_PKTIN_RET_CNT_ENA_ADDR \ + WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_ADDR +#define WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_CNT0_PKTIN_RET_CNT_ENA_MASK \ + 0x00000010 /* CNT0_PKTIN_RET_CNT_ENA[4] */ +#define WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_CNT0_PKTIN_RET_CNT_ENA_SHFT 4 +#define WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_CNT0_RET_CNT_ENA_ADDR \ + WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_ADDR +#define WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_CNT0_RET_CNT_ENA_MASK \ + 0x00000008 /* CNT0_RET_CNT_ENA[3] */ +#define WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_CNT0_RET_CNT_ENA_SHFT 3 +#define WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_CNT1_PKTIN_CNT_ENA_ADDR \ + WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_ADDR +#define WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_CNT1_PKTIN_CNT_ENA_MASK \ + 0x00000004 /* CNT1_PKTIN_CNT_ENA[2] */ +#define WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_CNT1_PKTIN_CNT_ENA_SHFT 2 +#define WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_CNT1_PKTIN_RET_CNT_ENA_ADDR \ + WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_ADDR +#define WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_CNT1_PKTIN_RET_CNT_ENA_MASK \ + 0x00000002 /* CNT1_PKTIN_RET_CNT_ENA[1] */ +#define WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_CNT1_PKTIN_RET_CNT_ENA_SHFT 1 +#define WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_CNT1_RET_CNT_ENA_ADDR \ + WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_ADDR +#define WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_CNT1_RET_CNT_ENA_MASK \ + 0x00000001 /* CNT1_RET_CNT_ENA[0] */ +#define WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_CNT1_RET_CNT_ENA_SHFT 0 + +/* +* ---CONTROL_SIGNAL (0x7C026000 + 0x18)--- +* CR_WACPU_MODE_EN[0] - (RW) Enable to WACPU mode for store forward +* packet to DLM +* RESERVED1[3..1] - (RO) Reserved bits +* WACPU_CMD_RET_PAGE_CNT[7..4] - (RW) WACPU mode, each packet in the CMD +* return the page count +* WACPU_TXD_RET_PAGE_CNT[11..8] - (RW) WACPU mode, each packet in the TXD +* return the page count +* WACPU_CMD_ASK_MAX_PAGE_CNT[15..12] - (RW) WACPU mode, CMD ask to require the +* maximum page count +* CR_HIF_ASK_SUB_ENA[16] - (RW) Enable packet in substration action from +* HIF ask period +* CR_PLE_SUB_ENA[17] - (RW) Enable packet in substration action from +PLE +* RESERVED18[19..18] - (RO) Reserved bits +* WACPU_TXD_ASK_MAX_PAGE_CNT[23..20] - (RW) WACPU mode, TXD ask to require the +* maximum page count +* WACPU_SUB_SRC_REFILL_ENA[24] - (RW) Enable terminate refill period when +* WACPU substrate source count to do refill action. +* WACPU_ADD_SRC_REFILL_ENA[25] - (RW) Enable terminate refill period when +* WACPU add source count to do refill action. +* WACPU_ADD_RES_REFILL_ENA[26] - (RW) Enable terminate refill period when +* WACPU add reserve count to do refill action. +* WACPU_RET_REFILL_ENA[27] - (RW) Enable terminate refill period when +* WACPU release packet to do refill action. +* RESERVED28[28] - (RO) Reserved bits +* CR_PLE_ADD_INT_REFILL_ENA[29] - (RW) Enable terminate refill period when PLE +* release packet to do addition. +* CR_PDMA_ADD_INT_REFILL_ENA[30] - (RW) Enable terminate refill period when +* packet in to do addition. +* CR_PKTIN_INT_REFILL_ENA[31] - (RW) Enable terminate refill period when +* packet in to do substration. +*/ +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_PKTIN_INT_REFILL_ENA_ADDR \ + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_PKTIN_INT_REFILL_ENA_MASK \ + 0x80000000 /* CR_PKTIN_INT_REFILL_ENA[31] */ +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_PKTIN_INT_REFILL_ENA_SHFT 31 +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_PDMA_ADD_INT_REFILL_ENA_ADDR \ + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_PDMA_ADD_INT_REFILL_ENA_MASK \ + 0x40000000 /* CR_PDMA_ADD_INT_REFILL_ENA[30] */ +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_PDMA_ADD_INT_REFILL_ENA_SHFT 30 +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_PLE_ADD_INT_REFILL_ENA_ADDR \ + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_PLE_ADD_INT_REFILL_ENA_MASK \ + 0x20000000 /* CR_PLE_ADD_INT_REFILL_ENA[29] */ +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_PLE_ADD_INT_REFILL_ENA_SHFT 29 +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_RET_REFILL_ENA_ADDR \ + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_RET_REFILL_ENA_MASK \ + 0x08000000 /* WACPU_RET_REFILL_ENA[27] */ +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_RET_REFILL_ENA_SHFT 27 +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_ADD_RES_REFILL_ENA_ADDR \ + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_ADD_RES_REFILL_ENA_MASK \ + 0x04000000 /* WACPU_ADD_RES_REFILL_ENA[26] */ +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_ADD_RES_REFILL_ENA_SHFT 26 +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_ADD_SRC_REFILL_ENA_ADDR \ + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_ADD_SRC_REFILL_ENA_MASK \ + 0x02000000 /* WACPU_ADD_SRC_REFILL_ENA[25] */ +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_ADD_SRC_REFILL_ENA_SHFT 25 +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_SUB_SRC_REFILL_ENA_ADDR \ + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_SUB_SRC_REFILL_ENA_MASK \ + 0x01000000 /* WACPU_SUB_SRC_REFILL_ENA[24] */ +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_SUB_SRC_REFILL_ENA_SHFT 24 +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_TXD_ASK_MAX_PAGE_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_TXD_ASK_MAX_PAGE_CNT_MASK \ + 0x00F00000 /* WACPU_TXD_ASK_MAX_PAGE_CNT[23..20] */ +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_TXD_ASK_MAX_PAGE_CNT_SHFT 20 +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_PLE_SUB_ENA_ADDR \ + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_PLE_SUB_ENA_MASK \ + 0x00020000 /* CR_PLE_SUB_ENA[17] */ +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_PLE_SUB_ENA_SHFT 17 +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_HIF_ASK_SUB_ENA_ADDR \ + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_HIF_ASK_SUB_ENA_MASK \ + 0x00010000 /* CR_HIF_ASK_SUB_ENA[16] */ +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_HIF_ASK_SUB_ENA_SHFT 16 +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_CMD_ASK_MAX_PAGE_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_CMD_ASK_MAX_PAGE_CNT_MASK \ + 0x0000F000 /* WACPU_CMD_ASK_MAX_PAGE_CNT[15..12] */ +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_CMD_ASK_MAX_PAGE_CNT_SHFT 12 +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_TXD_RET_PAGE_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_TXD_RET_PAGE_CNT_MASK \ + 0x00000F00 /* WACPU_TXD_RET_PAGE_CNT[11..8] */ +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_TXD_RET_PAGE_CNT_SHFT 8 +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_CMD_RET_PAGE_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_CMD_RET_PAGE_CNT_MASK \ + 0x000000F0 /* WACPU_CMD_RET_PAGE_CNT[7..4] */ +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_CMD_RET_PAGE_CNT_SHFT 4 +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_WACPU_MODE_EN_ADDR \ + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_WACPU_MODE_EN_MASK \ + 0x00000001 /* CR_WACPU_MODE_EN[0] */ +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_WACPU_MODE_EN_SHFT 0 + +/* +* ---PACKET_MAX_SIZE (0x7C026000 + 0x1c)--- +* PLE_PACKET_MAX_SIZE[11..0] - (RW) PLE packet maximum page size (group 0 ~ +11) +* RESERVED12[15..12] - (RO) Reserved bits +* PSE_PACKET_MAX_SIZE[27..16] - (RW) PSE packet maximum page size (group 15) +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_PSE_PACKET_MAX_SIZE_ADDR \ + WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_ADDR +#define WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_PSE_PACKET_MAX_SIZE_MASK \ + 0x0FFF0000 /* PSE_PACKET_MAX_SIZE[27..16] */ +#define WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_PSE_PACKET_MAX_SIZE_SHFT 16 +#define WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_PLE_PACKET_MAX_SIZE_ADDR \ + WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_ADDR +#define WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_PLE_PACKET_MAX_SIZE_MASK \ + 0x00000FFF /* PLE_PACKET_MAX_SIZE[11..0] */ +#define WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_PLE_PACKET_MAX_SIZE_SHFT 0 + +/* +* ---GROUP0_CONTROL (0x7C026000 + 0x20)--- +* GROUP0_MIN_QUOTA[11..0] - (RW) Group0 Minimum Quota +* RESERVED12[15..12] - (RO) Reserved bits +* GROUP0_MAX_QUOTA[27..16] - (RW) Group0 Maximum Quota +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_GROUP0_MAX_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_GROUP0_MAX_QUOTA_MASK \ + 0x0FFF0000 /* GROUP0_MAX_QUOTA[27..16] */ +#define WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_GROUP0_MAX_QUOTA_SHFT 16 +#define WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_GROUP0_MIN_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_GROUP0_MIN_QUOTA_MASK \ + 0x00000FFF /* GROUP0_MIN_QUOTA[11..0] */ +#define WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_GROUP0_MIN_QUOTA_SHFT 0 + +/* +* ---GROUP1_CONTROL (0x7C026000 + 0x24)--- +* GROUP1_MIN_QUOTA[11..0] - (RW) Group1 Minimum Quota +* RESERVED12[15..12] - (RO) Reserved bits +* GROUP1_MAX_QUOTA[27..16] - (RW) Group1 Maximum Quota +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_GROUP1_CONTROL_GROUP1_MAX_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP1_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP1_CONTROL_GROUP1_MAX_QUOTA_MASK \ + 0x0FFF0000 /* GROUP1_MAX_QUOTA[27..16] */ +#define WF_HIF_DMASHDL_TOP_GROUP1_CONTROL_GROUP1_MAX_QUOTA_SHFT 16 +#define WF_HIF_DMASHDL_TOP_GROUP1_CONTROL_GROUP1_MIN_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP1_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP1_CONTROL_GROUP1_MIN_QUOTA_MASK \ + 0x00000FFF /* GROUP1_MIN_QUOTA[11..0] */ +#define WF_HIF_DMASHDL_TOP_GROUP1_CONTROL_GROUP1_MIN_QUOTA_SHFT 0 + +/* +* ---GROUP2_CONTROL (0x7C026000 + 0x28)--- +* GROUP2_MIN_QUOTA[11..0] - (RW) Group2 Minimum Quota +* RESERVED12[15..12] - (RO) Reserved bits +* GROUP2_MAX_QUOTA[27..16] - (RW) Group2 Maximum Quota +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_GROUP2_CONTROL_GROUP2_MAX_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP2_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP2_CONTROL_GROUP2_MAX_QUOTA_MASK \ + 0x0FFF0000 /* GROUP2_MAX_QUOTA[27..16] */ +#define WF_HIF_DMASHDL_TOP_GROUP2_CONTROL_GROUP2_MAX_QUOTA_SHFT 16 +#define WF_HIF_DMASHDL_TOP_GROUP2_CONTROL_GROUP2_MIN_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP2_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP2_CONTROL_GROUP2_MIN_QUOTA_MASK \ + 0x00000FFF /* GROUP2_MIN_QUOTA[11..0] */ +#define WF_HIF_DMASHDL_TOP_GROUP2_CONTROL_GROUP2_MIN_QUOTA_SHFT 0 + +/* +* ---GROUP3_CONTROL (0x7C026000 + 0x2C)--- +* GROUP3_MIN_QUOTA[11..0] - (RW) Group3 Minimum Quota +* RESERVED12[15..12] - (RO) Reserved bits +* GROUP3_MAX_QUOTA[27..16] - (RW) Group3 Maximum Quota +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_GROUP3_CONTROL_GROUP3_MAX_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP3_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP3_CONTROL_GROUP3_MAX_QUOTA_MASK \ + 0x0FFF0000 /* GROUP3_MAX_QUOTA[27..16] */ +#define WF_HIF_DMASHDL_TOP_GROUP3_CONTROL_GROUP3_MAX_QUOTA_SHFT 16 +#define WF_HIF_DMASHDL_TOP_GROUP3_CONTROL_GROUP3_MIN_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP3_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP3_CONTROL_GROUP3_MIN_QUOTA_MASK \ + 0x00000FFF /* GROUP3_MIN_QUOTA[11..0] */ +#define WF_HIF_DMASHDL_TOP_GROUP3_CONTROL_GROUP3_MIN_QUOTA_SHFT 0 + +/* +* ---GROUP4_CONTROL (0x7C026000 + 0x30)--- +* GROUP4_MIN_QUOTA[11..0] - (RW) Group4 Minimum Quota +* RESERVED12[15..12] - (RO) Reserved bits +* GROUP4_MAX_QUOTA[27..16] - (RW) Group4 Maximum Quota +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_GROUP4_CONTROL_GROUP4_MAX_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP4_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP4_CONTROL_GROUP4_MAX_QUOTA_MASK \ + 0x0FFF0000 /* GROUP4_MAX_QUOTA[27..16] */ +#define WF_HIF_DMASHDL_TOP_GROUP4_CONTROL_GROUP4_MAX_QUOTA_SHFT 16 +#define WF_HIF_DMASHDL_TOP_GROUP4_CONTROL_GROUP4_MIN_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP4_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP4_CONTROL_GROUP4_MIN_QUOTA_MASK \ + 0x00000FFF /* GROUP4_MIN_QUOTA[11..0] */ +#define WF_HIF_DMASHDL_TOP_GROUP4_CONTROL_GROUP4_MIN_QUOTA_SHFT 0 + +/* +* ---GROUP5_CONTROL (0x7C026000 + 0x34)--- +* GROUP5_MIN_QUOTA[11..0] - (RW) Group5 Minimum Quota +* RESERVED12[15..12] - (RO) Reserved bits +* GROUP5_MAX_QUOTA[27..16] - (RW) Group5 Maximum Quota +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_GROUP5_CONTROL_GROUP5_MAX_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP5_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP5_CONTROL_GROUP5_MAX_QUOTA_MASK \ + 0x0FFF0000 /* GROUP5_MAX_QUOTA[27..16] */ +#define WF_HIF_DMASHDL_TOP_GROUP5_CONTROL_GROUP5_MAX_QUOTA_SHFT 16 +#define WF_HIF_DMASHDL_TOP_GROUP5_CONTROL_GROUP5_MIN_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP5_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP5_CONTROL_GROUP5_MIN_QUOTA_MASK \ + 0x00000FFF /* GROUP5_MIN_QUOTA[11..0] */ +#define WF_HIF_DMASHDL_TOP_GROUP5_CONTROL_GROUP5_MIN_QUOTA_SHFT 0 + +/* +* ---GROUP6_CONTROL (0x7C026000 + 0x38)--- +* GROUP6_MIN_QUOTA[11..0] - (RW) Group6 Minimum Quota +* RESERVED12[15..12] - (RO) Reserved bits +* GROUP6_MAX_QUOTA[27..16] - (RW) Group6 Maximum Quota +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_GROUP6_CONTROL_GROUP6_MAX_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP6_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP6_CONTROL_GROUP6_MAX_QUOTA_MASK \ + 0x0FFF0000 /* GROUP6_MAX_QUOTA[27..16] */ +#define WF_HIF_DMASHDL_TOP_GROUP6_CONTROL_GROUP6_MAX_QUOTA_SHFT 16 +#define WF_HIF_DMASHDL_TOP_GROUP6_CONTROL_GROUP6_MIN_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP6_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP6_CONTROL_GROUP6_MIN_QUOTA_MASK \ + 0x00000FFF /* GROUP6_MIN_QUOTA[11..0] */ +#define WF_HIF_DMASHDL_TOP_GROUP6_CONTROL_GROUP6_MIN_QUOTA_SHFT 0 + +/* +* ---GROUP7_CONTROL (0x7C026000 + 0x3C)--- +* GROUP7_MIN_QUOTA[11..0] - (RW) Group7 Minimum Quota +* RESERVED12[15..12] - (RO) Reserved bits +* GROUP7_MAX_QUOTA[27..16] - (RW) Group7 Maximum Quota +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_GROUP7_CONTROL_GROUP7_MAX_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP7_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP7_CONTROL_GROUP7_MAX_QUOTA_MASK \ + 0x0FFF0000 /* GROUP7_MAX_QUOTA[27..16] */ +#define WF_HIF_DMASHDL_TOP_GROUP7_CONTROL_GROUP7_MAX_QUOTA_SHFT 16 +#define WF_HIF_DMASHDL_TOP_GROUP7_CONTROL_GROUP7_MIN_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP7_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP7_CONTROL_GROUP7_MIN_QUOTA_MASK \ + 0x00000FFF /* GROUP7_MIN_QUOTA[11..0] */ +#define WF_HIF_DMASHDL_TOP_GROUP7_CONTROL_GROUP7_MIN_QUOTA_SHFT 0 + +/* +* ---GROUP8_CONTROL (0x7C026000 + 0x40)--- +* GROUP8_MIN_QUOTA[11..0] - (RW) Group8 Minimum Quota +* RESERVED12[15..12] - (RO) Reserved bits +* GROUP8_MAX_QUOTA[27..16] - (RW) Group8 Maximum Quota +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_GROUP8_CONTROL_GROUP8_MAX_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP8_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP8_CONTROL_GROUP8_MAX_QUOTA_MASK \ + 0x0FFF0000 /* GROUP8_MAX_QUOTA[27..16] */ +#define WF_HIF_DMASHDL_TOP_GROUP8_CONTROL_GROUP8_MAX_QUOTA_SHFT 16 +#define WF_HIF_DMASHDL_TOP_GROUP8_CONTROL_GROUP8_MIN_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP8_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP8_CONTROL_GROUP8_MIN_QUOTA_MASK \ + 0x00000FFF /* GROUP8_MIN_QUOTA[11..0] */ +#define WF_HIF_DMASHDL_TOP_GROUP8_CONTROL_GROUP8_MIN_QUOTA_SHFT 0 + +/* +* ---GROUP9_CONTROL (0x7C026000 + 0x44)--- +* GROUP9_MIN_QUOTA[11..0] - (RW) Group9 Minimum Quota +* RESERVED12[15..12] - (RO) Reserved bits +* GROUP9_MAX_QUOTA[27..16] - (RW) Group9 Maximum Quota +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_GROUP9_CONTROL_GROUP9_MAX_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP9_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP9_CONTROL_GROUP9_MAX_QUOTA_MASK \ + 0x0FFF0000 /* GROUP9_MAX_QUOTA[27..16] */ +#define WF_HIF_DMASHDL_TOP_GROUP9_CONTROL_GROUP9_MAX_QUOTA_SHFT 16 +#define WF_HIF_DMASHDL_TOP_GROUP9_CONTROL_GROUP9_MIN_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP9_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP9_CONTROL_GROUP9_MIN_QUOTA_MASK \ + 0x00000FFF /* GROUP9_MIN_QUOTA[11..0] */ +#define WF_HIF_DMASHDL_TOP_GROUP9_CONTROL_GROUP9_MIN_QUOTA_SHFT 0 + +/* +* ---GROUP10_CONTROL (0x7C026000 + 0x48)--- +* GROUP10_MIN_QUOTA[11..0] - (RW) Group10 Minimum Quota +* RESERVED12[15..12] - (RO) Reserved bits +* GROUP10_MAX_QUOTA[27..16] - (RW) Group10 Maximum Quota +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_GROUP10_CONTROL_GROUP10_MAX_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP10_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP10_CONTROL_GROUP10_MAX_QUOTA_MASK \ + 0x0FFF0000 /* GROUP10_MAX_QUOTA[27..16] */ +#define WF_HIF_DMASHDL_TOP_GROUP10_CONTROL_GROUP10_MAX_QUOTA_SHFT 16 +#define WF_HIF_DMASHDL_TOP_GROUP10_CONTROL_GROUP10_MIN_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP10_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP10_CONTROL_GROUP10_MIN_QUOTA_MASK \ + 0x00000FFF /* GROUP10_MIN_QUOTA[11..0] */ +#define WF_HIF_DMASHDL_TOP_GROUP10_CONTROL_GROUP10_MIN_QUOTA_SHFT 0 + +/* +* ---GROUP11_CONTROL (0x7C026000 + 0x4C)--- +* GROUP11_MIN_QUOTA[11..0] - (RW) Group11 Minimum Quota +* RESERVED12[15..12] - (RO) Reserved bits +* GROUP11_MAX_QUOTA[27..16] - (RW) Group11 Maximum Quota +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_GROUP11_CONTROL_GROUP11_MAX_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP11_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP11_CONTROL_GROUP11_MAX_QUOTA_MASK \ + 0x0FFF0000 /* GROUP11_MAX_QUOTA[27..16] */ +#define WF_HIF_DMASHDL_TOP_GROUP11_CONTROL_GROUP11_MAX_QUOTA_SHFT 16 +#define WF_HIF_DMASHDL_TOP_GROUP11_CONTROL_GROUP11_MIN_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP11_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP11_CONTROL_GROUP11_MIN_QUOTA_MASK \ + 0x00000FFF /* GROUP11_MIN_QUOTA[11..0] */ +#define WF_HIF_DMASHDL_TOP_GROUP11_CONTROL_GROUP11_MIN_QUOTA_SHFT 0 + +/* +* ---GROUP12_CONTROL (0x7C026000 + 0x50)--- +* GROUP12_MIN_QUOTA[11..0] - (RW) Group12 Minimum Quota +* RESERVED12[15..12] - (RO) Reserved bits +* GROUP12_MAX_QUOTA[27..16] - (RW) Group12 Maximum Quota +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_GROUP12_CONTROL_GROUP12_MAX_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP12_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP12_CONTROL_GROUP12_MAX_QUOTA_MASK \ + 0x0FFF0000 /* GROUP12_MAX_QUOTA[27..16] */ +#define WF_HIF_DMASHDL_TOP_GROUP12_CONTROL_GROUP12_MAX_QUOTA_SHFT 16 +#define WF_HIF_DMASHDL_TOP_GROUP12_CONTROL_GROUP12_MIN_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP12_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP12_CONTROL_GROUP12_MIN_QUOTA_MASK \ + 0x00000FFF /* GROUP12_MIN_QUOTA[11..0] */ +#define WF_HIF_DMASHDL_TOP_GROUP12_CONTROL_GROUP12_MIN_QUOTA_SHFT 0 + +/* +* ---GROUP13_CONTROL (0x7C026000 + 0x54)--- +* GROUP13_MIN_QUOTA[11..0] - (RW) Group13 Minimum Quota +* RESERVED12[15..12] - (RO) Reserved bits +* GROUP13_MAX_QUOTA[27..16] - (RW) Group13 Maximum Quota +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_GROUP13_CONTROL_GROUP13_MAX_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP13_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP13_CONTROL_GROUP13_MAX_QUOTA_MASK \ + 0x0FFF0000 /* GROUP13_MAX_QUOTA[27..16] */ +#define WF_HIF_DMASHDL_TOP_GROUP13_CONTROL_GROUP13_MAX_QUOTA_SHFT 16 +#define WF_HIF_DMASHDL_TOP_GROUP13_CONTROL_GROUP13_MIN_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP13_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP13_CONTROL_GROUP13_MIN_QUOTA_MASK \ + 0x00000FFF /* GROUP13_MIN_QUOTA[11..0] */ +#define WF_HIF_DMASHDL_TOP_GROUP13_CONTROL_GROUP13_MIN_QUOTA_SHFT 0 + +/* +* ---GROUP14_CONTROL (0x7C026000 + 0x58)--- +* GROUP14_MIN_QUOTA[11..0] - (RW) Group14 Minimum Quota +* RESERVED12[15..12] - (RO) Reserved bits +* GROUP14_MAX_QUOTA[27..16] - (RW) Group14 Maximum Quota +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_GROUP14_CONTROL_GROUP14_MAX_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP14_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP14_CONTROL_GROUP14_MAX_QUOTA_MASK \ + 0x0FFF0000 /* GROUP14_MAX_QUOTA[27..16] */ +#define WF_HIF_DMASHDL_TOP_GROUP14_CONTROL_GROUP14_MAX_QUOTA_SHFT 16 +#define WF_HIF_DMASHDL_TOP_GROUP14_CONTROL_GROUP14_MIN_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP14_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP14_CONTROL_GROUP14_MIN_QUOTA_MASK \ + 0x00000FFF /* GROUP14_MIN_QUOTA[11..0] */ +#define WF_HIF_DMASHDL_TOP_GROUP14_CONTROL_GROUP14_MIN_QUOTA_SHFT 0 + +/* +* ---GROUP15_CONTROL (0x7C026000 + 0x5C)--- +* GROUP15_MIN_QUOTA[11..0] - (RW) Group15 Minimum Quota +* RESERVED12[15..12] - (RO) Reserved bits +* GROUP15_MAX_QUOTA[27..16] - (RW) Group15 Maximum Quota +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_GROUP15_CONTROL_GROUP15_MAX_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP15_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP15_CONTROL_GROUP15_MAX_QUOTA_MASK \ + 0x0FFF0000 /* GROUP15_MAX_QUOTA[27..16] */ +#define WF_HIF_DMASHDL_TOP_GROUP15_CONTROL_GROUP15_MAX_QUOTA_SHFT 16 +#define WF_HIF_DMASHDL_TOP_GROUP15_CONTROL_GROUP15_MIN_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP15_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP15_CONTROL_GROUP15_MIN_QUOTA_MASK \ + 0x00000FFF /* GROUP15_MIN_QUOTA[11..0] */ +#define WF_HIF_DMASHDL_TOP_GROUP15_CONTROL_GROUP15_MIN_QUOTA_SHFT 0 + +/* +* ---QUEUE_MAPPING0 (0x7C026000 + 0x60)--- +* QUEUE0_MAPPING[3..0] - (RW) Queue 0 use which group ID +* QUEUE1_MAPPING[7..4] - (RW) Queue 1 use which group ID +* QUEUE2_MAPPING[11..8] - (RW) Queue 2 use which group ID +* QUEUE3_MAPPING[15..12] - (RW) Queue 3 use which group ID +* QUEUE4_MAPPING[19..16] - (RW) Queue 4 use which group ID +* QUEUE5_MAPPING[23..20] - (RW) Queue 5 use which group ID +* QUEUE6_MAPPING[27..24] - (RW) Queue 6 use which group ID +* QUEUE7_MAPPING[31..28] - (RW) Queue 7 use which group ID +*/ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE7_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE7_MAPPING_MASK \ + 0xF0000000 /* QUEUE7_MAPPING[31..28] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE7_MAPPING_SHFT 28 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE6_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE6_MAPPING_MASK \ + 0x0F000000 /* QUEUE6_MAPPING[27..24] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE6_MAPPING_SHFT 24 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE5_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE5_MAPPING_MASK \ + 0x00F00000 /* QUEUE5_MAPPING[23..20] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE5_MAPPING_SHFT 20 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE4_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE4_MAPPING_MASK \ + 0x000F0000 /* QUEUE4_MAPPING[19..16] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE4_MAPPING_SHFT 16 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE3_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE3_MAPPING_MASK \ + 0x0000F000 /* QUEUE3_MAPPING[15..12] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE3_MAPPING_SHFT 12 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE2_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE2_MAPPING_MASK \ + 0x00000F00 /* QUEUE2_MAPPING[11..8] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE2_MAPPING_SHFT 8 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE1_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE1_MAPPING_MASK \ + 0x000000F0 /* QUEUE1_MAPPING[7..4] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE1_MAPPING_SHFT 4 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE0_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE0_MAPPING_MASK \ + 0x0000000F /* QUEUE0_MAPPING[3..0] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE0_MAPPING_SHFT 0 + +/* +* ---QUEUE_MAPPING1 (0x7C026000 + 0x64)--- +* QUEUE8_MAPPING[3..0] - (RW) Queue 8 use which group ID +* QUEUE9_MAPPING[7..4] - (RW) Queue 9 use which group ID +* QUEUE10_MAPPING[11..8] - (RW) Queue 10 use which group ID +* QUEUE11_MAPPING[15..12] - (RW) Queue 11 use which group ID +* QUEUE12_MAPPING[19..16] - (RW) Queue 12 use which group ID +* QUEUE13_MAPPING[23..20] - (RW) Queue 13 use which group ID +* QUEUE14_MAPPING[27..24] - (RW) Queue 14 use which group ID +* QUEUE15_MAPPING[31..28] - (RW) Queue 15 use which group ID +*/ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE15_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE15_MAPPING_MASK \ + 0xF0000000 /* QUEUE15_MAPPING[31..28] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE15_MAPPING_SHFT 28 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE14_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE14_MAPPING_MASK \ + 0x0F000000 /* QUEUE14_MAPPING[27..24] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE14_MAPPING_SHFT 24 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE13_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE13_MAPPING_MASK \ + 0x00F00000 /* QUEUE13_MAPPING[23..20] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE13_MAPPING_SHFT 20 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE12_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE12_MAPPING_MASK \ + 0x000F0000 /* QUEUE12_MAPPING[19..16] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE12_MAPPING_SHFT 16 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE11_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE11_MAPPING_MASK \ + 0x0000F000 /* QUEUE11_MAPPING[15..12] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE11_MAPPING_SHFT 12 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE10_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE10_MAPPING_MASK \ + 0x00000F00 /* QUEUE10_MAPPING[11..8] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE10_MAPPING_SHFT 8 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE9_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE9_MAPPING_MASK \ + 0x000000F0 /* QUEUE9_MAPPING[7..4] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE9_MAPPING_SHFT 4 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE8_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE8_MAPPING_MASK \ + 0x0000000F /* QUEUE8_MAPPING[3..0] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE8_MAPPING_SHFT 0 + +/* +* ---QUEUE_MAPPING2 (0x7C026000 + 0x68)--- +* QUEUE16_MAPPING[3..0] - (RW) Queue 16 use which group ID +* QUEUE17_MAPPING[7..4] - (RW) Queue 17 use which group ID +* QUEUE18_MAPPING[11..8] - (RW) Queue 18 use which group ID +* QUEUE19_MAPPING[15..12] - (RW) Queue 19 use which group ID +* QUEUE20_MAPPING[19..16] - (RW) Queue 20 use which group ID +* QUEUE21_MAPPING[23..20] - (RW) Queue 21 use which group ID +* QUEUE22_MAPPING[27..24] - (RW) Queue 22 use which group ID +* QUEUE23_MAPPING[31..28] - (RW) Queue 23 use which group ID +*/ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE23_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE23_MAPPING_MASK \ + 0xF0000000 /* QUEUE23_MAPPING[31..28] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE23_MAPPING_SHFT 28 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE22_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE22_MAPPING_MASK \ + 0x0F000000 /* QUEUE22_MAPPING[27..24] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE22_MAPPING_SHFT 24 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE21_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE21_MAPPING_MASK \ + 0x00F00000 /* QUEUE21_MAPPING[23..20] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE21_MAPPING_SHFT 20 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE20_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE20_MAPPING_MASK \ + 0x000F0000 /* QUEUE20_MAPPING[19..16] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE20_MAPPING_SHFT 16 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE19_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE19_MAPPING_MASK \ + 0x0000F000 /* QUEUE19_MAPPING[15..12] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE19_MAPPING_SHFT 12 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE18_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE18_MAPPING_MASK \ + 0x00000F00 /* QUEUE18_MAPPING[11..8] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE18_MAPPING_SHFT 8 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE17_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE17_MAPPING_MASK \ + 0x000000F0 /* QUEUE17_MAPPING[7..4] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE17_MAPPING_SHFT 4 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE16_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE16_MAPPING_MASK \ + 0x0000000F /* QUEUE16_MAPPING[3..0] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE16_MAPPING_SHFT 0 + +/* +* ---QUEUE_MAPPING3 (0x7C026000 + 0x6c)--- +* QUEUE24_MAPPING[3..0] - (RW) Queue 24 use which group ID +* QUEUE25_MAPPING[7..4] - (RW) Queue 25 use which group ID +* QUEUE26_MAPPING[11..8] - (RW) Queue 26 use which group ID +* QUEUE27_MAPPING[15..12] - (RW) Queue 27 use which group ID +* QUEUE28_MAPPING[19..16] - (RW) Queue 28 use which group ID +* QUEUE29_MAPPING[23..20] - (RW) Queue 29 use which group ID +* QUEUE30_MAPPING[27..24] - (RW) Queue 30 use which group ID +* QUEUE31_MAPPING[31..28] - (RW) Queue 31 use which group ID +*/ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE31_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE31_MAPPING_MASK \ + 0xF0000000 /* QUEUE31_MAPPING[31..28] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE31_MAPPING_SHFT 28 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE30_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE30_MAPPING_MASK \ + 0x0F000000 /* QUEUE30_MAPPING[27..24] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE30_MAPPING_SHFT 24 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE29_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE29_MAPPING_MASK \ + 0x00F00000 /* QUEUE29_MAPPING[23..20] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE29_MAPPING_SHFT 20 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE28_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE28_MAPPING_MASK \ + 0x000F0000 /* QUEUE28_MAPPING[19..16] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE28_MAPPING_SHFT 16 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE27_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE27_MAPPING_MASK \ + 0x0000F000 /* QUEUE27_MAPPING[15..12] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE27_MAPPING_SHFT 12 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE26_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE26_MAPPING_MASK \ + 0x00000F00 /* QUEUE26_MAPPING[11..8] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE26_MAPPING_SHFT 8 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE25_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE25_MAPPING_MASK \ + 0x000000F0 /* QUEUE25_MAPPING[7..4] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE25_MAPPING_SHFT 4 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE24_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE24_MAPPING_MASK \ + 0x0000000F /* QUEUE24_MAPPING[3..0] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE24_MAPPING_SHFT 0 + +/* +* ---HIF_SCHEDULER_SETTING0 (0x7C026000 + 0x70)--- +* PRIORITY0_GROUP[3..0] - (RW) Which group is priority 0, this group is +* highest priority +* PRIORITY1_GROUP[7..4] - (RW) Which group is priority 1 +* PRIORITY2_GROUP[11..8] - (RW) Which group is priority 2 +* PRIORITY3_GROUP[15..12] - (RW) Which group is priority 3 +* PRIORITY4_GROUP[19..16] - (RW) Which group is priority 4 +* PRIORITY5_GROUP[23..20] - (RW) Which group is priority 5 +* PRIORITY6_GROUP[27..24] - (RW) Which group is priority 6 +* PRIORITY7_GROUP[31..28] - (RW) Which group is priority 7 +*/ +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY7_GROUP_ADDR \ + WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_ADDR +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY7_GROUP_MASK \ + 0xF0000000 /* PRIORITY7_GROUP[31..28] */ +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY7_GROUP_SHFT 28 +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY6_GROUP_ADDR \ + WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_ADDR +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY6_GROUP_MASK \ + 0x0F000000 /* PRIORITY6_GROUP[27..24] */ +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY6_GROUP_SHFT 24 +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY5_GROUP_ADDR \ + WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_ADDR +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY5_GROUP_MASK \ + 0x00F00000 /* PRIORITY5_GROUP[23..20] */ +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY5_GROUP_SHFT 20 +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY4_GROUP_ADDR \ + WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_ADDR +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY4_GROUP_MASK \ + 0x000F0000 /* PRIORITY4_GROUP[19..16] */ +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY4_GROUP_SHFT 16 +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY3_GROUP_ADDR \ + WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_ADDR +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY3_GROUP_MASK \ + 0x0000F000 /* PRIORITY3_GROUP[15..12] */ +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY3_GROUP_SHFT 12 +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY2_GROUP_ADDR \ + WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_ADDR +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY2_GROUP_MASK \ + 0x00000F00 /* PRIORITY2_GROUP[11..8] */ +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY2_GROUP_SHFT 8 +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY1_GROUP_ADDR \ + WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_ADDR +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY1_GROUP_MASK \ + 0x000000F0 /* PRIORITY1_GROUP[7..4] */ +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY1_GROUP_SHFT 4 +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY0_GROUP_ADDR \ + WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_ADDR +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY0_GROUP_MASK \ + 0x0000000F /* PRIORITY0_GROUP[3..0] */ +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY0_GROUP_SHFT 0 + +/* +* ---HIF_SCHEDULER_SETTING1 (0x7C026000 + 0x74)--- +* PRIORITY8_GROUP[3..0] - (RW) Which group is priority 8 +* PRIORITY9_GROUP[7..4] - (RW) Which group is priority 9 +* PRIORITY10_GROUP[11..8] - (RW) Which group is priority 10 +* PRIORITY11_GROUP[15..12] - (RW) Which group is priority 11 +* PRIORITY12_GROUP[19..16] - (RW) Which group is priority 12 +* PRIORITY13_GROUP[23..20] - (RW) Which group is priority 13 +* PRIORITY14_GROUP[27..24] - (RW) Which group is priority 14 +* PRIORITY15_GROUP[31..28] - (RW) Which group is priority 15, this group +* is last priority +*/ +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY15_GROUP_ADDR \ + WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_ADDR +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY15_GROUP_MASK \ + 0xF0000000 /* PRIORITY15_GROUP[31..28] */ +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY15_GROUP_SHFT 28 +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY14_GROUP_ADDR \ + WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_ADDR +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY14_GROUP_MASK \ + 0x0F000000 /* PRIORITY14_GROUP[27..24] */ +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY14_GROUP_SHFT 24 +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY13_GROUP_ADDR \ + WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_ADDR +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY13_GROUP_MASK \ + 0x00F00000 /* PRIORITY13_GROUP[23..20] */ +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY13_GROUP_SHFT 20 +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY12_GROUP_ADDR \ + WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_ADDR +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY12_GROUP_MASK \ + 0x000F0000 /* PRIORITY12_GROUP[19..16] */ +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY12_GROUP_SHFT 16 +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY11_GROUP_ADDR \ + WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_ADDR +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY11_GROUP_MASK \ + 0x0000F000 /* PRIORITY11_GROUP[15..12] */ +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY11_GROUP_SHFT 12 +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY10_GROUP_ADDR \ + WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_ADDR +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY10_GROUP_MASK \ + 0x00000F00 /* PRIORITY10_GROUP[11..8] */ +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY10_GROUP_SHFT 8 +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY9_GROUP_ADDR \ + WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_ADDR +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY9_GROUP_MASK \ + 0x000000F0 /* PRIORITY9_GROUP[7..4] */ +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY9_GROUP_SHFT 4 +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY8_GROUP_ADDR \ + WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_ADDR +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY8_GROUP_MASK \ + 0x0000000F /* PRIORITY8_GROUP[3..0] */ +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY8_GROUP_SHFT 0 + +/* +* ---SLOT_SETTING0 (0x7C026000 + 0x78)--- +* SLOT_0_SETTING[3..0] - (RW) Slot0 priority setting +* SLOT_1_SETTING[7..4] - (RW) Slot1 priority setting +* SLOT_2_SETTING[11..8] - (RW) Slot2 priority setting +* SLOT_3_SETTING[15..12] - (RW) Slot3 priority setting +* SLOT_4_SETTING[19..16] - (RW) Slot4 priority setting +* SLOT_5_SETTING[23..20] - (RW) Slot5 priority setting +* SLOT_6_SETTING[27..24] - (RW) Slot6 priority setting +* SLOT_7_SETTING[31..28] - (RW) Slot7 priority setting(which group ID) +*/ +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_7_SETTING_ADDR \ + WF_HIF_DMASHDL_TOP_SLOT_SETTING0_ADDR +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_7_SETTING_MASK \ + 0xF0000000 /* SLOT_7_SETTING[31..28] */ +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_7_SETTING_SHFT 28 +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_6_SETTING_ADDR \ + WF_HIF_DMASHDL_TOP_SLOT_SETTING0_ADDR +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_6_SETTING_MASK \ + 0x0F000000 /* SLOT_6_SETTING[27..24] */ +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_6_SETTING_SHFT 24 +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_5_SETTING_ADDR \ + WF_HIF_DMASHDL_TOP_SLOT_SETTING0_ADDR +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_5_SETTING_MASK \ + 0x00F00000 /* SLOT_5_SETTING[23..20] */ +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_5_SETTING_SHFT 20 +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_4_SETTING_ADDR \ + WF_HIF_DMASHDL_TOP_SLOT_SETTING0_ADDR +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_4_SETTING_MASK \ + 0x000F0000 /* SLOT_4_SETTING[19..16] */ +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_4_SETTING_SHFT 16 +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_3_SETTING_ADDR \ + WF_HIF_DMASHDL_TOP_SLOT_SETTING0_ADDR +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_3_SETTING_MASK \ + 0x0000F000 /* SLOT_3_SETTING[15..12] */ +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_3_SETTING_SHFT 12 +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_2_SETTING_ADDR \ + WF_HIF_DMASHDL_TOP_SLOT_SETTING0_ADDR +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_2_SETTING_MASK \ + 0x00000F00 /* SLOT_2_SETTING[11..8] */ +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_2_SETTING_SHFT 8 +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_1_SETTING_ADDR \ + WF_HIF_DMASHDL_TOP_SLOT_SETTING0_ADDR +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_1_SETTING_MASK \ + 0x000000F0 /* SLOT_1_SETTING[7..4] */ +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_1_SETTING_SHFT 4 +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_0_SETTING_ADDR \ + WF_HIF_DMASHDL_TOP_SLOT_SETTING0_ADDR +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_0_SETTING_MASK \ + 0x0000000F /* SLOT_0_SETTING[3..0] */ +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_0_SETTING_SHFT 0 + +/* +* ---SLOT_SETTING1 (0x7C026000 + 0x7C)--- +* SLOT_8_SETTING[3..0] - (RW) Slot8 priority setting +* SLOT_9_SETTING[7..4] - (RW) Slot9 priority setting +* SLOT_10_SETTING[11..8] - (RW) Slot10 priority setting +* SLOT_11_SETTING[15..12] - (RW) Slo11 priority setting +* SLOT_12_SETTING[19..16] - (RW) Slot12 priority setting +* SLOT_13_SETTING[23..20] - (RW) Slot13 priority setting +* SLOT_14_SETTING[27..24] - (RW) Slot14 priority setting +* SLOT_15_SETTING[31..28] - (RW) Slot15 priority setting(which group ID) +*/ +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_15_SETTING_ADDR \ + WF_HIF_DMASHDL_TOP_SLOT_SETTING1_ADDR +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_15_SETTING_MASK \ + 0xF0000000 /* SLOT_15_SETTING[31..28] */ +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_15_SETTING_SHFT 28 +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_14_SETTING_ADDR \ + WF_HIF_DMASHDL_TOP_SLOT_SETTING1_ADDR +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_14_SETTING_MASK \ + 0x0F000000 /* SLOT_14_SETTING[27..24] */ +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_14_SETTING_SHFT 24 +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_13_SETTING_ADDR \ + WF_HIF_DMASHDL_TOP_SLOT_SETTING1_ADDR +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_13_SETTING_MASK \ + 0x00F00000 /* SLOT_13_SETTING[23..20] */ +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_13_SETTING_SHFT 20 +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_12_SETTING_ADDR \ + WF_HIF_DMASHDL_TOP_SLOT_SETTING1_ADDR +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_12_SETTING_MASK \ + 0x000F0000 /* SLOT_12_SETTING[19..16] */ +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_12_SETTING_SHFT 16 +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_11_SETTING_ADDR \ + WF_HIF_DMASHDL_TOP_SLOT_SETTING1_ADDR +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_11_SETTING_MASK \ + 0x0000F000 /* SLOT_11_SETTING[15..12] */ +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_11_SETTING_SHFT 12 +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_10_SETTING_ADDR \ + WF_HIF_DMASHDL_TOP_SLOT_SETTING1_ADDR +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_10_SETTING_MASK \ + 0x00000F00 /* SLOT_10_SETTING[11..8] */ +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_10_SETTING_SHFT 8 +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_9_SETTING_ADDR \ + WF_HIF_DMASHDL_TOP_SLOT_SETTING1_ADDR +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_9_SETTING_MASK \ + 0x000000F0 /* SLOT_9_SETTING[7..4] */ +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_9_SETTING_SHFT 4 +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_8_SETTING_ADDR \ + WF_HIF_DMASHDL_TOP_SLOT_SETTING1_ADDR +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_8_SETTING_MASK \ + 0x0000000F /* SLOT_8_SETTING[3..0] */ +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_8_SETTING_SHFT 0 + +/* +* ---SLOT_PERIOD (0x7C026000 + 0x80)--- +* SLOT_PERIOD[15..0] - (RW) Slot Period (clock periods) +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_SLOT_PERIOD_SLOT_PERIOD_ADDR \ + WF_HIF_DMASHDL_TOP_SLOT_PERIOD_ADDR +#define WF_HIF_DMASHDL_TOP_SLOT_PERIOD_SLOT_PERIOD_MASK \ + 0x0000FFFF /* SLOT_PERIOD[15..0] */ +#define WF_HIF_DMASHDL_TOP_SLOT_PERIOD_SLOT_PERIOD_SHFT 0 + +/* +* ---DEBUG_PORT00 (0x7C026000 + 0xC0)--- +* DEBUG_N0_SEL[0] - (RW) Debug port n0 enable +* DEBUG_N1_SEL[1] - (RW) Debug port n1 enable +* DEBUG_N2_SEL[2] - (RW) Debug port n2 enable +* DEBUG_N3_SEL[3] - (RW) Debug port n3 enable +* RESERVED4[31..4] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT00_DEBUG_N3_SEL_ADDR \ + WF_HIF_DMASHDL_TOP_DEBUG_PORT00_ADDR +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT00_DEBUG_N3_SEL_MASK \ + 0x00000008 /* DEBUG_N3_SEL[3] */ +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT00_DEBUG_N3_SEL_SHFT 3 +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT00_DEBUG_N2_SEL_ADDR \ + WF_HIF_DMASHDL_TOP_DEBUG_PORT00_ADDR +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT00_DEBUG_N2_SEL_MASK \ + 0x00000004 /* DEBUG_N2_SEL[2] */ +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT00_DEBUG_N2_SEL_SHFT 2 +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT00_DEBUG_N1_SEL_ADDR \ + WF_HIF_DMASHDL_TOP_DEBUG_PORT00_ADDR +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT00_DEBUG_N1_SEL_MASK \ + 0x00000002 /* DEBUG_N1_SEL[1] */ +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT00_DEBUG_N1_SEL_SHFT 1 +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT00_DEBUG_N0_SEL_ADDR \ + WF_HIF_DMASHDL_TOP_DEBUG_PORT00_ADDR +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT00_DEBUG_N0_SEL_MASK \ + 0x00000001 /* DEBUG_N0_SEL[0] */ +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT00_DEBUG_N0_SEL_SHFT 0 + +/* +* ---DEBUG_PORT01 (0x7C026000 + 0xC4)--- +* DEBUG_FLAG_N0_SEL[7..0] - (RW) Debug port n0 select +* DEBUG_FLAG_N1_SEL[15..8] - (RW) Debug port n1 select +* DEBUG_FLAG_N2_SEL[23..16] - (RW) Debug port n2 select +* DEBUG_FLAG_N3_SEL[31..24] - (RW) Debug port n3 select +*/ +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT01_DEBUG_FLAG_N3_SEL_ADDR \ + WF_HIF_DMASHDL_TOP_DEBUG_PORT01_ADDR +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT01_DEBUG_FLAG_N3_SEL_MASK \ + 0xFF000000 /* DEBUG_FLAG_N3_SEL[31..24] */ +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT01_DEBUG_FLAG_N3_SEL_SHFT 24 +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT01_DEBUG_FLAG_N2_SEL_ADDR \ + WF_HIF_DMASHDL_TOP_DEBUG_PORT01_ADDR +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT01_DEBUG_FLAG_N2_SEL_MASK \ + 0x00FF0000 /* DEBUG_FLAG_N2_SEL[23..16] */ +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT01_DEBUG_FLAG_N2_SEL_SHFT 16 +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT01_DEBUG_FLAG_N1_SEL_ADDR \ + WF_HIF_DMASHDL_TOP_DEBUG_PORT01_ADDR +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT01_DEBUG_FLAG_N1_SEL_MASK \ + 0x0000FF00 /* DEBUG_FLAG_N1_SEL[15..8] */ +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT01_DEBUG_FLAG_N1_SEL_SHFT 8 +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT01_DEBUG_FLAG_N0_SEL_ADDR \ + WF_HIF_DMASHDL_TOP_DEBUG_PORT01_ADDR +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT01_DEBUG_FLAG_N0_SEL_MASK \ + 0x000000FF /* DEBUG_FLAG_N0_SEL[7..0] */ +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT01_DEBUG_FLAG_N0_SEL_SHFT 0 + +/* +* ---STATUS_RD02 (0x7C026000 + 0xC8)--- +* REFILL_CS[3..0] - (RO) Refill state machine for current state +* REFILL_NS[7..4] - (RO) Refill state machine for next state +* DMASHDL_CS[10..8] - (RO) DMASHDL state machine for current state +* RESERVED11[11] - (RO) Reserved bits +* DMASHDL_NS[14..12] - (RO) DMASHDL state machine for next state +* RESERVED15[15] - (RO) Reserved bits +* HIF_DMASHDL_DEBUG_PORT[31..16] - (RO) DMASHDL debug port signals +*/ +#define WF_HIF_DMASHDL_TOP_STATUS_RD02_HIF_DMASHDL_DEBUG_PORT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD02_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD02_HIF_DMASHDL_DEBUG_PORT_MASK \ + 0xFFFF0000 /* HIF_DMASHDL_DEBUG_PORT[31..16] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD02_HIF_DMASHDL_DEBUG_PORT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_STATUS_RD02_DMASHDL_NS_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD02_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD02_DMASHDL_NS_MASK \ + 0x00007000 /* DMASHDL_NS[14..12] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD02_DMASHDL_NS_SHFT 12 +#define WF_HIF_DMASHDL_TOP_STATUS_RD02_DMASHDL_CS_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD02_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD02_DMASHDL_CS_MASK \ + 0x00000700 /* DMASHDL_CS[10..8] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD02_DMASHDL_CS_SHFT 8 +#define WF_HIF_DMASHDL_TOP_STATUS_RD02_REFILL_NS_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD02_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD02_REFILL_NS_MASK \ + 0x000000F0 /* REFILL_NS[7..4] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD02_REFILL_NS_SHFT 4 +#define WF_HIF_DMASHDL_TOP_STATUS_RD02_REFILL_CS_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD02_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD02_REFILL_CS_MASK \ + 0x0000000F /* REFILL_CS[3..0] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD02_REFILL_CS_SHFT 0 + +/* +* ---COUNTER_UDF_CLR (0x7C026000 + 0xCC)--- +* FREEPG_CNT_UDF_CLR[0] - (RW) Clear freepage count underflow flag +* FFA_CNT_UDF_CLR[1] - (RW) Clear FFA count underflow flag +* SRC_SUB_CUR_UDF_CLR[2] - (RW) Clear PLE return stage source count +* underflow flag +* REFILL_MAX1_UDF_CLR[3] - (RW) Clear pktin return stage source count +* underflow flag +* REFILL_MAX0_UDF_CLR[4] - (RW) Clear RSV add SRC count greater than +* maximum quota +* RSV_SUB_CURR_UDF_CLR[5] - (RW) Clear reservation count underflow flag +* PLE_TXD_GT_MAX_SIZE_FLAG_CLR[6] - (RW) Clear PLE TXD size greater than max +* PLE TXD size flag +* PSE_SIZE_GT_MAX_SIZE_FLAG_CLR[7] - (RW) Clear PSE packet size greater than +* max packet size flag +* HIF_ASK_LONG_FLAG_CLR[8] - (RW) Clear the HIF ask after long time period +* to grant flag +* PSE_RSV_UDF_CLR[9] - (RW) Clear the HIF ask to let reservation +* count underflow flag +* PSE_SRC_PSERET_UDF_CLR[10] - (RW) Clear the PSE source count PSE module +* return underflow flag +* PSE_SRC_PKTRET_UDF_CLR[11] - (RW) Clear the PSE source count packet in +* return underflow flag +* RESERVED12[15..12] - (RO) Reserved bits +* HIF_ASK_PKTIN_CNT_CLR[16] - (RW) Clear the ask counters and pktin return +* counters for all groups +* RESERVED17[31..17] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_HIF_ASK_PKTIN_CNT_CLR_ADDR \ + WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_ADDR +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_HIF_ASK_PKTIN_CNT_CLR_MASK \ + 0x00010000 /* HIF_ASK_PKTIN_CNT_CLR[16] */ +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_HIF_ASK_PKTIN_CNT_CLR_SHFT 16 +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_PSE_SRC_PKTRET_UDF_CLR_ADDR \ + WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_ADDR +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_PSE_SRC_PKTRET_UDF_CLR_MASK \ + 0x00000800 /* PSE_SRC_PKTRET_UDF_CLR[11] */ +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_PSE_SRC_PKTRET_UDF_CLR_SHFT 11 +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_PSE_SRC_PSERET_UDF_CLR_ADDR \ + WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_ADDR +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_PSE_SRC_PSERET_UDF_CLR_MASK \ + 0x00000400 /* PSE_SRC_PSERET_UDF_CLR[10] */ +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_PSE_SRC_PSERET_UDF_CLR_SHFT 10 +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_PSE_RSV_UDF_CLR_ADDR \ + WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_ADDR +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_PSE_RSV_UDF_CLR_MASK \ + 0x00000200 /* PSE_RSV_UDF_CLR[9] */ +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_PSE_RSV_UDF_CLR_SHFT 9 +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_HIF_ASK_LONG_FLAG_CLR_ADDR \ + WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_ADDR +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_HIF_ASK_LONG_FLAG_CLR_MASK \ + 0x00000100 /* HIF_ASK_LONG_FLAG_CLR[8] */ +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_HIF_ASK_LONG_FLAG_CLR_SHFT 8 +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_PSE_SIZE_GT_MAX_SIZE_FLAG_CLR_ADDR \ + WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_ADDR +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_PSE_SIZE_GT_MAX_SIZE_FLAG_CLR_MASK \ + 0x00000080 /* PSE_SIZE_GT_MAX_SIZE_FLAG_CLR[7] */ +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_PSE_SIZE_GT_MAX_SIZE_FLAG_CLR_SHFT 7 +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_PLE_TXD_GT_MAX_SIZE_FLAG_CLR_ADDR \ + WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_ADDR +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_PLE_TXD_GT_MAX_SIZE_FLAG_CLR_MASK \ + 0x00000040 /* PLE_TXD_GT_MAX_SIZE_FLAG_CLR[6] */ +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_PLE_TXD_GT_MAX_SIZE_FLAG_CLR_SHFT 6 +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_RSV_SUB_CURR_UDF_CLR_ADDR \ + WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_ADDR +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_RSV_SUB_CURR_UDF_CLR_MASK \ + 0x00000020 /* RSV_SUB_CURR_UDF_CLR[5] */ +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_RSV_SUB_CURR_UDF_CLR_SHFT 5 +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_REFILL_MAX0_UDF_CLR_ADDR \ + WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_ADDR +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_REFILL_MAX0_UDF_CLR_MASK \ + 0x00000010 /* REFILL_MAX0_UDF_CLR[4] */ +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_REFILL_MAX0_UDF_CLR_SHFT 4 +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_REFILL_MAX1_UDF_CLR_ADDR \ + WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_ADDR +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_REFILL_MAX1_UDF_CLR_MASK \ + 0x00000008 /* REFILL_MAX1_UDF_CLR[3] */ +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_REFILL_MAX1_UDF_CLR_SHFT 3 +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_SRC_SUB_CUR_UDF_CLR_ADDR \ + WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_ADDR +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_SRC_SUB_CUR_UDF_CLR_MASK \ + 0x00000004 /* SRC_SUB_CUR_UDF_CLR[2] */ +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_SRC_SUB_CUR_UDF_CLR_SHFT 2 +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_FFA_CNT_UDF_CLR_ADDR \ + WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_ADDR +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_FFA_CNT_UDF_CLR_MASK \ + 0x00000002 /* FFA_CNT_UDF_CLR[1] */ +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_FFA_CNT_UDF_CLR_SHFT 1 +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_FREEPG_CNT_UDF_CLR_ADDR \ + WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_ADDR +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_FREEPG_CNT_UDF_CLR_MASK \ + 0x00000001 /* FREEPG_CNT_UDF_CLR[0] */ +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_FREEPG_CNT_UDF_CLR_SHFT 0 + +/* +* ---TX_PACKET_SIZE_PAGE_MAP (0x7C026000 + 0xD0)--- +* PACKET_SIZE_PAGE_MAP[7..0] - (RW) PSE Packet size page map +* 8'bxxxx_xxx1 : 32 bytes +* 8'bxxxx_xx10 : 64 bytes +* 8'bxxxx_x100 : 128 bytes +* 8'bxxxx_1000 : 256 bytes +* 8'bxxx1_0000 : 512 bytes +* 8'bxx10_0000 : 1024 bytes +* 8'bx100_0000 : 2048 bytes +* 8'b1000_0000 : 4096 bytes +* CR_PSE_LEN_MAP_SEL[8] - (RW) Enable pse packet length page mapping by +* CR Packet size page map or not +* RESERVED9[31..9] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_TX_PACKET_SIZE_PAGE_MAP_CR_PSE_LEN_MAP_SEL_ADDR \ + WF_HIF_DMASHDL_TOP_TX_PACKET_SIZE_PAGE_MAP_ADDR +#define WF_HIF_DMASHDL_TOP_TX_PACKET_SIZE_PAGE_MAP_CR_PSE_LEN_MAP_SEL_MASK \ + 0x00000100 /* CR_PSE_LEN_MAP_SEL[8] */ +#define WF_HIF_DMASHDL_TOP_TX_PACKET_SIZE_PAGE_MAP_CR_PSE_LEN_MAP_SEL_SHFT 8 +#define WF_HIF_DMASHDL_TOP_TX_PACKET_SIZE_PAGE_MAP_PACKET_SIZE_PAGE_MAP_ADDR \ + WF_HIF_DMASHDL_TOP_TX_PACKET_SIZE_PAGE_MAP_ADDR +#define WF_HIF_DMASHDL_TOP_TX_PACKET_SIZE_PAGE_MAP_PACKET_SIZE_PAGE_MAP_MASK \ + 0x000000FF /* PACKET_SIZE_PAGE_MAP[7..0] */ +#define WF_HIF_DMASHDL_TOP_TX_PACKET_SIZE_PAGE_MAP_PACKET_SIZE_PAGE_MAP_SHFT 0 + +/* +* ---HIF_ASK_LONG_CHECK (0x7C026000 + 0xD4)--- +* HIF_ASK_TICK_CNT[15..0] - (RO) HIF request ask wait period count. +* HIF_ASK_LONG_CNT_TH[31..16] - (RW) HIF request ask wait period threshold. +* (unit = 32us, wf_aon_32us_tick) +*/ +#define WF_HIF_DMASHDL_TOP_HIF_ASK_LONG_CHECK_HIF_ASK_LONG_CNT_TH_ADDR \ + WF_HIF_DMASHDL_TOP_HIF_ASK_LONG_CHECK_ADDR +#define WF_HIF_DMASHDL_TOP_HIF_ASK_LONG_CHECK_HIF_ASK_LONG_CNT_TH_MASK \ + 0xFFFF0000 /* HIF_ASK_LONG_CNT_TH[31..16] */ +#define WF_HIF_DMASHDL_TOP_HIF_ASK_LONG_CHECK_HIF_ASK_LONG_CNT_TH_SHFT 16 +#define WF_HIF_DMASHDL_TOP_HIF_ASK_LONG_CHECK_HIF_ASK_TICK_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_HIF_ASK_LONG_CHECK_ADDR +#define WF_HIF_DMASHDL_TOP_HIF_ASK_LONG_CHECK_HIF_ASK_TICK_CNT_MASK \ + 0x0000FFFF /* HIF_ASK_TICK_CNT[15..0] */ +#define WF_HIF_DMASHDL_TOP_HIF_ASK_LONG_CHECK_HIF_ASK_TICK_CNT_SHFT 0 + +/* +* ---CPU_QUOTA_SET (0x7C026000 + 0xD8)--- +* RETURN_PAGE_CNT[11..0] - (RW) CPU refill page count +* RESERVED12[15..12] - (RO) Reserved bits +* CPU_RETRUN_GID[19..16] - (RW) CPU refill group's ID +* RESERVED20[23..20] - (RO) Reserved bits +* CPU_RETRUN_MODE[25..24] - (RW) CPU refill mode selection +* 2'b00 : Substrate source mode +* 2'b01 : Return mode +* 2'b10 : Add source mode +* 2'b11 : Substrate reservation mode +* RESERVED26[30..26] - (RO) Reserved bits +* EXCUTE[31] - (WO) Excute this CR action +*/ +#define WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_EXCUTE_ADDR \ + WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_ADDR +#define WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_EXCUTE_MASK 0x80000000 /* EXCUTE[31] */ +#define WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_EXCUTE_SHFT 31 +#define WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_CPU_RETRUN_MODE_ADDR \ + WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_ADDR +#define WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_CPU_RETRUN_MODE_MASK \ + 0x03000000 /* CPU_RETRUN_MODE[25..24] */ +#define WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_CPU_RETRUN_MODE_SHFT 24 +#define WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_CPU_RETRUN_GID_ADDR \ + WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_ADDR +#define WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_CPU_RETRUN_GID_MASK \ + 0x000F0000 /* CPU_RETRUN_GID[19..16] */ +#define WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_CPU_RETRUN_GID_SHFT 16 +#define WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_RETURN_PAGE_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_ADDR +#define WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_RETURN_PAGE_CNT_MASK \ + 0x00000FFF /* RETURN_PAGE_CNT[11..0] */ +#define WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_RETURN_PAGE_CNT_SHFT 0 + +/* +* ---ERROR_FLAG_CTRL (0x7C026000 + 0xDC)--- +* CNT_UDF_INT_DMASK[15..0] - (RW) Underflow flag interrupt disable mask +control: +* bit[11] : pse_src_pktret_udf_flag +* bit[10] : pse_src_pseret_udf_flag +* bit[9] : pse_rsv_udf_flag +* bit[8] : hif_ask_long_flag_flag +* bit[7] : pse_size_gt_max_size_flag +* bit[6] : ple_txd_gt_max_size_flag +* bit[5] : rsv_sub_curr_udf_flag +* bit[4] : refill_max0_udf_flag +* bit[3] : refill_max1_udf_flag +* bit[2] : src_sub_cur_udf_flag +* bit[1] : ffa_cnt_udf_flag +* bit[0] : freepg_cnt_udf_flag +* FREEPG_CNT_UDF_FLAG[16] - (RO) Freepage count underflow flag +* FFA_CNT_UDF_FLAG[17] - (RO) FFA count underflow flag +* SRC_SUB_CUR_UDF_FLAG[18] - (RO) PLE return stage source count underflow +flag +* REFILL_MAX1_UDF_FLAG[19] - (RO) Pktin return stage source count +* underflow flag +* REFILL_MAX0_UDF_FLAG[20] - (RO) RSV add SRC count greater than maximum +quota +* RSV_SUB_CURR_UDF_FLAG[21] - (RO) Reservation count underflow flag +* PLE_TXD_GT_MAX_SIZE_FLAG[22] - (RO) PLE txd size greater than max PLE txd +* size flag +* PSE_SIZE_GT_MAX_SIZE_FLAG[23] - (RO) PSE packet size greater than max packet +* size flag +* HIF_ASK_LONG_FLAG[24] - (RO) The HIF ask after long time period to +* grant flag +* PSE_RSV_UDF_FLAG[25] - (RO) The HIF ask to let reservation count +* underflow flag +* PSE_SRC_PSERET_UDF_FLAG[26] - (RO) The PSE source count PSE module return +* underflow flag +* PSE_SRC_PKTRET_UDF_FLAG[27] - (RO) The PSE source count packet in return +* underflow flag +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_PSE_SRC_PKTRET_UDF_FLAG_ADDR \ + WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_ADDR +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_PSE_SRC_PKTRET_UDF_FLAG_MASK \ + 0x08000000 /* PSE_SRC_PKTRET_UDF_FLAG[27] */ +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_PSE_SRC_PKTRET_UDF_FLAG_SHFT 27 +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_PSE_SRC_PSERET_UDF_FLAG_ADDR \ + WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_ADDR +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_PSE_SRC_PSERET_UDF_FLAG_MASK \ + 0x04000000 /* PSE_SRC_PSERET_UDF_FLAG[26] */ +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_PSE_SRC_PSERET_UDF_FLAG_SHFT 26 +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_PSE_RSV_UDF_FLAG_ADDR \ + WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_ADDR +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_PSE_RSV_UDF_FLAG_MASK \ + 0x02000000 /* PSE_RSV_UDF_FLAG[25] */ +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_PSE_RSV_UDF_FLAG_SHFT 25 +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_HIF_ASK_LONG_FLAG_ADDR \ + WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_ADDR +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_HIF_ASK_LONG_FLAG_MASK \ + 0x01000000 /* HIF_ASK_LONG_FLAG[24] */ +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_HIF_ASK_LONG_FLAG_SHFT 24 +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_PSE_SIZE_GT_MAX_SIZE_FLAG_ADDR \ + WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_ADDR +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_PSE_SIZE_GT_MAX_SIZE_FLAG_MASK \ + 0x00800000 /* PSE_SIZE_GT_MAX_SIZE_FLAG[23] */ +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_PSE_SIZE_GT_MAX_SIZE_FLAG_SHFT 23 +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_PLE_TXD_GT_MAX_SIZE_FLAG_ADDR \ + WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_ADDR +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_PLE_TXD_GT_MAX_SIZE_FLAG_MASK \ + 0x00400000 /* PLE_TXD_GT_MAX_SIZE_FLAG[22] */ +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_PLE_TXD_GT_MAX_SIZE_FLAG_SHFT 22 +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_RSV_SUB_CURR_UDF_FLAG_ADDR \ + WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_ADDR +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_RSV_SUB_CURR_UDF_FLAG_MASK \ + 0x00200000 /* RSV_SUB_CURR_UDF_FLAG[21] */ +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_RSV_SUB_CURR_UDF_FLAG_SHFT 21 +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_REFILL_MAX0_UDF_FLAG_ADDR \ + WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_ADDR +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_REFILL_MAX0_UDF_FLAG_MASK \ + 0x00100000 /* REFILL_MAX0_UDF_FLAG[20] */ +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_REFILL_MAX0_UDF_FLAG_SHFT 20 +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_REFILL_MAX1_UDF_FLAG_ADDR \ + WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_ADDR +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_REFILL_MAX1_UDF_FLAG_MASK \ + 0x00080000 /* REFILL_MAX1_UDF_FLAG[19] */ +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_REFILL_MAX1_UDF_FLAG_SHFT 19 +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_SRC_SUB_CUR_UDF_FLAG_ADDR \ + WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_ADDR +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_SRC_SUB_CUR_UDF_FLAG_MASK \ + 0x00040000 /* SRC_SUB_CUR_UDF_FLAG[18] */ +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_SRC_SUB_CUR_UDF_FLAG_SHFT 18 +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_FFA_CNT_UDF_FLAG_ADDR \ + WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_ADDR +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_FFA_CNT_UDF_FLAG_MASK \ + 0x00020000 /* FFA_CNT_UDF_FLAG[17] */ +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_FFA_CNT_UDF_FLAG_SHFT 17 +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_FREEPG_CNT_UDF_FLAG_ADDR \ + WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_ADDR +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_FREEPG_CNT_UDF_FLAG_MASK \ + 0x00010000 /* FREEPG_CNT_UDF_FLAG[16] */ +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_FREEPG_CNT_UDF_FLAG_SHFT 16 +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_CNT_UDF_INT_DMASK_ADDR \ + WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_ADDR +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_CNT_UDF_INT_DMASK_MASK \ + 0x0000FFFF /* CNT_UDF_INT_DMASK[15..0] */ +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_CNT_UDF_INT_DMASK_SHFT 0 + +/* +* ---STATUS_RD (0x7C026000 + 0x100)--- +* FFA_CNT[11..0] - (RO) Free for all (FFA) count +* RESERVED12[15..12] - (RO) Reserved bits +* FREE_PAGE_CNT[27..16] - (RO) Free page count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_FREE_PAGE_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_FREE_PAGE_CNT_MASK \ + 0x0FFF0000 /* FREE_PAGE_CNT[27..16] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_FREE_PAGE_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_STATUS_RD_FFA_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_FFA_CNT_MASK \ + 0x00000FFF /* FFA_CNT[11..0] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_FFA_CNT_SHFT 0 + +/* +* ---STATUS_RD0 (0x7C026000 + 0x110)--- +* PLE_TXD_QID_MAX2_NZERO_CNT[3..0] - (RO) Number of TXD QID[6:5] not equal +* zero counter from PLE return. +* HOST_TXD_QID_MAX2_NZERO_CNT[7..4] - (RO) Number of TXD QID[6:5] not equal +* zero counter from host send. +* CURR_TXD_CTXD_FLAG[8] - (RO) Current TXD is cascade TXD format or not +* RESERVED9[31..9] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_STATUS_RD0_CURR_TXD_CTXD_FLAG_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD0_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD0_CURR_TXD_CTXD_FLAG_MASK \ + 0x00000100 /* CURR_TXD_CTXD_FLAG[8] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD0_CURR_TXD_CTXD_FLAG_SHFT 8 +#define WF_HIF_DMASHDL_TOP_STATUS_RD0_HOST_TXD_QID_MAX2_NZERO_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD0_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD0_HOST_TXD_QID_MAX2_NZERO_CNT_MASK \ + 0x000000F0 /* HOST_TXD_QID_MAX2_NZERO_CNT[7..4] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD0_HOST_TXD_QID_MAX2_NZERO_CNT_SHFT 4 +#define WF_HIF_DMASHDL_TOP_STATUS_RD0_PLE_TXD_QID_MAX2_NZERO_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD0_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD0_PLE_TXD_QID_MAX2_NZERO_CNT_MASK \ + 0x0000000F /* PLE_TXD_QID_MAX2_NZERO_CNT[3..0] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD0_PLE_TXD_QID_MAX2_NZERO_CNT_SHFT 0 + +/* +* ---STATUS_RD_GP0 (0x7C026000 + 0x140)--- +* G0_SRC_CNT[11..0] - (RO) Group0 source count +* RESERVED12[15..12] - (RO) Reserved bits +* G0_RSV_CNT[27..16] - (RO) Group0 reservation count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_G0_RSV_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_G0_RSV_CNT_MASK \ + 0x0FFF0000 /* G0_RSV_CNT[27..16] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_G0_RSV_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_G0_SRC_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_G0_SRC_CNT_MASK \ + 0x00000FFF /* G0_SRC_CNT[11..0] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_G0_SRC_CNT_SHFT 0 + +/* +* ---STATUS_RD_GP1 (0x7C026000 + 0x144)--- +* G1_SRC_CNT[11..0] - (RO) Group1 source count +* RESERVED12[15..12] - (RO) Reserved bits +* G1_RSV_CNT[27..16] - (RO) Group1 reservation count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP1_G1_RSV_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP1_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP1_G1_RSV_CNT_MASK \ + 0x0FFF0000 /* G1_RSV_CNT[27..16] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP1_G1_RSV_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP1_G1_SRC_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP1_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP1_G1_SRC_CNT_MASK \ + 0x00000FFF /* G1_SRC_CNT[11..0] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP1_G1_SRC_CNT_SHFT 0 + +/* +* ---STATUS_RD_GP2 (0x7C026000 + 0x148)--- +* G2_SRC_CNT[11..0] - (RO) Group2 source count +* RESERVED12[15..12] - (RO) Reserved bits +* G2_RSV_CNT[27..16] - (RO) Group2 reservation count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP2_G2_RSV_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP2_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP2_G2_RSV_CNT_MASK \ + 0x0FFF0000 /* G2_RSV_CNT[27..16] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP2_G2_RSV_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP2_G2_SRC_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP2_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP2_G2_SRC_CNT_MASK \ + 0x00000FFF /* G2_SRC_CNT[11..0] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP2_G2_SRC_CNT_SHFT 0 + +/* +* ---STATUS_RD_GP3 (0x7C026000 + 0x14c)--- +* G3_SRC_CNT[11..0] - (RO) Group3 source count +* RESERVED12[15..12] - (RO) Reserved bits +* G3_RSV_CNT[27..16] - (RO) Group3 reservation count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP3_G3_RSV_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP3_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP3_G3_RSV_CNT_MASK \ + 0x0FFF0000 /* G3_RSV_CNT[27..16] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP3_G3_RSV_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP3_G3_SRC_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP3_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP3_G3_SRC_CNT_MASK \ + 0x00000FFF /* G3_SRC_CNT[11..0] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP3_G3_SRC_CNT_SHFT 0 + +/* +* ---STATUS_RD_GP4 (0x7C026000 + 0x150)--- +* G4_SRC_CNT[11..0] - (RO) Group4 source count +* RESERVED12[15..12] - (RO) Reserved bits +* G4_RSV_CNT[27..16] - (RO) Group4 reservation count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP4_G4_RSV_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP4_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP4_G4_RSV_CNT_MASK \ + 0x0FFF0000 /* G4_RSV_CNT[27..16] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP4_G4_RSV_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP4_G4_SRC_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP4_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP4_G4_SRC_CNT_MASK \ + 0x00000FFF /* G4_SRC_CNT[11..0] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP4_G4_SRC_CNT_SHFT 0 + +/* +* ---STATUS_RD_GP5 (0x7C026000 + 0x154)--- +* G5_SRC_CNT[11..0] - (RO) Group5 source count +* RESERVED12[15..12] - (RO) Reserved bits +* G5_RSV_CNT[27..16] - (RO) Group5 reservation count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP5_G5_RSV_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP5_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP5_G5_RSV_CNT_MASK \ + 0x0FFF0000 /* G5_RSV_CNT[27..16] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP5_G5_RSV_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP5_G5_SRC_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP5_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP5_G5_SRC_CNT_MASK \ + 0x00000FFF /* G5_SRC_CNT[11..0] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP5_G5_SRC_CNT_SHFT 0 + +/* +* ---STATUS_RD_GP6 (0x7C026000 + 0x158)--- +* G6_SRC_CNT[11..0] - (RO) Group6 source count +* RESERVED12[15..12] - (RO) Reserved bits +* G6_RSV_CNT[27..16] - (RO) Group6 reservation count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP6_G6_RSV_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP6_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP6_G6_RSV_CNT_MASK \ + 0x0FFF0000 /* G6_RSV_CNT[27..16] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP6_G6_RSV_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP6_G6_SRC_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP6_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP6_G6_SRC_CNT_MASK \ + 0x00000FFF /* G6_SRC_CNT[11..0] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP6_G6_SRC_CNT_SHFT 0 + +/* +* ---STATUS_RD_GP7 (0x7C026000 + 0x15C)--- +* G7_SRC_CNT[11..0] - (RO) Group7 source count +* RESERVED12[15..12] - (RO) Reserved bits +* G7_RSV_CNT[27..16] - (RO) Group7 reservation count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP7_G7_RSV_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP7_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP7_G7_RSV_CNT_MASK \ + 0x0FFF0000 /* G7_RSV_CNT[27..16] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP7_G7_RSV_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP7_G7_SRC_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP7_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP7_G7_SRC_CNT_MASK \ + 0x00000FFF /* G7_SRC_CNT[11..0] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP7_G7_SRC_CNT_SHFT 0 + +/* +* ---STATUS_RD_GP8 (0x7C026000 + 0x160)--- +* G8_SRC_CNT[11..0] - (RO) Group8 source count +* RESERVED12[15..12] - (RO) Reserved bits +* G8_RSV_CNT[27..16] - (RO) Group8 reservation count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP8_G8_RSV_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP8_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP8_G8_RSV_CNT_MASK \ + 0x0FFF0000 /* G8_RSV_CNT[27..16] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP8_G8_RSV_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP8_G8_SRC_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP8_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP8_G8_SRC_CNT_MASK \ + 0x00000FFF /* G8_SRC_CNT[11..0] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP8_G8_SRC_CNT_SHFT 0 + +/* +* ---STATUS_RD_GP9 (0x7C026000 + 0x164)--- +* G9_SRC_CNT[11..0] - (RO) Group9 source count +* RESERVED12[15..12] - (RO) Reserved bits +* G9_RSV_CNT[27..16] - (RO) Group9 reservation count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP9_G9_RSV_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP9_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP9_G9_RSV_CNT_MASK \ + 0x0FFF0000 /* G9_RSV_CNT[27..16] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP9_G9_RSV_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP9_G9_SRC_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP9_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP9_G9_SRC_CNT_MASK \ + 0x00000FFF /* G9_SRC_CNT[11..0] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP9_G9_SRC_CNT_SHFT 0 + +/* +* ---STATUS_RD_GP10 (0x7C026000 + 0x168)--- +* G10_SRC_CNT[11..0] - (RO) Group10 source count +* RESERVED12[15..12] - (RO) Reserved bits +* G10_RSV_CNT[27..16] - (RO) Group10 reservation count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP10_G10_RSV_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP10_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP10_G10_RSV_CNT_MASK \ + 0x0FFF0000 /* G10_RSV_CNT[27..16] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP10_G10_RSV_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP10_G10_SRC_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP10_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP10_G10_SRC_CNT_MASK \ + 0x00000FFF /* G10_SRC_CNT[11..0] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP10_G10_SRC_CNT_SHFT 0 + +/* +* ---STATUS_RD_GP11 (0x7C026000 + 0x16c)--- +* G11_SRC_CNT[11..0] - (RO) Group11 source count +* RESERVED12[15..12] - (RO) Reserved bits +* G11_RSV_CNT[27..16] - (RO) Group11 reservation count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP11_G11_RSV_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP11_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP11_G11_RSV_CNT_MASK \ + 0x0FFF0000 /* G11_RSV_CNT[27..16] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP11_G11_RSV_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP11_G11_SRC_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP11_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP11_G11_SRC_CNT_MASK \ + 0x00000FFF /* G11_SRC_CNT[11..0] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP11_G11_SRC_CNT_SHFT 0 + +/* +* ---STATUS_RD_GP12 (0x7C026000 + 0x170)--- +* G12_SRC_CNT[11..0] - (RO) Group12 source count +* RESERVED12[15..12] - (RO) Reserved bits +* G12_RSV_CNT[27..16] - (RO) Group12 reservation count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP12_G12_RSV_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP12_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP12_G12_RSV_CNT_MASK \ + 0x0FFF0000 /* G12_RSV_CNT[27..16] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP12_G12_RSV_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP12_G12_SRC_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP12_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP12_G12_SRC_CNT_MASK \ + 0x00000FFF /* G12_SRC_CNT[11..0] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP12_G12_SRC_CNT_SHFT 0 + +/* +* ---STATUS_RD_GP13 (0x7C026000 + 0x174)--- +* G13_SRC_CNT[11..0] - (RO) Group13 source count +* RESERVED12[15..12] - (RO) Reserved bits +* G13_RSV_CNT[27..16] - (RO) Group13 reservation count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP13_G13_RSV_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP13_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP13_G13_RSV_CNT_MASK \ + 0x0FFF0000 /* G13_RSV_CNT[27..16] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP13_G13_RSV_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP13_G13_SRC_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP13_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP13_G13_SRC_CNT_MASK \ + 0x00000FFF /* G13_SRC_CNT[11..0] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP13_G13_SRC_CNT_SHFT 0 + +/* +* ---STATUS_RD_GP14 (0x7C026000 + 0x178)--- +* G14_SRC_CNT[11..0] - (RO) Group14 source count +* RESERVED12[15..12] - (RO) Reserved bits +* G14_RSV_CNT[27..16] - (RO) Group14 reservation count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP14_G14_RSV_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP14_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP14_G14_RSV_CNT_MASK \ + 0x0FFF0000 /* G14_RSV_CNT[27..16] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP14_G14_RSV_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP14_G14_SRC_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP14_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP14_G14_SRC_CNT_MASK \ + 0x00000FFF /* G14_SRC_CNT[11..0] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP14_G14_SRC_CNT_SHFT 0 + +/* +* ---STATUS_RD_GP15 (0x7C026000 + 0x17C)--- +* G15_SRC_CNT[11..0] - (RO) Group15 source count +* RESERVED12[15..12] - (RO) Reserved bits +* G15_RSV_CNT[27..16] - (RO) Group15 reservation count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP15_G15_RSV_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP15_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP15_G15_RSV_CNT_MASK \ + 0x0FFF0000 /* G15_RSV_CNT[27..16] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP15_G15_RSV_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP15_G15_SRC_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP15_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP15_G15_SRC_CNT_MASK \ + 0x00000FFF /* G15_SRC_CNT[11..0] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP15_G15_SRC_CNT_SHFT 0 + +/* +* ---RD_GROUP_PKT_CNT0 (0x7C026000 + 0x180)--- +* GP0_ASK_CNT[7..0] - (RO) Group0 ask count +* GP0_PKTIN_CNT[15..8] - (RO) Group0 packet in count +* GP1_ASK_CNT[23..16] - (RO) Group1 ask count +* GP1_PKTIN_CNT[31..24] - (RO) Group1 packet in count +*/ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT0_GP1_PKTIN_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT0_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT0_GP1_PKTIN_CNT_MASK \ + 0xFF000000 /* GP1_PKTIN_CNT[31..24] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT0_GP1_PKTIN_CNT_SHFT 24 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT0_GP1_ASK_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT0_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT0_GP1_ASK_CNT_MASK \ + 0x00FF0000 /* GP1_ASK_CNT[23..16] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT0_GP1_ASK_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT0_GP0_PKTIN_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT0_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT0_GP0_PKTIN_CNT_MASK \ + 0x0000FF00 /* GP0_PKTIN_CNT[15..8] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT0_GP0_PKTIN_CNT_SHFT 8 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT0_GP0_ASK_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT0_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT0_GP0_ASK_CNT_MASK \ + 0x000000FF /* GP0_ASK_CNT[7..0] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT0_GP0_ASK_CNT_SHFT 0 + +/* +* ---RD_GROUP_PKT_CNT1 (0x7C026000 + 0x184)--- +* GP2_ASK_CNT[7..0] - (RO) Group2 ask count +* GP2_PKTIN_CNT[15..8] - (RO) Group2 packet in count +* GP3_ASK_CNT[23..16] - (RO) Group3 ask count +* GP3_PKTIN_CNT[31..24] - (RO) Group3 packet in count +*/ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT1_GP3_PKTIN_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT1_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT1_GP3_PKTIN_CNT_MASK \ + 0xFF000000 /* GP3_PKTIN_CNT[31..24] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT1_GP3_PKTIN_CNT_SHFT 24 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT1_GP3_ASK_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT1_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT1_GP3_ASK_CNT_MASK \ + 0x00FF0000 /* GP3_ASK_CNT[23..16] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT1_GP3_ASK_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT1_GP2_PKTIN_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT1_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT1_GP2_PKTIN_CNT_MASK \ + 0x0000FF00 /* GP2_PKTIN_CNT[15..8] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT1_GP2_PKTIN_CNT_SHFT 8 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT1_GP2_ASK_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT1_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT1_GP2_ASK_CNT_MASK \ + 0x000000FF /* GP2_ASK_CNT[7..0] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT1_GP2_ASK_CNT_SHFT 0 + +/* +* ---RD_GROUP_PKT_CNT2 (0x7C026000 + 0x188)--- +* GP4_ASK_CNT[7..0] - (RO) Group4 ask count +* GP4_PKTIN_CNT[15..8] - (RO) Group4 packet in count +* GP5_ASK_CNT[23..16] - (RO) Group5 ask count +* GP5_PKTIN_CNT[31..24] - (RO) Group5 packet in count +*/ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT2_GP5_PKTIN_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT2_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT2_GP5_PKTIN_CNT_MASK \ + 0xFF000000 /* GP5_PKTIN_CNT[31..24] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT2_GP5_PKTIN_CNT_SHFT 24 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT2_GP5_ASK_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT2_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT2_GP5_ASK_CNT_MASK \ + 0x00FF0000 /* GP5_ASK_CNT[23..16] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT2_GP5_ASK_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT2_GP4_PKTIN_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT2_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT2_GP4_PKTIN_CNT_MASK \ + 0x0000FF00 /* GP4_PKTIN_CNT[15..8] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT2_GP4_PKTIN_CNT_SHFT 8 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT2_GP4_ASK_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT2_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT2_GP4_ASK_CNT_MASK \ + 0x000000FF /* GP4_ASK_CNT[7..0] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT2_GP4_ASK_CNT_SHFT 0 + +/* +* ---RD_GROUP_PKT_CNT3 (0x7C026000 + 0x18c)--- +* GP6_ASK_CNT[7..0] - (RO) Group6 ask count +* GP6_PKTIN_CNT[15..8] - (RO) Group6 packet in count +* GP7_ASK_CNT[23..16] - (RO) Group7 ask count +* GP7_PKTIN_CNT[31..24] - (RO) Group7 packet in count +*/ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT3_GP7_PKTIN_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT3_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT3_GP7_PKTIN_CNT_MASK \ + 0xFF000000 /* GP7_PKTIN_CNT[31..24] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT3_GP7_PKTIN_CNT_SHFT 24 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT3_GP7_ASK_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT3_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT3_GP7_ASK_CNT_MASK \ + 0x00FF0000 /* GP7_ASK_CNT[23..16] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT3_GP7_ASK_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT3_GP6_PKTIN_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT3_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT3_GP6_PKTIN_CNT_MASK \ + 0x0000FF00 /* GP6_PKTIN_CNT[15..8] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT3_GP6_PKTIN_CNT_SHFT 8 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT3_GP6_ASK_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT3_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT3_GP6_ASK_CNT_MASK \ + 0x000000FF /* GP6_ASK_CNT[7..0] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT3_GP6_ASK_CNT_SHFT 0 + +/* +* ---RD_GROUP_PKT_CNT4 (0x7C026000 + 0x190)--- +* GP8_ASK_CNT[7..0] - (RO) Group8 ask count +* GP8_PKTIN_CNT[15..8] - (RO) Group8 packet in count +* GP9_ASK_CNT[23..16] - (RO) Group9 ask count +* GP9_PKTIN_CNT[31..24] - (RO) Group9 packet in count +*/ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT4_GP9_PKTIN_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT4_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT4_GP9_PKTIN_CNT_MASK \ + 0xFF000000 /* GP9_PKTIN_CNT[31..24] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT4_GP9_PKTIN_CNT_SHFT 24 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT4_GP9_ASK_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT4_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT4_GP9_ASK_CNT_MASK \ + 0x00FF0000 /* GP9_ASK_CNT[23..16] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT4_GP9_ASK_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT4_GP8_PKTIN_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT4_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT4_GP8_PKTIN_CNT_MASK \ + 0x0000FF00 /* GP8_PKTIN_CNT[15..8] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT4_GP8_PKTIN_CNT_SHFT 8 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT4_GP8_ASK_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT4_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT4_GP8_ASK_CNT_MASK \ + 0x000000FF /* GP8_ASK_CNT[7..0] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT4_GP8_ASK_CNT_SHFT 0 + +/* +* ---RD_GROUP_PKT_CNT5 (0x7C026000 + 0x194)--- +* GP10_ASK_CNT[7..0] - (RO) Group10 ask count +* GP10_PKTIN_CNT[15..8] - (RO) Group10 packet in count +* GP11_ASK_CNT[23..16] - (RO) Group11 ask count +* GP11_PKTIN_CNT[31..24] - (RO) Group11 packet in count +*/ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT5_GP11_PKTIN_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT5_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT5_GP11_PKTIN_CNT_MASK \ + 0xFF000000 /* GP11_PKTIN_CNT[31..24] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT5_GP11_PKTIN_CNT_SHFT 24 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT5_GP11_ASK_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT5_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT5_GP11_ASK_CNT_MASK \ + 0x00FF0000 /* GP11_ASK_CNT[23..16] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT5_GP11_ASK_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT5_GP10_PKTIN_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT5_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT5_GP10_PKTIN_CNT_MASK \ + 0x0000FF00 /* GP10_PKTIN_CNT[15..8] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT5_GP10_PKTIN_CNT_SHFT 8 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT5_GP10_ASK_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT5_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT5_GP10_ASK_CNT_MASK \ + 0x000000FF /* GP10_ASK_CNT[7..0] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT5_GP10_ASK_CNT_SHFT 0 + +/* +* ---RD_GROUP_PKT_CNT6 (0x7C026000 + 0x198)--- +* GP12_ASK_CNT[7..0] - (RO) Group12 ask count +* GP12_PKTIN_CNT[15..8] - (RO) Group12 packet in count +* GP13_ASK_CNT[23..16] - (RO) Group13 ask count +* GP13_PKTIN_CNT[31..24] - (RO) Group13 packet in count +*/ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT6_GP13_PKTIN_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT6_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT6_GP13_PKTIN_CNT_MASK \ + 0xFF000000 /* GP13_PKTIN_CNT[31..24] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT6_GP13_PKTIN_CNT_SHFT 24 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT6_GP13_ASK_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT6_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT6_GP13_ASK_CNT_MASK \ + 0x00FF0000 /* GP13_ASK_CNT[23..16] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT6_GP13_ASK_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT6_GP12_PKTIN_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT6_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT6_GP12_PKTIN_CNT_MASK \ + 0x0000FF00 /* GP12_PKTIN_CNT[15..8] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT6_GP12_PKTIN_CNT_SHFT 8 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT6_GP12_ASK_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT6_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT6_GP12_ASK_CNT_MASK \ + 0x000000FF /* GP12_ASK_CNT[7..0] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT6_GP12_ASK_CNT_SHFT 0 + +/* +* ---RD_GROUP_PKT_CNT7 (0x7C026000 + 0x19c)--- +* GP14_ASK_CNT[7..0] - (RO) Group14 ask count +* GP14_PKTIN_CNT[15..8] - (RO) Group14 packet in count +* GP15_ASK_CNT[23..16] - (RO) Group15 ask count +* GP15_PKTIN_CNT[31..24] - (RO) Group15 packet in count +*/ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT7_GP15_PKTIN_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT7_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT7_GP15_PKTIN_CNT_MASK \ + 0xFF000000 /* GP15_PKTIN_CNT[31..24] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT7_GP15_PKTIN_CNT_SHFT 24 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT7_GP15_ASK_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT7_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT7_GP15_ASK_CNT_MASK \ + 0x00FF0000 /* GP15_ASK_CNT[23..16] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT7_GP15_ASK_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT7_GP14_PKTIN_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT7_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT7_GP14_PKTIN_CNT_MASK \ + 0x0000FF00 /* GP14_PKTIN_CNT[15..8] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT7_GP14_PKTIN_CNT_SHFT 8 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT7_GP14_ASK_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT7_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT7_GP14_ASK_CNT_MASK \ + 0x000000FF /* GP14_ASK_CNT[7..0] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT7_GP14_ASK_CNT_SHFT 0 + +#ifdef __cplusplus +} +#endif + +#endif /* __WF_HIF_DMASHDL_TOP_REGS_H__ */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/mt7961/wf_ple_top.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/mt7961/wf_ple_top.h new file mode 100644 index 0000000000000000000000000000000000000000..0e957b86cef912ed3f0e81312681c49f12581ba2 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/mt7961/wf_ple_top.h @@ -0,0 +1,6731 @@ +/* [File] : wf_ple_top.h */ +/* [Revision time] : Fri May 31 13:36:43 2019 */ +/* [Description] : This file is auto generated by CODA */ +/* [Copyright] : Copyright (C) 2019 Mediatek Incorportion. All rights */ +/* reserved. */ + +#ifndef __WF_PLE_TOP_REGS_H__ +#define __WF_PLE_TOP_REGS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* ************************************************************************** */ +/* */ +/* WF_PLE_TOP CR Definitions */ +/* */ +/* ************************************************************************** */ + +#define WF_PLE_TOP_BASE 0x820C0000 + +#define WF_PLE_TOP_GC_ADDR \ + (WF_PLE_TOP_BASE + 0x00) /* 0000 */ +#define WF_PLE_TOP_PBUF_CTRL_ADDR \ + (WF_PLE_TOP_BASE + 0x04) /* 0004 */ +#define WF_PLE_TOP_FREEPG_START_END_ADDR \ + (WF_PLE_TOP_BASE + 0x08) /* 0008 */ +#define WF_PLE_TOP_PG_HIF_GROUP_ADDR \ + (WF_PLE_TOP_BASE + 0x0c) /* 000C */ +#define WF_PLE_TOP_PG_HIF_WMTXD_GROUP_ADDR \ + (WF_PLE_TOP_BASE + 0x10) /* 0010 */ +#define WF_PLE_TOP_PG_HIF_TXCMD_GROUP_ADDR \ + (WF_PLE_TOP_BASE + 0x14) /* 0014 */ +#define WF_PLE_TOP_PG_CPU_GROUP_ADDR \ + (WF_PLE_TOP_BASE + 0x18) /* 0018 */ +#define WF_PLE_TOP_VOW_CONTROL_ADDR \ + (WF_PLE_TOP_BASE + 0x1c) /* 001C */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL1_ADDR \ + (WF_PLE_TOP_BASE + 0x20) /* 0020 */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL2_ADDR \ + (WF_PLE_TOP_BASE + 0x24) /* 0024 */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL3_ADDR \ + (WF_PLE_TOP_BASE + 0x28) /* 0028 */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL4_ADDR \ + (WF_PLE_TOP_BASE + 0x2c) /* 002C */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL5_ADDR \ + (WF_PLE_TOP_BASE + 0x30) /* 0030 */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL6_ADDR \ + (WF_PLE_TOP_BASE + 0x34) /* 0034 */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL7_ADDR \ + (WF_PLE_TOP_BASE + 0x38) /* 0038 */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL8_ADDR \ + (WF_PLE_TOP_BASE + 0x3c) /* 003C */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL9_ADDR \ + (WF_PLE_TOP_BASE + 0x40) /* 0040 */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL10_ADDR \ + (WF_PLE_TOP_BASE + 0x44) /* 0044 */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR \ + (WF_PLE_TOP_BASE + 0x48) /* 0048 */ +#define WF_PLE_TOP_INT_N9_EN_MASK_ADDR \ + (WF_PLE_TOP_BASE + 0x80) /* 0080 */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_ADDR \ + (WF_PLE_TOP_BASE + 0x84) /* 0084 */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR \ + (WF_PLE_TOP_BASE + 0x88) /* 0088 */ +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_ADDR \ + (WF_PLE_TOP_BASE + 0x8c) /* 008C */ +#define WF_PLE_TOP_HOST_REPORT0_ADDR \ + (WF_PLE_TOP_BASE + 0x90) /* 0090 */ +#define WF_PLE_TOP_HOST_REPORT1_ADDR \ + (WF_PLE_TOP_BASE + 0x94) /* 0094 */ +#define WF_PLE_TOP_HOST_REPORT2_ADDR \ + (WF_PLE_TOP_BASE + 0x98) /* 0098 */ +#define WF_PLE_TOP_RELEASE_CTRL_0_ADDR \ + (WF_PLE_TOP_BASE + 0x9c) /* 009C */ +#define WF_PLE_TOP_RELEASE_CTRL_1_ADDR \ + (WF_PLE_TOP_BASE + 0xA0) /* 00A0 */ +#define WF_PLE_TOP_RELEASE_CTRL_3_ADDR \ + (WF_PLE_TOP_BASE + 0xa8) /* 00A8 */ +#define WF_PLE_TOP_BLK_MODE_RATE_LMT_ADDR \ + (WF_PLE_TOP_BASE + 0xac) /* 00AC */ +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_ADDR \ + (WF_PLE_TOP_BASE + 0xb0) /* 00B0 */ +#define WF_PLE_TOP_PLE_DELAY_TX_CTRL_ADDR \ + (WF_PLE_TOP_BASE + 0xb4) /* 00B4 */ +#define WF_PLE_TOP_PLE_STATION_REDIR_CTRL_ADDR \ + (WF_PLE_TOP_BASE + 0xb8) /* 00B8 */ +#define WF_PLE_TOP_MACTX_LENGTH_LIMIT_ADDR \ + (WF_PLE_TOP_BASE + 0xBC) /* 00BC */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_ADDR \ + (WF_PLE_TOP_BASE + 0xc0) /* 00C0 */ +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_ADDR \ + (WF_PLE_TOP_BASE + 0xd0) /* 00D0 */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR \ + (WF_PLE_TOP_BASE + 0xd4) /* 00D4 */ +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_1_ADDR \ + (WF_PLE_TOP_BASE + 0xd8) /* 00D8 */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_ADDR \ + (WF_PLE_TOP_BASE + 0xdc) /* 00DC */ +#define WF_PLE_TOP_ERLY_TRM_CTRL0_ADDR \ + (WF_PLE_TOP_BASE + 0xf8) /* 00F8 */ +#define WF_PLE_TOP_ERLY_TRM_CTRL1_ADDR \ + (WF_PLE_TOP_BASE + 0xfc) /* 00FC */ +#define WF_PLE_TOP_STATION_PAUSE0_ADDR \ + (WF_PLE_TOP_BASE + 0x100) /* 0100 */ +#define WF_PLE_TOP_STATION_PAUSE1_ADDR \ + (WF_PLE_TOP_BASE + 0x104) /* 0104 */ +#define WF_PLE_TOP_DIS_STA_MAP0_ADDR \ + (WF_PLE_TOP_BASE + 0x140) /* 0140 */ +#define WF_PLE_TOP_DIS_STA_MAP1_ADDR \ + (WF_PLE_TOP_BASE + 0x144) /* 0144 */ +#define WF_PLE_TOP_STATION_REDIR0_ADDR \ + (WF_PLE_TOP_BASE + 0x180) /* 0180 */ +#define WF_PLE_TOP_STATION_REDIR1_ADDR \ + (WF_PLE_TOP_BASE + 0x184) /* 0184 */ +#define WF_PLE_TOP_TWT_STA_MAP0_ADDR \ + (WF_PLE_TOP_BASE + 0x1C0) /* 01C0 */ +#define WF_PLE_TOP_TWT_STA_MAP1_ADDR \ + (WF_PLE_TOP_BASE + 0x1C4) /* 01C4 */ +#define WF_PLE_TOP_TWT_TX_CTRL0_ADDR \ + (WF_PLE_TOP_BASE + 0x200) /* 0200 */ +#define WF_PLE_TOP_DRR_SPL_CTRL_ADDR \ + (WF_PLE_TOP_BASE + 0x204) /* 0204 */ +#define WF_PLE_TOP_BSS_DBDC_CTRL_ADDR \ + (WF_PLE_TOP_BASE + 0x208) /* 0208 */ +#define WF_PLE_TOP_VOW_CTRL1_ADDR \ + (WF_PLE_TOP_BASE + 0x20c) /* 020C */ +#define WF_PLE_TOP_TWT_STA_TABLE0_ADDR \ + (WF_PLE_TOP_BASE + 0x210) /* 0210 */ +#define WF_PLE_TOP_TWT_STA_TABLE1_ADDR \ + (WF_PLE_TOP_BASE + 0x214) /* 0214 */ +#define WF_PLE_TOP_TWT_STA_TABLE2_ADDR \ + (WF_PLE_TOP_BASE + 0x218) /* 0218 */ +#define WF_PLE_TOP_TWT_STA_TABLE3_ADDR \ + (WF_PLE_TOP_BASE + 0x21c) /* 021C */ +#define WF_PLE_TOP_TWT_SW_CTRL_ADDR \ + (WF_PLE_TOP_BASE + 0x220) /* 0220 */ +#define WF_PLE_TOP_TWT_HW_SRCHCMD_FULL_ADDR \ + (WF_PLE_TOP_BASE + 0x224) /* 0224 */ +#define WF_PLE_TOP_DRR_SW_CTRL_ADDR \ + (WF_PLE_TOP_BASE + 0x228) /* 0228 */ +#define WF_PLE_TOP_DRR_SPL_CTRL_1_ADDR \ + (WF_PLE_TOP_BASE + 0x22c) /* 022C */ +#define WF_PLE_TOP_TWT_STA_FIX_AC_ADDR \ + (WF_PLE_TOP_BASE + 0x234) /* 0234 */ +#define WF_PLE_TOP_EN_UMAC_L1_DCM_ADDR \ + (WF_PLE_TOP_BASE + 0x238) /* 0238 */ +#define WF_PLE_TOP_PCIE_POWER_CTRL_ADDR \ + (WF_PLE_TOP_BASE + 0x23c) /* 023C */ +#define WF_PLE_TOP_TIMEOUT_CTRL_ADDR \ + (WF_PLE_TOP_BASE + 0x280) /* 0280 */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_ADDR \ + (WF_PLE_TOP_BASE + 0x284) /* 0284 */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_1_ADDR \ + (WF_PLE_TOP_BASE + 0x288) /* 0288 */ +#define WF_PLE_TOP_PORT_SER_CTRL_ADDR \ + (WF_PLE_TOP_BASE + 0x290) /* 0290 */ +#define WF_PLE_TOP_MACTX_SER_CTRL_ADDR \ + (WF_PLE_TOP_BASE + 0x294) /* 0294 */ +#define WF_PLE_TOP_DRR_SER_CTRL_ADDR \ + (WF_PLE_TOP_BASE + 0x298) /* 0298 */ +#define WF_PLE_TOP_INT_N9_STS_ADDR \ + (WF_PLE_TOP_BASE + 0x300) /* 0300 */ +#define WF_PLE_TOP_INT_N9_ERR_STS_ADDR \ + (WF_PLE_TOP_BASE + 0x304) /* 0304 */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR \ + (WF_PLE_TOP_BASE + 0x308) /* 0308 */ +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_ADDR \ + (WF_PLE_TOP_BASE + 0x30c) /* 030C */ +#define WF_PLE_TOP_C_GET_FID_0_ADDR \ + (WF_PLE_TOP_BASE + 0x310) /* 0310 */ +#define WF_PLE_TOP_C_GET_FID_1_ADDR \ + (WF_PLE_TOP_BASE + 0x314) /* 0314 */ +#define WF_PLE_TOP_TO_N9_INT_ADDR \ + (WF_PLE_TOP_BASE + 0x318) /* 0318 */ +#define WF_PLE_TOP_C_EN_QUEUE_0_ADDR \ + (WF_PLE_TOP_BASE + 0x320) /* 0320 */ +#define WF_PLE_TOP_C_EN_QUEUE_1_ADDR \ + (WF_PLE_TOP_BASE + 0x324) /* 0324 */ +#define WF_PLE_TOP_C_EN_QUEUE_2_ADDR \ + (WF_PLE_TOP_BASE + 0x328) /* 0328 */ +#define WF_PLE_TOP_C_DE_QUEUE_0_ADDR \ + (WF_PLE_TOP_BASE + 0x330) /* 0330 */ +#define WF_PLE_TOP_C_DE_QUEUE_1_ADDR \ + (WF_PLE_TOP_BASE + 0x334) /* 0334 */ +#define WF_PLE_TOP_C_DE_QUEUE_2_ADDR \ + (WF_PLE_TOP_BASE + 0x338) /* 0338 */ +#define WF_PLE_TOP_C_DE_QUEUE_3_ADDR \ + (WF_PLE_TOP_BASE + 0x33c) /* 033C */ +#define WF_PLE_TOP_C_DE_QUEUE_4_ADDR \ + (WF_PLE_TOP_BASE + 0x340) /* 0340 */ +#define WF_PLE_TOP_ALLOCATE_0_ADDR \ + (WF_PLE_TOP_BASE + 0x350) /* 0350 */ +#define WF_PLE_TOP_ALLOCATE_1_ADDR \ + (WF_PLE_TOP_BASE + 0x354) /* 0354 */ +#define WF_PLE_TOP_ALLOCATE_2_ADDR \ + (WF_PLE_TOP_BASE + 0x358) /* 0358 */ +#define WF_PLE_TOP_QUEUE_EMPTY_ADDR \ + (WF_PLE_TOP_BASE + 0x360) /* 0360 */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR \ + (WF_PLE_TOP_BASE + 0x364) /* 0364 */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR \ + (WF_PLE_TOP_BASE + 0x368) /* 0368 */ +#define WF_PLE_TOP_DRR_CHNL_EMPTY_ADDR \ + (WF_PLE_TOP_BASE + 0x374) /* 0374 */ +#define WF_PLE_TOP_FREEPG_CNT_ADDR \ + (WF_PLE_TOP_BASE + 0x380) /* 0380 */ +#define WF_PLE_TOP_FREEPG_HEAD_TAIL_ADDR \ + (WF_PLE_TOP_BASE + 0x384) /* 0384 */ +#define WF_PLE_TOP_HIF_PG_INFO_ADDR \ + (WF_PLE_TOP_BASE + 0x388) /* 0388 */ +#define WF_PLE_TOP_HIF_WMTXD_PG_INFO_ADDR \ + (WF_PLE_TOP_BASE + 0x38c) /* 038C */ +#define WF_PLE_TOP_HIF_TXCMD_PG_INFO_ADDR \ + (WF_PLE_TOP_BASE + 0x390) /* 0390 */ +#define WF_PLE_TOP_CPU_PG_INFO_ADDR \ + (WF_PLE_TOP_BASE + 0x394) /* 0394 */ +#define WF_PLE_TOP_PLE_LOG_0_ADDR \ + (WF_PLE_TOP_BASE + 0x3a0) /* 03A0 */ +#define WF_PLE_TOP_PLE_LOG_1_ADDR \ + (WF_PLE_TOP_BASE + 0x3a4) /* 03A4 */ +#define WF_PLE_TOP_PLE_LOG_2_ADDR \ + (WF_PLE_TOP_BASE + 0x3a8) /* 03A8 */ +#define WF_PLE_TOP_PLE_LOG_3_ADDR \ + (WF_PLE_TOP_BASE + 0x3ac) /* 03AC */ +#define WF_PLE_TOP_WMMAC_PGCNT_0_ADDR \ + (WF_PLE_TOP_BASE + 0x3b0) /* 03B0 */ +#define WF_PLE_TOP_WMMAC_PGCNT_1_ADDR \ + (WF_PLE_TOP_BASE + 0x3b4) /* 03B4 */ +#define WF_PLE_TOP_WMMAC_PGCNT_2_ADDR \ + (WF_PLE_TOP_BASE + 0x3b8) /* 03B8 */ +#define WF_PLE_TOP_WMMAC_PGCNT_3_ADDR \ + (WF_PLE_TOP_BASE + 0x3bc) /* 03BC */ +#define WF_PLE_TOP_WMMAC_PGCNT_4_ADDR \ + (WF_PLE_TOP_BASE + 0x3c0) /* 03C0 */ +#define WF_PLE_TOP_WMMAC_PGCNT_5_ADDR \ + (WF_PLE_TOP_BASE + 0x3c4) /* 03C4 */ +#define WF_PLE_TOP_WMMAC_PGCNT_6_ADDR \ + (WF_PLE_TOP_BASE + 0x3c8) /* 03C8 */ +#define WF_PLE_TOP_WMMAC_PGCNT_7_ADDR \ + (WF_PLE_TOP_BASE + 0x3cc) /* 03CC */ +#define WF_PLE_TOP_RL_BUF_CTRL_0_ADDR \ + (WF_PLE_TOP_BASE + 0x3d0) /* 03D0 */ +#define WF_PLE_TOP_RL_BUF_CTRL_1_ADDR \ + (WF_PLE_TOP_BASE + 0x3d4) /* 03D4 */ +#define WF_PLE_TOP_FL_QUE_CTRL_0_ADDR \ + (WF_PLE_TOP_BASE + 0x3e0) /* 03E0 */ +#define WF_PLE_TOP_FL_QUE_CTRL_1_ADDR \ + (WF_PLE_TOP_BASE + 0x3e4) /* 03E4 */ +#define WF_PLE_TOP_FL_QUE_CTRL_2_ADDR \ + (WF_PLE_TOP_BASE + 0x3e8) /* 03E8 */ +#define WF_PLE_TOP_FL_QUE_CTRL_3_ADDR \ + (WF_PLE_TOP_BASE + 0x3ec) /* 03EC */ +#define WF_PLE_TOP_PL_QUE_CTRL_0_ADDR \ + (WF_PLE_TOP_BASE + 0x3f0) /* 03F0 */ +#define WF_PLE_TOP_HIF_ENQ_PKT_NUM_ADDR \ + (WF_PLE_TOP_BASE + 0x400) /* 0400 */ +#define WF_PLE_TOP_CPU_ENQ_PKT_NUM_ADDR \ + (WF_PLE_TOP_BASE + 0x404) /* 0404 */ +#define WF_PLE_TOP_RLS_MSDU_PKT_NUM_ADDR \ + (WF_PLE_TOP_BASE + 0x408) /* 0408 */ +#define WF_PLE_TOP_HOST_REPORT_NUM_ADDR \ + (WF_PLE_TOP_BASE + 0x40c) /* 040C */ +#define WF_PLE_TOP_UMAC_DBG_CTRL_ADDR \ + (WF_PLE_TOP_BASE + 0x410) /* 0410 */ +#define WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_ADDR \ + (WF_PLE_TOP_BASE + 0x414) /* 0414 */ +#define WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_ADDR \ + (WF_PLE_TOP_BASE + 0x418) /* 0418 */ +#define WF_PLE_TOP_FUNC_ACT_CNT_1_ADDR \ + (WF_PLE_TOP_BASE + 0x424) /* 0424 */ +#define WF_PLE_TOP_SRAM_MBIST_BACKGROUND_ADDR \ + (WF_PLE_TOP_BASE + 0x430) /* 0430 */ +#define WF_PLE_TOP_SRAM_MBIST_BSEL_ADDR \ + (WF_PLE_TOP_BASE + 0x434) /* 0434 */ +#define WF_PLE_TOP_SRAM_MBIST_DONE_ADDR \ + (WF_PLE_TOP_BASE + 0x438) /* 0438 */ +#define WF_PLE_TOP_SRAM_MBIST_FAIL_ADDR \ + (WF_PLE_TOP_BASE + 0x43c) /* 043C */ +#define WF_PLE_TOP_SRAM_AWT_HDEN_CTRL_ADDR \ + (WF_PLE_TOP_BASE + 0x440) /* 0440 */ +#define WF_PLE_TOP_DRR_TABLE_WDATA0_ADDR \ + (WF_PLE_TOP_BASE + 0x450) /* 0450 */ +#define WF_PLE_TOP_DRR_TABLE_WDATA1_ADDR \ + (WF_PLE_TOP_BASE + 0x454) /* 0454 */ +#define WF_PLE_TOP_DRR_TABLE_WDATA2_ADDR \ + (WF_PLE_TOP_BASE + 0x458) /* 0458 */ +#define WF_PLE_TOP_DRR_TABLE_WDATA3_ADDR \ + (WF_PLE_TOP_BASE + 0x45c) /* 045C */ +#define WF_PLE_TOP_DRR_TABLE_WDATA4_ADDR \ + (WF_PLE_TOP_BASE + 0x460) /* 0460 */ +#define WF_PLE_TOP_DRR_TABLE_WDATA5_ADDR \ + (WF_PLE_TOP_BASE + 0x464) /* 0464 */ +#define WF_PLE_TOP_DRR_TABLE_WDATA6_ADDR \ + (WF_PLE_TOP_BASE + 0x468) /* 0468 */ +#define WF_PLE_TOP_DRR_TABLE_WDATA7_ADDR \ + (WF_PLE_TOP_BASE + 0x46c) /* 046C */ +#define WF_PLE_TOP_DRR_TABLE_RDATA0_ADDR \ + (WF_PLE_TOP_BASE + 0x470) /* 0470 */ +#define WF_PLE_TOP_DRR_TABLE_RDATA1_ADDR \ + (WF_PLE_TOP_BASE + 0x474) /* 0474 */ +#define WF_PLE_TOP_DRR_TABLE_RDATA2_ADDR \ + (WF_PLE_TOP_BASE + 0x478) /* 0478 */ +#define WF_PLE_TOP_DRR_TABLE_RDATA3_ADDR \ + (WF_PLE_TOP_BASE + 0x47c) /* 047C */ +#define WF_PLE_TOP_DRR_TABLE_RDATA4_ADDR \ + (WF_PLE_TOP_BASE + 0x480) /* 0480 */ +#define WF_PLE_TOP_DRR_TABLE_RDATA5_ADDR \ + (WF_PLE_TOP_BASE + 0x484) /* 0484 */ +#define WF_PLE_TOP_DRR_TABLE_RDATA6_ADDR \ + (WF_PLE_TOP_BASE + 0x488) /* 0488 */ +#define WF_PLE_TOP_DRR_TABLE_RDATA7_ADDR \ + (WF_PLE_TOP_BASE + 0x48c) /* 048C */ +#define WF_PLE_TOP_DRR_TABLE_CTRL_ADDR \ + (WF_PLE_TOP_BASE + 0x490) /* 0490 */ +#define WF_PLE_TOP_AIRTIME_DRR_SIZE_ADDR \ + (WF_PLE_TOP_BASE + 0x494) /* 0494 */ +#define WF_PLE_TOP_CHECK_BW_TIME_TOKEN__ADDR \ + (WF_PLE_TOP_BASE + 0x498) /* 0498 */ +#define WF_PLE_TOP_CHECK_BW_LENGTH_TOKEN__ADDR \ + (WF_PLE_TOP_BASE + 0x49c) /* 049C */ +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_ADDR \ + (WF_PLE_TOP_BASE + 0x4a0) /* 04A0 */ +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_ADDR \ + (WF_PLE_TOP_BASE + 0x4a4)/* 04A4 */ +#define WF_PLE_TOP_DRR_HW_SRCHCMD_FULL_ADDR \ + (WF_PLE_TOP_BASE + 0x4c0) /* 04C0 */ +#define WF_PLE_TOP_TWT_DBG_ADDR \ + (WF_PLE_TOP_BASE + 0x4d0) /* 04D0 */ +#define WF_PLE_TOP_VOW_DBG_SEL_ADDR \ + (WF_PLE_TOP_BASE + 0x4d4) /* 04D4 */ +#define WF_PLE_TOP_AIRTIME_DBG_INFO0_ADDR \ + (WF_PLE_TOP_BASE + 0x4d8) /* 04D8 */ +#define WF_PLE_TOP_AIRTIME_DBG_INFO1_ADDR \ + (WF_PLE_TOP_BASE + 0x4dc) /* 04DC */ +#define WF_PLE_TOP_AC0_QUEUE_EMPTY0_ADDR \ + (WF_PLE_TOP_BASE + 0x500) /* 0500 */ +#define WF_PLE_TOP_AC0_QUEUE_EMPTY1_ADDR \ + (WF_PLE_TOP_BASE + 0x504) /* 0504 */ +#define WF_PLE_TOP_AC1_QUEUE_EMPTY0_ADDR \ + (WF_PLE_TOP_BASE + 0x540) /* 0540 */ +#define WF_PLE_TOP_AC1_QUEUE_EMPTY1_ADDR \ + (WF_PLE_TOP_BASE + 0x544) /* 0544 */ +#define WF_PLE_TOP_AC2_QUEUE_EMPTY0_ADDR \ + (WF_PLE_TOP_BASE + 0x580) /* 0580 */ +#define WF_PLE_TOP_AC2_QUEUE_EMPTY1_ADDR \ + (WF_PLE_TOP_BASE + 0x584) /* 0584 */ +#define WF_PLE_TOP_AC3_QUEUE_EMPTY0_ADDR \ + (WF_PLE_TOP_BASE + 0x5c0) /* 05C0 */ +#define WF_PLE_TOP_AC3_QUEUE_EMPTY1_ADDR \ + (WF_PLE_TOP_BASE + 0x5c4) /* 05C4 */ +#define WF_PLE_TOP_PEEK_CR_00_ADDR \ + (WF_PLE_TOP_BASE + 0x600) /* 0600 */ +#define WF_PLE_TOP_PEEK_CR_01_ADDR \ + (WF_PLE_TOP_BASE + 0x604) /* 0604 */ +#define WF_PLE_TOP_PEEK_CR_02_ADDR \ + (WF_PLE_TOP_BASE + 0x608) /* 0608 */ +#define WF_PLE_TOP_PEEK_CR_03_ADDR \ + (WF_PLE_TOP_BASE + 0x60C) /* 060C */ +#define WF_PLE_TOP_PEEK_CR_04_ADDR \ + (WF_PLE_TOP_BASE + 0x610) /* 0610 */ +#define WF_PLE_TOP_PEEK_CR_05_ADDR \ + (WF_PLE_TOP_BASE + 0x614) /* 0614 */ +#define WF_PLE_TOP_PEEK_CR_06_ADDR \ + (WF_PLE_TOP_BASE + 0x618) /* 0618 */ +#define WF_PLE_TOP_PEEK_CR_07_ADDR \ + (WF_PLE_TOP_BASE + 0x61c) /* 061C */ +#define WF_PLE_TOP_PEEK_CR_08_ADDR \ + (WF_PLE_TOP_BASE + 0x620) /* 0620 */ +#define WF_PLE_TOP_PEEK_CR_09_ADDR \ + (WF_PLE_TOP_BASE + 0x624) /* 0624 */ +#define WF_PLE_TOP_PEEK_CR_10_ADDR \ + (WF_PLE_TOP_BASE + 0x628) /* 0628 */ +#define WF_PLE_TOP_PEEK_CR_11_ADDR \ + (WF_PLE_TOP_BASE + 0x62c) /* 062C */ +#define WF_PLE_TOP_AMSDU_GC_ADDR \ + (WF_PLE_TOP_BASE + 0x1000) /* 1000 */ +#define WF_PLE_TOP_AMSDU_TXD_COMP_MAP_0_ADDR \ + (WF_PLE_TOP_BASE + 0x1004) /* 1004 */ +#define WF_PLE_TOP_AMSDU_TXD_COMP_MAP_1_ADDR \ + (WF_PLE_TOP_BASE + 0x1008) /* 1008 */ +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_ADDR \ + (WF_PLE_TOP_BASE + 0x100c) /* 100C */ +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_ADDR \ + (WF_PLE_TOP_BASE + 0x1010) /* 1010 */ +#define WF_PLE_TOP_AMSDU_PEEK_CR_00_ADDR \ + (WF_PLE_TOP_BASE + 0x10d0) /* 10D0 */ +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_ADDR \ + (WF_PLE_TOP_BASE + 0x10d4) /* 10D4 */ +#define WF_PLE_TOP_AMSDU_PACK_1_MSDU_CNT_ADDR \ + (WF_PLE_TOP_BASE + 0x10e0) /* 10E0 */ +#define WF_PLE_TOP_AMSDU_PACK_2_MSDU_CNT_ADDR \ + (WF_PLE_TOP_BASE + 0x10e4) /* 10E4 */ +#define WF_PLE_TOP_AMSDU_PACK_3_MSDU_CNT_ADDR \ + (WF_PLE_TOP_BASE + 0x10e8) /* 10E8 */ +#define WF_PLE_TOP_AMSDU_PACK_4_MSDU_CNT_ADDR \ + (WF_PLE_TOP_BASE + 0x10ec) /* 10EC */ +#define WF_PLE_TOP_AMSDU_PACK_5_MSDU_CNT_ADDR \ + (WF_PLE_TOP_BASE + 0x10f0) /* 10F0 */ +#define WF_PLE_TOP_AMSDU_PACK_6_MSDU_CNT_ADDR \ + (WF_PLE_TOP_BASE + 0x10f4) /* 10F4 */ +#define WF_PLE_TOP_AMSDU_PACK_7_MSDU_CNT_ADDR \ + (WF_PLE_TOP_BASE + 0x10f8) /* 10F8 */ +#define WF_PLE_TOP_AMSDU_PACK_8_MSDU_CNT_ADDR \ + (WF_PLE_TOP_BASE + 0x10fc) /* 10FC */ +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY0_ADDR \ + (WF_PLE_TOP_BASE + 0x1100) /* 1100 */ +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY1_ADDR \ + (WF_PLE_TOP_BASE + 0x1104) /* 1104 */ +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY0_ADDR \ + (WF_PLE_TOP_BASE + 0x1140) /* 1140 */ +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY1_ADDR \ + (WF_PLE_TOP_BASE + 0x1144) /* 1144 */ +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY0_ADDR \ + (WF_PLE_TOP_BASE + 0x1180) /* 1180 */ +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY1_ADDR \ + (WF_PLE_TOP_BASE + 0x1184) /* 1184 */ +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY0_ADDR \ + (WF_PLE_TOP_BASE + 0x11C0) /* 11C0 */ +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY1_ADDR \ + (WF_PLE_TOP_BASE + 0x11C4) /* 11C4 */ +#define WF_PLE_TOP_CFG_DBDC_CTRL0_ADDR (WF_PLE_TOP_BASE + 0x2008) /* 2008 */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_ADDR \ + (WF_PLE_TOP_BASE + 0x2480) /* 2480 */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_1_ADDR \ + (WF_PLE_TOP_BASE + 0x2484) /* 2484 */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_2_ADDR \ + (WF_PLE_TOP_BASE + 0x2488) /* 2488 */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_3_ADDR \ + (WF_PLE_TOP_BASE + 0x248c) /* 248C */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_4_ADDR \ + (WF_PLE_TOP_BASE + 0x2490) /* 2490 */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_ADDR \ + (WF_PLE_TOP_BASE + 0x2494) /* 2494 */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_6_ADDR \ + (WF_PLE_TOP_BASE + 0x2498) /* 2498 */ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_ADDR \ + (WF_PLE_TOP_BASE + 0x25c0) /* 25C0 */ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_1_ADDR \ + (WF_PLE_TOP_BASE + 0x25c4) /* 25C4 */ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_2_ADDR \ + (WF_PLE_TOP_BASE + 0x25c8) /* 25C8 */ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_3_ADDR \ + (WF_PLE_TOP_BASE + 0x25cc) /* 25CC */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_ADDR \ + (WF_PLE_TOP_BASE + 0x25e0) /* 25E0 */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_1_ADDR \ + (WF_PLE_TOP_BASE + 0x25e4) /* 25E4 */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_2_ADDR \ + (WF_PLE_TOP_BASE + 0x25e8) /* 25E8 */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_3_ADDR \ + (WF_PLE_TOP_BASE + 0x25ec) /* 25EC */ +#define WF_PLE_TOP_SYSRAM_MBIST_CTRL_ADDR \ + (WF_PLE_TOP_BASE + 0x3004) /* 3004 */ +#define WF_PLE_TOP_SYSRAM_MBIST_DEBUG_ADDR \ + (WF_PLE_TOP_BASE + 0x3008) /* 3008 */ +#define WF_PLE_TOP_SYSRAM_MBIST_MODE_ADDR \ + (WF_PLE_TOP_BASE + 0x300C) /* 300C */ +#define WF_PLE_TOP_SYSRAM_MBIST_HOLDB_ADDR \ + (WF_PLE_TOP_BASE + 0x3010) /* 3010 */ +#define WF_PLE_TOP_SYSRAM_MBIST_DONE_ADDR \ + (WF_PLE_TOP_BASE + 0x3014) /* 3014 */ +#define WF_PLE_TOP_SYSRAM_MBIST_FAIL_ADDR \ + (WF_PLE_TOP_BASE + 0x3018) /* 3018 */ +#define WF_PLE_TOP_SYSRAM_MBIST_SLEEP_TEST_ADDR \ + (WF_PLE_TOP_BASE + 0x301C) /* 301C */ +#define WF_PLE_TOP_SYSRAM_MBIST_SLEEP_INV_ADDR \ + (WF_PLE_TOP_BASE + 0x3020) /* 3020 */ +#define WF_PLE_TOP_SYSRAM_MBIST_SLEEP_W_ADDR \ + (WF_PLE_TOP_BASE + 0x3024) /* 3024 */ +#define WF_PLE_TOP_SYSRAM_MBIST_SLEEP_R_ADDR \ + (WF_PLE_TOP_BASE + 0x3028) /* 3028 */ +#define WF_PLE_TOP_SYSRAM_AWT_HDEN_ADDR \ + (WF_PLE_TOP_BASE + 0x302C) /* 302C */ +#define WF_PLE_TOP_SYSRAM_DBG_SEL_ADDR \ + (WF_PLE_TOP_BASE + 0x3030) /* 3030 */ +#define WF_PLE_TOP_SYSRAM_DELSEL_ADDR \ + (WF_PLE_TOP_BASE + 0x3070) /* 3070 */ +#define WF_PLE_TOP_SYSRAM_DELSEL_1_ADDR \ + (WF_PLE_TOP_BASE + 0x3074) /* 3074 */ +#define WF_PLE_TOP_SYSRAM_DELSEL_2_ADDR \ + (WF_PLE_TOP_BASE + 0x3078) /* 3078 */ +#define WF_PLE_TOP_SYSRAM_DELSEL_3_ADDR \ + (WF_PLE_TOP_BASE + 0x307C) /* 307C */ +#define WF_PLE_TOP_SYSRAM_OUTRAN_ERR_FLAG_ADDR \ + (WF_PLE_TOP_BASE + 0x3080) /* 3080 */ + +/* +* ---GC (0x820C0000 + 0x00)--- +* ALL_RESET[0] - (RW) Resets PLE logic and register +* LOGIC_RESET[1] - (RW) Resets PLE logic circuit +* INIT_DONE[2] - (RO) PLE control SRAM initialization +indicator +* UMAC_CFG_LOGIC_RESET[3] - (RW) Resets PF/MDP/SEC/UWTBL logic circuit +* RESERVED4[15..4] - (RO) Reserved bits +* SRAM_MBIST_G1_RESET[16] - (RW) Reset control of group 1 SRAM MBIST +* SRAM_MBIST_G2_RESET[17] - (RW) Reset control of group 2 SRAM MBIST +* DIS_PLE_DYN_CKG[18] - (RW) Disable control of wf_ple_top dynamic +* clock gating function +* RESERVED19[31..19] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_GC_DIS_PLE_DYN_CKG_ADDR WF_PLE_TOP_GC_ADDR +#define WF_PLE_TOP_GC_DIS_PLE_DYN_CKG_MASK 0x00040000 /* DIS_PLE_DYN_CKG[18] */ +#define WF_PLE_TOP_GC_DIS_PLE_DYN_CKG_SHFT 18 +#define WF_PLE_TOP_GC_SRAM_MBIST_G2_RESET_ADDR WF_PLE_TOP_GC_ADDR +#define WF_PLE_TOP_GC_SRAM_MBIST_G2_RESET_MASK \ + 0x00020000 /* SRAM_MBIST_G2_RESET[17] */ +#define WF_PLE_TOP_GC_SRAM_MBIST_G2_RESET_SHFT 17 +#define WF_PLE_TOP_GC_SRAM_MBIST_G1_RESET_ADDR WF_PLE_TOP_GC_ADDR +#define WF_PLE_TOP_GC_SRAM_MBIST_G1_RESET_MASK \ + 0x00010000 /* SRAM_MBIST_G1_RESET[16] */ +#define WF_PLE_TOP_GC_SRAM_MBIST_G1_RESET_SHFT 16 +#define WF_PLE_TOP_GC_UMAC_CFG_LOGIC_RESET_ADDR WF_PLE_TOP_GC_ADDR +#define WF_PLE_TOP_GC_UMAC_CFG_LOGIC_RESET_MASK \ + 0x00000008 /* UMAC_CFG_LOGIC_RESET[3] */ +#define WF_PLE_TOP_GC_UMAC_CFG_LOGIC_RESET_SHFT 3 +#define WF_PLE_TOP_GC_INIT_DONE_ADDR WF_PLE_TOP_GC_ADDR +#define WF_PLE_TOP_GC_INIT_DONE_MASK 0x00000004 /* INIT_DONE[2] */ +#define WF_PLE_TOP_GC_INIT_DONE_SHFT 2 +#define WF_PLE_TOP_GC_LOGIC_RESET_ADDR WF_PLE_TOP_GC_ADDR +#define WF_PLE_TOP_GC_LOGIC_RESET_MASK 0x00000002 /* LOGIC_RESET[1] */ +#define WF_PLE_TOP_GC_LOGIC_RESET_SHFT 1 +#define WF_PLE_TOP_GC_ALL_RESET_ADDR WF_PLE_TOP_GC_ADDR +#define WF_PLE_TOP_GC_ALL_RESET_MASK 0x00000001 /* ALL_RESET[0] */ +#define WF_PLE_TOP_GC_ALL_RESET_SHFT 0 + +/* +* ---PBUF_CTRL (0x820C0000 + 0x04)--- +* TOTAL_PAGE_NUM[11..0] - (RW) Total page number +* Set the total page before release PLE logic +* reset, and must not be changed after release logic reset. +* RESERVED12[16..12] - (RO) Reserved bits +* PBUF_OFFSET[25..17] - (RW) Packet buffer offset +* Set up the buffer offset before releasing +* PLE logic reset; it should not be changed after logic reset is released. +* RESERVED26[30..26] - (RO) Reserved bits +* PAGE_SIZE_CFG[31] - (RW) Configures page size +* Set up the page size before releasing PLE +* logic reset; it should not be changed after logic reset is released. +*/ +#define WF_PLE_TOP_PBUF_CTRL_PAGE_SIZE_CFG_ADDR WF_PLE_TOP_PBUF_CTRL_ADDR +#define WF_PLE_TOP_PBUF_CTRL_PAGE_SIZE_CFG_MASK \ + 0x80000000 /* PAGE_SIZE_CFG[31] */ +#define WF_PLE_TOP_PBUF_CTRL_PAGE_SIZE_CFG_SHFT 31 +#define WF_PLE_TOP_PBUF_CTRL_PBUF_OFFSET_ADDR WF_PLE_TOP_PBUF_CTRL_ADDR +#define WF_PLE_TOP_PBUF_CTRL_PBUF_OFFSET_MASK \ + 0x03FE0000 /* PBUF_OFFSET[25..17] */ +#define WF_PLE_TOP_PBUF_CTRL_PBUF_OFFSET_SHFT 17 +#define WF_PLE_TOP_PBUF_CTRL_TOTAL_PAGE_NUM_ADDR WF_PLE_TOP_PBUF_CTRL_ADDR +#define WF_PLE_TOP_PBUF_CTRL_TOTAL_PAGE_NUM_MASK \ + 0x00000FFF /* TOTAL_PAGE_NUM[11..0] */ +#define WF_PLE_TOP_PBUF_CTRL_TOTAL_PAGE_NUM_SHFT 0 + +/* +* ---FREEPG_START_END (0x820C0000 + 0x08)--- +* FREEPG_START[11..0] - (RW) Start page for free page list +* Set start page before release PLE logic +* reset, and must not be changed after release logic reset. +* RESERVED12[15..12] - (RO) Reserved bits +* FREEPG_END[27..16] - (RW) End page for free page list +* Set end page before release PLE logic +* reset, and must not be changed after release logic reset. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_FREEPG_START_END_FREEPG_END_ADDR \ + WF_PLE_TOP_FREEPG_START_END_ADDR +#define WF_PLE_TOP_FREEPG_START_END_FREEPG_END_MASK \ + 0x0FFF0000 /* FREEPG_END[27..16] */ +#define WF_PLE_TOP_FREEPG_START_END_FREEPG_END_SHFT 16 +#define WF_PLE_TOP_FREEPG_START_END_FREEPG_START_ADDR \ + WF_PLE_TOP_FREEPG_START_END_ADDR +#define WF_PLE_TOP_FREEPG_START_END_FREEPG_START_MASK \ + 0x00000FFF /* FREEPG_START[11..0] */ +#define WF_PLE_TOP_FREEPG_START_END_FREEPG_START_SHFT 0 + +/* +* ---PG_HIF_GROUP (0x820C0000 + 0x0c)--- +* HIF_MIN_QUOTA[11..0] - (RW) Min. quota of HIF group +* Set the quota before release PLE logic +* reset ,and must not be changed after release logic reset. +* RESERVED12[15..12] - (RO) Reserved bits +* HIF_MAX_QUOTA[27..16] - (RW) Max. quota of HIF group +* Set up the quota before releasing PLE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_PG_HIF_GROUP_HIF_MAX_QUOTA_ADDR WF_PLE_TOP_PG_HIF_GROUP_ADDR +#define WF_PLE_TOP_PG_HIF_GROUP_HIF_MAX_QUOTA_MASK \ + 0x0FFF0000 /* HIF_MAX_QUOTA[27..16] */ +#define WF_PLE_TOP_PG_HIF_GROUP_HIF_MAX_QUOTA_SHFT 16 +#define WF_PLE_TOP_PG_HIF_GROUP_HIF_MIN_QUOTA_ADDR WF_PLE_TOP_PG_HIF_GROUP_ADDR +#define WF_PLE_TOP_PG_HIF_GROUP_HIF_MIN_QUOTA_MASK \ + 0x00000FFF /* HIF_MIN_QUOTA[11..0] */ +#define WF_PLE_TOP_PG_HIF_GROUP_HIF_MIN_QUOTA_SHFT 0 + +/* +* ---PG_HIF_WMTXD_GROUP (0x820C0000 + 0x10)--- +* HIF_WMTXD_MIN_QUOTA[11..0] - (RW) Min. quota of HIF WMCPU TXD group +* Set the quota before release PLE logic +* reset ,and must not be changed after release logic reset. +* RESERVED12[15..12] - (RO) Reserved bits +* HIF_WMTXD_MAX_QUOTA[27..16] - (RW) Max. quota of HIF WMCPU TXD group +* Set up the quota before releasing PLE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_PG_HIF_WMTXD_GROUP_HIF_WMTXD_MAX_QUOTA_ADDR \ + WF_PLE_TOP_PG_HIF_WMTXD_GROUP_ADDR +#define WF_PLE_TOP_PG_HIF_WMTXD_GROUP_HIF_WMTXD_MAX_QUOTA_MASK \ + 0x0FFF0000 /* HIF_WMTXD_MAX_QUOTA[27..16] */ +#define WF_PLE_TOP_PG_HIF_WMTXD_GROUP_HIF_WMTXD_MAX_QUOTA_SHFT 16 +#define WF_PLE_TOP_PG_HIF_WMTXD_GROUP_HIF_WMTXD_MIN_QUOTA_ADDR \ + WF_PLE_TOP_PG_HIF_WMTXD_GROUP_ADDR +#define WF_PLE_TOP_PG_HIF_WMTXD_GROUP_HIF_WMTXD_MIN_QUOTA_MASK \ + 0x00000FFF /* HIF_WMTXD_MIN_QUOTA[11..0] */ +#define WF_PLE_TOP_PG_HIF_WMTXD_GROUP_HIF_WMTXD_MIN_QUOTA_SHFT 0 + +/* +* ---PG_HIF_TXCMD_GROUP (0x820C0000 + 0x14)--- +* HIF_TXCMD_MIN_QUOTA[11..0] - (RW) Min. quota of HIF TXCMD group +* Set the quota before release PLE logic +* reset ,and must not be changed after release logic reset. +* RESERVED12[15..12] - (RO) Reserved bits +* HIF_TXCMD_MAX_QUOTA[27..16] - (RW) Max. quota of HIF TXCMD group +* Set up the quota before releasing PLE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_PG_HIF_TXCMD_GROUP_HIF_TXCMD_MAX_QUOTA_ADDR \ + WF_PLE_TOP_PG_HIF_TXCMD_GROUP_ADDR +#define WF_PLE_TOP_PG_HIF_TXCMD_GROUP_HIF_TXCMD_MAX_QUOTA_MASK \ + 0x0FFF0000 /* HIF_TXCMD_MAX_QUOTA[27..16] */ +#define WF_PLE_TOP_PG_HIF_TXCMD_GROUP_HIF_TXCMD_MAX_QUOTA_SHFT 16 +#define WF_PLE_TOP_PG_HIF_TXCMD_GROUP_HIF_TXCMD_MIN_QUOTA_ADDR \ + WF_PLE_TOP_PG_HIF_TXCMD_GROUP_ADDR +#define WF_PLE_TOP_PG_HIF_TXCMD_GROUP_HIF_TXCMD_MIN_QUOTA_MASK \ + 0x00000FFF /* HIF_TXCMD_MIN_QUOTA[11..0] */ +#define WF_PLE_TOP_PG_HIF_TXCMD_GROUP_HIF_TXCMD_MIN_QUOTA_SHFT 0 + +/* +* ---PG_CPU_GROUP (0x820C0000 + 0x18)--- +* CPU_MIN_QUOTA[11..0] - (RW) Min. quota of CPU group +* Set up the quota before releasing PLE logic +* reset; it should not be changed after logic reset is released. +* RESERVED12[15..12] - (RO) Reserved bits +* CPU_MAX_QUOTA[27..16] - (RW) Max. quota of CPU group +* Set up the quota before releasing PLE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_PG_CPU_GROUP_CPU_MAX_QUOTA_ADDR WF_PLE_TOP_PG_CPU_GROUP_ADDR +#define WF_PLE_TOP_PG_CPU_GROUP_CPU_MAX_QUOTA_MASK \ + 0x0FFF0000 /* CPU_MAX_QUOTA[27..16] */ +#define WF_PLE_TOP_PG_CPU_GROUP_CPU_MAX_QUOTA_SHFT 16 +#define WF_PLE_TOP_PG_CPU_GROUP_CPU_MIN_QUOTA_ADDR WF_PLE_TOP_PG_CPU_GROUP_ADDR +#define WF_PLE_TOP_PG_CPU_GROUP_CPU_MIN_QUOTA_MASK \ + 0x00000FFF /* CPU_MIN_QUOTA[11..0] */ +#define WF_PLE_TOP_PG_CPU_GROUP_CPU_MIN_QUOTA_SHFT 0 + +/* +* ---VOW_CONTROL (0x820C0000 + 0x1c)--- +* PER_BSS_BW_CONTROL_ENABLE[15..0] - (RW) BW control of BSSID +* REFILL_PERIOD[18..16] - (RW) Period of token refill function +* RESERVED19[19] - (RO) Reserved bits +* DBDC1_SEARCH_RULE[20] - (RW) Priority for HW search if internal +* collision occurs +* DBDC0_SEARCH_RULE[21] - (RW) Priority for HW search if internal +* collision occcurs +* RESERVED22[25..22] - (RO) Reserved bits +* DRR_LOGIC_RESET[26] - (RW) DRR logic reset control +* DIS_WTBL_PS_IGNORE[27] - (RW) Disable control of the function that STA +* with WTBL PS ignore in TXQ busy +* ENABLE_TXOP_NO_CHANGE_BSS_GROUP[28] - (RW) HW cannot change BW group In TXOP +burst. +* ENABLE_AIRTIME_FAIRNESS[29] - (RW) When airtime function is disabled, HW +* will change station without checking station qouta. +* ENABLE_TOKEN_REFILL[30] - (RW) Enable control of token refill function +* ENABLE_BW_CONTROL[31] - (RW) HW will check if there are tokens in BW +* bucket before TX. +*/ +#define WF_PLE_TOP_VOW_CONTROL_ENABLE_BW_CONTROL_ADDR \ + WF_PLE_TOP_VOW_CONTROL_ADDR +#define WF_PLE_TOP_VOW_CONTROL_ENABLE_BW_CONTROL_MASK \ + 0x80000000 /* ENABLE_BW_CONTROL[31] */ +#define WF_PLE_TOP_VOW_CONTROL_ENABLE_BW_CONTROL_SHFT 31 +#define WF_PLE_TOP_VOW_CONTROL_ENABLE_TOKEN_REFILL_ADDR \ + WF_PLE_TOP_VOW_CONTROL_ADDR +#define WF_PLE_TOP_VOW_CONTROL_ENABLE_TOKEN_REFILL_MASK \ + 0x40000000 /* ENABLE_TOKEN_REFILL[30] */ +#define WF_PLE_TOP_VOW_CONTROL_ENABLE_TOKEN_REFILL_SHFT 30 +#define WF_PLE_TOP_VOW_CONTROL_ENABLE_AIRTIME_FAIRNESS_ADDR \ + WF_PLE_TOP_VOW_CONTROL_ADDR +#define WF_PLE_TOP_VOW_CONTROL_ENABLE_AIRTIME_FAIRNESS_MASK \ + 0x20000000 /* ENABLE_AIRTIME_FAIRNESS[29] */ +#define WF_PLE_TOP_VOW_CONTROL_ENABLE_AIRTIME_FAIRNESS_SHFT 29 +#define WF_PLE_TOP_VOW_CONTROL_ENABLE_TXOP_NO_CHANGE_BSS_GROUP_ADDR \ + WF_PLE_TOP_VOW_CONTROL_ADDR +#define WF_PLE_TOP_VOW_CONTROL_ENABLE_TXOP_NO_CHANGE_BSS_GROUP_MASK \ + 0x10000000 /* ENABLE_TXOP_NO_CHANGE_BSS_GROUP[28] */ +#define WF_PLE_TOP_VOW_CONTROL_ENABLE_TXOP_NO_CHANGE_BSS_GROUP_SHFT 28 +#define WF_PLE_TOP_VOW_CONTROL_DIS_WTBL_PS_IGNORE_ADDR \ + WF_PLE_TOP_VOW_CONTROL_ADDR +#define WF_PLE_TOP_VOW_CONTROL_DIS_WTBL_PS_IGNORE_MASK \ + 0x08000000 /* DIS_WTBL_PS_IGNORE[27] */ +#define WF_PLE_TOP_VOW_CONTROL_DIS_WTBL_PS_IGNORE_SHFT 27 +#define WF_PLE_TOP_VOW_CONTROL_DRR_LOGIC_RESET_ADDR WF_PLE_TOP_VOW_CONTROL_ADDR +#define WF_PLE_TOP_VOW_CONTROL_DRR_LOGIC_RESET_MASK \ + 0x04000000 /* DRR_LOGIC_RESET[26] */ +#define WF_PLE_TOP_VOW_CONTROL_DRR_LOGIC_RESET_SHFT 26 +#define WF_PLE_TOP_VOW_CONTROL_DBDC0_SEARCH_RULE_ADDR \ + WF_PLE_TOP_VOW_CONTROL_ADDR +#define WF_PLE_TOP_VOW_CONTROL_DBDC0_SEARCH_RULE_MASK \ + 0x00200000 /* DBDC0_SEARCH_RULE[21] */ +#define WF_PLE_TOP_VOW_CONTROL_DBDC0_SEARCH_RULE_SHFT 21 +#define WF_PLE_TOP_VOW_CONTROL_DBDC1_SEARCH_RULE_ADDR \ + WF_PLE_TOP_VOW_CONTROL_ADDR +#define WF_PLE_TOP_VOW_CONTROL_DBDC1_SEARCH_RULE_MASK \ + 0x00100000 /* DBDC1_SEARCH_RULE[20] */ +#define WF_PLE_TOP_VOW_CONTROL_DBDC1_SEARCH_RULE_SHFT 20 +#define WF_PLE_TOP_VOW_CONTROL_REFILL_PERIOD_ADDR WF_PLE_TOP_VOW_CONTROL_ADDR +#define WF_PLE_TOP_VOW_CONTROL_REFILL_PERIOD_MASK \ + 0x00070000 /* REFILL_PERIOD[18..16] */ +#define WF_PLE_TOP_VOW_CONTROL_REFILL_PERIOD_SHFT 16 +#define WF_PLE_TOP_VOW_CONTROL_PER_BSS_BW_CONTROL_ENABLE_ADDR \ + WF_PLE_TOP_VOW_CONTROL_ADDR +#define WF_PLE_TOP_VOW_CONTROL_PER_BSS_BW_CONTROL_ENABLE_MASK \ + 0x0000FFFF /* PER_BSS_BW_CONTROL_ENABLE[15..0] */ +#define WF_PLE_TOP_VOW_CONTROL_PER_BSS_BW_CONTROL_ENABLE_SHFT 0 + +/* +* ---SRAM_MBIST_DELSEL1 (0x820C0000 + 0x20)--- +* SRAM1_MBIST_DELSEL[31..0] - (RW) MBIST delsel setting of SRAM1 +*/ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL1_SRAM1_MBIST_DELSEL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_DELSEL1_ADDR +#define WF_PLE_TOP_SRAM_MBIST_DELSEL1_SRAM1_MBIST_DELSEL_MASK \ + 0xFFFFFFFF /* SRAM1_MBIST_DELSEL[31..0] */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL1_SRAM1_MBIST_DELSEL_SHFT 0 + +/* +* ---SRAM_MBIST_DELSEL2 (0x820C0000 + 0x24)--- +* SRAM2_MBIST_DELSEL[31..0] - (RW) MBIST delsel setting of SRAM2 +*/ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL2_SRAM2_MBIST_DELSEL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_DELSEL2_ADDR +#define WF_PLE_TOP_SRAM_MBIST_DELSEL2_SRAM2_MBIST_DELSEL_MASK \ + 0xFFFFFFFF /* SRAM2_MBIST_DELSEL[31..0] */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL2_SRAM2_MBIST_DELSEL_SHFT 0 + +/* +* ---SRAM_MBIST_DELSEL3 (0x820C0000 + 0x28)--- +* SRAM3_MBIST_DELSEL[31..0] - (RW) MBIST delsel setting of SRAM3 +*/ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL3_SRAM3_MBIST_DELSEL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_DELSEL3_ADDR +#define WF_PLE_TOP_SRAM_MBIST_DELSEL3_SRAM3_MBIST_DELSEL_MASK \ + 0xFFFFFFFF /* SRAM3_MBIST_DELSEL[31..0] */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL3_SRAM3_MBIST_DELSEL_SHFT 0 + +/* +* ---SRAM_MBIST_DELSEL4 (0x820C0000 + 0x2c)--- +* SRAM4_MBIST_DELSEL[31..0] - (RW) MBIST delsel setting of SRAM4 +*/ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL4_SRAM4_MBIST_DELSEL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_DELSEL4_ADDR +#define WF_PLE_TOP_SRAM_MBIST_DELSEL4_SRAM4_MBIST_DELSEL_MASK \ + 0xFFFFFFFF /* SRAM4_MBIST_DELSEL[31..0] */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL4_SRAM4_MBIST_DELSEL_SHFT 0 + +/* +* ---SRAM_MBIST_DELSEL5 (0x820C0000 + 0x30)--- +* SRAM5_MBIST_DELSEL[31..0] - (RW) MBIST delsel setting of SRAM5 +*/ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL5_SRAM5_MBIST_DELSEL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_DELSEL5_ADDR +#define WF_PLE_TOP_SRAM_MBIST_DELSEL5_SRAM5_MBIST_DELSEL_MASK \ + 0xFFFFFFFF /* SRAM5_MBIST_DELSEL[31..0] */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL5_SRAM5_MBIST_DELSEL_SHFT 0 + +/* +* ---SRAM_MBIST_DELSEL6 (0x820C0000 + 0x34)--- +* SRAM6_MBIST_DELSEL[31..0] - (RW) MBIST delsel setting of SRAM6 +*/ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL6_SRAM6_MBIST_DELSEL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_DELSEL6_ADDR +#define WF_PLE_TOP_SRAM_MBIST_DELSEL6_SRAM6_MBIST_DELSEL_MASK \ + 0xFFFFFFFF /* SRAM6_MBIST_DELSEL[31..0] */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL6_SRAM6_MBIST_DELSEL_SHFT 0 + +/* +* ---SRAM_MBIST_DELSEL7 (0x820C0000 + 0x38)--- +* SRAM7_MBIST_DELSEL[31..0] - (RW) MBIST delsel setting of SRAM7 +*/ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL7_SRAM7_MBIST_DELSEL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_DELSEL7_ADDR +#define WF_PLE_TOP_SRAM_MBIST_DELSEL7_SRAM7_MBIST_DELSEL_MASK \ + 0xFFFFFFFF /* SRAM7_MBIST_DELSEL[31..0] */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL7_SRAM7_MBIST_DELSEL_SHFT 0 + +/* +* ---SRAM_MBIST_DELSEL8 (0x820C0000 + 0x3c)--- +* SRAM8_MBIST_DELSEL[31..0] - (RW) MBIST delsel setting of SRAM8 +*/ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL8_SRAM8_MBIST_DELSEL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_DELSEL8_ADDR +#define WF_PLE_TOP_SRAM_MBIST_DELSEL8_SRAM8_MBIST_DELSEL_MASK \ + 0xFFFFFFFF /* SRAM8_MBIST_DELSEL[31..0] */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL8_SRAM8_MBIST_DELSEL_SHFT 0 + +/* +* ---SRAM_MBIST_DELSEL9 (0x820C0000 + 0x40)--- +* SRAM9_MBIST_DELSEL[31..0] - (RW) MBIST delsel setting of SRAM9 +*/ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL9_SRAM9_MBIST_DELSEL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_DELSEL9_ADDR +#define WF_PLE_TOP_SRAM_MBIST_DELSEL9_SRAM9_MBIST_DELSEL_MASK \ + 0xFFFFFFFF /* SRAM9_MBIST_DELSEL[31..0] */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL9_SRAM9_MBIST_DELSEL_SHFT 0 + +/* +* ---SRAM_MBIST_DELSEL10 (0x820C0000 + 0x44)--- +* SRAM10_MBIST_DELSEL[31..0] - (RW) MBIST delsel setting of SRAM10 +*/ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL10_SRAM10_MBIST_DELSEL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_DELSEL10_ADDR +#define WF_PLE_TOP_SRAM_MBIST_DELSEL10_SRAM10_MBIST_DELSEL_MASK \ + 0xFFFFFFFF /* SRAM10_MBIST_DELSEL[31..0] */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL10_SRAM10_MBIST_DELSEL_SHFT 0 + +/* +* ---SRAM_MBIST_CTRL (0x820C0000 + 0x48)--- +* G1_MBIST_MODE[0] - (RW) Control register for mbist_mode of group +* 1 MBIST +* G2_MBIST_MODE[1] - (RW) Control register for mbist_mode of group +* 2 MBIST +* RESERVED2[3..2] - (RO) Reserved bits +* G1_MBIST_HOLDB[4] - (RW) Control register for mbist_holdb of +* group 1 MBIST +* G2_MBIST_HOLDB[5] - (RW) Control register for mbist_holdb of +* group 2 MBIST +* RESERVED6[7..6] - (RO) Reserved bits +* G1_MBIST_DEBUG[8] - (RW) Control register for mbist_debug of +* group 1 MBIST +* G2_MBIST_DEBUG[9] - (RW) Control register for mbist_debug of +* group 2 MBIST +* G1_MBIST_USE_DEFAULT_DELSEL[10] - (RW) Control register for default DELSEL +* value of group 1 memory +* G2_MBIST_USE_DEFAULT_DELSEL[11] - (RW) Control register for default DELSEL +* value of group 2 memory +* MBIST_DIAG_SEL[16..12] - (RW) Selection register for +mbist_diag_scan_out +* RESERVED17[19..17] - (RO) Reserved bits +* UMAC_MBIST_DIAG_SEL[20] - (RW) Selection register for UMAC +* mbist_diag_scan_out (PLE or PSE) +* RESERVED21[23..21] - (RO) Reserved bits +* G1_MBIST_SLEEP_TEST[24] - (RW) Control register for sleep_test of group +* 1 MBIST +* G1_MBIST_SLEEP_INV[25] - (RW) Control register for sleep_inv of group +* 1 MBIST +* G1_MBIST_SLEEP_W[26] - (RW) Control register for sleep_w of group 1 +MBIST +* G1_MBIST_SLEEP_R[27] - (RW) Control register for sleep_r of group 1 +MBIST +* G2_MBIST_SLEEP_TEST[28] - (RW) Control register for sleep_test of group +* 2 MBIST +* G2_MBIST_SLEEP_INV[29] - (RW) Control register for sleep_inv of group +* 2 MBIST +* G2_MBIST_SLEEP_W[30] - (RW) Control register for sleep_w of group 2 +MBIST +* G2_MBIST_SLEEP_R[31] - (RW) Control register for sleep_r of group 2 +MBIST +*/ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_SLEEP_R_ADDR \ + WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_SLEEP_R_MASK \ + 0x80000000 /* G2_MBIST_SLEEP_R[31] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_SLEEP_R_SHFT 31 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_SLEEP_W_ADDR \ + WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_SLEEP_W_MASK \ + 0x40000000 /* G2_MBIST_SLEEP_W[30] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_SLEEP_W_SHFT 30 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_SLEEP_INV_ADDR \ + WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_SLEEP_INV_MASK \ + 0x20000000 /* G2_MBIST_SLEEP_INV[29] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_SLEEP_INV_SHFT 29 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_SLEEP_TEST_ADDR \ + WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_SLEEP_TEST_MASK \ + 0x10000000 /* G2_MBIST_SLEEP_TEST[28] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_SLEEP_TEST_SHFT 28 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_SLEEP_R_ADDR \ + WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_SLEEP_R_MASK \ + 0x08000000 /* G1_MBIST_SLEEP_R[27] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_SLEEP_R_SHFT 27 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_SLEEP_W_ADDR \ + WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_SLEEP_W_MASK \ + 0x04000000 /* G1_MBIST_SLEEP_W[26] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_SLEEP_W_SHFT 26 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_SLEEP_INV_ADDR \ + WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_SLEEP_INV_MASK \ + 0x02000000 /* G1_MBIST_SLEEP_INV[25] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_SLEEP_INV_SHFT 25 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_SLEEP_TEST_ADDR \ + WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_SLEEP_TEST_MASK \ + 0x01000000 /* G1_MBIST_SLEEP_TEST[24] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_SLEEP_TEST_SHFT 24 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_UMAC_MBIST_DIAG_SEL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_UMAC_MBIST_DIAG_SEL_MASK \ + 0x00100000 /* UMAC_MBIST_DIAG_SEL[20] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_UMAC_MBIST_DIAG_SEL_SHFT 20 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_MBIST_DIAG_SEL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_MBIST_DIAG_SEL_MASK \ + 0x0001F000 /* MBIST_DIAG_SEL[16..12] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_MBIST_DIAG_SEL_SHFT 12 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_USE_DEFAULT_DELSEL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_USE_DEFAULT_DELSEL_MASK \ + 0x00000800 /* G2_MBIST_USE_DEFAULT_DELSEL[11] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_USE_DEFAULT_DELSEL_SHFT 11 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_USE_DEFAULT_DELSEL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_USE_DEFAULT_DELSEL_MASK \ + 0x00000400 /* G1_MBIST_USE_DEFAULT_DELSEL[10] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_USE_DEFAULT_DELSEL_SHFT 10 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_DEBUG_ADDR \ + WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_DEBUG_MASK \ + 0x00000200 /* G2_MBIST_DEBUG[9] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_DEBUG_SHFT 9 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_DEBUG_ADDR \ + WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_DEBUG_MASK \ + 0x00000100 /* G1_MBIST_DEBUG[8] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_DEBUG_SHFT 8 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_HOLDB_ADDR \ + WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_HOLDB_MASK \ + 0x00000020 /* G2_MBIST_HOLDB[5] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_HOLDB_SHFT 5 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_HOLDB_ADDR \ + WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_HOLDB_MASK \ + 0x00000010 /* G1_MBIST_HOLDB[4] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_HOLDB_SHFT 4 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_MODE_ADDR \ + WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_MODE_MASK \ + 0x00000002 /* G2_MBIST_MODE[1] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_MODE_SHFT 1 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_MODE_ADDR \ + WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_MODE_MASK \ + 0x00000001 /* G1_MBIST_MODE[0] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_MODE_SHFT 0 + +/* +* ---INT_N9_EN_MASK (0x820C0000 + 0x80)--- +* EN_CPU_Q0_NE[0] - (RW) Enable control of interrupt for CPU +* queue 0 not empty +* EN_CPU_Q1_NE[1] - (RW) Enable control of interrupt for CPU +* queue 1 not empty +* EN_CPU_Q2_NE[2] - (RW) Enable control of interrupt for CPU +* queue 2 not empty +* EN_CPU_Q3_NE[3] - (RW) Enable control of interrupt for CPU +* queue 3 not empty +* RESERVED4[15..4] - (RO) Reserved bits +* EN_TOGGLE_INT[16] - (RW) Enable control of interrupt for data +* toggle of N9 toggle register (0xf0) +* RESERVED17[17] - (RO) Reserved bits +* EN_UMAC_SYSRAM_OUTRAN_ERROR_INT[18] - (RW) Enable control of interrupt for +* UMAC SYSRAM out range error +* RESERVED19[19] - (RO) Reserved bits +* EN_AC_NONEMPTY_INT[20] - (RW) Enable control of AC queue empty fail +interrupt +* EN_AC_EMPTY_INT[21] - (RW) Enable control of AC queue empty raise +interrupt +* EN_AC_ENQ_LMAC_INT[22] - (RW) Enable control of AC enqueue interrupt +* RESERVED23[23] - (RO) Reserved bits +* EN_DBDC0_NONEMPTY_INT[24] - (RW) Enable control of DBDC0 queue empty fail +interrupt +* EN_DBDC0_EMPTY_INT[25] - (RW) Enable control of DBDC0 queue empty +* raise interrupt +* EN_DBDC0_ENQ_LMAC_INT[26] - (RW) Enable control of DBDC0 enqueue +interrupt +* RESERVED27[27] - (RO) Reserved bits +* EN_DBDC1_NONEMPTY_INT[28] - (RW) Enable control of DBDC1 queue empty fail +interrupt +* EN_DBDC1_EMPTY_INT[29] - (RW) Enable control of DBDC1 queue empty +* raise interrupt +* EN_DBDC1_ENQ_LMAC_INT[30] - (RW) Enable control of DBDC1 enqueue +interrupt +* RESERVED31[31] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC1_ENQ_LMAC_INT_ADDR \ + WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC1_ENQ_LMAC_INT_MASK \ + 0x40000000 /* EN_DBDC1_ENQ_LMAC_INT[30] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC1_ENQ_LMAC_INT_SHFT 30 +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC1_EMPTY_INT_ADDR \ + WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC1_EMPTY_INT_MASK \ + 0x20000000 /* EN_DBDC1_EMPTY_INT[29] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC1_EMPTY_INT_SHFT 29 +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC1_NONEMPTY_INT_ADDR \ + WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC1_NONEMPTY_INT_MASK \ + 0x10000000 /* EN_DBDC1_NONEMPTY_INT[28] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC1_NONEMPTY_INT_SHFT 28 +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC0_ENQ_LMAC_INT_ADDR \ + WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC0_ENQ_LMAC_INT_MASK \ + 0x04000000 /* EN_DBDC0_ENQ_LMAC_INT[26] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC0_ENQ_LMAC_INT_SHFT 26 +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC0_EMPTY_INT_ADDR \ + WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC0_EMPTY_INT_MASK \ + 0x02000000 /* EN_DBDC0_EMPTY_INT[25] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC0_EMPTY_INT_SHFT 25 +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC0_NONEMPTY_INT_ADDR \ + WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC0_NONEMPTY_INT_MASK \ + 0x01000000 /* EN_DBDC0_NONEMPTY_INT[24] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC0_NONEMPTY_INT_SHFT 24 +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_AC_ENQ_LMAC_INT_ADDR \ + WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_AC_ENQ_LMAC_INT_MASK \ + 0x00400000 /* EN_AC_ENQ_LMAC_INT[22] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_AC_ENQ_LMAC_INT_SHFT 22 +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_AC_EMPTY_INT_ADDR \ + WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_AC_EMPTY_INT_MASK \ + 0x00200000 /* EN_AC_EMPTY_INT[21] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_AC_EMPTY_INT_SHFT 21 +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_AC_NONEMPTY_INT_ADDR \ + WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_AC_NONEMPTY_INT_MASK \ + 0x00100000 /* EN_AC_NONEMPTY_INT[20] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_AC_NONEMPTY_INT_SHFT 20 +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_UMAC_SYSRAM_OUTRAN_ERROR_INT_ADDR \ + WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_UMAC_SYSRAM_OUTRAN_ERROR_INT_MASK \ + 0x00040000 /* EN_UMAC_SYSRAM_OUTRAN_ERROR_INT[18] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_UMAC_SYSRAM_OUTRAN_ERROR_INT_SHFT 18 +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_TOGGLE_INT_ADDR \ + WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_TOGGLE_INT_MASK \ + 0x00010000 /* EN_TOGGLE_INT[16] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_TOGGLE_INT_SHFT 16 +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_CPU_Q3_NE_ADDR \ + WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_CPU_Q3_NE_MASK \ + 0x00000008 /* EN_CPU_Q3_NE[3] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_CPU_Q3_NE_SHFT 3 +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_CPU_Q2_NE_ADDR \ + WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_CPU_Q2_NE_MASK \ + 0x00000004 /* EN_CPU_Q2_NE[2] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_CPU_Q2_NE_SHFT 2 +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_CPU_Q1_NE_ADDR \ + WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_CPU_Q1_NE_MASK \ + 0x00000002 /* EN_CPU_Q1_NE[1] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_CPU_Q1_NE_SHFT 1 +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_CPU_Q0_NE_ADDR \ + WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_CPU_Q0_NE_MASK \ + 0x00000001 /* EN_CPU_Q0_NE[0] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_CPU_Q0_NE_SHFT 0 + +/* +* ---INT_N9_ERR_MASK (0x820C0000 + 0x84)--- +* EN_Q_CMD_ERR_P0[0] - (RW) Enables queue command error interrupt +* status of port 0 +* EN_Q_CMD_ERR_P1[1] - (RW) Enables queue command error interrupt +* status of port 1 +* EN_Q_CMD_ERR_P2[2] - (RW) Enables queue command error interrupt +* status of port 2 +* EN_PAGE_UDF_P0[3] - (RW) Enables page underflow interrupt status +* of port 0 +* EN_PAGE_UDF_P1[4] - (RW) Enables page underflow interrupt status +* of port 1 +* EN_PAGE_UDF_P2[5] - (RW) Enables page underflow interrupt status +* of port 2 +* EN_DOUBLE_RLS_ERR[6] - (RW) Enable double release error interrupt. +* EN_MDP_D_OPER_ERR[7] - (RW) Enable MDP data operation error +interrupt. +* EN_MDP_HANG_ERR[8] - (RW) Enable MDP FSM hang error interrupt. +* RESERVED9[9] - (RO) Reserved bits +* EN_DATA_OPER_ERR_P0[10] - (RW) Enables data operation error of port 0 +* EN_DATA_OPER_ERR_P1[11] - (RW) Enables data operation error of port 1 +* EN_DATA_OPER_ERR_P2[12] - (RW) Enables data operation error of port 2 +* EN_FL_HANG_ERR[13] - (RW) Enables frame link FSM hang error +interrupt +* EN_PL_HANG_ERR[14] - (RW) Enables page link FSM hang error +interrupt +* EN_HIF_HANG_ERR[15] - (RW) Enables HIF port FSM hang error +interrupt +* EN_CPU_HANG_ERR[16] - (RW) Enables CPU port FSM hang error +interrupt +* EN_LMAC_HANG_ERR[17] - (RW) Enables LMAC port FSM hang error +interrupt +* EN_FREE_HEAD_TAIL_ERR[18] - (RW) Enable free head/tail error interrupt. +* EN_QSTRUCT_ERR[19] - (RW) Enable queue struct data error +interrupt. +* EN_BN0_MACTX_HANG_ERR[20] - (RW) Enable BN0 MACTX Ctrl FSM Hang error +interrupt. +* EN_BN1_MACTX_HANG_ERR[21] - (RW) Enable BN1 MACTX Ctrl FSM Hang error +interrupt. +* EN_BN0_TXCMD_HANG_ERR[22] - (RW) Enable BN0 TXCMD Ctrl FSM Hang error +interrupt. +* EN_BN1_TXCMD_HANG_ERR[23] - (RW) Enable BN1 TXCMD Ctrl FSM Hang error +interrupt. +* EN_DRR_SRCH_DBDC0_ERR[24] - (RW) Enable DRR DBDC0 sta search error +interrupt. +* EN_DRR_SRCH_DBDC1_ERR[25] - (RW) Enable DRR DBDC1 sta search error +interrupt. +* EN_DRR_FL_ERR[26] - (RW) Enable DRR forward link access error +interrupt. +* EN_DRR_BL_ERR[27] - (RW) Enable DRR backward link access error +interrupt. +* EN_DRR_RL_ERR[28] - (RW) Enable DRR relay link access error +interrupt. +* EN_DRR_CHRG_STA_ERR[29] - (RW) Enable DRR wlanid error when charge +interrupt. +* EN_DRR_STA_WLANID_ERR[30] - (RW) Enable DRR wlanid error when add/remove +* sta interrupt. +* EN_DRR_STA_WMMID_ERR[31] - (RW) Enable DRR wmmid error when add/remove +* sta interrupt. +*/ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_STA_WMMID_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_STA_WMMID_ERR_MASK \ + 0x80000000 /* EN_DRR_STA_WMMID_ERR[31] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_STA_WMMID_ERR_SHFT 31 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_STA_WLANID_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_STA_WLANID_ERR_MASK \ + 0x40000000 /* EN_DRR_STA_WLANID_ERR[30] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_STA_WLANID_ERR_SHFT 30 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_CHRG_STA_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_CHRG_STA_ERR_MASK \ + 0x20000000 /* EN_DRR_CHRG_STA_ERR[29] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_CHRG_STA_ERR_SHFT 29 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_RL_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_RL_ERR_MASK \ + 0x10000000 /* EN_DRR_RL_ERR[28] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_RL_ERR_SHFT 28 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_BL_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_BL_ERR_MASK \ + 0x08000000 /* EN_DRR_BL_ERR[27] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_BL_ERR_SHFT 27 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_FL_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_FL_ERR_MASK \ + 0x04000000 /* EN_DRR_FL_ERR[26] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_FL_ERR_SHFT 26 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_SRCH_DBDC1_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_SRCH_DBDC1_ERR_MASK \ + 0x02000000 /* EN_DRR_SRCH_DBDC1_ERR[25] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_SRCH_DBDC1_ERR_SHFT 25 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_SRCH_DBDC0_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_SRCH_DBDC0_ERR_MASK \ + 0x01000000 /* EN_DRR_SRCH_DBDC0_ERR[24] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_SRCH_DBDC0_ERR_SHFT 24 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_BN1_TXCMD_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_BN1_TXCMD_HANG_ERR_MASK \ + 0x00800000 /* EN_BN1_TXCMD_HANG_ERR[23] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_BN1_TXCMD_HANG_ERR_SHFT 23 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_BN0_TXCMD_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_BN0_TXCMD_HANG_ERR_MASK \ + 0x00400000 /* EN_BN0_TXCMD_HANG_ERR[22] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_BN0_TXCMD_HANG_ERR_SHFT 22 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_BN1_MACTX_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_BN1_MACTX_HANG_ERR_MASK \ + 0x00200000 /* EN_BN1_MACTX_HANG_ERR[21] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_BN1_MACTX_HANG_ERR_SHFT 21 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_BN0_MACTX_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_BN0_MACTX_HANG_ERR_MASK \ + 0x00100000 /* EN_BN0_MACTX_HANG_ERR[20] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_BN0_MACTX_HANG_ERR_SHFT 20 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_QSTRUCT_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_QSTRUCT_ERR_MASK \ + 0x00080000 /* EN_QSTRUCT_ERR[19] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_QSTRUCT_ERR_SHFT 19 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_FREE_HEAD_TAIL_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_FREE_HEAD_TAIL_ERR_MASK \ + 0x00040000 /* EN_FREE_HEAD_TAIL_ERR[18] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_FREE_HEAD_TAIL_ERR_SHFT 18 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_LMAC_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_LMAC_HANG_ERR_MASK \ + 0x00020000 /* EN_LMAC_HANG_ERR[17] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_LMAC_HANG_ERR_SHFT 17 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_CPU_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_CPU_HANG_ERR_MASK \ + 0x00010000 /* EN_CPU_HANG_ERR[16] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_CPU_HANG_ERR_SHFT 16 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_HIF_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_HIF_HANG_ERR_MASK \ + 0x00008000 /* EN_HIF_HANG_ERR[15] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_HIF_HANG_ERR_SHFT 15 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_PL_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_PL_HANG_ERR_MASK \ + 0x00004000 /* EN_PL_HANG_ERR[14] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_PL_HANG_ERR_SHFT 14 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_FL_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_FL_HANG_ERR_MASK \ + 0x00002000 /* EN_FL_HANG_ERR[13] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_FL_HANG_ERR_SHFT 13 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P2_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P2_MASK \ + 0x00001000 /* EN_DATA_OPER_ERR_P2[12] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P2_SHFT 12 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P1_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P1_MASK \ + 0x00000800 /* EN_DATA_OPER_ERR_P1[11] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P1_SHFT 11 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P0_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P0_MASK \ + 0x00000400 /* EN_DATA_OPER_ERR_P0[10] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P0_SHFT 10 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_MDP_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_MDP_HANG_ERR_MASK \ + 0x00000100 /* EN_MDP_HANG_ERR[8] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_MDP_HANG_ERR_SHFT 8 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_MDP_D_OPER_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_MDP_D_OPER_ERR_MASK \ + 0x00000080 /* EN_MDP_D_OPER_ERR[7] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_MDP_D_OPER_ERR_SHFT 7 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DOUBLE_RLS_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DOUBLE_RLS_ERR_MASK \ + 0x00000040 /* EN_DOUBLE_RLS_ERR[6] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DOUBLE_RLS_ERR_SHFT 6 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P2_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P2_MASK \ + 0x00000020 /* EN_PAGE_UDF_P2[5] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P2_SHFT 5 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P1_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P1_MASK \ + 0x00000010 /* EN_PAGE_UDF_P1[4] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P1_SHFT 4 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P0_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P0_MASK \ + 0x00000008 /* EN_PAGE_UDF_P0[3] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P0_SHFT 3 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P2_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P2_MASK \ + 0x00000004 /* EN_Q_CMD_ERR_P2[2] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P2_SHFT 2 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P1_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P1_MASK \ + 0x00000002 /* EN_Q_CMD_ERR_P1[1] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P1_SHFT 1 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P0_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P0_MASK \ + 0x00000001 /* EN_Q_CMD_ERR_P0[0] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P0_SHFT 0 + +/* +* ---INT_N9_ERR_MASK_1 (0x820C0000 + 0x88)--- +* EN_BN0_MDP_TDP_HANG_ERR[0] - (RW) Enables Band0 MDP TDP FSM hang error +interrupt +* EN_MDP_RDP_HANG_ERR[1] - (RW) Enables MDP RDP FSM hang error interrupt +* EN_BN0_MDP_TIOC_HANG_ERR[2] - (RW) Enables Band0 MDP TIOC FSM hang error +interrupt +* EN_BN0_MDP_RIOC_HANG_ERR[3] - (RW) Enables Band0 MDP RIOC FSM hang error +interrupt +* EN_PF_HANG_ERR[4] - (RW) Enables PF FSM hang error interrupt +* EN_SEC0_HANG_ERR[5] - (RW) Enables SEC 0 FSM hang error interrupt +* EN_SEC1_HANG_ERR[6] - (RW) Enables SEC 1 FSM hang error interrupt +* EN_BN1_MDP_TDP_HANG_ERR[7] - (RW) Enables Band1 MDP TDP FSM hang error +interrupt +* EN_BN1_MDP_TIOC_HANG_ERR[8] - (RW) Enables Band1 MDP TIOC FSM hang error +interrupt +* EN_BN1_MDP_RIOC_HANG_ERR[9] - (RW) Enables Band1 MDP RIOC FSM hang error +interrupt +* RESERVED10[11..10] - (RO) Reserved bits +* EN_BN0_PREDL_ARB_HANG_ERR[12] - (RW) Enables Band0 PREDL ARB FSM hang error +interrupt +* EN_BN0_PREDL_TXCMD_HANG_ERR[13] - (RW) Enables Band0 PREDL TXCMD parser FSM +* hang error interrupt +* EN_BN1_PREDL_ARB_HANG_ERR[14] - (RW) Enables Band1 PREDL ARB FSM hang error +interrupt +* EN_BN1_PREDL_TXCMD_HANG_ERR[15] - (RW) Enables Band1 PREDL TXCMD parser FSM +* hang error interrupt +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_PREDL_TXCMD_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_PREDL_TXCMD_HANG_ERR_MASK \ + 0x00008000 /* EN_BN1_PREDL_TXCMD_HANG_ERR[15] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_PREDL_TXCMD_HANG_ERR_SHFT 15 +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_PREDL_ARB_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_PREDL_ARB_HANG_ERR_MASK \ + 0x00004000 /* EN_BN1_PREDL_ARB_HANG_ERR[14] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_PREDL_ARB_HANG_ERR_SHFT 14 +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_PREDL_TXCMD_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_PREDL_TXCMD_HANG_ERR_MASK \ + 0x00002000 /* EN_BN0_PREDL_TXCMD_HANG_ERR[13] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_PREDL_TXCMD_HANG_ERR_SHFT 13 +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_PREDL_ARB_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_PREDL_ARB_HANG_ERR_MASK \ + 0x00001000 /* EN_BN0_PREDL_ARB_HANG_ERR[12] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_PREDL_ARB_HANG_ERR_SHFT 12 +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_MDP_RIOC_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_MDP_RIOC_HANG_ERR_MASK \ + 0x00000200 /* EN_BN1_MDP_RIOC_HANG_ERR[9] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_MDP_RIOC_HANG_ERR_SHFT 9 +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_MDP_TIOC_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_MDP_TIOC_HANG_ERR_MASK \ + 0x00000100 /* EN_BN1_MDP_TIOC_HANG_ERR[8] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_MDP_TIOC_HANG_ERR_SHFT 8 +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_MDP_TDP_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_MDP_TDP_HANG_ERR_MASK \ + 0x00000080 /* EN_BN1_MDP_TDP_HANG_ERR[7] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_MDP_TDP_HANG_ERR_SHFT 7 +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_SEC1_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_SEC1_HANG_ERR_MASK \ + 0x00000040 /* EN_SEC1_HANG_ERR[6] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_SEC1_HANG_ERR_SHFT 6 +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_SEC0_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_SEC0_HANG_ERR_MASK \ + 0x00000020 /* EN_SEC0_HANG_ERR[5] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_SEC0_HANG_ERR_SHFT 5 +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_PF_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_PF_HANG_ERR_MASK \ + 0x00000010 /* EN_PF_HANG_ERR[4] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_PF_HANG_ERR_SHFT 4 +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_MDP_RIOC_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_MDP_RIOC_HANG_ERR_MASK \ + 0x00000008 /* EN_BN0_MDP_RIOC_HANG_ERR[3] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_MDP_RIOC_HANG_ERR_SHFT 3 +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_MDP_TIOC_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_MDP_TIOC_HANG_ERR_MASK \ + 0x00000004 /* EN_BN0_MDP_TIOC_HANG_ERR[2] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_MDP_TIOC_HANG_ERR_SHFT 2 +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_MDP_RDP_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_MDP_RDP_HANG_ERR_MASK \ + 0x00000002 /* EN_MDP_RDP_HANG_ERR[1] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_MDP_RDP_HANG_ERR_SHFT 1 +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_MDP_TDP_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_MDP_TDP_HANG_ERR_MASK \ + 0x00000001 /* EN_BN0_MDP_TDP_HANG_ERR[0] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_MDP_TDP_HANG_ERR_SHFT 0 + +/* +* ---N9_BSS_PS_INT_MASK (0x820C0000 + 0x8c)--- +* EN_BSSID0_NONEMPTY_INT[0] - (RW) Enable control of BSSID0 queue empty +fall +* EN_BSSID1_NONEMPTY_INT[1] - (RW) Enable control of BSSID1 queue empty +fall +* EN_BSSID2_NONEMPTY_INT[2] - (RW) Enable control of BSSID2 queue empty +fall +* EN_BSSID3_NONEMPTY_INT[3] - (RW) Enable control of BSSID3 queue empty +fall +* RESERVED4[7..4] - (RO) Reserved bits +* EN_BSSID0_EMPTY_INT[8] - (RW) Enable control of BSSID0 queue empty +raise +* EN_BSSID1_EMPTY_INT[9] - (RW) Enable control of BSSID1 queue empty +raise +* EN_BSSID2_EMPTY_INT[10] - (RW) Enable control of BSSID2 queue empty +raise +* EN_BSSID3_EMPTY_INT[11] - (RW) Enable control of BSSID3 queue empty +raise +* RESERVED12[15..12] - (RO) Reserved bits +* EN_BSSID0_ENQ_LMAC_INT[16] - (RW) Enable control of BSSID0 enqueue +interrupt +* EN_BSSID1_ENQ_LMAC_INT[17] - (RW) Enable control of BSSID1 enqueue +interrupt +* EN_BSSID2_ENQ_LMAC_INT[18] - (RW) Enable control of BSSID2 enqueue +interrupt +* EN_BSSID3_ENQ_LMAC_INT[19] - (RW) Enable control of BSSID3 enqueue +interrupt +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID3_ENQ_LMAC_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_MASK_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID3_ENQ_LMAC_INT_MASK \ + 0x00080000 /* EN_BSSID3_ENQ_LMAC_INT[19] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID3_ENQ_LMAC_INT_SHFT 19 +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID2_ENQ_LMAC_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_MASK_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID2_ENQ_LMAC_INT_MASK \ + 0x00040000 /* EN_BSSID2_ENQ_LMAC_INT[18] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID2_ENQ_LMAC_INT_SHFT 18 +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID1_ENQ_LMAC_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_MASK_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID1_ENQ_LMAC_INT_MASK \ + 0x00020000 /* EN_BSSID1_ENQ_LMAC_INT[17] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID1_ENQ_LMAC_INT_SHFT 17 +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID0_ENQ_LMAC_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_MASK_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID0_ENQ_LMAC_INT_MASK \ + 0x00010000 /* EN_BSSID0_ENQ_LMAC_INT[16] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID0_ENQ_LMAC_INT_SHFT 16 +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID3_EMPTY_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_MASK_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID3_EMPTY_INT_MASK \ + 0x00000800 /* EN_BSSID3_EMPTY_INT[11] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID3_EMPTY_INT_SHFT 11 +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID2_EMPTY_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_MASK_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID2_EMPTY_INT_MASK \ + 0x00000400 /* EN_BSSID2_EMPTY_INT[10] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID2_EMPTY_INT_SHFT 10 +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID1_EMPTY_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_MASK_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID1_EMPTY_INT_MASK \ + 0x00000200 /* EN_BSSID1_EMPTY_INT[9] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID1_EMPTY_INT_SHFT 9 +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID0_EMPTY_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_MASK_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID0_EMPTY_INT_MASK \ + 0x00000100 /* EN_BSSID0_EMPTY_INT[8] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID0_EMPTY_INT_SHFT 8 +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID3_NONEMPTY_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_MASK_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID3_NONEMPTY_INT_MASK \ + 0x00000008 /* EN_BSSID3_NONEMPTY_INT[3] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID3_NONEMPTY_INT_SHFT 3 +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID2_NONEMPTY_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_MASK_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID2_NONEMPTY_INT_MASK \ + 0x00000004 /* EN_BSSID2_NONEMPTY_INT[2] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID2_NONEMPTY_INT_SHFT 2 +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID1_NONEMPTY_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_MASK_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID1_NONEMPTY_INT_MASK \ + 0x00000002 /* EN_BSSID1_NONEMPTY_INT[1] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID1_NONEMPTY_INT_SHFT 1 +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID0_NONEMPTY_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_MASK_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID0_NONEMPTY_INT_MASK \ + 0x00000001 /* EN_BSSID0_NONEMPTY_INT[0] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID0_NONEMPTY_INT_SHFT 0 + +/* +* ---HOST_REPORT0 (0x820C0000 + 0x90)--- +* RESERVED0[0] - (RO) Reserved bits +* DIS_HOST_RPT[1] - (RW) Disables host report function +* HOST_RPT_VER0_EN[2] - (RW) Enable control for host report roll back +* to Version 2(MT7915 E1 used). +* HOST_RPT_TX_LATENCY[3] - (RW) Enable host report TX latency +* WMCPU_MSDU_ID_NUM[5..4] - (RW) Configuration of WMCPU MSDU ID usage. +* RESERVED6[7..6] - (RO) Reserved bits +* HOST_RPT_PACK_TH[15..8] - (RW) The buffer threshold for packing host +* report. The buffer size less then the MSDU numbers of a MPDU, would let +MSDU_ID +lose. +* HOST_RPT_QID[22..16] - (RW) PSE Queue ID control for host report. +* HOST_RPT_PID[23] - (RW) PSE Port ID control for host report. +* WMCPU_RPT_QID[30..24] - (RW) PSE Queue ID control for WMCPU report. +* WMCPU_RPT_PID[31] - (RW) PSE Port ID control for WMCPU report. +*/ +#define WF_PLE_TOP_HOST_REPORT0_WMCPU_RPT_PID_ADDR WF_PLE_TOP_HOST_REPORT0_ADDR +#define WF_PLE_TOP_HOST_REPORT0_WMCPU_RPT_PID_MASK \ + 0x80000000 /* WMCPU_RPT_PID[31] */ +#define WF_PLE_TOP_HOST_REPORT0_WMCPU_RPT_PID_SHFT 31 +#define WF_PLE_TOP_HOST_REPORT0_WMCPU_RPT_QID_ADDR WF_PLE_TOP_HOST_REPORT0_ADDR +#define WF_PLE_TOP_HOST_REPORT0_WMCPU_RPT_QID_MASK \ + 0x7F000000 /* WMCPU_RPT_QID[30..24] */ +#define WF_PLE_TOP_HOST_REPORT0_WMCPU_RPT_QID_SHFT 24 +#define WF_PLE_TOP_HOST_REPORT0_HOST_RPT_PID_ADDR WF_PLE_TOP_HOST_REPORT0_ADDR +#define WF_PLE_TOP_HOST_REPORT0_HOST_RPT_PID_MASK \ + 0x00800000 /* HOST_RPT_PID[23] */ +#define WF_PLE_TOP_HOST_REPORT0_HOST_RPT_PID_SHFT 23 +#define WF_PLE_TOP_HOST_REPORT0_HOST_RPT_QID_ADDR WF_PLE_TOP_HOST_REPORT0_ADDR +#define WF_PLE_TOP_HOST_REPORT0_HOST_RPT_QID_MASK \ + 0x007F0000 /* HOST_RPT_QID[22..16] */ +#define WF_PLE_TOP_HOST_REPORT0_HOST_RPT_QID_SHFT 16 +#define WF_PLE_TOP_HOST_REPORT0_HOST_RPT_PACK_TH_ADDR \ + WF_PLE_TOP_HOST_REPORT0_ADDR +#define WF_PLE_TOP_HOST_REPORT0_HOST_RPT_PACK_TH_MASK \ + 0x0000FF00 /* HOST_RPT_PACK_TH[15..8] */ +#define WF_PLE_TOP_HOST_REPORT0_HOST_RPT_PACK_TH_SHFT 8 +#define WF_PLE_TOP_HOST_REPORT0_WMCPU_MSDU_ID_NUM_ADDR \ + WF_PLE_TOP_HOST_REPORT0_ADDR +#define WF_PLE_TOP_HOST_REPORT0_WMCPU_MSDU_ID_NUM_MASK \ + 0x00000030 /* WMCPU_MSDU_ID_NUM[5..4] */ +#define WF_PLE_TOP_HOST_REPORT0_WMCPU_MSDU_ID_NUM_SHFT 4 +#define WF_PLE_TOP_HOST_REPORT0_HOST_RPT_TX_LATENCY_ADDR \ + WF_PLE_TOP_HOST_REPORT0_ADDR +#define WF_PLE_TOP_HOST_REPORT0_HOST_RPT_TX_LATENCY_MASK \ + 0x00000008 /* HOST_RPT_TX_LATENCY[3] */ +#define WF_PLE_TOP_HOST_REPORT0_HOST_RPT_TX_LATENCY_SHFT 3 +#define WF_PLE_TOP_HOST_REPORT0_HOST_RPT_VER0_EN_ADDR \ + WF_PLE_TOP_HOST_REPORT0_ADDR +#define WF_PLE_TOP_HOST_REPORT0_HOST_RPT_VER0_EN_MASK \ + 0x00000004 /* HOST_RPT_VER0_EN[2] */ +#define WF_PLE_TOP_HOST_REPORT0_HOST_RPT_VER0_EN_SHFT 2 +#define WF_PLE_TOP_HOST_REPORT0_DIS_HOST_RPT_ADDR WF_PLE_TOP_HOST_REPORT0_ADDR +#define WF_PLE_TOP_HOST_REPORT0_DIS_HOST_RPT_MASK \ + 0x00000002 /* DIS_HOST_RPT[1] */ +#define WF_PLE_TOP_HOST_REPORT0_DIS_HOST_RPT_SHFT 1 + +/* +* ---HOST_REPORT1 (0x820C0000 + 0x94)--- +* RESERVED0[7..0] - (RO) Reserved bits +* MD_RPT_QID[14..8] - (RW) PSE Queue ID control for MD CPU host +report. +* MD_RPT_PID[15] - (RW) PSE Port ID control for MD CPU host +report. +* HOST_RPT_PG_SIZE[19..16] - (RW) Setting of host report used PSE page +size. +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_HOST_REPORT1_HOST_RPT_PG_SIZE_ADDR \ + WF_PLE_TOP_HOST_REPORT1_ADDR +#define WF_PLE_TOP_HOST_REPORT1_HOST_RPT_PG_SIZE_MASK \ + 0x000F0000 /* HOST_RPT_PG_SIZE[19..16] */ +#define WF_PLE_TOP_HOST_REPORT1_HOST_RPT_PG_SIZE_SHFT 16 +#define WF_PLE_TOP_HOST_REPORT1_MD_RPT_PID_ADDR WF_PLE_TOP_HOST_REPORT1_ADDR +#define WF_PLE_TOP_HOST_REPORT1_MD_RPT_PID_MASK 0x00008000 /* MD_RPT_PID[15] */ +#define WF_PLE_TOP_HOST_REPORT1_MD_RPT_PID_SHFT 15 +#define WF_PLE_TOP_HOST_REPORT1_MD_RPT_QID_ADDR WF_PLE_TOP_HOST_REPORT1_ADDR +#define WF_PLE_TOP_HOST_REPORT1_MD_RPT_QID_MASK \ + 0x00007F00 /* MD_RPT_QID[14..8] */ +#define WF_PLE_TOP_HOST_REPORT1_MD_RPT_QID_SHFT 8 + +/* +* ---HOST_REPORT2 (0x820C0000 + 0x98)--- +* BN1_HOST_RPT_QID[6..0] - (RW) PSE Queue ID control for BN1 Host +report. +* BN1_HOST_RPT_PID[7] - (RW) PSE Port ID control for BN1 Host report. +* BN1_MD_RPT_QID[14..8] - (RW) PSE Queue ID control for BN1 MD CPU host +report. +* BN1_MD_RPT_PID[15] - (RW) PSE Port ID control for BN1 MD CPU host +report. +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_HOST_REPORT2_BN1_MD_RPT_PID_ADDR WF_PLE_TOP_HOST_REPORT2_ADDR +#define WF_PLE_TOP_HOST_REPORT2_BN1_MD_RPT_PID_MASK \ + 0x00008000 /* BN1_MD_RPT_PID[15] */ +#define WF_PLE_TOP_HOST_REPORT2_BN1_MD_RPT_PID_SHFT 15 +#define WF_PLE_TOP_HOST_REPORT2_BN1_MD_RPT_QID_ADDR WF_PLE_TOP_HOST_REPORT2_ADDR +#define WF_PLE_TOP_HOST_REPORT2_BN1_MD_RPT_QID_MASK \ + 0x00007F00 /* BN1_MD_RPT_QID[14..8] */ +#define WF_PLE_TOP_HOST_REPORT2_BN1_MD_RPT_QID_SHFT 8 +#define WF_PLE_TOP_HOST_REPORT2_BN1_HOST_RPT_PID_ADDR \ + WF_PLE_TOP_HOST_REPORT2_ADDR +#define WF_PLE_TOP_HOST_REPORT2_BN1_HOST_RPT_PID_MASK \ + 0x00000080 /* BN1_HOST_RPT_PID[7] */ +#define WF_PLE_TOP_HOST_REPORT2_BN1_HOST_RPT_PID_SHFT 7 +#define WF_PLE_TOP_HOST_REPORT2_BN1_HOST_RPT_QID_ADDR \ + WF_PLE_TOP_HOST_REPORT2_ADDR +#define WF_PLE_TOP_HOST_REPORT2_BN1_HOST_RPT_QID_MASK \ + 0x0000007F /* BN1_HOST_RPT_QID[6..0] */ +#define WF_PLE_TOP_HOST_REPORT2_BN1_HOST_RPT_QID_SHFT 0 + +/* +* ---RELEASE_CTRL_0 (0x820C0000 + 0x9c)--- +* NOR_RLS_QID[6..0] - (RW) Normal TX packet release DST QID +* RESERVED7[7] - (RO) Reserved bits +* NOR_RLS_PID[9..8] - (RW) Normal TX packet release DST PID +* RESERVED10[15..10] - (RO) Reserved bits +* DROP_RLS_QID[22..16] - (RW) Drop packet release DST QID +* RESERVED23[23] - (RO) Reserved bits +* DROP_RLS_PID[25..24] - (RW) Drop packet release DST PID +* RESERVED26[31..26] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_RELEASE_CTRL_0_DROP_RLS_PID_ADDR \ + WF_PLE_TOP_RELEASE_CTRL_0_ADDR +#define WF_PLE_TOP_RELEASE_CTRL_0_DROP_RLS_PID_MASK \ + 0x03000000 /* DROP_RLS_PID[25..24] */ +#define WF_PLE_TOP_RELEASE_CTRL_0_DROP_RLS_PID_SHFT 24 +#define WF_PLE_TOP_RELEASE_CTRL_0_DROP_RLS_QID_ADDR \ + WF_PLE_TOP_RELEASE_CTRL_0_ADDR +#define WF_PLE_TOP_RELEASE_CTRL_0_DROP_RLS_QID_MASK \ + 0x007F0000 /* DROP_RLS_QID[22..16] */ +#define WF_PLE_TOP_RELEASE_CTRL_0_DROP_RLS_QID_SHFT 16 +#define WF_PLE_TOP_RELEASE_CTRL_0_NOR_RLS_PID_ADDR \ + WF_PLE_TOP_RELEASE_CTRL_0_ADDR +#define WF_PLE_TOP_RELEASE_CTRL_0_NOR_RLS_PID_MASK \ + 0x00000300 /* NOR_RLS_PID[9..8] */ +#define WF_PLE_TOP_RELEASE_CTRL_0_NOR_RLS_PID_SHFT 8 +#define WF_PLE_TOP_RELEASE_CTRL_0_NOR_RLS_QID_ADDR \ + WF_PLE_TOP_RELEASE_CTRL_0_ADDR +#define WF_PLE_TOP_RELEASE_CTRL_0_NOR_RLS_QID_MASK \ + 0x0000007F /* NOR_RLS_QID[6..0] */ +#define WF_PLE_TOP_RELEASE_CTRL_0_NOR_RLS_QID_SHFT 0 + +/* +* ---RELEASE_CTRL_1 (0x820C0000 + 0xA0)--- +* BCN0_RLS_QID[6..0] - (RW) Beacon 0 packet release DST QID +* RESERVED7[7] - (RO) Reserved bits +* BCN0_RLS_PID[9..8] - (RW) Beacon 0 packet release DST PID +* RESERVED10[15..10] - (RO) Reserved bits +* BCN1_RLS_QID[22..16] - (RW) Beacon 1 packet release DST QID +* RESERVED23[23] - (RO) Reserved bits +* BCN1_RLS_PID[25..24] - (RW) Beacon 1 packet release DST PID +* RESERVED26[31..26] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_RELEASE_CTRL_1_BCN1_RLS_PID_ADDR \ + WF_PLE_TOP_RELEASE_CTRL_1_ADDR +#define WF_PLE_TOP_RELEASE_CTRL_1_BCN1_RLS_PID_MASK \ + 0x03000000 /* BCN1_RLS_PID[25..24] */ +#define WF_PLE_TOP_RELEASE_CTRL_1_BCN1_RLS_PID_SHFT 24 +#define WF_PLE_TOP_RELEASE_CTRL_1_BCN1_RLS_QID_ADDR \ + WF_PLE_TOP_RELEASE_CTRL_1_ADDR +#define WF_PLE_TOP_RELEASE_CTRL_1_BCN1_RLS_QID_MASK \ + 0x007F0000 /* BCN1_RLS_QID[22..16] */ +#define WF_PLE_TOP_RELEASE_CTRL_1_BCN1_RLS_QID_SHFT 16 +#define WF_PLE_TOP_RELEASE_CTRL_1_BCN0_RLS_PID_ADDR \ + WF_PLE_TOP_RELEASE_CTRL_1_ADDR +#define WF_PLE_TOP_RELEASE_CTRL_1_BCN0_RLS_PID_MASK \ + 0x00000300 /* BCN0_RLS_PID[9..8] */ +#define WF_PLE_TOP_RELEASE_CTRL_1_BCN0_RLS_PID_SHFT 8 +#define WF_PLE_TOP_RELEASE_CTRL_1_BCN0_RLS_QID_ADDR \ + WF_PLE_TOP_RELEASE_CTRL_1_ADDR +#define WF_PLE_TOP_RELEASE_CTRL_1_BCN0_RLS_QID_MASK \ + 0x0000007F /* BCN0_RLS_QID[6..0] */ +#define WF_PLE_TOP_RELEASE_CTRL_1_BCN0_RLS_QID_SHFT 0 + +/* +* ---RELEASE_CTRL_3 (0x820C0000 + 0xa8)--- +* RLS_FREE_DONE_PG_SIZE[3..0] - (RW) Page size configuration of Free done +* event(host report). +* RESERVED4[31..4] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_RELEASE_CTRL_3_RLS_FREE_DONE_PG_SIZE_ADDR \ + WF_PLE_TOP_RELEASE_CTRL_3_ADDR +#define WF_PLE_TOP_RELEASE_CTRL_3_RLS_FREE_DONE_PG_SIZE_MASK \ + 0x0000000F /* RLS_FREE_DONE_PG_SIZE[3..0] */ +#define WF_PLE_TOP_RELEASE_CTRL_3_RLS_FREE_DONE_PG_SIZE_SHFT 0 + +/* +* ---BLK_MODE_RATE_LMT (0x820C0000 + 0xac)--- +* BN0_MACTX_BLK_RATE_LMT[15..0] - (RW) TX Rate limitaion of CutThrough data +* block mode. The rate less then the limitation would turn on block mode. +* BN1_MACTX_BLK_RATE_LMT[31..16] - (RW) TX Rate limitaion of CutThrough data +* block mode. The rate less then the limitation would turn on block mode. +*/ +#define WF_PLE_TOP_BLK_MODE_RATE_LMT_BN1_MACTX_BLK_RATE_LMT_ADDR \ + WF_PLE_TOP_BLK_MODE_RATE_LMT_ADDR +#define WF_PLE_TOP_BLK_MODE_RATE_LMT_BN1_MACTX_BLK_RATE_LMT_MASK \ + 0xFFFF0000 /* BN1_MACTX_BLK_RATE_LMT[31..16] */ +#define WF_PLE_TOP_BLK_MODE_RATE_LMT_BN1_MACTX_BLK_RATE_LMT_SHFT 16 +#define WF_PLE_TOP_BLK_MODE_RATE_LMT_BN0_MACTX_BLK_RATE_LMT_ADDR \ + WF_PLE_TOP_BLK_MODE_RATE_LMT_ADDR +#define WF_PLE_TOP_BLK_MODE_RATE_LMT_BN0_MACTX_BLK_RATE_LMT_MASK \ + 0x0000FFFF /* BN0_MACTX_BLK_RATE_LMT[15..0] */ +#define WF_PLE_TOP_BLK_MODE_RATE_LMT_BN0_MACTX_BLK_RATE_LMT_SHFT 0 + +/* +* ---PLE_MODULE_CKG_DIS (0x820C0000 + 0xb0)--- +* DIS_FL_DYN_CKG[0] - (RW) Disable control of PLE frame link module +* dynamic clock gating function +* DIS_PL_DYN_CKG[1] - (RW) Disable control of PLE page link module +* dynamic clock gating function +* DIS_CPU_PORT_DYN_CKG[2] - (RW) Disable control of PLE CPU port module +* dynamic clock gating function +* DIS_HIF_PORT_DYN_CKG[3] - (RW) Disable control of PLE HIF port module +* dynamic clock gating function +* DIS_WF_PORT_DYN_CKG[4] - (RW) Disable control of PLE LMAC module +* dynamic clock gating function +* DIS_RLS_DYN_CKG[5] - (RW) Disable control of PLE release module +* dynamic clock gating function +* DIS_RL_DYN_CKG[6] - (RW) Disable control of PLE relay information +* module dynamic clock gating function +* DIS_MACTX_DYN_CKG[7] - (RW) Disable control of PLE MACTX module +* dynamic clock gating function +* DIS_PSEPORT_DYN_CKG[8] - (RW) Disable control of PLE PSE port module +* dynamic clock gating function +* DIS_CSR_DYN_CKG[9] - (RW) Disable control of PLE CR module dynamic +* clock gating function +* DIS_CPU_WRAP_DYN_CKG[10] - (RW) Disable control of PLE CPU_WRAP module +* dynamic clock gating function +* DIS_DBG_DYN_CKG[11] - (RW) Disable control of PLE debug module +* dynamic clock gating function +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_DBG_DYN_CKG_ADDR \ + WF_PLE_TOP_PLE_MODULE_CKG_DIS_ADDR +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_DBG_DYN_CKG_MASK \ + 0x00000800 /* DIS_DBG_DYN_CKG[11] */ +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_DBG_DYN_CKG_SHFT 11 +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_CPU_WRAP_DYN_CKG_ADDR \ + WF_PLE_TOP_PLE_MODULE_CKG_DIS_ADDR +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_CPU_WRAP_DYN_CKG_MASK \ + 0x00000400 /* DIS_CPU_WRAP_DYN_CKG[10] */ +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_CPU_WRAP_DYN_CKG_SHFT 10 +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_CSR_DYN_CKG_ADDR \ + WF_PLE_TOP_PLE_MODULE_CKG_DIS_ADDR +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_CSR_DYN_CKG_MASK \ + 0x00000200 /* DIS_CSR_DYN_CKG[9] */ +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_CSR_DYN_CKG_SHFT 9 +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_PSEPORT_DYN_CKG_ADDR \ + WF_PLE_TOP_PLE_MODULE_CKG_DIS_ADDR +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_PSEPORT_DYN_CKG_MASK \ + 0x00000100 /* DIS_PSEPORT_DYN_CKG[8] */ +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_PSEPORT_DYN_CKG_SHFT 8 +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_MACTX_DYN_CKG_ADDR \ + WF_PLE_TOP_PLE_MODULE_CKG_DIS_ADDR +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_MACTX_DYN_CKG_MASK \ + 0x00000080 /* DIS_MACTX_DYN_CKG[7] */ +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_MACTX_DYN_CKG_SHFT 7 +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_RL_DYN_CKG_ADDR \ + WF_PLE_TOP_PLE_MODULE_CKG_DIS_ADDR +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_RL_DYN_CKG_MASK \ + 0x00000040 /* DIS_RL_DYN_CKG[6] */ +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_RL_DYN_CKG_SHFT 6 +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_RLS_DYN_CKG_ADDR \ + WF_PLE_TOP_PLE_MODULE_CKG_DIS_ADDR +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_RLS_DYN_CKG_MASK \ + 0x00000020 /* DIS_RLS_DYN_CKG[5] */ +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_RLS_DYN_CKG_SHFT 5 +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_WF_PORT_DYN_CKG_ADDR \ + WF_PLE_TOP_PLE_MODULE_CKG_DIS_ADDR +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_WF_PORT_DYN_CKG_MASK \ + 0x00000010 /* DIS_WF_PORT_DYN_CKG[4] */ +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_WF_PORT_DYN_CKG_SHFT 4 +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_HIF_PORT_DYN_CKG_ADDR \ + WF_PLE_TOP_PLE_MODULE_CKG_DIS_ADDR +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_HIF_PORT_DYN_CKG_MASK \ + 0x00000008 /* DIS_HIF_PORT_DYN_CKG[3] */ +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_HIF_PORT_DYN_CKG_SHFT 3 +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_CPU_PORT_DYN_CKG_ADDR \ + WF_PLE_TOP_PLE_MODULE_CKG_DIS_ADDR +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_CPU_PORT_DYN_CKG_MASK \ + 0x00000004 /* DIS_CPU_PORT_DYN_CKG[2] */ +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_CPU_PORT_DYN_CKG_SHFT 2 +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_PL_DYN_CKG_ADDR \ + WF_PLE_TOP_PLE_MODULE_CKG_DIS_ADDR +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_PL_DYN_CKG_MASK \ + 0x00000002 /* DIS_PL_DYN_CKG[1] */ +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_PL_DYN_CKG_SHFT 1 +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_FL_DYN_CKG_ADDR \ + WF_PLE_TOP_PLE_MODULE_CKG_DIS_ADDR +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_FL_DYN_CKG_MASK \ + 0x00000001 /* DIS_FL_DYN_CKG[0] */ +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_FL_DYN_CKG_SHFT 0 + +/* +* ---PLE_DELAY_TX_CTRL (0x820C0000 + 0xb4)--- +* DELAY_TX_PAGE_TH[11..0] - (RW) Delay TX function is used to delay TXD +* be LMAC used. If the total pages of TXD large than page threshold, the delay +TX +* would be released. LMAC would use TXD to TX. +* RESERVED12[15..12] - (RO) Reserved bits +* DELAY_TX_TIMEOUT_TH[23..16] - (RW) Delay TX function is used to delay TXD +* be LMAC used. IF no more enqueue event in the time out threshold, the delay TX +* would be released. LMAC can use TXD to TX. (unit is 32us). +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_PLE_DELAY_TX_CTRL_DELAY_TX_TIMEOUT_TH_ADDR \ + WF_PLE_TOP_PLE_DELAY_TX_CTRL_ADDR +#define WF_PLE_TOP_PLE_DELAY_TX_CTRL_DELAY_TX_TIMEOUT_TH_MASK \ + 0x00FF0000 /* DELAY_TX_TIMEOUT_TH[23..16] */ +#define WF_PLE_TOP_PLE_DELAY_TX_CTRL_DELAY_TX_TIMEOUT_TH_SHFT 16 +#define WF_PLE_TOP_PLE_DELAY_TX_CTRL_DELAY_TX_PAGE_TH_ADDR \ + WF_PLE_TOP_PLE_DELAY_TX_CTRL_ADDR +#define WF_PLE_TOP_PLE_DELAY_TX_CTRL_DELAY_TX_PAGE_TH_MASK \ + 0x00000FFF /* DELAY_TX_PAGE_TH[11..0] */ +#define WF_PLE_TOP_PLE_DELAY_TX_CTRL_DELAY_TX_PAGE_TH_SHFT 0 + +/* +* ---PLE_STATION_REDIR_CTRL (0x820C0000 + 0xb8)--- +* STA_REDIR_QID[4..0] - (RW) Destitaion queue for Redirection +function. +* RESERVED5[5] - (RO) Reserved bits +* STA_REDIR_PID[7..6] - (RW) Destitaion port for Redirection +function. +* STA_REDIR_PASUE_TXD[8] - (RW) Pause TXD download for avoid race +* condition, when station redirection function turn off. +* RESERVED9[31..9] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_PLE_STATION_REDIR_CTRL_STA_REDIR_PASUE_TXD_ADDR \ + WF_PLE_TOP_PLE_STATION_REDIR_CTRL_ADDR +#define WF_PLE_TOP_PLE_STATION_REDIR_CTRL_STA_REDIR_PASUE_TXD_MASK \ + 0x00000100 /* STA_REDIR_PASUE_TXD[8] */ +#define WF_PLE_TOP_PLE_STATION_REDIR_CTRL_STA_REDIR_PASUE_TXD_SHFT 8 +#define WF_PLE_TOP_PLE_STATION_REDIR_CTRL_STA_REDIR_PID_ADDR \ + WF_PLE_TOP_PLE_STATION_REDIR_CTRL_ADDR +#define WF_PLE_TOP_PLE_STATION_REDIR_CTRL_STA_REDIR_PID_MASK \ + 0x000000C0 /* STA_REDIR_PID[7..6] */ +#define WF_PLE_TOP_PLE_STATION_REDIR_CTRL_STA_REDIR_PID_SHFT 6 +#define WF_PLE_TOP_PLE_STATION_REDIR_CTRL_STA_REDIR_QID_ADDR \ + WF_PLE_TOP_PLE_STATION_REDIR_CTRL_ADDR +#define WF_PLE_TOP_PLE_STATION_REDIR_CTRL_STA_REDIR_QID_MASK \ + 0x0000001F /* STA_REDIR_QID[4..0] */ +#define WF_PLE_TOP_PLE_STATION_REDIR_CTRL_STA_REDIR_QID_SHFT 0 + +/* +* ---MACTX_LENGTH_LIMIT (0x820C0000 + 0xBC)--- +* MACTX_LENGTH_LIMIT_BAND0[15..0] - (RW) MACTX download length limit of band0 +* MACTX_LENGTH_LIMIT_BAND1[31..16] - (RW) MACTX download length limit of band1 +*/ +#define WF_PLE_TOP_MACTX_LENGTH_LIMIT_MACTX_LENGTH_LIMIT_BAND1_ADDR \ + WF_PLE_TOP_MACTX_LENGTH_LIMIT_ADDR +#define WF_PLE_TOP_MACTX_LENGTH_LIMIT_MACTX_LENGTH_LIMIT_BAND1_MASK \ + 0xFFFF0000 /* MACTX_LENGTH_LIMIT_BAND1[31..16] */ +#define WF_PLE_TOP_MACTX_LENGTH_LIMIT_MACTX_LENGTH_LIMIT_BAND1_SHFT 16 +#define WF_PLE_TOP_MACTX_LENGTH_LIMIT_MACTX_LENGTH_LIMIT_BAND0_ADDR \ + WF_PLE_TOP_MACTX_LENGTH_LIMIT_ADDR +#define WF_PLE_TOP_MACTX_LENGTH_LIMIT_MACTX_LENGTH_LIMIT_BAND0_MASK \ + 0x0000FFFF /* MACTX_LENGTH_LIMIT_BAND0[15..0] */ +#define WF_PLE_TOP_MACTX_LENGTH_LIMIT_MACTX_LENGTH_LIMIT_BAND0_SHFT 0 + +/* +* ---TXS_BUF_PAUSE (0x820C0000 + 0xc0)--- +* EN_PAUSE_AC00_QUEUE[0] - (RW) Pause control of WMM0 AC0 queue. +* EN_PAUSE_AC01_QUEUE[1] - (RW) Pause control of WMM0 AC1 queue. +* EN_PAUSE_AC02_QUEUE[2] - (RW) Pause control of WMM0 AC2 queue. +* EN_PAUSE_AC03_QUEUE[3] - (RW) Pause control of WMM0 AC3 queue. +* EN_PAUSE_AC10_QUEUE[4] - (RW) Pause control of WMM1 AC0 queue. +* EN_PAUSE_AC11_QUEUE[5] - (RW) Pause control of WMM1 AC1 queue. +* EN_PAUSE_AC12_QUEUE[6] - (RW) Pause control of WMM1 AC2 queue. +* EN_PAUSE_AC13_QUEUE[7] - (RW) Pause control of WMM1 AC3 queue. +* EN_PAUSE_AC20_QUEUE[8] - (RW) Pause control of WMM2 AC0 queue. +* EN_PAUSE_AC21_QUEUE[9] - (RW) Pause control of WMM2 AC1 queue. +* EN_PAUSE_AC22_QUEUE[10] - (RW) Pause control of WMM2 AC2 queue. +* EN_PAUSE_AC23_QUEUE[11] - (RW) Pause control of WMM2 AC3 queue. +* EN_PAUSE_AC30_QUEUE[12] - (RW) Pause control of WMM3 AC0 queue. +* EN_PAUSE_AC31_QUEUE[13] - (RW) Pause control of WMM3 AC1 queue. +* EN_PAUSE_AC32_QUEUE[14] - (RW) Pause control of WMM3 AC2 queue. +* EN_PAUSE_AC33_QUEUE[15] - (RW) Pause control of WMM3 AC3 queue. +* EN_PAUSE_ALTX_0_QUEUE[16] - (RW) Pause control of ALTX queue 0. +* EN_PAUSE_BMC_0_QUEUE[17] - (RW) Pause control of BMC queue 0. +* EN_PAUSE_BCN_0_QUEUE[18] - (RW) Pause control of BCN queue 0. +* EN_PAUSE_PSMP_0_QUEUE[19] - (RW) Pause control of PSMP queue 0. +* EN_PAUSE_ALTX_1_QUEUE[20] - (RW) Pause control of ALTX queue 1. +* EN_PAUSE_BMC_1_QUEUE[21] - (RW) Pause control of BMC queue 1. +* EN_PAUSE_BCN_1_QUEUE[22] - (RW) Pause control of BCN queue 1. +* EN_PAUSE_PSMP_1_QUEUE[23] - (RW) Pause control of PSMP queue 1. +* EN_PAUSE_NAF_QUEUE[24] - (RW) Pause control of NAF queue. +* EN_PAUSE_NBCN_QUEUE[25] - (RW) Pause control of NBCN queue. +* RESERVED26[30..26] - (RO) Reserved bits +* PSE_TXS_BUF_VALID[31] - (RO) PSE TXS buffer status. +*/ +#define WF_PLE_TOP_TXS_BUF_PAUSE_PSE_TXS_BUF_VALID_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_PSE_TXS_BUF_VALID_MASK \ + 0x80000000 /* PSE_TXS_BUF_VALID[31] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_PSE_TXS_BUF_VALID_SHFT 31 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_NBCN_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_NBCN_QUEUE_MASK \ + 0x02000000 /* EN_PAUSE_NBCN_QUEUE[25] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_NBCN_QUEUE_SHFT 25 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_NAF_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_NAF_QUEUE_MASK \ + 0x01000000 /* EN_PAUSE_NAF_QUEUE[24] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_NAF_QUEUE_SHFT 24 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_PSMP_1_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_PSMP_1_QUEUE_MASK \ + 0x00800000 /* EN_PAUSE_PSMP_1_QUEUE[23] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_PSMP_1_QUEUE_SHFT 23 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_BCN_1_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_BCN_1_QUEUE_MASK \ + 0x00400000 /* EN_PAUSE_BCN_1_QUEUE[22] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_BCN_1_QUEUE_SHFT 22 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_BMC_1_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_BMC_1_QUEUE_MASK \ + 0x00200000 /* EN_PAUSE_BMC_1_QUEUE[21] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_BMC_1_QUEUE_SHFT 21 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_ALTX_1_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_ALTX_1_QUEUE_MASK \ + 0x00100000 /* EN_PAUSE_ALTX_1_QUEUE[20] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_ALTX_1_QUEUE_SHFT 20 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_PSMP_0_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_PSMP_0_QUEUE_MASK \ + 0x00080000 /* EN_PAUSE_PSMP_0_QUEUE[19] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_PSMP_0_QUEUE_SHFT 19 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_BCN_0_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_BCN_0_QUEUE_MASK \ + 0x00040000 /* EN_PAUSE_BCN_0_QUEUE[18] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_BCN_0_QUEUE_SHFT 18 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_BMC_0_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_BMC_0_QUEUE_MASK \ + 0x00020000 /* EN_PAUSE_BMC_0_QUEUE[17] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_BMC_0_QUEUE_SHFT 17 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_ALTX_0_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_ALTX_0_QUEUE_MASK \ + 0x00010000 /* EN_PAUSE_ALTX_0_QUEUE[16] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_ALTX_0_QUEUE_SHFT 16 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC33_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC33_QUEUE_MASK \ + 0x00008000 /* EN_PAUSE_AC33_QUEUE[15] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC33_QUEUE_SHFT 15 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC32_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC32_QUEUE_MASK \ + 0x00004000 /* EN_PAUSE_AC32_QUEUE[14] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC32_QUEUE_SHFT 14 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC31_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC31_QUEUE_MASK \ + 0x00002000 /* EN_PAUSE_AC31_QUEUE[13] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC31_QUEUE_SHFT 13 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC30_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC30_QUEUE_MASK \ + 0x00001000 /* EN_PAUSE_AC30_QUEUE[12] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC30_QUEUE_SHFT 12 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC23_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC23_QUEUE_MASK \ + 0x00000800 /* EN_PAUSE_AC23_QUEUE[11] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC23_QUEUE_SHFT 11 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC22_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC22_QUEUE_MASK \ + 0x00000400 /* EN_PAUSE_AC22_QUEUE[10] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC22_QUEUE_SHFT 10 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC21_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC21_QUEUE_MASK \ + 0x00000200 /* EN_PAUSE_AC21_QUEUE[9] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC21_QUEUE_SHFT 9 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC20_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC20_QUEUE_MASK \ + 0x00000100 /* EN_PAUSE_AC20_QUEUE[8] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC20_QUEUE_SHFT 8 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC13_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC13_QUEUE_MASK \ + 0x00000080 /* EN_PAUSE_AC13_QUEUE[7] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC13_QUEUE_SHFT 7 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC12_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC12_QUEUE_MASK \ + 0x00000040 /* EN_PAUSE_AC12_QUEUE[6] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC12_QUEUE_SHFT 6 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC11_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC11_QUEUE_MASK \ + 0x00000020 /* EN_PAUSE_AC11_QUEUE[5] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC11_QUEUE_SHFT 5 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC10_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC10_QUEUE_MASK \ + 0x00000010 /* EN_PAUSE_AC10_QUEUE[4] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC10_QUEUE_SHFT 4 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC03_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC03_QUEUE_MASK \ + 0x00000008 /* EN_PAUSE_AC03_QUEUE[3] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC03_QUEUE_SHFT 3 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC02_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC02_QUEUE_MASK \ + 0x00000004 /* EN_PAUSE_AC02_QUEUE[2] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC02_QUEUE_SHFT 2 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC01_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC01_QUEUE_MASK \ + 0x00000002 /* EN_PAUSE_AC01_QUEUE[1] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC01_QUEUE_SHFT 1 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC00_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC00_QUEUE_MASK \ + 0x00000001 /* EN_PAUSE_AC00_QUEUE[0] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC00_QUEUE_SHFT 0 + +/* +* ---FSM_IDLE_WD_CTRL (0x820C0000 + 0xd0)--- +* FL_IDLE_WD_TO_TH[7..0] - (RW) Watchdog timeout threshold for frame +* link FSM not returning to IDLE +* PL_IDLE_WD_TO_TH[15..8] - (RW) Watchdog timeout threshold for page link +* FSM not returning to IDLE +* PORT_IDLE_WD_TO_TH[23..16] - (RW) Watchdog timeout threshold for port oper +* FSM not returning to IDLE +* (Including HIF/CPU/LMAC port) +* MACTX_IDLE_WD_TO_TH[31..24] - (RW) Watchdog timeout threshold for MACTX FSM +* not returning to IDLE +*/ +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_MACTX_IDLE_WD_TO_TH_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_CTRL_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_MACTX_IDLE_WD_TO_TH_MASK \ + 0xFF000000 /* MACTX_IDLE_WD_TO_TH[31..24] */ +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_MACTX_IDLE_WD_TO_TH_SHFT 24 +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_PORT_IDLE_WD_TO_TH_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_CTRL_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_PORT_IDLE_WD_TO_TH_MASK \ + 0x00FF0000 /* PORT_IDLE_WD_TO_TH[23..16] */ +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_PORT_IDLE_WD_TO_TH_SHFT 16 +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_PL_IDLE_WD_TO_TH_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_CTRL_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_PL_IDLE_WD_TO_TH_MASK \ + 0x0000FF00 /* PL_IDLE_WD_TO_TH[15..8] */ +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_PL_IDLE_WD_TO_TH_SHFT 8 +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_FL_IDLE_WD_TO_TH_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_CTRL_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_FL_IDLE_WD_TO_TH_MASK \ + 0x000000FF /* FL_IDLE_WD_TO_TH[7..0] */ +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_FL_IDLE_WD_TO_TH_SHFT 0 + +/* +* ---FSM_IDLE_WD_EN (0x820C0000 + 0xd4)--- +* EN_FL_IDLE_WD_TO[0] - (RW) Enables watchdog for frame link FSM not +* returning to IDLE +* EN_PL_IDLE_WD_TO[1] - (RW) Enables watchdog for page link FSM not +* returning to IDLE +* EN_CPU_PORT_IDLE_WD_TO[2] - (RW) Enables watchdog for CPU port oper FSM +* not returning to IDLE +* EN_HIF_PORT_IDLE_WD_TO[3] - (RW) Enables watchdog for HIF port oper FSM +* not returning to IDLE +* EN_LMAC_PORT_IDLE_WD_TO[4] - (RW) Enables watchdog for LMAC port oper FSM +* not returning to IDLE +* EN_AMSDU_PORT_IDLE_WD_TO[5] - (RW) Enables watchdog for AMSDU port FSM not +* returning to IDLE +* EN_HW_AMSDU_IDLE_WD_TO[6] - (RW) Enables watchdog for HW AMSDU FSM not +* returning to IDLE +* RESERVED7[7] - (RO) Reserved bits +* EN_MACTX0_IDLE_WD_TO[8] - (RW) Enables watchdog for MACTX 0 FSM not +* returning to IDLE +* EN_MACTX2_IDLE_WD_TO[9] - (RW) Enables watchdog for MACTX 1 FSM not +* returning to IDLE +* EN_MACTX1_IDLE_WD_TO[10] - (RW) Enables watchdog for MACTX 2 FSM not +* returning to IDLE +* EN_MACTX3_IDLE_WD_TO[11] - (RW) Enables watchdog for MACTX 3 FSM not +* returning to IDLE +* EN_MDP_IDLE_WD_TO[12] - (RW) Enables watchdog for MDP port oper FSM +* not returning to IDLE +* EN_PREDL_ARB_IDLE_WD_TO[13] - (RW) Enables watchdog for Predl arbitrator +* FSM not returning to IDLE +* EN_PREDL_TXCMD_IDLE_WD_TO[14] - (RW) Enables watchdog for Predl TXCMD parser +* FSM not returning to IDLE +* RESERVED15[31..15] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_PREDL_TXCMD_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_PREDL_TXCMD_IDLE_WD_TO_MASK \ + 0x00004000 /* EN_PREDL_TXCMD_IDLE_WD_TO[14] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_PREDL_TXCMD_IDLE_WD_TO_SHFT 14 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_PREDL_ARB_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_PREDL_ARB_IDLE_WD_TO_MASK \ + 0x00002000 /* EN_PREDL_ARB_IDLE_WD_TO[13] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_PREDL_ARB_IDLE_WD_TO_SHFT 13 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MDP_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MDP_IDLE_WD_TO_MASK \ + 0x00001000 /* EN_MDP_IDLE_WD_TO[12] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MDP_IDLE_WD_TO_SHFT 12 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MACTX3_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MACTX3_IDLE_WD_TO_MASK \ + 0x00000800 /* EN_MACTX3_IDLE_WD_TO[11] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MACTX3_IDLE_WD_TO_SHFT 11 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MACTX1_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MACTX1_IDLE_WD_TO_MASK \ + 0x00000400 /* EN_MACTX1_IDLE_WD_TO[10] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MACTX1_IDLE_WD_TO_SHFT 10 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MACTX2_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MACTX2_IDLE_WD_TO_MASK \ + 0x00000200 /* EN_MACTX2_IDLE_WD_TO[9] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MACTX2_IDLE_WD_TO_SHFT 9 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MACTX0_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MACTX0_IDLE_WD_TO_MASK \ + 0x00000100 /* EN_MACTX0_IDLE_WD_TO[8] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MACTX0_IDLE_WD_TO_SHFT 8 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_HW_AMSDU_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_HW_AMSDU_IDLE_WD_TO_MASK \ + 0x00000040 /* EN_HW_AMSDU_IDLE_WD_TO[6] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_HW_AMSDU_IDLE_WD_TO_SHFT 6 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_AMSDU_PORT_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_AMSDU_PORT_IDLE_WD_TO_MASK \ + 0x00000020 /* EN_AMSDU_PORT_IDLE_WD_TO[5] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_AMSDU_PORT_IDLE_WD_TO_SHFT 5 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_LMAC_PORT_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_LMAC_PORT_IDLE_WD_TO_MASK \ + 0x00000010 /* EN_LMAC_PORT_IDLE_WD_TO[4] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_LMAC_PORT_IDLE_WD_TO_SHFT 4 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_HIF_PORT_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_HIF_PORT_IDLE_WD_TO_MASK \ + 0x00000008 /* EN_HIF_PORT_IDLE_WD_TO[3] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_HIF_PORT_IDLE_WD_TO_SHFT 3 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_CPU_PORT_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_CPU_PORT_IDLE_WD_TO_MASK \ + 0x00000004 /* EN_CPU_PORT_IDLE_WD_TO[2] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_CPU_PORT_IDLE_WD_TO_SHFT 2 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_PL_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_PL_IDLE_WD_TO_MASK \ + 0x00000002 /* EN_PL_IDLE_WD_TO[1] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_PL_IDLE_WD_TO_SHFT 1 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_FL_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_FL_IDLE_WD_TO_MASK \ + 0x00000001 /* EN_FL_IDLE_WD_TO[0] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_FL_IDLE_WD_TO_SHFT 0 + +/* +* ---FSM_IDLE_WD_CTRL_1 (0x820C0000 + 0xd8)--- +* MDP_IDLE_WD_TO_TH[7..0] - (RW) Watchdog timeout threshold for MDP FSM +* not returning to IDLE +* (Including MDP TDP/RDP/TIOC/RIOC) +* PF_IDLE_WD_TO_TH[15..8] - (RW) Watchdog timeout threshold for PF FSM +* not returning to IDLE +* SEC_IDLE_WD_TO_TH[23..16] - (RW) Watchdog timeout threshold for SEC FSM +* not returning to IDLE +* (Including SEC0/SEC1) +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_1_SEC_IDLE_WD_TO_TH_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_CTRL_1_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_1_SEC_IDLE_WD_TO_TH_MASK \ + 0x00FF0000 /* SEC_IDLE_WD_TO_TH[23..16] */ +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_1_SEC_IDLE_WD_TO_TH_SHFT 16 +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_1_PF_IDLE_WD_TO_TH_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_CTRL_1_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_1_PF_IDLE_WD_TO_TH_MASK \ + 0x0000FF00 /* PF_IDLE_WD_TO_TH[15..8] */ +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_1_PF_IDLE_WD_TO_TH_SHFT 8 +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_1_MDP_IDLE_WD_TO_TH_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_CTRL_1_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_1_MDP_IDLE_WD_TO_TH_MASK \ + 0x000000FF /* MDP_IDLE_WD_TO_TH[7..0] */ +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_1_MDP_IDLE_WD_TO_TH_SHFT 0 + +/* +* ---FSM_IDLE_WD_EN_1 (0x820C0000 + 0xdc)--- +* EN_BN0_MDP_TDP_IDLE_WD_TO[0] - (RW) Enables watchdog for Band0 MDP TDP FSM +* not returning to IDLE +* EN_MDP_RDP_IDLE_WD_TO[1] - (RW) Enables watchdog for MDP RDP FSM not +* returning to IDLE +* EN_BN0_MDP_TIOC_IDLE_WD_TO[2] - (RW) Enables watchdog for Band0 MDP TIOC FSM +* not returning to IDLE +* EN_BN0_MDP_RIOC_IDLE_WD_TO[3] - (RW) Enables watchdog for Band0 MDP RIOC FSM +* not returning to IDLE +* EN_PF_IDLE_WD_TO[4] - (RW) Enables watchdog for PF FSM not +* returning to IDLE +* EN_SEC0_IDLE_WD_TO[5] - (RW) Enables watchdog for SEC0 FSM not +* returning to IDLE +* EN_SEC1_IDLE_WD_TO[6] - (RW) Enables watchdog for SEC1 FSM not +* returning to IDLE +* EN_BN1_MDP_TDP_IDLE_WD_TO[7] - (RW) Enables watchdog for Band1 MDP TDP FSM +* not returning to IDLE +* EN_BN1_MDP_TIOC_IDLE_WD_TO[8] - (RW) Enables watchdog for Band1 MDP TIOC FSM +* not returning to IDLE +* EN_BN1_MDP_RIOC_IDLE_WD_TO[9] - (RW) Enables watchdog for Band1 MDP RIOC FSM +* not returning to IDLE +* RESERVED10[31..10] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN1_MDP_RIOC_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_1_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN1_MDP_RIOC_IDLE_WD_TO_MASK \ + 0x00000200 /* EN_BN1_MDP_RIOC_IDLE_WD_TO[9] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN1_MDP_RIOC_IDLE_WD_TO_SHFT 9 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN1_MDP_TIOC_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_1_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN1_MDP_TIOC_IDLE_WD_TO_MASK \ + 0x00000100 /* EN_BN1_MDP_TIOC_IDLE_WD_TO[8] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN1_MDP_TIOC_IDLE_WD_TO_SHFT 8 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN1_MDP_TDP_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_1_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN1_MDP_TDP_IDLE_WD_TO_MASK \ + 0x00000080 /* EN_BN1_MDP_TDP_IDLE_WD_TO[7] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN1_MDP_TDP_IDLE_WD_TO_SHFT 7 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_SEC1_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_1_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_SEC1_IDLE_WD_TO_MASK \ + 0x00000040 /* EN_SEC1_IDLE_WD_TO[6] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_SEC1_IDLE_WD_TO_SHFT 6 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_SEC0_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_1_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_SEC0_IDLE_WD_TO_MASK \ + 0x00000020 /* EN_SEC0_IDLE_WD_TO[5] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_SEC0_IDLE_WD_TO_SHFT 5 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_PF_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_1_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_PF_IDLE_WD_TO_MASK \ + 0x00000010 /* EN_PF_IDLE_WD_TO[4] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_PF_IDLE_WD_TO_SHFT 4 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN0_MDP_RIOC_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_1_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN0_MDP_RIOC_IDLE_WD_TO_MASK \ + 0x00000008 /* EN_BN0_MDP_RIOC_IDLE_WD_TO[3] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN0_MDP_RIOC_IDLE_WD_TO_SHFT 3 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN0_MDP_TIOC_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_1_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN0_MDP_TIOC_IDLE_WD_TO_MASK \ + 0x00000004 /* EN_BN0_MDP_TIOC_IDLE_WD_TO[2] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN0_MDP_TIOC_IDLE_WD_TO_SHFT 2 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_MDP_RDP_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_1_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_MDP_RDP_IDLE_WD_TO_MASK \ + 0x00000002 /* EN_MDP_RDP_IDLE_WD_TO[1] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_MDP_RDP_IDLE_WD_TO_SHFT 1 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN0_MDP_TDP_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_1_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN0_MDP_TDP_IDLE_WD_TO_MASK \ + 0x00000001 /* EN_BN0_MDP_TDP_IDLE_WD_TO[0] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN0_MDP_TDP_IDLE_WD_TO_SHFT 0 + +/* +* ---ERLY_TRM_CTRL0 (0x820C0000 + 0xf8)--- +* ERLY_TRM_EN[0] - (RW) Enable control of early terminate +function +* RESERVED1[7..1] - (RO) Reserved bits +* ERLY_TRM_MPDU_TH_0[15..8] - (RW) MPDU number Threshold for TX Bit Rate <= +97.5Mbps +* ERLY_TRM_MPDU_TH_1[23..16] - (RW) MPDU number Threshold for 97.5Mbps < TX +* Bit Rate <= 195Mbps +* ERLY_TRM_MPDU_TH_2[31..24] - (RW) MPDU number Threshold for TX Bit Rate <= +97.5Mbps +*/ +#define WF_PLE_TOP_ERLY_TRM_CTRL0_ERLY_TRM_MPDU_TH_2_ADDR \ + WF_PLE_TOP_ERLY_TRM_CTRL0_ADDR +#define WF_PLE_TOP_ERLY_TRM_CTRL0_ERLY_TRM_MPDU_TH_2_MASK \ + 0xFF000000 /* ERLY_TRM_MPDU_TH_2[31..24] */ +#define WF_PLE_TOP_ERLY_TRM_CTRL0_ERLY_TRM_MPDU_TH_2_SHFT 24 +#define WF_PLE_TOP_ERLY_TRM_CTRL0_ERLY_TRM_MPDU_TH_1_ADDR \ + WF_PLE_TOP_ERLY_TRM_CTRL0_ADDR +#define WF_PLE_TOP_ERLY_TRM_CTRL0_ERLY_TRM_MPDU_TH_1_MASK \ + 0x00FF0000 /* ERLY_TRM_MPDU_TH_1[23..16] */ +#define WF_PLE_TOP_ERLY_TRM_CTRL0_ERLY_TRM_MPDU_TH_1_SHFT 16 +#define WF_PLE_TOP_ERLY_TRM_CTRL0_ERLY_TRM_MPDU_TH_0_ADDR \ + WF_PLE_TOP_ERLY_TRM_CTRL0_ADDR +#define WF_PLE_TOP_ERLY_TRM_CTRL0_ERLY_TRM_MPDU_TH_0_MASK \ + 0x0000FF00 /* ERLY_TRM_MPDU_TH_0[15..8] */ +#define WF_PLE_TOP_ERLY_TRM_CTRL0_ERLY_TRM_MPDU_TH_0_SHFT 8 +#define WF_PLE_TOP_ERLY_TRM_CTRL0_ERLY_TRM_EN_ADDR \ + WF_PLE_TOP_ERLY_TRM_CTRL0_ADDR +#define WF_PLE_TOP_ERLY_TRM_CTRL0_ERLY_TRM_EN_MASK \ + 0x00000001 /* ERLY_TRM_EN[0] */ +#define WF_PLE_TOP_ERLY_TRM_CTRL0_ERLY_TRM_EN_SHFT 0 + +/* +* ---ERLY_TRM_CTRL1 (0x820C0000 + 0xfc)--- +* ERLY_TRM_MPDU_TH_3[7..0] - (RW) MPDU number Threshold for 325Mbps < TX +* Bit Rate <= 433Mbps +* ERLY_TRM_MPDU_TH_4[15..8] - (RW) MPDU number Threshold for 433Mbps < TX +* Bit Rate <= 866.7Mbps +* ERLY_TRM_MPDU_TH_5[23..16] - (RW) MPDU number Threshold for 866.7Mbps < TX +* Bit Rate <= 1300Mbps +* ERLY_TRM_MPDU_TH_6[31..24] - (RW) MPDU number Threshold for TX Bit Rate <= +97.5Mbps +*/ +#define WF_PLE_TOP_ERLY_TRM_CTRL1_ERLY_TRM_MPDU_TH_6_ADDR \ + WF_PLE_TOP_ERLY_TRM_CTRL1_ADDR +#define WF_PLE_TOP_ERLY_TRM_CTRL1_ERLY_TRM_MPDU_TH_6_MASK \ + 0xFF000000 /* ERLY_TRM_MPDU_TH_6[31..24] */ +#define WF_PLE_TOP_ERLY_TRM_CTRL1_ERLY_TRM_MPDU_TH_6_SHFT 24 +#define WF_PLE_TOP_ERLY_TRM_CTRL1_ERLY_TRM_MPDU_TH_5_ADDR \ + WF_PLE_TOP_ERLY_TRM_CTRL1_ADDR +#define WF_PLE_TOP_ERLY_TRM_CTRL1_ERLY_TRM_MPDU_TH_5_MASK \ + 0x00FF0000 /* ERLY_TRM_MPDU_TH_5[23..16] */ +#define WF_PLE_TOP_ERLY_TRM_CTRL1_ERLY_TRM_MPDU_TH_5_SHFT 16 +#define WF_PLE_TOP_ERLY_TRM_CTRL1_ERLY_TRM_MPDU_TH_4_ADDR \ + WF_PLE_TOP_ERLY_TRM_CTRL1_ADDR +#define WF_PLE_TOP_ERLY_TRM_CTRL1_ERLY_TRM_MPDU_TH_4_MASK \ + 0x0000FF00 /* ERLY_TRM_MPDU_TH_4[15..8] */ +#define WF_PLE_TOP_ERLY_TRM_CTRL1_ERLY_TRM_MPDU_TH_4_SHFT 8 +#define WF_PLE_TOP_ERLY_TRM_CTRL1_ERLY_TRM_MPDU_TH_3_ADDR \ + WF_PLE_TOP_ERLY_TRM_CTRL1_ADDR +#define WF_PLE_TOP_ERLY_TRM_CTRL1_ERLY_TRM_MPDU_TH_3_MASK \ + 0x000000FF /* ERLY_TRM_MPDU_TH_3[7..0] */ +#define WF_PLE_TOP_ERLY_TRM_CTRL1_ERLY_TRM_MPDU_TH_3_SHFT 0 + +/* +* ---STATION_PAUSE0 (0x820C0000 + 0x100)--- +* STATION_PAUSE_0[31..0] - (RW) SW can stop station TX by this setting +* for STA0~STA31. +*/ +#define WF_PLE_TOP_STATION_PAUSE0_STATION_PAUSE_0_ADDR \ + WF_PLE_TOP_STATION_PAUSE0_ADDR +#define WF_PLE_TOP_STATION_PAUSE0_STATION_PAUSE_0_MASK \ + 0xFFFFFFFF /* STATION_PAUSE_0[31..0] */ +#define WF_PLE_TOP_STATION_PAUSE0_STATION_PAUSE_0_SHFT 0 + +/* +* ---STATION_PAUSE1 (0x820C0000 + 0x104)--- +* STATION_PAUSE_1[31..0] - (RW) SW can stop station TX by this setting +* for STA32~STA63. +*/ +#define WF_PLE_TOP_STATION_PAUSE1_STATION_PAUSE_1_ADDR \ + WF_PLE_TOP_STATION_PAUSE1_ADDR +#define WF_PLE_TOP_STATION_PAUSE1_STATION_PAUSE_1_MASK \ + 0xFFFFFFFF /* STATION_PAUSE_1[31..0] */ +#define WF_PLE_TOP_STATION_PAUSE1_STATION_PAUSE_1_SHFT 0 + +/* +* ---DIS_STA_MAP0 (0x820C0000 + 0x140)--- +* DIS_STA_MAP_0[31..0] - (RW) Disable map for STA 0~31 TX +*/ +#define WF_PLE_TOP_DIS_STA_MAP0_DIS_STA_MAP_0_ADDR WF_PLE_TOP_DIS_STA_MAP0_ADDR +#define WF_PLE_TOP_DIS_STA_MAP0_DIS_STA_MAP_0_MASK \ + 0xFFFFFFFF /* DIS_STA_MAP_0[31..0] */ +#define WF_PLE_TOP_DIS_STA_MAP0_DIS_STA_MAP_0_SHFT 0 + +/* +* ---DIS_STA_MAP1 (0x820C0000 + 0x144)--- +* DIS_STA_MAP_1[31..0] - (RW) Disable map for STA 32~63 TX +*/ +#define WF_PLE_TOP_DIS_STA_MAP1_DIS_STA_MAP_1_ADDR WF_PLE_TOP_DIS_STA_MAP1_ADDR +#define WF_PLE_TOP_DIS_STA_MAP1_DIS_STA_MAP_1_MASK \ + 0xFFFFFFFF /* DIS_STA_MAP_1[31..0] */ +#define WF_PLE_TOP_DIS_STA_MAP1_DIS_STA_MAP_1_SHFT 0 + +/* +* ---STATION_REDIR0 (0x820C0000 + 0x180)--- +* STATION_REDIR_0[31..0] - (RW) SW can redirection to designed +* port/queue by this setting for STA0~STA31. +*/ +#define WF_PLE_TOP_STATION_REDIR0_STATION_REDIR_0_ADDR \ + WF_PLE_TOP_STATION_REDIR0_ADDR +#define WF_PLE_TOP_STATION_REDIR0_STATION_REDIR_0_MASK \ + 0xFFFFFFFF /* STATION_REDIR_0[31..0] */ +#define WF_PLE_TOP_STATION_REDIR0_STATION_REDIR_0_SHFT 0 + +/* +* ---STATION_REDIR1 (0x820C0000 + 0x184)--- +* STATION_REDIR_1[31..0] - (RW) SW can redirection to designed +* port/queue by this setting for STA32~STA63. +*/ +#define WF_PLE_TOP_STATION_REDIR1_STATION_REDIR_1_ADDR \ + WF_PLE_TOP_STATION_REDIR1_ADDR +#define WF_PLE_TOP_STATION_REDIR1_STATION_REDIR_1_MASK \ + 0xFFFFFFFF /* STATION_REDIR_1[31..0] */ +#define WF_PLE_TOP_STATION_REDIR1_STATION_REDIR_1_SHFT 0 + +/* +* ---TWT_STA_MAP0 (0x820C0000 + 0x1C0)--- +* TWT_STA_MAP_0[31..0] - (RW) TWT map for STA 0~31 TX +*/ +#define WF_PLE_TOP_TWT_STA_MAP0_TWT_STA_MAP_0_ADDR WF_PLE_TOP_TWT_STA_MAP0_ADDR +#define WF_PLE_TOP_TWT_STA_MAP0_TWT_STA_MAP_0_MASK \ + 0xFFFFFFFF /* TWT_STA_MAP_0[31..0] */ +#define WF_PLE_TOP_TWT_STA_MAP0_TWT_STA_MAP_0_SHFT 0 + +/* +* ---TWT_STA_MAP1 (0x820C0000 + 0x1C4)--- +* TWT_STA_MAP_1[31..0] - (RW) TWT map for STA 32~63 TX +*/ +#define WF_PLE_TOP_TWT_STA_MAP1_TWT_STA_MAP_1_ADDR WF_PLE_TOP_TWT_STA_MAP1_ADDR +#define WF_PLE_TOP_TWT_STA_MAP1_TWT_STA_MAP_1_MASK \ + 0xFFFFFFFF /* TWT_STA_MAP_1[31..0] */ +#define WF_PLE_TOP_TWT_STA_MAP1_TWT_STA_MAP_1_SHFT 0 + +/* +* ---TWT_TX_CTRL0 (0x820C0000 + 0x200)--- +* en_twt_stop_tx_ctrl_0[0] - (RW) Enable TWT non-active period TX control +function. +* en_twt_stop_tx_ctrl_1[1] - (RW) Enable TWT non-active period TX control +function. +* en_twt_stop_tx_ctrl_2[2] - (RW) Enable TWT non-active period TX control +function. +* en_twt_stop_tx_ctrl_3[3] - (RW) Enable TWT non-active period TX control +function. +* RESERVED4[31..4] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_TWT_TX_CTRL0_en_twt_stop_tx_ctrl_3_ADDR \ + WF_PLE_TOP_TWT_TX_CTRL0_ADDR +#define WF_PLE_TOP_TWT_TX_CTRL0_en_twt_stop_tx_ctrl_3_MASK \ + 0x00000008 /* en_twt_stop_tx_ctrl_3[3] */ +#define WF_PLE_TOP_TWT_TX_CTRL0_en_twt_stop_tx_ctrl_3_SHFT 3 +#define WF_PLE_TOP_TWT_TX_CTRL0_en_twt_stop_tx_ctrl_2_ADDR \ + WF_PLE_TOP_TWT_TX_CTRL0_ADDR +#define WF_PLE_TOP_TWT_TX_CTRL0_en_twt_stop_tx_ctrl_2_MASK \ + 0x00000004 /* en_twt_stop_tx_ctrl_2[2] */ +#define WF_PLE_TOP_TWT_TX_CTRL0_en_twt_stop_tx_ctrl_2_SHFT 2 +#define WF_PLE_TOP_TWT_TX_CTRL0_en_twt_stop_tx_ctrl_1_ADDR \ + WF_PLE_TOP_TWT_TX_CTRL0_ADDR +#define WF_PLE_TOP_TWT_TX_CTRL0_en_twt_stop_tx_ctrl_1_MASK \ + 0x00000002 /* en_twt_stop_tx_ctrl_1[1] */ +#define WF_PLE_TOP_TWT_TX_CTRL0_en_twt_stop_tx_ctrl_1_SHFT 1 +#define WF_PLE_TOP_TWT_TX_CTRL0_en_twt_stop_tx_ctrl_0_ADDR \ + WF_PLE_TOP_TWT_TX_CTRL0_ADDR +#define WF_PLE_TOP_TWT_TX_CTRL0_en_twt_stop_tx_ctrl_0_MASK \ + 0x00000001 /* en_twt_stop_tx_ctrl_0[0] */ +#define WF_PLE_TOP_TWT_TX_CTRL0_en_twt_stop_tx_ctrl_0_SHFT 0 + +/* +* ---DRR_SPL_CTRL (0x820C0000 + 0x204)--- +* RESERVED0[15..0] - (RO) Reserved bits +* SUBRND_TIMES[19..16] - (RW) Subround times setting to trigger round +end +* EN_SBTG_RNDEND[20] - (RW) Enable control of round ends by subround +times +* EN_QLEN_TH[21] - (RW) Enable control of queue length +* constraint to select station +* RESERVED22[31..22] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_DRR_SPL_CTRL_EN_QLEN_TH_ADDR WF_PLE_TOP_DRR_SPL_CTRL_ADDR +#define WF_PLE_TOP_DRR_SPL_CTRL_EN_QLEN_TH_MASK 0x00200000 /* EN_QLEN_TH[21] */ +#define WF_PLE_TOP_DRR_SPL_CTRL_EN_QLEN_TH_SHFT 21 +#define WF_PLE_TOP_DRR_SPL_CTRL_EN_SBTG_RNDEND_ADDR WF_PLE_TOP_DRR_SPL_CTRL_ADDR +#define WF_PLE_TOP_DRR_SPL_CTRL_EN_SBTG_RNDEND_MASK \ + 0x00100000 /* EN_SBTG_RNDEND[20] */ +#define WF_PLE_TOP_DRR_SPL_CTRL_EN_SBTG_RNDEND_SHFT 20 +#define WF_PLE_TOP_DRR_SPL_CTRL_SUBRND_TIMES_ADDR WF_PLE_TOP_DRR_SPL_CTRL_ADDR +#define WF_PLE_TOP_DRR_SPL_CTRL_SUBRND_TIMES_MASK \ + 0x000F0000 /* SUBRND_TIMES[19..16] */ +#define WF_PLE_TOP_DRR_SPL_CTRL_SUBRND_TIMES_SHFT 16 + +/* +* ---BSS_DBDC_CTRL (0x820C0000 + 0x208)--- +* BSS_BAND_SEL[15..0] - (RW) Select band of each BSS +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_BSS_DBDC_CTRL_BSS_BAND_SEL_ADDR WF_PLE_TOP_BSS_DBDC_CTRL_ADDR +#define WF_PLE_TOP_BSS_DBDC_CTRL_BSS_BAND_SEL_MASK \ + 0x0000FFFF /* BSS_BAND_SEL[15..0] */ +#define WF_PLE_TOP_BSS_DBDC_CTRL_BSS_BAND_SEL_SHFT 0 + +/* +* ---VOW_CTRL1 (0x820C0000 + 0x20c)--- +* RESERVED0[0] - (RO) Reserved bits +* EN_BSSID_CHECK[1] - (RW) Enable control of check BSSID's trap +* state in search station +* EN_LOCK_STA[2] - (RW) Lock mode for RTS retry same sta until +* RTS drop +* EN_KEEP_QTM[3] - (RW) Not reset remain Tx time when sta has +* new packet +* EN_TXCNT_MODE[4] - (RW) Tx count weighted round robin control +* EN_TXED_MODE[5] - (RW) Txed bitmap control +* EN_RXSCH_MODE[6] - (RW) Rx scheduling with rx earlyend bitmap +control +* EN_BWRF_SRCH[7] - (RW) Bandwidth refill search control +* DIS_BSSID0_TRAP_IGNORE[8] - (RW) Disable control of the function that STA +* with BSSID0 trap ignore in TXQ busy +* DIS_BSSID1_TRAP_IGNORE[9] - (RW) Disable control of the function that STA +* with BSSID1 trap ignore in TXQ busy +* DIS_BSSID2_TRAP_IGNORE[10] - (RW) Disable control of the function that STA +* with BSSID2 trap ignore in TXQ busy +* DIS_BSSID3_TRAP_IGNORE[11] - (RW) Disable control of the function that STA +* with BSSID3 trap ignore in TXQ busy +* DIS_KEEP_TRGT_BSS[12] - (RW) Disable control of keeping BSS as target +* station when SPL search +* RESERVED13[31..13] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_VOW_CTRL1_DIS_KEEP_TRGT_BSS_ADDR WF_PLE_TOP_VOW_CTRL1_ADDR +#define WF_PLE_TOP_VOW_CTRL1_DIS_KEEP_TRGT_BSS_MASK \ + 0x00001000 /* DIS_KEEP_TRGT_BSS[12] */ +#define WF_PLE_TOP_VOW_CTRL1_DIS_KEEP_TRGT_BSS_SHFT 12 +#define WF_PLE_TOP_VOW_CTRL1_DIS_BSSID3_TRAP_IGNORE_ADDR \ + WF_PLE_TOP_VOW_CTRL1_ADDR +#define WF_PLE_TOP_VOW_CTRL1_DIS_BSSID3_TRAP_IGNORE_MASK \ + 0x00000800 /* DIS_BSSID3_TRAP_IGNORE[11] */ +#define WF_PLE_TOP_VOW_CTRL1_DIS_BSSID3_TRAP_IGNORE_SHFT 11 +#define WF_PLE_TOP_VOW_CTRL1_DIS_BSSID2_TRAP_IGNORE_ADDR \ + WF_PLE_TOP_VOW_CTRL1_ADDR +#define WF_PLE_TOP_VOW_CTRL1_DIS_BSSID2_TRAP_IGNORE_MASK \ + 0x00000400 /* DIS_BSSID2_TRAP_IGNORE[10] */ +#define WF_PLE_TOP_VOW_CTRL1_DIS_BSSID2_TRAP_IGNORE_SHFT 10 +#define WF_PLE_TOP_VOW_CTRL1_DIS_BSSID1_TRAP_IGNORE_ADDR \ + WF_PLE_TOP_VOW_CTRL1_ADDR +#define WF_PLE_TOP_VOW_CTRL1_DIS_BSSID1_TRAP_IGNORE_MASK \ + 0x00000200 /* DIS_BSSID1_TRAP_IGNORE[9] */ +#define WF_PLE_TOP_VOW_CTRL1_DIS_BSSID1_TRAP_IGNORE_SHFT 9 +#define WF_PLE_TOP_VOW_CTRL1_DIS_BSSID0_TRAP_IGNORE_ADDR \ + WF_PLE_TOP_VOW_CTRL1_ADDR +#define WF_PLE_TOP_VOW_CTRL1_DIS_BSSID0_TRAP_IGNORE_MASK \ + 0x00000100 /* DIS_BSSID0_TRAP_IGNORE[8] */ +#define WF_PLE_TOP_VOW_CTRL1_DIS_BSSID0_TRAP_IGNORE_SHFT 8 +#define WF_PLE_TOP_VOW_CTRL1_EN_BWRF_SRCH_ADDR WF_PLE_TOP_VOW_CTRL1_ADDR +#define WF_PLE_TOP_VOW_CTRL1_EN_BWRF_SRCH_MASK 0x00000080 /* EN_BWRF_SRCH[7] */ +#define WF_PLE_TOP_VOW_CTRL1_EN_BWRF_SRCH_SHFT 7 +#define WF_PLE_TOP_VOW_CTRL1_EN_RXSCH_MODE_ADDR WF_PLE_TOP_VOW_CTRL1_ADDR +#define WF_PLE_TOP_VOW_CTRL1_EN_RXSCH_MODE_MASK \ + 0x00000040 /* EN_RXSCH_MODE[6] */ +#define WF_PLE_TOP_VOW_CTRL1_EN_RXSCH_MODE_SHFT 6 +#define WF_PLE_TOP_VOW_CTRL1_EN_TXED_MODE_ADDR WF_PLE_TOP_VOW_CTRL1_ADDR +#define WF_PLE_TOP_VOW_CTRL1_EN_TXED_MODE_MASK 0x00000020 /* EN_TXED_MODE[5] */ +#define WF_PLE_TOP_VOW_CTRL1_EN_TXED_MODE_SHFT 5 +#define WF_PLE_TOP_VOW_CTRL1_EN_TXCNT_MODE_ADDR WF_PLE_TOP_VOW_CTRL1_ADDR +#define WF_PLE_TOP_VOW_CTRL1_EN_TXCNT_MODE_MASK \ + 0x00000010 /* EN_TXCNT_MODE[4] */ +#define WF_PLE_TOP_VOW_CTRL1_EN_TXCNT_MODE_SHFT 4 +#define WF_PLE_TOP_VOW_CTRL1_EN_KEEP_QTM_ADDR WF_PLE_TOP_VOW_CTRL1_ADDR +#define WF_PLE_TOP_VOW_CTRL1_EN_KEEP_QTM_MASK 0x00000008 /* EN_KEEP_QTM[3] */ +#define WF_PLE_TOP_VOW_CTRL1_EN_KEEP_QTM_SHFT 3 +#define WF_PLE_TOP_VOW_CTRL1_EN_LOCK_STA_ADDR WF_PLE_TOP_VOW_CTRL1_ADDR +#define WF_PLE_TOP_VOW_CTRL1_EN_LOCK_STA_MASK 0x00000004 /* EN_LOCK_STA[2] */ +#define WF_PLE_TOP_VOW_CTRL1_EN_LOCK_STA_SHFT 2 +#define WF_PLE_TOP_VOW_CTRL1_EN_BSSID_CHECK_ADDR WF_PLE_TOP_VOW_CTRL1_ADDR +#define WF_PLE_TOP_VOW_CTRL1_EN_BSSID_CHECK_MASK \ + 0x00000002 /* EN_BSSID_CHECK[1] */ +#define WF_PLE_TOP_VOW_CTRL1_EN_BSSID_CHECK_SHFT 1 + +/* +* ---TWT_STA_TABLE0 (0x820C0000 + 0x210)--- +* TWT_STA_0[9..0] - (RW) TWT station 0 WLAN ID +* RESERVED10[31..10] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_TWT_STA_TABLE0_TWT_STA_0_ADDR WF_PLE_TOP_TWT_STA_TABLE0_ADDR +#define WF_PLE_TOP_TWT_STA_TABLE0_TWT_STA_0_MASK \ + 0x000003FF /* TWT_STA_0[9..0] */ +#define WF_PLE_TOP_TWT_STA_TABLE0_TWT_STA_0_SHFT 0 + +/* +* ---TWT_STA_TABLE1 (0x820C0000 + 0x214)--- +* TWT_STA_2[9..0] - (RW) TWT station 2 WLAN ID +* RESERVED10[31..10] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_TWT_STA_TABLE1_TWT_STA_2_ADDR WF_PLE_TOP_TWT_STA_TABLE1_ADDR +#define WF_PLE_TOP_TWT_STA_TABLE1_TWT_STA_2_MASK \ + 0x000003FF /* TWT_STA_2[9..0] */ +#define WF_PLE_TOP_TWT_STA_TABLE1_TWT_STA_2_SHFT 0 + +/* +* ---TWT_STA_TABLE2 (0x820C0000 + 0x218)--- +* TWT_STA_4[9..0] - (RW) TWT station 4 WLAN ID +* RESERVED10[31..10] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_TWT_STA_TABLE2_TWT_STA_4_ADDR WF_PLE_TOP_TWT_STA_TABLE2_ADDR +#define WF_PLE_TOP_TWT_STA_TABLE2_TWT_STA_4_MASK \ + 0x000003FF /* TWT_STA_4[9..0] */ +#define WF_PLE_TOP_TWT_STA_TABLE2_TWT_STA_4_SHFT 0 + +/* +* ---TWT_STA_TABLE3 (0x820C0000 + 0x21c)--- +* TWT_STA_6[9..0] - (RW) TWT station 6 WLAN ID +* RESERVED10[31..10] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_TWT_STA_TABLE3_TWT_STA_6_ADDR WF_PLE_TOP_TWT_STA_TABLE3_ADDR +#define WF_PLE_TOP_TWT_STA_TABLE3_TWT_STA_6_MASK \ + 0x000003FF /* TWT_STA_6[9..0] */ +#define WF_PLE_TOP_TWT_STA_TABLE3_TWT_STA_6_SHFT 0 + +/* +* ---TWT_SW_CTRL (0x820C0000 + 0x220)--- +* INDEX[15..0] - (RW) Operation index +* Mode 0x00/0x01/0x08/0x09: Bit[3:0]: station +number +* Mode 0x10/0x11: Bit[3:0]: table index +* MODE[23..16] - (RW) IO software command mode +* TWT_STA_FIX_AC_EN[24] - (RW) Enable TWT station fix AC function +* RESERVED25[29..25] - (RO) Reserved bits +* SRCH_CMD_DROP[30] - (W1C) IO search command drop flag due to +* command FIFO full +* RESERVED31[31] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_TWT_SW_CTRL_SRCH_CMD_DROP_ADDR WF_PLE_TOP_TWT_SW_CTRL_ADDR +#define WF_PLE_TOP_TWT_SW_CTRL_SRCH_CMD_DROP_MASK \ + 0x40000000 /* SRCH_CMD_DROP[30] */ +#define WF_PLE_TOP_TWT_SW_CTRL_SRCH_CMD_DROP_SHFT 30 +#define WF_PLE_TOP_TWT_SW_CTRL_TWT_STA_FIX_AC_EN_ADDR \ + WF_PLE_TOP_TWT_SW_CTRL_ADDR +#define WF_PLE_TOP_TWT_SW_CTRL_TWT_STA_FIX_AC_EN_MASK \ + 0x01000000 /* TWT_STA_FIX_AC_EN[24] */ +#define WF_PLE_TOP_TWT_SW_CTRL_TWT_STA_FIX_AC_EN_SHFT 24 +#define WF_PLE_TOP_TWT_SW_CTRL_MODE_ADDR WF_PLE_TOP_TWT_SW_CTRL_ADDR +#define WF_PLE_TOP_TWT_SW_CTRL_MODE_MASK 0x00FF0000 /* MODE[23..16] */ +#define WF_PLE_TOP_TWT_SW_CTRL_MODE_SHFT 16 +#define WF_PLE_TOP_TWT_SW_CTRL_INDEX_ADDR WF_PLE_TOP_TWT_SW_CTRL_ADDR +#define WF_PLE_TOP_TWT_SW_CTRL_INDEX_MASK 0x0000FFFF /* INDEX[15..0] */ +#define WF_PLE_TOP_TWT_SW_CTRL_INDEX_SHFT 0 + +/* +* ---TWT_HW_SRCHCMD_FULL (0x820C0000 + 0x224)--- +* TWT_SRCH_DL_FULL[0] - (RW) TWT hardware downlink search command +* full flag +* RESERVED1[31..1] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_TWT_HW_SRCHCMD_FULL_TWT_SRCH_DL_FULL_ADDR \ + WF_PLE_TOP_TWT_HW_SRCHCMD_FULL_ADDR +#define WF_PLE_TOP_TWT_HW_SRCHCMD_FULL_TWT_SRCH_DL_FULL_MASK \ + 0x00000001 /* TWT_SRCH_DL_FULL[0] */ +#define WF_PLE_TOP_TWT_HW_SRCHCMD_FULL_TWT_SRCH_DL_FULL_SHFT 0 + +/* +* ---DRR_SW_CTRL (0x820C0000 + 0x228)--- +* INDEX[15..0] - (RW) Operation index +* Mode 0x00: Bit[15:12]: QID, Bit[9:0]: wlan +ID +* Mode 0x01: Bit[15:12]: QID, Bit[9:0]: wlan +ID +* Mode 0x10: Bit[3:0]: QID +* Mode 0x11: Bit[3:0]: QID +* MODE[23..16] - (RW) IO software command mode +* RESERVED24[29..24] - (RO) Reserved bits +* SRCH_CMD_DROP[30] - (W1C) IO search command drop flag due to +* command FIFO full +* RESERVED31[31] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_DRR_SW_CTRL_SRCH_CMD_DROP_ADDR WF_PLE_TOP_DRR_SW_CTRL_ADDR +#define WF_PLE_TOP_DRR_SW_CTRL_SRCH_CMD_DROP_MASK \ + 0x40000000 /* SRCH_CMD_DROP[30] */ +#define WF_PLE_TOP_DRR_SW_CTRL_SRCH_CMD_DROP_SHFT 30 +#define WF_PLE_TOP_DRR_SW_CTRL_MODE_ADDR WF_PLE_TOP_DRR_SW_CTRL_ADDR +#define WF_PLE_TOP_DRR_SW_CTRL_MODE_MASK 0x00FF0000 /* MODE[23..16] */ +#define WF_PLE_TOP_DRR_SW_CTRL_MODE_SHFT 16 +#define WF_PLE_TOP_DRR_SW_CTRL_INDEX_ADDR WF_PLE_TOP_DRR_SW_CTRL_ADDR +#define WF_PLE_TOP_DRR_SW_CTRL_INDEX_MASK 0x0000FFFF /* INDEX[15..0] */ +#define WF_PLE_TOP_DRR_SW_CTRL_INDEX_SHFT 0 + +/* +* ---DRR_SPL_CTRL_1 (0x820C0000 + 0x22c)--- +* RESERVED0[16..0] - (RO) Reserved bits +* EN_BWCHRG_ORIG[17] - (RW) BW charge original scheme enable control +* RESERVED18[31..18] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_DRR_SPL_CTRL_1_EN_BWCHRG_ORIG_ADDR \ + WF_PLE_TOP_DRR_SPL_CTRL_1_ADDR +#define WF_PLE_TOP_DRR_SPL_CTRL_1_EN_BWCHRG_ORIG_MASK \ + 0x00020000 /* EN_BWCHRG_ORIG[17] */ +#define WF_PLE_TOP_DRR_SPL_CTRL_1_EN_BWCHRG_ORIG_SHFT 17 + +/* +* ---TWT_STA_FIX_AC (0x820C0000 + 0x234)--- +* DL_TWT_STA0_FIX_AC[1..0] - (RW) DL TWT station 0 fix AC setting +* DL_TWT_STA1_FIX_AC[3..2] - (RW) DL TWT station 1 fix AC setting +* DL_TWT_STA2_FIX_AC[5..4] - (RW) DL TWT station 2 fix AC setting +* DL_TWT_STA3_FIX_AC[7..6] - (RW) DL TWT station 3 fix AC setting +* DL_TWT_STA4_FIX_AC[9..8] - (RW) DL TWT station 4 fix AC setting +* DL_TWT_STA5_FIX_AC[11..10] - (RW) DL TWT station 5 fix AC setting +* DL_TWT_STA6_FIX_AC[13..12] - (RW) DL TWT station 6 fix AC setting +* DL_TWT_STA7_FIX_AC[15..14] - (RW) DL TWT station 7 fix AC setting +* UL_TWT_STA0_FIX_AC[17..16] - (RW) UL TWT station 0 fix AC setting +* UL_TWT_STA1_FIX_AC[19..18] - (RW) UL TWT station 1 fix AC setting +* UL_TWT_STA2_FIX_AC[21..20] - (RW) UL TWT station 2 fix AC setting +* UL_TWT_STA3_FIX_AC[23..22] - (RW) UL TWT station 3 fix AC setting +* UL_TWT_STA4_FIX_AC[25..24] - (RW) UL TWT station 4 fix AC setting +* UL_TWT_STA5_FIX_AC[27..26] - (RW) UL TWT station 5 fix AC setting +* UL_TWT_STA6_FIX_AC[29..28] - (RW) UL TWT station 6 fix AC setting +* RESERVED30[31..30] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_TWT_STA_FIX_AC_UL_TWT_STA6_FIX_AC_ADDR \ + WF_PLE_TOP_TWT_STA_FIX_AC_ADDR +#define WF_PLE_TOP_TWT_STA_FIX_AC_UL_TWT_STA6_FIX_AC_MASK \ + 0x30000000 /* UL_TWT_STA6_FIX_AC[29..28] */ +#define WF_PLE_TOP_TWT_STA_FIX_AC_UL_TWT_STA6_FIX_AC_SHFT 28 +#define WF_PLE_TOP_TWT_STA_FIX_AC_UL_TWT_STA5_FIX_AC_ADDR \ + WF_PLE_TOP_TWT_STA_FIX_AC_ADDR +#define WF_PLE_TOP_TWT_STA_FIX_AC_UL_TWT_STA5_FIX_AC_MASK \ + 0x0C000000 /* UL_TWT_STA5_FIX_AC[27..26] */ +#define WF_PLE_TOP_TWT_STA_FIX_AC_UL_TWT_STA5_FIX_AC_SHFT 26 +#define WF_PLE_TOP_TWT_STA_FIX_AC_UL_TWT_STA4_FIX_AC_ADDR \ + WF_PLE_TOP_TWT_STA_FIX_AC_ADDR +#define WF_PLE_TOP_TWT_STA_FIX_AC_UL_TWT_STA4_FIX_AC_MASK \ + 0x03000000 /* UL_TWT_STA4_FIX_AC[25..24] */ +#define WF_PLE_TOP_TWT_STA_FIX_AC_UL_TWT_STA4_FIX_AC_SHFT 24 +#define WF_PLE_TOP_TWT_STA_FIX_AC_UL_TWT_STA3_FIX_AC_ADDR \ + WF_PLE_TOP_TWT_STA_FIX_AC_ADDR +#define WF_PLE_TOP_TWT_STA_FIX_AC_UL_TWT_STA3_FIX_AC_MASK \ + 0x00C00000 /* UL_TWT_STA3_FIX_AC[23..22] */ +#define WF_PLE_TOP_TWT_STA_FIX_AC_UL_TWT_STA3_FIX_AC_SHFT 22 +#define WF_PLE_TOP_TWT_STA_FIX_AC_UL_TWT_STA2_FIX_AC_ADDR \ + WF_PLE_TOP_TWT_STA_FIX_AC_ADDR +#define WF_PLE_TOP_TWT_STA_FIX_AC_UL_TWT_STA2_FIX_AC_MASK \ + 0x00300000 /* UL_TWT_STA2_FIX_AC[21..20] */ +#define WF_PLE_TOP_TWT_STA_FIX_AC_UL_TWT_STA2_FIX_AC_SHFT 20 +#define WF_PLE_TOP_TWT_STA_FIX_AC_UL_TWT_STA1_FIX_AC_ADDR \ + WF_PLE_TOP_TWT_STA_FIX_AC_ADDR +#define WF_PLE_TOP_TWT_STA_FIX_AC_UL_TWT_STA1_FIX_AC_MASK \ + 0x000C0000 /* UL_TWT_STA1_FIX_AC[19..18] */ +#define WF_PLE_TOP_TWT_STA_FIX_AC_UL_TWT_STA1_FIX_AC_SHFT 18 +#define WF_PLE_TOP_TWT_STA_FIX_AC_UL_TWT_STA0_FIX_AC_ADDR \ + WF_PLE_TOP_TWT_STA_FIX_AC_ADDR +#define WF_PLE_TOP_TWT_STA_FIX_AC_UL_TWT_STA0_FIX_AC_MASK \ + 0x00030000 /* UL_TWT_STA0_FIX_AC[17..16] */ +#define WF_PLE_TOP_TWT_STA_FIX_AC_UL_TWT_STA0_FIX_AC_SHFT 16 +#define WF_PLE_TOP_TWT_STA_FIX_AC_DL_TWT_STA7_FIX_AC_ADDR \ + WF_PLE_TOP_TWT_STA_FIX_AC_ADDR +#define WF_PLE_TOP_TWT_STA_FIX_AC_DL_TWT_STA7_FIX_AC_MASK \ + 0x0000C000 /* DL_TWT_STA7_FIX_AC[15..14] */ +#define WF_PLE_TOP_TWT_STA_FIX_AC_DL_TWT_STA7_FIX_AC_SHFT 14 +#define WF_PLE_TOP_TWT_STA_FIX_AC_DL_TWT_STA6_FIX_AC_ADDR \ + WF_PLE_TOP_TWT_STA_FIX_AC_ADDR +#define WF_PLE_TOP_TWT_STA_FIX_AC_DL_TWT_STA6_FIX_AC_MASK \ + 0x00003000 /* DL_TWT_STA6_FIX_AC[13..12] */ +#define WF_PLE_TOP_TWT_STA_FIX_AC_DL_TWT_STA6_FIX_AC_SHFT 12 +#define WF_PLE_TOP_TWT_STA_FIX_AC_DL_TWT_STA5_FIX_AC_ADDR \ + WF_PLE_TOP_TWT_STA_FIX_AC_ADDR +#define WF_PLE_TOP_TWT_STA_FIX_AC_DL_TWT_STA5_FIX_AC_MASK \ + 0x00000C00 /* DL_TWT_STA5_FIX_AC[11..10] */ +#define WF_PLE_TOP_TWT_STA_FIX_AC_DL_TWT_STA5_FIX_AC_SHFT 10 +#define WF_PLE_TOP_TWT_STA_FIX_AC_DL_TWT_STA4_FIX_AC_ADDR \ + WF_PLE_TOP_TWT_STA_FIX_AC_ADDR +#define WF_PLE_TOP_TWT_STA_FIX_AC_DL_TWT_STA4_FIX_AC_MASK \ + 0x00000300 /* DL_TWT_STA4_FIX_AC[9..8] */ +#define WF_PLE_TOP_TWT_STA_FIX_AC_DL_TWT_STA4_FIX_AC_SHFT 8 +#define WF_PLE_TOP_TWT_STA_FIX_AC_DL_TWT_STA3_FIX_AC_ADDR \ + WF_PLE_TOP_TWT_STA_FIX_AC_ADDR +#define WF_PLE_TOP_TWT_STA_FIX_AC_DL_TWT_STA3_FIX_AC_MASK \ + 0x000000C0 /* DL_TWT_STA3_FIX_AC[7..6] */ +#define WF_PLE_TOP_TWT_STA_FIX_AC_DL_TWT_STA3_FIX_AC_SHFT 6 +#define WF_PLE_TOP_TWT_STA_FIX_AC_DL_TWT_STA2_FIX_AC_ADDR \ + WF_PLE_TOP_TWT_STA_FIX_AC_ADDR +#define WF_PLE_TOP_TWT_STA_FIX_AC_DL_TWT_STA2_FIX_AC_MASK \ + 0x00000030 /* DL_TWT_STA2_FIX_AC[5..4] */ +#define WF_PLE_TOP_TWT_STA_FIX_AC_DL_TWT_STA2_FIX_AC_SHFT 4 +#define WF_PLE_TOP_TWT_STA_FIX_AC_DL_TWT_STA1_FIX_AC_ADDR \ + WF_PLE_TOP_TWT_STA_FIX_AC_ADDR +#define WF_PLE_TOP_TWT_STA_FIX_AC_DL_TWT_STA1_FIX_AC_MASK \ + 0x0000000C /* DL_TWT_STA1_FIX_AC[3..2] */ +#define WF_PLE_TOP_TWT_STA_FIX_AC_DL_TWT_STA1_FIX_AC_SHFT 2 +#define WF_PLE_TOP_TWT_STA_FIX_AC_DL_TWT_STA0_FIX_AC_ADDR \ + WF_PLE_TOP_TWT_STA_FIX_AC_ADDR +#define WF_PLE_TOP_TWT_STA_FIX_AC_DL_TWT_STA0_FIX_AC_MASK \ + 0x00000003 /* DL_TWT_STA0_FIX_AC[1..0] */ +#define WF_PLE_TOP_TWT_STA_FIX_AC_DL_TWT_STA0_FIX_AC_SHFT 0 + +/* +* ---EN_UMAC_L1_DCM (0x820C0000 + 0x238)--- +* UMAC_DCM_KEEP_HIGH_SPEED[0] - (RW) UMAC L1 DCM control +* RESERVED1[22..1] - (RO) Reserved bits +* DCM_IDLE_CNT_DOWN_UNIT[23] - (RW) UMAC L1 DCM idle count down time unit +select. +* DCM_IDLE_CNT_DOWN_VALUE[31..24] - (RW) UMAC L1 DCM idle count down value. +*/ +#define WF_PLE_TOP_EN_UMAC_L1_DCM_DCM_IDLE_CNT_DOWN_VALUE_ADDR \ + WF_PLE_TOP_EN_UMAC_L1_DCM_ADDR +#define WF_PLE_TOP_EN_UMAC_L1_DCM_DCM_IDLE_CNT_DOWN_VALUE_MASK \ + 0xFF000000 /* DCM_IDLE_CNT_DOWN_VALUE[31..24] */ +#define WF_PLE_TOP_EN_UMAC_L1_DCM_DCM_IDLE_CNT_DOWN_VALUE_SHFT 24 +#define WF_PLE_TOP_EN_UMAC_L1_DCM_DCM_IDLE_CNT_DOWN_UNIT_ADDR \ + WF_PLE_TOP_EN_UMAC_L1_DCM_ADDR +#define WF_PLE_TOP_EN_UMAC_L1_DCM_DCM_IDLE_CNT_DOWN_UNIT_MASK \ + 0x00800000 /* DCM_IDLE_CNT_DOWN_UNIT[23] */ +#define WF_PLE_TOP_EN_UMAC_L1_DCM_DCM_IDLE_CNT_DOWN_UNIT_SHFT 23 +#define WF_PLE_TOP_EN_UMAC_L1_DCM_UMAC_DCM_KEEP_HIGH_SPEED_ADDR \ + WF_PLE_TOP_EN_UMAC_L1_DCM_ADDR +#define WF_PLE_TOP_EN_UMAC_L1_DCM_UMAC_DCM_KEEP_HIGH_SPEED_MASK \ + 0x00000001 /* UMAC_DCM_KEEP_HIGH_SPEED[0] */ +#define WF_PLE_TOP_EN_UMAC_L1_DCM_UMAC_DCM_KEEP_HIGH_SPEED_SHFT 0 + +/* +* ---PCIE_POWER_CTRL (0x820C0000 + 0x23c)--- +* DIS_UMAC_PCIE_POWER_CTRL[11..0] - (RW) MAC PCIE power control. +* RESERVED12[30..12] - (RO) Reserved bits +* EN_UMAC_PCIE_POWER_CTRL_GLO[31] - (RW) MAC PCIE power global control. +*/ +#define WF_PLE_TOP_PCIE_POWER_CTRL_EN_UMAC_PCIE_POWER_CTRL_GLO_ADDR \ + WF_PLE_TOP_PCIE_POWER_CTRL_ADDR +#define WF_PLE_TOP_PCIE_POWER_CTRL_EN_UMAC_PCIE_POWER_CTRL_GLO_MASK \ + 0x80000000 /* EN_UMAC_PCIE_POWER_CTRL_GLO[31] */ +#define WF_PLE_TOP_PCIE_POWER_CTRL_EN_UMAC_PCIE_POWER_CTRL_GLO_SHFT 31 +#define WF_PLE_TOP_PCIE_POWER_CTRL_DIS_UMAC_PCIE_POWER_CTRL_ADDR \ + WF_PLE_TOP_PCIE_POWER_CTRL_ADDR +#define WF_PLE_TOP_PCIE_POWER_CTRL_DIS_UMAC_PCIE_POWER_CTRL_MASK \ + 0x00000FFF /* DIS_UMAC_PCIE_POWER_CTRL[11..0] */ +#define WF_PLE_TOP_PCIE_POWER_CTRL_DIS_UMAC_PCIE_POWER_CTRL_SHFT 0 + +/* +* ---TIMEOUT_CTRL (0x820C0000 + 0x280)--- +* RESERVED0[7..0] - (RO) Reserved bits +* HOST_REPORT_TO_CTRL[15..8] - (RW) HOST report timeout control register +* APB_WD_TO_CTRL[23..16] - (RW) APB pready watch dog timeout control +register +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_TIMEOUT_CTRL_APB_WD_TO_CTRL_ADDR WF_PLE_TOP_TIMEOUT_CTRL_ADDR +#define WF_PLE_TOP_TIMEOUT_CTRL_APB_WD_TO_CTRL_MASK \ + 0x00FF0000 /* APB_WD_TO_CTRL[23..16] */ +#define WF_PLE_TOP_TIMEOUT_CTRL_APB_WD_TO_CTRL_SHFT 16 +#define WF_PLE_TOP_TIMEOUT_CTRL_HOST_REPORT_TO_CTRL_ADDR \ + WF_PLE_TOP_TIMEOUT_CTRL_ADDR +#define WF_PLE_TOP_TIMEOUT_CTRL_HOST_REPORT_TO_CTRL_MASK \ + 0x0000FF00 /* HOST_REPORT_TO_CTRL[15..8] */ +#define WF_PLE_TOP_TIMEOUT_CTRL_HOST_REPORT_TO_CTRL_SHFT 8 + +/* +* ---PLE_FUNC_CTRL_0 (0x820C0000 + 0x284)--- +* MACTX_REQ_DEASSERT[0] - (RW) Enable of DeAsser MACTX REQ.(Normal +* operation must be zero.) +* MACTX_ABORT_DEASSERT[1] - (RW) Enable of DeAsser MACTX ABORT.(Normal +* operation must be zero.) +* MPDU_DONE_CNT_IN_NO_TX_REQ[2] - (RW) MPDU done mode for LMAC no TX request +* MPDU_DONE_CNT_IN_NO_ADD[3] - (RW) MPDU done mode for LMAC no add +* ACK_LMAC_NO_FID_ADD[4] - (RW) MACTX ack mode for LMAC no add any fid +* for TX +* RESERVED5[5] - (RO) Reserved bits +* DIS_STA_RLS_TO_1F[6] - (RW) Release port setting of disable STA +function +* RESERVED7[7] - (RO) Reserved bits +* MACTX_REQ_ASSERT[8] - (RW) Enable of Asser MACTX REQ.(Normal +* operation must be zero.) +* MACTX_ABORT_ASSERT[9] - (RW) Enable of Asser MACTX ABORT.(Normal +* operation must be zero.) +* RESERVED10[21..10] - (RO) Reserved bits +* DIS_AUTORATE_TXP_REQ[22] - (RW) Disable auto rate TXP request function +* LATER_PKT_PRE_CUT_1US[23] - (RW) Pre cut 1us air time for later packet. +* TXP_REQ_CNTDOWN_TH[27..24] - (RW) Threshold of air time count down for TXP +request +* TXP_REQ_HSPEED_DL_NUM[29..28] - (RW) Packet number of high speed TXP request +* issue, by pre-cut more micro-second +* TXP_REQ_HSPEED_CUT_US[31..30] - (RW) Number of pre-cut micro-second for high +* speed packet +*/ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_TXP_REQ_HSPEED_CUT_US_ADDR \ + WF_PLE_TOP_PLE_FUNC_CTRL_0_ADDR +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_TXP_REQ_HSPEED_CUT_US_MASK \ + 0xC0000000 /* TXP_REQ_HSPEED_CUT_US[31..30] */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_TXP_REQ_HSPEED_CUT_US_SHFT 30 +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_TXP_REQ_HSPEED_DL_NUM_ADDR \ + WF_PLE_TOP_PLE_FUNC_CTRL_0_ADDR +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_TXP_REQ_HSPEED_DL_NUM_MASK \ + 0x30000000 /* TXP_REQ_HSPEED_DL_NUM[29..28] */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_TXP_REQ_HSPEED_DL_NUM_SHFT 28 +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_TXP_REQ_CNTDOWN_TH_ADDR \ + WF_PLE_TOP_PLE_FUNC_CTRL_0_ADDR +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_TXP_REQ_CNTDOWN_TH_MASK \ + 0x0F000000 /* TXP_REQ_CNTDOWN_TH[27..24] */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_TXP_REQ_CNTDOWN_TH_SHFT 24 +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_LATER_PKT_PRE_CUT_1US_ADDR \ + WF_PLE_TOP_PLE_FUNC_CTRL_0_ADDR +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_LATER_PKT_PRE_CUT_1US_MASK \ + 0x00800000 /* LATER_PKT_PRE_CUT_1US[23] */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_LATER_PKT_PRE_CUT_1US_SHFT 23 +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_DIS_AUTORATE_TXP_REQ_ADDR \ + WF_PLE_TOP_PLE_FUNC_CTRL_0_ADDR +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_DIS_AUTORATE_TXP_REQ_MASK \ + 0x00400000 /* DIS_AUTORATE_TXP_REQ[22] */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_DIS_AUTORATE_TXP_REQ_SHFT 22 +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MACTX_ABORT_ASSERT_ADDR \ + WF_PLE_TOP_PLE_FUNC_CTRL_0_ADDR +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MACTX_ABORT_ASSERT_MASK \ + 0x00000200 /* MACTX_ABORT_ASSERT[9] */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MACTX_ABORT_ASSERT_SHFT 9 +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MACTX_REQ_ASSERT_ADDR \ + WF_PLE_TOP_PLE_FUNC_CTRL_0_ADDR +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MACTX_REQ_ASSERT_MASK \ + 0x00000100 /* MACTX_REQ_ASSERT[8] */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MACTX_REQ_ASSERT_SHFT 8 +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_DIS_STA_RLS_TO_1F_ADDR \ + WF_PLE_TOP_PLE_FUNC_CTRL_0_ADDR +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_DIS_STA_RLS_TO_1F_MASK \ + 0x00000040 /* DIS_STA_RLS_TO_1F[6] */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_DIS_STA_RLS_TO_1F_SHFT 6 +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_ACK_LMAC_NO_FID_ADD_ADDR \ + WF_PLE_TOP_PLE_FUNC_CTRL_0_ADDR +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_ACK_LMAC_NO_FID_ADD_MASK \ + 0x00000010 /* ACK_LMAC_NO_FID_ADD[4] */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_ACK_LMAC_NO_FID_ADD_SHFT 4 +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MPDU_DONE_CNT_IN_NO_ADD_ADDR \ + WF_PLE_TOP_PLE_FUNC_CTRL_0_ADDR +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MPDU_DONE_CNT_IN_NO_ADD_MASK \ + 0x00000008 /* MPDU_DONE_CNT_IN_NO_ADD[3] */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MPDU_DONE_CNT_IN_NO_ADD_SHFT 3 +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MPDU_DONE_CNT_IN_NO_TX_REQ_ADDR \ + WF_PLE_TOP_PLE_FUNC_CTRL_0_ADDR +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MPDU_DONE_CNT_IN_NO_TX_REQ_MASK \ + 0x00000004 /* MPDU_DONE_CNT_IN_NO_TX_REQ[2] */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MPDU_DONE_CNT_IN_NO_TX_REQ_SHFT 2 +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MACTX_ABORT_DEASSERT_ADDR \ + WF_PLE_TOP_PLE_FUNC_CTRL_0_ADDR +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MACTX_ABORT_DEASSERT_MASK \ + 0x00000002 /* MACTX_ABORT_DEASSERT[1] */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MACTX_ABORT_DEASSERT_SHFT 1 +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MACTX_REQ_DEASSERT_ADDR \ + WF_PLE_TOP_PLE_FUNC_CTRL_0_ADDR +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MACTX_REQ_DEASSERT_MASK \ + 0x00000001 /* MACTX_REQ_DEASSERT[0] */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MACTX_REQ_DEASSERT_SHFT 0 + +/* +* ---PLE_FUNC_CTRL_1 (0x820C0000 + 0x288)--- +* RESERVED0[21..0] - (RO) Reserved bits +* PREDL_REQ_NORMAL_PRI[22] - (RW) Pre-download TXP request priority +control +* RESERVED23[31..23] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_PLE_FUNC_CTRL_1_PREDL_REQ_NORMAL_PRI_ADDR \ + WF_PLE_TOP_PLE_FUNC_CTRL_1_ADDR +#define WF_PLE_TOP_PLE_FUNC_CTRL_1_PREDL_REQ_NORMAL_PRI_MASK \ + 0x00400000 /* PREDL_REQ_NORMAL_PRI[22] */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_1_PREDL_REQ_NORMAL_PRI_SHFT 22 + +/* +* ---PORT_SER_CTRL (0x820C0000 + 0x290)--- +* EN_HIF_PORT_ALLOC_BLOCKING[0] - (RW) Enable HIF/AMSDU port allocate +* operation blocking. +* EN_CPU_PORT_ALLOC_BLOCKING[1] - (RW) Enable CPU port allocate operation +blocking. +* EN_WF_PORT_ALLOC_BLOCKING[2] - (RW) Enable LMAC port allocate operation +blocking. +* RESERVED3[7..3] - (RO) Reserved bits +* EN_HIF_PORT_D_OPR_BLOCKING[8] - (RW) Enable HIF/AMSDU/MDP/PREDL port data +* operation blocking. +* EN_CPU_PORT_D_OPR_BLOCKING[9] - (RW) Enable CPU port data operation +blocking. +* EN_WF_PORT_D_OPR_BLOCKING[10] - (RW) Enable LMAC port data operation +blocking. +* RESERVED11[15..11] - (RO) Reserved bits +* EN_HIF_PORT_Q_OPR_BLOCKING[16] - (RW) Enable HIF/AMSDU port queue operation +blocking. +* EN_CPU_PORT_Q_OPR_BLOCKING[17] - (RW) Enable CPU port queue operation +blocking. +* EN_WF_PORT_Q_OPR_BLOCKING[18] - (RW) Enable LMAC port queue operation +blocking. +* RESERVED19[31..19] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_PORT_SER_CTRL_EN_WF_PORT_Q_OPR_BLOCKING_ADDR \ + WF_PLE_TOP_PORT_SER_CTRL_ADDR +#define WF_PLE_TOP_PORT_SER_CTRL_EN_WF_PORT_Q_OPR_BLOCKING_MASK \ + 0x00040000 /* EN_WF_PORT_Q_OPR_BLOCKING[18] */ +#define WF_PLE_TOP_PORT_SER_CTRL_EN_WF_PORT_Q_OPR_BLOCKING_SHFT 18 +#define WF_PLE_TOP_PORT_SER_CTRL_EN_CPU_PORT_Q_OPR_BLOCKING_ADDR \ + WF_PLE_TOP_PORT_SER_CTRL_ADDR +#define WF_PLE_TOP_PORT_SER_CTRL_EN_CPU_PORT_Q_OPR_BLOCKING_MASK \ + 0x00020000 /* EN_CPU_PORT_Q_OPR_BLOCKING[17] */ +#define WF_PLE_TOP_PORT_SER_CTRL_EN_CPU_PORT_Q_OPR_BLOCKING_SHFT 17 +#define WF_PLE_TOP_PORT_SER_CTRL_EN_HIF_PORT_Q_OPR_BLOCKING_ADDR \ + WF_PLE_TOP_PORT_SER_CTRL_ADDR +#define WF_PLE_TOP_PORT_SER_CTRL_EN_HIF_PORT_Q_OPR_BLOCKING_MASK \ + 0x00010000 /* EN_HIF_PORT_Q_OPR_BLOCKING[16] */ +#define WF_PLE_TOP_PORT_SER_CTRL_EN_HIF_PORT_Q_OPR_BLOCKING_SHFT 16 +#define WF_PLE_TOP_PORT_SER_CTRL_EN_WF_PORT_D_OPR_BLOCKING_ADDR \ + WF_PLE_TOP_PORT_SER_CTRL_ADDR +#define WF_PLE_TOP_PORT_SER_CTRL_EN_WF_PORT_D_OPR_BLOCKING_MASK \ + 0x00000400 /* EN_WF_PORT_D_OPR_BLOCKING[10] */ +#define WF_PLE_TOP_PORT_SER_CTRL_EN_WF_PORT_D_OPR_BLOCKING_SHFT 10 +#define WF_PLE_TOP_PORT_SER_CTRL_EN_CPU_PORT_D_OPR_BLOCKING_ADDR \ + WF_PLE_TOP_PORT_SER_CTRL_ADDR +#define WF_PLE_TOP_PORT_SER_CTRL_EN_CPU_PORT_D_OPR_BLOCKING_MASK \ + 0x00000200 /* EN_CPU_PORT_D_OPR_BLOCKING[9] */ +#define WF_PLE_TOP_PORT_SER_CTRL_EN_CPU_PORT_D_OPR_BLOCKING_SHFT 9 +#define WF_PLE_TOP_PORT_SER_CTRL_EN_HIF_PORT_D_OPR_BLOCKING_ADDR \ + WF_PLE_TOP_PORT_SER_CTRL_ADDR +#define WF_PLE_TOP_PORT_SER_CTRL_EN_HIF_PORT_D_OPR_BLOCKING_MASK \ + 0x00000100 /* EN_HIF_PORT_D_OPR_BLOCKING[8] */ +#define WF_PLE_TOP_PORT_SER_CTRL_EN_HIF_PORT_D_OPR_BLOCKING_SHFT 8 +#define WF_PLE_TOP_PORT_SER_CTRL_EN_WF_PORT_ALLOC_BLOCKING_ADDR \ + WF_PLE_TOP_PORT_SER_CTRL_ADDR +#define WF_PLE_TOP_PORT_SER_CTRL_EN_WF_PORT_ALLOC_BLOCKING_MASK \ + 0x00000004 /* EN_WF_PORT_ALLOC_BLOCKING[2] */ +#define WF_PLE_TOP_PORT_SER_CTRL_EN_WF_PORT_ALLOC_BLOCKING_SHFT 2 +#define WF_PLE_TOP_PORT_SER_CTRL_EN_CPU_PORT_ALLOC_BLOCKING_ADDR \ + WF_PLE_TOP_PORT_SER_CTRL_ADDR +#define WF_PLE_TOP_PORT_SER_CTRL_EN_CPU_PORT_ALLOC_BLOCKING_MASK \ + 0x00000002 /* EN_CPU_PORT_ALLOC_BLOCKING[1] */ +#define WF_PLE_TOP_PORT_SER_CTRL_EN_CPU_PORT_ALLOC_BLOCKING_SHFT 1 +#define WF_PLE_TOP_PORT_SER_CTRL_EN_HIF_PORT_ALLOC_BLOCKING_ADDR \ + WF_PLE_TOP_PORT_SER_CTRL_ADDR +#define WF_PLE_TOP_PORT_SER_CTRL_EN_HIF_PORT_ALLOC_BLOCKING_MASK \ + 0x00000001 /* EN_HIF_PORT_ALLOC_BLOCKING[0] */ +#define WF_PLE_TOP_PORT_SER_CTRL_EN_HIF_PORT_ALLOC_BLOCKING_SHFT 0 + +/* +* ---MACTX_SER_CTRL (0x820C0000 + 0x294)--- +* EN_MACTX_G0_BLOCKING[0] - (RW) Enable MACTX group 0 operation +blocking. +* RESERVED1[7..1] - (RO) Reserved bits +* EN_MACTX_G1_BLOCKING[8] - (RW) Enable MACTX group 1 operation +blocking. +* RESERVED9[15..9] - (RO) Reserved bits +* EN_MACTX_G2_BLOCKING[16] - (RW) Enable MACTX group 2 operation blocking. +* RESERVED17[23..17] - (RO) Reserved bits +* EN_MACTX_G3_BLOCKING[24] - (RW) Enable MACTX group 3 operation blocking. +* RESERVED25[31..25] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_MACTX_SER_CTRL_EN_MACTX_G3_BLOCKING_ADDR \ + WF_PLE_TOP_MACTX_SER_CTRL_ADDR +#define WF_PLE_TOP_MACTX_SER_CTRL_EN_MACTX_G3_BLOCKING_MASK \ + 0x01000000 /* EN_MACTX_G3_BLOCKING[24] */ +#define WF_PLE_TOP_MACTX_SER_CTRL_EN_MACTX_G3_BLOCKING_SHFT 24 +#define WF_PLE_TOP_MACTX_SER_CTRL_EN_MACTX_G2_BLOCKING_ADDR \ + WF_PLE_TOP_MACTX_SER_CTRL_ADDR +#define WF_PLE_TOP_MACTX_SER_CTRL_EN_MACTX_G2_BLOCKING_MASK \ + 0x00010000 /* EN_MACTX_G2_BLOCKING[16] */ +#define WF_PLE_TOP_MACTX_SER_CTRL_EN_MACTX_G2_BLOCKING_SHFT 16 +#define WF_PLE_TOP_MACTX_SER_CTRL_EN_MACTX_G1_BLOCKING_ADDR \ + WF_PLE_TOP_MACTX_SER_CTRL_ADDR +#define WF_PLE_TOP_MACTX_SER_CTRL_EN_MACTX_G1_BLOCKING_MASK \ + 0x00000100 /* EN_MACTX_G1_BLOCKING[8] */ +#define WF_PLE_TOP_MACTX_SER_CTRL_EN_MACTX_G1_BLOCKING_SHFT 8 +#define WF_PLE_TOP_MACTX_SER_CTRL_EN_MACTX_G0_BLOCKING_ADDR \ + WF_PLE_TOP_MACTX_SER_CTRL_ADDR +#define WF_PLE_TOP_MACTX_SER_CTRL_EN_MACTX_G0_BLOCKING_MASK \ + 0x00000001 /* EN_MACTX_G0_BLOCKING[0] */ +#define WF_PLE_TOP_MACTX_SER_CTRL_EN_MACTX_G0_BLOCKING_SHFT 0 + +/* +* ---DRR_SER_CTRL (0x820C0000 + 0x298)--- +* EN_DRR_CHARGE_BLOCKING[0] - (RW) Enable DRR charge operation blocking. +* RESERVED1[3..1] - (RO) Reserved bits +* EN_DRR_SRCH_0_BLOCKING[4] - (RW) Enable DRR search 0 operation blocking. +* EN_DRR_SRCH_1_BLOCKING[5] - (RW) Enable DRR search 1 operation blocking. +* RESERVED6[7..6] - (RO) Reserved bits +* EN_DRR_RDG_0_BLOCKING[8] - (RW) Enable DRR RDG 0 operation blocking. +* EN_DRR_RDG_1_BLOCKING[9] - (RW) Enable DRR RDG 1 operation blocking. +* RESERVED10[31..10] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_RDG_1_BLOCKING_ADDR \ + WF_PLE_TOP_DRR_SER_CTRL_ADDR +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_RDG_1_BLOCKING_MASK \ + 0x00000200 /* EN_DRR_RDG_1_BLOCKING[9] */ +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_RDG_1_BLOCKING_SHFT 9 +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_RDG_0_BLOCKING_ADDR \ + WF_PLE_TOP_DRR_SER_CTRL_ADDR +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_RDG_0_BLOCKING_MASK \ + 0x00000100 /* EN_DRR_RDG_0_BLOCKING[8] */ +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_RDG_0_BLOCKING_SHFT 8 +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_SRCH_1_BLOCKING_ADDR \ + WF_PLE_TOP_DRR_SER_CTRL_ADDR +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_SRCH_1_BLOCKING_MASK \ + 0x00000020 /* EN_DRR_SRCH_1_BLOCKING[5] */ +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_SRCH_1_BLOCKING_SHFT 5 +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_SRCH_0_BLOCKING_ADDR \ + WF_PLE_TOP_DRR_SER_CTRL_ADDR +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_SRCH_0_BLOCKING_MASK \ + 0x00000010 /* EN_DRR_SRCH_0_BLOCKING[4] */ +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_SRCH_0_BLOCKING_SHFT 4 +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_CHARGE_BLOCKING_ADDR \ + WF_PLE_TOP_DRR_SER_CTRL_ADDR +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_CHARGE_BLOCKING_MASK \ + 0x00000001 /* EN_DRR_CHARGE_BLOCKING[0] */ +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_CHARGE_BLOCKING_SHFT 0 + +/* +* ---INT_N9_STS (0x820C0000 + 0x300)--- +* CPU_Q0_NE[0] - (W1C) CPU queue 0 not empty interrupt status +* CPU_Q1_NE[1] - (W1C) CPU queue 1 not empty interrupt status +* CPU_Q2_NE[2] - (W1C) CPU queue 2 not empty interrupt status +* CPU_Q3_NE[3] - (W1C) CPU queue 3 not empty interrupt status +* RESERVED4[12..4] - (RO) Reserved bits +* ERROR_INT[13] - (RO) Error condition interrupt status, define +* by 0x28 +* ERROR_INT_1[14] - (RO) Error condition interrupt status 1, +* define by 0xd8 +* AMSDU_ERROR_INT[15] - (RO) HW AMSDU Error condition interrupt +* status, define by 0x1028 +* DATA_TOGGLE[16] - (W1C) Interrupt status of data toggle of N9 +* toggle register (0xf0) +* RESERVED17[17] - (RO) Reserved bits +* UMAC_SYSRAM_OUTRAN_ERROR_INT[18] - (W1C) Interrupt status of UMAC SYSRAM out +* range error +* RESERVED19[19] - (RO) Reserved bits +* AC_NONEMPTY_INT[20] - (W1C) AC queue empty fail interrupt status +* AC_EMPTY_INT[21] - (W1C) AC queue empty raise interrupt status +* AC_ENQ_LMAC_INT[22] - (W1C) AC enqueue interrupt status +* RESERVED23[23] - (RO) Reserved bits +* DBDC0_NONEMPTY_INT[24] - (W1C) DBDC0 queue empty fail interrupt status +* DBDC0_EMPTY_INT[25] - (W1C) DBDC0 queue empty raise interrupt +status +* DBDC0_ENQ_LMAC_INT[26] - (W1C) DBDC0 enqueue interrupt status +* RESERVED27[27] - (RO) Reserved bits +* DBDC1_NONEMPTY_INT[28] - (W1C) DBDC1 queue empty fail interrupt status +* DBDC1_EMPTY_INT[29] - (W1C) DBDC1 queue empty raise interrupt +status +* DBDC1_ENQ_LMAC_INT[30] - (W1C) DBDC1 enqueue interrupt status +* RESERVED31[31] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_INT_N9_STS_DBDC1_ENQ_LMAC_INT_ADDR WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_DBDC1_ENQ_LMAC_INT_MASK \ + 0x40000000 /* DBDC1_ENQ_LMAC_INT[30] */ +#define WF_PLE_TOP_INT_N9_STS_DBDC1_ENQ_LMAC_INT_SHFT 30 +#define WF_PLE_TOP_INT_N9_STS_DBDC1_EMPTY_INT_ADDR WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_DBDC1_EMPTY_INT_MASK \ + 0x20000000 /* DBDC1_EMPTY_INT[29] */ +#define WF_PLE_TOP_INT_N9_STS_DBDC1_EMPTY_INT_SHFT 29 +#define WF_PLE_TOP_INT_N9_STS_DBDC1_NONEMPTY_INT_ADDR WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_DBDC1_NONEMPTY_INT_MASK \ + 0x10000000 /* DBDC1_NONEMPTY_INT[28] */ +#define WF_PLE_TOP_INT_N9_STS_DBDC1_NONEMPTY_INT_SHFT 28 +#define WF_PLE_TOP_INT_N9_STS_DBDC0_ENQ_LMAC_INT_ADDR WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_DBDC0_ENQ_LMAC_INT_MASK \ + 0x04000000 /* DBDC0_ENQ_LMAC_INT[26] */ +#define WF_PLE_TOP_INT_N9_STS_DBDC0_ENQ_LMAC_INT_SHFT 26 +#define WF_PLE_TOP_INT_N9_STS_DBDC0_EMPTY_INT_ADDR WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_DBDC0_EMPTY_INT_MASK \ + 0x02000000 /* DBDC0_EMPTY_INT[25] */ +#define WF_PLE_TOP_INT_N9_STS_DBDC0_EMPTY_INT_SHFT 25 +#define WF_PLE_TOP_INT_N9_STS_DBDC0_NONEMPTY_INT_ADDR WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_DBDC0_NONEMPTY_INT_MASK \ + 0x01000000 /* DBDC0_NONEMPTY_INT[24] */ +#define WF_PLE_TOP_INT_N9_STS_DBDC0_NONEMPTY_INT_SHFT 24 +#define WF_PLE_TOP_INT_N9_STS_AC_ENQ_LMAC_INT_ADDR WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_AC_ENQ_LMAC_INT_MASK \ + 0x00400000 /* AC_ENQ_LMAC_INT[22] */ +#define WF_PLE_TOP_INT_N9_STS_AC_ENQ_LMAC_INT_SHFT 22 +#define WF_PLE_TOP_INT_N9_STS_AC_EMPTY_INT_ADDR WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_AC_EMPTY_INT_MASK \ + 0x00200000 /* AC_EMPTY_INT[21] */ +#define WF_PLE_TOP_INT_N9_STS_AC_EMPTY_INT_SHFT 21 +#define WF_PLE_TOP_INT_N9_STS_AC_NONEMPTY_INT_ADDR WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_AC_NONEMPTY_INT_MASK \ + 0x00100000 /* AC_NONEMPTY_INT[20] */ +#define WF_PLE_TOP_INT_N9_STS_AC_NONEMPTY_INT_SHFT 20 +#define WF_PLE_TOP_INT_N9_STS_UMAC_SYSRAM_OUTRAN_ERROR_INT_ADDR \ + WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_UMAC_SYSRAM_OUTRAN_ERROR_INT_MASK \ + 0x00040000 /* UMAC_SYSRAM_OUTRAN_ERROR_INT[18] */ +#define WF_PLE_TOP_INT_N9_STS_UMAC_SYSRAM_OUTRAN_ERROR_INT_SHFT 18 +#define WF_PLE_TOP_INT_N9_STS_DATA_TOGGLE_ADDR WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_DATA_TOGGLE_MASK 0x00010000 /* DATA_TOGGLE[16] */ +#define WF_PLE_TOP_INT_N9_STS_DATA_TOGGLE_SHFT 16 +#define WF_PLE_TOP_INT_N9_STS_AMSDU_ERROR_INT_ADDR WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_AMSDU_ERROR_INT_MASK \ + 0x00008000 /* AMSDU_ERROR_INT[15] */ +#define WF_PLE_TOP_INT_N9_STS_AMSDU_ERROR_INT_SHFT 15 +#define WF_PLE_TOP_INT_N9_STS_ERROR_INT_1_ADDR WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_ERROR_INT_1_MASK 0x00004000 /* ERROR_INT_1[14] */ +#define WF_PLE_TOP_INT_N9_STS_ERROR_INT_1_SHFT 14 +#define WF_PLE_TOP_INT_N9_STS_ERROR_INT_ADDR WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_ERROR_INT_MASK 0x00002000 /* ERROR_INT[13] */ +#define WF_PLE_TOP_INT_N9_STS_ERROR_INT_SHFT 13 +#define WF_PLE_TOP_INT_N9_STS_CPU_Q3_NE_ADDR WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_CPU_Q3_NE_MASK 0x00000008 /* CPU_Q3_NE[3] */ +#define WF_PLE_TOP_INT_N9_STS_CPU_Q3_NE_SHFT 3 +#define WF_PLE_TOP_INT_N9_STS_CPU_Q2_NE_ADDR WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_CPU_Q2_NE_MASK 0x00000004 /* CPU_Q2_NE[2] */ +#define WF_PLE_TOP_INT_N9_STS_CPU_Q2_NE_SHFT 2 +#define WF_PLE_TOP_INT_N9_STS_CPU_Q1_NE_ADDR WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_CPU_Q1_NE_MASK 0x00000002 /* CPU_Q1_NE[1] */ +#define WF_PLE_TOP_INT_N9_STS_CPU_Q1_NE_SHFT 1 +#define WF_PLE_TOP_INT_N9_STS_CPU_Q0_NE_ADDR WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_CPU_Q0_NE_MASK 0x00000001 /* CPU_Q0_NE[0] */ +#define WF_PLE_TOP_INT_N9_STS_CPU_Q0_NE_SHFT 0 + +/* +* ---INT_N9_ERR_STS (0x820C0000 + 0x304)--- +* Q_CMD_ERR_P0[0] - (W1C) Queue command error interrupt status of +* port 0. Avoid unclear error flag, please clear flag when logic reset. +* Q_CMD_ERR_P1[1] - (W1C) Queue command error interrupt status of +* port 1. Avoid unclear error flag, please clear flag when logic reset. +* Q_CMD_ERR_P2[2] - (W1C) Queue command error interrupt status of +* port 2. Avoid unclear error flag, please clear flag when logic reset. +* PAGE_UDF_P0[3] - (W1C) Page underflow interrupt status of port +* 0. Avoid unclear error flag, please clear flag when logic reset. +* PAGE_UDF_P1[4] - (W1C) Page underflow interrupt status of port +* 1. Avoid unclear error flag, please clear flag when logic reset. +* PAGE_UDF_P2[5] - (W1C) Page underflow interrupt status of port +* 2. Avoid unclear error flag, please clear flag when logic reset. +* DOUBLE_RLS_ERR[6] - (W1C) Double release error interrupt. Avoid +* unclear error flag, please clear flag when logic reset. +* MDP_D_OPER_ERR[7] - (W1C) MDP data operation error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* MDP_HANG_ERR[8] - (W1C) MDP FSM Hang error interrupt. Avoid +* unclear error flag, please clear flag when logic reset. +* RESERVED9[9] - (RO) Reserved bits +* DATA_OPER_ERR_P0[10] - (W1C) Data operation error of port 0. Avoid +* unclear error flag, please clear flag when logic reset. +* DATA_OPER_ERR_P1[11] - (W1C) Data operation error of port 1. Avoid +* unclear error flag, please clear flag when logic reset. +* DATA_OPER_ERR_P2[12] - (W1C) Data operation error of port 2. Avoid +* unclear error flag, please clear flag when logic reset. +* FL_HANG_ERR[13] - (W1C) Frame link FSM hang error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* PL_HANG_ERR[14] - (W1C) Page link FSM hang error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* HIF_HANG_ERR[15] - (W1C) HIF port FSM hang error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* CPU_HANG_ERR[16] - (W1C) CPU port FSM hang error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* LMAC_HANG_ERR[17] - (W1C) LMAC port FSM hang error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* FREE_HEAD_TAIL_ERR[18] - (W1C) Free head/tail error interrupt. Avoid +* unclear error flag, please clear flag when logic reset. +* QSTRUCT_ERR[19] - (W1C) Queue struct data error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* BN0_MACTX_HANG_ERR[20] - (W1C) BN0 MACTX Ctrl FSM Hang error +* interrupt. Avoid unclear error flag, please clear flag when logic reset. +* BN1_MACTX_HANG_ERR[21] - (W1C) BN1 MACTX Ctrl FSM Hang error +* interrupt. Avoid unclear error flag, please clear flag when logic reset. +* BN0_TXCMD_HANG_ERR[22] - (W1C) BN0 TXCMD Ctrl FSM Hang error +* interrupt. Avoid unclear error flag, please clear flag when logic reset. +* BN1_TXCMD_HANG_ERR[23] - (W1C) BN1 TXCMD Ctrl FSM Hang error +* interrupt. Avoid unclear error flag, please clear flag when logic reset. +* DRR_SRCH_DBDC0_ERR[24] - (W1C) DRR DBDC0 sta serach error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* DRR_SRCH_DBDC1_ERR[25] - (W1C) DRR DBDC1 sta serach error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* DRR_FL_ERR[26] - (W1C) DRR forward link access error +* interrupt. Avoid unclear error flag, please clear flag when logic reset. +* DRR_BL_ERR[27] - (W1C) DRR backward link access error +* interrupt. Avoid unclear error flag, please clear flag when logic reset. +* DRR_RL_ERR[28] - (W1C) DRR relay link access error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* DRR_CHRG_STA_ERR[29] - (W1C) DRR charge wlanid error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* DRR_STA_WLANID_ERR[30] - (W1C) DRR wlanid error interrupt. Avoid +* unclear error flag, please clear flag when logic reset. +* DRR_STA_WMMID_ERR[31] - (W1C) DRR wmmid error interrupt. Avoid +* unclear error flag, please clear flag when logic reset. +*/ +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_STA_WMMID_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_STA_WMMID_ERR_MASK \ + 0x80000000 /* DRR_STA_WMMID_ERR[31] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_STA_WMMID_ERR_SHFT 31 +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_STA_WLANID_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_STA_WLANID_ERR_MASK \ + 0x40000000 /* DRR_STA_WLANID_ERR[30] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_STA_WLANID_ERR_SHFT 30 +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_CHRG_STA_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_CHRG_STA_ERR_MASK \ + 0x20000000 /* DRR_CHRG_STA_ERR[29] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_CHRG_STA_ERR_SHFT 29 +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_RL_ERR_ADDR WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_RL_ERR_MASK \ + 0x10000000 /* DRR_RL_ERR[28] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_RL_ERR_SHFT 28 +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_BL_ERR_ADDR WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_BL_ERR_MASK \ + 0x08000000 /* DRR_BL_ERR[27] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_BL_ERR_SHFT 27 +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_FL_ERR_ADDR WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_FL_ERR_MASK \ + 0x04000000 /* DRR_FL_ERR[26] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_FL_ERR_SHFT 26 +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_SRCH_DBDC1_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_SRCH_DBDC1_ERR_MASK \ + 0x02000000 /* DRR_SRCH_DBDC1_ERR[25] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_SRCH_DBDC1_ERR_SHFT 25 +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_SRCH_DBDC0_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_SRCH_DBDC0_ERR_MASK \ + 0x01000000 /* DRR_SRCH_DBDC0_ERR[24] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_SRCH_DBDC0_ERR_SHFT 24 +#define WF_PLE_TOP_INT_N9_ERR_STS_BN1_TXCMD_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_BN1_TXCMD_HANG_ERR_MASK \ + 0x00800000 /* BN1_TXCMD_HANG_ERR[23] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_BN1_TXCMD_HANG_ERR_SHFT 23 +#define WF_PLE_TOP_INT_N9_ERR_STS_BN0_TXCMD_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_BN0_TXCMD_HANG_ERR_MASK \ + 0x00400000 /* BN0_TXCMD_HANG_ERR[22] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_BN0_TXCMD_HANG_ERR_SHFT 22 +#define WF_PLE_TOP_INT_N9_ERR_STS_BN1_MACTX_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_BN1_MACTX_HANG_ERR_MASK \ + 0x00200000 /* BN1_MACTX_HANG_ERR[21] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_BN1_MACTX_HANG_ERR_SHFT 21 +#define WF_PLE_TOP_INT_N9_ERR_STS_BN0_MACTX_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_BN0_MACTX_HANG_ERR_MASK \ + 0x00100000 /* BN0_MACTX_HANG_ERR[20] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_BN0_MACTX_HANG_ERR_SHFT 20 +#define WF_PLE_TOP_INT_N9_ERR_STS_QSTRUCT_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_QSTRUCT_ERR_MASK \ + 0x00080000 /* QSTRUCT_ERR[19] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_QSTRUCT_ERR_SHFT 19 +#define WF_PLE_TOP_INT_N9_ERR_STS_FREE_HEAD_TAIL_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_FREE_HEAD_TAIL_ERR_MASK \ + 0x00040000 /* FREE_HEAD_TAIL_ERR[18] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_FREE_HEAD_TAIL_ERR_SHFT 18 +#define WF_PLE_TOP_INT_N9_ERR_STS_LMAC_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_LMAC_HANG_ERR_MASK \ + 0x00020000 /* LMAC_HANG_ERR[17] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_LMAC_HANG_ERR_SHFT 17 +#define WF_PLE_TOP_INT_N9_ERR_STS_CPU_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_CPU_HANG_ERR_MASK \ + 0x00010000 /* CPU_HANG_ERR[16] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_CPU_HANG_ERR_SHFT 16 +#define WF_PLE_TOP_INT_N9_ERR_STS_HIF_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_HIF_HANG_ERR_MASK \ + 0x00008000 /* HIF_HANG_ERR[15] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_HIF_HANG_ERR_SHFT 15 +#define WF_PLE_TOP_INT_N9_ERR_STS_PL_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_PL_HANG_ERR_MASK \ + 0x00004000 /* PL_HANG_ERR[14] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_PL_HANG_ERR_SHFT 14 +#define WF_PLE_TOP_INT_N9_ERR_STS_FL_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_FL_HANG_ERR_MASK \ + 0x00002000 /* FL_HANG_ERR[13] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_FL_HANG_ERR_SHFT 13 +#define WF_PLE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P2_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P2_MASK \ + 0x00001000 /* DATA_OPER_ERR_P2[12] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P2_SHFT 12 +#define WF_PLE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P1_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P1_MASK \ + 0x00000800 /* DATA_OPER_ERR_P1[11] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P1_SHFT 11 +#define WF_PLE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P0_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P0_MASK \ + 0x00000400 /* DATA_OPER_ERR_P0[10] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P0_SHFT 10 +#define WF_PLE_TOP_INT_N9_ERR_STS_MDP_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_MDP_HANG_ERR_MASK \ + 0x00000100 /* MDP_HANG_ERR[8] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_MDP_HANG_ERR_SHFT 8 +#define WF_PLE_TOP_INT_N9_ERR_STS_MDP_D_OPER_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_MDP_D_OPER_ERR_MASK \ + 0x00000080 /* MDP_D_OPER_ERR[7] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_MDP_D_OPER_ERR_SHFT 7 +#define WF_PLE_TOP_INT_N9_ERR_STS_DOUBLE_RLS_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_DOUBLE_RLS_ERR_MASK \ + 0x00000040 /* DOUBLE_RLS_ERR[6] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_DOUBLE_RLS_ERR_SHFT 6 +#define WF_PLE_TOP_INT_N9_ERR_STS_PAGE_UDF_P2_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_PAGE_UDF_P2_MASK \ + 0x00000020 /* PAGE_UDF_P2[5] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_PAGE_UDF_P2_SHFT 5 +#define WF_PLE_TOP_INT_N9_ERR_STS_PAGE_UDF_P1_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_PAGE_UDF_P1_MASK \ + 0x00000010 /* PAGE_UDF_P1[4] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_PAGE_UDF_P1_SHFT 4 +#define WF_PLE_TOP_INT_N9_ERR_STS_PAGE_UDF_P0_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_PAGE_UDF_P0_MASK \ + 0x00000008 /* PAGE_UDF_P0[3] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_PAGE_UDF_P0_SHFT 3 +#define WF_PLE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P2_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P2_MASK \ + 0x00000004 /* Q_CMD_ERR_P2[2] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P2_SHFT 2 +#define WF_PLE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P1_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P1_MASK \ + 0x00000002 /* Q_CMD_ERR_P1[1] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P1_SHFT 1 +#define WF_PLE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P0_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P0_MASK \ + 0x00000001 /* Q_CMD_ERR_P0[0] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P0_SHFT 0 + +/* +* ---INT_N9_ERR_STS_1 (0x820C0000 + 0x308)--- +* BN0_MDP_TDP_HANG_ERR[0] - (W1C) BN0 MDP TDP FSM hang error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* MDP_RDP_HANG_ERR[1] - (W1C) MDP RDP FSM hang error interrupt. Avoid +* unclear error flag, please clear flag when logic reset. +* BN0_MDP_TIOC_HANG_ERR[2] - (W1C) BN0 MDP TIOC FSM hang error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* BN0_MDP_RIOC_HANG_ERR[3] - (W1C) BN0 MDP RIOC FSM hang error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* PF_HANG_ERR[4] - (W1C) PF FSM hang error interrupt. Avoid +* unclear error flag, please clear flag when logic reset. +* SEC0_HANG_ERR[5] - (W1C) SEC 0 FSM hang error interrupt. Avoid +* unclear error flag, please clear flag when logic reset. +* SEC1_HANG_ERR[6] - (W1C) SEC 1 FSM hang error interrupt. Avoid +* unclear error flag, please clear flag when logic reset. +* BN1_MDP_TDP_HANG_ERR[7] - (W1C) BN1 MDP TDP FSM hang error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* BN1_MDP_TIOC_HANG_ERR[8] - (W1C) BN1 MDP TIOC FSM hang error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* BN1_MDP_RIOC_HANG_ERR[9] - (W1C) BN1 MDP RIOC FSM hang error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* RESERVED10[11..10] - (RO) Reserved bits +* BN0_RPEDL_ARB_HANG_ERR[12] - (W1C) BN0 PREDL ARB hang error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* BN0_PREDL_TXCMD_HANG_ERR[13] - (W1C) BN0 PREDL TXCDM FSM hang error +* interrupt. Avoid unclear error flag, please clear flag when logic reset. +* BN1_RPEDL_ARB_HANG_ERR[14] - (W1C) BN1 PREDL ARB hang error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* BN1_PREDL_TXCMD_HANG_ERR[15] - (W1C) BN1 PREDL TXCDM FSM hang error +* interrupt. Avoid unclear error flag, please clear flag when logic reset. +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_PREDL_TXCMD_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_PREDL_TXCMD_HANG_ERR_MASK \ + 0x00008000 /* BN1_PREDL_TXCMD_HANG_ERR[15] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_PREDL_TXCMD_HANG_ERR_SHFT 15 +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_RPEDL_ARB_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_RPEDL_ARB_HANG_ERR_MASK \ + 0x00004000 /* BN1_RPEDL_ARB_HANG_ERR[14] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_RPEDL_ARB_HANG_ERR_SHFT 14 +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_PREDL_TXCMD_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_PREDL_TXCMD_HANG_ERR_MASK \ + 0x00002000 /* BN0_PREDL_TXCMD_HANG_ERR[13] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_PREDL_TXCMD_HANG_ERR_SHFT 13 +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_RPEDL_ARB_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_RPEDL_ARB_HANG_ERR_MASK \ + 0x00001000 /* BN0_RPEDL_ARB_HANG_ERR[12] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_RPEDL_ARB_HANG_ERR_SHFT 12 +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_MDP_RIOC_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_MDP_RIOC_HANG_ERR_MASK \ + 0x00000200 /* BN1_MDP_RIOC_HANG_ERR[9] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_MDP_RIOC_HANG_ERR_SHFT 9 +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_MDP_TIOC_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_MDP_TIOC_HANG_ERR_MASK \ + 0x00000100 /* BN1_MDP_TIOC_HANG_ERR[8] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_MDP_TIOC_HANG_ERR_SHFT 8 +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_MDP_TDP_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_MDP_TDP_HANG_ERR_MASK \ + 0x00000080 /* BN1_MDP_TDP_HANG_ERR[7] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_MDP_TDP_HANG_ERR_SHFT 7 +#define WF_PLE_TOP_INT_N9_ERR_STS_1_SEC1_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_1_SEC1_HANG_ERR_MASK \ + 0x00000040 /* SEC1_HANG_ERR[6] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_SEC1_HANG_ERR_SHFT 6 +#define WF_PLE_TOP_INT_N9_ERR_STS_1_SEC0_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_1_SEC0_HANG_ERR_MASK \ + 0x00000020 /* SEC0_HANG_ERR[5] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_SEC0_HANG_ERR_SHFT 5 +#define WF_PLE_TOP_INT_N9_ERR_STS_1_PF_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_1_PF_HANG_ERR_MASK \ + 0x00000010 /* PF_HANG_ERR[4] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_PF_HANG_ERR_SHFT 4 +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_MDP_RIOC_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_MDP_RIOC_HANG_ERR_MASK \ + 0x00000008 /* BN0_MDP_RIOC_HANG_ERR[3] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_MDP_RIOC_HANG_ERR_SHFT 3 +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_MDP_TIOC_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_MDP_TIOC_HANG_ERR_MASK \ + 0x00000004 /* BN0_MDP_TIOC_HANG_ERR[2] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_MDP_TIOC_HANG_ERR_SHFT 2 +#define WF_PLE_TOP_INT_N9_ERR_STS_1_MDP_RDP_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_1_MDP_RDP_HANG_ERR_MASK \ + 0x00000002 /* MDP_RDP_HANG_ERR[1] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_MDP_RDP_HANG_ERR_SHFT 1 +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_MDP_TDP_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_MDP_TDP_HANG_ERR_MASK \ + 0x00000001 /* BN0_MDP_TDP_HANG_ERR[0] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_MDP_TDP_HANG_ERR_SHFT 0 + +/* +* ---N9_BSS_PS_INT_STS (0x820C0000 + 0x30c)--- +* BSSID0_NONEMPTY_INT[0] - (W1C) BSSID0 queue empty fall interrupt +status +* BSSID1_NONEMPTY_INT[1] - (W1C) BSSID1 queue empty fall interrupt +status +* BSSID2_NONEMPTY_INT[2] - (W1C) BSSID2 queue empty fall interrupt +status +* BSSID3_NONEMPTY_INT[3] - (W1C) BSSID3 queue empty fall interrupt +status +* RESERVED4[7..4] - (RO) Reserved bits +* BSSID0_EMPTY_INT[8] - (W1C) BSSID0 queue empty raise interrupt +status +* BSSID1_EMPTY_INT[9] - (W1C) BSSID1 queue empty raise interrupt +status +* BSSID2_EMPTY_INT[10] - (W1C) BSSID2 queue empty raise interrupt +status +* BSSID3_EMPTY_INT[11] - (W1C) BSSID3 queue empty raise interrupt +status +* RESERVED12[15..12] - (RO) Reserved bits +* BSSID0_ENQ_LMAC_INT[16] - (W1C) BSSID0 enqueue interrupt status +* BSSID1_ENQ_LMAC_INT[17] - (W1C) BSSID1 enqueue interrupt status +* BSSID2_ENQ_LMAC_INT[18] - (W1C) BSSID2 enqueue interrupt status +* BSSID3_ENQ_LMAC_INT[19] - (W1C) BSSID3 enqueue interrupt status +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID3_ENQ_LMAC_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_STS_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID3_ENQ_LMAC_INT_MASK \ + 0x00080000 /* BSSID3_ENQ_LMAC_INT[19] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID3_ENQ_LMAC_INT_SHFT 19 +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID2_ENQ_LMAC_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_STS_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID2_ENQ_LMAC_INT_MASK \ + 0x00040000 /* BSSID2_ENQ_LMAC_INT[18] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID2_ENQ_LMAC_INT_SHFT 18 +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID1_ENQ_LMAC_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_STS_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID1_ENQ_LMAC_INT_MASK \ + 0x00020000 /* BSSID1_ENQ_LMAC_INT[17] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID1_ENQ_LMAC_INT_SHFT 17 +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID0_ENQ_LMAC_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_STS_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID0_ENQ_LMAC_INT_MASK \ + 0x00010000 /* BSSID0_ENQ_LMAC_INT[16] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID0_ENQ_LMAC_INT_SHFT 16 +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID3_EMPTY_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_STS_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID3_EMPTY_INT_MASK \ + 0x00000800 /* BSSID3_EMPTY_INT[11] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID3_EMPTY_INT_SHFT 11 +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID2_EMPTY_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_STS_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID2_EMPTY_INT_MASK \ + 0x00000400 /* BSSID2_EMPTY_INT[10] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID2_EMPTY_INT_SHFT 10 +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID1_EMPTY_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_STS_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID1_EMPTY_INT_MASK \ + 0x00000200 /* BSSID1_EMPTY_INT[9] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID1_EMPTY_INT_SHFT 9 +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID0_EMPTY_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_STS_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID0_EMPTY_INT_MASK \ + 0x00000100 /* BSSID0_EMPTY_INT[8] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID0_EMPTY_INT_SHFT 8 +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID3_NONEMPTY_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_STS_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID3_NONEMPTY_INT_MASK \ + 0x00000008 /* BSSID3_NONEMPTY_INT[3] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID3_NONEMPTY_INT_SHFT 3 +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID2_NONEMPTY_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_STS_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID2_NONEMPTY_INT_MASK \ + 0x00000004 /* BSSID2_NONEMPTY_INT[2] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID2_NONEMPTY_INT_SHFT 2 +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID1_NONEMPTY_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_STS_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID1_NONEMPTY_INT_MASK \ + 0x00000002 /* BSSID1_NONEMPTY_INT[1] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID1_NONEMPTY_INT_SHFT 1 +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID0_NONEMPTY_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_STS_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID0_NONEMPTY_INT_MASK \ + 0x00000001 /* BSSID0_NONEMPTY_INT[0] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID0_NONEMPTY_INT_SHFT 0 + +/* +* ---C_GET_FID_0 (0x820C0000 + 0x310)--- +* GET_SRC_WLANID[9..0] - (RW) Source WLAN ID for get frame ID. +* RESERVED10[11..10] - (RO) Reserved bits +* GET_SRC_TGID[12] - (RW) Source TX Group ID for get frame ID. +* RESERVED13[13] - (RO) Reserved bits +* GET_SRC_PID[15..14] - (RW) Source port ID for get frame ID. +* GET_FRAME_TYPE[19..16] - (RW) GET_SUB_TYPE +* RESERVED20[23..20] - (RO) Reserved bits +* GET_SRC_QID[30..24] - (RW) Source Queue ID for get frame ID. +* EXECUTE[31] - (A0) Executes command +*/ +#define WF_PLE_TOP_C_GET_FID_0_EXECUTE_ADDR WF_PLE_TOP_C_GET_FID_0_ADDR +#define WF_PLE_TOP_C_GET_FID_0_EXECUTE_MASK 0x80000000 /* EXECUTE[31] */ +#define WF_PLE_TOP_C_GET_FID_0_EXECUTE_SHFT 31 +#define WF_PLE_TOP_C_GET_FID_0_GET_SRC_QID_ADDR WF_PLE_TOP_C_GET_FID_0_ADDR +#define WF_PLE_TOP_C_GET_FID_0_GET_SRC_QID_MASK \ + 0x7F000000 /* GET_SRC_QID[30..24] */ +#define WF_PLE_TOP_C_GET_FID_0_GET_SRC_QID_SHFT 24 +#define WF_PLE_TOP_C_GET_FID_0_GET_FRAME_TYPE_ADDR WF_PLE_TOP_C_GET_FID_0_ADDR +#define WF_PLE_TOP_C_GET_FID_0_GET_FRAME_TYPE_MASK \ + 0x000F0000 /* GET_FRAME_TYPE[19..16] */ +#define WF_PLE_TOP_C_GET_FID_0_GET_FRAME_TYPE_SHFT 16 +#define WF_PLE_TOP_C_GET_FID_0_GET_SRC_PID_ADDR WF_PLE_TOP_C_GET_FID_0_ADDR +#define WF_PLE_TOP_C_GET_FID_0_GET_SRC_PID_MASK \ + 0x0000C000 /* GET_SRC_PID[15..14] */ +#define WF_PLE_TOP_C_GET_FID_0_GET_SRC_PID_SHFT 14 +#define WF_PLE_TOP_C_GET_FID_0_GET_SRC_TGID_ADDR WF_PLE_TOP_C_GET_FID_0_ADDR +#define WF_PLE_TOP_C_GET_FID_0_GET_SRC_TGID_MASK \ + 0x00001000 /* GET_SRC_TGID[12] */ +#define WF_PLE_TOP_C_GET_FID_0_GET_SRC_TGID_SHFT 12 +#define WF_PLE_TOP_C_GET_FID_0_GET_SRC_WLANID_ADDR WF_PLE_TOP_C_GET_FID_0_ADDR +#define WF_PLE_TOP_C_GET_FID_0_GET_SRC_WLANID_MASK \ + 0x000003FF /* GET_SRC_WLANID[9..0] */ +#define WF_PLE_TOP_C_GET_FID_0_GET_SRC_WLANID_SHFT 0 + +/* +* ---C_GET_FID_1 (0x820C0000 + 0x314)--- +* GET_RETURN_FID[11..0] - (RO) Return frame ID +* RESERVED12[14..12] - (RO) Reserved bits +* END[15] - (RO) Return frame ID is end FID. +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_C_GET_FID_1_END_ADDR WF_PLE_TOP_C_GET_FID_1_ADDR +#define WF_PLE_TOP_C_GET_FID_1_END_MASK 0x00008000 /* END[15] */ +#define WF_PLE_TOP_C_GET_FID_1_END_SHFT 15 +#define WF_PLE_TOP_C_GET_FID_1_GET_RETURN_FID_ADDR WF_PLE_TOP_C_GET_FID_1_ADDR +#define WF_PLE_TOP_C_GET_FID_1_GET_RETURN_FID_MASK \ + 0x00000FFF /* GET_RETURN_FID[11..0] */ +#define WF_PLE_TOP_C_GET_FID_1_GET_RETURN_FID_SHFT 0 + +/* +* ---TO_N9_INT (0x820C0000 + 0x318)--- +* CR4_CMD[30..0] - (RW) Command for N9 +* TOGGLE[31] - (RW) When this bit is toggled, HW will send +* interrupt to N9. +*/ +#define WF_PLE_TOP_TO_N9_INT_TOGGLE_ADDR WF_PLE_TOP_TO_N9_INT_ADDR +#define WF_PLE_TOP_TO_N9_INT_TOGGLE_MASK 0x80000000 /* TOGGLE[31] */ +#define WF_PLE_TOP_TO_N9_INT_TOGGLE_SHFT 31 +#define WF_PLE_TOP_TO_N9_INT_CR4_CMD_ADDR WF_PLE_TOP_TO_N9_INT_ADDR +#define WF_PLE_TOP_TO_N9_INT_CR4_CMD_MASK 0x7FFFFFFF /* CR4_CMD[30..0] */ +#define WF_PLE_TOP_TO_N9_INT_CR4_CMD_SHFT 0 + +/* +* ---C_EN_QUEUE_0 (0x820C0000 + 0x320)--- +* DST_WLANID[9..0] - (RW) Destination WLANID for enqueue +* RESERVED10[11..10] - (RO) Reserved bits +* DST_TGID[12] - (RW) Destination TX Group ID for enqueue +* RESERVED13[13] - (RO) Reserved bits +* DST_PID[15..14] - (RW) Destination port ID for enqueue +* SUB_TYPE[19..16] - (RW) Sub-type of enqueue command +* RESERVED20[22..20] - (RO) Reserved bits +* DELAY_ENQ[23] - (RW) Delay enqueue +* ENQ_DST_QID[30..24] - (RW) Destination queue ID for enqueue +* EXECUTE[31] - (A0) Executes command +*/ +#define WF_PLE_TOP_C_EN_QUEUE_0_EXECUTE_ADDR WF_PLE_TOP_C_EN_QUEUE_0_ADDR +#define WF_PLE_TOP_C_EN_QUEUE_0_EXECUTE_MASK 0x80000000 /* EXECUTE[31] */ +#define WF_PLE_TOP_C_EN_QUEUE_0_EXECUTE_SHFT 31 +#define WF_PLE_TOP_C_EN_QUEUE_0_ENQ_DST_QID_ADDR WF_PLE_TOP_C_EN_QUEUE_0_ADDR +#define WF_PLE_TOP_C_EN_QUEUE_0_ENQ_DST_QID_MASK \ + 0x7F000000 /* ENQ_DST_QID[30..24] */ +#define WF_PLE_TOP_C_EN_QUEUE_0_ENQ_DST_QID_SHFT 24 +#define WF_PLE_TOP_C_EN_QUEUE_0_DELAY_ENQ_ADDR WF_PLE_TOP_C_EN_QUEUE_0_ADDR +#define WF_PLE_TOP_C_EN_QUEUE_0_DELAY_ENQ_MASK 0x00800000 /* DELAY_ENQ[23] */ +#define WF_PLE_TOP_C_EN_QUEUE_0_DELAY_ENQ_SHFT 23 +#define WF_PLE_TOP_C_EN_QUEUE_0_SUB_TYPE_ADDR WF_PLE_TOP_C_EN_QUEUE_0_ADDR +#define WF_PLE_TOP_C_EN_QUEUE_0_SUB_TYPE_MASK 0x000F0000 /* SUB_TYPE[19..16] */ +#define WF_PLE_TOP_C_EN_QUEUE_0_SUB_TYPE_SHFT 16 +#define WF_PLE_TOP_C_EN_QUEUE_0_DST_PID_ADDR WF_PLE_TOP_C_EN_QUEUE_0_ADDR +#define WF_PLE_TOP_C_EN_QUEUE_0_DST_PID_MASK 0x0000C000 /* DST_PID[15..14] */ +#define WF_PLE_TOP_C_EN_QUEUE_0_DST_PID_SHFT 14 +#define WF_PLE_TOP_C_EN_QUEUE_0_DST_TGID_ADDR WF_PLE_TOP_C_EN_QUEUE_0_ADDR +#define WF_PLE_TOP_C_EN_QUEUE_0_DST_TGID_MASK 0x00001000 /* DST_TGID[12] */ +#define WF_PLE_TOP_C_EN_QUEUE_0_DST_TGID_SHFT 12 +#define WF_PLE_TOP_C_EN_QUEUE_0_DST_WLANID_ADDR WF_PLE_TOP_C_EN_QUEUE_0_ADDR +#define WF_PLE_TOP_C_EN_QUEUE_0_DST_WLANID_MASK \ + 0x000003FF /* DST_WLANID[9..0] */ +#define WF_PLE_TOP_C_EN_QUEUE_0_DST_WLANID_SHFT 0 + +/* +* ---C_EN_QUEUE_1 (0x820C0000 + 0x324)--- +* CUR_LIST_FID_START[11..0] - (RW) Start frame ID of enqueue operation +* list, enqueue FID of enqueue operation +* RESERVED12[15..12] - (RO) Reserved bits +* CUR_LIST_FID_END[27..16] - (RW) End frame ID of enqueue operation list +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_C_EN_QUEUE_1_CUR_LIST_FID_END_ADDR \ + WF_PLE_TOP_C_EN_QUEUE_1_ADDR +#define WF_PLE_TOP_C_EN_QUEUE_1_CUR_LIST_FID_END_MASK \ + 0x0FFF0000 /* CUR_LIST_FID_END[27..16] */ +#define WF_PLE_TOP_C_EN_QUEUE_1_CUR_LIST_FID_END_SHFT 16 +#define WF_PLE_TOP_C_EN_QUEUE_1_CUR_LIST_FID_START_ADDR \ + WF_PLE_TOP_C_EN_QUEUE_1_ADDR +#define WF_PLE_TOP_C_EN_QUEUE_1_CUR_LIST_FID_START_MASK \ + 0x00000FFF /* CUR_LIST_FID_START[11..0] */ +#define WF_PLE_TOP_C_EN_QUEUE_1_CUR_LIST_FID_START_SHFT 0 + +/* +* ---C_EN_QUEUE_2 (0x820C0000 + 0x328)--- +* TARGET_FID[11..0] - (RW) Target reference FID for enqueue +operation +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_C_EN_QUEUE_2_TARGET_FID_ADDR WF_PLE_TOP_C_EN_QUEUE_2_ADDR +#define WF_PLE_TOP_C_EN_QUEUE_2_TARGET_FID_MASK \ + 0x00000FFF /* TARGET_FID[11..0] */ +#define WF_PLE_TOP_C_EN_QUEUE_2_TARGET_FID_SHFT 0 + +/* +* ---C_DE_QUEUE_0 (0x820C0000 + 0x330)--- +* SRC_WLANID[9..0] - (RW) Source WLAN ID for dequeue command +* RESERVED10[11..10] - (RO) Reserved bits +* SRC_TGID[12] - (RW) Source TX Group ID for dequeue command +* RESERVED13[13] - (RO) Reserved bits +* SRC_PID[15..14] - (RW) Source port ID for dequeue command +* DEQ_SUB_TYPE[19..16] - (RW) Dequeue subtype of dequeue command +* ENQ_SUB_TYPE[22..20] - (RW) Enqueue subtype of enqueue command +* Only valid in Deq&Enq type. +* ENQ_VLD[23] - (RW) Deq&Enq command valid +* SRC_QID[30..24] - (RW) Source queue ID for dequeue command +* EXECUTE[31] - (A0) Executes dequeue command +*/ +#define WF_PLE_TOP_C_DE_QUEUE_0_EXECUTE_ADDR WF_PLE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_0_EXECUTE_MASK 0x80000000 /* EXECUTE[31] */ +#define WF_PLE_TOP_C_DE_QUEUE_0_EXECUTE_SHFT 31 +#define WF_PLE_TOP_C_DE_QUEUE_0_SRC_QID_ADDR WF_PLE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_0_SRC_QID_MASK 0x7F000000 /* SRC_QID[30..24] */ +#define WF_PLE_TOP_C_DE_QUEUE_0_SRC_QID_SHFT 24 +#define WF_PLE_TOP_C_DE_QUEUE_0_ENQ_VLD_ADDR WF_PLE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_0_ENQ_VLD_MASK 0x00800000 /* ENQ_VLD[23] */ +#define WF_PLE_TOP_C_DE_QUEUE_0_ENQ_VLD_SHFT 23 +#define WF_PLE_TOP_C_DE_QUEUE_0_ENQ_SUB_TYPE_ADDR WF_PLE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_0_ENQ_SUB_TYPE_MASK \ + 0x00700000 /* ENQ_SUB_TYPE[22..20] */ +#define WF_PLE_TOP_C_DE_QUEUE_0_ENQ_SUB_TYPE_SHFT 20 +#define WF_PLE_TOP_C_DE_QUEUE_0_DEQ_SUB_TYPE_ADDR WF_PLE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_0_DEQ_SUB_TYPE_MASK \ + 0x000F0000 /* DEQ_SUB_TYPE[19..16] */ +#define WF_PLE_TOP_C_DE_QUEUE_0_DEQ_SUB_TYPE_SHFT 16 +#define WF_PLE_TOP_C_DE_QUEUE_0_SRC_PID_ADDR WF_PLE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_0_SRC_PID_MASK 0x0000C000 /* SRC_PID[15..14] */ +#define WF_PLE_TOP_C_DE_QUEUE_0_SRC_PID_SHFT 14 +#define WF_PLE_TOP_C_DE_QUEUE_0_SRC_TGID_ADDR WF_PLE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_0_SRC_TGID_MASK 0x00001000 /* SRC_TGID[12] */ +#define WF_PLE_TOP_C_DE_QUEUE_0_SRC_TGID_SHFT 12 +#define WF_PLE_TOP_C_DE_QUEUE_0_SRC_WLANID_ADDR WF_PLE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_0_SRC_WLANID_MASK \ + 0x000003FF /* SRC_WLANID[9..0] */ +#define WF_PLE_TOP_C_DE_QUEUE_0_SRC_WLANID_SHFT 0 + +/* +* ---C_DE_QUEUE_1 (0x820C0000 + 0x334)--- +* CUR_LIST_FID_START[11..0] - (RW) Start frame ID of dequeue operation +* list, enqueue start FID of enqueue operation +* Only valid in Deq&Enq type. +* RESERVED12[15..12] - (RO) Reserved bits +* CUR_LIST_FID_END[27..16] - (RW) End framd ID of dequeue operation list, +* enqueue end FID of enqueue operation +* Only valid in Deq&Enq type. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_C_DE_QUEUE_1_CUR_LIST_FID_END_ADDR \ + WF_PLE_TOP_C_DE_QUEUE_1_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_1_CUR_LIST_FID_END_MASK \ + 0x0FFF0000 /* CUR_LIST_FID_END[27..16] */ +#define WF_PLE_TOP_C_DE_QUEUE_1_CUR_LIST_FID_END_SHFT 16 +#define WF_PLE_TOP_C_DE_QUEUE_1_CUR_LIST_FID_START_ADDR \ + WF_PLE_TOP_C_DE_QUEUE_1_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_1_CUR_LIST_FID_START_MASK \ + 0x00000FFF /* CUR_LIST_FID_START[11..0] */ +#define WF_PLE_TOP_C_DE_QUEUE_1_CUR_LIST_FID_START_SHFT 0 + +/* +* ---C_DE_QUEUE_2 (0x820C0000 + 0x338)--- +* DEQ_ENQ_DST_WLANID[9..0] - (RW) Destination WLAN ID for enqueue command +* Only valid in Deq&Enq type. +* RESERVED10[11..10] - (RO) Reserved bits +* DEQ_ENQ_DST_TGID[12] - (RW) Destination TX Group ID for enqueue +command +* Only valid in Deq&Enq type. +* RESERVED13[13] - (RO) Reserved bits +* DEQ_ENQ_DST_PID[15..14] - (RW) Destination port ID for enqueue command +* OInly valid in Deq&Enq type. +* RESERVED16[23..16] - (RO) Reserved bits +* DEQ_ENQ_DST_QID[30..24] - (RW) Destination queue ID for enqueue command +* Only valid in Deq&Enq type. +* RESERVED31[31] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_QID_ADDR \ + WF_PLE_TOP_C_DE_QUEUE_2_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_QID_MASK \ + 0x7F000000 /* DEQ_ENQ_DST_QID[30..24] */ +#define WF_PLE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_QID_SHFT 24 +#define WF_PLE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_PID_ADDR \ + WF_PLE_TOP_C_DE_QUEUE_2_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_PID_MASK \ + 0x0000C000 /* DEQ_ENQ_DST_PID[15..14] */ +#define WF_PLE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_PID_SHFT 14 +#define WF_PLE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_TGID_ADDR \ + WF_PLE_TOP_C_DE_QUEUE_2_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_TGID_MASK \ + 0x00001000 /* DEQ_ENQ_DST_TGID[12] */ +#define WF_PLE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_TGID_SHFT 12 +#define WF_PLE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_WLANID_ADDR \ + WF_PLE_TOP_C_DE_QUEUE_2_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_WLANID_MASK \ + 0x000003FF /* DEQ_ENQ_DST_WLANID[9..0] */ +#define WF_PLE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_WLANID_SHFT 0 + +/* +* ---C_DE_QUEUE_3 (0x820C0000 + 0x33c)--- +* DEQ_HEAD_FID[11..0] - (RO) Head FID got from dequeue command +* RESERVED12[14..12] - (RO) Reserved bits +* DEQ_EMPTY[15] - (RO) Queue empty after dequeue command is +executed +* DEQ_TAIL_FID[27..16] - (RO) Last FID got from dequeue command +* RESERVED28[30..28] - (RO) Reserved bits +* BUSY[31] - (RO) Dequeue execute busy +*/ +#define WF_PLE_TOP_C_DE_QUEUE_3_BUSY_ADDR WF_PLE_TOP_C_DE_QUEUE_3_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_3_BUSY_MASK 0x80000000 /* BUSY[31] */ +#define WF_PLE_TOP_C_DE_QUEUE_3_BUSY_SHFT 31 +#define WF_PLE_TOP_C_DE_QUEUE_3_DEQ_TAIL_FID_ADDR WF_PLE_TOP_C_DE_QUEUE_3_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_3_DEQ_TAIL_FID_MASK \ + 0x0FFF0000 /* DEQ_TAIL_FID[27..16] */ +#define WF_PLE_TOP_C_DE_QUEUE_3_DEQ_TAIL_FID_SHFT 16 +#define WF_PLE_TOP_C_DE_QUEUE_3_DEQ_EMPTY_ADDR WF_PLE_TOP_C_DE_QUEUE_3_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_3_DEQ_EMPTY_MASK 0x00008000 /* DEQ_EMPTY[15] */ +#define WF_PLE_TOP_C_DE_QUEUE_3_DEQ_EMPTY_SHFT 15 +#define WF_PLE_TOP_C_DE_QUEUE_3_DEQ_HEAD_FID_ADDR WF_PLE_TOP_C_DE_QUEUE_3_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_3_DEQ_HEAD_FID_MASK \ + 0x00000FFF /* DEQ_HEAD_FID[11..0] */ +#define WF_PLE_TOP_C_DE_QUEUE_3_DEQ_HEAD_FID_SHFT 0 + +/* +* ---C_DE_QUEUE_4 (0x820C0000 + 0x340)--- +* DEQ_ENQ_REF_FID[11..0] - (RW) Reference frame ID for enqueue command +* Only valid in Deq&Enq type. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_C_DE_QUEUE_4_DEQ_ENQ_REF_FID_ADDR \ + WF_PLE_TOP_C_DE_QUEUE_4_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_4_DEQ_ENQ_REF_FID_MASK \ + 0x00000FFF /* DEQ_ENQ_REF_FID[11..0] */ +#define WF_PLE_TOP_C_DE_QUEUE_4_DEQ_ENQ_REF_FID_SHFT 0 + +/* +* ---ALLOCATE_0 (0x820C0000 + 0x350)--- +* ALLOCATE_FRAME_LENGTH[13..0] - (RW) Allocate frame length +* Unit: DW (4 bytes) +* RESERVED14[15..14] - (RO) Reserved bits +* ALLOCATE_QID[20..16] - (RW) QID used for allocate buffer +* RESERVED21[30..21] - (RO) Reserved bits +* EXECUTE[31] - (A0) Executes allocate buffer command +*/ +#define WF_PLE_TOP_ALLOCATE_0_EXECUTE_ADDR WF_PLE_TOP_ALLOCATE_0_ADDR +#define WF_PLE_TOP_ALLOCATE_0_EXECUTE_MASK 0x80000000 /* EXECUTE[31] */ +#define WF_PLE_TOP_ALLOCATE_0_EXECUTE_SHFT 31 +#define WF_PLE_TOP_ALLOCATE_0_ALLOCATE_QID_ADDR WF_PLE_TOP_ALLOCATE_0_ADDR +#define WF_PLE_TOP_ALLOCATE_0_ALLOCATE_QID_MASK \ + 0x001F0000 /* ALLOCATE_QID[20..16] */ +#define WF_PLE_TOP_ALLOCATE_0_ALLOCATE_QID_SHFT 16 +#define WF_PLE_TOP_ALLOCATE_0_ALLOCATE_FRAME_LENGTH_ADDR \ + WF_PLE_TOP_ALLOCATE_0_ADDR +#define WF_PLE_TOP_ALLOCATE_0_ALLOCATE_FRAME_LENGTH_MASK \ + 0x00003FFF /* ALLOCATE_FRAME_LENGTH[13..0] */ +#define WF_PLE_TOP_ALLOCATE_0_ALLOCATE_FRAME_LENGTH_SHFT 0 + +/* +* ---ALLOCATE_1 (0x820C0000 + 0x354)--- +* ALLOCATE_FID[11..0] - (RO) Return frame ID for allocate buffer +command +* RESERVED12[30..12] - (RO) Reserved bits +* EXECUTE[31] - (RO) Execute status of allocate buffer +command +*/ +#define WF_PLE_TOP_ALLOCATE_1_EXECUTE_ADDR WF_PLE_TOP_ALLOCATE_1_ADDR +#define WF_PLE_TOP_ALLOCATE_1_EXECUTE_MASK 0x80000000 /* EXECUTE[31] */ +#define WF_PLE_TOP_ALLOCATE_1_EXECUTE_SHFT 31 +#define WF_PLE_TOP_ALLOCATE_1_ALLOCATE_FID_ADDR WF_PLE_TOP_ALLOCATE_1_ADDR +#define WF_PLE_TOP_ALLOCATE_1_ALLOCATE_FID_MASK \ + 0x00000FFF /* ALLOCATE_FID[11..0] */ +#define WF_PLE_TOP_ALLOCATE_1_ALLOCATE_FID_SHFT 0 + +/* +* ---ALLOCATE_2 (0x820C0000 + 0x358)--- +* CPU_TXBYTE_COUNT[15..0] - (RW) TX data byte count +* This value should be the same as the first +* two bytes of TXD in PLE. +* CPU_MSDU_ID0_bit15_8[23..16] - (RW) MSDU_ID0 Bit15-Bit8 +* This value should be the same as the +* DW8[15:8] of TXD in PLE. +* CPU_PKT_FT[25..24] - (RW) TXD's PKT_FT +* This value should be the same as the +* DW0[24:23] of TXD in PLE. +* RESERVED26[31..26] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_ALLOCATE_2_CPU_PKT_FT_ADDR WF_PLE_TOP_ALLOCATE_2_ADDR +#define WF_PLE_TOP_ALLOCATE_2_CPU_PKT_FT_MASK \ + 0x03000000 /* CPU_PKT_FT[25..24] */ +#define WF_PLE_TOP_ALLOCATE_2_CPU_PKT_FT_SHFT 24 +#define WF_PLE_TOP_ALLOCATE_2_CPU_MSDU_ID0_bit15_8_ADDR \ + WF_PLE_TOP_ALLOCATE_2_ADDR +#define WF_PLE_TOP_ALLOCATE_2_CPU_MSDU_ID0_bit15_8_MASK \ + 0x00FF0000 /* CPU_MSDU_ID0_bit15_8[23..16] */ +#define WF_PLE_TOP_ALLOCATE_2_CPU_MSDU_ID0_bit15_8_SHFT 16 +#define WF_PLE_TOP_ALLOCATE_2_CPU_TXBYTE_COUNT_ADDR WF_PLE_TOP_ALLOCATE_2_ADDR +#define WF_PLE_TOP_ALLOCATE_2_CPU_TXBYTE_COUNT_MASK \ + 0x0000FFFF /* CPU_TXBYTE_COUNT[15..0] */ +#define WF_PLE_TOP_ALLOCATE_2_CPU_TXBYTE_COUNT_SHFT 0 + +/* +* ---QUEUE_EMPTY (0x820C0000 + 0x360)--- +* CPU_Q0_EMPTY[0] - (RO) CPU queue 0 empty status +* CPU_Q1_EMPTY[1] - (RO) CPU queue 1 empty status +* CPU_Q2_EMPTY[2] - (RO) CPU queue 2 empty status +* CPU_Q3_EMPTY[3] - (RO) CPU queue 3 empty status +* RESERVED4[7..4] - (RO) Reserved bits +* ALTX_0_EMPTY[8] - (RO) ALTX queue 0 empty status +* BMC_0_EMPTY[9] - (RO) BMC queue 0 empty status +* BCN_0_EMPTY[10] - (RO) BCN queue 0 empty status +* PSMP_0_EMPTY[11] - (RO) PSMP queue 0 empty status +* ALTX_1_EMPTY[12] - (RO) ALTX queue 1 empty status +* BMC_1_EMPTY[13] - (RO) BMC queue 1 empty status +* BCN_1_EMPTY[14] - (RO) BCN queue 1 empty status +* PSMP_1_EMPTY[15] - (RO) PSMP queue 1 empty status +* NAF_EMPTY[16] - (RO) NAF queue empty status +* NBCN_EMPTY[17] - (RO) NBCN queue empty status +* RESERVED18[19..18] - (RO) Reserved bits +* FIX_FID_EMPTY[20] - (RO) FIX_FID queue empty status +* RESERVED21[23..21] - (RO) Reserved bits +* ALL_AC_EMPTY[24] - (RO) All AC queue empty status +* RESERVED25[29..25] - (RO) Reserved bits +* RLS2_Q_EMTPY[30] - (RO) Release 2 queue empty status +* RLS_Q_EMTPY[31] - (RO) Release queue empty status +*/ +#define WF_PLE_TOP_QUEUE_EMPTY_RLS_Q_EMTPY_ADDR WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_RLS_Q_EMTPY_MASK 0x80000000 /* RLS_Q_EMTPY[31] */ +#define WF_PLE_TOP_QUEUE_EMPTY_RLS_Q_EMTPY_SHFT 31 +#define WF_PLE_TOP_QUEUE_EMPTY_RLS2_Q_EMTPY_ADDR WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_RLS2_Q_EMTPY_MASK \ + 0x40000000 /* RLS2_Q_EMTPY[30] */ +#define WF_PLE_TOP_QUEUE_EMPTY_RLS2_Q_EMTPY_SHFT 30 +#define WF_PLE_TOP_QUEUE_EMPTY_ALL_AC_EMPTY_ADDR WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_ALL_AC_EMPTY_MASK \ + 0x01000000 /* ALL_AC_EMPTY[24] */ +#define WF_PLE_TOP_QUEUE_EMPTY_ALL_AC_EMPTY_SHFT 24 +#define WF_PLE_TOP_QUEUE_EMPTY_FIX_FID_EMPTY_ADDR WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_FIX_FID_EMPTY_MASK \ + 0x00100000 /* FIX_FID_EMPTY[20] */ +#define WF_PLE_TOP_QUEUE_EMPTY_FIX_FID_EMPTY_SHFT 20 +#define WF_PLE_TOP_QUEUE_EMPTY_NBCN_EMPTY_ADDR WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_NBCN_EMPTY_MASK 0x00020000 /* NBCN_EMPTY[17] */ +#define WF_PLE_TOP_QUEUE_EMPTY_NBCN_EMPTY_SHFT 17 +#define WF_PLE_TOP_QUEUE_EMPTY_NAF_EMPTY_ADDR WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_NAF_EMPTY_MASK 0x00010000 /* NAF_EMPTY[16] */ +#define WF_PLE_TOP_QUEUE_EMPTY_NAF_EMPTY_SHFT 16 +#define WF_PLE_TOP_QUEUE_EMPTY_PSMP_1_EMPTY_ADDR WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_PSMP_1_EMPTY_MASK \ + 0x00008000 /* PSMP_1_EMPTY[15] */ +#define WF_PLE_TOP_QUEUE_EMPTY_PSMP_1_EMPTY_SHFT 15 +#define WF_PLE_TOP_QUEUE_EMPTY_BCN_1_EMPTY_ADDR WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_BCN_1_EMPTY_MASK 0x00004000 /* BCN_1_EMPTY[14] */ +#define WF_PLE_TOP_QUEUE_EMPTY_BCN_1_EMPTY_SHFT 14 +#define WF_PLE_TOP_QUEUE_EMPTY_BMC_1_EMPTY_ADDR WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_BMC_1_EMPTY_MASK 0x00002000 /* BMC_1_EMPTY[13] */ +#define WF_PLE_TOP_QUEUE_EMPTY_BMC_1_EMPTY_SHFT 13 +#define WF_PLE_TOP_QUEUE_EMPTY_ALTX_1_EMPTY_ADDR WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_ALTX_1_EMPTY_MASK \ + 0x00001000 /* ALTX_1_EMPTY[12] */ +#define WF_PLE_TOP_QUEUE_EMPTY_ALTX_1_EMPTY_SHFT 12 +#define WF_PLE_TOP_QUEUE_EMPTY_PSMP_0_EMPTY_ADDR WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_PSMP_0_EMPTY_MASK \ + 0x00000800 /* PSMP_0_EMPTY[11] */ +#define WF_PLE_TOP_QUEUE_EMPTY_PSMP_0_EMPTY_SHFT 11 +#define WF_PLE_TOP_QUEUE_EMPTY_BCN_0_EMPTY_ADDR WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_BCN_0_EMPTY_MASK 0x00000400 /* BCN_0_EMPTY[10] */ +#define WF_PLE_TOP_QUEUE_EMPTY_BCN_0_EMPTY_SHFT 10 +#define WF_PLE_TOP_QUEUE_EMPTY_BMC_0_EMPTY_ADDR WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_BMC_0_EMPTY_MASK 0x00000200 /* BMC_0_EMPTY[9] */ +#define WF_PLE_TOP_QUEUE_EMPTY_BMC_0_EMPTY_SHFT 9 +#define WF_PLE_TOP_QUEUE_EMPTY_ALTX_0_EMPTY_ADDR WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_ALTX_0_EMPTY_MASK \ + 0x00000100 /* ALTX_0_EMPTY[8] */ +#define WF_PLE_TOP_QUEUE_EMPTY_ALTX_0_EMPTY_SHFT 8 +#define WF_PLE_TOP_QUEUE_EMPTY_CPU_Q3_EMPTY_ADDR WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_CPU_Q3_EMPTY_MASK \ + 0x00000008 /* CPU_Q3_EMPTY[3] */ +#define WF_PLE_TOP_QUEUE_EMPTY_CPU_Q3_EMPTY_SHFT 3 +#define WF_PLE_TOP_QUEUE_EMPTY_CPU_Q2_EMPTY_ADDR WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_CPU_Q2_EMPTY_MASK \ + 0x00000004 /* CPU_Q2_EMPTY[2] */ +#define WF_PLE_TOP_QUEUE_EMPTY_CPU_Q2_EMPTY_SHFT 2 +#define WF_PLE_TOP_QUEUE_EMPTY_CPU_Q1_EMPTY_ADDR WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_CPU_Q1_EMPTY_MASK \ + 0x00000002 /* CPU_Q1_EMPTY[1] */ +#define WF_PLE_TOP_QUEUE_EMPTY_CPU_Q1_EMPTY_SHFT 1 +#define WF_PLE_TOP_QUEUE_EMPTY_CPU_Q0_EMPTY_ADDR WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_CPU_Q0_EMPTY_MASK \ + 0x00000001 /* CPU_Q0_EMPTY[0] */ +#define WF_PLE_TOP_QUEUE_EMPTY_CPU_Q0_EMPTY_SHFT 0 + +/* +* ---TXD_QUEUE_EMPTY (0x820C0000 + 0x364)--- +* AC00_EMPTY[0] - (RO) WMM0 AC0 queue empty status +* AC01_EMPTY[1] - (RO) WMM0 AC1 queue empty status +* AC02_EMPTY[2] - (RO) WMM0 AC2 queue empty status +* AC03_EMPTY[3] - (RO) WMM0 AC3 queue empty status +* AC10_EMPTY[4] - (RO) WMM1 AC0 queue empty status +* AC11_EMPTY[5] - (RO) WMM1 AC1 queue empty status +* AC12_EMPTY[6] - (RO) WMM1 AC2 queue empty status +* AC13_EMPTY[7] - (RO) WMM1 AC3 queue empty status +* AC20_EMPTY[8] - (RO) WMM2 AC0 queue empty status +* AC21_EMPTY[9] - (RO) WMM2 AC1 queue empty status +* AC22_EMPTY[10] - (RO) WMM2 AC2 queue empty status +* AC23_EMPTY[11] - (RO) WMM2 AC3 queue empty status +* AC30_EMPTY[12] - (RO) WMM3 AC0 queue empty status +* AC31_EMPTY[13] - (RO) WMM3 AC1 queue empty status +* AC32_EMPTY[14] - (RO) WMM3 AC2 queue empty status +* AC33_EMPTY[15] - (RO) WMM3 AC3 queue empty status +* ALTX_0_EMPTY[16] - (RO) ALTX queue 0 empty status +* BMC_0_EMPTY[17] - (RO) BMC queue 0 empty status +* BCN_0_EMPTY[18] - (RO) BCN queue 0 empty status +* PSMP_0_EMPTY[19] - (RO) PSMP queue 0 empty status +* ALTX_1_EMPTY[20] - (RO) ALTX queue 1 empty status +* BMC_1_EMPTY[21] - (RO) BMC queue 1 empty status +* BCN_1_EMPTY[22] - (RO) BCN queue 1 empty status +* PSMP_1_EMPTY[23] - (RO) PSMP queue 1 empty status +* NAF_EMPTY[24] - (RO) NAF queue empty status +* NBCN_EMPTY[25] - (RO) NBCN queue empty status +* RESERVED26[31..26] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_NBCN_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_NBCN_EMPTY_MASK \ + 0x02000000 /* NBCN_EMPTY[25] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_NBCN_EMPTY_SHFT 25 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_NAF_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_NAF_EMPTY_MASK 0x01000000 /* NAF_EMPTY[24] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_NAF_EMPTY_SHFT 24 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_PSMP_1_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_PSMP_1_EMPTY_MASK \ + 0x00800000 /* PSMP_1_EMPTY[23] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_PSMP_1_EMPTY_SHFT 23 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_BCN_1_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_BCN_1_EMPTY_MASK \ + 0x00400000 /* BCN_1_EMPTY[22] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_BCN_1_EMPTY_SHFT 22 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_BMC_1_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_BMC_1_EMPTY_MASK \ + 0x00200000 /* BMC_1_EMPTY[21] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_BMC_1_EMPTY_SHFT 21 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_ALTX_1_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_ALTX_1_EMPTY_MASK \ + 0x00100000 /* ALTX_1_EMPTY[20] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_ALTX_1_EMPTY_SHFT 20 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_PSMP_0_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_PSMP_0_EMPTY_MASK \ + 0x00080000 /* PSMP_0_EMPTY[19] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_PSMP_0_EMPTY_SHFT 19 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_BCN_0_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_BCN_0_EMPTY_MASK \ + 0x00040000 /* BCN_0_EMPTY[18] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_BCN_0_EMPTY_SHFT 18 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_BMC_0_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_BMC_0_EMPTY_MASK \ + 0x00020000 /* BMC_0_EMPTY[17] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_BMC_0_EMPTY_SHFT 17 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_ALTX_0_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_ALTX_0_EMPTY_MASK \ + 0x00010000 /* ALTX_0_EMPTY[16] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_ALTX_0_EMPTY_SHFT 16 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC33_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC33_EMPTY_MASK \ + 0x00008000 /* AC33_EMPTY[15] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC33_EMPTY_SHFT 15 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC32_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC32_EMPTY_MASK \ + 0x00004000 /* AC32_EMPTY[14] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC32_EMPTY_SHFT 14 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC31_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC31_EMPTY_MASK \ + 0x00002000 /* AC31_EMPTY[13] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC31_EMPTY_SHFT 13 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC30_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC30_EMPTY_MASK \ + 0x00001000 /* AC30_EMPTY[12] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC30_EMPTY_SHFT 12 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC23_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC23_EMPTY_MASK \ + 0x00000800 /* AC23_EMPTY[11] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC23_EMPTY_SHFT 11 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC22_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC22_EMPTY_MASK \ + 0x00000400 /* AC22_EMPTY[10] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC22_EMPTY_SHFT 10 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC21_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC21_EMPTY_MASK \ + 0x00000200 /* AC21_EMPTY[9] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC21_EMPTY_SHFT 9 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC20_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC20_EMPTY_MASK \ + 0x00000100 /* AC20_EMPTY[8] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC20_EMPTY_SHFT 8 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC13_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC13_EMPTY_MASK \ + 0x00000080 /* AC13_EMPTY[7] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC13_EMPTY_SHFT 7 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC12_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC12_EMPTY_MASK \ + 0x00000040 /* AC12_EMPTY[6] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC12_EMPTY_SHFT 6 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC11_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC11_EMPTY_MASK \ + 0x00000020 /* AC11_EMPTY[5] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC11_EMPTY_SHFT 5 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC10_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC10_EMPTY_MASK \ + 0x00000010 /* AC10_EMPTY[4] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC10_EMPTY_SHFT 4 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC03_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC03_EMPTY_MASK \ + 0x00000008 /* AC03_EMPTY[3] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC03_EMPTY_SHFT 3 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC02_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC02_EMPTY_MASK \ + 0x00000004 /* AC02_EMPTY[2] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC02_EMPTY_SHFT 2 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC01_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC01_EMPTY_MASK \ + 0x00000002 /* AC01_EMPTY[1] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC01_EMPTY_SHFT 1 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC00_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC00_EMPTY_MASK \ + 0x00000001 /* AC00_EMPTY[0] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC00_EMPTY_SHFT 0 + +/* +* ---NATIVE_TXD_QUEUE_EMPTY (0x820C0000 + 0x368)--- +* AC00_EMPTY[0] - (RO) WMM0 AC0 queue empty status +* AC01_EMPTY[1] - (RO) WMM0 AC1 queue empty status +* AC02_EMPTY[2] - (RO) WMM0 AC2 queue empty status +* AC03_EMPTY[3] - (RO) WMM0 AC3 queue empty status +* AC10_EMPTY[4] - (RO) WMM1 AC0 queue empty status +* AC11_EMPTY[5] - (RO) WMM1 AC1 queue empty status +* AC12_EMPTY[6] - (RO) WMM1 AC2 queue empty status +* AC13_EMPTY[7] - (RO) WMM1 AC3 queue empty status +* AC20_EMPTY[8] - (RO) WMM2 AC0 queue empty status +* AC21_EMPTY[9] - (RO) WMM2 AC1 queue empty status +* AC22_EMPTY[10] - (RO) WMM2 AC2 queue empty status +* AC23_EMPTY[11] - (RO) WMM2 AC3 queue empty status +* AC30_EMPTY[12] - (RO) WMM3 AC0 queue empty status +* AC31_EMPTY[13] - (RO) WMM3 AC1 queue empty status +* AC32_EMPTY[14] - (RO) WMM3 AC2 queue empty status +* AC33_EMPTY[15] - (RO) WMM3 AC3 queue empty status +* ALTX_0_EMPTY[16] - (RO) ALTX queue 0 empty status +* BMC_0_EMPTY[17] - (RO) BMC queue 0 empty status +* BCN_0_EMPTY[18] - (RO) BCN queue 0 empty status +* PSMP_0_EMPTY[19] - (RO) PSMP queue 0 empty status +* ALTX_1_EMPTY[20] - (RO) ALTX queue 1 empty status +* BMC_1_EMPTY[21] - (RO) BMC queue 1 empty status +* BCN_1_EMPTY[22] - (RO) BCN queue 1 empty status +* PSMP_1_EMPTY[23] - (RO) PSMP queue 1 empty status +* NAF_EMPTY[24] - (RO) NAF queue empty status +* NBCN_EMPTY[25] - (RO) NBCN queue empty status +* RESERVED26[31..26] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_NBCN_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_NBCN_EMPTY_MASK \ + 0x02000000 /* NBCN_EMPTY[25] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_NBCN_EMPTY_SHFT 25 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_NAF_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_NAF_EMPTY_MASK \ + 0x01000000 /* NAF_EMPTY[24] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_NAF_EMPTY_SHFT 24 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_PSMP_1_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_PSMP_1_EMPTY_MASK \ + 0x00800000 /* PSMP_1_EMPTY[23] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_PSMP_1_EMPTY_SHFT 23 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_BCN_1_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_BCN_1_EMPTY_MASK \ + 0x00400000 /* BCN_1_EMPTY[22] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_BCN_1_EMPTY_SHFT 22 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_BMC_1_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_BMC_1_EMPTY_MASK \ + 0x00200000 /* BMC_1_EMPTY[21] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_BMC_1_EMPTY_SHFT 21 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ALTX_1_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ALTX_1_EMPTY_MASK \ + 0x00100000 /* ALTX_1_EMPTY[20] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ALTX_1_EMPTY_SHFT 20 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_PSMP_0_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_PSMP_0_EMPTY_MASK \ + 0x00080000 /* PSMP_0_EMPTY[19] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_PSMP_0_EMPTY_SHFT 19 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_BCN_0_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_BCN_0_EMPTY_MASK \ + 0x00040000 /* BCN_0_EMPTY[18] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_BCN_0_EMPTY_SHFT 18 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_BMC_0_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_BMC_0_EMPTY_MASK \ + 0x00020000 /* BMC_0_EMPTY[17] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_BMC_0_EMPTY_SHFT 17 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ALTX_0_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ALTX_0_EMPTY_MASK \ + 0x00010000 /* ALTX_0_EMPTY[16] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ALTX_0_EMPTY_SHFT 16 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC33_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC33_EMPTY_MASK \ + 0x00008000 /* AC33_EMPTY[15] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC33_EMPTY_SHFT 15 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC32_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC32_EMPTY_MASK \ + 0x00004000 /* AC32_EMPTY[14] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC32_EMPTY_SHFT 14 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC31_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC31_EMPTY_MASK \ + 0x00002000 /* AC31_EMPTY[13] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC31_EMPTY_SHFT 13 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC30_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC30_EMPTY_MASK \ + 0x00001000 /* AC30_EMPTY[12] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC30_EMPTY_SHFT 12 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC23_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC23_EMPTY_MASK \ + 0x00000800 /* AC23_EMPTY[11] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC23_EMPTY_SHFT 11 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC22_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC22_EMPTY_MASK \ + 0x00000400 /* AC22_EMPTY[10] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC22_EMPTY_SHFT 10 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC21_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC21_EMPTY_MASK \ + 0x00000200 /* AC21_EMPTY[9] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC21_EMPTY_SHFT 9 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC20_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC20_EMPTY_MASK \ + 0x00000100 /* AC20_EMPTY[8] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC20_EMPTY_SHFT 8 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC13_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC13_EMPTY_MASK \ + 0x00000080 /* AC13_EMPTY[7] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC13_EMPTY_SHFT 7 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC12_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC12_EMPTY_MASK \ + 0x00000040 /* AC12_EMPTY[6] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC12_EMPTY_SHFT 6 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC11_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC11_EMPTY_MASK \ + 0x00000020 /* AC11_EMPTY[5] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC11_EMPTY_SHFT 5 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC10_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC10_EMPTY_MASK \ + 0x00000010 /* AC10_EMPTY[4] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC10_EMPTY_SHFT 4 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC03_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC03_EMPTY_MASK \ + 0x00000008 /* AC03_EMPTY[3] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC03_EMPTY_SHFT 3 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC02_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC02_EMPTY_MASK \ + 0x00000004 /* AC02_EMPTY[2] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC02_EMPTY_SHFT 2 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC01_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC01_EMPTY_MASK \ + 0x00000002 /* AC01_EMPTY[1] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC01_EMPTY_SHFT 1 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC00_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC00_EMPTY_MASK \ + 0x00000001 /* AC00_EMPTY[0] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC00_EMPTY_SHFT 0 + +/* +* ---DRR_CHNL_EMPTY (0x820C0000 + 0x374)--- +* WMM_STA_DL_EMPTY[15..0] - (RO) Indicate emptiness of 16 DL station link +* WMM_STA_UL_EMPTY[31..16] - (RO) Indicate emptiness of 16 UL station link +*/ +#define WF_PLE_TOP_DRR_CHNL_EMPTY_WMM_STA_UL_EMPTY_ADDR \ + WF_PLE_TOP_DRR_CHNL_EMPTY_ADDR +#define WF_PLE_TOP_DRR_CHNL_EMPTY_WMM_STA_UL_EMPTY_MASK \ + 0xFFFF0000 /* WMM_STA_UL_EMPTY[31..16] */ +#define WF_PLE_TOP_DRR_CHNL_EMPTY_WMM_STA_UL_EMPTY_SHFT 16 +#define WF_PLE_TOP_DRR_CHNL_EMPTY_WMM_STA_DL_EMPTY_ADDR \ + WF_PLE_TOP_DRR_CHNL_EMPTY_ADDR +#define WF_PLE_TOP_DRR_CHNL_EMPTY_WMM_STA_DL_EMPTY_MASK \ + 0x0000FFFF /* WMM_STA_DL_EMPTY[15..0] */ +#define WF_PLE_TOP_DRR_CHNL_EMPTY_WMM_STA_DL_EMPTY_SHFT 0 + +/* +* ---FREEPG_CNT (0x820C0000 + 0x380)--- +* FREEPG_CNT[11..0] - (RO) Total page number of free +* RESERVED12[15..12] - (RO) Reserved bits +* FFA_CNT[27..16] - (RO) Free page numbers of free for all +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_FREEPG_CNT_FFA_CNT_ADDR WF_PLE_TOP_FREEPG_CNT_ADDR +#define WF_PLE_TOP_FREEPG_CNT_FFA_CNT_MASK 0x0FFF0000 /* FFA_CNT[27..16] */ +#define WF_PLE_TOP_FREEPG_CNT_FFA_CNT_SHFT 16 +#define WF_PLE_TOP_FREEPG_CNT_FREEPG_CNT_ADDR WF_PLE_TOP_FREEPG_CNT_ADDR +#define WF_PLE_TOP_FREEPG_CNT_FREEPG_CNT_MASK 0x00000FFF /* FREEPG_CNT[11..0] */ +#define WF_PLE_TOP_FREEPG_CNT_FREEPG_CNT_SHFT 0 + +/* +* ---FREEPG_HEAD_TAIL (0x820C0000 + 0x384)--- +* FREEPG_HEAD[11..0] - (RO) Head page of free page list +* RESERVED12[15..12] - (RO) Reserved bits +* FREEPG_TAIL[27..16] - (RO) Tail page of free page list +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_FREEPG_HEAD_TAIL_FREEPG_TAIL_ADDR \ + WF_PLE_TOP_FREEPG_HEAD_TAIL_ADDR +#define WF_PLE_TOP_FREEPG_HEAD_TAIL_FREEPG_TAIL_MASK \ + 0x0FFF0000 /* FREEPG_TAIL[27..16] */ +#define WF_PLE_TOP_FREEPG_HEAD_TAIL_FREEPG_TAIL_SHFT 16 +#define WF_PLE_TOP_FREEPG_HEAD_TAIL_FREEPG_HEAD_ADDR \ + WF_PLE_TOP_FREEPG_HEAD_TAIL_ADDR +#define WF_PLE_TOP_FREEPG_HEAD_TAIL_FREEPG_HEAD_MASK \ + 0x00000FFF /* FREEPG_HEAD[11..0] */ +#define WF_PLE_TOP_FREEPG_HEAD_TAIL_FREEPG_HEAD_SHFT 0 + +/* +* ---HIF_PG_INFO (0x820C0000 + 0x388)--- +* HIF_RSV_CNT[11..0] - (RO) Reserved pages of HIF group +* RESERVED12[15..12] - (RO) Reserved bits +* HIF_SRC_CNT[27..16] - (RO) Used pages of HIF group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_HIF_PG_INFO_HIF_SRC_CNT_ADDR WF_PLE_TOP_HIF_PG_INFO_ADDR +#define WF_PLE_TOP_HIF_PG_INFO_HIF_SRC_CNT_MASK \ + 0x0FFF0000 /* HIF_SRC_CNT[27..16] */ +#define WF_PLE_TOP_HIF_PG_INFO_HIF_SRC_CNT_SHFT 16 +#define WF_PLE_TOP_HIF_PG_INFO_HIF_RSV_CNT_ADDR WF_PLE_TOP_HIF_PG_INFO_ADDR +#define WF_PLE_TOP_HIF_PG_INFO_HIF_RSV_CNT_MASK \ + 0x00000FFF /* HIF_RSV_CNT[11..0] */ +#define WF_PLE_TOP_HIF_PG_INFO_HIF_RSV_CNT_SHFT 0 + +/* +* ---HIF_WMTXD_PG_INFO (0x820C0000 + 0x38c)--- +* HIF_WMTXD_RSV_CNT[11..0] - (RO) Reserved pages of HIF WMCPU TXD group +* RESERVED12[15..12] - (RO) Reserved bits +* HIF_WMTXD_SRC_CNT[27..16] - (RO) Used pages of HIF WMCPU TXD group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_HIF_WMTXD_PG_INFO_HIF_WMTXD_SRC_CNT_ADDR \ + WF_PLE_TOP_HIF_WMTXD_PG_INFO_ADDR +#define WF_PLE_TOP_HIF_WMTXD_PG_INFO_HIF_WMTXD_SRC_CNT_MASK \ + 0x0FFF0000 /* HIF_WMTXD_SRC_CNT[27..16] */ +#define WF_PLE_TOP_HIF_WMTXD_PG_INFO_HIF_WMTXD_SRC_CNT_SHFT 16 +#define WF_PLE_TOP_HIF_WMTXD_PG_INFO_HIF_WMTXD_RSV_CNT_ADDR \ + WF_PLE_TOP_HIF_WMTXD_PG_INFO_ADDR +#define WF_PLE_TOP_HIF_WMTXD_PG_INFO_HIF_WMTXD_RSV_CNT_MASK \ + 0x00000FFF /* HIF_WMTXD_RSV_CNT[11..0] */ +#define WF_PLE_TOP_HIF_WMTXD_PG_INFO_HIF_WMTXD_RSV_CNT_SHFT 0 + +/* +* ---HIF_TXCMD_PG_INFO (0x820C0000 + 0x390)--- +* HIF_TXCMD_RSV_CNT[11..0] - (RO) Reserved pages of HIF TXCMD group +* RESERVED12[15..12] - (RO) Reserved bits +* HIF_TXCMD_SRC_CNT[27..16] - (RO) Used pages of HIF TXCMD group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_HIF_TXCMD_PG_INFO_HIF_TXCMD_SRC_CNT_ADDR \ + WF_PLE_TOP_HIF_TXCMD_PG_INFO_ADDR +#define WF_PLE_TOP_HIF_TXCMD_PG_INFO_HIF_TXCMD_SRC_CNT_MASK \ + 0x0FFF0000 /* HIF_TXCMD_SRC_CNT[27..16] */ +#define WF_PLE_TOP_HIF_TXCMD_PG_INFO_HIF_TXCMD_SRC_CNT_SHFT 16 +#define WF_PLE_TOP_HIF_TXCMD_PG_INFO_HIF_TXCMD_RSV_CNT_ADDR \ + WF_PLE_TOP_HIF_TXCMD_PG_INFO_ADDR +#define WF_PLE_TOP_HIF_TXCMD_PG_INFO_HIF_TXCMD_RSV_CNT_MASK \ + 0x00000FFF /* HIF_TXCMD_RSV_CNT[11..0] */ +#define WF_PLE_TOP_HIF_TXCMD_PG_INFO_HIF_TXCMD_RSV_CNT_SHFT 0 + +/* +* ---CPU_PG_INFO (0x820C0000 + 0x394)--- +* CPU_RSV_CNT[11..0] - (RO) Reserved pages of CPU group +* RESERVED12[15..12] - (RO) Reserved bits +* CPU_SRC_CNT[27..16] - (RO) Used pages of CPU group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_CPU_PG_INFO_CPU_SRC_CNT_ADDR WF_PLE_TOP_CPU_PG_INFO_ADDR +#define WF_PLE_TOP_CPU_PG_INFO_CPU_SRC_CNT_MASK \ + 0x0FFF0000 /* CPU_SRC_CNT[27..16] */ +#define WF_PLE_TOP_CPU_PG_INFO_CPU_SRC_CNT_SHFT 16 +#define WF_PLE_TOP_CPU_PG_INFO_CPU_RSV_CNT_ADDR WF_PLE_TOP_CPU_PG_INFO_ADDR +#define WF_PLE_TOP_CPU_PG_INFO_CPU_RSV_CNT_MASK \ + 0x00000FFF /* CPU_RSV_CNT[11..0] */ +#define WF_PLE_TOP_CPU_PG_INFO_CPU_RSV_CNT_SHFT 0 + +/* +* ---PLE_LOG_0 (0x820C0000 + 0x3a0)--- +* PLE_LOG_0[31..0] - (RW) Log message for SW +*/ +#define WF_PLE_TOP_PLE_LOG_0_PLE_LOG_0_ADDR WF_PLE_TOP_PLE_LOG_0_ADDR +#define WF_PLE_TOP_PLE_LOG_0_PLE_LOG_0_MASK 0xFFFFFFFF /* PLE_LOG_0[31..0] */ +#define WF_PLE_TOP_PLE_LOG_0_PLE_LOG_0_SHFT 0 + +/* +* ---PLE_LOG_1 (0x820C0000 + 0x3a4)--- +* PLE_LOG_1[31..0] - (RW) Log message for SW +*/ +#define WF_PLE_TOP_PLE_LOG_1_PLE_LOG_1_ADDR WF_PLE_TOP_PLE_LOG_1_ADDR +#define WF_PLE_TOP_PLE_LOG_1_PLE_LOG_1_MASK 0xFFFFFFFF /* PLE_LOG_1[31..0] */ +#define WF_PLE_TOP_PLE_LOG_1_PLE_LOG_1_SHFT 0 + +/* +* ---PLE_LOG_2 (0x820C0000 + 0x3a8)--- +* PLE_LOG_2[31..0] - (RW) Log message for SW +*/ +#define WF_PLE_TOP_PLE_LOG_2_PLE_LOG_2_ADDR WF_PLE_TOP_PLE_LOG_2_ADDR +#define WF_PLE_TOP_PLE_LOG_2_PLE_LOG_2_MASK 0xFFFFFFFF /* PLE_LOG_2[31..0] */ +#define WF_PLE_TOP_PLE_LOG_2_PLE_LOG_2_SHFT 0 + +/* +* ---PLE_LOG_3 (0x820C0000 + 0x3ac)--- +* PLE_LOG_3[31..0] - (RW) Log message for SW +*/ +#define WF_PLE_TOP_PLE_LOG_3_PLE_LOG_3_ADDR WF_PLE_TOP_PLE_LOG_3_ADDR +#define WF_PLE_TOP_PLE_LOG_3_PLE_LOG_3_MASK 0xFFFFFFFF /* PLE_LOG_3[31..0] */ +#define WF_PLE_TOP_PLE_LOG_3_PLE_LOG_3_SHFT 0 + +/* +* ---WMMAC_PGCNT_0 (0x820C0000 + 0x3b0)--- +* WMMAC_00_PGCNT[11..0] - (RO) WMMAC 00 used page count +* RESERVED12[15..12] - (RO) Reserved bits +* WMMAC_01_PGCNT[27..16] - (RO) WMMAC 01 used page count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_WMMAC_PGCNT_0_WMMAC_01_PGCNT_ADDR \ + WF_PLE_TOP_WMMAC_PGCNT_0_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_0_WMMAC_01_PGCNT_MASK \ + 0x0FFF0000 /* WMMAC_01_PGCNT[27..16] */ +#define WF_PLE_TOP_WMMAC_PGCNT_0_WMMAC_01_PGCNT_SHFT 16 +#define WF_PLE_TOP_WMMAC_PGCNT_0_WMMAC_00_PGCNT_ADDR \ + WF_PLE_TOP_WMMAC_PGCNT_0_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_0_WMMAC_00_PGCNT_MASK \ + 0x00000FFF /* WMMAC_00_PGCNT[11..0] */ +#define WF_PLE_TOP_WMMAC_PGCNT_0_WMMAC_00_PGCNT_SHFT 0 + +/* +* ---WMMAC_PGCNT_1 (0x820C0000 + 0x3b4)--- +* WMMAC_02_PGCNT[11..0] - (RO) WMMAC 02 used page count +* RESERVED12[15..12] - (RO) Reserved bits +* WMMAC_03_PGCNT[27..16] - (RO) WMMAC 03 used page count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_WMMAC_PGCNT_1_WMMAC_03_PGCNT_ADDR \ + WF_PLE_TOP_WMMAC_PGCNT_1_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_1_WMMAC_03_PGCNT_MASK \ + 0x0FFF0000 /* WMMAC_03_PGCNT[27..16] */ +#define WF_PLE_TOP_WMMAC_PGCNT_1_WMMAC_03_PGCNT_SHFT 16 +#define WF_PLE_TOP_WMMAC_PGCNT_1_WMMAC_02_PGCNT_ADDR \ + WF_PLE_TOP_WMMAC_PGCNT_1_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_1_WMMAC_02_PGCNT_MASK \ + 0x00000FFF /* WMMAC_02_PGCNT[11..0] */ +#define WF_PLE_TOP_WMMAC_PGCNT_1_WMMAC_02_PGCNT_SHFT 0 + +/* +* ---WMMAC_PGCNT_2 (0x820C0000 + 0x3b8)--- +* WMMAC_10_PGCNT[11..0] - (RO) WMMAC 10 used page count +* RESERVED12[15..12] - (RO) Reserved bits +* WMMAC_11_PGCNT[27..16] - (RO) WMMAC 11 used page count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_WMMAC_PGCNT_2_WMMAC_11_PGCNT_ADDR \ + WF_PLE_TOP_WMMAC_PGCNT_2_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_2_WMMAC_11_PGCNT_MASK \ + 0x0FFF0000 /* WMMAC_11_PGCNT[27..16] */ +#define WF_PLE_TOP_WMMAC_PGCNT_2_WMMAC_11_PGCNT_SHFT 16 +#define WF_PLE_TOP_WMMAC_PGCNT_2_WMMAC_10_PGCNT_ADDR \ + WF_PLE_TOP_WMMAC_PGCNT_2_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_2_WMMAC_10_PGCNT_MASK \ + 0x00000FFF /* WMMAC_10_PGCNT[11..0] */ +#define WF_PLE_TOP_WMMAC_PGCNT_2_WMMAC_10_PGCNT_SHFT 0 + +/* +* ---WMMAC_PGCNT_3 (0x820C0000 + 0x3bc)--- +* WMMAC_12_PGCNT[11..0] - (RO) WMMAC 12 used page count +* RESERVED12[15..12] - (RO) Reserved bits +* WMMAC_13_PGCNT[27..16] - (RO) WMMAC 13 used page count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_WMMAC_PGCNT_3_WMMAC_13_PGCNT_ADDR \ + WF_PLE_TOP_WMMAC_PGCNT_3_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_3_WMMAC_13_PGCNT_MASK \ + 0x0FFF0000 /* WMMAC_13_PGCNT[27..16] */ +#define WF_PLE_TOP_WMMAC_PGCNT_3_WMMAC_13_PGCNT_SHFT 16 +#define WF_PLE_TOP_WMMAC_PGCNT_3_WMMAC_12_PGCNT_ADDR \ + WF_PLE_TOP_WMMAC_PGCNT_3_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_3_WMMAC_12_PGCNT_MASK \ + 0x00000FFF /* WMMAC_12_PGCNT[11..0] */ +#define WF_PLE_TOP_WMMAC_PGCNT_3_WMMAC_12_PGCNT_SHFT 0 + +/* +* ---WMMAC_PGCNT_4 (0x820C0000 + 0x3c0)--- +* WMMAC_20_PGCNT[11..0] - (RO) WMMAC 20 used page count +* RESERVED12[15..12] - (RO) Reserved bits +* WMMAC_21_PGCNT[27..16] - (RO) WMMAC 21 used page count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_WMMAC_PGCNT_4_WMMAC_21_PGCNT_ADDR \ + WF_PLE_TOP_WMMAC_PGCNT_4_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_4_WMMAC_21_PGCNT_MASK \ + 0x0FFF0000 /* WMMAC_21_PGCNT[27..16] */ +#define WF_PLE_TOP_WMMAC_PGCNT_4_WMMAC_21_PGCNT_SHFT 16 +#define WF_PLE_TOP_WMMAC_PGCNT_4_WMMAC_20_PGCNT_ADDR \ + WF_PLE_TOP_WMMAC_PGCNT_4_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_4_WMMAC_20_PGCNT_MASK \ + 0x00000FFF /* WMMAC_20_PGCNT[11..0] */ +#define WF_PLE_TOP_WMMAC_PGCNT_4_WMMAC_20_PGCNT_SHFT 0 + +/* +* ---WMMAC_PGCNT_5 (0x820C0000 + 0x3c4)--- +* WMMAC_22_PGCNT[11..0] - (RO) WMMAC 22 used page count +* RESERVED12[15..12] - (RO) Reserved bits +* WMMAC_23_PGCNT[27..16] - (RO) WMMAC 23 used page count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_WMMAC_PGCNT_5_WMMAC_23_PGCNT_ADDR \ + WF_PLE_TOP_WMMAC_PGCNT_5_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_5_WMMAC_23_PGCNT_MASK \ + 0x0FFF0000 /* WMMAC_23_PGCNT[27..16] */ +#define WF_PLE_TOP_WMMAC_PGCNT_5_WMMAC_23_PGCNT_SHFT 16 +#define WF_PLE_TOP_WMMAC_PGCNT_5_WMMAC_22_PGCNT_ADDR \ + WF_PLE_TOP_WMMAC_PGCNT_5_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_5_WMMAC_22_PGCNT_MASK \ + 0x00000FFF /* WMMAC_22_PGCNT[11..0] */ +#define WF_PLE_TOP_WMMAC_PGCNT_5_WMMAC_22_PGCNT_SHFT 0 + +/* +* ---WMMAC_PGCNT_6 (0x820C0000 + 0x3c8)--- +* WMMAC_30_PGCNT[11..0] - (RO) WMMAC 30 used page count +* RESERVED12[15..12] - (RO) Reserved bits +* WMMAC_31_PGCNT[27..16] - (RO) WMMAC 31 used page count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_WMMAC_PGCNT_6_WMMAC_31_PGCNT_ADDR \ + WF_PLE_TOP_WMMAC_PGCNT_6_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_6_WMMAC_31_PGCNT_MASK \ + 0x0FFF0000 /* WMMAC_31_PGCNT[27..16] */ +#define WF_PLE_TOP_WMMAC_PGCNT_6_WMMAC_31_PGCNT_SHFT 16 +#define WF_PLE_TOP_WMMAC_PGCNT_6_WMMAC_30_PGCNT_ADDR \ + WF_PLE_TOP_WMMAC_PGCNT_6_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_6_WMMAC_30_PGCNT_MASK \ + 0x00000FFF /* WMMAC_30_PGCNT[11..0] */ +#define WF_PLE_TOP_WMMAC_PGCNT_6_WMMAC_30_PGCNT_SHFT 0 + +/* +* ---WMMAC_PGCNT_7 (0x820C0000 + 0x3cc)--- +* WMMAC_32_PGCNT[11..0] - (RO) WMMAC 32 used page count +* RESERVED12[15..12] - (RO) Reserved bits +* WMMAC_33_PGCNT[27..16] - (RO) WMMAC 33 used page count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_WMMAC_PGCNT_7_WMMAC_33_PGCNT_ADDR \ + WF_PLE_TOP_WMMAC_PGCNT_7_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_7_WMMAC_33_PGCNT_MASK \ + 0x0FFF0000 /* WMMAC_33_PGCNT[27..16] */ +#define WF_PLE_TOP_WMMAC_PGCNT_7_WMMAC_33_PGCNT_SHFT 16 +#define WF_PLE_TOP_WMMAC_PGCNT_7_WMMAC_32_PGCNT_ADDR \ + WF_PLE_TOP_WMMAC_PGCNT_7_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_7_WMMAC_32_PGCNT_MASK \ + 0x00000FFF /* WMMAC_32_PGCNT[11..0] */ +#define WF_PLE_TOP_WMMAC_PGCNT_7_WMMAC_32_PGCNT_SHFT 0 + +/* +* ---RL_BUF_CTRL_0 (0x820C0000 + 0x3d0)--- +* RELAY_BUF_ADDR[11..0] - (RW) Read address of relay buffer +* RESERVED12[30..12] - (RO) Reserved bits +* EXECUTE[31] - (A0) Executes relay buffer read command +*/ +#define WF_PLE_TOP_RL_BUF_CTRL_0_EXECUTE_ADDR WF_PLE_TOP_RL_BUF_CTRL_0_ADDR +#define WF_PLE_TOP_RL_BUF_CTRL_0_EXECUTE_MASK 0x80000000 /* EXECUTE[31] */ +#define WF_PLE_TOP_RL_BUF_CTRL_0_EXECUTE_SHFT 31 +#define WF_PLE_TOP_RL_BUF_CTRL_0_RELAY_BUF_ADDR_ADDR \ + WF_PLE_TOP_RL_BUF_CTRL_0_ADDR +#define WF_PLE_TOP_RL_BUF_CTRL_0_RELAY_BUF_ADDR_MASK \ + 0x00000FFF /* RELAY_BUF_ADDR[11..0] */ +#define WF_PLE_TOP_RL_BUF_CTRL_0_RELAY_BUF_ADDR_SHFT 0 + +/* +* ---RL_BUF_CTRL_1 (0x820C0000 + 0x3d4)--- +* PAGE_NUM_0[0] - (RO) Page number[0] of packet +* PKT_LEN[11..1] - (RO) Length of the packet with head page +* being the relay buffer address +* Unit: 32 bytes +* PKT_TAIL_PAGE[23..12] - (RO) Tail page of the packet with head page +* being the relay buffer address +* RESV_GRP_ID[24] - (RO) Group ID of reserved page used by FID +* RESERVED25[25] - (RO) Reserved bits +* PAGE_NUM_1[27..26] - (RO) Page number[2:1] of packet +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_RL_BUF_CTRL_1_PAGE_NUM_1_ADDR WF_PLE_TOP_RL_BUF_CTRL_1_ADDR +#define WF_PLE_TOP_RL_BUF_CTRL_1_PAGE_NUM_1_MASK \ + 0x0C000000 /* PAGE_NUM_1[27..26] */ +#define WF_PLE_TOP_RL_BUF_CTRL_1_PAGE_NUM_1_SHFT 26 +#define WF_PLE_TOP_RL_BUF_CTRL_1_RESV_GRP_ID_ADDR WF_PLE_TOP_RL_BUF_CTRL_1_ADDR +#define WF_PLE_TOP_RL_BUF_CTRL_1_RESV_GRP_ID_MASK \ + 0x01000000 /* RESV_GRP_ID[24] */ +#define WF_PLE_TOP_RL_BUF_CTRL_1_RESV_GRP_ID_SHFT 24 +#define WF_PLE_TOP_RL_BUF_CTRL_1_PKT_TAIL_PAGE_ADDR \ + WF_PLE_TOP_RL_BUF_CTRL_1_ADDR +#define WF_PLE_TOP_RL_BUF_CTRL_1_PKT_TAIL_PAGE_MASK \ + 0x00FFF000 /* PKT_TAIL_PAGE[23..12] */ +#define WF_PLE_TOP_RL_BUF_CTRL_1_PKT_TAIL_PAGE_SHFT 12 +#define WF_PLE_TOP_RL_BUF_CTRL_1_PKT_LEN_ADDR WF_PLE_TOP_RL_BUF_CTRL_1_ADDR +#define WF_PLE_TOP_RL_BUF_CTRL_1_PKT_LEN_MASK 0x00000FFE /* PKT_LEN[11..1] */ +#define WF_PLE_TOP_RL_BUF_CTRL_1_PKT_LEN_SHFT 1 +#define WF_PLE_TOP_RL_BUF_CTRL_1_PAGE_NUM_0_ADDR WF_PLE_TOP_RL_BUF_CTRL_1_ADDR +#define WF_PLE_TOP_RL_BUF_CTRL_1_PAGE_NUM_0_MASK 0x00000001 /* PAGE_NUM_0[0] */ +#define WF_PLE_TOP_RL_BUF_CTRL_1_PAGE_NUM_0_SHFT 0 + +/* +* ---FL_QUE_CTRL_0 (0x820C0000 + 0x3e0)--- +* Q_BUF_WLANID[9..0] - (RW) Address of queue structure buffer +WLANID. +* Q_BUF_PID[11..10] - (RW) Address of queue structure buffer PID +* FL_BUFFER_ADDR[23..12] - (RW) Frame address of read previous +* frame/next frame +* Q_BUF_QID[30..24] - (RW) Address of queue structure buffer QID +* EXECUTE[31] - (A0) Executes frame link and queue structure +* buffer read command +*/ +#define WF_PLE_TOP_FL_QUE_CTRL_0_EXECUTE_ADDR WF_PLE_TOP_FL_QUE_CTRL_0_ADDR +#define WF_PLE_TOP_FL_QUE_CTRL_0_EXECUTE_MASK 0x80000000 /* EXECUTE[31] */ +#define WF_PLE_TOP_FL_QUE_CTRL_0_EXECUTE_SHFT 31 +#define WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_QID_ADDR WF_PLE_TOP_FL_QUE_CTRL_0_ADDR +#define WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_QID_MASK \ + 0x7F000000 /* Q_BUF_QID[30..24] */ +#define WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_QID_SHFT 24 +#define WF_PLE_TOP_FL_QUE_CTRL_0_FL_BUFFER_ADDR_ADDR \ + WF_PLE_TOP_FL_QUE_CTRL_0_ADDR +#define WF_PLE_TOP_FL_QUE_CTRL_0_FL_BUFFER_ADDR_MASK \ + 0x00FFF000 /* FL_BUFFER_ADDR[23..12] */ +#define WF_PLE_TOP_FL_QUE_CTRL_0_FL_BUFFER_ADDR_SHFT 12 +#define WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_PID_ADDR WF_PLE_TOP_FL_QUE_CTRL_0_ADDR +#define WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_PID_MASK \ + 0x00000C00 /* Q_BUF_PID[11..10] */ +#define WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_PID_SHFT 10 +#define WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_WLANID_ADDR WF_PLE_TOP_FL_QUE_CTRL_0_ADDR +#define WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_WLANID_MASK \ + 0x000003FF /* Q_BUF_WLANID[9..0] */ +#define WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_WLANID_SHFT 0 + +/* +* ---FL_QUE_CTRL_1 (0x820C0000 + 0x3e4)--- +* NEXT_FID[11..0] - (RO) Next frame ID of FL_BUFFER_ADDR +* RESERVED12[15..12] - (RO) Reserved bits +* PREV_FID[27..16] - (RO) Previous frame ID of FL_BUFFER_ADDR +* RESERVED28[30..28] - (RO) Reserved bits +* Q_BUF_TGID[31] - (RW) Address of queue structure buffer TGID +*/ +#define WF_PLE_TOP_FL_QUE_CTRL_1_Q_BUF_TGID_ADDR WF_PLE_TOP_FL_QUE_CTRL_1_ADDR +#define WF_PLE_TOP_FL_QUE_CTRL_1_Q_BUF_TGID_MASK 0x80000000 /* Q_BUF_TGID[31] */ +#define WF_PLE_TOP_FL_QUE_CTRL_1_Q_BUF_TGID_SHFT 31 +#define WF_PLE_TOP_FL_QUE_CTRL_1_PREV_FID_ADDR WF_PLE_TOP_FL_QUE_CTRL_1_ADDR +#define WF_PLE_TOP_FL_QUE_CTRL_1_PREV_FID_MASK 0x0FFF0000 /* PREV_FID[27..16] */ +#define WF_PLE_TOP_FL_QUE_CTRL_1_PREV_FID_SHFT 16 +#define WF_PLE_TOP_FL_QUE_CTRL_1_NEXT_FID_ADDR WF_PLE_TOP_FL_QUE_CTRL_1_ADDR +#define WF_PLE_TOP_FL_QUE_CTRL_1_NEXT_FID_MASK 0x00000FFF /* NEXT_FID[11..0] */ +#define WF_PLE_TOP_FL_QUE_CTRL_1_NEXT_FID_SHFT 0 + +/* +* ---FL_QUE_CTRL_2 (0x820C0000 + 0x3e8)--- +* QUEUE_HEAD_FID[11..0] - (RO) Head frame ID of the quest queue setting +* in 0x01b0[15:0] +* RESERVED12[15..12] - (RO) Reserved bits +* QUEUE_TAIL_FID[27..16] - (RO) Tail frame ID of the quest queue setting +* in 0x01b0[15:0] +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_TAIL_FID_ADDR \ + WF_PLE_TOP_FL_QUE_CTRL_2_ADDR +#define WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_TAIL_FID_MASK \ + 0x0FFF0000 /* QUEUE_TAIL_FID[27..16] */ +#define WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_TAIL_FID_SHFT 16 +#define WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_HEAD_FID_ADDR \ + WF_PLE_TOP_FL_QUE_CTRL_2_ADDR +#define WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_HEAD_FID_MASK \ + 0x00000FFF /* QUEUE_HEAD_FID[11..0] */ +#define WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_HEAD_FID_SHFT 0 + +/* +* ---FL_QUE_CTRL_3 (0x820C0000 + 0x3ec)--- +* QUEUE_PKT_NUM[11..0] - (RO) Total packet number of the queue +* setting in 0x1b0[15:0] +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_FL_QUE_CTRL_3_QUEUE_PKT_NUM_ADDR \ + WF_PLE_TOP_FL_QUE_CTRL_3_ADDR +#define WF_PLE_TOP_FL_QUE_CTRL_3_QUEUE_PKT_NUM_MASK \ + 0x00000FFF /* QUEUE_PKT_NUM[11..0] */ +#define WF_PLE_TOP_FL_QUE_CTRL_3_QUEUE_PKT_NUM_SHFT 0 + +/* +* ---PL_QUE_CTRL_0 (0x820C0000 + 0x3f0)--- +* NEXT_PAGE[11..0] - (RO) Next page of PL_BUFFER_ADDR +* RESERVED12[15..12] - (RO) Reserved bits +* PL_BUFFER_ADDR[27..16] - (RW) Page address of read next page +* RESERVED28[30..28] - (RO) Reserved bits +* EXECUTE[31] - (A0) Executes page link buffer read command +*/ +#define WF_PLE_TOP_PL_QUE_CTRL_0_EXECUTE_ADDR WF_PLE_TOP_PL_QUE_CTRL_0_ADDR +#define WF_PLE_TOP_PL_QUE_CTRL_0_EXECUTE_MASK 0x80000000 /* EXECUTE[31] */ +#define WF_PLE_TOP_PL_QUE_CTRL_0_EXECUTE_SHFT 31 +#define WF_PLE_TOP_PL_QUE_CTRL_0_PL_BUFFER_ADDR_ADDR \ + WF_PLE_TOP_PL_QUE_CTRL_0_ADDR +#define WF_PLE_TOP_PL_QUE_CTRL_0_PL_BUFFER_ADDR_MASK \ + 0x0FFF0000 /* PL_BUFFER_ADDR[27..16] */ +#define WF_PLE_TOP_PL_QUE_CTRL_0_PL_BUFFER_ADDR_SHFT 16 +#define WF_PLE_TOP_PL_QUE_CTRL_0_NEXT_PAGE_ADDR WF_PLE_TOP_PL_QUE_CTRL_0_ADDR +#define WF_PLE_TOP_PL_QUE_CTRL_0_NEXT_PAGE_MASK \ + 0x00000FFF /* NEXT_PAGE[11..0] */ +#define WF_PLE_TOP_PL_QUE_CTRL_0_NEXT_PAGE_SHFT 0 + +/* +* ---HIF_ENQ_PKT_NUM (0x820C0000 + 0x400)--- +* HIF_ENQ_CPU_PKT_NUM[15..0] - (RO) Packet number of HIF enqueue to CPU, +* just keep in 16bits. +* HIF_ENQ_LMAC_PKT_NUM[31..16] - (RO) Packet number of HIF enqueue to LMAC, +* just keep in 16 bits +*/ +#define WF_PLE_TOP_HIF_ENQ_PKT_NUM_HIF_ENQ_LMAC_PKT_NUM_ADDR \ + WF_PLE_TOP_HIF_ENQ_PKT_NUM_ADDR +#define WF_PLE_TOP_HIF_ENQ_PKT_NUM_HIF_ENQ_LMAC_PKT_NUM_MASK \ + 0xFFFF0000 /* HIF_ENQ_LMAC_PKT_NUM[31..16] */ +#define WF_PLE_TOP_HIF_ENQ_PKT_NUM_HIF_ENQ_LMAC_PKT_NUM_SHFT 16 +#define WF_PLE_TOP_HIF_ENQ_PKT_NUM_HIF_ENQ_CPU_PKT_NUM_ADDR \ + WF_PLE_TOP_HIF_ENQ_PKT_NUM_ADDR +#define WF_PLE_TOP_HIF_ENQ_PKT_NUM_HIF_ENQ_CPU_PKT_NUM_MASK \ + 0x0000FFFF /* HIF_ENQ_CPU_PKT_NUM[15..0] */ +#define WF_PLE_TOP_HIF_ENQ_PKT_NUM_HIF_ENQ_CPU_PKT_NUM_SHFT 0 + +/* +* ---CPU_ENQ_PKT_NUM (0x820C0000 + 0x404)--- +* CPU_ENQ_LMAC_PKT_NUM[15..0] - (RO) Packet number of CPU enqueue to LMAC, +* just keep in 16 bits. +* RESV[31..16] - (RO) Reserved +*/ +#define WF_PLE_TOP_CPU_ENQ_PKT_NUM_RESV_ADDR WF_PLE_TOP_CPU_ENQ_PKT_NUM_ADDR +#define WF_PLE_TOP_CPU_ENQ_PKT_NUM_RESV_MASK 0xFFFF0000 /* RESV[31..16] */ +#define WF_PLE_TOP_CPU_ENQ_PKT_NUM_RESV_SHFT 16 +#define WF_PLE_TOP_CPU_ENQ_PKT_NUM_CPU_ENQ_LMAC_PKT_NUM_ADDR \ + WF_PLE_TOP_CPU_ENQ_PKT_NUM_ADDR +#define WF_PLE_TOP_CPU_ENQ_PKT_NUM_CPU_ENQ_LMAC_PKT_NUM_MASK \ + 0x0000FFFF /* CPU_ENQ_LMAC_PKT_NUM[15..0] */ +#define WF_PLE_TOP_CPU_ENQ_PKT_NUM_CPU_ENQ_LMAC_PKT_NUM_SHFT 0 + +/* +* ---RLS_MSDU_PKT_NUM (0x820C0000 + 0x408)--- +* RSL_RPT_TXD_NUM[15..0] - (RO) TXD number of host report function +* RSL_MSDUID_NUM[31..16] - (RO) Release MSDU_ID number of host report +function +*/ +#define WF_PLE_TOP_RLS_MSDU_PKT_NUM_RSL_MSDUID_NUM_ADDR \ + WF_PLE_TOP_RLS_MSDU_PKT_NUM_ADDR +#define WF_PLE_TOP_RLS_MSDU_PKT_NUM_RSL_MSDUID_NUM_MASK \ + 0xFFFF0000 /* RSL_MSDUID_NUM[31..16] */ +#define WF_PLE_TOP_RLS_MSDU_PKT_NUM_RSL_MSDUID_NUM_SHFT 16 +#define WF_PLE_TOP_RLS_MSDU_PKT_NUM_RSL_RPT_TXD_NUM_ADDR \ + WF_PLE_TOP_RLS_MSDU_PKT_NUM_ADDR +#define WF_PLE_TOP_RLS_MSDU_PKT_NUM_RSL_RPT_TXD_NUM_MASK \ + 0x0000FFFF /* RSL_RPT_TXD_NUM[15..0] */ +#define WF_PLE_TOP_RLS_MSDU_PKT_NUM_RSL_RPT_TXD_NUM_SHFT 0 + +/* +* ---HOST_REPORT_NUM (0x820C0000 + 0x40c)--- +* RSL_TXD_NUM[15..0] - (RO) All TXD number of release function, +* include the no host report(not CT) TXD packets. +* HOST_REPORT_NUM[31..16] - (RO) Host report number that be the PSE +* packets carry release MSDU_ID information +*/ +#define WF_PLE_TOP_HOST_REPORT_NUM_HOST_REPORT_NUM_ADDR \ + WF_PLE_TOP_HOST_REPORT_NUM_ADDR +#define WF_PLE_TOP_HOST_REPORT_NUM_HOST_REPORT_NUM_MASK \ + 0xFFFF0000 /* HOST_REPORT_NUM[31..16] */ +#define WF_PLE_TOP_HOST_REPORT_NUM_HOST_REPORT_NUM_SHFT 16 +#define WF_PLE_TOP_HOST_REPORT_NUM_RSL_TXD_NUM_ADDR \ + WF_PLE_TOP_HOST_REPORT_NUM_ADDR +#define WF_PLE_TOP_HOST_REPORT_NUM_RSL_TXD_NUM_MASK \ + 0x0000FFFF /* RSL_TXD_NUM[15..0] */ +#define WF_PLE_TOP_HOST_REPORT_NUM_RSL_TXD_NUM_SHFT 0 + +/* +* ---UMAC_DBG_CTRL (0x820C0000 + 0x410)--- +* UMAC_DBG_FUNC_SEL[3..0] - (RW) Selects UMAC debug mode +* RESERVED4[7..4] - (RO) Reserved bits +* PLE_DBG_FLAG_A_NIB_EN[11..8] - (RW) Enable control of PLE debug flag A +nibble +* PLE_DBG_FLAG_B_NIB_EN[15..12] - (RW) Enable control of PLE debug flag B +nibble +* PSE_DBG_FLAG_A_NIB_EN[19..16] - (RW) Enable control of PSE debug flag A +nibble +* PSE_DBG_FLAG_B_NIB_EN[23..20] - (RW) Enable control of PSE debug flag B +nibble +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_UMAC_DBG_CTRL_PSE_DBG_FLAG_B_NIB_EN_ADDR \ + WF_PLE_TOP_UMAC_DBG_CTRL_ADDR +#define WF_PLE_TOP_UMAC_DBG_CTRL_PSE_DBG_FLAG_B_NIB_EN_MASK \ + 0x00F00000 /* PSE_DBG_FLAG_B_NIB_EN[23..20] */ +#define WF_PLE_TOP_UMAC_DBG_CTRL_PSE_DBG_FLAG_B_NIB_EN_SHFT 20 +#define WF_PLE_TOP_UMAC_DBG_CTRL_PSE_DBG_FLAG_A_NIB_EN_ADDR \ + WF_PLE_TOP_UMAC_DBG_CTRL_ADDR +#define WF_PLE_TOP_UMAC_DBG_CTRL_PSE_DBG_FLAG_A_NIB_EN_MASK \ + 0x000F0000 /* PSE_DBG_FLAG_A_NIB_EN[19..16] */ +#define WF_PLE_TOP_UMAC_DBG_CTRL_PSE_DBG_FLAG_A_NIB_EN_SHFT 16 +#define WF_PLE_TOP_UMAC_DBG_CTRL_PLE_DBG_FLAG_B_NIB_EN_ADDR \ + WF_PLE_TOP_UMAC_DBG_CTRL_ADDR +#define WF_PLE_TOP_UMAC_DBG_CTRL_PLE_DBG_FLAG_B_NIB_EN_MASK \ + 0x0000F000 /* PLE_DBG_FLAG_B_NIB_EN[15..12] */ +#define WF_PLE_TOP_UMAC_DBG_CTRL_PLE_DBG_FLAG_B_NIB_EN_SHFT 12 +#define WF_PLE_TOP_UMAC_DBG_CTRL_PLE_DBG_FLAG_A_NIB_EN_ADDR \ + WF_PLE_TOP_UMAC_DBG_CTRL_ADDR +#define WF_PLE_TOP_UMAC_DBG_CTRL_PLE_DBG_FLAG_A_NIB_EN_MASK \ + 0x00000F00 /* PLE_DBG_FLAG_A_NIB_EN[11..8] */ +#define WF_PLE_TOP_UMAC_DBG_CTRL_PLE_DBG_FLAG_A_NIB_EN_SHFT 8 +#define WF_PLE_TOP_UMAC_DBG_CTRL_UMAC_DBG_FUNC_SEL_ADDR \ + WF_PLE_TOP_UMAC_DBG_CTRL_ADDR +#define WF_PLE_TOP_UMAC_DBG_CTRL_UMAC_DBG_FUNC_SEL_MASK \ + 0x0000000F /* UMAC_DBG_FUNC_SEL[3..0] */ +#define WF_PLE_TOP_UMAC_DBG_CTRL_UMAC_DBG_FUNC_SEL_SHFT 0 + +/* +* ---PLE_DBG_A_BYTE_SEL (0x820C0000 + 0x414)--- +* PLE_DBG_FLAG_A_BYTE0_SEL[7..0] - (RW) Debug flag selection of PLE debug A +* byte 0 +* PLE_DBG_FLAG_A_BYTE1_SEL[15..8] - (RW) Debug flag selection of PLE debug A +* byte 1 +* PLE_DBG_FLAG_A_BYTE2_SEL[23..16] - (RW) Debug flag selection of PLE debug A +* byte 2 +* PLE_DBG_FLAG_A_BYTE3_SEL[31..24] - (RW) Debug flag selection of PLE debug A +* byte 3 +*/ +#define WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_PLE_DBG_FLAG_A_BYTE3_SEL_ADDR \ + WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_ADDR +#define WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_PLE_DBG_FLAG_A_BYTE3_SEL_MASK \ + 0xFF000000 /* PLE_DBG_FLAG_A_BYTE3_SEL[31..24] */ +#define WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_PLE_DBG_FLAG_A_BYTE3_SEL_SHFT 24 +#define WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_PLE_DBG_FLAG_A_BYTE2_SEL_ADDR \ + WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_ADDR +#define WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_PLE_DBG_FLAG_A_BYTE2_SEL_MASK \ + 0x00FF0000 /* PLE_DBG_FLAG_A_BYTE2_SEL[23..16] */ +#define WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_PLE_DBG_FLAG_A_BYTE2_SEL_SHFT 16 +#define WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_PLE_DBG_FLAG_A_BYTE1_SEL_ADDR \ + WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_ADDR +#define WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_PLE_DBG_FLAG_A_BYTE1_SEL_MASK \ + 0x0000FF00 /* PLE_DBG_FLAG_A_BYTE1_SEL[15..8] */ +#define WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_PLE_DBG_FLAG_A_BYTE1_SEL_SHFT 8 +#define WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_PLE_DBG_FLAG_A_BYTE0_SEL_ADDR \ + WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_ADDR +#define WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_PLE_DBG_FLAG_A_BYTE0_SEL_MASK \ + 0x000000FF /* PLE_DBG_FLAG_A_BYTE0_SEL[7..0] */ +#define WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_PLE_DBG_FLAG_A_BYTE0_SEL_SHFT 0 + +/* +* ---PLE_DBG_B_BYTE_SEL (0x820C0000 + 0x418)--- +* PLE_DBG_FLAG_B_BYTE0_SEL[7..0] - (RW) Debug flag selection of PLE debug B +* byte 0 +* PLE_DBG_FLAG_B_BYTE1_SEL[15..8] - (RW) Debug flag selection of PLE debug B +* byte 1 +* PLE_DBG_FLAG_B_BYTE2_SEL[23..16] - (RW) Debug flag selection of PLE debug B +* byte 2 +* PLE_DBG_FLAG_B_BYTE3_SEL[31..24] - (RW) Debug flag selection of PLE debug B +* byte 3 +*/ +#define WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_PLE_DBG_FLAG_B_BYTE3_SEL_ADDR \ + WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_ADDR +#define WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_PLE_DBG_FLAG_B_BYTE3_SEL_MASK \ + 0xFF000000 /* PLE_DBG_FLAG_B_BYTE3_SEL[31..24] */ +#define WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_PLE_DBG_FLAG_B_BYTE3_SEL_SHFT 24 +#define WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_PLE_DBG_FLAG_B_BYTE2_SEL_ADDR \ + WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_ADDR +#define WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_PLE_DBG_FLAG_B_BYTE2_SEL_MASK \ + 0x00FF0000 /* PLE_DBG_FLAG_B_BYTE2_SEL[23..16] */ +#define WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_PLE_DBG_FLAG_B_BYTE2_SEL_SHFT 16 +#define WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_PLE_DBG_FLAG_B_BYTE1_SEL_ADDR \ + WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_ADDR +#define WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_PLE_DBG_FLAG_B_BYTE1_SEL_MASK \ + 0x0000FF00 /* PLE_DBG_FLAG_B_BYTE1_SEL[15..8] */ +#define WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_PLE_DBG_FLAG_B_BYTE1_SEL_SHFT 8 +#define WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_PLE_DBG_FLAG_B_BYTE0_SEL_ADDR \ + WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_ADDR +#define WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_PLE_DBG_FLAG_B_BYTE0_SEL_MASK \ + 0x000000FF /* PLE_DBG_FLAG_B_BYTE0_SEL[7..0] */ +#define WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_PLE_DBG_FLAG_B_BYTE0_SEL_SHFT 0 + +/* +* ---FUNC_ACT_CNT_1 (0x820C0000 + 0x424)--- +* MACTX0_ACT_CNT[3..0] - (RO) Counter of MACTX0 TX active. +* MACTX0_NOR_END_CNT[7..4] - (RO) Counter of MACTX0 TX normal end. +* MACTX0_ABORT_CNT[11..8] - (RO) Counter of MACTX0 TX abort. +* RESERVED12[15..12] - (RO) Reserved bits +* TXCMD0_ADD_FID_CNT[19..16] - (RO) Counter of TXCMD0 TX add FID. +* TXCMD0_NOR_END_CNT[23..20] - (RO) Counter of TXCMD0 TX normal end. +* TXCMD0_ABORT_CNT[27..24] - (RO) Counter of TXCMD0 TX abort. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_FUNC_ACT_CNT_1_TXCMD0_ABORT_CNT_ADDR \ + WF_PLE_TOP_FUNC_ACT_CNT_1_ADDR +#define WF_PLE_TOP_FUNC_ACT_CNT_1_TXCMD0_ABORT_CNT_MASK \ + 0x0F000000 /* TXCMD0_ABORT_CNT[27..24] */ +#define WF_PLE_TOP_FUNC_ACT_CNT_1_TXCMD0_ABORT_CNT_SHFT 24 +#define WF_PLE_TOP_FUNC_ACT_CNT_1_TXCMD0_NOR_END_CNT_ADDR \ + WF_PLE_TOP_FUNC_ACT_CNT_1_ADDR +#define WF_PLE_TOP_FUNC_ACT_CNT_1_TXCMD0_NOR_END_CNT_MASK \ + 0x00F00000 /* TXCMD0_NOR_END_CNT[23..20] */ +#define WF_PLE_TOP_FUNC_ACT_CNT_1_TXCMD0_NOR_END_CNT_SHFT 20 +#define WF_PLE_TOP_FUNC_ACT_CNT_1_TXCMD0_ADD_FID_CNT_ADDR \ + WF_PLE_TOP_FUNC_ACT_CNT_1_ADDR +#define WF_PLE_TOP_FUNC_ACT_CNT_1_TXCMD0_ADD_FID_CNT_MASK \ + 0x000F0000 /* TXCMD0_ADD_FID_CNT[19..16] */ +#define WF_PLE_TOP_FUNC_ACT_CNT_1_TXCMD0_ADD_FID_CNT_SHFT 16 +#define WF_PLE_TOP_FUNC_ACT_CNT_1_MACTX0_ABORT_CNT_ADDR \ + WF_PLE_TOP_FUNC_ACT_CNT_1_ADDR +#define WF_PLE_TOP_FUNC_ACT_CNT_1_MACTX0_ABORT_CNT_MASK \ + 0x00000F00 /* MACTX0_ABORT_CNT[11..8] */ +#define WF_PLE_TOP_FUNC_ACT_CNT_1_MACTX0_ABORT_CNT_SHFT 8 +#define WF_PLE_TOP_FUNC_ACT_CNT_1_MACTX0_NOR_END_CNT_ADDR \ + WF_PLE_TOP_FUNC_ACT_CNT_1_ADDR +#define WF_PLE_TOP_FUNC_ACT_CNT_1_MACTX0_NOR_END_CNT_MASK \ + 0x000000F0 /* MACTX0_NOR_END_CNT[7..4] */ +#define WF_PLE_TOP_FUNC_ACT_CNT_1_MACTX0_NOR_END_CNT_SHFT 4 +#define WF_PLE_TOP_FUNC_ACT_CNT_1_MACTX0_ACT_CNT_ADDR \ + WF_PLE_TOP_FUNC_ACT_CNT_1_ADDR +#define WF_PLE_TOP_FUNC_ACT_CNT_1_MACTX0_ACT_CNT_MASK \ + 0x0000000F /* MACTX0_ACT_CNT[3..0] */ +#define WF_PLE_TOP_FUNC_ACT_CNT_1_MACTX0_ACT_CNT_SHFT 0 + +/* +* ---SRAM_MBIST_BACKGROUND (0x820C0000 + 0x430)--- +* MBIST_BACKGROUND[15..0] - (RW) bsel setting for PLE SRAM MBIST circuit +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_SRAM_MBIST_BACKGROUND_MBIST_BACKGROUND_ADDR \ + WF_PLE_TOP_SRAM_MBIST_BACKGROUND_ADDR +#define WF_PLE_TOP_SRAM_MBIST_BACKGROUND_MBIST_BACKGROUND_MASK \ + 0x0000FFFF /* MBIST_BACKGROUND[15..0] */ +#define WF_PLE_TOP_SRAM_MBIST_BACKGROUND_MBIST_BACKGROUND_SHFT 0 + +/* +* ---SRAM_MBIST_BSEL (0x820C0000 + 0x434)--- +* MBIST_BSEL[15..0] - (RW) The bsel setting for PLE SRAM MBIST +circuit. +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_SRAM_MBIST_BSEL_MBIST_BSEL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_BSEL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_BSEL_MBIST_BSEL_MASK \ + 0x0000FFFF /* MBIST_BSEL[15..0] */ +#define WF_PLE_TOP_SRAM_MBIST_BSEL_MBIST_BSEL_SHFT 0 + +/* +* ---SRAM_MBIST_DONE (0x820C0000 + 0x438)--- +* G1_MBIST_DONE[0] - (RO) Working status of PLE G1 SRAM MBIST +circuit +* G2_MBIST_DONE[1] - (RO) Working status of PLE G2 SRAM MBIST +circuit +* RESERVED2[31..2] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_SRAM_MBIST_DONE_G2_MBIST_DONE_ADDR \ + WF_PLE_TOP_SRAM_MBIST_DONE_ADDR +#define WF_PLE_TOP_SRAM_MBIST_DONE_G2_MBIST_DONE_MASK \ + 0x00000002 /* G2_MBIST_DONE[1] */ +#define WF_PLE_TOP_SRAM_MBIST_DONE_G2_MBIST_DONE_SHFT 1 +#define WF_PLE_TOP_SRAM_MBIST_DONE_G1_MBIST_DONE_ADDR \ + WF_PLE_TOP_SRAM_MBIST_DONE_ADDR +#define WF_PLE_TOP_SRAM_MBIST_DONE_G1_MBIST_DONE_MASK \ + 0x00000001 /* G1_MBIST_DONE[0] */ +#define WF_PLE_TOP_SRAM_MBIST_DONE_G1_MBIST_DONE_SHFT 0 + +/* +* ---SRAM_MBIST_FAIL (0x820C0000 + 0x43c)--- +* G1_SRAM0_MBIST_FAIL[0] - (RO) MBIST check result of group 1 SRAM0 +* G1_SRAM1_MBIST_FAIL[1] - (RO) MBIST check result of group 1 SRAM1 +* G1_SRAM2_MBIST_FAIL[2] - (RO) MBIST check result of group 1 SRAM2 +* G1_SRAM3_MBIST_FAIL[3] - (RO) MBIST check result of group 1 SRAM3 +* G2_SRAM0_MBIST_FAIL[4] - (RO) MBIST check result of group 2 SRAM0 +* G2_SRAM1_MBIST_FAIL[5] - (RO) MBIST check result of group 2 SRAM1 +* G2_SRAM2_MBIST_FAIL[6] - (RO) MBIST check result of group 2 SRAM2 +* G2_SRAM3_MBIST_FAIL[7] - (RO) MBIST check result of group 2 SRAM3 +* G2_SRAM4_MBIST_FAIL[8] - (RO) MBIST check result of group 2 SRAM4 +* G2_SRAM5_MBIST_FAIL[9] - (RO) MBIST check result of group 2 SRAM5 +* RESERVED10[31..10] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM5_MBIST_FAIL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_FAIL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM5_MBIST_FAIL_MASK \ + 0x00000200 /* G2_SRAM5_MBIST_FAIL[9] */ +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM5_MBIST_FAIL_SHFT 9 +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM4_MBIST_FAIL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_FAIL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM4_MBIST_FAIL_MASK \ + 0x00000100 /* G2_SRAM4_MBIST_FAIL[8] */ +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM4_MBIST_FAIL_SHFT 8 +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM3_MBIST_FAIL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_FAIL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM3_MBIST_FAIL_MASK \ + 0x00000080 /* G2_SRAM3_MBIST_FAIL[7] */ +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM3_MBIST_FAIL_SHFT 7 +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM2_MBIST_FAIL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_FAIL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM2_MBIST_FAIL_MASK \ + 0x00000040 /* G2_SRAM2_MBIST_FAIL[6] */ +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM2_MBIST_FAIL_SHFT 6 +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM1_MBIST_FAIL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_FAIL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM1_MBIST_FAIL_MASK \ + 0x00000020 /* G2_SRAM1_MBIST_FAIL[5] */ +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM1_MBIST_FAIL_SHFT 5 +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM0_MBIST_FAIL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_FAIL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM0_MBIST_FAIL_MASK \ + 0x00000010 /* G2_SRAM0_MBIST_FAIL[4] */ +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM0_MBIST_FAIL_SHFT 4 +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G1_SRAM3_MBIST_FAIL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_FAIL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G1_SRAM3_MBIST_FAIL_MASK \ + 0x00000008 /* G1_SRAM3_MBIST_FAIL[3] */ +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G1_SRAM3_MBIST_FAIL_SHFT 3 +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G1_SRAM2_MBIST_FAIL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_FAIL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G1_SRAM2_MBIST_FAIL_MASK \ + 0x00000004 /* G1_SRAM2_MBIST_FAIL[2] */ +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G1_SRAM2_MBIST_FAIL_SHFT 2 +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G1_SRAM1_MBIST_FAIL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_FAIL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G1_SRAM1_MBIST_FAIL_MASK \ + 0x00000002 /* G1_SRAM1_MBIST_FAIL[1] */ +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G1_SRAM1_MBIST_FAIL_SHFT 1 +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G1_SRAM0_MBIST_FAIL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_FAIL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G1_SRAM0_MBIST_FAIL_MASK \ + 0x00000001 /* G1_SRAM0_MBIST_FAIL[0] */ +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G1_SRAM0_MBIST_FAIL_SHFT 0 + +/* +* ---SRAM_AWT_HDEN_CTRL (0x820C0000 + 0x440)--- +* SRAM_AWT_CTRL[13..0] - (RW) AWT setting of SRAMS +* RESERVED14[15..14] - (RO) Reserved bits +* SRAM_HDEN_CTRL[29..16] - (RW) HDEN setting of SRAMS +* RESERVED30[31..30] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_SRAM_AWT_HDEN_CTRL_SRAM_HDEN_CTRL_ADDR \ + WF_PLE_TOP_SRAM_AWT_HDEN_CTRL_ADDR +#define WF_PLE_TOP_SRAM_AWT_HDEN_CTRL_SRAM_HDEN_CTRL_MASK \ + 0x3FFF0000 /* SRAM_HDEN_CTRL[29..16] */ +#define WF_PLE_TOP_SRAM_AWT_HDEN_CTRL_SRAM_HDEN_CTRL_SHFT 16 +#define WF_PLE_TOP_SRAM_AWT_HDEN_CTRL_SRAM_AWT_CTRL_ADDR \ + WF_PLE_TOP_SRAM_AWT_HDEN_CTRL_ADDR +#define WF_PLE_TOP_SRAM_AWT_HDEN_CTRL_SRAM_AWT_CTRL_MASK \ + 0x00003FFF /* SRAM_AWT_CTRL[13..0] */ +#define WF_PLE_TOP_SRAM_AWT_HDEN_CTRL_SRAM_AWT_CTRL_SHFT 0 + +/* +* ---DRR_TABLE_WDATA0 (0x820C0000 + 0x450)--- +* DRR_TABLE_WDATA[31..0] - (RW) DRRwdata[31:0] for reading/writing DRR +table +* Mode 0x2?: DRR station mode +* WData[15:0]: Sta setting +* WData[127:16]: Reserved +* Mode 0x4?: BSS mode +* See SRAM layout. +* Mode 0x8?: Charge mode +* WData [15:0]: Charge length (unit: +byte) +* WData [31:16]: Charge time 9 unit +1.024us +* WData[127:32]: Reserved +*/ +#define WF_PLE_TOP_DRR_TABLE_WDATA0_DRR_TABLE_WDATA_ADDR \ + WF_PLE_TOP_DRR_TABLE_WDATA0_ADDR +#define WF_PLE_TOP_DRR_TABLE_WDATA0_DRR_TABLE_WDATA_MASK \ + 0xFFFFFFFF /* DRR_TABLE_WDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_WDATA0_DRR_TABLE_WDATA_SHFT 0 + +/* +* ---DRR_TABLE_WDATA1 (0x820C0000 + 0x454)--- +* DRR_TABLE_WDATA[31..0] - (RW) DRR wdata[63:32] for reading/writing DRR +table +*/ +#define WF_PLE_TOP_DRR_TABLE_WDATA1_DRR_TABLE_WDATA_ADDR \ + WF_PLE_TOP_DRR_TABLE_WDATA1_ADDR +#define WF_PLE_TOP_DRR_TABLE_WDATA1_DRR_TABLE_WDATA_MASK \ + 0xFFFFFFFF /* DRR_TABLE_WDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_WDATA1_DRR_TABLE_WDATA_SHFT 0 + +/* +* ---DRR_TABLE_WDATA2 (0x820C0000 + 0x458)--- +* DRR_TABLE_WDATA[31..0] - (RW) DRR wdata[95:64] for reading/writing DRR +table +*/ +#define WF_PLE_TOP_DRR_TABLE_WDATA2_DRR_TABLE_WDATA_ADDR \ + WF_PLE_TOP_DRR_TABLE_WDATA2_ADDR +#define WF_PLE_TOP_DRR_TABLE_WDATA2_DRR_TABLE_WDATA_MASK \ + 0xFFFFFFFF /* DRR_TABLE_WDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_WDATA2_DRR_TABLE_WDATA_SHFT 0 + +/* +* ---DRR_TABLE_WDATA3 (0x820C0000 + 0x45c)--- +* DRR_TABLE_WDATA[31..0] - (RW) DRR wdata[127:96] for reading/writing +* DRR table +*/ +#define WF_PLE_TOP_DRR_TABLE_WDATA3_DRR_TABLE_WDATA_ADDR \ + WF_PLE_TOP_DRR_TABLE_WDATA3_ADDR +#define WF_PLE_TOP_DRR_TABLE_WDATA3_DRR_TABLE_WDATA_MASK \ + 0xFFFFFFFF /* DRR_TABLE_WDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_WDATA3_DRR_TABLE_WDATA_SHFT 0 + +/* +* ---DRR_TABLE_WDATA4 (0x820C0000 + 0x460)--- +* DRR_TABLE_WDATA[31..0] - (RW) DRRwdata[159:128] for reading/writing +* DRR table +* Mode 0x4?: BSS mode +* See SRAM layout. +*/ +#define WF_PLE_TOP_DRR_TABLE_WDATA4_DRR_TABLE_WDATA_ADDR \ + WF_PLE_TOP_DRR_TABLE_WDATA4_ADDR +#define WF_PLE_TOP_DRR_TABLE_WDATA4_DRR_TABLE_WDATA_MASK \ + 0xFFFFFFFF /* DRR_TABLE_WDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_WDATA4_DRR_TABLE_WDATA_SHFT 0 + +/* +* ---DRR_TABLE_WDATA5 (0x820C0000 + 0x464)--- +* DRR_TABLE_WDATA[31..0] - (RW) DRR wdata[191:160] for reading/writing +* DRR table +*/ +#define WF_PLE_TOP_DRR_TABLE_WDATA5_DRR_TABLE_WDATA_ADDR \ + WF_PLE_TOP_DRR_TABLE_WDATA5_ADDR +#define WF_PLE_TOP_DRR_TABLE_WDATA5_DRR_TABLE_WDATA_MASK \ + 0xFFFFFFFF /* DRR_TABLE_WDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_WDATA5_DRR_TABLE_WDATA_SHFT 0 + +/* +* ---DRR_TABLE_WDATA6 (0x820C0000 + 0x468)--- +* DRR_TABLE_WDATA[31..0] - (RW) DRR wdata[223:192] for reading/writing +* DRR table +*/ +#define WF_PLE_TOP_DRR_TABLE_WDATA6_DRR_TABLE_WDATA_ADDR \ + WF_PLE_TOP_DRR_TABLE_WDATA6_ADDR +#define WF_PLE_TOP_DRR_TABLE_WDATA6_DRR_TABLE_WDATA_MASK \ + 0xFFFFFFFF /* DRR_TABLE_WDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_WDATA6_DRR_TABLE_WDATA_SHFT 0 + +/* +* ---DRR_TABLE_WDATA7 (0x820C0000 + 0x46c)--- +* DRR_TABLE_WDATA[31..0] - (RW) DRR wdata[255:224] for reading/writing +* DRR table +*/ +#define WF_PLE_TOP_DRR_TABLE_WDATA7_DRR_TABLE_WDATA_ADDR \ + WF_PLE_TOP_DRR_TABLE_WDATA7_ADDR +#define WF_PLE_TOP_DRR_TABLE_WDATA7_DRR_TABLE_WDATA_MASK \ + 0xFFFFFFFF /* DRR_TABLE_WDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_WDATA7_DRR_TABLE_WDATA_SHFT 0 + +/* +* ---DRR_TABLE_RDATA0 (0x820C0000 + 0x470)--- +* DRR_TABLE_RDATA[31..0] - (RW) DRR rdata[31:0] for reading/writing DRR +table +*/ +#define WF_PLE_TOP_DRR_TABLE_RDATA0_DRR_TABLE_RDATA_ADDR \ + WF_PLE_TOP_DRR_TABLE_RDATA0_ADDR +#define WF_PLE_TOP_DRR_TABLE_RDATA0_DRR_TABLE_RDATA_MASK \ + 0xFFFFFFFF /* DRR_TABLE_RDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_RDATA0_DRR_TABLE_RDATA_SHFT 0 + +/* +* ---DRR_TABLE_RDATA1 (0x820C0000 + 0x474)--- +* DRR_TABLE_RDATA[31..0] - (RW) DRR rdata[63:32] for reading/writing DRR +table +*/ +#define WF_PLE_TOP_DRR_TABLE_RDATA1_DRR_TABLE_RDATA_ADDR \ + WF_PLE_TOP_DRR_TABLE_RDATA1_ADDR +#define WF_PLE_TOP_DRR_TABLE_RDATA1_DRR_TABLE_RDATA_MASK \ + 0xFFFFFFFF /* DRR_TABLE_RDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_RDATA1_DRR_TABLE_RDATA_SHFT 0 + +/* +* ---DRR_TABLE_RDATA2 (0x820C0000 + 0x478)--- +* DRR_TABLE_RDATA[31..0] - (RW) DRR rdata[95:64] for reading/writing DRR +table +*/ +#define WF_PLE_TOP_DRR_TABLE_RDATA2_DRR_TABLE_RDATA_ADDR \ + WF_PLE_TOP_DRR_TABLE_RDATA2_ADDR +#define WF_PLE_TOP_DRR_TABLE_RDATA2_DRR_TABLE_RDATA_MASK \ + 0xFFFFFFFF /* DRR_TABLE_RDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_RDATA2_DRR_TABLE_RDATA_SHFT 0 + +/* +* ---DRR_TABLE_RDATA3 (0x820C0000 + 0x47c)--- +* DRR_TABLE_RDATA[31..0] - (RW) DRR rdata[127:96] for reading/writing +* DRR table +*/ +#define WF_PLE_TOP_DRR_TABLE_RDATA3_DRR_TABLE_RDATA_ADDR \ + WF_PLE_TOP_DRR_TABLE_RDATA3_ADDR +#define WF_PLE_TOP_DRR_TABLE_RDATA3_DRR_TABLE_RDATA_MASK \ + 0xFFFFFFFF /* DRR_TABLE_RDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_RDATA3_DRR_TABLE_RDATA_SHFT 0 + +/* +* ---DRR_TABLE_RDATA4 (0x820C0000 + 0x480)--- +* DRR_TABLE_RDATA[31..0] - (RW) DRR rdata[159:128] for reading/writing +* DRR table +*/ +#define WF_PLE_TOP_DRR_TABLE_RDATA4_DRR_TABLE_RDATA_ADDR \ + WF_PLE_TOP_DRR_TABLE_RDATA4_ADDR +#define WF_PLE_TOP_DRR_TABLE_RDATA4_DRR_TABLE_RDATA_MASK \ + 0xFFFFFFFF /* DRR_TABLE_RDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_RDATA4_DRR_TABLE_RDATA_SHFT 0 + +/* +* ---DRR_TABLE_RDATA5 (0x820C0000 + 0x484)--- +* DRR_TABLE_RDATA[31..0] - (RW) DRR rdata[191:160] for reading/writing +* DRR table +*/ +#define WF_PLE_TOP_DRR_TABLE_RDATA5_DRR_TABLE_RDATA_ADDR \ + WF_PLE_TOP_DRR_TABLE_RDATA5_ADDR +#define WF_PLE_TOP_DRR_TABLE_RDATA5_DRR_TABLE_RDATA_MASK \ + 0xFFFFFFFF /* DRR_TABLE_RDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_RDATA5_DRR_TABLE_RDATA_SHFT 0 + +/* +* ---DRR_TABLE_RDATA6 (0x820C0000 + 0x488)--- +* DRR_TABLE_RDATA[31..0] - (RW) DRR rdata[223:192] for reading/writing +* DRR table +*/ +#define WF_PLE_TOP_DRR_TABLE_RDATA6_DRR_TABLE_RDATA_ADDR \ + WF_PLE_TOP_DRR_TABLE_RDATA6_ADDR +#define WF_PLE_TOP_DRR_TABLE_RDATA6_DRR_TABLE_RDATA_MASK \ + 0xFFFFFFFF /* DRR_TABLE_RDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_RDATA6_DRR_TABLE_RDATA_SHFT 0 + +/* +* ---DRR_TABLE_RDATA7 (0x820C0000 + 0x48c)--- +* DRR_TABLE_RDATA[31..0] - (RW) DRR rdata[255:224] for reading/writing +* DRR table +*/ +#define WF_PLE_TOP_DRR_TABLE_RDATA7_DRR_TABLE_RDATA_ADDR \ + WF_PLE_TOP_DRR_TABLE_RDATA7_ADDR +#define WF_PLE_TOP_DRR_TABLE_RDATA7_DRR_TABLE_RDATA_MASK \ + 0xFFFFFFFF /* DRR_TABLE_RDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_RDATA7_DRR_TABLE_RDATA_SHFT 0 + +/* +* ---DRR_TABLE_CTRL (0x820C0000 + 0x490)--- +* INDEX[11..0] - (RW) Operation index +* Mode 0x00: DRR STA link, STA relay +* Bit[1:0]: qid +* Bit[10:2]: Station ID +//-- +* Mode 0x20: addr[6:0] mean station ID +* Mode 0x21: addr[6:0] mean station ID +* Mode 0x22: SRAM idx (debug mode) +* Mode 0x23: SRAM idx (debug mode) +* 0~35: STA bitmap +* 36~51: STA setting +//-- +* Mode 0x40: addr[3:0] = bssid, +* Mode 0x41: addr[3:0] = bssid, +* Mode 0x42: addr[3:0] = bssid, +* Mode 0x43: addr[3:0] = bssid, +* Mode 0x44: SRAM idx (debug mode) +* Mode 0x45: SRAM idx (debug mode) +* 0~15: BSS bitmap +* 16~31: BSS setting +* 32~47: Token status +//-- +* Mode 0x81~0x83: addr[3:0] = BSS group ID +* Bit[0]: Charge bw_token +* Bit[1]: Charge bw DRR +* Mode 0x84: addr[7:0] = station ID, +* addr[11:8]= qid +* Bit[2]: Charge airtime DRR +* Bit[3]: Charge is ADD mode +* WRITE_MASK[15..12] - (RW) DRR table will not be updated if mask +* write bits are enabled. +* MODE[23..16] - (RW) Operation mode for DRR table +* WRITE_MASK_2[27..24] - (RW) DRR table will not be updated if mask +* write bits are enabled. +* RESERVED28[30..28] - (RO) Reserved bits +* EXECUTE[31] - (RW) Excutes SW command to read/write DRR +table +*/ +#define WF_PLE_TOP_DRR_TABLE_CTRL_EXECUTE_ADDR WF_PLE_TOP_DRR_TABLE_CTRL_ADDR +#define WF_PLE_TOP_DRR_TABLE_CTRL_EXECUTE_MASK 0x80000000 /* EXECUTE[31] */ +#define WF_PLE_TOP_DRR_TABLE_CTRL_EXECUTE_SHFT 31 +#define WF_PLE_TOP_DRR_TABLE_CTRL_WRITE_MASK_2_ADDR \ + WF_PLE_TOP_DRR_TABLE_CTRL_ADDR +#define WF_PLE_TOP_DRR_TABLE_CTRL_WRITE_MASK_2_MASK \ + 0x0F000000 /* WRITE_MASK_2[27..24] */ +#define WF_PLE_TOP_DRR_TABLE_CTRL_WRITE_MASK_2_SHFT 24 +#define WF_PLE_TOP_DRR_TABLE_CTRL_MODE_ADDR WF_PLE_TOP_DRR_TABLE_CTRL_ADDR +#define WF_PLE_TOP_DRR_TABLE_CTRL_MODE_MASK 0x00FF0000 /* MODE[23..16] */ +#define WF_PLE_TOP_DRR_TABLE_CTRL_MODE_SHFT 16 +#define WF_PLE_TOP_DRR_TABLE_CTRL_WRITE_MASK_ADDR WF_PLE_TOP_DRR_TABLE_CTRL_ADDR +#define WF_PLE_TOP_DRR_TABLE_CTRL_WRITE_MASK_MASK \ + 0x0000F000 /* WRITE_MASK[15..12] */ +#define WF_PLE_TOP_DRR_TABLE_CTRL_WRITE_MASK_SHFT 12 +#define WF_PLE_TOP_DRR_TABLE_CTRL_INDEX_ADDR WF_PLE_TOP_DRR_TABLE_CTRL_ADDR +#define WF_PLE_TOP_DRR_TABLE_CTRL_INDEX_MASK 0x00000FFF /* INDEX[11..0] */ +#define WF_PLE_TOP_DRR_TABLE_CTRL_INDEX_SHFT 0 + +/* +* ---AIRTIME_DRR_SIZE (0x820C0000 + 0x494)--- +* AIRTIME_DEFICIT_BOUNDARY[7..0] - (RW) Limits airtime DRR's maximum deficit +* Unit: 256us +* RESERVED2[15..8] - (RW) xxx +* BW_DEFICIT_BOUNDARY[23..16] - (RW) Limits BW DRR's maximum deficit +* Unit: 256us +* DRR_TXCNT_SIZE[31..24] - (RW) Tx count mode charge time setting +* Unit: 256us +*/ +#define WF_PLE_TOP_AIRTIME_DRR_SIZE_DRR_TXCNT_SIZE_ADDR \ + WF_PLE_TOP_AIRTIME_DRR_SIZE_ADDR +#define WF_PLE_TOP_AIRTIME_DRR_SIZE_DRR_TXCNT_SIZE_MASK \ + 0xFF000000 /* DRR_TXCNT_SIZE[31..24] */ +#define WF_PLE_TOP_AIRTIME_DRR_SIZE_DRR_TXCNT_SIZE_SHFT 24 +#define WF_PLE_TOP_AIRTIME_DRR_SIZE_BW_DEFICIT_BOUNDARY_ADDR \ + WF_PLE_TOP_AIRTIME_DRR_SIZE_ADDR +#define WF_PLE_TOP_AIRTIME_DRR_SIZE_BW_DEFICIT_BOUNDARY_MASK \ + 0x00FF0000 /* BW_DEFICIT_BOUNDARY[23..16] */ +#define WF_PLE_TOP_AIRTIME_DRR_SIZE_BW_DEFICIT_BOUNDARY_SHFT 16 +#define WF_PLE_TOP_AIRTIME_DRR_SIZE_RESERVED2_ADDR \ + WF_PLE_TOP_AIRTIME_DRR_SIZE_ADDR +#define WF_PLE_TOP_AIRTIME_DRR_SIZE_RESERVED2_MASK \ + 0x0000FF00 /* RESERVED2[15..8] */ +#define WF_PLE_TOP_AIRTIME_DRR_SIZE_RESERVED2_SHFT 8 +#define WF_PLE_TOP_AIRTIME_DRR_SIZE_AIRTIME_DEFICIT_BOUNDARY_ADDR \ + WF_PLE_TOP_AIRTIME_DRR_SIZE_ADDR +#define WF_PLE_TOP_AIRTIME_DRR_SIZE_AIRTIME_DEFICIT_BOUNDARY_MASK \ + 0x000000FF /* AIRTIME_DEFICIT_BOUNDARY[7..0] */ +#define WF_PLE_TOP_AIRTIME_DRR_SIZE_AIRTIME_DEFICIT_BOUNDARY_SHFT 0 + +/* +* ---CHECK_BW_TIME_TOKEN_ (0x820C0000 + 0x498)--- +* DISABLE_BW_TIME_CHECK[15..0] - (RW) HW will ignore time token status. +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_CHECK_BW_TIME_TOKEN__DISABLE_BW_TIME_CHECK_ADDR \ + WF_PLE_TOP_CHECK_BW_TIME_TOKEN__ADDR +#define WF_PLE_TOP_CHECK_BW_TIME_TOKEN__DISABLE_BW_TIME_CHECK_MASK \ + 0x0000FFFF /* DISABLE_BW_TIME_CHECK[15..0] */ +#define WF_PLE_TOP_CHECK_BW_TIME_TOKEN__DISABLE_BW_TIME_CHECK_SHFT 0 + +/* +* ---CHECK_BW_LENGTH_TOKEN_ (0x820C0000 + 0x49c)--- +* DISABLE_BW_LENGTH_CHECK[15..0] - (RW) HW will ignore time token status. +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_CHECK_BW_LENGTH_TOKEN__DISABLE_BW_LENGTH_CHECK_ADDR \ + WF_PLE_TOP_CHECK_BW_LENGTH_TOKEN__ADDR +#define WF_PLE_TOP_CHECK_BW_LENGTH_TOKEN__DISABLE_BW_LENGTH_CHECK_MASK \ + 0x0000FFFF /* DISABLE_BW_LENGTH_CHECK[15..0] */ +#define WF_PLE_TOP_CHECK_BW_LENGTH_TOKEN__DISABLE_BW_LENGTH_CHECK_SHFT 0 + +/* +* ---AIRTIME_QUANTUM_SETTING0 (0x820C0000 + 0x4a0)--- +* AIRTIME_QUANTUM0[7..0] - (RW) Airtime quantum 0 +* AIRTIME_QUANTUM1[15..8] - (RW) Airtime quantum 1 +* AIRTIME_QUANTUM2[23..16] - (RW) Airtime quantum 2 +* AIRTIME_QUANTUM3[31..24] - (RW) Airtime quantum 3 +*/ +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_AIRTIME_QUANTUM3_ADDR \ + WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_ADDR +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_AIRTIME_QUANTUM3_MASK \ + 0xFF000000 /* AIRTIME_QUANTUM3[31..24] */ +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_AIRTIME_QUANTUM3_SHFT 24 +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_AIRTIME_QUANTUM2_ADDR \ + WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_ADDR +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_AIRTIME_QUANTUM2_MASK \ + 0x00FF0000 /* AIRTIME_QUANTUM2[23..16] */ +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_AIRTIME_QUANTUM2_SHFT 16 +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_AIRTIME_QUANTUM1_ADDR \ + WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_ADDR +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_AIRTIME_QUANTUM1_MASK \ + 0x0000FF00 /* AIRTIME_QUANTUM1[15..8] */ +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_AIRTIME_QUANTUM1_SHFT 8 +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_AIRTIME_QUANTUM0_ADDR \ + WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_ADDR +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_AIRTIME_QUANTUM0_MASK \ + 0x000000FF /* AIRTIME_QUANTUM0[7..0] */ +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_AIRTIME_QUANTUM0_SHFT 0 + +/* +* ---AIRTIME_QUANTUM_SETTING1 (0x820C0000 + 0x4a4)--- +* AIRTIME_QUANTUM4[7..0] - (RW) Airtime quantum 4 +* AIRTIME_QUANTUM5[15..8] - (RW) Airtime quantum 5 +* AIRTIME_QUANTUM6[23..16] - (RW) Airtime quantum 6 +* AIRTIME_QUANTUM7[31..24] - (RW) Airtime quantum 7 +*/ +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_AIRTIME_QUANTUM7_ADDR \ + WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_ADDR +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_AIRTIME_QUANTUM7_MASK \ + 0xFF000000 /* AIRTIME_QUANTUM7[31..24] */ +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_AIRTIME_QUANTUM7_SHFT 24 +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_AIRTIME_QUANTUM6_ADDR \ + WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_ADDR +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_AIRTIME_QUANTUM6_MASK \ + 0x00FF0000 /* AIRTIME_QUANTUM6[23..16] */ +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_AIRTIME_QUANTUM6_SHFT 16 +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_AIRTIME_QUANTUM5_ADDR \ + WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_ADDR +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_AIRTIME_QUANTUM5_MASK \ + 0x0000FF00 /* AIRTIME_QUANTUM5[15..8] */ +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_AIRTIME_QUANTUM5_SHFT 8 +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_AIRTIME_QUANTUM4_ADDR \ + WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_ADDR +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_AIRTIME_QUANTUM4_MASK \ + 0x000000FF /* AIRTIME_QUANTUM4[7..0] */ +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_AIRTIME_QUANTUM4_SHFT 0 + +/* +* ---DRR_HW_SRCHCMD_FULL (0x820C0000 + 0x4c0)--- +* CMD_FULL_CHNL_DL[15..0] - (RW) Hardware search command full flag of 16 +* backoff channel of downlink +* CMD_FULL_CHNL_UL[31..16] - (RW) Hardware search command full flag of 16 +* backoff channel of uplink +*/ +#define WF_PLE_TOP_DRR_HW_SRCHCMD_FULL_CMD_FULL_CHNL_UL_ADDR \ + WF_PLE_TOP_DRR_HW_SRCHCMD_FULL_ADDR +#define WF_PLE_TOP_DRR_HW_SRCHCMD_FULL_CMD_FULL_CHNL_UL_MASK \ + 0xFFFF0000 /* CMD_FULL_CHNL_UL[31..16] */ +#define WF_PLE_TOP_DRR_HW_SRCHCMD_FULL_CMD_FULL_CHNL_UL_SHFT 16 +#define WF_PLE_TOP_DRR_HW_SRCHCMD_FULL_CMD_FULL_CHNL_DL_ADDR \ + WF_PLE_TOP_DRR_HW_SRCHCMD_FULL_ADDR +#define WF_PLE_TOP_DRR_HW_SRCHCMD_FULL_CMD_FULL_CHNL_DL_MASK \ + 0x0000FFFF /* CMD_FULL_CHNL_DL[15..0] */ +#define WF_PLE_TOP_DRR_HW_SRCHCMD_FULL_CMD_FULL_CHNL_DL_SHFT 0 + +/* +* ---TWT_DBG (0x820C0000 + 0x4d0)--- +* TABLE_IDX_SEL[2..0] - (RW) Station index selection +* UL_TABLE_SEL[3] - (RW) Downlink/uplink station table selection +* RESERVED4[15..4] - (RO) Reserved bits +* TABLE_WLAN_ID[25..16] - (RO) Station WLAN ID in station table +* RESERVED26[27..26] - (RO) Reserved bits +* STA_CNT[31..28] - (RO) Valid station count in station table +*/ +#define WF_PLE_TOP_TWT_DBG_STA_CNT_ADDR WF_PLE_TOP_TWT_DBG_ADDR +#define WF_PLE_TOP_TWT_DBG_STA_CNT_MASK 0xF0000000 /* STA_CNT[31..28] */ +#define WF_PLE_TOP_TWT_DBG_STA_CNT_SHFT 28 +#define WF_PLE_TOP_TWT_DBG_TABLE_WLAN_ID_ADDR WF_PLE_TOP_TWT_DBG_ADDR +#define WF_PLE_TOP_TWT_DBG_TABLE_WLAN_ID_MASK \ + 0x03FF0000 /* TABLE_WLAN_ID[25..16] */ +#define WF_PLE_TOP_TWT_DBG_TABLE_WLAN_ID_SHFT 16 +#define WF_PLE_TOP_TWT_DBG_UL_TABLE_SEL_ADDR WF_PLE_TOP_TWT_DBG_ADDR +#define WF_PLE_TOP_TWT_DBG_UL_TABLE_SEL_MASK 0x00000008 /* UL_TABLE_SEL[3] */ +#define WF_PLE_TOP_TWT_DBG_UL_TABLE_SEL_SHFT 3 +#define WF_PLE_TOP_TWT_DBG_TABLE_IDX_SEL_ADDR WF_PLE_TOP_TWT_DBG_ADDR +#define WF_PLE_TOP_TWT_DBG_TABLE_IDX_SEL_MASK \ + 0x00000007 /* TABLE_IDX_SEL[2..0] */ +#define WF_PLE_TOP_TWT_DBG_TABLE_IDX_SEL_SHFT 0 + +/* +* ---VOW_DBG_SEL (0x820C0000 + 0x4d4)--- +* AIRTIME_DEBUG_SEL[15..0] - (RW) Selects airtime debug +* BW_DEBUG_SEL[31..16] - (RW) Selects BW control debug +*/ +#define WF_PLE_TOP_VOW_DBG_SEL_BW_DEBUG_SEL_ADDR WF_PLE_TOP_VOW_DBG_SEL_ADDR +#define WF_PLE_TOP_VOW_DBG_SEL_BW_DEBUG_SEL_MASK \ + 0xFFFF0000 /* BW_DEBUG_SEL[31..16] */ +#define WF_PLE_TOP_VOW_DBG_SEL_BW_DEBUG_SEL_SHFT 16 +#define WF_PLE_TOP_VOW_DBG_SEL_AIRTIME_DEBUG_SEL_ADDR \ + WF_PLE_TOP_VOW_DBG_SEL_ADDR +#define WF_PLE_TOP_VOW_DBG_SEL_AIRTIME_DEBUG_SEL_MASK \ + 0x0000FFFF /* AIRTIME_DEBUG_SEL[15..0] */ +#define WF_PLE_TOP_VOW_DBG_SEL_AIRTIME_DEBUG_SEL_SHFT 0 + +/* +* ---AIRTIME_DBG_INFO0 (0x820C0000 + 0x4d8)--- +* AIRTIME_DBG_INFO0[31..0] - (RO) Station link head/tail +*/ +#define WF_PLE_TOP_AIRTIME_DBG_INFO0_AIRTIME_DBG_INFO0_ADDR \ + WF_PLE_TOP_AIRTIME_DBG_INFO0_ADDR +#define WF_PLE_TOP_AIRTIME_DBG_INFO0_AIRTIME_DBG_INFO0_MASK \ + 0xFFFFFFFF /* AIRTIME_DBG_INFO0[31..0] */ +#define WF_PLE_TOP_AIRTIME_DBG_INFO0_AIRTIME_DBG_INFO0_SHFT 0 + +/* +* ---AIRTIME_DBG_INFO1 (0x820C0000 + 0x4dc)--- +* AIRTIME_DBG_INFO1[31..0] - (RO) Station link head/tail +*/ +#define WF_PLE_TOP_AIRTIME_DBG_INFO1_AIRTIME_DBG_INFO1_ADDR \ + WF_PLE_TOP_AIRTIME_DBG_INFO1_ADDR +#define WF_PLE_TOP_AIRTIME_DBG_INFO1_AIRTIME_DBG_INFO1_MASK \ + 0xFFFFFFFF /* AIRTIME_DBG_INFO1[31..0] */ +#define WF_PLE_TOP_AIRTIME_DBG_INFO1_AIRTIME_DBG_INFO1_SHFT 0 + +/* +* ---AC0_QUEUE_EMPTY0 (0x820C0000 + 0x500)--- +* AC0_QUEUE_EMPTY_0[31..0] - (RO) Empty flag for STA 0~31 AC0 queue +*/ +#define WF_PLE_TOP_AC0_QUEUE_EMPTY0_AC0_QUEUE_EMPTY_0_ADDR \ + WF_PLE_TOP_AC0_QUEUE_EMPTY0_ADDR +#define WF_PLE_TOP_AC0_QUEUE_EMPTY0_AC0_QUEUE_EMPTY_0_MASK \ + 0xFFFFFFFF /* AC0_QUEUE_EMPTY_0[31..0] */ +#define WF_PLE_TOP_AC0_QUEUE_EMPTY0_AC0_QUEUE_EMPTY_0_SHFT 0 + +/* +* ---AC0_QUEUE_EMPTY1 (0x820C0000 + 0x504)--- +* AC0_QUEUE_EMPTY_1[31..0] - (RO) Empty flag for STA 32~63 AC0 queue +*/ +#define WF_PLE_TOP_AC0_QUEUE_EMPTY1_AC0_QUEUE_EMPTY_1_ADDR \ + WF_PLE_TOP_AC0_QUEUE_EMPTY1_ADDR +#define WF_PLE_TOP_AC0_QUEUE_EMPTY1_AC0_QUEUE_EMPTY_1_MASK \ + 0xFFFFFFFF /* AC0_QUEUE_EMPTY_1[31..0] */ +#define WF_PLE_TOP_AC0_QUEUE_EMPTY1_AC0_QUEUE_EMPTY_1_SHFT 0 + +/* +* ---AC1_QUEUE_EMPTY0 (0x820C0000 + 0x540)--- +* AC1_QUEUE_EMPTY_0[31..0] - (RO) Empty flag for STA 0~31 AC1 queue +*/ +#define WF_PLE_TOP_AC1_QUEUE_EMPTY0_AC1_QUEUE_EMPTY_0_ADDR \ + WF_PLE_TOP_AC1_QUEUE_EMPTY0_ADDR +#define WF_PLE_TOP_AC1_QUEUE_EMPTY0_AC1_QUEUE_EMPTY_0_MASK \ + 0xFFFFFFFF /* AC1_QUEUE_EMPTY_0[31..0] */ +#define WF_PLE_TOP_AC1_QUEUE_EMPTY0_AC1_QUEUE_EMPTY_0_SHFT 0 + +/* +* ---AC1_QUEUE_EMPTY1 (0x820C0000 + 0x544)--- +* AC1_QUEUE_EMPTY_1[31..0] - (RO) Empty flag for STA 32~63 AC1 queue +*/ +#define WF_PLE_TOP_AC1_QUEUE_EMPTY1_AC1_QUEUE_EMPTY_1_ADDR \ + WF_PLE_TOP_AC1_QUEUE_EMPTY1_ADDR +#define WF_PLE_TOP_AC1_QUEUE_EMPTY1_AC1_QUEUE_EMPTY_1_MASK \ + 0xFFFFFFFF /* AC1_QUEUE_EMPTY_1[31..0] */ +#define WF_PLE_TOP_AC1_QUEUE_EMPTY1_AC1_QUEUE_EMPTY_1_SHFT 0 + +/* +* ---AC2_QUEUE_EMPTY0 (0x820C0000 + 0x580)--- +* AC2_QUEUE_EMPTY_0[31..0] - (RO) Empty flag for STA 0~31 AC2 queue +*/ +#define WF_PLE_TOP_AC2_QUEUE_EMPTY0_AC2_QUEUE_EMPTY_0_ADDR \ + WF_PLE_TOP_AC2_QUEUE_EMPTY0_ADDR +#define WF_PLE_TOP_AC2_QUEUE_EMPTY0_AC2_QUEUE_EMPTY_0_MASK \ + 0xFFFFFFFF /* AC2_QUEUE_EMPTY_0[31..0] */ +#define WF_PLE_TOP_AC2_QUEUE_EMPTY0_AC2_QUEUE_EMPTY_0_SHFT 0 + +/* +* ---AC2_QUEUE_EMPTY1 (0x820C0000 + 0x584)--- +* AC2_QUEUE_EMPTY_1[31..0] - (RO) Empty flag for STA 32~63 AC2 queue +*/ +#define WF_PLE_TOP_AC2_QUEUE_EMPTY1_AC2_QUEUE_EMPTY_1_ADDR \ + WF_PLE_TOP_AC2_QUEUE_EMPTY1_ADDR +#define WF_PLE_TOP_AC2_QUEUE_EMPTY1_AC2_QUEUE_EMPTY_1_MASK \ + 0xFFFFFFFF /* AC2_QUEUE_EMPTY_1[31..0] */ +#define WF_PLE_TOP_AC2_QUEUE_EMPTY1_AC2_QUEUE_EMPTY_1_SHFT 0 + +/* +* ---AC3_QUEUE_EMPTY0 (0x820C0000 + 0x5c0)--- +* AC3_QUEUE_EMPTY_0[31..0] - (RO) Empty flag for STA 0~31 AC3 queue +*/ +#define WF_PLE_TOP_AC3_QUEUE_EMPTY0_AC3_QUEUE_EMPTY_0_ADDR \ + WF_PLE_TOP_AC3_QUEUE_EMPTY0_ADDR +#define WF_PLE_TOP_AC3_QUEUE_EMPTY0_AC3_QUEUE_EMPTY_0_MASK \ + 0xFFFFFFFF /* AC3_QUEUE_EMPTY_0[31..0] */ +#define WF_PLE_TOP_AC3_QUEUE_EMPTY0_AC3_QUEUE_EMPTY_0_SHFT 0 + +/* +* ---AC3_QUEUE_EMPTY1 (0x820C0000 + 0x5c4)--- +* AC3_QUEUE_EMPTY_1[31..0] - (RO) Empty flag for STA 32~63 AC3 queue +*/ +#define WF_PLE_TOP_AC3_QUEUE_EMPTY1_AC3_QUEUE_EMPTY_1_ADDR \ + WF_PLE_TOP_AC3_QUEUE_EMPTY1_ADDR +#define WF_PLE_TOP_AC3_QUEUE_EMPTY1_AC3_QUEUE_EMPTY_1_MASK \ + 0xFFFFFFFF /* AC3_QUEUE_EMPTY_1[31..0] */ +#define WF_PLE_TOP_AC3_QUEUE_EMPTY1_AC3_QUEUE_EMPTY_1_SHFT 0 + +/* +* ---PEEK_CR_00 (0x820C0000 + 0x600)--- +* PEEK_CR_00[31..0] - (RO) Empty flag for STA 480~511 AC3 queue +*/ +#define WF_PLE_TOP_PEEK_CR_00_PEEK_CR_00_ADDR WF_PLE_TOP_PEEK_CR_00_ADDR +#define WF_PLE_TOP_PEEK_CR_00_PEEK_CR_00_MASK 0xFFFFFFFF /* PEEK_CR_00[31..0] */ +#define WF_PLE_TOP_PEEK_CR_00_PEEK_CR_00_SHFT 0 + +/* +* ---PEEK_CR_01 (0x820C0000 + 0x604)--- +* PEEK_CR_01[31..0] - (RO) Empty flag for STA 480~511 AC3 queue +*/ +#define WF_PLE_TOP_PEEK_CR_01_PEEK_CR_01_ADDR WF_PLE_TOP_PEEK_CR_01_ADDR +#define WF_PLE_TOP_PEEK_CR_01_PEEK_CR_01_MASK 0xFFFFFFFF /* PEEK_CR_01[31..0] */ +#define WF_PLE_TOP_PEEK_CR_01_PEEK_CR_01_SHFT 0 + +/* +* ---PEEK_CR_02 (0x820C0000 + 0x608)--- +* PEEK_CR_02[31..0] - (RO) Empty flag for STA 480~511 AC3 queue +*/ +#define WF_PLE_TOP_PEEK_CR_02_PEEK_CR_02_ADDR WF_PLE_TOP_PEEK_CR_02_ADDR +#define WF_PLE_TOP_PEEK_CR_02_PEEK_CR_02_MASK 0xFFFFFFFF /* PEEK_CR_02[31..0] */ +#define WF_PLE_TOP_PEEK_CR_02_PEEK_CR_02_SHFT 0 + +/* +* ---PEEK_CR_03 (0x820C0000 + 0x60C)--- +* PEEK_CR_03[31..0] - (RO) Empty flag for STA 480~511 AC3 queue +*/ +#define WF_PLE_TOP_PEEK_CR_03_PEEK_CR_03_ADDR WF_PLE_TOP_PEEK_CR_03_ADDR +#define WF_PLE_TOP_PEEK_CR_03_PEEK_CR_03_MASK 0xFFFFFFFF /* PEEK_CR_03[31..0] */ +#define WF_PLE_TOP_PEEK_CR_03_PEEK_CR_03_SHFT 0 + +/* +* ---PEEK_CR_04 (0x820C0000 + 0x610)--- +* PEEK_CR_04[31..0] - (RO) Empty flag for STA 480~511 AC3 queue +*/ +#define WF_PLE_TOP_PEEK_CR_04_PEEK_CR_04_ADDR WF_PLE_TOP_PEEK_CR_04_ADDR +#define WF_PLE_TOP_PEEK_CR_04_PEEK_CR_04_MASK 0xFFFFFFFF /* PEEK_CR_04[31..0] */ +#define WF_PLE_TOP_PEEK_CR_04_PEEK_CR_04_SHFT 0 + +/* +* ---PEEK_CR_05 (0x820C0000 + 0x614)--- +* PEEK_CR_05[31..0] - (RO) Empty flag for STA 480~511 AC3 queue +*/ +#define WF_PLE_TOP_PEEK_CR_05_PEEK_CR_05_ADDR WF_PLE_TOP_PEEK_CR_05_ADDR +#define WF_PLE_TOP_PEEK_CR_05_PEEK_CR_05_MASK 0xFFFFFFFF /* PEEK_CR_05[31..0] */ +#define WF_PLE_TOP_PEEK_CR_05_PEEK_CR_05_SHFT 0 + +/* +* ---PEEK_CR_06 (0x820C0000 + 0x618)--- +* PEEK_CR_06[31..0] - (RO) Empty flag for STA 480~511 AC3 queue +*/ +#define WF_PLE_TOP_PEEK_CR_06_PEEK_CR_06_ADDR WF_PLE_TOP_PEEK_CR_06_ADDR +#define WF_PLE_TOP_PEEK_CR_06_PEEK_CR_06_MASK 0xFFFFFFFF /* PEEK_CR_06[31..0] */ +#define WF_PLE_TOP_PEEK_CR_06_PEEK_CR_06_SHFT 0 + +/* +* ---PEEK_CR_07 (0x820C0000 + 0x61c)--- +* PEEK_CR_07[31..0] - (RO) Empty flag for STA 480~511 AC3 queue +*/ +#define WF_PLE_TOP_PEEK_CR_07_PEEK_CR_07_ADDR WF_PLE_TOP_PEEK_CR_07_ADDR +#define WF_PLE_TOP_PEEK_CR_07_PEEK_CR_07_MASK 0xFFFFFFFF /* PEEK_CR_07[31..0] */ +#define WF_PLE_TOP_PEEK_CR_07_PEEK_CR_07_SHFT 0 + +/* +* ---PEEK_CR_08 (0x820C0000 + 0x620)--- +* PEEK_CR_08[31..0] - (RO) Empty flag for STA 480~511 AC3 queue +*/ +#define WF_PLE_TOP_PEEK_CR_08_PEEK_CR_08_ADDR WF_PLE_TOP_PEEK_CR_08_ADDR +#define WF_PLE_TOP_PEEK_CR_08_PEEK_CR_08_MASK 0xFFFFFFFF /* PEEK_CR_08[31..0] */ +#define WF_PLE_TOP_PEEK_CR_08_PEEK_CR_08_SHFT 0 + +/* +* ---PEEK_CR_09 (0x820C0000 + 0x624)--- +* PEEK_CR_09[31..0] - (RO) Empty flag for STA 480~511 AC3 queue +*/ +#define WF_PLE_TOP_PEEK_CR_09_PEEK_CR_09_ADDR WF_PLE_TOP_PEEK_CR_09_ADDR +#define WF_PLE_TOP_PEEK_CR_09_PEEK_CR_09_MASK 0xFFFFFFFF /* PEEK_CR_09[31..0] */ +#define WF_PLE_TOP_PEEK_CR_09_PEEK_CR_09_SHFT 0 + +/* +* ---PEEK_CR_10 (0x820C0000 + 0x628)--- +* PEEK_CR_10[31..0] - (RO) Empty flag for STA 480~511 AC3 queue +*/ +#define WF_PLE_TOP_PEEK_CR_10_PEEK_CR_10_ADDR WF_PLE_TOP_PEEK_CR_10_ADDR +#define WF_PLE_TOP_PEEK_CR_10_PEEK_CR_10_MASK 0xFFFFFFFF /* PEEK_CR_10[31..0] */ +#define WF_PLE_TOP_PEEK_CR_10_PEEK_CR_10_SHFT 0 + +/* +* ---PEEK_CR_11 (0x820C0000 + 0x62c)--- +* PEEK_CR_11[31..0] - (RO) Empty flag for STA 480~511 AC3 queue +*/ +#define WF_PLE_TOP_PEEK_CR_11_PEEK_CR_11_ADDR WF_PLE_TOP_PEEK_CR_11_ADDR +#define WF_PLE_TOP_PEEK_CR_11_PEEK_CR_11_MASK 0xFFFFFFFF /* PEEK_CR_11[31..0] */ +#define WF_PLE_TOP_PEEK_CR_11_PEEK_CR_11_SHFT 0 + +/* +* ---AMSDU_GC (0x820C0000 + 0x1000)--- +* EN_HW_AMSDU[0] - (RW) Enable control of HW AMSDU function. +* RESERVED1[7..1] - (RO) Reserved bits +* DIS_AMSDU_Q_EMPTY_FLUSH[8] - (RW) Disable control of HW AMSDU queue empty +* trigger packet flush function. +* DIS_LMAC_TX_NO_FULL_FLUSH[9] - (RW) Disable control of LMAC TX no get full +* packet trigger packet flush function. +* DIS_SFD_KEEP_SAME_PAGE[10] - (RW) Disable control of keep same page number +* of StoreForward packet function. +* RESERVED11[31..11] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_AMSDU_GC_DIS_SFD_KEEP_SAME_PAGE_ADDR WF_PLE_TOP_AMSDU_GC_ADDR +#define WF_PLE_TOP_AMSDU_GC_DIS_SFD_KEEP_SAME_PAGE_MASK \ + 0x00000400 /* DIS_SFD_KEEP_SAME_PAGE[10] */ +#define WF_PLE_TOP_AMSDU_GC_DIS_SFD_KEEP_SAME_PAGE_SHFT 10 +#define WF_PLE_TOP_AMSDU_GC_DIS_LMAC_TX_NO_FULL_FLUSH_ADDR \ + WF_PLE_TOP_AMSDU_GC_ADDR +#define WF_PLE_TOP_AMSDU_GC_DIS_LMAC_TX_NO_FULL_FLUSH_MASK \ + 0x00000200 /* DIS_LMAC_TX_NO_FULL_FLUSH[9] */ +#define WF_PLE_TOP_AMSDU_GC_DIS_LMAC_TX_NO_FULL_FLUSH_SHFT 9 +#define WF_PLE_TOP_AMSDU_GC_DIS_AMSDU_Q_EMPTY_FLUSH_ADDR \ + WF_PLE_TOP_AMSDU_GC_ADDR +#define WF_PLE_TOP_AMSDU_GC_DIS_AMSDU_Q_EMPTY_FLUSH_MASK \ + 0x00000100 /* DIS_AMSDU_Q_EMPTY_FLUSH[8] */ +#define WF_PLE_TOP_AMSDU_GC_DIS_AMSDU_Q_EMPTY_FLUSH_SHFT 8 +#define WF_PLE_TOP_AMSDU_GC_EN_HW_AMSDU_ADDR WF_PLE_TOP_AMSDU_GC_ADDR +#define WF_PLE_TOP_AMSDU_GC_EN_HW_AMSDU_MASK 0x00000001 /* EN_HW_AMSDU[0] */ +#define WF_PLE_TOP_AMSDU_GC_EN_HW_AMSDU_SHFT 0 + +/* +* ---AMSDU_TXD_COMP_MAP_0 (0x820C0000 + 0x1004)--- +* TXDIN_TRIGGER_TH[11..0] - (RW) The TXD merge trigger threshold. +* RESERVED12[15..12] - (RO) Reserved bits +* TXD_COMPARE_NEED_MAP[31..16] - (RW) The compare bitmap for merging TXD. +*/ +#define WF_PLE_TOP_AMSDU_TXD_COMP_MAP_0_TXD_COMPARE_NEED_MAP_ADDR \ + WF_PLE_TOP_AMSDU_TXD_COMP_MAP_0_ADDR +#define WF_PLE_TOP_AMSDU_TXD_COMP_MAP_0_TXD_COMPARE_NEED_MAP_MASK \ + 0xFFFF0000 /* TXD_COMPARE_NEED_MAP[31..16] */ +#define WF_PLE_TOP_AMSDU_TXD_COMP_MAP_0_TXD_COMPARE_NEED_MAP_SHFT 16 +#define WF_PLE_TOP_AMSDU_TXD_COMP_MAP_0_TXDIN_TRIGGER_TH_ADDR \ + WF_PLE_TOP_AMSDU_TXD_COMP_MAP_0_ADDR +#define WF_PLE_TOP_AMSDU_TXD_COMP_MAP_0_TXDIN_TRIGGER_TH_MASK \ + 0x00000FFF /* TXDIN_TRIGGER_TH[11..0] */ +#define WF_PLE_TOP_AMSDU_TXD_COMP_MAP_0_TXDIN_TRIGGER_TH_SHFT 0 + +/* +* ---AMSDU_TXD_COMP_MAP_1 (0x820C0000 + 0x1008)--- +* TXD_COMPARE_NEED_MAP[31..0] - (RW) The compare bitmap for merging TXD. +*/ +#define WF_PLE_TOP_AMSDU_TXD_COMP_MAP_1_TXD_COMPARE_NEED_MAP_ADDR \ + WF_PLE_TOP_AMSDU_TXD_COMP_MAP_1_ADDR +#define WF_PLE_TOP_AMSDU_TXD_COMP_MAP_1_TXD_COMPARE_NEED_MAP_MASK \ + 0xFFFFFFFF /* TXD_COMPARE_NEED_MAP[31..0] */ +#define WF_PLE_TOP_AMSDU_TXD_COMP_MAP_1_TXD_COMPARE_NEED_MAP_SHFT 0 + +/* +* ---AMSDU_INT_N9_ERR_MASK (0x820C0000 + 0x100c)--- +* EN_AMSDU_Q_CMD_ERR[0] - (RW) Enables queue command error interrupt +* status of port AMSDU +* RESERVED1[3..1] - (RO) Reserved bits +* EN_AMSDU_PAGE_UDF[4] - (RW) Enables page underflow interrupt status +* of port AMSDU +* RESERVED5[11..5] - (RO) Reserved bits +* EN_AMSDU_DATA_OPER_ERR[12] - (RW) Enables data operation error of port +AMSDU +* RESERVED13[15..13] - (RO) Reserved bits +* EN_AMSDU_PORT_HANG_ERR[16] - (RW) Enables AMSDU port FSM hang error +interrupt +* EN_AMSDU_CTRL_HANG_ERR[17] - (RW) Enables AMSDU CTRL FSM hang error +interrupt +* RESERVED18[31..18] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_CTRL_HANG_ERR_ADDR \ + WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_CTRL_HANG_ERR_MASK \ + 0x00020000 /* EN_AMSDU_CTRL_HANG_ERR[17] */ +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_CTRL_HANG_ERR_SHFT 17 +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_PORT_HANG_ERR_ADDR \ + WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_PORT_HANG_ERR_MASK \ + 0x00010000 /* EN_AMSDU_PORT_HANG_ERR[16] */ +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_PORT_HANG_ERR_SHFT 16 +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_DATA_OPER_ERR_ADDR \ + WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_DATA_OPER_ERR_MASK \ + 0x00001000 /* EN_AMSDU_DATA_OPER_ERR[12] */ +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_DATA_OPER_ERR_SHFT 12 +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_PAGE_UDF_ADDR \ + WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_PAGE_UDF_MASK \ + 0x00000010 /* EN_AMSDU_PAGE_UDF[4] */ +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_PAGE_UDF_SHFT 4 +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_Q_CMD_ERR_ADDR \ + WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_Q_CMD_ERR_MASK \ + 0x00000001 /* EN_AMSDU_Q_CMD_ERR[0] */ +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_Q_CMD_ERR_SHFT 0 + +/* +* ---AMSDU_INT_N9_ERR_STS (0x820C0000 + 0x1010)--- +* AMSDU_Q_CMD_ERR[0] - (W1C) Queue command error interrupt status of +* port AMSDU. Avoid unclear error flag, please clear flag when logic reset. +* RESERVED1[3..1] - (RO) Reserved bits +* AMSDU_PAGE_UDF[4] - (W1C) Page underflow interrupt status of port +* AMSDU. Avoid unclear error flag, please clear flag when logic reset. +* RESERVED5[11..5] - (RO) Reserved bits +* AMSDU_DATA_OPER_ERR[12] - (W1C) Data operation error of port AMSDU. +* Avoid unclear error flag, please clear flag when logic reset. +* RESERVED13[15..13] - (RO) Reserved bits +* AMSDU_PORT_HANG_ERR[16] - (W1C) AMSDU port FSM hang error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* AMSDU_CTRL_HANG_ERR[17] - (W1C) AMSDU FSM hang error interrupt. Avoid +* unclear error flag, please clear flag when logic reset. +* RESERVED18[31..18] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_CTRL_HANG_ERR_ADDR \ + WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_CTRL_HANG_ERR_MASK \ + 0x00020000 /* AMSDU_CTRL_HANG_ERR[17] */ +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_CTRL_HANG_ERR_SHFT 17 +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_PORT_HANG_ERR_ADDR \ + WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_PORT_HANG_ERR_MASK \ + 0x00010000 /* AMSDU_PORT_HANG_ERR[16] */ +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_PORT_HANG_ERR_SHFT 16 +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_DATA_OPER_ERR_ADDR \ + WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_DATA_OPER_ERR_MASK \ + 0x00001000 /* AMSDU_DATA_OPER_ERR[12] */ +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_DATA_OPER_ERR_SHFT 12 +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_PAGE_UDF_ADDR \ + WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_PAGE_UDF_MASK \ + 0x00000010 /* AMSDU_PAGE_UDF[4] */ +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_PAGE_UDF_SHFT 4 +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_Q_CMD_ERR_ADDR \ + WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_Q_CMD_ERR_MASK \ + 0x00000001 /* AMSDU_Q_CMD_ERR[0] */ +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_Q_CMD_ERR_SHFT 0 + +/* +* ---AMSDU_PEEK_CR_00 (0x820C0000 + 0x10d0)--- +* AMSDU_DOP_CS[3..0] - (RO) AMSDU Data operation current state. +* RESERVED4[7..4] - (RO) Reserved bits +* AMSDU_CS[12..8] - (RO) AMSDU Merge Engine current state. +* RESERVED13[15..13] - (RO) Reserved bits +* AMSDU_Q_EMPTY_CS[17..16] - (RO) AMSDU Queue Empty Search Engine current +state. +* RESERVED18[23..18] - (RO) Reserved bits +* AMSDU_ARB_CS[26..24] - (RO) AMSDU Request Arbitration Current state. +* RESERVED27[31..27] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_AMSDU_PEEK_CR_00_AMSDU_ARB_CS_ADDR \ + WF_PLE_TOP_AMSDU_PEEK_CR_00_ADDR +#define WF_PLE_TOP_AMSDU_PEEK_CR_00_AMSDU_ARB_CS_MASK \ + 0x07000000 /* AMSDU_ARB_CS[26..24] */ +#define WF_PLE_TOP_AMSDU_PEEK_CR_00_AMSDU_ARB_CS_SHFT 24 +#define WF_PLE_TOP_AMSDU_PEEK_CR_00_AMSDU_Q_EMPTY_CS_ADDR \ + WF_PLE_TOP_AMSDU_PEEK_CR_00_ADDR +#define WF_PLE_TOP_AMSDU_PEEK_CR_00_AMSDU_Q_EMPTY_CS_MASK \ + 0x00030000 /* AMSDU_Q_EMPTY_CS[17..16] */ +#define WF_PLE_TOP_AMSDU_PEEK_CR_00_AMSDU_Q_EMPTY_CS_SHFT 16 +#define WF_PLE_TOP_AMSDU_PEEK_CR_00_AMSDU_CS_ADDR \ + WF_PLE_TOP_AMSDU_PEEK_CR_00_ADDR +#define WF_PLE_TOP_AMSDU_PEEK_CR_00_AMSDU_CS_MASK \ + 0x00001F00 /* AMSDU_CS[12..8] */ +#define WF_PLE_TOP_AMSDU_PEEK_CR_00_AMSDU_CS_SHFT 8 +#define WF_PLE_TOP_AMSDU_PEEK_CR_00_AMSDU_DOP_CS_ADDR \ + WF_PLE_TOP_AMSDU_PEEK_CR_00_ADDR +#define WF_PLE_TOP_AMSDU_PEEK_CR_00_AMSDU_DOP_CS_MASK \ + 0x0000000F /* AMSDU_DOP_CS[3..0] */ +#define WF_PLE_TOP_AMSDU_PEEK_CR_00_AMSDU_DOP_CS_SHFT 0 + +/* +* ---AMSDU_PEEK_CR_01 (0x820C0000 + 0x10d4)--- +* AMSDU_DOP_PBUF_CS[2..0] - (RO) PLE AMSDU port - Data operation PBUF +* current state. +* RESERVED3[3] - (RO) Reserved bits +* AMSDU_DOP_CACHE_CS[5..4] - (RO) PLE AMSDU port - Data operation CACHE +* current state. +* RESERVED6[7..6] - (RO) Reserved bits +* AMSDU_QOP_Q_OPER_CS[11..8] - (RO) PLE AMSDU port - Queue operation current +state. +* AMSDU_QOP_RL_OCP_CS[13..12] - (RO) PLE AMSDU port - Queue operation RL +* current state. +* RESERVED14[15..14] - (RO) Reserved bits +* AMSDU_QOP_PL_OCP_CS[17..16] - (RO) PLE AMSDU port - Queue operation PL +* current state. +* RESERVED18[19..18] - (RO) Reserved bits +* AMSDU_QOP_ALLOCATE_CS[22..20] - (RO) PLE AMSDU port - Queue operation +* allocate current state. +* RESERVED23[31..23] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_QOP_ALLOCATE_CS_ADDR \ + WF_PLE_TOP_AMSDU_PEEK_CR_01_ADDR +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_QOP_ALLOCATE_CS_MASK \ + 0x00700000 /* AMSDU_QOP_ALLOCATE_CS[22..20] */ +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_QOP_ALLOCATE_CS_SHFT 20 +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_QOP_PL_OCP_CS_ADDR \ + WF_PLE_TOP_AMSDU_PEEK_CR_01_ADDR +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_QOP_PL_OCP_CS_MASK \ + 0x00030000 /* AMSDU_QOP_PL_OCP_CS[17..16] */ +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_QOP_PL_OCP_CS_SHFT 16 +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_QOP_RL_OCP_CS_ADDR \ + WF_PLE_TOP_AMSDU_PEEK_CR_01_ADDR +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_QOP_RL_OCP_CS_MASK \ + 0x00003000 /* AMSDU_QOP_RL_OCP_CS[13..12] */ +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_QOP_RL_OCP_CS_SHFT 12 +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_QOP_Q_OPER_CS_ADDR \ + WF_PLE_TOP_AMSDU_PEEK_CR_01_ADDR +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_QOP_Q_OPER_CS_MASK \ + 0x00000F00 /* AMSDU_QOP_Q_OPER_CS[11..8] */ +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_QOP_Q_OPER_CS_SHFT 8 +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_DOP_CACHE_CS_ADDR \ + WF_PLE_TOP_AMSDU_PEEK_CR_01_ADDR +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_DOP_CACHE_CS_MASK \ + 0x00000030 /* AMSDU_DOP_CACHE_CS[5..4] */ +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_DOP_CACHE_CS_SHFT 4 +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_DOP_PBUF_CS_ADDR \ + WF_PLE_TOP_AMSDU_PEEK_CR_01_ADDR +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_DOP_PBUF_CS_MASK \ + 0x00000007 /* AMSDU_DOP_PBUF_CS[2..0] */ +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_DOP_PBUF_CS_SHFT 0 + +/* +* ---AMSDU_PACK_1_MSDU_CNT (0x820C0000 + 0x10e0)--- +* pack_1_msdu_cnt[15..0] - (RC) AMSDU pack count of 1 MSDU in TXD. +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_AMSDU_PACK_1_MSDU_CNT_pack_1_msdu_cnt_ADDR \ + WF_PLE_TOP_AMSDU_PACK_1_MSDU_CNT_ADDR +#define WF_PLE_TOP_AMSDU_PACK_1_MSDU_CNT_pack_1_msdu_cnt_MASK \ + 0x0000FFFF /* pack_1_msdu_cnt[15..0] */ +#define WF_PLE_TOP_AMSDU_PACK_1_MSDU_CNT_pack_1_msdu_cnt_SHFT 0 + +/* +* ---AMSDU_PACK_2_MSDU_CNT (0x820C0000 + 0x10e4)--- +* pack_2_msdu_cnt[15..0] - (RC) AMSDU pack count of 2 MSDU in TXD. +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_AMSDU_PACK_2_MSDU_CNT_pack_2_msdu_cnt_ADDR \ + WF_PLE_TOP_AMSDU_PACK_2_MSDU_CNT_ADDR +#define WF_PLE_TOP_AMSDU_PACK_2_MSDU_CNT_pack_2_msdu_cnt_MASK \ + 0x0000FFFF /* pack_2_msdu_cnt[15..0] */ +#define WF_PLE_TOP_AMSDU_PACK_2_MSDU_CNT_pack_2_msdu_cnt_SHFT 0 + +/* +* ---AMSDU_PACK_3_MSDU_CNT (0x820C0000 + 0x10e8)--- +* pack_3_msdu_cnt[15..0] - (RC) AMSDU pack count of 3 MSDU in TXD. +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_AMSDU_PACK_3_MSDU_CNT_pack_3_msdu_cnt_ADDR \ + WF_PLE_TOP_AMSDU_PACK_3_MSDU_CNT_ADDR +#define WF_PLE_TOP_AMSDU_PACK_3_MSDU_CNT_pack_3_msdu_cnt_MASK \ + 0x0000FFFF /* pack_3_msdu_cnt[15..0] */ +#define WF_PLE_TOP_AMSDU_PACK_3_MSDU_CNT_pack_3_msdu_cnt_SHFT 0 + +/* +* ---AMSDU_PACK_4_MSDU_CNT (0x820C0000 + 0x10ec)--- +* pack_4_msdu_cnt[15..0] - (RC) AMSDU pack count of 4 MSDU in TXD. +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_AMSDU_PACK_4_MSDU_CNT_pack_4_msdu_cnt_ADDR \ + WF_PLE_TOP_AMSDU_PACK_4_MSDU_CNT_ADDR +#define WF_PLE_TOP_AMSDU_PACK_4_MSDU_CNT_pack_4_msdu_cnt_MASK \ + 0x0000FFFF /* pack_4_msdu_cnt[15..0] */ +#define WF_PLE_TOP_AMSDU_PACK_4_MSDU_CNT_pack_4_msdu_cnt_SHFT 0 + +/* +* ---AMSDU_PACK_5_MSDU_CNT (0x820C0000 + 0x10f0)--- +* pack_5_msdu_cnt[15..0] - (RC) AMSDU pack count of 5 MSDU in TXD. +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_AMSDU_PACK_5_MSDU_CNT_pack_5_msdu_cnt_ADDR \ + WF_PLE_TOP_AMSDU_PACK_5_MSDU_CNT_ADDR +#define WF_PLE_TOP_AMSDU_PACK_5_MSDU_CNT_pack_5_msdu_cnt_MASK \ + 0x0000FFFF /* pack_5_msdu_cnt[15..0] */ +#define WF_PLE_TOP_AMSDU_PACK_5_MSDU_CNT_pack_5_msdu_cnt_SHFT 0 + +/* +* ---AMSDU_PACK_6_MSDU_CNT (0x820C0000 + 0x10f4)--- +* pack_6_msdu_cnt[15..0] - (RC) AMSDU pack count of 4 MSDU in TXD. +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_AMSDU_PACK_6_MSDU_CNT_pack_6_msdu_cnt_ADDR \ + WF_PLE_TOP_AMSDU_PACK_6_MSDU_CNT_ADDR +#define WF_PLE_TOP_AMSDU_PACK_6_MSDU_CNT_pack_6_msdu_cnt_MASK \ + 0x0000FFFF /* pack_6_msdu_cnt[15..0] */ +#define WF_PLE_TOP_AMSDU_PACK_6_MSDU_CNT_pack_6_msdu_cnt_SHFT 0 + +/* +* ---AMSDU_PACK_7_MSDU_CNT (0x820C0000 + 0x10f8)--- +* pack_7_msdu_cnt[15..0] - (RC) AMSDU pack count of 7 MSDU in TXD. +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_AMSDU_PACK_7_MSDU_CNT_pack_7_msdu_cnt_ADDR \ + WF_PLE_TOP_AMSDU_PACK_7_MSDU_CNT_ADDR +#define WF_PLE_TOP_AMSDU_PACK_7_MSDU_CNT_pack_7_msdu_cnt_MASK \ + 0x0000FFFF /* pack_7_msdu_cnt[15..0] */ +#define WF_PLE_TOP_AMSDU_PACK_7_MSDU_CNT_pack_7_msdu_cnt_SHFT 0 + +/* +* ---AMSDU_PACK_8_MSDU_CNT (0x820C0000 + 0x10fc)--- +* pack_8_msdu_cnt[15..0] - (RC) AMSDU pack count of 8 MSDU in TXD. +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_AMSDU_PACK_8_MSDU_CNT_pack_8_msdu_cnt_ADDR \ + WF_PLE_TOP_AMSDU_PACK_8_MSDU_CNT_ADDR +#define WF_PLE_TOP_AMSDU_PACK_8_MSDU_CNT_pack_8_msdu_cnt_MASK \ + 0x0000FFFF /* pack_8_msdu_cnt[15..0] */ +#define WF_PLE_TOP_AMSDU_PACK_8_MSDU_CNT_pack_8_msdu_cnt_SHFT 0 + +/* +* ---AMSDU_AC0_QUEUE_EMPTY0 (0x820C0000 + 0x1100)--- +* AMSDU_QUEUE_EMPTY_FLAG_31_0[31..0] - (RO) AC0 queue empty flag for +* station31~station0 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY0_AMSDU_QUEUE_EMPTY_FLAG_31_0_ADDR \ + WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY0_ADDR +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY0_AMSDU_QUEUE_EMPTY_FLAG_31_0_MASK \ + 0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_31_0[31..0] */ +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY0_AMSDU_QUEUE_EMPTY_FLAG_31_0_SHFT 0 + +/* +* ---AMSDU_AC0_QUEUE_EMPTY1 (0x820C0000 + 0x1104)--- +* AMSDU_QUEUE_EMPTY_FLAG_63_32[31..0] - (RO) AC0 queue empty flag for +* station63~station32 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY1_AMSDU_QUEUE_EMPTY_FLAG_63_32_ADDR \ + WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY1_ADDR +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY1_AMSDU_QUEUE_EMPTY_FLAG_63_32_MASK \ + 0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_63_32[31..0] */ +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY1_AMSDU_QUEUE_EMPTY_FLAG_63_32_SHFT 0 + +/* +* ---AMSDU_AC1_QUEUE_EMPTY0 (0x820C0000 + 0x1140)--- +* AMSDU_QUEUE_EMPTY_FLAG_31_0[31..0] - (RO) AC1 queue empty flag for +* station31~station0 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY0_AMSDU_QUEUE_EMPTY_FLAG_31_0_ADDR \ + WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY0_ADDR +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY0_AMSDU_QUEUE_EMPTY_FLAG_31_0_MASK \ + 0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_31_0[31..0] */ +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY0_AMSDU_QUEUE_EMPTY_FLAG_31_0_SHFT 0 + +/* +* ---AMSDU_AC1_QUEUE_EMPTY1 (0x820C0000 + 0x1144)--- +* AMSDU_QUEUE_EMPTY_FLAG_63_32[31..0] - (RO) AC1 queue empty flag for +* station63~station32 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY1_AMSDU_QUEUE_EMPTY_FLAG_63_32_ADDR \ + WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY1_ADDR +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY1_AMSDU_QUEUE_EMPTY_FLAG_63_32_MASK \ + 0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_63_32[31..0] */ +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY1_AMSDU_QUEUE_EMPTY_FLAG_63_32_SHFT 0 + +/* +* ---AMSDU_AC2_QUEUE_EMPTY0 (0x820C0000 + 0x1180)--- +* AMSDU_QUEUE_EMPTY_FLAG_31_0[31..0] - (RO) AC2 queue empty flag for +* station31~station0 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY0_AMSDU_QUEUE_EMPTY_FLAG_31_0_ADDR \ + WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY0_ADDR +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY0_AMSDU_QUEUE_EMPTY_FLAG_31_0_MASK \ + 0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_31_0[31..0] */ +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY0_AMSDU_QUEUE_EMPTY_FLAG_31_0_SHFT 0 + +/* +* ---AMSDU_AC2_QUEUE_EMPTY1 (0x820C0000 + 0x1184)--- +* AMSDU_QUEUE_EMPTY_FLAG_63_32[31..0] - (RO) AC2 queue empty flag for +* station63~station32 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY1_AMSDU_QUEUE_EMPTY_FLAG_63_32_ADDR \ + WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY1_ADDR +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY1_AMSDU_QUEUE_EMPTY_FLAG_63_32_MASK \ + 0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_63_32[31..0] */ +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY1_AMSDU_QUEUE_EMPTY_FLAG_63_32_SHFT 0 + +/* +* ---AMSDU_AC3_QUEUE_EMPTY0 (0x820C0000 + 0x11C0)--- +* AMSDU_QUEUE_EMPTY_FLAG_31_0[31..0] - (RO) AC3 queue empty flag for +* station31~station0 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY0_AMSDU_QUEUE_EMPTY_FLAG_31_0_ADDR \ + WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY0_ADDR +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY0_AMSDU_QUEUE_EMPTY_FLAG_31_0_MASK \ + 0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_31_0[31..0] */ +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY0_AMSDU_QUEUE_EMPTY_FLAG_31_0_SHFT 0 + +/* +* ---AMSDU_AC3_QUEUE_EMPTY1 (0x820C0000 + 0x11C4)--- +* AMSDU_QUEUE_EMPTY_FLAG_63_32[31..0] - (RO) AC3 queue empty flag for +* station63~station32 in HW AMSDU engine. +*/ +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY1_AMSDU_QUEUE_EMPTY_FLAG_63_32_ADDR \ + WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY1_ADDR +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY1_AMSDU_QUEUE_EMPTY_FLAG_63_32_MASK \ + 0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_63_32[31..0] */ +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY1_AMSDU_QUEUE_EMPTY_FLAG_63_32_SHFT 0 + +/* +* ---CFG_DBDC_CTRL0 (0x820C0000 + 0x2008)--- +* RESERVED0[7..0] - (RO) Reserved bits +* WMM_0TO3_BAND_SEL[11..8] - (RW) Selects WMM0~WMM3 band +* RESERVED12[15..12] - (RO) Reserved bits +* NAN_BAND_SEL[16] - (RW) Selects NAN band +* FUNCQ_BAND_SEL[17] - (RW) Selects Functional Queue band +* TGID 0 & TGID1 always selec to different +band +* RESERVED18[30..18] - (RO) Reserved bits +* DBDC_EN[31] - (RO) Enables DBDC +*/ +#define WF_PLE_TOP_CFG_DBDC_CTRL0_DBDC_EN_ADDR WF_PLE_TOP_CFG_DBDC_CTRL0_ADDR +#define WF_PLE_TOP_CFG_DBDC_CTRL0_DBDC_EN_MASK 0x80000000 /* DBDC_EN[31] */ +#define WF_PLE_TOP_CFG_DBDC_CTRL0_DBDC_EN_SHFT 31 +#define WF_PLE_TOP_CFG_DBDC_CTRL0_FUNCQ_BAND_SEL_ADDR \ + WF_PLE_TOP_CFG_DBDC_CTRL0_ADDR +#define WF_PLE_TOP_CFG_DBDC_CTRL0_FUNCQ_BAND_SEL_MASK \ + 0x00020000 /* FUNCQ_BAND_SEL[17] */ +#define WF_PLE_TOP_CFG_DBDC_CTRL0_FUNCQ_BAND_SEL_SHFT 17 +#define WF_PLE_TOP_CFG_DBDC_CTRL0_NAN_BAND_SEL_ADDR \ + WF_PLE_TOP_CFG_DBDC_CTRL0_ADDR +#define WF_PLE_TOP_CFG_DBDC_CTRL0_NAN_BAND_SEL_MASK \ + 0x00010000 /* NAN_BAND_SEL[16] */ +#define WF_PLE_TOP_CFG_DBDC_CTRL0_NAN_BAND_SEL_SHFT 16 +#define WF_PLE_TOP_CFG_DBDC_CTRL0_WMM_0TO3_BAND_SEL_ADDR \ + WF_PLE_TOP_CFG_DBDC_CTRL0_ADDR +#define WF_PLE_TOP_CFG_DBDC_CTRL0_WMM_0TO3_BAND_SEL_MASK \ + 0x00000F00 /* WMM_0TO3_BAND_SEL[11..8] */ +#define WF_PLE_TOP_CFG_DBDC_CTRL0_WMM_0TO3_BAND_SEL_SHFT 8 + +/* +* ---CFG_UWTBL_MBIST_CTRL_0 (0x820C0000 + 0x2480)--- +* UWTBL_MBIST_MODE[0] - (RW) Control register for mbist_mode of UWTBL +MBIST +* UWTBL_MBIST_HOLDB[1] - (RW) Control register for mbist_holdb of +* UWTBL MBIST +* UWTBL_MBIST_DEBUG[2] - (RW) Control register for mbist_debug of +* UWTBL MBIST +* UWTBL_MBIST_USE_DEFAULT_DELSEL[3] - (RW) Control register for default DELSEL +* value of UWTBL memory +* UWTBL_MBIST_SLEEP_TEST[4] - (RW) Control register for sleep_test of UWTBL +MBIST +* UWTBL_MBIST_SLEEP_INV[5] - (RW) Control register for sleep_inv of UWTBL +MBIST +* UWTBL_MBIST_SLEEP_W[6] - (RW) Control register for sleep_w of UWTBL +MBIST +* UWTBL_MBIST_SLEEP_R[7] - (RW) Control register for sleep_r of UWTBL +MBIST +* UWTBL_MBIST_DONE[8] - (RO) Working status of UWTBL SRAM MBIST +circuit +* RESERVED9[15..9] - (RO) Reserved bits +* UWTBL_MBIST_FAIL[21..16] - (RO) MBIST check result of UWTBL SRAM +* RESERVED22[31..22] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_FAIL_ADDR \ + WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_FAIL_MASK \ + 0x003F0000 /* UWTBL_MBIST_FAIL[21..16] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_FAIL_SHFT 16 +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_DONE_ADDR \ + WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_DONE_MASK \ + 0x00000100 /* UWTBL_MBIST_DONE[8] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_DONE_SHFT 8 +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_SLEEP_R_ADDR \ + WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_SLEEP_R_MASK \ + 0x00000080 /* UWTBL_MBIST_SLEEP_R[7] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_SLEEP_R_SHFT 7 +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_SLEEP_W_ADDR \ + WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_SLEEP_W_MASK \ + 0x00000040 /* UWTBL_MBIST_SLEEP_W[6] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_SLEEP_W_SHFT 6 +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_SLEEP_INV_ADDR \ + WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_SLEEP_INV_MASK \ + 0x00000020 /* UWTBL_MBIST_SLEEP_INV[5] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_SLEEP_INV_SHFT 5 +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_SLEEP_TEST_ADDR \ + WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_SLEEP_TEST_MASK \ + 0x00000010 /* UWTBL_MBIST_SLEEP_TEST[4] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_SLEEP_TEST_SHFT 4 +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_USE_DEFAULT_DELSEL_ADDR \ + WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_USE_DEFAULT_DELSEL_MASK \ + 0x00000008 /* UWTBL_MBIST_USE_DEFAULT_DELSEL[3] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_USE_DEFAULT_DELSEL_SHFT 3 +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_DEBUG_ADDR \ + WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_DEBUG_MASK \ + 0x00000004 /* UWTBL_MBIST_DEBUG[2] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_DEBUG_SHFT 2 +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_HOLDB_ADDR \ + WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_HOLDB_MASK \ + 0x00000002 /* UWTBL_MBIST_HOLDB[1] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_HOLDB_SHFT 1 +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_MODE_ADDR \ + WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_MODE_MASK \ + 0x00000001 /* UWTBL_MBIST_MODE[0] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_MODE_SHFT 0 + +/* +* ---CFG_UWTBL_MBIST_CTRL_1 (0x820C0000 + 0x2484)--- +* UWTBL_MBIST_HDEN[5..0] - (RW) Control register for mbist UWTBL HDEN +* RESERVED6[15..6] - (RO) Reserved bits +* UWTBL_MBIST_AWT[21..16] - (RW) Control register for mbist UWTBL AWT +* RESERVED22[31..22] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_1_UWTBL_MBIST_AWT_ADDR \ + WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_1_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_1_UWTBL_MBIST_AWT_MASK \ + 0x003F0000 /* UWTBL_MBIST_AWT[21..16] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_1_UWTBL_MBIST_AWT_SHFT 16 +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_1_UWTBL_MBIST_HDEN_ADDR \ + WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_1_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_1_UWTBL_MBIST_HDEN_MASK \ + 0x0000003F /* UWTBL_MBIST_HDEN[5..0] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_1_UWTBL_MBIST_HDEN_SHFT 0 + +/* +* ---CFG_UWTBL_MBIST_CTRL_2 (0x820C0000 + 0x2488)--- +* UWTBL_BACKGROUND[15..0] - (RW) The MBIST background control register +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_2_UWTBL_BACKGROUND_ADDR \ + WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_2_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_2_UWTBL_BACKGROUND_MASK \ + 0x0000FFFF /* UWTBL_BACKGROUND[15..0] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_2_UWTBL_BACKGROUND_SHFT 0 + +/* +* ---CFG_UWTBL_MBIST_CTRL_3 (0x820C0000 + 0x248c)--- +* UWTBL_DELSEL_0[31..0] - (RW) UWTBL DELSEL 0 +*/ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_3_UWTBL_DELSEL_0_ADDR \ + WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_3_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_3_UWTBL_DELSEL_0_MASK \ + 0xFFFFFFFF /* UWTBL_DELSEL_0[31..0] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_3_UWTBL_DELSEL_0_SHFT 0 + +/* +* ---CFG_UWTBL_MBIST_CTRL_4 (0x820C0000 + 0x2490)--- +* UWTBL_DELSEL_1[31..0] - (RW) UWTBL DELSEL 1 +*/ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_4_UWTBL_DELSEL_1_ADDR \ + WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_4_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_4_UWTBL_DELSEL_1_MASK \ + 0xFFFFFFFF /* UWTBL_DELSEL_1[31..0] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_4_UWTBL_DELSEL_1_SHFT 0 + +/* +* ---CFG_UWTBL_MBIST_CTRL_5 (0x820C0000 + 0x2494)--- +* UWTBL_FUSE[6..0] - (RW) UWTBL FUSE +* RESERVED7[7] - (RO) Reserved bits +* UWTBL_PRE_FUSE[14..8] - (RO) UWTBL MBIST Pre Fuse +* RESERVED15[15] - (RO) Reserved bits +* UWTBL_MBIST_REPAIR_OK[21..16] - (RO) MBIST Repair OK +* RESERVED22[23..22] - (RO) Reserved bits +* UWTBL_MBIST_REPAIR_FAIL[29..24] - (RO) MBIST Repair Fail +* RESERVED30[31..30] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_UWTBL_MBIST_REPAIR_FAIL_ADDR \ + WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_UWTBL_MBIST_REPAIR_FAIL_MASK \ + 0x3F000000 /* UWTBL_MBIST_REPAIR_FAIL[29..24] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_UWTBL_MBIST_REPAIR_FAIL_SHFT 24 +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_UWTBL_MBIST_REPAIR_OK_ADDR \ + WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_UWTBL_MBIST_REPAIR_OK_MASK \ + 0x003F0000 /* UWTBL_MBIST_REPAIR_OK[21..16] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_UWTBL_MBIST_REPAIR_OK_SHFT 16 +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_UWTBL_PRE_FUSE_ADDR \ + WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_UWTBL_PRE_FUSE_MASK \ + 0x00007F00 /* UWTBL_PRE_FUSE[14..8] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_UWTBL_PRE_FUSE_SHFT 8 +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_UWTBL_FUSE_ADDR \ + WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_UWTBL_FUSE_MASK \ + 0x0000007F /* UWTBL_FUSE[6..0] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_UWTBL_FUSE_SHFT 0 + +/* +* ---CFG_UWTBL_MBIST_CTRL_6 (0x820C0000 + 0x2498)--- +* UWTBL_DELSEL_2[31..0] - (RW) UWTBL DELSEL 2 +*/ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_6_UWTBL_DELSEL_2_ADDR \ + WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_6_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_6_UWTBL_DELSEL_2_MASK \ + 0xFFFFFFFF /* UWTBL_DELSEL_2[31..0] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_6_UWTBL_DELSEL_2_SHFT 0 + +/* +* ---CFG_SEC_MBIST_CTRL_0 (0x820C0000 + 0x25c0)--- +* SEC_MBIST_MODE[0] - (RW) Control register for mbist_mode of SEC +MBIST +* SEC_MBIST_HOLDB[1] - (RW) Control register for mbist_holdb of SEC +MBIST +* SEC_MBIST_DEBUG[2] - (RW) Control register for mbist_debug of SEC +MBIST +* SEC_MBIST_USE_DEFAULT_DELSEL[3] - (RW) Control register for default DELSEL +* value of SEC memory +* RESERVED4[7..4] - (RO) Reserved bits +* SEC_MBIST_DONE[8] - (RO) Working status of SEC SRAM MBIST circuit +* RESERVED9[15..9] - (RO) Reserved bits +* SEC_MBIST_FAIL[17..16] - (RO) MBIST check result of SEC SRAM +* RESERVED18[31..18] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_FAIL_ADDR \ + WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_FAIL_MASK \ + 0x00030000 /* SEC_MBIST_FAIL[17..16] */ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_FAIL_SHFT 16 +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_DONE_ADDR \ + WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_DONE_MASK \ + 0x00000100 /* SEC_MBIST_DONE[8] */ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_DONE_SHFT 8 +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_USE_DEFAULT_DELSEL_ADDR \ + WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_USE_DEFAULT_DELSEL_MASK \ + 0x00000008 /* SEC_MBIST_USE_DEFAULT_DELSEL[3] */ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_USE_DEFAULT_DELSEL_SHFT 3 +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_DEBUG_ADDR \ + WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_DEBUG_MASK \ + 0x00000004 /* SEC_MBIST_DEBUG[2] */ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_DEBUG_SHFT 2 +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_HOLDB_ADDR \ + WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_HOLDB_MASK \ + 0x00000002 /* SEC_MBIST_HOLDB[1] */ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_HOLDB_SHFT 1 +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_MODE_ADDR \ + WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_MODE_MASK \ + 0x00000001 /* SEC_MBIST_MODE[0] */ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_MODE_SHFT 0 + +/* +* ---CFG_SEC_MBIST_CTRL_1 (0x820C0000 + 0x25c4)--- +* SEC_MBIST_HDEN[0] - (RW) Control register for mbist SEC HDEN +* RESERVED1[15..1] - (RO) Reserved bits +* SEC_MBIST_AWT[16] - (RW) Control register for mbist SEC AWT +* RESERVED17[31..17] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_1_SEC_MBIST_AWT_ADDR \ + WF_PLE_TOP_CFG_SEC_MBIST_CTRL_1_ADDR +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_1_SEC_MBIST_AWT_MASK \ + 0x00010000 /* SEC_MBIST_AWT[16] */ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_1_SEC_MBIST_AWT_SHFT 16 +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_1_SEC_MBIST_HDEN_ADDR \ + WF_PLE_TOP_CFG_SEC_MBIST_CTRL_1_ADDR +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_1_SEC_MBIST_HDEN_MASK \ + 0x00000001 /* SEC_MBIST_HDEN[0] */ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_1_SEC_MBIST_HDEN_SHFT 0 + +/* +* ---CFG_SEC_MBIST_CTRL_2 (0x820C0000 + 0x25c8)--- +* SEC_BACKGROUND[15..0] - (RW) The MBIST background control register +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_2_SEC_BACKGROUND_ADDR \ + WF_PLE_TOP_CFG_SEC_MBIST_CTRL_2_ADDR +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_2_SEC_BACKGROUND_MASK \ + 0x0000FFFF /* SEC_BACKGROUND[15..0] */ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_2_SEC_BACKGROUND_SHFT 0 + +/* +* ---CFG_SEC_MBIST_CTRL_3 (0x820C0000 + 0x25cc)--- +* SEC_DELSEL_0[31..0] - (RW) SEC DELSEL 0 +*/ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_3_SEC_DELSEL_0_ADDR \ + WF_PLE_TOP_CFG_SEC_MBIST_CTRL_3_ADDR +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_3_SEC_DELSEL_0_MASK \ + 0xFFFFFFFF /* SEC_DELSEL_0[31..0] */ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_3_SEC_DELSEL_0_SHFT 0 + +/* +* ---CFG_PF_MBIST_CTRL_0 (0x820C0000 + 0x25e0)--- +* PF_MBIST_MODE[0] - (RW) Control register for mbist_mode of PF +MBIST +* PF_MBIST_HOLDB[1] - (RW) Control register for mbist_holdb of PF +MBIST +* PF_MBIST_DEBUG[2] - (RW) Control register for mbist_debug of PF +MBIST +* PF_MBIST_USE_DEFAULT_DELSEL[3] - (RW) Control register for default DELSEL +* value of PF memory +* PF_MBIST_SLEEP_TEST[4] - (RW) Control register for sleep_test of PF +MBIST +* PF_MBIST_SLEEP_INV[5] - (RW) Control register for sleep_inv of PF +MBIST +* PF_MBIST_SLEEP_W[6] - (RW) Control register for sleep_w of PF MBIST +* PF_MBIST_SLEEP_R[7] - (RW) Control register for sleep_r of PF MBIST +* PF_MBIST_DONE[8] - (RO) Working status of PF SRAM MBIST circuit +* RESERVED9[11..9] - (RO) Reserved bits +* PF_MBIST_FAIL[31..12] - (RO) MBIST check result of PF SRAM +*/ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_FAIL_ADDR \ + WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_FAIL_MASK \ + 0xFFFFF000 /* PF_MBIST_FAIL[31..12] */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_FAIL_SHFT 12 +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_DONE_ADDR \ + WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_DONE_MASK \ + 0x00000100 /* PF_MBIST_DONE[8] */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_DONE_SHFT 8 +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_SLEEP_R_ADDR \ + WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_SLEEP_R_MASK \ + 0x00000080 /* PF_MBIST_SLEEP_R[7] */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_SLEEP_R_SHFT 7 +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_SLEEP_W_ADDR \ + WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_SLEEP_W_MASK \ + 0x00000040 /* PF_MBIST_SLEEP_W[6] */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_SLEEP_W_SHFT 6 +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_SLEEP_INV_ADDR \ + WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_SLEEP_INV_MASK \ + 0x00000020 /* PF_MBIST_SLEEP_INV[5] */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_SLEEP_INV_SHFT 5 +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_SLEEP_TEST_ADDR \ + WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_SLEEP_TEST_MASK \ + 0x00000010 /* PF_MBIST_SLEEP_TEST[4] */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_SLEEP_TEST_SHFT 4 +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_USE_DEFAULT_DELSEL_ADDR \ + WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_USE_DEFAULT_DELSEL_MASK \ + 0x00000008 /* PF_MBIST_USE_DEFAULT_DELSEL[3] */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_USE_DEFAULT_DELSEL_SHFT 3 +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_DEBUG_ADDR \ + WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_DEBUG_MASK \ + 0x00000004 /* PF_MBIST_DEBUG[2] */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_DEBUG_SHFT 2 +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_HOLDB_ADDR \ + WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_HOLDB_MASK \ + 0x00000002 /* PF_MBIST_HOLDB[1] */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_HOLDB_SHFT 1 +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_MODE_ADDR \ + WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_MODE_MASK \ + 0x00000001 /* PF_MBIST_MODE[0] */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_MODE_SHFT 0 + +/* +* ---CFG_PF_MBIST_CTRL_1 (0x820C0000 + 0x25e4)--- +* PF_MBIST_HDEN[9..0] - (RW) Control register for mbist PF HDEN +* RESERVED10[11..10] - (RO) Reserved bits +* PF_MBIST_AWT[31..12] - (RW) Control register for mbist PF AWT +*/ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_1_PF_MBIST_AWT_ADDR \ + WF_PLE_TOP_CFG_PF_MBIST_CTRL_1_ADDR +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_1_PF_MBIST_AWT_MASK \ + 0xFFFFF000 /* PF_MBIST_AWT[31..12] */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_1_PF_MBIST_AWT_SHFT 12 +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_1_PF_MBIST_HDEN_ADDR \ + WF_PLE_TOP_CFG_PF_MBIST_CTRL_1_ADDR +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_1_PF_MBIST_HDEN_MASK \ + 0x000003FF /* PF_MBIST_HDEN[9..0] */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_1_PF_MBIST_HDEN_SHFT 0 + +/* +* ---CFG_PF_MBIST_CTRL_2 (0x820C0000 + 0x25e8)--- +* PF_BACKGROUND[15..0] - (RW) The MBIST background control register +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_2_PF_BACKGROUND_ADDR \ + WF_PLE_TOP_CFG_PF_MBIST_CTRL_2_ADDR +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_2_PF_BACKGROUND_MASK \ + 0x0000FFFF /* PF_BACKGROUND[15..0] */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_2_PF_BACKGROUND_SHFT 0 + +/* +* ---CFG_PF_MBIST_CTRL_3 (0x820C0000 + 0x25ec)--- +* PF_DELSEL_0[31..0] - (RW) PF DELSEL 0 +*/ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_3_PF_DELSEL_0_ADDR \ + WF_PLE_TOP_CFG_PF_MBIST_CTRL_3_ADDR +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_3_PF_DELSEL_0_MASK \ + 0xFFFFFFFF /* PF_DELSEL_0[31..0] */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_3_PF_DELSEL_0_SHFT 0 + +/* +* ---SYSRAM_MBIST_CTRL (0x820C0000 + 0x3004)--- +* MBIST_SW_RESET[0] - (RW) MBIST Software reset +* RESERVED1[7..1] - (RO) Reserved bits +* MBIST_BSEL[15..8] - (RW) Controls BSEL of SRAM MBIST circuit. +* MBIST_BACKGROUND[31..16] - (RW) The MBIST background control register +*/ +#define WF_PLE_TOP_SYSRAM_MBIST_CTRL_MBIST_BACKGROUND_ADDR \ + WF_PLE_TOP_SYSRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SYSRAM_MBIST_CTRL_MBIST_BACKGROUND_MASK \ + 0xFFFF0000 /* MBIST_BACKGROUND[31..16] */ +#define WF_PLE_TOP_SYSRAM_MBIST_CTRL_MBIST_BACKGROUND_SHFT 16 +#define WF_PLE_TOP_SYSRAM_MBIST_CTRL_MBIST_BSEL_ADDR \ + WF_PLE_TOP_SYSRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SYSRAM_MBIST_CTRL_MBIST_BSEL_MASK \ + 0x0000FF00 /* MBIST_BSEL[15..8] */ +#define WF_PLE_TOP_SYSRAM_MBIST_CTRL_MBIST_BSEL_SHFT 8 +#define WF_PLE_TOP_SYSRAM_MBIST_CTRL_MBIST_SW_RESET_ADDR \ + WF_PLE_TOP_SYSRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SYSRAM_MBIST_CTRL_MBIST_SW_RESET_MASK \ + 0x00000001 /* MBIST_SW_RESET[0] */ +#define WF_PLE_TOP_SYSRAM_MBIST_CTRL_MBIST_SW_RESET_SHFT 0 + +/* +* ---SYSRAM_MBIST_DEBUG (0x820C0000 + 0x3008)--- +* SYSRAM_MBIST_DEBUG[15..0] - (RW) Control register for mbist_debug of +* SYSRAM MBIST +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_SYSRAM_MBIST_DEBUG_SYSRAM_MBIST_DEBUG_ADDR \ + WF_PLE_TOP_SYSRAM_MBIST_DEBUG_ADDR +#define WF_PLE_TOP_SYSRAM_MBIST_DEBUG_SYSRAM_MBIST_DEBUG_MASK \ + 0x0000FFFF /* SYSRAM_MBIST_DEBUG[15..0] */ +#define WF_PLE_TOP_SYSRAM_MBIST_DEBUG_SYSRAM_MBIST_DEBUG_SHFT 0 + +/* +* ---SYSRAM_MBIST_MODE (0x820C0000 + 0x300C)--- +* SYSRAM_MBIST_MODE[15..0] - (RW) Control register for mbist_holdb of +* SYSRAM MBIST +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_SYSRAM_MBIST_MODE_SYSRAM_MBIST_MODE_ADDR \ + WF_PLE_TOP_SYSRAM_MBIST_MODE_ADDR +#define WF_PLE_TOP_SYSRAM_MBIST_MODE_SYSRAM_MBIST_MODE_MASK \ + 0x0000FFFF /* SYSRAM_MBIST_MODE[15..0] */ +#define WF_PLE_TOP_SYSRAM_MBIST_MODE_SYSRAM_MBIST_MODE_SHFT 0 + +/* +* ---SYSRAM_MBIST_HOLDB (0x820C0000 + 0x3010)--- +* SYSRAM_MBIST_HOLDB[15..0] - (RW) Control register for mbist_holdb of +* sysram MBIST +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_SYSRAM_MBIST_HOLDB_SYSRAM_MBIST_HOLDB_ADDR \ + WF_PLE_TOP_SYSRAM_MBIST_HOLDB_ADDR +#define WF_PLE_TOP_SYSRAM_MBIST_HOLDB_SYSRAM_MBIST_HOLDB_MASK \ + 0x0000FFFF /* SYSRAM_MBIST_HOLDB[15..0] */ +#define WF_PLE_TOP_SYSRAM_MBIST_HOLDB_SYSRAM_MBIST_HOLDB_SHFT 0 + +/* +* ---SYSRAM_MBIST_DONE (0x820C0000 + 0x3014)--- +* SYSRAM_MBIST_DONE[15..0] - (RO) Working status of SYSRAM MBIST 3 circuit +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_SYSRAM_MBIST_DONE_SYSRAM_MBIST_DONE_ADDR \ + WF_PLE_TOP_SYSRAM_MBIST_DONE_ADDR +#define WF_PLE_TOP_SYSRAM_MBIST_DONE_SYSRAM_MBIST_DONE_MASK \ + 0x0000FFFF /* SYSRAM_MBIST_DONE[15..0] */ +#define WF_PLE_TOP_SYSRAM_MBIST_DONE_SYSRAM_MBIST_DONE_SHFT 0 + +/* +* ---SYSRAM_MBIST_FAIL (0x820C0000 + 0x3018)--- +* SYSRAM_MBIST_FAIL[31..0] - (RO) MBIST check result of SYSRAM cell 3 +*/ +#define WF_PLE_TOP_SYSRAM_MBIST_FAIL_SYSRAM_MBIST_FAIL_ADDR \ + WF_PLE_TOP_SYSRAM_MBIST_FAIL_ADDR +#define WF_PLE_TOP_SYSRAM_MBIST_FAIL_SYSRAM_MBIST_FAIL_MASK \ + 0xFFFFFFFF /* SYSRAM_MBIST_FAIL[31..0] */ +#define WF_PLE_TOP_SYSRAM_MBIST_FAIL_SYSRAM_MBIST_FAIL_SHFT 0 + +/* +* ---SYSRAM_MBIST_SLEEP_TEST (0x820C0000 + 0x301C)--- +* SYSRAM_MBIST_SLEEP_TEST[15..0] - (RW) Control register for sleep_test of +* group 3 MBIST +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_SYSRAM_MBIST_SLEEP_TEST_SYSRAM_MBIST_SLEEP_TEST_ADDR \ + WF_PLE_TOP_SYSRAM_MBIST_SLEEP_TEST_ADDR +#define WF_PLE_TOP_SYSRAM_MBIST_SLEEP_TEST_SYSRAM_MBIST_SLEEP_TEST_MASK \ + 0x0000FFFF /* SYSRAM_MBIST_SLEEP_TEST[15..0] */ +#define WF_PLE_TOP_SYSRAM_MBIST_SLEEP_TEST_SYSRAM_MBIST_SLEEP_TEST_SHFT 0 + +/* +* ---SYSRAM_MBIST_SLEEP_INV (0x820C0000 + 0x3020)--- +* SYSRAM_MBIST_SLEEP_INV[15..0] - (RW) Control register for sleep_inv of group +* 3 MBIST +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_SYSRAM_MBIST_SLEEP_INV_SYSRAM_MBIST_SLEEP_INV_ADDR \ + WF_PLE_TOP_SYSRAM_MBIST_SLEEP_INV_ADDR +#define WF_PLE_TOP_SYSRAM_MBIST_SLEEP_INV_SYSRAM_MBIST_SLEEP_INV_MASK \ + 0x0000FFFF /* SYSRAM_MBIST_SLEEP_INV[15..0] */ +#define WF_PLE_TOP_SYSRAM_MBIST_SLEEP_INV_SYSRAM_MBIST_SLEEP_INV_SHFT 0 + +/* +* ---SYSRAM_MBIST_SLEEP_W (0x820C0000 + 0x3024)--- +* SYSRAM_MBIST_SLEEP_WRITE[15..0] - (RW) Control register for sleep_w of group +* 3 MBIST +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_SYSRAM_MBIST_SLEEP_W_SYSRAM_MBIST_SLEEP_WRITE_ADDR \ + WF_PLE_TOP_SYSRAM_MBIST_SLEEP_W_ADDR +#define WF_PLE_TOP_SYSRAM_MBIST_SLEEP_W_SYSRAM_MBIST_SLEEP_WRITE_MASK \ + 0x0000FFFF /* SYSRAM_MBIST_SLEEP_WRITE[15..0] */ +#define WF_PLE_TOP_SYSRAM_MBIST_SLEEP_W_SYSRAM_MBIST_SLEEP_WRITE_SHFT 0 + +/* +* ---SYSRAM_MBIST_SLEEP_R (0x820C0000 + 0x3028)--- +* SYSRAM_MBIST_SLEEP_READ[15..0] - (RW) Control register for sleep_r of group +* 3 MBIST +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_SYSRAM_MBIST_SLEEP_R_SYSRAM_MBIST_SLEEP_READ_ADDR \ + WF_PLE_TOP_SYSRAM_MBIST_SLEEP_R_ADDR +#define WF_PLE_TOP_SYSRAM_MBIST_SLEEP_R_SYSRAM_MBIST_SLEEP_READ_MASK \ + 0x0000FFFF /* SYSRAM_MBIST_SLEEP_READ[15..0] */ +#define WF_PLE_TOP_SYSRAM_MBIST_SLEEP_R_SYSRAM_MBIST_SLEEP_READ_SHFT 0 + +/* +* ---SYSRAM_AWT_HDEN (0x820C0000 + 0x302C)--- +* SYSRAM_MBIST_AWT[15..0] - (RW) Control register for mbist SYSRAM 3 AWT +* SYSRAM_MBIST_HDEN[31..16] - (RW) Control register for mbist SYSRAM 3 HDEN +*/ +#define WF_PLE_TOP_SYSRAM_AWT_HDEN_SYSRAM_MBIST_HDEN_ADDR \ + WF_PLE_TOP_SYSRAM_AWT_HDEN_ADDR +#define WF_PLE_TOP_SYSRAM_AWT_HDEN_SYSRAM_MBIST_HDEN_MASK \ + 0xFFFF0000 /* SYSRAM_MBIST_HDEN[31..16] */ +#define WF_PLE_TOP_SYSRAM_AWT_HDEN_SYSRAM_MBIST_HDEN_SHFT 16 +#define WF_PLE_TOP_SYSRAM_AWT_HDEN_SYSRAM_MBIST_AWT_ADDR \ + WF_PLE_TOP_SYSRAM_AWT_HDEN_ADDR +#define WF_PLE_TOP_SYSRAM_AWT_HDEN_SYSRAM_MBIST_AWT_MASK \ + 0x0000FFFF /* SYSRAM_MBIST_AWT[15..0] */ +#define WF_PLE_TOP_SYSRAM_AWT_HDEN_SYSRAM_MBIST_AWT_SHFT 0 + +/* +* ---SYSRAM_DBG_SEL (0x820C0000 + 0x3030)--- +* SYSRAM_DEBUG_SELECT_0[7..0] - (RW) Selects SYSRAM control debug 0 +* SYSRAM_DEBUG_SELECT_1[15..8] - (RW) Selects SYSRAM control debug 1 +* SYSRAM_DEBUG_SELECT_2[23..16] - (RW) Selects SYSRAM control debug 2 +* SYSRAM_DEBUG_SELECT_3[31..24] - (RW) Selects SYSRAM control debug 3 +*/ +#define WF_PLE_TOP_SYSRAM_DBG_SEL_SYSRAM_DEBUG_SELECT_3_ADDR \ + WF_PLE_TOP_SYSRAM_DBG_SEL_ADDR +#define WF_PLE_TOP_SYSRAM_DBG_SEL_SYSRAM_DEBUG_SELECT_3_MASK \ + 0xFF000000 /* SYSRAM_DEBUG_SELECT_3[31..24] */ +#define WF_PLE_TOP_SYSRAM_DBG_SEL_SYSRAM_DEBUG_SELECT_3_SHFT 24 +#define WF_PLE_TOP_SYSRAM_DBG_SEL_SYSRAM_DEBUG_SELECT_2_ADDR \ + WF_PLE_TOP_SYSRAM_DBG_SEL_ADDR +#define WF_PLE_TOP_SYSRAM_DBG_SEL_SYSRAM_DEBUG_SELECT_2_MASK \ + 0x00FF0000 /* SYSRAM_DEBUG_SELECT_2[23..16] */ +#define WF_PLE_TOP_SYSRAM_DBG_SEL_SYSRAM_DEBUG_SELECT_2_SHFT 16 +#define WF_PLE_TOP_SYSRAM_DBG_SEL_SYSRAM_DEBUG_SELECT_1_ADDR \ + WF_PLE_TOP_SYSRAM_DBG_SEL_ADDR +#define WF_PLE_TOP_SYSRAM_DBG_SEL_SYSRAM_DEBUG_SELECT_1_MASK \ + 0x0000FF00 /* SYSRAM_DEBUG_SELECT_1[15..8] */ +#define WF_PLE_TOP_SYSRAM_DBG_SEL_SYSRAM_DEBUG_SELECT_1_SHFT 8 +#define WF_PLE_TOP_SYSRAM_DBG_SEL_SYSRAM_DEBUG_SELECT_0_ADDR \ + WF_PLE_TOP_SYSRAM_DBG_SEL_ADDR +#define WF_PLE_TOP_SYSRAM_DBG_SEL_SYSRAM_DEBUG_SELECT_0_MASK \ + 0x000000FF /* SYSRAM_DEBUG_SELECT_0[7..0] */ +#define WF_PLE_TOP_SYSRAM_DBG_SEL_SYSRAM_DEBUG_SELECT_0_SHFT 0 + +/* +* ---SYSRAM_DELSEL (0x820C0000 + 0x3070)--- +* TYPE0_SYSRAM_DELSEL[31..0] - (RW) Type0 SYSRAM DELSEL bits +*/ +#define WF_PLE_TOP_SYSRAM_DELSEL_TYPE0_SYSRAM_DELSEL_ADDR \ + WF_PLE_TOP_SYSRAM_DELSEL_ADDR +#define WF_PLE_TOP_SYSRAM_DELSEL_TYPE0_SYSRAM_DELSEL_MASK \ + 0xFFFFFFFF /* TYPE0_SYSRAM_DELSEL[31..0] */ +#define WF_PLE_TOP_SYSRAM_DELSEL_TYPE0_SYSRAM_DELSEL_SHFT 0 + +/* +* ---SYSRAM_DELSEL_1 (0x820C0000 + 0x3074)--- +* TYPE1_SYSRAM_DELSEL[31..0] - (RW) Type1 SYSRAM DELSEL bits +*/ +#define WF_PLE_TOP_SYSRAM_DELSEL_1_TYPE1_SYSRAM_DELSEL_ADDR \ + WF_PLE_TOP_SYSRAM_DELSEL_1_ADDR +#define WF_PLE_TOP_SYSRAM_DELSEL_1_TYPE1_SYSRAM_DELSEL_MASK \ + 0xFFFFFFFF /* TYPE1_SYSRAM_DELSEL[31..0] */ +#define WF_PLE_TOP_SYSRAM_DELSEL_1_TYPE1_SYSRAM_DELSEL_SHFT 0 + +/* +* ---SYSRAM_DELSEL_2 (0x820C0000 + 0x3078)--- +* TYPE2_SYSRAM_DELSEL[31..0] - (RW) Type2 SYSRAM DELSEL bits +*/ +#define WF_PLE_TOP_SYSRAM_DELSEL_2_TYPE2_SYSRAM_DELSEL_ADDR \ + WF_PLE_TOP_SYSRAM_DELSEL_2_ADDR +#define WF_PLE_TOP_SYSRAM_DELSEL_2_TYPE2_SYSRAM_DELSEL_MASK \ + 0xFFFFFFFF /* TYPE2_SYSRAM_DELSEL[31..0] */ +#define WF_PLE_TOP_SYSRAM_DELSEL_2_TYPE2_SYSRAM_DELSEL_SHFT 0 + +/* +* ---SYSRAM_DELSEL_3 (0x820C0000 + 0x307C)--- +* TYPE3_SYSRAM_DELSEL[31..0] - (RW) Type3 SYSRAM DELSEL bits +*/ +#define WF_PLE_TOP_SYSRAM_DELSEL_3_TYPE3_SYSRAM_DELSEL_ADDR \ + WF_PLE_TOP_SYSRAM_DELSEL_3_ADDR +#define WF_PLE_TOP_SYSRAM_DELSEL_3_TYPE3_SYSRAM_DELSEL_MASK \ + 0xFFFFFFFF /* TYPE3_SYSRAM_DELSEL[31..0] */ +#define WF_PLE_TOP_SYSRAM_DELSEL_3_TYPE3_SYSRAM_DELSEL_SHFT 0 + +/* +* ---SYSRAM_OUTRAN_ERR_FLAG (0x820C0000 + 0x3080)--- +* SYSRAM_OUTRAN_ERR_FLAG[31..0] - (RO) Type3 SYSRAM DELSEL bits +*/ +#define WF_PLE_TOP_SYSRAM_OUTRAN_ERR_FLAG_SYSRAM_OUTRAN_ERR_FLAG_ADDR \ + WF_PLE_TOP_SYSRAM_OUTRAN_ERR_FLAG_ADDR +#define WF_PLE_TOP_SYSRAM_OUTRAN_ERR_FLAG_SYSRAM_OUTRAN_ERR_FLAG_MASK \ + 0xFFFFFFFF /* SYSRAM_OUTRAN_ERR_FLAG[31..0] */ +#define WF_PLE_TOP_SYSRAM_OUTRAN_ERR_FLAG_SYSRAM_OUTRAN_ERR_FLAG_SHFT 0 + +#ifdef __cplusplus +} +#endif + +#endif /* __WF_PLE_TOP_REGS_H__ */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/mt7961/wf_pse_top.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/mt7961/wf_pse_top.h new file mode 100644 index 0000000000000000000000000000000000000000..5199f127f81a3f09d0811b7ec05cf00e8b818db8 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/mt7961/wf_pse_top.h @@ -0,0 +1,3661 @@ +/* [File] : wf_pse_top.h */ +/* [Revision time] : Fri May 31 13:36:45 2019 */ +/* [Description] : This file is auto generated by CODA */ +/* [Copyright] : Copyright (C) 2019 Mediatek Incorportion. All rights */ +/* reserved. */ + +#ifndef __WF_PSE_TOP_REGS_H__ +#define __WF_PSE_TOP_REGS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* ************************************************************************** */ +/* */ +/* WF_PSE_TOP CR Definitions */ +/* */ +/* ************************************************************************** */ + +#define WF_PSE_TOP_BASE 0x820C8000 + +#define WF_PSE_TOP_GC_ADDR \ + (WF_PSE_TOP_BASE + 0x00) /* 8000 */ +#define WF_PSE_TOP_PBUF_CTRL_ADDR \ + (WF_PSE_TOP_BASE + 0x04) /* 8004 */ +#define WF_PSE_TOP_INT_N9_EN_MASK_ADDR \ + (WF_PSE_TOP_BASE + 0x08) /* 8008 */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_ADDR \ + (WF_PSE_TOP_BASE + 0x24) /* 8024 */ +#define WF_PSE_TOP_INT_N9_ERR1_MASK_ADDR \ + (WF_PSE_TOP_BASE + 0x28) /* 8028 */ +#define WF_PSE_TOP_INT_N9_STS_ADDR \ + (WF_PSE_TOP_BASE + 0x30) /* 8030 */ +#define WF_PSE_TOP_INT_N9_ERR_STS_ADDR \ + (WF_PSE_TOP_BASE + 0x34) /* 8034 */ +#define WF_PSE_TOP_INT_N9_ERR1_STS_ADDR \ + (WF_PSE_TOP_BASE + 0x38) /* 8038 */ +#define WF_PSE_TOP_QUEUE_EMPTY_ADDR \ + (WF_PSE_TOP_BASE + 0xB0) /* 80B0 */ +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_ADDR \ + (WF_PSE_TOP_BASE + 0xB4) /* 80B4 */ +#define WF_PSE_TOP_PSE_LP_CTRL_ADDR \ + (WF_PSE_TOP_BASE + 0xB8) /* 80B8 */ +#define WF_PSE_TOP_TO_N9_INT_ADDR \ + (WF_PSE_TOP_BASE + 0xF0) /* 80F0 */ +#define WF_PSE_TOP_GROUP_REFILL_CTRL_ADDR \ + (WF_PSE_TOP_BASE + 0x108) /* 8108 */ +#define WF_PSE_TOP_FREEPG_START_END_ADDR \ + (WF_PSE_TOP_BASE + 0x10C) /* 810C */ +#define WF_PSE_TOP_PG_HIF0_GROUP_ADDR \ + (WF_PSE_TOP_BASE + 0x110) /* 8110 */ +#define WF_PSE_TOP_PG_HIF1_GROUP_ADDR \ + (WF_PSE_TOP_BASE + 0x114) /* 8114 */ +#define WF_PSE_TOP_PG_CPU_GROUP_ADDR \ + (WF_PSE_TOP_BASE + 0x118) /* 8118 */ +#define WF_PSE_TOP_PG_PLE_GROUP_ADDR \ + (WF_PSE_TOP_BASE + 0x11C) /* 811C */ +#define WF_PSE_TOP_PG_PLE1_GROUP_ADDR \ + (WF_PSE_TOP_BASE + 0x120) /* 8120 */ +#define WF_PSE_TOP_PG_LMAC0_GROUP_ADDR \ + (WF_PSE_TOP_BASE + 0x124) /* 8124 */ +#define WF_PSE_TOP_PG_LMAC1_GROUP_ADDR \ + (WF_PSE_TOP_BASE + 0x128) /* 8128 */ +#define WF_PSE_TOP_PG_LMAC2_GROUP_ADDR \ + (WF_PSE_TOP_BASE + 0x12C) /* 812C */ +#define WF_PSE_TOP_PG_LMAC3_GROUP_ADDR \ + (WF_PSE_TOP_BASE + 0x130) /* 8130 */ +#define WF_PSE_TOP_PG_MDP_GROUP_ADDR \ + (WF_PSE_TOP_BASE + 0x134) /* 8134 */ +#define WF_PSE_TOP_PG_MDP1_GROUP_ADDR \ + (WF_PSE_TOP_BASE + 0x138) /* 8138 */ +#define WF_PSE_TOP_PG_MDP2_GROUP_ADDR \ + (WF_PSE_TOP_BASE + 0x13C) /* 813C */ +#define WF_PSE_TOP_PG_HIF2_GROUP_ADDR \ + (WF_PSE_TOP_BASE + 0x140) /* 8140 */ +#define WF_PSE_TOP_HIF0_PG_INFO_ADDR \ + (WF_PSE_TOP_BASE + 0x150) /* 8150 */ +#define WF_PSE_TOP_HIF1_PG_INFO_ADDR \ + (WF_PSE_TOP_BASE + 0x154) /* 8154 */ +#define WF_PSE_TOP_CPU_PG_INFO_ADDR \ + (WF_PSE_TOP_BASE + 0x158) /* 8158 */ +#define WF_PSE_TOP_PLE_PG_INFO_ADDR \ + (WF_PSE_TOP_BASE + 0x15C) /* 815C */ +#define WF_PSE_TOP_PLE1_PG_INFO_ADDR \ + (WF_PSE_TOP_BASE + 0x160) /* 8160 */ +#define WF_PSE_TOP_LMAC0_PG_INFO_ADDR \ + (WF_PSE_TOP_BASE + 0x164) /* 8164 */ +#define WF_PSE_TOP_LMAC1_PG_INFO_ADDR \ + (WF_PSE_TOP_BASE + 0x168) /* 8168 */ +#define WF_PSE_TOP_LMAC2_PG_INFO_ADDR \ + (WF_PSE_TOP_BASE + 0x16C) /* 816C */ +#define WF_PSE_TOP_LMAC3_PG_INFO_ADDR \ + (WF_PSE_TOP_BASE + 0x170) /* 8170 */ +#define WF_PSE_TOP_MDP_PG_INFO_ADDR \ + (WF_PSE_TOP_BASE + 0x174) /* 8174 */ +#define WF_PSE_TOP_MDP1_PG_INFO_ADDR \ + (WF_PSE_TOP_BASE + 0x178) /* 8178 */ +#define WF_PSE_TOP_MDP2_PG_INFO_ADDR \ + (WF_PSE_TOP_BASE + 0x17C) /* 817C */ +#define WF_PSE_TOP_HIF2_PG_INFO_ADDR \ + (WF_PSE_TOP_BASE + 0x180) /* 8180 */ +#define WF_PSE_TOP_DTIM_CTRL_ADDR \ + (WF_PSE_TOP_BASE + 0x190) /* 8190 */ +#define WF_PSE_TOP_FREEPG_START_END_DTIM_ADDR \ + (WF_PSE_TOP_BASE + 0x194) /* 8194 */ +#define WF_PSE_TOP_PG_LMAC0_GROUP_DTIM_ADDR \ + (WF_PSE_TOP_BASE + 0x198) /* 8198 */ +#define WF_PSE_TOP_PG_LMAC1_GROUP_DTIM_ADDR \ + (WF_PSE_TOP_BASE + 0x19C) /* 819C */ +#define WF_PSE_TOP_PG_MDP_GROUP_DTIM_ADDR \ + (WF_PSE_TOP_BASE + 0x1A0) /* 81A0 */ +#define WF_PSE_TOP_FL_QUE_CTRL_0_ADDR \ + (WF_PSE_TOP_BASE + 0x1B0) /* 81B0 */ +#define WF_PSE_TOP_FL_QUE_CTRL_1_ADDR \ + (WF_PSE_TOP_BASE + 0x1B4) /* 81B4 */ +#define WF_PSE_TOP_FL_QUE_CTRL_2_ADDR \ + (WF_PSE_TOP_BASE + 0x1B8) /* 81B8 */ +#define WF_PSE_TOP_FL_QUE_CTRL_3_ADDR \ + (WF_PSE_TOP_BASE + 0x1BC) /* 81BC */ +#define WF_PSE_TOP_PL_QUE_CTRL_0_ADDR \ + (WF_PSE_TOP_BASE + 0x1C0) /* 81C0 */ +#define WF_PSE_TOP_PSE_CT_PRI_CTRL_ADDR \ + (WF_PSE_TOP_BASE + 0x1EC) /* 81EC */ +#define WF_PSE_TOP_PLE_ENQ_PKT_NUM_ADDR \ + (WF_PSE_TOP_BASE + 0x1F0) /* 81F0 */ +#define WF_PSE_TOP_CPU_ENQ_PKT_NUM_ADDR \ + (WF_PSE_TOP_BASE + 0x1F4) /* 81F4 */ +#define WF_PSE_TOP_LMAC_ENQ_PKT_NUM_ADDR \ + (WF_PSE_TOP_BASE + 0x1F8) /* 81F8 */ +#define WF_PSE_TOP_HIF_ENQ_PKT_NUM_ADDR \ + (WF_PSE_TOP_BASE + 0x1FC) /* 81FC */ +#define WF_PSE_TOP_MDP_ENQ_PKT_NUM_ADDR \ + (WF_PSE_TOP_BASE + 0x200) /* 8200 */ +#define WF_PSE_TOP_RL_BUF_CTRL_0_ADDR \ + (WF_PSE_TOP_BASE + 0x210) /* 8210 */ +#define WF_PSE_TOP_RL_BUF_CTRL_1_ADDR \ + (WF_PSE_TOP_BASE + 0x214) /* 8214 */ +#define WF_PSE_TOP_TIMEOUT_CTRL_ADDR \ + (WF_PSE_TOP_BASE + 0x244) /* 8244 */ +#define WF_PSE_TOP_FSM_IDLE_WD_CTRL_ADDR \ + (WF_PSE_TOP_BASE + 0x248) /* 8248 */ +#define WF_PSE_TOP_FSM_IDLE_WD_EN_ADDR \ + (WF_PSE_TOP_BASE + 0x24C) /* 824C */ +#define WF_PSE_TOP_PSE_WFDMA_BUF_CTRL_ADDR \ + (WF_PSE_TOP_BASE + 0x250) /* 8250 */ +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_ADDR \ + (WF_PSE_TOP_BASE + 0x254) /* 8254 */ +#define WF_PSE_TOP_PSE_MISC_FUNC_CTRL_ADDR \ + (WF_PSE_TOP_BASE + 0x258) /* 8258 */ +#define WF_PSE_TOP_PSE_INTER_ERR_FLAG_ADDR \ + (WF_PSE_TOP_BASE + 0x280) /* 8280 */ +#define WF_PSE_TOP_PSE_SER_CTRL_ADDR \ + (WF_PSE_TOP_BASE + 0x2A0) /* 82A0 */ +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_ADDR \ + (WF_PSE_TOP_BASE + 0x2B0) /* 82B0 */ +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_1_ADDR \ + (WF_PSE_TOP_BASE + 0x2B4) /* 82B4 */ +#define WF_PSE_TOP_PSE_MBIST_BSEL_ADDR \ + (WF_PSE_TOP_BASE + 0x2B8) /* 82B8 */ +#define WF_PSE_TOP_SRAM_MBIST_BACKGROUND_ADDR \ + (WF_PSE_TOP_BASE + 0x2C0) /* 82C0 */ +#define WF_PSE_TOP_SRAM_MBIST_DONE_ADDR \ + (WF_PSE_TOP_BASE + 0x2C4) /* 82C4 */ +#define WF_PSE_TOP_SRAM_MBIST_FAIL_ADDR \ + (WF_PSE_TOP_BASE + 0x2C8) /* 82C8 */ +#define WF_PSE_TOP_SRAM_MBIST_CTRL_ADDR \ + (WF_PSE_TOP_BASE + 0x2D0) /* 82D0 */ +#define WF_PSE_TOP_SRAM_MBIST_DELSEL_ADDR \ + (WF_PSE_TOP_BASE + 0x2D4) /* 82D4 */ +#define WF_PSE_TOP_SRAM_MBIST_DELSEL_1_ADDR \ + (WF_PSE_TOP_BASE + 0x2D8) /* 82D8 */ +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_ADDR \ + (WF_PSE_TOP_BASE + 0x2DC) /* 82DC */ +#define WF_PSE_TOP_C_GET_FID_0_ADDR \ + (WF_PSE_TOP_BASE + 0x310) /* 8310 */ +#define WF_PSE_TOP_C_GET_FID_1_ADDR \ + (WF_PSE_TOP_BASE + 0x314) /* 8314 */ +#define WF_PSE_TOP_C_EN_QUEUE_0_ADDR \ + (WF_PSE_TOP_BASE + 0x320) /* 8320 */ +#define WF_PSE_TOP_C_EN_QUEUE_1_ADDR \ + (WF_PSE_TOP_BASE + 0x324) /* 8324 */ +#define WF_PSE_TOP_C_EN_QUEUE_2_ADDR \ + (WF_PSE_TOP_BASE + 0x328) /* 8328 */ +#define WF_PSE_TOP_C_DE_QUEUE_0_ADDR \ + (WF_PSE_TOP_BASE + 0x330) /* 8330 */ +#define WF_PSE_TOP_C_DE_QUEUE_1_ADDR \ + (WF_PSE_TOP_BASE + 0x334) /* 8334 */ +#define WF_PSE_TOP_C_DE_QUEUE_2_ADDR \ + (WF_PSE_TOP_BASE + 0x338) /* 8338 */ +#define WF_PSE_TOP_C_DE_QUEUE_3_ADDR \ + (WF_PSE_TOP_BASE + 0x33C) /* 833C */ +#define WF_PSE_TOP_C_DE_QUEUE_4_ADDR \ + (WF_PSE_TOP_BASE + 0x340) /* 8340 */ +#define WF_PSE_TOP_ALLOCATE_0_ADDR \ + (WF_PSE_TOP_BASE + 0x350) /* 8350 */ +#define WF_PSE_TOP_ALLOCATE_1_ADDR \ + (WF_PSE_TOP_BASE + 0x354) /* 8354 */ +#define WF_PSE_TOP_FREEPG_CNT_ADDR \ + (WF_PSE_TOP_BASE + 0x380) /* 8380 */ +#define WF_PSE_TOP_FREEPG_HEAD_TAIL_ADDR \ + (WF_PSE_TOP_BASE + 0x384) /* 8384 */ +#define WF_PSE_TOP_PSE_SEEK_CR_00_ADDR \ + (WF_PSE_TOP_BASE + 0x3D0) /* 83D0 */ +#define WF_PSE_TOP_PSE_SEEK_CR_01_ADDR \ + (WF_PSE_TOP_BASE + 0x3D4) /* 83D4 */ +#define WF_PSE_TOP_PSE_SEEK_CR_02_ADDR \ + (WF_PSE_TOP_BASE + 0x3D8) /* 83D8 */ +#define WF_PSE_TOP_PSE_SEEK_CR_03_ADDR \ + (WF_PSE_TOP_BASE + 0x3DC) /* 83DC */ +#define WF_PSE_TOP_PSE_SEEK_CR_04_ADDR \ + (WF_PSE_TOP_BASE + 0x3E0) /* 83E0 */ +#define WF_PSE_TOP_PSE_SEEK_CR_05_ADDR \ + (WF_PSE_TOP_BASE + 0x3E4) /* 83E4 */ +#define WF_PSE_TOP_PSE_SEEK_CR_06_ADDR \ + (WF_PSE_TOP_BASE + 0x3E8) /* 83E8 */ +#define WF_PSE_TOP_PSE_SEEK_CR_07_ADDR \ + (WF_PSE_TOP_BASE + 0x3EC) /* 83EC */ +#define WF_PSE_TOP_PSE_SEEK_CR_08_ADDR \ + (WF_PSE_TOP_BASE + 0x3F0) /* 83F0 */ +#define WF_PSE_TOP_PSE_SEEK_CR_09_ADDR \ + (WF_PSE_TOP_BASE + 0x3F4) /* 83F4 */ + +/* +* ---GC (0x820C8000 + 0x00)--- +* ALL_RESET[0] - (RW) Resets PSE logic and register +* LOGIC_RESET[1] - (RW) Resets PSE logic circuit +* INIT_DONE[2] - (RO) PSE control SRAM initialization +indicator +* RESERVED3[15..3] - (RO) Reserved bits +* SRAM_MBIST_RESET[16] - (RW) Reset control of SRAM MBIST (low active) +* RESERVED17[17] - (RO) Reserved bits +* DIS_PSE_DYN_CKG[18] - (RW) Disable control of wf_pse_top dynamic +* clock gating function +* RESERVED19[31..19] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_GC_DIS_PSE_DYN_CKG_ADDR WF_PSE_TOP_GC_ADDR +#define WF_PSE_TOP_GC_DIS_PSE_DYN_CKG_MASK 0x00040000 /* DIS_PSE_DYN_CKG[18] */ +#define WF_PSE_TOP_GC_DIS_PSE_DYN_CKG_SHFT 18 +#define WF_PSE_TOP_GC_SRAM_MBIST_RESET_ADDR WF_PSE_TOP_GC_ADDR +#define WF_PSE_TOP_GC_SRAM_MBIST_RESET_MASK \ + 0x00010000 /* SRAM_MBIST_RESET[16] */ +#define WF_PSE_TOP_GC_SRAM_MBIST_RESET_SHFT 16 +#define WF_PSE_TOP_GC_INIT_DONE_ADDR WF_PSE_TOP_GC_ADDR +#define WF_PSE_TOP_GC_INIT_DONE_MASK 0x00000004 /* INIT_DONE[2] */ +#define WF_PSE_TOP_GC_INIT_DONE_SHFT 2 +#define WF_PSE_TOP_GC_LOGIC_RESET_ADDR WF_PSE_TOP_GC_ADDR +#define WF_PSE_TOP_GC_LOGIC_RESET_MASK 0x00000002 /* LOGIC_RESET[1] */ +#define WF_PSE_TOP_GC_LOGIC_RESET_SHFT 1 +#define WF_PSE_TOP_GC_ALL_RESET_ADDR WF_PSE_TOP_GC_ADDR +#define WF_PSE_TOP_GC_ALL_RESET_MASK 0x00000001 /* ALL_RESET[0] */ +#define WF_PSE_TOP_GC_ALL_RESET_SHFT 0 + +/* +* ---PBUF_CTRL (0x820C8000 + 0x04)--- +* TOTAL_PAGE_NUM[11..0] - (RW) Total page numbers +* Set the total page before release PSE logic +* reset, and must not be changed after release logic reset. +* RESERVED12[16..12] - (RO) Reserved bits +* PBUF_OFFSET[25..17] - (RW) Packet buffer offset. +* Set the buffer offset before release PSE +* logic reset, and must not be changed after release logic reset. +* RESERVED26[30..26] - (RO) Reserved bits +* PAGE_SIZE_CFG[31] - (RW) Configures page size +* Set up the page size before releasing PSE +* logic reset; it should not be changed after logic reset is released. +*/ +#define WF_PSE_TOP_PBUF_CTRL_PAGE_SIZE_CFG_ADDR WF_PSE_TOP_PBUF_CTRL_ADDR +#define WF_PSE_TOP_PBUF_CTRL_PAGE_SIZE_CFG_MASK \ + 0x80000000 /* PAGE_SIZE_CFG[31] */ +#define WF_PSE_TOP_PBUF_CTRL_PAGE_SIZE_CFG_SHFT 31 +#define WF_PSE_TOP_PBUF_CTRL_PBUF_OFFSET_ADDR WF_PSE_TOP_PBUF_CTRL_ADDR +#define WF_PSE_TOP_PBUF_CTRL_PBUF_OFFSET_MASK \ + 0x03FE0000 /* PBUF_OFFSET[25..17] */ +#define WF_PSE_TOP_PBUF_CTRL_PBUF_OFFSET_SHFT 17 +#define WF_PSE_TOP_PBUF_CTRL_TOTAL_PAGE_NUM_ADDR WF_PSE_TOP_PBUF_CTRL_ADDR +#define WF_PSE_TOP_PBUF_CTRL_TOTAL_PAGE_NUM_MASK \ +0x00000FFF /* TOTAL_PAGE_NUM[11..0] */ +#define WF_PSE_TOP_PBUF_CTRL_TOTAL_PAGE_NUM_SHFT 0 + +/* +* ---INT_N9_EN_MASK (0x820C8000 + 0x08)--- +* EN_CPU_Q0_NE[0] - (RW) CPU queue 0 not empty interrupt +* EN_CPU_Q1_NE[1] - (RW) CPU queue 1 not empty interrupt +* EN_CPU_Q2_NE[2] - (RW) CPU queue 2 not empty interrupt +* EN_CPU_Q3_NE[3] - (RW) CPU queue 3 not empty interrupt +* RESERVED4[11..4] - (RO) Reserved bits +* EN_LMAC_ENQ[12] - (RW) Enables LMAC enq interrupt +* EN_ERROR_INT[13] - (RW) Error condition interrupt status +* RESERVED14[15..14] - (RO) Reserved bits +* EN_TOGGLE_INT[16] - (RW) Data toggle of CR4 toggle register +(0xe0) +* EN_LMAC_EMPTY_FALL[17] - (RW) LMAC Buffer empty fall edge detect +* EN_LMAC_EMPTY_RAISE[18] - (RW) LMAC Buffer empty raise edge detect +* EN_HIF_Q0_NE[19] - (RW) HIF queue 0 not empty interrupt +* EN_HIF_Q1_NE[20] - (RW) HIF queue 1 not empty interrupt +* EN_HIF_Q2_NE[21] - (RW) HIF queue 2 not empty interrupt +* EN_HIF_Q3_NE[22] - (RW) HIF queue 3 not empty interrupt +* EN_HIF_Q4_NE[23] - (RW) HIF queue 4 not empty interrupt +* EN_HIF_Q5_NE[24] - (RW) HIF queue 5 not empty interrupt +* EN_HIF_Q6_NE[25] - (RW) HIF queue 6 not empty interrupt +* EN_HIF_Q7_NE[26] - (RW) HIF queue 7 not empty interrupt +* EN_HIF_Q8_NE[27] - (RW) HIF queue 8 not empty interrupt +* EN_HIF_Q9_NE[28] - (RW) HIF queue 9 not empty interrupt +* EN_HIF_Q10_NE[29] - (RW) HIF queue 10 not empty interrupt +* EN_HIF_Q11_NE[30] - (RW) HIF queue 11 not empty interrupt +* RESERVED31[31] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q11_NE_ADDR \ +WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q11_NE_MASK \ +0x40000000 /* EN_HIF_Q11_NE[30] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q11_NE_SHFT 30 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q10_NE_ADDR \ +WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q10_NE_MASK \ +0x20000000 /* EN_HIF_Q10_NE[29] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q10_NE_SHFT 29 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q9_NE_ADDR \ +WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q9_NE_MASK \ +0x10000000 /* EN_HIF_Q9_NE[28] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q9_NE_SHFT 28 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q8_NE_ADDR \ +WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q8_NE_MASK \ +0x08000000 /* EN_HIF_Q8_NE[27] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q8_NE_SHFT 27 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q7_NE_ADDR \ +WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q7_NE_MASK \ +0x04000000 /* EN_HIF_Q7_NE[26] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q7_NE_SHFT 26 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q6_NE_ADDR \ +WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q6_NE_MASK \ +0x02000000 /* EN_HIF_Q6_NE[25] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q6_NE_SHFT 25 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q5_NE_ADDR \ +WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q5_NE_MASK \ +0x01000000 /* EN_HIF_Q5_NE[24] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q5_NE_SHFT 24 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q4_NE_ADDR \ +WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q4_NE_MASK \ +0x00800000 /* EN_HIF_Q4_NE[23] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q4_NE_SHFT 23 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q3_NE_ADDR \ +WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q3_NE_MASK \ +0x00400000 /* EN_HIF_Q3_NE[22] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q3_NE_SHFT 22 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q2_NE_ADDR \ +WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q2_NE_MASK \ +0x00200000 /* EN_HIF_Q2_NE[21] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q2_NE_SHFT 21 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q1_NE_ADDR \ +WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q1_NE_MASK \ +0x00100000 /* EN_HIF_Q1_NE[20] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q1_NE_SHFT 20 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q0_NE_ADDR \ +WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q0_NE_MASK \ +0x00080000 /* EN_HIF_Q0_NE[19] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q0_NE_SHFT 19 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_LMAC_EMPTY_RAISE_ADDR \ +WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_LMAC_EMPTY_RAISE_MASK \ +0x00040000 /* EN_LMAC_EMPTY_RAISE[18] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_LMAC_EMPTY_RAISE_SHFT 18 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_LMAC_EMPTY_FALL_ADDR \ +WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_LMAC_EMPTY_FALL_MASK \ +0x00020000 /* EN_LMAC_EMPTY_FALL[17] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_LMAC_EMPTY_FALL_SHFT 17 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_TOGGLE_INT_ADDR \ +WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_TOGGLE_INT_MASK \ +0x00010000 /* EN_TOGGLE_INT[16] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_TOGGLE_INT_SHFT 16 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_ERROR_INT_ADDR \ +WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_ERROR_INT_MASK \ +0x00002000 /* EN_ERROR_INT[13] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_ERROR_INT_SHFT 13 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_LMAC_ENQ_ADDR \ +WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_LMAC_ENQ_MASK \ + 0x00001000 /* EN_LMAC_ENQ[12] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_LMAC_ENQ_SHFT 12 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_CPU_Q3_NE_ADDR \ +WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_CPU_Q3_NE_MASK \ +0x00000008 /* EN_CPU_Q3_NE[3] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_CPU_Q3_NE_SHFT 3 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_CPU_Q2_NE_ADDR \ +WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_CPU_Q2_NE_MASK \ +0x00000004 /* EN_CPU_Q2_NE[2] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_CPU_Q2_NE_SHFT 2 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_CPU_Q1_NE_ADDR \ +WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_CPU_Q1_NE_MASK \ +0x00000002 /* EN_CPU_Q1_NE[1] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_CPU_Q1_NE_SHFT 1 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_CPU_Q0_NE_ADDR \ +WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_CPU_Q0_NE_MASK \ +0x00000001 /* EN_CPU_Q0_NE[0] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_CPU_Q0_NE_SHFT 0 + +/* +* ---INT_N9_ERR_MASK (0x820C8000 + 0x24)--- +* EN_Q_CMD_ERR_P0[0] - (RW) Enable Queue command error interrupt +* status of port 0. Avoid unclear error flag, please clear flag when logic +reset. +* EN_Q_CMD_ERR_P1[1] - (RW) Enable Queue command error interrupt +* status of port 1. Avoid unclear error flag, please clear flag when logic +reset. +* EN_Q_CMD_ERR_P2[2] - (RW) Enable Queue command error interrupt +* status of port 2. Avoid unclear error flag, please clear flag when logic +reset. +* EN_Q_CMD_ERR_P3[3] - (RW) Enable Queue command error interrupt +* status of port 3. Avoid unclear error flag, please clear flag when logic +reset. +* EN_Q_CMD_ERR_P4[4] - (RW) Enable Queue command error interrupt +* status of port 4. Avoid unclear error flag, please clear flag when logic +reset. +* EN_Q_CMD_ERR_P5[5] - (RW) Enable Queue command error interrupt +* status of port 5. Avoid unclear error flag, please clear flag when logic +reset. +* EN_Q_CMD_ERR_P6[6] - (RW) Enable Queue command error interrupt +* status of port 6. Avoid unclear error flag, please clear flag when logic +reset. +* RESERVED7[7] - (RO) Reserved bits +* EN_PAGE_UDF_P0[8] - (RW) Enable Page underflow interrupt status +* of port 0. Avoid unclear error flag, please clear flag when logic reset. +* EN_PAGE_UDF_P1[9] - (RW) Enable Page underflow interrupt status +* of port 1. Avoid unclear error flag, please clear flag when logic reset. +* EN_PAGE_UDF_P2[10] - (RW) Enable Page underflow interrupt status +* of port 2. Avoid unclear error flag, please clear flag when logic reset. +* EN_PAGE_UDF_P3[11] - (RW) Enable Page underflow interrupt status +* of port 3. Avoid unclear error flag, please clear flag when logic reset. +* EN_PAGE_UDF_P4[12] - (RW) Enable Page underflow interrupt status +* of port 4. Avoid unclear error flag, please clear flag when logic reset. +* EN_PAGE_UDF_P5[13] - (RW) Enable Page underflow interrupt status +* of port 5. Avoid unclear error flag, please clear flag when logic reset. +* EN_PAGE_UDF_P6[14] - (RW) Enable Page underflow interrupt status +* of port 6. Avoid unclear error flag, please clear flag when logic reset. +* RESERVED15[15] - (RO) Reserved bits +* EN_QUEUE_OPER_ERR_P0[16] - (RW) Enable Queue operation error of port 0. +* Avoid unclear error flag, please clear flag when logic reset. +* EN_QUEUE_OPER_ERR_P1[17] - (RW) Enable Queue operation error of port 1. +* Avoid unclear error flag, please clear flag when logic reset. +* EN_QUEUE_OPER_ERR_P2[18] - (RW) Enable Queue operation error of port 2. +* Avoid unclear error flag, please clear flag when logic reset. +* EN_QUEUE_OPER_ERR_P3[19] - (RW) Enable Queue operation error of port 3. +* Avoid unclear error flag, please clear flag when logic reset. +* EN_QUEUE_OPER_ERR_P4[20] - (RW) Enable Queue operation error of port 4. +* Avoid unclear error flag, please clear flag when logic reset. +* EN_QUEUE_OPER_ERR_P5[21] - (RW) Enable Queue operation error of port 5. +* Avoid unclear error flag, please clear flag when logic reset. +* EN_QUEUE_OPER_ERR_P6[22] - (RW) Enable Queue operation error of port 6. +* Avoid unclear error flag, please clear flag when logic reset. +* RESERVED23[23] - (RO) Reserved bits +* EN_DATA_OPER_ERR_P0[24] - (RW) Enable Data operation error of port 0. +* Avoid unclear error flag, please clear flag when logic reset. +* EN_DATA_OPER_ERR_P1[25] - (RW) Enable Data operation error of port 1. +* Avoid unclear error flag, please clear flag when logic reset. +* EN_DATA_OPER_ERR_P2[26] - (RW) Enable Data operation error of port 2. +* Avoid unclear error flag, please clear flag when logic reset. +* EN_DATA_OPER_ERR_P3[27] - (RW) Enable Data operation error of port 3. +* Avoid unclear error flag, please clear flag when logic reset. +* EN_DATA_OPER_ERR_P4[28] - (RW) Enable Data operation error of port 4. +* Avoid unclear error flag, please clear flag when logic reset. +* EN_DATA_OPER_ERR_P5[29] - (RW) Enable Data operation error of port 5. +* Avoid unclear error flag, please clear flag when logic reset. +* EN_DATA_OPER_EN_ERR_P6[30] - (RW) Enable Data operation error of port 6. +* Avoid unclear error flag, please clear flag when logic reset. +* RESERVED31[31] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_EN_ERR_P6_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_EN_ERR_P6_MASK \ +0x40000000 /* EN_DATA_OPER_EN_ERR_P6[30] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_EN_ERR_P6_SHFT 30 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P5_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P5_MASK \ +0x20000000 /* EN_DATA_OPER_ERR_P5[29] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P5_SHFT 29 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P4_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P4_MASK \ +0x10000000 /* EN_DATA_OPER_ERR_P4[28] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P4_SHFT 28 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P3_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P3_MASK \ +0x08000000 /* EN_DATA_OPER_ERR_P3[27] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P3_SHFT 27 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P2_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P2_MASK \ +0x04000000 /* EN_DATA_OPER_ERR_P2[26] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P2_SHFT 26 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P1_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P1_MASK \ +0x02000000 /* EN_DATA_OPER_ERR_P1[25] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P1_SHFT 25 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P0_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P0_MASK \ +0x01000000 /* EN_DATA_OPER_ERR_P0[24] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P0_SHFT 24 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P6_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P6_MASK \ +0x00400000 /* EN_QUEUE_OPER_ERR_P6[22] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P6_SHFT 22 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P5_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P5_MASK \ +0x00200000 /* EN_QUEUE_OPER_ERR_P5[21] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P5_SHFT 21 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P4_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P4_MASK \ +0x00100000 /* EN_QUEUE_OPER_ERR_P4[20] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P4_SHFT 20 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P3_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P3_MASK \ +0x00080000 /* EN_QUEUE_OPER_ERR_P3[19] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P3_SHFT 19 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P2_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P2_MASK \ +0x00040000 /* EN_QUEUE_OPER_ERR_P2[18] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P2_SHFT 18 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P1_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P1_MASK \ +0x00020000 /* EN_QUEUE_OPER_ERR_P1[17] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P1_SHFT 17 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P0_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P0_MASK \ +0x00010000 /* EN_QUEUE_OPER_ERR_P0[16] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P0_SHFT 16 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P6_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P6_MASK \ +0x00004000 /* EN_PAGE_UDF_P6[14] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P6_SHFT 14 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P5_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P5_MASK \ +0x00002000 /* EN_PAGE_UDF_P5[13] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P5_SHFT 13 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P4_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P4_MASK \ +0x00001000 /* EN_PAGE_UDF_P4[12] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P4_SHFT 12 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P3_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P3_MASK \ +0x00000800 /* EN_PAGE_UDF_P3[11] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P3_SHFT 11 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P2_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P2_MASK \ +0x00000400 /* EN_PAGE_UDF_P2[10] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P2_SHFT 10 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P1_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P1_MASK \ +0x00000200 /* EN_PAGE_UDF_P1[9] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P1_SHFT 9 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P0_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P0_MASK \ +0x00000100 /* EN_PAGE_UDF_P0[8] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P0_SHFT 8 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P6_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P6_MASK \ +0x00000040 /* EN_Q_CMD_ERR_P6[6] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P6_SHFT 6 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P5_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P5_MASK \ +0x00000020 /* EN_Q_CMD_ERR_P5[5] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P5_SHFT 5 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P4_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P4_MASK \ +0x00000010 /* EN_Q_CMD_ERR_P4[4] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P4_SHFT 4 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P3_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P3_MASK \ +0x00000008 /* EN_Q_CMD_ERR_P3[3] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P3_SHFT 3 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P2_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P2_MASK \ +0x00000004 /* EN_Q_CMD_ERR_P2[2] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P2_SHFT 2 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P1_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P1_MASK \ +0x00000002 /* EN_Q_CMD_ERR_P1[1] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P1_SHFT 1 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P0_ADDR \ +WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P0_MASK \ +0x00000001 /* EN_Q_CMD_ERR_P0[0] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P0_SHFT 0 + +/* +* ---INT_N9_ERR1_MASK (0x820C8000 + 0x28)--- +* EN_WDT_ERR_P0[0] - (RW) Enable Port state watch dog timeout +* error interrupt status of port 0. Avoid unclear error flag, please clear flag +* when logic reset. +* EN_WDT_ERR_P1[1] - (RW) Enable Port state watch dog timeout +* error interrupt status of port 1. Avoid unclear error flag, please clear flag +* when logic reset. +* EN_WDT_ERR_P2[2] - (RW) Enable Port state watch dog timeout +* error interrupt status of port 2. Avoid unclear error flag, please clear flag +* when logic reset. +* EN_WDT_ERR_P3[3] - (RW) Enable Port state watch dog timeout +* error interrupt status of port 3. Avoid unclear error flag, please clear flag +* when logic reset. +* EN_WDT_ERR_P4[4] - (RW) Enable Port state watch dog timeout +* error interrupt status of port 4. Avoid unclear error flag, please clear flag +* when logic reset. +* EN_WDT_ERR_P5[5] - (RW) Enable Port state watch dog timeout +* error interrupt status of port 5. Avoid unclear error flag, please clear flag +* when logic reset. +* EN_WDT_ERR_P6[6] - (RW) Enable Port state watch dog timeout +* error interrupt status of port 6. Avoid unclear error flag, please clear flag +* when logic reset. +* RESERVED7[7] - (RO) Reserved bits +* EN_FL_HANG_ERR[8] - (RW) Enable Frame link FSM hang error +* interrupt. Avoid unclear error flag, please clear flag when logic reset. +* PL_HANGEN__ERR[9] - (RW) Enable Page link FSM hang error +* interrupt. Avoid unclear error flag, please clear flag when logic reset. +* EN_DOUBLE_RLS_ERR[10] - (RW) Enable Double release error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* EN_FREE_HEAD_TAIL_ERR[11] - (RW) Enable Free head/tail error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* EN_FL_QSTRTUT_ERR[12] - (RW) Enable Frame Link queue NULL error +* interrupt. Avoid unclear error flag, please clear flag when logic reset. +* RESERVED13[31..13] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_FL_QSTRTUT_ERR_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_FL_QSTRTUT_ERR_MASK \ +0x00001000 /* EN_FL_QSTRTUT_ERR[12] */ +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_FL_QSTRTUT_ERR_SHFT 12 +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_FREE_HEAD_TAIL_ERR_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_FREE_HEAD_TAIL_ERR_MASK \ +0x00000800 /* EN_FREE_HEAD_TAIL_ERR[11] */ +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_FREE_HEAD_TAIL_ERR_SHFT 11 +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_DOUBLE_RLS_ERR_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_DOUBLE_RLS_ERR_MASK \ +0x00000400 /* EN_DOUBLE_RLS_ERR[10] */ +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_DOUBLE_RLS_ERR_SHFT 10 +#define WF_PSE_TOP_INT_N9_ERR1_MASK_PL_HANGEN__ERR_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_MASK_PL_HANGEN__ERR_MASK \ +0x00000200 /* PL_HANGEN__ERR[9] */ +#define WF_PSE_TOP_INT_N9_ERR1_MASK_PL_HANGEN__ERR_SHFT 9 +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_FL_HANG_ERR_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_FL_HANG_ERR_MASK \ +0x00000100 /* EN_FL_HANG_ERR[8] */ +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_FL_HANG_ERR_SHFT 8 +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P6_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P6_MASK \ +0x00000040 /* EN_WDT_ERR_P6[6] */ +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P6_SHFT 6 +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P5_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P5_MASK \ +0x00000020 /* EN_WDT_ERR_P5[5] */ +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P5_SHFT 5 +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P4_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P4_MASK \ +0x00000010 /* EN_WDT_ERR_P4[4] */ +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P4_SHFT 4 +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P3_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P3_MASK \ +0x00000008 /* EN_WDT_ERR_P3[3] */ +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P3_SHFT 3 +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P2_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P2_MASK \ +0x00000004 /* EN_WDT_ERR_P2[2] */ +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P2_SHFT 2 +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P1_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P1_MASK \ +0x00000002 /* EN_WDT_ERR_P1[1] */ +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P1_SHFT 1 +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P0_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P0_MASK \ +0x00000001 /* EN_WDT_ERR_P0[0] */ +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P0_SHFT 0 + +/* +* ---INT_N9_STS (0x820C8000 + 0x30)--- +* CPU_Q0_NE[0] - (W1C) CPU queue 0 not empty interrupt status +* CPU_Q1_NE[1] - (W1C) CPU queue 1 not empty interrupt status +* CPU_Q2_NE[2] - (W1C) CPU queue 2 not empty interrupt status +* CPU_Q3_NE[3] - (W1C) CPU queue 3 not empty interrupt status +* RESERVED4[11..4] - (RO) Reserved bits +* LMAC_ENQ[12] - (W1C) LMAC enq interrupt status +* ERROR_INT[13] - (RO) Error condition interrupt status +* ERROR_1_INT[14] - (RO) Error condition interrupt status +* RESERVED15[15] - (RO) Reserved bits +* DATA_TOGGLE[16] - (W1C) Data toggle of CR4 toggle register +(0xe0) +* LMAC_EMPTY_FALL[17] - (W1C) LMAC Buffer empty fall edge detect +* LMAC_EMPTY_RAISE[18] - (W1C) LMAC Buffer empty raise edge detect +* HIF_Q0_NE[19] - (W1C) HIF queue 0 not empty interrupt status +* HIF_Q1_NE[20] - (W1C) HIF queue 1 not empty interrupt status +* HIF_Q2_NE[21] - (W1C) HIF queue 2 not empty interrupt status +* HIF_Q3_NE[22] - (W1C) HIF queue 3 not empty interrupt status +* HIF_Q4_NE[23] - (W1C) HIF queue 4 not empty interrupt status +* HIF_Q5_NE[24] - (W1C) HIF queue 5 not empty interrupt status +* HIF_Q6_NE[25] - (W1C) HIF queue 6 not empty interrupt status +* HIF_Q7_NE[26] - (W1C) HIF queue 7 not empty interrupt status +* HIF_Q8_NE[27] - (W1C) HIF queue 8 not empty interrupt status +* HIF_Q9_NE[28] - (W1C) HIF queue 9 not empty interrupt status +* HIF_Q10_NE[29] - (W1C) HIF queue 10 not empty interrupt status +* HIF_Q11_NE[30] - (W1C) HIF queue 11 not empty interrupt status +* RESERVED31[31] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_INT_N9_STS_HIF_Q11_NE_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_HIF_Q11_NE_MASK 0x40000000 /* HIF_Q11_NE[30] */ +#define WF_PSE_TOP_INT_N9_STS_HIF_Q11_NE_SHFT 30 +#define WF_PSE_TOP_INT_N9_STS_HIF_Q10_NE_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_HIF_Q10_NE_MASK 0x20000000 /* HIF_Q10_NE[29] */ +#define WF_PSE_TOP_INT_N9_STS_HIF_Q10_NE_SHFT 29 +#define WF_PSE_TOP_INT_N9_STS_HIF_Q9_NE_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_HIF_Q9_NE_MASK 0x10000000 /* HIF_Q9_NE[28] */ +#define WF_PSE_TOP_INT_N9_STS_HIF_Q9_NE_SHFT 28 +#define WF_PSE_TOP_INT_N9_STS_HIF_Q8_NE_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_HIF_Q8_NE_MASK 0x08000000 /* HIF_Q8_NE[27] */ +#define WF_PSE_TOP_INT_N9_STS_HIF_Q8_NE_SHFT 27 +#define WF_PSE_TOP_INT_N9_STS_HIF_Q7_NE_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_HIF_Q7_NE_MASK 0x04000000 /* HIF_Q7_NE[26] */ +#define WF_PSE_TOP_INT_N9_STS_HIF_Q7_NE_SHFT 26 +#define WF_PSE_TOP_INT_N9_STS_HIF_Q6_NE_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_HIF_Q6_NE_MASK 0x02000000 /* HIF_Q6_NE[25] */ +#define WF_PSE_TOP_INT_N9_STS_HIF_Q6_NE_SHFT 25 +#define WF_PSE_TOP_INT_N9_STS_HIF_Q5_NE_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_HIF_Q5_NE_MASK 0x01000000 /* HIF_Q5_NE[24] */ +#define WF_PSE_TOP_INT_N9_STS_HIF_Q5_NE_SHFT 24 +#define WF_PSE_TOP_INT_N9_STS_HIF_Q4_NE_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_HIF_Q4_NE_MASK 0x00800000 /* HIF_Q4_NE[23] */ +#define WF_PSE_TOP_INT_N9_STS_HIF_Q4_NE_SHFT 23 +#define WF_PSE_TOP_INT_N9_STS_HIF_Q3_NE_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_HIF_Q3_NE_MASK 0x00400000 /* HIF_Q3_NE[22] */ +#define WF_PSE_TOP_INT_N9_STS_HIF_Q3_NE_SHFT 22 +#define WF_PSE_TOP_INT_N9_STS_HIF_Q2_NE_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_HIF_Q2_NE_MASK 0x00200000 /* HIF_Q2_NE[21] */ +#define WF_PSE_TOP_INT_N9_STS_HIF_Q2_NE_SHFT 21 +#define WF_PSE_TOP_INT_N9_STS_HIF_Q1_NE_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_HIF_Q1_NE_MASK 0x00100000 /* HIF_Q1_NE[20] */ +#define WF_PSE_TOP_INT_N9_STS_HIF_Q1_NE_SHFT 20 +#define WF_PSE_TOP_INT_N9_STS_HIF_Q0_NE_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_HIF_Q0_NE_MASK 0x00080000 /* HIF_Q0_NE[19] */ +#define WF_PSE_TOP_INT_N9_STS_HIF_Q0_NE_SHFT 19 +#define WF_PSE_TOP_INT_N9_STS_LMAC_EMPTY_RAISE_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_LMAC_EMPTY_RAISE_MASK \ +0x00040000 /* LMAC_EMPTY_RAISE[18] */ +#define WF_PSE_TOP_INT_N9_STS_LMAC_EMPTY_RAISE_SHFT 18 +#define WF_PSE_TOP_INT_N9_STS_LMAC_EMPTY_FALL_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_LMAC_EMPTY_FALL_MASK \ +0x00020000 /* LMAC_EMPTY_FALL[17] */ +#define WF_PSE_TOP_INT_N9_STS_LMAC_EMPTY_FALL_SHFT 17 +#define WF_PSE_TOP_INT_N9_STS_DATA_TOGGLE_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_DATA_TOGGLE_MASK 0x00010000 /* DATA_TOGGLE[16] */ +#define WF_PSE_TOP_INT_N9_STS_DATA_TOGGLE_SHFT 16 +#define WF_PSE_TOP_INT_N9_STS_ERROR_1_INT_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_ERROR_1_INT_MASK 0x00004000 /* ERROR_1_INT[14] */ +#define WF_PSE_TOP_INT_N9_STS_ERROR_1_INT_SHFT 14 +#define WF_PSE_TOP_INT_N9_STS_ERROR_INT_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_ERROR_INT_MASK 0x00002000 /* ERROR_INT[13] */ +#define WF_PSE_TOP_INT_N9_STS_ERROR_INT_SHFT 13 +#define WF_PSE_TOP_INT_N9_STS_LMAC_ENQ_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_LMAC_ENQ_MASK 0x00001000 /* LMAC_ENQ[12] */ +#define WF_PSE_TOP_INT_N9_STS_LMAC_ENQ_SHFT 12 +#define WF_PSE_TOP_INT_N9_STS_CPU_Q3_NE_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_CPU_Q3_NE_MASK 0x00000008 /* CPU_Q3_NE[3] */ +#define WF_PSE_TOP_INT_N9_STS_CPU_Q3_NE_SHFT 3 +#define WF_PSE_TOP_INT_N9_STS_CPU_Q2_NE_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_CPU_Q2_NE_MASK 0x00000004 /* CPU_Q2_NE[2] */ +#define WF_PSE_TOP_INT_N9_STS_CPU_Q2_NE_SHFT 2 +#define WF_PSE_TOP_INT_N9_STS_CPU_Q1_NE_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_CPU_Q1_NE_MASK 0x00000002 /* CPU_Q1_NE[1] */ +#define WF_PSE_TOP_INT_N9_STS_CPU_Q1_NE_SHFT 1 +#define WF_PSE_TOP_INT_N9_STS_CPU_Q0_NE_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_CPU_Q0_NE_MASK 0x00000001 /* CPU_Q0_NE[0] */ +#define WF_PSE_TOP_INT_N9_STS_CPU_Q0_NE_SHFT 0 + +/* +* ---INT_N9_ERR_STS (0x820C8000 + 0x34)--- +* Q_CMD_ERR_P0[0] - (W1C) Queue command error interrupt status of +* port 0. Avoid unclear error flag, please clear flag when logic reset. +* Q_CMD_ERR_P1[1] - (W1C) Queue command error interrupt status of +* port 1. Avoid unclear error flag, please clear flag when logic reset. +* Q_CMD_ERR_P2[2] - (W1C) Queue command error interrupt status of +* port 2. Avoid unclear error flag, please clear flag when logic reset. +* Q_CMD_ERR_P3[3] - (W1C) Queue command error interrupt status of +* port 3. Avoid unclear error flag, please clear flag when logic reset. +* Q_CMD_ERR_P4[4] - (W1C) Queue command error interrupt status of +* port 4. Avoid unclear error flag, please clear flag when logic reset. +* Q_CMD_ERR_P5[5] - (W1C) Queue command error interrupt status of +* port 5. Avoid unclear error flag, please clear flag when logic reset. +* Q_CMD_ERR_P6[6] - (W1C) Queue command error interrupt status of +* port 6. Avoid unclear error flag, please clear flag when logic reset. +* RESERVED7[7] - (RO) Reserved bits +* PAGE_UDF_P0[8] - (W1C) Page underflow interrupt status of port +* 0. Avoid unclear error flag, please clear flag when logic reset. +* PAGE_UDF_P1[9] - (W1C) Page underflow interrupt status of port +* 1. Avoid unclear error flag, please clear flag when logic reset. +* PAGE_UDF_P2[10] - (W1C) Page underflow interrupt status of port +* 2. Avoid unclear error flag, please clear flag when logic reset. +* PAGE_UDF_P3[11] - (W1C) Page underflow interrupt status of port +* 3. Avoid unclear error flag, please clear flag when logic reset. +* PAGE_UDF_P4[12] - (W1C) Page underflow interrupt status of port +* 4. Avoid unclear error flag, please clear flag when logic reset. +* PAGE_UDF_P5[13] - (W1C) Page underflow interrupt status of port +* 5. Avoid unclear error flag, please clear flag when logic reset. +* PAGE_UDF_P6[14] - (W1C) Page underflow interrupt status of port +* 6. Avoid unclear error flag, please clear flag when logic reset. +* RESERVED15[15] - (RO) Reserved bits +* QUEUE_OPER_ERR_P0[16] - (W1C) Queue operation error of port 0. Avoid +* unclear error flag, please clear flag when logic reset. +* QUEUE_OPER_ERR_P1[17] - (W1C) Queue operation error of port 1. Avoid +* unclear error flag, please clear flag when logic reset. +* QUEUE_OPER_ERR_P2[18] - (W1C) Queue operation error of port 2. Avoid +* unclear error flag, please clear flag when logic reset. +* QUEUE_OPER_ERR_P3[19] - (W1C) Queue operation error of port 3. Avoid +* unclear error flag, please clear flag when logic reset. +* QUEUE_OPER_ERR_P4[20] - (W1C) Queue operation error of port 4. Avoid +* unclear error flag, please clear flag when logic reset. +* QUEUE_OPER_ERR_P5[21] - (W1C) Queue operation error of port 5. Avoid +* unclear error flag, please clear flag when logic reset. +* QUEUE_OPER_ERR_P6[22] - (W1C) Queue operation error of port 6. Avoid +* unclear error flag, please clear flag when logic reset. +* RESERVED23[23] - (RO) Reserved bits +* DATA_OPER_ERR_P0[24] - (W1C) Data operation error of port 0. Avoid +* unclear error flag, please clear flag when logic reset. +* DATA_OPER_ERR_P1[25] - (W1C) Data operation error of port 1. Avoid +* unclear error flag, please clear flag when logic reset. +* DATA_OPER_ERR_P2[26] - (W1C) Data operation error of port 2. Avoid +* unclear error flag, please clear flag when logic reset. +* DATA_OPER_ERR_P3[27] - (W1C) Data operation error of port 3. Avoid +* unclear error flag, please clear flag when logic reset. +* DATA_OPER_ERR_P4[28] - (W1C) Data operation error of port 4. Avoid +* unclear error flag, please clear flag when logic reset. +* DATA_OPER_ERR_P5[29] - (W1C) Data operation error of port 5. Avoid +* unclear error flag, please clear flag when logic reset. +* DATA_OPER_ERR_P6[30] - (W1C) Data operation error of port 6. Avoid +* unclear error flag, please clear flag when logic reset. +* RESERVED31[31] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P6_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P6_MASK \ +0x40000000 /* DATA_OPER_ERR_P6[30] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P6_SHFT 30 +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P5_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P5_MASK \ +0x20000000 /* DATA_OPER_ERR_P5[29] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P5_SHFT 29 +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P4_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P4_MASK \ +0x10000000 /* DATA_OPER_ERR_P4[28] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P4_SHFT 28 +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P3_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P3_MASK \ +0x08000000 /* DATA_OPER_ERR_P3[27] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P3_SHFT 27 +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P2_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P2_MASK \ +0x04000000 /* DATA_OPER_ERR_P2[26] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P2_SHFT 26 +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P1_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P1_MASK \ +0x02000000 /* DATA_OPER_ERR_P1[25] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P1_SHFT 25 +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P0_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P0_MASK \ +0x01000000 /* DATA_OPER_ERR_P0[24] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P0_SHFT 24 +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P6_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P6_MASK \ +0x00400000 /* QUEUE_OPER_ERR_P6[22] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P6_SHFT 22 +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P5_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P5_MASK \ +0x00200000 /* QUEUE_OPER_ERR_P5[21] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P5_SHFT 21 +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P4_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P4_MASK \ +0x00100000 /* QUEUE_OPER_ERR_P4[20] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P4_SHFT 20 +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P3_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P3_MASK \ +0x00080000 /* QUEUE_OPER_ERR_P3[19] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P3_SHFT 19 +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P2_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P2_MASK \ +0x00040000 /* QUEUE_OPER_ERR_P2[18] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P2_SHFT 18 +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P1_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P1_MASK \ +0x00020000 /* QUEUE_OPER_ERR_P1[17] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P1_SHFT 17 +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P0_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P0_MASK \ +0x00010000 /* QUEUE_OPER_ERR_P0[16] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P0_SHFT 16 +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P6_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P6_MASK \ + 0x00004000 /* PAGE_UDF_P6[14] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P6_SHFT 14 +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P5_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P5_MASK \ + 0x00002000 /* PAGE_UDF_P5[13] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P5_SHFT 13 +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P4_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P4_MASK \ + 0x00001000 /* PAGE_UDF_P4[12] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P4_SHFT 12 +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P3_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P3_MASK \ + 0x00000800 /* PAGE_UDF_P3[11] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P3_SHFT 11 +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P2_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P2_MASK \ + 0x00000400 /* PAGE_UDF_P2[10] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P2_SHFT 10 +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P1_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P1_MASK \ + 0x00000200 /* PAGE_UDF_P1[9] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P1_SHFT 9 +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P0_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P0_MASK \ + 0x00000100 /* PAGE_UDF_P0[8] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P0_SHFT 8 +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P6_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P6_MASK \ +0x00000040 /* Q_CMD_ERR_P6[6] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P6_SHFT 6 +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P5_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P5_MASK \ +0x00000020 /* Q_CMD_ERR_P5[5] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P5_SHFT 5 +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P4_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P4_MASK \ +0x00000010 /* Q_CMD_ERR_P4[4] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P4_SHFT 4 +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P3_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P3_MASK \ +0x00000008 /* Q_CMD_ERR_P3[3] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P3_SHFT 3 +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P2_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P2_MASK \ +0x00000004 /* Q_CMD_ERR_P2[2] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P2_SHFT 2 +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P1_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P1_MASK \ +0x00000002 /* Q_CMD_ERR_P1[1] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P1_SHFT 1 +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P0_ADDR \ +WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P0_MASK \ +0x00000001 /* Q_CMD_ERR_P0[0] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P0_SHFT 0 + +/* +* ---INT_N9_ERR1_STS (0x820C8000 + 0x38)--- +* WDT_ERR_P0[0] - (W1C) Port state watch dog timeout error +* interrupt status of port 0. Avoid unclear error flag, please clear flag when +* logic reset. +* WDT_ERR_P1[1] - (W1C) Port state watch dog timeout error +* interrupt status of port 1. Avoid unclear error flag, please clear flag when +* logic reset. +* WDT_ERR_P2[2] - (W1C) Port state watch dog timeout error +* interrupt status of port 2. Avoid unclear error flag, please clear flag when +* logic reset. +* WDT_ERR_P3[3] - (W1C) Port state watch dog timeout error +* interrupt status of port 3. Avoid unclear error flag, please clear flag when +* logic reset. +* WDT_ERR_P4[4] - (W1C) Port state watch dog timeout error +* interrupt status of port 4. Avoid unclear error flag, please clear flag when +* logic reset. +* WDT_ERR_P5[5] - (W1C) Port state watch dog timeout error +* interrupt status of port 5. Avoid unclear error flag, please clear flag when +* logic reset. +* WDT_ERR_P6[6] - (W1C) Port state watch dog timeout error +* interrupt status of port 6. Avoid unclear error flag, please clear flag when +* logic reset. +* RESERVED7[7] - (RO) Reserved bits +* FL_HANG_ERR[8] - (W1C) Frame link FSM hang error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* PL_HANG_ERR[9] - (W1C) Page link FSM hang error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* DOUBLE_RLS_ERR[10] - (W1C) Double release error interrupt. Avoid +* unclear error flag, please clear flag when logic reset. +* FREE_HEAD_TAIL_ERR[11] - (W1C) Free head/tail error interrupt. Avoid +* unclear error flag, please clear flag when logic reset. +* FL_QSTRUCT_ERR[12] - (W1C) Frame Link queue NULL error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* RESERVED13[31..13] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_INT_N9_ERR1_STS_FL_QSTRUCT_ERR_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_STS_FL_QSTRUCT_ERR_MASK \ +0x00001000 /* FL_QSTRUCT_ERR[12] */ +#define WF_PSE_TOP_INT_N9_ERR1_STS_FL_QSTRUCT_ERR_SHFT 12 +#define WF_PSE_TOP_INT_N9_ERR1_STS_FREE_HEAD_TAIL_ERR_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_STS_FREE_HEAD_TAIL_ERR_MASK \ +0x00000800 /* FREE_HEAD_TAIL_ERR[11] */ +#define WF_PSE_TOP_INT_N9_ERR1_STS_FREE_HEAD_TAIL_ERR_SHFT 11 +#define WF_PSE_TOP_INT_N9_ERR1_STS_DOUBLE_RLS_ERR_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_STS_DOUBLE_RLS_ERR_MASK \ +0x00000400 /* DOUBLE_RLS_ERR[10] */ +#define WF_PSE_TOP_INT_N9_ERR1_STS_DOUBLE_RLS_ERR_SHFT 10 +#define WF_PSE_TOP_INT_N9_ERR1_STS_PL_HANG_ERR_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_STS_PL_HANG_ERR_MASK \ + 0x00000200 /* PL_HANG_ERR[9] */ +#define WF_PSE_TOP_INT_N9_ERR1_STS_PL_HANG_ERR_SHFT 9 +#define WF_PSE_TOP_INT_N9_ERR1_STS_FL_HANG_ERR_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_STS_FL_HANG_ERR_MASK \ + 0x00000100 /* FL_HANG_ERR[8] */ +#define WF_PSE_TOP_INT_N9_ERR1_STS_FL_HANG_ERR_SHFT 8 +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P6_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P6_MASK \ + 0x00000040 /* WDT_ERR_P6[6] */ +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P6_SHFT 6 +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P5_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P5_MASK \ + 0x00000020 /* WDT_ERR_P5[5] */ +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P5_SHFT 5 +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P4_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P4_MASK \ + 0x00000010 /* WDT_ERR_P4[4] */ +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P4_SHFT 4 +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P3_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P3_MASK \ + 0x00000008 /* WDT_ERR_P3[3] */ +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P3_SHFT 3 +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P2_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P2_MASK \ + 0x00000004 /* WDT_ERR_P2[2] */ +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P2_SHFT 2 +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P1_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P1_MASK \ + 0x00000002 /* WDT_ERR_P1[1] */ +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P1_SHFT 1 +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P0_ADDR \ +WF_PSE_TOP_INT_N9_ERR1_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P0_MASK \ + 0x00000001 /* WDT_ERR_P0[0] */ +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P0_SHFT 0 + +/* +* ---QUEUE_EMPTY (0x820C8000 + 0xB0)--- +* CPU_Q0_EMPTY[0] - (RO) CPU queue 0 empty status +* CPU_Q1_EMPTY[1] - (RO) CPU queue 1 empty status +* CPU_Q2_EMPTY[2] - (RO) CPU queue 2 empty status +* CPU_Q3_EMPTY[3] - (RO) CPU queue 3 empty status +* HIF_8_EMPTY[4] - (RO) HIF queue 8 empty status +* HIF_9_EMPTY[5] - (RO) HIF queue 9 empty status +* HIF_10_EMPTY[6] - (RO) HIF queue 10 empty status +* HIF_11_EMPTY[7] - (RO) HIF queue 11 empty status +* HIF_0_EMPTY[8] - (RO) HIF queue 0 empty status +* HIF_1_EMPTY[9] - (RO) HIF queue 1 empty status +* HIF_2_EMPTY[10] - (RO) HIF queue 2 empty status +* HIF_3_EMPTY[11] - (RO) HIF queue 3 empty status +* HIF_4_EMPTY[12] - (RO) HIF queue 4 empty status +* HIF_5_EMPTY[13] - (RO) HIF queue 5 empty status +* HIF_6_EMPTY[14] - (RO) HIF queue 6 empty status +* HIF_7_EMPTY[15] - (RO) HIF queue 7 empty status +* LMAC_TX_QUEUE_EMPTY[16] - (RO) LMAC TX queue empty status +* MDP_TX_QUEUE_EMPTY[17] - (RO) MDP TX queue empty status +* MDP_RX_QUEUE_EMPTY[18] - (RO) MDP RX queue empty status +* SEC_TX_QUEUE_EMPTY[19] - (RO) SEC TX queue empty status +* SEC_RX_QUEUE_EMPTY[20] - (RO) SEC RX queue empty status +* SFD_PARK_QUEUE_EMPTY[21] - (RO) SFD PARK queue empty status +* MDP_TXIOC_QUEUE_EMPTY[22] - (RO) MDP TXIOC queue empty status +* MDP_RXIOC_QUEUE_EMPTY[23] - (RO) MDP RXIOC queue empty status +* MDP_TX1_QUEUE_EMPTY[24] - (RO) MDP TX queue empty status for Band 1 +* SEC_TX1_QUEUE_EMPTY[25] - (RO) SEC TX queue empty status for Band 1 +* MDP_TXIOC1_QUEUE_EMPTY[26] - (RO) MDP TXIOC queue empty status for Band 1 +* MDP_RXIOC1_QUEUE_EMPTY[27] - (RO) MDP RXIOC queue empty status for Band 1 +* RESERVED28[30..28] - (RO) Reserved bits +* RLS_Q_EMTPY[31] - (RO) Release queue empty status +*/ +#define WF_PSE_TOP_QUEUE_EMPTY_RLS_Q_EMTPY_ADDR WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_RLS_Q_EMTPY_MASK 0x80000000 /* RLS_Q_EMTPY[31] */ +#define WF_PSE_TOP_QUEUE_EMPTY_RLS_Q_EMTPY_SHFT 31 +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_RXIOC1_QUEUE_EMPTY_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_RXIOC1_QUEUE_EMPTY_MASK \ +0x08000000 /* MDP_RXIOC1_QUEUE_EMPTY[27] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_RXIOC1_QUEUE_EMPTY_SHFT 27 +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_TXIOC1_QUEUE_EMPTY_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_TXIOC1_QUEUE_EMPTY_MASK \ +0x04000000 /* MDP_TXIOC1_QUEUE_EMPTY[26] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_TXIOC1_QUEUE_EMPTY_SHFT 26 +#define WF_PSE_TOP_QUEUE_EMPTY_SEC_TX1_QUEUE_EMPTY_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_SEC_TX1_QUEUE_EMPTY_MASK \ +0x02000000 /* SEC_TX1_QUEUE_EMPTY[25] */ +#define WF_PSE_TOP_QUEUE_EMPTY_SEC_TX1_QUEUE_EMPTY_SHFT 25 +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_TX1_QUEUE_EMPTY_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_TX1_QUEUE_EMPTY_MASK \ +0x01000000 /* MDP_TX1_QUEUE_EMPTY[24] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_TX1_QUEUE_EMPTY_SHFT 24 +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_RXIOC_QUEUE_EMPTY_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_RXIOC_QUEUE_EMPTY_MASK \ +0x00800000 /* MDP_RXIOC_QUEUE_EMPTY[23] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_RXIOC_QUEUE_EMPTY_SHFT 23 +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_TXIOC_QUEUE_EMPTY_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_TXIOC_QUEUE_EMPTY_MASK \ +0x00400000 /* MDP_TXIOC_QUEUE_EMPTY[22] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_TXIOC_QUEUE_EMPTY_SHFT 22 +#define WF_PSE_TOP_QUEUE_EMPTY_SFD_PARK_QUEUE_EMPTY_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_SFD_PARK_QUEUE_EMPTY_MASK \ +0x00200000 /* SFD_PARK_QUEUE_EMPTY[21] */ +#define WF_PSE_TOP_QUEUE_EMPTY_SFD_PARK_QUEUE_EMPTY_SHFT 21 +#define WF_PSE_TOP_QUEUE_EMPTY_SEC_RX_QUEUE_EMPTY_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_SEC_RX_QUEUE_EMPTY_MASK \ +0x00100000 /* SEC_RX_QUEUE_EMPTY[20] */ +#define WF_PSE_TOP_QUEUE_EMPTY_SEC_RX_QUEUE_EMPTY_SHFT 20 +#define WF_PSE_TOP_QUEUE_EMPTY_SEC_TX_QUEUE_EMPTY_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_SEC_TX_QUEUE_EMPTY_MASK \ +0x00080000 /* SEC_TX_QUEUE_EMPTY[19] */ +#define WF_PSE_TOP_QUEUE_EMPTY_SEC_TX_QUEUE_EMPTY_SHFT 19 +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_RX_QUEUE_EMPTY_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_RX_QUEUE_EMPTY_MASK \ +0x00040000 /* MDP_RX_QUEUE_EMPTY[18] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_RX_QUEUE_EMPTY_SHFT 18 +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_TX_QUEUE_EMPTY_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_TX_QUEUE_EMPTY_MASK \ +0x00020000 /* MDP_TX_QUEUE_EMPTY[17] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_TX_QUEUE_EMPTY_SHFT 17 +#define WF_PSE_TOP_QUEUE_EMPTY_LMAC_TX_QUEUE_EMPTY_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_LMAC_TX_QUEUE_EMPTY_MASK \ +0x00010000 /* LMAC_TX_QUEUE_EMPTY[16] */ +#define WF_PSE_TOP_QUEUE_EMPTY_LMAC_TX_QUEUE_EMPTY_SHFT 16 +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_7_EMPTY_ADDR WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_7_EMPTY_MASK 0x00008000 /* HIF_7_EMPTY[15] */ +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_7_EMPTY_SHFT 15 +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_6_EMPTY_ADDR WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_6_EMPTY_MASK 0x00004000 /* HIF_6_EMPTY[14] */ +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_6_EMPTY_SHFT 14 +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_5_EMPTY_ADDR WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_5_EMPTY_MASK 0x00002000 /* HIF_5_EMPTY[13] */ +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_5_EMPTY_SHFT 13 +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_4_EMPTY_ADDR WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_4_EMPTY_MASK 0x00001000 /* HIF_4_EMPTY[12] */ +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_4_EMPTY_SHFT 12 +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_3_EMPTY_ADDR WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_3_EMPTY_MASK 0x00000800 /* HIF_3_EMPTY[11] */ +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_3_EMPTY_SHFT 11 +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_2_EMPTY_ADDR WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_2_EMPTY_MASK 0x00000400 /* HIF_2_EMPTY[10] */ +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_2_EMPTY_SHFT 10 +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_1_EMPTY_ADDR WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_1_EMPTY_MASK 0x00000200 /* HIF_1_EMPTY[9] */ +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_1_EMPTY_SHFT 9 +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_0_EMPTY_ADDR WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_0_EMPTY_MASK 0x00000100 /* HIF_0_EMPTY[8] */ +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_0_EMPTY_SHFT 8 +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_11_EMPTY_ADDR WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_11_EMPTY_MASK \ + 0x00000080 /* HIF_11_EMPTY[7] */ +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_11_EMPTY_SHFT 7 +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_10_EMPTY_ADDR WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_10_EMPTY_MASK \ + 0x00000040 /* HIF_10_EMPTY[6] */ +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_10_EMPTY_SHFT 6 +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_9_EMPTY_ADDR WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_9_EMPTY_MASK 0x00000020 /* HIF_9_EMPTY[5] */ +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_9_EMPTY_SHFT 5 +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_8_EMPTY_ADDR WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_8_EMPTY_MASK 0x00000010 /* HIF_8_EMPTY[4] */ +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_8_EMPTY_SHFT 4 +#define WF_PSE_TOP_QUEUE_EMPTY_CPU_Q3_EMPTY_ADDR WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_CPU_Q3_EMPTY_MASK \ + 0x00000008 /* CPU_Q3_EMPTY[3] */ +#define WF_PSE_TOP_QUEUE_EMPTY_CPU_Q3_EMPTY_SHFT 3 +#define WF_PSE_TOP_QUEUE_EMPTY_CPU_Q2_EMPTY_ADDR WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_CPU_Q2_EMPTY_MASK \ + 0x00000004 /* CPU_Q2_EMPTY[2] */ +#define WF_PSE_TOP_QUEUE_EMPTY_CPU_Q2_EMPTY_SHFT 2 +#define WF_PSE_TOP_QUEUE_EMPTY_CPU_Q1_EMPTY_ADDR WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_CPU_Q1_EMPTY_MASK \ + 0x00000002 /* CPU_Q1_EMPTY[1] */ +#define WF_PSE_TOP_QUEUE_EMPTY_CPU_Q1_EMPTY_SHFT 1 +#define WF_PSE_TOP_QUEUE_EMPTY_CPU_Q0_EMPTY_ADDR WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_CPU_Q0_EMPTY_MASK \ + 0x00000001 /* CPU_Q0_EMPTY[0] */ +#define WF_PSE_TOP_QUEUE_EMPTY_CPU_Q0_EMPTY_SHFT 0 + +/* +* ---QUEUE_EMPTY_MASK (0x820C8000 + 0xB4)--- +* RESERVED0[7..0] - (RO) Reserved bits +* HIF_0_EMPTY_MASK[8] - (RW) Mask control of HIF queue 0 empty status +* HIF_1_EMPTY_MASK[9] - (RW) Mask control of HIF queue 1 empty status +* HIF_2_EMPTY_MASK[10] - (RW) Mask control of HIF queue 2 empty status +* HIF_3_EMPTY_MASK[11] - (RW) Mask control of HIF queue 3 empty status +* HIF_4_EMPTY_MASK[12] - (RW) Mask control of HIF queue 4 empty status +* HIF_5_EMPTY_MASK[13] - (RW) Mask control of HIF queue 5 empty status +* HIF_6_EMPTY_MASK[14] - (RW) Mask control of HIF queue 6 empty status +* HIF_7_EMPTY_MASK[15] - (RW) Mask control of HIF queue 7 empty status +* HIF_8_EMPTY_MASK[16] - (RW) Mask control of HIF queue 8 empty status +* HIF_9_EMPTY_MASK[17] - (RW) Mask control of HIF queue 9 empty status +* HIF_10_EMPTY_MASK[18] - (RW) Mask control of HIF queue 10 empty +status +* HIF_11_EMPTY_MASK[19] - (RW) Mask control of HIF queue 11 empty +status +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_11_EMPTY_MASK_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_MASK_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_11_EMPTY_MASK_MASK \ +0x00080000 /* HIF_11_EMPTY_MASK[19] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_11_EMPTY_MASK_SHFT 19 +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_10_EMPTY_MASK_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_MASK_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_10_EMPTY_MASK_MASK \ +0x00040000 /* HIF_10_EMPTY_MASK[18] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_10_EMPTY_MASK_SHFT 18 +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_9_EMPTY_MASK_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_MASK_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_9_EMPTY_MASK_MASK \ +0x00020000 /* HIF_9_EMPTY_MASK[17] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_9_EMPTY_MASK_SHFT 17 +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_8_EMPTY_MASK_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_MASK_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_8_EMPTY_MASK_MASK \ +0x00010000 /* HIF_8_EMPTY_MASK[16] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_8_EMPTY_MASK_SHFT 16 +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_7_EMPTY_MASK_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_MASK_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_7_EMPTY_MASK_MASK \ +0x00008000 /* HIF_7_EMPTY_MASK[15] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_7_EMPTY_MASK_SHFT 15 +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_6_EMPTY_MASK_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_MASK_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_6_EMPTY_MASK_MASK \ +0x00004000 /* HIF_6_EMPTY_MASK[14] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_6_EMPTY_MASK_SHFT 14 +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_5_EMPTY_MASK_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_MASK_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_5_EMPTY_MASK_MASK \ +0x00002000 /* HIF_5_EMPTY_MASK[13] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_5_EMPTY_MASK_SHFT 13 +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_4_EMPTY_MASK_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_MASK_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_4_EMPTY_MASK_MASK \ +0x00001000 /* HIF_4_EMPTY_MASK[12] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_4_EMPTY_MASK_SHFT 12 +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_3_EMPTY_MASK_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_MASK_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_3_EMPTY_MASK_MASK \ +0x00000800 /* HIF_3_EMPTY_MASK[11] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_3_EMPTY_MASK_SHFT 11 +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_2_EMPTY_MASK_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_MASK_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_2_EMPTY_MASK_MASK \ +0x00000400 /* HIF_2_EMPTY_MASK[10] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_2_EMPTY_MASK_SHFT 10 +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_1_EMPTY_MASK_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_MASK_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_1_EMPTY_MASK_MASK \ +0x00000200 /* HIF_1_EMPTY_MASK[9] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_1_EMPTY_MASK_SHFT 9 +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_0_EMPTY_MASK_ADDR \ +WF_PSE_TOP_QUEUE_EMPTY_MASK_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_0_EMPTY_MASK_MASK \ +0x00000100 /* HIF_0_EMPTY_MASK[8] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_0_EMPTY_MASK_SHFT 8 + +/* +* ---PSE_LP_CTRL (0x820C8000 + 0xB8)--- +* RESERVED0[6..0] - (RO) Reserved bits +* PSE_LP_WAKEUP[7] - (RW) PSE Low Power Wakeup control +* PSE2HIF_PSSS_EN[8] - (RW) PSE Access HIF port control +* MCU_COALEASCE[9] - (RW) Coalease CPU ENQ and ENQ_DLY for HIF +port +* RESERVED10[31..10] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_LP_CTRL_MCU_COALEASCE_ADDR WF_PSE_TOP_PSE_LP_CTRL_ADDR +#define WF_PSE_TOP_PSE_LP_CTRL_MCU_COALEASCE_MASK \ + 0x00000200 /* MCU_COALEASCE[9] */ +#define WF_PSE_TOP_PSE_LP_CTRL_MCU_COALEASCE_SHFT 9 +#define WF_PSE_TOP_PSE_LP_CTRL_PSE2HIF_PSSS_EN_ADDR WF_PSE_TOP_PSE_LP_CTRL_ADDR +#define WF_PSE_TOP_PSE_LP_CTRL_PSE2HIF_PSSS_EN_MASK \ +0x00000100 /* PSE2HIF_PSSS_EN[8] */ +#define WF_PSE_TOP_PSE_LP_CTRL_PSE2HIF_PSSS_EN_SHFT 8 +#define WF_PSE_TOP_PSE_LP_CTRL_PSE_LP_WAKEUP_ADDR WF_PSE_TOP_PSE_LP_CTRL_ADDR +#define WF_PSE_TOP_PSE_LP_CTRL_PSE_LP_WAKEUP_MASK \ + 0x00000080 /* PSE_LP_WAKEUP[7] */ +#define WF_PSE_TOP_PSE_LP_CTRL_PSE_LP_WAKEUP_SHFT 7 + +/* +* ---TO_N9_INT (0x820C8000 + 0xF0)--- +* CR4_CMD[30..0] - (RW) Command for N9 +* TOGGLE[31] - (RW) When this bit is toggled, HW will send +* interrupt to N9. +*/ +#define WF_PSE_TOP_TO_N9_INT_TOGGLE_ADDR WF_PSE_TOP_TO_N9_INT_ADDR +#define WF_PSE_TOP_TO_N9_INT_TOGGLE_MASK 0x80000000 /* TOGGLE[31] */ +#define WF_PSE_TOP_TO_N9_INT_TOGGLE_SHFT 31 +#define WF_PSE_TOP_TO_N9_INT_CR4_CMD_ADDR WF_PSE_TOP_TO_N9_INT_ADDR +#define WF_PSE_TOP_TO_N9_INT_CR4_CMD_MASK 0x7FFFFFFF /* CR4_CMD[30..0] */ +#define WF_PSE_TOP_TO_N9_INT_CR4_CMD_SHFT 0 + +/* +* ---GROUP_REFILL_CTRL (0x820C8000 + 0x108)--- +* GROUP_REFILL_PRI[12..0] - (RW) group refill priority control +* RESERVED13[15..13] - (RO) Reserved bits +* DIS_GROUP_REFILL[28..16] - (RW) group quota refill enable control +* RESERVED29[31..29] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_GROUP_REFILL_CTRL_DIS_GROUP_REFILL_ADDR \ +WF_PSE_TOP_GROUP_REFILL_CTRL_ADDR +#define WF_PSE_TOP_GROUP_REFILL_CTRL_DIS_GROUP_REFILL_MASK \ +0x1FFF0000 /* DIS_GROUP_REFILL[28..16] */ +#define WF_PSE_TOP_GROUP_REFILL_CTRL_DIS_GROUP_REFILL_SHFT 16 +#define WF_PSE_TOP_GROUP_REFILL_CTRL_GROUP_REFILL_PRI_ADDR \ +WF_PSE_TOP_GROUP_REFILL_CTRL_ADDR +#define WF_PSE_TOP_GROUP_REFILL_CTRL_GROUP_REFILL_PRI_MASK \ +0x00001FFF /* GROUP_REFILL_PRI[12..0] */ +#define WF_PSE_TOP_GROUP_REFILL_CTRL_GROUP_REFILL_PRI_SHFT 0 + +/* +* ---FREEPG_START_END (0x820C8000 + 0x10C)--- +* FREEPG_START[11..0] - (RW) Start page setting of free pages +* RESERVED12[15..12] - (RO) Reserved bits +* FREEPG_END[27..16] - (RW) End page setting of free page +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_FREEPG_START_END_FREEPG_END_ADDR \ +WF_PSE_TOP_FREEPG_START_END_ADDR +#define WF_PSE_TOP_FREEPG_START_END_FREEPG_END_MASK \ +0x0FFF0000 /* FREEPG_END[27..16] */ +#define WF_PSE_TOP_FREEPG_START_END_FREEPG_END_SHFT 16 +#define WF_PSE_TOP_FREEPG_START_END_FREEPG_START_ADDR \ +WF_PSE_TOP_FREEPG_START_END_ADDR +#define WF_PSE_TOP_FREEPG_START_END_FREEPG_START_MASK \ +0x00000FFF /* FREEPG_START[11..0] */ +#define WF_PSE_TOP_FREEPG_START_END_FREEPG_START_SHFT 0 + +/* +* ---PG_HIF0_GROUP (0x820C8000 + 0x110)--- +* HIF0_MIN_QUOTA[11..0] - (RW) Min. quota of HIF 0 group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED12[15..12] - (RO) Reserved bits +* HIF0_MAX_QUOTA[27..16] - (RW) Max. quota of HIF 0 group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PG_HIF0_GROUP_HIF0_MAX_QUOTA_ADDR \ +WF_PSE_TOP_PG_HIF0_GROUP_ADDR +#define WF_PSE_TOP_PG_HIF0_GROUP_HIF0_MAX_QUOTA_MASK \ +0x0FFF0000 /* HIF0_MAX_QUOTA[27..16] */ +#define WF_PSE_TOP_PG_HIF0_GROUP_HIF0_MAX_QUOTA_SHFT 16 +#define WF_PSE_TOP_PG_HIF0_GROUP_HIF0_MIN_QUOTA_ADDR \ +WF_PSE_TOP_PG_HIF0_GROUP_ADDR +#define WF_PSE_TOP_PG_HIF0_GROUP_HIF0_MIN_QUOTA_MASK \ +0x00000FFF /* HIF0_MIN_QUOTA[11..0] */ +#define WF_PSE_TOP_PG_HIF0_GROUP_HIF0_MIN_QUOTA_SHFT 0 + +/* +* ---PG_HIF1_GROUP (0x820C8000 + 0x114)--- +* HIF1_MIN_QUOTA[11..0] - (RW) Min. quota of HIF 1 group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED12[15..12] - (RO) Reserved bits +* HIF1_MAX_QUOTA[27..16] - (RW) Max. quota of HIF 1 group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PG_HIF1_GROUP_HIF1_MAX_QUOTA_ADDR \ +WF_PSE_TOP_PG_HIF1_GROUP_ADDR +#define WF_PSE_TOP_PG_HIF1_GROUP_HIF1_MAX_QUOTA_MASK \ +0x0FFF0000 /* HIF1_MAX_QUOTA[27..16] */ +#define WF_PSE_TOP_PG_HIF1_GROUP_HIF1_MAX_QUOTA_SHFT 16 +#define WF_PSE_TOP_PG_HIF1_GROUP_HIF1_MIN_QUOTA_ADDR \ +WF_PSE_TOP_PG_HIF1_GROUP_ADDR +#define WF_PSE_TOP_PG_HIF1_GROUP_HIF1_MIN_QUOTA_MASK \ +0x00000FFF /* HIF1_MIN_QUOTA[11..0] */ +#define WF_PSE_TOP_PG_HIF1_GROUP_HIF1_MIN_QUOTA_SHFT 0 + +/* +* ---PG_CPU_GROUP (0x820C8000 + 0x118)--- +* CPU_MIN_QUOTA[11..0] - (RW) Min. quota of CPU group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED12[15..12] - (RO) Reserved bits +* CPU_MAX_QUOTA[27..16] - (RW) Max. quota of CPU group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PG_CPU_GROUP_CPU_MAX_QUOTA_ADDR WF_PSE_TOP_PG_CPU_GROUP_ADDR +#define WF_PSE_TOP_PG_CPU_GROUP_CPU_MAX_QUOTA_MASK \ +0x0FFF0000 /* CPU_MAX_QUOTA[27..16] */ +#define WF_PSE_TOP_PG_CPU_GROUP_CPU_MAX_QUOTA_SHFT 16 +#define WF_PSE_TOP_PG_CPU_GROUP_CPU_MIN_QUOTA_ADDR WF_PSE_TOP_PG_CPU_GROUP_ADDR +#define WF_PSE_TOP_PG_CPU_GROUP_CPU_MIN_QUOTA_MASK \ +0x00000FFF /* CPU_MIN_QUOTA[11..0] */ +#define WF_PSE_TOP_PG_CPU_GROUP_CPU_MIN_QUOTA_SHFT 0 + +/* +* ---PG_PLE_GROUP (0x820C8000 + 0x11C)--- +* PLE_MIN_QUOTA[11..0] - (RW) Min. quota of PLE group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED12[15..12] - (RO) Reserved bits +* PLE_MAX_QUOTA[27..16] - (RW) Max. quota of PLE group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PG_PLE_GROUP_PLE_MAX_QUOTA_ADDR WF_PSE_TOP_PG_PLE_GROUP_ADDR +#define WF_PSE_TOP_PG_PLE_GROUP_PLE_MAX_QUOTA_MASK \ +0x0FFF0000 /* PLE_MAX_QUOTA[27..16] */ +#define WF_PSE_TOP_PG_PLE_GROUP_PLE_MAX_QUOTA_SHFT 16 +#define WF_PSE_TOP_PG_PLE_GROUP_PLE_MIN_QUOTA_ADDR WF_PSE_TOP_PG_PLE_GROUP_ADDR +#define WF_PSE_TOP_PG_PLE_GROUP_PLE_MIN_QUOTA_MASK \ +0x00000FFF /* PLE_MIN_QUOTA[11..0] */ +#define WF_PSE_TOP_PG_PLE_GROUP_PLE_MIN_QUOTA_SHFT 0 + +/* +* ---PG_PLE1_GROUP (0x820C8000 + 0x120)--- +* PLE_MIN_QUOTA[11..0] - (RW) Min. quota of PLE group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED12[15..12] - (RO) Reserved bits +* PLE_MAX_QUOTA[27..16] - (RW) Max. quota of PLE group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PG_PLE1_GROUP_PLE_MAX_QUOTA_ADDR \ +WF_PSE_TOP_PG_PLE1_GROUP_ADDR +#define WF_PSE_TOP_PG_PLE1_GROUP_PLE_MAX_QUOTA_MASK \ +0x0FFF0000 /* PLE_MAX_QUOTA[27..16] */ +#define WF_PSE_TOP_PG_PLE1_GROUP_PLE_MAX_QUOTA_SHFT 16 +#define WF_PSE_TOP_PG_PLE1_GROUP_PLE_MIN_QUOTA_ADDR \ +WF_PSE_TOP_PG_PLE1_GROUP_ADDR +#define WF_PSE_TOP_PG_PLE1_GROUP_PLE_MIN_QUOTA_MASK \ +0x00000FFF /* PLE_MIN_QUOTA[11..0] */ +#define WF_PSE_TOP_PG_PLE1_GROUP_PLE_MIN_QUOTA_SHFT 0 + +/* +* ---PG_LMAC0_GROUP (0x820C8000 + 0x124)--- +* LMAC0_MIN_QUOTA[11..0] - (RW) Min. quota of LMAC 0 group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED12[15..12] - (RO) Reserved bits +* LMAC0_MAX_QUOTA[27..16] - (RW) Max. quota of LMAC 0 group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PG_LMAC0_GROUP_LMAC0_MAX_QUOTA_ADDR \ +WF_PSE_TOP_PG_LMAC0_GROUP_ADDR +#define WF_PSE_TOP_PG_LMAC0_GROUP_LMAC0_MAX_QUOTA_MASK \ +0x0FFF0000 /* LMAC0_MAX_QUOTA[27..16] */ +#define WF_PSE_TOP_PG_LMAC0_GROUP_LMAC0_MAX_QUOTA_SHFT 16 +#define WF_PSE_TOP_PG_LMAC0_GROUP_LMAC0_MIN_QUOTA_ADDR \ +WF_PSE_TOP_PG_LMAC0_GROUP_ADDR +#define WF_PSE_TOP_PG_LMAC0_GROUP_LMAC0_MIN_QUOTA_MASK \ +0x00000FFF /* LMAC0_MIN_QUOTA[11..0] */ +#define WF_PSE_TOP_PG_LMAC0_GROUP_LMAC0_MIN_QUOTA_SHFT 0 + +/* +* ---PG_LMAC1_GROUP (0x820C8000 + 0x128)--- +* LMAC1_MIN_QUOTA[11..0] - (RW) Min. quota of LMAC 1 group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED12[15..12] - (RO) Reserved bits +* LMAC1_MAX_QUOTA[27..16] - (RW) Max. quota of LMAC 1 group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PG_LMAC1_GROUP_LMAC1_MAX_QUOTA_ADDR \ +WF_PSE_TOP_PG_LMAC1_GROUP_ADDR +#define WF_PSE_TOP_PG_LMAC1_GROUP_LMAC1_MAX_QUOTA_MASK \ +0x0FFF0000 /* LMAC1_MAX_QUOTA[27..16] */ +#define WF_PSE_TOP_PG_LMAC1_GROUP_LMAC1_MAX_QUOTA_SHFT 16 +#define WF_PSE_TOP_PG_LMAC1_GROUP_LMAC1_MIN_QUOTA_ADDR \ +WF_PSE_TOP_PG_LMAC1_GROUP_ADDR +#define WF_PSE_TOP_PG_LMAC1_GROUP_LMAC1_MIN_QUOTA_MASK \ +0x00000FFF /* LMAC1_MIN_QUOTA[11..0] */ +#define WF_PSE_TOP_PG_LMAC1_GROUP_LMAC1_MIN_QUOTA_SHFT 0 + +/* +* ---PG_LMAC2_GROUP (0x820C8000 + 0x12C)--- +* LMAC2_MIN_QUOTA[11..0] - (RW) Min. quota of LMAC 2 group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED12[15..12] - (RO) Reserved bits +* LMAC2_MAX_QUOTA[27..16] - (RW) Max. quota of LMAC 2 group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PG_LMAC2_GROUP_LMAC2_MAX_QUOTA_ADDR \ +WF_PSE_TOP_PG_LMAC2_GROUP_ADDR +#define WF_PSE_TOP_PG_LMAC2_GROUP_LMAC2_MAX_QUOTA_MASK \ +0x0FFF0000 /* LMAC2_MAX_QUOTA[27..16] */ +#define WF_PSE_TOP_PG_LMAC2_GROUP_LMAC2_MAX_QUOTA_SHFT 16 +#define WF_PSE_TOP_PG_LMAC2_GROUP_LMAC2_MIN_QUOTA_ADDR \ +WF_PSE_TOP_PG_LMAC2_GROUP_ADDR +#define WF_PSE_TOP_PG_LMAC2_GROUP_LMAC2_MIN_QUOTA_MASK \ +0x00000FFF /* LMAC2_MIN_QUOTA[11..0] */ +#define WF_PSE_TOP_PG_LMAC2_GROUP_LMAC2_MIN_QUOTA_SHFT 0 + +/* +* ---PG_LMAC3_GROUP (0x820C8000 + 0x130)--- +* LMAC3_MIN_QUOTA[11..0] - (RW) Min. quota of LMAC 3 group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED12[15..12] - (RO) Reserved bits +* LMAC3_MAX_QUOTA[27..16] - (RW) Max. quota of LMAC 3 group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PG_LMAC3_GROUP_LMAC3_MAX_QUOTA_ADDR \ +WF_PSE_TOP_PG_LMAC3_GROUP_ADDR +#define WF_PSE_TOP_PG_LMAC3_GROUP_LMAC3_MAX_QUOTA_MASK \ +0x0FFF0000 /* LMAC3_MAX_QUOTA[27..16] */ +#define WF_PSE_TOP_PG_LMAC3_GROUP_LMAC3_MAX_QUOTA_SHFT 16 +#define WF_PSE_TOP_PG_LMAC3_GROUP_LMAC3_MIN_QUOTA_ADDR \ +WF_PSE_TOP_PG_LMAC3_GROUP_ADDR +#define WF_PSE_TOP_PG_LMAC3_GROUP_LMAC3_MIN_QUOTA_MASK \ +0x00000FFF /* LMAC3_MIN_QUOTA[11..0] */ +#define WF_PSE_TOP_PG_LMAC3_GROUP_LMAC3_MIN_QUOTA_SHFT 0 + +/* +* ---PG_MDP_GROUP (0x820C8000 + 0x134)--- +* MDP_MIN_QUOTA[11..0] - (RW) Min. quota of MDP group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED12[15..12] - (RO) Reserved bits +* MDP_MAX_QUOTA[27..16] - (RW) Max. quota of MDP group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PG_MDP_GROUP_MDP_MAX_QUOTA_ADDR WF_PSE_TOP_PG_MDP_GROUP_ADDR +#define WF_PSE_TOP_PG_MDP_GROUP_MDP_MAX_QUOTA_MASK \ +0x0FFF0000 /* MDP_MAX_QUOTA[27..16] */ +#define WF_PSE_TOP_PG_MDP_GROUP_MDP_MAX_QUOTA_SHFT 16 +#define WF_PSE_TOP_PG_MDP_GROUP_MDP_MIN_QUOTA_ADDR WF_PSE_TOP_PG_MDP_GROUP_ADDR +#define WF_PSE_TOP_PG_MDP_GROUP_MDP_MIN_QUOTA_MASK \ +0x00000FFF /* MDP_MIN_QUOTA[11..0] */ +#define WF_PSE_TOP_PG_MDP_GROUP_MDP_MIN_QUOTA_SHFT 0 + +/* +* ---PG_MDP1_GROUP (0x820C8000 + 0x138)--- +* MDP1_MIN_QUOTA[11..0] - (RW) Min. quota of MDP1 group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED12[15..12] - (RO) Reserved bits +* MDP1_MAX_QUOTA[27..16] - (RW) Max. quota of MDP1 group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PG_MDP1_GROUP_MDP1_MAX_QUOTA_ADDR \ +WF_PSE_TOP_PG_MDP1_GROUP_ADDR +#define WF_PSE_TOP_PG_MDP1_GROUP_MDP1_MAX_QUOTA_MASK \ +0x0FFF0000 /* MDP1_MAX_QUOTA[27..16] */ +#define WF_PSE_TOP_PG_MDP1_GROUP_MDP1_MAX_QUOTA_SHFT 16 +#define WF_PSE_TOP_PG_MDP1_GROUP_MDP1_MIN_QUOTA_ADDR \ +WF_PSE_TOP_PG_MDP1_GROUP_ADDR +#define WF_PSE_TOP_PG_MDP1_GROUP_MDP1_MIN_QUOTA_MASK \ +0x00000FFF /* MDP1_MIN_QUOTA[11..0] */ +#define WF_PSE_TOP_PG_MDP1_GROUP_MDP1_MIN_QUOTA_SHFT 0 + +/* +* ---PG_MDP2_GROUP (0x820C8000 + 0x13C)--- +* MDP2_MIN_QUOTA[11..0] - (RW) Min. quota of MDP2 group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED12[15..12] - (RO) Reserved bits +* MDP2_MAX_QUOTA[27..16] - (RW) Max. quota of MDP2 group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PG_MDP2_GROUP_MDP2_MAX_QUOTA_ADDR \ +WF_PSE_TOP_PG_MDP2_GROUP_ADDR +#define WF_PSE_TOP_PG_MDP2_GROUP_MDP2_MAX_QUOTA_MASK \ +0x0FFF0000 /* MDP2_MAX_QUOTA[27..16] */ +#define WF_PSE_TOP_PG_MDP2_GROUP_MDP2_MAX_QUOTA_SHFT 16 +#define WF_PSE_TOP_PG_MDP2_GROUP_MDP2_MIN_QUOTA_ADDR \ +WF_PSE_TOP_PG_MDP2_GROUP_ADDR +#define WF_PSE_TOP_PG_MDP2_GROUP_MDP2_MIN_QUOTA_MASK \ +0x00000FFF /* MDP2_MIN_QUOTA[11..0] */ +#define WF_PSE_TOP_PG_MDP2_GROUP_MDP2_MIN_QUOTA_SHFT 0 + +/* +* ---PG_HIF2_GROUP (0x820C8000 + 0x140)--- +* HIF2_MIN_QUOTA[11..0] - (RW) Min. quota of HIF 2 group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED12[15..12] - (RO) Reserved bits +* HIF2_MAX_QUOTA[27..16] - (RW) Max. quota of HIF 2 group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PG_HIF2_GROUP_HIF2_MAX_QUOTA_ADDR \ +WF_PSE_TOP_PG_HIF2_GROUP_ADDR +#define WF_PSE_TOP_PG_HIF2_GROUP_HIF2_MAX_QUOTA_MASK \ +0x0FFF0000 /* HIF2_MAX_QUOTA[27..16] */ +#define WF_PSE_TOP_PG_HIF2_GROUP_HIF2_MAX_QUOTA_SHFT 16 +#define WF_PSE_TOP_PG_HIF2_GROUP_HIF2_MIN_QUOTA_ADDR \ +WF_PSE_TOP_PG_HIF2_GROUP_ADDR +#define WF_PSE_TOP_PG_HIF2_GROUP_HIF2_MIN_QUOTA_MASK \ +0x00000FFF /* HIF2_MIN_QUOTA[11..0] */ +#define WF_PSE_TOP_PG_HIF2_GROUP_HIF2_MIN_QUOTA_SHFT 0 + +/* +* ---HIF0_PG_INFO (0x820C8000 + 0x150)--- +* HIF0_RSV_CNT[11..0] - (RO) Reserved pages of HIF 0 group +* RESERVED12[15..12] - (RO) Reserved bits +* HIF0_SRC_CNT[27..16] - (RO) Used pages of HIF 0 group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_HIF0_PG_INFO_HIF0_SRC_CNT_ADDR WF_PSE_TOP_HIF0_PG_INFO_ADDR +#define WF_PSE_TOP_HIF0_PG_INFO_HIF0_SRC_CNT_MASK \ +0x0FFF0000 /* HIF0_SRC_CNT[27..16] */ +#define WF_PSE_TOP_HIF0_PG_INFO_HIF0_SRC_CNT_SHFT 16 +#define WF_PSE_TOP_HIF0_PG_INFO_HIF0_RSV_CNT_ADDR WF_PSE_TOP_HIF0_PG_INFO_ADDR +#define WF_PSE_TOP_HIF0_PG_INFO_HIF0_RSV_CNT_MASK \ +0x00000FFF /* HIF0_RSV_CNT[11..0] */ +#define WF_PSE_TOP_HIF0_PG_INFO_HIF0_RSV_CNT_SHFT 0 + +/* +* ---HIF1_PG_INFO (0x820C8000 + 0x154)--- +* HIF1_RSV_CNT[11..0] - (RO) Reserved pages of HIF 1 group +* RESERVED12[15..12] - (RO) Reserved bits +* HIF1_SRC_CNT[27..16] - (RO) Used pages of HIF 1 group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_HIF1_PG_INFO_HIF1_SRC_CNT_ADDR WF_PSE_TOP_HIF1_PG_INFO_ADDR +#define WF_PSE_TOP_HIF1_PG_INFO_HIF1_SRC_CNT_MASK \ +0x0FFF0000 /* HIF1_SRC_CNT[27..16] */ +#define WF_PSE_TOP_HIF1_PG_INFO_HIF1_SRC_CNT_SHFT 16 +#define WF_PSE_TOP_HIF1_PG_INFO_HIF1_RSV_CNT_ADDR WF_PSE_TOP_HIF1_PG_INFO_ADDR +#define WF_PSE_TOP_HIF1_PG_INFO_HIF1_RSV_CNT_MASK \ +0x00000FFF /* HIF1_RSV_CNT[11..0] */ +#define WF_PSE_TOP_HIF1_PG_INFO_HIF1_RSV_CNT_SHFT 0 + +/* +* ---CPU_PG_INFO (0x820C8000 + 0x158)--- +* CPU_RSV_CNT[11..0] - (RO) Reserved pages of CPU group +* RESERVED12[15..12] - (RO) Reserved bits +* CPU_SRC_CNT[27..16] - (RO) Used pages of CPU group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_CPU_PG_INFO_CPU_SRC_CNT_ADDR WF_PSE_TOP_CPU_PG_INFO_ADDR +#define WF_PSE_TOP_CPU_PG_INFO_CPU_SRC_CNT_MASK \ +0x0FFF0000 /* CPU_SRC_CNT[27..16] */ +#define WF_PSE_TOP_CPU_PG_INFO_CPU_SRC_CNT_SHFT 16 +#define WF_PSE_TOP_CPU_PG_INFO_CPU_RSV_CNT_ADDR WF_PSE_TOP_CPU_PG_INFO_ADDR +#define WF_PSE_TOP_CPU_PG_INFO_CPU_RSV_CNT_MASK \ + 0x00000FFF /* CPU_RSV_CNT[11..0] */ +#define WF_PSE_TOP_CPU_PG_INFO_CPU_RSV_CNT_SHFT 0 + +/* +* ---PLE_PG_INFO (0x820C8000 + 0x15C)--- +* PLE_RSV_CNT[11..0] - (RO) Reserved pages of PLE group +* RESERVED12[15..12] - (RO) Reserved bits +* PLE_SRC_CNT[27..16] - (RO) Used pages of PLE group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PLE_PG_INFO_PLE_SRC_CNT_ADDR WF_PSE_TOP_PLE_PG_INFO_ADDR +#define WF_PSE_TOP_PLE_PG_INFO_PLE_SRC_CNT_MASK \ +0x0FFF0000 /* PLE_SRC_CNT[27..16] */ +#define WF_PSE_TOP_PLE_PG_INFO_PLE_SRC_CNT_SHFT 16 +#define WF_PSE_TOP_PLE_PG_INFO_PLE_RSV_CNT_ADDR WF_PSE_TOP_PLE_PG_INFO_ADDR +#define WF_PSE_TOP_PLE_PG_INFO_PLE_RSV_CNT_MASK \ + 0x00000FFF /* PLE_RSV_CNT[11..0] */ +#define WF_PSE_TOP_PLE_PG_INFO_PLE_RSV_CNT_SHFT 0 + +/* +* ---PLE1_PG_INFO (0x820C8000 + 0x160)--- +* PLE_RSV_CNT[11..0] - (RO) Reserved pages of PLE group +* RESERVED12[15..12] - (RO) Reserved bits +* PLE_SRC_CNT[27..16] - (RO) Used pages of PLE group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PLE1_PG_INFO_PLE_SRC_CNT_ADDR WF_PSE_TOP_PLE1_PG_INFO_ADDR +#define WF_PSE_TOP_PLE1_PG_INFO_PLE_SRC_CNT_MASK \ +0x0FFF0000 /* PLE_SRC_CNT[27..16] */ +#define WF_PSE_TOP_PLE1_PG_INFO_PLE_SRC_CNT_SHFT 16 +#define WF_PSE_TOP_PLE1_PG_INFO_PLE_RSV_CNT_ADDR WF_PSE_TOP_PLE1_PG_INFO_ADDR +#define WF_PSE_TOP_PLE1_PG_INFO_PLE_RSV_CNT_MASK \ +0x00000FFF /* PLE_RSV_CNT[11..0] */ +#define WF_PSE_TOP_PLE1_PG_INFO_PLE_RSV_CNT_SHFT 0 + +/* +* ---LMAC0_PG_INFO (0x820C8000 + 0x164)--- +* LMAC0_RSV_CNT[11..0] - (RO) Reserved pages of LMAC 0 group +* RESERVED12[15..12] - (RO) Reserved bits +* LMAC0_SRC_CNT[27..16] - (RO) Used pages of LMAC 0 group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_LMAC0_PG_INFO_LMAC0_SRC_CNT_ADDR \ +WF_PSE_TOP_LMAC0_PG_INFO_ADDR +#define WF_PSE_TOP_LMAC0_PG_INFO_LMAC0_SRC_CNT_MASK \ +0x0FFF0000 /* LMAC0_SRC_CNT[27..16] */ +#define WF_PSE_TOP_LMAC0_PG_INFO_LMAC0_SRC_CNT_SHFT 16 +#define WF_PSE_TOP_LMAC0_PG_INFO_LMAC0_RSV_CNT_ADDR \ +WF_PSE_TOP_LMAC0_PG_INFO_ADDR +#define WF_PSE_TOP_LMAC0_PG_INFO_LMAC0_RSV_CNT_MASK \ +0x00000FFF /* LMAC0_RSV_CNT[11..0] */ +#define WF_PSE_TOP_LMAC0_PG_INFO_LMAC0_RSV_CNT_SHFT 0 + +/* +* ---LMAC1_PG_INFO (0x820C8000 + 0x168)--- +* LMAC1_RSV_CNT[11..0] - (RO) Reserved pages of LMAC 1 group +* RESERVED12[15..12] - (RO) Reserved bits +* LMAC1_SRC_CNT[27..16] - (RO) Used pages of LMAC 1 group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_LMAC1_PG_INFO_LMAC1_SRC_CNT_ADDR \ +WF_PSE_TOP_LMAC1_PG_INFO_ADDR +#define WF_PSE_TOP_LMAC1_PG_INFO_LMAC1_SRC_CNT_MASK \ +0x0FFF0000 /* LMAC1_SRC_CNT[27..16] */ +#define WF_PSE_TOP_LMAC1_PG_INFO_LMAC1_SRC_CNT_SHFT 16 +#define WF_PSE_TOP_LMAC1_PG_INFO_LMAC1_RSV_CNT_ADDR \ +WF_PSE_TOP_LMAC1_PG_INFO_ADDR +#define WF_PSE_TOP_LMAC1_PG_INFO_LMAC1_RSV_CNT_MASK \ +0x00000FFF /* LMAC1_RSV_CNT[11..0] */ +#define WF_PSE_TOP_LMAC1_PG_INFO_LMAC1_RSV_CNT_SHFT 0 + +/* +* ---LMAC2_PG_INFO (0x820C8000 + 0x16C)--- +* LMAC2_RSV_CNT[11..0] - (RO) Reserved pages of LMAC 2 group +* RESERVED12[15..12] - (RO) Reserved bits +* LMAC2_SRC_CNT[27..16] - (RO) Used pages of LMAC 2 group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_LMAC2_PG_INFO_LMAC2_SRC_CNT_ADDR \ +WF_PSE_TOP_LMAC2_PG_INFO_ADDR +#define WF_PSE_TOP_LMAC2_PG_INFO_LMAC2_SRC_CNT_MASK \ +0x0FFF0000 /* LMAC2_SRC_CNT[27..16] */ +#define WF_PSE_TOP_LMAC2_PG_INFO_LMAC2_SRC_CNT_SHFT 16 +#define WF_PSE_TOP_LMAC2_PG_INFO_LMAC2_RSV_CNT_ADDR \ +WF_PSE_TOP_LMAC2_PG_INFO_ADDR +#define WF_PSE_TOP_LMAC2_PG_INFO_LMAC2_RSV_CNT_MASK \ +0x00000FFF /* LMAC2_RSV_CNT[11..0] */ +#define WF_PSE_TOP_LMAC2_PG_INFO_LMAC2_RSV_CNT_SHFT 0 + +/* +* ---LMAC3_PG_INFO (0x820C8000 + 0x170)--- +* LMAC3_RSV_CNT[11..0] - (RO) Reserved pages of LMAC 3 group +* RESERVED12[15..12] - (RO) Reserved bits +* LMAC3_SRC_CNT[27..16] - (RO) Used pages of LMAC 3 group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_LMAC3_PG_INFO_LMAC3_SRC_CNT_ADDR \ +WF_PSE_TOP_LMAC3_PG_INFO_ADDR +#define WF_PSE_TOP_LMAC3_PG_INFO_LMAC3_SRC_CNT_MASK \ +0x0FFF0000 /* LMAC3_SRC_CNT[27..16] */ +#define WF_PSE_TOP_LMAC3_PG_INFO_LMAC3_SRC_CNT_SHFT 16 +#define WF_PSE_TOP_LMAC3_PG_INFO_LMAC3_RSV_CNT_ADDR \ +WF_PSE_TOP_LMAC3_PG_INFO_ADDR +#define WF_PSE_TOP_LMAC3_PG_INFO_LMAC3_RSV_CNT_MASK \ +0x00000FFF /* LMAC3_RSV_CNT[11..0] */ +#define WF_PSE_TOP_LMAC3_PG_INFO_LMAC3_RSV_CNT_SHFT 0 + +/* +* ---MDP_PG_INFO (0x820C8000 + 0x174)--- +* MDP_RSV_CNT[11..0] - (RO) Reserved pages of MDP group +* RESERVED12[15..12] - (RO) Reserved bits +* MDP_SRC_CNT[27..16] - (RO) Used pages of MDP group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_MDP_PG_INFO_MDP_SRC_CNT_ADDR WF_PSE_TOP_MDP_PG_INFO_ADDR +#define WF_PSE_TOP_MDP_PG_INFO_MDP_SRC_CNT_MASK \ +0x0FFF0000 /* MDP_SRC_CNT[27..16] */ +#define WF_PSE_TOP_MDP_PG_INFO_MDP_SRC_CNT_SHFT 16 +#define WF_PSE_TOP_MDP_PG_INFO_MDP_RSV_CNT_ADDR WF_PSE_TOP_MDP_PG_INFO_ADDR +#define WF_PSE_TOP_MDP_PG_INFO_MDP_RSV_CNT_MASK \ + 0x00000FFF /* MDP_RSV_CNT[11..0] */ +#define WF_PSE_TOP_MDP_PG_INFO_MDP_RSV_CNT_SHFT 0 + +/* +* ---MDP1_PG_INFO (0x820C8000 + 0x178)--- +* MDP1_RSV_CNT[11..0] - (RO) Reserved pages of MDP 1 group +* RESERVED12[15..12] - (RO) Reserved bits +* MDP1_SRC_CNT[27..16] - (RO) Used pages of MDP 1 group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_MDP1_PG_INFO_MDP1_SRC_CNT_ADDR WF_PSE_TOP_MDP1_PG_INFO_ADDR +#define WF_PSE_TOP_MDP1_PG_INFO_MDP1_SRC_CNT_MASK \ +0x0FFF0000 /* MDP1_SRC_CNT[27..16] */ +#define WF_PSE_TOP_MDP1_PG_INFO_MDP1_SRC_CNT_SHFT 16 +#define WF_PSE_TOP_MDP1_PG_INFO_MDP1_RSV_CNT_ADDR WF_PSE_TOP_MDP1_PG_INFO_ADDR +#define WF_PSE_TOP_MDP1_PG_INFO_MDP1_RSV_CNT_MASK \ +0x00000FFF /* MDP1_RSV_CNT[11..0] */ +#define WF_PSE_TOP_MDP1_PG_INFO_MDP1_RSV_CNT_SHFT 0 + +/* +* ---MDP2_PG_INFO (0x820C8000 + 0x17C)--- +* MDP2_RSV_CNT[11..0] - (RO) Reserved pages of MDP 2 group +* RESERVED12[15..12] - (RO) Reserved bits +* MDP2_SRC_CNT[27..16] - (RO) Used pages of MDP 2 group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_MDP2_PG_INFO_MDP2_SRC_CNT_ADDR WF_PSE_TOP_MDP2_PG_INFO_ADDR +#define WF_PSE_TOP_MDP2_PG_INFO_MDP2_SRC_CNT_MASK \ +0x0FFF0000 /* MDP2_SRC_CNT[27..16] */ +#define WF_PSE_TOP_MDP2_PG_INFO_MDP2_SRC_CNT_SHFT 16 +#define WF_PSE_TOP_MDP2_PG_INFO_MDP2_RSV_CNT_ADDR WF_PSE_TOP_MDP2_PG_INFO_ADDR +#define WF_PSE_TOP_MDP2_PG_INFO_MDP2_RSV_CNT_MASK \ +0x00000FFF /* MDP2_RSV_CNT[11..0] */ +#define WF_PSE_TOP_MDP2_PG_INFO_MDP2_RSV_CNT_SHFT 0 + +/* +* ---HIF2_PG_INFO (0x820C8000 + 0x180)--- +* HIF2_RSV_CNT[11..0] - (RO) Reserved pages of HIF 2 group +* RESERVED12[15..12] - (RO) Reserved bits +* HIF2_SRC_CNT[27..16] - (RO) Used pages of HIF 2 group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_HIF2_PG_INFO_HIF2_SRC_CNT_ADDR WF_PSE_TOP_HIF2_PG_INFO_ADDR +#define WF_PSE_TOP_HIF2_PG_INFO_HIF2_SRC_CNT_MASK \ +0x0FFF0000 /* HIF2_SRC_CNT[27..16] */ +#define WF_PSE_TOP_HIF2_PG_INFO_HIF2_SRC_CNT_SHFT 16 +#define WF_PSE_TOP_HIF2_PG_INFO_HIF2_RSV_CNT_ADDR WF_PSE_TOP_HIF2_PG_INFO_ADDR +#define WF_PSE_TOP_HIF2_PG_INFO_HIF2_RSV_CNT_MASK \ +0x00000FFF /* HIF2_RSV_CNT[11..0] */ +#define WF_PSE_TOP_HIF2_PG_INFO_HIF2_RSV_CNT_SHFT 0 + +/* +* ---DTIM_CTRL (0x820C8000 + 0x190)--- +* DTIM_MODE[0] - (RW) DTIM mode +* RESERVED1[31..1] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_DTIM_CTRL_DTIM_MODE_ADDR WF_PSE_TOP_DTIM_CTRL_ADDR +#define WF_PSE_TOP_DTIM_CTRL_DTIM_MODE_MASK 0x00000001 /* DTIM_MODE[0] */ +#define WF_PSE_TOP_DTIM_CTRL_DTIM_MODE_SHFT 0 + +/* +* ---FREEPG_START_END_DTIM (0x820C8000 + 0x194)--- +* FREEPG_START_DTIM[11..0] - (RW) Start page setting of DTIM free pages +* RESERVED12[15..12] - (RO) Reserved bits +* FREEPG_END_DTIM[27..16] - (RW) End page setting of DTIM free page +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_FREEPG_START_END_DTIM_FREEPG_END_DTIM_ADDR \ +WF_PSE_TOP_FREEPG_START_END_DTIM_ADDR +#define WF_PSE_TOP_FREEPG_START_END_DTIM_FREEPG_END_DTIM_MASK \ +0x0FFF0000 /* FREEPG_END_DTIM[27..16] */ +#define WF_PSE_TOP_FREEPG_START_END_DTIM_FREEPG_END_DTIM_SHFT 16 +#define WF_PSE_TOP_FREEPG_START_END_DTIM_FREEPG_START_DTIM_ADDR \ +WF_PSE_TOP_FREEPG_START_END_DTIM_ADDR +#define WF_PSE_TOP_FREEPG_START_END_DTIM_FREEPG_START_DTIM_MASK \ +0x00000FFF /* FREEPG_START_DTIM[11..0] */ +#define WF_PSE_TOP_FREEPG_START_END_DTIM_FREEPG_START_DTIM_SHFT 0 + +/* +* ---PG_LMAC0_GROUP_DTIM (0x820C8000 + 0x198)--- +* LMAC0_MIN_QUOTA_DTIM[11..0] - (RW) Min. quota of LMAC 0 group in DTIM +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED12[15..12] - (RO) Reserved bits +* LMAC0_MAX_QUOTA_DTIM[27..16] - (RW) Max. quota of LMAC 0 group in DTIM +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PG_LMAC0_GROUP_DTIM_LMAC0_MAX_QUOTA_DTIM_ADDR \ +WF_PSE_TOP_PG_LMAC0_GROUP_DTIM_ADDR +#define WF_PSE_TOP_PG_LMAC0_GROUP_DTIM_LMAC0_MAX_QUOTA_DTIM_MASK \ +0x0FFF0000 /* LMAC0_MAX_QUOTA_DTIM[27..16] */ +#define WF_PSE_TOP_PG_LMAC0_GROUP_DTIM_LMAC0_MAX_QUOTA_DTIM_SHFT 16 +#define WF_PSE_TOP_PG_LMAC0_GROUP_DTIM_LMAC0_MIN_QUOTA_DTIM_ADDR \ +WF_PSE_TOP_PG_LMAC0_GROUP_DTIM_ADDR +#define WF_PSE_TOP_PG_LMAC0_GROUP_DTIM_LMAC0_MIN_QUOTA_DTIM_MASK \ +0x00000FFF /* LMAC0_MIN_QUOTA_DTIM[11..0] */ +#define WF_PSE_TOP_PG_LMAC0_GROUP_DTIM_LMAC0_MIN_QUOTA_DTIM_SHFT 0 + +/* +* ---PG_LMAC1_GROUP_DTIM (0x820C8000 + 0x19C)--- +* LMAC1_MIN_QUOTA_DTIM[11..0] - (RW) Min. quota of LMAC 1 group in DTIM +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED12[15..12] - (RO) Reserved bits +* LMAC1_MAX_QUOTA_DTIM[27..16] - (RW) Max. quota of LMAC 1 group in DTIM +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PG_LMAC1_GROUP_DTIM_LMAC1_MAX_QUOTA_DTIM_ADDR \ +WF_PSE_TOP_PG_LMAC1_GROUP_DTIM_ADDR +#define WF_PSE_TOP_PG_LMAC1_GROUP_DTIM_LMAC1_MAX_QUOTA_DTIM_MASK \ +0x0FFF0000 /* LMAC1_MAX_QUOTA_DTIM[27..16] */ +#define WF_PSE_TOP_PG_LMAC1_GROUP_DTIM_LMAC1_MAX_QUOTA_DTIM_SHFT 16 +#define WF_PSE_TOP_PG_LMAC1_GROUP_DTIM_LMAC1_MIN_QUOTA_DTIM_ADDR \ +WF_PSE_TOP_PG_LMAC1_GROUP_DTIM_ADDR +#define WF_PSE_TOP_PG_LMAC1_GROUP_DTIM_LMAC1_MIN_QUOTA_DTIM_MASK \ +0x00000FFF /* LMAC1_MIN_QUOTA_DTIM[11..0] */ +#define WF_PSE_TOP_PG_LMAC1_GROUP_DTIM_LMAC1_MIN_QUOTA_DTIM_SHFT 0 + +/* +* ---PG_MDP_GROUP_DTIM (0x820C8000 + 0x1A0)--- +* MDP_MIN_QUOTA_DTIM[11..0] - (RW) Min. quota of MDP group in DTIM +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED12[15..12] - (RO) Reserved bits +* MDP_MAX_QUOTA_DTIM[27..16] - (RW) Max. quota of MDP group in DTIM +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PG_MDP_GROUP_DTIM_MDP_MAX_QUOTA_DTIM_ADDR \ +WF_PSE_TOP_PG_MDP_GROUP_DTIM_ADDR +#define WF_PSE_TOP_PG_MDP_GROUP_DTIM_MDP_MAX_QUOTA_DTIM_MASK \ +0x0FFF0000 /* MDP_MAX_QUOTA_DTIM[27..16] */ +#define WF_PSE_TOP_PG_MDP_GROUP_DTIM_MDP_MAX_QUOTA_DTIM_SHFT 16 +#define WF_PSE_TOP_PG_MDP_GROUP_DTIM_MDP_MIN_QUOTA_DTIM_ADDR \ +WF_PSE_TOP_PG_MDP_GROUP_DTIM_ADDR +#define WF_PSE_TOP_PG_MDP_GROUP_DTIM_MDP_MIN_QUOTA_DTIM_MASK \ +0x00000FFF /* MDP_MIN_QUOTA_DTIM[11..0] */ +#define WF_PSE_TOP_PG_MDP_GROUP_DTIM_MDP_MIN_QUOTA_DTIM_SHFT 0 + +/* +* ---FL_QUE_CTRL_0 (0x820C8000 + 0x1B0)--- +* Q_BUF_WLANID[9..0] - (RW) Address of queue structure buffer +WLANID. +* Q_BUF_PID[11..10] - (RW) Address of queue structure buffer PID +* FL_BUFFER_ADDR[23..12] - (RW) Frame address of read previous +* frame/next frame +* Q_BUF_QID[30..24] - (RW) Address of queue structure buffer QID +* EXECUTE[31] - (A0) Executes frame link and queue structure +* buffer read command +*/ +#define WF_PSE_TOP_FL_QUE_CTRL_0_EXECUTE_ADDR WF_PSE_TOP_FL_QUE_CTRL_0_ADDR +#define WF_PSE_TOP_FL_QUE_CTRL_0_EXECUTE_MASK 0x80000000 /* EXECUTE[31] */ +#define WF_PSE_TOP_FL_QUE_CTRL_0_EXECUTE_SHFT 31 +#define WF_PSE_TOP_FL_QUE_CTRL_0_Q_BUF_QID_ADDR WF_PSE_TOP_FL_QUE_CTRL_0_ADDR +#define WF_PSE_TOP_FL_QUE_CTRL_0_Q_BUF_QID_MASK \ + 0x7F000000 /* Q_BUF_QID[30..24] */ +#define WF_PSE_TOP_FL_QUE_CTRL_0_Q_BUF_QID_SHFT 24 +#define WF_PSE_TOP_FL_QUE_CTRL_0_FL_BUFFER_ADDR_ADDR \ +WF_PSE_TOP_FL_QUE_CTRL_0_ADDR +#define WF_PSE_TOP_FL_QUE_CTRL_0_FL_BUFFER_ADDR_MASK \ +0x00FFF000 /* FL_BUFFER_ADDR[23..12] */ +#define WF_PSE_TOP_FL_QUE_CTRL_0_FL_BUFFER_ADDR_SHFT 12 +#define WF_PSE_TOP_FL_QUE_CTRL_0_Q_BUF_PID_ADDR WF_PSE_TOP_FL_QUE_CTRL_0_ADDR +#define WF_PSE_TOP_FL_QUE_CTRL_0_Q_BUF_PID_MASK \ + 0x00000C00 /* Q_BUF_PID[11..10] */ +#define WF_PSE_TOP_FL_QUE_CTRL_0_Q_BUF_PID_SHFT 10 +#define WF_PSE_TOP_FL_QUE_CTRL_0_Q_BUF_WLANID_ADDR WF_PSE_TOP_FL_QUE_CTRL_0_ADDR +#define WF_PSE_TOP_FL_QUE_CTRL_0_Q_BUF_WLANID_MASK \ +0x000003FF /* Q_BUF_WLANID[9..0] */ +#define WF_PSE_TOP_FL_QUE_CTRL_0_Q_BUF_WLANID_SHFT 0 + +/* +* ---FL_QUE_CTRL_1 (0x820C8000 + 0x1B4)--- +* NEXT_FID[11..0] - (RO) Next frame ID of FL_BUFFER_ADDR +* RESERVED12[15..12] - (RO) Reserved bits +* PREV_FID[27..16] - (RO) Previous frame ID of FL_BUFFER_ADDR +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_FL_QUE_CTRL_1_PREV_FID_ADDR WF_PSE_TOP_FL_QUE_CTRL_1_ADDR +#define WF_PSE_TOP_FL_QUE_CTRL_1_PREV_FID_MASK 0x0FFF0000 /* PREV_FID[27..16] */ +#define WF_PSE_TOP_FL_QUE_CTRL_1_PREV_FID_SHFT 16 +#define WF_PSE_TOP_FL_QUE_CTRL_1_NEXT_FID_ADDR WF_PSE_TOP_FL_QUE_CTRL_1_ADDR +#define WF_PSE_TOP_FL_QUE_CTRL_1_NEXT_FID_MASK 0x00000FFF /* NEXT_FID[11..0] */ +#define WF_PSE_TOP_FL_QUE_CTRL_1_NEXT_FID_SHFT 0 + +/* +* ---FL_QUE_CTRL_2 (0x820C8000 + 0x1B8)--- +* QUEUE_HEAD_FID[11..0] - (RO) Head frame ID of quest queue setting in +0x01b0[15:0] +* RESERVED12[15..12] - (RO) Reserved bits +* QUEUE_TAIL_FID[27..16] - (RO) Tail frame ID of quest queue setting in +0x01b0[15:0] +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_FL_QUE_CTRL_2_QUEUE_TAIL_FID_ADDR \ +WF_PSE_TOP_FL_QUE_CTRL_2_ADDR +#define WF_PSE_TOP_FL_QUE_CTRL_2_QUEUE_TAIL_FID_MASK \ +0x0FFF0000 /* QUEUE_TAIL_FID[27..16] */ +#define WF_PSE_TOP_FL_QUE_CTRL_2_QUEUE_TAIL_FID_SHFT 16 +#define WF_PSE_TOP_FL_QUE_CTRL_2_QUEUE_HEAD_FID_ADDR \ +WF_PSE_TOP_FL_QUE_CTRL_2_ADDR +#define WF_PSE_TOP_FL_QUE_CTRL_2_QUEUE_HEAD_FID_MASK \ +0x00000FFF /* QUEUE_HEAD_FID[11..0] */ +#define WF_PSE_TOP_FL_QUE_CTRL_2_QUEUE_HEAD_FID_SHFT 0 + +/* +* ---FL_QUE_CTRL_3 (0x820C8000 + 0x1BC)--- +* QUEUE_PKT_NUM[11..0] - (RO) Total packet number of queue setting in +0x1b0[15:0] +* QUEUE_PAGE_NUM[23..12] - (RO) Total page number of queue setting in +0x1b0[15:0] +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_FL_QUE_CTRL_3_QUEUE_PAGE_NUM_ADDR \ +WF_PSE_TOP_FL_QUE_CTRL_3_ADDR +#define WF_PSE_TOP_FL_QUE_CTRL_3_QUEUE_PAGE_NUM_MASK \ +0x00FFF000 /* QUEUE_PAGE_NUM[23..12] */ +#define WF_PSE_TOP_FL_QUE_CTRL_3_QUEUE_PAGE_NUM_SHFT 12 +#define WF_PSE_TOP_FL_QUE_CTRL_3_QUEUE_PKT_NUM_ADDR \ +WF_PSE_TOP_FL_QUE_CTRL_3_ADDR +#define WF_PSE_TOP_FL_QUE_CTRL_3_QUEUE_PKT_NUM_MASK \ +0x00000FFF /* QUEUE_PKT_NUM[11..0] */ +#define WF_PSE_TOP_FL_QUE_CTRL_3_QUEUE_PKT_NUM_SHFT 0 + +/* +* ---PL_QUE_CTRL_0 (0x820C8000 + 0x1C0)--- +* NEXT_PAGE[11..0] - (RO) Next page of the PL_BUFFER_ADDR +* RESERVED12[15..12] - (RO) Reserved bits +* PL_BUFFER_ADDR[27..16] - (RW) Page address of read next page +* RESERVED28[30..28] - (RO) Reserved bits +* EXECUTE[31] - (A0) Executes page link buffer read command +*/ +#define WF_PSE_TOP_PL_QUE_CTRL_0_EXECUTE_ADDR WF_PSE_TOP_PL_QUE_CTRL_0_ADDR +#define WF_PSE_TOP_PL_QUE_CTRL_0_EXECUTE_MASK 0x80000000 /* EXECUTE[31] */ +#define WF_PSE_TOP_PL_QUE_CTRL_0_EXECUTE_SHFT 31 +#define WF_PSE_TOP_PL_QUE_CTRL_0_PL_BUFFER_ADDR_ADDR \ +WF_PSE_TOP_PL_QUE_CTRL_0_ADDR +#define WF_PSE_TOP_PL_QUE_CTRL_0_PL_BUFFER_ADDR_MASK \ +0x0FFF0000 /* PL_BUFFER_ADDR[27..16] */ +#define WF_PSE_TOP_PL_QUE_CTRL_0_PL_BUFFER_ADDR_SHFT 16 +#define WF_PSE_TOP_PL_QUE_CTRL_0_NEXT_PAGE_ADDR WF_PSE_TOP_PL_QUE_CTRL_0_ADDR +#define WF_PSE_TOP_PL_QUE_CTRL_0_NEXT_PAGE_MASK \ + 0x00000FFF /* NEXT_PAGE[11..0] */ +#define WF_PSE_TOP_PL_QUE_CTRL_0_NEXT_PAGE_SHFT 0 + +/* +* ---PSE_CT_PRI_CTRL (0x820C8000 + 0x1EC)--- +* PSE_CT_PRI_LOW_LV[11..0] - (RW) Low trigger level of Group0 qouta +* RESERVED12[15..12] - (RO) Reserved bits +* PSE_CT_PRI_HI_LV[27..16] - (RW) High trigger level of Group0 qouta +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_CT_PRI_CTRL_PSE_CT_PRI_HI_LV_ADDR \ +WF_PSE_TOP_PSE_CT_PRI_CTRL_ADDR +#define WF_PSE_TOP_PSE_CT_PRI_CTRL_PSE_CT_PRI_HI_LV_MASK \ +0x0FFF0000 /* PSE_CT_PRI_HI_LV[27..16] */ +#define WF_PSE_TOP_PSE_CT_PRI_CTRL_PSE_CT_PRI_HI_LV_SHFT 16 +#define WF_PSE_TOP_PSE_CT_PRI_CTRL_PSE_CT_PRI_LOW_LV_ADDR \ +WF_PSE_TOP_PSE_CT_PRI_CTRL_ADDR +#define WF_PSE_TOP_PSE_CT_PRI_CTRL_PSE_CT_PRI_LOW_LV_MASK \ +0x00000FFF /* PSE_CT_PRI_LOW_LV[11..0] */ +#define WF_PSE_TOP_PSE_CT_PRI_CTRL_PSE_CT_PRI_LOW_LV_SHFT 0 + +/* +* ---PLE_ENQ_PKT_NUM (0x820C8000 + 0x1F0)--- +* PLE_ENQ_HIF_Q_PKT_NUM[15..0] - (RO) The packets numbers of PLE port enqueue +* to HIF queue. +* PLE_ENQ_HIF_Q_SEL[19..16] - (RW) Select HIF queue which is PLE port +* enqueue to. +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PLE_ENQ_PKT_NUM_PLE_ENQ_HIF_Q_SEL_ADDR \ +WF_PSE_TOP_PLE_ENQ_PKT_NUM_ADDR +#define WF_PSE_TOP_PLE_ENQ_PKT_NUM_PLE_ENQ_HIF_Q_SEL_MASK \ +0x000F0000 /* PLE_ENQ_HIF_Q_SEL[19..16] */ +#define WF_PSE_TOP_PLE_ENQ_PKT_NUM_PLE_ENQ_HIF_Q_SEL_SHFT 16 +#define WF_PSE_TOP_PLE_ENQ_PKT_NUM_PLE_ENQ_HIF_Q_PKT_NUM_ADDR \ +WF_PSE_TOP_PLE_ENQ_PKT_NUM_ADDR +#define WF_PSE_TOP_PLE_ENQ_PKT_NUM_PLE_ENQ_HIF_Q_PKT_NUM_MASK \ +0x0000FFFF /* PLE_ENQ_HIF_Q_PKT_NUM[15..0] */ +#define WF_PSE_TOP_PLE_ENQ_PKT_NUM_PLE_ENQ_HIF_Q_PKT_NUM_SHFT 0 + +/* +* ---CPU_ENQ_PKT_NUM (0x820C8000 + 0x1F4)--- +* CPU_ENQ_HIF_Q_PKT_NUM[15..0] - (RO) The packets numbers of CPU port enqueue +* to HIF queue. +* CPU_ENQ_HIF_Q_SEL[19..16] - (RW) Select HIF queue which is CPU port +* enqueue to. +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_CPU_ENQ_PKT_NUM_CPU_ENQ_HIF_Q_SEL_ADDR \ +WF_PSE_TOP_CPU_ENQ_PKT_NUM_ADDR +#define WF_PSE_TOP_CPU_ENQ_PKT_NUM_CPU_ENQ_HIF_Q_SEL_MASK \ +0x000F0000 /* CPU_ENQ_HIF_Q_SEL[19..16] */ +#define WF_PSE_TOP_CPU_ENQ_PKT_NUM_CPU_ENQ_HIF_Q_SEL_SHFT 16 +#define WF_PSE_TOP_CPU_ENQ_PKT_NUM_CPU_ENQ_HIF_Q_PKT_NUM_ADDR \ +WF_PSE_TOP_CPU_ENQ_PKT_NUM_ADDR +#define WF_PSE_TOP_CPU_ENQ_PKT_NUM_CPU_ENQ_HIF_Q_PKT_NUM_MASK \ +0x0000FFFF /* CPU_ENQ_HIF_Q_PKT_NUM[15..0] */ +#define WF_PSE_TOP_CPU_ENQ_PKT_NUM_CPU_ENQ_HIF_Q_PKT_NUM_SHFT 0 + +/* +* ---LMAC_ENQ_PKT_NUM (0x820C8000 + 0x1F8)--- +* LMAC_ENQ_HIF_Q_PKT_NUM[15..0] - (RO) The packets numbers of LMAC port +* enqueue to HIF queue. +* LMAC_ENQ_HIF_Q_SEL[19..16] - (RW) Select HIF queue which is LMAC port +* enqueue to. +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_LMAC_ENQ_PKT_NUM_LMAC_ENQ_HIF_Q_SEL_ADDR \ +WF_PSE_TOP_LMAC_ENQ_PKT_NUM_ADDR +#define WF_PSE_TOP_LMAC_ENQ_PKT_NUM_LMAC_ENQ_HIF_Q_SEL_MASK \ +0x000F0000 /* LMAC_ENQ_HIF_Q_SEL[19..16] */ +#define WF_PSE_TOP_LMAC_ENQ_PKT_NUM_LMAC_ENQ_HIF_Q_SEL_SHFT 16 +#define WF_PSE_TOP_LMAC_ENQ_PKT_NUM_LMAC_ENQ_HIF_Q_PKT_NUM_ADDR \ +WF_PSE_TOP_LMAC_ENQ_PKT_NUM_ADDR +#define WF_PSE_TOP_LMAC_ENQ_PKT_NUM_LMAC_ENQ_HIF_Q_PKT_NUM_MASK \ +0x0000FFFF /* LMAC_ENQ_HIF_Q_PKT_NUM[15..0] */ +#define WF_PSE_TOP_LMAC_ENQ_PKT_NUM_LMAC_ENQ_HIF_Q_PKT_NUM_SHFT 0 + +/* +* ---HIF_ENQ_PKT_NUM (0x820C8000 + 0x1FC)--- +* HIF_ENQ_MDP[15..0] - (RO) The packets numbers of HIF port enqueue +* to MDP TX queue. +* HIF_ENQ_CPU[31..16] - (RO) The packets numbers of HIF port enqueue +* to CPU queue +*/ +#define WF_PSE_TOP_HIF_ENQ_PKT_NUM_HIF_ENQ_CPU_ADDR \ +WF_PSE_TOP_HIF_ENQ_PKT_NUM_ADDR +#define WF_PSE_TOP_HIF_ENQ_PKT_NUM_HIF_ENQ_CPU_MASK \ +0xFFFF0000 /* HIF_ENQ_CPU[31..16] */ +#define WF_PSE_TOP_HIF_ENQ_PKT_NUM_HIF_ENQ_CPU_SHFT 16 +#define WF_PSE_TOP_HIF_ENQ_PKT_NUM_HIF_ENQ_MDP_ADDR \ +WF_PSE_TOP_HIF_ENQ_PKT_NUM_ADDR +#define WF_PSE_TOP_HIF_ENQ_PKT_NUM_HIF_ENQ_MDP_MASK \ +0x0000FFFF /* HIF_ENQ_MDP[15..0] */ +#define WF_PSE_TOP_HIF_ENQ_PKT_NUM_HIF_ENQ_MDP_SHFT 0 + +/* +* ---MDP_ENQ_PKT_NUM (0x820C8000 + 0x200)--- +* MDP_ENQ_HIF_Q_PKT_NUM[15..0] - (RO) The packets numbers of MDP port enqueue +* to HIF queue. +* MDP_ENQ_HIF_Q_SEL[31..16] - (RW) Select HIF queue which is MDP port +* enqueue to. +*/ +#define WF_PSE_TOP_MDP_ENQ_PKT_NUM_MDP_ENQ_HIF_Q_SEL_ADDR \ +WF_PSE_TOP_MDP_ENQ_PKT_NUM_ADDR +#define WF_PSE_TOP_MDP_ENQ_PKT_NUM_MDP_ENQ_HIF_Q_SEL_MASK \ +0xFFFF0000 /* MDP_ENQ_HIF_Q_SEL[31..16] */ +#define WF_PSE_TOP_MDP_ENQ_PKT_NUM_MDP_ENQ_HIF_Q_SEL_SHFT 16 +#define WF_PSE_TOP_MDP_ENQ_PKT_NUM_MDP_ENQ_HIF_Q_PKT_NUM_ADDR \ +WF_PSE_TOP_MDP_ENQ_PKT_NUM_ADDR +#define WF_PSE_TOP_MDP_ENQ_PKT_NUM_MDP_ENQ_HIF_Q_PKT_NUM_MASK \ +0x0000FFFF /* MDP_ENQ_HIF_Q_PKT_NUM[15..0] */ +#define WF_PSE_TOP_MDP_ENQ_PKT_NUM_MDP_ENQ_HIF_Q_PKT_NUM_SHFT 0 + +/* +* ---RL_BUF_CTRL_0 (0x820C8000 + 0x210)--- +* RELAY_BUF_ADDR[11..0] - (RW) Read address of relay buffer +* RESERVED12[30..12] - (RO) Reserved bits +* EXECUTE[31] - (A0) Executes relay buffer read command +*/ +#define WF_PSE_TOP_RL_BUF_CTRL_0_EXECUTE_ADDR WF_PSE_TOP_RL_BUF_CTRL_0_ADDR +#define WF_PSE_TOP_RL_BUF_CTRL_0_EXECUTE_MASK 0x80000000 /* EXECUTE[31] */ +#define WF_PSE_TOP_RL_BUF_CTRL_0_EXECUTE_SHFT 31 +#define WF_PSE_TOP_RL_BUF_CTRL_0_RELAY_BUF_ADDR_ADDR \ +WF_PSE_TOP_RL_BUF_CTRL_0_ADDR +#define WF_PSE_TOP_RL_BUF_CTRL_0_RELAY_BUF_ADDR_MASK \ +0x00000FFF /* RELAY_BUF_ADDR[11..0] */ +#define WF_PSE_TOP_RL_BUF_CTRL_0_RELAY_BUF_ADDR_SHFT 0 + +/* +* ---RL_BUF_CTRL_1 (0x820C8000 + 0x214)--- +* PAGE_NUM[8..0] - (RO) Page number of packet +* RESERVED9[13..9] - (RO) Reserved bits +* PKT_TAIL_PAGE[25..14] - (RO) Tail page of the packet with head page +* being the relay buffer address +* RESERVED26[26] - (RO) Reserved bits +* RESV_GRP_ID[30..27] - (RO) Group ID of reserved page used by FID +* RESERVED31[31] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_RL_BUF_CTRL_1_RESV_GRP_ID_ADDR WF_PSE_TOP_RL_BUF_CTRL_1_ADDR +#define WF_PSE_TOP_RL_BUF_CTRL_1_RESV_GRP_ID_MASK \ +0x78000000 /* RESV_GRP_ID[30..27] */ +#define WF_PSE_TOP_RL_BUF_CTRL_1_RESV_GRP_ID_SHFT 27 +#define WF_PSE_TOP_RL_BUF_CTRL_1_PKT_TAIL_PAGE_ADDR \ +WF_PSE_TOP_RL_BUF_CTRL_1_ADDR +#define WF_PSE_TOP_RL_BUF_CTRL_1_PKT_TAIL_PAGE_MASK \ +0x03FFC000 /* PKT_TAIL_PAGE[25..14] */ +#define WF_PSE_TOP_RL_BUF_CTRL_1_PKT_TAIL_PAGE_SHFT 14 +#define WF_PSE_TOP_RL_BUF_CTRL_1_PAGE_NUM_ADDR WF_PSE_TOP_RL_BUF_CTRL_1_ADDR +#define WF_PSE_TOP_RL_BUF_CTRL_1_PAGE_NUM_MASK 0x000001FF /* PAGE_NUM[8..0] */ +#define WF_PSE_TOP_RL_BUF_CTRL_1_PAGE_NUM_SHFT 0 + +/* +* ---TIMEOUT_CTRL (0x820C8000 + 0x244)--- +* FL_WD_TO_CTRL[7..0] - (RW) FL watch dog timeput +* RESERVED8[15..8] - (RO) Reserved bits +* APB_WD_TO_CTRL[23..16] - (RW) APB pready watch dog timeout control +register. +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_TIMEOUT_CTRL_APB_WD_TO_CTRL_ADDR WF_PSE_TOP_TIMEOUT_CTRL_ADDR +#define WF_PSE_TOP_TIMEOUT_CTRL_APB_WD_TO_CTRL_MASK \ +0x00FF0000 /* APB_WD_TO_CTRL[23..16] */ +#define WF_PSE_TOP_TIMEOUT_CTRL_APB_WD_TO_CTRL_SHFT 16 +#define WF_PSE_TOP_TIMEOUT_CTRL_FL_WD_TO_CTRL_ADDR WF_PSE_TOP_TIMEOUT_CTRL_ADDR +#define WF_PSE_TOP_TIMEOUT_CTRL_FL_WD_TO_CTRL_MASK \ +0x000000FF /* FL_WD_TO_CTRL[7..0] */ +#define WF_PSE_TOP_TIMEOUT_CTRL_FL_WD_TO_CTRL_SHFT 0 + +/* +* ---FSM_IDLE_WD_CTRL (0x820C8000 + 0x248)--- +* FL_IDLE_WD_TO_TH[7..0] - (RW) Watchdog timeout threshold for frame +* link FSM not returning to IDLE +* PL_IDLE_WD_TO_TH[15..8] - (RW) Watchdog timeout threshold for page link +* FSM not returning to IDLE +* PORT_IDLE_WD_TO_TH[23..16] - (RW) Watchdog timeout threshold for page link +* Port Link not returning to IDLE +* (Including HIF/CPU/LMAC port) +* MACTX_IDLE_WD_TO_TH[31..24] - (RW) Watchdog timeout threshold for port oper +* MACTX not returning to IDLE +*/ +#define WF_PSE_TOP_FSM_IDLE_WD_CTRL_MACTX_IDLE_WD_TO_TH_ADDR \ +WF_PSE_TOP_FSM_IDLE_WD_CTRL_ADDR +#define WF_PSE_TOP_FSM_IDLE_WD_CTRL_MACTX_IDLE_WD_TO_TH_MASK \ +0xFF000000 /* MACTX_IDLE_WD_TO_TH[31..24] */ +#define WF_PSE_TOP_FSM_IDLE_WD_CTRL_MACTX_IDLE_WD_TO_TH_SHFT 24 +#define WF_PSE_TOP_FSM_IDLE_WD_CTRL_PORT_IDLE_WD_TO_TH_ADDR \ +WF_PSE_TOP_FSM_IDLE_WD_CTRL_ADDR +#define WF_PSE_TOP_FSM_IDLE_WD_CTRL_PORT_IDLE_WD_TO_TH_MASK \ +0x00FF0000 /* PORT_IDLE_WD_TO_TH[23..16] */ +#define WF_PSE_TOP_FSM_IDLE_WD_CTRL_PORT_IDLE_WD_TO_TH_SHFT 16 +#define WF_PSE_TOP_FSM_IDLE_WD_CTRL_PL_IDLE_WD_TO_TH_ADDR \ +WF_PSE_TOP_FSM_IDLE_WD_CTRL_ADDR +#define WF_PSE_TOP_FSM_IDLE_WD_CTRL_PL_IDLE_WD_TO_TH_MASK \ +0x0000FF00 /* PL_IDLE_WD_TO_TH[15..8] */ +#define WF_PSE_TOP_FSM_IDLE_WD_CTRL_PL_IDLE_WD_TO_TH_SHFT 8 +#define WF_PSE_TOP_FSM_IDLE_WD_CTRL_FL_IDLE_WD_TO_TH_ADDR \ +WF_PSE_TOP_FSM_IDLE_WD_CTRL_ADDR +#define WF_PSE_TOP_FSM_IDLE_WD_CTRL_FL_IDLE_WD_TO_TH_MASK \ +0x000000FF /* FL_IDLE_WD_TO_TH[7..0] */ +#define WF_PSE_TOP_FSM_IDLE_WD_CTRL_FL_IDLE_WD_TO_TH_SHFT 0 + +/* +* ---FSM_IDLE_WD_EN (0x820C8000 + 0x24C)--- +* EN_HIF_PORT_IDLE_WD_TO[0] - (RW) Enables watchdog for HIF port oper FSM +* not returning to IDLE +* EN_CPU_PORT_IDLE_WD_TO[1] - (RW) Enables watchdog for CPU port oper FSM +* not returning to IDLE +* EN_LMAC_PORT_IDLE_WD_TO[2] - (RW) Enables watchdog for LMAC port oper FSM +* not returning to IDLE +* EN_MDP_IDLE_WD_TO[3] - (RW) Enables watchdog for MDP port oper FSM +* not returning to IDLE +* EN_SEC_IDLE_WD_TO[4] - (RW) Enables watchdog for SEC port oper FSM +* not returning to IDLE +* EN_PLE_IDLE_WD_TO[5] - (RW) Enables watchdog for PLE port oper FSM +* not returning to IDLE +* EN_AMSDU_IDLE_WD_TO[6] - (RW) Enables watchdog for AMSDU port oper FSM +* not returning to IDLE +* RESERVED7[7] - (RO) Reserved bits +* EN_FL_IDLE_WD_TO[8] - (RW) Enables watchdog for frame link FSM not +* returning to IDLE +* EN_PL_IDLE_WD_TO[9] - (RW) Enables watchdog for page link FSM not +* returning to IDLE +* RESERVED10[31..10] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_PL_IDLE_WD_TO_ADDR \ +WF_PSE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_PL_IDLE_WD_TO_MASK \ +0x00000200 /* EN_PL_IDLE_WD_TO[9] */ +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_PL_IDLE_WD_TO_SHFT 9 +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_FL_IDLE_WD_TO_ADDR \ +WF_PSE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_FL_IDLE_WD_TO_MASK \ +0x00000100 /* EN_FL_IDLE_WD_TO[8] */ +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_FL_IDLE_WD_TO_SHFT 8 +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_AMSDU_IDLE_WD_TO_ADDR \ +WF_PSE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_AMSDU_IDLE_WD_TO_MASK \ +0x00000040 /* EN_AMSDU_IDLE_WD_TO[6] */ +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_AMSDU_IDLE_WD_TO_SHFT 6 +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_PLE_IDLE_WD_TO_ADDR \ +WF_PSE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_PLE_IDLE_WD_TO_MASK \ +0x00000020 /* EN_PLE_IDLE_WD_TO[5] */ +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_PLE_IDLE_WD_TO_SHFT 5 +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_SEC_IDLE_WD_TO_ADDR \ +WF_PSE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_SEC_IDLE_WD_TO_MASK \ +0x00000010 /* EN_SEC_IDLE_WD_TO[4] */ +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_SEC_IDLE_WD_TO_SHFT 4 +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_MDP_IDLE_WD_TO_ADDR \ +WF_PSE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_MDP_IDLE_WD_TO_MASK \ +0x00000008 /* EN_MDP_IDLE_WD_TO[3] */ +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_MDP_IDLE_WD_TO_SHFT 3 +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_LMAC_PORT_IDLE_WD_TO_ADDR \ +WF_PSE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_LMAC_PORT_IDLE_WD_TO_MASK \ +0x00000004 /* EN_LMAC_PORT_IDLE_WD_TO[2] */ +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_LMAC_PORT_IDLE_WD_TO_SHFT 2 +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_CPU_PORT_IDLE_WD_TO_ADDR \ +WF_PSE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_CPU_PORT_IDLE_WD_TO_MASK \ +0x00000002 /* EN_CPU_PORT_IDLE_WD_TO[1] */ +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_CPU_PORT_IDLE_WD_TO_SHFT 1 +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_HIF_PORT_IDLE_WD_TO_ADDR \ +WF_PSE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_HIF_PORT_IDLE_WD_TO_MASK \ +0x00000001 /* EN_HIF_PORT_IDLE_WD_TO[0] */ +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_HIF_PORT_IDLE_WD_TO_SHFT 0 + +/* +* ---PSE_WFDMA_BUF_CTRL (0x820C8000 + 0x250)--- +* WFDMA_TXS_BUF_VLD_TH[7..0] - (RW) TXS valid reserved page count threshold +* WFDMA_TXCMD_BUF_VLD_TH[15..8] - (RW) TXCMD valid reserved page count +threshold +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_WFDMA_BUF_CTRL_WFDMA_TXCMD_BUF_VLD_TH_ADDR \ +WF_PSE_TOP_PSE_WFDMA_BUF_CTRL_ADDR +#define WF_PSE_TOP_PSE_WFDMA_BUF_CTRL_WFDMA_TXCMD_BUF_VLD_TH_MASK \ +0x0000FF00 /* WFDMA_TXCMD_BUF_VLD_TH[15..8] */ +#define WF_PSE_TOP_PSE_WFDMA_BUF_CTRL_WFDMA_TXCMD_BUF_VLD_TH_SHFT 8 +#define WF_PSE_TOP_PSE_WFDMA_BUF_CTRL_WFDMA_TXS_BUF_VLD_TH_ADDR \ +WF_PSE_TOP_PSE_WFDMA_BUF_CTRL_ADDR +#define WF_PSE_TOP_PSE_WFDMA_BUF_CTRL_WFDMA_TXS_BUF_VLD_TH_MASK \ +0x000000FF /* WFDMA_TXS_BUF_VLD_TH[7..0] */ +#define WF_PSE_TOP_PSE_WFDMA_BUF_CTRL_WFDMA_TXS_BUF_VLD_TH_SHFT 0 + +/* +* ---PSE_MODULE_CKG_DIS (0x820C8000 + 0x254)--- +* DIS_FL_DYN_CKG[0] - (RW) Disable control of PSE frame link module +* dynamic clock gating function +* DIS_PL_DYN_CKG[1] - (RW) Disable control of PSE page link module +* dynamic clock gating function +* DIS_CPU_PORT_DYN_CKG[2] - (RW) Disable control of PSE CPU port module +* dynamic clock gating function +* DIS_HIF_PORT_DYN_CKG[3] - (RW) Disable control of PSE HIF port module +* dynamic clock gating function +* DIS_WF_PLE_PORT_DYN_CKG[4] - (RW) Disable control of PSE LMAC and PLE port +* module dynamic clock gating function +* DIS_RLS_DYN_CKG[5] - (RW) Disable control of PSE release module +* dynamic clock gating function +* DIS_RL_DYN_CKG[6] - (RW) Disable control of PSE relay information +* module dynamic clock gating function +* RESERVED7[8..7] - (RO) Reserved bits +* DIS_CSR_DYN_CKG[9] - (RW) Disable control of PSE CR module dynamic +* clock gating function +* DIS_CPU_WRAP_DYN_CKG[10] - (RW) Disable control of PSE CPU_WRAP module +* dynamic clock gating function +* DIS_DBG_DYN_CKG[11] - (RW) Disable control of PSE debug module +* dynamic clock gating function +* DIS_MDP_DYN_CKG[12] - (RW) Disable control of PSE MDP module +* dynamic clock gating function +* DIS_SEC_DYN_CKG[13] - (RW) Disable control of PSE SEC module +* dynamic clock gating function +* RESERVED14[31..14] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_SEC_DYN_CKG_ADDR \ +WF_PSE_TOP_PSE_MODULE_CKG_DIS_ADDR +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_SEC_DYN_CKG_MASK \ +0x00002000 /* DIS_SEC_DYN_CKG[13] */ +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_SEC_DYN_CKG_SHFT 13 +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_MDP_DYN_CKG_ADDR \ +WF_PSE_TOP_PSE_MODULE_CKG_DIS_ADDR +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_MDP_DYN_CKG_MASK \ +0x00001000 /* DIS_MDP_DYN_CKG[12] */ +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_MDP_DYN_CKG_SHFT 12 +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_DBG_DYN_CKG_ADDR \ +WF_PSE_TOP_PSE_MODULE_CKG_DIS_ADDR +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_DBG_DYN_CKG_MASK \ +0x00000800 /* DIS_DBG_DYN_CKG[11] */ +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_DBG_DYN_CKG_SHFT 11 +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_CPU_WRAP_DYN_CKG_ADDR \ +WF_PSE_TOP_PSE_MODULE_CKG_DIS_ADDR +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_CPU_WRAP_DYN_CKG_MASK \ +0x00000400 /* DIS_CPU_WRAP_DYN_CKG[10] */ +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_CPU_WRAP_DYN_CKG_SHFT 10 +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_CSR_DYN_CKG_ADDR \ +WF_PSE_TOP_PSE_MODULE_CKG_DIS_ADDR +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_CSR_DYN_CKG_MASK \ +0x00000200 /* DIS_CSR_DYN_CKG[9] */ +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_CSR_DYN_CKG_SHFT 9 +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_RL_DYN_CKG_ADDR \ +WF_PSE_TOP_PSE_MODULE_CKG_DIS_ADDR +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_RL_DYN_CKG_MASK \ +0x00000040 /* DIS_RL_DYN_CKG[6] */ +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_RL_DYN_CKG_SHFT 6 +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_RLS_DYN_CKG_ADDR \ +WF_PSE_TOP_PSE_MODULE_CKG_DIS_ADDR +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_RLS_DYN_CKG_MASK \ +0x00000020 /* DIS_RLS_DYN_CKG[5] */ +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_RLS_DYN_CKG_SHFT 5 +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_WF_PLE_PORT_DYN_CKG_ADDR \ +WF_PSE_TOP_PSE_MODULE_CKG_DIS_ADDR +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_WF_PLE_PORT_DYN_CKG_MASK \ +0x00000010 /* DIS_WF_PLE_PORT_DYN_CKG[4] */ +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_WF_PLE_PORT_DYN_CKG_SHFT 4 +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_HIF_PORT_DYN_CKG_ADDR \ +WF_PSE_TOP_PSE_MODULE_CKG_DIS_ADDR +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_HIF_PORT_DYN_CKG_MASK \ +0x00000008 /* DIS_HIF_PORT_DYN_CKG[3] */ +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_HIF_PORT_DYN_CKG_SHFT 3 +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_CPU_PORT_DYN_CKG_ADDR \ +WF_PSE_TOP_PSE_MODULE_CKG_DIS_ADDR +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_CPU_PORT_DYN_CKG_MASK \ +0x00000004 /* DIS_CPU_PORT_DYN_CKG[2] */ +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_CPU_PORT_DYN_CKG_SHFT 2 +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_PL_DYN_CKG_ADDR \ +WF_PSE_TOP_PSE_MODULE_CKG_DIS_ADDR +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_PL_DYN_CKG_MASK \ +0x00000002 /* DIS_PL_DYN_CKG[1] */ +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_PL_DYN_CKG_SHFT 1 +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_FL_DYN_CKG_ADDR \ +WF_PSE_TOP_PSE_MODULE_CKG_DIS_ADDR +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_FL_DYN_CKG_MASK \ +0x00000001 /* DIS_FL_DYN_CKG[0] */ +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_FL_DYN_CKG_SHFT 0 + +/* +* ---PSE_MISC_FUNC_CTRL (0x820C8000 + 0x258)--- +* RESERVED0[7..0] - (RO) Reserved bits +* PSE_QUEUE_ACK_MODE[8] - (RW) Queue ACK mode control +* RESERVED9[29..9] - (RO) Reserved bits +* DIS_BYPASS_INVALID_FID[30] - (RW) Bypass invalid FID control +* DIS_BLOCK_MODE[31] - (RW) Block Mode Control +*/ +#define WF_PSE_TOP_PSE_MISC_FUNC_CTRL_DIS_BLOCK_MODE_ADDR \ +WF_PSE_TOP_PSE_MISC_FUNC_CTRL_ADDR +#define WF_PSE_TOP_PSE_MISC_FUNC_CTRL_DIS_BLOCK_MODE_MASK \ +0x80000000 /* DIS_BLOCK_MODE[31] */ +#define WF_PSE_TOP_PSE_MISC_FUNC_CTRL_DIS_BLOCK_MODE_SHFT 31 +#define WF_PSE_TOP_PSE_MISC_FUNC_CTRL_DIS_BYPASS_INVALID_FID_ADDR \ +WF_PSE_TOP_PSE_MISC_FUNC_CTRL_ADDR +#define WF_PSE_TOP_PSE_MISC_FUNC_CTRL_DIS_BYPASS_INVALID_FID_MASK \ +0x40000000 /* DIS_BYPASS_INVALID_FID[30] */ +#define WF_PSE_TOP_PSE_MISC_FUNC_CTRL_DIS_BYPASS_INVALID_FID_SHFT 30 +#define WF_PSE_TOP_PSE_MISC_FUNC_CTRL_PSE_QUEUE_ACK_MODE_ADDR \ +WF_PSE_TOP_PSE_MISC_FUNC_CTRL_ADDR +#define WF_PSE_TOP_PSE_MISC_FUNC_CTRL_PSE_QUEUE_ACK_MODE_MASK \ +0x00000100 /* PSE_QUEUE_ACK_MODE[8] */ +#define WF_PSE_TOP_PSE_MISC_FUNC_CTRL_PSE_QUEUE_ACK_MODE_SHFT 8 + +/* +* ---PSE_INTER_ERR_FLAG (0x820C8000 + 0x280)--- +* DEQ_EMPTY_QUEUE[0] - (RO) DEQueue Empty Error Flag +* APB_WD_TO[1] - (RO) APB Write Data Timeout Error Flag +* FL_CTRL_WD_TO[2] - (RO) FL Write Data Timeout Error Flag +* RESERVED3[31..3] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_INTER_ERR_FLAG_FL_CTRL_WD_TO_ADDR \ +WF_PSE_TOP_PSE_INTER_ERR_FLAG_ADDR +#define WF_PSE_TOP_PSE_INTER_ERR_FLAG_FL_CTRL_WD_TO_MASK \ +0x00000004 /* FL_CTRL_WD_TO[2] */ +#define WF_PSE_TOP_PSE_INTER_ERR_FLAG_FL_CTRL_WD_TO_SHFT 2 +#define WF_PSE_TOP_PSE_INTER_ERR_FLAG_APB_WD_TO_ADDR \ +WF_PSE_TOP_PSE_INTER_ERR_FLAG_ADDR +#define WF_PSE_TOP_PSE_INTER_ERR_FLAG_APB_WD_TO_MASK \ + 0x00000002 /* APB_WD_TO[1] */ +#define WF_PSE_TOP_PSE_INTER_ERR_FLAG_APB_WD_TO_SHFT 1 +#define WF_PSE_TOP_PSE_INTER_ERR_FLAG_DEQ_EMPTY_QUEUE_ADDR \ +WF_PSE_TOP_PSE_INTER_ERR_FLAG_ADDR +#define WF_PSE_TOP_PSE_INTER_ERR_FLAG_DEQ_EMPTY_QUEUE_MASK \ +0x00000001 /* DEQ_EMPTY_QUEUE[0] */ +#define WF_PSE_TOP_PSE_INTER_ERR_FLAG_DEQ_EMPTY_QUEUE_SHFT 0 + +/* +* ---PSE_SER_CTRL (0x820C8000 + 0x2A0)--- +* HIF_SER_PAUSE_ALLOCATE[0] - (RW) System Error Recover function for Pause +* HIFBuffer Allocation +* CPU_SER_PAUSE_ALLOCATE[1] - (RW) System Error Recover function for Pause +* CPU Buffer Allocation +* WF_SER_PAUSE_ALLOCATE[2] - (RW) System Error Recover function for Pause +* WF Buffer Allocation +* MDP_SER_PAUSE_ALLOCATE[3] - (RW) System Error Recover function for Pause +* MDP Buffer Allocation +* SEC_SER_PAUSE_ALLOCATE[4] - (RW) System Error Recover function for Pause +* SEC Buffer Allocation +* PLE_SER_PAUSE_ALLOCATE[5] - (RW) System Error Recover function for Pause +* PLE Buffer Allocation +* RESERVED6[7..6] - (RO) Reserved bits +* HIF_SER_PAUSE_DATA[8] - (RW) System Error Recover function for Pause +* HIF DATA opeartion. +* CPU_SER_PAUSE_DATA[9] - (RW) System Error Recover function for Pause +* CPU DATA opeartion. +* WF_SER_PAUSE_DATA[10] - (RW) System Error Recover function for Pause +* WF DATA opeartion. +* MDP_SER_PAUSE_DATA[11] - (RW) System Error Recover function for Pause +* MDP DATA opeartion. +* SEC_SER_PAUSE_DATA[12] - (RW) System Error Recover function for Pause +* SEC DATA opeartion. +* PLE_SER_PAUSE_DATA[13] - (RW) System Error Recover function for Pause +* PLE DATA opeartion. +* RESERVED14[15..14] - (RO) Reserved bits +* HIF_SER_PAUSE_QUEUE[16] - (RW) System Error Recover function for Pause +* HIF Queue opeartion. +* CPU_SER_PAUSE_QUEUE[17] - (RW) System Error Recover function for Pause +* CPU Queue opeartion. +* WF_SER_PAUSE_QUEUE[18] - (RW) System Error Recover function for Pause +* WF Queue opeartion. +* MDP_SER_PAUSE_QUEUE[19] - (RW) System Error Recover function for Pause +* MDP Queue opeartion. +* SEC_SER_PAUSE_QUEUE[20] - (RW) System Error Recover function for Pause +* SEC Queue opeartion. +* PLE_SER_PAUSE_QUEUE[21] - (RW) System Error Recover function for Pause +* PLE Queue opeartion. +* RESERVED22[31..22] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_SER_CTRL_PLE_SER_PAUSE_QUEUE_ADDR \ +WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_PLE_SER_PAUSE_QUEUE_MASK \ +0x00200000 /* PLE_SER_PAUSE_QUEUE[21] */ +#define WF_PSE_TOP_PSE_SER_CTRL_PLE_SER_PAUSE_QUEUE_SHFT 21 +#define WF_PSE_TOP_PSE_SER_CTRL_SEC_SER_PAUSE_QUEUE_ADDR \ +WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_SEC_SER_PAUSE_QUEUE_MASK \ +0x00100000 /* SEC_SER_PAUSE_QUEUE[20] */ +#define WF_PSE_TOP_PSE_SER_CTRL_SEC_SER_PAUSE_QUEUE_SHFT 20 +#define WF_PSE_TOP_PSE_SER_CTRL_MDP_SER_PAUSE_QUEUE_ADDR \ +WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_MDP_SER_PAUSE_QUEUE_MASK \ +0x00080000 /* MDP_SER_PAUSE_QUEUE[19] */ +#define WF_PSE_TOP_PSE_SER_CTRL_MDP_SER_PAUSE_QUEUE_SHFT 19 +#define WF_PSE_TOP_PSE_SER_CTRL_WF_SER_PAUSE_QUEUE_ADDR \ +WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_WF_SER_PAUSE_QUEUE_MASK \ +0x00040000 /* WF_SER_PAUSE_QUEUE[18] */ +#define WF_PSE_TOP_PSE_SER_CTRL_WF_SER_PAUSE_QUEUE_SHFT 18 +#define WF_PSE_TOP_PSE_SER_CTRL_CPU_SER_PAUSE_QUEUE_ADDR \ +WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_CPU_SER_PAUSE_QUEUE_MASK \ +0x00020000 /* CPU_SER_PAUSE_QUEUE[17] */ +#define WF_PSE_TOP_PSE_SER_CTRL_CPU_SER_PAUSE_QUEUE_SHFT 17 +#define WF_PSE_TOP_PSE_SER_CTRL_HIF_SER_PAUSE_QUEUE_ADDR \ +WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_HIF_SER_PAUSE_QUEUE_MASK \ +0x00010000 /* HIF_SER_PAUSE_QUEUE[16] */ +#define WF_PSE_TOP_PSE_SER_CTRL_HIF_SER_PAUSE_QUEUE_SHFT 16 +#define WF_PSE_TOP_PSE_SER_CTRL_PLE_SER_PAUSE_DATA_ADDR \ +WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_PLE_SER_PAUSE_DATA_MASK \ +0x00002000 /* PLE_SER_PAUSE_DATA[13] */ +#define WF_PSE_TOP_PSE_SER_CTRL_PLE_SER_PAUSE_DATA_SHFT 13 +#define WF_PSE_TOP_PSE_SER_CTRL_SEC_SER_PAUSE_DATA_ADDR \ +WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_SEC_SER_PAUSE_DATA_MASK \ +0x00001000 /* SEC_SER_PAUSE_DATA[12] */ +#define WF_PSE_TOP_PSE_SER_CTRL_SEC_SER_PAUSE_DATA_SHFT 12 +#define WF_PSE_TOP_PSE_SER_CTRL_MDP_SER_PAUSE_DATA_ADDR \ +WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_MDP_SER_PAUSE_DATA_MASK \ +0x00000800 /* MDP_SER_PAUSE_DATA[11] */ +#define WF_PSE_TOP_PSE_SER_CTRL_MDP_SER_PAUSE_DATA_SHFT 11 +#define WF_PSE_TOP_PSE_SER_CTRL_WF_SER_PAUSE_DATA_ADDR \ +WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_WF_SER_PAUSE_DATA_MASK \ +0x00000400 /* WF_SER_PAUSE_DATA[10] */ +#define WF_PSE_TOP_PSE_SER_CTRL_WF_SER_PAUSE_DATA_SHFT 10 +#define WF_PSE_TOP_PSE_SER_CTRL_CPU_SER_PAUSE_DATA_ADDR \ +WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_CPU_SER_PAUSE_DATA_MASK \ +0x00000200 /* CPU_SER_PAUSE_DATA[9] */ +#define WF_PSE_TOP_PSE_SER_CTRL_CPU_SER_PAUSE_DATA_SHFT 9 +#define WF_PSE_TOP_PSE_SER_CTRL_HIF_SER_PAUSE_DATA_ADDR \ +WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_HIF_SER_PAUSE_DATA_MASK \ +0x00000100 /* HIF_SER_PAUSE_DATA[8] */ +#define WF_PSE_TOP_PSE_SER_CTRL_HIF_SER_PAUSE_DATA_SHFT 8 +#define WF_PSE_TOP_PSE_SER_CTRL_PLE_SER_PAUSE_ALLOCATE_ADDR \ +WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_PLE_SER_PAUSE_ALLOCATE_MASK \ +0x00000020 /* PLE_SER_PAUSE_ALLOCATE[5] */ +#define WF_PSE_TOP_PSE_SER_CTRL_PLE_SER_PAUSE_ALLOCATE_SHFT 5 +#define WF_PSE_TOP_PSE_SER_CTRL_SEC_SER_PAUSE_ALLOCATE_ADDR \ +WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_SEC_SER_PAUSE_ALLOCATE_MASK \ +0x00000010 /* SEC_SER_PAUSE_ALLOCATE[4] */ +#define WF_PSE_TOP_PSE_SER_CTRL_SEC_SER_PAUSE_ALLOCATE_SHFT 4 +#define WF_PSE_TOP_PSE_SER_CTRL_MDP_SER_PAUSE_ALLOCATE_ADDR \ +WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_MDP_SER_PAUSE_ALLOCATE_MASK \ +0x00000008 /* MDP_SER_PAUSE_ALLOCATE[3] */ +#define WF_PSE_TOP_PSE_SER_CTRL_MDP_SER_PAUSE_ALLOCATE_SHFT 3 +#define WF_PSE_TOP_PSE_SER_CTRL_WF_SER_PAUSE_ALLOCATE_ADDR \ +WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_WF_SER_PAUSE_ALLOCATE_MASK \ +0x00000004 /* WF_SER_PAUSE_ALLOCATE[2] */ +#define WF_PSE_TOP_PSE_SER_CTRL_WF_SER_PAUSE_ALLOCATE_SHFT 2 +#define WF_PSE_TOP_PSE_SER_CTRL_CPU_SER_PAUSE_ALLOCATE_ADDR \ +WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_CPU_SER_PAUSE_ALLOCATE_MASK \ +0x00000002 /* CPU_SER_PAUSE_ALLOCATE[1] */ +#define WF_PSE_TOP_PSE_SER_CTRL_CPU_SER_PAUSE_ALLOCATE_SHFT 1 +#define WF_PSE_TOP_PSE_SER_CTRL_HIF_SER_PAUSE_ALLOCATE_ADDR \ +WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_HIF_SER_PAUSE_ALLOCATE_MASK \ +0x00000001 /* HIF_SER_PAUSE_ALLOCATE[0] */ +#define WF_PSE_TOP_PSE_SER_CTRL_HIF_SER_PAUSE_ALLOCATE_SHFT 0 + +/* +* ---PSE_MBIST_RP_FUSE (0x820C8000 + 0x2B0)--- +* WF_PSE_MBIST_RP_FAIL[3..0] - (RO) MBIST Repair FAIL report +* RESERVED4[7..4] - (RO) Reserved bits +* WF_PSE_MBIST_RP_OK[11..8] - (RO) MBIST Repair OK report +* RESERVED12[14..12] - (RO) Reserved bits +* REG_FUSE_SEL[15] - (RW) MBIST FUSE setting +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_REG_FUSE_SEL_ADDR \ +WF_PSE_TOP_PSE_MBIST_RP_FUSE_ADDR +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_REG_FUSE_SEL_MASK \ +0x00008000 /* REG_FUSE_SEL[15] */ +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_REG_FUSE_SEL_SHFT 15 +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_WF_PSE_MBIST_RP_OK_ADDR \ +WF_PSE_TOP_PSE_MBIST_RP_FUSE_ADDR +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_WF_PSE_MBIST_RP_OK_MASK \ +0x00000F00 /* WF_PSE_MBIST_RP_OK[11..8] */ +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_WF_PSE_MBIST_RP_OK_SHFT 8 +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_WF_PSE_MBIST_RP_FAIL_ADDR \ +WF_PSE_TOP_PSE_MBIST_RP_FUSE_ADDR +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_WF_PSE_MBIST_RP_FAIL_MASK \ +0x0000000F /* WF_PSE_MBIST_RP_FAIL[3..0] */ +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_WF_PSE_MBIST_RP_FAIL_SHFT 0 + +/* +* ---PSE_MBIST_RP_FUSE_1 (0x820C8000 + 0x2B4)--- +* WF_UMAC_TOP_MBIST_PREFUSE_0[15..0] - (RW) MBIST PRE-FUSE setting +* WF_UMAC_TOP_MBIST_PREFUSE_D_0[31..16] - (RO) MBIST PRE-FUSE result +*/ +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_1_WF_UMAC_TOP_MBIST_PREFUSE_D_0_ADDR \ +WF_PSE_TOP_PSE_MBIST_RP_FUSE_1_ADDR +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_1_WF_UMAC_TOP_MBIST_PREFUSE_D_0_MASK \ +0xFFFF0000 /* WF_UMAC_TOP_MBIST_PREFUSE_D_0[31..16] */ +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_1_WF_UMAC_TOP_MBIST_PREFUSE_D_0_SHFT 16 +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_1_WF_UMAC_TOP_MBIST_PREFUSE_0_ADDR \ +WF_PSE_TOP_PSE_MBIST_RP_FUSE_1_ADDR +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_1_WF_UMAC_TOP_MBIST_PREFUSE_0_MASK \ +0x0000FFFF /* WF_UMAC_TOP_MBIST_PREFUSE_0[15..0] */ +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_1_WF_UMAC_TOP_MBIST_PREFUSE_0_SHFT 0 + +/* +* ---PSE_MBIST_BSEL (0x820C8000 + 0x2B8)--- +* WF_PSE_MBIST_BSEL[15..0] - (RW) Memory MBIST BSEL control +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_MBIST_BSEL_WF_PSE_MBIST_BSEL_ADDR \ +WF_PSE_TOP_PSE_MBIST_BSEL_ADDR +#define WF_PSE_TOP_PSE_MBIST_BSEL_WF_PSE_MBIST_BSEL_MASK \ +0x0000FFFF /* WF_PSE_MBIST_BSEL[15..0] */ +#define WF_PSE_TOP_PSE_MBIST_BSEL_WF_PSE_MBIST_BSEL_SHFT 0 + +/* +* ---SRAM_MBIST_BACKGROUND (0x820C8000 + 0x2C0)--- +* MBIST_BACKGROUND[15..0] - (RW) Background setting for PSE SRAM MBIST +circuit +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_SRAM_MBIST_BACKGROUND_MBIST_BACKGROUND_ADDR \ +WF_PSE_TOP_SRAM_MBIST_BACKGROUND_ADDR +#define WF_PSE_TOP_SRAM_MBIST_BACKGROUND_MBIST_BACKGROUND_MASK \ +0x0000FFFF /* MBIST_BACKGROUND[15..0] */ +#define WF_PSE_TOP_SRAM_MBIST_BACKGROUND_MBIST_BACKGROUND_SHFT 0 + +/* +* ---SRAM_MBIST_DONE (0x820C8000 + 0x2C4)--- +* MBIST_DONE[0] - (RO) Working status of PSE SRAM MBIST circuit +* RESERVED1[31..1] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_SRAM_MBIST_DONE_MBIST_DONE_ADDR \ +WF_PSE_TOP_SRAM_MBIST_DONE_ADDR +#define WF_PSE_TOP_SRAM_MBIST_DONE_MBIST_DONE_MASK \ + 0x00000001 /* MBIST_DONE[0] */ +#define WF_PSE_TOP_SRAM_MBIST_DONE_MBIST_DONE_SHFT 0 + +/* +* ---SRAM_MBIST_FAIL (0x820C8000 + 0x2C8)--- +* FORDLINK_SRAM_MBIST_FAIL[0] - (RO) MBIST check result of forward link SRAM +* BACKLINK_SRAM_MBIST_FAIL[1] - (RO) MBIST check result of backward link SRAM +* PAGELINK_SRAM_MBIST_FAIL[2] - (RO) MBIST check result of PAGELINK SRAM +* RLINFO_SRAM_MBIST_FAIL[3] - (RO) MBIST check result of RLINFO SRAM +* RESERVED4[31..4] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_SRAM_MBIST_FAIL_RLINFO_SRAM_MBIST_FAIL_ADDR \ +WF_PSE_TOP_SRAM_MBIST_FAIL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_FAIL_RLINFO_SRAM_MBIST_FAIL_MASK \ +0x00000008 /* RLINFO_SRAM_MBIST_FAIL[3] */ +#define WF_PSE_TOP_SRAM_MBIST_FAIL_RLINFO_SRAM_MBIST_FAIL_SHFT 3 +#define WF_PSE_TOP_SRAM_MBIST_FAIL_PAGELINK_SRAM_MBIST_FAIL_ADDR \ +WF_PSE_TOP_SRAM_MBIST_FAIL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_FAIL_PAGELINK_SRAM_MBIST_FAIL_MASK \ +0x00000004 /* PAGELINK_SRAM_MBIST_FAIL[2] */ +#define WF_PSE_TOP_SRAM_MBIST_FAIL_PAGELINK_SRAM_MBIST_FAIL_SHFT 2 +#define WF_PSE_TOP_SRAM_MBIST_FAIL_BACKLINK_SRAM_MBIST_FAIL_ADDR \ +WF_PSE_TOP_SRAM_MBIST_FAIL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_FAIL_BACKLINK_SRAM_MBIST_FAIL_MASK \ +0x00000002 /* BACKLINK_SRAM_MBIST_FAIL[1] */ +#define WF_PSE_TOP_SRAM_MBIST_FAIL_BACKLINK_SRAM_MBIST_FAIL_SHFT 1 +#define WF_PSE_TOP_SRAM_MBIST_FAIL_FORDLINK_SRAM_MBIST_FAIL_ADDR \ +WF_PSE_TOP_SRAM_MBIST_FAIL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_FAIL_FORDLINK_SRAM_MBIST_FAIL_MASK \ +0x00000001 /* FORDLINK_SRAM_MBIST_FAIL[0] */ +#define WF_PSE_TOP_SRAM_MBIST_FAIL_FORDLINK_SRAM_MBIST_FAIL_SHFT 0 + +/* +* ---SRAM_MBIST_CTRL (0x820C8000 + 0x2D0)--- +* MBIST_MODE[0] - (RW) Control register for mbist_mode of MBIST +* RESERVED1[3..1] - (RO) Reserved bits +* MBIST_HOLDB[4] - (RW) Control register for mbist_holdb of +MBIST +* RESERVED5[7..5] - (RO) Reserved bits +* MBIST_DEBUG[8] - (RW) Control register for mbist_debug of +MBIST +* MBIST_RPRST_B[9] - (RW) MBIST Repair function Enable +* MBIST_USE_DEFAULT_DELSEL[10] - (RW) MBIST delay select control +* RESERVED11[15..11] - (RO) Reserved bits +* MBIST_DIAG_SEL[19..16] - (RW) Selection register for +mbist_diag_scan_out +* RESERVED20[23..20] - (RO) Reserved bits +* MBIST_SLEEP_TEST[24] - (RW) Control register for sleep_test of MBIST +* MBIST_SLEEP_INV[25] - (RW) Control register for sleep_inv of MBIST +* MBIST_SLEEP_W[26] - (RW) Control register for sleep_w of MBIST +* MBIST_SLEEP_R[27] - (RW) Control register for sleep_r of MBIST +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_SLEEP_R_ADDR \ +WF_PSE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_SLEEP_R_MASK \ +0x08000000 /* MBIST_SLEEP_R[27] */ +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_SLEEP_R_SHFT 27 +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_SLEEP_W_ADDR \ +WF_PSE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_SLEEP_W_MASK \ +0x04000000 /* MBIST_SLEEP_W[26] */ +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_SLEEP_W_SHFT 26 +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_SLEEP_INV_ADDR \ +WF_PSE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_SLEEP_INV_MASK \ +0x02000000 /* MBIST_SLEEP_INV[25] */ +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_SLEEP_INV_SHFT 25 +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_SLEEP_TEST_ADDR \ +WF_PSE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_SLEEP_TEST_MASK \ +0x01000000 /* MBIST_SLEEP_TEST[24] */ +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_SLEEP_TEST_SHFT 24 +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_DIAG_SEL_ADDR \ +WF_PSE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_DIAG_SEL_MASK \ +0x000F0000 /* MBIST_DIAG_SEL[19..16] */ +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_DIAG_SEL_SHFT 16 +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_USE_DEFAULT_DELSEL_ADDR \ +WF_PSE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_USE_DEFAULT_DELSEL_MASK \ +0x00000400 /* MBIST_USE_DEFAULT_DELSEL[10] */ +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_USE_DEFAULT_DELSEL_SHFT 10 +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_RPRST_B_ADDR \ +WF_PSE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_RPRST_B_MASK \ +0x00000200 /* MBIST_RPRST_B[9] */ +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_RPRST_B_SHFT 9 +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_DEBUG_ADDR \ +WF_PSE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_DEBUG_MASK \ + 0x00000100 /* MBIST_DEBUG[8] */ +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_DEBUG_SHFT 8 +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_HOLDB_ADDR \ +WF_PSE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_HOLDB_MASK \ + 0x00000010 /* MBIST_HOLDB[4] */ +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_HOLDB_SHFT 4 +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_MODE_ADDR \ +WF_PSE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_MODE_MASK \ + 0x00000001 /* MBIST_MODE[0] */ +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_MODE_SHFT 0 + +/* +* ---SRAM_MBIST_DELSEL (0x820C8000 + 0x2D4)--- +* MBIST_DELSEL0_2[31..0] - (RW) Control register of delsel for PL SRAM +*/ +#define WF_PSE_TOP_SRAM_MBIST_DELSEL_MBIST_DELSEL0_2_ADDR \ +WF_PSE_TOP_SRAM_MBIST_DELSEL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_DELSEL_MBIST_DELSEL0_2_MASK \ +0xFFFFFFFF /* MBIST_DELSEL0_2[31..0] */ +#define WF_PSE_TOP_SRAM_MBIST_DELSEL_MBIST_DELSEL0_2_SHFT 0 + +/* +* ---SRAM_MBIST_DELSEL_1 (0x820C8000 + 0x2D8)--- +* MBIST_DELSEL3[31..0] - (RW) Control register of delsel for RLINFO +SRAM +*/ +#define WF_PSE_TOP_SRAM_MBIST_DELSEL_1_MBIST_DELSEL3_ADDR \ +WF_PSE_TOP_SRAM_MBIST_DELSEL_1_ADDR +#define WF_PSE_TOP_SRAM_MBIST_DELSEL_1_MBIST_DELSEL3_MASK \ +0xFFFFFFFF /* MBIST_DELSEL3[31..0] */ +#define WF_PSE_TOP_SRAM_MBIST_DELSEL_1_MBIST_DELSEL3_SHFT 0 + +/* +* ---SRAM_AWT_HDEN_CTRL (0x820C8000 + 0x2DC)--- +* FL_TBL_AWT1[0] - (RW) Memory AWT Control for FL_TBL1 +* FL_TBL_AWT2[1] - (RW) Memory AWT Control for FL_TBL2 +* PL_TBL_AWT[2] - (RW) Memory AWT Control for PL +* RLINFO_MEM_AWT[3] - (RW) Memory AWT Control for RL +* RESERVED4[15..4] - (RO) Reserved bits +* FL_TBL_HDEN1[16] - (RW) Memory HDEN Control for FL_TBL1 +* FL_TBL_HDEN2[17] - (RW) Memory HDEN Control for FL_TBL2 +* PL_TBL_HDEN[18] - (RW) Memory HDEN Control for PL +* RLINFO_MEM_HDEN[19] - (RW) Memory HDEN Control for RL +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_RLINFO_MEM_HDEN_ADDR \ +WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_ADDR +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_RLINFO_MEM_HDEN_MASK \ +0x00080000 /* RLINFO_MEM_HDEN[19] */ +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_RLINFO_MEM_HDEN_SHFT 19 +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_PL_TBL_HDEN_ADDR \ +WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_ADDR +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_PL_TBL_HDEN_MASK \ +0x00040000 /* PL_TBL_HDEN[18] */ +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_PL_TBL_HDEN_SHFT 18 +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_FL_TBL_HDEN2_ADDR \ +WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_ADDR +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_FL_TBL_HDEN2_MASK \ +0x00020000 /* FL_TBL_HDEN2[17] */ +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_FL_TBL_HDEN2_SHFT 17 +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_FL_TBL_HDEN1_ADDR \ +WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_ADDR +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_FL_TBL_HDEN1_MASK \ +0x00010000 /* FL_TBL_HDEN1[16] */ +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_FL_TBL_HDEN1_SHFT 16 +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_RLINFO_MEM_AWT_ADDR \ +WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_ADDR +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_RLINFO_MEM_AWT_MASK \ +0x00000008 /* RLINFO_MEM_AWT[3] */ +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_RLINFO_MEM_AWT_SHFT 3 +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_PL_TBL_AWT_ADDR \ +WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_ADDR +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_PL_TBL_AWT_MASK \ +0x00000004 /* PL_TBL_AWT[2] */ +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_PL_TBL_AWT_SHFT 2 +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_FL_TBL_AWT2_ADDR \ +WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_ADDR +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_FL_TBL_AWT2_MASK \ +0x00000002 /* FL_TBL_AWT2[1] */ +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_FL_TBL_AWT2_SHFT 1 +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_FL_TBL_AWT1_ADDR \ +WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_ADDR +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_FL_TBL_AWT1_MASK \ +0x00000001 /* FL_TBL_AWT1[0] */ +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_FL_TBL_AWT1_SHFT 0 + +/* +* ---C_GET_FID_0 (0x820C8000 + 0x310)--- +* QUEUE_FRAME_ID[15..0] - (RW) Frame ID for get command +* At GET_FRAME_TYPE = 2'h0/2'h1: +* QUEUE_FRAME_ID[15:14] = PID +* 2'h0: HIF port +* 2'h1: CPU port +* 2'h2: LMAC port +* QUEUE_FRAME_ID[9:0] = WLANID +* At GET_FRAME_TYPE = 2'h2/2'h3: +* QUEUE_FRAME_ID[11:0] = reference FID +* GET_FRAME_TYPE[19..16] - (RW) GET_SUB_TYPE +* RESERVED20[23..20] - (RO) Reserved bits +* GET_FRAME_QID[30..24] - (RW) Queue ID vlaue +* EXECUTE[31] - (A0) Executes command +*/ +#define WF_PSE_TOP_C_GET_FID_0_EXECUTE_ADDR WF_PSE_TOP_C_GET_FID_0_ADDR +#define WF_PSE_TOP_C_GET_FID_0_EXECUTE_MASK 0x80000000 /* EXECUTE[31] */ +#define WF_PSE_TOP_C_GET_FID_0_EXECUTE_SHFT 31 +#define WF_PSE_TOP_C_GET_FID_0_GET_FRAME_QID_ADDR WF_PSE_TOP_C_GET_FID_0_ADDR +#define WF_PSE_TOP_C_GET_FID_0_GET_FRAME_QID_MASK \ +0x7F000000 /* GET_FRAME_QID[30..24] */ +#define WF_PSE_TOP_C_GET_FID_0_GET_FRAME_QID_SHFT 24 +#define WF_PSE_TOP_C_GET_FID_0_GET_FRAME_TYPE_ADDR WF_PSE_TOP_C_GET_FID_0_ADDR +#define WF_PSE_TOP_C_GET_FID_0_GET_FRAME_TYPE_MASK \ +0x000F0000 /* GET_FRAME_TYPE[19..16] */ +#define WF_PSE_TOP_C_GET_FID_0_GET_FRAME_TYPE_SHFT 16 +#define WF_PSE_TOP_C_GET_FID_0_QUEUE_FRAME_ID_ADDR WF_PSE_TOP_C_GET_FID_0_ADDR +#define WF_PSE_TOP_C_GET_FID_0_QUEUE_FRAME_ID_MASK \ +0x0000FFFF /* QUEUE_FRAME_ID[15..0] */ +#define WF_PSE_TOP_C_GET_FID_0_QUEUE_FRAME_ID_SHFT 0 + +/* +* ---C_GET_FID_1 (0x820C8000 + 0x314)--- +* GET_RETURN_FID[11..0] - (RO) Return frame ID +* RESERVED12[14..12] - (RO) Reserved bits +* END[15] - (RO) Return frame ID is end FID +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_C_GET_FID_1_END_ADDR WF_PSE_TOP_C_GET_FID_1_ADDR +#define WF_PSE_TOP_C_GET_FID_1_END_MASK 0x00008000 /* END[15] */ +#define WF_PSE_TOP_C_GET_FID_1_END_SHFT 15 +#define WF_PSE_TOP_C_GET_FID_1_GET_RETURN_FID_ADDR WF_PSE_TOP_C_GET_FID_1_ADDR +#define WF_PSE_TOP_C_GET_FID_1_GET_RETURN_FID_MASK \ +0x00000FFF /* GET_RETURN_FID[11..0] */ +#define WF_PSE_TOP_C_GET_FID_1_GET_RETURN_FID_SHFT 0 + +/* +* ---C_EN_QUEUE_0 (0x820C8000 + 0x320)--- +* DST_WLANID[9..0] - (RW) Destination WLANID for enqueue +* RESERVED10[13..10] - (RO) Reserved bits +* DST_PID[15..14] - (RW) Destination port ID for enqueue +* SUB_TYPE[19..16] - (RW) Sub-type of enqueue command +* RESERVED20[22..20] - (RO) Reserved bits +* DELAY_ENQ[23] - (RW) Delays enqueue +* DST_QID[30..24] - (RW) Destination queue ID for enqueue +* EXECUTE[31] - (A0) Executes command +*/ +#define WF_PSE_TOP_C_EN_QUEUE_0_EXECUTE_ADDR WF_PSE_TOP_C_EN_QUEUE_0_ADDR +#define WF_PSE_TOP_C_EN_QUEUE_0_EXECUTE_MASK 0x80000000 /* EXECUTE[31] */ +#define WF_PSE_TOP_C_EN_QUEUE_0_EXECUTE_SHFT 31 +#define WF_PSE_TOP_C_EN_QUEUE_0_DST_QID_ADDR WF_PSE_TOP_C_EN_QUEUE_0_ADDR +#define WF_PSE_TOP_C_EN_QUEUE_0_DST_QID_MASK 0x7F000000 /* DST_QID[30..24] */ +#define WF_PSE_TOP_C_EN_QUEUE_0_DST_QID_SHFT 24 +#define WF_PSE_TOP_C_EN_QUEUE_0_DELAY_ENQ_ADDR WF_PSE_TOP_C_EN_QUEUE_0_ADDR +#define WF_PSE_TOP_C_EN_QUEUE_0_DELAY_ENQ_MASK 0x00800000 /* DELAY_ENQ[23] */ +#define WF_PSE_TOP_C_EN_QUEUE_0_DELAY_ENQ_SHFT 23 +#define WF_PSE_TOP_C_EN_QUEUE_0_SUB_TYPE_ADDR WF_PSE_TOP_C_EN_QUEUE_0_ADDR +#define WF_PSE_TOP_C_EN_QUEUE_0_SUB_TYPE_MASK 0x000F0000 /* SUB_TYPE[19..16] */ +#define WF_PSE_TOP_C_EN_QUEUE_0_SUB_TYPE_SHFT 16 +#define WF_PSE_TOP_C_EN_QUEUE_0_DST_PID_ADDR WF_PSE_TOP_C_EN_QUEUE_0_ADDR +#define WF_PSE_TOP_C_EN_QUEUE_0_DST_PID_MASK 0x0000C000 /* DST_PID[15..14] */ +#define WF_PSE_TOP_C_EN_QUEUE_0_DST_PID_SHFT 14 +#define WF_PSE_TOP_C_EN_QUEUE_0_DST_WLANID_ADDR WF_PSE_TOP_C_EN_QUEUE_0_ADDR +#define WF_PSE_TOP_C_EN_QUEUE_0_DST_WLANID_MASK \ + 0x000003FF /* DST_WLANID[9..0] */ +#define WF_PSE_TOP_C_EN_QUEUE_0_DST_WLANID_SHFT 0 + +/* +* ---C_EN_QUEUE_1 (0x820C8000 + 0x324)--- +* CUR_LIST_FID_START[11..0] - (RW) Start frame ID of enqueue operation +* list, enqueue FID of enqueue operation +* RESERVED12[15..12] - (RO) Reserved bits +* CUR_LIST_FID_END[27..16] - (RW) End frame ID of enqueue operation list +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_C_EN_QUEUE_1_CUR_LIST_FID_END_ADDR \ +WF_PSE_TOP_C_EN_QUEUE_1_ADDR +#define WF_PSE_TOP_C_EN_QUEUE_1_CUR_LIST_FID_END_MASK \ +0x0FFF0000 /* CUR_LIST_FID_END[27..16] */ +#define WF_PSE_TOP_C_EN_QUEUE_1_CUR_LIST_FID_END_SHFT 16 +#define WF_PSE_TOP_C_EN_QUEUE_1_CUR_LIST_FID_START_ADDR \ +WF_PSE_TOP_C_EN_QUEUE_1_ADDR +#define WF_PSE_TOP_C_EN_QUEUE_1_CUR_LIST_FID_START_MASK \ +0x00000FFF /* CUR_LIST_FID_START[11..0] */ +#define WF_PSE_TOP_C_EN_QUEUE_1_CUR_LIST_FID_START_SHFT 0 + +/* +* ---C_EN_QUEUE_2 (0x820C8000 + 0x328)--- +* TARGET_FID[11..0] - (RW) Target reference FID for enqueue +operation +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_C_EN_QUEUE_2_TARGET_FID_ADDR WF_PSE_TOP_C_EN_QUEUE_2_ADDR +#define WF_PSE_TOP_C_EN_QUEUE_2_TARGET_FID_MASK \ + 0x00000FFF /* TARGET_FID[11..0] */ +#define WF_PSE_TOP_C_EN_QUEUE_2_TARGET_FID_SHFT 0 + +/* +* ---C_DE_QUEUE_0 (0x820C8000 + 0x330)--- +* SRC_WLANID[9..0] - (RW) Source WLAN ID for dequeue command +* RESERVED10[13..10] - (RO) Reserved bits +* SRC_PID[15..14] - (RW) Source port ID for dequeue command +* DEQ_SUB_TYPE[19..16] - (RW) Dequeue subtype of dequeue command +* ENQ_SUB_TYPE[22..20] - (RW) Enqueue subtype of enqueue command +* Only valid in Deq&Enq type. +* ENQ_VLD[23] - (RW) Deq&Enq command valid +* SRC_QID[30..24] - (RW) Source queue ID for dequeue command +* EXECUTE[31] - (A0) Executes dequeue command +*/ +#define WF_PSE_TOP_C_DE_QUEUE_0_EXECUTE_ADDR WF_PSE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_0_EXECUTE_MASK 0x80000000 /* EXECUTE[31] */ +#define WF_PSE_TOP_C_DE_QUEUE_0_EXECUTE_SHFT 31 +#define WF_PSE_TOP_C_DE_QUEUE_0_SRC_QID_ADDR WF_PSE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_0_SRC_QID_MASK 0x7F000000 /* SRC_QID[30..24] */ +#define WF_PSE_TOP_C_DE_QUEUE_0_SRC_QID_SHFT 24 +#define WF_PSE_TOP_C_DE_QUEUE_0_ENQ_VLD_ADDR WF_PSE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_0_ENQ_VLD_MASK 0x00800000 /* ENQ_VLD[23] */ +#define WF_PSE_TOP_C_DE_QUEUE_0_ENQ_VLD_SHFT 23 +#define WF_PSE_TOP_C_DE_QUEUE_0_ENQ_SUB_TYPE_ADDR WF_PSE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_0_ENQ_SUB_TYPE_MASK \ +0x00700000 /* ENQ_SUB_TYPE[22..20] */ +#define WF_PSE_TOP_C_DE_QUEUE_0_ENQ_SUB_TYPE_SHFT 20 +#define WF_PSE_TOP_C_DE_QUEUE_0_DEQ_SUB_TYPE_ADDR WF_PSE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_0_DEQ_SUB_TYPE_MASK \ +0x000F0000 /* DEQ_SUB_TYPE[19..16] */ +#define WF_PSE_TOP_C_DE_QUEUE_0_DEQ_SUB_TYPE_SHFT 16 +#define WF_PSE_TOP_C_DE_QUEUE_0_SRC_PID_ADDR WF_PSE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_0_SRC_PID_MASK 0x0000C000 /* SRC_PID[15..14] */ +#define WF_PSE_TOP_C_DE_QUEUE_0_SRC_PID_SHFT 14 +#define WF_PSE_TOP_C_DE_QUEUE_0_SRC_WLANID_ADDR WF_PSE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_0_SRC_WLANID_MASK \ + 0x000003FF /* SRC_WLANID[9..0] */ +#define WF_PSE_TOP_C_DE_QUEUE_0_SRC_WLANID_SHFT 0 + +/* +* ---C_DE_QUEUE_1 (0x820C8000 + 0x334)--- +* CUR_LIST_FID_START[11..0] - (RW) Start frame ID of dequeue operation +* list, enqueue start FID of enqueue operation +* Only valid in Deq&Enq type. +* RESERVED12[15..12] - (RO) Reserved bits +* CUR_LIST_FID_END[27..16] - (RW) End framd ID of dequeue operation list, +* enqueue end FID of enqueue operation +* Only valid in Deq&Enq type. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_C_DE_QUEUE_1_CUR_LIST_FID_END_ADDR \ +WF_PSE_TOP_C_DE_QUEUE_1_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_1_CUR_LIST_FID_END_MASK \ +0x0FFF0000 /* CUR_LIST_FID_END[27..16] */ +#define WF_PSE_TOP_C_DE_QUEUE_1_CUR_LIST_FID_END_SHFT 16 +#define WF_PSE_TOP_C_DE_QUEUE_1_CUR_LIST_FID_START_ADDR \ +WF_PSE_TOP_C_DE_QUEUE_1_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_1_CUR_LIST_FID_START_MASK \ +0x00000FFF /* CUR_LIST_FID_START[11..0] */ +#define WF_PSE_TOP_C_DE_QUEUE_1_CUR_LIST_FID_START_SHFT 0 + +/* +* ---C_DE_QUEUE_2 (0x820C8000 + 0x338)--- +* DEQ_ENQ_DST_WLANID[9..0] - (RW) Destination WLAN ID for enqueue command +* Only valid in Deq&Enq type. +* RESERVED10[13..10] - (RO) Reserved bits +* DEQ_ENQ_DST_PID[15..14] - (RW) Destination port ID for dequeue command +* RESERVED16[23..16] - (RO) Reserved bits +* DEQ_ENQ_DST_QID[30..24] - (RW) Destination queue ID for enqueue command +* Only valid in Deq&Enq type. +* RESERVED31[31] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_QID_ADDR \ +WF_PSE_TOP_C_DE_QUEUE_2_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_QID_MASK \ +0x7F000000 /* DEQ_ENQ_DST_QID[30..24] */ +#define WF_PSE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_QID_SHFT 24 +#define WF_PSE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_PID_ADDR \ +WF_PSE_TOP_C_DE_QUEUE_2_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_PID_MASK \ +0x0000C000 /* DEQ_ENQ_DST_PID[15..14] */ +#define WF_PSE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_PID_SHFT 14 +#define WF_PSE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_WLANID_ADDR \ +WF_PSE_TOP_C_DE_QUEUE_2_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_WLANID_MASK \ +0x000003FF /* DEQ_ENQ_DST_WLANID[9..0] */ +#define WF_PSE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_WLANID_SHFT 0 + +/* +* ---C_DE_QUEUE_3 (0x820C8000 + 0x33C)--- +* DEQ_HEAD_FDI[11..0] - (RO) Head FID got from dequeue command +* RESERVED12[14..12] - (RO) Reserved bits +* DEQ_EMPTY[15] - (RO) Queue empty after dequeue command is +executed +* DEQ_TAIL_FID[27..16] - (RO) Last FID got from dequeue command +* RESERVED28[30..28] - (RO) Reserved bits +* BUSY[31] - (RO) Dequeue execute busy +*/ +#define WF_PSE_TOP_C_DE_QUEUE_3_BUSY_ADDR WF_PSE_TOP_C_DE_QUEUE_3_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_3_BUSY_MASK 0x80000000 /* BUSY[31] */ +#define WF_PSE_TOP_C_DE_QUEUE_3_BUSY_SHFT 31 +#define WF_PSE_TOP_C_DE_QUEUE_3_DEQ_TAIL_FID_ADDR WF_PSE_TOP_C_DE_QUEUE_3_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_3_DEQ_TAIL_FID_MASK \ +0x0FFF0000 /* DEQ_TAIL_FID[27..16] */ +#define WF_PSE_TOP_C_DE_QUEUE_3_DEQ_TAIL_FID_SHFT 16 +#define WF_PSE_TOP_C_DE_QUEUE_3_DEQ_EMPTY_ADDR WF_PSE_TOP_C_DE_QUEUE_3_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_3_DEQ_EMPTY_MASK 0x00008000 /* DEQ_EMPTY[15] */ +#define WF_PSE_TOP_C_DE_QUEUE_3_DEQ_EMPTY_SHFT 15 +#define WF_PSE_TOP_C_DE_QUEUE_3_DEQ_HEAD_FDI_ADDR WF_PSE_TOP_C_DE_QUEUE_3_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_3_DEQ_HEAD_FDI_MASK \ +0x00000FFF /* DEQ_HEAD_FDI[11..0] */ +#define WF_PSE_TOP_C_DE_QUEUE_3_DEQ_HEAD_FDI_SHFT 0 + +/* +* ---C_DE_QUEUE_4 (0x820C8000 + 0x340)--- +* DEQ_ENQ_REF_FID[11..0] - (RW) Reference frame ID for enqueue command +* Only valid in Deq&Enq type. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_C_DE_QUEUE_4_DEQ_ENQ_REF_FID_ADDR \ +WF_PSE_TOP_C_DE_QUEUE_4_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_4_DEQ_ENQ_REF_FID_MASK \ +0x00000FFF /* DEQ_ENQ_REF_FID[11..0] */ +#define WF_PSE_TOP_C_DE_QUEUE_4_DEQ_ENQ_REF_FID_SHFT 0 + +/* +* ---ALLOCATE_0 (0x820C8000 + 0x350)--- +* ALLOCATE_FRAME_LENGTH[13..0] - (RW) Allocate frame length +* Unit: DW (4 bytes) +* RESERVED14[15..14] - (RO) Reserved bits +* ALLOCATE_QID[20..16] - (RW) QID used for allocate buffer +* RESERVED21[30..21] - (RO) Reserved bits +* EXECUTE[31] - (A0) Executes allocate buffer command +*/ +#define WF_PSE_TOP_ALLOCATE_0_EXECUTE_ADDR WF_PSE_TOP_ALLOCATE_0_ADDR +#define WF_PSE_TOP_ALLOCATE_0_EXECUTE_MASK 0x80000000 /* EXECUTE[31] */ +#define WF_PSE_TOP_ALLOCATE_0_EXECUTE_SHFT 31 +#define WF_PSE_TOP_ALLOCATE_0_ALLOCATE_QID_ADDR WF_PSE_TOP_ALLOCATE_0_ADDR +#define WF_PSE_TOP_ALLOCATE_0_ALLOCATE_QID_MASK \ +0x001F0000 /* ALLOCATE_QID[20..16] */ +#define WF_PSE_TOP_ALLOCATE_0_ALLOCATE_QID_SHFT 16 +#define WF_PSE_TOP_ALLOCATE_0_ALLOCATE_FRAME_LENGTH_ADDR \ +WF_PSE_TOP_ALLOCATE_0_ADDR +#define WF_PSE_TOP_ALLOCATE_0_ALLOCATE_FRAME_LENGTH_MASK \ +0x00003FFF /* ALLOCATE_FRAME_LENGTH[13..0] */ +#define WF_PSE_TOP_ALLOCATE_0_ALLOCATE_FRAME_LENGTH_SHFT 0 + +/* +* ---ALLOCATE_1 (0x820C8000 + 0x354)--- +* ALLOCATE_FID[11..0] - (RO) Return frame ID for allocate buffer +command +* RESERVED12[30..12] - (RO) Reserved bits +* EXECUTE[31] - (RO) Execute status of allocate buffer +command +*/ +#define WF_PSE_TOP_ALLOCATE_1_EXECUTE_ADDR WF_PSE_TOP_ALLOCATE_1_ADDR +#define WF_PSE_TOP_ALLOCATE_1_EXECUTE_MASK 0x80000000 /* EXECUTE[31] */ +#define WF_PSE_TOP_ALLOCATE_1_EXECUTE_SHFT 31 +#define WF_PSE_TOP_ALLOCATE_1_ALLOCATE_FID_ADDR WF_PSE_TOP_ALLOCATE_1_ADDR +#define WF_PSE_TOP_ALLOCATE_1_ALLOCATE_FID_MASK \ +0x00000FFF /* ALLOCATE_FID[11..0] */ +#define WF_PSE_TOP_ALLOCATE_1_ALLOCATE_FID_SHFT 0 + +/* +* ---FREEPG_CNT (0x820C8000 + 0x380)--- +* FREEPG_CNT[11..0] - (RO) Total page number of free +* RESERVED12[15..12] - (RO) Reserved bits +* FFA_CNT[27..16] - (RO) Free page numbers of free for all +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_FREEPG_CNT_FFA_CNT_ADDR WF_PSE_TOP_FREEPG_CNT_ADDR +#define WF_PSE_TOP_FREEPG_CNT_FFA_CNT_MASK 0x0FFF0000 /* FFA_CNT[27..16] */ +#define WF_PSE_TOP_FREEPG_CNT_FFA_CNT_SHFT 16 +#define WF_PSE_TOP_FREEPG_CNT_FREEPG_CNT_ADDR WF_PSE_TOP_FREEPG_CNT_ADDR +#define WF_PSE_TOP_FREEPG_CNT_FREEPG_CNT_MASK 0x00000FFF /* FREEPG_CNT[11..0] */ +#define WF_PSE_TOP_FREEPG_CNT_FREEPG_CNT_SHFT 0 + +/* +* ---FREEPG_HEAD_TAIL (0x820C8000 + 0x384)--- +* FREEPG_HEAD[11..0] - (RO) Head page of free page list +* RESERVED12[15..12] - (RO) Reserved bits +* FREEPG_TAIL[27..16] - (RO) Tail page of free page list +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_FREEPG_HEAD_TAIL_FREEPG_TAIL_ADDR \ +WF_PSE_TOP_FREEPG_HEAD_TAIL_ADDR +#define WF_PSE_TOP_FREEPG_HEAD_TAIL_FREEPG_TAIL_MASK \ +0x0FFF0000 /* FREEPG_TAIL[27..16] */ +#define WF_PSE_TOP_FREEPG_HEAD_TAIL_FREEPG_TAIL_SHFT 16 +#define WF_PSE_TOP_FREEPG_HEAD_TAIL_FREEPG_HEAD_ADDR \ +WF_PSE_TOP_FREEPG_HEAD_TAIL_ADDR +#define WF_PSE_TOP_FREEPG_HEAD_TAIL_FREEPG_HEAD_MASK \ +0x00000FFF /* FREEPG_HEAD[11..0] */ +#define WF_PSE_TOP_FREEPG_HEAD_TAIL_FREEPG_HEAD_SHFT 0 + +/* +* ---PSE_SEEK_CR_00 (0x820C8000 + 0x3D0)--- +* PSE_FL_ARB_CS[2..0] - (RO) PSE debug state for FL_ARB_CS +* RESERVED3[3] - (RO) Reserved bits +* PSE_FL_CS[7..4] - (RO) PSE debug state for FL_CS +* PSE_ENQ_FL_CS[11..8] - (RO) PSE debug state for ENQ_FL_CS +* PSE_DEQ_FL_CS[15..12] - (RO) PSE debug state for DEQ_FL_CS +* PSE_ACC_LST_CS[18..16] - (RO) PSE debug state for ACC_LST_CS +* RESERVED19[31..19] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_ACC_LST_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_00_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_ACC_LST_CS_MASK \ +0x00070000 /* PSE_ACC_LST_CS[18..16] */ +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_ACC_LST_CS_SHFT 16 +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_DEQ_FL_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_00_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_DEQ_FL_CS_MASK \ +0x0000F000 /* PSE_DEQ_FL_CS[15..12] */ +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_DEQ_FL_CS_SHFT 12 +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_ENQ_FL_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_00_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_ENQ_FL_CS_MASK \ +0x00000F00 /* PSE_ENQ_FL_CS[11..8] */ +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_ENQ_FL_CS_SHFT 8 +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_FL_CS_ADDR WF_PSE_TOP_PSE_SEEK_CR_00_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_FL_CS_MASK \ + 0x000000F0 /* PSE_FL_CS[7..4] */ +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_FL_CS_SHFT 4 +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_FL_ARB_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_00_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_FL_ARB_CS_MASK \ +0x00000007 /* PSE_FL_ARB_CS[2..0] */ +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_FL_ARB_CS_SHFT 0 + +/* +* ---PSE_SEEK_CR_01 (0x820C8000 + 0x3D4)--- +* PSE_PL_ARB_CS[2..0] - (RO) PSE debug state for PL_ARB_CS +* RESERVED3[3] - (RO) Reserved bits +* PSE_PL_INIT_CS[5..4] - (RO) PSE debug state for PL_INIT_CS +* RESERVED6[7..6] - (RO) Reserved bits +* PSE_PL_GNEXT_CS[8] - (RO) PSE debug state for PL_GNEXT_CS +* RESERVED9[11..9] - (RO) Reserved bits +* PSE_PL_GBUF_CS[14..12] - (RO) PSE debug state for PL_GBUF_CS +* RESERVED15[15] - (RO) Reserved bits +* PSE_PL_RLS_CS[17..16] - (RO) PSE debug state for PL_RLS_CS +* RESERVED18[19..18] - (RO) Reserved bits +* PSE_PL_REFILL_CS[22..20] - (RO) PSE debug state for PL_REFILL_CS +* RESERVED23[23] - (RO) Reserved bits +* PSE_RLS_CS[25..24] - (RO) PSE debug state for RLS_CS +* RESERVED26[31..26] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_RLS_CS_ADDR WF_PSE_TOP_PSE_SEEK_CR_01_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_RLS_CS_MASK \ +0x03000000 /* PSE_RLS_CS[25..24] */ +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_RLS_CS_SHFT 24 +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_REFILL_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_01_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_REFILL_CS_MASK \ +0x00700000 /* PSE_PL_REFILL_CS[22..20] */ +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_REFILL_CS_SHFT 20 +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_RLS_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_01_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_RLS_CS_MASK \ +0x00030000 /* PSE_PL_RLS_CS[17..16] */ +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_RLS_CS_SHFT 16 +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_GBUF_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_01_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_GBUF_CS_MASK \ +0x00007000 /* PSE_PL_GBUF_CS[14..12] */ +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_GBUF_CS_SHFT 12 +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_GNEXT_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_01_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_GNEXT_CS_MASK \ +0x00000100 /* PSE_PL_GNEXT_CS[8] */ +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_GNEXT_CS_SHFT 8 +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_INIT_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_01_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_INIT_CS_MASK \ +0x00000030 /* PSE_PL_INIT_CS[5..4] */ +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_INIT_CS_SHFT 4 +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_ARB_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_01_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_ARB_CS_MASK \ +0x00000007 /* PSE_PL_ARB_CS[2..0] */ +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_ARB_CS_SHFT 0 + +/* +* ---PSE_SEEK_CR_02 (0x820C8000 + 0x3D8)--- +* PSE_HIF_DOP_PBUF_CS[2..0] - (RO) PSE debug state for HIF_DOP_PBUF_CS +* RESERVED3[3] - (RO) Reserved bits +* PSE_HIF_DOP_CACHE_CS[5..4] - (RO) PSE debug state for HIF_DOP_CACHE_CS +* RESERVED6[7..6] - (RO) Reserved bits +* PSE_HIF_QOP_Q_OPER_CS[11..8] - (RO) PSE debug state for HIF_QOP_Q_OPER_CS +* PSE_HIF_QOP_RL_OCP_CS[13..12] - (RO) PSE debug state for HIF_QOP_RL_OCP_CS +* RESERVED14[15..14] - (RO) Reserved bits +* PSE_HIF_QOP_PL_OCP_CS[17..16] - (RO) PSE debug state for HIF_QOP_PL_OCP_CS +* RESERVED18[19..18] - (RO) Reserved bits +* PSE_HIF_QOP_ALLOCATE_CS[22..20] - (RO) PSE debug state for +HIF_QOP_ALLOCATE_CS +* RESERVED23[23] - (RO) Reserved bits +* PSE_HIF_RX_DOP_PBUF_CS[26..24] - (RO) PSE debug state for HIF_RX_DOP_PBUF_CS +* RESERVED27[27] - (RO) Reserved bits +* PSE_HIF_RX_DOP_CACHE_CS[29..28] - (RO) PSE debug state for +HIF_RX_DOP_CACHE_CS +* RESERVED30[31..30] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_RX_DOP_CACHE_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_02_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_RX_DOP_CACHE_CS_MASK \ +0x30000000 /* PSE_HIF_RX_DOP_CACHE_CS[29..28] */ +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_RX_DOP_CACHE_CS_SHFT 28 +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_RX_DOP_PBUF_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_02_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_RX_DOP_PBUF_CS_MASK \ +0x07000000 /* PSE_HIF_RX_DOP_PBUF_CS[26..24] */ +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_RX_DOP_PBUF_CS_SHFT 24 +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_QOP_ALLOCATE_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_02_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_QOP_ALLOCATE_CS_MASK \ +0x00700000 /* PSE_HIF_QOP_ALLOCATE_CS[22..20] */ +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_QOP_ALLOCATE_CS_SHFT 20 +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_QOP_PL_OCP_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_02_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_QOP_PL_OCP_CS_MASK \ +0x00030000 /* PSE_HIF_QOP_PL_OCP_CS[17..16] */ +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_QOP_PL_OCP_CS_SHFT 16 +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_QOP_RL_OCP_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_02_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_QOP_RL_OCP_CS_MASK \ +0x00003000 /* PSE_HIF_QOP_RL_OCP_CS[13..12] */ +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_QOP_RL_OCP_CS_SHFT 12 +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_QOP_Q_OPER_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_02_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_QOP_Q_OPER_CS_MASK \ +0x00000F00 /* PSE_HIF_QOP_Q_OPER_CS[11..8] */ +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_QOP_Q_OPER_CS_SHFT 8 +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_DOP_CACHE_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_02_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_DOP_CACHE_CS_MASK \ +0x00000030 /* PSE_HIF_DOP_CACHE_CS[5..4] */ +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_DOP_CACHE_CS_SHFT 4 +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_DOP_PBUF_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_02_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_DOP_PBUF_CS_MASK \ +0x00000007 /* PSE_HIF_DOP_PBUF_CS[2..0] */ +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_DOP_PBUF_CS_SHFT 0 + +/* +* ---PSE_SEEK_CR_03 (0x820C8000 + 0x3DC)--- +* PSE_CPU_DOP_PBUF_CS[2..0] - (RO) PSE debug state for CPU_DOP_PBUF_CS +* RESERVED3[3] - (RO) Reserved bits +* PSE_CPU_DOP_CACHE_CS[5..4] - (RO) PSE debug state for CPU_DOP_CACHE_CS +* RESERVED6[7..6] - (RO) Reserved bits +* PSE_CPU_QOP_Q_OPER_CS[11..8] - (RO) PSE debug state for CPU_QOP_Q_OPER_CS +* PSE_CPU_QOP_RL_OCP_CS[13..12] - (RO) PSE debug state for CPU_QOP_RL_OCP_CS +* RESERVED14[15..14] - (RO) Reserved bits +* PSE_CPU_QOP_PL_OCP_CS[17..16] - (RO) PSE debug state for CPU_QOP_PL_OCP_CS +* RESERVED18[19..18] - (RO) Reserved bits +* PSE_CPU_QOP_ALLOCATE_CS[22..20] - (RO) PSE debug state for +CPU_QOP_ALLOCATE_CS +* RESERVED23[31..23] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_QOP_ALLOCATE_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_03_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_QOP_ALLOCATE_CS_MASK \ +0x00700000 /* PSE_CPU_QOP_ALLOCATE_CS[22..20] */ +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_QOP_ALLOCATE_CS_SHFT 20 +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_QOP_PL_OCP_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_03_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_QOP_PL_OCP_CS_MASK \ +0x00030000 /* PSE_CPU_QOP_PL_OCP_CS[17..16] */ +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_QOP_PL_OCP_CS_SHFT 16 +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_QOP_RL_OCP_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_03_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_QOP_RL_OCP_CS_MASK \ +0x00003000 /* PSE_CPU_QOP_RL_OCP_CS[13..12] */ +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_QOP_RL_OCP_CS_SHFT 12 +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_QOP_Q_OPER_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_03_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_QOP_Q_OPER_CS_MASK \ +0x00000F00 /* PSE_CPU_QOP_Q_OPER_CS[11..8] */ +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_QOP_Q_OPER_CS_SHFT 8 +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_DOP_CACHE_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_03_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_DOP_CACHE_CS_MASK \ +0x00000030 /* PSE_CPU_DOP_CACHE_CS[5..4] */ +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_DOP_CACHE_CS_SHFT 4 +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_DOP_PBUF_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_03_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_DOP_PBUF_CS_MASK \ +0x00000007 /* PSE_CPU_DOP_PBUF_CS[2..0] */ +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_DOP_PBUF_CS_SHFT 0 + +/* +* ---PSE_SEEK_CR_04 (0x820C8000 + 0x3E0)--- +* PSE_WF_DOP_PBUF_CS[2..0] - (RO) PSE debug state for WF_DOP_PBUF_CS +* RESERVED3[3] - (RO) Reserved bits +* PSE_WF_DOP_CACHE_CS[5..4] - (RO) PSE debug state for WF_DOP_CACHE_CS +* RESERVED6[7..6] - (RO) Reserved bits +* PSE_WF_QOP_Q_OPER_CS[11..8] - (RO) PSE debug state for WF_QOP_Q_OPER_CS +* PSE_WF_QOP_RL_OCP_CS[13..12] - (RO) PSE debug state for WF_QOP_RL_OCP_CS +* RESERVED14[15..14] - (RO) Reserved bits +* PSE_WF_QOP_PL_OCP_CS[17..16] - (RO) PSE debug state for WF_QOP_PL_OCP_CS +* RESERVED18[19..18] - (RO) Reserved bits +* PSE_WF_QOP_ALLOCATE_CS[22..20] - (RO) PSE debug state for WF_QOP_ALLOCATE_CS +* RESERVED23[31..23] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_QOP_ALLOCATE_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_04_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_QOP_ALLOCATE_CS_MASK \ +0x00700000 /* PSE_WF_QOP_ALLOCATE_CS[22..20] */ +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_QOP_ALLOCATE_CS_SHFT 20 +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_QOP_PL_OCP_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_04_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_QOP_PL_OCP_CS_MASK \ +0x00030000 /* PSE_WF_QOP_PL_OCP_CS[17..16] */ +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_QOP_PL_OCP_CS_SHFT 16 +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_QOP_RL_OCP_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_04_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_QOP_RL_OCP_CS_MASK \ +0x00003000 /* PSE_WF_QOP_RL_OCP_CS[13..12] */ +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_QOP_RL_OCP_CS_SHFT 12 +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_QOP_Q_OPER_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_04_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_QOP_Q_OPER_CS_MASK \ +0x00000F00 /* PSE_WF_QOP_Q_OPER_CS[11..8] */ +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_QOP_Q_OPER_CS_SHFT 8 +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_DOP_CACHE_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_04_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_DOP_CACHE_CS_MASK \ +0x00000030 /* PSE_WF_DOP_CACHE_CS[5..4] */ +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_DOP_CACHE_CS_SHFT 4 +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_DOP_PBUF_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_04_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_DOP_PBUF_CS_MASK \ +0x00000007 /* PSE_WF_DOP_PBUF_CS[2..0] */ +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_DOP_PBUF_CS_SHFT 0 + +/* +* ---PSE_SEEK_CR_05 (0x820C8000 + 0x3E4)--- +* PSE_MDP_DOP_PBUF_CS[2..0] - (RO) PSE debug state for MDP_DOP_PBUF_CS +* RESERVED3[3] - (RO) Reserved bits +* PSE_MDP_DOP_CACHE_CS[5..4] - (RO) PSE debug state for MDP_DOP_CACHE_CS +* RESERVED6[7..6] - (RO) Reserved bits +* PSE_MDP_QOP_Q_OPER_CS[11..8] - (RO) PSE debug state for MDP_QOP_Q_OPER_CS +* PSE_MDP_QOP_RL_OCP_CS[13..12] - (RO) PSE debug state for MDP_QOP_RL_OCP_CS +* RESERVED14[15..14] - (RO) Reserved bits +* PSE_MDP_QOP_PL_OCP_CS[17..16] - (RO) PSE debug state for MDP_QOP_PL_OCP_CS +* RESERVED18[19..18] - (RO) Reserved bits +* PSE_MDP_QOP_ALLOCATE_CS[22..20] - (RO) PSE debug state for +MDP_QOP_ALLOCATE_CS +* RESERVED23[31..23] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_QOP_ALLOCATE_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_05_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_QOP_ALLOCATE_CS_MASK \ +0x00700000 /* PSE_MDP_QOP_ALLOCATE_CS[22..20] */ +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_QOP_ALLOCATE_CS_SHFT 20 +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_QOP_PL_OCP_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_05_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_QOP_PL_OCP_CS_MASK \ +0x00030000 /* PSE_MDP_QOP_PL_OCP_CS[17..16] */ +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_QOP_PL_OCP_CS_SHFT 16 +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_QOP_RL_OCP_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_05_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_QOP_RL_OCP_CS_MASK \ +0x00003000 /* PSE_MDP_QOP_RL_OCP_CS[13..12] */ +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_QOP_RL_OCP_CS_SHFT 12 +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_QOP_Q_OPER_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_05_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_QOP_Q_OPER_CS_MASK \ +0x00000F00 /* PSE_MDP_QOP_Q_OPER_CS[11..8] */ +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_QOP_Q_OPER_CS_SHFT 8 +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_DOP_CACHE_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_05_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_DOP_CACHE_CS_MASK \ +0x00000030 /* PSE_MDP_DOP_CACHE_CS[5..4] */ +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_DOP_CACHE_CS_SHFT 4 +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_DOP_PBUF_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_05_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_DOP_PBUF_CS_MASK \ +0x00000007 /* PSE_MDP_DOP_PBUF_CS[2..0] */ +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_DOP_PBUF_CS_SHFT 0 + +/* +* ---PSE_SEEK_CR_06 (0x820C8000 + 0x3E8)--- +* PSE_SEC_DOP_PBUF_CS[2..0] - (RO) PSE debug state for SEC_DOP_PBUF_CS +* RESERVED3[3] - (RO) Reserved bits +* PSE_SEC_DOP_CACHE_CS[5..4] - (RO) PSE debug state for SEC_DOP_CACHE_CS +* RESERVED6[7..6] - (RO) Reserved bits +* PSE_SEC_QOP_Q_OPER_CS[11..8] - (RO) PSE debug state for SEC_QOP_Q_OPER_CS +* PSE_SEC_QOP_RL_OCP_CS[13..12] - (RO) PSE debug state for SEC_QOP_RL_OCP_CS +* RESERVED14[15..14] - (RO) Reserved bits +* PSE_SEC_QOP_PL_OCP_CS[17..16] - (RO) PSE debug state for SEC_QOP_PL_OCP_CS +* RESERVED18[19..18] - (RO) Reserved bits +* PSE_SEC_QOP_ALLOCATE_CS[22..20] - (RO) PSE debug state for +SEC_QOP_ALLOCATE_CS +* RESERVED23[31..23] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_QOP_ALLOCATE_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_06_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_QOP_ALLOCATE_CS_MASK \ +0x00700000 /* PSE_SEC_QOP_ALLOCATE_CS[22..20] */ +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_QOP_ALLOCATE_CS_SHFT 20 +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_QOP_PL_OCP_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_06_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_QOP_PL_OCP_CS_MASK \ +0x00030000 /* PSE_SEC_QOP_PL_OCP_CS[17..16] */ +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_QOP_PL_OCP_CS_SHFT 16 +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_QOP_RL_OCP_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_06_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_QOP_RL_OCP_CS_MASK \ +0x00003000 /* PSE_SEC_QOP_RL_OCP_CS[13..12] */ +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_QOP_RL_OCP_CS_SHFT 12 +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_QOP_Q_OPER_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_06_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_QOP_Q_OPER_CS_MASK \ +0x00000F00 /* PSE_SEC_QOP_Q_OPER_CS[11..8] */ +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_QOP_Q_OPER_CS_SHFT 8 +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_DOP_CACHE_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_06_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_DOP_CACHE_CS_MASK \ +0x00000030 /* PSE_SEC_DOP_CACHE_CS[5..4] */ +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_DOP_CACHE_CS_SHFT 4 +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_DOP_PBUF_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_06_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_DOP_PBUF_CS_MASK \ +0x00000007 /* PSE_SEC_DOP_PBUF_CS[2..0] */ +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_DOP_PBUF_CS_SHFT 0 + +/* +* ---PSE_SEEK_CR_07 (0x820C8000 + 0x3EC)--- +* PSE_PLE_DOP_PBUF_CS[2..0] - (RO) PSE debug state for PLE_DOP_PBUF_CS +* RESERVED3[3] - (RO) Reserved bits +* PSE_PLE_DOP_CACHE_CS[5..4] - (RO) PSE debug state for PLE_DOP_CACHE_CS +* RESERVED6[7..6] - (RO) Reserved bits +* PSE_PLE_QOP_Q_OPER_CS[11..8] - (RO) PSE debug state for PLE_QOP_Q_OPER_CS +* PSE_PLE_QOP_RL_OCP_CS[13..12] - (RO) PSE debug state for PLE_QOP_RL_OCP_CS +* RESERVED14[15..14] - (RO) Reserved bits +* PSE_PLE_QOP_PL_OCP_CS[17..16] - (RO) PSE debug state for PLE_QOP_PL_OCP_CS +* RESERVED18[19..18] - (RO) Reserved bits +* PSE_PLE_QOP_ALLOCATE_CS[22..20] - (RO) PSE debug state for +PLE_QOP_ALLOCATE_CS +* RESERVED23[31..23] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_QOP_ALLOCATE_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_07_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_QOP_ALLOCATE_CS_MASK \ +0x00700000 /* PSE_PLE_QOP_ALLOCATE_CS[22..20] */ +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_QOP_ALLOCATE_CS_SHFT 20 +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_QOP_PL_OCP_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_07_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_QOP_PL_OCP_CS_MASK \ +0x00030000 /* PSE_PLE_QOP_PL_OCP_CS[17..16] */ +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_QOP_PL_OCP_CS_SHFT 16 +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_QOP_RL_OCP_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_07_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_QOP_RL_OCP_CS_MASK \ +0x00003000 /* PSE_PLE_QOP_RL_OCP_CS[13..12] */ +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_QOP_RL_OCP_CS_SHFT 12 +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_QOP_Q_OPER_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_07_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_QOP_Q_OPER_CS_MASK \ +0x00000F00 /* PSE_PLE_QOP_Q_OPER_CS[11..8] */ +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_QOP_Q_OPER_CS_SHFT 8 +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_DOP_CACHE_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_07_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_DOP_CACHE_CS_MASK \ +0x00000030 /* PSE_PLE_DOP_CACHE_CS[5..4] */ +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_DOP_CACHE_CS_SHFT 4 +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_DOP_PBUF_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_07_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_DOP_PBUF_CS_MASK \ +0x00000007 /* PSE_PLE_DOP_PBUF_CS[2..0] */ +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_DOP_PBUF_CS_SHFT 0 + +/* +* ---PSE_SEEK_CR_08 (0x820C8000 + 0x3F0)--- +* PSE_AMSDU_DOP_PBUF_CS[2..0] - (RO) PSE debug state for AMSDU_DOP_PBUF_CS +* RESERVED3[3] - (RO) Reserved bits +* PSE_AMSDU_DOP_CACHE_CS[5..4] - (RO) PSE debug state for AMSDU_DOP_CACHE_CS +* RESERVED6[7..6] - (RO) Reserved bits +* CPU_Q_OP_CS[11..8] - (RO) PSE debug state for CPI_Q_OP_CS +* ARB_REQ_CS[14..12] - (RO) PSE debug state for ARB_REQ_CS +* RESERVED15[15] - (RO) Reserved bits +* APB_REQ_CS[18..16] - (RO) PSE debug state for APB_REQ_CS +* RESERVED19[31..19] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_SEEK_CR_08_APB_REQ_CS_ADDR WF_PSE_TOP_PSE_SEEK_CR_08_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_08_APB_REQ_CS_MASK \ +0x00070000 /* APB_REQ_CS[18..16] */ +#define WF_PSE_TOP_PSE_SEEK_CR_08_APB_REQ_CS_SHFT 16 +#define WF_PSE_TOP_PSE_SEEK_CR_08_ARB_REQ_CS_ADDR WF_PSE_TOP_PSE_SEEK_CR_08_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_08_ARB_REQ_CS_MASK \ +0x00007000 /* ARB_REQ_CS[14..12] */ +#define WF_PSE_TOP_PSE_SEEK_CR_08_ARB_REQ_CS_SHFT 12 +#define WF_PSE_TOP_PSE_SEEK_CR_08_CPU_Q_OP_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_08_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_08_CPU_Q_OP_CS_MASK \ +0x00000F00 /* CPU_Q_OP_CS[11..8] */ +#define WF_PSE_TOP_PSE_SEEK_CR_08_CPU_Q_OP_CS_SHFT 8 +#define WF_PSE_TOP_PSE_SEEK_CR_08_PSE_AMSDU_DOP_CACHE_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_08_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_08_PSE_AMSDU_DOP_CACHE_CS_MASK \ +0x00000030 /* PSE_AMSDU_DOP_CACHE_CS[5..4] */ +#define WF_PSE_TOP_PSE_SEEK_CR_08_PSE_AMSDU_DOP_CACHE_CS_SHFT 4 +#define WF_PSE_TOP_PSE_SEEK_CR_08_PSE_AMSDU_DOP_PBUF_CS_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_08_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_08_PSE_AMSDU_DOP_PBUF_CS_MASK \ +0x00000007 /* PSE_AMSDU_DOP_PBUF_CS[2..0] */ +#define WF_PSE_TOP_PSE_SEEK_CR_08_PSE_AMSDU_DOP_PBUF_CS_SHFT 0 + +/* +* ---PSE_SEEK_CR_09 (0x820C8000 + 0x3F4)--- +* RESERVED0[15..0] - (RO) Reserved bits +* DOUBLE_RLS_FID[27..16] - (RO) PSE double RLS FID PAGE +* RESERVED28[30..28] - (RO) Reserved bits +* DOUBLE_RLS_ERROR[31] - (RO) PSE double RLS error flag +*/ +#define WF_PSE_TOP_PSE_SEEK_CR_09_DOUBLE_RLS_ERROR_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_09_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_09_DOUBLE_RLS_ERROR_MASK \ +0x80000000 /* DOUBLE_RLS_ERROR[31] */ +#define WF_PSE_TOP_PSE_SEEK_CR_09_DOUBLE_RLS_ERROR_SHFT 31 +#define WF_PSE_TOP_PSE_SEEK_CR_09_DOUBLE_RLS_FID_ADDR \ +WF_PSE_TOP_PSE_SEEK_CR_09_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_09_DOUBLE_RLS_FID_MASK \ +0x0FFF0000 /* DOUBLE_RLS_FID[27..16] */ +#define WF_PSE_TOP_PSE_SEEK_CR_09_DOUBLE_RLS_FID_SHFT 16 + +#ifdef __cplusplus +} +#endif + +#endif /* __WF_PSE_TOP_REGS_H__ */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/mt7961/wf_wfdma_host_dma0.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/mt7961/wf_wfdma_host_dma0.h new file mode 100644 index 0000000000000000000000000000000000000000..115ead34a821aa66533cfd78911e79acd0f78162 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/mt7961/wf_wfdma_host_dma0.h @@ -0,0 +1,8406 @@ +/* [File] : wf_wfdma_host_dma0.h */ +/* [Revision time] : Thu May 30 10:53:24 2019 */ +/* [Description] : This file is auto generated by CODA */ +/* [Copyright] : Copyright (C) 2019 Mediatek Incorportion. All rights */ +/* reserved. */ + +#ifndef __WF_WFDMA_HOST_DMA0_REGS_H__ +#define __WF_WFDMA_HOST_DMA0_REGS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* ************************************************************************** */ +/* */ +/* WF_WFDMA_HOST_DMA0 CR Definitions */ +/* */ +/* ************************************************************************** */ + +#define WF_WFDMA_HOST_DMA0_BASE 0x7C024000 + +#define WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0XA0) /* 40A0 */ +#define WF_WFDMA_HOST_DMA0_HOST_IF_RX_DONE_STS_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0XA4) /* 40A4 */ +#define WF_WFDMA_HOST_DMA0_TX_DMAD_RNG_START_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x0B0) /* 40B0 */ +#define WF_WFDMA_HOST_DMA0_TX_DMAD_RNG_START_EXT_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x0B4) /* 40B4 */ +#define WF_WFDMA_HOST_DMA0_TX_DMAD_RNG_END_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x0B8) /* 40B8 */ +#define WF_WFDMA_HOST_DMA0_TX_DMAD_RNG_END_EXT_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x0BC) /* 40BC */ +#define WF_WFDMA_HOST_DMA0_RX_DMAD_RNG_START_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x0C0) /* 40C0 */ +#define WF_WFDMA_HOST_DMA0_RX_DMAD_RNG_START_EXT_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x0C4) /* 40C4 */ +#define WF_WFDMA_HOST_DMA0_RX_DMAD_RNG_END_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x0C8) /* 40C8 */ +#define WF_WFDMA_HOST_DMA0_RX_DMAD_RNG_END_EXT_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x0CC) /* 40CC */ +#define WF_WFDMA_HOST_DMA0_TX_PLD_RNG_START_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x0D0) /* 40D0 */ +#define WF_WFDMA_HOST_DMA0_TX_PLD_RNG_START_EXT_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x0D4) /* 40D4 */ +#define WF_WFDMA_HOST_DMA0_TX_PLD_RNG_END_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x0D8) /* 40D8 */ +#define WF_WFDMA_HOST_DMA0_TX_PLD_RNG_END_EXT_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x0DC) /* 40DC */ +#define WF_WFDMA_HOST_DMA0_RX_PLD_RNG_START_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x0E0) /* 40E0 */ +#define WF_WFDMA_HOST_DMA0_RX_PLD_RNG_START_EXT_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x0E4) /* 40E4 */ +#define WF_WFDMA_HOST_DMA0_RX_PLD_RNG_END_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x0E8) /* 40E8 */ +#define WF_WFDMA_HOST_DMA0_RX_PLD_RNG_END_EXT_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x0EC) /* 40EC */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_RST_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x100) /* 4100 */ +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0X108) /* 4108 */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x10C) /* 410C */ +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0X110) /* 4110 */ +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0X114) /* 4114 */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DUMMY_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x120) /* 4120 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_DBG_IDX_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x124) /* 4124 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_DBG_PROBE_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x128) /* 4128 */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x12C) /* 412C */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_PROBE_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x130) /* 4130 */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DMASHDL_DBG_PROBE_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x134) /* 4134 */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x138) /* 4138 */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x13c) /* 413C */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_FIFO_TEST_MOD_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x140) /* 4140 */ +#define WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x1E8) /* 41E8 */ +#define WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x1EC) /* 41EC */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x1F0) /* 41F0 */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x1F4) /* 41F4 */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x1F8) /* 41F8 */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x1FC) /* 41FC */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x200) /* 4200 */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0X204) /* 4204 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x208) /* 4208 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x20C) /* 420C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_TX_Q_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x224) /* 4224 */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0X228) /* 4228 */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0X22C) /* 422C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x230) /* 4230 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_MISC_CFG_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x234) /* 4234 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x240) /* 4240 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH10_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x260) /* 4260 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH32_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x264) /* 4264 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH54_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x268) /* 4268 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH76_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x26C) /* 426C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x280) /* 4280 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x284) /* 4284 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_EXT_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x288) /* 4288 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x298) /* 4298 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x29C) /* 429C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_DBG0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x2A0) /* 42A0 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_DBG1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x2A4) /* 42A4 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_DBG0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x2A8) /* 42A8 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_DBG1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x2AC) /* 42AC */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x2B0) /* 42B0 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x2B4) /* 42B4 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x2B8) /* 42B8 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x2D0) /* 42D0 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x2D4) /* 42D4 */ +#define WF_WFDMA_HOST_DMA0_HOST_PRI_INT_STA_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x2E0) /* 42E0 */ +#define WF_WFDMA_HOST_DMA0_HOST_PER_INT_ENA_STA_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x2E4) /* 42E4 */ +#define WF_WFDMA_HOST_DMA0_HOST_PER_DLY_INT_CFG_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x2E8) /* 42E8 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x2F0) /* 42F0 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x300) /* 4300 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x304) /* 4304 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x308) /* 4308 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL3_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x30c) /* 430C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x310) /* 4310 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x314) /* 4314 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x318) /* 4318 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL3_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x31c) /* 431C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x320) /* 4320 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x324) /* 4324 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x328) /* 4328 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL3_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x32c) /* 432C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x330) /* 4330 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x334) /* 4334 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x338) /* 4338 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL3_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x33c) /* 433C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x340) /* 4340 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x344) /* 4344 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x348) /* 4348 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_CTRL3_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x34c) /* 434C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x350) /* 4350 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x354) /* 4354 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x358) /* 4358 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_CTRL3_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x35c) /* 435C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x360) /* 4360 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x364) /* 4364 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x368) /* 4368 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_CTRL3_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x36c) /* 436C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x370) /* 4370 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x374) /* 4374 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x378) /* 4378 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_CTRL3_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x37c) /* 437C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x380) /* 4380 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x384) /* 4384 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x388) /* 4388 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_CTRL3_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x38c) /* 438C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x390) /* 4390 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x394) /* 4394 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x398) /* 4398 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_CTRL3_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x39c) /* 439C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x3a0) /* 43A0 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x3a4) /* 43A4 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x3a8) /* 43A8 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_CTRL3_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x3ac) /* 43AC */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x3b0) /* 43B0 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x3b4) /* 43B4 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x3b8) /* 43B8 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_CTRL3_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x3bc) /* 43BC */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x3c0) /* 43C0 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x3c4) /* 43C4 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x3c8) /* 43C8 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_CTRL3_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x3cc) /* 43CC */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x3d0) /* 43D0 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x3d4) /* 43D4 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x3d8) /* 43D8 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_CTRL3_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x3dc) /* 43DC */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x3e0) /* 43E0 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x3e4) /* 43E4 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x3e8) /* 43E8 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_CTRL3_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x3ec) /* 43EC */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x3f0) /* 43F0 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x3f4) /* 43F4 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x3f8) /* 43F8 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_CTRL3_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x3fc) /* 43FC */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x400) /* 4400 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x404) /* 4404 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x408) /* 4408 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_CTRL3_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x40c) /* 440C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x410) /* 4410 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x414) /* 4414 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x418) /* 4418 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_CTRL3_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x41c) /* 441C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x420) /* 4420 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x424) /* 4424 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x428) /* 4428 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_CTRL3_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x42c) /* 442C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x500) /* 4500 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x504) /* 4504 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x508) /* 4508 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL3_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x50c) /* 450C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x510) /* 4510 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x514) /* 4514 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x518) /* 4518 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL3_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x51c) /* 451C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x520) /* 4520 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x524) /* 4524 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x528) /* 4528 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL3_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x52C) /* 452C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x530) /* 4530 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x534) /* 4534 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x538) /* 4538 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL3_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x53C) /* 453C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x540) /* 4540 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x544) /* 4544 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x548) /* 4548 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL3_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x54c) /* 454C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x550) /* 4550 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x554) /* 4554 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x558) /* 4558 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL3_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x55c) /* 455C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x560) /* 4560 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x564) /* 4564 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x568) /* 4568 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL3_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x56C) /* 456C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x570) /* 4570 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x574) /* 4574 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x578) /* 4578 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL3_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x57C) /* 457C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_EXT_CTRL_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x600) /* 4600 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_EXT_CTRL_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x604) /* 4604 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_EXT_CTRL_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x608) /* 4608 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_EXT_CTRL_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x60C) /* 460C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_EXT_CTRL_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x610) /* 4610 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_EXT_CTRL_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x614) /* 4614 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_EXT_CTRL_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x618) /* 4618 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_EXT_CTRL_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x61C) /* 461C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_EXT_CTRL_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x620) /* 4620 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_EXT_CTRL_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x624) /* 4624 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_EXT_CTRL_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x628) /* 4628 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_EXT_CTRL_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x62C) /* 462C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_EXT_CTRL_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x630) /* 4630 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_EXT_CTRL_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x634) /* 4634 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_EXT_CTRL_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x638) /* 4638 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_EXT_CTRL_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x63C) /* 463C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_EXT_CTRL_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x640) /* 4640 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_EXT_CTRL_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x644) /* 4644 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_EXT_CTRL_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x648) /* 4648 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_EXT_CTRL_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x680) /* 4680 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_EXT_CTRL_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x684) /* 4684 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_EXT_CTRL_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x688) /* 4688 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_EXT_CTRL_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x68C) /* 468C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_EXT_CTRL_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x690) /* 4690 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_EXT_CTRL_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x694) /* 4694 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_EXT_CTRL_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x698) /* 4698 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_EXT_CTRL_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0x69C) /* 469C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xA00) /* 4A00 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xA04) /* 4A04 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xA08) /* 4A08 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xA10) /* 4A10 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xA14) /* 4A14 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xA18) /* 4A18 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xA20) /* 4A20 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xA24) /* 4A24 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xA28) /* 4A28 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xA30) /* 4A30 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xA34) /* 4A34 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xA38) /* 4A38 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_BKRS_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xA40) /* 4A40 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_BKRS_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xA44) /* 4A44 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_BKRS_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xA48) /* 4A48 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_BKRS_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xA50) /* 4A50 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_BKRS_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xA54) /* 4A54 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_BKRS_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xA58) /* 4A58 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_BKRS_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xA60) /* 4A60 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_BKRS_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xA64) /* 4A64 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_BKRS_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xA68) /* 4A68 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_BKRS_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xA70) /* 4A70 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_BKRS_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xA74) /* 4A74 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_BKRS_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xA78) /* 4A78 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_BKRS_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xA80) /* 4A80 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_BKRS_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xA84) /* 4A84 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_BKRS_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xA88) /* 4A88 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_BKRS_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xA90) /* 4A90 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_BKRS_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xA94) /* 4A94 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_BKRS_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xA98) /* 4A98 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_BKRS_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xAA0) /* 4AA0 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_BKRS_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xAA4) /* 4AA4 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_BKRS_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xAA8) /* 4AA8 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_BKRS_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xAB0) /* 4AB0 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_BKRS_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xAB4) /* 4AB4 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_BKRS_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xAB8) /* 4AB8 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_BKRS_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xAC0) /* 4AC0 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_BKRS_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xAC4) /* 4AC4 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_BKRS_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xAC8) /* 4AC8 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_BKRS_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xAD0) /* 4AD0 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_BKRS_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xAD4) /* 4AD4 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_BKRS_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xAD8) /* 4AD8 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_BKRS_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xAE0) /* 4AE0 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_BKRS_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xAE4) /* 4AE4 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_BKRS_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xAE8) /* 4AE8 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_BKRS_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xAF0) /* 4AF0 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_BKRS_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xAF4) /* 4AF4 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_BKRS_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xAF8) /* 4AF8 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_BKRS_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xB00) /* 4B00 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_BKRS_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xB04) /* 4B04 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_BKRS_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xB08) /* 4B08 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_BKRS_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xB10) /* 4B10 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_BKRS_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xB14) /* 4B14 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_BKRS_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xB18) /* 4B18 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_BKRS_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xB20) /* 4B20 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_BKRS_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xB24) /* 4B24 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_BKRS_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xB28) /* 4B28 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xC00) /* 4C00 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xC04) /* 4C04 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xC08) /* 4C08 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xC10) /* 4C10 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xC14) /* 4C14 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xC18) /* 4C18 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xC20) /* 4C20 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xC24) /* 4C24 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xC28) /* 4C28 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xC30) /* 4C30 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xC34) /* 4C34 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xC38) /* 4C38 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xC40) /* 4C40 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xC44) /* 4C44 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xC48) /* 4C48 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xC50) /* 4C50 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xC54) /* 4C54 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xC58) /* 4C58 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xC60) /* 4C60 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xC64) /* 4C64 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xC68) /* 4C68 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xC70) /* 4C70 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xC74) /* 4C74 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xC78) /* 4C78 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING8_BKRS_CTRL0_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xC80) /* 4C80 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING8_BKRS_CTRL1_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xC84) /* 4C84 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING8_BKRS_CTRL2_ADDR \ +(WF_WFDMA_HOST_DMA0_BASE + 0xC88) /* 4C88 */ + +/* +* ---HOST_IF_TX_DONE_STS (0x18024000 + 0XA0)--- +* fifo_dfet_txdone_dat0_done_sts[0] - (W1C) USB DAT0 FIFO Tx status +* 0 : no tx done +* 1 : pdma fetch data from USB endpoint +buffer +* fifo_dfet_txdone_dat1_done_sts[1] - (W1C) USB DAT1 FIFO Tx status +* 0 : no tx done +* 1 : pdma fetch data from USB endpoint +buffer +* fifo_dfet_txdone_dat2_done_sts[2] - (W1C) USB DAT2 FIFO Tx status +* 0 : no tx done +* 1 : pdma fetch data from USB endpoint +buffer +* fifo_dfet_txdone_dat3_done_sts[3] - (W1C) USB DAT3 FIFO Tx status +* 0 : no tx done +* 1 : pdma fetch data from USB endpoint +buffer +* fifo_dfet_txdone_dat4_done_sts[4] - (W1C) USB DAT4 FIFO Tx status +* 0 : no tx done +* 1 : pdma fetch data from USB endpoint +buffer +* fifo_dfet_txdone_cmd_done_sts[5] - (W1C) USB CMD FIFO Tx status +* 0 : no tx done +* 1 : pdma fetch data from USB endpoint +buffer +* fifo_dfet_txdone_fwdl_done_sts[6] - (W1C) USB Firmware download FIFO Tx +status +* 0 : no tx done +* 1 : pdma fetch data from USB endpoint +buffer +* SDIO Mode (All SDIO Tx packet goto firmware +* download FIFO) +* 0 : no tx done +* 1 : pdma start to fetch data from SDIO +buffer +* RESERVED7[31..7] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_fwdl_done_sts_ADDR \ + \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_ADDR +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_fwdl_done_sts_MASK \ + \ +0x00000040 /* fifo_dfet_txdone_fwdl_done_sts[6] */ +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_fwdl_done_sts_SHFT \ + \ +6 +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_cmd_done_sts_ADDR \ + \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_ADDR +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_cmd_done_sts_MASK \ + \ +0x00000020 /* fifo_dfet_txdone_cmd_done_sts[5] */ +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_cmd_done_sts_SHFT \ + \ +5 +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat4_done_sts_ADDR \ + \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_ADDR +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat4_done_sts_MASK \ + \ +0x00000010 /* fifo_dfet_txdone_dat4_done_sts[4] */ +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat4_done_sts_SHFT \ + \ +4 +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat3_done_sts_ADDR \ + \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_ADDR +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat3_done_sts_MASK \ + \ +0x00000008 /* fifo_dfet_txdone_dat3_done_sts[3] */ +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat3_done_sts_SHFT \ + \ +3 +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat2_done_sts_ADDR \ + \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_ADDR +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat2_done_sts_MASK \ + \ +0x00000004 /* fifo_dfet_txdone_dat2_done_sts[2] */ +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat2_done_sts_SHFT \ + \ +2 +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat1_done_sts_ADDR \ + \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_ADDR +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat1_done_sts_MASK \ + \ +0x00000002 /* fifo_dfet_txdone_dat1_done_sts[1] */ +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat1_done_sts_SHFT \ + \ +1 +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat0_done_sts_ADDR \ + \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_ADDR +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat0_done_sts_MASK \ + \ +0x00000001 /* fifo_dfet_txdone_dat0_done_sts[0] */ +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat0_done_sts_SHFT \ + \ +0 + +/* +* ---HOST_IF_RX_DONE_STS (0x18024000 + 0XA4)--- +* RESERVED0[0] - (RO) Reserved bits +* rx1_packet_done_sts[1] - (W1C) USB/SDIO Rx1 packet done status +* 0 : no rx packet done +* 1 : rx packet send to host interface +* Note : All SDIO Packet send to SIDO RX0 +port +* RESERVED2[31..2] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_HOST_IF_RX_DONE_STS_rx1_packet_done_sts_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_IF_RX_DONE_STS_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_IF_RX_DONE_STS_rx1_packet_done_sts_MASK \ +0x00000002 /* rx1_packet_done_sts[1] */ +#define WF_WFDMA_HOST_DMA0_HOST_IF_RX_DONE_STS_rx1_packet_done_sts_SHFT 1 + +/* +* ---TX_DMAD_RNG_START (0x18024000 + 0x0B0)--- +* tx_dmad_rng_start[31..0] - (RW) TX DMAD address range start [31:0] +*/ +#define WF_WFDMA_HOST_DMA0_TX_DMAD_RNG_START_tx_dmad_rng_start_ADDR \ +WF_WFDMA_HOST_DMA0_TX_DMAD_RNG_START_ADDR +#define WF_WFDMA_HOST_DMA0_TX_DMAD_RNG_START_tx_dmad_rng_start_MASK \ +0xFFFFFFFF /* tx_dmad_rng_start[31..0] */ +#define WF_WFDMA_HOST_DMA0_TX_DMAD_RNG_START_tx_dmad_rng_start_SHFT 0 + +/* +* ---TX_DMAD_RNG_START_EXT (0x18024000 + 0x0B4)--- +* tx_dmad_rng_start_ext[3..0] - (RW) TX DMAD address range start [35:32] +* RESERVED4[31..4] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_TX_DMAD_RNG_START_EXT_tx_dmad_rng_start_ext_ADDR \ +WF_WFDMA_HOST_DMA0_TX_DMAD_RNG_START_EXT_ADDR +#define WF_WFDMA_HOST_DMA0_TX_DMAD_RNG_START_EXT_tx_dmad_rng_start_ext_MASK \ +0x0000000F /* tx_dmad_rng_start_ext[3..0] */ +#define WF_WFDMA_HOST_DMA0_TX_DMAD_RNG_START_EXT_tx_dmad_rng_start_ext_SHFT 0 + +/* +* ---TX_DMAD_RNG_END (0x18024000 + 0x0B8)--- +* tx_dmad_rng_end[31..0] - (RW) TX DMAD address range end [31:0] +*/ +#define WF_WFDMA_HOST_DMA0_TX_DMAD_RNG_END_tx_dmad_rng_end_ADDR \ +WF_WFDMA_HOST_DMA0_TX_DMAD_RNG_END_ADDR +#define WF_WFDMA_HOST_DMA0_TX_DMAD_RNG_END_tx_dmad_rng_end_MASK \ +0xFFFFFFFF /* tx_dmad_rng_end[31..0] */ +#define WF_WFDMA_HOST_DMA0_TX_DMAD_RNG_END_tx_dmad_rng_end_SHFT 0 + +/* +* ---TX_DMAD_RNG_END_EXT (0x18024000 + 0x0BC)--- +* tx_dmad_rng_end_ext[3..0] - (RW) TX DMAD address range end [35:32] +* RESERVED4[31..4] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_TX_DMAD_RNG_END_EXT_tx_dmad_rng_end_ext_ADDR \ +WF_WFDMA_HOST_DMA0_TX_DMAD_RNG_END_EXT_ADDR +#define WF_WFDMA_HOST_DMA0_TX_DMAD_RNG_END_EXT_tx_dmad_rng_end_ext_MASK \ +0x0000000F /* tx_dmad_rng_end_ext[3..0] */ +#define WF_WFDMA_HOST_DMA0_TX_DMAD_RNG_END_EXT_tx_dmad_rng_end_ext_SHFT 0 + +/* +* ---RX_DMAD_RNG_START (0x18024000 + 0x0C0)--- +* rx_dmad_rng_start[31..0] - (RW) RX DMAD address range start [31:0] +*/ +#define WF_WFDMA_HOST_DMA0_RX_DMAD_RNG_START_rx_dmad_rng_start_ADDR \ +WF_WFDMA_HOST_DMA0_RX_DMAD_RNG_START_ADDR +#define WF_WFDMA_HOST_DMA0_RX_DMAD_RNG_START_rx_dmad_rng_start_MASK \ +0xFFFFFFFF /* rx_dmad_rng_start[31..0] */ +#define WF_WFDMA_HOST_DMA0_RX_DMAD_RNG_START_rx_dmad_rng_start_SHFT 0 + +/* +* ---RX_DMAD_RNG_START_EXT (0x18024000 + 0x0C4)--- +* rx_dmad_rng_start_ext[3..0] - (RW) RX DMAD address range start [35:32] +* RESERVED4[31..4] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_RX_DMAD_RNG_START_EXT_rx_dmad_rng_start_ext_ADDR \ +WF_WFDMA_HOST_DMA0_RX_DMAD_RNG_START_EXT_ADDR +#define WF_WFDMA_HOST_DMA0_RX_DMAD_RNG_START_EXT_rx_dmad_rng_start_ext_MASK \ +0x0000000F /* rx_dmad_rng_start_ext[3..0] */ +#define WF_WFDMA_HOST_DMA0_RX_DMAD_RNG_START_EXT_rx_dmad_rng_start_ext_SHFT 0 + +/* +* ---RX_DMAD_RNG_END (0x18024000 + 0x0C8)--- +* rx_dmad_rng_end[31..0] - (RW) RX DMAD address range end [31:0] +*/ +#define WF_WFDMA_HOST_DMA0_RX_DMAD_RNG_END_rx_dmad_rng_end_ADDR \ +WF_WFDMA_HOST_DMA0_RX_DMAD_RNG_END_ADDR +#define WF_WFDMA_HOST_DMA0_RX_DMAD_RNG_END_rx_dmad_rng_end_MASK \ +0xFFFFFFFF /* rx_dmad_rng_end[31..0] */ +#define WF_WFDMA_HOST_DMA0_RX_DMAD_RNG_END_rx_dmad_rng_end_SHFT 0 + +/* +* ---RX_DMAD_RNG_END_EXT (0x18024000 + 0x0CC)--- +* rx_dmad_rng_end_ext[3..0] - (RW) RX DMAD address range end [35:32] +* RESERVED4[31..4] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_RX_DMAD_RNG_END_EXT_rx_dmad_rng_end_ext_ADDR \ +WF_WFDMA_HOST_DMA0_RX_DMAD_RNG_END_EXT_ADDR +#define WF_WFDMA_HOST_DMA0_RX_DMAD_RNG_END_EXT_rx_dmad_rng_end_ext_MASK \ +0x0000000F /* rx_dmad_rng_end_ext[3..0] */ +#define WF_WFDMA_HOST_DMA0_RX_DMAD_RNG_END_EXT_rx_dmad_rng_end_ext_SHFT 0 + +/* +* ---TX_PLD_RNG_START (0x18024000 + 0x0D0)--- +* tx_pld_rng_start[31..0] - (RW) TX PLD address range start [31:0] +*/ +#define WF_WFDMA_HOST_DMA0_TX_PLD_RNG_START_tx_pld_rng_start_ADDR \ +WF_WFDMA_HOST_DMA0_TX_PLD_RNG_START_ADDR +#define WF_WFDMA_HOST_DMA0_TX_PLD_RNG_START_tx_pld_rng_start_MASK \ +0xFFFFFFFF /* tx_pld_rng_start[31..0] */ +#define WF_WFDMA_HOST_DMA0_TX_PLD_RNG_START_tx_pld_rng_start_SHFT 0 + +/* +* ---TX_PLD_RNG_START_EXT (0x18024000 + 0x0D4)--- +* tx_pld_rng_start_ext[3..0] - (RW) TX PLD address range start [35:32] +* RESERVED4[31..4] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_TX_PLD_RNG_START_EXT_tx_pld_rng_start_ext_ADDR \ +WF_WFDMA_HOST_DMA0_TX_PLD_RNG_START_EXT_ADDR +#define WF_WFDMA_HOST_DMA0_TX_PLD_RNG_START_EXT_tx_pld_rng_start_ext_MASK \ +0x0000000F /* tx_pld_rng_start_ext[3..0] */ +#define WF_WFDMA_HOST_DMA0_TX_PLD_RNG_START_EXT_tx_pld_rng_start_ext_SHFT 0 + +/* +* ---TX_PLD_RNG_END (0x18024000 + 0x0D8)--- +* tx_pld_rng_end[31..0] - (RW) TX PLD address range end [31:0] +*/ +#define WF_WFDMA_HOST_DMA0_TX_PLD_RNG_END_tx_pld_rng_end_ADDR \ +WF_WFDMA_HOST_DMA0_TX_PLD_RNG_END_ADDR +#define WF_WFDMA_HOST_DMA0_TX_PLD_RNG_END_tx_pld_rng_end_MASK \ +0xFFFFFFFF /* tx_pld_rng_end[31..0] */ +#define WF_WFDMA_HOST_DMA0_TX_PLD_RNG_END_tx_pld_rng_end_SHFT 0 + +/* +* ---TX_PLD_RNG_END_EXT (0x18024000 + 0x0DC)--- +* tx_pld_rng_end_ext[3..0] - (RW) TX PLD address range end [35:32] +* RESERVED4[31..4] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_TX_PLD_RNG_END_EXT_tx_pld_rng_end_ext_ADDR \ +WF_WFDMA_HOST_DMA0_TX_PLD_RNG_END_EXT_ADDR +#define WF_WFDMA_HOST_DMA0_TX_PLD_RNG_END_EXT_tx_pld_rng_end_ext_MASK \ +0x0000000F /* tx_pld_rng_end_ext[3..0] */ +#define WF_WFDMA_HOST_DMA0_TX_PLD_RNG_END_EXT_tx_pld_rng_end_ext_SHFT 0 + +/* +* ---RX_PLD_RNG_START (0x18024000 + 0x0E0)--- +* rx_pld_rng_start[31..0] - (RW) RX PLD address range start [31:0] +*/ +#define WF_WFDMA_HOST_DMA0_RX_PLD_RNG_START_rx_pld_rng_start_ADDR \ +WF_WFDMA_HOST_DMA0_RX_PLD_RNG_START_ADDR +#define WF_WFDMA_HOST_DMA0_RX_PLD_RNG_START_rx_pld_rng_start_MASK \ +0xFFFFFFFF /* rx_pld_rng_start[31..0] */ +#define WF_WFDMA_HOST_DMA0_RX_PLD_RNG_START_rx_pld_rng_start_SHFT 0 + +/* +* ---RX_PLD_RNG_START_EXT (0x18024000 + 0x0E4)--- +* rx_pld_rng_start_ext[3..0] - (RW) RX PLD address range start [35:32] +* RESERVED4[31..4] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_RX_PLD_RNG_START_EXT_rx_pld_rng_start_ext_ADDR \ +WF_WFDMA_HOST_DMA0_RX_PLD_RNG_START_EXT_ADDR +#define WF_WFDMA_HOST_DMA0_RX_PLD_RNG_START_EXT_rx_pld_rng_start_ext_MASK \ +0x0000000F /* rx_pld_rng_start_ext[3..0] */ +#define WF_WFDMA_HOST_DMA0_RX_PLD_RNG_START_EXT_rx_pld_rng_start_ext_SHFT 0 + +/* +* ---RX_PLD_RNG_END (0x18024000 + 0x0E8)--- +* rx_pld_rng_end[31..0] - (RW) RX PLD address range end [31:0] +*/ +#define WF_WFDMA_HOST_DMA0_RX_PLD_RNG_END_rx_pld_rng_end_ADDR \ +WF_WFDMA_HOST_DMA0_RX_PLD_RNG_END_ADDR +#define WF_WFDMA_HOST_DMA0_RX_PLD_RNG_END_rx_pld_rng_end_MASK \ +0xFFFFFFFF /* rx_pld_rng_end[31..0] */ +#define WF_WFDMA_HOST_DMA0_RX_PLD_RNG_END_rx_pld_rng_end_SHFT 0 + +/* +* ---RX_PLD_RNG_END_EXT (0x18024000 + 0x0EC)--- +* rx_pld_rng_end_ext[3..0] - (RW) RX PLD address range end [35:32] +* RESERVED4[31..4] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_RX_PLD_RNG_END_EXT_rx_pld_rng_end_ext_ADDR \ +WF_WFDMA_HOST_DMA0_RX_PLD_RNG_END_EXT_ADDR +#define WF_WFDMA_HOST_DMA0_RX_PLD_RNG_END_EXT_rx_pld_rng_end_ext_MASK \ +0x0000000F /* rx_pld_rng_end_ext[3..0] */ +#define WF_WFDMA_HOST_DMA0_RX_PLD_RNG_END_EXT_rx_pld_rng_end_ext_SHFT 0 + +/* +* ---CONN_HIF_RST (0x18024000 + 0x100)--- +* RESERVED0[3..0] - (RO) Reserved bits +* conn_hif_logic_rst_n[4] - (RW) This conn_hif_logic_rst_n would reset +* wpdma logic partial control register, include Tx/Rx ring control. +* Also, conn_hif_logic_rst_n would reset wifi +* data path, include tx fifo, rx fifo, r2x_bridge, axi_mux and other other +* asynchronous bridge. +* (Note : conn_hif_logic_rst_n would not +* reset hif_dmashdl logic) +* dmashdl_all_rst_n[5] - (RW) This dmashdl_all_rst_n would reset +* hif_dmashdl_top, include logic and control register. +* RESERVED6[31..6] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_RST_dmashdl_all_rst_n_ADDR \ +WF_WFDMA_HOST_DMA0_CONN_HIF_RST_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_RST_dmashdl_all_rst_n_MASK \ +0x00000020 /* dmashdl_all_rst_n[5] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_RST_dmashdl_all_rst_n_SHFT 5 +#define WF_WFDMA_HOST_DMA0_CONN_HIF_RST_conn_hif_logic_rst_n_ADDR \ +WF_WFDMA_HOST_DMA0_CONN_HIF_RST_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_RST_conn_hif_logic_rst_n_MASK \ +0x00000010 /* conn_hif_logic_rst_n[4] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_RST_conn_hif_logic_rst_n_SHFT 4 + +/* +* ---HOST2MCU_SW_INT_SET (0x18024000 + 0X108)--- +* host2mcu_sw_int_0_set[0] - (WO) Driver set this bit to generate MCU +* interrupt and 0x5000_0110[0] will be set to 1. +* host2mcu_sw_int_1_set[1] - (WO) Driver set this bit to generate MCU +* interrupt and 0x5000_0110[1] will be set to 1. +* host2mcu_sw_int_2_set[2] - (WO) Driver set this bit to generate MCU +* interrupt and 0x5000_0110[2] will be set to 1. +* host2mcu_sw_int_3_set[3] - (WO) Driver set [0x0_4108] bit[3] to generate +* MCU interrupt and 0x5000_0110[3] will be set to 1. +* host2mcu_sw_int_4_set[4] - (WO) Driver set [0x0_4108] bit[4] to generate +* MCU interrupt and 0x5000_0110[4] will be set to 1. +* host2mcu_sw_int_5_set[5] - (WO) Driver set [0x0_4108] bit[5] to generate +* MCU interrupt and 0x5000_0110[5] will be set to 1. +* host2mcu_sw_int_6_set[6] - (WO) Driver set [0x0_4108] bit[6] to generate +* MCU interrupt and 0x5000_0110[6] will be set to 1. +* host2mcu_sw_int_7_set[7] - (WO) Driver set [0x0_4108] bit[7] to generate +* MCU interrupt and 0x5000_0110[7] will be set to 1. +* RESERVED8[31..8] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_7_set_ADDR \ +WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_7_set_MASK \ +0x00000080 /* host2mcu_sw_int_7_set[7] */ +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_7_set_SHFT 7 +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_6_set_ADDR \ +WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_6_set_MASK \ +0x00000040 /* host2mcu_sw_int_6_set[6] */ +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_6_set_SHFT 6 +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_5_set_ADDR \ +WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_5_set_MASK \ +0x00000020 /* host2mcu_sw_int_5_set[5] */ +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_5_set_SHFT 5 +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_4_set_ADDR \ +WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_4_set_MASK \ +0x00000010 /* host2mcu_sw_int_4_set[4] */ +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_4_set_SHFT 4 +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_3_set_ADDR \ +WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_3_set_MASK \ +0x00000008 /* host2mcu_sw_int_3_set[3] */ +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_3_set_SHFT 3 +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_2_set_ADDR \ +WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_2_set_MASK \ +0x00000004 /* host2mcu_sw_int_2_set[2] */ +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_2_set_SHFT 2 +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_1_set_ADDR \ +WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_1_set_MASK \ +0x00000002 /* host2mcu_sw_int_1_set[1] */ +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_1_set_SHFT 1 +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_0_set_ADDR \ +WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_0_set_MASK \ +0x00000001 /* host2mcu_sw_int_0_set[0] */ +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_0_set_SHFT 0 + +/* +* ---MCU2HOST_SW_INT_SET (0x18024000 + 0x10C)--- +* mcu2host_sw_int_set_0[0] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[0] to check +* interrupt status +* mcu2host_sw_int_set_1[1] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[1] to check +* interrupt status +* mcu2host_sw_int_set_2[2] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[2] to check +* interrupt status +* mcu2host_sw_int_set_3[3] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[3] to check +* interrupt status +* mcu2host_sw_int_set_4[4] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[4] to check +* interrupt status +* mcu2host_sw_int_set_5[5] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[5] to check +* interrupt status +* mcu2host_sw_int_set_6[6] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[6] to check +* interrupt status +* mcu2host_sw_int_set_7[7] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[7] to check +* interrupt status +* mcu2host_sw_int_set_8[8] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[0] to check +* interrupt status +* mcu2host_sw_int_set_9[9] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[1] to check +* interrupt status +* mcu2host_sw_int_set_10[10] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[2] to check +* interrupt status +* mcu2host_sw_int_set_11[11] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[3] to check +* interrupt status +* mcu2host_sw_int_set_12[12] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[4] to check +* interrupt status +* mcu2host_sw_int_set_13[13] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[5] to check +* interrupt status +* mcu2host_sw_int_set_14[14] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[6] to check +* interrupt status +* mcu2host_sw_int_set_15[15] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[7] to check +* interrupt status +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_15_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_15_MASK \ +0x00008000 /* mcu2host_sw_int_set_15[15] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_15_SHFT 15 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_14_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_14_MASK \ +0x00004000 /* mcu2host_sw_int_set_14[14] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_14_SHFT 14 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_13_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_13_MASK \ +0x00002000 /* mcu2host_sw_int_set_13[13] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_13_SHFT 13 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_12_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_12_MASK \ +0x00001000 /* mcu2host_sw_int_set_12[12] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_12_SHFT 12 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_11_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_11_MASK \ +0x00000800 /* mcu2host_sw_int_set_11[11] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_11_SHFT 11 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_10_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_10_MASK \ +0x00000400 /* mcu2host_sw_int_set_10[10] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_10_SHFT 10 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_9_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_9_MASK \ +0x00000200 /* mcu2host_sw_int_set_9[9] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_9_SHFT 9 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_8_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_8_MASK \ +0x00000100 /* mcu2host_sw_int_set_8[8] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_8_SHFT 8 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_7_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_7_MASK \ +0x00000080 /* mcu2host_sw_int_set_7[7] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_7_SHFT 7 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_6_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_6_MASK \ +0x00000040 /* mcu2host_sw_int_set_6[6] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_6_SHFT 6 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_5_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_5_MASK \ +0x00000020 /* mcu2host_sw_int_set_5[5] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_5_SHFT 5 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_4_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_4_MASK \ +0x00000010 /* mcu2host_sw_int_set_4[4] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_4_SHFT 4 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_3_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_3_MASK \ +0x00000008 /* mcu2host_sw_int_set_3[3] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_3_SHFT 3 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_2_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_2_MASK \ +0x00000004 /* mcu2host_sw_int_set_2[2] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_2_SHFT 2 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_1_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_1_MASK \ +0x00000002 /* mcu2host_sw_int_set_1[1] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_1_SHFT 1 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_0_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_0_MASK \ +0x00000001 /* mcu2host_sw_int_set_0[0] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_0_SHFT 0 + +/* +* ---MCU_INT_STA (0x18024000 + 0X110)--- +* host2mcu_sw_int_sts[7..0] - (W1C) MCU interrupt status, write 1 to clear +* the interrupt +* wpdma_tx_timeout_int_sts[8] - (W1C) WPDMA TX dma timeout interrupt stauts, +* write 1 to clear the interrupt +* wpdma_rx_timeout_int_sts[9] - (W1C) WPDMA RX dma timeout interrupt stauts, +* write 1 to clear the interrupt +* wifi_txfifo0_wr_ovf_int_sts[10] - (W1C) conn_hif txfifo erorr detec +* interruptt. It indicate tx-fifo memory write overflow. +* wifi_txfifo1_wr_ovf_int_sts[11] - (W1C) conn_hif txfifo erorr detec +* interruptt. It indicate tx-fifo memory write overflow. +* wifi_rxfifo_wr_ovf_int_sts[12] - (W1C) conn_hif rxfifo erorr detect +* interrupt. It indicate rx-fifo memory write overflow. +* wpdma_tx_dmad_mem_range_err_mcu_int_sts[13] - (W1C) WPDMA tx dma descriptor +* memory range error detection mcu interrupt status +* When user setup WPDMA_TX_DMAD_RNG (not +* equal to zero), design would check tx_dmad address. If address range not +* correct, it would alarm memory range error interrupt +* wpdma_rx_dmad_mem_range_err_mcu_int_sts[14] - (W1C) WPDMA rx dma descriptor +* memory range error detection mcu interrupt status +* When user setup WPDMA_RX_DMAD_RNG (not +* equal to zero), design would check rx_dmad address. If address range not +* correct, it would alarm memory range error interrupt +* wpdma_tx_payload_mem_range_err_mcu_int_sts[15] - (W1C) WPDMA tx payload +* memory range error detection mcu interrupt status +* When user setup WPDMA_TX_PLD_RNG (not equal +* to zero), design would check tx_dma payload address. If address range not +* correct, it would alarm memory range error interrupt +* wpdma_rx_payload_mem_range_err_mcu_int_sts[16] - (W1C) WPDMA rx payload +* memory range error detection mcu interrupt status +* When user setup WPDMA_RX_PLD_RNG (not equal +* to zero), design would check rx_dma payload address. If address range not +* correct, it would alarm memory range error interrupt +* RESERVED17[31..17] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_rx_payload_mem_range_err_mcu_int_sts_ADDR \ + \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_rx_payload_mem_range_err_mcu_int_sts_MASK \ + \ +0x00010000 /* wpdma_rx_payload_mem_range_err_mcu_int_sts[16] */ +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_rx_payload_mem_range_err_mcu_int_sts_SHFT \ + \ +16 +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_tx_payload_mem_range_err_mcu_int_sts_ADDR \ + \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_tx_payload_mem_range_err_mcu_int_sts_MASK \ + \ +0x00008000 /* wpdma_tx_payload_mem_range_err_mcu_int_sts[15] */ +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_tx_payload_mem_range_err_mcu_int_sts_SHFT \ + \ +15 +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_rx_dmad_mem_range_err_mcu_int_sts_ADDR \ + \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_rx_dmad_mem_range_err_mcu_int_sts_MASK \ + \ +0x00004000 /* wpdma_rx_dmad_mem_range_err_mcu_int_sts[14] */ +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_rx_dmad_mem_range_err_mcu_int_sts_SHFT \ + \ +14 +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_tx_dmad_mem_range_err_mcu_int_sts_ADDR \ + \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_tx_dmad_mem_range_err_mcu_int_sts_MASK \ + \ +0x00002000 /* wpdma_tx_dmad_mem_range_err_mcu_int_sts[13] */ +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_tx_dmad_mem_range_err_mcu_int_sts_SHFT \ + \ +13 +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wifi_rxfifo_wr_ovf_int_sts_ADDR \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wifi_rxfifo_wr_ovf_int_sts_MASK \ +0x00001000 /* wifi_rxfifo_wr_ovf_int_sts[12] */ +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wifi_rxfifo_wr_ovf_int_sts_SHFT 12 +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wifi_txfifo1_wr_ovf_int_sts_ADDR \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wifi_txfifo1_wr_ovf_int_sts_MASK \ +0x00000800 /* wifi_txfifo1_wr_ovf_int_sts[11] */ +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wifi_txfifo1_wr_ovf_int_sts_SHFT 11 +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wifi_txfifo0_wr_ovf_int_sts_ADDR \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wifi_txfifo0_wr_ovf_int_sts_MASK \ +0x00000400 /* wifi_txfifo0_wr_ovf_int_sts[10] */ +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wifi_txfifo0_wr_ovf_int_sts_SHFT 10 +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_rx_timeout_int_sts_ADDR \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_rx_timeout_int_sts_MASK \ +0x00000200 /* wpdma_rx_timeout_int_sts[9] */ +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_rx_timeout_int_sts_SHFT 9 +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_tx_timeout_int_sts_ADDR \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_tx_timeout_int_sts_MASK \ +0x00000100 /* wpdma_tx_timeout_int_sts[8] */ +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_tx_timeout_int_sts_SHFT 8 +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_host2mcu_sw_int_sts_ADDR \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_host2mcu_sw_int_sts_MASK \ +0x000000FF /* host2mcu_sw_int_sts[7..0] */ +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_host2mcu_sw_int_sts_SHFT 0 + +/* +* ---MCU_INT_ENA (0x18024000 + 0X114)--- +* host2mcu_sw_int_ena[7..0] - (RW) host2mcu interrupt enable +* wpdma_tx_dma_timeout_int_ena[8] - (RW) WPDMA TX error detection interrupt +enable +* wpdma_rx_dma_timeout_int_ena[9] - (RW) WPDMA RX error detection interrupt +enable +* wifi_txfifo0_wr_ovf_int_ena[10] - (RW) conn_hif txfifo erorr detect +* interrupt enable. +* wifi_txfifo1_wr_ovf_int_ena[11] - (RW) conn_hif txfifo erorr detect +* interrupt enable. +* wifi_rxfifo_wr_ovf_int_ena[12] - (RW) conn_hif rxfifo erorr detect interrupt +enable. +* wpdma_tx_dmad_mem_range_err_mcu_int_ena[13] - (RW) WPDMA tx dma descriptor +* memory range error detection interrupt enable +* wpdma_rx_dmad_mem_range_err_mcu_int_ena[14] - (RW) WPDMA rx dma descriptor +* memory range error detection interrupt enable +* wpdma_tx_payload_mem_range_err_mcu_int_ena[15] - (RW) WPDMA tx payload +* memory range error detection interrupt enable +* wpdma_rx_payload_mem_range_err_mcu_int_ena[16] - (RW) WPDMA rx payload +* memory range error detection interrupt enable +* RESERVED17[31..17] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_rx_payload_mem_range_err_mcu_int_ena_ADDR \ + \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_rx_payload_mem_range_err_mcu_int_ena_MASK \ + \ +0x00010000 /* wpdma_rx_payload_mem_range_err_mcu_int_ena[16] */ +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_rx_payload_mem_range_err_mcu_int_ena_SHFT \ + \ +16 +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_tx_payload_mem_range_err_mcu_int_ena_ADDR \ + \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_tx_payload_mem_range_err_mcu_int_ena_MASK \ + \ +0x00008000 /* wpdma_tx_payload_mem_range_err_mcu_int_ena[15] */ +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_tx_payload_mem_range_err_mcu_int_ena_SHFT \ + \ +15 +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_rx_dmad_mem_range_err_mcu_int_ena_ADDR \ + \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_rx_dmad_mem_range_err_mcu_int_ena_MASK \ + \ +0x00004000 /* wpdma_rx_dmad_mem_range_err_mcu_int_ena[14] */ +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_rx_dmad_mem_range_err_mcu_int_ena_SHFT \ + \ +14 +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_tx_dmad_mem_range_err_mcu_int_ena_ADDR \ + \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_tx_dmad_mem_range_err_mcu_int_ena_MASK \ + \ +0x00002000 /* wpdma_tx_dmad_mem_range_err_mcu_int_ena[13] */ +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_tx_dmad_mem_range_err_mcu_int_ena_SHFT \ + \ +13 +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wifi_rxfifo_wr_ovf_int_ena_ADDR \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wifi_rxfifo_wr_ovf_int_ena_MASK \ +0x00001000 /* wifi_rxfifo_wr_ovf_int_ena[12] */ +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wifi_rxfifo_wr_ovf_int_ena_SHFT 12 +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wifi_txfifo1_wr_ovf_int_ena_ADDR \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wifi_txfifo1_wr_ovf_int_ena_MASK \ +0x00000800 /* wifi_txfifo1_wr_ovf_int_ena[11] */ +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wifi_txfifo1_wr_ovf_int_ena_SHFT 11 +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wifi_txfifo0_wr_ovf_int_ena_ADDR \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wifi_txfifo0_wr_ovf_int_ena_MASK \ +0x00000400 /* wifi_txfifo0_wr_ovf_int_ena[10] */ +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wifi_txfifo0_wr_ovf_int_ena_SHFT 10 +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_rx_dma_timeout_int_ena_ADDR \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_rx_dma_timeout_int_ena_MASK \ +0x00000200 /* wpdma_rx_dma_timeout_int_ena[9] */ +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_rx_dma_timeout_int_ena_SHFT 9 +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_tx_dma_timeout_int_ena_ADDR \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_tx_dma_timeout_int_ena_MASK \ +0x00000100 /* wpdma_tx_dma_timeout_int_ena[8] */ +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_tx_dma_timeout_int_ena_SHFT 8 +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_host2mcu_sw_int_ena_ADDR \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_host2mcu_sw_int_ena_MASK \ +0x000000FF /* host2mcu_sw_int_ena[7..0] */ +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_host2mcu_sw_int_ena_SHFT 0 + +/* +* ---CONN_HIF_DUMMY (0x18024000 + 0x120)--- +* CONN_HIF_DUMMY[31..0] - (RW) Reserved CR, SE will use it for pcie +calibration! +*/ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DUMMY_CONN_HIF_DUMMY_ADDR \ +WF_WFDMA_HOST_DMA0_CONN_HIF_DUMMY_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DUMMY_CONN_HIF_DUMMY_MASK \ +0xFFFFFFFF /* CONN_HIF_DUMMY[31..0] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DUMMY_CONN_HIF_DUMMY_SHFT 0 + +/* +* ---WPDMA_DBG_IDX (0x18024000 + 0x124)--- +* PDMA_DBG_IDX[7..0] - (RW) PDMA debug index +* PDMA_DBG_Enable[8] - (RW) PDMA Debug Enable +* 0: PDMA_DBG_port would has no function +* 1 : PDMA DBG_IDX select PDMA debug flag +index +* RESERVED9[31..9] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_DBG_IDX_PDMA_DBG_Enable_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_DBG_IDX_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_DBG_IDX_PDMA_DBG_Enable_MASK \ +0x00000100 /* PDMA_DBG_Enable[8] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_DBG_IDX_PDMA_DBG_Enable_SHFT 8 +#define WF_WFDMA_HOST_DMA0_WPDMA_DBG_IDX_PDMA_DBG_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_DBG_IDX_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_DBG_IDX_PDMA_DBG_IDX_MASK \ +0x000000FF /* PDMA_DBG_IDX[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_DBG_IDX_PDMA_DBG_IDX_SHFT 0 + +/* +* ---WPDMA_DBG_PROBE (0x18024000 + 0x128)--- +* PDMA_DBG_PROBE[31..0] - (RO) PDMA Debug probe read +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_DBG_PROBE_PDMA_DBG_PROBE_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_DBG_PROBE_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_DBG_PROBE_PDMA_DBG_PROBE_MASK \ +0xFFFFFFFF /* PDMA_DBG_PROBE[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_DBG_PROBE_PDMA_DBG_PROBE_SHFT 0 + +/* +* ---CONN_HIF_DBG_IDX (0x18024000 + 0x12C)--- +* conn_hif_dbg_byt0_sel[2..0] - (RW) conn_hif_dbg_byt0_sel : Select +* conn_hif_dbg[7:0] from "pdma_dbg"/"hif_dmashdl_top" +* conn_hif_dbg_byt1_sel[5..3] - (RW) conn_hif_dbg_byt1_sel : Select +* conn_hif_dbg[15:8] from "pdma_dbg"/"hif_dmashdl_top" +* conn_hif_dbg_byt2_sel[8..6] - (RW) conn_hif_dbg_byt2_sel : Select +* conn_hif_dbg[23:16] from "pdma_dbg"/"hif_dmashdl_top" +* conn_hif_dbg_byt3_sel[11..9] - (RW) conn_hif_dbg_byt3_sel : Select +* conn_hif_dbg[31:24] from "pdma_dbg"/"hif_dmashdl_top" +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_conn_hif_dbg_byt3_sel_ADDR \ +WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_conn_hif_dbg_byt3_sel_MASK \ +0x00000E00 /* conn_hif_dbg_byt3_sel[11..9] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_conn_hif_dbg_byt3_sel_SHFT 9 +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_conn_hif_dbg_byt2_sel_ADDR \ +WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_conn_hif_dbg_byt2_sel_MASK \ +0x000001C0 /* conn_hif_dbg_byt2_sel[8..6] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_conn_hif_dbg_byt2_sel_SHFT 6 +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_conn_hif_dbg_byt1_sel_ADDR \ +WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_conn_hif_dbg_byt1_sel_MASK \ +0x00000038 /* conn_hif_dbg_byt1_sel[5..3] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_conn_hif_dbg_byt1_sel_SHFT 3 +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_conn_hif_dbg_byt0_sel_ADDR \ +WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_conn_hif_dbg_byt0_sel_MASK \ +0x00000007 /* conn_hif_dbg_byt0_sel[2..0] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_conn_hif_dbg_byt0_sel_SHFT 0 + +/* +* ---CONN_HIF_DBG_PROBE (0x18024000 + 0x130)--- +* conn_hif_dbg_probe[31..0] - (RO) conn_hif_dbg_probe read +*/ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_PROBE_conn_hif_dbg_probe_ADDR \ +WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_PROBE_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_PROBE_conn_hif_dbg_probe_MASK \ +0xFFFFFFFF /* conn_hif_dbg_probe[31..0] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_PROBE_conn_hif_dbg_probe_SHFT 0 + +/* +* ---CONN_HIF_DMASHDL_DBG_PROBE (0x18024000 + 0x134)--- +* DMASHDL_DBG_PROBE[15..0] - (RO) conn_hif_dmashdl_dbg_probe read +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DMASHDL_DBG_PROBE_DMASHDL_DBG_PROBE_ADDR \ +WF_WFDMA_HOST_DMA0_CONN_HIF_DMASHDL_DBG_PROBE_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DMASHDL_DBG_PROBE_DMASHDL_DBG_PROBE_MASK \ +0x0000FFFF /* DMASHDL_DBG_PROBE[15..0] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DMASHDL_DBG_PROBE_DMASHDL_DBG_PROBE_SHFT 0 + +/* +* ---CONN_HIF_BUSY_STATUS (0x18024000 + 0x138)--- +* conn_hif_txfifo0_busy[0] - (RO) conn_hif txfifo0 busy status +* 0 : txfifo empty +* 1 : txfifo non empty +* conn_hif_txfifo1_busy[1] - (RO) conn_hif txfifo1 busy status +* 0 : txfifo empty +* 1 : txfifo non empty +* conn_hif_rxfifo_busy[2] - (RO) conn_hif rxfifo busy status +* 0 : rxfifo empty +* 1 : rxfifo non empty +* RESERVED[30..3] - (RO) Reserved CR +* conn_hif_busy[31] - (RO) Over all conn_hif busy status, it was +* busy summation of bit[6] ~ bit[0] status +*/ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_conn_hif_busy_ADDR \ +WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_conn_hif_busy_MASK \ +0x80000000 /* conn_hif_busy[31] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_conn_hif_busy_SHFT 31 +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_conn_hif_rxfifo_busy_ADDR \ +WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_conn_hif_rxfifo_busy_MASK \ +0x00000004 /* conn_hif_rxfifo_busy[2] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_conn_hif_rxfifo_busy_SHFT 2 +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_conn_hif_txfifo1_busy_ADDR \ +WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_conn_hif_txfifo1_busy_MASK \ +0x00000002 /* conn_hif_txfifo1_busy[1] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_conn_hif_txfifo1_busy_SHFT 1 +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_conn_hif_txfifo0_busy_ADDR \ +WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_conn_hif_txfifo0_busy_MASK \ +0x00000001 /* conn_hif_txfifo0_busy[0] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_conn_hif_txfifo0_busy_SHFT 0 + +/* +* ---CONN_HIF_BUSY_ENA (0x18024000 + 0x13c)--- +* conn_hif_txfifo0_busy_enable[0] - (RW) busy enable control +* 0: ignore busy status +* 1: conn_hif_busy would tack care busy +status +* conn_hif_txfifo1_busy_enable[1] - (RW) busy enable control +* 0: ignore busy status +* 1: conn_hif_busy would tack care busy +status +* conn_hif_rxfifo_busy_enable[2] - (RW) busy enable control +* 0: ignore busy status +* 1: conn_hif_busy would tack care busy +status +* RESERVED3[4..3] - (RO) Reserved bits +* RESERVED[31..5] - (RW) Reserved CR +*/ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_conn_hif_rxfifo_busy_enable_ADDR\ +WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_conn_hif_rxfifo_busy_enable_MASK\ +0x00000004 /* conn_hif_rxfifo_busy_enable[2] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_conn_hif_rxfifo_busy_enable_SHFT 2 +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_conn_hif_txfifo1_busy_enable_ADDR \ +WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_conn_hif_txfifo1_busy_enable_MASK \ +0x00000002 /* conn_hif_txfifo1_busy_enable[1] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_conn_hif_txfifo1_busy_enable_SHFT 1 +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_conn_hif_txfifo0_busy_enable_ADDR \ +WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_conn_hif_txfifo0_busy_enable_MASK \ +0x00000001 /* conn_hif_txfifo0_busy_enable[0] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_conn_hif_txfifo0_busy_enable_SHFT 0 + +/* +* ---CONN_HIF_FIFO_TEST_MOD (0x18024000 + 0x140)--- +* csr_wfdma_loopback_en[0] - (RW) conn_hif fifo loopback enable +* NOTICE : when loopback, OMIT_TX_INFO and +* OMIT_RX_INFO sould be both set to 1'b1 +* csr_wfdma_loopback_qsel[2..1] - (RW) No USE for (conn_hif fifo loopback +* packet go into Rx-ring number) +* RESERVED3[31..3] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_FIFO_TEST_MOD_csr_wfdma_loopback_qsel_ADDR \ +WF_WFDMA_HOST_DMA0_CONN_HIF_FIFO_TEST_MOD_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_FIFO_TEST_MOD_csr_wfdma_loopback_qsel_MASK \ +0x00000006 /* csr_wfdma_loopback_qsel[2..1] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_FIFO_TEST_MOD_csr_wfdma_loopback_qsel_SHFT 1 +#define WF_WFDMA_HOST_DMA0_CONN_HIF_FIFO_TEST_MOD_csr_wfdma_loopback_en_ADDR \ +WF_WFDMA_HOST_DMA0_CONN_HIF_FIFO_TEST_MOD_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_FIFO_TEST_MOD_csr_wfdma_loopback_en_MASK \ +0x00000001 /* csr_wfdma_loopback_en[0] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_FIFO_TEST_MOD_csr_wfdma_loopback_en_SHFT 0 + +/* +* ---WPDMA2HOST_ERR_INT_STA (0x18024000 + 0x1E8)--- +* wpdma_tx_timeout_int_sts[0] - (W1C) WPDMA TX error detection interrupt +* stauts, write 1 to clear the interrupt +* wpdma_rx_timeout_int_sts[1] - (W1C) WPDMA RX error detection interrupt +* stauts, write 1 to clear the interrupt +* RESERVED2[31..2] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_wpdma_rx_timeout_int_sts_ADDR \ + \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_wpdma_rx_timeout_int_sts_MASK \ + \ +0x00000002 /* wpdma_rx_timeout_int_sts[1] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_wpdma_rx_timeout_int_sts_SHFT \ + \ +1 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_wpdma_tx_timeout_int_sts_ADDR \ + \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_wpdma_tx_timeout_int_sts_MASK \ + \ +0x00000001 /* wpdma_tx_timeout_int_sts[0] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_wpdma_tx_timeout_int_sts_SHFT \ + \ +0 + +/* +* ---WPDMA2HOST_ERR_INT_ENA (0x18024000 + 0x1EC)--- +* wpdma_rx_timeout_int_ena[0] - (RW) WPDMA TX error detection interrupt +enable +* wpdma_tx_timeout_int_ena[1] - (RW) WPDMA RX error detection interrupt +enable +* RESERVED2[31..2] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_wpdma_tx_timeout_int_ena_ADDR \ + \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_wpdma_tx_timeout_int_ena_MASK \ + \ +0x00000002 /* wpdma_tx_timeout_int_ena[1] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_wpdma_tx_timeout_int_ena_SHFT \ + \ +1 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_wpdma_rx_timeout_int_ena_ADDR \ + \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_wpdma_rx_timeout_int_ena_MASK \ + \ +0x00000001 /* wpdma_rx_timeout_int_ena[0] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_wpdma_rx_timeout_int_ena_SHFT \ + \ +0 + +/* +* ---MCU2HOST_SW_INT_STA (0x18024000 + 0x1F0)--- +* mcu2host_sw_int_0[0] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_1[1] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_2[2] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_3[3] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_4[4] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_5[5] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_6[6] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_7[7] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_8[8] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_9[9] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_10[10] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_11[11] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_12[12] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_13[13] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_14[14] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_15[15] - (W1C) mcu2host interrupt status +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_15_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_15_MASK \ +0x00008000 /* mcu2host_sw_int_15[15] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_15_SHFT 15 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_14_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_14_MASK \ +0x00004000 /* mcu2host_sw_int_14[14] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_14_SHFT 14 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_13_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_13_MASK \ +0x00002000 /* mcu2host_sw_int_13[13] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_13_SHFT 13 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_12_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_12_MASK \ +0x00001000 /* mcu2host_sw_int_12[12] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_12_SHFT 12 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_11_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_11_MASK \ +0x00000800 /* mcu2host_sw_int_11[11] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_11_SHFT 11 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_10_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_10_MASK \ +0x00000400 /* mcu2host_sw_int_10[10] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_10_SHFT 10 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_9_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_9_MASK \ +0x00000200 /* mcu2host_sw_int_9[9] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_9_SHFT 9 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_8_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_8_MASK \ +0x00000100 /* mcu2host_sw_int_8[8] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_8_SHFT 8 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_7_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_7_MASK \ +0x00000080 /* mcu2host_sw_int_7[7] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_7_SHFT 7 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_6_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_6_MASK \ +0x00000040 /* mcu2host_sw_int_6[6] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_6_SHFT 6 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_5_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_5_MASK \ +0x00000020 /* mcu2host_sw_int_5[5] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_5_SHFT 5 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_4_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_4_MASK \ +0x00000010 /* mcu2host_sw_int_4[4] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_4_SHFT 4 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_3_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_3_MASK \ +0x00000008 /* mcu2host_sw_int_3[3] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_3_SHFT 3 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_2_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_2_MASK \ +0x00000004 /* mcu2host_sw_int_2[2] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_2_SHFT 2 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_1_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_1_MASK \ +0x00000002 /* mcu2host_sw_int_1[1] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_1_SHFT 1 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_0_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_0_MASK \ +0x00000001 /* mcu2host_sw_int_0[0] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_0_SHFT 0 + +/* +* ---MCU2HOST_SW_INT_ENA (0x18024000 + 0x1F4)--- +* mcu2host_int_ena_0[0] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_1[1] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_2[2] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_3[3] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_4[4] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_5[5] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_6[6] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_7[7] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_8[8] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_9[9] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_10[10] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_11[11] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_12[12] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_13[13] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_14[14] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_15[15] - (RW) MCU2HOST software interrupt interrupt +enable +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_15_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_15_MASK \ +0x00008000 /* mcu2host_int_ena_15[15] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_15_SHFT 15 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_14_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_14_MASK \ +0x00004000 /* mcu2host_int_ena_14[14] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_14_SHFT 14 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_13_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_13_MASK \ +0x00002000 /* mcu2host_int_ena_13[13] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_13_SHFT 13 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_12_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_12_MASK \ +0x00001000 /* mcu2host_int_ena_12[12] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_12_SHFT 12 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_11_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_11_MASK \ +0x00000800 /* mcu2host_int_ena_11[11] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_11_SHFT 11 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_10_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_10_MASK \ +0x00000400 /* mcu2host_int_ena_10[10] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_10_SHFT 10 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_9_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_9_MASK \ +0x00000200 /* mcu2host_int_ena_9[9] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_9_SHFT 9 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_8_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_8_MASK \ +0x00000100 /* mcu2host_int_ena_8[8] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_8_SHFT 8 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_7_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_7_MASK \ +0x00000080 /* mcu2host_int_ena_7[7] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_7_SHFT 7 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_6_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_6_MASK \ +0x00000040 /* mcu2host_int_ena_6[6] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_6_SHFT 6 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_5_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_5_MASK \ +0x00000020 /* mcu2host_int_ena_5[5] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_5_SHFT 5 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_4_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_4_MASK \ +0x00000010 /* mcu2host_int_ena_4[4] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_4_SHFT 4 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_3_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_3_MASK \ +0x00000008 /* mcu2host_int_ena_3[3] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_3_SHFT 3 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_2_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_2_MASK \ +0x00000004 /* mcu2host_int_ena_2[2] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_2_SHFT 2 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_1_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_1_MASK \ +0x00000002 /* mcu2host_int_ena_1[1] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_1_SHFT 1 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_0_ADDR \ +WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_0_MASK \ +0x00000001 /* mcu2host_int_ena_0[0] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_0_SHFT 0 + +/* +* ---SUBSYS2HOST_INT_STA (0x18024000 + 0x1F8)--- +* mac_int_sts_0[0] - (RO) MAC interrupt 0: Band0 TBTT +* interrupt(Check wf_int_wakeup_top/hwisr0 [0x820Fc03c]) +* 0 : no interrupt +* 1 : interrupt assert +* mac_int_sts_1[1] - (RO) MAC interrupt 1: Band0 Pre-TBTT +* interrupt(Check wf_int_wakeup_top/hwisr1 [0x820Fc044]) +* 0 : no interrupt +* 1 : interrupt assert +* mac_int_sts_2[2] - (RO) MAC interrupt 2: Band0 TX status +* interrupt(Check wf_int_wakeup_top/hwisr2 [0x820Fc04c]) +* 0 : no interrupt +* 1 : interrupt assert +* mac_int_sts_3[3] - (RO) MAC interrupt 3: Band0 Auto wakeup +* interrupt (Check wf_int_wakeup_top/hwisr3 [0x820Fc054]) +* 0 : no interrupt +* 1 : interrupt assert +* mac_int_sts_4[4] - (RO) MAC interrupt 4: Band0 GP timer +* interrupt (Check wf_int_wakeup_top/hwisr4 [0x820Fc05c]) +* 0 : no interrupt +* 1 : interrupt assert +* RESERVED5[7..5] - (RO) Reserved bits +* conn_hif_on_host_int_sts[8] - (RO) CONN_HIF_ON interrupt enable +* 0 : no conn_hif_on_host_int interrupt +* 1 : conn_hif_on_host_int interrupt assert. +* User should check conn_hif_on (host_csr) interrupt status and clear interrupt. +* conn2ap_sw_irq_sts[9] - (RO) MCUSYS conn2ap_sw_irq status (Check +* conn_mcu_config/EMI_CTL [0x80000150] bit[4:0]) +* 0 : no conn2ap_sw_irq interrupt. +* 1 : conn2ap_sw_irq interrupt assert. User +* should check mcusys_n9 interrupt status and clear interrupt. +* (conn_mcu_config/EMI_CTL [0x80000150] bit[4:0] != 0) +* dmashdl_int_sts[10] - (RO) DMASHDL error interrupt +* 0 : no interrupt +* 1 : interrupt assert +* mac_int_sts_5[11] - (RO) MAC interrupt 5: Band1 TBTT +* interrupt(Check wf_int_wakeup_top/hwisr0 [0x820Fc03c]) +* 0 : no interrupt +* 1 : interrupt assert +* mac_int_sts_6[12] - (RO) MAC interrupt 6: Band1 Pre-TBTT +* interrupt(Check wf_int_wakeup_top/hwisr1 [0x820Fc044]) +* 0 : no interrupt +* 1 : interrupt assert +* mac_int_sts_7[13] - (RO) MAC interrupt 7: Band1 TX status +* interrupt(Check wf_int_wakeup_top/hwisr2 [0x820Fc04c]) +* 0 : no interrupt +* 1 : interrupt assert +* mac_int_sts_8[14] - (RO) MAC interrupt 8: Band1 Auto wakeup +* interrupt (Check wf_int_wakeup_top/hwisr3 [0x820Fc054]) +* 0 : no interrupt +* 1 : interrupt assert +* mac_int_sts_9[15] - (RO) MAC interrupt 9: Band1 GP timer +* interrupt (Check wf_int_wakeup_top/hwisr4 [0x820Fc05c]) +* 0 : no interrupt +* 1 : interrupt assert +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_9_ADDR \ +WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_9_MASK \ +0x00008000 /* mac_int_sts_9[15] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_9_SHFT 15 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_8_ADDR \ +WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_8_MASK \ +0x00004000 /* mac_int_sts_8[14] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_8_SHFT 14 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_7_ADDR \ +WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_7_MASK \ +0x00002000 /* mac_int_sts_7[13] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_7_SHFT 13 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_6_ADDR \ +WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_6_MASK \ +0x00001000 /* mac_int_sts_6[12] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_6_SHFT 12 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_5_ADDR \ +WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_5_MASK \ +0x00000800 /* mac_int_sts_5[11] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_5_SHFT 11 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_dmashdl_int_sts_ADDR \ +WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_dmashdl_int_sts_MASK \ +0x00000400 /* dmashdl_int_sts[10] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_dmashdl_int_sts_SHFT 10 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_conn2ap_sw_irq_sts_ADDR \ +WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_conn2ap_sw_irq_sts_MASK \ +0x00000200 /* conn2ap_sw_irq_sts[9] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_conn2ap_sw_irq_sts_SHFT 9 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_conn_hif_on_host_int_sts_ADDR \ +WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_conn_hif_on_host_int_sts_MASK \ +0x00000100 /* conn_hif_on_host_int_sts[8] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_conn_hif_on_host_int_sts_SHFT 8 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_4_ADDR \ +WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_4_MASK \ +0x00000010 /* mac_int_sts_4[4] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_4_SHFT 4 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_3_ADDR \ +WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_3_MASK \ +0x00000008 /* mac_int_sts_3[3] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_3_SHFT 3 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_2_ADDR \ +WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_2_MASK \ +0x00000004 /* mac_int_sts_2[2] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_2_SHFT 2 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_1_ADDR \ +WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_1_MASK \ +0x00000002 /* mac_int_sts_1[1] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_1_SHFT 1 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_0_ADDR \ +WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_0_MASK \ +0x00000001 /* mac_int_sts_0[0] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_0_SHFT 0 + +/* +* ---SUBSYS2HOST_INT_ENA (0x18024000 + 0x1FC)--- +* mac_int_ena_0[0] - (RW) MAC interrupt enable +* mac_int_ena_1[1] - (RW) MAC interrupt enable +* mac_int_ena_2[2] - (RW) MAC interrupt enable +* mac_int_ena_3[3] - (RW) MAC interrupt enable +* mac_int_ena_4[4] - (RW) MAC interrupt enable +* RESERVED5[7..5] - (RO) Reserved bits +* conn_hif_on_host_int_ena[8] - (RW) CONN_HIF_ON interrupt enable +* conn2ap_sw_irq_ena[9] - (RW) MCUSYS conn2ap_sw_irq enable +* dmashdl_int_ena[10] - (RW) DMASHDL interrupt enable +* mac_int_ena_5[11] - (RW) MAC interrupt enable +* mac_int_ena_6[12] - (RW) MAC interrupt enable +* mac_int_ena_7[13] - (RW) MAC interrupt enable +* mac_int_ena_8[14] - (RW) MAC interrupt enable +* mac_int_ena_9[15] - (RW) MAC interrupt enable +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_9_ADDR \ +WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_9_MASK \ +0x00008000 /* mac_int_ena_9[15] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_9_SHFT 15 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_8_ADDR \ +WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_8_MASK \ +0x00004000 /* mac_int_ena_8[14] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_8_SHFT 14 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_7_ADDR \ +WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_7_MASK \ +0x00002000 /* mac_int_ena_7[13] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_7_SHFT 13 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_6_ADDR \ +WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_6_MASK \ +0x00001000 /* mac_int_ena_6[12] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_6_SHFT 12 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_5_ADDR \ +WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_5_MASK \ +0x00000800 /* mac_int_ena_5[11] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_5_SHFT 11 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_dmashdl_int_ena_ADDR \ +WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_dmashdl_int_ena_MASK \ +0x00000400 /* dmashdl_int_ena[10] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_dmashdl_int_ena_SHFT 10 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_conn2ap_sw_irq_ena_ADDR \ +WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_conn2ap_sw_irq_ena_MASK \ +0x00000200 /* conn2ap_sw_irq_ena[9] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_conn2ap_sw_irq_ena_SHFT 9 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_conn_hif_on_host_int_ena_ADDR \ +WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_conn_hif_on_host_int_ena_MASK \ +0x00000100 /* conn_hif_on_host_int_ena[8] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_conn_hif_on_host_int_ena_SHFT 8 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_4_ADDR \ +WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_4_MASK \ +0x00000010 /* mac_int_ena_4[4] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_4_SHFT 4 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_3_ADDR \ +WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_3_MASK \ +0x00000008 /* mac_int_ena_3[3] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_3_SHFT 3 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_2_ADDR \ +WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_2_MASK \ +0x00000004 /* mac_int_ena_2[2] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_2_SHFT 2 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_1_ADDR \ +WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_1_MASK \ +0x00000002 /* mac_int_ena_1[1] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_1_SHFT 1 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_0_ADDR \ +WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_0_MASK \ +0x00000001 /* mac_int_ena_0[0] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_0_SHFT 0 + +/* +* ---HOST_INT_STA (0x18024000 + 0x200)--- +* rx_done_int_sts_0[0] - (W1C) RX Queue#0 packet receive interrupt +* Write 1 to clear the interrupt +* Read to get the raw interrupt status +* rx_done_int_sts_1[1] - (W1C) RX Queue#1 packet receive interrupt +* Write 1 to clear the interrupt +* Read to get the raw interrupt status +* rx_done_int_sts_2[2] - (W1C) RX Queue#2 packet receive interrupt +* Write 1 to clear the interrupt +* Read to get the raw interrupt status +* rx_done_int_sts_3[3] - (W1C) RX Queue#3 packet receive interrupt +* Write 1 to clear the interrupt +* Read to get the raw interrupt status +* tx_done_int_sts_0[4] - (W1C) TX Queue#0 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_1[5] - (W1C) TX Queue#1 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_2[6] - (W1C) TX Queue#2 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_3[7] - (W1C) TX Queue#3 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_4[8] - (W1C) TX Queue#4 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_5[9] - (W1C) TX Queue#5 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_6[10] - (W1C) TX Queue#6 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_7[11] - (W1C) TX Queue#7 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_8[12] - (W1C) TX Queue#8 packet transmit +* interruptWrite 1 to clear the interrupt +* tx_done_int_sts_9[13] - (W1C) TX Queue#9 packet transmit +* interruptWrite 1 to clear the interrupt +* tx_done_int_sts_10[14] - (W1C) TX Queue#10 packet transmit +* interruptWrite 1 to clear the interrupt +* tx_done_int_sts_11[15] - (W1C) TX Queue#11 packet transmit +* interruptWrite 1 to clear the interrupt +* tx_done_int_sts_12[16] - (W1C) TX Queue#12 packet transmit +* interruptWrite 1 to clear the interrupt +* tx_done_int_sts_13[17] - (W1C) TX Queue#13 packet transmit +* interruptWrite 1 to clear the interrupt +* tx_done_int_sts_14[18] - (W1C) TX Queue#14 packet transmit +* interruptWrite 1 to clear the interrupt +* RESERVED19[19] - (RO) Reserved bits +* rx_coherent_int_sts[20] - (W1C) RX_DMA finds data coherent event when +* checking ddone bit +* Write 1 to clear the interrupt +* Read to get the raw interrupt status +* tx_coherent_int_sts[21] - (W1C) TX_DMA finds data coherent event when +* checking ddone bit +* Write 1 to clear the interrupt +* Read to get the raw interrupt status +* rx_done_int_sts_4[22] - (W1C) RX Queue#4 packet receive interrupt +* Write 1 to clear the interrupt Read to get the raw interrupt status +* rx_done_int_sts_5[23] - (W1C) RX Queue#5 packet receive interrupt +* Write 1 to clear the interrupt Read to get the raw interrupt status +* wpdma2host_err_int_sts[24] - (RO) wpdma interrupt overall status +* User should should check WPDMA_ERR_INT_STA +* for each wpdma error interrupt status +* Host could read [0x0_41E8] to check +* indivisual wpdma2host_error interrupt status +* RESERVED25[25] - (RO) Reserved bits +* tx_done_int_sts_16[26] - (W1C) TX Queue#16 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_17[27] - (W1C) TX Queue#17 packet transmit interrupt +* Write 1 to clear the interrupt +* subsys_int_sts[28] - (RO) subsys interrupt overall status +* User should should check +* SUBSYS2HOST_INT_STA for each interrupt status +* Host could read [0x0_41F8] to check +* indivisual subsys hw interrupt status +* mcu2host_sw_int_sts[29] - (RO) subsys interrupt overall status +* User should should check +* SUBSYS2HOST_INT_STA for each interrupt status +* Host could read [0x0_41F8] to check +* indivisual subsys hw interrupt status +* tx_done_int_sts_18[30] - (W1C) TX Queue#18 packet transmit interrupt +* Write 1 to clear the interrupt +* RESERVED[31] - (RO) reserved +*/ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_18_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_18_MASK \ +0x40000000 /* tx_done_int_sts_18[30] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_18_SHFT 30 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_mcu2host_sw_int_sts_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_mcu2host_sw_int_sts_MASK \ +0x20000000 /* mcu2host_sw_int_sts[29] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_mcu2host_sw_int_sts_SHFT 29 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_subsys_int_sts_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_subsys_int_sts_MASK \ +0x10000000 /* subsys_int_sts[28] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_subsys_int_sts_SHFT 28 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_17_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_17_MASK \ +0x08000000 /* tx_done_int_sts_17[27] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_17_SHFT 27 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_16_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_16_MASK \ +0x04000000 /* tx_done_int_sts_16[26] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_16_SHFT 26 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_wpdma2host_err_int_sts_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_wpdma2host_err_int_sts_MASK \ +0x01000000 /* wpdma2host_err_int_sts[24] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_wpdma2host_err_int_sts_SHFT 24 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_5_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_5_MASK \ +0x00800000 /* rx_done_int_sts_5[23] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_5_SHFT 23 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_4_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_4_MASK \ +0x00400000 /* rx_done_int_sts_4[22] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_4_SHFT 22 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_coherent_int_sts_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_coherent_int_sts_MASK \ +0x00200000 /* tx_coherent_int_sts[21] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_coherent_int_sts_SHFT 21 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_coherent_int_sts_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_coherent_int_sts_MASK \ +0x00100000 /* rx_coherent_int_sts[20] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_coherent_int_sts_SHFT 20 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_14_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_14_MASK \ +0x00040000 /* tx_done_int_sts_14[18] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_14_SHFT 18 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_13_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_13_MASK \ +0x00020000 /* tx_done_int_sts_13[17] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_13_SHFT 17 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_12_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_12_MASK \ +0x00010000 /* tx_done_int_sts_12[16] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_12_SHFT 16 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_11_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_11_MASK \ +0x00008000 /* tx_done_int_sts_11[15] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_11_SHFT 15 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_10_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_10_MASK \ +0x00004000 /* tx_done_int_sts_10[14] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_10_SHFT 14 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_9_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_9_MASK \ +0x00002000 /* tx_done_int_sts_9[13] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_9_SHFT 13 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_8_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_8_MASK \ +0x00001000 /* tx_done_int_sts_8[12] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_8_SHFT 12 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_7_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_7_MASK \ +0x00000800 /* tx_done_int_sts_7[11] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_7_SHFT 11 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_6_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_6_MASK \ +0x00000400 /* tx_done_int_sts_6[10] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_6_SHFT 10 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_5_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_5_MASK \ +0x00000200 /* tx_done_int_sts_5[9] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_5_SHFT 9 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_4_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_4_MASK \ +0x00000100 /* tx_done_int_sts_4[8] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_4_SHFT 8 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_3_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_3_MASK \ +0x00000080 /* tx_done_int_sts_3[7] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_3_SHFT 7 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_2_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_2_MASK \ +0x00000040 /* tx_done_int_sts_2[6] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_2_SHFT 6 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_1_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_1_MASK \ +0x00000020 /* tx_done_int_sts_1[5] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_1_SHFT 5 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_0_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_0_MASK \ +0x00000010 /* tx_done_int_sts_0[4] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_0_SHFT 4 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_3_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_3_MASK \ +0x00000008 /* rx_done_int_sts_3[3] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_3_SHFT 3 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_2_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_2_MASK \ +0x00000004 /* rx_done_int_sts_2[2] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_2_SHFT 2 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_1_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_1_MASK \ +0x00000002 /* rx_done_int_sts_1[1] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_1_SHFT 1 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_0_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_0_MASK \ +0x00000001 /* rx_done_int_sts_0[0] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_0_SHFT 0 + +/* +* ---HOST_INT_ENA (0x18024000 + 0X204)--- +* HOST_RX_DONE_INT_ENA0[0] - (RW) RX Queue#0 packet receive interrupt +* HOST_RX_DONE_INT_ENA1[1] - (RW) RX Queue#1 packet receive interrupt +* HOST_RX_DONE_INT_ENA2[2] - (RW) RX Queue#2 packet receive interrupt +* HOST_RX_DONE_INT_ENA3[3] - (RW) RX Queue#3 packet receive interrupt +* HOST_TX_DONE_INT_ENA0[4] - (RW) TX Queue#0 packet transmit interrupt +* HOST_TX_DONE_INT_ENA1[5] - (RW) TX Queue#1 packet transmit interrupt +* HOST_TX_DONE_INT_ENA2[6] - (RW) TX Queue#2 packet transmit interrupt +* HOST_TX_DONE_INT_ENA3[7] - (RW) TX Queue#3 packet transmit interrupt +* HOST_TX_DONE_INT_ENA4[8] - (RW) TX Queue#4 packet transmit interrupt +* HOST_TX_DONE_INT_ENA5[9] - (RW) TX Queue#5 packet transmit interrupt +* HOST_TX_DONE_INT_ENA6[10] - (RW) TX Queue#6 packet transmit interrupt +* HOST_TX_DONE_INT_ENA7[11] - (RW) TX Queue#7 packet transmit interrupt +* HOST_TX_DONE_INT_ENA8[12] - (RW) TX Queue#8 packet transmit interrupt +* HOST_TX_DONE_INT_ENA9[13] - (RW) TX Queue#9 packet transmit interrupt +* HOST_TX_DONE_INT_ENA10[14] - (RW) TX Queue#10 packet transmit interrupt +* HOST_TX_DONE_INT_ENA11[15] - (RW) TX Queue#11 packet transmit interrupt +* HOST_TX_DONE_INT_ENA12[16] - (RW) TX Queue#12 packet transmit interrupt +* HOST_TX_DONE_INT_ENA13[17] - (RW) TX Queue#13 packet transmit interrupt +* HOST_TX_DONE_INT_ENA14[18] - (RW) TX Queue#14 packet transmit interrupt +* RESERVED19[19] - (RO) Reserved bits +* HOST_RX_COHERENT_EN[20] - (RW) Enable for RX_DMA data coherent +interrupt +* HOST_TX_COHERENT_EN[21] - (RW) Enable for TX_DMA data coherent +interrupt +* HOST_RX_DONE_INT_ENA4[22] - (RW) RX Queue#4 packet receive interrupt +* HOST_RX_DONE_INT_ENA5[23] - (RW) RX Queue#5 packet receive interrupt +* wpdma2host_err_int_ena[24] - (RW) Enable bit of wpdma2host_err_int +* RESERVED[25] - (RO) reserved +* HOST_TX_DONE_INT_ENA16[26] - (RW) TX Queue#16 packet transmit interrupt +* HOST_TX_DONE_INT_ENA17[27] - (RW) TX Queue#17 packet transmit interrupt +* subsys_int_ena[28] - (RW) Enable bit of subsys_int +* mcu2host_sw_int_ena[29] - (RW) Enable bit of mcu2host_sw_int +* HOST_TX_DONE_INT_ENA18[30] - (RW) TX Queue#18 packet transmit interrupt +* RESERVED[31] - (RO) reserved +*/ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA18_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA18_MASK \ +0x40000000 /* HOST_TX_DONE_INT_ENA18[30] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA18_SHFT 30 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_mcu2host_sw_int_ena_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_mcu2host_sw_int_ena_MASK \ +0x20000000 /* mcu2host_sw_int_ena[29] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_mcu2host_sw_int_ena_SHFT 29 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_subsys_int_ena_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_subsys_int_ena_MASK \ +0x10000000 /* subsys_int_ena[28] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_subsys_int_ena_SHFT 28 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA17_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA17_MASK \ +0x08000000 /* HOST_TX_DONE_INT_ENA17[27] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA17_SHFT 27 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA16_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA16_MASK \ +0x04000000 /* HOST_TX_DONE_INT_ENA16[26] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA16_SHFT 26 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_wpdma2host_err_int_ena_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_wpdma2host_err_int_ena_MASK \ +0x01000000 /* wpdma2host_err_int_ena[24] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_wpdma2host_err_int_ena_SHFT 24 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA5_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA5_MASK \ +0x00800000 /* HOST_RX_DONE_INT_ENA5[23] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA5_SHFT 23 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA4_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA4_MASK \ +0x00400000 /* HOST_RX_DONE_INT_ENA4[22] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA4_SHFT 22 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_COHERENT_EN_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_COHERENT_EN_MASK \ +0x00200000 /* HOST_TX_COHERENT_EN[21] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_COHERENT_EN_SHFT 21 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_COHERENT_EN_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_COHERENT_EN_MASK \ +0x00100000 /* HOST_RX_COHERENT_EN[20] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_COHERENT_EN_SHFT 20 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA14_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA14_MASK \ +0x00040000 /* HOST_TX_DONE_INT_ENA14[18] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA14_SHFT 18 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA13_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA13_MASK \ +0x00020000 /* HOST_TX_DONE_INT_ENA13[17] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA13_SHFT 17 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA12_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA12_MASK \ +0x00010000 /* HOST_TX_DONE_INT_ENA12[16] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA12_SHFT 16 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA11_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA11_MASK \ +0x00008000 /* HOST_TX_DONE_INT_ENA11[15] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA11_SHFT 15 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA10_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA10_MASK \ +0x00004000 /* HOST_TX_DONE_INT_ENA10[14] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA10_SHFT 14 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA9_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA9_MASK \ +0x00002000 /* HOST_TX_DONE_INT_ENA9[13] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA9_SHFT 13 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA8_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA8_MASK \ +0x00001000 /* HOST_TX_DONE_INT_ENA8[12] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA8_SHFT 12 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA7_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA7_MASK \ +0x00000800 /* HOST_TX_DONE_INT_ENA7[11] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA7_SHFT 11 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA6_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA6_MASK \ +0x00000400 /* HOST_TX_DONE_INT_ENA6[10] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA6_SHFT 10 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA5_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA5_MASK \ +0x00000200 /* HOST_TX_DONE_INT_ENA5[9] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA5_SHFT 9 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA4_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA4_MASK \ +0x00000100 /* HOST_TX_DONE_INT_ENA4[8] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA4_SHFT 8 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA3_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA3_MASK \ +0x00000080 /* HOST_TX_DONE_INT_ENA3[7] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA3_SHFT 7 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA2_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA2_MASK \ +0x00000040 /* HOST_TX_DONE_INT_ENA2[6] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA2_SHFT 6 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA1_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA1_MASK \ +0x00000020 /* HOST_TX_DONE_INT_ENA1[5] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA1_SHFT 5 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA0_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA0_MASK \ +0x00000010 /* HOST_TX_DONE_INT_ENA0[4] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA0_SHFT 4 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA3_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA3_MASK \ +0x00000008 /* HOST_RX_DONE_INT_ENA3[3] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA3_SHFT 3 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA2_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA2_MASK \ +0x00000004 /* HOST_RX_DONE_INT_ENA2[2] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA2_SHFT 2 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA1_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA1_MASK \ +0x00000002 /* HOST_RX_DONE_INT_ENA1[1] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA1_SHFT 1 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA0_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA0_MASK \ +0x00000001 /* HOST_RX_DONE_INT_ENA0[0] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA0_SHFT 0 + +/* +* ---WPDMA_GLO_CFG (0x18024000 + 0x208)--- +* TX_DMA_EN[0] - (RW)TX_DMA Enable +* 1: Enable TX_DMA, MUST wait until all +* prefetch rings' MAX_CNT(WPDMA_T(R)X_RING*_EXT_CTRL)of DMA including neighbor +* DMA have been configured successfully +* 0: Disable TX_DMA +* TX_DMA_BUSY[1] - (RO)TX_DMA Busy indicator +* 1: TX_DMA is busy +* 0: TX_DMA is not busy +* RX_DMA_EN[2] - (RW)RX_DMA Enable +* 1: Enable RX_DMA, MUST wait until all +* prefetch rings' MAX_CNT(WPDMA_T(R)X_RING*_EXT_CTRL)of DMA including neighbor +* DMA have been configured successfully +* 0: Disable RX_DMA +* RX_DMA_BUSY[3] - (RO)RX_DMA Busy indicator +* 1: RX_DMA is busy +* 0: RX_DMA is not busy +* PDMA_BT_SIZE[5..4] - (RW)Define the burst size of WPDMA +* 2'h0 : 4 DWORD (16bytes) +* 2'h1 : 8 DWORD (32 bytes) +* 2'h2 : 16 DWORD (64 bytes) +* 2'h3 : 32 DWORD (128 bytes) +* TX_WB_DDONE[6] - (RW)1'b1 : TX engine will wait to assert IRQ +* util whole TX dmad has been fully written into AXI bus which represents HOST +* memory, 1'b0 : TX engine will assert IRQ once TX dmad write-back request have +* been ACKed +* BIG_ENDIAN[7] - (RW)The endian mode selection. DMA applies +* the endian rule to convert payload and TX/RX information. DMA won't apply +* endian rule to register or descriptor. +* 1: big endian. +* 0: little endian. +* DMAD_32B_EN[8] - (RW)DMA Descriptor 32-byte Enable +* 0: The size of descriptors is set to 16-byte +* 1: The size of descriptors is set to 32-byte +* FW_DWLD_Bypass_dmashdl[9] - (RW)No USE for (APSOC/PCIE)For firmware +* download packet, driver shold +* using tx-ring16 to download packet and set this bit to bypass dmashdl resource +* control. +* After firmware download finish, driver +* should clear this bit. +* After all, tx-ring16 could be used for +* normal data operation. For USB test_mode, user could set this bit +* to bypass dmashdl with all endpoint +* CSR_WFDMA_DUMMY_REG[10] - (RW)dummy CR for use if ECO needed +* CSR_AXI_BUFRDY_BYP[11] - (RW)to disable read data fifo available +* checking before issuing next AXI read request +* FIFO_LITTLE_ENDIAN[12] - (RW)Determines the endianness of the FIFO +* side +* 0: Big-endian +* 1: Little-endian +* CSR_RX_WB_DDONE[13] - (RW)1'b1 : RX engine will wait to assert IRQ +* util whole RX dmad has been fully written into AXI bus which represents HOST +* memory, 1'b0 : RX engine will assert IRQ once RX dmad write-back request have +* been ACKed +* CSR_PP_HIF_TXP_ACTIVE_EN[14] - (RW)1'b1 : enable legacy pp_hif_txp_active +* function to lock tx engine for favor TXP transmit requested directly from PP, +* other pdma TX rings request will be masked until pp_hif_txp_active is +* deasserted +* 1'b0 : disable legacy pp_hif_txp_active +* function, use latest TX source QoS design to change throttler settings to +* favor TXP transmit +* CSR_DISP_BASE_PTR_CHAIN_EN[15] - (RW)Enable prefet sram ring address +* arrangement by hardware chain structure(DMA#N TX ring group -> DMA#N RX ring +* group -> DMA#M TX ring group -> DMA#M RX ring group and son on). If not +* enabled, firmware need to program DISP_BASE_PTR of WPDMA_T(R)X_RING*_EXT_CTRL +* instead +* CSR_LBK_RX_Q_SEL[19..16] - (RW)loopback data from TXFIFO will be direct +* to this RX ring when CSR_LBK_RX_Q_SEL_EN in loopback mode, valid bit-width is +* equal to RX_RING_WIDTH which can be calculated from WPDMA_INFO 0x284[15:8] +* RX_RING_NUMBER +* CSR_LBK_RX_Q_SEL_EN[20] - (RW)Force configured CSR_LBK_RX_Q_SEL to +* receive loopback data from TXFIFO +* OMIT_RX_INFO_PFET2[21] - (RW)For loopback mode, set to 1'b1. +* For normal wifi data operation. User should +* not set this option and should keep 1'b0 because UMAC will always add extra QW +* for checksum after received packet's laster QW +* VERY IMPORTANT : for cpu_dma0/1 where CR +* resides in 0x5100_0xxx, OMIT_RX_INFO MUST be set to 1'b1 +* Omit rx_info of all RX packets +* 0: All the PX packets should end with a rx_info +* 1: All the PX packets should NOT end with a +* rx_info but an eof +* RESERVED22[23..22] - (RO)Reserved bits +* CSR_SW_RST[24] - (RO)SW reset all designs - To be tested for +* SER in the future. +* FORCE_TX_EOF[25] - (RW)Force to send an eof after PDMA being +* reset (for Packet_Processor) +* 0: Disabled +* 1: Enabled +* PDMA_ADDR_EXT_EN[26] - (RW)No Fnction for now!! For PDMA Address +* 32bits extension. When this design option was enable. PDMA would change Tx/Rx +* descriptor format for address extension. +* 0 : PDMA 32bits address +* 1 : PDMA Tx descirptor DW3 (TXINFO)would +* used to extend address +* PDMA Rx descirpt DW2 (Reserved)would used +* to extend address. +* OMIT_RX_INFO[27] - (RW)For loopback mode, set to 1'b1. +* For normal wifi data operation. User should +* not set this option and should keep 1'b0 because UMAC will always add extra QW +* for checksum after received packet's laster QW +* VERY IMPORTANT : for cpu_dma0/1 where CR +* resides in 0x5100_0xxx, OMIT_RX_INFO MUST be set to 1'b1 +* Omit rx_info of all RX packets +* 0: All the PX packets should end with a +* rx_info +* 1: All the PX packets should NOT end with a +* rx_info but an eof +* OMIT_TX_INFO[28] - (RW)For loopback mode, set to 1'b1. +* For normal wifi data operation. User should +* set this option to +* Omit tx_info of all TX packets because UMAC +* design not support TXINFO +* 0: The tx_info in DMAD will be sent at the +* beginning +* 1: The tx_info in DMAD will NOT be sent at +* the beginning +* BYTE_SWAP[29] - (RW)Byte Swapping for TX/RX DMAD +* 0: Not to swap (Endian of DMAD unchanged) +* 1: Swap (Endian of DMAD reversed) +* CLK_GATE_DIS[30] - (RW)PDMA Clock Gated Function Disable +* 0: normal function +* 1: disable clock gated function +* RX_2B_OFFSET[31] - (RW)RX PBF 2-byte Offset +* 1: Skip the first two bytes of the RX PBF +* 0: Not to skip the first two bytes of the +* RX PBF +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_RX_2B_OFFSET_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_RX_2B_OFFSET_MASK \ +0x80000000 /* RX_2B_OFFSET[31] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_RX_2B_OFFSET_SHFT 31 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CLK_GATE_DIS_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CLK_GATE_DIS_MASK \ +0x40000000 /* CLK_GATE_DIS[30] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CLK_GATE_DIS_SHFT 30 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_BYTE_SWAP_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_BYTE_SWAP_MASK \ +0x20000000 /* BYTE_SWAP[29] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_BYTE_SWAP_SHFT 29 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_OMIT_TX_INFO_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_OMIT_TX_INFO_MASK \ +0x10000000 /* OMIT_TX_INFO[28] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_OMIT_TX_INFO_SHFT 28 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_OMIT_RX_INFO_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_OMIT_RX_INFO_MASK \ +0x08000000 /* OMIT_RX_INFO[27] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_OMIT_RX_INFO_SHFT 27 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_PDMA_ADDR_EXT_EN_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_PDMA_ADDR_EXT_EN_MASK \ +0x04000000 /* PDMA_ADDR_EXT_EN[26] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_PDMA_ADDR_EXT_EN_SHFT 26 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_FORCE_TX_EOF_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_FORCE_TX_EOF_MASK \ +0x02000000 /* FORCE_TX_EOF[25] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_FORCE_TX_EOF_SHFT 25 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_SW_RST_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_SW_RST_MASK \ +0x01000000 /* CSR_SW_RST[24] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_SW_RST_SHFT 24 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_OMIT_RX_INFO_PFET2_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_OMIT_RX_INFO_PFET2_MASK \ +0x00200000 /* OMIT_RX_INFO_PFET2[21] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_OMIT_RX_INFO_PFET2_SHFT 21 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_LBK_RX_Q_SEL_EN_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_LBK_RX_Q_SEL_EN_MASK \ +0x00100000 /* CSR_LBK_RX_Q_SEL_EN[20] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_LBK_RX_Q_SEL_EN_SHFT 20 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_LBK_RX_Q_SEL_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_LBK_RX_Q_SEL_MASK \ +0x000F0000 /* CSR_LBK_RX_Q_SEL[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_LBK_RX_Q_SEL_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN_MASK \ +0x00008000 /* CSR_DISP_BASE_PTR_CHAIN_EN[15] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN_SHFT 15 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_PP_HIF_TXP_ACTIVE_EN_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_PP_HIF_TXP_ACTIVE_EN_MASK \ +0x00004000 /* CSR_PP_HIF_TXP_ACTIVE_EN[14] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_PP_HIF_TXP_ACTIVE_EN_SHFT 14 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_RX_WB_DDONE_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_RX_WB_DDONE_MASK \ +0x00002000 /* CSR_RX_WB_DDONE[13] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_RX_WB_DDONE_SHFT 13 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_FIFO_LITTLE_ENDIAN_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_FIFO_LITTLE_ENDIAN_MASK \ +0x00001000 /* FIFO_LITTLE_ENDIAN[12] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_FIFO_LITTLE_ENDIAN_SHFT 12 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_AXI_BUFRDY_BYP_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_AXI_BUFRDY_BYP_MASK \ +0x00000800 /* CSR_AXI_BUFRDY_BYP[11] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_AXI_BUFRDY_BYP_SHFT 11 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_WFDMA_DUMMY_REG_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_WFDMA_DUMMY_REG_MASK \ +0x00000400 /* CSR_WFDMA_DUMMY_REG[10] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_WFDMA_DUMMY_REG_SHFT 10 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_FW_DWLD_Bypass_dmashdl_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_FW_DWLD_Bypass_dmashdl_MASK \ +0x00000200 /* FW_DWLD_Bypass_dmashdl[9] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_FW_DWLD_Bypass_dmashdl_SHFT 9 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_DMAD_32B_EN_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_DMAD_32B_EN_MASK \ +0x00000100 /* DMAD_32B_EN[8] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_DMAD_32B_EN_SHFT 8 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_BIG_ENDIAN_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_BIG_ENDIAN_MASK \ +0x00000080 /* BIG_ENDIAN[7] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_BIG_ENDIAN_SHFT 7 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_TX_WB_DDONE_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_TX_WB_DDONE_MASK \ +0x00000040 /* TX_WB_DDONE[6] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_TX_WB_DDONE_SHFT 6 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_PDMA_BT_SIZE_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_PDMA_BT_SIZE_MASK \ +0x00000030 /* PDMA_BT_SIZE[5..4] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_PDMA_BT_SIZE_SHFT 4 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_RX_DMA_BUSY_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_RX_DMA_BUSY_MASK \ +0x00000008 /* RX_DMA_BUSY[3] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_RX_DMA_BUSY_SHFT 3 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_RX_DMA_EN_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_RX_DMA_EN_MASK \ +0x00000004 /* RX_DMA_EN[2] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_RX_DMA_EN_SHFT 2 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_TX_DMA_BUSY_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_TX_DMA_BUSY_MASK \ +0x00000002 /* TX_DMA_BUSY[1] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_TX_DMA_BUSY_SHFT 1 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_TX_DMA_EN_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_TX_DMA_EN_MASK \ +0x00000001 /* TX_DMA_EN[0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_TX_DMA_EN_SHFT 0 + +/* +* ---WPDMA_RST_DTX_PTR (0x18024000 + 0x20C)--- +* RST_DTX_IDX0[0] - (WO) Write 1 to reset to TX_DMATX_IDX0 to 0 +* RST_DTX_IDX1[1] - (WO) Write 1 to reset to TX_DMATX_IDX1 to 0 +* RST_DTX_IDX2[2] - (WO) Write 1 to reset to TX_DMATX_IDX2 to 0 +* RST_DTX_IDX3[3] - (WO) Write 1 to reset to TX_DMATX_IDX3 to 0 +* RST_DTX_IDX4[4] - (WO) Write 1 to reset to TX_DMATX_IDX4 to 0 +* RST_DTX_IDX5[5] - (WO) Write 1 to reset to TX_DMATX_IDX5 to 0 +* RST_DTX_IDX6[6] - (WO) Write 1 to reset to TX_DMATX_IDX6 to 0 +* RST_DTX_IDX7[7] - (WO) Write 1 to reset to TX_DMATX_IDX7 to 0 +* RST_DTX_IDX8[8] - (WO) Write 1 to reset to TX_DMATX_IDX8 to 0 +* RST_DTX_IDX9[9] - (WO) Write 1 to reset to TX_DMATX_IDX9 to 0 +* RST_DTX_IDX10[10] - (WO) Write 1 to reset to TX_DMATX_IDX10 to 0 +* RST_DTX_IDX11[11] - (WO) Write 1 to reset to TX_DMATX_IDX11 to 0 +* RST_DTX_IDX12[12] - (WO) Write 1 to reset to TX_DMATX_IDX12 to 0 +* RST_DTX_IDX13[13] - (WO) Write 1 to reset to TX_DMATX_IDX13 to 0 +* RST_DTX_IDX14[14] - (WO) Write 1 to reset to TX_DMATX_IDX14 to 0 +* RST_DTX_IDX15[15] - (WO) Write 1 to reset to TX_DMATX_IDX15 to 0 +* RST_DTX_IDX16[16] - (WO) Write 1 to reset to TX_DMATX_IDX16 to 0 +* RST_DTX_IDX17[17] - (WO) Write 1 to reset to TX_DMATX_IDX17 to 0 +* RST_DTX_IDX18[18] - (WO) Write 1 to reset to TX_DMATX_IDX18 to 0 +* RST_DTX_IDX19[19] - (WO) Write 1 to reset to TX_DMATX_IDX19 to 0 +* RST_DTX_IDX20[20] - (WO) Write 1 to reset to TX_DMATX_IDX20 to 0 +* RESERVED21[31..21] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX20_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX20_MASK \ +0x00100000 /* RST_DTX_IDX20[20] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX20_SHFT 20 +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX19_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX19_MASK \ +0x00080000 /* RST_DTX_IDX19[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX19_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX18_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX18_MASK \ +0x00040000 /* RST_DTX_IDX18[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX18_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX17_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX17_MASK \ +0x00020000 /* RST_DTX_IDX17[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX17_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX16_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX16_MASK \ +0x00010000 /* RST_DTX_IDX16[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX16_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX15_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX15_MASK \ +0x00008000 /* RST_DTX_IDX15[15] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX15_SHFT 15 +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX14_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX14_MASK \ +0x00004000 /* RST_DTX_IDX14[14] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX14_SHFT 14 +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX13_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX13_MASK \ +0x00002000 /* RST_DTX_IDX13[13] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX13_SHFT 13 +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX12_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX12_MASK \ +0x00001000 /* RST_DTX_IDX12[12] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX12_SHFT 12 +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX11_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX11_MASK \ +0x00000800 /* RST_DTX_IDX11[11] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX11_SHFT 11 +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX10_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX10_MASK \ +0x00000400 /* RST_DTX_IDX10[10] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX10_SHFT 10 +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX9_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX9_MASK \ +0x00000200 /* RST_DTX_IDX9[9] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX9_SHFT 9 +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX8_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX8_MASK \ +0x00000100 /* RST_DTX_IDX8[8] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX8_SHFT 8 +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX7_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX7_MASK \ +0x00000080 /* RST_DTX_IDX7[7] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX7_SHFT 7 +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX6_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX6_MASK \ +0x00000040 /* RST_DTX_IDX6[6] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX6_SHFT 6 +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX5_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX5_MASK \ +0x00000020 /* RST_DTX_IDX5[5] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX5_SHFT 5 +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX4_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX4_MASK \ +0x00000010 /* RST_DTX_IDX4[4] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX4_SHFT 4 +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX3_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX3_MASK \ +0x00000008 /* RST_DTX_IDX3[3] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX3_SHFT 3 +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX2_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX2_MASK \ +0x00000004 /* RST_DTX_IDX2[2] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX2_SHFT 2 +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX1_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX1_MASK \ +0x00000002 /* RST_DTX_IDX1[1] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX1_SHFT 1 +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX0_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX0_MASK \ +0x00000001 /* RST_DTX_IDX0[0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX0_SHFT 0 + +/* +* ---WPDMA_PAUSE_TX_Q (0x18024000 + 0x224)--- +* TX_Q_PAUSE[31..0] - (RW) Pause signal for each TX ring (16 bits +* for 16 rings) +* Set 0: Normal function; Set 1: The +* corresponding TX ring is paused +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_TX_Q_TX_Q_PAUSE_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_TX_Q_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_TX_Q_TX_Q_PAUSE_MASK \ +0xFFFFFFFF /* TX_Q_PAUSE[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_TX_Q_TX_Q_PAUSE_SHFT 0 + +/* +* ---HOST_INT_ENA_SET (0x18024000 + 0X228)--- +* HOST_RX_DONE_INT_ENA0[0] - (W1S) RX Queue#0 packet receive interrupt +* HOST_RX_DONE_INT_ENA1[1] - (W1S) RX Queue#1 packet receive interrupt +* HOST_RX_DONE_INT_ENA2[2] - (W1S) RX Queue#2 packet receive interrupt +* HOST_RX_DONE_INT_ENA3[3] - (W1S) RX Queue#3 packet receive interrupt +* HOST_TX_DONE_INT_ENA0[4] - (W1S) TX Queue#0 packet transmit interrupt +* HOST_TX_DONE_INT_ENA1[5] - (W1S) TX Queue#1 packet transmit interrupt +* HOST_TX_DONE_INT_ENA2[6] - (W1S) TX Queue#2 packet transmit interrupt +* HOST_TX_DONE_INT_ENA3[7] - (W1S) TX Queue#3 packet transmit interrupt +* HOST_TX_DONE_INT_ENA4[8] - (W1S) TX Queue#4 packet transmit interrupt +* HOST_TX_DONE_INT_ENA5[9] - (W1S) TX Queue#5 packet transmit interrupt +* HOST_TX_DONE_INT_ENA6[10] - (W1S) TX Queue#6 packet transmit interrupt +* HOST_TX_DONE_INT_ENA7[11] - (W1S) TX Queue#7 packet transmit interrupt +* HOST_TX_DONE_INT_ENA8[12] - (W1S) TX Queue#8 packet transmit interrupt +* HOST_TX_DONE_INT_ENA9[13] - (W1S) TX Queue#9 packet transmit interrupt +* HOST_TX_DONE_INT_ENA10[14] - (W1S) TX Queue#10 packet transmit interrupt +* HOST_TX_DONE_INT_ENA11[15] - (W1S) TX Queue#11 packet transmit interrupt +* HOST_TX_DONE_INT_ENA12[16] - (W1S) TX Queue#12 packet transmit interrupt +* HOST_TX_DONE_INT_ENA13[17] - (W1S) TX Queue#13 packet transmit interrupt +* HOST_TX_DONE_INT_ENA14[18] - (W1S) TX Queue#14 packet transmit interrupt +* RESERVED19[19] - (RO) Reserved bits +* HOST_RX_COHERENT_EN[20] - (W1S) Enable for RX_DMA data coherent +interrupt +* HOST_TX_COHERENT_EN[21] - (W1S) Enable for TX_DMA data coherent +interrupt +* HOST_RX_DONE_INT_ENA4[22] - (W1S) RX Queue#4 packet receive interrupt +* HOST_RX_DONE_INT_ENA5[23] - (W1S) RX Queue#5 packet receive interrupt +* wpdma2host_err_int_ena[24] - (W1S) Enable bit of wpdma2host_err_int +* RESERVED25[25] - (RO) Reserved bits +* HOST_TX_DONE_INT_ENA16[26] - (W1S) TX Queue#16 packet transmit interrupt +* HOST_TX_DONE_INT_ENA17[27] - (W1S) TX Queue#17 packet transmit interrupt +* subsys_int_ena[28] - (W1S) Enable bit of subsys_int +* mcu2host_sw_int_ena[29] - (W1S) Enable bit of mcu2host_sw_int +* HOST_TX_DONE_INT_ENA18[30] - (W1S) TX Queue#18 packet transmit interrupt +* RESERVED31[31] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA18_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA18_MASK \ +0x40000000 /* HOST_TX_DONE_INT_ENA18[30] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA18_SHFT 30 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_mcu2host_sw_int_ena_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_mcu2host_sw_int_ena_MASK \ +0x20000000 /* mcu2host_sw_int_ena[29] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_mcu2host_sw_int_ena_SHFT 29 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_subsys_int_ena_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_subsys_int_ena_MASK \ +0x10000000 /* subsys_int_ena[28] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_subsys_int_ena_SHFT 28 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA17_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA17_MASK \ +0x08000000 /* HOST_TX_DONE_INT_ENA17[27] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA17_SHFT 27 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA16_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA16_MASK \ +0x04000000 /* HOST_TX_DONE_INT_ENA16[26] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA16_SHFT 26 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_wpdma2host_err_int_ena_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_wpdma2host_err_int_ena_MASK \ +0x01000000 /* wpdma2host_err_int_ena[24] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_wpdma2host_err_int_ena_SHFT 24 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA5_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA5_MASK \ +0x00800000 /* HOST_RX_DONE_INT_ENA5[23] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA5_SHFT 23 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA4_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA4_MASK \ +0x00400000 /* HOST_RX_DONE_INT_ENA4[22] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA4_SHFT 22 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_COHERENT_EN_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_COHERENT_EN_MASK \ +0x00200000 /* HOST_TX_COHERENT_EN[21] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_COHERENT_EN_SHFT 21 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_COHERENT_EN_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_COHERENT_EN_MASK \ +0x00100000 /* HOST_RX_COHERENT_EN[20] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_COHERENT_EN_SHFT 20 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA14_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA14_MASK \ +0x00040000 /* HOST_TX_DONE_INT_ENA14[18] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA14_SHFT 18 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA13_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA13_MASK \ +0x00020000 /* HOST_TX_DONE_INT_ENA13[17] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA13_SHFT 17 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA12_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA12_MASK \ +0x00010000 /* HOST_TX_DONE_INT_ENA12[16] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA12_SHFT 16 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA11_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA11_MASK \ +0x00008000 /* HOST_TX_DONE_INT_ENA11[15] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA11_SHFT 15 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA10_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA10_MASK \ +0x00004000 /* HOST_TX_DONE_INT_ENA10[14] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA10_SHFT 14 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA9_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA9_MASK \ +0x00002000 /* HOST_TX_DONE_INT_ENA9[13] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA9_SHFT 13 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA8_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA8_MASK \ +0x00001000 /* HOST_TX_DONE_INT_ENA8[12] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA8_SHFT 12 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA7_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA7_MASK \ +0x00000800 /* HOST_TX_DONE_INT_ENA7[11] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA7_SHFT 11 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA6_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA6_MASK \ +0x00000400 /* HOST_TX_DONE_INT_ENA6[10] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA6_SHFT 10 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA5_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA5_MASK \ +0x00000200 /* HOST_TX_DONE_INT_ENA5[9] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA5_SHFT 9 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA4_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA4_MASK \ +0x00000100 /* HOST_TX_DONE_INT_ENA4[8] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA4_SHFT 8 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA3_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA3_MASK \ +0x00000080 /* HOST_TX_DONE_INT_ENA3[7] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA3_SHFT 7 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA2_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA2_MASK \ +0x00000040 /* HOST_TX_DONE_INT_ENA2[6] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA2_SHFT 6 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA1_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA1_MASK \ +0x00000020 /* HOST_TX_DONE_INT_ENA1[5] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA1_SHFT 5 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA0_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA0_MASK \ +0x00000010 /* HOST_TX_DONE_INT_ENA0[4] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA0_SHFT 4 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA3_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA3_MASK \ +0x00000008 /* HOST_RX_DONE_INT_ENA3[3] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA3_SHFT 3 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA2_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA2_MASK \ +0x00000004 /* HOST_RX_DONE_INT_ENA2[2] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA2_SHFT 2 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA1_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA1_MASK \ +0x00000002 /* HOST_RX_DONE_INT_ENA1[1] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA1_SHFT 1 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA0_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA0_MASK \ +0x00000001 /* HOST_RX_DONE_INT_ENA0[0] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA0_SHFT 0 + +/* +* ---HOST_INT_ENA_CLR (0x18024000 + 0X22C)--- +* HOST_RX_DONE_INT_ENA0[0] - (W1C) RX Queue#0 packet receive interrupt +* HOST_RX_DONE_INT_ENA1[1] - (W1C) RX Queue#1 packet receive interrupt +* HOST_RX_DONE_INT_ENA2[2] - (W1C) RX Queue#2 packet receive interrupt +* HOST_RX_DONE_INT_ENA3[3] - (W1C) RX Queue#3 packet receive interrupt +* HOST_TX_DONE_INT_ENA0[4] - (W1C) TX Queue#0 packet transmit interrupt +* HOST_TX_DONE_INT_ENA1[5] - (W1C) TX Queue#1 packet transmit interrupt +* HOST_TX_DONE_INT_ENA2[6] - (W1C) TX Queue#2 packet transmit interrupt +* HOST_TX_DONE_INT_ENA3[7] - (W1C) TX Queue#3 packet transmit interrupt +* HOST_TX_DONE_INT_ENA4[8] - (W1C) TX Queue#4 packet transmit interrupt +* HOST_TX_DONE_INT_ENA5[9] - (W1C) TX Queue#5 packet transmit interrupt +* HOST_TX_DONE_INT_ENA6[10] - (W1C) TX Queue#6 packet transmit interrupt +* HOST_TX_DONE_INT_ENA7[11] - (W1C) TX Queue#7 packet transmit interrupt +* HOST_TX_DONE_INT_ENA8[12] - (W1C) TX Queue#8 packet transmit interrupt +* HOST_TX_DONE_INT_ENA9[13] - (W1C) TX Queue#9 packet transmit interrupt +* HOST_TX_DONE_INT_ENA10[14] - (W1C) TX Queue#10 packet transmit interrupt +* HOST_TX_DONE_INT_ENA11[15] - (W1C) TX Queue#11 packet transmit interrupt +* HOST_TX_DONE_INT_ENA12[16] - (W1C) TX Queue#12 packet transmit interrupt +* HOST_TX_DONE_INT_ENA13[17] - (W1C) TX Queue#13 packet transmit interrupt +* HOST_TX_DONE_INT_ENA14[18] - (W1C) TX Queue#14 packet transmit interrupt +* RESERVED19[19] - (RO) Reserved bits +* HOST_RX_COHERENT_EN[20] - (W1C) Enable for RX_DMA data coherent +interrupt +* HOST_TX_COHERENT_EN[21] - (W1C) Enable for TX_DMA data coherent +interrupt +* HOST_RX_DONE_INT_ENA4[22] - (W1C) RX Queue#4 packet receive interrupt +* HOST_RX_DONE_INT_ENA5[23] - (W1C) RX Queue#5 packet receive interrupt +* wpdma2host_err_int_ena[24] - (W1C) Enable bit of wpdma2host_err_int +* RESERVED25[25] - (RO) Reserved bits +* HOST_TX_DONE_INT_ENA16[26] - (W1C) TX Queue#16 packet transmit interrupt +* HOST_TX_DONE_INT_ENA17[27] - (W1C) TX Queue#17 packet transmit interrupt +* subsys_int_ena[28] - (W1C) Enable bit of subsys_int +* mcu2host_sw_int_ena[29] - (W1C) Enable bit of mcu2host_sw_int +* HOST_TX_DONE_INT_ENA18[30] - (W1C) TX Queue#18 packet transmit interrupt +* RESERVED31[31] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA18_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA18_MASK \ +0x40000000 /* HOST_TX_DONE_INT_ENA18[30] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA18_SHFT 30 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_mcu2host_sw_int_ena_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_mcu2host_sw_int_ena_MASK \ +0x20000000 /* mcu2host_sw_int_ena[29] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_mcu2host_sw_int_ena_SHFT 29 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_subsys_int_ena_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_subsys_int_ena_MASK \ +0x10000000 /* subsys_int_ena[28] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_subsys_int_ena_SHFT 28 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA17_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA17_MASK \ +0x08000000 /* HOST_TX_DONE_INT_ENA17[27] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA17_SHFT 27 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA16_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA16_MASK \ +0x04000000 /* HOST_TX_DONE_INT_ENA16[26] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA16_SHFT 26 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_wpdma2host_err_int_ena_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_wpdma2host_err_int_ena_MASK \ +0x01000000 /* wpdma2host_err_int_ena[24] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_wpdma2host_err_int_ena_SHFT 24 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA5_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA5_MASK \ +0x00800000 /* HOST_RX_DONE_INT_ENA5[23] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA5_SHFT 23 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA4_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA4_MASK \ +0x00400000 /* HOST_RX_DONE_INT_ENA4[22] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA4_SHFT 22 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_COHERENT_EN_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_COHERENT_EN_MASK \ +0x00200000 /* HOST_TX_COHERENT_EN[21] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_COHERENT_EN_SHFT 21 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_COHERENT_EN_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_COHERENT_EN_MASK \ +0x00100000 /* HOST_RX_COHERENT_EN[20] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_COHERENT_EN_SHFT 20 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA14_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA14_MASK \ +0x00040000 /* HOST_TX_DONE_INT_ENA14[18] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA14_SHFT 18 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA13_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA13_MASK \ +0x00020000 /* HOST_TX_DONE_INT_ENA13[17] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA13_SHFT 17 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA12_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA12_MASK \ +0x00010000 /* HOST_TX_DONE_INT_ENA12[16] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA12_SHFT 16 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA11_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA11_MASK \ +0x00008000 /* HOST_TX_DONE_INT_ENA11[15] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA11_SHFT 15 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA10_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA10_MASK \ +0x00004000 /* HOST_TX_DONE_INT_ENA10[14] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA10_SHFT 14 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA9_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA9_MASK \ +0x00002000 /* HOST_TX_DONE_INT_ENA9[13] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA9_SHFT 13 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA8_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA8_MASK \ +0x00001000 /* HOST_TX_DONE_INT_ENA8[12] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA8_SHFT 12 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA7_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA7_MASK \ +0x00000800 /* HOST_TX_DONE_INT_ENA7[11] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA7_SHFT 11 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA6_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA6_MASK \ +0x00000400 /* HOST_TX_DONE_INT_ENA6[10] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA6_SHFT 10 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA5_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA5_MASK \ +0x00000200 /* HOST_TX_DONE_INT_ENA5[9] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA5_SHFT 9 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA4_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA4_MASK \ +0x00000100 /* HOST_TX_DONE_INT_ENA4[8] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA4_SHFT 8 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA3_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA3_MASK \ +0x00000080 /* HOST_TX_DONE_INT_ENA3[7] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA3_SHFT 7 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA2_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA2_MASK \ +0x00000040 /* HOST_TX_DONE_INT_ENA2[6] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA2_SHFT 6 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA1_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA1_MASK \ +0x00000020 /* HOST_TX_DONE_INT_ENA1[5] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA1_SHFT 5 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA0_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA0_MASK \ +0x00000010 /* HOST_TX_DONE_INT_ENA0[4] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA0_SHFT 4 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA3_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA3_MASK \ +0x00000008 /* HOST_RX_DONE_INT_ENA3[3] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA3_SHFT 3 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA2_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA2_MASK \ +0x00000004 /* HOST_RX_DONE_INT_ENA2[2] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA2_SHFT 2 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA1_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA1_MASK \ +0x00000002 /* HOST_RX_DONE_INT_ENA1[1] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA1_SHFT 1 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA0_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA0_MASK \ +0x00000001 /* HOST_RX_DONE_INT_ENA0[0] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA0_SHFT 0 + +/* +* ---WPDMA_TIMEOUT_CFG (0x18024000 + 0x230)--- +* WPDMA_TX_TIMEOUT_TH[7..0] - (RW) xxx +* WPDMA_TX_TIMEOUT_TICK[14..8] - (RW) xxx +* WPDMA_TX_TIMEOUT_ENA[15] - (RW) xxx +* WPDMA_RX_TIMEOUT_TH[23..16] - (RW) xxx +* WPDMA_RX_TIMEOUT_TICK[30..24] - (RW) xxx +* WPDMA_RX_TIMEOUT_ENA[31] - (RW) xxx +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_ENA_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_ENA_MASK \ +0x80000000 /* WPDMA_RX_TIMEOUT_ENA[31] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_ENA_SHFT 31 +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_TICK_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_TICK_MASK \ +0x7F000000 /* WPDMA_RX_TIMEOUT_TICK[30..24] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_TICK_SHFT 24 +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_TH_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_TH_MASK \ +0x00FF0000 /* WPDMA_RX_TIMEOUT_TH[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_TH_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_ENA_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_ENA_MASK \ +0x00008000 /* WPDMA_TX_TIMEOUT_ENA[15] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_ENA_SHFT 15 +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_TICK_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_TICK_MASK \ +0x00007F00 /* WPDMA_TX_TIMEOUT_TICK[14..8] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_TICK_SHFT 8 +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_TH_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_TH_MASK \ +0x000000FF /* WPDMA_TX_TIMEOUT_TH[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_TH_SHFT 0 + +/* +* ---WPDMA_MISC_CFG (0x18024000 + 0x234)--- +* WPDMA_TX_TIMEOUT_SEL[0] - (RW) xxx +* WPDMA_RX_TIMEOUT_SEL[1] - (RW) xxx +* WPDMA_RX_FREE_Q_TH[5..2] - (RW) When loopback, this will be used to +* generate correct tx_pause to avlid deadlock which caused from situration that +* tx_dma will start reading tx packet from memory without considering lack of RX +* dmad in prefetch sram and needing to read RX dmad from memory which tx dma is +* reading tx packet too and rready is deasserted due to txfifo full !! +* RX dmad in prefetch sram should be greater +* than RX_FREE_Q_TH for rx_dma to start writing received packet into memory!! +* RESERVED6[31..6] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_MISC_CFG_WPDMA_RX_FREE_Q_TH_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_MISC_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_MISC_CFG_WPDMA_RX_FREE_Q_TH_MASK \ +0x0000003C /* WPDMA_RX_FREE_Q_TH[5..2] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_MISC_CFG_WPDMA_RX_FREE_Q_TH_SHFT 2 +#define WF_WFDMA_HOST_DMA0_WPDMA_MISC_CFG_WPDMA_RX_TIMEOUT_SEL_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_MISC_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_MISC_CFG_WPDMA_RX_TIMEOUT_SEL_MASK \ +0x00000002 /* WPDMA_RX_TIMEOUT_SEL[1] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_MISC_CFG_WPDMA_RX_TIMEOUT_SEL_SHFT 1 +#define WF_WFDMA_HOST_DMA0_WPDMA_MISC_CFG_WPDMA_TX_TIMEOUT_SEL_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_MISC_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_MISC_CFG_WPDMA_TX_TIMEOUT_SEL_MASK \ +0x00000001 /* WPDMA_TX_TIMEOUT_SEL[0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_MISC_CFG_WPDMA_TX_TIMEOUT_SEL_SHFT 0 + +/* +* ---WPDMA_TX_WRR_ARB_GBF0 (0x18024000 + 0x240)--- +* WRR_REQ0_ARB_GBF[2..0] - (RW) WRR REQ#0 priority level, mapped to +* lumpped request from TX ring0~ring15 for host TXD +* WRR_REQ1_ARB_GBF[5..3] - (RW) WRR REQ#1 priority level, mapped to +* request from TX ring16 when dual tx fifo for host event packet +* WRR_REQ2_ARB_GBF[8..6] - (RW) WRR REQ#2 priority level, mapped to +* request from TX ring17 when dual tx fifo for host event packet +* WRR_REQ3_ARB_GBF[11..9] - (RW) WRR REQ#3 priority level, mapped to +* request from TX ring18 when dual tx fifo for host event packet +* WRR_REQ4_ARB_GBF[14..12] - (RW) WRR REQ#4 priority level, mapped to +* request from TX ring19 when dual tx fifo for host event packet +* RESERVED[31..15] - (RW) Reserved +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ4_ARB_GBF_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ4_ARB_GBF_MASK \ +0x00007000 /* WRR_REQ4_ARB_GBF[14..12] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ4_ARB_GBF_SHFT 12 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ3_ARB_GBF_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ3_ARB_GBF_MASK \ +0x00000E00 /* WRR_REQ3_ARB_GBF[11..9] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ3_ARB_GBF_SHFT 9 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ2_ARB_GBF_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ2_ARB_GBF_MASK \ +0x000001C0 /* WRR_REQ2_ARB_GBF[8..6] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ2_ARB_GBF_SHFT 6 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ1_ARB_GBF_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ1_ARB_GBF_MASK \ +0x00000038 /* WRR_REQ1_ARB_GBF[5..3] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ1_ARB_GBF_SHFT 3 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ0_ARB_GBF_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ0_ARB_GBF_MASK \ +0x00000007 /* WRR_REQ0_ARB_GBF[2..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ0_ARB_GBF_SHFT 0 + +/* +* ---WPDMA_PAUSE_RX_Q_TH10 (0x18024000 + 0x260)--- +* RX_DMAD_TH0[11..0] - (RW) RX Ring0 DMAD threshold to pause PP +* sending packet to RX FIFO +* pause_rx_q = (available RX DMAD counts) < + +* RESERVED12[15..12] - (RO) Reserved bits +* RX_DMAD_TH1[27..16] - (RW) RX Ring1 DMAD threshold to pause PP +* sending packet to RX FIFO +* pause_rx_q = (available RX DMAD counts) < + +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH10_RX_DMAD_TH1_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH10_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH10_RX_DMAD_TH1_MASK \ +0x0FFF0000 /* RX_DMAD_TH1[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH10_RX_DMAD_TH1_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH10_RX_DMAD_TH0_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH10_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH10_RX_DMAD_TH0_MASK \ +0x00000FFF /* RX_DMAD_TH0[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH10_RX_DMAD_TH0_SHFT 0 + +/* +* ---WPDMA_PAUSE_RX_Q_TH32 (0x18024000 + 0x264)--- +* RX_DMAD_TH2[11..0] - (RW) RX Ring2 DMAD threshold to pause PP +* sending packet to RX FIFO +* pause_rx_q = (available RX DMAD counts) < + +* RESERVED12[15..12] - (RO) Reserved bits +* RX_DMAD_TH3[27..16] - (RW) RX Ring3 DMAD threshold to pause PP +* sending packet to RX FIFO +* pause_rx_q = (available RX DMAD counts) < + +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH32_RX_DMAD_TH3_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH32_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH32_RX_DMAD_TH3_MASK \ +0x0FFF0000 /* RX_DMAD_TH3[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH32_RX_DMAD_TH3_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH32_RX_DMAD_TH2_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH32_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH32_RX_DMAD_TH2_MASK \ +0x00000FFF /* RX_DMAD_TH2[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH32_RX_DMAD_TH2_SHFT 0 + +/* +* ---WPDMA_PAUSE_RX_Q_TH54 (0x18024000 + 0x268)--- +* RX_DMAD_TH4[11..0] - (RW) RX Ring4 DMAD threshold to pause PP +* sending packet to RX FIFO +* pause_rx_q = (available RX DMAD counts) < + +* RESERVED12[15..12] - (RO) Reserved bits +* RX_DMAD_TH5[27..16] - (RW) RX Ring5 DMAD threshold to pause PP +* sending packet to RX FIFO +* pause_rx_q = (available RX DMAD counts) < + +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH54_RX_DMAD_TH5_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH54_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH54_RX_DMAD_TH5_MASK \ +0x0FFF0000 /* RX_DMAD_TH5[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH54_RX_DMAD_TH5_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH54_RX_DMAD_TH4_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH54_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH54_RX_DMAD_TH4_MASK \ +0x00000FFF /* RX_DMAD_TH4[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH54_RX_DMAD_TH4_SHFT 0 + +/* +* ---WPDMA_PAUSE_RX_Q_TH76 (0x18024000 + 0x26C)--- +* RX_DMAD_TH6[11..0] - (RW) RX Ring6 DMAD threshold to pause PP +* sending packet to RX FIFO +* pause_rx_q = (available RX DMAD counts) < + +* RESERVED12[15..12] - (RO) Reserved bits +* RX_DMAD_TH7[27..16] - (RW) RX Ring7 DMAD threshold to pause PP +* sending packet to RX FIFO +* pause_rx_q = (available RX DMAD counts) < + +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH76_RX_DMAD_TH7_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH76_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH76_RX_DMAD_TH7_MASK \ +0x0FFF0000 /* RX_DMAD_TH7[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH76_RX_DMAD_TH7_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH76_RX_DMAD_TH6_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH76_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH76_RX_DMAD_TH6_MASK \ +0x00000FFF /* RX_DMAD_TH6[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH76_RX_DMAD_TH6_SHFT 0 + +/* +* ---WPDMA_RST_DRX_PTR (0x18024000 + 0x280)--- +* RST_DRX_IDX0[0] - (WO) Write 1 to reset to RX_DMARX_IDX0 to 0 +* RST_DRX_IDX1[1] - (WO) Write 1 to reset to RX_DMARX_IDX1 to 0 +* RST_DRX_IDX2[2] - (WO) Write 1 to reset to RX_DMARX_IDX2 to 0 +* RST_DRX_IDX3[3] - (WO) Write 1 to reset to RX_DMARX_IDX3 to 0 +* RESERVED[31..4] - (WO) Reserved +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_RST_DRX_IDX3_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_RST_DRX_IDX3_MASK \ +0x00000008 /* RST_DRX_IDX3[3] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_RST_DRX_IDX3_SHFT 3 +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_RST_DRX_IDX2_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_RST_DRX_IDX2_MASK \ +0x00000004 /* RST_DRX_IDX2[2] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_RST_DRX_IDX2_SHFT 2 +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_RST_DRX_IDX1_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_RST_DRX_IDX1_MASK \ +0x00000002 /* RST_DRX_IDX1[1] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_RST_DRX_IDX1_SHFT 1 +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_RST_DRX_IDX0_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_RST_DRX_IDX0_MASK \ +0x00000001 /* RST_DRX_IDX0[0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_RST_DRX_IDX0_SHFT 0 + +/* +* ---WPDMA_INFO (0x18024000 + 0x284)--- +* TX_RING_NUMBER[7..0] - (RO) TX_RING_NUMBER +* RX_RING_NUMBER[15..8] - (RO) RX_RING_NUMBER +* BASE_PTR_WIDTH[23..16] - (RO) {2'h0, 6'd32-'BASE_PTR_WIDTH[5:0]} +* INDEX_WIDTH[27..24] - (RO) RING_INDEX_WIDTH +* PDMA_PREFETCH_SRAM_SIZE[30..28] - (RO) PDMA prefetch sram size{3'h0 : 128 +* byte, 3'h1 : 256 byte, 3'h2 : 512 byte, 3'h3 : 1KB, 3'h4 : 2KB, 3'h5 : 4KB, +* 3'h6 : 8KB, 3'h7 : reserved}, be noticed that prefetch sram is shared outside +* with other DMAs, please check all DMAs' total prefetch ring number and max_cnt +* for each prefetch ring to make sure that total size of all configured prefetch +* dmad of all DMAs' prefetch ring should be less than PDMA_PREFETCH_SRAM_SIZE +* WFDMA_PDA_EXIST[31] - (RO) Only cpu_dma1 will support pda functions +* for firmware download and wfdma_pda_top resides in between cpu_dma0 and +cpu_dma1! +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_WFDMA_PDA_EXIST_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_INFO_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_WFDMA_PDA_EXIST_MASK \ +0x80000000 /* WFDMA_PDA_EXIST[31] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_WFDMA_PDA_EXIST_SHFT 31 +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_PDMA_PREFETCH_SRAM_SIZE_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_INFO_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_PDMA_PREFETCH_SRAM_SIZE_MASK \ +0x70000000 /* PDMA_PREFETCH_SRAM_SIZE[30..28] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_PDMA_PREFETCH_SRAM_SIZE_SHFT 28 +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_INDEX_WIDTH_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_INFO_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_INDEX_WIDTH_MASK \ +0x0F000000 /* INDEX_WIDTH[27..24] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_INDEX_WIDTH_SHFT 24 +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_BASE_PTR_WIDTH_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_INFO_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_BASE_PTR_WIDTH_MASK \ +0x00FF0000 /* BASE_PTR_WIDTH[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_BASE_PTR_WIDTH_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_RX_RING_NUMBER_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_INFO_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_RX_RING_NUMBER_MASK \ +0x0000FF00 /* RX_RING_NUMBER[15..8] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_RX_RING_NUMBER_SHFT 8 +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_TX_RING_NUMBER_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_INFO_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_TX_RING_NUMBER_MASK \ +0x000000FF /* TX_RING_NUMBER[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_TX_RING_NUMBER_SHFT 0 + +/* +* ---WPDMA_INFO_EXT (0x18024000 + 0x288)--- +* TX_EVENT_RING_NUMBER[7..0] - (RO) When TX_EVENT_RING_NUMBER equal 8'h0, it +* means that this DMA doesn't support dual TX fifo, thus in default it only +* support TX_RING_NUMBER of TX rings !! +* But when TX_EVENT_RING_NUMBER NOT equal +* 8'h0, this dma is configured as dual TX fifo and +* TX_RING[16+TX_EVENT_RING_NUM-1:16] are for getting HOST EVENT packet from HOST +* to WX_CPU!! +* TX_DMAD_RING_NUMBER[15..8] - (RO) When TX_EVENT_RING_NUMBER not equal to +* 8'h0, it means that this DMA support dual TX fifo and TX +* ring[TX_DMAD_RING_NUMBER-1:0] are for getting TXD from HOST to UMAC!! +* RESERVED[30..16] - (RO) Reserved +* TX_DMASHDL_EXIST[31] - (RO) TX_DMASHDL_EXIST +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_EXT_TX_DMASHDL_EXIST_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_INFO_EXT_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_EXT_TX_DMASHDL_EXIST_MASK \ +0x80000000 /* TX_DMASHDL_EXIST[31] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_EXT_TX_DMASHDL_EXIST_SHFT 31 +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_EXT_TX_DMAD_RING_NUMBER_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_INFO_EXT_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_EXT_TX_DMAD_RING_NUMBER_MASK \ +0x0000FF00 /* TX_DMAD_RING_NUMBER[15..8] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_EXT_TX_DMAD_RING_NUMBER_SHFT 8 +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_EXT_TX_EVENT_RING_NUMBER_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_INFO_EXT_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_EXT_TX_EVENT_RING_NUMBER_MASK \ +0x000000FF /* TX_EVENT_RING_NUMBER[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_EXT_TX_EVENT_RING_NUMBER_SHFT 0 + +/* +* ---WPDMA_INT_RX_PRI_SEL (0x18024000 + 0x298)--- +* WPDMA_INT_RX_RING0_PRI_SEL[0] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_RX_RING1_PRI_SEL[1] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_RX_RING2_PRI_SEL[2] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_RX_RING3_PRI_SEL[3] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_RX_RING4_PRI_SEL[4] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_RX_RING5_PRI_SEL[5] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* RESERVED6[31..6] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING5_PRI_SEL_ADDR \ + \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING5_PRI_SEL_MASK \ + \ +0x00000020 /* WPDMA_INT_RX_RING5_PRI_SEL[5] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING5_PRI_SEL_SHFT \ + \ +5 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING4_PRI_SEL_ADDR \ + \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING4_PRI_SEL_MASK \ + \ +0x00000010 /* WPDMA_INT_RX_RING4_PRI_SEL[4] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING4_PRI_SEL_SHFT \ + \ +4 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING3_PRI_SEL_ADDR \ + \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING3_PRI_SEL_MASK \ + \ +0x00000008 /* WPDMA_INT_RX_RING3_PRI_SEL[3] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING3_PRI_SEL_SHFT \ + \ +3 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING2_PRI_SEL_ADDR \ + \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING2_PRI_SEL_MASK \ + \ +0x00000004 /* WPDMA_INT_RX_RING2_PRI_SEL[2] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING2_PRI_SEL_SHFT \ + \ +2 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING1_PRI_SEL_ADDR \ + \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING1_PRI_SEL_MASK \ + \ +0x00000002 /* WPDMA_INT_RX_RING1_PRI_SEL[1] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING1_PRI_SEL_SHFT \ + \ +1 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING0_PRI_SEL_ADDR \ + \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING0_PRI_SEL_MASK \ + \ +0x00000001 /* WPDMA_INT_RX_RING0_PRI_SEL[0] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING0_PRI_SEL_SHFT \ + \ +0 + +/* +* ---WPDMA_INT_TX_PRI_SEL (0x18024000 + 0x29C)--- +* WPDMA_INT_TX_RING0_PRI_SEL[0] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING1_PRI_SEL[1] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING2_PRI_SEL[2] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING3_PRI_SEL[3] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING4_PRI_SEL[4] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING5_PRI_SEL[5] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING6_PRI_SEL[6] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING7_PRI_SEL[7] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING8_PRI_SEL[8] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING9_PRI_SEL[9] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING10_PRI_SEL[10] - (RW) write 1 to enable corresponding ring +* to be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING11_PRI_SEL[11] - (RW) write 1 to enable corresponding ring +* to be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING12_PRI_SEL[12] - (RW) write 1 to enable corresponding ring +* to be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING13_PRI_SEL[13] - (RW) write 1 to enable corresponding ring +* to be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING14_PRI_SEL[14] - (RW) write 1 to enable corresponding ring +* to be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* RESERVED15[15] - (RO) Reserved bits +* WPDMA_INT_TX_RING16_PRI_SEL[16] - (RW) write 1 to enable corresponding ring +* to be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING17_PRI_SEL[17] - (RW) write 1 to enable corresponding ring +* to be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING18_PRI_SEL[18] - (RW) write 1 to enable corresponding ring +* to be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* RESERVED[19] - (RO) Reserved +* RESERVED[20] - (RO) Reserved +* RESERVED21[31..21] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING18_PRI_SEL_ADDR \ + \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING18_PRI_SEL_MASK \ + \ +0x00040000 /* WPDMA_INT_TX_RING18_PRI_SEL[18] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING18_PRI_SEL_SHFT \ + \ +18 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING17_PRI_SEL_ADDR \ + \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING17_PRI_SEL_MASK \ + \ +0x00020000 /* WPDMA_INT_TX_RING17_PRI_SEL[17] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING17_PRI_SEL_SHFT \ + \ +17 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING16_PRI_SEL_ADDR \ + \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING16_PRI_SEL_MASK \ + \ +0x00010000 /* WPDMA_INT_TX_RING16_PRI_SEL[16] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING16_PRI_SEL_SHFT \ + \ +16 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING14_PRI_SEL_ADDR \ + \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING14_PRI_SEL_MASK \ + \ +0x00004000 /* WPDMA_INT_TX_RING14_PRI_SEL[14] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING14_PRI_SEL_SHFT \ + \ +14 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING13_PRI_SEL_ADDR \ + \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING13_PRI_SEL_MASK \ + \ +0x00002000 /* WPDMA_INT_TX_RING13_PRI_SEL[13] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING13_PRI_SEL_SHFT \ + \ +13 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING12_PRI_SEL_ADDR \ + \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING12_PRI_SEL_MASK \ + \ +0x00001000 /* WPDMA_INT_TX_RING12_PRI_SEL[12] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING12_PRI_SEL_SHFT \ + \ +12 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING11_PRI_SEL_ADDR \ + \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING11_PRI_SEL_MASK \ + \ +0x00000800 /* WPDMA_INT_TX_RING11_PRI_SEL[11] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING11_PRI_SEL_SHFT \ + \ +11 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING10_PRI_SEL_ADDR \ + \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING10_PRI_SEL_MASK \ + \ +0x00000400 /* WPDMA_INT_TX_RING10_PRI_SEL[10] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING10_PRI_SEL_SHFT \ + \ +10 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING9_PRI_SEL_ADDR \ + \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING9_PRI_SEL_MASK \ + \ +0x00000200 /* WPDMA_INT_TX_RING9_PRI_SEL[9] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING9_PRI_SEL_SHFT \ + \ +9 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING8_PRI_SEL_ADDR \ + \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING8_PRI_SEL_MASK \ + \ +0x00000100 /* WPDMA_INT_TX_RING8_PRI_SEL[8] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING8_PRI_SEL_SHFT \ + \ +8 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING7_PRI_SEL_ADDR \ + \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING7_PRI_SEL_MASK \ + \ +0x00000080 /* WPDMA_INT_TX_RING7_PRI_SEL[7] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING7_PRI_SEL_SHFT \ + \ +7 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING6_PRI_SEL_ADDR \ + \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING6_PRI_SEL_MASK \ + \ +0x00000040 /* WPDMA_INT_TX_RING6_PRI_SEL[6] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING6_PRI_SEL_SHFT \ + \ +6 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING5_PRI_SEL_ADDR \ + \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING5_PRI_SEL_MASK \ + \ +0x00000020 /* WPDMA_INT_TX_RING5_PRI_SEL[5] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING5_PRI_SEL_SHFT \ + \ +5 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING4_PRI_SEL_ADDR \ + \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING4_PRI_SEL_MASK \ + \ +0x00000010 /* WPDMA_INT_TX_RING4_PRI_SEL[4] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING4_PRI_SEL_SHFT \ + \ +4 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING3_PRI_SEL_ADDR \ + \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING3_PRI_SEL_MASK \ + \ +0x00000008 /* WPDMA_INT_TX_RING3_PRI_SEL[3] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING3_PRI_SEL_SHFT \ + \ +3 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING2_PRI_SEL_ADDR \ + \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING2_PRI_SEL_MASK \ + \ +0x00000004 /* WPDMA_INT_TX_RING2_PRI_SEL[2] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING2_PRI_SEL_SHFT \ + \ +2 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING1_PRI_SEL_ADDR \ + \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING1_PRI_SEL_MASK \ + \ +0x00000002 /* WPDMA_INT_TX_RING1_PRI_SEL[1] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING1_PRI_SEL_SHFT \ + \ +1 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING0_PRI_SEL_ADDR \ + \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING0_PRI_SEL_MASK \ + \ +0x00000001 /* WPDMA_INT_TX_RING0_PRI_SEL[0] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING0_PRI_SEL_SHFT \ + \ +0 + +/* +* ---WPDMA_TX_DBG0 (0x18024000 + 0x2A0)--- +* WPDMA_TX_DBG0[31..0] - (RO) xxx +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_DBG0_WPDMA_TX_DBG0_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_DBG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_DBG0_WPDMA_TX_DBG0_MASK \ +0xFFFFFFFF /* WPDMA_TX_DBG0[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_DBG0_WPDMA_TX_DBG0_SHFT 0 + +/* +* ---WPDMA_TX_DBG1 (0x18024000 + 0x2A4)--- +* WPDMA_TX_DBG1[31..0] - (RO) xxx +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_DBG1_WPDMA_TX_DBG1_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_DBG1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_DBG1_WPDMA_TX_DBG1_MASK \ +0xFFFFFFFF /* WPDMA_TX_DBG1[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_DBG1_WPDMA_TX_DBG1_SHFT 0 + +/* +* ---WPDMA_RX_DBG0 (0x18024000 + 0x2A8)--- +* WPDMA_RX_DBG0[31..0] - (RO) xxx +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_DBG0_WPDMA_RX_DBG0_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_DBG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_DBG0_WPDMA_RX_DBG0_MASK \ +0xFFFFFFFF /* WPDMA_RX_DBG0[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_DBG0_WPDMA_RX_DBG0_SHFT 0 + +/* +* ---WPDMA_RX_DBG1 (0x18024000 + 0x2AC)--- +* WPDMA_RX_DBG1[31..0] - (RO) xxx +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_DBG1_WPDMA_RX_DBG1_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_DBG1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_DBG1_WPDMA_RX_DBG1_MASK \ +0xFFFFFFFF /* WPDMA_RX_DBG1[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_DBG1_WPDMA_RX_DBG1_SHFT 0 + +/* +* ---WPDMA_GLO_CFG_EXT0 (0x18024000 + 0x2B0)--- +* CSR_MAX_PREFETCH_CNT[1..0] - (RW) Max. dmad count per prefet request, +* 2'b00 : 1 entry, 2'b01 : 2 entries, 2'b10 : 4 entries, 2'b11 : 8 entries, Note +* : 1 entry(dmad size) is 16 bytes = 4 DWs = 2 QWs +* CSR_MEM_BST_SIZE[3..2] - (RW) Max. burst size per sram request. 00 : +* 16-byte, 01 : 32-byte, 10 : 64-byte, 11 : 128-byte +* CSR_MEM_ARB_LOCK_EN[4] - (RW) 1'b1 : Lock round-robin sram access +* arbiter until whole long burst request from dma FSM finish, 1'b0 : no lock +* sram +* arbiter, grant will be change per request due to round-robin +* CSR_RX_DMA_WBQ_EN[5] - (RW) 1'b1 : RX dmad will be posted-write and +* deal with next received packet immediately, 1'b0 : RX dmad will be written +* back +* immediately after received packet has been sent to host memory +* CSR_TX_DMASHDL_ENABLE[6] - (RW) 1'b1 : request DMASHDL before TX to +* select next TX ring, 1'b0 : disable DMASHDL and use round-robin arbiter to +* select next TX ring +* CSR_BRESP_ERROR_BYPASS_EN[7] - (RW) 1'b1 : Bypass AXI error bresp as a +* normal response. 1'b0 : Will not assert bready to error bresp(00 : OKAY, 01 : +* EXOKAY, 10 : SLVERR, 11 : DECERR) +* CSR_AXI_SLEEP_MODE[9..8] - (RW) 2'b00 : no sleep, normal TX/RX, 2b1* : +* sleep after AXI request, 2'b11 : force assertion of wvalid, rready and bready +* to finish all committed data phases, then sleep immediately +* RESERVED10[14..10] - (RO) Reserved bits +* CSR_Q_STATUS_IDX_BKRS_EN[15] - (RW) backup/restore enable bit for +* q_status(payload, prefetch and dispatch) index +* CSR_AXI_BST_SIZE[17..16] - (RW) AXI busrt length, 00 : 128-byte, 01 : +* 64-byte, 10 : 32-byte, 11 : 16-byte +* RESERVED18[18] - (RO) Reserved bits +* CSR_AXI_FAKE[19] - (RW) If set to 1'b1, all requests from DMA +* engine will not be sent to AXI INFRA, this try to fix AXI bus hang issue +* temporarily! +* CSR_DMAD_PREFETCH_THRESHOLD[21..20] - (RW) trigger dmad prefetch when +* available dmad cnt >= {1(2'b00), 2(2'b01), 4(2'b10), 8(2'b11)} +* CSR_BID_CHECK_BYPASS_EN[22] - (RW) If set to 1'b0, axi master will check +* matching between awid and bid before assert bready, if set to 1'b1, it will +* bypass this checking and assert bready for each bvalid even though bid doesn't +* match any awid ever issued! +* CSR_RX_INFO_WB_EN[23] - (RW) If set to 1'b0, only DW0 and DW1 will be +* written back into memory after received RX packet process finished, this will +* save bus bandwidth a little because DW2 and DW3 are useless for FW +* CSR_AXI_OUTSTANDING_NUM[27..24] - (RW) decide max. outstanding AXI requests, +* common for AXI read or write! +* CSR_AXI_ARUSER_LOCK_EN[28] - (RW) on/off customized lock ctrl design thru +* AXI aruser signal, this will influence TX QoS ctrl +* CSR_AXI_AWUSER_LOCK_EN[29] - (RW) on/off customized lock ctrl design thru +* AXI awuser signal when RX dmad write-back have to be separately written into +* memory due to external dispatcher exists! +* CSR_AXI_LOCK_EN[30] - (RW) Global lock enable to on/off AXI spec. +* lock(axlock) behavior and also will on/off customized lock ctrl design thru +* AXI awuser signal +* CSR_AXI_CLKGATE_BYP[31] - (RW) To bypass functional CG enable which +* incduced from coding style for DC inserted CG cell in all AXI read/write +* master +* design module +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_CLKGATE_BYP_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_CLKGATE_BYP_MASK \ +0x80000000 /* CSR_AXI_CLKGATE_BYP[31] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_CLKGATE_BYP_SHFT 31 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_LOCK_EN_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_LOCK_EN_MASK \ +0x40000000 /* CSR_AXI_LOCK_EN[30] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_LOCK_EN_SHFT 30 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_AWUSER_LOCK_EN_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_AWUSER_LOCK_EN_MASK \ +0x20000000 /* CSR_AXI_AWUSER_LOCK_EN[29] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_AWUSER_LOCK_EN_SHFT 29 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_ARUSER_LOCK_EN_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_ARUSER_LOCK_EN_MASK \ +0x10000000 /* CSR_AXI_ARUSER_LOCK_EN[28] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_ARUSER_LOCK_EN_SHFT 28 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_OUTSTANDING_NUM_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_OUTSTANDING_NUM_MASK \ +0x0F000000 /* CSR_AXI_OUTSTANDING_NUM[27..24] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_OUTSTANDING_NUM_SHFT 24 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_RX_INFO_WB_EN_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_RX_INFO_WB_EN_MASK \ +0x00800000 /* CSR_RX_INFO_WB_EN[23] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_RX_INFO_WB_EN_SHFT 23 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_BID_CHECK_BYPASS_EN_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_BID_CHECK_BYPASS_EN_MASK \ +0x00400000 /* CSR_BID_CHECK_BYPASS_EN[22] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_BID_CHECK_BYPASS_EN_SHFT 22 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_DMAD_PREFETCH_THRESHOLD_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_DMAD_PREFETCH_THRESHOLD_MASK \ +0x00300000 /* CSR_DMAD_PREFETCH_THRESHOLD[21..20] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_DMAD_PREFETCH_THRESHOLD_SHFT \ +20 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_FAKE_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_FAKE_MASK \ +0x00080000 /* CSR_AXI_FAKE[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_FAKE_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_BST_SIZE_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_BST_SIZE_MASK \ +0x00030000 /* CSR_AXI_BST_SIZE[17..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_BST_SIZE_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_Q_STATUS_IDX_BKRS_EN_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_Q_STATUS_IDX_BKRS_EN_MASK \ +0x00008000 /* CSR_Q_STATUS_IDX_BKRS_EN[15] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_Q_STATUS_IDX_BKRS_EN_SHFT 15 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_SLEEP_MODE_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_SLEEP_MODE_MASK \ +0x00000300 /* CSR_AXI_SLEEP_MODE[9..8] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_SLEEP_MODE_SHFT 8 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_BRESP_ERROR_BYPASS_EN_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_BRESP_ERROR_BYPASS_EN_MASK \ +0x00000080 /* CSR_BRESP_ERROR_BYPASS_EN[7] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_BRESP_ERROR_BYPASS_EN_SHFT 7 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_TX_DMASHDL_ENABLE_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_TX_DMASHDL_ENABLE_MASK \ +0x00000040 /* CSR_TX_DMASHDL_ENABLE[6] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_TX_DMASHDL_ENABLE_SHFT 6 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_RX_DMA_WBQ_EN_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_RX_DMA_WBQ_EN_MASK \ +0x00000020 /* CSR_RX_DMA_WBQ_EN[5] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_RX_DMA_WBQ_EN_SHFT 5 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_MEM_ARB_LOCK_EN_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_MEM_ARB_LOCK_EN_MASK \ +0x00000010 /* CSR_MEM_ARB_LOCK_EN[4] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_MEM_ARB_LOCK_EN_SHFT 4 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_MEM_BST_SIZE_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_MEM_BST_SIZE_MASK \ +0x0000000C /* CSR_MEM_BST_SIZE[3..2] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_MEM_BST_SIZE_SHFT 2 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_MAX_PREFETCH_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_MAX_PREFETCH_CNT_MASK \ +0x00000003 /* CSR_MAX_PREFETCH_CNT[1..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_MAX_PREFETCH_CNT_SHFT 0 + +/* +* ---WPDMA_GLO_CFG_EXT1 (0x18024000 + 0x2B4)--- +* CSR_TXFIFO0_RDY_THRESHOLD[7..0] - (RW) xxx +* CSR_TXFIFO1_RDY_THRESHOLD[15..8] - (RW) xxx +* CSR_TX_DISP_ARB_SCHEDULED_ACCESS_TIMER[23..16] - (RW) timer setting for +* SCHEDULED_ACCESS_TIME_ARB of csr_tx_disp_arb_mode +* CSR_TX_DISP_ARB_MODE[25..24] - (RW) 00 : FAIR_ARB, 01 : FIX_ARB, 10 : +* UNBALANCED_ARB, 11 : SCHEDULED_ACCESS_TIME_ARB +* CSR_FWDL_FLOW_CTRL_BYASS_EN[26] - (RW) To disable firmware download TX flow +* control of TX dma(host_dma1) when firmare download of RX dma(mcu_dma1) is in +* firmware download polling mode!! Remember to set to 1'b0 when firmware +download +* ring is set back to normal ring usage which should be in flow control for +* correct behavior!! +* CSR_FWDL_FLOW_CTRL_BYASS_LS_QSEL_EN[27] - (RW) select firmware download TX +* ring(LSB/MSB ring) to bypass TX flow control when firmare download RX +* ring(LSB/MSB ring) of RX dma(mcu_dma1) is in firmware download polling mode!! +* RESERVED28[30..28] - (RO) Reserved bits +* CSR_PF_WRAP_CALC_MODE[31] - (RW) 1'b0 : prefetch SRAM wrapping boundary +* is decided by bext ring base address 1'b1 : prefetch SRAM wrapping boundary +* is decided by prefetch max_cnt +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_PF_WRAP_CALC_MODE_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_PF_WRAP_CALC_MODE_MASK \ +0x80000000 /* CSR_PF_WRAP_CALC_MODE[31] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_PF_WRAP_CALC_MODE_SHFT 31 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_FWDL_FLOW_CTRL_BYASS_LS_QSEL_EN_ADDR \ + \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_FWDL_FLOW_CTRL_BYASS_LS_QSEL_EN_MASK \ + \ +0x08000000 /* CSR_FWDL_FLOW_CTRL_BYASS_LS_QSEL_EN[27] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_FWDL_FLOW_CTRL_BYASS_LS_QSEL_EN_SHFT \ + \ +27 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_FWDL_FLOW_CTRL_BYASS_EN_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_FWDL_FLOW_CTRL_BYASS_EN_MASK \ +0x04000000 /* CSR_FWDL_FLOW_CTRL_BYASS_EN[26] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_FWDL_FLOW_CTRL_BYASS_EN_SHFT \ +26 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_TX_DISP_ARB_MODE_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_TX_DISP_ARB_MODE_MASK \ +0x03000000 /* CSR_TX_DISP_ARB_MODE[25..24] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_TX_DISP_ARB_MODE_SHFT 24 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_TX_DISP_ARB_SCHEDULED_ACCESS_TIMER_AD\ +DR \ +\ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_TX_DISP_ARB_SCHEDULED_ACCESS_TIMER_MA\ +SK \ +\ +0x00FF0000 /* CSR_TX_DISP_ARB_SCHEDULED_ACCESS_TIMER[23..16] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_TX_DISP_ARB_SCHEDULED_ACCESS_TIMER_SH\ +FT \ +\ +16 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_TXFIFO1_RDY_THRESHOLD_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_TXFIFO1_RDY_THRESHOLD_MASK \ +0x0000FF00 /* CSR_TXFIFO1_RDY_THRESHOLD[15..8] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_TXFIFO1_RDY_THRESHOLD_SHFT 8 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_TXFIFO0_RDY_THRESHOLD_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_TXFIFO0_RDY_THRESHOLD_MASK \ +0x000000FF /* CSR_TXFIFO0_RDY_THRESHOLD[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_TXFIFO0_RDY_THRESHOLD_SHFT 0 + +/* +* ---WPDMA_GLO_CFG_EXT2 (0x18024000 + 0x2B8)--- +* RESERVED0[15..0] - (RO) Reserved bits +* CSR_TX_DROP_MODE[17..16] - (RW) 2'h0 : No TX drop , 2'h1 : Ignore DMAD +* fetch and UDMA APB , 2'h2 : Flush TX dispatch queue +* RESERVED18[31..18] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT2_CSR_TX_DROP_MODE_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT2_CSR_TX_DROP_MODE_MASK \ +0x00030000 /* CSR_TX_DROP_MODE[17..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT2_CSR_TX_DROP_MODE_SHFT 16 + +/* +* ---WPDMA_TX_QOS_QTM_CFG0 (0x18024000 + 0x2D0)--- +* CSR_TXP0_FFA_QTM[3..0] - (RW) CSR_TXP0_FFA_QTM +* CSR_TXP0_RSVD_QTM[7..4] - (RW) CSR_TXP0_RSVD_QTM +* CSR_TXP1_FFA_QTM[11..8] - (RW) CSR_TXP1_FFA_QTM +* CSR_TXP1_RSVD_QTM[15..12] - (RW) CSR_TXP1_RSVD_QTM +* RESERVED16[23..16] - (RO) Reserved bits +* CSR_FFA_TOTAL_QTM[27..24] - (RW) CSR_FFA_TOTAL_QTM +* CSR_QOS_QTM_MODE[29..28] - (RW) 2'b01 : csr_rsvd_qtm_mode_only, 2'b10 : +* csr_ffa_qtm_mode_only, others : rsvd+ffa mode +* RESERVED30[31..30] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_QOS_QTM_MODE_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_QOS_QTM_MODE_MASK \ +0x30000000 /* CSR_QOS_QTM_MODE[29..28] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_QOS_QTM_MODE_SHFT 28 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_FFA_TOTAL_QTM_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_FFA_TOTAL_QTM_MASK \ +0x0F000000 /* CSR_FFA_TOTAL_QTM[27..24] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_FFA_TOTAL_QTM_SHFT 24 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_TXP1_RSVD_QTM_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_TXP1_RSVD_QTM_MASK \ +0x0000F000 /* CSR_TXP1_RSVD_QTM[15..12] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_TXP1_RSVD_QTM_SHFT 12 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_TXP1_FFA_QTM_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_TXP1_FFA_QTM_MASK \ +0x00000F00 /* CSR_TXP1_FFA_QTM[11..8] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_TXP1_FFA_QTM_SHFT 8 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_TXP0_RSVD_QTM_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_TXP0_RSVD_QTM_MASK \ +0x000000F0 /* CSR_TXP0_RSVD_QTM[7..4] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_TXP0_RSVD_QTM_SHFT 4 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_TXP0_FFA_QTM_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_TXP0_FFA_QTM_MASK \ +0x0000000F /* CSR_TXP0_FFA_QTM[3..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_TXP0_FFA_QTM_SHFT 0 + +/* +* ---WPDMA_TX_QOS_QTM_CFG1 (0x18024000 + 0x2D4)--- +* CSR_DMAD_FFA_QTM[3..0] - (RW) CSR_DMAD_FFA_QTM +* CSR_DMAD_RSVD_QTM[7..4] - (RW) CSR_DMAD_RSVD_QTM +* CSR_TXD_FFA_QTM[11..8] - (RW) CSR_TXD_FFA_QTM +* CSR_TXD_RSVD_QTM[15..12] - (RW) CSR_TXD_RSVD_QTM +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_CSR_TXD_RSVD_QTM_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_CSR_TXD_RSVD_QTM_MASK \ +0x0000F000 /* CSR_TXD_RSVD_QTM[15..12] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_CSR_TXD_RSVD_QTM_SHFT 12 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_CSR_TXD_FFA_QTM_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_CSR_TXD_FFA_QTM_MASK \ +0x00000F00 /* CSR_TXD_FFA_QTM[11..8] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_CSR_TXD_FFA_QTM_SHFT 8 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_CSR_DMAD_RSVD_QTM_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_CSR_DMAD_RSVD_QTM_MASK \ +0x000000F0 /* CSR_DMAD_RSVD_QTM[7..4] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_CSR_DMAD_RSVD_QTM_SHFT 4 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_CSR_DMAD_FFA_QTM_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_CSR_DMAD_FFA_QTM_MASK \ +0x0000000F /* CSR_DMAD_FFA_QTM[3..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_CSR_DMAD_FFA_QTM_SHFT 0 + +/* +* ---HOST_PRI_INT_STA (0x18024000 + 0x2E0)--- +* host_pri_int_sts_0[0] - (W1C) tx_done_int[18], W1C to clear delay +interrupt +* host_pri_int_sts_1[1] - (W1C) tx_done_int[19], W1C to clear delay +interrupt +* host_pri_int_sts_2[2] - (W1C) rx_done_int[0], W1C to clear delay +interrupt +* host_pri_int_sts_3[3] - (W1C) rx_done_int[1], W1C to clear delay +interrupt +* host_pri_int_sts_4[4] - (W1C) rx_done_int[2], W1C to clear delay +interrupt +* RESERVED5[31..5] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_HOST_PRI_INT_STA_host_pri_int_sts_4_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_PRI_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_PRI_INT_STA_host_pri_int_sts_4_MASK \ +0x00000010 /* host_pri_int_sts_4[4] */ +#define WF_WFDMA_HOST_DMA0_HOST_PRI_INT_STA_host_pri_int_sts_4_SHFT 4 +#define WF_WFDMA_HOST_DMA0_HOST_PRI_INT_STA_host_pri_int_sts_3_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_PRI_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_PRI_INT_STA_host_pri_int_sts_3_MASK \ +0x00000008 /* host_pri_int_sts_3[3] */ +#define WF_WFDMA_HOST_DMA0_HOST_PRI_INT_STA_host_pri_int_sts_3_SHFT 3 +#define WF_WFDMA_HOST_DMA0_HOST_PRI_INT_STA_host_pri_int_sts_2_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_PRI_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_PRI_INT_STA_host_pri_int_sts_2_MASK \ +0x00000004 /* host_pri_int_sts_2[2] */ +#define WF_WFDMA_HOST_DMA0_HOST_PRI_INT_STA_host_pri_int_sts_2_SHFT 2 +#define WF_WFDMA_HOST_DMA0_HOST_PRI_INT_STA_host_pri_int_sts_1_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_PRI_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_PRI_INT_STA_host_pri_int_sts_1_MASK \ +0x00000002 /* host_pri_int_sts_1[1] */ +#define WF_WFDMA_HOST_DMA0_HOST_PRI_INT_STA_host_pri_int_sts_1_SHFT 1 +#define WF_WFDMA_HOST_DMA0_HOST_PRI_INT_STA_host_pri_int_sts_0_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_PRI_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_PRI_INT_STA_host_pri_int_sts_0_MASK \ +0x00000001 /* host_pri_int_sts_0[0] */ +#define WF_WFDMA_HOST_DMA0_HOST_PRI_INT_STA_host_pri_int_sts_0_SHFT 0 + +/* +* ---HOST_PER_INT_ENA_STA (0x18024000 + 0x2E4)--- +* wpdma_per_int_sts[3..0] - (W1C) status bit for rx ring periodic delayed +* interrupt to tracking ring is full or not, start delayed interrupt timer when +* RX ring is not full from falling edge of full flag and reset when ring full +* flag is asserted +* RESERVED4[15..4] - (RO) Reserved bits +* wpdma_per_int_ena[19..16] - (RW) enable bit for rx ring periodic delayed +* interrupt to tracking ring is full or not, start delayed interrupt timer when +* RX ring is not full from falling edge of full flag and reset when ring full +* flag is asserted +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_HOST_PER_INT_ENA_STA_wpdma_per_int_ena_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_PER_INT_ENA_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_PER_INT_ENA_STA_wpdma_per_int_ena_MASK \ +0x000F0000 /* wpdma_per_int_ena[19..16] */ +#define WF_WFDMA_HOST_DMA0_HOST_PER_INT_ENA_STA_wpdma_per_int_ena_SHFT 16 +#define WF_WFDMA_HOST_DMA0_HOST_PER_INT_ENA_STA_wpdma_per_int_sts_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_PER_INT_ENA_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_PER_INT_ENA_STA_wpdma_per_int_sts_MASK \ +0x0000000F /* wpdma_per_int_sts[3..0] */ +#define WF_WFDMA_HOST_DMA0_HOST_PER_INT_ENA_STA_wpdma_per_int_sts_SHFT 0 + +/* +* ---HOST_PER_DLY_INT_CFG (0x18024000 + 0x2E8)--- +* wpdma_per_max_ptime[7..0] - (RW) Specified Max pending time for the +* internal RX ring full flag falling edge. When the pending time equal or +greater +* PER_MAX_PTIME x 20us or the # of pended TX_DONE_INT equal or greater than +* TX_MAX_PINT (see above), an Final TX_DLY_INT is generated +* Set to 0 will disable pending interrupt +* time check +* wpdma_per_dly_int_en[11..8] - (RW) RX periodic Delayed Interrupt Enable +* 1: Enable RX periodic delayed interrupt +mechanism +* 0: Disable RX periodic delayed interrupt +mechanism +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_HOST_PER_DLY_INT_CFG_wpdma_per_dly_int_en_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_PER_DLY_INT_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_PER_DLY_INT_CFG_wpdma_per_dly_int_en_MASK \ +0x00000F00 /* wpdma_per_dly_int_en[11..8] */ +#define WF_WFDMA_HOST_DMA0_HOST_PER_DLY_INT_CFG_wpdma_per_dly_int_en_SHFT 8 +#define WF_WFDMA_HOST_DMA0_HOST_PER_DLY_INT_CFG_wpdma_per_max_ptime_ADDR \ +WF_WFDMA_HOST_DMA0_HOST_PER_DLY_INT_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_PER_DLY_INT_CFG_wpdma_per_max_ptime_MASK \ +0x000000FF /* wpdma_per_max_ptime[7..0] */ +#define WF_WFDMA_HOST_DMA0_HOST_PER_DLY_INT_CFG_wpdma_per_max_ptime_SHFT 0 + +/* +* ---WPDMA_PRI_DLY_INT_CFG0 (0x18024000 + 0x2F0)--- +* PRI0_MAX_PTIME[7..0] - (RW) Specified Max pending time for the +* internal PRI0_DONE_INT. When the pending time equal or greater PRI0_MAX_PTIME +x +* 20us or the # of pended PRI0_DONE_INT equal or greater than PRI0_MAX_PINT (see +* above), an Final PRI0_DLY_INT is generated +* Set to 0 will disable pending interrupt +* time check +* PRI0_MAX_PINT[14..8] - (RW) Specified Max # of pended interrupts. +* When the # of pended interrupts equal or +* greater than the value specified here or interrupt pending time reach the +limit +* (See below), a Final PRI0_DLY_INT is generated. +* Set to 0 will disable pending interrupt +* count check +* PRI0_DLY_INT_EN[15] - (RW) Priority Delayed Interrupt Enable +* 1: Enable Priority delayed interrupt +mechanism +* 0: Disable Priority delayed interrupt +mechanism +* In AXE host_dma0, these PRI1_* settings are +* for rx_ring[1]_int, and PRI0_* settings are for rx_ring[0]_int +* In AXE host_dma1, these PRI1_* settings are +* for rx_ring[0]_int, and PRI0_* settings are for Ored-tx_ring[14:0]_int +* In AXE mcu_dma0 and mcu_dma1, there are no +* priority interrupt thus no this 0x2E0 CR!! +* PRI1_MAX_PTIME[23..16] - (RW) Specified Max pending time for the +* internal PRI1_DONE_INT. When the pending time equal or greater PRI1_MAX_PTIME +x +* 20us or the # of pended PRI1_DONE_INT equal or greater than PRI1_MAX_PINT (see +* above), an Final PRI1_DLY_INT is generated +* Set to 0 will disable pending interrupt +* time check +* PRI1_MAX_PINT[30..24] - (RW) Specified Max # of pended interrupts. +* When the # of pended interrupts equal or +* greater than the value specified here or interrupt pending time reach the +limit +* (See below), a Final PRI1_DLY_INT is generated. +* Set to 0 will disable pending interrupt +* count check +* PRI1_DLY_INT_EN[31] - (RW) Priority Delayed Interrupt Enable +* 1: Enable Priority delayed interrupt +mechanism +* 0: Disable Priority delayed interrupt +mechanism +* In AXE host_dma0, these PRI1_* settings are +* for rx_ring[1]_int, and PRI0_* settings are for rx_ring[0]_int +* In AXE host_dma1, these PRI1_* settings are +* for rx_ring[0]_int, and PRI0_* settings are for Ored-tx_ring[14:0]_int +* In AXE mcu_dma0 and mcu_dma1, there are no +* priority interrupt thus no this 0x2E0 CR!! +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI1_DLY_INT_EN_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI1_DLY_INT_EN_MASK \ +0x80000000 /* PRI1_DLY_INT_EN[31] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI1_DLY_INT_EN_SHFT 31 +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI1_MAX_PINT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI1_MAX_PINT_MASK \ +0x7F000000 /* PRI1_MAX_PINT[30..24] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI1_MAX_PINT_SHFT 24 +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI1_MAX_PTIME_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI1_MAX_PTIME_MASK \ +0x00FF0000 /* PRI1_MAX_PTIME[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI1_MAX_PTIME_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI0_DLY_INT_EN_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI0_DLY_INT_EN_MASK \ +0x00008000 /* PRI0_DLY_INT_EN[15] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI0_DLY_INT_EN_SHFT 15 +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI0_MAX_PINT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI0_MAX_PINT_MASK \ +0x00007F00 /* PRI0_MAX_PINT[14..8] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI0_MAX_PINT_SHFT 8 +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI0_MAX_PTIME_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI0_MAX_PTIME_MASK \ +0x000000FF /* PRI0_MAX_PTIME[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI0_MAX_PTIME_SHFT 0 + +/* +* ---WPDMA_TX_RING0_CTRL0 (0x18024000 + 0x300)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring0 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL0_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL0_BASE_PTR_MASK \ +0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING0_CTRL1 (0x18024000 + 0x304)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_Ring0. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring0 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL1_BASE_PTR_EXT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL1_BASE_PTR_EXT_MASK \ +0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL1_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL1_MAX_CNT_MASK \ +0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING0_CTRL2 (0x18024000 + 0x308)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL2_CPU_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL2_CPU_IDX_MASK \ +0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING0_CTRL3 (0x18024000 + 0x30c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL3_DMA_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL3_DMA_IDX_MASK \ +0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING1_CTRL0 (0x18024000 + 0x310)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring1 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL0_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL0_BASE_PTR_MASK \ +0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING1_CTRL1 (0x18024000 + 0x314)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_Ring1. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring1 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL1_BASE_PTR_EXT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL1_BASE_PTR_EXT_MASK \ +0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL1_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL1_MAX_CNT_MASK \ +0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING1_CTRL2 (0x18024000 + 0x318)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL2_CPU_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL2_CPU_IDX_MASK \ +0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING1_CTRL3 (0x18024000 + 0x31c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL3_DMA_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL3_DMA_IDX_MASK \ +0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING2_CTRL0 (0x18024000 + 0x320)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring2 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL0_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL0_BASE_PTR_MASK \ +0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING2_CTRL1 (0x18024000 + 0x324)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_Ring2. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring2 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL1_BASE_PTR_EXT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL1_BASE_PTR_EXT_MASK \ +0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL1_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL1_MAX_CNT_MASK \ +0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING2_CTRL2 (0x18024000 + 0x328)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL2_CPU_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL2_CPU_IDX_MASK \ +0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING2_CTRL3 (0x18024000 + 0x32c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL3_DMA_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL3_DMA_IDX_MASK \ +0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING3_CTRL0 (0x18024000 + 0x330)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring3 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL0_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL0_BASE_PTR_MASK \ +0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING3_CTRL1 (0x18024000 + 0x334)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_Ring3. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring3 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL1_BASE_PTR_EXT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL1_BASE_PTR_EXT_MASK \ +0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL1_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL1_MAX_CNT_MASK \ +0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING3_CTRL2 (0x18024000 + 0x338)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL2_CPU_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL2_CPU_IDX_MASK \ +0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING3_CTRL3 (0x18024000 + 0x33c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL3_DMA_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL3_DMA_IDX_MASK \ +0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING4_CTRL0 (0x18024000 + 0x340)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring4 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_CTRL0_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_CTRL0_BASE_PTR_MASK \ +0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING4_CTRL1 (0x18024000 + 0x344)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_Ring4. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring4 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_CTRL1_BASE_PTR_EXT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_CTRL1_BASE_PTR_EXT_MASK \ +0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_CTRL1_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_CTRL1_MAX_CNT_MASK \ +0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING4_CTRL2 (0x18024000 + 0x348)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_CTRL2_CPU_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_CTRL2_CPU_IDX_MASK \ +0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING4_CTRL3 (0x18024000 + 0x34c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_CTRL3_DMA_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_CTRL3_DMA_IDX_MASK \ +0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING5_CTRL0 (0x18024000 + 0x350)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring5 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_CTRL0_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_CTRL0_BASE_PTR_MASK \ +0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING5_CTRL1 (0x18024000 + 0x354)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_Ring5. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring5 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_CTRL1_BASE_PTR_EXT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_CTRL1_BASE_PTR_EXT_MASK \ +0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_CTRL1_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_CTRL1_MAX_CNT_MASK \ +0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING5_CTRL2 (0x18024000 + 0x358)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_CTRL2_CPU_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_CTRL2_CPU_IDX_MASK \ +0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING5_CTRL3 (0x18024000 + 0x35c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_CTRL3_DMA_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_CTRL3_DMA_IDX_MASK \ +0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING6_CTRL0 (0x18024000 + 0x360)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring6 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_CTRL0_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_CTRL0_BASE_PTR_MASK \ +0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING6_CTRL1 (0x18024000 + 0x364)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_Ring6. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring6 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_CTRL1_BASE_PTR_EXT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_CTRL1_BASE_PTR_EXT_MASK \ +0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_CTRL1_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_CTRL1_MAX_CNT_MASK \ +0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING6_CTRL2 (0x18024000 + 0x368)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_CTRL2_CPU_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_CTRL2_CPU_IDX_MASK \ +0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING6_CTRL3 (0x18024000 + 0x36c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_CTRL3_DMA_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_CTRL3_DMA_IDX_MASK \ +0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING7_CTRL0 (0x18024000 + 0x370)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring7 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_CTRL0_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_CTRL0_BASE_PTR_MASK \ +0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING7_CTRL1 (0x18024000 + 0x374)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_Ring7. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring7 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_CTRL1_BASE_PTR_EXT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_CTRL1_BASE_PTR_EXT_MASK \ +0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_CTRL1_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_CTRL1_MAX_CNT_MASK \ +0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING7_CTRL2 (0x18024000 + 0x378)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_CTRL2_CPU_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_CTRL2_CPU_IDX_MASK \ +0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING7_CTRL3 (0x18024000 + 0x37c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_CTRL3_DMA_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_CTRL3_DMA_IDX_MASK \ +0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING8_CTRL0 (0x18024000 + 0x380)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring0 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_CTRL0_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_CTRL0_BASE_PTR_MASK \ +0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING8_CTRL1 (0x18024000 + 0x384)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_Ring0. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring0 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_CTRL1_BASE_PTR_EXT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_CTRL1_BASE_PTR_EXT_MASK \ +0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_CTRL1_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_CTRL1_MAX_CNT_MASK \ +0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING8_CTRL2 (0x18024000 + 0x388)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_CTRL2_CPU_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_CTRL2_CPU_IDX_MASK \ +0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING8_CTRL3 (0x18024000 + 0x38c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_CTRL3_DMA_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_CTRL3_DMA_IDX_MASK \ +0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING9_CTRL0 (0x18024000 + 0x390)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring1 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_CTRL0_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_CTRL0_BASE_PTR_MASK \ +0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING9_CTRL1 (0x18024000 + 0x394)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_Ring1. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring1 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_CTRL1_BASE_PTR_EXT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_CTRL1_BASE_PTR_EXT_MASK \ +0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_CTRL1_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_CTRL1_MAX_CNT_MASK \ +0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING9_CTRL2 (0x18024000 + 0x398)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_CTRL2_CPU_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_CTRL2_CPU_IDX_MASK \ +0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING9_CTRL3 (0x18024000 + 0x39c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_CTRL3_DMA_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_CTRL3_DMA_IDX_MASK \ +0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING10_CTRL0 (0x18024000 + 0x3a0)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring2 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_CTRL0_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_CTRL0_BASE_PTR_MASK \ +0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING10_CTRL1 (0x18024000 + 0x3a4)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_Ring2. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring2 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_CTRL1_BASE_PTR_EXT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_CTRL1_BASE_PTR_EXT_MASK \ +0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_CTRL1_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_CTRL1_MAX_CNT_MASK \ +0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING10_CTRL2 (0x18024000 + 0x3a8)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_CTRL2_CPU_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_CTRL2_CPU_IDX_MASK \ +0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING10_CTRL3 (0x18024000 + 0x3ac)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_CTRL3_DMA_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_CTRL3_DMA_IDX_MASK \ +0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING11_CTRL0 (0x18024000 + 0x3b0)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring3 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_CTRL0_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_CTRL0_BASE_PTR_MASK \ +0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING11_CTRL1 (0x18024000 + 0x3b4)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_Ring3. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring3 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_CTRL1_BASE_PTR_EXT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_CTRL1_BASE_PTR_EXT_MASK \ +0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_CTRL1_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_CTRL1_MAX_CNT_MASK \ +0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING11_CTRL2 (0x18024000 + 0x3b8)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_CTRL2_CPU_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_CTRL2_CPU_IDX_MASK \ +0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING11_CTRL3 (0x18024000 + 0x3bc)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_CTRL3_DMA_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_CTRL3_DMA_IDX_MASK \ +0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING12_CTRL0 (0x18024000 + 0x3c0)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring4 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_CTRL0_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_CTRL0_BASE_PTR_MASK \ +0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING12_CTRL1 (0x18024000 + 0x3c4)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_Ring4. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring4 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_CTRL1_BASE_PTR_EXT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_CTRL1_BASE_PTR_EXT_MASK \ +0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_CTRL1_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_CTRL1_MAX_CNT_MASK \ +0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING12_CTRL2 (0x18024000 + 0x3c8)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_CTRL2_CPU_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_CTRL2_CPU_IDX_MASK \ +0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING12_CTRL3 (0x18024000 + 0x3cc)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_CTRL3_DMA_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_CTRL3_DMA_IDX_MASK \ +0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING13_CTRL0 (0x18024000 + 0x3d0)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring5 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_CTRL0_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_CTRL0_BASE_PTR_MASK \ +0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING13_CTRL1 (0x18024000 + 0x3d4)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_Ring5. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring5 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_CTRL1_BASE_PTR_EXT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_CTRL1_BASE_PTR_EXT_MASK \ +0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_CTRL1_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_CTRL1_MAX_CNT_MASK \ +0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING13_CTRL2 (0x18024000 + 0x3d8)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_CTRL2_CPU_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_CTRL2_CPU_IDX_MASK \ +0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING13_CTRL3 (0x18024000 + 0x3dc)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_CTRL3_DMA_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_CTRL3_DMA_IDX_MASK \ +0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING14_CTRL0 (0x18024000 + 0x3e0)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring6 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_CTRL0_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_CTRL0_BASE_PTR_MASK \ +0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING14_CTRL1 (0x18024000 + 0x3e4)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_Ring6. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring6 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_CTRL1_BASE_PTR_EXT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_CTRL1_BASE_PTR_EXT_MASK \ +0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_CTRL1_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_CTRL1_MAX_CNT_MASK \ +0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING14_CTRL2 (0x18024000 + 0x3e8)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_CTRL2_CPU_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_CTRL2_CPU_IDX_MASK \ +0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING14_CTRL3 (0x18024000 + 0x3ec)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_CTRL3_DMA_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_CTRL3_DMA_IDX_MASK \ +0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING15_CTRL0 (0x18024000 + 0x3f0)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring7 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_CTRL0_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_CTRL0_BASE_PTR_MASK \ +0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING15_CTRL1 (0x18024000 + 0x3f4)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_Ring7. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring7 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_CTRL1_BASE_PTR_EXT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_CTRL1_BASE_PTR_EXT_MASK \ +0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_CTRL1_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_CTRL1_MAX_CNT_MASK \ +0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING15_CTRL2 (0x18024000 + 0x3f8)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_CTRL2_CPU_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_CTRL2_CPU_IDX_MASK \ +0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING15_CTRL3 (0x18024000 + 0x3fc)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_CTRL3_DMA_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_CTRL3_DMA_IDX_MASK \ +0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING16_CTRL0 (0x18024000 + 0x400)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_RING16 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_CTRL0_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_CTRL0_BASE_PTR_MASK \ +0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING16_CTRL1 (0x18024000 + 0x404)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_RING16. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring16 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_CTRL1_BASE_PTR_EXT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_CTRL1_BASE_PTR_EXT_MASK \ +0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_CTRL1_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_CTRL1_MAX_CNT_MASK \ +0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING16_CTRL2 (0x18024000 + 0x408)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_CTRL2_CPU_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_CTRL2_CPU_IDX_MASK \ +0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING16_CTRL3 (0x18024000 + 0x40c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_CTRL3_DMA_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_CTRL3_DMA_IDX_MASK \ +0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING17_CTRL0 (0x18024000 + 0x410)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring17 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_CTRL0_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_CTRL0_BASE_PTR_MASK \ +0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING17_CTRL1 (0x18024000 + 0x414)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_Ring17. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring17 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_CTRL1_BASE_PTR_EXT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_CTRL1_BASE_PTR_EXT_MASK \ +0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_CTRL1_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_CTRL1_MAX_CNT_MASK \ +0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING17_CTRL2 (0x18024000 + 0x418)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_CTRL2_CPU_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_CTRL2_CPU_IDX_MASK \ +0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING17_CTRL3 (0x18024000 + 0x41c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_CTRL3_DMA_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_CTRL3_DMA_IDX_MASK \ +0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING18_CTRL0 (0x18024000 + 0x420)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring18 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_CTRL0_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_CTRL0_BASE_PTR_MASK \ +0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING18_CTRL1 (0x18024000 + 0x424)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_Ring18. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring18 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_CTRL1_BASE_PTR_EXT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_CTRL1_BASE_PTR_EXT_MASK \ +0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_CTRL1_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_CTRL1_MAX_CNT_MASK \ +0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING18_CTRL2 (0x18024000 + 0x428)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_CTRL2_CPU_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_CTRL2_CPU_IDX_MASK \ +0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING18_CTRL3 (0x18024000 + 0x42c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_CTRL3_DMA_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_CTRL3_DMA_IDX_MASK \ +0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING0_CTRL0 (0x18024000 + 0x500)--- +* BASE_PTR[31..0] - (RW) Point to the base address of RXD Ring #0 +* (GE ports). It should be a 8-DWORD aligned address +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL0_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL0_BASE_PTR_MASK \ +0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_RX_RING0_CTRL1 (0x18024000 + 0x504)--- +* MAX_CNT[11..0] - (RW) The maximum number of RXD count in RXD +* Ring #0. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* RX_Ring0 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL1_BASE_PTR_EXT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL1_BASE_PTR_EXT_MASK \ +0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL1_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL1_MAX_CNT_MASK \ +0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING0_CTRL2 (0x18024000 + 0x508)--- +* CPU_IDX[11..0] - (RW) Point to the next RXD CPU wants to +* allocate to RXD Ring #0. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL2_CPU_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL2_CPU_IDX_MASK \ +0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING0_CTRL3 (0x18024000 + 0x50c)--- +* DMA_IDX[11..0] - (RW) Point to the next RXD PDMA engine wants +* to use for RXD Ring #0. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL3_DMA_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL3_DMA_IDX_MASK \ +0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING1_CTRL0 (0x18024000 + 0x510)--- +* BASE_PTR[31..0] - (RW) Point to the base address of RXD Ring #1 +* (GE ports). It should be a 8-DWORD aligned address +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL0_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL0_BASE_PTR_MASK \ +0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_RX_RING1_CTRL1 (0x18024000 + 0x514)--- +* MAX_CNT[11..0] - (RW) The maximum number of RXD count in RXD +* Ring #1. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* RX_Ring1 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL1_BASE_PTR_EXT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL1_BASE_PTR_EXT_MASK \ +0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL1_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL1_MAX_CNT_MASK \ +0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING1_CTRL2 (0x18024000 + 0x518)--- +* CPU_IDX[11..0] - (RW) Point to the next RXD CPU wants to +* allocate to RXD Ring #1. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL2_CPU_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL2_CPU_IDX_MASK \ +0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING1_CTRL3 (0x18024000 + 0x51c)--- +* DMA_IDX[11..0] - (RW) Point to the next RXD PDMA engine wants +* to use for RXD Ring #1. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL3_DMA_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL3_DMA_IDX_MASK \ +0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING2_CTRL0 (0x18024000 + 0x520)--- +* BASE_PTR[31..0] - (RW) Point to the base address of RXD Ring #2 +* (GE ports). It should be a 8-DWORD aligned address +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL0_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL0_BASE_PTR_MASK \ +0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_RX_RING2_CTRL1 (0x18024000 + 0x524)--- +* MAX_CNT[11..0] - (RW) The maximum number of RXD count in RXD +* Ring #2. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* RX_Ring2 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL1_BASE_PTR_EXT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL1_BASE_PTR_EXT_MASK \ +0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL1_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL1_MAX_CNT_MASK \ +0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING2_CTRL2 (0x18024000 + 0x528)--- +* CPU_IDX[11..0] - (RW) Point to the next RXD CPU wants to +* allocate to RXD Ring #2. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL2_CPU_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL2_CPU_IDX_MASK \ +0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING2_CTRL3 (0x18024000 + 0x52C)--- +* DMA_IDX[11..0] - (RW) Point to the next RXD PDMA engine wants +* to use for RXD Ring #2. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL3_DMA_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL3_DMA_IDX_MASK \ +0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING3_CTRL0 (0x18024000 + 0x530)--- +* BASE_PTR[31..0] - (RW) Point to the base address of RXD Ring #3 +* (GE ports). It should be a 8-DWORD aligned address +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL0_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL0_BASE_PTR_MASK \ +0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_RX_RING3_CTRL1 (0x18024000 + 0x534)--- +* MAX_CNT[11..0] - (RW) The maximum number of RXD count in RXD +* Ring #3. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* RX_Ring3 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL1_BASE_PTR_EXT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL1_BASE_PTR_EXT_MASK \ +0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL1_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL1_MAX_CNT_MASK \ +0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING3_CTRL2 (0x18024000 + 0x538)--- +* CPU_IDX[11..0] - (RW) Point to the next RXD CPU wants to +* allocate to RXD Ring #3. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL2_CPU_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL2_CPU_IDX_MASK \ +0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING3_CTRL3 (0x18024000 + 0x53C)--- +* DMA_IDX[11..0] - (RW) Point to the next RXD PDMA engine wants +* to use for RXD Ring #3. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL3_DMA_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL3_DMA_IDX_MASK \ +0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING4_CTRL0 (0x18024000 + 0x540)--- +* BASE_PTR[31..0] - (RW) Point to the base address of RXD Ring #4 +* (GE ports). It should be a 8-DWORD aligned address +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL0_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL0_BASE_PTR_MASK \ +0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_RX_RING4_CTRL1 (0x18024000 + 0x544)--- +* MAX_CNT[11..0] - (RW) The maximum number of RXD count in RXD +* Ring #4. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* RX_Ring4 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL1_BASE_PTR_EXT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL1_BASE_PTR_EXT_MASK \ +0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL1_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL1_MAX_CNT_MASK \ +0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING4_CTRL2 (0x18024000 + 0x548)--- +* CPU_IDX[11..0] - (RW) Point to the next RXD CPU wants to +* allocate to RXD Ring #4. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL2_CPU_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL2_CPU_IDX_MASK \ +0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING4_CTRL3 (0x18024000 + 0x54c)--- +* DMA_IDX[11..0] - (RW) Point to the next RXD PDMA engine wants +* to use for RXD Ring #4. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL3_DMA_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL3_DMA_IDX_MASK \ +0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING5_CTRL0 (0x18024000 + 0x550)--- +* BASE_PTR[31..0] - (RW) Point to the base address of RXD Ring #5 +* (GE ports). It should be a 8-DWORD aligned address +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL0_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL0_BASE_PTR_MASK \ +0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_RX_RING5_CTRL1 (0x18024000 + 0x554)--- +* MAX_CNT[11..0] - (RW) The maximum number of RXD count in RXD +* Ring #5. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* RX_Ring5 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL1_BASE_PTR_EXT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL1_BASE_PTR_EXT_MASK \ +0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL1_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL1_MAX_CNT_MASK \ +0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING5_CTRL2 (0x18024000 + 0x558)--- +* CPU_IDX[11..0] - (RW) Point to the next RXD CPU wants to +* allocate to RXD Ring #5. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL2_CPU_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL2_CPU_IDX_MASK \ +0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING5_CTRL3 (0x18024000 + 0x55c)--- +* DMA_IDX[11..0] - (RW) Point to the next RXD PDMA engine wants +* to use for RXD Ring #5. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL3_DMA_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL3_DMA_IDX_MASK \ +0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING6_CTRL0 (0x18024000 + 0x560)--- +* BASE_PTR[31..0] - (RW) Point to the base address of RXD Ring #6 +* (GE ports). It should be a 8-DWORD aligned address +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL0_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL0_BASE_PTR_MASK \ +0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_RX_RING6_CTRL1 (0x18024000 + 0x564)--- +* MAX_CNT[11..0] - (RW) The maximum number of RXD count in RXD +* Ring #6. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* RX_Ring6 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL1_BASE_PTR_EXT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL1_BASE_PTR_EXT_MASK \ +0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL1_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL1_MAX_CNT_MASK \ +0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING6_CTRL2 (0x18024000 + 0x568)--- +* CPU_IDX[11..0] - (RW) Point to the next RXD CPU wants to +* allocate to RXD Ring #6. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL2_CPU_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL2_CPU_IDX_MASK \ +0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING6_CTRL3 (0x18024000 + 0x56C)--- +* DMA_IDX[11..0] - (RW) Point to the next RXD PDMA engine wants +* to use for RXD Ring #6. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL3_DMA_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL3_DMA_IDX_MASK \ +0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING7_CTRL0 (0x18024000 + 0x570)--- +* BASE_PTR[31..0] - (RW) Point to the base address of RXD Ring #7 +* (GE ports). It should be a 8-DWORD aligned address +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL0_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL0_BASE_PTR_MASK \ +0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_RX_RING7_CTRL1 (0x18024000 + 0x574)--- +* MAX_CNT[11..0] - (RW) The maximum number of RXD count in RXD +* Ring #7. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* RX_Ring7 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL1_BASE_PTR_EXT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL1_BASE_PTR_EXT_MASK \ +0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL1_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL1_MAX_CNT_MASK \ +0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING7_CTRL2 (0x18024000 + 0x578)--- +* CPU_IDX[11..0] - (RW) Point to the next RXD CPU wants to +* allocate to RXD Ring #7. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL2_CPU_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL2_CPU_IDX_MASK \ +0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING7_CTRL3 (0x18024000 + 0x57C)--- +* DMA_IDX[11..0] - (RW) Point to the next RXD PDMA engine wants +* to use for RXD Ring #7. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL3_DMA_IDX_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL3_DMA_IDX_MASK \ +0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING0_EXT_CTRL (0x18024000 + 0x600)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #0 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_EXT_CTRL_DISP_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_EXT_CTRL_DISP_BASE_PTR_MASK \ +0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_EXT_CTRL_DISP_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_EXT_CTRL_DISP_MAX_CNT_MASK \ +0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING1_EXT_CTRL (0x18024000 + 0x604)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #1 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_EXT_CTRL_DISP_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_EXT_CTRL_DISP_BASE_PTR_MASK \ +0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_EXT_CTRL_DISP_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_EXT_CTRL_DISP_MAX_CNT_MASK \ +0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING2_EXT_CTRL (0x18024000 + 0x608)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #2 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_EXT_CTRL_DISP_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_EXT_CTRL_DISP_BASE_PTR_MASK \ +0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_EXT_CTRL_DISP_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_EXT_CTRL_DISP_MAX_CNT_MASK \ +0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING3_EXT_CTRL (0x18024000 + 0x60C)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #3 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_EXT_CTRL_DISP_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_EXT_CTRL_DISP_BASE_PTR_MASK \ +0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_EXT_CTRL_DISP_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_EXT_CTRL_DISP_MAX_CNT_MASK \ +0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING4_EXT_CTRL (0x18024000 + 0x610)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #4 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_EXT_CTRL_DISP_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_EXT_CTRL_DISP_BASE_PTR_MASK \ +0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_EXT_CTRL_DISP_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_EXT_CTRL_DISP_MAX_CNT_MASK \ +0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING5_EXT_CTRL (0x18024000 + 0x614)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #5 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_EXT_CTRL_DISP_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_EXT_CTRL_DISP_BASE_PTR_MASK \ +0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_EXT_CTRL_DISP_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_EXT_CTRL_DISP_MAX_CNT_MASK \ +0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING6_EXT_CTRL (0x18024000 + 0x618)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #6 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_EXT_CTRL_DISP_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_EXT_CTRL_DISP_BASE_PTR_MASK \ +0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_EXT_CTRL_DISP_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_EXT_CTRL_DISP_MAX_CNT_MASK \ +0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING7_EXT_CTRL (0x18024000 + 0x61C)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #7 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_EXT_CTRL_DISP_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_EXT_CTRL_DISP_BASE_PTR_MASK \ +0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_EXT_CTRL_DISP_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_EXT_CTRL_DISP_MAX_CNT_MASK \ +0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING8_EXT_CTRL (0x18024000 + 0x620)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #0 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_EXT_CTRL_DISP_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_EXT_CTRL_DISP_BASE_PTR_MASK \ +0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_EXT_CTRL_DISP_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_EXT_CTRL_DISP_MAX_CNT_MASK \ +0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING9_EXT_CTRL (0x18024000 + 0x624)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #1 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_EXT_CTRL_DISP_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_EXT_CTRL_DISP_BASE_PTR_MASK \ +0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_EXT_CTRL_DISP_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_EXT_CTRL_DISP_MAX_CNT_MASK \ +0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING10_EXT_CTRL (0x18024000 + 0x628)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #2 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_EXT_CTRL_DISP_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_EXT_CTRL_DISP_BASE_PTR_MASK \ +0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_EXT_CTRL_DISP_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_EXT_CTRL_DISP_MAX_CNT_MASK \ +0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING11_EXT_CTRL (0x18024000 + 0x62C)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #3 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_EXT_CTRL_DISP_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_EXT_CTRL_DISP_BASE_PTR_MASK \ +0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_EXT_CTRL_DISP_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_EXT_CTRL_DISP_MAX_CNT_MASK \ +0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING12_EXT_CTRL (0x18024000 + 0x630)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #4 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_EXT_CTRL_DISP_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_EXT_CTRL_DISP_BASE_PTR_MASK \ +0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_EXT_CTRL_DISP_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_EXT_CTRL_DISP_MAX_CNT_MASK \ +0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING13_EXT_CTRL (0x18024000 + 0x634)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #5 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_EXT_CTRL_DISP_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_EXT_CTRL_DISP_BASE_PTR_MASK \ +0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_EXT_CTRL_DISP_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_EXT_CTRL_DISP_MAX_CNT_MASK \ +0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING14_EXT_CTRL (0x18024000 + 0x638)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #6 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_EXT_CTRL_DISP_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_EXT_CTRL_DISP_BASE_PTR_MASK \ +0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_EXT_CTRL_DISP_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_EXT_CTRL_DISP_MAX_CNT_MASK \ +0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING15_EXT_CTRL (0x18024000 + 0x63C)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #7 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_EXT_CTRL_DISP_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_EXT_CTRL_DISP_BASE_PTR_MASK \ +0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_EXT_CTRL_DISP_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_EXT_CTRL_DISP_MAX_CNT_MASK \ +0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING16_EXT_CTRL (0x18024000 + 0x640)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #16 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_EXT_CTRL_DISP_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_EXT_CTRL_DISP_BASE_PTR_MASK \ +0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_EXT_CTRL_DISP_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_EXT_CTRL_DISP_MAX_CNT_MASK \ +0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING17_EXT_CTRL (0x18024000 + 0x644)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #17 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_EXT_CTRL_DISP_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_EXT_CTRL_DISP_BASE_PTR_MASK \ +0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_EXT_CTRL_DISP_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_EXT_CTRL_DISP_MAX_CNT_MASK \ +0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING18_EXT_CTRL (0x18024000 + 0x648)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #18 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_EXT_CTRL_DISP_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_EXT_CTRL_DISP_BASE_PTR_MASK \ +0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_EXT_CTRL_DISP_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_EXT_CTRL_DISP_MAX_CNT_MASK \ +0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING0_EXT_CTRL (0x18024000 + 0x680)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) RXD Ring #0 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_EXT_CTRL_DISP_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_EXT_CTRL_DISP_BASE_PTR_MASK \ +0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_EXT_CTRL_DISP_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_EXT_CTRL_DISP_MAX_CNT_MASK \ +0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING1_EXT_CTRL (0x18024000 + 0x684)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) RXD Ring #1 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_EXT_CTRL_DISP_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_EXT_CTRL_DISP_BASE_PTR_MASK \ +0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_EXT_CTRL_DISP_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_EXT_CTRL_DISP_MAX_CNT_MASK \ +0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING2_EXT_CTRL (0x18024000 + 0x688)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) RXD Ring #2 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_EXT_CTRL_DISP_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_EXT_CTRL_DISP_BASE_PTR_MASK \ +0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_EXT_CTRL_DISP_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_EXT_CTRL_DISP_MAX_CNT_MASK \ +0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING3_EXT_CTRL (0x18024000 + 0x68C)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) RXD Ring #3 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_EXT_CTRL_DISP_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_EXT_CTRL_DISP_BASE_PTR_MASK \ +0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_EXT_CTRL_DISP_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_EXT_CTRL_DISP_MAX_CNT_MASK \ +0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING4_EXT_CTRL (0x18024000 + 0x690)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) RXD Ring #4 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_EXT_CTRL_DISP_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_EXT_CTRL_DISP_BASE_PTR_MASK \ +0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_EXT_CTRL_DISP_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_EXT_CTRL_DISP_MAX_CNT_MASK \ +0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING5_EXT_CTRL (0x18024000 + 0x694)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) RXD Ring #5 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_EXT_CTRL_DISP_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_EXT_CTRL_DISP_BASE_PTR_MASK \ +0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_EXT_CTRL_DISP_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_EXT_CTRL_DISP_MAX_CNT_MASK \ +0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING6_EXT_CTRL (0x18024000 + 0x698)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) RXD Ring #6 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_EXT_CTRL_DISP_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_EXT_CTRL_DISP_BASE_PTR_MASK \ +0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_EXT_CTRL_DISP_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_EXT_CTRL_DISP_MAX_CNT_MASK \ +0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING7_EXT_CTRL (0x18024000 + 0x69C)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) RXD Ring #7 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_EXT_CTRL_DISP_BASE_PTR_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_EXT_CTRL_DISP_BASE_PTR_MASK \ +0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_EXT_CTRL_DISP_MAX_CNT_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_EXT_CTRL_DISP_MAX_CNT_MASK \ +0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING0_BKRS_CTRL0 (0x18024000 + 0xA00)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL0_pf_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL0_pf_didx_idx_MASK \ +0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL0_pld_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL0_pld_didx_idx_MASK \ +0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING0_BKRS_CTRL1 (0x18024000 + 0xA04)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL1_disp_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL1_disp_didx_idx_MASK \ +0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL1_disp_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL1_disp_cidx_idx_MASK \ +0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING0_BKRS_CTRL2 (0x18024000 + 0xA08)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_disp_ring_vld_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_disp_ring_vld_MASK \ +0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_pf_dq_ring_empty_MASK \ +0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_pf_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_pf_ring_empty_MASK \ +0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_pld_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_pld_ring_empty_MASK \ +0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_pld_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_pld_cidx_idx_MASK \ +0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING1_BKRS_CTRL0 (0x18024000 + 0xA10)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL0_pf_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL0_pf_didx_idx_MASK \ +0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL0_pld_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL0_pld_didx_idx_MASK \ +0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING1_BKRS_CTRL1 (0x18024000 + 0xA14)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL1_disp_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL1_disp_didx_idx_MASK \ +0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL1_disp_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL1_disp_cidx_idx_MASK \ +0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING1_BKRS_CTRL2 (0x18024000 + 0xA18)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_disp_ring_vld_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_disp_ring_vld_MASK \ +0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_pf_dq_ring_empty_MASK \ +0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_pf_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_pf_ring_empty_MASK \ +0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_pld_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_pld_ring_empty_MASK \ +0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_pld_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_pld_cidx_idx_MASK \ +0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING2_BKRS_CTRL0 (0x18024000 + 0xA20)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL0_pf_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL0_pf_didx_idx_MASK \ +0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL0_pld_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL0_pld_didx_idx_MASK \ +0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING2_BKRS_CTRL1 (0x18024000 + 0xA24)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL1_disp_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL1_disp_didx_idx_MASK \ +0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL1_disp_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL1_disp_cidx_idx_MASK \ +0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING2_BKRS_CTRL2 (0x18024000 + 0xA28)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_disp_ring_vld_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_disp_ring_vld_MASK \ +0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_pf_dq_ring_empty_MASK \ +0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_pf_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_pf_ring_empty_MASK \ +0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_pld_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_pld_ring_empty_MASK \ +0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_pld_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_pld_cidx_idx_MASK \ +0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING3_BKRS_CTRL0 (0x18024000 + 0xA30)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL0_pf_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL0_pf_didx_idx_MASK \ +0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL0_pld_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL0_pld_didx_idx_MASK \ +0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING3_BKRS_CTRL1 (0x18024000 + 0xA34)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL1_disp_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL1_disp_didx_idx_MASK \ +0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL1_disp_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL1_disp_cidx_idx_MASK \ +0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING3_BKRS_CTRL2 (0x18024000 + 0xA38)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_disp_ring_vld_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_disp_ring_vld_MASK \ +0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_pf_dq_ring_empty_MASK \ +0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_pf_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_pf_ring_empty_MASK \ +0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_pld_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_pld_ring_empty_MASK \ +0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_pld_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_pld_cidx_idx_MASK \ +0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING4_BKRS_CTRL0 (0x18024000 + 0xA40)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_BKRS_CTRL0_pf_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_BKRS_CTRL0_pf_didx_idx_MASK \ +0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_BKRS_CTRL0_pld_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_BKRS_CTRL0_pld_didx_idx_MASK \ +0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING4_BKRS_CTRL1 (0x18024000 + 0xA44)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_BKRS_CTRL1_disp_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_BKRS_CTRL1_disp_didx_idx_MASK \ +0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_BKRS_CTRL1_disp_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_BKRS_CTRL1_disp_cidx_idx_MASK \ +0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING4_BKRS_CTRL2 (0x18024000 + 0xA48)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_BKRS_CTRL2_disp_ring_vld_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_BKRS_CTRL2_disp_ring_vld_MASK \ +0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_BKRS_CTRL2_pf_dq_ring_empty_MASK \ +0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_BKRS_CTRL2_pf_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_BKRS_CTRL2_pf_ring_empty_MASK \ +0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_BKRS_CTRL2_pld_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_BKRS_CTRL2_pld_ring_empty_MASK \ +0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_BKRS_CTRL2_pld_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_BKRS_CTRL2_pld_cidx_idx_MASK \ +0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING4_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING5_BKRS_CTRL0 (0x18024000 + 0xA50)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_BKRS_CTRL0_pf_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_BKRS_CTRL0_pf_didx_idx_MASK \ +0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_BKRS_CTRL0_pld_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_BKRS_CTRL0_pld_didx_idx_MASK \ +0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING5_BKRS_CTRL1 (0x18024000 + 0xA54)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_BKRS_CTRL1_disp_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_BKRS_CTRL1_disp_didx_idx_MASK \ +0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_BKRS_CTRL1_disp_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_BKRS_CTRL1_disp_cidx_idx_MASK \ +0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING5_BKRS_CTRL2 (0x18024000 + 0xA58)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_BKRS_CTRL2_disp_ring_vld_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_BKRS_CTRL2_disp_ring_vld_MASK \ +0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_BKRS_CTRL2_pf_dq_ring_empty_MASK \ +0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_BKRS_CTRL2_pf_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_BKRS_CTRL2_pf_ring_empty_MASK \ +0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_BKRS_CTRL2_pld_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_BKRS_CTRL2_pld_ring_empty_MASK \ +0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_BKRS_CTRL2_pld_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_BKRS_CTRL2_pld_cidx_idx_MASK \ +0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING5_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING6_BKRS_CTRL0 (0x18024000 + 0xA60)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_BKRS_CTRL0_pf_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_BKRS_CTRL0_pf_didx_idx_MASK \ +0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_BKRS_CTRL0_pld_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_BKRS_CTRL0_pld_didx_idx_MASK \ +0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING6_BKRS_CTRL1 (0x18024000 + 0xA64)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_BKRS_CTRL1_disp_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_BKRS_CTRL1_disp_didx_idx_MASK \ +0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_BKRS_CTRL1_disp_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_BKRS_CTRL1_disp_cidx_idx_MASK \ +0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING6_BKRS_CTRL2 (0x18024000 + 0xA68)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_BKRS_CTRL2_disp_ring_vld_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_BKRS_CTRL2_disp_ring_vld_MASK \ +0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_BKRS_CTRL2_pf_dq_ring_empty_MASK \ +0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_BKRS_CTRL2_pf_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_BKRS_CTRL2_pf_ring_empty_MASK \ +0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_BKRS_CTRL2_pld_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_BKRS_CTRL2_pld_ring_empty_MASK \ +0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_BKRS_CTRL2_pld_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_BKRS_CTRL2_pld_cidx_idx_MASK \ +0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING6_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING7_BKRS_CTRL0 (0x18024000 + 0xA70)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_BKRS_CTRL0_pf_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_BKRS_CTRL0_pf_didx_idx_MASK \ +0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_BKRS_CTRL0_pld_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_BKRS_CTRL0_pld_didx_idx_MASK \ +0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING7_BKRS_CTRL1 (0x18024000 + 0xA74)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_BKRS_CTRL1_disp_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_BKRS_CTRL1_disp_didx_idx_MASK \ +0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_BKRS_CTRL1_disp_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_BKRS_CTRL1_disp_cidx_idx_MASK \ +0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING7_BKRS_CTRL2 (0x18024000 + 0xA78)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_BKRS_CTRL2_disp_ring_vld_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_BKRS_CTRL2_disp_ring_vld_MASK \ +0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_BKRS_CTRL2_pf_dq_ring_empty_MASK \ +0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_BKRS_CTRL2_pf_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_BKRS_CTRL2_pf_ring_empty_MASK \ +0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_BKRS_CTRL2_pld_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_BKRS_CTRL2_pld_ring_empty_MASK \ +0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_BKRS_CTRL2_pld_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_BKRS_CTRL2_pld_cidx_idx_MASK \ +0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING7_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING8_BKRS_CTRL0 (0x18024000 + 0xA80)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_BKRS_CTRL0_pf_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_BKRS_CTRL0_pf_didx_idx_MASK \ +0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_BKRS_CTRL0_pld_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_BKRS_CTRL0_pld_didx_idx_MASK \ +0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING8_BKRS_CTRL1 (0x18024000 + 0xA84)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_BKRS_CTRL1_disp_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_BKRS_CTRL1_disp_didx_idx_MASK \ +0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_BKRS_CTRL1_disp_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_BKRS_CTRL1_disp_cidx_idx_MASK \ +0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING8_BKRS_CTRL2 (0x18024000 + 0xA88)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_BKRS_CTRL2_disp_ring_vld_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_BKRS_CTRL2_disp_ring_vld_MASK \ +0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_BKRS_CTRL2_pf_dq_ring_empty_MASK \ +0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_BKRS_CTRL2_pf_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_BKRS_CTRL2_pf_ring_empty_MASK \ +0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_BKRS_CTRL2_pld_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_BKRS_CTRL2_pld_ring_empty_MASK \ +0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_BKRS_CTRL2_pld_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_BKRS_CTRL2_pld_cidx_idx_MASK \ +0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING8_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING9_BKRS_CTRL0 (0x18024000 + 0xA90)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_BKRS_CTRL0_pf_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_BKRS_CTRL0_pf_didx_idx_MASK \ +0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_BKRS_CTRL0_pld_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_BKRS_CTRL0_pld_didx_idx_MASK \ +0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING9_BKRS_CTRL1 (0x18024000 + 0xA94)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_BKRS_CTRL1_disp_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_BKRS_CTRL1_disp_didx_idx_MASK \ +0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_BKRS_CTRL1_disp_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_BKRS_CTRL1_disp_cidx_idx_MASK \ +0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING9_BKRS_CTRL2 (0x18024000 + 0xA98)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_BKRS_CTRL2_disp_ring_vld_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_BKRS_CTRL2_disp_ring_vld_MASK \ +0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_BKRS_CTRL2_pf_dq_ring_empty_MASK \ +0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_BKRS_CTRL2_pf_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_BKRS_CTRL2_pf_ring_empty_MASK \ +0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_BKRS_CTRL2_pld_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_BKRS_CTRL2_pld_ring_empty_MASK \ +0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_BKRS_CTRL2_pld_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_BKRS_CTRL2_pld_cidx_idx_MASK \ +0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING9_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING10_BKRS_CTRL0 (0x18024000 + 0xAA0)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_BKRS_CTRL0_pf_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_BKRS_CTRL0_pf_didx_idx_MASK \ +0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_BKRS_CTRL0_pld_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_BKRS_CTRL0_pld_didx_idx_MASK \ +0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING10_BKRS_CTRL1 (0x18024000 + 0xAA4)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_BKRS_CTRL1_disp_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_BKRS_CTRL1_disp_didx_idx_MASK \ +0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_BKRS_CTRL1_disp_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_BKRS_CTRL1_disp_cidx_idx_MASK \ +0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING10_BKRS_CTRL2 (0x18024000 + 0xAA8)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_BKRS_CTRL2_disp_ring_vld_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_BKRS_CTRL2_disp_ring_vld_MASK \ +0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_BKRS_CTRL2_pf_dq_ring_empty_MASK \ +0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_BKRS_CTRL2_pf_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_BKRS_CTRL2_pf_ring_empty_MASK \ +0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_BKRS_CTRL2_pld_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_BKRS_CTRL2_pld_ring_empty_MASK \ +0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_BKRS_CTRL2_pld_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_BKRS_CTRL2_pld_cidx_idx_MASK \ +0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING10_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING11_BKRS_CTRL0 (0x18024000 + 0xAB0)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_BKRS_CTRL0_pf_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_BKRS_CTRL0_pf_didx_idx_MASK \ +0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_BKRS_CTRL0_pld_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_BKRS_CTRL0_pld_didx_idx_MASK \ +0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING11_BKRS_CTRL1 (0x18024000 + 0xAB4)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_BKRS_CTRL1_disp_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_BKRS_CTRL1_disp_didx_idx_MASK \ +0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_BKRS_CTRL1_disp_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_BKRS_CTRL1_disp_cidx_idx_MASK \ +0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING11_BKRS_CTRL2 (0x18024000 + 0xAB8)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_BKRS_CTRL2_disp_ring_vld_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_BKRS_CTRL2_disp_ring_vld_MASK \ +0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_BKRS_CTRL2_pf_dq_ring_empty_MASK \ +0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_BKRS_CTRL2_pf_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_BKRS_CTRL2_pf_ring_empty_MASK \ +0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_BKRS_CTRL2_pld_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_BKRS_CTRL2_pld_ring_empty_MASK \ +0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_BKRS_CTRL2_pld_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_BKRS_CTRL2_pld_cidx_idx_MASK \ +0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING11_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING12_BKRS_CTRL0 (0x18024000 + 0xAC0)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_BKRS_CTRL0_pf_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_BKRS_CTRL0_pf_didx_idx_MASK \ +0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_BKRS_CTRL0_pld_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_BKRS_CTRL0_pld_didx_idx_MASK \ +0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING12_BKRS_CTRL1 (0x18024000 + 0xAC4)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_BKRS_CTRL1_disp_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_BKRS_CTRL1_disp_didx_idx_MASK \ +0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_BKRS_CTRL1_disp_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_BKRS_CTRL1_disp_cidx_idx_MASK \ +0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING12_BKRS_CTRL2 (0x18024000 + 0xAC8)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_BKRS_CTRL2_disp_ring_vld_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_BKRS_CTRL2_disp_ring_vld_MASK \ +0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_BKRS_CTRL2_pf_dq_ring_empty_MASK \ +0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_BKRS_CTRL2_pf_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_BKRS_CTRL2_pf_ring_empty_MASK \ +0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_BKRS_CTRL2_pld_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_BKRS_CTRL2_pld_ring_empty_MASK \ +0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_BKRS_CTRL2_pld_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_BKRS_CTRL2_pld_cidx_idx_MASK \ +0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING12_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING13_BKRS_CTRL0 (0x18024000 + 0xAD0)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_BKRS_CTRL0_pf_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_BKRS_CTRL0_pf_didx_idx_MASK \ +0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_BKRS_CTRL0_pld_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_BKRS_CTRL0_pld_didx_idx_MASK \ +0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING13_BKRS_CTRL1 (0x18024000 + 0xAD4)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_BKRS_CTRL1_disp_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_BKRS_CTRL1_disp_didx_idx_MASK \ +0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_BKRS_CTRL1_disp_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_BKRS_CTRL1_disp_cidx_idx_MASK \ +0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING13_BKRS_CTRL2 (0x18024000 + 0xAD8)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_BKRS_CTRL2_disp_ring_vld_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_BKRS_CTRL2_disp_ring_vld_MASK \ +0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_BKRS_CTRL2_pf_dq_ring_empty_MASK \ +0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_BKRS_CTRL2_pf_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_BKRS_CTRL2_pf_ring_empty_MASK \ +0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_BKRS_CTRL2_pld_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_BKRS_CTRL2_pld_ring_empty_MASK \ +0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_BKRS_CTRL2_pld_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_BKRS_CTRL2_pld_cidx_idx_MASK \ +0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING13_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING14_BKRS_CTRL0 (0x18024000 + 0xAE0)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_BKRS_CTRL0_pf_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_BKRS_CTRL0_pf_didx_idx_MASK \ +0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_BKRS_CTRL0_pld_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_BKRS_CTRL0_pld_didx_idx_MASK \ +0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING14_BKRS_CTRL1 (0x18024000 + 0xAE4)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_BKRS_CTRL1_disp_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_BKRS_CTRL1_disp_didx_idx_MASK \ +0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_BKRS_CTRL1_disp_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_BKRS_CTRL1_disp_cidx_idx_MASK \ +0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING14_BKRS_CTRL2 (0x18024000 + 0xAE8)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_BKRS_CTRL2_disp_ring_vld_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_BKRS_CTRL2_disp_ring_vld_MASK \ +0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_BKRS_CTRL2_pf_dq_ring_empty_MASK \ +0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_BKRS_CTRL2_pf_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_BKRS_CTRL2_pf_ring_empty_MASK \ +0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_BKRS_CTRL2_pld_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_BKRS_CTRL2_pld_ring_empty_MASK \ +0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_BKRS_CTRL2_pld_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_BKRS_CTRL2_pld_cidx_idx_MASK \ +0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING14_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING15_BKRS_CTRL0 (0x18024000 + 0xAF0)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_BKRS_CTRL0_pf_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_BKRS_CTRL0_pf_didx_idx_MASK \ +0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_BKRS_CTRL0_pld_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_BKRS_CTRL0_pld_didx_idx_MASK \ +0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING15_BKRS_CTRL1 (0x18024000 + 0xAF4)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_BKRS_CTRL1_disp_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_BKRS_CTRL1_disp_didx_idx_MASK \ +0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_BKRS_CTRL1_disp_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_BKRS_CTRL1_disp_cidx_idx_MASK \ +0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING15_BKRS_CTRL2 (0x18024000 + 0xAF8)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_BKRS_CTRL2_disp_ring_vld_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_BKRS_CTRL2_disp_ring_vld_MASK \ +0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_BKRS_CTRL2_pf_dq_ring_empty_MASK \ +0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_BKRS_CTRL2_pf_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_BKRS_CTRL2_pf_ring_empty_MASK \ +0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_BKRS_CTRL2_pld_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_BKRS_CTRL2_pld_ring_empty_MASK \ +0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_BKRS_CTRL2_pld_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_BKRS_CTRL2_pld_cidx_idx_MASK \ +0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING15_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING16_BKRS_CTRL0 (0x18024000 + 0xB00)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_BKRS_CTRL0_pf_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_BKRS_CTRL0_pf_didx_idx_MASK \ +0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_BKRS_CTRL0_pld_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_BKRS_CTRL0_pld_didx_idx_MASK \ +0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING16_BKRS_CTRL1 (0x18024000 + 0xB04)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_BKRS_CTRL1_disp_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_BKRS_CTRL1_disp_didx_idx_MASK \ +0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_BKRS_CTRL1_disp_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_BKRS_CTRL1_disp_cidx_idx_MASK \ +0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING16_BKRS_CTRL2 (0x18024000 + 0xB08)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_BKRS_CTRL2_disp_ring_vld_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_BKRS_CTRL2_disp_ring_vld_MASK \ +0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_BKRS_CTRL2_pf_dq_ring_empty_MASK \ +0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_BKRS_CTRL2_pf_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_BKRS_CTRL2_pf_ring_empty_MASK \ +0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_BKRS_CTRL2_pld_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_BKRS_CTRL2_pld_ring_empty_MASK \ +0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_BKRS_CTRL2_pld_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_BKRS_CTRL2_pld_cidx_idx_MASK \ +0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING17_BKRS_CTRL0 (0x18024000 + 0xB10)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_BKRS_CTRL0_pf_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_BKRS_CTRL0_pf_didx_idx_MASK \ +0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_BKRS_CTRL0_pld_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_BKRS_CTRL0_pld_didx_idx_MASK \ +0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING17_BKRS_CTRL1 (0x18024000 + 0xB14)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_BKRS_CTRL1_disp_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_BKRS_CTRL1_disp_didx_idx_MASK \ +0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_BKRS_CTRL1_disp_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_BKRS_CTRL1_disp_cidx_idx_MASK \ +0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING17_BKRS_CTRL2 (0x18024000 + 0xB18)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_BKRS_CTRL2_disp_ring_vld_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_BKRS_CTRL2_disp_ring_vld_MASK \ +0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_BKRS_CTRL2_pf_dq_ring_empty_MASK \ +0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_BKRS_CTRL2_pf_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_BKRS_CTRL2_pf_ring_empty_MASK \ +0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_BKRS_CTRL2_pld_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_BKRS_CTRL2_pld_ring_empty_MASK \ +0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_BKRS_CTRL2_pld_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_BKRS_CTRL2_pld_cidx_idx_MASK \ +0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING18_BKRS_CTRL0 (0x18024000 + 0xB20)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_BKRS_CTRL0_pf_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_BKRS_CTRL0_pf_didx_idx_MASK \ +0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_BKRS_CTRL0_pld_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_BKRS_CTRL0_pld_didx_idx_MASK \ +0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING18_BKRS_CTRL1 (0x18024000 + 0xB24)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_BKRS_CTRL1_disp_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_BKRS_CTRL1_disp_didx_idx_MASK \ +0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_BKRS_CTRL1_disp_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_BKRS_CTRL1_disp_cidx_idx_MASK \ +0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING18_BKRS_CTRL2 (0x18024000 + 0xB28)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_BKRS_CTRL2_disp_ring_vld_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_BKRS_CTRL2_disp_ring_vld_MASK \ +0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_BKRS_CTRL2_pf_dq_ring_empty_MASK \ +0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_BKRS_CTRL2_pf_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_BKRS_CTRL2_pf_ring_empty_MASK \ +0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_BKRS_CTRL2_pld_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_BKRS_CTRL2_pld_ring_empty_MASK \ +0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_BKRS_CTRL2_pld_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_BKRS_CTRL2_pld_cidx_idx_MASK \ +0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING0_BKRS_CTRL0 (0x18024000 + 0xC00)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL0_pf_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL0_pf_didx_idx_MASK \ +0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL0_pld_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL0_pld_didx_idx_MASK \ +0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING0_BKRS_CTRL1 (0x18024000 + 0xC04)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL1_disp_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL1_disp_didx_idx_MASK \ +0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL1_disp_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL1_disp_cidx_idx_MASK \ +0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING0_BKRS_CTRL2 (0x18024000 + 0xC08)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_disp_ring_vld_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_disp_ring_vld_MASK \ +0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_pf_dq_ring_empty_MASK \ +0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_pf_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_pf_ring_empty_MASK \ +0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_pld_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_pld_ring_empty_MASK \ +0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_pld_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_pld_cidx_idx_MASK \ +0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING1_BKRS_CTRL0 (0x18024000 + 0xC10)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL0_pf_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL0_pf_didx_idx_MASK \ +0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL0_pld_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL0_pld_didx_idx_MASK \ +0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING1_BKRS_CTRL1 (0x18024000 + 0xC14)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL1_disp_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL1_disp_didx_idx_MASK \ +0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL1_disp_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL1_disp_cidx_idx_MASK \ +0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING1_BKRS_CTRL2 (0x18024000 + 0xC18)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_disp_ring_vld_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_disp_ring_vld_MASK \ +0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_pf_dq_ring_empty_MASK \ +0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_pf_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_pf_ring_empty_MASK \ +0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_pld_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_pld_ring_empty_MASK \ +0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_pld_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_pld_cidx_idx_MASK \ +0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING2_BKRS_CTRL0 (0x18024000 + 0xC20)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL0_pf_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL0_pf_didx_idx_MASK \ +0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL0_pld_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL0_pld_didx_idx_MASK \ +0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING2_BKRS_CTRL1 (0x18024000 + 0xC24)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL1_disp_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL1_disp_didx_idx_MASK \ +0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL1_disp_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL1_disp_cidx_idx_MASK \ +0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING2_BKRS_CTRL2 (0x18024000 + 0xC28)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_disp_ring_vld_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_disp_ring_vld_MASK \ +0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_pf_dq_ring_empty_MASK \ +0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_pf_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_pf_ring_empty_MASK \ +0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_pld_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_pld_ring_empty_MASK \ +0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_pld_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_pld_cidx_idx_MASK \ +0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING3_BKRS_CTRL0 (0x18024000 + 0xC30)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL0_pf_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL0_pf_didx_idx_MASK \ +0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL0_pld_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL0_pld_didx_idx_MASK \ +0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING3_BKRS_CTRL1 (0x18024000 + 0xC34)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL1_disp_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL1_disp_didx_idx_MASK \ +0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL1_disp_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL1_disp_cidx_idx_MASK \ +0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING3_BKRS_CTRL2 (0x18024000 + 0xC38)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_disp_ring_vld_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_disp_ring_vld_MASK \ +0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_pf_dq_ring_empty_MASK \ +0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_pf_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_pf_ring_empty_MASK \ +0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_pld_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_pld_ring_empty_MASK \ +0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_pld_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_pld_cidx_idx_MASK \ +0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING4_BKRS_CTRL0 (0x18024000 + 0xC40)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL0_pf_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL0_pf_didx_idx_MASK \ +0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL0_pld_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL0_pld_didx_idx_MASK \ +0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING4_BKRS_CTRL1 (0x18024000 + 0xC44)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL1_disp_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL1_disp_didx_idx_MASK \ +0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL1_disp_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL1_disp_cidx_idx_MASK \ +0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING4_BKRS_CTRL2 (0x18024000 + 0xC48)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL2_disp_ring_vld_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL2_disp_ring_vld_MASK \ +0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL2_pf_dq_ring_empty_MASK \ +0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL2_pf_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL2_pf_ring_empty_MASK \ +0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL2_pld_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL2_pld_ring_empty_MASK \ +0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL2_pld_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL2_pld_cidx_idx_MASK \ +0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING5_BKRS_CTRL0 (0x18024000 + 0xC50)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL0_pf_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL0_pf_didx_idx_MASK \ +0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL0_pld_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL0_pld_didx_idx_MASK \ +0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING5_BKRS_CTRL1 (0x18024000 + 0xC54)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL1_disp_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL1_disp_didx_idx_MASK \ +0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL1_disp_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL1_disp_cidx_idx_MASK \ +0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING5_BKRS_CTRL2 (0x18024000 + 0xC58)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL2_disp_ring_vld_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL2_disp_ring_vld_MASK \ +0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL2_pf_dq_ring_empty_MASK \ +0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL2_pf_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL2_pf_ring_empty_MASK \ +0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL2_pld_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL2_pld_ring_empty_MASK \ +0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL2_pld_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL2_pld_cidx_idx_MASK \ +0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING6_BKRS_CTRL0 (0x18024000 + 0xC60)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL0_pf_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL0_pf_didx_idx_MASK \ +0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL0_pld_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL0_pld_didx_idx_MASK \ +0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING6_BKRS_CTRL1 (0x18024000 + 0xC64)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL1_disp_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL1_disp_didx_idx_MASK \ +0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL1_disp_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL1_disp_cidx_idx_MASK \ +0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING6_BKRS_CTRL2 (0x18024000 + 0xC68)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL2_disp_ring_vld_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL2_disp_ring_vld_MASK \ +0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL2_pf_dq_ring_empty_MASK \ +0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL2_pf_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL2_pf_ring_empty_MASK \ +0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL2_pld_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL2_pld_ring_empty_MASK \ +0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL2_pld_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL2_pld_cidx_idx_MASK \ +0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING7_BKRS_CTRL0 (0x18024000 + 0xC70)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL0_pf_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL0_pf_didx_idx_MASK \ +0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL0_pld_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL0_pld_didx_idx_MASK \ +0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING7_BKRS_CTRL1 (0x18024000 + 0xC74)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL1_disp_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL1_disp_didx_idx_MASK \ +0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL1_disp_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL1_disp_cidx_idx_MASK \ +0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING7_BKRS_CTRL2 (0x18024000 + 0xC78)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL2_disp_ring_vld_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL2_disp_ring_vld_MASK \ +0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL2_pf_dq_ring_empty_MASK \ +0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL2_pf_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL2_pf_ring_empty_MASK \ +0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL2_pld_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL2_pld_ring_empty_MASK \ +0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL2_pld_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL2_pld_cidx_idx_MASK \ +0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING8_BKRS_CTRL0 (0x18024000 + 0xC80)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING8_BKRS_CTRL0_pf_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING8_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING8_BKRS_CTRL0_pf_didx_idx_MASK \ +0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING8_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING8_BKRS_CTRL0_pld_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING8_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING8_BKRS_CTRL0_pld_didx_idx_MASK \ +0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING8_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING8_BKRS_CTRL1 (0x18024000 + 0xC84)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING8_BKRS_CTRL1_disp_didx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING8_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING8_BKRS_CTRL1_disp_didx_idx_MASK \ +0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING8_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING8_BKRS_CTRL1_disp_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING8_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING8_BKRS_CTRL1_disp_cidx_idx_MASK \ +0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING8_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING8_BKRS_CTRL2 (0x18024000 + 0xC88)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING8_BKRS_CTRL2_disp_ring_vld_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING8_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING8_BKRS_CTRL2_disp_ring_vld_MASK \ +0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING8_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING8_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING8_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING8_BKRS_CTRL2_pf_dq_ring_empty_MASK \ +0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING8_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING8_BKRS_CTRL2_pf_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING8_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING8_BKRS_CTRL2_pf_ring_empty_MASK \ +0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING8_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING8_BKRS_CTRL2_pld_ring_empty_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING8_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING8_BKRS_CTRL2_pld_ring_empty_MASK \ +0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING8_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING8_BKRS_CTRL2_pld_cidx_idx_ADDR \ +WF_WFDMA_HOST_DMA0_WPDMA_RX_RING8_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING8_BKRS_CTRL2_pld_cidx_idx_MASK \ +0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING8_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +#ifdef __cplusplus +} +#endif + +#endif /* __WF_WFDMA_HOST_DMA0_REGS_H__ */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/soc3_0/conn_infra_cfg.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/soc3_0/conn_infra_cfg.h new file mode 100644 index 0000000000000000000000000000000000000000..897b727cc6f03daad15502b39fcf44b963bf39eb --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/soc3_0/conn_infra_cfg.h @@ -0,0 +1,75 @@ +/* +*[File] : conn_infra_cfg.h +*[Revision time] : Tue Apr 16 15:11:54 2019 +*[Description] : This file is auto generated by CODA +*[Copyright] : Copyright (C) 2019 Mediatek Incorportion. +* All rights reserved. +*/ + +#ifndef __CONN_INFRA_CFG_REGS_H__ +#define __CONN_INFRA_CFG_REGS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +/**************************************************************************** +* +* CONN_INFRA_CFG CR Definitions +* +***************************************************************************** +*/ +#define CONN_INFRA_CFG_BASE 0x7C001000 +#define CONN_INFRA_CFG_AP2WF_BUS_ADDR 0x7C500000 +#define CONN_INFRA_CFG_PCIE2AP_REMAP_2_ADDR_DE_HARDCODE 0x18501844 + +#define CONN_INFRA_CFG_CONN_HW_VER_ADDR \ + (CONN_INFRA_CFG_BASE + 0x0000) /* 1000 */ +#define CONN_INFRA_CFG_CONN_CFG_ID_ADDR \ + (CONN_INFRA_CFG_BASE + 0x0004) /* 1004 */ +#define CONN_INFRA_CFG_CONN_FPGA_DUMMY0_ADDR \ + (CONN_INFRA_CFG_BASE + 0x0010) /* 1010 */ +#define CONN_INFRA_CFG_CONN_FPGA_DUMMY1_ADDR \ + (CONN_INFRA_CFG_BASE + 0x0014) /* 1014 */ +#define CONN_INFRA_CFG_EASY_SECURITY_WF_IRQ_CLR_ADDR \ + (CONN_INFRA_CFG_BASE + 0x00E0) /* 10E0 */ +#define CONN_INFRA_CFG_EASY_SECURITY_BGF_IRQ_CLR_ADDR \ + (CONN_INFRA_CFG_BASE + 0x00E4) /* 10E4 */ +#define CONN_INFRA_CFG_LIGHT_SECURITY_CTRL_ADDR \ + (CONN_INFRA_CFG_BASE + 0x00F0) /* 10F0 */ +#define CONN_INFRA_CFG_BUS_DEAD_CR_ADDRESS_ADDR \ + (CONN_INFRA_CFG_BASE + 0x00FC) /* 10FC */ +#define CONN_INFRA_CFG_AP2BGF_REMAP_0_ADDR \ + (CONN_INFRA_CFG_BASE + 0x0100) /* 1100 */ +#define CONN_INFRA_CFG_AP2BGF_REMAP_1_ADDR \ + (CONN_INFRA_CFG_BASE + 0x0104) /* 1104 */ +#define CONN_INFRA_CFG_AP2BGF_REMAP_2_ADDR \ + (CONN_INFRA_CFG_BASE + 0x0108) /* 1108 */ +#define CONN_INFRA_CFG_AP2BGF_REMAP_SEG_0_ADDR \ + (CONN_INFRA_CFG_BASE + 0x010C) /* 110C */ +#define CONN_INFRA_CFG_AP2BGF_REMAP_SEG_1_ADDR \ + (CONN_INFRA_CFG_BASE + 0x0110) /* 1110 */ +#define CONN_INFRA_CFG_SUBSYS2AP_REMAP_0_ADDR \ + (CONN_INFRA_CFG_BASE + 0x0114) /* 1114 */ +#define CONN_INFRA_CFG_AP2BGF_REMAP_3_ADDR \ + (CONN_INFRA_CFG_BASE + 0x0118) /* 1118 */ +#define CONN_INFRA_CFG_AP2WF_REMAP_0_ADDR \ + (CONN_INFRA_CFG_BASE + 0x011C) /* 111C */ + +/********************************************** +* Only define referenced CRs +*********************************************** +*/ + +#define CONN_INFRA_CFG_AP2WF_REMAP_1_ADDR \ + (CONN_INFRA_CFG_BASE + 0x0120) /* 1120 */ + +#define CONN_INFRA_CFG_PCIE2AP_REMAP_2_ADDR \ + (CONN_INFRA_CFG_BASE + 0x0198) /* 1198 */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CONN_INFRA_CFG_REGS_H__ */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/soc3_0/wf_hif_dmashdl_top.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/soc3_0/wf_hif_dmashdl_top.h new file mode 100644 index 0000000000000000000000000000000000000000..87c492dd20a628f4aa9298daa094852403fe5e64 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/soc3_0/wf_hif_dmashdl_top.h @@ -0,0 +1,2361 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +/* [File] : wf_hif_dmashdl_top.h */ +/* [Revision time] : Tue Aug 6 17:14:15 2019 */ +/* [Description] : This file is auto generated by CODA */ +/* [Copyright] : Copyright (C) 2019 Mediatek Incorportion. All rights */ +/* reserved. */ + +#ifndef __WF_HIF_DMASHDL_TOP_REGS_H__ +#define __WF_HIF_DMASHDL_TOP_REGS_H__ + + +#ifdef __cplusplus +extern "C" { +#endif + +/* ************************************************************************** */ +/* */ +/* WF_HIF_DMASHDL_TOP CR Definitions */ +/* */ +/* ************************************************************************** */ + +#define WF_HIF_DMASHDL_TOP_BASE 0x7C026000 + +#define WF_HIF_DMASHDL_TOP_WACPU_REFILL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x00) /* 6000 */ +#define WF_HIF_DMASHDL_TOP_SW_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x04) /* 6004 */ +#define WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x08) /* 6008 */ +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x0C) /* 600C */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x10) /* 6010 */ +#define WF_HIF_DMASHDL_TOP_TX_PACKET_SIZE_PAGE_MAP_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x14) /* 6014 */ +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x18) /* 6018 */ +#define WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x1c) /* 601C */ +#define WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x20) /* 6020 */ +#define WF_HIF_DMASHDL_TOP_GROUP1_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x24) /* 6024 */ +#define WF_HIF_DMASHDL_TOP_GROUP2_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x28) /* 6028 */ +#define WF_HIF_DMASHDL_TOP_GROUP3_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x2C) /* 602C */ +#define WF_HIF_DMASHDL_TOP_GROUP4_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x30) /* 6030 */ +#define WF_HIF_DMASHDL_TOP_GROUP5_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x34) /* 6034 */ +#define WF_HIF_DMASHDL_TOP_GROUP6_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x38) /* 6038 */ +#define WF_HIF_DMASHDL_TOP_GROUP7_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x3C) /* 603C */ +#define WF_HIF_DMASHDL_TOP_GROUP8_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x40) /* 6040 */ +#define WF_HIF_DMASHDL_TOP_GROUP9_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x44) /* 6044 */ +#define WF_HIF_DMASHDL_TOP_GROUP10_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x48) /* 6048 */ +#define WF_HIF_DMASHDL_TOP_GROUP11_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x4C) /* 604C */ +#define WF_HIF_DMASHDL_TOP_GROUP12_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x50) /* 6050 */ +#define WF_HIF_DMASHDL_TOP_GROUP13_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x54) /* 6054 */ +#define WF_HIF_DMASHDL_TOP_GROUP14_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x58) /* 6058 */ +#define WF_HIF_DMASHDL_TOP_GROUP15_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x5C) /* 605C */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD0_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x70) /* 6070 */ +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT00_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x80) /* 6080 */ +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT01_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x84) /* 6084 */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD02_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x88) /* 6088 */ +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x8C) /* 608C */ +#define WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x90) /* 6090 */ +#define WF_HIF_DMASHDL_TOP_HIF_ASK_LONG_CHECK_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x94) /* 6094 */ +#define WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x98) /* 6098 */ +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x9c) /* 609C */ +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0xB0) /* 60B0 */ +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0xB4) /* 60B4 */ +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0xC4) /* 60C4 */ +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0xC8) /* 60C8 */ +#define WF_HIF_DMASHDL_TOP_SLOT_PERIOD_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0xCC) /* 60CC */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0xd0) /* 60D0 */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0xd4) /* 60D4 */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0xd8) /* 60D8 */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0xdc) /* 60DC */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x100) /* 6100 */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x140) /* 6140 */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP1_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x144) /* 6144 */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP2_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x148) /* 6148 */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP3_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x14c) /* 614C */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP4_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x150) /* 6150 */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP5_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x154) /* 6154 */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP6_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x158) /* 6158 */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP7_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x15C) /* 615C */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP8_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x160) /* 6160 */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP9_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x164) /* 6164 */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP10_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x168) /* 6168 */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP11_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x16c) /* 616C */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP12_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x170) /* 6170 */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP13_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x174) /* 6174 */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP14_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x178) /* 6178 */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP15_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x17C) /* 617C */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT0_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x180) /* 6180 */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT1_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x184) /* 6184 */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT2_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x188) /* 6188 */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT3_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x18c) /* 618C */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT4_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x190) /* 6190 */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT5_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x194) /* 6194 */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT6_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x198) /* 6198 */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT7_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x19c) /* 619C */ + +/* +* ---WACPU_REFILL (0x7C026000 + 0x00)--- +* WACPU_RETURN_PAGE_CNT[11..0] - (RW) WACPU refill page count +* RESERVED12[15..12] - (RO) Reserved bits +* WACPU_RETRUN_QID[20..16] - (RW) WACPU refill queue ID +* RESERVED21[23..21] - (RO) Reserved bits +* WACPU_RETRUN_MODE[25..24] - (RW) WACPU refill mode selection +* 2'b00 : Return mode +* 2'b01 : Add reservation mode(initial quota +setting) +* 2'b10 : Substrate source mode +* 2'b11 : Add source mode +* RESERVED26[30..26] - (RO) Reserved bits +* WACPU_EXCUTE[31] - (WO) Excute this CR action +*/ +#define WF_HIF_DMASHDL_TOP_WACPU_REFILL_WACPU_EXCUTE_ADDR \ + WF_HIF_DMASHDL_TOP_WACPU_REFILL_ADDR +#define WF_HIF_DMASHDL_TOP_WACPU_REFILL_WACPU_EXCUTE_MASK \ + 0x80000000 /* WACPU_EXCUTE[31] */ +#define WF_HIF_DMASHDL_TOP_WACPU_REFILL_WACPU_EXCUTE_SHFT 31 +#define WF_HIF_DMASHDL_TOP_WACPU_REFILL_WACPU_RETRUN_MODE_ADDR \ + WF_HIF_DMASHDL_TOP_WACPU_REFILL_ADDR +#define WF_HIF_DMASHDL_TOP_WACPU_REFILL_WACPU_RETRUN_MODE_MASK \ + 0x03000000 /* WACPU_RETRUN_MODE[25..24] */ +#define WF_HIF_DMASHDL_TOP_WACPU_REFILL_WACPU_RETRUN_MODE_SHFT 24 +#define WF_HIF_DMASHDL_TOP_WACPU_REFILL_WACPU_RETRUN_QID_ADDR \ + WF_HIF_DMASHDL_TOP_WACPU_REFILL_ADDR +#define WF_HIF_DMASHDL_TOP_WACPU_REFILL_WACPU_RETRUN_QID_MASK \ + 0x001F0000 /* WACPU_RETRUN_QID[20..16] */ +#define WF_HIF_DMASHDL_TOP_WACPU_REFILL_WACPU_RETRUN_QID_SHFT 16 +#define WF_HIF_DMASHDL_TOP_WACPU_REFILL_WACPU_RETURN_PAGE_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_WACPU_REFILL_ADDR +#define WF_HIF_DMASHDL_TOP_WACPU_REFILL_WACPU_RETURN_PAGE_CNT_MASK \ + 0x00000FFF /* WACPU_RETURN_PAGE_CNT[11..0] */ +#define WF_HIF_DMASHDL_TOP_WACPU_REFILL_WACPU_RETURN_PAGE_CNT_SHFT 0 + +/* +* ---SW_CONTROL (0x7C026000 + 0x04)--- +* SW_LOG_RESET[0] - (RW) SW reset logic function action +* RESERVED1[27..1] - (RO) Reserved bits +* DMASHDL_BYPASS[28] - (RW) DMASHDL host ask and quota control +* function bypass +* RESERVED29[31..29] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_SW_CONTROL_DMASHDL_BYPASS_ADDR \ + WF_HIF_DMASHDL_TOP_SW_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_SW_CONTROL_DMASHDL_BYPASS_MASK \ + 0x10000000 /* DMASHDL_BYPASS[28] */ +#define WF_HIF_DMASHDL_TOP_SW_CONTROL_DMASHDL_BYPASS_SHFT 28 +#define WF_HIF_DMASHDL_TOP_SW_CONTROL_SW_LOG_RESET_ADDR \ + WF_HIF_DMASHDL_TOP_SW_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_SW_CONTROL_SW_LOG_RESET_MASK \ + 0x00000001 /* SW_LOG_RESET[0] */ +#define WF_HIF_DMASHDL_TOP_SW_CONTROL_SW_LOG_RESET_SHFT 0 + +/* +* ---OPTIONAL_CONTROL (0x7C026000 + 0x08)--- +* CR_HIF_GUP_ACT_MAP[15..0] - (RW) Group active mapping to joint the hif +* ask round robin setting in hif_ack_cnt_th period. +* Bit 0: group 0 joint active setting (1: +* joint, 0: disjoint) +* Bit 1: group 1 joint active setting (1: +* joint, 0: disjoint) +* Bit 2: group 2 joint active setting (1: +* joint, 0: disjoint) +* Bit 3: group 3 joint active setting (1: +* joint, 0: disjoint) +* Bit 4: group 4 joint active setting (1: +* joint, 0: disjoint) +* Bit 5: group 5 joint active setting (1: +* joint, 0: disjoint) +* Bit 6: group 6 joint active setting (1: +* joint, 0: disjoint) +* Bit 7: group 7 joint active setting (1: +* joint, 0: disjoint) +* Bit 8: group 8 joint active setting (1: +* joint, 0: disjoint) +* Bit 9: group 9 joint active setting (1: +* joint, 0: disjoint) +...... +* Bit 15: group 15 joint active setting (1: +* joint, 0: disjoint) +* CR_HIF_ACK_CNT_TH[23..16] - (RW) Host ask success count threshold setting +* to reset initial for round robin period +* RESERVED24[27..24] - (RO) Reserved bits +* CR_HIF_ASK_RR_ENA[28] - (RW) HIF ask round robin like arbiter enable +* CR_HIF_ASK_MIN_RR_ENA[29] - (RW) Source count below minimum quota check +* enable by round robin like arbitration +* CR_PSEBF_BL_TH2_NOBMIN_RASIGN_ENA[30] - (RW) Assignment when all TXD groups +* great or equal minimum quota +* CR_PSEBF_BL_TH2_CHK_DISABLE[31] - (RW) Disable PSE buffer Threshold 2 check +* and assignment +*/ +#define WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_CR_PSEBF_BL_TH2_CHK_DISABLE_ADDR \ + WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_CR_PSEBF_BL_TH2_CHK_DISABLE_MASK \ + 0x80000000 /* CR_PSEBF_BL_TH2_CHK_DISABLE[31] */ +#define WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_CR_PSEBF_BL_TH2_CHK_DISABLE_SHFT 31 +#define \ +WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_CR_PSEBF_BL_TH2_NOBMIN_RASIGN_ENA_ADDR \ + \ + WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_ADDR +#define \ +WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_CR_PSEBF_BL_TH2_NOBMIN_RASIGN_ENA_MASK \ + \ + 0x40000000 /* CR_PSEBF_BL_TH2_NOBMIN_RASIGN_ENA[30] */ +#define \ +WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_CR_PSEBF_BL_TH2_NOBMIN_RASIGN_ENA_SHFT \ + \ + 30 +#define WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_CR_HIF_ASK_MIN_RR_ENA_ADDR \ + WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_CR_HIF_ASK_MIN_RR_ENA_MASK \ + 0x20000000 /* CR_HIF_ASK_MIN_RR_ENA[29] */ +#define WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_CR_HIF_ASK_MIN_RR_ENA_SHFT 29 +#define WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_CR_HIF_ASK_RR_ENA_ADDR \ + WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_CR_HIF_ASK_RR_ENA_MASK \ + 0x10000000 /* CR_HIF_ASK_RR_ENA[28] */ +#define WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_CR_HIF_ASK_RR_ENA_SHFT 28 +#define WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_CR_HIF_ACK_CNT_TH_ADDR \ + WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_CR_HIF_ACK_CNT_TH_MASK \ + 0x00FF0000 /* CR_HIF_ACK_CNT_TH[23..16] */ +#define WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_CR_HIF_ACK_CNT_TH_SHFT 16 +#define WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_CR_HIF_GUP_ACT_MAP_ADDR \ + WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_CR_HIF_GUP_ACT_MAP_MASK \ + 0x0000FFFF /* CR_HIF_GUP_ACT_MAP[15..0] */ +#define WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_CR_HIF_GUP_ACT_MAP_SHFT 0 + +/* +* ---PAGE_SETTING (0x7C026000 + 0x0C)--- +* PSE_ADD_BSIZE[9..0] - (RW) PSE(command) packet size add extra byte +count +* RESERVED10[11..10] - (RO) Reserved bits +* PP_OFFSET_ADD_ENA[12] - (RW) PSE(command) packet size add offset +* enable from packet processor +* RESERVED13[15..13] - (RO) Reserved bits +* GROUP_SEQUENCE_ORDER_TYPE[16] - (RW) User program group sequence type +control +* SLOT_TYPE_ARBITER_CONTROL[17] - (RW) Slot type arbiter control +* DUMMY_00[18] - (RW) Dummy_00 bit +* DUMMY_01[19] - (RW) Dummy_01 bit +* SRC_CNT_PRI_EN[20] - (RW) Source count below min quota first +* priority check enable +* QUP_ACL_SLOT_CG_EN[21] - (RW) Group ack then slot ID change function +enable +* RESERVED22[31..22] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_QUP_ACL_SLOT_CG_EN_ADDR \ + WF_HIF_DMASHDL_TOP_PAGE_SETTING_ADDR +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_QUP_ACL_SLOT_CG_EN_MASK \ + 0x00200000 /* QUP_ACL_SLOT_CG_EN[21] */ +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_QUP_ACL_SLOT_CG_EN_SHFT 21 +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_SRC_CNT_PRI_EN_ADDR \ + WF_HIF_DMASHDL_TOP_PAGE_SETTING_ADDR +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_SRC_CNT_PRI_EN_MASK \ + 0x00100000 /* SRC_CNT_PRI_EN[20] */ +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_SRC_CNT_PRI_EN_SHFT 20 +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_DUMMY_01_ADDR \ + WF_HIF_DMASHDL_TOP_PAGE_SETTING_ADDR +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_DUMMY_01_MASK \ + 0x00080000 /* DUMMY_01[19] */ +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_DUMMY_01_SHFT 19 +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_DUMMY_00_ADDR \ + WF_HIF_DMASHDL_TOP_PAGE_SETTING_ADDR +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_DUMMY_00_MASK \ + 0x00040000 /* DUMMY_00[18] */ +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_DUMMY_00_SHFT 18 +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_SLOT_TYPE_ARBITER_CONTROL_ADDR \ + WF_HIF_DMASHDL_TOP_PAGE_SETTING_ADDR +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_SLOT_TYPE_ARBITER_CONTROL_MASK \ + 0x00020000 /* SLOT_TYPE_ARBITER_CONTROL[17] */ +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_SLOT_TYPE_ARBITER_CONTROL_SHFT 17 +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_GROUP_SEQUENCE_ORDER_TYPE_ADDR \ + WF_HIF_DMASHDL_TOP_PAGE_SETTING_ADDR +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_GROUP_SEQUENCE_ORDER_TYPE_MASK \ + 0x00010000 /* GROUP_SEQUENCE_ORDER_TYPE[16] */ +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_GROUP_SEQUENCE_ORDER_TYPE_SHFT 16 +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_PP_OFFSET_ADD_ENA_ADDR \ + WF_HIF_DMASHDL_TOP_PAGE_SETTING_ADDR +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_PP_OFFSET_ADD_ENA_MASK \ + 0x00001000 /* PP_OFFSET_ADD_ENA[12] */ +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_PP_OFFSET_ADD_ENA_SHFT 12 +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_PSE_ADD_BSIZE_ADDR \ + WF_HIF_DMASHDL_TOP_PAGE_SETTING_ADDR +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_PSE_ADD_BSIZE_MASK \ + 0x000003FF /* PSE_ADD_BSIZE[9..0] */ +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_PSE_ADD_BSIZE_SHFT 0 + +/* +* ---REFILL_CONTROL (0x7C026000 + 0x10)--- +* GROUP0_REFILL_PRIORITY[0] - (RW) Group0 refill priority +* GROUP1_REFILL_PRIORITY[1] - (RW) Group1 refill priority +* GROUP2_REFILL_PRIORITY[2] - (RW) Group2 refill priority +* GROUP3_REFILL_PRIORITY[3] - (RW) Group3 refill priority +* GROUP4_REFILL_PRIORITY[4] - (RW) Group4 refill priority +* GROUP5_REFILL_PRIORITY[5] - (RW) Group5 refill priority +* GROUP6_REFILL_PRIORITY[6] - (RW) Group6 refill priority +* GROUP7_REFILL_PRIORITY[7] - (RW) Group7 refill priority +* GROUP8_REFILL_PRIORITY[8] - (RW) Group8 refill priority +* GROUP9_REFILL_PRIORITY[9] - (RW) Group9 refill priority +* GROUP10_REFILL_PRIORITY[10] - (RW) Group10 refill priority +* GROUP11_REFILL_PRIORITY[11] - (RW) Group11 refill priority +* GROUP12_REFILL_PRIORITY[12] - (RW) Group12 refill priority +* GROUP13_REFILL_PRIORITY[13] - (RW) Group13 refill priority +* GROUP14_REFILL_PRIORITY[14] - (RW) Group14 refill priority +* GROUP15_REFILL_PRIORITY[15] - (RW) Group15 refill priority +* GROUP0_REFILL_DISABLE[16] - (RW) Group0 refill control +* GROUP1_REFILL_DISABLE[17] - (RW) Group1 refill control +* GROUP2_REFILL_DISABLE[18] - (RW) Group2 refill control +* GROUP3_REFILL_DISABLE[19] - (RW) Group3 refill control +* GROUP4_REFILL_DISABLE[20] - (RW) Group4 refill control +* GROUP5_REFILL_DISABLE[21] - (RW) Group5 refill control +* GROUP6_REFILL_DISABLE[22] - (RW) Group6 refill control +* GROUP7_REFILL_DISABLE[23] - (RW) Group7 refill control +* GROUP8_REFILL_DISABLE[24] - (RW) Group8 refill control +* GROUP9_REFILL_DISABLE[25] - (RW) Group9 refill control +* GROUP10_REFILL_DISABLE[26] - (RW) Group10 refill control +* GROUP11_REFILL_DISABLE[27] - (RW) Group11 refill control +* GROUP12_REFILL_DISABLE[28] - (RW) Group12 refill control +* GROUP13_REFILL_DISABLE[29] - (RW) Group13 refill control +* GROUP14_REFILL_DISABLE[30] - (RW) Group14 refill control +* GROUP15_REFILL_DISABLE[31] - (RW) Group15 refill control +*/ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP15_REFILL_DISABLE_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP15_REFILL_DISABLE_MASK \ + 0x80000000 /* GROUP15_REFILL_DISABLE[31] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP15_REFILL_DISABLE_SHFT 31 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP14_REFILL_DISABLE_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP14_REFILL_DISABLE_MASK \ + 0x40000000 /* GROUP14_REFILL_DISABLE[30] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP14_REFILL_DISABLE_SHFT 30 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP13_REFILL_DISABLE_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP13_REFILL_DISABLE_MASK \ + 0x20000000 /* GROUP13_REFILL_DISABLE[29] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP13_REFILL_DISABLE_SHFT 29 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP12_REFILL_DISABLE_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP12_REFILL_DISABLE_MASK \ + 0x10000000 /* GROUP12_REFILL_DISABLE[28] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP12_REFILL_DISABLE_SHFT 28 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP11_REFILL_DISABLE_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP11_REFILL_DISABLE_MASK \ + 0x08000000 /* GROUP11_REFILL_DISABLE[27] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP11_REFILL_DISABLE_SHFT 27 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP10_REFILL_DISABLE_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP10_REFILL_DISABLE_MASK \ + 0x04000000 /* GROUP10_REFILL_DISABLE[26] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP10_REFILL_DISABLE_SHFT 26 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP9_REFILL_DISABLE_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP9_REFILL_DISABLE_MASK \ + 0x02000000 /* GROUP9_REFILL_DISABLE[25] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP9_REFILL_DISABLE_SHFT 25 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP8_REFILL_DISABLE_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP8_REFILL_DISABLE_MASK \ + 0x01000000 /* GROUP8_REFILL_DISABLE[24] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP8_REFILL_DISABLE_SHFT 24 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP7_REFILL_DISABLE_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP7_REFILL_DISABLE_MASK \ + 0x00800000 /* GROUP7_REFILL_DISABLE[23] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP7_REFILL_DISABLE_SHFT 23 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP6_REFILL_DISABLE_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP6_REFILL_DISABLE_MASK \ + 0x00400000 /* GROUP6_REFILL_DISABLE[22] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP6_REFILL_DISABLE_SHFT 22 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP5_REFILL_DISABLE_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP5_REFILL_DISABLE_MASK \ + 0x00200000 /* GROUP5_REFILL_DISABLE[21] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP5_REFILL_DISABLE_SHFT 21 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP4_REFILL_DISABLE_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP4_REFILL_DISABLE_MASK \ + 0x00100000 /* GROUP4_REFILL_DISABLE[20] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP4_REFILL_DISABLE_SHFT 20 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP3_REFILL_DISABLE_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP3_REFILL_DISABLE_MASK \ + 0x00080000 /* GROUP3_REFILL_DISABLE[19] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP3_REFILL_DISABLE_SHFT 19 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP2_REFILL_DISABLE_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP2_REFILL_DISABLE_MASK \ + 0x00040000 /* GROUP2_REFILL_DISABLE[18] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP2_REFILL_DISABLE_SHFT 18 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP1_REFILL_DISABLE_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP1_REFILL_DISABLE_MASK \ + 0x00020000 /* GROUP1_REFILL_DISABLE[17] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP1_REFILL_DISABLE_SHFT 17 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP0_REFILL_DISABLE_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP0_REFILL_DISABLE_MASK \ + 0x00010000 /* GROUP0_REFILL_DISABLE[16] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP0_REFILL_DISABLE_SHFT 16 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP15_REFILL_PRIORITY_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP15_REFILL_PRIORITY_MASK \ + 0x00008000 /* GROUP15_REFILL_PRIORITY[15] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP15_REFILL_PRIORITY_SHFT 15 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP14_REFILL_PRIORITY_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP14_REFILL_PRIORITY_MASK \ + 0x00004000 /* GROUP14_REFILL_PRIORITY[14] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP14_REFILL_PRIORITY_SHFT 14 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP13_REFILL_PRIORITY_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP13_REFILL_PRIORITY_MASK \ + 0x00002000 /* GROUP13_REFILL_PRIORITY[13] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP13_REFILL_PRIORITY_SHFT 13 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP12_REFILL_PRIORITY_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP12_REFILL_PRIORITY_MASK \ + 0x00001000 /* GROUP12_REFILL_PRIORITY[12] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP12_REFILL_PRIORITY_SHFT 12 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP11_REFILL_PRIORITY_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP11_REFILL_PRIORITY_MASK \ + 0x00000800 /* GROUP11_REFILL_PRIORITY[11] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP11_REFILL_PRIORITY_SHFT 11 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP10_REFILL_PRIORITY_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP10_REFILL_PRIORITY_MASK \ + 0x00000400 /* GROUP10_REFILL_PRIORITY[10] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP10_REFILL_PRIORITY_SHFT 10 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP9_REFILL_PRIORITY_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP9_REFILL_PRIORITY_MASK \ + 0x00000200 /* GROUP9_REFILL_PRIORITY[9] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP9_REFILL_PRIORITY_SHFT 9 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP8_REFILL_PRIORITY_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP8_REFILL_PRIORITY_MASK \ + 0x00000100 /* GROUP8_REFILL_PRIORITY[8] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP8_REFILL_PRIORITY_SHFT 8 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP7_REFILL_PRIORITY_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP7_REFILL_PRIORITY_MASK \ + 0x00000080 /* GROUP7_REFILL_PRIORITY[7] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP7_REFILL_PRIORITY_SHFT 7 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP6_REFILL_PRIORITY_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP6_REFILL_PRIORITY_MASK \ + 0x00000040 /* GROUP6_REFILL_PRIORITY[6] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP6_REFILL_PRIORITY_SHFT 6 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP5_REFILL_PRIORITY_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP5_REFILL_PRIORITY_MASK \ + 0x00000020 /* GROUP5_REFILL_PRIORITY[5] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP5_REFILL_PRIORITY_SHFT 5 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP4_REFILL_PRIORITY_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP4_REFILL_PRIORITY_MASK \ + 0x00000010 /* GROUP4_REFILL_PRIORITY[4] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP4_REFILL_PRIORITY_SHFT 4 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP3_REFILL_PRIORITY_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP3_REFILL_PRIORITY_MASK \ + 0x00000008 /* GROUP3_REFILL_PRIORITY[3] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP3_REFILL_PRIORITY_SHFT 3 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP2_REFILL_PRIORITY_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP2_REFILL_PRIORITY_MASK \ + 0x00000004 /* GROUP2_REFILL_PRIORITY[2] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP2_REFILL_PRIORITY_SHFT 2 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP1_REFILL_PRIORITY_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP1_REFILL_PRIORITY_MASK \ + 0x00000002 /* GROUP1_REFILL_PRIORITY[1] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP1_REFILL_PRIORITY_SHFT 1 +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP0_REFILL_PRIORITY_ADDR \ + WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP0_REFILL_PRIORITY_MASK \ + 0x00000001 /* GROUP0_REFILL_PRIORITY[0] */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP0_REFILL_PRIORITY_SHFT 0 + +/* +* ---TX_PACKET_SIZE_PAGE_MAP (0x7C026000 + 0x14)--- +* PACKET_SIZE_PAGE_MAP[7..0] - (RW) PSE Packet size page map +* 8'bxxxx_xxx1 : 32 bytes +* 8'bxxxx_xx10 : 64 bytes +* 8'bxxxx_x100 : 128 bytes +* 8'bxxxx_1000 : 256 bytes +* 8'bxxx1_0000 : 512 bytes +* 8'bxx10_0000 : 1024 bytes +* 8'bx100_0000 : 2048 bytes +* 8'b1000_0000 : 4096 bytes +* CR_PSE_LEN_MAP_SEL[8] - (RW) Enable pse packet length page mapping by +* CR Packet size page map or not +* RESERVED9[31..9] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_TX_PACKET_SIZE_PAGE_MAP_CR_PSE_LEN_MAP_SEL_ADDR \ + WF_HIF_DMASHDL_TOP_TX_PACKET_SIZE_PAGE_MAP_ADDR +#define WF_HIF_DMASHDL_TOP_TX_PACKET_SIZE_PAGE_MAP_CR_PSE_LEN_MAP_SEL_MASK \ + 0x00000100 /* CR_PSE_LEN_MAP_SEL[8] */ +#define WF_HIF_DMASHDL_TOP_TX_PACKET_SIZE_PAGE_MAP_CR_PSE_LEN_MAP_SEL_SHFT 8 +#define WF_HIF_DMASHDL_TOP_TX_PACKET_SIZE_PAGE_MAP_PACKET_SIZE_PAGE_MAP_ADDR \ + WF_HIF_DMASHDL_TOP_TX_PACKET_SIZE_PAGE_MAP_ADDR +#define WF_HIF_DMASHDL_TOP_TX_PACKET_SIZE_PAGE_MAP_PACKET_SIZE_PAGE_MAP_MASK \ + 0x000000FF /* PACKET_SIZE_PAGE_MAP[7..0] */ +#define WF_HIF_DMASHDL_TOP_TX_PACKET_SIZE_PAGE_MAP_PACKET_SIZE_PAGE_MAP_SHFT 0 + +/* +* ---CONTROL_SIGNAL (0x7C026000 + 0x18)--- +* CR_WACPU_MODE_EN[0] - (RW) Enable to WACPU mode for store forward +* packet to DLM +* RESERVED1[3..1] - (RO) Reserved bits +* WACPU_CMD_RET_PAGE_CNT[7..4] - (RW) WACPU mode, each packet in the CMD +* return the page count +* WACPU_TXD_RET_PAGE_CNT[11..8] - (RW) WACPU mode, each packet in the TXD +* return the page count +* WACPU_CMD_ASK_MAX_PAGE_CNT[15..12] - (RW) WACPU mode, CMD ask to require the +* maximum page count +* CR_HIF_ASK_SUB_ENA[16] - (RW) Enable packet in substration action from +* HIF ask period +* CR_PLE_SUB_ENA[17] - (RW) Enable packet in substration action from +PLE +* RESERVED18[19..18] - (RO) Reserved bits +* WACPU_TXD_ASK_MAX_PAGE_CNT[23..20] - (RW) WACPU mode, TXD ask to require the +* maximum page count +* WACPU_SUB_SRC_REFILL_ENA[24] - (RW) Enable terminate refill period when +* WACPU substrate source count to do refill action. +* WACPU_ADD_SRC_REFILL_ENA[25] - (RW) Enable terminate refill period when +* WACPU add source count to do refill action. +* WACPU_ADD_RES_REFILL_ENA[26] - (RW) Enable terminate refill period when +* WACPU add reserve count to do refill action. +* WACPU_RET_REFILL_ENA[27] - (RW) Enable terminate refill period when +* WACPU release packet to do refill action. +* RESERVED28[28] - (RO) Reserved bits +* CR_PLE_ADD_INT_REFILL_ENA[29] - (RW) Enable terminate refill period when PLE +* release packet to do addition. +* CR_PDMA_ADD_INT_REFILL_ENA[30] - (RW) Enable terminate refill period when +* packet in to do addition. +* CR_PKTIN_INT_REFILL_ENA[31] - (RW) Enable terminate refill period when +* packet in to do substration. +*/ +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_PKTIN_INT_REFILL_ENA_ADDR \ + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_PKTIN_INT_REFILL_ENA_MASK \ + 0x80000000 /* CR_PKTIN_INT_REFILL_ENA[31] */ +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_PKTIN_INT_REFILL_ENA_SHFT 31 +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_PDMA_ADD_INT_REFILL_ENA_ADDR \ + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_PDMA_ADD_INT_REFILL_ENA_MASK \ + 0x40000000 /* CR_PDMA_ADD_INT_REFILL_ENA[30] */ +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_PDMA_ADD_INT_REFILL_ENA_SHFT 30 +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_PLE_ADD_INT_REFILL_ENA_ADDR \ + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_PLE_ADD_INT_REFILL_ENA_MASK \ + 0x20000000 /* CR_PLE_ADD_INT_REFILL_ENA[29] */ +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_PLE_ADD_INT_REFILL_ENA_SHFT 29 +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_RET_REFILL_ENA_ADDR \ + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_RET_REFILL_ENA_MASK \ + 0x08000000 /* WACPU_RET_REFILL_ENA[27] */ +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_RET_REFILL_ENA_SHFT 27 +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_ADD_RES_REFILL_ENA_ADDR \ + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_ADD_RES_REFILL_ENA_MASK \ + 0x04000000 /* WACPU_ADD_RES_REFILL_ENA[26] */ +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_ADD_RES_REFILL_ENA_SHFT 26 +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_ADD_SRC_REFILL_ENA_ADDR \ + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_ADD_SRC_REFILL_ENA_MASK \ + 0x02000000 /* WACPU_ADD_SRC_REFILL_ENA[25] */ +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_ADD_SRC_REFILL_ENA_SHFT 25 +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_SUB_SRC_REFILL_ENA_ADDR \ + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_SUB_SRC_REFILL_ENA_MASK \ + 0x01000000 /* WACPU_SUB_SRC_REFILL_ENA[24] */ +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_SUB_SRC_REFILL_ENA_SHFT 24 +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_TXD_ASK_MAX_PAGE_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_TXD_ASK_MAX_PAGE_CNT_MASK \ + 0x00F00000 /* WACPU_TXD_ASK_MAX_PAGE_CNT[23..20] */ +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_TXD_ASK_MAX_PAGE_CNT_SHFT 20 +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_PLE_SUB_ENA_ADDR \ + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_PLE_SUB_ENA_MASK \ + 0x00020000 /* CR_PLE_SUB_ENA[17] */ +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_PLE_SUB_ENA_SHFT 17 +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_HIF_ASK_SUB_ENA_ADDR \ + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_HIF_ASK_SUB_ENA_MASK \ + 0x00010000 /* CR_HIF_ASK_SUB_ENA[16] */ +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_HIF_ASK_SUB_ENA_SHFT 16 +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_CMD_ASK_MAX_PAGE_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_CMD_ASK_MAX_PAGE_CNT_MASK \ + 0x0000F000 /* WACPU_CMD_ASK_MAX_PAGE_CNT[15..12] */ +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_CMD_ASK_MAX_PAGE_CNT_SHFT 12 +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_TXD_RET_PAGE_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_TXD_RET_PAGE_CNT_MASK \ + 0x00000F00 /* WACPU_TXD_RET_PAGE_CNT[11..8] */ +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_TXD_RET_PAGE_CNT_SHFT 8 +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_CMD_RET_PAGE_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_CMD_RET_PAGE_CNT_MASK \ + 0x000000F0 /* WACPU_CMD_RET_PAGE_CNT[7..4] */ +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_WACPU_CMD_RET_PAGE_CNT_SHFT 4 +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_WACPU_MODE_EN_ADDR \ + WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_WACPU_MODE_EN_MASK \ + 0x00000001 /* CR_WACPU_MODE_EN[0] */ +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_WACPU_MODE_EN_SHFT 0 + +/* +* ---PACKET_MAX_SIZE (0x7C026000 + 0x1c)--- +* PLE_PACKET_MAX_SIZE[11..0] - (RW) PLE packet maximum page size (group 0 ~ +11) +* RESERVED12[15..12] - (RO) Reserved bits +* PSE_PACKET_MAX_SIZE[27..16] - (RW) PSE packet maximum page size (group 15) +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_PSE_PACKET_MAX_SIZE_ADDR \ + WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_ADDR +#define WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_PSE_PACKET_MAX_SIZE_MASK \ + 0x0FFF0000 /* PSE_PACKET_MAX_SIZE[27..16] */ +#define WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_PSE_PACKET_MAX_SIZE_SHFT 16 +#define WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_PLE_PACKET_MAX_SIZE_ADDR \ + WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_ADDR +#define WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_PLE_PACKET_MAX_SIZE_MASK \ + 0x00000FFF /* PLE_PACKET_MAX_SIZE[11..0] */ +#define WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_PLE_PACKET_MAX_SIZE_SHFT 0 + +/* +* ---GROUP0_CONTROL (0x7C026000 + 0x20)--- +* GROUP0_MIN_QUOTA[11..0] - (RW) Group0 Minimum Quota +* RESERVED12[15..12] - (RO) Reserved bits +* GROUP0_MAX_QUOTA[27..16] - (RW) Group0 Maximum Quota +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_GROUP0_MAX_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_GROUP0_MAX_QUOTA_MASK \ + 0x0FFF0000 /* GROUP0_MAX_QUOTA[27..16] */ +#define WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_GROUP0_MAX_QUOTA_SHFT 16 +#define WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_GROUP0_MIN_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_GROUP0_MIN_QUOTA_MASK \ + 0x00000FFF /* GROUP0_MIN_QUOTA[11..0] */ +#define WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_GROUP0_MIN_QUOTA_SHFT 0 + +/* +* ---GROUP1_CONTROL (0x7C026000 + 0x24)--- +* GROUP1_MIN_QUOTA[11..0] - (RW) Group1 Minimum Quota +* RESERVED12[15..12] - (RO) Reserved bits +* GROUP1_MAX_QUOTA[27..16] - (RW) Group1 Maximum Quota +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_GROUP1_CONTROL_GROUP1_MAX_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP1_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP1_CONTROL_GROUP1_MAX_QUOTA_MASK \ + 0x0FFF0000 /* GROUP1_MAX_QUOTA[27..16] */ +#define WF_HIF_DMASHDL_TOP_GROUP1_CONTROL_GROUP1_MAX_QUOTA_SHFT 16 +#define WF_HIF_DMASHDL_TOP_GROUP1_CONTROL_GROUP1_MIN_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP1_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP1_CONTROL_GROUP1_MIN_QUOTA_MASK \ + 0x00000FFF /* GROUP1_MIN_QUOTA[11..0] */ +#define WF_HIF_DMASHDL_TOP_GROUP1_CONTROL_GROUP1_MIN_QUOTA_SHFT 0 + +/* +* ---GROUP2_CONTROL (0x7C026000 + 0x28)--- +* GROUP2_MIN_QUOTA[11..0] - (RW) Group2 Minimum Quota +* RESERVED12[15..12] - (RO) Reserved bits +* GROUP2_MAX_QUOTA[27..16] - (RW) Group2 Maximum Quota +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_GROUP2_CONTROL_GROUP2_MAX_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP2_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP2_CONTROL_GROUP2_MAX_QUOTA_MASK \ + 0x0FFF0000 /* GROUP2_MAX_QUOTA[27..16] */ +#define WF_HIF_DMASHDL_TOP_GROUP2_CONTROL_GROUP2_MAX_QUOTA_SHFT 16 +#define WF_HIF_DMASHDL_TOP_GROUP2_CONTROL_GROUP2_MIN_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP2_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP2_CONTROL_GROUP2_MIN_QUOTA_MASK \ + 0x00000FFF /* GROUP2_MIN_QUOTA[11..0] */ +#define WF_HIF_DMASHDL_TOP_GROUP2_CONTROL_GROUP2_MIN_QUOTA_SHFT 0 + +/* +* ---GROUP3_CONTROL (0x7C026000 + 0x2C)--- +* GROUP3_MIN_QUOTA[11..0] - (RW) Group3 Minimum Quota +* RESERVED12[15..12] - (RO) Reserved bits +* GROUP3_MAX_QUOTA[27..16] - (RW) Group3 Maximum Quota +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_GROUP3_CONTROL_GROUP3_MAX_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP3_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP3_CONTROL_GROUP3_MAX_QUOTA_MASK \ + 0x0FFF0000 /* GROUP3_MAX_QUOTA[27..16] */ +#define WF_HIF_DMASHDL_TOP_GROUP3_CONTROL_GROUP3_MAX_QUOTA_SHFT 16 +#define WF_HIF_DMASHDL_TOP_GROUP3_CONTROL_GROUP3_MIN_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP3_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP3_CONTROL_GROUP3_MIN_QUOTA_MASK \ + 0x00000FFF /* GROUP3_MIN_QUOTA[11..0] */ +#define WF_HIF_DMASHDL_TOP_GROUP3_CONTROL_GROUP3_MIN_QUOTA_SHFT 0 + +/* +* ---GROUP4_CONTROL (0x7C026000 + 0x30)--- +* GROUP4_MIN_QUOTA[11..0] - (RW) Group4 Minimum Quota +* RESERVED12[15..12] - (RO) Reserved bits +* GROUP4_MAX_QUOTA[27..16] - (RW) Group4 Maximum Quota +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_GROUP4_CONTROL_GROUP4_MAX_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP4_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP4_CONTROL_GROUP4_MAX_QUOTA_MASK \ + 0x0FFF0000 /* GROUP4_MAX_QUOTA[27..16] */ +#define WF_HIF_DMASHDL_TOP_GROUP4_CONTROL_GROUP4_MAX_QUOTA_SHFT 16 +#define WF_HIF_DMASHDL_TOP_GROUP4_CONTROL_GROUP4_MIN_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP4_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP4_CONTROL_GROUP4_MIN_QUOTA_MASK \ + 0x00000FFF /* GROUP4_MIN_QUOTA[11..0] */ +#define WF_HIF_DMASHDL_TOP_GROUP4_CONTROL_GROUP4_MIN_QUOTA_SHFT 0 + +/* +* ---GROUP5_CONTROL (0x7C026000 + 0x34)--- +* GROUP5_MIN_QUOTA[11..0] - (RW) Group5 Minimum Quota +* RESERVED12[15..12] - (RO) Reserved bits +* GROUP5_MAX_QUOTA[27..16] - (RW) Group5 Maximum Quota +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_GROUP5_CONTROL_GROUP5_MAX_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP5_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP5_CONTROL_GROUP5_MAX_QUOTA_MASK \ + 0x0FFF0000 /* GROUP5_MAX_QUOTA[27..16] */ +#define WF_HIF_DMASHDL_TOP_GROUP5_CONTROL_GROUP5_MAX_QUOTA_SHFT 16 +#define WF_HIF_DMASHDL_TOP_GROUP5_CONTROL_GROUP5_MIN_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP5_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP5_CONTROL_GROUP5_MIN_QUOTA_MASK \ + 0x00000FFF /* GROUP5_MIN_QUOTA[11..0] */ +#define WF_HIF_DMASHDL_TOP_GROUP5_CONTROL_GROUP5_MIN_QUOTA_SHFT 0 + +/* +* ---GROUP6_CONTROL (0x7C026000 + 0x38)--- +* GROUP6_MIN_QUOTA[11..0] - (RW) Group6 Minimum Quota +* RESERVED12[15..12] - (RO) Reserved bits +* GROUP6_MAX_QUOTA[27..16] - (RW) Group6 Maximum Quota +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_GROUP6_CONTROL_GROUP6_MAX_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP6_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP6_CONTROL_GROUP6_MAX_QUOTA_MASK \ + 0x0FFF0000 /* GROUP6_MAX_QUOTA[27..16] */ +#define WF_HIF_DMASHDL_TOP_GROUP6_CONTROL_GROUP6_MAX_QUOTA_SHFT 16 +#define WF_HIF_DMASHDL_TOP_GROUP6_CONTROL_GROUP6_MIN_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP6_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP6_CONTROL_GROUP6_MIN_QUOTA_MASK \ + 0x00000FFF /* GROUP6_MIN_QUOTA[11..0] */ +#define WF_HIF_DMASHDL_TOP_GROUP6_CONTROL_GROUP6_MIN_QUOTA_SHFT 0 + +/* +* ---GROUP7_CONTROL (0x7C026000 + 0x3C)--- +* GROUP7_MIN_QUOTA[11..0] - (RW) Group7 Minimum Quota +* RESERVED12[15..12] - (RO) Reserved bits +* GROUP7_MAX_QUOTA[27..16] - (RW) Group7 Maximum Quota +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_GROUP7_CONTROL_GROUP7_MAX_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP7_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP7_CONTROL_GROUP7_MAX_QUOTA_MASK \ + 0x0FFF0000 /* GROUP7_MAX_QUOTA[27..16] */ +#define WF_HIF_DMASHDL_TOP_GROUP7_CONTROL_GROUP7_MAX_QUOTA_SHFT 16 +#define WF_HIF_DMASHDL_TOP_GROUP7_CONTROL_GROUP7_MIN_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP7_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP7_CONTROL_GROUP7_MIN_QUOTA_MASK \ + 0x00000FFF /* GROUP7_MIN_QUOTA[11..0] */ +#define WF_HIF_DMASHDL_TOP_GROUP7_CONTROL_GROUP7_MIN_QUOTA_SHFT 0 + +/* +* ---GROUP8_CONTROL (0x7C026000 + 0x40)--- +* GROUP8_MIN_QUOTA[11..0] - (RW) Group8 Minimum Quota +* RESERVED12[15..12] - (RO) Reserved bits +* GROUP8_MAX_QUOTA[27..16] - (RW) Group8 Maximum Quota +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_GROUP8_CONTROL_GROUP8_MAX_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP8_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP8_CONTROL_GROUP8_MAX_QUOTA_MASK \ + 0x0FFF0000 /* GROUP8_MAX_QUOTA[27..16] */ +#define WF_HIF_DMASHDL_TOP_GROUP8_CONTROL_GROUP8_MAX_QUOTA_SHFT 16 +#define WF_HIF_DMASHDL_TOP_GROUP8_CONTROL_GROUP8_MIN_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP8_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP8_CONTROL_GROUP8_MIN_QUOTA_MASK \ + 0x00000FFF /* GROUP8_MIN_QUOTA[11..0] */ +#define WF_HIF_DMASHDL_TOP_GROUP8_CONTROL_GROUP8_MIN_QUOTA_SHFT 0 + +/* +* ---GROUP9_CONTROL (0x7C026000 + 0x44)--- +* GROUP9_MIN_QUOTA[11..0] - (RW) Group9 Minimum Quota +* RESERVED12[15..12] - (RO) Reserved bits +* GROUP9_MAX_QUOTA[27..16] - (RW) Group9 Maximum Quota +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_GROUP9_CONTROL_GROUP9_MAX_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP9_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP9_CONTROL_GROUP9_MAX_QUOTA_MASK \ + 0x0FFF0000 /* GROUP9_MAX_QUOTA[27..16] */ +#define WF_HIF_DMASHDL_TOP_GROUP9_CONTROL_GROUP9_MAX_QUOTA_SHFT 16 +#define WF_HIF_DMASHDL_TOP_GROUP9_CONTROL_GROUP9_MIN_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP9_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP9_CONTROL_GROUP9_MIN_QUOTA_MASK \ + 0x00000FFF /* GROUP9_MIN_QUOTA[11..0] */ +#define WF_HIF_DMASHDL_TOP_GROUP9_CONTROL_GROUP9_MIN_QUOTA_SHFT 0 + +/* +* ---GROUP10_CONTROL (0x7C026000 + 0x48)--- +* GROUP10_MIN_QUOTA[11..0] - (RW) Group10 Minimum Quota +* RESERVED12[15..12] - (RO) Reserved bits +* GROUP10_MAX_QUOTA[27..16] - (RW) Group10 Maximum Quota +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_GROUP10_CONTROL_GROUP10_MAX_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP10_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP10_CONTROL_GROUP10_MAX_QUOTA_MASK \ + 0x0FFF0000 /* GROUP10_MAX_QUOTA[27..16] */ +#define WF_HIF_DMASHDL_TOP_GROUP10_CONTROL_GROUP10_MAX_QUOTA_SHFT 16 +#define WF_HIF_DMASHDL_TOP_GROUP10_CONTROL_GROUP10_MIN_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP10_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP10_CONTROL_GROUP10_MIN_QUOTA_MASK \ + 0x00000FFF /* GROUP10_MIN_QUOTA[11..0] */ +#define WF_HIF_DMASHDL_TOP_GROUP10_CONTROL_GROUP10_MIN_QUOTA_SHFT 0 + +/* +* ---GROUP11_CONTROL (0x7C026000 + 0x4C)--- +* GROUP11_MIN_QUOTA[11..0] - (RW) Group11 Minimum Quota +* RESERVED12[15..12] - (RO) Reserved bits +* GROUP11_MAX_QUOTA[27..16] - (RW) Group11 Maximum Quota +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_GROUP11_CONTROL_GROUP11_MAX_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP11_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP11_CONTROL_GROUP11_MAX_QUOTA_MASK \ + 0x0FFF0000 /* GROUP11_MAX_QUOTA[27..16] */ +#define WF_HIF_DMASHDL_TOP_GROUP11_CONTROL_GROUP11_MAX_QUOTA_SHFT 16 +#define WF_HIF_DMASHDL_TOP_GROUP11_CONTROL_GROUP11_MIN_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP11_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP11_CONTROL_GROUP11_MIN_QUOTA_MASK \ + 0x00000FFF /* GROUP11_MIN_QUOTA[11..0] */ +#define WF_HIF_DMASHDL_TOP_GROUP11_CONTROL_GROUP11_MIN_QUOTA_SHFT 0 + +/* +* ---GROUP12_CONTROL (0x7C026000 + 0x50)--- +* GROUP12_MIN_QUOTA[11..0] - (RW) Group12 Minimum Quota +* RESERVED12[15..12] - (RO) Reserved bits +* GROUP12_MAX_QUOTA[27..16] - (RW) Group12 Maximum Quota +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_GROUP12_CONTROL_GROUP12_MAX_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP12_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP12_CONTROL_GROUP12_MAX_QUOTA_MASK \ + 0x0FFF0000 /* GROUP12_MAX_QUOTA[27..16] */ +#define WF_HIF_DMASHDL_TOP_GROUP12_CONTROL_GROUP12_MAX_QUOTA_SHFT 16 +#define WF_HIF_DMASHDL_TOP_GROUP12_CONTROL_GROUP12_MIN_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP12_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP12_CONTROL_GROUP12_MIN_QUOTA_MASK \ + 0x00000FFF /* GROUP12_MIN_QUOTA[11..0] */ +#define WF_HIF_DMASHDL_TOP_GROUP12_CONTROL_GROUP12_MIN_QUOTA_SHFT 0 + +/* +* ---GROUP13_CONTROL (0x7C026000 + 0x54)--- +* GROUP13_MIN_QUOTA[11..0] - (RW) Group13 Minimum Quota +* RESERVED12[15..12] - (RO) Reserved bits +* GROUP13_MAX_QUOTA[27..16] - (RW) Group13 Maximum Quota +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_GROUP13_CONTROL_GROUP13_MAX_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP13_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP13_CONTROL_GROUP13_MAX_QUOTA_MASK \ + 0x0FFF0000 /* GROUP13_MAX_QUOTA[27..16] */ +#define WF_HIF_DMASHDL_TOP_GROUP13_CONTROL_GROUP13_MAX_QUOTA_SHFT 16 +#define WF_HIF_DMASHDL_TOP_GROUP13_CONTROL_GROUP13_MIN_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP13_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP13_CONTROL_GROUP13_MIN_QUOTA_MASK \ + 0x00000FFF /* GROUP13_MIN_QUOTA[11..0] */ +#define WF_HIF_DMASHDL_TOP_GROUP13_CONTROL_GROUP13_MIN_QUOTA_SHFT 0 + +/* +* ---GROUP14_CONTROL (0x7C026000 + 0x58)--- +* GROUP14_MIN_QUOTA[11..0] - (RW) Group14 Minimum Quota +* RESERVED12[15..12] - (RO) Reserved bits +* GROUP14_MAX_QUOTA[27..16] - (RW) Group14 Maximum Quota +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_GROUP14_CONTROL_GROUP14_MAX_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP14_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP14_CONTROL_GROUP14_MAX_QUOTA_MASK \ + 0x0FFF0000 /* GROUP14_MAX_QUOTA[27..16] */ +#define WF_HIF_DMASHDL_TOP_GROUP14_CONTROL_GROUP14_MAX_QUOTA_SHFT 16 +#define WF_HIF_DMASHDL_TOP_GROUP14_CONTROL_GROUP14_MIN_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP14_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP14_CONTROL_GROUP14_MIN_QUOTA_MASK \ + 0x00000FFF /* GROUP14_MIN_QUOTA[11..0] */ +#define WF_HIF_DMASHDL_TOP_GROUP14_CONTROL_GROUP14_MIN_QUOTA_SHFT 0 + +/* +* ---GROUP15_CONTROL (0x7C026000 + 0x5C)--- +* GROUP15_MIN_QUOTA[11..0] - (RW) Group15 Minimum Quota +* RESERVED12[15..12] - (RO) Reserved bits +* GROUP15_MAX_QUOTA[27..16] - (RW) Group15 Maximum Quota +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_GROUP15_CONTROL_GROUP15_MAX_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP15_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP15_CONTROL_GROUP15_MAX_QUOTA_MASK \ + 0x0FFF0000 /* GROUP15_MAX_QUOTA[27..16] */ +#define WF_HIF_DMASHDL_TOP_GROUP15_CONTROL_GROUP15_MAX_QUOTA_SHFT 16 +#define WF_HIF_DMASHDL_TOP_GROUP15_CONTROL_GROUP15_MIN_QUOTA_ADDR \ + WF_HIF_DMASHDL_TOP_GROUP15_CONTROL_ADDR +#define WF_HIF_DMASHDL_TOP_GROUP15_CONTROL_GROUP15_MIN_QUOTA_MASK \ + 0x00000FFF /* GROUP15_MIN_QUOTA[11..0] */ +#define WF_HIF_DMASHDL_TOP_GROUP15_CONTROL_GROUP15_MIN_QUOTA_SHFT 0 + +/* +* ---STATUS_RD0 (0x7C026000 + 0x70)--- +* PLE_TXD_QID_MAX2_NZERO_CNT[3..0] - (RO) Number of TXD QID[6:5] not equal +* zero counter from PLE return. +* HOST_TXD_QID_MAX2_NZERO_CNT[7..4] - (RO) Number of TXD QID[6:5] not equal +* zero counter from host send. +* CURR_TXD_CTXD_FLAG[8] - (RO) Current TXD is cascade TXD format or not +* RESERVED9[31..9] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_STATUS_RD0_CURR_TXD_CTXD_FLAG_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD0_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD0_CURR_TXD_CTXD_FLAG_MASK \ + 0x00000100 /* CURR_TXD_CTXD_FLAG[8] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD0_CURR_TXD_CTXD_FLAG_SHFT 8 +#define WF_HIF_DMASHDL_TOP_STATUS_RD0_HOST_TXD_QID_MAX2_NZERO_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD0_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD0_HOST_TXD_QID_MAX2_NZERO_CNT_MASK \ + 0x000000F0 /* HOST_TXD_QID_MAX2_NZERO_CNT[7..4] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD0_HOST_TXD_QID_MAX2_NZERO_CNT_SHFT 4 +#define WF_HIF_DMASHDL_TOP_STATUS_RD0_PLE_TXD_QID_MAX2_NZERO_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD0_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD0_PLE_TXD_QID_MAX2_NZERO_CNT_MASK \ + 0x0000000F /* PLE_TXD_QID_MAX2_NZERO_CNT[3..0] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD0_PLE_TXD_QID_MAX2_NZERO_CNT_SHFT 0 + +/* +* ---DEBUG_PORT00 (0x7C026000 + 0x80)--- +* DEBUG_N0_SEL[0] - (RW) Debug port n0 enable +* DEBUG_N1_SEL[1] - (RW) Debug port n1 enable +* DEBUG_N2_SEL[2] - (RW) Debug port n2 enable +* DEBUG_N3_SEL[3] - (RW) Debug port n3 enable +* RESERVED4[31..4] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT00_DEBUG_N3_SEL_ADDR \ + WF_HIF_DMASHDL_TOP_DEBUG_PORT00_ADDR +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT00_DEBUG_N3_SEL_MASK \ + 0x00000008 /* DEBUG_N3_SEL[3] */ +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT00_DEBUG_N3_SEL_SHFT 3 +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT00_DEBUG_N2_SEL_ADDR \ + WF_HIF_DMASHDL_TOP_DEBUG_PORT00_ADDR +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT00_DEBUG_N2_SEL_MASK \ + 0x00000004 /* DEBUG_N2_SEL[2] */ +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT00_DEBUG_N2_SEL_SHFT 2 +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT00_DEBUG_N1_SEL_ADDR \ + WF_HIF_DMASHDL_TOP_DEBUG_PORT00_ADDR +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT00_DEBUG_N1_SEL_MASK \ + 0x00000002 /* DEBUG_N1_SEL[1] */ +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT00_DEBUG_N1_SEL_SHFT 1 +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT00_DEBUG_N0_SEL_ADDR \ + WF_HIF_DMASHDL_TOP_DEBUG_PORT00_ADDR +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT00_DEBUG_N0_SEL_MASK \ + 0x00000001 /* DEBUG_N0_SEL[0] */ +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT00_DEBUG_N0_SEL_SHFT 0 + +/* +* ---DEBUG_PORT01 (0x7C026000 + 0x84)--- +* DEBUG_FLAG_N0_SEL[7..0] - (RW) Debug port n0 select +* DEBUG_FLAG_N1_SEL[15..8] - (RW) Debug port n1 select +* DEBUG_FLAG_N2_SEL[23..16] - (RW) Debug port n2 select +* DEBUG_FLAG_N3_SEL[31..24] - (RW) Debug port n3 select +*/ +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT01_DEBUG_FLAG_N3_SEL_ADDR \ + WF_HIF_DMASHDL_TOP_DEBUG_PORT01_ADDR +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT01_DEBUG_FLAG_N3_SEL_MASK \ + 0xFF000000 /* DEBUG_FLAG_N3_SEL[31..24] */ +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT01_DEBUG_FLAG_N3_SEL_SHFT 24 +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT01_DEBUG_FLAG_N2_SEL_ADDR \ + WF_HIF_DMASHDL_TOP_DEBUG_PORT01_ADDR +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT01_DEBUG_FLAG_N2_SEL_MASK \ + 0x00FF0000 /* DEBUG_FLAG_N2_SEL[23..16] */ +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT01_DEBUG_FLAG_N2_SEL_SHFT 16 +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT01_DEBUG_FLAG_N1_SEL_ADDR \ + WF_HIF_DMASHDL_TOP_DEBUG_PORT01_ADDR +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT01_DEBUG_FLAG_N1_SEL_MASK \ + 0x0000FF00 /* DEBUG_FLAG_N1_SEL[15..8] */ +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT01_DEBUG_FLAG_N1_SEL_SHFT 8 +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT01_DEBUG_FLAG_N0_SEL_ADDR \ + WF_HIF_DMASHDL_TOP_DEBUG_PORT01_ADDR +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT01_DEBUG_FLAG_N0_SEL_MASK \ + 0x000000FF /* DEBUG_FLAG_N0_SEL[7..0] */ +#define WF_HIF_DMASHDL_TOP_DEBUG_PORT01_DEBUG_FLAG_N0_SEL_SHFT 0 + +/* +* ---STATUS_RD02 (0x7C026000 + 0x88)--- +* REFILL_CS[3..0] - (RO) Refill state machine for current state +* REFILL_NS[7..4] - (RO) Refill state machine for next state +* DMASHDL_CS[10..8] - (RO) DMASHDL state machine for current state +* RESERVED11[11] - (RO) Reserved bits +* DMASHDL_NS[14..12] - (RO) DMASHDL state machine for next state +* RESERVED15[15] - (RO) Reserved bits +* HIF_DMASHDL_DEBUG_PORT[31..16] - (RO) DMASHDL debug port signals +*/ +#define WF_HIF_DMASHDL_TOP_STATUS_RD02_HIF_DMASHDL_DEBUG_PORT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD02_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD02_HIF_DMASHDL_DEBUG_PORT_MASK \ + 0xFFFF0000 /* HIF_DMASHDL_DEBUG_PORT[31..16] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD02_HIF_DMASHDL_DEBUG_PORT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_STATUS_RD02_DMASHDL_NS_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD02_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD02_DMASHDL_NS_MASK \ + 0x00007000 /* DMASHDL_NS[14..12] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD02_DMASHDL_NS_SHFT 12 +#define WF_HIF_DMASHDL_TOP_STATUS_RD02_DMASHDL_CS_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD02_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD02_DMASHDL_CS_MASK \ + 0x00000700 /* DMASHDL_CS[10..8] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD02_DMASHDL_CS_SHFT 8 +#define WF_HIF_DMASHDL_TOP_STATUS_RD02_REFILL_NS_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD02_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD02_REFILL_NS_MASK \ + 0x000000F0 /* REFILL_NS[7..4] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD02_REFILL_NS_SHFT 4 +#define WF_HIF_DMASHDL_TOP_STATUS_RD02_REFILL_CS_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD02_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD02_REFILL_CS_MASK \ + 0x0000000F /* REFILL_CS[3..0] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD02_REFILL_CS_SHFT 0 + +/* +* ---COUNTER_UDF_CLR (0x7C026000 + 0x8C)--- +* FREEPG_CNT_UDF_CLR[0] - (RW) Clear freepage count underflow flag +* FFA_CNT_UDF_CLR[1] - (RW) Clear FFA count underflow flag +* SRC_SUB_CUR_UDF_CLR[2] - (RW) Clear PLE return stage source count +* underflow flag +* REFILL_MAX1_UDF_CLR[3] - (RW) Clear pktin return stage source count +* underflow flag +* REFILL_MAX0_UDF_CLR[4] - (RW) Clear RSV add SRC count greater than +* maximum quota +* RSV_SUB_CURR_UDF_CLR[5] - (RW) Clear reservation count underflow flag +* PLE_TXD_GT_MAX_SIZE_FLAG_CLR[6] - (RW) Clear PLE TXD size greater than max +* PLE TXD size flag +* PSE_SIZE_GT_MAX_SIZE_FLAG_CLR[7] - (RW) Clear PSE packet size greater than +* max packet size flag +* HIF_ASK_LONG_FLAG_CLR[8] - (RW) Clear the HIF ask after long time period +* to grant flag +* PSE_RSV_UDF_CLR[9] - (RW) Clear the HIF ask to let reservation +* count underflow flag +* PSE_SRC_PSERET_UDF_CLR[10] - (RW) Clear the PSE source count PSE module +* return underflow flag +* PSE_SRC_PKTRET_UDF_CLR[11] - (RW) Clear the PSE source count packet in +* return underflow flag +* RESERVED12[15..12] - (RO) Reserved bits +* HIF_ASK_PKTIN_CNT_CLR[16] - (RW) Clear the ask counters and pktin return +* counters for all groups +* RESERVED17[31..17] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_HIF_ASK_PKTIN_CNT_CLR_ADDR \ + WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_ADDR +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_HIF_ASK_PKTIN_CNT_CLR_MASK \ + 0x00010000 /* HIF_ASK_PKTIN_CNT_CLR[16] */ +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_HIF_ASK_PKTIN_CNT_CLR_SHFT 16 +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_PSE_SRC_PKTRET_UDF_CLR_ADDR \ + WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_ADDR +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_PSE_SRC_PKTRET_UDF_CLR_MASK \ + 0x00000800 /* PSE_SRC_PKTRET_UDF_CLR[11] */ +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_PSE_SRC_PKTRET_UDF_CLR_SHFT 11 +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_PSE_SRC_PSERET_UDF_CLR_ADDR \ + WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_ADDR +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_PSE_SRC_PSERET_UDF_CLR_MASK \ + 0x00000400 /* PSE_SRC_PSERET_UDF_CLR[10] */ +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_PSE_SRC_PSERET_UDF_CLR_SHFT 10 +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_PSE_RSV_UDF_CLR_ADDR \ + WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_ADDR +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_PSE_RSV_UDF_CLR_MASK \ + 0x00000200 /* PSE_RSV_UDF_CLR[9] */ +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_PSE_RSV_UDF_CLR_SHFT 9 +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_HIF_ASK_LONG_FLAG_CLR_ADDR \ + WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_ADDR +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_HIF_ASK_LONG_FLAG_CLR_MASK \ + 0x00000100 /* HIF_ASK_LONG_FLAG_CLR[8] */ +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_HIF_ASK_LONG_FLAG_CLR_SHFT 8 +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_PSE_SIZE_GT_MAX_SIZE_FLAG_CLR_ADDR \ + WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_ADDR +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_PSE_SIZE_GT_MAX_SIZE_FLAG_CLR_MASK \ + 0x00000080 /* PSE_SIZE_GT_MAX_SIZE_FLAG_CLR[7] */ +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_PSE_SIZE_GT_MAX_SIZE_FLAG_CLR_SHFT 7 +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_PLE_TXD_GT_MAX_SIZE_FLAG_CLR_ADDR \ + WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_ADDR +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_PLE_TXD_GT_MAX_SIZE_FLAG_CLR_MASK \ + 0x00000040 /* PLE_TXD_GT_MAX_SIZE_FLAG_CLR[6] */ +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_PLE_TXD_GT_MAX_SIZE_FLAG_CLR_SHFT 6 +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_RSV_SUB_CURR_UDF_CLR_ADDR \ + WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_ADDR +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_RSV_SUB_CURR_UDF_CLR_MASK \ + 0x00000020 /* RSV_SUB_CURR_UDF_CLR[5] */ +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_RSV_SUB_CURR_UDF_CLR_SHFT 5 +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_REFILL_MAX0_UDF_CLR_ADDR \ + WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_ADDR +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_REFILL_MAX0_UDF_CLR_MASK \ + 0x00000010 /* REFILL_MAX0_UDF_CLR[4] */ +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_REFILL_MAX0_UDF_CLR_SHFT 4 +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_REFILL_MAX1_UDF_CLR_ADDR \ + WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_ADDR +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_REFILL_MAX1_UDF_CLR_MASK \ + 0x00000008 /* REFILL_MAX1_UDF_CLR[3] */ +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_REFILL_MAX1_UDF_CLR_SHFT 3 +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_SRC_SUB_CUR_UDF_CLR_ADDR \ + WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_ADDR +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_SRC_SUB_CUR_UDF_CLR_MASK \ + 0x00000004 /* SRC_SUB_CUR_UDF_CLR[2] */ +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_SRC_SUB_CUR_UDF_CLR_SHFT 2 +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_FFA_CNT_UDF_CLR_ADDR \ + WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_ADDR +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_FFA_CNT_UDF_CLR_MASK \ + 0x00000002 /* FFA_CNT_UDF_CLR[1] */ +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_FFA_CNT_UDF_CLR_SHFT 1 +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_FREEPG_CNT_UDF_CLR_ADDR \ + WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_ADDR +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_FREEPG_CNT_UDF_CLR_MASK \ + 0x00000001 /* FREEPG_CNT_UDF_CLR[0] */ +#define WF_HIF_DMASHDL_TOP_COUNTER_UDF_CLR_FREEPG_CNT_UDF_CLR_SHFT 0 + +/* +* ---PKT_IN_CNT_CTRL (0x7C026000 + 0x90)--- +* CNT1_RET_CNT_ENA[0] - (RW) Counter1 PLE/PSE return count enable +* CNT1_PKTIN_RET_CNT_ENA[1] - (RW) Counter1 pktin return count enable +* CNT1_PKTIN_CNT_ENA[2] - (RW) Counter1 pktin(ask) substrate count +enable +* CNT0_RET_CNT_ENA[3] - (RW) Counter0 PLE/PSE return count enable +* CNT0_PKTIN_RET_CNT_ENA[4] - (RW) Counter0 pktin return count enable +* CNT0_PKTIN_CNT_ENA[5] - (RW) Counter0 pktin(ask) substrate count +enable +* RESERVED6[31..6] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_CNT0_PKTIN_CNT_ENA_ADDR \ + WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_ADDR +#define WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_CNT0_PKTIN_CNT_ENA_MASK \ + 0x00000020 /* CNT0_PKTIN_CNT_ENA[5] */ +#define WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_CNT0_PKTIN_CNT_ENA_SHFT 5 +#define WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_CNT0_PKTIN_RET_CNT_ENA_ADDR \ + WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_ADDR +#define WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_CNT0_PKTIN_RET_CNT_ENA_MASK \ + 0x00000010 /* CNT0_PKTIN_RET_CNT_ENA[4] */ +#define WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_CNT0_PKTIN_RET_CNT_ENA_SHFT 4 +#define WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_CNT0_RET_CNT_ENA_ADDR \ + WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_ADDR +#define WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_CNT0_RET_CNT_ENA_MASK \ + 0x00000008 /* CNT0_RET_CNT_ENA[3] */ +#define WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_CNT0_RET_CNT_ENA_SHFT 3 +#define WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_CNT1_PKTIN_CNT_ENA_ADDR \ + WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_ADDR +#define WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_CNT1_PKTIN_CNT_ENA_MASK \ + 0x00000004 /* CNT1_PKTIN_CNT_ENA[2] */ +#define WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_CNT1_PKTIN_CNT_ENA_SHFT 2 +#define WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_CNT1_PKTIN_RET_CNT_ENA_ADDR \ + WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_ADDR +#define WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_CNT1_PKTIN_RET_CNT_ENA_MASK \ + 0x00000002 /* CNT1_PKTIN_RET_CNT_ENA[1] */ +#define WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_CNT1_PKTIN_RET_CNT_ENA_SHFT 1 +#define WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_CNT1_RET_CNT_ENA_ADDR \ + WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_ADDR +#define WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_CNT1_RET_CNT_ENA_MASK \ + 0x00000001 /* CNT1_RET_CNT_ENA[0] */ +#define WF_HIF_DMASHDL_TOP_PKT_IN_CNT_CTRL_CNT1_RET_CNT_ENA_SHFT 0 + +/* +* ---HIF_ASK_LONG_CHECK (0x7C026000 + 0x94)--- +* HIF_ASK_TICK_CNT[15..0] - (RO) HIF request ask wait period count. +* HIF_ASK_LONG_CNT_TH[31..16] - (RW) HIF request ask wait period threshold. +* (unit = 32us, wf_aon_32us_tick) +*/ +#define WF_HIF_DMASHDL_TOP_HIF_ASK_LONG_CHECK_HIF_ASK_LONG_CNT_TH_ADDR \ + WF_HIF_DMASHDL_TOP_HIF_ASK_LONG_CHECK_ADDR +#define WF_HIF_DMASHDL_TOP_HIF_ASK_LONG_CHECK_HIF_ASK_LONG_CNT_TH_MASK \ + 0xFFFF0000 /* HIF_ASK_LONG_CNT_TH[31..16] */ +#define WF_HIF_DMASHDL_TOP_HIF_ASK_LONG_CHECK_HIF_ASK_LONG_CNT_TH_SHFT 16 +#define WF_HIF_DMASHDL_TOP_HIF_ASK_LONG_CHECK_HIF_ASK_TICK_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_HIF_ASK_LONG_CHECK_ADDR +#define WF_HIF_DMASHDL_TOP_HIF_ASK_LONG_CHECK_HIF_ASK_TICK_CNT_MASK \ + 0x0000FFFF /* HIF_ASK_TICK_CNT[15..0] */ +#define WF_HIF_DMASHDL_TOP_HIF_ASK_LONG_CHECK_HIF_ASK_TICK_CNT_SHFT 0 + +/* +* ---CPU_QUOTA_SET (0x7C026000 + 0x98)--- +* RETURN_PAGE_CNT[11..0] - (RW) CPU refill page count +* RESERVED12[15..12] - (RO) Reserved bits +* CPU_RETRUN_GID[19..16] - (RW) CPU refill group's ID +* RESERVED20[23..20] - (RO) Reserved bits +* CPU_RETRUN_MODE[25..24] - (RW) CPU refill mode selection +* 2'b00 : Substrate source mode +* 2'b01 : Return mode +* 2'b10 : Add source mode +* 2'b11 : Substrate reservation mode +* RESERVED26[30..26] - (RO) Reserved bits +* EXCUTE[31] - (WO) Excute this CR action +*/ +#define WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_EXCUTE_ADDR \ + WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_ADDR +#define WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_EXCUTE_MASK 0x80000000 /* EXCUTE[31] */ +#define WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_EXCUTE_SHFT 31 +#define WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_CPU_RETRUN_MODE_ADDR \ + WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_ADDR +#define WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_CPU_RETRUN_MODE_MASK \ + 0x03000000 /* CPU_RETRUN_MODE[25..24] */ +#define WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_CPU_RETRUN_MODE_SHFT 24 +#define WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_CPU_RETRUN_GID_ADDR \ + WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_ADDR +#define WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_CPU_RETRUN_GID_MASK \ + 0x000F0000 /* CPU_RETRUN_GID[19..16] */ +#define WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_CPU_RETRUN_GID_SHFT 16 +#define WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_RETURN_PAGE_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_ADDR +#define WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_RETURN_PAGE_CNT_MASK \ + 0x00000FFF /* RETURN_PAGE_CNT[11..0] */ +#define WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_RETURN_PAGE_CNT_SHFT 0 + +/* +* ---ERROR_FLAG_CTRL (0x7C026000 + 0x9c)--- +* CNT_UDF_INT_DMASK[15..0] - (RW) Underflow flag interrupt disable mask +control: +* bit[11] : pse_src_pktret_udf_flag +* bit[10] : pse_src_pseret_udf_flag +* bit[9] : pse_rsv_udf_flag +* bit[8] : hif_ask_long_flag_flag +* bit[7] : pse_size_gt_max_size_flag +* bit[6] : ple_txd_gt_max_size_flag +* bit[5] : rsv_sub_curr_udf_flag +* bit[4] : refill_max0_udf_flag +* bit[3] : refill_max1_udf_flag +* bit[2] : src_sub_cur_udf_flag +* bit[1] : ffa_cnt_udf_flag +* bit[0] : freepg_cnt_udf_flag +* FREEPG_CNT_UDF_FLAG[16] - (RO) Freepage count underflow flag +* FFA_CNT_UDF_FLAG[17] - (RO) FFA count underflow flag +* SRC_SUB_CUR_UDF_FLAG[18] - (RO) PLE return stage source count underflow +flag +* REFILL_MAX1_UDF_FLAG[19] - (RO) Pktin return stage source count +* underflow flag +* REFILL_MAX0_UDF_FLAG[20] - (RO) RSV add SRC count greater than maximum +quota +* RSV_SUB_CURR_UDF_FLAG[21] - (RO) Reservation count underflow flag +* PLE_TXD_GT_MAX_SIZE_FLAG[22] - (RO) PLE txd size greater than max PLE txd +* size flag +* PSE_SIZE_GT_MAX_SIZE_FLAG[23] - (RO) PSE packet size greater than max packet +* size flag +* HIF_ASK_LONG_FLAG[24] - (RO) The HIF ask after long time period to +* grant flag +* PSE_RSV_UDF_FLAG[25] - (RO) The HIF ask to let reservation count +* underflow flag +* PSE_SRC_PSERET_UDF_FLAG[26] - (RO) The PSE source count PSE module return +* underflow flag +* PSE_SRC_PKTRET_UDF_FLAG[27] - (RO) The PSE source count packet in return +* underflow flag +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_PSE_SRC_PKTRET_UDF_FLAG_ADDR \ + WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_ADDR +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_PSE_SRC_PKTRET_UDF_FLAG_MASK \ + 0x08000000 /* PSE_SRC_PKTRET_UDF_FLAG[27] */ +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_PSE_SRC_PKTRET_UDF_FLAG_SHFT 27 +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_PSE_SRC_PSERET_UDF_FLAG_ADDR \ + WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_ADDR +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_PSE_SRC_PSERET_UDF_FLAG_MASK \ + 0x04000000 /* PSE_SRC_PSERET_UDF_FLAG[26] */ +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_PSE_SRC_PSERET_UDF_FLAG_SHFT 26 +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_PSE_RSV_UDF_FLAG_ADDR \ + WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_ADDR +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_PSE_RSV_UDF_FLAG_MASK \ + 0x02000000 /* PSE_RSV_UDF_FLAG[25] */ +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_PSE_RSV_UDF_FLAG_SHFT 25 +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_HIF_ASK_LONG_FLAG_ADDR \ + WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_ADDR +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_HIF_ASK_LONG_FLAG_MASK \ + 0x01000000 /* HIF_ASK_LONG_FLAG[24] */ +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_HIF_ASK_LONG_FLAG_SHFT 24 +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_PSE_SIZE_GT_MAX_SIZE_FLAG_ADDR \ + WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_ADDR +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_PSE_SIZE_GT_MAX_SIZE_FLAG_MASK \ + 0x00800000 /* PSE_SIZE_GT_MAX_SIZE_FLAG[23] */ +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_PSE_SIZE_GT_MAX_SIZE_FLAG_SHFT 23 +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_PLE_TXD_GT_MAX_SIZE_FLAG_ADDR \ + WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_ADDR +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_PLE_TXD_GT_MAX_SIZE_FLAG_MASK \ + 0x00400000 /* PLE_TXD_GT_MAX_SIZE_FLAG[22] */ +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_PLE_TXD_GT_MAX_SIZE_FLAG_SHFT 22 +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_RSV_SUB_CURR_UDF_FLAG_ADDR \ + WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_ADDR +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_RSV_SUB_CURR_UDF_FLAG_MASK \ + 0x00200000 /* RSV_SUB_CURR_UDF_FLAG[21] */ +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_RSV_SUB_CURR_UDF_FLAG_SHFT 21 +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_REFILL_MAX0_UDF_FLAG_ADDR \ + WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_ADDR +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_REFILL_MAX0_UDF_FLAG_MASK \ + 0x00100000 /* REFILL_MAX0_UDF_FLAG[20] */ +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_REFILL_MAX0_UDF_FLAG_SHFT 20 +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_REFILL_MAX1_UDF_FLAG_ADDR \ + WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_ADDR +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_REFILL_MAX1_UDF_FLAG_MASK \ + 0x00080000 /* REFILL_MAX1_UDF_FLAG[19] */ +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_REFILL_MAX1_UDF_FLAG_SHFT 19 +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_SRC_SUB_CUR_UDF_FLAG_ADDR \ + WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_ADDR +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_SRC_SUB_CUR_UDF_FLAG_MASK \ + 0x00040000 /* SRC_SUB_CUR_UDF_FLAG[18] */ +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_SRC_SUB_CUR_UDF_FLAG_SHFT 18 +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_FFA_CNT_UDF_FLAG_ADDR \ + WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_ADDR +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_FFA_CNT_UDF_FLAG_MASK \ + 0x00020000 /* FFA_CNT_UDF_FLAG[17] */ +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_FFA_CNT_UDF_FLAG_SHFT 17 +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_FREEPG_CNT_UDF_FLAG_ADDR \ + WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_ADDR +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_FREEPG_CNT_UDF_FLAG_MASK \ + 0x00010000 /* FREEPG_CNT_UDF_FLAG[16] */ +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_FREEPG_CNT_UDF_FLAG_SHFT 16 +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_CNT_UDF_INT_DMASK_ADDR \ + WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_ADDR +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_CNT_UDF_INT_DMASK_MASK \ + 0x0000FFFF /* CNT_UDF_INT_DMASK[15..0] */ +#define WF_HIF_DMASHDL_TOP_ERROR_FLAG_CTRL_CNT_UDF_INT_DMASK_SHFT 0 + +/* +* ---HIF_SCHEDULER_SETTING0 (0x7C026000 + 0xB0)--- +* PRIORITY0_GROUP[3..0] - (RW) Which group is priority 0, this group is +* highest priority +* PRIORITY1_GROUP[7..4] - (RW) Which group is priority 1 +* PRIORITY2_GROUP[11..8] - (RW) Which group is priority 2 +* PRIORITY3_GROUP[15..12] - (RW) Which group is priority 3 +* PRIORITY4_GROUP[19..16] - (RW) Which group is priority 4 +* PRIORITY5_GROUP[23..20] - (RW) Which group is priority 5 +* PRIORITY6_GROUP[27..24] - (RW) Which group is priority 6 +* PRIORITY7_GROUP[31..28] - (RW) Which group is priority 7 +*/ +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY7_GROUP_ADDR \ + WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_ADDR +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY7_GROUP_MASK \ + 0xF0000000 /* PRIORITY7_GROUP[31..28] */ +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY7_GROUP_SHFT 28 +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY6_GROUP_ADDR \ + WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_ADDR +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY6_GROUP_MASK \ + 0x0F000000 /* PRIORITY6_GROUP[27..24] */ +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY6_GROUP_SHFT 24 +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY5_GROUP_ADDR \ + WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_ADDR +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY5_GROUP_MASK \ + 0x00F00000 /* PRIORITY5_GROUP[23..20] */ +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY5_GROUP_SHFT 20 +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY4_GROUP_ADDR \ + WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_ADDR +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY4_GROUP_MASK \ + 0x000F0000 /* PRIORITY4_GROUP[19..16] */ +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY4_GROUP_SHFT 16 +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY3_GROUP_ADDR \ + WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_ADDR +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY3_GROUP_MASK \ + 0x0000F000 /* PRIORITY3_GROUP[15..12] */ +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY3_GROUP_SHFT 12 +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY2_GROUP_ADDR \ + WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_ADDR +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY2_GROUP_MASK \ + 0x00000F00 /* PRIORITY2_GROUP[11..8] */ +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY2_GROUP_SHFT 8 +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY1_GROUP_ADDR \ + WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_ADDR +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY1_GROUP_MASK \ + 0x000000F0 /* PRIORITY1_GROUP[7..4] */ +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY1_GROUP_SHFT 4 +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY0_GROUP_ADDR \ + WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_ADDR +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY0_GROUP_MASK \ + 0x0000000F /* PRIORITY0_GROUP[3..0] */ +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_PRIORITY0_GROUP_SHFT 0 + +/* +* ---HIF_SCHEDULER_SETTING1 (0x7C026000 + 0xB4)--- +* PRIORITY8_GROUP[3..0] - (RW) Which group is priority 8 +* PRIORITY9_GROUP[7..4] - (RW) Which group is priority 9 +* PRIORITY10_GROUP[11..8] - (RW) Which group is priority 10 +* PRIORITY11_GROUP[15..12] - (RW) Which group is priority 11 +* PRIORITY12_GROUP[19..16] - (RW) Which group is priority 12 +* PRIORITY13_GROUP[23..20] - (RW) Which group is priority 13 +* PRIORITY14_GROUP[27..24] - (RW) Which group is priority 14 +* PRIORITY15_GROUP[31..28] - (RW) Which group is priority 15, this group +* is last priority +*/ +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY15_GROUP_ADDR \ + WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_ADDR +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY15_GROUP_MASK \ + 0xF0000000 /* PRIORITY15_GROUP[31..28] */ +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY15_GROUP_SHFT 28 +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY14_GROUP_ADDR \ + WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_ADDR +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY14_GROUP_MASK \ + 0x0F000000 /* PRIORITY14_GROUP[27..24] */ +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY14_GROUP_SHFT 24 +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY13_GROUP_ADDR \ + WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_ADDR +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY13_GROUP_MASK \ + 0x00F00000 /* PRIORITY13_GROUP[23..20] */ +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY13_GROUP_SHFT 20 +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY12_GROUP_ADDR \ + WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_ADDR +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY12_GROUP_MASK \ + 0x000F0000 /* PRIORITY12_GROUP[19..16] */ +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY12_GROUP_SHFT 16 +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY11_GROUP_ADDR \ + WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_ADDR +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY11_GROUP_MASK \ + 0x0000F000 /* PRIORITY11_GROUP[15..12] */ +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY11_GROUP_SHFT 12 +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY10_GROUP_ADDR \ + WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_ADDR +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY10_GROUP_MASK \ + 0x00000F00 /* PRIORITY10_GROUP[11..8] */ +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY10_GROUP_SHFT 8 +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY9_GROUP_ADDR \ + WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_ADDR +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY9_GROUP_MASK \ + 0x000000F0 /* PRIORITY9_GROUP[7..4] */ +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY9_GROUP_SHFT 4 +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY8_GROUP_ADDR \ + WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_ADDR +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY8_GROUP_MASK \ + 0x0000000F /* PRIORITY8_GROUP[3..0] */ +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_PRIORITY8_GROUP_SHFT 0 + +/* +* ---SLOT_SETTING0 (0x7C026000 + 0xC4)--- +* SLOT_0_SETTING[3..0] - (RW) Slot0 priority setting +* SLOT_1_SETTING[7..4] - (RW) Slot1 priority setting +* SLOT_2_SETTING[11..8] - (RW) Slot2 priority setting +* SLOT_3_SETTING[15..12] - (RW) Slot3 priority setting +* SLOT_4_SETTING[19..16] - (RW) Slot4 priority setting +* SLOT_5_SETTING[23..20] - (RW) Slot5 priority setting +* SLOT_6_SETTING[27..24] - (RW) Slot6 priority setting +* SLOT_7_SETTING[31..28] - (RW) Slot7 priority setting(which group ID) +*/ +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_7_SETTING_ADDR \ + WF_HIF_DMASHDL_TOP_SLOT_SETTING0_ADDR +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_7_SETTING_MASK \ + 0xF0000000 /* SLOT_7_SETTING[31..28] */ +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_7_SETTING_SHFT 28 +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_6_SETTING_ADDR \ + WF_HIF_DMASHDL_TOP_SLOT_SETTING0_ADDR +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_6_SETTING_MASK \ + 0x0F000000 /* SLOT_6_SETTING[27..24] */ +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_6_SETTING_SHFT 24 +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_5_SETTING_ADDR \ + WF_HIF_DMASHDL_TOP_SLOT_SETTING0_ADDR +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_5_SETTING_MASK \ + 0x00F00000 /* SLOT_5_SETTING[23..20] */ +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_5_SETTING_SHFT 20 +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_4_SETTING_ADDR \ + WF_HIF_DMASHDL_TOP_SLOT_SETTING0_ADDR +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_4_SETTING_MASK \ + 0x000F0000 /* SLOT_4_SETTING[19..16] */ +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_4_SETTING_SHFT 16 +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_3_SETTING_ADDR \ + WF_HIF_DMASHDL_TOP_SLOT_SETTING0_ADDR +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_3_SETTING_MASK \ + 0x0000F000 /* SLOT_3_SETTING[15..12] */ +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_3_SETTING_SHFT 12 +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_2_SETTING_ADDR \ + WF_HIF_DMASHDL_TOP_SLOT_SETTING0_ADDR +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_2_SETTING_MASK \ + 0x00000F00 /* SLOT_2_SETTING[11..8] */ +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_2_SETTING_SHFT 8 +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_1_SETTING_ADDR \ + WF_HIF_DMASHDL_TOP_SLOT_SETTING0_ADDR +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_1_SETTING_MASK \ + 0x000000F0 /* SLOT_1_SETTING[7..4] */ +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_1_SETTING_SHFT 4 +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_0_SETTING_ADDR \ + WF_HIF_DMASHDL_TOP_SLOT_SETTING0_ADDR +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_0_SETTING_MASK \ + 0x0000000F /* SLOT_0_SETTING[3..0] */ +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING0_SLOT_0_SETTING_SHFT 0 + +/* +* ---SLOT_SETTING1 (0x7C026000 + 0xC8)--- +* SLOT_8_SETTING[3..0] - (RW) Slot8 priority setting +* SLOT_9_SETTING[7..4] - (RW) Slot9 priority setting +* SLOT_10_SETTING[11..8] - (RW) Slot10 priority setting +* SLOT_11_SETTING[15..12] - (RW) Slo11 priority setting +* SLOT_12_SETTING[19..16] - (RW) Slot12 priority setting +* SLOT_13_SETTING[23..20] - (RW) Slot13 priority setting +* SLOT_14_SETTING[27..24] - (RW) Slot14 priority setting +* SLOT_15_SETTING[31..28] - (RW) Slot15 priority setting(which group ID) +*/ +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_15_SETTING_ADDR \ + WF_HIF_DMASHDL_TOP_SLOT_SETTING1_ADDR +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_15_SETTING_MASK \ + 0xF0000000 /* SLOT_15_SETTING[31..28] */ +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_15_SETTING_SHFT 28 +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_14_SETTING_ADDR \ + WF_HIF_DMASHDL_TOP_SLOT_SETTING1_ADDR +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_14_SETTING_MASK \ + 0x0F000000 /* SLOT_14_SETTING[27..24] */ +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_14_SETTING_SHFT 24 +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_13_SETTING_ADDR \ + WF_HIF_DMASHDL_TOP_SLOT_SETTING1_ADDR +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_13_SETTING_MASK \ + 0x00F00000 /* SLOT_13_SETTING[23..20] */ +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_13_SETTING_SHFT 20 +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_12_SETTING_ADDR \ + WF_HIF_DMASHDL_TOP_SLOT_SETTING1_ADDR +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_12_SETTING_MASK \ + 0x000F0000 /* SLOT_12_SETTING[19..16] */ +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_12_SETTING_SHFT 16 +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_11_SETTING_ADDR \ + WF_HIF_DMASHDL_TOP_SLOT_SETTING1_ADDR +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_11_SETTING_MASK \ + 0x0000F000 /* SLOT_11_SETTING[15..12] */ +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_11_SETTING_SHFT 12 +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_10_SETTING_ADDR \ + WF_HIF_DMASHDL_TOP_SLOT_SETTING1_ADDR +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_10_SETTING_MASK \ + 0x00000F00 /* SLOT_10_SETTING[11..8] */ +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_10_SETTING_SHFT 8 +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_9_SETTING_ADDR \ + WF_HIF_DMASHDL_TOP_SLOT_SETTING1_ADDR +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_9_SETTING_MASK \ + 0x000000F0 /* SLOT_9_SETTING[7..4] */ +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_9_SETTING_SHFT 4 +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_8_SETTING_ADDR \ + WF_HIF_DMASHDL_TOP_SLOT_SETTING1_ADDR +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_8_SETTING_MASK \ + 0x0000000F /* SLOT_8_SETTING[3..0] */ +#define WF_HIF_DMASHDL_TOP_SLOT_SETTING1_SLOT_8_SETTING_SHFT 0 + +/* +* ---SLOT_PERIOD (0x7C026000 + 0xCC)--- +* SLOT_PERIOD[15..0] - (RW) Slot Period (clock periods) +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_SLOT_PERIOD_SLOT_PERIOD_ADDR \ + WF_HIF_DMASHDL_TOP_SLOT_PERIOD_ADDR +#define WF_HIF_DMASHDL_TOP_SLOT_PERIOD_SLOT_PERIOD_MASK \ + 0x0000FFFF /* SLOT_PERIOD[15..0] */ +#define WF_HIF_DMASHDL_TOP_SLOT_PERIOD_SLOT_PERIOD_SHFT 0 + +/* +* ---QUEUE_MAPPING0 (0x7C026000 + 0xd0)--- +* QUEUE0_MAPPING[3..0] - (RW) Queue 0 use which group ID +* QUEUE1_MAPPING[7..4] - (RW) Queue 1 use which group ID +* QUEUE2_MAPPING[11..8] - (RW) Queue 2 use which group ID +* QUEUE3_MAPPING[15..12] - (RW) Queue 3 use which group ID +* QUEUE4_MAPPING[19..16] - (RW) Queue 4 use which group ID +* QUEUE5_MAPPING[23..20] - (RW) Queue 5 use which group ID +* QUEUE6_MAPPING[27..24] - (RW) Queue 6 use which group ID +* QUEUE7_MAPPING[31..28] - (RW) Queue 7 use which group ID +*/ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE7_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE7_MAPPING_MASK \ + 0xF0000000 /* QUEUE7_MAPPING[31..28] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE7_MAPPING_SHFT 28 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE6_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE6_MAPPING_MASK \ + 0x0F000000 /* QUEUE6_MAPPING[27..24] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE6_MAPPING_SHFT 24 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE5_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE5_MAPPING_MASK \ + 0x00F00000 /* QUEUE5_MAPPING[23..20] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE5_MAPPING_SHFT 20 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE4_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE4_MAPPING_MASK \ + 0x000F0000 /* QUEUE4_MAPPING[19..16] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE4_MAPPING_SHFT 16 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE3_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE3_MAPPING_MASK \ + 0x0000F000 /* QUEUE3_MAPPING[15..12] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE3_MAPPING_SHFT 12 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE2_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE2_MAPPING_MASK \ + 0x00000F00 /* QUEUE2_MAPPING[11..8] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE2_MAPPING_SHFT 8 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE1_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE1_MAPPING_MASK \ + 0x000000F0 /* QUEUE1_MAPPING[7..4] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE1_MAPPING_SHFT 4 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE0_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE0_MAPPING_MASK \ + 0x0000000F /* QUEUE0_MAPPING[3..0] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE0_MAPPING_SHFT 0 + +/* +* ---QUEUE_MAPPING1 (0x7C026000 + 0xd4)--- +* QUEUE8_MAPPING[3..0] - (RW) Queue 8 use which group ID +* QUEUE9_MAPPING[7..4] - (RW) Queue 9 use which group ID +* QUEUE10_MAPPING[11..8] - (RW) Queue 10 use which group ID +* QUEUE11_MAPPING[15..12] - (RW) Queue 11 use which group ID +* QUEUE12_MAPPING[19..16] - (RW) Queue 12 use which group ID +* QUEUE13_MAPPING[23..20] - (RW) Queue 13 use which group ID +* QUEUE14_MAPPING[27..24] - (RW) Queue 14 use which group ID +* QUEUE15_MAPPING[31..28] - (RW) Queue 15 use which group ID +*/ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE15_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE15_MAPPING_MASK \ + 0xF0000000 /* QUEUE15_MAPPING[31..28] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE15_MAPPING_SHFT 28 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE14_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE14_MAPPING_MASK \ + 0x0F000000 /* QUEUE14_MAPPING[27..24] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE14_MAPPING_SHFT 24 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE13_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE13_MAPPING_MASK \ + 0x00F00000 /* QUEUE13_MAPPING[23..20] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE13_MAPPING_SHFT 20 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE12_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE12_MAPPING_MASK \ + 0x000F0000 /* QUEUE12_MAPPING[19..16] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE12_MAPPING_SHFT 16 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE11_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE11_MAPPING_MASK \ + 0x0000F000 /* QUEUE11_MAPPING[15..12] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE11_MAPPING_SHFT 12 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE10_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE10_MAPPING_MASK \ + 0x00000F00 /* QUEUE10_MAPPING[11..8] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE10_MAPPING_SHFT 8 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE9_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE9_MAPPING_MASK \ + 0x000000F0 /* QUEUE9_MAPPING[7..4] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE9_MAPPING_SHFT 4 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE8_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE8_MAPPING_MASK \ + 0x0000000F /* QUEUE8_MAPPING[3..0] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE8_MAPPING_SHFT 0 + +/* +* ---QUEUE_MAPPING2 (0x7C026000 + 0xd8)--- +* QUEUE16_MAPPING[3..0] - (RW) Queue 16 use which group ID +* QUEUE17_MAPPING[7..4] - (RW) Queue 17 use which group ID +* QUEUE18_MAPPING[11..8] - (RW) Queue 18 use which group ID +* QUEUE19_MAPPING[15..12] - (RW) Queue 19 use which group ID +* QUEUE20_MAPPING[19..16] - (RW) Queue 20 use which group ID +* QUEUE21_MAPPING[23..20] - (RW) Queue 21 use which group ID +* QUEUE22_MAPPING[27..24] - (RW) Queue 22 use which group ID +* QUEUE23_MAPPING[31..28] - (RW) Queue 23 use which group ID +*/ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE23_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE23_MAPPING_MASK \ + 0xF0000000 /* QUEUE23_MAPPING[31..28] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE23_MAPPING_SHFT 28 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE22_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE22_MAPPING_MASK \ + 0x0F000000 /* QUEUE22_MAPPING[27..24] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE22_MAPPING_SHFT 24 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE21_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE21_MAPPING_MASK \ + 0x00F00000 /* QUEUE21_MAPPING[23..20] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE21_MAPPING_SHFT 20 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE20_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE20_MAPPING_MASK \ + 0x000F0000 /* QUEUE20_MAPPING[19..16] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE20_MAPPING_SHFT 16 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE19_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE19_MAPPING_MASK \ + 0x0000F000 /* QUEUE19_MAPPING[15..12] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE19_MAPPING_SHFT 12 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE18_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE18_MAPPING_MASK \ + 0x00000F00 /* QUEUE18_MAPPING[11..8] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE18_MAPPING_SHFT 8 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE17_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE17_MAPPING_MASK \ + 0x000000F0 /* QUEUE17_MAPPING[7..4] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE17_MAPPING_SHFT 4 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE16_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE16_MAPPING_MASK \ + 0x0000000F /* QUEUE16_MAPPING[3..0] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE16_MAPPING_SHFT 0 + +/* +* ---QUEUE_MAPPING3 (0x7C026000 + 0xdc)--- +* QUEUE24_MAPPING[3..0] - (RW) Queue 24 use which group ID +* QUEUE25_MAPPING[7..4] - (RW) Queue 25 use which group ID +* QUEUE26_MAPPING[11..8] - (RW) Queue 26 use which group ID +* QUEUE27_MAPPING[15..12] - (RW) Queue 27 use which group ID +* QUEUE28_MAPPING[19..16] - (RW) Queue 28 use which group ID +* QUEUE29_MAPPING[23..20] - (RW) Queue 29 use which group ID +* QUEUE30_MAPPING[27..24] - (RW) Queue 30 use which group ID +* QUEUE31_MAPPING[31..28] - (RW) Queue 31 use which group ID +*/ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE31_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE31_MAPPING_MASK \ + 0xF0000000 /* QUEUE31_MAPPING[31..28] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE31_MAPPING_SHFT 28 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE30_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE30_MAPPING_MASK \ + 0x0F000000 /* QUEUE30_MAPPING[27..24] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE30_MAPPING_SHFT 24 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE29_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE29_MAPPING_MASK \ + 0x00F00000 /* QUEUE29_MAPPING[23..20] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE29_MAPPING_SHFT 20 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE28_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE28_MAPPING_MASK \ + 0x000F0000 /* QUEUE28_MAPPING[19..16] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE28_MAPPING_SHFT 16 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE27_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE27_MAPPING_MASK \ + 0x0000F000 /* QUEUE27_MAPPING[15..12] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE27_MAPPING_SHFT 12 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE26_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE26_MAPPING_MASK \ + 0x00000F00 /* QUEUE26_MAPPING[11..8] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE26_MAPPING_SHFT 8 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE25_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE25_MAPPING_MASK \ + 0x000000F0 /* QUEUE25_MAPPING[7..4] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE25_MAPPING_SHFT 4 +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE24_MAPPING_ADDR \ + WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_ADDR +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE24_MAPPING_MASK \ + 0x0000000F /* QUEUE24_MAPPING[3..0] */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_QUEUE24_MAPPING_SHFT 0 + +/* +* ---STATUS_RD (0x7C026000 + 0x100)--- +* FFA_CNT[11..0] - (RO) Free for all (FFA) count +* RESERVED12[15..12] - (RO) Reserved bits +* FREE_PAGE_CNT[27..16] - (RO) Free page count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_FREE_PAGE_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_FREE_PAGE_CNT_MASK \ + 0x0FFF0000 /* FREE_PAGE_CNT[27..16] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_FREE_PAGE_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_STATUS_RD_FFA_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_FFA_CNT_MASK \ + 0x00000FFF /* FFA_CNT[11..0] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_FFA_CNT_SHFT 0 + +/* +* ---STATUS_RD_GP0 (0x7C026000 + 0x140)--- +* G0_SRC_CNT[11..0] - (RO) Group0 source count +* RESERVED12[15..12] - (RO) Reserved bits +* G0_RSV_CNT[27..16] - (RO) Group0 reservation count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_G0_RSV_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_G0_RSV_CNT_MASK \ + 0x0FFF0000 /* G0_RSV_CNT[27..16] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_G0_RSV_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_G0_SRC_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_G0_SRC_CNT_MASK \ + 0x00000FFF /* G0_SRC_CNT[11..0] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_G0_SRC_CNT_SHFT 0 + +/* +* ---STATUS_RD_GP1 (0x7C026000 + 0x144)--- +* G1_SRC_CNT[11..0] - (RO) Group1 source count +* RESERVED12[15..12] - (RO) Reserved bits +* G1_RSV_CNT[27..16] - (RO) Group1 reservation count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP1_G1_RSV_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP1_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP1_G1_RSV_CNT_MASK \ + 0x0FFF0000 /* G1_RSV_CNT[27..16] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP1_G1_RSV_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP1_G1_SRC_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP1_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP1_G1_SRC_CNT_MASK \ + 0x00000FFF /* G1_SRC_CNT[11..0] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP1_G1_SRC_CNT_SHFT 0 + +/* +* ---STATUS_RD_GP2 (0x7C026000 + 0x148)--- +* G2_SRC_CNT[11..0] - (RO) Group2 source count +* RESERVED12[15..12] - (RO) Reserved bits +* G2_RSV_CNT[27..16] - (RO) Group2 reservation count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP2_G2_RSV_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP2_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP2_G2_RSV_CNT_MASK \ + 0x0FFF0000 /* G2_RSV_CNT[27..16] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP2_G2_RSV_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP2_G2_SRC_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP2_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP2_G2_SRC_CNT_MASK \ + 0x00000FFF /* G2_SRC_CNT[11..0] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP2_G2_SRC_CNT_SHFT 0 + +/* +* ---STATUS_RD_GP3 (0x7C026000 + 0x14c)--- +* G3_SRC_CNT[11..0] - (RO) Group3 source count +* RESERVED12[15..12] - (RO) Reserved bits +* G3_RSV_CNT[27..16] - (RO) Group3 reservation count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP3_G3_RSV_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP3_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP3_G3_RSV_CNT_MASK \ + 0x0FFF0000 /* G3_RSV_CNT[27..16] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP3_G3_RSV_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP3_G3_SRC_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP3_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP3_G3_SRC_CNT_MASK \ + 0x00000FFF /* G3_SRC_CNT[11..0] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP3_G3_SRC_CNT_SHFT 0 + +/* +* ---STATUS_RD_GP4 (0x7C026000 + 0x150)--- +* G4_SRC_CNT[11..0] - (RO) Group4 source count +* RESERVED12[15..12] - (RO) Reserved bits +* G4_RSV_CNT[27..16] - (RO) Group4 reservation count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP4_G4_RSV_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP4_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP4_G4_RSV_CNT_MASK \ + 0x0FFF0000 /* G4_RSV_CNT[27..16] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP4_G4_RSV_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP4_G4_SRC_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP4_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP4_G4_SRC_CNT_MASK \ + 0x00000FFF /* G4_SRC_CNT[11..0] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP4_G4_SRC_CNT_SHFT 0 + +/* +* ---STATUS_RD_GP5 (0x7C026000 + 0x154)--- +* G5_SRC_CNT[11..0] - (RO) Group5 source count +* RESERVED12[15..12] - (RO) Reserved bits +* G5_RSV_CNT[27..16] - (RO) Group5 reservation count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP5_G5_RSV_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP5_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP5_G5_RSV_CNT_MASK \ + 0x0FFF0000 /* G5_RSV_CNT[27..16] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP5_G5_RSV_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP5_G5_SRC_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP5_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP5_G5_SRC_CNT_MASK \ + 0x00000FFF /* G5_SRC_CNT[11..0] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP5_G5_SRC_CNT_SHFT 0 + +/* +* ---STATUS_RD_GP6 (0x7C026000 + 0x158)--- +* G6_SRC_CNT[11..0] - (RO) Group6 source count +* RESERVED12[15..12] - (RO) Reserved bits +* G6_RSV_CNT[27..16] - (RO) Group6 reservation count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP6_G6_RSV_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP6_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP6_G6_RSV_CNT_MASK \ + 0x0FFF0000 /* G6_RSV_CNT[27..16] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP6_G6_RSV_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP6_G6_SRC_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP6_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP6_G6_SRC_CNT_MASK \ + 0x00000FFF /* G6_SRC_CNT[11..0] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP6_G6_SRC_CNT_SHFT 0 + +/* +* ---STATUS_RD_GP7 (0x7C026000 + 0x15C)--- +* G7_SRC_CNT[11..0] - (RO) Group7 source count +* RESERVED12[15..12] - (RO) Reserved bits +* G7_RSV_CNT[27..16] - (RO) Group7 reservation count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP7_G7_RSV_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP7_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP7_G7_RSV_CNT_MASK \ + 0x0FFF0000 /* G7_RSV_CNT[27..16] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP7_G7_RSV_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP7_G7_SRC_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP7_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP7_G7_SRC_CNT_MASK \ + 0x00000FFF /* G7_SRC_CNT[11..0] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP7_G7_SRC_CNT_SHFT 0 + +/* +* ---STATUS_RD_GP8 (0x7C026000 + 0x160)--- +* G8_SRC_CNT[11..0] - (RO) Group8 source count +* RESERVED12[15..12] - (RO) Reserved bits +* G8_RSV_CNT[27..16] - (RO) Group8 reservation count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP8_G8_RSV_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP8_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP8_G8_RSV_CNT_MASK \ + 0x0FFF0000 /* G8_RSV_CNT[27..16] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP8_G8_RSV_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP8_G8_SRC_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP8_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP8_G8_SRC_CNT_MASK \ + 0x00000FFF /* G8_SRC_CNT[11..0] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP8_G8_SRC_CNT_SHFT 0 + +/* +* ---STATUS_RD_GP9 (0x7C026000 + 0x164)--- +* G9_SRC_CNT[11..0] - (RO) Group9 source count +* RESERVED12[15..12] - (RO) Reserved bits +* G9_RSV_CNT[27..16] - (RO) Group9 reservation count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP9_G9_RSV_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP9_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP9_G9_RSV_CNT_MASK \ + 0x0FFF0000 /* G9_RSV_CNT[27..16] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP9_G9_RSV_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP9_G9_SRC_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP9_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP9_G9_SRC_CNT_MASK \ + 0x00000FFF /* G9_SRC_CNT[11..0] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP9_G9_SRC_CNT_SHFT 0 + +/* +* ---STATUS_RD_GP10 (0x7C026000 + 0x168)--- +* G10_SRC_CNT[11..0] - (RO) Group10 source count +* RESERVED12[15..12] - (RO) Reserved bits +* G10_RSV_CNT[27..16] - (RO) Group10 reservation count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP10_G10_RSV_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP10_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP10_G10_RSV_CNT_MASK \ + 0x0FFF0000 /* G10_RSV_CNT[27..16] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP10_G10_RSV_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP10_G10_SRC_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP10_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP10_G10_SRC_CNT_MASK \ + 0x00000FFF /* G10_SRC_CNT[11..0] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP10_G10_SRC_CNT_SHFT 0 + +/* +* ---STATUS_RD_GP11 (0x7C026000 + 0x16c)--- +* G11_SRC_CNT[11..0] - (RO) Group11 source count +* RESERVED12[15..12] - (RO) Reserved bits +* G11_RSV_CNT[27..16] - (RO) Group11 reservation count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP11_G11_RSV_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP11_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP11_G11_RSV_CNT_MASK \ + 0x0FFF0000 /* G11_RSV_CNT[27..16] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP11_G11_RSV_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP11_G11_SRC_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP11_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP11_G11_SRC_CNT_MASK \ + 0x00000FFF /* G11_SRC_CNT[11..0] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP11_G11_SRC_CNT_SHFT 0 + +/* +* ---STATUS_RD_GP12 (0x7C026000 + 0x170)--- +* G12_SRC_CNT[11..0] - (RO) Group12 source count +* RESERVED12[15..12] - (RO) Reserved bits +* G12_RSV_CNT[27..16] - (RO) Group12 reservation count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP12_G12_RSV_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP12_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP12_G12_RSV_CNT_MASK \ + 0x0FFF0000 /* G12_RSV_CNT[27..16] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP12_G12_RSV_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP12_G12_SRC_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP12_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP12_G12_SRC_CNT_MASK \ + 0x00000FFF /* G12_SRC_CNT[11..0] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP12_G12_SRC_CNT_SHFT 0 + +/* +* ---STATUS_RD_GP13 (0x7C026000 + 0x174)--- +* G13_SRC_CNT[11..0] - (RO) Group13 source count +* RESERVED12[15..12] - (RO) Reserved bits +* G13_RSV_CNT[27..16] - (RO) Group13 reservation count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP13_G13_RSV_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP13_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP13_G13_RSV_CNT_MASK \ + 0x0FFF0000 /* G13_RSV_CNT[27..16] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP13_G13_RSV_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP13_G13_SRC_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP13_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP13_G13_SRC_CNT_MASK \ + 0x00000FFF /* G13_SRC_CNT[11..0] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP13_G13_SRC_CNT_SHFT 0 + +/* +* ---STATUS_RD_GP14 (0x7C026000 + 0x178)--- +* G14_SRC_CNT[11..0] - (RO) Group14 source count +* RESERVED12[15..12] - (RO) Reserved bits +* G14_RSV_CNT[27..16] - (RO) Group14 reservation count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP14_G14_RSV_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP14_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP14_G14_RSV_CNT_MASK \ + 0x0FFF0000 /* G14_RSV_CNT[27..16] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP14_G14_RSV_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP14_G14_SRC_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP14_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP14_G14_SRC_CNT_MASK \ + 0x00000FFF /* G14_SRC_CNT[11..0] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP14_G14_SRC_CNT_SHFT 0 + +/* +* ---STATUS_RD_GP15 (0x7C026000 + 0x17C)--- +* G15_SRC_CNT[11..0] - (RO) Group15 source count +* RESERVED12[15..12] - (RO) Reserved bits +* G15_RSV_CNT[27..16] - (RO) Group15 reservation count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP15_G15_RSV_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP15_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP15_G15_RSV_CNT_MASK \ + 0x0FFF0000 /* G15_RSV_CNT[27..16] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP15_G15_RSV_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP15_G15_SRC_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_STATUS_RD_GP15_ADDR +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP15_G15_SRC_CNT_MASK \ + 0x00000FFF /* G15_SRC_CNT[11..0] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP15_G15_SRC_CNT_SHFT 0 + +/* +* ---RD_GROUP_PKT_CNT0 (0x7C026000 + 0x180)--- +* GP0_ASK_CNT[7..0] - (RO) Group0 ask count +* GP0_PKTIN_CNT[15..8] - (RO) Group0 packet in count +* GP1_ASK_CNT[23..16] - (RO) Group1 ask count +* GP1_PKTIN_CNT[31..24] - (RO) Group1 packet in count +*/ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT0_GP1_PKTIN_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT0_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT0_GP1_PKTIN_CNT_MASK \ + 0xFF000000 /* GP1_PKTIN_CNT[31..24] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT0_GP1_PKTIN_CNT_SHFT 24 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT0_GP1_ASK_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT0_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT0_GP1_ASK_CNT_MASK \ + 0x00FF0000 /* GP1_ASK_CNT[23..16] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT0_GP1_ASK_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT0_GP0_PKTIN_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT0_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT0_GP0_PKTIN_CNT_MASK \ + 0x0000FF00 /* GP0_PKTIN_CNT[15..8] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT0_GP0_PKTIN_CNT_SHFT 8 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT0_GP0_ASK_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT0_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT0_GP0_ASK_CNT_MASK \ + 0x000000FF /* GP0_ASK_CNT[7..0] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT0_GP0_ASK_CNT_SHFT 0 + +/* +* ---RD_GROUP_PKT_CNT1 (0x7C026000 + 0x184)--- +* GP2_ASK_CNT[7..0] - (RO) Group2 ask count +* GP2_PKTIN_CNT[15..8] - (RO) Group2 packet in count +* GP3_ASK_CNT[23..16] - (RO) Group3 ask count +* GP3_PKTIN_CNT[31..24] - (RO) Group3 packet in count +*/ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT1_GP3_PKTIN_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT1_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT1_GP3_PKTIN_CNT_MASK \ + 0xFF000000 /* GP3_PKTIN_CNT[31..24] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT1_GP3_PKTIN_CNT_SHFT 24 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT1_GP3_ASK_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT1_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT1_GP3_ASK_CNT_MASK \ + 0x00FF0000 /* GP3_ASK_CNT[23..16] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT1_GP3_ASK_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT1_GP2_PKTIN_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT1_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT1_GP2_PKTIN_CNT_MASK \ + 0x0000FF00 /* GP2_PKTIN_CNT[15..8] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT1_GP2_PKTIN_CNT_SHFT 8 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT1_GP2_ASK_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT1_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT1_GP2_ASK_CNT_MASK \ + 0x000000FF /* GP2_ASK_CNT[7..0] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT1_GP2_ASK_CNT_SHFT 0 + +/* +* ---RD_GROUP_PKT_CNT2 (0x7C026000 + 0x188)--- +* GP4_ASK_CNT[7..0] - (RO) Group4 ask count +* GP4_PKTIN_CNT[15..8] - (RO) Group4 packet in count +* GP5_ASK_CNT[23..16] - (RO) Group5 ask count +* GP5_PKTIN_CNT[31..24] - (RO) Group5 packet in count +*/ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT2_GP5_PKTIN_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT2_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT2_GP5_PKTIN_CNT_MASK \ + 0xFF000000 /* GP5_PKTIN_CNT[31..24] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT2_GP5_PKTIN_CNT_SHFT 24 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT2_GP5_ASK_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT2_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT2_GP5_ASK_CNT_MASK \ + 0x00FF0000 /* GP5_ASK_CNT[23..16] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT2_GP5_ASK_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT2_GP4_PKTIN_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT2_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT2_GP4_PKTIN_CNT_MASK \ + 0x0000FF00 /* GP4_PKTIN_CNT[15..8] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT2_GP4_PKTIN_CNT_SHFT 8 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT2_GP4_ASK_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT2_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT2_GP4_ASK_CNT_MASK \ + 0x000000FF /* GP4_ASK_CNT[7..0] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT2_GP4_ASK_CNT_SHFT 0 + +/* +* ---RD_GROUP_PKT_CNT3 (0x7C026000 + 0x18c)--- +* GP6_ASK_CNT[7..0] - (RO) Group6 ask count +* GP6_PKTIN_CNT[15..8] - (RO) Group6 packet in count +* GP7_ASK_CNT[23..16] - (RO) Group7 ask count +* GP7_PKTIN_CNT[31..24] - (RO) Group7 packet in count +*/ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT3_GP7_PKTIN_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT3_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT3_GP7_PKTIN_CNT_MASK \ + 0xFF000000 /* GP7_PKTIN_CNT[31..24] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT3_GP7_PKTIN_CNT_SHFT 24 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT3_GP7_ASK_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT3_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT3_GP7_ASK_CNT_MASK \ + 0x00FF0000 /* GP7_ASK_CNT[23..16] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT3_GP7_ASK_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT3_GP6_PKTIN_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT3_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT3_GP6_PKTIN_CNT_MASK \ + 0x0000FF00 /* GP6_PKTIN_CNT[15..8] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT3_GP6_PKTIN_CNT_SHFT 8 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT3_GP6_ASK_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT3_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT3_GP6_ASK_CNT_MASK \ + 0x000000FF /* GP6_ASK_CNT[7..0] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT3_GP6_ASK_CNT_SHFT 0 + +/* +* ---RD_GROUP_PKT_CNT4 (0x7C026000 + 0x190)--- +* GP8_ASK_CNT[7..0] - (RO) Group8 ask count +* GP8_PKTIN_CNT[15..8] - (RO) Group8 packet in count +* GP9_ASK_CNT[23..16] - (RO) Group9 ask count +* GP9_PKTIN_CNT[31..24] - (RO) Group9 packet in count +*/ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT4_GP9_PKTIN_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT4_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT4_GP9_PKTIN_CNT_MASK \ + 0xFF000000 /* GP9_PKTIN_CNT[31..24] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT4_GP9_PKTIN_CNT_SHFT 24 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT4_GP9_ASK_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT4_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT4_GP9_ASK_CNT_MASK \ + 0x00FF0000 /* GP9_ASK_CNT[23..16] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT4_GP9_ASK_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT4_GP8_PKTIN_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT4_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT4_GP8_PKTIN_CNT_MASK \ + 0x0000FF00 /* GP8_PKTIN_CNT[15..8] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT4_GP8_PKTIN_CNT_SHFT 8 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT4_GP8_ASK_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT4_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT4_GP8_ASK_CNT_MASK \ + 0x000000FF /* GP8_ASK_CNT[7..0] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT4_GP8_ASK_CNT_SHFT 0 + +/* +* ---RD_GROUP_PKT_CNT5 (0x7C026000 + 0x194)--- +* GP10_ASK_CNT[7..0] - (RO) Group10 ask count +* GP10_PKTIN_CNT[15..8] - (RO) Group10 packet in count +* GP11_ASK_CNT[23..16] - (RO) Group11 ask count +* GP11_PKTIN_CNT[31..24] - (RO) Group11 packet in count +*/ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT5_GP11_PKTIN_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT5_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT5_GP11_PKTIN_CNT_MASK \ + 0xFF000000 /* GP11_PKTIN_CNT[31..24] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT5_GP11_PKTIN_CNT_SHFT 24 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT5_GP11_ASK_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT5_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT5_GP11_ASK_CNT_MASK \ + 0x00FF0000 /* GP11_ASK_CNT[23..16] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT5_GP11_ASK_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT5_GP10_PKTIN_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT5_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT5_GP10_PKTIN_CNT_MASK \ + 0x0000FF00 /* GP10_PKTIN_CNT[15..8] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT5_GP10_PKTIN_CNT_SHFT 8 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT5_GP10_ASK_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT5_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT5_GP10_ASK_CNT_MASK \ + 0x000000FF /* GP10_ASK_CNT[7..0] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT5_GP10_ASK_CNT_SHFT 0 + +/* +* ---RD_GROUP_PKT_CNT6 (0x7C026000 + 0x198)--- +* GP12_ASK_CNT[7..0] - (RO) Group12 ask count +* GP12_PKTIN_CNT[15..8] - (RO) Group12 packet in count +* GP13_ASK_CNT[23..16] - (RO) Group13 ask count +* GP13_PKTIN_CNT[31..24] - (RO) Group13 packet in count +*/ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT6_GP13_PKTIN_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT6_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT6_GP13_PKTIN_CNT_MASK \ + 0xFF000000 /* GP13_PKTIN_CNT[31..24] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT6_GP13_PKTIN_CNT_SHFT 24 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT6_GP13_ASK_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT6_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT6_GP13_ASK_CNT_MASK \ + 0x00FF0000 /* GP13_ASK_CNT[23..16] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT6_GP13_ASK_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT6_GP12_PKTIN_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT6_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT6_GP12_PKTIN_CNT_MASK \ + 0x0000FF00 /* GP12_PKTIN_CNT[15..8] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT6_GP12_PKTIN_CNT_SHFT 8 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT6_GP12_ASK_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT6_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT6_GP12_ASK_CNT_MASK \ + 0x000000FF /* GP12_ASK_CNT[7..0] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT6_GP12_ASK_CNT_SHFT 0 + +/* +* ---RD_GROUP_PKT_CNT7 (0x7C026000 + 0x19c)--- +* GP14_ASK_CNT[7..0] - (RO) Group14 ask count +* GP14_PKTIN_CNT[15..8] - (RO) Group14 packet in count +* GP15_ASK_CNT[23..16] - (RO) Group15 ask count +* GP15_PKTIN_CNT[31..24] - (RO) Group15 packet in count +*/ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT7_GP15_PKTIN_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT7_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT7_GP15_PKTIN_CNT_MASK \ + 0xFF000000 /* GP15_PKTIN_CNT[31..24] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT7_GP15_PKTIN_CNT_SHFT 24 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT7_GP15_ASK_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT7_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT7_GP15_ASK_CNT_MASK \ + 0x00FF0000 /* GP15_ASK_CNT[23..16] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT7_GP15_ASK_CNT_SHFT 16 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT7_GP14_PKTIN_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT7_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT7_GP14_PKTIN_CNT_MASK \ + 0x0000FF00 /* GP14_PKTIN_CNT[15..8] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT7_GP14_PKTIN_CNT_SHFT 8 +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT7_GP14_ASK_CNT_ADDR \ + WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT7_ADDR +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT7_GP14_ASK_CNT_MASK \ + 0x000000FF /* GP14_ASK_CNT[7..0] */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT7_GP14_ASK_CNT_SHFT 0 + +#ifdef __cplusplus +} +#endif + +#endif /* __WF_HIF_DMASHDL_TOP_REGS_H__ */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/soc3_0/wf_ple_top.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/soc3_0/wf_ple_top.h new file mode 100644 index 0000000000000000000000000000000000000000..ae6d51e5569e6a5d838ee8543d0be771075873df --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/soc3_0/wf_ple_top.h @@ -0,0 +1,6739 @@ +/* [File] : wf_ple_top.h */ +/* [Revision time] : Mon Apr 15 14:13:52 2019 */ +/* [Description] : This file is auto generated by CODA */ +/* [Copyright] : Copyright (C) 2019 Mediatek Incorportion. All rights +*/ +/* reserved. */ + +#ifndef __WF_PLE_TOP_REGS_H__ +#define __WF_PLE_TOP_REGS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* **************************************************************** */ +/* */ +/* WF_PLE_TOP CR Definitions */ +/* */ +/* **************************************************************** */ + +#define WF_PLE_TOP_BASE 0x820C0000 + +#define WF_PLE_TOP_GC_ADDR \ + (WF_PLE_TOP_BASE + 0x00) /* 0000 */ +#define WF_PLE_TOP_PBUF_CTRL_ADDR \ + (WF_PLE_TOP_BASE + 0x14) /* 0014 */ +#define WF_PLE_TOP_TIMEOUT_CTRL_ADDR \ + (WF_PLE_TOP_BASE + 0x1c) /* 001C */ +#define WF_PLE_TOP_INT_N9_EN_MASK_ADDR \ + (WF_PLE_TOP_BASE + 0x20) /* 0020 */ +#define WF_PLE_TOP_INT_N9_STS_ADDR \ + (WF_PLE_TOP_BASE + 0x24) /* 0024 */ +#define WF_PLE_TOP_INT_N9_ERR_STS_ADDR \ + (WF_PLE_TOP_BASE + 0x28) /* 0028 */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_ADDR \ + (WF_PLE_TOP_BASE + 0x2C) /* 002C */ +#define WF_PLE_TOP_HOST_REPORT0_ADDR \ + (WF_PLE_TOP_BASE + 0x30) /* 0030 */ +#define WF_PLE_TOP_HOST_REPORT1_ADDR \ + (WF_PLE_TOP_BASE + 0x34) /* 0034 */ +#define WF_PLE_TOP_HOST_REPORT2_ADDR \ + (WF_PLE_TOP_BASE + 0x38) /* 0038 */ +#define WF_PLE_TOP_BLK_MODE_RATE_LMT_ADDR \ + (WF_PLE_TOP_BASE + 0x3c) /* 003C */ +#define WF_PLE_TOP_C_GET_FID_0_ADDR \ + (WF_PLE_TOP_BASE + 0x40) /* 0040 */ +#define WF_PLE_TOP_C_GET_FID_1_ADDR \ + (WF_PLE_TOP_BASE + 0x44) /* 0044 */ +#define WF_PLE_TOP_RELEASE_CTRL_0_ADDR \ + (WF_PLE_TOP_BASE + 0x50) /* 0050 */ +#define WF_PLE_TOP_RELEASE_CTRL_1_ADDR \ + (WF_PLE_TOP_BASE + 0x54) /* 0054 */ +#define WF_PLE_TOP_RELEASE_CTRL_3_ADDR \ + (WF_PLE_TOP_BASE + 0x5c) /* 005C */ +#define WF_PLE_TOP_C_EN_QUEUE_0_ADDR \ + (WF_PLE_TOP_BASE + 0x60) /* 0060 */ +#define WF_PLE_TOP_C_EN_QUEUE_1_ADDR \ + (WF_PLE_TOP_BASE + 0x64) /* 0064 */ +#define WF_PLE_TOP_C_EN_QUEUE_2_ADDR \ + (WF_PLE_TOP_BASE + 0x68) /* 0068 */ +#define WF_PLE_TOP_C_DE_QUEUE_0_ADDR \ + (WF_PLE_TOP_BASE + 0x80) /* 0080 */ +#define WF_PLE_TOP_C_DE_QUEUE_1_ADDR \ + (WF_PLE_TOP_BASE + 0x84) /* 0084 */ +#define WF_PLE_TOP_C_DE_QUEUE_2_ADDR \ + (WF_PLE_TOP_BASE + 0x88) /* 0088 */ +#define WF_PLE_TOP_C_DE_QUEUE_3_ADDR \ + (WF_PLE_TOP_BASE + 0x8c) /* 008C */ +#define WF_PLE_TOP_C_DE_QUEUE_4_ADDR \ + (WF_PLE_TOP_BASE + 0x90) /* 0090 */ +#define WF_PLE_TOP_ALLOCATE_0_ADDR \ + (WF_PLE_TOP_BASE + 0xA0) /* 00A0 */ +#define WF_PLE_TOP_ALLOCATE_1_ADDR \ + (WF_PLE_TOP_BASE + 0xA4) /* 00A4 */ +#define WF_PLE_TOP_ALLOCATE_2_ADDR \ + (WF_PLE_TOP_BASE + 0xA8) /* 00A8 */ +#define WF_PLE_TOP_QUEUE_EMPTY_ADDR \ + (WF_PLE_TOP_BASE + 0xB0) /* 00B0 */ +#define WF_PLE_TOP_FREEPG_START_END_ADDR \ + (WF_PLE_TOP_BASE + 0xc0) /* 00C0 */ +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_ADDR \ + (WF_PLE_TOP_BASE + 0xc4) /* 00C4 */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR \ + (WF_PLE_TOP_BASE + 0xd8) /* 00D8 */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR \ + (WF_PLE_TOP_BASE + 0xdc) /* 00DC */ +#define WF_PLE_TOP_TO_N9_INT_ADDR \ + (WF_PLE_TOP_BASE + 0xf0) /* 00F0 */ +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_ADDR \ + (WF_PLE_TOP_BASE + 0xf4) /* 00F4 */ +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_ADDR \ + (WF_PLE_TOP_BASE + 0xf8) /* 00F8 */ +#define WF_PLE_TOP_FREEPG_CNT_ADDR \ + (WF_PLE_TOP_BASE + 0x100) /* 0100 */ +#define WF_PLE_TOP_FREEPG_HEAD_TAIL_ADDR \ + (WF_PLE_TOP_BASE + 0x104) /* 0104 */ +#define WF_PLE_TOP_PG_HIF_GROUP_ADDR \ + (WF_PLE_TOP_BASE + 0x110) /* 0110 */ +#define WF_PLE_TOP_HIF_PG_INFO_ADDR \ + (WF_PLE_TOP_BASE + 0x114) /* 0114 */ +#define WF_PLE_TOP_PG_HIF_WMTXD_GROUP_ADDR \ + (WF_PLE_TOP_BASE + 0x118) /* 0118 */ +#define WF_PLE_TOP_HIF_WMTXD_PG_INFO_ADDR \ + (WF_PLE_TOP_BASE + 0x11C) /* 011C */ +#define WF_PLE_TOP_PG_HIF_TXCMD_GROUP_ADDR \ + (WF_PLE_TOP_BASE + 0x120) /* 0120 */ +#define WF_PLE_TOP_HIF_TXCMD_PG_INFO_ADDR \ + (WF_PLE_TOP_BASE + 0x124) /* 0124 */ +#define WF_PLE_TOP_TWT_TX_CTRL0_ADDR \ + (WF_PLE_TOP_BASE + 0x130) /* 0130 */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_ADDR \ + (WF_PLE_TOP_BASE + 0x140) /* 0140 */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_1_ADDR \ + (WF_PLE_TOP_BASE + 0x144) /* 0144 */ +#define WF_PLE_TOP_PG_CPU_GROUP_ADDR \ + (WF_PLE_TOP_BASE + 0x150) /* 0150 */ +#define WF_PLE_TOP_CPU_PG_INFO_ADDR \ + (WF_PLE_TOP_BASE + 0x154) /* 0154 */ +#define WF_PLE_TOP_PLE_LOG_0_ADDR \ + (WF_PLE_TOP_BASE + 0x170) /* 0170 */ +#define WF_PLE_TOP_PLE_LOG_1_ADDR \ + (WF_PLE_TOP_BASE + 0x174) /* 0174 */ +#define WF_PLE_TOP_PLE_LOG_2_ADDR \ + (WF_PLE_TOP_BASE + 0x178) /* 0178 */ +#define WF_PLE_TOP_PLE_LOG_3_ADDR \ + (WF_PLE_TOP_BASE + 0x17c) /* 017C */ +#define WF_PLE_TOP_WMMAC_PGCNT_0_ADDR \ + (WF_PLE_TOP_BASE + 0x180) /* 0180 */ +#define WF_PLE_TOP_WMMAC_PGCNT_1_ADDR \ + (WF_PLE_TOP_BASE + 0x184) /* 0184 */ +#define WF_PLE_TOP_WMMAC_PGCNT_2_ADDR \ + (WF_PLE_TOP_BASE + 0x188) /* 0188 */ +#define WF_PLE_TOP_WMMAC_PGCNT_3_ADDR \ + (WF_PLE_TOP_BASE + 0x18c) /* 018C */ +#define WF_PLE_TOP_WMMAC_PGCNT_4_ADDR \ + (WF_PLE_TOP_BASE + 0x190) /* 0190 */ +#define WF_PLE_TOP_WMMAC_PGCNT_5_ADDR \ + (WF_PLE_TOP_BASE + 0x194) /* 0194 */ +#define WF_PLE_TOP_WMMAC_PGCNT_6_ADDR \ + (WF_PLE_TOP_BASE + 0x198) /* 0198 */ +#define WF_PLE_TOP_WMMAC_PGCNT_7_ADDR \ + (WF_PLE_TOP_BASE + 0x19c) /* 019C */ +#define WF_PLE_TOP_RL_BUF_CTRL_0_ADDR \ + (WF_PLE_TOP_BASE + 0x1A0) /* 01A0 */ +#define WF_PLE_TOP_RL_BUF_CTRL_1_ADDR \ + (WF_PLE_TOP_BASE + 0x1A4) /* 01A4 */ +#define WF_PLE_TOP_FL_QUE_CTRL_0_ADDR \ + (WF_PLE_TOP_BASE + 0x1B0) /* 01B0 */ +#define WF_PLE_TOP_FL_QUE_CTRL_1_ADDR \ + (WF_PLE_TOP_BASE + 0x1B4) /* 01B4 */ +#define WF_PLE_TOP_FL_QUE_CTRL_2_ADDR \ + (WF_PLE_TOP_BASE + 0x1B8) /* 01B8 */ +#define WF_PLE_TOP_FL_QUE_CTRL_3_ADDR \ + (WF_PLE_TOP_BASE + 0x1BC) /* 01BC */ +#define WF_PLE_TOP_PL_QUE_CTRL_0_ADDR \ + (WF_PLE_TOP_BASE + 0x1C0) /* 01C0 */ +#define WF_PLE_TOP_PLE_DELAY_TX_CTRL_ADDR \ + (WF_PLE_TOP_BASE + 0x1d0) /* 01D0 */ +#define WF_PLE_TOP_PLE_STATION_REDIR_CTRL_ADDR \ + (WF_PLE_TOP_BASE + 0x1d4) /* 01D4 */ +#define WF_PLE_TOP_MACTX_LENGTH_LIMIT_ADDR \ + (WF_PLE_TOP_BASE + 0x1ec) /* 01EC */ +#define WF_PLE_TOP_HIF_ENQ_PKT_NUM_ADDR \ + (WF_PLE_TOP_BASE + 0x1f0) /* 01F0 */ +#define WF_PLE_TOP_CPU_ENQ_PKT_NUM_ADDR \ + (WF_PLE_TOP_BASE + 0x1f4) /* 01F4 */ +#define WF_PLE_TOP_RLS_MSDU_PKT_NUM_ADDR \ + (WF_PLE_TOP_BASE + 0x1f8) /* 01F8 */ +#define WF_PLE_TOP_HOST_REPORT_NUM_ADDR \ + (WF_PLE_TOP_BASE + 0x1fc) /* 01FC */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR \ + (WF_PLE_TOP_BASE + 0x220) /* 0220 */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_ADDR \ + (WF_PLE_TOP_BASE + 0x224) /* 0224 */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR \ + (WF_PLE_TOP_BASE + 0x228) /* 0228 */ +#define WF_PLE_TOP_UMAC_DBG_CTRL_ADDR \ + (WF_PLE_TOP_BASE + 0x240) /* 0240 */ +#define WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_ADDR \ + (WF_PLE_TOP_BASE + 0x244) /* 0244 */ +#define WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_ADDR \ + (WF_PLE_TOP_BASE + 0x248) /* 0248 */ +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_ADDR \ + (WF_PLE_TOP_BASE + 0x24C) /* 024C */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR \ + (WF_PLE_TOP_BASE + 0x250) /* 0250 */ +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_1_ADDR \ + (WF_PLE_TOP_BASE + 0x258) /* 0258 */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_ADDR \ + (WF_PLE_TOP_BASE + 0x25C) /* 025C */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL9_ADDR \ + (WF_PLE_TOP_BASE + 0x260) /* 0260 */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL10_ADDR \ + (WF_PLE_TOP_BASE + 0x264) /* 0264 */ +#define WF_PLE_TOP_FUNC_ACT_CNT_1_ADDR \ + (WF_PLE_TOP_BASE + 0x284) /* 0284 */ +#define WF_PLE_TOP_PORT_SER_CTRL_ADDR \ + (WF_PLE_TOP_BASE + 0x2A0) /* 02A0 */ +#define WF_PLE_TOP_MACTX_SER_CTRL_ADDR \ + (WF_PLE_TOP_BASE + 0x2A4) /* 02A4 */ +#define WF_PLE_TOP_DRR_SER_CTRL_ADDR \ + (WF_PLE_TOP_BASE + 0x2A8) /* 02A8 */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL5_ADDR \ + (WF_PLE_TOP_BASE + 0x2c0) /* 02C0 */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL6_ADDR \ + (WF_PLE_TOP_BASE + 0x2c4) /* 02C4 */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL7_ADDR \ + (WF_PLE_TOP_BASE + 0x2c8) /* 02C8 */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL8_ADDR \ + (WF_PLE_TOP_BASE + 0x2cc) /* 02CC */ +#define WF_PLE_TOP_SRAM_MBIST_BACKGROUND_ADDR \ + (WF_PLE_TOP_BASE + 0x2d0) /* 02D0 */ +#define WF_PLE_TOP_SRAM_MBIST_BSEL_ADDR \ + (WF_PLE_TOP_BASE + 0x2d4) /* 02D4 */ +#define WF_PLE_TOP_SRAM_MBIST_DONE_ADDR \ + (WF_PLE_TOP_BASE + 0x2d8) /* 02D8 */ +#define WF_PLE_TOP_SRAM_MBIST_FAIL_ADDR \ + (WF_PLE_TOP_BASE + 0x2dc) /* 02DC */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR \ + (WF_PLE_TOP_BASE + 0x2e0) /* 02E0 */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL1_ADDR \ + (WF_PLE_TOP_BASE + 0x2e4) /* 02E4 */ +#define WF_PLE_TOP_BSS_DBDC_CTRL_ADDR \ + (WF_PLE_TOP_BASE + 0x2ec) /* 02EC */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL2_ADDR \ + (WF_PLE_TOP_BASE + 0x2f0) /* 02F0 */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL3_ADDR \ + (WF_PLE_TOP_BASE + 0x2f4) /* 02F4 */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL4_ADDR \ + (WF_PLE_TOP_BASE + 0x2f8) /* 02F8 */ +#define WF_PLE_TOP_SRAM_AWT_HDEN_CTRL_ADDR \ + (WF_PLE_TOP_BASE + 0x2fc) /* 02FC */ +#define WF_PLE_TOP_DRR_TABLE_WDATA0_ADDR \ + (WF_PLE_TOP_BASE + 0x340) /* 0340 */ +#define WF_PLE_TOP_DRR_TABLE_WDATA1_ADDR \ + (WF_PLE_TOP_BASE + 0x344) /* 0344 */ +#define WF_PLE_TOP_DRR_TABLE_WDATA2_ADDR \ + (WF_PLE_TOP_BASE + 0x348) /* 0348 */ +#define WF_PLE_TOP_DRR_TABLE_WDATA3_ADDR \ + (WF_PLE_TOP_BASE + 0x34c) /* 034C */ +#define WF_PLE_TOP_DRR_TABLE_RDATA0_ADDR \ + (WF_PLE_TOP_BASE + 0x350) /* 0350 */ +#define WF_PLE_TOP_DRR_TABLE_RDATA1_ADDR \ + (WF_PLE_TOP_BASE + 0x354) /* 0354 */ +#define WF_PLE_TOP_DRR_TABLE_RDATA2_ADDR \ + (WF_PLE_TOP_BASE + 0x358) /* 0358 */ +#define WF_PLE_TOP_DRR_TABLE_RDATA3_ADDR \ + (WF_PLE_TOP_BASE + 0x35c) /* 035C */ +#define WF_PLE_TOP_VOW_CONTROL_ADDR \ + (WF_PLE_TOP_BASE + 0x370) /* 0370 */ +#define WF_PLE_TOP_AIRTIME_DRR_SIZE_ADDR \ + (WF_PLE_TOP_BASE + 0x374) /* 0374 */ +#define WF_PLE_TOP_CHECK_BW_TIME_TOKEN__ADDR \ + (WF_PLE_TOP_BASE + 0x378) /* 0378 */ +#define WF_PLE_TOP_CHECK_BW_LENGTH_TOKEN__ADDR \ + (WF_PLE_TOP_BASE + 0x37c) /* 037C */ +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_ADDR \ + (WF_PLE_TOP_BASE + 0x380) /* 0380 */ +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_ADDR \ + (WF_PLE_TOP_BASE + 0x384) /* 0384 */ +#define WF_PLE_TOP_DRR_TABLE_CTRL_ADDR \ + (WF_PLE_TOP_BASE + 0x388) /* 0388 */ +#define WF_PLE_TOP_VOW_CTRL1_ADDR \ + (WF_PLE_TOP_BASE + 0x38C) /* 038C */ +#define WF_PLE_TOP_DRR_CHNL_EMPTY_ADDR \ + (WF_PLE_TOP_BASE + 0x390) /* 0390 */ +#define WF_PLE_TOP_DRR_SPL_CTRL_ADDR \ + (WF_PLE_TOP_BASE + 0x394) /* 0394 */ +#define WF_PLE_TOP_DRR_SPL_CTRL_1_ADDR \ + (WF_PLE_TOP_BASE + 0x398) /* 0398 */ +#define WF_PLE_TOP_VOW_DBG_SEL_ADDR \ + (WF_PLE_TOP_BASE + 0x3A0) /* 03A0 */ +#define WF_PLE_TOP_AIRTIME_DBG_INFO0_ADDR \ + (WF_PLE_TOP_BASE + 0x3A4) /* 03A4 */ +#define WF_PLE_TOP_AIRTIME_DBG_INFO1_ADDR \ + (WF_PLE_TOP_BASE + 0x3A8) /* 03A8 */ +#define WF_PLE_TOP_DRR_SW_CTRL_ADDR \ + (WF_PLE_TOP_BASE + 0x3C8) /* 03C8 */ +#define WF_PLE_TOP_DRR_HW_SRCHCMD_FULL_ADDR \ + (WF_PLE_TOP_BASE + 0x3CC) /* 03CC */ +#define WF_PLE_TOP_STATION_PAUSE0_ADDR \ + (WF_PLE_TOP_BASE + 0x400) /* 0400 */ +#define WF_PLE_TOP_DIS_STA_MAP0_ADDR \ + (WF_PLE_TOP_BASE + 0x440) /* 0440 */ +#define WF_PLE_TOP_STATION_REDIR0_ADDR \ + (WF_PLE_TOP_BASE + 0x480) /* 0480 */ +#define WF_PLE_TOP_TWT_STA_MAP0_ADDR \ + (WF_PLE_TOP_BASE + 0x4c0) /* 04C0 */ +#define WF_PLE_TOP_AC0_QUEUE_EMPTY0_ADDR \ + (WF_PLE_TOP_BASE + 0x500) /* 0500 */ +#define WF_PLE_TOP_AC1_QUEUE_EMPTY0_ADDR \ + (WF_PLE_TOP_BASE + 0x540) /* 0540 */ +#define WF_PLE_TOP_AC2_QUEUE_EMPTY0_ADDR \ + (WF_PLE_TOP_BASE + 0x580) /* 0580 */ +#define WF_PLE_TOP_AC3_QUEUE_EMPTY0_ADDR \ + (WF_PLE_TOP_BASE + 0x5c0) /* 05C0 */ +#define WF_PLE_TOP_DRR_TABLE_WDATA4_ADDR \ + (WF_PLE_TOP_BASE + 0x680) /* 0680 */ +#define WF_PLE_TOP_DRR_TABLE_WDATA5_ADDR \ + (WF_PLE_TOP_BASE + 0x684) /* 0684 */ +#define WF_PLE_TOP_DRR_TABLE_WDATA6_ADDR \ + (WF_PLE_TOP_BASE + 0x688) /* 0688 */ +#define WF_PLE_TOP_DRR_TABLE_WDATA7_ADDR \ + (WF_PLE_TOP_BASE + 0x68c) /* 068C */ +#define WF_PLE_TOP_DRR_TABLE_RDATA4_ADDR \ + (WF_PLE_TOP_BASE + 0x690) /* 0690 */ +#define WF_PLE_TOP_DRR_TABLE_RDATA5_ADDR \ + (WF_PLE_TOP_BASE + 0x694) /* 0694 */ +#define WF_PLE_TOP_DRR_TABLE_RDATA6_ADDR \ + (WF_PLE_TOP_BASE + 0x698) /* 0698 */ +#define WF_PLE_TOP_DRR_TABLE_RDATA7_ADDR \ + (WF_PLE_TOP_BASE + 0x69c) /* 069C */ +#define WF_PLE_TOP_TWT_STA_TABLE0_ADDR \ + (WF_PLE_TOP_BASE + 0x6a0) /* 06A0 */ +#define WF_PLE_TOP_TWT_STA_TABLE1_ADDR \ + (WF_PLE_TOP_BASE + 0x6a4) /* 06A4 */ +#define WF_PLE_TOP_TWT_STA_TABLE2_ADDR \ + (WF_PLE_TOP_BASE + 0x6a8) /* 06A8 */ +#define WF_PLE_TOP_TWT_STA_TABLE3_ADDR \ + (WF_PLE_TOP_BASE + 0x6ac) /* 06AC */ +#define WF_PLE_TOP_TWT_SW_CTRL_ADDR \ + (WF_PLE_TOP_BASE + 0x6b0) /* 06B0 */ +#define WF_PLE_TOP_TWT_DBG_ADDR (WF_PLE_TOP_BASE + 0x6b4) /* 06B4 */ +#define WF_PLE_TOP_TWT_HW_SRCHCMD_FULL_ADDR \ + (WF_PLE_TOP_BASE + 0x6b8) /* 06B8 */ +#define WF_PLE_TOP_AMSDU_GC_ADDR \ + (WF_PLE_TOP_BASE + 0x1000) /* 1000 */ +#define WF_PLE_TOP_AMSDU_TXD_COMP_MAP_0_ADDR \ + (WF_PLE_TOP_BASE + 0x1004) /* 1004 */ +#define WF_PLE_TOP_AMSDU_TXD_COMP_MAP_1_ADDR \ + (WF_PLE_TOP_BASE + 0x1008) /* 1008 */ +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_ADDR \ + (WF_PLE_TOP_BASE + 0x1028) /* 1028 */ +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_ADDR \ + (WF_PLE_TOP_BASE + 0x102C) /* 102C */ +#define WF_PLE_TOP_AMSDU_PEEK_CR_00_ADDR \ + (WF_PLE_TOP_BASE + 0x10d0) /* 10D0 */ +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_ADDR \ + (WF_PLE_TOP_BASE + 0x10d4) /* 10D4 */ +#define WF_PLE_TOP_AMSDU_PACK_1_MSDU_CNT_ADDR \ + (WF_PLE_TOP_BASE + 0x10e0) /* 10E0 */ +#define WF_PLE_TOP_AMSDU_PACK_2_MSDU_CNT_ADDR \ + (WF_PLE_TOP_BASE + 0x10e4) /* 10E4 */ +#define WF_PLE_TOP_AMSDU_PACK_3_MSDU_CNT_ADDR \ + (WF_PLE_TOP_BASE + 0x10e8) /* 10E8 */ +#define WF_PLE_TOP_AMSDU_PACK_4_MSDU_CNT_ADDR \ + (WF_PLE_TOP_BASE + 0x10ec) /* 10EC */ +#define WF_PLE_TOP_AMSDU_PACK_5_MSDU_CNT_ADDR \ + (WF_PLE_TOP_BASE + 0x10f0) /* 10F0 */ +#define WF_PLE_TOP_AMSDU_PACK_6_MSDU_CNT_ADDR \ + (WF_PLE_TOP_BASE + 0x10f4) /* 10F4 */ +#define WF_PLE_TOP_AMSDU_PACK_7_MSDU_CNT_ADDR \ + (WF_PLE_TOP_BASE + 0x10f8) /* 10F8 */ +#define WF_PLE_TOP_AMSDU_PACK_8_MSDU_CNT_ADDR \ + (WF_PLE_TOP_BASE + 0x10fc) /* 10FC */ +#define WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY0_ADDR \ + (WF_PLE_TOP_BASE + 0x1100) /* 1100 */ +#define WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY0_ADDR \ + (WF_PLE_TOP_BASE + 0x1140) /* 1140 */ +#define WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY0_ADDR \ + (WF_PLE_TOP_BASE + 0x1180) /* 1180 */ +#define WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY0_ADDR \ + (WF_PLE_TOP_BASE + 0x11C0) /* 11C0 */ +#define WF_PLE_TOP_CFG_DBDC_CTRL0_ADDR \ + (WF_PLE_TOP_BASE + 0x2008) /* 2008 */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_ADDR \ + (WF_PLE_TOP_BASE + 0x2480) /* 2480 */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_1_ADDR \ + (WF_PLE_TOP_BASE + 0x2484) /* 2484 */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_2_ADDR \ + (WF_PLE_TOP_BASE + 0x2488) /* 2488 */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_3_ADDR \ + (WF_PLE_TOP_BASE + 0x248c) /* 248C */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_4_ADDR \ + (WF_PLE_TOP_BASE + 0x2490) /* 2490 */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_ADDR \ + (WF_PLE_TOP_BASE + 0x2494) /* 2494 */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_6_ADDR \ + (WF_PLE_TOP_BASE + 0x2498) /* 2498 */ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_ADDR \ + (WF_PLE_TOP_BASE + 0x25c0) /* 25C0 */ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_1_ADDR \ + (WF_PLE_TOP_BASE + 0x25c4) /* 25C4 */ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_2_ADDR \ + (WF_PLE_TOP_BASE + 0x25c8) /* 25C8 */ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_3_ADDR \ + (WF_PLE_TOP_BASE + 0x25cc) /* 25CC */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_ADDR \ + (WF_PLE_TOP_BASE + 0x25e0) /* 25E0 */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_1_ADDR \ + (WF_PLE_TOP_BASE + 0x25e4) /* 25E4 */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_2_ADDR \ + (WF_PLE_TOP_BASE + 0x25e8) /* 25E8 */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_3_ADDR \ + (WF_PLE_TOP_BASE + 0x25ec) /* 25EC */ +#define WF_PLE_TOP_SYSRAM_MBIST_CTRL_ADDR \ + (WF_PLE_TOP_BASE + 0x3004) /* 3004 */ +#define WF_PLE_TOP_SYSRAM_MBIST_DEBUG_ADDR \ + (WF_PLE_TOP_BASE + 0x3008) /* 3008 */ +#define WF_PLE_TOP_SYSRAM_MBIST_MODE_ADDR \ + (WF_PLE_TOP_BASE + 0x300C) /* 300C */ +#define WF_PLE_TOP_SYSRAM_MBIST_HOLDB_ADDR \ + (WF_PLE_TOP_BASE + 0x3010) /* 3010 */ +#define WF_PLE_TOP_SYSRAM_MBIST_DONE_ADDR \ + (WF_PLE_TOP_BASE + 0x3014) /* 3014 */ +#define WF_PLE_TOP_SYSRAM_MBIST_FAIL_ADDR \ + (WF_PLE_TOP_BASE + 0x3018) /* 3018 */ +#define WF_PLE_TOP_SYSRAM_MBIST_SLEEP_TEST_ADDR \ + (WF_PLE_TOP_BASE + 0x301C) /* 301C */ +#define WF_PLE_TOP_SYSRAM_MBIST_SLEEP_INV_ADDR \ + (WF_PLE_TOP_BASE + 0x3020) /* 3020 */ +#define WF_PLE_TOP_SYSRAM_MBIST_SLEEP_W_ADDR \ + (WF_PLE_TOP_BASE + 0x3024) /* 3024 */ +#define WF_PLE_TOP_SYSRAM_MBIST_SLEEP_R_ADDR \ + (WF_PLE_TOP_BASE + 0x3028) /* 3028 */ +#define WF_PLE_TOP_SYSRAM_AWT_HDEN_ADDR \ + (WF_PLE_TOP_BASE + 0x302C) /* 302C */ +#define WF_PLE_TOP_SYSRAM_DBG_SEL_ADDR \ + (WF_PLE_TOP_BASE + 0x3030) /* 3030 */ +#define WF_PLE_TOP_SYSRAM_DELSEL_ADDR \ + (WF_PLE_TOP_BASE + 0x3070) /* 3070 */ +#define WF_PLE_TOP_SYSRAM_DELSEL_1_ADDR \ + (WF_PLE_TOP_BASE + 0x3074) /* 3074 */ +#define WF_PLE_TOP_SYSRAM_DELSEL_2_ADDR \ + (WF_PLE_TOP_BASE + 0x3078) /* 3078 */ +#define WF_PLE_TOP_SYSRAM_DELSEL_3_ADDR \ + (WF_PLE_TOP_BASE + 0x307C) /* 307C */ +#define WF_PLE_TOP_SYSRAM_OUTRAN_ERR_FLAG_ADDR \ + (WF_PLE_TOP_BASE + 0x3080) /* 3080 */ + +/* +* ---GC (0x820C0000 + 0x00)--- +* ALL_RESET[0] - (RW) Resets PLE logic and register +* LOGIC_RESET[1] - (RW) Resets PLE logic circuit +* INIT_DONE[2] - (RO) PLE control SRAM initialization +indicator +* UMAC_CFG_LOGIC_RESET[3] - (RW) Resets PF/MDP/SEC/UWTBL logic circuit +* RESERVED4[15..4] - (RO) Reserved bits +* SRAM_MBIST_G1_RESET[16] - (RW) Reset control of group 1 SRAM MBIST +* SRAM_MBIST_G2_RESET[17] - (RW) Reset control of group 2 SRAM MBIST +* DIS_PLE_DYN_CKG[18] - (RW) Disable control of wf_ple_top dynamic +* clock gating function +* RESERVED19[31..19] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_GC_DIS_PLE_DYN_CKG_ADDR WF_PLE_TOP_GC_ADDR +#define WF_PLE_TOP_GC_DIS_PLE_DYN_CKG_MASK \ + 0x00040000 /* DIS_PLE_DYN_CKG[18] */ +#define WF_PLE_TOP_GC_DIS_PLE_DYN_CKG_SHFT 18 +#define WF_PLE_TOP_GC_SRAM_MBIST_G2_RESET_ADDR WF_PLE_TOP_GC_ADDR +#define WF_PLE_TOP_GC_SRAM_MBIST_G2_RESET_MASK \ + 0x00020000 /* SRAM_MBIST_G2_RESET[17] */ +#define WF_PLE_TOP_GC_SRAM_MBIST_G2_RESET_SHFT 17 +#define WF_PLE_TOP_GC_SRAM_MBIST_G1_RESET_ADDR WF_PLE_TOP_GC_ADDR +#define WF_PLE_TOP_GC_SRAM_MBIST_G1_RESET_MASK \ + 0x00010000 /* SRAM_MBIST_G1_RESET[16] */ +#define WF_PLE_TOP_GC_SRAM_MBIST_G1_RESET_SHFT 16 +#define WF_PLE_TOP_GC_UMAC_CFG_LOGIC_RESET_ADDR WF_PLE_TOP_GC_ADDR +#define WF_PLE_TOP_GC_UMAC_CFG_LOGIC_RESET_MASK \ + 0x00000008 /* UMAC_CFG_LOGIC_RESET[3] */ +#define WF_PLE_TOP_GC_UMAC_CFG_LOGIC_RESET_SHFT 3 +#define WF_PLE_TOP_GC_INIT_DONE_ADDR WF_PLE_TOP_GC_ADDR +#define WF_PLE_TOP_GC_INIT_DONE_MASK 0x00000004 /* INIT_DONE[2] */ +#define WF_PLE_TOP_GC_INIT_DONE_SHFT 2 +#define WF_PLE_TOP_GC_LOGIC_RESET_ADDR WF_PLE_TOP_GC_ADDR +#define WF_PLE_TOP_GC_LOGIC_RESET_MASK 0x00000002 /* LOGIC_RESET[1] */ +#define WF_PLE_TOP_GC_LOGIC_RESET_SHFT 1 +#define WF_PLE_TOP_GC_ALL_RESET_ADDR WF_PLE_TOP_GC_ADDR +#define WF_PLE_TOP_GC_ALL_RESET_MASK 0x00000001 /* ALL_RESET[0] */ +#define WF_PLE_TOP_GC_ALL_RESET_SHFT 0 + +/* +* ---PBUF_CTRL (0x820C0000 + 0x14)--- +* TOTAL_PAGE_NUM[11..0] - (RW) Total page number +* Set the total page before release PLE logic +* reset, and must not be changed after release logic reset. +* RESERVED12[16..12] - (RO) Reserved bits +* PBUF_OFFSET[25..17] - (RW) Packet buffer offset +* Set up the buffer offset before releasing +* PLE logic reset; it should not be changed after logic reset is +released. +* RESERVED26[30..26] - (RO) Reserved bits +* PAGE_SIZE_CFG[31] - (RW) Configures page size +* Set up the page size before releasing PLE +* logic reset; it should not be changed after logic reset is released. +*/ +#define WF_PLE_TOP_PBUF_CTRL_PAGE_SIZE_CFG_ADDR \ + WF_PLE_TOP_PBUF_CTRL_ADDR +#define WF_PLE_TOP_PBUF_CTRL_PAGE_SIZE_CFG_MASK \ + 0x80000000 /* PAGE_SIZE_CFG[31] */ +#define WF_PLE_TOP_PBUF_CTRL_PAGE_SIZE_CFG_SHFT 31 +#define WF_PLE_TOP_PBUF_CTRL_PBUF_OFFSET_ADDR \ + WF_PLE_TOP_PBUF_CTRL_ADDR +#define WF_PLE_TOP_PBUF_CTRL_PBUF_OFFSET_MASK \ + 0x03FE0000 /* PBUF_OFFSET[25..17] */ +#define WF_PLE_TOP_PBUF_CTRL_PBUF_OFFSET_SHFT 17 +#define WF_PLE_TOP_PBUF_CTRL_TOTAL_PAGE_NUM_ADDR \ + WF_PLE_TOP_PBUF_CTRL_ADDR +#define WF_PLE_TOP_PBUF_CTRL_TOTAL_PAGE_NUM_MASK \ + 0x00000FFF /* TOTAL_PAGE_NUM[11..0] */ +#define WF_PLE_TOP_PBUF_CTRL_TOTAL_PAGE_NUM_SHFT 0 + +/* +* ---TIMEOUT_CTRL (0x820C0000 + 0x1c)--- +* RESERVED0[7..0] - (RO) Reserved bits +* HOST_REPORT_TO_CTRL[15..8] - (RW) HOST report timeout control +register +* APB_WD_TO_CTRL[23..16] - (RW) APB pready watch dog timeout control +register +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_TIMEOUT_CTRL_APB_WD_TO_CTRL_ADDR \ + WF_PLE_TOP_TIMEOUT_CTRL_ADDR +#define WF_PLE_TOP_TIMEOUT_CTRL_APB_WD_TO_CTRL_MASK \ + 0x00FF0000 /* APB_WD_TO_CTRL[23..16] */ +#define WF_PLE_TOP_TIMEOUT_CTRL_APB_WD_TO_CTRL_SHFT 16 +#define WF_PLE_TOP_TIMEOUT_CTRL_HOST_REPORT_TO_CTRL_ADDR \ + WF_PLE_TOP_TIMEOUT_CTRL_ADDR +#define WF_PLE_TOP_TIMEOUT_CTRL_HOST_REPORT_TO_CTRL_MASK \ + 0x0000FF00 /* HOST_REPORT_TO_CTRL[15..8] */ +#define WF_PLE_TOP_TIMEOUT_CTRL_HOST_REPORT_TO_CTRL_SHFT 8 + +/* +* ---INT_N9_EN_MASK (0x820C0000 + 0x20)--- +* EN_CPU_Q0_NE[0] - (RW) Enable control of interrupt for CPU +* queue 0 not empty +* EN_CPU_Q1_NE[1] - (RW) Enable control of interrupt for CPU +* queue 1 not empty +* EN_CPU_Q2_NE[2] - (RW) Enable control of interrupt for CPU +* queue 2 not empty +* EN_CPU_Q3_NE[3] - (RW) Enable control of interrupt for CPU +* queue 3 not empty +* RESERVED4[15..4] - (RO) Reserved bits +* EN_TOGGLE_INT[16] - (RW) Enable control of interrupt for data +* toggle of N9 toggle register (0xf0) +* RESERVED17[17] - (RO) Reserved bits +* EN_UMAC_SYSRAM_OUTRAN_ERROR_INT[18] - (RW) Enable control of +* interrupt for +* UMAC SYSRAM out range error +* RESERVED19[19] - (RO) Reserved bits +* EN_AC_NONEMPTY_INT[20] - (RW) Enable control of AC queue empty fail +interrupt +* EN_AC_EMPTY_INT[21] - (RW) Enable control of AC queue empty raise +interrupt +* EN_AC_ENQ_LMAC_INT[22] - (RW) Enable control of AC enqueue interrupt +* RESERVED23[23] - (RO) Reserved bits +* EN_DBDC0_NONEMPTY_INT[24] - (RW) Enable control of DBDC0 queue empty +fail +interrupt +* EN_DBDC0_EMPTY_INT[25] - (RW) Enable control of DBDC0 queue empty +* raise interrupt +* EN_DBDC0_ENQ_LMAC_INT[26] - (RW) Enable control of DBDC0 enqueue +interrupt +* RESERVED27[27] - (RO) Reserved bits +* EN_DBDC1_NONEMPTY_INT[28] - (RW) Enable control of DBDC1 queue empty +fail +interrupt +* EN_DBDC1_EMPTY_INT[29] - (RW) Enable control of DBDC1 queue empty +* raise interrupt +* EN_DBDC1_ENQ_LMAC_INT[30] - (RW) Enable control of DBDC1 enqueue +interrupt +* RESERVED31[31] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC1_ENQ_LMAC_INT_ADDR \ + WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC1_ENQ_LMAC_INT_MASK \ + 0x40000000 /* EN_DBDC1_ENQ_LMAC_INT[30] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC1_ENQ_LMAC_INT_SHFT 30 +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC1_EMPTY_INT_ADDR \ + WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC1_EMPTY_INT_MASK \ + 0x20000000 /* EN_DBDC1_EMPTY_INT[29] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC1_EMPTY_INT_SHFT 29 +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC1_NONEMPTY_INT_ADDR \ + WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC1_NONEMPTY_INT_MASK \ + 0x10000000 /* EN_DBDC1_NONEMPTY_INT[28] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC1_NONEMPTY_INT_SHFT 28 +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC0_ENQ_LMAC_INT_ADDR \ + WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC0_ENQ_LMAC_INT_MASK \ + 0x04000000 /* EN_DBDC0_ENQ_LMAC_INT[26] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC0_ENQ_LMAC_INT_SHFT 26 +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC0_EMPTY_INT_ADDR \ + WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC0_EMPTY_INT_MASK \ + 0x02000000 /* EN_DBDC0_EMPTY_INT[25] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC0_EMPTY_INT_SHFT 25 +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC0_NONEMPTY_INT_ADDR \ + WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC0_NONEMPTY_INT_MASK \ + 0x01000000 /* EN_DBDC0_NONEMPTY_INT[24] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_DBDC0_NONEMPTY_INT_SHFT 24 +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_AC_ENQ_LMAC_INT_ADDR \ + WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_AC_ENQ_LMAC_INT_MASK \ + 0x00400000 /* EN_AC_ENQ_LMAC_INT[22] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_AC_ENQ_LMAC_INT_SHFT 22 +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_AC_EMPTY_INT_ADDR \ + WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_AC_EMPTY_INT_MASK \ + 0x00200000 /* EN_AC_EMPTY_INT[21] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_AC_EMPTY_INT_SHFT 21 +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_AC_NONEMPTY_INT_ADDR \ + WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_AC_NONEMPTY_INT_MASK \ + 0x00100000 /* EN_AC_NONEMPTY_INT[20] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_AC_NONEMPTY_INT_SHFT 20 +#define \ +WF_PLE_TOP_INT_N9_EN_MASK_EN_UMAC_SYSRAM_OUTRAN_ERROR_INT_ADDR \ + WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define \ +WF_PLE_TOP_INT_N9_EN_MASK_EN_UMAC_SYSRAM_OUTRAN_ERROR_INT_MASK \ + 0x00040000 /* EN_UMAC_SYSRAM_OUTRAN_ERROR_INT[18] */ +#define \ +WF_PLE_TOP_INT_N9_EN_MASK_EN_UMAC_SYSRAM_OUTRAN_ERROR_INT_SHFT \ + 18 +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_TOGGLE_INT_ADDR \ + WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_TOGGLE_INT_MASK \ + 0x00010000 /* EN_TOGGLE_INT[16] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_TOGGLE_INT_SHFT 16 +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_CPU_Q3_NE_ADDR \ + WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_CPU_Q3_NE_MASK \ + 0x00000008 /* EN_CPU_Q3_NE[3] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_CPU_Q3_NE_SHFT 3 +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_CPU_Q2_NE_ADDR \ + WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_CPU_Q2_NE_MASK \ + 0x00000004 /* EN_CPU_Q2_NE[2] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_CPU_Q2_NE_SHFT 2 +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_CPU_Q1_NE_ADDR \ + WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_CPU_Q1_NE_MASK \ + 0x00000002 /* EN_CPU_Q1_NE[1] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_CPU_Q1_NE_SHFT 1 +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_CPU_Q0_NE_ADDR \ + WF_PLE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_CPU_Q0_NE_MASK \ + 0x00000001 /* EN_CPU_Q0_NE[0] */ +#define WF_PLE_TOP_INT_N9_EN_MASK_EN_CPU_Q0_NE_SHFT 0 + +/* +* ---INT_N9_STS (0x820C0000 + 0x24)--- +* CPU_Q0_NE[0] - (W1C) CPU queue 0 not empty interrupt status +* CPU_Q1_NE[1] - (W1C) CPU queue 1 not empty interrupt status +* CPU_Q2_NE[2] - (W1C) CPU queue 2 not empty interrupt status +* CPU_Q3_NE[3] - (W1C) CPU queue 3 not empty interrupt status +* RESERVED4[12..4] - (RO) Reserved bits +* ERROR_INT[13] - (RO) Error condition interrupt status, define +* by 0x28 +* ERROR_INT_1[14] - (RO) Error condition interrupt status 1, +* define by 0xd8 +* AMSDU_ERROR_INT[15] - (RO) HW AMSDU Error condition interrupt +* status, define by 0x1028 +* DATA_TOGGLE[16] - (W1C) Interrupt status of data toggle of N9 +* toggle register (0xf0) +* RESERVED17[17] - (RO) Reserved bits +* UMAC_SYSRAM_OUTRAN_ERROR_INT[18] - (W1C) Interrupt status of UMAC +* SYSRAM out +* range error +* RESERVED19[19] - (RO) Reserved bits +* AC_NONEMPTY_INT[20] - (W1C) AC queue empty fail interrupt status +* AC_EMPTY_INT[21] - (W1C) AC queue empty raise interrupt status +* AC_ENQ_LMAC_INT[22] - (W1C) AC enqueue interrupt status +* RESERVED23[23] - (RO) Reserved bits +* DBDC0_NONEMPTY_INT[24] - (W1C) DBDC0 queue empty fail interrupt +status +* DBDC0_EMPTY_INT[25] - (W1C) DBDC0 queue empty raise interrupt +status +* DBDC0_ENQ_LMAC_INT[26] - (W1C) DBDC0 enqueue interrupt status +* RESERVED27[27] - (RO) Reserved bits +* DBDC1_NONEMPTY_INT[28] - (W1C) DBDC1 queue empty fail interrupt +status +* DBDC1_EMPTY_INT[29] - (W1C) DBDC1 queue empty raise interrupt +status +* DBDC1_ENQ_LMAC_INT[30] - (W1C) DBDC1 enqueue interrupt status +* RESERVED31[31] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_INT_N9_STS_DBDC1_ENQ_LMAC_INT_ADDR \ + WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_DBDC1_ENQ_LMAC_INT_MASK \ + 0x40000000 /* DBDC1_ENQ_LMAC_INT[30] */ +#define WF_PLE_TOP_INT_N9_STS_DBDC1_ENQ_LMAC_INT_SHFT 30 +#define WF_PLE_TOP_INT_N9_STS_DBDC1_EMPTY_INT_ADDR \ + WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_DBDC1_EMPTY_INT_MASK \ + 0x20000000 /* DBDC1_EMPTY_INT[29] */ +#define WF_PLE_TOP_INT_N9_STS_DBDC1_EMPTY_INT_SHFT 29 +#define WF_PLE_TOP_INT_N9_STS_DBDC1_NONEMPTY_INT_ADDR \ + WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_DBDC1_NONEMPTY_INT_MASK \ + 0x10000000 /* DBDC1_NONEMPTY_INT[28] */ +#define WF_PLE_TOP_INT_N9_STS_DBDC1_NONEMPTY_INT_SHFT 28 +#define WF_PLE_TOP_INT_N9_STS_DBDC0_ENQ_LMAC_INT_ADDR \ + WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_DBDC0_ENQ_LMAC_INT_MASK \ + 0x04000000 /* DBDC0_ENQ_LMAC_INT[26] */ +#define WF_PLE_TOP_INT_N9_STS_DBDC0_ENQ_LMAC_INT_SHFT 26 +#define WF_PLE_TOP_INT_N9_STS_DBDC0_EMPTY_INT_ADDR \ + WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_DBDC0_EMPTY_INT_MASK \ + 0x02000000 /* DBDC0_EMPTY_INT[25] */ +#define WF_PLE_TOP_INT_N9_STS_DBDC0_EMPTY_INT_SHFT 25 +#define WF_PLE_TOP_INT_N9_STS_DBDC0_NONEMPTY_INT_ADDR \ + WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_DBDC0_NONEMPTY_INT_MASK \ + 0x01000000 /* DBDC0_NONEMPTY_INT[24] */ +#define WF_PLE_TOP_INT_N9_STS_DBDC0_NONEMPTY_INT_SHFT 24 +#define WF_PLE_TOP_INT_N9_STS_AC_ENQ_LMAC_INT_ADDR \ + WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_AC_ENQ_LMAC_INT_MASK \ + 0x00400000 /* AC_ENQ_LMAC_INT[22] */ +#define WF_PLE_TOP_INT_N9_STS_AC_ENQ_LMAC_INT_SHFT 22 +#define WF_PLE_TOP_INT_N9_STS_AC_EMPTY_INT_ADDR \ + WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_AC_EMPTY_INT_MASK \ + 0x00200000 /* AC_EMPTY_INT[21] */ +#define WF_PLE_TOP_INT_N9_STS_AC_EMPTY_INT_SHFT 21 +#define WF_PLE_TOP_INT_N9_STS_AC_NONEMPTY_INT_ADDR \ + WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_AC_NONEMPTY_INT_MASK \ + 0x00100000 /* AC_NONEMPTY_INT[20] */ +#define WF_PLE_TOP_INT_N9_STS_AC_NONEMPTY_INT_SHFT 20 +#define WF_PLE_TOP_INT_N9_STS_UMAC_SYSRAM_OUTRAN_ERROR_INT_ADDR \ + WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_UMAC_SYSRAM_OUTRAN_ERROR_INT_MASK \ + 0x00040000 /* UMAC_SYSRAM_OUTRAN_ERROR_INT[18] */ +#define WF_PLE_TOP_INT_N9_STS_UMAC_SYSRAM_OUTRAN_ERROR_INT_SHFT 18 +#define WF_PLE_TOP_INT_N9_STS_DATA_TOGGLE_ADDR \ + WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_DATA_TOGGLE_MASK \ + 0x00010000 /* DATA_TOGGLE[16] */ +#define WF_PLE_TOP_INT_N9_STS_DATA_TOGGLE_SHFT 16 +#define WF_PLE_TOP_INT_N9_STS_AMSDU_ERROR_INT_ADDR \ + WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_AMSDU_ERROR_INT_MASK \ + 0x00008000 /* AMSDU_ERROR_INT[15] */ +#define WF_PLE_TOP_INT_N9_STS_AMSDU_ERROR_INT_SHFT 15 +#define WF_PLE_TOP_INT_N9_STS_ERROR_INT_1_ADDR \ + WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_ERROR_INT_1_MASK \ + 0x00004000 /* ERROR_INT_1[14] */ +#define WF_PLE_TOP_INT_N9_STS_ERROR_INT_1_SHFT 14 +#define WF_PLE_TOP_INT_N9_STS_ERROR_INT_ADDR \ + WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_ERROR_INT_MASK \ + 0x00002000 /* ERROR_INT[13] */ +#define WF_PLE_TOP_INT_N9_STS_ERROR_INT_SHFT 13 +#define WF_PLE_TOP_INT_N9_STS_CPU_Q3_NE_ADDR \ + WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_CPU_Q3_NE_MASK \ + 0x00000008 /* CPU_Q3_NE[3] */ +#define WF_PLE_TOP_INT_N9_STS_CPU_Q3_NE_SHFT 3 +#define WF_PLE_TOP_INT_N9_STS_CPU_Q2_NE_ADDR \ + WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_CPU_Q2_NE_MASK \ + 0x00000004 /* CPU_Q2_NE[2] */ +#define WF_PLE_TOP_INT_N9_STS_CPU_Q2_NE_SHFT 2 +#define WF_PLE_TOP_INT_N9_STS_CPU_Q1_NE_ADDR \ + WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_CPU_Q1_NE_MASK \ + 0x00000002 /* CPU_Q1_NE[1] */ +#define WF_PLE_TOP_INT_N9_STS_CPU_Q1_NE_SHFT 1 +#define WF_PLE_TOP_INT_N9_STS_CPU_Q0_NE_ADDR \ + WF_PLE_TOP_INT_N9_STS_ADDR +#define WF_PLE_TOP_INT_N9_STS_CPU_Q0_NE_MASK \ + 0x00000001 /* CPU_Q0_NE[0] */ +#define WF_PLE_TOP_INT_N9_STS_CPU_Q0_NE_SHFT 0 + +/* +* ---INT_N9_ERR_STS (0x820C0000 + 0x28)--- +* Q_CMD_ERR_P0[0] - (W1C) Queue command error interrupt status of +* port 0. Avoid unclear error flag, please clear flag when logic +reset. +* Q_CMD_ERR_P1[1] - (W1C) Queue command error interrupt status of +* port 1. Avoid unclear error flag, please clear flag when logic +reset. +* Q_CMD_ERR_P2[2] - (W1C) Queue command error interrupt status of +* port 2. Avoid unclear error flag, please clear flag when logic +reset. +* PAGE_UDF_P0[3] - (W1C) Page underflow interrupt status of port +* 0. Avoid unclear error flag, please clear flag when logic reset. +* PAGE_UDF_P1[4] - (W1C) Page underflow interrupt status of port +* 1. Avoid unclear error flag, please clear flag when logic reset. +* PAGE_UDF_P2[5] - (W1C) Page underflow interrupt status of port +* 2. Avoid unclear error flag, please clear flag when logic reset. +* DOUBLE_RLS_ERR[6] - (W1C) Double release error interrupt. Avoid +* unclear error flag, please clear flag when logic reset. +* MDP_D_OPER_ERR[7] - (W1C) MDP data operation error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* MDP_HANG_ERR[8] - (W1C) MDP FSM Hang error interrupt. Avoid +* unclear error flag, please clear flag when logic reset. +* RESERVED9[9] - (RO) Reserved bits +* DATA_OPER_ERR_P0[10] - (W1C) Data operation error of port 0. Avoid +* unclear error flag, please clear flag when logic reset. +* DATA_OPER_ERR_P1[11] - (W1C) Data operation error of port 1. Avoid +* unclear error flag, please clear flag when logic reset. +* DATA_OPER_ERR_P2[12] - (W1C) Data operation error of port 2. Avoid +* unclear error flag, please clear flag when logic reset. +* FL_HANG_ERR[13] - (W1C) Frame link FSM hang error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* PL_HANG_ERR[14] - (W1C) Page link FSM hang error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* HIF_HANG_ERR[15] - (W1C) HIF port FSM hang error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* CPU_HANG_ERR[16] - (W1C) CPU port FSM hang error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* LMAC_HANG_ERR[17] - (W1C) LMAC port FSM hang error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* FREE_HEAD_TAIL_ERR[18] - (W1C) Free head/tail error interrupt. Avoid +* unclear error flag, please clear flag when logic reset. +* QSTRUCT_ERR[19] - (W1C) Queue struct data error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* BN0_MACTX_HANG_ERR[20] - (W1C) BN0 MACTX Ctrl FSM Hang error +* interrupt. Avoid unclear error flag, please clear flag when logic +reset. +* BN1_MACTX_HANG_ERR[21] - (W1C) BN1 MACTX Ctrl FSM Hang error +* interrupt. Avoid unclear error flag, please clear flag when logic +reset. +* BN0_TXCMD_HANG_ERR[22] - (W1C) BN0 TXCMD Ctrl FSM Hang error +* interrupt. Avoid unclear error flag, please clear flag when logic +reset. +* BN1_TXCMD_HANG_ERR[23] - (W1C) BN1 TXCMD Ctrl FSM Hang error +* interrupt. Avoid unclear error flag, please clear flag when logic +reset. +* DRR_SRCH_DBDC0_ERR[24] - (W1C) DRR DBDC0 sta serach error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* DRR_SRCH_DBDC1_ERR[25] - (W1C) DRR DBDC1 sta serach error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* DRR_FL_ERR[26] - (W1C) DRR forward link access error +* interrupt. Avoid unclear error flag, please clear flag when logic +reset. +* DRR_BL_ERR[27] - (W1C) DRR backward link access error +* interrupt. Avoid unclear error flag, please clear flag when logic +reset. +* DRR_RL_ERR[28] - (W1C) DRR relay link access error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* DRR_CHRG_STA_ERR[29] - (W1C) DRR charge wlanid error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* DRR_STA_WLANID_ERR[30] - (W1C) DRR wlanid error interrupt. Avoid +* unclear error flag, please clear flag when logic reset. +* DRR_STA_WMMID_ERR[31] - (W1C) DRR wmmid error interrupt. Avoid +* unclear error flag, please clear flag when logic reset. +*/ +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_STA_WMMID_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_STA_WMMID_ERR_MASK \ + 0x80000000 /* DRR_STA_WMMID_ERR[31] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_STA_WMMID_ERR_SHFT 31 +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_STA_WLANID_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_STA_WLANID_ERR_MASK \ + 0x40000000 /* DRR_STA_WLANID_ERR[30] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_STA_WLANID_ERR_SHFT 30 +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_CHRG_STA_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_CHRG_STA_ERR_MASK \ + 0x20000000 /* DRR_CHRG_STA_ERR[29] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_CHRG_STA_ERR_SHFT 29 +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_RL_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_RL_ERR_MASK \ + 0x10000000 /* DRR_RL_ERR[28] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_RL_ERR_SHFT 28 +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_BL_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_BL_ERR_MASK \ + 0x08000000 /* DRR_BL_ERR[27] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_BL_ERR_SHFT 27 +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_FL_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_FL_ERR_MASK \ + 0x04000000 /* DRR_FL_ERR[26] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_FL_ERR_SHFT 26 +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_SRCH_DBDC1_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_SRCH_DBDC1_ERR_MASK \ + 0x02000000 /* DRR_SRCH_DBDC1_ERR[25] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_SRCH_DBDC1_ERR_SHFT 25 +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_SRCH_DBDC0_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_SRCH_DBDC0_ERR_MASK \ + 0x01000000 /* DRR_SRCH_DBDC0_ERR[24] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_DRR_SRCH_DBDC0_ERR_SHFT 24 +#define WF_PLE_TOP_INT_N9_ERR_STS_BN1_TXCMD_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_BN1_TXCMD_HANG_ERR_MASK \ + 0x00800000 /* BN1_TXCMD_HANG_ERR[23] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_BN1_TXCMD_HANG_ERR_SHFT 23 +#define WF_PLE_TOP_INT_N9_ERR_STS_BN0_TXCMD_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_BN0_TXCMD_HANG_ERR_MASK \ + 0x00400000 /* BN0_TXCMD_HANG_ERR[22] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_BN0_TXCMD_HANG_ERR_SHFT 22 +#define WF_PLE_TOP_INT_N9_ERR_STS_BN1_MACTX_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_BN1_MACTX_HANG_ERR_MASK \ + 0x00200000 /* BN1_MACTX_HANG_ERR[21] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_BN1_MACTX_HANG_ERR_SHFT 21 +#define WF_PLE_TOP_INT_N9_ERR_STS_BN0_MACTX_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_BN0_MACTX_HANG_ERR_MASK \ + 0x00100000 /* BN0_MACTX_HANG_ERR[20] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_BN0_MACTX_HANG_ERR_SHFT 20 +#define WF_PLE_TOP_INT_N9_ERR_STS_QSTRUCT_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_QSTRUCT_ERR_MASK \ + 0x00080000 /* QSTRUCT_ERR[19] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_QSTRUCT_ERR_SHFT 19 +#define WF_PLE_TOP_INT_N9_ERR_STS_FREE_HEAD_TAIL_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_FREE_HEAD_TAIL_ERR_MASK \ + 0x00040000 /* FREE_HEAD_TAIL_ERR[18] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_FREE_HEAD_TAIL_ERR_SHFT 18 +#define WF_PLE_TOP_INT_N9_ERR_STS_LMAC_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_LMAC_HANG_ERR_MASK \ + 0x00020000 /* LMAC_HANG_ERR[17] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_LMAC_HANG_ERR_SHFT 17 +#define WF_PLE_TOP_INT_N9_ERR_STS_CPU_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_CPU_HANG_ERR_MASK \ + 0x00010000 /* CPU_HANG_ERR[16] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_CPU_HANG_ERR_SHFT 16 +#define WF_PLE_TOP_INT_N9_ERR_STS_HIF_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_HIF_HANG_ERR_MASK \ + 0x00008000 /* HIF_HANG_ERR[15] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_HIF_HANG_ERR_SHFT 15 +#define WF_PLE_TOP_INT_N9_ERR_STS_PL_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_PL_HANG_ERR_MASK \ + 0x00004000 /* PL_HANG_ERR[14] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_PL_HANG_ERR_SHFT 14 +#define WF_PLE_TOP_INT_N9_ERR_STS_FL_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_FL_HANG_ERR_MASK \ + 0x00002000 /* FL_HANG_ERR[13] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_FL_HANG_ERR_SHFT 13 +#define WF_PLE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P2_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P2_MASK \ + 0x00001000 /* DATA_OPER_ERR_P2[12] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P2_SHFT 12 +#define WF_PLE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P1_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P1_MASK \ + 0x00000800 /* DATA_OPER_ERR_P1[11] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P1_SHFT 11 +#define WF_PLE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P0_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P0_MASK \ + 0x00000400 /* DATA_OPER_ERR_P0[10] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P0_SHFT 10 +#define WF_PLE_TOP_INT_N9_ERR_STS_MDP_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_MDP_HANG_ERR_MASK \ + 0x00000100 /* MDP_HANG_ERR[8] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_MDP_HANG_ERR_SHFT 8 +#define WF_PLE_TOP_INT_N9_ERR_STS_MDP_D_OPER_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_MDP_D_OPER_ERR_MASK \ + 0x00000080 /* MDP_D_OPER_ERR[7] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_MDP_D_OPER_ERR_SHFT 7 +#define WF_PLE_TOP_INT_N9_ERR_STS_DOUBLE_RLS_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_DOUBLE_RLS_ERR_MASK \ + 0x00000040 /* DOUBLE_RLS_ERR[6] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_DOUBLE_RLS_ERR_SHFT 6 +#define WF_PLE_TOP_INT_N9_ERR_STS_PAGE_UDF_P2_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_PAGE_UDF_P2_MASK \ + 0x00000020 /* PAGE_UDF_P2[5] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_PAGE_UDF_P2_SHFT 5 +#define WF_PLE_TOP_INT_N9_ERR_STS_PAGE_UDF_P1_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_PAGE_UDF_P1_MASK \ + 0x00000010 /* PAGE_UDF_P1[4] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_PAGE_UDF_P1_SHFT 4 +#define WF_PLE_TOP_INT_N9_ERR_STS_PAGE_UDF_P0_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_PAGE_UDF_P0_MASK \ + 0x00000008 /* PAGE_UDF_P0[3] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_PAGE_UDF_P0_SHFT 3 +#define WF_PLE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P2_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P2_MASK \ + 0x00000004 /* Q_CMD_ERR_P2[2] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P2_SHFT 2 +#define WF_PLE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P1_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P1_MASK \ + 0x00000002 /* Q_CMD_ERR_P1[1] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P1_SHFT 1 +#define WF_PLE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P0_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P0_MASK \ + 0x00000001 /* Q_CMD_ERR_P0[0] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P0_SHFT 0 + +/* +* ---INT_N9_ERR_MASK (0x820C0000 + 0x2C)--- +* EN_Q_CMD_ERR_P0[0] - (RW) Enables queue command error interrupt +* status of port 0 +* EN_Q_CMD_ERR_P1[1] - (RW) Enables queue command error interrupt +* status of port 1 +* EN_Q_CMD_ERR_P2[2] - (RW) Enables queue command error interrupt +* status of port 2 +* EN_PAGE_UDF_P0[3] - (RW) Enables page underflow interrupt status +* of port 0 +* EN_PAGE_UDF_P1[4] - (RW) Enables page underflow interrupt status +* of port 1 +* EN_PAGE_UDF_P2[5] - (RW) Enables page underflow interrupt status +* of port 2 +* EN_DOUBLE_RLS_ERR[6] - (RW) Enable double release error interrupt. +* EN_MDP_D_OPER_ERR[7] - (RW) Enable MDP data operation error +interrupt. +* EN_MDP_HANG_ERR[8] - (RW) Enable MDP FSM hang error interrupt. +* RESERVED9[9] - (RO) Reserved bits +* EN_DATA_OPER_ERR_P0[10] - (RW) Enables data operation error of port +0 +* EN_DATA_OPER_ERR_P1[11] - (RW) Enables data operation error of port +1 +* EN_DATA_OPER_ERR_P2[12] - (RW) Enables data operation error of port +2 +* EN_FL_HANG_ERR[13] - (RW) Enables frame link FSM hang error +interrupt +* EN_PL_HANG_ERR[14] - (RW) Enables page link FSM hang error +interrupt +* EN_HIF_HANG_ERR[15] - (RW) Enables HIF port FSM hang error +interrupt +* EN_CPU_HANG_ERR[16] - (RW) Enables CPU port FSM hang error +interrupt +* EN_LMAC_HANG_ERR[17] - (RW) Enables LMAC port FSM hang error +interrupt +* EN_FREE_HEAD_TAIL_ERR[18] - (RW) Enable free head/tail error +interrupt. +* EN_QSTRUCT_ERR[19] - (RW) Enable queue struct data error +interrupt. +* EN_BN0_MACTX_HANG_ERR[20] - (RW) Enable BN0 MACTX Ctrl FSM Hang +error +interrupt. +* EN_BN1_MACTX_HANG_ERR[21] - (RW) Enable BN1 MACTX Ctrl FSM Hang +error +interrupt. +* EN_BN0_TXCMD_HANG_ERR[22] - (RW) Enable BN0 TXCMD Ctrl FSM Hang +error +interrupt. +* EN_BN1_TXCMD_HANG_ERR[23] - (RW) Enable BN1 TXCMD Ctrl FSM Hang +error +interrupt. +* EN_DRR_SRCH_DBDC0_ERR[24] - (RW) Enable DRR DBDC0 sta search error +interrupt. +* EN_DRR_SRCH_DBDC1_ERR[25] - (RW) Enable DRR DBDC1 sta search error +interrupt. +* EN_DRR_FL_ERR[26] - (RW) Enable DRR forward link access error +interrupt. +* EN_DRR_BL_ERR[27] - (RW) Enable DRR backward link access error +interrupt. +* EN_DRR_RL_ERR[28] - (RW) Enable DRR relay link access error +interrupt. +* EN_DRR_CHRG_STA_ERR[29] - (RW) Enable DRR wlanid error when charge +interrupt. +* EN_DRR_STA_WLANID_ERR[30] - (RW) Enable DRR wlanid error when +add/remove +* sta interrupt. +* EN_DRR_STA_WMMID_ERR[31] - (RW) Enable DRR wmmid error when +add/remove +* sta interrupt. +*/ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_STA_WMMID_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_STA_WMMID_ERR_MASK \ + 0x80000000 /* EN_DRR_STA_WMMID_ERR[31] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_STA_WMMID_ERR_SHFT 31 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_STA_WLANID_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_STA_WLANID_ERR_MASK \ + 0x40000000 /* EN_DRR_STA_WLANID_ERR[30] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_STA_WLANID_ERR_SHFT 30 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_CHRG_STA_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_CHRG_STA_ERR_MASK \ + 0x20000000 /* EN_DRR_CHRG_STA_ERR[29] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_CHRG_STA_ERR_SHFT 29 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_RL_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_RL_ERR_MASK \ + 0x10000000 /* EN_DRR_RL_ERR[28] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_RL_ERR_SHFT 28 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_BL_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_BL_ERR_MASK \ + 0x08000000 /* EN_DRR_BL_ERR[27] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_BL_ERR_SHFT 27 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_FL_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_FL_ERR_MASK \ + 0x04000000 /* EN_DRR_FL_ERR[26] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_FL_ERR_SHFT 26 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_SRCH_DBDC1_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_SRCH_DBDC1_ERR_MASK \ + 0x02000000 /* EN_DRR_SRCH_DBDC1_ERR[25] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_SRCH_DBDC1_ERR_SHFT 25 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_SRCH_DBDC0_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_SRCH_DBDC0_ERR_MASK \ + 0x01000000 /* EN_DRR_SRCH_DBDC0_ERR[24] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DRR_SRCH_DBDC0_ERR_SHFT 24 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_BN1_TXCMD_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_BN1_TXCMD_HANG_ERR_MASK \ + 0x00800000 /* EN_BN1_TXCMD_HANG_ERR[23] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_BN1_TXCMD_HANG_ERR_SHFT 23 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_BN0_TXCMD_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_BN0_TXCMD_HANG_ERR_MASK \ + 0x00400000 /* EN_BN0_TXCMD_HANG_ERR[22] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_BN0_TXCMD_HANG_ERR_SHFT 22 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_BN1_MACTX_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_BN1_MACTX_HANG_ERR_MASK \ + 0x00200000 /* EN_BN1_MACTX_HANG_ERR[21] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_BN1_MACTX_HANG_ERR_SHFT 21 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_BN0_MACTX_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_BN0_MACTX_HANG_ERR_MASK \ + 0x00100000 /* EN_BN0_MACTX_HANG_ERR[20] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_BN0_MACTX_HANG_ERR_SHFT 20 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_QSTRUCT_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_QSTRUCT_ERR_MASK \ + 0x00080000 /* EN_QSTRUCT_ERR[19] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_QSTRUCT_ERR_SHFT 19 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_FREE_HEAD_TAIL_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_FREE_HEAD_TAIL_ERR_MASK \ + 0x00040000 /* EN_FREE_HEAD_TAIL_ERR[18] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_FREE_HEAD_TAIL_ERR_SHFT 18 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_LMAC_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_LMAC_HANG_ERR_MASK \ + 0x00020000 /* EN_LMAC_HANG_ERR[17] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_LMAC_HANG_ERR_SHFT 17 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_CPU_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_CPU_HANG_ERR_MASK \ + 0x00010000 /* EN_CPU_HANG_ERR[16] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_CPU_HANG_ERR_SHFT 16 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_HIF_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_HIF_HANG_ERR_MASK \ + 0x00008000 /* EN_HIF_HANG_ERR[15] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_HIF_HANG_ERR_SHFT 15 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_PL_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_PL_HANG_ERR_MASK \ + 0x00004000 /* EN_PL_HANG_ERR[14] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_PL_HANG_ERR_SHFT 14 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_FL_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_FL_HANG_ERR_MASK \ + 0x00002000 /* EN_FL_HANG_ERR[13] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_FL_HANG_ERR_SHFT 13 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P2_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P2_MASK \ + 0x00001000 /* EN_DATA_OPER_ERR_P2[12] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P2_SHFT 12 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P1_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P1_MASK \ + 0x00000800 /* EN_DATA_OPER_ERR_P1[11] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P1_SHFT 11 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P0_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P0_MASK \ + 0x00000400 /* EN_DATA_OPER_ERR_P0[10] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P0_SHFT 10 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_MDP_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_MDP_HANG_ERR_MASK \ + 0x00000100 /* EN_MDP_HANG_ERR[8] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_MDP_HANG_ERR_SHFT 8 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_MDP_D_OPER_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_MDP_D_OPER_ERR_MASK \ + 0x00000080 /* EN_MDP_D_OPER_ERR[7] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_MDP_D_OPER_ERR_SHFT 7 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DOUBLE_RLS_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DOUBLE_RLS_ERR_MASK \ + 0x00000040 /* EN_DOUBLE_RLS_ERR[6] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_DOUBLE_RLS_ERR_SHFT 6 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P2_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P2_MASK \ + 0x00000020 /* EN_PAGE_UDF_P2[5] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P2_SHFT 5 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P1_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P1_MASK \ + 0x00000010 /* EN_PAGE_UDF_P1[4] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P1_SHFT 4 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P0_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P0_MASK \ + 0x00000008 /* EN_PAGE_UDF_P0[3] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P0_SHFT 3 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P2_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P2_MASK \ + 0x00000004 /* EN_Q_CMD_ERR_P2[2] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P2_SHFT 2 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P1_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P1_MASK \ + 0x00000002 /* EN_Q_CMD_ERR_P1[1] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P1_SHFT 1 +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P0_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P0_MASK \ + 0x00000001 /* EN_Q_CMD_ERR_P0[0] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P0_SHFT 0 + +/* +* ---HOST_REPORT0 (0x820C0000 + 0x30)--- +* RESERVED0[0] - (RO) Reserved bits +* DIS_HOST_RPT[1] - (RW) Disables host report function +* HOST_RPT_VER0_EN[2] - (RW) Enable control for host report roll back +* to Version 0(MT7615 used). +* RESERVED3[3] - (RO) Reserved bits +* WMCPU_MSDU_ID_NUM[5..4] - (RW) Configuration of WMCPU MSDU ID usage. +* RESERVED6[7..6] - (RO) Reserved bits +* HOST_RPT_PACK_TH[15..8] - (RW) The buffer threshold for packing host +* report. The buffer size less then the MSDU numbers of a MPDU, would +* let MSDU_ID +lose. +* HOST_RPT_QID[22..16] - (RW) PSE Queue ID control for host report. +* HOST_RPT_PID[23] - (RW) PSE Port ID control for host report. +* WMCPU_RPT_QID[30..24] - (RW) PSE Queue ID control for WMCPU report. +* WMCPU_RPT_PID[31] - (RW) PSE Port ID control for WMCPU report. +*/ +#define WF_PLE_TOP_HOST_REPORT0_WMCPU_RPT_PID_ADDR \ + WF_PLE_TOP_HOST_REPORT0_ADDR +#define WF_PLE_TOP_HOST_REPORT0_WMCPU_RPT_PID_MASK \ + 0x80000000 /* WMCPU_RPT_PID[31] */ +#define WF_PLE_TOP_HOST_REPORT0_WMCPU_RPT_PID_SHFT 31 +#define WF_PLE_TOP_HOST_REPORT0_WMCPU_RPT_QID_ADDR \ + WF_PLE_TOP_HOST_REPORT0_ADDR +#define WF_PLE_TOP_HOST_REPORT0_WMCPU_RPT_QID_MASK \ + 0x7F000000 /* WMCPU_RPT_QID[30..24] */ +#define WF_PLE_TOP_HOST_REPORT0_WMCPU_RPT_QID_SHFT 24 +#define WF_PLE_TOP_HOST_REPORT0_HOST_RPT_PID_ADDR \ + WF_PLE_TOP_HOST_REPORT0_ADDR +#define WF_PLE_TOP_HOST_REPORT0_HOST_RPT_PID_MASK \ + 0x00800000 /* HOST_RPT_PID[23] */ +#define WF_PLE_TOP_HOST_REPORT0_HOST_RPT_PID_SHFT 23 +#define WF_PLE_TOP_HOST_REPORT0_HOST_RPT_QID_ADDR \ + WF_PLE_TOP_HOST_REPORT0_ADDR +#define WF_PLE_TOP_HOST_REPORT0_HOST_RPT_QID_MASK \ + 0x007F0000 /* HOST_RPT_QID[22..16] */ +#define WF_PLE_TOP_HOST_REPORT0_HOST_RPT_QID_SHFT 16 +#define WF_PLE_TOP_HOST_REPORT0_HOST_RPT_PACK_TH_ADDR \ + WF_PLE_TOP_HOST_REPORT0_ADDR +#define WF_PLE_TOP_HOST_REPORT0_HOST_RPT_PACK_TH_MASK \ + 0x0000FF00 /* HOST_RPT_PACK_TH[15..8] */ +#define WF_PLE_TOP_HOST_REPORT0_HOST_RPT_PACK_TH_SHFT 8 +#define WF_PLE_TOP_HOST_REPORT0_WMCPU_MSDU_ID_NUM_ADDR \ + WF_PLE_TOP_HOST_REPORT0_ADDR +#define WF_PLE_TOP_HOST_REPORT0_WMCPU_MSDU_ID_NUM_MASK \ + 0x00000030 /* WMCPU_MSDU_ID_NUM[5..4] */ +#define WF_PLE_TOP_HOST_REPORT0_WMCPU_MSDU_ID_NUM_SHFT 4 +#define WF_PLE_TOP_HOST_REPORT0_HOST_RPT_VER0_EN_ADDR \ + WF_PLE_TOP_HOST_REPORT0_ADDR +#define WF_PLE_TOP_HOST_REPORT0_HOST_RPT_VER0_EN_MASK \ + 0x00000004 /* HOST_RPT_VER0_EN[2] */ +#define WF_PLE_TOP_HOST_REPORT0_HOST_RPT_VER0_EN_SHFT 2 +#define WF_PLE_TOP_HOST_REPORT0_DIS_HOST_RPT_ADDR \ + WF_PLE_TOP_HOST_REPORT0_ADDR +#define WF_PLE_TOP_HOST_REPORT0_DIS_HOST_RPT_MASK \ + 0x00000002 /* DIS_HOST_RPT[1] */ +#define WF_PLE_TOP_HOST_REPORT0_DIS_HOST_RPT_SHFT 1 + +/* +* ---HOST_REPORT1 (0x820C0000 + 0x34)--- +* RESERVED0[7..0] - (RO) Reserved bits +* MD_RPT_QID[14..8] - (RW) PSE Queue ID control for MD CPU host +report. +* MD_RPT_PID[15] - (RW) PSE Port ID control for MD CPU host +report. +* HOST_RPT_PG_SIZE[19..16] - (RW) Setting of host report used PSE page +size. +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_HOST_REPORT1_HOST_RPT_PG_SIZE_ADDR \ + WF_PLE_TOP_HOST_REPORT1_ADDR +#define WF_PLE_TOP_HOST_REPORT1_HOST_RPT_PG_SIZE_MASK \ + 0x000F0000 /* HOST_RPT_PG_SIZE[19..16] */ +#define WF_PLE_TOP_HOST_REPORT1_HOST_RPT_PG_SIZE_SHFT 16 +#define WF_PLE_TOP_HOST_REPORT1_MD_RPT_PID_ADDR \ + WF_PLE_TOP_HOST_REPORT1_ADDR +#define WF_PLE_TOP_HOST_REPORT1_MD_RPT_PID_MASK \ + 0x00008000 /* MD_RPT_PID[15] */ +#define WF_PLE_TOP_HOST_REPORT1_MD_RPT_PID_SHFT 15 +#define WF_PLE_TOP_HOST_REPORT1_MD_RPT_QID_ADDR \ + WF_PLE_TOP_HOST_REPORT1_ADDR +#define WF_PLE_TOP_HOST_REPORT1_MD_RPT_QID_MASK \ + 0x00007F00 /* MD_RPT_QID[14..8] */ +#define WF_PLE_TOP_HOST_REPORT1_MD_RPT_QID_SHFT 8 + +/* +* ---HOST_REPORT2 (0x820C0000 + 0x38)--- +* BN1_HOST_RPT_QID[6..0] - (RW) PSE Queue ID control for BN1 Host +report. +* BN1_HOST_RPT_PID[7] - (RW) PSE Port ID control for BN1 Host report. +* BN1_MD_RPT_QID[14..8] - (RW) PSE Queue ID control for BN1 MD CPU +host +report. +* BN1_MD_RPT_PID[15] - (RW) PSE Port ID control for BN1 MD CPU host +report. +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_HOST_REPORT2_BN1_MD_RPT_PID_ADDR \ + WF_PLE_TOP_HOST_REPORT2_ADDR +#define WF_PLE_TOP_HOST_REPORT2_BN1_MD_RPT_PID_MASK \ + 0x00008000 /* BN1_MD_RPT_PID[15] */ +#define WF_PLE_TOP_HOST_REPORT2_BN1_MD_RPT_PID_SHFT 15 +#define WF_PLE_TOP_HOST_REPORT2_BN1_MD_RPT_QID_ADDR \ + WF_PLE_TOP_HOST_REPORT2_ADDR +#define WF_PLE_TOP_HOST_REPORT2_BN1_MD_RPT_QID_MASK \ + 0x00007F00 /* BN1_MD_RPT_QID[14..8] */ +#define WF_PLE_TOP_HOST_REPORT2_BN1_MD_RPT_QID_SHFT 8 +#define WF_PLE_TOP_HOST_REPORT2_BN1_HOST_RPT_PID_ADDR \ + WF_PLE_TOP_HOST_REPORT2_ADDR +#define WF_PLE_TOP_HOST_REPORT2_BN1_HOST_RPT_PID_MASK \ + 0x00000080 /* BN1_HOST_RPT_PID[7] */ +#define WF_PLE_TOP_HOST_REPORT2_BN1_HOST_RPT_PID_SHFT 7 +#define WF_PLE_TOP_HOST_REPORT2_BN1_HOST_RPT_QID_ADDR \ + WF_PLE_TOP_HOST_REPORT2_ADDR +#define WF_PLE_TOP_HOST_REPORT2_BN1_HOST_RPT_QID_MASK \ + 0x0000007F /* BN1_HOST_RPT_QID[6..0] */ +#define WF_PLE_TOP_HOST_REPORT2_BN1_HOST_RPT_QID_SHFT 0 + +/* +* ---BLK_MODE_RATE_LMT (0x820C0000 + 0x3c)--- +* BN0_MACTX_BLK_RATE_LMT[15..0] - (RW) TX Rate limitaion of CutThrough +data +* block mode. The rate less then the limitation would turn on block +mode. +* BN1_MACTX_BLK_RATE_LMT[31..16] - (RW) TX Rate limitaion of +* CutThrough data +* block mode. The rate less then the limitation would turn on block +mode. +*/ +#define WF_PLE_TOP_BLK_MODE_RATE_LMT_BN1_MACTX_BLK_RATE_LMT_ADDR \ + WF_PLE_TOP_BLK_MODE_RATE_LMT_ADDR +#define WF_PLE_TOP_BLK_MODE_RATE_LMT_BN1_MACTX_BLK_RATE_LMT_MASK \ + 0xFFFF0000 /* BN1_MACTX_BLK_RATE_LMT[31..16] */ +#define WF_PLE_TOP_BLK_MODE_RATE_LMT_BN1_MACTX_BLK_RATE_LMT_SHFT 16 +#define WF_PLE_TOP_BLK_MODE_RATE_LMT_BN0_MACTX_BLK_RATE_LMT_ADDR \ + WF_PLE_TOP_BLK_MODE_RATE_LMT_ADDR +#define WF_PLE_TOP_BLK_MODE_RATE_LMT_BN0_MACTX_BLK_RATE_LMT_MASK \ + 0x0000FFFF /* BN0_MACTX_BLK_RATE_LMT[15..0] */ +#define WF_PLE_TOP_BLK_MODE_RATE_LMT_BN0_MACTX_BLK_RATE_LMT_SHFT 0 + +/* +* ---C_GET_FID_0 (0x820C0000 + 0x40)--- +* GET_SRC_WLANID[9..0] - (RW) Source WLAN ID for get frame ID. +* RESERVED10[11..10] - (RO) Reserved bits +* GET_SRC_TGID[12] - (RW) Source TX Group ID for get frame ID. +* RESERVED13[13] - (RO) Reserved bits +* GET_SRC_PID[15..14] - (RW) Source port ID for get frame ID. +* GET_FRAME_TYPE[19..16] - (RW) GET_SUB_TYPE +* RESERVED20[23..20] - (RO) Reserved bits +* GET_SRC_QID[30..24] - (RW) Source Queue ID for get frame ID. +* EXECUTE[31] - (A0) Executes command +*/ +#define WF_PLE_TOP_C_GET_FID_0_EXECUTE_ADDR \ + WF_PLE_TOP_C_GET_FID_0_ADDR +#define WF_PLE_TOP_C_GET_FID_0_EXECUTE_MASK \ + 0x80000000 /* EXECUTE[31] */ +#define WF_PLE_TOP_C_GET_FID_0_EXECUTE_SHFT 31 +#define WF_PLE_TOP_C_GET_FID_0_GET_SRC_QID_ADDR \ + WF_PLE_TOP_C_GET_FID_0_ADDR +#define WF_PLE_TOP_C_GET_FID_0_GET_SRC_QID_MASK \ + 0x7F000000 /* GET_SRC_QID[30..24] */ +#define WF_PLE_TOP_C_GET_FID_0_GET_SRC_QID_SHFT 24 +#define WF_PLE_TOP_C_GET_FID_0_GET_FRAME_TYPE_ADDR \ + WF_PLE_TOP_C_GET_FID_0_ADDR +#define WF_PLE_TOP_C_GET_FID_0_GET_FRAME_TYPE_MASK \ + 0x000F0000 /* GET_FRAME_TYPE[19..16] */ +#define WF_PLE_TOP_C_GET_FID_0_GET_FRAME_TYPE_SHFT 16 +#define WF_PLE_TOP_C_GET_FID_0_GET_SRC_PID_ADDR \ + WF_PLE_TOP_C_GET_FID_0_ADDR +#define WF_PLE_TOP_C_GET_FID_0_GET_SRC_PID_MASK \ + 0x0000C000 /* GET_SRC_PID[15..14] */ +#define WF_PLE_TOP_C_GET_FID_0_GET_SRC_PID_SHFT 14 +#define WF_PLE_TOP_C_GET_FID_0_GET_SRC_TGID_ADDR \ + WF_PLE_TOP_C_GET_FID_0_ADDR +#define WF_PLE_TOP_C_GET_FID_0_GET_SRC_TGID_MASK \ + 0x00001000 /* GET_SRC_TGID[12] */ +#define WF_PLE_TOP_C_GET_FID_0_GET_SRC_TGID_SHFT 12 +#define WF_PLE_TOP_C_GET_FID_0_GET_SRC_WLANID_ADDR \ + WF_PLE_TOP_C_GET_FID_0_ADDR +#define WF_PLE_TOP_C_GET_FID_0_GET_SRC_WLANID_MASK \ + 0x000003FF /* GET_SRC_WLANID[9..0] */ +#define WF_PLE_TOP_C_GET_FID_0_GET_SRC_WLANID_SHFT 0 + +/* +* ---C_GET_FID_1 (0x820C0000 + 0x44)--- +* GET_RETURN_FID[11..0] - (RO) Return frame ID +* RESERVED12[14..12] - (RO) Reserved bits +* END[15] - (RO) Return frame ID is end FID. +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_C_GET_FID_1_END_ADDR WF_PLE_TOP_C_GET_FID_1_ADDR +#define WF_PLE_TOP_C_GET_FID_1_END_MASK 0x00008000 /* END[15] */ +#define WF_PLE_TOP_C_GET_FID_1_END_SHFT 15 +#define WF_PLE_TOP_C_GET_FID_1_GET_RETURN_FID_ADDR \ + WF_PLE_TOP_C_GET_FID_1_ADDR +#define WF_PLE_TOP_C_GET_FID_1_GET_RETURN_FID_MASK \ + 0x00000FFF /* GET_RETURN_FID[11..0] */ +#define WF_PLE_TOP_C_GET_FID_1_GET_RETURN_FID_SHFT 0 + +/* +* ---RELEASE_CTRL_0 (0x820C0000 + 0x50)--- +* NOR_RLS_QID[6..0] - (RW) Normal TX packet release DST QID +* RESERVED7[7] - (RO) Reserved bits +* NOR_RLS_PID[9..8] - (RW) Normal TX packet release DST PID +* RESERVED10[15..10] - (RO) Reserved bits +* DROP_RLS_QID[22..16] - (RW) Drop packet release DST QID +* RESERVED23[23] - (RO) Reserved bits +* DROP_RLS_PID[25..24] - (RW) Drop packet release DST PID +* RESERVED26[31..26] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_RELEASE_CTRL_0_DROP_RLS_PID_ADDR \ + WF_PLE_TOP_RELEASE_CTRL_0_ADDR +#define WF_PLE_TOP_RELEASE_CTRL_0_DROP_RLS_PID_MASK \ + 0x03000000 /* DROP_RLS_PID[25..24] */ +#define WF_PLE_TOP_RELEASE_CTRL_0_DROP_RLS_PID_SHFT 24 +#define WF_PLE_TOP_RELEASE_CTRL_0_DROP_RLS_QID_ADDR \ + WF_PLE_TOP_RELEASE_CTRL_0_ADDR +#define WF_PLE_TOP_RELEASE_CTRL_0_DROP_RLS_QID_MASK \ + 0x007F0000 /* DROP_RLS_QID[22..16] */ +#define WF_PLE_TOP_RELEASE_CTRL_0_DROP_RLS_QID_SHFT 16 +#define WF_PLE_TOP_RELEASE_CTRL_0_NOR_RLS_PID_ADDR \ + WF_PLE_TOP_RELEASE_CTRL_0_ADDR +#define WF_PLE_TOP_RELEASE_CTRL_0_NOR_RLS_PID_MASK \ + 0x00000300 /* NOR_RLS_PID[9..8] */ +#define WF_PLE_TOP_RELEASE_CTRL_0_NOR_RLS_PID_SHFT 8 +#define WF_PLE_TOP_RELEASE_CTRL_0_NOR_RLS_QID_ADDR \ + WF_PLE_TOP_RELEASE_CTRL_0_ADDR +#define WF_PLE_TOP_RELEASE_CTRL_0_NOR_RLS_QID_MASK \ + 0x0000007F /* NOR_RLS_QID[6..0] */ +#define WF_PLE_TOP_RELEASE_CTRL_0_NOR_RLS_QID_SHFT 0 + +/* +* ---RELEASE_CTRL_1 (0x820C0000 + 0x54)--- +* BCN0_RLS_QID[6..0] - (RW) Beacon 0 packet release DST QID +* RESERVED7[7] - (RO) Reserved bits +* BCN0_RLS_PID[9..8] - (RW) Beacon 0 packet release DST PID +* RESERVED10[15..10] - (RO) Reserved bits +* BCN1_RLS_QID[22..16] - (RW) Beacon 1 packet release DST QID +* RESERVED23[23] - (RO) Reserved bits +* BCN1_RLS_PID[25..24] - (RW) Beacon 1 packet release DST PID +* RESERVED26[31..26] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_RELEASE_CTRL_1_BCN1_RLS_PID_ADDR \ + WF_PLE_TOP_RELEASE_CTRL_1_ADDR +#define WF_PLE_TOP_RELEASE_CTRL_1_BCN1_RLS_PID_MASK \ + 0x03000000 /* BCN1_RLS_PID[25..24] */ +#define WF_PLE_TOP_RELEASE_CTRL_1_BCN1_RLS_PID_SHFT 24 +#define WF_PLE_TOP_RELEASE_CTRL_1_BCN1_RLS_QID_ADDR \ + WF_PLE_TOP_RELEASE_CTRL_1_ADDR +#define WF_PLE_TOP_RELEASE_CTRL_1_BCN1_RLS_QID_MASK \ + 0x007F0000 /* BCN1_RLS_QID[22..16] */ +#define WF_PLE_TOP_RELEASE_CTRL_1_BCN1_RLS_QID_SHFT 16 +#define WF_PLE_TOP_RELEASE_CTRL_1_BCN0_RLS_PID_ADDR \ + WF_PLE_TOP_RELEASE_CTRL_1_ADDR +#define WF_PLE_TOP_RELEASE_CTRL_1_BCN0_RLS_PID_MASK \ + 0x00000300 /* BCN0_RLS_PID[9..8] */ +#define WF_PLE_TOP_RELEASE_CTRL_1_BCN0_RLS_PID_SHFT 8 +#define WF_PLE_TOP_RELEASE_CTRL_1_BCN0_RLS_QID_ADDR \ + WF_PLE_TOP_RELEASE_CTRL_1_ADDR +#define WF_PLE_TOP_RELEASE_CTRL_1_BCN0_RLS_QID_MASK \ + 0x0000007F /* BCN0_RLS_QID[6..0] */ +#define WF_PLE_TOP_RELEASE_CTRL_1_BCN0_RLS_QID_SHFT 0 + +/* +* ---RELEASE_CTRL_3 (0x820C0000 + 0x5c)--- +* RLS_FREE_DONE_PG_SIZE[3..0] - (RW) Page size configuration of Free +done +* event(host report). +* RESERVED4[31..4] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_RELEASE_CTRL_3_RLS_FREE_DONE_PG_SIZE_ADDR \ + WF_PLE_TOP_RELEASE_CTRL_3_ADDR +#define WF_PLE_TOP_RELEASE_CTRL_3_RLS_FREE_DONE_PG_SIZE_MASK \ + 0x0000000F /* RLS_FREE_DONE_PG_SIZE[3..0] */ +#define WF_PLE_TOP_RELEASE_CTRL_3_RLS_FREE_DONE_PG_SIZE_SHFT 0 + +/* +* ---C_EN_QUEUE_0 (0x820C0000 + 0x60)--- +* DST_WLANID[9..0] - (RW) Destination WLANID for enqueue +* RESERVED10[11..10] - (RO) Reserved bits +* DST_TGID[12] - (RW) Destination TX Group ID for enqueue +* RESERVED13[13] - (RO) Reserved bits +* DST_PID[15..14] - (RW) Destination port ID for enqueue +* SUB_TYPE[19..16] - (RW) Sub-type of enqueue command +* RESERVED20[22..20] - (RO) Reserved bits +* DELAY_ENQ[23] - (RW) Delay enqueue +* ENQ_DST_QID[30..24] - (RW) Destination queue ID for enqueue +* EXECUTE[31] - (A0) Executes command +*/ +#define WF_PLE_TOP_C_EN_QUEUE_0_EXECUTE_ADDR \ + WF_PLE_TOP_C_EN_QUEUE_0_ADDR +#define WF_PLE_TOP_C_EN_QUEUE_0_EXECUTE_MASK \ + 0x80000000 /* EXECUTE[31] */ +#define WF_PLE_TOP_C_EN_QUEUE_0_EXECUTE_SHFT 31 +#define WF_PLE_TOP_C_EN_QUEUE_0_ENQ_DST_QID_ADDR \ + WF_PLE_TOP_C_EN_QUEUE_0_ADDR +#define WF_PLE_TOP_C_EN_QUEUE_0_ENQ_DST_QID_MASK \ + 0x7F000000 /* ENQ_DST_QID[30..24] */ +#define WF_PLE_TOP_C_EN_QUEUE_0_ENQ_DST_QID_SHFT 24 +#define WF_PLE_TOP_C_EN_QUEUE_0_DELAY_ENQ_ADDR \ + WF_PLE_TOP_C_EN_QUEUE_0_ADDR +#define WF_PLE_TOP_C_EN_QUEUE_0_DELAY_ENQ_MASK \ + 0x00800000 /* DELAY_ENQ[23] */ +#define WF_PLE_TOP_C_EN_QUEUE_0_DELAY_ENQ_SHFT 23 +#define WF_PLE_TOP_C_EN_QUEUE_0_SUB_TYPE_ADDR \ + WF_PLE_TOP_C_EN_QUEUE_0_ADDR +#define WF_PLE_TOP_C_EN_QUEUE_0_SUB_TYPE_MASK \ + 0x000F0000 /* SUB_TYPE[19..16] */ +#define WF_PLE_TOP_C_EN_QUEUE_0_SUB_TYPE_SHFT 16 +#define WF_PLE_TOP_C_EN_QUEUE_0_DST_PID_ADDR \ + WF_PLE_TOP_C_EN_QUEUE_0_ADDR +#define WF_PLE_TOP_C_EN_QUEUE_0_DST_PID_MASK \ + 0x0000C000 /* DST_PID[15..14] */ +#define WF_PLE_TOP_C_EN_QUEUE_0_DST_PID_SHFT 14 +#define WF_PLE_TOP_C_EN_QUEUE_0_DST_TGID_ADDR \ + WF_PLE_TOP_C_EN_QUEUE_0_ADDR +#define WF_PLE_TOP_C_EN_QUEUE_0_DST_TGID_MASK \ + 0x00001000 /* DST_TGID[12] */ +#define WF_PLE_TOP_C_EN_QUEUE_0_DST_TGID_SHFT 12 +#define WF_PLE_TOP_C_EN_QUEUE_0_DST_WLANID_ADDR \ + WF_PLE_TOP_C_EN_QUEUE_0_ADDR +#define WF_PLE_TOP_C_EN_QUEUE_0_DST_WLANID_MASK \ + 0x000003FF /* DST_WLANID[9..0] */ +#define WF_PLE_TOP_C_EN_QUEUE_0_DST_WLANID_SHFT 0 + +/* +* ---C_EN_QUEUE_1 (0x820C0000 + 0x64)--- +* CUR_LIST_FID_START[11..0] - (RW) Start frame ID of enqueue operation +* list, enqueue FID of enqueue operation +* RESERVED12[15..12] - (RO) Reserved bits +* CUR_LIST_FID_END[27..16] - (RW) End frame ID of enqueue operation +list +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_C_EN_QUEUE_1_CUR_LIST_FID_END_ADDR \ + WF_PLE_TOP_C_EN_QUEUE_1_ADDR +#define WF_PLE_TOP_C_EN_QUEUE_1_CUR_LIST_FID_END_MASK \ + 0x0FFF0000 /* CUR_LIST_FID_END[27..16] */ +#define WF_PLE_TOP_C_EN_QUEUE_1_CUR_LIST_FID_END_SHFT 16 +#define WF_PLE_TOP_C_EN_QUEUE_1_CUR_LIST_FID_START_ADDR \ + WF_PLE_TOP_C_EN_QUEUE_1_ADDR +#define WF_PLE_TOP_C_EN_QUEUE_1_CUR_LIST_FID_START_MASK \ + 0x00000FFF /* CUR_LIST_FID_START[11..0] */ +#define WF_PLE_TOP_C_EN_QUEUE_1_CUR_LIST_FID_START_SHFT 0 + +/* +* ---C_EN_QUEUE_2 (0x820C0000 + 0x68)--- +* TARGET_FID[11..0] - (RW) Target reference FID for enqueue +operation +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_C_EN_QUEUE_2_TARGET_FID_ADDR \ + WF_PLE_TOP_C_EN_QUEUE_2_ADDR +#define WF_PLE_TOP_C_EN_QUEUE_2_TARGET_FID_MASK \ + 0x00000FFF /* TARGET_FID[11..0] */ +#define WF_PLE_TOP_C_EN_QUEUE_2_TARGET_FID_SHFT 0 + +/* +* ---C_DE_QUEUE_0 (0x820C0000 + 0x80)--- +* SRC_WLANID[9..0] - (RW) Source WLAN ID for dequeue command +* RESERVED10[11..10] - (RO) Reserved bits +* SRC_TGID[12] - (RW) Source TX Group ID for dequeue command +* RESERVED13[13] - (RO) Reserved bits +* SRC_PID[15..14] - (RW) Source port ID for dequeue command +* DEQ_SUB_TYPE[19..16] - (RW) Dequeue subtype of dequeue command +* ENQ_SUB_TYPE[22..20] - (RW) Enqueue subtype of enqueue command +* Only valid in Deq&Enq type. +* ENQ_VLD[23] - (RW) Deq&Enq command valid +* SRC_QID[30..24] - (RW) Source queue ID for dequeue command +* EXECUTE[31] - (A0) Executes dequeue command +*/ +#define WF_PLE_TOP_C_DE_QUEUE_0_EXECUTE_ADDR \ + WF_PLE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_0_EXECUTE_MASK \ + 0x80000000 /* EXECUTE[31] */ +#define WF_PLE_TOP_C_DE_QUEUE_0_EXECUTE_SHFT 31 +#define WF_PLE_TOP_C_DE_QUEUE_0_SRC_QID_ADDR \ + WF_PLE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_0_SRC_QID_MASK \ + 0x7F000000 /* SRC_QID[30..24] */ +#define WF_PLE_TOP_C_DE_QUEUE_0_SRC_QID_SHFT 24 +#define WF_PLE_TOP_C_DE_QUEUE_0_ENQ_VLD_ADDR \ + WF_PLE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_0_ENQ_VLD_MASK \ + 0x00800000 /* ENQ_VLD[23] */ +#define WF_PLE_TOP_C_DE_QUEUE_0_ENQ_VLD_SHFT 23 +#define WF_PLE_TOP_C_DE_QUEUE_0_ENQ_SUB_TYPE_ADDR \ + WF_PLE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_0_ENQ_SUB_TYPE_MASK \ + 0x00700000 /* ENQ_SUB_TYPE[22..20] */ +#define WF_PLE_TOP_C_DE_QUEUE_0_ENQ_SUB_TYPE_SHFT 20 +#define WF_PLE_TOP_C_DE_QUEUE_0_DEQ_SUB_TYPE_ADDR \ + WF_PLE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_0_DEQ_SUB_TYPE_MASK \ + 0x000F0000 /* DEQ_SUB_TYPE[19..16] */ +#define WF_PLE_TOP_C_DE_QUEUE_0_DEQ_SUB_TYPE_SHFT 16 +#define WF_PLE_TOP_C_DE_QUEUE_0_SRC_PID_ADDR \ + WF_PLE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_0_SRC_PID_MASK \ + 0x0000C000 /* SRC_PID[15..14] */ +#define WF_PLE_TOP_C_DE_QUEUE_0_SRC_PID_SHFT 14 +#define WF_PLE_TOP_C_DE_QUEUE_0_SRC_TGID_ADDR \ + WF_PLE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_0_SRC_TGID_MASK \ + 0x00001000 /* SRC_TGID[12] */ +#define WF_PLE_TOP_C_DE_QUEUE_0_SRC_TGID_SHFT 12 +#define WF_PLE_TOP_C_DE_QUEUE_0_SRC_WLANID_ADDR \ + WF_PLE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_0_SRC_WLANID_MASK \ + 0x000003FF /* SRC_WLANID[9..0] */ +#define WF_PLE_TOP_C_DE_QUEUE_0_SRC_WLANID_SHFT 0 + +/* +* ---C_DE_QUEUE_1 (0x820C0000 + 0x84)--- +* CUR_LIST_FID_START[11..0] - (RW) Start frame ID of dequeue operation +* list, enqueue start FID of enqueue operation +* Only valid in Deq&Enq type. +* RESERVED12[15..12] - (RO) Reserved bits +* CUR_LIST_FID_END[27..16] - (RW) End framd ID of dequeue operation +list, +* enqueue end FID of enqueue operation +* Only valid in Deq&Enq type. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_C_DE_QUEUE_1_CUR_LIST_FID_END_ADDR \ + WF_PLE_TOP_C_DE_QUEUE_1_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_1_CUR_LIST_FID_END_MASK \ + 0x0FFF0000 /* CUR_LIST_FID_END[27..16] */ +#define WF_PLE_TOP_C_DE_QUEUE_1_CUR_LIST_FID_END_SHFT 16 +#define WF_PLE_TOP_C_DE_QUEUE_1_CUR_LIST_FID_START_ADDR \ + WF_PLE_TOP_C_DE_QUEUE_1_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_1_CUR_LIST_FID_START_MASK \ + 0x00000FFF /* CUR_LIST_FID_START[11..0] */ +#define WF_PLE_TOP_C_DE_QUEUE_1_CUR_LIST_FID_START_SHFT 0 + +/* +* ---C_DE_QUEUE_2 (0x820C0000 + 0x88)--- +* DEQ_ENQ_DST_WLANID[9..0] - (RW) Destination WLAN ID for enqueue +command +* Only valid in Deq&Enq type. +* RESERVED10[11..10] - (RO) Reserved bits +* DEQ_ENQ_DST_TGID[12] - (RW) Destination TX Group ID for enqueue +command +* Only valid in Deq&Enq type. +* RESERVED13[13] - (RO) Reserved bits +* DEQ_ENQ_DST_PID[15..14] - (RW) Destination port ID for enqueue +command +* OInly valid in Deq&Enq type. +* RESERVED16[23..16] - (RO) Reserved bits +* DEQ_ENQ_DST_QID[30..24] - (RW) Destination queue ID for enqueue +command +* Only valid in Deq&Enq type. +* RESERVED31[31] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_QID_ADDR \ + WF_PLE_TOP_C_DE_QUEUE_2_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_QID_MASK \ + 0x7F000000 /* DEQ_ENQ_DST_QID[30..24] */ +#define WF_PLE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_QID_SHFT 24 +#define WF_PLE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_PID_ADDR \ + WF_PLE_TOP_C_DE_QUEUE_2_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_PID_MASK \ + 0x0000C000 /* DEQ_ENQ_DST_PID[15..14] */ +#define WF_PLE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_PID_SHFT 14 +#define WF_PLE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_TGID_ADDR \ + WF_PLE_TOP_C_DE_QUEUE_2_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_TGID_MASK \ + 0x00001000 /* DEQ_ENQ_DST_TGID[12] */ +#define WF_PLE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_TGID_SHFT 12 +#define WF_PLE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_WLANID_ADDR \ + WF_PLE_TOP_C_DE_QUEUE_2_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_WLANID_MASK \ + 0x000003FF /* DEQ_ENQ_DST_WLANID[9..0] */ +#define WF_PLE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_WLANID_SHFT 0 + +/* +* ---C_DE_QUEUE_3 (0x820C0000 + 0x8c)--- +* DEQ_HEAD_FID[11..0] - (RO) Head FID got from dequeue command +* RESERVED12[14..12] - (RO) Reserved bits +* DEQ_EMPTY[15] - (RO) Queue empty after dequeue command is +executed +* DEQ_TAIL_FID[27..16] - (RO) Last FID got from dequeue command +* RESERVED28[30..28] - (RO) Reserved bits +* BUSY[31] - (RO) Dequeue execute busy +*/ +#define WF_PLE_TOP_C_DE_QUEUE_3_BUSY_ADDR WF_PLE_TOP_C_DE_QUEUE_3_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_3_BUSY_MASK 0x80000000 /* BUSY[31] */ +#define WF_PLE_TOP_C_DE_QUEUE_3_BUSY_SHFT 31 +#define WF_PLE_TOP_C_DE_QUEUE_3_DEQ_TAIL_FID_ADDR \ + WF_PLE_TOP_C_DE_QUEUE_3_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_3_DEQ_TAIL_FID_MASK \ + 0x0FFF0000 /* DEQ_TAIL_FID[27..16] */ +#define WF_PLE_TOP_C_DE_QUEUE_3_DEQ_TAIL_FID_SHFT 16 +#define WF_PLE_TOP_C_DE_QUEUE_3_DEQ_EMPTY_ADDR \ + WF_PLE_TOP_C_DE_QUEUE_3_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_3_DEQ_EMPTY_MASK \ + 0x00008000 /* DEQ_EMPTY[15] */ +#define WF_PLE_TOP_C_DE_QUEUE_3_DEQ_EMPTY_SHFT 15 +#define WF_PLE_TOP_C_DE_QUEUE_3_DEQ_HEAD_FID_ADDR \ + WF_PLE_TOP_C_DE_QUEUE_3_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_3_DEQ_HEAD_FID_MASK \ + 0x00000FFF /* DEQ_HEAD_FID[11..0] */ +#define WF_PLE_TOP_C_DE_QUEUE_3_DEQ_HEAD_FID_SHFT 0 + +/* +* ---C_DE_QUEUE_4 (0x820C0000 + 0x90)--- +* DEQ_ENQ_REF_FID[11..0] - (RW) Reference frame ID for enqueue command +* Only valid in Deq&Enq type. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_C_DE_QUEUE_4_DEQ_ENQ_REF_FID_ADDR \ + WF_PLE_TOP_C_DE_QUEUE_4_ADDR +#define WF_PLE_TOP_C_DE_QUEUE_4_DEQ_ENQ_REF_FID_MASK \ + 0x00000FFF /* DEQ_ENQ_REF_FID[11..0] */ +#define WF_PLE_TOP_C_DE_QUEUE_4_DEQ_ENQ_REF_FID_SHFT 0 + +/* +* ---ALLOCATE_0 (0x820C0000 + 0xA0)--- +* ALLOCATE_FRAME_LENGTH[13..0] - (RW) Allocate frame length +* Unit: DW (4 bytes) +* RESERVED14[15..14] - (RO) Reserved bits +* ALLOCATE_QID[20..16] - (RW) QID used for allocate buffer +* RESERVED21[30..21] - (RO) Reserved bits +* EXECUTE[31] - (A0) Executes allocate buffer command +*/ +#define WF_PLE_TOP_ALLOCATE_0_EXECUTE_ADDR WF_PLE_TOP_ALLOCATE_0_ADDR +#define WF_PLE_TOP_ALLOCATE_0_EXECUTE_MASK \ + 0x80000000 /* EXECUTE[31] */ +#define WF_PLE_TOP_ALLOCATE_0_EXECUTE_SHFT 31 +#define WF_PLE_TOP_ALLOCATE_0_ALLOCATE_QID_ADDR \ + WF_PLE_TOP_ALLOCATE_0_ADDR +#define WF_PLE_TOP_ALLOCATE_0_ALLOCATE_QID_MASK \ + 0x001F0000 /* ALLOCATE_QID[20..16] */ +#define WF_PLE_TOP_ALLOCATE_0_ALLOCATE_QID_SHFT 16 +#define WF_PLE_TOP_ALLOCATE_0_ALLOCATE_FRAME_LENGTH_ADDR \ + WF_PLE_TOP_ALLOCATE_0_ADDR +#define WF_PLE_TOP_ALLOCATE_0_ALLOCATE_FRAME_LENGTH_MASK \ + 0x00003FFF /* ALLOCATE_FRAME_LENGTH[13..0] */ +#define WF_PLE_TOP_ALLOCATE_0_ALLOCATE_FRAME_LENGTH_SHFT 0 + +/* +* ---ALLOCATE_1 (0x820C0000 + 0xA4)--- +* ALLOCATE_FID[11..0] - (RO) Return frame ID for allocate buffer +command +* RESERVED12[30..12] - (RO) Reserved bits +* EXECUTE[31] - (RO) Execute status of allocate buffer +command +*/ +#define WF_PLE_TOP_ALLOCATE_1_EXECUTE_ADDR WF_PLE_TOP_ALLOCATE_1_ADDR +#define WF_PLE_TOP_ALLOCATE_1_EXECUTE_MASK \ + 0x80000000 /* EXECUTE[31] */ +#define WF_PLE_TOP_ALLOCATE_1_EXECUTE_SHFT 31 +#define WF_PLE_TOP_ALLOCATE_1_ALLOCATE_FID_ADDR \ + WF_PLE_TOP_ALLOCATE_1_ADDR +#define WF_PLE_TOP_ALLOCATE_1_ALLOCATE_FID_MASK \ + 0x00000FFF /* ALLOCATE_FID[11..0] */ +#define WF_PLE_TOP_ALLOCATE_1_ALLOCATE_FID_SHFT 0 + +/* +* ---ALLOCATE_2 (0x820C0000 + 0xA8)--- +* CPU_TXBYTE_COUNT[15..0] - (RW) TX data byte count +* This value should be the same as the first +* two bytes of TXD in PLE. +* CPU_MSDU_ID0_bit15_8[23..16] - (RW) MSDU_ID0 Bit15-Bit8 +* This value should be the same as the +* DW8[15:8] of TXD in PLE. +* CPU_PKT_FT[25..24] - (RW) TXD's PKT_FT +* This value should be the same as the +* DW0[24:23] of TXD in PLE. +* RESERVED26[31..26] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_ALLOCATE_2_CPU_PKT_FT_ADDR \ + WF_PLE_TOP_ALLOCATE_2_ADDR +#define WF_PLE_TOP_ALLOCATE_2_CPU_PKT_FT_MASK \ + 0x03000000 /* CPU_PKT_FT[25..24] */ +#define WF_PLE_TOP_ALLOCATE_2_CPU_PKT_FT_SHFT 24 +#define WF_PLE_TOP_ALLOCATE_2_CPU_MSDU_ID0_bit15_8_ADDR \ + WF_PLE_TOP_ALLOCATE_2_ADDR +#define WF_PLE_TOP_ALLOCATE_2_CPU_MSDU_ID0_bit15_8_MASK \ + 0x00FF0000 /* CPU_MSDU_ID0_bit15_8[23..16] */ +#define WF_PLE_TOP_ALLOCATE_2_CPU_MSDU_ID0_bit15_8_SHFT 16 +#define WF_PLE_TOP_ALLOCATE_2_CPU_TXBYTE_COUNT_ADDR \ + WF_PLE_TOP_ALLOCATE_2_ADDR +#define WF_PLE_TOP_ALLOCATE_2_CPU_TXBYTE_COUNT_MASK \ + 0x0000FFFF /* CPU_TXBYTE_COUNT[15..0] */ +#define WF_PLE_TOP_ALLOCATE_2_CPU_TXBYTE_COUNT_SHFT 0 + +/* +* ---QUEUE_EMPTY (0x820C0000 + 0xB0)--- +* CPU_Q0_EMPTY[0] - (RO) CPU queue 0 empty status +* CPU_Q1_EMPTY[1] - (RO) CPU queue 1 empty status +* CPU_Q2_EMPTY[2] - (RO) CPU queue 2 empty status +* CPU_Q3_EMPTY[3] - (RO) CPU queue 3 empty status +* RESERVED4[7..4] - (RO) Reserved bits +* ALTX_0_EMPTY[8] - (RO) ALTX queue 0 empty status +* BMC_0_EMPTY[9] - (RO) BMC queue 0 empty status +* BCN_0_EMPTY[10] - (RO) BCN queue 0 empty status +* PSMP_0_EMPTY[11] - (RO) PSMP queue 0 empty status +* ALTX_1_EMPTY[12] - (RO) ALTX queue 1 empty status +* BMC_1_EMPTY[13] - (RO) BMC queue 1 empty status +* BCN_1_EMPTY[14] - (RO) BCN queue 1 empty status +* PSMP_1_EMPTY[15] - (RO) PSMP queue 1 empty status +* NAF_EMPTY[16] - (RO) NAF queue empty status +* NBCN_EMPTY[17] - (RO) NBCN queue empty status +* RESERVED18[19..18] - (RO) Reserved bits +* FIX_FID_EMPTY[20] - (RO) FIX_FID queue empty status +* RESERVED21[23..21] - (RO) Reserved bits +* ALL_AC_EMPTY[24] - (RO) All AC queue empty status +* RESERVED25[29..25] - (RO) Reserved bits +* RLS2_Q_EMTPY[30] - (RO) Release 2 queue empty status +* RLS_Q_EMTPY[31] - (RO) Release queue empty status +*/ +#define WF_PLE_TOP_QUEUE_EMPTY_RLS_Q_EMTPY_ADDR \ + WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_RLS_Q_EMTPY_MASK \ + 0x80000000 /* RLS_Q_EMTPY[31] */ +#define WF_PLE_TOP_QUEUE_EMPTY_RLS_Q_EMTPY_SHFT 31 +#define WF_PLE_TOP_QUEUE_EMPTY_RLS2_Q_EMTPY_ADDR \ + WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_RLS2_Q_EMTPY_MASK \ + 0x40000000 /* RLS2_Q_EMTPY[30] */ +#define WF_PLE_TOP_QUEUE_EMPTY_RLS2_Q_EMTPY_SHFT 30 +#define WF_PLE_TOP_QUEUE_EMPTY_ALL_AC_EMPTY_ADDR \ + WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_ALL_AC_EMPTY_MASK \ + 0x01000000 /* ALL_AC_EMPTY[24] */ +#define WF_PLE_TOP_QUEUE_EMPTY_ALL_AC_EMPTY_SHFT 24 +#define WF_PLE_TOP_QUEUE_EMPTY_FIX_FID_EMPTY_ADDR \ + WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_FIX_FID_EMPTY_MASK \ + 0x00100000 /* FIX_FID_EMPTY[20] */ +#define WF_PLE_TOP_QUEUE_EMPTY_FIX_FID_EMPTY_SHFT 20 +#define WF_PLE_TOP_QUEUE_EMPTY_NBCN_EMPTY_ADDR \ + WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_NBCN_EMPTY_MASK \ + 0x00020000 /* NBCN_EMPTY[17] */ +#define WF_PLE_TOP_QUEUE_EMPTY_NBCN_EMPTY_SHFT 17 +#define WF_PLE_TOP_QUEUE_EMPTY_NAF_EMPTY_ADDR \ + WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_NAF_EMPTY_MASK \ + 0x00010000 /* NAF_EMPTY[16] */ +#define WF_PLE_TOP_QUEUE_EMPTY_NAF_EMPTY_SHFT 16 +#define WF_PLE_TOP_QUEUE_EMPTY_PSMP_1_EMPTY_ADDR \ + WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_PSMP_1_EMPTY_MASK \ + 0x00008000 /* PSMP_1_EMPTY[15] */ +#define WF_PLE_TOP_QUEUE_EMPTY_PSMP_1_EMPTY_SHFT 15 +#define WF_PLE_TOP_QUEUE_EMPTY_BCN_1_EMPTY_ADDR \ + WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_BCN_1_EMPTY_MASK \ + 0x00004000 /* BCN_1_EMPTY[14] */ +#define WF_PLE_TOP_QUEUE_EMPTY_BCN_1_EMPTY_SHFT 14 +#define WF_PLE_TOP_QUEUE_EMPTY_BMC_1_EMPTY_ADDR \ + WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_BMC_1_EMPTY_MASK \ + 0x00002000 /* BMC_1_EMPTY[13] */ +#define WF_PLE_TOP_QUEUE_EMPTY_BMC_1_EMPTY_SHFT 13 +#define WF_PLE_TOP_QUEUE_EMPTY_ALTX_1_EMPTY_ADDR \ + WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_ALTX_1_EMPTY_MASK \ + 0x00001000 /* ALTX_1_EMPTY[12] */ +#define WF_PLE_TOP_QUEUE_EMPTY_ALTX_1_EMPTY_SHFT 12 +#define WF_PLE_TOP_QUEUE_EMPTY_PSMP_0_EMPTY_ADDR \ + WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_PSMP_0_EMPTY_MASK \ + 0x00000800 /* PSMP_0_EMPTY[11] */ +#define WF_PLE_TOP_QUEUE_EMPTY_PSMP_0_EMPTY_SHFT 11 +#define WF_PLE_TOP_QUEUE_EMPTY_BCN_0_EMPTY_ADDR \ + WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_BCN_0_EMPTY_MASK \ + 0x00000400 /* BCN_0_EMPTY[10] */ +#define WF_PLE_TOP_QUEUE_EMPTY_BCN_0_EMPTY_SHFT 10 +#define WF_PLE_TOP_QUEUE_EMPTY_BMC_0_EMPTY_ADDR \ + WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_BMC_0_EMPTY_MASK \ + 0x00000200 /* BMC_0_EMPTY[9] */ +#define WF_PLE_TOP_QUEUE_EMPTY_BMC_0_EMPTY_SHFT 9 +#define WF_PLE_TOP_QUEUE_EMPTY_ALTX_0_EMPTY_ADDR \ + WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_ALTX_0_EMPTY_MASK \ + 0x00000100 /* ALTX_0_EMPTY[8] */ +#define WF_PLE_TOP_QUEUE_EMPTY_ALTX_0_EMPTY_SHFT 8 +#define WF_PLE_TOP_QUEUE_EMPTY_CPU_Q3_EMPTY_ADDR \ + WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_CPU_Q3_EMPTY_MASK \ + 0x00000008 /* CPU_Q3_EMPTY[3] */ +#define WF_PLE_TOP_QUEUE_EMPTY_CPU_Q3_EMPTY_SHFT 3 +#define WF_PLE_TOP_QUEUE_EMPTY_CPU_Q2_EMPTY_ADDR \ + WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_CPU_Q2_EMPTY_MASK \ + 0x00000004 /* CPU_Q2_EMPTY[2] */ +#define WF_PLE_TOP_QUEUE_EMPTY_CPU_Q2_EMPTY_SHFT 2 +#define WF_PLE_TOP_QUEUE_EMPTY_CPU_Q1_EMPTY_ADDR \ + WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_CPU_Q1_EMPTY_MASK \ + 0x00000002 /* CPU_Q1_EMPTY[1] */ +#define WF_PLE_TOP_QUEUE_EMPTY_CPU_Q1_EMPTY_SHFT 1 +#define WF_PLE_TOP_QUEUE_EMPTY_CPU_Q0_EMPTY_ADDR \ + WF_PLE_TOP_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_QUEUE_EMPTY_CPU_Q0_EMPTY_MASK \ + 0x00000001 /* CPU_Q0_EMPTY[0] */ +#define WF_PLE_TOP_QUEUE_EMPTY_CPU_Q0_EMPTY_SHFT 0 + +/* +* ---FREEPG_START_END (0x820C0000 + 0xc0)--- +* FREEPG_START[11..0] - (RW) Start page for free page list +* Set start page before release PLE logic +* reset, and must not be changed after release logic reset. +* RESERVED12[15..12] - (RO) Reserved bits +* FREEPG_END[27..16] - (RW) End page for free page list +* Set end page before release PLE logic +* reset, and must not be changed after release logic reset. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_FREEPG_START_END_FREEPG_END_ADDR \ + WF_PLE_TOP_FREEPG_START_END_ADDR +#define WF_PLE_TOP_FREEPG_START_END_FREEPG_END_MASK \ + 0x0FFF0000 /* FREEPG_END[27..16] */ +#define WF_PLE_TOP_FREEPG_START_END_FREEPG_END_SHFT 16 +#define WF_PLE_TOP_FREEPG_START_END_FREEPG_START_ADDR \ + WF_PLE_TOP_FREEPG_START_END_ADDR +#define WF_PLE_TOP_FREEPG_START_END_FREEPG_START_MASK \ + 0x00000FFF /* FREEPG_START[11..0] */ +#define WF_PLE_TOP_FREEPG_START_END_FREEPG_START_SHFT 0 + +/* +* ---PLE_MODULE_CKG_DIS (0x820C0000 + 0xc4)--- +* DIS_FL_DYN_CKG[0] - (RW) Disable control of PLE frame link module +* dynamic clock gating function +* DIS_PL_DYN_CKG[1] - (RW) Disable control of PLE page link module +* dynamic clock gating function +* DIS_CPU_PORT_DYN_CKG[2] - (RW) Disable control of PLE CPU port +module +* dynamic clock gating function +* DIS_HIF_PORT_DYN_CKG[3] - (RW) Disable control of PLE HIF port +module +* dynamic clock gating function +* DIS_WF_PORT_DYN_CKG[4] - (RW) Disable control of PLE LMAC module +* dynamic clock gating function +* DIS_RLS_DYN_CKG[5] - (RW) Disable control of PLE release module +* dynamic clock gating function +* DIS_RL_DYN_CKG[6] - (RW) Disable control of PLE relay information +* module dynamic clock gating function +* DIS_MACTX_DYN_CKG[7] - (RW) Disable control of PLE MACTX module +* dynamic clock gating function +* DIS_PSEPORT_DYN_CKG[8] - (RW) Disable control of PLE PSE port module +* dynamic clock gating function +* DIS_CSR_DYN_CKG[9] - (RW) Disable control of PLE CR module dynamic +* clock gating function +* DIS_CPU_WRAP_DYN_CKG[10] - (RW) Disable control of PLE CPU_WRAP +module +* dynamic clock gating function +* DIS_DBG_DYN_CKG[11] - (RW) Disable control of PLE debug module +* dynamic clock gating function +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_DBG_DYN_CKG_ADDR \ + WF_PLE_TOP_PLE_MODULE_CKG_DIS_ADDR +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_DBG_DYN_CKG_MASK \ + 0x00000800 /* DIS_DBG_DYN_CKG[11] */ +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_DBG_DYN_CKG_SHFT 11 +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_CPU_WRAP_DYN_CKG_ADDR \ + WF_PLE_TOP_PLE_MODULE_CKG_DIS_ADDR +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_CPU_WRAP_DYN_CKG_MASK \ + 0x00000400 /* DIS_CPU_WRAP_DYN_CKG[10] */ +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_CPU_WRAP_DYN_CKG_SHFT 10 +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_CSR_DYN_CKG_ADDR \ + WF_PLE_TOP_PLE_MODULE_CKG_DIS_ADDR +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_CSR_DYN_CKG_MASK \ + 0x00000200 /* DIS_CSR_DYN_CKG[9] */ +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_CSR_DYN_CKG_SHFT 9 +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_PSEPORT_DYN_CKG_ADDR \ + WF_PLE_TOP_PLE_MODULE_CKG_DIS_ADDR +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_PSEPORT_DYN_CKG_MASK \ + 0x00000100 /* DIS_PSEPORT_DYN_CKG[8] */ +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_PSEPORT_DYN_CKG_SHFT 8 +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_MACTX_DYN_CKG_ADDR \ + WF_PLE_TOP_PLE_MODULE_CKG_DIS_ADDR +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_MACTX_DYN_CKG_MASK \ + 0x00000080 /* DIS_MACTX_DYN_CKG[7] */ +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_MACTX_DYN_CKG_SHFT 7 +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_RL_DYN_CKG_ADDR \ + WF_PLE_TOP_PLE_MODULE_CKG_DIS_ADDR +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_RL_DYN_CKG_MASK \ + 0x00000040 /* DIS_RL_DYN_CKG[6] */ +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_RL_DYN_CKG_SHFT 6 +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_RLS_DYN_CKG_ADDR \ + WF_PLE_TOP_PLE_MODULE_CKG_DIS_ADDR +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_RLS_DYN_CKG_MASK \ + 0x00000020 /* DIS_RLS_DYN_CKG[5] */ +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_RLS_DYN_CKG_SHFT 5 +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_WF_PORT_DYN_CKG_ADDR \ + WF_PLE_TOP_PLE_MODULE_CKG_DIS_ADDR +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_WF_PORT_DYN_CKG_MASK \ + 0x00000010 /* DIS_WF_PORT_DYN_CKG[4] */ +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_WF_PORT_DYN_CKG_SHFT 4 +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_HIF_PORT_DYN_CKG_ADDR \ + WF_PLE_TOP_PLE_MODULE_CKG_DIS_ADDR +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_HIF_PORT_DYN_CKG_MASK \ + 0x00000008 /* DIS_HIF_PORT_DYN_CKG[3] */ +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_HIF_PORT_DYN_CKG_SHFT 3 +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_CPU_PORT_DYN_CKG_ADDR \ + WF_PLE_TOP_PLE_MODULE_CKG_DIS_ADDR +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_CPU_PORT_DYN_CKG_MASK \ + 0x00000004 /* DIS_CPU_PORT_DYN_CKG[2] */ +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_CPU_PORT_DYN_CKG_SHFT 2 +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_PL_DYN_CKG_ADDR \ + WF_PLE_TOP_PLE_MODULE_CKG_DIS_ADDR +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_PL_DYN_CKG_MASK \ + 0x00000002 /* DIS_PL_DYN_CKG[1] */ +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_PL_DYN_CKG_SHFT 1 +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_FL_DYN_CKG_ADDR \ + WF_PLE_TOP_PLE_MODULE_CKG_DIS_ADDR +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_FL_DYN_CKG_MASK \ + 0x00000001 /* DIS_FL_DYN_CKG[0] */ +#define WF_PLE_TOP_PLE_MODULE_CKG_DIS_DIS_FL_DYN_CKG_SHFT 0 + +/* +* ---INT_N9_ERR_STS_1 (0x820C0000 + 0xd8)--- +* BN0_MDP_TDP_HANG_ERR[0] - (W1C) BN0 MDP TDP FSM hang error +interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* MDP_RDP_HANG_ERR[1] - (W1C) MDP RDP FSM hang error interrupt. Avoid +* unclear error flag, please clear flag when logic reset. +* BN0_MDP_TIOC_HANG_ERR[2] - (W1C) BN0 MDP TIOC FSM hang error +interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* BN0_MDP_RIOC_HANG_ERR[3] - (W1C) BN0 MDP RIOC FSM hang error +interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* PF_HANG_ERR[4] - (W1C) PF FSM hang error interrupt. Avoid +* unclear error flag, please clear flag when logic reset. +* SEC0_HANG_ERR[5] - (W1C) SEC 0 FSM hang error interrupt. Avoid +* unclear error flag, please clear flag when logic reset. +* SEC1_HANG_ERR[6] - (W1C) SEC 1 FSM hang error interrupt. Avoid +* unclear error flag, please clear flag when logic reset. +* BN1_MDP_TDP_HANG_ERR[7] - (W1C) BN1 MDP TDP FSM hang error +interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* BN1_MDP_TIOC_HANG_ERR[8] - (W1C) BN1 MDP TIOC FSM hang error +interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* BN1_MDP_RIOC_HANG_ERR[9] - (W1C) BN1 MDP RIOC FSM hang error +interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* RESERVED10[11..10] - (RO) Reserved bits +* BN0_RPEDL_ARB_HANG_ERR[12] - (W1C) BN0 PREDL ARB hang error +interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* BN0_PREDL_TXCMD_HANG_ERR[13] - (W1C) BN0 PREDL TXCDM FSM hang error +* interrupt. Avoid unclear error flag, please clear flag when logic +reset. +* BN1_RPEDL_ARB_HANG_ERR[14] - (W1C) BN1 PREDL ARB hang error +interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* BN1_PREDL_TXCMD_HANG_ERR[15] - (W1C) BN1 PREDL TXCDM FSM hang error +* interrupt. Avoid unclear error flag, please clear flag when logic +reset. +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_PREDL_TXCMD_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_PREDL_TXCMD_HANG_ERR_MASK \ + 0x00008000 /* BN1_PREDL_TXCMD_HANG_ERR[15] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_PREDL_TXCMD_HANG_ERR_SHFT 15 +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_RPEDL_ARB_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_RPEDL_ARB_HANG_ERR_MASK \ + 0x00004000 /* BN1_RPEDL_ARB_HANG_ERR[14] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_RPEDL_ARB_HANG_ERR_SHFT 14 +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_PREDL_TXCMD_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_PREDL_TXCMD_HANG_ERR_MASK \ + 0x00002000 /* BN0_PREDL_TXCMD_HANG_ERR[13] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_PREDL_TXCMD_HANG_ERR_SHFT 13 +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_RPEDL_ARB_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_RPEDL_ARB_HANG_ERR_MASK \ + 0x00001000 /* BN0_RPEDL_ARB_HANG_ERR[12] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_RPEDL_ARB_HANG_ERR_SHFT 12 +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_MDP_RIOC_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_MDP_RIOC_HANG_ERR_MASK \ + 0x00000200 /* BN1_MDP_RIOC_HANG_ERR[9] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_MDP_RIOC_HANG_ERR_SHFT 9 +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_MDP_TIOC_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_MDP_TIOC_HANG_ERR_MASK \ + 0x00000100 /* BN1_MDP_TIOC_HANG_ERR[8] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_MDP_TIOC_HANG_ERR_SHFT 8 +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_MDP_TDP_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_MDP_TDP_HANG_ERR_MASK \ + 0x00000080 /* BN1_MDP_TDP_HANG_ERR[7] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN1_MDP_TDP_HANG_ERR_SHFT 7 +#define WF_PLE_TOP_INT_N9_ERR_STS_1_SEC1_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_1_SEC1_HANG_ERR_MASK \ + 0x00000040 /* SEC1_HANG_ERR[6] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_SEC1_HANG_ERR_SHFT 6 +#define WF_PLE_TOP_INT_N9_ERR_STS_1_SEC0_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_1_SEC0_HANG_ERR_MASK \ + 0x00000020 /* SEC0_HANG_ERR[5] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_SEC0_HANG_ERR_SHFT 5 +#define WF_PLE_TOP_INT_N9_ERR_STS_1_PF_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_1_PF_HANG_ERR_MASK \ + 0x00000010 /* PF_HANG_ERR[4] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_PF_HANG_ERR_SHFT 4 +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_MDP_RIOC_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_MDP_RIOC_HANG_ERR_MASK \ + 0x00000008 /* BN0_MDP_RIOC_HANG_ERR[3] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_MDP_RIOC_HANG_ERR_SHFT 3 +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_MDP_TIOC_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_MDP_TIOC_HANG_ERR_MASK \ + 0x00000004 /* BN0_MDP_TIOC_HANG_ERR[2] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_MDP_TIOC_HANG_ERR_SHFT 2 +#define WF_PLE_TOP_INT_N9_ERR_STS_1_MDP_RDP_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_1_MDP_RDP_HANG_ERR_MASK \ + 0x00000002 /* MDP_RDP_HANG_ERR[1] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_MDP_RDP_HANG_ERR_SHFT 1 +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_MDP_TDP_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_STS_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_MDP_TDP_HANG_ERR_MASK \ + 0x00000001 /* BN0_MDP_TDP_HANG_ERR[0] */ +#define WF_PLE_TOP_INT_N9_ERR_STS_1_BN0_MDP_TDP_HANG_ERR_SHFT 0 + +/* +* ---INT_N9_ERR_MASK_1 (0x820C0000 + 0xdc)--- +* EN_BN0_MDP_TDP_HANG_ERR[0] - (RW) Enables Band0 MDP TDP FSM hang +error +interrupt +* EN_MDP_RDP_HANG_ERR[1] - (RW) Enables MDP RDP FSM hang error +interrupt +* EN_BN0_MDP_TIOC_HANG_ERR[2] - (RW) Enables Band0 MDP TIOC FSM hang +error +interrupt +* EN_BN0_MDP_RIOC_HANG_ERR[3] - (RW) Enables Band0 MDP RIOC FSM hang +error +interrupt +* EN_PF_HANG_ERR[4] - (RW) Enables PF FSM hang error interrupt +* EN_SEC0_HANG_ERR[5] - (RW) Enables SEC 0 FSM hang error interrupt +* EN_SEC1_HANG_ERR[6] - (RW) Enables SEC 1 FSM hang error interrupt +* EN_BN1_MDP_TDP_HANG_ERR[7] - (RW) Enables Band1 MDP TDP FSM hang +error +interrupt +* EN_BN1_MDP_TIOC_HANG_ERR[8] - (RW) Enables Band1 MDP TIOC FSM hang +error +interrupt +* EN_BN1_MDP_RIOC_HANG_ERR[9] - (RW) Enables Band1 MDP RIOC FSM hang +error +interrupt +* RESERVED10[11..10] - (RO) Reserved bits +* EN_BN0_PREDL_ARB_HANG_ERR[12] - (RW) Enables Band0 PREDL ARB FSM +* hang error +interrupt +* EN_BN0_PREDL_TXCMD_HANG_ERR[13] - (RW) Enables Band0 PREDL TXCMD +* parser FSM +* hang error interrupt +* EN_BN1_PREDL_ARB_HANG_ERR[14] - (RW) Enables Band1 PREDL ARB FSM +* hang error +interrupt +* EN_BN1_PREDL_TXCMD_HANG_ERR[15] - (RW) Enables Band1 PREDL TXCMD +* parser FSM +* hang error interrupt +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define \ +WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_PREDL_TXCMD_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR +#define \ +WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_PREDL_TXCMD_HANG_ERR_MASK \ + 0x00008000 /* EN_BN1_PREDL_TXCMD_HANG_ERR[15] */ +#define \ +WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_PREDL_TXCMD_HANG_ERR_SHFT \ + 15 +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_PREDL_ARB_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_PREDL_ARB_HANG_ERR_MASK \ + 0x00004000 /* EN_BN1_PREDL_ARB_HANG_ERR[14] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_PREDL_ARB_HANG_ERR_SHFT 14 +#define \ +WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_PREDL_TXCMD_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR +#define \ +WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_PREDL_TXCMD_HANG_ERR_MASK \ + 0x00002000 /* EN_BN0_PREDL_TXCMD_HANG_ERR[13] */ +#define \ +WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_PREDL_TXCMD_HANG_ERR_SHFT \ + 13 +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_PREDL_ARB_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_PREDL_ARB_HANG_ERR_MASK \ + 0x00001000 /* EN_BN0_PREDL_ARB_HANG_ERR[12] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_PREDL_ARB_HANG_ERR_SHFT 12 +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_MDP_RIOC_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_MDP_RIOC_HANG_ERR_MASK \ + 0x00000200 /* EN_BN1_MDP_RIOC_HANG_ERR[9] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_MDP_RIOC_HANG_ERR_SHFT 9 +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_MDP_TIOC_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_MDP_TIOC_HANG_ERR_MASK \ + 0x00000100 /* EN_BN1_MDP_TIOC_HANG_ERR[8] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_MDP_TIOC_HANG_ERR_SHFT 8 +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_MDP_TDP_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_MDP_TDP_HANG_ERR_MASK \ + 0x00000080 /* EN_BN1_MDP_TDP_HANG_ERR[7] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN1_MDP_TDP_HANG_ERR_SHFT 7 +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_SEC1_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_SEC1_HANG_ERR_MASK \ + 0x00000040 /* EN_SEC1_HANG_ERR[6] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_SEC1_HANG_ERR_SHFT 6 +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_SEC0_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_SEC0_HANG_ERR_MASK \ + 0x00000020 /* EN_SEC0_HANG_ERR[5] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_SEC0_HANG_ERR_SHFT 5 +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_PF_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_PF_HANG_ERR_MASK \ + 0x00000010 /* EN_PF_HANG_ERR[4] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_PF_HANG_ERR_SHFT 4 +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_MDP_RIOC_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_MDP_RIOC_HANG_ERR_MASK \ + 0x00000008 /* EN_BN0_MDP_RIOC_HANG_ERR[3] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_MDP_RIOC_HANG_ERR_SHFT 3 +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_MDP_TIOC_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_MDP_TIOC_HANG_ERR_MASK \ + 0x00000004 /* EN_BN0_MDP_TIOC_HANG_ERR[2] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_MDP_TIOC_HANG_ERR_SHFT 2 +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_MDP_RDP_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_MDP_RDP_HANG_ERR_MASK \ + 0x00000002 /* EN_MDP_RDP_HANG_ERR[1] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_MDP_RDP_HANG_ERR_SHFT 1 +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_MDP_TDP_HANG_ERR_ADDR \ + WF_PLE_TOP_INT_N9_ERR_MASK_1_ADDR +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_MDP_TDP_HANG_ERR_MASK \ + 0x00000001 /* EN_BN0_MDP_TDP_HANG_ERR[0] */ +#define WF_PLE_TOP_INT_N9_ERR_MASK_1_EN_BN0_MDP_TDP_HANG_ERR_SHFT 0 + +/* +* ---TO_N9_INT (0x820C0000 + 0xf0)--- +* CR4_CMD[30..0] - (RW) Command for N9 +* TOGGLE[31] - (RW) When this bit is toggled, HW will send +* interrupt to N9. +*/ +#define WF_PLE_TOP_TO_N9_INT_TOGGLE_ADDR WF_PLE_TOP_TO_N9_INT_ADDR +#define WF_PLE_TOP_TO_N9_INT_TOGGLE_MASK 0x80000000 /* TOGGLE[31] */ +#define WF_PLE_TOP_TO_N9_INT_TOGGLE_SHFT 31 +#define WF_PLE_TOP_TO_N9_INT_CR4_CMD_ADDR WF_PLE_TOP_TO_N9_INT_ADDR +#define WF_PLE_TOP_TO_N9_INT_CR4_CMD_MASK \ + 0x7FFFFFFF /* CR4_CMD[30..0] */ +#define WF_PLE_TOP_TO_N9_INT_CR4_CMD_SHFT 0 + +/* +* ---N9_BSS_PS_INT_MASK (0x820C0000 + 0xf4)--- +* EN_BSSID0_NONEMPTY_INT[0] - (RW) Enable control of BSSID0 queue +empty +fall +* EN_BSSID1_NONEMPTY_INT[1] - (RW) Enable control of BSSID1 queue +empty +fall +* EN_BSSID2_NONEMPTY_INT[2] - (RW) Enable control of BSSID2 queue +empty +fall +* EN_BSSID3_NONEMPTY_INT[3] - (RW) Enable control of BSSID3 queue +empty +fall +* RESERVED4[7..4] - (RO) Reserved bits +* EN_BSSID0_EMPTY_INT[8] - (RW) Enable control of BSSID0 queue empty +raise +* EN_BSSID1_EMPTY_INT[9] - (RW) Enable control of BSSID1 queue empty +raise +* EN_BSSID2_EMPTY_INT[10] - (RW) Enable control of BSSID2 queue empty +raise +* EN_BSSID3_EMPTY_INT[11] - (RW) Enable control of BSSID3 queue empty +raise +* RESERVED12[15..12] - (RO) Reserved bits +* EN_BSSID0_ENQ_LMAC_INT[16] - (RW) Enable control of BSSID0 enqueue +interrupt +* EN_BSSID1_ENQ_LMAC_INT[17] - (RW) Enable control of BSSID1 enqueue +interrupt +* EN_BSSID2_ENQ_LMAC_INT[18] - (RW) Enable control of BSSID2 enqueue +interrupt +* EN_BSSID3_ENQ_LMAC_INT[19] - (RW) Enable control of BSSID3 enqueue +interrupt +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID3_ENQ_LMAC_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_MASK_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID3_ENQ_LMAC_INT_MASK \ + 0x00080000 /* EN_BSSID3_ENQ_LMAC_INT[19] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID3_ENQ_LMAC_INT_SHFT 19 +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID2_ENQ_LMAC_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_MASK_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID2_ENQ_LMAC_INT_MASK \ + 0x00040000 /* EN_BSSID2_ENQ_LMAC_INT[18] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID2_ENQ_LMAC_INT_SHFT 18 +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID1_ENQ_LMAC_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_MASK_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID1_ENQ_LMAC_INT_MASK \ + 0x00020000 /* EN_BSSID1_ENQ_LMAC_INT[17] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID1_ENQ_LMAC_INT_SHFT 17 +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID0_ENQ_LMAC_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_MASK_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID0_ENQ_LMAC_INT_MASK \ + 0x00010000 /* EN_BSSID0_ENQ_LMAC_INT[16] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID0_ENQ_LMAC_INT_SHFT 16 +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID3_EMPTY_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_MASK_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID3_EMPTY_INT_MASK \ + 0x00000800 /* EN_BSSID3_EMPTY_INT[11] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID3_EMPTY_INT_SHFT 11 +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID2_EMPTY_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_MASK_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID2_EMPTY_INT_MASK \ + 0x00000400 /* EN_BSSID2_EMPTY_INT[10] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID2_EMPTY_INT_SHFT 10 +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID1_EMPTY_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_MASK_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID1_EMPTY_INT_MASK \ + 0x00000200 /* EN_BSSID1_EMPTY_INT[9] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID1_EMPTY_INT_SHFT 9 +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID0_EMPTY_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_MASK_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID0_EMPTY_INT_MASK \ + 0x00000100 /* EN_BSSID0_EMPTY_INT[8] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID0_EMPTY_INT_SHFT 8 +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID3_NONEMPTY_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_MASK_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID3_NONEMPTY_INT_MASK \ + 0x00000008 /* EN_BSSID3_NONEMPTY_INT[3] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID3_NONEMPTY_INT_SHFT 3 +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID2_NONEMPTY_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_MASK_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID2_NONEMPTY_INT_MASK \ + 0x00000004 /* EN_BSSID2_NONEMPTY_INT[2] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID2_NONEMPTY_INT_SHFT 2 +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID1_NONEMPTY_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_MASK_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID1_NONEMPTY_INT_MASK \ + 0x00000002 /* EN_BSSID1_NONEMPTY_INT[1] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID1_NONEMPTY_INT_SHFT 1 +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID0_NONEMPTY_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_MASK_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID0_NONEMPTY_INT_MASK \ + 0x00000001 /* EN_BSSID0_NONEMPTY_INT[0] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_MASK_EN_BSSID0_NONEMPTY_INT_SHFT 0 + +/* +* ---N9_BSS_PS_INT_STS (0x820C0000 + 0xf8)--- +* BSSID0_NONEMPTY_INT[0] - (W1C) BSSID0 queue empty fall interrupt +status +* BSSID1_NONEMPTY_INT[1] - (W1C) BSSID1 queue empty fall interrupt +status +* BSSID2_NONEMPTY_INT[2] - (W1C) BSSID2 queue empty fall interrupt +status +* BSSID3_NONEMPTY_INT[3] - (W1C) BSSID3 queue empty fall interrupt +status +* RESERVED4[7..4] - (RO) Reserved bits +* BSSID0_EMPTY_INT[8] - (W1C) BSSID0 queue empty raise interrupt +status +* BSSID1_EMPTY_INT[9] - (W1C) BSSID1 queue empty raise interrupt +status +* BSSID2_EMPTY_INT[10] - (W1C) BSSID2 queue empty raise interrupt +status +* BSSID3_EMPTY_INT[11] - (W1C) BSSID3 queue empty raise interrupt +status +* RESERVED12[15..12] - (RO) Reserved bits +* BSSID0_ENQ_LMAC_INT[16] - (W1C) BSSID0 enqueue interrupt status +* BSSID1_ENQ_LMAC_INT[17] - (W1C) BSSID1 enqueue interrupt status +* BSSID2_ENQ_LMAC_INT[18] - (W1C) BSSID2 enqueue interrupt status +* BSSID3_ENQ_LMAC_INT[19] - (W1C) BSSID3 enqueue interrupt status +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID3_ENQ_LMAC_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_STS_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID3_ENQ_LMAC_INT_MASK \ + 0x00080000 /* BSSID3_ENQ_LMAC_INT[19] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID3_ENQ_LMAC_INT_SHFT 19 +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID2_ENQ_LMAC_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_STS_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID2_ENQ_LMAC_INT_MASK \ + 0x00040000 /* BSSID2_ENQ_LMAC_INT[18] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID2_ENQ_LMAC_INT_SHFT 18 +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID1_ENQ_LMAC_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_STS_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID1_ENQ_LMAC_INT_MASK \ + 0x00020000 /* BSSID1_ENQ_LMAC_INT[17] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID1_ENQ_LMAC_INT_SHFT 17 +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID0_ENQ_LMAC_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_STS_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID0_ENQ_LMAC_INT_MASK \ + 0x00010000 /* BSSID0_ENQ_LMAC_INT[16] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID0_ENQ_LMAC_INT_SHFT 16 +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID3_EMPTY_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_STS_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID3_EMPTY_INT_MASK \ + 0x00000800 /* BSSID3_EMPTY_INT[11] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID3_EMPTY_INT_SHFT 11 +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID2_EMPTY_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_STS_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID2_EMPTY_INT_MASK \ + 0x00000400 /* BSSID2_EMPTY_INT[10] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID2_EMPTY_INT_SHFT 10 +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID1_EMPTY_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_STS_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID1_EMPTY_INT_MASK \ + 0x00000200 /* BSSID1_EMPTY_INT[9] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID1_EMPTY_INT_SHFT 9 +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID0_EMPTY_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_STS_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID0_EMPTY_INT_MASK \ + 0x00000100 /* BSSID0_EMPTY_INT[8] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID0_EMPTY_INT_SHFT 8 +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID3_NONEMPTY_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_STS_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID3_NONEMPTY_INT_MASK \ + 0x00000008 /* BSSID3_NONEMPTY_INT[3] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID3_NONEMPTY_INT_SHFT 3 +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID2_NONEMPTY_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_STS_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID2_NONEMPTY_INT_MASK \ + 0x00000004 /* BSSID2_NONEMPTY_INT[2] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID2_NONEMPTY_INT_SHFT 2 +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID1_NONEMPTY_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_STS_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID1_NONEMPTY_INT_MASK \ + 0x00000002 /* BSSID1_NONEMPTY_INT[1] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID1_NONEMPTY_INT_SHFT 1 +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID0_NONEMPTY_INT_ADDR \ + WF_PLE_TOP_N9_BSS_PS_INT_STS_ADDR +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID0_NONEMPTY_INT_MASK \ + 0x00000001 /* BSSID0_NONEMPTY_INT[0] */ +#define WF_PLE_TOP_N9_BSS_PS_INT_STS_BSSID0_NONEMPTY_INT_SHFT 0 + +/* +* ---FREEPG_CNT (0x820C0000 + 0x100)--- +* FREEPG_CNT[11..0] - (RO) Total page number of free +* RESERVED12[15..12] - (RO) Reserved bits +* FFA_CNT[27..16] - (RO) Free page numbers of free for all +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_FREEPG_CNT_FFA_CNT_ADDR WF_PLE_TOP_FREEPG_CNT_ADDR +#define WF_PLE_TOP_FREEPG_CNT_FFA_CNT_MASK \ + 0x0FFF0000 /* FFA_CNT[27..16] */ +#define WF_PLE_TOP_FREEPG_CNT_FFA_CNT_SHFT 16 +#define WF_PLE_TOP_FREEPG_CNT_FREEPG_CNT_ADDR \ + WF_PLE_TOP_FREEPG_CNT_ADDR +#define WF_PLE_TOP_FREEPG_CNT_FREEPG_CNT_MASK \ + 0x00000FFF /* FREEPG_CNT[11..0] */ +#define WF_PLE_TOP_FREEPG_CNT_FREEPG_CNT_SHFT 0 + +/* +* ---FREEPG_HEAD_TAIL (0x820C0000 + 0x104)--- +* FREEPG_HEAD[11..0] - (RO) Head page of free page list +* RESERVED12[15..12] - (RO) Reserved bits +* FREEPG_TAIL[27..16] - (RO) Tail page of free page list +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_FREEPG_HEAD_TAIL_FREEPG_TAIL_ADDR \ + WF_PLE_TOP_FREEPG_HEAD_TAIL_ADDR +#define WF_PLE_TOP_FREEPG_HEAD_TAIL_FREEPG_TAIL_MASK \ + 0x0FFF0000 /* FREEPG_TAIL[27..16] */ +#define WF_PLE_TOP_FREEPG_HEAD_TAIL_FREEPG_TAIL_SHFT 16 +#define WF_PLE_TOP_FREEPG_HEAD_TAIL_FREEPG_HEAD_ADDR \ + WF_PLE_TOP_FREEPG_HEAD_TAIL_ADDR +#define WF_PLE_TOP_FREEPG_HEAD_TAIL_FREEPG_HEAD_MASK \ + 0x00000FFF /* FREEPG_HEAD[11..0] */ +#define WF_PLE_TOP_FREEPG_HEAD_TAIL_FREEPG_HEAD_SHFT 0 + +/* +* ---PG_HIF_GROUP (0x820C0000 + 0x110)--- +* HIF_MIN_QUOTA[11..0] - (RW) Min. quota of HIF group +* Set the quota before release PLE logic +* reset ,and must not be changed after release logic reset. +* RESERVED12[15..12] - (RO) Reserved bits +* HIF_MAX_QUOTA[27..16] - (RW) Max. quota of HIF group +* Set up the quota before releasing PLE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_PG_HIF_GROUP_HIF_MAX_QUOTA_ADDR \ + WF_PLE_TOP_PG_HIF_GROUP_ADDR +#define WF_PLE_TOP_PG_HIF_GROUP_HIF_MAX_QUOTA_MASK \ + 0x0FFF0000 /* HIF_MAX_QUOTA[27..16] */ +#define WF_PLE_TOP_PG_HIF_GROUP_HIF_MAX_QUOTA_SHFT 16 +#define WF_PLE_TOP_PG_HIF_GROUP_HIF_MIN_QUOTA_ADDR \ + WF_PLE_TOP_PG_HIF_GROUP_ADDR +#define WF_PLE_TOP_PG_HIF_GROUP_HIF_MIN_QUOTA_MASK \ + 0x00000FFF /* HIF_MIN_QUOTA[11..0] */ +#define WF_PLE_TOP_PG_HIF_GROUP_HIF_MIN_QUOTA_SHFT 0 + +/* +* ---HIF_PG_INFO (0x820C0000 + 0x114)--- +* HIF_RSV_CNT[11..0] - (RO) Reserved pages of HIF group +* RESERVED12[15..12] - (RO) Reserved bits +* HIF_SRC_CNT[27..16] - (RO) Used pages of HIF group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_HIF_PG_INFO_HIF_SRC_CNT_ADDR \ + WF_PLE_TOP_HIF_PG_INFO_ADDR +#define WF_PLE_TOP_HIF_PG_INFO_HIF_SRC_CNT_MASK \ + 0x0FFF0000 /* HIF_SRC_CNT[27..16] */ +#define WF_PLE_TOP_HIF_PG_INFO_HIF_SRC_CNT_SHFT 16 +#define WF_PLE_TOP_HIF_PG_INFO_HIF_RSV_CNT_ADDR \ + WF_PLE_TOP_HIF_PG_INFO_ADDR +#define WF_PLE_TOP_HIF_PG_INFO_HIF_RSV_CNT_MASK \ + 0x00000FFF /* HIF_RSV_CNT[11..0] */ +#define WF_PLE_TOP_HIF_PG_INFO_HIF_RSV_CNT_SHFT 0 + +/* +* ---PG_HIF_WMTXD_GROUP (0x820C0000 + 0x118)--- +* HIF_WMTXD_MIN_QUOTA[11..0] - (RW) Min. quota of HIF WMCPU TXD group +* Set the quota before release PLE logic +* reset ,and must not be changed after release logic reset. +* RESERVED12[15..12] - (RO) Reserved bits +* HIF_WMTXD_MAX_QUOTA[27..16] - (RW) Max. quota of HIF WMCPU TXD group +* Set up the quota before releasing PLE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_PG_HIF_WMTXD_GROUP_HIF_WMTXD_MAX_QUOTA_ADDR \ + WF_PLE_TOP_PG_HIF_WMTXD_GROUP_ADDR +#define WF_PLE_TOP_PG_HIF_WMTXD_GROUP_HIF_WMTXD_MAX_QUOTA_MASK \ + 0x0FFF0000 /* HIF_WMTXD_MAX_QUOTA[27..16] */ +#define WF_PLE_TOP_PG_HIF_WMTXD_GROUP_HIF_WMTXD_MAX_QUOTA_SHFT 16 +#define WF_PLE_TOP_PG_HIF_WMTXD_GROUP_HIF_WMTXD_MIN_QUOTA_ADDR \ + WF_PLE_TOP_PG_HIF_WMTXD_GROUP_ADDR +#define WF_PLE_TOP_PG_HIF_WMTXD_GROUP_HIF_WMTXD_MIN_QUOTA_MASK \ + 0x00000FFF /* HIF_WMTXD_MIN_QUOTA[11..0] */ +#define WF_PLE_TOP_PG_HIF_WMTXD_GROUP_HIF_WMTXD_MIN_QUOTA_SHFT 0 + +/* +* ---HIF_WMTXD_PG_INFO (0x820C0000 + 0x11C)--- +* HIF_WMTXD_RSV_CNT[11..0] - (RO) Reserved pages of HIF WMCPU TXD +group +* RESERVED12[15..12] - (RO) Reserved bits +* HIF_WMTXD_SRC_CNT[27..16] - (RO) Used pages of HIF WMCPU TXD group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_HIF_WMTXD_PG_INFO_HIF_WMTXD_SRC_CNT_ADDR \ + WF_PLE_TOP_HIF_WMTXD_PG_INFO_ADDR +#define WF_PLE_TOP_HIF_WMTXD_PG_INFO_HIF_WMTXD_SRC_CNT_MASK \ + 0x0FFF0000 /* HIF_WMTXD_SRC_CNT[27..16] */ +#define WF_PLE_TOP_HIF_WMTXD_PG_INFO_HIF_WMTXD_SRC_CNT_SHFT 16 +#define WF_PLE_TOP_HIF_WMTXD_PG_INFO_HIF_WMTXD_RSV_CNT_ADDR \ + WF_PLE_TOP_HIF_WMTXD_PG_INFO_ADDR +#define WF_PLE_TOP_HIF_WMTXD_PG_INFO_HIF_WMTXD_RSV_CNT_MASK \ + 0x00000FFF /* HIF_WMTXD_RSV_CNT[11..0] */ +#define WF_PLE_TOP_HIF_WMTXD_PG_INFO_HIF_WMTXD_RSV_CNT_SHFT 0 + +/* +* ---PG_HIF_TXCMD_GROUP (0x820C0000 + 0x120)--- +* HIF_TXCMD_MIN_QUOTA[11..0] - (RW) Min. quota of HIF TXCMD group +* Set the quota before release PLE logic +* reset ,and must not be changed after release logic reset. +* RESERVED12[15..12] - (RO) Reserved bits +* HIF_TXCMD_MAX_QUOTA[27..16] - (RW) Max. quota of HIF TXCMD group +* Set up the quota before releasing PLE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_PG_HIF_TXCMD_GROUP_HIF_TXCMD_MAX_QUOTA_ADDR \ + WF_PLE_TOP_PG_HIF_TXCMD_GROUP_ADDR +#define WF_PLE_TOP_PG_HIF_TXCMD_GROUP_HIF_TXCMD_MAX_QUOTA_MASK \ + 0x0FFF0000 /* HIF_TXCMD_MAX_QUOTA[27..16] */ +#define WF_PLE_TOP_PG_HIF_TXCMD_GROUP_HIF_TXCMD_MAX_QUOTA_SHFT 16 +#define WF_PLE_TOP_PG_HIF_TXCMD_GROUP_HIF_TXCMD_MIN_QUOTA_ADDR \ + WF_PLE_TOP_PG_HIF_TXCMD_GROUP_ADDR +#define WF_PLE_TOP_PG_HIF_TXCMD_GROUP_HIF_TXCMD_MIN_QUOTA_MASK \ + 0x00000FFF /* HIF_TXCMD_MIN_QUOTA[11..0] */ +#define WF_PLE_TOP_PG_HIF_TXCMD_GROUP_HIF_TXCMD_MIN_QUOTA_SHFT 0 + +/* +* ---HIF_TXCMD_PG_INFO (0x820C0000 + 0x124)--- +* HIF_TXCMD_RSV_CNT[11..0] - (RO) Reserved pages of HIF TXCMD group +* RESERVED12[15..12] - (RO) Reserved bits +* HIF_TXCMD_SRC_CNT[27..16] - (RO) Used pages of HIF TXCMD group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_HIF_TXCMD_PG_INFO_HIF_TXCMD_SRC_CNT_ADDR \ + WF_PLE_TOP_HIF_TXCMD_PG_INFO_ADDR +#define WF_PLE_TOP_HIF_TXCMD_PG_INFO_HIF_TXCMD_SRC_CNT_MASK \ + 0x0FFF0000 /* HIF_TXCMD_SRC_CNT[27..16] */ +#define WF_PLE_TOP_HIF_TXCMD_PG_INFO_HIF_TXCMD_SRC_CNT_SHFT 16 +#define WF_PLE_TOP_HIF_TXCMD_PG_INFO_HIF_TXCMD_RSV_CNT_ADDR \ + WF_PLE_TOP_HIF_TXCMD_PG_INFO_ADDR +#define WF_PLE_TOP_HIF_TXCMD_PG_INFO_HIF_TXCMD_RSV_CNT_MASK \ + 0x00000FFF /* HIF_TXCMD_RSV_CNT[11..0] */ +#define WF_PLE_TOP_HIF_TXCMD_PG_INFO_HIF_TXCMD_RSV_CNT_SHFT 0 + +/* +* ---TWT_TX_CTRL0 (0x820C0000 + 0x130)--- +* en_twt_stop_tx_ctrl_0[0] - (RW) Enable TWT non-active period TX control +function. +* en_twt_stop_tx_ctrl_1[1] - (RW) Enable TWT non-active period TX control +function. +* en_twt_stop_tx_ctrl_2[2] - (RW) Enable TWT non-active period TX control +function. +* en_twt_stop_tx_ctrl_3[3] - (RW) Enable TWT non-active period TX control +function. +* RESERVED4[31..4] - (RO) Reserved bits +*/ + +#define WF_PLE_TOP_TWT_TX_CTRL0_en_twt_stop_tx_ctrl_3_ADDR \ + WF_PLE_TOP_TWT_TX_CTRL0_ADDR +#define WF_PLE_TOP_TWT_TX_CTRL0_en_twt_stop_tx_ctrl_3_MASK \ + 0x00000008 /* en_twt_stop_tx_ctrl_3[3] */ +#define WF_PLE_TOP_TWT_TX_CTRL0_en_twt_stop_tx_ctrl_3_SHFT 3 +#define WF_PLE_TOP_TWT_TX_CTRL0_en_twt_stop_tx_ctrl_2_ADDR \ + WF_PLE_TOP_TWT_TX_CTRL0_ADDR +#define WF_PLE_TOP_TWT_TX_CTRL0_en_twt_stop_tx_ctrl_2_MASK \ + 0x00000004 /* en_twt_stop_tx_ctrl_2[2] */ +#define WF_PLE_TOP_TWT_TX_CTRL0_en_twt_stop_tx_ctrl_2_SHFT 2 +#define WF_PLE_TOP_TWT_TX_CTRL0_en_twt_stop_tx_ctrl_1_ADDR \ + WF_PLE_TOP_TWT_TX_CTRL0_ADDR +#define WF_PLE_TOP_TWT_TX_CTRL0_en_twt_stop_tx_ctrl_1_MASK \ + 0x00000002 /* en_twt_stop_tx_ctrl_1[1] */ +#define WF_PLE_TOP_TWT_TX_CTRL0_en_twt_stop_tx_ctrl_1_SHFT 1 +#define WF_PLE_TOP_TWT_TX_CTRL0_en_twt_stop_tx_ctrl_0_ADDR \ + WF_PLE_TOP_TWT_TX_CTRL0_ADDR +#define WF_PLE_TOP_TWT_TX_CTRL0_en_twt_stop_tx_ctrl_0_MASK \ + 0x00000001 /* en_twt_stop_tx_ctrl_0[0] */ +#define WF_PLE_TOP_TWT_TX_CTRL0_en_twt_stop_tx_ctrl_0_SHFT 0 + +/* +* ---PLE_FUNC_CTRL_0 (0x820C0000 + 0x140)--- +* MACTX_REQ_DEASSERT[0] - (RW) Enable of DeAsser MACTX REQ.(Normal +* operation must be zero.) +* MACTX_ABORT_DEASSERT[1] - (RW) Enable of DeAsser MACTX ABORT.(Normal +* operation must be zero.) +* MPDU_DONE_CNT_IN_NO_TX_REQ[2] - (RW) MPDU done mode for LMAC no TX +request +* MPDU_DONE_CNT_IN_NO_ADD[3] - (RW) MPDU done mode for LMAC no add +* ACK_LMAC_NO_FID_ADD[4] - (RW) MACTX ack mode for LMAC no add any fid +* for TX +* RESERVED5[5] - (RO) Reserved bits +* DIS_STA_RLS_TO_1F[6] - (RW) Release port setting of disable STA +function +* RESERVED7[7] - (RO) Reserved bits +* MACTX_REQ_ASSERT[8] - (RW) Enable of Asser MACTX REQ.(Normal +* operation must be zero.) +* MACTX_ABORT_ASSERT[9] - (RW) Enable of Asser MACTX ABORT.(Normal +* operation must be zero.) +* RESERVED10[21..10] - (RO) Reserved bits +* DIS_AUTORATE_TXP_REQ[22] - (RW) Disable auto rate TXP request +function +* LATER_PKT_PRE_CUT_1US[23] - (RW) Pre cut 1us air time for later +packet. +* TXP_REQ_CNTDOWN_TH[27..24] - (RW) Threshold of air time count down +* for TXP +request +* TXP_REQ_HSPEED_DL_NUM[29..28] - (RW) Packet number of high speed TXP +request +* issue, by pre-cut more micro-second +* TXP_REQ_HSPEED_CUT_US[31..30] - (RW) Number of pre-cut micro-second +* for high +* speed packet +*/ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_TXP_REQ_HSPEED_CUT_US_ADDR \ + WF_PLE_TOP_PLE_FUNC_CTRL_0_ADDR +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_TXP_REQ_HSPEED_CUT_US_MASK \ + 0xC0000000 /* TXP_REQ_HSPEED_CUT_US[31..30] */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_TXP_REQ_HSPEED_CUT_US_SHFT 30 +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_TXP_REQ_HSPEED_DL_NUM_ADDR \ + WF_PLE_TOP_PLE_FUNC_CTRL_0_ADDR +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_TXP_REQ_HSPEED_DL_NUM_MASK \ + 0x30000000 /* TXP_REQ_HSPEED_DL_NUM[29..28] */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_TXP_REQ_HSPEED_DL_NUM_SHFT 28 +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_TXP_REQ_CNTDOWN_TH_ADDR \ + WF_PLE_TOP_PLE_FUNC_CTRL_0_ADDR +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_TXP_REQ_CNTDOWN_TH_MASK \ + 0x0F000000 /* TXP_REQ_CNTDOWN_TH[27..24] */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_TXP_REQ_CNTDOWN_TH_SHFT 24 +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_LATER_PKT_PRE_CUT_1US_ADDR \ + WF_PLE_TOP_PLE_FUNC_CTRL_0_ADDR +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_LATER_PKT_PRE_CUT_1US_MASK \ + 0x00800000 /* LATER_PKT_PRE_CUT_1US[23] */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_LATER_PKT_PRE_CUT_1US_SHFT 23 +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_DIS_AUTORATE_TXP_REQ_ADDR \ + WF_PLE_TOP_PLE_FUNC_CTRL_0_ADDR +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_DIS_AUTORATE_TXP_REQ_MASK \ + 0x00400000 /* DIS_AUTORATE_TXP_REQ[22] */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_DIS_AUTORATE_TXP_REQ_SHFT 22 +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MACTX_ABORT_ASSERT_ADDR \ + WF_PLE_TOP_PLE_FUNC_CTRL_0_ADDR +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MACTX_ABORT_ASSERT_MASK \ + 0x00000200 /* MACTX_ABORT_ASSERT[9] */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MACTX_ABORT_ASSERT_SHFT 9 +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MACTX_REQ_ASSERT_ADDR \ + WF_PLE_TOP_PLE_FUNC_CTRL_0_ADDR +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MACTX_REQ_ASSERT_MASK \ + 0x00000100 /* MACTX_REQ_ASSERT[8] */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MACTX_REQ_ASSERT_SHFT 8 +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_DIS_STA_RLS_TO_1F_ADDR \ + WF_PLE_TOP_PLE_FUNC_CTRL_0_ADDR +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_DIS_STA_RLS_TO_1F_MASK \ + 0x00000040 /* DIS_STA_RLS_TO_1F[6] */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_DIS_STA_RLS_TO_1F_SHFT 6 +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_ACK_LMAC_NO_FID_ADD_ADDR \ + WF_PLE_TOP_PLE_FUNC_CTRL_0_ADDR +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_ACK_LMAC_NO_FID_ADD_MASK \ + 0x00000010 /* ACK_LMAC_NO_FID_ADD[4] */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_ACK_LMAC_NO_FID_ADD_SHFT 4 +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MPDU_DONE_CNT_IN_NO_ADD_ADDR \ + WF_PLE_TOP_PLE_FUNC_CTRL_0_ADDR +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MPDU_DONE_CNT_IN_NO_ADD_MASK \ + 0x00000008 /* MPDU_DONE_CNT_IN_NO_ADD[3] */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MPDU_DONE_CNT_IN_NO_ADD_SHFT 3 +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MPDU_DONE_CNT_IN_NO_TX_REQ_ADDR \ + WF_PLE_TOP_PLE_FUNC_CTRL_0_ADDR +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MPDU_DONE_CNT_IN_NO_TX_REQ_MASK \ + 0x00000004 /* MPDU_DONE_CNT_IN_NO_TX_REQ[2] */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MPDU_DONE_CNT_IN_NO_TX_REQ_SHFT 2 +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MACTX_ABORT_DEASSERT_ADDR \ + WF_PLE_TOP_PLE_FUNC_CTRL_0_ADDR +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MACTX_ABORT_DEASSERT_MASK \ + 0x00000002 /* MACTX_ABORT_DEASSERT[1] */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MACTX_ABORT_DEASSERT_SHFT 1 +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MACTX_REQ_DEASSERT_ADDR \ + WF_PLE_TOP_PLE_FUNC_CTRL_0_ADDR +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MACTX_REQ_DEASSERT_MASK \ + 0x00000001 /* MACTX_REQ_DEASSERT[0] */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_0_MACTX_REQ_DEASSERT_SHFT 0 + +/* +* ---PLE_FUNC_CTRL_1 (0x820C0000 + 0x144)--- +* RESERVED0[21..0] - (RO) Reserved bits +* PREDL_REQ_NORMAL_PRI[22] - (RW) Pre-download TXP request priority +control +* RESERVED23[31..23] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_PLE_FUNC_CTRL_1_PREDL_REQ_NORMAL_PRI_ADDR \ + WF_PLE_TOP_PLE_FUNC_CTRL_1_ADDR +#define WF_PLE_TOP_PLE_FUNC_CTRL_1_PREDL_REQ_NORMAL_PRI_MASK \ + 0x00400000 /* PREDL_REQ_NORMAL_PRI[22] */ +#define WF_PLE_TOP_PLE_FUNC_CTRL_1_PREDL_REQ_NORMAL_PRI_SHFT 22 + +/* +* ---PG_CPU_GROUP (0x820C0000 + 0x150)--- +* CPU_MIN_QUOTA[11..0] - (RW) Min. quota of CPU group +* Set up the quota before releasing PLE logic +* reset; it should not be changed after logic reset is released. +* RESERVED12[15..12] - (RO) Reserved bits +* CPU_MAX_QUOTA[27..16] - (RW) Max. quota of CPU group +* Set up the quota before releasing PLE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_PG_CPU_GROUP_CPU_MAX_QUOTA_ADDR \ + WF_PLE_TOP_PG_CPU_GROUP_ADDR +#define WF_PLE_TOP_PG_CPU_GROUP_CPU_MAX_QUOTA_MASK \ + 0x0FFF0000 /* CPU_MAX_QUOTA[27..16] */ +#define WF_PLE_TOP_PG_CPU_GROUP_CPU_MAX_QUOTA_SHFT 16 +#define WF_PLE_TOP_PG_CPU_GROUP_CPU_MIN_QUOTA_ADDR \ + WF_PLE_TOP_PG_CPU_GROUP_ADDR +#define WF_PLE_TOP_PG_CPU_GROUP_CPU_MIN_QUOTA_MASK \ + 0x00000FFF /* CPU_MIN_QUOTA[11..0] */ +#define WF_PLE_TOP_PG_CPU_GROUP_CPU_MIN_QUOTA_SHFT 0 + +/* +* ---CPU_PG_INFO (0x820C0000 + 0x154)--- +* CPU_RSV_CNT[11..0] - (RO) Reserved pages of CPU group +* RESERVED12[15..12] - (RO) Reserved bits +* CPU_SRC_CNT[27..16] - (RO) Used pages of CPU group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_CPU_PG_INFO_CPU_SRC_CNT_ADDR \ + WF_PLE_TOP_CPU_PG_INFO_ADDR +#define WF_PLE_TOP_CPU_PG_INFO_CPU_SRC_CNT_MASK \ + 0x0FFF0000 /* CPU_SRC_CNT[27..16] */ +#define WF_PLE_TOP_CPU_PG_INFO_CPU_SRC_CNT_SHFT 16 +#define WF_PLE_TOP_CPU_PG_INFO_CPU_RSV_CNT_ADDR \ + WF_PLE_TOP_CPU_PG_INFO_ADDR +#define WF_PLE_TOP_CPU_PG_INFO_CPU_RSV_CNT_MASK \ + 0x00000FFF /* CPU_RSV_CNT[11..0] */ +#define WF_PLE_TOP_CPU_PG_INFO_CPU_RSV_CNT_SHFT 0 + +/* +* ---PLE_LOG_0 (0x820C0000 + 0x170)--- +* PLE_LOG_0[31..0] - (RW) Log message for SW +*/ +#define WF_PLE_TOP_PLE_LOG_0_PLE_LOG_0_ADDR WF_PLE_TOP_PLE_LOG_0_ADDR +#define WF_PLE_TOP_PLE_LOG_0_PLE_LOG_0_MASK \ + 0xFFFFFFFF /* PLE_LOG_0[31..0] */ +#define WF_PLE_TOP_PLE_LOG_0_PLE_LOG_0_SHFT 0 + +/* +* ---PLE_LOG_1 (0x820C0000 + 0x174)--- +* PLE_LOG_1[31..0] - (RW) Log message for SW +*/ +#define WF_PLE_TOP_PLE_LOG_1_PLE_LOG_1_ADDR WF_PLE_TOP_PLE_LOG_1_ADDR +#define WF_PLE_TOP_PLE_LOG_1_PLE_LOG_1_MASK \ + 0xFFFFFFFF /* PLE_LOG_1[31..0] */ +#define WF_PLE_TOP_PLE_LOG_1_PLE_LOG_1_SHFT 0 + +/* +* ---PLE_LOG_2 (0x820C0000 + 0x178)--- +* PLE_LOG_2[31..0] - (RW) Log message for SW +*/ +#define WF_PLE_TOP_PLE_LOG_2_PLE_LOG_2_ADDR WF_PLE_TOP_PLE_LOG_2_ADDR +#define WF_PLE_TOP_PLE_LOG_2_PLE_LOG_2_MASK \ + 0xFFFFFFFF /* PLE_LOG_2[31..0] */ +#define WF_PLE_TOP_PLE_LOG_2_PLE_LOG_2_SHFT 0 + +/* +* ---PLE_LOG_3 (0x820C0000 + 0x17c)--- +* PLE_LOG_3[31..0] - (RW) Log message for SW +*/ +#define WF_PLE_TOP_PLE_LOG_3_PLE_LOG_3_ADDR WF_PLE_TOP_PLE_LOG_3_ADDR +#define WF_PLE_TOP_PLE_LOG_3_PLE_LOG_3_MASK \ + 0xFFFFFFFF /* PLE_LOG_3[31..0] */ +#define WF_PLE_TOP_PLE_LOG_3_PLE_LOG_3_SHFT 0 + +/* +* ---WMMAC_PGCNT_0 (0x820C0000 + 0x180)--- +* WMMAC_00_PGCNT[11..0] - (RO) WMMAC 00 used page count +* RESERVED12[15..12] - (RO) Reserved bits +* WMMAC_01_PGCNT[27..16] - (RO) WMMAC 01 used page count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_WMMAC_PGCNT_0_WMMAC_01_PGCNT_ADDR \ + WF_PLE_TOP_WMMAC_PGCNT_0_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_0_WMMAC_01_PGCNT_MASK \ + 0x0FFF0000 /* WMMAC_01_PGCNT[27..16] */ +#define WF_PLE_TOP_WMMAC_PGCNT_0_WMMAC_01_PGCNT_SHFT 16 +#define WF_PLE_TOP_WMMAC_PGCNT_0_WMMAC_00_PGCNT_ADDR \ + WF_PLE_TOP_WMMAC_PGCNT_0_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_0_WMMAC_00_PGCNT_MASK \ + 0x00000FFF /* WMMAC_00_PGCNT[11..0] */ +#define WF_PLE_TOP_WMMAC_PGCNT_0_WMMAC_00_PGCNT_SHFT 0 + +/* +* ---WMMAC_PGCNT_1 (0x820C0000 + 0x184)--- +* WMMAC_02_PGCNT[11..0] - (RO) WMMAC 02 used page count +* RESERVED12[15..12] - (RO) Reserved bits +* WMMAC_03_PGCNT[27..16] - (RO) WMMAC 03 used page count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_WMMAC_PGCNT_1_WMMAC_03_PGCNT_ADDR \ + WF_PLE_TOP_WMMAC_PGCNT_1_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_1_WMMAC_03_PGCNT_MASK \ + 0x0FFF0000 /* WMMAC_03_PGCNT[27..16] */ +#define WF_PLE_TOP_WMMAC_PGCNT_1_WMMAC_03_PGCNT_SHFT 16 +#define WF_PLE_TOP_WMMAC_PGCNT_1_WMMAC_02_PGCNT_ADDR \ + WF_PLE_TOP_WMMAC_PGCNT_1_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_1_WMMAC_02_PGCNT_MASK \ + 0x00000FFF /* WMMAC_02_PGCNT[11..0] */ +#define WF_PLE_TOP_WMMAC_PGCNT_1_WMMAC_02_PGCNT_SHFT 0 + +/* +* ---WMMAC_PGCNT_2 (0x820C0000 + 0x188)--- +* WMMAC_10_PGCNT[11..0] - (RO) WMMAC 10 used page count +* RESERVED12[15..12] - (RO) Reserved bits +* WMMAC_11_PGCNT[27..16] - (RO) WMMAC 11 used page count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_WMMAC_PGCNT_2_WMMAC_11_PGCNT_ADDR \ + WF_PLE_TOP_WMMAC_PGCNT_2_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_2_WMMAC_11_PGCNT_MASK \ + 0x0FFF0000 /* WMMAC_11_PGCNT[27..16] */ +#define WF_PLE_TOP_WMMAC_PGCNT_2_WMMAC_11_PGCNT_SHFT 16 +#define WF_PLE_TOP_WMMAC_PGCNT_2_WMMAC_10_PGCNT_ADDR \ + WF_PLE_TOP_WMMAC_PGCNT_2_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_2_WMMAC_10_PGCNT_MASK \ + 0x00000FFF /* WMMAC_10_PGCNT[11..0] */ +#define WF_PLE_TOP_WMMAC_PGCNT_2_WMMAC_10_PGCNT_SHFT 0 + +/* +* ---WMMAC_PGCNT_3 (0x820C0000 + 0x18c)--- +* WMMAC_12_PGCNT[11..0] - (RO) WMMAC 12 used page count +* RESERVED12[15..12] - (RO) Reserved bits +* WMMAC_13_PGCNT[27..16] - (RO) WMMAC 13 used page count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_WMMAC_PGCNT_3_WMMAC_13_PGCNT_ADDR \ + WF_PLE_TOP_WMMAC_PGCNT_3_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_3_WMMAC_13_PGCNT_MASK \ + 0x0FFF0000 /* WMMAC_13_PGCNT[27..16] */ +#define WF_PLE_TOP_WMMAC_PGCNT_3_WMMAC_13_PGCNT_SHFT 16 +#define WF_PLE_TOP_WMMAC_PGCNT_3_WMMAC_12_PGCNT_ADDR \ + WF_PLE_TOP_WMMAC_PGCNT_3_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_3_WMMAC_12_PGCNT_MASK \ + 0x00000FFF /* WMMAC_12_PGCNT[11..0] */ +#define WF_PLE_TOP_WMMAC_PGCNT_3_WMMAC_12_PGCNT_SHFT 0 + +/* +* ---WMMAC_PGCNT_4 (0x820C0000 + 0x190)--- +* WMMAC_20_PGCNT[11..0] - (RO) WMMAC 20 used page count +* RESERVED12[15..12] - (RO) Reserved bits +* WMMAC_21_PGCNT[27..16] - (RO) WMMAC 21 used page count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_WMMAC_PGCNT_4_WMMAC_21_PGCNT_ADDR \ + WF_PLE_TOP_WMMAC_PGCNT_4_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_4_WMMAC_21_PGCNT_MASK \ + 0x0FFF0000 /* WMMAC_21_PGCNT[27..16] */ +#define WF_PLE_TOP_WMMAC_PGCNT_4_WMMAC_21_PGCNT_SHFT 16 +#define WF_PLE_TOP_WMMAC_PGCNT_4_WMMAC_20_PGCNT_ADDR \ + WF_PLE_TOP_WMMAC_PGCNT_4_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_4_WMMAC_20_PGCNT_MASK \ + 0x00000FFF /* WMMAC_20_PGCNT[11..0] */ +#define WF_PLE_TOP_WMMAC_PGCNT_4_WMMAC_20_PGCNT_SHFT 0 + +/* +* ---WMMAC_PGCNT_5 (0x820C0000 + 0x194)--- +* WMMAC_22_PGCNT[11..0] - (RO) WMMAC 22 used page count +* RESERVED12[15..12] - (RO) Reserved bits +* WMMAC_23_PGCNT[27..16] - (RO) WMMAC 23 used page count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_WMMAC_PGCNT_5_WMMAC_23_PGCNT_ADDR \ + WF_PLE_TOP_WMMAC_PGCNT_5_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_5_WMMAC_23_PGCNT_MASK \ + 0x0FFF0000 /* WMMAC_23_PGCNT[27..16] */ +#define WF_PLE_TOP_WMMAC_PGCNT_5_WMMAC_23_PGCNT_SHFT 16 +#define WF_PLE_TOP_WMMAC_PGCNT_5_WMMAC_22_PGCNT_ADDR \ + WF_PLE_TOP_WMMAC_PGCNT_5_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_5_WMMAC_22_PGCNT_MASK \ + 0x00000FFF /* WMMAC_22_PGCNT[11..0] */ +#define WF_PLE_TOP_WMMAC_PGCNT_5_WMMAC_22_PGCNT_SHFT 0 + +/* +* ---WMMAC_PGCNT_6 (0x820C0000 + 0x198)--- +* WMMAC_30_PGCNT[11..0] - (RO) WMMAC 30 used page count +* RESERVED12[15..12] - (RO) Reserved bits +* WMMAC_31_PGCNT[27..16] - (RO) WMMAC 31 used page count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_WMMAC_PGCNT_6_WMMAC_31_PGCNT_ADDR \ + WF_PLE_TOP_WMMAC_PGCNT_6_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_6_WMMAC_31_PGCNT_MASK \ + 0x0FFF0000 /* WMMAC_31_PGCNT[27..16] */ +#define WF_PLE_TOP_WMMAC_PGCNT_6_WMMAC_31_PGCNT_SHFT 16 +#define WF_PLE_TOP_WMMAC_PGCNT_6_WMMAC_30_PGCNT_ADDR \ + WF_PLE_TOP_WMMAC_PGCNT_6_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_6_WMMAC_30_PGCNT_MASK \ + 0x00000FFF /* WMMAC_30_PGCNT[11..0] */ +#define WF_PLE_TOP_WMMAC_PGCNT_6_WMMAC_30_PGCNT_SHFT 0 + +/* +* ---WMMAC_PGCNT_7 (0x820C0000 + 0x19c)--- +* WMMAC_32_PGCNT[11..0] - (RO) WMMAC 32 used page count +* RESERVED12[15..12] - (RO) Reserved bits +* WMMAC_33_PGCNT[27..16] - (RO) WMMAC 33 used page count +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_WMMAC_PGCNT_7_WMMAC_33_PGCNT_ADDR \ + WF_PLE_TOP_WMMAC_PGCNT_7_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_7_WMMAC_33_PGCNT_MASK \ + 0x0FFF0000 /* WMMAC_33_PGCNT[27..16] */ +#define WF_PLE_TOP_WMMAC_PGCNT_7_WMMAC_33_PGCNT_SHFT 16 +#define WF_PLE_TOP_WMMAC_PGCNT_7_WMMAC_32_PGCNT_ADDR \ + WF_PLE_TOP_WMMAC_PGCNT_7_ADDR +#define WF_PLE_TOP_WMMAC_PGCNT_7_WMMAC_32_PGCNT_MASK \ + 0x00000FFF /* WMMAC_32_PGCNT[11..0] */ +#define WF_PLE_TOP_WMMAC_PGCNT_7_WMMAC_32_PGCNT_SHFT 0 + +/* +* ---RL_BUF_CTRL_0 (0x820C0000 + 0x1A0)--- +* RELAY_BUF_ADDR[11..0] - (RW) Read address of relay buffer +* RESERVED12[30..12] - (RO) Reserved bits +* EXECUTE[31] - (A0) Executes relay buffer read command +*/ +#define WF_PLE_TOP_RL_BUF_CTRL_0_EXECUTE_ADDR \ + WF_PLE_TOP_RL_BUF_CTRL_0_ADDR +#define WF_PLE_TOP_RL_BUF_CTRL_0_EXECUTE_MASK \ + 0x80000000 /* EXECUTE[31] */ +#define WF_PLE_TOP_RL_BUF_CTRL_0_EXECUTE_SHFT 31 +#define WF_PLE_TOP_RL_BUF_CTRL_0_RELAY_BUF_ADDR_ADDR \ + WF_PLE_TOP_RL_BUF_CTRL_0_ADDR +#define WF_PLE_TOP_RL_BUF_CTRL_0_RELAY_BUF_ADDR_MASK \ + 0x00000FFF /* RELAY_BUF_ADDR[11..0] */ +#define WF_PLE_TOP_RL_BUF_CTRL_0_RELAY_BUF_ADDR_SHFT 0 + +/* +* ---RL_BUF_CTRL_1 (0x820C0000 + 0x1A4)--- +* PAGE_NUM_0[0] - (RO) Page number[0] of packet +* PKT_LEN[11..1] - (RO) Length of the packet with head page +* being the relay buffer address +* Unit: 32 bytes +* PKT_TAIL_PAGE[23..12] - (RO) Tail page of the packet with head page +* being the relay buffer address +* RESV_GRP_ID[24] - (RO) Group ID of reserved page used by FID +* RESERVED25[25] - (RO) Reserved bits +* PAGE_NUM_1[27..26] - (RO) Page number[2:1] of packet +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_RL_BUF_CTRL_1_PAGE_NUM_1_ADDR \ + WF_PLE_TOP_RL_BUF_CTRL_1_ADDR +#define WF_PLE_TOP_RL_BUF_CTRL_1_PAGE_NUM_1_MASK \ + 0x0C000000 /* PAGE_NUM_1[27..26] */ +#define WF_PLE_TOP_RL_BUF_CTRL_1_PAGE_NUM_1_SHFT 26 +#define WF_PLE_TOP_RL_BUF_CTRL_1_RESV_GRP_ID_ADDR \ + WF_PLE_TOP_RL_BUF_CTRL_1_ADDR +#define WF_PLE_TOP_RL_BUF_CTRL_1_RESV_GRP_ID_MASK \ + 0x01000000 /* RESV_GRP_ID[24] */ +#define WF_PLE_TOP_RL_BUF_CTRL_1_RESV_GRP_ID_SHFT 24 +#define WF_PLE_TOP_RL_BUF_CTRL_1_PKT_TAIL_PAGE_ADDR \ + WF_PLE_TOP_RL_BUF_CTRL_1_ADDR +#define WF_PLE_TOP_RL_BUF_CTRL_1_PKT_TAIL_PAGE_MASK \ + 0x00FFF000 /* PKT_TAIL_PAGE[23..12] */ +#define WF_PLE_TOP_RL_BUF_CTRL_1_PKT_TAIL_PAGE_SHFT 12 +#define WF_PLE_TOP_RL_BUF_CTRL_1_PKT_LEN_ADDR \ + WF_PLE_TOP_RL_BUF_CTRL_1_ADDR +#define WF_PLE_TOP_RL_BUF_CTRL_1_PKT_LEN_MASK \ + 0x00000FFE /* PKT_LEN[11..1] */ +#define WF_PLE_TOP_RL_BUF_CTRL_1_PKT_LEN_SHFT 1 +#define WF_PLE_TOP_RL_BUF_CTRL_1_PAGE_NUM_0_ADDR \ + WF_PLE_TOP_RL_BUF_CTRL_1_ADDR +#define WF_PLE_TOP_RL_BUF_CTRL_1_PAGE_NUM_0_MASK \ + 0x00000001 /* PAGE_NUM_0[0] */ +#define WF_PLE_TOP_RL_BUF_CTRL_1_PAGE_NUM_0_SHFT 0 + +/* +* ---FL_QUE_CTRL_0 (0x820C0000 + 0x1B0)--- +* Q_BUF_WLANID[9..0] - (RW) Address of queue structure buffer +WLANID. +* Q_BUF_PID[11..10] - (RW) Address of queue structure buffer PID +* FL_BUFFER_ADDR[23..12] - (RW) Frame address of read previous +* frame/next frame +* Q_BUF_QID[30..24] - (RW) Address of queue structure buffer QID +* EXECUTE[31] - (A0) Executes frame link and queue structure +* buffer read command +*/ +#define WF_PLE_TOP_FL_QUE_CTRL_0_EXECUTE_ADDR \ + WF_PLE_TOP_FL_QUE_CTRL_0_ADDR +#define WF_PLE_TOP_FL_QUE_CTRL_0_EXECUTE_MASK \ + 0x80000000 /* EXECUTE[31] */ +#define WF_PLE_TOP_FL_QUE_CTRL_0_EXECUTE_SHFT 31 +#define WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_QID_ADDR \ + WF_PLE_TOP_FL_QUE_CTRL_0_ADDR +#define WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_QID_MASK \ + 0x7F000000 /* Q_BUF_QID[30..24] */ +#define WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_QID_SHFT 24 +#define WF_PLE_TOP_FL_QUE_CTRL_0_FL_BUFFER_ADDR_ADDR \ + WF_PLE_TOP_FL_QUE_CTRL_0_ADDR +#define WF_PLE_TOP_FL_QUE_CTRL_0_FL_BUFFER_ADDR_MASK \ + 0x00FFF000 /* FL_BUFFER_ADDR[23..12] */ +#define WF_PLE_TOP_FL_QUE_CTRL_0_FL_BUFFER_ADDR_SHFT 12 +#define WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_PID_ADDR \ + WF_PLE_TOP_FL_QUE_CTRL_0_ADDR +#define WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_PID_MASK \ + 0x00000C00 /* Q_BUF_PID[11..10] */ +#define WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_PID_SHFT 10 +#define WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_WLANID_ADDR \ + WF_PLE_TOP_FL_QUE_CTRL_0_ADDR +#define WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_WLANID_MASK \ + 0x000003FF /* Q_BUF_WLANID[9..0] */ +#define WF_PLE_TOP_FL_QUE_CTRL_0_Q_BUF_WLANID_SHFT 0 + +/* +* ---FL_QUE_CTRL_1 (0x820C0000 + 0x1B4)--- +* NEXT_FID[11..0] - (RO) Next frame ID of FL_BUFFER_ADDR +* RESERVED12[15..12] - (RO) Reserved bits +* PREV_FID[27..16] - (RO) Previous frame ID of FL_BUFFER_ADDR +* RESERVED28[30..28] - (RO) Reserved bits +* Q_BUF_TGID[31] - (RW) Address of queue structure buffer TGID +*/ +#define WF_PLE_TOP_FL_QUE_CTRL_1_Q_BUF_TGID_ADDR \ + WF_PLE_TOP_FL_QUE_CTRL_1_ADDR +#define WF_PLE_TOP_FL_QUE_CTRL_1_Q_BUF_TGID_MASK \ + 0x80000000 /* Q_BUF_TGID[31] */ +#define WF_PLE_TOP_FL_QUE_CTRL_1_Q_BUF_TGID_SHFT 31 +#define WF_PLE_TOP_FL_QUE_CTRL_1_PREV_FID_ADDR \ + WF_PLE_TOP_FL_QUE_CTRL_1_ADDR +#define WF_PLE_TOP_FL_QUE_CTRL_1_PREV_FID_MASK \ + 0x0FFF0000 /* PREV_FID[27..16] */ +#define WF_PLE_TOP_FL_QUE_CTRL_1_PREV_FID_SHFT 16 +#define WF_PLE_TOP_FL_QUE_CTRL_1_NEXT_FID_ADDR \ + WF_PLE_TOP_FL_QUE_CTRL_1_ADDR +#define WF_PLE_TOP_FL_QUE_CTRL_1_NEXT_FID_MASK \ + 0x00000FFF /* NEXT_FID[11..0] */ +#define WF_PLE_TOP_FL_QUE_CTRL_1_NEXT_FID_SHFT 0 + +/* +* ---FL_QUE_CTRL_2 (0x820C0000 + 0x1B8)--- +* QUEUE_HEAD_FID[11..0] - (RO) Head frame ID of the quest queue +setting +* in 0x01b0[15:0] +* RESERVED12[15..12] - (RO) Reserved bits +* QUEUE_TAIL_FID[27..16] - (RO) Tail frame ID of the quest queue +setting +* in 0x01b0[15:0] +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_TAIL_FID_ADDR \ + WF_PLE_TOP_FL_QUE_CTRL_2_ADDR +#define WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_TAIL_FID_MASK \ + 0x0FFF0000 /* QUEUE_TAIL_FID[27..16] */ +#define WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_TAIL_FID_SHFT 16 +#define WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_HEAD_FID_ADDR \ + WF_PLE_TOP_FL_QUE_CTRL_2_ADDR +#define WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_HEAD_FID_MASK \ + 0x00000FFF /* QUEUE_HEAD_FID[11..0] */ +#define WF_PLE_TOP_FL_QUE_CTRL_2_QUEUE_HEAD_FID_SHFT 0 + +/* +* ---FL_QUE_CTRL_3 (0x820C0000 + 0x1BC)--- +* QUEUE_PKT_NUM[11..0] - (RO) Total packet number of the queue +* setting in 0x1b0[15:0] +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_FL_QUE_CTRL_3_QUEUE_PKT_NUM_ADDR \ + WF_PLE_TOP_FL_QUE_CTRL_3_ADDR +#define WF_PLE_TOP_FL_QUE_CTRL_3_QUEUE_PKT_NUM_MASK \ + 0x00000FFF /* QUEUE_PKT_NUM[11..0] */ +#define WF_PLE_TOP_FL_QUE_CTRL_3_QUEUE_PKT_NUM_SHFT 0 + +/* +* ---PL_QUE_CTRL_0 (0x820C0000 + 0x1C0)--- +* NEXT_PAGE[11..0] - (RO) Next page of PL_BUFFER_ADDR +* RESERVED12[15..12] - (RO) Reserved bits +* PL_BUFFER_ADDR[27..16] - (RW) Page address of read next page +* RESERVED28[30..28] - (RO) Reserved bits +* EXECUTE[31] - (A0) Executes page link buffer read command +*/ +#define WF_PLE_TOP_PL_QUE_CTRL_0_EXECUTE_ADDR \ + WF_PLE_TOP_PL_QUE_CTRL_0_ADDR +#define WF_PLE_TOP_PL_QUE_CTRL_0_EXECUTE_MASK \ + 0x80000000 /* EXECUTE[31] */ +#define WF_PLE_TOP_PL_QUE_CTRL_0_EXECUTE_SHFT 31 +#define WF_PLE_TOP_PL_QUE_CTRL_0_PL_BUFFER_ADDR_ADDR \ + WF_PLE_TOP_PL_QUE_CTRL_0_ADDR +#define WF_PLE_TOP_PL_QUE_CTRL_0_PL_BUFFER_ADDR_MASK \ + 0x0FFF0000 /* PL_BUFFER_ADDR[27..16] */ +#define WF_PLE_TOP_PL_QUE_CTRL_0_PL_BUFFER_ADDR_SHFT 16 +#define WF_PLE_TOP_PL_QUE_CTRL_0_NEXT_PAGE_ADDR \ + WF_PLE_TOP_PL_QUE_CTRL_0_ADDR +#define WF_PLE_TOP_PL_QUE_CTRL_0_NEXT_PAGE_MASK \ + 0x00000FFF /* NEXT_PAGE[11..0] */ +#define WF_PLE_TOP_PL_QUE_CTRL_0_NEXT_PAGE_SHFT 0 + +/* +* ---PLE_DELAY_TX_CTRL (0x820C0000 + 0x1d0)--- +* DELAY_TX_PAGE_TH[11..0] - (RW) Delay TX function is used to delay +TXD +* be LMAC used. If the total pages of TXD large than page threshold, +* the delay TX +* would be released. LMAC would use TXD to TX. +* RESERVED12[15..12] - (RO) Reserved bits +* DELAY_TX_TIMEOUT_TH[23..16] - (RW) Delay TX function is used to +* delay TXD +* be LMAC used. IF no more enqueue event in the time out threshold, +* the delay TX +* would be released. LMAC can use TXD to TX. (unit is 32us). +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_PLE_DELAY_TX_CTRL_DELAY_TX_TIMEOUT_TH_ADDR \ + WF_PLE_TOP_PLE_DELAY_TX_CTRL_ADDR +#define WF_PLE_TOP_PLE_DELAY_TX_CTRL_DELAY_TX_TIMEOUT_TH_MASK \ + 0x00FF0000 /* DELAY_TX_TIMEOUT_TH[23..16] */ +#define WF_PLE_TOP_PLE_DELAY_TX_CTRL_DELAY_TX_TIMEOUT_TH_SHFT 16 +#define WF_PLE_TOP_PLE_DELAY_TX_CTRL_DELAY_TX_PAGE_TH_ADDR \ + WF_PLE_TOP_PLE_DELAY_TX_CTRL_ADDR +#define WF_PLE_TOP_PLE_DELAY_TX_CTRL_DELAY_TX_PAGE_TH_MASK \ + 0x00000FFF /* DELAY_TX_PAGE_TH[11..0] */ +#define WF_PLE_TOP_PLE_DELAY_TX_CTRL_DELAY_TX_PAGE_TH_SHFT 0 + +/* +* ---PLE_STATION_REDIR_CTRL (0x820C0000 + 0x1d4)--- +* STA_REDIR_QID[4..0] - (RW) Destitaion queue for Redirection +function. +* RESERVED5[5] - (RO) Reserved bits +* STA_REDIR_PID[7..6] - (RW) Destitaion port for Redirection +function. +* STA_REDIR_PASUE_TXD[8] - (RW) Pause TXD download for avoid race +* condition, when station redirection function turn off. +* RESERVED9[31..9] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_PLE_STATION_REDIR_CTRL_STA_REDIR_PASUE_TXD_ADDR \ + WF_PLE_TOP_PLE_STATION_REDIR_CTRL_ADDR +#define WF_PLE_TOP_PLE_STATION_REDIR_CTRL_STA_REDIR_PASUE_TXD_MASK \ + 0x00000100 /* STA_REDIR_PASUE_TXD[8] */ +#define WF_PLE_TOP_PLE_STATION_REDIR_CTRL_STA_REDIR_PASUE_TXD_SHFT 8 +#define WF_PLE_TOP_PLE_STATION_REDIR_CTRL_STA_REDIR_PID_ADDR \ + WF_PLE_TOP_PLE_STATION_REDIR_CTRL_ADDR +#define WF_PLE_TOP_PLE_STATION_REDIR_CTRL_STA_REDIR_PID_MASK \ + 0x000000C0 /* STA_REDIR_PID[7..6] */ +#define WF_PLE_TOP_PLE_STATION_REDIR_CTRL_STA_REDIR_PID_SHFT 6 +#define WF_PLE_TOP_PLE_STATION_REDIR_CTRL_STA_REDIR_QID_ADDR \ + WF_PLE_TOP_PLE_STATION_REDIR_CTRL_ADDR +#define WF_PLE_TOP_PLE_STATION_REDIR_CTRL_STA_REDIR_QID_MASK \ + 0x0000001F /* STA_REDIR_QID[4..0] */ +#define WF_PLE_TOP_PLE_STATION_REDIR_CTRL_STA_REDIR_QID_SHFT 0 + +/* +* ---MACTX_LENGTH_LIMIT (0x820C0000 + 0x1ec)--- +* MACTX_LENGTH_LIMIT_BAND0[15..0] - (RW) MACTX download length limit +* of band0 +* MACTX_LENGTH_LIMIT_BAND1[31..16] - (RW) MACTX download length limit +* of band1 +*/ +#define WF_PLE_TOP_MACTX_LENGTH_LIMIT_MACTX_LENGTH_LIMIT_BAND1_ADDR \ + WF_PLE_TOP_MACTX_LENGTH_LIMIT_ADDR +#define WF_PLE_TOP_MACTX_LENGTH_LIMIT_MACTX_LENGTH_LIMIT_BAND1_MASK \ + 0xFFFF0000 /* MACTX_LENGTH_LIMIT_BAND1[31..16] */ +#define WF_PLE_TOP_MACTX_LENGTH_LIMIT_MACTX_LENGTH_LIMIT_BAND1_SHFT 16 +#define WF_PLE_TOP_MACTX_LENGTH_LIMIT_MACTX_LENGTH_LIMIT_BAND0_ADDR \ + WF_PLE_TOP_MACTX_LENGTH_LIMIT_ADDR +#define WF_PLE_TOP_MACTX_LENGTH_LIMIT_MACTX_LENGTH_LIMIT_BAND0_MASK \ + 0x0000FFFF /* MACTX_LENGTH_LIMIT_BAND0[15..0] */ +#define WF_PLE_TOP_MACTX_LENGTH_LIMIT_MACTX_LENGTH_LIMIT_BAND0_SHFT 0 + +/* +* ---HIF_ENQ_PKT_NUM (0x820C0000 + 0x1f0)--- +* HIF_ENQ_CPU_PKT_NUM[15..0] - (RO) Packet number of HIF enqueue to +CPU, +* just keep in 16bits. +* HIF_ENQ_LMAC_PKT_NUM[31..16] - (RO) Packet number of HIF enqueue to +LMAC, +* just keep in 16 bits +*/ +#define WF_PLE_TOP_HIF_ENQ_PKT_NUM_HIF_ENQ_LMAC_PKT_NUM_ADDR \ + WF_PLE_TOP_HIF_ENQ_PKT_NUM_ADDR +#define WF_PLE_TOP_HIF_ENQ_PKT_NUM_HIF_ENQ_LMAC_PKT_NUM_MASK \ + 0xFFFF0000 /* HIF_ENQ_LMAC_PKT_NUM[31..16] */ +#define WF_PLE_TOP_HIF_ENQ_PKT_NUM_HIF_ENQ_LMAC_PKT_NUM_SHFT 16 +#define WF_PLE_TOP_HIF_ENQ_PKT_NUM_HIF_ENQ_CPU_PKT_NUM_ADDR \ + WF_PLE_TOP_HIF_ENQ_PKT_NUM_ADDR +#define WF_PLE_TOP_HIF_ENQ_PKT_NUM_HIF_ENQ_CPU_PKT_NUM_MASK \ + 0x0000FFFF /* HIF_ENQ_CPU_PKT_NUM[15..0] */ +#define WF_PLE_TOP_HIF_ENQ_PKT_NUM_HIF_ENQ_CPU_PKT_NUM_SHFT 0 + +/* +* ---CPU_ENQ_PKT_NUM (0x820C0000 + 0x1f4)--- +* CPU_ENQ_LMAC_PKT_NUM[15..0] - (RO) Packet number of CPU enqueue to +LMAC, +* just keep in 16 bits. +* RESV[31..16] - (RO) Reserved +*/ +#define WF_PLE_TOP_CPU_ENQ_PKT_NUM_RESV_ADDR \ + WF_PLE_TOP_CPU_ENQ_PKT_NUM_ADDR +#define WF_PLE_TOP_CPU_ENQ_PKT_NUM_RESV_MASK \ + 0xFFFF0000 /* RESV[31..16] */ +#define WF_PLE_TOP_CPU_ENQ_PKT_NUM_RESV_SHFT 16 +#define WF_PLE_TOP_CPU_ENQ_PKT_NUM_CPU_ENQ_LMAC_PKT_NUM_ADDR \ + WF_PLE_TOP_CPU_ENQ_PKT_NUM_ADDR +#define WF_PLE_TOP_CPU_ENQ_PKT_NUM_CPU_ENQ_LMAC_PKT_NUM_MASK \ + 0x0000FFFF /* CPU_ENQ_LMAC_PKT_NUM[15..0] */ +#define WF_PLE_TOP_CPU_ENQ_PKT_NUM_CPU_ENQ_LMAC_PKT_NUM_SHFT 0 + +/* +* ---RLS_MSDU_PKT_NUM (0x820C0000 + 0x1f8)--- +* RSL_RPT_TXD_NUM[15..0] - (RO) TXD number of host report function +* RSL_MSDUID_NUM[31..16] - (RO) Release MSDU_ID number of host report +function +*/ +#define WF_PLE_TOP_RLS_MSDU_PKT_NUM_RSL_MSDUID_NUM_ADDR \ + WF_PLE_TOP_RLS_MSDU_PKT_NUM_ADDR +#define WF_PLE_TOP_RLS_MSDU_PKT_NUM_RSL_MSDUID_NUM_MASK \ + 0xFFFF0000 /* RSL_MSDUID_NUM[31..16] */ +#define WF_PLE_TOP_RLS_MSDU_PKT_NUM_RSL_MSDUID_NUM_SHFT 16 +#define WF_PLE_TOP_RLS_MSDU_PKT_NUM_RSL_RPT_TXD_NUM_ADDR \ + WF_PLE_TOP_RLS_MSDU_PKT_NUM_ADDR +#define WF_PLE_TOP_RLS_MSDU_PKT_NUM_RSL_RPT_TXD_NUM_MASK \ + 0x0000FFFF /* RSL_RPT_TXD_NUM[15..0] */ +#define WF_PLE_TOP_RLS_MSDU_PKT_NUM_RSL_RPT_TXD_NUM_SHFT 0 + +/* +* ---HOST_REPORT_NUM (0x820C0000 + 0x1fc)--- +* RSL_TXD_NUM[15..0] - (RO) All TXD number of release function, +* include the no host report(not CT) TXD packets. +* HOST_REPORT_NUM[31..16] - (RO) Host report number that be the PSE +* packets carry release MSDU_ID information +*/ +#define WF_PLE_TOP_HOST_REPORT_NUM_HOST_REPORT_NUM_ADDR \ + WF_PLE_TOP_HOST_REPORT_NUM_ADDR +#define WF_PLE_TOP_HOST_REPORT_NUM_HOST_REPORT_NUM_MASK \ + 0xFFFF0000 /* HOST_REPORT_NUM[31..16] */ +#define WF_PLE_TOP_HOST_REPORT_NUM_HOST_REPORT_NUM_SHFT 16 +#define WF_PLE_TOP_HOST_REPORT_NUM_RSL_TXD_NUM_ADDR \ + WF_PLE_TOP_HOST_REPORT_NUM_ADDR +#define WF_PLE_TOP_HOST_REPORT_NUM_RSL_TXD_NUM_MASK \ + 0x0000FFFF /* RSL_TXD_NUM[15..0] */ +#define WF_PLE_TOP_HOST_REPORT_NUM_RSL_TXD_NUM_SHFT 0 + +/* +* ---TXD_QUEUE_EMPTY (0x820C0000 + 0x220)--- +* AC00_EMPTY[0] - (RO) WMM0 AC0 queue empty status +* AC01_EMPTY[1] - (RO) WMM0 AC1 queue empty status +* AC02_EMPTY[2] - (RO) WMM0 AC2 queue empty status +* AC03_EMPTY[3] - (RO) WMM0 AC3 queue empty status +* AC10_EMPTY[4] - (RO) WMM1 AC0 queue empty status +* AC11_EMPTY[5] - (RO) WMM1 AC1 queue empty status +* AC12_EMPTY[6] - (RO) WMM1 AC2 queue empty status +* AC13_EMPTY[7] - (RO) WMM1 AC3 queue empty status +* AC20_EMPTY[8] - (RO) WMM2 AC0 queue empty status +* AC21_EMPTY[9] - (RO) WMM2 AC1 queue empty status +* AC22_EMPTY[10] - (RO) WMM2 AC2 queue empty status +* AC23_EMPTY[11] - (RO) WMM2 AC3 queue empty status +* AC30_EMPTY[12] - (RO) WMM3 AC0 queue empty status +* AC31_EMPTY[13] - (RO) WMM3 AC1 queue empty status +* AC32_EMPTY[14] - (RO) WMM3 AC2 queue empty status +* AC33_EMPTY[15] - (RO) WMM3 AC3 queue empty status +* ALTX_0_EMPTY[16] - (RO) ALTX queue 0 empty status +* BMC_0_EMPTY[17] - (RO) BMC queue 0 empty status +* BCN_0_EMPTY[18] - (RO) BCN queue 0 empty status +* PSMP_0_EMPTY[19] - (RO) PSMP queue 0 empty status +* ALTX_1_EMPTY[20] - (RO) ALTX queue 1 empty status +* BMC_1_EMPTY[21] - (RO) BMC queue 1 empty status +* BCN_1_EMPTY[22] - (RO) BCN queue 1 empty status +* PSMP_1_EMPTY[23] - (RO) PSMP queue 1 empty status +* NAF_EMPTY[24] - (RO) NAF queue empty status +* NBCN_EMPTY[25] - (RO) NBCN queue empty status +* RESERVED26[31..26] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_NBCN_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_NBCN_EMPTY_MASK \ + 0x02000000 /* NBCN_EMPTY[25] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_NBCN_EMPTY_SHFT 25 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_NAF_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_NAF_EMPTY_MASK \ + 0x01000000 /* NAF_EMPTY[24] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_NAF_EMPTY_SHFT 24 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_PSMP_1_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_PSMP_1_EMPTY_MASK \ + 0x00800000 /* PSMP_1_EMPTY[23] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_PSMP_1_EMPTY_SHFT 23 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_BCN_1_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_BCN_1_EMPTY_MASK \ + 0x00400000 /* BCN_1_EMPTY[22] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_BCN_1_EMPTY_SHFT 22 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_BMC_1_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_BMC_1_EMPTY_MASK \ + 0x00200000 /* BMC_1_EMPTY[21] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_BMC_1_EMPTY_SHFT 21 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_ALTX_1_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_ALTX_1_EMPTY_MASK \ + 0x00100000 /* ALTX_1_EMPTY[20] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_ALTX_1_EMPTY_SHFT 20 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_PSMP_0_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_PSMP_0_EMPTY_MASK \ + 0x00080000 /* PSMP_0_EMPTY[19] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_PSMP_0_EMPTY_SHFT 19 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_BCN_0_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_BCN_0_EMPTY_MASK \ + 0x00040000 /* BCN_0_EMPTY[18] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_BCN_0_EMPTY_SHFT 18 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_BMC_0_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_BMC_0_EMPTY_MASK \ + 0x00020000 /* BMC_0_EMPTY[17] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_BMC_0_EMPTY_SHFT 17 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_ALTX_0_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_ALTX_0_EMPTY_MASK \ + 0x00010000 /* ALTX_0_EMPTY[16] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_ALTX_0_EMPTY_SHFT 16 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC33_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC33_EMPTY_MASK \ + 0x00008000 /* AC33_EMPTY[15] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC33_EMPTY_SHFT 15 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC32_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC32_EMPTY_MASK \ + 0x00004000 /* AC32_EMPTY[14] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC32_EMPTY_SHFT 14 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC31_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC31_EMPTY_MASK \ + 0x00002000 /* AC31_EMPTY[13] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC31_EMPTY_SHFT 13 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC30_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC30_EMPTY_MASK \ + 0x00001000 /* AC30_EMPTY[12] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC30_EMPTY_SHFT 12 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC23_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC23_EMPTY_MASK \ + 0x00000800 /* AC23_EMPTY[11] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC23_EMPTY_SHFT 11 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC22_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC22_EMPTY_MASK \ + 0x00000400 /* AC22_EMPTY[10] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC22_EMPTY_SHFT 10 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC21_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC21_EMPTY_MASK \ + 0x00000200 /* AC21_EMPTY[9] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC21_EMPTY_SHFT 9 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC20_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC20_EMPTY_MASK \ + 0x00000100 /* AC20_EMPTY[8] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC20_EMPTY_SHFT 8 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC13_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC13_EMPTY_MASK \ + 0x00000080 /* AC13_EMPTY[7] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC13_EMPTY_SHFT 7 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC12_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC12_EMPTY_MASK \ + 0x00000040 /* AC12_EMPTY[6] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC12_EMPTY_SHFT 6 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC11_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC11_EMPTY_MASK \ + 0x00000020 /* AC11_EMPTY[5] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC11_EMPTY_SHFT 5 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC10_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC10_EMPTY_MASK \ + 0x00000010 /* AC10_EMPTY[4] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC10_EMPTY_SHFT 4 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC03_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC03_EMPTY_MASK \ + 0x00000008 /* AC03_EMPTY[3] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC03_EMPTY_SHFT 3 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC02_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC02_EMPTY_MASK \ + 0x00000004 /* AC02_EMPTY[2] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC02_EMPTY_SHFT 2 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC01_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC01_EMPTY_MASK \ + 0x00000002 /* AC01_EMPTY[1] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC01_EMPTY_SHFT 1 +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC00_EMPTY_ADDR \ + WF_PLE_TOP_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC00_EMPTY_MASK \ + 0x00000001 /* AC00_EMPTY[0] */ +#define WF_PLE_TOP_TXD_QUEUE_EMPTY_AC00_EMPTY_SHFT 0 + +/* +* ---TXS_BUF_PAUSE (0x820C0000 + 0x224)--- +* EN_PAUSE_AC00_QUEUE[0] - (RW) Pause control of WMM0 AC0 queue. +* EN_PAUSE_AC01_QUEUE[1] - (RW) Pause control of WMM0 AC1 queue. +* EN_PAUSE_AC02_QUEUE[2] - (RW) Pause control of WMM0 AC2 queue. +* EN_PAUSE_AC03_QUEUE[3] - (RW) Pause control of WMM0 AC3 queue. +* EN_PAUSE_AC10_QUEUE[4] - (RW) Pause control of WMM1 AC0 queue. +* EN_PAUSE_AC11_QUEUE[5] - (RW) Pause control of WMM1 AC1 queue. +* EN_PAUSE_AC12_QUEUE[6] - (RW) Pause control of WMM1 AC2 queue. +* EN_PAUSE_AC13_QUEUE[7] - (RW) Pause control of WMM1 AC3 queue. +* EN_PAUSE_AC20_QUEUE[8] - (RW) Pause control of WMM2 AC0 queue. +* EN_PAUSE_AC21_QUEUE[9] - (RW) Pause control of WMM2 AC1 queue. +* EN_PAUSE_AC22_QUEUE[10] - (RW) Pause control of WMM2 AC2 queue. +* EN_PAUSE_AC23_QUEUE[11] - (RW) Pause control of WMM2 AC3 queue. +* EN_PAUSE_AC30_QUEUE[12] - (RW) Pause control of WMM3 AC0 queue. +* EN_PAUSE_AC31_QUEUE[13] - (RW) Pause control of WMM3 AC1 queue. +* EN_PAUSE_AC32_QUEUE[14] - (RW) Pause control of WMM3 AC2 queue. +* EN_PAUSE_AC33_QUEUE[15] - (RW) Pause control of WMM3 AC3 queue. +* EN_PAUSE_ALTX_0_QUEUE[16] - (RW) Pause control of ALTX queue 0. +* EN_PAUSE_BMC_0_QUEUE[17] - (RW) Pause control of BMC queue 0. +* EN_PAUSE_BCN_0_QUEUE[18] - (RW) Pause control of BCN queue 0. +* EN_PAUSE_PSMP_0_QUEUE[19] - (RW) Pause control of PSMP queue 0. +* EN_PAUSE_ALTX_1_QUEUE[20] - (RW) Pause control of ALTX queue 1. +* EN_PAUSE_BMC_1_QUEUE[21] - (RW) Pause control of BMC queue 1. +* EN_PAUSE_BCN_1_QUEUE[22] - (RW) Pause control of BCN queue 1. +* EN_PAUSE_PSMP_1_QUEUE[23] - (RW) Pause control of PSMP queue 1. +* EN_PAUSE_NAF_QUEUE[24] - (RW) Pause control of NAF queue. +* EN_PAUSE_NBCN_QUEUE[25] - (RW) Pause control of NBCN queue. +* RESERVED26[30..26] - (RO) Reserved bits +* PSE_TXS_BUF_VALID[31] - (RO) PSE TXS buffer status. +*/ +#define WF_PLE_TOP_TXS_BUF_PAUSE_PSE_TXS_BUF_VALID_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_PSE_TXS_BUF_VALID_MASK \ + 0x80000000 /* PSE_TXS_BUF_VALID[31] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_PSE_TXS_BUF_VALID_SHFT 31 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_NBCN_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_NBCN_QUEUE_MASK \ + 0x02000000 /* EN_PAUSE_NBCN_QUEUE[25] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_NBCN_QUEUE_SHFT 25 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_NAF_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_NAF_QUEUE_MASK \ + 0x01000000 /* EN_PAUSE_NAF_QUEUE[24] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_NAF_QUEUE_SHFT 24 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_PSMP_1_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_PSMP_1_QUEUE_MASK \ + 0x00800000 /* EN_PAUSE_PSMP_1_QUEUE[23] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_PSMP_1_QUEUE_SHFT 23 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_BCN_1_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_BCN_1_QUEUE_MASK \ + 0x00400000 /* EN_PAUSE_BCN_1_QUEUE[22] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_BCN_1_QUEUE_SHFT 22 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_BMC_1_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_BMC_1_QUEUE_MASK \ + 0x00200000 /* EN_PAUSE_BMC_1_QUEUE[21] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_BMC_1_QUEUE_SHFT 21 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_ALTX_1_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_ALTX_1_QUEUE_MASK \ + 0x00100000 /* EN_PAUSE_ALTX_1_QUEUE[20] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_ALTX_1_QUEUE_SHFT 20 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_PSMP_0_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_PSMP_0_QUEUE_MASK \ + 0x00080000 /* EN_PAUSE_PSMP_0_QUEUE[19] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_PSMP_0_QUEUE_SHFT 19 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_BCN_0_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_BCN_0_QUEUE_MASK \ + 0x00040000 /* EN_PAUSE_BCN_0_QUEUE[18] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_BCN_0_QUEUE_SHFT 18 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_BMC_0_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_BMC_0_QUEUE_MASK \ + 0x00020000 /* EN_PAUSE_BMC_0_QUEUE[17] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_BMC_0_QUEUE_SHFT 17 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_ALTX_0_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_ALTX_0_QUEUE_MASK \ + 0x00010000 /* EN_PAUSE_ALTX_0_QUEUE[16] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_ALTX_0_QUEUE_SHFT 16 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC33_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC33_QUEUE_MASK \ + 0x00008000 /* EN_PAUSE_AC33_QUEUE[15] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC33_QUEUE_SHFT 15 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC32_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC32_QUEUE_MASK \ + 0x00004000 /* EN_PAUSE_AC32_QUEUE[14] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC32_QUEUE_SHFT 14 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC31_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC31_QUEUE_MASK \ + 0x00002000 /* EN_PAUSE_AC31_QUEUE[13] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC31_QUEUE_SHFT 13 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC30_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC30_QUEUE_MASK \ + 0x00001000 /* EN_PAUSE_AC30_QUEUE[12] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC30_QUEUE_SHFT 12 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC23_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC23_QUEUE_MASK \ + 0x00000800 /* EN_PAUSE_AC23_QUEUE[11] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC23_QUEUE_SHFT 11 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC22_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC22_QUEUE_MASK \ + 0x00000400 /* EN_PAUSE_AC22_QUEUE[10] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC22_QUEUE_SHFT 10 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC21_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC21_QUEUE_MASK \ + 0x00000200 /* EN_PAUSE_AC21_QUEUE[9] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC21_QUEUE_SHFT 9 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC20_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC20_QUEUE_MASK \ + 0x00000100 /* EN_PAUSE_AC20_QUEUE[8] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC20_QUEUE_SHFT 8 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC13_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC13_QUEUE_MASK \ + 0x00000080 /* EN_PAUSE_AC13_QUEUE[7] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC13_QUEUE_SHFT 7 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC12_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC12_QUEUE_MASK \ + 0x00000040 /* EN_PAUSE_AC12_QUEUE[6] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC12_QUEUE_SHFT 6 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC11_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC11_QUEUE_MASK \ + 0x00000020 /* EN_PAUSE_AC11_QUEUE[5] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC11_QUEUE_SHFT 5 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC10_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC10_QUEUE_MASK \ + 0x00000010 /* EN_PAUSE_AC10_QUEUE[4] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC10_QUEUE_SHFT 4 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC03_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC03_QUEUE_MASK \ + 0x00000008 /* EN_PAUSE_AC03_QUEUE[3] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC03_QUEUE_SHFT 3 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC02_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC02_QUEUE_MASK \ + 0x00000004 /* EN_PAUSE_AC02_QUEUE[2] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC02_QUEUE_SHFT 2 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC01_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC01_QUEUE_MASK \ + 0x00000002 /* EN_PAUSE_AC01_QUEUE[1] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC01_QUEUE_SHFT 1 +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC00_QUEUE_ADDR \ + WF_PLE_TOP_TXS_BUF_PAUSE_ADDR +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC00_QUEUE_MASK \ + 0x00000001 /* EN_PAUSE_AC00_QUEUE[0] */ +#define WF_PLE_TOP_TXS_BUF_PAUSE_EN_PAUSE_AC00_QUEUE_SHFT 0 + +/* +* ---NATIVE_TXD_QUEUE_EMPTY (0x820C0000 + 0x228)--- +* AC00_EMPTY[0] - (RO) WMM0 AC0 queue empty status +* AC01_EMPTY[1] - (RO) WMM0 AC1 queue empty status +* AC02_EMPTY[2] - (RO) WMM0 AC2 queue empty status +* AC03_EMPTY[3] - (RO) WMM0 AC3 queue empty status +* AC10_EMPTY[4] - (RO) WMM1 AC0 queue empty status +* AC11_EMPTY[5] - (RO) WMM1 AC1 queue empty status +* AC12_EMPTY[6] - (RO) WMM1 AC2 queue empty status +* AC13_EMPTY[7] - (RO) WMM1 AC3 queue empty status +* AC20_EMPTY[8] - (RO) WMM2 AC0 queue empty status +* AC21_EMPTY[9] - (RO) WMM2 AC1 queue empty status +* AC22_EMPTY[10] - (RO) WMM2 AC2 queue empty status +* AC23_EMPTY[11] - (RO) WMM2 AC3 queue empty status +* AC30_EMPTY[12] - (RO) WMM3 AC0 queue empty status +* AC31_EMPTY[13] - (RO) WMM3 AC1 queue empty status +* AC32_EMPTY[14] - (RO) WMM3 AC2 queue empty status +* AC33_EMPTY[15] - (RO) WMM3 AC3 queue empty status +* ALTX_0_EMPTY[16] - (RO) ALTX queue 0 empty status +* BMC_0_EMPTY[17] - (RO) BMC queue 0 empty status +* BCN_0_EMPTY[18] - (RO) BCN queue 0 empty status +* PSMP_0_EMPTY[19] - (RO) PSMP queue 0 empty status +* ALTX_1_EMPTY[20] - (RO) ALTX queue 1 empty status +* BMC_1_EMPTY[21] - (RO) BMC queue 1 empty status +* BCN_1_EMPTY[22] - (RO) BCN queue 1 empty status +* PSMP_1_EMPTY[23] - (RO) PSMP queue 1 empty status +* NAF_EMPTY[24] - (RO) NAF queue empty status +* NBCN_EMPTY[25] - (RO) NBCN queue empty status +* RESERVED26[31..26] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_NBCN_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_NBCN_EMPTY_MASK \ + 0x02000000 /* NBCN_EMPTY[25] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_NBCN_EMPTY_SHFT 25 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_NAF_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_NAF_EMPTY_MASK \ + 0x01000000 /* NAF_EMPTY[24] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_NAF_EMPTY_SHFT 24 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_PSMP_1_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_PSMP_1_EMPTY_MASK \ + 0x00800000 /* PSMP_1_EMPTY[23] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_PSMP_1_EMPTY_SHFT 23 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_BCN_1_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_BCN_1_EMPTY_MASK \ + 0x00400000 /* BCN_1_EMPTY[22] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_BCN_1_EMPTY_SHFT 22 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_BMC_1_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_BMC_1_EMPTY_MASK \ + 0x00200000 /* BMC_1_EMPTY[21] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_BMC_1_EMPTY_SHFT 21 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ALTX_1_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ALTX_1_EMPTY_MASK \ + 0x00100000 /* ALTX_1_EMPTY[20] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ALTX_1_EMPTY_SHFT 20 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_PSMP_0_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_PSMP_0_EMPTY_MASK \ + 0x00080000 /* PSMP_0_EMPTY[19] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_PSMP_0_EMPTY_SHFT 19 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_BCN_0_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_BCN_0_EMPTY_MASK \ + 0x00040000 /* BCN_0_EMPTY[18] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_BCN_0_EMPTY_SHFT 18 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_BMC_0_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_BMC_0_EMPTY_MASK \ + 0x00020000 /* BMC_0_EMPTY[17] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_BMC_0_EMPTY_SHFT 17 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ALTX_0_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ALTX_0_EMPTY_MASK \ + 0x00010000 /* ALTX_0_EMPTY[16] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ALTX_0_EMPTY_SHFT 16 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC33_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC33_EMPTY_MASK \ + 0x00008000 /* AC33_EMPTY[15] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC33_EMPTY_SHFT 15 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC32_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC32_EMPTY_MASK \ + 0x00004000 /* AC32_EMPTY[14] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC32_EMPTY_SHFT 14 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC31_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC31_EMPTY_MASK \ + 0x00002000 /* AC31_EMPTY[13] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC31_EMPTY_SHFT 13 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC30_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC30_EMPTY_MASK \ + 0x00001000 /* AC30_EMPTY[12] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC30_EMPTY_SHFT 12 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC23_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC23_EMPTY_MASK \ + 0x00000800 /* AC23_EMPTY[11] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC23_EMPTY_SHFT 11 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC22_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC22_EMPTY_MASK \ + 0x00000400 /* AC22_EMPTY[10] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC22_EMPTY_SHFT 10 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC21_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC21_EMPTY_MASK \ + 0x00000200 /* AC21_EMPTY[9] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC21_EMPTY_SHFT 9 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC20_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC20_EMPTY_MASK \ + 0x00000100 /* AC20_EMPTY[8] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC20_EMPTY_SHFT 8 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC13_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC13_EMPTY_MASK \ + 0x00000080 /* AC13_EMPTY[7] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC13_EMPTY_SHFT 7 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC12_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC12_EMPTY_MASK \ + 0x00000040 /* AC12_EMPTY[6] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC12_EMPTY_SHFT 6 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC11_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC11_EMPTY_MASK \ + 0x00000020 /* AC11_EMPTY[5] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC11_EMPTY_SHFT 5 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC10_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC10_EMPTY_MASK \ + 0x00000010 /* AC10_EMPTY[4] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC10_EMPTY_SHFT 4 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC03_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC03_EMPTY_MASK \ + 0x00000008 /* AC03_EMPTY[3] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC03_EMPTY_SHFT 3 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC02_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC02_EMPTY_MASK \ + 0x00000004 /* AC02_EMPTY[2] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC02_EMPTY_SHFT 2 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC01_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC01_EMPTY_MASK \ + 0x00000002 /* AC01_EMPTY[1] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC01_EMPTY_SHFT 1 +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC00_EMPTY_ADDR \ + WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_ADDR +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC00_EMPTY_MASK \ + 0x00000001 /* AC00_EMPTY[0] */ +#define WF_PLE_TOP_NATIVE_TXD_QUEUE_EMPTY_AC00_EMPTY_SHFT 0 + +/* +* ---UMAC_DBG_CTRL (0x820C0000 + 0x240)--- +* UMAC_DBG_FUNC_SEL[3..0] - (RW) Selects UMAC debug mode +* RESERVED4[7..4] - (RO) Reserved bits +* PLE_DBG_FLAG_A_NIB_EN[11..8] - (RW) Enable control of PLE debug flag +A +nibble +* PLE_DBG_FLAG_B_NIB_EN[15..12] - (RW) Enable control of PLE debug +* flag B +nibble +* PSE_DBG_FLAG_A_NIB_EN[19..16] - (RW) Enable control of PSE debug +* flag A +nibble +* PSE_DBG_FLAG_B_NIB_EN[23..20] - (RW) Enable control of PSE debug +* flag B +nibble +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_UMAC_DBG_CTRL_PSE_DBG_FLAG_B_NIB_EN_ADDR \ + WF_PLE_TOP_UMAC_DBG_CTRL_ADDR +#define WF_PLE_TOP_UMAC_DBG_CTRL_PSE_DBG_FLAG_B_NIB_EN_MASK \ + 0x00F00000 /* PSE_DBG_FLAG_B_NIB_EN[23..20] */ +#define WF_PLE_TOP_UMAC_DBG_CTRL_PSE_DBG_FLAG_B_NIB_EN_SHFT 20 +#define WF_PLE_TOP_UMAC_DBG_CTRL_PSE_DBG_FLAG_A_NIB_EN_ADDR \ + WF_PLE_TOP_UMAC_DBG_CTRL_ADDR +#define WF_PLE_TOP_UMAC_DBG_CTRL_PSE_DBG_FLAG_A_NIB_EN_MASK \ + 0x000F0000 /* PSE_DBG_FLAG_A_NIB_EN[19..16] */ +#define WF_PLE_TOP_UMAC_DBG_CTRL_PSE_DBG_FLAG_A_NIB_EN_SHFT 16 +#define WF_PLE_TOP_UMAC_DBG_CTRL_PLE_DBG_FLAG_B_NIB_EN_ADDR \ + WF_PLE_TOP_UMAC_DBG_CTRL_ADDR +#define WF_PLE_TOP_UMAC_DBG_CTRL_PLE_DBG_FLAG_B_NIB_EN_MASK \ + 0x0000F000 /* PLE_DBG_FLAG_B_NIB_EN[15..12] */ +#define WF_PLE_TOP_UMAC_DBG_CTRL_PLE_DBG_FLAG_B_NIB_EN_SHFT 12 +#define WF_PLE_TOP_UMAC_DBG_CTRL_PLE_DBG_FLAG_A_NIB_EN_ADDR \ + WF_PLE_TOP_UMAC_DBG_CTRL_ADDR +#define WF_PLE_TOP_UMAC_DBG_CTRL_PLE_DBG_FLAG_A_NIB_EN_MASK \ + 0x00000F00 /* PLE_DBG_FLAG_A_NIB_EN[11..8] */ +#define WF_PLE_TOP_UMAC_DBG_CTRL_PLE_DBG_FLAG_A_NIB_EN_SHFT 8 +#define WF_PLE_TOP_UMAC_DBG_CTRL_UMAC_DBG_FUNC_SEL_ADDR \ + WF_PLE_TOP_UMAC_DBG_CTRL_ADDR +#define WF_PLE_TOP_UMAC_DBG_CTRL_UMAC_DBG_FUNC_SEL_MASK \ + 0x0000000F /* UMAC_DBG_FUNC_SEL[3..0] */ +#define WF_PLE_TOP_UMAC_DBG_CTRL_UMAC_DBG_FUNC_SEL_SHFT 0 + +/* +* ---PLE_DBG_A_BYTE_SEL (0x820C0000 + 0x244)--- +* PLE_DBG_FLAG_A_BYTE0_SEL[7..0] - (RW) Debug flag selection of PLE +* debug A +* byte 0 +* PLE_DBG_FLAG_A_BYTE1_SEL[15..8] - (RW) Debug flag selection of PLE +* debug A +* byte 1 +* PLE_DBG_FLAG_A_BYTE2_SEL[23..16] - (RW) Debug flag selection of PLE +* debug A +* byte 2 +* PLE_DBG_FLAG_A_BYTE3_SEL[31..24] - (RW) Debug flag selection of PLE +* debug A +* byte 3 +*/ +#define WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_PLE_DBG_FLAG_A_BYTE3_SEL_ADDR \ + WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_ADDR +#define WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_PLE_DBG_FLAG_A_BYTE3_SEL_MASK \ + 0xFF000000 /* PLE_DBG_FLAG_A_BYTE3_SEL[31..24] */ +#define WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_PLE_DBG_FLAG_A_BYTE3_SEL_SHFT 24 +#define WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_PLE_DBG_FLAG_A_BYTE2_SEL_ADDR \ + WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_ADDR +#define WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_PLE_DBG_FLAG_A_BYTE2_SEL_MASK \ + 0x00FF0000 /* PLE_DBG_FLAG_A_BYTE2_SEL[23..16] */ +#define WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_PLE_DBG_FLAG_A_BYTE2_SEL_SHFT 16 +#define WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_PLE_DBG_FLAG_A_BYTE1_SEL_ADDR \ + WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_ADDR +#define WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_PLE_DBG_FLAG_A_BYTE1_SEL_MASK \ + 0x0000FF00 /* PLE_DBG_FLAG_A_BYTE1_SEL[15..8] */ +#define WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_PLE_DBG_FLAG_A_BYTE1_SEL_SHFT 8 +#define WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_PLE_DBG_FLAG_A_BYTE0_SEL_ADDR \ + WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_ADDR +#define WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_PLE_DBG_FLAG_A_BYTE0_SEL_MASK \ + 0x000000FF /* PLE_DBG_FLAG_A_BYTE0_SEL[7..0] */ +#define WF_PLE_TOP_PLE_DBG_A_BYTE_SEL_PLE_DBG_FLAG_A_BYTE0_SEL_SHFT 0 + +/* +* ---PLE_DBG_B_BYTE_SEL (0x820C0000 + 0x248)--- +* PLE_DBG_FLAG_B_BYTE0_SEL[7..0] - (RW) Debug flag selection of PLE +* debug B +* byte 0 +* PLE_DBG_FLAG_B_BYTE1_SEL[15..8] - (RW) Debug flag selection of PLE +* debug B +* byte 1 +* PLE_DBG_FLAG_B_BYTE2_SEL[23..16] - (RW) Debug flag selection of PLE +* debug B +* byte 2 +* PLE_DBG_FLAG_B_BYTE3_SEL[31..24] - (RW) Debug flag selection of PLE +* debug B +* byte 3 +*/ +#define WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_PLE_DBG_FLAG_B_BYTE3_SEL_ADDR \ + WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_ADDR +#define WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_PLE_DBG_FLAG_B_BYTE3_SEL_MASK \ + 0xFF000000 /* PLE_DBG_FLAG_B_BYTE3_SEL[31..24] */ +#define WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_PLE_DBG_FLAG_B_BYTE3_SEL_SHFT 24 +#define WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_PLE_DBG_FLAG_B_BYTE2_SEL_ADDR \ + WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_ADDR +#define WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_PLE_DBG_FLAG_B_BYTE2_SEL_MASK \ + 0x00FF0000 /* PLE_DBG_FLAG_B_BYTE2_SEL[23..16] */ +#define WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_PLE_DBG_FLAG_B_BYTE2_SEL_SHFT 16 +#define WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_PLE_DBG_FLAG_B_BYTE1_SEL_ADDR \ + WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_ADDR +#define WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_PLE_DBG_FLAG_B_BYTE1_SEL_MASK \ + 0x0000FF00 /* PLE_DBG_FLAG_B_BYTE1_SEL[15..8] */ +#define WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_PLE_DBG_FLAG_B_BYTE1_SEL_SHFT 8 +#define WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_PLE_DBG_FLAG_B_BYTE0_SEL_ADDR \ + WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_ADDR +#define WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_PLE_DBG_FLAG_B_BYTE0_SEL_MASK \ + 0x000000FF /* PLE_DBG_FLAG_B_BYTE0_SEL[7..0] */ +#define WF_PLE_TOP_PLE_DBG_B_BYTE_SEL_PLE_DBG_FLAG_B_BYTE0_SEL_SHFT 0 + +/* +* ---FSM_IDLE_WD_CTRL (0x820C0000 + 0x24C)--- +* FL_IDLE_WD_TO_TH[7..0] - (RW) Watchdog timeout threshold for frame +* link FSM not returning to IDLE +* PL_IDLE_WD_TO_TH[15..8] - (RW) Watchdog timeout threshold for page +link +* FSM not returning to IDLE +* PORT_IDLE_WD_TO_TH[23..16] - (RW) Watchdog timeout threshold for +* port oper +* FSM not returning to IDLE +* (Including HIF/CPU/LMAC port) +* MACTX_IDLE_WD_TO_TH[31..24] - (RW) Watchdog timeout threshold for +* MACTX FSM +* not returning to IDLE +*/ +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_MACTX_IDLE_WD_TO_TH_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_CTRL_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_MACTX_IDLE_WD_TO_TH_MASK \ + 0xFF000000 /* MACTX_IDLE_WD_TO_TH[31..24] */ +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_MACTX_IDLE_WD_TO_TH_SHFT 24 +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_PORT_IDLE_WD_TO_TH_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_CTRL_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_PORT_IDLE_WD_TO_TH_MASK \ + 0x00FF0000 /* PORT_IDLE_WD_TO_TH[23..16] */ +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_PORT_IDLE_WD_TO_TH_SHFT 16 +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_PL_IDLE_WD_TO_TH_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_CTRL_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_PL_IDLE_WD_TO_TH_MASK \ + 0x0000FF00 /* PL_IDLE_WD_TO_TH[15..8] */ +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_PL_IDLE_WD_TO_TH_SHFT 8 +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_FL_IDLE_WD_TO_TH_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_CTRL_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_FL_IDLE_WD_TO_TH_MASK \ + 0x000000FF /* FL_IDLE_WD_TO_TH[7..0] */ +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_FL_IDLE_WD_TO_TH_SHFT 0 + +/* +* ---FSM_IDLE_WD_EN (0x820C0000 + 0x250)--- +* EN_FL_IDLE_WD_TO[0] - (RW) Enables watchdog for frame link FSM not +* returning to IDLE +* EN_PL_IDLE_WD_TO[1] - (RW) Enables watchdog for page link FSM not +* returning to IDLE +* EN_CPU_PORT_IDLE_WD_TO[2] - (RW) Enables watchdog for CPU port oper +FSM +* not returning to IDLE +* EN_HIF_PORT_IDLE_WD_TO[3] - (RW) Enables watchdog for HIF port oper +FSM +* not returning to IDLE +* EN_LMAC_PORT_IDLE_WD_TO[4] - (RW) Enables watchdog for LMAC port +* oper FSM +* not returning to IDLE +* EN_AMSDU_PORT_IDLE_WD_TO[5] - (RW) Enables watchdog for AMSDU port +* FSM not +* returning to IDLE +* EN_HW_AMSDU_IDLE_WD_TO[6] - (RW) Enables watchdog for HW AMSDU FSM +not +* returning to IDLE +* RESERVED7[7] - (RO) Reserved bits +* EN_MACTX0_IDLE_WD_TO[8] - (RW) Enables watchdog for MACTX 0 FSM not +* returning to IDLE +* EN_MACTX2_IDLE_WD_TO[9] - (RW) Enables watchdog for MACTX 1 FSM not +* returning to IDLE +* EN_MACTX1_IDLE_WD_TO[10] - (RW) Enables watchdog for MACTX 2 FSM not +* returning to IDLE +* EN_MACTX3_IDLE_WD_TO[11] - (RW) Enables watchdog for MACTX 3 FSM not +* returning to IDLE +* EN_MDP_IDLE_WD_TO[12] - (RW) Enables watchdog for MDP port oper FSM +* not returning to IDLE +* EN_PREDL_ARB_IDLE_WD_TO[13] - (RW) Enables watchdog for Predl +arbitrator +* FSM not returning to IDLE +* EN_PREDL_TXCMD_IDLE_WD_TO[14] - (RW) Enables watchdog for Predl +* TXCMD parser +* FSM not returning to IDLE +* RESERVED15[31..15] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_PREDL_TXCMD_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_PREDL_TXCMD_IDLE_WD_TO_MASK \ + 0x00004000 /* EN_PREDL_TXCMD_IDLE_WD_TO[14] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_PREDL_TXCMD_IDLE_WD_TO_SHFT 14 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_PREDL_ARB_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_PREDL_ARB_IDLE_WD_TO_MASK \ + 0x00002000 /* EN_PREDL_ARB_IDLE_WD_TO[13] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_PREDL_ARB_IDLE_WD_TO_SHFT 13 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MDP_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MDP_IDLE_WD_TO_MASK \ + 0x00001000 /* EN_MDP_IDLE_WD_TO[12] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MDP_IDLE_WD_TO_SHFT 12 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MACTX3_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MACTX3_IDLE_WD_TO_MASK \ + 0x00000800 /* EN_MACTX3_IDLE_WD_TO[11] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MACTX3_IDLE_WD_TO_SHFT 11 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MACTX1_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MACTX1_IDLE_WD_TO_MASK \ + 0x00000400 /* EN_MACTX1_IDLE_WD_TO[10] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MACTX1_IDLE_WD_TO_SHFT 10 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MACTX2_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MACTX2_IDLE_WD_TO_MASK \ + 0x00000200 /* EN_MACTX2_IDLE_WD_TO[9] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MACTX2_IDLE_WD_TO_SHFT 9 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MACTX0_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MACTX0_IDLE_WD_TO_MASK \ + 0x00000100 /* EN_MACTX0_IDLE_WD_TO[8] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_MACTX0_IDLE_WD_TO_SHFT 8 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_HW_AMSDU_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_HW_AMSDU_IDLE_WD_TO_MASK \ + 0x00000040 /* EN_HW_AMSDU_IDLE_WD_TO[6] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_HW_AMSDU_IDLE_WD_TO_SHFT 6 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_AMSDU_PORT_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_AMSDU_PORT_IDLE_WD_TO_MASK \ + 0x00000020 /* EN_AMSDU_PORT_IDLE_WD_TO[5] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_AMSDU_PORT_IDLE_WD_TO_SHFT 5 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_LMAC_PORT_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_LMAC_PORT_IDLE_WD_TO_MASK \ + 0x00000010 /* EN_LMAC_PORT_IDLE_WD_TO[4] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_LMAC_PORT_IDLE_WD_TO_SHFT 4 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_HIF_PORT_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_HIF_PORT_IDLE_WD_TO_MASK \ + 0x00000008 /* EN_HIF_PORT_IDLE_WD_TO[3] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_HIF_PORT_IDLE_WD_TO_SHFT 3 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_CPU_PORT_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_CPU_PORT_IDLE_WD_TO_MASK \ + 0x00000004 /* EN_CPU_PORT_IDLE_WD_TO[2] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_CPU_PORT_IDLE_WD_TO_SHFT 2 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_PL_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_PL_IDLE_WD_TO_MASK \ + 0x00000002 /* EN_PL_IDLE_WD_TO[1] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_PL_IDLE_WD_TO_SHFT 1 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_FL_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_FL_IDLE_WD_TO_MASK \ + 0x00000001 /* EN_FL_IDLE_WD_TO[0] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_EN_FL_IDLE_WD_TO_SHFT 0 + +/* +* ---FSM_IDLE_WD_CTRL_1 (0x820C0000 + 0x258)--- +* MDP_IDLE_WD_TO_TH[7..0] - (RW) Watchdog timeout threshold for MDP +FSM +* not returning to IDLE +* (Including MDP TDP/RDP/TIOC/RIOC) +* PF_IDLE_WD_TO_TH[15..8] - (RW) Watchdog timeout threshold for PF FSM +* not returning to IDLE +* SEC_IDLE_WD_TO_TH[23..16] - (RW) Watchdog timeout threshold for SEC +FSM +* not returning to IDLE +* (Including SEC0/SEC1) +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_1_SEC_IDLE_WD_TO_TH_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_CTRL_1_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_1_SEC_IDLE_WD_TO_TH_MASK \ + 0x00FF0000 /* SEC_IDLE_WD_TO_TH[23..16] */ +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_1_SEC_IDLE_WD_TO_TH_SHFT 16 +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_1_PF_IDLE_WD_TO_TH_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_CTRL_1_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_1_PF_IDLE_WD_TO_TH_MASK \ + 0x0000FF00 /* PF_IDLE_WD_TO_TH[15..8] */ +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_1_PF_IDLE_WD_TO_TH_SHFT 8 +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_1_MDP_IDLE_WD_TO_TH_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_CTRL_1_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_1_MDP_IDLE_WD_TO_TH_MASK \ + 0x000000FF /* MDP_IDLE_WD_TO_TH[7..0] */ +#define WF_PLE_TOP_FSM_IDLE_WD_CTRL_1_MDP_IDLE_WD_TO_TH_SHFT 0 + +/* +* ---FSM_IDLE_WD_EN_1 (0x820C0000 + 0x25C)--- +* EN_BN0_MDP_TDP_IDLE_WD_TO[0] - (RW) Enables watchdog for Band0 MDP +* TDP FSM +* not returning to IDLE +* EN_MDP_RDP_IDLE_WD_TO[1] - (RW) Enables watchdog for MDP RDP FSM not +* returning to IDLE +* EN_BN0_MDP_TIOC_IDLE_WD_TO[2] - (RW) Enables watchdog for Band0 MDP +* TIOC FSM +* not returning to IDLE +* EN_BN0_MDP_RIOC_IDLE_WD_TO[3] - (RW) Enables watchdog for Band0 MDP +* RIOC FSM +* not returning to IDLE +* EN_PF_IDLE_WD_TO[4] - (RW) Enables watchdog for PF FSM not +* returning to IDLE +* EN_SEC0_IDLE_WD_TO[5] - (RW) Enables watchdog for SEC0 FSM not +* returning to IDLE +* EN_SEC1_IDLE_WD_TO[6] - (RW) Enables watchdog for SEC1 FSM not +* returning to IDLE +* EN_BN1_MDP_TDP_IDLE_WD_TO[7] - (RW) Enables watchdog for Band1 MDP +* TDP FSM +* not returning to IDLE +* EN_BN1_MDP_TIOC_IDLE_WD_TO[8] - (RW) Enables watchdog for Band1 MDP +* TIOC FSM +* not returning to IDLE +* EN_BN1_MDP_RIOC_IDLE_WD_TO[9] - (RW) Enables watchdog for Band1 MDP +* RIOC FSM +* not returning to IDLE +* RESERVED10[31..10] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN1_MDP_RIOC_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_1_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN1_MDP_RIOC_IDLE_WD_TO_MASK \ + 0x00000200 /* EN_BN1_MDP_RIOC_IDLE_WD_TO[9] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN1_MDP_RIOC_IDLE_WD_TO_SHFT 9 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN1_MDP_TIOC_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_1_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN1_MDP_TIOC_IDLE_WD_TO_MASK \ + 0x00000100 /* EN_BN1_MDP_TIOC_IDLE_WD_TO[8] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN1_MDP_TIOC_IDLE_WD_TO_SHFT 8 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN1_MDP_TDP_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_1_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN1_MDP_TDP_IDLE_WD_TO_MASK \ + 0x00000080 /* EN_BN1_MDP_TDP_IDLE_WD_TO[7] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN1_MDP_TDP_IDLE_WD_TO_SHFT 7 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_SEC1_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_1_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_SEC1_IDLE_WD_TO_MASK \ + 0x00000040 /* EN_SEC1_IDLE_WD_TO[6] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_SEC1_IDLE_WD_TO_SHFT 6 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_SEC0_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_1_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_SEC0_IDLE_WD_TO_MASK \ + 0x00000020 /* EN_SEC0_IDLE_WD_TO[5] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_SEC0_IDLE_WD_TO_SHFT 5 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_PF_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_1_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_PF_IDLE_WD_TO_MASK \ + 0x00000010 /* EN_PF_IDLE_WD_TO[4] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_PF_IDLE_WD_TO_SHFT 4 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN0_MDP_RIOC_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_1_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN0_MDP_RIOC_IDLE_WD_TO_MASK \ + 0x00000008 /* EN_BN0_MDP_RIOC_IDLE_WD_TO[3] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN0_MDP_RIOC_IDLE_WD_TO_SHFT 3 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN0_MDP_TIOC_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_1_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN0_MDP_TIOC_IDLE_WD_TO_MASK \ + 0x00000004 /* EN_BN0_MDP_TIOC_IDLE_WD_TO[2] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN0_MDP_TIOC_IDLE_WD_TO_SHFT 2 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_MDP_RDP_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_1_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_MDP_RDP_IDLE_WD_TO_MASK \ + 0x00000002 /* EN_MDP_RDP_IDLE_WD_TO[1] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_MDP_RDP_IDLE_WD_TO_SHFT 1 +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN0_MDP_TDP_IDLE_WD_TO_ADDR \ + WF_PLE_TOP_FSM_IDLE_WD_EN_1_ADDR +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN0_MDP_TDP_IDLE_WD_TO_MASK \ + 0x00000001 /* EN_BN0_MDP_TDP_IDLE_WD_TO[0] */ +#define WF_PLE_TOP_FSM_IDLE_WD_EN_1_EN_BN0_MDP_TDP_IDLE_WD_TO_SHFT 0 + +/* +* ---SRAM_MBIST_DELSEL9 (0x820C0000 + 0x260)--- +* SRAM9_MBIST_DELSEL[31..0] - (RW) MBIST delsel setting of SRAM9 +*/ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL9_SRAM9_MBIST_DELSEL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_DELSEL9_ADDR +#define WF_PLE_TOP_SRAM_MBIST_DELSEL9_SRAM9_MBIST_DELSEL_MASK \ + 0xFFFFFFFF /* SRAM9_MBIST_DELSEL[31..0] */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL9_SRAM9_MBIST_DELSEL_SHFT 0 + +/* +* ---SRAM_MBIST_DELSEL10 (0x820C0000 + 0x264)--- +* SRAM10_MBIST_DELSEL[31..0] - (RW) MBIST delsel setting of SRAM10 +*/ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL10_SRAM10_MBIST_DELSEL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_DELSEL10_ADDR +#define WF_PLE_TOP_SRAM_MBIST_DELSEL10_SRAM10_MBIST_DELSEL_MASK \ + 0xFFFFFFFF /* SRAM10_MBIST_DELSEL[31..0] */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL10_SRAM10_MBIST_DELSEL_SHFT 0 + +/* +* ---FUNC_ACT_CNT_1 (0x820C0000 + 0x284)--- +* MACTX0_ACT_CNT[3..0] - (RO) Counter of MACTX0 TX active. +* MACTX0_NOR_END_CNT[7..4] - (RO) Counter of MACTX0 TX normal end. +* MACTX0_ABORT_CNT[11..8] - (RO) Counter of MACTX0 TX abort. +* RESERVED12[15..12] - (RO) Reserved bits +* TXCMD0_ADD_FID_CNT[19..16] - (RO) Counter of TXCMD0 TX add FID. +* TXCMD0_NOR_END_CNT[23..20] - (RO) Counter of TXCMD0 TX normal end. +* TXCMD0_ABORT_CNT[27..24] - (RO) Counter of TXCMD0 TX abort. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_FUNC_ACT_CNT_1_TXCMD0_ABORT_CNT_ADDR \ + WF_PLE_TOP_FUNC_ACT_CNT_1_ADDR +#define WF_PLE_TOP_FUNC_ACT_CNT_1_TXCMD0_ABORT_CNT_MASK \ + 0x0F000000 /* TXCMD0_ABORT_CNT[27..24] */ +#define WF_PLE_TOP_FUNC_ACT_CNT_1_TXCMD0_ABORT_CNT_SHFT 24 +#define WF_PLE_TOP_FUNC_ACT_CNT_1_TXCMD0_NOR_END_CNT_ADDR \ + WF_PLE_TOP_FUNC_ACT_CNT_1_ADDR +#define WF_PLE_TOP_FUNC_ACT_CNT_1_TXCMD0_NOR_END_CNT_MASK \ + 0x00F00000 /* TXCMD0_NOR_END_CNT[23..20] */ +#define WF_PLE_TOP_FUNC_ACT_CNT_1_TXCMD0_NOR_END_CNT_SHFT 20 +#define WF_PLE_TOP_FUNC_ACT_CNT_1_TXCMD0_ADD_FID_CNT_ADDR \ + WF_PLE_TOP_FUNC_ACT_CNT_1_ADDR +#define WF_PLE_TOP_FUNC_ACT_CNT_1_TXCMD0_ADD_FID_CNT_MASK \ + 0x000F0000 /* TXCMD0_ADD_FID_CNT[19..16] */ +#define WF_PLE_TOP_FUNC_ACT_CNT_1_TXCMD0_ADD_FID_CNT_SHFT 16 +#define WF_PLE_TOP_FUNC_ACT_CNT_1_MACTX0_ABORT_CNT_ADDR \ + WF_PLE_TOP_FUNC_ACT_CNT_1_ADDR +#define WF_PLE_TOP_FUNC_ACT_CNT_1_MACTX0_ABORT_CNT_MASK \ + 0x00000F00 /* MACTX0_ABORT_CNT[11..8] */ +#define WF_PLE_TOP_FUNC_ACT_CNT_1_MACTX0_ABORT_CNT_SHFT 8 +#define WF_PLE_TOP_FUNC_ACT_CNT_1_MACTX0_NOR_END_CNT_ADDR \ + WF_PLE_TOP_FUNC_ACT_CNT_1_ADDR +#define WF_PLE_TOP_FUNC_ACT_CNT_1_MACTX0_NOR_END_CNT_MASK \ + 0x000000F0 /* MACTX0_NOR_END_CNT[7..4] */ +#define WF_PLE_TOP_FUNC_ACT_CNT_1_MACTX0_NOR_END_CNT_SHFT 4 +#define WF_PLE_TOP_FUNC_ACT_CNT_1_MACTX0_ACT_CNT_ADDR \ + WF_PLE_TOP_FUNC_ACT_CNT_1_ADDR +#define WF_PLE_TOP_FUNC_ACT_CNT_1_MACTX0_ACT_CNT_MASK \ + 0x0000000F /* MACTX0_ACT_CNT[3..0] */ +#define WF_PLE_TOP_FUNC_ACT_CNT_1_MACTX0_ACT_CNT_SHFT 0 + +/* +* ---PORT_SER_CTRL (0x820C0000 + 0x2A0)--- +* EN_HIF_PORT_ALLOC_BLOCKING[0] - (RW) Enable HIF/AMSDU port allocate +* operation blocking. +* EN_CPU_PORT_ALLOC_BLOCKING[1] - (RW) Enable CPU port allocate +operation +blocking. +* EN_WF_PORT_ALLOC_BLOCKING[2] - (RW) Enable LMAC port allocate +operation +blocking. +* RESERVED3[7..3] - (RO) Reserved bits +* EN_HIF_PORT_D_OPR_BLOCKING[8] - (RW) Enable HIF/AMSDU/MDP/PREDL port +data +* operation blocking. +* EN_CPU_PORT_D_OPR_BLOCKING[9] - (RW) Enable CPU port data operation +blocking. +* EN_WF_PORT_D_OPR_BLOCKING[10] - (RW) Enable LMAC port data operation +blocking. +* RESERVED11[15..11] - (RO) Reserved bits +* EN_HIF_PORT_Q_OPR_BLOCKING[16] - (RW) Enable HIF/AMSDU port queue +operation +blocking. +* EN_CPU_PORT_Q_OPR_BLOCKING[17] - (RW) Enable CPU port queue +operation +blocking. +* EN_WF_PORT_Q_OPR_BLOCKING[18] - (RW) Enable LMAC port queue +operation +blocking. +* RESERVED19[31..19] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_PORT_SER_CTRL_EN_WF_PORT_Q_OPR_BLOCKING_ADDR \ + WF_PLE_TOP_PORT_SER_CTRL_ADDR +#define WF_PLE_TOP_PORT_SER_CTRL_EN_WF_PORT_Q_OPR_BLOCKING_MASK \ + 0x00040000 /* EN_WF_PORT_Q_OPR_BLOCKING[18] */ +#define WF_PLE_TOP_PORT_SER_CTRL_EN_WF_PORT_Q_OPR_BLOCKING_SHFT 18 +#define WF_PLE_TOP_PORT_SER_CTRL_EN_CPU_PORT_Q_OPR_BLOCKING_ADDR \ + WF_PLE_TOP_PORT_SER_CTRL_ADDR +#define WF_PLE_TOP_PORT_SER_CTRL_EN_CPU_PORT_Q_OPR_BLOCKING_MASK \ + 0x00020000 /* EN_CPU_PORT_Q_OPR_BLOCKING[17] */ +#define WF_PLE_TOP_PORT_SER_CTRL_EN_CPU_PORT_Q_OPR_BLOCKING_SHFT 17 +#define WF_PLE_TOP_PORT_SER_CTRL_EN_HIF_PORT_Q_OPR_BLOCKING_ADDR \ + WF_PLE_TOP_PORT_SER_CTRL_ADDR +#define WF_PLE_TOP_PORT_SER_CTRL_EN_HIF_PORT_Q_OPR_BLOCKING_MASK \ + 0x00010000 /* EN_HIF_PORT_Q_OPR_BLOCKING[16] */ +#define WF_PLE_TOP_PORT_SER_CTRL_EN_HIF_PORT_Q_OPR_BLOCKING_SHFT 16 +#define WF_PLE_TOP_PORT_SER_CTRL_EN_WF_PORT_D_OPR_BLOCKING_ADDR \ + WF_PLE_TOP_PORT_SER_CTRL_ADDR +#define WF_PLE_TOP_PORT_SER_CTRL_EN_WF_PORT_D_OPR_BLOCKING_MASK \ + 0x00000400 /* EN_WF_PORT_D_OPR_BLOCKING[10] */ +#define WF_PLE_TOP_PORT_SER_CTRL_EN_WF_PORT_D_OPR_BLOCKING_SHFT 10 +#define WF_PLE_TOP_PORT_SER_CTRL_EN_CPU_PORT_D_OPR_BLOCKING_ADDR \ + WF_PLE_TOP_PORT_SER_CTRL_ADDR +#define WF_PLE_TOP_PORT_SER_CTRL_EN_CPU_PORT_D_OPR_BLOCKING_MASK \ + 0x00000200 /* EN_CPU_PORT_D_OPR_BLOCKING[9] */ +#define WF_PLE_TOP_PORT_SER_CTRL_EN_CPU_PORT_D_OPR_BLOCKING_SHFT 9 +#define WF_PLE_TOP_PORT_SER_CTRL_EN_HIF_PORT_D_OPR_BLOCKING_ADDR \ + WF_PLE_TOP_PORT_SER_CTRL_ADDR +#define WF_PLE_TOP_PORT_SER_CTRL_EN_HIF_PORT_D_OPR_BLOCKING_MASK \ + 0x00000100 /* EN_HIF_PORT_D_OPR_BLOCKING[8] */ +#define WF_PLE_TOP_PORT_SER_CTRL_EN_HIF_PORT_D_OPR_BLOCKING_SHFT 8 +#define WF_PLE_TOP_PORT_SER_CTRL_EN_WF_PORT_ALLOC_BLOCKING_ADDR \ + WF_PLE_TOP_PORT_SER_CTRL_ADDR +#define WF_PLE_TOP_PORT_SER_CTRL_EN_WF_PORT_ALLOC_BLOCKING_MASK \ + 0x00000004 /* EN_WF_PORT_ALLOC_BLOCKING[2] */ +#define WF_PLE_TOP_PORT_SER_CTRL_EN_WF_PORT_ALLOC_BLOCKING_SHFT 2 +#define WF_PLE_TOP_PORT_SER_CTRL_EN_CPU_PORT_ALLOC_BLOCKING_ADDR \ + WF_PLE_TOP_PORT_SER_CTRL_ADDR +#define WF_PLE_TOP_PORT_SER_CTRL_EN_CPU_PORT_ALLOC_BLOCKING_MASK \ + 0x00000002 /* EN_CPU_PORT_ALLOC_BLOCKING[1] */ +#define WF_PLE_TOP_PORT_SER_CTRL_EN_CPU_PORT_ALLOC_BLOCKING_SHFT 1 +#define WF_PLE_TOP_PORT_SER_CTRL_EN_HIF_PORT_ALLOC_BLOCKING_ADDR \ + WF_PLE_TOP_PORT_SER_CTRL_ADDR +#define WF_PLE_TOP_PORT_SER_CTRL_EN_HIF_PORT_ALLOC_BLOCKING_MASK \ + 0x00000001 /* EN_HIF_PORT_ALLOC_BLOCKING[0] */ +#define WF_PLE_TOP_PORT_SER_CTRL_EN_HIF_PORT_ALLOC_BLOCKING_SHFT 0 + +/* +* ---MACTX_SER_CTRL (0x820C0000 + 0x2A4)--- +* EN_MACTX_G0_BLOCKING[0] - (RW) Enable MACTX group 0 operation +blocking. +* RESERVED1[7..1] - (RO) Reserved bits +* EN_MACTX_G1_BLOCKING[8] - (RW) Enable MACTX group 1 operation +blocking. +* RESERVED9[15..9] - (RO) Reserved bits +* EN_MACTX_G2_BLOCKING[16] - (RW) Enable MACTX group 2 operation +blocking. +* RESERVED17[23..17] - (RO) Reserved bits +* EN_MACTX_G3_BLOCKING[24] - (RW) Enable MACTX group 3 operation +blocking. +* RESERVED25[31..25] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_MACTX_SER_CTRL_EN_MACTX_G3_BLOCKING_ADDR \ + WF_PLE_TOP_MACTX_SER_CTRL_ADDR +#define WF_PLE_TOP_MACTX_SER_CTRL_EN_MACTX_G3_BLOCKING_MASK \ + 0x01000000 /* EN_MACTX_G3_BLOCKING[24] */ +#define WF_PLE_TOP_MACTX_SER_CTRL_EN_MACTX_G3_BLOCKING_SHFT 24 +#define WF_PLE_TOP_MACTX_SER_CTRL_EN_MACTX_G2_BLOCKING_ADDR \ + WF_PLE_TOP_MACTX_SER_CTRL_ADDR +#define WF_PLE_TOP_MACTX_SER_CTRL_EN_MACTX_G2_BLOCKING_MASK \ + 0x00010000 /* EN_MACTX_G2_BLOCKING[16] */ +#define WF_PLE_TOP_MACTX_SER_CTRL_EN_MACTX_G2_BLOCKING_SHFT 16 +#define WF_PLE_TOP_MACTX_SER_CTRL_EN_MACTX_G1_BLOCKING_ADDR \ + WF_PLE_TOP_MACTX_SER_CTRL_ADDR +#define WF_PLE_TOP_MACTX_SER_CTRL_EN_MACTX_G1_BLOCKING_MASK \ + 0x00000100 /* EN_MACTX_G1_BLOCKING[8] */ +#define WF_PLE_TOP_MACTX_SER_CTRL_EN_MACTX_G1_BLOCKING_SHFT 8 +#define WF_PLE_TOP_MACTX_SER_CTRL_EN_MACTX_G0_BLOCKING_ADDR \ + WF_PLE_TOP_MACTX_SER_CTRL_ADDR +#define WF_PLE_TOP_MACTX_SER_CTRL_EN_MACTX_G0_BLOCKING_MASK \ + 0x00000001 /* EN_MACTX_G0_BLOCKING[0] */ +#define WF_PLE_TOP_MACTX_SER_CTRL_EN_MACTX_G0_BLOCKING_SHFT 0 + +/* +* ---DRR_SER_CTRL (0x820C0000 + 0x2A8)--- +* EN_DRR_CHARGE_BLOCKING[0] - (RW) Enable DRR charge operation +blocking. +* RESERVED1[3..1] - (RO) Reserved bits +* EN_DRR_SRCH_0_BLOCKING[4] - (RW) Enable DRR search 0 operation +blocking. +* EN_DRR_SRCH_1_BLOCKING[5] - (RW) Enable DRR search 1 operation +blocking. +* RESERVED6[7..6] - (RO) Reserved bits +* EN_DRR_RDG_0_BLOCKING[8] - (RW) Enable DRR RDG 0 operation blocking. +* EN_DRR_RDG_1_BLOCKING[9] - (RW) Enable DRR RDG 1 operation blocking. +* RESERVED10[31..10] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_RDG_1_BLOCKING_ADDR \ + WF_PLE_TOP_DRR_SER_CTRL_ADDR +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_RDG_1_BLOCKING_MASK \ + 0x00000200 /* EN_DRR_RDG_1_BLOCKING[9] */ +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_RDG_1_BLOCKING_SHFT 9 +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_RDG_0_BLOCKING_ADDR \ + WF_PLE_TOP_DRR_SER_CTRL_ADDR +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_RDG_0_BLOCKING_MASK \ + 0x00000100 /* EN_DRR_RDG_0_BLOCKING[8] */ +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_RDG_0_BLOCKING_SHFT 8 +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_SRCH_1_BLOCKING_ADDR \ + WF_PLE_TOP_DRR_SER_CTRL_ADDR +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_SRCH_1_BLOCKING_MASK \ + 0x00000020 /* EN_DRR_SRCH_1_BLOCKING[5] */ +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_SRCH_1_BLOCKING_SHFT 5 +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_SRCH_0_BLOCKING_ADDR \ + WF_PLE_TOP_DRR_SER_CTRL_ADDR +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_SRCH_0_BLOCKING_MASK \ + 0x00000010 /* EN_DRR_SRCH_0_BLOCKING[4] */ +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_SRCH_0_BLOCKING_SHFT 4 +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_CHARGE_BLOCKING_ADDR \ + WF_PLE_TOP_DRR_SER_CTRL_ADDR +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_CHARGE_BLOCKING_MASK \ + 0x00000001 /* EN_DRR_CHARGE_BLOCKING[0] */ +#define WF_PLE_TOP_DRR_SER_CTRL_EN_DRR_CHARGE_BLOCKING_SHFT 0 + +/* +* ---SRAM_MBIST_DELSEL5 (0x820C0000 + 0x2c0)--- +* SRAM5_MBIST_DELSEL[31..0] - (RW) MBIST delsel setting of SRAM5 +*/ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL5_SRAM5_MBIST_DELSEL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_DELSEL5_ADDR +#define WF_PLE_TOP_SRAM_MBIST_DELSEL5_SRAM5_MBIST_DELSEL_MASK \ + 0xFFFFFFFF /* SRAM5_MBIST_DELSEL[31..0] */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL5_SRAM5_MBIST_DELSEL_SHFT 0 + +/* +* ---SRAM_MBIST_DELSEL6 (0x820C0000 + 0x2c4)--- +* SRAM6_MBIST_DELSEL[31..0] - (RW) MBIST delsel setting of SRAM6 +*/ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL6_SRAM6_MBIST_DELSEL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_DELSEL6_ADDR +#define WF_PLE_TOP_SRAM_MBIST_DELSEL6_SRAM6_MBIST_DELSEL_MASK \ + 0xFFFFFFFF /* SRAM6_MBIST_DELSEL[31..0] */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL6_SRAM6_MBIST_DELSEL_SHFT 0 + +/* +* ---SRAM_MBIST_DELSEL7 (0x820C0000 + 0x2c8)--- +* SRAM7_MBIST_DELSEL[31..0] - (RW) MBIST delsel setting of SRAM7 +*/ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL7_SRAM7_MBIST_DELSEL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_DELSEL7_ADDR +#define WF_PLE_TOP_SRAM_MBIST_DELSEL7_SRAM7_MBIST_DELSEL_MASK \ + 0xFFFFFFFF /* SRAM7_MBIST_DELSEL[31..0] */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL7_SRAM7_MBIST_DELSEL_SHFT 0 + +/* +* ---SRAM_MBIST_DELSEL8 (0x820C0000 + 0x2cc)--- +* SRAM8_MBIST_DELSEL[31..0] - (RW) MBIST delsel setting of SRAM8 +*/ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL8_SRAM8_MBIST_DELSEL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_DELSEL8_ADDR +#define WF_PLE_TOP_SRAM_MBIST_DELSEL8_SRAM8_MBIST_DELSEL_MASK \ + 0xFFFFFFFF /* SRAM8_MBIST_DELSEL[31..0] */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL8_SRAM8_MBIST_DELSEL_SHFT 0 + +/* +* ---SRAM_MBIST_BACKGROUND (0x820C0000 + 0x2d0)--- +* MBIST_BACKGROUND[15..0] - (RW) bsel setting for PLE SRAM MBIST +circuit +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_SRAM_MBIST_BACKGROUND_MBIST_BACKGROUND_ADDR \ + WF_PLE_TOP_SRAM_MBIST_BACKGROUND_ADDR +#define WF_PLE_TOP_SRAM_MBIST_BACKGROUND_MBIST_BACKGROUND_MASK \ + 0x0000FFFF /* MBIST_BACKGROUND[15..0] */ +#define WF_PLE_TOP_SRAM_MBIST_BACKGROUND_MBIST_BACKGROUND_SHFT 0 + +/* +* ---SRAM_MBIST_BSEL (0x820C0000 + 0x2d4)--- +* MBIST_BSEL[15..0] - (RW) The bsel setting for PLE SRAM MBIST +circuit. +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_SRAM_MBIST_BSEL_MBIST_BSEL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_BSEL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_BSEL_MBIST_BSEL_MASK \ + 0x0000FFFF /* MBIST_BSEL[15..0] */ +#define WF_PLE_TOP_SRAM_MBIST_BSEL_MBIST_BSEL_SHFT 0 + +/* +* ---SRAM_MBIST_DONE (0x820C0000 + 0x2d8)--- +* G1_MBIST_DONE[0] - (RO) Working status of PLE G1 SRAM MBIST +circuit +* G2_MBIST_DONE[1] - (RO) Working status of PLE G2 SRAM MBIST +circuit +* RESERVED2[31..2] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_SRAM_MBIST_DONE_G2_MBIST_DONE_ADDR \ + WF_PLE_TOP_SRAM_MBIST_DONE_ADDR +#define WF_PLE_TOP_SRAM_MBIST_DONE_G2_MBIST_DONE_MASK \ + 0x00000002 /* G2_MBIST_DONE[1] */ +#define WF_PLE_TOP_SRAM_MBIST_DONE_G2_MBIST_DONE_SHFT 1 +#define WF_PLE_TOP_SRAM_MBIST_DONE_G1_MBIST_DONE_ADDR \ + WF_PLE_TOP_SRAM_MBIST_DONE_ADDR +#define WF_PLE_TOP_SRAM_MBIST_DONE_G1_MBIST_DONE_MASK \ + 0x00000001 /* G1_MBIST_DONE[0] */ +#define WF_PLE_TOP_SRAM_MBIST_DONE_G1_MBIST_DONE_SHFT 0 + +/* +* ---SRAM_MBIST_FAIL (0x820C0000 + 0x2dc)--- +* G1_SRAM0_MBIST_FAIL[0] - (RO) MBIST check result of group 1 SRAM0 +* G1_SRAM1_MBIST_FAIL[1] - (RO) MBIST check result of group 1 SRAM1 +* G1_SRAM2_MBIST_FAIL[2] - (RO) MBIST check result of group 1 SRAM2 +* G1_SRAM3_MBIST_FAIL[3] - (RO) MBIST check result of group 1 SRAM3 +* G2_SRAM0_MBIST_FAIL[4] - (RO) MBIST check result of group 2 SRAM0 +* G2_SRAM1_MBIST_FAIL[5] - (RO) MBIST check result of group 2 SRAM1 +* G2_SRAM2_MBIST_FAIL[6] - (RO) MBIST check result of group 2 SRAM2 +* G2_SRAM3_MBIST_FAIL[7] - (RO) MBIST check result of group 2 SRAM3 +* G2_SRAM4_MBIST_FAIL[8] - (RO) MBIST check result of group 2 SRAM4 +* G2_SRAM5_MBIST_FAIL[9] - (RO) MBIST check result of group 2 SRAM5 +* RESERVED10[31..10] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM5_MBIST_FAIL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_FAIL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM5_MBIST_FAIL_MASK \ + 0x00000200 /* G2_SRAM5_MBIST_FAIL[9] */ +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM5_MBIST_FAIL_SHFT 9 +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM4_MBIST_FAIL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_FAIL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM4_MBIST_FAIL_MASK \ + 0x00000100 /* G2_SRAM4_MBIST_FAIL[8] */ +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM4_MBIST_FAIL_SHFT 8 +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM3_MBIST_FAIL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_FAIL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM3_MBIST_FAIL_MASK \ + 0x00000080 /* G2_SRAM3_MBIST_FAIL[7] */ +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM3_MBIST_FAIL_SHFT 7 +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM2_MBIST_FAIL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_FAIL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM2_MBIST_FAIL_MASK \ + 0x00000040 /* G2_SRAM2_MBIST_FAIL[6] */ +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM2_MBIST_FAIL_SHFT 6 +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM1_MBIST_FAIL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_FAIL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM1_MBIST_FAIL_MASK \ + 0x00000020 /* G2_SRAM1_MBIST_FAIL[5] */ +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM1_MBIST_FAIL_SHFT 5 +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM0_MBIST_FAIL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_FAIL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM0_MBIST_FAIL_MASK \ + 0x00000010 /* G2_SRAM0_MBIST_FAIL[4] */ +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G2_SRAM0_MBIST_FAIL_SHFT 4 +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G1_SRAM3_MBIST_FAIL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_FAIL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G1_SRAM3_MBIST_FAIL_MASK \ + 0x00000008 /* G1_SRAM3_MBIST_FAIL[3] */ +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G1_SRAM3_MBIST_FAIL_SHFT 3 +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G1_SRAM2_MBIST_FAIL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_FAIL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G1_SRAM2_MBIST_FAIL_MASK \ + 0x00000004 /* G1_SRAM2_MBIST_FAIL[2] */ +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G1_SRAM2_MBIST_FAIL_SHFT 2 +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G1_SRAM1_MBIST_FAIL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_FAIL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G1_SRAM1_MBIST_FAIL_MASK \ + 0x00000002 /* G1_SRAM1_MBIST_FAIL[1] */ +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G1_SRAM1_MBIST_FAIL_SHFT 1 +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G1_SRAM0_MBIST_FAIL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_FAIL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G1_SRAM0_MBIST_FAIL_MASK \ + 0x00000001 /* G1_SRAM0_MBIST_FAIL[0] */ +#define WF_PLE_TOP_SRAM_MBIST_FAIL_G1_SRAM0_MBIST_FAIL_SHFT 0 + +/* +* ---SRAM_MBIST_CTRL (0x820C0000 + 0x2e0)--- +* G1_MBIST_MODE[0] - (RW) Control register for mbist_mode of group +* 1 MBIST +* G2_MBIST_MODE[1] - (RW) Control register for mbist_mode of group +* 2 MBIST +* RESERVED2[3..2] - (RO) Reserved bits +* G1_MBIST_HOLDB[4] - (RW) Control register for mbist_holdb of +* group 1 MBIST +* G2_MBIST_HOLDB[5] - (RW) Control register for mbist_holdb of +* group 2 MBIST +* RESERVED6[7..6] - (RO) Reserved bits +* G1_MBIST_DEBUG[8] - (RW) Control register for mbist_debug of +* group 1 MBIST +* G2_MBIST_DEBUG[9] - (RW) Control register for mbist_debug of +* group 2 MBIST +* G1_MBIST_USE_DEFAULT_DELSEL[10] - (RW) Control register for default +DELSEL +* value of group 1 memory +* G2_MBIST_USE_DEFAULT_DELSEL[11] - (RW) Control register for default +DELSEL +* value of group 2 memory +* MBIST_DIAG_SEL[16..12] - (RW) Selection register for +mbist_diag_scan_out +* RESERVED17[19..17] - (RO) Reserved bits +* UMAC_MBIST_DIAG_SEL[20] - (RW) Selection register for UMAC +* mbist_diag_scan_out (PLE or PSE) +* RESERVED21[23..21] - (RO) Reserved bits +* G1_MBIST_SLEEP_TEST[24] - (RW) Control register for sleep_test of +group +* 1 MBIST +* G1_MBIST_SLEEP_INV[25] - (RW) Control register for sleep_inv of +group +* 1 MBIST +* G1_MBIST_SLEEP_W[26] - (RW) Control register for sleep_w of group 1 +MBIST +* G1_MBIST_SLEEP_R[27] - (RW) Control register for sleep_r of group 1 +MBIST +* G2_MBIST_SLEEP_TEST[28] - (RW) Control register for sleep_test of +group +* 2 MBIST +* G2_MBIST_SLEEP_INV[29] - (RW) Control register for sleep_inv of +group +* 2 MBIST +* G2_MBIST_SLEEP_W[30] - (RW) Control register for sleep_w of group 2 +MBIST +* G2_MBIST_SLEEP_R[31] - (RW) Control register for sleep_r of group 2 +MBIST +*/ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_SLEEP_R_ADDR \ + WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_SLEEP_R_MASK \ + 0x80000000 /* G2_MBIST_SLEEP_R[31] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_SLEEP_R_SHFT 31 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_SLEEP_W_ADDR \ + WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_SLEEP_W_MASK \ + 0x40000000 /* G2_MBIST_SLEEP_W[30] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_SLEEP_W_SHFT 30 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_SLEEP_INV_ADDR \ + WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_SLEEP_INV_MASK \ + 0x20000000 /* G2_MBIST_SLEEP_INV[29] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_SLEEP_INV_SHFT 29 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_SLEEP_TEST_ADDR \ + WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_SLEEP_TEST_MASK \ + 0x10000000 /* G2_MBIST_SLEEP_TEST[28] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_SLEEP_TEST_SHFT 28 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_SLEEP_R_ADDR \ + WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_SLEEP_R_MASK \ + 0x08000000 /* G1_MBIST_SLEEP_R[27] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_SLEEP_R_SHFT 27 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_SLEEP_W_ADDR \ + WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_SLEEP_W_MASK \ + 0x04000000 /* G1_MBIST_SLEEP_W[26] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_SLEEP_W_SHFT 26 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_SLEEP_INV_ADDR \ + WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_SLEEP_INV_MASK \ + 0x02000000 /* G1_MBIST_SLEEP_INV[25] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_SLEEP_INV_SHFT 25 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_SLEEP_TEST_ADDR \ + WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_SLEEP_TEST_MASK \ + 0x01000000 /* G1_MBIST_SLEEP_TEST[24] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_SLEEP_TEST_SHFT 24 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_UMAC_MBIST_DIAG_SEL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_UMAC_MBIST_DIAG_SEL_MASK \ + 0x00100000 /* UMAC_MBIST_DIAG_SEL[20] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_UMAC_MBIST_DIAG_SEL_SHFT 20 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_MBIST_DIAG_SEL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_MBIST_DIAG_SEL_MASK \ + 0x0001F000 /* MBIST_DIAG_SEL[16..12] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_MBIST_DIAG_SEL_SHFT 12 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_USE_DEFAULT_DELSEL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_USE_DEFAULT_DELSEL_MASK \ + 0x00000800 /* G2_MBIST_USE_DEFAULT_DELSEL[11] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_USE_DEFAULT_DELSEL_SHFT 11 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_USE_DEFAULT_DELSEL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_USE_DEFAULT_DELSEL_MASK \ + 0x00000400 /* G1_MBIST_USE_DEFAULT_DELSEL[10] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_USE_DEFAULT_DELSEL_SHFT 10 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_DEBUG_ADDR \ + WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_DEBUG_MASK \ + 0x00000200 /* G2_MBIST_DEBUG[9] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_DEBUG_SHFT 9 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_DEBUG_ADDR \ + WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_DEBUG_MASK \ + 0x00000100 /* G1_MBIST_DEBUG[8] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_DEBUG_SHFT 8 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_HOLDB_ADDR \ + WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_HOLDB_MASK \ + 0x00000020 /* G2_MBIST_HOLDB[5] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_HOLDB_SHFT 5 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_HOLDB_ADDR \ + WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_HOLDB_MASK \ + 0x00000010 /* G1_MBIST_HOLDB[4] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_HOLDB_SHFT 4 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_MODE_ADDR \ + WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_MODE_MASK \ + 0x00000002 /* G2_MBIST_MODE[1] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G2_MBIST_MODE_SHFT 1 +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_MODE_ADDR \ + WF_PLE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_MODE_MASK \ + 0x00000001 /* G1_MBIST_MODE[0] */ +#define WF_PLE_TOP_SRAM_MBIST_CTRL_G1_MBIST_MODE_SHFT 0 + +/* +* ---SRAM_MBIST_DELSEL1 (0x820C0000 + 0x2e4)--- +* SRAM1_MBIST_DELSEL[31..0] - (RW) MBIST delsel setting of SRAM1 +*/ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL1_SRAM1_MBIST_DELSEL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_DELSEL1_ADDR +#define WF_PLE_TOP_SRAM_MBIST_DELSEL1_SRAM1_MBIST_DELSEL_MASK \ + 0xFFFFFFFF /* SRAM1_MBIST_DELSEL[31..0] */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL1_SRAM1_MBIST_DELSEL_SHFT 0 + +/* +* ---BSS_DBDC_CTRL (0x820C0000 + 0x2ec)--- +* BSS_BAND_SEL[15..0] - (RW) Select band of each BSS +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_BSS_DBDC_CTRL_BSS_BAND_SEL_ADDR \ + WF_PLE_TOP_BSS_DBDC_CTRL_ADDR +#define WF_PLE_TOP_BSS_DBDC_CTRL_BSS_BAND_SEL_MASK \ + 0x0000FFFF /* BSS_BAND_SEL[15..0] */ +#define WF_PLE_TOP_BSS_DBDC_CTRL_BSS_BAND_SEL_SHFT 0 + +/* +* ---SRAM_MBIST_DELSEL2 (0x820C0000 + 0x2f0)--- +* SRAM2_MBIST_DELSEL[31..0] - (RW) MBIST delsel setting of SRAM2 +*/ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL2_SRAM2_MBIST_DELSEL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_DELSEL2_ADDR +#define WF_PLE_TOP_SRAM_MBIST_DELSEL2_SRAM2_MBIST_DELSEL_MASK \ + 0xFFFFFFFF /* SRAM2_MBIST_DELSEL[31..0] */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL2_SRAM2_MBIST_DELSEL_SHFT 0 + +/* +* ---SRAM_MBIST_DELSEL3 (0x820C0000 + 0x2f4)--- +* SRAM3_MBIST_DELSEL[31..0] - (RW) MBIST delsel setting of SRAM3 +*/ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL3_SRAM3_MBIST_DELSEL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_DELSEL3_ADDR +#define WF_PLE_TOP_SRAM_MBIST_DELSEL3_SRAM3_MBIST_DELSEL_MASK \ + 0xFFFFFFFF /* SRAM3_MBIST_DELSEL[31..0] */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL3_SRAM3_MBIST_DELSEL_SHFT 0 + +/* +* ---SRAM_MBIST_DELSEL4 (0x820C0000 + 0x2f8)--- +* SRAM4_MBIST_DELSEL[31..0] - (RW) MBIST delsel setting of SRAM4 +*/ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL4_SRAM4_MBIST_DELSEL_ADDR \ + WF_PLE_TOP_SRAM_MBIST_DELSEL4_ADDR +#define WF_PLE_TOP_SRAM_MBIST_DELSEL4_SRAM4_MBIST_DELSEL_MASK \ + 0xFFFFFFFF /* SRAM4_MBIST_DELSEL[31..0] */ +#define WF_PLE_TOP_SRAM_MBIST_DELSEL4_SRAM4_MBIST_DELSEL_SHFT 0 + +/* +* ---SRAM_AWT_HDEN_CTRL (0x820C0000 + 0x2fc)--- +* SRAM_AWT_CTRL[13..0] - (RW) AWT setting of SRAMS +* RESERVED14[15..14] - (RO) Reserved bits +* SRAM_HDEN_CTRL[29..16] - (RW) HDEN setting of SRAMS +* RESERVED30[31..30] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_SRAM_AWT_HDEN_CTRL_SRAM_HDEN_CTRL_ADDR \ + WF_PLE_TOP_SRAM_AWT_HDEN_CTRL_ADDR +#define WF_PLE_TOP_SRAM_AWT_HDEN_CTRL_SRAM_HDEN_CTRL_MASK \ + 0x3FFF0000 /* SRAM_HDEN_CTRL[29..16] */ +#define WF_PLE_TOP_SRAM_AWT_HDEN_CTRL_SRAM_HDEN_CTRL_SHFT 16 +#define WF_PLE_TOP_SRAM_AWT_HDEN_CTRL_SRAM_AWT_CTRL_ADDR \ + WF_PLE_TOP_SRAM_AWT_HDEN_CTRL_ADDR +#define WF_PLE_TOP_SRAM_AWT_HDEN_CTRL_SRAM_AWT_CTRL_MASK \ + 0x00003FFF /* SRAM_AWT_CTRL[13..0] */ +#define WF_PLE_TOP_SRAM_AWT_HDEN_CTRL_SRAM_AWT_CTRL_SHFT 0 + +/* +* ---DRR_TABLE_WDATA0 (0x820C0000 + 0x340)--- +* DRR_TABLE_WDATA[31..0] - (RW) DRRwdata[31:0] for reading/writing DRR +table +* Mode 0x2?: DRR station mode +* WData[15:0]: Sta setting +* WData[127:16]: Reserved +* Mode 0x4?: BSS mode +* See SRAM layout. +* Mode 0x8?: Charge mode +* WData [15:0]: Charge length (unit: +byte) +* WData [31:16]: Charge time 9 unit +1.024us +* WData[127:32]: Reserved +*/ +#define WF_PLE_TOP_DRR_TABLE_WDATA0_DRR_TABLE_WDATA_ADDR \ + WF_PLE_TOP_DRR_TABLE_WDATA0_ADDR +#define WF_PLE_TOP_DRR_TABLE_WDATA0_DRR_TABLE_WDATA_MASK \ + 0xFFFFFFFF /* DRR_TABLE_WDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_WDATA0_DRR_TABLE_WDATA_SHFT 0 + +/* +* ---DRR_TABLE_WDATA1 (0x820C0000 + 0x344)--- +* DRR_TABLE_WDATA[31..0] - (RW) DRR wdata[63:32] for reading/writing +DRR +table +*/ +#define WF_PLE_TOP_DRR_TABLE_WDATA1_DRR_TABLE_WDATA_ADDR \ + WF_PLE_TOP_DRR_TABLE_WDATA1_ADDR +#define WF_PLE_TOP_DRR_TABLE_WDATA1_DRR_TABLE_WDATA_MASK \ + 0xFFFFFFFF /* DRR_TABLE_WDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_WDATA1_DRR_TABLE_WDATA_SHFT 0 + +/* +* ---DRR_TABLE_WDATA2 (0x820C0000 + 0x348)--- +* DRR_TABLE_WDATA[31..0] - (RW) DRR wdata[95:64] for reading/writing +DRR +table +*/ +#define WF_PLE_TOP_DRR_TABLE_WDATA2_DRR_TABLE_WDATA_ADDR \ + WF_PLE_TOP_DRR_TABLE_WDATA2_ADDR +#define WF_PLE_TOP_DRR_TABLE_WDATA2_DRR_TABLE_WDATA_MASK \ + 0xFFFFFFFF /* DRR_TABLE_WDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_WDATA2_DRR_TABLE_WDATA_SHFT 0 + +/* +* ---DRR_TABLE_WDATA3 (0x820C0000 + 0x34c)--- +* DRR_TABLE_WDATA[31..0] - (RW) DRR wdata[127:96] for reading/writing +* DRR table +*/ +#define WF_PLE_TOP_DRR_TABLE_WDATA3_DRR_TABLE_WDATA_ADDR \ + WF_PLE_TOP_DRR_TABLE_WDATA3_ADDR +#define WF_PLE_TOP_DRR_TABLE_WDATA3_DRR_TABLE_WDATA_MASK \ + 0xFFFFFFFF /* DRR_TABLE_WDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_WDATA3_DRR_TABLE_WDATA_SHFT 0 + +/* +* ---DRR_TABLE_RDATA0 (0x820C0000 + 0x350)--- +* DRR_TABLE_RDATA[31..0] - (RW) DRR rdata[31:0] for reading/writing +DRR +table +*/ +#define WF_PLE_TOP_DRR_TABLE_RDATA0_DRR_TABLE_RDATA_ADDR \ + WF_PLE_TOP_DRR_TABLE_RDATA0_ADDR +#define WF_PLE_TOP_DRR_TABLE_RDATA0_DRR_TABLE_RDATA_MASK \ + 0xFFFFFFFF /* DRR_TABLE_RDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_RDATA0_DRR_TABLE_RDATA_SHFT 0 + +/* +* ---DRR_TABLE_RDATA1 (0x820C0000 + 0x354)--- +* DRR_TABLE_RDATA[31..0] - (RW) DRR rdata[63:32] for reading/writing +DRR +table +*/ +#define WF_PLE_TOP_DRR_TABLE_RDATA1_DRR_TABLE_RDATA_ADDR \ + WF_PLE_TOP_DRR_TABLE_RDATA1_ADDR +#define WF_PLE_TOP_DRR_TABLE_RDATA1_DRR_TABLE_RDATA_MASK \ + 0xFFFFFFFF /* DRR_TABLE_RDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_RDATA1_DRR_TABLE_RDATA_SHFT 0 + +/* +* ---DRR_TABLE_RDATA2 (0x820C0000 + 0x358)--- +* DRR_TABLE_RDATA[31..0] - (RW) DRR rdata[95:64] for reading/writing +DRR +table +*/ +#define WF_PLE_TOP_DRR_TABLE_RDATA2_DRR_TABLE_RDATA_ADDR \ + WF_PLE_TOP_DRR_TABLE_RDATA2_ADDR +#define WF_PLE_TOP_DRR_TABLE_RDATA2_DRR_TABLE_RDATA_MASK \ + 0xFFFFFFFF /* DRR_TABLE_RDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_RDATA2_DRR_TABLE_RDATA_SHFT 0 + +/* +* ---DRR_TABLE_RDATA3 (0x820C0000 + 0x35c)--- +* DRR_TABLE_RDATA[31..0] - (RW) DRR rdata[127:96] for reading/writing +* DRR table +*/ +#define WF_PLE_TOP_DRR_TABLE_RDATA3_DRR_TABLE_RDATA_ADDR \ + WF_PLE_TOP_DRR_TABLE_RDATA3_ADDR +#define WF_PLE_TOP_DRR_TABLE_RDATA3_DRR_TABLE_RDATA_MASK \ + 0xFFFFFFFF /* DRR_TABLE_RDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_RDATA3_DRR_TABLE_RDATA_SHFT 0 + +/* +* ---VOW_CONTROL (0x820C0000 + 0x370)--- +* PER_BSS_BW_CONTROL_ENABLE[15..0] - (RW) BW control of BSSID +* REFILL_PERIOD[18..16] - (RW) Period of token refill function +* RESERVED19[19] - (RO) Reserved bits +* DBDC1_SEARCH_RULE[20] - (RW) Priority for HW search if internal +* collision occurs +* DBDC0_SEARCH_RULE[21] - (RW) Priority for HW search if internal +* collision occcurs +* RESERVED22[25..22] - (RO) Reserved bits +* DRR_LOGIC_RESET[26] - (RW) DRR logic reset control +* DIS_WTBL_PS_IGNORE[27] - (RW) Disable control of the function that +STA +* with WTBL PS ignore in TXQ busy +* ENABLE_TXOP_NO_CHANGE_BSS_GROUP[28] - (RW) HW cannot change BW group +* In TXOP +burst. +* ENABLE_AIRTIME_FAIRNESS[29] - (RW) When airtime function is +* disabled, HW +* will change station without checking station qouta. +* ENABLE_TOKEN_REFILL[30] - (RW) Enable control of token refill +function +* ENABLE_BW_CONTROL[31] - (RW) HW will check if there are tokens in BW +* bucket before TX. +*/ +#define WF_PLE_TOP_VOW_CONTROL_ENABLE_BW_CONTROL_ADDR \ + WF_PLE_TOP_VOW_CONTROL_ADDR +#define WF_PLE_TOP_VOW_CONTROL_ENABLE_BW_CONTROL_MASK \ + 0x80000000 /* ENABLE_BW_CONTROL[31] */ +#define WF_PLE_TOP_VOW_CONTROL_ENABLE_BW_CONTROL_SHFT 31 +#define WF_PLE_TOP_VOW_CONTROL_ENABLE_TOKEN_REFILL_ADDR \ + WF_PLE_TOP_VOW_CONTROL_ADDR +#define WF_PLE_TOP_VOW_CONTROL_ENABLE_TOKEN_REFILL_MASK \ + 0x40000000 /* ENABLE_TOKEN_REFILL[30] */ +#define WF_PLE_TOP_VOW_CONTROL_ENABLE_TOKEN_REFILL_SHFT 30 +#define WF_PLE_TOP_VOW_CONTROL_ENABLE_AIRTIME_FAIRNESS_ADDR \ + WF_PLE_TOP_VOW_CONTROL_ADDR +#define WF_PLE_TOP_VOW_CONTROL_ENABLE_AIRTIME_FAIRNESS_MASK \ + 0x20000000 /* ENABLE_AIRTIME_FAIRNESS[29] */ +#define WF_PLE_TOP_VOW_CONTROL_ENABLE_AIRTIME_FAIRNESS_SHFT 29 +#define WF_PLE_TOP_VOW_CONTROL_ENABLE_TXOP_NO_CHANGE_BSS_GROUP_ADDR \ + WF_PLE_TOP_VOW_CONTROL_ADDR +#define WF_PLE_TOP_VOW_CONTROL_ENABLE_TXOP_NO_CHANGE_BSS_GROUP_MASK \ + 0x10000000 /* ENABLE_TXOP_NO_CHANGE_BSS_GROUP[28] */ +#define WF_PLE_TOP_VOW_CONTROL_ENABLE_TXOP_NO_CHANGE_BSS_GROUP_SHFT 28 +#define WF_PLE_TOP_VOW_CONTROL_DIS_WTBL_PS_IGNORE_ADDR \ + WF_PLE_TOP_VOW_CONTROL_ADDR +#define WF_PLE_TOP_VOW_CONTROL_DIS_WTBL_PS_IGNORE_MASK \ + 0x08000000 /* DIS_WTBL_PS_IGNORE[27] */ +#define WF_PLE_TOP_VOW_CONTROL_DIS_WTBL_PS_IGNORE_SHFT 27 +#define WF_PLE_TOP_VOW_CONTROL_DRR_LOGIC_RESET_ADDR \ + WF_PLE_TOP_VOW_CONTROL_ADDR +#define WF_PLE_TOP_VOW_CONTROL_DRR_LOGIC_RESET_MASK \ + 0x04000000 /* DRR_LOGIC_RESET[26] */ +#define WF_PLE_TOP_VOW_CONTROL_DRR_LOGIC_RESET_SHFT 26 +#define WF_PLE_TOP_VOW_CONTROL_DBDC0_SEARCH_RULE_ADDR \ + WF_PLE_TOP_VOW_CONTROL_ADDR +#define WF_PLE_TOP_VOW_CONTROL_DBDC0_SEARCH_RULE_MASK \ + 0x00200000 /* DBDC0_SEARCH_RULE[21] */ +#define WF_PLE_TOP_VOW_CONTROL_DBDC0_SEARCH_RULE_SHFT 21 +#define WF_PLE_TOP_VOW_CONTROL_DBDC1_SEARCH_RULE_ADDR \ + WF_PLE_TOP_VOW_CONTROL_ADDR +#define WF_PLE_TOP_VOW_CONTROL_DBDC1_SEARCH_RULE_MASK \ + 0x00100000 /* DBDC1_SEARCH_RULE[20] */ +#define WF_PLE_TOP_VOW_CONTROL_DBDC1_SEARCH_RULE_SHFT 20 +#define WF_PLE_TOP_VOW_CONTROL_REFILL_PERIOD_ADDR \ + WF_PLE_TOP_VOW_CONTROL_ADDR +#define WF_PLE_TOP_VOW_CONTROL_REFILL_PERIOD_MASK \ + 0x00070000 /* REFILL_PERIOD[18..16] */ +#define WF_PLE_TOP_VOW_CONTROL_REFILL_PERIOD_SHFT 16 +#define WF_PLE_TOP_VOW_CONTROL_PER_BSS_BW_CONTROL_ENABLE_ADDR \ + WF_PLE_TOP_VOW_CONTROL_ADDR +#define WF_PLE_TOP_VOW_CONTROL_PER_BSS_BW_CONTROL_ENABLE_MASK \ + 0x0000FFFF /* PER_BSS_BW_CONTROL_ENABLE[15..0] */ +#define WF_PLE_TOP_VOW_CONTROL_PER_BSS_BW_CONTROL_ENABLE_SHFT 0 + +/* +* ---AIRTIME_DRR_SIZE (0x820C0000 + 0x374)--- +* AIRTIME_DEFICIT_BOUNDARY[7..0] - (RW) Limits airtime DRR's maximum +deficit +* Unit: 256us +* RESERVED2[15..8] - (RW) xxx +* BW_DEFICIT_BOUNDARY[23..16] - (RW) Limits BW DRR's maximum deficit +* Unit: 256us +* DRR_TXCNT_SIZE[31..24] - (RW) Tx count mode charge time setting +* Unit: 256us +*/ +#define WF_PLE_TOP_AIRTIME_DRR_SIZE_DRR_TXCNT_SIZE_ADDR \ + WF_PLE_TOP_AIRTIME_DRR_SIZE_ADDR +#define WF_PLE_TOP_AIRTIME_DRR_SIZE_DRR_TXCNT_SIZE_MASK \ + 0xFF000000 /* DRR_TXCNT_SIZE[31..24] */ +#define WF_PLE_TOP_AIRTIME_DRR_SIZE_DRR_TXCNT_SIZE_SHFT 24 +#define WF_PLE_TOP_AIRTIME_DRR_SIZE_BW_DEFICIT_BOUNDARY_ADDR \ + WF_PLE_TOP_AIRTIME_DRR_SIZE_ADDR +#define WF_PLE_TOP_AIRTIME_DRR_SIZE_BW_DEFICIT_BOUNDARY_MASK \ + 0x00FF0000 /* BW_DEFICIT_BOUNDARY[23..16] */ +#define WF_PLE_TOP_AIRTIME_DRR_SIZE_BW_DEFICIT_BOUNDARY_SHFT 16 +#define WF_PLE_TOP_AIRTIME_DRR_SIZE_RESERVED2_ADDR \ + WF_PLE_TOP_AIRTIME_DRR_SIZE_ADDR +#define WF_PLE_TOP_AIRTIME_DRR_SIZE_RESERVED2_MASK \ + 0x0000FF00 /* RESERVED2[15..8] */ +#define WF_PLE_TOP_AIRTIME_DRR_SIZE_RESERVED2_SHFT 8 +#define WF_PLE_TOP_AIRTIME_DRR_SIZE_AIRTIME_DEFICIT_BOUNDARY_ADDR \ + WF_PLE_TOP_AIRTIME_DRR_SIZE_ADDR +#define WF_PLE_TOP_AIRTIME_DRR_SIZE_AIRTIME_DEFICIT_BOUNDARY_MASK \ + 0x000000FF /* AIRTIME_DEFICIT_BOUNDARY[7..0] */ +#define WF_PLE_TOP_AIRTIME_DRR_SIZE_AIRTIME_DEFICIT_BOUNDARY_SHFT 0 + +/* +* ---CHECK_BW_TIME_TOKEN_ (0x820C0000 + 0x378)--- +* DISABLE_BW_TIME_CHECK[15..0] - (RW) HW will ignore time token +status. +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_CHECK_BW_TIME_TOKEN__DISABLE_BW_TIME_CHECK_ADDR \ + WF_PLE_TOP_CHECK_BW_TIME_TOKEN__ADDR +#define WF_PLE_TOP_CHECK_BW_TIME_TOKEN__DISABLE_BW_TIME_CHECK_MASK \ + 0x0000FFFF /* DISABLE_BW_TIME_CHECK[15..0] */ +#define WF_PLE_TOP_CHECK_BW_TIME_TOKEN__DISABLE_BW_TIME_CHECK_SHFT 0 + +/* +* ---CHECK_BW_LENGTH_TOKEN_ (0x820C0000 + 0x37c)--- +* DISABLE_BW_LENGTH_CHECK[15..0] - (RW) HW will ignore time token +status. +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define \ +WF_PLE_TOP_CHECK_BW_LENGTH_TOKEN__DISABLE_BW_LENGTH_CHECK_ADDR \ + WF_PLE_TOP_CHECK_BW_LENGTH_TOKEN__ADDR +#define \ +WF_PLE_TOP_CHECK_BW_LENGTH_TOKEN__DISABLE_BW_LENGTH_CHECK_MASK \ + 0x0000FFFF /* DISABLE_BW_LENGTH_CHECK[15..0] */ +#define \ +WF_PLE_TOP_CHECK_BW_LENGTH_TOKEN__DISABLE_BW_LENGTH_CHECK_SHFT \ + 0 + +/* +* ---AIRTIME_QUANTUM_SETTING0 (0x820C0000 + 0x380)--- +* AIRTIME_QUANTUM0[7..0] - (RW) Airtime quantum 0 +* AIRTIME_QUANTUM1[15..8] - (RW) Airtime quantum 1 +* AIRTIME_QUANTUM2[23..16] - (RW) Airtime quantum 2 +* AIRTIME_QUANTUM3[31..24] - (RW) Airtime quantum 3 +*/ +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_AIRTIME_QUANTUM3_ADDR \ + WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_ADDR +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_AIRTIME_QUANTUM3_MASK \ + 0xFF000000 /* AIRTIME_QUANTUM3[31..24] */ +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_AIRTIME_QUANTUM3_SHFT 24 +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_AIRTIME_QUANTUM2_ADDR \ + WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_ADDR +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_AIRTIME_QUANTUM2_MASK \ + 0x00FF0000 /* AIRTIME_QUANTUM2[23..16] */ +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_AIRTIME_QUANTUM2_SHFT 16 +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_AIRTIME_QUANTUM1_ADDR \ + WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_ADDR +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_AIRTIME_QUANTUM1_MASK \ + 0x0000FF00 /* AIRTIME_QUANTUM1[15..8] */ +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_AIRTIME_QUANTUM1_SHFT 8 +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_AIRTIME_QUANTUM0_ADDR \ + WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_ADDR +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_AIRTIME_QUANTUM0_MASK \ + 0x000000FF /* AIRTIME_QUANTUM0[7..0] */ +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING0_AIRTIME_QUANTUM0_SHFT 0 + +/* +* ---AIRTIME_QUANTUM_SETTING1 (0x820C0000 + 0x384)--- +* AIRTIME_QUANTUM4[7..0] - (RW) Airtime quantum 4 +* AIRTIME_QUANTUM5[15..8] - (RW) Airtime quantum 5 +* AIRTIME_QUANTUM6[23..16] - (RW) Airtime quantum 6 +* AIRTIME_QUANTUM7[31..24] - (RW) Airtime quantum 7 +*/ +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_AIRTIME_QUANTUM7_ADDR \ + WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_ADDR +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_AIRTIME_QUANTUM7_MASK \ + 0xFF000000 /* AIRTIME_QUANTUM7[31..24] */ +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_AIRTIME_QUANTUM7_SHFT 24 +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_AIRTIME_QUANTUM6_ADDR \ + WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_ADDR +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_AIRTIME_QUANTUM6_MASK \ + 0x00FF0000 /* AIRTIME_QUANTUM6[23..16] */ +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_AIRTIME_QUANTUM6_SHFT 16 +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_AIRTIME_QUANTUM5_ADDR \ + WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_ADDR +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_AIRTIME_QUANTUM5_MASK \ + 0x0000FF00 /* AIRTIME_QUANTUM5[15..8] */ +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_AIRTIME_QUANTUM5_SHFT 8 +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_AIRTIME_QUANTUM4_ADDR \ + WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_ADDR +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_AIRTIME_QUANTUM4_MASK \ + 0x000000FF /* AIRTIME_QUANTUM4[7..0] */ +#define WF_PLE_TOP_AIRTIME_QUANTUM_SETTING1_AIRTIME_QUANTUM4_SHFT 0 + +/* +* ---DRR_TABLE_CTRL (0x820C0000 + 0x388)--- +* INDEX[11..0] - (RW) Operation index +* Mode 0x00: DRR STA link, STA relay +* Bit[1:0]: qid +* Bit[10:2]: Station ID +//-- +* Mode 0x20: addr[6:0] mean station ID +* Mode 0x21: addr[6:0] mean station ID +* Mode 0x22: SRAM idx (debug mode) +* Mode 0x23: SRAM idx (debug mode) +* 0~35: STA bitmap +* 36~51: STA setting +//-- +* Mode 0x40: addr[3:0] = bssid, +* Mode 0x41: addr[3:0] = bssid, +* Mode 0x42: addr[3:0] = bssid, +* Mode 0x43: addr[3:0] = bssid, +* Mode 0x44: SRAM idx (debug mode) +* Mode 0x45: SRAM idx (debug mode) +* 0~15: BSS bitmap +* 16~31: BSS setting +* 32~47: Token status +//-- +* Mode 0x81~0x83: addr[3:0] = BSS group ID +* Bit[0]: Charge bw_token +* Bit[1]: Charge bw DRR +* Mode 0x84: addr[7:0] = station ID, +* addr[11:8]= qid +* Bit[2]: Charge airtime DRR +* Bit[3]: Charge is ADD mode +* WRITE_MASK[15..12] - (RW) DRR table will not be updated if mask +* write bits are enabled. +* MODE[23..16] - (RW) Operation mode for DRR table +* WRITE_MASK_2[27..24] - (RW) DRR table will not be updated if mask +* write bits are enabled. +* RESERVED28[30..28] - (RO) Reserved bits +* EXECUTE[31] - (RW) Excutes SW command to read/write DRR +table +*/ +#define WF_PLE_TOP_DRR_TABLE_CTRL_EXECUTE_ADDR \ + WF_PLE_TOP_DRR_TABLE_CTRL_ADDR +#define WF_PLE_TOP_DRR_TABLE_CTRL_EXECUTE_MASK \ + 0x80000000 /* EXECUTE[31] */ +#define WF_PLE_TOP_DRR_TABLE_CTRL_EXECUTE_SHFT 31 +#define WF_PLE_TOP_DRR_TABLE_CTRL_WRITE_MASK_2_ADDR \ + WF_PLE_TOP_DRR_TABLE_CTRL_ADDR +#define WF_PLE_TOP_DRR_TABLE_CTRL_WRITE_MASK_2_MASK \ + 0x0F000000 /* WRITE_MASK_2[27..24] */ +#define WF_PLE_TOP_DRR_TABLE_CTRL_WRITE_MASK_2_SHFT 24 +#define WF_PLE_TOP_DRR_TABLE_CTRL_MODE_ADDR \ + WF_PLE_TOP_DRR_TABLE_CTRL_ADDR +#define WF_PLE_TOP_DRR_TABLE_CTRL_MODE_MASK \ + 0x00FF0000 /* MODE[23..16] */ +#define WF_PLE_TOP_DRR_TABLE_CTRL_MODE_SHFT 16 +#define WF_PLE_TOP_DRR_TABLE_CTRL_WRITE_MASK_ADDR \ + WF_PLE_TOP_DRR_TABLE_CTRL_ADDR +#define WF_PLE_TOP_DRR_TABLE_CTRL_WRITE_MASK_MASK \ + 0x0000F000 /* WRITE_MASK[15..12] */ +#define WF_PLE_TOP_DRR_TABLE_CTRL_WRITE_MASK_SHFT 12 +#define WF_PLE_TOP_DRR_TABLE_CTRL_INDEX_ADDR \ + WF_PLE_TOP_DRR_TABLE_CTRL_ADDR +#define WF_PLE_TOP_DRR_TABLE_CTRL_INDEX_MASK \ + 0x00000FFF /* INDEX[11..0] */ +#define WF_PLE_TOP_DRR_TABLE_CTRL_INDEX_SHFT 0 + +/* +* ---VOW_CTRL1 (0x820C0000 + 0x38C)--- +* RESERVED0[0] - (RO) Reserved bits +* EN_BSSID_CHECK[1] - (RW) Enable control of check BSSID's trap +* state in search station +* EN_LOCK_STA[2] - (RW) Lock mode for RTS retry same sta until +* RTS drop +* EN_KEEP_QTM[3] - (RW) Not reset remain Tx time when sta has +* new packet +* EN_TXCNT_MODE[4] - (RW) Tx count weighted round robin control +* EN_TXED_MODE[5] - (RW) Txed bitmap control +* EN_RXSCH_MODE[6] - (RW) Rx scheduling with rx earlyend bitmap +control +* EN_BWRF_SRCH[7] - (RW) Bandwidth refill search control +* DIS_BSSID0_TRAP_IGNORE[8] - (RW) Disable control of the function +* that STA +* with BSSID0 trap ignore in TXQ busy +* DIS_BSSID1_TRAP_IGNORE[9] - (RW) Disable control of the function +* that STA +* with BSSID1 trap ignore in TXQ busy +* DIS_BSSID2_TRAP_IGNORE[10] - (RW) Disable control of the function +* that STA +* with BSSID2 trap ignore in TXQ busy +* DIS_BSSID3_TRAP_IGNORE[11] - (RW) Disable control of the function +* that STA +* with BSSID3 trap ignore in TXQ busy +* DIS_KEEP_TRGT_BSS[12] - (RW) Disable control of keeping BSS as +target +* station when SPL search +* RESERVED13[31..13] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_VOW_CTRL1_DIS_KEEP_TRGT_BSS_ADDR \ + WF_PLE_TOP_VOW_CTRL1_ADDR +#define WF_PLE_TOP_VOW_CTRL1_DIS_KEEP_TRGT_BSS_MASK \ + 0x00001000 /* DIS_KEEP_TRGT_BSS[12] */ +#define WF_PLE_TOP_VOW_CTRL1_DIS_KEEP_TRGT_BSS_SHFT 12 +#define WF_PLE_TOP_VOW_CTRL1_DIS_BSSID3_TRAP_IGNORE_ADDR \ + WF_PLE_TOP_VOW_CTRL1_ADDR +#define WF_PLE_TOP_VOW_CTRL1_DIS_BSSID3_TRAP_IGNORE_MASK \ + 0x00000800 /* DIS_BSSID3_TRAP_IGNORE[11] */ +#define WF_PLE_TOP_VOW_CTRL1_DIS_BSSID3_TRAP_IGNORE_SHFT 11 +#define WF_PLE_TOP_VOW_CTRL1_DIS_BSSID2_TRAP_IGNORE_ADDR \ + WF_PLE_TOP_VOW_CTRL1_ADDR +#define WF_PLE_TOP_VOW_CTRL1_DIS_BSSID2_TRAP_IGNORE_MASK \ + 0x00000400 /* DIS_BSSID2_TRAP_IGNORE[10] */ +#define WF_PLE_TOP_VOW_CTRL1_DIS_BSSID2_TRAP_IGNORE_SHFT 10 +#define WF_PLE_TOP_VOW_CTRL1_DIS_BSSID1_TRAP_IGNORE_ADDR \ + WF_PLE_TOP_VOW_CTRL1_ADDR +#define WF_PLE_TOP_VOW_CTRL1_DIS_BSSID1_TRAP_IGNORE_MASK \ + 0x00000200 /* DIS_BSSID1_TRAP_IGNORE[9] */ +#define WF_PLE_TOP_VOW_CTRL1_DIS_BSSID1_TRAP_IGNORE_SHFT 9 +#define WF_PLE_TOP_VOW_CTRL1_DIS_BSSID0_TRAP_IGNORE_ADDR \ + WF_PLE_TOP_VOW_CTRL1_ADDR +#define WF_PLE_TOP_VOW_CTRL1_DIS_BSSID0_TRAP_IGNORE_MASK \ + 0x00000100 /* DIS_BSSID0_TRAP_IGNORE[8] */ +#define WF_PLE_TOP_VOW_CTRL1_DIS_BSSID0_TRAP_IGNORE_SHFT 8 +#define WF_PLE_TOP_VOW_CTRL1_EN_BWRF_SRCH_ADDR \ + WF_PLE_TOP_VOW_CTRL1_ADDR +#define WF_PLE_TOP_VOW_CTRL1_EN_BWRF_SRCH_MASK \ + 0x00000080 /* EN_BWRF_SRCH[7] */ +#define WF_PLE_TOP_VOW_CTRL1_EN_BWRF_SRCH_SHFT 7 +#define WF_PLE_TOP_VOW_CTRL1_EN_RXSCH_MODE_ADDR \ + WF_PLE_TOP_VOW_CTRL1_ADDR +#define WF_PLE_TOP_VOW_CTRL1_EN_RXSCH_MODE_MASK \ + 0x00000040 /* EN_RXSCH_MODE[6] */ +#define WF_PLE_TOP_VOW_CTRL1_EN_RXSCH_MODE_SHFT 6 +#define WF_PLE_TOP_VOW_CTRL1_EN_TXED_MODE_ADDR \ + WF_PLE_TOP_VOW_CTRL1_ADDR +#define WF_PLE_TOP_VOW_CTRL1_EN_TXED_MODE_MASK \ + 0x00000020 /* EN_TXED_MODE[5] */ +#define WF_PLE_TOP_VOW_CTRL1_EN_TXED_MODE_SHFT 5 +#define WF_PLE_TOP_VOW_CTRL1_EN_TXCNT_MODE_ADDR \ + WF_PLE_TOP_VOW_CTRL1_ADDR +#define WF_PLE_TOP_VOW_CTRL1_EN_TXCNT_MODE_MASK \ + 0x00000010 /* EN_TXCNT_MODE[4] */ +#define WF_PLE_TOP_VOW_CTRL1_EN_TXCNT_MODE_SHFT 4 +#define WF_PLE_TOP_VOW_CTRL1_EN_KEEP_QTM_ADDR \ + WF_PLE_TOP_VOW_CTRL1_ADDR +#define WF_PLE_TOP_VOW_CTRL1_EN_KEEP_QTM_MASK \ + 0x00000008 /* EN_KEEP_QTM[3] */ +#define WF_PLE_TOP_VOW_CTRL1_EN_KEEP_QTM_SHFT 3 +#define WF_PLE_TOP_VOW_CTRL1_EN_LOCK_STA_ADDR \ + WF_PLE_TOP_VOW_CTRL1_ADDR +#define WF_PLE_TOP_VOW_CTRL1_EN_LOCK_STA_MASK \ + 0x00000004 /* EN_LOCK_STA[2] */ +#define WF_PLE_TOP_VOW_CTRL1_EN_LOCK_STA_SHFT 2 +#define WF_PLE_TOP_VOW_CTRL1_EN_BSSID_CHECK_ADDR \ + WF_PLE_TOP_VOW_CTRL1_ADDR +#define WF_PLE_TOP_VOW_CTRL1_EN_BSSID_CHECK_MASK \ + 0x00000002 /* EN_BSSID_CHECK[1] */ +#define WF_PLE_TOP_VOW_CTRL1_EN_BSSID_CHECK_SHFT 1 + +/* +* ---DRR_CHNL_EMPTY (0x820C0000 + 0x390)--- +* WMM_STA_DL_EMPTY[15..0] - (RO) Indicate emptiness of 16 DL station +link +* WMM_STA_UL_EMPTY[31..16] - (RO) Indicate emptiness of 16 UL station +link +*/ +#define WF_PLE_TOP_DRR_CHNL_EMPTY_WMM_STA_UL_EMPTY_ADDR \ + WF_PLE_TOP_DRR_CHNL_EMPTY_ADDR +#define WF_PLE_TOP_DRR_CHNL_EMPTY_WMM_STA_UL_EMPTY_MASK \ + 0xFFFF0000 /* WMM_STA_UL_EMPTY[31..16] */ +#define WF_PLE_TOP_DRR_CHNL_EMPTY_WMM_STA_UL_EMPTY_SHFT 16 +#define WF_PLE_TOP_DRR_CHNL_EMPTY_WMM_STA_DL_EMPTY_ADDR \ + WF_PLE_TOP_DRR_CHNL_EMPTY_ADDR +#define WF_PLE_TOP_DRR_CHNL_EMPTY_WMM_STA_DL_EMPTY_MASK \ + 0x0000FFFF /* WMM_STA_DL_EMPTY[15..0] */ +#define WF_PLE_TOP_DRR_CHNL_EMPTY_WMM_STA_DL_EMPTY_SHFT 0 + +/* +* ---DRR_SPL_CTRL (0x820C0000 + 0x394)--- +* RESERVED0[15..0] - (RO) Reserved bits +* SUBRND_TIMES[19..16] - (RW) Subround times setting to trigger round +end +* EN_SBTG_RNDEND[20] - (RW) Enable control of round ends by subround +times +* EN_QLEN_TH[21] - (RW) Enable control of queue length +* constraint to select station +* RESERVED22[31..22] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_DRR_SPL_CTRL_EN_QLEN_TH_ADDR \ + WF_PLE_TOP_DRR_SPL_CTRL_ADDR +#define WF_PLE_TOP_DRR_SPL_CTRL_EN_QLEN_TH_MASK \ + 0x00200000 /* EN_QLEN_TH[21] */ +#define WF_PLE_TOP_DRR_SPL_CTRL_EN_QLEN_TH_SHFT 21 +#define WF_PLE_TOP_DRR_SPL_CTRL_EN_SBTG_RNDEND_ADDR \ + WF_PLE_TOP_DRR_SPL_CTRL_ADDR +#define WF_PLE_TOP_DRR_SPL_CTRL_EN_SBTG_RNDEND_MASK \ + 0x00100000 /* EN_SBTG_RNDEND[20] */ +#define WF_PLE_TOP_DRR_SPL_CTRL_EN_SBTG_RNDEND_SHFT 20 +#define WF_PLE_TOP_DRR_SPL_CTRL_SUBRND_TIMES_ADDR \ + WF_PLE_TOP_DRR_SPL_CTRL_ADDR +#define WF_PLE_TOP_DRR_SPL_CTRL_SUBRND_TIMES_MASK \ + 0x000F0000 /* SUBRND_TIMES[19..16] */ +#define WF_PLE_TOP_DRR_SPL_CTRL_SUBRND_TIMES_SHFT 16 + +/* +* ---DRR_SPL_CTRL_1 (0x820C0000 + 0x398)--- +* RESERVED0[15..0] - (RO) Reserved bits +* EN_BWRF_FILTER[16] - (RW) BW refill mode SPL with NE=1 STA_CNT=0 +* filter enable control +* RESERVED17[31..17] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_DRR_SPL_CTRL_1_EN_BWRF_FILTER_ADDR \ + WF_PLE_TOP_DRR_SPL_CTRL_1_ADDR +#define WF_PLE_TOP_DRR_SPL_CTRL_1_EN_BWRF_FILTER_MASK \ + 0x00010000 /* EN_BWRF_FILTER[16] */ +#define WF_PLE_TOP_DRR_SPL_CTRL_1_EN_BWRF_FILTER_SHFT 16 + +/* +* ---VOW_DBG_SEL (0x820C0000 + 0x3A0)--- +* AIRTIME_DEBUG_SEL[15..0] - (RW) Selects airtime debug +* BW_DEBUG_SEL[31..16] - (RW) Selects BW control debug +*/ +#define WF_PLE_TOP_VOW_DBG_SEL_BW_DEBUG_SEL_ADDR \ + WF_PLE_TOP_VOW_DBG_SEL_ADDR +#define WF_PLE_TOP_VOW_DBG_SEL_BW_DEBUG_SEL_MASK \ + 0xFFFF0000 /* BW_DEBUG_SEL[31..16] */ +#define WF_PLE_TOP_VOW_DBG_SEL_BW_DEBUG_SEL_SHFT 16 +#define WF_PLE_TOP_VOW_DBG_SEL_AIRTIME_DEBUG_SEL_ADDR \ + WF_PLE_TOP_VOW_DBG_SEL_ADDR +#define WF_PLE_TOP_VOW_DBG_SEL_AIRTIME_DEBUG_SEL_MASK \ + 0x0000FFFF /* AIRTIME_DEBUG_SEL[15..0] */ +#define WF_PLE_TOP_VOW_DBG_SEL_AIRTIME_DEBUG_SEL_SHFT 0 + +/* +* ---AIRTIME_DBG_INFO0 (0x820C0000 + 0x3A4)--- +* AIRTIME_DBG_INFO0[31..0] - (RO) Station link head/tail +*/ +#define WF_PLE_TOP_AIRTIME_DBG_INFO0_AIRTIME_DBG_INFO0_ADDR \ + WF_PLE_TOP_AIRTIME_DBG_INFO0_ADDR +#define WF_PLE_TOP_AIRTIME_DBG_INFO0_AIRTIME_DBG_INFO0_MASK \ + 0xFFFFFFFF /* AIRTIME_DBG_INFO0[31..0] */ +#define WF_PLE_TOP_AIRTIME_DBG_INFO0_AIRTIME_DBG_INFO0_SHFT 0 + +/* +* ---AIRTIME_DBG_INFO1 (0x820C0000 + 0x3A8)--- +* AIRTIME_DBG_INFO1[31..0] - (RO) Station link head/tail +*/ +#define WF_PLE_TOP_AIRTIME_DBG_INFO1_AIRTIME_DBG_INFO1_ADDR \ + WF_PLE_TOP_AIRTIME_DBG_INFO1_ADDR +#define WF_PLE_TOP_AIRTIME_DBG_INFO1_AIRTIME_DBG_INFO1_MASK \ + 0xFFFFFFFF /* AIRTIME_DBG_INFO1[31..0] */ +#define WF_PLE_TOP_AIRTIME_DBG_INFO1_AIRTIME_DBG_INFO1_SHFT 0 + +/* +* ---DRR_SW_CTRL (0x820C0000 + 0x3C8)--- +* INDEX[15..0] - (RW) Operation index +* Mode 0x00: Bit[15:12]: QID, Bit[9:0]: wlan +ID +* Mode 0x01: Bit[15:12]: QID, Bit[9:0]: wlan +ID +* Mode 0x10: Bit[3:0]: QID +* Mode 0x11: Bit[3:0]: QID +* MODE[23..16] - (RW) IO software command mode +* RESERVED24[29..24] - (RO) Reserved bits +* SRCH_CMD_DROP[30] - (W1C) IO search command drop flag due to +* command FIFO full +* EXECUTE[31] - (RW) Executes SW command to trigger search +* event and add/remove station +*/ +#define WF_PLE_TOP_DRR_SW_CTRL_EXECUTE_ADDR \ + WF_PLE_TOP_DRR_SW_CTRL_ADDR +#define WF_PLE_TOP_DRR_SW_CTRL_EXECUTE_MASK \ + 0x80000000 /* EXECUTE[31] */ +#define WF_PLE_TOP_DRR_SW_CTRL_EXECUTE_SHFT 31 +#define WF_PLE_TOP_DRR_SW_CTRL_SRCH_CMD_DROP_ADDR \ + WF_PLE_TOP_DRR_SW_CTRL_ADDR +#define WF_PLE_TOP_DRR_SW_CTRL_SRCH_CMD_DROP_MASK \ + 0x40000000 /* SRCH_CMD_DROP[30] */ +#define WF_PLE_TOP_DRR_SW_CTRL_SRCH_CMD_DROP_SHFT 30 +#define WF_PLE_TOP_DRR_SW_CTRL_MODE_ADDR WF_PLE_TOP_DRR_SW_CTRL_ADDR +#define WF_PLE_TOP_DRR_SW_CTRL_MODE_MASK 0x00FF0000 /* MODE[23..16] */ +#define WF_PLE_TOP_DRR_SW_CTRL_MODE_SHFT 16 +#define WF_PLE_TOP_DRR_SW_CTRL_INDEX_ADDR WF_PLE_TOP_DRR_SW_CTRL_ADDR +#define WF_PLE_TOP_DRR_SW_CTRL_INDEX_MASK \ + 0x0000FFFF /* INDEX[15..0] */ +#define WF_PLE_TOP_DRR_SW_CTRL_INDEX_SHFT 0 + +/* +* ---DRR_HW_SRCHCMD_FULL (0x820C0000 + 0x3CC)--- +* CMD_FULL_CHNL_DL[15..0] - (RW) Hardware search command full flag of +16 +* backoff channel of downlink +* CMD_FULL_CHNL_UL[31..16] - (RW) Hardware search command full flag of +16 +* backoff channel of uplink +*/ +#define WF_PLE_TOP_DRR_HW_SRCHCMD_FULL_CMD_FULL_CHNL_UL_ADDR \ + WF_PLE_TOP_DRR_HW_SRCHCMD_FULL_ADDR +#define WF_PLE_TOP_DRR_HW_SRCHCMD_FULL_CMD_FULL_CHNL_UL_MASK \ + 0xFFFF0000 /* CMD_FULL_CHNL_UL[31..16] */ +#define WF_PLE_TOP_DRR_HW_SRCHCMD_FULL_CMD_FULL_CHNL_UL_SHFT 16 +#define WF_PLE_TOP_DRR_HW_SRCHCMD_FULL_CMD_FULL_CHNL_DL_ADDR \ + WF_PLE_TOP_DRR_HW_SRCHCMD_FULL_ADDR +#define WF_PLE_TOP_DRR_HW_SRCHCMD_FULL_CMD_FULL_CHNL_DL_MASK \ + 0x0000FFFF /* CMD_FULL_CHNL_DL[15..0] */ +#define WF_PLE_TOP_DRR_HW_SRCHCMD_FULL_CMD_FULL_CHNL_DL_SHFT 0 + +/* +* ---STATION_PAUSE0 (0x820C0000 + 0x400)--- +* STATION_PAUSE_0[31..0] - (RW) SW can stop station TX by this setting +* for STA0~STA31. +*/ +#define WF_PLE_TOP_STATION_PAUSE0_STATION_PAUSE_0_ADDR \ + WF_PLE_TOP_STATION_PAUSE0_ADDR +#define WF_PLE_TOP_STATION_PAUSE0_STATION_PAUSE_0_MASK \ + 0xFFFFFFFF /* STATION_PAUSE_0[31..0] */ +#define WF_PLE_TOP_STATION_PAUSE0_STATION_PAUSE_0_SHFT 0 + +/* +* ---DIS_STA_MAP0 (0x820C0000 + 0x440)--- +* DIS_STA_MAP_0[31..0] - (RW) Disable map for STA 0~31 TX +*/ +#define WF_PLE_TOP_DIS_STA_MAP0_DIS_STA_MAP_0_ADDR \ + WF_PLE_TOP_DIS_STA_MAP0_ADDR +#define WF_PLE_TOP_DIS_STA_MAP0_DIS_STA_MAP_0_MASK \ + 0xFFFFFFFF /* DIS_STA_MAP_0[31..0] */ +#define WF_PLE_TOP_DIS_STA_MAP0_DIS_STA_MAP_0_SHFT 0 + +/* +* ---STATION_REDIR0 (0x820C0000 + 0x480)--- +* STATION_REDIR_0[31..0] - (RW) SW can redirection to designed +* port/queue by this setting for STA0~STA31. +*/ +#define WF_PLE_TOP_STATION_REDIR0_STATION_REDIR_0_ADDR \ + WF_PLE_TOP_STATION_REDIR0_ADDR +#define WF_PLE_TOP_STATION_REDIR0_STATION_REDIR_0_MASK \ + 0xFFFFFFFF /* STATION_REDIR_0[31..0] */ +#define WF_PLE_TOP_STATION_REDIR0_STATION_REDIR_0_SHFT 0 + +/* +* ---TWT_STA_MAP0 (0x820C0000 + 0x4c0)--- +* TWT_STA_MAP_0[31..0] - (RW) TWT map for STA 0~31 TX +*/ +#define WF_PLE_TOP_TWT_STA_MAP0_TWT_STA_MAP_0_ADDR \ + WF_PLE_TOP_TWT_STA_MAP0_ADDR +#define WF_PLE_TOP_TWT_STA_MAP0_TWT_STA_MAP_0_MASK \ + 0xFFFFFFFF /* TWT_STA_MAP_0[31..0] */ +#define WF_PLE_TOP_TWT_STA_MAP0_TWT_STA_MAP_0_SHFT 0 + +/* +* ---AC0_QUEUE_EMPTY0 (0x820C0000 + 0x500)--- +* AC0_QUEUE_EMPTY_0[31..0] - (RO) Empty flag for STA 0~31 AC0 queue +*/ +#define WF_PLE_TOP_AC0_QUEUE_EMPTY0_AC0_QUEUE_EMPTY_0_ADDR \ + WF_PLE_TOP_AC0_QUEUE_EMPTY0_ADDR +#define WF_PLE_TOP_AC0_QUEUE_EMPTY0_AC0_QUEUE_EMPTY_0_MASK \ + 0xFFFFFFFF /* AC0_QUEUE_EMPTY_0[31..0] */ +#define WF_PLE_TOP_AC0_QUEUE_EMPTY0_AC0_QUEUE_EMPTY_0_SHFT 0 + +/* +* ---AC1_QUEUE_EMPTY0 (0x820C0000 + 0x540)--- +* AC1_QUEUE_EMPTY_0[31..0] - (RO) Empty flag for STA 0~31 AC1 queue +*/ +#define WF_PLE_TOP_AC1_QUEUE_EMPTY0_AC1_QUEUE_EMPTY_0_ADDR \ + WF_PLE_TOP_AC1_QUEUE_EMPTY0_ADDR +#define WF_PLE_TOP_AC1_QUEUE_EMPTY0_AC1_QUEUE_EMPTY_0_MASK \ + 0xFFFFFFFF /* AC1_QUEUE_EMPTY_0[31..0] */ +#define WF_PLE_TOP_AC1_QUEUE_EMPTY0_AC1_QUEUE_EMPTY_0_SHFT 0 + +/* +* ---AC2_QUEUE_EMPTY0 (0x820C0000 + 0x580)--- +* AC2_QUEUE_EMPTY_0[31..0] - (RO) Empty flag for STA 0~31 AC2 queue +*/ +#define WF_PLE_TOP_AC2_QUEUE_EMPTY0_AC2_QUEUE_EMPTY_0_ADDR \ + WF_PLE_TOP_AC2_QUEUE_EMPTY0_ADDR +#define WF_PLE_TOP_AC2_QUEUE_EMPTY0_AC2_QUEUE_EMPTY_0_MASK \ + 0xFFFFFFFF /* AC2_QUEUE_EMPTY_0[31..0] */ +#define WF_PLE_TOP_AC2_QUEUE_EMPTY0_AC2_QUEUE_EMPTY_0_SHFT 0 + +/* +* ---AC3_QUEUE_EMPTY0 (0x820C0000 + 0x5c0)--- +* AC3_QUEUE_EMPTY_0[31..0] - (RO) Empty flag for STA 0~31 AC3 queue +*/ +#define WF_PLE_TOP_AC3_QUEUE_EMPTY0_AC3_QUEUE_EMPTY_0_ADDR \ + WF_PLE_TOP_AC3_QUEUE_EMPTY0_ADDR +#define WF_PLE_TOP_AC3_QUEUE_EMPTY0_AC3_QUEUE_EMPTY_0_MASK \ + 0xFFFFFFFF /* AC3_QUEUE_EMPTY_0[31..0] */ +#define WF_PLE_TOP_AC3_QUEUE_EMPTY0_AC3_QUEUE_EMPTY_0_SHFT 0 + +/* +* ---DRR_TABLE_WDATA4 (0x820C0000 + 0x680)--- +* DRR_TABLE_WDATA[31..0] - (RW) DRRwdata[159:128] for reading/writing +* DRR table +* Mode 0x4?: BSS mode +* See SRAM layout. +*/ +#define WF_PLE_TOP_DRR_TABLE_WDATA4_DRR_TABLE_WDATA_ADDR \ + WF_PLE_TOP_DRR_TABLE_WDATA4_ADDR +#define WF_PLE_TOP_DRR_TABLE_WDATA4_DRR_TABLE_WDATA_MASK \ + 0xFFFFFFFF /* DRR_TABLE_WDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_WDATA4_DRR_TABLE_WDATA_SHFT 0 + +/* +* ---DRR_TABLE_WDATA5 (0x820C0000 + 0x684)--- +* DRR_TABLE_WDATA[31..0] - (RW) DRR wdata[191:160] for reading/writing +* DRR table +*/ +#define WF_PLE_TOP_DRR_TABLE_WDATA5_DRR_TABLE_WDATA_ADDR \ + WF_PLE_TOP_DRR_TABLE_WDATA5_ADDR +#define WF_PLE_TOP_DRR_TABLE_WDATA5_DRR_TABLE_WDATA_MASK \ + 0xFFFFFFFF /* DRR_TABLE_WDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_WDATA5_DRR_TABLE_WDATA_SHFT 0 + +/* +* ---DRR_TABLE_WDATA6 (0x820C0000 + 0x688)--- +* DRR_TABLE_WDATA[31..0] - (RW) DRR wdata[223:192] for reading/writing +* DRR table +*/ +#define WF_PLE_TOP_DRR_TABLE_WDATA6_DRR_TABLE_WDATA_ADDR \ + WF_PLE_TOP_DRR_TABLE_WDATA6_ADDR +#define WF_PLE_TOP_DRR_TABLE_WDATA6_DRR_TABLE_WDATA_MASK \ + 0xFFFFFFFF /* DRR_TABLE_WDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_WDATA6_DRR_TABLE_WDATA_SHFT 0 + +/* +* ---DRR_TABLE_WDATA7 (0x820C0000 + 0x68c)--- +* DRR_TABLE_WDATA[31..0] - (RW) DRR wdata[255:224] for reading/writing +* DRR table +*/ +#define WF_PLE_TOP_DRR_TABLE_WDATA7_DRR_TABLE_WDATA_ADDR \ + WF_PLE_TOP_DRR_TABLE_WDATA7_ADDR +#define WF_PLE_TOP_DRR_TABLE_WDATA7_DRR_TABLE_WDATA_MASK \ + 0xFFFFFFFF /* DRR_TABLE_WDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_WDATA7_DRR_TABLE_WDATA_SHFT 0 + +/* +* ---DRR_TABLE_RDATA4 (0x820C0000 + 0x690)--- +* DRR_TABLE_RDATA[31..0] - (RW) DRR rdata[159:128] for reading/writing +* DRR table +*/ +#define WF_PLE_TOP_DRR_TABLE_RDATA4_DRR_TABLE_RDATA_ADDR \ + WF_PLE_TOP_DRR_TABLE_RDATA4_ADDR +#define WF_PLE_TOP_DRR_TABLE_RDATA4_DRR_TABLE_RDATA_MASK \ + 0xFFFFFFFF /* DRR_TABLE_RDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_RDATA4_DRR_TABLE_RDATA_SHFT 0 + +/* +* ---DRR_TABLE_RDATA5 (0x820C0000 + 0x694)--- +* DRR_TABLE_RDATA[31..0] - (RW) DRR rdata[191:160] for reading/writing +* DRR table +*/ +#define WF_PLE_TOP_DRR_TABLE_RDATA5_DRR_TABLE_RDATA_ADDR \ + WF_PLE_TOP_DRR_TABLE_RDATA5_ADDR +#define WF_PLE_TOP_DRR_TABLE_RDATA5_DRR_TABLE_RDATA_MASK \ + 0xFFFFFFFF /* DRR_TABLE_RDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_RDATA5_DRR_TABLE_RDATA_SHFT 0 + +/* +* ---DRR_TABLE_RDATA6 (0x820C0000 + 0x698)--- +* DRR_TABLE_RDATA[31..0] - (RW) DRR rdata[223:192] for reading/writing +* DRR table +*/ +#define WF_PLE_TOP_DRR_TABLE_RDATA6_DRR_TABLE_RDATA_ADDR \ + WF_PLE_TOP_DRR_TABLE_RDATA6_ADDR +#define WF_PLE_TOP_DRR_TABLE_RDATA6_DRR_TABLE_RDATA_MASK \ + 0xFFFFFFFF /* DRR_TABLE_RDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_RDATA6_DRR_TABLE_RDATA_SHFT 0 + +/* +* ---DRR_TABLE_RDATA7 (0x820C0000 + 0x69c)--- +* DRR_TABLE_RDATA[31..0] - (RW) DRR rdata[255:224] for reading/writing +* DRR table +*/ +#define WF_PLE_TOP_DRR_TABLE_RDATA7_DRR_TABLE_RDATA_ADDR \ + WF_PLE_TOP_DRR_TABLE_RDATA7_ADDR +#define WF_PLE_TOP_DRR_TABLE_RDATA7_DRR_TABLE_RDATA_MASK \ + 0xFFFFFFFF /* DRR_TABLE_RDATA[31..0] */ +#define WF_PLE_TOP_DRR_TABLE_RDATA7_DRR_TABLE_RDATA_SHFT 0 + +/* +* ---TWT_STA_TABLE0 (0x820C0000 + 0x6a0)--- +* TWT_STA_0[9..0] - (RW) TWT station 0 WLAN ID +* RESERVED10[15..10] - (RO) Reserved bits +* TWT_STA_1[25..16] - (RW) TWT station 1 WLAN ID +* RESERVED26[31..26] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_TWT_STA_TABLE0_TWT_STA_1_ADDR \ + WF_PLE_TOP_TWT_STA_TABLE0_ADDR +#define WF_PLE_TOP_TWT_STA_TABLE0_TWT_STA_1_MASK \ + 0x03FF0000 /* TWT_STA_1[25..16] */ +#define WF_PLE_TOP_TWT_STA_TABLE0_TWT_STA_1_SHFT 16 +#define WF_PLE_TOP_TWT_STA_TABLE0_TWT_STA_0_ADDR \ + WF_PLE_TOP_TWT_STA_TABLE0_ADDR +#define WF_PLE_TOP_TWT_STA_TABLE0_TWT_STA_0_MASK \ + 0x000003FF /* TWT_STA_0[9..0] */ +#define WF_PLE_TOP_TWT_STA_TABLE0_TWT_STA_0_SHFT 0 + +/* +* ---TWT_STA_TABLE1 (0x820C0000 + 0x6a4)--- +* TWT_STA_2[9..0] - (RW) TWT station 2 WLAN ID +* RESERVED10[15..10] - (RO) Reserved bits +* TWT_STA_3[25..16] - (RW) TWT station 3 WLAN ID +* RESERVED26[31..26] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_TWT_STA_TABLE1_TWT_STA_3_ADDR \ + WF_PLE_TOP_TWT_STA_TABLE1_ADDR +#define WF_PLE_TOP_TWT_STA_TABLE1_TWT_STA_3_MASK \ + 0x03FF0000 /* TWT_STA_3[25..16] */ +#define WF_PLE_TOP_TWT_STA_TABLE1_TWT_STA_3_SHFT 16 +#define WF_PLE_TOP_TWT_STA_TABLE1_TWT_STA_2_ADDR \ + WF_PLE_TOP_TWT_STA_TABLE1_ADDR +#define WF_PLE_TOP_TWT_STA_TABLE1_TWT_STA_2_MASK \ + 0x000003FF /* TWT_STA_2[9..0] */ +#define WF_PLE_TOP_TWT_STA_TABLE1_TWT_STA_2_SHFT 0 + +/* +* ---TWT_STA_TABLE2 (0x820C0000 + 0x6a8)--- +* TWT_STA_4[9..0] - (RW) TWT station 4 WLAN ID +* RESERVED10[15..10] - (RO) Reserved bits +* TWT_STA_5[25..16] - (RW) TWT station 5 WLAN ID +* RESERVED26[31..26] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_TWT_STA_TABLE2_TWT_STA_5_ADDR \ + WF_PLE_TOP_TWT_STA_TABLE2_ADDR +#define WF_PLE_TOP_TWT_STA_TABLE2_TWT_STA_5_MASK \ + 0x03FF0000 /* TWT_STA_5[25..16] */ +#define WF_PLE_TOP_TWT_STA_TABLE2_TWT_STA_5_SHFT 16 +#define WF_PLE_TOP_TWT_STA_TABLE2_TWT_STA_4_ADDR \ + WF_PLE_TOP_TWT_STA_TABLE2_ADDR +#define WF_PLE_TOP_TWT_STA_TABLE2_TWT_STA_4_MASK \ + 0x000003FF /* TWT_STA_4[9..0] */ +#define WF_PLE_TOP_TWT_STA_TABLE2_TWT_STA_4_SHFT 0 + +/* +* ---TWT_STA_TABLE3 (0x820C0000 + 0x6ac)--- +* TWT_STA_6[9..0] - (RW) TWT station 6 WLAN ID +* RESERVED10[15..10] - (RO) Reserved bits +* TWT_STA_7[25..16] - (RW) TWT station 7 WLAN ID +* RESERVED26[31..26] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_TWT_STA_TABLE3_TWT_STA_7_ADDR \ + WF_PLE_TOP_TWT_STA_TABLE3_ADDR +#define WF_PLE_TOP_TWT_STA_TABLE3_TWT_STA_7_MASK \ + 0x03FF0000 /* TWT_STA_7[25..16] */ +#define WF_PLE_TOP_TWT_STA_TABLE3_TWT_STA_7_SHFT 16 +#define WF_PLE_TOP_TWT_STA_TABLE3_TWT_STA_6_ADDR \ + WF_PLE_TOP_TWT_STA_TABLE3_ADDR +#define WF_PLE_TOP_TWT_STA_TABLE3_TWT_STA_6_MASK \ + 0x000003FF /* TWT_STA_6[9..0] */ +#define WF_PLE_TOP_TWT_STA_TABLE3_TWT_STA_6_SHFT 0 + +/* +* ---TWT_SW_CTRL (0x820C0000 + 0x6b0)--- +* INDEX[15..0] - (RW) Operation index +* Mode 0x00/0x01/0x08/0x09: Bit[3:0]: station +number +* Mode 0x10/0x11: Bit[3:0]: table index +* MODE[23..16] - (RW) IO software command mode +* RESERVED24[29..24] - (RO) Reserved bits +* SRCH_CMD_DROP[30] - (W1C) IO search command drop flag due to +* command FIFO full +* EXECUTE[31] - (RW) Executes SW command to trigger TWT +* search event and add/remove TWT station +*/ +#define WF_PLE_TOP_TWT_SW_CTRL_EXECUTE_ADDR \ + WF_PLE_TOP_TWT_SW_CTRL_ADDR +#define WF_PLE_TOP_TWT_SW_CTRL_EXECUTE_MASK \ + 0x80000000 /* EXECUTE[31] */ +#define WF_PLE_TOP_TWT_SW_CTRL_EXECUTE_SHFT 31 +#define WF_PLE_TOP_TWT_SW_CTRL_SRCH_CMD_DROP_ADDR \ + WF_PLE_TOP_TWT_SW_CTRL_ADDR +#define WF_PLE_TOP_TWT_SW_CTRL_SRCH_CMD_DROP_MASK \ + 0x40000000 /* SRCH_CMD_DROP[30] */ +#define WF_PLE_TOP_TWT_SW_CTRL_SRCH_CMD_DROP_SHFT 30 +#define WF_PLE_TOP_TWT_SW_CTRL_MODE_ADDR WF_PLE_TOP_TWT_SW_CTRL_ADDR +#define WF_PLE_TOP_TWT_SW_CTRL_MODE_MASK 0x00FF0000 /* MODE[23..16] */ +#define WF_PLE_TOP_TWT_SW_CTRL_MODE_SHFT 16 +#define WF_PLE_TOP_TWT_SW_CTRL_INDEX_ADDR WF_PLE_TOP_TWT_SW_CTRL_ADDR +#define WF_PLE_TOP_TWT_SW_CTRL_INDEX_MASK \ + 0x0000FFFF /* INDEX[15..0] */ +#define WF_PLE_TOP_TWT_SW_CTRL_INDEX_SHFT 0 + +/* +* ---TWT_DBG (0x820C0000 + 0x6b4)--- +* TABLE_IDX_SEL[2..0] - (RW) Station index selection +* UL_TABLE_SEL[3] - (RW) Downlink/uplink station table selection +* RESERVED4[15..4] - (RO) Reserved bits +* TABLE_WLAN_ID[25..16] - (RO) Station WLAN ID in station table +* RESERVED26[27..26] - (RO) Reserved bits +* STA_CNT[31..28] - (RO) Valid station count in station table +*/ +#define WF_PLE_TOP_TWT_DBG_STA_CNT_ADDR WF_PLE_TOP_TWT_DBG_ADDR +#define WF_PLE_TOP_TWT_DBG_STA_CNT_MASK \ + 0xF0000000 /* STA_CNT[31..28] */ +#define WF_PLE_TOP_TWT_DBG_STA_CNT_SHFT 28 +#define WF_PLE_TOP_TWT_DBG_TABLE_WLAN_ID_ADDR WF_PLE_TOP_TWT_DBG_ADDR +#define WF_PLE_TOP_TWT_DBG_TABLE_WLAN_ID_MASK \ + 0x03FF0000 /* TABLE_WLAN_ID[25..16] */ +#define WF_PLE_TOP_TWT_DBG_TABLE_WLAN_ID_SHFT 16 +#define WF_PLE_TOP_TWT_DBG_UL_TABLE_SEL_ADDR WF_PLE_TOP_TWT_DBG_ADDR +#define WF_PLE_TOP_TWT_DBG_UL_TABLE_SEL_MASK \ + 0x00000008 /* UL_TABLE_SEL[3] */ +#define WF_PLE_TOP_TWT_DBG_UL_TABLE_SEL_SHFT 3 +#define WF_PLE_TOP_TWT_DBG_TABLE_IDX_SEL_ADDR WF_PLE_TOP_TWT_DBG_ADDR +#define WF_PLE_TOP_TWT_DBG_TABLE_IDX_SEL_MASK \ + 0x00000007 /* TABLE_IDX_SEL[2..0] */ +#define WF_PLE_TOP_TWT_DBG_TABLE_IDX_SEL_SHFT 0 + +/* +* ---TWT_HW_SRCHCMD_FULL (0x820C0000 + 0x6b8)--- +* TWT_SRCH_DL_FULL[0] - (RW) TWT hardware downlink search command +* full flag +* TWT_SRCH_UL_FULL[1] - (RW) TWT hardware uplink search command full +flag +* RESERVED2[31..2] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_TWT_HW_SRCHCMD_FULL_TWT_SRCH_UL_FULL_ADDR \ + WF_PLE_TOP_TWT_HW_SRCHCMD_FULL_ADDR +#define WF_PLE_TOP_TWT_HW_SRCHCMD_FULL_TWT_SRCH_UL_FULL_MASK \ + 0x00000002 /* TWT_SRCH_UL_FULL[1] */ +#define WF_PLE_TOP_TWT_HW_SRCHCMD_FULL_TWT_SRCH_UL_FULL_SHFT 1 +#define WF_PLE_TOP_TWT_HW_SRCHCMD_FULL_TWT_SRCH_DL_FULL_ADDR \ + WF_PLE_TOP_TWT_HW_SRCHCMD_FULL_ADDR +#define WF_PLE_TOP_TWT_HW_SRCHCMD_FULL_TWT_SRCH_DL_FULL_MASK \ + 0x00000001 /* TWT_SRCH_DL_FULL[0] */ +#define WF_PLE_TOP_TWT_HW_SRCHCMD_FULL_TWT_SRCH_DL_FULL_SHFT 0 + +/* +* ---AMSDU_GC (0x820C0000 + 0x1000)--- +* EN_HW_AMSDU[0] - (RW) Enable control of HW AMSDU function. +* RESERVED1[7..1] - (RO) Reserved bits +* DIS_AMSDU_Q_EMPTY_FLUSH[8] - (RW) Disable control of HW AMSDU queue +empty +* trigger packet flush function. +* DIS_LMAC_TX_NO_FULL_FLUSH[9] - (RW) Disable control of LMAC TX no +* get full +* packet trigger packet flush function. +* DIS_SFD_KEEP_SAME_PAGE[10] - (RW) Disable control of keep same page +number +* of StoreForward packet function. +* RESERVED11[31..11] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_AMSDU_GC_DIS_SFD_KEEP_SAME_PAGE_ADDR \ + WF_PLE_TOP_AMSDU_GC_ADDR +#define WF_PLE_TOP_AMSDU_GC_DIS_SFD_KEEP_SAME_PAGE_MASK \ + 0x00000400 /* DIS_SFD_KEEP_SAME_PAGE[10] */ +#define WF_PLE_TOP_AMSDU_GC_DIS_SFD_KEEP_SAME_PAGE_SHFT 10 +#define WF_PLE_TOP_AMSDU_GC_DIS_LMAC_TX_NO_FULL_FLUSH_ADDR \ + WF_PLE_TOP_AMSDU_GC_ADDR +#define WF_PLE_TOP_AMSDU_GC_DIS_LMAC_TX_NO_FULL_FLUSH_MASK \ + 0x00000200 /* DIS_LMAC_TX_NO_FULL_FLUSH[9] */ +#define WF_PLE_TOP_AMSDU_GC_DIS_LMAC_TX_NO_FULL_FLUSH_SHFT 9 +#define WF_PLE_TOP_AMSDU_GC_DIS_AMSDU_Q_EMPTY_FLUSH_ADDR \ + WF_PLE_TOP_AMSDU_GC_ADDR +#define WF_PLE_TOP_AMSDU_GC_DIS_AMSDU_Q_EMPTY_FLUSH_MASK \ + 0x00000100 /* DIS_AMSDU_Q_EMPTY_FLUSH[8] */ +#define WF_PLE_TOP_AMSDU_GC_DIS_AMSDU_Q_EMPTY_FLUSH_SHFT 8 +#define WF_PLE_TOP_AMSDU_GC_EN_HW_AMSDU_ADDR WF_PLE_TOP_AMSDU_GC_ADDR +#define WF_PLE_TOP_AMSDU_GC_EN_HW_AMSDU_MASK \ + 0x00000001 /* EN_HW_AMSDU[0] */ +#define WF_PLE_TOP_AMSDU_GC_EN_HW_AMSDU_SHFT 0 + +/* +* ---AMSDU_TXD_COMP_MAP_0 (0x820C0000 + 0x1004)--- +* TXDIN_TRIGGER_TH[11..0] - (RW) The TXD merge trigger threshold. +* RESERVED12[15..12] - (RO) Reserved bits +* TXD_COMPARE_NEED_MAP[31..16] - (RW) The compare bitmap for merging +TXD. +*/ +#define WF_PLE_TOP_AMSDU_TXD_COMP_MAP_0_TXD_COMPARE_NEED_MAP_ADDR \ + WF_PLE_TOP_AMSDU_TXD_COMP_MAP_0_ADDR +#define WF_PLE_TOP_AMSDU_TXD_COMP_MAP_0_TXD_COMPARE_NEED_MAP_MASK \ + 0xFFFF0000 /* TXD_COMPARE_NEED_MAP[31..16] */ +#define WF_PLE_TOP_AMSDU_TXD_COMP_MAP_0_TXD_COMPARE_NEED_MAP_SHFT 16 +#define WF_PLE_TOP_AMSDU_TXD_COMP_MAP_0_TXDIN_TRIGGER_TH_ADDR \ + WF_PLE_TOP_AMSDU_TXD_COMP_MAP_0_ADDR +#define WF_PLE_TOP_AMSDU_TXD_COMP_MAP_0_TXDIN_TRIGGER_TH_MASK \ + 0x00000FFF /* TXDIN_TRIGGER_TH[11..0] */ +#define WF_PLE_TOP_AMSDU_TXD_COMP_MAP_0_TXDIN_TRIGGER_TH_SHFT 0 + +/* +* ---AMSDU_TXD_COMP_MAP_1 (0x820C0000 + 0x1008)--- +* TXD_COMPARE_NEED_MAP[31..0] - (RW) The compare bitmap for merging +TXD. +*/ +#define WF_PLE_TOP_AMSDU_TXD_COMP_MAP_1_TXD_COMPARE_NEED_MAP_ADDR \ + WF_PLE_TOP_AMSDU_TXD_COMP_MAP_1_ADDR +#define WF_PLE_TOP_AMSDU_TXD_COMP_MAP_1_TXD_COMPARE_NEED_MAP_MASK \ + 0xFFFFFFFF /* TXD_COMPARE_NEED_MAP[31..0] */ +#define WF_PLE_TOP_AMSDU_TXD_COMP_MAP_1_TXD_COMPARE_NEED_MAP_SHFT 0 + +/* +* ---AMSDU_INT_N9_ERR_STS (0x820C0000 + 0x1028)--- +* AMSDU_Q_CMD_ERR[0] - (W1C) Queue command error interrupt status of +* port AMSDU. Avoid unclear error flag, please clear flag when logic +reset. +* RESERVED1[3..1] - (RO) Reserved bits +* AMSDU_PAGE_UDF[4] - (W1C) Page underflow interrupt status of port +* AMSDU. Avoid unclear error flag, please clear flag when logic reset. +* RESERVED5[11..5] - (RO) Reserved bits +* AMSDU_DATA_OPER_ERR[12] - (W1C) Data operation error of port AMSDU. +* Avoid unclear error flag, please clear flag when logic reset. +* RESERVED13[15..13] - (RO) Reserved bits +* AMSDU_PORT_HANG_ERR[16] - (W1C) AMSDU port FSM hang error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* AMSDU_CTRL_HANG_ERR[17] - (W1C) AMSDU FSM hang error interrupt. +Avoid +* unclear error flag, please clear flag when logic reset. +* RESERVED18[31..18] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_CTRL_HANG_ERR_ADDR \ + WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_CTRL_HANG_ERR_MASK \ + 0x00020000 /* AMSDU_CTRL_HANG_ERR[17] */ +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_CTRL_HANG_ERR_SHFT 17 +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_PORT_HANG_ERR_ADDR \ + WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_PORT_HANG_ERR_MASK \ + 0x00010000 /* AMSDU_PORT_HANG_ERR[16] */ +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_PORT_HANG_ERR_SHFT 16 +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_DATA_OPER_ERR_ADDR \ + WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_DATA_OPER_ERR_MASK \ + 0x00001000 /* AMSDU_DATA_OPER_ERR[12] */ +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_DATA_OPER_ERR_SHFT 12 +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_PAGE_UDF_ADDR \ + WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_PAGE_UDF_MASK \ + 0x00000010 /* AMSDU_PAGE_UDF[4] */ +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_PAGE_UDF_SHFT 4 +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_Q_CMD_ERR_ADDR \ + WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_ADDR +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_Q_CMD_ERR_MASK \ + 0x00000001 /* AMSDU_Q_CMD_ERR[0] */ +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_STS_AMSDU_Q_CMD_ERR_SHFT 0 + +/* +* ---AMSDU_INT_N9_ERR_MASK (0x820C0000 + 0x102C)--- +* EN_AMSDU_Q_CMD_ERR[0] - (RW) Enables queue command error interrupt +* status of port AMSDU +* RESERVED1[3..1] - (RO) Reserved bits +* EN_AMSDU_PAGE_UDF[4] - (RW) Enables page underflow interrupt status +* of port AMSDU +* RESERVED5[11..5] - (RO) Reserved bits +* EN_AMSDU_DATA_OPER_ERR[12] - (RW) Enables data operation error of +port +AMSDU +* RESERVED13[15..13] - (RO) Reserved bits +* EN_AMSDU_PORT_HANG_ERR[16] - (RW) Enables AMSDU port FSM hang error +interrupt +* EN_AMSDU_CTRL_HANG_ERR[17] - (RW) Enables AMSDU CTRL FSM hang error +interrupt +* RESERVED18[31..18] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_CTRL_HANG_ERR_ADDR \ + WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_CTRL_HANG_ERR_MASK \ + 0x00020000 /* EN_AMSDU_CTRL_HANG_ERR[17] */ +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_CTRL_HANG_ERR_SHFT \ + 17 +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_PORT_HANG_ERR_ADDR \ + WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_PORT_HANG_ERR_MASK \ + 0x00010000 /* EN_AMSDU_PORT_HANG_ERR[16] */ +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_PORT_HANG_ERR_SHFT \ + 16 +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_DATA_OPER_ERR_ADDR \ + WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_DATA_OPER_ERR_MASK \ + 0x00001000 /* EN_AMSDU_DATA_OPER_ERR[12] */ +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_DATA_OPER_ERR_SHFT \ + 12 +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_PAGE_UDF_ADDR \ + WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_PAGE_UDF_MASK \ + 0x00000010 /* EN_AMSDU_PAGE_UDF[4] */ +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_PAGE_UDF_SHFT 4 +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_Q_CMD_ERR_ADDR \ + WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_ADDR +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_Q_CMD_ERR_MASK \ + 0x00000001 /* EN_AMSDU_Q_CMD_ERR[0] */ +#define WF_PLE_TOP_AMSDU_INT_N9_ERR_MASK_EN_AMSDU_Q_CMD_ERR_SHFT 0 + +/* +* ---AMSDU_PEEK_CR_00 (0x820C0000 + 0x10d0)--- +* AMSDU_DOP_CS[3..0] - (RO) AMSDU Data operation current state. +* RESERVED4[7..4] - (RO) Reserved bits +* AMSDU_CS[12..8] - (RO) AMSDU Merge Engine current state. +* RESERVED13[15..13] - (RO) Reserved bits +* AMSDU_Q_EMPTY_CS[17..16] - (RO) AMSDU Queue Empty Search Engine +current +state. +* RESERVED18[23..18] - (RO) Reserved bits +* AMSDU_ARB_CS[26..24] - (RO) AMSDU Request Arbitration Current state. +* RESERVED27[31..27] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_AMSDU_PEEK_CR_00_AMSDU_ARB_CS_ADDR \ + WF_PLE_TOP_AMSDU_PEEK_CR_00_ADDR +#define WF_PLE_TOP_AMSDU_PEEK_CR_00_AMSDU_ARB_CS_MASK \ + 0x07000000 /* AMSDU_ARB_CS[26..24] */ +#define WF_PLE_TOP_AMSDU_PEEK_CR_00_AMSDU_ARB_CS_SHFT 24 +#define WF_PLE_TOP_AMSDU_PEEK_CR_00_AMSDU_Q_EMPTY_CS_ADDR \ + WF_PLE_TOP_AMSDU_PEEK_CR_00_ADDR +#define WF_PLE_TOP_AMSDU_PEEK_CR_00_AMSDU_Q_EMPTY_CS_MASK \ + 0x00030000 /* AMSDU_Q_EMPTY_CS[17..16] */ +#define WF_PLE_TOP_AMSDU_PEEK_CR_00_AMSDU_Q_EMPTY_CS_SHFT 16 +#define WF_PLE_TOP_AMSDU_PEEK_CR_00_AMSDU_CS_ADDR \ + WF_PLE_TOP_AMSDU_PEEK_CR_00_ADDR +#define WF_PLE_TOP_AMSDU_PEEK_CR_00_AMSDU_CS_MASK \ + 0x00001F00 /* AMSDU_CS[12..8] */ +#define WF_PLE_TOP_AMSDU_PEEK_CR_00_AMSDU_CS_SHFT 8 +#define WF_PLE_TOP_AMSDU_PEEK_CR_00_AMSDU_DOP_CS_ADDR \ + WF_PLE_TOP_AMSDU_PEEK_CR_00_ADDR +#define WF_PLE_TOP_AMSDU_PEEK_CR_00_AMSDU_DOP_CS_MASK \ + 0x0000000F /* AMSDU_DOP_CS[3..0] */ +#define WF_PLE_TOP_AMSDU_PEEK_CR_00_AMSDU_DOP_CS_SHFT 0 + +/* +* ---AMSDU_PEEK_CR_01 (0x820C0000 + 0x10d4)--- +* AMSDU_DOP_PBUF_CS[2..0] - (RO) PLE AMSDU port - Data operation PBUF +* current state. +* RESERVED3[3] - (RO) Reserved bits +* AMSDU_DOP_CACHE_CS[5..4] - (RO) PLE AMSDU port - Data operation +CACHE +* current state. +* RESERVED6[7..6] - (RO) Reserved bits +* AMSDU_QOP_Q_OPER_CS[11..8] - (RO) PLE AMSDU port - Queue operation +current +state. +* AMSDU_QOP_RL_OCP_CS[13..12] - (RO) PLE AMSDU port - Queue operation +RL +* current state. +* RESERVED14[15..14] - (RO) Reserved bits +* AMSDU_QOP_PL_OCP_CS[17..16] - (RO) PLE AMSDU port - Queue operation +PL +* current state. +* RESERVED18[19..18] - (RO) Reserved bits +* AMSDU_QOP_ALLOCATE_CS[22..20] - (RO) PLE AMSDU port - Queue +operation +* allocate current state. +* RESERVED23[31..23] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_QOP_ALLOCATE_CS_ADDR \ + WF_PLE_TOP_AMSDU_PEEK_CR_01_ADDR +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_QOP_ALLOCATE_CS_MASK \ + 0x00700000 /* AMSDU_QOP_ALLOCATE_CS[22..20] */ +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_QOP_ALLOCATE_CS_SHFT 20 +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_QOP_PL_OCP_CS_ADDR \ + WF_PLE_TOP_AMSDU_PEEK_CR_01_ADDR +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_QOP_PL_OCP_CS_MASK \ + 0x00030000 /* AMSDU_QOP_PL_OCP_CS[17..16] */ +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_QOP_PL_OCP_CS_SHFT 16 +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_QOP_RL_OCP_CS_ADDR \ + WF_PLE_TOP_AMSDU_PEEK_CR_01_ADDR +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_QOP_RL_OCP_CS_MASK \ + 0x00003000 /* AMSDU_QOP_RL_OCP_CS[13..12] */ +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_QOP_RL_OCP_CS_SHFT 12 +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_QOP_Q_OPER_CS_ADDR \ + WF_PLE_TOP_AMSDU_PEEK_CR_01_ADDR +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_QOP_Q_OPER_CS_MASK \ + 0x00000F00 /* AMSDU_QOP_Q_OPER_CS[11..8] */ +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_QOP_Q_OPER_CS_SHFT 8 +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_DOP_CACHE_CS_ADDR \ + WF_PLE_TOP_AMSDU_PEEK_CR_01_ADDR +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_DOP_CACHE_CS_MASK \ + 0x00000030 /* AMSDU_DOP_CACHE_CS[5..4] */ +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_DOP_CACHE_CS_SHFT 4 +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_DOP_PBUF_CS_ADDR \ + WF_PLE_TOP_AMSDU_PEEK_CR_01_ADDR +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_DOP_PBUF_CS_MASK \ + 0x00000007 /* AMSDU_DOP_PBUF_CS[2..0] */ +#define WF_PLE_TOP_AMSDU_PEEK_CR_01_AMSDU_DOP_PBUF_CS_SHFT 0 + +/* +* ---AMSDU_PACK_1_MSDU_CNT (0x820C0000 + 0x10e0)--- +* pack_1_msdu_cnt[15..0] - (RC) AMSDU pack count of 1 MSDU in TXD. +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_AMSDU_PACK_1_MSDU_CNT_pack_1_msdu_cnt_ADDR \ + WF_PLE_TOP_AMSDU_PACK_1_MSDU_CNT_ADDR +#define WF_PLE_TOP_AMSDU_PACK_1_MSDU_CNT_pack_1_msdu_cnt_MASK \ + 0x0000FFFF /* pack_1_msdu_cnt[15..0] */ +#define WF_PLE_TOP_AMSDU_PACK_1_MSDU_CNT_pack_1_msdu_cnt_SHFT 0 + +/* +* ---AMSDU_PACK_2_MSDU_CNT (0x820C0000 + 0x10e4)--- +* pack_2_msdu_cnt[15..0] - (RC) AMSDU pack count of 2 MSDU in TXD. +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_AMSDU_PACK_2_MSDU_CNT_pack_2_msdu_cnt_ADDR \ + WF_PLE_TOP_AMSDU_PACK_2_MSDU_CNT_ADDR +#define WF_PLE_TOP_AMSDU_PACK_2_MSDU_CNT_pack_2_msdu_cnt_MASK \ + 0x0000FFFF /* pack_2_msdu_cnt[15..0] */ +#define WF_PLE_TOP_AMSDU_PACK_2_MSDU_CNT_pack_2_msdu_cnt_SHFT 0 + +/* +* ---AMSDU_PACK_3_MSDU_CNT (0x820C0000 + 0x10e8)--- +* pack_3_msdu_cnt[15..0] - (RC) AMSDU pack count of 3 MSDU in TXD. +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_AMSDU_PACK_3_MSDU_CNT_pack_3_msdu_cnt_ADDR \ + WF_PLE_TOP_AMSDU_PACK_3_MSDU_CNT_ADDR +#define WF_PLE_TOP_AMSDU_PACK_3_MSDU_CNT_pack_3_msdu_cnt_MASK \ + 0x0000FFFF /* pack_3_msdu_cnt[15..0] */ +#define WF_PLE_TOP_AMSDU_PACK_3_MSDU_CNT_pack_3_msdu_cnt_SHFT 0 + +/* +* ---AMSDU_PACK_4_MSDU_CNT (0x820C0000 + 0x10ec)--- +* pack_4_msdu_cnt[15..0] - (RC) AMSDU pack count of 4 MSDU in TXD. +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_AMSDU_PACK_4_MSDU_CNT_pack_4_msdu_cnt_ADDR \ + WF_PLE_TOP_AMSDU_PACK_4_MSDU_CNT_ADDR +#define WF_PLE_TOP_AMSDU_PACK_4_MSDU_CNT_pack_4_msdu_cnt_MASK \ + 0x0000FFFF /* pack_4_msdu_cnt[15..0] */ +#define WF_PLE_TOP_AMSDU_PACK_4_MSDU_CNT_pack_4_msdu_cnt_SHFT 0 + +/* +* ---AMSDU_PACK_5_MSDU_CNT (0x820C0000 + 0x10f0)--- +* pack_5_msdu_cnt[15..0] - (RC) AMSDU pack count of 5 MSDU in TXD. +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_AMSDU_PACK_5_MSDU_CNT_pack_5_msdu_cnt_ADDR \ + WF_PLE_TOP_AMSDU_PACK_5_MSDU_CNT_ADDR +#define WF_PLE_TOP_AMSDU_PACK_5_MSDU_CNT_pack_5_msdu_cnt_MASK \ + 0x0000FFFF /* pack_5_msdu_cnt[15..0] */ +#define WF_PLE_TOP_AMSDU_PACK_5_MSDU_CNT_pack_5_msdu_cnt_SHFT 0 + +/* +* ---AMSDU_PACK_6_MSDU_CNT (0x820C0000 + 0x10f4)--- +* pack_6_msdu_cnt[15..0] - (RC) AMSDU pack count of 4 MSDU in TXD. +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_AMSDU_PACK_6_MSDU_CNT_pack_6_msdu_cnt_ADDR \ + WF_PLE_TOP_AMSDU_PACK_6_MSDU_CNT_ADDR +#define WF_PLE_TOP_AMSDU_PACK_6_MSDU_CNT_pack_6_msdu_cnt_MASK \ + 0x0000FFFF /* pack_6_msdu_cnt[15..0] */ +#define WF_PLE_TOP_AMSDU_PACK_6_MSDU_CNT_pack_6_msdu_cnt_SHFT 0 + +/* +* ---AMSDU_PACK_7_MSDU_CNT (0x820C0000 + 0x10f8)--- +* pack_7_msdu_cnt[15..0] - (RC) AMSDU pack count of 7 MSDU in TXD. +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_AMSDU_PACK_7_MSDU_CNT_pack_7_msdu_cnt_ADDR \ + WF_PLE_TOP_AMSDU_PACK_7_MSDU_CNT_ADDR +#define WF_PLE_TOP_AMSDU_PACK_7_MSDU_CNT_pack_7_msdu_cnt_MASK \ + 0x0000FFFF /* pack_7_msdu_cnt[15..0] */ +#define WF_PLE_TOP_AMSDU_PACK_7_MSDU_CNT_pack_7_msdu_cnt_SHFT 0 + +/* +* ---AMSDU_PACK_8_MSDU_CNT (0x820C0000 + 0x10fc)--- +* pack_8_msdu_cnt[15..0] - (RC) AMSDU pack count of 8 MSDU in TXD. +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_AMSDU_PACK_8_MSDU_CNT_pack_8_msdu_cnt_ADDR \ + WF_PLE_TOP_AMSDU_PACK_8_MSDU_CNT_ADDR +#define WF_PLE_TOP_AMSDU_PACK_8_MSDU_CNT_pack_8_msdu_cnt_MASK \ + 0x0000FFFF /* pack_8_msdu_cnt[15..0] */ +#define WF_PLE_TOP_AMSDU_PACK_8_MSDU_CNT_pack_8_msdu_cnt_SHFT 0 + +/* +* ---AMSDU_AC0_QUEUE_EMPTY0 (0x820C0000 + 0x1100)--- +* AMSDU_QUEUE_EMPTY_FLAG_31_0[31..0] - (RO) AC0 queue empty flag for +* station31~station0 in HW AMSDU engine. +*/ +#define \ +WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY0_AMSDU_QUEUE_EMPTY_FLAG_31_0_ADDR \ + WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY0_ADDR +#define \ +WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY0_AMSDU_QUEUE_EMPTY_FLAG_31_0_MASK \ + 0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_31_0[31..0] */ +#define \ +WF_PLE_TOP_AMSDU_AC0_QUEUE_EMPTY0_AMSDU_QUEUE_EMPTY_FLAG_31_0_SHFT \ + 0 + +/* +* ---AMSDU_AC1_QUEUE_EMPTY0 (0x820C0000 + 0x1140)--- +* AMSDU_QUEUE_EMPTY_FLAG_31_0[31..0] - (RO) AC1 queue empty flag for +* station31~station0 in HW AMSDU engine. +*/ +#define \ +WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY0_AMSDU_QUEUE_EMPTY_FLAG_31_0_ADDR \ + WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY0_ADDR +#define \ +WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY0_AMSDU_QUEUE_EMPTY_FLAG_31_0_MASK \ + 0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_31_0[31..0] */ +#define \ +WF_PLE_TOP_AMSDU_AC1_QUEUE_EMPTY0_AMSDU_QUEUE_EMPTY_FLAG_31_0_SHFT \ + 0 + +/* +* ---AMSDU_AC2_QUEUE_EMPTY0 (0x820C0000 + 0x1180)--- +* AMSDU_QUEUE_EMPTY_FLAG_31_0[31..0] - (RO) AC2 queue empty flag for +* station31~station0 in HW AMSDU engine. +*/ +#define \ +WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY0_AMSDU_QUEUE_EMPTY_FLAG_31_0_ADDR \ + WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY0_ADDR +#define \ +WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY0_AMSDU_QUEUE_EMPTY_FLAG_31_0_MASK \ + 0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_31_0[31..0] */ +#define \ +WF_PLE_TOP_AMSDU_AC2_QUEUE_EMPTY0_AMSDU_QUEUE_EMPTY_FLAG_31_0_SHFT \ + 0 + +/* +* ---AMSDU_AC3_QUEUE_EMPTY0 (0x820C0000 + 0x11C0)--- +* AMSDU_QUEUE_EMPTY_FLAG_31_0[31..0] - (RO) AC3 queue empty flag for +* station31~station0 in HW AMSDU engine. +*/ +#define \ +WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY0_AMSDU_QUEUE_EMPTY_FLAG_31_0_ADDR \ + WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY0_ADDR +#define \ +WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY0_AMSDU_QUEUE_EMPTY_FLAG_31_0_MASK \ + 0xFFFFFFFF /* AMSDU_QUEUE_EMPTY_FLAG_31_0[31..0] */ +#define \ +WF_PLE_TOP_AMSDU_AC3_QUEUE_EMPTY0_AMSDU_QUEUE_EMPTY_FLAG_31_0_SHFT \ + 0 + +/* +* ---CFG_DBDC_CTRL0 (0x820C0000 + 0x2008)--- +* RESERVED0[7..0] - (RO) Reserved bits +* WMM_0TO3_BAND_SEL[11..8] - (RW) Selects WMM0~WMM3 band +* RESERVED12[15..12] - (RO) Reserved bits +* NAN_BAND_SEL[16] - (RW) Selects NAN band +* FUNCQ_BAND_SEL[17] - (RW) Selects Functional Queue band +* TGID 0 & TGID1 always selec to different +band +* RESERVED18[30..18] - (RO) Reserved bits +* DBDC_EN[31] - (RO) Enables DBDC +*/ +#define WF_PLE_TOP_CFG_DBDC_CTRL0_DBDC_EN_ADDR \ + WF_PLE_TOP_CFG_DBDC_CTRL0_ADDR +#define WF_PLE_TOP_CFG_DBDC_CTRL0_DBDC_EN_MASK \ + 0x80000000 /* DBDC_EN[31] */ +#define WF_PLE_TOP_CFG_DBDC_CTRL0_DBDC_EN_SHFT 31 +#define WF_PLE_TOP_CFG_DBDC_CTRL0_FUNCQ_BAND_SEL_ADDR \ + WF_PLE_TOP_CFG_DBDC_CTRL0_ADDR +#define WF_PLE_TOP_CFG_DBDC_CTRL0_FUNCQ_BAND_SEL_MASK \ + 0x00020000 /* FUNCQ_BAND_SEL[17] */ +#define WF_PLE_TOP_CFG_DBDC_CTRL0_FUNCQ_BAND_SEL_SHFT 17 +#define WF_PLE_TOP_CFG_DBDC_CTRL0_NAN_BAND_SEL_ADDR \ + WF_PLE_TOP_CFG_DBDC_CTRL0_ADDR +#define WF_PLE_TOP_CFG_DBDC_CTRL0_NAN_BAND_SEL_MASK \ + 0x00010000 /* NAN_BAND_SEL[16] */ +#define WF_PLE_TOP_CFG_DBDC_CTRL0_NAN_BAND_SEL_SHFT 16 +#define WF_PLE_TOP_CFG_DBDC_CTRL0_WMM_0TO3_BAND_SEL_ADDR \ + WF_PLE_TOP_CFG_DBDC_CTRL0_ADDR +#define WF_PLE_TOP_CFG_DBDC_CTRL0_WMM_0TO3_BAND_SEL_MASK \ + 0x00000F00 /* WMM_0TO3_BAND_SEL[11..8] */ +#define WF_PLE_TOP_CFG_DBDC_CTRL0_WMM_0TO3_BAND_SEL_SHFT 8 + +/* +* ---CFG_UWTBL_MBIST_CTRL_0 (0x820C0000 + 0x2480)--- +* UWTBL_MBIST_MODE[0] - (RW) Control register for mbist_mode of UWTBL +MBIST +* UWTBL_MBIST_HOLDB[1] - (RW) Control register for mbist_holdb of +* UWTBL MBIST +* UWTBL_MBIST_DEBUG[2] - (RW) Control register for mbist_debug of +* UWTBL MBIST +* UWTBL_MBIST_USE_DEFAULT_DELSEL[3] - (RW) Control register for +* default DELSEL +* value of UWTBL memory +* UWTBL_MBIST_SLEEP_TEST[4] - (RW) Control register for sleep_test of +UWTBL +MBIST +* UWTBL_MBIST_SLEEP_INV[5] - (RW) Control register for sleep_inv of +UWTBL +MBIST +* UWTBL_MBIST_SLEEP_W[6] - (RW) Control register for sleep_w of UWTBL +MBIST +* UWTBL_MBIST_SLEEP_R[7] - (RW) Control register for sleep_r of UWTBL +MBIST +* UWTBL_MBIST_DONE[8] - (RO) Working status of UWTBL SRAM MBIST +circuit +* RESERVED9[15..9] - (RO) Reserved bits +* UWTBL_MBIST_FAIL[21..16] - (RO) MBIST check result of UWTBL SRAM +* RESERVED22[31..22] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_FAIL_ADDR \ + WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_FAIL_MASK \ + 0x003F0000 /* UWTBL_MBIST_FAIL[21..16] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_FAIL_SHFT 16 +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_DONE_ADDR \ + WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_DONE_MASK \ + 0x00000100 /* UWTBL_MBIST_DONE[8] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_DONE_SHFT 8 +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_SLEEP_R_ADDR \ + WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_SLEEP_R_MASK \ + 0x00000080 /* UWTBL_MBIST_SLEEP_R[7] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_SLEEP_R_SHFT 7 +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_SLEEP_W_ADDR \ + WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_SLEEP_W_MASK \ + 0x00000040 /* UWTBL_MBIST_SLEEP_W[6] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_SLEEP_W_SHFT 6 +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_SLEEP_INV_ADDR \ + WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_SLEEP_INV_MASK \ + 0x00000020 /* UWTBL_MBIST_SLEEP_INV[5] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_SLEEP_INV_SHFT 5 +#define \ +WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_SLEEP_TEST_ADDR \ + WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_ADDR +#define \ +WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_SLEEP_TEST_MASK \ + 0x00000010 /* UWTBL_MBIST_SLEEP_TEST[4] */ +#define \ +WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_SLEEP_TEST_SHFT \ + 4 +#define \ +WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_USE_DEFAULT_DELSEL_ADDR\ +\ + WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_ADDR +#define \ +WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_USE_DEFAULT_DELSEL_MASK\ +\ + 0x00000008 /* UWTBL_MBIST_USE_DEFAULT_DELSEL[3] */ +#define \ +WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_USE_DEFAULT_DELSEL_SHFT\ +3 +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_DEBUG_ADDR \ + WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_DEBUG_MASK \ + 0x00000004 /* UWTBL_MBIST_DEBUG[2] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_DEBUG_SHFT 2 +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_HOLDB_ADDR \ + WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_HOLDB_MASK \ + 0x00000002 /* UWTBL_MBIST_HOLDB[1] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_HOLDB_SHFT 1 +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_MODE_ADDR \ + WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_MODE_MASK \ + 0x00000001 /* UWTBL_MBIST_MODE[0] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_0_UWTBL_MBIST_MODE_SHFT 0 + +/* +* ---CFG_UWTBL_MBIST_CTRL_1 (0x820C0000 + 0x2484)--- +* UWTBL_MBIST_HDEN[5..0] - (RW) Control register for mbist UWTBL HDEN +* RESERVED6[15..6] - (RO) Reserved bits +* UWTBL_MBIST_AWT[21..16] - (RW) Control register for mbist UWTBL AWT +* RESERVED22[31..22] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_1_UWTBL_MBIST_AWT_ADDR \ + WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_1_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_1_UWTBL_MBIST_AWT_MASK \ + 0x003F0000 /* UWTBL_MBIST_AWT[21..16] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_1_UWTBL_MBIST_AWT_SHFT 16 +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_1_UWTBL_MBIST_HDEN_ADDR \ + WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_1_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_1_UWTBL_MBIST_HDEN_MASK \ + 0x0000003F /* UWTBL_MBIST_HDEN[5..0] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_1_UWTBL_MBIST_HDEN_SHFT 0 + +/* +* ---CFG_UWTBL_MBIST_CTRL_2 (0x820C0000 + 0x2488)--- +* UWTBL_BACKGROUND[15..0] - (RW) The MBIST background control register +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_2_UWTBL_BACKGROUND_ADDR \ + WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_2_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_2_UWTBL_BACKGROUND_MASK \ + 0x0000FFFF /* UWTBL_BACKGROUND[15..0] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_2_UWTBL_BACKGROUND_SHFT 0 + +/* +* ---CFG_UWTBL_MBIST_CTRL_3 (0x820C0000 + 0x248c)--- +* UWTBL_DELSEL_0[31..0] - (RW) UWTBL DELSEL 0 +*/ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_3_UWTBL_DELSEL_0_ADDR \ + WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_3_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_3_UWTBL_DELSEL_0_MASK \ + 0xFFFFFFFF /* UWTBL_DELSEL_0[31..0] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_3_UWTBL_DELSEL_0_SHFT 0 + +/* +* ---CFG_UWTBL_MBIST_CTRL_4 (0x820C0000 + 0x2490)--- +* UWTBL_DELSEL_1[31..0] - (RW) UWTBL DELSEL 1 +*/ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_4_UWTBL_DELSEL_1_ADDR \ + WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_4_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_4_UWTBL_DELSEL_1_MASK \ + 0xFFFFFFFF /* UWTBL_DELSEL_1[31..0] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_4_UWTBL_DELSEL_1_SHFT 0 + +/* +* ---CFG_UWTBL_MBIST_CTRL_5 (0x820C0000 + 0x2494)--- +* UWTBL_FUSE[6..0] - (RW) UWTBL FUSE +* RESERVED7[7] - (RO) Reserved bits +* UWTBL_PRE_FUSE[14..8] - (RO) UWTBL MBIST Pre Fuse +* RESERVED15[15] - (RO) Reserved bits +* UWTBL_MBIST_REPAIR_OK[21..16] - (RO) MBIST Repair OK +* RESERVED22[23..22] - (RO) Reserved bits +* UWTBL_MBIST_REPAIR_FAIL[29..24] - (RO) MBIST Repair Fail +* RESERVED30[31..30] - (RO) Reserved bits +*/ +#define \ +WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_UWTBL_MBIST_REPAIR_FAIL_ADDR \ + WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_ADDR +#define \ +WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_UWTBL_MBIST_REPAIR_FAIL_MASK \ + 0x3F000000 /* UWTBL_MBIST_REPAIR_FAIL[29..24] */ +#define \ +WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_UWTBL_MBIST_REPAIR_FAIL_SHFT \ + 24 +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_UWTBL_MBIST_REPAIR_OK_ADDR \ + WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_UWTBL_MBIST_REPAIR_OK_MASK \ + 0x003F0000 /* UWTBL_MBIST_REPAIR_OK[21..16] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_UWTBL_MBIST_REPAIR_OK_SHFT \ + 16 +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_UWTBL_PRE_FUSE_ADDR \ + WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_UWTBL_PRE_FUSE_MASK \ + 0x00007F00 /* UWTBL_PRE_FUSE[14..8] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_UWTBL_PRE_FUSE_SHFT 8 +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_UWTBL_FUSE_ADDR \ + WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_UWTBL_FUSE_MASK \ + 0x0000007F /* UWTBL_FUSE[6..0] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_5_UWTBL_FUSE_SHFT 0 + +/* +* ---CFG_UWTBL_MBIST_CTRL_6 (0x820C0000 + 0x2498)--- +* UWTBL_DELSEL_2[31..0] - (RW) UWTBL DELSEL 2 +*/ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_6_UWTBL_DELSEL_2_ADDR \ + WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_6_ADDR +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_6_UWTBL_DELSEL_2_MASK \ + 0xFFFFFFFF /* UWTBL_DELSEL_2[31..0] */ +#define WF_PLE_TOP_CFG_UWTBL_MBIST_CTRL_6_UWTBL_DELSEL_2_SHFT 0 + +/* +* ---CFG_SEC_MBIST_CTRL_0 (0x820C0000 + 0x25c0)--- +* SEC_MBIST_MODE[0] - (RW) Control register for mbist_mode of SEC +MBIST +* SEC_MBIST_HOLDB[1] - (RW) Control register for mbist_holdb of SEC +MBIST +* SEC_MBIST_DEBUG[2] - (RW) Control register for mbist_debug of SEC +MBIST +* SEC_MBIST_USE_DEFAULT_DELSEL[3] - (RW) Control register for default +DELSEL +* value of SEC memory +* RESERVED4[7..4] - (RO) Reserved bits +* SEC_MBIST_DONE[8] - (RO) Working status of SEC SRAM MBIST circuit +* RESERVED9[15..9] - (RO) Reserved bits +* SEC_MBIST_FAIL[17..16] - (RO) MBIST check result of SEC SRAM +* RESERVED18[31..18] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_FAIL_ADDR \ + WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_FAIL_MASK \ + 0x00030000 /* SEC_MBIST_FAIL[17..16] */ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_FAIL_SHFT 16 +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_DONE_ADDR \ + WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_DONE_MASK \ + 0x00000100 /* SEC_MBIST_DONE[8] */ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_DONE_SHFT 8 +#define \ +WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_USE_DEFAULT_DELSEL_ADDR \ + WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_ADDR +#define \ +WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_USE_DEFAULT_DELSEL_MASK \ + 0x00000008 /* SEC_MBIST_USE_DEFAULT_DELSEL[3] */ +#define \ +WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_USE_DEFAULT_DELSEL_SHFT \ + 3 +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_DEBUG_ADDR \ + WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_DEBUG_MASK \ + 0x00000004 /* SEC_MBIST_DEBUG[2] */ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_DEBUG_SHFT 2 +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_HOLDB_ADDR \ + WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_HOLDB_MASK \ + 0x00000002 /* SEC_MBIST_HOLDB[1] */ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_HOLDB_SHFT 1 +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_MODE_ADDR \ + WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_MODE_MASK \ + 0x00000001 /* SEC_MBIST_MODE[0] */ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_0_SEC_MBIST_MODE_SHFT 0 + +/* +* ---CFG_SEC_MBIST_CTRL_1 (0x820C0000 + 0x25c4)--- +* SEC_MBIST_HDEN[0] - (RW) Control register for mbist SEC HDEN +* RESERVED1[15..1] - (RO) Reserved bits +* SEC_MBIST_AWT[16] - (RW) Control register for mbist SEC AWT +* RESERVED17[31..17] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_1_SEC_MBIST_AWT_ADDR \ + WF_PLE_TOP_CFG_SEC_MBIST_CTRL_1_ADDR +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_1_SEC_MBIST_AWT_MASK \ + 0x00010000 /* SEC_MBIST_AWT[16] */ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_1_SEC_MBIST_AWT_SHFT 16 +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_1_SEC_MBIST_HDEN_ADDR \ + WF_PLE_TOP_CFG_SEC_MBIST_CTRL_1_ADDR +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_1_SEC_MBIST_HDEN_MASK \ + 0x00000001 /* SEC_MBIST_HDEN[0] */ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_1_SEC_MBIST_HDEN_SHFT 0 + +/* +* ---CFG_SEC_MBIST_CTRL_2 (0x820C0000 + 0x25c8)--- +* SEC_BACKGROUND[15..0] - (RW) The MBIST background control register +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_2_SEC_BACKGROUND_ADDR \ + WF_PLE_TOP_CFG_SEC_MBIST_CTRL_2_ADDR +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_2_SEC_BACKGROUND_MASK \ + 0x0000FFFF /* SEC_BACKGROUND[15..0] */ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_2_SEC_BACKGROUND_SHFT 0 + +/* +* ---CFG_SEC_MBIST_CTRL_3 (0x820C0000 + 0x25cc)--- +* SEC_DELSEL_0[31..0] - (RW) SEC DELSEL 0 +*/ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_3_SEC_DELSEL_0_ADDR \ + WF_PLE_TOP_CFG_SEC_MBIST_CTRL_3_ADDR +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_3_SEC_DELSEL_0_MASK \ + 0xFFFFFFFF /* SEC_DELSEL_0[31..0] */ +#define WF_PLE_TOP_CFG_SEC_MBIST_CTRL_3_SEC_DELSEL_0_SHFT 0 + +/* +* ---CFG_PF_MBIST_CTRL_0 (0x820C0000 + 0x25e0)--- +* PF_MBIST_MODE[0] - (RW) Control register for mbist_mode of PF +MBIST +* PF_MBIST_HOLDB[1] - (RW) Control register for mbist_holdb of PF +MBIST +* PF_MBIST_DEBUG[2] - (RW) Control register for mbist_debug of PF +MBIST +* PF_MBIST_USE_DEFAULT_DELSEL[3] - (RW) Control register for default +DELSEL +* value of PF memory +* PF_MBIST_SLEEP_TEST[4] - (RW) Control register for sleep_test of PF +MBIST +* PF_MBIST_SLEEP_INV[5] - (RW) Control register for sleep_inv of PF +MBIST +* PF_MBIST_SLEEP_W[6] - (RW) Control register for sleep_w of PF MBIST +* PF_MBIST_SLEEP_R[7] - (RW) Control register for sleep_r of PF MBIST +* PF_MBIST_DONE[8] - (RO) Working status of PF SRAM MBIST circuit +* RESERVED9[11..9] - (RO) Reserved bits +* PF_MBIST_FAIL[31..12] - (RO) MBIST check result of PF SRAM +*/ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_FAIL_ADDR \ + WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_FAIL_MASK \ + 0xFFFFF000 /* PF_MBIST_FAIL[31..12] */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_FAIL_SHFT 12 +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_DONE_ADDR \ + WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_DONE_MASK \ + 0x00000100 /* PF_MBIST_DONE[8] */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_DONE_SHFT 8 +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_SLEEP_R_ADDR \ + WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_SLEEP_R_MASK \ + 0x00000080 /* PF_MBIST_SLEEP_R[7] */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_SLEEP_R_SHFT 7 +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_SLEEP_W_ADDR \ + WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_SLEEP_W_MASK \ + 0x00000040 /* PF_MBIST_SLEEP_W[6] */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_SLEEP_W_SHFT 6 +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_SLEEP_INV_ADDR \ + WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_SLEEP_INV_MASK \ + 0x00000020 /* PF_MBIST_SLEEP_INV[5] */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_SLEEP_INV_SHFT 5 +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_SLEEP_TEST_ADDR \ + WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_SLEEP_TEST_MASK \ + 0x00000010 /* PF_MBIST_SLEEP_TEST[4] */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_SLEEP_TEST_SHFT 4 +#define \ +WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_USE_DEFAULT_DELSEL_ADDR \ + WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_ADDR +#define \ +WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_USE_DEFAULT_DELSEL_MASK \ + 0x00000008 /* PF_MBIST_USE_DEFAULT_DELSEL[3] */ +#define \ +WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_USE_DEFAULT_DELSEL_SHFT \ + 3 +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_DEBUG_ADDR \ + WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_DEBUG_MASK \ + 0x00000004 /* PF_MBIST_DEBUG[2] */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_DEBUG_SHFT 2 +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_HOLDB_ADDR \ + WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_HOLDB_MASK \ + 0x00000002 /* PF_MBIST_HOLDB[1] */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_HOLDB_SHFT 1 +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_MODE_ADDR \ + WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_ADDR +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_MODE_MASK \ + 0x00000001 /* PF_MBIST_MODE[0] */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_0_PF_MBIST_MODE_SHFT 0 + +/* +* ---CFG_PF_MBIST_CTRL_1 (0x820C0000 + 0x25e4)--- +* PF_MBIST_HDEN[9..0] - (RW) Control register for mbist PF HDEN +* RESERVED10[11..10] - (RO) Reserved bits +* PF_MBIST_AWT[31..12] - (RW) Control register for mbist PF AWT +*/ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_1_PF_MBIST_AWT_ADDR \ + WF_PLE_TOP_CFG_PF_MBIST_CTRL_1_ADDR +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_1_PF_MBIST_AWT_MASK \ + 0xFFFFF000 /* PF_MBIST_AWT[31..12] */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_1_PF_MBIST_AWT_SHFT 12 +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_1_PF_MBIST_HDEN_ADDR \ + WF_PLE_TOP_CFG_PF_MBIST_CTRL_1_ADDR +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_1_PF_MBIST_HDEN_MASK \ + 0x000003FF /* PF_MBIST_HDEN[9..0] */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_1_PF_MBIST_HDEN_SHFT 0 + +/* +* ---CFG_PF_MBIST_CTRL_2 (0x820C0000 + 0x25e8)--- +* PF_BACKGROUND[15..0] - (RW) The MBIST background control register +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_2_PF_BACKGROUND_ADDR \ + WF_PLE_TOP_CFG_PF_MBIST_CTRL_2_ADDR +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_2_PF_BACKGROUND_MASK \ + 0x0000FFFF /* PF_BACKGROUND[15..0] */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_2_PF_BACKGROUND_SHFT 0 + +/* +* ---CFG_PF_MBIST_CTRL_3 (0x820C0000 + 0x25ec)--- +* PF_DELSEL_0[31..0] - (RW) PF DELSEL 0 +*/ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_3_PF_DELSEL_0_ADDR \ + WF_PLE_TOP_CFG_PF_MBIST_CTRL_3_ADDR +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_3_PF_DELSEL_0_MASK \ + 0xFFFFFFFF /* PF_DELSEL_0[31..0] */ +#define WF_PLE_TOP_CFG_PF_MBIST_CTRL_3_PF_DELSEL_0_SHFT 0 + +/* +* ---SYSRAM_MBIST_CTRL (0x820C0000 + 0x3004)--- +* MBIST_SW_RESET[0] - (RW) MBIST Software reset +* RESERVED1[7..1] - (RO) Reserved bits +* MBIST_BSEL[15..8] - (RW) Controls BSEL of SRAM MBIST circuit. +* MBIST_BACKGROUND[31..16] - (RW) The MBIST background control +register +*/ +#define WF_PLE_TOP_SYSRAM_MBIST_CTRL_MBIST_BACKGROUND_ADDR \ + WF_PLE_TOP_SYSRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SYSRAM_MBIST_CTRL_MBIST_BACKGROUND_MASK \ + 0xFFFF0000 /* MBIST_BACKGROUND[31..16] */ +#define WF_PLE_TOP_SYSRAM_MBIST_CTRL_MBIST_BACKGROUND_SHFT 16 +#define WF_PLE_TOP_SYSRAM_MBIST_CTRL_MBIST_BSEL_ADDR \ + WF_PLE_TOP_SYSRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SYSRAM_MBIST_CTRL_MBIST_BSEL_MASK \ + 0x0000FF00 /* MBIST_BSEL[15..8] */ +#define WF_PLE_TOP_SYSRAM_MBIST_CTRL_MBIST_BSEL_SHFT 8 +#define WF_PLE_TOP_SYSRAM_MBIST_CTRL_MBIST_SW_RESET_ADDR \ + WF_PLE_TOP_SYSRAM_MBIST_CTRL_ADDR +#define WF_PLE_TOP_SYSRAM_MBIST_CTRL_MBIST_SW_RESET_MASK \ + 0x00000001 /* MBIST_SW_RESET[0] */ +#define WF_PLE_TOP_SYSRAM_MBIST_CTRL_MBIST_SW_RESET_SHFT 0 + +/* +* ---SYSRAM_MBIST_DEBUG (0x820C0000 + 0x3008)--- +* SYSRAM_MBIST_DEBUG[15..0] - (RW) Control register for mbist_debug of +* SYSRAM MBIST +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_SYSRAM_MBIST_DEBUG_SYSRAM_MBIST_DEBUG_ADDR \ + WF_PLE_TOP_SYSRAM_MBIST_DEBUG_ADDR +#define WF_PLE_TOP_SYSRAM_MBIST_DEBUG_SYSRAM_MBIST_DEBUG_MASK \ + 0x0000FFFF /* SYSRAM_MBIST_DEBUG[15..0] */ +#define WF_PLE_TOP_SYSRAM_MBIST_DEBUG_SYSRAM_MBIST_DEBUG_SHFT 0 + +/* +* ---SYSRAM_MBIST_MODE (0x820C0000 + 0x300C)--- +* SYSRAM_MBIST_MODE[15..0] - (RW) Control register for mbist_holdb of +* SYSRAM MBIST +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_SYSRAM_MBIST_MODE_SYSRAM_MBIST_MODE_ADDR \ + WF_PLE_TOP_SYSRAM_MBIST_MODE_ADDR +#define WF_PLE_TOP_SYSRAM_MBIST_MODE_SYSRAM_MBIST_MODE_MASK \ + 0x0000FFFF /* SYSRAM_MBIST_MODE[15..0] */ +#define WF_PLE_TOP_SYSRAM_MBIST_MODE_SYSRAM_MBIST_MODE_SHFT 0 + +/* +* ---SYSRAM_MBIST_HOLDB (0x820C0000 + 0x3010)--- +* SYSRAM_MBIST_HOLDB[15..0] - (RW) Control register for mbist_holdb of +* sysram MBIST +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_SYSRAM_MBIST_HOLDB_SYSRAM_MBIST_HOLDB_ADDR \ + WF_PLE_TOP_SYSRAM_MBIST_HOLDB_ADDR +#define WF_PLE_TOP_SYSRAM_MBIST_HOLDB_SYSRAM_MBIST_HOLDB_MASK \ + 0x0000FFFF /* SYSRAM_MBIST_HOLDB[15..0] */ +#define WF_PLE_TOP_SYSRAM_MBIST_HOLDB_SYSRAM_MBIST_HOLDB_SHFT 0 + +/* +* ---SYSRAM_MBIST_DONE (0x820C0000 + 0x3014)--- +* SYSRAM_MBIST_DONE[15..0] - (RO) Working status of SYSRAM MBIST 3 +circuit +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_SYSRAM_MBIST_DONE_SYSRAM_MBIST_DONE_ADDR \ + WF_PLE_TOP_SYSRAM_MBIST_DONE_ADDR +#define WF_PLE_TOP_SYSRAM_MBIST_DONE_SYSRAM_MBIST_DONE_MASK \ + 0x0000FFFF /* SYSRAM_MBIST_DONE[15..0] */ +#define WF_PLE_TOP_SYSRAM_MBIST_DONE_SYSRAM_MBIST_DONE_SHFT 0 + +/* +* ---SYSRAM_MBIST_FAIL (0x820C0000 + 0x3018)--- +* SYSRAM_MBIST_FAIL[31..0] - (RO) MBIST check result of SYSRAM cell 3 +*/ +#define WF_PLE_TOP_SYSRAM_MBIST_FAIL_SYSRAM_MBIST_FAIL_ADDR \ + WF_PLE_TOP_SYSRAM_MBIST_FAIL_ADDR +#define WF_PLE_TOP_SYSRAM_MBIST_FAIL_SYSRAM_MBIST_FAIL_MASK \ + 0xFFFFFFFF /* SYSRAM_MBIST_FAIL[31..0] */ +#define WF_PLE_TOP_SYSRAM_MBIST_FAIL_SYSRAM_MBIST_FAIL_SHFT 0 + +/* +* ---SYSRAM_MBIST_SLEEP_TEST (0x820C0000 + 0x301C)--- +* SYSRAM_MBIST_SLEEP_TEST[15..0] - (RW) Control register for +* sleep_test of +* group 3 MBIST +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define \ +WF_PLE_TOP_SYSRAM_MBIST_SLEEP_TEST_SYSRAM_MBIST_SLEEP_TEST_ADDR \ + WF_PLE_TOP_SYSRAM_MBIST_SLEEP_TEST_ADDR +#define \ +WF_PLE_TOP_SYSRAM_MBIST_SLEEP_TEST_SYSRAM_MBIST_SLEEP_TEST_MASK \ + 0x0000FFFF /* SYSRAM_MBIST_SLEEP_TEST[15..0] */ +#define \ +WF_PLE_TOP_SYSRAM_MBIST_SLEEP_TEST_SYSRAM_MBIST_SLEEP_TEST_SHFT \ + 0 + +/* +* ---SYSRAM_MBIST_SLEEP_INV (0x820C0000 + 0x3020)--- +* SYSRAM_MBIST_SLEEP_INV[15..0] - (RW) Control register for sleep_inv +* of group +* 3 MBIST +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define \ +WF_PLE_TOP_SYSRAM_MBIST_SLEEP_INV_SYSRAM_MBIST_SLEEP_INV_ADDR \ + WF_PLE_TOP_SYSRAM_MBIST_SLEEP_INV_ADDR +#define \ +WF_PLE_TOP_SYSRAM_MBIST_SLEEP_INV_SYSRAM_MBIST_SLEEP_INV_MASK \ + 0x0000FFFF /* SYSRAM_MBIST_SLEEP_INV[15..0] */ +#define \ +WF_PLE_TOP_SYSRAM_MBIST_SLEEP_INV_SYSRAM_MBIST_SLEEP_INV_SHFT \ + 0 + +/* +* ---SYSRAM_MBIST_SLEEP_W (0x820C0000 + 0x3024)--- +* SYSRAM_MBIST_SLEEP_WRITE[15..0] - (RW) Control register for sleep_w +* of group +* 3 MBIST +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define \ +WF_PLE_TOP_SYSRAM_MBIST_SLEEP_W_SYSRAM_MBIST_SLEEP_WRITE_ADDR \ + WF_PLE_TOP_SYSRAM_MBIST_SLEEP_W_ADDR +#define \ +WF_PLE_TOP_SYSRAM_MBIST_SLEEP_W_SYSRAM_MBIST_SLEEP_WRITE_MASK \ + 0x0000FFFF /* SYSRAM_MBIST_SLEEP_WRITE[15..0] */ +#define \ +WF_PLE_TOP_SYSRAM_MBIST_SLEEP_W_SYSRAM_MBIST_SLEEP_WRITE_SHFT \ + 0 + +/* +* ---SYSRAM_MBIST_SLEEP_R (0x820C0000 + 0x3028)--- +* SYSRAM_MBIST_SLEEP_READ[15..0] - (RW) Control register for sleep_r +* of group +* 3 MBIST +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PLE_TOP_SYSRAM_MBIST_SLEEP_R_SYSRAM_MBIST_SLEEP_READ_ADDR \ + WF_PLE_TOP_SYSRAM_MBIST_SLEEP_R_ADDR +#define WF_PLE_TOP_SYSRAM_MBIST_SLEEP_R_SYSRAM_MBIST_SLEEP_READ_MASK \ + 0x0000FFFF /* SYSRAM_MBIST_SLEEP_READ[15..0] */ +#define WF_PLE_TOP_SYSRAM_MBIST_SLEEP_R_SYSRAM_MBIST_SLEEP_READ_SHFT 0 + +/* +* ---SYSRAM_AWT_HDEN (0x820C0000 + 0x302C)--- +* SYSRAM_MBIST_AWT[15..0] - (RW) Control register for mbist SYSRAM 3 +AWT +* SYSRAM_MBIST_HDEN[31..16] - (RW) Control register for mbist SYSRAM 3 +HDEN +*/ +#define WF_PLE_TOP_SYSRAM_AWT_HDEN_SYSRAM_MBIST_HDEN_ADDR \ + WF_PLE_TOP_SYSRAM_AWT_HDEN_ADDR +#define WF_PLE_TOP_SYSRAM_AWT_HDEN_SYSRAM_MBIST_HDEN_MASK \ + 0xFFFF0000 /* SYSRAM_MBIST_HDEN[31..16] */ +#define WF_PLE_TOP_SYSRAM_AWT_HDEN_SYSRAM_MBIST_HDEN_SHFT 16 +#define WF_PLE_TOP_SYSRAM_AWT_HDEN_SYSRAM_MBIST_AWT_ADDR \ + WF_PLE_TOP_SYSRAM_AWT_HDEN_ADDR +#define WF_PLE_TOP_SYSRAM_AWT_HDEN_SYSRAM_MBIST_AWT_MASK \ + 0x0000FFFF /* SYSRAM_MBIST_AWT[15..0] */ +#define WF_PLE_TOP_SYSRAM_AWT_HDEN_SYSRAM_MBIST_AWT_SHFT 0 + +/* +* ---SYSRAM_DBG_SEL (0x820C0000 + 0x3030)--- +* SYSRAM_DEBUG_SELECT_0[7..0] - (RW) Selects SYSRAM control debug 0 +* SYSRAM_DEBUG_SELECT_1[15..8] - (RW) Selects SYSRAM control debug 1 +* SYSRAM_DEBUG_SELECT_2[23..16] - (RW) Selects SYSRAM control debug 2 +* SYSRAM_DEBUG_SELECT_3[31..24] - (RW) Selects SYSRAM control debug 3 +*/ +#define WF_PLE_TOP_SYSRAM_DBG_SEL_SYSRAM_DEBUG_SELECT_3_ADDR \ + WF_PLE_TOP_SYSRAM_DBG_SEL_ADDR +#define WF_PLE_TOP_SYSRAM_DBG_SEL_SYSRAM_DEBUG_SELECT_3_MASK \ + 0xFF000000 /* SYSRAM_DEBUG_SELECT_3[31..24] */ +#define WF_PLE_TOP_SYSRAM_DBG_SEL_SYSRAM_DEBUG_SELECT_3_SHFT 24 +#define WF_PLE_TOP_SYSRAM_DBG_SEL_SYSRAM_DEBUG_SELECT_2_ADDR \ + WF_PLE_TOP_SYSRAM_DBG_SEL_ADDR +#define WF_PLE_TOP_SYSRAM_DBG_SEL_SYSRAM_DEBUG_SELECT_2_MASK \ + 0x00FF0000 /* SYSRAM_DEBUG_SELECT_2[23..16] */ +#define WF_PLE_TOP_SYSRAM_DBG_SEL_SYSRAM_DEBUG_SELECT_2_SHFT 16 +#define WF_PLE_TOP_SYSRAM_DBG_SEL_SYSRAM_DEBUG_SELECT_1_ADDR \ + WF_PLE_TOP_SYSRAM_DBG_SEL_ADDR +#define WF_PLE_TOP_SYSRAM_DBG_SEL_SYSRAM_DEBUG_SELECT_1_MASK \ + 0x0000FF00 /* SYSRAM_DEBUG_SELECT_1[15..8] */ +#define WF_PLE_TOP_SYSRAM_DBG_SEL_SYSRAM_DEBUG_SELECT_1_SHFT 8 +#define WF_PLE_TOP_SYSRAM_DBG_SEL_SYSRAM_DEBUG_SELECT_0_ADDR \ + WF_PLE_TOP_SYSRAM_DBG_SEL_ADDR +#define WF_PLE_TOP_SYSRAM_DBG_SEL_SYSRAM_DEBUG_SELECT_0_MASK \ + 0x000000FF /* SYSRAM_DEBUG_SELECT_0[7..0] */ +#define WF_PLE_TOP_SYSRAM_DBG_SEL_SYSRAM_DEBUG_SELECT_0_SHFT 0 + +/* +* ---SYSRAM_DELSEL (0x820C0000 + 0x3070)--- +* TYPE0_SYSRAM_DELSEL[31..0] - (RW) Type0 SYSRAM DELSEL bits +*/ +#define WF_PLE_TOP_SYSRAM_DELSEL_TYPE0_SYSRAM_DELSEL_ADDR \ + WF_PLE_TOP_SYSRAM_DELSEL_ADDR +#define WF_PLE_TOP_SYSRAM_DELSEL_TYPE0_SYSRAM_DELSEL_MASK \ + 0xFFFFFFFF /* TYPE0_SYSRAM_DELSEL[31..0] */ +#define WF_PLE_TOP_SYSRAM_DELSEL_TYPE0_SYSRAM_DELSEL_SHFT 0 + +/* +* ---SYSRAM_DELSEL_1 (0x820C0000 + 0x3074)--- +* TYPE1_SYSRAM_DELSEL[31..0] - (RW) Type1 SYSRAM DELSEL bits +*/ +#define WF_PLE_TOP_SYSRAM_DELSEL_1_TYPE1_SYSRAM_DELSEL_ADDR \ + WF_PLE_TOP_SYSRAM_DELSEL_1_ADDR +#define WF_PLE_TOP_SYSRAM_DELSEL_1_TYPE1_SYSRAM_DELSEL_MASK \ + 0xFFFFFFFF /* TYPE1_SYSRAM_DELSEL[31..0] */ +#define WF_PLE_TOP_SYSRAM_DELSEL_1_TYPE1_SYSRAM_DELSEL_SHFT 0 + +/* +* ---SYSRAM_DELSEL_2 (0x820C0000 + 0x3078)--- +* TYPE2_SYSRAM_DELSEL[31..0] - (RW) Type2 SYSRAM DELSEL bits +*/ +#define WF_PLE_TOP_SYSRAM_DELSEL_2_TYPE2_SYSRAM_DELSEL_ADDR \ + WF_PLE_TOP_SYSRAM_DELSEL_2_ADDR +#define WF_PLE_TOP_SYSRAM_DELSEL_2_TYPE2_SYSRAM_DELSEL_MASK \ + 0xFFFFFFFF /* TYPE2_SYSRAM_DELSEL[31..0] */ +#define WF_PLE_TOP_SYSRAM_DELSEL_2_TYPE2_SYSRAM_DELSEL_SHFT 0 + +/* +* ---SYSRAM_DELSEL_3 (0x820C0000 + 0x307C)--- +* TYPE3_SYSRAM_DELSEL[31..0] - (RW) Type3 SYSRAM DELSEL bits +*/ +#define WF_PLE_TOP_SYSRAM_DELSEL_3_TYPE3_SYSRAM_DELSEL_ADDR \ + WF_PLE_TOP_SYSRAM_DELSEL_3_ADDR +#define WF_PLE_TOP_SYSRAM_DELSEL_3_TYPE3_SYSRAM_DELSEL_MASK \ + 0xFFFFFFFF /* TYPE3_SYSRAM_DELSEL[31..0] */ +#define WF_PLE_TOP_SYSRAM_DELSEL_3_TYPE3_SYSRAM_DELSEL_SHFT 0 + +/* +* ---SYSRAM_OUTRAN_ERR_FLAG (0x820C0000 + 0x3080)--- +* SYSRAM_OUTRAN_ERR_FLAG[31..0] - (RO) Type3 SYSRAM DELSEL bits +*/ +#define \ +WF_PLE_TOP_SYSRAM_OUTRAN_ERR_FLAG_SYSRAM_OUTRAN_ERR_FLAG_ADDR \ + WF_PLE_TOP_SYSRAM_OUTRAN_ERR_FLAG_ADDR +#define \ +WF_PLE_TOP_SYSRAM_OUTRAN_ERR_FLAG_SYSRAM_OUTRAN_ERR_FLAG_MASK \ + 0xFFFFFFFF /* SYSRAM_OUTRAN_ERR_FLAG[31..0] */ +#define \ +WF_PLE_TOP_SYSRAM_OUTRAN_ERR_FLAG_SYSRAM_OUTRAN_ERR_FLAG_SHFT \ + 0 + +#ifdef __cplusplus +} +#endif + +#endif /* __WF_PLE_TOP_REGS_H__ */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/soc3_0/wf_pse_top.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/soc3_0/wf_pse_top.h new file mode 100644 index 0000000000000000000000000000000000000000..5820a942057b4562a469c512eac5ca256cde169a --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/soc3_0/wf_pse_top.h @@ -0,0 +1,3719 @@ +/* [File] : wf_pse_top.h */ +/* [Revision time] : Mon Apr 15 14:14:44 2019 */ +/* [Description] : This file is auto generated by CODA */ +/* [Copyright] : Copyright (C) 2019 Mediatek Incorportion. All rights +*/ +/* reserved. */ + +#ifndef __WF_PSE_TOP_REGS_H__ +#define __WF_PSE_TOP_REGS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* **************************************************************** */ +/* */ +/* WF_PSE_TOP CR Definitions */ +/* */ +/* **************************************************************** */ + +#define WF_PSE_TOP_BASE 0x820C8000 + +#define WF_PSE_TOP_GC_ADDR (WF_PSE_TOP_BASE + 0x00) /* 8000 */ +#define WF_PSE_TOP_PBUF_CTRL_ADDR (WF_PSE_TOP_BASE + 0x14) /* 8014 */ +#define WF_PSE_TOP_INT_N9_EN_MASK_ADDR \ + (WF_PSE_TOP_BASE + 0x20) /* 8020 */ +#define WF_PSE_TOP_INT_N9_STS_ADDR \ + (WF_PSE_TOP_BASE + 0x24) /* 8024 */ +#define WF_PSE_TOP_INT_N9_ERR_STS_ADDR \ + (WF_PSE_TOP_BASE + 0x28) /* 8028 */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_ADDR \ + (WF_PSE_TOP_BASE + 0x2C) /* 802C */ +#define WF_PSE_TOP_INT_N9_ERR1_STS_ADDR \ + (WF_PSE_TOP_BASE + 0x30) /* 8030 */ +#define WF_PSE_TOP_INT_N9_ERR1_MASK_ADDR \ + (WF_PSE_TOP_BASE + 0x34) /* 8034 */ +#define WF_PSE_TOP_C_GET_FID_0_ADDR \ + (WF_PSE_TOP_BASE + 0x40) /* 8040 */ +#define WF_PSE_TOP_C_GET_FID_1_ADDR \ + (WF_PSE_TOP_BASE + 0x44) /* 8044 */ +#define WF_PSE_TOP_C_EN_QUEUE_0_ADDR \ + (WF_PSE_TOP_BASE + 0x60) /* 8060 */ +#define WF_PSE_TOP_C_EN_QUEUE_1_ADDR \ + (WF_PSE_TOP_BASE + 0x64) /* 8064 */ +#define WF_PSE_TOP_C_EN_QUEUE_2_ADDR \ + (WF_PSE_TOP_BASE + 0x68) /* 8068 */ +#define WF_PSE_TOP_C_DE_QUEUE_0_ADDR \ + (WF_PSE_TOP_BASE + 0x80) /* 8080 */ +#define WF_PSE_TOP_C_DE_QUEUE_1_ADDR \ + (WF_PSE_TOP_BASE + 0x84) /* 8084 */ +#define WF_PSE_TOP_C_DE_QUEUE_2_ADDR \ + (WF_PSE_TOP_BASE + 0x88) /* 8088 */ +#define WF_PSE_TOP_C_DE_QUEUE_3_ADDR \ + (WF_PSE_TOP_BASE + 0x8c) /* 808C */ +#define WF_PSE_TOP_C_DE_QUEUE_4_ADDR \ + (WF_PSE_TOP_BASE + 0x90) /* 8090 */ +#define WF_PSE_TOP_ALLOCATE_0_ADDR \ + (WF_PSE_TOP_BASE + 0xA0) /* 80A0 */ +#define WF_PSE_TOP_ALLOCATE_1_ADDR \ + (WF_PSE_TOP_BASE + 0xA4) /* 80A4 */ +#define WF_PSE_TOP_QUEUE_EMPTY_ADDR \ + (WF_PSE_TOP_BASE + 0xB0) /* 80B0 */ +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_ADDR \ + (WF_PSE_TOP_BASE + 0xB4) /* 80B4 */ +#define WF_PSE_TOP_FREEPG_START_END_ADDR \ + (WF_PSE_TOP_BASE + 0xC0) /* 80C0 */ +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_ADDR \ + (WF_PSE_TOP_BASE + 0xc4) /* 80C4 */ +#define WF_PSE_TOP_TO_N9_INT_ADDR (WF_PSE_TOP_BASE + 0xf0) /* 80F0 */ +#define WF_PSE_TOP_FREEPG_CNT_ADDR \ + (WF_PSE_TOP_BASE + 0x100) /* 8100 */ +#define WF_PSE_TOP_FREEPG_HEAD_TAIL_ADDR \ + (WF_PSE_TOP_BASE + 0x104) /* 8104 */ +#define WF_PSE_TOP_GROUP_REFILL_CTRL_ADDR \ + (WF_PSE_TOP_BASE + 0x108) /* 8108 */ +#define WF_PSE_TOP_PG_HIF0_GROUP_ADDR \ + (WF_PSE_TOP_BASE + 0x110) /* 8110 */ +#define WF_PSE_TOP_HIF0_PG_INFO_ADDR \ + (WF_PSE_TOP_BASE + 0x114) /* 8114 */ +#define WF_PSE_TOP_PG_HIF1_GROUP_ADDR \ + (WF_PSE_TOP_BASE + 0x118) /* 8118 */ +#define WF_PSE_TOP_HIF1_PG_INFO_ADDR \ + (WF_PSE_TOP_BASE + 0x11C) /* 811C */ +#define WF_PSE_TOP_PG_CPU_GROUP_ADDR \ + (WF_PSE_TOP_BASE + 0x150) /* 8150 */ +#define WF_PSE_TOP_CPU_PG_INFO_ADDR \ + (WF_PSE_TOP_BASE + 0x154) /* 8154 */ +#define WF_PSE_TOP_PG_PLE_GROUP_ADDR \ + (WF_PSE_TOP_BASE + 0x160) /* 8160 */ +#define WF_PSE_TOP_PLE_PG_INFO_ADDR \ + (WF_PSE_TOP_BASE + 0x164) /* 8164 */ +#define WF_PSE_TOP_PG_PLE1_GROUP_ADDR \ + (WF_PSE_TOP_BASE + 0x168) /* 8168 */ +#define WF_PSE_TOP_PLE1_PG_INFO_ADDR \ + (WF_PSE_TOP_BASE + 0x16C) /* 816C */ +#define WF_PSE_TOP_PG_LMAC0_GROUP_ADDR \ + (WF_PSE_TOP_BASE + 0x170) /* 8170 */ +#define WF_PSE_TOP_LMAC0_PG_INFO_ADDR \ + (WF_PSE_TOP_BASE + 0x174) /* 8174 */ +#define WF_PSE_TOP_PG_LMAC1_GROUP_ADDR \ + (WF_PSE_TOP_BASE + 0x178) /* 8178 */ +#define WF_PSE_TOP_LMAC1_PG_INFO_ADDR \ + (WF_PSE_TOP_BASE + 0x17C) /* 817C */ +#define WF_PSE_TOP_PG_LMAC2_GROUP_ADDR \ + (WF_PSE_TOP_BASE + 0x180) /* 8180 */ +#define WF_PSE_TOP_LMAC2_PG_INFO_ADDR \ + (WF_PSE_TOP_BASE + 0x184) /* 8184 */ +#define WF_PSE_TOP_PG_LMAC3_GROUP_ADDR \ + (WF_PSE_TOP_BASE + 0x188) /* 8188 */ +#define WF_PSE_TOP_LMAC3_PG_INFO_ADDR \ + (WF_PSE_TOP_BASE + 0x18C) /* 818C */ +#define WF_PSE_TOP_PG_MDP_GROUP_ADDR \ + (WF_PSE_TOP_BASE + 0x198) /* 8198 */ +#define WF_PSE_TOP_MDP_PG_INFO_ADDR \ + (WF_PSE_TOP_BASE + 0x19C) /* 819C */ +#define WF_PSE_TOP_RL_BUF_CTRL_0_ADDR \ + (WF_PSE_TOP_BASE + 0x1A0) /* 81A0 */ +#define WF_PSE_TOP_RL_BUF_CTRL_1_ADDR \ + (WF_PSE_TOP_BASE + 0x1A4) /* 81A4 */ +#define WF_PSE_TOP_FL_QUE_CTRL_0_ADDR \ + (WF_PSE_TOP_BASE + 0x1B0) /* 81B0 */ +#define WF_PSE_TOP_FL_QUE_CTRL_1_ADDR \ + (WF_PSE_TOP_BASE + 0x1B4) /* 81B4 */ +#define WF_PSE_TOP_FL_QUE_CTRL_2_ADDR \ + (WF_PSE_TOP_BASE + 0x1B8) /* 81B8 */ +#define WF_PSE_TOP_FL_QUE_CTRL_3_ADDR \ + (WF_PSE_TOP_BASE + 0x1BC) /* 81BC */ +#define WF_PSE_TOP_PL_QUE_CTRL_0_ADDR \ + (WF_PSE_TOP_BASE + 0x1C0) /* 81C0 */ +#define WF_PSE_TOP_PSE_LP_CTRL_ADDR \ + (WF_PSE_TOP_BASE + 0x1D0) /* 81D0 */ +#define WF_PSE_TOP_PSE_WFDMA_BUF_CTRL_ADDR \ + (WF_PSE_TOP_BASE + 0x1E0) /* 81E0 */ +#define WF_PSE_TOP_PSE_CT_PRI_CTRL_ADDR \ + (WF_PSE_TOP_BASE + 0x1EC) /* 81EC */ +#define WF_PSE_TOP_PLE_ENQ_PKT_NUM_ADDR \ + (WF_PSE_TOP_BASE + 0x1F0) /* 81F0 */ +#define WF_PSE_TOP_CPU_ENQ_PKT_NUM_ADDR \ + (WF_PSE_TOP_BASE + 0x1F4) /* 81F4 */ +#define WF_PSE_TOP_LMAC_ENQ_PKT_NUM_ADDR \ + (WF_PSE_TOP_BASE + 0x1F8) /* 81F8 */ +#define WF_PSE_TOP_HIF_ENQ_PKT_NUM_ADDR \ + (WF_PSE_TOP_BASE + 0x1FC) /* 81FC */ +#define WF_PSE_TOP_MDP_ENQ_PKT_NUM_ADDR \ + (WF_PSE_TOP_BASE + 0x200) /* 8200 */ +#define WF_PSE_TOP_TIMEOUT_CTRL_ADDR \ + (WF_PSE_TOP_BASE + 0x244) /* 8244 */ +#define WF_PSE_TOP_FSM_IDLE_WD_CTRL_ADDR \ + (WF_PSE_TOP_BASE + 0x24C) /* 824C */ +#define WF_PSE_TOP_FSM_IDLE_WD_EN_ADDR \ + (WF_PSE_TOP_BASE + 0x250) /* 8250 */ +#define WF_PSE_TOP_PSE_INTER_ERR_FLAG_ADDR \ + (WF_PSE_TOP_BASE + 0x280) /* 8280 */ +#define WF_PSE_TOP_PSE_SER_CTRL_ADDR \ + (WF_PSE_TOP_BASE + 0x2a0) /* 82A0 */ +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_ADDR \ + (WF_PSE_TOP_BASE + 0x2b0) /* 82B0 */ +#define WF_PSE_TOP_PSE_MBIST_BSEL_ADDR \ + (WF_PSE_TOP_BASE + 0x2b4) /* 82B4 */ +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_1_ADDR \ + (WF_PSE_TOP_BASE + 0x2b8) /* 82B8 */ +#define WF_PSE_TOP_SRAM_MBIST_BACKGROUND_ADDR \ + (WF_PSE_TOP_BASE + 0x2d0) /* 82D0 */ +#define WF_PSE_TOP_PSE_MISC_FUNC_CTRL_ADDR \ + (WF_PSE_TOP_BASE + 0x2d4) /* 82D4 */ +#define WF_PSE_TOP_SRAM_MBIST_DONE_ADDR \ + (WF_PSE_TOP_BASE + 0x2d8) /* 82D8 */ +#define WF_PSE_TOP_SRAM_MBIST_FAIL_ADDR \ + (WF_PSE_TOP_BASE + 0x2dc) /* 82DC */ +#define WF_PSE_TOP_SRAM_MBIST_CTRL_ADDR \ + (WF_PSE_TOP_BASE + 0x2e0) /* 82E0 */ +#define WF_PSE_TOP_SRAM_MBIST_DELSEL_ADDR \ + (WF_PSE_TOP_BASE + 0x2e4) /* 82E4 */ +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_ADDR \ + (WF_PSE_TOP_BASE + 0x2e8) /* 82E8 */ +#define WF_PSE_TOP_SRAM_MBIST_DELSEL_1_ADDR \ + (WF_PSE_TOP_BASE + 0x2f0) /* 82F0 */ +#define WF_PSE_TOP_PSE_SEEK_CR_00_ADDR \ + (WF_PSE_TOP_BASE + 0x3d0) /* 83D0 */ +#define WF_PSE_TOP_PSE_SEEK_CR_01_ADDR \ + (WF_PSE_TOP_BASE + 0x3d4) /* 83D4 */ +#define WF_PSE_TOP_PSE_SEEK_CR_02_ADDR \ + (WF_PSE_TOP_BASE + 0x3d8) /* 83D8 */ +#define WF_PSE_TOP_PSE_SEEK_CR_03_ADDR \ + (WF_PSE_TOP_BASE + 0x3dc) /* 83DC */ +#define WF_PSE_TOP_PSE_SEEK_CR_04_ADDR \ + (WF_PSE_TOP_BASE + 0x3e0) /* 83E0 */ +#define WF_PSE_TOP_PSE_SEEK_CR_05_ADDR \ + (WF_PSE_TOP_BASE + 0x3e4) /* 83E4 */ +#define WF_PSE_TOP_PSE_SEEK_CR_06_ADDR \ + (WF_PSE_TOP_BASE + 0x3e8) /* 83E8 */ +#define WF_PSE_TOP_PSE_SEEK_CR_07_ADDR \ + (WF_PSE_TOP_BASE + 0x3ec) /* 83EC */ +#define WF_PSE_TOP_PSE_SEEK_CR_08_ADDR \ + (WF_PSE_TOP_BASE + 0x3f0) /* 83F0 */ +#define WF_PSE_TOP_PSE_SEEK_CR_09_ADDR \ + (WF_PSE_TOP_BASE + 0x3f4) /* 83F4 */ + +/* +* ---GC (0x820C8000 + 0x00)--- +* ALL_RESET[0] - (RW) Resets PSE logic and register +* LOGIC_RESET[1] - (RW) Resets PSE logic circuit +* INIT_DONE[2] - (RO) PSE control SRAM initialization +indicator +* RESERVED3[15..3] - (RO) Reserved bits +* SRAM_MBIST_RESET[16] - (RW) Reset control of SRAM MBIST (low active) +* RESERVED17[17] - (RO) Reserved bits +* DIS_PSE_DYN_CKG[18] - (RW) Disable control of wf_pse_top dynamic +* clock gating function +* RESERVED19[31..19] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_GC_DIS_PSE_DYN_CKG_ADDR WF_PSE_TOP_GC_ADDR +#define WF_PSE_TOP_GC_DIS_PSE_DYN_CKG_MASK \ + 0x00040000 /* DIS_PSE_DYN_CKG[18] */ +#define WF_PSE_TOP_GC_DIS_PSE_DYN_CKG_SHFT 18 +#define WF_PSE_TOP_GC_SRAM_MBIST_RESET_ADDR WF_PSE_TOP_GC_ADDR +#define WF_PSE_TOP_GC_SRAM_MBIST_RESET_MASK \ + 0x00010000 /* SRAM_MBIST_RESET[16] */ +#define WF_PSE_TOP_GC_SRAM_MBIST_RESET_SHFT 16 +#define WF_PSE_TOP_GC_INIT_DONE_ADDR WF_PSE_TOP_GC_ADDR +#define WF_PSE_TOP_GC_INIT_DONE_MASK 0x00000004 /* INIT_DONE[2] */ +#define WF_PSE_TOP_GC_INIT_DONE_SHFT 2 +#define WF_PSE_TOP_GC_LOGIC_RESET_ADDR WF_PSE_TOP_GC_ADDR +#define WF_PSE_TOP_GC_LOGIC_RESET_MASK 0x00000002 /* LOGIC_RESET[1] */ +#define WF_PSE_TOP_GC_LOGIC_RESET_SHFT 1 +#define WF_PSE_TOP_GC_ALL_RESET_ADDR WF_PSE_TOP_GC_ADDR +#define WF_PSE_TOP_GC_ALL_RESET_MASK 0x00000001 /* ALL_RESET[0] */ +#define WF_PSE_TOP_GC_ALL_RESET_SHFT 0 + +/* +* ---PBUF_CTRL (0x820C8000 + 0x14)--- +* TOTAL_PAGE_NUM[11..0] - (RW) Total page numbers +* Set the total page before release PSE logic +* reset, and must not be changed after release logic reset. +* RESERVED12[16..12] - (RO) Reserved bits +* PBUF_OFFSET[25..17] - (RW) Packet buffer offset. +* Set the buffer offset before release PSE +* logic reset, and must not be changed after release logic reset. +* RESERVED26[30..26] - (RO) Reserved bits +* PAGE_SIZE_CFG[31] - (RW) Configures page size +* Set up the page size before releasing PSE +* logic reset; it should not be changed after logic reset is released. +*/ +#define WF_PSE_TOP_PBUF_CTRL_PAGE_SIZE_CFG_ADDR \ + WF_PSE_TOP_PBUF_CTRL_ADDR +#define WF_PSE_TOP_PBUF_CTRL_PAGE_SIZE_CFG_MASK \ + 0x80000000 /* PAGE_SIZE_CFG[31] */ +#define WF_PSE_TOP_PBUF_CTRL_PAGE_SIZE_CFG_SHFT 31 +#define WF_PSE_TOP_PBUF_CTRL_PBUF_OFFSET_ADDR \ + WF_PSE_TOP_PBUF_CTRL_ADDR +#define WF_PSE_TOP_PBUF_CTRL_PBUF_OFFSET_MASK \ + 0x03FE0000 /* PBUF_OFFSET[25..17] */ +#define WF_PSE_TOP_PBUF_CTRL_PBUF_OFFSET_SHFT 17 +#define WF_PSE_TOP_PBUF_CTRL_TOTAL_PAGE_NUM_ADDR \ + WF_PSE_TOP_PBUF_CTRL_ADDR +#define WF_PSE_TOP_PBUF_CTRL_TOTAL_PAGE_NUM_MASK \ + 0x00000FFF /* TOTAL_PAGE_NUM[11..0] */ +#define WF_PSE_TOP_PBUF_CTRL_TOTAL_PAGE_NUM_SHFT 0 + +/* +* ---INT_N9_EN_MASK (0x820C8000 + 0x20)--- +* EN_CPU_Q0_NE[0] - (RW) CPU queue 0 not empty interrupt +* EN_CPU_Q1_NE[1] - (RW) CPU queue 1 not empty interrupt +* EN_CPU_Q2_NE[2] - (RW) CPU queue 2 not empty interrupt +* EN_CPU_Q3_NE[3] - (RW) CPU queue 3 not empty interrupt +* RESERVED4[11..4] - (RO) Reserved bits +* EN_LMAC_ENQ[12] - (RW) Enables LMAC enq interrupt +* EN_ERROR_INT[13] - (RW) Error condition interrupt status +* RESERVED14[15..14] - (RO) Reserved bits +* EN_TOGGLE_INT[16] - (RW) Data toggle of CR4 toggle register +(0xe0) +* EN_LMAC_EMPTY_FALL[17] - (RW) LMAC Buffer empty fall edge detect +* EN_LMAC_EMPTY_RAISE[18] - (RW) LMAC Buffer empty raise edge detect +* EN_HIF_Q0_NE[19] - (RW) HIF queue 0 not empty interrupt +* EN_HIF_Q1_NE[20] - (RW) HIF queue 1 not empty interrupt +* EN_HIF_Q2_NE[21] - (RW) HIF queue 2 not empty interrupt +* EN_HIF_Q3_NE[22] - (RW) HIF queue 3 not empty interrupt +* EN_HIF_Q4_NE[23] - (RW) HIF queue 4 not empty interrupt +* EN_HIF_Q5_NE[24] - (RW) HIF queue 5 not empty interrupt +* EN_HIF_Q6_NE[25] - (RW) HIF queue 6 not empty interrupt +* EN_HIF_Q7_NE[26] - (RW) HIF queue 7 not empty interrupt +* EN_HIF_Q8_NE[27] - (RW) HIF queue 8 not empty interrupt +* EN_HIF_Q9_NE[28] - (RW) HIF queue 9 not empty interrupt +* EN_HIF_Q10_NE[29] - (RW) HIF queue 10 not empty interrupt +* EN_HIF_Q11_NE[30] - (RW) HIF queue 11 not empty interrupt +* RESERVED31[31] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q11_NE_ADDR \ + WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q11_NE_MASK \ + 0x40000000 /* EN_HIF_Q11_NE[30] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q11_NE_SHFT 30 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q10_NE_ADDR \ + WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q10_NE_MASK \ + 0x20000000 /* EN_HIF_Q10_NE[29] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q10_NE_SHFT 29 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q9_NE_ADDR \ + WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q9_NE_MASK \ + 0x10000000 /* EN_HIF_Q9_NE[28] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q9_NE_SHFT 28 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q8_NE_ADDR \ + WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q8_NE_MASK \ + 0x08000000 /* EN_HIF_Q8_NE[27] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q8_NE_SHFT 27 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q7_NE_ADDR \ + WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q7_NE_MASK \ + 0x04000000 /* EN_HIF_Q7_NE[26] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q7_NE_SHFT 26 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q6_NE_ADDR \ + WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q6_NE_MASK \ + 0x02000000 /* EN_HIF_Q6_NE[25] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q6_NE_SHFT 25 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q5_NE_ADDR \ + WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q5_NE_MASK \ + 0x01000000 /* EN_HIF_Q5_NE[24] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q5_NE_SHFT 24 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q4_NE_ADDR \ + WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q4_NE_MASK \ + 0x00800000 /* EN_HIF_Q4_NE[23] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q4_NE_SHFT 23 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q3_NE_ADDR \ + WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q3_NE_MASK \ + 0x00400000 /* EN_HIF_Q3_NE[22] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q3_NE_SHFT 22 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q2_NE_ADDR \ + WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q2_NE_MASK \ + 0x00200000 /* EN_HIF_Q2_NE[21] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q2_NE_SHFT 21 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q1_NE_ADDR \ + WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q1_NE_MASK \ + 0x00100000 /* EN_HIF_Q1_NE[20] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q1_NE_SHFT 20 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q0_NE_ADDR \ + WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q0_NE_MASK \ + 0x00080000 /* EN_HIF_Q0_NE[19] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_HIF_Q0_NE_SHFT 19 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_LMAC_EMPTY_RAISE_ADDR \ + WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_LMAC_EMPTY_RAISE_MASK \ + 0x00040000 /* EN_LMAC_EMPTY_RAISE[18] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_LMAC_EMPTY_RAISE_SHFT 18 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_LMAC_EMPTY_FALL_ADDR \ + WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_LMAC_EMPTY_FALL_MASK \ + 0x00020000 /* EN_LMAC_EMPTY_FALL[17] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_LMAC_EMPTY_FALL_SHFT 17 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_TOGGLE_INT_ADDR \ + WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_TOGGLE_INT_MASK \ + 0x00010000 /* EN_TOGGLE_INT[16] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_TOGGLE_INT_SHFT 16 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_ERROR_INT_ADDR \ + WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_ERROR_INT_MASK \ + 0x00002000 /* EN_ERROR_INT[13] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_ERROR_INT_SHFT 13 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_LMAC_ENQ_ADDR \ + WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_LMAC_ENQ_MASK \ + 0x00001000 /* EN_LMAC_ENQ[12] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_LMAC_ENQ_SHFT 12 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_CPU_Q3_NE_ADDR \ + WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_CPU_Q3_NE_MASK \ + 0x00000008 /* EN_CPU_Q3_NE[3] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_CPU_Q3_NE_SHFT 3 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_CPU_Q2_NE_ADDR \ + WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_CPU_Q2_NE_MASK \ + 0x00000004 /* EN_CPU_Q2_NE[2] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_CPU_Q2_NE_SHFT 2 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_CPU_Q1_NE_ADDR \ + WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_CPU_Q1_NE_MASK \ + 0x00000002 /* EN_CPU_Q1_NE[1] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_CPU_Q1_NE_SHFT 1 +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_CPU_Q0_NE_ADDR \ + WF_PSE_TOP_INT_N9_EN_MASK_ADDR +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_CPU_Q0_NE_MASK \ + 0x00000001 /* EN_CPU_Q0_NE[0] */ +#define WF_PSE_TOP_INT_N9_EN_MASK_EN_CPU_Q0_NE_SHFT 0 + +/* +* ---INT_N9_STS (0x820C8000 + 0x24)--- +* CPU_Q0_NE[0] - (W1C) CPU queue 0 not empty interrupt status +* CPU_Q1_NE[1] - (W1C) CPU queue 1 not empty interrupt status +* CPU_Q2_NE[2] - (W1C) CPU queue 2 not empty interrupt status +* CPU_Q3_NE[3] - (W1C) CPU queue 3 not empty interrupt status +* RESERVED4[11..4] - (RO) Reserved bits +* LMAC_ENQ[12] - (W1C) LMAC enq interrupt status +* ERROR_INT[13] - (RO) Error condition interrupt status +* ERROR_1_INT[14] - (RO) Error condition interrupt status +* RESERVED15[15] - (RO) Reserved bits +* DATA_TOGGLE[16] - (W1C) Data toggle of CR4 toggle register +(0xe0) +* LMAC_EMPTY_FALL[17] - (W1C) LMAC Buffer empty fall edge detect +* LMAC_EMPTY_RAISE[18] - (W1C) LMAC Buffer empty raise edge detect +* HIF_Q0_NE[19] - (W1C) HIF queue 0 not empty interrupt status +* HIF_Q1_NE[20] - (W1C) HIF queue 1 not empty interrupt status +* HIF_Q2_NE[21] - (W1C) HIF queue 2 not empty interrupt status +* HIF_Q3_NE[22] - (W1C) HIF queue 3 not empty interrupt status +* HIF_Q4_NE[23] - (W1C) HIF queue 4 not empty interrupt status +* HIF_Q5_NE[24] - (W1C) HIF queue 5 not empty interrupt status +* HIF_Q6_NE[25] - (W1C) HIF queue 6 not empty interrupt status +* HIF_Q7_NE[26] - (W1C) HIF queue 7 not empty interrupt status +* HIF_Q8_NE[27] - (W1C) HIF queue 8 not empty interrupt status +* HIF_Q9_NE[28] - (W1C) HIF queue 9 not empty interrupt status +* HIF_Q10_NE[29] - (W1C) HIF queue 10 not empty interrupt status +* HIF_Q11_NE[30] - (W1C) HIF queue 11 not empty interrupt status +* RESERVED31[31] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_INT_N9_STS_HIF_Q11_NE_ADDR \ + WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_HIF_Q11_NE_MASK \ + 0x40000000 /* HIF_Q11_NE[30] */ +#define WF_PSE_TOP_INT_N9_STS_HIF_Q11_NE_SHFT 30 +#define WF_PSE_TOP_INT_N9_STS_HIF_Q10_NE_ADDR \ + WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_HIF_Q10_NE_MASK \ + 0x20000000 /* HIF_Q10_NE[29] */ +#define WF_PSE_TOP_INT_N9_STS_HIF_Q10_NE_SHFT 29 +#define WF_PSE_TOP_INT_N9_STS_HIF_Q9_NE_ADDR \ + WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_HIF_Q9_NE_MASK \ + 0x10000000 /* HIF_Q9_NE[28] */ +#define WF_PSE_TOP_INT_N9_STS_HIF_Q9_NE_SHFT 28 +#define WF_PSE_TOP_INT_N9_STS_HIF_Q8_NE_ADDR \ + WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_HIF_Q8_NE_MASK \ + 0x08000000 /* HIF_Q8_NE[27] */ +#define WF_PSE_TOP_INT_N9_STS_HIF_Q8_NE_SHFT 27 +#define WF_PSE_TOP_INT_N9_STS_HIF_Q7_NE_ADDR \ + WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_HIF_Q7_NE_MASK \ + 0x04000000 /* HIF_Q7_NE[26] */ +#define WF_PSE_TOP_INT_N9_STS_HIF_Q7_NE_SHFT 26 +#define WF_PSE_TOP_INT_N9_STS_HIF_Q6_NE_ADDR \ + WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_HIF_Q6_NE_MASK \ + 0x02000000 /* HIF_Q6_NE[25] */ +#define WF_PSE_TOP_INT_N9_STS_HIF_Q6_NE_SHFT 25 +#define WF_PSE_TOP_INT_N9_STS_HIF_Q5_NE_ADDR \ + WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_HIF_Q5_NE_MASK \ + 0x01000000 /* HIF_Q5_NE[24] */ +#define WF_PSE_TOP_INT_N9_STS_HIF_Q5_NE_SHFT 24 +#define WF_PSE_TOP_INT_N9_STS_HIF_Q4_NE_ADDR \ + WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_HIF_Q4_NE_MASK \ + 0x00800000 /* HIF_Q4_NE[23] */ +#define WF_PSE_TOP_INT_N9_STS_HIF_Q4_NE_SHFT 23 +#define WF_PSE_TOP_INT_N9_STS_HIF_Q3_NE_ADDR \ + WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_HIF_Q3_NE_MASK \ + 0x00400000 /* HIF_Q3_NE[22] */ +#define WF_PSE_TOP_INT_N9_STS_HIF_Q3_NE_SHFT 22 +#define WF_PSE_TOP_INT_N9_STS_HIF_Q2_NE_ADDR \ + WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_HIF_Q2_NE_MASK \ + 0x00200000 /* HIF_Q2_NE[21] */ +#define WF_PSE_TOP_INT_N9_STS_HIF_Q2_NE_SHFT 21 +#define WF_PSE_TOP_INT_N9_STS_HIF_Q1_NE_ADDR \ + WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_HIF_Q1_NE_MASK \ + 0x00100000 /* HIF_Q1_NE[20] */ +#define WF_PSE_TOP_INT_N9_STS_HIF_Q1_NE_SHFT 20 +#define WF_PSE_TOP_INT_N9_STS_HIF_Q0_NE_ADDR \ + WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_HIF_Q0_NE_MASK \ + 0x00080000 /* HIF_Q0_NE[19] */ +#define WF_PSE_TOP_INT_N9_STS_HIF_Q0_NE_SHFT 19 +#define WF_PSE_TOP_INT_N9_STS_LMAC_EMPTY_RAISE_ADDR \ + WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_LMAC_EMPTY_RAISE_MASK \ + 0x00040000 /* LMAC_EMPTY_RAISE[18] */ +#define WF_PSE_TOP_INT_N9_STS_LMAC_EMPTY_RAISE_SHFT 18 +#define WF_PSE_TOP_INT_N9_STS_LMAC_EMPTY_FALL_ADDR \ + WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_LMAC_EMPTY_FALL_MASK \ + 0x00020000 /* LMAC_EMPTY_FALL[17] */ +#define WF_PSE_TOP_INT_N9_STS_LMAC_EMPTY_FALL_SHFT 17 +#define WF_PSE_TOP_INT_N9_STS_DATA_TOGGLE_ADDR \ + WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_DATA_TOGGLE_MASK \ + 0x00010000 /* DATA_TOGGLE[16] */ +#define WF_PSE_TOP_INT_N9_STS_DATA_TOGGLE_SHFT 16 +#define WF_PSE_TOP_INT_N9_STS_ERROR_1_INT_ADDR \ + WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_ERROR_1_INT_MASK \ + 0x00004000 /* ERROR_1_INT[14] */ +#define WF_PSE_TOP_INT_N9_STS_ERROR_1_INT_SHFT 14 +#define WF_PSE_TOP_INT_N9_STS_ERROR_INT_ADDR \ + WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_ERROR_INT_MASK \ + 0x00002000 /* ERROR_INT[13] */ +#define WF_PSE_TOP_INT_N9_STS_ERROR_INT_SHFT 13 +#define WF_PSE_TOP_INT_N9_STS_LMAC_ENQ_ADDR WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_LMAC_ENQ_MASK \ + 0x00001000 /* LMAC_ENQ[12] */ +#define WF_PSE_TOP_INT_N9_STS_LMAC_ENQ_SHFT 12 +#define WF_PSE_TOP_INT_N9_STS_CPU_Q3_NE_ADDR \ + WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_CPU_Q3_NE_MASK \ + 0x00000008 /* CPU_Q3_NE[3] */ +#define WF_PSE_TOP_INT_N9_STS_CPU_Q3_NE_SHFT 3 +#define WF_PSE_TOP_INT_N9_STS_CPU_Q2_NE_ADDR \ + WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_CPU_Q2_NE_MASK \ + 0x00000004 /* CPU_Q2_NE[2] */ +#define WF_PSE_TOP_INT_N9_STS_CPU_Q2_NE_SHFT 2 +#define WF_PSE_TOP_INT_N9_STS_CPU_Q1_NE_ADDR \ + WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_CPU_Q1_NE_MASK \ + 0x00000002 /* CPU_Q1_NE[1] */ +#define WF_PSE_TOP_INT_N9_STS_CPU_Q1_NE_SHFT 1 +#define WF_PSE_TOP_INT_N9_STS_CPU_Q0_NE_ADDR \ + WF_PSE_TOP_INT_N9_STS_ADDR +#define WF_PSE_TOP_INT_N9_STS_CPU_Q0_NE_MASK \ + 0x00000001 /* CPU_Q0_NE[0] */ +#define WF_PSE_TOP_INT_N9_STS_CPU_Q0_NE_SHFT 0 + +/* +* ---INT_N9_ERR_STS (0x820C8000 + 0x28)--- +* Q_CMD_ERR_P0[0] - (W1C) Queue command error interrupt status of +* port 0. Avoid unclear error flag, please clear flag when logic +reset. +* Q_CMD_ERR_P1[1] - (W1C) Queue command error interrupt status of +* port 1. Avoid unclear error flag, please clear flag when logic +reset. +* Q_CMD_ERR_P2[2] - (W1C) Queue command error interrupt status of +* port 2. Avoid unclear error flag, please clear flag when logic +reset. +* Q_CMD_ERR_P3[3] - (W1C) Queue command error interrupt status of +* port 3. Avoid unclear error flag, please clear flag when logic +reset. +* Q_CMD_ERR_P4[4] - (W1C) Queue command error interrupt status of +* port 4. Avoid unclear error flag, please clear flag when logic +reset. +* Q_CMD_ERR_P5[5] - (W1C) Queue command error interrupt status of +* port 5. Avoid unclear error flag, please clear flag when logic +reset. +* Q_CMD_ERR_P6[6] - (W1C) Queue command error interrupt status of +* port 6. Avoid unclear error flag, please clear flag when logic +reset. +* RESERVED7[7] - (RO) Reserved bits +* PAGE_UDF_P0[8] - (W1C) Page underflow interrupt status of port +* 0. Avoid unclear error flag, please clear flag when logic reset. +* PAGE_UDF_P1[9] - (W1C) Page underflow interrupt status of port +* 1. Avoid unclear error flag, please clear flag when logic reset. +* PAGE_UDF_P2[10] - (W1C) Page underflow interrupt status of port +* 2. Avoid unclear error flag, please clear flag when logic reset. +* PAGE_UDF_P3[11] - (W1C) Page underflow interrupt status of port +* 3. Avoid unclear error flag, please clear flag when logic reset. +* PAGE_UDF_P4[12] - (W1C) Page underflow interrupt status of port +* 4. Avoid unclear error flag, please clear flag when logic reset. +* PAGE_UDF_P5[13] - (W1C) Page underflow interrupt status of port +* 5. Avoid unclear error flag, please clear flag when logic reset. +* PAGE_UDF_P6[14] - (W1C) Page underflow interrupt status of port +* 6. Avoid unclear error flag, please clear flag when logic reset. +* RESERVED15[15] - (RO) Reserved bits +* QUEUE_OPER_ERR_P0[16] - (W1C) Queue operation error of port 0. Avoid +* unclear error flag, please clear flag when logic reset. +* QUEUE_OPER_ERR_P1[17] - (W1C) Queue operation error of port 1. Avoid +* unclear error flag, please clear flag when logic reset. +* QUEUE_OPER_ERR_P2[18] - (W1C) Queue operation error of port 2. Avoid +* unclear error flag, please clear flag when logic reset. +* QUEUE_OPER_ERR_P3[19] - (W1C) Queue operation error of port 3. Avoid +* unclear error flag, please clear flag when logic reset. +* QUEUE_OPER_ERR_P4[20] - (W1C) Queue operation error of port 4. Avoid +* unclear error flag, please clear flag when logic reset. +* QUEUE_OPER_ERR_P5[21] - (W1C) Queue operation error of port 5. Avoid +* unclear error flag, please clear flag when logic reset. +* QUEUE_OPER_ERR_P6[22] - (W1C) Queue operation error of port 6. Avoid +* unclear error flag, please clear flag when logic reset. +* RESERVED23[23] - (RO) Reserved bits +* DATA_OPER_ERR_P0[24] - (W1C) Data operation error of port 0. Avoid +* unclear error flag, please clear flag when logic reset. +* DATA_OPER_ERR_P1[25] - (W1C) Data operation error of port 1. Avoid +* unclear error flag, please clear flag when logic reset. +* DATA_OPER_ERR_P2[26] - (W1C) Data operation error of port 2. Avoid +* unclear error flag, please clear flag when logic reset. +* DATA_OPER_ERR_P3[27] - (W1C) Data operation error of port 3. Avoid +* unclear error flag, please clear flag when logic reset. +* DATA_OPER_ERR_P4[28] - (W1C) Data operation error of port 4. Avoid +* unclear error flag, please clear flag when logic reset. +* DATA_OPER_ERR_P5[29] - (W1C) Data operation error of port 5. Avoid +* unclear error flag, please clear flag when logic reset. +* DATA_OPER_ERR_P6[30] - (W1C) Data operation error of port 6. Avoid +* unclear error flag, please clear flag when logic reset. +* RESERVED31[31] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P6_ADDR \ + WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P6_MASK \ + 0x40000000 /* DATA_OPER_ERR_P6[30] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P6_SHFT 30 +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P5_ADDR \ + WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P5_MASK \ + 0x20000000 /* DATA_OPER_ERR_P5[29] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P5_SHFT 29 +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P4_ADDR \ + WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P4_MASK \ + 0x10000000 /* DATA_OPER_ERR_P4[28] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P4_SHFT 28 +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P3_ADDR \ + WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P3_MASK \ + 0x08000000 /* DATA_OPER_ERR_P3[27] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P3_SHFT 27 +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P2_ADDR \ + WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P2_MASK \ + 0x04000000 /* DATA_OPER_ERR_P2[26] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P2_SHFT 26 +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P1_ADDR \ + WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P1_MASK \ + 0x02000000 /* DATA_OPER_ERR_P1[25] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P1_SHFT 25 +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P0_ADDR \ + WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P0_MASK \ + 0x01000000 /* DATA_OPER_ERR_P0[24] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_DATA_OPER_ERR_P0_SHFT 24 +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P6_ADDR \ + WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P6_MASK \ + 0x00400000 /* QUEUE_OPER_ERR_P6[22] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P6_SHFT 22 +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P5_ADDR \ + WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P5_MASK \ + 0x00200000 /* QUEUE_OPER_ERR_P5[21] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P5_SHFT 21 +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P4_ADDR \ + WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P4_MASK \ + 0x00100000 /* QUEUE_OPER_ERR_P4[20] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P4_SHFT 20 +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P3_ADDR \ + WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P3_MASK \ + 0x00080000 /* QUEUE_OPER_ERR_P3[19] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P3_SHFT 19 +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P2_ADDR \ + WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P2_MASK \ + 0x00040000 /* QUEUE_OPER_ERR_P2[18] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P2_SHFT 18 +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P1_ADDR \ + WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P1_MASK \ + 0x00020000 /* QUEUE_OPER_ERR_P1[17] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P1_SHFT 17 +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P0_ADDR \ + WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P0_MASK \ + 0x00010000 /* QUEUE_OPER_ERR_P0[16] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_QUEUE_OPER_ERR_P0_SHFT 16 +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P6_ADDR \ + WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P6_MASK \ + 0x00004000 /* PAGE_UDF_P6[14] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P6_SHFT 14 +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P5_ADDR \ + WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P5_MASK \ + 0x00002000 /* PAGE_UDF_P5[13] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P5_SHFT 13 +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P4_ADDR \ + WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P4_MASK \ + 0x00001000 /* PAGE_UDF_P4[12] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P4_SHFT 12 +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P3_ADDR \ + WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P3_MASK \ + 0x00000800 /* PAGE_UDF_P3[11] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P3_SHFT 11 +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P2_ADDR \ + WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P2_MASK \ + 0x00000400 /* PAGE_UDF_P2[10] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P2_SHFT 10 +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P1_ADDR \ + WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P1_MASK \ + 0x00000200 /* PAGE_UDF_P1[9] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P1_SHFT 9 +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P0_ADDR \ + WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P0_MASK \ + 0x00000100 /* PAGE_UDF_P0[8] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_PAGE_UDF_P0_SHFT 8 +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P6_ADDR \ + WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P6_MASK \ + 0x00000040 /* Q_CMD_ERR_P6[6] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P6_SHFT 6 +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P5_ADDR \ + WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P5_MASK \ + 0x00000020 /* Q_CMD_ERR_P5[5] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P5_SHFT 5 +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P4_ADDR \ + WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P4_MASK \ + 0x00000010 /* Q_CMD_ERR_P4[4] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P4_SHFT 4 +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P3_ADDR \ + WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P3_MASK \ + 0x00000008 /* Q_CMD_ERR_P3[3] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P3_SHFT 3 +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P2_ADDR \ + WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P2_MASK \ + 0x00000004 /* Q_CMD_ERR_P2[2] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P2_SHFT 2 +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P1_ADDR \ + WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P1_MASK \ + 0x00000002 /* Q_CMD_ERR_P1[1] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P1_SHFT 1 +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P0_ADDR \ + WF_PSE_TOP_INT_N9_ERR_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P0_MASK \ + 0x00000001 /* Q_CMD_ERR_P0[0] */ +#define WF_PSE_TOP_INT_N9_ERR_STS_Q_CMD_ERR_P0_SHFT 0 + +/* +* ---INT_N9_ERR_MASK (0x820C8000 + 0x2C)--- +* EN_Q_CMD_ERR_P0[0] - (RW) Enable Queue command error interrupt +* status of port 0. Avoid unclear error flag, please clear flag when +logic +reset. +* EN_Q_CMD_ERR_P1[1] - (RW) Enable Queue command error interrupt +* status of port 1. Avoid unclear error flag, please clear flag when +logic +reset. +* EN_Q_CMD_ERR_P2[2] - (RW) Enable Queue command error interrupt +* status of port 2. Avoid unclear error flag, please clear flag when +logic +reset. +* EN_Q_CMD_ERR_P3[3] - (RW) Enable Queue command error interrupt +* status of port 3. Avoid unclear error flag, please clear flag when +logic +reset. +* EN_Q_CMD_ERR_P4[4] - (RW) Enable Queue command error interrupt +* status of port 4. Avoid unclear error flag, please clear flag when +logic +reset. +* EN_Q_CMD_ERR_P5[5] - (RW) Enable Queue command error interrupt +* status of port 5. Avoid unclear error flag, please clear flag when +logic +reset. +* EN_Q_CMD_ERR_P6[6] - (RW) Enable Queue command error interrupt +* status of port 6. Avoid unclear error flag, please clear flag when +logic +reset. +* RESERVED7[7] - (RO) Reserved bits +* EN_PAGE_UDF_P0[8] - (RW) Enable Page underflow interrupt status +* of port 0. Avoid unclear error flag, please clear flag when logic +reset. +* EN_PAGE_UDF_P1[9] - (RW) Enable Page underflow interrupt status +* of port 1. Avoid unclear error flag, please clear flag when logic +reset. +* EN_PAGE_UDF_P2[10] - (RW) Enable Page underflow interrupt status +* of port 2. Avoid unclear error flag, please clear flag when logic +reset. +* EN_PAGE_UDF_P3[11] - (RW) Enable Page underflow interrupt status +* of port 3. Avoid unclear error flag, please clear flag when logic +reset. +* EN_PAGE_UDF_P4[12] - (RW) Enable Page underflow interrupt status +* of port 4. Avoid unclear error flag, please clear flag when logic +reset. +* EN_PAGE_UDF_P5[13] - (RW) Enable Page underflow interrupt status +* of port 5. Avoid unclear error flag, please clear flag when logic +reset. +* EN_PAGE_UDF_P6[14] - (RW) Enable Page underflow interrupt status +* of port 6. Avoid unclear error flag, please clear flag when logic +reset. +* RESERVED15[15] - (RO) Reserved bits +* EN_QUEUE_OPER_ERR_P0[16] - (RW) Enable Queue operation error of port +0. +* Avoid unclear error flag, please clear flag when logic reset. +* EN_QUEUE_OPER_ERR_P1[17] - (RW) Enable Queue operation error of port +1. +* Avoid unclear error flag, please clear flag when logic reset. +* EN_QUEUE_OPER_ERR_P2[18] - (RW) Enable Queue operation error of port +2. +* Avoid unclear error flag, please clear flag when logic reset. +* EN_QUEUE_OPER_ERR_P3[19] - (RW) Enable Queue operation error of port +3. +* Avoid unclear error flag, please clear flag when logic reset. +* EN_QUEUE_OPER_ERR_P4[20] - (RW) Enable Queue operation error of port +4. +* Avoid unclear error flag, please clear flag when logic reset. +* EN_QUEUE_OPER_ERR_P5[21] - (RW) Enable Queue operation error of port +5. +* Avoid unclear error flag, please clear flag when logic reset. +* EN_QUEUE_OPER_ERR_P6[22] - (RW) Enable Queue operation error of port +6. +* Avoid unclear error flag, please clear flag when logic reset. +* RESERVED23[23] - (RO) Reserved bits +* EN_DATA_OPER_ERR_P0[24] - (RW) Enable Data operation error of port +0. +* Avoid unclear error flag, please clear flag when logic reset. +* EN_DATA_OPER_ERR_P1[25] - (RW) Enable Data operation error of port +1. +* Avoid unclear error flag, please clear flag when logic reset. +* EN_DATA_OPER_ERR_P2[26] - (RW) Enable Data operation error of port +2. +* Avoid unclear error flag, please clear flag when logic reset. +* EN_DATA_OPER_ERR_P3[27] - (RW) Enable Data operation error of port +3. +* Avoid unclear error flag, please clear flag when logic reset. +* EN_DATA_OPER_ERR_P4[28] - (RW) Enable Data operation error of port +4. +* Avoid unclear error flag, please clear flag when logic reset. +* EN_DATA_OPER_ERR_P5[29] - (RW) Enable Data operation error of port +5. +* Avoid unclear error flag, please clear flag when logic reset. +* EN_DATA_OPER_EN_ERR_P6[30] - (RW) Enable Data operation error of +* port 6. +* Avoid unclear error flag, please clear flag when logic reset. +* RESERVED31[31] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_EN_ERR_P6_ADDR \ + WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_EN_ERR_P6_MASK \ + 0x40000000 /* EN_DATA_OPER_EN_ERR_P6[30] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_EN_ERR_P6_SHFT 30 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P5_ADDR \ + WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P5_MASK \ + 0x20000000 /* EN_DATA_OPER_ERR_P5[29] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P5_SHFT 29 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P4_ADDR \ + WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P4_MASK \ + 0x10000000 /* EN_DATA_OPER_ERR_P4[28] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P4_SHFT 28 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P3_ADDR \ + WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P3_MASK \ + 0x08000000 /* EN_DATA_OPER_ERR_P3[27] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P3_SHFT 27 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P2_ADDR \ + WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P2_MASK \ + 0x04000000 /* EN_DATA_OPER_ERR_P2[26] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P2_SHFT 26 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P1_ADDR \ + WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P1_MASK \ + 0x02000000 /* EN_DATA_OPER_ERR_P1[25] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P1_SHFT 25 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P0_ADDR \ + WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P0_MASK \ + 0x01000000 /* EN_DATA_OPER_ERR_P0[24] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_DATA_OPER_ERR_P0_SHFT 24 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P6_ADDR \ + WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P6_MASK \ + 0x00400000 /* EN_QUEUE_OPER_ERR_P6[22] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P6_SHFT 22 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P5_ADDR \ + WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P5_MASK \ + 0x00200000 /* EN_QUEUE_OPER_ERR_P5[21] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P5_SHFT 21 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P4_ADDR \ + WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P4_MASK \ + 0x00100000 /* EN_QUEUE_OPER_ERR_P4[20] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P4_SHFT 20 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P3_ADDR \ + WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P3_MASK \ + 0x00080000 /* EN_QUEUE_OPER_ERR_P3[19] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P3_SHFT 19 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P2_ADDR \ + WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P2_MASK \ + 0x00040000 /* EN_QUEUE_OPER_ERR_P2[18] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P2_SHFT 18 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P1_ADDR \ + WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P1_MASK \ + 0x00020000 /* EN_QUEUE_OPER_ERR_P1[17] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P1_SHFT 17 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P0_ADDR \ + WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P0_MASK \ + 0x00010000 /* EN_QUEUE_OPER_ERR_P0[16] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_QUEUE_OPER_ERR_P0_SHFT 16 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P6_ADDR \ + WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P6_MASK \ + 0x00004000 /* EN_PAGE_UDF_P6[14] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P6_SHFT 14 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P5_ADDR \ + WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P5_MASK \ + 0x00002000 /* EN_PAGE_UDF_P5[13] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P5_SHFT 13 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P4_ADDR \ + WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P4_MASK \ + 0x00001000 /* EN_PAGE_UDF_P4[12] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P4_SHFT 12 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P3_ADDR \ + WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P3_MASK \ + 0x00000800 /* EN_PAGE_UDF_P3[11] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P3_SHFT 11 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P2_ADDR \ + WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P2_MASK \ + 0x00000400 /* EN_PAGE_UDF_P2[10] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P2_SHFT 10 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P1_ADDR \ + WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P1_MASK \ + 0x00000200 /* EN_PAGE_UDF_P1[9] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P1_SHFT 9 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P0_ADDR \ + WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P0_MASK \ + 0x00000100 /* EN_PAGE_UDF_P0[8] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_PAGE_UDF_P0_SHFT 8 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P6_ADDR \ + WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P6_MASK \ + 0x00000040 /* EN_Q_CMD_ERR_P6[6] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P6_SHFT 6 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P5_ADDR \ + WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P5_MASK \ + 0x00000020 /* EN_Q_CMD_ERR_P5[5] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P5_SHFT 5 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P4_ADDR \ + WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P4_MASK \ + 0x00000010 /* EN_Q_CMD_ERR_P4[4] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P4_SHFT 4 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P3_ADDR \ + WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P3_MASK \ + 0x00000008 /* EN_Q_CMD_ERR_P3[3] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P3_SHFT 3 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P2_ADDR \ + WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P2_MASK \ + 0x00000004 /* EN_Q_CMD_ERR_P2[2] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P2_SHFT 2 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P1_ADDR \ + WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P1_MASK \ + 0x00000002 /* EN_Q_CMD_ERR_P1[1] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P1_SHFT 1 +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P0_ADDR \ + WF_PSE_TOP_INT_N9_ERR_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P0_MASK \ + 0x00000001 /* EN_Q_CMD_ERR_P0[0] */ +#define WF_PSE_TOP_INT_N9_ERR_MASK_EN_Q_CMD_ERR_P0_SHFT 0 + +/* +* ---INT_N9_ERR1_STS (0x820C8000 + 0x30)--- +* WDT_ERR_P0[0] - (W1C) Port state watch dog timeout error +* interrupt status of port 0. Avoid unclear error flag, please clear +* flag when +* logic reset. +* WDT_ERR_P1[1] - (W1C) Port state watch dog timeout error +* interrupt status of port 1. Avoid unclear error flag, please clear +* flag when +* logic reset. +* WDT_ERR_P2[2] - (W1C) Port state watch dog timeout error +* interrupt status of port 2. Avoid unclear error flag, please clear +* flag when +* logic reset. +* WDT_ERR_P3[3] - (W1C) Port state watch dog timeout error +* interrupt status of port 3. Avoid unclear error flag, please clear +* flag when +* logic reset. +* WDT_ERR_P4[4] - (W1C) Port state watch dog timeout error +* interrupt status of port 4. Avoid unclear error flag, please clear +* flag when +* logic reset. +* WDT_ERR_P5[5] - (W1C) Port state watch dog timeout error +* interrupt status of port 5. Avoid unclear error flag, please clear +* flag when +* logic reset. +* WDT_ERR_P6[6] - (W1C) Port state watch dog timeout error +* interrupt status of port 6. Avoid unclear error flag, please clear +* flag when +* logic reset. +* RESERVED7[7] - (RO) Reserved bits +* FL_HANG_ERR[8] - (W1C) Frame link FSM hang error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* PL_HANG_ERR[9] - (W1C) Page link FSM hang error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* DOUBLE_RLS_ERR[10] - (W1C) Double release error interrupt. Avoid +* unclear error flag, please clear flag when logic reset. +* FREE_HEAD_TAIL_ERR[11] - (W1C) Free head/tail error interrupt. Avoid +* unclear error flag, please clear flag when logic reset. +* FL_QSTRUCT_ERR[12] - (W1C) Frame Link queue NULL error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* RESERVED13[31..13] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_INT_N9_ERR1_STS_FL_QSTRUCT_ERR_ADDR \ + WF_PSE_TOP_INT_N9_ERR1_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_STS_FL_QSTRUCT_ERR_MASK \ + 0x00001000 /* FL_QSTRUCT_ERR[12] */ +#define WF_PSE_TOP_INT_N9_ERR1_STS_FL_QSTRUCT_ERR_SHFT 12 +#define WF_PSE_TOP_INT_N9_ERR1_STS_FREE_HEAD_TAIL_ERR_ADDR \ + WF_PSE_TOP_INT_N9_ERR1_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_STS_FREE_HEAD_TAIL_ERR_MASK \ + 0x00000800 /* FREE_HEAD_TAIL_ERR[11] */ +#define WF_PSE_TOP_INT_N9_ERR1_STS_FREE_HEAD_TAIL_ERR_SHFT 11 +#define WF_PSE_TOP_INT_N9_ERR1_STS_DOUBLE_RLS_ERR_ADDR \ + WF_PSE_TOP_INT_N9_ERR1_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_STS_DOUBLE_RLS_ERR_MASK \ + 0x00000400 /* DOUBLE_RLS_ERR[10] */ +#define WF_PSE_TOP_INT_N9_ERR1_STS_DOUBLE_RLS_ERR_SHFT 10 +#define WF_PSE_TOP_INT_N9_ERR1_STS_PL_HANG_ERR_ADDR \ + WF_PSE_TOP_INT_N9_ERR1_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_STS_PL_HANG_ERR_MASK \ + 0x00000200 /* PL_HANG_ERR[9] */ +#define WF_PSE_TOP_INT_N9_ERR1_STS_PL_HANG_ERR_SHFT 9 +#define WF_PSE_TOP_INT_N9_ERR1_STS_FL_HANG_ERR_ADDR \ + WF_PSE_TOP_INT_N9_ERR1_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_STS_FL_HANG_ERR_MASK \ + 0x00000100 /* FL_HANG_ERR[8] */ +#define WF_PSE_TOP_INT_N9_ERR1_STS_FL_HANG_ERR_SHFT 8 +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P6_ADDR \ + WF_PSE_TOP_INT_N9_ERR1_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P6_MASK \ + 0x00000040 /* WDT_ERR_P6[6] */ +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P6_SHFT 6 +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P5_ADDR \ + WF_PSE_TOP_INT_N9_ERR1_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P5_MASK \ + 0x00000020 /* WDT_ERR_P5[5] */ +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P5_SHFT 5 +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P4_ADDR \ + WF_PSE_TOP_INT_N9_ERR1_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P4_MASK \ + 0x00000010 /* WDT_ERR_P4[4] */ +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P4_SHFT 4 +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P3_ADDR \ + WF_PSE_TOP_INT_N9_ERR1_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P3_MASK \ + 0x00000008 /* WDT_ERR_P3[3] */ +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P3_SHFT 3 +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P2_ADDR \ + WF_PSE_TOP_INT_N9_ERR1_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P2_MASK \ + 0x00000004 /* WDT_ERR_P2[2] */ +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P2_SHFT 2 +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P1_ADDR \ + WF_PSE_TOP_INT_N9_ERR1_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P1_MASK \ + 0x00000002 /* WDT_ERR_P1[1] */ +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P1_SHFT 1 +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P0_ADDR \ + WF_PSE_TOP_INT_N9_ERR1_STS_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P0_MASK \ + 0x00000001 /* WDT_ERR_P0[0] */ +#define WF_PSE_TOP_INT_N9_ERR1_STS_WDT_ERR_P0_SHFT 0 + +/* +* ---INT_N9_ERR1_MASK (0x820C8000 + 0x34)--- +* EN_WDT_ERR_P0[0] - (RW) Enable Port state watch dog timeout +* error interrupt status of port 0. Avoid unclear error flag, please +* clear flag +* when logic reset. +* EN_WDT_ERR_P1[1] - (RW) Enable Port state watch dog timeout +* error interrupt status of port 1. Avoid unclear error flag, please +* clear flag +* when logic reset. +* EN_WDT_ERR_P2[2] - (RW) Enable Port state watch dog timeout +* error interrupt status of port 2. Avoid unclear error flag, please +* clear flag +* when logic reset. +* EN_WDT_ERR_P3[3] - (RW) Enable Port state watch dog timeout +* error interrupt status of port 3. Avoid unclear error flag, please +* clear flag +* when logic reset. +* EN_WDT_ERR_P4[4] - (RW) Enable Port state watch dog timeout +* error interrupt status of port 4. Avoid unclear error flag, please +* clear flag +* when logic reset. +* EN_WDT_ERR_P5[5] - (RW) Enable Port state watch dog timeout +* error interrupt status of port 5. Avoid unclear error flag, please +* clear flag +* when logic reset. +* EN_WDT_ERR_P6[6] - (RW) Enable Port state watch dog timeout +* error interrupt status of port 6. Avoid unclear error flag, please +* clear flag +* when logic reset. +* RESERVED7[7] - (RO) Reserved bits +* EN_FL_HANG_ERR[8] - (RW) Enable Frame link FSM hang error +* interrupt. Avoid unclear error flag, please clear flag when logic +reset. +* PL_HANGEN__ERR[9] - (RW) Enable Page link FSM hang error +* interrupt. Avoid unclear error flag, please clear flag when logic +reset. +* EN_DOUBLE_RLS_ERR[10] - (RW) Enable Double release error interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* EN_FREE_HEAD_TAIL_ERR[11] - (RW) Enable Free head/tail error +interrupt. +* Avoid unclear error flag, please clear flag when logic reset. +* EN_FL_QSTRTUT_ERR[12] - (RW) Enable Frame Link queue NULL error +* interrupt. Avoid unclear error flag, please clear flag when logic +reset. +* RESERVED13[31..13] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_FL_QSTRTUT_ERR_ADDR \ + WF_PSE_TOP_INT_N9_ERR1_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_FL_QSTRTUT_ERR_MASK \ + 0x00001000 /* EN_FL_QSTRTUT_ERR[12] */ +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_FL_QSTRTUT_ERR_SHFT 12 +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_FREE_HEAD_TAIL_ERR_ADDR \ + WF_PSE_TOP_INT_N9_ERR1_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_FREE_HEAD_TAIL_ERR_MASK \ + 0x00000800 /* EN_FREE_HEAD_TAIL_ERR[11] */ +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_FREE_HEAD_TAIL_ERR_SHFT 11 +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_DOUBLE_RLS_ERR_ADDR \ + WF_PSE_TOP_INT_N9_ERR1_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_DOUBLE_RLS_ERR_MASK \ + 0x00000400 /* EN_DOUBLE_RLS_ERR[10] */ +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_DOUBLE_RLS_ERR_SHFT 10 +#define WF_PSE_TOP_INT_N9_ERR1_MASK_PL_HANGEN__ERR_ADDR \ + WF_PSE_TOP_INT_N9_ERR1_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_MASK_PL_HANGEN__ERR_MASK \ + 0x00000200 /* PL_HANGEN__ERR[9] */ +#define WF_PSE_TOP_INT_N9_ERR1_MASK_PL_HANGEN__ERR_SHFT 9 +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_FL_HANG_ERR_ADDR \ + WF_PSE_TOP_INT_N9_ERR1_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_FL_HANG_ERR_MASK \ + 0x00000100 /* EN_FL_HANG_ERR[8] */ +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_FL_HANG_ERR_SHFT 8 +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P6_ADDR \ + WF_PSE_TOP_INT_N9_ERR1_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P6_MASK \ + 0x00000040 /* EN_WDT_ERR_P6[6] */ +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P6_SHFT 6 +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P5_ADDR \ + WF_PSE_TOP_INT_N9_ERR1_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P5_MASK \ + 0x00000020 /* EN_WDT_ERR_P5[5] */ +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P5_SHFT 5 +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P4_ADDR \ + WF_PSE_TOP_INT_N9_ERR1_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P4_MASK \ + 0x00000010 /* EN_WDT_ERR_P4[4] */ +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P4_SHFT 4 +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P3_ADDR \ + WF_PSE_TOP_INT_N9_ERR1_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P3_MASK \ + 0x00000008 /* EN_WDT_ERR_P3[3] */ +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P3_SHFT 3 +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P2_ADDR \ + WF_PSE_TOP_INT_N9_ERR1_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P2_MASK \ + 0x00000004 /* EN_WDT_ERR_P2[2] */ +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P2_SHFT 2 +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P1_ADDR \ + WF_PSE_TOP_INT_N9_ERR1_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P1_MASK \ + 0x00000002 /* EN_WDT_ERR_P1[1] */ +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P1_SHFT 1 +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P0_ADDR \ + WF_PSE_TOP_INT_N9_ERR1_MASK_ADDR +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P0_MASK \ + 0x00000001 /* EN_WDT_ERR_P0[0] */ +#define WF_PSE_TOP_INT_N9_ERR1_MASK_EN_WDT_ERR_P0_SHFT 0 + +/* +* ---C_GET_FID_0 (0x820C8000 + 0x40)--- +* QUEUE_FRAME_ID[15..0] - (RW) Frame ID for get command +* At GET_FRAME_TYPE = 2'h0/2'h1: +* QUEUE_FRAME_ID[15:14] = PID +* 2'h0: HIF port +* 2'h1: CPU port +* 2'h2: LMAC port +* QUEUE_FRAME_ID[9:0] = WLANID +* At GET_FRAME_TYPE = 2'h2/2'h3: +* QUEUE_FRAME_ID[11:0] = reference FID +* GET_FRAME_TYPE[19..16] - (RW) GET_SUB_TYPE +* RESERVED20[23..20] - (RO) Reserved bits +* GET_FRAME_QID[30..24] - (RW) Queue ID vlaue +* EXECUTE[31] - (A0) Executes command +*/ +#define WF_PSE_TOP_C_GET_FID_0_EXECUTE_ADDR \ + WF_PSE_TOP_C_GET_FID_0_ADDR +#define WF_PSE_TOP_C_GET_FID_0_EXECUTE_MASK \ + 0x80000000 /* EXECUTE[31] */ +#define WF_PSE_TOP_C_GET_FID_0_EXECUTE_SHFT 31 +#define WF_PSE_TOP_C_GET_FID_0_GET_FRAME_QID_ADDR \ + WF_PSE_TOP_C_GET_FID_0_ADDR +#define WF_PSE_TOP_C_GET_FID_0_GET_FRAME_QID_MASK \ + 0x7F000000 /* GET_FRAME_QID[30..24] */ +#define WF_PSE_TOP_C_GET_FID_0_GET_FRAME_QID_SHFT 24 +#define WF_PSE_TOP_C_GET_FID_0_GET_FRAME_TYPE_ADDR \ + WF_PSE_TOP_C_GET_FID_0_ADDR +#define WF_PSE_TOP_C_GET_FID_0_GET_FRAME_TYPE_MASK \ + 0x000F0000 /* GET_FRAME_TYPE[19..16] */ +#define WF_PSE_TOP_C_GET_FID_0_GET_FRAME_TYPE_SHFT 16 +#define WF_PSE_TOP_C_GET_FID_0_QUEUE_FRAME_ID_ADDR \ + WF_PSE_TOP_C_GET_FID_0_ADDR +#define WF_PSE_TOP_C_GET_FID_0_QUEUE_FRAME_ID_MASK \ + 0x0000FFFF /* QUEUE_FRAME_ID[15..0] */ +#define WF_PSE_TOP_C_GET_FID_0_QUEUE_FRAME_ID_SHFT 0 + +/* +* ---C_GET_FID_1 (0x820C8000 + 0x44)--- +* GET_RETURN_FID[11..0] - (RO) Return frame ID +* RESERVED12[14..12] - (RO) Reserved bits +* END[15] - (RO) Return frame ID is end FID +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_C_GET_FID_1_END_ADDR WF_PSE_TOP_C_GET_FID_1_ADDR +#define WF_PSE_TOP_C_GET_FID_1_END_MASK 0x00008000 /* END[15] */ +#define WF_PSE_TOP_C_GET_FID_1_END_SHFT 15 +#define WF_PSE_TOP_C_GET_FID_1_GET_RETURN_FID_ADDR \ + WF_PSE_TOP_C_GET_FID_1_ADDR +#define WF_PSE_TOP_C_GET_FID_1_GET_RETURN_FID_MASK \ + 0x00000FFF /* GET_RETURN_FID[11..0] */ +#define WF_PSE_TOP_C_GET_FID_1_GET_RETURN_FID_SHFT 0 + +/* +* ---C_EN_QUEUE_0 (0x820C8000 + 0x60)--- +* DST_WLANID[9..0] - (RW) Destination WLANID for enqueue +* RESERVED10[13..10] - (RO) Reserved bits +* DST_PID[15..14] - (RW) Destination port ID for enqueue +* SUB_TYPE[19..16] - (RW) Sub-type of enqueue command +* RESERVED20[22..20] - (RO) Reserved bits +* DELAY_ENQ[23] - (RW) Delays enqueue +* DST_QID[30..24] - (RW) Destination queue ID for enqueue +* EXECUTE[31] - (A0) Executes command +*/ +#define WF_PSE_TOP_C_EN_QUEUE_0_EXECUTE_ADDR \ + WF_PSE_TOP_C_EN_QUEUE_0_ADDR +#define WF_PSE_TOP_C_EN_QUEUE_0_EXECUTE_MASK \ + 0x80000000 /* EXECUTE[31] */ +#define WF_PSE_TOP_C_EN_QUEUE_0_EXECUTE_SHFT 31 +#define WF_PSE_TOP_C_EN_QUEUE_0_DST_QID_ADDR \ + WF_PSE_TOP_C_EN_QUEUE_0_ADDR +#define WF_PSE_TOP_C_EN_QUEUE_0_DST_QID_MASK \ + 0x7F000000 /* DST_QID[30..24] */ +#define WF_PSE_TOP_C_EN_QUEUE_0_DST_QID_SHFT 24 +#define WF_PSE_TOP_C_EN_QUEUE_0_DELAY_ENQ_ADDR \ + WF_PSE_TOP_C_EN_QUEUE_0_ADDR +#define WF_PSE_TOP_C_EN_QUEUE_0_DELAY_ENQ_MASK \ + 0x00800000 /* DELAY_ENQ[23] */ +#define WF_PSE_TOP_C_EN_QUEUE_0_DELAY_ENQ_SHFT 23 +#define WF_PSE_TOP_C_EN_QUEUE_0_SUB_TYPE_ADDR \ + WF_PSE_TOP_C_EN_QUEUE_0_ADDR +#define WF_PSE_TOP_C_EN_QUEUE_0_SUB_TYPE_MASK \ + 0x000F0000 /* SUB_TYPE[19..16] */ +#define WF_PSE_TOP_C_EN_QUEUE_0_SUB_TYPE_SHFT 16 +#define WF_PSE_TOP_C_EN_QUEUE_0_DST_PID_ADDR \ + WF_PSE_TOP_C_EN_QUEUE_0_ADDR +#define WF_PSE_TOP_C_EN_QUEUE_0_DST_PID_MASK \ + 0x0000C000 /* DST_PID[15..14] */ +#define WF_PSE_TOP_C_EN_QUEUE_0_DST_PID_SHFT 14 +#define WF_PSE_TOP_C_EN_QUEUE_0_DST_WLANID_ADDR \ + WF_PSE_TOP_C_EN_QUEUE_0_ADDR +#define WF_PSE_TOP_C_EN_QUEUE_0_DST_WLANID_MASK \ + 0x000003FF /* DST_WLANID[9..0] */ +#define WF_PSE_TOP_C_EN_QUEUE_0_DST_WLANID_SHFT 0 + +/* +* ---C_EN_QUEUE_1 (0x820C8000 + 0x64)--- +* CUR_LIST_FID_START[11..0] - (RW) Start frame ID of enqueue operation +* list, enqueue FID of enqueue operation +* RESERVED12[15..12] - (RO) Reserved bits +* CUR_LIST_FID_END[27..16] - (RW) End frame ID of enqueue operation +list +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_C_EN_QUEUE_1_CUR_LIST_FID_END_ADDR \ + WF_PSE_TOP_C_EN_QUEUE_1_ADDR +#define WF_PSE_TOP_C_EN_QUEUE_1_CUR_LIST_FID_END_MASK \ + 0x0FFF0000 /* CUR_LIST_FID_END[27..16] */ +#define WF_PSE_TOP_C_EN_QUEUE_1_CUR_LIST_FID_END_SHFT 16 +#define WF_PSE_TOP_C_EN_QUEUE_1_CUR_LIST_FID_START_ADDR \ + WF_PSE_TOP_C_EN_QUEUE_1_ADDR +#define WF_PSE_TOP_C_EN_QUEUE_1_CUR_LIST_FID_START_MASK \ + 0x00000FFF /* CUR_LIST_FID_START[11..0] */ +#define WF_PSE_TOP_C_EN_QUEUE_1_CUR_LIST_FID_START_SHFT 0 + +/* +* ---C_EN_QUEUE_2 (0x820C8000 + 0x68)--- +* TARGET_FID[11..0] - (RW) Target reference FID for enqueue +operation +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_C_EN_QUEUE_2_TARGET_FID_ADDR \ + WF_PSE_TOP_C_EN_QUEUE_2_ADDR +#define WF_PSE_TOP_C_EN_QUEUE_2_TARGET_FID_MASK \ + 0x00000FFF /* TARGET_FID[11..0] */ +#define WF_PSE_TOP_C_EN_QUEUE_2_TARGET_FID_SHFT 0 + +/* +* ---C_DE_QUEUE_0 (0x820C8000 + 0x80)--- +* SRC_WLANID[9..0] - (RW) Source WLAN ID for dequeue command +* RESERVED10[13..10] - (RO) Reserved bits +* SRC_PID[15..14] - (RW) Source port ID for dequeue command +* DEQ_SUB_TYPE[19..16] - (RW) Dequeue subtype of dequeue command +* ENQ_SUB_TYPE[22..20] - (RW) Enqueue subtype of enqueue command +* Only valid in Deq&Enq type. +* ENQ_VLD[23] - (RW) Deq&Enq command valid +* SRC_QID[30..24] - (RW) Source queue ID for dequeue command +* EXECUTE[31] - (A0) Executes dequeue command +*/ +#define WF_PSE_TOP_C_DE_QUEUE_0_EXECUTE_ADDR \ + WF_PSE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_0_EXECUTE_MASK \ + 0x80000000 /* EXECUTE[31] */ +#define WF_PSE_TOP_C_DE_QUEUE_0_EXECUTE_SHFT 31 +#define WF_PSE_TOP_C_DE_QUEUE_0_SRC_QID_ADDR \ + WF_PSE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_0_SRC_QID_MASK \ + 0x7F000000 /* SRC_QID[30..24] */ +#define WF_PSE_TOP_C_DE_QUEUE_0_SRC_QID_SHFT 24 +#define WF_PSE_TOP_C_DE_QUEUE_0_ENQ_VLD_ADDR \ + WF_PSE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_0_ENQ_VLD_MASK \ + 0x00800000 /* ENQ_VLD[23] */ +#define WF_PSE_TOP_C_DE_QUEUE_0_ENQ_VLD_SHFT 23 +#define WF_PSE_TOP_C_DE_QUEUE_0_ENQ_SUB_TYPE_ADDR \ + WF_PSE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_0_ENQ_SUB_TYPE_MASK \ + 0x00700000 /* ENQ_SUB_TYPE[22..20] */ +#define WF_PSE_TOP_C_DE_QUEUE_0_ENQ_SUB_TYPE_SHFT 20 +#define WF_PSE_TOP_C_DE_QUEUE_0_DEQ_SUB_TYPE_ADDR \ + WF_PSE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_0_DEQ_SUB_TYPE_MASK \ + 0x000F0000 /* DEQ_SUB_TYPE[19..16] */ +#define WF_PSE_TOP_C_DE_QUEUE_0_DEQ_SUB_TYPE_SHFT 16 +#define WF_PSE_TOP_C_DE_QUEUE_0_SRC_PID_ADDR \ + WF_PSE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_0_SRC_PID_MASK \ + 0x0000C000 /* SRC_PID[15..14] */ +#define WF_PSE_TOP_C_DE_QUEUE_0_SRC_PID_SHFT 14 +#define WF_PSE_TOP_C_DE_QUEUE_0_SRC_WLANID_ADDR \ + WF_PSE_TOP_C_DE_QUEUE_0_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_0_SRC_WLANID_MASK \ + 0x000003FF /* SRC_WLANID[9..0] */ +#define WF_PSE_TOP_C_DE_QUEUE_0_SRC_WLANID_SHFT 0 + +/* +* ---C_DE_QUEUE_1 (0x820C8000 + 0x84)--- +* CUR_LIST_FID_START[11..0] - (RW) Start frame ID of dequeue operation +* list, enqueue start FID of enqueue operation +* Only valid in Deq&Enq type. +* RESERVED12[15..12] - (RO) Reserved bits +* CUR_LIST_FID_END[27..16] - (RW) End framd ID of dequeue operation +list, +* enqueue end FID of enqueue operation +* Only valid in Deq&Enq type. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_C_DE_QUEUE_1_CUR_LIST_FID_END_ADDR \ + WF_PSE_TOP_C_DE_QUEUE_1_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_1_CUR_LIST_FID_END_MASK \ + 0x0FFF0000 /* CUR_LIST_FID_END[27..16] */ +#define WF_PSE_TOP_C_DE_QUEUE_1_CUR_LIST_FID_END_SHFT 16 +#define WF_PSE_TOP_C_DE_QUEUE_1_CUR_LIST_FID_START_ADDR \ + WF_PSE_TOP_C_DE_QUEUE_1_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_1_CUR_LIST_FID_START_MASK \ + 0x00000FFF /* CUR_LIST_FID_START[11..0] */ +#define WF_PSE_TOP_C_DE_QUEUE_1_CUR_LIST_FID_START_SHFT 0 + +/* +* ---C_DE_QUEUE_2 (0x820C8000 + 0x88)--- +* DEQ_ENQ_DST_WLANID[9..0] - (RW) Destination WLAN ID for enqueue +command +* Only valid in Deq&Enq type. +* RESERVED10[13..10] - (RO) Reserved bits +* DEQ_ENQ_DST_PID[15..14] - (RW) Destination port ID for dequeue +command +* RESERVED16[23..16] - (RO) Reserved bits +* DEQ_ENQ_DST_QID[30..24] - (RW) Destination queue ID for enqueue +command +* Only valid in Deq&Enq type. +* RESERVED31[31] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_QID_ADDR \ + WF_PSE_TOP_C_DE_QUEUE_2_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_QID_MASK \ + 0x7F000000 /* DEQ_ENQ_DST_QID[30..24] */ +#define WF_PSE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_QID_SHFT 24 +#define WF_PSE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_PID_ADDR \ + WF_PSE_TOP_C_DE_QUEUE_2_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_PID_MASK \ + 0x0000C000 /* DEQ_ENQ_DST_PID[15..14] */ +#define WF_PSE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_PID_SHFT 14 +#define WF_PSE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_WLANID_ADDR \ + WF_PSE_TOP_C_DE_QUEUE_2_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_WLANID_MASK \ + 0x000003FF /* DEQ_ENQ_DST_WLANID[9..0] */ +#define WF_PSE_TOP_C_DE_QUEUE_2_DEQ_ENQ_DST_WLANID_SHFT 0 + +/* +* ---C_DE_QUEUE_3 (0x820C8000 + 0x8c)--- +* DEQ_HEAD_FDI[11..0] - (RO) Head FID got from dequeue command +* RESERVED12[14..12] - (RO) Reserved bits +* DEQ_EMPTY[15] - (RO) Queue empty after dequeue command is +executed +* DEQ_TAIL_FID[27..16] - (RO) Last FID got from dequeue command +* RESERVED28[30..28] - (RO) Reserved bits +* BUSY[31] - (RO) Dequeue execute busy +*/ +#define WF_PSE_TOP_C_DE_QUEUE_3_BUSY_ADDR WF_PSE_TOP_C_DE_QUEUE_3_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_3_BUSY_MASK 0x80000000 /* BUSY[31] */ +#define WF_PSE_TOP_C_DE_QUEUE_3_BUSY_SHFT 31 +#define WF_PSE_TOP_C_DE_QUEUE_3_DEQ_TAIL_FID_ADDR \ + WF_PSE_TOP_C_DE_QUEUE_3_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_3_DEQ_TAIL_FID_MASK \ + 0x0FFF0000 /* DEQ_TAIL_FID[27..16] */ +#define WF_PSE_TOP_C_DE_QUEUE_3_DEQ_TAIL_FID_SHFT 16 +#define WF_PSE_TOP_C_DE_QUEUE_3_DEQ_EMPTY_ADDR \ + WF_PSE_TOP_C_DE_QUEUE_3_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_3_DEQ_EMPTY_MASK \ + 0x00008000 /* DEQ_EMPTY[15] */ +#define WF_PSE_TOP_C_DE_QUEUE_3_DEQ_EMPTY_SHFT 15 +#define WF_PSE_TOP_C_DE_QUEUE_3_DEQ_HEAD_FDI_ADDR \ + WF_PSE_TOP_C_DE_QUEUE_3_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_3_DEQ_HEAD_FDI_MASK \ + 0x00000FFF /* DEQ_HEAD_FDI[11..0] */ +#define WF_PSE_TOP_C_DE_QUEUE_3_DEQ_HEAD_FDI_SHFT 0 + +/* +* ---C_DE_QUEUE_4 (0x820C8000 + 0x90)--- +* DEQ_ENQ_REF_FID[11..0] - (RW) Reference frame ID for enqueue command +* Only valid in Deq&Enq type. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_C_DE_QUEUE_4_DEQ_ENQ_REF_FID_ADDR \ + WF_PSE_TOP_C_DE_QUEUE_4_ADDR +#define WF_PSE_TOP_C_DE_QUEUE_4_DEQ_ENQ_REF_FID_MASK \ + 0x00000FFF /* DEQ_ENQ_REF_FID[11..0] */ +#define WF_PSE_TOP_C_DE_QUEUE_4_DEQ_ENQ_REF_FID_SHFT 0 + +/* +* ---ALLOCATE_0 (0x820C8000 + 0xA0)--- +* ALLOCATE_FRAME_LENGTH[13..0] - (RW) Allocate frame length +* Unit: DW (4 bytes) +* RESERVED14[15..14] - (RO) Reserved bits +* ALLOCATE_QID[20..16] - (RW) QID used for allocate buffer +* RESERVED21[30..21] - (RO) Reserved bits +* EXECUTE[31] - (A0) Executes allocate buffer command +*/ +#define WF_PSE_TOP_ALLOCATE_0_EXECUTE_ADDR WF_PSE_TOP_ALLOCATE_0_ADDR +#define WF_PSE_TOP_ALLOCATE_0_EXECUTE_MASK \ + 0x80000000 /* EXECUTE[31] */ +#define WF_PSE_TOP_ALLOCATE_0_EXECUTE_SHFT 31 +#define WF_PSE_TOP_ALLOCATE_0_ALLOCATE_QID_ADDR \ + WF_PSE_TOP_ALLOCATE_0_ADDR +#define WF_PSE_TOP_ALLOCATE_0_ALLOCATE_QID_MASK \ + 0x001F0000 /* ALLOCATE_QID[20..16] */ +#define WF_PSE_TOP_ALLOCATE_0_ALLOCATE_QID_SHFT 16 +#define WF_PSE_TOP_ALLOCATE_0_ALLOCATE_FRAME_LENGTH_ADDR \ + WF_PSE_TOP_ALLOCATE_0_ADDR +#define WF_PSE_TOP_ALLOCATE_0_ALLOCATE_FRAME_LENGTH_MASK \ + 0x00003FFF /* ALLOCATE_FRAME_LENGTH[13..0] */ +#define WF_PSE_TOP_ALLOCATE_0_ALLOCATE_FRAME_LENGTH_SHFT 0 + +/* +* ---ALLOCATE_1 (0x820C8000 + 0xA4)--- +* ALLOCATE_FID[11..0] - (RO) Return frame ID for allocate buffer +command +* RESERVED12[30..12] - (RO) Reserved bits +* EXECUTE[31] - (RO) Execute status of allocate buffer +command +*/ +#define WF_PSE_TOP_ALLOCATE_1_EXECUTE_ADDR WF_PSE_TOP_ALLOCATE_1_ADDR +#define WF_PSE_TOP_ALLOCATE_1_EXECUTE_MASK \ + 0x80000000 /* EXECUTE[31] */ +#define WF_PSE_TOP_ALLOCATE_1_EXECUTE_SHFT 31 +#define WF_PSE_TOP_ALLOCATE_1_ALLOCATE_FID_ADDR \ + WF_PSE_TOP_ALLOCATE_1_ADDR +#define WF_PSE_TOP_ALLOCATE_1_ALLOCATE_FID_MASK \ + 0x00000FFF /* ALLOCATE_FID[11..0] */ +#define WF_PSE_TOP_ALLOCATE_1_ALLOCATE_FID_SHFT 0 + +/* +* ---QUEUE_EMPTY (0x820C8000 + 0xB0)--- +* CPU_Q0_EMPTY[0] - (RO) CPU queue 0 empty status +* CPU_Q1_EMPTY[1] - (RO) CPU queue 1 empty status +* CPU_Q2_EMPTY[2] - (RO) CPU queue 2 empty status +* CPU_Q3_EMPTY[3] - (RO) CPU queue 3 empty status +* HIF_8_EMPTY[4] - (RO) HIF queue 8 empty status +* HIF_9_EMPTY[5] - (RO) HIF queue 9 empty status +* HIF_10_EMPTY[6] - (RO) HIF queue 10 empty status +* HIF_11_EMPTY[7] - (RO) HIF queue 11 empty status +* HIF_0_EMPTY[8] - (RO) HIF queue 0 empty status +* HIF_1_EMPTY[9] - (RO) HIF queue 1 empty status +* HIF_2_EMPTY[10] - (RO) HIF queue 2 empty status +* HIF_3_EMPTY[11] - (RO) HIF queue 3 empty status +* HIF_4_EMPTY[12] - (RO) HIF queue 4 empty status +* HIF_5_EMPTY[13] - (RO) HIF queue 5 empty status +* HIF_6_EMPTY[14] - (RO) HIF queue 6 empty status +* HIF_7_EMPTY[15] - (RO) HIF queue 7 empty status +* LMAC_TX_QUEUE_EMPTY[16] - (RO) LMAC TX queue empty status +* MDP_TX_QUEUE_EMPTY[17] - (RO) MDP TX queue empty status +* MDP_RX_QUEUE_EMPTY[18] - (RO) MDP RX queue empty status +* SEC_TX_QUEUE_EMPTY[19] - (RO) SEC TX queue empty status +* SEC_RX_QUEUE_EMPTY[20] - (RO) SEC RX queue empty status +* SFD_PARK_QUEUE_EMPTY[21] - (RO) SFD PARK queue empty status +* MDP_TXIOC_QUEUE_EMPTY[22] - (RO) MDP TXIOC queue empty status +* MDP_RXIOC_QUEUE_EMPTY[23] - (RO) MDP RXIOC queue empty status +* MDP_TX1_QUEUE_EMPTY[24] - (RO) MDP TX queue empty status for Band 1 +* SEC_TX1_QUEUE_EMPTY[25] - (RO) SEC TX queue empty status for Band 1 +* MDP_TXIOC1_QUEUE_EMPTY[26] - (RO) MDP TXIOC queue empty status for +* Band 1 +* MDP_RXIOC1_QUEUE_EMPTY[27] - (RO) MDP RXIOC queue empty status for +* Band 1 +* RESERVED28[30..28] - (RO) Reserved bits +* RLS_Q_EMTPY[31] - (RO) Release queue empty status +*/ +#define WF_PSE_TOP_QUEUE_EMPTY_RLS_Q_EMTPY_ADDR \ + WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_RLS_Q_EMTPY_MASK \ + 0x80000000 /* RLS_Q_EMTPY[31] */ +#define WF_PSE_TOP_QUEUE_EMPTY_RLS_Q_EMTPY_SHFT 31 +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_RXIOC1_QUEUE_EMPTY_ADDR \ + WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_RXIOC1_QUEUE_EMPTY_MASK \ + 0x08000000 /* MDP_RXIOC1_QUEUE_EMPTY[27] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_RXIOC1_QUEUE_EMPTY_SHFT 27 +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_TXIOC1_QUEUE_EMPTY_ADDR \ + WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_TXIOC1_QUEUE_EMPTY_MASK \ + 0x04000000 /* MDP_TXIOC1_QUEUE_EMPTY[26] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_TXIOC1_QUEUE_EMPTY_SHFT 26 +#define WF_PSE_TOP_QUEUE_EMPTY_SEC_TX1_QUEUE_EMPTY_ADDR \ + WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_SEC_TX1_QUEUE_EMPTY_MASK \ + 0x02000000 /* SEC_TX1_QUEUE_EMPTY[25] */ +#define WF_PSE_TOP_QUEUE_EMPTY_SEC_TX1_QUEUE_EMPTY_SHFT 25 +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_TX1_QUEUE_EMPTY_ADDR \ + WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_TX1_QUEUE_EMPTY_MASK \ + 0x01000000 /* MDP_TX1_QUEUE_EMPTY[24] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_TX1_QUEUE_EMPTY_SHFT 24 +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_RXIOC_QUEUE_EMPTY_ADDR \ + WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_RXIOC_QUEUE_EMPTY_MASK \ + 0x00800000 /* MDP_RXIOC_QUEUE_EMPTY[23] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_RXIOC_QUEUE_EMPTY_SHFT 23 +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_TXIOC_QUEUE_EMPTY_ADDR \ + WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_TXIOC_QUEUE_EMPTY_MASK \ + 0x00400000 /* MDP_TXIOC_QUEUE_EMPTY[22] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_TXIOC_QUEUE_EMPTY_SHFT 22 +#define WF_PSE_TOP_QUEUE_EMPTY_SFD_PARK_QUEUE_EMPTY_ADDR \ + WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_SFD_PARK_QUEUE_EMPTY_MASK \ + 0x00200000 /* SFD_PARK_QUEUE_EMPTY[21] */ +#define WF_PSE_TOP_QUEUE_EMPTY_SFD_PARK_QUEUE_EMPTY_SHFT 21 +#define WF_PSE_TOP_QUEUE_EMPTY_SEC_RX_QUEUE_EMPTY_ADDR \ + WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_SEC_RX_QUEUE_EMPTY_MASK \ + 0x00100000 /* SEC_RX_QUEUE_EMPTY[20] */ +#define WF_PSE_TOP_QUEUE_EMPTY_SEC_RX_QUEUE_EMPTY_SHFT 20 +#define WF_PSE_TOP_QUEUE_EMPTY_SEC_TX_QUEUE_EMPTY_ADDR \ + WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_SEC_TX_QUEUE_EMPTY_MASK \ + 0x00080000 /* SEC_TX_QUEUE_EMPTY[19] */ +#define WF_PSE_TOP_QUEUE_EMPTY_SEC_TX_QUEUE_EMPTY_SHFT 19 +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_RX_QUEUE_EMPTY_ADDR \ + WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_RX_QUEUE_EMPTY_MASK \ + 0x00040000 /* MDP_RX_QUEUE_EMPTY[18] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_RX_QUEUE_EMPTY_SHFT 18 +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_TX_QUEUE_EMPTY_ADDR \ + WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_TX_QUEUE_EMPTY_MASK \ + 0x00020000 /* MDP_TX_QUEUE_EMPTY[17] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MDP_TX_QUEUE_EMPTY_SHFT 17 +#define WF_PSE_TOP_QUEUE_EMPTY_LMAC_TX_QUEUE_EMPTY_ADDR \ + WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_LMAC_TX_QUEUE_EMPTY_MASK \ + 0x00010000 /* LMAC_TX_QUEUE_EMPTY[16] */ +#define WF_PSE_TOP_QUEUE_EMPTY_LMAC_TX_QUEUE_EMPTY_SHFT 16 +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_7_EMPTY_ADDR \ + WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_7_EMPTY_MASK \ + 0x00008000 /* HIF_7_EMPTY[15] */ +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_7_EMPTY_SHFT 15 +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_6_EMPTY_ADDR \ + WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_6_EMPTY_MASK \ + 0x00004000 /* HIF_6_EMPTY[14] */ +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_6_EMPTY_SHFT 14 +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_5_EMPTY_ADDR \ + WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_5_EMPTY_MASK \ + 0x00002000 /* HIF_5_EMPTY[13] */ +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_5_EMPTY_SHFT 13 +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_4_EMPTY_ADDR \ + WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_4_EMPTY_MASK \ + 0x00001000 /* HIF_4_EMPTY[12] */ +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_4_EMPTY_SHFT 12 +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_3_EMPTY_ADDR \ + WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_3_EMPTY_MASK \ + 0x00000800 /* HIF_3_EMPTY[11] */ +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_3_EMPTY_SHFT 11 +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_2_EMPTY_ADDR \ + WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_2_EMPTY_MASK \ + 0x00000400 /* HIF_2_EMPTY[10] */ +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_2_EMPTY_SHFT 10 +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_1_EMPTY_ADDR \ + WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_1_EMPTY_MASK \ + 0x00000200 /* HIF_1_EMPTY[9] */ +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_1_EMPTY_SHFT 9 +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_0_EMPTY_ADDR \ + WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_0_EMPTY_MASK \ + 0x00000100 /* HIF_0_EMPTY[8] */ +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_0_EMPTY_SHFT 8 +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_11_EMPTY_ADDR \ + WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_11_EMPTY_MASK \ + 0x00000080 /* HIF_11_EMPTY[7] */ +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_11_EMPTY_SHFT 7 +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_10_EMPTY_ADDR \ + WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_10_EMPTY_MASK \ + 0x00000040 /* HIF_10_EMPTY[6] */ +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_10_EMPTY_SHFT 6 +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_9_EMPTY_ADDR \ + WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_9_EMPTY_MASK \ + 0x00000020 /* HIF_9_EMPTY[5] */ +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_9_EMPTY_SHFT 5 +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_8_EMPTY_ADDR \ + WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_8_EMPTY_MASK \ + 0x00000010 /* HIF_8_EMPTY[4] */ +#define WF_PSE_TOP_QUEUE_EMPTY_HIF_8_EMPTY_SHFT 4 +#define WF_PSE_TOP_QUEUE_EMPTY_CPU_Q3_EMPTY_ADDR \ + WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_CPU_Q3_EMPTY_MASK \ + 0x00000008 /* CPU_Q3_EMPTY[3] */ +#define WF_PSE_TOP_QUEUE_EMPTY_CPU_Q3_EMPTY_SHFT 3 +#define WF_PSE_TOP_QUEUE_EMPTY_CPU_Q2_EMPTY_ADDR \ + WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_CPU_Q2_EMPTY_MASK \ + 0x00000004 /* CPU_Q2_EMPTY[2] */ +#define WF_PSE_TOP_QUEUE_EMPTY_CPU_Q2_EMPTY_SHFT 2 +#define WF_PSE_TOP_QUEUE_EMPTY_CPU_Q1_EMPTY_ADDR \ + WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_CPU_Q1_EMPTY_MASK \ + 0x00000002 /* CPU_Q1_EMPTY[1] */ +#define WF_PSE_TOP_QUEUE_EMPTY_CPU_Q1_EMPTY_SHFT 1 +#define WF_PSE_TOP_QUEUE_EMPTY_CPU_Q0_EMPTY_ADDR \ + WF_PSE_TOP_QUEUE_EMPTY_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_CPU_Q0_EMPTY_MASK \ + 0x00000001 /* CPU_Q0_EMPTY[0] */ +#define WF_PSE_TOP_QUEUE_EMPTY_CPU_Q0_EMPTY_SHFT 0 + +/* +* ---QUEUE_EMPTY_MASK (0x820C8000 + 0xB4)--- +* RESERVED0[7..0] - (RO) Reserved bits +* HIF_0_EMPTY_MASK[8] - (RW) Mask control of HIF queue 0 empty status +* HIF_1_EMPTY_MASK[9] - (RW) Mask control of HIF queue 1 empty status +* HIF_2_EMPTY_MASK[10] - (RW) Mask control of HIF queue 2 empty status +* HIF_3_EMPTY_MASK[11] - (RW) Mask control of HIF queue 3 empty status +* HIF_4_EMPTY_MASK[12] - (RW) Mask control of HIF queue 4 empty status +* HIF_5_EMPTY_MASK[13] - (RW) Mask control of HIF queue 5 empty status +* HIF_6_EMPTY_MASK[14] - (RW) Mask control of HIF queue 6 empty status +* HIF_7_EMPTY_MASK[15] - (RW) Mask control of HIF queue 7 empty status +* HIF_8_EMPTY_MASK[16] - (RW) Mask control of HIF queue 8 empty status +* HIF_9_EMPTY_MASK[17] - (RW) Mask control of HIF queue 9 empty status +* HIF_10_EMPTY_MASK[18] - (RW) Mask control of HIF queue 10 empty +status +* HIF_11_EMPTY_MASK[19] - (RW) Mask control of HIF queue 11 empty +status +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_11_EMPTY_MASK_ADDR \ + WF_PSE_TOP_QUEUE_EMPTY_MASK_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_11_EMPTY_MASK_MASK \ + 0x00080000 /* HIF_11_EMPTY_MASK[19] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_11_EMPTY_MASK_SHFT 19 +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_10_EMPTY_MASK_ADDR \ + WF_PSE_TOP_QUEUE_EMPTY_MASK_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_10_EMPTY_MASK_MASK \ + 0x00040000 /* HIF_10_EMPTY_MASK[18] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_10_EMPTY_MASK_SHFT 18 +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_9_EMPTY_MASK_ADDR \ + WF_PSE_TOP_QUEUE_EMPTY_MASK_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_9_EMPTY_MASK_MASK \ + 0x00020000 /* HIF_9_EMPTY_MASK[17] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_9_EMPTY_MASK_SHFT 17 +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_8_EMPTY_MASK_ADDR \ + WF_PSE_TOP_QUEUE_EMPTY_MASK_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_8_EMPTY_MASK_MASK \ + 0x00010000 /* HIF_8_EMPTY_MASK[16] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_8_EMPTY_MASK_SHFT 16 +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_7_EMPTY_MASK_ADDR \ + WF_PSE_TOP_QUEUE_EMPTY_MASK_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_7_EMPTY_MASK_MASK \ + 0x00008000 /* HIF_7_EMPTY_MASK[15] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_7_EMPTY_MASK_SHFT 15 +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_6_EMPTY_MASK_ADDR \ + WF_PSE_TOP_QUEUE_EMPTY_MASK_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_6_EMPTY_MASK_MASK \ + 0x00004000 /* HIF_6_EMPTY_MASK[14] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_6_EMPTY_MASK_SHFT 14 +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_5_EMPTY_MASK_ADDR \ + WF_PSE_TOP_QUEUE_EMPTY_MASK_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_5_EMPTY_MASK_MASK \ + 0x00002000 /* HIF_5_EMPTY_MASK[13] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_5_EMPTY_MASK_SHFT 13 +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_4_EMPTY_MASK_ADDR \ + WF_PSE_TOP_QUEUE_EMPTY_MASK_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_4_EMPTY_MASK_MASK \ + 0x00001000 /* HIF_4_EMPTY_MASK[12] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_4_EMPTY_MASK_SHFT 12 +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_3_EMPTY_MASK_ADDR \ + WF_PSE_TOP_QUEUE_EMPTY_MASK_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_3_EMPTY_MASK_MASK \ + 0x00000800 /* HIF_3_EMPTY_MASK[11] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_3_EMPTY_MASK_SHFT 11 +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_2_EMPTY_MASK_ADDR \ + WF_PSE_TOP_QUEUE_EMPTY_MASK_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_2_EMPTY_MASK_MASK \ + 0x00000400 /* HIF_2_EMPTY_MASK[10] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_2_EMPTY_MASK_SHFT 10 +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_1_EMPTY_MASK_ADDR \ + WF_PSE_TOP_QUEUE_EMPTY_MASK_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_1_EMPTY_MASK_MASK \ + 0x00000200 /* HIF_1_EMPTY_MASK[9] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_1_EMPTY_MASK_SHFT 9 +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_0_EMPTY_MASK_ADDR \ + WF_PSE_TOP_QUEUE_EMPTY_MASK_ADDR +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_0_EMPTY_MASK_MASK \ + 0x00000100 /* HIF_0_EMPTY_MASK[8] */ +#define WF_PSE_TOP_QUEUE_EMPTY_MASK_HIF_0_EMPTY_MASK_SHFT 8 + +/* +* ---FREEPG_START_END (0x820C8000 + 0xC0)--- +* FREEPG_START[11..0] - (RW) Start page setting of free pages +* RESERVED12[15..12] - (RO) Reserved bits +* FREEPG_END[27..16] - (RW) End page setting of free page +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_FREEPG_START_END_FREEPG_END_ADDR \ + WF_PSE_TOP_FREEPG_START_END_ADDR +#define WF_PSE_TOP_FREEPG_START_END_FREEPG_END_MASK \ + 0x0FFF0000 /* FREEPG_END[27..16] */ +#define WF_PSE_TOP_FREEPG_START_END_FREEPG_END_SHFT 16 +#define WF_PSE_TOP_FREEPG_START_END_FREEPG_START_ADDR \ + WF_PSE_TOP_FREEPG_START_END_ADDR +#define WF_PSE_TOP_FREEPG_START_END_FREEPG_START_MASK \ + 0x00000FFF /* FREEPG_START[11..0] */ +#define WF_PSE_TOP_FREEPG_START_END_FREEPG_START_SHFT 0 + +/* +* ---PSE_MODULE_CKG_DIS (0x820C8000 + 0xc4)--- +* DIS_FL_DYN_CKG[0] - (RW) Disable control of PSE frame link module +* dynamic clock gating function +* DIS_PL_DYN_CKG[1] - (RW) Disable control of PSE page link module +* dynamic clock gating function +* DIS_CPU_PORT_DYN_CKG[2] - (RW) Disable control of PSE CPU port +module +* dynamic clock gating function +* DIS_HIF_PORT_DYN_CKG[3] - (RW) Disable control of PSE HIF port +module +* dynamic clock gating function +* DIS_WF_PLE_PORT_DYN_CKG[4] - (RW) Disable control of PSE LMAC and +* PLE port +* module dynamic clock gating function +* DIS_RLS_DYN_CKG[5] - (RW) Disable control of PSE release module +* dynamic clock gating function +* DIS_RL_DYN_CKG[6] - (RW) Disable control of PSE relay information +* module dynamic clock gating function +* RESERVED7[8..7] - (RO) Reserved bits +* DIS_CSR_DYN_CKG[9] - (RW) Disable control of PSE CR module dynamic +* clock gating function +* DIS_CPU_WRAP_DYN_CKG[10] - (RW) Disable control of PSE CPU_WRAP +module +* dynamic clock gating function +* DIS_DBG_DYN_CKG[11] - (RW) Disable control of PSE debug module +* dynamic clock gating function +* DIS_MDP_DYN_CKG[12] - (RW) Disable control of PSE MDP module +* dynamic clock gating function +* DIS_SEC_DYN_CKG[13] - (RW) Disable control of PSE SEC module +* dynamic clock gating function +* RESERVED14[31..14] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_SEC_DYN_CKG_ADDR \ + WF_PSE_TOP_PSE_MODULE_CKG_DIS_ADDR +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_SEC_DYN_CKG_MASK \ + 0x00002000 /* DIS_SEC_DYN_CKG[13] */ +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_SEC_DYN_CKG_SHFT 13 +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_MDP_DYN_CKG_ADDR \ + WF_PSE_TOP_PSE_MODULE_CKG_DIS_ADDR +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_MDP_DYN_CKG_MASK \ + 0x00001000 /* DIS_MDP_DYN_CKG[12] */ +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_MDP_DYN_CKG_SHFT 12 +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_DBG_DYN_CKG_ADDR \ + WF_PSE_TOP_PSE_MODULE_CKG_DIS_ADDR +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_DBG_DYN_CKG_MASK \ + 0x00000800 /* DIS_DBG_DYN_CKG[11] */ +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_DBG_DYN_CKG_SHFT 11 +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_CPU_WRAP_DYN_CKG_ADDR \ + WF_PSE_TOP_PSE_MODULE_CKG_DIS_ADDR +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_CPU_WRAP_DYN_CKG_MASK \ + 0x00000400 /* DIS_CPU_WRAP_DYN_CKG[10] */ +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_CPU_WRAP_DYN_CKG_SHFT 10 +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_CSR_DYN_CKG_ADDR \ + WF_PSE_TOP_PSE_MODULE_CKG_DIS_ADDR +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_CSR_DYN_CKG_MASK \ + 0x00000200 /* DIS_CSR_DYN_CKG[9] */ +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_CSR_DYN_CKG_SHFT 9 +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_RL_DYN_CKG_ADDR \ + WF_PSE_TOP_PSE_MODULE_CKG_DIS_ADDR +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_RL_DYN_CKG_MASK \ + 0x00000040 /* DIS_RL_DYN_CKG[6] */ +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_RL_DYN_CKG_SHFT 6 +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_RLS_DYN_CKG_ADDR \ + WF_PSE_TOP_PSE_MODULE_CKG_DIS_ADDR +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_RLS_DYN_CKG_MASK \ + 0x00000020 /* DIS_RLS_DYN_CKG[5] */ +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_RLS_DYN_CKG_SHFT 5 +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_WF_PLE_PORT_DYN_CKG_ADDR \ + WF_PSE_TOP_PSE_MODULE_CKG_DIS_ADDR +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_WF_PLE_PORT_DYN_CKG_MASK \ + 0x00000010 /* DIS_WF_PLE_PORT_DYN_CKG[4] */ +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_WF_PLE_PORT_DYN_CKG_SHFT 4 +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_HIF_PORT_DYN_CKG_ADDR \ + WF_PSE_TOP_PSE_MODULE_CKG_DIS_ADDR +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_HIF_PORT_DYN_CKG_MASK \ + 0x00000008 /* DIS_HIF_PORT_DYN_CKG[3] */ +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_HIF_PORT_DYN_CKG_SHFT 3 +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_CPU_PORT_DYN_CKG_ADDR \ + WF_PSE_TOP_PSE_MODULE_CKG_DIS_ADDR +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_CPU_PORT_DYN_CKG_MASK \ + 0x00000004 /* DIS_CPU_PORT_DYN_CKG[2] */ +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_CPU_PORT_DYN_CKG_SHFT 2 +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_PL_DYN_CKG_ADDR \ + WF_PSE_TOP_PSE_MODULE_CKG_DIS_ADDR +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_PL_DYN_CKG_MASK \ + 0x00000002 /* DIS_PL_DYN_CKG[1] */ +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_PL_DYN_CKG_SHFT 1 +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_FL_DYN_CKG_ADDR \ + WF_PSE_TOP_PSE_MODULE_CKG_DIS_ADDR +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_FL_DYN_CKG_MASK \ + 0x00000001 /* DIS_FL_DYN_CKG[0] */ +#define WF_PSE_TOP_PSE_MODULE_CKG_DIS_DIS_FL_DYN_CKG_SHFT 0 + +/* +* ---TO_N9_INT (0x820C8000 + 0xf0)--- +* CR4_CMD[30..0] - (RW) Command for N9 +* TOGGLE[31] - (RW) When this bit is toggled, HW will send +* interrupt to N9. +*/ +#define WF_PSE_TOP_TO_N9_INT_TOGGLE_ADDR WF_PSE_TOP_TO_N9_INT_ADDR +#define WF_PSE_TOP_TO_N9_INT_TOGGLE_MASK 0x80000000 /* TOGGLE[31] */ +#define WF_PSE_TOP_TO_N9_INT_TOGGLE_SHFT 31 +#define WF_PSE_TOP_TO_N9_INT_CR4_CMD_ADDR WF_PSE_TOP_TO_N9_INT_ADDR +#define WF_PSE_TOP_TO_N9_INT_CR4_CMD_MASK \ + 0x7FFFFFFF /* CR4_CMD[30..0] */ +#define WF_PSE_TOP_TO_N9_INT_CR4_CMD_SHFT 0 + +/* +* ---FREEPG_CNT (0x820C8000 + 0x100)--- +* FREEPG_CNT[11..0] - (RO) Total page number of free +* RESERVED12[15..12] - (RO) Reserved bits +* FFA_CNT[27..16] - (RO) Free page numbers of free for all +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_FREEPG_CNT_FFA_CNT_ADDR WF_PSE_TOP_FREEPG_CNT_ADDR +#define WF_PSE_TOP_FREEPG_CNT_FFA_CNT_MASK \ + 0x0FFF0000 /* FFA_CNT[27..16] */ +#define WF_PSE_TOP_FREEPG_CNT_FFA_CNT_SHFT 16 +#define WF_PSE_TOP_FREEPG_CNT_FREEPG_CNT_ADDR \ + WF_PSE_TOP_FREEPG_CNT_ADDR +#define WF_PSE_TOP_FREEPG_CNT_FREEPG_CNT_MASK \ + 0x00000FFF /* FREEPG_CNT[11..0] */ +#define WF_PSE_TOP_FREEPG_CNT_FREEPG_CNT_SHFT 0 + +/* +* ---FREEPG_HEAD_TAIL (0x820C8000 + 0x104)--- +* FREEPG_HEAD[11..0] - (RO) Head page of free page list +* RESERVED12[15..12] - (RO) Reserved bits +* FREEPG_TAIL[27..16] - (RO) Tail page of free page list +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_FREEPG_HEAD_TAIL_FREEPG_TAIL_ADDR \ + WF_PSE_TOP_FREEPG_HEAD_TAIL_ADDR +#define WF_PSE_TOP_FREEPG_HEAD_TAIL_FREEPG_TAIL_MASK \ + 0x0FFF0000 /* FREEPG_TAIL[27..16] */ +#define WF_PSE_TOP_FREEPG_HEAD_TAIL_FREEPG_TAIL_SHFT 16 +#define WF_PSE_TOP_FREEPG_HEAD_TAIL_FREEPG_HEAD_ADDR \ + WF_PSE_TOP_FREEPG_HEAD_TAIL_ADDR +#define WF_PSE_TOP_FREEPG_HEAD_TAIL_FREEPG_HEAD_MASK \ + 0x00000FFF /* FREEPG_HEAD[11..0] */ +#define WF_PSE_TOP_FREEPG_HEAD_TAIL_FREEPG_HEAD_SHFT 0 + +/* +* ---GROUP_REFILL_CTRL (0x820C8000 + 0x108)--- +* GROUP_REFILL_PRI[8..0] - (RW) group refill priority control +* RESERVED9[15..9] - (RO) Reserved bits +* DIS_GROUP_REFILL[24..16] - (RW) group quota refill enable control +* RESERVED25[31..25] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_GROUP_REFILL_CTRL_DIS_GROUP_REFILL_ADDR \ + WF_PSE_TOP_GROUP_REFILL_CTRL_ADDR +#define WF_PSE_TOP_GROUP_REFILL_CTRL_DIS_GROUP_REFILL_MASK \ + 0x01FF0000 /* DIS_GROUP_REFILL[24..16] */ +#define WF_PSE_TOP_GROUP_REFILL_CTRL_DIS_GROUP_REFILL_SHFT 16 +#define WF_PSE_TOP_GROUP_REFILL_CTRL_GROUP_REFILL_PRI_ADDR \ + WF_PSE_TOP_GROUP_REFILL_CTRL_ADDR +#define WF_PSE_TOP_GROUP_REFILL_CTRL_GROUP_REFILL_PRI_MASK \ + 0x000001FF /* GROUP_REFILL_PRI[8..0] */ +#define WF_PSE_TOP_GROUP_REFILL_CTRL_GROUP_REFILL_PRI_SHFT 0 + +/* +* ---PG_HIF0_GROUP (0x820C8000 + 0x110)--- +* HIF0_MIN_QUOTA[11..0] - (RW) Min. quota of HIF 0 group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED12[15..12] - (RO) Reserved bits +* HIF0_MAX_QUOTA[27..16] - (RW) Max. quota of HIF 0 group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PG_HIF0_GROUP_HIF0_MAX_QUOTA_ADDR \ + WF_PSE_TOP_PG_HIF0_GROUP_ADDR +#define WF_PSE_TOP_PG_HIF0_GROUP_HIF0_MAX_QUOTA_MASK \ + 0x0FFF0000 /* HIF0_MAX_QUOTA[27..16] */ +#define WF_PSE_TOP_PG_HIF0_GROUP_HIF0_MAX_QUOTA_SHFT 16 +#define WF_PSE_TOP_PG_HIF0_GROUP_HIF0_MIN_QUOTA_ADDR \ + WF_PSE_TOP_PG_HIF0_GROUP_ADDR +#define WF_PSE_TOP_PG_HIF0_GROUP_HIF0_MIN_QUOTA_MASK \ + 0x00000FFF /* HIF0_MIN_QUOTA[11..0] */ +#define WF_PSE_TOP_PG_HIF0_GROUP_HIF0_MIN_QUOTA_SHFT 0 + +/* +* ---HIF0_PG_INFO (0x820C8000 + 0x114)--- +* HIF0_RSV_CNT[11..0] - (RO) Reserved pages of HIF 0 group +* RESERVED12[15..12] - (RO) Reserved bits +* HIF0_SRC_CNT[27..16] - (RO) Used pages of HIF 0 group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_HIF0_PG_INFO_HIF0_SRC_CNT_ADDR \ + WF_PSE_TOP_HIF0_PG_INFO_ADDR +#define WF_PSE_TOP_HIF0_PG_INFO_HIF0_SRC_CNT_MASK \ + 0x0FFF0000 /* HIF0_SRC_CNT[27..16] */ +#define WF_PSE_TOP_HIF0_PG_INFO_HIF0_SRC_CNT_SHFT 16 +#define WF_PSE_TOP_HIF0_PG_INFO_HIF0_RSV_CNT_ADDR \ + WF_PSE_TOP_HIF0_PG_INFO_ADDR +#define WF_PSE_TOP_HIF0_PG_INFO_HIF0_RSV_CNT_MASK \ + 0x00000FFF /* HIF0_RSV_CNT[11..0] */ +#define WF_PSE_TOP_HIF0_PG_INFO_HIF0_RSV_CNT_SHFT 0 + +/* +* ---PG_HIF1_GROUP (0x820C8000 + 0x118)--- +* HIF1_MIN_QUOTA[11..0] - (RW) Min. quota of HIF 1 group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED12[15..12] - (RO) Reserved bits +* HIF1_MAX_QUOTA[27..16] - (RW) Max. quota of HIF 1 group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PG_HIF1_GROUP_HIF1_MAX_QUOTA_ADDR \ + WF_PSE_TOP_PG_HIF1_GROUP_ADDR +#define WF_PSE_TOP_PG_HIF1_GROUP_HIF1_MAX_QUOTA_MASK \ + 0x0FFF0000 /* HIF1_MAX_QUOTA[27..16] */ +#define WF_PSE_TOP_PG_HIF1_GROUP_HIF1_MAX_QUOTA_SHFT 16 +#define WF_PSE_TOP_PG_HIF1_GROUP_HIF1_MIN_QUOTA_ADDR \ + WF_PSE_TOP_PG_HIF1_GROUP_ADDR +#define WF_PSE_TOP_PG_HIF1_GROUP_HIF1_MIN_QUOTA_MASK \ + 0x00000FFF /* HIF1_MIN_QUOTA[11..0] */ +#define WF_PSE_TOP_PG_HIF1_GROUP_HIF1_MIN_QUOTA_SHFT 0 + +/* +* ---HIF1_PG_INFO (0x820C8000 + 0x11C)--- +* HIF1_RSV_CNT[11..0] - (RO) Reserved pages of HIF 1 group +* RESERVED12[15..12] - (RO) Reserved bits +* HIF1_SRC_CNT[27..16] - (RO) Used pages of HIF 1 group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_HIF1_PG_INFO_HIF1_SRC_CNT_ADDR \ + WF_PSE_TOP_HIF1_PG_INFO_ADDR +#define WF_PSE_TOP_HIF1_PG_INFO_HIF1_SRC_CNT_MASK \ + 0x0FFF0000 /* HIF1_SRC_CNT[27..16] */ +#define WF_PSE_TOP_HIF1_PG_INFO_HIF1_SRC_CNT_SHFT 16 +#define WF_PSE_TOP_HIF1_PG_INFO_HIF1_RSV_CNT_ADDR \ + WF_PSE_TOP_HIF1_PG_INFO_ADDR +#define WF_PSE_TOP_HIF1_PG_INFO_HIF1_RSV_CNT_MASK \ + 0x00000FFF /* HIF1_RSV_CNT[11..0] */ +#define WF_PSE_TOP_HIF1_PG_INFO_HIF1_RSV_CNT_SHFT 0 + +/* +* ---PG_CPU_GROUP (0x820C8000 + 0x150)--- +* CPU_MIN_QUOTA[11..0] - (RW) Min. quota of CPU group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED12[15..12] - (RO) Reserved bits +* CPU_MAX_QUOTA[27..16] - (RW) Max. quota of CPU group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PG_CPU_GROUP_CPU_MAX_QUOTA_ADDR \ + WF_PSE_TOP_PG_CPU_GROUP_ADDR +#define WF_PSE_TOP_PG_CPU_GROUP_CPU_MAX_QUOTA_MASK \ + 0x0FFF0000 /* CPU_MAX_QUOTA[27..16] */ +#define WF_PSE_TOP_PG_CPU_GROUP_CPU_MAX_QUOTA_SHFT 16 +#define WF_PSE_TOP_PG_CPU_GROUP_CPU_MIN_QUOTA_ADDR \ + WF_PSE_TOP_PG_CPU_GROUP_ADDR +#define WF_PSE_TOP_PG_CPU_GROUP_CPU_MIN_QUOTA_MASK \ + 0x00000FFF /* CPU_MIN_QUOTA[11..0] */ +#define WF_PSE_TOP_PG_CPU_GROUP_CPU_MIN_QUOTA_SHFT 0 + +/* +* ---CPU_PG_INFO (0x820C8000 + 0x154)--- +* CPU_RSV_CNT[11..0] - (RO) Reserved pages of CPU group +* RESERVED12[15..12] - (RO) Reserved bits +* CPU_SRC_CNT[27..16] - (RO) Used pages of CPU group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_CPU_PG_INFO_CPU_SRC_CNT_ADDR \ + WF_PSE_TOP_CPU_PG_INFO_ADDR +#define WF_PSE_TOP_CPU_PG_INFO_CPU_SRC_CNT_MASK \ + 0x0FFF0000 /* CPU_SRC_CNT[27..16] */ +#define WF_PSE_TOP_CPU_PG_INFO_CPU_SRC_CNT_SHFT 16 +#define WF_PSE_TOP_CPU_PG_INFO_CPU_RSV_CNT_ADDR \ + WF_PSE_TOP_CPU_PG_INFO_ADDR +#define WF_PSE_TOP_CPU_PG_INFO_CPU_RSV_CNT_MASK \ + 0x00000FFF /* CPU_RSV_CNT[11..0] */ +#define WF_PSE_TOP_CPU_PG_INFO_CPU_RSV_CNT_SHFT 0 + +/* +* ---PG_PLE_GROUP (0x820C8000 + 0x160)--- +* PLE_MIN_QUOTA[11..0] - (RW) Min. quota of PLE group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED12[15..12] - (RO) Reserved bits +* PLE_MAX_QUOTA[27..16] - (RW) Max. quota of PLE group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PG_PLE_GROUP_PLE_MAX_QUOTA_ADDR \ + WF_PSE_TOP_PG_PLE_GROUP_ADDR +#define WF_PSE_TOP_PG_PLE_GROUP_PLE_MAX_QUOTA_MASK \ + 0x0FFF0000 /* PLE_MAX_QUOTA[27..16] */ +#define WF_PSE_TOP_PG_PLE_GROUP_PLE_MAX_QUOTA_SHFT 16 +#define WF_PSE_TOP_PG_PLE_GROUP_PLE_MIN_QUOTA_ADDR \ + WF_PSE_TOP_PG_PLE_GROUP_ADDR +#define WF_PSE_TOP_PG_PLE_GROUP_PLE_MIN_QUOTA_MASK \ + 0x00000FFF /* PLE_MIN_QUOTA[11..0] */ +#define WF_PSE_TOP_PG_PLE_GROUP_PLE_MIN_QUOTA_SHFT 0 + +/* +* ---PLE_PG_INFO (0x820C8000 + 0x164)--- +* PLE_RSV_CNT[11..0] - (RO) Reserved pages of PLE group +* RESERVED12[15..12] - (RO) Reserved bits +* PLE_SRC_CNT[27..16] - (RO) Used pages of PLE group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PLE_PG_INFO_PLE_SRC_CNT_ADDR \ + WF_PSE_TOP_PLE_PG_INFO_ADDR +#define WF_PSE_TOP_PLE_PG_INFO_PLE_SRC_CNT_MASK \ + 0x0FFF0000 /* PLE_SRC_CNT[27..16] */ +#define WF_PSE_TOP_PLE_PG_INFO_PLE_SRC_CNT_SHFT 16 +#define WF_PSE_TOP_PLE_PG_INFO_PLE_RSV_CNT_ADDR \ + WF_PSE_TOP_PLE_PG_INFO_ADDR +#define WF_PSE_TOP_PLE_PG_INFO_PLE_RSV_CNT_MASK \ + 0x00000FFF /* PLE_RSV_CNT[11..0] */ +#define WF_PSE_TOP_PLE_PG_INFO_PLE_RSV_CNT_SHFT 0 + +/* +* ---PG_PLE1_GROUP (0x820C8000 + 0x168)--- +* PLE_MIN_QUOTA[11..0] - (RW) Min. quota of PLE group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED12[15..12] - (RO) Reserved bits +* PLE_MAX_QUOTA[27..16] - (RW) Max. quota of PLE group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PG_PLE1_GROUP_PLE_MAX_QUOTA_ADDR \ + WF_PSE_TOP_PG_PLE1_GROUP_ADDR +#define WF_PSE_TOP_PG_PLE1_GROUP_PLE_MAX_QUOTA_MASK \ + 0x0FFF0000 /* PLE_MAX_QUOTA[27..16] */ +#define WF_PSE_TOP_PG_PLE1_GROUP_PLE_MAX_QUOTA_SHFT 16 +#define WF_PSE_TOP_PG_PLE1_GROUP_PLE_MIN_QUOTA_ADDR \ + WF_PSE_TOP_PG_PLE1_GROUP_ADDR +#define WF_PSE_TOP_PG_PLE1_GROUP_PLE_MIN_QUOTA_MASK \ + 0x00000FFF /* PLE_MIN_QUOTA[11..0] */ +#define WF_PSE_TOP_PG_PLE1_GROUP_PLE_MIN_QUOTA_SHFT 0 + +/* +* ---PLE1_PG_INFO (0x820C8000 + 0x16C)--- +* PLE_RSV_CNT[11..0] - (RO) Reserved pages of PLE group +* RESERVED12[15..12] - (RO) Reserved bits +* PLE_SRC_CNT[27..16] - (RO) Used pages of PLE group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PLE1_PG_INFO_PLE_SRC_CNT_ADDR \ + WF_PSE_TOP_PLE1_PG_INFO_ADDR +#define WF_PSE_TOP_PLE1_PG_INFO_PLE_SRC_CNT_MASK \ + 0x0FFF0000 /* PLE_SRC_CNT[27..16] */ +#define WF_PSE_TOP_PLE1_PG_INFO_PLE_SRC_CNT_SHFT 16 +#define WF_PSE_TOP_PLE1_PG_INFO_PLE_RSV_CNT_ADDR \ + WF_PSE_TOP_PLE1_PG_INFO_ADDR +#define WF_PSE_TOP_PLE1_PG_INFO_PLE_RSV_CNT_MASK \ + 0x00000FFF /* PLE_RSV_CNT[11..0] */ +#define WF_PSE_TOP_PLE1_PG_INFO_PLE_RSV_CNT_SHFT 0 + +/* +* ---PG_LMAC0_GROUP (0x820C8000 + 0x170)--- +* LMAC0_MIN_QUOTA[11..0] - (RW) Min. quota of LMAC 0 group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED12[15..12] - (RO) Reserved bits +* LMAC0_MAX_QUOTA[27..16] - (RW) Max. quota of LMAC 0 group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PG_LMAC0_GROUP_LMAC0_MAX_QUOTA_ADDR \ + WF_PSE_TOP_PG_LMAC0_GROUP_ADDR +#define WF_PSE_TOP_PG_LMAC0_GROUP_LMAC0_MAX_QUOTA_MASK \ + 0x0FFF0000 /* LMAC0_MAX_QUOTA[27..16] */ +#define WF_PSE_TOP_PG_LMAC0_GROUP_LMAC0_MAX_QUOTA_SHFT 16 +#define WF_PSE_TOP_PG_LMAC0_GROUP_LMAC0_MIN_QUOTA_ADDR \ + WF_PSE_TOP_PG_LMAC0_GROUP_ADDR +#define WF_PSE_TOP_PG_LMAC0_GROUP_LMAC0_MIN_QUOTA_MASK \ + 0x00000FFF /* LMAC0_MIN_QUOTA[11..0] */ +#define WF_PSE_TOP_PG_LMAC0_GROUP_LMAC0_MIN_QUOTA_SHFT 0 + +/* +* ---LMAC0_PG_INFO (0x820C8000 + 0x174)--- +* LMAC0_RSV_CNT[11..0] - (RO) Reserved pages of LMAC 0 group +* RESERVED12[15..12] - (RO) Reserved bits +* LMAC0_SRC_CNT[27..16] - (RO) Used pages of LMAC 0 group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_LMAC0_PG_INFO_LMAC0_SRC_CNT_ADDR \ + WF_PSE_TOP_LMAC0_PG_INFO_ADDR +#define WF_PSE_TOP_LMAC0_PG_INFO_LMAC0_SRC_CNT_MASK \ + 0x0FFF0000 /* LMAC0_SRC_CNT[27..16] */ +#define WF_PSE_TOP_LMAC0_PG_INFO_LMAC0_SRC_CNT_SHFT 16 +#define WF_PSE_TOP_LMAC0_PG_INFO_LMAC0_RSV_CNT_ADDR \ + WF_PSE_TOP_LMAC0_PG_INFO_ADDR +#define WF_PSE_TOP_LMAC0_PG_INFO_LMAC0_RSV_CNT_MASK \ + 0x00000FFF /* LMAC0_RSV_CNT[11..0] */ +#define WF_PSE_TOP_LMAC0_PG_INFO_LMAC0_RSV_CNT_SHFT 0 + +/* +* ---PG_LMAC1_GROUP (0x820C8000 + 0x178)--- +* LMAC1_MIN_QUOTA[11..0] - (RW) Min. quota of LMAC 1 group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED12[15..12] - (RO) Reserved bits +* LMAC1_MAX_QUOTA[27..16] - (RW) Max. quota of LMAC 1 group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PG_LMAC1_GROUP_LMAC1_MAX_QUOTA_ADDR \ + WF_PSE_TOP_PG_LMAC1_GROUP_ADDR +#define WF_PSE_TOP_PG_LMAC1_GROUP_LMAC1_MAX_QUOTA_MASK \ + 0x0FFF0000 /* LMAC1_MAX_QUOTA[27..16] */ +#define WF_PSE_TOP_PG_LMAC1_GROUP_LMAC1_MAX_QUOTA_SHFT 16 +#define WF_PSE_TOP_PG_LMAC1_GROUP_LMAC1_MIN_QUOTA_ADDR \ + WF_PSE_TOP_PG_LMAC1_GROUP_ADDR +#define WF_PSE_TOP_PG_LMAC1_GROUP_LMAC1_MIN_QUOTA_MASK \ + 0x00000FFF /* LMAC1_MIN_QUOTA[11..0] */ +#define WF_PSE_TOP_PG_LMAC1_GROUP_LMAC1_MIN_QUOTA_SHFT 0 + +/* +* ---LMAC1_PG_INFO (0x820C8000 + 0x17C)--- +* LMAC1_RSV_CNT[11..0] - (RO) Reserved pages of LMAC 1 group +* RESERVED12[15..12] - (RO) Reserved bits +* LMAC1_SRC_CNT[27..16] - (RO) Used pages of LMAC 1 group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_LMAC1_PG_INFO_LMAC1_SRC_CNT_ADDR \ + WF_PSE_TOP_LMAC1_PG_INFO_ADDR +#define WF_PSE_TOP_LMAC1_PG_INFO_LMAC1_SRC_CNT_MASK \ + 0x0FFF0000 /* LMAC1_SRC_CNT[27..16] */ +#define WF_PSE_TOP_LMAC1_PG_INFO_LMAC1_SRC_CNT_SHFT 16 +#define WF_PSE_TOP_LMAC1_PG_INFO_LMAC1_RSV_CNT_ADDR \ + WF_PSE_TOP_LMAC1_PG_INFO_ADDR +#define WF_PSE_TOP_LMAC1_PG_INFO_LMAC1_RSV_CNT_MASK \ + 0x00000FFF /* LMAC1_RSV_CNT[11..0] */ +#define WF_PSE_TOP_LMAC1_PG_INFO_LMAC1_RSV_CNT_SHFT 0 + +/* +* ---PG_LMAC2_GROUP (0x820C8000 + 0x180)--- +* LMAC2_MIN_QUOTA[11..0] - (RW) Min. quota of LMAC 2 group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED12[15..12] - (RO) Reserved bits +* LMAC2_MAX_QUOTA[27..16] - (RW) Max. quota of LMAC 2 group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PG_LMAC2_GROUP_LMAC2_MAX_QUOTA_ADDR \ + WF_PSE_TOP_PG_LMAC2_GROUP_ADDR +#define WF_PSE_TOP_PG_LMAC2_GROUP_LMAC2_MAX_QUOTA_MASK \ + 0x0FFF0000 /* LMAC2_MAX_QUOTA[27..16] */ +#define WF_PSE_TOP_PG_LMAC2_GROUP_LMAC2_MAX_QUOTA_SHFT 16 +#define WF_PSE_TOP_PG_LMAC2_GROUP_LMAC2_MIN_QUOTA_ADDR \ + WF_PSE_TOP_PG_LMAC2_GROUP_ADDR +#define WF_PSE_TOP_PG_LMAC2_GROUP_LMAC2_MIN_QUOTA_MASK \ + 0x00000FFF /* LMAC2_MIN_QUOTA[11..0] */ +#define WF_PSE_TOP_PG_LMAC2_GROUP_LMAC2_MIN_QUOTA_SHFT 0 + +/* +* ---LMAC2_PG_INFO (0x820C8000 + 0x184)--- +* LMAC2_RSV_CNT[11..0] - (RO) Reserved pages of LMAC 2 group +* RESERVED12[15..12] - (RO) Reserved bits +* LMAC2_SRC_CNT[27..16] - (RO) Used pages of LMAC 2 group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_LMAC2_PG_INFO_LMAC2_SRC_CNT_ADDR \ + WF_PSE_TOP_LMAC2_PG_INFO_ADDR +#define WF_PSE_TOP_LMAC2_PG_INFO_LMAC2_SRC_CNT_MASK \ + 0x0FFF0000 /* LMAC2_SRC_CNT[27..16] */ +#define WF_PSE_TOP_LMAC2_PG_INFO_LMAC2_SRC_CNT_SHFT 16 +#define WF_PSE_TOP_LMAC2_PG_INFO_LMAC2_RSV_CNT_ADDR \ + WF_PSE_TOP_LMAC2_PG_INFO_ADDR +#define WF_PSE_TOP_LMAC2_PG_INFO_LMAC2_RSV_CNT_MASK \ + 0x00000FFF /* LMAC2_RSV_CNT[11..0] */ +#define WF_PSE_TOP_LMAC2_PG_INFO_LMAC2_RSV_CNT_SHFT 0 + +/* +* ---PG_LMAC3_GROUP (0x820C8000 + 0x188)--- +* LMAC3_MIN_QUOTA[11..0] - (RW) Min. quota of LMAC 3 group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED12[15..12] - (RO) Reserved bits +* LMAC3_MAX_QUOTA[27..16] - (RW) Max. quota of LMAC 3 group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PG_LMAC3_GROUP_LMAC3_MAX_QUOTA_ADDR \ + WF_PSE_TOP_PG_LMAC3_GROUP_ADDR +#define WF_PSE_TOP_PG_LMAC3_GROUP_LMAC3_MAX_QUOTA_MASK \ + 0x0FFF0000 /* LMAC3_MAX_QUOTA[27..16] */ +#define WF_PSE_TOP_PG_LMAC3_GROUP_LMAC3_MAX_QUOTA_SHFT 16 +#define WF_PSE_TOP_PG_LMAC3_GROUP_LMAC3_MIN_QUOTA_ADDR \ + WF_PSE_TOP_PG_LMAC3_GROUP_ADDR +#define WF_PSE_TOP_PG_LMAC3_GROUP_LMAC3_MIN_QUOTA_MASK \ + 0x00000FFF /* LMAC3_MIN_QUOTA[11..0] */ +#define WF_PSE_TOP_PG_LMAC3_GROUP_LMAC3_MIN_QUOTA_SHFT 0 + +/* +* ---LMAC3_PG_INFO (0x820C8000 + 0x18C)--- +* LMAC3_RSV_CNT[11..0] - (RO) Reserved pages of LMAC 3 group +* RESERVED12[15..12] - (RO) Reserved bits +* LMAC3_SRC_CNT[27..16] - (RO) Used pages of LMAC 3 group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_LMAC3_PG_INFO_LMAC3_SRC_CNT_ADDR \ + WF_PSE_TOP_LMAC3_PG_INFO_ADDR +#define WF_PSE_TOP_LMAC3_PG_INFO_LMAC3_SRC_CNT_MASK \ + 0x0FFF0000 /* LMAC3_SRC_CNT[27..16] */ +#define WF_PSE_TOP_LMAC3_PG_INFO_LMAC3_SRC_CNT_SHFT 16 +#define WF_PSE_TOP_LMAC3_PG_INFO_LMAC3_RSV_CNT_ADDR \ + WF_PSE_TOP_LMAC3_PG_INFO_ADDR +#define WF_PSE_TOP_LMAC3_PG_INFO_LMAC3_RSV_CNT_MASK \ + 0x00000FFF /* LMAC3_RSV_CNT[11..0] */ +#define WF_PSE_TOP_LMAC3_PG_INFO_LMAC3_RSV_CNT_SHFT 0 + +/* +* ---PG_MDP_GROUP (0x820C8000 + 0x198)--- +* MDP_MIN_QUOTA[11..0] - (RW) Min. quota of MDP group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED12[15..12] - (RO) Reserved bits +* MDP_MAX_QUOTA[27..16] - (RW) Max. quota of MDP group +* Set up the quota before releasing PSE logic +* reset; it should not be changed after logic reset is released. +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PG_MDP_GROUP_MDP_MAX_QUOTA_ADDR \ + WF_PSE_TOP_PG_MDP_GROUP_ADDR +#define WF_PSE_TOP_PG_MDP_GROUP_MDP_MAX_QUOTA_MASK \ + 0x0FFF0000 /* MDP_MAX_QUOTA[27..16] */ +#define WF_PSE_TOP_PG_MDP_GROUP_MDP_MAX_QUOTA_SHFT 16 +#define WF_PSE_TOP_PG_MDP_GROUP_MDP_MIN_QUOTA_ADDR \ + WF_PSE_TOP_PG_MDP_GROUP_ADDR +#define WF_PSE_TOP_PG_MDP_GROUP_MDP_MIN_QUOTA_MASK \ + 0x00000FFF /* MDP_MIN_QUOTA[11..0] */ +#define WF_PSE_TOP_PG_MDP_GROUP_MDP_MIN_QUOTA_SHFT 0 + +/* +* ---MDP_PG_INFO (0x820C8000 + 0x19C)--- +* MDP_RSV_CNT[11..0] - (RO) Reserved pages of MDP group +* RESERVED12[15..12] - (RO) Reserved bits +* MDP_SRC_CNT[27..16] - (RO) Used pages of MDP group +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_MDP_PG_INFO_MDP_SRC_CNT_ADDR \ + WF_PSE_TOP_MDP_PG_INFO_ADDR +#define WF_PSE_TOP_MDP_PG_INFO_MDP_SRC_CNT_MASK \ + 0x0FFF0000 /* MDP_SRC_CNT[27..16] */ +#define WF_PSE_TOP_MDP_PG_INFO_MDP_SRC_CNT_SHFT 16 +#define WF_PSE_TOP_MDP_PG_INFO_MDP_RSV_CNT_ADDR \ + WF_PSE_TOP_MDP_PG_INFO_ADDR +#define WF_PSE_TOP_MDP_PG_INFO_MDP_RSV_CNT_MASK \ + 0x00000FFF /* MDP_RSV_CNT[11..0] */ +#define WF_PSE_TOP_MDP_PG_INFO_MDP_RSV_CNT_SHFT 0 + +/* +* ---RL_BUF_CTRL_0 (0x820C8000 + 0x1A0)--- +* RELAY_BUF_ADDR[11..0] - (RW) Read address of relay buffer +* RESERVED12[30..12] - (RO) Reserved bits +* EXECUTE[31] - (A0) Executes relay buffer read command +*/ +#define WF_PSE_TOP_RL_BUF_CTRL_0_EXECUTE_ADDR \ + WF_PSE_TOP_RL_BUF_CTRL_0_ADDR +#define WF_PSE_TOP_RL_BUF_CTRL_0_EXECUTE_MASK \ + 0x80000000 /* EXECUTE[31] */ +#define WF_PSE_TOP_RL_BUF_CTRL_0_EXECUTE_SHFT 31 +#define WF_PSE_TOP_RL_BUF_CTRL_0_RELAY_BUF_ADDR_ADDR \ + WF_PSE_TOP_RL_BUF_CTRL_0_ADDR +#define WF_PSE_TOP_RL_BUF_CTRL_0_RELAY_BUF_ADDR_MASK \ + 0x00000FFF /* RELAY_BUF_ADDR[11..0] */ +#define WF_PSE_TOP_RL_BUF_CTRL_0_RELAY_BUF_ADDR_SHFT 0 + +/* +* ---RL_BUF_CTRL_1 (0x820C8000 + 0x1A4)--- +* PAGE_NUM[8..0] - (RO) Page number of packet +* RESERVED9[13..9] - (RO) Reserved bits +* PKT_TAIL_PAGE[25..14] - (RO) Tail page of the packet with head page +* being the relay buffer address +* RESERVED26[26] - (RO) Reserved bits +* RESV_GRP_ID[30..27] - (RO) Group ID of reserved page used by FID +* RESERVED31[31] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_RL_BUF_CTRL_1_RESV_GRP_ID_ADDR \ + WF_PSE_TOP_RL_BUF_CTRL_1_ADDR +#define WF_PSE_TOP_RL_BUF_CTRL_1_RESV_GRP_ID_MASK \ + 0x78000000 /* RESV_GRP_ID[30..27] */ +#define WF_PSE_TOP_RL_BUF_CTRL_1_RESV_GRP_ID_SHFT 27 +#define WF_PSE_TOP_RL_BUF_CTRL_1_PKT_TAIL_PAGE_ADDR \ + WF_PSE_TOP_RL_BUF_CTRL_1_ADDR +#define WF_PSE_TOP_RL_BUF_CTRL_1_PKT_TAIL_PAGE_MASK \ + 0x03FFC000 /* PKT_TAIL_PAGE[25..14] */ +#define WF_PSE_TOP_RL_BUF_CTRL_1_PKT_TAIL_PAGE_SHFT 14 +#define WF_PSE_TOP_RL_BUF_CTRL_1_PAGE_NUM_ADDR \ + WF_PSE_TOP_RL_BUF_CTRL_1_ADDR +#define WF_PSE_TOP_RL_BUF_CTRL_1_PAGE_NUM_MASK \ + 0x000001FF /* PAGE_NUM[8..0] */ +#define WF_PSE_TOP_RL_BUF_CTRL_1_PAGE_NUM_SHFT 0 + +/* +* ---FL_QUE_CTRL_0 (0x820C8000 + 0x1B0)--- +* Q_BUF_WLANID[9..0] - (RW) Address of queue structure buffer +WLANID. +* Q_BUF_PID[11..10] - (RW) Address of queue structure buffer PID +* FL_BUFFER_ADDR[23..12] - (RW) Frame address of read previous +* frame/next frame +* Q_BUF_QID[30..24] - (RW) Address of queue structure buffer QID +* EXECUTE[31] - (A0) Executes frame link and queue structure +* buffer read command +*/ +#define WF_PSE_TOP_FL_QUE_CTRL_0_EXECUTE_ADDR \ + WF_PSE_TOP_FL_QUE_CTRL_0_ADDR +#define WF_PSE_TOP_FL_QUE_CTRL_0_EXECUTE_MASK \ + 0x80000000 /* EXECUTE[31] */ +#define WF_PSE_TOP_FL_QUE_CTRL_0_EXECUTE_SHFT 31 +#define WF_PSE_TOP_FL_QUE_CTRL_0_Q_BUF_QID_ADDR \ + WF_PSE_TOP_FL_QUE_CTRL_0_ADDR +#define WF_PSE_TOP_FL_QUE_CTRL_0_Q_BUF_QID_MASK \ + 0x7F000000 /* Q_BUF_QID[30..24] */ +#define WF_PSE_TOP_FL_QUE_CTRL_0_Q_BUF_QID_SHFT 24 +#define WF_PSE_TOP_FL_QUE_CTRL_0_FL_BUFFER_ADDR_ADDR \ + WF_PSE_TOP_FL_QUE_CTRL_0_ADDR +#define WF_PSE_TOP_FL_QUE_CTRL_0_FL_BUFFER_ADDR_MASK \ + 0x00FFF000 /* FL_BUFFER_ADDR[23..12] */ +#define WF_PSE_TOP_FL_QUE_CTRL_0_FL_BUFFER_ADDR_SHFT 12 +#define WF_PSE_TOP_FL_QUE_CTRL_0_Q_BUF_PID_ADDR \ + WF_PSE_TOP_FL_QUE_CTRL_0_ADDR +#define WF_PSE_TOP_FL_QUE_CTRL_0_Q_BUF_PID_MASK \ + 0x00000C00 /* Q_BUF_PID[11..10] */ +#define WF_PSE_TOP_FL_QUE_CTRL_0_Q_BUF_PID_SHFT 10 +#define WF_PSE_TOP_FL_QUE_CTRL_0_Q_BUF_WLANID_ADDR \ + WF_PSE_TOP_FL_QUE_CTRL_0_ADDR +#define WF_PSE_TOP_FL_QUE_CTRL_0_Q_BUF_WLANID_MASK \ + 0x000003FF /* Q_BUF_WLANID[9..0] */ +#define WF_PSE_TOP_FL_QUE_CTRL_0_Q_BUF_WLANID_SHFT 0 + +/* +* ---FL_QUE_CTRL_1 (0x820C8000 + 0x1B4)--- +* NEXT_FID[11..0] - (RO) Next frame ID of FL_BUFFER_ADDR +* RESERVED12[15..12] - (RO) Reserved bits +* PREV_FID[27..16] - (RO) Previous frame ID of FL_BUFFER_ADDR +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_FL_QUE_CTRL_1_PREV_FID_ADDR \ + WF_PSE_TOP_FL_QUE_CTRL_1_ADDR +#define WF_PSE_TOP_FL_QUE_CTRL_1_PREV_FID_MASK \ + 0x0FFF0000 /* PREV_FID[27..16] */ +#define WF_PSE_TOP_FL_QUE_CTRL_1_PREV_FID_SHFT 16 +#define WF_PSE_TOP_FL_QUE_CTRL_1_NEXT_FID_ADDR \ + WF_PSE_TOP_FL_QUE_CTRL_1_ADDR +#define WF_PSE_TOP_FL_QUE_CTRL_1_NEXT_FID_MASK \ + 0x00000FFF /* NEXT_FID[11..0] */ +#define WF_PSE_TOP_FL_QUE_CTRL_1_NEXT_FID_SHFT 0 + +/* +* ---FL_QUE_CTRL_2 (0x820C8000 + 0x1B8)--- +* QUEUE_HEAD_FID[11..0] - (RO) Head frame ID of quest queue setting in +0x01b0[15:0] +* RESERVED12[15..12] - (RO) Reserved bits +* QUEUE_TAIL_FID[27..16] - (RO) Tail frame ID of quest queue setting +in +0x01b0[15:0] +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_FL_QUE_CTRL_2_QUEUE_TAIL_FID_ADDR \ + WF_PSE_TOP_FL_QUE_CTRL_2_ADDR +#define WF_PSE_TOP_FL_QUE_CTRL_2_QUEUE_TAIL_FID_MASK \ + 0x0FFF0000 /* QUEUE_TAIL_FID[27..16] */ +#define WF_PSE_TOP_FL_QUE_CTRL_2_QUEUE_TAIL_FID_SHFT 16 +#define WF_PSE_TOP_FL_QUE_CTRL_2_QUEUE_HEAD_FID_ADDR \ + WF_PSE_TOP_FL_QUE_CTRL_2_ADDR +#define WF_PSE_TOP_FL_QUE_CTRL_2_QUEUE_HEAD_FID_MASK \ + 0x00000FFF /* QUEUE_HEAD_FID[11..0] */ +#define WF_PSE_TOP_FL_QUE_CTRL_2_QUEUE_HEAD_FID_SHFT 0 + +/* +* ---FL_QUE_CTRL_3 (0x820C8000 + 0x1BC)--- +* QUEUE_PKT_NUM[11..0] - (RO) Total packet number of queue setting in +0x1b0[15:0] +* QUEUE_PAGE_NUM[23..12] - (RO) Total page number of queue setting in +0x1b0[15:0] +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_FL_QUE_CTRL_3_QUEUE_PAGE_NUM_ADDR \ + WF_PSE_TOP_FL_QUE_CTRL_3_ADDR +#define WF_PSE_TOP_FL_QUE_CTRL_3_QUEUE_PAGE_NUM_MASK \ + 0x00FFF000 /* QUEUE_PAGE_NUM[23..12] */ +#define WF_PSE_TOP_FL_QUE_CTRL_3_QUEUE_PAGE_NUM_SHFT 12 +#define WF_PSE_TOP_FL_QUE_CTRL_3_QUEUE_PKT_NUM_ADDR \ + WF_PSE_TOP_FL_QUE_CTRL_3_ADDR +#define WF_PSE_TOP_FL_QUE_CTRL_3_QUEUE_PKT_NUM_MASK \ + 0x00000FFF /* QUEUE_PKT_NUM[11..0] */ +#define WF_PSE_TOP_FL_QUE_CTRL_3_QUEUE_PKT_NUM_SHFT 0 + +/* +* ---PL_QUE_CTRL_0 (0x820C8000 + 0x1C0)--- +* NEXT_PAGE[11..0] - (RO) Next page of the PL_BUFFER_ADDR +* RESERVED12[15..12] - (RO) Reserved bits +* PL_BUFFER_ADDR[27..16] - (RW) Page address of read next page +* RESERVED28[30..28] - (RO) Reserved bits +* EXECUTE[31] - (A0) Executes page link buffer read command +*/ +#define WF_PSE_TOP_PL_QUE_CTRL_0_EXECUTE_ADDR \ + WF_PSE_TOP_PL_QUE_CTRL_0_ADDR +#define WF_PSE_TOP_PL_QUE_CTRL_0_EXECUTE_MASK \ + 0x80000000 /* EXECUTE[31] */ +#define WF_PSE_TOP_PL_QUE_CTRL_0_EXECUTE_SHFT 31 +#define WF_PSE_TOP_PL_QUE_CTRL_0_PL_BUFFER_ADDR_ADDR \ + WF_PSE_TOP_PL_QUE_CTRL_0_ADDR +#define WF_PSE_TOP_PL_QUE_CTRL_0_PL_BUFFER_ADDR_MASK \ + 0x0FFF0000 /* PL_BUFFER_ADDR[27..16] */ +#define WF_PSE_TOP_PL_QUE_CTRL_0_PL_BUFFER_ADDR_SHFT 16 +#define WF_PSE_TOP_PL_QUE_CTRL_0_NEXT_PAGE_ADDR \ + WF_PSE_TOP_PL_QUE_CTRL_0_ADDR +#define WF_PSE_TOP_PL_QUE_CTRL_0_NEXT_PAGE_MASK \ + 0x00000FFF /* NEXT_PAGE[11..0] */ +#define WF_PSE_TOP_PL_QUE_CTRL_0_NEXT_PAGE_SHFT 0 + +/* +* ---PSE_LP_CTRL (0x820C8000 + 0x1D0)--- +* RESERVED0[6..0] - (RO) Reserved bits +* PSE_LP_WAKEUP[7] - (RW) PSE Low Power Wakeup control +* PSE2HIF_PSSS_EN[8] - (RW) PSE Access HIF port control +* MCU_COALEASCE[9] - (RW) Coalease CPU ENQ and ENQ_DLY for HIF +port +* RESERVED10[31..10] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_LP_CTRL_MCU_COALEASCE_ADDR \ + WF_PSE_TOP_PSE_LP_CTRL_ADDR +#define WF_PSE_TOP_PSE_LP_CTRL_MCU_COALEASCE_MASK \ + 0x00000200 /* MCU_COALEASCE[9] */ +#define WF_PSE_TOP_PSE_LP_CTRL_MCU_COALEASCE_SHFT 9 +#define WF_PSE_TOP_PSE_LP_CTRL_PSE2HIF_PSSS_EN_ADDR \ + WF_PSE_TOP_PSE_LP_CTRL_ADDR +#define WF_PSE_TOP_PSE_LP_CTRL_PSE2HIF_PSSS_EN_MASK \ + 0x00000100 /* PSE2HIF_PSSS_EN[8] */ +#define WF_PSE_TOP_PSE_LP_CTRL_PSE2HIF_PSSS_EN_SHFT 8 +#define WF_PSE_TOP_PSE_LP_CTRL_PSE_LP_WAKEUP_ADDR \ + WF_PSE_TOP_PSE_LP_CTRL_ADDR +#define WF_PSE_TOP_PSE_LP_CTRL_PSE_LP_WAKEUP_MASK \ + 0x00000080 /* PSE_LP_WAKEUP[7] */ +#define WF_PSE_TOP_PSE_LP_CTRL_PSE_LP_WAKEUP_SHFT 7 + +/* +* ---PSE_WFDMA_BUF_CTRL (0x820C8000 + 0x1E0)--- +* WFDMA_TXS_BUF_VLD_TH[7..0] - (RW) TXS valid reserved page count +threshold +* WFDMA_TXCMD_BUF_VLD_TH[15..8] - (RW) TXCMD valid reserved page count +threshold +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_WFDMA_BUF_CTRL_WFDMA_TXCMD_BUF_VLD_TH_ADDR \ + WF_PSE_TOP_PSE_WFDMA_BUF_CTRL_ADDR +#define WF_PSE_TOP_PSE_WFDMA_BUF_CTRL_WFDMA_TXCMD_BUF_VLD_TH_MASK \ + 0x0000FF00 /* WFDMA_TXCMD_BUF_VLD_TH[15..8] */ +#define WF_PSE_TOP_PSE_WFDMA_BUF_CTRL_WFDMA_TXCMD_BUF_VLD_TH_SHFT 8 +#define WF_PSE_TOP_PSE_WFDMA_BUF_CTRL_WFDMA_TXS_BUF_VLD_TH_ADDR \ + WF_PSE_TOP_PSE_WFDMA_BUF_CTRL_ADDR +#define WF_PSE_TOP_PSE_WFDMA_BUF_CTRL_WFDMA_TXS_BUF_VLD_TH_MASK \ + 0x000000FF /* WFDMA_TXS_BUF_VLD_TH[7..0] */ +#define WF_PSE_TOP_PSE_WFDMA_BUF_CTRL_WFDMA_TXS_BUF_VLD_TH_SHFT 0 + +/* +* ---PSE_CT_PRI_CTRL (0x820C8000 + 0x1EC)--- +* PSE_CT_PRI_LOW_LV[11..0] - (RW) Low trigger level of Group0 qouta +* RESERVED12[15..12] - (RO) Reserved bits +* PSE_CT_PRI_HI_LV[27..16] - (RW) High trigger level of Group0 qouta +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_CT_PRI_CTRL_PSE_CT_PRI_HI_LV_ADDR \ + WF_PSE_TOP_PSE_CT_PRI_CTRL_ADDR +#define WF_PSE_TOP_PSE_CT_PRI_CTRL_PSE_CT_PRI_HI_LV_MASK \ + 0x0FFF0000 /* PSE_CT_PRI_HI_LV[27..16] */ +#define WF_PSE_TOP_PSE_CT_PRI_CTRL_PSE_CT_PRI_HI_LV_SHFT 16 +#define WF_PSE_TOP_PSE_CT_PRI_CTRL_PSE_CT_PRI_LOW_LV_ADDR \ + WF_PSE_TOP_PSE_CT_PRI_CTRL_ADDR +#define WF_PSE_TOP_PSE_CT_PRI_CTRL_PSE_CT_PRI_LOW_LV_MASK \ + 0x00000FFF /* PSE_CT_PRI_LOW_LV[11..0] */ +#define WF_PSE_TOP_PSE_CT_PRI_CTRL_PSE_CT_PRI_LOW_LV_SHFT 0 + +/* +* ---PLE_ENQ_PKT_NUM (0x820C8000 + 0x1F0)--- +* PLE_ENQ_HIF_Q_PKT_NUM[15..0] - (RO) The packets numbers of PLE port +enqueue +* to HIF queue. +* PLE_ENQ_HIF_Q_SEL[19..16] - (RW) Select HIF queue which is PLE port +* enqueue to. +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PLE_ENQ_PKT_NUM_PLE_ENQ_HIF_Q_SEL_ADDR \ + WF_PSE_TOP_PLE_ENQ_PKT_NUM_ADDR +#define WF_PSE_TOP_PLE_ENQ_PKT_NUM_PLE_ENQ_HIF_Q_SEL_MASK \ + 0x000F0000 /* PLE_ENQ_HIF_Q_SEL[19..16] */ +#define WF_PSE_TOP_PLE_ENQ_PKT_NUM_PLE_ENQ_HIF_Q_SEL_SHFT 16 +#define WF_PSE_TOP_PLE_ENQ_PKT_NUM_PLE_ENQ_HIF_Q_PKT_NUM_ADDR \ + WF_PSE_TOP_PLE_ENQ_PKT_NUM_ADDR +#define WF_PSE_TOP_PLE_ENQ_PKT_NUM_PLE_ENQ_HIF_Q_PKT_NUM_MASK \ + 0x0000FFFF /* PLE_ENQ_HIF_Q_PKT_NUM[15..0] */ +#define WF_PSE_TOP_PLE_ENQ_PKT_NUM_PLE_ENQ_HIF_Q_PKT_NUM_SHFT 0 + +/* +* ---CPU_ENQ_PKT_NUM (0x820C8000 + 0x1F4)--- +* CPU_ENQ_HIF_Q_PKT_NUM[15..0] - (RO) The packets numbers of CPU port +enqueue +* to HIF queue. +* CPU_ENQ_HIF_Q_SEL[19..16] - (RW) Select HIF queue which is CPU port +* enqueue to. +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_CPU_ENQ_PKT_NUM_CPU_ENQ_HIF_Q_SEL_ADDR \ + WF_PSE_TOP_CPU_ENQ_PKT_NUM_ADDR +#define WF_PSE_TOP_CPU_ENQ_PKT_NUM_CPU_ENQ_HIF_Q_SEL_MASK \ + 0x000F0000 /* CPU_ENQ_HIF_Q_SEL[19..16] */ +#define WF_PSE_TOP_CPU_ENQ_PKT_NUM_CPU_ENQ_HIF_Q_SEL_SHFT 16 +#define WF_PSE_TOP_CPU_ENQ_PKT_NUM_CPU_ENQ_HIF_Q_PKT_NUM_ADDR \ + WF_PSE_TOP_CPU_ENQ_PKT_NUM_ADDR +#define WF_PSE_TOP_CPU_ENQ_PKT_NUM_CPU_ENQ_HIF_Q_PKT_NUM_MASK \ + 0x0000FFFF /* CPU_ENQ_HIF_Q_PKT_NUM[15..0] */ +#define WF_PSE_TOP_CPU_ENQ_PKT_NUM_CPU_ENQ_HIF_Q_PKT_NUM_SHFT 0 + +/* +* ---LMAC_ENQ_PKT_NUM (0x820C8000 + 0x1F8)--- +* LMAC_ENQ_HIF_Q_PKT_NUM[15..0] - (RO) The packets numbers of LMAC +port +* enqueue to HIF queue. +* LMAC_ENQ_HIF_Q_SEL[19..16] - (RW) Select HIF queue which is LMAC +port +* enqueue to. +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_LMAC_ENQ_PKT_NUM_LMAC_ENQ_HIF_Q_SEL_ADDR \ + WF_PSE_TOP_LMAC_ENQ_PKT_NUM_ADDR +#define WF_PSE_TOP_LMAC_ENQ_PKT_NUM_LMAC_ENQ_HIF_Q_SEL_MASK \ + 0x000F0000 /* LMAC_ENQ_HIF_Q_SEL[19..16] */ +#define WF_PSE_TOP_LMAC_ENQ_PKT_NUM_LMAC_ENQ_HIF_Q_SEL_SHFT 16 +#define WF_PSE_TOP_LMAC_ENQ_PKT_NUM_LMAC_ENQ_HIF_Q_PKT_NUM_ADDR \ + WF_PSE_TOP_LMAC_ENQ_PKT_NUM_ADDR +#define WF_PSE_TOP_LMAC_ENQ_PKT_NUM_LMAC_ENQ_HIF_Q_PKT_NUM_MASK \ + 0x0000FFFF /* LMAC_ENQ_HIF_Q_PKT_NUM[15..0] */ +#define WF_PSE_TOP_LMAC_ENQ_PKT_NUM_LMAC_ENQ_HIF_Q_PKT_NUM_SHFT 0 + +/* +* ---HIF_ENQ_PKT_NUM (0x820C8000 + 0x1FC)--- +* HIF_ENQ_MDP[15..0] - (RO) The packets numbers of HIF port enqueue +* to MDP TX queue. +* HIF_ENQ_CPU[31..16] - (RO) The packets numbers of HIF port enqueue +* to CPU queue +*/ +#define WF_PSE_TOP_HIF_ENQ_PKT_NUM_HIF_ENQ_CPU_ADDR \ + WF_PSE_TOP_HIF_ENQ_PKT_NUM_ADDR +#define WF_PSE_TOP_HIF_ENQ_PKT_NUM_HIF_ENQ_CPU_MASK \ + 0xFFFF0000 /* HIF_ENQ_CPU[31..16] */ +#define WF_PSE_TOP_HIF_ENQ_PKT_NUM_HIF_ENQ_CPU_SHFT 16 +#define WF_PSE_TOP_HIF_ENQ_PKT_NUM_HIF_ENQ_MDP_ADDR \ + WF_PSE_TOP_HIF_ENQ_PKT_NUM_ADDR +#define WF_PSE_TOP_HIF_ENQ_PKT_NUM_HIF_ENQ_MDP_MASK \ + 0x0000FFFF /* HIF_ENQ_MDP[15..0] */ +#define WF_PSE_TOP_HIF_ENQ_PKT_NUM_HIF_ENQ_MDP_SHFT 0 + +/* +* ---MDP_ENQ_PKT_NUM (0x820C8000 + 0x200)--- +* MDP_ENQ_HIF_Q_PKT_NUM[15..0] - (RO) The packets numbers of MDP port +enqueue +* to HIF queue. +* MDP_ENQ_HIF_Q_SEL[31..16] - (RW) Select HIF queue which is MDP port +* enqueue to. +*/ +#define WF_PSE_TOP_MDP_ENQ_PKT_NUM_MDP_ENQ_HIF_Q_SEL_ADDR \ + WF_PSE_TOP_MDP_ENQ_PKT_NUM_ADDR +#define WF_PSE_TOP_MDP_ENQ_PKT_NUM_MDP_ENQ_HIF_Q_SEL_MASK \ + 0xFFFF0000 /* MDP_ENQ_HIF_Q_SEL[31..16] */ +#define WF_PSE_TOP_MDP_ENQ_PKT_NUM_MDP_ENQ_HIF_Q_SEL_SHFT 16 +#define WF_PSE_TOP_MDP_ENQ_PKT_NUM_MDP_ENQ_HIF_Q_PKT_NUM_ADDR \ + WF_PSE_TOP_MDP_ENQ_PKT_NUM_ADDR +#define WF_PSE_TOP_MDP_ENQ_PKT_NUM_MDP_ENQ_HIF_Q_PKT_NUM_MASK \ + 0x0000FFFF /* MDP_ENQ_HIF_Q_PKT_NUM[15..0] */ +#define WF_PSE_TOP_MDP_ENQ_PKT_NUM_MDP_ENQ_HIF_Q_PKT_NUM_SHFT 0 + +/* +* ---TIMEOUT_CTRL (0x820C8000 + 0x244)--- +* FL_WD_TO_CTRL[7..0] - (RW) FL watch dog timeput +* RESERVED8[15..8] - (RO) Reserved bits +* APB_WD_TO_CTRL[23..16] - (RW) APB pready watch dog timeout control +register. +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_TIMEOUT_CTRL_APB_WD_TO_CTRL_ADDR \ + WF_PSE_TOP_TIMEOUT_CTRL_ADDR +#define WF_PSE_TOP_TIMEOUT_CTRL_APB_WD_TO_CTRL_MASK \ + 0x00FF0000 /* APB_WD_TO_CTRL[23..16] */ +#define WF_PSE_TOP_TIMEOUT_CTRL_APB_WD_TO_CTRL_SHFT 16 +#define WF_PSE_TOP_TIMEOUT_CTRL_FL_WD_TO_CTRL_ADDR \ + WF_PSE_TOP_TIMEOUT_CTRL_ADDR +#define WF_PSE_TOP_TIMEOUT_CTRL_FL_WD_TO_CTRL_MASK \ + 0x000000FF /* FL_WD_TO_CTRL[7..0] */ +#define WF_PSE_TOP_TIMEOUT_CTRL_FL_WD_TO_CTRL_SHFT 0 + +/* +* ---FSM_IDLE_WD_CTRL (0x820C8000 + 0x24C)--- +* FL_IDLE_WD_TO_TH[7..0] - (RW) Watchdog timeout threshold for frame +* link FSM not returning to IDLE +* PL_IDLE_WD_TO_TH[15..8] - (RW) Watchdog timeout threshold for page +link +* FSM not returning to IDLE +* PORT_IDLE_WD_TO_TH[23..16] - (RW) Watchdog timeout threshold for +* page link +* Port Link not returning to IDLE +* (Including HIF/CPU/LMAC port) +* MACTX_IDLE_WD_TO_TH[31..24] - (RW) Watchdog timeout threshold for +* port oper +* MACTX not returning to IDLE +*/ +#define WF_PSE_TOP_FSM_IDLE_WD_CTRL_MACTX_IDLE_WD_TO_TH_ADDR \ + WF_PSE_TOP_FSM_IDLE_WD_CTRL_ADDR +#define WF_PSE_TOP_FSM_IDLE_WD_CTRL_MACTX_IDLE_WD_TO_TH_MASK \ + 0xFF000000 /* MACTX_IDLE_WD_TO_TH[31..24] */ +#define WF_PSE_TOP_FSM_IDLE_WD_CTRL_MACTX_IDLE_WD_TO_TH_SHFT 24 +#define WF_PSE_TOP_FSM_IDLE_WD_CTRL_PORT_IDLE_WD_TO_TH_ADDR \ + WF_PSE_TOP_FSM_IDLE_WD_CTRL_ADDR +#define WF_PSE_TOP_FSM_IDLE_WD_CTRL_PORT_IDLE_WD_TO_TH_MASK \ + 0x00FF0000 /* PORT_IDLE_WD_TO_TH[23..16] */ +#define WF_PSE_TOP_FSM_IDLE_WD_CTRL_PORT_IDLE_WD_TO_TH_SHFT 16 +#define WF_PSE_TOP_FSM_IDLE_WD_CTRL_PL_IDLE_WD_TO_TH_ADDR \ + WF_PSE_TOP_FSM_IDLE_WD_CTRL_ADDR +#define WF_PSE_TOP_FSM_IDLE_WD_CTRL_PL_IDLE_WD_TO_TH_MASK \ + 0x0000FF00 /* PL_IDLE_WD_TO_TH[15..8] */ +#define WF_PSE_TOP_FSM_IDLE_WD_CTRL_PL_IDLE_WD_TO_TH_SHFT 8 +#define WF_PSE_TOP_FSM_IDLE_WD_CTRL_FL_IDLE_WD_TO_TH_ADDR \ + WF_PSE_TOP_FSM_IDLE_WD_CTRL_ADDR +#define WF_PSE_TOP_FSM_IDLE_WD_CTRL_FL_IDLE_WD_TO_TH_MASK \ + 0x000000FF /* FL_IDLE_WD_TO_TH[7..0] */ +#define WF_PSE_TOP_FSM_IDLE_WD_CTRL_FL_IDLE_WD_TO_TH_SHFT 0 + +/* +* ---FSM_IDLE_WD_EN (0x820C8000 + 0x250)--- +* EN_HIF_PORT_IDLE_WD_TO[0] - (RW) Enables watchdog for HIF port oper +FSM +* not returning to IDLE +* EN_CPU_PORT_IDLE_WD_TO[1] - (RW) Enables watchdog for CPU port oper +FSM +* not returning to IDLE +* EN_LMAC_PORT_IDLE_WD_TO[2] - (RW) Enables watchdog for LMAC port +* oper FSM +* not returning to IDLE +* EN_MDP_IDLE_WD_TO[3] - (RW) Enables watchdog for MDP port oper FSM +* not returning to IDLE +* EN_SEC_IDLE_WD_TO[4] - (RW) Enables watchdog for SEC port oper FSM +* not returning to IDLE +* EN_PLE_IDLE_WD_TO[5] - (RW) Enables watchdog for PLE port oper FSM +* not returning to IDLE +* EN_AMSDU_IDLE_WD_TO[6] - (RW) Enables watchdog for AMSDU port oper +FSM +* not returning to IDLE +* RESERVED7[7] - (RO) Reserved bits +* EN_FL_IDLE_WD_TO[8] - (RW) Enables watchdog for frame link FSM not +* returning to IDLE +* EN_PL_IDLE_WD_TO[9] - (RW) Enables watchdog for page link FSM not +* returning to IDLE +* RESERVED10[31..10] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_PL_IDLE_WD_TO_ADDR \ + WF_PSE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_PL_IDLE_WD_TO_MASK \ + 0x00000200 /* EN_PL_IDLE_WD_TO[9] */ +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_PL_IDLE_WD_TO_SHFT 9 +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_FL_IDLE_WD_TO_ADDR \ + WF_PSE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_FL_IDLE_WD_TO_MASK \ + 0x00000100 /* EN_FL_IDLE_WD_TO[8] */ +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_FL_IDLE_WD_TO_SHFT 8 +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_AMSDU_IDLE_WD_TO_ADDR \ + WF_PSE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_AMSDU_IDLE_WD_TO_MASK \ + 0x00000040 /* EN_AMSDU_IDLE_WD_TO[6] */ +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_AMSDU_IDLE_WD_TO_SHFT 6 +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_PLE_IDLE_WD_TO_ADDR \ + WF_PSE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_PLE_IDLE_WD_TO_MASK \ + 0x00000020 /* EN_PLE_IDLE_WD_TO[5] */ +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_PLE_IDLE_WD_TO_SHFT 5 +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_SEC_IDLE_WD_TO_ADDR \ + WF_PSE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_SEC_IDLE_WD_TO_MASK \ + 0x00000010 /* EN_SEC_IDLE_WD_TO[4] */ +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_SEC_IDLE_WD_TO_SHFT 4 +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_MDP_IDLE_WD_TO_ADDR \ + WF_PSE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_MDP_IDLE_WD_TO_MASK \ + 0x00000008 /* EN_MDP_IDLE_WD_TO[3] */ +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_MDP_IDLE_WD_TO_SHFT 3 +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_LMAC_PORT_IDLE_WD_TO_ADDR \ + WF_PSE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_LMAC_PORT_IDLE_WD_TO_MASK \ + 0x00000004 /* EN_LMAC_PORT_IDLE_WD_TO[2] */ +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_LMAC_PORT_IDLE_WD_TO_SHFT 2 +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_CPU_PORT_IDLE_WD_TO_ADDR \ + WF_PSE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_CPU_PORT_IDLE_WD_TO_MASK \ + 0x00000002 /* EN_CPU_PORT_IDLE_WD_TO[1] */ +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_CPU_PORT_IDLE_WD_TO_SHFT 1 +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_HIF_PORT_IDLE_WD_TO_ADDR \ + WF_PSE_TOP_FSM_IDLE_WD_EN_ADDR +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_HIF_PORT_IDLE_WD_TO_MASK \ + 0x00000001 /* EN_HIF_PORT_IDLE_WD_TO[0] */ +#define WF_PSE_TOP_FSM_IDLE_WD_EN_EN_HIF_PORT_IDLE_WD_TO_SHFT 0 + +/* +* ---PSE_INTER_ERR_FLAG (0x820C8000 + 0x280)--- +* DEQ_EMPTY_QUEUE[0] - (RO) DEQueue Empty Error Flag +* APB_WD_TO[1] - (RO) APB Write Data Timeout Error Flag +* FL_CTRL_WD_TO[2] - (RO) FL Write Data Timeout Error Flag +* RESERVED3[31..3] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_INTER_ERR_FLAG_FL_CTRL_WD_TO_ADDR \ + WF_PSE_TOP_PSE_INTER_ERR_FLAG_ADDR +#define WF_PSE_TOP_PSE_INTER_ERR_FLAG_FL_CTRL_WD_TO_MASK \ + 0x00000004 /* FL_CTRL_WD_TO[2] */ +#define WF_PSE_TOP_PSE_INTER_ERR_FLAG_FL_CTRL_WD_TO_SHFT 2 +#define WF_PSE_TOP_PSE_INTER_ERR_FLAG_APB_WD_TO_ADDR \ + WF_PSE_TOP_PSE_INTER_ERR_FLAG_ADDR +#define WF_PSE_TOP_PSE_INTER_ERR_FLAG_APB_WD_TO_MASK \ + 0x00000002 /* APB_WD_TO[1] */ +#define WF_PSE_TOP_PSE_INTER_ERR_FLAG_APB_WD_TO_SHFT 1 +#define WF_PSE_TOP_PSE_INTER_ERR_FLAG_DEQ_EMPTY_QUEUE_ADDR \ + WF_PSE_TOP_PSE_INTER_ERR_FLAG_ADDR +#define WF_PSE_TOP_PSE_INTER_ERR_FLAG_DEQ_EMPTY_QUEUE_MASK \ + 0x00000001 /* DEQ_EMPTY_QUEUE[0] */ +#define WF_PSE_TOP_PSE_INTER_ERR_FLAG_DEQ_EMPTY_QUEUE_SHFT 0 + +/* +* ---PSE_SER_CTRL (0x820C8000 + 0x2a0)--- +* HIF_SER_PAUSE_ALLOCATE[0] - (RW) System Error Recover function for +Pause +* HIFBuffer Allocation +* CPU_SER_PAUSE_ALLOCATE[1] - (RW) System Error Recover function for +Pause +* CPU Buffer Allocation +* WF_SER_PAUSE_ALLOCATE[2] - (RW) System Error Recover function for +Pause +* WF Buffer Allocation +* MDP_SER_PAUSE_ALLOCATE[3] - (RW) System Error Recover function for +Pause +* MDP Buffer Allocation +* SEC_SER_PAUSE_ALLOCATE[4] - (RW) System Error Recover function for +Pause +* SEC Buffer Allocation +* PLE_SER_PAUSE_ALLOCATE[5] - (RW) System Error Recover function for +Pause +* PLE Buffer Allocation +* RESERVED6[7..6] - (RO) Reserved bits +* HIF_SER_PAUSE_DATA[8] - (RW) System Error Recover function for Pause +* HIF DATA opeartion. +* CPU_SER_PAUSE_DATA[9] - (RW) System Error Recover function for Pause +* CPU DATA opeartion. +* WF_SER_PAUSE_DATA[10] - (RW) System Error Recover function for Pause +* WF DATA opeartion. +* MDP_SER_PAUSE_DATA[11] - (RW) System Error Recover function for +Pause +* MDP DATA opeartion. +* SEC_SER_PAUSE_DATA[12] - (RW) System Error Recover function for +Pause +* SEC DATA opeartion. +* PLE_SER_PAUSE_DATA[13] - (RW) System Error Recover function for +Pause +* PLE DATA opeartion. +* RESERVED14[15..14] - (RO) Reserved bits +* HIF_SER_PAUSE_QUEUE[16] - (RW) System Error Recover function for +Pause +* HIF Queue opeartion. +* CPU_SER_PAUSE_QUEUE[17] - (RW) System Error Recover function for +Pause +* CPU Queue opeartion. +* WF_SER_PAUSE_QUEUE[18] - (RW) System Error Recover function for +Pause +* WF Queue opeartion. +* MDP_SER_PAUSE_QUEUE[19] - (RW) System Error Recover function for +Pause +* MDP Queue opeartion. +* SEC_SER_PAUSE_QUEUE[20] - (RW) System Error Recover function for +Pause +* SEC Queue opeartion. +* PLE_SER_PAUSE_QUEUE[21] - (RW) System Error Recover function for +Pause +* PLE Queue opeartion. +* RESERVED22[31..22] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_SER_CTRL_PLE_SER_PAUSE_QUEUE_ADDR \ + WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_PLE_SER_PAUSE_QUEUE_MASK \ + 0x00200000 /* PLE_SER_PAUSE_QUEUE[21] */ +#define WF_PSE_TOP_PSE_SER_CTRL_PLE_SER_PAUSE_QUEUE_SHFT 21 +#define WF_PSE_TOP_PSE_SER_CTRL_SEC_SER_PAUSE_QUEUE_ADDR \ + WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_SEC_SER_PAUSE_QUEUE_MASK \ + 0x00100000 /* SEC_SER_PAUSE_QUEUE[20] */ +#define WF_PSE_TOP_PSE_SER_CTRL_SEC_SER_PAUSE_QUEUE_SHFT 20 +#define WF_PSE_TOP_PSE_SER_CTRL_MDP_SER_PAUSE_QUEUE_ADDR \ + WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_MDP_SER_PAUSE_QUEUE_MASK \ + 0x00080000 /* MDP_SER_PAUSE_QUEUE[19] */ +#define WF_PSE_TOP_PSE_SER_CTRL_MDP_SER_PAUSE_QUEUE_SHFT 19 +#define WF_PSE_TOP_PSE_SER_CTRL_WF_SER_PAUSE_QUEUE_ADDR \ + WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_WF_SER_PAUSE_QUEUE_MASK \ + 0x00040000 /* WF_SER_PAUSE_QUEUE[18] */ +#define WF_PSE_TOP_PSE_SER_CTRL_WF_SER_PAUSE_QUEUE_SHFT 18 +#define WF_PSE_TOP_PSE_SER_CTRL_CPU_SER_PAUSE_QUEUE_ADDR \ + WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_CPU_SER_PAUSE_QUEUE_MASK \ + 0x00020000 /* CPU_SER_PAUSE_QUEUE[17] */ +#define WF_PSE_TOP_PSE_SER_CTRL_CPU_SER_PAUSE_QUEUE_SHFT 17 +#define WF_PSE_TOP_PSE_SER_CTRL_HIF_SER_PAUSE_QUEUE_ADDR \ + WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_HIF_SER_PAUSE_QUEUE_MASK \ + 0x00010000 /* HIF_SER_PAUSE_QUEUE[16] */ +#define WF_PSE_TOP_PSE_SER_CTRL_HIF_SER_PAUSE_QUEUE_SHFT 16 +#define WF_PSE_TOP_PSE_SER_CTRL_PLE_SER_PAUSE_DATA_ADDR \ + WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_PLE_SER_PAUSE_DATA_MASK \ + 0x00002000 /* PLE_SER_PAUSE_DATA[13] */ +#define WF_PSE_TOP_PSE_SER_CTRL_PLE_SER_PAUSE_DATA_SHFT 13 +#define WF_PSE_TOP_PSE_SER_CTRL_SEC_SER_PAUSE_DATA_ADDR \ + WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_SEC_SER_PAUSE_DATA_MASK \ + 0x00001000 /* SEC_SER_PAUSE_DATA[12] */ +#define WF_PSE_TOP_PSE_SER_CTRL_SEC_SER_PAUSE_DATA_SHFT 12 +#define WF_PSE_TOP_PSE_SER_CTRL_MDP_SER_PAUSE_DATA_ADDR \ + WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_MDP_SER_PAUSE_DATA_MASK \ + 0x00000800 /* MDP_SER_PAUSE_DATA[11] */ +#define WF_PSE_TOP_PSE_SER_CTRL_MDP_SER_PAUSE_DATA_SHFT 11 +#define WF_PSE_TOP_PSE_SER_CTRL_WF_SER_PAUSE_DATA_ADDR \ + WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_WF_SER_PAUSE_DATA_MASK \ + 0x00000400 /* WF_SER_PAUSE_DATA[10] */ +#define WF_PSE_TOP_PSE_SER_CTRL_WF_SER_PAUSE_DATA_SHFT 10 +#define WF_PSE_TOP_PSE_SER_CTRL_CPU_SER_PAUSE_DATA_ADDR \ + WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_CPU_SER_PAUSE_DATA_MASK \ + 0x00000200 /* CPU_SER_PAUSE_DATA[9] */ +#define WF_PSE_TOP_PSE_SER_CTRL_CPU_SER_PAUSE_DATA_SHFT 9 +#define WF_PSE_TOP_PSE_SER_CTRL_HIF_SER_PAUSE_DATA_ADDR \ + WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_HIF_SER_PAUSE_DATA_MASK \ + 0x00000100 /* HIF_SER_PAUSE_DATA[8] */ +#define WF_PSE_TOP_PSE_SER_CTRL_HIF_SER_PAUSE_DATA_SHFT 8 +#define WF_PSE_TOP_PSE_SER_CTRL_PLE_SER_PAUSE_ALLOCATE_ADDR \ + WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_PLE_SER_PAUSE_ALLOCATE_MASK \ + 0x00000020 /* PLE_SER_PAUSE_ALLOCATE[5] */ +#define WF_PSE_TOP_PSE_SER_CTRL_PLE_SER_PAUSE_ALLOCATE_SHFT 5 +#define WF_PSE_TOP_PSE_SER_CTRL_SEC_SER_PAUSE_ALLOCATE_ADDR \ + WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_SEC_SER_PAUSE_ALLOCATE_MASK \ + 0x00000010 /* SEC_SER_PAUSE_ALLOCATE[4] */ +#define WF_PSE_TOP_PSE_SER_CTRL_SEC_SER_PAUSE_ALLOCATE_SHFT 4 +#define WF_PSE_TOP_PSE_SER_CTRL_MDP_SER_PAUSE_ALLOCATE_ADDR \ + WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_MDP_SER_PAUSE_ALLOCATE_MASK \ + 0x00000008 /* MDP_SER_PAUSE_ALLOCATE[3] */ +#define WF_PSE_TOP_PSE_SER_CTRL_MDP_SER_PAUSE_ALLOCATE_SHFT 3 +#define WF_PSE_TOP_PSE_SER_CTRL_WF_SER_PAUSE_ALLOCATE_ADDR \ + WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_WF_SER_PAUSE_ALLOCATE_MASK \ + 0x00000004 /* WF_SER_PAUSE_ALLOCATE[2] */ +#define WF_PSE_TOP_PSE_SER_CTRL_WF_SER_PAUSE_ALLOCATE_SHFT 2 +#define WF_PSE_TOP_PSE_SER_CTRL_CPU_SER_PAUSE_ALLOCATE_ADDR \ + WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_CPU_SER_PAUSE_ALLOCATE_MASK \ + 0x00000002 /* CPU_SER_PAUSE_ALLOCATE[1] */ +#define WF_PSE_TOP_PSE_SER_CTRL_CPU_SER_PAUSE_ALLOCATE_SHFT 1 +#define WF_PSE_TOP_PSE_SER_CTRL_HIF_SER_PAUSE_ALLOCATE_ADDR \ + WF_PSE_TOP_PSE_SER_CTRL_ADDR +#define WF_PSE_TOP_PSE_SER_CTRL_HIF_SER_PAUSE_ALLOCATE_MASK \ + 0x00000001 /* HIF_SER_PAUSE_ALLOCATE[0] */ +#define WF_PSE_TOP_PSE_SER_CTRL_HIF_SER_PAUSE_ALLOCATE_SHFT 0 + +/* +* ---PSE_MBIST_RP_FUSE (0x820C8000 + 0x2b0)--- +* WF_PSE_MBIST_RP_FAIL[3..0] - (RO) MBIST Repair FAIL report +* RESERVED4[7..4] - (RO) Reserved bits +* WF_PSE_MBIST_RP_OK[11..8] - (RO) MBIST Repair OK report +* RESERVED12[14..12] - (RO) Reserved bits +* REG_FUSE_SEL[15] - (RW) MBIST FUSE setting +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_REG_FUSE_SEL_ADDR \ + WF_PSE_TOP_PSE_MBIST_RP_FUSE_ADDR +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_REG_FUSE_SEL_MASK \ + 0x00008000 /* REG_FUSE_SEL[15] */ +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_REG_FUSE_SEL_SHFT 15 +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_WF_PSE_MBIST_RP_OK_ADDR \ + WF_PSE_TOP_PSE_MBIST_RP_FUSE_ADDR +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_WF_PSE_MBIST_RP_OK_MASK \ + 0x00000F00 /* WF_PSE_MBIST_RP_OK[11..8] */ +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_WF_PSE_MBIST_RP_OK_SHFT 8 +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_WF_PSE_MBIST_RP_FAIL_ADDR \ + WF_PSE_TOP_PSE_MBIST_RP_FUSE_ADDR +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_WF_PSE_MBIST_RP_FAIL_MASK \ + 0x0000000F /* WF_PSE_MBIST_RP_FAIL[3..0] */ +#define WF_PSE_TOP_PSE_MBIST_RP_FUSE_WF_PSE_MBIST_RP_FAIL_SHFT 0 + +/* +* ---PSE_MBIST_BSEL (0x820C8000 + 0x2b4)--- +* WF_PSE_MBIST_BSEL[15..0] - (RW) Memory MBIST BSEL control +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_MBIST_BSEL_WF_PSE_MBIST_BSEL_ADDR \ + WF_PSE_TOP_PSE_MBIST_BSEL_ADDR +#define WF_PSE_TOP_PSE_MBIST_BSEL_WF_PSE_MBIST_BSEL_MASK \ + 0x0000FFFF /* WF_PSE_MBIST_BSEL[15..0] */ +#define WF_PSE_TOP_PSE_MBIST_BSEL_WF_PSE_MBIST_BSEL_SHFT 0 + +/* +* ---PSE_MBIST_RP_FUSE_1 (0x820C8000 + 0x2b8)--- +* WF_UMAC_TOP_MBIST_PREFUSE_0[15..0] - (RW) MBIST PRE-FUSE setting +* WF_UMAC_TOP_MBIST_PREFUSE_D_0[31..16] - (RO) MBIST PRE-FUSE result +*/ +#define \ +WF_PSE_TOP_PSE_MBIST_RP_FUSE_1_WF_UMAC_TOP_MBIST_PREFUSE_D_0_ADDR \ + WF_PSE_TOP_PSE_MBIST_RP_FUSE_1_ADDR +#define \ +WF_PSE_TOP_PSE_MBIST_RP_FUSE_1_WF_UMAC_TOP_MBIST_PREFUSE_D_0_MASK \ + 0xFFFF0000 /* WF_UMAC_TOP_MBIST_PREFUSE_D_0[31..16] */ +#define \ +WF_PSE_TOP_PSE_MBIST_RP_FUSE_1_WF_UMAC_TOP_MBIST_PREFUSE_D_0_SHFT \ + 16 +#define \ +WF_PSE_TOP_PSE_MBIST_RP_FUSE_1_WF_UMAC_TOP_MBIST_PREFUSE_0_ADDR \ + WF_PSE_TOP_PSE_MBIST_RP_FUSE_1_ADDR +#define \ +WF_PSE_TOP_PSE_MBIST_RP_FUSE_1_WF_UMAC_TOP_MBIST_PREFUSE_0_MASK \ + 0x0000FFFF /* WF_UMAC_TOP_MBIST_PREFUSE_0[15..0] */ +#define \ +WF_PSE_TOP_PSE_MBIST_RP_FUSE_1_WF_UMAC_TOP_MBIST_PREFUSE_0_SHFT \ + 0 + +/* +* ---SRAM_MBIST_BACKGROUND (0x820C8000 + 0x2d0)--- +* MBIST_BACKGROUND[15..0] - (RW) Background setting for PSE SRAM MBIST +circuit +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_SRAM_MBIST_BACKGROUND_MBIST_BACKGROUND_ADDR \ + WF_PSE_TOP_SRAM_MBIST_BACKGROUND_ADDR +#define WF_PSE_TOP_SRAM_MBIST_BACKGROUND_MBIST_BACKGROUND_MASK \ + 0x0000FFFF /* MBIST_BACKGROUND[15..0] */ +#define WF_PSE_TOP_SRAM_MBIST_BACKGROUND_MBIST_BACKGROUND_SHFT 0 + +/* +* ---PSE_MISC_FUNC_CTRL (0x820C8000 + 0x2d4)--- +* RESERVED0[7..0] - (RO) Reserved bits +* PSE_QUEUE_ACK_MODE[8] - (RW) Queue ACK mode control +* RESERVED9[29..9] - (RO) Reserved bits +* DIS_BYPASS_INVALID_FID[30] - (RW) Bypass invalid FID control +* DIS_BLOCK_MODE[31] - (RW) Block Mode Control +*/ +#define WF_PSE_TOP_PSE_MISC_FUNC_CTRL_DIS_BLOCK_MODE_ADDR \ + WF_PSE_TOP_PSE_MISC_FUNC_CTRL_ADDR +#define WF_PSE_TOP_PSE_MISC_FUNC_CTRL_DIS_BLOCK_MODE_MASK \ + 0x80000000 /* DIS_BLOCK_MODE[31] */ +#define WF_PSE_TOP_PSE_MISC_FUNC_CTRL_DIS_BLOCK_MODE_SHFT 31 +#define WF_PSE_TOP_PSE_MISC_FUNC_CTRL_DIS_BYPASS_INVALID_FID_ADDR \ + WF_PSE_TOP_PSE_MISC_FUNC_CTRL_ADDR +#define WF_PSE_TOP_PSE_MISC_FUNC_CTRL_DIS_BYPASS_INVALID_FID_MASK \ + 0x40000000 /* DIS_BYPASS_INVALID_FID[30] */ +#define WF_PSE_TOP_PSE_MISC_FUNC_CTRL_DIS_BYPASS_INVALID_FID_SHFT 30 +#define WF_PSE_TOP_PSE_MISC_FUNC_CTRL_PSE_QUEUE_ACK_MODE_ADDR \ + WF_PSE_TOP_PSE_MISC_FUNC_CTRL_ADDR +#define WF_PSE_TOP_PSE_MISC_FUNC_CTRL_PSE_QUEUE_ACK_MODE_MASK \ + 0x00000100 /* PSE_QUEUE_ACK_MODE[8] */ +#define WF_PSE_TOP_PSE_MISC_FUNC_CTRL_PSE_QUEUE_ACK_MODE_SHFT 8 + +/* +* ---SRAM_MBIST_DONE (0x820C8000 + 0x2d8)--- +* MBIST_DONE[0] - (RO) Working status of PSE SRAM MBIST circuit +* RESERVED1[31..1] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_SRAM_MBIST_DONE_MBIST_DONE_ADDR \ + WF_PSE_TOP_SRAM_MBIST_DONE_ADDR +#define WF_PSE_TOP_SRAM_MBIST_DONE_MBIST_DONE_MASK \ + 0x00000001 /* MBIST_DONE[0] */ +#define WF_PSE_TOP_SRAM_MBIST_DONE_MBIST_DONE_SHFT 0 + +/* +* ---SRAM_MBIST_FAIL (0x820C8000 + 0x2dc)--- +* FORDLINK_SRAM_MBIST_FAIL[0] - (RO) MBIST check result of forward +* link SRAM +* BACKLINK_SRAM_MBIST_FAIL[1] - (RO) MBIST check result of backward +* link SRAM +* PAGELINK_SRAM_MBIST_FAIL[2] - (RO) MBIST check result of PAGELINK +SRAM +* RLINFO_SRAM_MBIST_FAIL[3] - (RO) MBIST check result of RLINFO SRAM +* RESERVED4[31..4] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_SRAM_MBIST_FAIL_RLINFO_SRAM_MBIST_FAIL_ADDR \ + WF_PSE_TOP_SRAM_MBIST_FAIL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_FAIL_RLINFO_SRAM_MBIST_FAIL_MASK \ + 0x00000008 /* RLINFO_SRAM_MBIST_FAIL[3] */ +#define WF_PSE_TOP_SRAM_MBIST_FAIL_RLINFO_SRAM_MBIST_FAIL_SHFT 3 +#define WF_PSE_TOP_SRAM_MBIST_FAIL_PAGELINK_SRAM_MBIST_FAIL_ADDR \ + WF_PSE_TOP_SRAM_MBIST_FAIL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_FAIL_PAGELINK_SRAM_MBIST_FAIL_MASK \ + 0x00000004 /* PAGELINK_SRAM_MBIST_FAIL[2] */ +#define WF_PSE_TOP_SRAM_MBIST_FAIL_PAGELINK_SRAM_MBIST_FAIL_SHFT 2 +#define WF_PSE_TOP_SRAM_MBIST_FAIL_BACKLINK_SRAM_MBIST_FAIL_ADDR \ + WF_PSE_TOP_SRAM_MBIST_FAIL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_FAIL_BACKLINK_SRAM_MBIST_FAIL_MASK \ + 0x00000002 /* BACKLINK_SRAM_MBIST_FAIL[1] */ +#define WF_PSE_TOP_SRAM_MBIST_FAIL_BACKLINK_SRAM_MBIST_FAIL_SHFT 1 +#define WF_PSE_TOP_SRAM_MBIST_FAIL_FORDLINK_SRAM_MBIST_FAIL_ADDR \ + WF_PSE_TOP_SRAM_MBIST_FAIL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_FAIL_FORDLINK_SRAM_MBIST_FAIL_MASK \ + 0x00000001 /* FORDLINK_SRAM_MBIST_FAIL[0] */ +#define WF_PSE_TOP_SRAM_MBIST_FAIL_FORDLINK_SRAM_MBIST_FAIL_SHFT 0 + +/* +* ---SRAM_MBIST_CTRL (0x820C8000 + 0x2e0)--- +* MBIST_MODE[0] - (RW) Control register for mbist_mode of MBIST +* RESERVED1[3..1] - (RO) Reserved bits +* MBIST_HOLDB[4] - (RW) Control register for mbist_holdb of +MBIST +* RESERVED5[7..5] - (RO) Reserved bits +* MBIST_DEBUG[8] - (RW) Control register for mbist_debug of +MBIST +* MBIST_RPRST_B[9] - (RW) MBIST Repair function Enable +* MBIST_USE_DEFAULT_DELSEL[10] - (RW) MBIST delay select control +* RESERVED11[15..11] - (RO) Reserved bits +* MBIST_DIAG_SEL[19..16] - (RW) Selection register for +mbist_diag_scan_out +* RESERVED20[23..20] - (RO) Reserved bits +* MBIST_SLEEP_TEST[24] - (RW) Control register for sleep_test of MBIST +* MBIST_SLEEP_INV[25] - (RW) Control register for sleep_inv of MBIST +* MBIST_SLEEP_W[26] - (RW) Control register for sleep_w of MBIST +* MBIST_SLEEP_R[27] - (RW) Control register for sleep_r of MBIST +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_SLEEP_R_ADDR \ + WF_PSE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_SLEEP_R_MASK \ + 0x08000000 /* MBIST_SLEEP_R[27] */ +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_SLEEP_R_SHFT 27 +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_SLEEP_W_ADDR \ + WF_PSE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_SLEEP_W_MASK \ + 0x04000000 /* MBIST_SLEEP_W[26] */ +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_SLEEP_W_SHFT 26 +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_SLEEP_INV_ADDR \ + WF_PSE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_SLEEP_INV_MASK \ + 0x02000000 /* MBIST_SLEEP_INV[25] */ +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_SLEEP_INV_SHFT 25 +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_SLEEP_TEST_ADDR \ + WF_PSE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_SLEEP_TEST_MASK \ + 0x01000000 /* MBIST_SLEEP_TEST[24] */ +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_SLEEP_TEST_SHFT 24 +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_DIAG_SEL_ADDR \ + WF_PSE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_DIAG_SEL_MASK \ + 0x000F0000 /* MBIST_DIAG_SEL[19..16] */ +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_DIAG_SEL_SHFT 16 +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_USE_DEFAULT_DELSEL_ADDR \ + WF_PSE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_USE_DEFAULT_DELSEL_MASK \ + 0x00000400 /* MBIST_USE_DEFAULT_DELSEL[10] */ +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_USE_DEFAULT_DELSEL_SHFT 10 +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_RPRST_B_ADDR \ + WF_PSE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_RPRST_B_MASK \ + 0x00000200 /* MBIST_RPRST_B[9] */ +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_RPRST_B_SHFT 9 +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_DEBUG_ADDR \ + WF_PSE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_DEBUG_MASK \ + 0x00000100 /* MBIST_DEBUG[8] */ +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_DEBUG_SHFT 8 +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_HOLDB_ADDR \ + WF_PSE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_HOLDB_MASK \ + 0x00000010 /* MBIST_HOLDB[4] */ +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_HOLDB_SHFT 4 +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_MODE_ADDR \ + WF_PSE_TOP_SRAM_MBIST_CTRL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_MODE_MASK \ + 0x00000001 /* MBIST_MODE[0] */ +#define WF_PSE_TOP_SRAM_MBIST_CTRL_MBIST_MODE_SHFT 0 + +/* +* ---SRAM_MBIST_DELSEL (0x820C8000 + 0x2e4)--- +* MBIST_DELSEL0_2[31..0] - (RW) Control register of delsel for PL SRAM +*/ +#define WF_PSE_TOP_SRAM_MBIST_DELSEL_MBIST_DELSEL0_2_ADDR \ + WF_PSE_TOP_SRAM_MBIST_DELSEL_ADDR +#define WF_PSE_TOP_SRAM_MBIST_DELSEL_MBIST_DELSEL0_2_MASK \ + 0xFFFFFFFF /* MBIST_DELSEL0_2[31..0] */ +#define WF_PSE_TOP_SRAM_MBIST_DELSEL_MBIST_DELSEL0_2_SHFT 0 + +/* +* ---SRAM_AWT_HDEN_CTRL (0x820C8000 + 0x2e8)--- +* FL_TBL_AWT1[0] - (RW) Memory AWT Control for FL_TBL1 +* FL_TBL_AWT2[1] - (RW) Memory AWT Control for FL_TBL2 +* PL_TBL_AWT[2] - (RW) Memory AWT Control for PL +* RLINFO_MEM_AWT[3] - (RW) Memory AWT Control for RL +* RESERVED4[15..4] - (RO) Reserved bits +* FL_TBL_HDEN1[16] - (RW) Memory HDEN Control for FL_TBL1 +* FL_TBL_HDEN2[17] - (RW) Memory HDEN Control for FL_TBL2 +* PL_TBL_HDEN[18] - (RW) Memory HDEN Control for PL +* RLINFO_MEM_HDEN[19] - (RW) Memory HDEN Control for RL +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_RLINFO_MEM_HDEN_ADDR \ + WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_ADDR +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_RLINFO_MEM_HDEN_MASK \ + 0x00080000 /* RLINFO_MEM_HDEN[19] */ +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_RLINFO_MEM_HDEN_SHFT 19 +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_PL_TBL_HDEN_ADDR \ + WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_ADDR +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_PL_TBL_HDEN_MASK \ + 0x00040000 /* PL_TBL_HDEN[18] */ +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_PL_TBL_HDEN_SHFT 18 +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_FL_TBL_HDEN2_ADDR \ + WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_ADDR +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_FL_TBL_HDEN2_MASK \ + 0x00020000 /* FL_TBL_HDEN2[17] */ +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_FL_TBL_HDEN2_SHFT 17 +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_FL_TBL_HDEN1_ADDR \ + WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_ADDR +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_FL_TBL_HDEN1_MASK \ + 0x00010000 /* FL_TBL_HDEN1[16] */ +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_FL_TBL_HDEN1_SHFT 16 +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_RLINFO_MEM_AWT_ADDR \ + WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_ADDR +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_RLINFO_MEM_AWT_MASK \ + 0x00000008 /* RLINFO_MEM_AWT[3] */ +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_RLINFO_MEM_AWT_SHFT 3 +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_PL_TBL_AWT_ADDR \ + WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_ADDR +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_PL_TBL_AWT_MASK \ + 0x00000004 /* PL_TBL_AWT[2] */ +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_PL_TBL_AWT_SHFT 2 +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_FL_TBL_AWT2_ADDR \ + WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_ADDR +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_FL_TBL_AWT2_MASK \ + 0x00000002 /* FL_TBL_AWT2[1] */ +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_FL_TBL_AWT2_SHFT 1 +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_FL_TBL_AWT1_ADDR \ + WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_ADDR +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_FL_TBL_AWT1_MASK \ + 0x00000001 /* FL_TBL_AWT1[0] */ +#define WF_PSE_TOP_SRAM_AWT_HDEN_CTRL_FL_TBL_AWT1_SHFT 0 + +/* +* ---SRAM_MBIST_DELSEL_1 (0x820C8000 + 0x2f0)--- +* MBIST_DELSEL3[31..0] - (RW) Control register of delsel for RLINFO +SRAM +*/ +#define WF_PSE_TOP_SRAM_MBIST_DELSEL_1_MBIST_DELSEL3_ADDR \ + WF_PSE_TOP_SRAM_MBIST_DELSEL_1_ADDR +#define WF_PSE_TOP_SRAM_MBIST_DELSEL_1_MBIST_DELSEL3_MASK \ + 0xFFFFFFFF /* MBIST_DELSEL3[31..0] */ +#define WF_PSE_TOP_SRAM_MBIST_DELSEL_1_MBIST_DELSEL3_SHFT 0 + +/* +* ---PSE_SEEK_CR_00 (0x820C8000 + 0x3d0)--- +* PSE_FL_ARB_CS[2..0] - (RO) PSE debug state for FL_ARB_CS +* RESERVED3[3] - (RO) Reserved bits +* PSE_FL_CS[7..4] - (RO) PSE debug state for FL_CS +* PSE_ENQ_FL_CS[11..8] - (RO) PSE debug state for ENQ_FL_CS +* PSE_DEQ_FL_CS[15..12] - (RO) PSE debug state for DEQ_FL_CS +* PSE_ACC_LST_CS[18..16] - (RO) PSE debug state for ACC_LST_CS +* RESERVED19[31..19] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_ACC_LST_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_00_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_ACC_LST_CS_MASK \ + 0x00070000 /* PSE_ACC_LST_CS[18..16] */ +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_ACC_LST_CS_SHFT 16 +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_DEQ_FL_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_00_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_DEQ_FL_CS_MASK \ + 0x0000F000 /* PSE_DEQ_FL_CS[15..12] */ +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_DEQ_FL_CS_SHFT 12 +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_ENQ_FL_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_00_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_ENQ_FL_CS_MASK \ + 0x00000F00 /* PSE_ENQ_FL_CS[11..8] */ +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_ENQ_FL_CS_SHFT 8 +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_FL_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_00_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_FL_CS_MASK \ + 0x000000F0 /* PSE_FL_CS[7..4] */ +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_FL_CS_SHFT 4 +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_FL_ARB_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_00_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_FL_ARB_CS_MASK \ + 0x00000007 /* PSE_FL_ARB_CS[2..0] */ +#define WF_PSE_TOP_PSE_SEEK_CR_00_PSE_FL_ARB_CS_SHFT 0 + +/* +* ---PSE_SEEK_CR_01 (0x820C8000 + 0x3d4)--- +* PSE_PL_ARB_CS[2..0] - (RO) PSE debug state for PL_ARB_CS +* RESERVED3[3] - (RO) Reserved bits +* PSE_PL_INIT_CS[5..4] - (RO) PSE debug state for PL_INIT_CS +* RESERVED6[7..6] - (RO) Reserved bits +* PSE_PL_GNEXT_CS[8] - (RO) PSE debug state for PL_GNEXT_CS +* RESERVED9[11..9] - (RO) Reserved bits +* PSE_PL_GBUF_CS[14..12] - (RO) PSE debug state for PL_GBUF_CS +* RESERVED15[15] - (RO) Reserved bits +* PSE_PL_RLS_CS[17..16] - (RO) PSE debug state for PL_RLS_CS +* RESERVED18[19..18] - (RO) Reserved bits +* PSE_PL_REFILL_CS[22..20] - (RO) PSE debug state for PL_REFILL_CS +* RESERVED23[23] - (RO) Reserved bits +* PSE_RLS_CS[25..24] - (RO) PSE debug state for RLS_CS +* RESERVED26[31..26] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_RLS_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_01_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_RLS_CS_MASK \ + 0x03000000 /* PSE_RLS_CS[25..24] */ +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_RLS_CS_SHFT 24 +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_REFILL_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_01_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_REFILL_CS_MASK \ + 0x00700000 /* PSE_PL_REFILL_CS[22..20] */ +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_REFILL_CS_SHFT 20 +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_RLS_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_01_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_RLS_CS_MASK \ + 0x00030000 /* PSE_PL_RLS_CS[17..16] */ +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_RLS_CS_SHFT 16 +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_GBUF_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_01_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_GBUF_CS_MASK \ + 0x00007000 /* PSE_PL_GBUF_CS[14..12] */ +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_GBUF_CS_SHFT 12 +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_GNEXT_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_01_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_GNEXT_CS_MASK \ + 0x00000100 /* PSE_PL_GNEXT_CS[8] */ +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_GNEXT_CS_SHFT 8 +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_INIT_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_01_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_INIT_CS_MASK \ + 0x00000030 /* PSE_PL_INIT_CS[5..4] */ +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_INIT_CS_SHFT 4 +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_ARB_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_01_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_ARB_CS_MASK \ + 0x00000007 /* PSE_PL_ARB_CS[2..0] */ +#define WF_PSE_TOP_PSE_SEEK_CR_01_PSE_PL_ARB_CS_SHFT 0 + +/* +* ---PSE_SEEK_CR_02 (0x820C8000 + 0x3d8)--- +* PSE_HIF_DOP_PBUF_CS[2..0] - (RO) PSE debug state for HIF_DOP_PBUF_CS +* RESERVED3[3] - (RO) Reserved bits +* PSE_HIF_DOP_CACHE_CS[5..4] - (RO) PSE debug state for +HIF_DOP_CACHE_CS +* RESERVED6[7..6] - (RO) Reserved bits +* PSE_HIF_QOP_Q_OPER_CS[11..8] - (RO) PSE debug state for +HIF_QOP_Q_OPER_CS +* PSE_HIF_QOP_RL_OCP_CS[13..12] - (RO) PSE debug state for +HIF_QOP_RL_OCP_CS +* RESERVED14[15..14] - (RO) Reserved bits +* PSE_HIF_QOP_PL_OCP_CS[17..16] - (RO) PSE debug state for +HIF_QOP_PL_OCP_CS +* RESERVED18[19..18] - (RO) Reserved bits +* PSE_HIF_QOP_ALLOCATE_CS[22..20] - (RO) PSE debug state for +HIF_QOP_ALLOCATE_CS +* RESERVED23[23] - (RO) Reserved bits +* PSE_HIF_RX_DOP_PBUF_CS[26..24] - (RO) PSE debug state for +HIF_RX_DOP_PBUF_CS +* RESERVED27[27] - (RO) Reserved bits +* PSE_HIF_RX_DOP_CACHE_CS[29..28] - (RO) PSE debug state for +HIF_RX_DOP_CACHE_CS +* RESERVED30[31..30] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_RX_DOP_CACHE_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_02_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_RX_DOP_CACHE_CS_MASK \ + 0x30000000 /* PSE_HIF_RX_DOP_CACHE_CS[29..28] */ +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_RX_DOP_CACHE_CS_SHFT 28 +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_RX_DOP_PBUF_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_02_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_RX_DOP_PBUF_CS_MASK \ + 0x07000000 /* PSE_HIF_RX_DOP_PBUF_CS[26..24] */ +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_RX_DOP_PBUF_CS_SHFT 24 +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_QOP_ALLOCATE_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_02_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_QOP_ALLOCATE_CS_MASK \ + 0x00700000 /* PSE_HIF_QOP_ALLOCATE_CS[22..20] */ +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_QOP_ALLOCATE_CS_SHFT 20 +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_QOP_PL_OCP_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_02_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_QOP_PL_OCP_CS_MASK \ + 0x00030000 /* PSE_HIF_QOP_PL_OCP_CS[17..16] */ +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_QOP_PL_OCP_CS_SHFT 16 +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_QOP_RL_OCP_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_02_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_QOP_RL_OCP_CS_MASK \ + 0x00003000 /* PSE_HIF_QOP_RL_OCP_CS[13..12] */ +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_QOP_RL_OCP_CS_SHFT 12 +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_QOP_Q_OPER_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_02_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_QOP_Q_OPER_CS_MASK \ + 0x00000F00 /* PSE_HIF_QOP_Q_OPER_CS[11..8] */ +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_QOP_Q_OPER_CS_SHFT 8 +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_DOP_CACHE_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_02_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_DOP_CACHE_CS_MASK \ + 0x00000030 /* PSE_HIF_DOP_CACHE_CS[5..4] */ +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_DOP_CACHE_CS_SHFT 4 +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_DOP_PBUF_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_02_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_DOP_PBUF_CS_MASK \ + 0x00000007 /* PSE_HIF_DOP_PBUF_CS[2..0] */ +#define WF_PSE_TOP_PSE_SEEK_CR_02_PSE_HIF_DOP_PBUF_CS_SHFT 0 + +/* +* ---PSE_SEEK_CR_03 (0x820C8000 + 0x3dc)--- +* PSE_CPU_DOP_PBUF_CS[2..0] - (RO) PSE debug state for CPU_DOP_PBUF_CS +* RESERVED3[3] - (RO) Reserved bits +* PSE_CPU_DOP_CACHE_CS[5..4] - (RO) PSE debug state for +CPU_DOP_CACHE_CS +* RESERVED6[7..6] - (RO) Reserved bits +* PSE_CPU_QOP_Q_OPER_CS[11..8] - (RO) PSE debug state for +CPU_QOP_Q_OPER_CS +* PSE_CPU_QOP_RL_OCP_CS[13..12] - (RO) PSE debug state for +CPU_QOP_RL_OCP_CS +* RESERVED14[15..14] - (RO) Reserved bits +* PSE_CPU_QOP_PL_OCP_CS[17..16] - (RO) PSE debug state for +CPU_QOP_PL_OCP_CS +* RESERVED18[19..18] - (RO) Reserved bits +* PSE_CPU_QOP_ALLOCATE_CS[22..20] - (RO) PSE debug state for +CPU_QOP_ALLOCATE_CS +* RESERVED23[31..23] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_QOP_ALLOCATE_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_03_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_QOP_ALLOCATE_CS_MASK \ + 0x00700000 /* PSE_CPU_QOP_ALLOCATE_CS[22..20] */ +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_QOP_ALLOCATE_CS_SHFT 20 +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_QOP_PL_OCP_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_03_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_QOP_PL_OCP_CS_MASK \ + 0x00030000 /* PSE_CPU_QOP_PL_OCP_CS[17..16] */ +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_QOP_PL_OCP_CS_SHFT 16 +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_QOP_RL_OCP_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_03_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_QOP_RL_OCP_CS_MASK \ + 0x00003000 /* PSE_CPU_QOP_RL_OCP_CS[13..12] */ +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_QOP_RL_OCP_CS_SHFT 12 +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_QOP_Q_OPER_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_03_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_QOP_Q_OPER_CS_MASK \ + 0x00000F00 /* PSE_CPU_QOP_Q_OPER_CS[11..8] */ +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_QOP_Q_OPER_CS_SHFT 8 +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_DOP_CACHE_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_03_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_DOP_CACHE_CS_MASK \ + 0x00000030 /* PSE_CPU_DOP_CACHE_CS[5..4] */ +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_DOP_CACHE_CS_SHFT 4 +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_DOP_PBUF_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_03_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_DOP_PBUF_CS_MASK \ + 0x00000007 /* PSE_CPU_DOP_PBUF_CS[2..0] */ +#define WF_PSE_TOP_PSE_SEEK_CR_03_PSE_CPU_DOP_PBUF_CS_SHFT 0 + +/* +* ---PSE_SEEK_CR_04 (0x820C8000 + 0x3e0)--- +* PSE_WF_DOP_PBUF_CS[2..0] - (RO) PSE debug state for WF_DOP_PBUF_CS +* RESERVED3[3] - (RO) Reserved bits +* PSE_WF_DOP_CACHE_CS[5..4] - (RO) PSE debug state for WF_DOP_CACHE_CS +* RESERVED6[7..6] - (RO) Reserved bits +* PSE_WF_QOP_Q_OPER_CS[11..8] - (RO) PSE debug state for +WF_QOP_Q_OPER_CS +* PSE_WF_QOP_RL_OCP_CS[13..12] - (RO) PSE debug state for +WF_QOP_RL_OCP_CS +* RESERVED14[15..14] - (RO) Reserved bits +* PSE_WF_QOP_PL_OCP_CS[17..16] - (RO) PSE debug state for +WF_QOP_PL_OCP_CS +* RESERVED18[19..18] - (RO) Reserved bits +* PSE_WF_QOP_ALLOCATE_CS[22..20] - (RO) PSE debug state for +WF_QOP_ALLOCATE_CS +* RESERVED23[31..23] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_QOP_ALLOCATE_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_04_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_QOP_ALLOCATE_CS_MASK \ + 0x00700000 /* PSE_WF_QOP_ALLOCATE_CS[22..20] */ +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_QOP_ALLOCATE_CS_SHFT 20 +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_QOP_PL_OCP_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_04_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_QOP_PL_OCP_CS_MASK \ + 0x00030000 /* PSE_WF_QOP_PL_OCP_CS[17..16] */ +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_QOP_PL_OCP_CS_SHFT 16 +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_QOP_RL_OCP_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_04_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_QOP_RL_OCP_CS_MASK \ + 0x00003000 /* PSE_WF_QOP_RL_OCP_CS[13..12] */ +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_QOP_RL_OCP_CS_SHFT 12 +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_QOP_Q_OPER_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_04_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_QOP_Q_OPER_CS_MASK \ + 0x00000F00 /* PSE_WF_QOP_Q_OPER_CS[11..8] */ +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_QOP_Q_OPER_CS_SHFT 8 +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_DOP_CACHE_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_04_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_DOP_CACHE_CS_MASK \ + 0x00000030 /* PSE_WF_DOP_CACHE_CS[5..4] */ +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_DOP_CACHE_CS_SHFT 4 +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_DOP_PBUF_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_04_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_DOP_PBUF_CS_MASK \ + 0x00000007 /* PSE_WF_DOP_PBUF_CS[2..0] */ +#define WF_PSE_TOP_PSE_SEEK_CR_04_PSE_WF_DOP_PBUF_CS_SHFT 0 + +/* +* ---PSE_SEEK_CR_05 (0x820C8000 + 0x3e4)--- +* PSE_MDP_DOP_PBUF_CS[2..0] - (RO) PSE debug state for MDP_DOP_PBUF_CS +* RESERVED3[3] - (RO) Reserved bits +* PSE_MDP_DOP_CACHE_CS[5..4] - (RO) PSE debug state for +MDP_DOP_CACHE_CS +* RESERVED6[7..6] - (RO) Reserved bits +* PSE_MDP_QOP_Q_OPER_CS[11..8] - (RO) PSE debug state for +MDP_QOP_Q_OPER_CS +* PSE_MDP_QOP_RL_OCP_CS[13..12] - (RO) PSE debug state for +MDP_QOP_RL_OCP_CS +* RESERVED14[15..14] - (RO) Reserved bits +* PSE_MDP_QOP_PL_OCP_CS[17..16] - (RO) PSE debug state for +MDP_QOP_PL_OCP_CS +* RESERVED18[19..18] - (RO) Reserved bits +* PSE_MDP_QOP_ALLOCATE_CS[22..20] - (RO) PSE debug state for +MDP_QOP_ALLOCATE_CS +* RESERVED23[31..23] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_QOP_ALLOCATE_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_05_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_QOP_ALLOCATE_CS_MASK \ + 0x00700000 /* PSE_MDP_QOP_ALLOCATE_CS[22..20] */ +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_QOP_ALLOCATE_CS_SHFT 20 +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_QOP_PL_OCP_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_05_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_QOP_PL_OCP_CS_MASK \ + 0x00030000 /* PSE_MDP_QOP_PL_OCP_CS[17..16] */ +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_QOP_PL_OCP_CS_SHFT 16 +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_QOP_RL_OCP_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_05_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_QOP_RL_OCP_CS_MASK \ + 0x00003000 /* PSE_MDP_QOP_RL_OCP_CS[13..12] */ +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_QOP_RL_OCP_CS_SHFT 12 +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_QOP_Q_OPER_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_05_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_QOP_Q_OPER_CS_MASK \ + 0x00000F00 /* PSE_MDP_QOP_Q_OPER_CS[11..8] */ +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_QOP_Q_OPER_CS_SHFT 8 +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_DOP_CACHE_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_05_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_DOP_CACHE_CS_MASK \ + 0x00000030 /* PSE_MDP_DOP_CACHE_CS[5..4] */ +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_DOP_CACHE_CS_SHFT 4 +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_DOP_PBUF_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_05_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_DOP_PBUF_CS_MASK \ + 0x00000007 /* PSE_MDP_DOP_PBUF_CS[2..0] */ +#define WF_PSE_TOP_PSE_SEEK_CR_05_PSE_MDP_DOP_PBUF_CS_SHFT 0 + +/* +* ---PSE_SEEK_CR_06 (0x820C8000 + 0x3e8)--- +* PSE_SEC_DOP_PBUF_CS[2..0] - (RO) PSE debug state for SEC_DOP_PBUF_CS +* RESERVED3[3] - (RO) Reserved bits +* PSE_SEC_DOP_CACHE_CS[5..4] - (RO) PSE debug state for +SEC_DOP_CACHE_CS +* RESERVED6[7..6] - (RO) Reserved bits +* PSE_SEC_QOP_Q_OPER_CS[11..8] - (RO) PSE debug state for +SEC_QOP_Q_OPER_CS +* PSE_SEC_QOP_RL_OCP_CS[13..12] - (RO) PSE debug state for +SEC_QOP_RL_OCP_CS +* RESERVED14[15..14] - (RO) Reserved bits +* PSE_SEC_QOP_PL_OCP_CS[17..16] - (RO) PSE debug state for +SEC_QOP_PL_OCP_CS +* RESERVED18[19..18] - (RO) Reserved bits +* PSE_SEC_QOP_ALLOCATE_CS[22..20] - (RO) PSE debug state for +SEC_QOP_ALLOCATE_CS +* RESERVED23[31..23] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_QOP_ALLOCATE_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_06_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_QOP_ALLOCATE_CS_MASK \ + 0x00700000 /* PSE_SEC_QOP_ALLOCATE_CS[22..20] */ +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_QOP_ALLOCATE_CS_SHFT 20 +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_QOP_PL_OCP_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_06_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_QOP_PL_OCP_CS_MASK \ + 0x00030000 /* PSE_SEC_QOP_PL_OCP_CS[17..16] */ +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_QOP_PL_OCP_CS_SHFT 16 +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_QOP_RL_OCP_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_06_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_QOP_RL_OCP_CS_MASK \ + 0x00003000 /* PSE_SEC_QOP_RL_OCP_CS[13..12] */ +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_QOP_RL_OCP_CS_SHFT 12 +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_QOP_Q_OPER_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_06_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_QOP_Q_OPER_CS_MASK \ + 0x00000F00 /* PSE_SEC_QOP_Q_OPER_CS[11..8] */ +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_QOP_Q_OPER_CS_SHFT 8 +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_DOP_CACHE_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_06_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_DOP_CACHE_CS_MASK \ + 0x00000030 /* PSE_SEC_DOP_CACHE_CS[5..4] */ +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_DOP_CACHE_CS_SHFT 4 +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_DOP_PBUF_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_06_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_DOP_PBUF_CS_MASK \ + 0x00000007 /* PSE_SEC_DOP_PBUF_CS[2..0] */ +#define WF_PSE_TOP_PSE_SEEK_CR_06_PSE_SEC_DOP_PBUF_CS_SHFT 0 + +/* +* ---PSE_SEEK_CR_07 (0x820C8000 + 0x3ec)--- +* PSE_PLE_DOP_PBUF_CS[2..0] - (RO) PSE debug state for PLE_DOP_PBUF_CS +* RESERVED3[3] - (RO) Reserved bits +* PSE_PLE_DOP_CACHE_CS[5..4] - (RO) PSE debug state for +PLE_DOP_CACHE_CS +* RESERVED6[7..6] - (RO) Reserved bits +* PSE_PLE_QOP_Q_OPER_CS[11..8] - (RO) PSE debug state for +PLE_QOP_Q_OPER_CS +* PSE_PLE_QOP_RL_OCP_CS[13..12] - (RO) PSE debug state for +PLE_QOP_RL_OCP_CS +* RESERVED14[15..14] - (RO) Reserved bits +* PSE_PLE_QOP_PL_OCP_CS[17..16] - (RO) PSE debug state for +PLE_QOP_PL_OCP_CS +* RESERVED18[19..18] - (RO) Reserved bits +* PSE_PLE_QOP_ALLOCATE_CS[22..20] - (RO) PSE debug state for +PLE_QOP_ALLOCATE_CS +* RESERVED23[31..23] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_QOP_ALLOCATE_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_07_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_QOP_ALLOCATE_CS_MASK \ + 0x00700000 /* PSE_PLE_QOP_ALLOCATE_CS[22..20] */ +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_QOP_ALLOCATE_CS_SHFT 20 +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_QOP_PL_OCP_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_07_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_QOP_PL_OCP_CS_MASK \ + 0x00030000 /* PSE_PLE_QOP_PL_OCP_CS[17..16] */ +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_QOP_PL_OCP_CS_SHFT 16 +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_QOP_RL_OCP_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_07_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_QOP_RL_OCP_CS_MASK \ + 0x00003000 /* PSE_PLE_QOP_RL_OCP_CS[13..12] */ +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_QOP_RL_OCP_CS_SHFT 12 +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_QOP_Q_OPER_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_07_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_QOP_Q_OPER_CS_MASK \ + 0x00000F00 /* PSE_PLE_QOP_Q_OPER_CS[11..8] */ +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_QOP_Q_OPER_CS_SHFT 8 +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_DOP_CACHE_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_07_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_DOP_CACHE_CS_MASK \ + 0x00000030 /* PSE_PLE_DOP_CACHE_CS[5..4] */ +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_DOP_CACHE_CS_SHFT 4 +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_DOP_PBUF_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_07_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_DOP_PBUF_CS_MASK \ + 0x00000007 /* PSE_PLE_DOP_PBUF_CS[2..0] */ +#define WF_PSE_TOP_PSE_SEEK_CR_07_PSE_PLE_DOP_PBUF_CS_SHFT 0 + +/* +* ---PSE_SEEK_CR_08 (0x820C8000 + 0x3f0)--- +* PSE_AMSDU_DOP_PBUF_CS[2..0] - (RO) PSE debug state for +AMSDU_DOP_PBUF_CS +* RESERVED3[3] - (RO) Reserved bits +* PSE_AMSDU_DOP_CACHE_CS[5..4] - (RO) PSE debug state for +AMSDU_DOP_CACHE_CS +* RESERVED6[7..6] - (RO) Reserved bits +* CPU_Q_OP_CS[11..8] - (RO) PSE debug state for CPI_Q_OP_CS +* ARB_REQ_CS[14..12] - (RO) PSE debug state for ARB_REQ_CS +* RESERVED15[15] - (RO) Reserved bits +* APB_REQ_CS[18..16] - (RO) PSE debug state for APB_REQ_CS +* RESERVED19[31..19] - (RO) Reserved bits +*/ +#define WF_PSE_TOP_PSE_SEEK_CR_08_APB_REQ_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_08_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_08_APB_REQ_CS_MASK \ + 0x00070000 /* APB_REQ_CS[18..16] */ +#define WF_PSE_TOP_PSE_SEEK_CR_08_APB_REQ_CS_SHFT 16 +#define WF_PSE_TOP_PSE_SEEK_CR_08_ARB_REQ_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_08_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_08_ARB_REQ_CS_MASK \ + 0x00007000 /* ARB_REQ_CS[14..12] */ +#define WF_PSE_TOP_PSE_SEEK_CR_08_ARB_REQ_CS_SHFT 12 +#define WF_PSE_TOP_PSE_SEEK_CR_08_CPU_Q_OP_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_08_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_08_CPU_Q_OP_CS_MASK \ + 0x00000F00 /* CPU_Q_OP_CS[11..8] */ +#define WF_PSE_TOP_PSE_SEEK_CR_08_CPU_Q_OP_CS_SHFT 8 +#define WF_PSE_TOP_PSE_SEEK_CR_08_PSE_AMSDU_DOP_CACHE_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_08_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_08_PSE_AMSDU_DOP_CACHE_CS_MASK \ + 0x00000030 /* PSE_AMSDU_DOP_CACHE_CS[5..4] */ +#define WF_PSE_TOP_PSE_SEEK_CR_08_PSE_AMSDU_DOP_CACHE_CS_SHFT 4 +#define WF_PSE_TOP_PSE_SEEK_CR_08_PSE_AMSDU_DOP_PBUF_CS_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_08_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_08_PSE_AMSDU_DOP_PBUF_CS_MASK \ + 0x00000007 /* PSE_AMSDU_DOP_PBUF_CS[2..0] */ +#define WF_PSE_TOP_PSE_SEEK_CR_08_PSE_AMSDU_DOP_PBUF_CS_SHFT 0 + +/* +* ---PSE_SEEK_CR_09 (0x820C8000 + 0x3f4)--- +* RESERVED0[15..0] - (RO) Reserved bits +* DOUBLE_RLS_FID[27..16] - (RO) PSE double RLS FID PAGE +* RESERVED28[30..28] - (RO) Reserved bits +* DOUBLE_RLS_ERROR[31] - (RO) PSE double RLS error flag +*/ +#define WF_PSE_TOP_PSE_SEEK_CR_09_DOUBLE_RLS_ERROR_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_09_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_09_DOUBLE_RLS_ERROR_MASK \ + 0x80000000 /* DOUBLE_RLS_ERROR[31] */ +#define WF_PSE_TOP_PSE_SEEK_CR_09_DOUBLE_RLS_ERROR_SHFT 31 +#define WF_PSE_TOP_PSE_SEEK_CR_09_DOUBLE_RLS_FID_ADDR \ + WF_PSE_TOP_PSE_SEEK_CR_09_ADDR +#define WF_PSE_TOP_PSE_SEEK_CR_09_DOUBLE_RLS_FID_MASK \ + 0x0FFF0000 /* DOUBLE_RLS_FID[27..16] */ +#define WF_PSE_TOP_PSE_SEEK_CR_09_DOUBLE_RLS_FID_SHFT 16 + +#ifdef __cplusplus +} +#endif + +#endif /* __WF_PSE_TOP_REGS_H__ */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/soc3_0/wf_wfdma_host_dma0.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/soc3_0/wf_wfdma_host_dma0.h new file mode 100644 index 0000000000000000000000000000000000000000..fc54b7cea924174252f80cda95da3680e35ea673 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/soc3_0/wf_wfdma_host_dma0.h @@ -0,0 +1,5922 @@ +/* [File] : wf_wfdma_host_dma0.h */ +/* [Revision time] : Mon Apr 15 14:14:47 2019 */ +/* [Description] : This file is auto generated by CODA */ +/* [Copyright] : Copyright (C) 2019 Mediatek Incorportion. All rights */ +/* reserved. */ + +#ifndef __WF_WFDMA_HOST_DMA0_REGS_H__ +#define __WF_WFDMA_HOST_DMA0_REGS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* ************************************************************************** */ +/* */ +/* WF_WFDMA_HOST_DMA0 CR Definitions */ +/* */ +/* ************************************************************************** */ + +#define WF_WFDMA_HOST_DMA0_BASE 0x7C024000 + +#define WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0XA0) /* 40A0 */ +#define WF_WFDMA_HOST_DMA0_HOST_IF_RX_DONE_STS_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0XA4) /* 40A4 */ +#define WF_WFDMA_HOST_DMA0_TX_DMAD_RNG_START_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x0B0) /* 40B0 */ +#define WF_WFDMA_HOST_DMA0_TX_DMAD_RNG_START_EXT_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x0B4) /* 40B4 */ +#define WF_WFDMA_HOST_DMA0_TX_DMAD_RNG_END_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x0B8) /* 40B8 */ +#define WF_WFDMA_HOST_DMA0_TX_DMAD_RNG_END_EXT_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x0BC) /* 40BC */ +#define WF_WFDMA_HOST_DMA0_RX_DMAD_RNG_START_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x0C0) /* 40C0 */ +#define WF_WFDMA_HOST_DMA0_RX_DMAD_RNG_START_EXT_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x0C4) /* 40C4 */ +#define WF_WFDMA_HOST_DMA0_RX_DMAD_RNG_END_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x0C8) /* 40C8 */ +#define WF_WFDMA_HOST_DMA0_RX_DMAD_RNG_END_EXT_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x0CC) /* 40CC */ +#define WF_WFDMA_HOST_DMA0_TX_PLD_RNG_START_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x0D0) /* 40D0 */ +#define WF_WFDMA_HOST_DMA0_TX_PLD_RNG_START_EXT_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x0D4) /* 40D4 */ +#define WF_WFDMA_HOST_DMA0_TX_PLD_RNG_END_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x0D8) /* 40D8 */ +#define WF_WFDMA_HOST_DMA0_TX_PLD_RNG_END_EXT_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x0DC) /* 40DC */ +#define WF_WFDMA_HOST_DMA0_RX_PLD_RNG_START_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x0E0) /* 40E0 */ +#define WF_WFDMA_HOST_DMA0_RX_PLD_RNG_START_EXT_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x0E4) /* 40E4 */ +#define WF_WFDMA_HOST_DMA0_RX_PLD_RNG_END_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x0E8) /* 40E8 */ +#define WF_WFDMA_HOST_DMA0_RX_PLD_RNG_END_EXT_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x0EC) /* 40EC */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_RST_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x100) /* 4100 */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_TOP_MISC_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x104) /* 4104 */ +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0X108) /* 4108 */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x10C) /* 410C */ +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0X110) /* 4110 */ +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0X114) /* 4114 */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DUMMY_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x120) /* 4120 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_DBG_IDX_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x124) /* 4124 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_DBG_PROBE_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x128) /* 4128 */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x12C) /* 412C */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_PROBE_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x130) /* 4130 */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DMASHDL_DBG_PROBE_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x134) /* 4134 */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x138) /* 4138 */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x13c) /* 413C */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_FIFO_TEST_MOD_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x140) /* 4140 */ +#define WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x1E8) /* 41E8 */ +#define WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x1EC) /* 41EC */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x1F0) /* 41F0 */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x1F4) /* 41F4 */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x1F8) /* 41F8 */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x1FC) /* 41FC */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x200) /* 4200 */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0X204) /* 4204 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x208) /* 4208 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x20C) /* 420C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_TX_Q_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x224) /* 4224 */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0X228) /* 4228 */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0X22C) /* 422C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x230) /* 4230 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_MISC_CFG_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x234) /* 4234 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x240) /* 4240 */ +#define WF_WFDMA_HOST_DMA0_MD_INT_STA_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x250) /* 4250 */ +#define WF_WFDMA_HOST_DMA0_MD_INT_ENA_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x254) /* 4254 */ +#define WF_WFDMA_HOST_DMA0_MCU2MD_SW_INT_SET_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x258) /* 4258 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH10_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x260) /* 4260 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH32_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x264) /* 4264 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH54_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x268) /* 4268 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH76_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x26C) /* 426C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x280) /* 4280 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x284) /* 4284 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_EXT_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x288) /* 4288 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x298) /* 4298 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_DBG0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x2A0) /* 42A0 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_DBG1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x2A4) /* 42A4 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_DBG0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x2A8) /* 42A8 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_DBG1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x2AC) /* 42AC */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x2B0) /* 42B0 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x2B4) /* 42B4 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x2C0) /* 42C0 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x2C4) /* 42C4 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x2C8) /* 42C8 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x2CC) /* 42CC */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x2D0) /* 42D0 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x2D4) /* 42D4 */ +#define WF_WFDMA_HOST_DMA0_HOST_PRI_INT_STA_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x2E0) /* 42E0 */ +#define WF_WFDMA_HOST_DMA0_HOST_PER_INT_ENA_STA_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x2E4) /* 42E4 */ +#define WF_WFDMA_HOST_DMA0_HOST_PER_DLY_INT_CFG_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x2E8) /* 42E8 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x2F0) /* 42F0 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x300) /* 4300 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x304) /* 4304 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x308) /* 4308 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x30c) /* 430C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x310) /* 4310 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x314) /* 4314 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x318) /* 4318 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x31c) /* 431C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x320) /* 4320 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x324) /* 4324 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x328) /* 4328 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x32c) /* 432C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x330) /* 4330 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x334) /* 4334 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x338) /* 4338 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x33c) /* 433C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x500) /* 4500 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x504) /* 4504 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x508) /* 4508 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x50c) /* 450C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x510) /* 4510 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x514) /* 4514 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x518) /* 4518 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x51c) /* 451C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x520) /* 4520 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x524) /* 4524 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x528) /* 4528 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x52C) /* 452C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x530) /* 4530 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x534) /* 4534 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x538) /* 4538 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x53C) /* 453C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x540) /* 4540 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x544) /* 4544 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x548) /* 4548 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x54c) /* 454C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x550) /* 4550 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x554) /* 4554 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x558) /* 4558 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x55c) /* 455C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x560) /* 4560 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x564) /* 4564 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x568) /* 4568 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x56C) /* 456C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x570) /* 4570 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x574) /* 4574 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x578) /* 4578 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x57C) /* 457C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x600) /* 4600 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x604) /* 4604 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x608) /* 4608 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x60C) /* 460C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x680) /* 4680 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x684) /* 4684 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x688) /* 4688 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x68C) /* 468C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x690) /* 4690 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x694) /* 4694 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x698) /* 4698 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0x69C) /* 469C */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xA00) /* 4A00 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xA04) /* 4A04 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xA08) /* 4A08 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xA10) /* 4A10 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xA14) /* 4A14 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xA18) /* 4A18 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xA20) /* 4A20 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xA24) /* 4A24 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xA28) /* 4A28 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xA30) /* 4A30 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xA34) /* 4A34 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xA38) /* 4A38 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xC00) /* 4C00 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xC04) /* 4C04 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xC08) /* 4C08 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xC10) /* 4C10 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xC14) /* 4C14 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xC18) /* 4C18 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xC20) /* 4C20 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xC24) /* 4C24 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xC28) /* 4C28 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xC30) /* 4C30 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xC34) /* 4C34 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xC38) /* 4C38 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xC40) /* 4C40 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xC44) /* 4C44 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xC48) /* 4C48 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xC50) /* 4C50 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xC54) /* 4C54 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xC58) /* 4C58 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xC60) /* 4C60 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xC64) /* 4C64 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xC68) /* 4C68 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xC70) /* 4C70 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xC74) /* 4C74 */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA0_BASE + 0xC78) /* 4C78 */ + +/* +* ---HOST_IF_TX_DONE_STS (0x18024000 + 0XA0)--- +* fifo_dfet_txdone_dat0_done_sts[0] - (W1C) USB DAT0 FIFO Tx status +* 0 : no tx done +* 1 : pdma fetch data from USB endpoint +buffer +* fifo_dfet_txdone_dat1_done_sts[1] - (W1C) USB DAT1 FIFO Tx status +* 0 : no tx done +* 1 : pdma fetch data from USB endpoint +buffer +* fifo_dfet_txdone_dat2_done_sts[2] - (W1C) USB DAT2 FIFO Tx status +* 0 : no tx done +* 1 : pdma fetch data from USB endpoint +buffer +* fifo_dfet_txdone_dat3_done_sts[3] - (W1C) USB DAT3 FIFO Tx status +* 0 : no tx done +* 1 : pdma fetch data from USB endpoint +buffer +* fifo_dfet_txdone_dat4_done_sts[4] - (W1C) USB DAT4 FIFO Tx status +* 0 : no tx done +* 1 : pdma fetch data from USB endpoint +buffer +* fifo_dfet_txdone_cmd_done_sts[5] - (W1C) USB CMD FIFO Tx status +* 0 : no tx done +* 1 : pdma fetch data from USB endpoint +buffer +* fifo_dfet_txdone_fwdl_done_sts[6] - (W1C) USB Firmware download FIFO Tx +status +* 0 : no tx done +* 1 : pdma fetch data from USB endpoint +buffer +* SDIO Mode (All SDIO Tx packet goto firmware +* download FIFO) +* 0 : no tx done +* 1 : pdma start to fetch data from SDIO +buffer +* RESERVED7[31..7] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_fwdl_done_sts_ADDR \ + \ + WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_ADDR +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_fwdl_done_sts_MASK \ + \ + 0x00000040 /* fifo_dfet_txdone_fwdl_done_sts[6] */ +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_fwdl_done_sts_SHFT \ + \ + 6 +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_cmd_done_sts_ADDR \ + \ + WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_ADDR +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_cmd_done_sts_MASK \ + \ + 0x00000020 /* fifo_dfet_txdone_cmd_done_sts[5] */ +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_cmd_done_sts_SHFT \ + \ + 5 +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat4_done_sts_ADDR \ + \ + WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_ADDR +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat4_done_sts_MASK \ + \ + 0x00000010 /* fifo_dfet_txdone_dat4_done_sts[4] */ +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat4_done_sts_SHFT \ + \ + 4 +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat3_done_sts_ADDR \ + \ + WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_ADDR +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat3_done_sts_MASK \ + \ + 0x00000008 /* fifo_dfet_txdone_dat3_done_sts[3] */ +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat3_done_sts_SHFT \ + \ + 3 +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat2_done_sts_ADDR \ + \ + WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_ADDR +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat2_done_sts_MASK \ + \ + 0x00000004 /* fifo_dfet_txdone_dat2_done_sts[2] */ +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat2_done_sts_SHFT \ + \ + 2 +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat1_done_sts_ADDR \ + \ + WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_ADDR +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat1_done_sts_MASK \ + \ + 0x00000002 /* fifo_dfet_txdone_dat1_done_sts[1] */ +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat1_done_sts_SHFT \ + \ + 1 +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat0_done_sts_ADDR \ + \ + WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_ADDR +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat0_done_sts_MASK \ + \ + 0x00000001 /* fifo_dfet_txdone_dat0_done_sts[0] */ +#define \ +WF_WFDMA_HOST_DMA0_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat0_done_sts_SHFT \ + \ + 0 + +/* +* ---HOST_IF_RX_DONE_STS (0x18024000 + 0XA4)--- +* rx0_packet_done_sts[0] - (W1C) USB/SDIO Rx0 packet done status +* 0 : no rx packet done +* 1 : rx packet send to host interface +* rx1_packet_done_sts[1] - (W1C) USB/SDIO Rx1 packet done status +* 0 : no rx packet done +* 1 : rx packet send to host interface +* Note : All SDIO Packet send to SIDO RX0 +port +* RESERVED2[31..2] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_HOST_IF_RX_DONE_STS_rx1_packet_done_sts_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_IF_RX_DONE_STS_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_IF_RX_DONE_STS_rx1_packet_done_sts_MASK \ + 0x00000002 /* rx1_packet_done_sts[1] */ +#define WF_WFDMA_HOST_DMA0_HOST_IF_RX_DONE_STS_rx1_packet_done_sts_SHFT 1 +#define WF_WFDMA_HOST_DMA0_HOST_IF_RX_DONE_STS_rx0_packet_done_sts_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_IF_RX_DONE_STS_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_IF_RX_DONE_STS_rx0_packet_done_sts_MASK \ + 0x00000001 /* rx0_packet_done_sts[0] */ +#define WF_WFDMA_HOST_DMA0_HOST_IF_RX_DONE_STS_rx0_packet_done_sts_SHFT 0 + +/* +* ---TX_DMAD_RNG_START (0x18024000 + 0x0B0)--- +* tx_dmad_rng_start[31..0] - (RW) TX DMAD address range start [31:0] +*/ +#define WF_WFDMA_HOST_DMA0_TX_DMAD_RNG_START_tx_dmad_rng_start_ADDR \ + WF_WFDMA_HOST_DMA0_TX_DMAD_RNG_START_ADDR +#define WF_WFDMA_HOST_DMA0_TX_DMAD_RNG_START_tx_dmad_rng_start_MASK \ + 0xFFFFFFFF /* tx_dmad_rng_start[31..0] */ +#define WF_WFDMA_HOST_DMA0_TX_DMAD_RNG_START_tx_dmad_rng_start_SHFT 0 + +/* +* ---TX_DMAD_RNG_START_EXT (0x18024000 + 0x0B4)--- +* tx_dmad_rng_start_ext[3..0] - (RW) TX DMAD address range start [35:32] +* RESERVED4[31..4] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_TX_DMAD_RNG_START_EXT_tx_dmad_rng_start_ext_ADDR \ + WF_WFDMA_HOST_DMA0_TX_DMAD_RNG_START_EXT_ADDR +#define WF_WFDMA_HOST_DMA0_TX_DMAD_RNG_START_EXT_tx_dmad_rng_start_ext_MASK \ + 0x0000000F /* tx_dmad_rng_start_ext[3..0] */ +#define WF_WFDMA_HOST_DMA0_TX_DMAD_RNG_START_EXT_tx_dmad_rng_start_ext_SHFT 0 + +/* +* ---TX_DMAD_RNG_END (0x18024000 + 0x0B8)--- +* tx_dmad_rng_end[31..0] - (RW) TX DMAD address range end [31:0] +*/ +#define WF_WFDMA_HOST_DMA0_TX_DMAD_RNG_END_tx_dmad_rng_end_ADDR \ + WF_WFDMA_HOST_DMA0_TX_DMAD_RNG_END_ADDR +#define WF_WFDMA_HOST_DMA0_TX_DMAD_RNG_END_tx_dmad_rng_end_MASK \ + 0xFFFFFFFF /* tx_dmad_rng_end[31..0] */ +#define WF_WFDMA_HOST_DMA0_TX_DMAD_RNG_END_tx_dmad_rng_end_SHFT 0 + +/* +* ---TX_DMAD_RNG_END_EXT (0x18024000 + 0x0BC)--- +* tx_dmad_rng_end_ext[3..0] - (RW) TX DMAD address range end [35:32] +* RESERVED4[31..4] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_TX_DMAD_RNG_END_EXT_tx_dmad_rng_end_ext_ADDR \ + WF_WFDMA_HOST_DMA0_TX_DMAD_RNG_END_EXT_ADDR +#define WF_WFDMA_HOST_DMA0_TX_DMAD_RNG_END_EXT_tx_dmad_rng_end_ext_MASK \ + 0x0000000F /* tx_dmad_rng_end_ext[3..0] */ +#define WF_WFDMA_HOST_DMA0_TX_DMAD_RNG_END_EXT_tx_dmad_rng_end_ext_SHFT 0 + +/* +* ---RX_DMAD_RNG_START (0x18024000 + 0x0C0)--- +* rx_dmad_rng_start[31..0] - (RW) RX DMAD address range start [31:0] +*/ +#define WF_WFDMA_HOST_DMA0_RX_DMAD_RNG_START_rx_dmad_rng_start_ADDR \ + WF_WFDMA_HOST_DMA0_RX_DMAD_RNG_START_ADDR +#define WF_WFDMA_HOST_DMA0_RX_DMAD_RNG_START_rx_dmad_rng_start_MASK \ + 0xFFFFFFFF /* rx_dmad_rng_start[31..0] */ +#define WF_WFDMA_HOST_DMA0_RX_DMAD_RNG_START_rx_dmad_rng_start_SHFT 0 + +/* +* ---RX_DMAD_RNG_START_EXT (0x18024000 + 0x0C4)--- +* rx_dmad_rng_start_ext[3..0] - (RW) RX DMAD address range start [35:32] +* RESERVED4[31..4] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_RX_DMAD_RNG_START_EXT_rx_dmad_rng_start_ext_ADDR \ + WF_WFDMA_HOST_DMA0_RX_DMAD_RNG_START_EXT_ADDR +#define WF_WFDMA_HOST_DMA0_RX_DMAD_RNG_START_EXT_rx_dmad_rng_start_ext_MASK \ + 0x0000000F /* rx_dmad_rng_start_ext[3..0] */ +#define WF_WFDMA_HOST_DMA0_RX_DMAD_RNG_START_EXT_rx_dmad_rng_start_ext_SHFT 0 + +/* +* ---RX_DMAD_RNG_END (0x18024000 + 0x0C8)--- +* rx_dmad_rng_end[31..0] - (RW) RX DMAD address range end [31:0] +*/ +#define WF_WFDMA_HOST_DMA0_RX_DMAD_RNG_END_rx_dmad_rng_end_ADDR \ + WF_WFDMA_HOST_DMA0_RX_DMAD_RNG_END_ADDR +#define WF_WFDMA_HOST_DMA0_RX_DMAD_RNG_END_rx_dmad_rng_end_MASK \ + 0xFFFFFFFF /* rx_dmad_rng_end[31..0] */ +#define WF_WFDMA_HOST_DMA0_RX_DMAD_RNG_END_rx_dmad_rng_end_SHFT 0 + +/* +* ---RX_DMAD_RNG_END_EXT (0x18024000 + 0x0CC)--- +* rx_dmad_rng_end_ext[3..0] - (RW) RX DMAD address range end [35:32] +* RESERVED4[31..4] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_RX_DMAD_RNG_END_EXT_rx_dmad_rng_end_ext_ADDR \ + WF_WFDMA_HOST_DMA0_RX_DMAD_RNG_END_EXT_ADDR +#define WF_WFDMA_HOST_DMA0_RX_DMAD_RNG_END_EXT_rx_dmad_rng_end_ext_MASK \ + 0x0000000F /* rx_dmad_rng_end_ext[3..0] */ +#define WF_WFDMA_HOST_DMA0_RX_DMAD_RNG_END_EXT_rx_dmad_rng_end_ext_SHFT 0 + +/* +* ---TX_PLD_RNG_START (0x18024000 + 0x0D0)--- +* tx_pld_rng_start[31..0] - (RW) TX PLD address range start [31:0] +*/ +#define WF_WFDMA_HOST_DMA0_TX_PLD_RNG_START_tx_pld_rng_start_ADDR \ + WF_WFDMA_HOST_DMA0_TX_PLD_RNG_START_ADDR +#define WF_WFDMA_HOST_DMA0_TX_PLD_RNG_START_tx_pld_rng_start_MASK \ + 0xFFFFFFFF /* tx_pld_rng_start[31..0] */ +#define WF_WFDMA_HOST_DMA0_TX_PLD_RNG_START_tx_pld_rng_start_SHFT 0 + +/* +* ---TX_PLD_RNG_START_EXT (0x18024000 + 0x0D4)--- +* tx_pld_rng_start_ext[3..0] - (RW) TX PLD address range start [35:32] +* RESERVED4[31..4] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_TX_PLD_RNG_START_EXT_tx_pld_rng_start_ext_ADDR \ + WF_WFDMA_HOST_DMA0_TX_PLD_RNG_START_EXT_ADDR +#define WF_WFDMA_HOST_DMA0_TX_PLD_RNG_START_EXT_tx_pld_rng_start_ext_MASK \ + 0x0000000F /* tx_pld_rng_start_ext[3..0] */ +#define WF_WFDMA_HOST_DMA0_TX_PLD_RNG_START_EXT_tx_pld_rng_start_ext_SHFT 0 + +/* +* ---TX_PLD_RNG_END (0x18024000 + 0x0D8)--- +* tx_pld_rng_end[31..0] - (RW) TX PLD address range end [31:0] +*/ +#define WF_WFDMA_HOST_DMA0_TX_PLD_RNG_END_tx_pld_rng_end_ADDR \ + WF_WFDMA_HOST_DMA0_TX_PLD_RNG_END_ADDR +#define WF_WFDMA_HOST_DMA0_TX_PLD_RNG_END_tx_pld_rng_end_MASK \ + 0xFFFFFFFF /* tx_pld_rng_end[31..0] */ +#define WF_WFDMA_HOST_DMA0_TX_PLD_RNG_END_tx_pld_rng_end_SHFT 0 + +/* +* ---TX_PLD_RNG_END_EXT (0x18024000 + 0x0DC)--- +* tx_pld_rng_end_ext[3..0] - (RW) TX PLD address range end [35:32] +* RESERVED4[31..4] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_TX_PLD_RNG_END_EXT_tx_pld_rng_end_ext_ADDR \ + WF_WFDMA_HOST_DMA0_TX_PLD_RNG_END_EXT_ADDR +#define WF_WFDMA_HOST_DMA0_TX_PLD_RNG_END_EXT_tx_pld_rng_end_ext_MASK \ + 0x0000000F /* tx_pld_rng_end_ext[3..0] */ +#define WF_WFDMA_HOST_DMA0_TX_PLD_RNG_END_EXT_tx_pld_rng_end_ext_SHFT 0 + +/* +* ---RX_PLD_RNG_START (0x18024000 + 0x0E0)--- +* rx_pld_rng_start[31..0] - (RW) RX PLD address range start [31:0] +*/ +#define WF_WFDMA_HOST_DMA0_RX_PLD_RNG_START_rx_pld_rng_start_ADDR \ + WF_WFDMA_HOST_DMA0_RX_PLD_RNG_START_ADDR +#define WF_WFDMA_HOST_DMA0_RX_PLD_RNG_START_rx_pld_rng_start_MASK \ + 0xFFFFFFFF /* rx_pld_rng_start[31..0] */ +#define WF_WFDMA_HOST_DMA0_RX_PLD_RNG_START_rx_pld_rng_start_SHFT 0 + +/* +* ---RX_PLD_RNG_START_EXT (0x18024000 + 0x0E4)--- +* rx_pld_rng_start_ext[3..0] - (RW) RX PLD address range start [35:32] +* RESERVED4[31..4] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_RX_PLD_RNG_START_EXT_rx_pld_rng_start_ext_ADDR \ + WF_WFDMA_HOST_DMA0_RX_PLD_RNG_START_EXT_ADDR +#define WF_WFDMA_HOST_DMA0_RX_PLD_RNG_START_EXT_rx_pld_rng_start_ext_MASK \ + 0x0000000F /* rx_pld_rng_start_ext[3..0] */ +#define WF_WFDMA_HOST_DMA0_RX_PLD_RNG_START_EXT_rx_pld_rng_start_ext_SHFT 0 + +/* +* ---RX_PLD_RNG_END (0x18024000 + 0x0E8)--- +* rx_pld_rng_end[31..0] - (RW) RX PLD address range end [31:0] +*/ +#define WF_WFDMA_HOST_DMA0_RX_PLD_RNG_END_rx_pld_rng_end_ADDR \ + WF_WFDMA_HOST_DMA0_RX_PLD_RNG_END_ADDR +#define WF_WFDMA_HOST_DMA0_RX_PLD_RNG_END_rx_pld_rng_end_MASK \ + 0xFFFFFFFF /* rx_pld_rng_end[31..0] */ +#define WF_WFDMA_HOST_DMA0_RX_PLD_RNG_END_rx_pld_rng_end_SHFT 0 + +/* +* ---RX_PLD_RNG_END_EXT (0x18024000 + 0x0EC)--- +* rx_pld_rng_end_ext[3..0] - (RW) RX PLD address range end [35:32] +* RESERVED4[31..4] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_RX_PLD_RNG_END_EXT_rx_pld_rng_end_ext_ADDR \ + WF_WFDMA_HOST_DMA0_RX_PLD_RNG_END_EXT_ADDR +#define WF_WFDMA_HOST_DMA0_RX_PLD_RNG_END_EXT_rx_pld_rng_end_ext_MASK \ + 0x0000000F /* rx_pld_rng_end_ext[3..0] */ +#define WF_WFDMA_HOST_DMA0_RX_PLD_RNG_END_EXT_rx_pld_rng_end_ext_SHFT 0 + +/* +* ---CONN_HIF_RST (0x18024000 + 0x100)--- +* RESERVED0[3..0] - (RO) Reserved bits +* conn_hif_logic_rst_n[4] - (RW) This conn_hif_logic_rst_n would reset +* wpdma logic partial control register, include Tx/Rx ring control. +* Also, conn_hif_logic_rst_n would reset wifi +* data path, include tx fifo, rx fifo, r2x_bridge, axi_mux and other other +* asynchronous bridge. +* (Note : conn_hif_logic_rst_n would not +* reset hif_dmashdl logic) +* dmashdl_all_rst_n[5] - (RW) This dmashdl_all_rst_n would reset +* hif_dmashdl_top, include logic and control register. +* RESERVED6[31..6] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_RST_dmashdl_all_rst_n_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_RST_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_RST_dmashdl_all_rst_n_MASK \ + 0x00000020 /* dmashdl_all_rst_n[5] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_RST_dmashdl_all_rst_n_SHFT 5 +#define WF_WFDMA_HOST_DMA0_CONN_HIF_RST_conn_hif_logic_rst_n_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_RST_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_RST_conn_hif_logic_rst_n_MASK \ + 0x00000010 /* conn_hif_logic_rst_n[4] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_RST_conn_hif_logic_rst_n_SHFT 4 + +/* +* ---CONN_HIF_TOP_MISC (0x18024000 + 0x104)--- +* ahb_mux_2to1_ultra[1..0] - (RW) conn _hif ahb mux ultra +* ahb_mux_2to1_qos_en[2] - (RW) conn_hif ahb mux qos enable +* RESERVED3[15..3] - (RO) Reserved bits +* pdma_rxring1_immint_en[16] - (RW) PDMA RX Ring 1 Immediate Interrupt +Enable +* RESERVED17[31..17] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_TOP_MISC_pdma_rxring1_immint_en_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_TOP_MISC_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_TOP_MISC_pdma_rxring1_immint_en_MASK \ + 0x00010000 /* pdma_rxring1_immint_en[16] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_TOP_MISC_pdma_rxring1_immint_en_SHFT 16 +#define WF_WFDMA_HOST_DMA0_CONN_HIF_TOP_MISC_ahb_mux_2to1_qos_en_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_TOP_MISC_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_TOP_MISC_ahb_mux_2to1_qos_en_MASK \ + 0x00000004 /* ahb_mux_2to1_qos_en[2] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_TOP_MISC_ahb_mux_2to1_qos_en_SHFT 2 +#define WF_WFDMA_HOST_DMA0_CONN_HIF_TOP_MISC_ahb_mux_2to1_ultra_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_TOP_MISC_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_TOP_MISC_ahb_mux_2to1_ultra_MASK \ + 0x00000003 /* ahb_mux_2to1_ultra[1..0] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_TOP_MISC_ahb_mux_2to1_ultra_SHFT 0 + +/* +* ---HOST2MCU_SW_INT_SET (0x18024000 + 0X108)--- +* host2mcu_sw_int_0_set[0] - (WO) Driver set this bit to generate MCU +* interrupt and 0x5000_0110[0] will be set to 1. +* host2mcu_sw_int_1_set[1] - (WO) Driver set this bit to generate MCU +* interrupt and 0x5000_0110[1] will be set to 1. +* host2mcu_sw_int_2_set[2] - (WO) Driver set this bit to generate MCU +* interrupt and 0x5000_0110[2] will be set to 1. +* host2mcu_sw_int_3_set[3] - (WO) Driver set [0x0_4108] bit[3] to generate +* MCU interrupt and 0x5000_0110[3] will be set to 1. +* host2mcu_sw_int_4_set[4] - (WO) Driver set [0x0_4108] bit[4] to generate +* MCU interrupt and 0x5000_0110[4] will be set to 1. +* host2mcu_sw_int_5_set[5] - (WO) Driver set [0x0_4108] bit[5] to generate +* MCU interrupt and 0x5000_0110[5] will be set to 1. +* host2mcu_sw_int_6_set[6] - (WO) Driver set [0x0_4108] bit[6] to generate +* MCU interrupt and 0x5000_0110[6] will be set to 1. +* host2mcu_sw_int_7_set[7] - (WO) Driver set [0x0_4108] bit[7] to generate +* MCU interrupt and 0x5000_0110[7] will be set to 1. +* RESERVED8[31..8] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_7_set_ADDR \ + WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_7_set_MASK \ + 0x00000080 /* host2mcu_sw_int_7_set[7] */ +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_7_set_SHFT 7 +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_6_set_ADDR \ + WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_6_set_MASK \ + 0x00000040 /* host2mcu_sw_int_6_set[6] */ +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_6_set_SHFT 6 +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_5_set_ADDR \ + WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_5_set_MASK \ + 0x00000020 /* host2mcu_sw_int_5_set[5] */ +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_5_set_SHFT 5 +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_4_set_ADDR \ + WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_4_set_MASK \ + 0x00000010 /* host2mcu_sw_int_4_set[4] */ +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_4_set_SHFT 4 +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_3_set_ADDR \ + WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_3_set_MASK \ + 0x00000008 /* host2mcu_sw_int_3_set[3] */ +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_3_set_SHFT 3 +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_2_set_ADDR \ + WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_2_set_MASK \ + 0x00000004 /* host2mcu_sw_int_2_set[2] */ +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_2_set_SHFT 2 +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_1_set_ADDR \ + WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_1_set_MASK \ + 0x00000002 /* host2mcu_sw_int_1_set[1] */ +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_1_set_SHFT 1 +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_0_set_ADDR \ + WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_0_set_MASK \ + 0x00000001 /* host2mcu_sw_int_0_set[0] */ +#define WF_WFDMA_HOST_DMA0_HOST2MCU_SW_INT_SET_host2mcu_sw_int_0_set_SHFT 0 + +/* +* ---MCU2HOST_SW_INT_SET (0x18024000 + 0x10C)--- +* mcu2host_sw_int_set_0[0] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[0] to check +* interrupt status +* mcu2host_sw_int_set_1[1] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[1] to check +* interrupt status +* mcu2host_sw_int_set_2[2] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[2] to check +* interrupt status +* mcu2host_sw_int_set_3[3] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[3] to check +* interrupt status +* mcu2host_sw_int_set_4[4] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[4] to check +* interrupt status +* mcu2host_sw_int_set_5[5] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[5] to check +* interrupt status +* mcu2host_sw_int_set_6[6] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[6] to check +* interrupt status +* mcu2host_sw_int_set_7[7] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[7] to check +* interrupt status +* mcu2host_sw_int_set_8[8] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[0] to check +* interrupt status +* mcu2host_sw_int_set_9[9] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[1] to check +* interrupt status +* mcu2host_sw_int_set_10[10] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[2] to check +* interrupt status +* mcu2host_sw_int_set_11[11] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[3] to check +* interrupt status +* mcu2host_sw_int_set_12[12] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[4] to check +* interrupt status +* mcu2host_sw_int_set_13[13] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[5] to check +* interrupt status +* mcu2host_sw_int_set_14[14] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[6] to check +* interrupt status +* mcu2host_sw_int_set_15[15] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[7] to check +* interrupt status +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_15_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_15_MASK \ + 0x00008000 /* mcu2host_sw_int_set_15[15] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_15_SHFT 15 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_14_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_14_MASK \ + 0x00004000 /* mcu2host_sw_int_set_14[14] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_14_SHFT 14 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_13_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_13_MASK \ + 0x00002000 /* mcu2host_sw_int_set_13[13] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_13_SHFT 13 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_12_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_12_MASK \ + 0x00001000 /* mcu2host_sw_int_set_12[12] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_12_SHFT 12 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_11_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_11_MASK \ + 0x00000800 /* mcu2host_sw_int_set_11[11] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_11_SHFT 11 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_10_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_10_MASK \ + 0x00000400 /* mcu2host_sw_int_set_10[10] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_10_SHFT 10 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_9_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_9_MASK \ + 0x00000200 /* mcu2host_sw_int_set_9[9] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_9_SHFT 9 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_8_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_8_MASK \ + 0x00000100 /* mcu2host_sw_int_set_8[8] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_8_SHFT 8 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_7_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_7_MASK \ + 0x00000080 /* mcu2host_sw_int_set_7[7] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_7_SHFT 7 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_6_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_6_MASK \ + 0x00000040 /* mcu2host_sw_int_set_6[6] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_6_SHFT 6 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_5_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_5_MASK \ + 0x00000020 /* mcu2host_sw_int_set_5[5] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_5_SHFT 5 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_4_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_4_MASK \ + 0x00000010 /* mcu2host_sw_int_set_4[4] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_4_SHFT 4 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_3_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_3_MASK \ + 0x00000008 /* mcu2host_sw_int_set_3[3] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_3_SHFT 3 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_2_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_2_MASK \ + 0x00000004 /* mcu2host_sw_int_set_2[2] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_2_SHFT 2 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_1_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_1_MASK \ + 0x00000002 /* mcu2host_sw_int_set_1[1] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_1_SHFT 1 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_0_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_0_MASK \ + 0x00000001 /* mcu2host_sw_int_set_0[0] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_0_SHFT 0 + +/* +* ---MCU_INT_STA (0x18024000 + 0X110)--- +* host2mcu_sw_int_sts[7..0] - (W1C) MCU interrupt status, write 1 to clear +* the interrupt +* wpdma_tx_timeout_int_sts[8] - (W1C) WPDMA TX dma timeout interrupt stauts, +* write 1 to clear the interrupt +* wpdma_rx_timeout_int_sts[9] - (W1C) WPDMA RX dma timeout interrupt stauts, +* write 1 to clear the interrupt +* wifi_txfifo0_wr_ovf_int_sts[10] - (W1C) conn_hif txfifo erorr detec +* interruptt. It indicate tx-fifo memory write overflow. +* wifi_txfifo1_wr_ovf_int_sts[11] - (W1C) conn_hif txfifo erorr detec +* interruptt. It indicate tx-fifo memory write overflow. +* wifi_rxfifo_wr_ovf_int_sts[12] - (W1C) conn_hif rxfifo erorr detect +* interrupt. It indicate rx-fifo memory write overflow. +* wpdma_tx_dmad_mem_range_err_mcu_int_sts[13] - (W1C) WPDMA tx dma descriptor +* memory range error detection mcu interrupt status +* When user setup WPDMA_TX_DMAD_RNG (not +* equal to zero), design would check tx_dmad address. If address range not +* correct, it would alarm memory range error interrupt +* wpdma_rx_dmad_mem_range_err_mcu_int_sts[14] - (W1C) WPDMA rx dma descriptor +* memory range error detection mcu interrupt status +* When user setup WPDMA_RX_DMAD_RNG (not +* equal to zero), design would check rx_dmad address. If address range not +* correct, it would alarm memory range error interrupt +* wpdma_tx_payload_mem_range_err_mcu_int_sts[15] - (W1C) WPDMA tx payload +* memory range error detection mcu interrupt status +* When user setup WPDMA_TX_PLD_RNG (not equal +* to zero), design would check tx_dma payload address. If address range not +* correct, it would alarm memory range error interrupt +* wpdma_rx_payload_mem_range_err_mcu_int_sts[16] - (W1C) WPDMA rx payload +* memory range error detection mcu interrupt status +* When user setup WPDMA_RX_PLD_RNG (not equal +* to zero), design would check rx_dma payload address. If address range not +* correct, it would alarm memory range error interrupt +* RESERVED17[31..17] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_rx_payload_mem_range_err_mcu_int_sts_ADDR \ + \ + WF_WFDMA_HOST_DMA0_MCU_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_rx_payload_mem_range_err_mcu_int_sts_MASK \ + \ + 0x00010000 /* wpdma_rx_payload_mem_range_err_mcu_int_sts[16] */ +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_rx_payload_mem_range_err_mcu_int_sts_SHFT \ + \ + 16 +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_tx_payload_mem_range_err_mcu_int_sts_ADDR \ + \ + WF_WFDMA_HOST_DMA0_MCU_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_tx_payload_mem_range_err_mcu_int_sts_MASK \ + \ + 0x00008000 /* wpdma_tx_payload_mem_range_err_mcu_int_sts[15] */ +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_tx_payload_mem_range_err_mcu_int_sts_SHFT \ + \ + 15 +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_rx_dmad_mem_range_err_mcu_int_sts_ADDR \ + \ + WF_WFDMA_HOST_DMA0_MCU_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_rx_dmad_mem_range_err_mcu_int_sts_MASK \ + \ + 0x00004000 /* wpdma_rx_dmad_mem_range_err_mcu_int_sts[14] */ +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_rx_dmad_mem_range_err_mcu_int_sts_SHFT \ + \ + 14 +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_tx_dmad_mem_range_err_mcu_int_sts_ADDR \ + \ + WF_WFDMA_HOST_DMA0_MCU_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_tx_dmad_mem_range_err_mcu_int_sts_MASK \ + \ + 0x00002000 /* wpdma_tx_dmad_mem_range_err_mcu_int_sts[13] */ +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_tx_dmad_mem_range_err_mcu_int_sts_SHFT \ + \ + 13 +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wifi_rxfifo_wr_ovf_int_sts_ADDR \ + WF_WFDMA_HOST_DMA0_MCU_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wifi_rxfifo_wr_ovf_int_sts_MASK \ + 0x00001000 /* wifi_rxfifo_wr_ovf_int_sts[12] */ +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wifi_rxfifo_wr_ovf_int_sts_SHFT 12 +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wifi_txfifo1_wr_ovf_int_sts_ADDR \ + WF_WFDMA_HOST_DMA0_MCU_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wifi_txfifo1_wr_ovf_int_sts_MASK \ + 0x00000800 /* wifi_txfifo1_wr_ovf_int_sts[11] */ +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wifi_txfifo1_wr_ovf_int_sts_SHFT 11 +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wifi_txfifo0_wr_ovf_int_sts_ADDR \ + WF_WFDMA_HOST_DMA0_MCU_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wifi_txfifo0_wr_ovf_int_sts_MASK \ + 0x00000400 /* wifi_txfifo0_wr_ovf_int_sts[10] */ +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wifi_txfifo0_wr_ovf_int_sts_SHFT 10 +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_rx_timeout_int_sts_ADDR \ + WF_WFDMA_HOST_DMA0_MCU_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_rx_timeout_int_sts_MASK \ + 0x00000200 /* wpdma_rx_timeout_int_sts[9] */ +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_rx_timeout_int_sts_SHFT 9 +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_tx_timeout_int_sts_ADDR \ + WF_WFDMA_HOST_DMA0_MCU_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_tx_timeout_int_sts_MASK \ + 0x00000100 /* wpdma_tx_timeout_int_sts[8] */ +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_wpdma_tx_timeout_int_sts_SHFT 8 +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_host2mcu_sw_int_sts_ADDR \ + WF_WFDMA_HOST_DMA0_MCU_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_host2mcu_sw_int_sts_MASK \ + 0x000000FF /* host2mcu_sw_int_sts[7..0] */ +#define WF_WFDMA_HOST_DMA0_MCU_INT_STA_host2mcu_sw_int_sts_SHFT 0 + +/* +* ---MCU_INT_ENA (0x18024000 + 0X114)--- +* host2mcu_sw_int_ena[7..0] - (RW) host2mcu interrupt enable +* wpdma_tx_dma_timeout_int_ena[8] - (RW) WPDMA TX error detection interrupt +enable +* wpdma_rx_dma_timeout_int_ena[9] - (RW) WPDMA RX error detection interrupt +enable +* wifi_txfifo0_wr_ovf_int_ena[10] - (RW) conn_hif txfifo erorr detect +* interrupt enable. +* wifi_txfifo1_wr_ovf_int_ena[11] - (RW) conn_hif txfifo erorr detect +* interrupt enable. +* wifi_rxfifo_wr_ovf_int_ena[12] - (RW) conn_hif rxfifo erorr detect interrupt +enable. +* wpdma_tx_dmad_mem_range_err_mcu_int_ena[13] - (RW) WPDMA tx dma descriptor +* memory range error detection interrupt enable +* wpdma_rx_dmad_mem_range_err_mcu_int_ena[14] - (RW) WPDMA rx dma descriptor +* memory range error detection interrupt enable +* wpdma_tx_payload_mem_range_err_mcu_int_ena[15] - (RW) WPDMA tx payload +* memory range error detection interrupt enable +* wpdma_rx_payload_mem_range_err_mcu_int_ena[16] - (RW) WPDMA rx payload +* memory range error detection interrupt enable +* RESERVED17[31..17] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_rx_payload_mem_range_err_mcu_int_ena_ADDR \ + \ + WF_WFDMA_HOST_DMA0_MCU_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_rx_payload_mem_range_err_mcu_int_ena_MASK \ + \ + 0x00010000 /* wpdma_rx_payload_mem_range_err_mcu_int_ena[16] */ +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_rx_payload_mem_range_err_mcu_int_ena_SHFT \ + \ + 16 +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_tx_payload_mem_range_err_mcu_int_ena_ADDR \ + \ + WF_WFDMA_HOST_DMA0_MCU_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_tx_payload_mem_range_err_mcu_int_ena_MASK \ + \ + 0x00008000 /* wpdma_tx_payload_mem_range_err_mcu_int_ena[15] */ +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_tx_payload_mem_range_err_mcu_int_ena_SHFT \ + \ + 15 +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_rx_dmad_mem_range_err_mcu_int_ena_ADDR \ + \ + WF_WFDMA_HOST_DMA0_MCU_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_rx_dmad_mem_range_err_mcu_int_ena_MASK \ + \ + 0x00004000 /* wpdma_rx_dmad_mem_range_err_mcu_int_ena[14] */ +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_rx_dmad_mem_range_err_mcu_int_ena_SHFT \ + \ + 14 +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_tx_dmad_mem_range_err_mcu_int_ena_ADDR \ + \ + WF_WFDMA_HOST_DMA0_MCU_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_tx_dmad_mem_range_err_mcu_int_ena_MASK \ + \ + 0x00002000 /* wpdma_tx_dmad_mem_range_err_mcu_int_ena[13] */ +#define \ +WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_tx_dmad_mem_range_err_mcu_int_ena_SHFT \ + \ + 13 +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wifi_rxfifo_wr_ovf_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_MCU_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wifi_rxfifo_wr_ovf_int_ena_MASK \ + 0x00001000 /* wifi_rxfifo_wr_ovf_int_ena[12] */ +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wifi_rxfifo_wr_ovf_int_ena_SHFT 12 +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wifi_txfifo1_wr_ovf_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_MCU_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wifi_txfifo1_wr_ovf_int_ena_MASK \ + 0x00000800 /* wifi_txfifo1_wr_ovf_int_ena[11] */ +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wifi_txfifo1_wr_ovf_int_ena_SHFT 11 +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wifi_txfifo0_wr_ovf_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_MCU_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wifi_txfifo0_wr_ovf_int_ena_MASK \ + 0x00000400 /* wifi_txfifo0_wr_ovf_int_ena[10] */ +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wifi_txfifo0_wr_ovf_int_ena_SHFT 10 +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_rx_dma_timeout_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_MCU_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_rx_dma_timeout_int_ena_MASK \ + 0x00000200 /* wpdma_rx_dma_timeout_int_ena[9] */ +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_rx_dma_timeout_int_ena_SHFT 9 +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_tx_dma_timeout_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_MCU_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_tx_dma_timeout_int_ena_MASK \ + 0x00000100 /* wpdma_tx_dma_timeout_int_ena[8] */ +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_wpdma_tx_dma_timeout_int_ena_SHFT 8 +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_host2mcu_sw_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_MCU_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_host2mcu_sw_int_ena_MASK \ + 0x000000FF /* host2mcu_sw_int_ena[7..0] */ +#define WF_WFDMA_HOST_DMA0_MCU_INT_ENA_host2mcu_sw_int_ena_SHFT 0 + +/* +* ---CONN_HIF_DUMMY (0x18024000 + 0x120)--- +* CONN_HIF_DUMMY[31..0] - (RW) Reserved CR, SE will use it for pcie +calibration! +*/ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DUMMY_CONN_HIF_DUMMY_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_DUMMY_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DUMMY_CONN_HIF_DUMMY_MASK \ + 0xFFFFFFFF /* CONN_HIF_DUMMY[31..0] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DUMMY_CONN_HIF_DUMMY_SHFT 0 + +/* +* ---WPDMA_DBG_IDX (0x18024000 + 0x124)--- +* PDMA_DBG_IDX[7..0] - (RW) PDMA debug index +* PDMA_DBG_Enable[8] - (RW) PDMA Debug Enable +* 0: PDMA_DBG_port would has no function +* 1 : PDMA DBG_IDX select PDMA debug flag +index +* RESERVED9[31..9] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_DBG_IDX_PDMA_DBG_Enable_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_DBG_IDX_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_DBG_IDX_PDMA_DBG_Enable_MASK \ + 0x00000100 /* PDMA_DBG_Enable[8] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_DBG_IDX_PDMA_DBG_Enable_SHFT 8 +#define WF_WFDMA_HOST_DMA0_WPDMA_DBG_IDX_PDMA_DBG_IDX_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_DBG_IDX_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_DBG_IDX_PDMA_DBG_IDX_MASK \ + 0x000000FF /* PDMA_DBG_IDX[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_DBG_IDX_PDMA_DBG_IDX_SHFT 0 + +/* +* ---WPDMA_DBG_PROBE (0x18024000 + 0x128)--- +* PDMA_DBG_PROBE[31..0] - (RO) PDMA Debug probe read +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_DBG_PROBE_PDMA_DBG_PROBE_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_DBG_PROBE_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_DBG_PROBE_PDMA_DBG_PROBE_MASK \ + 0xFFFFFFFF /* PDMA_DBG_PROBE[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_DBG_PROBE_PDMA_DBG_PROBE_SHFT 0 + +/* +* ---CONN_HIF_DBG_IDX (0x18024000 + 0x12C)--- +* conn_hif_dbg_byt0_sel[2..0] - (RW) conn_hif_dbg_byt0_sel : Select +* conn_hif_dbg[7:0] from "pdma_dbg"/"hif_dmashdl_top" +* conn_hif_dbg_byt1_sel[5..3] - (RW) conn_hif_dbg_byt1_sel : Select +* conn_hif_dbg[15:8] from "pdma_dbg"/"hif_dmashdl_top" +* conn_hif_dbg_byt2_sel[8..6] - (RW) conn_hif_dbg_byt2_sel : Select +* conn_hif_dbg[23:16] from "pdma_dbg"/"hif_dmashdl_top" +* conn_hif_dbg_byt3_sel[11..9] - (RW) conn_hif_dbg_byt3_sel : Select +* conn_hif_dbg[31:24] from "pdma_dbg"/"hif_dmashdl_top" +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_conn_hif_dbg_byt3_sel_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_conn_hif_dbg_byt3_sel_MASK \ + 0x00000E00 /* conn_hif_dbg_byt3_sel[11..9] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_conn_hif_dbg_byt3_sel_SHFT 9 +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_conn_hif_dbg_byt2_sel_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_conn_hif_dbg_byt2_sel_MASK \ + 0x000001C0 /* conn_hif_dbg_byt2_sel[8..6] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_conn_hif_dbg_byt2_sel_SHFT 6 +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_conn_hif_dbg_byt1_sel_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_conn_hif_dbg_byt1_sel_MASK \ + 0x00000038 /* conn_hif_dbg_byt1_sel[5..3] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_conn_hif_dbg_byt1_sel_SHFT 3 +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_conn_hif_dbg_byt0_sel_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_conn_hif_dbg_byt0_sel_MASK \ + 0x00000007 /* conn_hif_dbg_byt0_sel[2..0] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_IDX_conn_hif_dbg_byt0_sel_SHFT 0 + +/* +* ---CONN_HIF_DBG_PROBE (0x18024000 + 0x130)--- +* conn_hif_dbg_probe[31..0] - (RO) conn_hif_dbg_probe read +*/ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_PROBE_conn_hif_dbg_probe_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_PROBE_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_PROBE_conn_hif_dbg_probe_MASK \ + 0xFFFFFFFF /* conn_hif_dbg_probe[31..0] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DBG_PROBE_conn_hif_dbg_probe_SHFT 0 + +/* +* ---CONN_HIF_DMASHDL_DBG_PROBE (0x18024000 + 0x134)--- +* DMASHDL_DBG_PROBE[15..0] - (RO) conn_hif_dmashdl_dbg_probe read +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DMASHDL_DBG_PROBE_DMASHDL_DBG_PROBE_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_DMASHDL_DBG_PROBE_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DMASHDL_DBG_PROBE_DMASHDL_DBG_PROBE_MASK \ + 0x0000FFFF /* DMASHDL_DBG_PROBE[15..0] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_DMASHDL_DBG_PROBE_DMASHDL_DBG_PROBE_SHFT 0 + +/* +* ---CONN_HIF_BUSY_STATUS (0x18024000 + 0x138)--- +* conn_hif_txfifo0_busy[0] - (RO) conn_hif txfifo0 busy status +* 0 : txfifo empty +* 1 : txfifo non empty +* conn_hif_txfifo1_busy[1] - (RO) conn_hif txfifo1 busy status +* 0 : txfifo empty +* 1 : txfifo non empty +* conn_hif_rxfifo_busy[2] - (RO) conn_hif rxfifo busy status +* 0 : rxfifo empty +* 1 : rxfifo non empty +* RESERVED[30..3] - (RO) Reserved CR +* conn_hif_busy[31] - (RO) Over all conn_hif busy status, it was +* busy summation of bit[6] ~ bit[0] status +*/ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_conn_hif_busy_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_conn_hif_busy_MASK \ + 0x80000000 /* conn_hif_busy[31] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_conn_hif_busy_SHFT 31 +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_conn_hif_rxfifo_busy_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_conn_hif_rxfifo_busy_MASK \ + 0x00000004 /* conn_hif_rxfifo_busy[2] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_conn_hif_rxfifo_busy_SHFT 2 +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_conn_hif_txfifo1_busy_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_conn_hif_txfifo1_busy_MASK \ + 0x00000002 /* conn_hif_txfifo1_busy[1] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_conn_hif_txfifo1_busy_SHFT 1 +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_conn_hif_txfifo0_busy_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_conn_hif_txfifo0_busy_MASK \ + 0x00000001 /* conn_hif_txfifo0_busy[0] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_STATUS_conn_hif_txfifo0_busy_SHFT 0 + +/* +* ---CONN_HIF_BUSY_ENA (0x18024000 + 0x13c)--- +* conn_hif_txfifo0_busy_enable[0] - (RW) busy enable control +* 0: ignore busy status +* 1: conn_hif_busy would tack care busy +status +* conn_hif_txfifo1_busy_enable[1] - (RW) busy enable control +* 0: ignore busy status +* 1: conn_hif_busy would tack care busy +status +* conn_hif_rxfifo_busy_enable[2] - (RW) busy enable control +* 0: ignore busy status +* 1: conn_hif_busy would tack care busy +status +* RESERVED3[4..3] - (RO) Reserved bits +* RESERVED[31..5] - (RW) Reserved CR +*/ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_conn_hif_rxfifo_busy_enable_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_conn_hif_rxfifo_busy_enable_MASK \ + 0x00000004 /* conn_hif_rxfifo_busy_enable[2] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_conn_hif_rxfifo_busy_enable_SHFT 2 +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_conn_hif_txfifo1_busy_enable_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_conn_hif_txfifo1_busy_enable_MASK \ + 0x00000002 /* conn_hif_txfifo1_busy_enable[1] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_conn_hif_txfifo1_busy_enable_SHFT 1 +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_conn_hif_txfifo0_busy_enable_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_conn_hif_txfifo0_busy_enable_MASK \ + 0x00000001 /* conn_hif_txfifo0_busy_enable[0] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_BUSY_ENA_conn_hif_txfifo0_busy_enable_SHFT 0 + +/* +* ---CONN_HIF_FIFO_TEST_MOD (0x18024000 + 0x140)--- +* csr_wfdma_loopback_en[0] - (RW) conn_hif fifo loopback enable +* NOTICE : when loopback, OMIT_TX_INFO and +* OMIT_RX_INFO sould be both set to 1'b1 +* csr_wfdma_loopback_qsel[2..1] - (RW) No USE for (conn_hif fifo loopback +* packet go into Rx-ring number) +* RESERVED3[31..3] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_FIFO_TEST_MOD_csr_wfdma_loopback_qsel_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_FIFO_TEST_MOD_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_FIFO_TEST_MOD_csr_wfdma_loopback_qsel_MASK \ + 0x00000006 /* csr_wfdma_loopback_qsel[2..1] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_FIFO_TEST_MOD_csr_wfdma_loopback_qsel_SHFT 1 +#define WF_WFDMA_HOST_DMA0_CONN_HIF_FIFO_TEST_MOD_csr_wfdma_loopback_en_ADDR \ + WF_WFDMA_HOST_DMA0_CONN_HIF_FIFO_TEST_MOD_ADDR +#define WF_WFDMA_HOST_DMA0_CONN_HIF_FIFO_TEST_MOD_csr_wfdma_loopback_en_MASK \ + 0x00000001 /* csr_wfdma_loopback_en[0] */ +#define WF_WFDMA_HOST_DMA0_CONN_HIF_FIFO_TEST_MOD_csr_wfdma_loopback_en_SHFT 0 + +/* +* ---WPDMA2HOST_ERR_INT_STA (0x18024000 + 0x1E8)--- +* wpdma_tx_timeout_int_sts[0] - (W1C) WPDMA TX error detection interrupt +* stauts, write 1 to clear the interrupt +* wpdma_rx_timeout_int_sts[1] - (W1C) WPDMA RX error detection interrupt +* stauts, write 1 to clear the interrupt +* RESERVED2[31..2] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_wpdma_rx_timeout_int_sts_ADDR \ + \ + WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_wpdma_rx_timeout_int_sts_MASK \ + \ + 0x00000002 /* wpdma_rx_timeout_int_sts[1] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_wpdma_rx_timeout_int_sts_SHFT \ + \ + 1 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_wpdma_tx_timeout_int_sts_ADDR \ + \ + WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_wpdma_tx_timeout_int_sts_MASK \ + \ + 0x00000001 /* wpdma_tx_timeout_int_sts[0] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_STA_wpdma_tx_timeout_int_sts_SHFT \ + \ + 0 + +/* +* ---WPDMA2HOST_ERR_INT_ENA (0x18024000 + 0x1EC)--- +* wpdma_rx_timeout_int_ena[0] - (RW) WPDMA TX error detection interrupt +enable +* wpdma_tx_timeout_int_ena[1] - (RW) WPDMA RX error detection interrupt +enable +* RESERVED2[31..2] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_wpdma_tx_timeout_int_ena_ADDR \ + \ + WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_wpdma_tx_timeout_int_ena_MASK \ + \ + 0x00000002 /* wpdma_tx_timeout_int_ena[1] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_wpdma_tx_timeout_int_ena_SHFT \ + \ + 1 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_wpdma_rx_timeout_int_ena_ADDR \ + \ + WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_wpdma_rx_timeout_int_ena_MASK \ + \ + 0x00000001 /* wpdma_rx_timeout_int_ena[0] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA2HOST_ERR_INT_ENA_wpdma_rx_timeout_int_ena_SHFT \ + \ + 0 + +/* +* ---MCU2HOST_SW_INT_STA (0x18024000 + 0x1F0)--- +* mcu2host_sw_int_0[0] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_1[1] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_2[2] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_3[3] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_4[4] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_5[5] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_6[6] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_7[7] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_8[8] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_9[9] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_10[10] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_11[11] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_12[12] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_13[13] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_14[14] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_15[15] - (W1C) mcu2host interrupt status +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_15_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_15_MASK \ + 0x00008000 /* mcu2host_sw_int_15[15] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_15_SHFT 15 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_14_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_14_MASK \ + 0x00004000 /* mcu2host_sw_int_14[14] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_14_SHFT 14 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_13_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_13_MASK \ + 0x00002000 /* mcu2host_sw_int_13[13] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_13_SHFT 13 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_12_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_12_MASK \ + 0x00001000 /* mcu2host_sw_int_12[12] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_12_SHFT 12 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_11_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_11_MASK \ + 0x00000800 /* mcu2host_sw_int_11[11] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_11_SHFT 11 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_10_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_10_MASK \ + 0x00000400 /* mcu2host_sw_int_10[10] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_10_SHFT 10 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_9_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_9_MASK \ + 0x00000200 /* mcu2host_sw_int_9[9] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_9_SHFT 9 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_8_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_8_MASK \ + 0x00000100 /* mcu2host_sw_int_8[8] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_8_SHFT 8 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_7_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_7_MASK \ + 0x00000080 /* mcu2host_sw_int_7[7] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_7_SHFT 7 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_6_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_6_MASK \ + 0x00000040 /* mcu2host_sw_int_6[6] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_6_SHFT 6 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_5_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_5_MASK \ + 0x00000020 /* mcu2host_sw_int_5[5] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_5_SHFT 5 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_4_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_4_MASK \ + 0x00000010 /* mcu2host_sw_int_4[4] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_4_SHFT 4 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_3_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_3_MASK \ + 0x00000008 /* mcu2host_sw_int_3[3] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_3_SHFT 3 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_2_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_2_MASK \ + 0x00000004 /* mcu2host_sw_int_2[2] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_2_SHFT 2 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_1_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_1_MASK \ + 0x00000002 /* mcu2host_sw_int_1[1] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_1_SHFT 1 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_0_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_0_MASK \ + 0x00000001 /* mcu2host_sw_int_0[0] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_STA_mcu2host_sw_int_0_SHFT 0 + +/* +* ---MCU2HOST_SW_INT_ENA (0x18024000 + 0x1F4)--- +* mcu2host_int_ena_0[0] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_1[1] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_2[2] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_3[3] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_4[4] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_5[5] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_6[6] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_7[7] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_8[8] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_9[9] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_10[10] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_11[11] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_12[12] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_13[13] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_14[14] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_15[15] - (RW) MCU2HOST software interrupt interrupt +enable +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_15_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_15_MASK \ + 0x00008000 /* mcu2host_int_ena_15[15] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_15_SHFT 15 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_14_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_14_MASK \ + 0x00004000 /* mcu2host_int_ena_14[14] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_14_SHFT 14 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_13_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_13_MASK \ + 0x00002000 /* mcu2host_int_ena_13[13] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_13_SHFT 13 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_12_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_12_MASK \ + 0x00001000 /* mcu2host_int_ena_12[12] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_12_SHFT 12 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_11_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_11_MASK \ + 0x00000800 /* mcu2host_int_ena_11[11] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_11_SHFT 11 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_10_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_10_MASK \ + 0x00000400 /* mcu2host_int_ena_10[10] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_10_SHFT 10 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_9_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_9_MASK \ + 0x00000200 /* mcu2host_int_ena_9[9] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_9_SHFT 9 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_8_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_8_MASK \ + 0x00000100 /* mcu2host_int_ena_8[8] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_8_SHFT 8 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_7_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_7_MASK \ + 0x00000080 /* mcu2host_int_ena_7[7] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_7_SHFT 7 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_6_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_6_MASK \ + 0x00000040 /* mcu2host_int_ena_6[6] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_6_SHFT 6 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_5_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_5_MASK \ + 0x00000020 /* mcu2host_int_ena_5[5] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_5_SHFT 5 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_4_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_4_MASK \ + 0x00000010 /* mcu2host_int_ena_4[4] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_4_SHFT 4 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_3_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_3_MASK \ + 0x00000008 /* mcu2host_int_ena_3[3] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_3_SHFT 3 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_2_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_2_MASK \ + 0x00000004 /* mcu2host_int_ena_2[2] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_2_SHFT 2 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_1_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_1_MASK \ + 0x00000002 /* mcu2host_int_ena_1[1] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_1_SHFT 1 +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_0_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_0_MASK \ + 0x00000001 /* mcu2host_int_ena_0[0] */ +#define WF_WFDMA_HOST_DMA0_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_0_SHFT 0 + +/* +* ---SUBSYS2HOST_INT_STA (0x18024000 + 0x1F8)--- +* mac_int_sts_0[0] - (RO) MAC interrupt 0: TBTT interrupt(Check +* wf_int_wakeup_top/hwisr0 [0x820Fc03c]) +* 0 : no interrupt +* 1 : interrupt assert +* mac_int_sts_1[1] - (RO) MAC interrupt 1: Pre-TBTT +* interrupt(Check wf_int_wakeup_top/hwisr1 [0x820Fc044]) +* 0 : no interrupt +* 1 : interrupt assert +* mac_int_sts_2[2] - (RO) MAC interrupt 2: TX status +* interrupt(Check wf_int_wakeup_top/hwisr2 [0x820Fc04c]) +* 0 : no interrupt +* 1 : interrupt assert +* mac_int_sts_3[3] - (RO) MAC interrupt 3: Auto wakeup interrupt +* (Check wf_int_wakeup_top/hwisr3 [0x820Fc054]) +* 0 : no interrupt +* 1 : interrupt assert +* mac_int_sts_4[4] - (RO) MAC interrupt 4: GP timer interrupt +* (Check wf_int_wakeup_top/hwisr4 [0x820Fc05c]) +* 0 : no interrupt +* 1 : interrupt assert +* RESERVED5[7..5] - (RO) Reserved bits +* conn_hif_on_host_int_sts[8] - (RO) CONN_HIF_ON interrupt enable +* 0 : no conn_hif_on_host_int interrupt +* 1 : conn_hif_on_host_int interrupt assert. +* User should check conn_hif_on (host_csr) interrupt status and clear interrupt. +* conn2ap_sw_irq_sts[9] - (RO) MCUSYS conn2ap_sw_irq status (Check +* conn_mcu_config/EMI_CTL [0x80000150] bit[4:0]) +* 0 : no conn2ap_sw_irq interrupt. +* 1 : conn2ap_sw_irq interrupt assert. User +* should check mcusys_n9 interrupt status and clear interrupt. +* (conn_mcu_config/EMI_CTL [0x80000150] bit[4:0] != 0) +* RESERVED10[31..10] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_conn2ap_sw_irq_sts_ADDR \ + WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_conn2ap_sw_irq_sts_MASK \ + 0x00000200 /* conn2ap_sw_irq_sts[9] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_conn2ap_sw_irq_sts_SHFT 9 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_conn_hif_on_host_int_sts_ADDR \ + WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_conn_hif_on_host_int_sts_MASK \ + 0x00000100 /* conn_hif_on_host_int_sts[8] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_conn_hif_on_host_int_sts_SHFT 8 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_4_ADDR \ + WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_4_MASK \ + 0x00000010 /* mac_int_sts_4[4] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_4_SHFT 4 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_3_ADDR \ + WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_3_MASK \ + 0x00000008 /* mac_int_sts_3[3] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_3_SHFT 3 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_2_ADDR \ + WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_2_MASK \ + 0x00000004 /* mac_int_sts_2[2] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_2_SHFT 2 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_1_ADDR \ + WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_1_MASK \ + 0x00000002 /* mac_int_sts_1[1] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_1_SHFT 1 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_0_ADDR \ + WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_0_MASK \ + 0x00000001 /* mac_int_sts_0[0] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_STA_mac_int_sts_0_SHFT 0 + +/* +* ---SUBSYS2HOST_INT_ENA (0x18024000 + 0x1FC)--- +* mac_int_ena_0[0] - (RW) MAC interrupt enable +* mac_int_ena_1[1] - (RW) MAC interrupt enable +* mac_int_ena_2[2] - (RW) MAC interrupt enable +* mac_int_ena_3[3] - (RW) MAC interrupt enable +* mac_int_ena_4[4] - (RW) MAC interrupt enable +* RESERVED5[7..5] - (RO) Reserved bits +* conn_hif_on_host_int_ena[8] - (RW) CONN_HIF_ON interrupt enable +* conn2ap_sw_irq_ena[9] - (RW) MCUSYS conn2ap_sw_irq enable +* dmashdl_int_ena[10] - (RW) DMASHDL interrupt enable +* mac_int_ena_5[11] - (RW) MAC interrupt enable +* mac_int_ena_6[12] - (RW) MAC interrupt enable +* mac_int_ena_7[13] - (RW) MAC interrupt enable +* mac_int_ena_8[14] - (RW) MAC interrupt enable +* mac_int_ena_9[15] - (RW) MAC interrupt enable +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_9_ADDR \ + WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_9_MASK \ + 0x00008000 /* mac_int_ena_9[15] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_9_SHFT 15 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_8_ADDR \ + WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_8_MASK \ + 0x00004000 /* mac_int_ena_8[14] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_8_SHFT 14 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_7_ADDR \ + WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_7_MASK \ + 0x00002000 /* mac_int_ena_7[13] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_7_SHFT 13 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_6_ADDR \ + WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_6_MASK \ + 0x00001000 /* mac_int_ena_6[12] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_6_SHFT 12 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_5_ADDR \ + WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_5_MASK \ + 0x00000800 /* mac_int_ena_5[11] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_5_SHFT 11 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_dmashdl_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_dmashdl_int_ena_MASK \ + 0x00000400 /* dmashdl_int_ena[10] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_dmashdl_int_ena_SHFT 10 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_conn2ap_sw_irq_ena_ADDR \ + WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_conn2ap_sw_irq_ena_MASK \ + 0x00000200 /* conn2ap_sw_irq_ena[9] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_conn2ap_sw_irq_ena_SHFT 9 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_conn_hif_on_host_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_conn_hif_on_host_int_ena_MASK \ + 0x00000100 /* conn_hif_on_host_int_ena[8] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_conn_hif_on_host_int_ena_SHFT 8 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_4_ADDR \ + WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_4_MASK \ + 0x00000010 /* mac_int_ena_4[4] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_4_SHFT 4 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_3_ADDR \ + WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_3_MASK \ + 0x00000008 /* mac_int_ena_3[3] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_3_SHFT 3 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_2_ADDR \ + WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_2_MASK \ + 0x00000004 /* mac_int_ena_2[2] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_2_SHFT 2 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_1_ADDR \ + WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_1_MASK \ + 0x00000002 /* mac_int_ena_1[1] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_1_SHFT 1 +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_0_ADDR \ + WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_0_MASK \ + 0x00000001 /* mac_int_ena_0[0] */ +#define WF_WFDMA_HOST_DMA0_SUBSYS2HOST_INT_ENA_mac_int_ena_0_SHFT 0 + +/* +* ---HOST_INT_STA (0x18024000 + 0x200)--- +* rx_done_int_sts_0[0] - (W1C) RX Queue#0 packet receive interrupt +* Write 1 to clear the interrupt +* Read to get the raw interrupt status +* rx_done_int_sts_1[1] - (W1C) RX Queue#1 packet receive interrupt +* Write 1 to clear the interrupt +* Read to get the raw interrupt status +* rx_done_int_sts_2[2] - (W1C) RX Queue#2 packet receive interrupt +* Write 1 to clear the interrupt +* Read to get the raw interrupt status +* rx_done_int_sts_3[3] - (W1C) RX Queue#3 packet receive interrupt +* Write 1 to clear the interrupt +* Read to get the raw interrupt status +* tx_done_int_sts_0[4] - (W1C) TX Queue#0 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_1[5] - (W1C) TX Queue#1 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_2[6] - (W1C) TX Queue#2 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_3[7] - (W1C) TX Queue#3 packet transmit interrupt +* Write 1 to clear the interrupt +* RESERVED8[18..8] - (RO) Reserved bits +* rx_done_int_sts_6[19] - (W1C) RX Queue#6 packet receive interrupt +* Write 1 to clear the interrupt Read to get the raw interrupt status +* rx_coherent_int_sts[20] - (W1C) RX_DMA finds data coherent event when +* checking ddone bit +* Write 1 to clear the interrupt +* Read to get the raw interrupt status +* tx_coherent_int_sts[21] - (W1C) TX_DMA finds data coherent event when +* checking ddone bit +* Write 1 to clear the interrupt +* Read to get the raw interrupt status +* rx_done_int_sts_4[22] - (W1C) RX Queue#4 packet receive interrupt +* Write 1 to clear the interrupt Read to get the raw interrupt status +* rx_done_int_sts_5[23] - (W1C) RX Queue#5 packet receive interrupt +* Write 1 to clear the interrupt Read to get the raw interrupt status +* wpdma2host_err_int_sts[24] - (RO) wpdma interrupt overall status +* User should should check WPDMA_ERR_INT_STA +* for each wpdma error interrupt status +* Host could read [0x0_41E8] to check +* indivisual wpdma2host_error interrupt status +* rx_done_int_sts_7[25] - (W1C) RX Queue#7 packet receive interrupt +* Write 1 to clear the interrupt Read to get the raw interrupt status +* RESERVED26[27..26] - (RO) Reserved bits +* subsys_int_sts[28] - (RO) subsys interrupt overall status +* User should should check +* SUBSYS2HOST_INT_STA for each interrupt status +* Host could read [0x0_41F8] to check +* indivisual subsys hw interrupt status +* mcu2host_sw_int_sts[29] - (RO) subsys interrupt overall status +* User should should check +* SUBSYS2HOST_INT_STA for each interrupt status +* Host could read [0x0_41F8] to check +* indivisual subsys hw interrupt status +* RESERVED30[31..30] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_mcu2host_sw_int_sts_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_mcu2host_sw_int_sts_MASK \ + 0x20000000 /* mcu2host_sw_int_sts[29] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_mcu2host_sw_int_sts_SHFT 29 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_subsys_int_sts_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_subsys_int_sts_MASK \ + 0x10000000 /* subsys_int_sts[28] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_subsys_int_sts_SHFT 28 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_7_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_7_MASK \ + 0x02000000 /* rx_done_int_sts_7[25] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_7_SHFT 25 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_wpdma2host_err_int_sts_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_wpdma2host_err_int_sts_MASK \ + 0x01000000 /* wpdma2host_err_int_sts[24] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_wpdma2host_err_int_sts_SHFT 24 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_5_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_5_MASK \ + 0x00800000 /* rx_done_int_sts_5[23] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_5_SHFT 23 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_4_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_4_MASK \ + 0x00400000 /* rx_done_int_sts_4[22] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_4_SHFT 22 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_coherent_int_sts_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_coherent_int_sts_MASK \ + 0x00200000 /* tx_coherent_int_sts[21] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_coherent_int_sts_SHFT 21 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_coherent_int_sts_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_coherent_int_sts_MASK \ + 0x00100000 /* rx_coherent_int_sts[20] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_coherent_int_sts_SHFT 20 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_6_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_6_MASK \ + 0x00080000 /* rx_done_int_sts_6[19] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_6_SHFT 19 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_3_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_3_MASK \ + 0x00000080 /* tx_done_int_sts_3[7] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_3_SHFT 7 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_2_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_2_MASK \ + 0x00000040 /* tx_done_int_sts_2[6] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_2_SHFT 6 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_1_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_1_MASK \ + 0x00000020 /* tx_done_int_sts_1[5] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_1_SHFT 5 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_0_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_0_MASK \ + 0x00000010 /* tx_done_int_sts_0[4] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_tx_done_int_sts_0_SHFT 4 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_3_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_3_MASK \ + 0x00000008 /* rx_done_int_sts_3[3] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_3_SHFT 3 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_2_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_2_MASK \ + 0x00000004 /* rx_done_int_sts_2[2] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_2_SHFT 2 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_1_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_1_MASK \ + 0x00000002 /* rx_done_int_sts_1[1] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_1_SHFT 1 +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_0_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_0_MASK \ + 0x00000001 /* rx_done_int_sts_0[0] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_rx_done_int_sts_0_SHFT 0 + +/* +* ---HOST_INT_ENA (0x18024000 + 0X204)--- +* HOST_RX_DONE_INT_ENA0[0] - (RW) RX Queue#0 packet receive interrupt +* HOST_RX_DONE_INT_ENA1[1] - (RW) RX Queue#1 packet receive interrupt +* HOST_RX_DONE_INT_ENA2[2] - (RW) RX Queue#2 packet receive interrupt +* HOST_RX_DONE_INT_ENA3[3] - (RW) RX Queue#3 packet receive interrupt +* HOST_TX_DONE_INT_ENA0[4] - (RW) TX Queue#0 packet transmit interrupt +* HOST_TX_DONE_INT_ENA1[5] - (RW) TX Queue#1 packet transmit interrupt +* HOST_TX_DONE_INT_ENA2[6] - (RW) TX Queue#2 packet transmit interrupt +* HOST_TX_DONE_INT_ENA3[7] - (RW) TX Queue#3 packet transmit interrupt +* RESERVED8[18..8] - (RO) Reserved bits +* HOST_RX_DONE_INT_ENA6[19] - (RW) RX Queue#6 packet receive interrupt +* HOST_RX_COHERENT_EN[20] - (RW) Enable for RX_DMA data coherent +interrupt +* HOST_TX_COHERENT_EN[21] - (RW) Enable for TX_DMA data coherent +interrupt +* HOST_RX_DONE_INT_ENA4[22] - (RW) RX Queue#4 packet receive interrupt +* HOST_RX_DONE_INT_ENA5[23] - (RW) RX Queue#5 packet receive interrupt +* wpdma2host_err_int_ena[24] - (RW) Enable bit of wpdma2host_err_int +* HOST_RX_DONE_INT_ENA7[25] - (RW) RX Queue#7 packet receive interrupt +* RESERVED26[27..26] - (RO) Reserved bits +* subsys_int_ena[28] - (RW) Enable bit of subsys_int +* mcu2host_sw_int_ena[29] - (RW) Enable bit of mcu2host_sw_int +* RESERVED30[31..30] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_mcu2host_sw_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_mcu2host_sw_int_ena_MASK \ + 0x20000000 /* mcu2host_sw_int_ena[29] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_mcu2host_sw_int_ena_SHFT 29 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_subsys_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_subsys_int_ena_MASK \ + 0x10000000 /* subsys_int_ena[28] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_subsys_int_ena_SHFT 28 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA7_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA7_MASK \ + 0x02000000 /* HOST_RX_DONE_INT_ENA7[25] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA7_SHFT 25 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_wpdma2host_err_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_wpdma2host_err_int_ena_MASK \ + 0x01000000 /* wpdma2host_err_int_ena[24] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_wpdma2host_err_int_ena_SHFT 24 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA5_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA5_MASK \ + 0x00800000 /* HOST_RX_DONE_INT_ENA5[23] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA5_SHFT 23 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA4_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA4_MASK \ + 0x00400000 /* HOST_RX_DONE_INT_ENA4[22] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA4_SHFT 22 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_COHERENT_EN_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_COHERENT_EN_MASK \ + 0x00200000 /* HOST_TX_COHERENT_EN[21] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_COHERENT_EN_SHFT 21 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_COHERENT_EN_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_COHERENT_EN_MASK \ + 0x00100000 /* HOST_RX_COHERENT_EN[20] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_COHERENT_EN_SHFT 20 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA6_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA6_MASK \ + 0x00080000 /* HOST_RX_DONE_INT_ENA6[19] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA6_SHFT 19 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA3_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA3_MASK \ + 0x00000080 /* HOST_TX_DONE_INT_ENA3[7] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA3_SHFT 7 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA2_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA2_MASK \ + 0x00000040 /* HOST_TX_DONE_INT_ENA2[6] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA2_SHFT 6 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA1_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA1_MASK \ + 0x00000020 /* HOST_TX_DONE_INT_ENA1[5] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA1_SHFT 5 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA0_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA0_MASK \ + 0x00000010 /* HOST_TX_DONE_INT_ENA0[4] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_TX_DONE_INT_ENA0_SHFT 4 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA3_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA3_MASK \ + 0x00000008 /* HOST_RX_DONE_INT_ENA3[3] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA3_SHFT 3 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA2_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA2_MASK \ + 0x00000004 /* HOST_RX_DONE_INT_ENA2[2] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA2_SHFT 2 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA1_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA1_MASK \ + 0x00000002 /* HOST_RX_DONE_INT_ENA1[1] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA1_SHFT 1 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA0_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA0_MASK \ + 0x00000001 /* HOST_RX_DONE_INT_ENA0[0] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_HOST_RX_DONE_INT_ENA0_SHFT 0 + +/* +* ---WPDMA_GLO_CFG (0x18024000 + 0x208)--- +* TX_DMA_EN[0] - (RW) TX_DMA Enable +* 1: Enable TX_DMA, MUST wait until all +* prefetch rings' MAX_CNT(WPDMA_T(R)X_RING*_EXT_CTRL) of DMA including neighbor +* DMA have been configured successfully +* 0: Disable TX_DMA +* TX_DMA_BUSY[1] - (RO) TX_DMA Busy indicator +* 1: TX_DMA is busy +* 0: TX_DMA is not busy +* RX_DMA_EN[2] - (RW) RX_DMA Enable +* 1: Enable RX_DMA, MUST wait until all +* prefetch rings' MAX_CNT(WPDMA_T(R)X_RING*_EXT_CTRL) of DMA including neighbor +* DMA have been configured successfully +* 0: Disable RX_DMA +* RX_DMA_BUSY[3] - (RO) RX_DMA Busy indicator +* 1: RX_DMA is busy +* 0: RX_DMA is not busy +* PDMA_BT_SIZE[5..4] - (RW) Define the burst size of WPDMA +* 2'h0 : 4 DWORD (16bytes) +* 2'h1 : 8 DWORD (32 bytes) +* 2'h2 : 16 DWORD (64 bytes) +* 2'h3 : 32 DWORD (128 bytes) +* TX_WB_DDONE[6] - (RW) 1'b1 : TX engine will wait to assert IRQ +* util whole TX dmad has been fully written into AXI bus which represents HOST +* memory, 1'b0 : TX engine will assert IRQ once TX dmad write-back request have +* been ACKed +* BIG_ENDIAN[7] - (RW) The endian mode selection. DMA applies +* the endian rule to convert payload and TX/RX information. DMA won't apply +* endian rule to register or descriptor. +* 1: big endian. +* 0: little endian. +* DMAD_32B_EN[8] - (RW) DMA Descriptor 32-byte Enable +* 0: The size of descriptors is set to 16-byte +* 1: The size of descriptors is set to 32-byte +* FW_DWLD_Bypass_dmashdl[9] - (RW) No USE for (APSOC/PCIE) +* For firmware download packet, driver shold using tx-ring16 to download packet +* and set this bit to bypass dmashdl resource control. +* After firmware download finish, driver should clear this bit. +* After all, tx-ring16 could be used for normal data operation. +(USB) +* For USB test_mode, user could set this bit to bypass dmashdl with all endpoint +* CSR_WFDMA_DUMMY_REG[10] - (RW) dummy CR for use if ECO needed +* CSR_AXI_BUFRDY_BYP[11] - (RW) to disable read data fifo available +* checking before issuing next AXI read request +* FIFO_LITTLE_ENDIAN[12] - (RW) Determines the endianness of the FIFO side +* 0: Big-endian +* 1: Little-endian +* CSR_RX_WB_DDONE[13] - (RW) 1'b1 : RX engine will wait to assert IRQ +* util whole RX dmad has been fully written into AXI bus which represents HOST +* memory, 1'b0 : RX engine will assert IRQ once RX dmad write-back request have +* been ACKed +* CSR_PP_HIF_TXP_ACTIVE_EN[14] - (RW) 1'b1 : enable legacy pp_hif_txp_active +* function to lock tx engine for favor TXP transmit requested directly from PP, +* other pdma TX rings request will be masked until pp_hif_txp_active is +deasserted +* 1'b0 : disable legacy pp_hif_txp_active function, use latest TX source QoS +* design to change throttler settings to favor TXP transmit! +* CSR_DISP_BASE_PTR_CHAIN_EN[15] - (RW) Enable prefet sram ring address +* arrangement by hardware chain structure(DMA#N TX ring group -> DMA#N RX ring +* group -> DMA#M TX ring group -> DMA#M RX ring group and son on). If not +* enabled, firmware need to program DISP_BASE_PTR of WPDMA_T(R)X_RING*_EXT_CTRL +instead!! +*CSR_LBK_RX_Q_SEL[18..16] - (RW) loopback data from TXFIFO will be direct to +* this RX ring when CSR_LBK_RX_Q_SEL_EN in loopback mode, valid bit-width is +* equal to RX_RING_WIDTH which can be calculated from WPDMA_INFO 0x284[15:8] +RX_RING_NUMBER +* RESERVED19[19] - (RO) Reserved bits +* CSR_LBK_RX_Q_SEL_EN[20] - (RW) Force configured CSR_LBK_RX_Q_SEL to +* receive loopback data from TXFIFO +* RESERVED21[23..21] - (RO) Reserved bits +* CSR_SW_RST[24] - (RO) SW reset all designs (To be tested for SER in the +future) +* FORCE_TX_EOF[25] - (RW) Force to send an eof after PDMA being reset (for +Packet_Processor) +* 0: Disabled +* 1: Enabled +* PDMA_ADDR_EXT_EN[26] - (RW) No Fnction for now!! For PDMA Address 32bits +* extension. When this design option was enable. PDMA would change Tx/Rx +* descriptor format for address extension. +* 0 : PDMA 32bits address +* 1 : PDMA Tx descirptor DW3 (TXINFO) would used to extend address +* PDMA Rx descirpt DW2 (Reserved) would used to extend address. +* OMIT_RX_INFO[27] - (RW) For loopback mode, set to 1'b1. +* For normal wifi data operation. User should not set this option and should +* keep 1'b0 because UMAC will always add extra QW for checksum after received +* packet's laster QW +* VERY IMPORTANT : for cpu_dma0/1 where CR +* resides in 0x5100_0xxx, OMIT_RX_INFO MUST be set to 1'b1 +* Omit rx_info of all RX packets +* 0: All the PX packets should end with a rx_info +* 1: All the PX packets should NOT end with a rx_info but an eof +* OMIT_TX_INFO[28] - (RW) For loopback mode, set to 1'b1. +* For normal wifi data operation. User should +* set this option to +* Omit tx_info of all TX packets because UMAC +* design not support TXINFO +* 0: The tx_info in DMAD will be sent at the beginning +* 1: The tx_info in DMAD will NOT be sent at the beginning +* BYTE_SWAP[29] - (RW) Byte Swapping for TX/RX DMAD +* 0: Not to swap (Endian of DMAD unchanged) +* 1: Swap (Endian of DMAD reversed) +* CLK_GATE_DIS[30] - (RW) PDMA Clock Gated Function Disable +* 0: normal function +* 1: disable clock gated function +* RX_2B_OFFSET[31] - (RW) RX PBF 2-byte Offset +* 1: Skip the first two bytes of the RX PBF +* 0: Not to skip the first two bytes of the +* RX PBF +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_RX_2B_OFFSET_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_RX_2B_OFFSET_MASK \ + 0x80000000 /* RX_2B_OFFSET[31] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_RX_2B_OFFSET_SHFT 31 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CLK_GATE_DIS_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CLK_GATE_DIS_MASK \ + 0x40000000 /* CLK_GATE_DIS[30] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CLK_GATE_DIS_SHFT 30 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_BYTE_SWAP_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_BYTE_SWAP_MASK \ + 0x20000000 /* BYTE_SWAP[29] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_BYTE_SWAP_SHFT 29 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_OMIT_TX_INFO_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_OMIT_TX_INFO_MASK \ + 0x10000000 /* OMIT_TX_INFO[28] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_OMIT_TX_INFO_SHFT 28 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_OMIT_RX_INFO_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_OMIT_RX_INFO_MASK \ + 0x08000000 /* OMIT_RX_INFO[27] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_OMIT_RX_INFO_SHFT 27 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_PDMA_ADDR_EXT_EN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_PDMA_ADDR_EXT_EN_MASK \ + 0x04000000 /* PDMA_ADDR_EXT_EN[26] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_PDMA_ADDR_EXT_EN_SHFT 26 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_FORCE_TX_EOF_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_FORCE_TX_EOF_MASK \ + 0x02000000 /* FORCE_TX_EOF[25] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_FORCE_TX_EOF_SHFT 25 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_SW_RST_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_SW_RST_MASK \ + 0x01000000 /* CSR_SW_RST[24] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_SW_RST_SHFT 24 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_LBK_RX_Q_SEL_EN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_LBK_RX_Q_SEL_EN_MASK \ + 0x00100000 /* CSR_LBK_RX_Q_SEL_EN[20] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_LBK_RX_Q_SEL_EN_SHFT 20 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_LBK_RX_Q_SEL_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_LBK_RX_Q_SEL_MASK \ + 0x00070000 /* CSR_LBK_RX_Q_SEL[18..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_LBK_RX_Q_SEL_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN_MASK \ + 0x00008000 /* CSR_DISP_BASE_PTR_CHAIN_EN[15] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN_SHFT 15 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_PP_HIF_TXP_ACTIVE_EN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_PP_HIF_TXP_ACTIVE_EN_MASK \ + 0x00004000 /* CSR_PP_HIF_TXP_ACTIVE_EN[14] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_PP_HIF_TXP_ACTIVE_EN_SHFT 14 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_RX_WB_DDONE_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_RX_WB_DDONE_MASK \ + 0x00002000 /* CSR_RX_WB_DDONE[13] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_RX_WB_DDONE_SHFT 13 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_FIFO_LITTLE_ENDIAN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_FIFO_LITTLE_ENDIAN_MASK \ + 0x00001000 /* FIFO_LITTLE_ENDIAN[12] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_FIFO_LITTLE_ENDIAN_SHFT 12 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_AXI_BUFRDY_BYP_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_AXI_BUFRDY_BYP_MASK \ + 0x00000800 /* CSR_AXI_BUFRDY_BYP[11] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_AXI_BUFRDY_BYP_SHFT 11 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_WFDMA_DUMMY_REG_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_WFDMA_DUMMY_REG_MASK \ + 0x00000400 /* CSR_WFDMA_DUMMY_REG[10] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_CSR_WFDMA_DUMMY_REG_SHFT 10 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_FW_DWLD_Bypass_dmashdl_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_FW_DWLD_Bypass_dmashdl_MASK \ + 0x00000200 /* FW_DWLD_Bypass_dmashdl[9] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_FW_DWLD_Bypass_dmashdl_SHFT 9 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_DMAD_32B_EN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_DMAD_32B_EN_MASK \ + 0x00000100 /* DMAD_32B_EN[8] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_DMAD_32B_EN_SHFT 8 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_BIG_ENDIAN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_BIG_ENDIAN_MASK \ + 0x00000080 /* BIG_ENDIAN[7] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_BIG_ENDIAN_SHFT 7 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_TX_WB_DDONE_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_TX_WB_DDONE_MASK \ + 0x00000040 /* TX_WB_DDONE[6] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_TX_WB_DDONE_SHFT 6 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_PDMA_BT_SIZE_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_PDMA_BT_SIZE_MASK \ + 0x00000030 /* PDMA_BT_SIZE[5..4] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_PDMA_BT_SIZE_SHFT 4 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_RX_DMA_BUSY_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_RX_DMA_BUSY_MASK \ + 0x00000008 /* RX_DMA_BUSY[3] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_RX_DMA_BUSY_SHFT 3 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_RX_DMA_EN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_RX_DMA_EN_MASK \ + 0x00000004 /* RX_DMA_EN[2] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_RX_DMA_EN_SHFT 2 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_TX_DMA_BUSY_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_TX_DMA_BUSY_MASK \ + 0x00000002 /* TX_DMA_BUSY[1] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_TX_DMA_BUSY_SHFT 1 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_TX_DMA_EN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_TX_DMA_EN_MASK \ + 0x00000001 /* TX_DMA_EN[0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_TX_DMA_EN_SHFT 0 + +/* +* ---WPDMA_RST_DTX_PTR (0x18024000 + 0x20C)--- +* RST_DTX_IDX0[0] - (WO) Write 1 to reset to TX_DMATX_IDX0 to 0 +* RST_DTX_IDX1[1] - (WO) Write 1 to reset to TX_DMATX_IDX1 to 0 +* RST_DTX_IDX2[2] - (WO) Write 1 to reset to TX_DMATX_IDX2 to 0 +* RST_DTX_IDX3[3] - (WO) Write 1 to reset to TX_DMATX_IDX3 to 0 +* RESERVED[31..4] - (WO) Reserved +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX3_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX3_MASK \ + 0x00000008 /* RST_DTX_IDX3[3] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX3_SHFT 3 +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX2_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX2_MASK \ + 0x00000004 /* RST_DTX_IDX2[2] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX2_SHFT 2 +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX1_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX1_MASK \ + 0x00000002 /* RST_DTX_IDX1[1] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX1_SHFT 1 +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX0_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX0_MASK \ + 0x00000001 /* RST_DTX_IDX0[0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DTX_PTR_RST_DTX_IDX0_SHFT 0 + +/* +* ---WPDMA_PAUSE_TX_Q (0x18024000 + 0x224)--- +* TX_Q_PAUSE[3..0] - (RW) Pause signal for each TX ring (16 bits +* for 16 rings) +* Set 0: Normal function; Set 1: The +* corresponding TX ring is paused +* RESERVED4[31..4] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_TX_Q_TX_Q_PAUSE_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_TX_Q_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_TX_Q_TX_Q_PAUSE_MASK \ + 0x0000000F /* TX_Q_PAUSE[3..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_TX_Q_TX_Q_PAUSE_SHFT 0 + +/* +* ---HOST_INT_ENA_SET (0x18024000 + 0X228)--- +* HOST_RX_DONE_INT_ENA0[0] - (W1S) RX Queue#0 packet receive interrupt +* HOST_RX_DONE_INT_ENA1[1] - (W1S) RX Queue#1 packet receive interrupt +* HOST_RX_DONE_INT_ENA2[2] - (W1S) RX Queue#2 packet receive interrupt +* HOST_RX_DONE_INT_ENA3[3] - (W1S) RX Queue#3 packet receive interrupt +* HOST_TX_DONE_INT_ENA0[4] - (W1S) TX Queue#0 packet transmit interrupt +* HOST_TX_DONE_INT_ENA1[5] - (W1S) TX Queue#1 packet transmit interrupt +* HOST_TX_DONE_INT_ENA2[6] - (W1S) TX Queue#2 packet transmit interrupt +* HOST_TX_DONE_INT_ENA3[7] - (W1S) TX Queue#3 packet transmit interrupt +* RESERVED8[18..8] - (RO) Reserved bits +* HOST_RX_DONE_INT_ENA6[19] - (W1S) RX Queue#6 packet receive interrupt +* HOST_RX_COHERENT_EN[20] - (W1S) Enable for RX_DMA data coherent +interrupt +* HOST_TX_COHERENT_EN[21] - (W1S) Enable for TX_DMA data coherent +interrupt +* HOST_RX_DONE_INT_ENA4[22] - (W1S) RX Queue#4 packet receive interrupt +* HOST_RX_DONE_INT_ENA5[23] - (W1S) RX Queue#5 packet receive interrupt +* wpdma2host_err_int_ena[24] - (W1S) Enable bit of wpdma2host_err_int +* HOST_RX_DONE_INT_ENA7[25] - (W1S) RX Queue#7 packet receive interrupt +* RESERVED26[27..26] - (RO) Reserved bits +* subsys_int_ena[28] - (W1S) Enable bit of subsys_int +* mcu2host_sw_int_ena[29] - (W1S) Enable bit of mcu2host_sw_int +* RESERVED30[31..30] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_mcu2host_sw_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_mcu2host_sw_int_ena_MASK \ + 0x20000000 /* mcu2host_sw_int_ena[29] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_mcu2host_sw_int_ena_SHFT 29 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_subsys_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_subsys_int_ena_MASK \ + 0x10000000 /* subsys_int_ena[28] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_subsys_int_ena_SHFT 28 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA7_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA7_MASK \ + 0x02000000 /* HOST_RX_DONE_INT_ENA7[25] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA7_SHFT 25 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_wpdma2host_err_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_wpdma2host_err_int_ena_MASK \ + 0x01000000 /* wpdma2host_err_int_ena[24] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_wpdma2host_err_int_ena_SHFT 24 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA5_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA5_MASK \ + 0x00800000 /* HOST_RX_DONE_INT_ENA5[23] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA5_SHFT 23 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA4_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA4_MASK \ + 0x00400000 /* HOST_RX_DONE_INT_ENA4[22] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA4_SHFT 22 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_COHERENT_EN_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_COHERENT_EN_MASK \ + 0x00200000 /* HOST_TX_COHERENT_EN[21] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_COHERENT_EN_SHFT 21 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_COHERENT_EN_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_COHERENT_EN_MASK \ + 0x00100000 /* HOST_RX_COHERENT_EN[20] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_COHERENT_EN_SHFT 20 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA6_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA6_MASK \ + 0x00080000 /* HOST_RX_DONE_INT_ENA6[19] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA6_SHFT 19 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA3_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA3_MASK \ + 0x00000080 /* HOST_TX_DONE_INT_ENA3[7] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA3_SHFT 7 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA2_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA2_MASK \ + 0x00000040 /* HOST_TX_DONE_INT_ENA2[6] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA2_SHFT 6 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA1_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA1_MASK \ + 0x00000020 /* HOST_TX_DONE_INT_ENA1[5] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA1_SHFT 5 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA0_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA0_MASK \ + 0x00000010 /* HOST_TX_DONE_INT_ENA0[4] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA0_SHFT 4 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA3_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA3_MASK \ + 0x00000008 /* HOST_RX_DONE_INT_ENA3[3] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA3_SHFT 3 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA2_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA2_MASK \ + 0x00000004 /* HOST_RX_DONE_INT_ENA2[2] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA2_SHFT 2 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA1_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA1_MASK \ + 0x00000002 /* HOST_RX_DONE_INT_ENA1[1] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA1_SHFT 1 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA0_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA0_MASK \ + 0x00000001 /* HOST_RX_DONE_INT_ENA0[0] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA0_SHFT 0 + +/* +* ---HOST_INT_ENA_CLR (0x18024000 + 0X22C)--- +* HOST_RX_DONE_INT_ENA0[0] - (W1C) RX Queue#0 packet receive interrupt +* HOST_RX_DONE_INT_ENA1[1] - (W1C) RX Queue#1 packet receive interrupt +* HOST_RX_DONE_INT_ENA2[2] - (W1C) RX Queue#2 packet receive interrupt +* HOST_RX_DONE_INT_ENA3[3] - (W1C) RX Queue#3 packet receive interrupt +* HOST_TX_DONE_INT_ENA0[4] - (W1C) TX Queue#0 packet transmit interrupt +* HOST_TX_DONE_INT_ENA1[5] - (W1C) TX Queue#1 packet transmit interrupt +* HOST_TX_DONE_INT_ENA2[6] - (W1C) TX Queue#2 packet transmit interrupt +* HOST_TX_DONE_INT_ENA3[7] - (W1C) TX Queue#3 packet transmit interrupt +* RESERVED8[18..8] - (RO) Reserved bits +* HOST_RX_DONE_INT_ENA6[19] - (W1C) RX Queue#6 packet receive interrupt +* HOST_RX_COHERENT_EN[20] - (W1C) Enable for RX_DMA data coherent +interrupt +* HOST_TX_COHERENT_EN[21] - (W1C) Enable for TX_DMA data coherent +interrupt +* HOST_RX_DONE_INT_ENA4[22] - (W1C) RX Queue#4 packet receive interrupt +* HOST_RX_DONE_INT_ENA5[23] - (W1C) RX Queue#5 packet receive interrupt +* wpdma2host_err_int_ena[24] - (W1C) Enable bit of wpdma2host_err_int +* HOST_RX_DONE_INT_ENA7[25] - (W1C) RX Queue#7 packet receive interrupt +* RESERVED26[27..26] - (RO) Reserved bits +* subsys_int_ena[28] - (W1C) Enable bit of subsys_int +* mcu2host_sw_int_ena[29] - (W1C) Enable bit of mcu2host_sw_int +* RESERVED30[31..30] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_mcu2host_sw_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_mcu2host_sw_int_ena_MASK \ + 0x20000000 /* mcu2host_sw_int_ena[29] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_mcu2host_sw_int_ena_SHFT 29 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_subsys_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_subsys_int_ena_MASK \ + 0x10000000 /* subsys_int_ena[28] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_subsys_int_ena_SHFT 28 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA7_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA7_MASK \ + 0x02000000 /* HOST_RX_DONE_INT_ENA7[25] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA7_SHFT 25 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_wpdma2host_err_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_wpdma2host_err_int_ena_MASK \ + 0x01000000 /* wpdma2host_err_int_ena[24] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_wpdma2host_err_int_ena_SHFT 24 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA5_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA5_MASK \ + 0x00800000 /* HOST_RX_DONE_INT_ENA5[23] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA5_SHFT 23 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA4_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA4_MASK \ + 0x00400000 /* HOST_RX_DONE_INT_ENA4[22] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA4_SHFT 22 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_COHERENT_EN_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_COHERENT_EN_MASK \ + 0x00200000 /* HOST_TX_COHERENT_EN[21] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_COHERENT_EN_SHFT 21 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_COHERENT_EN_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_COHERENT_EN_MASK \ + 0x00100000 /* HOST_RX_COHERENT_EN[20] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_COHERENT_EN_SHFT 20 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA6_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA6_MASK \ + 0x00080000 /* HOST_RX_DONE_INT_ENA6[19] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA6_SHFT 19 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA3_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA3_MASK \ + 0x00000080 /* HOST_TX_DONE_INT_ENA3[7] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA3_SHFT 7 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA2_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA2_MASK \ + 0x00000040 /* HOST_TX_DONE_INT_ENA2[6] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA2_SHFT 6 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA1_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA1_MASK \ + 0x00000020 /* HOST_TX_DONE_INT_ENA1[5] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA1_SHFT 5 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA0_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA0_MASK \ + 0x00000010 /* HOST_TX_DONE_INT_ENA0[4] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA0_SHFT 4 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA3_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA3_MASK \ + 0x00000008 /* HOST_RX_DONE_INT_ENA3[3] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA3_SHFT 3 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA2_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA2_MASK \ + 0x00000004 /* HOST_RX_DONE_INT_ENA2[2] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA2_SHFT 2 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA1_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA1_MASK \ + 0x00000002 /* HOST_RX_DONE_INT_ENA1[1] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA1_SHFT 1 +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA0_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA0_MASK \ + 0x00000001 /* HOST_RX_DONE_INT_ENA0[0] */ +#define WF_WFDMA_HOST_DMA0_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA0_SHFT 0 + +/* +* ---WPDMA_TIMEOUT_CFG (0x18024000 + 0x230)--- +* WPDMA_TX_TIMEOUT_TH[7..0] - (RW) xxx +* WPDMA_TX_TIMEOUT_TICK[14..8] - (RW) xxx +* WPDMA_TX_TIMEOUT_ENA[15] - (RW) xxx +* WPDMA_RX_TIMEOUT_TH[23..16] - (RW) xxx +* WPDMA_RX_TIMEOUT_TICK[30..24] - (RW) xxx +* WPDMA_RX_TIMEOUT_ENA[31] - (RW) xxx +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_ENA_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_ENA_MASK \ + 0x80000000 /* WPDMA_RX_TIMEOUT_ENA[31] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_ENA_SHFT 31 +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_TICK_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_TICK_MASK \ + 0x7F000000 /* WPDMA_RX_TIMEOUT_TICK[30..24] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_TICK_SHFT 24 +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_TH_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_TH_MASK \ + 0x00FF0000 /* WPDMA_RX_TIMEOUT_TH[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_TH_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_ENA_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_ENA_MASK \ + 0x00008000 /* WPDMA_TX_TIMEOUT_ENA[15] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_ENA_SHFT 15 +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_TICK_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_TICK_MASK \ + 0x00007F00 /* WPDMA_TX_TIMEOUT_TICK[14..8] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_TICK_SHFT 8 +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_TH_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_TH_MASK \ + 0x000000FF /* WPDMA_TX_TIMEOUT_TH[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_TH_SHFT 0 + +/* +* ---WPDMA_MISC_CFG (0x18024000 + 0x234)--- +* WPDMA_TX_TIMEOUT_SEL[0] - (RW) xxx +* WPDMA_RX_TIMEOUT_SEL[1] - (RW) xxx +* WPDMA_RX_FREE_Q_TH[5..2] - (RW) When loopback, this will be used to +* generate correct tx_pause to avlid deadlock which caused from situration that +* tx_dma will start reading tx packet from memory without considering lack of RX +* dmad in prefetch sram and needing to read RX dmad from memory which tx dma is +* reading tx packet too and rready is deasserted due to txfifo full !! +* RX dmad in prefetch sram should be greater +* than RX_FREE_Q_TH for rx_dma to start writing received packet into memory!! +* RESERVED6[31..6] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_MISC_CFG_WPDMA_RX_FREE_Q_TH_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_MISC_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_MISC_CFG_WPDMA_RX_FREE_Q_TH_MASK \ + 0x0000003C /* WPDMA_RX_FREE_Q_TH[5..2] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_MISC_CFG_WPDMA_RX_FREE_Q_TH_SHFT 2 +#define WF_WFDMA_HOST_DMA0_WPDMA_MISC_CFG_WPDMA_RX_TIMEOUT_SEL_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_MISC_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_MISC_CFG_WPDMA_RX_TIMEOUT_SEL_MASK \ + 0x00000002 /* WPDMA_RX_TIMEOUT_SEL[1] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_MISC_CFG_WPDMA_RX_TIMEOUT_SEL_SHFT 1 +#define WF_WFDMA_HOST_DMA0_WPDMA_MISC_CFG_WPDMA_TX_TIMEOUT_SEL_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_MISC_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_MISC_CFG_WPDMA_TX_TIMEOUT_SEL_MASK \ + 0x00000001 /* WPDMA_TX_TIMEOUT_SEL[0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_MISC_CFG_WPDMA_TX_TIMEOUT_SEL_SHFT 0 + +/* +* ---WPDMA_TX_WRR_ARB_GBF0 (0x18024000 + 0x240)--- +* WRR_REQ0_ARB_GBF[2..0] - (RW) WRR REQ#0 priority level, mapped to +* lumpped request from TX ring0~ring15 for host TXD +* WRR_REQ1_ARB_GBF[5..3] - (RW) WRR REQ#1 priority level, mapped to +* request from TX ring16 when dual tx fifo for host event packet +* WRR_REQ2_ARB_GBF[8..6] - (RW) WRR REQ#2 priority level, mapped to +* request from TX ring17 when dual tx fifo for host event packet +* WRR_REQ3_ARB_GBF[11..9] - (RW) WRR REQ#3 priority level, mapped to +* request from TX ring18 when dual tx fifo for host event packet +* WRR_REQ4_ARB_GBF[14..12] - (RW) WRR REQ#4 priority level, mapped to +* request from TX ring19 when dual tx fifo for host event packet +* RESERVED[31..15] - (RW) Reserved +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ4_ARB_GBF_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ4_ARB_GBF_MASK \ + 0x00007000 /* WRR_REQ4_ARB_GBF[14..12] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ4_ARB_GBF_SHFT 12 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ3_ARB_GBF_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ3_ARB_GBF_MASK \ + 0x00000E00 /* WRR_REQ3_ARB_GBF[11..9] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ3_ARB_GBF_SHFT 9 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ2_ARB_GBF_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ2_ARB_GBF_MASK \ + 0x000001C0 /* WRR_REQ2_ARB_GBF[8..6] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ2_ARB_GBF_SHFT 6 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ1_ARB_GBF_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ1_ARB_GBF_MASK \ + 0x00000038 /* WRR_REQ1_ARB_GBF[5..3] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ1_ARB_GBF_SHFT 3 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ0_ARB_GBF_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ0_ARB_GBF_MASK \ + 0x00000007 /* WRR_REQ0_ARB_GBF[2..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ0_ARB_GBF_SHFT 0 + +/* +* ---MD_INT_STA (0x18024000 + 0x250)--- +* MCU2MD_SW_INT_STS[15..0] - (W1C) MCU to MD S/W interrupt indicator +* CONN_HIF_ON_MD_INT_STS[16] - (RO) MD driver own interrupt indicator +* RESERVED17[31..17] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_MD_INT_STA_CONN_HIF_ON_MD_INT_STS_ADDR \ + WF_WFDMA_HOST_DMA0_MD_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MD_INT_STA_CONN_HIF_ON_MD_INT_STS_MASK \ + 0x00010000 /* CONN_HIF_ON_MD_INT_STS[16] */ +#define WF_WFDMA_HOST_DMA0_MD_INT_STA_CONN_HIF_ON_MD_INT_STS_SHFT 16 +#define WF_WFDMA_HOST_DMA0_MD_INT_STA_MCU2MD_SW_INT_STS_ADDR \ + WF_WFDMA_HOST_DMA0_MD_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_MD_INT_STA_MCU2MD_SW_INT_STS_MASK \ + 0x0000FFFF /* MCU2MD_SW_INT_STS[15..0] */ +#define WF_WFDMA_HOST_DMA0_MD_INT_STA_MCU2MD_SW_INT_STS_SHFT 0 + +/* +* ---MD_INT_ENA (0x18024000 + 0x254)--- +* MCU2MD_SW_INT_ENA[15..0] - (RW) MCU to MD S/W interrupt enable +* CONN_HIF_ON_MD_INT_ENA[16] - (RW) MD driver own interrupt enable +* RESERVED17[31..17] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_MD_INT_ENA_CONN_HIF_ON_MD_INT_ENA_ADDR \ + WF_WFDMA_HOST_DMA0_MD_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MD_INT_ENA_CONN_HIF_ON_MD_INT_ENA_MASK \ + 0x00010000 /* CONN_HIF_ON_MD_INT_ENA[16] */ +#define WF_WFDMA_HOST_DMA0_MD_INT_ENA_CONN_HIF_ON_MD_INT_ENA_SHFT 16 +#define WF_WFDMA_HOST_DMA0_MD_INT_ENA_MCU2MD_SW_INT_ENA_ADDR \ + WF_WFDMA_HOST_DMA0_MD_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA0_MD_INT_ENA_MCU2MD_SW_INT_ENA_MASK \ + 0x0000FFFF /* MCU2MD_SW_INT_ENA[15..0] */ +#define WF_WFDMA_HOST_DMA0_MD_INT_ENA_MCU2MD_SW_INT_ENA_SHFT 0 + +/* +* ---MCU2MD_SW_INT_SET (0x18024000 + 0x258)--- +* MCU2MD_SW_INT_SET[15..0] - (RO) MCU to MD S/W interrupt set +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_MCU2MD_SW_INT_SET_MCU2MD_SW_INT_SET_ADDR \ + WF_WFDMA_HOST_DMA0_MCU2MD_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA0_MCU2MD_SW_INT_SET_MCU2MD_SW_INT_SET_MASK \ + 0x0000FFFF /* MCU2MD_SW_INT_SET[15..0] */ +#define WF_WFDMA_HOST_DMA0_MCU2MD_SW_INT_SET_MCU2MD_SW_INT_SET_SHFT 0 + +/* +* ---WPDMA_PAUSE_RX_Q_TH10 (0x18024000 + 0x260)--- +* RX_DMAD_TH0[11..0] - (RW) RX Ring0 DMAD threshold to pause PP +* sending packet to RX FIFO +* pause_rx_q = (available RX DMAD counts) < + +* RESERVED12[15..12] - (RO) Reserved bits +* RX_DMAD_TH1[27..16] - (RW) RX Ring1 DMAD threshold to pause PP +* sending packet to RX FIFO +* pause_rx_q = (available RX DMAD counts) < + +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH10_RX_DMAD_TH1_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH10_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH10_RX_DMAD_TH1_MASK \ + 0x0FFF0000 /* RX_DMAD_TH1[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH10_RX_DMAD_TH1_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH10_RX_DMAD_TH0_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH10_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH10_RX_DMAD_TH0_MASK \ + 0x00000FFF /* RX_DMAD_TH0[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH10_RX_DMAD_TH0_SHFT 0 + +/* +* ---WPDMA_PAUSE_RX_Q_TH32 (0x18024000 + 0x264)--- +* RX_DMAD_TH2[11..0] - (RW) RX Ring2 DMAD threshold to pause PP +* sending packet to RX FIFO +* pause_rx_q = (available RX DMAD counts) < + +* RESERVED12[15..12] - (RO) Reserved bits +* RX_DMAD_TH3[27..16] - (RW) RX Ring3 DMAD threshold to pause PP +* sending packet to RX FIFO +* pause_rx_q = (available RX DMAD counts) < + +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH32_RX_DMAD_TH3_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH32_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH32_RX_DMAD_TH3_MASK \ + 0x0FFF0000 /* RX_DMAD_TH3[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH32_RX_DMAD_TH3_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH32_RX_DMAD_TH2_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH32_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH32_RX_DMAD_TH2_MASK \ + 0x00000FFF /* RX_DMAD_TH2[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH32_RX_DMAD_TH2_SHFT 0 + +/* +* ---WPDMA_PAUSE_RX_Q_TH54 (0x18024000 + 0x268)--- +* RX_DMAD_TH4[11..0] - (RW) RX Ring4 DMAD threshold to pause PP +* sending packet to RX FIFO +* pause_rx_q = (available RX DMAD counts) < + +* RESERVED12[15..12] - (RO) Reserved bits +* RX_DMAD_TH5[27..16] - (RW) RX Ring5 DMAD threshold to pause PP +* sending packet to RX FIFO +* pause_rx_q = (available RX DMAD counts) < + +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH54_RX_DMAD_TH5_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH54_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH54_RX_DMAD_TH5_MASK \ + 0x0FFF0000 /* RX_DMAD_TH5[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH54_RX_DMAD_TH5_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH54_RX_DMAD_TH4_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH54_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH54_RX_DMAD_TH4_MASK \ + 0x00000FFF /* RX_DMAD_TH4[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH54_RX_DMAD_TH4_SHFT 0 + +/* +* ---WPDMA_PAUSE_RX_Q_TH76 (0x18024000 + 0x26C)--- +* RX_DMAD_TH6[11..0] - (RW) RX Ring6 DMAD threshold to pause PP +* sending packet to RX FIFO +* pause_rx_q = (available RX DMAD counts) < + +* RESERVED12[15..12] - (RO) Reserved bits +* RX_DMAD_TH7[27..16] - (RW) RX Ring7 DMAD threshold to pause PP +* sending packet to RX FIFO +* pause_rx_q = (available RX DMAD counts) < + +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH76_RX_DMAD_TH7_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH76_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH76_RX_DMAD_TH7_MASK \ + 0x0FFF0000 /* RX_DMAD_TH7[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH76_RX_DMAD_TH7_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH76_RX_DMAD_TH6_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH76_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH76_RX_DMAD_TH6_MASK \ + 0x00000FFF /* RX_DMAD_TH6[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PAUSE_RX_Q_TH76_RX_DMAD_TH6_SHFT 0 + +/* +* ---WPDMA_RST_DRX_PTR (0x18024000 + 0x280)--- +* RST_DRX_IDX0[0] - (WO) Write 1 to reset to RX_DMARX_IDX0 to 0 +* RST_DRX_IDX1[1] - (WO) Write 1 to reset to RX_DMARX_IDX1 to 0 +* RST_DRX_IDX2[2] - (WO) Write 1 to reset to RX_DMARX_IDX2 to 0 +* RST_DRX_IDX3[3] - (WO) Write 1 to reset to RX_DMARX_IDX3 to 0 +* RESERVED[31..4] - (WO) Reserved +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_RST_DRX_IDX3_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_RST_DRX_IDX3_MASK \ + 0x00000008 /* RST_DRX_IDX3[3] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_RST_DRX_IDX3_SHFT 3 +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_RST_DRX_IDX2_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_RST_DRX_IDX2_MASK \ + 0x00000004 /* RST_DRX_IDX2[2] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_RST_DRX_IDX2_SHFT 2 +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_RST_DRX_IDX1_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_RST_DRX_IDX1_MASK \ + 0x00000002 /* RST_DRX_IDX1[1] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_RST_DRX_IDX1_SHFT 1 +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_RST_DRX_IDX0_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_RST_DRX_IDX0_MASK \ + 0x00000001 /* RST_DRX_IDX0[0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RST_DRX_PTR_RST_DRX_IDX0_SHFT 0 + +/* +* ---WPDMA_INFO (0x18024000 + 0x284)--- +* TX_RING_NUMBER[7..0] - (RO) TX_RING_NUMBER +* RX_RING_NUMBER[15..8] - (RO) RX_RING_NUMBER +* BASE_PTR_WIDTH[23..16] - (RO) {2'h0, 6'd32-'BASE_PTR_WIDTH[5:0]} +* INDEX_WIDTH[27..24] - (RO) RING_INDEX_WIDTH +* PDMA_PREFETCH_SRAM_SIZE[30..28] - (RO) PDMA prefetch sram size{3'h0 : 128 +* byte, 3'h1 : 256 byte, 3'h2 : 512 byte, 3'h3 : 1KB, 3'h4 : 2KB, 3'h5 : 4KB, +* 3'h6 : 8KB, 3'h7 : reserved}, be noticed that prefetch sram is shared outside +* with other DMAs, please check all DMAs' total prefetch ring number and max_cnt +* for each prefetch ring to make sure that total size of all configured prefetch +* dmad of all DMAs' prefetch ring should be less than PDMA_PREFETCH_SRAM_SIZE +* WFDMA_PDA_EXIST[31] - (RO) Only cpu_dma1 will support pda functions +* for firmware download and wfdma_pda_top resides in between cpu_dma0 and +cpu_dma1! +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_WFDMA_PDA_EXIST_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_INFO_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_WFDMA_PDA_EXIST_MASK \ + 0x80000000 /* WFDMA_PDA_EXIST[31] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_WFDMA_PDA_EXIST_SHFT 31 +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_PDMA_PREFETCH_SRAM_SIZE_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_INFO_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_PDMA_PREFETCH_SRAM_SIZE_MASK \ + 0x70000000 /* PDMA_PREFETCH_SRAM_SIZE[30..28] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_PDMA_PREFETCH_SRAM_SIZE_SHFT 28 +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_INDEX_WIDTH_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_INFO_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_INDEX_WIDTH_MASK \ + 0x0F000000 /* INDEX_WIDTH[27..24] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_INDEX_WIDTH_SHFT 24 +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_BASE_PTR_WIDTH_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_INFO_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_BASE_PTR_WIDTH_MASK \ + 0x00FF0000 /* BASE_PTR_WIDTH[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_BASE_PTR_WIDTH_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_RX_RING_NUMBER_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_INFO_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_RX_RING_NUMBER_MASK \ + 0x0000FF00 /* RX_RING_NUMBER[15..8] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_RX_RING_NUMBER_SHFT 8 +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_TX_RING_NUMBER_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_INFO_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_TX_RING_NUMBER_MASK \ + 0x000000FF /* TX_RING_NUMBER[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_TX_RING_NUMBER_SHFT 0 + +/* +* ---WPDMA_INFO_EXT (0x18024000 + 0x288)--- +* TX_EVENT_RING_NUMBER[7..0] - (RO) When TX_EVENT_RING_NUMBER equal 8'h0, it +* means that this DMA doesn't support dual TX fifo, thus in default it only +* support TX_RING_NUMBER of TX rings !! +* But when TX_EVENT_RING_NUMBER NOT equal +* 8'h0, this dma is configured as dual TX fifo and +* TX_RING[16+TX_EVENT_RING_NUM-1:16] are for getting HOST EVENT packet from HOST +* to WX_CPU!! +* TX_DMAD_RING_NUMBER[15..8] - (RO) When TX_EVENT_RING_NUMBER not equal to +* 8'h0, it means that this DMA support dual TX fifo and TX +* ring[TX_DMAD_RING_NUMBER-1:0] are for getting TXD from HOST to UMAC!! +* RESERVED[30..16] - (RO) Reserved +* TX_DMASHDL_EXIST[31] - (RO) TX_DMASHDL_EXIST +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_EXT_TX_DMASHDL_EXIST_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_INFO_EXT_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_EXT_TX_DMASHDL_EXIST_MASK \ + 0x80000000 /* TX_DMASHDL_EXIST[31] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_EXT_TX_DMASHDL_EXIST_SHFT 31 +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_EXT_TX_DMAD_RING_NUMBER_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_INFO_EXT_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_EXT_TX_DMAD_RING_NUMBER_MASK \ + 0x0000FF00 /* TX_DMAD_RING_NUMBER[15..8] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_EXT_TX_DMAD_RING_NUMBER_SHFT 8 +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_EXT_TX_EVENT_RING_NUMBER_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_INFO_EXT_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_EXT_TX_EVENT_RING_NUMBER_MASK \ + 0x000000FF /* TX_EVENT_RING_NUMBER[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_INFO_EXT_TX_EVENT_RING_NUMBER_SHFT 0 + +/* +* ---WPDMA_INT_RX_PRI_SEL (0x18024000 + 0x298)--- +* WPDMA_INT_RX_RING0_PRI_SEL[0] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_RX_RING1_PRI_SEL[1] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_RX_RING2_PRI_SEL[2] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_RX_RING3_PRI_SEL[3] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_RX_RING4_PRI_SEL[4] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_RX_RING5_PRI_SEL[5] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_RX_RING6_PRI_SEL[6] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_RX_RING7_PRI_SEL[7] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* RESERVED8[31..8] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING7_PRI_SEL_ADDR \ + \ + WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING7_PRI_SEL_MASK \ + \ + 0x00000080 /* WPDMA_INT_RX_RING7_PRI_SEL[7] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING7_PRI_SEL_SHFT \ + \ + 7 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING6_PRI_SEL_ADDR \ + \ + WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING6_PRI_SEL_MASK \ + \ + 0x00000040 /* WPDMA_INT_RX_RING6_PRI_SEL[6] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING6_PRI_SEL_SHFT \ + \ + 6 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING5_PRI_SEL_ADDR \ + \ + WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING5_PRI_SEL_MASK \ + \ + 0x00000020 /* WPDMA_INT_RX_RING5_PRI_SEL[5] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING5_PRI_SEL_SHFT \ + \ + 5 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING4_PRI_SEL_ADDR \ + \ + WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING4_PRI_SEL_MASK \ + \ + 0x00000010 /* WPDMA_INT_RX_RING4_PRI_SEL[4] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING4_PRI_SEL_SHFT \ + \ + 4 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING3_PRI_SEL_ADDR \ + \ + WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING3_PRI_SEL_MASK \ + \ + 0x00000008 /* WPDMA_INT_RX_RING3_PRI_SEL[3] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING3_PRI_SEL_SHFT \ + \ + 3 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING2_PRI_SEL_ADDR \ + \ + WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING2_PRI_SEL_MASK \ + \ + 0x00000004 /* WPDMA_INT_RX_RING2_PRI_SEL[2] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING2_PRI_SEL_SHFT \ + \ + 2 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING1_PRI_SEL_ADDR \ + \ + WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING1_PRI_SEL_MASK \ + \ + 0x00000002 /* WPDMA_INT_RX_RING1_PRI_SEL[1] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING1_PRI_SEL_SHFT \ + \ + 1 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING0_PRI_SEL_ADDR \ + \ + WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING0_PRI_SEL_MASK \ + \ + 0x00000001 /* WPDMA_INT_RX_RING0_PRI_SEL[0] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING0_PRI_SEL_SHFT \ + \ + 0 + +/* +* ---WPDMA_TX_DBG0 (0x18024000 + 0x2A0)--- +* WPDMA_TX_DBG0[31..0] - (RO) xxx +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_DBG0_WPDMA_TX_DBG0_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_DBG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_DBG0_WPDMA_TX_DBG0_MASK \ + 0xFFFFFFFF /* WPDMA_TX_DBG0[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_DBG0_WPDMA_TX_DBG0_SHFT 0 + +/* +* ---WPDMA_TX_DBG1 (0x18024000 + 0x2A4)--- +* WPDMA_TX_DBG1[31..0] - (RO) xxx +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_DBG1_WPDMA_TX_DBG1_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_DBG1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_DBG1_WPDMA_TX_DBG1_MASK \ + 0xFFFFFFFF /* WPDMA_TX_DBG1[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_DBG1_WPDMA_TX_DBG1_SHFT 0 + +/* +* ---WPDMA_RX_DBG0 (0x18024000 + 0x2A8)--- +* WPDMA_RX_DBG0[31..0] - (RO) xxx +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_DBG0_WPDMA_RX_DBG0_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_DBG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_DBG0_WPDMA_RX_DBG0_MASK \ + 0xFFFFFFFF /* WPDMA_RX_DBG0[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_DBG0_WPDMA_RX_DBG0_SHFT 0 + +/* +* ---WPDMA_RX_DBG1 (0x18024000 + 0x2AC)--- +* WPDMA_RX_DBG1[31..0] - (RO) xxx +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_DBG1_WPDMA_RX_DBG1_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_DBG1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_DBG1_WPDMA_RX_DBG1_MASK \ + 0xFFFFFFFF /* WPDMA_RX_DBG1[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_DBG1_WPDMA_RX_DBG1_SHFT 0 + +/* +* ---WPDMA_GLO_CFG_EXT0 (0x18024000 + 0x2B0)--- +* CSR_MAX_PREFETCH_CNT[1..0] - (RW) Max. dmad count per prefet request, +* 2'b00 : 1 entry, 2'b01 : 2 entries, 2'b10 : 4 entries, 2'b11 : 8 entries, Note +* : 1 entry(dmad size) is 16 bytes = 4 DWs = 2 QWs +* CSR_MEM_BST_SIZE[3..2] - (RW) Max. burst size per sram request. 00 : +* 16-byte, 01 : 32-byte, 10 : 64-byte, 11 : 128-byte +* CSR_MEM_ARB_LOCK_EN[4] - (RW) 1'b1 : Lock round-robin sram access +* arbiter until whole long burst request from dma FSM finish, 1'b0 : no lock +sram +* arbiter, grant will be change per request due to round-robin +* CSR_RX_DMA_WBQ_EN[5] - (RW) 1'b1 : RX dmad will be posted-write and +* deal with next received packet immediately, 1'b0 : RX dmad will be written +back +* immediately after received packet has been sent to host memory +* CSR_TX_DMASHDL_ENABLE[6] - (RW) 1'b1 : request DMASHDL before TX to +* select next TX ring, 1'b0 : disable DMASHDL and use round-robin arbiter to +* select next TX ring +* CSR_BRESP_ERROR_BYPASS_EN[7] - (RW) 1'b1 : Bypass AXI error bresp as a +* normal response. 1'b0 : Will not assert bready to error bresp(00 : OKAY, 01 : +* EXOKAY, 10 : SLVERR, 11 : DECERR) +* CSR_AXI_SLEEP_MODE[9..8] - (RW) 2'b00 : no sleep, normal TX/RX, 2b1* : +* sleep after AXI request, 2'b11 : force assertion of wvalid, rready and bready +* to finish all committed data phases, then sleep immediately +* RESERVED10[14..10] - (RO) Reserved bits +* CSR_Q_STATUS_IDX_BKRS_EN[15] - (RW) backup/restore enable bit for +* q_status(payload, prefetch and dispatch) index +* CSR_AXI_BST_SIZE[17..16] - (RW) AXI busrt length, 00 : 128-byte, 01 : +* 64-byte, 10 : 32-byte, 11 : 16-byte +* RESERVED18[18] - (RO) Reserved bits +* CSR_AXI_FAKE[19] - (RW) If set to 1'b1, all requests from DMA +* engine will not be sent to AXI INFRA, this try to fix AXI bus hang issue +temporarily! +* CSR_DMAD_PREFETCH_THRESHOLD[21..20] - (RW) trigger dmad prefetch when +* available dmad cnt >= {1(2'b00), 2(2'b01), 4(2'b10), 8(2'b11)} +* CSR_BID_CHECK_BYPASS_EN[22] - (RW) If set to 1'b0, axi master will check +* matching between awid and bid before assert bready, if set to 1'b1, it will +* bypass this checking and assert bready for each bvalid even though bid doesn't +* match any awid ever issued! +* CSR_RX_INFO_WB_EN[23] - (RW) If set to 1'b0, only DW0 and DW1 will be +* written back into memory after received RX packet process finished, this will +* save bus bandwidth a little because DW2 and DW3 are useless for FW +* CSR_AXI_OUTSTANDING_NUM[27..24] - (RW) decide max. outstanding AXI requests, +* common for AXI read or write! +* CSR_AXI_ARUSER_LOCK_EN[28] - (RW) on/off customized lock ctrl design thru +* AXI aruser signal, this will influence TX QoS ctrl +* CSR_AXI_AWUSER_LOCK_EN[29] - (RW) on/off customized lock ctrl design thru AXI +* awuser signal when RX dmad write-back have to be separately written into +* memory due to external dispatcher exists! +* CSR_AXI_LOCK_EN[30] - (RW) Global lock enable to on/off AXI spec. lock(axlock) +* behavior and also will on/off customized lock ctrl design thru AXI awuser +signal +* CSR_AXI_CLKGATE_BYP[31] - (RW) To bypass functional CG enable which +* incduced from coding style for DC inserted CG cell in all AXI read/write +master +* design module +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_CLKGATE_BYP_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_CLKGATE_BYP_MASK \ + 0x80000000 /* CSR_AXI_CLKGATE_BYP[31] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_CLKGATE_BYP_SHFT 31 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_LOCK_EN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_LOCK_EN_MASK \ + 0x40000000 /* CSR_AXI_LOCK_EN[30] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_LOCK_EN_SHFT 30 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_AWUSER_LOCK_EN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_AWUSER_LOCK_EN_MASK \ + 0x20000000 /* CSR_AXI_AWUSER_LOCK_EN[29] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_AWUSER_LOCK_EN_SHFT 29 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_ARUSER_LOCK_EN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_ARUSER_LOCK_EN_MASK \ + 0x10000000 /* CSR_AXI_ARUSER_LOCK_EN[28] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_ARUSER_LOCK_EN_SHFT 28 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_OUTSTANDING_NUM_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_OUTSTANDING_NUM_MASK \ + 0x0F000000 /* CSR_AXI_OUTSTANDING_NUM[27..24] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_OUTSTANDING_NUM_SHFT 24 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_RX_INFO_WB_EN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_RX_INFO_WB_EN_MASK \ + 0x00800000 /* CSR_RX_INFO_WB_EN[23] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_RX_INFO_WB_EN_SHFT 23 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_BID_CHECK_BYPASS_EN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_BID_CHECK_BYPASS_EN_MASK \ + 0x00400000 /* CSR_BID_CHECK_BYPASS_EN[22] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_BID_CHECK_BYPASS_EN_SHFT 22 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_DMAD_PREFETCH_THRESHOLD_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_DMAD_PREFETCH_THRESHOLD_MASK \ + 0x00300000 /* CSR_DMAD_PREFETCH_THRESHOLD[21..20] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_DMAD_PREFETCH_THRESHOLD_SHFT \ + 20 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_FAKE_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_FAKE_MASK \ + 0x00080000 /* CSR_AXI_FAKE[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_FAKE_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_BST_SIZE_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_BST_SIZE_MASK \ + 0x00030000 /* CSR_AXI_BST_SIZE[17..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_BST_SIZE_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_Q_STATUS_IDX_BKRS_EN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_Q_STATUS_IDX_BKRS_EN_MASK \ + 0x00008000 /* CSR_Q_STATUS_IDX_BKRS_EN[15] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_Q_STATUS_IDX_BKRS_EN_SHFT 15 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_SLEEP_MODE_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_SLEEP_MODE_MASK \ + 0x00000300 /* CSR_AXI_SLEEP_MODE[9..8] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_AXI_SLEEP_MODE_SHFT 8 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_BRESP_ERROR_BYPASS_EN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_BRESP_ERROR_BYPASS_EN_MASK \ + 0x00000080 /* CSR_BRESP_ERROR_BYPASS_EN[7] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_BRESP_ERROR_BYPASS_EN_SHFT 7 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_TX_DMASHDL_ENABLE_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_TX_DMASHDL_ENABLE_MASK \ + 0x00000040 /* CSR_TX_DMASHDL_ENABLE[6] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_TX_DMASHDL_ENABLE_SHFT 6 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_RX_DMA_WBQ_EN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_RX_DMA_WBQ_EN_MASK \ + 0x00000020 /* CSR_RX_DMA_WBQ_EN[5] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_RX_DMA_WBQ_EN_SHFT 5 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_MEM_ARB_LOCK_EN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_MEM_ARB_LOCK_EN_MASK \ + 0x00000010 /* CSR_MEM_ARB_LOCK_EN[4] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_MEM_ARB_LOCK_EN_SHFT 4 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_MEM_BST_SIZE_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_MEM_BST_SIZE_MASK \ + 0x0000000C /* CSR_MEM_BST_SIZE[3..2] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_MEM_BST_SIZE_SHFT 2 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_MAX_PREFETCH_CNT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_MAX_PREFETCH_CNT_MASK \ + 0x00000003 /* CSR_MAX_PREFETCH_CNT[1..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT0_CSR_MAX_PREFETCH_CNT_SHFT 0 + +/* +* ---WPDMA_GLO_CFG_EXT1 (0x18024000 + 0x2B4)--- +* CSR_TXFIFO0_RDY_THRESHOLD[7..0] - (RW) xxx +* CSR_TXFIFO1_RDY_THRESHOLD[15..8] - (RW) xxx +* CSR_TX_DISP_ARB_SCHEDULED_ACCESS_TIMER[23..16] - (RW) timer setting for +* SCHEDULED_ACCESS_TIME_ARB of csr_tx_disp_arb_mode +* CSR_TX_DISP_ARB_MODE[25..24] - (RW) 00 : FAIR_ARB, 01 : FIX_ARB, 10 : +* UNBALANCED_ARB, 11 : SCHEDULED_ACCESS_TIME_ARB +* CSR_FWDL_FLOW_CTRL_BYASS_EN[26] - (RW) To disable firmware download TX flow +* control of TX dma(host_dma1) when firmare download of RX dma(mcu_dma1) is in +* firmware download polling mode!! Remember to set to 1'b0 when firmware +download +* ring is set back to normal ring usage which should be in flow control for +* correct behavior!! +* CSR_FWDL_FLOW_CTRL_BYASS_LS_QSEL_EN[27] - (RW) select firmware download TX +* ring(LSB/MSB ring) to bypass TX flow control when firmare download RX +* ring(LSB/MSB ring) of RX dma(mcu_dma1) is in firmware download polling mode!! +* RESERVED[31..28] - (RW) reserved +*/ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_FWDL_FLOW_CTRL_BYASS_LS_QSEL_EN_ADDR \ + \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_FWDL_FLOW_CTRL_BYASS_LS_QSEL_EN_MASK \ + \ + 0x08000000 /* CSR_FWDL_FLOW_CTRL_BYASS_LS_QSEL_EN[27] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_FWDL_FLOW_CTRL_BYASS_LS_QSEL_EN_SHFT \ + \ + 27 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_FWDL_FLOW_CTRL_BYASS_EN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_FWDL_FLOW_CTRL_BYASS_EN_MASK \ + 0x04000000 /* CSR_FWDL_FLOW_CTRL_BYASS_EN[26] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_FWDL_FLOW_CTRL_BYASS_EN_SHFT \ + 26 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_TX_DISP_ARB_MODE_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_TX_DISP_ARB_MODE_MASK \ + 0x03000000 /* CSR_TX_DISP_ARB_MODE[25..24] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_TX_DISP_ARB_MODE_SHFT 24 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_TX_DISP_ARB_SCHEDULED_ACCESS_TIMER_AD\ +DR \ +\ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_TX_DISP_ARB_SCHEDULED_ACCESS_TIMER_MA\ +SK \ +\ + 0x00FF0000 /* CSR_TX_DISP_ARB_SCHEDULED_ACCESS_TIMER[23..16] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_TX_DISP_ARB_SCHEDULED_ACCESS_TIMER_SH\ +FT \ +\ + 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_TXFIFO1_RDY_THRESHOLD_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_TXFIFO1_RDY_THRESHOLD_MASK \ + 0x0000FF00 /* CSR_TXFIFO1_RDY_THRESHOLD[15..8] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_TXFIFO1_RDY_THRESHOLD_SHFT 8 +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_TXFIFO0_RDY_THRESHOLD_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_TXFIFO0_RDY_THRESHOLD_MASK \ + 0x000000FF /* CSR_TXFIFO0_RDY_THRESHOLD[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_GLO_CFG_EXT1_CSR_TXFIFO0_RDY_THRESHOLD_SHFT 0 + +/* +* ---WPDMA_TX_QOS_LMT_CFG0 (0x18024000 + 0x2C0)--- +* CSR_TX_PLD_0_AXI_LIMITER_REQ[2..0] - (RW) QoS CR, Limiter Enable for packet +* traffice of type TX_PLD_0 +* CSR_TX_PLD_0_AXI_LIMITER_EN_REQ[3] - (RW) QoS CR, Limiter Enable for packet +* traffice of type TX_PLD_0 +* CSR_TX_PLD_0_AXI_LIMITER_PKT[6..4] - (RW) QoS CR, Limiter Enable for packet +* traffice of type TX_PLD_0 +* CSR_TX_PLD_0_AXI_LIMITER_EN_PKT[7] - (RW) QoS CR, Limiter Enable for packet +* traffice of type TX_PLD_0 +* CSR_TX_PLD_1_PLD_AXI_LIMITER_REQ[10..8] - (RW) QoS CR, Limiter Enable for +* request traffice of type TX_PLD_1_PLD +* CSR_TX_PLD_1_PLD_AXI_LIMITER_EN_REQ[11] - (RW) QoS CR, Limiter Enable for +* request traffice of type TX_PLD_1_PLD +* CSR_TX_PLD_1_PLD_AXI_LIMITER_PKT[14..12] - (RW) QoS CR, Limiter Enable for +* request traffice of type TX_PLD_1_PLD +* CSR_TX_PLD_1_PLD_AXI_LIMITER_EN_PKT[15] - (RW) QoS CR, Limiter Enable for +* request traffice of type TX_PLD_1_PLD +* CSR_RX_PLD_AXI_LIMITER_REQ[18..16] - (RW) QoS CR, Limiter Enable for request +* traffice of type RX_PLD +* CSR_RX_PLD_AXI_LIMITER_EN_REQ[19] - (RW) QoS CR, Limiter Enable for request +* traffice of type RX_PLD +* CSR_RX_PLD_AXI_LIMITER_PKT[22..20] - (RW) QoS CR, Limiter Enable for request +* traffice of type RX_PLD +* CSR_RX_PLD_AXI_LIMITER_EN_PKT[23] - (RW) QoS CR, Limiter Enable for request +* traffice of type RX_PLD +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_EN_PKT_ADDR \ + \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_EN_PKT_MASK \ + \ + 0x00800000 /* CSR_RX_PLD_AXI_LIMITER_EN_PKT[23] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_EN_PKT_SHFT \ + \ + 23 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_PKT_ADDR \ + \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_PKT_MASK \ + \ + 0x00700000 /* CSR_RX_PLD_AXI_LIMITER_PKT[22..20] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_PKT_SHFT \ + \ + 20 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_EN_REQ_ADDR \ + \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_EN_REQ_MASK \ + \ + 0x00080000 /* CSR_RX_PLD_AXI_LIMITER_EN_REQ[19] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_EN_REQ_SHFT \ + \ + 19 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_REQ_ADDR \ + \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_REQ_MASK \ + \ + 0x00070000 /* CSR_RX_PLD_AXI_LIMITER_REQ[18..16] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_REQ_SHFT \ + \ + 16 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_1_PLD_AXI_LIMITER_EN_PKT_AD\ +DR \ +\ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_1_PLD_AXI_LIMITER_EN_PKT_MA\ +SK \ +\ + 0x00008000 /* CSR_TX_PLD_1_PLD_AXI_LIMITER_EN_PKT[15] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_1_PLD_AXI_LIMITER_EN_PKT_SH\ +FT \ +\ + 15 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_1_PLD_AXI_LIMITER_PKT_ADDR \ + \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_1_PLD_AXI_LIMITER_PKT_MASK \ + \ + 0x00007000 /* CSR_TX_PLD_1_PLD_AXI_LIMITER_PKT[14..12] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_1_PLD_AXI_LIMITER_PKT_SHFT \ + \ + 12 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_1_PLD_AXI_LIMITER_EN_REQ_AD\ +DR \ +\ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_1_PLD_AXI_LIMITER_EN_REQ_MA\ +SK \ +\ + 0x00000800 /* CSR_TX_PLD_1_PLD_AXI_LIMITER_EN_REQ[11] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_1_PLD_AXI_LIMITER_EN_REQ_SH\ +FT \ +\ + 11 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_1_PLD_AXI_LIMITER_REQ_ADDR \ + \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_1_PLD_AXI_LIMITER_REQ_MASK \ + \ + 0x00000700 /* CSR_TX_PLD_1_PLD_AXI_LIMITER_REQ[10..8] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_1_PLD_AXI_LIMITER_REQ_SHFT \ + \ + 8 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_0_AXI_LIMITER_EN_PKT_ADDR \ + \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_0_AXI_LIMITER_EN_PKT_MASK \ + \ + 0x00000080 /* CSR_TX_PLD_0_AXI_LIMITER_EN_PKT[7] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_0_AXI_LIMITER_EN_PKT_SHFT \ + \ + 7 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_0_AXI_LIMITER_PKT_ADDR \ + \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_0_AXI_LIMITER_PKT_MASK \ + \ + 0x00000070 /* CSR_TX_PLD_0_AXI_LIMITER_PKT[6..4] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_0_AXI_LIMITER_PKT_SHFT \ + \ + 4 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_0_AXI_LIMITER_EN_REQ_ADDR \ + \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_0_AXI_LIMITER_EN_REQ_MASK \ + \ + 0x00000008 /* CSR_TX_PLD_0_AXI_LIMITER_EN_REQ[3] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_0_AXI_LIMITER_EN_REQ_SHFT \ + \ + 3 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_0_AXI_LIMITER_REQ_ADDR \ + \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_0_AXI_LIMITER_REQ_MASK \ + \ + 0x00000007 /* CSR_TX_PLD_0_AXI_LIMITER_REQ[2..0] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_0_AXI_LIMITER_REQ_SHFT \ + \ + 0 + +/* +* ---WPDMA_TX_QOS_LMT_CFG1 (0x18024000 + 0x2C4)--- +* CSR_AUX_TX_PLD_0_AXI_LIMITER_REQ[2..0] - (RW) QoS CR, Limiter value selected +* by PP dynamically +* RESERVED3[3] - (RO) Reserved bits +* CSR_AUX_TX_PLD_0_AXI_LIMITER_PKT[6..4] - (RW) QoS CR, Limiter value selected +* by PP dynamically +* RESERVED7[7] - (RO) Reserved bits +* CSR_AUX_TX_PLD_1_AXI_LIMITER_REQ[10..8] - (RW) QoS CR, Limiter value +* selected by PP dynamically +* RESERVED11[11] - (RO) Reserved bits +* CSR_AUX_TX_PLD_1_AXI_LIMITER_PKT[14..12] - (RW) QoS CR, Limiter value +* selected by PP dynamically +* RESERVED15[15] - (RO) Reserved bits +* CSR_AUX_RX_PLD_AXI_LIMITER_REQ[18..16] - (RW) QoS CR, Limiter value selected +* by PP dynamically +* RESERVED19[19] - (RO) Reserved bits +* CSR_AUX_RX_PLD_AXI_LIMITER_PKT[22..20] - (RW) QoS CR, Limiter value selected +* by PP dynamically +* RESERVED23[31..23] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_RX_PLD_AXI_LIMITER_PKT_ADDR \ + \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_RX_PLD_AXI_LIMITER_PKT_MASK \ + \ + 0x00700000 /* CSR_AUX_RX_PLD_AXI_LIMITER_PKT[22..20] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_RX_PLD_AXI_LIMITER_PKT_SHFT \ + \ + 20 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_RX_PLD_AXI_LIMITER_REQ_ADDR \ + \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_RX_PLD_AXI_LIMITER_REQ_MASK \ + \ + 0x00070000 /* CSR_AUX_RX_PLD_AXI_LIMITER_REQ[18..16] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_RX_PLD_AXI_LIMITER_REQ_SHFT \ + \ + 16 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_TX_PLD_1_AXI_LIMITER_PKT_ADDR \ + \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_TX_PLD_1_AXI_LIMITER_PKT_MASK \ + \ + 0x00007000 /* CSR_AUX_TX_PLD_1_AXI_LIMITER_PKT[14..12] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_TX_PLD_1_AXI_LIMITER_PKT_SHFT \ + \ + 12 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_TX_PLD_1_AXI_LIMITER_REQ_ADDR \ + \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_TX_PLD_1_AXI_LIMITER_REQ_MASK \ + \ + 0x00000700 /* CSR_AUX_TX_PLD_1_AXI_LIMITER_REQ[10..8] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_TX_PLD_1_AXI_LIMITER_REQ_SHFT \ + \ + 8 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_TX_PLD_0_AXI_LIMITER_PKT_ADDR \ + \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_TX_PLD_0_AXI_LIMITER_PKT_MASK \ + \ + 0x00000070 /* CSR_AUX_TX_PLD_0_AXI_LIMITER_PKT[6..4] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_TX_PLD_0_AXI_LIMITER_PKT_SHFT \ + \ + 4 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_TX_PLD_0_AXI_LIMITER_REQ_ADDR \ + \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_TX_PLD_0_AXI_LIMITER_REQ_MASK \ + \ + 0x00000007 /* CSR_AUX_TX_PLD_0_AXI_LIMITER_REQ[2..0] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_TX_PLD_0_AXI_LIMITER_REQ_SHFT \ + \ + 0 + +/* +* ---WPDMA_TX_QOS_LMT_CFG2 (0x18024000 + 0x2C8)--- +* CSR_RX_RD_DMAD_AXI_LIMITER_REQ[2..0] - (RW) QoS CR, Limiter Value for +* packet traffice of type RX_RD_DMAD +* CSR_RX_RD_DMAD_AXI_LIMITER_EN_REQ[3] - (RW) QoS CR, Limiter Enable for +* request traffice of type RX_RD_DMAD +* CSR_RX_RD_DMAD_AXI_LIMITER_PKT[6..4] - (RW) QoS CR, Limiter Value for +* packet traffice of type RX_RD_DMAD +* CSR_RX_RD_DMAD_AXI_LIMITER_EN_PKT[7] - (RW) QoS CR, Limiter Enable for +* packet traffice of type RX_RD_DMAD +* CSR_RX_WR_DMAD_AXI_LIMITER_REQ[10..8] - (RW) QoS CR, Limiter Value for +* packet traffice of type RX_WR_DMAD +* CSR_RX_WR_DMAD_AXI_LIMITER_EN_REQ[11] - (RW) QoS CR, Limiter Enable for +* request traffice of type RX_WR_DMAD +* CSR_RX_WR_DMAD_AXI_LIMITER_PKT[14..12] - (RW) QoS CR, Limiter Value for +* packet traffice of type RX_WR_DMAD +* CSR_RX_WR_DMAD_AXI_LIMITER_EN_PKT[15] - (RW) QoS CR, Limiter Enable for +* packet traffice of type RX_WR_DMAD +* CSR_TX_RD_DMAD_AXI_LIMITER_REQ[18..16] - (RW) QoS CR, Limiter Value for +* packet traffice of type TX_RD_DMAD +* CSR_TX_RD_DMAD_AXI_LIMITER_EN_REQ[19] - (RW) QoS CR, Limiter Enable for +* request traffice of type TX_RD_DMAD +* CSR_TX_RD_DMAD_AXI_LIMITER_PKT[22..20] - (RW) QoS CR, Limiter Value for +* packet traffice of type TX_RD_DMAD +* CSR_TX_RD_DMAD_AXI_LIMITER_EN_PKT[23] - (RW) QoS CR, Limiter Enable for +* packet traffice of type TX_RD_DMAD +* CSR_TX_WR_DMAD_AXI_LIMITER_REQ[26..24] - (RW) QoS CR, Limiter Value for +* packet traffice of type TX_WR_DMAD +* CSR_TX_WR_DMAD_AXI_LIMITER_EN_REQ[27] - (RW) QoS CR, Limiter Enable for +* request traffice of type TX_WR_DMAD +* CSR_TX_WR_DMAD_AXI_LIMITER_PKT[30..28] - (RW) QoS CR, Limiter Value for +* packet traffice of type TX_WR_DMAD +* CSR_TX_WR_DMAD_AXI_LIMITER_EN_PKT[31] - (RW) QoS CR, Limiter Enable for +* packet traffice of type TX_WR_DMAD +*/ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_EN_PKT_ADDR\ +\ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_EN_PKT_MASK\ +\ + 0x80000000 /* CSR_TX_WR_DMAD_AXI_LIMITER_EN_PKT[31] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_EN_PKT_SHFT\ +\ + 31 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_PKT_ADDR \ + \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_PKT_MASK \ + \ + 0x70000000 /* CSR_TX_WR_DMAD_AXI_LIMITER_PKT[30..28] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_PKT_SHFT \ + \ + 28 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_EN_REQ_ADDR\ +\ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_EN_REQ_MASK\ +\ + 0x08000000 /* CSR_TX_WR_DMAD_AXI_LIMITER_EN_REQ[27] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_EN_REQ_SHFT\ +\ + 27 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_REQ_ADDR \ + \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_REQ_MASK \ + \ + 0x07000000 /* CSR_TX_WR_DMAD_AXI_LIMITER_REQ[26..24] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_REQ_SHFT \ + \ + 24 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_EN_PKT_ADDR\ +\ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_EN_PKT_MASK\ +\ + 0x00800000 /* CSR_TX_RD_DMAD_AXI_LIMITER_EN_PKT[23] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_EN_PKT_SHFT\ +\ + 23 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_PKT_ADDR \ + \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_PKT_MASK \ + \ + 0x00700000 /* CSR_TX_RD_DMAD_AXI_LIMITER_PKT[22..20] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_PKT_SHFT \ + \ + 20 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_EN_REQ_ADDR\ +\ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_EN_REQ_MASK\ +\ + 0x00080000 /* CSR_TX_RD_DMAD_AXI_LIMITER_EN_REQ[19] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_EN_REQ_SHFT\ +\ + 19 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_REQ_ADDR \ + \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_REQ_MASK \ + \ + 0x00070000 /* CSR_TX_RD_DMAD_AXI_LIMITER_REQ[18..16] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_REQ_SHFT \ + \ + 16 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_EN_PKT_ADDR\ +\ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_EN_PKT_MASK\ +\ + 0x00008000 /* CSR_RX_WR_DMAD_AXI_LIMITER_EN_PKT[15] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_EN_PKT_SHFT\ +\ + 15 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_PKT_ADDR \ + \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_PKT_MASK \ + \ + 0x00007000 /* CSR_RX_WR_DMAD_AXI_LIMITER_PKT[14..12] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_PKT_SHFT \ + \ + 12 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_EN_REQ_ADDR\ +\ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_EN_REQ_MASK\ +\ + 0x00000800 /* CSR_RX_WR_DMAD_AXI_LIMITER_EN_REQ[11] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_EN_REQ_SHFT\ +\ + 11 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_REQ_ADDR \ + \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_REQ_MASK \ + \ + 0x00000700 /* CSR_RX_WR_DMAD_AXI_LIMITER_REQ[10..8] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_REQ_SHFT \ + \ + 8 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_EN_PKT_ADDR\ +\ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_EN_PKT_MASK\ +\ + 0x00000080 /* CSR_RX_RD_DMAD_AXI_LIMITER_EN_PKT[7] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_EN_PKT_SHFT\ +\ + 7 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_PKT_ADDR \ + \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_PKT_MASK \ + \ + 0x00000070 /* CSR_RX_RD_DMAD_AXI_LIMITER_PKT[6..4] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_PKT_SHFT \ + \ + 4 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_EN_REQ_ADDR\ +\ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_EN_REQ_MASK\ +\ + 0x00000008 /* CSR_RX_RD_DMAD_AXI_LIMITER_EN_REQ[3] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_EN_REQ_SHFT\ +\ + 3 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_REQ_ADDR \ + \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_REQ_MASK \ + \ + 0x00000007 /* CSR_RX_RD_DMAD_AXI_LIMITER_REQ[2..0] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_REQ_SHFT \ + \ + 0 + +/* +* ---WPDMA_TX_QOS_LMT_CFG3 (0x18024000 + 0x2CC)--- +* CSR_AUX_RX_RD_DMAD_AXI_LIMITER_REQ[2..0] - (RW) QoS CR, Limiter value +* selected by PP dynamically +* RESERVED3[3] - (RO) Reserved bits +* CSR_AUX_RX_RD_DMAD_AXI_LIMITER_PKT[6..4] - (RW) QoS CR, Limiter value +* selected by PP dynamically +* RESERVED7[7] - (RO) Reserved bits +* CSR_AUX_RX_WR_DMAD_AXI_LIMITER_REQ[10..8] - (RW) QoS CR, Limiter value +* selected by PP dynamically +* RESERVED11[11] - (RO) Reserved bits +* CSR_AUX_RX_WR_DMAD_AXI_LIMITER_PKT[14..12] - (RW) QoS CR, Limiter value +* selected by PP dynamically +* RESERVED15[15] - (RO) Reserved bits +* CSR_AUX_TX_RD_DMAD_AXI_LIMITER_REQ[18..16] - (RW) QoS CR, Limiter value +* selected by PP dynamically +* RESERVED19[19] - (RO) Reserved bits +* CSR_AUX_TX_RD_DMAD_AXI_LIMITER_PKT[22..20] - (RW) QoS CR, Limiter value +* selected by PP dynamically +* RESERVED23[23] - (RO) Reserved bits +* CSR_AUX_TX_WR_DMAD_AXI_LIMITER_REQ[26..24] - (RW) QoS CR, Limiter value +* selected by PP dynamically +* RESERVED27[27] - (RO) Reserved bits +* CSR_AUX_TX_WR_DMAD_AXI_LIMITER_PKT[30..28] - (RW) QoS CR, Limiter value +* selected by PP dynamically +* RESERVED31[31] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_WR_DMAD_AXI_LIMITER_PKT_ADD\ +R \ +\ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_WR_DMAD_AXI_LIMITER_PKT_MAS\ +K \ +\ + 0x70000000 /* CSR_AUX_TX_WR_DMAD_AXI_LIMITER_PKT[30..28] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_WR_DMAD_AXI_LIMITER_PKT_SHF\ +T \ +\ + 28 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_WR_DMAD_AXI_LIMITER_REQ_ADD\ +R \ +\ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_WR_DMAD_AXI_LIMITER_REQ_MAS\ +K \ +\ + 0x07000000 /* CSR_AUX_TX_WR_DMAD_AXI_LIMITER_REQ[26..24] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_WR_DMAD_AXI_LIMITER_REQ_SHF\ +T \ +\ + 24 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_RD_DMAD_AXI_LIMITER_PKT_ADD\ +R \ +\ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_RD_DMAD_AXI_LIMITER_PKT_MAS\ +K \ +\ + 0x00700000 /* CSR_AUX_TX_RD_DMAD_AXI_LIMITER_PKT[22..20] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_RD_DMAD_AXI_LIMITER_PKT_SHF\ +T \ +\ + 20 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_RD_DMAD_AXI_LIMITER_REQ_ADD\ +R \ +\ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_RD_DMAD_AXI_LIMITER_REQ_MAS\ +K \ +\ + 0x00070000 /* CSR_AUX_TX_RD_DMAD_AXI_LIMITER_REQ[18..16] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_RD_DMAD_AXI_LIMITER_REQ_SHF\ +T \ +\ + 16 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_WR_DMAD_AXI_LIMITER_PKT_ADD\ +R \ +\ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_WR_DMAD_AXI_LIMITER_PKT_MAS\ +K \ +\ + 0x00007000 /* CSR_AUX_RX_WR_DMAD_AXI_LIMITER_PKT[14..12] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_WR_DMAD_AXI_LIMITER_PKT_SHF\ +T \ +\ + 12 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_WR_DMAD_AXI_LIMITER_REQ_ADD\ +R \ +\ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_WR_DMAD_AXI_LIMITER_REQ_MAS\ +K \ +\ + 0x00000700 /* CSR_AUX_RX_WR_DMAD_AXI_LIMITER_REQ[10..8] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_WR_DMAD_AXI_LIMITER_REQ_SHF\ +T \ +\ + 8 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_RD_DMAD_AXI_LIMITER_PKT_ADD\ +R \ +\ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_RD_DMAD_AXI_LIMITER_PKT_MAS\ +K \ +\ + 0x00000070 /* CSR_AUX_RX_RD_DMAD_AXI_LIMITER_PKT[6..4] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_RD_DMAD_AXI_LIMITER_PKT_SHF\ +T \ +\ + 4 +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_RD_DMAD_AXI_LIMITER_REQ_ADD\ +R \ +\ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_ADDR +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_RD_DMAD_AXI_LIMITER_REQ_MAS\ +K \ +\ + 0x00000007 /* CSR_AUX_RX_RD_DMAD_AXI_LIMITER_REQ[2..0] */ +#define \ +WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_RD_DMAD_AXI_LIMITER_REQ_SHF\ +T \ +\ + 0 + +/* +* ---WPDMA_TX_QOS_QTM_CFG0 (0x18024000 + 0x2D0)--- +* CSR_TXP0_FFA_QTM[3..0] - (RW) CSR_TXP0_FFA_QTM +* CSR_TXP0_RSVD_QTM[7..4] - (RW) CSR_TXP0_RSVD_QTM +* CSR_TXP1_FFA_QTM[11..8] - (RW) CSR_TXP1_FFA_QTM +* CSR_TXP1_RSVD_QTM[15..12] - (RW) CSR_TXP1_RSVD_QTM +* RESERVED16[23..16] - (RO) Reserved bits +* CSR_FFA_TOTAL_QTM[27..24] - (RW) CSR_FFA_TOTAL_QTM +* CSR_QOS_QTM_MODE[29..28] - (RW) 2'b01 : csr_rsvd_qtm_mode_only, 2'b10 : +* csr_ffa_qtm_mode_only, others : rsvd+ffa mode +* RESERVED30[31..30] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_QOS_QTM_MODE_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_QOS_QTM_MODE_MASK \ + 0x30000000 /* CSR_QOS_QTM_MODE[29..28] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_QOS_QTM_MODE_SHFT 28 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_FFA_TOTAL_QTM_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_FFA_TOTAL_QTM_MASK \ + 0x0F000000 /* CSR_FFA_TOTAL_QTM[27..24] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_FFA_TOTAL_QTM_SHFT 24 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_TXP1_RSVD_QTM_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_TXP1_RSVD_QTM_MASK \ + 0x0000F000 /* CSR_TXP1_RSVD_QTM[15..12] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_TXP1_RSVD_QTM_SHFT 12 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_TXP1_FFA_QTM_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_TXP1_FFA_QTM_MASK \ + 0x00000F00 /* CSR_TXP1_FFA_QTM[11..8] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_TXP1_FFA_QTM_SHFT 8 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_TXP0_RSVD_QTM_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_TXP0_RSVD_QTM_MASK \ + 0x000000F0 /* CSR_TXP0_RSVD_QTM[7..4] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_TXP0_RSVD_QTM_SHFT 4 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_TXP0_FFA_QTM_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_TXP0_FFA_QTM_MASK \ + 0x0000000F /* CSR_TXP0_FFA_QTM[3..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG0_CSR_TXP0_FFA_QTM_SHFT 0 + +/* +* ---WPDMA_TX_QOS_QTM_CFG1 (0x18024000 + 0x2D4)--- +* CSR_DMAD_FFA_QTM[3..0] - (RW) CSR_DMAD_FFA_QTM +* CSR_DMAD_RSVD_QTM[7..4] - (RW) CSR_DMAD_RSVD_QTM +* CSR_TXD_FFA_QTM[11..8] - (RW) CSR_TXD_FFA_QTM +* CSR_TXD_RSVD_QTM[15..12] - (RW) CSR_TXD_RSVD_QTM +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_CSR_TXD_RSVD_QTM_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_CSR_TXD_RSVD_QTM_MASK \ + 0x0000F000 /* CSR_TXD_RSVD_QTM[15..12] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_CSR_TXD_RSVD_QTM_SHFT 12 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_CSR_TXD_FFA_QTM_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_CSR_TXD_FFA_QTM_MASK \ + 0x00000F00 /* CSR_TXD_FFA_QTM[11..8] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_CSR_TXD_FFA_QTM_SHFT 8 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_CSR_DMAD_RSVD_QTM_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_CSR_DMAD_RSVD_QTM_MASK \ + 0x000000F0 /* CSR_DMAD_RSVD_QTM[7..4] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_CSR_DMAD_RSVD_QTM_SHFT 4 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_CSR_DMAD_FFA_QTM_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_CSR_DMAD_FFA_QTM_MASK \ + 0x0000000F /* CSR_DMAD_FFA_QTM[3..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_QOS_QTM_CFG1_CSR_DMAD_FFA_QTM_SHFT 0 + +/* +* ---HOST_PRI_INT_STA (0x18024000 + 0x2E0)--- +* host_pri_int_sts_0[0] - (W1C) rx_done_int[0], W1C to clear delay +interrupt +* host_pri_int_sts_1[1] - (W1C) rx_done_int[1], W1C to clear delay +interrupt +* RESERVED2[31..2] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_HOST_PRI_INT_STA_host_pri_int_sts_1_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_PRI_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_PRI_INT_STA_host_pri_int_sts_1_MASK \ + 0x00000002 /* host_pri_int_sts_1[1] */ +#define WF_WFDMA_HOST_DMA0_HOST_PRI_INT_STA_host_pri_int_sts_1_SHFT 1 +#define WF_WFDMA_HOST_DMA0_HOST_PRI_INT_STA_host_pri_int_sts_0_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_PRI_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_PRI_INT_STA_host_pri_int_sts_0_MASK \ + 0x00000001 /* host_pri_int_sts_0[0] */ +#define WF_WFDMA_HOST_DMA0_HOST_PRI_INT_STA_host_pri_int_sts_0_SHFT 0 + +/* +* ---HOST_PER_INT_ENA_STA (0x18024000 + 0x2E4)--- +* wpdma_per_int_sts[3..0] - (W1C) status bit for rx ring periodic delayed +* interrupt to tracking ring is full or not, start delayed interrupt timer when +* RX ring is not full from falling edge of full flag and reset when ring full +* flag is asserted +* RESERVED4[15..4] - (RO) Reserved bits +* wpdma_per_int_ena[19..16] - (RW) enable bit for rx ring periodic delayed +* interrupt to tracking ring is full or not, start delayed interrupt timer when +* RX ring is not full from falling edge of full flag and reset when ring full +* flag is asserted +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_HOST_PER_INT_ENA_STA_wpdma_per_int_ena_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_PER_INT_ENA_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_PER_INT_ENA_STA_wpdma_per_int_ena_MASK \ + 0x000F0000 /* wpdma_per_int_ena[19..16] */ +#define WF_WFDMA_HOST_DMA0_HOST_PER_INT_ENA_STA_wpdma_per_int_ena_SHFT 16 +#define WF_WFDMA_HOST_DMA0_HOST_PER_INT_ENA_STA_wpdma_per_int_sts_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_PER_INT_ENA_STA_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_PER_INT_ENA_STA_wpdma_per_int_sts_MASK \ + 0x0000000F /* wpdma_per_int_sts[3..0] */ +#define WF_WFDMA_HOST_DMA0_HOST_PER_INT_ENA_STA_wpdma_per_int_sts_SHFT 0 + +/* +* ---HOST_PER_DLY_INT_CFG (0x18024000 + 0x2E8)--- +* wpdma_per_max_ptime[7..0] - (RW) Specified Max pending time for the +* internal RX ring full flag falling edge. When the pending time equal or +greater +* PER_MAX_PTIME x 20us or the # of pended TX_DONE_INT equal or greater than +* TX_MAX_PINT (see above), an Final TX_DLY_INT is generated +* Set to 0 will disable pending interrupt +* time check +* wpdma_per_dly_int_en[11..8] - (RW) RX periodic Delayed Interrupt Enable +* 1: Enable RX periodic delayed interrupt +mechanism +* 0: Disable RX periodic delayed interrupt +mechanism +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_HOST_PER_DLY_INT_CFG_wpdma_per_dly_int_en_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_PER_DLY_INT_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_PER_DLY_INT_CFG_wpdma_per_dly_int_en_MASK \ + 0x00000F00 /* wpdma_per_dly_int_en[11..8] */ +#define WF_WFDMA_HOST_DMA0_HOST_PER_DLY_INT_CFG_wpdma_per_dly_int_en_SHFT 8 +#define WF_WFDMA_HOST_DMA0_HOST_PER_DLY_INT_CFG_wpdma_per_max_ptime_ADDR \ + WF_WFDMA_HOST_DMA0_HOST_PER_DLY_INT_CFG_ADDR +#define WF_WFDMA_HOST_DMA0_HOST_PER_DLY_INT_CFG_wpdma_per_max_ptime_MASK \ + 0x000000FF /* wpdma_per_max_ptime[7..0] */ +#define WF_WFDMA_HOST_DMA0_HOST_PER_DLY_INT_CFG_wpdma_per_max_ptime_SHFT 0 + +/* +* ---WPDMA_PRI_DLY_INT_CFG0 (0x18024000 + 0x2F0)--- +* PRI0_MAX_PTIME[7..0] - (RW) Specified Max pending time for the +* internal PRI0_DONE_INT. When the pending time equal or greater PRI0_MAX_PTIME +x +* 20us or the # of pended PRI0_DONE_INT equal or greater than PRI0_MAX_PINT (see +* above), an Final PRI0_DLY_INT is generated +* Set to 0 will disable pending interrupt +* time check +* PRI0_MAX_PINT[14..8] - (RW) Specified Max # of pended interrupts. +* When the # of pended interrupts equal or +* greater than the value specified here or interrupt pending time reach the +limit +* (See below), a Final PRI0_DLY_INT is generated. +* Set to 0 will disable pending interrupt +* count check +* PRI0_DLY_INT_EN[15] - (RW) Priority Delayed Interrupt Enable +* 1: Enable Priority delayed interrupt +mechanism +* 0: Disable Priority delayed interrupt +mechanism +* In AXE host_dma0, these PRI1_* settings are +* for rx_ring[1]_int, and PRI0_* settings are for rx_ring[0]_int +* In AXE host_dma1, these PRI1_* settings are +* for rx_ring[0]_int, and PRI0_* settings are for Ored-tx_ring[14:0]_int +* In AXE mcu_dma0 and mcu_dma1, there are no +* priority interrupt thus no this 0x2E0 CR!! +* PRI1_MAX_PTIME[23..16] - (RW) Specified Max pending time for the +* internal PRI1_DONE_INT. When the pending time equal or greater PRI1_MAX_PTIME +x +* 20us or the # of pended PRI1_DONE_INT equal or greater than PRI1_MAX_PINT (see +* above), an Final PRI1_DLY_INT is generated +* Set to 0 will disable pending interrupt +* time check +* PRI1_MAX_PINT[30..24] - (RW) Specified Max # of pended interrupts. +* When the # of pended interrupts equal or +* greater than the value specified here or interrupt pending time reach the +limit +* (See below), a Final PRI1_DLY_INT is generated. +* Set to 0 will disable pending interrupt +* count check +* PRI1_DLY_INT_EN[31] - (RW) Priority Delayed Interrupt Enable +* 1: Enable Priority delayed interrupt +mechanism +* 0: Disable Priority delayed interrupt +mechanism +* In AXE host_dma0, these PRI1_* settings are +* for rx_ring[1]_int, and PRI0_* settings are for rx_ring[0]_int +* In AXE host_dma1, these PRI1_* settings are +* for rx_ring[0]_int, and PRI0_* settings are for Ored-tx_ring[14:0]_int +* In AXE mcu_dma0 and mcu_dma1, there are no +* priority interrupt thus no this 0x2E0 CR!! +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI1_DLY_INT_EN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI1_DLY_INT_EN_MASK \ + 0x80000000 /* PRI1_DLY_INT_EN[31] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI1_DLY_INT_EN_SHFT 31 +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI1_MAX_PINT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI1_MAX_PINT_MASK \ + 0x7F000000 /* PRI1_MAX_PINT[30..24] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI1_MAX_PINT_SHFT 24 +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI1_MAX_PTIME_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI1_MAX_PTIME_MASK \ + 0x00FF0000 /* PRI1_MAX_PTIME[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI1_MAX_PTIME_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI0_DLY_INT_EN_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI0_DLY_INT_EN_MASK \ + 0x00008000 /* PRI0_DLY_INT_EN[15] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI0_DLY_INT_EN_SHFT 15 +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI0_MAX_PINT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI0_MAX_PINT_MASK \ + 0x00007F00 /* PRI0_MAX_PINT[14..8] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI0_MAX_PINT_SHFT 8 +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI0_MAX_PTIME_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI0_MAX_PTIME_MASK \ + 0x000000FF /* PRI0_MAX_PTIME[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_PRI_DLY_INT_CFG0_PRI0_MAX_PTIME_SHFT 0 + +/* +* ---WPDMA_TX_RING0_CTRL0 (0x18024000 + 0x300)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring0 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING0_CTRL1 (0x18024000 + 0x304)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_Ring0. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring0 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING0_CTRL2 (0x18024000 + 0x308)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING0_CTRL3 (0x18024000 + 0x30c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING1_CTRL0 (0x18024000 + 0x310)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring1 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING1_CTRL1 (0x18024000 + 0x314)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_Ring1. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring1 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING1_CTRL2 (0x18024000 + 0x318)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING1_CTRL3 (0x18024000 + 0x31c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING2_CTRL0 (0x18024000 + 0x320)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring2 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING2_CTRL1 (0x18024000 + 0x324)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_Ring2. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring2 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING2_CTRL2 (0x18024000 + 0x328)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING2_CTRL3 (0x18024000 + 0x32c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING3_CTRL0 (0x18024000 + 0x330)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring3 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING3_CTRL1 (0x18024000 + 0x334)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_Ring3. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring3 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING3_CTRL2 (0x18024000 + 0x338)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING3_CTRL3 (0x18024000 + 0x33c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING0_CTRL0 (0x18024000 + 0x500)--- +* BASE_PTR[31..0] - (RW) Point to the base address of RXD Ring #0 +* (GE ports). It should be a 8-DWORD aligned address +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_RX_RING0_CTRL1 (0x18024000 + 0x504)--- +* MAX_CNT[11..0] - (RW) The maximum number of RXD count in RXD +* Ring #0. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring0 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING0_CTRL2 (0x18024000 + 0x508)--- +* CPU_IDX[11..0] - (RW) Point to the next RXD CPU wants to +* allocate to RXD Ring #0. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING0_CTRL3 (0x18024000 + 0x50c)--- +* DMA_IDX[11..0] - (RW) In normal operation, user dma_index +* would udated by hardware when moving rx packet done. User should not write +dma_index. +* Point to the next RXD DMA wants to use in +* FDS Ring#0. It should be a 8-DWORD aligned address. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING1_CTRL0 (0x18024000 + 0x510)--- +* BASE_PTR[31..0] - (RW) Point to the base address of RXD Ring #1 +* (GE ports). It should be a 8-DWORD aligned address +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_RX_RING1_CTRL1 (0x18024000 + 0x514)--- +* MAX_CNT[11..0] - (RW) The maximum number of RXD count in RXD +* Ring #1. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring1 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING1_CTRL2 (0x18024000 + 0x518)--- +* CPU_IDX[11..0] - (RW) Point to the next RXD CPU wants to +* allocate to RXD Ring #1. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING1_CTRL3 (0x18024000 + 0x51c)--- +* DMA_IDX[11..0] - (RW) In normal operation, user dma_index +* would udated by hardware when moving rx packet done. User should not write +dma_index. +* Point to the next RXD DMA wants to use in +* FDS Ring#1. It should be a 8-DWORD aligned address. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING2_CTRL0 (0x18024000 + 0x520)--- +* BASE_PTR[31..0] - (RW) Point to the base address of RXD Ring #2 +* (GE ports). It should be a 8-DWORD aligned address +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_RX_RING2_CTRL1 (0x18024000 + 0x524)--- +* MAX_CNT[11..0] - (RW) The maximum number of RXD count in RXD +* Ring #2. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring2 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING2_CTRL2 (0x18024000 + 0x528)--- +* CPU_IDX[11..0] - (RW) Point to the next RXD CPU wants to +* allocate to RXD Ring #2. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING2_CTRL3 (0x18024000 + 0x52C)--- +* DMA_IDX[11..0] - (RW) In normal operation, user dma_index +* would udated by hardware when moving rx packet done. User should not write +dma_index. +* Point to the next RXD DMA wants to use in +* FDS Ring#2. It should be a 8-DWORD aligned address. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING3_CTRL0 (0x18024000 + 0x530)--- +* BASE_PTR[31..0] - (RW) Point to the base address of RXD Ring #3 +* (GE ports). It should be a 8-DWORD aligned address +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_RX_RING3_CTRL1 (0x18024000 + 0x534)--- +* MAX_CNT[11..0] - (RW) The maximum number of RXD count in RXD +* Ring #3. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring3 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING3_CTRL2 (0x18024000 + 0x538)--- +* CPU_IDX[11..0] - (RW) Point to the next RXD CPU wants to +* allocate to RXD Ring #3. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING3_CTRL3 (0x18024000 + 0x53C)--- +* DMA_IDX[11..0] - (RW) In normal operation, user dma_index +* would udated by hardware when moving rx packet done. User should not write +dma_index. +* Point to the next RXD DMA wants to use in +* FDS Ring#3. It should be a 8-DWORD aligned address. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING4_CTRL0 (0x18024000 + 0x540)--- +* BASE_PTR[31..0] - (RW) Point to the base address of RXD Ring #0 +* (GE ports). It should be a 8-DWORD aligned address +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_RX_RING4_CTRL1 (0x18024000 + 0x544)--- +* MAX_CNT[11..0] - (RW) The maximum number of RXD count in RXD +* Ring #0. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring0 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING4_CTRL2 (0x18024000 + 0x548)--- +* CPU_IDX[11..0] - (RW) Point to the next RXD CPU wants to +* allocate to RXD Ring #0. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING4_CTRL3 (0x18024000 + 0x54c)--- +* DMA_IDX[11..0] - (RW) In normal operation, user dma_index +* would udated by hardware when moving rx packet done. User should not write +dma_index. +* Point to the next RXD DMA wants to use in +* FDS Ring#0. It should be a 8-DWORD aligned address. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING5_CTRL0 (0x18024000 + 0x550)--- +* BASE_PTR[31..0] - (RW) Point to the base address of RXD Ring #1 +* (GE ports). It should be a 8-DWORD aligned address +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_RX_RING5_CTRL1 (0x18024000 + 0x554)--- +* MAX_CNT[11..0] - (RW) The maximum number of RXD count in RXD +* Ring #1. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring1 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING5_CTRL2 (0x18024000 + 0x558)--- +* CPU_IDX[11..0] - (RW) Point to the next RXD CPU wants to +* allocate to RXD Ring #1. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING5_CTRL3 (0x18024000 + 0x55c)--- +* DMA_IDX[11..0] - (RW) In normal operation, user dma_index +* would udated by hardware when moving rx packet done. User should not write +dma_index. +* Point to the next RXD DMA wants to use in +* FDS Ring#1. It should be a 8-DWORD aligned address. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING6_CTRL0 (0x18024000 + 0x560)--- +* BASE_PTR[31..0] - (RW) Point to the base address of RXD Ring #2 +* (GE ports). It should be a 8-DWORD aligned address +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_RX_RING6_CTRL1 (0x18024000 + 0x564)--- +* MAX_CNT[11..0] - (RW) The maximum number of RXD count in RXD +* Ring #2. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring2 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING6_CTRL2 (0x18024000 + 0x568)--- +* CPU_IDX[11..0] - (RW) Point to the next RXD CPU wants to +* allocate to RXD Ring #2. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING6_CTRL3 (0x18024000 + 0x56C)--- +* DMA_IDX[11..0] - (RW) In normal operation, user dma_index +* would udated by hardware when moving rx packet done. User should not write +dma_index. +* Point to the next RXD DMA wants to use in +* FDS Ring#2. It should be a 8-DWORD aligned address. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING7_CTRL0 (0x18024000 + 0x570)--- +* BASE_PTR[31..0] - (RW) Point to the base address of RXD Ring #3 +* (GE ports). It should be a 8-DWORD aligned address +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_RX_RING7_CTRL1 (0x18024000 + 0x574)--- +* MAX_CNT[11..0] - (RW) The maximum number of RXD count in RXD +* Ring #3. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring3 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING7_CTRL2 (0x18024000 + 0x578)--- +* CPU_IDX[11..0] - (RW) Point to the next RXD CPU wants to +* allocate to RXD Ring #3. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING7_CTRL3 (0x18024000 + 0x57C)--- +* DMA_IDX[11..0] - (RW) In normal operation, user dma_index +* would udated by hardware when moving rx packet done. User should not write +dma_index. +* Point to the next RXD DMA wants to use in +* FDS Ring#3. It should be a 8-DWORD aligned address. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING0_EXT_CTRL (0x18024000 + 0x600)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #0 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING1_EXT_CTRL (0x18024000 + 0x604)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #1 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING2_EXT_CTRL (0x18024000 + 0x608)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #2 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING3_EXT_CTRL (0x18024000 + 0x60C)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #3 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING0_EXT_CTRL (0x18024000 + 0x680)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) RXD Ring #0 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING1_EXT_CTRL (0x18024000 + 0x684)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) RXD Ring #1 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING2_EXT_CTRL (0x18024000 + 0x688)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) RXD Ring #2 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING3_EXT_CTRL (0x18024000 + 0x68C)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) RXD Ring #3 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING4_EXT_CTRL (0x18024000 + 0x690)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) RXD Ring #0 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING5_EXT_CTRL (0x18024000 + 0x694)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) RXD Ring #1 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING6_EXT_CTRL (0x18024000 + 0x698)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) RXD Ring #2 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING7_EXT_CTRL (0x18024000 + 0x69C)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) RXD Ring #3 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING0_BKRS_CTRL0 (0x18024000 + 0xA00)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING0_BKRS_CTRL1 (0x18024000 + 0xA04)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING0_BKRS_CTRL2 (0x18024000 + 0xA08)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING0_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING1_BKRS_CTRL0 (0x18024000 + 0xA10)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING1_BKRS_CTRL1 (0x18024000 + 0xA14)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING1_BKRS_CTRL2 (0x18024000 + 0xA18)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING1_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING2_BKRS_CTRL0 (0x18024000 + 0xA20)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING2_BKRS_CTRL1 (0x18024000 + 0xA24)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING2_BKRS_CTRL2 (0x18024000 + 0xA28)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING2_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING3_BKRS_CTRL0 (0x18024000 + 0xA30)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING3_BKRS_CTRL1 (0x18024000 + 0xA34)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING3_BKRS_CTRL2 (0x18024000 + 0xA38)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_TX_RING3_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING0_BKRS_CTRL0 (0x18024000 + 0xC00)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING0_BKRS_CTRL1 (0x18024000 + 0xC04)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING0_BKRS_CTRL2 (0x18024000 + 0xC08)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING1_BKRS_CTRL0 (0x18024000 + 0xC10)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING1_BKRS_CTRL1 (0x18024000 + 0xC14)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING1_BKRS_CTRL2 (0x18024000 + 0xC18)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING2_BKRS_CTRL0 (0x18024000 + 0xC20)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING2_BKRS_CTRL1 (0x18024000 + 0xC24)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING2_BKRS_CTRL2 (0x18024000 + 0xC28)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING3_BKRS_CTRL0 (0x18024000 + 0xC30)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING3_BKRS_CTRL1 (0x18024000 + 0xC34)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING3_BKRS_CTRL2 (0x18024000 + 0xC38)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING3_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING4_BKRS_CTRL0 (0x18024000 + 0xC40)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING4_BKRS_CTRL1 (0x18024000 + 0xC44)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING4_BKRS_CTRL2 (0x18024000 + 0xC48)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING5_BKRS_CTRL0 (0x18024000 + 0xC50)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING5_BKRS_CTRL1 (0x18024000 + 0xC54)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING5_BKRS_CTRL2 (0x18024000 + 0xC58)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING6_BKRS_CTRL0 (0x18024000 + 0xC60)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING6_BKRS_CTRL1 (0x18024000 + 0xC64)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING6_BKRS_CTRL2 (0x18024000 + 0xC68)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING6_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING7_BKRS_CTRL0 (0x18024000 + 0xC70)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING7_BKRS_CTRL1 (0x18024000 + 0xC74)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING7_BKRS_CTRL2 (0x18024000 + 0xC78)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA0_WPDMA_RX_RING7_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +#ifdef __cplusplus +} +#endif + +#endif /* __WF_WFDMA_HOST_DMA0_REGS_H__ */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/soc3_0/wf_wfdma_host_dma1.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/soc3_0/wf_wfdma_host_dma1.h new file mode 100644 index 0000000000000000000000000000000000000000..38a666ca2d6fb942085a56276af6c386d7a5a579 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/coda/soc3_0/wf_wfdma_host_dma1.h @@ -0,0 +1,8328 @@ +/* [File] : wf_wfdma_host_dma1.h */ +/* [Revision time] : Mon Apr 15 14:14:46 2019 */ +/* [Description] : This file is auto generated by CODA */ +/* [Copyright] : Copyright (C) 2019 Mediatek Incorportion. All rights */ +/* reserved. */ + +#ifndef __WF_WFDMA_HOST_DMA1_REGS_H__ +#define __WF_WFDMA_HOST_DMA1_REGS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* ************************************************************************** */ +/* */ +/* WF_WFDMA_HOST_DMA1 CR Definitions */ +/* */ +/* ************************************************************************** */ + +#define WF_WFDMA_HOST_DMA1_BASE 0x7C025000 + +#define WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0XA0) /* 50A0 */ +#define WF_WFDMA_HOST_DMA1_HOST_IF_RX_DONE_STS_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0XA4) /* 50A4 */ +#define WF_WFDMA_HOST_DMA1_TX_DMAD_RNG_START_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x0B0) /* 50B0 */ +#define WF_WFDMA_HOST_DMA1_TX_DMAD_RNG_START_EXT_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x0B4) /* 50B4 */ +#define WF_WFDMA_HOST_DMA1_TX_DMAD_RNG_END_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x0B8) /* 50B8 */ +#define WF_WFDMA_HOST_DMA1_TX_DMAD_RNG_END_EXT_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x0BC) /* 50BC */ +#define WF_WFDMA_HOST_DMA1_RX_DMAD_RNG_START_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x0C0) /* 50C0 */ +#define WF_WFDMA_HOST_DMA1_RX_DMAD_RNG_START_EXT_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x0C4) /* 50C4 */ +#define WF_WFDMA_HOST_DMA1_RX_DMAD_RNG_END_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x0C8) /* 50C8 */ +#define WF_WFDMA_HOST_DMA1_RX_DMAD_RNG_END_EXT_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x0CC) /* 50CC */ +#define WF_WFDMA_HOST_DMA1_TX_PLD_RNG_START_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x0D0) /* 50D0 */ +#define WF_WFDMA_HOST_DMA1_TX_PLD_RNG_START_EXT_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x0D4) /* 50D4 */ +#define WF_WFDMA_HOST_DMA1_TX_PLD_RNG_END_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x0D8) /* 50D8 */ +#define WF_WFDMA_HOST_DMA1_TX_PLD_RNG_END_EXT_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x0DC) /* 50DC */ +#define WF_WFDMA_HOST_DMA1_RX_PLD_RNG_START_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x0E0) /* 50E0 */ +#define WF_WFDMA_HOST_DMA1_RX_PLD_RNG_START_EXT_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x0E4) /* 50E4 */ +#define WF_WFDMA_HOST_DMA1_RX_PLD_RNG_END_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x0E8) /* 50E8 */ +#define WF_WFDMA_HOST_DMA1_RX_PLD_RNG_END_EXT_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x0EC) /* 50EC */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_RST_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x100) /* 5100 */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_TOP_MISC_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x104) /* 5104 */ +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0X108) /* 5108 */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x10C) /* 510C */ +#define WF_WFDMA_HOST_DMA1_MCU_INT_STA_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0X110) /* 5110 */ +#define WF_WFDMA_HOST_DMA1_MCU_INT_ENA_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0X114) /* 5114 */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DUMMY_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x120) /* 5120 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_DBG_IDX_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x124) /* 5124 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_DBG_PROBE_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x128) /* 5128 */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_IDX_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x12C) /* 512C */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_PROBE_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x130) /* 5130 */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DMASHDL_DBG_PROBE_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x134) /* 5134 */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_STATUS_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x138) /* 5138 */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_ENA_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x13c) /* 513C */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_FIFO_TEST_MOD_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x140) /* 5140 */ +#define WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x1E8) /* 51E8 */ +#define WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x1EC) /* 51EC */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x1F0) /* 51F0 */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x1F4) /* 51F4 */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x1F8) /* 51F8 */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x1FC) /* 51FC */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x200) /* 5200 */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0X204) /* 5204 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x208) /* 5208 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x20C) /* 520C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_TX_Q_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x224) /* 5224 */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0X228) /* 5228 */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0X22C) /* 522C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x230) /* 5230 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_MISC_CFG_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x234) /* 5234 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_WRR_ARB_GBF0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x240) /* 5240 */ +#define WF_WFDMA_HOST_DMA1_MD_INT_STA_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x250) /* 5250 */ +#define WF_WFDMA_HOST_DMA1_MD_INT_ENA_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x254) /* 5254 */ +#define WF_WFDMA_HOST_DMA1_MCU2MD_SW_INT_SET_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x258) /* 5258 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH10_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x260) /* 5260 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH32_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x264) /* 5264 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH54_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x268) /* 5268 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH76_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x26C) /* 526C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DRX_PTR_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x280) /* 5280 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x284) /* 5284 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_EXT_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x288) /* 5288 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_INT_RX_PRI_SEL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x298) /* 5298 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x29C) /* 529C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_DBG0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x2A0) /* 52A0 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_DBG1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x2A4) /* 52A4 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_DBG0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x2A8) /* 52A8 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_DBG1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x2AC) /* 52AC */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x2B0) /* 52B0 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x2B4) /* 52B4 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x2C0) /* 52C0 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x2C4) /* 52C4 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x2C8) /* 52C8 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x2CC) /* 52CC */ +#define WF_WFDMA_HOST_DMA1_HOST_PRI_INT_STA_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x2E0) /* 52E0 */ +#define WF_WFDMA_HOST_DMA1_HOST_PER_INT_ENA_STA_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x2E4) /* 52E4 */ +#define WF_WFDMA_HOST_DMA1_HOST_PER_DLY_INT_CFG_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x2E8) /* 52E8 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x2F0) /* 52F0 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x300) /* 5300 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x304) /* 5304 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x308) /* 5308 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x30c) /* 530C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x310) /* 5310 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x314) /* 5314 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x318) /* 5318 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x31c) /* 531C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x320) /* 5320 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x324) /* 5324 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x328) /* 5328 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x32c) /* 532C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x330) /* 5330 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x334) /* 5334 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x338) /* 5338 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x33c) /* 533C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x340) /* 5340 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x344) /* 5344 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x348) /* 5348 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x34c) /* 534C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x350) /* 5350 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x354) /* 5354 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x358) /* 5358 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x35c) /* 535C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x360) /* 5360 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x364) /* 5364 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x368) /* 5368 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x36c) /* 536C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x370) /* 5370 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x374) /* 5374 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x378) /* 5378 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x37c) /* 537C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x380) /* 5380 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x384) /* 5384 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x388) /* 5388 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x38c) /* 538C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x390) /* 5390 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x394) /* 5394 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x398) /* 5398 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x39c) /* 539C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3a0) /* 53A0 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3a4) /* 53A4 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3a8) /* 53A8 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3ac) /* 53AC */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3b0) /* 53B0 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3b4) /* 53B4 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3b8) /* 53B8 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3bc) /* 53BC */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3c0) /* 53C0 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3c4) /* 53C4 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3c8) /* 53C8 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3cc) /* 53CC */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3d0) /* 53D0 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3d4) /* 53D4 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3d8) /* 53D8 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3dc) /* 53DC */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3e0) /* 53E0 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3e4) /* 53E4 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3e8) /* 53E8 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3ec) /* 53EC */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3f0) /* 53F0 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3f4) /* 53F4 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3f8) /* 53F8 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x3fc) /* 53FC */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x400) /* 5400 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x404) /* 5404 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x408) /* 5408 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x40c) /* 540C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x410) /* 5410 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x414) /* 5414 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x418) /* 5418 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x41c) /* 541C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x420) /* 5420 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x424) /* 5424 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x428) /* 5428 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x42c) /* 542C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x430) /* 5430 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x434) /* 5434 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x438) /* 5438 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x43c) /* 543C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x500) /* 5500 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x504) /* 5504 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x508) /* 5508 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x50c) /* 550C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x510) /* 5510 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x514) /* 5514 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x518) /* 5518 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x51c) /* 551C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x520) /* 5520 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x524) /* 5524 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x528) /* 5528 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x52C) /* 552C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x530) /* 5530 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x534) /* 5534 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x538) /* 5538 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL3_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x53C) /* 553C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x600) /* 5600 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x604) /* 5604 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x608) /* 5608 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x60C) /* 560C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x610) /* 5610 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x614) /* 5614 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x618) /* 5618 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x61C) /* 561C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x620) /* 5620 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x624) /* 5624 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x628) /* 5628 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x62C) /* 562C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x630) /* 5630 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x634) /* 5634 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x638) /* 5638 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x63C) /* 563C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x640) /* 5640 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x644) /* 5644 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x648) /* 5648 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x64C) /* 564C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x680) /* 5680 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x684) /* 5684 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x688) /* 5688 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_EXT_CTRL_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0x68C) /* 568C */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA00) /* 5A00 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA04) /* 5A04 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA08) /* 5A08 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA10) /* 5A10 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA14) /* 5A14 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA18) /* 5A18 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA20) /* 5A20 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA24) /* 5A24 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA28) /* 5A28 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA30) /* 5A30 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA34) /* 5A34 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA38) /* 5A38 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA40) /* 5A40 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA44) /* 5A44 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA48) /* 5A48 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA50) /* 5A50 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA54) /* 5A54 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA58) /* 5A58 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA60) /* 5A60 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA64) /* 5A64 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA68) /* 5A68 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA70) /* 5A70 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA74) /* 5A74 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA78) /* 5A78 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA80) /* 5A80 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA84) /* 5A84 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA88) /* 5A88 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA90) /* 5A90 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA94) /* 5A94 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xA98) /* 5A98 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xAA0) /* 5AA0 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xAA4) /* 5AA4 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xAA8) /* 5AA8 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xAB0) /* 5AB0 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xAB4) /* 5AB4 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xAB8) /* 5AB8 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xAC0) /* 5AC0 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xAC4) /* 5AC4 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xAC8) /* 5AC8 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xAD0) /* 5AD0 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xAD4) /* 5AD4 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xAD8) /* 5AD8 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xAE0) /* 5AE0 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xAE4) /* 5AE4 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xAE8) /* 5AE8 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xAF0) /* 5AF0 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xAF4) /* 5AF4 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xAF8) /* 5AF8 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xB00) /* 5B00 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xB04) /* 5B04 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xB08) /* 5B08 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xB10) /* 5B10 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xB14) /* 5B14 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xB18) /* 5B18 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xB20) /* 5B20 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xB24) /* 5B24 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xB28) /* 5B28 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xB30) /* 5B30 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xB34) /* 5B34 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xB38) /* 5B38 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xC00) /* 5C00 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xC04) /* 5C04 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xC08) /* 5C08 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xC10) /* 5C10 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xC14) /* 5C14 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xC18) /* 5C18 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xC20) /* 5C20 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xC24) /* 5C24 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xC28) /* 5C28 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL0_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xC30) /* 5C30 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL1_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xC34) /* 5C34 */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL2_ADDR \ + (WF_WFDMA_HOST_DMA1_BASE + 0xC38) /* 5C38 */ + +/* +* ---HOST_IF_TX_DONE_STS (0x18025000 + 0XA0)--- +* fifo_dfet_txdone_dat0_done_sts[0] - (W1C) USB DAT0 FIFO Tx status +* 0 : no tx done +* 1 : pdma fetch data from USB endpoint +buffer +* fifo_dfet_txdone_dat1_done_sts[1] - (W1C) USB DAT1 FIFO Tx status +* 0 : no tx done +* 1 : pdma fetch data from USB endpoint +buffer +* fifo_dfet_txdone_dat2_done_sts[2] - (W1C) USB DAT2 FIFO Tx status +* 0 : no tx done +* 1 : pdma fetch data from USB endpoint +buffer +* fifo_dfet_txdone_dat3_done_sts[3] - (W1C) USB DAT3 FIFO Tx status +* 0 : no tx done +* 1 : pdma fetch data from USB endpoint +buffer +* fifo_dfet_txdone_dat4_done_sts[4] - (W1C) USB DAT4 FIFO Tx status +* 0 : no tx done +* 1 : pdma fetch data from USB endpoint +buffer +* fifo_dfet_txdone_cmd_done_sts[5] - (W1C) USB CMD FIFO Tx status +* 0 : no tx done +* 1 : pdma fetch data from USB endpoint +buffer +* fifo_dfet_txdone_fwdl_done_sts[6] - (W1C) USB Firmware download FIFO Tx +status +* 0 : no tx done +* 1 : pdma fetch data from USB endpoint +buffer +* SDIO Mode (All SDIO Tx packet goto firmware +* download FIFO) +* 0 : no tx done +* 1 : pdma start to fetch data from SDIO +buffer +* RESERVED7[31..7] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_fwdl_done_sts_ADDR \ + \ + WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_ADDR +#define \ +WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_fwdl_done_sts_MASK \ + \ + 0x00000040 /* fifo_dfet_txdone_fwdl_done_sts[6] */ +#define \ +WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_fwdl_done_sts_SHFT \ + \ + 6 +#define \ +WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_cmd_done_sts_ADDR \ + \ + WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_ADDR +#define \ +WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_cmd_done_sts_MASK \ + \ + 0x00000020 /* fifo_dfet_txdone_cmd_done_sts[5] */ +#define \ +WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_cmd_done_sts_SHFT \ + \ + 5 +#define \ +WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat4_done_sts_ADDR \ + \ + WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_ADDR +#define \ +WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat4_done_sts_MASK \ + \ + 0x00000010 /* fifo_dfet_txdone_dat4_done_sts[4] */ +#define \ +WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat4_done_sts_SHFT \ + \ + 4 +#define \ +WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat3_done_sts_ADDR \ + \ + WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_ADDR +#define \ +WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat3_done_sts_MASK \ + \ + 0x00000008 /* fifo_dfet_txdone_dat3_done_sts[3] */ +#define \ +WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat3_done_sts_SHFT \ + \ + 3 +#define \ +WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat2_done_sts_ADDR \ + \ + WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_ADDR +#define \ +WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat2_done_sts_MASK \ + \ + 0x00000004 /* fifo_dfet_txdone_dat2_done_sts[2] */ +#define \ +WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat2_done_sts_SHFT \ + \ + 2 +#define \ +WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat1_done_sts_ADDR \ + \ + WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_ADDR +#define \ +WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat1_done_sts_MASK \ + \ + 0x00000002 /* fifo_dfet_txdone_dat1_done_sts[1] */ +#define \ +WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat1_done_sts_SHFT \ + \ + 1 +#define \ +WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat0_done_sts_ADDR \ + \ + WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_ADDR +#define \ +WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat0_done_sts_MASK \ + \ + 0x00000001 /* fifo_dfet_txdone_dat0_done_sts[0] */ +#define \ +WF_WFDMA_HOST_DMA1_HOST_IF_TX_DONE_STS_fifo_dfet_txdone_dat0_done_sts_SHFT \ + \ + 0 + +/* +* ---HOST_IF_RX_DONE_STS (0x18025000 + 0XA4)--- +* RESERVED0[0] - (RO) Reserved bits +* rx1_packet_done_sts[1] - (W1C) USB/SDIO Rx1 packet done status +* 0 : no rx packet done +* 1 : rx packet send to host interface +* Note : All SDIO Packet send to SIDO RX0 +port +* RESERVED2[31..2] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_HOST_IF_RX_DONE_STS_rx1_packet_done_sts_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_IF_RX_DONE_STS_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_IF_RX_DONE_STS_rx1_packet_done_sts_MASK \ + 0x00000002 /* rx1_packet_done_sts[1] */ +#define WF_WFDMA_HOST_DMA1_HOST_IF_RX_DONE_STS_rx1_packet_done_sts_SHFT 1 + +/* +* ---TX_DMAD_RNG_START (0x18025000 + 0x0B0)--- +* tx_dmad_rng_start[31..0] - (RW) TX DMAD address range start [31:0] +*/ +#define WF_WFDMA_HOST_DMA1_TX_DMAD_RNG_START_tx_dmad_rng_start_ADDR \ + WF_WFDMA_HOST_DMA1_TX_DMAD_RNG_START_ADDR +#define WF_WFDMA_HOST_DMA1_TX_DMAD_RNG_START_tx_dmad_rng_start_MASK \ + 0xFFFFFFFF /* tx_dmad_rng_start[31..0] */ +#define WF_WFDMA_HOST_DMA1_TX_DMAD_RNG_START_tx_dmad_rng_start_SHFT 0 + +/* +* ---TX_DMAD_RNG_START_EXT (0x18025000 + 0x0B4)--- +* tx_dmad_rng_start_ext[3..0] - (RW) TX DMAD address range start [35:32] +* RESERVED4[31..4] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_TX_DMAD_RNG_START_EXT_tx_dmad_rng_start_ext_ADDR \ + WF_WFDMA_HOST_DMA1_TX_DMAD_RNG_START_EXT_ADDR +#define WF_WFDMA_HOST_DMA1_TX_DMAD_RNG_START_EXT_tx_dmad_rng_start_ext_MASK \ + 0x0000000F /* tx_dmad_rng_start_ext[3..0] */ +#define WF_WFDMA_HOST_DMA1_TX_DMAD_RNG_START_EXT_tx_dmad_rng_start_ext_SHFT 0 + +/* +* ---TX_DMAD_RNG_END (0x18025000 + 0x0B8)--- +* tx_dmad_rng_end[31..0] - (RW) TX DMAD address range end [31:0] +*/ +#define WF_WFDMA_HOST_DMA1_TX_DMAD_RNG_END_tx_dmad_rng_end_ADDR \ + WF_WFDMA_HOST_DMA1_TX_DMAD_RNG_END_ADDR +#define WF_WFDMA_HOST_DMA1_TX_DMAD_RNG_END_tx_dmad_rng_end_MASK \ + 0xFFFFFFFF /* tx_dmad_rng_end[31..0] */ +#define WF_WFDMA_HOST_DMA1_TX_DMAD_RNG_END_tx_dmad_rng_end_SHFT 0 + +/* +* ---TX_DMAD_RNG_END_EXT (0x18025000 + 0x0BC)--- +* tx_dmad_rng_end_ext[3..0] - (RW) TX DMAD address range end [35:32] +* RESERVED4[31..4] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_TX_DMAD_RNG_END_EXT_tx_dmad_rng_end_ext_ADDR \ + WF_WFDMA_HOST_DMA1_TX_DMAD_RNG_END_EXT_ADDR +#define WF_WFDMA_HOST_DMA1_TX_DMAD_RNG_END_EXT_tx_dmad_rng_end_ext_MASK \ + 0x0000000F /* tx_dmad_rng_end_ext[3..0] */ +#define WF_WFDMA_HOST_DMA1_TX_DMAD_RNG_END_EXT_tx_dmad_rng_end_ext_SHFT 0 + +/* +* ---RX_DMAD_RNG_START (0x18025000 + 0x0C0)--- +* rx_dmad_rng_start[31..0] - (RW) RX DMAD address range start [31:0] +*/ +#define WF_WFDMA_HOST_DMA1_RX_DMAD_RNG_START_rx_dmad_rng_start_ADDR \ + WF_WFDMA_HOST_DMA1_RX_DMAD_RNG_START_ADDR +#define WF_WFDMA_HOST_DMA1_RX_DMAD_RNG_START_rx_dmad_rng_start_MASK \ + 0xFFFFFFFF /* rx_dmad_rng_start[31..0] */ +#define WF_WFDMA_HOST_DMA1_RX_DMAD_RNG_START_rx_dmad_rng_start_SHFT 0 + +/* +* ---RX_DMAD_RNG_START_EXT (0x18025000 + 0x0C4)--- +* rx_dmad_rng_start_ext[3..0] - (RW) RX DMAD address range start [35:32] +* RESERVED4[31..4] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_RX_DMAD_RNG_START_EXT_rx_dmad_rng_start_ext_ADDR \ + WF_WFDMA_HOST_DMA1_RX_DMAD_RNG_START_EXT_ADDR +#define WF_WFDMA_HOST_DMA1_RX_DMAD_RNG_START_EXT_rx_dmad_rng_start_ext_MASK \ + 0x0000000F /* rx_dmad_rng_start_ext[3..0] */ +#define WF_WFDMA_HOST_DMA1_RX_DMAD_RNG_START_EXT_rx_dmad_rng_start_ext_SHFT 0 + +/* +* ---RX_DMAD_RNG_END (0x18025000 + 0x0C8)--- +* rx_dmad_rng_end[31..0] - (RW) RX DMAD address range end [31:0] +*/ +#define WF_WFDMA_HOST_DMA1_RX_DMAD_RNG_END_rx_dmad_rng_end_ADDR \ + WF_WFDMA_HOST_DMA1_RX_DMAD_RNG_END_ADDR +#define WF_WFDMA_HOST_DMA1_RX_DMAD_RNG_END_rx_dmad_rng_end_MASK \ + 0xFFFFFFFF /* rx_dmad_rng_end[31..0] */ +#define WF_WFDMA_HOST_DMA1_RX_DMAD_RNG_END_rx_dmad_rng_end_SHFT 0 + +/* +* ---RX_DMAD_RNG_END_EXT (0x18025000 + 0x0CC)--- +* rx_dmad_rng_end_ext[3..0] - (RW) RX DMAD address range end [35:32] +* RESERVED4[31..4] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_RX_DMAD_RNG_END_EXT_rx_dmad_rng_end_ext_ADDR \ + WF_WFDMA_HOST_DMA1_RX_DMAD_RNG_END_EXT_ADDR +#define WF_WFDMA_HOST_DMA1_RX_DMAD_RNG_END_EXT_rx_dmad_rng_end_ext_MASK \ + 0x0000000F /* rx_dmad_rng_end_ext[3..0] */ +#define WF_WFDMA_HOST_DMA1_RX_DMAD_RNG_END_EXT_rx_dmad_rng_end_ext_SHFT 0 + +/* +* ---TX_PLD_RNG_START (0x18025000 + 0x0D0)--- +* tx_pld_rng_start[31..0] - (RW) TX PLD address range start [31:0] +*/ +#define WF_WFDMA_HOST_DMA1_TX_PLD_RNG_START_tx_pld_rng_start_ADDR \ + WF_WFDMA_HOST_DMA1_TX_PLD_RNG_START_ADDR +#define WF_WFDMA_HOST_DMA1_TX_PLD_RNG_START_tx_pld_rng_start_MASK \ + 0xFFFFFFFF /* tx_pld_rng_start[31..0] */ +#define WF_WFDMA_HOST_DMA1_TX_PLD_RNG_START_tx_pld_rng_start_SHFT 0 + +/* +* ---TX_PLD_RNG_START_EXT (0x18025000 + 0x0D4)--- +* tx_pld_rng_start_ext[3..0] - (RW) TX PLD address range start [35:32] +* RESERVED4[31..4] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_TX_PLD_RNG_START_EXT_tx_pld_rng_start_ext_ADDR \ + WF_WFDMA_HOST_DMA1_TX_PLD_RNG_START_EXT_ADDR +#define WF_WFDMA_HOST_DMA1_TX_PLD_RNG_START_EXT_tx_pld_rng_start_ext_MASK \ + 0x0000000F /* tx_pld_rng_start_ext[3..0] */ +#define WF_WFDMA_HOST_DMA1_TX_PLD_RNG_START_EXT_tx_pld_rng_start_ext_SHFT 0 + +/* +* ---TX_PLD_RNG_END (0x18025000 + 0x0D8)--- +* tx_pld_rng_end[31..0] - (RW) TX PLD address range end [31:0] +*/ +#define WF_WFDMA_HOST_DMA1_TX_PLD_RNG_END_tx_pld_rng_end_ADDR \ + WF_WFDMA_HOST_DMA1_TX_PLD_RNG_END_ADDR +#define WF_WFDMA_HOST_DMA1_TX_PLD_RNG_END_tx_pld_rng_end_MASK \ + 0xFFFFFFFF /* tx_pld_rng_end[31..0] */ +#define WF_WFDMA_HOST_DMA1_TX_PLD_RNG_END_tx_pld_rng_end_SHFT 0 + +/* +* ---TX_PLD_RNG_END_EXT (0x18025000 + 0x0DC)--- +* tx_pld_rng_end_ext[3..0] - (RW) TX PLD address range end [35:32] +* RESERVED4[31..4] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_TX_PLD_RNG_END_EXT_tx_pld_rng_end_ext_ADDR \ + WF_WFDMA_HOST_DMA1_TX_PLD_RNG_END_EXT_ADDR +#define WF_WFDMA_HOST_DMA1_TX_PLD_RNG_END_EXT_tx_pld_rng_end_ext_MASK \ + 0x0000000F /* tx_pld_rng_end_ext[3..0] */ +#define WF_WFDMA_HOST_DMA1_TX_PLD_RNG_END_EXT_tx_pld_rng_end_ext_SHFT 0 + +/* +* ---RX_PLD_RNG_START (0x18025000 + 0x0E0)--- +* rx_pld_rng_start[31..0] - (RW) RX PLD address range start [31:0] +*/ +#define WF_WFDMA_HOST_DMA1_RX_PLD_RNG_START_rx_pld_rng_start_ADDR \ + WF_WFDMA_HOST_DMA1_RX_PLD_RNG_START_ADDR +#define WF_WFDMA_HOST_DMA1_RX_PLD_RNG_START_rx_pld_rng_start_MASK \ + 0xFFFFFFFF /* rx_pld_rng_start[31..0] */ +#define WF_WFDMA_HOST_DMA1_RX_PLD_RNG_START_rx_pld_rng_start_SHFT 0 + +/* +* ---RX_PLD_RNG_START_EXT (0x18025000 + 0x0E4)--- +* rx_pld_rng_start_ext[3..0] - (RW) RX PLD address range start [35:32] +* RESERVED4[31..4] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_RX_PLD_RNG_START_EXT_rx_pld_rng_start_ext_ADDR \ + WF_WFDMA_HOST_DMA1_RX_PLD_RNG_START_EXT_ADDR +#define WF_WFDMA_HOST_DMA1_RX_PLD_RNG_START_EXT_rx_pld_rng_start_ext_MASK \ + 0x0000000F /* rx_pld_rng_start_ext[3..0] */ +#define WF_WFDMA_HOST_DMA1_RX_PLD_RNG_START_EXT_rx_pld_rng_start_ext_SHFT 0 + +/* +* ---RX_PLD_RNG_END (0x18025000 + 0x0E8)--- +* rx_pld_rng_end[31..0] - (RW) RX PLD address range end [31:0] +*/ +#define WF_WFDMA_HOST_DMA1_RX_PLD_RNG_END_rx_pld_rng_end_ADDR \ + WF_WFDMA_HOST_DMA1_RX_PLD_RNG_END_ADDR +#define WF_WFDMA_HOST_DMA1_RX_PLD_RNG_END_rx_pld_rng_end_MASK \ + 0xFFFFFFFF /* rx_pld_rng_end[31..0] */ +#define WF_WFDMA_HOST_DMA1_RX_PLD_RNG_END_rx_pld_rng_end_SHFT 0 + +/* +* ---RX_PLD_RNG_END_EXT (0x18025000 + 0x0EC)--- +* rx_pld_rng_end_ext[3..0] - (RW) RX PLD address range end [35:32] +* RESERVED4[31..4] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_RX_PLD_RNG_END_EXT_rx_pld_rng_end_ext_ADDR \ + WF_WFDMA_HOST_DMA1_RX_PLD_RNG_END_EXT_ADDR +#define WF_WFDMA_HOST_DMA1_RX_PLD_RNG_END_EXT_rx_pld_rng_end_ext_MASK \ + 0x0000000F /* rx_pld_rng_end_ext[3..0] */ +#define WF_WFDMA_HOST_DMA1_RX_PLD_RNG_END_EXT_rx_pld_rng_end_ext_SHFT 0 + +/* +* ---CONN_HIF_RST (0x18025000 + 0x100)--- +* RESERVED0[3..0] - (RO) Reserved bits +* conn_hif_logic_rst_n[4] - (RW) This conn_hif_logic_rst_n would reset +* wpdma logic partial control register, include Tx/Rx ring control. +* Also, conn_hif_logic_rst_n would reset wifi +* data path, include tx fifo, rx fifo, r2x_bridge, axi_mux and other other +* asynchronous bridge. +* (Note : conn_hif_logic_rst_n would not +* reset hif_dmashdl logic) +* dmashdl_all_rst_n[5] - (RW) This dmashdl_all_rst_n would reset +* hif_dmashdl_top, include logic and control register. +* RESERVED6[31..6] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_RST_dmashdl_all_rst_n_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_RST_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_RST_dmashdl_all_rst_n_MASK \ + 0x00000020 /* dmashdl_all_rst_n[5] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_RST_dmashdl_all_rst_n_SHFT 5 +#define WF_WFDMA_HOST_DMA1_CONN_HIF_RST_conn_hif_logic_rst_n_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_RST_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_RST_conn_hif_logic_rst_n_MASK \ + 0x00000010 /* conn_hif_logic_rst_n[4] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_RST_conn_hif_logic_rst_n_SHFT 4 + +/* +* ---CONN_HIF_TOP_MISC (0x18025000 + 0x104)--- +* ahb_mux_2to1_ultra[1..0] - (RW) conn _hif ahb mux ultra +* ahb_mux_2to1_qos_en[2] - (RW) conn_hif ahb mux qos enable +* RESERVED3[15..3] - (RO) Reserved bits +* pdma_rxring1_immint_en[16] - (RW) PDMA RX Ring 1 Immediate Interrupt +Enable +* RESERVED17[31..17] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_TOP_MISC_pdma_rxring1_immint_en_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_TOP_MISC_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_TOP_MISC_pdma_rxring1_immint_en_MASK \ + 0x00010000 /* pdma_rxring1_immint_en[16] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_TOP_MISC_pdma_rxring1_immint_en_SHFT 16 +#define WF_WFDMA_HOST_DMA1_CONN_HIF_TOP_MISC_ahb_mux_2to1_qos_en_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_TOP_MISC_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_TOP_MISC_ahb_mux_2to1_qos_en_MASK \ + 0x00000004 /* ahb_mux_2to1_qos_en[2] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_TOP_MISC_ahb_mux_2to1_qos_en_SHFT 2 +#define WF_WFDMA_HOST_DMA1_CONN_HIF_TOP_MISC_ahb_mux_2to1_ultra_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_TOP_MISC_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_TOP_MISC_ahb_mux_2to1_ultra_MASK \ + 0x00000003 /* ahb_mux_2to1_ultra[1..0] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_TOP_MISC_ahb_mux_2to1_ultra_SHFT 0 + +/* +* ---HOST2MCU_SW_INT_SET (0x18025000 + 0X108)--- +* host2mcu_sw_int_0_set[0] - (WO) Driver set this bit to generate MCU +* interrupt and 0x5000_0110[0] will be set to 1. +* host2mcu_sw_int_1_set[1] - (WO) Driver set this bit to generate MCU +* interrupt and 0x5000_0110[1] will be set to 1. +* host2mcu_sw_int_2_set[2] - (WO) Driver set this bit to generate MCU +* interrupt and 0x5000_0110[2] will be set to 1. +* host2mcu_sw_int_3_set[3] - (WO) Driver set [0x0_4108] bit[3] to generate +* MCU interrupt and 0x5000_0110[3] will be set to 1. +* host2mcu_sw_int_4_set[4] - (WO) Driver set [0x0_4108] bit[4] to generate +* MCU interrupt and 0x5000_0110[4] will be set to 1. +* host2mcu_sw_int_5_set[5] - (WO) Driver set [0x0_4108] bit[5] to generate +* MCU interrupt and 0x5000_0110[5] will be set to 1. +* host2mcu_sw_int_6_set[6] - (WO) Driver set [0x0_4108] bit[6] to generate +* MCU interrupt and 0x5000_0110[6] will be set to 1. +* host2mcu_sw_int_7_set[7] - (WO) Driver set [0x0_4108] bit[7] to generate +* MCU interrupt and 0x5000_0110[7] will be set to 1. +* RESERVED8[31..8] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_7_set_ADDR \ + WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_7_set_MASK \ + 0x00000080 /* host2mcu_sw_int_7_set[7] */ +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_7_set_SHFT 7 +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_6_set_ADDR \ + WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_6_set_MASK \ + 0x00000040 /* host2mcu_sw_int_6_set[6] */ +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_6_set_SHFT 6 +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_5_set_ADDR \ + WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_5_set_MASK \ + 0x00000020 /* host2mcu_sw_int_5_set[5] */ +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_5_set_SHFT 5 +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_4_set_ADDR \ + WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_4_set_MASK \ + 0x00000010 /* host2mcu_sw_int_4_set[4] */ +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_4_set_SHFT 4 +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_3_set_ADDR \ + WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_3_set_MASK \ + 0x00000008 /* host2mcu_sw_int_3_set[3] */ +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_3_set_SHFT 3 +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_2_set_ADDR \ + WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_2_set_MASK \ + 0x00000004 /* host2mcu_sw_int_2_set[2] */ +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_2_set_SHFT 2 +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_1_set_ADDR \ + WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_1_set_MASK \ + 0x00000002 /* host2mcu_sw_int_1_set[1] */ +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_1_set_SHFT 1 +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_0_set_ADDR \ + WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_0_set_MASK \ + 0x00000001 /* host2mcu_sw_int_0_set[0] */ +#define WF_WFDMA_HOST_DMA1_HOST2MCU_SW_INT_SET_host2mcu_sw_int_0_set_SHFT 0 + +/* +* ---MCU2HOST_SW_INT_SET (0x18025000 + 0x10C)--- +* mcu2host_sw_int_set_0[0] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[0] to check +* interrupt status +* mcu2host_sw_int_set_1[1] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[1] to check +* interrupt status +* mcu2host_sw_int_set_2[2] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[2] to check +* interrupt status +* mcu2host_sw_int_set_3[3] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[3] to check +* interrupt status +* mcu2host_sw_int_set_4[4] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[4] to check +* interrupt status +* mcu2host_sw_int_set_5[5] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[5] to check +* interrupt status +* mcu2host_sw_int_set_6[6] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[6] to check +* interrupt status +* mcu2host_sw_int_set_7[7] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[7] to check +* interrupt status +* mcu2host_sw_int_set_8[8] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[0] to check +* interrupt status +* mcu2host_sw_int_set_9[9] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[1] to check +* interrupt status +* mcu2host_sw_int_set_10[10] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[2] to check +* interrupt status +* mcu2host_sw_int_set_11[11] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[3] to check +* interrupt status +* mcu2host_sw_int_set_12[12] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[4] to check +* interrupt status +* mcu2host_sw_int_set_13[13] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[5] to check +* interrupt status +* mcu2host_sw_int_set_14[14] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[6] to check +* interrupt status +* mcu2host_sw_int_set_15[15] - (WO) Internal CPU writes this register will +* trigger MCU2HOST software interrupt interrupt to host. +* Host could read [0x0_41F0] bit[7] to check +* interrupt status +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_15_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_15_MASK \ + 0x00008000 /* mcu2host_sw_int_set_15[15] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_15_SHFT 15 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_14_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_14_MASK \ + 0x00004000 /* mcu2host_sw_int_set_14[14] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_14_SHFT 14 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_13_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_13_MASK \ + 0x00002000 /* mcu2host_sw_int_set_13[13] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_13_SHFT 13 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_12_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_12_MASK \ + 0x00001000 /* mcu2host_sw_int_set_12[12] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_12_SHFT 12 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_11_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_11_MASK \ + 0x00000800 /* mcu2host_sw_int_set_11[11] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_11_SHFT 11 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_10_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_10_MASK \ + 0x00000400 /* mcu2host_sw_int_set_10[10] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_10_SHFT 10 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_9_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_9_MASK \ + 0x00000200 /* mcu2host_sw_int_set_9[9] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_9_SHFT 9 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_8_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_8_MASK \ + 0x00000100 /* mcu2host_sw_int_set_8[8] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_8_SHFT 8 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_7_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_7_MASK \ + 0x00000080 /* mcu2host_sw_int_set_7[7] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_7_SHFT 7 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_6_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_6_MASK \ + 0x00000040 /* mcu2host_sw_int_set_6[6] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_6_SHFT 6 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_5_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_5_MASK \ + 0x00000020 /* mcu2host_sw_int_set_5[5] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_5_SHFT 5 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_4_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_4_MASK \ + 0x00000010 /* mcu2host_sw_int_set_4[4] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_4_SHFT 4 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_3_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_3_MASK \ + 0x00000008 /* mcu2host_sw_int_set_3[3] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_3_SHFT 3 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_2_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_2_MASK \ + 0x00000004 /* mcu2host_sw_int_set_2[2] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_2_SHFT 2 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_1_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_1_MASK \ + 0x00000002 /* mcu2host_sw_int_set_1[1] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_1_SHFT 1 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_0_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_0_MASK \ + 0x00000001 /* mcu2host_sw_int_set_0[0] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_SET_mcu2host_sw_int_set_0_SHFT 0 + +/* +* ---MCU_INT_STA (0x18025000 + 0X110)--- +* host2mcu_sw_int_sts[7..0] - (W1C) MCU interrupt status, write 1 to clear +* the interrupt +* wpdma_tx_timeout_int_sts[8] - (W1C) WPDMA TX dma timeout interrupt stauts, +* write 1 to clear the interrupt +* wpdma_rx_timeout_int_sts[9] - (W1C) WPDMA RX dma timeout interrupt stauts, +* write 1 to clear the interrupt +* wifi_txfifo0_wr_ovf_int_sts[10] - (W1C) conn_hif txfifo erorr detec +* interruptt. It indicate tx-fifo memory write overflow. +* wifi_txfifo1_wr_ovf_int_sts[11] - (W1C) conn_hif txfifo erorr detec +* interruptt. It indicate tx-fifo memory write overflow. +* wifi_rxfifo_wr_ovf_int_sts[12] - (W1C) conn_hif rxfifo erorr detect +* interrupt. It indicate rx-fifo memory write overflow. +* wpdma_tx_dmad_mem_range_err_mcu_int_sts[13] - (W1C) WPDMA tx dma descriptor +* memory range error detection mcu interrupt status +* When user setup WPDMA_TX_DMAD_RNG (not +* equal to zero), design would check tx_dmad address. If address range not +* correct, it would alarm memory range error interrupt +* wpdma_rx_dmad_mem_range_err_mcu_int_sts[14] - (W1C) WPDMA rx dma descriptor +* memory range error detection mcu interrupt status +* When user setup WPDMA_RX_DMAD_RNG (not +* equal to zero), design would check rx_dmad address. If address range not +* correct, it would alarm memory range error interrupt +* wpdma_tx_payload_mem_range_err_mcu_int_sts[15] - (W1C) WPDMA tx payload +* memory range error detection mcu interrupt status +* When user setup WPDMA_TX_PLD_RNG (not equal +* to zero), design would check tx_dma payload address. If address range not +* correct, it would alarm memory range error interrupt +* wpdma_rx_payload_mem_range_err_mcu_int_sts[16] - (W1C) WPDMA rx payload +* memory range error detection mcu interrupt status +* When user setup WPDMA_RX_PLD_RNG (not equal +* to zero), design would check rx_dma payload address. If address range not +* correct, it would alarm memory range error interrupt +* RESERVED17[31..17] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_STA_wpdma_rx_payload_mem_range_err_mcu_int_sts_ADDR \ + \ + WF_WFDMA_HOST_DMA1_MCU_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_STA_wpdma_rx_payload_mem_range_err_mcu_int_sts_MASK \ + \ + 0x00010000 /* wpdma_rx_payload_mem_range_err_mcu_int_sts[16] */ +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_STA_wpdma_rx_payload_mem_range_err_mcu_int_sts_SHFT \ + \ + 16 +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_STA_wpdma_tx_payload_mem_range_err_mcu_int_sts_ADDR \ + \ + WF_WFDMA_HOST_DMA1_MCU_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_STA_wpdma_tx_payload_mem_range_err_mcu_int_sts_MASK \ + \ + 0x00008000 /* wpdma_tx_payload_mem_range_err_mcu_int_sts[15] */ +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_STA_wpdma_tx_payload_mem_range_err_mcu_int_sts_SHFT \ + \ + 15 +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_STA_wpdma_rx_dmad_mem_range_err_mcu_int_sts_ADDR \ + \ + WF_WFDMA_HOST_DMA1_MCU_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_STA_wpdma_rx_dmad_mem_range_err_mcu_int_sts_MASK \ + \ + 0x00004000 /* wpdma_rx_dmad_mem_range_err_mcu_int_sts[14] */ +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_STA_wpdma_rx_dmad_mem_range_err_mcu_int_sts_SHFT \ + \ + 14 +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_STA_wpdma_tx_dmad_mem_range_err_mcu_int_sts_ADDR \ + \ + WF_WFDMA_HOST_DMA1_MCU_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_STA_wpdma_tx_dmad_mem_range_err_mcu_int_sts_MASK \ + \ + 0x00002000 /* wpdma_tx_dmad_mem_range_err_mcu_int_sts[13] */ +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_STA_wpdma_tx_dmad_mem_range_err_mcu_int_sts_SHFT \ + \ + 13 +#define WF_WFDMA_HOST_DMA1_MCU_INT_STA_wifi_rxfifo_wr_ovf_int_sts_ADDR \ + WF_WFDMA_HOST_DMA1_MCU_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU_INT_STA_wifi_rxfifo_wr_ovf_int_sts_MASK \ + 0x00001000 /* wifi_rxfifo_wr_ovf_int_sts[12] */ +#define WF_WFDMA_HOST_DMA1_MCU_INT_STA_wifi_rxfifo_wr_ovf_int_sts_SHFT 12 +#define WF_WFDMA_HOST_DMA1_MCU_INT_STA_wifi_txfifo1_wr_ovf_int_sts_ADDR \ + WF_WFDMA_HOST_DMA1_MCU_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU_INT_STA_wifi_txfifo1_wr_ovf_int_sts_MASK \ + 0x00000800 /* wifi_txfifo1_wr_ovf_int_sts[11] */ +#define WF_WFDMA_HOST_DMA1_MCU_INT_STA_wifi_txfifo1_wr_ovf_int_sts_SHFT 11 +#define WF_WFDMA_HOST_DMA1_MCU_INT_STA_wifi_txfifo0_wr_ovf_int_sts_ADDR \ + WF_WFDMA_HOST_DMA1_MCU_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU_INT_STA_wifi_txfifo0_wr_ovf_int_sts_MASK \ + 0x00000400 /* wifi_txfifo0_wr_ovf_int_sts[10] */ +#define WF_WFDMA_HOST_DMA1_MCU_INT_STA_wifi_txfifo0_wr_ovf_int_sts_SHFT 10 +#define WF_WFDMA_HOST_DMA1_MCU_INT_STA_wpdma_rx_timeout_int_sts_ADDR \ + WF_WFDMA_HOST_DMA1_MCU_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU_INT_STA_wpdma_rx_timeout_int_sts_MASK \ + 0x00000200 /* wpdma_rx_timeout_int_sts[9] */ +#define WF_WFDMA_HOST_DMA1_MCU_INT_STA_wpdma_rx_timeout_int_sts_SHFT 9 +#define WF_WFDMA_HOST_DMA1_MCU_INT_STA_wpdma_tx_timeout_int_sts_ADDR \ + WF_WFDMA_HOST_DMA1_MCU_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU_INT_STA_wpdma_tx_timeout_int_sts_MASK \ + 0x00000100 /* wpdma_tx_timeout_int_sts[8] */ +#define WF_WFDMA_HOST_DMA1_MCU_INT_STA_wpdma_tx_timeout_int_sts_SHFT 8 +#define WF_WFDMA_HOST_DMA1_MCU_INT_STA_host2mcu_sw_int_sts_ADDR \ + WF_WFDMA_HOST_DMA1_MCU_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU_INT_STA_host2mcu_sw_int_sts_MASK \ + 0x000000FF /* host2mcu_sw_int_sts[7..0] */ +#define WF_WFDMA_HOST_DMA1_MCU_INT_STA_host2mcu_sw_int_sts_SHFT 0 + +/* +* ---MCU_INT_ENA (0x18025000 + 0X114)--- +* host2mcu_sw_int_ena[7..0] - (RW) host2mcu interrupt enable +* wpdma_tx_dma_timeout_int_ena[8] - (RW) WPDMA TX error detection interrupt +enable +* wpdma_rx_dma_timeout_int_ena[9] - (RW) WPDMA RX error detection interrupt +enable +* wifi_txfifo0_wr_ovf_int_ena[10] - (RW) conn_hif txfifo erorr detect +* interrupt enable. +* wifi_txfifo1_wr_ovf_int_ena[11] - (RW) conn_hif txfifo erorr detect +* interrupt enable. +* wifi_rxfifo_wr_ovf_int_ena[12] - (RW) conn_hif rxfifo erorr detect interrupt +enable. +* wpdma_tx_dmad_mem_range_err_mcu_int_ena[13] - (RW) WPDMA tx dma descriptor +* memory range error detection interrupt enable +* wpdma_rx_dmad_mem_range_err_mcu_int_ena[14] - (RW) WPDMA rx dma descriptor +* memory range error detection interrupt enable +* wpdma_tx_payload_mem_range_err_mcu_int_ena[15] - (RW) WPDMA tx payload +* memory range error detection interrupt enable +* wpdma_rx_payload_mem_range_err_mcu_int_ena[16] - (RW) WPDMA rx payload +* memory range error detection interrupt enable +* RESERVED17[31..17] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wpdma_rx_payload_mem_range_err_mcu_int_ena_ADDR \ + \ + WF_WFDMA_HOST_DMA1_MCU_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wpdma_rx_payload_mem_range_err_mcu_int_ena_MASK \ + \ + 0x00010000 /* wpdma_rx_payload_mem_range_err_mcu_int_ena[16] */ +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wpdma_rx_payload_mem_range_err_mcu_int_ena_SHFT \ + \ + 16 +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wpdma_tx_payload_mem_range_err_mcu_int_ena_ADDR \ + \ + WF_WFDMA_HOST_DMA1_MCU_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wpdma_tx_payload_mem_range_err_mcu_int_ena_MASK \ + \ + 0x00008000 /* wpdma_tx_payload_mem_range_err_mcu_int_ena[15] */ +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wpdma_tx_payload_mem_range_err_mcu_int_ena_SHFT \ + \ + 15 +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wpdma_rx_dmad_mem_range_err_mcu_int_ena_ADDR \ + \ + WF_WFDMA_HOST_DMA1_MCU_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wpdma_rx_dmad_mem_range_err_mcu_int_ena_MASK \ + \ + 0x00004000 /* wpdma_rx_dmad_mem_range_err_mcu_int_ena[14] */ +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wpdma_rx_dmad_mem_range_err_mcu_int_ena_SHFT \ + \ + 14 +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wpdma_tx_dmad_mem_range_err_mcu_int_ena_ADDR \ + \ + WF_WFDMA_HOST_DMA1_MCU_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wpdma_tx_dmad_mem_range_err_mcu_int_ena_MASK \ + \ + 0x00002000 /* wpdma_tx_dmad_mem_range_err_mcu_int_ena[13] */ +#define \ +WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wpdma_tx_dmad_mem_range_err_mcu_int_ena_SHFT \ + \ + 13 +#define WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wifi_rxfifo_wr_ovf_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_MCU_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wifi_rxfifo_wr_ovf_int_ena_MASK \ + 0x00001000 /* wifi_rxfifo_wr_ovf_int_ena[12] */ +#define WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wifi_rxfifo_wr_ovf_int_ena_SHFT 12 +#define WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wifi_txfifo1_wr_ovf_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_MCU_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wifi_txfifo1_wr_ovf_int_ena_MASK \ + 0x00000800 /* wifi_txfifo1_wr_ovf_int_ena[11] */ +#define WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wifi_txfifo1_wr_ovf_int_ena_SHFT 11 +#define WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wifi_txfifo0_wr_ovf_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_MCU_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wifi_txfifo0_wr_ovf_int_ena_MASK \ + 0x00000400 /* wifi_txfifo0_wr_ovf_int_ena[10] */ +#define WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wifi_txfifo0_wr_ovf_int_ena_SHFT 10 +#define WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wpdma_rx_dma_timeout_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_MCU_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wpdma_rx_dma_timeout_int_ena_MASK \ + 0x00000200 /* wpdma_rx_dma_timeout_int_ena[9] */ +#define WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wpdma_rx_dma_timeout_int_ena_SHFT 9 +#define WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wpdma_tx_dma_timeout_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_MCU_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wpdma_tx_dma_timeout_int_ena_MASK \ + 0x00000100 /* wpdma_tx_dma_timeout_int_ena[8] */ +#define WF_WFDMA_HOST_DMA1_MCU_INT_ENA_wpdma_tx_dma_timeout_int_ena_SHFT 8 +#define WF_WFDMA_HOST_DMA1_MCU_INT_ENA_host2mcu_sw_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_MCU_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU_INT_ENA_host2mcu_sw_int_ena_MASK \ + 0x000000FF /* host2mcu_sw_int_ena[7..0] */ +#define WF_WFDMA_HOST_DMA1_MCU_INT_ENA_host2mcu_sw_int_ena_SHFT 0 + +/* +* ---CONN_HIF_DUMMY (0x18025000 + 0x120)--- +* CONN_HIF_DUMMY[31..0] - (RW) Reserved CR, SE will use it for pcie +calibration! +*/ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DUMMY_CONN_HIF_DUMMY_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_DUMMY_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DUMMY_CONN_HIF_DUMMY_MASK \ + 0xFFFFFFFF /* CONN_HIF_DUMMY[31..0] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DUMMY_CONN_HIF_DUMMY_SHFT 0 + +/* +* ---WPDMA_DBG_IDX (0x18025000 + 0x124)--- +* PDMA_DBG_IDX[7..0] - (RW) PDMA debug index +* PDMA_DBG_Enable[8] - (RW) PDMA Debug Enable +* 0: PDMA_DBG_port would has no function +* 1 : PDMA DBG_IDX select PDMA debug flag +index +* RESERVED9[31..9] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_DBG_IDX_PDMA_DBG_Enable_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_DBG_IDX_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_DBG_IDX_PDMA_DBG_Enable_MASK \ + 0x00000100 /* PDMA_DBG_Enable[8] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_DBG_IDX_PDMA_DBG_Enable_SHFT 8 +#define WF_WFDMA_HOST_DMA1_WPDMA_DBG_IDX_PDMA_DBG_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_DBG_IDX_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_DBG_IDX_PDMA_DBG_IDX_MASK \ + 0x000000FF /* PDMA_DBG_IDX[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_DBG_IDX_PDMA_DBG_IDX_SHFT 0 + +/* +* ---WPDMA_DBG_PROBE (0x18025000 + 0x128)--- +* PDMA_DBG_PROBE[31..0] - (RO) PDMA Debug probe read +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_DBG_PROBE_PDMA_DBG_PROBE_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_DBG_PROBE_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_DBG_PROBE_PDMA_DBG_PROBE_MASK \ + 0xFFFFFFFF /* PDMA_DBG_PROBE[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_DBG_PROBE_PDMA_DBG_PROBE_SHFT 0 + +/* +* ---CONN_HIF_DBG_IDX (0x18025000 + 0x12C)--- +* conn_hif_dbg_byt0_sel[2..0] - (RW) conn_hif_dbg_byt0_sel : Select +* conn_hif_dbg[7:0] from "pdma_dbg"/"hif_dmashdl_top" +* conn_hif_dbg_byt1_sel[5..3] - (RW) conn_hif_dbg_byt1_sel : Select +* conn_hif_dbg[15:8] from "pdma_dbg"/"hif_dmashdl_top" +* conn_hif_dbg_byt2_sel[8..6] - (RW) conn_hif_dbg_byt2_sel : Select +* conn_hif_dbg[23:16] from "pdma_dbg"/"hif_dmashdl_top" +* conn_hif_dbg_byt3_sel[11..9] - (RW) conn_hif_dbg_byt3_sel : Select +* conn_hif_dbg[31:24] from "pdma_dbg"/"hif_dmashdl_top" +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_IDX_conn_hif_dbg_byt3_sel_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_IDX_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_IDX_conn_hif_dbg_byt3_sel_MASK \ + 0x00000E00 /* conn_hif_dbg_byt3_sel[11..9] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_IDX_conn_hif_dbg_byt3_sel_SHFT 9 +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_IDX_conn_hif_dbg_byt2_sel_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_IDX_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_IDX_conn_hif_dbg_byt2_sel_MASK \ + 0x000001C0 /* conn_hif_dbg_byt2_sel[8..6] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_IDX_conn_hif_dbg_byt2_sel_SHFT 6 +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_IDX_conn_hif_dbg_byt1_sel_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_IDX_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_IDX_conn_hif_dbg_byt1_sel_MASK \ + 0x00000038 /* conn_hif_dbg_byt1_sel[5..3] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_IDX_conn_hif_dbg_byt1_sel_SHFT 3 +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_IDX_conn_hif_dbg_byt0_sel_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_IDX_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_IDX_conn_hif_dbg_byt0_sel_MASK \ + 0x00000007 /* conn_hif_dbg_byt0_sel[2..0] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_IDX_conn_hif_dbg_byt0_sel_SHFT 0 + +/* +* ---CONN_HIF_DBG_PROBE (0x18025000 + 0x130)--- +* conn_hif_dbg_probe[31..0] - (RO) conn_hif_dbg_probe read +*/ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_PROBE_conn_hif_dbg_probe_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_PROBE_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_PROBE_conn_hif_dbg_probe_MASK \ + 0xFFFFFFFF /* conn_hif_dbg_probe[31..0] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DBG_PROBE_conn_hif_dbg_probe_SHFT 0 + +/* +* ---CONN_HIF_DMASHDL_DBG_PROBE (0x18025000 + 0x134)--- +* DMASHDL_DBG_PROBE[15..0] - (RO) conn_hif_dmashdl_dbg_probe read +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DMASHDL_DBG_PROBE_DMASHDL_DBG_PROBE_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_DMASHDL_DBG_PROBE_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DMASHDL_DBG_PROBE_DMASHDL_DBG_PROBE_MASK \ + 0x0000FFFF /* DMASHDL_DBG_PROBE[15..0] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_DMASHDL_DBG_PROBE_DMASHDL_DBG_PROBE_SHFT 0 + +/* +* ---CONN_HIF_BUSY_STATUS (0x18025000 + 0x138)--- +* conn_hif_txfifo0_busy[0] - (RO) conn_hif txfifo0 busy status +* 0 : txfifo empty +* 1 : txfifo non empty +* conn_hif_txfifo1_busy[1] - (RO) conn_hif txfifo1 busy status +* 0 : txfifo empty +* 1 : txfifo non empty +* conn_hif_rxfifo_busy[2] - (RO) conn_hif rxfifo busy status +* 0 : rxfifo empty +* 1 : rxfifo non empty +* RESERVED[30..3] - (RO) Reserved CR +* conn_hif_busy[31] - (RO) Over all conn_hif busy status, it was +* busy summation of bit[6] ~ bit[0] status +*/ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_STATUS_conn_hif_busy_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_STATUS_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_STATUS_conn_hif_busy_MASK \ + 0x80000000 /* conn_hif_busy[31] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_STATUS_conn_hif_busy_SHFT 31 +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_STATUS_conn_hif_rxfifo_busy_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_STATUS_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_STATUS_conn_hif_rxfifo_busy_MASK \ + 0x00000004 /* conn_hif_rxfifo_busy[2] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_STATUS_conn_hif_rxfifo_busy_SHFT 2 +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_STATUS_conn_hif_txfifo1_busy_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_STATUS_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_STATUS_conn_hif_txfifo1_busy_MASK \ + 0x00000002 /* conn_hif_txfifo1_busy[1] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_STATUS_conn_hif_txfifo1_busy_SHFT 1 +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_STATUS_conn_hif_txfifo0_busy_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_STATUS_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_STATUS_conn_hif_txfifo0_busy_MASK \ + 0x00000001 /* conn_hif_txfifo0_busy[0] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_STATUS_conn_hif_txfifo0_busy_SHFT 0 + +/* +* ---CONN_HIF_BUSY_ENA (0x18025000 + 0x13c)--- +* conn_hif_txfifo0_busy_enable[0] - (RW) busy enable control +* 0: ignore busy status +* 1: conn_hif_busy would tack care busy +status +* conn_hif_txfifo1_busy_enable[1] - (RW) busy enable control +* 0: ignore busy status +* 1: conn_hif_busy would tack care busy +status +* conn_hif_rxfifo_busy_enable[2] - (RW) busy enable control +* 0: ignore busy status +* 1: conn_hif_busy would tack care busy +status +* RESERVED3[4..3] - (RO) Reserved bits +* RESERVED[31..5] - (RW) Reserved CR +*/ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_ENA_conn_hif_rxfifo_busy_enable_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_ENA_conn_hif_rxfifo_busy_enable_MASK \ + 0x00000004 /* conn_hif_rxfifo_busy_enable[2] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_ENA_conn_hif_rxfifo_busy_enable_SHFT 2 +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_ENA_conn_hif_txfifo1_busy_enable_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_ENA_conn_hif_txfifo1_busy_enable_MASK \ + 0x00000002 /* conn_hif_txfifo1_busy_enable[1] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_ENA_conn_hif_txfifo1_busy_enable_SHFT 1 +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_ENA_conn_hif_txfifo0_busy_enable_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_ENA_conn_hif_txfifo0_busy_enable_MASK \ + 0x00000001 /* conn_hif_txfifo0_busy_enable[0] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_BUSY_ENA_conn_hif_txfifo0_busy_enable_SHFT 0 + +/* +* ---CONN_HIF_FIFO_TEST_MOD (0x18025000 + 0x140)--- +* csr_wfdma_loopback_en[0] - (RW) conn_hif fifo loopback enable +* NOTICE : when loopback, OMIT_TX_INFO and +* OMIT_RX_INFO sould be both set to 1'b1 +* csr_wfdma_loopback_qsel[2..1] - (RW) No USE for (conn_hif fifo loopback +* packet go into Rx-ring number) +* RESERVED3[31..3] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_FIFO_TEST_MOD_csr_wfdma_loopback_qsel_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_FIFO_TEST_MOD_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_FIFO_TEST_MOD_csr_wfdma_loopback_qsel_MASK \ + 0x00000006 /* csr_wfdma_loopback_qsel[2..1] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_FIFO_TEST_MOD_csr_wfdma_loopback_qsel_SHFT 1 +#define WF_WFDMA_HOST_DMA1_CONN_HIF_FIFO_TEST_MOD_csr_wfdma_loopback_en_ADDR \ + WF_WFDMA_HOST_DMA1_CONN_HIF_FIFO_TEST_MOD_ADDR +#define WF_WFDMA_HOST_DMA1_CONN_HIF_FIFO_TEST_MOD_csr_wfdma_loopback_en_MASK \ + 0x00000001 /* csr_wfdma_loopback_en[0] */ +#define WF_WFDMA_HOST_DMA1_CONN_HIF_FIFO_TEST_MOD_csr_wfdma_loopback_en_SHFT 0 + +/* +* ---WPDMA2HOST_ERR_INT_STA (0x18025000 + 0x1E8)--- +* wpdma_tx_timeout_int_sts[0] - (W1C) WPDMA TX error detection interrupt +* stauts, write 1 to clear the interrupt +* wpdma_rx_timeout_int_sts[1] - (W1C) WPDMA RX error detection interrupt +* stauts, write 1 to clear the interrupt +* RESERVED2[31..2] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_wpdma_rx_timeout_int_sts_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_wpdma_rx_timeout_int_sts_MASK \ + \ + 0x00000002 /* wpdma_rx_timeout_int_sts[1] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_wpdma_rx_timeout_int_sts_SHFT \ + \ + 1 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_wpdma_tx_timeout_int_sts_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_wpdma_tx_timeout_int_sts_MASK \ + \ + 0x00000001 /* wpdma_tx_timeout_int_sts[0] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_STA_wpdma_tx_timeout_int_sts_SHFT \ + \ + 0 + +/* +* ---WPDMA2HOST_ERR_INT_ENA (0x18025000 + 0x1EC)--- +* wpdma_rx_timeout_int_ena[0] - (RW) WPDMA TX error detection interrupt +enable +* wpdma_tx_timeout_int_ena[1] - (RW) WPDMA RX error detection interrupt +enable +* RESERVED2[31..2] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_wpdma_tx_timeout_int_ena_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_wpdma_tx_timeout_int_ena_MASK \ + \ + 0x00000002 /* wpdma_tx_timeout_int_ena[1] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_wpdma_tx_timeout_int_ena_SHFT \ + \ + 1 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_wpdma_rx_timeout_int_ena_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_wpdma_rx_timeout_int_ena_MASK \ + \ + 0x00000001 /* wpdma_rx_timeout_int_ena[0] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA2HOST_ERR_INT_ENA_wpdma_rx_timeout_int_ena_SHFT \ + \ + 0 + +/* +* ---MCU2HOST_SW_INT_STA (0x18025000 + 0x1F0)--- +* mcu2host_sw_int_0[0] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_1[1] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_2[2] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_3[3] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_4[4] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_5[5] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_6[6] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_7[7] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_8[8] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_9[9] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_10[10] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_11[11] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_12[12] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_13[13] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_14[14] - (W1C) mcu2host interrupt status +* mcu2host_sw_int_15[15] - (W1C) mcu2host interrupt status +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_15_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_15_MASK \ + 0x00008000 /* mcu2host_sw_int_15[15] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_15_SHFT 15 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_14_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_14_MASK \ + 0x00004000 /* mcu2host_sw_int_14[14] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_14_SHFT 14 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_13_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_13_MASK \ + 0x00002000 /* mcu2host_sw_int_13[13] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_13_SHFT 13 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_12_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_12_MASK \ + 0x00001000 /* mcu2host_sw_int_12[12] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_12_SHFT 12 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_11_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_11_MASK \ + 0x00000800 /* mcu2host_sw_int_11[11] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_11_SHFT 11 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_10_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_10_MASK \ + 0x00000400 /* mcu2host_sw_int_10[10] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_10_SHFT 10 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_9_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_9_MASK \ + 0x00000200 /* mcu2host_sw_int_9[9] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_9_SHFT 9 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_8_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_8_MASK \ + 0x00000100 /* mcu2host_sw_int_8[8] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_8_SHFT 8 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_7_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_7_MASK \ + 0x00000080 /* mcu2host_sw_int_7[7] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_7_SHFT 7 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_6_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_6_MASK \ + 0x00000040 /* mcu2host_sw_int_6[6] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_6_SHFT 6 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_5_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_5_MASK \ + 0x00000020 /* mcu2host_sw_int_5[5] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_5_SHFT 5 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_4_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_4_MASK \ + 0x00000010 /* mcu2host_sw_int_4[4] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_4_SHFT 4 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_3_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_3_MASK \ + 0x00000008 /* mcu2host_sw_int_3[3] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_3_SHFT 3 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_2_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_2_MASK \ + 0x00000004 /* mcu2host_sw_int_2[2] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_2_SHFT 2 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_1_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_1_MASK \ + 0x00000002 /* mcu2host_sw_int_1[1] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_1_SHFT 1 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_0_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_0_MASK \ + 0x00000001 /* mcu2host_sw_int_0[0] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_STA_mcu2host_sw_int_0_SHFT 0 + +/* +* ---MCU2HOST_SW_INT_ENA (0x18025000 + 0x1F4)--- +* mcu2host_int_ena_0[0] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_1[1] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_2[2] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_3[3] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_4[4] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_5[5] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_6[6] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_7[7] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_8[8] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_9[9] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_10[10] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_11[11] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_12[12] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_13[13] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_14[14] - (RW) MCU2HOST software interrupt interrupt +enable +* mcu2host_int_ena_15[15] - (RW) MCU2HOST software interrupt interrupt +enable +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_15_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_15_MASK \ + 0x00008000 /* mcu2host_int_ena_15[15] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_15_SHFT 15 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_14_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_14_MASK \ + 0x00004000 /* mcu2host_int_ena_14[14] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_14_SHFT 14 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_13_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_13_MASK \ + 0x00002000 /* mcu2host_int_ena_13[13] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_13_SHFT 13 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_12_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_12_MASK \ + 0x00001000 /* mcu2host_int_ena_12[12] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_12_SHFT 12 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_11_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_11_MASK \ + 0x00000800 /* mcu2host_int_ena_11[11] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_11_SHFT 11 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_10_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_10_MASK \ + 0x00000400 /* mcu2host_int_ena_10[10] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_10_SHFT 10 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_9_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_9_MASK \ + 0x00000200 /* mcu2host_int_ena_9[9] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_9_SHFT 9 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_8_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_8_MASK \ + 0x00000100 /* mcu2host_int_ena_8[8] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_8_SHFT 8 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_7_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_7_MASK \ + 0x00000080 /* mcu2host_int_ena_7[7] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_7_SHFT 7 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_6_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_6_MASK \ + 0x00000040 /* mcu2host_int_ena_6[6] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_6_SHFT 6 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_5_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_5_MASK \ + 0x00000020 /* mcu2host_int_ena_5[5] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_5_SHFT 5 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_4_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_4_MASK \ + 0x00000010 /* mcu2host_int_ena_4[4] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_4_SHFT 4 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_3_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_3_MASK \ + 0x00000008 /* mcu2host_int_ena_3[3] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_3_SHFT 3 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_2_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_2_MASK \ + 0x00000004 /* mcu2host_int_ena_2[2] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_2_SHFT 2 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_1_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_1_MASK \ + 0x00000002 /* mcu2host_int_ena_1[1] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_1_SHFT 1 +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_0_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_0_MASK \ + 0x00000001 /* mcu2host_int_ena_0[0] */ +#define WF_WFDMA_HOST_DMA1_MCU2HOST_SW_INT_ENA_mcu2host_int_ena_0_SHFT 0 + +/* +* ---SUBSYS2HOST_INT_STA (0x18025000 + 0x1F8)--- +* mac_int_sts_0[0] - (RO) MAC interrupt 0: Band0 TBTT +* interrupt(Check wf_int_wakeup_top/hwisr0 [0x820Fc03c]) +* 0 : no interrupt +* 1 : interrupt assert +* mac_int_sts_1[1] - (RO) MAC interrupt 1: Band0 Pre-TBTT +* interrupt(Check wf_int_wakeup_top/hwisr1 [0x820Fc044]) +* 0 : no interrupt +* 1 : interrupt assert +* mac_int_sts_2[2] - (RO) MAC interrupt 2: Band0 TX status +* interrupt(Check wf_int_wakeup_top/hwisr2 [0x820Fc04c]) +* 0 : no interrupt +* 1 : interrupt assert +* mac_int_sts_3[3] - (RO) MAC interrupt 3: Band0 Auto wakeup +* interrupt (Check wf_int_wakeup_top/hwisr3 [0x820Fc054]) +* 0 : no interrupt +* 1 : interrupt assert +* mac_int_sts_4[4] - (RO) MAC interrupt 4: Band0 GP timer +* interrupt (Check wf_int_wakeup_top/hwisr4 [0x820Fc05c]) +* 0 : no interrupt +* 1 : interrupt assert +* RESERVED5[7..5] - (RO) Reserved bits +* conn_hif_on_host_int_sts[8] - (RO) CONN_HIF_ON interrupt enable +* 0 : no conn_hif_on_host_int interrupt +* 1 : conn_hif_on_host_int interrupt assert. +* User should check conn_hif_on (host_csr) interrupt status and clear interrupt. +* conn2ap_sw_irq_sts[9] - (RO) MCUSYS conn2ap_sw_irq status (Check +* conn_mcu_config/EMI_CTL [0x80000150] bit[4:0]) +* 0 : no conn2ap_sw_irq interrupt. +* 1 : conn2ap_sw_irq interrupt assert. User +* should check mcusys_n9 interrupt status and clear interrupt. +* (conn_mcu_config/EMI_CTL [0x80000150] bit[4:0] != 0) +* dmashdl_int_sts[10] - (RO) DMASHDL error interrupt +* 0 : no interrupt +* 1 : interrupt assert +* mac_int_sts_5[11] - (RO) MAC interrupt 5: Band1 TBTT +* interrupt(Check wf_int_wakeup_top/hwisr0 [0x820Fc03c]) +* 0 : no interrupt +* 1 : interrupt assert +* mac_int_sts_6[12] - (RO) MAC interrupt 6: Band1 Pre-TBTT +* interrupt(Check wf_int_wakeup_top/hwisr1 [0x820Fc044]) +* 0 : no interrupt +* 1 : interrupt assert +* mac_int_sts_7[13] - (RO) MAC interrupt 7: Band1 TX status +* interrupt(Check wf_int_wakeup_top/hwisr2 [0x820Fc04c]) +* 0 : no interrupt +* 1 : interrupt assert +* mac_int_sts_8[14] - (RO) MAC interrupt 8: Band1 Auto wakeup +* interrupt (Check wf_int_wakeup_top/hwisr3 [0x820Fc054]) +* 0 : no interrupt +* 1 : interrupt assert +* mac_int_sts_9[15] - (RO) MAC interrupt 9: Band1 GP timer +* interrupt (Check wf_int_wakeup_top/hwisr4 [0x820Fc05c]) +* 0 : no interrupt +* 1 : interrupt assert +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_9_ADDR \ + WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_9_MASK \ + 0x00008000 /* mac_int_sts_9[15] */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_9_SHFT 15 +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_8_ADDR \ + WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_8_MASK \ + 0x00004000 /* mac_int_sts_8[14] */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_8_SHFT 14 +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_7_ADDR \ + WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_7_MASK \ + 0x00002000 /* mac_int_sts_7[13] */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_7_SHFT 13 +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_6_ADDR \ + WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_6_MASK \ + 0x00001000 /* mac_int_sts_6[12] */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_6_SHFT 12 +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_5_ADDR \ + WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_5_MASK \ + 0x00000800 /* mac_int_sts_5[11] */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_5_SHFT 11 +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_dmashdl_int_sts_ADDR \ + WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_dmashdl_int_sts_MASK \ + 0x00000400 /* dmashdl_int_sts[10] */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_dmashdl_int_sts_SHFT 10 +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_conn2ap_sw_irq_sts_ADDR \ + WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_conn2ap_sw_irq_sts_MASK \ + 0x00000200 /* conn2ap_sw_irq_sts[9] */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_conn2ap_sw_irq_sts_SHFT 9 +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_conn_hif_on_host_int_sts_ADDR \ + WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_conn_hif_on_host_int_sts_MASK \ + 0x00000100 /* conn_hif_on_host_int_sts[8] */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_conn_hif_on_host_int_sts_SHFT 8 +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_4_ADDR \ + WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_4_MASK \ + 0x00000010 /* mac_int_sts_4[4] */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_4_SHFT 4 +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_3_ADDR \ + WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_3_MASK \ + 0x00000008 /* mac_int_sts_3[3] */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_3_SHFT 3 +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_2_ADDR \ + WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_2_MASK \ + 0x00000004 /* mac_int_sts_2[2] */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_2_SHFT 2 +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_1_ADDR \ + WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_1_MASK \ + 0x00000002 /* mac_int_sts_1[1] */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_1_SHFT 1 +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_0_ADDR \ + WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_0_MASK \ + 0x00000001 /* mac_int_sts_0[0] */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_STA_mac_int_sts_0_SHFT 0 + +/* +* ---SUBSYS2HOST_INT_ENA (0x18025000 + 0x1FC)--- +* mac_int_ena_0[0] - (RW) MAC interrupt enable +* mac_int_ena_1[1] - (RW) MAC interrupt enable +* mac_int_ena_2[2] - (RW) MAC interrupt enable +* mac_int_ena_3[3] - (RW) MAC interrupt enable +* mac_int_ena_4[4] - (RW) MAC interrupt enable +* RESERVED5[7..5] - (RO) Reserved bits +* conn_hif_on_host_int_ena[8] - (RW) CONN_HIF_ON interrupt enable +* conn2ap_sw_irq_ena[9] - (RW) MCUSYS conn2ap_sw_irq enable +* dmashdl_int_ena[10] - (RW) DMASHDL interrupt enable +* mac_int_ena_5[11] - (RW) MAC interrupt enable +* mac_int_ena_6[12] - (RW) MAC interrupt enable +* mac_int_ena_7[13] - (RW) MAC interrupt enable +* mac_int_ena_8[14] - (RW) MAC interrupt enable +* mac_int_ena_9[15] - (RW) MAC interrupt enable +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_9_ADDR \ + WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_9_MASK \ + 0x00008000 /* mac_int_ena_9[15] */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_9_SHFT 15 +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_8_ADDR \ + WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_8_MASK \ + 0x00004000 /* mac_int_ena_8[14] */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_8_SHFT 14 +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_7_ADDR \ + WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_7_MASK \ + 0x00002000 /* mac_int_ena_7[13] */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_7_SHFT 13 +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_6_ADDR \ + WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_6_MASK \ + 0x00001000 /* mac_int_ena_6[12] */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_6_SHFT 12 +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_5_ADDR \ + WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_5_MASK \ + 0x00000800 /* mac_int_ena_5[11] */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_5_SHFT 11 +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_dmashdl_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_dmashdl_int_ena_MASK \ + 0x00000400 /* dmashdl_int_ena[10] */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_dmashdl_int_ena_SHFT 10 +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_conn2ap_sw_irq_ena_ADDR \ + WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_conn2ap_sw_irq_ena_MASK \ + 0x00000200 /* conn2ap_sw_irq_ena[9] */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_conn2ap_sw_irq_ena_SHFT 9 +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_conn_hif_on_host_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_conn_hif_on_host_int_ena_MASK \ + 0x00000100 /* conn_hif_on_host_int_ena[8] */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_conn_hif_on_host_int_ena_SHFT 8 +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_4_ADDR \ + WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_4_MASK \ + 0x00000010 /* mac_int_ena_4[4] */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_4_SHFT 4 +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_3_ADDR \ + WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_3_MASK \ + 0x00000008 /* mac_int_ena_3[3] */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_3_SHFT 3 +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_2_ADDR \ + WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_2_MASK \ + 0x00000004 /* mac_int_ena_2[2] */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_2_SHFT 2 +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_1_ADDR \ + WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_1_MASK \ + 0x00000002 /* mac_int_ena_1[1] */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_1_SHFT 1 +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_0_ADDR \ + WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_0_MASK \ + 0x00000001 /* mac_int_ena_0[0] */ +#define WF_WFDMA_HOST_DMA1_SUBSYS2HOST_INT_ENA_mac_int_ena_0_SHFT 0 + +/* +* ---HOST_INT_STA (0x18025000 + 0x200)--- +* rx_done_int_sts_0[0] - (W1C) RX Queue#0 packet receive interrupt +* Write 1 to clear the interrupt +* Read to get the raw interrupt status +* rx_done_int_sts_1[1] - (W1C) RX Queue#1 packet receive interrupt +* Write 1 to clear the interrupt +* Read to get the raw interrupt status +* rx_done_int_sts_2[2] - (W1C) RX Queue#2 packet receive interrupt +* Write 1 to clear the interrupt +* Read to get the raw interrupt status +* rx_done_int_sts_3[3] - (W1C) RX Queue#3 packet receive interrupt +* Write 1 to clear the interrupt +* Read to get the raw interrupt status +* tx_done_int_sts_0[4] - (W1C) TX Queue#0 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_1[5] - (W1C) TX Queue#1 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_2[6] - (W1C) TX Queue#2 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_3[7] - (W1C) TX Queue#3 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_4[8] - (W1C) TX Queue#4 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_5[9] - (W1C) TX Queue#5 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_6[10] - (W1C) TX Queue#6 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_7[11] - (W1C) TX Queue#7 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_8[12] - (W1C) TX Queue#8 packet transmit +* interruptWrite 1 to clear the interrupt +* tx_done_int_sts_9[13] - (W1C) TX Queue#9 packet transmit +* interruptWrite 1 to clear the interrupt +* tx_done_int_sts_10[14] - (W1C) TX Queue#10 packet transmit +* interruptWrite 1 to clear the interrupt +* tx_done_int_sts_11[15] - (W1C) TX Queue#11 packet transmit +* interruptWrite 1 to clear the interrupt +* tx_done_int_sts_12[16] - (W1C) TX Queue#12 packet transmit +* interruptWrite 1 to clear the interrupt +* tx_done_int_sts_13[17] - (W1C) TX Queue#13 packet transmit +* interruptWrite 1 to clear the interrupt +* tx_done_int_sts_14[18] - (W1C) TX Queue#14 packet transmit +* interruptWrite 1 to clear the interrupt +* RESERVED19[19] - (RO) Reserved bits +* rx_coherent_int_sts[20] - (W1C) RX_DMA finds data coherent event when +* checking ddone bit +* Write 1 to clear the interrupt +* Read to get the raw interrupt status +* tx_coherent_int_sts[21] - (W1C) TX_DMA finds data coherent event when +* checking ddone bit +* Write 1 to clear the interrupt +* Read to get the raw interrupt status +* RESERVED[23..22] - (RO) reserved, originally used for delayed +* interrupt of legacy TX/RX done +* wpdma2host_err_int_sts[24] - (RO) wpdma interrupt overall status +* User should should check WPDMA_ERR_INT_STA +* for each wpdma error interrupt status +* Host could read [0x0_41E8] to check +* indivisual wpdma2host_error interrupt status +* RESERVED[25] - (RO) reserved, originally used for delayed +* interrupt of legacy TX/RX done +* tx_done_int_sts_16[26] - (W1C) TX Queue#16 packet transmit interrupt +* Write 1 to clear the interrupt +* tx_done_int_sts_17[27] - (W1C) TX Queue#17 packet transmit interrupt +* Write 1 to clear the interrupt +* subsys_int_sts[28] - (RO) subsys interrupt overall status +* User should should check +* SUBSYS2HOST_INT_STA for each interrupt status +* Host could read [0x0_41F8] to check +* indivisual subsys hw interrupt status +* mcu2host_sw_int_sts[29] - (RO) subsys interrupt overall status +* User should should check +* SUBSYS2HOST_INT_STA for each interrupt status +* Host could read [0x0_41F8] to check +* indivisual subsys hw interrupt status +* tx_done_int_sts_18[30] - (W1C) TX Queue#18 packet transmit interrupt +* Write 1 to clear the interrupt +* RESERVED[31] - (RO) reserved +*/ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_18_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_18_MASK \ + 0x40000000 /* tx_done_int_sts_18[30] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_18_SHFT 30 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_mcu2host_sw_int_sts_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_mcu2host_sw_int_sts_MASK \ + 0x20000000 /* mcu2host_sw_int_sts[29] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_mcu2host_sw_int_sts_SHFT 29 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_subsys_int_sts_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_subsys_int_sts_MASK \ + 0x10000000 /* subsys_int_sts[28] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_subsys_int_sts_SHFT 28 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_17_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_17_MASK \ + 0x08000000 /* tx_done_int_sts_17[27] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_17_SHFT 27 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_16_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_16_MASK \ + 0x04000000 /* tx_done_int_sts_16[26] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_16_SHFT 26 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_wpdma2host_err_int_sts_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_wpdma2host_err_int_sts_MASK \ + 0x01000000 /* wpdma2host_err_int_sts[24] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_wpdma2host_err_int_sts_SHFT 24 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_coherent_int_sts_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_coherent_int_sts_MASK \ + 0x00200000 /* tx_coherent_int_sts[21] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_coherent_int_sts_SHFT 21 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_rx_coherent_int_sts_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_rx_coherent_int_sts_MASK \ + 0x00100000 /* rx_coherent_int_sts[20] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_rx_coherent_int_sts_SHFT 20 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_14_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_14_MASK \ + 0x00040000 /* tx_done_int_sts_14[18] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_14_SHFT 18 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_13_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_13_MASK \ + 0x00020000 /* tx_done_int_sts_13[17] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_13_SHFT 17 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_12_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_12_MASK \ + 0x00010000 /* tx_done_int_sts_12[16] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_12_SHFT 16 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_11_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_11_MASK \ + 0x00008000 /* tx_done_int_sts_11[15] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_11_SHFT 15 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_10_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_10_MASK \ + 0x00004000 /* tx_done_int_sts_10[14] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_10_SHFT 14 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_9_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_9_MASK \ + 0x00002000 /* tx_done_int_sts_9[13] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_9_SHFT 13 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_8_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_8_MASK \ + 0x00001000 /* tx_done_int_sts_8[12] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_8_SHFT 12 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_7_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_7_MASK \ + 0x00000800 /* tx_done_int_sts_7[11] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_7_SHFT 11 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_6_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_6_MASK \ + 0x00000400 /* tx_done_int_sts_6[10] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_6_SHFT 10 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_5_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_5_MASK \ + 0x00000200 /* tx_done_int_sts_5[9] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_5_SHFT 9 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_4_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_4_MASK \ + 0x00000100 /* tx_done_int_sts_4[8] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_4_SHFT 8 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_3_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_3_MASK \ + 0x00000080 /* tx_done_int_sts_3[7] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_3_SHFT 7 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_2_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_2_MASK \ + 0x00000040 /* tx_done_int_sts_2[6] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_2_SHFT 6 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_1_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_1_MASK \ + 0x00000020 /* tx_done_int_sts_1[5] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_1_SHFT 5 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_0_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_0_MASK \ + 0x00000010 /* tx_done_int_sts_0[4] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_tx_done_int_sts_0_SHFT 4 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_rx_done_int_sts_3_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_rx_done_int_sts_3_MASK \ + 0x00000008 /* rx_done_int_sts_3[3] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_rx_done_int_sts_3_SHFT 3 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_rx_done_int_sts_2_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_rx_done_int_sts_2_MASK \ + 0x00000004 /* rx_done_int_sts_2[2] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_rx_done_int_sts_2_SHFT 2 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_rx_done_int_sts_1_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_rx_done_int_sts_1_MASK \ + 0x00000002 /* rx_done_int_sts_1[1] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_rx_done_int_sts_1_SHFT 1 +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_rx_done_int_sts_0_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_rx_done_int_sts_0_MASK \ + 0x00000001 /* rx_done_int_sts_0[0] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_STA_rx_done_int_sts_0_SHFT 0 + +/* +* ---HOST_INT_ENA (0x18025000 + 0X204)--- +* HOST_RX_DONE_INT_ENA0[0] - (RW) RX Queue#0 packet receive interrupt +* HOST_RX_DONE_INT_ENA1[1] - (RW) RX Queue#1 packet receive interrupt +* HOST_RX_DONE_INT_ENA2[2] - (RW) RX Queue#2 packet receive interrupt +* HOST_RX_DONE_INT_ENA3[3] - (RW) RX Queue#3 packet receive interrupt +* HOST_TX_DONE_INT_ENA0[4] - (RW) TX Queue#0 packet transmit interrupt +* HOST_TX_DONE_INT_ENA1[5] - (RW) TX Queue#1 packet transmit interrupt +* HOST_TX_DONE_INT_ENA2[6] - (RW) TX Queue#2 packet transmit interrupt +* HOST_TX_DONE_INT_ENA3[7] - (RW) TX Queue#3 packet transmit interrupt +* HOST_TX_DONE_INT_ENA4[8] - (RW) TX Queue#4 packet transmit interrupt +* HOST_TX_DONE_INT_ENA5[9] - (RW) TX Queue#5 packet transmit interrupt +* HOST_TX_DONE_INT_ENA6[10] - (RW) TX Queue#6 packet transmit interrupt +* HOST_TX_DONE_INT_ENA7[11] - (RW) TX Queue#7 packet transmit interrupt +* HOST_TX_DONE_INT_ENA8[12] - (RW) TX Queue#8 packet transmit interrupt +* HOST_TX_DONE_INT_ENA9[13] - (RW) TX Queue#9 packet transmit interrupt +* HOST_TX_DONE_INT_ENA10[14] - (RW) TX Queue#10 packet transmit interrupt +* HOST_TX_DONE_INT_ENA11[15] - (RW) TX Queue#11 packet transmit interrupt +* HOST_TX_DONE_INT_ENA12[16] - (RW) TX Queue#12 packet transmit interrupt +* HOST_TX_DONE_INT_ENA13[17] - (RW) TX Queue#13 packet transmit interrupt +* HOST_TX_DONE_INT_ENA14[18] - (RW) TX Queue#14 packet transmit interrupt +* RESERVED19[19] - (RO) Reserved bits +* HOST_RX_COHERENT_EN[20] - (RW) Enable for RX_DMA data coherent +interrupt +* HOST_TX_COHERENT_EN[21] - (RW) Enable for TX_DMA data coherent +interrupt +* RESERVED[23..22] - (RO) reserved, originally used for delayed +* interrupt of legacy TX/RX done +* wpdma2host_err_int_ena[24] - (RW) Enable bit of wpdma2host_err_int +* RESERVED[25] - (RO) reserved +* HOST_TX_DONE_INT_ENA16[26] - (RW) TX Queue#16 packet transmit interrupt +* HOST_TX_DONE_INT_ENA17[27] - (RW) TX Queue#17 packet transmit interrupt +* subsys_int_ena[28] - (RW) Enable bit of subsys_int +* mcu2host_sw_int_ena[29] - (RW) Enable bit of mcu2host_sw_int +* HOST_TX_DONE_INT_ENA18[30] - (RW) TX Queue#18 packet transmit interrupt +* RESERVED[31] - (RO) reserved +*/ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA18_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA18_MASK \ + 0x40000000 /* HOST_TX_DONE_INT_ENA18[30] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA18_SHFT 30 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_mcu2host_sw_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_mcu2host_sw_int_ena_MASK \ + 0x20000000 /* mcu2host_sw_int_ena[29] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_mcu2host_sw_int_ena_SHFT 29 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_subsys_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_subsys_int_ena_MASK \ + 0x10000000 /* subsys_int_ena[28] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_subsys_int_ena_SHFT 28 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA17_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA17_MASK \ + 0x08000000 /* HOST_TX_DONE_INT_ENA17[27] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA17_SHFT 27 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA16_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA16_MASK \ + 0x04000000 /* HOST_TX_DONE_INT_ENA16[26] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA16_SHFT 26 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_wpdma2host_err_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_wpdma2host_err_int_ena_MASK \ + 0x01000000 /* wpdma2host_err_int_ena[24] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_wpdma2host_err_int_ena_SHFT 24 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_COHERENT_EN_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_COHERENT_EN_MASK \ + 0x00200000 /* HOST_TX_COHERENT_EN[21] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_COHERENT_EN_SHFT 21 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_RX_COHERENT_EN_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_RX_COHERENT_EN_MASK \ + 0x00100000 /* HOST_RX_COHERENT_EN[20] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_RX_COHERENT_EN_SHFT 20 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA14_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA14_MASK \ + 0x00040000 /* HOST_TX_DONE_INT_ENA14[18] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA14_SHFT 18 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA13_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA13_MASK \ + 0x00020000 /* HOST_TX_DONE_INT_ENA13[17] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA13_SHFT 17 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA12_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA12_MASK \ + 0x00010000 /* HOST_TX_DONE_INT_ENA12[16] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA12_SHFT 16 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA11_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA11_MASK \ + 0x00008000 /* HOST_TX_DONE_INT_ENA11[15] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA11_SHFT 15 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA10_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA10_MASK \ + 0x00004000 /* HOST_TX_DONE_INT_ENA10[14] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA10_SHFT 14 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA9_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA9_MASK \ + 0x00002000 /* HOST_TX_DONE_INT_ENA9[13] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA9_SHFT 13 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA8_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA8_MASK \ + 0x00001000 /* HOST_TX_DONE_INT_ENA8[12] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA8_SHFT 12 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA7_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA7_MASK \ + 0x00000800 /* HOST_TX_DONE_INT_ENA7[11] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA7_SHFT 11 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA6_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA6_MASK \ + 0x00000400 /* HOST_TX_DONE_INT_ENA6[10] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA6_SHFT 10 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA5_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA5_MASK \ + 0x00000200 /* HOST_TX_DONE_INT_ENA5[9] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA5_SHFT 9 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA4_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA4_MASK \ + 0x00000100 /* HOST_TX_DONE_INT_ENA4[8] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA4_SHFT 8 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA3_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA3_MASK \ + 0x00000080 /* HOST_TX_DONE_INT_ENA3[7] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA3_SHFT 7 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA2_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA2_MASK \ + 0x00000040 /* HOST_TX_DONE_INT_ENA2[6] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA2_SHFT 6 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA1_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA1_MASK \ + 0x00000020 /* HOST_TX_DONE_INT_ENA1[5] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA1_SHFT 5 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA0_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA0_MASK \ + 0x00000010 /* HOST_TX_DONE_INT_ENA0[4] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_TX_DONE_INT_ENA0_SHFT 4 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_RX_DONE_INT_ENA3_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_RX_DONE_INT_ENA3_MASK \ + 0x00000008 /* HOST_RX_DONE_INT_ENA3[3] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_RX_DONE_INT_ENA3_SHFT 3 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_RX_DONE_INT_ENA2_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_RX_DONE_INT_ENA2_MASK \ + 0x00000004 /* HOST_RX_DONE_INT_ENA2[2] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_RX_DONE_INT_ENA2_SHFT 2 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_RX_DONE_INT_ENA1_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_RX_DONE_INT_ENA1_MASK \ + 0x00000002 /* HOST_RX_DONE_INT_ENA1[1] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_RX_DONE_INT_ENA1_SHFT 1 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_RX_DONE_INT_ENA0_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_RX_DONE_INT_ENA0_MASK \ + 0x00000001 /* HOST_RX_DONE_INT_ENA0[0] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_HOST_RX_DONE_INT_ENA0_SHFT 0 + +/* +* ---WPDMA_GLO_CFG (0x18025000 + 0x208)--- +* TX_DMA_EN[0] - (RW) TX_DMA Enable +* 1: Enable TX_DMA, MUST wait until all +* prefetch rings' MAX_CNT(WPDMA_T(R)X_RING*_EXT_CTRL) of DMA including neighbor +* DMA have been configured successfully +* 0: Disable TX_DMA +* TX_DMA_BUSY[1] - (RO) TX_DMA Busy indicator +* 1: TX_DMA is busy +* 0: TX_DMA is not busy +* RX_DMA_EN[2] - (RW) RX_DMA Enable +* 1: Enable RX_DMA, MUST wait until all +* prefetch rings' MAX_CNT(WPDMA_T(R)X_RING*_EXT_CTRL) of DMA including neighbor +* DMA have been configured successfully +* 0: Disable RX_DMA +* RX_DMA_BUSY[3] - (RO) RX_DMA Busy indicator +* 1: RX_DMA is busy +* 0: RX_DMA is not busy +* PDMA_BT_SIZE[5..4] - (RW) Define the burst size of WPDMA +* 2'h0 : 4 DWORD (16bytes) +* 2'h1 : 8 DWORD (32 bytes) +* 2'h2 : 16 DWORD (64 bytes) +* 2'h3 : 32 DWORD (128 bytes) +* TX_WB_DDONE[6] - (RW) 1'b1 : TX engine will wait to assert IRQ +* util whole TX dmad has been fully written into AXI bus which represents HOST +* memory, 1'b0 : TX engine will assert IRQ once TX dmad write-back request have +* been ACKed +* BIG_ENDIAN[7] - (RW) The endian mode selection. DMA applies +* the endian rule to convert payload and TX/RX information. DMA won't apply +* endian rule to register or descriptor. +* 1: big endian. +* 0: little endian. +* DMAD_32B_EN[8] - (RW) DMA Descriptor 32-byte Enable +* 0: The size of descriptors is set to 16-byte +* 1: The size of descriptors is set to 32-byte +* FW_DWLD_Bypass_dmashdl[9] - (RW) No USE for (APSOC/PCIE) +* For firmware download packet, driver shold using tx-ring16 to download packet +* and set this bit to bypass dmashdl resource control. +* After firmware download finish, driver +* should clear this bit. +* After all, tx-ring16 could be used for normal data operation. +(USB) +* For USB test_mode, user could set this bit to bypass dmashdl with all endpoint +* CSR_WFDMA_DUMMY_REG[10] - (RW) dummy CR for use if ECO needed +* CSR_AXI_BUFRDY_BYP[11] - (RW) to disable read data fifo available checking +* before issuing next AXI read request +* FIFO_LITTLE_ENDIAN[12] - (RW) Determines the endianness of the FIFO side +* 0: Big-endian +* 1: Little-endian +* CSR_RX_WB_DDONE[13] - (RW) 1'b1 : RX engine will wait to assert IRQ +* util whole RX dmad has been fully written into AXI bus which represents HOST +* memory, 1'b0 : RX engine will assert IRQ once RX dmad write-back request have +* been ACKed +* CSR_PP_HIF_TXP_ACTIVE_EN[14] - (RW) 1'b1 : enable legacy pp_hif_txp_active +* function to lock tx engine for favor TXP transmit requested directly from PP, +* other pdma TX rings request will be masked until pp_hif_txp_active is +deasserted +* 1'b0 : disable legacy pp_hif_txp_active function, use latest TX source QoS +* design to change throttler settings to favor TXP transmit! +* CSR_DISP_BASE_PTR_CHAIN_EN[15] - (RW) Enable prefet sram ring address +* arrangement by hardware chain structure(DMA#N TX ring group -> DMA#N RX ring +* group -> DMA#M TX ring group -> DMA#M RX ring group and son on). If not +* enabled, firmware need to program DISP_BASE_PTR of WPDMA_T(R)X_RING*_EXT_CTRL +instead!! +* CSR_LBK_RX_Q_SEL[17..16] - (RW) loopback data from TXFIFO will be direct to +* this RX ring when CSR_LBK_RX_Q_SEL_EN in loopback mode, valid bit-width is +* equal to RX_RING_WIDTH which can be calculated from WPDMA_INFO 0x284[15:8] +RX_RING_NUMBER +* RESERVED18[19..18] - (RO) Reserved bits +* CSR_LBK_RX_Q_SEL_EN[20] - (RW) Force configured CSR_LBK_RX_Q_SEL to +* receive loopback data from TXFIFO +* RESERVED21[23..21] - (RO) Reserved bits +* CSR_SW_RST[24] - (RO) SW reset all designs (To be tested for SER in the +future) +* FORCE_TX_EOF[25] - (RW) Force to send an eof after PDMA being reset (for +Packet_Processor) +* 0: Disabled +* 1: Enabled +* PDMA_ADDR_EXT_EN[26] - (RW) No Fnction for now!! For PDMA Address 32bits +* extension. When this design option was enable. PDMA would change Tx/Rx +* descriptor format for address extension. +* 0 : PDMA 32bits address +* 1 : PDMA Tx descirptor DW3 (TXINFO) would used to extend address +* PDMA Rx descirpt DW2 (Reserved) would used to extend address. +* OMIT_RX_INFO[27] - (RW) For loopback mode, set to 1'b1. +* For normal wifi data operation. User should not set this option and should +* keep 1'b0 because UMAC will always add extra QW for checksum after received +* packet's laster QW +* VERY IMPORTANT : for cpu_dma0/1 where CR +* resides in 0x5100_0xxx, OMIT_RX_INFO MUST be set to 1'b1 +* Omit rx_info of all RX packets +* 0: All the PX packets should end with a rx_info +* 1: All the PX packets should NOT end with a rx_info but an eof +* OMIT_TX_INFO[28] - (RW) For loopback mode, set to 1'b1. +* For normal wifi data operation. User should +* set this option to +* Omit tx_info of all TX packets because UMAC +* design not support TXINFO +* 0: The tx_info in DMAD will be sent at the beginning +* 1: The tx_info in DMAD will NOT be sent at the beginning +* BYTE_SWAP[29] - (RW) Byte Swapping for TX/RX DMAD +* 0: Not to swap (Endian of DMAD unchanged) +* 1: Swap (Endian of DMAD reversed) +* CLK_GATE_DIS[30] - (RW) PDMA Clock Gated Function Disable +* 0: normal function +* 1: disable clock gated function +* RX_2B_OFFSET[31] - (RW) RX PBF 2-byte Offset +* 1: Skip the first two bytes of the RX PBF +* 0: Not to skip the first two bytes of the +* RX PBF +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_RX_2B_OFFSET_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_RX_2B_OFFSET_MASK \ + 0x80000000 /* RX_2B_OFFSET[31] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_RX_2B_OFFSET_SHFT 31 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CLK_GATE_DIS_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CLK_GATE_DIS_MASK \ + 0x40000000 /* CLK_GATE_DIS[30] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CLK_GATE_DIS_SHFT 30 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_BYTE_SWAP_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_BYTE_SWAP_MASK \ + 0x20000000 /* BYTE_SWAP[29] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_BYTE_SWAP_SHFT 29 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_OMIT_TX_INFO_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_OMIT_TX_INFO_MASK \ + 0x10000000 /* OMIT_TX_INFO[28] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_OMIT_TX_INFO_SHFT 28 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_OMIT_RX_INFO_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_OMIT_RX_INFO_MASK \ + 0x08000000 /* OMIT_RX_INFO[27] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_OMIT_RX_INFO_SHFT 27 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_PDMA_ADDR_EXT_EN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_PDMA_ADDR_EXT_EN_MASK \ + 0x04000000 /* PDMA_ADDR_EXT_EN[26] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_PDMA_ADDR_EXT_EN_SHFT 26 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_FORCE_TX_EOF_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_FORCE_TX_EOF_MASK \ + 0x02000000 /* FORCE_TX_EOF[25] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_FORCE_TX_EOF_SHFT 25 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_SW_RST_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_SW_RST_MASK \ + 0x01000000 /* CSR_SW_RST[24] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_SW_RST_SHFT 24 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_LBK_RX_Q_SEL_EN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_LBK_RX_Q_SEL_EN_MASK \ + 0x00100000 /* CSR_LBK_RX_Q_SEL_EN[20] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_LBK_RX_Q_SEL_EN_SHFT 20 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_LBK_RX_Q_SEL_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_LBK_RX_Q_SEL_MASK \ + 0x00030000 /* CSR_LBK_RX_Q_SEL[17..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_LBK_RX_Q_SEL_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN_MASK \ + 0x00008000 /* CSR_DISP_BASE_PTR_CHAIN_EN[15] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN_SHFT 15 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_PP_HIF_TXP_ACTIVE_EN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_PP_HIF_TXP_ACTIVE_EN_MASK \ + 0x00004000 /* CSR_PP_HIF_TXP_ACTIVE_EN[14] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_PP_HIF_TXP_ACTIVE_EN_SHFT 14 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_RX_WB_DDONE_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_RX_WB_DDONE_MASK \ + 0x00002000 /* CSR_RX_WB_DDONE[13] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_RX_WB_DDONE_SHFT 13 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_FIFO_LITTLE_ENDIAN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_FIFO_LITTLE_ENDIAN_MASK \ + 0x00001000 /* FIFO_LITTLE_ENDIAN[12] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_FIFO_LITTLE_ENDIAN_SHFT 12 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_AXI_BUFRDY_BYP_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_AXI_BUFRDY_BYP_MASK \ + 0x00000800 /* CSR_AXI_BUFRDY_BYP[11] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_AXI_BUFRDY_BYP_SHFT 11 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_WFDMA_DUMMY_REG_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_WFDMA_DUMMY_REG_MASK \ + 0x00000400 /* CSR_WFDMA_DUMMY_REG[10] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_CSR_WFDMA_DUMMY_REG_SHFT 10 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_FW_DWLD_Bypass_dmashdl_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_FW_DWLD_Bypass_dmashdl_MASK \ + 0x00000200 /* FW_DWLD_Bypass_dmashdl[9] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_FW_DWLD_Bypass_dmashdl_SHFT 9 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_DMAD_32B_EN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_DMAD_32B_EN_MASK \ + 0x00000100 /* DMAD_32B_EN[8] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_DMAD_32B_EN_SHFT 8 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_BIG_ENDIAN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_BIG_ENDIAN_MASK \ + 0x00000080 /* BIG_ENDIAN[7] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_BIG_ENDIAN_SHFT 7 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_TX_WB_DDONE_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_TX_WB_DDONE_MASK \ + 0x00000040 /* TX_WB_DDONE[6] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_TX_WB_DDONE_SHFT 6 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_PDMA_BT_SIZE_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_PDMA_BT_SIZE_MASK \ + 0x00000030 /* PDMA_BT_SIZE[5..4] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_PDMA_BT_SIZE_SHFT 4 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_RX_DMA_BUSY_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_RX_DMA_BUSY_MASK \ + 0x00000008 /* RX_DMA_BUSY[3] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_RX_DMA_BUSY_SHFT 3 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_RX_DMA_EN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_RX_DMA_EN_MASK \ + 0x00000004 /* RX_DMA_EN[2] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_RX_DMA_EN_SHFT 2 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_TX_DMA_BUSY_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_TX_DMA_BUSY_MASK \ + 0x00000002 /* TX_DMA_BUSY[1] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_TX_DMA_BUSY_SHFT 1 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_TX_DMA_EN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_TX_DMA_EN_MASK \ + 0x00000001 /* TX_DMA_EN[0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_TX_DMA_EN_SHFT 0 + +/* +* ---WPDMA_RST_DTX_PTR (0x18025000 + 0x20C)--- +* RST_DTX_IDX0[0] - (WO) Write 1 to reset to TX_DMATX_IDX0 to 0 +* RST_DTX_IDX1[1] - (WO) Write 1 to reset to TX_DMATX_IDX1 to 0 +* RST_DTX_IDX2[2] - (WO) Write 1 to reset to TX_DMATX_IDX2 to 0 +* RST_DTX_IDX3[3] - (WO) Write 1 to reset to TX_DMATX_IDX3 to 0 +* RST_DTX_IDX4[4] - (WO) Write 1 to reset to TX_DMATX_IDX4 to 0 +* RST_DTX_IDX5[5] - (WO) Write 1 to reset to TX_DMATX_IDX5 to 0 +* RST_DTX_IDX6[6] - (WO) Write 1 to reset to TX_DMATX_IDX6 to 0 +* RST_DTX_IDX7[7] - (WO) Write 1 to reset to TX_DMATX_IDX7 to 0 +* RST_DTX_IDX8[8] - (WO) Write 1 to reset to TX_DMATX_IDX8 to 0 +* RST_DTX_IDX9[9] - (WO) Write 1 to reset to TX_DMATX_IDX9 to 0 +* RST_DTX_IDX10[10] - (WO) Write 1 to reset to TX_DMATX_IDX10 to 0 +* RST_DTX_IDX11[11] - (WO) Write 1 to reset to TX_DMATX_IDX11 to 0 +* RST_DTX_IDX12[12] - (WO) Write 1 to reset to TX_DMATX_IDX12 to 0 +* RST_DTX_IDX13[13] - (WO) Write 1 to reset to TX_DMATX_IDX13 to 0 +* RST_DTX_IDX14[14] - (WO) Write 1 to reset to TX_DMATX_IDX14 to 0 +* RST_DTX_IDX15[15] - (WO) Write 1 to reset to TX_DMATX_IDX15 to 0 +* RST_DTX_IDX16[16] - (WO) Write 1 to reset to TX_DMATX_IDX16 to 0 +* RST_DTX_IDX17[17] - (WO) Write 1 to reset to TX_DMATX_IDX17 to 0 +* RST_DTX_IDX18[18] - (WO) Write 1 to reset to TX_DMATX_IDX18 to 0 +* RST_DTX_IDX19[19] - (WO) Write 1 to reset to TX_DMATX_IDX19 to 0 +* RST_DTX_IDX20[20] - (WO) Write 1 to reset to TX_DMATX_IDX20 to 0 +* RESERVED21[31..21] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX20_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX20_MASK \ + 0x00100000 /* RST_DTX_IDX20[20] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX20_SHFT 20 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX19_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX19_MASK \ + 0x00080000 /* RST_DTX_IDX19[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX19_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX18_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX18_MASK \ + 0x00040000 /* RST_DTX_IDX18[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX18_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX17_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX17_MASK \ + 0x00020000 /* RST_DTX_IDX17[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX17_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX16_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX16_MASK \ + 0x00010000 /* RST_DTX_IDX16[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX16_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX15_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX15_MASK \ + 0x00008000 /* RST_DTX_IDX15[15] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX15_SHFT 15 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX14_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX14_MASK \ + 0x00004000 /* RST_DTX_IDX14[14] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX14_SHFT 14 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX13_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX13_MASK \ + 0x00002000 /* RST_DTX_IDX13[13] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX13_SHFT 13 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX12_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX12_MASK \ + 0x00001000 /* RST_DTX_IDX12[12] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX12_SHFT 12 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX11_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX11_MASK \ + 0x00000800 /* RST_DTX_IDX11[11] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX11_SHFT 11 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX10_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX10_MASK \ + 0x00000400 /* RST_DTX_IDX10[10] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX10_SHFT 10 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX9_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX9_MASK \ + 0x00000200 /* RST_DTX_IDX9[9] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX9_SHFT 9 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX8_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX8_MASK \ + 0x00000100 /* RST_DTX_IDX8[8] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX8_SHFT 8 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX7_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX7_MASK \ + 0x00000080 /* RST_DTX_IDX7[7] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX7_SHFT 7 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX6_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX6_MASK \ + 0x00000040 /* RST_DTX_IDX6[6] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX6_SHFT 6 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX5_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX5_MASK \ + 0x00000020 /* RST_DTX_IDX5[5] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX5_SHFT 5 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX4_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX4_MASK \ + 0x00000010 /* RST_DTX_IDX4[4] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX4_SHFT 4 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX3_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX3_MASK \ + 0x00000008 /* RST_DTX_IDX3[3] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX3_SHFT 3 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX2_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX2_MASK \ + 0x00000004 /* RST_DTX_IDX2[2] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX2_SHFT 2 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX1_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX1_MASK \ + 0x00000002 /* RST_DTX_IDX1[1] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX1_SHFT 1 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX0_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX0_MASK \ + 0x00000001 /* RST_DTX_IDX0[0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DTX_PTR_RST_DTX_IDX0_SHFT 0 + +/* +* ---WPDMA_PAUSE_TX_Q (0x18025000 + 0x224)--- +* TX_Q_PAUSE[31..0] - (RW) Pause signal for each TX ring (16 bits +* for 16 rings) +* Set 0: Normal function; Set 1: The +* corresponding TX ring is paused +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_TX_Q_TX_Q_PAUSE_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_TX_Q_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_TX_Q_TX_Q_PAUSE_MASK \ + 0xFFFFFFFF /* TX_Q_PAUSE[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_TX_Q_TX_Q_PAUSE_SHFT 0 + +/* +* ---HOST_INT_ENA_SET (0x18025000 + 0X228)--- +* HOST_RX_DONE_INT_ENA0[0] - (W1S) RX Queue#0 packet receive interrupt +* HOST_RX_DONE_INT_ENA1[1] - (W1S) RX Queue#1 packet receive interrupt +* HOST_RX_DONE_INT_ENA2[2] - (W1S) RX Queue#2 packet receive interrupt +* HOST_RX_DONE_INT_ENA3[3] - (W1S) RX Queue#3 packet receive interrupt +* HOST_TX_DONE_INT_ENA0[4] - (W1S) TX Queue#0 packet transmit interrupt +* HOST_TX_DONE_INT_ENA1[5] - (W1S) TX Queue#1 packet transmit interrupt +* HOST_TX_DONE_INT_ENA2[6] - (W1S) TX Queue#2 packet transmit interrupt +* HOST_TX_DONE_INT_ENA3[7] - (W1S) TX Queue#3 packet transmit interrupt +* HOST_TX_DONE_INT_ENA4[8] - (W1S) TX Queue#4 packet transmit interrupt +* HOST_TX_DONE_INT_ENA5[9] - (W1S) TX Queue#5 packet transmit interrupt +* HOST_TX_DONE_INT_ENA6[10] - (W1S) TX Queue#6 packet transmit interrupt +* HOST_TX_DONE_INT_ENA7[11] - (W1S) TX Queue#7 packet transmit interrupt +* HOST_TX_DONE_INT_ENA8[12] - (W1S) TX Queue#8 packet transmit interrupt +* HOST_TX_DONE_INT_ENA9[13] - (W1S) TX Queue#9 packet transmit interrupt +* HOST_TX_DONE_INT_ENA10[14] - (W1S) TX Queue#10 packet transmit interrupt +* HOST_TX_DONE_INT_ENA11[15] - (W1S) TX Queue#11 packet transmit interrupt +* HOST_TX_DONE_INT_ENA12[16] - (W1S) TX Queue#12 packet transmit interrupt +* HOST_TX_DONE_INT_ENA13[17] - (W1S) TX Queue#13 packet transmit interrupt +* HOST_TX_DONE_INT_ENA14[18] - (W1S) TX Queue#14 packet transmit interrupt +* RESERVED19[19] - (RO) Reserved bits +* HOST_RX_COHERENT_EN[20] - (W1S) Enable for RX_DMA data coherent +interrupt +* HOST_TX_COHERENT_EN[21] - (W1S) Enable for TX_DMA data coherent +interrupt +* RESERVED22[23..22] - (RO) Reserved bits +* wpdma2host_err_int_ena[24] - (W1S) Enable bit of wpdma2host_err_int +* RESERVED25[25] - (RO) Reserved bits +* HOST_TX_DONE_INT_ENA16[26] - (W1S) TX Queue#16 packet transmit interrupt +* HOST_TX_DONE_INT_ENA17[27] - (W1S) TX Queue#17 packet transmit interrupt +* subsys_int_ena[28] - (W1S) Enable bit of subsys_int +* mcu2host_sw_int_ena[29] - (W1S) Enable bit of mcu2host_sw_int +* HOST_TX_DONE_INT_ENA18[30] - (W1S) TX Queue#18 packet transmit interrupt +* RESERVED31[31] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA18_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA18_MASK \ + 0x40000000 /* HOST_TX_DONE_INT_ENA18[30] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA18_SHFT 30 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_mcu2host_sw_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_mcu2host_sw_int_ena_MASK \ + 0x20000000 /* mcu2host_sw_int_ena[29] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_mcu2host_sw_int_ena_SHFT 29 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_subsys_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_subsys_int_ena_MASK \ + 0x10000000 /* subsys_int_ena[28] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_subsys_int_ena_SHFT 28 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA17_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA17_MASK \ + 0x08000000 /* HOST_TX_DONE_INT_ENA17[27] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA17_SHFT 27 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA16_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA16_MASK \ + 0x04000000 /* HOST_TX_DONE_INT_ENA16[26] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA16_SHFT 26 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_wpdma2host_err_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_wpdma2host_err_int_ena_MASK \ + 0x01000000 /* wpdma2host_err_int_ena[24] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_wpdma2host_err_int_ena_SHFT 24 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_COHERENT_EN_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_COHERENT_EN_MASK \ + 0x00200000 /* HOST_TX_COHERENT_EN[21] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_COHERENT_EN_SHFT 21 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_RX_COHERENT_EN_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_RX_COHERENT_EN_MASK \ + 0x00100000 /* HOST_RX_COHERENT_EN[20] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_RX_COHERENT_EN_SHFT 20 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA14_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA14_MASK \ + 0x00040000 /* HOST_TX_DONE_INT_ENA14[18] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA14_SHFT 18 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA13_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA13_MASK \ + 0x00020000 /* HOST_TX_DONE_INT_ENA13[17] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA13_SHFT 17 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA12_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA12_MASK \ + 0x00010000 /* HOST_TX_DONE_INT_ENA12[16] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA12_SHFT 16 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA11_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA11_MASK \ + 0x00008000 /* HOST_TX_DONE_INT_ENA11[15] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA11_SHFT 15 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA10_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA10_MASK \ + 0x00004000 /* HOST_TX_DONE_INT_ENA10[14] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA10_SHFT 14 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA9_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA9_MASK \ + 0x00002000 /* HOST_TX_DONE_INT_ENA9[13] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA9_SHFT 13 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA8_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA8_MASK \ + 0x00001000 /* HOST_TX_DONE_INT_ENA8[12] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA8_SHFT 12 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA7_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA7_MASK \ + 0x00000800 /* HOST_TX_DONE_INT_ENA7[11] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA7_SHFT 11 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA6_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA6_MASK \ + 0x00000400 /* HOST_TX_DONE_INT_ENA6[10] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA6_SHFT 10 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA5_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA5_MASK \ + 0x00000200 /* HOST_TX_DONE_INT_ENA5[9] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA5_SHFT 9 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA4_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA4_MASK \ + 0x00000100 /* HOST_TX_DONE_INT_ENA4[8] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA4_SHFT 8 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA3_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA3_MASK \ + 0x00000080 /* HOST_TX_DONE_INT_ENA3[7] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA3_SHFT 7 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA2_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA2_MASK \ + 0x00000040 /* HOST_TX_DONE_INT_ENA2[6] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA2_SHFT 6 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA1_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA1_MASK \ + 0x00000020 /* HOST_TX_DONE_INT_ENA1[5] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA1_SHFT 5 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA0_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA0_MASK \ + 0x00000010 /* HOST_TX_DONE_INT_ENA0[4] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_TX_DONE_INT_ENA0_SHFT 4 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA3_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA3_MASK \ + 0x00000008 /* HOST_RX_DONE_INT_ENA3[3] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA3_SHFT 3 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA2_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA2_MASK \ + 0x00000004 /* HOST_RX_DONE_INT_ENA2[2] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA2_SHFT 2 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA1_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA1_MASK \ + 0x00000002 /* HOST_RX_DONE_INT_ENA1[1] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA1_SHFT 1 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA0_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA0_MASK \ + 0x00000001 /* HOST_RX_DONE_INT_ENA0[0] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_SET_HOST_RX_DONE_INT_ENA0_SHFT 0 + +/* +* ---HOST_INT_ENA_CLR (0x18025000 + 0X22C)--- +* HOST_RX_DONE_INT_ENA0[0] - (W1C) RX Queue#0 packet receive interrupt +* HOST_RX_DONE_INT_ENA1[1] - (W1C) RX Queue#1 packet receive interrupt +* HOST_RX_DONE_INT_ENA2[2] - (W1C) RX Queue#2 packet receive interrupt +* HOST_RX_DONE_INT_ENA3[3] - (W1C) RX Queue#3 packet receive interrupt +* HOST_TX_DONE_INT_ENA0[4] - (W1C) TX Queue#0 packet transmit interrupt +* HOST_TX_DONE_INT_ENA1[5] - (W1C) TX Queue#1 packet transmit interrupt +* HOST_TX_DONE_INT_ENA2[6] - (W1C) TX Queue#2 packet transmit interrupt +* HOST_TX_DONE_INT_ENA3[7] - (W1C) TX Queue#3 packet transmit interrupt +* HOST_TX_DONE_INT_ENA4[8] - (W1C) TX Queue#4 packet transmit interrupt +* HOST_TX_DONE_INT_ENA5[9] - (W1C) TX Queue#5 packet transmit interrupt +* HOST_TX_DONE_INT_ENA6[10] - (W1C) TX Queue#6 packet transmit interrupt +* HOST_TX_DONE_INT_ENA7[11] - (W1C) TX Queue#7 packet transmit interrupt +* HOST_TX_DONE_INT_ENA8[12] - (W1C) TX Queue#8 packet transmit interrupt +* HOST_TX_DONE_INT_ENA9[13] - (W1C) TX Queue#9 packet transmit interrupt +* HOST_TX_DONE_INT_ENA10[14] - (W1C) TX Queue#10 packet transmit interrupt +* HOST_TX_DONE_INT_ENA11[15] - (W1C) TX Queue#11 packet transmit interrupt +* HOST_TX_DONE_INT_ENA12[16] - (W1C) TX Queue#12 packet transmit interrupt +* HOST_TX_DONE_INT_ENA13[17] - (W1C) TX Queue#13 packet transmit interrupt +* HOST_TX_DONE_INT_ENA14[18] - (W1C) TX Queue#14 packet transmit interrupt +* RESERVED19[19] - (RO) Reserved bits +* HOST_RX_COHERENT_EN[20] - (W1C) Enable for RX_DMA data coherent +interrupt +* HOST_TX_COHERENT_EN[21] - (W1C) Enable for TX_DMA data coherent +interrupt +* RESERVED22[23..22] - (RO) Reserved bits +* wpdma2host_err_int_ena[24] - (W1C) Enable bit of wpdma2host_err_int +* RESERVED25[25] - (RO) Reserved bits +* HOST_TX_DONE_INT_ENA16[26] - (W1C) TX Queue#16 packet transmit interrupt +* HOST_TX_DONE_INT_ENA17[27] - (W1C) TX Queue#17 packet transmit interrupt +* subsys_int_ena[28] - (W1C) Enable bit of subsys_int +* mcu2host_sw_int_ena[29] - (W1C) Enable bit of mcu2host_sw_int +* HOST_TX_DONE_INT_ENA18[30] - (W1C) TX Queue#18 packet transmit interrupt +* RESERVED31[31] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA18_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA18_MASK \ + 0x40000000 /* HOST_TX_DONE_INT_ENA18[30] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA18_SHFT 30 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_mcu2host_sw_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_mcu2host_sw_int_ena_MASK \ + 0x20000000 /* mcu2host_sw_int_ena[29] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_mcu2host_sw_int_ena_SHFT 29 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_subsys_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_subsys_int_ena_MASK \ + 0x10000000 /* subsys_int_ena[28] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_subsys_int_ena_SHFT 28 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA17_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA17_MASK \ + 0x08000000 /* HOST_TX_DONE_INT_ENA17[27] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA17_SHFT 27 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA16_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA16_MASK \ + 0x04000000 /* HOST_TX_DONE_INT_ENA16[26] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA16_SHFT 26 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_wpdma2host_err_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_wpdma2host_err_int_ena_MASK \ + 0x01000000 /* wpdma2host_err_int_ena[24] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_wpdma2host_err_int_ena_SHFT 24 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_COHERENT_EN_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_COHERENT_EN_MASK \ + 0x00200000 /* HOST_TX_COHERENT_EN[21] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_COHERENT_EN_SHFT 21 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_RX_COHERENT_EN_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_RX_COHERENT_EN_MASK \ + 0x00100000 /* HOST_RX_COHERENT_EN[20] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_RX_COHERENT_EN_SHFT 20 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA14_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA14_MASK \ + 0x00040000 /* HOST_TX_DONE_INT_ENA14[18] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA14_SHFT 18 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA13_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA13_MASK \ + 0x00020000 /* HOST_TX_DONE_INT_ENA13[17] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA13_SHFT 17 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA12_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA12_MASK \ + 0x00010000 /* HOST_TX_DONE_INT_ENA12[16] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA12_SHFT 16 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA11_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA11_MASK \ + 0x00008000 /* HOST_TX_DONE_INT_ENA11[15] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA11_SHFT 15 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA10_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA10_MASK \ + 0x00004000 /* HOST_TX_DONE_INT_ENA10[14] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA10_SHFT 14 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA9_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA9_MASK \ + 0x00002000 /* HOST_TX_DONE_INT_ENA9[13] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA9_SHFT 13 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA8_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA8_MASK \ + 0x00001000 /* HOST_TX_DONE_INT_ENA8[12] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA8_SHFT 12 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA7_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA7_MASK \ + 0x00000800 /* HOST_TX_DONE_INT_ENA7[11] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA7_SHFT 11 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA6_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA6_MASK \ + 0x00000400 /* HOST_TX_DONE_INT_ENA6[10] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA6_SHFT 10 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA5_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA5_MASK \ + 0x00000200 /* HOST_TX_DONE_INT_ENA5[9] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA5_SHFT 9 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA4_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA4_MASK \ + 0x00000100 /* HOST_TX_DONE_INT_ENA4[8] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA4_SHFT 8 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA3_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA3_MASK \ + 0x00000080 /* HOST_TX_DONE_INT_ENA3[7] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA3_SHFT 7 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA2_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA2_MASK \ + 0x00000040 /* HOST_TX_DONE_INT_ENA2[6] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA2_SHFT 6 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA1_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA1_MASK \ + 0x00000020 /* HOST_TX_DONE_INT_ENA1[5] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA1_SHFT 5 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA0_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA0_MASK \ + 0x00000010 /* HOST_TX_DONE_INT_ENA0[4] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_TX_DONE_INT_ENA0_SHFT 4 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA3_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA3_MASK \ + 0x00000008 /* HOST_RX_DONE_INT_ENA3[3] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA3_SHFT 3 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA2_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA2_MASK \ + 0x00000004 /* HOST_RX_DONE_INT_ENA2[2] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA2_SHFT 2 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA1_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA1_MASK \ + 0x00000002 /* HOST_RX_DONE_INT_ENA1[1] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA1_SHFT 1 +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA0_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA0_MASK \ + 0x00000001 /* HOST_RX_DONE_INT_ENA0[0] */ +#define WF_WFDMA_HOST_DMA1_HOST_INT_ENA_CLR_HOST_RX_DONE_INT_ENA0_SHFT 0 + +/* +* ---WPDMA_TIMEOUT_CFG (0x18025000 + 0x230)--- +* WPDMA_TX_TIMEOUT_TH[7..0] - (RW) xxx +* WPDMA_TX_TIMEOUT_TICK[14..8] - (RW) xxx +* WPDMA_TX_TIMEOUT_ENA[15] - (RW) xxx +* WPDMA_RX_TIMEOUT_TH[23..16] - (RW) xxx +* WPDMA_RX_TIMEOUT_TICK[30..24] - (RW) xxx +* WPDMA_RX_TIMEOUT_ENA[31] - (RW) xxx +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_ENA_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_ENA_MASK \ + 0x80000000 /* WPDMA_RX_TIMEOUT_ENA[31] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_ENA_SHFT 31 +#define WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_TICK_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_TICK_MASK \ + 0x7F000000 /* WPDMA_RX_TIMEOUT_TICK[30..24] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_TICK_SHFT 24 +#define WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_TH_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_TH_MASK \ + 0x00FF0000 /* WPDMA_RX_TIMEOUT_TH[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_WPDMA_RX_TIMEOUT_TH_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_ENA_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_ENA_MASK \ + 0x00008000 /* WPDMA_TX_TIMEOUT_ENA[15] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_ENA_SHFT 15 +#define WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_TICK_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_TICK_MASK \ + 0x00007F00 /* WPDMA_TX_TIMEOUT_TICK[14..8] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_TICK_SHFT 8 +#define WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_TH_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_TH_MASK \ + 0x000000FF /* WPDMA_TX_TIMEOUT_TH[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TIMEOUT_CFG_WPDMA_TX_TIMEOUT_TH_SHFT 0 + +/* +* ---WPDMA_MISC_CFG (0x18025000 + 0x234)--- +* WPDMA_TX_TIMEOUT_SEL[0] - (RW) xxx +* WPDMA_RX_TIMEOUT_SEL[1] - (RW) xxx +* WPDMA_RX_FREE_Q_TH[5..2] - (RW) When loopback, this will be used to +* generate correct tx_pause to avlid deadlock which caused from situration that +* tx_dma will start reading tx packet from memory without considering lack of RX +* dmad in prefetch sram and needing to read RX dmad from memory which tx dma is +* reading tx packet too and rready is deasserted due to txfifo full !! +* RX dmad in prefetch sram should be greater +* than RX_FREE_Q_TH for rx_dma to start writing received packet into memory!! +* RESERVED6[31..6] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_MISC_CFG_WPDMA_RX_FREE_Q_TH_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_MISC_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_MISC_CFG_WPDMA_RX_FREE_Q_TH_MASK \ + 0x0000003C /* WPDMA_RX_FREE_Q_TH[5..2] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_MISC_CFG_WPDMA_RX_FREE_Q_TH_SHFT 2 +#define WF_WFDMA_HOST_DMA1_WPDMA_MISC_CFG_WPDMA_RX_TIMEOUT_SEL_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_MISC_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_MISC_CFG_WPDMA_RX_TIMEOUT_SEL_MASK \ + 0x00000002 /* WPDMA_RX_TIMEOUT_SEL[1] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_MISC_CFG_WPDMA_RX_TIMEOUT_SEL_SHFT 1 +#define WF_WFDMA_HOST_DMA1_WPDMA_MISC_CFG_WPDMA_TX_TIMEOUT_SEL_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_MISC_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_MISC_CFG_WPDMA_TX_TIMEOUT_SEL_MASK \ + 0x00000001 /* WPDMA_TX_TIMEOUT_SEL[0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_MISC_CFG_WPDMA_TX_TIMEOUT_SEL_SHFT 0 + +/* +* ---WPDMA_TX_WRR_ARB_GBF0 (0x18025000 + 0x240)--- +* WRR_REQ0_ARB_GBF[2..0] - (RW) WRR REQ#0 priority level, mapped to +* lumpped request from TX ring0~ring15 for host TXD +* WRR_REQ1_ARB_GBF[5..3] - (RW) WRR REQ#1 priority level, mapped to +* request from TX ring16 when dual tx fifo for host event packet +* WRR_REQ2_ARB_GBF[8..6] - (RW) WRR REQ#2 priority level, mapped to +* request from TX ring17 when dual tx fifo for host event packet +* WRR_REQ3_ARB_GBF[11..9] - (RW) WRR REQ#3 priority level, mapped to +* request from TX ring18 when dual tx fifo for host event packet +* WRR_REQ4_ARB_GBF[14..12] - (RW) WRR REQ#4 priority level, mapped to +* request from TX ring19 when dual tx fifo for host event packet +* RESERVED[31..15] - (RW) Reserved +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ4_ARB_GBF_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_WRR_ARB_GBF0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ4_ARB_GBF_MASK \ + 0x00007000 /* WRR_REQ4_ARB_GBF[14..12] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ4_ARB_GBF_SHFT 12 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ3_ARB_GBF_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_WRR_ARB_GBF0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ3_ARB_GBF_MASK \ + 0x00000E00 /* WRR_REQ3_ARB_GBF[11..9] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ3_ARB_GBF_SHFT 9 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ2_ARB_GBF_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_WRR_ARB_GBF0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ2_ARB_GBF_MASK \ + 0x000001C0 /* WRR_REQ2_ARB_GBF[8..6] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ2_ARB_GBF_SHFT 6 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ1_ARB_GBF_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_WRR_ARB_GBF0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ1_ARB_GBF_MASK \ + 0x00000038 /* WRR_REQ1_ARB_GBF[5..3] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ1_ARB_GBF_SHFT 3 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ0_ARB_GBF_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_WRR_ARB_GBF0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ0_ARB_GBF_MASK \ + 0x00000007 /* WRR_REQ0_ARB_GBF[2..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_WRR_ARB_GBF0_WRR_REQ0_ARB_GBF_SHFT 0 + +/* +* ---MD_INT_STA (0x18025000 + 0x250)--- +* MCU2MD_SW_INT_STS[15..0] - (W1C) MCU to MD S/W interrupt indicator +* CONN_HIF_ON_MD_INT_STS[16] - (RO) MD driver own interrupt indicator +* RESERVED17[31..17] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_MD_INT_STA_CONN_HIF_ON_MD_INT_STS_ADDR \ + WF_WFDMA_HOST_DMA1_MD_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MD_INT_STA_CONN_HIF_ON_MD_INT_STS_MASK \ + 0x00010000 /* CONN_HIF_ON_MD_INT_STS[16] */ +#define WF_WFDMA_HOST_DMA1_MD_INT_STA_CONN_HIF_ON_MD_INT_STS_SHFT 16 +#define WF_WFDMA_HOST_DMA1_MD_INT_STA_MCU2MD_SW_INT_STS_ADDR \ + WF_WFDMA_HOST_DMA1_MD_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_MD_INT_STA_MCU2MD_SW_INT_STS_MASK \ + 0x0000FFFF /* MCU2MD_SW_INT_STS[15..0] */ +#define WF_WFDMA_HOST_DMA1_MD_INT_STA_MCU2MD_SW_INT_STS_SHFT 0 + +/* +* ---MD_INT_ENA (0x18025000 + 0x254)--- +* MCU2MD_SW_INT_ENA[15..0] - (RW) MCU to MD S/W interrupt enable +* CONN_HIF_ON_MD_INT_ENA[16] - (RW) MD driver own interrupt enable +* RESERVED17[31..17] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_MD_INT_ENA_CONN_HIF_ON_MD_INT_ENA_ADDR \ + WF_WFDMA_HOST_DMA1_MD_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MD_INT_ENA_CONN_HIF_ON_MD_INT_ENA_MASK \ + 0x00010000 /* CONN_HIF_ON_MD_INT_ENA[16] */ +#define WF_WFDMA_HOST_DMA1_MD_INT_ENA_CONN_HIF_ON_MD_INT_ENA_SHFT 16 +#define WF_WFDMA_HOST_DMA1_MD_INT_ENA_MCU2MD_SW_INT_ENA_ADDR \ + WF_WFDMA_HOST_DMA1_MD_INT_ENA_ADDR +#define WF_WFDMA_HOST_DMA1_MD_INT_ENA_MCU2MD_SW_INT_ENA_MASK \ + 0x0000FFFF /* MCU2MD_SW_INT_ENA[15..0] */ +#define WF_WFDMA_HOST_DMA1_MD_INT_ENA_MCU2MD_SW_INT_ENA_SHFT 0 + +/* +* ---MCU2MD_SW_INT_SET (0x18025000 + 0x258)--- +* MCU2MD_SW_INT_SET[15..0] - (RO) MCU to MD S/W interrupt set +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_MCU2MD_SW_INT_SET_MCU2MD_SW_INT_SET_ADDR \ + WF_WFDMA_HOST_DMA1_MCU2MD_SW_INT_SET_ADDR +#define WF_WFDMA_HOST_DMA1_MCU2MD_SW_INT_SET_MCU2MD_SW_INT_SET_MASK \ + 0x0000FFFF /* MCU2MD_SW_INT_SET[15..0] */ +#define WF_WFDMA_HOST_DMA1_MCU2MD_SW_INT_SET_MCU2MD_SW_INT_SET_SHFT 0 + +/* +* ---WPDMA_PAUSE_RX_Q_TH10 (0x18025000 + 0x260)--- +* RX_DMAD_TH0[11..0] - (RW) RX Ring0 DMAD threshold to pause PP +* sending packet to RX FIFO +* pause_rx_q = (available RX DMAD counts) < + +* RESERVED12[15..12] - (RO) Reserved bits +* RX_DMAD_TH1[27..16] - (RW) RX Ring1 DMAD threshold to pause PP +* sending packet to RX FIFO +* pause_rx_q = (available RX DMAD counts) < + +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH10_RX_DMAD_TH1_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH10_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH10_RX_DMAD_TH1_MASK \ + 0x0FFF0000 /* RX_DMAD_TH1[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH10_RX_DMAD_TH1_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH10_RX_DMAD_TH0_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH10_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH10_RX_DMAD_TH0_MASK \ + 0x00000FFF /* RX_DMAD_TH0[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH10_RX_DMAD_TH0_SHFT 0 + +/* +* ---WPDMA_PAUSE_RX_Q_TH32 (0x18025000 + 0x264)--- +* RX_DMAD_TH2[11..0] - (RW) RX Ring2 DMAD threshold to pause PP +* sending packet to RX FIFO +* pause_rx_q = (available RX DMAD counts) < + +* RESERVED12[15..12] - (RO) Reserved bits +* RX_DMAD_TH3[27..16] - (RW) RX Ring3 DMAD threshold to pause PP +* sending packet to RX FIFO +* pause_rx_q = (available RX DMAD counts) < + +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH32_RX_DMAD_TH3_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH32_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH32_RX_DMAD_TH3_MASK \ + 0x0FFF0000 /* RX_DMAD_TH3[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH32_RX_DMAD_TH3_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH32_RX_DMAD_TH2_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH32_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH32_RX_DMAD_TH2_MASK \ + 0x00000FFF /* RX_DMAD_TH2[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH32_RX_DMAD_TH2_SHFT 0 + +/* +* ---WPDMA_PAUSE_RX_Q_TH54 (0x18025000 + 0x268)--- +* RX_DMAD_TH4[11..0] - (RW) RX Ring4 DMAD threshold to pause PP +* sending packet to RX FIFO +* pause_rx_q = (available RX DMAD counts) < + +* RESERVED12[15..12] - (RO) Reserved bits +* RX_DMAD_TH5[27..16] - (RW) RX Ring5 DMAD threshold to pause PP +* sending packet to RX FIFO +* pause_rx_q = (available RX DMAD counts) < + +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH54_RX_DMAD_TH5_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH54_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH54_RX_DMAD_TH5_MASK \ + 0x0FFF0000 /* RX_DMAD_TH5[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH54_RX_DMAD_TH5_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH54_RX_DMAD_TH4_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH54_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH54_RX_DMAD_TH4_MASK \ + 0x00000FFF /* RX_DMAD_TH4[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH54_RX_DMAD_TH4_SHFT 0 + +/* +* ---WPDMA_PAUSE_RX_Q_TH76 (0x18025000 + 0x26C)--- +* RX_DMAD_TH6[11..0] - (RW) RX Ring6 DMAD threshold to pause PP +* sending packet to RX FIFO +* pause_rx_q = (available RX DMAD counts) < + +* RESERVED12[15..12] - (RO) Reserved bits +* RX_DMAD_TH7[27..16] - (RW) RX Ring7 DMAD threshold to pause PP +* sending packet to RX FIFO +* pause_rx_q = (available RX DMAD counts) < + +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH76_RX_DMAD_TH7_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH76_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH76_RX_DMAD_TH7_MASK \ + 0x0FFF0000 /* RX_DMAD_TH7[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH76_RX_DMAD_TH7_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH76_RX_DMAD_TH6_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH76_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH76_RX_DMAD_TH6_MASK \ + 0x00000FFF /* RX_DMAD_TH6[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_PAUSE_RX_Q_TH76_RX_DMAD_TH6_SHFT 0 + +/* +* ---WPDMA_RST_DRX_PTR (0x18025000 + 0x280)--- +* RST_DRX_IDX0[0] - (WO) Write 1 to reset to RX_DMARX_IDX0 to 0 +* RST_DRX_IDX1[1] - (WO) Write 1 to reset to RX_DMARX_IDX1 to 0 +* RST_DRX_IDX2[2] - (WO) Write 1 to reset to RX_DMARX_IDX2 to 0 +* RST_DRX_IDX3[3] - (WO) Write 1 to reset to RX_DMARX_IDX3 to 0 +* RESERVED[31..4] - (WO) Reserved +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DRX_PTR_RST_DRX_IDX3_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DRX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DRX_PTR_RST_DRX_IDX3_MASK \ + 0x00000008 /* RST_DRX_IDX3[3] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DRX_PTR_RST_DRX_IDX3_SHFT 3 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DRX_PTR_RST_DRX_IDX2_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DRX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DRX_PTR_RST_DRX_IDX2_MASK \ + 0x00000004 /* RST_DRX_IDX2[2] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DRX_PTR_RST_DRX_IDX2_SHFT 2 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DRX_PTR_RST_DRX_IDX1_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DRX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DRX_PTR_RST_DRX_IDX1_MASK \ + 0x00000002 /* RST_DRX_IDX1[1] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DRX_PTR_RST_DRX_IDX1_SHFT 1 +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DRX_PTR_RST_DRX_IDX0_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RST_DRX_PTR_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DRX_PTR_RST_DRX_IDX0_MASK \ + 0x00000001 /* RST_DRX_IDX0[0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RST_DRX_PTR_RST_DRX_IDX0_SHFT 0 + +/* +* ---WPDMA_INFO (0x18025000 + 0x284)--- +* TX_RING_NUMBER[7..0] - (RO) TX_RING_NUMBER +* RX_RING_NUMBER[15..8] - (RO) RX_RING_NUMBER +* BASE_PTR_WIDTH[23..16] - (RO) {2'h0, 6'd32-'BASE_PTR_WIDTH[5:0]} +* INDEX_WIDTH[27..24] - (RO) RING_INDEX_WIDTH +* PDMA_PREFETCH_SRAM_SIZE[30..28] - (RO) PDMA prefetch sram size{3'h0 : 128 +* byte, 3'h1 : 256 byte, 3'h2 : 512 byte, 3'h3 : 1KB, 3'h4 : 2KB, 3'h5 : 4KB, +* 3'h6 : 8KB, 3'h7 : reserved}, be noticed that prefetch sram is shared outside +* with other DMAs, please check all DMAs' total prefetch ring number and max_cnt +* for each prefetch ring to make sure that total size of all configured prefetch +* dmad of all DMAs' prefetch ring should be less than PDMA_PREFETCH_SRAM_SIZE +* WFDMA_PDA_EXIST[31] - (RO) Only cpu_dma1 will support pda functions +* for firmware download and wfdma_pda_top resides in between cpu_dma0 and +cpu_dma1! +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_WFDMA_PDA_EXIST_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_INFO_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_WFDMA_PDA_EXIST_MASK \ + 0x80000000 /* WFDMA_PDA_EXIST[31] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_WFDMA_PDA_EXIST_SHFT 31 +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_PDMA_PREFETCH_SRAM_SIZE_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_INFO_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_PDMA_PREFETCH_SRAM_SIZE_MASK \ + 0x70000000 /* PDMA_PREFETCH_SRAM_SIZE[30..28] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_PDMA_PREFETCH_SRAM_SIZE_SHFT 28 +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_INDEX_WIDTH_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_INFO_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_INDEX_WIDTH_MASK \ + 0x0F000000 /* INDEX_WIDTH[27..24] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_INDEX_WIDTH_SHFT 24 +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_BASE_PTR_WIDTH_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_INFO_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_BASE_PTR_WIDTH_MASK \ + 0x00FF0000 /* BASE_PTR_WIDTH[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_BASE_PTR_WIDTH_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_RX_RING_NUMBER_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_INFO_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_RX_RING_NUMBER_MASK \ + 0x0000FF00 /* RX_RING_NUMBER[15..8] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_RX_RING_NUMBER_SHFT 8 +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_TX_RING_NUMBER_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_INFO_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_TX_RING_NUMBER_MASK \ + 0x000000FF /* TX_RING_NUMBER[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_TX_RING_NUMBER_SHFT 0 + +/* +* ---WPDMA_INFO_EXT (0x18025000 + 0x288)--- +* TX_EVENT_RING_NUMBER[7..0] - (RO) When TX_EVENT_RING_NUMBER equal 8'h0, it +* means that this DMA doesn't support dual TX fifo, thus in default it only +* support TX_RING_NUMBER of TX rings !! +* But when TX_EVENT_RING_NUMBER NOT equal +* 8'h0, this dma is configured as dual TX fifo and +* TX_RING[16+TX_EVENT_RING_NUM-1:16] are for getting HOST EVENT packet from HOST +* to WX_CPU!! +* TX_DMAD_RING_NUMBER[15..8] - (RO) When TX_EVENT_RING_NUMBER not equal to +* 8'h0, it means that this DMA support dual TX fifo and TX +* ring[TX_DMAD_RING_NUMBER-1:0] are for getting TXD from HOST to UMAC!! +* RESERVED[30..16] - (RO) Reserved +* TX_DMASHDL_EXIST[31] - (RO) TX_DMASHDL_EXIST +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_EXT_TX_DMASHDL_EXIST_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_INFO_EXT_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_EXT_TX_DMASHDL_EXIST_MASK \ + 0x80000000 /* TX_DMASHDL_EXIST[31] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_EXT_TX_DMASHDL_EXIST_SHFT 31 +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_EXT_TX_DMAD_RING_NUMBER_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_INFO_EXT_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_EXT_TX_DMAD_RING_NUMBER_MASK \ + 0x0000FF00 /* TX_DMAD_RING_NUMBER[15..8] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_EXT_TX_DMAD_RING_NUMBER_SHFT 8 +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_EXT_TX_EVENT_RING_NUMBER_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_INFO_EXT_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_EXT_TX_EVENT_RING_NUMBER_MASK \ + 0x000000FF /* TX_EVENT_RING_NUMBER[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_INFO_EXT_TX_EVENT_RING_NUMBER_SHFT 0 + +/* +* ---WPDMA_INT_RX_PRI_SEL (0x18025000 + 0x298)--- +* WPDMA_INT_RX_RING0_PRI_SEL[0] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_RX_RING1_PRI_SEL[1] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_RX_RING2_PRI_SEL[2] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_RX_RING3_PRI_SEL[3] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* RESERVED4[31..4] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING3_PRI_SEL_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_RX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING3_PRI_SEL_MASK \ + \ + 0x00000008 /* WPDMA_INT_RX_RING3_PRI_SEL[3] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING3_PRI_SEL_SHFT \ + \ + 3 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING2_PRI_SEL_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_RX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING2_PRI_SEL_MASK \ + \ + 0x00000004 /* WPDMA_INT_RX_RING2_PRI_SEL[2] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING2_PRI_SEL_SHFT \ + \ + 2 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING1_PRI_SEL_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_RX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING1_PRI_SEL_MASK \ + \ + 0x00000002 /* WPDMA_INT_RX_RING1_PRI_SEL[1] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING1_PRI_SEL_SHFT \ + \ + 1 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING0_PRI_SEL_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_RX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING0_PRI_SEL_MASK \ + \ + 0x00000001 /* WPDMA_INT_RX_RING0_PRI_SEL[0] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_RX_PRI_SEL_WPDMA_INT_RX_RING0_PRI_SEL_SHFT \ + \ + 0 + +/* +* ---WPDMA_INT_TX_PRI_SEL (0x18025000 + 0x29C)--- +* WPDMA_INT_TX_RING0_PRI_SEL[0] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING1_PRI_SEL[1] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING2_PRI_SEL[2] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING3_PRI_SEL[3] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING4_PRI_SEL[4] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING5_PRI_SEL[5] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING6_PRI_SEL[6] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING7_PRI_SEL[7] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING8_PRI_SEL[8] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING9_PRI_SEL[9] - (RW) write 1 to enable corresponding ring to +* be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING10_PRI_SEL[10] - (RW) write 1 to enable corresponding ring +* to be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING11_PRI_SEL[11] - (RW) write 1 to enable corresponding ring +* to be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING12_PRI_SEL[12] - (RW) write 1 to enable corresponding ring +* to be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING13_PRI_SEL[13] - (RW) write 1 to enable corresponding ring +* to be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING14_PRI_SEL[14] - (RW) write 1 to enable corresponding ring +* to be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* RESERVED15[15] - (RO) Reserved bits +* WPDMA_INT_TX_RING16_PRI_SEL[16] - (RW) write 1 to enable corresponding ring +* to be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING17_PRI_SEL[17] - (RW) write 1 to enable corresponding ring +* to be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING18_PRI_SEL[18] - (RW) write 1 to enable corresponding ring +* to be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING19_PRI_SEL[19] - (RW) write 1 to enable corresponding ring +* to be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* WPDMA_INT_TX_RING20_PRI_SEL[20] - (RW) write 1 to enable corresponding ring +* to be priority-selected interrupt for MSI message[6:0] and CIRQ[45:38], write +* 1'b0 to disable and combine it into legacy interrupt +* RESERVED21[31..21] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING20_PRI_SEL_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING20_PRI_SEL_MASK \ + \ + 0x00100000 /* WPDMA_INT_TX_RING20_PRI_SEL[20] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING20_PRI_SEL_SHFT \ + \ + 20 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING19_PRI_SEL_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING19_PRI_SEL_MASK \ + \ + 0x00080000 /* WPDMA_INT_TX_RING19_PRI_SEL[19] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING19_PRI_SEL_SHFT \ + \ + 19 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING18_PRI_SEL_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING18_PRI_SEL_MASK \ + \ + 0x00040000 /* WPDMA_INT_TX_RING18_PRI_SEL[18] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING18_PRI_SEL_SHFT \ + \ + 18 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING17_PRI_SEL_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING17_PRI_SEL_MASK \ + \ + 0x00020000 /* WPDMA_INT_TX_RING17_PRI_SEL[17] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING17_PRI_SEL_SHFT \ + \ + 17 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING16_PRI_SEL_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING16_PRI_SEL_MASK \ + \ + 0x00010000 /* WPDMA_INT_TX_RING16_PRI_SEL[16] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING16_PRI_SEL_SHFT \ + \ + 16 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING14_PRI_SEL_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING14_PRI_SEL_MASK \ + \ + 0x00004000 /* WPDMA_INT_TX_RING14_PRI_SEL[14] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING14_PRI_SEL_SHFT \ + \ + 14 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING13_PRI_SEL_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING13_PRI_SEL_MASK \ + \ + 0x00002000 /* WPDMA_INT_TX_RING13_PRI_SEL[13] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING13_PRI_SEL_SHFT \ + \ + 13 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING12_PRI_SEL_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING12_PRI_SEL_MASK \ + \ + 0x00001000 /* WPDMA_INT_TX_RING12_PRI_SEL[12] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING12_PRI_SEL_SHFT \ + \ + 12 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING11_PRI_SEL_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING11_PRI_SEL_MASK \ + \ + 0x00000800 /* WPDMA_INT_TX_RING11_PRI_SEL[11] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING11_PRI_SEL_SHFT \ + \ + 11 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING10_PRI_SEL_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING10_PRI_SEL_MASK \ + \ + 0x00000400 /* WPDMA_INT_TX_RING10_PRI_SEL[10] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING10_PRI_SEL_SHFT \ + \ + 10 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING9_PRI_SEL_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING9_PRI_SEL_MASK \ + \ + 0x00000200 /* WPDMA_INT_TX_RING9_PRI_SEL[9] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING9_PRI_SEL_SHFT \ + \ + 9 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING8_PRI_SEL_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING8_PRI_SEL_MASK \ + \ + 0x00000100 /* WPDMA_INT_TX_RING8_PRI_SEL[8] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING8_PRI_SEL_SHFT \ + \ + 8 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING7_PRI_SEL_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING7_PRI_SEL_MASK \ + \ + 0x00000080 /* WPDMA_INT_TX_RING7_PRI_SEL[7] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING7_PRI_SEL_SHFT \ + \ + 7 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING6_PRI_SEL_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING6_PRI_SEL_MASK \ + \ + 0x00000040 /* WPDMA_INT_TX_RING6_PRI_SEL[6] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING6_PRI_SEL_SHFT \ + \ + 6 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING5_PRI_SEL_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING5_PRI_SEL_MASK \ + \ + 0x00000020 /* WPDMA_INT_TX_RING5_PRI_SEL[5] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING5_PRI_SEL_SHFT \ + \ + 5 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING4_PRI_SEL_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING4_PRI_SEL_MASK \ + \ + 0x00000010 /* WPDMA_INT_TX_RING4_PRI_SEL[4] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING4_PRI_SEL_SHFT \ + \ + 4 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING3_PRI_SEL_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING3_PRI_SEL_MASK \ + \ + 0x00000008 /* WPDMA_INT_TX_RING3_PRI_SEL[3] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING3_PRI_SEL_SHFT \ + \ + 3 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING2_PRI_SEL_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING2_PRI_SEL_MASK \ + \ + 0x00000004 /* WPDMA_INT_TX_RING2_PRI_SEL[2] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING2_PRI_SEL_SHFT \ + \ + 2 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING1_PRI_SEL_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING1_PRI_SEL_MASK \ + \ + 0x00000002 /* WPDMA_INT_TX_RING1_PRI_SEL[1] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING1_PRI_SEL_SHFT \ + \ + 1 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING0_PRI_SEL_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING0_PRI_SEL_MASK \ + \ + 0x00000001 /* WPDMA_INT_TX_RING0_PRI_SEL[0] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_INT_TX_PRI_SEL_WPDMA_INT_TX_RING0_PRI_SEL_SHFT \ + \ + 0 + +/* +* ---WPDMA_TX_DBG0 (0x18025000 + 0x2A0)--- +* WPDMA_TX_DBG0[31..0] - (RO) xxx +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_DBG0_WPDMA_TX_DBG0_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_DBG0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_DBG0_WPDMA_TX_DBG0_MASK \ + 0xFFFFFFFF /* WPDMA_TX_DBG0[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_DBG0_WPDMA_TX_DBG0_SHFT 0 + +/* +* ---WPDMA_TX_DBG1 (0x18025000 + 0x2A4)--- +* WPDMA_TX_DBG1[31..0] - (RO) xxx +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_DBG1_WPDMA_TX_DBG1_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_DBG1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_DBG1_WPDMA_TX_DBG1_MASK \ + 0xFFFFFFFF /* WPDMA_TX_DBG1[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_DBG1_WPDMA_TX_DBG1_SHFT 0 + +/* +* ---WPDMA_RX_DBG0 (0x18025000 + 0x2A8)--- +* WPDMA_RX_DBG0[31..0] - (RO) xxx +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_DBG0_WPDMA_RX_DBG0_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_DBG0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_DBG0_WPDMA_RX_DBG0_MASK \ + 0xFFFFFFFF /* WPDMA_RX_DBG0[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_DBG0_WPDMA_RX_DBG0_SHFT 0 + +/* +* ---WPDMA_RX_DBG1 (0x18025000 + 0x2AC)--- +* WPDMA_RX_DBG1[31..0] - (RO) xxx +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_DBG1_WPDMA_RX_DBG1_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_DBG1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_DBG1_WPDMA_RX_DBG1_MASK \ + 0xFFFFFFFF /* WPDMA_RX_DBG1[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_DBG1_WPDMA_RX_DBG1_SHFT 0 + +/* +* ---WPDMA_GLO_CFG_EXT0 (0x18025000 + 0x2B0)--- +* CSR_MAX_PREFETCH_CNT[1..0] - (RW) Max. dmad count per prefet request, +* 2'b00 : 1 entry, 2'b01 : 2 entries, 2'b10 : 4 entries, 2'b11 : 8 entries, Note +* : 1 entry(dmad size) is 16 bytes = 4 DWs = 2 QWs +* CSR_MEM_BST_SIZE[3..2] - (RW) Max. burst size per sram request. 00 : +* 16-byte, 01 : 32-byte, 10 : 64-byte, 11 : 128-byte +* CSR_MEM_ARB_LOCK_EN[4] - (RW) 1'b1 : Lock round-robin sram access +* arbiter until whole long burst request from dma FSM finish, 1'b0 : no lock +sram +* arbiter, grant will be change per request due to round-robin +* CSR_RX_DMA_WBQ_EN[5] - (RW) 1'b1 : RX dmad will be posted-write and +* deal with next received packet immediately, 1'b0 : RX dmad will be written +back +* immediately after received packet has been sent to host memory +* CSR_TX_DMASHDL_ENABLE[6] - (RW) 1'b1 : request DMASHDL before TX to +* select next TX ring, 1'b0 : disable DMASHDL and use round-robin arbiter to +* select next TX ring +* CSR_BRESP_ERROR_BYPASS_EN[7] - (RW) 1'b1 : Bypass AXI error bresp as a +* normal response. 1'b0 : Will not assert bready to error bresp(00 : OKAY, 01 : +* EXOKAY, 10 : SLVERR, 11 : DECERR) +* CSR_AXI_SLEEP_MODE[9..8] - (RW) 2'b00 : no sleep, normal TX/RX, 2b1* : +* sleep after AXI request, 2'b11 : force assertion of wvalid, rready and bready +* to finish all committed data phases, then sleep immediately +* RESERVED10[14..10] - (RO) Reserved bits +* CSR_Q_STATUS_IDX_BKRS_EN[15] - (RW) backup/restore enable bit for +* q_status(payload, prefetch and dispatch) index +* CSR_AXI_BST_SIZE[17..16] - (RW) AXI busrt length, 00 : 128-byte, 01 : +* 64-byte, 10 : 32-byte, 11 : 16-byte +* RESERVED18[18] - (RO) Reserved bits +* CSR_AXI_FAKE[19] - (RW) If set to 1'b1, all requests from DMA +* engine will not be sent to AXI INFRA, this try to fix AXI bus hang issue +temporarily! +* CSR_DMAD_PREFETCH_THRESHOLD[21..20] - (RW) trigger dmad prefetch when +* available dmad cnt >= {1(2'b00), 2(2'b01), 4(2'b10), 8(2'b11)} +* CSR_BID_CHECK_BYPASS_EN[22] - (RW) If set to 1'b0, axi master will check +* matching between awid and bid before assert bready, if set to 1'b1, it will +* bypass this checking and assert bready for each bvalid even though bid doesn't +* match any awid ever issued! +* CSR_RX_INFO_WB_EN[23] - (RW) If set to 1'b0, only DW0 and DW1 will be +* written back into memory after received RX packet process finished, this will +* save bus bandwidth a little because DW2 and DW3 are useless for FW +* CSR_AXI_OUTSTANDING_NUM[27..24] - (RW) decide max. outstanding AXI requests, +* common for AXI read or write! +* CSR_AXI_ARUSER_LOCK_EN[28] - (RW) on/off customized lock ctrl design thru AXI +* aruser signal, this will influence TX QoS ctrl +* CSR_AXI_AWUSER_LOCK_EN[29] - (RW) on/off customized lock ctrl design thru AXI +* awuser signal when RX dmad write-back have to be separately written into +* memory due to external dispatcher exists! +* CSR_AXI_LOCK_EN[30] - (RW) Global lock enable to on/off AXI spec. +* lock(axlock) behavior and also will on/off customized lock ctrl design thru +* AXI awuser signal +* CSR_AXI_CLKGATE_BYP[31] - (RW) To bypass functional CG enable which +* incduced from coding style for DC inserted CG cell in all AXI read/write +master +* design module +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_CLKGATE_BYP_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_CLKGATE_BYP_MASK \ + 0x80000000 /* CSR_AXI_CLKGATE_BYP[31] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_CLKGATE_BYP_SHFT 31 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_LOCK_EN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_LOCK_EN_MASK \ + 0x40000000 /* CSR_AXI_LOCK_EN[30] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_LOCK_EN_SHFT 30 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_AWUSER_LOCK_EN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_AWUSER_LOCK_EN_MASK \ + 0x20000000 /* CSR_AXI_AWUSER_LOCK_EN[29] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_AWUSER_LOCK_EN_SHFT 29 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_ARUSER_LOCK_EN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_ARUSER_LOCK_EN_MASK \ + 0x10000000 /* CSR_AXI_ARUSER_LOCK_EN[28] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_ARUSER_LOCK_EN_SHFT 28 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_OUTSTANDING_NUM_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_OUTSTANDING_NUM_MASK \ + 0x0F000000 /* CSR_AXI_OUTSTANDING_NUM[27..24] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_OUTSTANDING_NUM_SHFT 24 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_RX_INFO_WB_EN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_RX_INFO_WB_EN_MASK \ + 0x00800000 /* CSR_RX_INFO_WB_EN[23] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_RX_INFO_WB_EN_SHFT 23 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_BID_CHECK_BYPASS_EN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_BID_CHECK_BYPASS_EN_MASK \ + 0x00400000 /* CSR_BID_CHECK_BYPASS_EN[22] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_BID_CHECK_BYPASS_EN_SHFT 22 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_DMAD_PREFETCH_THRESHOLD_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_DMAD_PREFETCH_THRESHOLD_MASK \ + 0x00300000 /* CSR_DMAD_PREFETCH_THRESHOLD[21..20] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_DMAD_PREFETCH_THRESHOLD_SHFT \ + 20 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_FAKE_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_FAKE_MASK \ + 0x00080000 /* CSR_AXI_FAKE[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_FAKE_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_BST_SIZE_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_BST_SIZE_MASK \ + 0x00030000 /* CSR_AXI_BST_SIZE[17..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_BST_SIZE_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_Q_STATUS_IDX_BKRS_EN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_Q_STATUS_IDX_BKRS_EN_MASK \ + 0x00008000 /* CSR_Q_STATUS_IDX_BKRS_EN[15] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_Q_STATUS_IDX_BKRS_EN_SHFT 15 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_SLEEP_MODE_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_SLEEP_MODE_MASK \ + 0x00000300 /* CSR_AXI_SLEEP_MODE[9..8] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_AXI_SLEEP_MODE_SHFT 8 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_BRESP_ERROR_BYPASS_EN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_BRESP_ERROR_BYPASS_EN_MASK \ + 0x00000080 /* CSR_BRESP_ERROR_BYPASS_EN[7] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_BRESP_ERROR_BYPASS_EN_SHFT 7 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_TX_DMASHDL_ENABLE_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_TX_DMASHDL_ENABLE_MASK \ + 0x00000040 /* CSR_TX_DMASHDL_ENABLE[6] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_TX_DMASHDL_ENABLE_SHFT 6 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_RX_DMA_WBQ_EN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_RX_DMA_WBQ_EN_MASK \ + 0x00000020 /* CSR_RX_DMA_WBQ_EN[5] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_RX_DMA_WBQ_EN_SHFT 5 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_MEM_ARB_LOCK_EN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_MEM_ARB_LOCK_EN_MASK \ + 0x00000010 /* CSR_MEM_ARB_LOCK_EN[4] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_MEM_ARB_LOCK_EN_SHFT 4 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_MEM_BST_SIZE_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_MEM_BST_SIZE_MASK \ + 0x0000000C /* CSR_MEM_BST_SIZE[3..2] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_MEM_BST_SIZE_SHFT 2 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_MAX_PREFETCH_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_MAX_PREFETCH_CNT_MASK \ + 0x00000003 /* CSR_MAX_PREFETCH_CNT[1..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT0_CSR_MAX_PREFETCH_CNT_SHFT 0 + +/* +* ---WPDMA_GLO_CFG_EXT1 (0x18025000 + 0x2B4)--- +* CSR_TXFIFO0_RDY_THRESHOLD[7..0] - (RW) xxx +* CSR_TXFIFO1_RDY_THRESHOLD[15..8] - (RW) xxx +* CSR_TX_DISP_ARB_SCHEDULED_ACCESS_TIMER[23..16] - (RW) timer setting for +* SCHEDULED_ACCESS_TIME_ARB of csr_tx_disp_arb_mode +* CSR_TX_DISP_ARB_MODE[25..24] - (RW) 00 : FAIR_ARB, 01 : FIX_ARB, 10 : +* UNBALANCED_ARB, 11 : SCHEDULED_ACCESS_TIME_ARB +* CSR_FWDL_FLOW_CTRL_BYASS_EN[26] - (RW) To disable firmware download TX flow +* control of TX dma(host_dma1) when firmare download of RX dma(mcu_dma1) is in +* firmware download polling mode!! Remember to set to 1'b0 when firmware +download +* ring is set back to normal ring usage which should be in flow control for +* correct behavior!! +* CSR_FWDL_FLOW_CTRL_BYASS_LS_QSEL_EN[27] - (RW) select firmware download TX +* ring(LSB/MSB ring) to bypass TX flow control when firmare download RX +* ring(LSB/MSB ring) of RX dma(mcu_dma1) is in firmware download polling mode!! +* RESERVED[31..28] - (RW) reserved +*/ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_CSR_FWDL_FLOW_CTRL_BYASS_LS_QSEL_EN_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_CSR_FWDL_FLOW_CTRL_BYASS_LS_QSEL_EN_MASK \ + \ + 0x08000000 /* CSR_FWDL_FLOW_CTRL_BYASS_LS_QSEL_EN[27] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_CSR_FWDL_FLOW_CTRL_BYASS_LS_QSEL_EN_SHFT \ + \ + 27 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_CSR_FWDL_FLOW_CTRL_BYASS_EN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_CSR_FWDL_FLOW_CTRL_BYASS_EN_MASK \ + 0x04000000 /* CSR_FWDL_FLOW_CTRL_BYASS_EN[26] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_CSR_FWDL_FLOW_CTRL_BYASS_EN_SHFT \ + 26 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_CSR_TX_DISP_ARB_MODE_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_CSR_TX_DISP_ARB_MODE_MASK \ + 0x03000000 /* CSR_TX_DISP_ARB_MODE[25..24] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_CSR_TX_DISP_ARB_MODE_SHFT 24 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_CSR_TX_DISP_ARB_SCHEDULED_ACCESS_TIMER_AD\ +DR \ +\ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_CSR_TX_DISP_ARB_SCHEDULED_ACCESS_TIMER_MA\ +SK \ +\ + 0x00FF0000 /* CSR_TX_DISP_ARB_SCHEDULED_ACCESS_TIMER[23..16] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_CSR_TX_DISP_ARB_SCHEDULED_ACCESS_TIMER_SH\ +FT \ +\ + 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_CSR_TXFIFO1_RDY_THRESHOLD_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_CSR_TXFIFO1_RDY_THRESHOLD_MASK \ + 0x0000FF00 /* CSR_TXFIFO1_RDY_THRESHOLD[15..8] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_CSR_TXFIFO1_RDY_THRESHOLD_SHFT 8 +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_CSR_TXFIFO0_RDY_THRESHOLD_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_CSR_TXFIFO0_RDY_THRESHOLD_MASK \ + 0x000000FF /* CSR_TXFIFO0_RDY_THRESHOLD[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_GLO_CFG_EXT1_CSR_TXFIFO0_RDY_THRESHOLD_SHFT 0 + +/* +* ---WPDMA_TX_QOS_LMT_CFG0 (0x18025000 + 0x2C0)--- +* CSR_TX_PLD_AXI_LIMITER_REQ[2..0] - (RW) QoS CR, Limiter Enable for packet +* traffice of type TX_PLD +* CSR_TX_PLD_AXI_LIMITER_EN_REQ[3] - (RW) QoS CR, Limiter Enable for packet +* traffice of type TX_PLD +* CSR_TX_PLD_AXI_LIMITER_PKT[6..4] - (RW) QoS CR, Limiter Enable for packet +* traffice of type TX_PLD +* CSR_TX_PLD_AXI_LIMITER_EN_PKT[7] - (RW) QoS CR, Limiter Enable for packet +* traffice of type TX_PLD +* CSR_RX_PLD_AXI_LIMITER_REQ[10..8] - (RW) QoS CR, Limiter Enable for request +* traffice of type RX_PLD +* CSR_RX_PLD_AXI_LIMITER_EN_REQ[11] - (RW) QoS CR, Limiter Enable for request +* traffice of type RX_PLD +* CSR_RX_PLD_AXI_LIMITER_PKT[14..12] - (RW) QoS CR, Limiter Enable for request +* traffice of type RX_PLD +* CSR_RX_PLD_AXI_LIMITER_EN_PKT[15] - (RW) QoS CR, Limiter Enable for request +* traffice of type RX_PLD +* RESERVED16[31..16] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_EN_PKT_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_EN_PKT_MASK \ + \ + 0x00008000 /* CSR_RX_PLD_AXI_LIMITER_EN_PKT[15] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_EN_PKT_SHFT \ + \ + 15 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_PKT_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_PKT_MASK \ + \ + 0x00007000 /* CSR_RX_PLD_AXI_LIMITER_PKT[14..12] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_PKT_SHFT \ + \ + 12 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_EN_REQ_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_EN_REQ_MASK \ + \ + 0x00000800 /* CSR_RX_PLD_AXI_LIMITER_EN_REQ[11] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_EN_REQ_SHFT \ + \ + 11 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_REQ_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_REQ_MASK \ + \ + 0x00000700 /* CSR_RX_PLD_AXI_LIMITER_REQ[10..8] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_RX_PLD_AXI_LIMITER_REQ_SHFT \ + \ + 8 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_AXI_LIMITER_EN_PKT_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_AXI_LIMITER_EN_PKT_MASK \ + \ + 0x00000080 /* CSR_TX_PLD_AXI_LIMITER_EN_PKT[7] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_AXI_LIMITER_EN_PKT_SHFT \ + \ + 7 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_AXI_LIMITER_PKT_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_AXI_LIMITER_PKT_MASK \ + \ + 0x00000070 /* CSR_TX_PLD_AXI_LIMITER_PKT[6..4] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_AXI_LIMITER_PKT_SHFT \ + \ + 4 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_AXI_LIMITER_EN_REQ_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_AXI_LIMITER_EN_REQ_MASK \ + \ + 0x00000008 /* CSR_TX_PLD_AXI_LIMITER_EN_REQ[3] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_AXI_LIMITER_EN_REQ_SHFT \ + \ + 3 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_AXI_LIMITER_REQ_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_AXI_LIMITER_REQ_MASK \ + \ + 0x00000007 /* CSR_TX_PLD_AXI_LIMITER_REQ[2..0] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG0_CSR_TX_PLD_AXI_LIMITER_REQ_SHFT \ + \ + 0 + +/* +* ---WPDMA_TX_QOS_LMT_CFG1 (0x18025000 + 0x2C4)--- +* CSR_AUX_TX_PLD_AXI_LIMITER_REQ[2..0] - (RW) QoS CR, Limiter value selected +* by PP dynamically +* RESERVED3[3] - (RO) Reserved bits +* CSR_AUX_TX_PLD_AXI_LIMITER_PKT[6..4] - (RW) QoS CR, Limiter value selected +* by PP dynamically +* RESERVED7[7] - (RO) Reserved bits +* CSR_AUX_RX_PLD_AXI_LIMITER_REQ[10..8] - (RW) QoS CR, Limiter value selected +* by PP dynamically +* RESERVED11[11] - (RO) Reserved bits +* CSR_AUX_RX_PLD_AXI_LIMITER_PKT[14..12] - (RW) QoS CR, Limiter value selected +* by PP dynamically +* RESERVED15[31..15] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_RX_PLD_AXI_LIMITER_PKT_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG1_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_RX_PLD_AXI_LIMITER_PKT_MASK \ + \ + 0x00007000 /* CSR_AUX_RX_PLD_AXI_LIMITER_PKT[14..12] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_RX_PLD_AXI_LIMITER_PKT_SHFT \ + \ + 12 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_RX_PLD_AXI_LIMITER_REQ_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG1_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_RX_PLD_AXI_LIMITER_REQ_MASK \ + \ + 0x00000700 /* CSR_AUX_RX_PLD_AXI_LIMITER_REQ[10..8] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_RX_PLD_AXI_LIMITER_REQ_SHFT \ + \ + 8 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_TX_PLD_AXI_LIMITER_PKT_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG1_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_TX_PLD_AXI_LIMITER_PKT_MASK \ + \ + 0x00000070 /* CSR_AUX_TX_PLD_AXI_LIMITER_PKT[6..4] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_TX_PLD_AXI_LIMITER_PKT_SHFT \ + \ + 4 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_TX_PLD_AXI_LIMITER_REQ_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG1_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_TX_PLD_AXI_LIMITER_REQ_MASK \ + \ + 0x00000007 /* CSR_AUX_TX_PLD_AXI_LIMITER_REQ[2..0] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG1_CSR_AUX_TX_PLD_AXI_LIMITER_REQ_SHFT \ + \ + 0 + +/* +* ---WPDMA_TX_QOS_LMT_CFG2 (0x18025000 + 0x2C8)--- +* CSR_RX_RD_DMAD_AXI_LIMITER_REQ[2..0] - (RW) QoS CR, Limiter Value for +* packet traffice of type RX_RD_DMAD +* CSR_RX_RD_DMAD_AXI_LIMITER_EN_REQ[3] - (RW) QoS CR, Limiter Enable for +* request traffice of type RX_RD_DMAD +* CSR_RX_RD_DMAD_AXI_LIMITER_PKT[6..4] - (RW) QoS CR, Limiter Value for +* packet traffice of type RX_RD_DMAD +* CSR_RX_RD_DMAD_AXI_LIMITER_EN_PKT[7] - (RW) QoS CR, Limiter Enable for +* packet traffice of type RX_RD_DMAD +* CSR_RX_WR_DMAD_AXI_LIMITER_REQ[10..8] - (RW) QoS CR, Limiter Value for +* packet traffice of type RX_WR_DMAD +* CSR_RX_WR_DMAD_AXI_LIMITER_EN_REQ[11] - (RW) QoS CR, Limiter Enable for +* request traffice of type RX_WR_DMAD +* CSR_RX_WR_DMAD_AXI_LIMITER_PKT[14..12] - (RW) QoS CR, Limiter Value for +* packet traffice of type RX_WR_DMAD +* CSR_RX_WR_DMAD_AXI_LIMITER_EN_PKT[15] - (RW) QoS CR, Limiter Enable for +* packet traffice of type RX_WR_DMAD +* CSR_TX_RD_DMAD_AXI_LIMITER_REQ[18..16] - (RW) QoS CR, Limiter Value for +* packet traffice of type TX_RD_DMAD +* CSR_TX_RD_DMAD_AXI_LIMITER_EN_REQ[19] - (RW) QoS CR, Limiter Enable for +* request traffice of type TX_RD_DMAD +* CSR_TX_RD_DMAD_AXI_LIMITER_PKT[22..20] - (RW) QoS CR, Limiter Value for +* packet traffice of type TX_RD_DMAD +* CSR_TX_RD_DMAD_AXI_LIMITER_EN_PKT[23] - (RW) QoS CR, Limiter Enable for +* packet traffice of type TX_RD_DMAD +* CSR_TX_WR_DMAD_AXI_LIMITER_REQ[26..24] - (RW) QoS CR, Limiter Value for +* packet traffice of type TX_WR_DMAD +* CSR_TX_WR_DMAD_AXI_LIMITER_EN_REQ[27] - (RW) QoS CR, Limiter Enable for +* request traffice of type TX_WR_DMAD +* CSR_TX_WR_DMAD_AXI_LIMITER_PKT[30..28] - (RW) QoS CR, Limiter Value for +* packet traffice of type TX_WR_DMAD +* CSR_TX_WR_DMAD_AXI_LIMITER_EN_PKT[31] - (RW) QoS CR, Limiter Enable for +* packet traffice of type TX_WR_DMAD +*/ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_EN_PKT_ADDR\ +\ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_EN_PKT_MASK\ +\ + 0x80000000 /* CSR_TX_WR_DMAD_AXI_LIMITER_EN_PKT[31] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_EN_PKT_SHFT\ +\ + 31 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_PKT_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_PKT_MASK \ + \ + 0x70000000 /* CSR_TX_WR_DMAD_AXI_LIMITER_PKT[30..28] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_PKT_SHFT \ + \ + 28 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_EN_REQ_ADDR\ +\ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_EN_REQ_MASK\ +\ + 0x08000000 /* CSR_TX_WR_DMAD_AXI_LIMITER_EN_REQ[27] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_EN_REQ_SHFT\ +\ + 27 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_REQ_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_REQ_MASK \ + \ + 0x07000000 /* CSR_TX_WR_DMAD_AXI_LIMITER_REQ[26..24] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_WR_DMAD_AXI_LIMITER_REQ_SHFT \ + \ + 24 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_EN_PKT_ADDR\ +\ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_EN_PKT_MASK\ +\ + 0x00800000 /* CSR_TX_RD_DMAD_AXI_LIMITER_EN_PKT[23] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_EN_PKT_SHFT\ +\ + 23 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_PKT_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_PKT_MASK \ + \ + 0x00700000 /* CSR_TX_RD_DMAD_AXI_LIMITER_PKT[22..20] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_PKT_SHFT \ + \ + 20 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_EN_REQ_ADDR\ +\ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_EN_REQ_MASK\ +\ + 0x00080000 /* CSR_TX_RD_DMAD_AXI_LIMITER_EN_REQ[19] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_EN_REQ_SHFT\ +\ + 19 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_REQ_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_REQ_MASK \ + \ + 0x00070000 /* CSR_TX_RD_DMAD_AXI_LIMITER_REQ[18..16] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_TX_RD_DMAD_AXI_LIMITER_REQ_SHFT \ + \ + 16 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_EN_PKT_ADDR\ +\ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_EN_PKT_MASK\ +\ + 0x00008000 /* CSR_RX_WR_DMAD_AXI_LIMITER_EN_PKT[15] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_EN_PKT_SHFT\ +\ + 15 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_PKT_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_PKT_MASK \ + \ + 0x00007000 /* CSR_RX_WR_DMAD_AXI_LIMITER_PKT[14..12] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_PKT_SHFT \ + \ + 12 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_EN_REQ_ADDR\ +\ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_EN_REQ_MASK\ +\ + 0x00000800 /* CSR_RX_WR_DMAD_AXI_LIMITER_EN_REQ[11] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_EN_REQ_SHFT\ +\ + 11 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_REQ_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_REQ_MASK \ + \ + 0x00000700 /* CSR_RX_WR_DMAD_AXI_LIMITER_REQ[10..8] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_WR_DMAD_AXI_LIMITER_REQ_SHFT \ + \ + 8 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_EN_PKT_ADDR\ +\ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_EN_PKT_MASK\ +\ + 0x00000080 /* CSR_RX_RD_DMAD_AXI_LIMITER_EN_PKT[7] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_EN_PKT_SHFT\ +\ + 7 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_PKT_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_PKT_MASK \ + \ + 0x00000070 /* CSR_RX_RD_DMAD_AXI_LIMITER_PKT[6..4] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_PKT_SHFT \ + \ + 4 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_EN_REQ_ADDR\ +\ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_EN_REQ_MASK\ +\ + 0x00000008 /* CSR_RX_RD_DMAD_AXI_LIMITER_EN_REQ[3] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_EN_REQ_SHFT\ +\ + 3 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_REQ_ADDR \ + \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_REQ_MASK \ + \ + 0x00000007 /* CSR_RX_RD_DMAD_AXI_LIMITER_REQ[2..0] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG2_CSR_RX_RD_DMAD_AXI_LIMITER_REQ_SHFT \ + \ + 0 + +/* +* ---WPDMA_TX_QOS_LMT_CFG3 (0x18025000 + 0x2CC)--- +* CSR_AUX_RX_RD_DMAD_AXI_LIMITER_REQ[2..0] - (RW) QoS CR, Limiter value +* selected by PP dynamically +* RESERVED3[3] - (RO) Reserved bits +* CSR_AUX_RX_RD_DMAD_AXI_LIMITER_PKT[6..4] - (RW) QoS CR, Limiter value +* selected by PP dynamically +* RESERVED7[7] - (RO) Reserved bits +* CSR_AUX_RX_WR_DMAD_AXI_LIMITER_REQ[10..8] - (RW) QoS CR, Limiter value +* selected by PP dynamically +* RESERVED11[11] - (RO) Reserved bits +* CSR_AUX_RX_WR_DMAD_AXI_LIMITER_PKT[14..12] - (RW) QoS CR, Limiter value +* selected by PP dynamically +* RESERVED15[15] - (RO) Reserved bits +* CSR_AUX_TX_RD_DMAD_AXI_LIMITER_REQ[18..16] - (RW) QoS CR, Limiter value +* selected by PP dynamically +* RESERVED19[19] - (RO) Reserved bits +* CSR_AUX_TX_RD_DMAD_AXI_LIMITER_PKT[22..20] - (RW) QoS CR, Limiter value +* selected by PP dynamically +* RESERVED23[23] - (RO) Reserved bits +* CSR_AUX_TX_WR_DMAD_AXI_LIMITER_REQ[26..24] - (RW) QoS CR, Limiter value +* selected by PP dynamically +* RESERVED27[27] - (RO) Reserved bits +* CSR_AUX_TX_WR_DMAD_AXI_LIMITER_PKT[30..28] - (RW) QoS CR, Limiter value +* selected by PP dynamically +* RESERVED31[31] - (RO) Reserved bits +*/ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_WR_DMAD_AXI_LIMITER_PKT_ADD\ +R \ +\ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_WR_DMAD_AXI_LIMITER_PKT_MAS\ +K \ +\ + 0x70000000 /* CSR_AUX_TX_WR_DMAD_AXI_LIMITER_PKT[30..28] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_WR_DMAD_AXI_LIMITER_PKT_SHF\ +T \ +\ + 28 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_WR_DMAD_AXI_LIMITER_REQ_ADD\ +R \ +\ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_WR_DMAD_AXI_LIMITER_REQ_MAS\ +K \ +\ + 0x07000000 /* CSR_AUX_TX_WR_DMAD_AXI_LIMITER_REQ[26..24] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_WR_DMAD_AXI_LIMITER_REQ_SHF\ +T \ +\ + 24 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_RD_DMAD_AXI_LIMITER_PKT_ADD\ +R \ +\ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_RD_DMAD_AXI_LIMITER_PKT_MAS\ +K \ +\ + 0x00700000 /* CSR_AUX_TX_RD_DMAD_AXI_LIMITER_PKT[22..20] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_RD_DMAD_AXI_LIMITER_PKT_SHF\ +T \ +\ + 20 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_RD_DMAD_AXI_LIMITER_REQ_ADD\ +R \ +\ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_RD_DMAD_AXI_LIMITER_REQ_MAS\ +K \ +\ + 0x00070000 /* CSR_AUX_TX_RD_DMAD_AXI_LIMITER_REQ[18..16] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_TX_RD_DMAD_AXI_LIMITER_REQ_SHF\ +T \ +\ + 16 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_WR_DMAD_AXI_LIMITER_PKT_ADD\ +R \ +\ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_WR_DMAD_AXI_LIMITER_PKT_MAS\ +K \ +\ + 0x00007000 /* CSR_AUX_RX_WR_DMAD_AXI_LIMITER_PKT[14..12] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_WR_DMAD_AXI_LIMITER_PKT_SHF\ +T \ +\ + 12 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_WR_DMAD_AXI_LIMITER_REQ_ADD\ +R \ +\ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_WR_DMAD_AXI_LIMITER_REQ_MAS\ +K \ +\ + 0x00000700 /* CSR_AUX_RX_WR_DMAD_AXI_LIMITER_REQ[10..8] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_WR_DMAD_AXI_LIMITER_REQ_SHF\ +T \ +\ + 8 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_RD_DMAD_AXI_LIMITER_PKT_ADD\ +R \ +\ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_RD_DMAD_AXI_LIMITER_PKT_MAS\ +K \ +\ + 0x00000070 /* CSR_AUX_RX_RD_DMAD_AXI_LIMITER_PKT[6..4] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_RD_DMAD_AXI_LIMITER_PKT_SHF\ +T \ +\ + 4 +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_RD_DMAD_AXI_LIMITER_REQ_ADD\ +R \ +\ + WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_ADDR +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_RD_DMAD_AXI_LIMITER_REQ_MAS\ +K \ +\ + 0x00000007 /* CSR_AUX_RX_RD_DMAD_AXI_LIMITER_REQ[2..0] */ +#define \ +WF_WFDMA_HOST_DMA1_WPDMA_TX_QOS_LMT_CFG3_CSR_AUX_RX_RD_DMAD_AXI_LIMITER_REQ_SHF\ +T \ +\ + 0 + +/* +* ---HOST_PRI_INT_STA (0x18025000 + 0x2E0)--- +* host_pri_int_sts_0[0] - (W1C) tx_done_int[18], W1C to clear delay +interrupt +* host_pri_int_sts_1[1] - (W1C) tx_done_int[19], W1C to clear delay +interrupt +* host_pri_int_sts_2[2] - (W1C) rx_done_int[0], W1C to clear delay +interrupt +* host_pri_int_sts_3[3] - (W1C) rx_done_int[1], W1C to clear delay +interrupt +* host_pri_int_sts_4[4] - (W1C) rx_done_int[2], W1C to clear delay +interrupt +* RESERVED5[31..5] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_HOST_PRI_INT_STA_host_pri_int_sts_4_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_PRI_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_PRI_INT_STA_host_pri_int_sts_4_MASK \ + 0x00000010 /* host_pri_int_sts_4[4] */ +#define WF_WFDMA_HOST_DMA1_HOST_PRI_INT_STA_host_pri_int_sts_4_SHFT 4 +#define WF_WFDMA_HOST_DMA1_HOST_PRI_INT_STA_host_pri_int_sts_3_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_PRI_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_PRI_INT_STA_host_pri_int_sts_3_MASK \ + 0x00000008 /* host_pri_int_sts_3[3] */ +#define WF_WFDMA_HOST_DMA1_HOST_PRI_INT_STA_host_pri_int_sts_3_SHFT 3 +#define WF_WFDMA_HOST_DMA1_HOST_PRI_INT_STA_host_pri_int_sts_2_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_PRI_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_PRI_INT_STA_host_pri_int_sts_2_MASK \ + 0x00000004 /* host_pri_int_sts_2[2] */ +#define WF_WFDMA_HOST_DMA1_HOST_PRI_INT_STA_host_pri_int_sts_2_SHFT 2 +#define WF_WFDMA_HOST_DMA1_HOST_PRI_INT_STA_host_pri_int_sts_1_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_PRI_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_PRI_INT_STA_host_pri_int_sts_1_MASK \ + 0x00000002 /* host_pri_int_sts_1[1] */ +#define WF_WFDMA_HOST_DMA1_HOST_PRI_INT_STA_host_pri_int_sts_1_SHFT 1 +#define WF_WFDMA_HOST_DMA1_HOST_PRI_INT_STA_host_pri_int_sts_0_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_PRI_INT_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_PRI_INT_STA_host_pri_int_sts_0_MASK \ + 0x00000001 /* host_pri_int_sts_0[0] */ +#define WF_WFDMA_HOST_DMA1_HOST_PRI_INT_STA_host_pri_int_sts_0_SHFT 0 + +/* +* ---HOST_PER_INT_ENA_STA (0x18025000 + 0x2E4)--- +* wpdma_per_int_sts[3..0] - (W1C) status bit for rx ring periodic delayed +* interrupt to tracking ring is full or not, start delayed interrupt timer when +* RX ring is not full from falling edge of full flag and reset when ring full +* flag is asserted +* RESERVED4[15..4] - (RO) Reserved bits +* wpdma_per_int_ena[19..16] - (RW) enable bit for rx ring periodic delayed +* interrupt to tracking ring is full or not, start delayed interrupt timer when +* RX ring is not full from falling edge of full flag and reset when ring full +* flag is asserted +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_HOST_PER_INT_ENA_STA_wpdma_per_int_ena_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_PER_INT_ENA_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_PER_INT_ENA_STA_wpdma_per_int_ena_MASK \ + 0x000F0000 /* wpdma_per_int_ena[19..16] */ +#define WF_WFDMA_HOST_DMA1_HOST_PER_INT_ENA_STA_wpdma_per_int_ena_SHFT 16 +#define WF_WFDMA_HOST_DMA1_HOST_PER_INT_ENA_STA_wpdma_per_int_sts_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_PER_INT_ENA_STA_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_PER_INT_ENA_STA_wpdma_per_int_sts_MASK \ + 0x0000000F /* wpdma_per_int_sts[3..0] */ +#define WF_WFDMA_HOST_DMA1_HOST_PER_INT_ENA_STA_wpdma_per_int_sts_SHFT 0 + +/* +* ---HOST_PER_DLY_INT_CFG (0x18025000 + 0x2E8)--- +* wpdma_per_max_ptime[7..0] - (RW) Specified Max pending time for the +* internal RX ring full flag falling edge. When the pending time equal or +greater +* PER_MAX_PTIME x 20us or the # of pended TX_DONE_INT equal or greater than +* TX_MAX_PINT (see above), an Final TX_DLY_INT is generated +* Set to 0 will disable pending interrupt +* time check +* wpdma_per_dly_int_en[11..8] - (RW) RX periodic Delayed Interrupt Enable +* 1: Enable RX periodic delayed interrupt +mechanism +* 0: Disable RX periodic delayed interrupt +mechanism +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_HOST_PER_DLY_INT_CFG_wpdma_per_dly_int_en_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_PER_DLY_INT_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_PER_DLY_INT_CFG_wpdma_per_dly_int_en_MASK \ + 0x00000F00 /* wpdma_per_dly_int_en[11..8] */ +#define WF_WFDMA_HOST_DMA1_HOST_PER_DLY_INT_CFG_wpdma_per_dly_int_en_SHFT 8 +#define WF_WFDMA_HOST_DMA1_HOST_PER_DLY_INT_CFG_wpdma_per_max_ptime_ADDR \ + WF_WFDMA_HOST_DMA1_HOST_PER_DLY_INT_CFG_ADDR +#define WF_WFDMA_HOST_DMA1_HOST_PER_DLY_INT_CFG_wpdma_per_max_ptime_MASK \ + 0x000000FF /* wpdma_per_max_ptime[7..0] */ +#define WF_WFDMA_HOST_DMA1_HOST_PER_DLY_INT_CFG_wpdma_per_max_ptime_SHFT 0 + +/* +* ---WPDMA_PRI_DLY_INT_CFG0 (0x18025000 + 0x2F0)--- +* PRI0_MAX_PTIME[7..0] - (RW) Specified Max pending time for the +* internal PRI0_DONE_INT. When the pending time equal or greater PRI0_MAX_PTIME +x +* 20us or the # of pended PRI0_DONE_INT equal or greater than PRI0_MAX_PINT (see +* above), an Final PRI0_DLY_INT is generated +* Set to 0 will disable pending interrupt +* time check +* PRI0_MAX_PINT[14..8] - (RW) Specified Max # of pended interrupts. +* When the # of pended interrupts equal or +* greater than the value specified here or interrupt pending time reach the +limit +* (See below), a Final PRI0_DLY_INT is generated. +* Set to 0 will disable pending interrupt +* count check +* PRI0_DLY_INT_EN[15] - (RW) Priority Delayed Interrupt Enable +* 1: Enable Priority delayed interrupt +mechanism +* 0: Disable Priority delayed interrupt +mechanism +* In AXE host_dma0, these PRI1_* settings are +* for rx_ring[1]_int, and PRI0_* settings are for rx_ring[0]_int +* In AXE host_dma1, these PRI1_* settings are +* for rx_ring[0]_int, and PRI0_* settings are for Ored-tx_ring[14:0]_int +* In AXE mcu_dma0 and mcu_dma1, there are no +* priority interrupt thus no this 0x2E0 CR!! +* PRI1_MAX_PTIME[23..16] - (RW) Specified Max pending time for the +* internal PRI1_DONE_INT. When the pending time equal or greater PRI1_MAX_PTIME +x +* 20us or the # of pended PRI1_DONE_INT equal or greater than PRI1_MAX_PINT (see +* above), an Final PRI1_DLY_INT is generated +* Set to 0 will disable pending interrupt +* time check +* PRI1_MAX_PINT[30..24] - (RW) Specified Max # of pended interrupts. +* When the # of pended interrupts equal or +* greater than the value specified here or interrupt pending time reach the +limit +* (See below), a Final PRI1_DLY_INT is generated. +* Set to 0 will disable pending interrupt +* count check +* PRI1_DLY_INT_EN[31] - (RW) Priority Delayed Interrupt Enable +* 1: Enable Priority delayed interrupt +mechanism +* 0: Disable Priority delayed interrupt +mechanism +* In AXE host_dma0, these PRI1_* settings are +* for rx_ring[1]_int, and PRI0_* settings are for rx_ring[0]_int +* In AXE host_dma1, these PRI1_* settings are +* for rx_ring[0]_int, and PRI0_* settings are for Ored-tx_ring[14:0]_int +* In AXE mcu_dma0 and mcu_dma1, there are no +* priority interrupt thus no this 0x2E0 CR!! +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_PRI1_DLY_INT_EN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_PRI1_DLY_INT_EN_MASK \ + 0x80000000 /* PRI1_DLY_INT_EN[31] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_PRI1_DLY_INT_EN_SHFT 31 +#define WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_PRI1_MAX_PINT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_PRI1_MAX_PINT_MASK \ + 0x7F000000 /* PRI1_MAX_PINT[30..24] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_PRI1_MAX_PINT_SHFT 24 +#define WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_PRI1_MAX_PTIME_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_PRI1_MAX_PTIME_MASK \ + 0x00FF0000 /* PRI1_MAX_PTIME[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_PRI1_MAX_PTIME_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_PRI0_DLY_INT_EN_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_PRI0_DLY_INT_EN_MASK \ + 0x00008000 /* PRI0_DLY_INT_EN[15] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_PRI0_DLY_INT_EN_SHFT 15 +#define WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_PRI0_MAX_PINT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_PRI0_MAX_PINT_MASK \ + 0x00007F00 /* PRI0_MAX_PINT[14..8] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_PRI0_MAX_PINT_SHFT 8 +#define WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_PRI0_MAX_PTIME_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_PRI0_MAX_PTIME_MASK \ + 0x000000FF /* PRI0_MAX_PTIME[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_PRI_DLY_INT_CFG0_PRI0_MAX_PTIME_SHFT 0 + +/* +* ---WPDMA_TX_RING0_CTRL0 (0x18025000 + 0x300)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring0 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING0_CTRL1 (0x18025000 + 0x304)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_Ring0. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring0 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING0_CTRL2 (0x18025000 + 0x308)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING0_CTRL3 (0x18025000 + 0x30c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING1_CTRL0 (0x18025000 + 0x310)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring1 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING1_CTRL1 (0x18025000 + 0x314)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_Ring1. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring1 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING1_CTRL2 (0x18025000 + 0x318)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING1_CTRL3 (0x18025000 + 0x31c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING2_CTRL0 (0x18025000 + 0x320)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring2 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING2_CTRL1 (0x18025000 + 0x324)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_Ring2. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring2 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING2_CTRL2 (0x18025000 + 0x328)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING2_CTRL3 (0x18025000 + 0x32c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING3_CTRL0 (0x18025000 + 0x330)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring3 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING3_CTRL1 (0x18025000 + 0x334)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_Ring3. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring3 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING3_CTRL2 (0x18025000 + 0x338)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING3_CTRL3 (0x18025000 + 0x33c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING4_CTRL0 (0x18025000 + 0x340)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring4 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING4_CTRL1 (0x18025000 + 0x344)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_Ring4. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring4 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING4_CTRL2 (0x18025000 + 0x348)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING4_CTRL3 (0x18025000 + 0x34c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING5_CTRL0 (0x18025000 + 0x350)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring5 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING5_CTRL1 (0x18025000 + 0x354)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_Ring5. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring5 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING5_CTRL2 (0x18025000 + 0x358)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING5_CTRL3 (0x18025000 + 0x35c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING6_CTRL0 (0x18025000 + 0x360)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring6 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING6_CTRL1 (0x18025000 + 0x364)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_Ring6. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring6 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING6_CTRL2 (0x18025000 + 0x368)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING6_CTRL3 (0x18025000 + 0x36c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING7_CTRL0 (0x18025000 + 0x370)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring7 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING7_CTRL1 (0x18025000 + 0x374)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_Ring7. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring7 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING7_CTRL2 (0x18025000 + 0x378)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING7_CTRL3 (0x18025000 + 0x37c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING8_CTRL0 (0x18025000 + 0x380)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring0 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING8_CTRL1 (0x18025000 + 0x384)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_Ring0. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring0 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING8_CTRL2 (0x18025000 + 0x388)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING8_CTRL3 (0x18025000 + 0x38c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING9_CTRL0 (0x18025000 + 0x390)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring1 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING9_CTRL1 (0x18025000 + 0x394)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_Ring1. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring1 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING9_CTRL2 (0x18025000 + 0x398)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING9_CTRL3 (0x18025000 + 0x39c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING10_CTRL0 (0x18025000 + 0x3a0)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring2 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING10_CTRL1 (0x18025000 + 0x3a4)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_Ring2. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring2 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING10_CTRL2 (0x18025000 + 0x3a8)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING10_CTRL3 (0x18025000 + 0x3ac)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING11_CTRL0 (0x18025000 + 0x3b0)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring3 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING11_CTRL1 (0x18025000 + 0x3b4)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_Ring3. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring3 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING11_CTRL2 (0x18025000 + 0x3b8)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING11_CTRL3 (0x18025000 + 0x3bc)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING12_CTRL0 (0x18025000 + 0x3c0)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring4 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING12_CTRL1 (0x18025000 + 0x3c4)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_Ring4. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring4 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING12_CTRL2 (0x18025000 + 0x3c8)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING12_CTRL3 (0x18025000 + 0x3cc)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING13_CTRL0 (0x18025000 + 0x3d0)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring5 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING13_CTRL1 (0x18025000 + 0x3d4)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_Ring5. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring5 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING13_CTRL2 (0x18025000 + 0x3d8)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING13_CTRL3 (0x18025000 + 0x3dc)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING14_CTRL0 (0x18025000 + 0x3e0)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring6 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING14_CTRL1 (0x18025000 + 0x3e4)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_Ring6. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring6 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING14_CTRL2 (0x18025000 + 0x3e8)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING14_CTRL3 (0x18025000 + 0x3ec)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING15_CTRL0 (0x18025000 + 0x3f0)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring7 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING15_CTRL1 (0x18025000 + 0x3f4)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_Ring7. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring7 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING15_CTRL2 (0x18025000 + 0x3f8)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING15_CTRL3 (0x18025000 + 0x3fc)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING16_CTRL0 (0x18025000 + 0x400)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_RING16 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING16_CTRL1 (0x18025000 + 0x404)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_RING16. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring16 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING16_CTRL2 (0x18025000 + 0x408)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING16_CTRL3 (0x18025000 + 0x40c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING17_CTRL0 (0x18025000 + 0x410)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring17 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING17_CTRL1 (0x18025000 + 0x414)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_Ring17. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring17 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING17_CTRL2 (0x18025000 + 0x418)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING17_CTRL3 (0x18025000 + 0x41c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING18_CTRL0 (0x18025000 + 0x420)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring18 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING18_CTRL1 (0x18025000 + 0x424)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_Ring18. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring18 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING18_CTRL2 (0x18025000 + 0x428)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING18_CTRL3 (0x18025000 + 0x42c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING19_CTRL0 (0x18025000 + 0x430)--- +* BASE_PTR[31..0] - (RW) Point to the base address of TX_Ring19 +* (8-DWORD aligned address) +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_TX_RING19_CTRL1 (0x18025000 + 0x434)--- +* MAX_CNT[11..0] - (RW) The maximum number of TXD count in +TXD_Ring19. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* TX_Ring19 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING19_CTRL2 (0x18025000 + 0x438)--- +* CPU_IDX[11..0] - (RW) Point to the next TXD CPU wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING19_CTRL3 (0x18025000 + 0x43c)--- +* DMA_IDX[11..0] - (RO) Point to the next TXD DMA wants to use +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING0_CTRL0 (0x18025000 + 0x500)--- +* BASE_PTR[31..0] - (RW) Point to the base address of RXD Ring #0 +* (GE ports). It should be a 8-DWORD aligned address +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_RX_RING0_CTRL1 (0x18025000 + 0x504)--- +* MAX_CNT[11..0] - (RW) The maximum number of RXD count in RXD +* Ring #0. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* RX_Ring0 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING0_CTRL2 (0x18025000 + 0x508)--- +* CPU_IDX[11..0] - (RW) Point to the next RXD CPU wants to +* allocate to RXD Ring #0. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING0_CTRL3 (0x18025000 + 0x50c)--- +* DMA_IDX[11..0] - (RW) In normal operation, user dma_index +* would udated by hardware when moving rx packet done. User should not write +dma_index. +* Point to the next RXD DMA wants to use in +* FDS Ring#0. It should be a 8-DWORD aligned address. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING1_CTRL0 (0x18025000 + 0x510)--- +* BASE_PTR[31..0] - (RW) Point to the base address of RXD Ring #1 +* (GE ports). It should be a 8-DWORD aligned address +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_RX_RING1_CTRL1 (0x18025000 + 0x514)--- +* MAX_CNT[11..0] - (RW) The maximum number of RXD count in RXD +* Ring #1. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* RX_Ring1 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING1_CTRL2 (0x18025000 + 0x518)--- +* CPU_IDX[11..0] - (RW) Point to the next RXD CPU wants to +* allocate to RXD Ring #1. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING1_CTRL3 (0x18025000 + 0x51c)--- +* DMA_IDX[11..0] - (RW) In normal operation, user dma_index +* would udated by hardware when moving rx packet done. User should not write +dma_index. +* Point to the next RXD DMA wants to use in +* FDS Ring#1. It should be a 8-DWORD aligned address. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING2_CTRL0 (0x18025000 + 0x520)--- +* BASE_PTR[31..0] - (RW) Point to the base address of RXD Ring #2 +* (GE ports). It should be a 8-DWORD aligned address +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_RX_RING2_CTRL1 (0x18025000 + 0x524)--- +* MAX_CNT[11..0] - (RW) The maximum number of RXD count in RXD +* Ring #2. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* RX_Ring2 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING2_CTRL2 (0x18025000 + 0x528)--- +* CPU_IDX[11..0] - (RW) Point to the next RXD CPU wants to +* allocate to RXD Ring #2. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING2_CTRL3 (0x18025000 + 0x52C)--- +* DMA_IDX[11..0] - (RW) In normal operation, user dma_index +* would udated by hardware when moving rx packet done. User should not write +dma_index. +* Point to the next RXD DMA wants to use in +* FDS Ring#2. It should be a 8-DWORD aligned address. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING3_CTRL0 (0x18025000 + 0x530)--- +* BASE_PTR[31..0] - (RW) Point to the base address of RXD Ring #3 +* (GE ports). It should be a 8-DWORD aligned address +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL0_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL0_BASE_PTR_MASK \ + 0xFFFFFFFF /* BASE_PTR[31..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL0_BASE_PTR_SHFT 0 + +/* +* ---WPDMA_RX_RING3_CTRL1 (0x18025000 + 0x534)--- +* MAX_CNT[11..0] - (RW) The maximum number of RXD count in RXD +* Ring #3. +* RESERVED12[15..12] - (RO) Reserved bits +* BASE_PTR_EXT[19..16] - (RW) Point to the base address[35:32] of +* RX_Ring3 (8-DWORD aligned address) +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL1_BASE_PTR_EXT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL1_BASE_PTR_EXT_MASK \ + 0x000F0000 /* BASE_PTR_EXT[19..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL1_BASE_PTR_EXT_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL1_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL1_MAX_CNT_MASK \ + 0x00000FFF /* MAX_CNT[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL1_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING3_CTRL2 (0x18025000 + 0x538)--- +* CPU_IDX[11..0] - (RW) Point to the next RXD CPU wants to +* allocate to RXD Ring #3. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL2_CPU_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL2_CPU_IDX_MASK \ + 0x00000FFF /* CPU_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL2_CPU_IDX_SHFT 0 + +/* +* ---WPDMA_RX_RING3_CTRL3 (0x18025000 + 0x53C)--- +* DMA_IDX[11..0] - (RW) In normal operation, user dma_index +* would udated by hardware when moving rx packet done. User should not write +dma_index. +* Point to the next RXD DMA wants to use in +* FDS Ring#3. It should be a 8-DWORD aligned address. +* RESERVED12[31..12] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL3_DMA_IDX_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL3_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL3_DMA_IDX_MASK \ + 0x00000FFF /* DMA_IDX[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_CTRL3_DMA_IDX_SHFT 0 + +/* +* ---WPDMA_TX_RING0_EXT_CTRL (0x18025000 + 0x600)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #0 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING1_EXT_CTRL (0x18025000 + 0x604)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #1 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING2_EXT_CTRL (0x18025000 + 0x608)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #2 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING3_EXT_CTRL (0x18025000 + 0x60C)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #3 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING4_EXT_CTRL (0x18025000 + 0x610)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #4 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING5_EXT_CTRL (0x18025000 + 0x614)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #5 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING6_EXT_CTRL (0x18025000 + 0x618)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #6 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING7_EXT_CTRL (0x18025000 + 0x61C)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #7 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING8_EXT_CTRL (0x18025000 + 0x620)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #0 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING9_EXT_CTRL (0x18025000 + 0x624)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #1 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING10_EXT_CTRL (0x18025000 + 0x628)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #2 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING11_EXT_CTRL (0x18025000 + 0x62C)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #3 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING12_EXT_CTRL (0x18025000 + 0x630)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #4 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING13_EXT_CTRL (0x18025000 + 0x634)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #5 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING14_EXT_CTRL (0x18025000 + 0x638)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #6 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING15_EXT_CTRL (0x18025000 + 0x63C)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #7 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING16_EXT_CTRL (0x18025000 + 0x640)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #16 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING17_EXT_CTRL (0x18025000 + 0x644)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #17 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING18_EXT_CTRL (0x18025000 + 0x648)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #18 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING19_EXT_CTRL (0x18025000 + 0x64C)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) TXD Ring #19 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING0_EXT_CTRL (0x18025000 + 0x680)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) RXD Ring #0 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING1_EXT_CTRL (0x18025000 + 0x684)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) RXD Ring #1 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING2_EXT_CTRL (0x18025000 + 0x688)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) RXD Ring #2 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_RX_RING3_EXT_CTRL (0x18025000 + 0x68C)--- +* DISP_MAX_CNT[7..0] - (RW) xxx +* RESERVED8[15..8] - (RO) Reserved bits +* DISP_BASE_PTR[31..16] - (RW) RXD Ring #3 Extension, to configure +* prefetch settings, like base_ptr means each prefetch ring's base address in +* internal prefetch sram, disp_max_cnt means each prefetch ring's depth +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_EXT_CTRL_DISP_BASE_PTR_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_EXT_CTRL_DISP_BASE_PTR_MASK \ + 0xFFFF0000 /* DISP_BASE_PTR[31..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_EXT_CTRL_DISP_BASE_PTR_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_EXT_CTRL_DISP_MAX_CNT_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_EXT_CTRL_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_EXT_CTRL_DISP_MAX_CNT_MASK \ + 0x000000FF /* DISP_MAX_CNT[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_EXT_CTRL_DISP_MAX_CNT_SHFT 0 + +/* +* ---WPDMA_TX_RING0_BKRS_CTRL0 (0x18025000 + 0xA00)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING0_BKRS_CTRL1 (0x18025000 + 0xA04)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING0_BKRS_CTRL2 (0x18025000 + 0xA08)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING0_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING1_BKRS_CTRL0 (0x18025000 + 0xA10)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING1_BKRS_CTRL1 (0x18025000 + 0xA14)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING1_BKRS_CTRL2 (0x18025000 + 0xA18)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING1_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING2_BKRS_CTRL0 (0x18025000 + 0xA20)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING2_BKRS_CTRL1 (0x18025000 + 0xA24)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING2_BKRS_CTRL2 (0x18025000 + 0xA28)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING2_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING3_BKRS_CTRL0 (0x18025000 + 0xA30)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING3_BKRS_CTRL1 (0x18025000 + 0xA34)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING3_BKRS_CTRL2 (0x18025000 + 0xA38)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING3_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING4_BKRS_CTRL0 (0x18025000 + 0xA40)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING4_BKRS_CTRL1 (0x18025000 + 0xA44)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING4_BKRS_CTRL2 (0x18025000 + 0xA48)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING4_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING5_BKRS_CTRL0 (0x18025000 + 0xA50)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING5_BKRS_CTRL1 (0x18025000 + 0xA54)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING5_BKRS_CTRL2 (0x18025000 + 0xA58)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING5_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING6_BKRS_CTRL0 (0x18025000 + 0xA60)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING6_BKRS_CTRL1 (0x18025000 + 0xA64)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING6_BKRS_CTRL2 (0x18025000 + 0xA68)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING6_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING7_BKRS_CTRL0 (0x18025000 + 0xA70)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING7_BKRS_CTRL1 (0x18025000 + 0xA74)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING7_BKRS_CTRL2 (0x18025000 + 0xA78)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING7_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING8_BKRS_CTRL0 (0x18025000 + 0xA80)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING8_BKRS_CTRL1 (0x18025000 + 0xA84)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING8_BKRS_CTRL2 (0x18025000 + 0xA88)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING8_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING9_BKRS_CTRL0 (0x18025000 + 0xA90)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING9_BKRS_CTRL1 (0x18025000 + 0xA94)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING9_BKRS_CTRL2 (0x18025000 + 0xA98)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING9_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING10_BKRS_CTRL0 (0x18025000 + 0xAA0)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING10_BKRS_CTRL1 (0x18025000 + 0xAA4)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING10_BKRS_CTRL2 (0x18025000 + 0xAA8)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING10_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING11_BKRS_CTRL0 (0x18025000 + 0xAB0)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING11_BKRS_CTRL1 (0x18025000 + 0xAB4)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING11_BKRS_CTRL2 (0x18025000 + 0xAB8)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING11_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING12_BKRS_CTRL0 (0x18025000 + 0xAC0)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING12_BKRS_CTRL1 (0x18025000 + 0xAC4)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING12_BKRS_CTRL2 (0x18025000 + 0xAC8)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING12_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING13_BKRS_CTRL0 (0x18025000 + 0xAD0)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING13_BKRS_CTRL1 (0x18025000 + 0xAD4)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING13_BKRS_CTRL2 (0x18025000 + 0xAD8)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING13_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING14_BKRS_CTRL0 (0x18025000 + 0xAE0)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING14_BKRS_CTRL1 (0x18025000 + 0xAE4)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING14_BKRS_CTRL2 (0x18025000 + 0xAE8)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING14_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING15_BKRS_CTRL0 (0x18025000 + 0xAF0)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING15_BKRS_CTRL1 (0x18025000 + 0xAF4)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING15_BKRS_CTRL2 (0x18025000 + 0xAF8)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING15_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING16_BKRS_CTRL0 (0x18025000 + 0xB00)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING16_BKRS_CTRL1 (0x18025000 + 0xB04)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING16_BKRS_CTRL2 (0x18025000 + 0xB08)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING16_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING17_BKRS_CTRL0 (0x18025000 + 0xB10)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING17_BKRS_CTRL1 (0x18025000 + 0xB14)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING17_BKRS_CTRL2 (0x18025000 + 0xB18)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING17_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING18_BKRS_CTRL0 (0x18025000 + 0xB20)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING18_BKRS_CTRL1 (0x18025000 + 0xB24)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING18_BKRS_CTRL2 (0x18025000 + 0xB28)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING18_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING19_BKRS_CTRL0 (0x18025000 + 0xB30)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING19_BKRS_CTRL1 (0x18025000 + 0xB34)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_TX_RING19_BKRS_CTRL2 (0x18025000 + 0xB38)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_TX_RING19_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING0_BKRS_CTRL0 (0x18025000 + 0xC00)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING0_BKRS_CTRL1 (0x18025000 + 0xC04)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING0_BKRS_CTRL2 (0x18025000 + 0xC08)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING0_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING1_BKRS_CTRL0 (0x18025000 + 0xC10)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING1_BKRS_CTRL1 (0x18025000 + 0xC14)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING1_BKRS_CTRL2 (0x18025000 + 0xC18)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING1_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING2_BKRS_CTRL0 (0x18025000 + 0xC20)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING2_BKRS_CTRL1 (0x18025000 + 0xC24)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING2_BKRS_CTRL2 (0x18025000 + 0xC28)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING2_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING3_BKRS_CTRL0 (0x18025000 + 0xC30)--- +* pld_didx_idx[11..0] - (RO) pld_didx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pf_didx_idx[27..16] - (RO) pf_didx_idx +* RESERVED28[31..28] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL0_pf_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL0_pf_didx_idx_MASK \ + 0x0FFF0000 /* pf_didx_idx[27..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL0_pf_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL0_pld_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL0_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL0_pld_didx_idx_MASK \ + 0x00000FFF /* pld_didx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL0_pld_didx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING3_BKRS_CTRL1 (0x18025000 + 0xC34)--- +* disp_cidx_idx[7..0] - (RO) disp_cidx_idx +* RESERVED8[15..8] - (RO) Reserved bits +* disp_didx_idx[23..16] - (RO) disp_didx_idx +* RESERVED24[31..24] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL1_disp_didx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL1_disp_didx_idx_MASK \ + 0x00FF0000 /* disp_didx_idx[23..16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL1_disp_didx_idx_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL1_disp_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL1_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL1_disp_cidx_idx_MASK \ + 0x000000FF /* disp_cidx_idx[7..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL1_disp_cidx_idx_SHFT 0 + +/* +* ---WPDMA_RX_RING3_BKRS_CTRL2 (0x18025000 + 0xC38)--- +* pld_cidx_idx[11..0] - (RO) pld_cidx_idx +* RESERVED12[15..12] - (RO) Reserved bits +* pld_ring_empty[16] - (RO) pld_ring_empty +* pf_ring_empty[17] - (RO) pf_ring_empty +* pf_dq_ring_empty[18] - (RO) pf_dq_ring_empty +* disp_ring_vld[19] - (RO) disp_ring_vld +* RESERVED20[31..20] - (RO) Reserved bits +*/ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL2_disp_ring_vld_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL2_disp_ring_vld_MASK \ + 0x00080000 /* disp_ring_vld[19] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL2_disp_ring_vld_SHFT 19 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL2_pf_dq_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL2_pf_dq_ring_empty_MASK \ + 0x00040000 /* pf_dq_ring_empty[18] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL2_pf_dq_ring_empty_SHFT 18 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL2_pf_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL2_pf_ring_empty_MASK \ + 0x00020000 /* pf_ring_empty[17] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL2_pf_ring_empty_SHFT 17 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL2_pld_ring_empty_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL2_pld_ring_empty_MASK \ + 0x00010000 /* pld_ring_empty[16] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL2_pld_ring_empty_SHFT 16 +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL2_pld_cidx_idx_ADDR \ + WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL2_ADDR +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL2_pld_cidx_idx_MASK \ + 0x00000FFF /* pld_cidx_idx[11..0] */ +#define WF_WFDMA_HOST_DMA1_WPDMA_RX_RING3_BKRS_CTRL2_pld_cidx_idx_SHFT 0 + +#ifdef __cplusplus +} +#endif + +#endif /* __WF_WFDMA_HOST_DMA1_REGS_H__ */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/connac.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/connac.h new file mode 100644 index 0000000000000000000000000000000000000000..dbbf357f49163bb84047a7df1fb71320eab36b62 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/connac.h @@ -0,0 +1,133 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/ + * MT6620_WIFI_DRIVER_V2_3/include/chips/connac.h#1 + */ + +/*! \file connac.h + * \brief This file contains the info of CONNAC + */ + +#ifdef CONNAC + +#ifndef _CONNAC_H +#define _CONNAC_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "gl_os.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#define CONNAC_CHIP_ID (0x0001) +#define CONNAC_CHIP_ADIE_INFO (0x6631) +#define CONNAC_SW_SYNC0 CONN_CFG_ON_CONN_ON_MISC_ADDR +#define CONNAC_SW_SYNC0_RDY_OFFSET \ + CONN_CFG_ON_CONN_ON_MISC_DRV_FM_STAT_SYNC_SHFT +#define CONNAC_PATCH_START_ADDR (0x0001C000) +#define CONNAC_TOP_CFG_BASE CONN_CFG_BASE +#define CONNAC_TX_DESC_APPEND_LENGTH 32 +#if (CFG_WIFI_IP_SET == 1) +#define CONNAC_RX_DESC_LENGTH 16 +#else +#define CONNAC_RX_DESC_LENGTH 20 +#endif +#define CONNAC_INIT_EVT_RX_DESC_LENGTH 16 +#define CONNAC_RX_INIT_EVENT_LENGTH 8 +#define CONNAC_RX_EVENT_HDR_LENGTH 12 +#define MTK_CUSTOM_OID_INTERFACE_VERSION 0x00006620 /* for WPDWifi DLL */ +#define MTK_EM_INTERFACE_VERSION 0x0000 + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#endif /* _CONNAC_H */ + +#endif /* CONNAC */ + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/connac2x2.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/connac2x2.h new file mode 100644 index 0000000000000000000000000000000000000000..031c5d398b8d9be0371124ce9dd1fbde8f7f1d2a --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/connac2x2.h @@ -0,0 +1,128 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/ + * MT6620_WIFI_DRIVER_V2_3/include/chips/connac.h#1 + */ + +/*! \file connac.h + * \brief This file contains the info of CONNAC + */ + +#ifdef CONNAC2X2 + +#ifndef _CONNAC2X2_H +#define _CONNAC2X2_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "gl_os.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#define CONNAC2X2_CHIP_ID (0x0001) +#define CONNAC_CHIP_ADIE_INFO (0x6635) +#define CONNAC2X2_SW_SYNC0 CONN_CFG_ON_CONN_ON_MISC_ADDR +#define CONNAC2X2_SW_SYNC0_RDY_OFFSET \ + CONN_CFG_ON_CONN_ON_MISC_DRV_FM_STAT_SYNC_SHFT +#define CONNAC2X2_PATCH_START_ADDR (0x0001C000) +#define CONNAC2X2_TOP_CFG_BASE CONN_CFG_BASE +#define CONNAC2X2_TX_DESC_APPEND_LENGTH 32 +#define CONNAC2X2_RX_DESC_LENGTH 20 +#define CONNAC2X2_RX_INIT_EVENT_LENGTH 8 +#define CONNAC2X2_RX_EVENT_HDR_LENGTH 12 +#define MTK_CUSTOM_OID_INTERFACE_VERSION 0x00000200 /* for WPDWifi DLL */ +#define MTK_EM_INTERFACE_VERSION 0x0001 + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#endif /* _CONNAC2X2_H */ + +#endif /* CONNAC2X2 */ + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/dma_sch.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/dma_sch.h new file mode 100644 index 0000000000000000000000000000000000000000..857ffbe9b2376d3c82b2807c3afa0ad4a804d35a --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/dma_sch.h @@ -0,0 +1,199 @@ +/* + *************************************************************************** + * Ralink Tech Inc. + * 4F, No. 2 Technology 5th Rd. + * Science-based Industrial Park + * Hsin-chu, Taiwan, R.O.C. + * + * (c) Copyright 2002-2004, Ralink Technology, Inc. + * + * All rights reserved. Ralink's source code is an unpublished work and the + * use of a copyright notice does not imply otherwise. This source code + * contains confidential trade secret material of Ralink Tech. Any attemp + * or participation in deciphering, decoding, reverse engineering or in any + * way altering the source code is stricitly prohibited, unless the prior + * written consent of Ralink Technology, Inc. is obtained. + *************************************************************************** + + Module Name: + dma_sch.h + + Abstract: + Ralink Wireless Chip MAC related definition & structures + + Revision History: + Who When What + -------- ---------- ------------------------------------- +*/ + + +#ifndef __DMA_SCH_H__ +#define __DMA_SCH_H__ + +#define DMASHDL_BASE 0x5000a000 + +#define MT_HIF_DMASHDL_PKT_MAX_SIZE (DMASHDL_BASE + 0x1c) + +#define PLE_PKT_MAX_SIZE_MASK (0xfff << 0) +#define PLE_PKT_MAX_SIZE_NUM(p) (((p) & 0xfff) << 0) +#define GET_PLE_PKT_MAX_SIZE_NUM(p) (((p) & PLE_PKT_MAX_SIZE_MASK) >> 0) + +#define PSE_PKT_MAX_SIZE_MASK (0xfff << 16) +#define PSE_PKT_MAX_SIZE_NUM(p) (((p) & 0xfff) << 16) +#define GET_PSE_PKT_MAX_SIZE_NUM(p) (((p) & PSE_PKT_MAX_SIZE_MASK) >> 16) +#define MT_HIF_DMASHDL_OPTION_CTRL (DMASHDL_BASE + 0x08) +#define MT_HIF_DMASHDL_REFILL_CTRL (DMASHDL_BASE + 0x10) +#define MT_HIF_DMASHDL_GROUP0_CTRL (DMASHDL_BASE + 0x20) +#define MT_HIF_DMASHDL_GROUP1_CTRL (DMASHDL_BASE + 0x24) +#define MT_HIF_DMASHDL_GROUP2_CTRL (DMASHDL_BASE + 0x28) +#define MT_HIF_DMASHDL_GROUP3_CTRL (DMASHDL_BASE + 0x2c) +#define MT_HIF_DMASHDL_GROUP4_CTRL (DMASHDL_BASE + 0x30) +#define MT_HIF_DMASHDL_GROUP5_CTRL (DMASHDL_BASE + 0x34) +#define MT_HIF_DMASHDL_GROUP6_CTRL (DMASHDL_BASE + 0x38) +#define MT_HIF_DMASHDL_GROUP7_CTRL (DMASHDL_BASE + 0x3c) +#define MT_HIF_DMASHDL_GROUP8_CTRL (DMASHDL_BASE + 0x40) +#define MT_HIF_DMASHDL_GROUP9_CTRL (DMASHDL_BASE + 0x44) +#define MT_HIF_DMASHDL_GROUP10_CTRL (DMASHDL_BASE + 0x48) +#define MT_HIF_DMASHDL_GROUP11_CTRL (DMASHDL_BASE + 0x4c) +#define MT_HIF_DMASHDL_GROUP12_CTRL (DMASHDL_BASE + 0x50) +#define MT_HIF_DMASHDL_GROUP13_CTRL (DMASHDL_BASE + 0x54) +#define MT_HIF_DMASHDL_GROUP14_CTRL (DMASHDL_BASE + 0x58) +#define MT_HIF_DMASHDL_GROUP15_CTRL (DMASHDL_BASE + 0x5c) + +#define MT_HIF_DMASHDL_SHDL_SET0 (DMASHDL_BASE + 0xb0) +#define MT_HIF_DMASHDL_SHDL_SET1 (DMASHDL_BASE + 0xb4) + + +#define MT_HIF_DMASHDL_SLOT_SET0 (DMASHDL_BASE + 0xc4) +#define MT_HIF_DMASHDL_SLOT_SET1 (DMASHDL_BASE + 0xc8) + + +#define MT_HIF_DMASHDL_Q_MAP0 (DMASHDL_BASE + 0xd0) +#define MT_HIF_DMASHDL_Q_MAP1 (DMASHDL_BASE + 0xd4) +#define MT_HIF_DMASHDL_Q_MAP2 (DMASHDL_BASE + 0xd8) +#define MT_HIF_DMASHDL_Q_MAP3 (DMASHDL_BASE + 0xdc) + +#define MT_HIF_DMASHDL_PAGE_SET (DMASHDL_BASE + 0x0c) + +/* User program group sequence type control */ +/* 0: user program group sequence order type, + * 1: pre define each slot group strict order + */ +#define DMASHDL_GROUP_SEQ_ORDER_TYPE BIT(16) + + +#define MT_HIF_DMASHDL_CTRL_SIGNAL (DMASHDL_BASE + 0x18) +/* enable to clear the flag of PLE TXD size greater than ple max. size */ +#define DMASHDL_PLE_TXD_GT_MAX_SIZE_FLAG_CLR BIT(0) +/* enable packet in substration action from HIF ask period */ +#define DMASHDL_HIF_ASK_SUB_ENA BIT(16) +/* enable packet in substration action from PLE */ +#define DMASHDL_PLE_SUB_ENA BIT(17) +/* enable terminate refill period when PLE release packet to do addition */ +#define DMASHDL_PLE_ADD_INT_REFILL_ENA BIT(29) +/* enable terminate refill period when packet in to do addition */ +#define DMASHDL_PDMA_ADD_INT_REFILL_ENA BIT(30) +/* enable terminate refill period when packet in to do substration */ +#define DMASHDL_PKTIN_INT_REFILL_ENA BIT(31) + +#define MT_HIF_DMASHDL_ERROR_FLAG_CTRL (DMASHDL_BASE + 0x9c) + +#define MT_HIF_DMASHDL_STATUS_RD (DMASHDL_BASE + 0x100) +#define MT_HIF_DMASHDL_STATUS_RD_GP0 (DMASHDL_BASE + 0x140) +#define MT_HIF_DMASHDL_STATUS_RD_GP1 (DMASHDL_BASE + 0x144) +#define MT_HIF_DMASHDL_STATUS_RD_GP2 (DMASHDL_BASE + 0x148) +#define MT_HIF_DMASHDL_STATUS_RD_GP3 (DMASHDL_BASE + 0x14c) +#define MT_HIF_DMASHDL_STATUS_RD_GP4 (DMASHDL_BASE + 0x150) +#define MT_HIF_DMASHDL_STATUS_RD_GP5 (DMASHDL_BASE + 0x154) +#define MT_HIF_DMASHDL_STATUS_RD_GP6 (DMASHDL_BASE + 0x158) +#define MT_HIF_DMASHDL_STATUS_RD_GP7 (DMASHDL_BASE + 0x15c) +#define MT_HIF_DMASHDL_STATUS_RD_GP8 (DMASHDL_BASE + 0x160) +#define MT_HIF_DMASHDL_STATUS_RD_GP9 (DMASHDL_BASE + 0x164) +#define MT_HIF_DMASHDL_STATUS_RD_GP10 (DMASHDL_BASE + 0x168) +#define MT_HIF_DMASHDL_STATUS_RD_GP11 (DMASHDL_BASE + 0x16c) +#define MT_HIF_DMASHDL_STATUS_RD_GP12 (DMASHDL_BASE + 0x170) +#define MT_HIF_DMASHDL_STATUS_RD_GP13 (DMASHDL_BASE + 0x174) +#define MT_HIF_DMASHDL_STATUS_RD_GP14 (DMASHDL_BASE + 0x178) +#define MT_HIF_DMASHDL_STATUS_RD_GP15 (DMASHDL_BASE + 0x17c) +#define MT_HIF_DMASHDLRD_GP_PKT_CNT_0 (DMASHDL_BASE + 0x180) +#define MT_HIF_DMASHDLRD_GP_PKT_CNT_1 (DMASHDL_BASE + 0x184) +#define MT_HIF_DMASHDLRD_GP_PKT_CNT_2 (DMASHDL_BASE + 0x188) +#define MT_HIF_DMASHDLRD_GP_PKT_CNT_3 (DMASHDL_BASE + 0x18c) +#define MT_HIF_DMASHDLRD_GP_PKT_CNT_4 (DMASHDL_BASE + 0x190) +#define MT_HIF_DMASHDLRD_GP_PKT_CNT_5 (DMASHDL_BASE + 0x194) +#define MT_HIF_DMASHDLRD_GP_PKT_CNT_6 (DMASHDL_BASE + 0x198) +#define MT_HIF_DMASHDLRD_GP_PKT_CNT_7 (DMASHDL_BASE + 0x19c) + +#define DMASHDL_RSV_CNT_MASK (0xfff << 16) +#define DMASHDL_SRC_CNT_MASK (0xfff << 0) +#define DMASHDL_RSV_CNT_OFFSET 16 +#define DMASHDL_SRC_CNT_OFFSET 0 +#define DMASHDL_FREE_PG_CNT_MASK (0xfff << 16) +#define DMASHDL_FFA_CNT_MASK (0xfff << 0) +#define DMASHDL_FREE_PG_CNT_OFFSET 16 +#define DMASHDL_FFA_CNT_OFFSET 0 +#define DMASHDL_MAX_QUOTA_MASK (0xfff << 16) +#define DMASHDL_MIN_QUOTA_MASK (0xfff << 0) +#define DMASHDL_MAX_QUOTA_OFFSET 16 +#define DMASHDL_MIN_QUOTA_OFFSET 0 + +#define DMASHDL_MIN_QUOTA_NUM(p) (((p) & 0xfff) << DMASHDL_MIN_QUOTA_OFFSET) +#define GET_DMASHDL_MIN_QUOTA_NUM(p)\ + (((p) & DMASHDL_MIN_QUOTA_MASK) >> DMASHDL_MIN_QUOTA_OFFSET) + +#define DMASHDL_MAX_QUOTA_NUM(p) (((p) & 0xfff) << DMASHDL_MAX_QUOTA_OFFSET) +#define GET_DMASHDL_MAX_QUOTA_NUM(p)\ + (((p) & DMASHDL_MAX_QUOTA_MASK) >> DMASHDL_MAX_QUOTA_OFFSET) + + +#define ODD_GROUP_ASK_CN_MASK (0xff << 16) +#define ODD_GROUP_ASK_CN_OFFSET 16 +#define GET_ODD_GROUP_ASK_CNT(p)\ + (((p) & ODD_GROUP_ASK_CN_MASK) >> ODD_GROUP_ASK_CN_OFFSET) +#define ODD_GROUP_PKT_IN_CN_MASK (0xff << 24) +#define ODD_GROUP_PKT_IN_CN_OFFSET 24 +#define GET_ODD_GROUP_PKT_IN_CNT(p)\ + (((p) & ODD_GROUP_PKT_IN_CN_MASK) >> ODD_GROUP_PKT_IN_CN_OFFSET) +#define EVEN_GROUP_ASK_CN_MASK (0xff << 0) +#define EVEN_GROUP_ASK_CN_OFFSET 0 +#define GET_EVEN_GROUP_ASK_CNT(p)\ + (((p) & EVEN_GROUP_ASK_CN_MASK) >> EVEN_GROUP_ASK_CN_OFFSET) +#define EVEN_GROUP_PKT_IN_CN_MASK (0xff << 8) +#define EVEN_GROUP_PKT_IN_CN_OFFSET 8 +#define GET_EVEN_GROUP_PKT_IN_CNT(p)\ + (((p) & EVEN_GROUP_PKT_IN_CN_MASK) >> EVEN_GROUP_PKT_IN_CN_OFFSET) +#if defined(P18) || defined(MT7663) || defined(AXE) +#define HIF_DMASHDL_IO_READ32(_A, _R, _pV)\ + HW_IO_READ32(_A->hdev_ctrl, (0x6000+((uint32_t)_R&0xfff)), _pV) +#define HIF_DMASHDL_IO_WRITE32(_A, _R, _pV)\ + HW_IO_WRITE32(_A->hdev_ctrl, (0x6000+((uint32_t)_R&0xfff)), _pV) +#else +#define HIF_DMASHDL_IO_READ32(_A, _R, _pV)\ + do {\ + uint32_t restore_remap_addr;\ + HW_IO_READ32(_A->hdev_ctrl, 0x2504, &restore_remap_addr);\ + \ + HW_IO_WRITE32(_A->hdev_ctrl, 0x2504, DMASHDL_BASE);\ + HW_IO_READ32(_A->hdev_ctrl,\ + (0x80000+((uint32_t)_R&0xffff)), _pV);\ + \ + HW_IO_WRITE32(_A->hdev_ctrl, 0x2504, restore_remap_addr);\ + } while (0) + +#define HIF_DMASHDL_IO_WRITE32(_A, _R, _pV) \ + do {\ + uint32_t restore_remap_addr;\ + \ + HW_IO_READ32(_A->hdev_ctrl, 0x2504, &restore_remap_addr);\ + \ + HW_IO_WRITE32(_A->hdev_ctrl, 0x2504, DMASHDL_BASE);\ + HW_IO_WRITE32(_A->hdev_ctrl,\ + (0x80000+((uint32_t)_R&0xffff)), _pV);\ + \ + HW_IO_WRITE32(_A->hdev_ctrl, 0x2504, restore_remap_addr);\ + } while (0) +#endif + + +#endif /* __DMA_SCH_H__ */ + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/fw_dl.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/fw_dl.h new file mode 100644 index 0000000000000000000000000000000000000000..a08b82f922065be9c947cbdc73d6acc7ce1affe1 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/fw_dl.h @@ -0,0 +1,417 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/*! \file fw_dl.h + */ + +#ifndef _FW_DL_H +#define _FW_DL_H + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/* PDA - Patch Decryption Accelerator */ +#define PDA_N9 0 +#define PDA_CR4 1 + +#define MAX_FWDL_SECTION_NUM 10 +#define N9_FWDL_SECTION_NUM 2 +#define CR4_FWDL_SECTION_NUM HIF_CR4_FWDL_SECTION_NUM +#define IMG_DL_STATUS_PORT_IDX HIF_IMG_DL_STATUS_PORT_IDX + +#define DOWNLOAD_CONFIG_ENCRYPTION_MODE BIT(0) +#define DOWNLOAD_CONFIG_KEY_INDEX_MASK BITS(1, 2) +#define DOWNLOAD_CONFIG_RESET_OPTION BIT(3) +#define DOWNLOAD_CONFIG_WORKING_PDA_OPTION BIT(4) +#define DOWNLOAD_CONFIG_VALID_RAM_ENTRY BIT(5) +#define DOWNLOAD_CONFIG_ENCRY_MODE_SEL BIT(6) /* 0 - AES, 1 - SCRAMBLE */ +#define DOWNLOAD_CONFIG_EMI BIT(7) +#define DOWNLOAD_CONFIG_ACK_OPTION BIT(31) + +/* + * FW feature set + * bit(0) : encrypt or not. + * bit(1,2): encrypt key index. + * bit(3) : compressed image or not. (added in CONNAC) + * bit(4) : encrypt mode, 1 for scramble, 0 for AES. + * bit(5) : replace RAM code starting address with image + * destination address or not. (added in CONNAC) + * bit(7) : download to EMI or not. (added in CONNAC) + */ +#define FW_FEATURE_SET_ENCRY BIT(0) +#define FW_FEATURE_SET_KEY_MASK BITS(1, 2) +#define GET_FW_FEATURE_SET_KEY(p) (((p) & FW_FEATURE_SET_KEY_MASK) >> 1) +#define FW_FEATURE_COMPRESS_IMG BIT(3) +#define FW_FEATURE_ENCRY_MODE BIT(4) +#define FW_FEATURE_OVERRIDE_RAM_ADDR BIT(5) +#define FW_FEATURE_NOT_DOWNLOAD BIT(6) +#define FW_FEATURE_DL_TO_EMI BIT(7) + +#if CFG_SUPPORT_COMPRESSION_FW_OPTION +#define COMPRESSION_OPTION_OFFSET 4 +#define COMPRESSION_OPTION_MASK BIT(4) +#endif + +#define RELEASE_INFO_SEPARATOR_LEN 16 + +#if CFG_MTK_ANDROID_EMI +#define WIFI_EMI_ADDR_MASK 0xFFFFFF +extern phys_addr_t gConEmiPhyBaseFinal; +extern unsigned long long gConEmiSizeFinal; +#endif + +#if (!defined(UT_TEST_MODE) || !defined(CFG_BUILD_X86_PLATFORM)) +extern phys_addr_t gConEmiPhyBase; +extern unsigned long long gConEmiSize; +#endif + +/* + * patch format: + * PATCH_FORMAT_V1 support 7636, 7637, 7615, 7622, CONNAC (p18, 7663) + * PATCH_FORMAT_V2 support CONNANC2.0 (7915) + */ +/* Magic number, means use this multi-address patch header format*/ +#define PATCH_VERSION_MAGIC_NUM 0xffffffff +#define PATCH_SEC_TYPE_MASK 0x0000ffff +#define PATCH_SEC_TYPE_BIN_INFO 0x2 + +enum ENUM_IMG_DL_IDX_T { + IMG_DL_IDX_N9_FW, + IMG_DL_IDX_CR4_FW, + IMG_DL_IDX_PATCH, + IMG_DL_IDX_MCU_ROM_EMI, + IMG_DL_IDX_WIFI_ROM_EMI +}; + +struct FWDL_OPS_T { + /* load firmware bin priority */ + void (*constructFirmwarePrio)(struct GLUE_INFO *prGlueInfo, + uint8_t **apucNameTable, uint8_t **apucName, + uint8_t *pucNameIdx, uint8_t ucMaxNameIdx); + void (*constructPatchName)(struct GLUE_INFO *prGlueInfo, + uint8_t **apucName, uint8_t *pucNameIdx); + + uint32_t (*downloadPatch)(IN struct ADAPTER *prAdapter); + uint32_t (*downloadFirmware)(IN struct ADAPTER *prAdapter, + IN enum ENUM_IMG_DL_IDX_T eDlIdx); + uint32_t (*downloadByDynMemMap)( + IN struct ADAPTER *prAdapter, IN uint32_t u4Addr, + IN uint32_t u4Len, IN uint8_t *pucStartPtr, + IN enum ENUM_IMG_DL_IDX_T eDlIdx); + void (*getFwInfo)(IN struct ADAPTER *prAdapter, + IN uint8_t u4SecIdx, IN enum ENUM_IMG_DL_IDX_T eDlIdx, + OUT uint32_t *pu4Addr, OUT uint32_t *pu4Len, + OUT uint32_t *pu4DataMode, OUT u_int8_t *pfgIsEMIDownload, + OUT u_int8_t *pfgIsNotDownload); + unsigned int (*getFwDlInfo)(struct ADAPTER *prAdapter, + char *pcBuf, int i4TotalLen); + uint32_t (*phyAction)(IN struct ADAPTER *prAdapter); +}; + +#if (CFG_UMAC_GENERATION >= 0x20) +#define LEN_4_BYTE_CRC (4) + +struct TAILER_COMMON_FORMAT_T { + uint8_t ucChipInfo; + uint8_t ucEcoCode; + uint8_t ucRegionNum; + uint8_t ucFormatVer; + uint8_t ucFormatFlag; + uint8_t aucReserved[2]; + uint8_t aucRamVersion[10]; + uint8_t aucRamBuiltDate[15]; + uint32_t u4CRC; +}; + +struct TAILER_REGION_FORMAT_T { + uint32_t u4CRC; + uint32_t u4RealSize; + uint32_t u4BlockSize; + uint8_t aucReserved1[4]; + uint32_t u4Addr; + uint32_t u4Len; + uint8_t ucFeatureSet; + uint8_t aucReserved2[15]; +}; + +struct TAILER_FORMAT_T { + uint32_t addr; + uint8_t chip_info; + uint8_t feature_set; + uint8_t eco_code; + uint8_t ram_version[10]; + uint8_t ram_built_date[15]; + uint32_t len; +}; + +struct HEADER_RELEASE_INFO { + uint16_t u2Len; + uint8_t ucPaddingLen; + uint8_t ucTag; +}; + +#if CFG_SUPPORT_COMPRESSION_FW_OPTION +struct TAILER_FORMAT_T_2 { + uint32_t crc; + uint32_t addr; + uint32_t block_size; + uint32_t real_size; + uint8_t chip_info; + uint8_t feature_set; + uint8_t eco_code; + uint8_t ram_version[10]; + uint8_t ram_built_date[15]; + uint32_t len; +}; + +struct FW_IMAGE_TAILER_T_2 { + struct TAILER_FORMAT_T_2 ilm_info; + struct TAILER_FORMAT_T_2 dlm_info; +}; + +struct FW_IMAGE_TAILER_CHECK { + uint8_t chip_info; + uint8_t feature_set; + uint8_t eco_code; + uint8_t ram_version[10]; + uint8_t ram_built_date[15]; + uint32_t len; +}; +#endif + +struct PATCH_FORMAT_T { + uint8_t aucBuildDate[16]; + uint8_t aucPlatform[4]; + uint32_t u4SwHwVersion; + uint32_t u4PatchVersion; + uint16_t u2CRC; /* CRC calculated for image only */ + uint8_t ucPatchImage[0]; +}; + +struct PATCH_FORMAT_V2_T { + uint8_t aucBuildDate[16]; + uint8_t aucPlatform[4]; + uint32_t u4SwHwVersion; + uint32_t u4PatchVersion; + uint16_t u2Reserved; + uint16_t u2CRC; /* CRC calculated for image only */ +}; + +/* multi-addr patch format */ +struct PATCH_GLO_DESC { + uint32_t patch_ver; + uint32_t subsys; + uint32_t feature; + uint32_t section_num; + uint32_t crc; + uint32_t reserved[11]; +}; + +struct PATCH_SEC_MAP { + uint32_t section_type; + uint32_t section_offset; + uint32_t section_size; + union { + uint32_t section_spec[13]; + struct { + uint32_t dl_addr; + uint32_t dl_size; + uint32_t sec_key_idx; + uint32_t align_len; + uint32_t reserved[9]; + } bin_info_spec; + }; +}; + +struct patch_dl_buf { + uint8_t *img_ptr; + uint32_t img_dest_addr; + uint32_t img_size; + bool check_crc; +}; + +struct patch_dl_target { + struct patch_dl_buf *patch_region; + uint8_t num_of_region; +}; + +#endif + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +#if CFG_ENABLE_FW_DOWNLOAD +uint32_t wlanGetDataMode(IN struct ADAPTER *prAdapter, + IN enum ENUM_IMG_DL_IDX_T eDlIdx, IN uint8_t ucFeatureSet); + +void wlanGetHarvardFwInfo(IN struct ADAPTER *prAdapter, + IN uint8_t u4SecIdx, IN enum ENUM_IMG_DL_IDX_T eDlIdx, + OUT uint32_t *pu4Addr, OUT uint32_t *pu4Len, + OUT uint32_t *pu4DataMode, OUT u_int8_t *pfgIsEMIDownload, + OUT u_int8_t *pfgIsNotDownload); + +void wlanGetConnacFwInfo(IN struct ADAPTER *prAdapter, + IN uint8_t u4SecIdx, IN enum ENUM_IMG_DL_IDX_T eDlIdx, + OUT uint32_t *pu4Addr, OUT uint32_t *pu4Len, + OUT uint32_t *pu4DataMode, OUT u_int8_t *pfgIsEMIDownload, + OUT u_int8_t *pfgIsNotDownload); + +void wlanImageSectionGetPatchInfoV2(IN struct ADAPTER + *prAdapter, + IN void *pvFwImageMapFile, IN uint32_t u4FwImageFileLength, + OUT uint32_t *pu4DataMode, + struct patch_dl_target *target); + +void wlanImageSectionGetPatchInfo(IN struct ADAPTER + *prAdapter, + IN void *pvFwImageMapFile, IN uint32_t u4FwImageFileLength, + OUT uint32_t *pu4StartOffset, OUT uint32_t *pu4Addr, + OUT uint32_t *pu4Len, + OUT uint32_t *pu4DataMode); + +#if CFG_SUPPORT_COMPRESSION_FW_OPTION +uint32_t wlanCompressedImageSectionDownloadStage(IN struct ADAPTER *prAdapter, + IN void *pvFwImageMapFile, IN uint32_t u4FwImageFileLength, + uint8_t ucSectionNumber, IN enum ENUM_IMG_DL_IDX_T eDlIdx, + OUT uint8_t *ucIsCompressed, + OUT struct INIT_CMD_WIFI_DECOMPRESSION_START *prFwImageInFo); +#endif +uint32_t wlanImageSectionDownloadStage(IN struct ADAPTER *prAdapter, + IN void *pvFwImageMapFile, + IN uint32_t u4FwImageFileLength, IN uint8_t ucSectionNumber, + IN enum ENUM_IMG_DL_IDX_T eDlIdx); + +uint32_t wlanPatchSendComplete(IN struct ADAPTER *prAdapter); + +#if (CFG_DOWNLOAD_DYN_MEMORY_MAP == 1) +uint32_t wlanPatchDynMemMapSendComplete(IN struct ADAPTER *prAdapter); + +uint32_t wlanRamCodeDynMemMapSendComplete(IN struct ADAPTER *prAdapter, + IN u_int8_t fgEnable, IN uint32_t u4StartAddress, + IN uint8_t ucPDA); +#endif + +uint32_t wlanDownloadSection(IN struct ADAPTER *prAdapter, + IN uint32_t u4Addr, IN uint32_t u4Len, + IN uint32_t u4DataMode, IN uint8_t *pucStartPtr, + IN enum ENUM_IMG_DL_IDX_T eDlIdx); + +uint32_t wlanDownloadSectionV2(IN struct ADAPTER *prAdapter, + IN uint32_t u4DataMode, + IN enum ENUM_IMG_DL_IDX_T eDlIdx, + struct patch_dl_target *target); + +uint32_t wlanDownloadEMISection(IN struct ADAPTER *prAdapter, + IN uint32_t u4DestAddr, + IN uint32_t u4Len, IN uint8_t *pucStartPtr); + +uint32_t wlanGetHarvardTailerInfo(IN struct ADAPTER *prAdapter, + IN void *prFwBuffer, IN uint32_t u4FwSize, + IN uint32_t ucTotSecNum, IN enum ENUM_IMG_DL_IDX_T eDlIdx); + +uint32_t wlanGetConnacTailerInfo(IN struct ADAPTER *prAdapter, + IN void *prFwBuffer, + IN uint32_t u4FwSize, IN enum ENUM_IMG_DL_IDX_T eDlIdx); + +uint32_t wlanImageSectionConfig(IN struct ADAPTER *prAdapter, + IN uint32_t u4DestAddr, IN uint32_t u4ImgSecSize, + IN uint32_t u4DataMode, + IN enum ENUM_IMG_DL_IDX_T eDlIdx); + +uint32_t wlanImageSectionDownload(IN struct ADAPTER *prAdapter, + IN uint32_t u4ImgSecSize, IN uint8_t *pucImgSecBuf); + +uint32_t wlanImageQueryStatus(IN struct ADAPTER *prAdapter); + +uint32_t wlanConfigWifiFuncStatus(IN struct ADAPTER *prAdapter, + IN uint8_t ucCmdSeqNum); + +uint32_t wlanConfigWifiFunc(IN struct ADAPTER *prAdapter, + IN u_int8_t fgEnable, IN uint32_t u4StartAddress, + IN uint8_t ucPDA); + +uint32_t wlanCRC32(uint8_t *buf, uint32_t len); + +uint32_t wlanDownloadCR4FW(IN struct ADAPTER *prAdapter, + void *prFwBuffer); + +uint32_t wlanDownloadFW(IN struct ADAPTER *prAdapter); + +uint32_t wlanDownloadPatch(IN struct ADAPTER *prAdapter); + +uint32_t wlanHarvardFormatDownload(IN struct ADAPTER *prAdapter, + IN enum ENUM_IMG_DL_IDX_T eDlIdx); + +uint32_t wlanConnacFormatDownload(IN struct ADAPTER *prAdapter, + IN enum ENUM_IMG_DL_IDX_T eDlIdx); + +uint32_t wlanGetPatchInfo(IN struct ADAPTER *prAdapter); + +uint32_t fwDlGetFwdlInfo(struct ADAPTER *prAdapter, + char *pcBuf, int i4TotalLen); + +void fwDlGetReleaseInfoSection(struct ADAPTER *prAdapter, uint8_t *pucStartPtr); +void fwDlGetReleaseManifest(struct ADAPTER *prAdapter, + struct HEADER_RELEASE_INFO *prRelInfo, + uint8_t *pucStartPtr); + +#endif + +#if (CFG_SUPPORT_CONNINFRA == 1) +extern void conninfra_get_phy_addr(unsigned int *addr, unsigned int *size); +#endif + +#endif /* _FW_DL_H */ + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/hal_dmashdl_mt7961.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/hal_dmashdl_mt7961.h new file mode 100644 index 0000000000000000000000000000000000000000..389f9e9bc7efeb0366a67f23454cb4a5731a3603 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/hal_dmashdl_mt7961.h @@ -0,0 +1,376 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2019 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2019 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/*! \file hal_dmashdl_mt7961.h +* \brief DMASHDL HAL API for MT7961 +* +* This file contains all routines which are exported + from MediaTek 802.11 Wireless LAN driver stack to GLUE Layer. +*/ + +#ifndef _HAL_DMASHDL_MT7961_H +#define _HAL_DMASHDL_MT7961_H + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ +/* align MT7663 setting first */ +#if defined(_HIF_PCIE) || defined(_HIF_AXI) + +/* 1: 3rd arbitration makes decision based on group priority in current slot. + * 0: 3rd arbitration makes decision based on fixed user-defined priority. + */ +#define MT7961_DMASHDL_SLOT_ARBITER_EN (0) +#define MT7961_DMASHDL_PKT_PLE_MAX_PAGE (0x1) +/* Buzzard CMD packet flow control is controlled by WFDMA, not DMASHDL. + * So, CMD packet (group 15) related CRs in DMASHDL are ignored. + */ +#define MT7961_DMASHDL_PKT_PSE_MAX_PAGE (0x0) +#define MT7961_DMASHDL_GROUP_0_REFILL_EN (1) +#define MT7961_DMASHDL_GROUP_1_REFILL_EN (0) +#define MT7961_DMASHDL_GROUP_2_REFILL_EN (0) +#define MT7961_DMASHDL_GROUP_3_REFILL_EN (0) +#define MT7961_DMASHDL_GROUP_4_REFILL_EN (0) +#define MT7961_DMASHDL_GROUP_5_REFILL_EN (0) +#define MT7961_DMASHDL_GROUP_6_REFILL_EN (0) +#define MT7961_DMASHDL_GROUP_7_REFILL_EN (0) +#define MT7961_DMASHDL_GROUP_8_REFILL_EN (0) +#define MT7961_DMASHDL_GROUP_9_REFILL_EN (0) +#define MT7961_DMASHDL_GROUP_10_REFILL_EN (0) +#define MT7961_DMASHDL_GROUP_11_REFILL_EN (0) +#define MT7961_DMASHDL_GROUP_12_REFILL_EN (0) +#define MT7961_DMASHDL_GROUP_13_REFILL_EN (0) +#define MT7961_DMASHDL_GROUP_14_REFILL_EN (0) +#define MT7961_DMASHDL_GROUP_15_REFILL_EN (0) +#define MT7961_DMASHDL_GROUP_0_MAX_QUOTA (0xFFF) +#define MT7961_DMASHDL_GROUP_1_MAX_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_2_MAX_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_3_MAX_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_4_MAX_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_5_MAX_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_6_MAX_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_7_MAX_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_8_MAX_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_9_MAX_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_10_MAX_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_11_MAX_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_12_MAX_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_13_MAX_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_14_MAX_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_15_MAX_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_0_MIN_QUOTA (0x3) +#define MT7961_DMASHDL_GROUP_1_MIN_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_2_MIN_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_3_MIN_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_4_MIN_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_5_MIN_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_6_MIN_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_7_MIN_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_8_MIN_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_9_MIN_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_10_MIN_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_11_MIN_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_12_MIN_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_13_MIN_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_14_MIN_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_15_MIN_QUOTA (0x0) +#define MT7961_DMASHDL_QUEUE_0_TO_GROUP (0x0) /* LMAC AC00 */ +#define MT7961_DMASHDL_QUEUE_1_TO_GROUP (0x0) /* LMAC AC01 */ +#define MT7961_DMASHDL_QUEUE_2_TO_GROUP (0x0) /* LMAC AC02 */ +#define MT7961_DMASHDL_QUEUE_3_TO_GROUP (0x0) /* LMAC AC03 */ +#define MT7961_DMASHDL_QUEUE_4_TO_GROUP (0x0) /* LMAC AC10 */ +#define MT7961_DMASHDL_QUEUE_5_TO_GROUP (0x0) /* LMAC AC11 */ +#define MT7961_DMASHDL_QUEUE_6_TO_GROUP (0x0) /* LMAC AC12 */ +#define MT7961_DMASHDL_QUEUE_7_TO_GROUP (0x0) /* LMAC AC13 */ +#define MT7961_DMASHDL_QUEUE_8_TO_GROUP (0x0) /* LMAC AC20 */ +#define MT7961_DMASHDL_QUEUE_9_TO_GROUP (0x0) /* LMAC AC21 */ +#define MT7961_DMASHDL_QUEUE_10_TO_GROUP (0x0) /* LMAC AC22 */ +#define MT7961_DMASHDL_QUEUE_11_TO_GROUP (0x0) /* LMAC AC23 */ +#define MT7961_DMASHDL_QUEUE_12_TO_GROUP (0x0) /* LMAC AC30 */ +#define MT7961_DMASHDL_QUEUE_13_TO_GROUP (0x0) /* LMAC AC31 */ +#define MT7961_DMASHDL_QUEUE_14_TO_GROUP (0x0) /* LMAC AC32 */ +#define MT7961_DMASHDL_QUEUE_15_TO_GROUP (0x0) /* LMAC AC33 */ +#define MT7961_DMASHDL_QUEUE_16_TO_GROUP (0x0) /* ALTX */ +#define MT7961_DMASHDL_QUEUE_17_TO_GROUP (0x0) /* BMC */ +#define MT7961_DMASHDL_QUEUE_18_TO_GROUP (0x0) /* BCN */ +#define MT7961_DMASHDL_QUEUE_19_TO_GROUP (0x1) /* HW Reserved */ +#define MT7961_DMASHDL_QUEUE_20_TO_GROUP (0x1) /* HW Reserved */ +#define MT7961_DMASHDL_QUEUE_21_TO_GROUP (0x1) /* HW Reserved */ +#define MT7961_DMASHDL_QUEUE_22_TO_GROUP (0x1) /* HW Reserved */ +#define MT7961_DMASHDL_QUEUE_23_TO_GROUP (0x1) /* HW Reserved */ +#define MT7961_DMASHDL_QUEUE_24_TO_GROUP (0x0) /* NAF */ +#define MT7961_DMASHDL_QUEUE_25_TO_GROUP (0x0) /* NBCN */ +#define MT7961_DMASHDL_QUEUE_26_TO_GROUP (0x0) /* FIXFID */ +#define MT7961_DMASHDL_QUEUE_27_TO_GROUP (0x1) /* Reserved */ +#define MT7961_DMASHDL_QUEUE_28_TO_GROUP (0x1) /* Reserved */ +#define MT7961_DMASHDL_QUEUE_29_TO_GROUP (0x1) /* Reserved */ +#define MT7961_DMASHDL_QUEUE_30_TO_GROUP (0x1) /* Reserved */ +#define MT7961_DMASHDL_QUEUE_31_TO_GROUP (0x1) /* Reserved */ +#define MT7961_DMASHDL_PRIORITY0_GROUP (0x0) +#define MT7961_DMASHDL_PRIORITY1_GROUP (0x1) +#define MT7961_DMASHDL_PRIORITY2_GROUP (0x2) +#define MT7961_DMASHDL_PRIORITY3_GROUP (0x3) +#define MT7961_DMASHDL_PRIORITY4_GROUP (0x4) +#define MT7961_DMASHDL_PRIORITY5_GROUP (0x5) +#define MT7961_DMASHDL_PRIORITY6_GROUP (0x6) +#define MT7961_DMASHDL_PRIORITY7_GROUP (0x7) +#define MT7961_DMASHDL_PRIORITY8_GROUP (0x8) +#define MT7961_DMASHDL_PRIORITY9_GROUP (0x9) +#define MT7961_DMASHDL_PRIORITY10_GROUP (0xA) +#define MT7961_DMASHDL_PRIORITY11_GROUP (0xB) +#define MT7961_DMASHDL_PRIORITY12_GROUP (0xC) +#define MT7961_DMASHDL_PRIORITY13_GROUP (0xD) +#define MT7961_DMASHDL_PRIORITY14_GROUP (0xE) +#define MT7961_DMASHDL_PRIORITY15_GROUP (0xF) + +#elif defined(_HIF_USB) + +/* 1: 3rd arbitration makes decision based on group priority in current slot. + * 0: 3rd arbitration makes decision based on fixed user-defined priority. + */ +#define MT7961_DMASHDL_SLOT_ARBITER_EN (0) +#define MT7961_DMASHDL_PKT_PLE_MAX_PAGE (0x1) +/* Buzzard CMD packet flow control is controlled by WFDMA, not DMASHDL. + * So, CMD packet (group 15) related CRs in DMASHDL are ignored. + */ +#define MT7961_DMASHDL_PKT_PSE_MAX_PAGE (0x0) +#define MT7961_DMASHDL_GROUP_0_REFILL_EN (1) +#define MT7961_DMASHDL_GROUP_1_REFILL_EN (1) +#define MT7961_DMASHDL_GROUP_2_REFILL_EN (1) +#define MT7961_DMASHDL_GROUP_3_REFILL_EN (1) +#define MT7961_DMASHDL_GROUP_4_REFILL_EN (1) +#define MT7961_DMASHDL_GROUP_5_REFILL_EN (0) +#define MT7961_DMASHDL_GROUP_6_REFILL_EN (0) +#define MT7961_DMASHDL_GROUP_7_REFILL_EN (0) +#define MT7961_DMASHDL_GROUP_8_REFILL_EN (0) +#define MT7961_DMASHDL_GROUP_9_REFILL_EN (0) +#define MT7961_DMASHDL_GROUP_10_REFILL_EN (0) +#define MT7961_DMASHDL_GROUP_11_REFILL_EN (0) +#define MT7961_DMASHDL_GROUP_12_REFILL_EN (0) +#define MT7961_DMASHDL_GROUP_13_REFILL_EN (0) +#define MT7961_DMASHDL_GROUP_14_REFILL_EN (0) +#define MT7961_DMASHDL_GROUP_15_REFILL_EN (0) +#define MT7961_DMASHDL_GROUP_0_MAX_QUOTA (0xFFF) +#define MT7961_DMASHDL_GROUP_1_MAX_QUOTA (0xFFF) +#define MT7961_DMASHDL_GROUP_2_MAX_QUOTA (0xFFF) +#define MT7961_DMASHDL_GROUP_3_MAX_QUOTA (0xFFF) +#define MT7961_DMASHDL_GROUP_4_MAX_QUOTA (0xFFF) +#define MT7961_DMASHDL_GROUP_5_MAX_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_6_MAX_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_7_MAX_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_8_MAX_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_9_MAX_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_10_MAX_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_11_MAX_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_12_MAX_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_13_MAX_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_14_MAX_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_15_MAX_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_0_MIN_QUOTA (0x3) +#define MT7961_DMASHDL_GROUP_1_MIN_QUOTA (0x3) +#define MT7961_DMASHDL_GROUP_2_MIN_QUOTA (0x3) +#define MT7961_DMASHDL_GROUP_3_MIN_QUOTA (0x3) +#define MT7961_DMASHDL_GROUP_4_MIN_QUOTA (0x3) +#define MT7961_DMASHDL_GROUP_5_MIN_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_6_MIN_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_7_MIN_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_8_MIN_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_9_MIN_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_10_MIN_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_11_MIN_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_12_MIN_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_13_MIN_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_14_MIN_QUOTA (0x0) +#define MT7961_DMASHDL_GROUP_15_MIN_QUOTA (0x0) +#define MT7961_DMASHDL_QUEUE_0_TO_GROUP (0x0) /* LMAC AC00 */ +#define MT7961_DMASHDL_QUEUE_1_TO_GROUP (0x1) /* LMAC AC01 */ +#define MT7961_DMASHDL_QUEUE_2_TO_GROUP (0x2) /* LMAC AC02 */ +#define MT7961_DMASHDL_QUEUE_3_TO_GROUP (0x3) /* LMAC AC03 */ +#define MT7961_DMASHDL_QUEUE_4_TO_GROUP (0x4) /* LMAC AC10 */ +#define MT7961_DMASHDL_QUEUE_5_TO_GROUP (0x4) /* LMAC AC11 */ +#define MT7961_DMASHDL_QUEUE_6_TO_GROUP (0x4) /* LMAC AC12 */ +#define MT7961_DMASHDL_QUEUE_7_TO_GROUP (0x4) /* LMAC AC13 */ +#define MT7961_DMASHDL_QUEUE_8_TO_GROUP (0x4) /* LMAC AC20 */ +#define MT7961_DMASHDL_QUEUE_9_TO_GROUP (0x4) /* LMAC AC21 */ +#define MT7961_DMASHDL_QUEUE_10_TO_GROUP (0x4) /* LMAC AC22 */ +#define MT7961_DMASHDL_QUEUE_11_TO_GROUP (0x4) /* LMAC AC23 */ +#define MT7961_DMASHDL_QUEUE_12_TO_GROUP (0x4) /* LMAC AC30 */ +#define MT7961_DMASHDL_QUEUE_13_TO_GROUP (0x4) /* LMAC AC31 */ +#define MT7961_DMASHDL_QUEUE_14_TO_GROUP (0x4) /* LMAC AC32 */ +#define MT7961_DMASHDL_QUEUE_15_TO_GROUP (0x4) /* LMAC AC33 */ +#define MT7961_DMASHDL_QUEUE_16_TO_GROUP (0x4) /* ALTX */ +#define MT7961_DMASHDL_QUEUE_17_TO_GROUP (0x4) /* BMC */ +#define MT7961_DMASHDL_QUEUE_18_TO_GROUP (0x4) /* BCN */ +#define MT7961_DMASHDL_QUEUE_19_TO_GROUP (0x5) /* HW Reserved */ +#define MT7961_DMASHDL_QUEUE_20_TO_GROUP (0x5) /* HW Reserved */ +#define MT7961_DMASHDL_QUEUE_21_TO_GROUP (0x5) /* HW Reserved */ +#define MT7961_DMASHDL_QUEUE_22_TO_GROUP (0x5) /* HW Reserved */ +#define MT7961_DMASHDL_QUEUE_23_TO_GROUP (0x5) /* HW Reserved */ +#define MT7961_DMASHDL_QUEUE_24_TO_GROUP (0x4) /* NAF */ +#define MT7961_DMASHDL_QUEUE_25_TO_GROUP (0x4) /* NBCN */ +#define MT7961_DMASHDL_QUEUE_26_TO_GROUP (0x4) /* FIXFID */ +#define MT7961_DMASHDL_QUEUE_27_TO_GROUP (0x5) /* Reserved */ +#define MT7961_DMASHDL_QUEUE_28_TO_GROUP (0x5) /* Reserved */ +#define MT7961_DMASHDL_QUEUE_29_TO_GROUP (0x5) /* Reserved */ +#define MT7961_DMASHDL_QUEUE_30_TO_GROUP (0x5) /* Reserved */ +#define MT7961_DMASHDL_QUEUE_31_TO_GROUP (0x5) /* Reserved */ +#define MT7961_DMASHDL_PRIORITY0_GROUP (0x3) +#define MT7961_DMASHDL_PRIORITY1_GROUP (0x2) +#define MT7961_DMASHDL_PRIORITY2_GROUP (0x1) +#define MT7961_DMASHDL_PRIORITY3_GROUP (0x0) +#define MT7961_DMASHDL_PRIORITY4_GROUP (0x4) +#define MT7961_DMASHDL_PRIORITY5_GROUP (0x5) +#define MT7961_DMASHDL_PRIORITY6_GROUP (0x6) +#define MT7961_DMASHDL_PRIORITY7_GROUP (0x7) +#define MT7961_DMASHDL_PRIORITY8_GROUP (0x8) +#define MT7961_DMASHDL_PRIORITY9_GROUP (0x9) +#define MT7961_DMASHDL_PRIORITY10_GROUP (0xA) +#define MT7961_DMASHDL_PRIORITY11_GROUP (0xB) +#define MT7961_DMASHDL_PRIORITY12_GROUP (0xC) +#define MT7961_DMASHDL_PRIORITY13_GROUP (0xD) +#define MT7961_DMASHDL_PRIORITY14_GROUP (0xE) +#define MT7961_DMASHDL_PRIORITY15_GROUP (0xF) + +#endif /* defined(_HIF_PCIE) || defined(_HIF_AXI) */ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +enum ENUM_MT7961_DMASHDL_GROUP_IDX { + ENUM_MT7961_DMASHDL_GROUP_0 = 0, + ENUM_MT7961_DMASHDL_GROUP_1, + ENUM_MT7961_DMASHDL_GROUP_2, + ENUM_MT7961_DMASHDL_GROUP_3, + ENUM_MT7961_DMASHDL_GROUP_4, + ENUM_MT7961_DMASHDL_GROUP_5, + ENUM_MT7961_DMASHDL_GROUP_6, + ENUM_MT7961_DMASHDL_GROUP_7, + ENUM_MT7961_DMASHDL_GROUP_8, + ENUM_MT7961_DMASHDL_GROUP_9, + ENUM_MT7961_DMASHDL_GROUP_10, + ENUM_MT7961_DMASHDL_GROUP_11, + ENUM_MT7961_DMASHDL_GROUP_12, + ENUM_MT7961_DMASHDL_GROUP_13, + ENUM_MT7961_DMASHDL_GROUP_14, + ENUM_MT7961_DMASHDL_GROUP_15, + ENUM_MT7961_DMASHDL_GROUP_NUM +}; + +struct MT7961_DMASHDL_CFG { + u_int8_t fgSlotArbiterEn; + uint16_t u2PktPleMaxPage; + uint16_t u2PktPseMaxPage; + u_int8_t afgRefillEn[ENUM_MT7961_DMASHDL_GROUP_NUM]; + uint16_t au2MaxQuota[ENUM_MT7961_DMASHDL_GROUP_NUM]; + uint16_t au2MinQuota[ENUM_MT7961_DMASHDL_GROUP_NUM]; + uint8_t aucQueue2Group[32]; + uint8_t aucPriority2Group[16]; +}; + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +void mt7961HalDmashdlSetPlePktMaxPage(struct ADAPTER *prAdapter, + uint16_t u2MaxPage); + +void mt7961HalDmashdlSetPsePktMaxPage(struct ADAPTER *prAdapter, + uint16_t u2MaxPage); + +void mt7961HalDmashdlSetRefill(struct ADAPTER *prAdapter, uint8_t ucGroup, + u_int8_t fgEnable); + +void mt7961HalDmashdlSetMaxQuota(struct ADAPTER *prAdapter, uint8_t ucGroup, + uint16_t u2MaxQuota); + +void mt7961HalDmashdlSetMinQuota(struct ADAPTER *prAdatper, uint8_t ucGroup, + uint16_t u2MinQuota); + +void mt7961HalDmashdlSetQueueMapping(struct ADAPTER *prAdapter, uint8_t ucQueue, + uint8_t ucGroup); + +void mt7961DmashdlInit(struct ADAPTER *prAdapter); + +#endif /* _HAL_DMASHDL_MT7961_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/hal_dmashdl_soc3_0.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/hal_dmashdl_soc3_0.h new file mode 100644 index 0000000000000000000000000000000000000000..67f263b44acadaca89c80765b5c438c6e89015a3 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/hal_dmashdl_soc3_0.h @@ -0,0 +1,233 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +/*! \file hal_dmashdl_mt6885.h +* \brief DMASHDL HAL API for MT6885 +* +* This file contains all routines which are exported + from MediaTek 802.11 Wireless LAN driver stack to GLUE Layer. +*/ + +#ifndef _HAL_DMASHDL_MT6885_H +#define _HAL_DMASHDL_MT6885_H + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ +/* align MT7663 setting first */ +#if defined(_HIF_PCIE) || defined(_HIF_AXI) + +/* 1: 3rd arbitration makes decision based on group priority in current slot. + * 0: 3rd arbitration makes decision based on fixed user-defined priority. + */ +#define MT6885_DMASHDL_SLOT_ARBITER_EN (0) +#define MT6885_DMASHDL_PKT_PLE_MAX_PAGE (0x1) +#define MT6885_DMASHDL_PKT_PSE_MAX_PAGE (0x0) +#define MT6885_DMASHDL_GROUP_0_REFILL_EN (1) +#define MT6885_DMASHDL_GROUP_1_REFILL_EN (1) +#define MT6885_DMASHDL_GROUP_2_REFILL_EN (0) +#define MT6885_DMASHDL_GROUP_3_REFILL_EN (0) +#define MT6885_DMASHDL_GROUP_4_REFILL_EN (0) +#define MT6885_DMASHDL_GROUP_5_REFILL_EN (0) +#define MT6885_DMASHDL_GROUP_6_REFILL_EN (0) +#define MT6885_DMASHDL_GROUP_7_REFILL_EN (0) +#define MT6885_DMASHDL_GROUP_8_REFILL_EN (0) +#define MT6885_DMASHDL_GROUP_9_REFILL_EN (0) +#define MT6885_DMASHDL_GROUP_10_REFILL_EN (0) +#define MT6885_DMASHDL_GROUP_11_REFILL_EN (0) +#define MT6885_DMASHDL_GROUP_12_REFILL_EN (0) +#define MT6885_DMASHDL_GROUP_13_REFILL_EN (0) +#define MT6885_DMASHDL_GROUP_14_REFILL_EN (0) +#define MT6885_DMASHDL_GROUP_15_REFILL_EN (0) +#define MT6885_DMASHDL_GROUP_0_MAX_QUOTA (0x15D) +#define MT6885_DMASHDL_GROUP_1_MAX_QUOTA (0x15D) +#define MT6885_DMASHDL_GROUP_2_MAX_QUOTA (0x0) +#define MT6885_DMASHDL_GROUP_3_MAX_QUOTA (0x0) +#define MT6885_DMASHDL_GROUP_4_MAX_QUOTA (0x0) +#define MT6885_DMASHDL_GROUP_5_MAX_QUOTA (0x0) +#define MT6885_DMASHDL_GROUP_6_MAX_QUOTA (0x0) +#define MT6885_DMASHDL_GROUP_7_MAX_QUOTA (0x0) +#define MT6885_DMASHDL_GROUP_8_MAX_QUOTA (0x0) +#define MT6885_DMASHDL_GROUP_9_MAX_QUOTA (0x0) +#define MT6885_DMASHDL_GROUP_10_MAX_QUOTA (0x0) +#define MT6885_DMASHDL_GROUP_11_MAX_QUOTA (0x0) +#define MT6885_DMASHDL_GROUP_12_MAX_QUOTA (0x0) +#define MT6885_DMASHDL_GROUP_13_MAX_QUOTA (0x0) +#define MT6885_DMASHDL_GROUP_14_MAX_QUOTA (0x0) +#define MT6885_DMASHDL_GROUP_15_MAX_QUOTA (0x0) +#define MT6885_DMASHDL_GROUP_0_MIN_QUOTA (0x10) +#define MT6885_DMASHDL_GROUP_1_MIN_QUOTA (0x10) +#define MT6885_DMASHDL_GROUP_2_MIN_QUOTA (0x0) +#define MT6885_DMASHDL_GROUP_3_MIN_QUOTA (0x0) +#define MT6885_DMASHDL_GROUP_4_MIN_QUOTA (0x0) +#define MT6885_DMASHDL_GROUP_5_MIN_QUOTA (0x0) +#define MT6885_DMASHDL_GROUP_6_MIN_QUOTA (0x0) +#define MT6885_DMASHDL_GROUP_7_MIN_QUOTA (0x0) +#define MT6885_DMASHDL_GROUP_8_MIN_QUOTA (0x0) +#define MT6885_DMASHDL_GROUP_9_MIN_QUOTA (0x0) +#define MT6885_DMASHDL_GROUP_10_MIN_QUOTA (0x0) +#define MT6885_DMASHDL_GROUP_11_MIN_QUOTA (0x0) +#define MT6885_DMASHDL_GROUP_12_MIN_QUOTA (0x0) +#define MT6885_DMASHDL_GROUP_13_MIN_QUOTA (0x0) +#define MT6885_DMASHDL_GROUP_14_MIN_QUOTA (0x0) +#define MT6885_DMASHDL_GROUP_15_MIN_QUOTA (0x0) +#define MT6885_DMASHDL_QUEUE_0_TO_GROUP (0x0) /* LMAC AC00 */ +#define MT6885_DMASHDL_QUEUE_1_TO_GROUP (0x0) /* LMAC AC01 */ +#define MT6885_DMASHDL_QUEUE_2_TO_GROUP (0x0) /* LMAC AC02 */ +#define MT6885_DMASHDL_QUEUE_3_TO_GROUP (0x0) /* LMAC AC03 */ +#define MT6885_DMASHDL_QUEUE_4_TO_GROUP (0x1) /* LMAC AC10 */ +#define MT6885_DMASHDL_QUEUE_5_TO_GROUP (0x1) /* LMAC AC11 */ +#define MT6885_DMASHDL_QUEUE_6_TO_GROUP (0x1) /* LMAC AC12 */ +#define MT6885_DMASHDL_QUEUE_7_TO_GROUP (0x1) /* LMAC AC13 */ +#define MT6885_DMASHDL_QUEUE_8_TO_GROUP (0x0) /* LMAC AC20 */ +#define MT6885_DMASHDL_QUEUE_9_TO_GROUP (0x0) /* LMAC AC21 */ +#define MT6885_DMASHDL_QUEUE_10_TO_GROUP (0x0) /* LMAC AC22 */ +#define MT6885_DMASHDL_QUEUE_11_TO_GROUP (0x0) /* LMAC AC23 */ +#define MT6885_DMASHDL_QUEUE_12_TO_GROUP (0x0) /* LMAC AC30 */ +#define MT6885_DMASHDL_QUEUE_13_TO_GROUP (0x0) /* LMAC AC31 */ +#define MT6885_DMASHDL_QUEUE_14_TO_GROUP (0x0) /* LMAC AC32 */ +#define MT6885_DMASHDL_QUEUE_15_TO_GROUP (0x0) /* LMAC AC33 */ +#define MT6885_DMASHDL_QUEUE_16_TO_GROUP (0x0) /* ALTX */ +#define MT6885_DMASHDL_QUEUE_17_TO_GROUP (0x0) /* BMC */ +#define MT6885_DMASHDL_QUEUE_18_TO_GROUP (0x0) /* BCN */ +#define MT6885_DMASHDL_QUEUE_19_TO_GROUP (0x1) /* HW Reserved */ +#define MT6885_DMASHDL_QUEUE_20_TO_GROUP (0x1) /* HW Reserved */ +#define MT6885_DMASHDL_QUEUE_21_TO_GROUP (0x1) /* HW Reserved */ +#define MT6885_DMASHDL_QUEUE_22_TO_GROUP (0x1) /* HW Reserved */ +#define MT6885_DMASHDL_QUEUE_23_TO_GROUP (0x1) /* HW Reserved */ +#define MT6885_DMASHDL_QUEUE_24_TO_GROUP (0x0) /* NAF */ +#define MT6885_DMASHDL_QUEUE_25_TO_GROUP (0x0) /* NBCN */ +#define MT6885_DMASHDL_QUEUE_26_TO_GROUP (0x0) /* FIXFID */ +#define MT6885_DMASHDL_QUEUE_27_TO_GROUP (0x1) /* Reserved */ +#define MT6885_DMASHDL_QUEUE_28_TO_GROUP (0x1) /* Reserved */ +#define MT6885_DMASHDL_QUEUE_29_TO_GROUP (0x1) /* Reserved */ +#define MT6885_DMASHDL_QUEUE_30_TO_GROUP (0x1) /* Reserved */ +#define MT6885_DMASHDL_QUEUE_31_TO_GROUP (0x1) /* Reserved */ +#define MT6885_DMASHDL_PRIORITY0_GROUP (0x0) +#define MT6885_DMASHDL_PRIORITY1_GROUP (0x1) +#define MT6885_DMASHDL_PRIORITY2_GROUP (0x2) +#define MT6885_DMASHDL_PRIORITY3_GROUP (0x3) +#define MT6885_DMASHDL_PRIORITY4_GROUP (0x4) +#define MT6885_DMASHDL_PRIORITY5_GROUP (0x5) +#define MT6885_DMASHDL_PRIORITY6_GROUP (0x6) +#define MT6885_DMASHDL_PRIORITY7_GROUP (0x7) +#define MT6885_DMASHDL_PRIORITY8_GROUP (0x8) +#define MT6885_DMASHDL_PRIORITY9_GROUP (0x9) +#define MT6885_DMASHDL_PRIORITY10_GROUP (0xA) +#define MT6885_DMASHDL_PRIORITY11_GROUP (0xB) +#define MT6885_DMASHDL_PRIORITY12_GROUP (0xC) +#define MT6885_DMASHDL_PRIORITY13_GROUP (0xD) +#define MT6885_DMASHDL_PRIORITY14_GROUP (0xE) +#define MT6885_DMASHDL_PRIORITY15_GROUP (0xF) + +#endif /* defined(_HIF_PCIE) || defined(_HIF_AXI) */ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +enum ENUM_MT6885_DMASHDL_GROUP_IDX { + ENUM_MT6885_DMASHDL_GROUP_0 = 0, + ENUM_MT6885_DMASHDL_GROUP_1, + ENUM_MT6885_DMASHDL_GROUP_2, + ENUM_MT6885_DMASHDL_GROUP_3, + ENUM_MT6885_DMASHDL_GROUP_4, + ENUM_MT6885_DMASHDL_GROUP_5, + ENUM_MT6885_DMASHDL_GROUP_6, + ENUM_MT6885_DMASHDL_GROUP_7, + ENUM_MT6885_DMASHDL_GROUP_8, + ENUM_MT6885_DMASHDL_GROUP_9, + ENUM_MT6885_DMASHDL_GROUP_10, + ENUM_MT6885_DMASHDL_GROUP_11, + ENUM_MT6885_DMASHDL_GROUP_12, + ENUM_MT6885_DMASHDL_GROUP_13, + ENUM_MT6885_DMASHDL_GROUP_14, + ENUM_MT6885_DMASHDL_GROUP_15, + ENUM_MT6885_DMASHDL_GROUP_NUM +}; + +struct MT6885_DMASHDL_CFG { + u_int8_t fgSlotArbiterEn; + uint16_t u2PktPleMaxPage; + uint16_t u2PktPseMaxPage; + u_int8_t afgRefillEn[ENUM_MT6885_DMASHDL_GROUP_NUM]; + uint16_t au2MaxQuota[ENUM_MT6885_DMASHDL_GROUP_NUM]; + uint16_t au2MinQuota[ENUM_MT6885_DMASHDL_GROUP_NUM]; + uint8_t aucQueue2Group[32]; + uint8_t aucPriority2Group[16]; +}; + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +void mt6885HalDmashdlSetPlePktMaxPage(struct ADAPTER *prAdapter, + uint16_t u2MaxPage); + +void mt6885HalDmashdlSetPsePktMaxPage(struct ADAPTER *prAdapter, + uint16_t u2MaxPage); + +void mt6885HalDmashdlSetRefill(struct ADAPTER *prAdapter, uint8_t ucGroup, + u_int8_t fgEnable); + +void mt6885HalDmashdlSetMaxQuota(struct ADAPTER *prAdapter, uint8_t ucGroup, + uint16_t u2MaxQuota); + +void mt6885HalDmashdlSetMinQuota(struct ADAPTER *prAdatper, uint8_t ucGroup, + uint16_t u2MinQuota); + +void mt6885HalDmashdlSetQueueMapping(struct ADAPTER *prAdapter, uint8_t ucQueue, + uint8_t ucGroup); + +void mt6885DmashdlInit(struct ADAPTER *prAdapter); + +void mt6885HalDmashdlGetPktMaxPage(struct ADAPTER *prAdapter); + +void mt6885HalDmashdlGetRefill(struct ADAPTER *prAdapter); + +void mt6885HalDmashdlGetGroupControl(struct ADAPTER *prAdapter, + uint8_t ucGroup); + +uint32_t mt6885HalDmashdlGetRsvCount(struct ADAPTER *prAdapter, + uint8_t ucGroup); + +uint32_t mt6885HalDmashdlGetSrcCount(struct ADAPTER *prAdapter, + uint8_t ucGroup); + +void mt6885HalDmashdlGetPKTCount(struct ADAPTER *prAdapter, + uint8_t ucGroup); +#endif /* _HAL_DMASHDL_MT6885_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/host_csr.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/host_csr.h new file mode 100644 index 0000000000000000000000000000000000000000..9c4f554b9057fa3798ef4410bb18dc73e014a8c4 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/host_csr.h @@ -0,0 +1,104 @@ +/* + *************************************************************************** + * Ralink Tech Inc. + * 4F, No. 2 Technology 5th Rd. + * Science-based Industrial Park + * Hsin-chu, Taiwan, R.O.C. + * + * (c) Copyright 2002-2004, Ralink Technology, Inc. + * + * All rights reserved. Ralink's source code is an unpublished work and the + * use of a copyright notice does not imply otherwise. This source code + * contains confidential trade secret material of Ralink Tech. Any attemp + * or participation in deciphering, decoding, reverse engineering or in any + * way altering the source code is stricitly prohibited, unless the prior + * written consent of Ralink Technology, Inc. is obtained. + *************************************************************************** + + Module Name: + host_csr.h + + Abstract: + Ralink Wireless Chip MAC related definition & structures + + Revision History: + Who When What + -------- ---------- -------------------------------------- +*/ + +#ifndef __HOST_CSR_H__ +#define __HOST_CSR_H__ + +#define HOST_CSR_DRIVER_OWN_INFO 0x7000 +#define HOST_CSR_BASE 0x7100 + +/* MCU programming Counter info (no sync) */ +#define HOST_CSR_MCU_PORG_COUNT (HOST_CSR_BASE + 0x04) + +/* RGU Info */ +#define HOST_CSR_RGU (HOST_CSR_BASE + 0x08) + +/* HIF_BUSY / CIRQ / WFSYS_ON info */ +#define HOST_CSR_HIF_BUSY_CORQ_WFSYS_ON (HOST_CSR_BASE + 0x0C) + +/* Pinmux/mon_flag info */ +#define HOST_CSR_PINMUX_MON_FLAG (HOST_CSR_BASE + 0x10) + +/* Bit[5] mcu_pwr_stat */ +#define HOST_CSR_MCU_PWR_STAT (HOST_CSR_BASE + 0x14) + +/* Bit[15] fw_own_stat */ +#define HOST_CSR_FW_OWN_SET (HOST_CSR_BASE + 0x18) + +/* MCU SW Mailbox */ +#define HOST_CSR_MCU_SW_MAILBOX_0 (HOST_CSR_BASE + 0x1C) +#define HOST_CSR_MCU_SW_MAILBOX_1 (HOST_CSR_BASE + 0x20) +#define HOST_CSR_MCU_SW_MAILBOX_2 (HOST_CSR_BASE + 0x24) +#define HOST_CSR_MCU_SW_MAILBOX_3 (HOST_CSR_BASE + 0x28) + +/* Conn_cfg_on info */ +#define HOST_CSR_CONN_CFG_ON (HOST_CSR_BASE + 0x2C) + +/* Get conn_cfg_on IRQ ENA/IRQ Status 0xC_1170~0xC_1174 */ +#define HOST_CSR_IRQ_STA 0xC1170 +#define HOST_CSR_IRQ_ENA 0xC1174 + +/* Get mcu_cfg PC programming Counter log info 0x0_2450~0x0_24D0 */ +#define HOST_CSR_MCU_PROG_COUNT 0x2450 + +#if (CFG_ENABLE_HOST_BUS_TIMEOUT == 1) +#define HOST_CSR_BUS_TIMOUT_CTRL_ADDR (HOST_CSR_DRIVER_OWN_INFO + 0x44) +#define HOST_CSR_AP2CONN_AHB_HADDR (HOST_CSR_DRIVER_OWN_INFO + 0x4C) +#endif + +#if CFG_MTK_MCIF_WIFI_SUPPORT +/* Modem LP control */ +#define HOST_CSR_CONN_HIF_ON_MD_LPCTL_ADDR (HOST_CSR_DRIVER_OWN_INFO + 0x30) +/* Modem interrupt enable */ +#define HOST_CSR_CONN_HIF_ON_MD_IRQ_STAT_ADDR (HOST_CSR_DRIVER_OWN_INFO + 0x34) +/* Modem interrupt status */ +#define HOST_CSR_CONN_HIF_ON_MD_IRQ_ENA_ADDR (HOST_CSR_DRIVER_OWN_INFO + 0x38) +#endif + +/* +* AP2CONN_ADDR_MAP1[31..16] +* Mapping [0x180A_xxxx] to [ap2conn_addr_map0[15:0], xxxx] +* +* AP2CONN_ADDR_MAP0[15..0] +* Mapping [0x180D_xxxx] to [ap2conn_addr_map1[15:0], xxxx] +*/ +#define CONN_HIF_ON_ADDR_REMAP1 0x700C +#define AP2CONN_ADDR_MAP0 0xD0000 +#define AP2CONN_ADDR_MAP1 0xA0000 +/* +* AP2CONN_ADDR_MAP3[31..16] +* Mapping [0x180F_xxxx] to [ap2conn_addr_map3[15:0], xxxx] +* +* AP2CONN_ADDR_MAP2[15..0] +* Mapping [0x1804_xxxx] to [ap2conn_addr_map2[15:0], xxxx] +*/ +#define CONN_HIF_ON_ADDR_REMAP2 0x7010 +#define AP2CONN_ADDR_MAP2 0x40000 +#define AP2CONN_ADDR_MAP3 0xF0000 + +#endif /* __HOST_CSR_H__ */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/mt6632.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/mt6632.h new file mode 100644 index 0000000000000000000000000000000000000000..0621852cd6440a27d70002cf15f4b01efae79d66 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/mt6632.h @@ -0,0 +1,118 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/ + * MT6620_WIFI_DRIVER_V2_3/include/chips/mt6632.h#1 + */ + +/*! \file mt6632.h + * \brief This file contains the info of MT6632 + */ + +#ifndef _MT6632_H +#define _MT6632_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#define MT6632_CHIP_ID (0x6632) +#define MT6632_SW_SYNC0 WIFI_CFG_SW_SYNC0 +#define MT6632_SW_SYNC0_RDY_OFFSET WIFI_CFG_SYNC0_RDY_OFFSET +#define MT6632_PATCH_START_ADDR (0x000B4000) +#define MT6632_TOP_CFG_BASE (0x0000) +#define MT6632_TX_DESC_APPEND_LENGTH 44 +#define MT6632_RX_DESC_LENGTH 16 +#define MT6632_RX_INIT_EVENT_LENGTH 8 +#define MT6632_RX_EVENT_HDR_LENGTH 12 + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#endif /* _MT6632_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/mt7663.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/mt7663.h new file mode 100644 index 0000000000000000000000000000000000000000..ca5b457160ba62312d3a45efe335cb5919c8ad69 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/mt7663.h @@ -0,0 +1,124 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/ + * MT6620_WIFI_DRIVER_V2_3/include/chips/mt7668.h#1 + */ + +/*! \file mt7663.h + * \brief This file contains the info of MT7663 + */ + +#ifdef MT7663 + +#ifndef _MT7663_H +#define _MT7663_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#define MT7663_CHIP_ID (0x7663) +#define MT7663_SW_SYNC0 CONN_CFG_ON_CONN_ON_MISC_ADDR +#define MT7663_SW_SYNC0_RDY_OFFSET \ + CONN_CFG_ON_CONN_ON_MISC_DRV_FM_STAT_SYNC_SHFT +#define MT7663_PATCH_START_ADDR (0x000DC000) +#define MT7663_TOP_CFG_BASE CONN_CFG_BASE +#define MT7663_TX_DESC_APPEND_LENGTH 32 +#define MT7663_RX_DESC_LENGTH 16 +#define MT7663_RX_INIT_EVENT_LENGTH 8 +#define MT7663_RX_EVENT_HDR_LENGTH 12 + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#endif /* _MT7663_H */ + +#endif /* MT7663 */ + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/mt7668.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/mt7668.h new file mode 100644 index 0000000000000000000000000000000000000000..867cbc38601eb2c6d544f834de46772a4320f67a --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/mt7668.h @@ -0,0 +1,120 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/ + * MT6620_WIFI_DRIVER_V2_3/include/chips/mt7668.h#1 + */ + +/*! \file mt7668.h + * \brief This file contains the info of MT7668 + */ + +#ifndef _MT7668_H +#define _MT7668_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#define MT7668_CHIP_ID (0x7668) +#define MT7668_SW_SYNC0 WIFI_RGU_SW_SYNC0 +#define MT7668_SW_SYNC0_RDY_OFFSET WIFI_RGU_SYNC0_RDY_OFFSET +#define MT7668_PATCH_START_ADDR (0x000C8000) +#define MT7668_TOP_CFG_BASE (0x0000) +#define MT7668_TX_DESC_APPEND_LENGTH 44 +#define MT7668_RX_DESC_LENGTH 16 +#define MT7668_RX_INIT_EVENT_LENGTH 8 +#define MT7668_RX_EVENT_HDR_LENGTH 12 + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#endif /* _MT7668_H */ + + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/mt7915.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/mt7915.h new file mode 100644 index 0000000000000000000000000000000000000000..95f26ed56555aebf4db57566fb5a530ff54e62ea --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/mt7915.h @@ -0,0 +1,139 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ + +/*! \file mt7915.h +* \brief This file contains the info of MT7915 +*/ + +#ifdef MT7915 + +#ifndef _MT7915_H +#define _MT7915_H + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ +/*TODO: To use correct ID after FPGA uses correct ID @20170927*/ + +#define CONNAC2X_TOP_HCR 0x70010200 +#define CONNAC2X_TOP_FVR 0x70010204 +#define CONNAC2X_TOP_HVR 0x70010208 +#define CONNAC2x_CONN_CFG_ON_BASE 0x7C060000 +#define CONNAC2x_CONN_CFG_ON_CONN_ON_MISC_ADDR \ + (CONNAC2x_CONN_CFG_ON_BASE + 0xF0) +#define CONNAC2x_CONN_CFG_ON_CONN_ON_MISC_DRV_FM_STAT_SYNC_SHFT 0 + +/* + * 0 is MT7915 E1 RX padding rule + * 1 is 8 bytes RX padding rule for MT7915e2 and chips after MT7915e2 + */ +#define CONNAC2X_WFDMA_RX_CSO_OPTION BIT(8) + +#define MT7915_CHIP_ID (0x7915) +#define MT7915_SW_SYNC0 CONNAC2x_CONN_CFG_ON_CONN_ON_MISC_ADDR +#define MT7915_SW_SYNC0_RDY_OFFSET \ + CONNAC2x_CONN_CFG_ON_CONN_ON_MISC_DRV_FM_STAT_SYNC_SHFT +#define MT7915_PATCH_START_ADDR (0x00200000) +#define MT7915_TOP_CFG_BASE CONN_CFG_BASE +#define MT7915_TX_DESC_APPEND_LENGTH 44 +#define MT7915_RX_DESC_LENGTH 24 +#define MT7915_ARB_AC_MODE_ADDR (0x820e3020) + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +void mt7915_show_ple_info( + struct ADAPTER *prAdapter, + u_int8_t fgDumpTxd); +void mt7915_show_pse_info( + struct ADAPTER *prAdapter); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _MT7915_H */ +#endif /* MT7915 */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/mt7961.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/mt7961.h new file mode 100644 index 0000000000000000000000000000000000000000..d64b45ad4fc66c62be1241d0f7683e5917b8dfbb --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/mt7961.h @@ -0,0 +1,141 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ + +/*! \file mt7961.h +* \brief This file contains the info of MT7961 +*/ + +#ifdef MT7961 + +#ifndef _MT7961_H +#define _MT7961_H + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ +/*TODO: To use correct ID after FPGA uses correct ID @20170927*/ + +#define CONNAC2X_TOP_HCR 0x70010200 +#define CONNAC2X_TOP_HVR 0x70010204 +#define CONNAC2X_TOP_FVR 0x70010208 +#define CONNAC2x_CONN_CFG_ON_BASE 0x7C060000 +#define CONNAC2x_CONN_CFG_ON_CONN_ON_MISC_ADDR \ + (CONNAC2x_CONN_CFG_ON_BASE + 0xF0) +#define CONNAC2x_CONN_CFG_ON_CONN_ON_MISC_DRV_FM_STAT_SYNC_SHFT 0 + +#define MT7961_CHIP_ID (0x7961) +#define MT7961_SW_SYNC0 CONNAC2x_CONN_CFG_ON_CONN_ON_MISC_ADDR +#define MT7961_SW_SYNC0_RDY_OFFSET \ + CONNAC2x_CONN_CFG_ON_CONN_ON_MISC_DRV_FM_STAT_SYNC_SHFT +#define MT7961_PATCH_START_ADDR (0x00900000) +#define MT7961_TOP_CFG_BASE CONN_CFG_BASE +#define MT7961_TX_DESC_APPEND_LENGTH 32 +#define MT7961_RX_DESC_LENGTH 24 +#define MT7961_ARB_AC_MODE_ADDR (0x820E315C) + +/*------------------------------------------------------------------------------ + * MACRO for WTBL INFO GET + *------------------------------------------------------------------------------ + */ + +#define MT7961_WIFI_LWTBL_BASE 0x820d4200 +#define MT7961_WIFI_UWTBL_BASE 0x820c4094 + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +void mt7961_show_ple_info( + struct ADAPTER *prAdapter, + u_int8_t fgDumpTxd); +void mt7961_show_pse_info( + struct ADAPTER *prAdapter); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _MT7961_H */ + +#endif /* MT7961 */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/mt_dmac.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/mt_dmac.h new file mode 100644 index 0000000000000000000000000000000000000000..f2a20c6faf584dd3298d2d131983f1e4951c1322 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/mt_dmac.h @@ -0,0 +1,362 @@ +/* + *************************************************************************** + * Ralink Tech Inc. + * 4F, No. 2 Technology 5th Rd. + * Science-based Industrial Park + * Hsin-chu, Taiwan, R.O.C. + * + * (c) Copyright 2002-2004, Ralink Technology, Inc. + * + * All rights reserved. Ralink's source code is an unpublished work and the + * use of a copyright notice does not imply otherwise. This source code + * contains confidential trade secret material of Ralink Tech. Any attemp + * or participation in deciphering, decoding, reverse engineering or in any + * way altering the source code is stricitly prohibited, unless the prior + * written consent of Ralink Technology, Inc. is obtained. + *************************************************************************** + + Module Name: + mt_dmac.h + + Abstract: + Ralink Wireless Chip MAC related definition & structures + + Revision History: + Who When What + -------- ---------- ------------------------------------- +*/ + +#ifndef __MT_DMAC_H__ +#define __MT_DMAC_H__ + +struct TMAC_TXD_0 { + /* DWORD 0 */ + uint32_t TxByteCount : 16; + uint32_t EthTypeOffset : 7; + uint32_t IpChkSumOffload : 1; + uint32_t UdpTcpChkSumOffload : 1; + uint32_t rsv_25 : 1; + uint32_t q_idx : 5; + uint32_t p_idx : 1; /* P_IDX_XXX */ +}; + +/* TMAC_TXD_0.PIdx */ +#define P_IDX_LMAC 0 +#define P_IDX_MCU 1 +#define P_IDX_PLE_CTRL_PSE_PORT_3 3 + +#define UMAC_PLE_CTRL_P3_Q_0X1E 0x1e +#define UMAC_PLE_CTRL_P3_Q_0X1F 0x1f + +/* TMAC_TXD_0.QIdx */ +#define TxQ_IDX_AC0 0x00 +#define TxQ_IDX_AC1 0x01 +#define TxQ_IDX_AC2 0x02 +#define TxQ_IDX_AC3 0x03 +#define TxQ_IDX_AC10 0x04 +#define TxQ_IDX_AC11 0x05 +#define TxQ_IDX_AC12 0x06 +#define TxQ_IDX_AC13 0x07 +#define TxQ_IDX_AC20 0x08 +#define TxQ_IDX_AC21 0x09 +#define TxQ_IDX_AC22 0x0a +#define TxQ_IDX_AC23 0x0b +#define TxQ_IDX_AC30 0x0c +#define TxQ_IDX_AC31 0x0d +#define TxQ_IDX_AC32 0x0e +#define TxQ_IDX_AC33 0x0f + +#define TxQ_IDX_ALTX0 0x10 +#define TxQ_IDX_BMC0 0x11 +#define TxQ_IDX_BCN0 0x12 +#define TxQ_IDX_PSMP0 0x13 + +#define TxQ_IDX_ALTX1 0x14 +#define TxQ_IDX_BMC1 0x15 +#define TxQ_IDX_BCN1 0x16 +#define TxQ_IDX_PSMP1 0x17 + +#define TxQ_IDX_MCU0 0x00 +#define TxQ_IDX_MCU1 0x01 +#define TxQ_IDX_MCU2 0x02 +#define TxQ_IDX_MCU3 0x03 +#define TxQ_IDX_MCU_PDA 0x1e + + +/* TMAC_TXD_0.p_idx + TMAC_TXD_0.q_idx */ +#define PQ_IDX_WMM0_AC0 ((P_IDX_LMAC << 5) | (TxQ_IDX_AC0)) +#define PQ_IDX_WMM0_AC1 ((P_IDX_LMAC << 5) | (TxQ_IDX_AC1)) +#define PQ_IDX_WMM0_AC2 ((P_IDX_LMAC << 5) | (TxQ_IDX_AC2)) +#define PQ_IDX_WMM0_AC3 ((P_IDX_LMAC << 5) | (TxQ_IDX_AC3)) +#define PQ_IDX_WMM1_AC0 ((P_IDX_LMAC << 5) | (TxQ_IDX_AC10)) +#define PQ_IDX_WMM1_AC1 ((P_IDX_LMAC << 5) | (TxQ_IDX_AC11)) +#define PQ_IDX_WMM1_AC2 ((P_IDX_LMAC << 5) | (TxQ_IDX_AC12)) +#define PQ_IDX_WMM1_AC3 ((P_IDX_LMAC << 5) | (TxQ_IDX_AC13)) +#define PQ_IDX_WMM2_AC0 ((P_IDX_LMAC << 5) | (TxQ_IDX_AC20)) +#define PQ_IDX_WMM2_AC1 ((P_IDX_LMAC << 5) | (TxQ_IDX_AC21)) +#define PQ_IDX_WMM2_AC2 ((P_IDX_LMAC << 5) | (TxQ_IDX_AC22)) +#define PQ_IDX_WMM2_AC3 ((P_IDX_LMAC << 5) | (TxQ_IDX_AC23)) +#define PQ_IDX_WMM3_AC0 ((P_IDX_LMAC << 5) | (TxQ_IDX_AC30)) +#define PQ_IDX_WMM3_AC1 ((P_IDX_LMAC << 5) | (TxQ_IDX_AC31)) +#define PQ_IDX_WMM3_AC2 ((P_IDX_LMAC << 5) | (TxQ_IDX_AC32)) +#define PQ_IDX_WMM3_AC3 ((P_IDX_LMAC << 5) | (TxQ_IDX_AC33)) + +#define PQ_IDX_ALTX0 ((P_IDX_LMAC << 5) | (TxQ_IDX_ALTX0)) +#define PQ_IDX_BMC0 ((P_IDX_LMAC << 5) | (TxQ_IDX_ALTX0)) +#define PQ_IDX_BCN0 ((P_IDX_LMAC << 5) | (TxQ_IDX_ALTX0)) +#define PQ_IDX_PSMP0 ((P_IDX_LMAC << 5) | (TxQ_IDX_ALTX0)) + +#define PQ_IDX_MCU_RQ0 ((P_IDX_MCU << 5) | (TxQ_IDX_MCU0)) +#define PQ_IDX_MCU_RQ1 ((P_IDX_MCU << 5) | (TxQ_IDX_MCU1)) +#define PQ_IDX_MCU_RQ2 ((P_IDX_MCU << 5) | (TxQ_IDX_MCU2)) +#define PQ_IDX_MCU_RQ3 ((P_IDX_MCU << 5) | (TxQ_IDX_MCU3)) + +struct TMAC_TXD_1 { + /* DWORD 1 */ + uint32_t wlan_idx : 8; + uint32_t hdr_info : 5; /* in unit of WORD(2 bytes) */ + uint32_t hdr_format : 2; /* TMI_HDR_FT_XXX */ + uint32_t ft : 1; /* TMI_HDR_FT_XXX */ + uint32_t txd_len : 1; /* TMI_FT_XXXX */ + uint32_t hdr_pad : 2; + uint32_t UNxV : 1; + uint32_t amsdu : 1; + uint32_t tid : 3; + uint32_t pkt_ft : 2; + uint32_t OwnMacAddr : 6; +}; + +/* TMAC_TXD_1.pkt_ft */ +#define TMI_PKT_FT_HIF_CT 0 /* Cut-through */ +#define TMI_PKT_FT_HIF_SF 1 /* Store & forward */ +#define TMI_PKT_FT_HIF_CMD 2 /* Command frame to N9/CR4 */ +#define TMI_PKT_FT_HIF_FW 3 /* Firmware frame to PDA */ + +#define TMI_PKT_FT_MCU_CT 0 /* N9 Cut-through */ +#define TMI_PKT_FT_MCU_FW 3 /* N9 to UMAC/LMAC */ + +/* TMAC_TXD_1.hdr_format */ +#define TMI_HDR_FT_NON_80211 0x0 +#define TMI_HDR_FT_CMD 0x1 +#define TMI_HDR_FT_NOR_80211 0x2 +#define TMI_HDR_FT_ENH_80211 0x3 + +/* if TMAC_TXD_1.hdr_format == HDR_FORMAT_NON_80211 */ +#define TMI_HDR_INFO_0_BIT_MRD 0 +#define TMI_HDR_INFO_0_BIT_EOSP 1 +#define TMI_HDR_INFO_0_BIT_RMVL 2 +#define TMI_HDR_INFO_0_BIT_VLAN 3 +#define TMI_HDR_INFO_0_BIT_ETYP 4 +#define TMI_HDR_INFO_0_VAL(_mrd, _eosp, _rmvl, _vlan, _etyp) \ + ((((_mrd) ? 1 : 0) << TMI_HDR_INFO_0_BIT_MRD) | \ + (((_eosp) ? 1 : 0) << TMI_HDR_INFO_0_BIT_EOSP) |\ + (((_rmvl) ? 1 : 0) << TMI_HDR_INFO_0_BIT_RMVL) |\ + (((_vlan) ? 1 : 0) << TMI_HDR_INFO_0_BIT_VLAN) |\ + (((_etyp) ? 1 : 0) << TMI_HDR_INFO_0_BIT_ETYP)) + + +/* if TMAC_TXD_1.hdr_format == HDR_FORMAT_CMD */ +#define TMI_HDR_INFO_1_MASK_RSV (0x1f) +#define TMI_HDR_INFO_1_VAL 0 + +/* if TMAC_TXD_1.hdr_format == HDR_FORMAT_NOR_80211 */ +#define TMI_HDR_INFO_2_MASK_LEN (0x1f) +#define TMI_HDR_INFO_2_VAL(_len) (_len >> 1) + +/* if TMAC_TXD_1.hdr_format == HDR_FORMAT_ENH_80211 */ +#define TMI_HDR_INFO_3_BIT_EOSP 1 +#define TMI_HDR_INFO_3_BIT_AMS 2 +#define TMI_HDR_INFO_3_VAL(_eosp, _ams) \ + ((((_eosp) ? 1 : 0) << TMI_HDR_INFO_3_BIT_EOSP) | \ + (((_ams) ? 1 : 0) << TMI_HDR_INFO_3_BIT_AMS)) + +/* TMAC_TXD_1.TxDFmt */ +#define TMI_FT_SHORT 0 +#define TMI_FT_LONG 1 + +/* TMAC_TXD_1.HdrPad */ +#define TMI_HDR_PAD_BIT_MODE 1 +#define TMI_HDR_PAD_MODE_TAIL 0 +#define TMI_HDR_PAD_MODE_HEAD 1 +#define TMI_HDR_PAD_BIT_LEN 0 +#define TMI_HDR_PAD_MASK_LEN 0x3 + +struct TMAC_TXD_2 { + /* DWORD 2 */ + uint32_t sub_type : 4; + uint32_t frm_type : 2; + uint32_t ndp : 1; + uint32_t ndpa : 1; + uint32_t sounding : 1; + uint32_t rts : 1; + uint32_t bc_mc_pkt : 1; + uint32_t bip : 1; + uint32_t duration : 1; + uint32_t htc_vld : 1; + uint32_t frag : 2; + uint32_t max_tx_time : 8; + uint32_t pwr_offset : 5; + uint32_t ba_disable : 1; + uint32_t timing_measure : 1; + uint32_t fix_rate : 1; +}; + +struct TMAC_TXD_3 { + /* DWORD 3 */ + uint32_t no_ack : 1; + uint32_t protect_frm : 1; + uint32_t rsv_2_5 : 4; + uint32_t tx_cnt : 5; + uint32_t remain_tx_cnt : 5; + uint32_t sn : 12; + uint32_t rsv_28_29 : 2; + uint32_t pn_vld : 1; + uint32_t sn_vld : 1; +}; + +struct TMAC_TXD_4 { + /* DWORD 4 */ + uint32_t pn_low; +}; + +struct TMAC_TXD_5 { + /* DWORD 5 */ + uint32_t pid:8; + uint32_t tx_status_fmt:1; + uint32_t tx_status_2_mcu:1; + uint32_t tx_status_2_host:1; + uint32_t da_select:1; + uint32_t rsv_12:1; + uint32_t pwr_mgmt:1; + uint32_t rsv_14_15:2; + uint32_t pn_high:16; +}; + +/* TMAC_TXD_5.da_select */ +#define TMI_DAS_FROM_MPDU 0 +#define TMI_DAS_FROM_WTBL 1 + +/* TMAC_TXD_5.bar_sn_ctrl */ +#define TMI_BSN_CFG_BY_HW 0 +#define TMI_BSN_CFG_BY_SW 1 + +/* TMAC_TXD_5.pwr_mgmt */ +#define TMI_PM_BIT_CFG_BY_HW 0 +#define TMI_PM_BIT_CFG_BY_SW 1 + +struct TMAC_TXD_6 { + /* DWORD 6 */ + uint32_t bw:3; + uint32_t dyn_bw:1; + uint32_t ant_id:12; + uint32_t tx_rate:12; + uint32_t TxBF:1; + uint32_t ldpc:1; + uint32_t gi:1; + uint32_t fix_rate_mode:1; +}; + +/* TMAC_TXD_6.fix_rate_mode */ +#define TMI_FIX_RATE_BY_TXD 0 +#define TMI_FIX_RATE_BY_CR 1 + +#define TMI_TX_RATE_BIT_STBC 11 +#define TMI_TX_RATE_BIT_NSS 9 +#define TMI_TX_RATE_MASK_NSS 0x3 + +#define TMI_TX_RATE_BIT_MODE 6 +#define TMI_TX_RATE_MASK_MODE 0x7 +#define TMI_TX_RATE_MODE_CCK 0 +#define TMI_TX_RATE_MODE_OFDM 1 +#define TMI_TX_RATE_MODE_HTMIX 2 +#define TMI_TX_RATE_MODE_HTGF 3 +#define TMI_TX_RATE_MODE_VHT 4 + +#define SHORT_PREAMBLE 0 +#define LONG_PREAMBLE 1 + +#define TMI_TX_RATE_BIT_MCS 0 +#define TMI_TX_RATE_MASK_MCS 0x3f +#define TMI_TX_RATE_CCK_1M_LP 0 +#define TMI_TX_RATE_CCK_2M_LP 1 +#define TMI_TX_RATE_CCK_5M_LP 2 +#define TMI_TX_RATE_CCK_11M_LP 3 + +#define TMI_TX_RATE_CCK_2M_SP 5 +#define TMI_TX_RATE_CCK_5M_SP 6 +#define TMI_TX_RATE_CCK_11M_SP 7 + +#define TMI_TX_RATE_OFDM_6M 11 +#define TMI_TX_RATE_OFDM_9M 15 +#define TMI_TX_RATE_OFDM_12M 10 +#define TMI_TX_RATE_OFDM_18M 14 +#define TMI_TX_RATE_OFDM_24M 9 +#define TMI_TX_RATE_OFDM_36M 13 +#define TMI_TX_RATE_OFDM_48M 8 +#define TMI_TX_RATE_OFDM_54M 12 + +#define TMI_TX_RATE_HT_MCS0 0 +#define TMI_TX_RATE_HT_MCS1 1 +#define TMI_TX_RATE_HT_MCS2 2 +#define TMI_TX_RATE_HT_MCS3 3 +#define TMI_TX_RATE_HT_MCS4 4 +#define TMI_TX_RATE_HT_MCS5 5 +#define TMI_TX_RATE_HT_MCS6 6 +#define TMI_TX_RATE_HT_MCS7 7 +#define TMI_TX_RATE_HT_MCS8 8 +#define TMI_TX_RATE_HT_MCS9 9 +#define TMI_TX_RATE_HT_MCS10 10 +#define TMI_TX_RATE_HT_MCS11 11 +#define TMI_TX_RATE_HT_MCS12 12 +#define TMI_TX_RATE_HT_MCS13 13 +#define TMI_TX_RATE_HT_MCS14 14 +#define TMI_TX_RATE_HT_MCS15 15 +#define TMI_TX_RATE_HT_MCS16 16 +#define TMI_TX_RATE_HT_MCS17 17 +#define TMI_TX_RATE_HT_MCS18 18 +#define TMI_TX_RATE_HT_MCS19 19 +#define TMI_TX_RATE_HT_MCS20 20 +#define TMI_TX_RATE_HT_MCS21 21 +#define TMI_TX_RATE_HT_MCS22 22 +#define TMI_TX_RATE_HT_MCS23 23 + +#define TMI_TX_RATE_HT_MCS32 32 + +#define TMI_TX_RATE_VHT_MCS0 0 +#define TMI_TX_RATE_VHT_MCS1 1 +#define TMI_TX_RATE_VHT_MCS2 2 +#define TMI_TX_RATE_VHT_MCS3 3 +#define TMI_TX_RATE_VHT_MCS4 4 +#define TMI_TX_RATE_VHT_MCS5 5 +#define TMI_TX_RATE_VHT_MCS6 6 +#define TMI_TX_RATE_VHT_MCS7 7 +#define TMI_TX_RATE_VHT_MCS8 8 +#define TMI_TX_RATE_VHT_MCS9 9 + +struct TMAC_TXD_7 { + uint32_t sw_tx_time:10; + uint32_t rsv_10:1; + uint32_t spe_idx:5; + uint32_t pse_fid:14; + uint32_t hw_amsdu_cap:1; + uint32_t hif_err:1; +}; + +struct TMAC_TXD_L { + struct TMAC_TXD_0 TxD0; + struct TMAC_TXD_1 TxD1; + struct TMAC_TXD_2 TxD2; + struct TMAC_TXD_3 TxD3; + struct TMAC_TXD_4 TxD4; + struct TMAC_TXD_5 TxD5; + struct TMAC_TXD_6 TxD6; + struct TMAC_TXD_7 TxD7; +}; + +struct TMAC_TXD_S { + struct TMAC_TXD_0 TxD0; + struct TMAC_TXD_1 TxD1; + struct TMAC_TXD_7 TxD7; +}; + +#endif /* __MT_DMAC_H__ */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/pse.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/pse.h new file mode 100644 index 0000000000000000000000000000000000000000..21a11ab042f2e5daaf6f746406d5623dfe082320 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/pse.h @@ -0,0 +1,281 @@ +/* + *************************************************************************** + * Ralink Tech Inc. + * 4F, No. 2 Technology 5th Rd. + * Science-based Industrial Park + * Hsin-chu, Taiwan, R.O.C. + * + * (c) Copyright 2002-2004, Ralink Technology, Inc. + * + * All rights reserved. Ralink's source code is an unpublished work and the + * use of a copyright notice does not imply otherwise. This source code + * contains confidential trade secret material of Ralink Tech. Any attemp + * or participation in deciphering, decoding, reverse engineering or in any + * way altering the source code is stricitly prohibited, unless the prior + * written consent of Ralink Technology, Inc. is obtained. + *************************************************************************** + + Module Name: + pse.h + + Abstract: + Ralink Wireless Chip MAC related definition & structures + + Revision History: + Who When What + -------- ---------- -------------------------------------- +*/ + + +#ifndef __PSE_H__ +#define __PSE_H__ + +#define PSE_BASE 0xc000 + +/* PSE Reset Control Register */ +#define PSE_RESET (PSE_BASE + 0x00) +#define PSE_ALL_RST (1 << 0) +#define PSE_LOGICAL_RST (1 << 1) +#define PSE_INIT_DONE (1 << 2) +#define GET_PSE_INIT_DONE(p) (((p) & PSE_INIT_DONE) >> 2) + +/* PSE Buffer Control Register */ +#define PSE_PBUF_CTRL (PSE_BASE + 0x14) +#define PSE_TOTAL_PAGE_NUM_MASK (0xfff) +#define PSE_GET_TOTAL_PAGE_NUM(p) (((p) & 0xfff)) +#define PSE_TOTAL_PAGE_CFG_MASK (0xf << 16) +#define PSE_GET_TOTAL_PAGE_CFG(p) (((p) & PSE_TOTAL_PAGE_CFG_MASK) >> 16) + +#define PSE_PBUF_OFFSET_MASK (0xf << 20) +#define GET_PSE_PBUF_OFFSET(p) (((p) & PSE_PBUF_OFFSET_MASK) >> 20) + +#define PSE_GC (PSE_BASE) +#define PSE_INT_STS (PSE_BASE + 0x24) +#define PSE_INT_ERR_STS (PSE_BASE + 0x28) + +/* Queue Empty */ +#define PSE_QUEUE_EMPTY (PSE_BASE + 0xb0) +/* Queue Empty Mask */ +#define PSE_QUEUE_EMPTY_MASK (PSE_BASE + 0xb4) + +/* Page Flow Control */ +#define PSE_FREEPG_CNT (PSE_BASE + 0x100) + +#define PSE_FREEPG_HEAD_TAIL (PSE_BASE + 0x104) + +#define PSE_ENQ_0 (PSE_BASE + 0x60) +#define PSE_DEQ_0 (PSE_BASE + 0x80) +#define PSE_ENDEQ_OFFSET 0x4 +#define PSE_ENDEQ_NUM 3 + +#define PSE_PG_HIF0_GROUP (PSE_BASE + 0x110) +#define PSE_HIF0_PG_INFO (PSE_BASE + 0x114) +#define PSE_PG_HIF1_GROUP (PSE_BASE + 0x118) +#define PSE_HIF1_PG_INFO (PSE_BASE + 0x11c) + +#define PSE_PG_CPU_GROUP (PSE_BASE + 0x150) +#define PSE_CPU_PG_INFO (PSE_BASE + 0x154) + +#define PSE_PG_LMAC0_GROUP (PSE_BASE + 0x170) +#define PSE_LMAC0_PG_INFO (PSE_BASE + 0x174) +#define PSE_PG_LMAC1_GROUP (PSE_BASE + 0x178) +#define PSE_LMAC1_PG_INFO (PSE_BASE + 0x17c) +#define PSE_PG_LMAC2_GROUP (PSE_BASE + 0x180) +#define PSE_LMAC2_PG_INFO (PSE_BASE + 0x184) +#define PSE_PG_PLE_GROUP (PSE_BASE + 0x190) +#define PSE_PLE_PG_INFO (PSE_BASE + 0x194) + +#define PSE_RL_BUF_CTRL_0 (PSE_BASE + 0x1a0) +#define PSE_RL_BUF_CTRL_1 (PSE_BASE + 0x1a4) + +/* Indirect path for read/write */ +#define PSE_FL_QUE_CTRL_0 (PSE_BASE + 0x1b0) +#define PSE_FL_QUE_CTRL_1 (PSE_BASE + 0x1b4) +#define PSE_FL_QUE_CTRL_2 (PSE_BASE + 0x1b8) +#define PSE_FL_QUE_CTRL_3 (PSE_BASE + 0x1bc) +#define PSE_PL_QUE_CTRL_0 (PSE_BASE + 0x1c0) + +/* PSE spare dummy CR */ +#define PSE_SPARE_DUMMY_CR1 (PSE_BASE + 0x1e4) +#define PSE_SPARE_DUMMY_CR2 (PSE_BASE + 0x1e8) +#define PSE_SPARE_DUMMY_CR3 (PSE_BASE + 0x2e8) +#define PSE_SPARE_DUMMY_CR4 (PSE_BASE + 0x2ec) + +#define PSE_PEEK_CR_0 (PSE_BASE + 0x3d0) +#define PSE_PEEK_CR_OFFSET 0x4 +#define PSE_PEEK_CR_NUM 9 + +/* CPU Interface Get First Frame ID Control Regitser */ +#define C_GFF (PSE_BASE + 0x24) +#define GET_FIRST_FID_MASK (0xfff) +#define GET_FIRST_FID(p) (((p) & GET_FIRST_FID_MASK)) +#define GET_QID_MASK (0x1f << 16) +#define SET_GET_QID(p) (((p) & 0x1f) << 16) +#define GET_QID(p) (((p) & GET_QID_MASK) >> 16) +#define GET_PID_MASK (0x3 << 21) +#define SET_GET_PID(p) (((p) & 0x3) << 21) +#define GET_PID(p) (((p) & GET_PID_MASK) >> 21) +#define GET_RVSE_MASK (1 << 23) +#define SET_GET_RVSE(p) (((p) & 0x1) << 23) +#define GET_RVSE(p) (((p) & GET_RVSE_MASK) >> 23) + +/* CPU Interface Get Frame ID Control Register */ +#define C_GF (PSE_BASE + 0x28) +#define GET_RETURN_FID_MASK (0xfff) +#define GET_RETURN_FID(p) (((p) & GET_RETURN_FID_MASK)) +#define CURR_FID_MASK (0xfff << 16) +#define SET_CURR_FID(p) (((p) & 0xfff) << 16) +#define GET_CURR_FID(p) (((p) & CURR_FID_MASK) >> 16) +#define GET_PREV_MASK (1 << 28) +#define SET_GET_PREV(p) (((p) & 0x1) << 28) +#define GET_PREV(p) (((p) & GET_PREV_MASK) >> 28) +#define GET_AUTO_MASK (1 << 29) +#define SET_GET_AUTO(p) (((p) & 0x1) >> 29) +#define GET_AUTO(p) (((p) & GET_AUTO_MASK) >> 29) + +/* Get Queue Length Control Register */ +#define GQC (PSE_BASE + 0x118) +#define QLEN_RETURN_VALUE_MASK (0xfff) +#define GET_QLEN_RETURN_VALUE(p) (((p) & QLEN_RETURN_VALUE_MASK)) +#define GET_QLEN_QID_MASK (0x1f << 16) +#define SET_GET_QLEN_QID(p) (((p) & 0x1f) << 16) +#define GET_QLEN_QID(p) (((p) & GET_QLEN_QID_MASK) >> 16) +#define GET_QLEN_PID_MASK (0x3 << 21) +#define SET_GET_QLEN_PID(p) (((p) & 0x3) << 21) +#define GET_QLEN_PID(p) (((p) & GET_QLEN_PID_MASK) >> 21) +#define QLEN_IN_PAGE (1 << 23) +#define GET_QLEN_IN_PAGE(p) (((p) & QLEN_IN_PAGE) >> 23) + +/* Flow Control P0 Control Register */ +#define FC_P0 (PSE_BASE + 0x120) +#define MIN_RSRV_P0_MASK (0xfff) +#define MIN_RSRV_P0(p) (((p) & 0xfff)) +#define GET_MIN_RSRV_P0(p) (((p) & MIN_RSRV_P0_MASK)) +#define MAX_QUOTA_P0_MASK (0xfff << 16) +#define MAX_QUOTA_P0(p) (((p) & 0xfff) << 16) +#define GET_MAX_QUOTA_P0(p) (((p) & MAX_QUOTA_P0_MASK) >> 16) + +/* Flow Control P1 Control Register */ +#define FC_P1 (PSE_BASE + 0x124) +#define MIN_RSRV_P1_MASK (0xfff) +#define MIN_RSRV_P1(p) (((p) & 0xfff)) +#define GET_MIN_RSRV_P1(p) (((p) & MIN_RSRV_P1_MASK)) +#define MAX_QUOTA_P1_MASK (0xfff << 16) +#define MAX_QUOTA_P1(p) (((p) & 0xfff) << 16) +#define GET_MAX_QUOTA_P1(p) (((p) & MAX_QUOTA_P1_MASK) >> 16) + +/* Flow Control P2_RQ0 Control Register */ +#define FC_P2Q0 (PSE_BASE + 0x128) +#define MIN_RSRV_P2_RQ0_MASK (0xfff) +#define MIN_RSRV_P2_RQ0(p) (((p) & 0xfff)) +#define GET_MIN_RSRV_P2_RQ0(p) (((p) & MIN_RSRV_P2_RQ0_MASK)) +#define MAX_QUOTA_P2_RQ0_MASK (0xfff << 16) +#define MAX_QUOTA_P2_RQ0(p) (((p) & 0xfff) << 16) +#define GET_MAX_QUOTA_P2_RQ0(p) (((p) & MAX_QUOTA_P2_RQ0_MASK) >> 16) + +/* Flow Control P2_RQ1 Control Register */ +#define FC_P2Q1 (PSE_BASE + 0x12c) +#define MIN_RSRV_P2_RQ1_MASK (0xfff) +#define MIN_RSRV_P2_RQ1(p) (((p) & 0xfff)) +#define GET_MIN_RSRV_P2_RQ1(p) (((p) & MIN_RSRV_P2_RQ1_MASK)) +#define MAX_QUOTA_P2_RQ1_MASK (0xfff << 16) +#define MAX_QUOTA_P2_RQ1(p) (((p) & 0xfff) << 16) +#define GET_MAX_QUOTA_P2_RQ1(p) (((p) & MAX_QUOTA_P2_RQ1_MASK) >> 16) + +/* Flow Control P2_RQ2 Control Register */ +#define FC_P2Q2 (PSE_BASE + 0x130) +#define MIN_RSRV_P2_RQ2_MASK (0xfff) +#define MIN_RSRV_P2_RQ2(p) (((p) & 0xfff)) +#define GET_MIN_RSRV_P2_RQ2(p) (((p) & MIN_RSRV_P2_RQ2_MASK)) +#define MAX_QUOTA_P2_RQ2_MASK (0xfff << 16) +#define MAX_QUOTA_P2_RQ2(p) (((p) & 0xfff) << 16) +#define GET_MAX_QUOTA_P2_RQ2(p) (((p) & MAX_QUOTA_P2_RQ2_MASK) >> 16) + +/* Flow Control Free for All and Free Page Counter Register */ +#define FC_FFC (PSE_BASE + 0x134) +#define FREE_PAGE_CNT_MASK (0xfff) +#define GET_FREE_PAGE_CNT(p) (((p) & FREE_PAGE_CNT_MASK)) +#define FFA_CNT_MASK (0xfff << 16) +#define GET_FFA_CNT(p) (((p) & FFA_CNT_MASK) >> 16) + +/* Flow Control Reserve from FFA priority Control Register */ +#define FC_FRP (PSE_BASE + 0x138) +#define RSRV_PRI_P0_MASK (0x7) +#define RSRV_PRI_P0(p) (((p) & 0x7)) +#define GET_RSRV_PRI_P0(p) (((p) & RSRV_PRI_P0_MASK)) +#define RSRV_PRI_P1_MASK (0x7 << 3) +#define RSRV_PRI_P1(p) (((p) & 0x7) << 3) +#define GET_RSRV_PRI_P1(p) (((p) & RSRV_PRI_P1_MASK) >> 3) +#define RSRV_PRI_P2_RQ0_MASK (0x7 << 6) +#define RSRV_PRI_P2_RQ0(p) (((p) & 0x7) << 6) +#define GET_RSRV_PRI_P2_RQ0(p) (((p) & RSRV_PRI_P2_RQ0_MASK) >> 6) +#define RSRV_PRI_P2_RQ1_MASK (0x7 << 9) +#define RSRV_PRI_P2_RQ1(p) (((p) & 0x7) << 9) +#define GET_RSRV_PRI_P2_RQ1(p) (((p) & RSRV_PRI_P2_RQ1_MASK) >> 9) +#define RSRV_PRI_P2_RQ2_MASK (0x7 << 12) +#define RSRV_PRI_P2_RQ2(p) (((p) & 0x7) << 12) +#define GET_RSRV_PRI_P2_RQ2(p) (((p) & RSRV_PRI_P2_RQ2_MASK) >> 12) + +/* Flow Control P0 and P1 Reserve Counter Register */ +#define FC_RP0P1 (PSE_BASE + 0x13c) +#define RSRV_CNT_P0_MASK (0xfff) +#define RSRV_CNT_P0(p) (((p) & 0xfff)) +#define GET_RSRV_CNT_P0(p) (((p) & RSRV_CNT_P0_MASK)) +#define RSRV_CNT_P1_MASK (0xfff << 16) +#define RSRV_CNT_P1(p) (((p) & 0xfff) << 16) +#define GET_RSRV_CNT_P1(p) (((p) & RSRV_CNT_P1_MASK) >> 16) + +/* Flow Control P2_RQ0 and P2_RQ1 Reserve Counter Register */ +#define FC_RP2Q0Q1 (PSE_BASE + 0x140) +#define RSRV_CNT_P2_RQ0_MASK (0xfff) +#define RSRV_CNT_P2_RQ0(p) (((p) & 0xfff)) +#define GET_RSRV_CNT_P2_RQ0(p) (((p) & RSRV_CNT_P2_RQ0_MASK)) +#define RSRV_CNT_P2_RQ1_MASK (0xfff << 16) +#define RSRV_CNT_P2_RQ1(p) (((p) & 0xfff) << 16) +#define GET_RSRV_CNT_P2_RQ1(p) (((p) & RSRV_CNT_P2_RQ1_MASK) >> 16) + +/* Flow Control P2_RQ2 Reserve Counter Register */ +#define FC_RP2Q2 (PSE_BASE + 0x144) +#define RSRV_CNT_P2_RQ2_MASK (0xfff) +#define RSRV_CNT_P2_RQ2(p) (((p) & 0xfff)) +#define GET_RSRV_CNT_P2_RQ2(p) (((p) & RSRV_CNT_P2_RQ2_MASK)) + +/* Flow Control P0 and P1 Source Counter Register */ +#define FC_SP0P1 (PSE_BASE + 0x148) +#define SRC_CNT_P0_MASK (0xfff) +#define GET_SRC_CNT_P0(p) (((p) & SRC_CNT_P0_MASK)) +#define SRC_CNT_P1_MASK (0xfff << 16) +#define GET_SRC_CNT_P1(p) (((p) & SRC_CNT_P1_MASK) >> 16) + +/* FLow Control P2_RQ0 and P2_RQ1 Source Counter Register */ +#define FC_SP2Q0Q1 (PSE_BASE + 0x14c) +#define SRC_CNT_P2_RQ0_MASK (0xfff) +#define GET_SRC_CNT_P2_RQ0(p) (((p) & SRC_CNT_P2_RQ0_MASK)) +#define SRC_CNT_P2_RQ1_MASK (0xfff << 16) +#define GET_SRC_CNT_P2_RQ1(p) (((p) & SRC_CNT_P2_RQ1_MASK) >> 16) + +/* Flow Control P2_RQ2 Source Counter Register */ +#define FC_SP2Q2 (PSE_BASE + 0x150) +#define SRC_CNT_P2_RQ2_MASK (0xfff) +#define GET_SRC_CNT_P2_RQ2(p) (((p) & 0xfff)) + +#define PSE_RTA (PSE_BASE + 0x194) +#define PSE_RTA_RD_RULE_QID_MASK (0x1f) +#define PSE_RTA_RD_RULE_QID(p) (((p) & 0x1f)) +#define GET_PSE_RTA_RD_RULE_QID(p) (((p) & PSE_RTA_RD_RULE_QID_MASK)) +#define PSE_RTA_RD_RULE_PID_MASK (0x3 << 5) +#define PSE_RTA_RD_RULE_PID(p) (((p) & 0x3) << 5) +#define GET_PSE_RTA_RD_RULE_PID(p) (((p) & PSE_RTA_RD_RULE_PID_MASK) >> 5) +#define PSE_RTA_RD_RULE_F (1 << 7) +#define GET_PSE_RTA_RD_RULE_F(p) (((p) & PSE_RTA_RD_RULE_F) >> 7) +#define PSE_RTA_TAG_MASK (0xff << 8) +#define PSE_RTA_TAG(p) (((p) & 0xff) << 8) +#define GET_PSE_RTA_TAG(p) (((p) & PSE_RTA_TAG_MASK) >> 8) +#define PSE_RTA_RD_RW (1 << 16) +#define PSE_RTA_RD_KICK_BUSY (1 << 31) +#define GET_PSE_RTA_RD_KICK_BUSY(p) (((p) & PSE_RTA_RD_KICK_BUSY) >> 31) + +#define PSE_PAYLOAD_BASE 0xB0000000 + +#endif /* _PSE */ + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/soc3_0.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/soc3_0.h new file mode 100644 index 0000000000000000000000000000000000000000..677c57b66cfcbfec5cedba40b13f9a621c15f5cb --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/soc3_0.h @@ -0,0 +1,394 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ + +/*! \file soc3_0.h +* \brief This file contains the info of soc3_0 +*/ + +#ifdef SOC3_0 + +#ifndef _SOC3_0_H +#define _SOC3_0_H +#if (CFG_SUPPORT_CONNINFRA == 1) +#include "conninfra.h" +#endif +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ +#define CONNAC2X_TOP_HCR 0x88000000 /*no use, set HCR = HVR*/ +#define CONNAC2X_TOP_HVR 0x88000000 +#define CONNAC2X_TOP_FVR 0x88000004 +#define CONNAC2x_CONN_CFG_ON_BASE 0x7C060000 +#define CONNAC2x_CONN_CFG_ON_CONN_ON_MISC_ADDR \ + (CONNAC2x_CONN_CFG_ON_BASE + 0xF0) +#define CONNAC2x_CONN_CFG_ON_CONN_ON_MISC_DRV_FM_STAT_SYNC_SHFT 0 + +#define SOC3_0_CHIP_ID (0x7915) +#define SOC3_0_SW_SYNC0 CONNAC2x_CONN_CFG_ON_CONN_ON_MISC_ADDR +#define SOC3_0_SW_SYNC0_RDY_OFFSET \ + CONNAC2x_CONN_CFG_ON_CONN_ON_MISC_DRV_FM_STAT_SYNC_SHFT +#define SOC3_0_PATCH_START_ADDR (0x00100000) +#define SOC3_0_TOP_CFG_BASE CONN_CFG_BASE +#define SOC3_0_TX_DESC_APPEND_LENGTH 32 +#define SOC3_0_RX_DESC_LENGTH 24 +#define SOC3_0_ARB_AC_MODE_ADDR (0x820e3020) +#define MTK_CUSTOM_OID_INTERFACE_VERSION 0x00000200 /* for WPDWifi DLL */ +#define MTK_EM_INTERFACE_VERSION 0x0001 + +#define CONN_HOST_CSR_TOP_BASE_ADDR 0x18060000 +#define CONN_INFRA_CFG_BASE_ADDR 0x18001000 +#define CONN_INFRA_RGU_BASE_ADDR 0x18000000 +#define CONN_INFRA_BRCM_BASE_ADDR 0x1800E000 +#define WFDMA_AXI0_R2A_CTRL_0 0x7c027500 + +#define WF_TOP_MISC_OFF_BASE_ADDR 0x184B0000 +#define BID_CHK_BYP_EN_MASK 0x00000800 + +#define CONN_INFRA_WAKEUP_WF_ADDR (CONN_HOST_CSR_TOP_BASE_ADDR + 0x01A4) +#define CONN_INFRA_ON2OFF_SLP_PROT_ACK_ADDR \ + (CONN_HOST_CSR_TOP_BASE_ADDR + 0x0184) +#define CONN_HW_VER_ADDR (CONN_INFRA_CFG_BASE_ADDR + 0x0000) +#define WFSYS_SW_RST_B_ADDR (CONN_INFRA_RGU_BASE_ADDR + 0x0018) +#define WFSYS_CPU_SW_RST_B_ADDR (CONN_INFRA_RGU_BASE_ADDR + 0x0010) +#define WFSYS_ON_TOP_PWR_CTL_ADDR (CONN_INFRA_RGU_BASE_ADDR + 0x0000) +#define TOP_DBG_DUMMY_3_CONNSYS_PWR_STATUS_ADDR \ + (CONN_HOST_CSR_TOP_BASE_ADDR + 0x02CC) +#define CONN_INFRA_WF_SLP_CTRL_R_ADDR (CONN_INFRA_CFG_BASE_ADDR + 0x0620) +#define CONN_INFRA_WFDMA_SLP_CTRL_R_ADDR (CONN_INFRA_CFG_BASE_ADDR + 0x0624) +#define CONN_INFRA_WFSYS_EMI_REQ_ADDR (CONN_INFRA_CFG_BASE_ADDR + 0x0c14) + +#define WF_VDNR_EN_ADDR (CONN_INFRA_BRCM_BASE_ADDR + 0x6C) +#define WFSYS_VERSION_ID_ADDR (WF_TOP_MISC_OFF_BASE_ADDR + 0x10) +#define CONN_CFG_AP2WF_REMAP_1_ADDR (CONN_INFRA_CFG_BASE_ADDR + 0x0120) +#define CONN_MCU_CONFG_HS_BASE 0x89040000 +#define WFSYS_VERSION_ID 0x20010000 +#define WF_DYNAMIC_BASE 0x18500000 +#define MCU_EMI_ENTRY_OFFSET 0x01DC +#define WF_EMI_ENTRY_OFFSET 0x01E0 +#define CONN_AFE_CTL_RG_DIG_EN_ADDR (0x18003008) + +#define CONNSYS_ROM_DONE_CHECK 0x00001D1E + +#define WF_ROM_CODE_INDEX_ADDR 0x184C1604 + +#define WF_TRIGGER_AP2CONN_EINT 0x10001F00 +#define WF_CONN_INFA_BUS_CLOCK_RATE 0x1000123C + +#define WFSYS_CPUPCR_ADDR (CONNAC2x_CONN_CFG_ON_BASE + 0x0204) +#define WFSYS_LP_ADDR (CONNAC2x_CONN_CFG_ON_BASE + 0x0208) + +#define WMMCU_ROM_PATCH_DATE_ADDR 0xF027F0D0 +#define WMMCU_MCU_ROM_EMI_DATE_ADDR 0xF027F0E0 +#define WMMCU_WIFI_ROM_EMI_DATE_ADDR 0xF027F0F0 +#define DATE_CODE_SIZE 16 + +#if CFG_MTK_ANDROID_EMI +extern phys_addr_t gConEmiPhyBaseFinal; +extern unsigned long long gConEmiSizeFinal; +#endif + +union soc3_0_WPDMA_INT_MASK { + + struct { + uint32_t wfdma1_rx_done_0:1; + uint32_t wfdma1_rx_done_1:1; + uint32_t wfdma1_rx_done_2:1; + uint32_t wfdma1_rx_done_3:1; + uint32_t wfdma1_tx_done_0:1; + uint32_t wfdma1_tx_done_1:1; + uint32_t wfdma1_tx_done_2:1; + uint32_t wfdma1_tx_done_3:1; + uint32_t wfdma1_tx_done_4:1; + uint32_t wfdma1_tx_done_5:1; + uint32_t wfdma1_tx_done_6:1; + uint32_t wfdma1_tx_done_7:1; + uint32_t wfdma1_tx_done_8:1; + uint32_t wfdma1_tx_done_9:1; + uint32_t wfdma1_tx_done_10:1; + uint32_t wfdma1_tx_done_11:1; + uint32_t wfdma1_tx_done_12:1; + uint32_t wfdma1_tx_done_13:1; + uint32_t wfdma1_tx_done_14:1; + uint32_t reserved19:1; + uint32_t wfdma1_rx_coherent:1; + uint32_t wfdma1_tx_coherent:1; + uint32_t reserved:2; + uint32_t wpdma2host_err_int_en:1; + uint32_t reserved25:1; + uint32_t wfdma1_tx_done_16:1; + uint32_t wfdma1_tx_done_17:1; + uint32_t wfdma1_subsys_int_en:1; + uint32_t wfdma1_mcu2host_sw_int_en:1; + uint32_t wfdma1_tx_done_18:1; + uint32_t reserved31:1; + } field_wfdma1_ena; + + struct { + uint32_t wfdma0_rx_done_0:1; + uint32_t wfdma0_rx_done_1:1; + uint32_t wfdma0_rx_done_2:1; + uint32_t wfdma0_rx_done_3:1; + uint32_t wfdma0_tx_done_0:1; + uint32_t wfdma0_tx_done_1:1; + uint32_t wfdma0_tx_done_2:1; + uint32_t wfdma0_tx_done_3:1; + uint32_t reserved8:11; + uint32_t wfdma0_rx_done_6:1; + uint32_t wfdma0_rx_coherent:1; + uint32_t wfdma0_tx_coherent:1; + uint32_t wfdma0_rx_done_4:1; + uint32_t wfdma0_rx_done_5:1; + uint32_t wpdma2host_err_int_en:1; + uint32_t wfdma0_rx_done_7:1; + uint32_t reserved26:2; + uint32_t wfdma0_subsys_int_en:1; + uint32_t wfdma0_mcu2host_sw_int_en:1; + uint32_t reserved30:2; + } field_wfdma0_ena; + uint32_t word; +}; +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ +enum ENUM_WLAN_POWER_ON_DOWNLOAD { + ENUM_WLAN_POWER_ON_DOWNLOAD_EMI = 0, + ENUM_WLAN_POWER_ON_DOWNLOAD_ROM_PATCH = 1, + ENUM_WLAN_POWER_ON_DOWNLOAD_WIFI_RAM_CODE = 2 +}; + +struct ROM_EMI_HEADER { + uint8_t ucDateTime[16]; + uint8_t ucPLat[4]; + uint16_t u2HwVer; + uint16_t u2SwVer; + uint32_t u4PatchAddr; + uint32_t u4PatchType; + uint32_t u4CRC[4]; +}; + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ +extern struct platform_device *g_prPlatDev; +#if (CFG_SUPPORT_CONNINFRA == 1) +extern u_int8_t g_IsWfsysBusHang; +extern struct completion g_triggerComp; +extern bool g_IsTriggerTimeout; +extern u_int8_t fgIsResetting; +extern u_int8_t g_fgRstRecover; +extern struct regmap *g_regmap; +#endif +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +void soc3_0_show_ple_info( + struct ADAPTER *prAdapter, + u_int8_t fgDumpTxd); +void soc3_0_show_pse_info( + struct ADAPTER *prAdapter); + +void soc3_0_show_wfdma_info( + IN struct ADAPTER *prAdapter); + +void soc3_0_show_wfdma_info_by_type( + IN struct ADAPTER *prAdapter, + bool bShowWFDMA_type); + +void soc3_0_show_wfdma_info_by_type_without_adapter( + bool bIsHostDMA); + +void soc3_0_DumpWFDMACr(struct ADAPTER *prAdapter); + +void soc3_0_show_dmashdl_info( + IN struct ADAPTER *prAdapter); +void soc3_0_dump_mac_info( + IN struct ADAPTER *prAdapter); +void soc3_0EnableInterrupt( + struct ADAPTER *prAdapter); + +void soc3_0EnableInterrupt( + struct ADAPTER *prAdapter); +extern void kalConstructDefaultFirmwarePrio( + struct GLUE_INFO *prGlueInfo, + uint8_t **apucNameTable, + uint8_t **apucName, + uint8_t *pucNameIdx, + uint8_t ucMaxNameIdx); + +extern uint32_t kalFirmwareOpen( + IN struct GLUE_INFO *prGlueInfo, + IN uint8_t **apucNameTable); + + +extern uint32_t kalFirmwareSize( + IN struct GLUE_INFO *prGlueInfo, + OUT uint32_t *pu4Size); + +extern uint32_t kalFirmwareLoad( + IN struct GLUE_INFO *prGlueInfo, + OUT void *prBuf, IN uint32_t u4Offset, + OUT uint32_t *pu4Size); + +extern uint32_t kalFirmwareClose( + IN struct GLUE_INFO *prGlueInfo); + +extern void wlanWakeLockInit( + struct GLUE_INFO *prGlueInfo); + +extern void wlanWakeLockUninit( + struct GLUE_INFO *prGlueInfo); + +extern struct wireless_dev *wlanNetCreate( + void *pvData, + void *pvDriverData); + +extern void wlanNetDestroy( + struct wireless_dev *prWdev); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#if (CFG_DOWNLOAD_DYN_MEMORY_MAP == 1) +uint32_t soc3_0_DownloadByDynMemMap(IN struct ADAPTER *prAdapter, + IN uint32_t u4Addr, IN uint32_t u4Len, + IN uint8_t *pucStartPtr, IN enum ENUM_IMG_DL_IDX_T eDlIdx); +#endif +void soc3_0_DumpWfsyscpupcr(struct ADAPTER *prAdapter); +void soc3_0_WfdmaAxiCtrl(struct ADAPTER *prAdapter); + +int hifWmmcuPwrOn(void); +int hifWmmcuPwrOff(void); +int wf_ioremap_read(size_t addr, unsigned int *val); + +int wf_ioremap_write(phys_addr_t addr, unsigned int val); +int soc3_0_Trigger_fw_assert(void); +int soc3_0_CheckBusHang(void *adapter, + uint8_t ucWfResetEnable); +void soc3_0_DumpBusHangCr(struct ADAPTER *prAdapter); + +void wlanCoAntWiFi(void); +void wlanCoAntMD(void); +void wlanCoAntVFE28En(IN struct ADAPTER *prAdapter); +void wlanCoAntVFE28Dis(void); + +#if (CFG_SUPPORT_CONNINFRA == 1) +int wlanConnacPccifon(void); +int wlanConnacPccifoff(void); +int soc3_0_Trigger_whole_chip_rst(char *reason); +void soc3_0_Sw_interrupt_handler(struct ADAPTER *prAdapter); +void soc3_0_Conninfra_cb_register(void); +extern void update_driver_reset_status(uint8_t fgIsResetting); +extern int32_t get_wifi_process_status(void); +extern int32_t get_wifi_powered_status(void); +extern void update_pre_cal_status(uint8_t fgIsPreCal); +extern int8_t get_pre_cal_status(void); +#endif +void soc3_0_DumpWfsysdebugflag(void); +#if (CFG_POWER_ON_DOWNLOAD_EMI_ROM_PATCH == 1) +void soc3_0_ConstructFirmwarePrio(struct GLUE_INFO *prGlueInfo, + uint8_t **apucNameTable, uint8_t **apucName, + uint8_t *pucNameIdx, uint8_t ucMaxNameIdx); +void * +soc3_0_kalFirmwareImageMapping(IN struct GLUE_INFO *prGlueInfo, + OUT void **ppvMapFileBuf, OUT uint32_t *pu4FileLength, + IN enum ENUM_IMG_DL_IDX_T eDlIdx); +uint32_t soc3_0_wlanImageSectionDownloadStage( + IN struct ADAPTER *prAdapter, IN void *pvFwImageMapFile, + IN uint32_t u4FwImageFileLength, IN uint8_t ucSectionNumber, + IN enum ENUM_IMG_DL_IDX_T eDlIdx); +uint32_t soc3_0_wlanPowerOnDownload( + IN struct ADAPTER *prAdapter, + IN uint8_t ucDownloadItem); +int32_t soc3_0_wlanPowerOnInit( + enum ENUM_WLAN_POWER_ON_DOWNLOAD eDownloadItem); +#endif + +#if (CFG_SUPPORT_PRE_ON_PHY_ACTION == 1) +uint32_t soc3_0_wlanPhyAction(IN struct ADAPTER *prAdapter); +int soc3_0_wlanPreCalPwrOn(void); +int soc3_0_wlanPreCal(void); +uint8_t *soc3_0_wlanGetCalResult(uint32_t *prCalSize); +void soc3_0_wlanCalDebugCmd(uint32_t cmd, uint32_t para); +#endif /* (CFG_SUPPORT_PRE_ON_PHY_ACTION == 1) */ + +void soc3_0_icapRiseVcoreClockRate(void); +void soc3_0_icapDownVcoreClockRate(void); + +#endif /* _SOC3_0_H */ + +#endif /* soc3_0 */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/wf_ple.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/wf_ple.h new file mode 100644 index 0000000000000000000000000000000000000000..97d81df161a2f49c0fd5caad97de42c551521146 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/chips/wf_ple.h @@ -0,0 +1,233 @@ +/* + *************************************************************************** + * Ralink Tech Inc. + * 4F, No. 2 Technology 5th Rd. + * Science-based Industrial Park + * Hsin-chu, Taiwan, R.O.C. + * + * (c) Copyright 2002-2004, Ralink Technology, Inc. + * + * All rights reserved. Ralink's source code is an unpublished work and the + * use of a copyright notice does not imply otherwise. This source code + * contains confidential trade secret material of Ralink Tech. Any attemp + * or participation in deciphering, decoding, reverse engineering or in any + * way altering the source code is stricitly prohibited, unless the prior + * written consent of Ralink Technology, Inc. is obtained. + *************************************************************************** + + Module Name: + wf_ple.h + + Abstract: + Ralink Wireless Chip MAC related definition & structures + + Revision History: + Who When What + -------- ---------- ------------------------------------- +*/ + +#ifndef __WF_PLE_H__ +#define __WF_PLE_H__ + +#define PLE_BASE 0x8000 + + +/* PLE Buffer Control Register */ +#define PLE_PBUF_CTRL (PLE_BASE + 0x14) +#define PLE_TOTAL_PAGE_NUM_MASK (0xfff) +#define PLE_GET_TOTAL_PAGE_NUM(p) (((p) & 0xfff)) +#define PLE_TOTAL_PAGE_CFG_MASK (0xf << 16) +#define PLE_GET_TOTAL_PAGE_CFG(p) (((p) & PSE_TOTAL_PAGE_CFG_MASK) >> 16) +#define PLE_PBUF_OFFSET_MASK (0xf << 20) +#define GET_PLE_PBUF_OFFSET(p) (((p) & PSE_PBUF_OFFSET_MASK) >> 20) + + +/* Release Control */ +#define PLE_RELEASE_CTRL (PLE_BASE + 0x30) +#define PLE_NORMAL_TX_RLS_QID_MASK (0x1f) +#define GET_PLE_NORMAL_TX_RLS_QID(p) (((p) & GET_FIRST_FID_MASK)) +#define PLE_NORMAL_TX_RLS_PID_MASK (0x3 << 6) +#define GET_PLE_NORMAL_TX_RLS_PID(p) (((p) & PLE_NORMAL_TX_RLS_PID_MASK) >> 6) + +#define BCNx_RLS_QID_MASK (0x1f) +#define BCNx_RLS_PID_MASK (0x3) +#define SET_BCN0_RLS_QID(p) (((p) & BCNx_RLS_QID_MASK) << 16) +#define SET_BCN0_RLS_PID(p) (((p) & BCNx_RLS_PID_MASK) << 22) +#define SET_BCN1_RLS_QID(p) (((p) & BCNx_RLS_QID_MASK) << 24) +#define SET_BCN1_RLS_PID(p) (((p) & BCNx_RLS_PID_MASK) << 30) + +#define PLE_GC (PLE_BASE) +#define PLE_INT_STS (PLE_BASE + 0x24) +#define PLE_INT_ERR_STS (PLE_BASE + 0x28) +#define PLE_QUEUE_CMD_ERR_STS (PLE_BASE + 0x550) + +/* HIF Report Control */ +#define PLE_HIF_REPORT (PLE_BASE + 0x34) + +/* CPU Interface get frame ID Control */ +#define PLE_C_GET_FID_0 (PLE_BASE + 0x40) + +/* CPU Interface get frame ID Control */ +#define PLE_C_GET_FID_1 (PLE_BASE + 0x44) + +#define PLE_C_EN_QUEUE_0 (PLE_BASE + 0x60) +#define PLE_C_EN_QUEUE_1 (PLE_BASE + 0x64) +#define PLE_C_EN_QUEUE_2 (PLE_BASE + 0x68) + +#define PLE_C_DE_QUEUE_0 (PLE_BASE + 0x80) +#define PLE_C_DE_QUEUE_1 (PLE_BASE + 0x84) +#define PLE_C_DE_QUEUE_2 (PLE_BASE + 0x88) +#define PLE_C_DE_QUEUE_3 (PLE_BASE + 0x8c) + +#define PLE_TO_N9_INT (PLE_BASE + 0xf0) +#define PLE_TO_N9_INT_TOGGLE_MASK 0x80000000 + + + +/* Queue Empty */ +#define PLE_QUEUE_EMPTY (PLE_BASE + 0xb0) +#define PLE_AC0_QUEUE_EMPTY_0 (PLE_BASE + 0x300) +#define PLE_AC0_QUEUE_EMPTY_1 (PLE_BASE + 0x304) +#define PLE_AC0_QUEUE_EMPTY_2 (PLE_BASE + 0x308) +#define PLE_AC0_QUEUE_EMPTY_3 (PLE_BASE + 0x30c) + +#define PLE_AC1_QUEUE_EMPTY_0 (PLE_BASE + 0x310) +#define PLE_AC1_QUEUE_EMPTY_1 (PLE_BASE + 0x314) +#define PLE_AC1_QUEUE_EMPTY_2 (PLE_BASE + 0x318) +#define PLE_AC1_QUEUE_EMPTY_3 (PLE_BASE + 0x31c) + +#define PLE_AC2_QUEUE_EMPTY_0 (PLE_BASE + 0x320) +#define PLE_AC2_QUEUE_EMPTY_1 (PLE_BASE + 0x324) +#define PLE_AC2_QUEUE_EMPTY_2 (PLE_BASE + 0x328) +#define PLE_AC2_QUEUE_EMPTY_3 (PLE_BASE + 0x32c) + +#define PLE_AC3_QUEUE_EMPTY_0 (PLE_BASE + 0x330) +#define PLE_AC3_QUEUE_EMPTY_1 (PLE_BASE + 0x334) +#define PLE_AC3_QUEUE_EMPTY_2 (PLE_BASE + 0x338) +#define PLE_AC3_QUEUE_EMPTY_3 (PLE_BASE + 0x33c) + +#define PLE_STATION_PAUSE0 (PLE_BASE + 0x360) +#define PLE_STATION_PAUSE1 (PLE_BASE + 0x364) +#define PLE_STATION_PAUSE2 (PLE_BASE + 0x368) +#define PLE_STATION_PAUSE3 (PLE_BASE + 0x36C) + +/* Page Flow Control */ +#define PLE_FREEPG_CNT (PLE_BASE + 0x100) + +#define PLE_FREEPG_HEAD_TAIL (PLE_BASE + 0x104) + +#define PLE_PG_HIF_GROUP (PLE_BASE + 0x110) +#define PLE_HIF_PG_INFO (PLE_BASE + 0x114) + +#define PLE_PG_CPU_GROUP (PLE_BASE + 0x150) +#define PLE_CPU_PG_INFO (PLE_BASE + 0x154) + + +/* Indirect path for read/write */ +#define PLE_FL_QUE_CTRL_0 (PLE_BASE + 0x1b0) +#define PLE_FL_QUE_CTRL_1 (PLE_BASE + 0x1b4) +#define PLE_FL_QUE_CTRL_2 (PLE_BASE + 0x1b8) +#define PLE_FL_QUE_CTRL_3 (PLE_BASE + 0x1bc) +#define PLE_PL_QUE_CTRL_0 (PLE_BASE + 0x1c0) + +/* Disable Station control */ +#define DIS_STA_MAP0 (PLE_BASE + 0x260) +#define DIS_STA_MAP1 (PLE_BASE + 0x264) +#define DIS_STA_MAP2 (PLE_BASE + 0x268) +#define DIS_STA_MAP3 (PLE_BASE + 0x26c) + +/* Station Pause control register */ +#define STATION_PAUSE0 (PLE_BASE + 0x360) +#define STATION_PAUSE1 (PLE_BASE + 0x364) +#define STATION_PAUSE2 (PLE_BASE + 0x368) +#define STATION_PAUSE3 (PLE_BASE + 0x36c) + +#define PLE_PEEK_CR_0 (PLE_BASE + 0x3d0) +#define PLE_PEEK_CR_OFFSET 0x4 +#define PLE_PEEK_CR_NUM 12 + +/* VOW Ctrl */ +#define VOW_RESET_DISABLE (1 << 26) +#define STA_MAX_DEFICIT_MASK (0x0000FFFF) +#define VOW_DBDC_BW_GROUP_CTRL (PLE_BASE + 0x2ec) +#define VOW_CONTROL (PLE_BASE + 0x370) +#define AIRTIME_DRR_SIZE (PLE_BASE + 0x374) + +#define PLE_PAYLOAD_BASE 0xA0000000 + +enum ENUM_UMAC_PORT { + ENUM_UMAC_HIF_PORT_0 = 0, + ENUM_UMAC_CPU_PORT_1 = 1, + ENUM_UMAC_LMAC_PORT_2 = 2, + ENUM_PLE_CTRL_PSE_PORT_3 = 3, + ENUM_UMAC_PSE_PLE_PORT_TOTAL_NUM = 4 +}; + +/* N9 MCU QUEUE LIST */ +enum ENUM_UMAC_CPU_P_QUEUE { + ENUM_UMAC_CTX_Q_0 = 0, + ENUM_UMAC_CTX_Q_1 = 1, + ENUM_UMAC_CTX_Q_2 = 2, + ENUM_UMAC_CTX_Q_3 = 3, + ENUM_UMAC_CRX = 0, + ENUM_UMAC_CIF_QUEUE_TOTAL_NUM = 4 +}; + + +/* LMAC PLE TX QUEUE LIST */ +enum ENUM_UMAC_LMAC_PLE_TX_P_QUEUE { + ENUM_UMAC_LMAC_PLE_TX_Q_00 = 0x00, + ENUM_UMAC_LMAC_PLE_TX_Q_01 = 0x01, + ENUM_UMAC_LMAC_PLE_TX_Q_02 = 0x02, + ENUM_UMAC_LMAC_PLE_TX_Q_03 = 0x03, + + ENUM_UMAC_LMAC_PLE_TX_Q_10 = 0x04, + ENUM_UMAC_LMAC_PLE_TX_Q_11 = 0x05, + ENUM_UMAC_LMAC_PLE_TX_Q_12 = 0x06, + ENUM_UMAC_LMAC_PLE_TX_Q_13 = 0x07, + + ENUM_UMAC_LMAC_PLE_TX_Q_20 = 0x08, + ENUM_UMAC_LMAC_PLE_TX_Q_21 = 0x09, + ENUM_UMAC_LMAC_PLE_TX_Q_22 = 0x0a, + ENUM_UMAC_LMAC_PLE_TX_Q_23 = 0x0b, + + ENUM_UMAC_LMAC_PLE_TX_Q_30 = 0x0c, + ENUM_UMAC_LMAC_PLE_TX_Q_31 = 0x0d, + ENUM_UMAC_LMAC_PLE_TX_Q_32 = 0x0e, + ENUM_UMAC_LMAC_PLE_TX_Q_33 = 0x0f, + + ENUM_UMAC_LMAC_PLE_TX_Q_ALTX_0 = 0x10, + ENUM_UMAC_LMAC_PLE_TX_Q_BMC_0 = 0x11, + ENUM_UMAC_LMAC_PLE_TX_Q_BNC_0 = 0x12, + ENUM_UMAC_LMAC_PLE_TX_Q_PSMP_0 = 0x13, + + ENUM_UMAC_LMAC_PLE_TX_Q_ALTX_1 = 0x14, + ENUM_UMAC_LMAC_PLE_TX_Q_BMC_1 = 0x15, + ENUM_UMAC_LMAC_PLE_TX_Q_BNC_1 = 0x16, + ENUM_UMAC_LMAC_PLE_TX_Q_PSMP_1 = 0x17, + ENUM_UMAC_LMAC_PLE_TX_Q_NAF = 0x18, + ENUM_UMAC_LMAC_PLE_TX_Q_NBCN = 0x19, +/* DE suggests not to use 0x1f, it's only for hw free queue */ + ENUM_UMAC_LMAC_PLE_TX_Q_RELEASE = 0x1f, + ENUM_UMAC_LMAC_QUEUE_TOTAL_NUM = 24, + +}; + +/* LMAC PLE For PSE Control P3 */ +enum ENUM_UMAC_PLE_CTRL_P3_QUEUE { + ENUM_UMAC_PLE_CTRL_P3_Q_0X1E = 0x1e, + ENUM_UMAC_PLE_CTRL_P3_Q_0X1F = 0x1f, + ENUM_UMAC_PLE_CTRL_P3_TOTAL_NUM = 2 +}; + + + +struct EMPTY_QUEUE_INFO { + int8_t *QueueName; + uint32_t Portid; + uint32_t Queueid; +}; + + +#endif /* __WF_PLE_H__ */ + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/config.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/config.h new file mode 100644 index 0000000000000000000000000000000000000000..0d155f5780172ae3f27ea59d9d396fb718e2b918 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/config.h @@ -0,0 +1,1492 @@ +/******************************************************************************* + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/config.h#3 + */ + +/*! \file "config.h" + * \brief This file includes the various configurable parameters for + * customers + * + * This file ncludes the configurable parameters except the parameters + * indicate the turning-on/off of some features + */ + +#ifndef _CONFIG_H +#define _CONFIG_H + +#include + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +/* 2 Flags for OS capability */ + +#if defined(_HIF_SDIO) +/* #ifdef CONFIG_X86 */ +/*Kernel-3.10-ARM did not provide X86_FLAG & HIF shouldn't bind platform*/ +#if (CFG_MTK_ANDROID_WMT) +#define MTK_WCN_HIF_SDIO 1 +#else +#define MTK_WCN_HIF_SDIO 0 +#endif +#else +#define MTK_WCN_HIF_SDIO 0 +#endif + +#if defined(_HIF_AXI) +#ifdef LINUX +#ifdef CONFIG_X86 +#define MTK_WCN_HIF_AXI 0 +#else +#define MTK_WCN_HIF_AXI 1 +#endif +#else +#define MTK_WCN_HIF_AXI 0 +#endif +#else +#define MTK_WCN_HIF_AXI 0 +#endif + + + +/* Android build-in driver switch, Mike 2016/11/11*/ +#ifndef CFG_BUILT_IN_DRIVER +#define CFG_BUILT_IN_DRIVER 0 +#endif + +/* Mike 2016/09/01 ALPS update K3.18 80211_disconnect to K4.4 version*/ +/* work around for any alps K3.18 platform*/ +#ifndef CFG_WPS_DISCONNECT +#define CFG_WPS_DISCONNECT 0 +#endif + + +#if (CFG_SUPPORT_AEE == 1) +/* TODO: temp remove for 7663 on mobile */ +/* #define CFG_ENABLE_AEE_MSG 1 */ +#define CFG_ENABLE_AEE_MSG 0 +#else +#define CFG_ENABLE_AEE_MSG 0 +#endif + +#define CFG_ENABLE_EARLY_SUSPEND 0 +#define CFG_ENABLE_NET_DEV_NOTIFY 1 + +/* 2 Flags for Driver Features */ +#define CFG_TX_FRAGMENT 1 /*!< 1: Enable TX fragmentation */ +/* 0: Disable */ +#define CFG_SUPPORT_PERFORMANCE_TEST 0 /*Only for performance Test */ + +#define CFG_COUNTRY_CODE NULL /* "US" */ +#define CFG_SUPPORT_DEBUG_FS 0 +#define CFG_SUPPORT_SET_CAM_BY_PROC 1 /*Enable/disable powersave mode*/ + +#ifndef LINUX +#define CFG_FW_FILENAME L"WIFI_RAM_CODE" +#define CFG_CR4_FW_FILENAME L"WIFI_RAM_CODE2" +#else +#define CFG_FW_FILENAME "WIFI_RAM_CODE" +#define CFG_CR4_FW_FILENAME "WIFI_RAM_CODE2" +#endif + +#ifndef CFG_MET_PACKET_TRACE_SUPPORT +#define CFG_MET_PACKET_TRACE_SUPPORT 0 /*move to wlan/MAKEFILE */ +#endif + +#ifndef CFG_MET_TAG_SUPPORT +#define CFG_MET_TAG_SUPPORT 0 +#endif + +#ifndef CFG_SUPPORT_PERF_IND +#define CFG_SUPPORT_PERF_IND 1 +#endif + +/* Support AP Selection */ +#define CFG_SUPPORT_RSN_SCORE 0 +#define CFG_SELECT_BSS_BASE_ON_MULTI_PARAM 1 +#define CFG_MAX_NUM_OF_CHNL_INFO 50 +#define CFG_SUPPORT_CHNL_CONFLICT_REVISE 0 + + +/*------------------------------------------------------------------------------ + * Driver config + *------------------------------------------------------------------------------ + */ + +#ifndef LINUX +#define CFG_SUPPORT_CFG_FILE 0 +#else +#define CFG_SUPPORT_CFG_FILE 1 +#endif + +/*!< 1(default): Enable 802.11d */ +#define CFG_SUPPORT_802_11D 1 +/* 0: Disable */ + +/* Radio Reasource Measurement (802.11k) */ +#define CFG_SUPPORT_RRM 0 + +/* DFS (802.11h) */ +#define CFG_SUPPORT_DFS 1 +#ifndef CFG_SUPPORT_DFS_MASTER +#define CFG_SUPPORT_DFS_MASTER 1 +/* SoftAp Cross Band Channel Switch */ +#define CFG_SUPPORT_IDC_CH_SWITCH 1 +#endif + +#if (CFG_SUPPORT_DFS == 1) /* Add by Enlai */ +/* Quiet (802.11h) */ +#define CFG_SUPPORT_QUIET 0 +/* Spectrum Management (802.11h): TPC and DFS */ +#define CFG_SUPPORT_SPEC_MGMT 1 +#else +/* Quiet (802.11h) */ +#define CFG_SUPPORT_QUIET 0 +/* Spectrum Management (802.11h): TPC and DFS */ +#define CFG_SUPPORT_SPEC_MGMT 0 +#endif + +/* 11n feature. RX RDG capability */ +#define CFG_SUPPORT_RX_RDG 0 + +/* 802.11n MCS Feedback responder */ +#define CFG_SUPPORT_MFB 0 + +/* 802.11n RX STBC (1SS) */ +#define CFG_SUPPORT_RX_STBC 1 + +/* 802.11n RX short GI for both 20M and 40M BW */ +#define CFG_SUPPORT_RX_SGI 1 + +/* 802.11n RX HT green-field capability */ +#define CFG_SUPPORT_RX_HT_GF 1 + +#define CFG_SUPPORT_BFER 0 +#define CFG_SUPPORT_BFEE 1 +/* Enable Bfee only when AP's Nss > STA's Nss */ +#define CFG_SUPPORT_CONDITIONAL_BFEE 1 + +#define CFG_SUPPORT_WAPI 1 + +/* Enable QA Tool Support */ +#define CFG_SUPPORT_QA_TOOL 1 + +/* Enable TX BF Support */ +#define CFG_SUPPORT_TX_BF 1 + +#define CFG_SUPPORT_TX_BF_FPGA 1 + +/* Enable MU MIMO Support */ +#define CFG_SUPPORT_MU_MIMO 1 + +/* Enable WOW Support */ +#define CFG_WOW_SUPPORT 1 + +/* Enable A-MSDU RX Reordering Support */ +#define CFG_SUPPORT_RX_AMSDU 1 + +/* Enable Detection for 2021 Frag/AGG Attack from WFA */ +#define CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION 1 + +/* Enable Android wake_lock operations */ +#ifndef CFG_ENABLE_WAKE_LOCK +#define CFG_ENABLE_WAKE_LOCK 1 +#endif + +#define CFG_SUPPORT_OSHARE 1 + +#define CFG_SUPPORT_LOWLATENCY_MODE 1 + +#define CFG_SUPPORT_ANT_SWAP 1 + +/* If skb_buff mark field marked with pre-defined value, change priority to VO*/ +#define CFG_CHANGE_PRIORITY_BY_SKB_MARK_FIELD 1 + +#if KERNEL_VERSION(4, 4, 0) <= LINUX_VERSION_CODE +#define CFG_SUPPORT_DATA_STALL 1 +#define CFG_SUPPORT_BIGDATA_PIP 1 +#else +#define CFG_SUPPORT_DATA_STALL 0 +#define CFG_SUPPORT_BIGDATA_PIP 0 +#endif + +#define CFG_SUPPORT_HE_ER 1 + +/*------------------------------------------------------------------------------ + * Flags of Buffer mode SUPPORT + *------------------------------------------------------------------------------ + */ +#define CFG_SUPPORT_BUFFER_MODE 1 + +/*------------------------------------------------------------------------------ + * SLT Option + *------------------------------------------------------------------------------ + */ +#define CFG_SLT_SUPPORT 0 + +#ifdef NDIS60_MINIPORT +#define CFG_NATIVE_802_11 1 + +#define CFG_TX_MAX_PKT_SIZE 2304 + +/* !< 1: Enable TCP/IP header checksum offload */ +#define CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60 0 + +/* 0: Disable */ +#define CFG_TCP_IP_CHKSUM_OFFLOAD 0 +#define CFG_WHQL_DOT11_STATISTICS 1 +#define CFG_WHQL_ADD_REMOVE_KEY 1 +#define CFG_WHQL_CUSTOM_IE 1 +#define CFG_WHQL_SAFE_MODE_ENABLED 1 + +#else +#define CFG_TCP_IP_CHKSUM_OFFLOAD 1 +#define CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60 0 +#define CFG_TX_MAX_PKT_SIZE 1600 +#define CFG_NATIVE_802_11 0 +#endif + +/* By using GRO at NAPI level, the driver is doing the aggregation to a large + * SKB very early, right at the receive completion handler. This means that all + * the next functions in the receive stack do much less processing. + * The GRO feature could enhance "Rx" tput. + */ +#define CFG_SUPPORT_RX_GRO 1 + +/* 2 Flags for Driver Parameters */ +/*------------------------------------------------------------------------------ + * Flags for EHPI Interface in Colibri Platform + *------------------------------------------------------------------------------ + */ +/*!< 1: Do workaround for faster bus timing */ +/* 0(default): Disable */ +#define CFG_EHPI_FASTER_BUS_TIMING 0 + +/*------------------------------------------------------------------------------ + * Flags for UMAC + *------------------------------------------------------------------------------ + */ +#define CFG_UMAC_GENERATION 0x20 + +/*------------------------------------------------------------------------------ + * Flags for HIFSYS Interface + *------------------------------------------------------------------------------ + */ +#ifdef _lint +/* #define _HIF_SDIO 1 */ +#endif + +/* 1(default): Enable SDIO ISR & TX/RX status enhance mode + * 0: Disable + */ +#define CFG_SDIO_INTR_ENHANCE 1 +/* 1(default): Enable SDIO ISR & TX/RX status enhance mode + * 0: Disable + */ +#define CFG_SDIO_RX_ENHANCE 1 +/* 1: Enable SDIO TX enhance mode(Multiple frames in single BLOCK CMD) + * 0(default): Disable + */ +#define CFG_SDIO_TX_AGG 1 + +/* 1: Enable SDIO RX enhance mode(Multiple frames in single BLOCK CMD) + * 0(default): Disable + */ +#define CFG_SDIO_RX_AGG 1 + +/* 1: Enable SDIO RX Tasklet De-Aggregation + * 0(default): Disable + */ +#ifndef CFG_SDIO_RX_AGG_TASKLET +#define CFG_SDIO_RX_AGG_TASKLET 0 +#endif + +#if (CFG_SDIO_RX_AGG == 1) && (CFG_SDIO_INTR_ENHANCE == 0) +#error \ + "CFG_SDIO_INTR_ENHANCE should be 1 once CFG_SDIO_RX_AGG equals to 1" +#elif (CFG_SDIO_INTR_ENHANCE == 1 || CFG_SDIO_RX_ENHANCE == 1) && \ + (CFG_SDIO_RX_AGG == 0) +#error \ + "CFG_SDIO_RX_AGG should be 1 once CFG_SDIO_INTR_ENHANCE and/or CFG_SDIO_RX_ENHANCE equals to 1" +#endif + +#ifdef WINDOWS_CE +/*!< 1: Support pass through (PATHRU) mode */ +#define CFG_SDIO_PATHRU_MODE 1 +/* 0: Disable */ +#else +/*!< 0: Always disable if WINDOWS_CE is not defined */ +#define CFG_SDIO_PATHRU_MODE 0 +#endif + +#define CFG_SDIO_ACCESS_N9_REGISTER_BY_MAILBOX 0 +#define CFG_MAX_RX_ENHANCE_LOOP_COUNT 3 + +#define CFG_USB_TX_AGG 1 +#define CFG_USB_CONSISTENT_DMA 0 +#define CFG_USB_TX_HANDLE_IN_HIF_THREAD 0 +#define CFG_USB_RX_HANDLE_IN_HIF_THREAD 0 + +#ifndef CFG_TX_DIRECT_USB +#define CFG_TX_DIRECT_USB 1 +#endif +#ifndef CFG_RX_DIRECT_USB +#define CFG_RX_DIRECT_USB 1 +#endif + +#define CFG_HW_WMM_BY_BSS 1 + +/*------------------------------------------------------------------------------ + * Flags and Parameters for Integration + *------------------------------------------------------------------------------ + */ + +#define CFG_MULTI_ECOVER_SUPPORT 1 + +#define CFG_ENABLE_CAL_LOG 1 +#define CFG_REPORT_RFBB_VERSION 1 + +#define MAX_BSSID_NUM 4 /* MAX BSSID number */ + +#define CFG_CHIP_RESET_SUPPORT 1 + +#if CFG_CHIP_RESET_SUPPORT +#define CFG_CHIP_RESET_HANG 0 +#else +#define CFG_CHIP_RESET_HANG 0 +#endif + +#define HW_BSSID_NUM 4 /* HW BSSID number by chip */ + +/*------------------------------------------------------------------------------ + * Flags for workaround + *------------------------------------------------------------------------------ + */ + +/*------------------------------------------------------------------------------ + * Flags for driver version + *------------------------------------------------------------------------------ + */ +#define CFG_DRV_OWN_VERSION ((uint16_t)((NIC_DRIVER_MAJOR_VERSION << 8) | \ + (NIC_DRIVER_MINOR_VERSION))) +#define CFG_DRV_PEER_VERSION ((uint16_t)0x0000) + +/*------------------------------------------------------------------------------ + * Flags and Parameters for TX path + *------------------------------------------------------------------------------ + */ + +/*! Maximum number of SW TX packet queue */ +#define CFG_TX_MAX_PKT_NUM 1024 + +/*! Maximum number of SW TX CMD packet buffer */ +#define CFG_TX_MAX_CMD_PKT_NUM 32 + +/*------------------------------------------------------------------------------ + * Flags and Parameters for RX path + *------------------------------------------------------------------------------ + */ + +/*------------------------------------------------------------------------------ + * CONFIG_TITLE : Move BA from FW to Driver + * OWNER : Puff Wen + * Description : Move BA from FW to Driver + *------------------------------------------------------------------------------ + */ +#define CFG_M0VE_BA_TO_DRIVER 0 + +/*! Max. descriptor number - sync. with firmware */ +#if CFG_SLT_SUPPORT +#define CFG_NUM_OF_RX0_HIF_DESC 42 +#else +#define CFG_NUM_OF_RX0_HIF_DESC 16 +#endif +#define CFG_NUM_OF_RX1_HIF_DESC 2 + +/*! Max. buffer hold by QM */ +#define CFG_NUM_OF_QM_RX_PKT_NUM HIF_NUM_OF_QM_RX_PKT_NUM + +/*! Maximum number of SW RX packet buffer */ +#define CFG_RX_MAX_PKT_NUM ((CFG_NUM_OF_RX0_HIF_DESC + \ + CFG_NUM_OF_RX1_HIF_DESC) * 3 \ + + CFG_NUM_OF_QM_RX_PKT_NUM) + +#define CFG_RX_REORDER_Q_THRESHOLD 8 + +#ifndef LINUX +#define CFG_RX_RETAINED_PKT_THRESHOLD (CFG_NUM_OF_RX0_HIF_DESC + \ + CFG_NUM_OF_RX1_HIF_DESC \ + + CFG_NUM_OF_QM_RX_PKT_NUM) +#else +#define CFG_RX_RETAINED_PKT_THRESHOLD 0 +#endif + +/*! Maximum RX packet size, if exceed this value, drop incoming packet */ +/* 7.2.3 Maganement frames */ +/* TODO: it should be 4096 under emulation mode */ +#define CFG_RX_MAX_PKT_SIZE (28 + 2312 + 12 /*HIF_RX_HEADER_T*/) + +/*! Minimum RX packet size, if lower than this value, drop incoming packet */ +#define CFG_RX_MIN_PKT_SIZE 10 /*!< 802.11 Control Frame is 10 bytes */ + +/*! RX BA capability */ +#define CFG_NUM_OF_RX_BA_AGREEMENTS 80 +#if CFG_M0VE_BA_TO_DRIVER +#define CFG_RX_BA_MAX_WINSIZE 64 +#endif +#define CFG_RX_BA_INC_SIZE 64 +#define CFG_RX_MAX_BA_TID_NUM 8 +#define CFG_RX_REORDERING_ENABLED 1 + +#define CFG_PF_ARP_NS_MAX_NUM 3 + +#define CFG_COMPRESSION_DEBUG 0 +#define CFG_DECOMPRESSION_TMP_ADDRESS 0 +#define CFG_SUPPORT_COMPRESSION_FW_OPTION 0 + +/*------------------------------------------------------------------------------ + * Flags and Parameters for CMD/RESPONSE + *------------------------------------------------------------------------------ + */ +/* WMT expects wlan driver on/off to be completed within 4s. + * To avoid on/off timeout, only polling ready bit in 1s + * (CFG_RESPONSE_POLLING_TIMEOUT * CFG_RESPONSE_POLLING_DELAY). + */ +#if CFG_MTK_ANDROID_WMT +#define CFG_RESPONSE_POLLING_TIMEOUT 200 +#else +#define CFG_RESPONSE_POLLING_TIMEOUT 1000 +#endif +#define CFG_RESPONSE_POLLING_DELAY 5 + +/*------------------------------------------------------------------------------ + * Flags and Parameters for Protocol Stack + *------------------------------------------------------------------------------ + */ +/*! Maximum number of BSS in the SCAN list */ +#define CFG_MAX_NUM_BSS_LIST 192 + +#define CFG_MAX_COMMON_IE_BUF_LEN ((1500 * CFG_MAX_NUM_BSS_LIST) / 3) + +/*! Maximum size of Header buffer of each SCAN record */ +#define CFG_RAW_BUFFER_SIZE 1024 + +/*! Maximum size of IE buffer of each SCAN record */ +#define CFG_IE_BUFFER_SIZE 512 + +/*------------------------------------------------------------------------------ + * Flags and Parameters for Power management + *------------------------------------------------------------------------------ + */ +#define CFG_ENABLE_FULL_PM 1 +#define CFG_ENABLE_WAKEUP_ON_LAN 0 + +/* debug which packet wake up host */ +#define CFG_SUPPORT_WAKEUP_REASON_DEBUG 1 + +#define CFG_INIT_POWER_SAVE_PROF ENUM_PSP_FAST_SWITCH + +#define CFG_INIT_ENABLE_PATTERN_FILTER_ARP 0 + +/* (BIT(3) | BIT(2) | BIT(1) | BIT(0)) */ +#define CFG_INIT_UAPSD_AC_BMP 0 + +/* #define CFG_SUPPORT_WAPI 0 */ +#define CFG_SUPPORT_WPS 1 +#define CFG_SUPPORT_WPS2 1 + +/*------------------------------------------------------------------------------ + * Flags 1: drop all multicast packets when device suspend + * Flags 0: drop multicast packets except white list when device suspend + *------------------------------------------------------------------------------ + */ +#define CFG_SUPPORT_DROP_ALL_MC_PACKET 0 + +/*------------------------------------------------------------------------------ + * Auto Channel Selection maximun channel number + *------------------------------------------------------------------------------ + */ +/* ARRAY_SIZE(mtk_5ghz_channels) + ARRAY_SIZE(mtk_2ghz_channels) */ +#define MAX_CHN_NUM 39 + +#define MAX_2G_BAND_CHN_NUM 14 +#define MAX_5G_BAND_CHN_NUM (MAX_CHN_NUM - MAX_2G_BAND_CHN_NUM) +#define ACS_PRINT_BUFFER_LEN 200 + +/*------------------------------------------------------------------------------ + * Flags and Parameters for Ad-Hoc + *------------------------------------------------------------------------------ + */ +#define CFG_INIT_ADHOC_FREQ (2462000) +#define CFG_INIT_ADHOC_MODE AD_HOC_MODE_MIXED_11BG +#define CFG_INIT_ADHOC_BEACON_INTERVAL (100) +#define CFG_INIT_ADHOC_ATIM_WINDOW (0) + +/*------------------------------------------------------------------------------ + * Maximum scan SSID number and channel number + * Should be aligned with FW scan command + *------------------------------------------------------------------------------ + */ +#define SCAN_CMD_SSID_NUM (4) +#define SCAN_CMD_CHNL_NUM (32) + +#if 0 +/* to be compatible with old FW, we set ssid num to 0 here, + * we should set correct num when query of scan capability from FW is done + */ +#define SCAN_CMD_EXT_SSID_NUM (0) +#define SCAN_CMD_EXT_CHNL_NUM (0) +#else +#define SCAN_CMD_EXT_SSID_NUM (6) +#define SCAN_CMD_EXT_CHNL_NUM (32) +#endif +#define CFG_SCAN_SSID_MAX_NUM (SCAN_CMD_SSID_NUM+SCAN_CMD_EXT_SSID_NUM) +#define MAXIMUM_OPERATION_CHANNEL_LIST (SCAN_CMD_CHNL_NUM+SCAN_CMD_EXT_CHNL_NUM) + + +/*------------------------------------------------------------------------------ + * Flags and Parameters for Load Setup Default + *------------------------------------------------------------------------------ + */ + +/*------------------------------------------------------------------------------ + * Flags for enable 802.11A Band setting + *------------------------------------------------------------------------------ + */ + +/*------------------------------------------------------------------------------ + * Flags and Parameters for Interrupt Process + *------------------------------------------------------------------------------ + */ +#define CFG_IST_LOOP_COUNT HIF_IST_LOOP_COUNT + +#define CFG_INT_WRITE_CLEAR 0 + +/* 2 Flags for Driver Debug Options */ +/*------------------------------------------------------------------------------ + * Flags of TX Debug Option. NOTE(Kevin): Confirm with SA before modifying + * following flags. + *------------------------------------------------------------------------------ + */ +/*!< 1: Debug statistics usage of MGMT Buffer */ +/* 0: Disable */ +#define CFG_DBG_MGT_BUF 1 + +#define CFG_HIF_STATISTICS 0 + +#define CFG_HIF_RX_STARVATION_WARNING 0 + +#define CFG_RX_PKTS_DUMP 0 + +#define CFG_SUPPORT_STATISTICS 1 + +#define CFG_ASSERT_DUMP 1 + +#define CFG_SUPPORT_TRACE_TC4 1 +/*------------------------------------------------------------------------------ + * Flags of Firmware Download Option. + *------------------------------------------------------------------------------ + */ +#define CFG_ENABLE_FW_DOWNLOAD 1 + +#define CFG_ENABLE_FW_DOWNLOAD_ACK 1 + +#ifndef CFG_WIFI_IP_SET +#define CFG_WIFI_IP_SET 1 +#endif + +/*------------------------------------------------------------------------------ + * Flags of Bluetooth-over-WiFi (BT 3.0 + HS) support + *------------------------------------------------------------------------------ + */ + +#define CFG_ENABLE_BT_OVER_WIFI 0 + +#define CFG_BOW_SEPARATE_DATA_PATH 1 + +#define CFG_BOW_PHYSICAL_LINK_NUM 4 + +#define CFG_BOW_LIMIT_AIS_CHNL 1 + +#define CFG_BOW_SUPPORT_11N 1 + +#define CFG_BOW_RATE_LIMITATION 1 + +/*------------------------------------------------------------------------------ + * Flags of Wi-Fi Direct support + *------------------------------------------------------------------------------ + */ +/*------------------------------------------------------------------------------ + * Support reporting all BSS networks to cfg80211 kernel when scan + * request is from P2P interface + * Originally only P2P networks will be reported when scan request is from p2p0 + *------------------------------------------------------------------------------ + */ +#ifndef CFG_P2P_SCAN_REPORT_ALL_BSS +#define CFG_P2P_SCAN_REPORT_ALL_BSS 0 +#endif + +/* Allow connection with no P2P IE device */ +#ifndef CFG_P2P_CONNECT_ALL_BSS +#define CFG_P2P_CONNECT_ALL_BSS 0 +#endif + +/* Allow setting max P2P GO client count */ +#ifndef CFG_P2P_DEFAULT_CLIENT_COUNT +#define CFG_P2P_DEFAULT_CLIENT_COUNT 0 +#endif + +/*------------------------------------------------------------------------------ + * Flags for GTK rekey offload + *------------------------------------------------------------------------------ + */ + +#ifdef LINUX +#ifdef CONFIG_X86 +#define CFG_ENABLE_WIFI_DIRECT 1 +#define CFG_SUPPORT_802_11W 1 +#define CONFIG_SUPPORT_GTK_REKEY 1 +#else +#define CFG_ENABLE_WIFI_DIRECT 1 + +/*!< 0(default): Disable 802.11W */ +#define CFG_SUPPORT_802_11W 1 + +#define CONFIG_SUPPORT_GTK_REKEY 1 +#endif +#else /* !LINUX */ +#define CFG_ENABLE_WIFI_DIRECT 0 +#define CFG_SUPPORT_802_11W 0 /* Not support at WinXP */ +#endif /* LINUX */ + +#define CFG_SUPPORT_PERSISTENT_GROUP 0 + +#define CFG_TEST_WIFI_DIRECT_GO 0 + +#define CFG_TEST_ANDROID_DIRECT_GO 0 + +#define CFG_UNITEST_P2P 0 + +#ifndef CONFIG_WLAN_DRV_BUILD_IN +#define CONFIG_WLAN_DRV_BUILD_IN 0 +#endif + +/* + * Enable cfg80211 option after Android 2.2(Froyo) is suggested, + * cfg80211 on linux 2.6.29 is not mature yet + */ +#define CFG_ENABLE_WIFI_DIRECT_CFG_80211 1 + +#define CFG_SUPPORT_HOTSPOT_OPTIMIZATION 0 +#define CFG_HOTSPOT_OPTIMIZATION_BEACON_INTERVAL 300 +#define CFG_HOTSPOT_OPTIMIZATION_DTIM 1 +#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE +#define CFG_AUTO_CHANNEL_SEL_SUPPORT 0 +#else +#define CFG_AUTO_CHANNEL_SEL_SUPPORT 1 +#endif + +#define CFG_SUPPORT_SOFTAP_WPA3 1 + +#define CFG_HOTSPOT_SUPPORT_ADJUST_SCC 1 + +#if CFG_TC1_FEATURE +#define CFG_HOTSPOT_SUPPORT_FORCE_ACS_SCC 0 +#elif CFG_TC10_FEATURE +#define CFG_HOTSPOT_SUPPORT_FORCE_ACS_SCC 1 +#else +#define CFG_HOTSPOT_SUPPORT_FORCE_ACS_SCC 0 +#endif + +#ifndef CFG_ENABLE_UNIFY_WIPHY +#define CFG_ENABLE_UNIFY_WIPHY 1 +#endif + +#define CFG_ENABLE_OFFCHANNEL_TX 1 + +/*------------------------------------------------------------------------------ + * Configuration Flags (Linux Only) + *------------------------------------------------------------------------------ + */ +#define CFG_SUPPORT_EXT_CONFIG 0 + +/*------------------------------------------------------------------------------ + * Statistics Buffering Mechanism + *------------------------------------------------------------------------------ + */ +#if CFG_SUPPORT_PERFORMANCE_TEST +#define CFG_ENABLE_STATISTICS_BUFFERING 1 +#else +#define CFG_ENABLE_STATISTICS_BUFFERING 0 +#endif +#define CFG_STATISTICS_VALID_CYCLE 2000 +#define CFG_LINK_QUALITY_VALID_PERIOD 500 + +/*------------------------------------------------------------------------------ + * Migration Option + *------------------------------------------------------------------------------ + */ +#define CFG_SUPPORT_ADHOC 1 +#define CFG_SUPPORT_AAA 1 + +#define CFG_SUPPORT_BCM 0 +#define CFG_SUPPORT_BCM_BWCS 0 +#define CFG_SUPPORT_BCM_BWCS_DEBUG 0 + +#define CFG_SUPPORT_RDD_TEST_MODE 0 + +#define CFG_SUPPORT_PWR_MGT 1 + +#define CFG_ENABLE_HOTSPOT_PRIVACY_CHECK 1 + +#define CFG_MGMT_FRAME_HANDLING 1 + +#define CFG_MGMT_HW_ACCESS_REPLACEMENT 0 + +#if CFG_SUPPORT_PERFORMANCE_TEST + +#else + +#endif + +#define CFG_SUPPORT_AIS_5GHZ 1 +#define CFG_SUPPORT_DETECT_SECURITY_MODE_CHANGE 0 + +/*------------------------------------------------------------------------------ + * Option for NVRAM and Version Checking + *------------------------------------------------------------------------------ + */ +#define CFG_SUPPORT_NVRAM 1 +#define CFG_NVRAM_EXISTENCE_CHECK 1 +#define CFG_SW_NVRAM_VERSION_CHECK 1 +#define CFG_SUPPORT_NIC_CAPABILITY 1 + +/*------------------------------------------------------------------------------ + * CONFIG_TITLE : Stress Test Option + * OWNER : Puff Wen + * Description : For stress test only. DO NOT enable it while normal operation + *------------------------------------------------------------------------------ + */ +#define CFG_STRESS_TEST_SUPPORT 0 + +/*------------------------------------------------------------------------------ + * Flags for LINT + *------------------------------------------------------------------------------ + */ +#define LINT_SAVE_AND_DISABLE /*lint -save -e* */ + +#define LINT_RESTORE /*lint -restore */ + +#define LINT_EXT_HEADER_BEGIN LINT_SAVE_AND_DISABLE + +#define LINT_EXT_HEADER_END LINT_RESTORE + +/*------------------------------------------------------------------------------ + * Flags of Features + *------------------------------------------------------------------------------ + */ + +#define CFG_SUPPORT_TDLS 1 + +/* Enable/disable QoS TX, AMPDU */ +#define CFG_SUPPORT_QOS 1 + +#define CFG_SUPPORT_AMPDU_TX 1 +#define CFG_SUPPORT_AMPDU_RX 1 + +/* Enable/disable TS-related Action frames handling */ +#define CFG_SUPPORT_TSPEC 0 +#define CFG_SUPPORT_UAPSD 1 +#define CFG_SUPPORT_UL_PSMP 0 + +/* Roaming System */ +#ifndef CFG_SUPPORT_ROAMING +#define CFG_SUPPORT_ROAMING 1 +#endif + +#if (CFG_SUPPORT_ROAMING == 1) + +/* Roaming feature: skip roaming when only one ESSID AP + * Need Android background scan + * if no roaming event occurred + * to trigger roaming scan + * after skip roaming in one ESSID AP case + */ +#define CFG_SUPPORT_ROAMING_SKIP_ONE_AP 0 +#define CFG_SUPPORT_DRIVER_ROAMING 1 +#else +#define CFG_SUPPORT_ROAMING_SKIP_ONE_AP 0 +#define CFG_SUPPORT_DRIVER_ROAMING 0 + +#endif /* CFG_SUPPORT_ROAMING */ + +#define CFG_SUPPORT_SWCR 1 + +#define CFG_SUPPORT_ANTI_PIRACY 1 + +#define CFG_SUPPORT_OSC_SETTING 1 + +#define CFG_SUPPORT_P2P_RSSI_QUERY 0 + +#define CFG_SUPPORT_P2P_GO_OFFLOAD_PROBE_RSP 0 + +#define CFG_SHOW_MACADDR_SOURCE 1 + +#if BUILD_QA_DBG +#define CFG_SHOW_FULL_MACADDR 1 +#else +#define CFG_SHOW_FULL_MACADDR 0 +#endif + +#ifndef CFG_SUPPORT_VO_ENTERPRISE +#define CFG_SUPPORT_VO_ENTERPRISE 1 +#endif +#define CFG_SUPPORT_WMM_AC 1 +#if CFG_SUPPORT_VO_ENTERPRISE +#define CFG_SUPPORT_802_11R 1 +#define CFG_SUPPORT_802_11K 1 +#else +#define CFG_SUPPORT_802_11R 0 +#define CFG_SUPPORT_802_11K 0 +#endif +#define CFG_SUPPORT_MBO 1 + +#define CFG_SUPPORT_SUPPLICANT_SME 0 + +#if (CFG_SUPPORT_802_11K == 1) && (CFG_SUPPORT_SUPPLICANT_SME == 1) +/* Enable to do beacon reports by supplicant. + * Beacon report is a sub-feature of 802_11K(RRM) + * Supplicant only support RRM when SME supported. + */ +#define CFG_SUPPORT_RM_BEACON_REPORT_BY_SUPPLICANT 0 +#else +#define CFG_SUPPORT_RM_BEACON_REPORT_BY_SUPPLICANT 0 +#endif + +/* Support 802.11v Wireless Network Management */ +#ifndef CFG_SUPPORT_802_11V +#define CFG_SUPPORT_802_11V 1 +#endif +#if CFG_SUPPORT_802_11V +#define CFG_SUPPORT_802_11V_BSS_TRANSITION_MGT 1 +#else +#define CFG_SUPPORT_802_11V_BSS_TRANSITION_MGT 0 +#endif +#define CFG_SUPPORT_802_11V_TIMING_MEASUREMENT 0 + +#if (CFG_SUPPORT_802_11V_TIMING_MEASUREMENT == 1) && \ + (CFG_SUPPORT_802_11V == 0) +#error \ +"CFG_SUPPORT_802_11V should be 1 once CFG_SUPPORT_802_11V_TIMING_MEASUREMENT equals to 1" +#endif + +#define WNM_UNIT_TEST CFG_SUPPORT_802_11V + +#define CFG_SUPPORT_802_11V_MBSSID 0 +#if (CFG_SUPPORT_802_11AX == 1) +/*11v MBSSID is mandatory for 11ax*/ +#undef CFG_SUPPORT_802_11V_MBSSID +#define CFG_SUPPORT_802_11V_MBSSID 1 +#endif + +#define CFG_SUPPORT_PPR2 1 +#define CFG_DRIVER_COMPOSE_ASSOC_REQ 1 +#define CFG_SUPPORT_802_11AC 1 +#define CFG_STRICT_CHECK_CAPINFO_PRIVACY 0 + +#define CFG_SUPPORT_WFD 1 +#define CFG_SUPPORT_WFD_COMPOSE_IE 1 + +/* Support Customer vendor IE */ +#define CFG_SUPPORT_CUSTOM_VENDOR_IE 1 + +#define CFG_SUPPORT_HOTSPOT_WPS_MANAGER 1 +#define CFG_SUPPORT_NFC_BEAM_PLUS 1 + +/* Refer to CONFIG_MTK_STAGE_SCAN */ +#define CFG_MTK_STAGE_SCAN 1 + +/* Enable driver support multicore */ +#define CFG_SUPPORT_MULTITHREAD 1 + +#define CFG_SUPPORT_MTK_SYNERGY 1 + +#define CFG_SUPPORT_VHT_IE_IN_2G 1 + +#define CFG_SUPPORT_PWR_LIMIT_COUNTRY 1 + +#define CFG_SUPPORT_DYNAMIC_PWR_LIMIT 1 + +#define CFG_FIX_2_TX_PORT 0 + +#define CFG_CHANGE_CRITICAL_PACKET_PRIORITY 1 + +/*------------------------------------------------------------------------------ + * Flags of bus error tolerance + *------------------------------------------------------------------------------ + */ +#define CFG_FORCE_RESET_UNDER_BUS_ERROR 0 + +/*------------------------------------------------------------------------------ + * Build Date Code Integration + *------------------------------------------------------------------------------ + */ +#define CFG_SUPPORT_BUILD_DATE_CODE 0 + +/*------------------------------------------------------------------------------ + * Flags of SDIO test pattern support + *------------------------------------------------------------------------------ + */ +#define CFG_SUPPORT_SDIO_READ_WRITE_PATTERN 1 + +/*------------------------------------------------------------------------------ + * Flags of Workaround + *------------------------------------------------------------------------------ + */ +#define CFG_ENABLE_READ_EXTRA_4_BYTES 1 + +/* Handle IOT issue for 11ac certification */ +#define CFG_OPMODE_CONFLICT_OPINFO 1 + +/*------------------------------------------------------------------------------ + * Flags of Packet Lifetime Profiling Mechanism + *------------------------------------------------------------------------------ + */ +#define CFG_ENABLE_PKT_LIFETIME_PROFILE 1 +#define CFG_PRINT_PKT_LIFETIME_PROFILE 0 + +#define CFG_ENABLE_PER_STA_STATISTICS 1 + +#define CFG_ENABLE_PER_STA_STATISTICS_LOG 1 + +/*------------------------------------------------------------------------------ + * Flags for prepare the FW compile flag + *------------------------------------------------------------------------------ + */ +#define COMPILE_FLAG0_GET_STA_LINK_STATUS (1<<0) +#define COMPILE_FLAG0_WFD_ENHANCEMENT_PROTECT (1<<1) + +/*------------------------------------------------------------------------------ + * Flags of Batch Scan SUPPORT + *------------------------------------------------------------------------------ + */ +#define CFG_SUPPORT_BATCH_SCAN (0) +#define CFG_BATCH_MAX_MSCAN (2) + +/*------------------------------------------------------------------------------ + * Flags of SCHEDULE SCAN SUPPORT + *------------------------------------------------------------------------------ + */ +#define CFG_SUPPORT_SCHED_SCAN (1) +#define SCHED_SCAN_CMD_VERSION (1) + +/* this value should be aligned to auSsid in struct CMD_SCHED_SCAN_REQ */ +#define CFG_SCAN_HIDDEN_SSID_MAX_NUM (10) +/* this value should be aligned to auMatchSsid in struct CMD_SCHED_SCAN_REQ */ +#define CFG_SCAN_SSID_MATCH_MAX_NUM (16) + +/*------------------------------------------------------------------------------ + * Full2Partial Scan SUPPORT + *------------------------------------------------------------------------------ + */ +/* During a full2partial scan period, all online full scan requests would be + * changed to partial scan. The unit of this value is second + */ +#define CFG_SUPPORT_FULL2PARTIAL_SCAN (1) +#define CFG_SCAN_FULL2PARTIAL_PERIOD (60) + +/*------------------------------------------------------------------------------ + * Value of scan cache result + *------------------------------------------------------------------------------ + */ +#define CFG_SUPPORT_SCAN_CACHE_RESULT (1) +#define CFG_SCAN_CACHE_RESULT_PERIOD (7000) /* Unit: ms */ +#define CFG_SCAN_CACHE_MIN_CHANNEL_NUM (10) + +/*------------------------------------------------------------------------------ + * Default value: the duration in ms to check TRX + * while the beacon timeout event comes. + * This is the default value for + * prAdapter->rWifiVar.u4BeaconTimoutFilterDurationMs + * can customize + * 1. by project's requirement in this default value + * 2. or by define in wifi.cfg directly (BeaconTimoutFilterDurationMs) + * if the value set to 0, it means disable the filter. + * if the value set to 2000, it means the duration of fitler is 2000 ms + *------------------------------------------------------------------------------ + */ +#define CFG_BEACON_TIMEOUT_FILTER_DURATION_DEFAULT_VALUE 2000 + +/*------------------------------------------------------------------------------ + * Flags of Random MAC support + *------------------------------------------------------------------------------ + */ +#define CFG_SUPPORT_SCAN_RANDOM_MAC (1) + +/*------------------------------------------------------------------------------ + * Flags of Sniffer SUPPORT + *------------------------------------------------------------------------------ + */ +#define CFG_SUPPORT_SNIFFER 1 + +#define WLAN_INCLUDE_PROC 1 + +#if CFG_TC10_FEATURE +#define WLAN_INCLUDE_SYS 1 +#else +#define WLAN_INCLUDE_SYS 0 +#endif + +/*------------------------------------------------------------------------------ + * Flags of Sniffer SUPPORT + *------------------------------------------------------------------------------ + */ +#define CFG_DUAL_P2PLIKE_INTERFACE 1 + +#define RUNNING_P2P_MODE 0 +#define RUNNING_AP_MODE 1 +#define RUNNING_DUAL_AP_MODE 2 +#define RUNNING_P2P_AP_MODE 3 +#define RUNNING_P2P_MODE_NUM 4 + +/*------------------------------------------------------------------------------ + * Flags of MSP SUPPORT + *------------------------------------------------------------------------------ + */ +#define CFG_SUPPORT_MSP 1 + + + +/*------------------------------------------------------------------------------ + * Flags of driver fw customization + *------------------------------------------------------------------------------ + */ + +#define CFG_SUPPORT_EASY_DEBUG 1 + + +/*------------------------------------------------------------------------------ + * Flags of driver delay calibration atfer efuse buffer mode CMD + *------------------------------------------------------------------------------ + */ + +#define CFG_EFUSE_BUFFER_MODE_DELAY_CAL 1 + +/*------------------------------------------------------------------------------ + * Flags of Drop Packet Replay SUPPORT + *------------------------------------------------------------------------------ + */ +#define CFG_SUPPORT_REPLAY_DETECTION 1 + +/*------------------------------------------------------------------------------ + * Flags of driver EEPROM pages for QA tool + *------------------------------------------------------------------------------ + */ + +#define CFG_EEPROM_PAGE_ACCESS 1 + +/*------------------------------------------------------------------------------ + * Flags for HOST_OFFLOAD + *------------------------------------------------------------------------------ + */ + +#define CFG_SUPPORT_WIFI_HOST_OFFLOAD 1 + +/*------------------------------------------------------------------------------ + * Flags for DBDC Feature + *------------------------------------------------------------------------------ + */ + +#define CFG_SUPPORT_DBDC 1 +#define CFG_SUPPORT_DBDC_NO_BLOCKING_OPMODE 1 +#define CFG_SUPPORT_SAP_DFS_CHANNEL 1 + +/*------------------------------------------------------------------------------ + * Flags for Using TC4 Resource in ROM code stage + *------------------------------------------------------------------------------ + */ + +#define CFG_USE_TC4_RESOURCE_FOR_INIT_CMD 0 + +/*------------------------------------------------------------------------------ + * Flags for Efuse Start and End address report from FW + *------------------------------------------------------------------------------ + */ + +#define CFG_FW_Report_Efuse_Address 1 + +/*------------------------------------------------------------------------------ + * FW name max length + *------------------------------------------------------------------------------ + */ +#define CFG_FW_NAME_MAX_LEN (64) + +/*------------------------------------------------------------------------------ + * Support WMT WIFI Path Config + *------------------------------------------------------------------------------ + */ +#define CFG_WMT_WIFI_PATH_SUPPORT 0 + +/*------------------------------------------------------------------------------ + * Support CFG_SISO_SW_DEVELOP + *------------------------------------------------------------------------------ + */ +#define CFG_SISO_SW_DEVELOP 1 + +/*------------------------------------------------------------------------------ + * Support spatial extension control + *------------------------------------------------------------------------------ + */ +#define CFG_SUPPORT_SPE_IDX_CONTROL 1 + +/*------------------------------------------------------------------------------ + * Flags for a Goal for MT6632 : Cal Result Backup in Host or NVRam when Android + * Boot + *------------------------------------------------------------------------------ + */ +#if 0 /*(MTK_WCN_HIF_SDIO) : 20161003 Default Off, later will enable + * by MTK_WCN_HIF_SDIO + */ +#define CFG_SUPPORT_CAL_RESULT_BACKUP_TO_HOST 1 +#define CFG_SUPPORT_CAL_RESULT_BACKUP_TO_HOST_DBGLOG 0 +#else +#define CFG_SUPPORT_CAL_RESULT_BACKUP_TO_HOST 0 +#define CFG_SUPPORT_CAL_RESULT_BACKUP_TO_HOST_DBGLOG 0 +#endif + +/*------------------------------------------------------------------------------ + * Enable SDIO 1-bit Data Mode. (Usually debug only) + *------------------------------------------------------------------------------ + */ +#define CFG_SDIO_1BIT_DATA_MODE 0 + +/*------------------------------------------------------------------------------ + * Single Sku + *------------------------------------------------------------------------------ + */ +#define CFG_SUPPORT_SINGLE_SKU 1 +#ifndef CFG_SUPPORT_SINGLE_SKU_LOCAL_DB +#define CFG_SUPPORT_SINGLE_SKU_LOCAL_DB 1 +#endif + + +/*------------------------------------------------------------------------------ + * Direct Control for RF/PHY/BB/MAC for Manual Configuration via command/api + *------------------------------------------------------------------------------ + */ +#define CFG_SUPPORT_ADVANCE_CONTROL 1 + + +/*------------------------------------------------------------------------------ + * Driver pre-allocate total size of memory in one time + *------------------------------------------------------------------------------ + */ +#ifndef CFG_PRE_ALLOCATION_IO_BUFFER +#define CFG_PRE_ALLOCATION_IO_BUFFER 0 +#endif + +/*------------------------------------------------------------------------------ + * Auto enable SDIO asynchronous interrupt mode + *------------------------------------------------------------------------------ + */ +#define CFG_SDIO_ASYNC_IRQ_AUTO_ENABLE 1 + +/*------------------------------------------------------------------------------ + * Flags to force enable performance monitor even when screen is OFF + *------------------------------------------------------------------------------ + */ +#define CFG_FORCE_ENABLE_PERF_MONITOR 0 + +/*------------------------------------------------------------------------------ + * Flags to ignore invalid auth tsn issue (ex. ALPS03089071) + *------------------------------------------------------------------------------ + */ +#define CFG_IGNORE_INVALID_AUTH_TSN 1 + +/*------------------------------------------------------------------------------ + * Flags of Network Controlled HandOver(NCHO) support + * TC10 only: To improve the voice quality during handover, + * the NCHO is required to precisely control scanning parameters + * CFG_SUPPORT_NCHO: 1: support, 0: not support + * CFG_SUPPORT_NCHO_AUTO_ENABLE: sub-feature depends with CFG_SUPPORT_NCHO + *------------------------------------------------------------------------------ + */ +#define CFG_SUPPORT_NCHO 0 +#define CFG_SUPPORT_NCHO_AUTO_ENABLE 0 + +/*------------------------------------------------------------------------------ + * Flags of Key Word Exception Mechanism + *------------------------------------------------------------------------------ + */ +#define CFG_ENABLE_KEYWORD_EXCEPTION_MECHANISM 0 + +/*------------------------------------------------------------------------------ + * Flags of WPA3 support + *------------------------------------------------------------------------------ + */ + +#define CFG_SUPPORT_WPA3 1 + +/*------------------------------------------------------------------------------ + * Driver supports preferred frequency list for p2p operating channel + *------------------------------------------------------------------------------ + */ +#define CFG_SUPPORT_P2P_PREFERRED_FREQ_LIST 1 + +/*------------------------------------------------------------------------------ + * Flag used for P2P GO to find the best channel list + * Value 0: Disable + * Value 1: Enable + * Note: Must Enable CFG_SUPPORT_P2P_PREFERRED_FREQ_LIST in advance + *------------------------------------------------------------------------------ + */ +#define CFG_SUPPORT_P2PGO_ACS 1 + +/*----------------------------------------------------------------------------- +* Flags to support IOT AP blacklist +*------------------------------------------------------------------------------ +*/ +#ifndef CFG_SUPPORT_IOT_AP_BLACKLIST +#if CFG_SUPPORT_DBDC +#define CFG_SUPPORT_IOT_AP_BLACKLIST 1 +#else +#define CFG_SUPPORT_IOT_AP_BLACKLIST 0 +#endif +#endif + +#if CFG_SUPPORT_IOT_AP_BLACKLIST +#define CFG_IOT_AP_RULE_MAX_CNT 32 +#define CFG_IOT_AP_DATA_MAX_LEN 16 +#endif +/*------------------------------------------------------------------------------ + * Driver supports reporting max tx rate instead of current tx rate + * in mtk_cfg80211_get_station + *------------------------------------------------------------------------------ + */ +#define CFG_REPORT_MAX_TX_RATE 0 + +/*------------------------------------------------------------------------------ + * Link Quality Monitor + * Link quality monitor execution period base on performance monitor timer + * CFG_LINK_QUALITY_MONITOR_UPDATE_FREQUENCY base on PERF_MON_UPDATE_INTERVAL + *------------------------------------------------------------------------------ + */ +#define CFG_SUPPORT_LINK_QUALITY_MONITOR +#ifdef CFG_SUPPORT_LINK_QUALITY_MONITOR +#define CFG_LINK_QUALITY_MONITOR_UPDATE_FREQUENCY 1 +#endif /* CFG_SUPPORT_LINK_QUALITY_MONITOR */ + +/*------------------------------------------------------------------------------ + * Driver supports SYS DVT automation + *------------------------------------------------------------------------------ + */ +#ifndef CFG_SUPPORT_WIFI_SYSDVT +#define CFG_SUPPORT_WIFI_SYSDVT 0 +#endif + +#ifndef CFG_SUPPORT_DMASHDL_SYSDVT +#define CFG_SUPPORT_DMASHDL_SYSDVT 0 +#endif + +/*------------------------------------------------------------------------------ + * Flags of using wlan_assistant to read/write NVRAM + *------------------------------------------------------------------------------ + */ +#define CFG_WLAN_ASSISTANT_NVRAM 1 + +/*------------------------------------------------------------------------------ + * SW handles WTBL_SEARCH_FAIL + *------------------------------------------------------------------------------ + */ +#define CFG_WIFI_SW_WTBL_SEARCH_FAIL 1 + +/*------------------------------------------------------------------------------ + * SW enables CIPHER_MISMATCH + *------------------------------------------------------------------------------ + */ +#define CFG_WIFI_SW_CIPHER_MISMATCH 1 + +/*------------------------------------------------------------------------------ + * CONNINFRA SUPPORT (Without WMT) + * CFG_SUPPORT_CONNINFRA: 1 : conninfra driver exist + * 0 : conninfra driver doesn't exist + * We replace WMT driver with CONNINFRA driver in mobile project + * after connac2.0. + * CFG_MTK_ANDROID_WMT is used to separate between mobile project and others. + * Although WMT driver is removed, CFG_MTK_ANDROID_WMT still need to be set 1 + * for some code flow in mobile gen4m. + *------------------------------------------------------------------------------ + */ +#ifndef CFG_SUPPORT_CONNINFRA +#define CFG_SUPPORT_CONNINFRA 0 +#endif + +#ifndef CFG_SUPPORT_PRE_ON_PHY_ACTION +#define CFG_SUPPORT_PRE_ON_PHY_ACTION 0 +#endif + +#ifndef CFG_POWER_ON_DOWNLOAD_EMI_ROM_PATCH +#define CFG_POWER_ON_DOWNLOAD_EMI_ROM_PATCH 0 +#endif + +#ifndef CFG_DOWNLOAD_DYN_MEMORY_MAP +#define CFG_DOWNLOAD_DYN_MEMORY_MAP 0 +#endif + +#ifndef CFG_ROM_PATCH_NO_SEM_CTRL +#define CFG_ROM_PATCH_NO_SEM_CTRL 0 +#endif + +/*------------------------------------------------------------------------------ + * Flags of Disconnect with disable channel based on REGD update + *------------------------------------------------------------------------------ + */ +#ifndef CFG_SUPPORT_REGD_UPDATE_DISCONNECT_ALLOWED +#define CFG_SUPPORT_REGD_UPDATE_DISCONNECT_ALLOWED 0 +#endif + +/*------------------------------------------------------------------------------ + * Notify clients to reconnect when channel switch in hotspot mode to avoid IOT + * issues, eg. cross band switch. + *------------------------------------------------------------------------------ + */ +#define CFG_SEND_DEAUTH_DURING_CHNL_SWITCH 1 + +/*------------------------------------------------------------------------------ + *Smart Gear Feature Configure + *------------------------------------------------------------------------------ +*/ +#ifndef CFG_SUPPORT_SMART_GEAR +#define CFG_SUPPORT_SMART_GEAR 0 +#endif + +/*------------------------------------------------------------------------------ + * Flag used for AIS persistent netdev creating. + * Value 0: Create & register AIS netdev for each wifi on, + * and unregister & free AIS netdev for each wifi off. + * Value 1: Create & register AIS netdev for first wifi on, + * and unregister & free AIS netdev during module exit. + *------------------------------------------------------------------------------ + */ +#define CFG_SUPPORT_PERSIST_NETDEV 1 + + +/*------------------------------------------------------------------------------ + * Dynamic tx power control: + * Support additional tx power setting on OFDM + * + * No define: CCK,HT20L,HT20H,HT40L,HT40H,HT80L,HT80H,HT160L,HT160H + * Defined: CCK,OFDM_L,OFDM_H,HT20L,HT20H,HT40L,HT40H,HT80L,HT80H,HT160L,HT160H + * + * note: need to confirm firmware support this feature + * COUNTRY_CHANNEL_TXPOWER_LIMIT_TYPE_COMP_11AG_11N + *------------------------------------------------------------------------------ + */ +#define CFG_SUPPORT_DYNA_TX_PWR_CTRL_OFDM_SETTING 0 + +/*------------------------------------------------------------------------------ + * tx power control: + * Support additional tx power setting for HE + * + * support power limit for RU26/RU52/RU104/RU242/RU484/RU996 + * + * note: need to confirm firmware support HE (802.11AX) + *------------------------------------------------------------------------------ + */ +#if (CFG_SUPPORT_802_11AX == 1) +#define CFG_SUPPORT_PWR_LIMIT_HE 1 +#else +#define CFG_SUPPORT_PWR_LIMIT_HE 0 +#endif + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +#endif /* _CONFIG_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/debug.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/debug.h new file mode 100644 index 0000000000000000000000000000000000000000..f058758cd222bfca272abcd009dc03e45c9549b7 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/debug.h @@ -0,0 +1,676 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: include/debug.h + */ + +/*! \file debug.h + * \brief Definition of SW debugging level. + * + * In this file, it describes the definition of various SW debugging levels + * and assert functions. + */ + +#ifndef _DEBUG_H +#define _DEBUG_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ +#ifndef BUILD_QA_DBG +#define BUILD_QA_DBG 0 +#endif + +#define DBG_DISABLE_ALL_LOG 0 + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "gl_typedef.h" + +extern u_int8_t wlan_fb_power_down; +extern uint8_t aucDebugModule[]; +extern uint32_t au4LogLevel[]; + +extern void set_logtoomuch_enable(int value) __attribute__((weak)); +extern int get_logtoomuch_enable(void) __attribute__((weak)); + +extern struct MIB_INFO_STAT g_arMibInfo[ENUM_BAND_NUM]; + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +/* Define debug category (class): + * (1) ERROR (2) WARN (3) STATE (4) EVENT (5) TRACE (6) INFO (7) LOUD (8) TEMP + */ +#define DBG_CLASS_ERROR BIT(0) +#define DBG_CLASS_WARN BIT(1) +#define DBG_CLASS_STATE BIT(2) +#define DBG_CLASS_EVENT BIT(3) +#define DBG_CLASS_TRACE BIT(4) +#define DBG_CLASS_INFO BIT(5) +#define DBG_CLASS_LOUD BIT(6) +#define DBG_CLASS_TEMP BIT(7) +#define DBG_CLASS_MASK BITS(0, 7) + +#define DBG_LOG_LEVEL_DEFAULT \ + (DBG_CLASS_ERROR | \ + DBG_CLASS_WARN | \ + DBG_CLASS_STATE | \ + DBG_CLASS_EVENT | \ + DBG_CLASS_INFO) +#define DBG_LOG_LEVEL_MORE \ + (DBG_LOG_LEVEL_DEFAULT | \ + DBG_CLASS_TRACE) +#define DBG_LOG_LEVEL_EXTREME \ + (DBG_LOG_LEVEL_MORE | \ + DBG_CLASS_LOUD) + +#if defined(LINUX) +#define DBG_PRINTF_64BIT_DEC "lld" +#else /* Windows */ +#define DBG_PRINTF_64BIT_DEC "I64d" +#endif +#define DBG_ALL_MODULE_IDX 0xFFFFFFFF + +#define DEG_HIF_ALL BIT(0) +#define DEG_HIF_HOST_CSR BIT(1) +#define DEG_HIF_PDMA BIT(2) +#define DEG_HIF_DMASCH BIT(3) +#define DEG_HIF_PSE BIT(4) +#define DEG_HIF_PLE BIT(5) +#define DEG_HIF_MAC BIT(6) +#define DEG_HIF_PHY BIT(7) + +#define DEG_HIF_DEFAULT_DUMP \ + (DEG_HIF_HOST_CSR | DEG_HIF_PDMA | DEG_HIF_DMASCH | \ + DEG_HIF_PSE | DEG_HIF_PLE) + +#define HIF_CHK_TX_HANG BIT(1) +#define HIF_DRV_SER BIT(2) + +#define DUMP_MEM_SIZE 64 + +#if CFG_SUPPORT_ADVANCE_CONTROL +#define CMD_SW_DBGCTL_ADVCTL_SET_ID 0xa1260000 +#define CMD_SW_DBGCTL_ADVCTL_GET_ID 0xb1260000 +#endif + +#define CFG_STAT_DBG_PEER_NUM 10 +#define AGG_RANGE_SEL_4BYTE_NUM 4 + +#define AGG_RANGE_SEL_0_MASK BITS(0, 7) +#define AGG_RANGE_SEL_0_OFFSET 0 +#define AGG_RANGE_SEL_1_MASK BITS(8, 15) +#define AGG_RANGE_SEL_1_OFFSET 8 +#define AGG_RANGE_SEL_2_MASK BITS(16, 23) +#define AGG_RANGE_SEL_2_OFFSET 16 +#define AGG_RANGE_SEL_3_MASK BITS(24, 31) +#define AGG_RANGE_SEL_3_OFFSET 24 +#define AGG_RANGE_SEL_4_MASK AGG_RANGE_SEL_0_MASK +#define AGG_RANGE_SEL_4_OFFSET AGG_RANGE_SEL_0_OFFSET +#define AGG_RANGE_SEL_5_MASK AGG_RANGE_SEL_1_MASK +#define AGG_RANGE_SEL_5_OFFSET AGG_RANGE_SEL_1_OFFSET +#define AGG_RANGE_SEL_6_MASK AGG_RANGE_SEL_2_MASK +#define AGG_RANGE_SEL_6_OFFSET AGG_RANGE_SEL_2_OFFSET + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +/* Define debug module index */ +enum ENUM_DBG_MODULE { + DBG_INIT_IDX = 0, /* 0x00 *//* For driver initial */ + DBG_HAL_IDX, /* 0x01 *//* For HAL(HW) Layer */ + DBG_INTR_IDX, /* 0x02 *//* For Interrupt */ + DBG_REQ_IDX, /* 0x03 */ + DBG_TX_IDX, /* 0x04 */ + DBG_RX_IDX, /* 0x05 */ + DBG_RFTEST_IDX, /* 0x06 *//* For RF test mode */ + DBG_EMU_IDX, /* 0x07 *//* Developer specific */ + DBG_SW1_IDX, /* 0x08 *//* Developer specific */ + DBG_SW2_IDX, /* 0x09 *//* Developer specific */ + DBG_SW3_IDX, /* 0x0A *//* Developer specific */ + DBG_SW4_IDX, /* 0x0B *//* Developer specific */ + DBG_HEM_IDX, /* 0x0C *//* HEM */ + DBG_AIS_IDX, /* 0x0D *//* AIS */ + DBG_RLM_IDX, /* 0x0E *//* RLM */ + DBG_MEM_IDX, /* 0x0F *//* RLM */ + DBG_CNM_IDX, /* 0x10 *//* CNM */ + DBG_RSN_IDX, /* 0x11 *//* RSN */ + DBG_BSS_IDX, /* 0x12 *//* BSS */ + DBG_SCN_IDX, /* 0x13 *//* SCN */ + DBG_SAA_IDX, /* 0x14 *//* SAA */ + DBG_AAA_IDX, /* 0x15 *//* AAA */ + DBG_P2P_IDX, /* 0x16 *//* P2P */ + DBG_QM_IDX, /* 0x17 *//* QUE_MGT */ + DBG_SEC_IDX, /* 0x18 *//* SEC */ + DBG_BOW_IDX, /* 0x19 *//* BOW */ + DBG_WAPI_IDX, /* 0x1A *//* WAPI */ + DBG_ROAMING_IDX, /* 0x1B *//* ROAMING */ + DBG_TDLS_IDX, /* 0x1C *//* TDLS *//* CFG_SUPPORT_TDLS */ + DBG_PF_IDX, /* 0x1D *//* PF */ + DBG_OID_IDX, /* 0x1E *//* OID */ + DBG_NIC_IDX, /* 0x1F *//* NIC */ + DBG_WNM_IDX, /* 0x20 *//* WNM */ + DBG_WMM_IDX, /* 0x21 *//* WMM */ + DBG_TRACE_IDX, /* 0x22 *//* TRACE *//* don't add before */ + DBG_TWT_REQUESTER_IDX, + DBG_TWT_PLANNER_IDX, + DBG_RRM_IDX, + DBG_MODULE_NUM /* Notice the XLOG check */ +}; +enum ENUM_DBG_ASSERT_CTRL_LEVEL { + DBG_ASSERT_CTRL_LEVEL_ERROR, + DBG_ASSERT_CTRL_LEVEL_WARN, + DBG_ASSERT_CTRL_LEVEL_LITE +}; +enum ENUM_DBG_ASSERT_PATH { + DBG_ASSERT_PATH_WIFI, + DBG_ASSERT_PATH_WMT +}; + +struct CHIP_DBG_OPS { + void (*showPdmaInfo)(struct ADAPTER *prAdapter); + void (*showPseInfo)(struct ADAPTER *prAdapter); + void (*showPleInfo)(struct ADAPTER *prAdapter, u_int8_t fgDumpTxd); + void (*showTxdInfo)(struct ADAPTER *prAdapter, u_int32_t fid); + bool (*showCsrInfo)(struct ADAPTER *prAdapter); + void (*showDmaschInfo)(struct ADAPTER *prAdapter); + void (*dumpMacInfo)(struct ADAPTER *prAdapter); + int32_t (*showWtblInfo)( + struct ADAPTER *prAdapter, + uint32_t u4Index, + char *pcCommand, + int32_t i4TotalLen); +#if (CFG_SUPPORT_CONNAC2X == 1) + int32_t (*showUmacFwtblInfo)( + struct ADAPTER *prAdapter, + uint32_t u4Index, + char *pcCommand, + int32_t i4TotalLen); +#endif /* CFG_SUPPORT_CONNAC2X == 1 */ + void (*showHifInfo)(struct ADAPTER *prAdapter); + void (*printHifDbgInfo)(struct ADAPTER *prAdapter); + int32_t (*show_rx_rate_info)( + struct ADAPTER *prAdapter, + char *pcCommand, + int32_t i4TotalLen, + uint8_t ucStaIdx); + int32_t (*show_rx_rssi_info)( + struct ADAPTER *prAdapter, + char *pcCommand, + int32_t i4TotalLen, + uint8_t ucStaIdx); + int32_t (*show_stat_info)( + struct ADAPTER *prAdapter, + char *pcCommand, + int32_t i4TotalLen, + struct PARAM_HW_WLAN_INFO *prHwWlanInfo, + struct PARAM_GET_STA_STATISTICS *prQueryStaStatistics, + uint8_t fgResetCnt, + uint32_t u4StatGroup); +#ifdef CFG_SUPPORT_LINK_QUALITY_MONITOR + int (*get_rx_rate_info)( + struct ADAPTER *prAdapter, + uint32_t *pu4Rate, + uint32_t *pu4Nss, + uint32_t *pu4RxMode, + uint32_t *pu4FrMode, + uint32_t *pu4Sgi); +#endif +}; + +enum PKT_PHASE { + PHASE_XMIT_RCV, + PHASE_ENQ_QM, + PHASE_HIF_TX, +}; + +struct WLAN_DEBUG_INFO { + u_int8_t fgVoE5_7Test:1; + u_int8_t fgReserved:7; +}; + +#if (CFG_SUPPORT_STATISTICS == 1) +enum WAKE_DATA_TYPE { + WLAN_WAKE_ARP = 0, + WLAN_WAKE_IPV4, + WLAN_WAKE_IPV6, + WLAN_WAKE_1X, + WLAN_WAKE_TDLS, + WLAN_WAKE_OTHER, + WLAN_WAKE_MAX_NUM +}; +#endif + +#if MTK_WCN_HIF_SDIO +#define DBG_ASSERT_PATH_DEFAULT DBG_ASSERT_PATH_WMT +#else +#define DBG_ASSERT_PATH_DEFAULT DBG_ASSERT_PATH_WIFI +#endif +#define DBG_ASSERT_CTRL_LEVEL_DEFAULT DBG_ASSERT_CTRL_LEVEL_ERROR +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ +/* Debug print format string for the OS system time */ +#define OS_SYSTIME_DBG_FORMAT "0x%08x" +/* Debug print argument for the OS system time */ +#define OS_SYSTIME_DBG_ARGUMENT(systime) (systime) +#if CFG_SHOW_FULL_MACADDR +/* Debug print format string for the MAC Address */ +#define MACSTR "%pM" +/* Debug print argument for the MAC Address */ +#define MAC2STR(a) a +#else +#define MACSTR "%02x:%02x:**:**:**:%02x" +#define MAC2STR(a) ((uint8_t *)a)[0], ((uint8_t *)a)[1], ((uint8_t *)a)[5] +#endif +#define PMKSTR "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%03x%02x%02x" +/* Debug print format string for the IPv4 Address */ +#define IPV4STR "%pI4" +/* Debug print argument for the IPv4 Address */ +#define IPV4TOSTR(a) a +/* Debug print format string for the IPv6 Address */ +#define IPV6STR "%pI6" +/* Debug print argument for the IPv6 Address */ +#define IPV6TOSTR(a) a +/* The pre-defined format to dump the varaible value with its name shown. */ +#define DUMPVAR(variable, format) (#variable " = " format "\n", variable) +/* The pre-defined format to dump the MAC type value with its name shown. */ +#define DUMPMACADDR(addr) (#addr " = " MACSTR "\n", MAC2STR(addr)) +/* Debug print format string for the floating point */ +#define FPSTR "%u.%u" +/* Debug print argument for the floating point */ +#define DIV2INT(_dividend, _divisor) \ + ((_divisor) ? (_dividend) / (_divisor) : 0) +#define DIV2DEC(_dividend, _divisor) \ + ((_divisor) ? (((_dividend) * 100) / (_divisor)) % 100 : 0) +/* for HIDE some information for user load */ +#ifdef BUILD_QA_DBG +#define HIDE(_str) _str +#else +#define HIDE(_str) "***" +#endif + +/* Basiclly, we just do renaming of KAL functions although they should + * be defined as "Nothing to do" if DBG=0. But in some compiler, the macro + * syntax does not support #define LOG_FUNC(x,...) + * + * A caller shall not invoke these three macros when DBG=0. + */ +#define LOG_FUNC kalPrint +#define LOG_FUNC_LIMITED kalPrintLimited + +/* If __FUNCTION__ is already defined by compiler, we just use it. */ +#define DEBUGFUNC(_Func) +/* Disabled due to AOSP + * #if defined(__FUNCTION__) + * #define DEBUGFUNC(_Func) + * #else + * #define DEBUGFUNC(_Func) static const char __FUNCTION__[] = _Func; + * #endif + */ +#if DBG_DISABLE_ALL_LOG +#define DBGLOG(_Module, _Class, _Fmt) +#define DBGLOG_LIMITED(_Module, _Class, _Fmt) +#define DBGLOG_MEM8(_Module, _Class, _StartAddr, _Length) +#define DBGLOG_MEM32(_Module, _Class, _StartAddr, _Length) +#else +#define DBGLOG(_Mod, _Clz, _Fmt, ...) \ + do { \ + if ((aucDebugModule[DBG_##_Mod##_IDX] & \ + DBG_CLASS_##_Clz) == 0) \ + break; \ + LOG_FUNC("[%u]%s:(" #_Mod " " #_Clz ") " _Fmt, \ + KAL_GET_CURRENT_THREAD_ID(), \ + __func__, ##__VA_ARGS__); \ + } while (0) +#define DBGLOG_LIMITED(_Mod, _Clz, _Fmt, ...) \ + do { \ + if ((aucDebugModule[DBG_##_Mod##_IDX] & \ + DBG_CLASS_##_Clz) == 0) \ + break; \ + LOG_FUNC_LIMITED("[%u]%s:(" #_Mod " " #_Clz ") " _Fmt, \ + KAL_GET_CURRENT_THREAD_ID(), \ + __func__, ##__VA_ARGS__); \ + } while (0) +#define DBGFWLOG(_Mod, _Clz, _Fmt, ...) \ + do { \ + if ((aucDebugModule[DBG_##_Mod##_IDX] & \ + DBG_CLASS_##_Clz) == 0) \ + break; \ + wlanPrintFwLog(NULL, 0, DEBUG_MSG_TYPE_DRIVER, \ + "[%u]%s:(" #_Mod " " #_Clz ") " _Fmt, \ + KAL_GET_CURRENT_THREAD_ID(), \ + __func__, ##__VA_ARGS__); \ + } while (0) +#define TOOL_PRINTLOG(_Mod, _Clz, _Fmt, ...) \ + do { \ + if ((aucDebugModule[DBG_##_Mod##_IDX] & \ + DBG_CLASS_##_Clz) == 0) \ + break; \ + LOG_FUNC(_Fmt, ##__VA_ARGS__); \ + } while (0) +#define DBGLOG_MEM8(_Mod, _Clz, _Adr, _Len) \ + { \ + if (aucDebugModule[DBG_##_Mod##_IDX] & DBG_CLASS_##_Clz) { \ + LOG_FUNC("%s:(" #_Mod " " #_Clz ")\n", __func__); \ + dumpMemory8((uint8_t *)(_Adr), (uint32_t)(_Len)); \ + } \ + } +#define DBGLOG_MEM32(_Mod, _Clz, _Adr, _Len) \ + { \ + if (aucDebugModule[DBG_##_Mod##_IDX] & DBG_CLASS_##_Clz) { \ + LOG_FUNC("%s:(" #_Mod " " #_Clz ")\n", __func__); \ + dumpMemory32((uint32_t *)(_Adr), (uint32_t)(_Len)); \ + } \ + } +#endif +#define DISP_STRING(_str) _str +#undef ASSERT +#undef ASSERT_REPORT +#if (BUILD_QA_DBG || DBG) +#define ASSERT_NOMEM() \ +{ \ + LOG_FUNC("alloate memory failed at %s:%d\n", __FILE__, __LINE__); \ + kalSendAeeWarning("Wlan_Gen4 No Mem", "Memory Alloate Failed %s:%d",\ + __FILE__, __LINE__); \ +} +#ifdef _lint +#define ASSERT(_exp) \ + { \ + if (!(_exp)) { \ + do {} while (1); \ + } \ + } +#define ASSERT_REPORT(_exp, _fmt) \ + { \ + LOG_FUNC("Assertion failed: %s:%d (%s)\n", \ + __FILE__, __LINE__, #_exp); \ + LOG_FUNC _fmt; \ + if (!(_exp)) { \ + do {} while (1); \ + } \ + } +#elif defined(WINDOWS_CE) +#define UNICODE_TEXT(_msg) TEXT(_msg) +#define ASSERT(_exp) \ + { \ + if (!(_exp)) { \ + TCHAR rUbuf[256]; \ + kalBreakPoint(); \ + _stprintf(rUbuf, TEXT("Assertion failed: %s:%d %s\n"), \ + UNICODE_TEXT(__FILE__), __LINE__, \ + UNICODE_TEXT(#_exp)); \ + MessageBox(NULL, rUbuf, TEXT("ASSERT!"), MB_OK); \ + } \ + } +#define ASSERT_REPORT(_exp, _fmt) \ + { \ + if (!(_exp)) { \ + TCHAR rUbuf[256]; \ + kalBreakPoint(); \ + _stprintf(rUbuf, TEXT("Assertion failed: %s:%d %s\n"), \ + UNICODE_TEXT(__FILE__), __LINE__, \ + UNICODE_TEXT(#_exp)); \ + MessageBox(NULL, rUbuf, TEXT("ASSERT!"), MB_OK); \ + } \ + } +#else +#define ASSERT_NOMEM() \ +{ \ + LOG_FUNC("alloate memory failed at %s:%d\n", __FILE__, __LINE__); \ + kalSendAeeWarning("Wlan_Gen4 No Mem", "Memory Alloate Failed %s:%d",\ + __FILE__, __LINE__); \ +} + +#define ASSERT(_exp) \ + { \ + if (!(_exp)) { \ + LOG_FUNC("Assertion failed: %s:%d (%s)\n", \ + __FILE__, __LINE__, #_exp); \ + kalBreakPoint(); \ + } \ + } +#define ASSERT_REPORT(_exp, _fmt) \ + { \ + if (!(_exp)) { \ + LOG_FUNC("Assertion failed: %s:%d (%s)\n", \ + __FILE__, __LINE__, #_exp); \ + LOG_FUNC _fmt; \ + kalBreakPoint(); \ + } \ + } +#endif /* WINDOWS_CE */ +#else +#define ASSERT_NOMEM() {} +#define ASSERT(_exp) {} +#define ASSERT_REPORT(_exp, _fmt) {} +#endif /* BUILD_QA_DBG */ +/* LOG function for print to buffer */ +/* If buffer pointer is NULL, redirect to normal DBGLOG */ +#define LOGBUF(_pucBuf, _maxLen, _curLen, _Fmt, ...) \ + { \ + if (_pucBuf) \ + (_curLen) += kalSnprintf((_pucBuf) + (_curLen), \ + (_maxLen) - (_curLen), _Fmt, ##__VA_ARGS__); \ + else \ + DBGLOG(SW4, INFO, _Fmt, ##__VA_ARGS__); \ + } +/* The following macro is used for debugging packed structures. */ +#ifndef DATA_STRUCT_INSPECTING_ASSERT +#define DATA_STRUCT_INSPECTING_ASSERT(expr) \ +{ \ + switch (0) {case 0: case (expr): default:; } \ +} +#endif + +/* Name alias of debug functions to skip check patch*/ +#define log_dbg DBGLOG +#define log_limited_dbg DBGLOG_LIMITED +#define log_fw_dbg DBGFWLOG +#define log_mem8_dbg DBGLOG_MEM8 +#define log_mem32_dbg DBGLOG_MEM32 +#define log_tool_dbg TOOL_PRINTLOG +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +void dumpMemory8(IN uint8_t *pucStartAddr, + IN uint32_t u4Length); +void dumpMemory32(IN uint32_t *pu4StartAddr, + IN uint32_t u4Length); +void wlanPrintFwLog(uint8_t *pucLogContent, + uint16_t u2MsgSize, uint8_t ucMsgType, + const uint8_t *pucFmt, ...); + +void wlanDbgLogLevelInit(void); +void wlanDbgLogLevelUninit(void); +uint32_t wlanDbgLevelUiSupport(IN struct ADAPTER *prAdapter, + uint32_t u4Version, uint32_t ucModule); +uint32_t wlanDbgGetLogLevelImpl(IN struct ADAPTER *prAdapter, + uint32_t u4Version, uint32_t ucModule); +void wlanDbgSetLogLevelImpl(IN struct ADAPTER *prAdapter, + uint32_t u4Version, uint32_t u4Module, uint32_t u4level); +void wlanDriverDbgLevelSync(void); +u_int8_t wlanDbgGetGlobalLogLevel(uint32_t u4Module, uint32_t *pu4Level); +u_int8_t wlanDbgSetGlobalLogLevel(uint32_t u4Module, uint32_t u4Level); + +void wlanFillTimestamp(struct ADAPTER *prAdapter, void *pvPacket, + uint8_t ucPhase); + +void halShowPseInfo(IN struct ADAPTER *prAdapter); +void halShowPleInfo(IN struct ADAPTER *prAdapter, + u_int8_t fgDumpTxd); +void halShowDmaschInfo(IN struct ADAPTER *prAdapter); +void haldumpMacInfo(IN struct ADAPTER *prAdapter); +void halDumpTxdInfo(IN struct ADAPTER *prAdapter, uint32_t *tmac_info); +void halShowTxdInfo( + struct ADAPTER *prAdapter, + u_int32_t fid); +int32_t halShowStatInfo(struct ADAPTER *prAdapter, + IN char *pcCommand, IN int i4TotalLen, + struct PARAM_HW_WLAN_INFO *prHwWlanInfo, + struct PARAM_GET_STA_STATISTICS *prQueryStaStatistics, + u_int8_t fgResetCnt, uint32_t u4StatGroup); +#ifdef CFG_SUPPORT_LINK_QUALITY_MONITOR +int connac_get_rx_rate_info(struct ADAPTER *prAdapter, + uint32_t *pu4Rate, + uint32_t *pu4Nss, + uint32_t *pu4RxMode, + uint32_t *pu4FrMode, + uint32_t *pu4Sgi); +#endif + +#if (CFG_SUPPORT_CONNAC2X == 1) +void connac2x_show_txd_Info( + struct ADAPTER *prAdapter, + u_int32_t fid); +int32_t connac2x_show_wtbl_info( + struct ADAPTER *prAdapter, + uint32_t u4Index, + char *pcCommand, + int i4TotalLen); +int32_t connac2x_show_umac_wtbl_info( + struct ADAPTER *prAdapter, + uint32_t u4Index, + char *pcCommand, + int i4TotalLen); + +int32_t connac2x_show_rx_rate_info( + struct ADAPTER *prAdapter, + char *pcCommand, + int32_t i4TotalLen, + uint8_t ucStaIdx); + +int32_t connac2x_show_rx_rssi_info( + struct ADAPTER *prAdapter, + char *pcCommand, + int32_t i4TotalLen, + uint8_t ucStaIdx); + +int32_t connac2x_show_stat_info( + struct ADAPTER *prAdapter, + char *pcCommand, + int32_t i4TotalLen, + struct PARAM_HW_WLAN_INFO *prHwWlanInfo, + struct PARAM_GET_STA_STATISTICS *prQueryStaStatistics, + uint8_t fgResetCnt, + uint32_t u4StatGroup); + +#ifdef CFG_SUPPORT_LINK_QUALITY_MONITOR +int connac2x_get_rx_rate_info( + struct ADAPTER *prAdapter, + uint32_t *pu4Rate, + uint32_t *pu4Nss, + uint32_t *pu4RxMode, + uint32_t *pu4FrMode, + uint32_t *pu4Sgi); +#endif + +#endif /* CFG_SUPPORT_CONNAC2X == 1 */ + +#if (CFG_SUPPORT_CONNINFRA == 1) +void fw_log_bug_hang_register(void *); +#endif + +#if (CFG_SUPPORT_STATISTICS == 1) +void wlanWakeStaticsInit(void); +void wlanWakeStaticsUninit(void); +uint32_t wlanWakeLogCmd(uint8_t ucCmdId); +uint32_t wlanWakeLogEvent(uint8_t ucEventId); +void wlanLogTxData(enum WAKE_DATA_TYPE dataType); +void wlanLogRxData(enum WAKE_DATA_TYPE dataType); +uint32_t wlanWakeDumpRes(void); +#endif + +#if (CFG_SUPPORT_RA_GEN == 1) +int32_t mt7663_show_stat_info(struct ADAPTER *prAdapter, + char *pcCommand, int32_t i4TotalLen, + struct PARAM_HW_WLAN_INFO *prHwWlanInfo, + struct PARAM_GET_STA_STATISTICS *prQueryStaStatistics, + uint8_t fgResetCnt, uint32_t u4StatGroup); +#endif + +#if (CFG_SUPPORT_RA_GEN == 0) +int32_t mt7668_show_stat_info(struct ADAPTER *prAdapter, + char *pcCommand, int32_t i4TotalLen, + struct PARAM_HW_WLAN_INFO *prHwWlanInfo, + struct PARAM_GET_STA_STATISTICS *prQueryStaStatistics, + uint8_t fgResetCnt, uint32_t u4StatGroup); + +int32_t mt6632_show_stat_info(struct ADAPTER *prAdapter, + char *pcCommand, int32_t i4TotalLen, + struct PARAM_HW_WLAN_INFO *prHwWlanInfo, + struct PARAM_GET_STA_STATISTICS *prQueryStaStatistics, + uint8_t fgResetCnt, uint32_t u4StatGroup); +#endif +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +#endif /* _DEBUG_H */ + + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/dvt/dvt_common.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/dvt/dvt_common.h new file mode 100644 index 0000000000000000000000000000000000000000..1461bdc810ec4a7813ac661ae00a5840c5d866ff --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/dvt/dvt_common.h @@ -0,0 +1,387 @@ +/******************************************************************************* + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ + +/* + ** Id: include/dvt_common.h + */ + +/*! \file "dvt_common.h" + * \brief This file contains the declairations of sys dvt command + */ + +#ifndef _DVT_COMMON_H +#define _DVT_COMMON_H + +#if CFG_SUPPORT_WIFI_SYSDVT + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#define PID_SIZE 256 +#define TXS_LIST_ELEM_NUM 4096 +#define TX_TEST_UNLIMITIED 0xFFFF +#define TX_TEST_UP_UNDEF 0xFF +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ +#define IS_SKIP_CH_CHECK(_prAdapter) \ + ((_prAdapter)->auto_dvt && (_prAdapter)->auto_dvt->skip_legal_ch_enable) + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +enum ENUM_SYSDVT_CTRL_EXT_T { + EXAMPLE_FEATURE_ID = 0, + SYSDVT_CTRL_EXT_NUM +}; + +enum ENUM_AUTOMATION_TXS_TESTYPE { + TXS_INIT = 0, + TXS_COUNT_TEST, + TXS_BAR_TEST, + TXS_DEAUTH_TEST, + TXS_RTS_TEST, + TXS_BA_TEST, + TXS_DUMP_DATA, + TXS_NUM +}; + +#if CFG_TCP_IP_CHKSUM_OFFLOAD +enum ENUM_AUTOMATION_CSO_TESTYPE { + CSO_TX_IPV4 = BIT(0), + CSO_TX_IPV6 = BIT(1), + CSO_TX_TCP = BIT(2), + CSO_TX_UDP = BIT(3), + CSO_RX_IPV4 = BIT(4), + CSO_RX_IPV6 = BIT(5), + CSO_RX_TCP = BIT(6), + CSO_RX_UDP = BIT(7), +}; +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ + +enum ENUM_AUTOMATION_INIT_TYPE { + TXS = 0, + RXV, +#if (CFG_SUPPORT_DMASHDL_SYSDVT) + DMASHDL, +#endif + CSO, + SKIP_CH +}; + +enum ENUM_AUTOMATION_FRAME_TYPE { + AUTOMATION_MANAGEMENT = 10, + AUTOMATION_CONTROL, + AUTOMATION_DATA +}; + +struct SYSDVT_CTRL_EXT_T { + /* DWORD_0 - Common Part */ + uint8_t ucCmdVer; + uint8_t aucPadding0[1]; + uint16_t u2CmdLen; /* Cmd size including common part and body */ + + /* DWORD_N - Body Part */ + uint32_t u4FeatureIdx; /* Feature ID */ + uint32_t u4Type; /* Test case ID (Type) */ + uint32_t u4Lth; /* dvt parameter's data struct size (Length) */ + uint8_t u1cBuffer[0]; /* dvt parameter's data struct (Value) */ +}; + +struct SYS_DVT_HANDLER { + uint32_t u4FeatureIdx; + uint8_t *str_feature_dvt; + int32_t (*pFeatureDvtHandler)(struct ADAPTER *, uint8_t *); + void (*pDoneHandler)(struct ADAPTER *, struct CMD_INFO *, uint8_t *); +}; + +struct TXS_CHECK_ITEM { + uint32_t time_stamp; +}; + +struct TXS_LIST_ENTRY { + struct list_head mList; + uint8_t wlan_idx; +}; + +struct TXS_LIST_POOL { + struct TXS_LIST_ENTRY Entry[TXS_LIST_ELEM_NUM]; + struct list_head List; +}; + +struct TXS_FREE_LIST_POOL { + struct TXS_LIST_ENTRY head; + struct TXS_LIST_POOL pool_head; + uint32_t entry_number; + spinlock_t Lock; + uint32_t txs_list_cnt; +}; + +struct TXS_LIST { + uint32_t Num; + spinlock_t lock; + struct TXS_LIST_ENTRY pHead[PID_SIZE]; + struct TXS_FREE_LIST_POOL *pFreeEntrylist; +}; + +struct TXS_TEST { + bool isinit; + uint32_t test_type; + uint8_t format; + + uint8_t pid; + uint8_t received_pid; + bool stop_send_test; + bool duplicate_txs; + + /* statistic */ + uint32_t total_req; + uint32_t total_rsp; + struct TXS_LIST txs_list; + struct TXS_CHECK_ITEM check_item[PID_SIZE]; +}; + +struct RXV_TEST { + bool enable; + bool rxv_test_result; + uint32_t rx_count; + + uint32_t rx_mode:3; + uint32_t rx_rate:7; + uint32_t rx_bw:2; + uint32_t rx_sgi:1; + uint32_t rx_stbc:2; + uint32_t rx_ldpc:1; + uint32_t rx_nss:1; +}; + +#if (CFG_SUPPORT_DMASHDL_SYSDVT) +struct DMASHDL_TEST { + uint8_t dvt_item; + uint8_t dvt_sub_item; + uint8_t dvt_queue_idx; + uint8_t dvt_ping_nums[32]; + uint8_t dvt_ping_seq[20]; +}; +#endif + +struct AUTOMATION_DVT { + uint8_t skip_legal_ch_enable; + struct TXS_TEST txs; + struct RXV_TEST rxv; +#if (CFG_SUPPORT_DMASHDL_SYSDVT) + struct DMASHDL_TEST dmashdl; +#endif + uint8_t cso_ctrl; +}; + +struct _FRAME_RTS { + /* MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2Duration; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ +}; + +/* 2-byte BAR CONTROL field in BAR frame */ +struct _BAR_CONTROL { + uint16_t ACKPolicy:1; /* 0:normal ack, 1:no ack. */ +/*if this bit1, use FRAME_MTBA_REQ, if 0, use FRAME_BA_REQ */ + uint16_t MTID:1; + uint16_t Compressed:1; + uint16_t Rsv1:9; + uint16_t TID:4; +}; + +/* 2-byte BA Starting Seq CONTROL field */ +union _BASEQ_CONTROL { + struct { + uint16_t FragNum:4; /* always set to 0 */ +/* sequence number of the 1st MSDU for which this BAR is sent */ + uint16_t StartSeq:12; + } field; + uint16_t word; +}; + +struct _FRAME_BA { + /* MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2Duration; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + struct _BAR_CONTROL BarControl; + union _BASEQ_CONTROL StartingSeq; + unsigned char bitmask[8]; +}; +#endif /* CFG_SUPPORT_WIFI_SYSDVT */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +#if CFG_TCP_IP_CHKSUM_OFFLOAD +#define CSO_TX_IPV4_ENABLED(pAd) \ + (pAd->auto_dvt && (pAd->auto_dvt->cso_ctrl & CSO_TX_IPV4)) +#define CSO_TX_IPV6_ENABLED(pAd) \ + (pAd->auto_dvt && (pAd->auto_dvt->cso_ctrl & CSO_TX_IPV6)) +#define CSO_TX_UDP_ENABLED(pAd) \ + (pAd->auto_dvt && (pAd->auto_dvt->cso_ctrl & CSO_TX_UDP)) +#define CSO_TX_TCP_ENABLED(pAd) \ + (pAd->auto_dvt && (pAd->auto_dvt->cso_ctrl & CSO_TX_TCP)) +#endif + +#define RXV_AUTODVT_DNABLED(pAd) \ + (pAd->auto_dvt && pAd->auto_dvt->rxv.enable) + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +#if CFG_SUPPORT_WIFI_SYSDVT +struct TXS_LIST_ENTRY *GetTxsEntryFromFreeList(void); + +int SendRTS( + struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + PFN_TX_DONE_HANDLER pfTxDoneHandler); + +int SendBA( + struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + PFN_TX_DONE_HANDLER pfTxDoneHandler); + +bool send_add_txs_queue(uint8_t pid, uint8_t wlan_idx); + +bool receive_del_txs_queue( + uint32_t sn, uint8_t pid, + uint8_t wlan_idx, + uint32_t time_stamp); + +int priv_driver_txs_test( + IN struct net_device *prNetDev, + IN char *pcCommand, + IN int i4TotalLen); + +int priv_driver_txs_test_result( + IN struct net_device *prNetDev, + IN char *pcCommand, + IN int i4TotalLen); + +int is_frame_test(struct ADAPTER *pAd, uint8_t send_received); + +uint32_t AutomationTxDone(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN enum ENUM_TX_RESULT_CODE rTxDoneStatus); + +int priv_driver_set_tx_test( + IN struct net_device *prNetDev, IN char *pcCommand, + IN int i4TotalLen); +int priv_driver_set_tx_test_ac( + IN struct net_device *prNetDev, IN char *pcCommand, + IN int i4TotalLen); + +/* RXV Test */ +int priv_driver_rxv_test( + IN struct net_device *prNetDev, + IN char *pcCommand, + IN int i4TotalLen); + +int priv_driver_rxv_test_result( + IN struct net_device *prNetDev, + IN char *pcCommand, + IN int i4TotalLen); + +void connac2x_rxv_correct_test( + IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb); + +/* CSO Test */ +int priv_driver_cso_test( + IN struct net_device *prNetDev, + IN char *pcCommand, + IN int i4TotalLen); + +/* skip legal channel sanity check for fpga dvt */ +int priv_driver_skip_legal_ch_check( + IN struct net_device *prNetDev, + IN char *pcCommand, + IN int i4TotalLen); + +bool AutomationInit(struct ADAPTER *pAd, int32_t auto_type); + +#endif /* CFG_SUPPORT_WIFI_SYSDVT */ +#endif /* _DVT_COMMON_H */ + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/dvt/dvt_dmashdl.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/dvt/dvt_dmashdl.h new file mode 100644 index 0000000000000000000000000000000000000000..caa14281816fae8e443bd24a7c87838b89de77e6 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/dvt/dvt_dmashdl.h @@ -0,0 +1,258 @@ +/***************************************************************************** + *============================================================================ + * HISTORY + * Log + * + * 10 05 2018 Kai.lin + * commit id bece10b96739cf7ca196930c313eab8ddcef45b3 + * Porting from 7668 + * + ****************************************************************************/ + + +#ifndef __DVT_DMASHDL_H__ +#define __DVT_DMASHDL_H__ + +#if (CFG_SUPPORT_DMASHDL_SYSDVT) +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#define WF_HIF_DMASHDL_TOP_BASE (0x7C026000) +#define WF_HIF_DMASHDL_TOP_WACPU_REFILL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x00) /* 6000 */ +#define WF_HIF_DMASHDL_TOP_SW_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x04) /* 6004 */ +#define WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x08) /* 6008 */ +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x0C) /* 600C */ +#define WF_HIF_DMASHDL_TOP_REFILL_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x10) /* 6010 */ +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x18) /* 6018 */ +#define WF_HIF_DMASHDL_TOP_PACKET_MAX_SIZE_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x1c) /* 601C */ +#define WF_HIF_DMASHDL_TOP_GROUP0_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x20) /* 6020 */ +#define WF_HIF_DMASHDL_TOP_GROUP1_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x24) /* 6024 */ +#define WF_HIF_DMASHDL_TOP_GROUP2_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x28) /* 6028 */ +#define WF_HIF_DMASHDL_TOP_GROUP3_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x2C) /* 602C */ +#define WF_HIF_DMASHDL_TOP_GROUP4_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x30) /* 6030 */ +#define WF_HIF_DMASHDL_TOP_GROUP15_CONTROL_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x5C) /* 605C */ +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING0_ADDR\ + (WF_HIF_DMASHDL_TOP_BASE + 0xB0) /* 60B0 */ +#define WF_HIF_DMASHDL_TOP_HIF_SCHEDULER_SETTING1_ADDR\ + (WF_HIF_DMASHDL_TOP_BASE + 0xB4) /* 60B4 */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING0_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0xd0) /* 60D0 */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING1_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0xd4) /* 60D4 */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING2_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0xd8) /* 60D8 */ +#define WF_HIF_DMASHDL_TOP_QUEUE_MAPPING3_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0xdc) /* 60DC */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x100) /* 6100 */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x140) /* 6140 */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP15_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x17C) /* 617C */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT0_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x180) /* 6180 */ +#define WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x98) /* 6098 */ +#define WF_HIF_DMASHDL_TOP_RD_GROUP_PKT_CNT7_ADDR \ + (WF_HIF_DMASHDL_TOP_BASE + 0x19c) /* 619C */ + +#define WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_CR_HIF_ACK_CNT_TH_MASK \ + 0x00FF0000 /* CR_HIF_ACK_CNT_TH[23..16] */ +#define WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_CR_HIF_ACK_CNT_TH_SHFT \ + 16 +#define WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_CR_HIF_GUP_ACT_MAP_MASK \ + 0x0000FFFF /* CR_HIF_GUP_ACT_MAP[15..0] */ +#define WF_HIF_DMASHDL_TOP_OPTIONAL_CONTROL_CR_HIF_GUP_ACT_MAP_SHFT \ + 0 +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_SRC_CNT_PRI_EN_MASK \ + 0x00100000 +#define WF_HIF_DMASHDL_TOP_PAGE_SETTING_GROUP_SEQUENCE_ORDER_TYPE_MASK \ + 0x00010000 /* GROUP_SEQUENCE_ORDER_TYPE[16] */ +#define WF_HIF_DMASHDL_TOP_CONTROL_SIGNAL_CR_WACPU_MODE_EN_MASK \ + 0x00000001 /* CR_WACPU_MODE_EN[0] */ +#define WF_HIF_DMASHDL_TOP_WACPU_REFILL_WACPU_EXCUTE_MASK \ + 0x80000000 /* WACPU_EXCUTE[31] */ +#define WF_HIF_DMASHDL_TOP_WACPU_REFILL_WACPU_RETRUN_MODE_SHFT \ + 24 +#define WF_HIF_DMASHDL_TOP_WACPU_REFILL_WACPU_RETRUN_QID_SHFT \ + 16 +#define WF_HIF_DMASHDL_TOP_WACPU_REFILL_WACPU_RETURN_PAGE_CNT_SHFT \ + 0 +#define WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_EXCUTE_MASK \ + 0x80000000 /* EXCUTE[31] */ +#define WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_CPU_RETRUN_MODE_SHFT \ + 24 +#define WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_CPU_RETRUN_GID_SHFT \ + 16 +#define WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_RETURN_PAGE_CNT_SHFT \ + 0 +#define WF_HIF_DMASHDL_TOP_STATUS_RD_FREE_PAGE_CNT_MASK \ + 0x0FFF0000 /* FREE_PAGE_CNT[27..16] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_FREE_PAGE_CNT_SHFT \ + 16 +#define WF_HIF_DMASHDL_TOP_STATUS_RD_FFA_CNT_MASK \ + 0x00000FFF /* FFA_CNT[11..0] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_FFA_CNT_SHFT \ + 0 +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_G0_RSV_CNT_MASK \ + 0x0FFF0000 /* G0_RSV_CNT[27..16] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_G0_RSV_CNT_SHFT \ + 16 +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_G0_SRC_CNT_MASK \ + 0x00000FFF /* G0_SRC_CNT[11..0] */ +#define WF_HIF_DMASHDL_TOP_STATUS_RD_GP0_G0_SRC_CNT_SHFT \ + 0 + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ +/* HIF_RESET_SW_LOGIC */ +#define HIF_RESET_SW_LOGIC(prGlueInfo) \ + { \ + kalDevRegWrite(prGlueInfo, \ + WF_HIF_DMASHDL_TOP_SW_CONTROL_ADDR, 1); \ + kalDevRegWrite(prGlueInfo, \ + WF_HIF_DMASHDL_TOP_SW_CONTROL_ADDR, 0); \ + } + +#define HIF_CPU_RTN_CNT(prGlueInfo, ucGroup, ucRtnCnt) \ + kalDevRegWrite(prGlueInfo, WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_ADDR, \ + WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_EXCUTE_MASK | \ + 0x1 << WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_CPU_RETRUN_MODE_SHFT | \ + ucGroup << WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_CPU_RETRUN_GID_SHFT | \ + ucRtnCnt << WF_HIF_DMASHDL_TOP_CPU_QUOTA_SET_RETURN_PAGE_CNT_SHFT) + +/* HIF_ADD_RSV_CNT */ +#define HIF_ADD_RSV_CNT(prGlueInfo, ucQueue, ucRsvCnt) \ + kalDevRegWrite(prGlueInfo, WF_HIF_DMASHDL_TOP_WACPU_REFILL_ADDR, \ + WF_HIF_DMASHDL_TOP_WACPU_REFILL_WACPU_EXCUTE_MASK | \ + 0x1 << WF_HIF_DMASHDL_TOP_WACPU_REFILL_WACPU_RETRUN_MODE_SHFT | \ + ucQueue << WF_HIF_DMASHDL_TOP_WACPU_REFILL_WACPU_RETRUN_QID_SHFT | \ + ucRsvCnt << WF_HIF_DMASHDL_TOP_WACPU_REFILL_WACPU_RETURN_PAGE_CNT_SHFT) + +/* HIF_SUB_SRC_CNT */ +#define HIF_SUB_SRC_CNT(prGlueInfo, ucQueue, ucSrcCnt) \ + kalDevRegWrite(prGlueInfo, WF_HIF_DMASHDL_TOP_WACPU_REFILL_ADDR, \ + WF_HIF_DMASHDL_TOP_WACPU_REFILL_WACPU_EXCUTE_MASK | \ + 0x2 << WF_HIF_DMASHDL_TOP_WACPU_REFILL_WACPU_RETRUN_MODE_SHFT | \ + ucQueue << WF_HIF_DMASHDL_TOP_WACPU_REFILL_WACPU_RETRUN_QID_SHFT | \ + ucSrcCnt << WF_HIF_DMASHDL_TOP_WACPU_REFILL_WACPU_RETURN_PAGE_CNT_SHFT) + +/* HIF_ADD_SRC_CNT */ +#define HIF_ADD_SRC_CNT(prGlueInfo, ucQueue, ucSrcCnt) \ + kalDevRegWrite(prGlueInfo, WF_HIF_DMASHDL_TOP_WACPU_REFILL_ADDR, \ + WF_HIF_DMASHDL_TOP_WACPU_REFILL_WACPU_EXCUTE_MASK | \ + 0x3 << WF_HIF_DMASHDL_TOP_WACPU_REFILL_WACPU_RETRUN_MODE_SHFT | \ + ucQueue << WF_HIF_DMASHDL_TOP_WACPU_REFILL_WACPU_RETRUN_QID_SHFT | \ + ucSrcCnt << WF_HIF_DMASHDL_TOP_WACPU_REFILL_WACPU_RETURN_PAGE_CNT_SHFT) + +#define DMASHDL_DVT_SET_ITEM(pAd, item) \ + do { \ + if (pAd->auto_dvt) \ + pAd->auto_dvt->dmashdl.dvt_item = item; \ + } while (0) +#define DMASHDL_DVT_GET_ITEM(pAd) \ + ((pAd->auto_dvt)?pAd->auto_dvt->dmashdl.dvt_item:0) + +#define DMASHDL_DVT_SET_SUBITEM(pAd, subitem) \ + do { \ + if (pAd->auto_dvt) \ + pAd->auto_dvt->dmashdl.dvt_sub_item = subitem;\ + } while (0) +#define DMASHDL_DVT_GET_SUBITEM(pAd) \ + ((pAd->auto_dvt)?pAd->auto_dvt->dmashdl.dvt_sub_item:0) + +#define DMASHDL_DVT_RESET(pAd) \ + do { \ + if (pAd->auto_dvt) \ + memset(&(pAd->auto_dvt->dmashdl), \ + 0, sizeof(struct DMASHDL_TEST)); \ + } while (0) + +#define DMASHDL_DVT_ALLOW_PING_ONLY(pAd) \ + (pAd->auto_dvt && \ + (pAd->auto_dvt->dmashdl.dvt_item == DMASHDL_DVT_ITEM_1 ||\ + pAd->auto_dvt->dmashdl.dvt_item == DMASHDL_DVT_ITEM_3 ||\ + pAd->auto_dvt->dmashdl.dvt_item == DMASHDL_DVT_ITEM_4 ||\ + (pAd->auto_dvt->dmashdl.dvt_item == DMASHDL_DVT_ITEM_5 &&\ + pAd->auto_dvt->dmashdl.dvt_sub_item == DMASHDL_DVT_SUBITEM_2)\ + )) +#define DMASHDL_DVT_QUEUE_MAPPING_TYPE1(pAd) \ + (pAd->auto_dvt && \ + (pAd->auto_dvt->dmashdl.dvt_item == DMASHDL_DVT_ITEM_1 ||\ + pAd->auto_dvt->dmashdl.dvt_item == DMASHDL_DVT_ITEM_2 ||\ + pAd->auto_dvt->dmashdl.dvt_item == DMASHDL_DVT_ITEM_3 ||\ + pAd->auto_dvt->dmashdl.dvt_item == DMASHDL_DVT_ITEM_4)) +#define DMASHDL_DVT_QUEUE_MAPPING_TYPE2(pAd) \ + (pAd->auto_dvt && \ + (pAd->auto_dvt->dmashdl.dvt_item == DMASHDL_DVT_ITEM_5 &&\ + pAd->auto_dvt->dmashdl.dvt_sub_item == DMASHDL_DVT_SUBITEM_2)) +/* No check pAd->auto_dvt because */ +/* must call DMASHDL_DVT_QUEUE_MAPPING_TYPEX before call those MARCO */ +#define DMASHDL_DVT_GET_MAPPING_QID(pAd) \ + (pAd->auto_dvt->dmashdl.dvt_queue_idx) +#define DMASHDL_DVT_SET_MAPPING_QID(pAd, qidx) \ + (pAd->auto_dvt->dmashdl.dvt_queue_idx = (qidx)) +#define DMASHDL_DVT_INC_PING_PKT_CNT(pAd, qidx) \ + (pAd->auto_dvt->dmashdl.dvt_ping_nums[qidx]++) + + + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +/* ================ DMASHDL DVT ================ */ +enum _ENUM_DMASHDL_DVT_ITEM_T { + DMASHDL_DVT_RESULT = 0, + DMASHDL_DVT_ITEM_1 = 1, + DMASHDL_DVT_ITEM_2, + DMASHDL_DVT_ITEM_3, + DMASHDL_DVT_ITEM_4, + DMASHDL_DVT_ITEM_5, + DMASHDL_DVT_ITEM_6, + DMASHDL_DVT_ITEM_NUM +}; + +enum _ENUM_DMASHDL_DVT_SUBITEM_T { + DMASHDL_DVT_SUBITEM_1 = 1, + DMASHDL_DVT_SUBITEM_2 = 2, +}; + +struct DMASHDL_DVT_CMD_T { + uint8_t ucItemNo; + uint8_t ucSubItemNo; + uint8_t ucArgNo; + uint8_t ucReserve; +}; + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +int32_t priv_driver_dmashdl_dvt_item( + IN struct net_device *prNetDev, + IN char *pcCommand, + IN int32_t i4TotalLen); +int32_t priv_driver_show_dmashdl_allcr( + IN struct net_device *prNetDev, + IN char *pcCommand, + IN int i4TotalLen); +#endif +#endif /* __DVT_DMASHDL_H__ */ + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/hif_cmm.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/hif_cmm.h new file mode 100644 index 0000000000000000000000000000000000000000..64fb849f4d3f880f7b6efa243fafb08aae9da50b --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/hif_cmm.h @@ -0,0 +1,139 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/*! \file "hif.h" + * \brief Functions for the driver to register bus and setup the IRQ + * + * Functions for the driver to register bus and setup the IRQ + */ + + +#ifndef _HIF_CMM_H +#define _HIF_CMM_H + + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/* Interface Type */ +enum MT_INF_TYPE { + MT_DEV_INF_UNKNOWN = 0, + MT_DEV_INF_PCI = 1, + MT_DEV_INF_USB = 2, + MT_DEV_INF_RBUS = 4, + MT_DEV_INF_PCIE = 5, + MT_DEV_INF_SDIO = 6, + MT_DEV_INF_EHPI = 7, + MT_DEV_INF_AXI = 8, + #ifdef UT_TEST_MODE + MT_DEV_INF_UT = 10, + #endif /* UT_TEST_MODE */ +}; + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ +#define IS_SDIO_INF(__GlueInfo) \ + ((__GlueInfo)->u4InfType == MT_DEV_INF_SDIO) +#define IS_USB_INF(__GlueInfo) \ + ((__GlueInfo)->u4InfType == MT_DEV_INF_USB) +#define IS_PCIE_INF(__GlueInfo) \ + ((__GlueInfo)->u4InfType == MT_DEV_INF_PCIE) +#define IS_EHPI_INF(__GlueInfo) \ + ((__GlueInfo)->u4InfType == MT_DEV_INF_PCIE) + +#define HAL_WRITE_HIF_TXD(_prChipInfo, _pucOutputBuf, _u2InfoBufLen) \ +{ \ + uint16_t _u2DataLen = (uint16_t)(_u2InfoBufLen); \ + uint8_t *_prBuf = (_pucOutputBuf); \ + if (_prChipInfo->fillHifTxDesc) \ + _prChipInfo->fillHifTxDesc(&_prBuf, &_u2DataLen); \ +} + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +#endif /* _HIF_CMM_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/link.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/link.h new file mode 100644 index 0000000000000000000000000000000000000000..f3b92fabc60ba89df5b4777865c9d540210aa494 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/link.h @@ -0,0 +1,529 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: include/link.h + */ + +/*! \file link.h + * \brief Definition for simple doubly linked list operations. + * + * In this file we define the simple doubly linked list data structure + * and its operation MACROs and INLINE functions. + */ + +#ifndef _LINK_H +#define _LINK_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "gl_typedef.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +/* May cause page fault & unalignment issue (data abort) */ +#define INVALID_LINK_POISON1 ((void *) 0x00100101) + +/* Used to verify that nonbody uses non-initialized link entries. */ +#define INVALID_LINK_POISON2 ((void *) 0x00100201) + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +/* Simple Doubly Linked List Structures - Entry Part */ +struct LINK_ENTRY { + struct LINK_ENTRY *prNext, *prPrev; +}; + +/* Simple Doubly Linked List Structures - List Part */ +struct LINK { + struct LINK_ENTRY *prNext; + struct LINK_ENTRY *prPrev; + uint32_t u4NumElem; +}; + +/* Support AP Selection */ +struct LINK_MGMT { + struct LINK rUsingLink; + struct LINK rFreeLink; +}; +/* end Support AP Selection */ +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ +#if 0 +/* No one use it, temporarily mark it for [Lint - Info 773] */ +#define LINK_ADDR(rLink) \ + { (struct LINK_ENTRY *)(&(rLink)), \ + (struct LINK_ENTRY *)(&(rLink)), 0 } + +#define LINK_DECLARATION(rLink) \ + struct LINK rLink = LINK_ADDR(rLink) +#endif + +#define LINK_INITIALIZE(prLink) \ + do { \ + ((struct LINK *)(prLink))->prNext = \ + (struct LINK_ENTRY *)(prLink); \ + ((struct LINK *)(prLink))->prPrev = \ + (struct LINK_ENTRY *)(prLink); \ + ((struct LINK *)(prLink))->u4NumElem = 0; \ + } while (0) +/* Support AP Selection */ +#define LINK_MGMT_INIT(prLinkMgmt) \ + do { \ + LINK_INITIALIZE(&((struct LINK_MGMT *)prLinkMgmt)->rUsingLink); \ + LINK_INITIALIZE(&((struct LINK_MGMT *)prLinkMgmt)->rFreeLink); \ + } while (0) + +#define LINK_MGMT_GET_ENTRY(prLinkMgmt, prEntry, EntryType, memType) \ + do { \ + LINK_REMOVE_HEAD(&((struct LINK_MGMT *)prLinkMgmt)->rFreeLink, \ + prEntry, EntryType*); \ + if (!prEntry) \ + prEntry = kalMemAlloc(sizeof(EntryType), memType); \ + if (prEntry) {\ + kalMemZero(prEntry, sizeof(EntryType));\ + LINK_INSERT_TAIL( \ + &((struct LINK_MGMT *)prLinkMgmt)->rUsingLink, \ + &prEntry->rLinkEntry); \ + } \ + } while (0) + +#define LINK_MGMT_RETURN_ENTRY(prLinkMgmt, prEntry) \ + do {\ + if (!prEntry)\ + break;\ + LINK_REMOVE_KNOWN_ENTRY( \ + &((struct LINK_MGMT *)prLinkMgmt)->rUsingLink, \ + prEntry); \ + LINK_INSERT_TAIL(&((struct LINK_MGMT *)prLinkMgmt)->rFreeLink, \ + &prEntry->rLinkEntry); \ + } while (0) + +#define LINK_MGMT_UNINIT(prLinkMgmt, EntryType, memType) \ + do { \ + EntryType *prEntry = NULL; \ + struct LINK *prFreeList = &((struct LINK_MGMT *)prLinkMgmt)->rFreeLink; \ + struct LINK *prUsingList = &((struct LINK_MGMT *)prLinkMgmt)->rUsingLink; \ + LINK_REMOVE_HEAD(prFreeList, prEntry, EntryType *); \ + while (prEntry) { \ + kalMemFree(prEntry, memType, sizeof(EntryType)); \ + LINK_REMOVE_HEAD(prFreeList, prEntry, EntryType *); \ + } \ + LINK_REMOVE_HEAD(prUsingList, prEntry, EntryType *); \ + while (prEntry) { \ + kalMemFree(prEntry, memType, sizeof(EntryType)); \ + LINK_REMOVE_HEAD(prUsingList, prEntry, EntryType *); \ + } \ + } while (0) +/* end Support AP Selection */ + +#define LINK_ENTRY_INITIALIZE(prEntry) \ + do { \ + ((struct LINK_ENTRY *)(prEntry))->prNext = \ + (struct LINK_ENTRY *)NULL; \ + ((struct LINK_ENTRY *)(prEntry))->prPrev = \ + (struct LINK_ENTRY *)NULL; \ + } while (0) + +#define LINK_ENTRY_INVALID(prEntry) \ + do { \ + ((struct LINK_ENTRY *)(prEntry))->prNext = \ + (struct LINK_ENTRY *)INVALID_LINK_POISON1; \ + ((struct LINK_ENTRY *)(prEntry))->prPrev = \ + (struct LINK_ENTRY *)INVALID_LINK_POISON2; \ + } while (0) + +#define LINK_IS_EMPTY(prLink) \ + (((struct LINK *)(prLink))->prNext == (struct LINK_ENTRY *)(prLink)) + +#define LINK_ENTRY_IS_VALID(prEntry) \ + (((struct LINK_ENTRY *)(prEntry))->prNext != (struct LINK_ENTRY *)NULL && \ + ((struct LINK_ENTRY *)(prEntry))->prNext != \ + (struct LINK_ENTRY *)INVALID_LINK_POISON1 && \ + ((struct LINK_ENTRY *)(prEntry))->prPrev != (struct LINK_ENTRY *)NULL && \ + ((struct LINK_ENTRY *)(prEntry))->prPrev != \ + (struct LINK_ENTRY *)INVALID_LINK_POISON2) + + + +/* NOTE: We should do memory zero before any LINK been initiated, + * so we can check if it is valid before parsing the LINK. + */ +#define LINK_IS_INVALID(prLink) \ + (((struct LINK *)(prLink))->prNext == (struct LINK_ENTRY *)NULL) + +#define LINK_IS_VALID(prLink) \ + (((struct LINK *)(prLink))->prNext != (struct LINK_ENTRY *)NULL) + +#define LINK_ENTRY(ptr, type, member) ENTRY_OF(ptr, type, member) + +/* Insert an entry into a link list's head */ +#define LINK_INSERT_HEAD(prLink, prEntry) \ + { \ + linkAdd(prEntry, prLink); \ + ((prLink)->u4NumElem)++; \ + } + +/* Append an entry into a link list's tail */ +#define LINK_INSERT_TAIL(prLink, prEntry) \ + { \ + linkAddTail(prEntry, prLink); \ + ((prLink)->u4NumElem)++; \ + } + +/* Peek head entry, but keep still in link list */ +#define LINK_PEEK_HEAD(prLink, _type, _member) \ + ( \ + LINK_IS_EMPTY(prLink) ? \ + NULL : LINK_ENTRY((prLink)->prNext, _type, _member) \ + ) + +/* Peek tail entry, but keep still in link list */ +#define LINK_PEEK_TAIL(prLink, _type, _member) \ + ( \ + LINK_IS_EMPTY(prLink) ? \ + NULL : LINK_ENTRY((prLink)->prPrev, _type, _member) \ + ) + +/* Get first entry from a link list */ +/* NOTE: We assume the link entry located at the beginning of "prEntry Type", + * so that we can cast the link entry to other data type without doubts. + * And this macro also decrease the total entry count at the same time. + */ +#define LINK_REMOVE_HEAD(prLink, prEntry, _P_TYPE) \ + { \ + ASSERT(prLink); \ + if (LINK_IS_EMPTY(prLink)) { \ + prEntry = (_P_TYPE)NULL; \ + } \ + else { \ + prEntry = \ + (_P_TYPE)(((struct LINK *)(prLink))->prNext); \ + linkDel((struct LINK_ENTRY *)prEntry); \ + ((prLink)->u4NumElem)--; \ + } \ + } + +/* Assume the link entry located at the beginning of prEntry Type. + * And also decrease the total entry count. + */ +#define LINK_REMOVE_KNOWN_ENTRY(prLink, prEntry) \ + { \ + ASSERT(prLink); \ + ASSERT(prEntry); \ + linkDel((struct LINK_ENTRY *)prEntry); \ + ((prLink)->u4NumElem)--; \ + } + +/* Merge prSrcLink to prDstLink and put prSrcLink ahead of prDstLink */ +#define LINK_MERGE_TO_HEAD(prDstLink, prSrcLink) \ + { \ + if (!LINK_IS_EMPTY(prSrcLink)) { \ + linkMergeToHead((struct LINK *)prDstLink, \ + (struct LINK *)prSrcLink); \ + (prDstLink)->u4NumElem += (prSrcLink)->u4NumElem; \ + LINK_INITIALIZE(prSrcLink); \ + } \ + } + +/* Merge prSrcLink to prDstLink and put prSrcLink at tail */ +#define LINK_MERGE_TO_TAIL(prDstLink, prSrcLink) \ + { \ + if (!LINK_IS_EMPTY(prSrcLink)) { \ + linkMergeToTail((struct LINK *)prDstLink, \ + (struct LINK *)prSrcLink); \ + (prDstLink)->u4NumElem += (prSrcLink)->u4NumElem; \ + LINK_INITIALIZE(prSrcLink); \ + } \ + } + +/* Iterate over a link list */ +#define LINK_FOR_EACH(prEntry, prLink) \ + for (prEntry = (prLink)->prNext; \ + prEntry != (struct LINK_ENTRY *)(prLink); \ + prEntry = (struct LINK_ENTRY *)prEntry->prNext) + +/* Iterate over a link list backwards */ +#define LINK_FOR_EACH_PREV(prEntry, prLink) \ + for (prEntry = (prLink)->prPrev; \ + prEntry != (struct LINK_ENTRY *)(prLink); \ + prEntry = (struct LINK_ENTRY *)prEntry->prPrev) + +/* Iterate over a link list safe against removal of link entry */ +#define LINK_FOR_EACH_SAFE(prEntry, prNextEntry, prLink) \ + for (prEntry = (prLink)->prNext, prNextEntry = prEntry->prNext; \ + prEntry != (struct LINK_ENTRY *)(prLink); \ + prEntry = prNextEntry, prNextEntry = prEntry->prNext) + +/* Iterate over a link list of given type */ +#define LINK_FOR_EACH_ENTRY(prObj, prLink, rMember, _TYPE) \ + for (prObj = LINK_ENTRY((prLink)->prNext, _TYPE, rMember); \ + &prObj->rMember != (struct LINK_ENTRY *)(prLink); \ + prObj = LINK_ENTRY(prObj->rMember.prNext, _TYPE, rMember)) + +/* Iterate backwards over a link list of given type */ +#define LINK_FOR_EACH_ENTRY_PREV(prObj, prLink, rMember, _TYPE) \ + for (prObj = LINK_ENTRY((prLink)->prPrev, _TYPE, rMember); \ + &prObj->rMember != (struct LINK_ENTRY *)(prLink); \ + prObj = LINK_ENTRY(prObj->rMember.prPrev, _TYPE, rMember)) + +/* Iterate over a link list of given type safe against removal of link entry */ +#define LINK_FOR_EACH_ENTRY_SAFE(prObj, prNextObj, prLink, rMember, _TYPE) \ + for (prObj = LINK_ENTRY((prLink)->prNext, _TYPE, rMember), \ + prNextObj = LINK_ENTRY(prObj->rMember.prNext, _TYPE, rMember); \ + &prObj->rMember != (struct LINK_ENTRY *)(prLink); \ + prObj = prNextObj, \ + prNextObj = LINK_ENTRY(prNextObj->rMember.prNext, _TYPE, rMember)) + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is only for internal link list manipulation. + * + * \param[in] prNew Pointer of new link head + * \param[in] prPrev Pointer of previous link head + * \param[in] prNext Pointer of next link head + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +static __KAL_INLINE__ void __linkAdd(IN struct LINK_ENTRY + *prNew, IN struct LINK_ENTRY *prPrev, + IN struct LINK_ENTRY *prNext) +{ + if (prNext) { + prNext->prPrev = prNew; + prNew->prNext = prNext; + } + if (prPrev) { + prNew->prPrev = prPrev; + prPrev->prNext = prNew; + } +} /* end of __linkAdd() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function will add a new entry after the specified link head. + * + * \param[in] prNew New entry to be added + * \param[in] prHead Specified link head to add it after + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +static __KAL_INLINE__ void linkAdd(IN struct LINK_ENTRY + *prNew, IN struct LINK *prLink) +{ + __linkAdd(prNew, (struct LINK_ENTRY *) prLink, + prLink->prNext); +} /* end of linkAdd() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function will add a new entry before the specified link head. + * + * \param[in] prNew New entry to be added + * \param[in] prHead Specified link head to add it before + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +static __KAL_INLINE__ void linkAddTail(IN struct LINK_ENTRY + *prNew, IN struct LINK *prLink) +{ + __linkAdd(prNew, prLink->prPrev, + (struct LINK_ENTRY *) prLink); +} /* end of linkAddTail() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is only for internal link list manipulation. + * + * \param[in] prPrev Pointer of previous link head + * \param[in] prNext Pointer of next link head + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +static __KAL_INLINE__ void __linkDel(IN struct LINK_ENTRY + *prPrev, IN struct LINK_ENTRY *prNext) +{ + if (prNext) + prNext->prPrev = prPrev; + if (prPrev) + prPrev->prNext = prNext; +} /* end of __linkDel() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function will delete a specified entry from link list. + * NOTE: the entry is in an initial state. + * + * \param prEntry Specified link head(entry) + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +static __KAL_INLINE__ void linkDel(IN struct LINK_ENTRY + *prEntry) +{ + __linkDel(prEntry->prPrev, prEntry->prNext); + + LINK_ENTRY_INITIALIZE(prEntry); +} /* end of linkDel() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function will delete a specified entry from link list + * and then add it after the specified link head. + * + * \param[in] prEntry Specified link head(entry) + * \param[in] prOtherHead Another link head to add it after + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +static __KAL_INLINE__ void linkMove(IN struct LINK_ENTRY + *prEntry, IN struct LINK *prLink) +{ + __linkDel(prEntry->prPrev, prEntry->prNext); + linkAdd(prEntry, prLink); +} /* end of linkMove() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function will delete a specified entry from link list + * and then add it before the specified link head. + * + * \param[in] prEntry Specified link head(entry) + * \param[in] prOtherHead Another link head to add it before + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +static __KAL_INLINE__ void linkMoveTail(IN struct LINK_ENTRY + *prEntry, IN struct LINK *prLink) +{ + __linkDel(prEntry->prPrev, prEntry->prNext); + linkAddTail(prEntry, prLink); +} /* end of linkMoveTail() */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function will merge source link to the tail of destination link. +* +* \param[in] prDst destination link +* \param[in] prSrc source link +* +* \return (none) +*/ +/*----------------------------------------------------------------------------*/ +static __KAL_INLINE__ void linkMergeToTail(struct LINK *prDst, + struct LINK *prSrc) +{ + prSrc->prNext->prPrev = prDst->prPrev; + prSrc->prPrev->prNext = (struct LINK_ENTRY *)prDst; + prDst->prPrev->prNext = prSrc->prNext; + prDst->prPrev = prSrc->prPrev; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function will merge source link to the head of destination link. +* +* \param[in] prDst destination link +* \param[in] prSrc source link + +* +* \return (none) +*/ +/*----------------------------------------------------------------------------*/ +static __KAL_INLINE__ void linkMergeToHead(struct LINK *prDst, + struct LINK *prSrc) +{ + prSrc->prNext->prPrev = (struct LINK_ENTRY *)prDst; + prSrc->prPrev->prNext = prDst->prNext; + prDst->prNext->prPrev = prSrc->prPrev; + prDst->prNext = prSrc->prNext; +} + +#endif /* _LINK_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/link_drv.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/link_drv.h new file mode 100644 index 0000000000000000000000000000000000000000..715796f7f44718d16b6a07557ea0c795fec719f3 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/link_drv.h @@ -0,0 +1,527 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: include/link.h + */ + +/*! \file link.h + * \brief Definition for simple doubly linked list operations. + * + * In this file we define the simple doubly linked list data structure + * and its operation MACROs and INLINE functions. + */ + +#ifndef _LINK_H +#define _LINK_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "gl_typedef.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +/* May cause page fault & unalignment issue (data abort) */ +#define INVALID_LINK_POISON1 ((void *) 0x00100101) + +/* Used to verify that nonbody uses non-initialized link entries. */ +#define INVALID_LINK_POISON2 ((void *) 0x00100201) + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +/* Simple Doubly Linked List Structures - Entry Part */ +struct LINK_ENTRY { + struct LINK_ENTRY *prNext, *prPrev; +}; + +/* Simple Doubly Linked List Structures - List Part */ +struct LINK { + struct LINK_ENTRY *prNext; + struct LINK_ENTRY *prPrev; + uint32_t u4NumElem; +}; + +/* Support AP Selection */ +struct LINK_MGMT { + struct LINK rUsingLink; + struct LINK rFreeLink; +}; +/* end Support AP Selection */ +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ +#if 0 +/* No one use it, temporarily mark it for [Lint - Info 773] */ +#define LINK_ADDR(rLink) \ + { (struct LINK_ENTRY *)(&(rLink)), \ + (struct LINK_ENTRY *)(&(rLink)), 0 } + +#define LINK_DECLARATION(rLink) \ + struct LINK rLink = LINK_ADDR(rLink) +#endif + +#define LINK_INITIALIZE(prLink) \ + do { \ + ((struct LINK *)(prLink))->prNext = \ + (struct LINK_ENTRY *)(prLink); \ + ((struct LINK *)(prLink))->prPrev = \ + (struct LINK_ENTRY *)(prLink); \ + ((struct LINK *)(prLink))->u4NumElem = 0; \ + } while (0) +/* Support AP Selection */ +#define LINK_MGMT_INIT(prLinkMgmt) \ +do { \ + LINK_INITIALIZE(&((struct LINK_MGMT *)prLinkMgmt)->rUsingLink); \ + LINK_INITIALIZE(&((struct LINK_MGMT *)prLinkMgmt)->rFreeLink); \ +} while (0) + +#define LINK_MGMT_GET_ENTRY(prLinkMgmt, prEntry, EntryType, memType) \ + do { \ + LINK_REMOVE_HEAD(&((struct LINK_MGMT *)prLinkMgmt)->rFreeLink, \ + prEntry, EntryType*); \ + if (!prEntry) \ + prEntry = kalMemAlloc(sizeof(EntryType), memType); \ + if (prEntry) {\ + kalMemZero(prEntry, sizeof(EntryType));\ + LINK_INSERT_TAIL( \ + &((struct LINK_MGMT *)prLinkMgmt)->rUsingLink, \ + &prEntry->rLinkEntry); \ + } \ + } while (0) + +#define LINK_MGMT_RETURN_ENTRY(prLinkMgmt, prEntry) \ + do {\ + if (!prEntry)\ + break;\ + LINK_REMOVE_KNOWN_ENTRY( \ + &((struct LINK_MGMT *)prLinkMgmt)->rUsingLink, \ + prEntry); \ + LINK_INSERT_TAIL(&((struct LINK_MGMT *)prLinkMgmt)->rFreeLink, \ + &prEntry->rLinkEntry); \ + } while (0) + +#define LINK_MGMT_UNINIT(prLinkMgmt, EntryType, memType) \ + do { \ + EntryType *prEntry = NULL; \ + struct LINK *prFreeList = \ + &((struct LINK_MGMT *)prLinkMgmt)->rFreeLink; \ + struct LINK *prUsingList = \ + &((struct LINK_MGMT *)prLinkMgmt)->rUsingLink; \ + LINK_REMOVE_HEAD(prFreeList, prEntry, EntryType *); \ + while (prEntry) { \ + kalMemFree(prEntry, memType, sizeof(EntryType)); \ + LINK_REMOVE_HEAD(prFreeList, prEntry, EntryType *); \ + } \ + LINK_REMOVE_HEAD(prUsingList, prEntry, EntryType *); \ + while (prEntry) { \ + kalMemFree(prEntry, memType, sizeof(EntryType)); \ + LINK_REMOVE_HEAD(prUsingList, prEntry, EntryType *); \ + } \ + } while (0) +/* end Support AP Selection */ + +#define LINK_ENTRY_INITIALIZE(prEntry) \ + do { \ + ((struct LINK_ENTRY *)(prEntry))->prNext = \ + (struct LINK_ENTRY *)NULL; \ + ((struct LINK_ENTRY *)(prEntry))->prPrev = \ + (struct LINK_ENTRY *)NULL; \ + } while (0) + +#define LINK_ENTRY_INVALID(prEntry) \ + do { \ + ((struct LINK_ENTRY *)(prEntry))->prNext = \ + (struct LINK_ENTRY *)INVALID_LINK_POISON1; \ + ((struct LINK_ENTRY *)(prEntry))->prPrev = \ + (struct LINK_ENTRY *)INVALID_LINK_POISON2; \ + } while (0) + +#define LINK_IS_EMPTY(prLink) \ + (((struct LINK *)(prLink))->prNext == (struct LINK_ENTRY *)(prLink)) + +#define LINK_ENTRY_IS_VALID(prEntry) \ + (((struct LINK_ENTRY *)(prEntry))->prNext != \ + (struct LINK_ENTRY *)NULL && \ + ((struct LINK_ENTRY *)(prEntry))->prNext != \ + (struct LINK_ENTRY *)INVALID_LINK_POISON1 && \ + ((struct LINK_ENTRY *)(prEntry))->prPrev != \ + (struct LINK_ENTRY *)NULL && \ + ((struct LINK_ENTRY *)(prEntry))->prPrev != \ + (struct LINK_ENTRY *)INVALID_LINK_POISON2) + + + +/* NOTE: We should do memory zero before any LINK been initiated, + * so we can check if it is valid before parsing the LINK. + */ +#define LINK_IS_INVALID(prLink) \ + (((struct LINK *)(prLink))->prNext == (struct LINK_ENTRY *)NULL) + +#define LINK_IS_VALID(prLink) \ + (((struct LINK *)(prLink))->prNext != (struct LINK_ENTRY *)NULL) + +#define LINK_ENTRY(ptr, type, member) ENTRY_OF(ptr, type, member) + +/* Insert an entry into a link list's head */ +#define LINK_INSERT_HEAD(prLink, prEntry) \ + { \ + linkAdd(prEntry, prLink); \ + ((prLink)->u4NumElem)++; \ + } + +/* Append an entry into a link list's tail */ +#define LINK_INSERT_TAIL(prLink, prEntry) \ + { \ + linkAddTail(prEntry, prLink); \ + ((prLink)->u4NumElem)++; \ + } + +/* Peek head entry, but keep still in link list */ +#define LINK_PEEK_HEAD(prLink, _type, _member) \ + ( \ + LINK_IS_EMPTY(prLink) ? \ + NULL : LINK_ENTRY((prLink)->prNext, _type, _member) \ + ) + +/* Peek tail entry, but keep still in link list */ +#define LINK_PEEK_TAIL(prLink, _type, _member) \ + ( \ + LINK_IS_EMPTY(prLink) ? \ + NULL : LINK_ENTRY((prLink)->prPrev, _type, _member) \ + ) + +/* Get first entry from a link list */ +/* NOTE: We assume the link entry located at the beginning of "prEntry Type", + * so that we can cast the link entry to other data type without doubts. + * And this macro also decrease the total entry count at the same time. + */ +#define LINK_REMOVE_HEAD(prLink, prEntry, _P_TYPE) \ + { \ + ASSERT(prLink); \ + if (LINK_IS_EMPTY(prLink)) { \ + prEntry = (_P_TYPE)NULL; \ + } \ + else { \ + prEntry = \ + (_P_TYPE)(((struct LINK *)(prLink))->prNext); \ + linkDel((struct LINK_ENTRY *)prEntry); \ + ((prLink)->u4NumElem)--; \ + } \ + } + +/* Assume the link entry located at the beginning of prEntry Type. + * And also decrease the total entry count. + */ +#define LINK_REMOVE_KNOWN_ENTRY(prLink, prEntry) \ + { \ + ASSERT(prLink); \ + ASSERT(prEntry); \ + linkDel((struct LINK_ENTRY *)prEntry); \ + ((prLink)->u4NumElem)--; \ + } + +/* Merge prSrcLink to prDstLink and put prSrcLink ahead of prDstLink */ +#define LINK_MERGE_TO_HEAD(prDstLink, prSrcLink) \ + { \ + if (!LINK_IS_EMPTY(prSrcLink)) { \ + linkMergeToHead((struct LINK *)prDstLink, \ + (struct LINK *)prSrcLink); \ + (prDstLink)->u4NumElem += (prSrcLink)->u4NumElem; \ + LINK_INITIALIZE(prSrcLink); \ + } \ + } + +/* Merge prSrcLink to prDstLink and put prSrcLink at tail */ +#define LINK_MERGE_TO_TAIL(prDstLink, prSrcLink) \ + { \ + if (!LINK_IS_EMPTY(prSrcLink)) { \ + linkMergeToTail((struct LINK *)prDstLink, \ + (struct LINK *)prSrcLink); \ + (prDstLink)->u4NumElem += (prSrcLink)->u4NumElem; \ + LINK_INITIALIZE(prSrcLink); \ + } \ + } + +/* Iterate over a link list */ +#define LINK_FOR_EACH(prEntry, prLink) \ + for (prEntry = (prLink)->prNext; \ + prEntry != (struct LINK_ENTRY *)(prLink); \ + prEntry = (struct LINK_ENTRY *)prEntry->prNext) + +/* Iterate over a link list backwards */ +#define LINK_FOR_EACH_PREV(prEntry, prLink) \ + for (prEntry = (prLink)->prPrev; \ + prEntry != (struct LINK_ENTRY *)(prLink); \ + prEntry = (struct LINK_ENTRY *)prEntry->prPrev) + +/* Iterate over a link list safe against removal of link entry */ +#define LINK_FOR_EACH_SAFE(prEntry, prNextEntry, prLink) \ + for (prEntry = (prLink)->prNext, prNextEntry = prEntry->prNext; \ + prEntry != (struct LINK_ENTRY *)(prLink); \ + prEntry = prNextEntry, prNextEntry = prEntry->prNext) + +/* Iterate over a link list of given type */ +#define LINK_FOR_EACH_ENTRY(prObj, prLink, rMember, _TYPE) \ + for (prObj = LINK_ENTRY((prLink)->prNext, _TYPE, rMember); \ + &prObj->rMember != (struct LINK_ENTRY *)(prLink); \ + prObj = LINK_ENTRY(prObj->rMember.prNext, _TYPE, rMember)) + +/* Iterate backwards over a link list of given type */ +#define LINK_FOR_EACH_ENTRY_PREV(prObj, prLink, rMember, _TYPE) \ + for (prObj = LINK_ENTRY((prLink)->prPrev, _TYPE, rMember); \ + &prObj->rMember != (struct LINK_ENTRY *)(prLink); \ + prObj = LINK_ENTRY(prObj->rMember.prPrev, _TYPE, rMember)) + +/* Iterate over a link list of given type safe against removal of link entry */ +#define LINK_FOR_EACH_ENTRY_SAFE(prObj, prNextObj, prLink, rMember, _TYPE) \ + for (prObj = LINK_ENTRY((prLink)->prNext, _TYPE, rMember), \ + prNextObj = LINK_ENTRY(prObj->rMember.prNext, _TYPE, rMember); \ + &prObj->rMember != (struct LINK_ENTRY *)(prLink); \ + prObj = prNextObj, \ + prNextObj = LINK_ENTRY(prNextObj->rMember.prNext, _TYPE, rMember)) + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is only for internal link list manipulation. + * + * \param[in] prNew Pointer of new link head + * \param[in] prPrev Pointer of previous link head + * \param[in] prNext Pointer of next link head + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +static __KAL_INLINE__ void __linkAdd(IN struct LINK_ENTRY + *prNew, IN struct LINK_ENTRY *prPrev, + IN struct LINK_ENTRY *prNext) +{ + prNext->prPrev = prNew; + prNew->prNext = prNext; + prNew->prPrev = prPrev; + prPrev->prNext = prNew; +} /* end of __linkAdd() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function will add a new entry after the specified link head. + * + * \param[in] prNew New entry to be added + * \param[in] prHead Specified link head to add it after + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +static __KAL_INLINE__ void linkAdd(IN struct LINK_ENTRY + *prNew, IN struct LINK *prLink) +{ + __linkAdd(prNew, (struct LINK_ENTRY *) prLink, + prLink->prNext); +} /* end of linkAdd() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function will add a new entry before the specified link head. + * + * \param[in] prNew New entry to be added + * \param[in] prHead Specified link head to add it before + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +static __KAL_INLINE__ void linkAddTail(IN struct LINK_ENTRY + *prNew, IN struct LINK *prLink) +{ + __linkAdd(prNew, prLink->prPrev, + (struct LINK_ENTRY *) prLink); +} /* end of linkAddTail() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is only for internal link list manipulation. + * + * \param[in] prPrev Pointer of previous link head + * \param[in] prNext Pointer of next link head + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +static __KAL_INLINE__ void __linkDel(IN struct LINK_ENTRY + *prPrev, IN struct LINK_ENTRY *prNext) +{ + prNext->prPrev = prPrev; + prPrev->prNext = prNext; +} /* end of __linkDel() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function will delete a specified entry from link list. + * NOTE: the entry is in an initial state. + * + * \param prEntry Specified link head(entry) + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +static __KAL_INLINE__ void linkDel(IN struct LINK_ENTRY + *prEntry) +{ + __linkDel(prEntry->prPrev, prEntry->prNext); + + LINK_ENTRY_INITIALIZE(prEntry); +} /* end of linkDel() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function will delete a specified entry from link list + * and then add it after the specified link head. + * + * \param[in] prEntry Specified link head(entry) + * \param[in] prOtherHead Another link head to add it after + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +static __KAL_INLINE__ void linkMove(IN struct LINK_ENTRY + *prEntry, IN struct LINK *prLink) +{ + __linkDel(prEntry->prPrev, prEntry->prNext); + linkAdd(prEntry, prLink); +} /* end of linkMove() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function will delete a specified entry from link list + * and then add it before the specified link head. + * + * \param[in] prEntry Specified link head(entry) + * \param[in] prOtherHead Another link head to add it before + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +static __KAL_INLINE__ void linkMoveTail(IN struct LINK_ENTRY + *prEntry, IN struct LINK *prLink) +{ + __linkDel(prEntry->prPrev, prEntry->prNext); + linkAddTail(prEntry, prLink); +} /* end of linkMoveTail() */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function will merge source link to the tail of destination link. +* +* \param[in] prDst destination link +* \param[in] prSrc source link +* +* \return (none) +*/ +/*----------------------------------------------------------------------------*/ +static __KAL_INLINE__ void linkMergeToTail(struct LINK *prDst, + struct LINK *prSrc) +{ + prSrc->prNext->prPrev = prDst->prPrev; + prSrc->prPrev->prNext = (struct LINK_ENTRY *)prDst; + prDst->prPrev->prNext = prSrc->prNext; + prDst->prPrev = prSrc->prPrev; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function will merge source link to the head of destination link. +* +* \param[in] prDst destination link +* \param[in] prSrc source link + +* +* \return (none) +*/ +/*----------------------------------------------------------------------------*/ +static __KAL_INLINE__ void linkMergeToHead(struct LINK *prDst, + struct LINK *prSrc) +{ + prSrc->prNext->prPrev = (struct LINK_ENTRY *)prDst; + prSrc->prPrev->prNext = prDst->prNext; + prDst->prNext->prPrev = prSrc->prPrev; + prDst->prNext = prSrc->prNext; +} + +#endif /* _LINK_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/aa_fsm.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/aa_fsm.h new file mode 100644 index 0000000000000000000000000000000000000000..5db7bf6e5f126ff28f390163a6f1e9fb47ce9313 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/aa_fsm.h @@ -0,0 +1,234 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/ + * include/mgmt/aa_fsm.h#1 + */ + +/*! \file aa_fsm.h + * \brief Declaration of functions and finite state machine for + * SAA/AAA Module. + * + * Declaration of functions and finite state machine for SAA/AAA Module. + */ + +#ifndef _AA_FSM_H +#define _AA_FSM_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +/* Retry interval for retransmiting authentication-request MMPDU. */ +#define TX_AUTHENTICATION_RETRY_TIMEOUT_TU 100 /* TU. */ + +/* Retry interval for retransmiting association-request MMPDU. */ +#define TX_ASSOCIATION_RETRY_TIMEOUT_TU 100 /* TU. */ + +/* Wait for a response to a transmitted authentication-request MMPDU. */ +#define DOT11_AUTHENTICATION_RESPONSE_TIMEOUT_TU 512 /* TU. */ + +/* Wait for a response to a transmitted association-request MMPDU. */ +#define DOT11_ASSOCIATION_RESPONSE_TIMEOUT_TU 512 /* TU. */ + +/* The maximum time to wait for JOIN process complete. */ +/* Beacon Interval, 20 * 100TU = 2 sec. */ +#define JOIN_FAILURE_TIMEOUT_BEACON_INTERVAL 20 + +/* Retry interval for next JOIN request. */ +#define JOIN_RETRY_INTERVAL_SEC 10 /* Seconds */ + +/* Maximum Retry Count for accept a JOIN request. */ +#define JOIN_MAX_RETRY_FAILURE_COUNT 2 /* Times */ + +#define TX_AUTHENTICATION_RESPONSE_TIMEOUT_TU 512 /* TU. */ + +#define TX_ASSOCIATE_TIMEOUT_TU 2048 /* TU. */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +enum ENUM_AA_STATE { + AA_STATE_IDLE = 0, + SAA_STATE_SEND_AUTH1, + SAA_STATE_WAIT_AUTH2, + SAA_STATE_SEND_AUTH3, + SAA_STATE_WAIT_AUTH4, + SAA_STATE_EXTERNAL_AUTH, + SAA_STATE_SEND_ASSOC1, + SAA_STATE_WAIT_ASSOC2, + AAA_STATE_SEND_AUTH2, + AAA_STATE_SEND_AUTH4, /* We may not use, */ + /* because P2P GO didn't support WEP and 11r */ + AAA_STATE_SEND_ASSOC2, + AA_STATE_RESOURCE, /* A state for debugging the case of */ + /* out of msg buffer. */ + AA_STATE_NUM +}; + +enum ENUM_AA_FRM_TYPE { + FRM_DISASSOC = 0, + FRM_DEAUTH +}; + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/*----------------------------------------------------------------------------*/ +/* Routines in saa_fsm.c */ +/*----------------------------------------------------------------------------*/ +void +saaFsmSteps(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, + IN enum ENUM_AA_STATE eNextState, + IN struct SW_RFB *prRetainedSwRfb); + +uint32_t +saaFsmSendEventJoinComplete(IN struct ADAPTER *prAdapter, + uint32_t rJoinStatus, struct STA_RECORD *prStaRec, + struct SW_RFB *prSwRfb); + +void saaFsmRunEventStart(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); + +uint32_t +saaFsmRunEventTxDone(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN enum ENUM_TX_RESULT_CODE rTxDoneStatus); + +void saaFsmRunEventTxReqTimeOut(IN struct ADAPTER + *prAdapter, IN unsigned long plParamPtr); + +void saaFsmRunEventRxRespTimeOut(IN struct ADAPTER + *prAdapter, IN unsigned long ulParamPtr); + +void saaFsmRunEventRxAuth(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb); + +uint32_t saaFsmRunEventRxAssoc(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb); + +uint32_t saaFsmRunEventRxDeauth(IN struct ADAPTER + *prAdapter, IN struct SW_RFB *prSwRfb); + +uint32_t saaFsmRunEventRxDisassoc(IN struct ADAPTER + *prAdapter, IN struct SW_RFB *prSwRfb); + +void saaFsmRunEventAbort(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); + +void saaChkDeauthfrmParamHandler(IN struct ADAPTER + *prAdapter, IN struct SW_RFB *prSwRfb, + IN struct STA_RECORD *prStaRec); + +void +saaChkDisassocfrmParamHandler(IN struct ADAPTER *prAdapter, + IN struct WLAN_DISASSOC_FRAME *prDisassocFrame, + IN struct STA_RECORD *prStaRec, + IN struct SW_RFB *prSwRfb); + +void +saaSendDisconnectMsgHandler(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, + IN struct BSS_INFO *prAisBssInfo, + IN enum ENUM_AA_FRM_TYPE eFrmType); + +void saaFsmRunEventFTContinue(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); + +void saaFsmRunEventExternalAuthDone(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); + +/*----------------------------------------------------------------------------*/ +/* Routines in aaa_fsm.c */ +/*----------------------------------------------------------------------------*/ +void aaaFsmRunEventRxAuth(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb); + +uint32_t aaaFsmRunEventRxAssoc(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb); + +uint32_t +aaaFsmRunEventTxDone(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN enum ENUM_TX_RESULT_CODE rTxDoneStatus); + + +#endif /* _AA_FSM_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/ais_fsm.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/ais_fsm.h new file mode 100644 index 0000000000000000000000000000000000000000..fc68d31c7c5c4020381228058b2f39435dc94c32 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/ais_fsm.h @@ -0,0 +1,757 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/ + * include/mgmt/ais_fsm.h#2 + */ + +/*! \file ais_fsm.h + * \brief Declaration of functions and finite state machine for AIS Module. + * + * Declaration of functions and finite state machine for AIS Module. + */ + + +#ifndef _AIS_FSM_H +#define _AIS_FSM_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#define AIS_BG_SCAN_INTERVAL_MIN_SEC 2 /* 30 // exponential to 960 */ +#define AIS_BG_SCAN_INTERVAL_MAX_SEC 2 /* 960 // 16min */ + +#define AIS_DELAY_TIME_OF_DISCONNECT_SEC 5 /* 10 */ + +#define AIS_IBSS_ALONE_TIMEOUT_SEC 20 /* seconds */ + +#define AIS_BEACON_TIMEOUT_COUNT_ADHOC 30 +#define AIS_BEACON_TIMEOUT_COUNT_INFRA 10 +#define AIS_BEACON_TIMEOUT_GUARD_TIME_SEC 1 /* Second */ + +#define AIS_BEACON_MAX_TIMEOUT_TU 100 +#define AIS_BEACON_MIN_TIMEOUT_TU 5 +#define AIS_BEACON_MAX_TIMEOUT_VALID TRUE +#define AIS_BEACON_MIN_TIMEOUT_VALID TRUE + +#define AIS_BMC_MAX_TIMEOUT_TU 100 +#define AIS_BMC_MIN_TIMEOUT_TU 5 +#define AIS_BMC_MAX_TIMEOUT_VALID TRUE +#define AIS_BMC_MIN_TIMEOUT_VALID TRUE + +#define AIS_JOIN_CH_GRANT_THRESHOLD 10 +#define AIS_JOIN_CH_REQUEST_INTERVAL 4000 +#define AIS_SCN_DONE_TIMEOUT_SEC 15 /* 15 for 2.4G + 5G */ /* 5 */ +#define AIS_SCN_REPORT_SEQ_NOT_SET (0xFFFF) + +/* Support AP Selection*/ +#define AIS_BLACKLIST_TIMEOUT 15 /* seconds */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +enum ENUM_AIS_STATE { + AIS_STATE_IDLE = 0, + AIS_STATE_SEARCH, + AIS_STATE_SCAN, + AIS_STATE_ONLINE_SCAN, + AIS_STATE_LOOKING_FOR, + AIS_STATE_WAIT_FOR_NEXT_SCAN, + AIS_STATE_REQ_CHANNEL_JOIN, + AIS_STATE_JOIN, + AIS_STATE_JOIN_FAILURE, + AIS_STATE_IBSS_ALONE, + AIS_STATE_IBSS_MERGE, + AIS_STATE_NORMAL_TR, + AIS_STATE_DISCONNECTING, + AIS_STATE_REQ_REMAIN_ON_CHANNEL, + AIS_STATE_REMAIN_ON_CHANNEL, + AIS_STATE_OFF_CHNL_TX, + AIS_STATE_NUM +}; + +/* reconnect level for determining if we should reconnect */ +enum ENUM_RECONNECT_LEVEL_T { + RECONNECT_LEVEL_MIN = 0, + RECONNECT_LEVEL_ROAMING_FAIL, /* roaming failed */ + RECONNECT_LEVEL_BEACON_TIMEOUT, /* driver beacon timeout */ + RECONNECT_LEVEL_USER_SET, /* user set connect */ + /* or disassociate */ + RECONNECT_LEVEL_MAX +}; + +struct MSG_AIS_ABORT { + struct MSG_HDR rMsgHdr; /* Must be the first member */ + uint8_t ucReasonOfDisconnect; + u_int8_t fgDelayIndication; + uint8_t ucBssIndex; +}; + +struct MSG_AIS_IBSS_PEER_FOUND { + struct MSG_HDR rMsgHdr; /* Must be the first member */ + uint8_t ucBssIndex; + u_int8_t fgIsMergeIn; /* TRUE: Merge In, FALSE: Merge Out */ + struct STA_RECORD *prStaRec; +}; + +enum ENUM_AIS_REQUEST_TYPE { + AIS_REQUEST_SCAN, + AIS_REQUEST_RECONNECT, + AIS_REQUEST_ROAMING_SEARCH, + AIS_REQUEST_ROAMING_CONNECT, + AIS_REQUEST_REMAIN_ON_CHANNEL, + AIS_REQUEST_NUM +}; + +struct AIS_REQ_HDR { + struct LINK_ENTRY rLinkEntry; + enum ENUM_AIS_REQUEST_TYPE eReqType; +}; + +struct AIS_REQ_CHNL_INFO { + enum ENUM_BAND eBand; + enum ENUM_CHNL_EXT eSco; + uint8_t ucChannelNum; + uint32_t u4DurationMs; + uint64_t u8Cookie; + enum ENUM_CH_REQ_TYPE eReqType; +}; + +struct AIS_MGMT_TX_REQ_INFO { + struct LINK rTxReqLink; + u_int8_t fgIsMgmtTxRequested; + struct MSDU_INFO *prMgmtTxMsdu; + uint64_t u8Cookie; +}; + +/* Support AP Selection */ +struct AIS_BLACKLIST_ITEM { + struct LINK_ENTRY rLinkEntry; + + uint8_t aucBSSID[MAC_ADDR_LEN]; + uint16_t u2DeauthReason; + uint16_t u2AuthStatus; + uint8_t ucCount; + uint8_t ucSSIDLen; + uint8_t aucSSID[32]; + OS_SYSTIME rAddTime; + u_int8_t fgDeauthLastTime; + u_int8_t fgIsInFWKBlacklist; +}; +/* end Support AP Selection */ + +struct AIS_FSM_INFO { + enum ENUM_AIS_STATE ePreviousState; + enum ENUM_AIS_STATE eCurrentState; + + u_int8_t fgIsScanning; + + u_int8_t fgIsChannelRequested; + u_int8_t fgIsChannelGranted; + + uint8_t ucAvailableAuthTypes; /* Used for AUTH_MODE_AUTO_SWITCH */ + + struct BSS_DESC *prTargetBssDesc; /* For destination */ + + struct STA_RECORD *prTargetStaRec; /* For JOIN Abort */ + + uint32_t u4SleepInterval; + + struct TIMER rBGScanTimer; + + struct TIMER rIbssAloneTimer; + + uint32_t u4PostponeIndStartTime; + + struct TIMER rJoinTimeoutTimer; + + struct TIMER rChannelTimeoutTimer; + + struct TIMER rScanDoneTimer; + + struct TIMER rDeauthDoneTimer; + +#if CFG_SUPPORT_DETECT_SECURITY_MODE_CHANGE + struct TIMER rSecModeChangeTimer; +#endif + + uint8_t ucSeqNumOfReqMsg; + uint8_t ucSeqNumOfChReq; + uint8_t ucSeqNumOfScanReq; + + /* Save SeqNum for reporting scan done. + * In order to distinguish seq num and default value, make sure that + * sizeof(u2SeqNumOfScanReport) > sizeof(ucSeqNumOfScanReq). + * Set AIS_SCN_REPORT_SEQ_NOT_SET as default value + */ + uint16_t u2SeqNumOfScanReport; + + uint32_t u4ChGrantedInterval; + + uint8_t ucConnTrialCount; + uint8_t ucConnTrialCountLimit; + + struct PARAM_SCAN_REQUEST_ADV rScanRequest; + uint8_t aucScanIEBuf[MAX_IE_LENGTH]; + + u_int8_t fgIsScanOidAborted; + + /* Pending Request List */ + struct LINK rPendingReqList; + + /* Join Request Timestamp */ + OS_SYSTIME rJoinReqTime; + + /* for cfg80211 REMAIN_ON_CHANNEL support */ + struct AIS_REQ_CHNL_INFO rChReqInfo; + + /* Mgmt tx related. */ + struct AIS_MGMT_TX_REQ_INFO rMgmtTxInfo; + + /* Packet filter for AIS module. */ + uint32_t u4AisPacketFilter; + + /* for roaming target */ + struct PARAM_SSID rRoamingSSID; + + /* Support AP Selection */ + uint8_t ucJoinFailCntAfterScan; + /* end Support AP Selection */ + + /* Scan target channel when device roaming */ + uint8_t fgTargetChnlScanIssued; +}; + +struct AIS_OFF_CHNL_TX_REQ_INFO { + struct LINK_ENTRY rLinkEntry; + struct MSDU_INFO *prMgmtTxMsdu; + u_int8_t fgNoneCckRate; + struct RF_CHANNEL_INFO rChannelInfo; /* Off channel TX. */ + enum ENUM_CHNL_EXT eChnlExt; + /* See if driver should keep at the same channel. */ + u_int8_t fgIsWaitRsp; + uint64_t u8Cookie; /* cookie used to match with supplicant */ + uint32_t u4Duration; /* wait time for tx request */ +}; + +enum WNM_AIS_BSS_TRANSITION { + BSS_TRANSITION_NO_MORE_ACTION, + BSS_TRANSITION_REQ_ROAMING, + BSS_TRANSITION_DISASSOC, + BSS_TRANSITION_MAX_NUM +}; +struct MSG_AIS_BSS_TRANSITION_T { + struct MSG_HDR rMsgHdr; /* Must be the first member */ + uint8_t ucToken; + u_int8_t fgNeedResponse; + uint8_t ucValidityInterval; + enum WNM_AIS_BSS_TRANSITION eTransitionType; + uint16_t u2CandListLen; + uint8_t *pucCandList; + uint8_t ucBssIndex; +}; +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ +#define aisChangeMediaState(_prAisBssInfo, _eNewMediaState) \ + (_prAisBssInfo->eConnectionState = (_eNewMediaState)) + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +void aisInitializeConnectionSettings(IN struct ADAPTER + *prAdapter, IN struct REG_INFO *prRegInfo, + IN uint8_t ucBssIndex); + +void aisFsmInit(IN struct ADAPTER *prAdapter, uint8_t ucBssIndex); + +void aisFsmUninit(IN struct ADAPTER *prAdapter, uint8_t ucBssIndex); + +bool aisFsmIsInProcessPostpone(IN struct ADAPTER *prAdapter, + uint8_t ucBssIndex); + +bool aisFsmIsInBeaconTimeout(IN struct ADAPTER *prAdapter, + uint8_t ucBssIndex); + +void aisFsmStateInit_JOIN(IN struct ADAPTER *prAdapter, + struct BSS_DESC *prBssDesc, uint8_t ucBssIndex); + +u_int8_t aisFsmStateInit_RetryJOIN(IN struct ADAPTER + *prAdapter, IN struct STA_RECORD *prStaRec, + uint8_t ucBssIndex); + +void aisFsmStateInit_IBSS_ALONE(IN struct ADAPTER + *prAdapter, uint8_t ucBssIndex); + +void aisFsmStateInit_IBSS_MERGE(IN struct ADAPTER + *prAdapter, struct BSS_DESC *prBssDesc, uint8_t ucBssIndex); + +void aisFsmStateAbort(IN struct ADAPTER *prAdapter, + uint8_t ucReasonOfDisconnect, u_int8_t fgDelayIndication, + uint8_t ucBssIndex); + +void aisFsmStateAbort_JOIN(IN struct ADAPTER *prAdapter, uint8_t ucBssIndex); + +void aisFsmStateAbort_SCAN(IN struct ADAPTER *prAdapter, uint8_t ucBssIndex); + +void aisFsmStateAbort_NORMAL_TR(IN struct ADAPTER + *prAdapter, uint8_t ucBssIndex); + +void aisFsmStateAbort_IBSS(IN struct ADAPTER *prAdapter, uint8_t ucBssIndex); + +void aisFsmSteps(IN struct ADAPTER *prAdapter, + enum ENUM_AIS_STATE eNextState, uint8_t ucBssIndex); + +/*----------------------------------------------------------------------------*/ +/* Mailbox Message Handling */ +/*----------------------------------------------------------------------------*/ +void aisFsmRunEventScanDone(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); + +void aisFsmRunEventAbort(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); + +void aisFsmRunEventJoinComplete(IN struct ADAPTER + *prAdapter, IN struct MSG_HDR *prMsgHdr); + +enum ENUM_AIS_STATE aisFsmJoinCompleteAction( + IN struct ADAPTER *prAdapter, IN struct MSG_HDR *prMsgHdr); + +void aisFsmRunEventFoundIBSSPeer(IN struct ADAPTER + *prAdapter, IN struct MSG_HDR *prMsgHdr); + +void aisFsmRunEventRemainOnChannel(IN struct ADAPTER + *prAdapter, IN struct MSG_HDR *prMsgHdr); + +void aisFsmRunEventCancelRemainOnChannel(IN struct ADAPTER + *prAdapter, IN struct MSG_HDR *prMsgHdr); + +/*----------------------------------------------------------------------------*/ +/* Handling for Ad-Hoc Network */ +/*----------------------------------------------------------------------------*/ +void aisFsmCreateIBSS(IN struct ADAPTER *prAdapter, uint8_t ucBssIndex); + +void aisFsmMergeIBSS(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec); + +/*----------------------------------------------------------------------------*/ +/* Handling of Incoming Mailbox Message from CNM */ +/*----------------------------------------------------------------------------*/ +void aisFsmRunEventChGrant(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); + +/*----------------------------------------------------------------------------*/ +/* Generating Outgoing Mailbox Message to CNM */ +/*----------------------------------------------------------------------------*/ +void aisFsmReleaseCh(IN struct ADAPTER *prAdapter, IN uint8_t ucBssIndex); + +/*----------------------------------------------------------------------------*/ +/* Event Indication */ +/*----------------------------------------------------------------------------*/ +void +aisIndicationOfMediaStateToHost(IN struct ADAPTER + *prAdapter, + enum ENUM_PARAM_MEDIA_STATE eConnectionState, + u_int8_t fgDelayIndication, + uint8_t ucBssIndex); + +void aisPostponedEventOfDisconnTimeout(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +void aisUpdateBssInfoForJOIN(IN struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + struct SW_RFB *prAssocRspSwRfb); + +void aisUpdateBssInfoForCreateIBSS(IN struct ADAPTER *prAdapter, + uint8_t ucBssIndex); + +void aisUpdateBssInfoForMergeIBSS(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec); + +u_int8_t aisValidateProbeReq(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, + IN uint8_t ucBssIndex, + OUT uint32_t *pu4ControlFlags); + +uint32_t +aisFsmRunEventMgmtFrameTxDone(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN enum ENUM_TX_RESULT_CODE rTxDoneStatus); + +/*----------------------------------------------------------------------------*/ +/* Disconnection Handling */ +/*----------------------------------------------------------------------------*/ +void aisFsmDisconnect(IN struct ADAPTER *prAdapter, + IN u_int8_t fgDelayIndication, + IN uint8_t ucBssIndex); + +/*----------------------------------------------------------------------------*/ +/* Event Handling */ +/*----------------------------------------------------------------------------*/ +void aisBssBeaconTimeout(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +void aisBssBeaconTimeout_impl(IN struct ADAPTER *prAdapter, + IN uint8_t ucBcnTimeoutReason, IN uint8_t ucDisconnectReason, + IN uint8_t ucBssIndex); + +void aisBssLinkDown(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +#if CFG_SUPPORT_DETECT_SECURITY_MODE_CHANGE +void aisBssSecurityChanged(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); +#endif + +uint32_t +aisDeauthXmitComplete(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN enum ENUM_TX_RESULT_CODE rTxDoneStatus); +uint32_t +aisDeauthXmitCompleteBss(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN enum ENUM_TX_RESULT_CODE rTxDoneStatus); + +#if CFG_SUPPORT_ROAMING +void aisFsmRunEventRoamingDiscovery( + IN struct ADAPTER *prAdapter, + uint32_t u4ReqScan, + uint8_t ucBssIndex); + +enum ENUM_AIS_STATE aisFsmRoamingScanResultsUpdate( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +void aisFsmRoamingDisconnectPrevAP(IN struct ADAPTER + *prAdapter, + IN struct STA_RECORD *prTargetStaRec); + +void aisUpdateBssInfoForRoamingAP(IN struct ADAPTER + *prAdapter, IN struct STA_RECORD *prStaRec, + IN struct SW_RFB *prAssocRspSwRfb); +#endif /*CFG_SUPPORT_ROAMING */ + +/*----------------------------------------------------------------------------*/ +/* Timeout Handling */ +/*----------------------------------------------------------------------------*/ +void aisFsmRunEventBGSleepTimeOut(IN struct ADAPTER + *prAdapter, unsigned long ulParamPtr); + +void aisFsmRunEventIbssAloneTimeOut(IN struct ADAPTER + *prAdapter, unsigned long ulParamPtr); + +void aisFsmRunEventJoinTimeout(IN struct ADAPTER *prAdapter, + unsigned long ulParamPtr); + +void aisFsmRunEventChannelTimeout(IN struct ADAPTER + *prAdapter, unsigned long ulParamPtr); + +void aisFsmRunEventDeauthTimeout(IN struct ADAPTER + *prAdapter, unsigned long ulParamPtr); + +#if CFG_SUPPORT_DETECT_SECURITY_MODE_CHANGE +void aisFsmRunEventSecModeChangeTimeout(IN struct ADAPTER + *prAdapter, unsigned long ulParamPtr); +#endif + +/*----------------------------------------------------------------------------*/ +/* OID/IOCTL Handling */ +/*----------------------------------------------------------------------------*/ +void aisFsmScanRequest(IN struct ADAPTER *prAdapter, + IN struct PARAM_SSID *prSsid, IN uint8_t *pucIe, + IN uint32_t u4IeLength, + IN uint8_t ucBssIndex); + +void +aisFsmScanRequestAdv(IN struct ADAPTER *prAdapter, + IN struct PARAM_SCAN_REQUEST_ADV *prRequestIn); + +/*----------------------------------------------------------------------------*/ +/* Internal State Checking */ +/*----------------------------------------------------------------------------*/ +u_int8_t aisFsmIsRequestPending(IN struct ADAPTER *prAdapter, + IN enum ENUM_AIS_REQUEST_TYPE eReqType, + IN u_int8_t bRemove, + IN uint8_t ucBssIndex); + +void aisFsmRemoveRoamingRequest( + IN struct ADAPTER *prAdapter, IN uint8_t ucBssIndex); + +struct AIS_REQ_HDR *aisFsmGetNextRequest(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +u_int8_t aisFsmInsertRequest(IN struct ADAPTER *prAdapter, + IN enum ENUM_AIS_REQUEST_TYPE eReqType, + IN uint8_t ucBssIndex); + +u_int8_t aisFsmInsertRequestToHead(IN struct ADAPTER *prAdapter, + IN enum ENUM_AIS_REQUEST_TYPE eReqType, + IN uint8_t ucBssIndex); + +u_int8_t aisFsmClearRequest(IN struct ADAPTER *prAdapter, + IN enum ENUM_AIS_REQUEST_TYPE eReqType, + IN uint8_t ucBssIndex); + +void aisFsmFlushRequest(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +uint32_t +aisFuncTxMgmtFrame(IN struct ADAPTER *prAdapter, + IN struct AIS_MGMT_TX_REQ_INFO *prMgmtTxReqInfo, + IN struct MSDU_INFO *prMgmtTxMsdu, IN uint64_t u8Cookie, + IN uint8_t ucBssIndex); + +void aisFsmRunEventMgmtFrameTx(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); + +#if CFG_SUPPORT_NCHO +void aisFsmRunEventNchoActionFrameTx(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); +#endif + +void aisFuncValidateRxActionFrame(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb); + +void aisFsmRunEventBssTransition(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); + +void aisFsmRunEventCancelTxWait(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); + +enum ENUM_AIS_STATE aisFsmStateSearchAction( + IN struct ADAPTER *prAdapter, uint8_t ucBssIndex); +#if defined(CFG_TEST_MGMT_FSM) && (CFG_TEST_MGMT_FSM != 0) +void aisTest(void); +#endif /* CFG_TEST_MGMT_FSM */ + +/* Support AP Selection */ +void aisRefreshFWKBlacklist(struct ADAPTER *prAdapter); +struct AIS_BLACKLIST_ITEM *aisAddBlacklist(struct ADAPTER *prAdapter, + struct BSS_DESC *prBssDesc); +void aisRemoveBlackList(struct ADAPTER *prAdapter, struct BSS_DESC *prBssDesc); +void aisRemoveTimeoutBlacklist(struct ADAPTER *prAdapter); +struct AIS_BLACKLIST_ITEM *aisQueryBlackList(struct ADAPTER *prAdapter, + struct BSS_DESC *prBssDesc); +/* end Support AP Selection */ + +/* Support 11K */ +void aisResetNeighborApList(struct ADAPTER *prAdapter, + uint8_t ucBssIndex); +#if CFG_SUPPORT_802_11K +void aisCollectNeighborAP(struct ADAPTER *prAdapter, uint8_t *pucApBuf, + uint16_t u2ApBufLen, uint8_t ucValidInterval, + uint8_t ucBssIndex); +#endif +void aisSendNeighborRequest(struct ADAPTER *prAdapter, + uint8_t ucBssIndex); +/* end Support 11K */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#define AIS_DEFAULT_INDEX (0) + +struct AIS_FSM_INFO *aisGetAisFsmInfo( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +struct AIS_SPECIFIC_BSS_INFO *aisGetAisSpecBssInfo( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +struct BSS_TRANSITION_MGT_PARAM_T * + aisGetBTMParam( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +struct BSS_INFO *aisGetConnectedBssInfo( + IN struct ADAPTER *prAdapter); + +struct BSS_INFO *aisGetAisBssInfo( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +struct STA_RECORD *aisGetStaRecOfAP( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +struct BSS_DESC *aisGetTargetBssDesc( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +struct STA_RECORD *aisGetTargetStaRec( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +uint8_t aisGetTargetBssDescChannel( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +#if CFG_SUPPORT_DETECT_SECURITY_MODE_CHANGE +struct TIMER *aisGetSecModeChangeTimer( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); +#endif + +struct TIMER *aisGetScanDoneTimer( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +enum ENUM_AIS_STATE aisGetCurrState( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +struct CONNECTION_SETTINGS * + aisGetConnSettings( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +struct GL_WPA_INFO *aisGetWpaInfo( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +u_int8_t aisGetWapiMode( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +enum ENUM_PARAM_AUTH_MODE aisGetAuthMode( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +enum ENUM_PARAM_OP_MODE aisGetOPMode( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +enum ENUM_WEP_STATUS aisGetEncStatus( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +struct IEEE_802_11_MIB *aisGetMib( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +struct ROAMING_INFO *aisGetRoamingInfo( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +struct PARAM_BSSID_EX *aisGetCurrBssId( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +#if CFG_SUPPORT_PASSPOINT +struct HS20_INFO *aisGetHS20Info( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); +#endif + +struct RADIO_MEASUREMENT_REQ_PARAMS *aisGetRmReqParam( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +struct RADIO_MEASUREMENT_REPORT_PARAMS * + aisGetRmReportParam( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +struct WMM_INFO * + aisGetWMMInfo( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +#ifdef CFG_SUPPORT_REPLAY_DETECTION +struct GL_DETECT_REPLAY_INFO * + aisGetDetRplyInfo( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); +#endif + +uint8_t * + aisGetFsmState( + IN enum ENUM_AIS_STATE); + +struct FT_IES * + aisGetFtIe( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +struct cfg80211_ft_event_params * + aisGetFtEventParam( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +#endif /* _AIS_FSM_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/ap_selection.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/ap_selection.h new file mode 100644 index 0000000000000000000000000000000000000000..fb45704a6f6a69b0eb9d8b8443f7c64bdf2a3b6f --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/ap_selection.h @@ -0,0 +1,78 @@ +/******************************************************************************* + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ + +#ifndef _AP_SELECTION_H +#define _AP_SELECTION_H + +/* Support AP Selection */ +#if (CFG_SUPPORT_802_11AX == 1) +#define AX_SEL_DEF_WEIGHT (0) +#define AX_SEL_DEF_DIVIDER (1) +#endif + +enum ROAM_TYPE { + ROAM_TYPE_RCPI, + ROAM_TYPE_PER, + ROAM_TYPE_NUM +}; + +struct BSS_DESC *scanSearchBssDescByScoreForAis(struct ADAPTER *prAdapter, + enum ENUM_ROAMING_REASON eRoamReason, uint8_t ucBssIndex); +void scanGetCurrentEssChnlList(struct ADAPTER *prAdapter, uint8_t ucBssIndex); +uint8_t scanCheckNeedDriverRoaming( + struct ADAPTER *prAdapter, uint8_t ucBssIndex); +uint8_t scanBeaconTimeoutFilterPolicyForAis(struct ADAPTER *prAdapter, + uint8_t ucBssIndex); +u_int8_t scanApOverload(uint16_t status, uint16_t reason); + +#endif + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/assoc.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/assoc.h new file mode 100644 index 0000000000000000000000000000000000000000..8457f5d8547a7821cdc2866db48389fa4d83dcc6 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/assoc.h @@ -0,0 +1,157 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/ + * include/mgmt/assoc.h#1 + */ + +/*! \file assoc.h + * \brief This file contains the ASSOC REQ/RESP of + * IEEE 802.11 family for MediaTek 802.11 Wireless LAN Adapters. + */ + + +#ifndef _ASSOC_H +#define _ASSOC_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +/*----------------------------------------------------------------------------*/ +/* Routines in assoc.c */ +/*----------------------------------------------------------------------------*/ +uint32_t assocSendReAssocReqFrame(IN struct ADAPTER + *prAdapter, IN struct STA_RECORD *prStaRec); + +uint32_t assocCheckTxReAssocReqFrame(IN struct ADAPTER + *prAdapter, IN struct MSDU_INFO *prMsduInfo); + +uint32_t assocCheckTxReAssocRespFrame(IN struct ADAPTER + *prAdapter, IN struct MSDU_INFO *prMsduInfo); + +uint32_t +assocCheckRxReAssocRspFrameStatus(IN struct ADAPTER + *prAdapter, IN struct SW_RFB *prSwRfb, + OUT uint16_t *pu2StatusCode); + +uint32_t assocSendDisAssocFrame(IN struct ADAPTER + *prAdapter, IN struct STA_RECORD *prStaRec, + IN uint16_t u2ReasonCode); + +uint32_t +assocProcessRxDisassocFrame(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, + IN uint8_t aucBSSID[], + OUT uint16_t *pu2ReasonCode); + +uint32_t assocProcessRxAssocReqFrame(IN struct ADAPTER + *prAdapter, IN struct SW_RFB *prSwRfb, + OUT uint16_t *pu2StatusCode); + +uint32_t assocSendReAssocRespFrame(IN struct ADAPTER + *prAdapter, IN struct STA_RECORD *prStaRec); + +uint16_t assocBuildCapabilityInfo(IN struct ADAPTER + *prAdapter, IN struct STA_RECORD *prStaRec); + +uint16_t assoc_get_nonwfa_vend_ie_len(struct ADAPTER *prAdapter, + uint8_t ucBssIndex); + +void assoc_build_nonwfa_vend_ie(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo); + +void assocGenerateMDIE(IN struct ADAPTER *prAdapter, + IN OUT struct MSDU_INFO *prMsduInfo); + +uint32_t assocCalculateConnIELen(struct ADAPTER *prAdapter, uint8_t ucBssIdx, + struct STA_RECORD *prStaRec); + +void assocGenerateConnIE(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo); + +#endif /* _ASSOC_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/auth.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/auth.h new file mode 100644 index 0000000000000000000000000000000000000000..e318d605a99ac6cf8b5d0b455704da2d7259fad2 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/auth.h @@ -0,0 +1,182 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/ + * include/mgmt/auth.h#1 + */ + +/*! \file auth.h + * \brief This file contains the authentication REQ/RESP of + * IEEE 802.11 family for MediaTek 802.11 Wireless LAN Adapters. + */ + + +#ifndef _AUTH_H +#define _AUTH_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +/*----------------------------------------------------------------------------*/ +/* Routines in auth.c */ +/*----------------------------------------------------------------------------*/ +void authAddIEChallengeText(IN struct ADAPTER *prAdapter, + IN OUT struct MSDU_INFO *prMsduInfo); + +#if !CFG_SUPPORT_AAA +uint32_t authSendAuthFrame(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, + IN uint16_t u2TransactionSeqNum); +#else +uint32_t +authSendAuthFrame(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, + IN uint8_t uBssIndex, + IN struct SW_RFB *prFalseAuthSwRfb, + IN uint16_t u2TransactionSeqNum, + IN uint16_t u2StatusCode); +#endif /* CFG_SUPPORT_AAA */ + +uint32_t authCheckTxAuthFrame(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN uint16_t u2TransactionSeqNum); + +uint32_t authCheckRxAuthFrameTransSeq(IN struct ADAPTER + *prAdapter, IN struct SW_RFB *prSwRfb); + +uint32_t +authCheckRxAuthFrameStatus(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, + IN uint16_t u2TransactionSeqNum, + OUT uint16_t *pu2StatusCode); + +void authHandleIEChallengeText(struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb, struct IE_HDR *prIEHdr); + +uint32_t authProcessRxAuth2_Auth4Frame(IN struct ADAPTER + *prAdapter, IN struct SW_RFB *prSwRfb); + +uint32_t +authSendDeauthFrame(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo, + IN struct STA_RECORD *prStaRec, + IN struct SW_RFB *prClassErrSwRfb, IN uint16_t u2ReasonCode, + IN PFN_TX_DONE_HANDLER pfTxDoneHandler); + +uint32_t authProcessRxDeauthFrame(IN struct SW_RFB *prSwRfb, + IN uint8_t aucBSSID[], OUT uint16_t *pu2ReasonCode); + +uint32_t +authProcessRxAuth1Frame(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, + IN uint8_t aucExpectedBSSID[], + IN uint16_t u2ExpectedAuthAlgNum, + IN uint16_t u2ExpectedTransSeqNum, + OUT uint16_t *pu2ReturnStatusCode); +uint32_t +authProcessRxAuthFrame(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, + IN struct BSS_INFO *prBssInfo, + OUT uint16_t *pu2ReturnStatusCode); + +void authAddMDIE(IN struct ADAPTER *prAdapter, + IN OUT struct MSDU_INFO *prMsduInfo); + +uint32_t authCalculateRSNIELen(struct ADAPTER *prAdapter, uint8_t ucBssIdx, + struct STA_RECORD *prStaRec); + +void authAddRSNIE(IN struct ADAPTER *prAdapter, + IN OUT struct MSDU_INFO *prMsduInfo); + +uint32_t authAddRSNIE_impl(IN struct ADAPTER *prAdapter, + IN OUT struct MSDU_INFO *prMsduInfo); + +void authHandleFtIEs(struct ADAPTER *prAdapter, struct SW_RFB *prSwRfb, + struct IE_HDR *prIEHdr); + +#endif /* _AUTH_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/bow_fsm.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/bow_fsm.h new file mode 100644 index 0000000000000000000000000000000000000000..51c5ff69879696012f9972f2ff99f27a87701608 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/bow_fsm.h @@ -0,0 +1,189 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* +** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/bow_fsm.h#1 +*/ + +/*! \file bow_fsm.h +* \brief Declaration of functions and finite state machine for BOW Module. +* +* Declaration of functions and finite state machine for BOW Module. +*/ + + +#ifndef _BOW_FSM_H +#define _BOW_FSM_H + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +#define BOW_BG_SCAN_INTERVAL_MIN_SEC 2 /* 30 // exponential to 960 */ +#define BOW_BG_SCAN_INTERVAL_MAX_SEC 2 /* 960 // 16min */ + +#define BOW_DELAY_TIME_OF_DISCONNECT_SEC 10 + +#define BOW_BEACON_TIMEOUT_COUNT_STARTING 10 +#define BOW_BEACON_TIMEOUT_GUARD_TIME_SEC 1 /* Second */ + +#define BOW_BEACON_MAX_TIMEOUT_TU 100 +#define BOW_BEACON_MIN_TIMEOUT_TU 5 +#define BOW_BEACON_MAX_TIMEOUT_VALID TRUE +#define BOW_BEACON_MIN_TIMEOUT_VALID TRUE + +#define BOW_BMC_MAX_TIMEOUT_TU 100 +#define BOW_BMC_MIN_TIMEOUT_TU 5 +#define BOW_BMC_MAX_TIMEOUT_VALID TRUE +#define BOW_BMC_MIN_TIMEOUT_VALID TRUE + +#define BOW_JOIN_CH_GRANT_THRESHOLD 10 +#define BOW_JOIN_CH_REQUEST_INTERVAL 2000 + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +enum ENUM_BOW_STATE { + BOW_STATE_IDLE = 0, + BOW_STATE_SEARCH, + BOW_STATE_SCAN, + BOW_STATE_ONLINE_SCAN, + BOW_STATE_LOOKING_FOR, + BOW_STATE_WAIT_FOR_NEXT_SCAN, + BOW_STATE_REQ_CHANNEL_JOIN, + BOW_STATE_REQ_CHANNEL_ALONE, + BOW_STATE_REQ_CHANNEL_MERGE, + BOW_STATE_JOIN, + BOW_STATE_IBSS_ALONE, + BOW_STATE_IBSS_MERGE, + BOW_STATE_NORMAL_TR, + BOW_STATE_NUM +}; + +struct BOW_FSM_INFO { + /* Channel Privilege */ + u_int8_t fgIsChannelRequested; + u_int8_t fgIsChannelGranted; + uint32_t u4ChGrantedInterval; + + uint8_t ucPrimaryChannel; + enum ENUM_BAND eBand; + uint16_t u2BeaconInterval; + + struct STA_RECORD *prTargetStaRec; + struct BSS_DESC *prTargetBssDesc; /* For destination */ + + uint8_t aucPeerAddress[6]; + uint8_t ucBssIndex; /* Assume there is only 1 BSS for BOW */ + uint8_t ucRole; /* Initiator or responder */ + uint8_t ucAvailableAuthTypes; /* Used for AUTH_MODE_AUTO_SWITCH */ + + u_int8_t fgSupportQoS; + + /* Sequence number of requested message. */ + uint8_t ucSeqNumOfChReq; + uint8_t ucSeqNumOfReqMsg; + uint8_t ucSeqNumOfScnMsg; + uint8_t ucSeqNumOfScanReq; + uint8_t ucSeqNumOfCancelMsg; + + /* Timer */ + struct TIMER rStartingBeaconTimer; /* For device discovery time of each discovery request from user. */ + struct TIMER rChGrantedTimer; + + /* can be deleted? */ + struct TIMER rIndicationOfDisconnectTimer; + +}; + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +#define bowChangeMediaState(_prBssInfo, _eNewMediaState) \ + (_prBssInfo->eConnectionState = (_eNewMediaState)) + /* (_prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX].eConnectionState = (_eNewMediaState)); */ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/bss.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/bss.h new file mode 100644 index 0000000000000000000000000000000000000000..f82f15dbda326aed23d4d9f7dea4500eb6065153 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/bss.h @@ -0,0 +1,300 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ + +/*! \file "bss.h" + * \brief In this file we define the function prototype used in BSS/IBSS. + * + * The file contains the function declarations and defines + * for used in BSS/IBSS. + */ + + +#ifndef _BSS_H +#define _BSS_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "wlan_def.h" +extern const uint8_t *apucNetworkType[NETWORK_TYPE_NUM]; + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#define BSS_DEFAULT_NUM KAL_BSS_NUM + +/* Define how many concurrent operation networks. */ +#define BSS_P2P_NUM KAL_P2P_NUM + +#if (BSS_P2P_NUM > MAX_BSSID_NUM) +#error Exceed HW capability (KAL_BSS_NUM or KAL_P2P_NUM)!! +#endif + +/* NOTE(Kevin): change define for george */ +/* #define MAX_LEN_TIM_PARTIAL_BMP (((MAX_ASSOC_ID + 1) + 7) / 8) */ +/* Required bits = (MAX_ASSOC_ID + 1) */ +#define MAX_LEN_TIM_PARTIAL_BMP ((CFG_STA_REC_NUM + 7) / 8) +/* reserve length greater than maximum size of STA_REC */ +/* obsoleted: Assume we only use AID:1~15 */ + +/* CTRL FLAGS for Probe Response */ +#define BSS_PROBE_RESP_USE_P2P_DEV_ADDR BIT(0) +#define BSS_PROBE_RESP_INCLUDE_P2P_IE BIT(1) + +#define MAX_BSS_INDEX HW_BSSID_NUM +#define P2P_DEV_BSS_INDEX MAX_BSS_INDEX + +#define IS_BSS_ALIVE(_prAdapter, _prBssInfo) \ + (_prBssInfo->fgIsInUse && \ + _prBssInfo->fgIsNetActive && \ + (_prBssInfo->eConnectionState == MEDIA_STATE_CONNECTED || \ + (_prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT && \ + IS_NET_PWR_STATE_ACTIVE(_prAdapter, \ + _prBssInfo->ucBssIndex)))) + +#define IS_BSS_NOT_ALIVE(_prAdapter, _prBssInfo) \ + (!IS_BSS_ALIVE(_prAdapter, _prBssInfo)) + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ +#define IS_BSS_INDEX_VALID(_ucBssIndex) ((_ucBssIndex) <= P2P_DEV_BSS_INDEX) + +#define GET_BSS_INFO_BY_INDEX(_prAdapter, _ucBssIndex) \ + ((_prAdapter)->aprBssInfo[(_ucBssIndex)]) + +#define bssAssignAssocID(_prStaRec) ((_prStaRec)->ucIndex + 1) + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +/*----------------------------------------------------------------------------*/ +/* Routines for all Operation Modes */ +/*----------------------------------------------------------------------------*/ +struct STA_RECORD * +bssCreateStaRecFromBssDesc(IN struct ADAPTER *prAdapter, + IN enum ENUM_STA_TYPE eStaType, IN uint8_t uBssIndex, + IN struct BSS_DESC *prBssDesc); + +void bssComposeNullFrame(IN struct ADAPTER *prAdapter, + IN uint8_t *pucBuffer, IN struct STA_RECORD *prStaRec); + +void +bssComposeQoSNullFrame(IN struct ADAPTER *prAdapter, + IN uint8_t *pucBuffer, IN struct STA_RECORD *prStaRec, + IN uint8_t ucUP, IN u_int8_t fgSetEOSP); + +uint32_t +bssSendNullFrame(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, + IN PFN_TX_DONE_HANDLER pfTxDoneHandler); + +uint32_t +bssSendQoSNullFrame(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, IN uint8_t ucUP, + IN PFN_TX_DONE_HANDLER pfTxDoneHandler); + +void bssDumpBssInfo(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +void bssDetermineApBssInfoPhyTypeSet(IN struct ADAPTER + *prAdapter, IN u_int8_t fgIsPureAp, + OUT struct BSS_INFO *prBssInfo); +int8_t bssGetRxNss(IN struct ADAPTER *prAdapter, + IN struct BSS_DESC *prBssDesc); +#if CFG_SUPPORT_IOT_AP_BLACKLIST +uint32_t bssGetIotApAction(IN struct ADAPTER *prAdapter, + IN struct BSS_DESC *prBssDesc); +#endif +/*----------------------------------------------------------------------------*/ +/* Routines for both IBSS(AdHoc) and BSS(AP) */ +/*----------------------------------------------------------------------------*/ +void bssGenerateExtSuppRate_IE(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo); + +void +bssBuildBeaconProbeRespFrameCommonIEs(IN struct MSDU_INFO + *prMsduInfo, + IN struct BSS_INFO *prBssInfo, + IN uint8_t *pucDestAddr); + +void +bssComposeBeaconProbeRespFrameHeaderAndFF( + IN uint8_t *pucBuffer, + IN uint8_t *pucDestAddr, + IN uint8_t *pucOwnMACAddress, + IN uint8_t *pucBSSID, IN uint16_t u2BeaconInterval, + IN uint16_t u2CapInfo); + +uint32_t +bssSendBeaconProbeResponse(IN struct ADAPTER *prAdapter, + IN uint8_t uBssIndex, IN uint8_t *pucDestAddr, + IN uint32_t u4ControlFlags); + +uint32_t bssProcessProbeRequest(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb); + +void bssInitializeClientList(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo); + +void bssAddClient(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo, + IN struct STA_RECORD *prStaRec); + +u_int8_t bssRemoveClient(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo, + IN struct STA_RECORD *prStaRec); + +struct STA_RECORD *bssRemoveClientByMac(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo, + IN uint8_t *pucMac); + +struct STA_RECORD *bssGetClientByMac(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo, + IN uint8_t *pucMac); + +struct STA_RECORD *bssRemoveHeadClient(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo); + +uint32_t bssGetClientCount(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo); + +void bssDumpClientList(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo); + +void bssCheckClientList(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo); + +/*----------------------------------------------------------------------------*/ +/* Routines for IBSS(AdHoc) only */ +/*----------------------------------------------------------------------------*/ +void +ibssProcessMatchedBeacon(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo, + IN struct BSS_DESC *prBssDesc, IN uint8_t ucRCPI); + +uint32_t ibssCheckCapabilityForAdHocMode( + IN struct ADAPTER *prAdapter, + IN struct BSS_DESC *prBssDesc, + IN uint8_t uBssIndex); + +void ibssInitForAdHoc(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo); + +uint32_t bssUpdateBeaconContent(IN struct ADAPTER + *prAdapter, IN uint8_t uBssIndex); + +/*----------------------------------------------------------------------------*/ +/* Routines for BSS(AP) only */ +/*----------------------------------------------------------------------------*/ +void bssInitForAP(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo, IN u_int8_t fgIsRateUpdate); + +void bssUpdateDTIMCount(IN struct ADAPTER *prAdapter, + IN uint8_t uBssIndex); + +void bssSetTIMBitmap(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo, IN uint16_t u2AssocId); + +/*link function to p2p module for txBcnIETable*/ + +/* WMM-2.2.2 WMM ACI to AC coding */ +enum ENUM_ACI { + ACI_BE = 0, + ACI_BK = 1, + ACI_VI = 2, + ACI_VO = 3, + ACI_NUM +}; + +enum ENUM_AC_PRIORITY { + AC_BK_PRIORITY = 0, + AC_BE_PRIORITY, + AC_VI_PRIORITY, + AC_VO_PRIORITY +}; + +#if (CFG_SUPPORT_HE_ER == 1) +struct EVENT_ER_TX_MODE { + uint8_t ucBssInfoIdx; + uint8_t ucErMode; +}; + +void bssProcessErTxModeEvent(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent); +#endif + +#endif /* _BSS_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/cnm.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/cnm.h new file mode 100644 index 0000000000000000000000000000000000000000..12652f22f9b068c5832f5373d5063a6c0bc9b38b --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/cnm.h @@ -0,0 +1,418 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3 + * /include/mgmt/cnm.h#1 + */ + +/*! \file "cnm.h" + * \brief + */ + + +#ifndef _CNM_H +#define _CNM_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "nic_cmd_event.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#if CFG_SUPPORT_DBDC +#define DBDC_5G_WMM_INDEX 0 +#define DBDC_2G_WMM_INDEX 1 +#endif +#define HW_WMM_NUM (prAdapter->ucWmmSetNum) +#define MAX_HW_WMM_INDEX (HW_WMM_NUM - 1) +#define DEFAULT_HW_WMM_INDEX MAX_HW_WMM_INDEX +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +#if (CFG_SUPPORT_IDC_CH_SWITCH == 1) +enum ENUM_CH_SWITCH_TYPE { + CH_SWITCH_2G, /* Default */ + CH_SWITCH_5G, + CH_SWITCH_NUM +}; +#endif + +struct MSG_CH_REQ { + struct MSG_HDR rMsgHdr; /* Must be the first member */ + uint8_t ucBssIndex; + uint8_t ucTokenID; + uint8_t ucPrimaryChannel; + enum ENUM_CHNL_EXT eRfSco; + enum ENUM_BAND eRfBand; + + /* To support 80/160MHz bandwidth */ + enum ENUM_CHANNEL_WIDTH eRfChannelWidth; + + uint8_t ucRfCenterFreqSeg1; /* To support 80/160MHz bandwidth */ + uint8_t ucRfCenterFreqSeg2; /* To support 80/160MHz bandwidth */ + enum ENUM_CH_REQ_TYPE eReqType; + uint32_t u4MaxInterval; /* In unit of ms */ + enum ENUM_DBDC_BN eDBDCBand; +}; + +struct MSG_CH_ABORT { + struct MSG_HDR rMsgHdr; /* Must be the first member */ + uint8_t ucBssIndex; + uint8_t ucTokenID; + enum ENUM_DBDC_BN eDBDCBand; +}; + +struct MSG_CH_GRANT { + struct MSG_HDR rMsgHdr; /* Must be the first member */ + uint8_t ucBssIndex; + uint8_t ucTokenID; + uint8_t ucPrimaryChannel; + enum ENUM_CHNL_EXT eRfSco; + enum ENUM_BAND eRfBand; + + /* To support 80/160MHz bandwidth */ + enum ENUM_CHANNEL_WIDTH eRfChannelWidth; + + uint8_t ucRfCenterFreqSeg1; /* To support 80/160MHz bandwidth */ + uint8_t ucRfCenterFreqSeg2; /* To support 80/160MHz bandwidth */ + enum ENUM_CH_REQ_TYPE eReqType; + uint32_t u4GrantInterval; /* In unit of ms */ + enum ENUM_DBDC_BN eDBDCBand; +}; + +struct MSG_CH_REOCVER { + struct MSG_HDR rMsgHdr; /* Must be the first member */ + uint8_t ucBssIndex; + uint8_t ucTokenID; + uint8_t ucPrimaryChannel; + enum ENUM_CHNL_EXT eRfSco; + enum ENUM_BAND eRfBand; + + /* To support 80/160MHz bandwidth */ + enum ENUM_CHANNEL_WIDTH eRfChannelWidth; + + uint8_t ucRfCenterFreqSeg1; /* To support 80/160MHz bandwidth */ + uint8_t ucRfCenterFreqSeg2; /* To support 80/160MHz bandwidth */ + enum ENUM_CH_REQ_TYPE eReqType; +}; + +struct CNM_INFO { + u_int8_t fgChGranted; + uint8_t ucBssIndex; + uint8_t ucTokenID; +}; + +#if CFG_ENABLE_WIFI_DIRECT +/* Moved from p2p_fsm.h */ +struct DEVICE_TYPE { + uint16_t u2CategoryId; /* Category ID */ + uint8_t aucOui[4]; /* OUI */ + uint16_t u2SubCategoryId; /* Sub Category ID */ +} __KAL_ATTRIB_PACKED__; +#endif + +#if CFG_SUPPORT_DBDC +enum ENUM_CNM_DBDC_MODE { + /* A/G traffic separate by WMM, but both + * TRX on band 0, CANNOT enable DBDC + */ + ENUM_DBDC_MODE_DISABLED, + + /* A/G traffic separate by WMM, WMM0/1 + * TRX on band 0/1, CANNOT disable DBDC + */ + ENUM_DBDC_MODE_STATIC, + + /* Automatically enable/disable DBDC, + * setting just like static/disable mode + */ + ENUM_DBDC_MODE_DYNAMIC, + + ENUM_DBDC_MODE_NUM +}; + +enum ENUM_CNM_DBDC_SWITCH_MECHANISM { /* When DBDC available in dynamic DBDC */ + /* Switch to DBDC when available (less latency) */ + ENUM_DBDC_SWITCH_MECHANISM_LATENCY_MODE, + + /* Switch to DBDC when DBDC T-put > MCC T-put */ + ENUM_DBDC_SWITCH_MECHANISM_THROUGHPUT_MODE, + + ENUM_DBDC_SWITCH_MECHANISM_NUM +}; +#endif /* CFG_SUPPORT_DBDC */ + +enum ENUM_CNM_NETWORK_TYPE_T { + ENUM_CNM_NETWORK_TYPE_OTHER, + ENUM_CNM_NETWORK_TYPE_AIS, + ENUM_CNM_NETWORK_TYPE_P2P_GC, + ENUM_CNM_NETWORK_TYPE_P2P_GO, + ENUM_CNM_NETWORK_TYPE_NUM +}; + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ +#define CNM_CH_GRANTED_FOR_BSS(_prAdapter, _ucBssIndex) \ + ((_prAdapter)->rCnmInfo.fgChGranted && \ + (_prAdapter)->rCnmInfo.ucBssIndex == (_ucBssIndex)) + +/* True if our TxNss > 1 && peer support 2ss rate && peer no Rx limit. */ +#define IS_CONNECTION_NSS2(prBssInfo, prStaRec) \ + ((((prBssInfo)->ucOpTxNss > 1) && \ + ((prStaRec)->aucRxMcsBitmask[1] != 0x00) \ + && (((prStaRec)->u2HtCapInfo & HT_CAP_INFO_SM_POWER_SAVE) != 0)) || \ + (((prBssInfo)->ucOpTxNss > 1) && ((((prStaRec)->u2VhtRxMcsMap \ + & BITS(2, 3)) >> 2) != BITS(0, 1)) && ((((prStaRec)->ucVhtOpMode \ + & VHT_OP_MODE_RX_NSS) >> VHT_OP_MODE_RX_NSS_OFFSET) > 0))) + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +void cnmInit(struct ADAPTER *prAdapter); + +void cnmUninit(struct ADAPTER *prAdapter); + +void cnmChMngrRequestPrivilege(struct ADAPTER *prAdapter, + struct MSG_HDR *prMsgHdr); + +void cnmChMngrAbortPrivilege(struct ADAPTER *prAdapter, + struct MSG_HDR *prMsgHdr); + +void cnmChMngrHandleChEvent(struct ADAPTER *prAdapter, + struct WIFI_EVENT *prEvent); + +#if (CFG_SUPPORT_DFS_MASTER == 1) +void cnmRadarDetectEvent(struct ADAPTER *prAdapter, + struct WIFI_EVENT *prEvent); + +void cnmCsaDoneEvent(struct ADAPTER *prAdapter, + struct WIFI_EVENT *prEvent); + +#if (CFG_SUPPORT_IDC_CH_SWITCH == 1) +uint8_t cnmIdcCsaReq(IN struct ADAPTER *prAdapter, + IN uint8_t ch_num, IN uint8_t ucRoleIdx); + +void cnmIdcDetectHandler(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent); +#endif +#endif + +uint8_t cnmSapChannelSwitchReq(IN struct ADAPTER *prAdapter, + IN struct RF_CHANNEL_INFO *prRfChannelInfo, + IN uint8_t ucRoleIdx); + +u_int8_t cnmPreferredChannel(struct ADAPTER *prAdapter, enum ENUM_BAND *prBand, + uint8_t *pucPrimaryChannel, enum ENUM_CHNL_EXT *prBssSCO); + +u_int8_t cnmAisInfraChannelFixed(struct ADAPTER *prAdapter, + enum ENUM_BAND *prBand, uint8_t *pucPrimaryChannel); + +void cnmAisInfraConnectNotify(struct ADAPTER *prAdapter); + +u_int8_t cnmAisIbssIsPermitted(struct ADAPTER *prAdapter); + +u_int8_t cnmP2PIsPermitted(struct ADAPTER *prAdapter); + +u_int8_t cnmBowIsPermitted(struct ADAPTER *prAdapter); + +u_int8_t cnmBss40mBwPermitted(struct ADAPTER *prAdapter, uint8_t ucBssIndex); + +u_int8_t cnmBss80mBwPermitted(struct ADAPTER *prAdapter, uint8_t ucBssIndex); + +uint8_t cnmGetBssMaxBw(struct ADAPTER *prAdapter, uint8_t ucBssIndex); + +uint8_t cnmGetBssMaxBwToChnlBW(struct ADAPTER *prAdapter, uint8_t ucBssIndex); + +struct BSS_INFO *cnmGetBssInfoAndInit(struct ADAPTER *prAdapter, + enum ENUM_NETWORK_TYPE eNetworkType, u_int8_t fgIsP2pDevice); + +void cnmFreeBssInfo(struct ADAPTER *prAdapter, struct BSS_INFO *prBssInfo); +#if CFG_SUPPORT_CHNL_CONFLICT_REVISE +u_int8_t cnmAisDetectP2PChannel(struct ADAPTER *prAdapter, + enum ENUM_BAND *prBand, uint8_t *pucPrimaryChannel); +#endif + +u_int8_t cnmWmmIndexDecision(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo); +void cnmFreeWmmIndex(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo); + +#if CFG_SUPPORT_DBDC +void cnmInitDbdcSetting(IN struct ADAPTER *prAdapter); + +uint32_t cnmUpdateDbdcSetting( + IN struct ADAPTER *prAdapter, + IN u_int8_t fgDbdcEn); + +uint8_t cnmGetDbdcBwCapability( + struct ADAPTER *prAdapter, + uint8_t ucBssIndex +); + +void cnmDbdcPreConnectionEnableDecision( + IN struct ADAPTER *prAdapter, + IN uint8_t ucChangedBssIndex, + IN enum ENUM_BAND eRfBand, + IN uint8_t ucPrimaryChannel, + IN uint8_t ucWmmQueIdx +); + +void cnmDbdcRuntimeCheckDecision(IN struct ADAPTER *prAdapter, + IN uint8_t ucChangedBssIndex); +void cnmDbdcGuardTimerCallback(IN struct ADAPTER *prAdapter, + IN unsigned long plParamPtr); +void cnmDbdcEventHwSwitchDone(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent); +u_int8_t cnmDBDCIsReqPeivilegeLock(void); +#endif /*CFG_SUPPORT_DBDC*/ + +enum ENUM_CNM_NETWORK_TYPE_T cnmGetBssNetworkType(struct BSS_INFO *prBssInfo); + +u_int8_t cnmSapIsActive(IN struct ADAPTER *prAdapter); + +u_int8_t cnmSapIsConcurrent(IN struct ADAPTER *prAdapter); + +struct BSS_INFO *cnmGetSapBssInfo(IN struct ADAPTER *prAdapter); + +void cnmOpModeGetTRxNss( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + OUT uint8_t *pucOpRxNss, + OUT uint8_t *pucOpTxNss +); +#if CFG_SUPPORT_SMART_GEAR +void cnmEventSGStatus( + IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent +); +#endif + +void cnmOpmodeEventHandler( + IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent +); + +u_int8_t cnmP2pIsActive(IN struct ADAPTER *prAdapter); + +struct BSS_INFO *cnmGetP2pBssInfo(IN struct ADAPTER *prAdapter); + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +#ifndef _lint +/* We don't have to call following function to inspect the data structure. + * It will check automatically while at compile time. + * We'll need this to guarantee the same member order in different structures + * to simply handling effort in some functions. + */ +static __KAL_INLINE__ void cnmMsgDataTypeCheck(void) +{ + DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF( + struct MSG_CH_GRANT, rMsgHdr) + == 0); + + DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF( + struct MSG_CH_GRANT, rMsgHdr) + == OFFSET_OF(struct MSG_CH_REOCVER, rMsgHdr)); + + DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF( + struct MSG_CH_GRANT, ucBssIndex) + == OFFSET_OF(struct MSG_CH_REOCVER, ucBssIndex)); + + DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF( + struct MSG_CH_GRANT, ucTokenID) + == OFFSET_OF(struct MSG_CH_REOCVER, ucTokenID)); + + DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF( + struct MSG_CH_GRANT, ucPrimaryChannel) + == OFFSET_OF(struct MSG_CH_REOCVER, ucPrimaryChannel)); + + DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF( + struct MSG_CH_GRANT, eRfSco) + == OFFSET_OF(struct MSG_CH_REOCVER, eRfSco)); + + DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF( + struct MSG_CH_GRANT, eRfBand) + == OFFSET_OF(struct MSG_CH_REOCVER, eRfBand)); + + DATA_STRUCT_INSPECTING_ASSERT( + OFFSET_OF(struct MSG_CH_GRANT, eReqType) + == OFFSET_OF(struct MSG_CH_REOCVER, eReqType)); +} +#endif /* _lint */ + +#endif /* _CNM_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/cnm_mem.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/cnm_mem.h new file mode 100644 index 0000000000000000000000000000000000000000..09fdafcb3f9718c9c43b866cd554d4c243b7c5b7 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/cnm_mem.h @@ -0,0 +1,1224 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3 + * /include/mgmt/cnm_mem.h#1 + */ + +/*! \file "cnm_mem.h" + * \brief In this file we define the structure of the control unit of + * packet buffer and MGT/MSG Memory Buffer. + */ + + +#ifndef _CNM_MEM_H +#define _CNM_MEM_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "qosmap.h" +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +#ifndef POWER_OF_2 +#define POWER_OF_2(n) BIT(n) +#endif + +/* Size of a basic management buffer block in power of 2 */ +/* 7 to the power of 2 = 128 */ +#define MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2 7 + +/* 5 to the power of 2 = 32 */ +#define MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2 5 + +/* Size of a basic management buffer block */ +#define MGT_BUF_BLOCK_SIZE POWER_OF_2(MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2) +#define MSG_BUF_BLOCK_SIZE POWER_OF_2(MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2) + +/* Total size of (n) basic management buffer blocks */ +#define MGT_BUF_BLOCKS_SIZE(n) \ + ((uint32_t)(n) << MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2) +#define MSG_BUF_BLOCKS_SIZE(n) \ + ((uint32_t)(n) << MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2) + +/* Number of management buffer block */ +#define MAX_NUM_OF_BUF_BLOCKS 32 /* Range: 1~32 */ + +/* Size of overall management frame buffer */ +#define MGT_BUFFER_SIZE (MAX_NUM_OF_BUF_BLOCKS * MGT_BUF_BLOCK_SIZE) +#define MSG_BUFFER_SIZE (MAX_NUM_OF_BUF_BLOCKS * MSG_BUF_BLOCK_SIZE) + +/* STA_REC related definitions */ +#define STA_REC_INDEX_BMCAST 0xFF +#define STA_REC_INDEX_NOT_FOUND 0xFE + +/* Number of SW queues in each STA_REC: AC0~AC4 */ +#define STA_WAIT_QUEUE_NUM 5 + +/* Number of SC caches in each STA_REC: AC0~AC4 */ +#define SC_CACHE_INDEX_NUM 5 + +/* P2P related definitions */ +#if CFG_ENABLE_WIFI_DIRECT +/* Moved from p2p_fsm.h */ +#define WPS_ATTRI_MAX_LEN_DEVICE_NAME 32 /* 0x1011 */ + +/* NOTE(Kevin): Shall <= 16 */ +#define P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT 8 +#endif + +/* Define the argument of cnmStaFreeAllStaByNetwork when all station records + * will be free. No one will be free + */ +#define STA_REC_EXCLUDE_NONE CFG_STA_REC_NUM + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +/* Use 32 bits to represent buffur bitmap in BUF_INFO, i.e., the variable + * rFreeBlocksBitmap in BUF_INFO structure. + */ +#if (MAX_NUM_OF_BUF_BLOCKS != 32) +#error > #define MAX_NUM_OF_MGT_BUF_BLOCKS should be 32 ! +#endif /* MAX_NUM_OF_MGT_BUF_BLOCKS */ + +/* Control variable of TX management memory pool */ +struct BUF_INFO { + uint8_t *pucBuf; + +#if CFG_DBG_MGT_BUF + uint32_t u4AllocCount; + uint32_t u4FreeCount; + uint32_t u4AllocNullCount; +#endif /* CFG_DBG_MGT_BUF */ + + uint32_t rFreeBlocksBitmap; + uint8_t aucAllocatedBlockNum[MAX_NUM_OF_BUF_BLOCKS]; +}; + +/* Wi-Fi divides RAM into three types + * MSG: Mailbox message (Small size) + * BUF: HW DMA buffers (HIF/MAC) + */ +enum ENUM_RAM_TYPE { + RAM_TYPE_MSG = 0, + RAM_TYPE_BUF +}; + +enum ENUM_BUFFER_SOURCE { + BUFFER_SOURCE_HIF_TX0 = 0, + BUFFER_SOURCE_HIF_TX1, + BUFFER_SOURCE_MAC_RX, + BUFFER_SOURCE_MNG, + BUFFER_SOURCE_BCN, + BUFFER_SOURCE_NUM +}; + +enum ENUM_SEC_STATE { + SEC_STATE_INIT, + SEC_STATE_INITIATOR_PORT_BLOCKED, + SEC_STATE_RESPONDER_PORT_BLOCKED, + SEC_STATE_CHECK_OK, + SEC_STATE_SEND_EAPOL, + SEC_STATE_SEND_DEAUTH, + SEC_STATE_COUNTERMEASURE, + SEC_STATE_NUM +}; + +struct TSPEC_ENTRY { + uint8_t ucStatus; + uint8_t ucToken; /* Dialog Token in ADDTS_REQ or ADDTS_RSP */ + uint16_t u2MediumTime; + uint32_t u4TsInfo; + /* PARAM_QOS_TS_INFO rParamTsInfo; */ + /* Add other retained QoS parameters below */ +}; + +#if 0 +struct SEC_INFO { + + enum ENUM_SEC_STATE ePreviousState; + enum ENUM_SEC_STATE eCurrentState; + + u_int8_t fg2nd1xSend; + u_int8_t fgKeyStored; + + uint8_t aucStoredKey[64]; + + u_int8_t fgAllowOnly1x; +}; +#endif + +#define MAX_NUM_CONCURRENT_FRAGMENTED_MSDUS 3 + +#define UPDATE_BSS_RSSI_INTERVAL_SEC 3 /* Seconds */ + +/* Fragment information structure */ +struct FRAG_INFO { + uint16_t u2SeqNo; + uint8_t ucNextFragNo; +#if CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION + uint8_t ucSecMode; + uint64_t u8NextPN; +#endif /* CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION */ + uint8_t *pucNextFragStart; + struct SW_RFB *pr1stFrag; + + /* The receive time of 1st fragment */ + OS_SYSTIME rReceiveLifetimeLimit; +}; + +#if CFG_SUPPORT_802_11W +/* AP PMF */ +struct AP_PMF_CFG { + u_int8_t fgMfpc; + u_int8_t fgMfpr; + u_int8_t fgSha256; + u_int8_t fgAPApplyPmfReq; + u_int8_t fgBipKeyInstalled; +}; + +struct STA_PMF_CFG { + u_int8_t fgMfpc; + u_int8_t fgMfpr; + u_int8_t fgSha256; + u_int8_t fgSaeRequireMfp; + u_int8_t fgApplyPmf; + u_int8_t fgBipKeyInstalled; + + /* for certification 4.3.3.1, 4.3.3.2 TX unprotected deauth */ + u_int8_t fgRxDeauthResp; + + /* For PMF SA query TX request retry a timer */ + /* record the start time of 1st SAQ request */ + uint32_t u4SAQueryStart; + + uint32_t u4SAQueryCount; + uint8_t ucSAQueryTimedOut; /* retry more than 1000ms */ + struct TIMER rSAQueryTimer; + uint16_t u2TransactionID; +}; +#endif + +/* Define STA record structure */ +struct STA_RECORD { + struct LINK_ENTRY rLinkEntry; + uint8_t ucIndex; /* Not modify it except initializing */ + uint8_t ucWlanIndex; /* WLAN table index */ + +#if 0 /* TODO: Remove this */ + /* The BSS STA Rx WLAN index, IBSS Rx BC WLAN table + * index, work at IBSS Open and WEP + */ + uint8_t ucBMCWlanIndex; +#endif + + u_int8_t fgIsInUse; /* Indicate if this entry is in use or not */ + uint8_t aucMacAddr[MAC_ADDR_LEN]; /* MAC address */ + + /* SAA/AAA */ + /* Store STATE Value used in SAA/AAA */ + enum ENUM_AA_STATE eAuthAssocState; + + uint8_t ucAuthAssocReqSeqNum; + + /* Indicate the role of this STA in the network (for example, P2P GO) */ + enum ENUM_STA_TYPE eStaType; + + uint8_t ucBssIndex; /* BSS_INFO_I index */ + + uint8_t ucStaState; /* STATE_1,2,3 */ + + /* Available PHY Type Set of this peer (may deduced from + * received struct BSS_DESC) + */ + uint8_t ucPhyTypeSet; + + /* record from bcn or probe response */ + uint8_t ucVhtCapNumSoundingDimensions; + + /* The match result by AND operation of peer's PhyTypeSet and ours. */ + uint8_t ucDesiredPhyTypeSet; + + /* A flag to indicate a Basic Phy Type which is used to generate some + * Phy Attribute IE (e.g. capability, MIB) during association. + */ + u_int8_t fgHasBasicPhyType; + + /* The Basic Phy Type chosen among the ucDesiredPhyTypeSet. */ + uint8_t ucNonHTBasicPhyType; + + uint16_t u2HwDefaultFixedRateCode; + + /* For Infra Mode, to store Capability Info. from Association Resp(SAA). + * For AP Mode, to store Capability Info. from Association Req(AAA). + */ + uint16_t u2CapInfo; + + /* For Infra Mode, to store AID from Association Resp(SAA). + * For AP Mode, to store the Assigned AID(AAA). + */ + uint16_t u2AssocId; + + uint16_t u2ListenInterval; /* Listen Interval from STA(AAA) */ + + /* Our Current Desired Rate Set after match + * with STA's Operational Rate Set + */ + uint16_t u2DesiredNonHTRateSet; + + uint16_t u2OperationalRateSet; /* Operational Rate Set of peer BSS */ + uint16_t u2BSSBasicRateSet; /* Basic Rate Set of peer BSS */ + + /* For IBSS Mode, to indicate that Merge is ongoing */ + u_int8_t fgIsMerging; + + /* For Infra/AP Mode, to diagnose the Connection with this peer + * by sending ProbeReq/Null frame + */ + u_int8_t fgDiagnoseConnection; + + /*---------------------------------------------------------------------- + * 802.11n HT capabilities when (prStaRec->ucPhyTypeSet & + * PHY_TYPE_BIT_HT) is true. They have the same definition with fields + * of information element + *---------------------------------------------------------------------- + */ + uint8_t ucMcsSet; /* MCS0~7 rate set of peer BSS */ + u_int8_t fgSupMcs32; /* MCS32 is supported by peer BSS */ + uint8_t aucRxMcsBitmask[SUP_MCS_RX_BITMASK_OCTET_NUM]; + uint16_t u2RxHighestSupportedRate; + uint32_t u4TxRateInfo; + uint16_t u2HtCapInfo; /* HT cap info field by HT cap IE */ + uint8_t ucAmpduParam; /* Field A-MPDU Parameters in HT cap IE */ + uint16_t u2HtExtendedCap; /* HT extended cap field by HT cap IE */ + + /* TX beamforming cap field by HT cap IE */ + uint32_t u4TxBeamformingCap; + + uint8_t ucAselCap; /* ASEL cap field by HT cap IE */ + +#if 1 /* CFG_SUPPORT_802_11AC */ + /*---------------------------------------------------------------------- + * 802.11ac VHT capabilities when (prStaRec->ucPhyTypeSet & + * PHY_TYPE_BIT_VHT) is true. They have the same definition with fields + * of information element + *---------------------------------------------------------------------- + */ + uint32_t u4VhtCapInfo; + uint16_t u2VhtRxMcsMap; + uint16_t u2VhtRxMcsMapAssoc; + uint16_t u2VhtRxHighestSupportedDataRate; + uint16_t u2VhtTxMcsMap; + uint16_t u2VhtTxHighestSupportedDataRate; + uint8_t ucVhtOpMode; +#endif + +#if (CFG_SUPPORT_802_11AX == 1) + /*--------------------------------------------------------------------*/ + /* HE capability if (prStaRec->ucPhyTypeSet & PHY_TYPE_BIT_HE) is set */ + /* They have the same definition with fields of information element */ + /*--------------------------------------------------------------------*/ + uint8_t ucHeMacCapInfo[HE_MAC_CAP_BYTE_NUM]; + uint8_t ucHePhyCapInfo[HE_PHY_CAP_BYTE_NUM]; + + uint16_t u2HeRxMcsMapBW80; + uint16_t u2HeTxMcsMapBW80; + uint16_t u2HeRxMcsMapBW160; + uint16_t u2HeTxMcsMapBW160; + uint16_t u2HeRxMcsMapBW80P80; + uint16_t u2HeTxMcsMapBW80P80; +#endif + + /*---------------------------------------------------------------------- + * 802.11ac HT operation info when (prStaRec->ucPhyTypeSet & + * PHY_TYPE_BIT_HT) is true. They have the same definition with fields + * of information element + *---------------------------------------------------------------------- + */ + uint8_t ucHtPeerOpInfo1; /* Backup peer HT OP Info */ + + /*---------------------------------------------------------------------- + * 802.11ac VHT operation info when (prStaRec->ucPhyTypeSet & + * PHY_TYPE_BIT_VHT) is true. They have the same definition with fields + * of information element + *---------------------------------------------------------------------- + */ + /* Backup peer VHT Op Info */ + uint8_t ucVhtOpChannelWidth; + uint8_t ucVhtOpChannelFrequencyS1; + uint8_t ucVhtOpChannelFrequencyS2; + + + uint8_t ucRCPI; /* RCPI of peer */ + + /* Target BSS's DTIM Period, we use this value for + * setup Listen Interval + * TODO(Kevin): TBD + */ + uint8_t ucDTIMPeriod; + + /* For Infra/AP Mode, the Auth Algorithm Num used + * in Authentication(SAA/AAA) + */ + uint8_t ucAuthAlgNum; + uint8_t ucAuthTranNum; /* For Infra/AP Mode, the Auth Transaction Number + */ + + /* For Infra/AP Mode, to indicate ReAssoc Frame was in used(SAA/AAA) */ + u_int8_t fgIsReAssoc; + + /* For Infra Mode, the Retry Count of TX Auth/Assod Frame(SAA) */ + uint8_t ucTxAuthAssocRetryCount; + + /* For Infra Mode, the Retry Limit of TX Auth/Assod Frame(SAA) */ + uint8_t ucTxAuthAssocRetryLimit; + + uint16_t u2StatusCode; /* Status of Auth/Assoc Req */ + uint16_t u2ReasonCode; /* Reason that been Deauth/Disassoc */ + + /* Point to an allocated buffer for storing Challenge */ + /* Text for Shared Key Authentication */ + struct IE_CHALLENGE_TEXT *prChallengeText; + + /* For Infra Mode, a timer used to send a timeout event + * while waiting for TX request done or RX response. + */ + struct TIMER rTxReqDoneOrRxRespTimer; + + /* For Infra Mode, a timer used to avoid the Deauth frame + * not be sent + */ + struct TIMER rDeauthTxDoneTimer; + + /*---------------------------------------------------------------------- + * Power Management related fields (for STA/ AP/ P2P/ BOW power saving + * mode) + *---------------------------------------------------------------------- + */ + /* For Infra Mode, to indicate that outgoing frame need + * toggle the Pwr Mgt Bit in its Frame Control Field. + */ + u_int8_t fgSetPwrMgtBit; + + /* For AP Mode, to indicate the client PS state(PM). + * TRUE: In PS Mode; FALSE: In Active Mode. + */ + u_int8_t fgIsInPS; + + /* For Infra Mode, to indicate we've sent a PS POLL to AP + * and start the PS_POLL Service Period(LP) + */ + u_int8_t fgIsInPsPollSP; + + /* For Infra Mode, to indicate we've sent a Trigger Frame + * to AP and start the Delivery Service Period(LP) + */ + u_int8_t fgIsInTriggerSP; + + uint8_t ucBmpDeliveryAC; /* 0: AC0, 1: AC1, 2: AC2, 3: AC3 */ + + uint8_t ucBmpTriggerAC; /* 0: AC0, 1: AC1, 2: AC2, 3: AC3 */ + + uint8_t ucUapsdSp; /* Max SP length */ + + /*--------------------------------------------------------------------*/ + + u_int8_t fgIsRtsEnabled; + + /* (4) System Timestamp of Successful TX and RX */ + uint32_t rUpdateTime; + + /* (4) System Timestamp of latest JOIN process */ + uint32_t rLastJoinTime; + + uint8_t ucJoinFailureCount; /* Retry Count of JOIN process */ + + /* For TXM to defer pkt forwarding to MAC TX DMA */ + struct LINK arStaWaitQueue[STA_WAIT_QUEUE_NUM]; + + /* Duplicate removal for HT STA on a + * per-TID basis ("+1" is for MMPDU and non-QoS) + */ + uint16_t au2CachedSeqCtrl[TID_NUM + 1]; + + u_int8_t afgIsIgnoreAmsduDuplicate[TID_NUM + 1]; + +#if CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION + uint16_t au2AmsduInvalidSN[TID_NUM + 1]; + u_int8_t afgIsAmsduInvalid[TID_NUM + 1]; +#endif /* CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION */ + +#if 0 + /* RXM */ + struct RX_BA_ENTRY *aprRxBaTable[TID_NUM]; + + /* TXM */ + P_TX_BA_ENTRY_T aprTxBaTable[TID_NUM]; +#endif + + struct FRAG_INFO rFragInfo[MAX_NUM_CONCURRENT_FRAGMENTED_MSDUS]; + +#if 0 /* TODO: Remove this */ + struct SEC_INFO rSecInfo; /* The security state machine */ +#endif + +#if CFG_SUPPORT_ADHOC + /* Ad-hoc RSN Rx BC key exist flag, only reserved two + * entry for each peer + */ + u_int8_t fgAdhocRsnBcKeyExist[2]; + + /* Ad-hoc RSN Rx BC wlan index */ + uint8_t ucAdhocRsnBcWlanIndex[2]; +#endif + + u_int8_t fgPortBlock; /* The 802.1x Port Control flag */ + + u_int8_t fgTransmitKeyExist; /* Unicast key exist for this STA */ + + u_int8_t fgTxAmpduEn; /* Enable TX AMPDU for this Peer */ + u_int8_t fgRxAmpduEn; /* Enable RX AMPDU for this Peer */ + + uint8_t *pucAssocReqIe; + uint16_t u2AssocReqIeLen; + + /* link layer satatistics */ + struct WIFI_WMM_AC_STAT arLinkStatistics[WMM_AC_INDEX_NUM]; + + /*---------------------------------------------------------------------- + * WMM/QoS related fields + *---------------------------------------------------------------------- + */ + /* If the STA is associated as a QSTA or QAP (for TX/RX) */ + u_int8_t fgIsQoS; + + /* If the peer supports WMM, set to TRUE (for association) */ + u_int8_t fgIsWmmSupported; + + /* Set according to the scan result (for association) */ + u_int8_t fgIsUapsdSupported; + + u_int8_t afgAcmRequired[ACI_NUM]; + +#if (CFG_SUPPORT_802_11AX == 1) + /* If the peer supports MU EDCA, set to TRUE (for association)*/ + u_int8_t fgIsMuEdcaSupported; +#endif + + /*---------------------------------------------------------------------- + * P2P related fields + *---------------------------------------------------------------------- + */ +#if CFG_ENABLE_WIFI_DIRECT + uint8_t u2DevNameLen; + uint8_t aucDevName[WPS_ATTRI_MAX_LEN_DEVICE_NAME]; + + uint8_t aucDevAddr[MAC_ADDR_LEN]; /* P2P Device Address */ + + uint16_t u2ConfigMethods; + + uint8_t ucDeviceCap; + + uint8_t ucSecondaryDevTypeCount; + + struct DEVICE_TYPE rPrimaryDevTypeBE; + + struct DEVICE_TYPE arSecondaryDevTypeBE[ + P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT]; +#endif /* CFG_SUPPORT_P2P */ + + /*---------------------------------------------------------------------- + * QM related fields + *---------------------------------------------------------------------- + */ + /* Per Sta flow controal. Valid when fgIsInPS is TRUE. + * Change it for per Queue flow control + */ + uint8_t ucFreeQuota; + +#if 0 /* TODO: Remove this */ + /* used in future */ + uint8_t aucFreeQuotaPerQueue[NUM_OF_PER_STA_TX_QUEUES]; +#endif + uint8_t ucFreeQuotaForDelivery; + uint8_t ucFreeQuotaForNonDelivery; + + /*---------------------------------------------------------------------- + * TXM related fields + *---------------------------------------------------------------------- + */ + void *aprTxDescTemplate[TX_DESC_TID_NUM]; + +#if CFG_ENABLE_PKT_LIFETIME_PROFILE && CFG_ENABLE_PER_STA_STATISTICS + uint32_t u4TotalTxPktsNumber; + uint32_t u4TotalTxPktsTime; + uint32_t u4TotalTxPktsHifTxTime; + + uint32_t u4TotalRxPktsNumber; + uint32_t u4MaxTxPktsTime; + uint32_t u4MaxTxPktsHifTime; + + uint32_t u4ThresholdCounter; + uint32_t u4EnqueueCounter; + uint32_t u4DeqeueuCounter; +#endif + +#if 1 + /*---------------------------------------------------------------------- + * To be removed, this is to make que_mgt compilation success only + *---------------------------------------------------------------------- + */ + /* When this STA_REC is in use, set to TRUE. */ + u_int8_t fgIsValid; + + /* TX key is ready */ + u_int8_t fgIsTxKeyReady; + + /* When the STA is connected or TX key is ready */ + u_int8_t fgIsTxAllowed; + + /* Per-STA Queues: [0] AC0, [1] AC1, [2] AC2, [3] AC3 */ + struct QUE arTxQueue[NUM_OF_PER_STA_TX_QUEUES]; + + /* Per-STA Pending Queues: [0] AC0, [1] AC1, [2] AC2, [3] AC3 */ + /* This queue is for Tx packet in protected BSS before key is set */ + struct QUE arPendingTxQueue[NUM_OF_PER_STA_TX_QUEUES]; + + /* Tx packet target queue pointer. Select between arTxQueue & + * arPendingTxQueue + */ + struct QUE *aprTargetQueue[NUM_OF_PER_STA_TX_QUEUES]; + + /* Reorder Parameter reference table */ + struct RX_BA_ENTRY *aprRxReorderParamRefTbl[CFG_RX_MAX_BA_TID_NUM]; + +#endif + +#if CFG_SUPPORT_802_11V_TIMING_MEASUREMENT + struct TIMINGMSMT_PARAM rWNMTimingMsmt; +#endif + uint8_t ucTrafficDataType; /* 0: auto 1: data 2: video 3: voice */ + + /* 0: auto 1:Force enable 2: Force disable 3: enable by peer */ + uint8_t ucTxGfMode; + + /* 0: auto 1:Force enable 2: Force disable 3: enable by peer */ + uint8_t ucTxSgiMode; + + /* 0: auto 1:Force enable 2: Force disable 3: enable by peer */ + uint8_t ucTxStbcMode; + + uint32_t u4FixedPhyRate; + uint16_t u2MaxLinkSpeed; /* unit is 0.5 Mbps */ + uint16_t u2MinLinkSpeed; + uint32_t u4Flags; /* reserved for MTK Synergies */ + +#if CFG_SUPPORT_TDLS + u_int8_t fgTdlsIsProhibited; /* TRUE: AP prohibits TDLS links */ + + /* TRUE: AP prohibits TDLS chan switch */ + u_int8_t fgTdlsIsChSwProhibited; + + u_int8_t flgTdlsIsInitiator; /* TRUE: the peer is the initiator */ + + /* temp to queue HT capability element */ + struct IE_HT_CAP rTdlsHtCap; + + struct PARAM_KEY rTdlsKeyTemp; /* temp to queue the key information */ + uint8_t ucTdlsIndex; +#endif /* CFG_SUPPORT_TDLS */ +#if CFG_SUPPORT_TX_BF + struct TXBF_PFMU_STA_INFO rTxBfPfmuStaInfo; +#endif +#if CFG_SUPPORT_MSP + uint32_t u4RxVector0; + uint32_t u4RxVector1; + uint32_t u4RxVector2; + uint32_t u4RxVector3; + uint32_t u4RxVector4; +#endif + uint8_t ucSmDialogToken; /* Spectrum Mngt Dialog Token */ + uint8_t ucSmMsmtRequestMode; /* Measurement Request Mode */ + uint8_t ucSmMsmtToken; /* Measurement Request Token */ + + /* Element for AMSDU */ + uint8_t ucAmsduEnBitmap; /* Tid bit mask of AMSDU enable */ + uint8_t ucMaxMpduCount; + uint32_t u4MaxMpduLen; + uint32_t u4MinMpduLen; +#if CFG_SUPPORT_802_11W + /* AP PMF */ + struct STA_PMF_CFG rPmfCfg; +#endif +#if DSCP_SUPPORT + uint8_t qosMapSet[64]; +#endif +#if (CFG_SUPPORT_TWT == 1) + /* TWT Requester state */ + enum _ENUM_TWT_REQUESTER_STATE_T aeTWTReqState; + struct _TWT_FLOW_T arTWTFlow[TWT_MAX_FLOW_NUM]; +#endif +#if (CFG_SUPPORT_802_11AX == 1) + struct HE_A_CTRL_OM_T arHeACtrlOm; +#endif + + u_int8_t fgSupportBTM; /* Indicates whether to support BTM */ + + /* + * Flag used to record the connected status of upper layer. + * Indicate connected status only when disconnected, and only + * indicate disconnected status only when connected. + */ + u_int8_t fgIsConnected; +#if CFG_SUPPORT_HE_ER + u_int8_t fgIsExtendedRange; +#endif +}; + +#if 0 +/* use nic_tx.h instead */ +/* MSDU_INFO and SW_RFB structure */ +struct MSDU_INFO { + + /* 4 ----------------MSDU_INFO and SW_RFB Common Fields-------------- */ + + struct LINK_ENTRY rLinkEntry; + uint8_t *pucBuffer; /* Pointer to the associated buffer */ + + uint8_t ucBufferSource; /* HIF TX0, HIF TX1, MAC RX, or MNG Pool */ + + /* Network type index that this TX packet is assocaited with */ + uint8_t ucNetworkTypeIndex; + + /* 0 to 5 (used by HIF TX to increment the corresponding TC counter) */ + uint8_t ucTC; + + uint8_t ucTID; /* Traffic Identification */ + + u_int8_t fgIs802_11Frame; /* Set to TRUE for 802.11 frame */ + uint8_t ucMacHeaderLength; + uint16_t u2PayloadLength; + uint8_t *pucMacHeader; /* 802.11 header */ + uint8_t *pucPayload; /* 802.11 payload */ + + OS_SYSTIME rArrivalTime; /* System Timestamp (4) */ + struct STA_RECORD *prStaRec; + +#if CFG_PROFILE_BUFFER_TRACING + ENUM_BUFFER_ACTIVITY_TYPE_T eActivity[2]; + uint32_t rActivityTime[2]; +#endif +#if DBG && CFG_BUFFER_FREE_CHK + u_int8_t fgBufferInSource; +#endif + + /* For specify some Control Flags, e.g. Basic Rate */ + uint8_t ucControlFlag; + + /* 4 -----------------------Non-Common ------------------------- */ + /* TODO: move flags to ucControlFlag */ + + u_int8_t fgIs1xFrame; /* Set to TRUE for 802.1x frame */ + + /* TXM: For TX Done handling, callback function & parameter (5) */ + u_int8_t fgIsTxFailed; /* Set to TRUE if transmission failure */ + + PFN_TX_DONE_HANDLER pfTxDoneHandler; + + uint64_t u8TimeStamp; /* record the TX timestamp */ + + /* TXM: For PS forwarding control (per-STA flow control) */ + /* Delivery-enabled, non-delivery-enabled, non-PS */ + uint8_t ucPsForwardingType; + + /* The Power Save session id for PS forwarding control */ + uint8_t ucPsSessionID; + + /* TXM: For MAC TX DMA operations */ + uint8_t ucMacTxQueIdx; /* MAC TX queue: AC0-AC6, BCM, or BCN */ + + /* Set to true if Ack is not required for this packet */ + u_int8_t fgNoAck; + + u_int8_t fgBIP; /* Set to true if BIP is used for this packet */ + uint8_t ucFragTotalCount; + uint8_t ucFragFinishedCount; + + /* Fragmentation threshold without WLAN Header & FCS */ + uint16_t u2FragThreshold; + + u_int8_t fgFixedRate; /* If a fixed rate is used, set to TRUE. */ + + /* The rate code copied to MAC TX Desc */ + uint8_t ucFixedRateCode; + + /* The retry limit when a fixed rate is used */ + uint8_t ucFixedRateRetryLimit; + + /* Set to true if this packet is the end of BMC */ + u_int8_t fgIsBmcQueueEnd; + + /* TXM: For flushing ACL frames */ + uint16_t u2PalLLH; /* 802.11 PAL LLH */ + /* UINT_16 u2LLH; */ + uint16_t u2ACLSeq; /* u2LLH+u2ACLSeq for AM HCI flush ACL frame */ + + /* TXM for retransmitting a flushed packet */ + u_int8_t fgIsSnAssigned; + + /* To remember the Sequence Control field of this MPDU */ + uint16_t u2SequenceNumber; +}; +#endif + +#if 0 +/* nic_rx.h */ +struct SW_RFB { + + /* 4 ----------------MSDU_INFO and SW_RFB Common Fields-------------- */ + + struct LINK_ENTRY rLinkEntry; + uint8_t *pucBuffer; /* Pointer to the associated buffer */ + + uint8_t ucBufferSource; /* HIF TX0, HIF TX1, MAC RX, or MNG Pool */ + + /* Network type index that this TX packet is assocaited with */ + uint8_t ucNetworkTypeIndex; + + /* 0 to 5 (used by HIF TX to increment the corresponding TC counter) */ + uint8_t ucTC; + + uint8_t ucTID; /* Traffic Identification */ + + u_int8_t fgIs802_11Frame; /* Set to TRUE for 802.11 frame */ + uint8_t ucMacHeaderLength; + uint16_t u2PayloadLength; + uint8_t *pucMacHeader; /* 802.11 header */ + uint8_t *pucPayload; /* 802.11 payload */ + + OS_SYSTIME rArrivalTime; /* System Timestamp (4) */ + struct STA_RECORD *prStaRec; + +#if CFG_PROFILE_BUFFER_TRACING + ENUM_BUFFER_ACTIVITY_TYPE_T eActivity[2]; + uint32_t rActivityTime[2]; +#endif +#if DBG && CFG_BUFFER_FREE_CHK + u_int8_t fgBufferInSource; +#endif + + /* For specify some Control Flags, e.g. Basic Rate */ + uint8_t ucControlFlag; + + /* 4 -----------------------Non-Common ------------------------- */ + + /* For composing the HIF RX Header (TODO: move flags to + * ucControlFlag) + */ + /* Pointer to the Response packet to * HIF RX0 or RX1 */ + uint8_t *pucHifRxPacket; + + uint16_t u2HifRxPacketLength; + uint8_t ucHeaderOffset; + uint8_t ucHifRxPortIndex; + + uint16_t u2SequenceControl; + + /* (For MAC RX packet parsing) set to TRUE if 4 addresses are present */ + u_int8_t fgIsA4Frame; + + u_int8_t fgIsBAR; + u_int8_t fgIsQoSData; + u_int8_t fgIsAmsduSubframe; /* Set to TRUE for A-MSDU Subframe */ + + /* For HIF RX DMA Desc */ + u_int8_t fgTUChecksumCheckRequired; + u_int8_t fgIPChecksumCheckRequired; + uint8_t ucEtherTypeOffset; + +}; +#endif + +enum ENUM_STA_REC_CMD_ACTION { + STA_REC_CMD_ACTION_STA = 0, + STA_REC_CMD_ACTION_BSS = 1, + STA_REC_CMD_ACTION_BSS_EXCLUDE_STA = 2 +}; + +#if CFG_SUPPORT_TDLS + +/* TDLS FSM */ +struct CMD_PEER_ADD { + + uint8_t aucPeerMac[6]; + enum ENUM_STA_TYPE eStaType; + uint8_t ucBssIdx; +}; + +struct CMD_PEER_UPDATE_HT_CAP_MCS_INFO { + uint8_t arRxMask[SUP_MCS_RX_BITMASK_OCTET_NUM]; + uint16_t u2RxHighest; + uint8_t ucTxParams; + uint8_t Reserved[3]; +}; + +struct CMD_PEER_UPDATE_VHT_CAP_MCS_INFO { + uint8_t arRxMask[SUP_MCS_RX_BITMASK_OCTET_NUM]; +}; + +struct CMD_PEER_UPDATE_HT_CAP { + uint16_t u2CapInfo; + uint8_t ucAmpduParamsInfo; + + /* 16 bytes MCS information */ + struct CMD_PEER_UPDATE_HT_CAP_MCS_INFO rMCS; + + uint16_t u2ExtHtCapInfo; + uint32_t u4TxBfCapInfo; + uint8_t ucAntennaSelInfo; +}; + +struct CMD_PEER_UPDATE_VHT_CAP { + uint16_t u2CapInfo; + /* 16 bytes MCS information */ + struct CMD_PEER_UPDATE_VHT_CAP_MCS_INFO rVMCS; + +}; + +struct CMD_PEER_UPDATE { + + uint8_t aucPeerMac[6]; + +#define CMD_PEER_UPDATE_SUP_CHAN_MAX 50 + uint8_t aucSupChan[CMD_PEER_UPDATE_SUP_CHAN_MAX]; + + uint16_t u2StatusCode; + +#define CMD_PEER_UPDATE_SUP_RATE_MAX 50 + uint8_t aucSupRate[CMD_PEER_UPDATE_SUP_RATE_MAX]; + uint16_t u2SupRateLen; + + uint8_t UapsdBitmap; + uint8_t UapsdMaxSp; /* MAX_SP */ + + uint16_t u2Capability; +#define CMD_PEER_UPDATE_EXT_CAP_MAXLEN 5 + uint8_t aucExtCap[CMD_PEER_UPDATE_EXT_CAP_MAXLEN]; + uint16_t u2ExtCapLen; + + struct CMD_PEER_UPDATE_HT_CAP rHtCap; + struct CMD_PEER_UPDATE_VHT_CAP rVHtCap; + + u_int8_t fgIsSupHt; + enum ENUM_STA_TYPE eStaType; + uint8_t ucBssIdx; + + /* TODO */ + /* So far, TDLS only a few of the parameters, the rest will be added + * in the future requiements + */ + /* kernel 3.10 station paramenters */ +#if 0 + struct station_parameters { + const u8 *supported_rates; + struct net_device *vlan; + u32 sta_flags_mask, sta_flags_set; + u32 sta_modify_mask; + int listen_interval; + u16 aid; + u8 supported_rates_len; + u8 plink_action; + u8 plink_state; + const struct ieee80211_ht_cap *ht_capa; + const struct ieee80211_vht_cap *vht_capa; + u8 uapsd_queues; + u8 max_sp; + enum nl80211_mesh_power_mode local_pm; + u16 capability; + const u8 *ext_capab; + u8 ext_capab_len; + const u8 *supported_channels; + u8 supported_channels_len; + const u8 *supported_oper_classes; + u8 supported_oper_classes_len; + }; +#endif + +}; + +#endif + +#if CFG_DBG_MGT_BUF +struct MEM_TRACK { + struct LINK_ENTRY rLinkEntry; + uint16_t u2CmdIdAndWhere; + uint8_t *pucFileAndLine; +}; +#endif +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ +#define STRL(x) #x +#define STRLINE(x) STRL(x) + +#if CFG_DBG_MGT_BUF +#define cnmMgtPktAlloc(_prAdapter, _u4Length) \ + cnmPktAllocWrapper((_prAdapter), (_u4Length), (uint8_t *)__func__) + +#define cnmMgtPktFree(_prAdapter, _prMsduInfo) \ + cnmPktFreeWrapper((_prAdapter), (_prMsduInfo), (uint8_t *)__func__) + +#define cnmMemAlloc(_prAdapter, eRameType, u4Length) \ + cnmMemAllocX(_prAdapter, eRameType, u4Length, \ + __FILE__ ":" STRLINE(__LINE__)) + +#define IS_FROM_BUF(_prAdapter, pucInfoBuffer) \ + (((uint8_t *)(pucInfoBuffer) >= \ + (uint8_t *)_prAdapter->rMgtBufInfo.pucBuf) && \ + ((uint8_t *)(pucInfoBuffer) < \ + (uint8_t *)_prAdapter->rMgtBufInfo.pucBuf + MGT_BUFFER_SIZE)) +#else +#define cnmMgtPktAlloc cnmPktAlloc +#define cnmMgtPktFree cnmPktFree +#endif + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +struct MSDU_INFO *cnmPktAllocWrapper(IN struct ADAPTER *prAdapter, + IN uint32_t u4Length, IN uint8_t *pucStr); + +void cnmPktFreeWrapper(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, IN uint8_t *pucStr); + +struct MSDU_INFO *cnmPktAlloc(IN struct ADAPTER *prAdapter, + IN uint32_t u4Length); + +void cnmPktFree(IN struct ADAPTER *prAdapter, IN struct MSDU_INFO *prMsduInfo); + +void cnmMemInit(IN struct ADAPTER *prAdapter); + +#if CFG_DBG_MGT_BUF +void *cnmMemAllocX(IN struct ADAPTER *prAdapter, + IN enum ENUM_RAM_TYPE eRamType, IN uint32_t u4Length, + uint8_t *fileAndLine); +#else +void *cnmMemAlloc(IN struct ADAPTER *prAdapter, IN enum ENUM_RAM_TYPE eRamType, + IN uint32_t u4Length); +#endif + +void cnmMemFree(IN struct ADAPTER *prAdapter, IN void *pvMemory); + +void cnmStaRecInit(IN struct ADAPTER *prAdapter); + +struct STA_RECORD * +cnmStaRecAlloc(IN struct ADAPTER *prAdapter, IN enum ENUM_STA_TYPE eStaType, + IN uint8_t ucBssIndex, IN uint8_t *pucMacAddr); + +void cnmStaRecFree(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec); + +void cnmStaFreeAllStaByNetwork(struct ADAPTER *prAdapter, uint8_t ucBssIndex, + uint8_t ucStaRecIndexExcluded); + +struct STA_RECORD *cnmGetStaRecByIndex(IN struct ADAPTER *prAdapter, + IN uint8_t ucIndex); + +struct STA_RECORD *cnmGetStaRecByAddress(struct ADAPTER *prAdapter, + uint8_t ucBssIndex, uint8_t aucPeerMACAddress[]); + +void cnmStaRecChangeState(IN struct ADAPTER *prAdapter, + IN OUT struct STA_RECORD *prStaRec, IN uint8_t ucNewState); + +void cnmDumpStaRec(IN struct ADAPTER *prAdapter, IN uint8_t ucStaRecIdx); + +uint32_t cnmDumpMemoryStatus(IN struct ADAPTER *prAdapter, IN uint8_t *pucBuf, + IN uint32_t u4Max); + +#if CFG_SUPPORT_TDLS +uint32_t /* TDLS_STATUS */ +cnmPeerAdd(struct ADAPTER *prAdapter, void *pvSetBuffer, + uint32_t u4SetBufferLen, uint32_t *pu4SetInfoLen); + +uint32_t /* TDLS_STATUS */ +cnmPeerUpdate(struct ADAPTER *prAdapter, void *pvSetBuffer, + uint32_t u4SetBufferLen, uint32_t *pu4SetInfoLen); + +struct STA_RECORD *cnmGetTdlsPeerByAddress(struct ADAPTER *prAdapter, + uint8_t ucBssIndex, uint8_t aucPeerMACAddress[]); +#endif + +void cnmStaSendUpdateCmd(struct ADAPTER *prAdapter, struct STA_RECORD *prStaRec, + struct TXBF_PFMU_STA_INFO *prTxBfPfmuStaInfo, u_int8_t fgNeedResp); + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +#ifndef _lint +/* Kevin: we don't have to call following function to inspect the data + * structure. It will check automatically while at compile time. + * We'll need this for porting driver to different RTOS. + */ +static __KAL_INLINE__ void cnmMemDataTypeCheck(void) +{ +#if 0 + DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF( + struct MSDU_INFO, rLinkEntry) + == 0); + + DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF( + struct MSDU_INFO, rLinkEntry) + == OFFSET_OF(struct SW_RFB, rLinkEntry)); + + DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF( + struct MSDU_INFO, pucBuffer) + == OFFSET_OF(struct SW_RFB, pucBuffer)); + + DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF( + struct MSDU_INFO, ucBufferSource) + == OFFSET_OF(struct SW_RFB, ucBufferSource)); + + DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF( + struct MSDU_INFO, pucMacHeader) + == OFFSET_OF(struct SW_RFB, pucMacHeader)); + + DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF( + struct MSDU_INFO, ucMacHeaderLength) + == OFFSET_OF(struct SW_RFB, ucMacHeaderLength)); + + DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF( + struct MSDU_INFO, pucPayload) + == OFFSET_OF(struct SW_RFB, pucPayload)); + + DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF( + struct MSDU_INFO, u2PayloadLength) + == OFFSET_OF(struct SW_RFB, u2PayloadLength)); + + DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF( + struct MSDU_INFO, prStaRec) + == OFFSET_OF(struct SW_RFB, prStaRec)); + + DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF( + struct MSDU_INFO, ucNetworkTypeIndex) + == OFFSET_OF(struct SW_RFB, ucNetworkTypeIndex)); + + DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF( + struct MSDU_INFO, ucTID) + == OFFSET_OF(struct SW_RFB, ucTID)); + + DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF( + struct MSDU_INFO, fgIs802_11Frame) + == OFFSET_OF(struct SW_RFB, fgIs802_11Frame)); + + DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF( + struct MSDU_INFO, ucControlFlag) + == OFFSET_OF(struct SW_RFB, ucControlFlag)); + + DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF( + struct MSDU_INFO, rArrivalTime) + == OFFSET_OF(struct SW_RFB, rArrivalTime)); + + DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF( + struct MSDU_INFO, ucTC) + == OFFSET_OF(struct SW_RFB, ucTC)); + +#if CFG_PROFILE_BUFFER_TRACING + DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF( + struct MSDU_INFO, eActivity[0]) + == OFFSET_OF(struct SW_RFB, eActivity[0])); + + DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF( + struct MSDU_INFO, rActivityTime[0]) + == OFFSET_OF(struct SW_RFB, rActivityTime[0])); +#endif + +#if DBG && CFG_BUFFER_FREE_CHK + DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF( + struct MSDU_INFO, fgBufferInSource) + == OFFSET_OF(struct SW_RFB, fgBufferInSource)); +#endif + + DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF( + struct STA_RECORD, rLinkEntry) + == 0); + + return; +#endif +} +#endif /* _lint */ + +#endif /* _CNM_MEM_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/cnm_scan.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/cnm_scan.h new file mode 100644 index 0000000000000000000000000000000000000000..46babe311422cbb3746dcc86cbce1bfea24359f5 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/cnm_scan.h @@ -0,0 +1,164 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: @(#) + */ + +/*! \file "cnm_scan.h" + * \brief + * + */ + + +#ifndef _CNM_SCAN_H +#define _CNM_SCAN_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#define SCN_CHANNEL_DWELL_TIME_MIN_MSEC 12 +#define SCN_CHANNEL_DWELL_TIME_EXT_MSEC 98 + +#define SCN_TOTAL_PROBEREQ_NUM_FOR_FULL 3 +#define SCN_SPECIFIC_PROBEREQ_NUM_FOR_FULL 1 + +#define SCN_TOTAL_PROBEREQ_NUM_FOR_PARTIAL 2 +#define SCN_SPECIFIC_PROBEREQ_NUM_FOR_PARTIAL 1 + +/* Used by partial scan */ +#define SCN_INTERLACED_CHANNEL_GROUPS_NUM 3 + +#define SCN_PARTIAL_SCAN_NUM 3 + +#define SCN_PARTIAL_SCAN_IDLE_MSEC 100 + +#define SCN_P2P_FULL_SCAN_PARAM 0 + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +/* The type of Scan Source */ +enum ENUM_SCN_REQ_SOURCE { + SCN_REQ_SOURCE_HEM = 0, + SCN_REQ_SOURCE_NET_FSM, + SCN_REQ_SOURCE_ROAMING, /* ROAMING Module is independent of AIS FSM */ + SCN_REQ_SOURCE_OBSS, /* 2.4G OBSS scan */ + SCN_REQ_SOURCE_NUM +}; + +enum ENUM_SCAN_PROFILE { + SCAN_PROFILE_FULL = 0, + SCAN_PROFILE_PARTIAL, + SCAN_PROFILE_VOIP, + SCAN_PROFILE_FULL_2G4, + SCAN_PROFILE_NUM +}; + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +#if 0 +void cnmScanInit(void); + +void cnmScanRunEventScanRequest(IN struct MSG_HDR *prMsgHdr); + +u_int8_t cnmScanRunEventScanAbort(IN struct MSG_HDR *prMsgHdr); + +void cnmScanProfileSelection(void); + +void cnmScanProcessStart(void); + +void cnmScanProcessStop(void); + +void cnmScanRunEventReqAISAbsDone(IN struct MSG_HDR *prMsgHdr); + +void cnmScanRunEventCancelAISAbsDone(IN struct MSG_HDR *prMsgHdr); + +void cnmScanPartialScanTimeout(uint32_t u4Param); + +void cnmScanRunEventScnFsmComplete(IN struct MSG_HDR *prMsgHdr); +#endif + +#endif /* _CNM_SCAN_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/cnm_timer.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/cnm_timer.h new file mode 100644 index 0000000000000000000000000000000000000000..9fb2994a4819b7f529ec9c820f514f1a32f3052a --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/cnm_timer.h @@ -0,0 +1,268 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3 + * /include/mgmt/cnm_timer.h#1 + */ + +/*! \file cnm_timer.h + * \brief Declaration of timer obj and related timer macro for setup time + * out event. + * + * In this file we declare the timer object and provide several macro for + * Protocol functional blocks to setup their own time out event. + */ + + +#ifndef _CNM_TIMER_H +#define _CNM_TIMER_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#undef MSEC_PER_SEC +#define MSEC_PER_SEC 1000 +#undef USEC_PER_MSEC +#define USEC_PER_MSEC 1000 +#undef USEC_PER_SEC +#define USEC_PER_SEC 1000000 + +#define USEC_PER_TU 1024 /* microsecond */ + +#define MSEC_PER_MIN (60 * MSEC_PER_SEC) + +#define MGMT_MAX_TIMEOUT_INTERVAL ((uint32_t)0x7fffffff) + +#define WAKE_LOCK_MAX_TIME 5 /* Unit: sec */ + +/* If WAKE_LOCK_MAX_TIME is too large, the whole system may always keep awake + * because of periodic timer of OBSS scanning + */ +#if (WAKE_LOCK_MAX_TIME >= OBSS_SCAN_MIN_INTERVAL) +#error WAKE_LOCK_MAX_TIME is too large +#endif + +enum ENUM_TIMER_WAKELOCK_TYPE_T { + TIMER_WAKELOCK_AUTO, + TIMER_WAKELOCK_NONE, + TIMER_WAKELOCK_REQUEST, + TIMER_WAKELOCK_NUM +}; + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +typedef void(*PFN_MGMT_TIMEOUT_FUNC) (struct ADAPTER *, unsigned long); + +struct TIMER { + struct LINK_ENTRY rLinkEntry; + OS_SYSTIME rExpiredSysTime; + uint16_t u2Minutes; + uint16_t u2Reserved; + unsigned long ulDataPtr; + PFN_MGMT_TIMEOUT_FUNC pfMgmtTimeOutFunc; + enum ENUM_TIMER_WAKELOCK_TYPE_T eType; +}; + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ +/* Check if time "a" is before time "b" */ +/* In 32-bit variable, 0x00000001~0x7fffffff -> positive number, + * 0x80000000~0xffffffff -> negative number + */ +#define TIME_BEFORE_64bit(a, b) (a < b) + +#define TIME_BEFORE(a, b) \ + ((uint32_t)((uint32_t)(a) - (uint32_t)(b)) > 0x7fffffff) + +/* #define TIME_BEFORE(a,b) ((int32_t)((int32_t)(b) - (int32_t)(a)) > 0) + * may cause UNexpect result between Free build and Check build for WinCE + */ + +#define TIME_AFTER(a, b) TIME_BEFORE(b, a) + +#define SYSTIME_TO_SEC(_systime) ((_systime) / KAL_HZ) +#define SEC_TO_SYSTIME(_sec) ((_sec) * KAL_HZ) + +/* The macros to convert second & millisecond */ +#define MSEC_TO_SEC(_msec) ((_msec) / MSEC_PER_SEC) +#define SEC_TO_MSEC(_sec) ((uint32_t)(_sec) * MSEC_PER_SEC) +#define SEC_TO_USEC(_sec) ((uint32_t)(_sec) * USEC_PER_SEC) + +/* The macros to convert millisecond & microsecond */ +#define USEC_TO_MSEC(_usec) ((_usec) / USEC_PER_MSEC) +#define MSEC_TO_USEC(_msec) ((uint32_t)(_msec) * USEC_PER_MSEC) + +/* The macros to convert TU & microsecond, TU & millisecond */ +#define TU_TO_USEC(_tu) ((_tu) * USEC_PER_TU) +#define TU_TO_MSEC(_tu) USEC_TO_MSEC(TU_TO_USEC(_tu)) + +/* The macros to convert TU & & OS system time, round up by 0.5 */ +#define TU_TO_SYSTIME(_tu) MSEC_TO_SYSTIME(TU_TO_MSEC(_tu)) +#define SYSTIME_TO_TU(_systime) \ + ((SYSTIME_TO_USEC(_systime) + ((USEC_PER_TU / 2) - 1)) / USEC_PER_TU) + +/* The macros to convert OS system time & microsecond */ +#define SYSTIME_TO_USEC(_systime) (((_systime) * USEC_PER_SEC) / KAL_HZ) + +/* The macro to get the current OS system time */ +#define GET_CURRENT_SYSTIME(_systime_p) { *(_systime_p) = kalGetTimeTick(); } + +/* monotonic time since boot, which also includes the time spent in suspend */ +#define GET_BOOT_SYSTIME(_systime_p) \ + { *(_systime_p) = \ + ({uint64_t __ret = kalGetBootTime(); \ + do_div(__ret, USEC_PER_MSEC); \ + (OS_SYSTIME) __ret; }); \ + } + +/* The macro to copy the system time */ +#define COPY_SYSTIME(_destTime, _srcTime) {(_destTime) = (_srcTime); } + +/* The macro to get the system time difference between t1 and t2 (t1 - t2) */ +/* #define GET_SYSTIME_DIFFERENCE(_time1, _time2, _diffTime) \ + * (_diffTime) = (_time1) - (_time2) + */ + +/* The macro to check for the expiration, if TRUE means + * _currentTime >= _expirationTime + */ +#define CHECK_FOR_EXPIRATION(_currentTime, _expirationTime) \ + (((uint32_t)(_currentTime) - (uint32_t)(_expirationTime)) \ + <= 0x7fffffffUL) + +/* The macro to check for the timeout */ +#define CHECK_FOR_TIMEOUT(_currentTime, _timeoutStartingTime, _timeout) \ + CHECK_FOR_EXPIRATION((_currentTime), \ + ((_timeoutStartingTime) + (_timeout))) + +/* The macro to set the expiration time with a specified timeout */ +/* Watch out for round up. */ +#define SET_EXPIRATION_TIME(_expirationTime, _timeout) \ + { \ + GET_CURRENT_SYSTIME(&(_expirationTime)); \ + (_expirationTime) += (OS_SYSTIME)(_timeout); \ + } + +#define timerRenewTimer(adapter, tmr, interval) \ + timerStartTimer(adapter, tmr, interval, (tmr)->function, (tmr)->data) + +#define MGMT_INIT_TIMER(_adapter_p, _timer, _callbackFunc) \ + timerInitTimer(_adapter_p, &(_timer), (uint32_t)(_callbackFunc)) + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +void cnmTimerInitialize(IN struct ADAPTER *prAdapter); + +void cnmTimerDestroy(IN struct ADAPTER *prAdapter); + +void cnmTimerInitTimerOption(IN struct ADAPTER *prAdapter, + IN struct TIMER *prTimer, + IN PFN_MGMT_TIMEOUT_FUNC pfFunc, + IN unsigned long ulDataPtr, + IN enum ENUM_TIMER_WAKELOCK_TYPE_T eType); + +void cnmTimerStopTimer(IN struct ADAPTER *prAdapter, IN struct TIMER *prTimer); + +void cnmTimerStartTimer(IN struct ADAPTER *prAdapter, IN struct TIMER *prTimer, + IN uint32_t u4TimeoutMs); + +void cnmTimerDoTimeOutCheck(IN struct ADAPTER *prAdapter); + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +static __KAL_INLINE__ int32_t timerPendingTimer(IN struct TIMER *prTimer) +{ + ASSERT(prTimer); + + return prTimer->rLinkEntry.prNext != NULL; +} + +static __KAL_INLINE__ void cnmTimerInitTimer(IN struct ADAPTER *prAdapter, + IN struct TIMER *prTimer, + IN PFN_MGMT_TIMEOUT_FUNC pfFunc, + IN unsigned long ulDataPtr) +{ + cnmTimerInitTimerOption(prAdapter, prTimer, pfFunc, ulDataPtr, + TIMER_WAKELOCK_AUTO); +} + + +#endif /* _CNM_TIMER_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/he_ie.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/he_ie.h new file mode 100644 index 0000000000000000000000000000000000000000..4c26e2da8184538c8f4966bbb6097a616ed22012 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/he_ie.h @@ -0,0 +1,733 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +#ifndef _HE_IE_H +#define _HE_IE_H + +#if (CFG_SUPPORT_802_11AX == 1) + +/* HE Capabilities */ +#define ELEM_EXT_ID_HE_CAP 35 +/* HE Operation */ +#define ELEM_EXT_ID_HE_OP 36 +/* UL OFDMA-based Random Access (UORA) Parameter Set element */ +#define ELEM_EXT_ID_UORA_PARAM 37 +/* MU EDCA Parameter Set element */ +#define ELEM_EXT_ID_MU_EDCA_PARAM 38 +/* Spatial Reuse Parameter Set element */ +#define ELEM_EXT_ID_SR_PARAM 39 + +#define ELEM_EXT_CAP_TWT_REQUESTER_SUPP_BIT 77 +#define ELEM_EXT_CAP_TWT_RESPONDER_SUPP_BIT 78 + +#define HE_PHY_CAP_INFO_LEN 9 + +/* HE CAP - HE MAC Capabilities Information field */ +#define HE_MAC_CAP_BYTE_NUM 6 + +/* HE MAC Capablilites byte0 */ +#define HE_MAC_CAP0_HTC_HE BIT(0) +#define HE_MAC_CAP0_HTC_HE_SHFT 0 +#define HE_MAC_CAP0_TWT_REQ BIT(1) +#define HE_MAC_CAP0_TWT_REQ_SHFT 1 +#define HE_MAC_CAP0_TWT_RSP BIT(2) +#define HE_MAC_CAP0_TWT_RSP_SHFT 2 +#define HE_MAC_CAP0_FRAGMENTATION_SHFT 3 +#define HE_MAC_CAP0_MAX_NUM_OF_FRAGMENTATION_SHFT 5 + +/* HE MAC Capablilites byte1 */ +#define HE_MAC_CAP1_MIN_FRAGMENT_SIZE_SHFT 0 +#define HE_MAC_CAP1_TRIGGER_PAD_DURATION_MASK BITS(2, 3) +#define HE_MAC_CAP1_TRIGGER_PAD_DURATION_SHFT 2 +#define HE_MAC_CAP1_MULTI_TID_AGG_RX_SHFT 4 +#define HE_MAC_CAP1_LINK_ADP_SHFT 7 + +/* HE MAC Capablilites byte2 */ +#define HE_MAC_CAP2_LINK_ADP_SHFT 0 +#define HE_MAC_CAP2_ALL_ACK_SHFT 1 +#define HE_MAC_CAP2_TRS_SHFT 2 +#define HE_MAC_CAP2_BSR_SHFT 3 +#define HE_MAC_CAP2_BTWT_SHFT 4 +#define HE_MAC_CAP2_32BIT_BA_BITMAP_SHFT 5 +#define HE_MAC_CAP2_MU_CASCAD_SHFT 6 +#define HE_MAC_CAP2_ACK_ENABLED_AGG_SHFT 7 + +/* HE MAC Capablilites byte3 */ +#define HE_MAC_CAP3_RESERVED 0 +#define HE_MAC_CAP3_OM_CTRL BIT(1) +#define HE_MAC_CAP3_OM_CTRL_SHFT 1 +#define HE_MAC_CAP3_OFDMA_RA_SHFT 2 +#define HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_SHFT 3 +#define HE_MAC_CAP3_AMSDU_FRAGMENT_SHFT 5 +#define HE_MAC_CAP3_FLEXIBLE_TWT_SHDL BIT(6) +#define HE_MAC_CAP3_FLEXIBLE_TWT_SHDL_SHFT 6 +#define HE_MAC_CAP3_RX_CTRL_TO_MUTI_BSS_SHFT 7 + +/* HE MAC Capablilites byte4 */ +#define HE_MAC_CAP4_BSRP_BQRP_AMPDU_AGG_SHFT 0 +#define HE_MAC_CAP4_QTP_SHFT 1 +#define HE_MAC_CAP4_BQR_SHFT 2 +#define HE_MAC_CAP4_SRP_RSP_SHFT 3 +#define HE_MAC_CAP4_NDP_FEEDBACK_REPORT_SHFT 4 +#define HE_MAC_CAP4_OPS_SHFT 5 +#define HE_MAC_CAP4_AMSDU_IN_AMDU BIT(6) +#define HE_MAC_CAP4_AMSDU_IN_AMDU_SHFT 6 +#define HE_MAC_CAP4_MULTI_TID_AGG_TX 7 + +/* HE MAC Capablilites byte5 */ +#define HE_MAC_CAP5_MULTI_TID_AGG_TX_MASK BITS(0, 1) +#define HE_MAC_CAP5_MULTI_TID_AGG_TX_SHFT 0 +#define HE_MAC_CAP5_SUBCHANNEL_SEL_TX_SHFT 2 +#define HE_MAC_CAP5_UL_2X996TONE_RU_SHFT 3 +#define HE_MAC_CAP5_OM_CNTL_ULMUDATE_DISABLE_RX_SHFT 4 + +/* HE CAP - HE PHY Capabilities Information field */ +#define HE_PHY_CAP_BYTE_NUM 11 + +/* HE PHY Capablilites byte0 */ +#define HE_PHY_CAP0_RESERVED 0 +#define HE_PHY_CAP0_CHAN_WIDTH_SET_BW40_2G BIT(1) +#define HE_PHY_CAP0_CHAN_WIDTH_SET_BW40_BW80_5G BIT(2) +#define HE_PHY_CAP0_CHAN_WIDTH_SET_BW160_5G BIT(3) +#define HE_PHY_CAP0_CHAN_WIDTH_SET_BW80P80_5G BIT(4) +#define HE_PHY_CAP0_CHAN_WIDTH_SET_242TONE_2G BIT(5) +#define HE_PHY_CAP0_CHAN_WIDTH_SET_242TONE_5G BIT(6) +#define HE_PHY_CAP0_CHAN_WIDTH_SET_MASK BITS(1, 7) +#define HE_PHY_CAP0_CHAN_WIDTH_SET_SHFT 1 + +/* HE PHY Capablilites byte1 */ +#define HE_PHY_CAP1_PUNCTURED_PREAMBLE_RX_SHFT 0 +#define HE_PHY_CAP1_DEVICE_CALSS_SHFT 4 +#define HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD BIT(5) +#define HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD_SHFT 5 +#define HE_PHY_CAP1_1X_HE_LTF_SHFT 6 +#define HE_PHY_CAP1_MIDAMBLE_TXRX_MAX_NSTS_SHFT 7 + + +/* HE PHY Capablilites byte2 */ +#define HE_PHY_CAP2_MIDAMBLE_TXRX_MAX_NSTS_SHFT 0 +#define HE_PHY_CAP2_NDP_4X_HE_LTF_SHFT 1 +#define HE_PHY_CAP2_STBC_TX_LT_OR_EQ_80M BIT(2) +#define HE_PHY_CAP2_STBC_TX_LT_OR_EQ_80M_SHFT 2 +#define HE_PHY_CAP2_STBC_RX_LT_OR_EQ_80M BIT(3) +#define HE_PHY_CAP2_STBC_RX_LT_OR_EQ_80M_SHFT 3 +#define HE_PHY_CAP2_DOPPLER_TX_SHFT 4 +#define HE_PHY_CAP2_DOPPLER_RX_SHFT 5 +#define HE_PHY_CAP2_FULL_BW_UL_MU_MIMO BIT(6) +#define HE_PHY_CAP2_FULL_BW_UL_MU_MIMO_SHFT 6 +#define HE_PHY_CAP2_PARTIAL_BW_UL_MU_MIMO BIT(7) +#define HE_PHY_CAP2_PARTIAL_BW_UL_MU_MIMO_SHFT 7 + +/* HE PHY Capablilites byte3 */ +#define HE_PHY_CAP3_DCM_MAX_CONSTELLATION_TX_SHFT 0 +#define HE_PHY_CAP3_DCM_MAX_CONSTELLATION_TX_MASK BITS(0, 1) +#define HE_PHY_CAP3_DCM_MAX_NSS_TX_SHFT 2 +#define HE_PHY_CAP3_DCM_MAX_CONSTELLATION_RX_SHFT 3 +#define HE_PHY_CAP3_DCM_MAX_CONSTELLATION_RX_MASK BITS(3, 4) +#define HE_PHY_CAP3_DCM_MAX_NSS_RX_SHFT 5 +#define HE_PHY_CAP3_UL_HE_MU_PPDU_SHFT 6 +#define HE_PHY_CAP3_SU_BFMER BIT(7) +#define HE_PHY_CAP3_SU_BFMER_SHFT 7 + +/* HE PHY Capablilites byte4 */ +#define HE_PHY_CAP4_SU_BFMEE BIT(0) +#define HE_PHY_CAP4_SU_BFMEE_SHFT 0 +#define HE_PHY_CAP4_MU_BFMER BIT(1) +#define HE_PHY_CAP4_MU_BFMER_SHFT 1 +#define HE_PHY_CAP4_BFMEE_STS_LT_OR_EQ_80M_MASK BITS(2, 4) +#define HE_PHY_CAP4_BFMEE_STS_LT_OR_EQ_80M_SHFT 2 +#define HE_PHY_CAP4_BFMEE_STS_GT_80M_SHFT 5 + +/* HE PHY Capablilites byte5 */ +#define HE_PHY_CAP5_NUM_OF_SND_DIM_LT_OR_EQ_80M_SHFT 0 +#define HE_PHY_CAP5_NUM_OF_SND_DIM_GT_80M_SHFT 3 +#define HE_PHY_CAP5_NG_16_SU_FB BIT(6) +#define HE_PHY_CAP5_NG_16_SU_FB_SHFT 6 +#define HE_PHY_CAP5_NG_16_MU_FB BIT(7) +#define HE_PHY_CAP5_NG_16_MU_FB_SHFT 7 + +/* HE PHY Capablilites byte6 */ +#define HE_PHY_CAP6_CODE_BOOK_4_2_SU_FB BIT(0) +#define HE_PHY_CAP6_CODE_BOOK_4_2_SU_FB_SHFT 0 +#define HE_PHY_CAP6_CODE_BOOK_7_5_MU_FB BIT(1) +#define HE_PHY_CAP6_CODE_BOOK_7_5_MU_FB_SHFT 1 +#define HE_PHY_CAP6_TRIG_SU_BF_FB BIT(2) +#define HE_PHY_CAP6_TRIG_SU_BF_FB_SHFT 2 +#define HE_PHY_CAP6_TRIG_MU_BF_PARTIAL_BW_FB BIT(3) +#define HE_PHY_CAP6_TRIG_MU_BF_PARTIAL_BW_FB_SHFT 3 +#define HE_PHY_CAP6_TRIG_CQI_FB_SHFT 4 +#define HE_PHY_CAP6_PARTIAL_BW_EXTENDED_RANGE BIT(5) +#define HE_PHY_CAP6_PARTIAL_BW_EXTENDED_RANGE_SHFT 5 +#define HE_PHY_CAP6_PARTIAL_BW_DL_MU_MIMO_SHFT 6 +#define HE_PHY_CAP6_PPE_THRESHOLD BIT(7) +#define HE_PHY_CAP6_PPE_THRESHOLD_SHFT 7 + +/* HE PHY Capablilites byte7 */ +#define HE_PHY_CAP7_SRP_BASED_SR_SHFT 0 +#define HE_PHY_CAP7_POWER_BOOST_FACTOR_SHFT 1 +#define HE_PHY_CAP7_SU_MU_4X_HE_LTF_SHFT 2 +#define HE_PHY_CAP7_MAX_NC_MASK BITS(3, 5) +#define HE_PHY_CAP7_MAX_NC_SHFT 3 +#define HE_PHY_CAP7_STBC_TX_GT_80M BIT(6) +#define HE_PHY_CAP7_STBC_TX_GT_80M_SHFT 6 +#define HE_PHY_CAP7_STBC_RX_GT_80M BIT(7) +#define HE_PHY_CAP7_STBC_RX_GT_80M_SHFT 7 + +/* HE PHY Capablilites byte8 */ +#define HE_PHY_CAP8_ER_SU_4X_HE_LTF BIT(0) +#define HE_PHY_CAP8_ER_SU_4X_HE_LTF_SHFT 0 +#define HE_PHY_CAP8_20M_IN_40M_HE_PPDU_2G_SHFT 1 +#define HE_PHY_CAP8_20M_IN_160M_HE_PPDU_SHFT 2 +#define HE_PHY_CAP8_80M_IN_160M_HE_PPDU_SHFT 3 +#define HE_PHY_CAP8_ER_SU_PPDU_1X_HE_LTF BIT(4) +#define HE_PHY_CAP8_ER_SU_PPDU_1X_HE_LTF_SHFT 4 +#define HE_PHY_CAP8_MIDAMBLE_RX_2X_1X_HE_LTF_SHFT 5 +#define HE_PHY_CAP8_DCM_MAX_BW_SHFT 6 + +/* HE PHY Capablilites byte9 */ +#define HE_PHY_CAP9_LT_16_SIGB_OFDM_SYMBOL_SHFT 0 +#define HE_PHY_CAP9_NON_TRIGGER_CQI_FB_SHFT 1 +#define HE_PHY_CAP9_TX_1024_QAM_LESS_242_RU_SHFT 2 +#define HE_PHY_CAP9_RX_1024_QAM_LESS_242_RU_SHFT 3 +#define HE_PHY_CAP9_RX_FULL_BW_COMPRESS_SIGB_SHFT 4 +#define HE_PHY_CAP9_RX_FULL_BW_NONCOMPRESS_SIGB_SHFT 5 + +/* HE PHY Capablilites byte10 */ +/* ALL reserved */ + +/* Trigger Frame MAC Padding Duration */ +#define HE_CAP_TRIGGER_PAD_DURATION_0 0 +#define HE_CAP_TRIGGER_PAD_DURATION_8 1 +#define HE_CAP_TRIGGER_PAD_DURATION_16 2 + +#define HE_CAP_INFO_MCS_MAP_MCS7 0 +#define HE_CAP_INFO_MCS_MAP_MCS9 1 +#define HE_CAP_INFO_MCS_MAP_MCS11 2 +#define HE_CAP_INFO_MCS_NOT_SUPPORTED 3 + +/* PPE Threshold Field */ +#define HE_CAP_PPE_NSS BITS(0, 2) +#define HE_CAP_PPE_NSS_SHFT 0 +#define HE_CAP_PPE_RU_IDX_BMP BITS(3, 6) +#define HE_CAP_PPE_RU_IDX_BMP_SHFT 3 +#define HE_CAP_PPE_PPET16_NSS1_RU0 BITS(7, 9) +#define HE_CAP_PPE_PPET16_NSS1_RU0_SHFT 7 +#define HE_CAP_PPE_PPET8_NSS1_RU0 BITS(10, 12) +#define HE_CAP_PPE_PPET8_NSS1_RU0_SHFT 10 + +#define HE_CAP_PPE_242_RU_IDX BIT(3) +#define HE_CAP_PPE_484_RU_IDX BITS(3, 4) +#define HE_CAP_PPE_996_RU_IDX BITS(3, 5) +#define HE_CAP_PPE_996X2_RU_IDX BITS(3, 6) + +#define CONSTELL_IDX_BPSK 0 +#define CONSTELL_IDX_QPSK 1 +#define CONSTELL_IDX_16QAM 2 +#define CONSTELL_IDX_64QAM 3 +#define CONSTELL_IDX_256QAM 4 +#define CONSTELL_IDX_1024QAM 5 +#define CONSTELL_IDX_RESERVED 6 +#define CONSTELL_IDX_NONE 7 + +/* HE Operation element - HE Operation Parameters field */ +#define HE_OP_BYTE_NUM 3 + +/* HE Operation Parameters - byte0 */ +#define HE_OP_PARAM0_DEFAULT_PE_DUR_MASK BITS(0, 2) +#define HE_OP_PARAM0_DEFAULT_PE_DUR_SHFT 0 +#define HE_OP_PARAM0_TWT_REQUIRED_SHFT 3 +#define HE_OP_PARAM0_TXOP_DUR_RTS_THRESHOLD_MASK BITS(4, 7) +#define HE_OP_PARAM0_TXOP_DUR_RTS_THRESHOLD_SHFT 4 + +/* HE Operation Parameters - byte1 */ +#define HE_OP_PARAM1_TXOP_DUR_RTS_THRESHOLD_MASK BITS(0, 5) +#define HE_OP_PARAM1_TXOP_DUR_RTS_THRESHOLD_SHFT 0 +#define HE_OP_PARAM1_VHT_OP_INFO_PRESENT BIT(6) +#define HE_OP_PARAM1_VHT_OP_INFO_PRESENT_SHFT 6 +#define HE_OP_PARAM1_CO_LOCATED_BSS_SHFT 7 + +/* HE Operation Parameters - byte2 */ +#define HE_OP_PARAM2_ER_SU_DISABLE_MASK BIT(0) +#define HE_OP_PARAM2_ER_SU_DISABLE_SHFT 0 + +/* HE Operation element - BSS Color Information */ +#define HE_OP_BSSCOLOR_BSS_COLOR_SHFT 0 +#define HE_OP_BSSCOLOR_PARTIAL_BSS_COLOR_SHFT 6 +#define HE_OP_BSSCOLOR_BSS_COLOR_DISABLE_SHFT 7 + +/* Spatial Reuse Parameter Set element - SR Control field */ +#define SR_PARAM_SRP_DISALLOWED BIT(0) +#define SR_PARAM_SRP_DISALLOWED_SHFT 0 +#define SR_PARAM_NON_SRG_OBSS_PD_SR_DISALLOWED BIT(1) +#define SR_PARAM_NON_SRG_OBSS_PD_SR_DISALLOWED_SHFT 1 +#define SR_PARAM_NON_SRG_OFFSET_PRESENT BIT(2) +#define SR_PARAM_NON_SRG_OFFSET_PRESENT_SHFT 2 +#define SR_PARAM_SRG_INFO_PRESENT BIT(3) +#define SR_PARAM_SRG_INFO_PRESENT_SHFT 3 +#define SR_PARAM_HESIGA_SR_VALUE15_ALLOWED BIT(4) +#define SR_PARAM_HESIGA_SR_VALUE15_SHFT 4 + +/* 11ax_D3.0 9.2.4.6 HT Control field */ +#define HTC_HE_VARIANT BITS(0, 1) +/* 11ax_D3.0 9.2.4.6.4 A-Control */ +#define HTC_HE_A_CTRL_TRS 0 +#define HTC_HE_A_CTRL_OM 1 +#define HTC_HE_A_CTRL_HLA 2 +#define HTC_HE_A_CTRL_BSR 3 +#define HTC_HE_A_CTRL_UPH 4 +#define HTC_HE_A_CTRL_BQR 5 +#define HTC_HE_A_CTRL_CAS 6 + +/* 1st - OM_Ctrl, 2nd - UPH_Ctrl */ +#define HTC_HE_1ST_A_CTRL_ID BITS(2, 5) +#define HTC_HE_1ST_A_CTRL_ID_SHIFT 2 + +/* 11ax_D3.0 9.2.4.6a.2 OM Control */ +#define HTC_HE_OM_RX_NSS BITS(6, 8) +#define HTC_HE_OM_RX_NSS_SHFT 6 +#define HTC_HE_OM_CH_WIDTH BITS(9, 10) +#define HTC_HE_OM_CH_WIDTH_SHFT 9 +#define HTC_HE_OM_UL_MU_DISABLE BIT(11) +#define HTC_HE_OM_UL_MU_DISABLE_SHFT 11 +#define HTC_HE_OM_TX_NSTS BITS(12, 14) +#define HTC_HE_OM_TX_NSTS_SHFT 12 +#define HTC_HE_OM_ER_SU_DISABLE BIT(15) +#define HTC_HE_OM_ER_SU_DISABLE_SHFT 15 +#define HTC_HE_OM_DL_MUMIMO_RESND_RECMD BIT(16) +#define HTC_HE_OM_DL_MUMIMO_RESND_RECMD_SHFT 16 +#define HTC_HE_OM_UL_MU_DATA_DISABLE BIT(17) +#define HTC_HE_OM_UL_MU_DATA_DISABLE_SHFT 17 + +/* 1st - OM_CTRL, 2nd - UPH_CTRL */ +#define HTC_HE_2ND_A_CTRL_ID BITS(18, 21) +#define HTC_HE_2ND_A_CTRL_ID_SHIFT 18 + +/* 11ax_D3.0 9.2.4.6a.5 UPH Control */ +#define HTC_HE_UPH_UL_PWR_HEADROOM BITS(22, 27) +#define HTC_HE_UPH_UL_PWR_HEADROOM_SHIFT 22 +#define HTC_HE_UPH_MIN_TX_PWR_FLAG BIT(28) +#define HTC_HE_UPH_MIN_TX_PWR_FLAG_SHIFT 28 + +enum ENUM_HTC_HE_OM_CH_WIDTH { + CH_BW_20 = 0, + CH_BW_40 = 1, + CH_BW_80 = 2, + CH_BW_160 = 3, +}; + +/* 11ax_D3.0 9.3.1.9 BlockAck frame format */ +#define HE_BA_TYPE BITS(1, 4) +#define HE_BA_TYPE_SHFT 1 +enum ENUM_HEBA_TYPE { + HE_BA_TYPE_BASIC = 0, /* 0 Basic */ + HE_BA_TYPE_EXT_COMPRESSED = 1, /* 1 Extended Compressed */ + HE_BA_TYPE_COMPRESSED = 2, /* 2 Compressed */ + HE_BA_TYPE_MULTI_TID = 3, /* 3 Multi-TID */ + /* 4-5 Reserved */ + HE_BA_TYPE_GCR = 6, /* 6 GCR */ + /* 7-9 Reserved */ + HE_BA_TYPE_GLK_GCR = 10, /* 10 GLK-GCR */ + HE_BA_TYPE_MULTI_STA = 11, /* 11 Multi-STA */ + /* 12-15 Reserved */ +}; + +/* should use macro to access field of HE MAC CAP*/ +#define HE_SET_MAC_CAP_HTC_HE(_aucHeMacCapInfo) \ + (_aucHeMacCapInfo[0] |= HE_MAC_CAP0_HTC_HE) + +#define HE_SET_MAC_CAP_TWT_REQ(_aucHeMacCapInfo) \ + (_aucHeMacCapInfo[0] |= HE_MAC_CAP0_TWT_REQ) + +#define HE_IS_MAC_CAP_TWT_RSP(_aucHeMacCapInfo) \ + (_aucHeMacCapInfo[0] & HE_MAC_CAP0_TWT_RSP) + +#define HE_SET_MAC_CAP_TRIGGER_PAD_DURATION(_aucHeMacCapInfo, _ucDur) \ +{ \ + _aucHeMacCapInfo[1] &= ~(HE_MAC_CAP1_TRIGGER_PAD_DURATION_MASK); \ + _aucHeMacCapInfo[1] |= \ + ((_ucDur << HE_MAC_CAP1_TRIGGER_PAD_DURATION_SHFT) \ + & HE_MAC_CAP1_TRIGGER_PAD_DURATION_MASK); \ +} + +#define HE_IS_MAC_CAP_FLEXIBLE_TWT_SHDL(_aucHeMacCapInfo) \ + (_aucHeMacCapInfo[3] & HE_MAC_CAP3_FLEXIBLE_TWT_SHDL) + + +#define HE_SET_MAC_CAP_OM_CTRL(_aucHeMacCapInfo) \ + (_aucHeMacCapInfo[3] |= HE_MAC_CAP3_OM_CTRL) + +/* should use macro to access field of HE PHY CAP*/ +#define HE_SET_PHY_CAP_CHAN_WIDTH_SET_BW40_2G(_aucHePhyCapInfo) \ + (_aucHePhyCapInfo[0] |= HE_PHY_CAP0_CHAN_WIDTH_SET_BW40_2G) + +#define HE_SET_PHY_CAP_CHAN_WIDTH_SET_BW40_BW80_5G(_aucHePhyCapInfo) \ + (_aucHePhyCapInfo[0] |= HE_PHY_CAP0_CHAN_WIDTH_SET_BW40_BW80_5G) + +#define HE_IS_PHY_CAP_CHAN_WIDTH_SET_BW160_5G(_aucHePhyCapInfo) \ + (_aucHePhyCapInfo[0] & HE_PHY_CAP0_CHAN_WIDTH_SET_BW160_5G) + +#define HE_SET_PHY_CAP_CHAN_WIDTH_SET_BW160_5G(_aucHePhyCapInfo) \ + (_aucHePhyCapInfo[0] |= HE_PHY_CAP0_CHAN_WIDTH_SET_BW160_5G) + +#define HE_IS_PHY_CAP_CHAN_WIDTH_SET_BW80P80_5G(_aucHePhyCapInfo) \ + (_aucHePhyCapInfo[0] & HE_PHY_CAP0_CHAN_WIDTH_SET_BW80P80_5G) + +#define HE_SET_PHY_CAP_CHAN_WIDTH_SET_BW80P80_5G(_aucHePhyCapInfo) \ + (_aucHePhyCapInfo[0] |= HE_PHY_CAP0_CHAN_WIDTH_SET_BW80P80_5G) + +#define HE_SET_PHY_CAP_LDPC_CODING_IN_PAYLOAD(_aucHePhyCapInfo) \ + (_aucHePhyCapInfo[1] |= HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD) + +#define HE_SET_PHY_CAP_STBC_TX_LT_OR_EQ_80M(_aucHePhyCapInfo) \ + (_aucHePhyCapInfo[2] |= HE_PHY_CAP2_STBC_TX_LT_OR_EQ_80M) + +#define HE_SET_PHY_CAP_STBC_RX_LT_OR_EQ_80M(_aucHePhyCapInfo) \ + (_aucHePhyCapInfo[2] |= HE_PHY_CAP2_STBC_RX_LT_OR_EQ_80M) + +#define HE_UNSET_PHY_CAP_SU_BFMER(_aucHePhyCapInfo) \ + (_aucHePhyCapInfo[3] &= ~HE_PHY_CAP3_SU_BFMER) + +/* set to 0 if DCM is not supported */ +/* set to 1 for BPSK */ +/* set to 2 for QPSK */ +/* set to 3 for 16-QAM */ +#define HE_SET_PHY_CAP_DCM_MAX_CONSTELLATION_TX(_aucHePhyCapInfo, _ucVal) \ +{ \ + _aucHePhyCapInfo[3] &= ~(HE_PHY_CAP3_DCM_MAX_CONSTELLATION_TX_MASK); \ + _aucHePhyCapInfo[3] |= \ + ((_ucVal << HE_PHY_CAP3_DCM_MAX_CONSTELLATION_TX_SHFT) \ + & HE_PHY_CAP3_DCM_MAX_CONSTELLATION_TX_MASK); \ +} + +/* set to 0 if DCM is not supported */ +/* set to 1 for BPSK */ +/* set to 2 for QPSK */ +/* set to 3 for 16-QAM */ +#define HE_SET_PHY_CAP_DCM_MAX_CONSTELLATION_RX(_aucHePhyCapInfo, _ucVal) \ +{ \ + _aucHePhyCapInfo[3] &= ~(HE_PHY_CAP3_DCM_MAX_CONSTELLATION_RX_MASK); \ + _aucHePhyCapInfo[3] |= \ + ((_ucVal << HE_PHY_CAP3_DCM_MAX_CONSTELLATION_RX_SHFT) \ + & HE_PHY_CAP3_DCM_MAX_CONSTELLATION_RX_MASK); \ +} + +#define HE_GET_PHY_CAP_DCM_MAX_CONSTELLATION_TX(_aucHePhyCapInfo) \ + ((_aucHePhyCapInfo[3] & HE_PHY_CAP3_DCM_MAX_CONSTELLATION_TX_MASK) \ + >> HE_PHY_CAP3_DCM_MAX_CONSTELLATION_TX_SHFT) + +#define HE_GET_PHY_CAP_DCM_MAX_CONSTELLATION_RX(_aucHePhyCapInfo) \ + ((_aucHePhyCapInfo[3] & HE_PHY_CAP3_DCM_MAX_CONSTELLATION_RX_MASK) \ + >> HE_PHY_CAP3_DCM_MAX_CONSTELLATION_RX_SHFT) + +#define HE_SET_PHY_CAP_SU_BFMEE(_aucHePhyCapInfo) \ + (_aucHePhyCapInfo[4] |= HE_PHY_CAP4_SU_BFMEE) + +#define HE_UNSET_PHY_CAP_MU_BFMER(_aucHePhyCapInfo) \ + (_aucHePhyCapInfo[4] &= ~HE_PHY_CAP4_MU_BFMER) + +#define HE_SET_PHY_CAP_BFMEE_STS_LT_OR_EQ_80M(_aucHePhyCapInfo, _ucSts) \ +{ \ + _aucHePhyCapInfo[4] &= ~(HE_PHY_CAP4_BFMEE_STS_LT_OR_EQ_80M_MASK); \ + _aucHePhyCapInfo[4] |= \ + ((_ucSts << HE_PHY_CAP4_BFMEE_STS_LT_OR_EQ_80M_SHFT) \ + & HE_PHY_CAP4_BFMEE_STS_LT_OR_EQ_80M_MASK); \ +} + +#define HE_SET_PHY_CAP_NG_16_SU_FB(_aucHePhyCapInfo) \ + (_aucHePhyCapInfo[5] |= HE_PHY_CAP5_NG_16_SU_FB) + +#define HE_SET_PHY_CAP_NG_16_MU_FB(_aucHePhyCapInfo) \ + (_aucHePhyCapInfo[5] |= HE_PHY_CAP5_NG_16_MU_FB) + +#define HE_SET_PHY_CAP_CODE_BOOK_4_2_SU_FB(_aucHePhyCapInfo) \ + (_aucHePhyCapInfo[6] |= HE_PHY_CAP6_CODE_BOOK_4_2_SU_FB) + +#define HE_SET_PHY_CAP_CODE_BOOK_7_5_MU_FB(_aucHePhyCapInfo) \ + (_aucHePhyCapInfo[6] |= HE_PHY_CAP6_CODE_BOOK_7_5_MU_FB) + +#define HE_SET_PHY_CAP_TRIG_SU_BF_FB(_aucHePhyCapInfo) \ + (_aucHePhyCapInfo[6] |= HE_PHY_CAP6_TRIG_SU_BF_FB) + +#define HE_SET_PHY_CAP_TRIG_MU_BF_PARTIAL_BW_FB(_aucHePhyCapInfo) \ + (_aucHePhyCapInfo[6] |= HE_PHY_CAP6_TRIG_MU_BF_PARTIAL_BW_FB) + +#define HE_SET_PHY_CAP_HE_PHY_CAP6_TRIG_MU_BF_PARTIAL_BW_FB(_aucHePhyCapInfo) \ + (_aucHePhyCapInfo[6] |= HE_PHY_CAP6_TRIG_MU_BF_PARTIAL_BW_FB) + +#define HE_SET_PHY_CAP_PARTIAL_BW_EXTENDED_RANGE(_aucHePhyCapInfo) \ + (_aucHePhyCapInfo[6] |= HE_PHY_CAP6_PARTIAL_BW_EXTENDED_RANGE) + +#define HE_GET_PHY_CAP_PARTIAL_BW_EXTENDED_RANGE(_aucHePhyCapInfo) \ + ((_aucHePhyCapInfo[6] & HE_PHY_CAP6_PARTIAL_BW_EXTENDED_RANGE) \ + >> HE_PHY_CAP6_PARTIAL_BW_EXTENDED_RANGE_SHFT) + +#define HE_IS_PHY_CAP_PPE_THRESHOLD(_aucHePhyCapInfo) \ + (_aucHePhyCapInfo[6] & HE_PHY_CAP6_PPE_THRESHOLD) + +#define HE_SET_PHY_CAP_MAX_NC(_aucHePhyCapInfo, _ucMaxNc) \ +{ \ + _aucHePhyCapInfo[7] &= ~(HE_PHY_CAP7_MAX_NC_MASK); \ + _aucHePhyCapInfo[7] |= ((_ucMaxNc << HE_PHY_CAP7_MAX_NC_SHFT) \ + & HE_PHY_CAP7_MAX_NC_MASK); \ +} + +#define HE_SET_PHY_CAP_STBC_TX_GT_80M(_aucHePhyCapInfo) \ + (_aucHePhyCapInfo[7] |= HE_PHY_CAP7_STBC_TX_GT_80M) + +#define HE_SET_PHY_CAP_STBC_RX_GT_80M(_aucHePhyCapInfo) \ + (_aucHePhyCapInfo[7] |= HE_PHY_CAP7_STBC_RX_GT_80M) + +#define HE_SET_PHY_CAP_ER_SU_4X_HE_LTF(_aucHePhyCapInfo) \ + (_aucHePhyCapInfo[8] |= HE_PHY_CAP8_ER_SU_4X_HE_LTF) + +#define HE_GET_PHY_CAP_ER_SU_4X_HE_LTF(_aucHePhyCapInfo) \ + ((_aucHePhyCapInfo[8] & HE_PHY_CAP8_ER_SU_4X_HE_LTF) \ + >> HE_PHY_CAP8_ER_SU_4X_HE_LTF_SHFT) + +#define HE_SET_PHY_CAP_ER_SU_PPDU_1X_HE_LTF(_aucHePhyCapInfo) \ + (_aucHePhyCapInfo[8] |= HE_PHY_CAP8_ER_SU_PPDU_1X_HE_LTF) + +#define HE_GET_PHY_CAP_ER_SU_PPDU_1X_HE_LTF(_aucHePhyCapInfo) \ + ((_aucHePhyCapInfo[8] & HE_PHY_CAP8_ER_SU_PPDU_1X_HE_LTF) \ + >> HE_PHY_CAP8_ER_SU_PPDU_1X_HE_LTF_SHFT) + +/* should use macro to access field of HE OP*/ +#define HE_IS_VHT_OP_INFO_PRESENT(_aucHeOpParams) \ + (_aucHeOpParams[1] |= HE_OP_PARAM1_VHT_OP_INFO_PRESENT) + + +#define HE_IS_HTC_HE_VARIANT(_u4HTC) \ + (_u4HTC & HTC_HE_VARIANT == HTC_HE_VARIANT) +#define HE_SET_HTC_HE_VARIANT(_u4HTC) \ + (_u4HTC |= HTC_HE_VARIANT) + +/* Control ID */ +#define HE_SET_HTC_1ST_A_CTRL_ID(_u4HTC, _ctrl_id) \ +{\ +(_u4HTC) &= ~(HTC_HE_1ST_A_CTRL_ID); \ +(_u4HTC) |= (((_ctrl_id) << (HTC_HE_1ST_A_CTRL_ID_SHIFT)) \ + & (HTC_HE_1ST_A_CTRL_ID)); \ +} +#define HE_GET_HTC_1ST_A_CTRL_ID(_u4HTC) \ + ((_u4HTC & HTC_HE_1ST_A_CTRL_ID) >> HTC_HE_1ST_A_CTRL_ID_SHIFT) + +#define HE_SET_HTC_2ND_A_CTRL_ID(_u4HTC, _ctrl_id) \ +{\ + (_u4HTC) &= ~(HTC_HE_2ND_A_CTRL_ID); \ + (_u4HTC) |= (((_ctrl_id) << (HTC_HE_2ND_A_CTRL_ID_SHIFT)) \ + & (HTC_HE_2ND_A_CTRL_ID)); \ +} +#define HE_GET_HTC_2ND_A_CTRL_ID(_u4HTC) \ + ((_u4HTC & HTC_HE_2ND_A_CTRL_ID) >> HTC_HE_2ND_A_CTRL_ID_SHIFT) + +/* OM - RX NSS */ +#define HE_SET_HTC_HE_OM_RX_NSS(_u4HTC, _rx_nss) \ +{\ +(_u4HTC) &= ~(HTC_HE_OM_RX_NSS); \ +(_u4HTC) |= (((_rx_nss) << (HTC_HE_OM_RX_NSS_SHFT)) & (HTC_HE_OM_RX_NSS)); \ +} +#define HE_GET_HTC_HE_OM_RX_NSS(_u4HTC) \ + ((_u4HTC & HTC_HE_OM_RX_NSS) >> HTC_HE_OM_RX_NSS_SHFT) + +/* OM - TX NSTS */ +#define HE_SET_HTC_HE_OM_TX_NSTS(_u4HTC, _tx_nsts) \ +{\ +(_u4HTC) &= ~(HTC_HE_OM_TX_NSTS); \ +(_u4HTC) |= (((_tx_nsts) << (HTC_HE_OM_TX_NSTS_SHFT)) & (HTC_HE_OM_TX_NSTS)); \ +} +#define HE_GET_HTC_HE_OM_TX_NSTS(_u4HTC) \ + ((_u4HTC & HTC_HE_OM_TX_NSTS) >> HTC_HE_OM_TX_NSTS_SHFT) + +/* OM - Channel Width */ +#define HE_SET_HTC_HE_OM_CH_WIDTH(_u4HTC, _bw) \ +{\ +(_u4HTC) &= ~(HTC_HE_OM_CH_WIDTH); \ +(_u4HTC) |= (((_bw) << (HTC_HE_OM_CH_WIDTH_SHFT)) & (HTC_HE_OM_CH_WIDTH)); \ +} +#define HE_GET_HTC_HE_OM_CH_WIDTH(_u4HTC) \ + ((_u4HTC & HTC_HE_OM_CH_WIDTH) >> HTC_HE_OM_CH_WIDTH_SHFT) + +/* OM - ER SU Disable */ +#define HE_SET_HTC_HE_OM_ER_SU_DISABLE(_u4HTC, _er_dis) \ +{\ +(_u4HTC) &= ~(HTC_HE_OM_ER_SU_DISABLE); \ +(_u4HTC) |= (((_er_dis) << (HTC_HE_OM_ER_SU_DISABLE_SHFT)) \ + & (HTC_HE_OM_ER_SU_DISABLE)); \ +} +#define HE_GET_HTC_HE_OM_ER_SU_DISABLE(_u4HTC) \ + ((_u4HTC & HTC_HE_OM_ER_SU_DISABLE) >> HTC_HE_OM_ER_SU_DISABLE_SHFT) + +/* OM - UL MU Disable */ +#define HE_SET_HTC_HE_OM_UL_MU_DISABLE(_u4HTC, _ul_dis) \ +{\ +(_u4HTC) &= ~(HTC_HE_OM_UL_MU_DISABLE); \ +(_u4HTC) |= (((_ul_dis) << (HTC_HE_OM_UL_MU_DISABLE_SHFT)) \ + & (HTC_HE_OM_UL_MU_DISABLE)); \ +} +#define HE_GET_HTC_HE_OM_UL_MU_DISABLE(_u4HTC) \ + ((_u4HTC & HTC_HE_OM_UL_MU_DISABLE) >> HTC_HE_OM_UL_MU_DISABLE_SHFT) + +/* OM - UL MU Data Disable */ +#define HE_SET_HTC_HE_OM_UL_MU_DATA_DISABLE(_u4HTC, _ul_data_dis) \ +{\ +(_u4HTC) &= ~(HTC_HE_OM_UL_MU_DATA_DISABLE); \ +(_u4HTC) |= (((_ul_data_dis) << (HTC_HE_OM_UL_MU_DATA_DISABLE_SHFT)) \ + & (HTC_HE_OM_UL_MU_DATA_DISABLE)); \ +} +#define HE_GET_HTC_HE_OM_UL_MU_DATA_DISABLE(_u4HTC) \ + ((_u4HTC & HTC_HE_OM_UL_MU_DATA_DISABLE) \ + >> HTC_HE_OM_UL_MU_DATA_DISABLE_SHFT) + +/* UPH - UL PWR HEADROOM */ +#define HE_SET_HTC_HE_UPH(_u4HTC, _uph) \ +{\ +(_u4HTC) &= ~(HTC_HE_UPH_UL_PWR_HEADROOM); \ +(_u4HTC) |= (((_uph) << (HTC_HE_UPH_UL_PWR_HEADROOM_SHIFT)) \ + & (HTC_HE_UPH_UL_PWR_HEADROOM)); \ +} +#define HE_GET_HTC_HE_UPH(_u4HTC) \ + ((_u4HTC & HTC_HE_UPH_UL_PWR_HEADROOM) \ + >> HTC_HE_UPH_UL_PWR_HEADROOM_SHIFT) + +/* UPH - MIN TX PWR FLAG */ +#define HE_SET_HTC_HE_UPH_MIN_TX_PWR_FLAG(_u4HTC, _flag) \ +{\ +(_u4HTC) &= ~(HTC_HE_UPH_MIN_TX_PWR_FLAG); \ +(_u4HTC) |= (((_flag) << (HTC_HE_UPH_MIN_TX_PWR_FLAG_SHIFT)) \ + & (HTC_HE_UPH_MIN_TX_PWR_FLAG)); \ +} +#define HE_GET_HTC_HE_UPH_MIN_TX_PWR_FLAG(_u4HTC) \ + ((_u4HTC & HTC_HE_UPH_MIN_TX_PWR_FLAG) \ + >> HTC_HE_UPH_MIN_TX_PWR_FLAG_SHIFT) + +/* should use macro to access field of HE OP*/ +#define HE_RESET_HE_OP(_aucHeOpInfo) \ + memset(_aucHeOpInfo, 0, HE_OP_BYTE_NUM) + +#define HE_SET_OP_PARAM_ER_SU_DISABLE(_aucHeOpParams) \ + (_aucHeOpParams[2] |= HE_OP_PARAM2_ER_SU_DISABLE_MASK) + +#define HE_IS_ER_SU_DISABLE(_aucHeOpParams) \ + (_aucHeOpParams[2] & HE_OP_PARAM2_ER_SU_DISABLE_MASK) + +struct _IE_HE_CAP_T { + u_int8_t ucId; + u_int8_t ucLength; + u_int8_t ucExtId; + u_int8_t ucHeMacCap[HE_MAC_CAP_BYTE_NUM]; /* BIT0 ~ BIT47 */ + u_int8_t ucHePhyCap[HE_PHY_CAP_BYTE_NUM]; /* BIT0 ~ BIT87 */ + u_int8_t aucVarInfo[0]; +} __KAL_ATTRIB_PACKED__; + +struct _IE_HE_OP_T { + u_int8_t ucId; + u_int8_t ucLength; + u_int8_t ucExtId; + u_int8_t ucHeOpParams[HE_OP_BYTE_NUM]; + u_int8_t ucBssColorInfo; + u_int16_t u2HeBasicMcsSet; + u_int8_t aucVarInfo[0]; +} __KAL_ATTRIB_PACKED__; + +struct _HE_SUPPORTED_MCS_FIELD { + u_int16_t u2RxMcsMap; + u_int16_t u2TxMcsMap; +} __KAL_ATTRIB_PACKED__; + +struct _PPE_THRESHOLD_FIELD { + /* 128-bit space can support 4 NSS */ + u_int64_t u8Space0; + u_int64_t u8Space1; +} __KAL_ATTRIB_PACKED__; + +struct _VHT_OP_INFO_T { + u_int8_t ucVhtOperation[3]; +} __KAL_ATTRIB_PACKED__; + +struct _HE_MAX_BSSID_IND_T { + u_int8_t ucMaxBSSIDIndicator; +} __KAL_ATTRIB_PACKED__; + +struct _MU_AC_PARAM_RECORD_T { + u_int8_t ucAciAifsn; + u_int8_t ucEcw; + u_int8_t ucMUEdcaTimer; +} __KAL_ATTRIB_PACKED__; + +struct _IE_MU_EDCA_PARAM_T { + u_int8_t ucId; + u_int8_t ucLength; + u_int8_t ucExtId; + u_int8_t ucMUQosInfo; + struct _MU_AC_PARAM_RECORD_T arMUAcParam[4]; +} __KAL_ATTRIB_PACKED__; + +struct _SRG_SR_INFO_T { + u_int8_t ucObssPdMinOffset; + u_int8_t ucObssPdMaxOffset; + u_int64_t u8BSSColorBitmap; + u_int64_t u8PartialBSSIDBitmap; +} __KAL_ATTRIB_PACKED__; + +struct _NON_SRG_SR_INFO_T { + u_int8_t ucObssPdMaxOffset; +} __KAL_ATTRIB_PACKED__; + +struct _IE_SR_PARAM_T { + u_int8_t ucId; + u_int8_t ucLength; + u_int8_t ucExtId; + u_int8_t ucSRControl; + u_int8_t aucVarInfo[1]; +} __KAL_ATTRIB_PACKED__; + +#endif /* CFG_SUPPORT_802_11AX == 1 */ +#endif /* !_HE_IE_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/he_rlm.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/he_rlm.h new file mode 100644 index 0000000000000000000000000000000000000000..f657ca4a4d90da7cb7f241ba65bf0ab58a38647a --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/he_rlm.h @@ -0,0 +1,187 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ + +/*! \file "rlm.h" + * \brief + */ + +#ifndef _HE_RLM_H +#define _HE_RLM_H + +#if (CFG_SUPPORT_802_11AX == 1) + +/****************************************************************************** + * C O M P I L E R F L A G S + ****************************************************************************** + */ + +/****************************************************************************** + * E X T E R N A L R E F E R E N C E S + ****************************************************************************** + */ + +/****************************************************************************** + * C O N S T A N T S + ****************************************************************************** + */ + +#define HE_PHY_CAP2_INFO_DEFAULT_VAL (HE_PHY_CAP2_FULL_BW_UL_MU_MIMO | \ + HE_PHY_CAP2_PARTIAL_BW_UL_MU_MIMO) +#define HE_PHY_CAP6_INFO_DEFAULT_VAL (HE_PHY_CAP6_PPE_THRESHOLD) + +#define PPE_RU_IDX_SIZE 4 +#define PPE_SUBFIELD_BITS_NUM 6 + +/****************************************************************************** + * M A C R O S + ****************************************************************************** + */ +#define HE_RESET_MAC_CAP(_aucHeMacCapInfo) \ + (memset(_aucHeMacCapInfo, 0, HE_MAC_CAP_BYTE_NUM)) + +#define HE_RESET_PHY_CAP(_aucHePhyCapInfo) \ +{ \ + memset(_aucHePhyCapInfo, 0, HE_PHY_CAP_BYTE_NUM); \ + _aucHePhyCapInfo[2] = (u_int8_t)HE_PHY_CAP2_INFO_DEFAULT_VAL; \ + _aucHePhyCapInfo[6] = (u_int8_t)HE_PHY_CAP6_INFO_DEFAULT_VAL; \ +} + +/****************************************************************************** + * D A T A T Y P E S + ****************************************************************************** + */ +struct __HE_TWT_INFO_T { + u_int8_t ucFlowType; + u_int8_t ucFlowID; + u_int8_t ucIntervalExp; + u_int8_t ucProtection; +}; + +struct __HE_CFG_INFO_T { + u_int8_t fgHeSupport; /* HE Support */ + u_int8_t fgHeEnable; /* HE Enable/Disable Control */ + u_int8_t fgTwtRequesterEnable; /* HW TWT Requester Control */ + u_int8_t fgTwtResponderEnable; /* HW TWT Responder Control */ + u_int8_t fgHtcHe; /* +HTC HE Support */ + u_int8_t fgFragment; /* Fragmentation Support */ + u_int8_t fgMultiTidAgg; /* Multi-TID Aggregation Support */ + u_int8_t fgAmsduFragment; /* A-MSDU Fragmentation Support */ + u_int8_t fg32bitBaBitmap; /* 32-bit BA Bitmap Support */ +}; + +struct HE_A_CTRL_OM_T { + u_int8_t ucRxNss; + u_int8_t ucTxNsts; + u_int8_t ucBW; + u_int8_t fgDisMuUL; + u_int8_t fgDisMuULData; +}; + + +/****************************************************************************** + * P U B L I C D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * P R I V A T E D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N D E C L A R A T I O N S + ****************************************************************************** + */ + +u_int32_t heRlmCalculateHeCapIELen( + struct ADAPTER *prAdapter, + u_int8_t ucBssIndex, + struct STA_RECORD *prStaRec); +u_int32_t heRlmCalculateHeOpIELen( + struct ADAPTER *prAdapter, + u_int8_t ucBssIndex, + struct STA_RECORD *prStaRec); +void heRlmReqGenerateHeCapIE( + struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo); +void heRlmRspGenerateHeCapIE( + struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo); +void heRlmRspGenerateHeOpIE( + struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo); +void heRlmRecHeCapInfo( + struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + u_int8_t *pucIE); +void heRlmRecHeOperation( + struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, + u_int8_t *pucIE); +u_int8_t heRlmRecHeSRParams( + struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, + struct SW_RFB *prSwRfb, + u_int8_t *pucIE, + u_int16_t u2IELength); +void heRlmInitHeHtcACtrlOMAndUPH( + struct ADAPTER *prAdapter); +void heRlmParseHeHtcACtrlOM( + uint32_t u4Htc, + struct HE_A_CTRL_OM_T *prHeActrlOM); +uint32_t heRlmSendHtcNullFrame( + IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, + IN uint8_t ucUP, + IN PFN_TX_DONE_HANDLER pfTxDoneHandler); +#endif /* CFG_SUPPORT_802_11AX == 1 */ +#endif /* !_HE_RLM_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/hem_mbox.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/hem_mbox.h new file mode 100644 index 0000000000000000000000000000000000000000..d1e105bfc41b1cdb3d461aa373331de9f7e2d8b9 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/hem_mbox.h @@ -0,0 +1,452 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: include/mgmt/hem_mbox.h + */ + +/*! \file hem_mbox.h + * \brief + * + */ + +#ifndef _HEM_MBOX_H +#define _HEM_MBOX_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +/* Message IDs */ +enum ENUM_MSG_ID { + /* MANY notify CNM to obtain channel privilege */ + MID_MNY_CNM_CH_REQ, + /* MANY notify CNM to abort/release channel privilege */ + MID_MNY_CNM_CH_ABORT, + + /* CNM notify AIS for indicating channel granted */ + MID_CNM_AIS_CH_GRANT, + /* CNM notify P2P for indicating channel granted */ + MID_CNM_P2P_CH_GRANT, + /* CNM notify BOW for indicating channel granted */ + MID_CNM_BOW_CH_GRANT, + +#if (CFG_SUPPORT_DFS_MASTER == 1) + MID_CNM_P2P_RADAR_DETECT, + MID_CNM_P2P_CSA_DONE, +#endif + /*--------------------------------------------------*/ + /* SCN Module Mailbox Messages */ + /*--------------------------------------------------*/ + /* AIS notify SCN for starting scan */ + MID_AIS_SCN_SCAN_REQ, + /* AIS notify SCN for starting scan with multiple SSID support */ + MID_AIS_SCN_SCAN_REQ_V2, + /* AIS notify SCN for cancelling scan */ + MID_AIS_SCN_SCAN_CANCEL, + /* P2P notify SCN for starting scan */ + MID_P2P_SCN_SCAN_REQ, + /* P2P notify SCN for starting scan with multiple SSID support */ + MID_P2P_SCN_SCAN_REQ_V2, + /* P2P notify SCN for cancelling scan */ + MID_P2P_SCN_SCAN_CANCEL, + /* BOW notify SCN for starting scan */ + MID_BOW_SCN_SCAN_REQ, + /* BOW notify SCN for starting scan with multiple SSID support */ + MID_BOW_SCN_SCAN_REQ_V2, + /* BOW notify SCN for cancelling scan */ + MID_BOW_SCN_SCAN_CANCEL, + /* RLM notify SCN for starting scan (OBSS-SCAN) */ + MID_RLM_SCN_SCAN_REQ, + /* RLM notify SCN for starting scan (OBSS-SCAN) + * with multiple SSID support + */ + MID_RLM_SCN_SCAN_REQ_V2, + /* RLM notify SCN for cancelling scan (OBSS-SCAN) */ + MID_RLM_SCN_SCAN_CANCEL, + /* SCN notify AIS for scan completion */ + MID_SCN_AIS_SCAN_DONE, + /* SCN notify P2P for scan completion */ + MID_SCN_P2P_SCAN_DONE, + /* SCN notify BOW for scan completion */ + MID_SCN_BOW_SCAN_DONE, + /* SCN notify RLM for scan completion (OBSS-SCAN) */ + MID_SCN_RLM_SCAN_DONE, + + /*--------------------------------------------------*/ + /* AIS Module Mailbox Messages */ + /*--------------------------------------------------*/ + /* OID/IOCTL notify AIS for join */ + MID_OID_AIS_FSM_JOIN_REQ, + /* OID/IOCTL notify AIS for abort */ + MID_OID_AIS_FSM_ABORT, + /* AIS notify SAA for Starting authentication/association fsm */ + MID_AIS_SAA_FSM_START, + /* OID notify SAA to continue to do authentication/association fsm for + ** FT + */ + MID_OID_SAA_FSM_CONTINUE, + /* OID notify SAA to continue SAE authentication/association fsm */ + MID_OID_SAA_FSM_EXTERNAL_AUTH, + /* AIS notify SAA for Aborting authentication/association fsm */ + MID_AIS_SAA_FSM_ABORT, + /* SAA notify AIS for indicating join complete */ + MID_SAA_AIS_JOIN_COMPLETE, + +#if CFG_ENABLE_BT_OVER_WIFI + /*--------------------------------------------------*/ + /* BOW Module Mailbox Messages */ + /*--------------------------------------------------*/ + /* BOW notify SAA for Starting authentication/association fsm */ + MID_BOW_SAA_FSM_START, + /* BOW notify SAA for Aborting authentication/association fsm */ + MID_BOW_SAA_FSM_ABORT, + /* SAA notify BOW for indicating join complete */ + MID_SAA_BOW_JOIN_COMPLETE, +#endif + +#if CFG_ENABLE_WIFI_DIRECT + /*--------------------------------------------------*/ + /* P2P Module Mailbox Messages */ + /*--------------------------------------------------*/ + /* P2P notify SAA for Starting authentication/association fsm */ + MID_P2P_SAA_FSM_START, + /* P2P notify SAA for Aborting authentication/association fsm */ + MID_P2P_SAA_FSM_ABORT, + /* SAA notify P2P for indicating join complete */ + MID_SAA_P2P_JOIN_COMPLETE, + + MID_MNY_P2P_FUN_SWITCH, /* Enable P2P FSM. */ + /* Start device discovery. */ + MID_MNY_P2P_DEVICE_DISCOVERY, + /* Connection request. */ + MID_MNY_P2P_CONNECTION_REQ, + /* Abort connection request, P2P FSM return to IDLE. */ + MID_MNY_P2P_CONNECTION_ABORT, + MID_MNY_P2P_BEACON_UPDATE, + MID_MNY_P2P_STOP_AP, + MID_MNY_P2P_CHNL_REQ, + MID_MNY_P2P_CHNL_ABORT, + MID_MNY_P2P_MGMT_TX, + MID_MNY_P2P_MGMT_TX_CANCEL_WAIT, + MID_MNY_P2P_GROUP_DISSOLVE, + MID_MNY_P2P_MGMT_FRAME_REGISTER, + MID_MNY_P2P_NET_DEV_REGISTER, + MID_MNY_P2P_START_AP, + MID_MNY_P2P_DEL_IFACE, + MID_MNY_P2P_MGMT_FRAME_UPDATE, +#if (CFG_SUPPORT_DFS_MASTER == 1) + MID_MNY_P2P_DFS_CAC, + MID_MNY_P2P_SET_NEW_CHANNEL, +#endif +#if CFG_SUPPORT_WFD + MID_MNY_P2P_WFD_CFG_UPDATE, +#endif + MID_MNY_P2P_ACTIVE_BSS, +#endif + +#if CFG_SUPPORT_ADHOC + /* SCN notify AIS that an IBSS Peer has been found + * and can merge into + */ + MID_SCN_AIS_FOUND_IBSS, +#endif /* CFG_SUPPORT_ADHOC */ + + /* SAA notify AIS for indicating deauthentication/disassociation */ + MID_SAA_AIS_FSM_ABORT, + + /*--------------------------------------------------*/ + /* AIS MGMT-TX Support */ + /*--------------------------------------------------*/ + MID_MNY_AIS_REMAIN_ON_CHANNEL, + MID_MNY_AIS_CANCEL_REMAIN_ON_CHANNEL, + MID_MNY_AIS_MGMT_TX, + MID_MNY_AIS_MGMT_TX_CANCEL_WAIT, + MID_WNM_AIS_BSS_TRANSITION, + MID_OID_WMM_TSPEC_OPERATE, + MID_RRM_REQ_SCHEDULE, +#if CFG_SUPPORT_NCHO + MID_MNY_AIS_NCHO_ACTION_FRAME, +#endif + MID_MNY_P2P_ACS, +#if (CFG_SUPPORT_TWT == 1) + /*--------------------------------------------------*/ + /* TWT Requester Support */ + /*--------------------------------------------------*/ + MID_TWT_REQ_FSM_START, + MID_TWT_REQ_FSM_TEARDOWN, + MID_TWT_REQ_FSM_SUSPEND, + MID_TWT_REQ_FSM_RESUME, + MID_TWT_REQ_IND_RESULT, + MID_TWT_REQ_IND_SUSPEND_DONE, + MID_TWT_REQ_IND_RESUME_DONE, + MID_TWT_REQ_IND_TEARDOWN_DONE, + MID_TWT_REQ_IND_INFOFRM, + MID_TWT_PARAMS_SET, +#endif + MID_TOTAL_NUM +}; + +/* Message header of inter-components */ +struct MSG_HDR { + struct LINK_ENTRY rLinkEntry; + enum ENUM_MSG_ID eMsgId; +}; + +typedef void(*PFN_MSG_HNDL_FUNC) (struct ADAPTER *, + struct MSG_HDR *); + +struct MSG_HNDL_ENTRY { + enum ENUM_MSG_ID eMsgId; + PFN_MSG_HNDL_FUNC pfMsgHndl; +}; + +enum EUNM_MSG_SEND_METHOD { + /* Message is put in the queue and will be */ + MSG_SEND_METHOD_BUF = 0, + /*executed when mailbox is checked. */ + /* The handler function is called immediately */ + MSG_SEND_METHOD_UNBUF + /* in the same context of the sender */ +}; + +enum ENUM_MBOX_ID { + MBOX_ID_0 = 0, + MBOX_ID_TOTAL_NUM +}; + +/* Define Mailbox structure */ +struct MBOX { + struct LINK rLinkHead; +}; + +struct MSG_SAA_FSM_START { + struct MSG_HDR rMsgHdr; /* Must be the first member */ + uint8_t ucSeqNum; + struct STA_RECORD *prStaRec; +}; + +struct MSG_SAA_FSM_COMP { + struct MSG_HDR rMsgHdr; /* Must be the first member */ + uint8_t ucSeqNum; + uint32_t rJoinStatus; + struct STA_RECORD *prStaRec; + struct SW_RFB *prSwRfb; +}; + +struct MSG_SAA_FSM_ABORT { + struct MSG_HDR rMsgHdr; /* Must be the first member */ + uint8_t ucSeqNum; + struct STA_RECORD *prStaRec; +}; + +struct MSG_CONNECTION_ABORT { + struct MSG_HDR rMsgHdr; /* Must be the first member */ + uint8_t ucNetTypeIndex; +}; + +struct MSG_REMAIN_ON_CHANNEL { + struct MSG_HDR rMsgHdr; /* Must be the first member */ + enum ENUM_BAND eBand; + enum ENUM_CHNL_EXT eSco; + uint8_t ucChannelNum; + uint32_t u4DurationMs; + uint64_t u8Cookie; + enum ENUM_CH_REQ_TYPE eReqType; + uint8_t ucBssIdx; +}; + +struct MSG_CANCEL_REMAIN_ON_CHANNEL { + struct MSG_HDR rMsgHdr; /* Must be the first member */ + uint64_t u8Cookie; + uint8_t ucBssIdx; +}; + +struct MSG_MGMT_TX_REQUEST { + struct MSG_HDR rMsgHdr; + uint8_t ucBssIdx; + struct MSDU_INFO *prMgmtMsduInfo; + uint64_t u8Cookie; /* For indication. */ + u_int8_t fgNoneCckRate; + u_int8_t fgIsOffChannel; + struct RF_CHANNEL_INFO rChannelInfo; + enum ENUM_CHNL_EXT eChnlExt; + u_int8_t fgIsWaitRsp; + uint32_t u4Duration; +}; + +#if (CFG_SUPPORT_TWT == 1) +struct _MSG_TWT_REQFSM_START_T { + struct MSG_HDR rMsgHdr; /* Must be the first member */ + struct STA_RECORD *prStaRec; + u_int8_t ucTWTFlowId; +}; + +struct _MSG_TWT_REQFSM_IND_RESULT_T { + struct MSG_HDR rMsgHdr; /* Must be the first member */ + struct STA_RECORD *prStaRec; + u_int8_t ucTWTFlowId; +}; + +struct _MSG_TWT_REQFSM_TEARDOWN_T { + struct MSG_HDR rMsgHdr; /* Must be the first member */ + struct STA_RECORD *prStaRec; + u_int8_t ucTWTFlowId; +}; + +struct _MSG_TWT_REQFSM_SUSPEND_T { + struct MSG_HDR rMsgHdr; /* Must be the first member */ + struct STA_RECORD *prStaRec; + u_int8_t ucTWTFlowId; +}; + +struct _MSG_TWT_REQFSM_RESUME_T { + struct MSG_HDR rMsgHdr; /* Must be the first member */ + struct STA_RECORD *prStaRec; + u_int8_t ucTWTFlowId; + u_int8_t ucNextTWTSize; + u_int64_t u8NextTWT; +}; + +struct _MSG_TWT_REQFSM_IND_INFOFRM_T { + struct MSG_HDR rMsgHdr; /* Must be the first member */ + struct STA_RECORD *prStaRec; + u_int8_t ucTWTFlowId; + struct _NEXT_TWT_INFO_T rNextTWTInfo; +}; + +struct _MSG_TWT_PARAMS_SET_T { + struct MSG_HDR rMsgHdr; /* Must be the first member */ + struct _TWT_CTRL_T rTWTCtrl; +}; +#endif + +struct MSG_CANCEL_TX_WAIT_REQUEST { + struct MSG_HDR rMsgHdr; /* Must be the first member */ + uint64_t u8Cookie; + uint8_t ucBssIdx; +}; + +struct MSG_SAA_FT_CONTINUE { + struct MSG_HDR rMsgHdr; + struct STA_RECORD *prStaRec; + /* if fgFTRicRequest is TRUE, then will do FT Resource + ** Request Protocol + */ + u_int8_t fgFTRicRequest; +}; + +struct MSG_SAA_EXTERNAL_AUTH_DONE { + struct MSG_HDR rMsgHdr; + struct STA_RECORD *prStaRec; + uint16_t status; +}; + +/* specific message data types */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +void mboxSetup(IN struct ADAPTER *prAdapter, + IN enum ENUM_MBOX_ID eMboxId); + +void +mboxSendMsg(IN struct ADAPTER *prAdapter, + IN enum ENUM_MBOX_ID eMboxId, IN struct MSG_HDR *prMsg, + IN enum EUNM_MSG_SEND_METHOD eMethod); + +void mboxRcvAllMsg(IN struct ADAPTER *prAdapter, + IN enum ENUM_MBOX_ID eMboxId); + +void mboxInitialize(IN struct ADAPTER *prAdapter); + +void mboxDestroy(IN struct ADAPTER *prAdapter); + +void mboxDummy(IN struct ADAPTER *prAdapter, + struct MSG_HDR *prMsgHdr); + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#endif /* _HEM_MBOX_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/hs20.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/hs20.h new file mode 100644 index 0000000000000000000000000000000000000000..b3ca798dd4a593321998795b57598cbb764ddb40 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/hs20.h @@ -0,0 +1,200 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ + +/*! \file hs20.h + * \brief This file contains the function declaration for hs20.c. + */ + +#ifndef _HS20_H +#define _HS20_H + +#if CFG_SUPPORT_PASSPOINT +/****************************************************************************** + * C O M P I L E R F L A G S + ****************************************************************************** + */ + +/****************************************************************************** + * E X T E R N A L R E F E R E N C E S + ****************************************************************************** + */ + +/****************************************************************************** + * C O N S T A N T S + ****************************************************************************** + */ +#define BSSID_POOL_MAX_SIZE 8 +#define HS20_SIGMA_SCAN_RESULT_TIMEOUT 30 /* sec */ + +/****************************************************************************** + * D A T A T Y P E S + ****************************************************************************** + */ + +#if CFG_ENABLE_GTK_FRAME_FILTER +/*For GTK Frame Filter*/ +struct IPV4_NETWORK_ADDRESS_LIST { + uint8_t ucAddrCount; + struct CMD_IPV4_NETWORK_ADDRESS arNetAddr[1]; +}; +#endif + +/* Entry of BSSID Pool - For SIGMA Test */ +struct BSSID_ENTRY { + uint8_t aucBSSID[MAC_ADDR_LEN]; +}; + +struct HS20_INFO { + /*Hotspot 2.0 Information */ + uint8_t aucHESSID[MAC_ADDR_LEN]; + uint8_t ucAccessNetworkOptions; + uint8_t ucVenueGroup; /* VenueInfo - Group */ + uint8_t ucVenueType; + uint8_t ucHotspotConfig; + + /*Roaming Consortium Information */ + /* PARAM_HS20_ROAMING_CONSORTIUM_INFO rRCInfo; */ + + /*Hotspot 2.0 dummy AP Info */ + + /*Time Advertisement Information */ + /* UINT_32 u4UTCOffsetTime; */ + /* UINT_8 aucTimeZone[ELEM_MAX_LEN_TIME_ZONE]; */ + /* UINT_8 ucLenTimeZone; */ + + /* For SIGMA Test */ + /* BSSID Pool */ + struct BSSID_ENTRY arBssidPool[BSSID_POOL_MAX_SIZE]; + uint8_t ucNumBssidPoolEntry; + u_int8_t fgIsHS2SigmaMode; + + uint8_t ucHotspotConfig; + u_int8_t fgConnectHS20AP; + +}; + +/****************************************************************************** + * P U B L I C D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * P R I V A T E D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * M A C R O S + ****************************************************************************** + */ + +/*For GTK Frame Filter*/ +#if DBG +#define FREE_IPV4_NETWORK_ADDR_LIST(_prAddrList) \ + { \ + uint32_t u4Size = \ + OFFSET_OF(struct IPV4_NETWORK_ADDRESS_LIST, \ + arNetAddr) + \ + (((_prAddrList)->ucAddrCount) * \ + sizeof(struct CMD_IPV4_NETWORK_ADDRESS)); \ + kalMemFree((_prAddrList), VIR_MEM_TYPE, u4Size); \ + (_prAddrList) = NULL; \ + } +#else +#define FREE_IPV4_NETWORK_ADDR_LIST(_prAddrList) \ + { \ + kalMemFree((_prAddrList), VIR_MEM_TYPE, 0); \ + (_prAddrList) = NULL; \ + } +#endif + +/****************************************************************************** + * F U N C T I O N S + ****************************************************************************** + */ + +void hs20FillExtCapIE(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, struct MSDU_INFO *prMsduInfo); + +void hs20FillProreqExtCapIE(IN struct ADAPTER *prAdapter, OUT uint8_t *pucIE); + +void hs20FillHS20IE(IN struct ADAPTER *prAdapter, OUT uint8_t *pucIE); + +uint32_t hs20CalculateHS20RelatedIEForProbeReq(IN struct ADAPTER *prAdapter, + IN uint8_t *pucTargetBSSID); + +uint32_t hs20GenerateHS20RelatedIEForProbeReq(IN struct ADAPTER *prAdapter, + IN uint8_t *pucTargetBSSID, OUT uint8_t *prIE); + +u_int8_t hs20IsGratuitousArp(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prCurrSwRfb); + +u_int8_t hs20IsUnsolicitedNeighborAdv(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prCurrSwRfb); + +#if CFG_ENABLE_GTK_FRAME_FILTER +u_int8_t hs20IsForgedGTKFrame(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo, IN struct SW_RFB *prCurrSwRfb); +#endif + +u_int8_t hs20IsUnsecuredFrame(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo, IN struct SW_RFB *prCurrSwRfb); + +u_int8_t hs20IsFrameFilterEnabled(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo); + +uint32_t hs20SetBssidPool(IN struct ADAPTER *prAdapter, + IN void *pvBuffer, + IN uint8_t ucBssIndex); + +#endif /* CFG_SUPPORT_PASSPOINT */ +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/mddp.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/mddp.h new file mode 100644 index 0000000000000000000000000000000000000000..c64bba2ffa57ad33beec9ce4f1b52e7c34144bf9 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/mddp.h @@ -0,0 +1,87 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +/* + ** Id: //Department/DaVinci/BRANCHES/ + * MT6620_WIFI_DRIVER_V2_3/include/mgmt/mddp.h#1 + */ + +/*! \file "mddp.h" + * \brief The declaration of nic functions + * + * Detail description. + */ + + +#ifndef _MDDP_H +#define _MDDP_H + +#if CFG_MTK_MCIF_WIFI_SUPPORT + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "mddp_export.h" +#include "mddp.h" +#include "mt-plat/mtk_ccci_common.h" +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +void mddpInit(void); +int32_t mddpMdNotifyInfo(struct mddpw_md_notify_info_t *prMdInfo); +int32_t mddpChangeState(enum mddp_state_e event, void *buf, uint32_t *buf_len); +int32_t mddpGetMdStats(IN struct net_device *prDev); +int32_t mddpSetTxDescTemplate(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, + IN uint8_t fgActivate); +void mddpUpdateReorderQueParm(struct ADAPTER *prAdapter, + struct RX_BA_ENTRY *prReorderQueParm, + struct SW_RFB *prSwRfb); +int32_t mddpNotifyDrvMac(IN struct ADAPTER *prAdapter); +int32_t mddpNotifyDrvTxd(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, + IN uint8_t fgActivate); +int32_t mddpNotifyStaTxd(IN struct ADAPTER *prAdapter); +void mddpNotifyWifiOnStart(void); +int32_t mddpNotifyWifiOnEnd(void); +void mddpNotifyWifiOffStart(void); +void mddpNotifyWifiOffEnd(void); +void setMddpSupportRegister(IN struct ADAPTER *prAdapter); +void mddpMdStateChangedCb(enum MD_STATE old_state, + enum MD_STATE new_state); + +#endif +#endif /* _MDDP_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/mib.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/mib.h new file mode 100644 index 0000000000000000000000000000000000000000..9c7b5513fc58ed340ba66103cf0cd8e47f50a8b9 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/mib.h @@ -0,0 +1,189 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/ + * include/mgmt/mib.h#1 + */ + +/*! \file mib.h + * \brief This file contains the IEEE 802.11 family related MIB definition + * for MediaTek 802.11 Wireless LAN Adapters. + */ + + +#ifndef _MIB_H +#define _MIB_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +/* Entry in SMT AuthenticationAlgorithms Table: + * dot11AuthenticationAlgorithmsEntry + */ +struct DOT11_AUTHENTICATION_ALGORITHMS_ENTRY { + /* dot11AuthenticationAlgorithmsEntry 3 */ + u_int8_t dot11AuthenticationAlgorithmsEnable; +}; + +/* Entry in SMT dot11RSNAConfigPairwiseCiphersTalbe Table: + * dot11RSNAConfigPairwiseCiphersEntry + */ +struct DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY { + /* dot11RSNAConfigPairwiseCiphersEntry 2 */ + uint32_t dot11RSNAConfigPairwiseCipher; + /* dot11RSNAConfigPairwiseCiphersEntry 3 */ + u_int8_t dot11RSNAConfigPairwiseCipherEnabled; +}; + +/* Entry in SMT dot11RSNAConfigAuthenticationSuitesTalbe Table: + * dot11RSNAConfigAuthenticationSuitesEntry + */ +struct DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY { + /* dot11RSNAConfigAuthenticationSuitesEntry 2 */ + uint32_t dot11RSNAConfigAuthenticationSuite; + /* dot11RSNAConfigAuthenticationSuitesEntry 3 */ + u_int8_t dot11RSNAConfigAuthenticationSuiteEnabled; +}; + +/* ----- IEEE 802.11 MIB Major sections ----- */ +struct IEEE_802_11_MIB { + /* dot11PrivacyTable (dot11smt 5) */ + uint8_t dot11WEPDefaultKeyID; /* dot11PrivacyEntry 2 */ + u_int8_t dot11TranmitKeyAvailable; + uint32_t dot11WEPICVErrorCount; /* dot11PrivacyEntry 5 */ + uint32_t dot11WEPExcludedCount; /* dot11PrivacyEntry 6 */ + + /* dot11RSNAConfigTable (dot11smt 8) */ + uint32_t dot11RSNAConfigGroupCipher; /* dot11RSNAConfigEntry 4 */ + + /* dot11RSNAConfigPairwiseCiphersTable (dot11smt 9) */ + struct DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY + dot11RSNAConfigPairwiseCiphersTable[MAX_NUM_SUPPORTED_CIPHER_SUITES]; + + /* dot11RSNAConfigAuthenticationSuitesTable (dot11smt 10) */ + struct DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY + dot11RSNAConfigAuthenticationSuitesTable[MAX_NUM_SUPPORTED_AKM_SUITES]; + +#if 0 /* SUPPORT_WAPI */ + u_int8_t fgWapiKeyInstalled; + struct PARAM_WPI_KEY rWapiPairwiseKey[2]; + u_int8_t fgPairwiseKeyUsed[2]; + uint8_t ucWpiActivedPWKey; /* Must be 0 or 1, by wapi spec */ + struct PARAM_WPI_KEY rWapiGroupKey[2]; + u_int8_t fgGroupKeyUsed[2]; +#endif +}; + +/* ------------------ IEEE 802.11 non HT PHY characteristics ---------------- */ +struct NON_HT_PHY_ATTRIBUTE { + uint16_t u2SupportedRateSet; + + u_int8_t fgIsShortPreambleOptionImplemented; + + u_int8_t fgIsShortSlotTimeOptionImplemented; +}; + +struct NON_HT_ATTRIBUTE { + enum ENUM_PHY_TYPE_INDEX ePhyTypeIndex; + + uint16_t u2BSSBasicRateSet; +}; + + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ +extern const struct NON_HT_PHY_ATTRIBUTE + rNonHTPhyAttributes[]; +extern const struct NON_HT_ATTRIBUTE + rNonHTAdHocModeAttributes[]; +extern const struct NON_HT_ATTRIBUTE + rNonHTApModeAttributes[]; + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#endif /* _MIB_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/p2p_assoc.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/p2p_assoc.h new file mode 100644 index 0000000000000000000000000000000000000000..da5c3286538bd5ed501cbb9f1563fb5ecc3c7fdb --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/p2p_assoc.h @@ -0,0 +1,104 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ + +/*! \file p2p_assoc.h + * \brief This file contains the Wi-Fi Direct ASSOC REQ/RESP of + * IEEE 802.11 family for MediaTek 802.11 Wireless LAN Adapters. + */ + +#ifndef _P2P_ASSOC_H +#define _P2P_ASSOC_H + +/****************************************************************************** + * C O M P I L E R F L A G S + ****************************************************************************** + */ + +/****************************************************************************** + * E X T E R N A L R E F E R E N C E S + ****************************************************************************** + */ + +/****************************************************************************** + * C O N S T A N T S + ****************************************************************************** + */ + +/****************************************************************************** + * M A C R O S + ****************************************************************************** + */ + +/****************************************************************************** + * D A T A T Y P E S + ****************************************************************************** + */ + +/****************************************************************************** + * P U B L I C D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * P R I V A T E D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N D E C L A R A T I O N S + ****************************************************************************** + */ + +uint8_t *p2pBuildReAssocReqFrameCommonIEs(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, IN uint8_t *pucBuffer); + +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/p2p_bss.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/p2p_bss.h new file mode 100644 index 0000000000000000000000000000000000000000..75704fc7d92660602603c5ac774b59d1c691f093 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/p2p_bss.h @@ -0,0 +1,109 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/mgmt/p2p_bss.h#2 + */ + +/*! \file "p2p_bss.h" + * \brief In this file we define the function prototype used + * in p2p BSS/IBSS. + * + * The file contains the function declarations and defines + * for used in BSS/IBSS. + */ + +#ifndef _P2P_BSS_H +#define _P2P_BSS_H + +/****************************************************************************** + * C O M P I L E R F L A G S + ****************************************************************************** + */ + +/****************************************************************************** + * E X T E R N A L R E F E R E N C E S + ****************************************************************************** + */ + +/****************************************************************************** + * C O N S T A N T S + ****************************************************************************** + */ + +/****************************************************************************** + * M A C R O S + ****************************************************************************** + */ + +/****************************************************************************** + * D A T A T Y P E S + ****************************************************************************** + */ + +/****************************************************************************** + * P U B L I C D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * P R I V A T E D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N D E C L A R A T I O N S + ****************************************************************************** + */ + +uint32_t p2pGetTxProbRspIeTableSize(void); + +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/p2p_dev.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/p2p_dev.h new file mode 100644 index 0000000000000000000000000000000000000000..0ebbd7e50d77bfcd05e73eba5b16beb272dfa57d --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/p2p_dev.h @@ -0,0 +1,270 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +enum ENUM_P2P_DEV_STATE { + P2P_DEV_STATE_IDLE = 0, + P2P_DEV_STATE_SCAN, + P2P_DEV_STATE_REQING_CHANNEL, + P2P_DEV_STATE_CHNL_ON_HAND, + P2P_DEV_STATE_OFF_CHNL_TX, + /* Requesting Channel to Send Specific Frame. */ + P2P_DEV_STATE_NUM +}; + +/*-------------------- EVENT MESSAGE ---------------------*/ +struct MSG_P2P_SCAN_REQUEST { + struct MSG_HDR rMsgHdr; /* Must be the first member */ + uint8_t ucBssIdx; + enum ENUM_SCAN_TYPE eScanType; + struct P2P_SSID_STRUCT *prSSID; + int32_t i4SsidNum; + uint32_t u4NumChannel; + uint8_t *pucIEBuf; + uint32_t u4IELen; + u_int8_t fgIsAbort; + enum ENUM_SCAN_REASON eScanReason; + struct RF_CHANNEL_INFO arChannelListInfo[1]; +}; + +struct MSG_P2P_CHNL_REQUEST { + struct MSG_HDR rMsgHdr; /* Must be the first member */ + uint64_t u8Cookie; + uint32_t u4Duration; + enum ENUM_CHNL_EXT eChnlSco; + struct RF_CHANNEL_INFO rChannelInfo; + enum ENUM_CH_REQ_TYPE eChnlReqType; +}; + +#define P2P_DEV_EXTEND_CHAN_TIME 500 + +#if CFG_SUPPORT_WFD + +#define WFD_FLAGS_DEV_INFO_VALID BIT(0) +/* 1. WFD_DEV_INFO, 2. WFD_CTRL_PORT, 3. WFD_MAT_TP. */ +#define WFD_FLAGS_SINK_INFO_VALID BIT(1) +/* 1. WFD_SINK_STATUS, 2. WFD_SINK_MAC. */ +#define WFD_FLAGS_ASSOC_MAC_VALID BIT(2) +/* 1. WFD_ASSOC_MAC. */ +#define WFD_FLAGS_EXT_CAPABILITY_VALID BIT(3) +/* 1. WFD_EXTEND_CAPABILITY. */ + +struct WFD_CFG_SETTINGS { + uint32_t u4WfdCmdType; + uint8_t ucWfdEnable; + uint8_t ucWfdCoupleSinkStatus; + uint8_t ucWfdSessionAvailable; /* 0: NA 1:Set 2:Clear */ + uint8_t ucWfdSigmaMode; + uint16_t u2WfdDevInfo; + uint16_t u2WfdControlPort; + uint16_t u2WfdMaximumTp; + uint16_t u2WfdExtendCap; + uint8_t aucWfdCoupleSinkAddress[MAC_ADDR_LEN]; + uint8_t aucWfdAssociatedBssid[MAC_ADDR_LEN]; + uint8_t aucWfdVideoIp[4]; + uint8_t aucWfdAudioIp[4]; + uint16_t u2WfdVideoPort; + uint16_t u2WfdAudioPort; + uint32_t u4WfdFlag; + uint32_t u4WfdPolicy; + uint32_t u4WfdState; + uint8_t aucWfdSessionInformationIE[24 * 8]; + uint16_t u2WfdSessionInformationIELen; + uint8_t aucReserved1[2]; + uint8_t aucWfdPrimarySinkMac[MAC_ADDR_LEN]; + uint8_t aucWfdSecondarySinkMac[MAC_ADDR_LEN]; + uint32_t u4WfdAdvancedFlag; + /* Group 1 64 bytes */ + uint8_t aucWfdLocalIp[4]; + uint16_t u2WfdLifetimeAc2; /* Unit is 2 TU */ + uint16_t u2WfdLifetimeAc3; /* Unit is 2 TU */ + uint16_t u2WfdCounterThreshold; /* Unit is ms */ + uint8_t aucReverved2[54]; + /* Group 2 64 bytes */ + uint8_t aucReverved3[64]; + /* Group 3 64 bytes */ + uint8_t aucReverved4[64]; + uint32_t u4LinkScore; +}; + +#endif + +struct MSG_P2P_ACTIVE_DEV_BSS { + struct MSG_HDR rMsgHdr; +}; + +/*-------------------- P2P FSM ACTION STRUCT ---------------------*/ + +struct P2P_OFF_CHNL_TX_REQ_INFO { + struct LINK_ENTRY rLinkEntry; + struct MSDU_INFO *prMgmtTxMsdu; + u_int8_t fgNoneCckRate; + struct RF_CHANNEL_INFO rChannelInfo; /* Off channel TX. */ + enum ENUM_CHNL_EXT eChnlExt; + /* See if driver should keep at the same channel. */ + u_int8_t fgIsWaitRsp; + uint64_t u8Cookie; /* cookie used to match with supplicant */ + uint32_t u4Duration; /* wait time for tx request */ + uint8_t ucBssIndex; +}; + +struct P2P_DEV_FSM_INFO { + uint8_t ucBssIndex; + /* State related. */ + enum ENUM_P2P_DEV_STATE eCurrentState; + + /* Channel related. */ + struct P2P_CHNL_REQ_INFO rChnlReqInfo; + + /* Scan related. */ + struct P2P_SCAN_REQ_INFO rScanReqInfo; + + /* Mgmt tx related. */ + struct P2P_MGMT_TX_REQ_INFO rMgmtTxInfo; + + /* FSM Timer */ + struct TIMER rP2pFsmTimeoutTimer; + + /* Packet filter for P2P module. */ + uint32_t u4P2pPacketFilter; + + /* Queued p2p action frame */ + struct P2P_QUEUED_ACTION_FRAME rQueuedActionFrame; +}; + +struct MSG_P2P_NETDEV_REGISTER { + struct MSG_HDR rMsgHdr; /* Must be the first member */ + u_int8_t fgIsEnable; + uint8_t ucMode; +}; + +#if CFG_SUPPORT_WFD +struct MSG_WFD_CONFIG_SETTINGS_CHANGED { + struct MSG_HDR rMsgHdr; /* Must be the first member */ + struct WFD_CFG_SETTINGS *prWfdCfgSettings; +}; +#endif + +struct MSG_P2P_ACS_REQUEST { + struct MSG_HDR rMsgHdr; /* Must be the first member */ + uint8_t ucRoleIdx; + u_int8_t fgIsHtEnable; + u_int8_t fgIsHt40Enable; + u_int8_t fgIsVhtEnable; + enum ENUM_MAX_BANDWIDTH_SETTING eChnlBw; + enum P2P_VENDOR_ACS_HW_MODE eHwMode; + uint32_t u4NumChannel; + struct RF_CHANNEL_INFO arChannelListInfo[1]; +}; + +/*========================= Initial ============================*/ + +uint8_t p2pDevFsmInit(IN struct ADAPTER *prAdapter); + +void p2pDevFsmUninit(IN struct ADAPTER *prAdapter); + +/*========================= FUNCTIONs ============================*/ + +void +p2pDevFsmStateTransition(IN struct ADAPTER *prAdapter, + IN struct P2P_DEV_FSM_INFO *prP2pDevFsmInfo, + IN enum ENUM_P2P_DEV_STATE eNextState); + +void p2pDevFsmRunEventAbort(IN struct ADAPTER *prAdapter, + IN struct P2P_DEV_FSM_INFO *prP2pDevFsmInfo); + +void p2pDevFsmRunEventTimeout(IN struct ADAPTER *prAdapter, + IN unsigned long ulParamPtr); + +/*================ Message Event =================*/ +void p2pDevFsmRunEventScanRequest(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); +void p2pDevFsmRunEventScanAbort(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIdx); + +void +p2pDevFsmRunEventScanDone(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr, + IN struct P2P_DEV_FSM_INFO *prP2pDevFsmInfo); + +void p2pDevFsmRunEventChannelRequest(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); + +void p2pDevFsmRunEventChannelAbort(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); + +void +p2pDevFsmRunEventChnlGrant(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr, + IN struct P2P_DEV_FSM_INFO *prP2pDevFsmInfo); + +void p2pDevFsmRunEventMgmtTx(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); + +uint32_t +p2pDevFsmRunEventMgmtFrameTxDone(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN enum ENUM_TX_RESULT_CODE rTxDoneStatus); + +void p2pDevFsmRunEventMgmtFrameRegister(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); + +/* /////////////////////////////// */ + +void p2pDevFsmRunEventActiveDevBss(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); + +void +p2pDevFsmNotifyP2pRx(IN struct ADAPTER *prAdapter, uint8_t p2pFrameType, + u_int8_t *prFgBufferFrame); + +void p2pDevFsmRunEventTxCancelWait(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/p2p_dev_state.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/p2p_dev_state.h new file mode 100644 index 0000000000000000000000000000000000000000..868e5d3fec75c0355d64b90e520c65f33ca72cee --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/p2p_dev_state.h @@ -0,0 +1,107 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +#ifndef _P2P_DEV_STATE_H +#define _P2P_DEV_STATE_H + +u_int8_t +p2pDevStateInit_IDLE(IN struct ADAPTER *prAdapter, + IN struct P2P_CHNL_REQ_INFO *prChnlReqInfo, + OUT enum ENUM_P2P_DEV_STATE *peNextState); + +void p2pDevStateAbort_IDLE(IN struct ADAPTER *prAdapter); + +u_int8_t +p2pDevStateInit_REQING_CHANNEL(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIdx, + IN struct P2P_CHNL_REQ_INFO *prChnlReqInfo, + OUT enum ENUM_P2P_DEV_STATE *peNextState); + +void +p2pDevStateAbort_REQING_CHANNEL(IN struct ADAPTER *prAdapter, + IN struct P2P_CHNL_REQ_INFO *prChnlReqInfo, + IN enum ENUM_P2P_DEV_STATE eNextState); + +void +p2pDevStateInit_CHNL_ON_HAND(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prP2pBssInfo, + IN struct P2P_DEV_FSM_INFO *prP2pDevFsmInfo, + IN struct P2P_CHNL_REQ_INFO *prChnlReqInfo); + +void +p2pDevStateAbort_CHNL_ON_HAND(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prP2pBssInfo, + IN struct P2P_DEV_FSM_INFO *prP2pDevFsmInfo, + IN struct P2P_CHNL_REQ_INFO *prChnlReqInfo, + IN enum ENUM_P2P_DEV_STATE eNextState); + +void p2pDevStateInit_SCAN(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN struct P2P_SCAN_REQ_INFO *prScanReqInfo); + +void p2pDevStateAbort_SCAN(IN struct ADAPTER *prAdapter, + IN struct P2P_DEV_FSM_INFO *prP2pDevFsmInfo); + +u_int8_t +p2pDevStateInit_OFF_CHNL_TX(IN struct ADAPTER *prAdapter, + IN struct P2P_DEV_FSM_INFO *prP2pDevFsmInfo, + IN struct P2P_CHNL_REQ_INFO *prChnlReqInfo, + IN struct P2P_MGMT_TX_REQ_INFO *prP2pMgmtTxInfo, + OUT enum ENUM_P2P_DEV_STATE *peNextState); + +void +p2pDevStateAbort_OFF_CHNL_TX(IN struct ADAPTER *prAdapter, + IN struct P2P_DEV_FSM_INFO *prP2pDevFsmInfo, + IN struct P2P_MGMT_TX_REQ_INFO *prP2pMgmtTxInfo, + IN struct P2P_CHNL_REQ_INFO *prChnlReqInfo, + IN enum ENUM_P2P_DEV_STATE eNextState); + +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/p2p_fsm.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/p2p_fsm.h new file mode 100644 index 0000000000000000000000000000000000000000..8b8b091a299061c41246beaf892cb54b433c5cae --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/p2p_fsm.h @@ -0,0 +1,92 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/mgmt/p2p_fsm.h#23 + */ + +/*! \file p2p_fsm.h + * \brief Declaration of functions and finite state machine for P2P Module. + * + * Declaration of functions and finite state machine for P2P Module. + */ + + +#ifndef _P2P_FSM_H +#define _P2P_FSM_H + +void p2pFsmRunEventScanRequest(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); + +void p2pFsmRunEventChGrant(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); + +void p2pFsmRunEventNetDeviceRegister(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); + +void p2pFsmRunEventUpdateMgmtFrame(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); + +#if CFG_SUPPORT_WFD +void p2pFsmRunEventWfdSettingUpdate(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); +#endif + +void p2pFsmRunEventScanDone(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); + +void p2pFsmRunEventMgmtFrameTx(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); + +void p2pFsmRunEventTxCancelWait(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); + +#endif /* _P2P_FSM_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/p2p_func.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/p2p_func.h new file mode 100644 index 0000000000000000000000000000000000000000..b387e961a71b96472a14e9ac7116c6c5e285b7ad --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/p2p_func.h @@ -0,0 +1,490 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +#ifndef _P2P_FUNC_H +#define _P2P_FUNC_H + +#define P2P_OFF_CHNL_TX_DEFAULT_TIME_MS 1000 + +#if (CFG_SUPPORT_DFS_MASTER == 1) +extern struct P2P_RADAR_INFO g_rP2pRadarInfo; + +enum _ENUM_DFS_STATE_T { + DFS_STATE_INACTIVE = 0, + DFS_STATE_CHECKING, + DFS_STATE_ACTIVE, + DFS_STATE_DETECTED, + DFS_STATE_NUM +}; +#endif + +/****************************************************************************** + * M A C R O S + ****************************************************************************** + */ +#define ATTRI_ID(_fp) (((struct P2P_ATTRIBUTE *)_fp)->ucId) +#define ATTRI_LEN(_fp) \ +(((uint16_t)((uint8_t *)&((struct P2P_ATTRIBUTE *)_fp)->u2Length)[0]) | \ +((uint16_t)((uint8_t *)&((struct P2P_ATTRIBUTE *)_fp)->u2Length)[1] << 8)) + +#define ATTRI_SIZE(_fp) (P2P_ATTRI_HDR_LEN + ATTRI_LEN(_fp)) + +#define P2P_ATTRI_FOR_EACH(_pucAttriBuf, _u2AttriBufLen, _u2Offset) \ + for ((_u2Offset) = 0; ((_u2Offset) < (_u2AttriBufLen)); \ + (_u2Offset) += ATTRI_SIZE(_pucAttriBuf), \ + ((_pucAttriBuf) += ATTRI_SIZE(_pucAttriBuf))) + +#define P2P_IE(_fp) ((struct IE_P2P *)_fp) + +#define WSC_ATTRI_ID(_fp) \ +(((uint16_t)((uint8_t *)&((struct WSC_ATTRIBUTE *)_fp)->u2Id)[0] << 8) | \ +((uint16_t)((uint8_t *)&((struct WSC_ATTRIBUTE *)_fp)->u2Id)[1])) + +#define WSC_ATTRI_LEN(_fp) \ +(((uint16_t)((uint8_t *)&((struct WSC_ATTRIBUTE *)_fp)->u2Length)[0] << 8) | \ +((uint16_t)((uint8_t *)&((struct WSC_ATTRIBUTE *)_fp)->u2Length)[1])) + +#define WSC_ATTRI_SIZE(_fp) (WSC_ATTRI_HDR_LEN + WSC_ATTRI_LEN(_fp)) + +#define WSC_ATTRI_FOR_EACH(_pucAttriBuf, _u2AttriBufLen, _u2Offset) \ + for ((_u2Offset) = 0; ((_u2Offset) < (_u2AttriBufLen)); \ + (_u2Offset) += WSC_ATTRI_SIZE(_pucAttriBuf), \ + ((_pucAttriBuf) += WSC_ATTRI_SIZE(_pucAttriBuf))) + +#define WSC_IE(_fp) ((struct IE_P2P *)_fp) + +#define WFD_ATTRI_SIZE(_fp) (P2P_ATTRI_HDR_LEN + WSC_ATTRI_LEN(_fp)) + +#define WFD_ATTRI_FOR_EACH(_pucAttriBuf, _u2AttriBufLen, _u2Offset) \ + for ((_u2Offset) = 0; ((_u2Offset) < (_u2AttriBufLen)); \ + (_u2Offset) += WFD_ATTRI_SIZE(_pucAttriBuf), \ + ((_pucAttriBuf) += WFD_ATTRI_SIZE(_pucAttriBuf))) + +/****************************************************************************** + * F U N C T I O N D E C L A R A T I O N S + ****************************************************************************** + */ + +void p2pFuncRequestScan(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN struct P2P_SCAN_REQ_INFO *prScanReqInfo); + +void p2pFuncCancelScan(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN struct P2P_SCAN_REQ_INFO *prScanReqInfo); + +void +p2pFuncUpdateBssInfoForJOIN(IN struct ADAPTER *prAdapter, + IN struct BSS_DESC *prBssDesc, + IN struct STA_RECORD *prStaRec, + IN struct BSS_INFO *prP2pBssInfo, + IN struct SW_RFB *prAssocRspSwRfb); + +void p2pFuncAcquireCh(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIdx, + IN struct P2P_CHNL_REQ_INFO *prChnlReqInfo); + +void +p2pFuncDisconnect(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prP2pBssInfo, + IN struct STA_RECORD *prStaRec, + IN u_int8_t fgSendDeauth, + IN uint16_t u2ReasonCode); + +struct BSS_INFO *p2pFuncBSSIDFindBssInfo(IN struct ADAPTER *prAdapter, + IN uint8_t *pucBSSID); + +void p2pFuncGCJoin(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prP2pBssInfo, + IN struct P2P_JOIN_INFO *prP2pJoinInfo); + +void p2pFuncStopComplete(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prP2pBssInfo); + +void +p2pFuncStartGO(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo, + IN struct P2P_CONNECTION_REQ_INFO *prP2pConnReqInfo, + IN struct P2P_CHNL_REQ_INFO *prP2pChnlReqInfo); + +void p2pFuncStopGO(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prP2pBssInfo); + +uint32_t p2pFuncRoleToBssIdx(IN struct ADAPTER *prAdapter, + IN uint8_t ucRoleIdx, + OUT uint8_t *pucBssIdx); + +struct P2P_ROLE_FSM_INFO *p2pFuncGetRoleByBssIdx(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +void +p2pFuncSwitchOPMode(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prP2pBssInfo, + IN enum ENUM_OP_MODE eOpMode, + IN u_int8_t fgSyncToFW); + +void p2pFuncReleaseCh(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIdx, + IN struct P2P_CHNL_REQ_INFO *prChnlReqInfo); + +#if (CFG_SUPPORT_DFS_MASTER == 1) +void p2pFuncStartRdd(IN struct ADAPTER *prAdapter, IN uint8_t ucBssIdx); + +void p2pFuncStopRdd(IN struct ADAPTER *prAdapter, IN uint8_t ucBssIdx); + +void p2pFuncDfsSwitchCh(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo, + IN struct P2P_CHNL_REQ_INFO rP2pChnlReqInfo); + +u_int8_t p2pFuncCheckWeatherRadarBand( + IN struct P2P_CHNL_REQ_INFO *prChnlReqInfo); + +int32_t p2pFuncSetDriverCacTime(IN uint32_t u4CacTime); + +void p2pFuncEnableManualCac(void); + +uint32_t p2pFuncGetDriverCacTime(void); + +u_int8_t p2pFuncIsManualCac(void); + +void p2pFuncRadarInfoInit(void); + +void p2pFuncShowRadarInfo(IN struct ADAPTER *prAdapter, IN uint8_t ucBssIdx); + +void p2pFuncGetRadarInfo(IN struct P2P_RADAR_INFO *prP2pRadarInfo); + +uint8_t *p2pFuncJpW53RadarType(void); + +uint8_t *p2pFuncJpW56RadarType(void); + +void p2pFuncSetRadarDetectMode(IN uint8_t ucRadarDetectMode); + +uint8_t p2pFuncGetRadarDetectMode(void); + +void p2pFuncSetDfsState(IN uint8_t ucDfsState); + +uint8_t p2pFuncGetDfsState(void); + +uint8_t *p2pFuncShowDfsState(void); + +void p2pFuncRecordCacStartBootTime(void); + +uint32_t p2pFuncGetCacRemainingTime(void); +#endif + +void p2pFuncSetChannel(IN struct ADAPTER *prAdapter, + IN uint8_t ucRoleIdx, + IN struct RF_CHANNEL_INFO *prRfChannelInfo); + +u_int8_t p2pFuncRetryJOIN(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, + IN struct P2P_JOIN_INFO *prJoinInfo); + +uint32_t +p2pFuncTxMgmtFrame(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN struct MSDU_INFO *prMgmtTxMsdu, + IN u_int8_t fgNonCckRate); + +uint32_t +p2pFuncBeaconUpdate(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prP2pBssInfo, + IN struct P2P_BEACON_UPDATE_INFO *prBcnUpdateInfo, + IN uint8_t *pucNewBcnHdr, + IN uint32_t u4NewHdrLen, + IN uint8_t *pucNewBcnBody, + IN uint32_t u4NewBodyLen); + +uint32_t +p2pFuncAssocRespUpdate(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prP2pBssInfo, + IN uint8_t *AssocRespIE, + IN uint32_t u4AssocRespLen); + +#if CFG_SUPPORT_P2P_GO_OFFLOAD_PROBE_RSP +uint32_t +p2pFuncProbeRespUpdate(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prP2pBssInfo, + IN uint8_t *ProbeRespIE, IN uint32_t u4ProbeRespLen); +#endif + +u_int8_t +p2pFuncValidateAuth(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo, IN struct SW_RFB *prSwRfb, + IN struct STA_RECORD **pprStaRec, OUT uint16_t *pu2StatusCode); + +u_int8_t p2pFuncValidateAssocReq(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, OUT uint16_t *pu2StatusCode); + +void p2pFuncResetStaRecStatus(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec); + +void +p2pFuncInitConnectionSettings(IN struct ADAPTER *prAdapter, + IN struct P2P_CONNECTION_SETTINGS *prP2PConnSettings, + IN u_int8_t fgIsApMode); + +u_int8_t p2pFuncParseCheckForP2PInfoElem(IN struct ADAPTER *prAdapter, + IN uint8_t *pucBuf, OUT uint8_t *pucOuiType); + +u_int8_t p2pFuncParseCheckForTKIPInfoElem(IN uint8_t *pucBuf); + +u_int8_t +p2pFuncValidateProbeReq(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, OUT uint32_t *pu4ControlFlags, + IN u_int8_t fgIsDevInterface, IN uint8_t ucRoleIdx); + +void p2pFuncValidateRxActionFrame(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, + IN u_int8_t fgIsDevInterface, IN uint8_t ucRoleIdx); + +u_int8_t p2pFuncIsAPMode(IN struct P2P_CONNECTION_SETTINGS *prP2pConnSettings); + +void +p2pFuncParseBeaconContent(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prP2pBssInfo, + IN uint8_t *pucIEInfo, IN uint32_t u4IELen); + +struct BSS_DESC * +p2pFuncKeepOnConnection(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo, + IN struct P2P_CONNECTION_REQ_INFO *prConnReqInfo, + IN struct P2P_CHNL_REQ_INFO *prChnlReqInfo, + IN struct P2P_SCAN_REQ_INFO *prScanReqInfo); + +void p2pFuncStoreAssocRspIEBuffer(IN struct ADAPTER *prAdapter, + IN struct P2P_JOIN_INFO *prP2pJoinInfo, + IN struct SW_RFB *prSwRfb); + +void +p2pFuncMgmtFrameRegister(IN struct ADAPTER *prAdapter, + IN uint16_t u2FrameType, + IN u_int8_t fgIsRegistered, + OUT uint32_t *pu4P2pPacketFilter); + +void p2pFuncUpdateMgmtFrameRegister(IN struct ADAPTER *prAdapter, + IN uint32_t u4OsFilter); + +void p2pFuncGetStationInfo(IN struct ADAPTER *prAdapter, + IN uint8_t *pucMacAddr, + OUT struct P2P_STATION_INFO *prStaInfo); + +struct MSDU_INFO *p2pFuncProcessP2pProbeRsp(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIdx, IN struct MSDU_INFO *prMgmtTxMsdu); + +#if 0 /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) */ +uint32_t +p2pFuncCalculateExtra_IELenForBeacon(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, IN struct STA_RECORD *prStaRec); + +void p2pFuncGenerateExtra_IEForBeacon(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo); + +#else +uint32_t p2pFuncCalculateP2p_IELenForBeacon(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, IN struct STA_RECORD *prStaRec); + +void p2pFuncGenerateP2p_IEForBeacon(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo); + +uint32_t p2pFuncCalculateWSC_IELenForBeacon(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, IN struct STA_RECORD *prStaRec); + +void p2pFuncGenerateWSC_IEForBeacon(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo); +#endif +uint32_t +p2pFuncCalculateP2p_IELenForAssocRsp(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, IN struct STA_RECORD *prStaRec); + +void p2pFuncGenerateP2p_IEForAssocRsp(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo); + +uint32_t +p2pFuncCalculateP2P_IELen(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN struct STA_RECORD *prStaRec, + IN struct APPEND_VAR_ATTRI_ENTRY arAppendAttriTable[], + IN uint32_t u4AttriTableSize); + +void +p2pFuncGenerateP2P_IE(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN u_int8_t fgIsAssocFrame, + IN uint16_t *pu2Offset, + IN uint8_t *pucBuf, + IN uint16_t u2BufSize, + IN struct APPEND_VAR_ATTRI_ENTRY arAppendAttriTable[], + IN uint32_t u4AttriTableSize); + +uint32_t +p2pFuncAppendAttriStatusForAssocRsp(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN u_int8_t fgIsAssocFrame, + IN uint16_t *pu2Offset, + IN uint8_t *pucBuf, + IN uint16_t u2BufSize); + +uint32_t +p2pFuncAppendAttriExtListenTiming(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN u_int8_t fgIsAssocFrame, + IN uint16_t *pu2Offset, + IN uint8_t *pucBuf, + IN uint16_t u2BufSize); + +void +p2pFuncDissolve(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prP2pBssInfo, + IN u_int8_t fgSendDeauth, + IN uint16_t u2ReasonCode); + +struct IE_HDR * +p2pFuncGetSpecIE(IN struct ADAPTER *prAdapter, + IN uint8_t *pucIEBuf, + IN uint16_t u2BufferLen, + IN uint8_t ucElemID, + IN u_int8_t *pfgIsMore); + +struct P2P_ATTRIBUTE * +p2pFuncGetSpecAttri(IN struct ADAPTER *prAdapter, + IN uint8_t ucOuiType, + IN uint8_t *pucIEBuf, + IN uint16_t u2BufferLen, + IN uint8_t ucAttriID); + +uint32_t wfdFuncCalculateWfdIELenForAssocRsp(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, IN struct STA_RECORD *prStaRec); + +void wfdFuncGenerateWfdIEForAssocRsp(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo); + +uint32_t p2pFuncCalculateP2P_IE_NoA(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIdx, IN struct STA_RECORD *prStaRec); + +void p2pFuncGenerateP2P_IE_NoA(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo); + +void p2pFunCleanQueuedMgmtFrame(IN struct ADAPTER *prAdapter, + IN struct P2P_QUEUED_ACTION_FRAME *prFrame); + +void p2pFuncSwitchSapChannel(IN struct ADAPTER *prAdapter); + +uint32_t p2pFunGetPreferredFreqList(IN struct ADAPTER *prAdapter, + IN enum ENUM_IFTYPE eIftype, OUT uint32_t *freq_list, + OUT uint32_t *num_freq_list); + +enum ENUM_P2P_CONNECT_STATE +p2pFuncGetP2pActionFrameType(IN struct MSDU_INFO *prMgmtMsdu); + +u_int8_t +p2pFuncCheckOnRocChnl(IN struct RF_CHANNEL_INFO *prTxChnl, + IN struct P2P_CHNL_REQ_INFO *prChnlReqInfo); + +u_int8_t +p2pFuncNeedWaitRsp(IN struct ADAPTER *prAdapter, + IN enum ENUM_P2P_CONNECT_STATE eConnState); + +void +p2pFunClearAllTxReq(IN struct ADAPTER *prAdapter, + IN struct P2P_MGMT_TX_REQ_INFO *prP2pMgmtTxInfo); + +uint8_t p2pFunGetAcsBestCh(IN struct ADAPTER *prAdapter, + IN enum ENUM_BAND eBand, + IN enum ENUM_MAX_BANDWIDTH_SETTING eChnlBw, + IN uint32_t u4LteSafeChnMask_2G, + IN uint32_t u4LteSafeChnMask_5G_1, + IN uint32_t u4LteSafeChnMask_5G_2); +#if (CFG_SUPPORT_P2PGO_ACS == 1) + +void p2pFunGetAcsBestChList(IN struct ADAPTER *prAdapter, + IN uint8_t eBand, + IN enum ENUM_MAX_BANDWIDTH_SETTING eChnlBw, + IN uint32_t u4LteSafeChnMask_2G, + IN uint32_t u4LteSafeChnMask_5G_1, + IN uint32_t u4LteSafeChnMask_5G_2, + OUT uint8_t *pucSortChannelNumber, + OUT struct RF_CHANNEL_INFO *paucSortChannelList); +#endif +void p2pFunProcessAcsReport(IN struct ADAPTER *prAdapter, + IN uint8_t ucRoleIndex, + IN struct PARAM_GET_CHN_INFO *prLteSafeChnInfo, + IN struct P2P_ACS_REQ_INFO *prAcsReqInfo); + +void p2pFunIndicateAcsResult(IN struct GLUE_INFO *prGlueInfo, + IN struct P2P_ACS_REQ_INFO *prAcsReqInfo); + +void p2pFunCalAcsChnScores(IN struct ADAPTER *prAdapter); + +enum ENUM_CHNL_SWITCH_POLICY +p2pFunDetermineChnlSwitchPolicy(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIdx, + IN struct RF_CHANNEL_INFO *prNewChannelInfo); + +void +p2pFunNotifyChnlSwitch(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIdx, + enum ENUM_CHNL_SWITCH_POLICY ePolicy, + IN struct RF_CHANNEL_INFO *prNewChannelInfo); + +void +p2pFunChnlSwitchNotifyDone(IN struct ADAPTER *prAdapter); + +uint8_t p2pFuncIsBufferableMMPDU(IN struct ADAPTER *prAdapter, + IN enum ENUM_P2P_CONNECT_STATE eConnState, + IN struct MSDU_INFO *prMgmtTxMsdu); + +uint8_t p2pFuncIsTimingCriticalFrames( + IN struct ADAPTER *prAdapter, + IN enum ENUM_P2P_CONNECT_STATE eConnState, + IN struct MSDU_INFO *prMgmtTxMsdu); + +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/p2p_ie.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/p2p_ie.h new file mode 100644 index 0000000000000000000000000000000000000000..cd287743cdd15f1c03fd1a3e5dd4bb64e3fcceae --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/p2p_ie.h @@ -0,0 +1,102 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +#ifndef _P2P_IE_H +#define _P2P_IE_H + +#if CFG_SUPPORT_WFD + +#define ELEM_MAX_LEN_WFD 62 /* TODO: Move to appropriate place */ + +/*---------------- WFD Data Element Definitions ----------------*/ +/* WFD 4.1.1 - WFD IE format */ +#define WFD_OUI_TYPE_LEN 4 + +/* == OFFSET_OF(IE_P2P_T,*/ +/*aucP2PAttributes[0]) */ +#define WFD_IE_OUI_HDR (ELEM_HDR_LEN + WFD_OUI_TYPE_LEN) + +/* WFD 4.1.1 - General WFD Attribute */ +#define WFD_ATTRI_HDR_LEN 3 /* ID(1 octet) + Length(2 octets) */ + +/* WFD Attribute Code */ +#define WFD_ATTRI_ID_DEV_INFO 0 +#define WFD_ATTRI_ID_ASSOC_BSSID 1 +#define WFD_ATTRI_ID_COUPLED_SINK_INFO 6 +#define WFD_ATTRI_ID_EXT_CAPABILITY 7 +#define WFD_ATTRI_ID_SESSION_INFO 9 +#define WFD_ATTRI_ID_ALTER_MAC_ADDRESS 10 + +/* Maximum Length of WFD Attributes */ +#define WFD_ATTRI_MAX_LEN_DEV_INFO 6 /* 0 */ +#define WFD_ATTRI_MAX_LEN_ASSOC_BSSID 6 /* 1 */ +#define WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO 7 /* 6 */ +#define WFD_ATTRI_MAX_LEN_EXT_CAPABILITY 2 /* 7 */ +#define WFD_ATTRI_MAX_LEN_SESSION_INFO 0 /* 9 */ /* 24 * #Clients */ +#define WFD_ATTRI_MAX_LEN_ALTER_MAC_ADDRESS 6 /* 10 */ + +struct WFD_DEVICE_INFORMATION_IE { + uint8_t ucElemID; + uint16_t u2Length; + uint16_t u2WfdDevInfo; + uint16_t u2SessionMgmtCtrlPort; + uint16_t u2WfdDevMaxSpeed; +} __KAL_ATTRIB_PACKED__; + +#endif + +uint32_t p2pCalculate_IEForAssocReq(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, IN struct STA_RECORD *prStaRec); + +void p2pGenerate_IEForAssocReq(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo); + +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/p2p_rlm.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/p2p_rlm.h new file mode 100644 index 0000000000000000000000000000000000000000..ebb91946eecebde246d58e9a06fe4406ebe3110f --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/p2p_rlm.h @@ -0,0 +1,136 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ + +/*! \file "rlm.h" + * \brief + */ + +#ifndef _P2P_RLM_H +#define _P2P_RLM_H + +/****************************************************************************** + * C O M P I L E R F L A G S + ****************************************************************************** + */ + +/****************************************************************************** + * E X T E R N A L R E F E R E N C E S + ****************************************************************************** + */ + +/****************************************************************************** + * C O N S T A N T S + ****************************************************************************** + */ + +#define CHANNEL_SPAN_20 20 + +/****************************************************************************** + * M A C R O S + ****************************************************************************** + */ + +/****************************************************************************** + * D A T A T Y P E S + ****************************************************************************** + */ + +/****************************************************************************** + * P U B L I C D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * P R I V A T E D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N D E C L A R A T I O N S + ****************************************************************************** + */ + +void rlmBssInitForAP(struct ADAPTER *prAdapter, struct BSS_INFO *prBssInfo); + +u_int8_t rlmUpdateBwByChListForAP(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo); + +void rlmUpdateParamsForAP(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, u_int8_t fgUpdateBeacon); + +void rlmFuncInitialChannelList(IN struct ADAPTER *prAdapter); + +void +rlmFuncCommonChannelList(IN struct ADAPTER *prAdapter, + IN struct CHANNEL_ENTRY_FIELD *prChannelEntryII, + IN uint8_t ucChannelListSize); + +uint8_t rlmFuncFindOperatingClass(IN struct ADAPTER *prAdapter, + IN uint8_t ucChannelNum); + +u_int8_t +rlmFuncFindAvailableChannel(IN struct ADAPTER *prAdapter, + IN uint8_t ucCheckChnl, + IN uint8_t *pucSuggestChannel, + IN u_int8_t fgIsSocialChannel, IN u_int8_t fgIsDefaultChannel); + +enum ENUM_CHNL_EXT rlmDecideScoForAP(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo); + +enum ENUM_CHNL_EXT rlmGetScoForAP(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo); + +uint8_t rlmGetVhtS1ForAP(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo); + + +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/p2p_rlm_obss.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/p2p_rlm_obss.h new file mode 100644 index 0000000000000000000000000000000000000000..ba340c9a99c2e2d8e9648c051f43bafe6a7e1074 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/p2p_rlm_obss.h @@ -0,0 +1,118 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/mgmt/p2p_rlm_obss.h#1 + */ + +/*! \file "rlm_obss.h" + * \brief + */ + +#ifndef _P2P_RLM_OBSS_H +#define _P2P_RLM_OBSS_H + +/****************************************************************************** + * C O M P I L E R F L A G S + ****************************************************************************** + */ + +/****************************************************************************** + * E X T E R N A L R E F E R E N C E S + ****************************************************************************** + */ + +/****************************************************************************** + * C O N S T A N T S + ****************************************************************************** + */ + +/****************************************************************************** + * M A C R O S + ****************************************************************************** + */ + +/****************************************************************************** + * D A T A T Y P E S + ****************************************************************************** + */ + +/****************************************************************************** + * P U B L I C D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * P R I V A T E D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N D E C L A R A T I O N S + ****************************************************************************** + */ + +void rlmRspGenerateObssScanIE(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo); + +void rlmProcessPublicAction(struct ADAPTER *prAdapter, struct SW_RFB *prSwRfb); + +void rlmHandleObssStatusEventPkt(struct ADAPTER *prAdapter, + struct EVENT_AP_OBSS_STATUS *prObssStatus); + +uint8_t rlmObssChnlLevel(struct BSS_INFO *prBssInfo, + enum ENUM_BAND eBand, uint8_t ucPriChannel, + enum ENUM_CHNL_EXT eExtend); + +void rlmObssScanExemptionRsp(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, struct SW_RFB *prSwRfb); + +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/p2p_role.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/p2p_role.h new file mode 100644 index 0000000000000000000000000000000000000000..cbbb89918aa1ad160e00f65d25b2e6cf8b4fb4f7 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/p2p_role.h @@ -0,0 +1,507 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +#ifndef _P2P_ROLE_H +#define _P2P_ROLE_H + +#define P2P_ROLE_GET_STATISTICS_TIME 5000 + +enum ENUM_BUFFER_TYPE { + ENUM_FRAME_TYPE_EXTRA_IE_BEACON, + ENUM_FRAME_TYPE_EXTRA_IE_ASSOC_RSP, + ENUM_FRAME_TYPE_EXTRA_IE_PROBE_RSP, + ENUM_FRAME_TYPE_PROBE_RSP_TEMPLATE, + ENUM_FRAME_TYPE_BEACON_TEMPLATE, + ENUM_FRAME_IE_NUM +}; + +enum ENUM_HIDDEN_SSID_TYPE { + ENUM_HIDDEN_SSID_NONE, + ENUM_HIDDEN_SSID_ZERO_LEN, + ENUM_HIDDEN_SSID_ZERO_CONTENT, + ENUM_HIDDEN_SSID_NUM +}; + +struct P2P_BEACON_UPDATE_INFO { + uint8_t *pucBcnHdr; + uint32_t u4BcnHdrLen; + uint8_t *pucBcnBody; + uint32_t u4BcnBodyLen; +}; + +struct P2P_PROBE_RSP_UPDATE_INFO { + struct MSDU_INFO *prProbeRspMsduTemplate; +}; + +struct P2P_ASSOC_RSP_UPDATE_INFO { + uint8_t *pucAssocRspExtIE; + uint16_t u2AssocIELen; +}; + +struct AP_CRYPTO_SETTINGS { + uint32_t u4WpaVersion; + uint32_t u4CipherGroup; + int32_t i4NumOfCiphers; + uint32_t aucCiphersPairwise[5]; + int32_t i4NumOfAkmSuites; + uint32_t aucAkmSuites[2]; + u_int8_t fgIsControlPort; + uint16_t u2ControlPortBE; + u_int8_t fgIsControlPortEncrypt; +}; + +/* ////////////////////////// Message ////////////////////////////////// */ + +struct MSG_P2P_BEACON_UPDATE { + struct MSG_HDR rMsgHdr; + uint8_t ucRoleIndex; + uint32_t u4BcnHdrLen; + uint32_t u4BcnBodyLen; + uint32_t u4AssocRespLen; +#if CFG_SUPPORT_P2P_GO_OFFLOAD_PROBE_RSP + uint32_t u4ProbeRespLen; +#endif + uint8_t *pucBcnHdr; + uint8_t *pucBcnBody; + uint8_t *pucAssocRespIE; +#if CFG_SUPPORT_P2P_GO_OFFLOAD_PROBE_RSP + uint8_t *pucProbeRespIE; +#endif + u_int8_t fgIsWepCipher; + uint8_t aucBuffer[1]; /* Header & Body & Extra IEs are put here. */ +}; + +struct MSG_P2P_MGMT_FRAME_UPDATE { + struct MSG_HDR rMsgHdr; + enum ENUM_BUFFER_TYPE eBufferType; + uint32_t u4BufferLen; + uint8_t aucBuffer[1]; +}; + +struct MSG_P2P_SWITCH_OP_MODE { + struct MSG_HDR rMsgHdr; /* Must be the first member */ + enum ENUM_OP_MODE eOpMode; + uint8_t ucRoleIdx; + enum ENUM_IFTYPE eIftype; +}; + +struct MSG_P2P_MGMT_FRAME_REGISTER { + struct MSG_HDR rMsgHdr; /* Must be the first member */ + uint16_t u2FrameType; + u_int8_t fgIsRegister; +}; + +struct MSG_P2P_CHNL_ABORT { + struct MSG_HDR rMsgHdr; /* Must be the first member */ + uint64_t u8Cookie; +}; + +struct MSG_P2P_CONNECTION_REQUEST { + struct MSG_HDR rMsgHdr; /* Must be the first member */ + uint8_t ucRoleIdx; + struct P2P_SSID_STRUCT rSsid; + uint8_t aucBssid[MAC_ADDR_LEN]; + uint8_t aucSrcMacAddr[MAC_ADDR_LEN]; + enum ENUM_CHNL_EXT eChnlSco; + struct RF_CHANNEL_INFO rChannelInfo; + uint32_t u4IELen; + uint8_t aucIEBuf[1]; + /* TODO: Auth Type, OPEN, SHARED, FT, EAP... */ +}; + +struct MSG_P2P_CONNECTION_ABORT { + struct MSG_HDR rMsgHdr; /* Must be the first member. */ + uint8_t ucRoleIdx; + uint8_t aucTargetID[MAC_ADDR_LEN]; + uint16_t u2ReasonCode; + u_int8_t fgSendDeauth; +}; + +struct MSG_P2P_START_AP { + struct MSG_HDR rMsgHdr; + uint32_t u4DtimPeriod; + uint32_t u4BcnInterval; + uint8_t aucSsid[32]; + uint16_t u2SsidLen; + uint8_t ucHiddenSsidType; + u_int8_t fgIsPrivacy; + uint8_t ucRoleIdx; + struct AP_CRYPTO_SETTINGS rEncryptionSettings; + int32_t i4InactiveTimeout; +}; + +struct MSG_P2P_STOP_AP { + struct MSG_HDR rMsgHdr; + uint8_t ucRoleIdx; +}; + +#if (CFG_SUPPORT_DFS_MASTER == 1) +struct MSG_P2P_DFS_CAC { + struct MSG_HDR rMsgHdr; + enum ENUM_CHANNEL_WIDTH eChannelWidth; + uint8_t ucRoleIdx; +}; + +struct MSG_P2P_RADAR_DETECT { + struct MSG_HDR rMsgHdr; + uint8_t ucBssIndex; +}; + +struct P2P_RADAR_INFO { + uint8_t ucRadarReportMode; + /*0: Only report radar detected; 1: Add parameter reports*/ + uint8_t ucRddIdx; + uint8_t ucLongDetected; + uint8_t ucPeriodicDetected; + uint8_t ucLPBNum; + uint8_t ucPPBNum; + uint8_t ucLPBPeriodValid; + uint8_t ucLPBWidthValid; + uint8_t ucPRICountM1; + uint8_t ucPRICountM1TH; + uint8_t ucPRICountM2; + uint8_t ucPRICountM2TH; + uint32_t u4PRI1stUs; + struct LONG_PULSE_BUFFER arLpbContent[32]; + struct PERIODIC_PULSE_BUFFER arPpbContent[32]; +}; + +struct MSG_P2P_SET_NEW_CHANNEL { + struct MSG_HDR rMsgHdr; + enum ENUM_CHANNEL_WIDTH eChannelWidth; + uint8_t ucRoleIdx; + uint8_t ucBssIndex; +}; + +struct MSG_P2P_CSA_DONE { + struct MSG_HDR rMsgHdr; + uint8_t ucBssIndex; +}; +#endif + +struct MSG_P2P_DEL_IFACE { + struct MSG_HDR rMsgHdr; + uint8_t ucRoleIdx; +}; + +struct P2P_STATION_INFO { + uint32_t u4InactiveTime; + uint32_t u4RxBytes; /* TODO: */ + uint32_t u4TxBytes; /* TODO: */ + uint32_t u4RxPackets; /* TODO: */ + uint32_t u4TxPackets; /* TODO: */ + /* TODO: Add more for requirement. */ +}; + +/* 3 --------------- WFA P2P Attributes Handler prototype --------------- */ +typedef uint32_t(*PFN_APPEND_ATTRI_FUNC) (struct ADAPTER *, + uint8_t, u_int8_t, uint16_t *, uint8_t *, uint16_t); + +typedef uint32_t(*PFN_CALCULATE_VAR_ATTRI_LEN_FUNC) (struct ADAPTER *, + struct STA_RECORD *); + +struct APPEND_VAR_ATTRI_ENTRY { + uint16_t u2EstimatedFixedAttriLen; /* For fixed length */ + PFN_CALCULATE_VAR_ATTRI_LEN_FUNC pfnCalculateVariableAttriLen; + PFN_APPEND_ATTRI_FUNC pfnAppendAttri; +}; + +/* //////////////////////////////////////////////////////////////// */ + +enum ENUM_P2P_ROLE_STATE { + P2P_ROLE_STATE_IDLE = 0, + P2P_ROLE_STATE_SCAN, + P2P_ROLE_STATE_REQING_CHANNEL, + P2P_ROLE_STATE_AP_CHNL_DETECTION, + /* Requesting Channel to Send Specific Frame. */ + P2P_ROLE_STATE_GC_JOIN, + P2P_ROLE_STATE_OFF_CHNL_TX, +#if (CFG_SUPPORT_DFS_MASTER == 1) + P2P_ROLE_STATE_DFS_CAC, + P2P_ROLE_STATE_SWITCH_CHANNEL, +#endif + P2P_ROLE_STATE_NUM +}; + +enum ENUM_P2P_CONNECTION_TYPE { + P2P_CONNECTION_TYPE_IDLE = 0, + P2P_CONNECTION_TYPE_GO, + P2P_CONNECTION_TYPE_GC, + P2P_CONNECTION_TYPE_PURE_AP, + P2P_CONNECTION_TYPE_NUM +}; + +struct P2P_JOIN_INFO { + uint8_t ucSeqNumOfReqMsg; + uint8_t ucAvailableAuthTypes; + struct STA_RECORD *prTargetStaRec; + struct BSS_DESC *prTargetBssDesc; + u_int8_t fgIsJoinComplete; + /* For ASSOC Rsp. */ + uint32_t u4BufLength; + uint8_t aucIEBuf[MAX_IE_LENGTH]; +}; + +/* For STA & AP mode. */ +struct P2P_CONNECTION_REQ_INFO { + enum ENUM_P2P_CONNECTION_TYPE eConnRequest; + struct P2P_SSID_STRUCT rSsidStruct; + uint8_t aucBssid[MAC_ADDR_LEN]; + + /* AP preferred channel. */ + struct RF_CHANNEL_INFO rChannelInfo; + enum ENUM_CHNL_EXT eChnlExt; + + /* To record channel bandwidth from CFG80211 */ + enum ENUM_MAX_BANDWIDTH_SETTING eChnlBw; + + /* To record primary channel frequency (MHz) from CFG80211 */ + uint16_t u2PriChnlFreq; + + /* To record Channel Center Frequency Segment 0 (MHz) from CFG80211 */ + uint32_t u4CenterFreq1; + + /* To record Channel Center Frequency Segment 1 (MHz) from CFG80211 */ + uint32_t u4CenterFreq2; + + /* For ASSOC Req. */ + uint32_t u4BufLength; + uint8_t aucIEBuf[MAX_IE_LENGTH]; +}; + +#define P2P_ROLE_INDEX_2_ROLE_FSM_INFO(_prAdapter, _RoleIndex) \ + ((_prAdapter)->rWifiVar.aprP2pRoleFsmInfo[_RoleIndex]) + +struct P2P_ROLE_FSM_INFO { + uint8_t ucRoleIndex; + + uint8_t ucBssIndex; + + /* State related. */ + enum ENUM_P2P_ROLE_STATE eCurrentState; + + /* Channel related. */ + struct P2P_CHNL_REQ_INFO rChnlReqInfo; + + /* Scan related. */ + struct P2P_SCAN_REQ_INFO rScanReqInfo; + + /* Mgmt tx related. */ + struct P2P_MGMT_TX_REQ_INFO rMgmtTxInfo; + + /* Auto channel selection related. */ + struct P2P_ACS_REQ_INFO rAcsReqInfo; + + /* FSM Timer */ + struct TIMER rP2pRoleFsmTimeoutTimer; + +#if CFG_ENABLE_PER_STA_STATISTICS_LOG + /* Get statistics Timer */ + struct TIMER rP2pRoleFsmGetStatisticsTimer; +#endif + +#if (CFG_SUPPORT_DFS_MASTER == 1) + struct TIMER rDfsShutDownTimer; +#endif + + /* Packet filter for P2P module. */ + uint32_t u4P2pPacketFilter; + + /* GC Join related. */ + struct P2P_JOIN_INFO rJoinInfo; + + /* Connection related. */ + struct P2P_CONNECTION_REQ_INFO rConnReqInfo; + + /* Beacon Information. */ + struct P2P_BEACON_UPDATE_INFO rBeaconUpdateInfo; +}; + +/*========================= Initial ============================*/ + +uint8_t p2pRoleFsmInit(IN struct ADAPTER *prAdapter, IN uint8_t ucRoleIdx); + +void p2pRoleFsmUninit(IN struct ADAPTER *prAdapter, IN uint8_t ucRoleIdx); + +/*================== Message Event ==================*/ + +void p2pRoleFsmRunEventAbort(IN struct ADAPTER *prAdapter, + IN struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo); + +void p2pRoleFsmRunEventStartAP(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); + +void p2pRoleFsmRunEventDelIface(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); + +void p2pRoleFsmRunEventStopAP(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); + +#if (CFG_SUPPORT_DFS_MASTER == 1) +void p2pRoleFsmRunEventDfsCac(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); + +void p2pRoleFsmRunEventRadarDet(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); + +void p2pRoleFsmRunEventSetNewChannel(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); + +void p2pRoleFsmRunEventCsaDone(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); + +void p2pRoleFsmRunEventDfsShutDownTimeout(IN struct ADAPTER *prAdapter, + IN unsigned long ulParamPtr); +#endif + +void p2pRoleFsmRunEventScanRequest(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); + +void +p2pRoleFsmRunEventScanDone(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr, + IN struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo); + +void p2pRoleFsmRunEventJoinComplete(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); + +void p2pRoleFsmRunEventTimeout(IN struct ADAPTER *prAdapter, + IN unsigned long ulParamPtr); + +void p2pRoleFsmDeauthTimeout(IN struct ADAPTER *prAdapter, + IN unsigned long ulParamPtr); + +void p2pRoleFsmRunEventBeaconTimeout(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prP2pBssInfo); + +void p2pRoleUpdateACLEntry(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIdx); + +u_int8_t p2pRoleProcessACLInspection(IN struct ADAPTER *prAdapter, + IN uint8_t *pMacAddr, IN uint8_t ucBssIdx); + +uint32_t +p2pRoleFsmRunEventAAAComplete(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, + IN struct BSS_INFO *prP2pBssInfo); + +uint32_t +p2pRoleFsmRunEventAAASuccess(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, + IN struct BSS_INFO *prP2pBssInfo); + +void p2pRoleFsmRunEventAAATxFail(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, + IN struct BSS_INFO *prP2pBssInfo); + +void p2pRoleFsmRunEventConnectionRequest(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); + +void p2pRoleFsmRunEventConnectionAbort(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); + +void +p2pRoleFsmRunEventChnlGrant(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr, + IN struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo); + +uint32_t +p2pRoleFsmRunEventDeauthTxDone(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN enum ENUM_TX_RESULT_CODE rTxDoneStatus); + +void p2pRoleFsmRunEventRxDeauthentication(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, IN struct SW_RFB *prSwRfb); + +void p2pRoleFsmRunEventRxDisassociation(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, IN struct SW_RFB *prSwRfb); + +/* //////////////////////// TO BE REFINE ///////////////////// */ +void p2pRoleFsmRunEventSwitchOPMode(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); + +void p2pRoleFsmRunEventBeaconUpdate(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); + +void p2pRoleFsmRunEventDissolve(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); + +void +p2pProcessEvent_UpdateNOAParam(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIdx, + IN struct EVENT_UPDATE_NOA_PARAMS *prEventUpdateNoaParam); + +#if CFG_ENABLE_PER_STA_STATISTICS_LOG +void p2pRoleFsmGetStaStatistics(IN struct ADAPTER *prAdapter, + IN unsigned long ulParamPtr); +#endif + +void p2pRoleFsmNotifyEapolTxStatus(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN enum ENUM_EAPOL_KEY_TYPE_T rEapolKeyType, + IN enum ENUM_TX_RESULT_CODE rTxDoneStatus); + +void p2pRoleFsmNotifyDhcpDone(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +void p2pRoleFsmRunEventMgmtTx(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); + +void p2pRoleFsmRunEventTxCancelWait(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); + +void p2pRoleFsmRunEventAcs(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); + +void p2pRoleFsmRunEventScanAbort(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIdx); + +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/p2p_role_state.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/p2p_role_state.h new file mode 100644 index 0000000000000000000000000000000000000000..3ad21d1dadc1bd1fff42da5ae67b087f756b8a34 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/p2p_role_state.h @@ -0,0 +1,160 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +#ifndef _P2P_ROLE_STATE_H +#define _P2P_ROLE_STATE_H + +void +p2pRoleStateInit_IDLE(IN struct ADAPTER *prAdapter, + IN struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo, + IN struct BSS_INFO *prP2pBssInfo); + +void +p2pRoleStateAbort_IDLE(IN struct ADAPTER *prAdapter, + IN struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo, + IN struct P2P_CHNL_REQ_INFO *prP2pChnlReqInfo); + +void p2pRoleStateInit_SCAN(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN struct P2P_SCAN_REQ_INFO *prScanReqInfo); + +void p2pRoleStateAbort_SCAN(IN struct ADAPTER *prAdapter, + IN struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo); + +void +p2pRoleStateInit_REQING_CHANNEL(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIdx, + IN struct P2P_CHNL_REQ_INFO *prChnlReqInfo); + +void +p2pRoleStateAbort_REQING_CHANNEL(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prP2pRoleBssInfo, + IN struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo, + IN enum ENUM_P2P_ROLE_STATE eNextState); + +void +p2pRoleStateInit_AP_CHNL_DETECTION(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN struct P2P_SCAN_REQ_INFO *prScanReqInfo, + IN struct P2P_CONNECTION_REQ_INFO *prConnReqInfo); + +void +p2pRoleStateAbort_AP_CHNL_DETECTION(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN struct P2P_CONNECTION_REQ_INFO *prP2pConnReqInfo, + IN struct P2P_CHNL_REQ_INFO *prChnlReqInfo, + IN struct P2P_SCAN_REQ_INFO *prP2pScanReqInfo, + IN enum ENUM_P2P_ROLE_STATE eNextState); + +void +p2pRoleStateInit_GC_JOIN(IN struct ADAPTER *prAdapter, + IN struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo, + IN struct P2P_CHNL_REQ_INFO *prChnlReqInfo); + +void +p2pRoleStateAbort_GC_JOIN(IN struct ADAPTER *prAdapter, + IN struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo, + IN struct P2P_JOIN_INFO *prJoinInfo, + IN enum ENUM_P2P_ROLE_STATE eNextState); + +#if (CFG_SUPPORT_DFS_MASTER == 1) +void +p2pRoleStateInit_DFS_CAC(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIdx, + IN struct P2P_CHNL_REQ_INFO *prChnlReqInfo); + +void +p2pRoleStateAbort_DFS_CAC(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prP2pRoleBssInfo, + IN struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo, + IN enum ENUM_P2P_ROLE_STATE eNextState); + +void +p2pRoleStateInit_SWITCH_CHANNEL(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIdx, + IN struct P2P_CHNL_REQ_INFO *prChnlReqInfo); + +void +p2pRoleStateAbort_SWITCH_CHANNEL(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prP2pRoleBssInfo, + IN struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo, + IN enum ENUM_P2P_ROLE_STATE eNextState); + +void +p2pRoleStatePrepare_To_DFS_CAC_STATE(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo, + IN enum ENUM_CHANNEL_WIDTH rChannelWidth, + IN struct P2P_CONNECTION_REQ_INFO *prConnReqInfo, + OUT struct P2P_CHNL_REQ_INFO *prChnlReqInfo); + +#endif + +void +p2pRoleStatePrepare_To_REQING_CHANNEL_STATE(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo, + IN struct P2P_CONNECTION_REQ_INFO *prConnReqInfo, + OUT struct P2P_CHNL_REQ_INFO *prChnlReqInfo); + +u_int8_t +p2pRoleStateInit_OFF_CHNL_TX(IN struct ADAPTER *prAdapter, + IN struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo, + IN struct P2P_CHNL_REQ_INFO *prChnlReqInfo, + IN struct P2P_MGMT_TX_REQ_INFO *prP2pMgmtTxInfo, + OUT enum ENUM_P2P_ROLE_STATE *peNextState); + +void +p2pRoleStateAbort_OFF_CHNL_TX(IN struct ADAPTER *prAdapter, + IN struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo, + IN struct P2P_MGMT_TX_REQ_INFO *prP2pMgmtTxInfo, + IN struct P2P_CHNL_REQ_INFO *prChnlReqInfo, + IN enum ENUM_P2P_ROLE_STATE eNextState); + +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/p2p_scan.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/p2p_scan.h new file mode 100644 index 0000000000000000000000000000000000000000..e33ff64f25e7d7f9fdc06074703a56890fa37103 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/p2p_scan.h @@ -0,0 +1,125 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/mgmt/p2p_scan.h#1 + */ + +/*! \file "scan.h" + * \brief + * + */ + +#ifndef _P2P_SCAN_H +#define _P2P_SCAN_H + +/****************************************************************************** + * C O M P I L E R F L A G S + ****************************************************************************** + */ + +/****************************************************************************** + * E X T E R N A L R E F E R E N C E S + ****************************************************************************** + */ + +/****************************************************************************** + * C O N S T A N T S + ****************************************************************************** + */ + +/****************************************************************************** + * M A C R O S + ****************************************************************************** + */ + +/****************************************************************************** + * D A T A T Y P E S + ****************************************************************************** + */ + +/****************************************************************************** + * P U B L I C D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * P R I V A T E D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N D E C L A R A T I O N S + ****************************************************************************** + */ + +void scnEventReturnChannel(IN struct ADAPTER *prAdapter, + IN uint8_t ucScnSeqNum); + +u_int8_t scanUpdateP2pDeviceDesc(IN struct ADAPTER *prAdapter, + IN struct BSS_DESC *prBssDesc); + +void +scanP2pProcessBeaconAndProbeResp(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, + IN uint32_t *prStatus, + IN struct BSS_DESC *prBssDesc, + IN struct WLAN_BEACON_FRAME *prWlanBeaconFrame); + +void scanRemoveAllP2pBssDesc(struct ADAPTER *prAdapter); + +void scanRemoveP2pBssDesc(struct ADAPTER *prAdapter, + struct BSS_DESC *prBssDesc); + +struct BSS_DESC *scanP2pSearchDesc(IN struct ADAPTER *prAdapter, + IN struct P2P_CONNECTION_REQ_INFO *prConnReqInfo); + +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/privacy.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/privacy.h new file mode 100644 index 0000000000000000000000000000000000000000..8742b4bc4c9f782e95e4b2bc3ba97a44c98363d3 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/privacy.h @@ -0,0 +1,295 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: include/mgmt/privacy.h#1 + */ + +/*! \file privacy.h + * \brief This file contains the function declaration for privacy.c. + */ + + +#ifndef _PRIVACY_H +#define _PRIVACY_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#define MAX_KEY_NUM 4 +#define WEP_40_LEN 5 +#define WEP_104_LEN 13 +#define WEP_128_LEN 16 +#define LEGACY_KEY_MAX_LEN 16 +#define CCMP_KEY_LEN 16 +#define TKIP_KEY_LEN 32 +#define MAX_KEY_LEN 32 +#define MIC_RX_KEY_OFFSET 16 +#define MIC_TX_KEY_OFFSET 24 +#define MIC_KEY_LEN 8 + +#define WEP_KEY_ID_FIELD BITS(0, 29) +#define KEY_ID_FIELD BITS(0, 7) + +#define IS_TRANSMIT_KEY BIT(31) +#define IS_UNICAST_KEY BIT(30) +#define IS_AUTHENTICATOR BIT(28) + +/* WTBL cipher selector, sync with HAL RX from hal_hw_def_rom.h */ +#define CIPHER_SUITE_NONE 0 +#define CIPHER_SUITE_WEP40 1 +#define CIPHER_SUITE_TKIP 2 +#define CIPHER_SUITE_TKIP_WO_MIC 3 +#define CIPHER_SUITE_CCMP 4 +#define CIPHER_SUITE_WEP104 5 +#define CIPHER_SUITE_BIP 6 +#define CIPHER_SUITE_WEP128 7 +#define CIPHER_SUITE_WPI 8 +#define CIPHER_SUITE_CCMP_W_CCX 9 /* CCMP-128 for DFP or CCX MFP */ +#define CIPHER_SUITE_CCMP_256 10 +#define CIPHER_SUITE_GCMP_128 11 +#define CIPHER_SUITE_GCMP_256 12 +#define CIPHER_SUITE_GCM_WPI_128 13 + +/* Todo:: Move to register */ +#if defined(MT6630) +#define WTBL_RESERVED_ENTRY 255 +#else +#define WTBL_RESERVED_ENTRY 255 +#endif +/* Todo:: By chip capability */ +/* Max wlan table size, the max+1 used for probe request,... mgmt frame */ +/*sending use basic rate and no security */ +#define WTBL_SIZE 32 + +#define WTBL_ALLOC_FAIL WTBL_RESERVED_ENTRY +#define WTBL_DEFAULT_ENTRY 0 + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +struct IEEE_802_1X_HDR { + uint8_t ucVersion; + uint8_t ucType; + uint16_t u2Length; + /* followed by length octets of data */ +}; + +struct EAPOL_KEY { + uint8_t ucType; + /* Note: key_info, key_length, and key_data_length are unaligned */ + uint8_t aucKeyInfo[2]; /* big endian */ + uint8_t aucKeyLength[2]; /* big endian */ + uint8_t aucReplayCounter[8]; + uint8_t aucKeyNonce[16]; + uint8_t aucKeyIv[16]; + uint8_t aucKeyRsc[8]; + uint8_t aucKeyId[8]; /* Reserved in IEEE 802.11i/RSN */ + uint8_t aucKeyMic[16]; + uint8_t aucKeyDataLength[2]; /* big endian */ + /* followed by key_data_length bytes of key_data */ +}; + +/* WPA2 PMKID candicate structure */ +struct PMKID_CANDICATE { + uint8_t aucBssid[MAC_ADDR_LEN]; + uint32_t u4PreAuthFlags; +}; + +#if 0 +/* WPA2 PMKID cache structure */ +struct PMKID_ENTRY { + struct PARAM_BSSID_INFO rBssidInfo; + u_int8_t fgPmkidExist; +}; +#endif + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +void secInit(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +void secSetPortBlocked(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prSta, IN u_int8_t fgPort); + +u_int8_t secCheckClassError(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, + IN struct STA_RECORD *prStaRec); + +u_int8_t secTxPortControlCheck(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN struct STA_RECORD *prStaRec); + +u_int8_t secRxPortControlCheck(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSWRfb); + +void secSetCipherSuite(IN struct ADAPTER *prAdapter, + IN uint32_t u4CipherSuitesFlags, + IN uint8_t ucBssIndex); + +u_int8_t secIsProtectedFrame(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsdu, + IN struct STA_RECORD *prStaRec); + +u_int8_t secRsnKeyHandshakeEnabled(IN struct ADAPTER + *prAdapter); + +uint8_t secGetBmcWlanIndex(IN struct ADAPTER *prAdapter, + IN enum ENUM_NETWORK_TYPE eNetType, + IN struct STA_RECORD *prStaRec); + +u_int8_t secTransmitKeyExist(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prSta); + +u_int8_t secEnabledInAis(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +u_int8_t secPrivacySeekForEntry(IN struct ADAPTER + *prAdapter, IN struct STA_RECORD *prSta); + +void secPrivacyFreeForEntry(IN struct ADAPTER *prAdapter, + IN uint8_t ucEntry); + +void secPrivacyFreeSta(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec); + +void secRemoveBssBcEntry(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo, IN u_int8_t fgRoam); + +uint8_t +secPrivacySeekForBcEntry(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN uint8_t *pucAddr, IN uint8_t ucStaIdx, + IN uint8_t ucAlg, IN uint8_t ucKeyId); + +uint8_t secGetStaIdxByWlanIdx(IN struct ADAPTER *prAdapter, + IN uint8_t ucWlanIdx); + +uint8_t secGetBssIdxByWlanIdx(IN struct ADAPTER *prAdapter, + IN uint8_t ucWlanIdx); + +uint8_t secGetBssIdxByRfb(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb); + +uint8_t secLookupStaRecIndexFromTA(struct ADAPTER + *prAdapter, uint8_t *pucMacAddress); + +void secPrivacyDumpWTBL(IN struct ADAPTER *prAdapter); + +u_int8_t secCheckWTBLAssign(IN struct ADAPTER *prAdapter); + +u_int8_t secIsProtected1xFrame(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec); + +u_int8_t secIsProtectedBss(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo); + +u_int8_t secIsRobustActionFrame(IN struct ADAPTER *prAdapter, + IN void *prPacket); + +u_int8_t secIsRobustMgmtFrame(IN struct ADAPTER *prAdapter, + IN void *prPacket); + +u_int8_t secIsWepBss(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo); + +u_int8_t tkipMicDecapsulate(IN struct SW_RFB *prSwRfb, + IN uint8_t *pucMicKey); + +u_int8_t tkipMicDecapsulateInRxHdrTransMode( + IN struct SW_RFB *prSwRfb, IN uint8_t *pucMicKey); + +void secPostUpdateAddr(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo); + +enum ENUM_EAPOL_KEY_TYPE_T secGetEapolKeyType( + uint8_t *pucPacket); + +void secHandleNoWtbl(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb); + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#endif /* _PRIVACY_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/qosmap.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/qosmap.h new file mode 100644 index 0000000000000000000000000000000000000000..1cb46d2a3d04efb05200dc67a3aab355c5f499b4 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/qosmap.h @@ -0,0 +1,122 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/*! \file "qosmap.h" + * \brief This file including the qosmap related function. + * + * This file provided the macros and functions library support for the + * protocol layer qosmap related function. + * + */ + +#ifndef _QOSMAP_H +#define _QOSMAP_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ +#define DSCP_SUPPORT 1 +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +void handleQosMapConf(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb); + +int qosHandleQosMapConfigure(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb); + +void qosMapSetInit(IN struct STA_RECORD *prStaRec); + +void qosParseQosMapSet(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, IN uint8_t *qosMapSet); + +uint8_t getUpFromDscp(IN struct GLUE_INFO *prGlueInfo, + IN int type, IN int dscp); + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#endif /* _QOSMAP_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/rate.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/rate.h new file mode 100644 index 0000000000000000000000000000000000000000..555ec7c414036ff26b4ebdb7e666c771fe11650c --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/rate.h @@ -0,0 +1,133 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/ + * include/mgmt/rate.h#1 + */ + +/*! \file rate.h + * \brief This file contains the rate utility function of + * IEEE 802.11 family for MediaTek 802.11 Wireless LAN Adapters. + */ + +#ifndef _RATE_H +#define _RATE_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ +extern const uint8_t aucDataRate[]; + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +/*----------------------------------------------------------------------------*/ +/* Routines in rate.c */ +/*----------------------------------------------------------------------------*/ +void +rateGetRateSetFromIEs(IN struct IE_SUPPORTED_RATE_IOT + *prIeSupportedRate, + IN struct IE_EXT_SUPPORTED_RATE *prIeExtSupportedRate, OUT + uint16_t *pu2OperationalRateSet, + OUT uint16_t *pu2BSSBasicRateSet, + OUT u_int8_t *pfgIsUnknownBSSBasicRate); + +void +rateGetDataRatesFromRateSet(IN uint16_t + u2OperationalRateSet, IN uint16_t u2BSSBasicRateSet, + OUT uint8_t *pucDataRates, OUT + uint8_t *pucDataRatesLen); + +u_int8_t rateGetHighestRateIndexFromRateSet( + IN uint16_t u2RateSet, OUT uint8_t *pucHighestRateIndex); + +u_int8_t rateGetLowestRateIndexFromRateSet( + IN uint16_t u2RateSet, OUT uint8_t *pucLowestRateIndex); + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#endif /* _RATE_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/rlm.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/rlm.h new file mode 100644 index 0000000000000000000000000000000000000000..5e3a760e3f597190f07f04bc31ed1c5e3099239e --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/rlm.h @@ -0,0 +1,512 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/ + * include/mgmt/rlm.h#2 + */ + +/*! \file "rlm.h" + * \brief + */ + + +#ifndef _RLM_H +#define _RLM_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +extern u_int8_t g_bIcapEnable; +extern u_int8_t g_bCaptureDone; +extern uint16_t g_u2DumpIndex; +#if CFG_SUPPORT_QA_TOOL +extern uint32_t g_au4Offset[2][2]; +extern uint32_t g_au4IQData[256]; +#endif + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#define ELEM_EXT_CAP_DEFAULT_VAL \ + (ELEM_EXT_CAP_20_40_COEXIST_SUPPORT /*| ELEM_EXT_CAP_PSMP_CAP*/) + +#if CFG_SUPPORT_RX_STBC +#define FIELD_HT_CAP_INFO_RX_STBC HT_CAP_INFO_RX_STBC_1_SS +#else +#define FIELD_HT_CAP_INFO_RX_STBC HT_CAP_INFO_RX_STBC_NO_SUPPORTED +#endif + +#if CFG_SUPPORT_RX_SGI +#define FIELD_HT_CAP_INFO_SGI_20M HT_CAP_INFO_SHORT_GI_20M +#define FIELD_HT_CAP_INFO_SGI_40M HT_CAP_INFO_SHORT_GI_40M +#else +#define FIELD_HT_CAP_INFO_SGI_20M 0 +#define FIELD_HT_CAP_INFO_SGI_40M 0 +#endif + +#if CFG_SUPPORT_RX_HT_GF +#define FIELD_HT_CAP_INFO_HT_GF HT_CAP_INFO_HT_GF +#else +#define FIELD_HT_CAP_INFO_HT_GF 0 +#endif + +#define HT_CAP_INFO_DEFAULT_VAL \ + (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_DSSS_CCK_IN_40M \ + | HT_CAP_INFO_SM_POWER_SAVE) + +#define AMPDU_PARAM_DEFAULT_VAL \ + (AMPDU_PARAM_MAX_AMPDU_LEN_64K | AMPDU_PARAM_MSS_NO_RESTRICIT) + +#define SUP_MCS_TX_DEFAULT_VAL \ + SUP_MCS_TX_SET_DEFINED /* TX defined and TX/RX equal (TBD) */ + +#if CFG_SUPPORT_MFB +#define FIELD_HT_EXT_CAP_MFB HT_EXT_CAP_MCS_FEEDBACK_BOTH +#else +#define FIELD_HT_EXT_CAP_MFB HT_EXT_CAP_MCS_FEEDBACK_NO_FB +#endif + +#if CFG_SUPPORT_RX_RDG +#define FIELD_HT_EXT_CAP_RDR HT_EXT_CAP_RD_RESPONDER +#else +#define FIELD_HT_EXT_CAP_RDR 0 +#endif + +#if CFG_SUPPORT_MFB || CFG_SUPPORT_RX_RDG +#define FIELD_HT_EXT_CAP_HTC HT_EXT_CAP_HTC_SUPPORT +#else +#define FIELD_HT_EXT_CAP_HTC 0 +#endif + +#define HT_EXT_CAP_DEFAULT_VAL \ + (HT_EXT_CAP_PCO | HT_EXT_CAP_PCO_TRANS_TIME_NONE | \ + FIELD_HT_EXT_CAP_MFB | FIELD_HT_EXT_CAP_HTC | \ + FIELD_HT_EXT_CAP_RDR) + +#define TX_BEAMFORMING_CAP_DEFAULT_VAL 0 + +#if CFG_SUPPORT_BFEE +#define TX_BEAMFORMING_CAP_BFEE \ + (TXBF_RX_NDP_CAPABLE | \ + TXBF_EXPLICIT_COMPRESSED_FEEDBACK_IMMEDIATE_CAPABLE | \ + TXBF_MINIMAL_GROUPING_1_2_3_CAPABLE | \ + TXBF_COMPRESSED_TX_ANTENNANUM_4_SUPPORTED | \ + TXBF_CHANNEL_ESTIMATION_4STS_CAPABILITY) +#else +#define TX_BEAMFORMING_CAP_BFEE 0 +#endif + +#if CFG_SUPPORT_BFER +#define TX_BEAMFORMING_CAP_BFER \ + (TXBF_TX_NDP_CAPABLE | \ + TXBF_EXPLICIT_COMPRESSED_TX_CAPAB) +#else +#define TX_BEAMFORMING_CAP_BFER 0 +#endif + +#define ASEL_CAP_DEFAULT_VAL 0 + +/* Define bandwidth from user setting */ +#define CONFIG_BW_20_40M 0 +#define CONFIG_BW_20M 1 /* 20MHz only */ + +#define RLM_INVALID_POWER_LIMIT -127 /* dbm */ + +#define RLM_MAX_TX_PWR 20 /* dbm */ +#define RLM_MIN_TX_PWR 8 /* dbm */ + +#if CFG_SUPPORT_802_11AC +#if CFG_SUPPORT_BFEE +#define FIELD_VHT_CAP_INFO_BFEE \ + (VHT_CAP_INFO_SU_BEAMFORMEE_CAPABLE) +#define VHT_CAP_INFO_BEAMFORMEE_STS_CAP_MAX 3 +#else +#define FIELD_VHT_CAP_INFO_BFEE 0 +#endif + +#if CFG_SUPPORT_BFER +#define FIELD_VHT_CAP_INFO_BFER \ + (VHT_CAP_INFO_SU_BEAMFORMER_CAPABLE| \ + VHT_CAP_INFO_NUMBER_OF_SOUNDING_DIMENSIONS_2_SUPPORTED) +#else +#define FIELD_VHT_CAP_INFO_BFER 0 +#endif + +#define VHT_CAP_INFO_DEFAULT_VAL \ + (VHT_CAP_INFO_MAX_MPDU_LEN_3K | \ + (AMPDU_PARAM_MAX_AMPDU_LEN_1024K \ + << VHT_CAP_INFO_MAX_AMPDU_LENGTH_OFFSET)) + +#define VHT_CAP_INFO_DEFAULT_HIGHEST_DATA_RATE 0 +#endif +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +#if CFG_SUPPORT_CAL_RESULT_BACKUP_TO_HOST +struct RLM_CAL_RESULT_ALL_V2 { + /* Used for checking the Cal Data is damaged */ + uint32_t u4MagicNum1; + + /* Thermal Value when do these Calibration */ + uint32_t u4ThermalInfo; + + /* Total Rom Data Length Backup in Host Side */ + uint32_t u4ValidRomCalDataLength; + + /* Total Ram Data Length Backup in Host Side */ + uint32_t u4ValidRamCalDataLength; + + /* All Rom Cal Data Dumpped by FW */ + uint32_t au4RomCalData[10000]; + + /* All Ram Cal Data Dumpped by FW */ + uint32_t au4RamCalData[10000]; + + /* Used for checking the Cal Data is damaged */ + uint32_t u4MagicNum2; +}; +extern struct RLM_CAL_RESULT_ALL_V2 g_rBackupCalDataAllV2; +#endif + +typedef void (*PFN_OPMODE_NOTIFY_DONE_FUNC)( + struct ADAPTER *, uint8_t, bool); + +enum ENUM_OP_NOTIFY_TYPE_T { + OP_NOTIFY_TYPE_VHT_NSS_BW = 0, + OP_NOTIFY_TYPE_HT_NSS, + OP_NOTIFY_TYPE_HT_BW, + OP_NOTIFY_TYPE_NUM +}; + +enum ENUM_OP_CHANGE_STATUS_T { + OP_CHANGE_STATUS_INVALID = 0, /* input invalid */ + /* input valid, but no need to change */ + OP_CHANGE_STATUS_VALID_NO_CHANGE, + /* process callback done before function return */ + OP_CHANGE_STATUS_VALID_CHANGE_CALLBACK_DONE, + /* wait next INT to call callback */ + OP_CHANGE_STATUS_VALID_CHANGE_CALLBACK_WAIT, + OP_CHANGE_STATUS_NUM +}; + +struct SUB_ELEMENT_LIST { + struct SUB_ELEMENT_LIST *prNext; + struct SUB_ELEMENT rSubIE; +}; + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/* It is used for RLM module to judge if specific network is valid + * Note: Ad-hoc mode of AIS is not included now. (TBD) + */ +#define RLM_NET_PARAM_VALID(_prBssInfo) \ + (IS_BSS_ACTIVE(_prBssInfo) && \ + ((_prBssInfo)->eConnectionState == MEDIA_STATE_CONNECTED || \ + (_prBssInfo)->eCurrentOPMode == OP_MODE_ACCESS_POINT || \ + (_prBssInfo)->eCurrentOPMode == OP_MODE_IBSS || \ + IS_BSS_BOW(_prBssInfo)) \ + ) + +#define RLM_NET_IS_11N(_prBssInfo) \ + ((_prBssInfo)->ucPhyTypeSet & PHY_TYPE_SET_802_11N) +#define RLM_NET_IS_11GN(_prBssInfo) \ + ((_prBssInfo)->ucPhyTypeSet & PHY_TYPE_SET_802_11GN) + +#if CFG_SUPPORT_802_11AC +#define RLM_NET_IS_11AC(_prBssInfo) \ + ((_prBssInfo)->ucPhyTypeSet & PHY_TYPE_SET_802_11AC) +#endif +#if (CFG_SUPPORT_802_11AX == 1) +#define RLM_NET_IS_11AX(_prBssInfo) \ + ((_prBssInfo)->ucPhyTypeSet & PHY_TYPE_SET_802_11AX) +#endif + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +void rlmFsmEventInit(struct ADAPTER *prAdapter); + +void rlmFsmEventUninit(struct ADAPTER *prAdapter); + +void rlmReqGenerateHtCapIE(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo); + +void rlmReqGeneratePowerCapIE(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo); + +void rlmReqGenerateSupportedChIE(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo); + +void rlmReqGenerateExtCapIE(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo); + +void rlmRspGenerateHtCapIE(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo); + +void rlmRspGenerateExtCapIE(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo); + +void rlmRspGenerateHtOpIE(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo); + +void rlmRspGenerateErpIE(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo); + +void rlmGenerateMTKOuiIE(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo); + +u_int8_t rlmParseCheckMTKOuiIE(IN struct ADAPTER *prAdapter, + IN uint8_t *pucBuf, IN uint32_t *pu4Cap); + +void rlmGenerateCsaIE(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo); + +void rlmProcessBcn(struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb, uint8_t *pucIE, + uint16_t u2IELength); + +void rlmProcessAssocRsp(struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb, uint8_t *pucIE, + uint16_t u2IELength); + +void rlmProcessHtAction(struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb); + +#if CFG_SUPPORT_802_11AC +void rlmProcessVhtAction(struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb); +#endif + +void rlmFillSyncCmdParam(struct CMD_SET_BSS_RLM_PARAM + *prCmdBody, struct BSS_INFO *prBssInfo); + +void rlmSyncOperationParams(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo); + +void rlmBssInitForAPandIbss(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo); + +void rlmProcessAssocReq(struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb, uint8_t *pucIE, + uint16_t u2IELength); + +void rlmBssAborted(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo); + +#if CFG_SUPPORT_TDLS +uint32_t +rlmFillHtCapIEByParams(u_int8_t fg40mAllowed, + u_int8_t fgShortGIDisabled, + uint8_t u8SupportRxSgi20, + uint8_t u8SupportRxSgi40, uint8_t u8SupportRxGf, + enum ENUM_OP_MODE eCurrentOPMode, uint8_t *pOutBuf); + +uint32_t rlmFillHtCapIEByAdapter(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, uint8_t *pOutBuf); + +uint32_t rlmFillVhtCapIEByAdapter(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, uint8_t *pOutBuf); + +#endif + +#if CFG_SUPPORT_802_11AC +void rlmReqGenerateVhtCapIE(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo); + +void rlmRspGenerateVhtCapIE(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo); + +void rlmRspGenerateVhtOpIE(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo); + +void rlmFillVhtOpIE(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, struct MSDU_INFO *prMsduInfo); + +void rlmRspGenerateVhtOpNotificationIE(struct ADAPTER + *prAdapter, struct MSDU_INFO *prMsduInfo); +void rlmReqGenerateVhtOpNotificationIE(struct ADAPTER + *prAdapter, struct MSDU_INFO *prMsduInfo); + + + + +#endif + +void rlmGenerateCountryIE(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo); + +#if CFG_SUPPORT_DFS +void rlmProcessSpecMgtAction(struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb); +#endif + +uint32_t +rlmSendOpModeNotificationFrame(struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + uint8_t ucChannelWidth, uint8_t ucNss); + +uint32_t +rlmSendSmPowerSaveFrame(struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, uint8_t ucNss); + +void rlmSendChannelSwitchFrame(struct ADAPTER *prAdapter, + uint8_t ucBssIndex); + +uint32_t +rlmNotifyVhtOpModeTxDone(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo, + enum ENUM_TX_RESULT_CODE rTxDoneStatus); + +uint32_t +rlmSmPowerSaveTxDone(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo, + enum ENUM_TX_RESULT_CODE rTxDoneStatus); + +uint32_t +rlmNotifyChannelWidthtTxDone(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo, + enum ENUM_TX_RESULT_CODE rTxDoneStatus); + +uint8_t +rlmGetBssOpBwByVhtAndHtOpInfo(struct BSS_INFO *prBssInfo); + +uint8_t +rlmGetVhtOpBwByBssOpBw(uint8_t ucBssOpBw); + +void +rlmFillVhtOpInfoByBssOpBw(struct BSS_INFO *prBssInfo, + uint8_t ucChannelWidth); + +enum ENUM_OP_CHANGE_STATUS_T +rlmChangeOperationMode( + struct ADAPTER *prAdapter, + uint8_t ucBssIndex, + uint8_t ucChannelWidth, + uint8_t ucOpRxNss, + uint8_t ucOpTxNss, + #if CFG_SUPPORT_SMART_GEAR + uint8_t eNewReq, + #endif + PFN_OPMODE_NOTIFY_DONE_FUNC pfOpChangeHandler +); + +void +rlmDummyChangeOpHandler(struct ADAPTER *prAdapter, + uint8_t ucBssIndex, bool fgIsChangeSuccess); + + +#if CFG_SUPPORT_CAL_RESULT_BACKUP_TO_HOST +uint32_t rlmCalBackup( + struct ADAPTER *prAdapter, + uint8_t ucReason, + uint8_t ucAction, + uint8_t ucRomRam +); + +uint32_t rlmTriggerCalBackup( + struct ADAPTER *prAdapter, + u_int8_t fgIsCalDataBackuped +); +#endif + +void rlmModifyVhtBwPara(uint8_t *pucVhtChannelFrequencyS1, + uint8_t *pucVhtChannelFrequencyS2, + uint8_t *pucVhtChannelWidth); + +void rlmReviseMaxBw( + struct ADAPTER *prAdapter, + uint8_t ucBssIndex, + enum ENUM_CHNL_EXT *peExtend, + enum ENUM_CHANNEL_WIDTH *peChannelWidth, + uint8_t *pucS1, + uint8_t *pucPrimaryCh); + +void rlmSetMaxTxPwrLimit(IN struct ADAPTER *prAdapter, int8_t cLimit, + uint8_t ucEnable); + +void rlmSyncExtCapIEwithSupplicant(uint8_t *aucCapabilities, + const uint8_t *supExtCapIEs, size_t IElen); + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#ifndef _lint +static __KAL_INLINE__ void rlmDataTypeCheck(void) +{ +} +#endif /* _lint */ + +#endif /* _RLM_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/rlm_domain.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/rlm_domain.h new file mode 100644 index 0000000000000000000000000000000000000000..dc9dc2a8303e48ddf880d3aa9631f7a912b7b116 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/rlm_domain.h @@ -0,0 +1,1147 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/ + * include/mgmt/rlm_domain.h#1 + */ + +/*! \file "rlm_domain.h" + * \brief + */ + + +#ifndef _RLM_DOMAIN_H +#define _RLM_DOMAIN_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + #include "wsys_cmd_handler_fw.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#define MAX_SUBBAND_NUM 6 +#define MAX_SUBBAND_NUM_5G 8 + +#define COUNTRY_CODE_NULL ((uint16_t)0x0) + +/* ISO/IEC 3166-1 two-character country codes */ + +/* Andorra */ +#define COUNTRY_CODE_AD (((uint16_t) 'A' << 8) | (uint16_t) 'D') +/* UAE */ +#define COUNTRY_CODE_AE (((uint16_t) 'A' << 8) | (uint16_t) 'E') +/* Afghanistan */ +#define COUNTRY_CODE_AF (((uint16_t) 'A' << 8) | (uint16_t) 'F') +/* Antigua & Barbuda */ +#define COUNTRY_CODE_AG (((uint16_t) 'A' << 8) | (uint16_t) 'G') +/* Anguilla */ +#define COUNTRY_CODE_AI (((uint16_t) 'A' << 8) | (uint16_t) 'I') +/* Albania */ +#define COUNTRY_CODE_AL (((uint16_t) 'A' << 8) | (uint16_t) 'L') +/* Armenia */ +#define COUNTRY_CODE_AM (((uint16_t) 'A' << 8) | (uint16_t) 'M') +/* Netherlands Antilles */ +#define COUNTRY_CODE_AN (((uint16_t) 'A' << 8) | (uint16_t) 'N') +/* Angola */ +#define COUNTRY_CODE_AO (((uint16_t) 'A' << 8) | (uint16_t) 'O') +/* Argentina */ +#define COUNTRY_CODE_AR (((uint16_t) 'A' << 8) | (uint16_t) 'R') +/* American Samoa (USA) */ +#define COUNTRY_CODE_AS (((uint16_t) 'A' << 8) | (uint16_t) 'S') +/* Austria */ +#define COUNTRY_CODE_AT (((uint16_t) 'A' << 8) | (uint16_t) 'T') +/* Australia */ +#define COUNTRY_CODE_AU (((uint16_t) 'A' << 8) | (uint16_t) 'U') +/* Aruba */ +#define COUNTRY_CODE_AW (((uint16_t) 'A' << 8) | (uint16_t) 'W') +/* Azerbaijan */ +#define COUNTRY_CODE_AZ (((uint16_t) 'A' << 8) | (uint16_t) 'Z') +/* Bosnia and Herzegovina */ +#define COUNTRY_CODE_BA (((uint16_t) 'B' << 8) | (uint16_t) 'A') +/* Barbados */ +#define COUNTRY_CODE_BB (((uint16_t) 'B' << 8) | (uint16_t) 'B') +/* Bangladesh */ +#define COUNTRY_CODE_BD (((uint16_t) 'B' << 8) | (uint16_t) 'D') +/* Belgium */ +#define COUNTRY_CODE_BE (((uint16_t) 'B' << 8) | (uint16_t) 'E') +/* Burkina Faso */ +#define COUNTRY_CODE_BF (((uint16_t) 'B' << 8) | (uint16_t) 'F') +/* Bulgaria */ +#define COUNTRY_CODE_BG (((uint16_t) 'B' << 8) | (uint16_t) 'G') +/* Bahrain */ +#define COUNTRY_CODE_BH (((uint16_t) 'B' << 8) | (uint16_t) 'H') +/* Burundi */ +#define COUNTRY_CODE_BI (((uint16_t) 'B' << 8) | (uint16_t) 'I') +/* Benin */ +#define COUNTRY_CODE_BJ (((uint16_t) 'B' << 8) | (uint16_t) 'J') +/* Bermuda */ +#define COUNTRY_CODE_BM (((uint16_t) 'B' << 8) | (uint16_t) 'M') +/* Brunei */ +#define COUNTRY_CODE_BN (((uint16_t) 'B' << 8) | (uint16_t) 'N') +/* Bolivia */ +#define COUNTRY_CODE_BO (((uint16_t) 'B' << 8) | (uint16_t) 'O') +/* Brazil */ +#define COUNTRY_CODE_BR (((uint16_t) 'B' << 8) | (uint16_t) 'R') +/* Bahamas */ +#define COUNTRY_CODE_BS (((uint16_t) 'B' << 8) | (uint16_t) 'S') +/* Bhutan */ +#define COUNTRY_CODE_BT (((uint16_t) 'B' << 8) | (uint16_t) 'T') +/* Botswana */ +#define COUNTRY_CODE_BW (((uint16_t) 'B' << 8) | (uint16_t) 'W') +/* Belarus */ +#define COUNTRY_CODE_BY (((uint16_t) 'B' << 8) | (uint16_t) 'Y') +/* Belize */ +#define COUNTRY_CODE_BZ (((uint16_t) 'B' << 8) | (uint16_t) 'Z') +/* Canada */ +#define COUNTRY_CODE_CA (((uint16_t) 'C' << 8) | (uint16_t) 'A') +/* Democratic Republic of the Congo */ +#define COUNTRY_CODE_CD (((uint16_t) 'C' << 8) | (uint16_t) 'D') +/* Central African Republic */ +#define COUNTRY_CODE_CF (((uint16_t) 'C' << 8) | (uint16_t) 'F') +/* Republic of the Congo */ +#define COUNTRY_CODE_CG (((uint16_t) 'C' << 8) | (uint16_t) 'G') +/* Switzerland */ +#define COUNTRY_CODE_CH (((uint16_t) 'C' << 8) | (uint16_t) 'H') +/* Cote d'lvoire */ +#define COUNTRY_CODE_CI (((uint16_t) 'C' << 8) | (uint16_t) 'I') +/* Cook Island */ +#define COUNTRY_CODE_CK (((uint16_t) 'C' << 8) | (uint16_t) 'K') +/* Chile */ +#define COUNTRY_CODE_CL (((uint16_t) 'C' << 8) | (uint16_t) 'L') +/* Cameroon */ +#define COUNTRY_CODE_CM (((uint16_t) 'C' << 8) | (uint16_t) 'M') +/* China */ +#define COUNTRY_CODE_CN (((uint16_t) 'C' << 8) | (uint16_t) 'N') +/* Columbia */ +#define COUNTRY_CODE_CO (((uint16_t) 'C' << 8) | (uint16_t) 'O') +/* Costa Rica */ +#define COUNTRY_CODE_CR (((uint16_t) 'C' << 8) | (uint16_t) 'R') +/* Cuba */ +#define COUNTRY_CODE_CU (((uint16_t) 'C' << 8) | (uint16_t) 'U') +/* Cape Verde */ +#define COUNTRY_CODE_CV (((uint16_t) 'C' << 8) | (uint16_t) 'V') +/* "Christmas Island(Australia) */ +#define COUNTRY_CODE_CX (((uint16_t) 'C' << 8) | (uint16_t) 'X') +/* Cyprus */ +#define COUNTRY_CODE_CY (((uint16_t) 'C' << 8) | (uint16_t) 'Y') +/* Czech */ +#define COUNTRY_CODE_CZ (((uint16_t) 'C' << 8) | (uint16_t) 'Z') +/* Germany */ +#define COUNTRY_CODE_DE (((uint16_t) 'D' << 8) | (uint16_t) 'E') +/* Djibouti */ +#define COUNTRY_CODE_DJ (((uint16_t) 'D' << 8) | (uint16_t) 'J') +/* Denmark */ +#define COUNTRY_CODE_DK (((uint16_t) 'D' << 8) | (uint16_t) 'K') +/* Dominica */ +#define COUNTRY_CODE_DM (((uint16_t) 'D' << 8) | (uint16_t) 'M') +/* Dominican Republic */ +#define COUNTRY_CODE_DO (((uint16_t) 'D' << 8) | (uint16_t) 'O') +/* Algeria */ +#define COUNTRY_CODE_DZ (((uint16_t) 'D' << 8) | (uint16_t) 'Z') +/* Ecuador */ +#define COUNTRY_CODE_EC (((uint16_t) 'E' << 8) | (uint16_t) 'C') +/* Estonia */ +#define COUNTRY_CODE_EE (((uint16_t) 'E' << 8) | (uint16_t) 'E') +/* Egypt */ +#define COUNTRY_CODE_EG (((uint16_t) 'E' << 8) | (uint16_t) 'G') +/* Western Sahara (Morocco) */ +#define COUNTRY_CODE_EH (((uint16_t) 'E' << 8) | (uint16_t) 'H') +/* Eritrea */ +#define COUNTRY_CODE_ER (((uint16_t) 'E' << 8) | (uint16_t) 'R') +/* Spain */ +#define COUNTRY_CODE_ES (((uint16_t) 'E' << 8) | (uint16_t) 'S') +/* Ethiopia */ +#define COUNTRY_CODE_ET (((uint16_t) 'E' << 8) | (uint16_t) 'T') +/* Europe */ +#define COUNTRY_CODE_EU (((uint16_t) 'E' << 8) | (uint16_t) 'U') +/* Finland */ +#define COUNTRY_CODE_FI (((uint16_t) 'F' << 8) | (uint16_t) 'I') +/* Fiji */ +#define COUNTRY_CODE_FJ (((uint16_t) 'F' << 8) | (uint16_t) 'J') +/* Falkland Island */ +#define COUNTRY_CODE_FK (((uint16_t) 'F' << 8) | (uint16_t) 'K') +/* Micronesia */ +#define COUNTRY_CODE_FM (((uint16_t) 'F' << 8) | (uint16_t) 'M') +/* Faroe Island */ +#define COUNTRY_CODE_FO (((uint16_t) 'F' << 8) | (uint16_t) 'O') +/* France */ +#define COUNTRY_CODE_FR (((uint16_t) 'F' << 8) | (uint16_t) 'R') +/* Wallis and Futuna (France) */ +#define COUNTRY_CODE_FR (((uint16_t) 'F' << 8) | (uint16_t) 'R') +/* Gabon */ +#define COUNTRY_CODE_GA (((uint16_t) 'G' << 8) | (uint16_t) 'A') +/* United Kingdom */ +#define COUNTRY_CODE_GB (((uint16_t) 'G' << 8) | (uint16_t) 'B') +/* Grenada */ +#define COUNTRY_CODE_GD (((uint16_t) 'G' << 8) | (uint16_t) 'D') +/* Georgia */ +#define COUNTRY_CODE_GE (((uint16_t) 'G' << 8) | (uint16_t) 'E') +/* French Guiana */ +#define COUNTRY_CODE_GF (((uint16_t) 'G' << 8) | (uint16_t) 'F') +/* Guernsey */ +#define COUNTRY_CODE_GG (((uint16_t) 'G' << 8) | (uint16_t) 'G') +/* Ghana */ +#define COUNTRY_CODE_GH (((uint16_t) 'G' << 8) | (uint16_t) 'H') +/* Gibraltar */ +#define COUNTRY_CODE_GI (((uint16_t) 'G' << 8) | (uint16_t) 'I') +/* Gambia */ +#define COUNTRY_CODE_GM (((uint16_t) 'G' << 8) | (uint16_t) 'M') +/* Guinea */ +#define COUNTRY_CODE_GN (((uint16_t) 'G' << 8) | (uint16_t) 'N') +/* Guadeloupe */ +#define COUNTRY_CODE_GP (((uint16_t) 'G' << 8) | (uint16_t) 'P') +/* Equatorial Guinea */ +#define COUNTRY_CODE_GQ (((uint16_t) 'G' << 8) | (uint16_t) 'Q') +/* Greece */ +#define COUNTRY_CODE_GR (((uint16_t) 'G' << 8) | (uint16_t) 'R') +/* Guatemala */ +#define COUNTRY_CODE_GT (((uint16_t) 'G' << 8) | (uint16_t) 'T') +/* Guam */ +#define COUNTRY_CODE_GU (((uint16_t) 'G' << 8) | (uint16_t) 'U') +/* Guinea-Bissau */ +#define COUNTRY_CODE_GW (((uint16_t) 'G' << 8) | (uint16_t) 'W') +/* Guyana */ +#define COUNTRY_CODE_GY (((uint16_t) 'G' << 8) | (uint16_t) 'Y') +/* Hong Kong */ +#define COUNTRY_CODE_HK (((uint16_t) 'H' << 8) | (uint16_t) 'K') +/* Honduras */ +#define COUNTRY_CODE_HN (((uint16_t) 'H' << 8) | (uint16_t) 'N') +/* Croatia */ +#define COUNTRY_CODE_HR (((uint16_t) 'H' << 8) | (uint16_t) 'R') +/* Haiti */ +#define COUNTRY_CODE_HT (((uint16_t) 'H' << 8) | (uint16_t) 'T') +/* Hungary */ +#define COUNTRY_CODE_HU (((uint16_t) 'H' << 8) | (uint16_t) 'U') +/* Indonesia */ +#define COUNTRY_CODE_ID (((uint16_t) 'I' << 8) | (uint16_t) 'D') +/* Ireland */ +#define COUNTRY_CODE_IE (((uint16_t) 'I' << 8) | (uint16_t) 'E') +/* Israel */ +#define COUNTRY_CODE_IL (((uint16_t) 'I' << 8) | (uint16_t) 'L') +/* Isle of Man */ +#define COUNTRY_CODE_IM (((uint16_t) 'I' << 8) | (uint16_t) 'M') +/* India */ +#define COUNTRY_CODE_IN (((uint16_t) 'I' << 8) | (uint16_t) 'N') +/* Iraq */ +#define COUNTRY_CODE_IQ (((uint16_t) 'I' << 8) | (uint16_t) 'Q') +/* Iran */ +#define COUNTRY_CODE_IR (((uint16_t) 'I' << 8) | (uint16_t) 'R') +/* Iceland */ +#define COUNTRY_CODE_IS (((uint16_t) 'I' << 8) | (uint16_t) 'S') +/* Italy */ +#define COUNTRY_CODE_IT (((uint16_t) 'I' << 8) | (uint16_t) 'T') +/* Jersey */ +#define COUNTRY_CODE_JE (((uint16_t) 'J' << 8) | (uint16_t) 'E') +/* Jameica */ +#define COUNTRY_CODE_JM (((uint16_t) 'J' << 8) | (uint16_t) 'M') +/* Jordan */ +#define COUNTRY_CODE_JO (((uint16_t) 'J' << 8) | (uint16_t) 'O') +/* Japan */ +#define COUNTRY_CODE_JP (((uint16_t) 'J' << 8) | (uint16_t) 'P') +/* Kenya */ +#define COUNTRY_CODE_KE (((uint16_t) 'K' << 8) | (uint16_t) 'E') +/* Kyrgyzstan */ +#define COUNTRY_CODE_KG (((uint16_t) 'K' << 8) | (uint16_t) 'G') +/* Cambodia */ +#define COUNTRY_CODE_KH (((uint16_t) 'K' << 8) | (uint16_t) 'H') +/* Kiribati */ +#define COUNTRY_CODE_KI (((uint16_t) 'K' << 8) | (uint16_t) 'I') +/* Comoros */ +#define COUNTRY_CODE_KM (((uint16_t) 'K' << 8) | (uint16_t) 'M') +/* Saint Kitts and Nevis */ +#define COUNTRY_CODE_KN (((uint16_t) 'K' << 8) | (uint16_t) 'N') +/* North Korea */ +#define COUNTRY_CODE_KP (((uint16_t) 'K' << 8) | (uint16_t) 'P') +/* South Korea */ +#define COUNTRY_CODE_KR (((uint16_t) 'K' << 8) | (uint16_t) 'R') +/* Kuwait */ +#define COUNTRY_CODE_KW (((uint16_t) 'K' << 8) | (uint16_t) 'W') +/* Cayman Islands */ +#define COUNTRY_CODE_KY (((uint16_t) 'K' << 8) | (uint16_t) 'Y') +/* Kazakhstan */ +#define COUNTRY_CODE_KZ (((uint16_t) 'K' << 8) | (uint16_t) 'Z') +/* Laos */ +#define COUNTRY_CODE_LA (((uint16_t) 'L' << 8) | (uint16_t) 'A') +/* Lebanon */ +#define COUNTRY_CODE_LB (((uint16_t) 'L' << 8) | (uint16_t) 'B') +/* Saint Lucia */ +#define COUNTRY_CODE_LC (((uint16_t) 'L' << 8) | (uint16_t) 'C') +/* Liechtenstein */ +#define COUNTRY_CODE_LI (((uint16_t) 'L' << 8) | (uint16_t) 'I') +/* Sri Lanka */ +#define COUNTRY_CODE_LK (((uint16_t) 'L' << 8) | (uint16_t) 'K') +/* Liberia */ +#define COUNTRY_CODE_LR (((uint16_t) 'L' << 8) | (uint16_t) 'R') +/* Lesotho */ +#define COUNTRY_CODE_LS (((uint16_t) 'L' << 8) | (uint16_t) 'S') +/* Lithuania */ +#define COUNTRY_CODE_LT (((uint16_t) 'L' << 8) | (uint16_t) 'T') +/* Luxemburg */ +#define COUNTRY_CODE_LU (((uint16_t) 'L' << 8) | (uint16_t) 'U') +/* Latvia */ +#define COUNTRY_CODE_LV (((uint16_t) 'L' << 8) | (uint16_t) 'V') +/* Libya */ +#define COUNTRY_CODE_LY (((uint16_t) 'L' << 8) | (uint16_t) 'Y') +/* Morocco */ +#define COUNTRY_CODE_MA (((uint16_t) 'M' << 8) | (uint16_t) 'A') +/* Monaco */ +#define COUNTRY_CODE_MC (((uint16_t) 'M' << 8) | (uint16_t) 'C') +/* Moldova */ +#define COUNTRY_CODE_MD (((uint16_t) 'M' << 8) | (uint16_t) 'D') +/* Montenegro */ +#define COUNTRY_CODE_ME (((uint16_t) 'M' << 8) | (uint16_t) 'E') +/* Saint Martin / Sint Marteen (Added on window's list) */ +#define COUNTRY_CODE_MF (((uint16_t) 'M' << 8) | (uint16_t) 'F') +/* Madagascar */ +#define COUNTRY_CODE_MG (((uint16_t) 'M' << 8) | (uint16_t) 'G') +/* Marshall Islands */ +#define COUNTRY_CODE_MH (((uint16_t) 'M' << 8) | (uint16_t) 'H') +/* Macedonia */ +#define COUNTRY_CODE_MK (((uint16_t) 'M' << 8) | (uint16_t) 'K') +/* Mali */ +#define COUNTRY_CODE_ML (((uint16_t) 'M' << 8) | (uint16_t) 'L') +/* Myanmar */ +#define COUNTRY_CODE_MM (((uint16_t) 'M' << 8) | (uint16_t) 'M') +/* Mongolia */ +#define COUNTRY_CODE_MN (((uint16_t) 'M' << 8) | (uint16_t) 'N') +/* Macao */ +#define COUNTRY_CODE_MO (((uint16_t) 'M' << 8) | (uint16_t) 'O') +/* Northern Mariana Islands (Rota Island Saipan and Tinian Island) */ +#define COUNTRY_CODE_MP (((uint16_t) 'M' << 8) | (uint16_t) 'P') +/* Martinique (France) */ +#define COUNTRY_CODE_MQ (((uint16_t) 'M' << 8) | (uint16_t) 'Q') +/* Mauritania */ +#define COUNTRY_CODE_MR (((uint16_t) 'M' << 8) | (uint16_t) 'R') +/* Montserrat (UK) */ +#define COUNTRY_CODE_MS (((uint16_t) 'M' << 8) | (uint16_t) 'S') +/* Malta */ +#define COUNTRY_CODE_MT (((uint16_t) 'M' << 8) | (uint16_t) 'T') +/* Mauritius */ +#define COUNTRY_CODE_MU (((uint16_t) 'M' << 8) | (uint16_t) 'U') +/* Maldives */ +#define COUNTRY_CODE_MV (((uint16_t) 'M' << 8) | (uint16_t) 'V') +/* Malawi */ +#define COUNTRY_CODE_MW (((uint16_t) 'M' << 8) | (uint16_t) 'W') +/* Mexico */ +#define COUNTRY_CODE_MX (((uint16_t) 'M' << 8) | (uint16_t) 'X') +/* Malaysia */ +#define COUNTRY_CODE_MY (((uint16_t) 'M' << 8) | (uint16_t) 'Y') +/* Mozambique */ +#define COUNTRY_CODE_MZ (((uint16_t) 'M' << 8) | (uint16_t) 'Z') +/* Namibia */ +#define COUNTRY_CODE_NA (((uint16_t) 'N' << 8) | (uint16_t) 'A') +/* New Caledonia */ +#define COUNTRY_CODE_NC (((uint16_t) 'N' << 8) | (uint16_t) 'C') +/* Niger */ +#define COUNTRY_CODE_NE (((uint16_t) 'N' << 8) | (uint16_t) 'E') +/* Norfolk Island */ +#define COUNTRY_CODE_NF (((uint16_t) 'N' << 8) | (uint16_t) 'F') +/* Nigeria */ +#define COUNTRY_CODE_NG (((uint16_t) 'N' << 8) | (uint16_t) 'G') +/* Nicaragua */ +#define COUNTRY_CODE_NI (((uint16_t) 'N' << 8) | (uint16_t) 'I') +/* Netherlands */ +#define COUNTRY_CODE_NL (((uint16_t) 'N' << 8) | (uint16_t) 'L') +/* Norway */ +#define COUNTRY_CODE_NO (((uint16_t) 'N' << 8) | (uint16_t) 'O') +/* Nepal */ +#define COUNTRY_CODE_NP (((uint16_t) 'N' << 8) | (uint16_t) 'P') +/* Nauru */ +#define COUNTRY_CODE_NR (((uint16_t) 'N' << 8) | (uint16_t) 'R') +/* Niue */ +#define COUNTRY_CODE_NU (((uint16_t) 'N' << 8) | (uint16_t) 'U') +/* New Zealand */ +#define COUNTRY_CODE_NZ (((uint16_t) 'N' << 8) | (uint16_t) 'Z') +/* Oman */ +#define COUNTRY_CODE_OM (((uint16_t) 'O' << 8) | (uint16_t) 'M') +/* Panama */ +#define COUNTRY_CODE_PA (((uint16_t) 'P' << 8) | (uint16_t) 'A') +/* Peru */ +#define COUNTRY_CODE_PE (((uint16_t) 'P' << 8) | (uint16_t) 'E') +/* "French Polynesia */ +#define COUNTRY_CODE_PF (((uint16_t) 'P' << 8) | (uint16_t) 'F') +/* Papua New Guinea */ +#define COUNTRY_CODE_PG (((uint16_t) 'P' << 8) | (uint16_t) 'G') +/* Philippines */ +#define COUNTRY_CODE_PH (((uint16_t) 'P' << 8) | (uint16_t) 'H') +/* Pakistan */ +#define COUNTRY_CODE_PK (((uint16_t) 'P' << 8) | (uint16_t) 'K') +/* Poland */ +#define COUNTRY_CODE_PL (((uint16_t) 'P' << 8) | (uint16_t) 'L') +/* Saint Pierre and Miquelon */ +#define COUNTRY_CODE_PM (((uint16_t) 'P' << 8) | (uint16_t) 'M') +/* Pitcairn Islands */ +#define COUNTRY_CODE_PN (((uint16_t) 'P' << 8) | (uint16_t) 'N') +/* Puerto Rico (USA) */ +#define COUNTRY_CODE_PR (((uint16_t) 'P' << 8) | (uint16_t) 'R') +/* Palestinian Authority */ +#define COUNTRY_CODE_PS (((uint16_t) 'P' << 8) | (uint16_t) 'S') +/* Portugal */ +#define COUNTRY_CODE_PT (((uint16_t) 'P' << 8) | (uint16_t) 'T') +/* Palau */ +#define COUNTRY_CODE_PW (((uint16_t) 'P' << 8) | (uint16_t) 'W') +/* Paraguay */ +#define COUNTRY_CODE_PY (((uint16_t) 'P' << 8) | (uint16_t) 'Y') +/* Qatar */ +#define COUNTRY_CODE_QA (((uint16_t) 'Q' << 8) | (uint16_t) 'A') +/* Reunion (France) */ +#define COUNTRY_CODE_RE (((uint16_t) 'R' << 8) | (uint16_t) 'E') +/* Kosvo (Added on window's list) */ +#define COUNTRY_CODE_RKS (((uint16_t) 'R' << 8) | (uint16_t) 'K') +/* Romania */ +#define COUNTRY_CODE_RO (((uint16_t) 'R' << 8) | (uint16_t) 'O') +/* Serbia */ +#define COUNTRY_CODE_RS (((uint16_t) 'R' << 8) | (uint16_t) 'S') +/* Russia */ +#define COUNTRY_CODE_RU (((uint16_t) 'R' << 8) | (uint16_t) 'U') +/* Rwanda */ +#define COUNTRY_CODE_RW (((uint16_t) 'R' << 8) | (uint16_t) 'W') +/* Saudi Arabia */ +#define COUNTRY_CODE_SA (((uint16_t) 'S' << 8) | (uint16_t) 'A') +/* Solomon Islands */ +#define COUNTRY_CODE_SB (((uint16_t) 'S' << 8) | (uint16_t) 'B') +/* Seychelles */ +#define COUNTRY_CODE_SC (((uint16_t) 'S' << 8) | (uint16_t) 'C') +/* Sudan */ +#define COUNTRY_CODE_SD (((uint16_t) 'S' << 8) | (uint16_t) 'D') +/* Sweden */ +#define COUNTRY_CODE_SE (((uint16_t) 'S' << 8) | (uint16_t) 'E') +/* Singapole */ +#define COUNTRY_CODE_SG (((uint16_t) 'S' << 8) | (uint16_t) 'G') +/* Slovenia */ +#define COUNTRY_CODE_SI (((uint16_t) 'S' << 8) | (uint16_t) 'I') +/* Slovakia */ +#define COUNTRY_CODE_SK (((uint16_t) 'S' << 8) | (uint16_t) 'K') +/* Sierra Leone */ +#define COUNTRY_CODE_SL (((uint16_t) 'S' << 8) | (uint16_t) 'L') +/* San Marino */ +#define COUNTRY_CODE_SM (((uint16_t) 'S' << 8) | (uint16_t) 'M') +/* Senegal */ +#define COUNTRY_CODE_SN (((uint16_t) 'S' << 8) | (uint16_t) 'N') +/* Somalia */ +#define COUNTRY_CODE_SO (((uint16_t) 'S' << 8) | (uint16_t) 'O') +/* Suriname */ +#define COUNTRY_CODE_SR (((uint16_t) 'S' << 8) | (uint16_t) 'R') +/* South_Sudan */ +#define COUNTRY_CODE_SS (((uint16_t) 'S' << 8) | (uint16_t) 'S') +/* Sao Tome and Principe */ +#define COUNTRY_CODE_ST (((uint16_t) 'S' << 8) | (uint16_t) 'T') +/* El Salvador */ +#define COUNTRY_CODE_SV (((uint16_t) 'S' << 8) | (uint16_t) 'V') +/* Syria */ +#define COUNTRY_CODE_SY (((uint16_t) 'S' << 8) | (uint16_t) 'Y') +/* Swaziland */ +#define COUNTRY_CODE_SZ (((uint16_t) 'S' << 8) | (uint16_t) 'Z') +/* Turks and Caicos Islands (UK) */ +#define COUNTRY_CODE_TC (((uint16_t) 'T' << 8) | (uint16_t) 'C') +/* Chad */ +#define COUNTRY_CODE_TD (((uint16_t) 'T' << 8) | (uint16_t) 'D') +/* French Southern and Antarctic Lands */ +#define COUNTRY_CODE_TF (((uint16_t) 'T' << 8) | (uint16_t) 'F') +/* Togo */ +#define COUNTRY_CODE_TG (((uint16_t) 'T' << 8) | (uint16_t) 'G') +/* Thailand */ +#define COUNTRY_CODE_TH (((uint16_t) 'T' << 8) | (uint16_t) 'H') +/* Tajikistan */ +#define COUNTRY_CODE_TJ (((uint16_t) 'T' << 8) | (uint16_t) 'J') +/* East Timor */ +#define COUNTRY_CODE_TL (((uint16_t) 'T' << 8) | (uint16_t) 'L') +/* Turkmenistan */ +#define COUNTRY_CODE_TM (((uint16_t) 'T' << 8) | (uint16_t) 'M') +/* Tunisia */ +#define COUNTRY_CODE_TN (((uint16_t) 'T' << 8) | (uint16_t) 'N') +/* Tonga */ +#define COUNTRY_CODE_TO (((uint16_t) 'T' << 8) | (uint16_t) 'O') +/* Turkey */ +#define COUNTRY_CODE_TR (((uint16_t) 'T' << 8) | (uint16_t) 'R') +/* Trinidad and Tobago */ +#define COUNTRY_CODE_TT (((uint16_t) 'T' << 8) | (uint16_t) 'T') +/* Tuvalu */ +#define COUNTRY_CODE_TV (((uint16_t) 'T' << 8) | (uint16_t) 'V') +/* Taiwan */ +#define COUNTRY_CODE_TW (((uint16_t) 'T' << 8) | (uint16_t) 'W') +/* Tanzania */ +#define COUNTRY_CODE_TZ (((uint16_t) 'T' << 8) | (uint16_t) 'Z') +/* Ukraine */ +#define COUNTRY_CODE_UA (((uint16_t) 'U' << 8) | (uint16_t) 'A') +/* Ugnada */ +#define COUNTRY_CODE_UG (((uint16_t) 'U' << 8) | (uint16_t) 'G') +/* US */ +#define COUNTRY_CODE_US (((uint16_t) 'U' << 8) | (uint16_t) 'S') +/* Uruguay */ +#define COUNTRY_CODE_UY (((uint16_t) 'U' << 8) | (uint16_t) 'Y') +/* Uzbekistan */ +#define COUNTRY_CODE_UZ (((uint16_t) 'U' << 8) | (uint16_t) 'Z') +/* Vatican (Holy See) */ +#define COUNTRY_CODE_VA (((uint16_t) 'V' << 8) | (uint16_t) 'A') +/* Saint Vincent and the Grenadines */ +#define COUNTRY_CODE_VC (((uint16_t) 'V' << 8) | (uint16_t) 'C') +/* Venezuela */ +#define COUNTRY_CODE_VE (((uint16_t) 'V' << 8) | (uint16_t) 'E') +/* British Virgin Islands */ +#define COUNTRY_CODE_VG (((uint16_t) 'V' << 8) | (uint16_t) 'G') +/* US Virgin Islands */ +#define COUNTRY_CODE_VI (((uint16_t) 'V' << 8) | (uint16_t) 'I') +/* Vietnam */ +#define COUNTRY_CODE_VN (((uint16_t) 'V' << 8) | (uint16_t) 'N') +/* Vanuatu */ +#define COUNTRY_CODE_VU (((uint16_t) 'V' << 8) | (uint16_t) 'U') +/* Samoa */ +#define COUNTRY_CODE_WS (((uint16_t) 'W' << 8) | (uint16_t) 'S') +/* Yemen */ +#define COUNTRY_CODE_YE (((uint16_t) 'Y' << 8) | (uint16_t) 'E') +/* Mayotte (France) */ +#define COUNTRY_CODE_YT (((uint16_t) 'Y' << 8) | (uint16_t) 'T') +/* South Africa */ +#define COUNTRY_CODE_ZA (((uint16_t) 'Z' << 8) | (uint16_t) 'A') +/* Zambia */ +#define COUNTRY_CODE_ZM (((uint16_t) 'Z' << 8) | (uint16_t) 'M') +/* Zimbabwe */ +#define COUNTRY_CODE_ZW (((uint16_t) 'Z' << 8) | (uint16_t) 'W') +/* Default country domain */ +#define COUNTRY_CODE_DF (((uint16_t) 'D' << 8) | (uint16_t) 'F') +/* World Wide */ +#define COUNTRY_CODE_WW (((uint16_t) '0' << 8) | (uint16_t) '0') + + +/* dot11RegDomainsSupportValue */ +#define MIB_REG_DOMAIN_FCC 0x10 /* FCC (US) */ +#define MIB_REG_DOMAIN_IC 0x20 /* IC or DOC (Canada) */ +#define MIB_REG_DOMAIN_ETSI 0x30 /* ETSI (Europe) */ +#define MIB_REG_DOMAIN_SPAIN 0x31 /* Spain */ +#define MIB_REG_DOMAIN_FRANCE 0x32 /* France */ +#define MIB_REG_DOMAIN_JAPAN 0x40 /* MPHPT (Japan) */ +#define MIB_REG_DOMAIN_OTHER 0x00 /* other */ + +/*2.4G*/ +#define BAND_2G4_LOWER_BOUND 1 +#define BAND_2G4_UPPER_BOUND 14 +/*5G SubBand FCC spec*/ +#define UNII1_LOWER_BOUND 36 +#define UNII1_UPPER_BOUND 48 +#define UNII2A_LOWER_BOUND 52 +#define UNII2A_UPPER_BOUND 64 +#define UNII2C_LOWER_BOUND 100 +#define UNII2C_UPPER_BOUND 144 +#define UNII3_LOWER_BOUND 149 +#define UNII3_UPPER_BOUND 165 + +#if CFG_SUPPORT_PWR_LIMIT_COUNTRY +#define POWER_LIMIT_TABLE_NULL 0xFFFF +#define MAX_TX_POWER 63 +#define MIN_TX_POWER -64 +/*align Frimware Max Power Limit CH Num*/ +#define MAX_CMD_SUPPORT_CHANNEL_NUM 64 +#endif + +#if (CFG_SUPPORT_SINGLE_SKU == 1) +/* ARRAY_SIZE(mtk_2ghz_channels) + ARRAY_SIZE(mtk_5ghz_channels) */ +#define MAX_SUPPORTED_CH_COUNT (MAX_CHN_NUM) +#define REG_RULE_LIGHT(start, end, bw, reg_flags) \ + REG_RULE(start, end, bw, 0, 0, reg_flags) +#endif + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +#if CFG_SUPPORT_PWR_LIMIT_COUNTRY + +/* Define Tx Power Control Channel Type */ +#define MAX_TX_PWR_CTRL_ELEMENT_NAME_SIZE 16 +#define PWR_CTRL_CHNL_TYPE_KEY_ALL "ALL" +#define PWR_CTRL_CHNL_TYPE_KEY_2G4 "2G4" +#define PWR_CTRL_CHNL_TYPE_KEY_5G "5G" +#define PWR_CTRL_CHNL_TYPE_KEY_BANDEDGE_2G4 "BANDEDGE2G4" +#define PWR_CTRL_CHNL_TYPE_KEY_BANDEDGE_5G "BANDEDGE5G" +#define PWR_CTRL_CHNL_TYPE_KEY_5G_BAND1 "5GBAND1" +#define PWR_CTRL_CHNL_TYPE_KEY_5G_BAND2 "5GBAND2" +#define PWR_CTRL_CHNL_TYPE_KEY_5G_BAND3 "5GBAND3" +#define PWR_CTRL_CHNL_TYPE_KEY_5G_BAND4 "5GBAND4" + +#define PWR_CFG_PRAM_NUM_ALL_RATE 1 + +#define PWR_CFG_PRAM_NUM_AX 18 +#if (CFG_SUPPORT_DYNA_TX_PWR_CTRL_OFDM_SETTING == 1) +#define PWR_CFG_PRAM_NUM_AC 11 +#else +#define PWR_CFG_PRAM_NUM_AC 9 +#endif /* CFG_SUPPORT_DYNA_TX_PWR_CTRL_OFDM_SETTING */ + +enum ENUM_TX_POWER_CTRL_LIST_TYPE { + PWR_CTRL_TYPE_DEFAULT_LIST = 0, + PWR_CTRL_TYPE_DYNAMIC_LIST, + PWR_CTRL_TYPE_ALL_LIST, +}; + +enum ENUM_TX_POWER_CTRL_APPLIED_WAY { + PWR_CTRL_TYPE_APPLIED_WAY_WIFION = 1, + PWR_CTRL_TYPE_APPLIED_WAY_IOCTL, +}; + +enum ENUM_TX_POWER_CTRL_OPERATION { + PWR_CTRL_TYPE_OPERATION_POWER_LEVEL = 1, + PWR_CTRL_TYPE_OPERATION_POWER_OFFSET, +}; + +enum ENUM_TX_POWER_CTRL_TYPE { + PWR_CTRL_TYPE_WIFION_POWER_LEVEL = 1, + PWR_CTRL_TYPE_WIFION_POWER_OFFSET, + PWR_CTRL_TYPE_IOCTL_POWER_LEVEL, + PWR_CTRL_TYPE_IOCTL_POWER_OFFSET, +}; + +enum ENUM_TX_POWER_CTRL_VALUE_SIGN { + PWR_CTRL_TYPE_NO_ACTION = 0, + PWR_CTRL_TYPE_POSITIVE, + PWR_CTRL_TYPE_NEGATIVE, +}; + +enum ENUM_TX_POWER_CTRL_CHANNEL_TYPE { + PWR_CTRL_CHNL_TYPE_NORMAL = 0, + PWR_CTRL_CHNL_TYPE_ALL, + PWR_CTRL_CHNL_TYPE_RANGE, + PWR_CTRL_CHNL_TYPE_2G4, + PWR_CTRL_CHNL_TYPE_5G, + PWR_CTRL_CHNL_TYPE_BANDEDGE_2G4, + PWR_CTRL_CHNL_TYPE_BANDEDGE_5G, + PWR_CTRL_CHNL_TYPE_5G_BAND1, + PWR_CTRL_CHNL_TYPE_5G_BAND2, + PWR_CTRL_CHNL_TYPE_5G_BAND3, + PWR_CTRL_CHNL_TYPE_5G_BAND4, +}; + +enum ENUM_POWER_LIMIT { + PWR_LIMIT_CCK, +#if (CFG_SUPPORT_DYNA_TX_PWR_CTRL_OFDM_SETTING == 1) + PWR_LIMIT_OFDM_L, + PWR_LIMIT_OFDM_H, +#endif /* CFG_SUPPORT_DYNA_TX_PWR_CTRL_OFDM_SETTING */ + PWR_LIMIT_20M_L, + PWR_LIMIT_20M_H, + PWR_LIMIT_40M_L, + PWR_LIMIT_40M_H, + PWR_LIMIT_80M_L, + PWR_LIMIT_80M_H, + PWR_LIMIT_160M_L, + PWR_LIMIT_160M_H, + PWR_LIMIT_NUM +}; +enum ENUM_POWER_LIMIT_HE { + PWR_LIMIT_RU26_L, /* MCS0~4 */ + PWR_LIMIT_RU26_H, /* MCS5~9 */ + PWR_LIMIT_RU26_U, /* MCS10~11 */ + + PWR_LIMIT_RU52_L, /* MCS0~4 */ + PWR_LIMIT_RU52_H, /* MCS5~9 */ + PWR_LIMIT_RU52_U, /* MCS10~11 */ + + PWR_LIMIT_RU106_L, /* MCS0~4 */ + PWR_LIMIT_RU106_H, /* MCS5~9 */ + PWR_LIMIT_RU106_U, /* MCS10~11 */ + + PWR_LIMIT_RU242_L, /* MCS0~4 */ + PWR_LIMIT_RU242_H, /* MCS5~9 */ + PWR_LIMIT_RU242_U, /* MCS10~11 */ + + PWR_LIMIT_RU484_L, /* MCS0~4 */ + PWR_LIMIT_RU484_H, /* MCS5~9 */ + PWR_LIMIT_RU484_U, /* MCS10~11 */ + + PWR_LIMIT_RU996_L, /* MCS0~4 */ + PWR_LIMIT_RU996_H, /* MCS5~9 */ + PWR_LIMIT_RU996_U, /* MCS10~11 */ + PWR_LIMIT_HE_NUM +}; + +struct TX_PWR_CTRL_CHANNEL_SETTING { + enum ENUM_TX_POWER_CTRL_CHANNEL_TYPE eChnlType; + uint8_t channelParam[2]; + + enum ENUM_TX_POWER_CTRL_VALUE_SIGN op[PWR_LIMIT_NUM]; + int8_t i8PwrLimit[PWR_LIMIT_NUM]; + + enum ENUM_TX_POWER_CTRL_VALUE_SIGN opHE[PWR_LIMIT_HE_NUM]; + int8_t i8PwrLimitHE[PWR_LIMIT_HE_NUM]; +}; + +struct TX_PWR_CTRL_ELEMENT { + struct LINK_ENTRY node; + u_int8_t fgApplied; + char name[MAX_TX_PWR_CTRL_ELEMENT_NAME_SIZE]; /* scenario name */ + uint8_t index; /* scenario index */ + enum ENUM_TX_POWER_CTRL_TYPE eCtrlType; + uint8_t settingCount; + struct TX_PWR_CTRL_CHANNEL_SETTING rChlSettingList[1]; +}; + +struct PARAM_TX_PWR_CTRL_IOCTL { + u_int8_t fgApplied; + uint8_t *name; + uint8_t index; + uint8_t *newSetting; +}; + +#endif + +enum ENUM_POWER_LIMIT_SUBBAND { + POWER_LIMIT_2G4 = 0, + POWER_LIMIT_UNII1 = 1, + POWER_LIMIT_UNII2A = 2, + POWER_LIMIT_UNII2C = 3, + POWER_LIMIT_UNII3 = 4, + POWER_LIMIT_SUBAND_NUM +}; + +/* Define channel offset in unit of 5MHz bandwidth */ +enum ENUM_CHNL_SPAN { + CHNL_SPAN_5 = 1, + CHNL_SPAN_10 = 2, + CHNL_SPAN_20 = 4, + CHNL_SPAN_40 = 8 +}; + +/* Define BSS operating bandwidth */ +enum ENUM_CHNL_BW { + CHNL_BW_20, + CHNL_BW_20_40, + CHNL_BW_10, + CHNL_BW_5 +}; + +#if 0 +/* If channel width is CHNL_BW_20_40, the first channel will be SCA and + * the second channel is SCB, then iteratively. + * Note the final channel will not be SCA. + */ +struct DOMAIN_SUBBAND_INFO { + uint8_t ucRegClass; + enum ENUM_BAND eBand; + enum ENUM_CHNL_SPAN eChannelSpan; + uint8_t ucFirstChannelNum; + uint8_t ucNumChannels; + enum ENUM_CHNL_BW eChannelBw; + u_int8_t fgDfsNeeded; + u_int8_t fgIbssProhibited; +}; + +/* Use it as all available channel list for STA */ +struct DOMAIN_INFO_ENTRY { + uint16_t u2CountryCode; + uint16_t u2MibRegDomainValue; + + /* If different attributes, put them into different rSubBands. + * For example, DFS shall be used or not. + */ + struct DOMAIN_SUBBAND_INFO rSubBand[MAX_SUBBAND_NUM]; +}; + +#else /* New definition 20110830 */ + +/* In all bands, the first channel will be SCA and the second channel is SCB, + * then iteratively. + * Note the final channel will not be SCA. + */ +struct DOMAIN_SUBBAND_INFO { + /* Note1: regulation class depends on operation bandwidth and RF band. + * For example: 2.4GHz, 1~13, 20MHz ==> regulation class = 81 + * 2.4GHz, 1~13, SCA ==> regulation class = 83 + * 2.4GHz, 1~13, SCB ==> regulation class = 84 + * Note2: TX power limit is not specified here because path loss + * is unknown. + */ + uint8_t ucRegClass; /* Regulation class for 20MHz */ + uint8_t ucBand; /* Type: ENUM_BAND_T */ + uint8_t ucChannelSpan; /* Type: ENUM_CHNL_SPAN_T */ + uint8_t ucFirstChannelNum; + uint8_t ucNumChannels; + uint8_t fgDfs; /* Type: BOOLEAN*/ +}; + +/* Use it as all available channel list for STA */ +struct DOMAIN_INFO_ENTRY { + uint16_t *pu2CountryGroup; + uint32_t u4CountryNum; + + /* If different attributes, put them into different rSubBands. + * For example, DFS shall be used or not. + */ + struct DOMAIN_SUBBAND_INFO rSubBand[MAX_SUBBAND_NUM]; +}; +#endif + +#if CFG_SUPPORT_PWR_LIMIT_COUNTRY + +#if (CFG_SUPPORT_SINGLE_SKU == 1) +/* + * MT_TxPwrLimit.dat format + */ +#define SECTION_PREFIX (0x23232323) +#define ELEMENT_PREFIX (0xffff) +#define VERSION (0x00000001) +#define SIZE_OF_VERSION 4 +#define WLAN_TX_PWR_LIMIT_FILE_BUF_SIZE 204800 + +struct tx_pwr_element { + uint16_t prefix; + uint8_t channel_num; + uint8_t reserved; + + /*the followings are in unit: 0.5 dbm*/ + + uint8_t tx_pwr_dsss_cck; + uint8_t tx_pwr_dsss_bpsk; + + uint8_t tx_pwr_ofdm_bpsk; /* 6M, 9M */ + uint8_t tx_pwr_ofdm_qpsk; /* 12M, 18M */ + uint8_t tx_pwr_ofdm_16qam; /* 24M, 36M */ + uint8_t tx_pwr_ofdm_48m; + uint8_t tx_pwr_ofdm_54m; + + uint8_t tx_pwr_ht20_bpsk; /* MCS0*/ + uint8_t tx_pwr_ht20_qpsk; /* MCS1, MCS2*/ + uint8_t tx_pwr_ht20_16qam; /* MCS3, MCS4*/ + uint8_t tx_pwr_ht20_mcs5; /* MCS5*/ + uint8_t tx_pwr_ht20_mcs6; /* MCS6*/ + uint8_t tx_pwr_ht20_mcs7; /* MCS7*/ + + uint8_t tx_pwr_ht40_bpsk; /* MCS0*/ + uint8_t tx_pwr_ht40_qpsk; /* MCS1, MCS2*/ + uint8_t tx_pwr_ht40_16qam; /* MCS3, MCS4*/ + uint8_t tx_pwr_ht40_mcs5; /* MCS5*/ + uint8_t tx_pwr_ht40_mcs6; /* MCS6*/ + uint8_t tx_pwr_ht40_mcs7; /* MCS7*/ + + uint8_t tx_pwr_vht20_bpsk; /* MCS0*/ + uint8_t tx_pwr_vht20_qpsk; /* MCS1, MCS2*/ + uint8_t tx_pwr_vht20_16qam; /* MCS3, MCS4*/ + uint8_t tx_pwr_vht20_64qam; /* MCS5, MCS6*/ + uint8_t tx_pwr_vht20_mcs7; + uint8_t tx_pwr_vht20_mcs8; + uint8_t tx_pwr_vht20_mcs9; + + uint8_t tx_pwr_vht_40; + uint8_t tx_pwr_vht_80; + uint8_t tx_pwr_vht_160nc; + uint8_t tx_pwr_lg_40; + uint8_t tx_pwr_lg_80; + + uint8_t tx_pwr_1ss_delta; + uint8_t reserved_3[3]; +}; + +struct tx_pwr_section { + uint32_t prefix; + uint32_t country_code; +}; +#endif /*#if (CFG_SUPPORT_SINGLE_SKU == 1)*/ + +struct COUNTRY_POWER_LIMIT_TABLE_DEFAULT { + uint8_t aucCountryCode[2]; + /* 0: ch 1 ~14 + * 1: ch 36 ~48 + * 2: ch 52 ~64 + * 3: ch 100 ~144 + * 4: ch 149 ~165 + */ + int8_t aucPwrLimitSubBand[POWER_LIMIT_SUBAND_NUM]; + /* bit0: cPwrLimit2G4, bit1: cPwrLimitUnii1; bit2: cPwrLimitUnii2A;*/ + /* bit3: cPwrLimitUnii2C; bit4: cPwrLimitUnii3; mW: 0, mW\MHz : 1 */ + uint8_t ucPwrUnit; +}; + +struct COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION { + uint8_t aucCountryCode[2]; + uint8_t ucCentralCh; + /* Note: this array doesn't include cPwrLimitOFDM_L & cPwrLimitOFDM_H */ + int8_t aucPwrLimit[PWR_LIMIT_NUM]; +}; + +struct COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION_HE { + uint8_t aucCountryCode[2]; + uint8_t ucCentralCh; + int8_t aucPwrLimit[PWR_LIMIT_HE_NUM]; +}; + + +struct SUBBAND_CHANNEL { + uint8_t ucStartCh; + uint8_t ucEndCh; + uint8_t ucInterval; + uint8_t ucReserved; +}; + +#endif /* CFG_SUPPORT_PWR_LIMIT_COUNTRY */ + +#if (CFG_SUPPORT_SINGLE_SKU == 1) +/* + * Event from chip for single sku + */ +struct SINGLE_SKU_INFO { + uint32_t u4EfuseCountryCode; + uint8_t isEfuseValid; + uint8_t ucReserved[7]; +}; + +/* + * single sku control structure + */ +enum regd_state { + REGD_STATE_UNDEFINED, + REGD_STATE_INIT, + REGD_STATE_SET_WW_CORE, + REGD_STATE_SET_COUNTRY_USER, + REGD_STATE_SET_COUNTRY_DRIVER, + REGD_STATE_SET_COUNTRY_IE, + REGD_STATE_INVALID +}; + +enum regd_control_flag { + REGD_CTRL_FLAG_SUPPORT_LOCAL_REGD_DB = (0x1 << 0) +}; + +struct mtk_regd_control { + u_int8_t en; + u_int8_t isEfuseCountryCodeUsed; + enum regd_state state; + u32 alpha2; + u32 tmp_alpha2; /*store country code set by iwpriv "country XX"*/ + u32 flag; /*enum regd_control_flag*/ + struct GLUE_INFO *pGlueInfo; /*wlan GlueInfo*/ + u8 n_channel_active_2g; + u8 n_channel_active_5g; + struct CMD_DOMAIN_CHANNEL channels[MAX_SUPPORTED_CH_COUNT]; + enum nl80211_dfs_regions dfs_region; +}; + +#if (CFG_SUPPORT_SINGLE_SKU_LOCAL_DB == 1) +struct mtk_regdomain { + char country_code[4]; + const struct ieee80211_regdomain *prRegdRules; +}; +#endif + +#endif +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ +#define CAL_CH_OFFSET_80M(_PRIMARY_CH, _CENTRAL_CH) \ + (((_PRIMARY_CH - _CENTRAL_CH) + 6) >> 2) + +#define CAL_CH_OFFSET_160M(_PRIMARY_CH, _CENTRAL_CH) \ + (((_PRIMARY_CH - _CENTRAL_CH) + 14) >> 2) + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +struct DOMAIN_INFO_ENTRY *rlmDomainGetDomainInfo( + struct ADAPTER *prAdapter); + +u_int8_t rlmIsValidChnl(struct ADAPTER *prAdapter, uint8_t ucNumOfChannel, + enum ENUM_BAND eBand); + +void +rlmDomainGetChnlList(struct ADAPTER *prAdapter, + enum ENUM_BAND eSpecificBand, u_int8_t fgNoDfs, + uint8_t ucMaxChannelNum, uint8_t *pucNumOfChannel, + struct RF_CHANNEL_INFO *paucChannelList); + +void rlmDomainGetDfsChnls(struct ADAPTER *prAdapter, + uint8_t ucMaxChannelNum, uint8_t *pucNumOfChannel, + struct RF_CHANNEL_INFO *paucChannelList); + +void rlmDomainSendCmd(struct ADAPTER *prAdapter); + +void rlmDomainSendDomainInfoCmd(struct ADAPTER *prAdapter); + +void rlmDomainSendPassiveScanInfoCmd(struct ADAPTER + *prAdapter); + +uint32_t rlmDomainSupOperatingClassIeFill(uint8_t *pBuf); + +u_int8_t rlmDomainCheckChannelEntryValid(struct ADAPTER + *prAdapter, uint8_t ucCentralCh); + +uint8_t rlmDomainGetCenterChannel(enum ENUM_BAND eBand, + uint8_t ucPriChannel, + enum ENUM_CHNL_EXT eExtend); + +u_int8_t rlmDomainIsValidRfSetting(struct ADAPTER *prAdapter, + enum ENUM_BAND eBand, uint8_t ucPriChannel, + enum ENUM_CHNL_EXT eExtend, + enum ENUM_CHANNEL_WIDTH eChannelWidth, + uint8_t ucChannelS1, uint8_t ucChannelS2); + +#if CFG_SUPPORT_PWR_LIMIT_COUNTRY + +u_int8_t +rlmDomainCheckPowerLimitValid(struct ADAPTER *prAdapter, + struct COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION + rPowerLimitTableConfiguration, + uint8_t ucPwrLimitNum); + +void rlmDomainCheckCountryPowerLimitTable( + struct ADAPTER *prAdapter); + +uint16_t rlmDomainPwrLimitDefaultTableDecision( + struct ADAPTER *prAdapter, uint16_t u2CountryCode); + +void rlmDomainSendPwrLimitCmd(struct ADAPTER *prAdapter); +#endif + +#if (CFG_SUPPORT_SINGLE_SKU == 1) +extern struct ieee80211_supported_band mtk_band_2ghz; +extern struct ieee80211_supported_band mtk_band_5ghz; + +u_int8_t rlmDomainIsCtrlStateEqualTo(enum regd_state state); +u_int8_t rlmDomainIsUsingLocalRegDomainDataBase(void); +enum regd_state rlmDomainStateTransition(enum regd_state + request_state, struct regulatory_request *pRequest); +void rlmDomainSetCountryCode(char *alpha2, + u8 size_of_alpha2); +void rlmDomainSetDfsRegion(enum nl80211_dfs_regions + dfs_region); +enum nl80211_dfs_regions rlmDomainGetDfsRegion(void); +void rlmDomainResetCtrlInfo(u_int8_t force); +void rlmDomainAddActiveChannel(u8 band); +u8 rlmDomainGetActiveChannelCount(u8 band); +void rlmDomainParsingChannel(IN struct wiphy *pWiphy); +struct CMD_DOMAIN_CHANNEL *rlmDomainGetActiveChannels(void); +void rlmExtractChannelInfo(u32 max_ch_count, + struct CMD_DOMAIN_ACTIVE_CHANNEL_LIST *prBuff); +void regd_set_using_local_regdomain_db(void); +void rlmDomainSetDefaultCountryCode(void); +enum regd_state rlmDomainGetCtrlState(void); +bool rlmDomainIsSameCountryCode(char *alpha2, + u8 size_of_alpha2); +const struct ieee80211_regdomain +*rlmDomainSearchRegdomainFromLocalDataBase(char *alpha2); +struct GLUE_INFO *rlmDomainGetGlueInfo(void); +bool rlmDomainIsEfuseUsed(void); +uint8_t rlmDomainGetChannelBw(uint8_t channelNum); + +#if (CFG_SUPPORT_SINGLE_SKU_LOCAL_DB == 1) +extern const struct mtk_regdomain *g_prRegRuleTable[]; +#endif + +#endif + +const struct ieee80211_regdomain +*rlmDomainGetLocalDefaultRegd(void); +void rlmDomainSendInfoToFirmware(IN struct ADAPTER + *prAdapter); +uint32_t rlmDomainExtractSingleSkuInfoFromFirmware( + IN struct ADAPTER *prAdapter, IN uint8_t *pucEventBuf); +u_int8_t regd_is_single_sku_en(void); +u_int8_t rlmDomainIsLegalChannel(struct ADAPTER *prAdapter, + enum ENUM_BAND eBand, uint8_t ucChannel); +u_int8_t rlmDomainIsLegalDfsChannel(struct ADAPTER *prAdapter, + enum ENUM_BAND eBand, uint8_t ucChannel); +enum ENUM_CHNL_EXT rlmSelectSecondaryChannelType( + struct ADAPTER *prAdapter, enum ENUM_BAND band, + u8 primary_ch); +void rlmDomainOidSetCountry(IN struct ADAPTER *prAdapter, + char *country, u8 size_of_country); +u32 rlmDomainGetCountryCode(void); +u32 rlmDomainGetTempCountryCode(void); +void rlmDomainAssert(u_int8_t cond); + +#if CFG_SUPPORT_DYNAMIC_PWR_LIMIT +/* dynamic tx power control */ +void txPwrCtrlInit(struct ADAPTER *prAdapter); +void txPwrCtrlLoadConfig(struct ADAPTER *prAdapter); +void txPwrCtrlUninit(struct ADAPTER *prAdapter); +void txPwrCtrlShowList(struct ADAPTER *prAdapter, + uint8_t filterType, + char *message); +void txPwrCtrlDeleteElement(struct ADAPTER *prAdapter, + uint8_t *name, uint32_t index, + enum ENUM_TX_POWER_CTRL_LIST_TYPE eListType); +struct TX_PWR_CTRL_ELEMENT *txPwrCtrlStringToStruct(char *pcContent, + u_int8_t fgSkipHeader); +struct TX_PWR_CTRL_ELEMENT *txPwrCtrlFindElement( + struct ADAPTER *prAdapter, + uint8_t *name, + uint32_t index, + u_int8_t fgCheckIsApplied, + enum ENUM_TX_POWER_CTRL_LIST_TYPE eListType); +void txPwrCtrlAddElement(struct ADAPTER *prAdapter, + struct TX_PWR_CTRL_ELEMENT *prElement); +#endif +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#endif /* _RLM_DOMAIN_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/rlm_obss.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/rlm_obss.h new file mode 100644 index 0000000000000000000000000000000000000000..40f60b92fd32784dbd559998e80d2a81915c75be --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/rlm_obss.h @@ -0,0 +1,148 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/ + * include/mgmt/rlm_obss.h#1 + */ + +/*! \file "rlm_obss.h" + * \brief + */ + + +#ifndef _RLM_OBSS_H +#define _RLM_OBSS_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#define CHNL_LIST_SZ_2G 14 +#define CHNL_LIST_SZ_5G 14 + +#define CHNL_LEVEL0 0 +#define CHNL_LEVEL1 1 +#define CHNL_LEVEL2 2 + +#define AFFECTED_CHNL_OFFSET 5 + +#define OBSS_SCAN_MIN_INTERVAL 10 /* In unit of sec */ + +#define PUBLIC_ACTION_MAX_LEN 200 /* In unit of byte */ + +/* P2P GO only */ +/* Define default OBSS Scan parameters (from MIB in spec.) */ +#define dot11OBSSScanPassiveDwell 20 +#define dot11OBSSScanActiveDwell 10 +#define dot11OBSSScanPassiveTotalPerChannel 200 +#define dot11OBSSScanActiveTotalPerChannel 20 +#define dot11BSSWidthTriggerScanInterval 300 /* Unit: sec */ +#define dot11BSSWidthChannelTransitionDelayFactor 5 +#define dot11OBSSScanActivityThreshold 25 + +#define OBSS_20_40M_TIMEOUT (dot11BSSWidthTriggerScanInterval + 10) + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/* Control MAC PCO function */ +enum ENUM_SYS_PCO_PHASE { + SYS_PCO_PHASE_DISABLED = 0, + SYS_PCO_PHASE_20M, + SYS_PCO_PHASE_40M +}; + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +void rlmObssInit(struct ADAPTER *prAdapter); + +void rlmObssScanDone(struct ADAPTER *prAdapter, + struct MSG_HDR *prMsgHdr); + +void rlmObssTriggerScan(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo); + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#endif /* _RLM_OBSS_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/rlm_protection.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/rlm_protection.h new file mode 100644 index 0000000000000000000000000000000000000000..ed542da978e7675aaa3de264768295014326c1f8 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/rlm_protection.h @@ -0,0 +1,142 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/ + * include/mgmt/rlm_protection.h#1 + */ + +/*! \file "rlm_protection.h" + * \brief + */ + +#ifndef _RLM_PROTECTION_H +#define _RLM_PROTECTION_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +enum ENUM_SYS_PROTECT_MODE { + SYS_PROTECT_MODE_NONE = 0, /* Mode 0 */ + SYS_PROTECT_MODE_ERP, /* Mode 1 */ + SYS_PROTECT_MODE_NON_HT, /* Mode 2 */ + SYS_PROTECT_MODE_20M, /* Mode 3 */ + + SYS_PROTECT_MODE_NUM +}; + +/* This definition follows HT Protection field of HT Operation IE */ +enum ENUM_HT_PROTECT_MODE { + HT_PROTECT_MODE_NONE = 0, + HT_PROTECT_MODE_NON_MEMBER, + HT_PROTECT_MODE_20M, + HT_PROTECT_MODE_NON_HT, + + HT_PROTECT_MODE_NUM +}; + +enum ENUM_GF_MODE { + GF_MODE_NORMAL = 0, + GF_MODE_PROTECT, + GF_MODE_DISALLOWED, + + GF_MODE_NUM +}; + +enum ENUM_RIFS_MODE { + RIFS_MODE_NORMAL = 0, + RIFS_MODE_DISALLOWED, + + RIFS_MODE_NUM +}; + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#endif /* _RLM_PROTECTION_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/rlm_txpwr_init.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/rlm_txpwr_init.h new file mode 100644 index 0000000000000000000000000000000000000000..81586148f7ca41ed27286fbb7103b5d38343835d --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/rlm_txpwr_init.h @@ -0,0 +1,1609 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/ + * include/mgmt/rlm_txpwr_init.h#1 + */ + +/*! \file "rlm_txpwr_init.h" + * \brief + */ + +#ifndef _RLM_TXPWR_INIT_H +#define _RLM_TXPWR_INIT_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +/*Support Tx Power Range : 63~ -64 (unit : 0.5dBm)*/ + +#define PWR_LIMIT_2G4_IN_MW_MHZ BIT(0) +#define PWR_LIMIT_UNII1_IN_MW_MHZ BIT(1) +#define PWR_LIMIT_UNII2A_IN_MW_MHZ BIT(2) +#define PWR_LIMIT_UNII2C_IN_MW_MHZ BIT(3) +#define PWR_LIMIT_UNII3_IN_MW_MHZ BIT(4) + +#if CFG_SUPPORT_PWR_LIMIT_COUNTRY +/*Set to MAX_TX_PWR = 63dBm if larger than it*/ +struct COUNTRY_POWER_LIMIT_TABLE_DEFAULT + g_rRlmPowerLimitDefault[] = { + + { {'A', 'R'} + , {60, 34, 48, 48, 60} + , 0 + } + , + { {'A', 'U'} + , {63, 46, 46, 60, 63} + , 0 + } + , + { {'N', 'Z'} + , {63, 46, 46, 60, 63} + , 0 + } + , + { {'A', 'T'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'B', 'E'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'B', 'R'} + , {63, 46, 46, 60, 63} + , 0 + } + , + { {'B', 'G'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'C', 'A'} + , {60, 46, 48, 48, 60} + , 0 + } + , + { {'C', 'L'} + , {43, 43, 43, 63, 43} + , 0 + } + , + { {'C', 'N'} + , {40, 46, 46, 63, 63} + , 0 + } + , + { {'H', 'R'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'C', 'Z'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'D', 'K'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'D', 'M'} + , {60, 34, 46, 46, 60} + , 0 + } + , + { {'E', 'C'} + , {60, 34, 48, 48, 60} + , 0 + } + , + { {'E', 'G'} + , {40, 46, 46, 63, 46} + , 0 + } + , + { {'S', 'V'} + , {60, 34, 46, 46, 60} + , 0 + } + , + { {'F', 'I'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'F', 'R'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'G', 'R'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'H', 'N'} + , {60, 60, 48, 48, 60} + , 0 + } + , + { {'H', 'K'} + , {63, 46, 46, 60, 63} + , 0 + } + , + { {'H', 'U'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'I', 'S'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'I', 'N'} + , {63, 46, 46, 63, 46} + , 0 + } + , + { {'I', 'D'} + , {46, 63, 63, 63, 46} + , 0 + } + , + { {'I', 'E'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'I', 'L'} + , {40, 46, 46, 63, 63} + , 0 + } + , + { {'I', 'T'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'J', 'P'} + , {46, 46, 46, 46, 63} + , 0 + } + , + { {'K', 'R'} + , {46, 34, 46, 46, 46} + , 0 + } + , + { {'L', 'U'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'M', 'Y'} + , {54, 60, 60, 63, 60} + , 0 + } + , + { {'M', 'X'} + , {60, 46, 48, 63, 60} + , 0 + } + , + { {'N', 'L'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'N', 'O'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'O', 'M'} + , {40, 46, 46, 60, 63} + , 0 + } + , + { {'P', 'K'} + , {40, 63, 63, 63, 40} + , 0 + } + , + { {'P', 'Y'} + , {60, 46, 46, 48, 60} + , 0 + } + , + { {'P', 'E'} + , {54, 46, 48, 42, 48} + , 0 + } + , + { {'P', 'H'} + , {48, 48, 48, 48, 48} + , 0 + } + , + { {'P', 'L'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'P', 'T'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'Q', 'A'} + , {40, 63, 63, 63, 40} + , 0 + } + , + { {'R', 'O'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'R', 'U'} + , {48, 40, 40, 60, 60} + , 0 + } + , + { {'S', 'A'} + , {40, 46, 46, 46, 46} + , 0 + } + , + { {'S', 'G'} + , {46, 40, 40, 60, 60} + , 0 + } + , + { {'S', 'K'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'S', 'I'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'Z', 'A'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'E', 'S'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'S', 'E'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'C', 'H'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'T', 'W'} + , {60, 48, 48, 48, 60} + , 0 + } + , + { {'T', 'H'} + , {40, 46, 46, 60, 60} + , 0 + } + , + { {'A', 'E'} + , {40, 46, 46, 60, 60} + , 0 + } + , + { {'G', 'B'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'U', 'Y'} + , {60, 34, 46, 46, 60} + , 0 + } + , + { {'U', 'S'} + , {60, 48, 48, 48, 60} + , 0 + } + , + { {'V', 'E'} + , {60, 46, 46, 63, 46} + , 0 + } + , + { {'V', 'N'} + , {40, 46, 46, 60, 34} + , 0 + } + , + { {'A', 'O'} + , {40, 63, 63, 63, 63} + , 0 + } + , + { {'B', 'Z'} + , {40, 63, 63, 63, 63} + , 0 + } + , + { {'B', 'J'} + , {40, 63, 63, 63, 63} + , 0 + } + , + { {'B', 'T'} + , {40, 63, 63, 63, 63} + , 0 + } + , + { {'B', 'O'} + , {40, 63, 63, 63, 63} + , 0 + } + , + { {'B', 'I'} + , {40, 63, 63, 63, 63} + , 0 + } + , + { {'C', 'M'} + , {40, 63, 63, 63, 63} + , 0 + } + , + { {'C', 'F'} + , {40, 63, 63, 63, 63} + , 0 + } + , + { {'T', 'D'} + , {40, 63, 63, 63, 63} + , 0 + } + , + { {'K', 'M'} + , {40, 63, 63, 63, 63} + , 0 + } + , + { {'C', 'D'} + , {40, 63, 63, 63, 63} + , 0 + } + , + { {'C', 'G'} + , {40, 63, 63, 63, 63} + , 0 + } + , + { {'C', 'I'} + , {40, 63, 63, 63, 63} + , 0 + } + , + { {'D', 'J'} + , {40, 63, 63, 63, 63} + , 0 + } + , + { {'G', 'Q'} + , {40, 63, 63, 63, 63} + , 0 + } + , + { {'E', 'R'} + , {40, 63, 63, 63, 63} + , 0 + } + , + { {'F', 'J'} + , {40, 63, 63, 63, 63} + , 0 + } + , + { {'G', 'A'} + , {40, 63, 63, 63, 63} + , 0 + } + , + { {'G', 'M'} + , {40, 63, 63, 63, 63} + , 0 + } + , + { {'G', 'N'} + , {40, 63, 63, 63, 63} + , 0 + } + , + { {'G', 'W'} + , {40, 63, 63, 63, 63} + , 0 + } + , + { {'R', 'K'} + , {40, 63, 63, 63, 63} + , 0 + } + , + { {'K', 'G'} + , {40, 63, 63, 63, 63} + , 0 + } + , + { {'L', 'Y'} + , {40, 63, 63, 63, 63} + , 0 + } + , + { {'M', 'G'} + , {40, 63, 63, 63, 63} + , 0 + } + , + { {'M', 'L'} + , {40, 63, 63, 63, 63} + , 0 + } + , + { {'N', 'R'} + , {40, 63, 63, 63, 63} + , 0 + } + , + { {'N', 'C'} + , {40, 63, 63, 63, 63} + , 0 + } + , + { {'S', 'T'} + , {40, 63, 63, 63, 63} + , 0 + } + , + { {'S', 'C'} + , {40, 63, 63, 63, 63} + , 0 + } + , + { {'S', 'L'} + , {40, 63, 63, 63, 63} + , 0 + } + , + { {'S', 'B'} + , {40, 63, 63, 63, 63} + , 0 + } + , + { {'S', 'O'} + , {40, 63, 63, 63, 63} + , 0 + } + , + { {'S', 'R'} + , {40, 63, 63, 63, 63} + , 0 + } + , + { {'S', 'Z'} + , {40, 63, 63, 63, 63} + , 0 + } + , + { {'T', 'J'} + , {40, 63, 63, 63, 63} + , 0 + } + , + { {'T', 'G'} + , {40, 63, 63, 63, 63} + , 0 + } + , + { {'T', 'O'} + , {40, 63, 63, 63, 63} + , 0 + } + , + { {'T', 'M'} + , {40, 63, 63, 63, 63} + , 0 + } + , + { {'T', 'V'} + , {40, 63, 63, 63, 63} + , 0 + } + , + { {'V', 'U'} + , {40, 63, 63, 63, 63} + , 0 + } + , + { {'Y', 'E'} + , {40, 63, 63, 63, 63} + , 0 + } + , + { {'A', 'S'} + , {60, 34, 46, 48, 60} + , 0 + } + , + { {'A', 'I'} + , {60, 34, 48, 60, 60} + , 0 + } + , + { {'B', 'M'} + , {60, 34, 48, 48, 60} + , 0 + } + , + { {'K', 'Y'} + , {60, 34, 48, 60, 60} + , 0 + } + , + { {'G', 'U'} + , {60, 34, 48, 48, 60} + , 0 + } + , + { {'F', 'M'} + , {60, 34, 48, 48, 60} + , 0 + } + , + { {'P', 'R'} + , {60, 34, 46, 48, 60} + , 0 + } + , + { {'V', 'I'} + , {60, 34, 48, 48, 60} + , 0 + } + , + { {'A', 'Z'} + , {40, 34, 48, 60, 60} + , 0 + } + , + { {'B', 'W'} + , {40, 46, 46, 60, 60} + , 0 + } + , + { {'K', 'H'} + , {40, 46, 46, 48, 60} + , 0 + } + , + { {'C', 'X'} + , {63, 46, 46, 60, 63} + , 0 + } + , + { {'C', 'O'} + , {60, 34, 48, 48, 60} + , 0 + } + , + { {'C', 'R'} + , {60, 34, 48, 48, 60} + , 0 + } + , + { {'G', 'D'} + , {40, 46, 46, 60, 60} + , 0 + } + , + { {'G', 'T'} + , {40, 34, 48, 48, 60} + , 0 + } + , + { {'K', 'I'} + , {63, 46, 46, 60, 63} + , 0 + } + , + { {'L', 'B'} + , {40, 46, 46, 46, 46} + , 0 + } + , + { {'L', 'R'} + , {60, 46, 60, 63, 63} + , 0 + } + , + { {'M', 'N'} + , {46, 32, 46, 46, 58} + , 0 + } + , + { {'A', 'N'} + , {60, 34, 48, 48, 60} + , 0 + } + , + { {'N', 'I'} + , {60, 34, 48, 48, 60} + , 0 + } + , + { {'P', 'W'} + , {60, 60, 60, 60, 60} + , 0 + } + , + { {'W', 'S'} + , {40, 40, 40, 40, 60} + , 0 + } + , + { {'L', 'K'} + , {46, 46, 46, 46, 46} + , 0 + } + , + { {'T', 'T'} + , {60, 46, 46, 60, 60} + , 0 + } + , + { {'A', 'W'} + , {60, 46, 60, 60, 63} + , 0 + } + , + { {'L', 'A'} + , {40, 46, 46, 60, 63} + , 0 + } + , + { {'U', 'G'} + , {40, 46, 46, 48, 60} + , 0 + } + , + { {'M', 'M'} + , {40, 46, 46, 60, 63} + , 0 + } + , + { {'A', 'L'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'D', 'Z'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'A', 'D'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'B', 'Y'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'B', 'A'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'V', 'G'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'C', 'V'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'C', 'Y'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'E', 'E'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'E', 'T'} + , {40, 40, 40, 40, 28} + , 0 + } + , + { {'G', 'F'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'P', 'F'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'T', 'F'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'G', 'E'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'D', 'E'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'G', 'H'} + , {40, 34, 48, 60, 28} + , 0 + } + , + { {'G', 'P'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'I', 'Q'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'K', 'E'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'L', 'V'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'L', 'S'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'L', 'I'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'L', 'T'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'M', 'K'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'M', 'T'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'M', 'Q'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'M', 'R'} + , {40, 46, 46, 46, 28} + , 0 + } + , + { {'M', 'U'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'Y', 'T'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'M', 'D'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'M', 'C'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'M', 'E'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'M', 'S'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'R', 'E'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'M', 'F'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'S', 'M'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'S', 'N'} + , {40, 40, 40, 60, 28} + , 0 + } + , + { {'R', 'S'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'T', 'R'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'T', 'C'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'V', 'A'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'A', 'M'} + , {40, 40, 40, 63, 63} + , 0 + } + , + { {'K', 'W'} + , {40, 46, 46, 63, 63} + , 0 + } + , + { {'M', 'A'} + , {40, 46, 46, 63, 63} + , 0 + } + , + { {'N', 'E'} + , {40, 46, 46, 63, 63} + , 0 + } + , + { {'T', 'N'} + , {40, 46, 46, 63, 63} + , 0 + } + , + { {'N', 'P'} + , {60, 46, 46, 63, 60} + , 0 + } + , + { {'A', 'F'} + , {40, 46, 63, 63, 63} + , 0 + } + , + { {'A', 'G'} + , {40, 46, 48, 63, 54} + , 0 + } + , + { {'B', 'S'} + , {63, 46, 60, 63, 63} + , 0 + } + , + { {'B', 'H'} + , {40, 46, 46, 63, 63} + , 0 + } + , + { {'B', 'B'} + , {40, 46, 48, 63, 54} + , 0 + } + , + { {'B', 'N'} + , {46, 46, 46, 63, 60} + , 0 + } + , + { {'M', 'V'} + , {40, 46, 46, 63, 40} + , 0 + } + , + { {'P', 'A'} + , {60, 34, 48, 63, 60} + , 0 + } + , + { {'Z', 'M'} + , {60, 46, 46, 63, 60} + , 0 + } + , + { {'J', 'O'} + , {40, 46, 63, 63, 46} + , 0 + } + , + { {'P', 'G'} + , {40, 46, 63, 63, 60} + , 0 + } + , + { {'B', 'F'} + , {40, 63, 63, 63, 60} + , 0 + } + , + { {'G', 'Y'} + , {60, 63, 63, 63, 60} + , 0 + } + , + { {'H', 'T'} + , {40, 63, 63, 63, 60} + , 0 + } + , + { {'J', 'M'} + , {54, 63, 63, 63, 57} + , 0 + } + , + { {'M', 'O'} + , {40, 63, 63, 63, 40} + , 0 + } + , + { {'M', 'W'} + , {60, 63, 63, 63, 60} + , 0 + } + , + { {'R', 'W'} + , {40, 63, 63, 63, 60} + , 0 + } + , + { {'K', 'N'} + , {40, 63, 63, 63, 60} + , 0 + } + , + { {'T', 'Z'} + , {40, 63, 63, 63, 40} + , 0 + } + , + { {'N', 'G'} + , {40, 63, 46, 63, 60} + , 0 + } + , + { {'B', 'D'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'D', 'O'} + , {63, 46, 46, 60, 63} + , 0 + } + , + { {'F', 'K'} + , {40, 46, 46, 60, 28} + , 0 + } + , + { {'K', 'Z'} + , {40, 34, 48, 60, 60} + , 0 + } + , + { {'M', 'Z'} + , {40, 34, 46, 48, 60} + , 0 + } + , + { {'N', 'A'} + , {40, 34, 46, 48, 60} + , 0 + } + , + { {'L', 'C'} + , {40, 34, 48, 48, 60} + , 0 + } + , + { {'V', 'C'} + , {40, 34, 46, 48, 60} + , 0 + } + , + { {'U', 'A'} + , {40, 46, 46, 46, 48} + , 0 + } + , + { {'U', 'Z'} + , {40, 48, 48, 48, 60} + , 0 + } + , + { {'Z', 'W'} + , {40, 34, 46, 48, 60} + , 0 + } + , + { {'M', 'P'} + , {60, 34, 46, 48, 60} + , 0 + } + , + { {'C', 'K'} + , {63, 63, 63, 63, 63} + , 0 + } + , + { {'C', 'U'} + , {63, 63, 63, 63, 63} + , 0 + } + , + { {'T', 'L'} + , {63, 63, 63, 63, 63} + , 0 + } + , + { {'F', 'O'} + , {63, 63, 63, 63, 63} + , 0 + } + , + { {'G', 'I'} + , {63, 63, 63, 63, 63} + , 0 + } + , + { {'I', 'R'} + , {63, 63, 63, 63, 63} + , 0 + } + , + { {'I', 'M'} + , {63, 63, 63, 63, 63} + , 0 + } + , + { {'J', 'E'} + , {63, 63, 63, 63, 63} + , 0 + } + , + { {'K', 'P'} + , {63, 63, 63, 63, 63} + , 0 + } + , + { {'M', 'H'} + , {63, 63, 63, 63, 63} + , 0 + } + , + { {'N', 'U'} + , {63, 63, 63, 63, 63} + , 0 + } + , + { {'N', 'F'} + , {63, 63, 63, 63, 63} + , 0 + } + , + { {'P', 'S'} + , {63, 63, 63, 63, 63} + , 0 + } + , + { {'P', 'N'} + , {63, 63, 63, 63, 63} + , 0 + } + , + { {'P', 'M'} + , {63, 63, 63, 63, 63} + , 0 + } + , + { {'S', 'S'} + , {63, 63, 63, 63, 63} + , 0 + } + , + { {'S', 'D'} + , {63, 63, 63, 63, 63} + , 0 + } + , + { {'S', 'Y'} + , {63, 63, 63, 63, 63} + , 0 + } + , +#if 1 /* Temp define as 6630 */ + { {'E', 'H'} + , {40, 46, 46, 63, 63} + , 0 + } + , + { {'G', 'G'} + , {63, 63, 63, 63, 63} + , 0 + } + , +#endif + + /*Default*/ + { {0, 0} + , {63, 63, 63, 63, 63} + , 0 + } +}; + +struct COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION_HE + g_rRlmPowerLimitConfigurationHE[] = { + /*Default*/ + { {0, 0} + , 36, + {64, 64, 64, /* RU26 L,H,U */ + 64, 64, 64, /* RU52 L,H,U*/ + 64, 64, 64, /* RU106 L,H,U*/ + 64, 64, 64, /* RU242 L,H,U*/ + 64, 64, 64, /* RU484 L,H,U*/ + 64, 64, 64} /* RU996 L,H,U*/ + } +}; + +struct COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION + g_rRlmPowerLimitConfiguration[] = { + + { {'A', 'I'} + , 144, {48, 48, 48, 48, 48, 48, 48, 48, 48} + } + , + { {'A', 'Z'} + , 144, {48, 48, 48, 48, 48, 48, 48, 48, 48} + } + , + { {'B', 'W'} + , 144, {48, 48, 48, 48, 48, 48, 48, 48, 48} + } + , + { {'G', 'D'} + , 144, {48, 48, 48, 48, 48, 48, 48, 48, 48} + } + , + { {'L', 'B'} + , 144, {48, 48, 48, 48, 48, 48, 48, 48, 48} + } + , + { {'L', 'R'} + , 144, {48, 48, 48, 48, 48, 48, 48, 48, 48} + } + , + { {'W', 'S'} + , 165, {40, 40, 40, 40, 40, 40, 40, 40, 40} + } + , + { {'U', 'S'} + , 1, {39, 34, 32, 60, 60, 60, 60, 60, 60} + } + , + { {'U', 'S'} + , 6, {60, 60, 60, 60, 60, 60, 60, 60, 60} + } + , + { {'U', 'S'} + , 11, {39, 33, 32, 60, 60, 60, 60, 60, 60} + } + , + { {'U', 'S'} + , 3, {60, 60, 60, 31, 30, 60, 60, 60, 60} + } + , + { {'U', 'S'} + , 9, {60, 60, 60, 31, 30, 60, 60, 60, 60} + } + , + { {'U', 'S'} + , 36, {48, 36, 36, 48, 48, 48, 48, 48, 48} + } + , + { {'U', 'S'} + , 40, {48, 48, 48, 48, 48, 48, 48, 48, 48} + } + , + { {'U', 'S'} + , 48, {48, 48, 48, 48, 48, 48, 48, 48, 48} + } + , + { {'U', 'S'} + , 52, {48, 48, 48, 48, 48, 48, 48, 48, 48} + } + , + { {'U', 'S'} + , 60, {48, 48, 48, 48, 48, 48, 48, 48, 48} + } + , + { {'U', 'S'} + , 64, {48, 36, 36, 48, 48, 48, 48, 48, 48} + } + , + { {'U', 'S'} + , 100, {48, 37, 37, 48, 48, 48, 48, 48, 48} + } + , + { {'U', 'S'} + , 116, {48, 48, 48, 48, 48, 48, 48, 48, 48} + } + , + { {'U', 'S'} + , 140, {48, 42, 42, 48, 48, 48, 48, 48, 48} + } + , + { {'U', 'S'} + , 149, {60, 41, 41, 60, 60, 60, 60, 60, 60} + } + , + { {'U', 'S'} + , 157, {60, 60, 60, 60, 60, 60, 60, 60, 60} + } + , + { {'U', 'S'} + , 165, {60, 42, 42, 60, 60, 60, 60, 60, 60} + } + , + { {'U', 'S'} + , 38, {48, 48, 48, 27, 27, 48, 48, 48, 48} + } + , + { {'U', 'S'} + , 46, {48, 48, 48, 48, 48, 48, 48, 48, 48} + } + , + { {'U', 'S'} + , 54, {48, 48, 48, 48, 48, 48, 48, 48, 48} + } + , + { {'U', 'S'} + , 62, {48, 48, 48, 28, 28, 48, 48, 48, 48} + } + , + { {'U', 'S'} + , 102, {48, 48, 48, 29, 29, 48, 48, 48, 48} + } + , + { {'U', 'S'} + , 110, {48, 48, 48, 48, 48, 48, 48, 48, 48} + } + , + { {'U', 'S'} + , 134, {48, 48, 48, 41, 41, 48, 48, 48, 48} + } + , + { {'U', 'S'} + , 151, {60, 60, 60, 36, 36, 60, 60, 60, 60} + } + , + { {'U', 'S'} + , 159, {60, 60, 60, 60, 60, 60, 60, 60, 60} + } + , + { {'U', 'S'} + , 42, {48, 48, 48, 48, 48, 24, 24, 48, 48} + } + , + { {'U', 'S'} + , 58, {48, 48, 48, 48, 48, 26, 26, 48, 48} + } + , + { {'U', 'S'} + , 106, {48, 48, 48, 48, 48, 25, 25, 48, 48} + } + , + { {'U', 'S'} + , 122, {48, 48, 48, 48, 48, 48, 48, 48, 48} + } + , + { {'U', 'S'} + , 155, {60, 60, 60, 60, 60, 36, 36, 60, 60} + } + , + { {'U', 'S'} + , 50, {48, 48, 48, 48, 48, 48, 48, 24, 24} + } + , + { {'U', 'S'} + , 114, {48, 48, 48, 48, 48, 48, 48, 24, 24} + } + , + { {'T', 'W'} + , 1, {39, 34, 32, 60, 60, 60, 60, 60, 60} + } + , + { {'T', 'W'} + , 6, {60, 60, 60, 60, 60, 60, 60, 60, 60} + } + , + { {'T', 'W'} + , 11, {39, 33, 32, 60, 60, 60, 60, 60, 60} + } + , + { {'T', 'W'} + , 3, {60, 60, 60, 31, 30, 60, 60, 60, 60} + } + , + { {'T', 'W'} + , 9, {60, 60, 60, 31, 30, 60, 60, 60, 60} + } + , + { {'T', 'W'} + , 36, {48, 36, 36, 48, 48, 48, 48, 48, 48} + } + , + { {'T', 'W'} + , 40, {48, 48, 48, 48, 48, 48, 48, 48, 48} + } + , + { {'T', 'W'} + , 48, {48, 48, 48, 48, 48, 48, 48, 48, 48} + } + , + { {'T', 'W'} + , 52, {48, 48, 48, 48, 48, 48, 48, 48, 48} + } + , + { {'T', 'W'} + , 60, {48, 48, 48, 48, 48, 48, 48, 48, 48} + } + , + { {'T', 'W'} + , 64, {48, 36, 36, 48, 48, 48, 48, 48, 48} + } + , + { {'T', 'W'} + , 100, {48, 37, 37, 48, 48, 48, 48, 48, 48} + } + , + { {'T', 'W'} + , 116, {48, 48, 48, 48, 48, 48, 48, 48, 48} + } + , + { {'T', 'W'} + , 140, {48, 42, 42, 48, 48, 48, 48, 48, 48} + } + , + { {'T', 'W'} + , 149, {60, 41, 41, 60, 60, 60, 60, 60, 60} + } + , + { {'T', 'W'} + , 157, {60, 60, 60, 60, 60, 60, 60, 60, 60} + } + , + { {'T', 'W'} + , 165, {60, 42, 42, 60, 60, 60, 60, 60, 60} + } + , + { {'T', 'W'} + , 38, {48, 48, 48, 27, 27, 48, 48, 48, 48} + } + , + { {'T', 'W'} + , 46, {48, 48, 48, 48, 48, 48, 48, 48, 48} + } + , + { {'T', 'W'} + , 54, {48, 48, 48, 48, 48, 48, 48, 48, 48} + } + , + { {'T', 'W'} + , 62, {48, 48, 48, 28, 28, 48, 48, 48, 48} + } + , + { {'T', 'W'} + , 102, {48, 48, 48, 29, 29, 48, 48, 48, 48} + } + , + { {'T', 'W'} + , 110, {48, 48, 48, 48, 48, 48, 48, 48, 48} + } + , + { {'T', 'W'} + , 134, {48, 48, 48, 41, 41, 48, 48, 48, 48} + } + , + { {'T', 'W'} + , 151, {60, 60, 60, 36, 36, 60, 60, 60, 60} + } + , + { {'T', 'W'} + , 159, {60, 60, 60, 60, 60, 60, 60, 60, 60} + } + , + { {'T', 'W'} + , 42, {48, 48, 48, 48, 48, 24, 24, 48, 48} + } + , + { {'T', 'W'} + , 58, {48, 48, 48, 48, 48, 26, 26, 48, 48} + } + , + { {'T', 'W'} + , 106, {48, 48, 48, 48, 48, 25, 25, 48, 48} + } + , + { {'T', 'W'} + , 122, {48, 48, 48, 48, 48, 48, 48, 48, 48} + } + , + { {'T', 'W'} + , 155, {60, 60, 60, 60, 60, 36, 36, 60, 60} + } + , + { {'T', 'W'} + , 50, {48, 48, 48, 48, 48, 48, 48, 24, 24} + } + , + { {'T', 'W'} + , 114, {48, 48, 48, 48, 48, 48, 48, 24, 24} + } + , + + /*Default*/ + { {0, 0} + , 165, {63, 63, 63, 63, 63, 63, 63, 63, 63} + } +}; + +#endif + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +#endif /* _RLM_TXPWR_INIT_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/roaming_fsm.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/roaming_fsm.h new file mode 100644 index 0000000000000000000000000000000000000000..921f64d91427c65b18b773d3c7e9179ae3f28d27 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/roaming_fsm.h @@ -0,0 +1,232 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: + */ + +/*! \file "roaming_fsm.h" + * \brief This file defines the FSM for Roaming MODULE. + * + * This file defines the FSM for Roaming MODULE. + */ + + +#ifndef _ROAMING_FSM_H +#define _ROAMING_FSM_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +/* Roaming Discovery interval, SCAN result need to be updated */ +#define ROAMING_DISCOVER_TIMEOUT_SEC 10 /* Seconds. */ +#define ROAMING_INACTIVE_TIMEOUT_SEC 10 /* Seconds. */ +#if CFG_SUPPORT_ROAMING_SKIP_ONE_AP +#define ROAMING_ONE_AP_SKIP_TIMES 3 +#endif + +/* #define ROAMING_NO_SWING_RCPI_STEP 5 //rcpi */ +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +enum ENUM_ROAMING_FAIL_REASON { + ROAMING_FAIL_REASON_CONNLIMIT = 0, + ROAMING_FAIL_REASON_NOCANDIDATE, + ROAMING_FAIL_REASON_NUM +}; + +/* events of roaming between driver and firmware */ +enum ENUM_ROAMING_EVENT { + ROAMING_EVENT_START = 0, + ROAMING_EVENT_DISCOVERY, + ROAMING_EVENT_ROAM, + ROAMING_EVENT_FAIL, + ROAMING_EVENT_ABORT, + ROAMING_EVENT_THRESHOLD_UPDATE, + ROAMING_EVENT_NUM +}; + +enum ENUM_ROAMING_REASON { + ROAMING_REASON_POOR_RCPI = 0, + ROAMING_REASON_TX_ERR, /*Lowest rate, high PER*/ + ROAMING_REASON_RETRY, + ROAMING_REASON_IDLE, + ROAMING_REASON_BEACON_TIMEOUT, + ROAMING_REASON_INACTIVE, + ROAMING_REASON_SAA_FAIL, + ROAMING_REASON_NUM +}; + +struct CMD_ROAMING_TRANSIT { + uint16_t u2Event; + uint16_t u2Data; + uint16_t u2RcpiLowThreshold; + uint8_t ucIsSupport11B; + uint8_t ucBssidx; + enum ENUM_ROAMING_REASON eReason; + uint32_t u4RoamingTriggerTime; /*sec in mcu*/ + uint16_t u2RcpiHighThreshold; + uint8_t aucReserved2[6]; +}; + + +struct CMD_ROAMING_CTRL { + uint8_t fgEnable; + uint8_t ucRcpiAdjustStep; + uint16_t u2RcpiLowThr; + uint8_t ucRoamingRetryLimit; + uint8_t ucRoamingStableTimeout; + uint8_t aucReserved[2]; +}; + +#if CFG_SUPPORT_ROAMING_SKIP_ONE_AP +struct CMD_ROAMING_SKIP_ONE_AP { + uint8_t fgIsRoamingSkipOneAP; + uint8_t aucReserved[3]; + uint8_t aucReserved2[8]; +}; +#endif + +enum ENUM_ROAMING_STATE { + ROAMING_STATE_IDLE = 0, + ROAMING_STATE_DECISION, + ROAMING_STATE_DISCOVERY, + ROAMING_STATE_REQ_CAND_LIST, + ROAMING_STATE_ROAM, + ROAMING_STATE_NUM +}; + +struct ROAMING_INFO { + u_int8_t fgIsEnableRoaming; + + enum ENUM_ROAMING_STATE eCurrentState; + + OS_SYSTIME rRoamingDiscoveryUpdateTime; +#if CFG_SUPPORT_DRIVER_ROAMING + OS_SYSTIME rRoamingLastDecisionTime; +#endif + + u_int8_t fgDrvRoamingAllow; + struct TIMER rWaitCandidateTimer; + enum ENUM_ROAMING_REASON eReason; + uint8_t ucPER; + uint8_t ucRcpi; + uint8_t ucThreshold; +}; + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +void roamingFsmInit(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +void roamingFsmUninit(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +void roamingFsmSendCmd(IN struct ADAPTER *prAdapter, + IN struct CMD_ROAMING_TRANSIT *prTransit); + +void roamingFsmScanResultsUpdate(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +void roamingFsmSteps(IN struct ADAPTER *prAdapter, + IN enum ENUM_ROAMING_STATE eNextState, + IN uint8_t ucBssIndex); + +void roamingFsmRunEventStart(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +void roamingFsmRunEventDiscovery(IN struct ADAPTER *prAdapter, + IN struct CMD_ROAMING_TRANSIT *prTransit); + +void roamingFsmRunEventRoam(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +void roamingFsmRunEventFail(IN struct ADAPTER *prAdapter, + IN uint32_t u4Reason, + IN uint8_t ucBssIndex); + +void roamingFsmRunEventAbort(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +uint32_t roamingFsmProcessEvent(IN struct ADAPTER *prAdapter, + IN struct CMD_ROAMING_TRANSIT *prTransit); + +#endif /* _ROAMING_FSM_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/rrm.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/rrm.h new file mode 100644 index 0000000000000000000000000000000000000000..f30e7d7ba436e6c081b3012c782c70238a79a1a0 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/rrm.h @@ -0,0 +1,201 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef _RRM_H +#define _RRM_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/* Radio Measurement Request Mode definition */ +#define RM_REQ_MODE_PARALLEL_BIT BIT(0) +#define RM_REQ_MODE_ENABLE_BIT BIT(1) +#define RM_REQ_MODE_REQUEST_BIT BIT(2) +#define RM_REQ_MODE_REPORT_BIT BIT(3) +#define RM_REQ_MODE_DURATION_MANDATORY_BIT BIT(4) +#define RM_REP_MODE_LATE BIT(0) +#define RM_REP_MODE_INCAPABLE BIT(1) +#define RM_REP_MODE_REFUSED BIT(2) + +/* Radio Measurement Report Frame Max Length */ +#define RM_REPORT_FRAME_MAX_LENGTH (1600 - NIC_TX_DESC_AND_PADDING_LENGTH) +/* beacon request mode definition */ +#define RM_BCN_REQ_PASSIVE_MODE 0 +#define RM_BCN_REQ_ACTIVE_MODE 1 +#define RM_BCN_REQ_TABLE_MODE 2 + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +enum BCN_RM_STATE { + RM_NO_REQUEST, + RM_ON_GOING, + RM_WAITING, /*waiting normal scan done */ +}; + +enum RM_REQ_PRIORITY { + RM_PRI_BROADCAST, + RM_PRI_MULTICAST, + RM_PRI_UNICAST +}; + +struct NORMAL_SCAN_PARAMS { + struct PARAM_SCAN_REQUEST_ADV rScanRequest; + uint8_t aucScanIEBuf[MAX_IE_LENGTH]; + u_int8_t fgExist; +}; + +/* Beacon RM related parameters */ +struct BCN_RM_PARAMS { + enum BCN_RM_STATE eState; + struct NORMAL_SCAN_PARAMS rNormalScan; + + uint8_t token; + uint8_t lastIndication; + u8 ssid[ELEM_MAX_LEN_SSID]; + size_t ssidLen; + enum BEACON_REPORT_DETAIL reportDetail; + uint8_t *reportIeIds; + uint8_t reportIeIdsLen; + uint8_t *apChannels; + uint8_t apChannelsLen; +}; + +struct RM_BEACON_REPORT_PARAMS { + uint8_t ucChannel; + uint8_t ucRCPI; + uint8_t ucRSNI; + uint8_t ucAntennaID; + uint8_t ucFrameInfo; + uint8_t aucBcnFixedField[12]; +}; + +struct RM_MEASURE_REPORT_ENTRY { + struct LINK_ENTRY rLinkEntry; + uint8_t aucBSSID[MAC_ADDR_LEN]; + uint16_t u2MeasReportLen; + uint8_t *pucMeasReport; +}; + +struct RADIO_MEASUREMENT_REQ_PARAMS { + /* Remain Request Elements Length, started at prMeasElem. if it is 0, + * means RM is done + */ + uint16_t u2RemainReqLen; + uint16_t u2ReqIeBufLen; + struct IE_MEASUREMENT_REQ *prCurrMeasElem; + OS_SYSTIME rStartTime; + uint16_t u2Repetitions; + uint8_t *pucReqIeBuf; + enum RM_REQ_PRIORITY ePriority; + u_int8_t fgRmIsOngoing; + u_int8_t fgInitialLoop; + OS_SYSTIME rScanStartTime; + + struct BCN_RM_PARAMS rBcnRmParam; +}; + +struct RADIO_MEASUREMENT_REPORT_PARAMS { + /* the total length of Measurement Report elements */ + uint16_t u2ReportFrameLen; + uint8_t *pucReportFrameBuff; + /* Variables to collect report */ + struct LINK rReportLink; /* a link to save received report entry */ +}; + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +void rrmParamInit(struct ADAPTER *prAdapter, uint8_t ucBssIndex); + +void rrmParamUninit(struct ADAPTER *prAdapter, uint8_t ucBssIndex); + +void rrmProcessNeighborReportResonse(struct ADAPTER *prAdapter, + struct WLAN_ACTION_FRAME *prAction, + struct SW_RFB *prSwRfb); + +void rrmTxNeighborReportRequest(struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + struct SUB_ELEMENT_LIST *prSubIEs); + +void rrmGenerateRRMEnabledCapIE(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo); + +void rrmProcessRadioMeasurementRequest(struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb); + +void rrmProcessLinkMeasurementRequest(struct ADAPTER *prAdapter, + struct WLAN_ACTION_FRAME *prAction); + +void rrmFillRrmCapa(uint8_t *pucCapa); + +void rrmStartNextMeasurement(struct ADAPTER *prAdapter, u_int8_t fgNewStarted, + uint8_t ucBssIndex); + + +u_int8_t rrmFillScanMsg(struct ADAPTER *prAdapter, + struct MSG_SCN_SCAN_REQ_V2 *prMsg); + +void rrmDoBeaconMeasurement(struct ADAPTER *prAdapter, unsigned long ulParam); + +void rrmTxNeighborReportRequest(struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + struct SUB_ELEMENT_LIST *prSubIEs); + +void rrmTxRadioMeasurementReport(struct ADAPTER *prAdapter, + uint8_t ucBssIndex); + +void rrmFreeMeasurementResources(struct ADAPTER *prAdapter, + uint8_t ucBssIndex); + +enum RM_REQ_PRIORITY rrmGetRmRequestPriority(uint8_t *pucDestAddr); + +void rrmRunEventProcessNextRm(struct ADAPTER *prAdapter, + struct MSG_HDR *prMsgHdr); + +void rrmScheduleNextRm(struct ADAPTER *prAdapter, + uint8_t ucBssIndex); + +void rrmUpdateBssTimeTsf(struct ADAPTER *prAdapter, struct BSS_DESC *prBssDesc); + +void rrmCollectBeaconReport(IN struct ADAPTER *prAdapter, + IN struct BSS_DESC *prBssDesc, IN uint8_t ucBssIndex); + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#endif /* _RRM_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/rsn.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/rsn.h new file mode 100644 index 0000000000000000000000000000000000000000..3f28eacc7989634d34339ff3a7dd49e5292f43ee --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/rsn.h @@ -0,0 +1,343 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: include/mgmt/rsn.h#1 + */ + +/*! \file rsn.h + * \brief The wpa/rsn related define, macro and structure are described here. + */ + +#ifndef _RSN_H +#define _RSN_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +/* ----- Definitions for Cipher Suite Selectors ----- */ +#define RSN_CIPHER_SUITE_USE_GROUP_KEY 0x00AC0F00 +#define RSN_CIPHER_SUITE_WEP40 0x01AC0F00 +#define RSN_CIPHER_SUITE_TKIP 0x02AC0F00 +#define RSN_CIPHER_SUITE_CCMP 0x04AC0F00 +#define RSN_CIPHER_SUITE_WEP104 0x05AC0F00 +#if CFG_SUPPORT_802_11W +#define RSN_CIPHER_SUITE_AES_128_CMAC 0x06AC0F00 +#endif +#define RSN_CIPHER_SUITE_GROUP_NOT_USED 0x07AC0F00 +#define RSN_CIPHER_SUITE_GCMP 0x08AC0F00 +#define RSN_CIPHER_SUITE_GCMP_256 0x09AC0F00 +#define RSN_CIPHER_SUITE_CCMP_256 0x0AAC0F00 +#define RSN_CIPHER_SUITE_BIP_GMAC_128 0x0BAC0F00 +#define RSN_CIPHER_SUITE_BIP_GMAC_256 0x0CAC0F00 +#define RSN_CIPHER_SUITE_BIP_CMAC_256 0x0DAC0F00 + +#define WPA_CIPHER_SUITE_NONE 0x00F25000 +#define WPA_CIPHER_SUITE_WEP40 0x01F25000 +#define WPA_CIPHER_SUITE_TKIP 0x02F25000 +#define WPA_CIPHER_SUITE_CCMP 0x04F25000 +#define WPA_CIPHER_SUITE_WEP104 0x05F25000 + +/* Definitions for Authentication and Key Management Suite Selectors */ +#define RSN_AKM_SUITE_NONE 0x00AC0F00 +#define RSN_AKM_SUITE_802_1X 0x01AC0F00 +#define RSN_AKM_SUITE_PSK 0x02AC0F00 +#define RSN_AKM_SUITE_FT_802_1X 0x03AC0F00 +#define RSN_AKM_SUITE_FT_PSK 0x04AC0F00 +#if KERNEL_VERSION(4, 12, 0) > CFG80211_VERSION_CODE +#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03 +#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04 +#endif +/* Add AKM SUITE for OWE since kernel haven't defined it. */ +#define WLAN_AKM_SUITE_OWE 0x000FAC12 +#if CFG_SUPPORT_802_11W +#define RSN_AKM_SUITE_802_1X_SHA256 0x05AC0F00 +#define RSN_AKM_SUITE_PSK_SHA256 0x06AC0F00 +#endif + +#define RSN_AKM_SUITE_TDLS 0x07AC0F00 +#define RSN_AKM_SUITE_SAE 0x08AC0F00 +#define RSN_AKM_SUITE_FT_OVER_SAE 0x09AC0F00 +#define RSN_AKM_SUITE_8021X_SUITE_B 0x0BAC0F00 +#define RSN_AKM_SUITE_8021X_SUITE_B_192 0x0CAC0F00 +#define RSN_AKM_SUITE_FILS_SHA256 0x0EAC0F00 +#define RSN_AKM_SUITE_FILS_SHA384 0x0FAC0F00 +#define RSN_AKM_SUITE_FT_FILS_SHA256 0x10AC0F00 +#define RSN_AKM_SUITE_FT_FILS_SHA384 0x11AC0F00 +#define RSN_AKM_SUITE_OWE 0x12AC0F00 + +#define WPA_AKM_SUITE_NONE 0x00F25000 +#define WPA_AKM_SUITE_802_1X 0x01F25000 +#define WPA_AKM_SUITE_PSK 0x02F25000 + +#define WFA_AKM_SUITE_OSEN 0x019A6F50 +/* this define should be in ieee80211.h, but kernel didn't update it. + * so we define here temporary + */ +#define WLAN_AKM_SUITE_OSEN 0x506f9a01 +#define WLAN_CIPHER_SUITE_NO_GROUP_ADDR 0x000fac07 + +/* The RSN IE len for associate request */ +#define ELEM_ID_RSN_LEN_FIXED 20 + +/* The WPA IE len for associate request */ +#define ELEM_ID_WPA_LEN_FIXED 22 + +#define MASK_RSNIE_CAP_PREAUTH BIT(0) + +#define GET_SELECTOR_TYPE(x) ((uint8_t)(((x) >> 24) & 0x000000FF)) +#define SET_SELECTOR_TYPE(x, y) (x = (((x) & 0x00FFFFFF) | \ + (((uint32_t)(y) << 24) & 0xFF000000))) + +#define AUTH_CIPHER_CCMP 0x00000008 + +/* Cihpher suite flags */ +#define CIPHER_FLAG_NONE 0x00000000 +#define CIPHER_FLAG_WEP40 0x00000001 /* BIT 1 */ +#define CIPHER_FLAG_TKIP 0x00000002 /* BIT 2 */ +#define CIPHER_FLAG_CCMP 0x00000008 /* BIT 3 */ +#define CIPHER_FLAG_WEP104 0x00000010 /* BIT 4 */ +#define CIPHER_FLAG_WEP128 0x00000020 /* BIT 5 */ +#define CIPHER_FLAG_GCMP256 0x00000080 /* BIT 7 */ + +#define TKIP_COUNTERMEASURE_SEC 60 /* seconds */ + +#if CFG_SUPPORT_802_11W +#define RSN_AUTH_MFP_DISABLED 0 /* MFP disabled */ +#define RSN_AUTH_MFP_OPTIONAL 1 /* MFP optional */ +#define RSN_AUTH_MFP_REQUIRED 2 /* MFP required */ +#endif + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/* Flags for PMKID Candidate list structure */ +#define EVENT_PMKID_CANDIDATE_PREAUTH_ENABLED 0x01 + +#define CONTROL_FLAG_UC_MGMT_NO_ENC BIT(5) + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ +#define RSN_IE(fp) ((struct RSN_INFO_ELEM *) fp) +#define WPA_IE(fp) ((struct WPA_INFO_ELEM *) fp) + +#define ELEM_MAX_LEN_ASSOC_RSP_WSC_IE (32 - ELEM_HDR_LEN) +#define ELEM_MAX_LEN_TIMEOUT_IE (5) + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +u_int8_t rsnParseRsnIE(IN struct ADAPTER *prAdapter, + IN struct RSN_INFO_ELEM *prInfoElem, + OUT struct RSN_INFO *prRsnInfo); + +u_int8_t rsnParseWpaIE(IN struct ADAPTER *prAdapter, + IN struct WPA_INFO_ELEM *prInfoElem, + OUT struct RSN_INFO *prWpaInfo); + +u_int8_t rsnSearchSupportedCipher(IN struct ADAPTER + *prAdapter, + IN uint32_t u4Cipher, OUT uint32_t *pu4Index, + IN uint8_t ucBssIndex); + +u_int8_t rsnIsSuitableBSS(IN struct ADAPTER *prAdapter, + IN struct BSS_DESC *prBss, + IN struct RSN_INFO *prBssRsnInfo, + IN uint8_t ucBssIndex); + +u_int8_t rsnSearchAKMSuite(IN struct ADAPTER *prAdapter, + IN uint32_t u4AkmSuite, OUT uint32_t *pu4Index, + IN uint8_t ucBssIndex); + +u_int8_t rsnPerformPolicySelection(IN struct ADAPTER + *prAdapter, + IN struct BSS_DESC *prBss, + IN uint8_t ucBssIndex); + +void rsnGenerateWpaNoneIE(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo); + +void rsnGenerateWPAIE(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo); + +void rsnGenerateRSNIE(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo); + +u_int8_t +rsnParseCheckForWFAInfoElem(IN struct ADAPTER *prAdapter, + IN uint8_t *pucBuf, OUT uint8_t *pucOuiType, + OUT uint16_t *pu2SubTypeVersion); + +#if CFG_SUPPORT_AAA +void rsnParserCheckForRSNCCMPPSK(struct ADAPTER *prAdapter, + struct RSN_INFO_ELEM *prIe, + struct STA_RECORD *prStaRec, + uint16_t *pu2StatusCode); +#endif + +void rsnTkipHandleMICFailure(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prSta, + IN u_int8_t fgErrorKeyType); + +struct PMKID_ENTRY *rsnSearchPmkidEntry(IN struct ADAPTER *prAdapter, + IN uint8_t *pucBssid, + IN uint8_t ucBssIndex); + +void rsnCheckPmkidCache(IN struct ADAPTER *prAdapter, + IN struct BSS_DESC *prBss, + IN uint8_t ucBssIndex); + +void rsnGeneratePmkidIndication(IN struct ADAPTER *prAdapter, + IN struct PARAM_PMKID_CANDIDATE *prCandi, + IN uint8_t ucBssIndex); + +uint32_t rsnSetPmkid(IN struct ADAPTER *prAdapter, + IN struct PARAM_PMKID *prPmkid); + +uint32_t rsnDelPmkid(IN struct ADAPTER *prAdapter, + IN struct PARAM_PMKID *prPmkid); + +uint32_t rsnFlushPmkid(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +#if CFG_SUPPORT_802_11W +uint32_t rsnCheckBipKeyInstalled(IN struct ADAPTER + *prAdapter, IN struct STA_RECORD *prStaRec); + +uint8_t rsnCheckSaQueryTimeout( + IN struct ADAPTER *prAdapter, IN uint8_t ucBssIdx); + +void rsnStartSaQueryTimer(IN struct ADAPTER *prAdapter, + IN unsigned long ulParamPtr); + +void rsnStartSaQuery(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIdx); + +void rsnStopSaQuery(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIdx); + +void rsnSaQueryRequest(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb); + +void rsnSaQueryAction(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb); + +uint16_t rsnPmfCapableValidation(IN struct ADAPTER + *prAdapter, IN struct BSS_INFO *prBssInfo, + IN struct STA_RECORD *prStaRec); + +void rsnPmfGenerateTimeoutIE(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo); + +void rsnApStartSaQuery(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec); + +void rsnApSaQueryAction(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb); + +#endif /* CFG_SUPPORT_802_11W */ + +#if CFG_SUPPORT_AAA +void rsnGenerateWSCIEForAssocRsp(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo); +#endif + +u_int8_t rsnParseOsenIE(struct ADAPTER *prAdapter, + struct IE_WFA_OSEN *prInfoElem, + struct RSN_INFO *prOsenInfo); + +#if CFG_SUPPORT_DETECT_SECURITY_MODE_CHANGE +u_int8_t rsnCheckSecurityModeChanged(struct ADAPTER + *prAdapter, struct BSS_INFO *prBssInfo, + struct BSS_DESC *prBssDesc); +#endif + +uint32_t rsnCalculateFTIELen(struct ADAPTER *prAdapter, uint8_t ucBssIdx, + struct STA_RECORD *prStaRec); + +void rsnGenerateFTIE(IN struct ADAPTER *prAdapter, + IN OUT struct MSDU_INFO *prMsduInfo); + +u_int8_t rsnIsFtOverTheAir(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIdx, IN uint8_t ucStaRecIdx); + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#endif /* _RSN_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/scan.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/scan.h new file mode 100644 index 0000000000000000000000000000000000000000..2d4d2ba2c96aa7d27876b31948409e9ecd2b2b41 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/scan.h @@ -0,0 +1,943 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: @(#) + */ + +/*! \file "scan.h" + * \brief + * + */ + + +#ifndef _SCAN_H +#define _SCAN_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +/*! Maximum buffer size of SCAN list */ +#define SCN_MAX_BUFFER_SIZE \ + (CFG_MAX_NUM_BSS_LIST * ALIGN_4(sizeof(struct BSS_DESC))) + +/* Remove SCAN result except the connected one. */ +#define SCN_RM_POLICY_EXCLUDE_CONNECTED BIT(0) + +/* Remove the timeout one */ +#define SCN_RM_POLICY_TIMEOUT BIT(1) + +/* Remove the oldest one with hidden ssid */ +#define SCN_RM_POLICY_OLDEST_HIDDEN BIT(2) + +/* If there are more than half BSS which has the same ssid as connection + * setting, remove the weakest one from them Else remove the weakest one. + */ +#define SCN_RM_POLICY_SMART_WEAKEST BIT(3) + +/* Remove entire SCAN result */ +#define SCN_RM_POLICY_ENTIRE BIT(4) + +/* Remove SCAN result except the specific one. */ +#define SCN_RM_POLICY_EXCLUDE_SPECIFIC_SSID BIT(5) + +/* This is used by POLICY SMART WEAKEST, If exceed this value, remove weakest + * struct BSS_DESC with same SSID first in large network. + */ +#define SCN_BSS_DESC_SAME_SSID_THRESHOLD 20 + +#define SCN_BSS_DESC_STALE_SEC 20 /* Scan Request Timeout */ + +/* For WFD scan need about 15s. */ +#define SCN_BSS_DESC_STALE_SEC_WFD 30 + +#define SCN_PROBE_DELAY_MSEC 0 + +#define SCN_ADHOC_BSS_DESC_TIMEOUT_SEC 5 /* Second. */ +#if CFG_ENABLE_WIFI_DIRECT +#if CFG_SUPPORT_WFD + /* Second. For WFD scan timeout. */ +#define SCN_ADHOC_BSS_DESC_TIMEOUT_SEC_WFD 20 +#endif +#endif + +#define SCAN_DONE_DIFFERENCE 3 + +/* Full2Partial */ +/* Define a full scan as scan channel number larger than this number */ +#define SCAN_FULL2PARTIAL_CHANNEL_NUM (20) +#define SCAN_CHANNEL_BITMAP_ARRAY_LEN (8) +#define BITS_OF_UINT (32) +#define BITS_OF_BYTE (8) + +/* dwell time setting, should align FW setting */ +#define SCAN_CHANNEL_DWELL_TIME_MIN_MSEC (42) + +/* dwell time setting, reduce APP trigger scan dwell time to 20 */ +#define SCAN_CHANNEL_MIN_DWELL_TIME_MSEC_APP (20) +#define SCAN_CHANNEL_DWELL_TIME_MSEC_APP (40) + +/*----------------------------------------------------------------------------*/ +/* MSG_SCN_SCAN_REQ */ +/*----------------------------------------------------------------------------*/ +#define SCAN_REQ_SSID_WILDCARD BIT(0) +#define SCAN_REQ_SSID_P2P_WILDCARD BIT(1) +#define SCAN_REQ_SSID_SPECIFIED \ + BIT(2) /* two probe req will be sent, wildcard and specified */ +#define SCAN_REQ_SSID_SPECIFIED_ONLY \ + BIT(3) /* only a specified ssid probe request will be sent */ + +/*----------------------------------------------------------------------------*/ +/* Support Multiple SSID SCAN */ +/*----------------------------------------------------------------------------*/ +#define SCN_SSID_MAX_NUM CFG_SCAN_SSID_MAX_NUM +#define SCN_SSID_MATCH_MAX_NUM CFG_SCAN_SSID_MATCH_MAX_NUM + +#if CFG_SUPPORT_AGPS_ASSIST +#define SCN_AGPS_AP_LIST_MAX_NUM 32 +#endif + +#define SCN_BSS_JOIN_FAIL_CNT_RESET_SEC 15 +#define SCN_BSS_JOIN_FAIL_RESET_STEP 2 + +#if CFG_SUPPORT_BATCH_SCAN +/*----------------------------------------------------------------------------*/ +/* SCAN_BATCH_REQ */ +/*----------------------------------------------------------------------------*/ +#define SCAN_BATCH_REQ_START BIT(0) +#define SCAN_BATCH_REQ_STOP BIT(1) +#define SCAN_BATCH_REQ_RESULT BIT(2) +#endif + +/* Support AP Setection */ +#define SCN_BSS_JOIN_FAIL_THRESOLD 4 + +#define SCN_CTRL_SCAN_CHANNEL_LISTEN_TIME_ENABLE BIT(1) +#define SCN_CTRL_IGNORE_AIS_FIX_CHANNEL BIT(1) +#define SCN_CTRL_ENABLE BIT(0) + +#define SCN_CTRL_DEFAULT_SCAN_CTRL SCN_CTRL_IGNORE_AIS_FIX_CHANNEL + +#define SCN_SCAN_DONE_PRINT_BUFFER_LENGTH 300 +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +enum ENUM_SCAN_TYPE { + SCAN_TYPE_PASSIVE_SCAN = 0, + SCAN_TYPE_ACTIVE_SCAN, + SCAN_TYPE_NUM +}; + +enum ENUM_SCAN_STATE { + SCAN_STATE_IDLE = 0, + SCAN_STATE_SCANNING, + SCAN_STATE_NUM +}; + +enum ENUM_FW_SCAN_STATE { + FW_SCAN_STATE_IDLE = 0, /* 0 */ + FW_SCAN_STATE_SCAN_START, /* 1 */ + FW_SCAN_STATE_REQ_CHANNEL, /* 2 */ + FW_SCAN_STATE_SET_CHANNEL, /* 3 */ + FW_SCAN_STATE_DELAYED_ACTIVE_PROB_REQ, /* 4 */ + FW_SCAN_STATE_ACTIVE_PROB_REQ, /* 5 */ + FW_SCAN_STATE_LISTEN, /* 6 */ + FW_SCAN_STATE_SCAN_DONE, /* 7 */ + FW_SCAN_STATE_NLO_START, /* 8 */ + FW_SCAN_STATE_NLO_HIT_CHECK, /* 9 */ + FW_SCAN_STATE_NLO_STOP, /* 10 */ + FW_SCAN_STATE_BATCH_START, /* 11 */ + FW_SCAN_STATE_BATCH_CHECK, /* 12 */ + FW_SCAN_STATE_BATCH_STOP, /* 13 */ + FW_SCAN_STATE_NUM /* 14 */ +}; + +enum ENUM_SCAN_CHANNEL { + SCAN_CHANNEL_FULL = 0, + SCAN_CHANNEL_2G4, + SCAN_CHANNEL_5G, + SCAN_CHANNEL_P2P_SOCIAL, + SCAN_CHANNEL_SPECIFIED, + SCAN_CHANNEL_NUM +}; + +struct MSG_SCN_FSM { + struct MSG_HDR rMsgHdr; /* Must be the first member */ + uint32_t u4Dummy; +}; + +enum ENUM_SCHED_SCAN_ACT { + SCHED_SCAN_ACT_ENABLE = 0, + SCHED_SCAN_ACT_DISABLE, +}; + +#define SCAN_LOG_PREFIX_MAX_LEN (16) +#define SCAN_LOG_MSG_MAX_LEN (500) +#define SCAN_LOG_BUFF_SIZE (200) +#define SCAN_LOG_DYN_ALLOC_MEM (0) + +enum ENUM_SCAN_LOG_PREFIX { + /* Scan */ + LOG_SCAN_REQ_K2D = 0, /* 0 */ + LOG_SCAN_REQ_D2F, + LOG_SCAN_RESULT_F2D, + LOG_SCAN_RESULT_D2K, + LOG_SCAN_DONE_F2D, + LOG_SCAN_DONE_D2K, /* 5 */ + + /* Sched scan */ + LOG_SCHED_SCAN_REQ_START_K2D, + LOG_SCHED_SCAN_REQ_START_D2F, + LOG_SCHED_SCAN_REQ_STOP_K2D, + LOG_SCHED_SCAN_REQ_STOP_D2F, + LOG_SCHED_SCAN_DONE_F2D, /* 10 */ + LOG_SCHED_SCAN_DONE_D2K, + + /* Scan abort */ + LOG_SCAN_ABORT_REQ_K2D, + LOG_SCAN_ABORT_REQ_D2F, + LOG_SCAN_ABORT_DONE_D2K, + + /* Driver only */ + LOG_SCAN_D2D, + + /* Last one */ + LOG_SCAN_MAX +}; + +/*----------------------------------------------------------------------------*/ +/* BSS Descriptors */ +/*----------------------------------------------------------------------------*/ +struct BSS_DESC { + struct LINK_ENTRY rLinkEntry; + /* Support AP Selection*/ + struct LINK_ENTRY rLinkEntryEss[KAL_AIS_NUM]; + + uint8_t aucBSSID[MAC_ADDR_LEN]; + + /* For IBSS, the SrcAddr is different from BSSID */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; + + /* If we are going to connect to this BSS (JOIN or ROAMING to another + * BSS), don't remove this record from BSS List. + * Is a Bitmap, Bit0: BSS0, Bit1: Bss1 + */ + u_int8_t fgIsConnecting; + + /* If we have connected to this BSS (NORMAL_TR), don't removed + * this record from BSS list. + * Is a Bitmap, Bit0: BSS0, Bit1: Bss1 + */ + u_int8_t fgIsConnected; + + /* When this flag is TRUE, means the SSID of this + * BSS is not known yet. + */ + u_int8_t fgIsHiddenSSID; + + uint8_t ucSSIDLen; + uint8_t aucSSID[ELEM_MAX_LEN_SSID]; + + OS_SYSTIME rUpdateTime; + + enum ENUM_BSS_TYPE eBSSType; + + uint16_t u2CapInfo; + + uint16_t u2BeaconInterval; + uint16_t u2ATIMWindow; + + uint16_t u2OperationalRateSet; + uint16_t u2BSSBasicRateSet; + u_int8_t fgIsUnknownBssBasicRate; + + u_int8_t fgIsERPPresent; + u_int8_t fgIsHTPresent; + u_int8_t fgIsVHTPresent; +#if (CFG_SUPPORT_802_11AX == 1) + u_int8_t fgIsHEPresent; +#endif + +#if (CFG_SUPPORT_802_11V_MBSSID == 1) + /* Max BSSID indicator. Range from 1 to 8. + * 0 means MBSSID function is disabled + */ + u_int8_t ucMaxBSSIDIndicator; + /* MBSSID index which DUT connected for this BSS. + * 0 means DUT connect to transmitted BSSID + */ + u_int8_t ucMBSSIDIndex; +#endif + + uint8_t ucPhyTypeSet; /* Available PHY Type Set of this BSS */ + + /* record from bcn or probe response */ + uint8_t ucVhtCapNumSoundingDimensions; + + uint8_t ucChannelNum; + + /* Record bandwidth for association process. Some AP will + * send association resp by 40MHz BW + */ + enum ENUM_CHNL_EXT eSco; + + enum ENUM_CHANNEL_WIDTH eChannelWidth; /* VHT operation ie */ + uint8_t ucCenterFreqS1; + uint8_t ucCenterFreqS2; + enum ENUM_BAND eBand; + + uint8_t ucDTIMPeriod; + u_int8_t fgTIMPresent; + + /* This BSS's TimeStamp is larger than us(TCL == 1 in RX_STATUS_T) */ + u_int8_t fgIsLargerTSF; + + uint8_t ucRCPI; + + /* A flag to indicate this BSS's WMM capability */ + uint8_t ucWmmFlag; + + /*! \brief The srbiter Search State will matched the scan result, + * and saved the selected cipher and akm, and report the score, + * for arbiter join state, join module will carry this target BSS + * to rsn generate ie function, for gen wpa/rsn ie + */ + uint32_t u4RsnSelectedGroupCipher; + uint32_t u4RsnSelectedPairwiseCipher; + uint32_t u4RsnSelectedAKMSuite; + + uint16_t u2RsnCap; + + struct RSN_INFO rRSNInfo; + struct RSN_INFO rWPAInfo; +#if 1 /* CFG_SUPPORT_WAPI */ + struct WAPI_INFO rIEWAPI; + u_int8_t fgIEWAPI; +#endif + u_int8_t fgIERSN; + u_int8_t fgIEWPA; + u_int8_t fgIEOsen; + + /*! \brief RSN parameters selected for connection */ + /*! \brief The Select score for final AP selection, + * 0, no sec, 1,2,3 group cipher is WEP, TKIP, CCMP + */ + uint8_t ucEncLevel; + +#if CFG_ENABLE_WIFI_DIRECT + u_int8_t fgIsP2PPresent; + u_int8_t fgIsP2PReport; /* TRUE: report to upper layer */ + struct P2P_DEVICE_DESC *prP2pDesc; + + /* For IBSS, the SrcAddr is different from BSSID */ + uint8_t aucIntendIfAddr[MAC_ADDR_LEN]; + +#if 0 /* TODO: Remove this */ + /* Device Capability Attribute. (P2P_DEV_CAPABILITY_XXXX) */ + uint8_t ucDevCapabilityBitmap; + + /* Group Capability Attribute. (P2P_GROUP_CAPABILITY_XXXX) */ + uint8_t ucGroupCapabilityBitmap; +#endif + + struct LINK rP2pDeviceList; + +/* P_LINK_T prP2pDeviceList; */ + + /* For + * 1. P2P Capability. + * 2. P2P Device ID. ( in aucSrcAddr[] ) + * 3. NOA (TODO:) + * 4. Extend Listen Timing. (Probe Rsp) (TODO:) + * 5. P2P Device Info. (Probe Rsp) + * 6. P2P Group Info. (Probe Rsp) + */ +#endif + + /* the beacon doesn't advertise the FT AKM but will + * use FT when supported clients connect + */ + uint8_t ucIsAdaptive11r; + + /* The received IE length exceed the maximum IE buffer size */ + u_int8_t fgIsIEOverflow; + + uint16_t u2RawLength; /* The byte count of aucRawBuf[] */ + uint16_t u2IELength; /* The byte count of aucIEBuf[] */ + + /* Place u8TimeStamp before aucIEBuf[1] to force DW align */ + union ULARGE_INTEGER u8TimeStamp; + + uint8_t aucRawBuf[CFG_RAW_BUFFER_SIZE]; + uint8_t aucIEBuf[CFG_IE_BUFFER_SIZE]; + uint16_t u2JoinStatus; + OS_SYSTIME rJoinFailTime; + + /* Support AP Selection */ + struct AIS_BLACKLIST_ITEM *prBlack; +#if CFG_SUPPORT_MBO + uint8_t fgIsDisallowed; +#endif + uint16_t u2StaCnt; + uint16_t u2AvaliableAC; /* Available Admission Capacity */ + uint8_t ucJoinFailureCount; + uint8_t ucChnlUtilization; + uint8_t ucSNR; + u_int8_t fgSeenProbeResp; + u_int8_t fgExsitBssLoadIE; + u_int8_t fgMultiAnttenaAndSTBC; + uint32_t u4UpdateIdx; + uint8_t fgIotApActionValid; + uint8_t ucIotApAct; +#if CFG_SUPPORT_RSN_SCORE + u_int8_t fgIsRSNSuitableBss; +#endif + /* end Support AP Selection */ + int8_t cPowerLimit; + uint8_t aucRrmCap[5]; +#if CFG_SUPPORT_HE_ER + uint8_t fgIsERSUDisable; + uint8_t ucDCMMaxConRx; +#endif +}; + +struct SCAN_PARAM { /* Used by SCAN FSM */ + /* Active or Passive */ + enum ENUM_SCAN_TYPE eScanType; + + /* Network Type */ + uint8_t ucBssIndex; + + /* Specified SSID Type */ + uint8_t ucSSIDType; + uint8_t ucSSIDNum; + + /* Length of Specified SSID */ + uint8_t ucSpecifiedSSIDLen[SCN_SSID_MAX_NUM]; + + /* Specified SSID */ + uint8_t aucSpecifiedSSID[SCN_SSID_MAX_NUM][ELEM_MAX_LEN_SSID]; + +#if CFG_ENABLE_WIFI_DIRECT + u_int8_t fgFindSpecificDev; /* P2P: Discovery Protocol */ + uint8_t aucDiscoverDevAddr[MAC_ADDR_LEN]; + u_int8_t fgIsDevType; + struct P2P_DEVICE_TYPE rDiscoverDevType; + + /* TODO: Find Specific Device Type. */ +#endif /* CFG_ENABLE_WIFI_DIRECT */ + + uint16_t u2ChannelDwellTime; + uint16_t u2ChannelMinDwellTime; + uint16_t u2TimeoutValue; + + uint8_t aucBSSID[MAC_ADDR_LEN]; + + enum ENUM_MSG_ID eMsgId; + u_int8_t fgIsScanV2; + + /* Run time flags */ + uint16_t u2ProbeDelayTime; + + /* channel information */ + enum ENUM_SCAN_CHANNEL eScanChannel; + uint8_t ucChannelListNum; + struct RF_CHANNEL_INFO arChnlInfoList[MAXIMUM_OPERATION_CHANNEL_LIST]; + + /* random mac */ + uint8_t ucScnFuncMask; + uint8_t aucRandomMac[MAC_ADDR_LEN]; + + /* Feedback information */ + uint8_t ucSeqNum; + + /* Information Element */ + uint16_t u2IELen; + uint8_t aucIE[MAX_IE_LENGTH]; + +}; + +struct SCHED_SCAN_PARAM { /* Used by SCAN FSM */ + uint8_t ucSeqNum; + uint8_t ucBssIndex; /* Network Type */ + u_int8_t fgStopAfterIndication; /* always FALSE */ + uint8_t ucMatchSSIDNum; /* Match SSID */ + struct BSS_DESC *aprPendingBssDescToInd[SCN_SSID_MATCH_MAX_NUM]; +}; + +struct SCAN_LOG_ELEM_BSS { + struct LINK_ENTRY rLinkEntry; + + uint8_t aucBSSID[MAC_ADDR_LEN]; + uint16_t u2SeqCtrl; +}; + +struct SCAN_LOG_CACHE { + struct LINK rBSSListFW; + struct LINK rBSSListCFG; + + struct SCAN_LOG_ELEM_BSS arBSSListBufFW[SCAN_LOG_BUFF_SIZE]; + struct SCAN_LOG_ELEM_BSS arBSSListBufCFG[SCAN_LOG_BUFF_SIZE]; +}; + +struct SCAN_INFO { + /* Store the STATE variable of SCAN FSM */ + enum ENUM_SCAN_STATE eCurrentState; + + OS_SYSTIME rLastScanCompletedTime; + + struct SCAN_PARAM rScanParam; + struct SCHED_SCAN_PARAM rSchedScanParam; + + uint32_t u4NumOfBssDesc; + + uint8_t aucScanBuffer[SCN_MAX_BUFFER_SIZE]; + + struct LINK rBSSDescList; + + struct LINK rFreeBSSDescList; + + struct LINK rPendingMsgList; + + /* Sparse Channel Detection */ + u_int8_t fgIsSparseChannelValid; + struct RF_CHANNEL_INFO rSparseChannel; + + /* Sched scan state tracking */ + u_int8_t fgSchedScanning; + + /* Full2Partial */ + OS_SYSTIME u4LastFullScanTime; + u_int8_t fgIsScanForFull2Partial; + u_int8_t ucFull2PartialSeq; + uint32_t au4ChannelBitMap[SCAN_CHANNEL_BITMAP_ARRAY_LEN]; + + /*channel idle count # Mike */ + uint8_t ucSparseChannelArrayValidNum; + uint8_t aucReserved[3]; + uint8_t aucChannelNum[64]; + uint16_t au2ChannelIdleTime[64]; + /* Mdrdy Count in each Channel */ + uint8_t aucChannelMDRDYCnt[64]; + /* Beacon and Probe Response Count in each Channel */ + uint8_t aucChannelBAndPCnt[64]; + uint16_t au2ChannelScanTime[64]; + /* Support AP Selection */ + uint32_t u4ScanUpdateIdx; + + /* Scan log cache */ + struct SCAN_LOG_CACHE rScanLogCache; +}; + +/* Incoming Mailbox Messages */ +struct MSG_SCN_SCAN_REQ { + struct MSG_HDR rMsgHdr; /* Must be the first member */ + uint8_t ucSeqNum; + uint8_t ucBssIndex; + enum ENUM_SCAN_TYPE eScanType; + + /* BIT(0) wildcard / BIT(1) P2P-wildcard / BIT(2) specific */ + uint8_t ucSSIDType; + + uint8_t ucSSIDLength; + uint8_t aucSSID[PARAM_MAX_LEN_SSID]; + uint16_t u2ChannelDwellTime; /* ms unit */ + uint16_t u2TimeoutValue; /* ms unit */ + enum ENUM_SCAN_CHANNEL eScanChannel; + uint8_t ucChannelListNum; + struct RF_CHANNEL_INFO arChnlInfoList[MAXIMUM_OPERATION_CHANNEL_LIST]; + uint16_t u2IELen; + uint8_t aucIE[MAX_IE_LENGTH]; +}; + +struct MSG_SCN_SCAN_REQ_V2 { + struct MSG_HDR rMsgHdr; /* Must be the first member */ + uint8_t ucSeqNum; + uint8_t ucBssIndex; + enum ENUM_SCAN_TYPE eScanType; + + /* BIT(0) wildcard / BIT(1) P2P-wildcard / BIT(2) specific */ + uint8_t ucSSIDType; + + uint8_t ucSSIDNum; + struct PARAM_SSID *prSsid; + uint16_t u2ProbeDelay; + uint16_t u2ChannelDwellTime; /* In TU. 1024us. */ + uint16_t u2ChannelMinDwellTime; /* In TU. 1024us. */ + uint16_t u2TimeoutValue; /* ms unit */ + + uint8_t aucBSSID[MAC_ADDR_LEN]; + enum ENUM_SCAN_CHANNEL eScanChannel; + uint8_t ucChannelListNum; + struct RF_CHANNEL_INFO arChnlInfoList[MAXIMUM_OPERATION_CHANNEL_LIST]; + uint8_t ucScnFuncMask; + uint8_t aucRandomMac[MAC_ADDR_LEN]; /* random mac */ + uint16_t u2IELen; + uint8_t aucIE[MAX_IE_LENGTH]; +}; + +struct MSG_SCN_SCAN_CANCEL { + struct MSG_HDR rMsgHdr; /* Must be the first member */ + uint8_t ucSeqNum; + uint8_t ucBssIndex; + u_int8_t fgIsChannelExt; + u_int8_t fgIsOidRequest; +}; + +/* Outgoing Mailbox Messages */ +enum ENUM_SCAN_STATUS { + SCAN_STATUS_DONE = 0, + SCAN_STATUS_CANCELLED, + SCAN_STATUS_FAIL, + SCAN_STATUS_BUSY, + SCAN_STATUS_NUM +}; + +struct MSG_SCN_SCAN_DONE { + struct MSG_HDR rMsgHdr; /* Must be the first member */ + uint8_t ucSeqNum; + uint8_t ucBssIndex; + enum ENUM_SCAN_STATUS eScanStatus; +}; + +#if CFG_SUPPORT_AGPS_ASSIST +enum AP_PHY_TYPE { + AGPS_PHY_A, + AGPS_PHY_B, + AGPS_PHY_G, +}; + +struct AGPS_AP_INFO { + uint8_t aucBSSID[MAC_ADDR_LEN]; + int16_t i2ApRssi; /* -127..128 */ + uint16_t u2Channel; /* 0..256 */ + enum AP_PHY_TYPE ePhyType; +}; + +struct AGPS_AP_LIST { + uint8_t ucNum; + struct AGPS_AP_INFO arApInfo[SCN_AGPS_AP_LIST_MAX_NUM]; +}; +#endif +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ +extern const char aucScanLogPrefix[][SCAN_LOG_PREFIX_MAX_LEN]; + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ +#if DBG_DISABLE_ALL_LOG +#define scanlog_dbg(prefix, _Clz, _Fmt, ...) +#else /* DBG_DISABLE_ALL_LOG */ +#define scanlog_dbg(prefix, _Clz, _Fmt, ...) \ + do { \ + if ((aucDebugModule[DBG_SCN_IDX] & \ + DBG_CLASS_##_Clz) == 0) \ + break; \ + LOG_FUNC("[%u]SCANLOG:(SCN " #_Clz ") %s " _Fmt, \ + KAL_GET_CURRENT_THREAD_ID(), \ + aucScanLogPrefix[prefix], ##__VA_ARGS__); \ + } while (0) +#endif /* DBG_DISABLE_ALL_LOG */ + + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +/*----------------------------------------------------------------------------*/ +/* Routines in scan.c */ +/*----------------------------------------------------------------------------*/ +void scnInit(IN struct ADAPTER *prAdapter); + +void scnUninit(IN struct ADAPTER *prAdapter); + +/* Scan utilities */ +uint32_t scanCountBits(IN uint32_t bitMap[], IN uint32_t bitMapSize); + +void scanSetRequestChannel(IN struct ADAPTER *prAdapter, + IN uint32_t u4ScanChannelNum, + IN struct RF_CHANNEL_INFO arChannel[], + IN uint32_t u4ScanFlags, + IN uint8_t fgIsOnlineScan, + OUT struct MSG_SCN_SCAN_REQ_V2 *prScanReqMsg); + +/* BSS-DESC Search */ +struct BSS_DESC *scanSearchBssDescByBssid(IN struct ADAPTER *prAdapter, + IN uint8_t aucBSSID[]); + +struct BSS_DESC * +scanSearchBssDescByBssidAndSsid(IN struct ADAPTER *prAdapter, + IN uint8_t aucBSSID[], + IN u_int8_t fgCheckSsid, + IN struct PARAM_SSID *prSsid); + +struct BSS_DESC *scanSearchBssDescByTA(IN struct ADAPTER *prAdapter, + IN uint8_t aucSrcAddr[]); + +struct BSS_DESC * +scanSearchBssDescByTAAndSsid(IN struct ADAPTER *prAdapter, + IN uint8_t aucSrcAddr[], + IN u_int8_t fgCheckSsid, + IN struct PARAM_SSID *prSsid); + +/* BSS-DESC Search - Alternative */ +struct BSS_DESC * +scanSearchExistingBssDesc(IN struct ADAPTER *prAdapter, + IN enum ENUM_BSS_TYPE eBSSType, + IN uint8_t aucBSSID[], + IN uint8_t aucSrcAddr[]); + +struct BSS_DESC * +scanSearchExistingBssDescWithSsid(IN struct ADAPTER *prAdapter, + IN enum ENUM_BSS_TYPE eBSSType, + IN uint8_t aucBSSID[], + IN uint8_t aucSrcAddr[], + IN u_int8_t fgCheckSsid, + IN struct PARAM_SSID *prSsid); + +/* BSS-DESC Allocation */ +struct BSS_DESC *scanAllocateBssDesc(IN struct ADAPTER *prAdapter); + +/* BSS-DESC Removal */ +void scanRemoveBssDescsByPolicy(IN struct ADAPTER *prAdapter, + IN uint32_t u4RemovePolicy); + +void scanRemoveBssDescByBssid(IN struct ADAPTER *prAdapter, + IN uint8_t aucBSSID[]); + +void scanRemoveBssDescByBandAndNetwork( + IN struct ADAPTER *prAdapter, + IN enum ENUM_BAND eBand, + IN uint8_t ucBssIndex); + +/* BSS-DESC State Change */ +void scanRemoveConnFlagOfBssDescByBssid(IN struct ADAPTER *prAdapter, + IN uint8_t aucBSSID[], + IN uint8_t ucBssIndex); + +/* BSS-DESC Insertion - ALTERNATIVE */ +struct BSS_DESC *scanAddToBssDesc(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb); + +uint32_t scanProcessBeaconAndProbeResp(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSWRfb); + +void +scanBuildProbeReqFrameCommonIEs(IN struct MSDU_INFO *prMsduInfo, + IN uint8_t *pucDesiredSsid, + IN uint32_t u4DesiredSsidLen, + IN uint16_t u2SupportedRateSet); + +uint32_t scanSendProbeReqFrames(IN struct ADAPTER *prAdapter, + IN struct SCAN_PARAM *prScanParam); + +void scanUpdateBssDescForSearch(IN struct ADAPTER *prAdapter, + IN struct BSS_DESC *prBssDesc); + +struct BSS_DESC *scanSearchBssDescByPolicy(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +uint32_t scanAddScanResult(IN struct ADAPTER *prAdapter, + IN struct BSS_DESC *prBssDesc, + IN struct SW_RFB *prSwRfb); + +void scanReportBss2Cfg80211(IN struct ADAPTER *prAdapter, + IN enum ENUM_BSS_TYPE eBSSType, + IN struct BSS_DESC *SpecificprBssDesc); + +/*----------------------------------------------------------------------------*/ +/* Routines in scan_fsm.c */ +/*----------------------------------------------------------------------------*/ +void scnFsmSteps(IN struct ADAPTER *prAdapter, + IN enum ENUM_SCAN_STATE eNextState); + +/*----------------------------------------------------------------------------*/ +/* Command Routines */ +/*----------------------------------------------------------------------------*/ +void scnSendScanReq(IN struct ADAPTER *prAdapter); + +void scnSendScanReqV2(IN struct ADAPTER *prAdapter); + +/*----------------------------------------------------------------------------*/ +/* RX Event Handling */ +/*----------------------------------------------------------------------------*/ +void scnEventScanDone(IN struct ADAPTER *prAdapter, + IN struct EVENT_SCAN_DONE *prScanDone, + u_int8_t fgIsNewVersion); + +void scnEventSchedScanDone(IN struct ADAPTER *prAdapter, + IN struct EVENT_SCHED_SCAN_DONE *prSchedScanDone); + +/*----------------------------------------------------------------------------*/ +/* Mailbox Message Handling */ +/*----------------------------------------------------------------------------*/ +void scnFsmMsgStart(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); + +void scnFsmMsgAbort(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr); + +void scnFsmHandleScanMsg(IN struct ADAPTER *prAdapter, + IN struct MSG_SCN_SCAN_REQ *prScanReqMsg); + +void scnFsmHandleScanMsgV2(IN struct ADAPTER *prAdapter, + IN struct MSG_SCN_SCAN_REQ_V2 *prScanReqMsg); + +void scnFsmRemovePendingMsg(IN struct ADAPTER *prAdapter, + IN uint8_t ucSeqNum, + IN uint8_t ucBssIndex); + +/*----------------------------------------------------------------------------*/ +/* Mailbox Message Generation */ +/*----------------------------------------------------------------------------*/ +void +scnFsmGenerateScanDoneMsg(IN struct ADAPTER *prAdapter, + IN enum ENUM_MSG_ID eMsgId, + IN uint8_t ucSeqNum, + IN uint8_t ucBssIndex, + IN enum ENUM_SCAN_STATUS eScanStatus); + +/*----------------------------------------------------------------------------*/ +/* Query for sparse channel */ +/*----------------------------------------------------------------------------*/ +u_int8_t scnQuerySparseChannel(IN struct ADAPTER *prAdapter, + enum ENUM_BAND *prSparseBand, + uint8_t *pucSparseChannel); + +/*----------------------------------------------------------------------------*/ +/* OID/IOCTL Handling */ +/*----------------------------------------------------------------------------*/ +#if CFG_SUPPORT_PASSPOINT +struct BSS_DESC *scanSearchBssDescByBssidAndLatestUpdateTime( + IN struct ADAPTER *prAdapter, + IN uint8_t aucBSSID[]); +#endif /* CFG_SUPPORT_PASSPOINT */ + +#if CFG_SUPPORT_AGPS_ASSIST +void scanReportScanResultToAgps(struct ADAPTER *prAdapter); +#endif + +#if CFG_SUPPORT_SCHED_SCAN +u_int8_t scnFsmSchedScanRequest(IN struct ADAPTER *prAdapter, + IN struct PARAM_SCHED_SCAN_REQUEST *prSchedScanRequest); + +u_int8_t scnFsmSchedScanStopRequest(IN struct ADAPTER *prAdapter); + +u_int8_t scnFsmSchedScanSetAction(IN struct ADAPTER *prAdapter, + IN enum ENUM_SCHED_SCAN_ACT ucSchedScanAct); + +u_int8_t scnFsmSchedScanSetCmd(IN struct ADAPTER *prAdapter, + IN struct CMD_SCHED_SCAN_REQ *prSchedScanCmd); + +void scnSetSchedScanPlan(IN struct ADAPTER *prAdapter, + IN struct CMD_SCHED_SCAN_REQ *prSchedScanCmd); + +#endif /* CFG_SUPPORT_SCHED_SCAN */ + +void scanLogEssResult(struct ADAPTER *prAdapter); +void scanInitEssResult(struct ADAPTER *prAdapter); +#if CFG_SUPPORT_SCAN_CACHE_RESULT +/*----------------------------------------------------------------------------*/ +/* Routines in scan_cache.c */ +/*----------------------------------------------------------------------------*/ +u_int8_t isScanCacheDone(struct GL_SCAN_CACHE_INFO *prScanCache); +#endif /* CFG_SUPPORT_SCAN_CACHE_RESULT */ + +void scanReqLog(struct CMD_SCAN_REQ_V2 *prCmdScanReq); +void scanResultLog(struct ADAPTER *prAdapter, struct SW_RFB *prSwRfb); +void scanLogCacheAddBSS(struct LINK *prList, + struct SCAN_LOG_ELEM_BSS *prListBuf, + enum ENUM_SCAN_LOG_PREFIX prefix, + uint8_t bssId[], uint16_t seq); +void scanLogCacheFlushBSS(struct LINK *prList, + enum ENUM_SCAN_LOG_PREFIX prefix); +void scanLogCacheFlushAll(struct ADAPTER *prAdapter, + struct SCAN_LOG_CACHE *prScanLogCache, + enum ENUM_SCAN_LOG_PREFIX prefix); + +void scanRemoveBssDescFromList(IN struct LINK *prBSSDescList, + IN struct BSS_DESC *prBssDesc, + IN struct ADAPTER *prAdapter); +void scanInsertBssDescToList(IN struct LINK *prBSSDescList, + IN struct BSS_DESC *prBssDesc, + IN u_int8_t init); +void scanResetBssDesc(IN struct ADAPTER *prAdapter, + IN struct BSS_DESC *prBssDesc); + +/* Check if VHT IE filled in Epigram IE */ +void scanCheckEpigramVhtIE(IN uint8_t *pucBuf, IN struct BSS_DESC *prBssDesc); +void scanParseVHTCapIE(IN uint8_t *pucIE, IN struct BSS_DESC *prBssDesc); +void scanParseVHTOpIE(IN uint8_t *pucIE, IN struct BSS_DESC *prBssDesc); + +void scanCheckAdaptive11rIE(IN uint8_t *pucBuf, IN struct BSS_DESC *prBssDesc); + +#endif /* _SCAN_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/stats.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/stats.h new file mode 100644 index 0000000000000000000000000000000000000000..655186f1d24ea89c8030d1503db5b2216ba7b716 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/stats.h @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the + * GNU General Public License version 2 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. + * + * You should have received a copy of the GNU General Public License along + * with this program. + * If not, see . + */ + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O D E C L A R A T I O N S + ******************************************************************************* + */ + +#if (CFG_SUPPORT_STATISTICS == 1) +#define STATS_RX_PKT_INFO_DISPLAY StatsRxPktInfoDisplay +#define STATS_TX_PKT_INFO_DISPLAY StatsTxPktInfoDisplay +#else +#define STATS_RX_PKT_INFO_DISPLAY +#define STATS_TX_PKT_INFO_DISPLAY +#endif /* CFG_SUPPORT_STATISTICS */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E F U N C T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C F U N C T I O N S + ******************************************************************************* + */ + +#define STATS_TX_TIME_ARRIVE(__Skb__) \ +do { \ + uint64_t __SysTime; \ + __SysTime = StatsEnvTimeGet(); /* us */ \ + GLUE_SET_PKT_XTIME(__Skb__, __SysTime); \ +} while (FALSE) + +uint64_t StatsEnvTimeGet(void); + +void StatsEnvTxTime2Hif(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo); + +void StatsEnvRxTime2Host(IN struct ADAPTER *prAdapter, + struct sk_buff *prSkb, + struct net_device *prNetDev); + +void StatsRxPktInfoDisplay(struct SW_RFB *prSwRfb); + +void StatsTxPktInfoDisplay(struct sk_buff *prSkb); + +void StatsResetTxRx(void); + +void StatsEnvSetPktDelay(IN uint8_t ucTxOrRx, + IN uint8_t ucIpProto, IN uint16_t u2UdpPort, + uint32_t u4DelayThreshold); + +void StatsEnvGetPktDelay(OUT uint8_t *pucTxRxFlag, + OUT uint8_t *pucTxIpProto, OUT uint16_t *pu2TxUdpPort, + OUT uint32_t *pu4TxDelayThreshold, + OUT uint8_t *pucRxIpProto, + OUT uint16_t *pu2RxUdpPort, + OUT uint32_t *pu4RxDelayThreshold); +/* End of stats.h */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/swcr.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/swcr.h new file mode 100644 index 0000000000000000000000000000000000000000..c1467c6e25d74eb3332ff5538e155ff22147f68c --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/swcr.h @@ -0,0 +1,269 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/ + * MT6620_WIFI_DRIVER_V2_3/include/mgmt/swcr.h#1 + */ + +/*! \file "swcr.h" + * \brief + */ + +/* + * + */ + +#ifndef _SWCR_H +#define _SWCR_H + +#include "nic_cmd_event.h" + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#define TEST_PS 1 + +#define SWCR_VAR(x) ((void *)&x) +#define SWCR_FUNC(x) ((void *)x) + +#define SWCR_T_FUNC BIT(7) + +#define SWCR_L_32 3 +#define SWCR_L_16 2 +#define SWCR_L_8 1 + +#define SWCR_READ 0 +#define SWCR_WRITE 1 + +#define SWCR_MAP_NUM(x) (ARRAY_SIZE(x)) + +#define SWCR_CR_NUM 7 + +#define SWCR_GET_RW_INDEX(action, rw, index) \ +do { \ + index = action & 0x7F; \ + rw = action >> 7; \ +} while (0) + +extern uint32_t g_au4SwCr[]; /*: 0: command other: data */ + +typedef void(*PFN_SWCR_RW_T) (struct ADAPTER *prAdapter, + uint8_t ucRead, uint16_t u2Addr, uint32_t *pu4Data); +typedef void(*PFN_CMD_RW_T) (struct ADAPTER *prAdapter, + uint8_t ucCate, uint8_t ucAction, uint8_t ucOpt0, + uint8_t ucOpt1); + +struct SWCR_MAP_ENTRY { + uint16_t u2Type; + void *u4Addr; +}; + +struct SWCR_MOD_MAP_ENTRY { + uint8_t ucMapNum; + struct SWCR_MAP_ENTRY *prSwCrMap; +}; + +enum ENUM_SWCR_DBG_TYPE { + SWCR_DBG_TYPE_ALL = 0, + SWCR_DBG_TYPE_TXRX, + SWCR_DBG_TYPE_RX_RATES, + SWCR_DBG_TYPE_PS, + SWCR_DBG_TYPE_NUM +}; + +enum ENUM_SWCR_DBG_ALL { + SWCR_DBG_ALL_TX_CNT = 0, + SWCR_DBG_ALL_TX_BCN_CNT, + SWCR_DBG_ALL_TX_FAILED_CNT, + SWCR_DBG_ALL_TX_RETRY_CNT, + SWCR_DBG_ALL_TX_AGING_TIMEOUT_CNT, + SWCR_DBG_ALL_TX_PS_OVERFLOW_CNT, + SWCR_DBG_ALL_TX_MGNT_DROP_CNT, + SWCR_DBG_ALL_TX_ERROR_CNT, + + SWCR_DBG_ALL_RX_CNT, + SWCR_DBG_ALL_RX_DROP_CNT, + SWCR_DBG_ALL_RX_DUP_DROP_CNT, + SWCR_DBG_ALL_RX_TYPE_ERROR_DROP_CNT, + SWCR_DBG_ALL_RX_CLASS_ERROR_DROP_CNT, + SWCR_DBG_ALL_RX_AMPDU_ERROR_DROP_CNT, + + SWCR_DBG_ALL_RX_STATUS_ERROR_DROP_CNT, + SWCR_DBG_ALL_RX_FORMAT_ERROR_DROP_CNT, + SWCR_DBG_ALL_RX_ICV_ERROR_DROP_CNT, + SWCR_DBG_ALL_RX_KEY_ERROR_DROP_CNT, + SWCR_DBG_ALL_RX_TKIP_ERROR_DROP_CNT, + SWCR_DBG_ALL_RX_MIC_ERROR_DROP_CNT, + SWCR_DBG_ALL_RX_BIP_ERROR_DROP_CNT, + + SWCR_DBG_ALL_RX_FCSERR_CNT, + SWCR_DBG_ALL_RX_FIFOFULL_CNT, + SWCR_DBG_ALL_RX_PFDROP_CNT, + + SWCR_DBG_ALL_PWR_PS_POLL_CNT, + SWCR_DBG_ALL_PWR_TRIGGER_NULL_CNT, + SWCR_DBG_ALL_PWR_BCN_IND_CNT, + SWCR_DBG_ALL_PWR_BCN_TIMEOUT_CNT, + SWCR_DBG_ALL_PWR_PM_STATE0, + SWCR_DBG_ALL_PWR_PM_STATE1, + SWCR_DBG_ALL_PWR_CUR_PS_PROF0, + SWCR_DBG_ALL_PWR_CUR_PS_PROF1, + + SWCR_DBG_ALL_AR_STA0_RATE, + SWCR_DBG_ALL_AR_STA0_BWGI, + SWCR_DBG_ALL_AR_STA0_RX_RATE_RCPI, + + SWCR_DBG_ALL_ROAMING_ENABLE, + SWCR_DBG_ALL_ROAMING_ROAM_CNT, + SWCR_DBG_ALL_ROAMING_INT_CNT, + + SWCR_DBG_ALL_BB_RX_MDRDY_CNT, + SWCR_DBG_ALL_BB_RX_FCSERR_CNT, + SWCR_DBG_ALL_BB_CCK_PD_CNT, + SWCR_DBG_ALL_BB_OFDM_PD_CNT, + SWCR_DBG_ALL_BB_CCK_SFDERR_CNT, + SWCR_DBG_ALL_BB_CCK_SIGERR_CNT, + SWCR_DBG_ALL_BB_OFDM_TAGERR_CNT, + SWCR_DBG_ALL_BB_OFDM_SIGERR_CNT, + + SWCR_DBG_ALL_NUM +}; + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +void swCrReadWriteCmd(struct ADAPTER *prAdapter, + uint8_t ucRead, uint16_t u2Addr, uint32_t *pu4Data); + +/* Debug Support */ +void swCrFrameCheckEnable(struct ADAPTER *prAdapter, + uint32_t u4DumpType); +void swCrDebugInit(struct ADAPTER *prAdapter); +void swCrDebugCheckEnable(struct ADAPTER *prAdapter, + u_int8_t fgIsEnable, uint8_t ucType, uint32_t u4Timeout); +void swCrDebugUninit(struct ADAPTER *prAdapter); + +#if CFG_SUPPORT_SWCR +void swCtrlCmdCategory0(struct ADAPTER *prAdapter, + uint8_t ucCate, uint8_t ucAction, uint8_t ucOpt0, + uint8_t ucOpt1); +void swCtrlCmdCategory1(struct ADAPTER *prAdapter, + uint8_t ucCate, uint8_t ucAction, uint8_t ucOpt0, + uint8_t ucOpt1); +#if TEST_PS +void testPsCmdCategory0(struct ADAPTER *prAdapter, + uint8_t ucCate, uint8_t ucAction, uint8_t ucOpt0, + uint8_t ucOpt1); +void testPsCmdCategory1(struct ADAPTER *prAdapter, + uint8_t ucCate, uint8_t ucAction, uint8_t ucOpt0, + uint8_t ucOpt1); +#endif +#if CFG_SUPPORT_802_11V +#if (CFG_SUPPORT_802_11V_TIMING_MEASUREMENT == 1) && (WNM_UNIT_TEST == 1) +void testWNMCmdCategory0(struct ADAPTER *prAdapter, + uint8_t ucCate, uint8_t ucAction, uint8_t ucOpt0, + uint8_t ucOpt1); +#endif +#endif +void swCtrlSwCr(struct ADAPTER *prAdapter, uint8_t ucRead, + uint16_t u2Addr, uint32_t *pu4Data); + +/* Support Debug */ +void swCrDebugCheck(struct ADAPTER *prAdapter, + struct CMD_SW_DBG_CTRL *prCmdSwCtrl); +void swCrDebugCheckTimeout(IN struct ADAPTER *prAdapter, + unsigned long ulParamPtr); +void swCrDebugQuery(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf); +void swCrDebugQueryTimeout(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo); +#endif + +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/tdls.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/tdls.h new file mode 100644 index 0000000000000000000000000000000000000000..ec39932967eb63d7a56a111898e33ea179a59837 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/tdls.h @@ -0,0 +1,485 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: include/tdls.h#1 + */ + +/*! \file "tdls.h" + * \brief This file contains the internal used in TDLS modules + * for MediaTek Inc. 802.11 Wireless LAN Adapters. + */ + + +#ifndef _TDLS_H +#define _TDLS_H + +#if CFG_SUPPORT_TDLS + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ +#define TDLS_CFG_CMD_TEST + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/* assign station record idx for the packet */ +#define TDLSEX_STA_REC_IDX_GET(__prAdapter__, __MsduInfo__) \ +{ \ + struct STA_RECORD *__StaRec__; \ + __MsduInfo__->ucStaRecIndex = STA_REC_INDEX_NOT_FOUND; \ + __StaRec__ = cnmGetStaRecByAddress(__prAdapter__, \ + (uint8_t) NETWORK_TYPE_AIS_INDEX, \ + __MsduInfo__->aucEthDestAddr); \ + if ((__StaRec__ != NULL) && (IS_DLS_STA(__StaRec__))) \ + __MsduInfo__->ucStaRecIndex = __StaRec__->ucIndex; \ +} + +/* fill wiphy flag */ +#define TDLSEX_WIPHY_FLAGS_INIT(__fgFlag__) \ +{ \ + __fgFlag__ |= (WIPHY_FLAG_SUPPORTS_TDLS | \ + WIPHY_FLAG_TDLS_EXTERNAL_SETUP); \ +} + +#define LR_TDLS_FME_FIELD_FILL(__Len) \ +{ \ + pPkt += __Len; \ + u4PktLen += __Len; \ +} + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/* Status code */ +#define TDLS_STATUS uint32_t + +#define TDLS_STATUS_SUCCESS WLAN_STATUS_SUCCESS +#define TDLS_STATUS_FAIL WLAN_STATUS_FAILURE +#define TDLS_STATUS_INVALID_LENGTH WLAN_STATUS_INVALID_LENGTH +#define TDLS_STATUS_RESOURCES WLAN_STATUS_RESOURCES +#define TDLS_STATUS_PENDING WLAN_STATUS_PENDING + +#define TDLS_FME_MAC_ADDR_LEN 6 +#define TDLS_EX_CAP_PEER_UAPSD BIT(0) +#define TDLS_EX_CAP_CHAN_SWITCH BIT(1) +#define TDLS_EX_CAP_TDLS BIT(2) +#define TDLS_CMD_PEER_UPDATE_EXT_CAP_MAXLEN 5 +#define TDLS_CMD_PEER_UPDATE_SUP_RATE_MAX 50 +#define TDLS_CMD_PEER_UPDATE_SUP_CHAN_MAX 50 +#define TDLS_SEC_BUF_LENGTH 600 + +#define MAXNUM_TDLS_PEER 4 + +/* command */ +enum TDLS_CMD_ID { + TDLS_CMD_TEST_TX_FRAME = 0x00, + TDLS_CMD_TEST_RCV_FRAME, + TDLS_CMD_TEST_PEER_ADD, + TDLS_CMD_TEST_PEER_UPDATE, + TDLS_CMD_TEST_DATA_FRAME, + TDLS_CMD_TEST_RCV_NULL +}; + +/* protocol */ +#define TDLS_FRM_PROT_TYPE 0x890d + +/* payload specific type in the LLC/SNAP header */ +#define TDLS_FRM_PAYLOAD_TYPE 2 + +#define TDLS_FRM_CATEGORY 12 + +enum TDLS_FRM_ACTION_ID { + TDLS_FRM_ACTION_SETUP_REQ = 0x00, + TDLS_FRM_ACTION_SETUP_RSP, + TDLS_FRM_ACTION_CONFIRM, + TDLS_FRM_ACTION_TEARDOWN, + TDLS_FRM_ACTION_PTI, + TDLS_FRM_ACTION_CHAN_SWITCH_REQ, + TDLS_FRM_ACTION_CHAN_SWITCH_RSP, + TDLS_FRM_ACTION_PEER_PSM_REQ, + TDLS_FRM_ACTION_PEER_PSM_RSP, + TDLS_FRM_ACTION_PTI_RSP, + TDLS_FRM_ACTION_DISCOVERY_REQ, + TDLS_FRM_ACTION_DISCOVERY_RSP = 0x0e, + TDLS_FRM_ACTION_EVENT_TEAR_DOWN_TO_SUPPLICANT = 0x30 +}; + +/* 7.3.2.62 Link Identifier element */ +#define ELEM_ID_LINK_IDENTIFIER 101 + +struct IE_LINK_IDENTIFIER { + uint8_t ucId; + uint8_t ucLength; + uint8_t aBSSID[6]; + uint8_t aInitiator[6]; + uint8_t aResponder[6]; +} __KAL_ATTRIB_PACKED__; + +#define TDLS_LINK_IDENTIFIER_IE(__ie__) ((struct IE_LINK_IDENTIFIER *)(__ie__)) + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +struct STATION_PRARAMETERS { + const u8 *supported_rates; + struct net_device *vlan; + u32 sta_flags_mask, sta_flags_set; + u32 sta_modify_mask; + int listen_interval; + u16 aid; + u8 supported_rates_len; + u8 plink_action; + u8 plink_state; + u8 uapsd_queues; + u8 max_sp; + /* enum nl80211_mesh_power_mode local_pm; */ + u16 capability; + const u8 *ext_capab; + u8 ext_capab_len; +}; + +/* test command use */ +struct PARAM_CUSTOM_TDLS_CMD_STRUCT { + + uint8_t ucFmeType; /* TDLS_FRM_ACTION_ID */ + + uint8_t ucToken; + uint8_t ucCap; + + /* bit0: TDLS, bit1: Peer U-APSD Buffer, bit2: Channel Switching */ + + uint8_t ucExCap; + + uint8_t arSupRate[4]; + uint8_t arSupChan[4]; + + uint32_t u4Timeout; + + uint8_t arRspAddr[TDLS_FME_MAC_ADDR_LEN]; + uint8_t arBssid[TDLS_FME_MAC_ADDR_LEN]; + + /* Linux Kernel-3.10 */ + + /* struct */ + struct STATION_PRARAMETERS rPeerInfo; + +}; + +enum ENUM_TDLS_LINK_OPER { + TDLS_DISCOVERY_REQ, + TDLS_SETUP, + TDLS_TEARDOWN, + TDLS_ENABLE_LINK, + TDLS_DISABLE_LINK +}; + +struct TDLS_CMD_LINK_OPER { + + uint8_t aucPeerMac[6]; + enum ENUM_TDLS_LINK_OPER oper; + uint8_t ucBssIdx; +}; + +struct TDLS_CMD_LINK_MGT { + + uint8_t aucPeer[6]; + uint8_t ucActionCode; + uint8_t ucDialogToken; + uint16_t u2StatusCode; + uint32_t u4SecBufLen; + uint8_t aucSecBuf[TDLS_SEC_BUF_LENGTH]; + uint8_t ucBssIdx; +}; + +struct TDLS_CMD_PEER_ADD { + + uint8_t aucPeerMac[6]; + enum ENUM_STA_TYPE eStaType; +}; + +struct TDLS_CMD_PEER_UPDATE_HT_CAP_MCS_INFO { + uint8_t arRxMask[SUP_MCS_RX_BITMASK_OCTET_NUM]; + uint16_t u2RxHighest; + uint8_t ucTxParams; + uint8_t Reserved[3]; +}; + +struct TDLS_CMD_PEER_UPDATE_VHT_CAP_MCS_INFO { + uint8_t arRxMask[SUP_MCS_RX_BITMASK_OCTET_NUM]; +}; + +struct TDLS_CMD_PEER_UPDATE_HT_CAP { + uint16_t u2CapInfo; + uint8_t ucAmpduParamsInfo; + + /* 16 bytes MCS information */ + struct TDLS_CMD_PEER_UPDATE_HT_CAP_MCS_INFO rMCS; + + uint16_t u2ExtHtCapInfo; + uint32_t u4TxBfCapInfo; + uint8_t ucAntennaSelInfo; +}; + +struct TDLS_CMD_PEER_UPDATE_VHT_CAP { + uint16_t u2CapInfo; + /* 16 bytes MCS information */ + struct TDLS_CMD_PEER_UPDATE_VHT_CAP_MCS_INFO rVMCS; + +}; + +struct TDLS_CMD_PEER_UPDATE { + + uint8_t aucPeerMac[6]; + + uint8_t aucSupChan[TDLS_CMD_PEER_UPDATE_SUP_CHAN_MAX]; + + uint16_t u2StatusCode; + + uint8_t aucSupRate[TDLS_CMD_PEER_UPDATE_SUP_RATE_MAX]; + uint16_t u2SupRateLen; + + uint8_t UapsdBitmap; + uint8_t UapsdMaxSp; /* MAX_SP */ + + uint16_t u2Capability; + + uint8_t aucExtCap[TDLS_CMD_PEER_UPDATE_EXT_CAP_MAXLEN]; + uint16_t u2ExtCapLen; + + struct TDLS_CMD_PEER_UPDATE_HT_CAP rHtCap; + struct TDLS_CMD_PEER_UPDATE_VHT_CAP rVHtCap; + + u_int8_t fgIsSupHt; + enum ENUM_STA_TYPE eStaType; + +}; + +/* Command to TDLS core module */ +enum TDLS_CMD_CORE_ID { + TDLS_CORE_CMD_TEST_NULL_RCV = 0x00 +}; + +struct TDLS_CMD_CORE_TEST_NULL_RCV { + + uint32_t u4PM; +}; + +struct TDLS_CMD_CORE { + + uint32_t u4Command; + + uint8_t aucPeerMac[6]; + +#define TDLS_CMD_CORE_RESERVED_SIZE 50 + union { + struct TDLS_CMD_CORE_TEST_NULL_RCV rCmdNullRcv; + uint8_t Reserved[TDLS_CMD_CORE_RESERVED_SIZE]; + } Content; +}; + +enum TDLS_EVENT_HOST_ID { + TDLS_HOST_EVENT_TEAR_DOWN = 0x00, + TDLS_HOST_EVENT_TX_DONE +}; + +enum TDLS_EVENT_HOST_SUBID_TEAR_DOWN { + TDLS_HOST_EVENT_TD_PTI_TIMEOUT = 0x00, + TDLS_HOST_EVENT_TD_AGE_TIMEOUT, + TDLS_HOST_EVENT_TD_PTI_SEND_FAIL, + TDLS_HOST_EVENT_TD_PTI_SEND_MAX_FAIL, + TDLS_HOST_EVENT_TD_WRONG_NETWORK_IDX, + TDLS_HOST_EVENT_TD_NON_STATE3, + TDLS_HOST_EVENT_TD_LOST_TEAR_DOWN +}; + +enum TDLS_REASON_CODE { + TDLS_REASON_CODE_NONE = 0, + + TDLS_REASON_CODE_UNREACHABLE = 25, + TDLS_REASON_CODE_UNSPECIFIED = 26, + + TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_UNKNOWN = 0x80, /*128*/ + TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_WIFI_OFF = 0x81, /*129*/ + TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_ROAMING = 0x82, /*130*/ + TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_TIMEOUT = 0x83, /*131*/ + TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_AGE_TIMEOUT = 0x84, /*132*/ + TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_REKEY = 0x85, /*133*/ + TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_SEND_FAIL = 0x86, /*134*/ + TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_SEND_MAX_FAIL = 0x87,/*135*/ + TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_WRONG_NETWORK_IDX = 0x88,/*136*/ + TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_NON_STATE3 = 0x89, /*137*/ + TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_TX_QUOTA_EMPTY = 0x8a, /*138*/ + TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_LOST_TEAR_DOWN = 0x8b /*139*/ +}; + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +uint32_t TdlsFrameGeneralIeAppend(struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, uint8_t *pPkt); + +uint32_t /* TDLS_STATUS */ + +TdlsDataFrameSend_TearDown(struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + uint8_t *pPeerMac, + uint8_t ucActionCode, + uint8_t ucDialogToken, uint16_t u2StatusCode, + uint8_t *pAppendIe, uint32_t AppendIeLen); + +uint32_t /* TDLS_STATUS */ + +TdlsDataFrameSend_CONFIRM(struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + uint8_t *pPeerMac, + uint8_t ucActionCode, + uint8_t ucDialogToken, uint16_t u2StatusCode, + uint8_t *pAppendIe, uint32_t AppendIeLen); + +uint32_t /* TDLS_STATUS */ + +TdlsDataFrameSend_SETUP_REQ(struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + uint8_t *pPeerMac, + uint8_t ucActionCode, + uint8_t ucDialogToken, uint16_t u2StatusCode, + uint8_t *pAppendIe, uint32_t AppendIeLen); + +uint32_t /* TDLS_STATUS */ + +TdlsDataFrameSend_DISCOVERY_REQ(struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + uint8_t *pPeerMac, + uint8_t ucActionCode, + uint8_t ucDialogToken, uint16_t u2StatusCode, + uint8_t *pAppendIe, uint32_t AppendIeLen); + +uint32_t /* TDLS_STATUS */ + +TdlsDataFrameSend_SETUP_RSP(struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + uint8_t *pPeerMac, + uint8_t ucActionCode, + uint8_t ucDialogToken, uint16_t u2StatusCode, + uint8_t *pAppendIe, uint32_t AppendIeLen); + +uint32_t /* TDLS_STATUS */ + +TdlsDataFrameSend_DISCOVERY_RSP(struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + uint8_t *pPeerMac, + uint8_t ucActionCode, + uint8_t ucDialogToken, uint16_t u2StatusCode, + uint8_t *pAppendIe, uint32_t AppendIeLen); + +uint32_t TdlsexLinkOper(struct ADAPTER *prAdapter, + void *pvSetBuffer, uint32_t u4SetBufferLen, + uint32_t *pu4SetInfoLen); + +uint32_t TdlsexLinkMgt(struct ADAPTER *prAdapter, + void *pvSetBuffer, uint32_t u4SetBufferLen, + uint32_t *pu4SetInfoLen); + +void TdlsexEventHandle(struct GLUE_INFO *prGlueInfo, + uint8_t *prInBuf, uint32_t u4InBufLen); + +void TdlsEventTearDown(struct GLUE_INFO *prGlueInfo, + uint8_t *prInBuf, uint32_t u4InBufLen); + +void TdlsBssExtCapParse(struct STA_RECORD *prStaRec, + uint8_t *pucIE); + +uint32_t +TdlsSendChSwControlCmd(struct ADAPTER *prAdapter, + void *pvSetBuffer, uint32_t u4SetBufferLen, + uint32_t *pu4SetInfoLen); + +void TdlsHandleTxDoneStatus(struct ADAPTER *prAdapter, + enum ENUM_TX_RESULT_CODE rTxDoneStatus); + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#endif /* CFG_SUPPORT_TDLS */ + +#endif /* _TDLS_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/twt.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/twt.h new file mode 100644 index 0000000000000000000000000000000000000000..858caaa350522f13ee1437205d3d167833acfb64 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/twt.h @@ -0,0 +1,266 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2017 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2017 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +#ifndef _TWT_H +#define _TWT_H + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ +#define TWT_MAX_FLOW_NUM 8 +#define TWT_MAX_WAKE_INTVAL_EXP (TWT_REQ_TYPE_TWT_WAKE_INTVAL_EXP >> \ + TWT_REQ_TYPE_TWT_WAKE_INTVAL_EXP_OFFSET) + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ +enum _ENUM_TWT_SMART_STA_STATE_T { + TWT_SMART_STA_STATE_IDLE = 0, + TWT_SMART_STA_STATE_REQUESTING = 1, + TWT_SMART_STA_STATE_SUCCESS = 2, + TWT_SMART_STA_STATE_FAIL = 3 +}; + + +struct _TWT_SMART_STA_T { + u_int8_t fgTwtSmartStaReq; + u_int8_t fgTwtSmartStaActivated; + u_int8_t fgTwtSmartStaTeardownReq; + uint8_t ucBssIndex; + uint8_t ucFlowId; + uint32_t u4CurTp; + uint32_t u4LastTp; + uint32_t u4Count; + uint32_t u4TwtSwitch; + enum _ENUM_TWT_SMART_STA_STATE_T eState; +}; + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/* Macros for setting request type bit fields in TWT IE */ +#define SET_TWT_RT_REQUEST(fgReq) \ + (((fgReq) << TWT_REQ_TYPE_TWT_REQUEST_OFFSET) & \ + TWT_REQ_TYPE_TWT_REQUEST) + +#define SET_TWT_RT_SETUP_CMD(ucSetupCmd) \ + (((ucSetupCmd) << TWT_REQ_TYPE_TWT_SETUP_COMMAND_OFFSET) & \ + TWT_REQ_TYPE_TWT_SETUP_COMMAND) + +#define SET_TWT_RT_TRIGGER(fgTrigger) \ + (((fgTrigger) << TWT_REQ_TYPE_TRIGGER_OFFSET) & TWT_REQ_TYPE_TRIGGER) + +#define SET_TWT_RT_FLOW_TYPE(fgUnannounced) \ + (((fgUnannounced) << TWT_REQ_TYPE_FLOWTYPE_OFFSET) & \ + TWT_REQ_TYPE_FLOWTYPE) + +#define SET_TWT_RT_FLOW_ID(ucTWTFlowId) \ + (((ucTWTFlowId) << TWT_REQ_TYPE_TWT_FLOW_IDENTIFIER_OFFSET) & \ + TWT_REQ_TYPE_TWT_FLOW_IDENTIFIER) + +#define SET_TWT_RT_WAKE_INTVAL_EXP(ucWakeIntvlExponent) \ + (((ucWakeIntvlExponent) << TWT_REQ_TYPE_TWT_WAKE_INTVAL_EXP_OFFSET) & \ + TWT_REQ_TYPE_TWT_WAKE_INTVAL_EXP) + +#define SET_TWT_RT_PROTECTION(fgProtect) \ + (((fgProtect) << TWT_REQ_TYPE_TWT_PROTECTION_OFFSET) & \ + TWT_REQ_TYPE_TWT_PROTECTION) + +/* Macros for getting request type bit fields in TWT IE */ +#define GET_TWT_RT_REQUEST(u2ReqType) \ + (((u2ReqType) & TWT_REQ_TYPE_TWT_REQUEST) >> \ + TWT_REQ_TYPE_TWT_REQUEST_OFFSET) + +#define GET_TWT_RT_SETUP_CMD(u2ReqType) \ + (((u2ReqType) & TWT_REQ_TYPE_TWT_SETUP_COMMAND) >> \ + TWT_REQ_TYPE_TWT_SETUP_COMMAND_OFFSET) + +#define GET_TWT_RT_TRIGGER(u2ReqType) \ + (((u2ReqType) & TWT_REQ_TYPE_TRIGGER) >> TWT_REQ_TYPE_TRIGGER_OFFSET) + +#define GET_TWT_RT_FLOW_TYPE(u2ReqType) \ + (((u2ReqType) & TWT_REQ_TYPE_FLOWTYPE) >> TWT_REQ_TYPE_FLOWTYPE_OFFSET) + +#define GET_TWT_RT_FLOW_ID(u2ReqType) \ + (((u2ReqType) & TWT_REQ_TYPE_TWT_FLOW_IDENTIFIER) >> \ + TWT_REQ_TYPE_TWT_FLOW_IDENTIFIER_OFFSET) + +#define GET_TWT_RT_WAKE_INTVAL_EXP(u2ReqType) \ + (((u2ReqType) & TWT_REQ_TYPE_TWT_WAKE_INTVAL_EXP) >> \ + TWT_REQ_TYPE_TWT_WAKE_INTVAL_EXP_OFFSET) + +#define GET_TWT_RT_PROTECTION(u2ReqType) \ + (((u2ReqType) & TWT_REQ_TYPE_TWT_PROTECTION) >> \ + TWT_REQ_TYPE_TWT_PROTECTION_OFFSET) + +/* Macros to set TWT info field */ +#define SET_TWT_INFO_FLOW_ID(ucNextTWTCtrl) \ + (((ucNextTWTCtrl) << TWT_INFO_FLOW_ID_OFFSET) & TWT_INFO_FLOW_ID) + +#define SET_TWT_INFO_RESP_REQUESTED(ucNextTWTCtrl) \ + (((ucNextTWTCtrl) << TWT_INFO_RESP_REQUESTED_OFFSET) & \ + TWT_INFO_RESP_REQUESTED) + +#define SET_TWT_INFO_NEXT_TWT_REQ(ucNextTWTCtrl) \ + (((ucNextTWTCtrl) << TWT_INFO_NEXT_TWT_REQ_OFFSET) & \ + TWT_INFO_NEXT_TWT_REQ) + +#define SET_TWT_INFO_NEXT_TWT_SIZE(ucNextTWTCtrl) \ + (((ucNextTWTCtrl) << TWT_INFO_NEXT_TWT_SIZE_OFFSET) & \ + TWT_INFO_NEXT_TWT_SIZE) + +#define SET_TWT_INFO_BCAST_RESCHED(ucNextTWTCtrl) \ + (((ucNextTWTCtrl) << TWT_INFO_BCAST_RESCHED_OFFSET) & \ + TWT_INFO_BCAST_RESCHED) + +/* Macros to get TWT info field */ +#define GET_TWT_INFO_FLOW_ID(ucNextTWTCtrl) \ + (((ucNextTWTCtrl) & TWT_INFO_FLOW_ID) >> TWT_INFO_FLOW_ID_OFFSET) + +#define GET_TWT_INFO_RESP_REQUESTED(ucNextTWTCtrl) \ + (((ucNextTWTCtrl) & TWT_INFO_RESP_REQUESTED) >> \ + TWT_INFO_RESP_REQUESTED_OFFSET) + +#define GET_TWT_INFO_NEXT_TWT_REQ(ucNextTWTCtrl) \ + (((ucNextTWTCtrl) & TWT_INFO_NEXT_TWT_REQ) >> \ + TWT_INFO_NEXT_TWT_REQ_OFFSET) + +#define GET_TWT_INFO_NEXT_TWT_SIZE(ucNextTWTCtrl) \ + (((ucNextTWTCtrl) & TWT_INFO_NEXT_TWT_SIZE) >> \ + TWT_INFO_NEXT_TWT_SIZE_OFFSET) + +#define GET_TWT_INFO_BCAST_RESCHED(ucNextTWTCtrl) \ + (((ucNextTWTCtrl) & TWT_INFO_BCAST_RESCHED) >> \ + TWT_INFO_BCAST_RESCHED_OFFSET) + +/* Next TWT from the packet should be little endian */ +#define GET_48_BITS_NEXT_TWT_FROM_PKT(pMem) \ + ((u_int64_t)(*((u_int8_t *)(pMem))) | \ + ((u_int64_t)(*(((u_int8_t *)(pMem)) + 1)) >> 8) | \ + ((u_int64_t)(*(((u_int8_t *)(pMem)) + 2)) >> 16) | \ + ((u_int64_t)(*(((u_int8_t *)(pMem)) + 3)) >> 24) | \ + ((u_int64_t)(*(((u_int8_t *)(pMem)) + 4)) >> 32) | \ + ((u_int64_t)(*(((u_int8_t *)(pMem)) + 5)) >> 40)) + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +void twtProcessS1GAction( + struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb); + +uint32_t twtSendSetupFrame( + struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + u_int8_t ucTWTFlowId, + struct _TWT_PARAMS_T *prTWTParams, + PFN_TX_DONE_HANDLER pfTxDoneHandler); + +uint32_t twtSendTeardownFrame( + struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + u_int8_t ucTWTFlowId, + PFN_TX_DONE_HANDLER pfTxDoneHandler); + +uint32_t twtSendInfoFrame( + struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + u_int8_t ucTWTFlowId, + struct _NEXT_TWT_INFO_T *prNextTWTInfo, + PFN_TX_DONE_HANDLER pfTxDoneHandler); + +u_int8_t twtGetTxSetupFlowId( + struct MSDU_INFO *prMsduInfo); + +u_int8_t twtGetTxTeardownFlowId( + struct MSDU_INFO *prMsduInfo); + +uint8_t twtGetTxInfoFlowId( + struct MSDU_INFO *prMsduInfo); + +static inline u_int8_t twtGetNextTWTByteCnt(u_int8_t ucNextTWTSize) +{ + return (ucNextTWTSize == NEXT_TWT_SUBFIELD_64_BITS) ? 8 : + ((ucNextTWTSize == NEXT_TWT_SUBFIELD_32_BITS) ? 4 : + ((ucNextTWTSize == NEXT_TWT_SUBFIELD_48_BITS) ? 6 : 0)); +} +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _TWT_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/twt_planner.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/twt_planner.h new file mode 100644 index 0000000000000000000000000000000000000000..deb543eb783499fe0d38ea2ec5c0844bf5f374df --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/twt_planner.h @@ -0,0 +1,177 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2017 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2017 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +#ifndef _TWT_PLANNER_H +#define _TWT_PLANNER_H + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +struct _TWT_FLOW_T { + struct _TWT_PARAMS_T rTWTParams; + struct _TWT_PARAMS_T rTWTPeerParams; + u_int64_t u8NextTWT; +}; + +struct _TWT_AGRT_T { + u_int8_t fgValid; + u_int8_t ucAgrtTblIdx; + u_int8_t ucBssIdx; + u_int8_t ucFlowId; + struct _TWT_PARAMS_T rTWTAgrt; +}; + +struct _TWT_PLANNER_T { + struct _TWT_AGRT_T arTWTAgrtTbl[TWT_AGRT_MAX_NUM]; +}; + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +#define TSF_OFFSET_FOR_EMU (1 * 1000 * 1000) /* after 1 sec */ +#define TSF_OFFSET_FOR_AGRT_ADD (5 * 1000 * 1000) /* after 5 sec */ +#define TSF_OFFSET_FOR_AGRT_RESUME (5 * 1000 * 1000) /* after 5 sec */ + +/* Definitions for action control of TWT params */ +enum { + TWT_PARAM_ACTION_NONE = 0, + TWT_PARAM_ACTION_ADD_BYPASS = 1, /* bypass nego & add an agrt */ + TWT_PARAM_ACTION_DEL_BYPASS = 2, /* bypass proto & del an agrt */ + TWT_PARAM_ACTION_MOD_BYPASS = 3, /* bypass proto & modify an agrt */ + TWT_PARAM_ACTION_ADD = 4, + TWT_PARAM_ACTION_DEL = 5, + TWT_PARAM_ACTION_SUSPEND = 6, + TWT_PARAM_ACTION_RESUME = 7, + TWT_PARAM_ACTION_MAX +}; + +#define IS_TWT_PARAM_ACTION_ADD_BYPASS(ucCtrlAction) \ + ((ucCtrlAction) == TWT_PARAM_ACTION_ADD_BYPASS) +#define IS_TWT_PARAM_ACTION_DEL_BYPASS(ucCtrlAction) \ + ((ucCtrlAction) == TWT_PARAM_ACTION_DEL_BYPASS) +#define IS_TWT_PARAM_ACTION_MOD_BYPASS(ucCtrlAction) \ + ((ucCtrlAction) == TWT_PARAM_ACTION_MOD_BYPASS) +#define IS_TWT_PARAM_ACTION_ADD(ucCtrlAction) \ + ((ucCtrlAction) == TWT_PARAM_ACTION_ADD) +#define IS_TWT_PARAM_ACTION_DEL(ucCtrlAction) \ + ((ucCtrlAction) == TWT_PARAM_ACTION_DEL) +#define IS_TWT_PARAM_ACTION_SUSPEND(ucCtrlAction) \ + ((ucCtrlAction) == TWT_PARAM_ACTION_SUSPEND) +#define IS_TWT_PARAM_ACTION_RESUME(ucCtrlAction) \ + ((ucCtrlAction) == TWT_PARAM_ACTION_RESUME) + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +void twtPlannerSetParams( + struct ADAPTER *prAdapter, + struct MSG_HDR *prMsgHdr); + +uint32_t twtPlannerReset( + struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo); + +void twtPlannerRxNegoResult( + struct ADAPTER *prAdapter, + struct MSG_HDR *prMsgHdr); + +void twtPlannerSuspendDone( + struct ADAPTER *prAdapter, + struct MSG_HDR *prMsgHdr); + +void twtPlannerTeardownDone( + struct ADAPTER *prAdapter, + struct MSG_HDR *prMsgHdr); + +void twtPlannerResumeDone( + struct ADAPTER *prAdapter, + struct MSG_HDR *prMsgHdr); + +void twtPlannerRxInfoFrm( + struct ADAPTER *prAdapter, + struct MSG_HDR *prMsgHdr); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _TWT_PLANNER_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/twt_req_fsm.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/twt_req_fsm.h new file mode 100644 index 0000000000000000000000000000000000000000..d39a9908191d147659824380455e752b9b8cdceb --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/twt_req_fsm.h @@ -0,0 +1,154 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2017 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2017 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +#ifndef _TWT_REQ_FSM_H +#define _TWT_REQ_FSM_H + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +enum _ENUM_TWT_REQUESTER_STATE_T { + TWT_REQ_STATE_IDLE = 0, + TWT_REQ_STATE_REQTX, + TWT_REQ_STATE_WAIT_RSP, + TWT_REQ_STATE_SUSPENDING, + TWT_REQ_STATE_SUSPENDED, + TWT_REQ_STATE_RESUMING, + TWT_REQ_STATE_TEARING_DOWN, + TWT_REQ_STATE_RX_TEARDOWN, + TWT_REQ_STATE_RX_INFOFRM, + TWT_REQ_STATE_NUM +}; + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +u_int32_t +twtReqFsmRunEventTxDone( + struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo, + enum ENUM_TX_RESULT_CODE rTxDoneStatus); + +void twtReqFsmRunEventRxSetup( + struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb, + struct STA_RECORD *prStaRec, + u_int8_t ucTWTFlowId); + +void twtReqFsmRunEventRxTeardown( + struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb, + struct STA_RECORD *prStaRec, + u_int8_t ucTWTFlowId); + +void twtReqFsmRunEventRxInfoFrm( + struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb, + struct STA_RECORD *prStaRec, + u_int8_t ucTWTFlowId, + struct _NEXT_TWT_INFO_T *prNextTWTInfo); + +void twtReqFsmRunEventStart( + struct ADAPTER *prAdapter, + struct MSG_HDR *prMsgHdr); + +void twtReqFsmRunEventTeardown( + struct ADAPTER *prAdapter, + struct MSG_HDR *prMsgHdr); + +void twtReqFsmRunEventSuspend( + struct ADAPTER *prAdapter, + struct MSG_HDR *prMsgHdr); + +void twtReqFsmRunEventResume( + struct ADAPTER *prAdapter, + struct MSG_HDR *prMsgHdr); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _TWT_REQ_FSM_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/wapi.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/wapi.h new file mode 100644 index 0000000000000000000000000000000000000000..f1526409dcd875e0afb003511fd9e2c3f8a4ee1d --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/wapi.h @@ -0,0 +1,133 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/ + * include/mgmt/wapi.h#1 + */ + +/*! \file wapi.h + * \brief The wapi related define, macro and structure are described here. + */ + + +#ifndef _WAPI_H +#define _WAPI_H + +#if CFG_SUPPORT_WAPI + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ +#define WAPI_CIPHER_SUITE_WPI 0x01721400 /* WPI_SMS4 */ +#define WAPI_AKM_SUITE_802_1X 0x01721400 /* WAI */ +#define WAPI_AKM_SUITE_PSK 0x02721400 /* WAI_PSK */ + +#define ELEM_ID_WAPI 68 /* WAPI IE */ + +#define WAPI_IE(fp) ((struct WAPI_INFO_ELEM *) fp) + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +u_int8_t wapiParseWapiIE(IN struct WAPI_INFO_ELEM + *prInfoElem, OUT struct WAPI_INFO *prWapiInfo); + +u_int8_t wapiPerformPolicySelection( + IN struct ADAPTER *prAdapter, + IN struct BSS_DESC *prBss, + IN uint8_t ucBssIndex); + +/* BOOLEAN */ +/* wapiUpdateTxKeyIdx ( */ +/* IN P_STA_RECORD_T prStaRec, */ +/* IN UINT_8 ucWlanIdx */ +/* ); */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +#endif +#endif /* _WAPI_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/wlan_typedef.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/wlan_typedef.h new file mode 100644 index 0000000000000000000000000000000000000000..99ab88227616de2fe02d98cb611de8422ba62d76 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/wlan_typedef.h @@ -0,0 +1,156 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3 + * /include/mgmt/wlan_typedef.h#1 + */ + +/*! \file wlan_typedef.h + * \brief Declaration of data type and return values of internal protocol + * stack. + * + * In this file we declare the data type and return values which will be + * exported to all MGMT Protocol Stack. + */ + + +#ifndef _WLAN_TYPEDEF_H +#define _WLAN_TYPEDEF_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ +#define NIC_TX_ENABLE_SECOND_HW_QUEUE 0 + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +/* Type definition for BSS_INFO structure, to describe the + * attributes used in a common BSS. + */ +struct BSS_INFO; /* declare BSS_INFO_T */ +struct BSS_INFO; /* declare P2P_DEV_INFO_T */ + + +struct AIS_SPECIFIC_BSS_INFO; /* declare AIS_SPECIFIC_BSS_INFO_T */ +struct P2P_SPECIFIC_BSS_INFO; /* declare P2P_SPECIFIC_BSS_INFO_T */ +struct BOW_SPECIFIC_BSS_INFO; /* declare BOW_SPECIFIC_BSS_INFO_T */ +/* CFG_SUPPORT_WFD */ +struct WFD_CFG_SETTINGS; /* declare WFD_CFG_SETTINGS_T */ + +/* BSS related structures */ +/* Type definition for BSS_DESC structure, to describe parameter + * sets of a particular BSS + */ +struct BSS_DESC; /* declare BSS_DESC */ + +#if CFG_SUPPORT_PASSPOINT +struct HS20_INFO; /* declare HS20_INFO_T */ +#endif /* CFG_SUPPORT_PASSPOINT */ + +/* Tc Resource index */ +enum ENUM_TRAFFIC_CLASS_INDEX { + /*First HW queue */ + TC0_INDEX = 0, /* HIF TX: AC0 packets */ + TC1_INDEX, /* HIF TX: AC1 packets */ + TC2_INDEX, /* HIF TX: AC2 packets */ + TC3_INDEX, /* HIF TX: AC3 packets */ + TC4_INDEX, /* HIF TX: CPU packets */ + +#if NIC_TX_ENABLE_SECOND_HW_QUEUE + /* Second HW queue */ + TC5_INDEX, /* HIF TX: AC10 packets */ + TC6_INDEX, /* HIF TX: AC11 packets */ + TC7_INDEX, /* HIF TX: AC12 packets */ + TC8_INDEX, /* HIF TX: AC13 packets */ +#endif + + TC_NUM /* Maximum number of Traffic Classes. */ +}; + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +#endif /* _WLAN_TYPEDEF_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/wmm.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/wmm.h new file mode 100644 index 0000000000000000000000000000000000000000..b31b86f4c232f5937408fb74f95fcc2fd5294c9e --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/wmm.h @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software: you can redistribute it and/or modify it under + * the terms of the + * GNU General Public License version 2 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. + * + * You should have received a copy of the GNU General Public License along with + * this program. + * If not, see . + */ + +#ifndef WMM_HDR_H +#define WMM_HDR_H + +#define VENDOR_OUI_TYPE_TSRS 8 +#define VENDOR_OUI_TYPE_TSM 7 +#define VENDOR_OUI_TYPE_EDCALIFE 9 +#define WLAN_MAC_ACTION_ADDTS_LEN (WLAN_MAC_MGMT_HEADER_HTC_LEN + 66) +#define WLAN_MAC_ACTION_DELTS_LEN (WLAN_MAC_MGMT_HEADER_HTC_LEN + 7) +#define TSPEC_POLICY_CHECK_INTERVAL 2500 /* unit ms */ + +#define WMM_TS_STATUS_ADMISSION_ACCEPTED 0 +#define WMM_TS_STATUS_ADDTS_INVALID_PARAM 1 +#define WMM_TS_STATUS_ADDTS_REFUSED 3 +#define WMM_TS_STATUS_ASSOC_QOS_FAILED 0xc8 +#define WMM_TS_STATUS_POLICY_CONFIG_REFUSED 0xc9 +#define WMM_TS_STATUS_ASSOC_INSUFFICIENT_BANDWIDTH 0xca +#define WMM_TS_STATUS_ASSOC_INVALID_PARAM 0xcb + +#define CFG_SUPPORT_SOFT_ACM 1 /* do Admission Control in driver */ +/* + * In WMM, TSs are identified with TIDs values 0 through 7. Any TID may + * map onto any UP and thus onto any AC, however for each AC used between + * an RA and TA, only the following combinations are valid: + * No TS, One uplink TS, one Download link TS, one uplink and one uplink + * TS, one bi-directional TS. + * so maximum 8 TSs are allowed in a RA & TA context. + */ +#define WMM_TSPEC_ID_NUM 8 + +/*WMM-2.2.11 WMM TSPEC IE*/ +#define ELEM_MAX_LEN_WMM_TSPEC 61 + +enum WMM_ADDTS_STATUS { + ADDTS_ACCEPTED = 0, + ADDTS_INVALID_PARAMS = 1, + ADDTS_REFUSED = 2 +}; + +enum TSPEC_OP_CODE { + TX_ADDTS_REQ, + RX_ADDTS_RSP, + TX_DELTS_REQ, + RX_DELTS_REQ, + DISC_DELTS_REQ, + UPDATE_TS_REQ +}; + +enum QOS_TS_STATE { + QOS_TS_INACTIVE, + QOS_TS_ACTIVE, + QOS_TS_SETUPING, + QOS_TS_STATE_MAX +}; + +enum TSPEC_DIR { + UPLINK_TS = 0, + DOWNLINK_TS = 1, + BI_DIR_TS = 3 +}; + +struct TSPEC_INFO { + struct TIMER rAddTsTimer; + uint8_t ucToken; + u_int8_t fgUapsd; + enum ENUM_ACI eAC:8; + enum TSPEC_DIR eDir:8; + enum QOS_TS_STATE eState:8; + /* debug information */ + uint16_t u2MediumTime; + uint32_t u4PhyRate; + uint8_t ucTid; +}; + +struct TSM_TRIGGER_COND { + uint8_t ucCondition; + uint8_t ucAvgErrThreshold; + uint8_t ucConsecutiveErr; + uint8_t ucDelayThreshold; + uint8_t ucMeasureCount; + /* In this time frame, for one condition, only once report is allowed */ + uint8_t ucTriggerTimeout; +}; + +struct RM_TSM_REQ { + uint16_t u2Duration; /* unit: TUs */ + uint8_t aucPeerAddr[MAC_ADDR_LEN]; + uint8_t ucToken; + uint8_t ucTID; + uint8_t ucACI; + uint8_t ucB0Range; /* 2^(i-1)*ucB0Range =< delay < 2^i * ucB0Range */ + struct TSM_TRIGGER_COND rTriggerCond; +}; + +struct ACTIVE_RM_TSM_REQ { + struct LINK_ENTRY rLinkEntry; + struct RM_TSM_REQ *prTsmReq; + struct TIMER rTsmTimer; + uint8_t ucBssIdx; +}; + +#if CFG_SUPPORT_SOFT_ACM +struct SOFT_ACM_CTRL { + uint32_t u4RemainTime; + uint32_t u4AdmittedTime; + uint32_t u4IntervalEndSec; + uint16_t u2DeqNum; +}; +#endif + +struct WMM_INFO { + /* A TS is identified uniquely by its TID value within the context of + ** the RA and TA + ** the index is TID for this array + */ + struct TSPEC_INFO arTsInfo[WMM_TSPEC_ID_NUM]; + struct LINK rActiveTsmReq; + OS_SYSTIME rTriggeredTsmRptTime; + struct TIMER rTsmTimer; +#if CFG_SUPPORT_SOFT_ACM + struct TIMER rAcmDeqTimer; + struct SOFT_ACM_CTRL arAcmCtrl[ACI_NUM]; /* 0 ~ 3, BE, BK, VI, VO */ +#endif +}; + +struct WMM_ADDTS_RSP_STEP_PARAM { + uint8_t ucDlgToken; + uint8_t ucStatusCode; + uint8_t ucApsd; + enum TSPEC_DIR eDir:8; + uint16_t u2EdcaLifeTime; + uint16_t u2MediumTime; + uint32_t u4PhyRate; +}; + +struct MSG_TS_OPERATE { + struct MSG_HDR rMsgHdr; + enum TSPEC_OP_CODE eOpCode; + uint8_t ucTid; + struct PARAM_QOS_TSPEC rTspecParam; + uint8_t ucBssIdx; +}; + +#define WMM_TSINFO_TRAFFIC_TYPE(tsinfo) (tsinfo & BIT(0)) +#define WMM_TSINFO_TSID(tsinfo) ((tsinfo & BITS(1, 4)) >> 1) +#define WMM_TSINFO_DIR(tsinfo) ((tsinfo & BITS(5, 6)) >> 5) +#define WMM_TSINFO_AC(tsinfo) ((tsinfo & BITS(7, 8)) >> 7) +#define WMM_TSINFO_PSB(tsinfo) ((tsinfo & BIT(10)) >> 10) +#define WMM_TSINFO_UP(tsinfo) ((tsinfo & BITS(11, 13)) >> 11) + +#define TSM_TRIGGER_CONDITION_ALL BITS(0, 2) +#define TSM_TRIGGER_AVG BIT(0) +#define TSM_TRIGGER_CONSECUTIVE BIT(1) +#define TSM_TIRGGER_DELAY BIT(2) + +extern uint8_t const aucUp2ACIMap[8]; +void wmmFillTsinfo(struct PARAM_QOS_TSINFO *prTsInfo, uint8_t *pucTsInfo); +void wmmSetupTspecTimeOut(struct ADAPTER *prAdapter, unsigned long ulParam); +void wmmStartTsmMeasurement(struct ADAPTER *prAdapter, unsigned long ulParam, + uint8_t ucBssIndex); +void wmmRunEventTSOperate(struct ADAPTER *prAdapter, struct MSG_HDR *prMsgHdr); +u_int8_t wmmParseQosAction(struct ADAPTER *prAdapter, struct SW_RFB *prSwRfb); +u_int8_t wmmParseTspecIE(struct ADAPTER *prAdapter, uint8_t *pucIE, + struct PARAM_QOS_TSPEC *prTspec); +void wmmTspecSteps(struct ADAPTER *prAdapter, uint8_t ucTid, + enum TSPEC_OP_CODE eOpCode, void *prStepParams, uint8_t ucBssIndex); +uint8_t wmmHasActiveTspec(struct WMM_INFO *prWmmInfo); +void wmmNotifyDisconnected(struct ADAPTER *prAdapter, uint8_t ucBssIndex); +void wmmComposeTsmRpt(struct ADAPTER *prAdapter, struct CMD_INFO *prCmdInfo, + uint8_t *pucEventBuf); +void wmmInit(IN struct ADAPTER *prAdapter); +void wmmUnInit(IN struct ADAPTER *prAdapter); +u_int8_t wmmTsmIsOngoing(struct ADAPTER *prAdapter, uint8_t ucBssIndex); +void wmmRemoveAllTsmMeasurement(struct ADAPTER *prAdapter, + u_int8_t fgOnlyTriggered, uint8_t ucBssIndex); +uint8_t wmmCalculateUapsdSetting(struct ADAPTER *prAdapter, + uint8_t ucBssIndex); +uint32_t wmmDumpActiveTspecs(struct ADAPTER *prAdapter, uint8_t *pucBuffer, + uint16_t u2BufferLenu, uint8_t ucBssIndex); +#if CFG_SUPPORT_SOFT_ACM +u_int8_t wmmAcmCanDequeue(struct ADAPTER *prAdapter, uint8_t ucAc, + uint32_t u4PktTxTime, uint8_t ucBssIndex); +void wmmAcmTxStatistic(struct ADAPTER *prAdapter, uint8_t ucAc, + uint32_t u4Remain, uint16_t u2DeqNum); + +uint32_t wmmCalculatePktUsedTime(struct BSS_INFO *prBssInfo, + struct STA_RECORD *prStaRec, + uint16_t u2PktLen); +void wmmPrepareFastUsedTimeCal(struct ADAPTER *prAdapter); +uint32_t wmmFastCalPktUsedTime(struct WMM_INFO *prWmmInfo, uint8_t ucAc, + uint16_t u2PktLen); +#endif /* CFG_SUPPORT_SOFT_ACM */ +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/wnm.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/wnm.h new file mode 100644 index 0000000000000000000000000000000000000000..0f71de00afa7eb38aec99fa7dfc0eb4e738d721e --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/mgmt/wnm.h @@ -0,0 +1,184 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: //Department/DaVinci/TRUNK/MT6620_5931_WiFi_Driver/include/mgmt/wnm.h#1 + */ + +/*! \file wnm.h + * \brief This file contains the IEEE 802.11 family related 802.11v + * network management for MediaTek 802.11 Wireless LAN Adapters. + */ + + +#ifndef _WNM_H +#define _WNM_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +struct TIMINGMSMT_PARAM { + u_int8_t fgInitiator; + uint8_t ucTrigger; + uint8_t ucDialogToken; /* Dialog Token */ + uint8_t ucFollowUpDialogToken; /* Follow Up Dialog Token */ + uint32_t u4ToD; /* Timestamp of Departure [10ns] */ + uint32_t u4ToA; /* Timestamp of Arrival [10ns] */ +}; + +struct BSS_TRANSITION_MGT_PARAM_T { + /* for Query */ + uint8_t ucDialogToken; + uint8_t ucQueryReason; + /* for Request */ + uint8_t ucRequestMode; + uint16_t u2DisassocTimer; + uint16_t u2TermDuration; + uint8_t aucTermTsf[8]; + uint8_t ucSessionURLLen; + uint8_t aucSessionURL[255]; + /* for Respone */ + u_int8_t fgPendingResponse:1; + u_int8_t fgUnsolicitedReq:1; + u_int8_t fgReserved:6; + uint8_t ucStatusCode; + uint8_t ucTermDelay; + uint8_t aucTargetBssid[MAC_ADDR_LEN]; + uint8_t *pucOurNeighborBss; + uint16_t u2OurNeighborBssLen; +}; + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ +#define BTM_REQ_MODE_CAND_INCLUDED_BIT BIT(0) +#define BTM_REQ_MODE_ABRIDGED BIT(1) +#define BTM_REQ_MODE_DISC_IMM BIT(2) +#define BTM_REQ_MODE_BSS_TERM_INCLUDE BIT(3) +#define BTM_REQ_MODE_ESS_DISC_IMM BIT(4) + +#define BSS_TRANSITION_MGT_STATUS_ACCEPT 0 +#define BSS_TRANSITION_MGT_STATUS_UNSPECIFIED 1 +#define BSS_TRANSITION_MGT_STATUS_NEED_SCAN 2 +#define BSS_TRANSITION_MGT_STATUS_CAND_NO_CAPACITY 3 +#define BSS_TRANSITION_MGT_STATUS_TERM_UNDESIRED 4 +#define BSS_TRANSITION_MGT_STATUS_TERM_DELAY_REQUESTED 5 +#define BSS_TRANSITION_MGT_STATUS_CAND_LIST_PROVIDED 6 +#define BSS_TRANSITION_MGT_STATUS_CAND_NO_CANDIDATES 7 +#define BSS_TRANSITION_MGT_STATUS_LEAVING_ESS 8 + +/* 802.11v: define Transtion and Transition Query reasons */ +#define BSS_TRANSITION_BETTER_AP_FOUND 6 +#define BSS_TRANSITION_LOW_RSSI 16 +#define BSS_TRANSITION_INCLUDE_PREFER_CAND_LIST 19 +#define BSS_TRANSITION_LEAVING_ESS 20 + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +void wnmWNMAction(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb); + +void wnmReportTimingMeas(IN struct ADAPTER *prAdapter, + IN uint8_t ucStaRecIndex, IN uint32_t u4ToD, + IN uint32_t u4ToA); + +#if WNM_UNIT_TEST +void wnmTimingMeasUnitTest1(struct ADAPTER *prAdapter, + uint8_t ucStaRecIndex); +#endif + +void wnmRecvBTMRequest(IN struct ADAPTER *prAdapter, IN struct SW_RFB *prSwRfb); + +void wnmSendBTMQueryFrame(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec); + +void wnmSendBTMResponseFrame(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec); + +uint8_t wnmGetBtmToken(void); + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#endif /* _WNM_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/adapter.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/adapter.h new file mode 100644 index 0000000000000000000000000000000000000000..8a243494c26a9284b6f8e8e6e2317018b15d5ad1 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/adapter.h @@ -0,0 +1,1906 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/*! \file adapter.h + * \brief Definition of internal data structure for driver manipulation. + * + * In this file we define the internal data structure - ADAPTER_T which stands + * for MiniPort ADAPTER(From Windows point of view) or stands for + * Network ADAPTER. + */ + +#ifndef _ADAPTER_H +#define _ADAPTER_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#if CFG_SUPPORT_PASSPOINT +#include "hs20.h" +#endif /* CFG_SUPPORT_PASSPOINT */ +#include "gl_os.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +#define MIN_TX_DURATION_TIME_MS 100 + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +enum { + ENUM_SW_TEST_MODE_NONE = 0, + ENUM_SW_TEST_MODE_SIGMA_AC = 0x1, + ENUM_SW_TEST_MODE_SIGMA_WFD = 0x2, + ENUM_SW_TEST_MODE_CTIA = 0x3, + ENUM_SW_TEST_MODE_SIGMA_TDLS = 0x4, + ENUM_SW_TEST_MODE_SIGMA_P2P = 0x5, + ENUM_SW_TEST_MODE_SIGMA_N = 0x6, + ENUM_SW_TEST_MODE_SIGMA_HS20_R1 = 0x7, + ENUM_SW_TEST_MODE_SIGMA_HS20_R2 = 0x8, + ENUM_SW_TEST_MODE_SIGMA_PMF = 0x9, + ENUM_SW_TEST_MODE_SIGMA_WMMPS = 0xA, + ENUM_SW_TEST_MODE_SIGMA_AC_R2 = 0xB, + ENUM_SW_TEST_MODE_SIGMA_NAN = 0xC, + ENUM_SW_TEST_MODE_SIGMA_AC_AP = 0xD, + ENUM_SW_TEST_MODE_SIGMA_N_AP = 0xE, + ENUM_SW_TEST_MODE_SIGMA_WFDS = 0xF, + ENUM_SW_TEST_MODE_SIGMA_WFD_R2 = 0x10, + ENUM_SW_TEST_MODE_SIGMA_LOCATION = 0x11, + ENUM_SW_TEST_MODE_SIGMA_TIMING_MANAGEMENT = 0x12, + ENUM_SW_TEST_MODE_SIGMA_WMMAC = 0x13, + ENUM_SW_TEST_MODE_SIGMA_VOICE_ENT = 0x14, + ENUM_SW_TEST_MODE_SIGMA_AX = 0x15, + ENUM_SW_TEST_MODE_SIGMA_AX_AP = 0x16, + ENUM_SW_TEST_MODE_NUM +}; + +struct ESS_SCAN_RESULT_T { + uint8_t aucBSSID[MAC_ADDR_LEN]; + uint16_t u2SSIDLen; + uint8_t aucSSID[PARAM_MAX_LEN_SSID]; +}; + +struct WLAN_INFO { + struct PARAM_BSSID_EX rCurrBssId[KAL_AIS_NUM]; + + /* Scan Result */ + struct PARAM_BSSID_EX arScanResult[CFG_MAX_NUM_BSS_LIST]; + uint8_t *apucScanResultIEs[CFG_MAX_NUM_BSS_LIST]; + uint32_t u4ScanResultNum; + + struct ESS_SCAN_RESULT_T arScanResultEss[CFG_MAX_NUM_BSS_LIST]; + uint32_t u4ScanResultEssNum; + uint32_t u4ScanDbgTimes1; + uint32_t u4ScanDbgTimes2; + uint32_t u4ScanDbgTimes3; + uint32_t u4ScanDbgTimes4; + + /* IE pool for Scanning Result */ + uint8_t aucScanIEBuf[CFG_MAX_COMMON_IE_BUF_LEN]; + uint32_t u4ScanIEBufferUsage; + + OS_SYSTIME u4SysTime; + + /* connection parameter (for Ad-Hoc) */ + uint16_t u2BeaconPeriod; + uint16_t u2AtimWindow; + + uint8_t eDesiredRates[PARAM_MAX_LEN_RATES]; + struct CMD_LINK_ATTRIB eLinkAttr; +/* CMD_PS_PROFILE_T ePowerSaveMode; */ + struct CMD_PS_PROFILE arPowerSaveMode[MAX_BSSID_NUM]; + + /* Support power save flag for the caller */ + uint32_t u4PowerSaveFlag[MAX_BSSID_NUM]; + + /* trigger parameter */ + enum ENUM_RSSI_TRIGGER_TYPE eRssiTriggerType; + int32_t rRssiTriggerValue; + + /* Privacy Filter */ + enum ENUM_PARAM_PRIVACY_FILTER ePrivacyFilter; + + /* RTS Threshold */ + uint32_t eRtsThreshold; + + /* Network Type */ + uint8_t ucNetworkType[KAL_AIS_NUM]; + + /* Network Type In Use */ + uint8_t ucNetworkTypeInUse; + + /* Force enable/disable power save mode*/ + u_int8_t fgEnSpecPwrMgt; + +}; + +/* Session for CONNECTION SETTINGS */ +struct CONNECTION_SETTINGS { + + uint8_t aucMacAddress[MAC_ADDR_LEN]; + + uint8_t ucDelayTimeOfDisconnectEvent; + + u_int8_t fgIsConnByBssidIssued; + uint8_t aucBSSID[MAC_ADDR_LEN]; + uint8_t aucBSSIDHint[MAC_ADDR_LEN]; + + uint8_t ucSSIDLen; + uint8_t aucSSID[ELEM_MAX_LEN_SSID]; + + enum ENUM_PARAM_OP_MODE eOPMode; + + enum ENUM_PARAM_CONNECTION_POLICY eConnectionPolicy; + + enum ENUM_PARAM_AD_HOC_MODE eAdHocMode; + + enum ENUM_PARAM_AUTH_MODE eAuthMode; + + enum ENUM_WEP_STATUS eEncStatus; + + u_int8_t fgIsScanReqIssued; + + /* MIB attributes */ + uint16_t u2BeaconPeriod; + + uint16_t u2RTSThreshold; /* User desired setting */ + + uint16_t u2DesiredNonHTRateSet; /* User desired setting */ + + uint8_t ucAdHocChannelNum; /* For AdHoc */ + + enum ENUM_BAND eAdHocBand; /* For AdHoc */ + + uint32_t u4FreqInKHz; /* Center frequency */ + + /* ATIM windows using for IBSS power saving function */ + uint16_t u2AtimWindow; + + /* Features */ + u_int8_t fgIsEnableRoaming; + + u_int8_t fgIsAdHocQoSEnable; + + enum ENUM_PARAM_PHY_CONFIG eDesiredPhyConfig; + +#if CFG_SUPPORT_802_11D + u_int8_t fgMultiDomainCapabilityEnabled; +#endif /* CFG_SUPPORT_802_11D */ + +#if 1 /* CFG_SUPPORT_WAPI */ + u_int8_t fgWapiMode; + uint32_t u4WapiSelectedGroupCipher; + uint32_t u4WapiSelectedPairwiseCipher; + uint32_t u4WapiSelectedAKMSuite; +#endif + + /* for cfg80211 connected indication */ + uint32_t u4RspIeLength; + uint8_t aucRspIe[CFG_CFG80211_IE_BUF_LEN]; + + uint32_t u4ReqIeLength; + uint8_t aucReqIe[CFG_CFG80211_IE_BUF_LEN]; + + u_int8_t fgWpsActive; + uint8_t aucWSCIE[GLUE_INFO_WSCIE_LENGTH]; /*for probe req */ + uint16_t u2WSCIELen; + + /* + * Buffer to hold non-wfa vendor specific IEs set + * from wpa_supplicant. This is used in sending + * Association Request in AIS mode. + */ + uint16_t non_wfa_vendor_ie_len; + uint8_t non_wfa_vendor_ie_buf[NON_WFA_VENDOR_IE_MAX_LEN]; + + /* 11R */ + struct FT_IES rFtIeForTx; + struct cfg80211_ft_event_params rFtEventParam; + + /* CR1486, CR1640 */ + /* for WPS, disable the privacy check for AP selection policy */ + u_int8_t fgPrivacyCheckDisable; + + /* b0~3: trigger-en AC0~3. b4~7: delivery-en AC0~3 */ + uint8_t bmfgApsdEnAc; + + /* for RSN info store, when upper layer set rsn info */ + struct RSN_INFO rRsnInfo; + +#if CFG_SUPPORT_DETECT_SECURITY_MODE_CHANGE + u_int8_t fgSecModeChangeStartTimer; +#endif + + uint8_t *pucAssocIEs; + size_t assocIeLen; +}; + +struct BSS_INFO { + + enum ENUM_NETWORK_TYPE eNetworkType; + + /* Private data parameter for each NETWORK type usage. */ + uint32_t u4PrivateData; + /* P2P network type has 3 network interface to distinguish. */ + + /* Connected Flag used in AIS_NORMAL_TR */ + enum ENUM_PARAM_MEDIA_STATE eConnectionState; + /* The Media State that report to HOST */ + enum ENUM_PARAM_MEDIA_STATE eConnectionStateIndicated; + + /* Current Operation Mode - Infra/IBSS */ + enum ENUM_OP_MODE eCurrentOPMode; +#if CFG_ENABLE_WIFI_DIRECT + enum ENUM_OP_MODE eIntendOPMode; +#endif + +#if (CFG_SUPPORT_DFS_MASTER == 1) + u_int8_t fgIsDfsActive; +#endif + + u_int8_t fgIsInUse; /* For CNM to assign BSS_INFO */ + u_int8_t fgIsNetActive; /* TRUE if this network has been activated */ + + uint8_t ucBssIndex; /* BSS_INFO_T index */ + + uint8_t ucReasonOfDisconnect; /* Used by media state indication */ + + uint8_t ucSSIDLen; /* Length of SSID */ + +#if CFG_ENABLE_WIFI_DIRECT + /* For Hidden SSID usage. */ + enum ENUM_HIDDEN_SSID_TYPE eHiddenSsidType; +#endif + + uint8_t aucSSID[ELEM_MAX_LEN_SSID]; /* SSID used in this BSS */ + + uint8_t aucBSSID[MAC_ADDR_LEN]; /* The BSSID of the associated BSS */ + + /* Owned MAC Address used in this BSS */ + uint8_t aucOwnMacAddr[MAC_ADDR_LEN]; + + uint8_t ucOwnMacIndex; /* Owned MAC index used in this BSS */ + + /* For Infra Mode, and valid only if + * eConnectionState == MEDIA_STATE_CONNECTED + */ + struct STA_RECORD *prStaRecOfAP; + /* For IBSS/AP Mode, all known STAs in current BSS */ + struct LINK rStaRecOfClientList; + + /* For open Mode, BC/MC Tx wlan index, For STA, BC/MC Rx wlan index */ + uint8_t ucBMCWlanIndex; + + /* For AP Mode, BC/MC Tx wlan index, For STA, BC/MC Rx wlan index */ + uint8_t ucBMCWlanIndexS[MAX_KEY_NUM]; + uint8_t ucBMCWlanIndexSUsed[MAX_KEY_NUM]; + + u_int8_t fgBcDefaultKeyExist; /* Bc Transmit key exist or not */ + /* Bc default key idx, for STA, the Rx just set, + * for AP, the tx key id + */ + uint8_t ucBcDefaultKeyIdx; + + uint8_t wepkeyUsed[MAX_KEY_NUM]; + uint8_t wepkeyWlanIdx; /* wlan index of the wep key */ + + uint16_t u2CapInfo; /* Change Detection */ + + uint16_t u2BeaconInterval; /* The Beacon Interval of this BSS */ + + uint16_t u2ATIMWindow; /* For IBSS Mode */ + + /* For Infra Mode, it is the Assoc ID assigned by AP. */ + uint16_t u2AssocId; + + uint8_t ucDTIMPeriod; /* For Infra/AP Mode */ + u_int8_t fgTIMPresent; + + /* For AP Mode, it is the DTIM value we should carried in + * the Beacon of next TBTT. + */ + uint8_t ucDTIMCount; + + /* Available PHY Type Set of this peer + * (This is deduced from received struct BSS_DESC) + */ + uint8_t ucPhyTypeSet; + + /* The Basic PHY Type Index, used to setup Phy Capability */ + uint8_t ucNonHTBasicPhyType; + /* The configuration of AdHoc/AP Mode. e.g. 11g or 11b */ + uint8_t ucConfigAdHocAPMode; + u_int8_t fgIsWepCipherGroup; + + /* For Infra/AP Mode, it is a threshold of Beacon Lost Count to + * confirm connection was lost + */ + uint8_t ucBeaconTimeoutCount; + + /* For IBSS Mode, to keep use same BSSID + * to extend the life cycle of an IBSS + */ + u_int8_t fgHoldSameBssidForIBSS; + /* For AP/IBSS Mode, it is used to indicate that Beacon is sending */ + u_int8_t fgIsBeaconActivated; + + struct MSDU_INFO *prBeacon; /* For AP/IBSS Mode - Beacon Frame */ + + /* For IBSS Mode - To indicate that we can reply ProbeResp Frame. + * In current TBTT interval + */ + u_int8_t fgIsIBSSMaster; + + /* From Capability Info. of AssocResp Frame + * AND of Beacon/ProbeResp Frame + */ + u_int8_t fgIsShortPreambleAllowed; + /* Short Preamble is enabled in current BSS. */ + u_int8_t fgUseShortPreamble; + /* Short Slot Time is enabled in current BSS. */ + u_int8_t fgUseShortSlotTime; + + /* Operational Rate Set of current BSS */ + uint16_t u2OperationalRateSet; + uint16_t u2BSSBasicRateSet; /* Basic Rate Set of current BSS */ + + /* Used for composing Beacon Frame in AdHoc or AP Mode */ + uint8_t ucAllSupportedRatesLen; + uint8_t aucAllSupportedRates[RATE_NUM_SW]; + /* TODO(Kevin): Number of associated clients */ + uint8_t ucAssocClientCnt; + + u_int8_t fgIsProtection; + /* For Infra/AP/IBSS Mode, it is used to indicate if we support WMM in + * current BSS. + */ + u_int8_t fgIsQBSS; + u_int8_t fgIsNetAbsent; /* TRUE: BSS is absent, FALSE: BSS is present */ + + uint32_t u4RsnSelectedGroupCipher; + uint32_t u4RsnSelectedPairwiseCipher; + uint32_t u4RsnSelectedAKMSuite; + uint16_t u2RsnSelectedCapInfo; + + /*-------------------------------------------------------------------*/ + /* Operation mode change notification */ + /*-------------------------------------------------------------------*/ + /*Need to change OpMode channel width*/ + u_int8_t fgIsOpChangeChannelWidth; + /* The OpMode channel width that we want to change to*/ + /* 0:20MHz, 1:40MHz, 2:80MHz, 3:160MHz 4:80+80MHz*/ + uint8_t ucOpChangeChannelWidth; + + /* Need to change OpMode RxNss */ + uint8_t fgIsOpChangeRxNss; + /* The OpMode RxNss that we want to change to */ + uint8_t ucOpChangeRxNss; + + /* Need to change OpMode TxNss */ + uint8_t fgIsOpChangeTxNss; + /* The OpMode TxNss that we want to change to */ + uint8_t ucOpChangeTxNss; + + PFN_OPMODE_NOTIFY_DONE_FUNC pfOpChangeHandler; + + uint8_t aucOpModeChangeState[OP_NOTIFY_TYPE_NUM]; + + uint8_t aucOpModeChangeRetryCnt[OP_NOTIFY_TYPE_NUM]; + + + /*-------------------------------------------------------------------*/ + /* Power Management related information */ + /*-------------------------------------------------------------------*/ + struct PM_PROFILE_SETUP_INFO rPmProfSetupInfo; + + /*-------------------------------------------------------------------*/ + /* WMM/QoS related information */ + /*-------------------------------------------------------------------*/ + /* Used to detect the change of EDCA parameters. For AP mode, + * the value is used in WMM IE + */ + uint8_t ucWmmParamSetCount; + + struct AC_QUE_PARMS arACQueParms[WMM_AC_INDEX_NUM]; + /* For AP mode, broadcast the CWminLog2 */ + uint8_t aucCWminLog2ForBcast[WMM_AC_INDEX_NUM]; + /* For AP mode, broadcast the CWmaxLog2 */ + uint8_t aucCWmaxLog2ForBcast[WMM_AC_INDEX_NUM]; + /* For AP mode, broadcast the value */ + struct AC_QUE_PARMS arACQueParmsForBcast[WMM_AC_INDEX_NUM]; + uint8_t ucWmmQueSet; +#if (CFG_SUPPORT_802_11AX == 1) + uint8_t ucMUEdcaUpdateCnt; + /* + * Store MU EDCA params for each ACs in BSS info + * Use the same format as the update cmd for memory copy + */ + struct _CMD_MU_EDCA_PARAMS_T arMUEdcaParams[WMM_AC_INDEX_NUM]; + + /* Spatial Reuse Parameter Set for the BSS */ + uint8_t ucSRControl; + uint8_t ucNonSRGObssPdMaxOffset; + uint8_t ucSRGObssPdMinOffset; + uint8_t ucSRGObssPdMaxOffset; + uint64_t u8SRGBSSColorBitmap; + uint64_t u8SRGPartialBSSIDBitmap; +#endif + +#if (CFG_HW_WMM_BY_BSS == 1) + u_int8_t fgIsWmmInited; +#endif + + /*-------------------------------------------------------------------*/ + /* 802.11n HT operation IE when (prStaRec->ucPhyTypeSet */ + /* & PHY_TYPE_BIT_HT) is true. They have the same definition with */ + /* fields of information element (CM) */ + /*-------------------------------------------------------------------*/ + enum ENUM_BAND eBand; + uint8_t ucPrimaryChannel; + uint8_t ucHtOpInfo1; + uint16_t u2HtOpInfo2; + uint16_t u2HtOpInfo3; + uint8_t ucOpRxNss; /* Own OP RxNss */ + uint8_t ucOpTxNss; /* Own OP TxNss */ + + /*-------------------------------------------------------------------*/ + /* 802.11ac VHT operation IE when (prStaRec->ucPhyTypeSet */ + /* & PHY_TYPE_BIT_VHT) is true. They have the same definition with */ + /* fields of information element (EASON) */ + /*-------------------------------------------------------------------*/ +#if 1 /* CFG_SUPPORT_802_11AC */ + uint8_t ucVhtChannelWidth; + uint8_t ucVhtChannelFrequencyS1; + uint8_t ucVhtChannelFrequencyS2; + uint16_t u2VhtBasicMcsSet; +#endif +#if (CFG_SUPPORT_802_11AX == 1) + uint8_t ucHeOpParams[HE_OP_BYTE_NUM]; + uint8_t ucBssColorInfo; + uint16_t u2HeBasicMcsSet; +#endif + +#if (CFG_SUPPORT_802_11V_MBSSID == 1) + uint8_t ucMaxBSSIDIndicator; + uint8_t ucMBSSIDIndex; +#endif + + /*-------------------------------------------------------------------*/ + /* Required protection modes (CM) */ + /*-------------------------------------------------------------------*/ + u_int8_t fgErpProtectMode; + enum ENUM_HT_PROTECT_MODE eHtProtectMode; + enum ENUM_GF_MODE eGfOperationMode; + enum ENUM_RIFS_MODE eRifsOperationMode; + + u_int8_t fgObssErpProtectMode; /* GO only */ + enum ENUM_HT_PROTECT_MODE eObssHtProtectMode; /* GO only */ + enum ENUM_GF_MODE eObssGfOperationMode; /* GO only */ + u_int8_t fgObssRifsOperationMode; /* GO only */ + + /*-------------------------------------------------------------------*/ + /* OBSS to decide if 20/40M bandwidth is permitted. */ + /* The first member indicates the following channel list length. */ + /*-------------------------------------------------------------------*/ + u_int8_t fgAssoc40mBwAllowed; + u_int8_t fg40mBwAllowed; + enum ENUM_CHNL_EXT eBssSCO; /* Real setting for HW + * 20/40M AP mode will always set 40M, + * but its OP IE can be changed. + */ + uint8_t auc2G_20mReqChnlList[CHNL_LIST_SZ_2G + 1]; + uint8_t auc2G_NonHtChnlList[CHNL_LIST_SZ_2G + 1]; + uint8_t auc2G_PriChnlList[CHNL_LIST_SZ_2G + 1]; + uint8_t auc2G_SecChnlList[CHNL_LIST_SZ_2G + 1]; + + uint8_t auc5G_20mReqChnlList[CHNL_LIST_SZ_5G + 1]; + uint8_t auc5G_NonHtChnlList[CHNL_LIST_SZ_5G + 1]; + uint8_t auc5G_PriChnlList[CHNL_LIST_SZ_5G + 1]; + uint8_t auc5G_SecChnlList[CHNL_LIST_SZ_5G + 1]; + + /*-------------------------------------------------------------------*/ + /* Scan related information */ + /*-------------------------------------------------------------------*/ + /* Set scanning MAC OUI */ + u_int8_t fgIsScanOuiSet; + uint8_t ucScanOui[MAC_OUI_LEN]; + + struct TIMER rObssScanTimer; + uint16_t u2ObssScanInterval; /* in unit of sec */ + + u_int8_t fgObssActionForcedTo20M; /* GO only */ + u_int8_t fgObssBeaconForcedTo20M; /* GO only */ + + /*--------------------------------------------------------------------*/ + /* HW Related Fields (Kevin) */ + /*--------------------------------------------------------------------*/ + /* The default rate code copied to MAC TX Desc */ + uint16_t u2HwDefaultFixedRateCode; + uint16_t u2HwLPWakeupGuardTimeUsec; + + uint8_t ucBssFreeQuota; /* The value is updated from FW */ + +#if CFG_ENABLE_GTK_FRAME_FILTER + struct IPV4_NETWORK_ADDRESS_LIST *prIpV4NetAddrList; +#endif + uint16_t u2DeauthReason; + +#if CFG_SUPPORT_TDLS + u_int8_t fgTdlsIsProhibited; + u_int8_t fgTdlsIsChSwProhibited; +#endif + + /*link layer statistics */ + struct WIFI_WMM_AC_STAT arLinkStatistics[WMM_AC_INDEX_NUM]; + + uint32_t u4CoexPhyRateLimit; + + u_int8_t fgIsGranted; + enum ENUM_BAND eBandGranted; + uint8_t ucPrimaryChannelGranted; + struct PARAM_CUSTOM_ACL rACL; + +#if CFG_SUPPORT_802_11W + /* AP PMF */ + struct AP_PMF_CFG rApPmfCfg; + /* STA PMF: for encrypted deauth frame */ + struct completion rDeauthComp; + u_int8_t encryptedDeauthIsInProcess; +#endif + +#if (CFG_SUPPORT_HE_ER == 1) + uint8_t ucErMode; +#endif + + uint8_t ucCountryIELen; + uint8_t aucCountryStr[3]; + uint8_t aucSubbandTriplet[253]; + enum ENUM_IFTYPE eIftype; +}; + +/* Support AP Selection */ +struct ESS_CHNL_INFO { + uint8_t ucChannel; + uint8_t ucUtilization; + uint8_t ucApNum; +}; +/* end Support AP Selection */ + +struct NEIGHBOR_AP_T { + struct LINK_ENTRY rLinkEntry; + uint8_t aucBssid[MAC_ADDR_LEN]; + u_int8_t fgHT:1; + u_int8_t fgSameMD:1; + u_int8_t fgRmEnabled:1; + u_int8_t fgFromBtm:1; + u_int8_t fgQoS:1; + uint8_t ucReserved:3; + u_int8_t fgPrefPresence; + uint8_t ucPreference; + uint8_t ucChannel; + uint64_t u8TermTsf; +}; + +struct AIS_SPECIFIC_BSS_INFO { + /* This value indicate the roaming type used in AIS_JOIN */ + uint8_t ucRoamingAuthTypes; + + u_int8_t fgIsIBSSActive; + + /*! \brief Global flag to let arbiter stay at standby + * and not connect to any network + */ + u_int8_t fgCounterMeasure; + +#if 0 + u_int8_t fgWepWapiBcKeyExist; /* WEP WAPI BC key exist flag */ + uint8_t ucWepWapiBcWlanIndex; /* WEP WAPI BC wlan index */ + + /* RSN BC key exist flag, map to key id 0, 1, 2, 3 */ + u_int8_t fgRsnBcKeyExist[4]; + /* RSN BC wlan index, map to key id 0, 1, 2, 3 */ + uint8_t ucRsnBcWlanIndex[4]; +#endif + + /* While Do CounterMeasure procedure, + * check the EAPoL Error report have send out + */ + u_int8_t fgCheckEAPoLTxDone; + + uint32_t u4RsnaLastMICFailTime; + + /* By the flow chart of 802.11i, + * wait 60 sec before associating to same AP + * or roaming to a new AP + * or sending data in IBSS, + * keep a timer for handle the 60 sec counterMeasure + */ + struct TIMER rRsnaBlockTrafficTimer; + struct TIMER rRsnaEAPoLReportTimeoutTimer; + + /* For Keep the Tx/Rx Mic key for TKIP SW Calculate Mic */ + /* This is only one for AIS/AP */ + uint8_t aucTxMicKey[8]; + uint8_t aucRxMicKey[8]; + + /* Buffer for WPA2 PMKID */ + /* The PMKID cache lifetime is expire by media_disconnect_indication */ + struct LINK rPmkidCache; +#if CFG_SUPPORT_802_11W + u_int8_t fgMgmtProtection; + uint32_t u4SaQueryStart; + uint32_t u4SaQueryCount; + uint8_t ucSaQueryTimedOut; + uint8_t *pucSaQueryTransId; + struct TIMER rSaQueryTimer; + u_int8_t fgBipKeyInstalled; +#endif + uint8_t ucKeyAlgorithmId; + + /* Support AP Selection */ +#if CFG_SUPPORT_ROAMING_SKIP_ONE_AP + uint8_t ucRoamSkipTimes; + u_int8_t fgGoodRcpiArea; + u_int8_t fgPoorRcpiArea; +#endif + struct ESS_CHNL_INFO arCurEssChnlInfo[CFG_MAX_NUM_OF_CHNL_INFO]; + uint8_t ucCurEssChnlInfoNum; + struct LINK rCurEssLink; + /* end Support AP Selection */ + + struct BSS_TRANSITION_MGT_PARAM_T rBTMParam; + struct LINK_MGMT rNeighborApList; + OS_SYSTIME rNeiApRcvTime; + uint32_t u4NeiApValidInterval; +}; + +struct BOW_SPECIFIC_BSS_INFO { + uint16_t u2Reserved; /* Reserved for Data Type Check */ +}; + +#if CFG_SLT_SUPPORT +struct SLT_INFO { + + struct BSS_DESC *prPseudoBssDesc; + uint16_t u2SiteID; + uint8_t ucChannel2G4; + uint8_t ucChannel5G; + u_int8_t fgIsDUT; + uint32_t u4BeaconReceiveCnt; + /* ///////Deprecated///////// */ + struct STA_RECORD *prPseudoStaRec; +}; +#endif + +struct WLAN_TABLE { + uint8_t ucUsed; + uint8_t ucBssIndex; + uint8_t ucKeyId; + uint8_t ucPairwise; + uint8_t aucMacAddr[MAC_ADDR_LEN]; + uint8_t ucStaIndex; +}; + +/* Major member variables for WiFi FW operation. + * Variables within this region will be ready for + * access after WIFI function is enabled. + */ +struct WIFI_VAR { + u_int8_t fgIsRadioOff; + + u_int8_t fgIsEnterD3ReqIssued; + + u_int8_t fgDebugCmdResp; + + /* Common connection settings start */ + /* Used for AP mode for desired channel and bandwidth */ + uint16_t u2CountryCode; + uint8_t uc2G4BandwidthMode; /* 20/40M or 20M only *//* Not used */ + uint8_t uc5GBandwidthMode; /* 20/40M or 20M only *//* Not used */ + /* Support AP Selection */ + struct LINK_MGMT rBlackList; +#if CFG_SUPPORT_MBO + struct PARAM_BSS_DISALLOWED_LIST rBssDisallowedList; +#endif + enum ENUM_PARAM_PHY_CONFIG eDesiredPhyConfig; + /* Common connection settings end */ + + struct CONNECTION_SETTINGS rConnSettings[KAL_AIS_NUM]; + + struct SCAN_INFO rScanInfo; + +#if CFG_SUPPORT_ROAMING + struct ROAMING_INFO rRoamingInfo[KAL_AIS_NUM]; +#endif /* CFG_SUPPORT_ROAMING */ + + struct AIS_FSM_INFO rAisFsmInfo[KAL_AIS_NUM]; + + enum ENUM_PWR_STATE aePwrState[MAX_BSSID_NUM + 1]; + + struct BSS_INFO arBssInfoPool[MAX_BSSID_NUM]; + + struct BSS_INFO rP2pDevInfo; + + struct AIS_SPECIFIC_BSS_INFO rAisSpecificBssInfo[KAL_AIS_NUM]; + +#if CFG_ENABLE_WIFI_DIRECT + struct P2P_CONNECTION_SETTINGS *prP2PConnSettings[BSS_P2P_NUM]; + + struct P2P_SPECIFIC_BSS_INFO *prP2pSpecificBssInfo[BSS_P2P_NUM]; + +/* P_P2P_FSM_INFO_T prP2pFsmInfo; */ + + struct P2P_DEV_FSM_INFO *prP2pDevFsmInfo; + + /* Currently we only support 2 p2p interface. */ + struct P2P_ROLE_FSM_INFO *aprP2pRoleFsmInfo[BSS_P2P_NUM]; + +#if CFG_ENABLE_PER_STA_STATISTICS_LOG + struct PARAM_GET_STA_STATISTICS *prP2pQueryStaStatistics[BSS_P2P_NUM]; +#endif + +#endif /* CFG_ENABLE_WIFI_DIRECT */ + +#if CFG_ENABLE_BT_OVER_WIFI + struct BOW_SPECIFIC_BSS_INFO rBowSpecificBssInfo; + struct BOW_FSM_INFO rBowFsmInfo; +#endif /* CFG_ENABLE_BT_OVER_WIFI */ + + struct WLAN_TABLE arWtbl[WTBL_SIZE]; + + struct DEAUTH_INFO arDeauthInfo[MAX_DEAUTH_INFO_COUNT]; + + /* Current Wi-Fi Settings and Flags */ + uint8_t aucPermanentAddress[MAC_ADDR_LEN]; + uint8_t aucMacAddress[MAC_ADDR_LEN]; + uint8_t aucMacAddress1[MAC_ADDR_LEN]; + uint8_t aucDeviceAddress[MAC_ADDR_LEN]; + uint8_t aucInterfaceAddress[KAL_P2P_NUM][MAC_ADDR_LEN]; + + uint8_t ucAvailablePhyTypeSet; + + /* Basic Phy Type used by SCN according + * to the set of Available PHY Types + */ + enum ENUM_PHY_TYPE_INDEX eNonHTBasicPhyType2G4; + + enum ENUM_PARAM_PREAMBLE_TYPE ePreambleType; + enum ENUM_REGISTRY_FIXED_RATE eRateSetting; + + u_int8_t fgIsShortSlotTimeOptionEnable; + /* User desired setting, but will honor the capability of AP */ + + u_int8_t fgEnableJoinToHiddenSSID; + u_int8_t fgSupportWZCDisassociation; + +#if CFG_SUPPORT_WFD + struct WFD_CFG_SETTINGS rWfdConfigureSettings; +#endif + +#if CFG_SLT_SUPPORT + struct SLT_INFO rSltInfo; +#endif + +#if CFG_SUPPORT_PASSPOINT + struct HS20_INFO rHS20Info[KAL_AIS_NUM]; +#endif /* CFG_SUPPORT_PASSPOINT */ + uint8_t aucMediatekOuiIE[64]; + uint16_t u2MediatekOuiIELen; + + /* Feature Options */ + uint8_t ucQoS; + + uint8_t ucStaHt; + uint8_t ucStaVht; +#if (CFG_SUPPORT_802_11AX == 1) + uint8_t ucStaHe; + uint8_t ucApHe; + uint8_t ucP2pGoHe; + uint8_t ucP2pGcHe; + uint8_t ucApSelAxWeight; + uint8_t ucApSelAxScoreDiv; +#endif + uint8_t ucApHt; + uint8_t ucApVht; + uint8_t ucP2pGoHt; + uint8_t ucP2pGoVht; + uint8_t ucP2pGcHt; + uint8_t ucP2pGcVht; + + /* NIC capability from FW event*/ + uint8_t ucHwNotSupportAC; + + uint8_t ucAmpduTx; + uint8_t ucAmpduRx; + uint8_t ucAmsduInAmpduTx; + uint8_t ucAmsduInAmpduRx; + uint8_t ucHtAmsduInAmpduTx; + uint8_t ucHtAmsduInAmpduRx; + uint8_t ucVhtAmsduInAmpduTx; + uint8_t ucVhtAmsduInAmpduRx; +#if (CFG_SUPPORT_802_11AX == 1) + uint8_t ucHeAmsduInAmpduTx; + uint8_t ucHeAmsduInAmpduRx; + uint8_t ucHeCertForceAmsdu; + uint8_t ucTrigMacPadDur; + uint8_t ucStaHeBfee; +#endif +#if (CFG_SUPPORT_TWT == 1) + uint8_t ucTWTRequester; + uint8_t ucTWTResponder; + uint8_t ucTWTStaBandBitmap; +#endif +#if (CFG_TWT_SMART_STA == 1) + uint8_t ucTWTSmartSta; +#endif + uint8_t ucTspec; + uint8_t ucUapsd; + uint8_t ucStaUapsd; + uint8_t ucApUapsd; + uint8_t ucP2pUapsd; + + uint8_t ucTxShortGI; + uint8_t ucRxShortGI; + uint8_t ucTxLdpc; + uint8_t ucRxLdpc; + uint8_t ucTxStbc; + uint8_t ucRxStbc; + uint8_t ucRxStbcNss; + uint8_t ucTxGf; + uint8_t ucRxGf; + + uint8_t ucMCS32; + + uint8_t ucTxopPsTx; + uint8_t ucSigTaRts; + uint8_t ucDynBwRts; + + uint8_t ucStaHtBfee; + uint8_t ucStaVhtBfee; + uint8_t ucStaHtBfer; + uint8_t ucStaVhtBfer; + uint8_t ucStaVhtMuBfee; + uint8_t fgForceSTSNum; + + uint8_t ucDataTxDone; + uint8_t ucDataTxRateMode; + uint32_t u4DataTxRateCode; + + uint8_t ucApWpsMode; + uint8_t ucApChannel; + + uint8_t ucApSco; + uint8_t ucP2pGoSco; + + uint8_t ucStaBandwidth; + uint8_t ucSta5gBandwidth; + uint8_t ucSta2gBandwidth; + uint8_t ucApBandwidth; + uint8_t ucAp2gBandwidth; + uint8_t ucAp5gBandwidth; + uint8_t ucP2p5gBandwidth; + uint8_t ucP2p2gBandwidth; + + /* If enable, AP channel bandwidth Channel + * Center Frequency Segment 0/1 + */ + /* and secondary channel offset will align wifi.cfg */ + /* Otherwise align cfg80211 */ + uint8_t ucApChnlDefFromCfg; + + /* + * According TGn/TGac 4.2.44, AP should not connect + * with TKIP client with HT/VHT capabilities. We leave + * a wifi.cfg item for user to decide whether to + * enable HT/VHT capabilities in that case + */ + uint8_t ucApAllowHtVhtTkip; + + uint8_t ucNSS; + uint8_t fgSta1NSS; /* Less or euqal than ucNss */ + uint8_t ucAp5gNSS; /* Less or euqal than ucNss */ + uint8_t ucAp2gNSS; /* Less or euqal than ucNss */ + uint8_t ucGo5gNSS; /* Less or euqal than ucNss */ + uint8_t ucGo2gNSS; /* Less or euqal than ucNss */ + + uint8_t ucRxMaxMpduLen; + uint32_t u4TxMaxAmsduInAmpduLen; + + uint8_t ucTxBaSize; + uint8_t ucRxHtBaSize; + uint8_t ucRxVhtBaSize; +#if (CFG_SUPPORT_802_11AX == 1) + uint16_t u2RxHeBaSize; + uint16_t u2TxHeBaSize; +#endif + + uint8_t ucThreadScheduling; + uint8_t ucThreadPriority; + int8_t cThreadNice; + + uint8_t ucTcRestrict; + uint32_t u4MaxTxDeQLimit; + uint8_t ucAlwaysResetUsedRes; + + uint32_t u4NetifStopTh; + uint32_t u4NetifStartTh; + struct PARAM_GET_CHN_INFO rChnLoadInfo; + +#if CFG_SUPPORT_MTK_SYNERGY + uint8_t ucMtkOui; + uint32_t u4MtkOuiCap; + uint8_t aucMtkFeature[4]; + u_int8_t ucGbandProbe256QAM; +#endif +#if CFG_SUPPORT_VHT_IE_IN_2G + uint8_t ucVhtIeIn2g; +#endif + u_int8_t fgCsaInProgress; + uint8_t ucChannelSwitchMode; + uint8_t ucNewChannelNumber; + uint8_t ucChannelSwitchCount; + + uint32_t u4HifIstLoopCount; + uint32_t u4Rx2OsLoopCount; + uint32_t u4HifTxloopCount; + uint32_t u4TxRxLoopCount; + uint32_t u4TxFromOsLoopCount; + uint32_t u4TxIntThCount; + + uint32_t au4TcPageCount[TC_NUM]; + uint32_t au4TcPageCountPle[TC_NUM]; + uint8_t ucExtraTxDone; + uint8_t ucTxDbg; + + uint8_t ucCmdRsvResource; + uint32_t u4MgmtQueueDelayTimeout; + + uint32_t u4StatsLogTimeout; + uint32_t u4StatsLogDuration; + uint8_t ucDhcpTxDone; + uint8_t ucArpTxDone; + + uint8_t ucMacAddrOverride; + uint8_t aucMacAddrStr[WLAN_CFG_VALUE_LEN_MAX]; + + uint8_t ucCtiaMode; + uint8_t ucTpTestMode; + uint8_t ucSigmaTestMode; +#if CFG_SUPPORT_DBDC + enum ENUM_CNM_DBDC_MODE eDbdcMode; + u_int8_t fgDbDcModeEn; +#endif + uint8_t u4ScanCtrl; + uint8_t ucScanChannelListenTime; + +#if (CFG_EFUSE_BUFFER_MODE_DELAY_CAL == 1) + uint8_t ucEfuseBufferModeCal; +#endif + uint8_t ucCalTimingCtrl; + uint8_t ucWow; + uint8_t ucOffload; + uint8_t ucAdvPws; /* enable LP multiple DTIM function, default enable */ + uint8_t ucWowOnMdtim; /* multiple DTIM if WOW enable, default 1 */ + uint8_t ucWowOffMdtim; /* multiple DTIM if WOW disable, default 3 */ + + uint8_t u4SwTestMode; + uint8_t ucCtrlFlagAssertPath; + uint8_t ucCtrlFlagDebugLevel; + uint32_t u4WakeLockRxTimeout; + uint32_t u4WakeLockThreadWakeup; + uint32_t u4RegP2pIfAtProbe; /* register p2p interface during probe */ + /* p2p group interface use the same mac addr as p2p device interface */ + uint8_t ucP2pShareMacAddr; + uint8_t ucSmartRTS; + + uint32_t u4UapsdAcBmp; + uint32_t u4MaxSpLen; + /* 0: enable online scan, non-zero: disable online scan */ + uint32_t fgDisOnlineScan; + uint32_t fgDisBcnLostDetection; + uint32_t fgDisRoaming; /* 0:enable roaming 1:disable */ + uint32_t u4AisRoamingNumber; + uint32_t fgEnArpFilter; + + uint8_t uDeQuePercentEnable; + uint32_t u4DeQuePercentVHT80Nss1; + uint32_t u4DeQuePercentVHT40Nss1; + uint32_t u4DeQuePercentVHT20Nss1; + uint32_t u4DeQuePercentHT40Nss1; + uint32_t u4DeQuePercentHT20Nss1; + + uint32_t u4PerfMonUpdatePeriod; + uint32_t u4PerfMonTpTh[PERF_MON_TP_MAX_THRESHOLD]; + uint32_t u4BoostCpuTh; + + uint32_t u4PerfMonPendingTh; + uint32_t u4PerfMonUsedTh; + + u_int8_t fgTdlsBufferSTASleep; /* Support TDLS 5.5.4.2 optional case */ + u_int8_t fgChipResetRecover; + enum PARAM_POWER_MODE ePowerMode; + + u_int8_t fgNvramCheckEn; /* nvram checking in scan result*/ + + uint8_t fgEnableSer; + uint8_t fgRstRecover; + +#if CFG_SUPPORT_SPE_IDX_CONTROL + u_int8_t ucSpeIdxCtrl; /* 0: WF0, 1: WF1, 2: duplicate */ +#endif + +#if CFG_SUPPORT_LOWLATENCY_MODE + uint8_t ucLowLatencyModeScan; + uint8_t ucLowLatencyModeReOrder; + uint8_t ucLowLatencyModePower; + uint8_t ucLowLatencyPacketPriority; + uint8_t ucLowLatencyCmdData; + uint8_t ucLowLatencyCmdDataAllPacket; +#endif /* CFG_SUPPORT_LOWLATENCY_MODE */ +#if CFG_SUPPORT_IDC_CH_SWITCH + uint8_t ucChannelSwtichColdownTime; + uint8_t fgCrossBandSwitchEn; +#endif +#if CFG_SUPPORT_PERF_IND + u_int8_t fgPerfIndicatorEn; +#endif + + /* 11K */ + struct RADIO_MEASUREMENT_REQ_PARAMS rRmReqParams[KAL_AIS_NUM]; + struct RADIO_MEASUREMENT_REPORT_PARAMS rRmRepParams[KAL_AIS_NUM]; + + /* WMMAC */ + struct WMM_INFO rWmmInfo[KAL_AIS_NUM]; + + /* Tx Msdu Queue method */ + uint8_t ucTxMsduQueue; + uint8_t ucTxMsduQueueInit; + uint32_t u4TxHifRes; + + uint32_t u4MTU; /* net device maximum transmission unit */ +#if CFG_SUPPORT_RX_GRO + uint32_t ucGROFlushTimeout; /* Flush packet timeout (ms) */ + uint32_t ucGROEnableTput; /* Threshold of enable GRO Tput */ +#endif + +#if CFG_SUPPORT_IOT_AP_BLACKLIST + uint8_t fgEnDefaultIotApRule; +#endif + uint8_t ucMsduReportTimeout; + +#if CFG_SUPPORT_DATA_STALL + uint32_t u4PerHighThreshole; + uint32_t u4TxLowRateThreshole; + uint32_t u4RxLowRateThreshole; + uint32_t u4ReportEventInterval; + uint32_t u4TrafficThreshold; +#endif + +#if CFG_SUPPORT_HE_ER + uint8_t u4ExtendedRange; +#endif +#if CFG_SUPPORT_SMART_GEAR + uint8_t ucSGCfg; + uint8_t ucSG24GFavorANT; + uint8_t ucSG5GFavorANT; +#endif +#if (CFG_SUPPORT_P2PGO_ACS == 1) + uint8_t ucP2pGoACS; +#endif + uint8_t fgReuseRSNIE; + + uint32_t u4DiscoverTimeout; + uint32_t u4InactiveTimeout; +#if ARP_MONITER_ENABLE + uint32_t uArpMonitorNumber; + uint32_t uArpMonitorRxPktNum; +#endif /* ARP_MONITER_ENABLE */ +}; + +/* cnm_timer module */ +struct ROOT_TIMER { + struct LINK rLinkHead; + OS_SYSTIME rNextExpiredSysTime; + KAL_WAKE_LOCK_T *rWakeLock; + u_int8_t fgWakeLocked; +}; + +/* FW/DRV/NVRAM version information */ +struct WIFI_VER_INFO { + + /* NVRAM or Registry */ + uint16_t u2Part1CfgOwnVersion; + uint16_t u2Part1CfgPeerVersion; + uint16_t u2Part2CfgOwnVersion; + uint16_t u2Part2CfgPeerVersion; + + /* Firmware */ + uint8_t aucReleaseManifest[256]; + + /* N9 SW */ + uint16_t u2FwProductID; + uint16_t u2FwOwnVersion; + uint16_t u2FwPeerVersion; + uint8_t ucFwBuildNumber; + uint8_t aucFwBranchInfo[4]; + uint8_t aucFwDateCode[16]; + + struct TAILER_COMMON_FORMAT_T rCommonTailer; + struct TAILER_REGION_FORMAT_T rRegionTailers[MAX_FWDL_SECTION_NUM]; + + /* N9 tailer */ + struct TAILER_FORMAT_T rN9tailer[N9_FWDL_SECTION_NUM]; + + /* CR4 tailer */ + struct TAILER_FORMAT_T rCR4tailer[CR4_FWDL_SECTION_NUM]; +#if CFG_SUPPORT_COMPRESSION_FW_OPTION + /* N9 Compressed tailer */ + struct TAILER_FORMAT_T_2 rN9Compressedtailer; + /* CR4 tailer */ + struct TAILER_FORMAT_T_2 rCR4Compressedtailer; + u_int8_t fgIsN9CompressedFW; + u_int8_t fgIsCR4CompressedFW; +#endif + /* Patch header */ + struct PATCH_FORMAT_T rPatchHeader; + u_int8_t fgPatchIsDlByDrv; +}; + +#if CFG_ENABLE_WIFI_DIRECT +/* + * p2p function pointer structure + */ + +struct P2P_FUNCTION_LINKER { + P2P_REMOVE prP2pRemove; + + P2P_GENERATE_P2P_IE prP2pGenerateWSC_IEForBeacon; + + P2P_NET_REGISTER prP2pNetRegister; + P2P_NET_UNREGISTER prP2pNetUnregister; + /* All IEs generated from supplicant. */ + P2P_CALCULATE_P2P_IE_LEN prP2pCalculateP2p_IELenForAssocReq; + /* All IEs generated from supplicant. */ + P2P_GENERATE_P2P_IE prP2pGenerateP2p_IEForAssocReq; +}; + +#endif + +struct CFG_SCAN_CHNL { + uint8_t ucChannelListNum; + struct RF_CHANNEL_INFO arChnlInfoList[MAXIMUM_OPERATION_CHANNEL_LIST]; +}; + +#if CFG_SUPPORT_NCHO +enum ENUM_NCHO_ITEM_SET_TYPE { + ITEM_SET_TYPE_NUM, + ITEM_SET_TYPE_STR +}; + +enum ENUM_NCHO_BAND { + NCHO_BAND_AUTO = 0, + NCHO_BAND_5G, + NCHO_BAND_2G4, + NCHO_BAND_NUM +}; + +enum ENUM_NCHO_DFS_SCN_MODE { + NCHO_DFS_SCN_DISABLE = 0, + NCHO_DFS_SCN_ENABLE1, + NCHO_DFS_SCN_ENABLE2, + NCHO_DFS_SCN_NUM +}; + +struct CFG_NCHO_RE_ASSOC { + /*!< SSID length in bytes. Zero length is broadcast(any) SSID */ + uint32_t u4SsidLen; + uint8_t aucSsid[ELEM_MAX_LEN_SSID]; + uint8_t aucBssid[MAC_ADDR_LEN]; + uint32_t u4CenterFreq; +}; + +#define CFG_NCHO_SCAN_CHNL CFG_SCAN_CHNL + +struct NCHO_ACTION_FRAME_PARAMS { + uint8_t aucBssid[MAC_ADDR_LEN]; + int32_t i4channel; + int32_t i4DwellTime; + int32_t i4len; + uint8_t aucData[520]; +}; + +struct NCHO_AF_INFO { + uint8_t *aucBssid; + int32_t i4channel; + int32_t i4DwellTime; + int32_t i4len; + uint8_t *pucData; +}; + +struct NCHO_INFO { + u_int8_t fgNCHOEnabled; + u_int8_t fgChGranted; + u_int8_t fgIsSendingAF; + int32_t i4RoamTrigger; /* db */ + int32_t i4RoamDelta; /* db */ + uint32_t u4RoamScanPeriod; /* ms */ + uint32_t u4ScanChannelTime; /* ms */ + uint32_t u4ScanHomeTime; /* ms */ + uint32_t u4ScanHomeawayTime; /* ms */ + uint32_t u4ScanNProbes; + uint32_t u4WesMode; + enum ENUM_NCHO_BAND eBand; + enum ENUM_NCHO_DFS_SCN_MODE eDFSScnMode; + uint32_t u4RoamScanControl; + struct CFG_NCHO_SCAN_CHNL rRoamScnChnl; + struct CFG_NCHO_SCAN_CHNL rAddRoamScnChnl; + struct NCHO_ACTION_FRAME_PARAMS rParamActionFrame; +}; +#endif + +struct WIFI_FEM_CFG { + /* WiFi FEM path */ + uint16_t u2WifiPath; + uint16_t u2Reserved; + /* Reserved */ + uint32_t au4Reserved[4]; +}; +/* + * State Machine: + * -->STOP: No Tx/Rx traffic + * -->DISABLE: Screen is off + * -->RUNNING: Screen is on && Tx/Rx traffic is active + */ +struct PERF_MONITOR { + struct TIMER rPerfMonTimer; + OS_SYSTIME rLastUpdateTime; + unsigned long ulPerfMonFlag; + unsigned long ulLastTxBytes[BSS_DEFAULT_NUM]; + unsigned long ulLastRxBytes[BSS_DEFAULT_NUM]; + unsigned long ulLastTxPackets[BSS_DEFAULT_NUM]; + unsigned long ulLastRxPackets[BSS_DEFAULT_NUM]; + uint64_t ulThroughput; /* in bps */ + unsigned long ulTxTp[BSS_DEFAULT_NUM]; /* in Bps */ + unsigned long ulRxTp[BSS_DEFAULT_NUM]; /* in Bps */ + uint32_t u4UpdatePeriod; /* in ms */ + uint32_t u4TarPerfLevel; + uint32_t u4CurrPerfLevel; + uint32_t u4UsedCnt; + unsigned long ulTotalTxSuccessCount; + unsigned long ulTotalTxFailCount; +}; + +struct HIF_STATS { + unsigned long ulUpdatePeriod; /* in ms */ + uint32_t u4HwIsrCount; + uint32_t u4SwIsrCount; + uint32_t u4CmdInCount; /* cmd from main_thread to hif_thread */ + uint32_t u4CmdTxCount; /* cmd from hif_thread to DMA */ + uint32_t u4CmdTxdoneCount; /* cmd from DMA to consys */ + uint32_t u4DataInCount; /* data from main_thread to hif_thread */ + uint32_t u4DataTxCount; /* data from hif_thread to DMA */ + uint32_t u4DataTxdoneCount; /* data from DMA to consys */ + uint32_t u4DataMsduRptCount; /* data from consys to air */ + uint32_t u4EventRxCount; /* event from DMA to hif_thread */ + uint32_t u4DataRxCount; /* data from DMA to hif_thread */ +}; + +/* + * Major ADAPTER structure + * Major data structure for driver operation + */ +struct ADAPTER { + struct mt66xx_chip_info *chip_info; + uint8_t ucRevID; + u_int8_t fgIsReadRevID; + + uint16_t u2NicOpChnlNum; + + u_int8_t fgIsEnableWMM; + /* This flag is used to indicate that WMM is enable in current BSS */ + u_int8_t fgIsWmmAssoc; + + uint32_t u4OsPacketFilter; /* packet filter used by OS */ + u_int8_t fgAllMulicastFilter; /* mDNS filter used by OS */ + + struct BSS_INFO *aprBssInfo[MAX_BSSID_NUM + 1]; + struct BSS_INFO *prAisBssInfo[KAL_AIS_NUM]; + uint8_t ucHwBssIdNum; + uint8_t ucWmmSetNum; + uint8_t ucWtblEntryNum; + uint8_t ucTxDefaultWlanIndex; + uint8_t ucP2PDevBssIdx; + +#if CFG_TCP_IP_CHKSUM_OFFLOAD + /* Does FW support Checksum Offload feature */ + u_int8_t fgIsSupportCsumOffload; + uint32_t u4CSUMFlags; +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ + + enum ENUM_BAND aePreferBand[NETWORK_TYPE_NUM]; + + /* ADAPTER flags */ + uint32_t u4Flags; + uint32_t u4HwFlags; + + u_int8_t fgIsRadioOff; + + u_int8_t fgIsEnterD3ReqIssued; + + uint8_t aucMacAddress[MAC_ADDR_LEN]; + + /* Current selection basing on the set of Available PHY Types */ + enum ENUM_PHY_TYPE_INDEX eCurrentPhyType; + + uint32_t u4CoalescingBufCachedSize; + uint8_t *pucCoalescingBufCached; + + /* Buffer for CMD_INFO_T, Mgt packet and mailbox message */ + struct BUF_INFO rMgtBufInfo; + struct BUF_INFO rMsgBufInfo; + uint8_t *pucMgtBufCached; + uint32_t u4MgtBufCachedSize; + uint8_t aucMsgBuf[MSG_BUFFER_SIZE]; +#if CFG_DBG_MGT_BUF + uint32_t u4MemAllocDynamicCount; /* Debug only */ + uint32_t u4MemFreeDynamicCount; /* Debug only */ +#endif + + struct STA_RECORD arStaRec[CFG_STA_REC_NUM]; + + /* Element for TX PATH */ + struct TX_CTRL rTxCtrl; + struct QUE rFreeCmdList; + struct CMD_INFO arHifCmdDesc[CFG_TX_MAX_CMD_PKT_NUM]; + + /* Element for RX PATH */ + struct RX_CTRL rRxCtrl; + + /* Timer for restarting RFB setup procedure */ + struct TIMER rPacketDelaySetupTimer; + + uint32_t u4IntStatus; + + enum ENUM_ACPI_STATE rAcpiState; + + u_int8_t fgIsIntEnable; + u_int8_t fgIsIntEnableWithLPOwnSet; + + u_int8_t fgIsFwOwn; + u_int8_t fgWiFiInSleepyState; + + /* Set by callback to make sure WOW done before system suspend */ + u_int8_t fgSetPfCapabilityDone; + u_int8_t fgSetWowDone; + + OS_SYSTIME rLastOwnFailedLogTime; + uint32_t u4OwnFailedCount; + uint32_t u4OwnFailedLogCount; + + uint32_t u4PwrCtrlBlockCnt; + + /* TX Direct related : BEGIN */ + u_int8_t fgTxDirectInited; + + #define TX_DIRECT_CHECK_INTERVAL (1000 * HZ / USEC_PER_SEC) + /* check if an empty MsduInfo is available */ + struct timer_list rTxDirectSkbTimer; + /* check if HIF port is ready to accept a new Msdu */ + struct timer_list rTxDirectHifTimer; + + struct sk_buff_head rTxDirectSkbQueue; + struct QUE rTxDirectHifQueue[TX_PORT_NUM]; + + struct QUE rStaPsQueue[CFG_STA_REC_NUM]; + uint32_t u4StaPsBitmap; + struct QUE rBssAbsentQueue[MAX_BSSID_NUM + 1]; + uint32_t u4BssAbsentBitmap; + /* TX Direct related : END */ + + struct QUE rPendingCmdQueue; + +#if CFG_SUPPORT_MULTITHREAD + struct QUE rTxCmdQueue; + struct QUE rTxCmdDoneQueue; +#if CFG_FIX_2_TX_PORT + struct QUE rTxP0Queue; + struct QUE rTxP1Queue; +#else + struct QUE rTxPQueue[TX_PORT_NUM]; +#endif + struct QUE rRxQueue; + struct QUE rTxDataDoneQueue; +#endif + + struct GLUE_INFO *prGlueInfo; + + uint8_t ucCmdSeqNum; + uint8_t ucTxSeqNum; + uint8_t aucPidPool[WTBL_SIZE]; + +#if 1 /* CFG_SUPPORT_WAPI */ + u_int8_t fgUseWapi; +#endif + + /* RF Test flags */ + u_int8_t fgTestMode; + u_int8_t fgIcapMode; + + /* WLAN Info for DRIVER_CORE OID query */ + struct WLAN_INFO rWlanInfo; + +#if CFG_ENABLE_WIFI_DIRECT + uint8_t u4P2pMode; + u_int8_t fgIsP2PRegistered; + /* flag to report all networks in p2p scan */ + u_int8_t p2p_scan_report_all_bss; + enum ENUM_NET_REG_STATE rP2PNetRegState; + /* BOOLEAN fgIsWlanLaunched; */ + struct P2P_INFO *prP2pInfo; +#if CFG_SUPPORT_P2P_RSSI_QUERY + OS_SYSTIME rP2pLinkQualityUpdateTime; + u_int8_t fgIsP2pLinkQualityValid; + struct LINK_QUALITY rP2pLinkQuality; +#endif +#endif + + /* Online Scan Option */ + u_int8_t fgEnOnlineScan; + + /* Online Scan Option */ + u_int8_t fgDisBcnLostDetection; + + /* MAC address */ + uint8_t rMyMacAddr[PARAM_MAC_ADDR_LEN]; + + /* Wake-up Event for WOL */ + uint32_t u4WakeupEventEnable; + + /* Event Buffering */ + struct EVENT_STATISTICS rStatStruct; + OS_SYSTIME rStatUpdateTime; + u_int8_t fgIsStatValid; + +#if CFG_SUPPORT_MSP + struct EVENT_WLAN_INFO rEventWlanInfo; +#endif + + struct PARAM_LINK_SPEED_EX rLinkQuality; + + /* WIFI_VAR_T */ + struct WIFI_VAR rWifiVar; + + /* MTK WLAN NIC driver IEEE 802.11 MIB */ + struct IEEE_802_11_MIB rMib[KAL_AIS_NUM]; + + /* Mailboxs for inter-module communication */ + struct MBOX arMbox[MBOX_ID_TOTAL_NUM]; + + /* Timers for OID Pending Handling */ + struct TIMER rOidTimeoutTimer; + uint8_t ucOidTimeoutCount; + + /* Root Timer for cnm_timer module */ + struct ROOT_TIMER rRootTimer; + + u_int8_t fgIsChipNoAck; + u_int8_t fgIsChipAssert; + + /* RLM maintenance */ + enum ENUM_CHNL_EXT eRfSco; + enum ENUM_SYS_PROTECT_MODE eSysProtectMode; + enum ENUM_GF_MODE eSysHtGfMode; + enum ENUM_RIFS_MODE eSysTxRifsMode; + enum ENUM_SYS_PCO_PHASE eSysPcoPhase; + + struct DOMAIN_INFO_ENTRY *prDomainInfo; + + /* QM */ + struct QUE_MGT rQM; + + struct CNM_INFO rCnmInfo; + + uint32_t u4PowerMode; + + uint32_t u4CtiaPowerMode; + u_int8_t fgEnCtiaPowerMode; + + uint32_t fgEnArpFilter; + + uint32_t u4UapsdAcBmp; + + uint32_t u4MaxSpLen; + + uint32_t u4PsCurrentMeasureEn; + + /* Version Information */ + struct WIFI_VER_INFO rVerInfo; + + /* 5GHz support (from F/W) */ + u_int8_t fgIsHw5GBandDisabled; + u_int8_t fgEnable5GBand; + u_int8_t fgIsEepromUsed; + u_int8_t fgIsEfuseValid; + u_int8_t fgIsEmbbededMacAddrValid; + +#if CFG_SUPPORT_ANT_SWAP + u_int8_t fgIsSupportAntSwp; +#endif +#if CFG_SUPPORT_PWR_LIMIT_COUNTRY + u_int8_t fgIsPowerLimitTableValid; +#endif + + /* Packet Forwarding Tracking */ + int32_t i4PendingFwdFrameCount; + +#if CFG_SUPPORT_RDD_TEST_MODE + uint8_t ucRddStatus; +#endif + + u_int8_t fgDisStaAgingTimeoutDetection; + + uint32_t u4FwCompileFlag0; + uint32_t u4FwCompileFlag1; + uint32_t u4FwFeatureFlag0; + uint32_t u4FwFeatureFlag1; + +#if CFG_SUPPORT_CFG_FILE + struct WLAN_CFG *prWlanCfg; + struct WLAN_CFG rWlanCfg; + + struct WLAN_CFG_REC *prWlanCfgRec; + struct WLAN_CFG_REC rWlanCfgRec; + + struct WLAN_CFG *prWlanCfgEm; + struct WLAN_CFG rWlanCfgEm; +#endif + +#if CFG_M0VE_BA_TO_DRIVER + struct TIMER rMqmIdleRxBaDetectionTimer; + uint32_t u4FlagBitmap; +#endif +#if CFG_ASSERT_DUMP + struct TIMER rN9CorDumpTimer; + struct TIMER rCr4CorDumpTimer; + u_int8_t fgN9CorDumpFileOpend; + u_int8_t fgCr4CorDumpFileOpend; + u_int8_t fgN9AssertDumpOngoing; + u_int8_t fgCr4AssertDumpOngoing; + u_int8_t fgKeepPrintCoreDump; +#endif + /* Tx resource information */ + u_int8_t fgIsNicTxReousrceValid; + struct tx_resource_info nicTxReousrce; + + /* Efuse Start and End address */ + uint32_t u4EfuseStartAddress; + uint32_t u4EfuseEndAddress; + + /* COEX feature */ + uint32_t u4FddMode; + + /* host status EMI offset*/ + uint32_t u4HostStatusEmiOffset; + +#if CFG_WOW_SUPPORT + struct WOW_CTRL rWowCtrl; +#endif + +#if CFG_SUPPORT_NCHO /* NCHO information */ + struct NCHO_INFO rNchoInfo; +#endif + struct CFG_SCAN_CHNL rAddRoamScnChnl; + +/*#if (CFG_EEPROM_PAGE_ACCESS == 1)*/ + uint8_t aucEepromVaule[16]; /* HQA CMD for Efuse Block size contents */ + uint32_t u4FreeBlockNum; + uint32_t u4GetTxPower; +/*#endif*/ + u_int8_t fgIsCr4FwDownloaded; + u_int8_t fgIsFwDownloaded; + u_int8_t fgIsSupportBufferBinSize16Byte; + u_int8_t fgIsSupportDelayCal; + u_int8_t fgIsSupportGetFreeEfuseBlockCount; + u_int8_t fgIsSupportQAAccessEfuse; + u_int8_t fgIsSupportPowerOnSendBufferModeCMD; + u_int8_t fgIsSupportGetTxPower; + u_int8_t fgIsEnableLpdvt; + + /* SER related info */ + uint8_t ucSerState; + +#if (CFG_HW_WMM_BY_BSS == 1) + uint8_t ucHwWmmEnBit; +#endif + unsigned long ulSuspendFlag; + struct WIFI_FEM_CFG rWifiFemCfg; + + /* Smar Gear */ + uint8_t ucSmarGearSupportSisoOnly; + uint8_t ucSmartGearWfPathSupport; + + struct PERF_MONITOR rPerMonitor; + struct ICAP_INFO_T rIcapInfo; + struct RECAL_INFO_T rReCalInfo; + + /* Support change QM RX BA entry miss timeout (unit: ms) dynamically */ + uint32_t u4QmRxBaMissTimeout; + +#if CFG_SUPPORT_LOWLATENCY_MODE + u_int8_t fgEnLowLatencyMode; + u_int8_t fgEnCfg80211Scan; + u_int8_t fgEnTxDupDetect; + u_int8_t fgTxDupCertificate; + OS_SYSTIME tmTxDataInterval; +#endif /* CFG_SUPPORT_LOWLATENCY_MODE */ + +#if (CFG_SUPPORT_802_11AX == 1) + struct __HE_CFG_INFO_T rHeCfg; + uint8_t ucMcsMapSetFromSigma; + u_int8_t fgMcsMapBeenSet; + u_int8_t fgMuEdcaOverride; + uint32_t u4MBACount; + uint32_t u4HeHtcOM; + uint8_t fgEnShowHETrigger; + uint8_t fgTxPPDU; +#endif /* CFG_SUPPORT_802_11AX == 1 */ +#if (CFG_SUPPORT_TWT == 1) + struct _TWT_PLANNER_T rTWTPlanner; +#endif + +#if CFG_SUPPORT_WIFI_SYSDVT + struct AUTOMATION_DVT *auto_dvt; + uint16_t u2TxTest; + uint16_t u2TxTestCount; + uint8_t ucTxTestUP; +#endif /* CFG_SUPPORT_WIFI_SYSDVT */ + + uint32_t u4HifDbgFlag; + uint32_t u4HifChkFlag; + uint32_t u4NoMoreRfb; + + /* Only for PCIE DmaSchdl usage so far. */ + struct { + bool fgRun; + uint32_t u4Quota; + } rWmmQuotaReqCS[BSS_DEFAULT_NUM]; + + /* TX HIF Control falgs */ + uint32_t au4TxHifResCtl[TX_PORT_NUM]; + uint32_t u4TxHifResCtlIdx; + uint32_t u4TxHifResCtlNum; + +#if CFG_SUPPORT_OSHARE + bool fgEnOshareMode; +#endif + +#if CFG_MTK_MCIF_WIFI_SUPPORT + bool fgMddpActivated; +#endif + + struct WLAN_DEBUG_INFO rDebugInfo; +#if CFG_SUPPORT_IOT_AP_BLACKLIST + struct WLAN_IOT_AP_RULE_T rIotApRule[CFG_IOT_AP_RULE_MAX_CNT]; +#endif + +#ifdef CFG_SUPPORT_LINK_QUALITY_MONITOR + uint32_t u4LastLinkQuality; + uint32_t u4LinkQualityCounter; + struct WIFI_LINK_QUALITY_INFO rLinkQualityInfo; + struct PARAM_GET_STA_STATISTICS rQueryStaStatistics; + struct PARAM_802_11_STATISTICS_STRUCT rStat; + uint32_t u4BufLen; +#endif /* CFG_SUPPORT_LINK_QUALITY_MONITOR */ + +#if CFG_SUPPORT_DYNAMIC_PWR_LIMIT + /* dynamic tx power control */ + struct LINK rTxPwr_DefaultList; + struct LINK rTxPwr_DynamicList; +#endif + +#if CFG_DBG_MGT_BUF + struct LINK rMemTrackLink; +#endif + +#if CFG_SUPPORT_DATA_STALL + OS_SYSTIME tmReportinterval; +#endif + +#if CFG_SUPPORT_BIGDATA_PIP + OS_SYSTIME tmDataPipReportinterval; +#endif + + int8_t cArpNoResponseIdx; + + u_int8_t fgEnDbgPowerMode; + + struct HIF_STATS rHifStats; +}; /* end of _ADAPTER_T */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +#define SUSPEND_FLAG_FOR_WAKEUP_REASON (0) +#define SUSPEND_FLAG_CLEAR_WHEN_RESUME (1) + +/* Macros for argument _BssIndex */ +#define IS_NET_ACTIVE(_prAdapter, _BssIndex) \ + ((_prAdapter)->aprBssInfo[(_BssIndex)]->fgIsNetActive) + +/* Macros for argument _prBssInfo */ +#define IS_BSS_ACTIVE(_prBssInfo) ((_prBssInfo)->fgIsNetActive) + +#define IS_BSS_AIS(_prBssInfo) \ + ((_prBssInfo)->eNetworkType == NETWORK_TYPE_AIS) + +#define IS_BSS_INDEX_AIS(_prAdapter, _BssIndex) \ + (_BssIndex < KAL_AIS_NUM) + +#define IS_BSS_P2P(_prBssInfo) \ + ((_prBssInfo)->eNetworkType == NETWORK_TYPE_P2P) + +#define IS_BSS_BOW(_prBssInfo) \ + ((_prBssInfo)->eNetworkType == NETWORK_TYPE_BOW) + +#define IS_BSS_APGO(_prBssInfo) \ + (IS_BSS_P2P(_prBssInfo) && \ + (_prBssInfo)->eCurrentOPMode == OP_MODE_ACCESS_POINT) + +#define SET_NET_ACTIVE(_prAdapter, _BssIndex) \ + {(_prAdapter)->aprBssInfo[(_BssIndex)]->fgIsNetActive = TRUE; } + +#define UNSET_NET_ACTIVE(_prAdapter, _BssIndex) \ + {(_prAdapter)->aprBssInfo[(_BssIndex)]->fgIsNetActive = FALSE; } + +#define BSS_INFO_INIT(_prAdapter, _prBssInfo) \ +{ uint8_t _aucZeroMacAddr[] = NULL_MAC_ADDR; \ + \ + (_prBssInfo)->eConnectionState = MEDIA_STATE_DISCONNECTED; \ + (_prBssInfo)->eConnectionStateIndicated = \ + MEDIA_STATE_DISCONNECTED; \ + (_prBssInfo)->eCurrentOPMode = OP_MODE_INFRASTRUCTURE; \ + (_prBssInfo)->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_RESERVED; \ + COPY_MAC_ADDR((_prBssInfo)->aucBSSID, _aucZeroMacAddr); \ + LINK_INITIALIZE(&((_prBssInfo)->rStaRecOfClientList)); \ + (_prBssInfo)->fgIsBeaconActivated = FALSE; \ + (_prBssInfo)->u2HwDefaultFixedRateCode = RATE_CCK_1M_LONG; \ +} + +/*----------------------------------------------------------------------------*/ +/* Macros for Power State */ +/*----------------------------------------------------------------------------*/ +#define SET_NET_PWR_STATE_IDLE(_prAdapter, _BssIndex) \ + {_prAdapter->rWifiVar.aePwrState[(_BssIndex)] = PWR_STATE_IDLE; } + +#define SET_NET_PWR_STATE_ACTIVE(_prAdapter, _BssIndex) \ + {_prAdapter->rWifiVar.aePwrState[(_BssIndex)] = PWR_STATE_ACTIVE; } + +#define SET_NET_PWR_STATE_PS(_prAdapter, _BssIndex) \ + {_prAdapter->rWifiVar.aePwrState[(_BssIndex)] = PWR_STATE_PS; } + +#define IS_NET_PWR_STATE_ACTIVE(_prAdapter, _BssIndex) \ + (_prAdapter->rWifiVar.aePwrState[(_BssIndex)] == PWR_STATE_ACTIVE) + +#define IS_NET_PWR_STATE_IDLE(_prAdapter, _BssIndex) \ + (_prAdapter->rWifiVar.aePwrState[(_BssIndex)] == PWR_STATE_IDLE) + +#define IS_SCN_PWR_STATE_ACTIVE(_prAdapter) \ + (_prAdapter->rWifiVar.rScanInfo.eScanPwrState == SCAN_PWR_STATE_ACTIVE) + +#define IS_SCN_PWR_STATE_IDLE(_prAdapter) \ + (_prAdapter->rWifiVar.rScanInfo.eScanPwrState == SCAN_PWR_STATE_IDLE) + +#define IS_WIFI_2G4_WF0_SUPPORT(_prAdapter) \ + ((_prAdapter)->rWifiFemCfg.u2WifiPath & WLAN_FLAG_2G4_WF0) + +#define IS_WIFI_5G_WF0_SUPPORT(_prAdapter) \ + ((_prAdapter)->rWifiFemCfg.u2WifiPath & WLAN_FLAG_5G_WF0) + +#define IS_WIFI_2G4_WF1_SUPPORT(_prAdapter) \ + ((_prAdapter)->rWifiFemCfg.u2WifiPath & WLAN_FLAG_2G4_WF1) + +#define IS_WIFI_5G_WF1_SUPPORT(_prAdapter) \ + ((_prAdapter)->rWifiFemCfg.u2WifiPath & WLAN_FLAG_5G_WF1) + +#define IS_WIFI_2G4_SISO(_prAdapter) \ + ((IS_WIFI_2G4_WF0_SUPPORT(_prAdapter) && \ + !(IS_WIFI_2G4_WF1_SUPPORT(_prAdapter))) || \ + (IS_WIFI_2G4_WF1_SUPPORT(_prAdapter) && \ + !(IS_WIFI_2G4_WF0_SUPPORT(_prAdapter)))) + +#define IS_WIFI_5G_SISO(_prAdapter) \ + ((IS_WIFI_5G_WF0_SUPPORT(_prAdapter) && \ + !(IS_WIFI_5G_WF1_SUPPORT(_prAdapter))) || \ + (IS_WIFI_5G_WF1_SUPPORT(_prAdapter) && \ + !(IS_WIFI_5G_WF0_SUPPORT(_prAdapter)))) + +#define IS_WIFI_SMART_GEAR_SUPPORT_WF0_SISO(_prAdapter) \ + ((_prAdapter)->ucSmarGearSupportSisoOnly && \ + ((_prAdapter)->ucSmartGearWfPathSupport == BIT(ANTENNA_WF0))) + +#define IS_WIFI_SMART_GEAR_SUPPORT_WF1_SISO(_prAdapter) \ + ((_prAdapter)->ucSmarGearSupportSisoOnly && \ + ((_prAdapter)->ucSmartGearWfPathSupport == BIT(ANTENNA_WF1))) + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#endif /* _ADAPTER_H */ + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/bow.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/bow.h new file mode 100644 index 0000000000000000000000000000000000000000..c7e7cbe85b8e14073715520222cb8e6f3fc3f4bc --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/bow.h @@ -0,0 +1,266 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* +** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/bow.h#1 +*/ + + +#ifndef _BOW_H_ +#define _BOW_H_ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +#define BOWDEVNAME "bow0" + +#define MAX_BOW_NUMBER_OF_CHANNEL_2G4 14 +#define MAX_BOW_NUMBER_OF_CHANNEL_5G 4 +/* (MAX_BOW_NUMBER_OF_CHANNEL_2G4 + MAX_BOW_NUMBER_OF_CHANNEL_5G) */ +#define MAX_BOW_NUMBER_OF_CHANNEL 18 + +#define MAX_ACTIVITY_REPORT 2 +#define MAX_ACTIVITY_REPROT_TIME 660 + +#define ACTIVITY_REPORT_STATUS_SUCCESS 0 +#define ACTIVITY_REPORT_STATUS_FAILURE 1 +#define ACTIVITY_REPORT_STATUS_TIME_INVALID 2 +#define ACTIVITY_REPORT_STATUS_OTHERS 3 + +#define ACTIVITY_REPORT_SCHEDULE_UNKNOWN 0 /* Does not know the schedule of the interference */ +#define ACTIVITY_REPORT_SCHEDULE_KNOWN 1 + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ +struct BT_OVER_WIFI_COMMAND_HEADER { + uint8_t ucCommandId; + uint8_t ucSeqNumber; + uint16_t u2PayloadLength; +}; + +struct BT_OVER_WIFI_COMMAND { + struct BT_OVER_WIFI_COMMAND_HEADER rHeader; + uint8_t aucPayload[0]; +}; + +struct BT_OVER_WIFI_EVENT_HEADER { + uint8_t ucEventId; + uint8_t ucSeqNumber; + uint16_t u2PayloadLength; +}; + +struct BT_OVER_WIFI_EVENT { + struct BT_OVER_WIFI_EVENT_HEADER rHeader; + uint8_t aucPayload[0]; +}; + +struct CHANNEL_DESC { + uint8_t ucChannelBand; + uint8_t ucChannelNum; +}; + +/* Command Structures */ +struct BOW_SETUP_CONNECTION { +/* Fixed to 2.4G */ + uint8_t ucChannelNum; + uint8_t ucReserved1; + uint8_t aucPeerAddress[6]; + uint16_t u2BeaconInterval; + uint8_t ucTimeoutDiscovery; + uint8_t ucTimeoutInactivity; + uint8_t ucRole; + uint8_t ucPAL_Capabilities; + int8_t cMaxTxPower; + uint8_t ucReserved2; + +/* Pending, for future BOW 5G supporting. */ +/* UINT_8 aucPeerAddress[6]; + * UINT_16 u2BeaconInterval; + * UINT_8 ucTimeoutDiscovery; + * UINT_8 ucTimeoutInactivity; + * UINT_8 ucRole; + * UINT_8 ucPAL_Capabilities; + * INT_8 cMaxTxPower; + * UINT_8 ucChannelListNum; + * CHANNEL_DESC arChannelList[1]; + */ +}; + +struct BOW_DESTROY_CONNECTION { + uint8_t aucPeerAddress[6]; + uint8_t aucReserved[2]; +}; + +struct BOW_SET_PTK { + uint8_t aucPeerAddress[6]; + uint8_t aucReserved[2]; + uint8_t aucTemporalKey[16]; +}; + +struct BOW_READ_RSSI { + uint8_t aucPeerAddress[6]; + uint8_t aucReserved[2]; +}; + +struct BOW_READ_LINK_QUALITY { + uint8_t aucPeerAddress[6]; + uint8_t aucReserved[2]; +}; + +struct BOW_SHORT_RANGE_MODE { + uint8_t aucPeerAddress[6]; + int8_t cTxPower; + uint8_t ucReserved; +}; + +/* Event Structures */ +struct BOW_COMMAND_STATUS { + uint8_t ucStatus; + uint8_t ucReserved[3]; +}; + +struct BOW_MAC_STATUS { + uint8_t aucMacAddr[6]; + uint8_t ucAvailability; + uint8_t ucNumOfChannel; + struct CHANNEL_DESC arChannelList[MAX_BOW_NUMBER_OF_CHANNEL]; +}; + +struct BOW_LINK_CONNECTED { + struct CHANNEL_DESC rChannel; + uint8_t aucReserved; + uint8_t aucPeerAddress[6]; +}; + +struct BOW_LINK_DISCONNECTED { + uint8_t ucReason; + uint8_t aucReserved; + uint8_t aucPeerAddress[6]; +}; + +struct BOW_RSSI { + int8_t cRssi; + uint8_t aucReserved[3]; +}; + +struct BOW_LINK_QUALITY { + uint8_t ucLinkQuality; + uint8_t aucReserved[3]; +}; + +enum ENUM_BOW_CMD_ID { + BOW_CMD_ID_GET_MAC_STATUS = 1, + BOW_CMD_ID_SETUP_CONNECTION, + BOW_CMD_ID_DESTROY_CONNECTION, + BOW_CMD_ID_SET_PTK, + BOW_CMD_ID_READ_RSSI, + BOW_CMD_ID_READ_LINK_QUALITY, + BOW_CMD_ID_SHORT_RANGE_MODE, + BOW_CMD_ID_GET_CHANNEL_LIST, +}; + +enum ENUM_BOW_EVENT_ID { + BOW_EVENT_ID_COMMAND_STATUS = 1, + BOW_EVENT_ID_MAC_STATUS, + BOW_EVENT_ID_LINK_CONNECTED, + BOW_EVENT_ID_LINK_DISCONNECTED, + BOW_EVENT_ID_RSSI, + BOW_EVENT_ID_LINK_QUALITY, + BOW_EVENT_ID_CHANNEL_LIST, + BOW_EVENT_ID_CHANNEL_SELECTED, +}; + +enum ENUM_BOW_DEVICE_STATE { + BOW_DEVICE_STATE_DISCONNECTED = 0, + BOW_DEVICE_STATE_DISCONNECTING, + BOW_DEVICE_STATE_ACQUIRING_CHANNEL, + BOW_DEVICE_STATE_STARTING, + BOW_DEVICE_STATE_SCANNING, + BOW_DEVICE_STATE_CONNECTING, + BOW_DEVICE_STATE_CONNECTED, + BOW_DEVICE_STATE_NUM +}; + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +#endif /*_BOW_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/cmd_buf.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/cmd_buf.h new file mode 100644 index 0000000000000000000000000000000000000000..fc879d56f4a5ccef42cd1701c13e501e535ca1de --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/cmd_buf.h @@ -0,0 +1,227 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: + */ + +/*! \file "cmd_buf.h" + * \brief In this file we define the structure for Command Packet. + * + * In this file we define the structure for Command Packet and the + * control unit of MGMT Memory Pool. + */ + + +#ifndef _CMD_BUF_H +#define _CMD_BUF_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +enum COMMAND_TYPE { + COMMAND_TYPE_GENERAL_IOCTL, + COMMAND_TYPE_NETWORK_IOCTL, + COMMAND_TYPE_SECURITY_FRAME, + COMMAND_TYPE_MANAGEMENT_FRAME, + COMMAND_TYPE_DATA_FRAME, + COMMAND_TYPE_NUM +}; + +typedef void(*PFN_CMD_DONE_HANDLER) (IN struct ADAPTER + *prAdapter, IN struct CMD_INFO *prCmdInfo, + IN uint8_t *pucEventBuf); + +typedef void(*PFN_CMD_TIMEOUT_HANDLER) (IN struct ADAPTER + *prAdapter, IN struct CMD_INFO *prCmdInfo); + +typedef void(*PFN_HIF_TX_CMD_DONE_CB) (IN struct ADAPTER + *prAdapter, IN struct CMD_INFO *prCmdInfo); + +struct CMD_INFO { + struct QUE_ENTRY rQueEntry; + + enum COMMAND_TYPE eCmdType; + + uint16_t u2InfoBufLen; /* This is actual CMD buffer length */ + uint8_t *pucInfoBuffer; /* May pointer to structure in prAdapter */ + struct MSDU_INFO + *prMsduInfo; /* only valid when it's a security/MGMT frame */ + void *prPacket; /* only valid when it's a security frame */ + + PFN_CMD_DONE_HANDLER pfCmdDoneHandler; + PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler; + PFN_HIF_TX_CMD_DONE_CB pfHifTxCmdDoneCb; + + u_int8_t fgIsOid; /* Used to check if we need indicate */ + + uint8_t ucCID; + u_int8_t fgSetQuery; + u_int8_t fgNeedResp; + uint8_t ucCmdSeqNum; + uint32_t u4SetInfoLen; /* Indicate how many byte we read for Set OID */ + + /* information indicating by OID/ioctl */ + void *pvInformationBuffer; + uint32_t u4InformationBufferLength; + + /* private data */ + uint32_t u4PrivateData; + + /* TXD/TXP pointer/len for hif tx copy */ + uint32_t u4TxdLen; + uint32_t u4TxpLen; + uint8_t *pucTxd; + uint8_t *pucTxp; +}; + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ +#if CFG_DBG_MGT_BUF +#define cmdBufAllocateCmdInfo(_prAdapter, u4Length) \ + cmdBufAllocateCmdInfoX(_prAdapter, u4Length, \ + __FILE__ ":" STRLINE(__LINE__)) +#endif + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +void cmdBufInitialize(IN struct ADAPTER *prAdapter); + +#if CFG_DBG_MGT_BUF +struct CMD_INFO *cmdBufAllocateCmdInfoX(IN struct ADAPTER + *prAdapter, IN uint32_t u4Length, + uint8_t *fileAndLine); +#else +struct CMD_INFO *cmdBufAllocateCmdInfo(IN struct ADAPTER + *prAdapter, IN uint32_t u4Length); +#endif + +void cmdBufFreeCmdInfo(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo); + +/*----------------------------------------------------------------------------*/ +/* Routines for CMDs */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanSendSetQueryCmd(IN struct ADAPTER *prAdapter, + uint8_t ucCID, + u_int8_t fgSetQuery, + u_int8_t fgNeedResp, + u_int8_t fgIsOid, + PFN_CMD_DONE_HANDLER pfCmdDoneHandler, + PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler, + uint32_t u4SetQueryInfoLen, + uint8_t *pucInfoBuffer, OUT void *pvSetQueryBuffer, + IN uint32_t u4SetQueryBufferLen); + +#if CFG_SUPPORT_TX_BF +uint32_t +wlanSendSetQueryExtCmd(IN struct ADAPTER *prAdapter, + uint8_t ucCID, + uint8_t ucExtCID, + u_int8_t fgSetQuery, + u_int8_t fgNeedResp, + u_int8_t fgIsOid, + PFN_CMD_DONE_HANDLER pfCmdDoneHandler, + PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler, + uint32_t u4SetQueryInfoLen, + uint8_t *pucInfoBuffer, OUT void *pvSetQueryBuffer, + IN uint32_t u4SetQueryBufferLen); +#endif + +void cmdBufDumpCmdQueue(struct QUE *prQueue, + int8_t *queName); +#if (CFG_SUPPORT_TRACE_TC4 == 1) +void wlanDebugTC4Init(void); +void wlanDebugTC4Uninit(void); +void wlanTraceReleaseTcRes(struct ADAPTER *prAdapter, + uint32_t u4TxRlsCnt, uint32_t u4Available); +void wlanTraceTxCmd(struct CMD_INFO *prCmd); +void wlanDumpTcResAndTxedCmd(uint8_t *pucBuf, + uint32_t maxLen); +#endif + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +#endif /* _CMD_BUF_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/connac_dmashdl.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/connac_dmashdl.h new file mode 100644 index 0000000000000000000000000000000000000000..51750e81530beba34929279002a142546bb111e4 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/connac_dmashdl.h @@ -0,0 +1,458 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/*! \file "connac_dmashdl.h" + * \brief The common register definition of MT6630 + * + * N/A + */ + + + +#ifndef _CONNAC_DMASHDL_H +#define _CONNAC_DMASHDL_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +#if defined(_HIF_PCIE) || defined(_HIF_AXI) +#define PCIE_HIF_DMASHDL_BASE 0x6000 +#endif /* _HIF_PCIE */ + +#if defined(_HIF_USB) +#define USB_HIF_DMASHDL_BASE 0x5000A000 +#endif /* _HIF_USB */ + +#define CONN_HIF_DMASHDL_SW_CONTROL(_base) (_base + 0x04) +#define CONN_HIF_DMASHDL_OPTIONAL_CONTROL(_base) (_base + 0x08) + +#define CONN_HIF_DMASHDL_PAGE_SETTING(_base) (_base + 0x0C) +/* User program group sequence type control */ +/* 0: user program group sequence order type, + * 1: pre define each slot group strict order + */ +#define CONN_HIF_DMASHDL_GROUP_SEQ_ORDER_TYPE BIT(16) + +#define CONN_HIF_DMASHDL_REFILL_CONTROL(_base) (_base + 0x10) +#define CONN_HIF_DMASHDL_TX_PACKET_SIZE_PAGE_MAP(_base) (_base + 0x14) + +#define CONN_HIF_DMASHDL_CONTROL_SIGNAL(_base) (_base + 0x18) +/* enable to clear the flag of PLE TXD size greater than ple max. size */ +#define CONN_HIF_DMASHDL_PLE_TXD_GT_MAX_SIZE_FLAG_CLR \ + BIT(0) +#define CONN_HIF_DMASHDL_HIF_ASK_SUB_ENA \ + BIT(16) /* enable packet in substration action from HIF ask period */ +#define CONN_HIF_DMASHDL_PLE_SUB_ENA \ + BIT(17) /* enable packet in substration action from PLE */ +/* enable terminate refill period when PLE release packet to do addition */ +#define CONN_HIF_DMASHDL_PLE_ADD_INT_REFILL_ENA \ + BIT(29) +/* enable terminate refill period when packet in to do addition */ +#define CONN_HIF_DMASHDL_PDMA_ADD_INT_REFILL_ENA \ + BIT(30) +/* enable terminate refill period when packet in to do substration */ +#define CONN_HIF_DMASHDL_PKTIN_INT_REFILL_ENA \ + BIT(31) + +#define CONN_HIF_DMASHDL_PACKET_MAX_SIZE(_base) (_base + 0x1C) +#define CONN_HIF_DMASHDL_GROUP0_CONTROL(_base) (_base + 0x20) +#define CONN_HIF_DMASHDL_REFILL_CTRL(_base) (_base + 0x10) +#define CONN_HIF_DMASHDL_GROUP0_CTRL(_base) (_base + 0x20) +#define CONN_HIF_DMASHDL_GROUP1_CTRL(_base) (_base + 0x24) +#define CONN_HIF_DMASHDL_GROUP2_CTRL(_base) (_base + 0x28) +#define CONN_HIF_DMASHDL_GROUP3_CTRL(_base) (_base + 0x2c) +#define CONN_HIF_DMASHDL_GROUP4_CTRL(_base) (_base + 0x30) +#define CONN_HIF_DMASHDL_GROUP5_CTRL(_base) (_base + 0x34) +#define CONN_HIF_DMASHDL_GROUP6_CTRL(_base) (_base + 0x38) +#define CONN_HIF_DMASHDL_GROUP7_CTRL(_base) (_base + 0x3c) +#define CONN_HIF_DMASHDL_GROUP8_CTRL(_base) (_base + 0x40) +#define CONN_HIF_DMASHDL_GROUP9_CTRL(_base) (_base + 0x44) +#define CONN_HIF_DMASHDL_GROUP10_CTRL(_base) (_base + 0x48) +#define CONN_HIF_DMASHDL_GROUP11_CTRL(_base) (_base + 0x4c) +#define CONN_HIF_DMASHDL_GROUP12_CTRL(_base) (_base + 0x50) +#define CONN_HIF_DMASHDL_GROUP13_CTRL(_base) (_base + 0x54) +#define CONN_HIF_DMASHDL_GROUP14_CTRL(_base) (_base + 0x58) +#define CONN_HIF_DMASHDL_GROUP15_CTRL(_base) (_base + 0x5c) +#define CONN_HIF_DMASHDL_SHDL_SET0(_base) (_base + 0xb0) +#define CONN_HIF_DMASHDL_SHDL_SET1(_base) (_base + 0xb4) +#define CONN_HIF_DMASHDL_SLOT_SET0(_base) (_base + 0xc4) +#define CONN_HIF_DMASHDL_SLOT_SET1(_base) (_base + 0xc8) +#define CONN_HIF_DMASHDL_Q_MAP0(_base) (_base + 0xd0) +#define CONN_HIF_DMASHDL_Q_MAP1(_base) (_base + 0xd4) +#define CONN_HIF_DMASHDL_Q_MAP2(_base) (_base + 0xd8) +#define CONN_HIF_DMASHDL_Q_MAP3(_base) (_base + 0xdc) + +#define CONN_HIF_DMASHDL_ERROR_FLAG_CTRL(_base) (_base + 0x9c) + +#define CONN_HIF_DMASHDL_STATUS_RD(_base) (_base + 0x100) +#define CONN_HIF_DMASHDL_STATUS_RD_GP0(_base) (_base + 0x140) +#define CONN_HIF_DMASHDL_STATUS_RD_GP1(_base) (_base + 0x144) +#define CONN_HIF_DMASHDL_STATUS_RD_GP2(_base) (_base + 0x148) +#define CONN_HIF_DMASHDL_STATUS_RD_GP3(_base) (_base + 0x14c) +#define CONN_HIF_DMASHDL_STATUS_RD_GP4(_base) (_base + 0x150) +#define CONN_HIF_DMASHDL_STATUS_RD_GP5(_base) (_base + 0x154) +#define CONN_HIF_DMASHDL_STATUS_RD_GP6(_base) (_base + 0x158) +#define CONN_HIF_DMASHDL_STATUS_RD_GP7(_base) (_base + 0x15c) +#define CONN_HIF_DMASHDL_STATUS_RD_GP8(_base) (_base + 0x160) +#define CONN_HIF_DMASHDL_STATUS_RD_GP9(_base) (_base + 0x164) +#define CONN_HIF_DMASHDL_STATUS_RD_GP10(_base) (_base + 0x168) +#define CONN_HIF_DMASHDL_STATUS_RD_GP11(_base) (_base + 0x16c) +#define CONN_HIF_DMASHDL_STATUS_RD_GP12(_base) (_base + 0x170) +#define CONN_HIF_DMASHDL_STATUS_RD_GP13(_base) (_base + 0x174) +#define CONN_HIF_DMASHDL_STATUS_RD_GP14(_base) (_base + 0x178) +#define CONN_HIF_DMASHDL_STATUS_RD_GP15(_base) (_base + 0x17c) +#define CONN_HIF_DMASHDLRD_GP_PKT_CNT_0(_base) (_base + 0x180) +#define CONN_HIF_DMASHDLRD_GP_PKT_CNT_1(_base) (_base + 0x184) +#define CONN_HIF_DMASHDLRD_GP_PKT_CNT_2(_base) (_base + 0x188) +#define CONN_HIF_DMASHDLRD_GP_PKT_CNT_3(_base) (_base + 0x18c) +#define CONN_HIF_DMASHDLRD_GP_PKT_CNT_4(_base) (_base + 0x190) +#define CONN_HIF_DMASHDLRD_GP_PKT_CNT_5(_base) (_base + 0x194) +#define CONN_HIF_DMASHDLRD_GP_PKT_CNT_6(_base) (_base + 0x198) +#define CONN_HIF_DMASHDLRD_GP_PKT_CNT_7(_base) (_base + 0x19c) + +/* ============================================================================ + * + * ---REFILL_CONTROL (0x5000A000 + 0x10)--- + * + * GROUP0_REFILL_DISABLE[16] - (RW) Group0 refill control + * GROUP1_REFILL_DISABLE[17] - (RW) Group1 refill control + * GROUP2_REFILL_DISABLE[18] - (RW) Group2 refill control + * GROUP3_REFILL_DISABLE[19] - (RW) Group3 refill control + * GROUP4_REFILL_DISABLE[20] - (RW) Group4 refill control + * GROUP5_REFILL_DISABLE[21] - (RW) Group5 refill control + * GROUP6_REFILL_DISABLE[22] - (RW) Group6 refill control + * GROUP7_REFILL_DISABLE[23] - (RW) Group7 refill control + * GROUP8_REFILL_DISABLE[24] - (RW) Group8 refill control + * GROUP9_REFILL_DISABLE[25] - (RW) Group9 refill control + * GROUP10_REFILL_DISABLE[26] - (RW) Group10 refill control + * GROUP11_REFILL_DISABLE[27] - (RW) Group11 refill control + * GROUP12_REFILL_DISABLE[28] - (RW) Group12 refill control + * GROUP13_REFILL_DISABLE[29] - (RW) Group13 refill control + * GROUP14_REFILL_DISABLE[30] - (RW) Group14 refill control + * GROUP15_REFILL_DISABLE[31] - (RW) Group15 refill control + * + * ============================================================================ + */ +#define CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP15_REFILL_DISABLE_MASK \ + 0x80000000 +#define CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP14_REFILL_DISABLE_MASK \ + 0x40000000 +#define CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP13_REFILL_DISABLE_MASK \ + 0x20000000 +#define CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP12_REFILL_DISABLE_MASK \ + 0x10000000 +#define CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP11_REFILL_DISABLE_MASK \ + 0x08000000 +#define CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP10_REFILL_DISABLE_MASK \ + 0x04000000 +#define CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP9_REFILL_DISABLE_MASK \ + 0x02000000 +#define CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP8_REFILL_DISABLE_MASK \ + 0x01000000 +#define CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP7_REFILL_DISABLE_MASK \ + 0x00800000 +#define CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP6_REFILL_DISABLE_MASK \ + 0x00400000 +#define CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP5_REFILL_DISABLE_MASK \ + 0x00200000 +#define CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP4_REFILL_DISABLE_MASK \ + 0x00100000 +#define CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP3_REFILL_DISABLE_MASK \ + 0x00080000 +#define CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP2_REFILL_DISABLE_MASK \ + 0x00040000 +#define CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP1_REFILL_DISABLE_MASK \ + 0x00020000 +#define CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP0_REFILL_DISABLE_MASK \ + 0x00010000 +#define CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP15_REFILL_PRIORITY_MASK \ + 0x00008000 +#define CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP14_REFILL_PRIORITY_MASK \ + 0x00004000 +#define CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP13_REFILL_PRIORITY_MASK \ + 0x00002000 +#define CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP12_REFILL_PRIORITY_MASK \ + 0x00001000 +#define CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP11_REFILL_PRIORITY_MASK \ + 0x00000800 +#define CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP10_REFILL_PRIORITY_MASK \ + 0x00000400 +#define CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP9_REFILL_PRIORITY_MASK \ + 0x00000200 +#define CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP8_REFILL_PRIORITY_MASK \ + 0x00000100 +#define CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP7_REFILL_PRIORITY_MASK \ + 0x00000080 +#define CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP6_REFILL_PRIORITY_MASK \ + 0x00000040 +#define CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP5_REFILL_PRIORITY_MASK \ + 0x00000020 +#define CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP4_REFILL_PRIORITY_MASK \ + 0x00000010 +#define CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP3_REFILL_PRIORITY_MASK \ + 0x00000008 +#define CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP2_REFILL_PRIORITY_MASK \ + 0x00000004 +#define CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP1_REFILL_PRIORITY_MASK \ + 0x00000002 +#define CONN_HIF_DMASHDL_TOP_REFILL_CONTROL_GROUP0_REFILL_PRIORITY_MASK \ + 0x00000001 + +/* ============================================================================ + * + * ---QUEUE_MAPPING0 (0x5000A000 + 0xd0)--- + * + * QUEUE0_MAPPING[3..0] - (RW) queue 0 use which group ID + * QUEUE1_MAPPING[7..4] - (RW) queue 1 use which group ID + * QUEUE2_MAPPING[11..8] - (RW) queue 2 use which group ID + * QUEUE3_MAPPING[15..12] - (RW) queue 3 use which group ID + * QUEUE4_MAPPING[19..16] - (RW) queue 4 use which group ID + * QUEUE5_MAPPING[23..20] - (RW) queue 5 use which group ID + * QUEUE6_MAPPING[27..24] - (RW) queue 6 use which group ID + * QUEUE7_MAPPING[31..28] - (RW) queue 7 use which group ID + * + * ============================================================================ + */ +#define CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE7_MAPPING 28 +#define CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE6_MAPPING 24 +#define CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE5_MAPPING 20 +#define CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE4_MAPPING 16 +#define CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE3_MAPPING 12 +#define CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE2_MAPPING 8 +#define CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE1_MAPPING 4 +#define CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING0_QUEUE0_MAPPING 0 + +/* ============================================================================ + * + * ---QUEUE_MAPPING1 (0x5000A000 + 0xd4)--- + * + * QUEUE8_MAPPING[3..0] - (RW) queue 8 use which group ID + * QUEUE9_MAPPING[7..4] - (RW) queue 9 use which group ID + * QUEUE10_MAPPING[11..8] - (RW) queue 10 use which group ID + * QUEUE11_MAPPING[15..12] - (RW) queue 11 use which group ID + * QUEUE12_MAPPING[19..16] - (RW) queue 12 use which group ID + * QUEUE13_MAPPING[23..20] - (RW) queue 13 use which group ID + * QUEUE14_MAPPING[27..24] - (RW) queue 14 use which group ID + * QUEUE15_MAPPING[31..28] - (RW) queue 15 use which group ID + * + * ============================================================================ + */ +#define CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE15_MAPPING 28 +#define CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE14_MAPPING 24 +#define CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE13_MAPPING 20 +#define CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE12_MAPPING 16 +#define CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE11_MAPPING 12 +#define CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE10_MAPPING 8 +#define CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE9_MAPPING 4 +#define CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING1_QUEUE8_MAPPING 0 + +/* ============================================================================ + * + * ---QUEUE_MAPPING2 (0x5000A000 + 0xd8)--- + * + * QUEUE16_MAPPING[3..0] - (RW) queue 16 use which group ID + * QUEUE17_MAPPING[7..4] - (RW) queue 17 use which group ID + * QUEUE18_MAPPING[11..8] - (RW) queue 18 use which group ID + * QUEUE19_MAPPING[15..12] - (RW) queue 19 use which group ID + * QUEUE20_MAPPING[19..16] - (RW) queue 20 use which group ID + * QUEUE21_MAPPING[23..20] - (RW) queue 21 use which group ID + * QUEUE22_MAPPING[27..24] - (RW) queue 22 use which group ID + * QUEUE23_MAPPING[31..28] - (RW) queue 23 use which group ID + * + * ============================================================================= + */ +#define CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE23_MAPPING 28 +#define CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE22_MAPPING 24 +#define CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE21_MAPPING 20 +#define CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE20_MAPPING 16 +#define CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE19_MAPPING 12 +#define CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE18_MAPPING 8 +#define CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE17_MAPPING 4 +#define CONN_HIF_DMASHDL_TOP_QUEUE_MAPPING2_QUEUE16_MAPPING 0 + +#define DMASHDL_RSV_CNT_MASK (0xfff << 16) +#define DMASHDL_SRC_CNT_MASK (0xfff << 0) +#define DMASHDL_RSV_CNT_OFFSET 16 +#define DMASHDL_SRC_CNT_OFFSET 0 +#define DMASHDL_FREE_PG_CNT_MASK (0xfff << 16) +#define DMASHDL_FFA_CNT_MASK (0xfff << 0) +#define DMASHDL_FREE_PG_CNT_OFFSET 16 +#define DMASHDL_FFA_CNT_OFFSET 0 +#define DMASHDL_MAX_QUOTA_MASK (0xfff << 16) +#define DMASHDL_MIN_QUOTA_MASK (0xfff << 0) +#define DMASHDL_MAX_QUOTA_OFFSET 16 +#define DMASHDL_MIN_QUOTA_OFFSET 0 + +#define DMASHDL_MIN_QUOTA_NUM(p) (((p) & 0xfff) << DMASHDL_MIN_QUOTA_OFFSET) +#define GET_DMASHDL_MIN_QUOTA_NUM(p) \ + (((p) & DMASHDL_MIN_QUOTA_MASK) >> DMASHDL_MIN_QUOTA_OFFSET) + +#define DMASHDL_MAX_QUOTA_NUM(p) \ + (((p) & 0xfff) << DMASHDL_MAX_QUOTA_OFFSET) +#define GET_DMASHDL_MAX_QUOTA_NUM(p) \ + (((p) & DMASHDL_MAX_QUOTA_MASK) >> DMASHDL_MAX_QUOTA_OFFSET) + +#define ODD_GROUP_ASK_CN_MASK (0xff << 16) +#define ODD_GROUP_ASK_CN_OFFSET 16 +#define GET_ODD_GROUP_ASK_CNT(p) \ + (((p) & ODD_GROUP_ASK_CN_MASK) >> ODD_GROUP_ASK_CN_OFFSET) +#define ODD_GROUP_PKT_IN_CN_MASK (0xff << 24) +#define ODD_GROUP_PKT_IN_CN_OFFSET 24 +#define GET_ODD_GROUP_PKT_IN_CNT(p) \ + (((p) & ODD_GROUP_PKT_IN_CN_MASK) >> ODD_GROUP_PKT_IN_CN_OFFSET) +#define EVEN_GROUP_ASK_CN_MASK (0xff << 0) +#define EVEN_GROUP_ASK_CN_OFFSET 0 +#define GET_EVEN_GROUP_ASK_CNT(p) \ + (((p) & EVEN_GROUP_ASK_CN_MASK) >> EVEN_GROUP_ASK_CN_OFFSET) +#define EVEN_GROUP_PKT_IN_CN_MASK (0xff << 8) +#define EVEN_GROUP_PKT_IN_CN_OFFSET 8 +#define GET_EVEN_GROUP_PKT_IN_CNT(p) \ + (((p) & EVEN_GROUP_PKT_IN_CN_MASK) >> EVEN_GROUP_PKT_IN_CN_OFFSET) + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +#if defined(_HIF_PCIE) || defined(_HIF_AXI) +/* DMASHDL_REFILL_CONTROL */ +union _DMASHDL_REFILL_CONTROL { + struct { + uint32_t PRIORITY:16; + uint32_t DISABLE:16; + } field; + + uint32_t word; +}; + +/* DMASHDL_PACKET_MAX_SIZE */ +union _DMASHDL_PACKET_MAX_SIZE { + struct { + uint32_t PLE_SIZE:12; + uint32_t RSV_12_15:4; + uint32_t PSE_SIZE:12; + uint32_t RSV_28_31:4; + } field; + + uint32_t word; +}; + +/* DMASHDL_GROUP_CONTROL */ +union _DMASHDL_GROUP_CONTROL { + struct { + uint32_t MIN_QUOTAE:12; + uint32_t RSV_12_15:4; + uint32_t MAX_QUOTAE:12; + uint32_t RSV_28_31:4; + } field; + + uint32_t word; +}; +#endif /* _HIF_PCIE */ + +/* Group index */ +enum _ENUM_GROUP_INDEX_T { + GROUP0_INDEX = 0, + GROUP1_INDEX, + GROUP2_INDEX, + GROUP3_INDEX, + GROUP4_INDEX, + GROUP5_INDEX, + GROUP6_INDEX, + GROUP7_INDEX, + GROUP8_INDEX, + GROUP9_INDEX, + GROUP10_INDEX, + GROUP11_INDEX, + GROUP12_INDEX, + GROUP13_INDEX, + GROUP14_INDEX, + GROUP15_INDEX, + MAX_GROUP_NUM +}; + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/connac_reg.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/connac_reg.h new file mode 100644 index 0000000000000000000000000000000000000000..e14c09daef1f842d82db52ecb72e6fb859d5de78 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/connac_reg.h @@ -0,0 +1,270 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/*! \file "connac_reg.h" + * \brief The common register definition of MT6630 + * + * N/A + */ + + + +#ifndef _CONNAC_REG_H +#define _CONNAC_REG_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#define CONN_CFG_BASE 0x80020000 + +#define CONN_CFG_ON_BASE 0x81021000 + +#define CONN_CFG_ON_CONN_ON_MISC_ADDR (CONN_CFG_ON_BASE + 0x140) +#define CONN_CFG_CHIP_ID_ADDR (CONN_CFG_BASE + 0x1010) + +#define CONN_MCU_CONFG_ON_BASE 0x81030000 + +#define CONN_MCU_CONFG_ON_HOST_MAILBOX_WF_ADDR \ + (CONN_MCU_CONFG_ON_BASE + 0x100) + +/* + * ============================================================================ + * + * ---CONN_ON_MISC (0x81021000 + 0x140)--- + * + * HOST_LPCR_FW_OWN[0] - (W1C) xxx + * DRV_FM_STAT_SYNC[3..1] - (RW) xxx + * RBIST_MODE[4] - (RW) xxx + * RESERVED5[31..5] - (RO) Reserved bits + * + * ============================================================================ + */ +#define CONN_CFG_ON_CONN_ON_MISC_RBIST_MODE_ADDR \ + CONN_CFG_ON_CONN_ON_MISC_ADDR +#define CONN_CFG_ON_CONN_ON_MISC_RBIST_MODE_MASK \ + 0x00000010/*RBIST_MODE[4]*/ +#define CONN_CFG_ON_CONN_ON_MISC_RBIST_MODE_SHFT 4 +#define CONN_CFG_ON_CONN_ON_MISC_DRV_FM_STAT_SYNC_ADDR \ + CONN_CFG_ON_CONN_ON_MISC_ADDR +#define CONN_CFG_ON_CONN_ON_MISC_DRV_FM_STAT_SYNC_MASK \ + 0x0000000E/*DRV_FM_STAT_SYNC[3..1]*/ +#define CONN_CFG_ON_CONN_ON_MISC_DRV_FM_STAT_SYNC_SHFT 1 +#define CONN_CFG_ON_CONN_ON_MISC_HOST_LPCR_FW_OWN_ADDR \ + CONN_CFG_ON_CONN_ON_MISC_ADDR +#define CONN_CFG_ON_CONN_ON_MISC_HOST_LPCR_FW_OWN_MASK \ + 0x00000001/*HOST_LPCR_FW_OWN[0]*/ +#define CONN_CFG_ON_CONN_ON_MISC_HOST_LPCR_FW_OWN_SHFT 0 + +#define CONN_HIF_BASE 0x7000 +#define CONN_HIF_ON_LPCTL (CONN_HIF_BASE) +#define CONN_HIF_ON_IRQ_STAT (CONN_HIF_BASE + 0x4) +#define CONN_HIF_ON_IRQ_ENA (CONN_HIF_BASE + 0x8) +#define CONN_HIF_ON_DBGCR01 (CONN_HIF_BASE + 0x104) + +#if defined(_HIF_PCIE) || defined(_HIF_AXI) + +/* MCU Interrupt Event */ +#define HOST2MCU_SW_INT_SET (PCIE_HIF_BASE + 0x0108) + +/* MCU2HOST Software interrupt set */ +#define MCU2HOST_SW_INT_SET (PCIE_HIF_BASE + 0x010C) + +/* MCU to Host interrupt status */ +#define MCU2HOST_SW_INT_STA (PCIE_HIF_BASE + 0x01F0) + +/* MCU to Host interrupt enable */ +#define MCU2HOST_SW_INT_ENA (PCIE_HIF_BASE + 0x01F4) + +#define WPDMA_PAUSE_TX_Q (PCIE_HIF_BASE + 0x0224) + +/* Configuraiton Push */ +#define PCIE_DOORBELL_PUSH (0x484) +#define CR_PCIE_CFG_SET_OWN (0x1 << 0) +#define CR_PCIE_CFG_CLEAR_OWN (0x1 << 1) +#endif /* _HIF_PCIE */ + +#if defined(_HIF_USB) +#define CONNAC_UDMA_BASE 0x7C000000 +#define CONNAC_UDMA_TX_QSEL (CONNAC_UDMA_BASE + 0x8) +#define CONNAC_UDMA_RESET (CONNAC_UDMA_BASE + 0x14) +#define CONNAC_UDMA_WLCFG_1 (CONNAC_UDMA_BASE + 0xc) +#define CONNAC_UDMA_WLCFG_0 (CONNAC_UDMA_BASE + 0x18) + +#define UDMA_WLCFG_0_TX_BUSY_MASK (0x1 << 31) +#define UDMA_WLCFG_0_1US_TIMER_EN_MASK (0x1 << 20) +#define UDMA_WLCFG_0_1US_TIMER_EN(p) (((p) & 0x1) << 20) +#define UDMA_WLCFG_0_RX_FLUSH_MASK (0x1 << 19) +#define UDMA_WLCFG_0_TX_TIMEOUT_EN_MASK (0x1 << 16) + +#define UDMA_WLCFG_1_TX_TIMEOUT_LIMIT_MASK (0xFFFFF << 8) +#define UDMA_WLCFG_1_TX_TIMEOUT_LIMIT(p) (((p) & 0xFFFFF) << 8) +#define UDMA_TX_TIMEOUT_STATUS_MASK (0x1 << 13) + +#define UDMA_TX_TIMEOUT_LIMIT (50000) + +#define UDMA_TX_IDLE_MASK 0x00003f00 + +#define PDMA_IF_MISC 0x500000a8 +#define PDMA_IF_MISC_TX_ENABLE_MASK 0x00000001 + +#define PDMA_HIF_RESET 0x50000100 +#define DPMA_HIF_LOGIC_RESET_MASK (0x1 << 4) + +#define PDMA_DEBUG_EN 0x50000124 +#define PDMA_DEBUG_STATUS 0x50000128 +#define PDMA_DEBUG_TX_STATUS_MASK 0x004c0000 /* 0x00400000 */ +#define PDMA_DEBUG_DMASHDL_REQUEST_DONE_MASK 0x00100000 + +#define PDMA_BUSY_STATUS 0x50000168 +#define PDMA_TX_BUSY_MASK 0x00000001 + +#define PDMA_TX_IDLE_WAIT_COUNT 30 +#endif /* _HIF_USB */ + +#if defined(_HIF_PCIE) || defined(_HIF_AXI) +#define PDMA_DEBUG_EN 0x50000124 +#define PDMA_DEBUG_STATUS 0x50000128 +#define AXI_DEBUG_DEBUG_EN 0x5000012C +#define CONN_HIF_DEBUG_STATUS 0x50000130 +#define PDMA_DEBUG_HIF_BUSY_STATUS 0x50000138 +#define PDMA_DEBUG_BUSY_STATUS 0x50000168 +#define PDMA_DEBUG_REFill 0x5000A010 + +#define PDMA_AXI_DEBUG_FLAG 0x2222 +#define GALS_AXI_DEBUG_FLAG 0x3333 +#define MCU_AXI_DEBUG_FLAG 0x4444 +#define RBUS_DEBUG_FLAG 0x118 + +#define WPDMA_PAUSE_TX_Q_RINGIDX_OFFSET 16 +#define WPDMA_PAUSE_TX_Q_RINGIDX_MASK 0xFFFF0000 +#endif /* _HIF_PCIE */ + + +#define PLE_PKT_MAX_SIZE_MASK (0xfff << 0) +#define PLE_PKT_MAX_SIZE_NUM(p) (((p) & 0xfff) << 0) +#define GET_PLE_PKT_MAX_SIZE_NUM(p) (((p) & PLE_PKT_MAX_SIZE_MASK) >> 0) + +#define PSE_PKT_MAX_SIZE_MASK (0xfff << 16) +#define PSE_PKT_MAX_SIZE_NUM(p) (((p) & 0xfff) << 16) +#define GET_PSE_PKT_MAX_SIZE_NUM(p) (((p) & PSE_PKT_MAX_SIZE_MASK) >> 16) + +#define EXTRA_TXD_SIZE_FOR_TX_BYTE_COUNT 32 + +#define MCU_INT_PDMA0_STOP_DONE BIT(0) +#define MCU_INT_PDMA0_INIT_DONE BIT(1) +#define MCU_INT_SER_TRIGGER_FROM_HOST BIT(2) +#define MCU_INT_PDMA0_RECOVERY_DONE BIT(3) +#define MCU_INT_DRIVER_SER BIT(4) +#define MCU_INT_NOTIFY_MD_CRASH BIT(5) +#define CONNAC_MCU_SW_INT BIT(29) + +#define ERROR_DETECT_STOP_PDMA_WITH_FW_RELOAD BIT(1) +#define ERROR_DETECT_STOP_PDMA BIT(2) +#define ERROR_DETECT_RESET_DONE BIT(3) +#define ERROR_DETECT_RECOVERY_DONE BIT(4) +#define ERROR_DETECT_MCU_NORMAL_STATE BIT(5) +#define CP_LMAC_HANG_WORKAROUND_STEP1 BIT(8) +#define CP_LMAC_HANG_WORKAROUND_STEP2 BIT(9) +#define ERROR_DETECT_LMAC_ERROR BIT(24) +#define ERROR_DETECT_PSE_ERROR BIT(25) +#define ERROR_DETECT_PLE_ERROR BIT(26) +#define ERROR_DETECT_PDMA_ERROR BIT(27) +#define ERROR_DETECT_PCIE_ERROR BIT(28) + +#define ERROR_DETECT_MASK \ + (ERROR_DETECT_STOP_PDMA \ + | ERROR_DETECT_RESET_DONE \ + | ERROR_DETECT_RECOVERY_DONE \ + | ERROR_DETECT_MCU_NORMAL_STATE) + + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/hal.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/hal.h new file mode 100644 index 0000000000000000000000000000000000000000..df083136a7031e63be4e1a5195bdeea0c78edf3d --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/hal.h @@ -0,0 +1,1232 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/*! \file "hal.h" + * \brief The declaration of hal functions + * + * N/A + */ + + +#ifndef _HAL_H +#define _HAL_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#define WIFI_SER_SYNC_TIMER_TIMEOUT_IN_MS (100) + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +enum ERR_RECOVERY_STATE { + ERR_RECOV_STOP_IDLE = 0, + ERR_RECOV_STOP_PDMA0, + ERR_RECOV_RESET_PDMA0, + ERR_RECOV_WAIT_MCU_NORMAL, + ERR_RECOV_STATE_NUM +}; + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ +#if defined(_HIF_USB) +extern struct TIMER rSerSyncTimer; +#endif + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/* Macros for flag operations for the Adapter structure */ +#define HAL_SET_FLAG(_M, _F) ((_M)->u4HwFlags |= (_F)) +#define HAL_CLEAR_FLAG(_M, _F) ((_M)->u4HwFlags &= ~(_F)) +#define HAL_TEST_FLAG(_M, _F) ((_M)->u4HwFlags & (_F)) +#define HAL_TEST_FLAGS(_M, _F) (((_M)->u4HwFlags & (_F)) == (_F)) + +#if CFG_SUPPORT_SNIFFER +#define HAL_MON_EN(_prAdapter) (_prAdapter->prGlueInfo->fgIsEnableMon) +#else +#define HAL_MON_EN(_prAdapter) FALSE +#endif + +#if defined(_HIF_SDIO) +#define HAL_MCR_RD(_prAdapter, _u4Offset, _pu4Value) \ +do { \ + if (HAL_TEST_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { \ + if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ + ASSERT(0); \ + } \ + if (_u4Offset > 0xFFFF) { \ + if (kalDevRegRead_mac(_prAdapter->prGlueInfo, \ + _u4Offset, _pu4Value) == FALSE) {\ + HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \ + fgIsBusAccessFailed = TRUE; \ + DBGLOG(HAL, ERROR, \ + "HAL_MCR_RD (MAC) access fail! 0x%x: 0x%x\n", \ + (uint32_t) (_u4Offset), \ + *((uint32_t *) (_pu4Value))); \ + } \ + } else { \ + if (kalDevRegRead(_prAdapter->prGlueInfo, \ + _u4Offset, _pu4Value) == FALSE) {\ + HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \ + fgIsBusAccessFailed = TRUE; \ + DBGLOG(HAL, ERROR, \ + "HAL_MCR_RD (SDIO) access fail! 0x%x: 0x%x\n", \ + (uint32_t) (_u4Offset), \ + *((uint32_t *) (_pu4Value))); \ + } \ + } \ + } else { \ + DBGLOG(HAL, WARN, "ignore HAL_MCR_RD access! 0x%x\n", \ + (uint32_t) (_u4Offset)); \ + } \ +} while (0) + +#define HAL_MCR_WR(_prAdapter, _u4Offset, _u4Value) \ +do { \ + if (HAL_TEST_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { \ + if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ + ASSERT(0); \ + } \ + if (_u4Offset > 0xFFFF) { \ + if (kalDevRegWrite_mac(_prAdapter->prGlueInfo, \ + _u4Offset, _u4Value) == FALSE) {\ + HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \ + fgIsBusAccessFailed = TRUE; \ + DBGLOG(HAL, ERROR, \ + "HAL_MCR_WR (MAC) access fail! 0x%x: 0x%x\n", \ + (uint32_t) (_u4Offset), \ + (uint32_t) (_u4Value)); \ + } \ + } else { \ + if (kalDevRegWrite(_prAdapter->prGlueInfo, \ + _u4Offset, _u4Value) == FALSE) {\ + HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \ + fgIsBusAccessFailed = TRUE; \ + DBGLOG(HAL, ERROR, \ + "HAL_MCR_WR (SDIO) access fail! 0x%x: 0x%x\n", \ + (uint32_t) (_u4Offset), \ + (uint32_t) (_u4Value)); \ + } \ + } \ + } else { \ + DBGLOG(HAL, WARN, "ignore HAL_MCR_WR access! 0x%x: 0x%x\n", \ + (uint32_t) (_u4Offset), (uint32_t) (_u4Value)); \ + } \ +} while (0) + +#define HAL_PORT_RD(_prAdapter, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ +{ \ + /*fgResult = FALSE; */\ + if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ + ASSERT(0); \ + } \ + if (HAL_TEST_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { \ + if (kalDevPortRead(_prAdapter->prGlueInfo, _u4Port, _u4Len, \ + _pucBuf, _u4ValidBufSize) == FALSE) {\ + HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \ + fgIsBusAccessFailed = TRUE; \ + DBGLOG(HAL, ERROR, "HAL_PORT_RD access fail! 0x%x\n", \ + (uint32_t) (_u4Port)); \ + } \ + else { \ + /*fgResult = TRUE;*/ } \ + } else { \ + DBGLOG(HAL, WARN, "ignore HAL_PORT_RD access! 0x%x\n", \ + (uint32_t) (_u4Port)); \ + } \ +} + +#define HAL_PORT_WR(_prAdapter, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ +{ \ + /*fgResult = FALSE; */\ + if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ + ASSERT(0); \ + } \ + if (HAL_TEST_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { \ + if (kalDevPortWrite(_prAdapter->prGlueInfo, _u4Port, \ + _u4Len, _pucBuf, _u4ValidBufSize) == FALSE) {\ + HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \ + fgIsBusAccessFailed = TRUE; \ + DBGLOG(HAL, ERROR, "HAL_PORT_WR access fail! 0x%x\n", \ + (uint32_t) (_u4Port)); \ + } \ + else \ + ; /*fgResult = TRUE;*/ \ + } else { \ + DBGLOG(HAL, WARN, "ignore HAL_PORT_WR access! 0x%x\n", \ + (uint32_t) (_u4Port)); \ + } \ +} + +#define HAL_BYTE_WR(_prAdapter, _u4Port, _ucBuf) \ +{ \ + if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ + ASSERT(0); \ + } \ + if (HAL_TEST_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { \ + if (kalDevWriteWithSdioCmd52(_prAdapter->prGlueInfo, \ + _u4Port, _ucBuf) == FALSE) {\ + HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \ + fgIsBusAccessFailed = TRUE; \ + DBGLOG(HAL, ERROR, "HAL_BYTE_WR access fail! 0x%x\n", \ + (uint32_t)(_u4Port)); \ + } \ + else { \ + /* Todo:: Nothing*/ \ + } \ + } \ + else { \ + DBGLOG(HAL, WARN, "ignore HAL_BYTE_WR access! 0x%x\n", \ + (uint32_t) (_u4Port)); \ + } \ +} + +#define HAL_DRIVER_OWN_BY_SDIO_CMD52(_prAdapter, _pfgDriverIsOwnReady) \ +{ \ + uint8_t ucBuf = BIT(1); \ + if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ + ASSERT(0); \ + } \ + if (HAL_TEST_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { \ + if (kalDevReadAfterWriteWithSdioCmd52(_prAdapter->prGlueInfo, \ + MCR_WHLPCR_BYTE1, &ucBuf, 1) == FALSE) {\ + HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \ + fgIsBusAccessFailed = TRUE; \ + DBGLOG(HAL, ERROR, \ + "kalDevReadAfterWriteWithSdioCmd52 access fail!\n"); \ + } \ + else { \ + *_pfgDriverIsOwnReady = (ucBuf & BIT(0)) \ + ? TRUE : FALSE; \ + } \ + } else { \ + DBGLOG(HAL, WARN, \ + "ignore HAL_DRIVER_OWN_BY_SDIO_CMD52 access!\n"); \ + } \ +} + +#else /* #if defined(_HIF_SDIO) */ +#define HAL_MCR_RD(_prAdapter, _u4Offset, _pu4Value) \ +{ \ + if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ + ASSERT(0); \ + } \ + kalDevRegRead(_prAdapter->prGlueInfo, _u4Offset, _pu4Value); \ +} + +#define HAL_MCR_WR(_prAdapter, _u4Offset, _u4Value) \ +{ \ + if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ + ASSERT(0); \ + } \ + kalDevRegWrite(_prAdapter->prGlueInfo, _u4Offset, _u4Value); \ +} + +#define HAL_PORT_RD(_prAdapter, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ +{ \ + if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ + ASSERT(0); \ + } \ + kalDevPortRead(_prAdapter->prGlueInfo, _u4Port, \ + _u4Len, _pucBuf, _u4ValidBufSize); \ +} + +#define HAL_PORT_WR(_prAdapter, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ +{ \ + if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ + ASSERT(0); \ + } \ + kalDevPortWrite(_prAdapter->prGlueInfo, _u4Port, \ + _u4Len, _pucBuf, _u4ValidBufSize); \ +} + +#define HAL_BYTE_WR(_prAdapter, _u4Port, _ucBuf) \ +{ \ + HAL_MCR_WR(_prAdapter, _u4Port, (uint32_t)_ucBuf); \ +} + +#endif /* #if defined(_HIF_SDIO) */ + +#define HAL_WRITE_TX_DATA(_prAdapter, _prMsduInfo) \ +{ \ + if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ + ASSERT(0); \ + } \ + kalDevWriteData(_prAdapter->prGlueInfo, _prMsduInfo); \ +} + +#define HAL_KICK_TX_DATA(_prAdapter) \ +{ \ + if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ + ASSERT(0); \ + } \ + kalDevKickData(_prAdapter->prGlueInfo); \ +} + +#define HAL_WRITE_TX_CMD(_prAdapter, _prCmdInfo, _ucTC) \ +{ \ + enum ENUM_CMD_TX_RESULT ret; \ + if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ + ASSERT(0); \ + } \ + ret = kalDevWriteCmd(_prAdapter->prGlueInfo, _prCmdInfo, _ucTC); \ + if (ret == CMD_TX_RESULT_SUCCESS) { \ + if (_prCmdInfo && _prCmdInfo->pfHifTxCmdDoneCb) \ + _prCmdInfo->pfHifTxCmdDoneCb(_prAdapter, _prCmdInfo); \ + } \ +} + +#if defined(_HIF_PCIE) || defined(_HIF_AXI) +#define HAL_READ_RX_PORT(prAdapter, u4PortId, u4Len, pvBuf, _u4ValidBufSize) \ +{ \ + ASSERT(u4PortId < 2); \ + HAL_PORT_RD(prAdapter, \ + u4PortId, \ + u4Len, \ + pvBuf, \ + _u4ValidBufSize/*temp!!*//*4Kbyte*/) \ +} + +#define HAL_WRITE_TX_PORT(_prAdapter, _u4PortId, _u4Len, _pucBuf, _u4BufSize) \ +{ \ + HAL_PORT_WR(_prAdapter, \ + _u4PortId, \ + _u4Len, \ + _pucBuf, \ + _u4BufSize/*temp!!*//*4KByte*/) \ +} + +#define HAL_MCR_RD_AND_WAIT(_pAdapter, _offset, _pReadValue, \ + _waitCondition, _waitDelay, _waitCount, _status) + +#define HAL_MCR_WR_AND_WAIT(_pAdapter, _offset, _writeValue, \ + _busyMask, _waitDelay, _waitCount, _status) + +#define HAL_GET_CHIP_ID_VER(_prAdapter, pu2ChipId, pu2Version) \ +{ \ + uint32_t u4Value = 0; \ + HAL_MCR_RD(_prAdapter, HIF_SYS_REV, &u4Value); \ + *pu2ChipId = ((u4Value & PCIE_HIF_SYS_PROJ) >> 16); \ + *pu2Version = (u4Value & PCIE_HIF_SYS_REV); \ +} + +#define HAL_WIFI_FUNC_READY_CHECK(_prAdapter, _checkItem, _pfgResult) \ +do { \ + struct mt66xx_chip_info *prChipInfo = NULL; \ + uint32_t u4Value = 0; \ + if (!_prAdapter->chip_info) \ + ASSERT(0); \ + *_pfgResult = FALSE; \ + prChipInfo = _prAdapter->chip_info; \ + HAL_MCR_RD(_prAdapter, prChipInfo->sw_sync0, &u4Value); \ + if ((u4Value & (_checkItem << prChipInfo->sw_ready_bit_offset)) \ + == (_checkItem << prChipInfo->sw_ready_bit_offset)) \ + *_pfgResult = TRUE; \ +} while (0) + +#define HAL_WIFI_FUNC_OFF_CHECK(_prAdapter, _checkItem, _pfgResult) \ +do { \ + u_int8_t fgLpOwnResult; \ + HAL_WIFI_FUNC_READY_CHECK(_prAdapter, _checkItem, _pfgResult); \ + if (*_pfgResult) { \ + HAL_LP_OWN_RD(_prAdapter, &fgLpOwnResult); \ + if (fgLpOwnResult == FALSE) { \ + DBGLOG(INIT, INFO, \ + "HAL_LP_OWN_RD %d\n", fgLpOwnResult); \ + HAL_LP_OWN_SET(prAdapter, &fgLpOwnResult); \ + DBGLOG(INIT, INFO, \ + "HAL_LP_OWN_SET %d\n", fgLpOwnResult); \ + } \ + } \ + *_pfgResult = !*_pfgResult; \ +} while (0) + +#define HAL_WIFI_FUNC_GET_STATUS(_prAdapter, _u4Result) \ +do { \ + struct mt66xx_chip_info *prChipInfo = NULL; \ + struct BUS_INFO *prBusInfo = NULL; \ + uint32_t u4Value = 0; \ + if (!_prAdapter->chip_info || !_prAdapter->chip_info->bus_info) \ + ASSERT(0); \ + prChipInfo = _prAdapter->chip_info; \ + prBusInfo = prChipInfo->bus_info; \ + HAL_MCR_RD(_prAdapter, prChipInfo->sw_sync0, &_u4Result); \ + if (prBusInfo->getMailboxStatus) { \ + prBusInfo->getMailboxStatus(_prAdapter, &u4Value); \ + DBGLOG(INIT, INFO, "Mailbox: 0x%x\n", u4Value); \ + } \ +} while (0) + +#define HAL_INTR_DISABLE(_prAdapter) + +#define HAL_INTR_ENABLE(_prAdapter) + +#define HAL_INTR_ENABLE_AND_LP_OWN_SET(_prAdapter) + +/* Polling interrupt status bit due to CFG_PCIE_LPCR_HOST + * status bit not work when chip sleep + */ +#define HAL_LP_OWN_RD(_prAdapter, _pfgResult) \ +do { \ + struct mt66xx_chip_info *prChipInfo = NULL; \ + struct BUS_INFO *prBusInfo = NULL; \ + if (!_prAdapter->chip_info || !_prAdapter->chip_info->bus_info) \ + ASSERT(0); \ + prChipInfo = _prAdapter->chip_info; \ + prBusInfo = prChipInfo->bus_info; \ + prBusInfo->lowPowerOwnRead(_prAdapter, _pfgResult); \ +} while (0) + +#define HAL_LP_OWN_SET(_prAdapter, _pfgResult) \ +do { \ + struct mt66xx_chip_info *prChipInfo = NULL; \ + struct BUS_INFO *prBusInfo = NULL; \ + if (!_prAdapter->chip_info || !_prAdapter->chip_info->bus_info) \ + ASSERT(0); \ + prChipInfo = _prAdapter->chip_info; \ + prBusInfo = prChipInfo->bus_info; \ + prBusInfo->lowPowerOwnSet(_prAdapter, _pfgResult); \ +} while (0) + +#define HAL_LP_OWN_CLR(_prAdapter, _pfgResult) \ +do { \ + struct mt66xx_chip_info *prChipInfo = NULL; \ + struct BUS_INFO *prBusInfo = NULL; \ + if (!_prAdapter->chip_info || !_prAdapter->chip_info->bus_info) \ + ASSERT(0); \ + prChipInfo = _prAdapter->chip_info; \ + prBusInfo = prChipInfo->bus_info; \ + prBusInfo->lowPowerOwnClear(_prAdapter, _pfgResult); \ +} while (0) + +#define HAL_GET_ABNORMAL_INTERRUPT_REASON_CODE(_prAdapter, pu4AbnormalReason) + +#define HAL_DISABLE_RX_ENHANCE_MODE(_prAdapter) + +#define HAL_ENABLE_RX_ENHANCE_MODE(_prAdapter) + +#define HAL_CFG_MAX_HIF_RX_LEN_NUM(_prAdapter, _ucNumOfRxLen) + +#define HAL_SET_INTR_STATUS_READ_CLEAR(prAdapter) + +#define HAL_SET_INTR_STATUS_WRITE_1_CLEAR(prAdapter) + +#define HAL_READ_INTR_STATUS(prAdapter, length, pvBuf) + +#define HAL_READ_TX_RELEASED_COUNT(_prAdapter, au2TxReleaseCount) + +#define HAL_READ_RX_LENGTH(prAdapter, pu2Rx0Len, pu2Rx1Len) + +#define HAL_GET_INTR_STATUS_FROM_ENHANCE_MODE_STRUCT(pvBuf, u2Len, pu4Status) + +#define HAL_GET_TX_STATUS_FROM_ENHANCE_MODE_STRUCT(pvInBuf, \ + pu4BufOut, u4LenBufOut) + +#define HAL_GET_RX_LENGTH_FROM_ENHANCE_MODE_STRUCT(pvInBuf, \ + pu2Rx0Num, au2Rx0Len, pu2Rx1Num, au2Rx1Len) + +#define HAL_GET_MAILBOX_FROM_ENHANCE_MODE_STRUCT(pvInBuf, \ + pu4Mailbox0, pu4Mailbox1) + +#define HAL_IS_TX_DONE_INTR(u4IntrStatus) \ + ((u4IntrStatus & (WPDMA_TX_DONE_INT0 | \ + WPDMA_TX_DONE_INT1 | WPDMA_TX_DONE_INT2 | WPDMA_TX_DONE_INT3 | \ + WPDMA_TX_DONE_INT15)) ? TRUE : FALSE) + +#define HAL_IS_RX_DONE_INTR(u4IntrStatus) \ + ((u4IntrStatus & (WPDMA_RX_DONE_INT0 | WPDMA_RX_DONE_INT1)) \ + ? TRUE : FALSE) + +#define HAL_IS_ABNORMAL_INTR(u4IntrStatus) + +#define HAL_IS_FW_OWNBACK_INTR(u4IntrStatus) + +#define HAL_PUT_MAILBOX(prAdapter, u4MboxId, u4Data) + +#define HAL_GET_MAILBOX(prAdapter, u4MboxId, pu4Data) + +#define HAL_SET_MAILBOX_READ_CLEAR(prAdapter, fgEnableReadClear) \ +{ \ + prAdapter->prGlueInfo->rHifInfo.fgMbxReadClear = fgEnableReadClear;\ +} + +#define HAL_GET_MAILBOX_READ_CLEAR(prAdapter) \ + (prAdapter->prGlueInfo->rHifInfo.fgMbxReadClear) + +#define HAL_READ_INT_STATUS(_prAdapter, _pu4IntStatus) \ +{ \ + struct BUS_INFO *prBusInfo; \ + prBusInfo = _prAdapter->chip_info->bus_info; \ + if (prBusInfo->devReadIntStatus) \ + prBusInfo->devReadIntStatus(_prAdapter, _pu4IntStatus); \ + else \ + kalDevReadIntStatus(_prAdapter, _pu4IntStatus);\ + if (_prAdapter->u4NoMoreRfb != 0) \ + *_pu4IntStatus |= WHISR_RX0_DONE_INT; \ +} + +#define HAL_HIF_INIT(prAdapter) + +#define HAL_ENABLE_FWDL(_prAdapter, _fgEnable) \ +{ \ + halEnableFWDownload(_prAdapter, _fgEnable); \ +} + +#define HAL_WAKE_UP_WIFI(_prAdapter) \ +{ \ + halWakeUpWiFi(_prAdapter);\ +} + +#define HAL_CLEAR_DUMMY_REQ(_prAdapter) \ +{ \ + struct mt66xx_chip_info *prChipInfo = NULL; \ + uint32_t u4Value = 0; \ + if (!_prAdapter->chip_info) {\ + ASSERT(0); \ + } else {\ + prChipInfo = _prAdapter->chip_info; \ + HAL_MCR_RD(_prAdapter, prChipInfo->sw_sync0, &u4Value); \ + u4Value &= ~(WIFI_FUNC_DUMMY_REQ << \ + prChipInfo->sw_ready_bit_offset);\ + HAL_MCR_WR(prAdapter, prChipInfo->sw_sync0, u4Value);\ + } \ +} + +#define HAL_IS_TX_DIRECT(_prAdapter) FALSE + +#define HAL_IS_RX_DIRECT(_prAdapter) FALSE + +#endif + +#if defined(_HIF_SDIO) +#define HIF_H2D_SW_INT_SHFT (16) +/* bit16 */ +#define SDIO_MAILBOX_FUNC_READ_REG_IDX (BIT(0) << HIF_H2D_SW_INT_SHFT) +/* bit17 */ +#define SDIO_MAILBOX_FUNC_WRITE_REG_IDX (BIT(1) << HIF_H2D_SW_INT_SHFT) +/* bit18 */ +#define SDIO_MAILBOX_FUNC_CHECKSUN16_IDX (BIT(2) << HIF_H2D_SW_INT_SHFT) + +#define HAL_READ_RX_PORT(prAdapter, u4PortId, u4Len, pvBuf, _u4ValidBufSize) \ +{ \ + ASSERT(u4PortId < 2); \ + HAL_PORT_RD(prAdapter, \ + ((u4PortId == 0) ? MCR_WRDR0 : MCR_WRDR1), \ + u4Len, \ + pvBuf, \ + _u4ValidBufSize/*temp!!*//*4Kbyte*/) \ +} + +#define HAL_WRITE_TX_PORT(_prAdapter, _u4PortId, _u4Len, _pucBuf, _u4BufSize) \ +{ \ + if ((_u4BufSize - _u4Len) >= sizeof(uint32_t)) { \ + /* fill with single dword of zero as TX-aggregation end */ \ + *(uint32_t *) (&((_pucBuf)[ALIGN_4(_u4Len)])) = 0; \ + } \ + HAL_PORT_WR(_prAdapter, \ + MCR_WTDR1, \ + _u4Len, \ + _pucBuf, \ + _u4BufSize/*temp!!*//*4KByte*/) \ +} + +/* The macro to read the given MCR several times to check if the wait + * condition come true. + */ +#define HAL_MCR_RD_AND_WAIT(_pAdapter, _offset, _pReadValue, \ + _waitCondition, _waitDelay, _waitCount, _status) \ + { \ + uint32_t count = 0; \ + (_status) = FALSE; \ + for (count = 0; count < (_waitCount); count++) { \ + HAL_MCR_RD((_pAdapter), (_offset), (_pReadValue)); \ + if ((_waitCondition)) { \ + (_status) = TRUE; \ + break; \ + } \ + kalUdelay((_waitDelay)); \ + } \ + } + +/* The macro to write 1 to a R/S bit and read it several times to check if the + * command is done + */ +#define HAL_MCR_WR_AND_WAIT(_pAdapter, _offset, _writeValue, _busyMask, \ + _waitDelay, _waitCount, _status) \ + { \ + uint32_t u4Temp = 0; \ + uint32_t u4Count = _waitCount; \ + (_status) = FALSE; \ + HAL_MCR_WR((_pAdapter), (_offset), (_writeValue)); \ + do { \ + kalUdelay((_waitDelay)); \ + HAL_MCR_RD((_pAdapter), (_offset), &u4Temp); \ + if (!(u4Temp & (_busyMask))) { \ + (_status) = TRUE; \ + break; \ + } \ + u4Count--; \ + } while (u4Count); \ + } + +#define HAL_GET_CHIP_ID_VER(_prAdapter, pu2ChipId, pu2Version) \ +{ \ + uint32_t u4Value = 0; \ + HAL_MCR_RD(_prAdapter, \ + MCR_WCIR, \ + &u4Value); \ + *pu2ChipId = (uint16_t)(u4Value & WCIR_CHIP_ID); \ + *pu2Version = (uint16_t)(u4Value & WCIR_REVISION_ID) >> 16; \ +} + +#define HAL_WIFI_FUNC_READY_CHECK(_prAdapter, _checkItem, _pfgResult) \ +do { \ + uint32_t u4Value = 0; \ + *_pfgResult = FALSE; \ + HAL_MCR_RD(_prAdapter, \ + MCR_WCIR, \ + &u4Value); \ + if (u4Value & WCIR_WLAN_READY) { \ + *_pfgResult = TRUE; \ + } \ +} while (0) + +#define HAL_WIFI_FUNC_OFF_CHECK(_prAdapter, _checkItem, _pfgResult) \ +do { \ + uint32_t u4Value = 0; \ + *_pfgResult = FALSE; \ + HAL_MCR_RD(_prAdapter, MCR_WCIR, &u4Value); \ + if ((u4Value & WCIR_WLAN_READY) == 0) { \ + *_pfgResult = TRUE; \ + } \ + halPrintMailbox(_prAdapter);\ + halPollDbgCr(_prAdapter, LP_DBGCR_POLL_ROUND); \ +} while (0) + +#define HAL_WIFI_FUNC_GET_STATUS(_prAdapter, _u4Result) \ + halGetMailbox(_prAdapter, 0, &_u4Result) + +#define HAL_INTR_DISABLE(_prAdapter) \ + HAL_MCR_WR(_prAdapter, \ + MCR_WHLPCR, \ + WHLPCR_INT_EN_CLR) + +#define HAL_INTR_ENABLE(_prAdapter) \ + HAL_MCR_WR(_prAdapter, \ + MCR_WHLPCR, \ + WHLPCR_INT_EN_SET) + +#define HAL_INTR_ENABLE_AND_LP_OWN_SET(_prAdapter) \ + HAL_MCR_WR(_prAdapter, \ + MCR_WHLPCR, \ + (WHLPCR_INT_EN_SET | WHLPCR_FW_OWN_REQ_SET)) + +#define HAL_LP_OWN_RD(_prAdapter, _pfgResult) \ +{ \ + uint32_t u4RegValue = 0; \ + *_pfgResult = FALSE; \ + HAL_MCR_RD(_prAdapter, MCR_WHLPCR, &u4RegValue); \ + if (u4RegValue & WHLPCR_IS_DRIVER_OWN) { \ + *_pfgResult = TRUE; \ + } \ +} + +#define HAL_LP_OWN_SET(_prAdapter, _pfgResult) \ +{ \ + uint32_t u4RegValue = 0; \ + *_pfgResult = FALSE; \ + HAL_MCR_WR(_prAdapter, \ + MCR_WHLPCR, \ + WHLPCR_FW_OWN_REQ_SET); \ + HAL_MCR_RD(_prAdapter, MCR_WHLPCR, &u4RegValue); \ + if (u4RegValue & WHLPCR_IS_DRIVER_OWN) { \ + *_pfgResult = TRUE; \ + } \ +} + +#define HAL_LP_OWN_CLR(_prAdapter, _pfgResult) \ +{ \ + uint32_t u4RegValue = 0; \ + *_pfgResult = FALSE; \ + /* Software get LP ownership */ \ + HAL_MCR_WR(_prAdapter, \ + MCR_WHLPCR, \ + WHLPCR_FW_OWN_REQ_CLR); \ + HAL_MCR_RD(_prAdapter, MCR_WHLPCR, &u4RegValue); \ + if (u4RegValue & WHLPCR_IS_DRIVER_OWN) { \ + *_pfgResult = TRUE; \ + } \ +} + +#define HAL_GET_ABNORMAL_INTERRUPT_REASON_CODE(_prAdapter, pu4AbnormalReason) \ +{ \ + HAL_MCR_RD(_prAdapter, \ + MCR_WASR, \ + pu4AbnormalReason); \ +} + +#define HAL_DISABLE_RX_ENHANCE_MODE(_prAdapter) \ +{ \ + uint32_t u4Value = 0; \ + HAL_MCR_RD(_prAdapter, \ + MCR_WHCR, \ + &u4Value); \ + HAL_MCR_WR(_prAdapter, \ + MCR_WHCR, \ + u4Value & ~WHCR_RX_ENHANCE_MODE_EN); \ +} + +#define HAL_ENABLE_RX_ENHANCE_MODE(_prAdapter) \ +{ \ + uint32_t u4Value = 0; \ + HAL_MCR_RD(_prAdapter, \ + MCR_WHCR, \ + &u4Value); \ + HAL_MCR_WR(_prAdapter, \ + MCR_WHCR, \ + u4Value | WHCR_RX_ENHANCE_MODE_EN); \ +} + +#define HAL_CFG_MAX_HIF_RX_LEN_NUM(_prAdapter, _ucNumOfRxLen) \ +{ \ + uint32_t u4Value = 0, ucNum; \ + ucNum = ((_ucNumOfRxLen >= 16) ? 0 : _ucNumOfRxLen); \ + HAL_MCR_RD(_prAdapter, \ + MCR_WHCR, \ + &u4Value); \ + u4Value &= ~WHCR_MAX_HIF_RX_LEN_NUM; \ + u4Value |= ((((uint32_t)ucNum) << WHCR_OFFSET_MAX_HIF_RX_LEN_NUM) \ + & WHCR_MAX_HIF_RX_LEN_NUM); \ + HAL_MCR_WR(_prAdapter, \ + MCR_WHCR, \ + u4Value); \ +} + +#define HAL_SET_INTR_STATUS_READ_CLEAR(prAdapter) \ +{ \ + uint32_t u4Value = 0; \ + HAL_MCR_RD(prAdapter, \ + MCR_WHCR, \ + &u4Value); \ + HAL_MCR_WR(prAdapter, \ + MCR_WHCR, \ + u4Value & ~WHCR_W_INT_CLR_CTRL); \ + prAdapter->prGlueInfo->rHifInfo.fgIntReadClear = TRUE;\ +} + +#define HAL_SET_INTR_STATUS_WRITE_1_CLEAR(prAdapter) \ +{ \ + uint32_t u4Value = 0; \ + HAL_MCR_RD(prAdapter, \ + MCR_WHCR, \ + &u4Value); \ + HAL_MCR_WR(prAdapter, \ + MCR_WHCR, \ + u4Value | WHCR_W_INT_CLR_CTRL); \ + prAdapter->prGlueInfo->rHifInfo.fgIntReadClear = FALSE;\ +} + +/* Note: enhance mode structure may also carried inside the buffer, + * if the length of the buffer is long enough + */ +#define HAL_READ_INTR_STATUS(prAdapter, length, pvBuf) \ + HAL_PORT_RD(prAdapter, \ + MCR_WHISR, \ + length, \ + pvBuf, \ + length) + +#define HAL_READ_TX_RELEASED_COUNT(_prAdapter, au2TxReleaseCount) \ +{ \ + uint32_t *pu4Value = (uint32_t *)au2TxReleaseCount; \ + HAL_MCR_RD(_prAdapter, \ + MCR_WTQCR0, \ + &pu4Value[0]); \ + HAL_MCR_RD(_prAdapter, \ + MCR_WTQCR1, \ + &pu4Value[1]); \ + HAL_MCR_RD(_prAdapter, \ + MCR_WTQCR2, \ + &pu4Value[2]); \ + HAL_MCR_RD(_prAdapter, \ + MCR_WTQCR3, \ + &pu4Value[3]); \ + HAL_MCR_RD(_prAdapter, \ + MCR_WTQCR4, \ + &pu4Value[4]); \ + HAL_MCR_RD(_prAdapter, \ + MCR_WTQCR5, \ + &pu4Value[5]); \ + HAL_MCR_RD(_prAdapter, \ + MCR_WTQCR6, \ + &pu4Value[6]); \ + HAL_MCR_RD(_prAdapter, \ + MCR_WTQCR7, \ + &pu4Value[7]); \ +} + +#define HAL_READ_RX_LENGTH(prAdapter, pu2Rx0Len, pu2Rx1Len) \ +{ \ + uint32_t u4Value = 0; \ + HAL_MCR_RD(prAdapter, \ + MCR_WRPLR, \ + &u4Value); \ + *pu2Rx0Len = (uint16_t)u4Value; \ + *pu2Rx1Len = (uint16_t)(u4Value >> 16); \ +} + +#define HAL_GET_INTR_STATUS_FROM_ENHANCE_MODE_STRUCT(pvBuf, \ + u2Len, pu4Status) \ +{ \ + uint32_t *pu4Buf = (uint32_t *)pvBuf; \ + *pu4Status = pu4Buf[0]; \ +} + +#define HAL_GET_TX_STATUS_FROM_ENHANCE_MODE_STRUCT(pvInBuf, \ + pu4BufOut, u4LenBufOut) \ +{ \ + uint32_t *pu4Buf = (uint32_t *)pvInBuf; \ + ASSERT(u4LenBufOut >= 8); \ + pu4BufOut[0] = pu4Buf[1]; \ + pu4BufOut[1] = pu4Buf[2]; \ +} + +#define HAL_GET_RX_LENGTH_FROM_ENHANCE_MODE_STRUCT(pvInBuf, \ + pu2Rx0Num, au2Rx0Len, pu2Rx1Num, au2Rx1Len) \ +{ \ + uint32_t *pu4Buf = (uint32_t *)pvInBuf; \ + ASSERT((sizeof(au2Rx0Len) / sizeof(uint16_t)) >= 16); \ + ASSERT((sizeof(au2Rx1Len) / sizeof(uint16_t)) >= 16); \ + *pu2Rx0Num = (uint16_t)pu4Buf[3]; \ + *pu2Rx1Num = (uint16_t)(pu4Buf[3] >> 16); \ + kalMemCopy(au2Rx0Len, &pu4Buf[4], 8); \ + kalMemCopy(au2Rx1Len, &pu4Buf[12], 8); \ +} + +#define HAL_GET_MAILBOX_FROM_ENHANCE_MODE_STRUCT(pvInBuf, \ + pu4Mailbox0, pu4Mailbox1) \ +{ \ + uint32_t *pu4Buf = (uint32_t *)pvInBuf; \ + *pu4Mailbox0 = (uint16_t)pu4Buf[21]; \ + *pu4Mailbox1 = (uint16_t)pu4Buf[22]; \ +} + +#define HAL_IS_TX_DONE_INTR(u4IntrStatus) \ + ((u4IntrStatus & WHISR_TX_DONE_INT) ? TRUE : FALSE) + +#define HAL_IS_RX_DONE_INTR(u4IntrStatus) \ + ((u4IntrStatus & (WHISR_RX0_DONE_INT | WHISR_RX1_DONE_INT)) \ + ? TRUE : FALSE) + +#define HAL_IS_ABNORMAL_INTR(u4IntrStatus) \ + ((u4IntrStatus & WHISR_ABNORMAL_INT) ? TRUE : FALSE) + +#define HAL_IS_FW_OWNBACK_INTR(u4IntrStatus) \ + ((u4IntrStatus & WHISR_FW_OWN_BACK_INT) ? TRUE : FALSE) + +#define HAL_PUT_MAILBOX(prAdapter, u4MboxId, u4Data) \ +{ \ + ASSERT(u4MboxId < 2); \ + HAL_MCR_WR(prAdapter, \ + ((u4MboxId == 0) ? MCR_H2DSM0R : MCR_H2DSM1R), \ + u4Data); \ +} + +#define HAL_GET_MAILBOX(prAdapter, u4MboxId, pu4Data) \ +{ \ + ASSERT(u4MboxId < 2); \ + HAL_MCR_RD(prAdapter, \ + ((u4MboxId == 0) ? MCR_D2HRM0R : MCR_D2HRM1R), \ + pu4Data); \ +} + +#define HAL_SET_MAILBOX_READ_CLEAR(prAdapter, fgEnableReadClear) \ +{ \ + uint32_t u4Value = 0; \ + HAL_MCR_RD(prAdapter, MCR_WHCR, &u4Value);\ + HAL_MCR_WR(prAdapter, MCR_WHCR, \ + (fgEnableReadClear) ? \ + (u4Value | WHCR_RECV_MAILBOX_RD_CLR_EN) : \ + (u4Value & ~WHCR_RECV_MAILBOX_RD_CLR_EN)); \ + prAdapter->prGlueInfo->rHifInfo.fgMbxReadClear = fgEnableReadClear;\ +} + +#define HAL_GET_MAILBOX_READ_CLEAR(prAdapter) \ + (prAdapter->prGlueInfo->rHifInfo.fgMbxReadClear) + +#define HAL_READ_INT_STATUS(prAdapter, _pu4IntStatus) \ +{ \ + kalDevReadIntStatus(prAdapter, _pu4IntStatus);\ +} + +#define HAL_HIF_INIT(_prAdapter) \ +{ \ + halDevInit(_prAdapter);\ +} + +#define HAL_ENABLE_FWDL(_prAdapter, _fgEnable) + +#define HAL_WAKE_UP_WIFI(_prAdapter) \ +{ \ + halWakeUpWiFi(_prAdapter);\ +} + +#define HAL_IS_TX_DIRECT(_prAdapter) FALSE + +#define HAL_IS_RX_DIRECT(_prAdapter) FALSE + +#endif + +#if defined(_HIF_USB) +#define HAL_GET_ABNORMAL_INTERRUPT_REASON_CODE(_prAdapter, \ + pu4AbnormalReason) + +#define HAL_DISABLE_RX_ENHANCE_MODE(_prAdapter) + +#define HAL_ENABLE_RX_ENHANCE_MODE(_prAdapter) + +#define HAL_CFG_MAX_HIF_RX_LEN_NUM(_prAdapter, _ucNumOfRxLen) + +#define HAL_SET_INTR_STATUS_READ_CLEAR(prAdapter) + +#define HAL_SET_INTR_STATUS_WRITE_1_CLEAR(prAdapter) + +#define HAL_READ_INTR_STATUS(prAdapter, length, pvBuf) + +#define HAL_READ_TX_RELEASED_COUNT(_prAdapter, au2TxReleaseCount) + +#define HAL_READ_RX_LENGTH(prAdapter, pu2Rx0Len, pu2Rx1Len) + +#define HAL_GET_INTR_STATUS_FROM_ENHANCE_MODE_STRUCT(pvBuf, \ + u2Len, pu4Status) + +#define HAL_GET_TX_STATUS_FROM_ENHANCE_MODE_STRUCT(pvInBuf, \ + pu4BufOut, u4LenBufOut) + +#define HAL_GET_RX_LENGTH_FROM_ENHANCE_MODE_STRUCT(pvInBuf, \ + pu2Rx0Num, au2Rx0Len, pu2Rx1Num, au2Rx1Len) + +#define HAL_GET_MAILBOX_FROM_ENHANCE_MODE_STRUCT(pvInBuf, \ + pu4Mailbox0, pu4Mailbox1) + +#define HAL_READ_TX_RELEASED_COUNT(_prAdapter, au2TxReleaseCount) + +#define HAL_IS_TX_DONE_INTR(u4IntrStatus) FALSE + +#define HAL_IS_RX_DONE_INTR(u4IntrStatus) + +#define HAL_IS_ABNORMAL_INTR(u4IntrStatus) + +#define HAL_IS_FW_OWNBACK_INTR(u4IntrStatus) + +#define HAL_PUT_MAILBOX(prAdapter, u4MboxId, u4Data) + +#define HAL_GET_MAILBOX(prAdapter, u4MboxId, pu4Data) TRUE + +#define HAL_SET_MAILBOX_READ_CLEAR(prAdapter, fgEnableReadClear) + +#define HAL_GET_MAILBOX_READ_CLEAR(prAdapter) TRUE + +#define HAL_WIFI_FUNC_POWER_ON(_prAdapter) \ + mtk_usb_vendor_request(_prAdapter->prGlueInfo, 0, \ + _prAdapter->chip_info->bus_info->u4device_vender_request_out, \ + VND_REQ_POWER_ON_WIFI, 0, 1, NULL, 0) + +#define HAL_WIFI_FUNC_CHIP_RESET(_prAdapter) \ + mtk_usb_vendor_request(_prAdapter->prGlueInfo, 0, \ + _prAdapter->chip_info->bus_info->u4device_vender_request_out, \ + VND_REQ_POWER_ON_WIFI, 1, 1, NULL, 0) + +#define HAL_WIFI_FUNC_READY_CHECK(_prAdapter, _checkItem, _pfgResult) \ +do { \ + struct mt66xx_chip_info *prChipInfo = NULL; \ + uint32_t u4Value = 0; \ + if (!_prAdapter->chip_info) \ + ASSERT(0); \ + *_pfgResult = FALSE; \ + prChipInfo = _prAdapter->chip_info; \ + HAL_MCR_RD(_prAdapter, prChipInfo->sw_sync0, &u4Value); \ + if ((u4Value & (_checkItem << prChipInfo->sw_ready_bit_offset)) \ + == (_checkItem << prChipInfo->sw_ready_bit_offset)) \ + *_pfgResult = TRUE; \ +} while (0) + +#define HAL_WIFI_FUNC_OFF_CHECK(_prAdapter, _checkItem, _pfgResult) \ +do { \ + struct mt66xx_chip_info *prChipInfo = NULL; \ + uint32_t u4Value = 0; \ + if (!_prAdapter->chip_info) \ + ASSERT(0); \ + *_pfgResult = FALSE; \ + prChipInfo = _prAdapter->chip_info; \ + HAL_MCR_RD(_prAdapter, prChipInfo->sw_sync0, &u4Value); \ + if ((u4Value & (_checkItem << prChipInfo->sw_ready_bit_offset)) == 0) \ + *_pfgResult = TRUE; \ +} while (0) + +#define HAL_WIFI_FUNC_GET_STATUS(_prAdapter, _u4Result) \ +do { \ + struct mt66xx_chip_info *prChipInfo = NULL; \ + if (!_prAdapter->chip_info) \ + ASSERT(0); \ + prChipInfo = _prAdapter->chip_info; \ + HAL_MCR_RD(_prAdapter, prChipInfo->sw_sync0, &_u4Result); \ +} while (0) + +#define HAL_INTR_DISABLE(_prAdapter) + +#define HAL_INTR_ENABLE(_prAdapter) + +#define HAL_INTR_ENABLE_AND_LP_OWN_SET(_prAdapter) + +#define HAL_READ_INT_STATUS(prAdapter, _pu4IntStatus) \ +{ \ + halGetCompleteStatus(prAdapter, _pu4IntStatus); \ +} + +#define HAL_HIF_INIT(_prAdapter) \ +{ \ + halDevInit(_prAdapter);\ +} + +#define HAL_ENABLE_FWDL(_prAdapter, _fgEnable) \ +{ \ + halEnableFWDownload(_prAdapter, _fgEnable);\ +} + +#define HAL_WAKE_UP_WIFI(_prAdapter) \ +{ \ + halWakeUpWiFi(_prAdapter);\ +} + +#define HAL_LP_OWN_RD(_prAdapter, _pfgResult) + +#define HAL_LP_OWN_SET(_prAdapter, _pfgResult) + +#define HAL_LP_OWN_CLR(_prAdapter, _pfgResult) + +#define HAL_WRITE_TX_PORT(_prAdapter, _u4PortId, _u4Len, _pucBuf, _u4BufSize) \ +{ \ + HAL_PORT_WR(_prAdapter, \ + _u4PortId, \ + _u4Len, \ + _pucBuf, \ + _u4BufSize/*temp!!*//*4KByte*/) \ +} + +#define HAL_IS_TX_DIRECT(_prAdapter) \ + ((CFG_TX_DIRECT_USB) ? TRUE : FALSE) + +#define HAL_IS_RX_DIRECT(_prAdapter) \ + ((CFG_RX_DIRECT_USB) ? TRUE : FALSE) + +#endif + +/* + * TODO: os-related, should we separate the file just leave API here and + * do the implementation in os folder (?) + * followings are the necessary API for build PASS + */ +#ifdef CFG_VIRTUAL_OS +#define HAL_WRITE_TX_PORT(_prAd, _u4PortId, _u4Len, _pucBuf, _u4BufSize) \ + kal_virt_write_tx_port(_prAd, _u4PortId, _u4Len, _pucBuf, _u4BufSize) + +#define HAL_WIFI_FUNC_GET_STATUS(_prAdapter, _u4Result) \ + kal_virt_get_wifi_func_stat(_prAdapter, &_u4Result) + +#define HAL_WIFI_FUNC_OFF_CHECK(_prAdapter, _checkItem, _pfgResult) \ + kal_virt_chk_wifi_func_off(_prAdapter, _checkItem, _pfgResult) + +#define HAL_WIFI_FUNC_READY_CHECK(_prAdapter, _checkItem, _pfgResult) \ + kal_virt_chk_wifi_func_ready(_prAdapter, _checkItem, _pfgResult) + +#define HAL_SET_MAILBOX_READ_CLEAR(_prAdapter, _fgEnableReadClear) \ + kal_virt_set_mailbox_readclear(_prAdapter, _fgEnableReadClear) + +#define HAL_SET_INTR_STATUS_READ_CLEAR(_prAdapter) \ + kal_virt_set_int_stat_readclear(_prAdapter) + +#define HAL_HIF_INIT(_prAdapter) \ + kal_virt_init_hif(_prAdapter) + +#define HAL_ENABLE_FWDL(_prAdapter, _fgEnable) \ + kal_virt_enable_fwdl(_prAdapter, _fgEnable) + +#define HAL_READ_INT_STATUS(_prAdapter, _pu4IntStatus) \ + kal_virt_get_int_status(_prAdapter, _pu4IntStatus) + +#define HAL_IS_TX_DIRECT(_prAdapter) FALSE + +#define HAL_IS_RX_DIRECT(_prAdapter) FALSE +#endif +#define INVALID_VERSION 0xFFFF /* used by HW/FW version */ +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +u_int8_t halVerifyChipID(IN struct ADAPTER *prAdapter); +uint32_t halGetChipHwVer(IN struct ADAPTER *prAdapter); +uint32_t halGetChipSwVer(IN struct ADAPTER *prAdapter); + +uint32_t halRxWaitResponse(IN struct ADAPTER *prAdapter, + IN uint8_t ucPortIdx, OUT uint8_t *pucRspBuffer, + IN uint32_t u4MaxRespBufferLen, OUT uint32_t *pu4Length); + +void halEnableInterrupt(IN struct ADAPTER *prAdapter); +void halDisableInterrupt(IN struct ADAPTER *prAdapter); + +u_int8_t halSetDriverOwn(IN struct ADAPTER *prAdapter); +void halSetFWOwn(IN struct ADAPTER *prAdapter, + IN u_int8_t fgEnableGlobalInt); + +void halDevInit(IN struct ADAPTER *prAdapter); +void halEnableFWDownload(IN struct ADAPTER *prAdapter, + IN u_int8_t fgEnable); +void halWakeUpWiFi(IN struct ADAPTER *prAdapter); +void halTxCancelSendingCmd(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo); +void halTxCancelAllSending(IN struct ADAPTER *prAdapter); +u_int8_t halTxIsDataBufEnough(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo); +void halProcessTxInterrupt(IN struct ADAPTER *prAdapter); +uint32_t halTxPollingResource(IN struct ADAPTER *prAdapter, + IN uint8_t ucTC); +void halSerHifReset(IN struct ADAPTER *prAdapter); + +void halProcessRxInterrupt(IN struct ADAPTER *prAdapter); +void halProcessAbnormalInterrupt(IN struct ADAPTER *prAdapter); +void halProcessSoftwareInterrupt(IN struct ADAPTER *prAdapter); +/* Hif power off wifi */ +uint32_t halHifPowerOffWifi(IN struct ADAPTER *prAdapter); + + +bool halHifSwInfoInit(IN struct ADAPTER *prAdapter); +void halHifSwInfoUnInit(IN struct GLUE_INFO *prGlueInfo); +void halRxProcessMsduReport(IN struct ADAPTER *prAdapter, + IN OUT struct SW_RFB *prSwRfb); +uint32_t halTxGetPageCount(IN struct ADAPTER *prAdapter, + IN uint32_t u4FrameLength, IN u_int8_t fgIncludeDesc); +uint32_t halDumpHifStatus(IN struct ADAPTER *prAdapter, + IN uint8_t *pucBuf, IN uint32_t u4Max); +u_int8_t halIsPendingRx(IN struct ADAPTER *prAdapter); +uint32_t halGetValidCoalescingBufSize(IN struct ADAPTER *prAdapter); +uint32_t halAllocateIOBuffer(IN struct ADAPTER *prAdapter); +uint32_t halReleaseIOBuffer(IN struct ADAPTER *prAdapter); +void halDeAggRxPktWorker(struct work_struct *work); +void halRxTasklet(unsigned long data); +void halTxCompleteTasklet(unsigned long data); +void halPrintHifDbgInfo(IN struct ADAPTER *prAdapter); +u_int8_t halIsTxResourceControlEn(IN struct ADAPTER *prAdapter); +void halTxResourceResetHwTQCounter(IN struct ADAPTER *prAdapter); +uint32_t halGetHifTxPageSize(IN struct ADAPTER *prAdapter); +void halTxReturnFreeResource(IN struct ADAPTER *prAdapter, + IN uint16_t *au2TxDoneCnt); +void halTxGetFreeResource(IN struct ADAPTER *prAdapter, + IN uint16_t *au2TxDoneCnt, IN uint16_t *au2TxRlsCnt); +void halRestoreTxResource(IN struct ADAPTER *prAdapter); +void halRestoreTxResource_v1(IN struct ADAPTER *prAdapter); +void halUpdateTxDonePendingCount_v1(IN struct ADAPTER *prAdapter, + IN u_int8_t isIncr, IN uint8_t ucTc, IN uint16_t u2Cnt); +void halUpdateTxDonePendingCount(IN struct ADAPTER *prAdapter, + IN u_int8_t isIncr, IN uint8_t ucTc, IN uint32_t u4Len); +void halTxReturnFreeResource_v1(IN struct ADAPTER *prAdapter, + IN uint16_t *au2TxDoneCnt); +uint8_t halTxRingDataSelect(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo); +void halUpdateTxMaxQuota(IN struct ADAPTER *prAdapter); +void halNotifyMdCrash(IN struct ADAPTER *prAdapter); + +#if defined(_HIF_USB) +void halSerSyncTimerHandler(IN struct ADAPTER *prAdapter); +#endif /* defined(_HIF_USB) */ +bool halIsHifStateReady(IN struct ADAPTER *prAdapter, uint8_t *pucState); +bool halIsHifStateLinkup(IN struct ADAPTER *prAdapter); +bool halIsHifStateSuspend(IN struct ADAPTER *prAdapter); + +#if defined(_HIF_PCIE) || defined(_HIF_AXI) +void halRxReceiveRFBs(IN struct ADAPTER *prAdapter, uint32_t u4Port, + uint8_t fgRxData); +u_int8_t halWpdmaWaitIdle(struct GLUE_INFO *prGlueInfo, + int32_t round, int32_t wait_us); +bool halWpdmaAllocRxRing(struct GLUE_INFO *prGlueInfo, uint32_t u4Num, + uint32_t u4Size, uint32_t u4DescSize, + uint32_t u4BufSize, bool fgAllocMem); +#endif /* defined(_HIF_PCIE) || defined(_HIF_AXI) */ + +#endif /* _HAL_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/hif_rx.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/hif_rx.h new file mode 100644 index 0000000000000000000000000000000000000000..2df38d9cd267c3d3eb823819a37d608eb19bc3c7 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/hif_rx.h @@ -0,0 +1,156 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/ + * MT6620_WIFI_DRIVER_V2_3/include/nic/hif_rx.h#1 + */ + +/*! \file "hif_rx.h" + * \brief Provide HIF RX Header Information between F/W and Driver + * + * N/A + */ + + +#ifndef _HIF_RX_H +#define _HIF_RX_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/*! HIF_RX_HEADER_T */ +/* DW 0, Byte 1 */ +#define HIF_RX_HDR_PACKET_TYPE_MASK BITS(0, 1) + +/* DW 1, Byte 0 */ +#define HIF_RX_HDR_HEADER_LEN BITS(2, 7) +#define HIF_RX_HDR_HEADER_LEN_OFFSET 2 +#define HIF_RX_HDR_HEADER_OFFSET_MASK BITS(0, 1) + +/* DW 1, Byte 1 */ +#define HIF_RX_HDR_80211_HEADER_FORMAT BIT(0) +#define HIF_RX_HDR_DO_REORDER BIT(1) +#define HIF_RX_HDR_PAL BIT(2) +#define HIF_RX_HDR_TCL BIT(3) +#define HIF_RX_HDR_NETWORK_IDX_MASK BITS(4, 7) +#define HIF_RX_HDR_NETWORK_IDX_OFFSET 4 + +/* DW 1, Byte 2, 3 */ +#define HIF_RX_HDR_SEQ_NO_MASK BITS(0, 11) +#define HIF_RX_HDR_TID_MASK BITS(12, 14) +#define HIF_RX_HDR_TID_OFFSET 12 +#define HIF_RX_HDR_BAR_FRAME BIT(15) + +#define HIF_RX_HDR_FLAG_AMP_WDS BIT(0) +#define HIF_RX_HDR_FLAG_802_11_FORMAT BIT(1) +#define HIF_RX_HDR_FLAG_BAR_FRAME BIT(2) +#define HIF_RX_HDR_FLAG_DO_REORDERING BIT(3) +#define HIF_RX_HDR_FLAG_CTRL_WARPPER_FRAME BIT(4) + +#define HIF_RX_HW_APPENDED_LEN 4 + +/* For DW 2, Byte 3 - ucHwChannelNum */ +#define HW_CHNL_NUM_MAX_2G4 (14) +#define HW_CHNL_NUM_MAX_4G_5G (255 - HW_CHNL_NUM_MAX_2G4) + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +static __KAL_INLINE__ void hifDataTypeCheck(void); + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +/* Kevin: we don't have to call following function to inspect the data + * structure. It will check automatically while at compile time. + * We'll need this for porting driver to different RTOS. + */ +static __KAL_INLINE__ void hifDataTypeCheck(void) +{ +} + +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/hif_tx.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/hif_tx.h new file mode 100644 index 0000000000000000000000000000000000000000..39336abd2ede1caba6f324e83dd8ff50689a5c52 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/hif_tx.h @@ -0,0 +1,169 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/ + * MT6620_WIFI_DRIVER_V2_3/include/nic/hif_tx.h#1 + */ + + +#ifndef _HIF_TX_H +#define _HIF_TX_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +/* Maximum buffer size for individual HIF TCQ Buffer */ +/* Reserved field was not included */ +#define HIF_TX_BUFF_MAX_SIZE 1552 + +/* Maximum buffer count for individual HIF TCQ */ +#if 0 +#define HIF_TX_BUFF_COUNT_TC0 3 +#define HIF_TX_BUFF_COUNT_TC1 3 +#define HIF_TX_BUFF_COUNT_TC2 3 +#define HIF_TX_BUFF_COUNT_TC3 3 +#define HIF_TX_BUFF_COUNT_TC4 2 +#endif + +#define TX_HDR_SIZE sizeof(struct HIF_TX_HEADER) + +/* !< 2048 Bytes CMD payload buffer */ +#define CMD_PKT_SIZE_FOR_IMAGE 2048 + +/*! NIC_HIF_TX_HEADER_T (for short-header format) */ +/* DW 0, Byte 0,1 */ +#define HIF_TX_HDR_TX_BYTE_COUNT_MASK BITS(0, 15) + +/* DW 0, Byte 2 */ +#define HIF_TX_HDR_ETHER_TYPE_OFFSET_MASK BITS(0, 6) +#define HIF_TX_HDR_IP_CSUM BIT(7) + +/* DW 0, Byte 3 */ +#define HIF_TX_HDR_TCP_CSUM BIT(0) +#define HIF_TX_HDR_QUEUE_IDX_MASK BITS(3, 6) +#define HIF_TX_HDR_QUEUE_IDX_OFFSET 3 +#define HIF_TX_HDR_PORT_IDX_MASK BIT(7) +#define HIF_TX_HDR_PORT_IDX_OFFSET 7 + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +struct HIF_HW_TX_HEADER { + uint16_t u2TxByteCount; + uint8_t ucEtherTypeOffset; + uint8_t ucCSflags; + uint8_t aucBuffer[0]; +}; + +struct HIF_TX_HEADER { + uint16_t u2TxByteCount_UserPriority; + uint8_t ucEtherTypeOffset; + uint8_t ucResource_PktType_CSflags; + uint8_t ucWlanHeaderLength; + uint8_t ucPktFormtId_Flags; + uint16_t u2LLH; /* for BOW */ + uint16_t u2SeqNo; /* for BOW */ + uint8_t ucStaRecIdx; + uint8_t ucForwardingType_SessionID_Reserved; + uint8_t ucPacketSeqNo; + uint8_t ucAck_BIP_BasicRate; + uint8_t aucReserved[2]; +}; + +enum ENUM_HIF_OOB_CTRL_PKT_TYPE { + HIF_OOB_CTRL_PKT_TYPE_LOOPBACK = 1, + HIF_OOB_CTRL_PKT_TYP_NUM +}; + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ +#define TFCB_FRAME_PAD_TO_DW(u2Length) ALIGN_4(u2Length) + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +/* Kevin: we don't have to call following function to inspect the data + * structure. It will check automatically while at compile time. + */ +static __KAL_INLINE__ void hif_txDataTypeCheck(void); + +static __KAL_INLINE__ void hif_txDataTypeCheck(void) +{ + DATA_STRUCT_INSPECTING_ASSERT(sizeof(struct HIF_TX_HEADER) == 16); +} + +#endif /*_HIF_TX_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/mac.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/mac.h new file mode 100644 index 0000000000000000000000000000000000000000..ab19613fccb7f3501ddccaa5a827415ee1628bee --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/mac.h @@ -0,0 +1,3686 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/*! \file "mac.h" + * \brief Brief description. + * + * Detail description. + */ + + +#ifndef _MAC_H +#define _MAC_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +/* 3 --------------- Constants for Ethernet/802.11 MAC --------------- */ +/* MAC Address */ +#define MAC_ADDR_LEN 6 +#define MAC_OUI_LEN (3) + +#define MAC_ADDR_LOCAL_ADMIN BIT(1) + +#define ETH_P_IPV4 0x0800 +#define ETH_P_ARP 0x0806 +#define ETH_P_IPX 0x8137 /* Novell IPX */ +/* AppleTalk Address Resolution Protocol (AARP) */ +#define ETH_P_AARP 0x80F3 +#define ETH_P_IPV6 0x86DD +#define ETH_P_VLAN 0x8100 + +#define IP_PRO_ICMP 0x01 +#define IP_PRO_UDP 0x11 +#define IP_PRO_TCP 0x06 + +#define UDP_PORT_DHCPS 0x43 +#define UDP_PORT_DHCPC 0x44 +#define UDP_PORT_DNS 0x35 + +#define ETH_P_1X 0x888E +#define ETH_P_PRE_1X 0x88C7 +#if CFG_SUPPORT_WAPI +#define ETH_WPI_1X 0x88B4 +#endif +#define ETH_EAPOL_KEY 3 + +#define ETH_PRO_TDLS 0x890d + +/* 802.3 Frame If Ether Type/Len <= 1500 */ +#define ETH_802_3_MAX_LEN 1500 + +/* IP Header definition */ +#define IP_VERSION_MASK BITS(4, 7) +#define IP_VERSION_OFFSET 4 +#define IP_VERSION_4 4 +#define IP_VERSION_6 6 + +#define IP_PRO_ICMP 0x01 +#define IP_PRO_UDP 0x11 +#define IP_PRO_TCP 0x06 + +#define UDP_PORT_DHCPS 0x43 +#define UDP_PORT_DHCPC 0x44 +#define UDP_PORT_DNS 0x35 + +/* IPv4 Header definition */ +#define IPV4_HDR_TOS_OFFSET 1 +#define IPV4_HDR_TOS_PREC_MASK BITS(5, 7) +#define IPV4_HDR_TOS_PREC_OFFSET 5 +#define IPV4_HDR_IP_IDENTIFICATION_OFFSET 4 +#define IPV4_HDR_IP_PROTOCOL_OFFSET 9 +#define IPV4_HDR_IP_CSUM_OFFSET 10 +#define IPV4_HDR_IP_SRC_ADDR_OFFSET 12 +#define IPV4_HDR_IP_DST_ADDR_OFFSET 16 + +#define IPV4_HDR_LEN 20 +#define IPV4_ADDR_LEN 4 + +#define IPV6_HDR_IP_PROTOCOL_OFFSET 6 +#define IPV6_HDR_IP_SRC_ADDR_OFFSET 8 +#define IPV6_HDR_IP_DST_ADDR_OFFSET 24 +#define IPV6_HDR_IP_DST_ADDR_MAC_HIGH_OFFSET 32 +#define IPV6_HDR_IP_DST_ADDR_MAC_LOW_OFFSET 37 +#define IPV6_PROTOCOL_ICMPV6 0x3A + +#define IPV6_HDR_TC_PREC_OFFSET 1 +#define IPV6_HDR_TC_PREC_MASK BITS(1, 3) +#define IPV6_HDR_PROTOCOL_OFFSET 6 +#define IPV6_HDR_LEN 40 + +#define IPV6_ADDR_LEN 16 + +#define ICMPV6_TYPE_OFFSET 0 +#define ICMPV6_FLAG_OFFSET 4 +#define ICMPV6_TARGET_ADDR_OFFSET 8 +#define ICMPV6_TARGET_LL_ADDR_TYPE_OFFSET 24 +#define ICMPV6_TARGET_LL_ADDR_LEN_OFFSET 25 +#define ICMPV6_TARGET_LL_ADDR_TA_OFFSET 26 + +#define ICMPV6_FLAG_ROUTER_BIT BIT(7) +#define ICMPV6_FLAG_SOLICITED_BIT BIT(6) +#define ICMPV6_FLAG_OVERWRITE_BIT BIT(5) +#define ICMPV6_TYPE_NEIGHBOR_SOLICITATION 0x87 +#define ICMPV6_TYPE_NEIGHBOR_ADVERTISEMENT 0x88 + +#define TCP_HDR_TCP_CSUM_OFFSET 16 + +#define UDP_HDR_LEN 8 + +#define UDP_HDR_SRC_PORT_OFFSET 0 +#define UDP_HDR_DST_PORT_OFFSET 2 +#define UDP_HDR_UDP_CSUM_OFFSET 6 + +#define IP_PORT_BOOTP_SERVER 67 +#define IP_PORT_BOOTP_CLIENT 68 + +#define DHCP_MAGIC_NUMBER 0x63825363 + +#define ARP_OPERATION_OFFSET 6 +#define ARP_SENDER_MAC_OFFSET 8 +#define ARP_SENDER_IP_OFFSET 14 +#define ARP_TARGET_MAC_OFFSET 18 +#define ARP_TARGET_IP_OFFSET 24 +#define ARP_OPERATION_REQUEST 0x0001 +#define ARP_OPERATION_RESPONSE 0x0002 + +#define ARP_PRO_REQ 1 +#define ARP_PRO_RSP 2 + +#define TDLS_ACTION_CODE_OFFSET 2 + +/* LLC(3) + SNAP(3) + EtherType(2) */ +#define LLC_LEN 8 + +#define NULL_MAC_ADDR {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} +#define BC_MAC_ADDR {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} + +#if 1 + +#define ETH_HLEN 14 +#define ETH_TYPE_LEN_OFFSET 12 + +#define IPVERSION 4 +#define IP_HEADER_LEN 20 +#define IP_PROTO_HLEN 9 + +#define IPVH_VERSION_OFFSET 4 /* For Little-Endian */ +#define IPVH_VERSION_MASK 0xF0 +#define IPTOS_PREC_OFFSET 5 +#define IPTOS_PREC_MASK 0xE0 + +#define SOURCE_PORT_LEN 2 + +#define LOOK_AHEAD_LEN \ + (ETH_HLEN + IP_HEADER_LEN + SOURCE_PORT_LEN) + +#endif + +/* Ethernet Frame Field Size, in byte */ +#define ETHER_HEADER_LEN 14 +#define ETHER_TYPE_LEN 2 +#define ETHER_MIN_PKT_SZ 60 +#define ETHER_MAX_PKT_SZ 1514 + +#define ETHER_TYPE_LEN_OFFSET 12 + +/* 802.1Q (VLAN) */ +#define ETH_802_1Q_HEADER_LEN 4 + +/* 802.2 LLC/SNAP */ +#define ETH_LLC_OFFSET (ETHER_HEADER_LEN) +#define ETH_LLC_LEN 3 +#define ETH_LLC_DSAP_SNAP 0xAA +#define ETH_LLC_SSAP_SNAP 0xAA +#define ETH_LLC_CONTROL_UNNUMBERED_INFORMATION 0x03 +#define ETH_LLC \ + {ETH_LLC_DSAP_SNAP, ETH_LLC_SSAP_SNAP, \ + ETH_LLC_CONTROL_UNNUMBERED_INFORMATION} + +/* Bluetooth SNAP */ +#define ETH_SNAP_OFFSET (ETHER_HEADER_LEN + ETH_LLC_LEN) +#define ETH_SNAP_LEN 5 +#define ETH_SNAP_OUI_LEN 3 +#define ETH_SNAP_BT_SIG_OUI_0 0x00 +#define ETH_SNAP_BT_SIG_OUI_1 0x19 +#define ETH_SNAP_BT_SIG_OUI_2 0x58 +#define ETH_SNAP_BT_SIG_OUI \ + {ETH_SNAP_BT_SIG_OUI_0, ETH_SNAP_BT_SIG_OUI_1, ETH_SNAP_BT_SIG_OUI_2} + +#define BOW_PROTOCOL_ID_SECURITY_FRAME 0x0003 + +/* IEEE 802.11 WLAN Frame Field Size, in byte */ +/* Address 4 excluded */ +#define WLAN_MAC_HEADER_LEN 24 +/* Address 4 included */ +#define WLAN_MAC_HEADER_A4_LEN 30 +/* QoS Control included */ +#define WLAN_MAC_HEADER_QOS_LEN 26 +/* QoS Control and HTC included */ +#define WLAN_MAC_HEADER_QOS_HTC_LEN 30 +/* Address 4 and QoS Control included */ +#define WLAN_MAC_HEADER_A4_QOS_LEN 32 +/* Address 4, QoS Control and HTC included */ +#define WLAN_MAC_HEADER_A4_QOS_HTC_LEN 36 +/* Address 4 excluded */ +#define WLAN_MAC_MGMT_HEADER_LEN 24 +/* HTC included */ +#define WLAN_MAC_MGMT_HEADER_HTC_LEN 28 + +#define QOS_CTRL_LEN 2 +#define HT_CTRL_LEN 4 + +#define WLAN_MAC_CTS_ACK_LEN \ + (WLAN_MAC_CTS_ACK_FRAME_HEADER_LEN + FCS_LEN) + +/* 6.2.1.1.2 Semantics of the service primitive */ +#define MSDU_MAX_LENGTH 2304 + +/* 7.1.3.3.3 Broadcast BSSID */ +#define BC_BSSID BC_MAC_ADDR + +/* 7.1.3.7 FCS field */ +#define FCS_LEN 4 + +/* 7.3.1.6 Listen Interval field */ +/* In unit of AP's DTIM interval, */ +#define DEFAULT_LISTEN_INTERVAL_BY_DTIM_PERIOD 2 +#define DEFAULT_LISTEN_INTERVAL 10 + +/* 7.3.2.1 Broadcast(Wildcard) SSID */ +#define BC_SSID "" +#define BC_SSID_LEN 0 + +/* 7.3.2.2 Data Rate Value */ +#define RATE_1M 2 /* 1M in unit of 500kb/s */ +#define RATE_2M 4 /* 2M */ +#define RATE_5_5M 11 /* 5.5M */ +#define RATE_11M 22 /* 11M */ +#define RATE_22M 44 /* 22M */ +#define RATE_33M 66 /* 33M */ +#define RATE_6M 12 /* 6M */ +#define RATE_9M 18 /* 9M */ +#define RATE_12M 24 /* 12M */ +#define RATE_18M 36 /* 18M */ +#define RATE_24M 48 /* 24M */ +#define RATE_36M 72 /* 36M */ +#define RATE_48M 96 /* 48M */ +#define RATE_54M 108 /* 54M */ +/* 7.3.2.14 BSS membership selector */ + +/* BSS Selector - Clause 22. HT PHY */ +#define RATE_VHT_PHY 126 +/* BSS Selector - Clause 20. HT PHY */ +#define RATE_HT_PHY 127 +/* mask bits for the rate */ +#define RATE_MASK BITS(0, 6) +/* mask bit for the rate belonging to the BSSBasicRateSet */ +#define RATE_BASIC_BIT BIT(7) + +/* 8.3.2.2 TKIP MPDU formats */ +#define TKIP_MIC_LEN 8 + +/* 9.2.10 DIFS */ +#define DIFS 2 /* 2 x aSlotTime */ + +/* 11.3 STA Authentication and Association */ +/* Accept Class 1 frames */ +#define STA_STATE_1 0 +/* Accept Class 1 & 2 frames */ +#define STA_STATE_2 1 +/* Accept Class 1,2 & 3 frames */ +#define STA_STATE_3 2 + +/* 15.4.8.5 802.11k RCPI-dBm mapping*/ +#define NDBM_LOW_BOUND_FOR_RCPI 110 +#define RCPI_LOW_BOUND 0 +#define RCPI_HIGH_BOUND 220 +#define RCPI_MEASUREMENT_NOT_AVAILABLE 255 + +/* PHY characteristics */ +/* 17.4.4/18.3.3/19.8.4 Slot Time (aSlotTime) */ +/* Long Slot Time */ +#define SLOT_TIME_LONG 20 +/* Short Slot Time */ +#define SLOT_TIME_SHORT 9 + +/* 802.11b aSlotTime */ +#define SLOT_TIME_HR_DSSS SLOT_TIME_LONG +/* 802.11a aSlotTime(20M Spacing) */ +#define SLOT_TIME_OFDM SLOT_TIME_SHORT +/* 802.11a aSlotTime(10M Spacing) */ +#define SLOT_TIME_OFDM_10M_SPACING 13 +/* 802.11g aSlotTime(Long) */ +#define SLOT_TIME_ERP_LONG SLOT_TIME_LONG +/* 802.11g aSlotTime(Short) */ +#define SLOT_TIME_ERP_SHORT SLOT_TIME_SHORT + +/* 17.4.4/18.3.3/19.8.4 Contention Window (aCWmin & aCWmax) */ +/* 802.11a aCWmin */ +#define CWMIN_OFDM 15 +/* 802.11a aCWmax */ +#define CWMAX_OFDM 1023 + +/* 802.11b aCWmin */ +#define CWMIN_HR_DSSS 31 +/* 802.11b aCWmax */ +#define CWMAX_HR_DSSS 1023 + +/* 802.11g aCWmin(0) - for only have 1/2/5/11Mbps Rates */ +#define CWMIN_ERP_0 31 +/* 802.11g aCWmin(1) */ +#define CWMIN_ERP_1 15 +/* 802.11g aCWmax */ +#define CWMAX_ERP 1023 + +/* Short Inter-Frame Space (aSIFSTime) */ +/* 15.3.3 802.11b aSIFSTime */ +#define SIFS_TIME_HR_DSSS 10 +/* 17.4.4 802.11a aSIFSTime */ +#define SIFS_TIME_OFDM 16 +/* 19.8.4 802.11g aSIFSTime */ +#define SIFS_TIME_ERP 10 + +/* 15.4.6.2 Number of operating channels */ +#define CH_1 0x1 +#define CH_2 0x2 +#define CH_3 0x3 +#define CH_4 0x4 +#define CH_5 0x5 +#define CH_6 0x6 +#define CH_7 0x7 +#define CH_8 0x8 +#define CH_9 0x9 +#define CH_10 0xa +#define CH_11 0xb +#define CH_12 0xc +#define CH_13 0xd +#define CH_14 0xe + +/* 3 --------------- IEEE 802.11 PICS --------------- */ +/* Annex D - dot11OperationEntry 2 */ +#define DOT11_RTS_THRESHOLD_MIN 0 +#define DOT11_RTS_THRESHOLD_MAX 2347 /* from Windows DDK */ +/* #define DOT11_RTS_THRESHOLD_MAX 3000 // from Annex D */ + +#define DOT11_RTS_THRESHOLD_DEFAULT \ + DOT11_RTS_THRESHOLD_MAX + +/* Annex D - dot11OperationEntry 5 */ +#define DOT11_FRAGMENTATION_THRESHOLD_MIN 256 +#define DOT11_FRAGMENTATION_THRESHOLD_MAX 2346 /* from Windows DDK */ +/* #define DOT11_FRAGMENTATION_THRESHOLD_MAX 3000 // from Annex D */ + +#define DOT11_FRAGMENTATION_THRESHOLD_DEFAULT \ + DOT11_FRAGMENTATION_THRESHOLD_MAX + +/* Annex D - dot11OperationEntry 6 */ +#define DOT11_TRANSMIT_MSDU_LIFETIME_TU_MIN 1 +#define DOT11_TRANSMIT_MSDU_LIFETIME_TU_MAX 0xFFFFffff + +/* 802.11 define 512 */ +/* MT5921 only aceept N <= 4095 */ +#define DOT11_TRANSMIT_MSDU_LIFETIME_TU_DEFAULT 4095 + +/* Annex D - dot11OperationEntry 7 */ +#define DOT11_RECEIVE_LIFETIME_TU_MIN 1 +#define DOT11_RECEIVE_LIFETIME_TU_MAX 0xFFFFffff +#define DOT11_RECEIVE_LIFETIME_TU_DEFAULT 4096 /* 802.11 define 512 */ + +/* Annex D - dot11StationConfigEntry 12 */ +#define DOT11_BEACON_PERIOD_MIN 1 /* TU. */ +#define DOT11_BEACON_PERIOD_MAX 0xffff /* TU. */ +#define DOT11_BEACON_PERIOD_DEFAULT 100 /* TU. */ + +/* Annex D - dot11StationConfigEntry 13 */ +#define DOT11_DTIM_PERIOD_MIN 1 /* TU. */ +#define DOT11_DTIM_PERIOD_MAX 255 /* TU. */ +#define DOT11_DTIM_PERIOD_DEFAULT 1 /* TU. */ + +/* Annex D - dot11RegDomainsSupportValue */ +#define REGULATION_DOMAIN_FCC 0x10 /* FCC (US) */ +#define REGULATION_DOMAIN_IC 0x20 /* IC or DOC (Canada) */ +#define REGULATION_DOMAIN_ETSI 0x30 /* ETSI (Europe) */ +#define REGULATION_DOMAIN_SPAIN 0x31 /* Spain */ +#define REGULATION_DOMAIN_FRANCE 0x32 /* France */ +#define REGULATION_DOMAIN_JAPAN 0x40 /* MKK (Japan) */ +#define REGULATION_DOMAIN_CHINA 0x50 /* China */ +#define REGULATION_DOMAIN_OTHER 0x00 /* Other */ + +/* 3 --------------- IEEE 802.11 MAC header fields --------------- */ +/* 7.1.3.1 Masks for the subfields in the Frame Control field */ +#define MASK_FC_PROTOCOL_VER BITS(0, 1) +#define MASK_FC_TYPE BITS(2, 3) +#define MASK_FC_SUBTYPE BITS(4, 7) +#define MASK_FC_SUBTYPE_QOS_DATA BIT(7) +#define MASK_FC_TO_DS BIT(8) +#define MASK_FC_FROM_DS BIT(9) +#define MASK_FC_MORE_FRAG BIT(10) +#define MASK_FC_RETRY BIT(11) +#define MASK_FC_PWR_MGT BIT(12) +#define MASK_FC_MORE_DATA BIT(13) +#define MASK_FC_PROTECTED_FRAME BIT(14) +#define MASK_FC_ORDER BIT(15) + +#define MASK_FRAME_TYPE (MASK_FC_TYPE | MASK_FC_SUBTYPE) +#define MASK_TO_DS_FROM_DS \ + (MASK_FC_TO_DS | MASK_FC_FROM_DS) + +#define MAX_NUM_OF_FC_SUBTYPES 16 +#define OFFSET_OF_FC_SUBTYPE 4 + +/* 7.1.3.1.2 MAC frame types and subtypes */ +#define MAC_FRAME_TYPE_MGT 0 +#define MAC_FRAME_TYPE_CTRL BIT(2) +#define MAC_FRAME_TYPE_DATA BIT(3) +#define MAC_FRAME_TYPE_QOS_DATA \ + (MAC_FRAME_TYPE_DATA | MASK_FC_SUBTYPE_QOS_DATA) + +#define MAC_FRAME_ASSOC_REQ (MAC_FRAME_TYPE_MGT | 0x0000) +#define MAC_FRAME_ASSOC_RSP (MAC_FRAME_TYPE_MGT | 0x0010) +#define MAC_FRAME_REASSOC_REQ (MAC_FRAME_TYPE_MGT | 0x0020) +#define MAC_FRAME_REASSOC_RSP (MAC_FRAME_TYPE_MGT | 0x0030) +#define MAC_FRAME_PROBE_REQ (MAC_FRAME_TYPE_MGT | 0x0040) +#define MAC_FRAME_PROBE_RSP (MAC_FRAME_TYPE_MGT | 0x0050) +#define MAC_FRAME_BEACON (MAC_FRAME_TYPE_MGT | 0x0080) +#define MAC_FRAME_ATIM (MAC_FRAME_TYPE_MGT | 0x0090) +#define MAC_FRAME_DISASSOC (MAC_FRAME_TYPE_MGT | 0x00A0) +#define MAC_FRAME_AUTH (MAC_FRAME_TYPE_MGT | 0x00B0) +#define MAC_FRAME_DEAUTH (MAC_FRAME_TYPE_MGT | 0x00C0) +#define MAC_FRAME_ACTION (MAC_FRAME_TYPE_MGT | 0x00D0) +#define MAC_FRAME_ACTION_NO_ACK (MAC_FRAME_TYPE_MGT | 0x00E0) + +#define MAC_FRAME_HE_TRIGGER (MAC_FRAME_TYPE_CTRL | 0x0020) +#define MAC_FRAME_CONTRL_WRAPPER (MAC_FRAME_TYPE_CTRL | 0x0070) +#define MAC_FRAME_BLOCK_ACK_REQ (MAC_FRAME_TYPE_CTRL | 0x0080) +#define MAC_FRAME_BLOCK_ACK (MAC_FRAME_TYPE_CTRL | 0x0090) +#define MAC_FRAME_PS_POLL (MAC_FRAME_TYPE_CTRL | 0x00A0) +#define MAC_FRAME_RTS (MAC_FRAME_TYPE_CTRL | 0x00B0) +#define MAC_FRAME_CTS (MAC_FRAME_TYPE_CTRL | 0x00C0) +#define MAC_FRAME_ACK (MAC_FRAME_TYPE_CTRL | 0x00D0) +#define MAC_FRAME_CF_END (MAC_FRAME_TYPE_CTRL | 0x00E0) +#define MAC_FRAME_CF_END_CF_ACK (MAC_FRAME_TYPE_CTRL | 0x00F0) + +#define MAC_FRAME_DATA (MAC_FRAME_TYPE_DATA | 0x0000) +#define MAC_FRAME_DATA_CF_ACK (MAC_FRAME_TYPE_DATA | 0x0010) +#define MAC_FRAME_DATA_CF_POLL (MAC_FRAME_TYPE_DATA | 0x0020) +#define MAC_FRAME_DATA_CF_ACK_CF_POLL (MAC_FRAME_TYPE_DATA | 0x0030) +#define MAC_FRAME_NULL (MAC_FRAME_TYPE_DATA | 0x0040) +#define MAC_FRAME_CF_ACK (MAC_FRAME_TYPE_DATA | 0x0050) +#define MAC_FRAME_CF_POLL (MAC_FRAME_TYPE_DATA | 0x0060) +#define MAC_FRAME_CF_ACK_CF_POLL (MAC_FRAME_TYPE_DATA | 0x0070) +#define MAC_FRAME_QOS_DATA (MAC_FRAME_TYPE_DATA | 0x0080) +#define MAC_FRAME_QOS_DATA_CF_ACK (MAC_FRAME_TYPE_DATA | 0x0090) +#define MAC_FRAME_QOS_DATA_CF_POLL (MAC_FRAME_TYPE_DATA | 0x00A0) +#define MAC_FRAME_QOS_DATA_CF_ACK_CF_POLL (MAC_FRAME_TYPE_DATA | 0x00B0) +#define MAC_FRAME_QOS_NULL (MAC_FRAME_TYPE_DATA | 0x00C0) +#define MAC_FRAME_QOS_CF_POLL (MAC_FRAME_TYPE_DATA | 0x00E0) +#define MAC_FRAME_QOS_CF_ACK_CF_POLL (MAC_FRAME_TYPE_DATA | 0x00F0) + +/* 7.1.3.2 Mask for the AID value in the Duration/ID field */ +#define MASK_DI_DURATION BITS(0, 14) +#define MASK_DI_AID BITS(0, 13) +#define MASK_DI_AID_MSB BITS(14, 15) +#define MASK_DI_CFP_FIXED_VALUE BIT(15) + +/* 7.1.3.4 Masks for the subfields in the Sequence Control field */ +#define MASK_SC_SEQ_NUM BITS(4, 15) +#define MASK_SC_SEQ_NUM_OFFSET 4 +#define MASK_SC_FRAG_NUM BITS(0, 3) + +/* According to 6.2.1.1.2 + * FRAG_NUM won't equal to 15 + */ +#define INVALID_SEQ_CTRL_NUM 0x000F + +/* 7.1.3.5 QoS Control field */ +#define TID_NUM 16 +#define TID_MASK BITS(0, 3) +#define EOSP BIT(4) +#define ACK_POLICY BITS(5, 6) +#define A_MSDU_PRESENT BIT(7) + +#define MASK_QC_TID BITS(0, 3) +#define MASK_QC_EOSP BIT(4) +#define MASK_QC_EOSP_OFFSET 4 +#define MASK_QC_ACK_POLICY BITS(5, 6) +#define MASK_QC_ACK_POLICY_OFFSET 5 +#define MASK_QC_A_MSDU_PRESENT BIT(7) + +/* 7.1.3.5a HT Control field */ +#define HT_CTRL_LINK_ADAPTATION_CTRL BITS(0, 15) +#define HT_CTRL_CALIBRATION_POSITION BITS(16, 17) +#define HT_CTRL_CALIBRATION_SEQUENCE BITS(18, 19) +#define HT_CTRL_CSI_STEERING BITS(22, 23) +#define HT_CTRL_NDP_ANNOUNCEMENT BIT(24) +#define HT_CTRL_AC_CONSTRAINT BIT(30) +#define HT_CTRL_RDG_MORE_PPDU BIT(31) + +#define LINK_ADAPTATION_CTRL_TRQ BIT(1) +#define LINK_ADAPTATION_CTRL_MAI_MRQ BIT(2) +#define LINK_ADAPTATION_CTRL_MAI_MSI BITS(3, 5) +#define LINK_ADAPTATION_CTRL_MFSI BITS(6, 8) +#define LINK_ADAPTATION_CTRL_MFB_ASELC_CMD BITS(9, 11) +#define LINK_ADAPTATION_CTRL_MFB_ASELC_DATA BITS(12, 15) + +/* 7.1.3.5.3 Ack Policy subfield*/ +#define ACK_POLICY_NORMAL_ACK_IMPLICIT_BA_REQ 0 +#define ACK_POLICY_NO_ACK 1 +#define ACK_POLICY_NO_EXPLICIT_ACK_PSMP_ACK 2 +#define ACK_POLICY_BA 3 + +/* 7.1.3.7 FCS field */ +#define FCS_LEN 4 + +/* 7.2.1.4 WLAN Control Frame - PS-POLL Frame */ +#define PSPOLL_FRAME_LEN 16 /* w/o FCS */ + +/* 7.2.7.1 BAR */ +#define OFFSET_BAR_SSC_SN 4 + +/* 8.3.2.2 TKIP MPDU formats */ +#define TKIP_MIC_LEN 8 + +#define BA_POLICY_IMMEDIATE BIT(1) + +/* Block Ack Starting Sequence Control field */ +#define BA_START_SEQ_CTL_FRAG_NUM BITS(0, 3) +#define BA_START_SEQ_CTL_SSN BITS(4, 15) + +/* BAR Control field */ +#define BAR_CONTROL_NO_ACK_POLICY BIT(0) +#define BAR_CONTROL_MULTI_TID BIT(1) +#define BAR_CONTROL_COMPRESSED_BA BIT(2) +#define BAR_CONTROL_TID_INFO BITS(12, 15) +#define BAR_CONTROL_TID_INFO_OFFSET 12 + +/* TID Value */ +#define BAR_INFO_TID_VALUE BITS(12, 15) + +#define BAR_COMPRESSED_VARIANT_FRAME_LEN (16 + 4) + +/* 3 --------------- IEEE 802.11 frame body fields --------------- */ +/* 3 Management frame body components (I): Fixed Fields. */ +/* 7.3.1.1 Authentication Algorithm Number field */ +#define AUTH_ALGORITHM_NUM_FIELD_LEN 2 + +#define AUTH_ALGORITHM_NUM_OPEN_SYSTEM 0 /* Open System */ +#define AUTH_ALGORITHM_NUM_SHARED_KEY 1 /* Shared Key */ +#define AUTH_ALGORITHM_NUM_FAST_BSS_TRANSITION \ + 2 /* Fast BSS Transition */ +#define AUTH_ALGORITHM_NUM_SAE 3 /* WPA3 - SAE */ + +/* 7.3.1.2 Authentication Transaction Sequence Number field */ +#define AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN 2 +#define AUTH_TRANSACTION_SEQ_1 1 +#define AUTH_TRANSACTION_SEQ_2 2 +#define AUTH_TRANSACTION_SEQ_3 3 +#define AUTH_TRANSACTION_SEQ_4 4 + +/* 7.3.1.3 Beacon Interval field */ +#define BEACON_INTERVAL_FIELD_LEN 2 + +/* 7.3.1.4 Capability Information field */ +#define CAP_INFO_FIELD_LEN 2 +#define CAP_INFO_ESS BIT(0) +#define CAP_INFO_IBSS BIT(1) +#define CAP_INFO_BSS_TYPE \ + (CAP_INFO_ESS | CAP_INFO_IBSS) +#define CAP_INFO_CF_POLLABLE BIT(2) +#define CAP_INFO_CF_POLL_REQ BIT(3) +#define CAP_INFO_CF \ + (CAP_INFO_CF_POLLABLE | CAP_INFO_CF_POLL_REQ) +#define CAP_INFO_PRIVACY BIT(4) +#define CAP_INFO_SHORT_PREAMBLE BIT(5) +#define CAP_INFO_PBCC BIT(6) +#define CAP_INFO_CH_AGILITY BIT(7) +#define CAP_INFO_SPEC_MGT BIT(8) +#define CAP_INFO_QOS BIT(9) +#define CAP_INFO_SHORT_SLOT_TIME BIT(10) +#define CAP_INFO_APSD BIT(11) +#define CAP_INFO_RADIO_MEASUREMENT BIT(12) +#define CAP_INFO_DSSS_OFDM BIT(13) +#define CAP_INFO_DELAYED_BLOCK_ACK BIT(14) +#define CAP_INFO_IMM_BLOCK_ACK BIT(15) +/* STA usage of CF-Pollable and CF-Poll Request subfields */ +/* STA: not CF-Pollable */ +#define CAP_CF_STA_NOT_POLLABLE 0x0000 +/* STA: CF-Pollable, not requesting on the CF-Polling list */ +#define CAP_CF_STA_NOT_ON_LIST CAP_INFO_CF_POLL_REQ +/* STA: CF-Pollable, requesting on the CF-Polling list */ +#define CAP_CF_STA_ON_LIST CAP_INFO_CF_POLLABLE +/* STA: CF-Pollable, requesting never to be polled */ +#define CAP_CF_STA_NEVER_POLLED \ + (CAP_INFO_CF_POLLABLE | CAP_INFO_CF_POLL_REQ) + +/* AP usage of CF-Pollable and CF-Poll Request subfields */ +/* AP: No point coordinator (PC) */ +#define CAP_CF_AP_NO_PC 0x0000 +/* AP: PC at AP for delivery only (no polling) */ +#define CAP_CF_AP_DELIVERY_ONLY CAP_INFO_CF_POLL_REQ +/* AP: PC at AP for delivery and polling */ +#define CAP_CF_AP_DELIVERY_POLLING CAP_INFO_CF_POLLABLE + +/* 7.3.1.5 Current AP Address field */ +#define CURR_AP_ADDR_FIELD_LEN MAC_ADDR_LEN + +/* 7.3.1.6 Listen Interval field */ +#define LISTEN_INTERVAL_FIELD_LEN 2 + +/* 7.3.1.7 Reason Code field */ +#define REASON_CODE_FIELD_LEN 2 + +/* Reseved */ +#define REASON_CODE_RESERVED 0 +/* Unspecified reason */ +#define REASON_CODE_UNSPECIFIED 1 +/* Previous auth no longer valid */ +#define REASON_CODE_PREV_AUTH_INVALID 2 +/* Deauth because sending STA is leaving BSS */ +#define REASON_CODE_DEAUTH_LEAVING_BSS 3 +/* Disassoc due to inactivity */ +#define REASON_CODE_DISASSOC_INACTIVITY 4 +/* Disassoc because AP is unable to handle all assoc STAs */ +#define REASON_CODE_DISASSOC_AP_OVERLOAD 5 +/* Class 2 frame rx from nonauth STA */ +#define REASON_CODE_CLASS_2_ERR 6 +/* Class 3 frame rx from nonassoc STA */ +#define REASON_CODE_CLASS_3_ERR 7 +/* Disassoc because sending STA is leaving BSS */ +#define REASON_CODE_DISASSOC_LEAVING_BSS 8 +/* STA requesting (re)assoc is not auth with responding STA */ +#define REASON_CODE_ASSOC_BEFORE_AUTH 9 +/* Disassoc because the info in Power Capability is unacceptable */ +#define REASON_CODE_DISASSOC_PWR_CAP_UNACCEPTABLE 10 +/* Disassoc because the info in Supported Channels is unacceptable */ +#define REASON_CODE_DISASSOC_SUP_CHS_UNACCEPTABLE 11 +/* Invalid information element */ +#define REASON_CODE_INVALID_INFO_ELEM 13 +/* MIC failure */ +#define REASON_CODE_MIC_FAILURE 14 +/* 4-way handshake timeout */ +#define REASON_CODE_4_WAY_HANDSHAKE_TIMEOUT 15 +/* Group key update timeout */ +#define REASON_CODE_GROUP_KEY_UPDATE_TIMEOUT 16 +/* Info element in 4-way handshake different from */ +/* (Re-)associate request/Probe response/Beacon */ +#define REASON_CODE_DIFFERENT_INFO_ELEM 17 +/* Multicast Cipher is not valid */ +#define REASON_CODE_MULTICAST_CIPHER_NOT_VALID 18 +/* Unicast Cipher is not valid */ +#define REASON_CODE_UNICAST_CIPHER_NOT_VALID 19 +/* AKMP is not valid */ +#define REASON_CODE_AKMP_NOT_VALID 20 +/* Unsupported RSNE version */ +#define REASON_CODE_UNSUPPORTED_RSNE_VERSION 21 +/* Invalid RSNE Capabilities */ +#define REASON_CODE_INVALID_RSNE_CAPABILITIES 22 +/* IEEE 802.1X Authentication failed */ +#define REASON_CODE_IEEE_802_1X_AUTH_FAILED 23 +/* Cipher suite rejected because of the security policy */ +#define REASON_CODE_CIPHER_REJECT_SEC_POLICY 24 +/* Disassoc for unspecified, QoS-related reason */ +#define REASON_CODE_DISASSOC_UNSPECIFIED_QOS 32 +/* Disassoc because QAP lacks sufficient bandwidth for this QSTA */ +#define REASON_CODE_DISASSOC_LACK_OF_BANDWIDTH 33 +/* Disassoc because of too many ACKs lost for AP transmissions */ +/* and/or poor channel conditions */ +#define REASON_CODE_DISASSOC_ACK_LOST_POOR_CHANNEL 34 +/* Disassoc because QSTA is transmitting outside the limits of its TXOPs */ +#define REASON_CODE_DISASSOC_TX_OUTSIDE_TXOP_LIMIT 35 +/* QSTA is leaving the QBSS or resetting */ +#define REASON_CODE_PEER_WHILE_LEAVING 36 +/* Peer does not want to use this mechanism */ +#define REASON_CODE_PEER_REFUSE_DLP 37 +/* Frames received but a setup is reqired */ +#define REASON_CODE_PEER_SETUP_REQUIRED 38 +/* Time out */ +#define REASON_CODE_PEER_TIME_OUT 39 +/* Peer does not support the requested cipher suite */ +#define REASON_CODE_PEER_CIPHER_UNSUPPORTED 45 +/* for beacon timeout, defined by mediatek */ +#define REASON_CODE_BEACON_TIMEOUT 100 +/* 7.3.1.8 AID field */ +#define AID_FIELD_LEN 2 +#define AID_MASK BITS(0, 13) +#define AID_MSB BITS(14, 15) +#define AID_MIN_VALUE 1 +#define AID_MAX_VALUE 2007 + +/* 7.3.1.9 Status Code field */ +#define STATUS_CODE_FIELD_LEN 2 +/* Reserved - Used by TX Auth */ +#define STATUS_CODE_RESERVED 0 +/* Successful */ +#define STATUS_CODE_SUCCESSFUL 0 +/* Unspecified failure */ +#define STATUS_CODE_UNSPECIFIED_FAILURE 1 +/* Cannot support all requested cap in the Cap Info field */ +#define STATUS_CODE_CAP_NOT_SUPPORTED 10 +/* Reassoc denied due to inability to confirm that assoc exists */ +#define STATUS_CODE_REASSOC_DENIED_WITHOUT_ASSOC 11 +/* Assoc denied due to reason outside the scope of this std. */ +#define STATUS_CODE_ASSOC_DENIED_OUTSIDE_STANDARD 12 +/* Responding STA does not support the specified auth algorithm */ +#define STATUS_CODE_AUTH_ALGORITHM_NOT_SUPPORTED 13 +/* Rx an auth frame with auth transaction seq num out of expected seq */ +#define STATUS_CODE_AUTH_OUT_OF_SEQ 14 +/* Auth rejected because of challenge failure */ +#define STATUS_CODE_AUTH_REJECTED_CHAL_FAIL 15 +/* Auth rejected due to timeout waiting for next frame in sequence */ +#define STATUS_CODE_AUTH_REJECTED_TIMEOUT 16 +/* Assoc denied because AP is unable to handle additional assoc STAs */ +#define STATUS_CODE_ASSOC_DENIED_AP_OVERLOAD 17 +/* Assoc denied due to requesting STA not supporting all of basic rates */ +#define STATUS_CODE_ASSOC_DENIED_RATE_NOT_SUPPORTED 18 +/* Assoc denied due to requesting STA not supporting short preamble */ +#define STATUS_CODE_ASSOC_DENIED_NO_SHORT_PREAMBLE 19 +/* Assoc denied due to requesting STA not supporting PBCC */ +#define STATUS_CODE_ASSOC_DENIED_NO_PBCC 20 +/* Assoc denied due to requesting STA not supporting channel agility */ +#define STATUS_CODE_ASSOC_DENIED_NO_CH_AGILITY 21 +/* Assoc rejected because Spectrum Mgt capability is required */ +#define STATUS_CODE_ASSOC_REJECTED_NO_SPEC_MGT 22 +/* Assoc rejected because the info in Power Capability is unacceptable */ +#define STATUS_CODE_ASSOC_REJECTED_PWR_CAP 23 +/* Assoc rejected because the info in Supported Channels is unacceptable */ +#define STATUS_CODE_ASSOC_REJECTED_SUP_CHS 24 +/* Assoc denied due to requesting STA not supporting short slot time */ +#define STATUS_CODE_ASSOC_DENIED_NO_SHORT_SLOT_TIME 25 +/* Assoc denied due to requesting STA not supporting DSSS-OFDM */ +#define STATUS_CODE_ASSOC_DENIED_NO_DSSS_OFDM 26 +#if CFG_SUPPORT_802_11W +/* IEEE 802.11w, Assoc denied due to the SA query */ +#define STATUS_CODE_ASSOC_REJECTED_TEMPORARILY 30 +/* IEEE 802.11w, Assoc denied due to the MFP select policy */ +#define STATUS_CODE_ROBUST_MGMT_FRAME_POLICY_VIOLATION 31 +#endif +/* Unspecified, QoS-related failure */ +#define STATUS_CODE_UNSPECIFIED_QOS_FAILURE 32 +/* Assoc denied due to insufficient bandwidth to handle another QSTA */ +#define STATUS_CODE_ASSOC_DENIED_BANDWIDTH 33 +/* Assoc denied due to excessive frame loss + * rates and/or poor channel conditions + */ +#define STATUS_CODE_ASSOC_DENIED_POOR_CHANNEL 34 +/* Assoc denied due to requesting STA not supporting QoS facility */ +#define STATUS_CODE_ASSOC_DENIED_NO_QOS_FACILITY 35 +/* Request has been declined */ +#define STATUS_CODE_REQ_DECLINED 37 +/* Request has not been successful as one + * or more parameters have invalid values + */ +#define STATUS_CODE_REQ_INVALID_PARAMETER_VALUE 38 +/* TS not created because request cannot be honored. */ +/* Suggested TSPEC provided. */ +#define STATUS_CODE_REQ_NOT_HONORED_TSPEC 39 +/* Invalid information element */ +#define STATUS_CODE_INVALID_INFO_ELEMENT 40 +/* Invalid group cipher */ +#define STATUS_CODE_INVALID_GROUP_CIPHER 41 +/* Invalid pairwise cipher */ +#define STATUS_CODE_INVALID_PAIRWISE_CIPHER 42 +/* Invalid AKMP */ +#define STATUS_CODE_INVALID_AKMP 43 +/* Unsupported RSN information element version */ +#define STATUS_CODE_UNSUPPORTED_RSN_IE_VERSION 44 +/* Invalid RSN information element capabilities */ +#define STATUS_CODE_INVALID_RSN_IE_CAP 45 +/* Cipher suite rejected because of security policy */ +#define STATUS_CODE_CIPHER_SUITE_REJECTED 46 +/* TS not created because request cannot be honored. */ +/* Attempt to create a TS later. */ +#define STATUS_CODE_REQ_NOT_HONORED_TS_DELAY 47 +/* Direct Link is not allowed in the BSS by policy */ +#define STATUS_CODE_DIRECT_LINK_NOT_ALLOWED 48 +/* Destination STA is not present within this QBSS */ +#define STATUS_CODE_DESTINATION_STA_NOT_PRESENT 49 +/* Destination STA is not a QSTA */ +#define STATUS_CODE_DESTINATION_STA_NOT_QSTA 50 +/* Association denied because the ListenInterval is too large */ +#define STATUS_CODE_ASSOC_DENIED_LARGE_LIS_INTERVAL 51 +/* Invalid pairwise master key identifier (PMKID) */ +#define STATUS_INVALID_PMKID 53 + +/* proprietary definition of reserved field of Status Code */ +/* Join failure */ +#define STATUS_CODE_JOIN_FAILURE 0xFFF0 +/* Join timeout */ +#define STATUS_CODE_JOIN_TIMEOUT 0xFFF1 +/* Authentication timeout */ +#define STATUS_CODE_AUTH_TIMEOUT 0xFFF2 +/* (Re)Association timeout */ +#define STATUS_CODE_ASSOC_TIMEOUT 0xFFF3 +/* CCX CCKM reassociation failure */ +#define STATUS_CODE_CCX_CCKM_REASSOC_FAILURE 0xFFF4 + +/* 7.3.1.10 Timestamp field */ +#define TIMESTAMP_FIELD_LEN 8 + +/* 80211-2016 Table 9-47 Category of Action field */ +#define CATEGORY_SPEC_MGT 0 +/* QoS action */ +#define CATEGORY_QOS_ACTION 1 +/* Direct Link Protocol (DLP) action */ +#define CATEGORY_DLS_ACTION 2 +/* Block ack action */ +#define CATEGORY_BLOCK_ACK_ACTION 3 +/* Public action */ +#define CATEGORY_PUBLIC_ACTION 4 +/* Radio measurement action */ +#define CATEGORY_RM_ACTION 5 +/* Fast BSS Transition */ +#define CATEGORY_FT_ACTION 6 +/* HT */ +#define CATEGORY_HT_ACTION 7 +/* SA Qurery */ +#define CATEGORY_SA_QUERY_ACTION 8 +/* Protected Dual of Public Action */ +#define CATEGORY_PROTECTED_DUAL_OF_PUBLIC_ACTION 9 +/* 802.11v Wireless Network Management */ +#define CATEGORY_WNM_ACTION 10 +/* 802.11v Unprotected Wireless Network Management */ +#define CATEGORY_UNPROTECTED_WNM_ACTION 11 +/* TDLS */ +#define CATEGORY_TDLS_ACTION 12 +/* Mesh */ +#define CATEGORY_MESH_ACTION 13 +/* Multihop */ +#define CATEGORY_MULTIHOP_ACTION 14 +/* Self-protected */ +#define CATEGORY_SELF_PROTECTED_ACTION 15 +/* Directional Multi-Gigabit */ +#define CATEGORY_DMG_ACTION 16 +/* WME management notification */ +#define CATEGORY_WME_MGT_NOTIFICATION 17 +/* Fast Session Transfer */ +#define CATEGORY_FST_ACTION 18 +/* Robust AV Streaming */ +#define CATEGORY_ROBUST_AV_STREAMING_ACTION 19 +/* Unprotected DMG */ +#define CATEGORY_UNPROTECTED_DMG_ACTION 20 +/* VHT action */ +#define CATEGORY_VHT_ACTION 21 +#if (CFG_SUPPORT_TWT == 1) +#define CATEGORY_S1G_ACTION 22 /* S1G action */ +#endif +/* Vendor-specific Protected */ +#define CATEGORY_VENDOR_SPECIFIC_PROTECTED_ACTION 126 +/* Vendor-specific */ +#define CATEGORY_VENDOR_SPECIFIC_ACTION 127 + +/* 7.3.1.14 Block Ack Parameter Set field */ +#define BA_PARAM_SET_ACK_POLICY_MASK BIT(1) +#define BA_PARAM_SET_ACK_POLICY_MASK_OFFSET 1 +#define BA_PARAM_SET_TID_MASK BITS(2, 5) +#define BA_PARAM_SET_TID_MASK_OFFSET 2 +#define BA_PARAM_SET_BUFFER_SIZE_MASK BITS(6, 15) +#define BA_PARAM_SET_BUFFER_SIZE_MASK_OFFSET 6 + +#define BA_PARAM_SET_ACK_POLICY_IMMEDIATE_BA 1 +#define BA_PARAM_SET_ACK_POLICY_DELAYED_BA 0 + +/* 3 Management frame body components (II): Information Elements. */ +/* 7.3.2 Element IDs of information elements */ +#define ELEM_HDR_LEN 2 + +#define ELEM_ID_SSID \ + 0 /* SSID */ +#define ELEM_ID_SUP_RATES \ + 1 /* Supported rates */ +#define ELEM_ID_FH_PARAM_SET \ + 2 /* FH parameter set */ +#define ELEM_ID_DS_PARAM_SET \ + 3 /* DS parameter set */ +#define ELEM_ID_CF_PARAM_SET \ + 4 /* CF parameter set */ +#define ELEM_ID_TIM \ + 5 /* TIM */ +#define ELEM_ID_IBSS_PARAM_SET \ + 6 /* IBSS parameter set */ +#define ELEM_ID_COUNTRY_INFO \ + 7 /* Country information */ +#define ELEM_ID_HOPPING_PATTERN_PARAM \ + 8 /* Hopping pattern parameters */ +#define ELEM_ID_HOPPING_PATTERN_TABLE \ + 9 /* Hopping pattern table */ +#define ELEM_ID_REQUEST \ + 10 /* Request */ +#define ELEM_ID_BSS_LOAD \ + 11 /* BSS load */ +#define ELEM_ID_EDCA_PARAM_SET \ + 12 /* EDCA parameter set */ +#define ELEM_ID_TSPEC \ + 13 /* Traffic specification (TSPEC) */ +#define ELEM_ID_TCLAS \ + 14 /* Traffic classification (TCLAS) */ +#define ELEM_ID_SCHEDULE \ + 15 /* Schedule */ +#define ELEM_ID_CHALLENGE_TEXT \ + 16 /* Challenge text */ + +#define ELEM_ID_PWR_CONSTRAINT \ + 32 /* Power constraint */ +#define ELEM_ID_PWR_CAP \ + 33 /* Power capability */ +#define ELEM_ID_TPC_REQ \ + 34 /* TPC request */ +#define ELEM_ID_TPC_REPORT \ + 35 /* TPC report */ +#define ELEM_ID_SUP_CHS \ + 36 /* Supported channels */ +#define ELEM_ID_CH_SW_ANNOUNCEMENT \ + 37 /* Channel switch announcement */ +#define ELEM_ID_MEASUREMENT_REQ \ + 38 /* Measurement request */ +#define ELEM_ID_MEASUREMENT_REPORT \ + 39 /* Measurement report */ +#define ELEM_ID_QUIET \ + 40 /* Quiet */ +#define ELEM_ID_IBSS_DFS \ + 41 /* IBSS DFS */ +#define ELEM_ID_ERP_INFO \ + 42 /* ERP information */ +#define ELEM_ID_TS_DELAY \ + 43 /* TS delay */ +#define ELEM_ID_TCLAS_PROCESSING \ + 44 /* TCLAS processing */ +#define ELEM_ID_HT_CAP \ + 45 /* HT Capabilities subelement */ +#define ELEM_ID_QOS_CAP \ + 46 /* QoS capability */ +#define ELEM_ID_RSN \ + 48 /* RSN IE */ +#define ELEM_ID_EXTENDED_SUP_RATES \ + 50 /* Extended supported rates */ +#define ELEM_ID_AP_CHANNEL_REPORT \ + 51 /* AP Channel Report Element */ +#define ELEM_ID_NEIGHBOR_REPORT \ + 52 /* Neighbor Report */ +#define ELEM_ID_MOBILITY_DOMAIN \ + 54 /* Mobility Domain for 802.11R */ +#define ELEM_ID_FAST_TRANSITION \ + 55 /* Fast Bss Transition for 802.11 R */ +#if CFG_SUPPORT_802_11W +#define ELEM_ID_TIMEOUT_INTERVAL \ + 56 /* 802.11w SA Timeout interval */ +#endif +#define ELEM_ID_RESOURCE_INFO_CONTAINER \ + 57 /* Resource Information Container for 802.11 R */ +#define ELEM_ID_SUP_OPERATING_CLASS \ + 59 /* Supported Operating Classes */ + +#define ELEM_ID_HT_OP \ + 61 /* HT Operation */ +#define ELEM_ID_SCO \ + 62 /* Secondary Channel Offset */ +#define ELEM_ID_RRM_ENABLED_CAP \ + 70 /* Radio Resource Management Enabled Capabilities */ +#define ELEM_ID_MBSSID \ + 71 /* Multiple BSSID element */ +#define ELEM_ID_20_40_BSS_COEXISTENCE \ + 72 /* 20/40 BSS Coexistence */ +#define ELEM_ID_20_40_INTOLERANT_CHNL_REPORT \ + 73 /* 20/40 BSS Intolerant Channel Report */ +#define ELEM_ID_OBSS_SCAN_PARAMS \ + 74 /* Overlapping BSS Scan Parameters */ +#define ELEM_ID_MBSSID_INDEX \ + 85 /* Multiple BSSID-Index element */ +#define ELEM_ID_EXTENDED_CAP \ + 127 /* Extended capabilities */ + +#define ELEM_ID_INTERWORKING \ + 107 /* Interworking with External Network */ +#define ELEM_ID_ADVERTISEMENT_PROTOCOL \ + 108 /* Advertisement Protocol */ +#define ELEM_ID_QOS_MAP_SET \ + 110 /* QoS Map Set */ +#define ELEM_ID_ROAMING_CONSORTIUM \ + 111 /* Roaming Consortium */ +#define ELEM_ID_EXTENDED_CAP \ + 127 /* Extended capabilities */ + +#if (CFG_SUPPORT_TWT == 1) +#define ELEM_ID_TWT \ + 216 /* Target Wake Time (TWT) @11ah/11ax */ +#endif + +#define ELEM_ID_VENDOR \ + 221 /* Vendor specific IE */ +#define ELEM_ID_WPA \ + ELEM_ID_VENDOR /* WPA IE */ +#define ELEM_ID_WMM \ + ELEM_ID_VENDOR /* WMM IE */ +#define ELEM_ID_P2P \ + ELEM_ID_VENDOR /* WiFi Direct */ +#define ELEM_ID_WSC \ + ELEM_ID_VENDOR /* WSC IE */ + +#define ELEM_ID_VHT_CAP \ + 191 /* VHT Capabilities subelement */ +#define ELEM_ID_VHT_OP \ + 192 /* VHT Operation information */ +#define ELEM_ID_WIDE_BAND_CHANNEL_SWITCH \ + 194 /*Wide Bandwidth Channel Switch */ +#define ELEM_ID_OP_MODE \ + 199 /* Operation Mode Notification */ +#define ELEM_ID_RESERVED \ + 255 /* Reserved */ + +#if CFG_SUPPORT_MBO +/* MBO v0.0_r19, 4.2: MBO Attributes */ +/* Table 4-5: MBO Attributes */ +/* OCE v0.0.10, Table 4-3: OCE Attributes */ +enum MBO_ATTR_ID { + MBO_ATTR_ID_AP_CAPA_IND = 1, + MBO_ATTR_ID_NON_PREF_CHAN_REPORT = 2, + MBO_ATTR_ID_CELL_DATA_CAPA = 3, + MBO_ATTR_ID_ASSOC_DISALLOW = 4, + MBO_ATTR_ID_CELL_DATA_PREF = 5, + MBO_ATTR_ID_TRANSITION_REASON = 6, + MBO_ATTR_ID_TRANSITION_REJECT_REASON = 7, + MBO_ATTR_ID_ASSOC_RETRY_DELAY = 8, + OCE_ATTR_ID_CAPA_IND = 101, + OCE_ATTR_ID_RSSI_BASED_ASSOC_REJECT = 102, + OCE_ATTR_ID_REDUCED_WAN_METRICS = 103, + OCE_ATTR_ID_RNR_COMPLETENESS = 104, +}; +#endif + +/* 7.3.2.1 SSID element */ +#define ELEM_MAX_LEN_SSID 32 + +/* 7.3.2.2 Supported Rates */ +#define ELEM_MAX_LEN_SUP_RATES 8 + +#define ELEM_MAX_LEN_SUP_RATES_IOT 16 + +/* 7.3.2.4 DS Parameter Set */ +#define ELEM_MAX_LEN_DS_PARAMETER_SET 1 + +/* 7.3.2.5 CF Parameter Set */ +#define ELEM_CF_PARM_LEN 8 + +/* 7.3.2.6 TIM */ +#define ELEM_MIX_LEN_TIM 4 +#define ELEM_MAX_LEN_TIM 254 + +/* 7.3.2.7 IBSS Parameter Set element */ +#define ELEM_MAX_LEN_IBSS_PARAMETER_SET 2 + +/* 7.3.2.8 Challenge Text element */ +#define ELEM_MIN_LEN_CHALLENGE_TEXT 1 +#define ELEM_MAX_LEN_CHALLENGE_TEXT 253 + +/* 7.3.2.9 Country Information element */ +/* Country IE should contain at least 3-bytes country + * code string and one subband triplet. + */ +#define ELEM_MIN_LEN_COUNTRY_INFO 6 + +#define ELEM_ID_COUNTRY_INFO_TRIPLET_LEN_FIXED 3 +#define ELEM_ID_COUNTRY_INFO_SUBBAND_TRIPLET_LEN_FIXED 3 +#define ELEM_ID_COUNTRY_INFO_REGULATORY_TRIPLET_LEN_FIXED 3 + +/* 7.3.2.13 ERP Information element */ +#define ELEM_MAX_LEN_ERP 1 +/* -- bits in the ERP Information element */ +/* NonERP_Present bit */ +#define ERP_INFO_NON_ERP_PRESENT BIT(0) +/* Use_Protection bit */ +#define ERP_INFO_USE_PROTECTION BIT(1) +/* Barker_Preamble_Mode bit */ +#define ERP_INFO_BARKER_PREAMBLE_MODE BIT(2) + +#define ELEM_MAX_LEN_SUPPORTED_CHANNELS (MAX_CHN_NUM * 2) + +/* 7.3.2.14 Extended Supported Rates */ +#define ELEM_MAX_LEN_EXTENDED_SUP_RATES 255 + +/* 7.3.2.16 Power Capability element */ +#define ELEM_MAX_LEN_POWER_CAP 2 + + +/* 7.3.2.21 Measurement Request element */ +#define ELEM_RM_TYPE_BASIC_REQ 0 +#define ELEM_RM_TYPE_CCA_REQ 1 +#define ELEM_RM_TYPE_RPI_HISTOGRAM_REQ 2 +#define ELEM_RM_TYPE_CHNL_LOAD_REQ 3 +#define ELEM_RM_TYPE_NOISE_HISTOGRAM_REQ 4 +#define ELEM_RM_TYPE_BEACON_REQ 5 +#define ELEM_RM_TYPE_FRAME_REQ 6 +#define ELEM_RM_TYPE_STA_STATISTICS_REQ 7 +#define ELEM_RM_TYPE_LCI_REQ 8 +#define ELEM_RM_TYPE_TSM_REQ 9 +#define ELEM_RM_TYPE_MEASURE_PAUSE_REQ 255 + +/* 7.3.2.22 Measurement Report element */ +#define ELEM_RM_TYPE_BASIC_REPORT 0 +#define ELEM_RM_TYPE_CCA_REPORT 1 +#define ELEM_RM_TYPE_RPI_HISTOGRAM_REPORT 2 +#define ELEM_RM_TYPE_CHNL_LOAD_REPORT 3 +#define ELEM_RM_TYPE_NOISE_HISTOGRAM_REPORT 4 +#define ELEM_RM_TYPE_BEACON_REPORT 5 +#define ELEM_RM_TYPE_FRAME_REPORT 6 +#define ELEM_RM_TYPE_STA_STATISTICS_REPORT 7 +#define ELEM_RM_TYPE_LCI_REPORT 8 +#define ELEM_RM_TYPE_TSM_REPORT 9 + +/* 7.3.2.37 Subelement IDs for Neighbor Report, Table 7-43b */ +#define ELEM_ID_NR_BSS_TRANSITION_CAND_PREF 3 +#define ELEM_ID_NR_BSS_TERMINATION_DURATION 4 + +/* + * IEEE Std 802.11-2016, Table 9-87 - Measurement Mode definitions for Beacon + * request + */ +enum BEACON_REPORT_MODE { + BEACON_REPORT_MODE_PASSIVE = 0, + BEACON_REPORT_MODE_ACTIVE = 1, + BEACON_REPORT_MODE_TABLE = 2, +}; + +/* IEEE Std 802.11-2016, Table 9-88 - Beacon Request subelement IDs + * IEEE P802.11-REVmd/D2.0, Table 9-106 - Optional subelement IDs for + * Beacon request + */ +#define BEACON_REQUEST_SUBELEM_SSID 0 +#define BEACON_REQUEST_SUBELEM_INFO 1 /* Beacon Reporting */ +#define BEACON_REQUEST_SUBELEM_DETAIL 2 /* Reporting Detail */ +#define BEACON_REQUEST_SUBELEM_REQUEST 10 +#define BEACON_REQUEST_SUBELEM_AP_CHANNEL 51 /* AP Channel Report */ +#define BEACON_REQUEST_SUBELEM_LAST_INDICATION 164 +#define BEACON_REQUEST_SUBELEM_VENDOR 221 + +/* + * IEEE Std 802.11-2016, Table 9-90 - Reporting Detail values + */ +enum BEACON_REPORT_DETAIL { + /* No fixed-length fields or elements */ + BEACON_REPORT_DETAIL_NONE = 0, + /* All fixed-length fields and any requested elements in the Request + * element if resent + */ + BEACON_REPORT_DETAIL_REQUESTED_ONLY = 1, + /* All fixed-length fields and elements (default, used when Reporting + * Detail subelement is not included in a Beacon request) + */ + BEACON_REPORT_DETAIL_ALL_FIELDS_AND_ELEMENTS = 2, +}; + +/* IEEE Std 802.11-2016, Table 9-112 - Beacon report Subelement IDs + * IEEE P802.11-REVmd/D2.0, Table 9-130 - Optional subelement IDs for + * Beacon report + */ +#define BEACON_REPORT_SUBELEM_FRAME_BODY 1 +#define BEACON_REPORT_SUBELEM_FRAME_BODY_FRAGMENT_ID 2 +#define BEACON_REPORT_SUBELEM_LAST_INDICATION 164 +#define BEACON_REPORT_SUBELEM_VENDOR 221 + +/* IEEE P802.11-REVmd/D2.0, Table 9-232 - Data field format of the + * Reported Frame Body Fragment ID subelement + */ +#define REPORTED_FRAME_BODY_SUBELEM_LEN 4 +#define REPORTED_FRAME_BODY_MORE_FRAGMENTS BIT(7) + +/* IEEE P802.11-REVmd/D2.0, 9.4.2.21.7 - Beacon report */ +#define BEACON_REPORT_LAST_INDICATION_SUBELEM_LEN 3 + +/* IEEE Std 802.11-2016, Figure 9-192 - Measurement Report Mode field */ +#define MEASUREMENT_REPORT_MODE_ACCEPT 0 +#define MEASUREMENT_REPORT_MODE_REJECT_LATE BIT(0) +#define MEASUREMENT_REPORT_MODE_REJECT_INCAPABLE BIT(1) +#define MEASUREMENT_REPORT_MODE_REJECT_REFUSED BIT(2) + +/* 7.3.2.25 RSN information element */ +/* two pairwise, one AKM suite, one PMKID */ +#define ELEM_MAX_LEN_WPA 38 +/* two pairwise, one AKM suite, one PMKID */ +#define ELEM_MAX_LEN_RSN 42 +/* one pairwise, one AKM suite, one BKID */ +#define ELEM_MAX_LEN_WAPI 38 +/* one pairwise, one AKM suite, one BKID */ +#define ELEM_MAX_LEN_WSC 200 + +#if CFG_SUPPORT_802_11W +#define ELEM_WPA_CAP_MFPR BIT(6) +#define ELEM_WPA_CAP_MFPC BIT(7) +#endif + +/* 7.3.2.27 Extended Capabilities information element */ +#define ELEM_EXT_CAP_20_40_COEXIST_SUPPORT BIT(0) +#define ELEM_EXT_CAP_PSMP_CAP BIT(4) +#define ELEM_EXT_CAP_SERVICE_INTERVAL_GRANULARITY BIT(5) +#define ELEM_EXT_CAP_SCHEDULE_PSMP BIT(6) + +#define ELEM_EXT_CAP_BSS_TRANSITION_BIT 19 +#define ELEM_EXT_CAP_MBSSID_BIT 22 +#define ELEM_EXT_CAP_UTC_TSF_OFFSET_BIT 27 +#define ELEM_EXT_CAP_INTERWORKING_BIT 31 +#define ELEM_EXT_CAP_QOSMAPSET_BIT 32 +#define ELEM_EXT_CAP_WNM_NOTIFICATION_BIT 46 +#define ELEM_EXT_CAP_WNM_NOTIFICATION_BIT 46 +#define ELEM_EXT_CAP_OP_MODE_NOTIFICATION_BIT 62 +#if (CFG_SUPPORT_TWT == 1) +#define ELEM_EXT_CAP_TWT_REQUESTER_BIT 77 +#endif + +#define ELEM_MAX_LEN_EXT_CAP_11ABGNAC (8) + +#if (CFG_SUPPORT_802_11AX == 1) +#define ELEM_MAX_LEN_EXT_CAP (10) +#else +#define ELEM_MAX_LEN_EXT_CAP (8) +#endif + +/* 7.3.2.30 TSPEC element */ +/* WMM: 0 (Asynchronous TS of low-duty cycles) */ +#define TS_INFO_TRAFFIC_TYPE_MASK BIT(0) +#define TS_INFO_TID_OFFSET 1 +#define TS_INFO_TID_MASK BITS(1, 4) +#define TS_INFO_DIRECTION_OFFSET 5 +#define TS_INFO_DIRECTION_MASK BITS(5, 6) +#define TS_INFO_ACCESS_POLICY_OFFSET 7 +#define TS_INFO_ACCESS_POLICY_MASK BITS(7, 8) +#define TS_INFO_AGGREGATION_MASK BIT(9) /* WMM: 0 */ +#define TS_INFO_APSD_MASK BIT(10) +#define TS_INFO_UP_OFFSET 11 +#define TS_INFO_UP_MASK BITS(11, 13) +#define TS_INFO_ACK_POLICY_OFFSET 14 +#define TS_INFO_ACK_POLICY_MASK BITS(14, 15) +#define TS_INFO_SCHEDULE_MASK 16 + +/* 7.3.2.45 RRM Enabled Capbility element */ +#define ELEM_MAX_LEN_RRM_CAP 5 +#define RRM_CAP_INFO_LINK_MEASURE_BIT 0 +#define RRM_CAP_INFO_NEIGHBOR_REPORT_BIT 1 +#define RRM_CAP_INFO_REPEATED_MEASUREMENT 3 +#define RRM_CAP_INFO_BEACON_PASSIVE_MEASURE_BIT 4 +#define RRM_CAP_INFO_BEACON_ACTIVE_MEASURE_BIT 5 +#define RRM_CAP_INFO_BEACON_TABLE_BIT 6 +#define RRM_CAP_INFO_TSM_BIT 14 +#define RRM_CAP_INFO_RRM_BIT 17 + +/* 7.3.2.56 HT capabilities element */ +#define ELEM_MAX_LEN_HT_CAP \ + (28 - ELEM_HDR_LEN) /* sizeof(IE_HT_CAP_T)-2 */ + +/* 7.3.2.56.2 HT capabilities Info field */ +#define HT_CAP_INFO_LDPC_CAP BIT(0) +#define HT_CAP_INFO_SUP_CHNL_WIDTH BIT(1) +#define HT_CAP_INFO_SM_POWER_SAVE BITS(2, 3) +#define HT_CAP_INFO_SM_POWER_SAVE_OFFSET 2 +#define HT_CAP_INFO_HT_GF BIT(4) +#define HT_CAP_INFO_SHORT_GI_20M BIT(5) +#define HT_CAP_INFO_SHORT_GI_40M BIT(6) +#define HT_CAP_INFO_TX_STBC BIT(7) +#define HT_CAP_INFO_RX_STBC BITS(8, 9) +#define HT_CAP_INFO_HT_DELAYED_BA BIT(10) +#define HT_CAP_INFO_MAX_AMSDU_LEN BIT(11) +#define HT_CAP_INFO_DSSS_CCK_IN_40M BIT(12) +#define HT_CAP_INFO_40M_INTOLERANT BIT(14) +#define HT_CAP_INFO_LSIG_TXOP_SUPPORT BIT(15) + +#define HT_CAP_INFO_RX_STBC_NO_SUPPORTED 0 +#define HT_CAP_INFO_RX_STBC_1_SS BIT(8) +#define HT_CAP_INFO_RX_STBC_2_SS BIT(9) +#define HT_CAP_INFO_RX_STBC_3_SS HT_CAP_INFO_RX_STBC + +#define ELEM_MAX_LEN_VHT_CAP \ + (14 - ELEM_HDR_LEN) /* sizeof(IE_VHT_CAP_T)-2 */ +/* 8.4.2.161 VHT Operation element */ +#define ELEM_MAX_LEN_VHT_OP \ + (7 - ELEM_HDR_LEN) /* sizeof(IE_VHT_OP_T)-2 */ + +#define ELEM_MAX_LEN_VHT_OP_MODE_NOTIFICATION \ + (3 - ELEM_HDR_LEN) /* sizeof(IE_VHT_OP_MODE_T)-2 */ + +/*8.4.2.160.3 VHT Supported MCS Set field*/ + +/*8.4.2.160.2 VHT Capabilities Info field*/ +#define VHT_CAP_INFO_MAX_MPDU_LEN_3K 0 +#define VHT_CAP_INFO_MAX_MPDU_LEN_8K BIT(0) +#define VHT_CAP_INFO_MAX_MPDU_LEN_11K BIT(1) +#define VHT_CAP_INFO_MAX_MPDU_LEN_MASK BITS(0, 1) + +#define VHT_CAP_INFO_MAX_SUP_CHANNEL_WIDTH_SET_NONE 0 +#define VHT_CAP_INFO_MAX_SUP_CHANNEL_WIDTH_SET_160 BIT(2) +#define VHT_CAP_INFO_MAX_SUP_CHANNEL_WIDTH_SET_160_80P80 BIT(3) +#define VHT_CAP_INFO_MAX_SUP_CHANNEL_WIDTH_MASK BITS(2, 3) + +#define VHT_CAP_INFO_RX_LDPC BIT(4) +#define VHT_CAP_INFO_SHORT_GI_80 BIT(5) +#define VHT_CAP_INFO_SHORT_GI_160_80P80 BIT(6) +#define VHT_CAP_INFO_TX_STBC BIT(7) + +#define VHT_CAP_INFO_RX_STBC_NONE 0 +#define VHT_CAP_INFO_RX_STBC_MASK BITS(8, 10) +#define VHT_CAP_INFO_RX_STBC_OFFSET 8 +#define VHT_CAP_INFO_RX_STBC_ONE_STREAM BIT(8) +#define VHT_CAP_INFO_RX_STBC_TWO_STREAM BIT(9) +#define VHT_CAP_INFO_RX_STBC_THREE_STREAM BITS(8, 9) +#define VHT_CAP_INFO_RX_STBC_FOUR_STREAM BIT(10) + +#define VHT_CAP_INFO_SU_BEAMFORMER_CAPABLE BIT(11) +#define VHT_CAP_INFO_SU_BEAMFORMEE_CAPABLE BIT(12) + +/* VHT_CAP_INFO_COMPRESSED_STEERING_NUMBER_OF + * _BEAMFORMER_ANTENNAS_SUPPOERTED + */ +#define VHT_CAP_INFO_COMPRESSED_STEERING_NUMBER_OF_BEAMFORMER_ANTENNAS_SUP_OFF \ + 13 +#define VHT_CAP_INFO_COMPRESSED_STEERING_NUMBER_OF_BEAMFORMER_ANTENNAS_SUP \ + BITS(13, 15) +#define VHT_CAP_INFO_COMPRESSED_STEERING_NUMBER_OF_BEAMFORMER_ANTENNAS_2_SUP \ + BIT(13) +#define VHT_CAP_INFO_COMPRESSED_STEERING_NUMBER_OF_BEAMFORMER_ANTENNAS_3_SUP \ + BIT(14) +#define VHT_CAP_INFO_COMPRESSED_STEERING_NUMBER_OF_BEAMFORMER_ANTENNAS_4_SUP \ + BITS(13, 14) + +#define VHT_CAP_INFO_NUMBER_OF_SOUNDING_DIMENSIONS_OFFSET 16 +#define VHT_CAP_INFO_NUMBER_OF_SOUNDING_DIMENSIONS BITS(16, 18) +#define VHT_CAP_INFO_NUMBER_OF_SOUNDING_DIMENSIONS_2_SUPPORTED BIT(16) +#define VHT_CAP_INFO_NUMBER_OF_SOUNDING_DIMENSIONS_3_SUPPORTED BIT(17) +#define VHT_CAP_INFO_NUMBER_OF_SOUNDING_DIMENSIONS_4_SUPPORTED BITS(16, 17) + +#define VHT_CAP_INFO_MU_BEAMFOMER_CAPABLE BIT(19) +#define VHT_CAP_INFO_MU_BEAMFOMEE_CAPABLE BIT(20) +#define VHT_CAP_INFO_VHT_TXOP_PS BIT(21) +#define VHT_CAP_INFO_HTC_VHT_CAPABLE BIT(22) + +#define VHT_CAP_INFO_MAX_AMPDU_LENGTH_OFFSET 23 + +#define VHT_CAP_INFO_VHT_LINK_ADAPTATION_CAPABLE_NOFEEDBACK 0 +#define VHT_CAP_INFO_VHT_LINK_ADAPTATION_CAPABLE_UNSOLICITED BITS(27) +#define VHT_CAP_INFO_VHT_LINK_ADAPTATION_CAPABLE_BOTH BITS(26, 27) + +#define VHT_CAP_INFO_RX_ANTENNA_PATTERN_CONSISTENCY BIT(28) +#define VHT_CAP_INFO_TX_ANTENNA_PATTERN_CONSISTENCY BIT(29) + +#define VHT_CAP_INFO_MCS_MAP_MCS7 0 +#define VHT_CAP_INFO_MCS_MAP_MCS8 BIT(0) +#define VHT_CAP_INFO_MCS_MAP_MCS9 BIT(1) +#define VHT_CAP_INFO_MCS_NOT_SUPPORTED BITS(0, 1) + +#define VHT_CAP_INFO_MCS_1SS_OFFSET 0 +#define VHT_CAP_INFO_MCS_2SS_OFFSET 2 +#define VHT_CAP_INFO_MCS_3SS_OFFSET 4 +#define VHT_CAP_INFO_MCS_4SS_OFFSET 6 +#define VHT_CAP_INFO_MCS_5SS_OFFSET 8 +#define VHT_CAP_INFO_MCS_6SS_OFFSET 10 +#define VHT_CAP_INFO_MCS_7SS_OFFSET 12 +#define VHT_CAP_INFO_MCS_8SS_OFFSET 14 + +#define VHT_CAP_INFO_MCS_1SS_MASK BITS(0, 1) +#define VHT_CAP_INFO_MCS_2SS_MASK BITS(2, 3) +#define VHT_CAP_INFO_MCS_3SS_MASK BITS(4, 5) +#define VHT_CAP_INFO_MCS_4SS_MASK BITS(6, 7) +#define VHT_CAP_INFO_MCS_5SS_MASK BITS(8, 9) +#define VHT_CAP_INFO_MCS_6SS_MASK BITS(10, 11) +#define VHT_CAP_INFO_MCS_7SS_MASK BITS(12, 13) +#define VHT_CAP_INFO_MCS_8SS_MASK BITS(14, 15) + +#define VHT_OP_CHANNEL_WIDTH_20_40 0 +#define VHT_OP_CHANNEL_WIDTH_80 1 +#define VHT_OP_CHANNEL_WIDTH_160 2 +#define VHT_OP_CHANNEL_WIDTH_80P80 3 + +/*8.4.1.50 Operating Mode Field*/ +#define VHT_OP_MODE_CHANNEL_WIDTH BITS(0, 1) +#define VHT_OP_MODE_RX_NSS BITS(4, 6) +#define VHT_OP_MODE_RX_NSS_TYPE BIT(7) + +#define VHT_OP_MODE_NSS_1 0x00 +#define VHT_OP_MODE_NSS_2 0x01 + +#define VHT_OP_MODE_CHANNEL_WIDTH_OFFSET 0 +#define VHT_OP_MODE_RX_NSS_OFFSET 4 +#define VHT_OP_MODE_RX_NSS_TYPE_OFFSET 7 + +#define VHT_OP_MODE_CHANNEL_WIDTH_20 0 +#define VHT_OP_MODE_CHANNEL_WIDTH_40 1 +#define VHT_OP_MODE_CHANNEL_WIDTH_80 2 +#define VHT_OP_MODE_CHANNEL_WIDTH_160_80P80 3 + +/* 8.4.1.22 SM Power Control field*/ +#define HT_SM_POWER_SAVE_CONTROL_ENABLED BIT(0) +/* 0:static, 1:dynamic */ +#define HT_SM_POWER_SAVE_CONTROL_SM_MODE BIT(1) +#define HT_SM_POWER_SAVE_CONTROL_SM_MODE_OFFSET 1 + +/* 8.4.1.21 Channel Width field */ +#define HT_NOTIFY_CHANNEL_WIDTH_20 0 +#define HT_NOTIFY_CHANNEL_WIDTH_ANY_SUPPORT_CAHNNAEL_WIDTH 1 + +/* 7.3.2.56.3 A-MPDU Parameters field */ +#define AMPDU_PARAM_MAX_AMPDU_LEN_EXP BITS(0, 1) +#define AMPDU_PARAM_MIN_START_SPACING BITS(2, 4) + +#define AMPDU_PARAM_MAX_AMPDU_LEN_8K 0 +#define AMPDU_PARAM_MAX_AMPDU_LEN_16K BIT(0) +#define AMPDU_PARAM_MAX_AMPDU_LEN_32K BIT(1) +#define AMPDU_PARAM_MAX_AMPDU_LEN_64K BITS(0, 1) +#define AMPDU_PARAM_MAX_AMPDU_LEN_128K BIT(2) +#define AMPDU_PARAM_MAX_AMPDU_LEN_256K (BIT(2) | BIT(0)) +#define AMPDU_PARAM_MAX_AMPDU_LEN_512K BITS(1, 2) +#define AMPDU_PARAM_MAX_AMPDU_LEN_1024K BITS(0, 2) + +#define AMPDU_PARAM_MSS_NO_RESTRICIT 0 +#define AMPDU_PARAM_MSS_1_4_US BIT(2) +#define AMPDU_PARAM_MSS_1_2_US BIT(3) +#define AMPDU_PARAM_MSS_1_US BITS(2, 3) +#define AMPDU_PARAM_MSS_2_US BIT(4) +#define AMPDU_PARAM_MSS_4_US (BIT(4) | BIT(2)) +#define AMPDU_PARAM_MSS_8_US (BIT(4) | BIT(3)) +#define AMPDU_PARAM_MSS_16_US BITS(2, 4) + +/* 7.3.2.56.4 Supported MCS Set field (TX rate: octects 12~15) */ +#define SUP_MCS_TX_SET_DEFINED BIT(0) +#define SUP_MCS_TX_RX_SET_NOT_EQUAL BIT(1) +#define SUP_MCS_TX_MAX_NUM_SS BITS(2, 3) +#define SUP_MCS_TX_UNEQUAL_MODULATION BIT(4) + +#define SUP_MCS_TX_MAX_NUM_1_SS 0 +#define SUP_MCS_TX_MAX_NUM_2_SS BIT(2) +#define SUP_MCS_TX_MAX_NUM_3_SS BIT(3) +#define SUP_MCS_TX_MAX_NUM_4_SS BITS(2, 3) + +#define SUP_MCS_RX_BITMASK_OCTET_NUM 10 +#define SUP_MCS_RX_DEFAULT_HIGHEST_RATE 0 /* Not specify */ + +/* 7.3.2.56.5 HT Extended Capabilities field */ +#define HT_EXT_CAP_PCO BIT(0) +#define HT_EXT_CAP_PCO_TRANSITION_TIME BITS(1, 2) +#define HT_EXT_CAP_MCS_FEEDBACK BITS(8, 9) +#define HT_EXT_CAP_HTC_SUPPORT BIT(10) +#define HT_EXT_CAP_RD_RESPONDER BIT(11) + +#define HT_EXT_CAP_PCO_TRANS_TIME_NONE 0 +#define HT_EXT_CAP_PCO_TRANS_TIME_400US BIT(1) +#define HT_EXT_CAP_PCO_TRANS_TIME_1_5MS BIT(2) +#define HT_EXT_CAP_PCO_TRANS_TIME_5MS BITS(1, 2) + +#define HT_EXT_CAP_MCS_FEEDBACK_NO_FB 0 +#define HT_EXT_CAP_MCS_FEEDBACK_UNSOLICITED BIT(9) +#define HT_EXT_CAP_MCS_FEEDBACK_BOTH BITS(8, 9) + +/* 7.3.2.56.6 Transmit Beamforming Capabilities field */ +#define TXBF_IMPLICIT_RX_CAPABLE BIT(0) +#define TXBF_RX_STAGGERED_SOUNDING_CAPABLE BIT(1) +#define TXBF_TX_STAGGERED_SOUNDING_CAPABLE BIT(2) +#define TXBF_RX_NDP_CAPABLE BIT(3) +#define TXBF_TX_NDP_CAPABLE BIT(4) +#define TXBF_IMPLICIT_TX_CAPABLE BIT(5) +#define TXBF_CALIBRATION_CAPABLE BITS(6, 7) +#define TXBF_EXPLICIT_CSI_TX_CAPABLE BIT(8) +#define TXBF_EXPLICIT_NONCOMPRESSED_TX_CAPABLE BIT(9) +#define TXBF_EXPLICIT_COMPRESSED_TX_CAPAB BIT(10) +#define TXBF_EXPLICIT_CSI_FEEDBACK_CAPABLE BITS(11, 12) +#define TXBF_EXPLICIT_NONCOMPRESSED_FEEDBACK_CAPABLE BITS(13, 14) + +#define TXBF_EXPLICIT_COMPRESSED_FEEDBACK_CAPABLE BITS(15, 16) +#define TXBF_EXPLICIT_COMPRESSED_FEEDBACK_IMMEDIATE_CAPABLE BIT(16) + +#define TXBF_MINIMAL_GROUPING_CAPABLE BITS(17, 18) +#define TXBF_MINIMAL_GROUPING_1_2_3_CAPABLE BITS(17, 18) + +#define TXBF_CSI_BFER_ANTENNANUM_SUPPORTED BITS(19, 20) +#define TXBF_NONCOMPRESSED_TX_ANTENNANUM_SUPPORTED BITS(21, 22) + +#define TXBF_COMPRESSED_TX_ANTENNANUM_SUPPORTED BITS(23, 24) +#define TXBF_COMPRESSED_TX_ANTENNANUM_4_SUPPORTED BITS(23, 24) + +#define TXBF_CSI_MAX_ROWS_BFER_SUPPORTED BITS(25, 26) + +#define TXBF_CHANNEL_ESTIMATION_CAPABILITY BITS(27, 28) +#define TXBF_CHANNEL_ESTIMATION_4STS_CAPABILITY BITS(27, 28) + +/* 7.3.2.56.7 Antenna Selection Capability field */ +#define ASEL_CAP_CAPABLE BIT(0) +#define ASEL_CAP_CSI_FB_BY_TX_ASEL_CAPABLE BIT(1) +#define ASEL_CAP_ANT_INDICES_FB_BY_TX_ASEL_CAPABLE BIT(2) +#define ASEL_CAP_EXPLICIT_CSI_FB_CAPABLE BIT(3) +#define ASEL_CAP_ANT_INDICES_CAPABLE BIT(4) +#define ASEL_CAP_RX_ASEL_CAPABLE BIT(5) +#define ASEL_CAP_TX_SOUNDING_CAPABLE BIT(6) + +/* 7.3.2.57 HT Operation element */ +/* sizeof(IE_HT_OP_T)-2 */ +#define ELEM_MAX_LEN_HT_OP (24 - ELEM_HDR_LEN) + +#define HT_OP_INFO1_SCO BITS(0, 1) +#define HT_OP_INFO1_STA_CHNL_WIDTH BIT(2) +#define HT_OP_INFO1_RIFS_MODE BIT(3) + +#define HT_OP_INFO1_STA_CHNL_WIDTH_OFFSET 2 + +#define HT_OP_INFO2_HT_PROTECTION BITS(0, 1) +#define HT_OP_INFO2_NON_GF_HT_STA_PRESENT BIT(2) +#define HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT BIT(4) + +#define HT_OP_INFO3_DUAL_BEACON BIT(6) +#define HT_OP_INFO3_DUAL_CTS_PROTECTION BIT(7) +#define HT_OP_INFO3_STBC_BEACON BIT(8) +#define HT_OP_INFO3_LSIG_TXOP_FULL_SUPPORT BIT(9) +#define HT_OP_INFO3_PCO_ACTIVE BIT(10) +#define HT_OP_INFO3_PCO_PHASE BIT(11) + +/* 7.3.2.59 OBSS Scan Parameter element */ +#define ELEM_MAX_LEN_OBSS_SCAN (16 - ELEM_HDR_LEN) + +/* 7.3.2.60 20/40 BSS Coexistence element */ +#define ELEM_MAX_LEN_20_40_BSS_COEXIST (3 - ELEM_HDR_LEN) + +#define BSS_COEXIST_INFO_REQ BIT(0) +#define BSS_COEXIST_40M_INTOLERANT BIT(1) +#define BSS_COEXIST_20M_REQ BIT(2) +#define BSS_COEXIST_OBSS_SCAN_EXEMPTION_REQ BIT(3) +#define BSS_COEXIST_OBSS_SCAN_EXEMPTION_GRANT BIT(4) + +/* 802.11u 7.3.2.92 Interworking IE */ +#define ELEM_MAX_LEN_INTERWORKING (11 - ELEM_HDR_LEN) + +/* 802.11u 7.3.2.93 Advertisement Protocol IE */ +#define ELEM_MAX_LEN_ADV_PROTOCOL (4 - ELEM_HDR_LEN) + +/* 802.11u 7.3.2.96 Roaming Consortium IE */ +#define ELEM_MAX_LEN_ROAMING_CONSORTIUM (19 - ELEM_HDR_LEN) + +#define IW_IE_LENGTH_ANO 1 +#define IW_IE_LENGTH_ANO_VENUE 3 +#define IW_IE_LENGTH_ANO_HESSID 7 +#define IW_IE_LENGTH_ANO_VENUE_HESSID 9 + +#if CFG_SUPPORT_PASSPOINT +/* HOTSPOT 2.0 Indication IE*/ +#define ELEM_MAX_LEN_HS20_INDICATION 5 +#define ELEM_MIN_LEN_HS20_INDICATION 4 + +/* Hotspot Configuration*/ +/* Downstream Group-Addressed Forwarding */ +#define ELEM_HS_CONFIG_DGAF_DISABLED_MASK BIT(0) +#endif /* CFG_SUPPORT_PASSPOINT */ + +/* MTK Vendor Specific OUI */ +#define ELEM_MIN_LEN_MTK_OUI 7 +#define VENDOR_OUI_MTK { 0x00, 0x0C, 0xE7 } +#define MTK_SYNERGY_CAP_SUPPORT_24G_MCS89 BIT(3) +#define MTK_SYNERGY_CAP_SUPPORT_24G_MCS89_PROBING BIT(4) +#define MTK_SYNERGY_CAP0 \ + (MTK_SYNERGY_CAP_SUPPORT_24G_MCS89) +#define MTK_SYNERGY_CAP1 0x0 +#define MTK_SYNERGY_CAP2 0x0 +#define MTK_SYNERGY_CAP3 0x0 + +/* 802.11h CSA element */ +#define ELEM_MIN_LEN_CSA 3 + +/* 3 Management frame body components (III): 7.4 Action frame format details. */ +/* 7.4.1 Spectrum Measurement Action frame details */ +/* Spectrum measurement request */ +#define ACTION_MEASUREMENT_REQ 0 +/* Spectrum measurement report */ +#define ACTION_MEASUREMENT_REPORT 1 +/* TPC request */ +#define ACTION_TPC_REQ 2 +/* TPC report */ +#define ACTION_TPC_REPORT 3 +/* Channel Switch Announcement */ +#define ACTION_CHNL_SWITCH 4 + +#define ACTION_SM_TPC_REQ_LEN 5 +#define ACTION_SM_TPC_REPORT_LEN 7 +#define ACTION_SM_MEASURE_REQ_LEN 19 +#define ACTION_SM_MEASURE_REPORT_LEN 8 +#define ACTION_SM_BASIC_REPORT_LEN 12 +#define ACTION_SM_CCA_REPORT_LEN 12 +#define ACTION_SM_PRI_REPORT_LEN 19 +/* Negative value ((dBm) */ +#define MIN_RCV_PWR 100 + +/* 7.4.2 QoS Action frame details */ +#define ACTION_ADDTS_REQ 0 /* ADDTS request */ +#define ACTION_ADDTS_RSP 1 /* ADDTS response */ +#define ACTION_DELTS 2 /* DELTS */ +#define ACTION_SCHEDULE 3 /* Schedule */ +#define ACTION_QOS_MAP_CONFIGURE 4 /*Qos Map Configure*/ + +/* WMM TSPEC IE: 63 */ +#define ACTION_ADDTS_REQ_FRAME_LEN (24+3+63) +/* WMM Status Code: 1; WMM TSPEC IE: 63 */ +#define ACTION_ADDTS_RSP_FRAME_LEN (24 + 4 + 63) +/*category + action + WMM TSinfo:3 + reason:2*/ +#define ACTION_DELTS_FRAME_LEN (24 + 7) + +/* 7.4.3 DLS Action frame details */ +#define ACTION_DLS_REQ 0 /* DLS request */ +#define ACTION_DLS_RSP 1 /* DLS response */ +#define ACTION_DLS_TEARDOWN 2 /* DLS teardown */ + +/* 7.4.4 Block ack Action frame details */ +#define ACTION_ADDBA_REQ 0 /* ADDBA request */ +#define ACTION_ADDBA_RSP 1 /* ADDBA response */ +#define ACTION_DELBA 2 /* DELBA */ + +#define ACTION_ADDBA_REQ_FRAME_LEN (24+9) +#define ACTION_ADDBA_RSP_FRAME_LEN (24+9) + +#define ACTION_DELBA_INITIATOR_MASK BIT(11) +#define ACTION_DELBA_TID_MASK BITS(12, 15) +#define ACTION_DELBA_TID_OFFSET 12 +#define ACTION_DELBA_FRAME_LEN (24+6) + +/* 7.4.6 Radio Measurement Action frame details */ +/* Radio measurement request */ +#define ACTION_RM_REQ 0 +/* Radio measurement report */ +#define ACTION_RM_REPORT 1 +/* Link measurement request */ +#define ACTION_LM_REQ 2 +/* Link measurement report */ +#define ACTION_LM_REPORT 3 +/* Neighbor report request */ +#define ACTION_NEIGHBOR_REPORT_REQ 4 +/* Neighbor report response */ +#define ACTION_NEIGHBOR_REPORT_RSP 5 + +/* 7.4.7 Public Action frame details */ +/* 20/40 BSS coexistence */ +#define ACTION_PUBLIC_20_40_COEXIST 0 +/* 20/40 BSS coexistence */ +#define ACTION_PUBLIC_VENDOR_SPECIFIC 9 + +#if CFG_SUPPORT_802_11W +/* SA Query Action frame (IEEE 802.11w/D8.0, 7.4.9) */ +#define ACTION_SA_QUERY_REQUEST 0 +#define ACTION_SA_QUERY_RESPONSE 1 + +#define ACTION_SA_QUERY_TR_ID_LEN 2 + +/* Timeout Interval Type */ +#define ACTION_SA_TIMEOUT_REASSOC_DEADLINE 1 +#define ACTION_SA_TIMEOUT_KEY_LIFETIME 2 +#define ACTION_SA_TIMEOUT_ASSOC_COMEBACK 3 +#endif + +/* 7.4.10.1 HT action frame details */ +/* Notify Channel Width */ +#define ACTION_HT_NOTIFY_CHANNEL_WIDTH 0 +/* SM Power Save */ +#define ACTION_HT_SM_POWER_SAVE 1 +/* PSMP */ +#define ACTION_HT_PSMP 2 +/* Set PCO Phase */ +#define ACTION_HT_SET_PCO_PHASE 3 +/* CSI */ +#define ACTION_HT_CSI 4 +/* Non-compressed Beamforming */ +#define ACTION_HT_NON_COMPRESSED_BEAMFORM 5 +/* Compressed Beamforming */ +#define ACTION_HT_COMPRESSED_BEAMFORM 6 +/* Antenna Selection Indices Feedback */ +#define ACTION_HT_ANT_SEL_INDICES_FB 7 + +#define ACTION_WNM_NOTIFICATION_REQUEST 26 +/* 802.11v Wireless Network Management */ +#define ACTION_WNM_TIMING_MEASUREMENT_REQUEST 27 + +#define ACTION_UNPROTECTED_WNM_TIM 0 +#define ACTION_UNPROTECTED_WNM_TIMING_MEASUREMENT 1 +#define ACTION_WNM_BSS_TRANSITION_MANAGEMENT_QUERY 6 +#define ACTION_WNM_BSS_TRANSITION_MANAGEMENT_REQ 7 +#define ACTION_WNM_BSS_TRANSITION_MANAGEMENT_RSP 8 +#define ACTION_UNPROTECTED_WNM_TIMING_MEAS_LEN 12 + +/* 8.5.23.1 VHT Action */ +#define ACTION_VHT_COMPRESSED_BFEAMFORMING 0 +#define ACTION_GROUP_ID_MANAGEMENT 1 +#define ACTION_OPERATING_MODE_NOTIFICATION 2 + +#if (CFG_SUPPORT_TWT == 1) +/* S1G Action */ +#define ACTION_S1G_TWT_SETUP 6 +#define ACTION_S1G_TWT_TEARDOWN 7 +#define ACTION_S1G_TWT_INFORMATION 11 +#endif + +/* 3 --------------- WFA frame body fields --------------- */ +#define VENDOR_OUI_WFA { 0x00, 0x50, 0xF2 } +#define VENDOR_OUI_WFA_SPECIFIC { 0x50, 0x6F, 0x9A } +#define VENDOR_OUI_TYPE_WPA 1 +#define VENDOR_OUI_TYPE_WMM 2 +#define VENDOR_OUI_TYPE_WPS 4 +#define VENDOR_OUI_TYPE_P2P 9 +#define VENDOR_OUI_TYPE_WFD 10 + +/* Epigram IE */ +#define VENDOR_IE_EPIGRAM_OUI 0x00904c +#define VENDOR_IE_EPIGRAM_VHTTYPE1 0x0400 +#define VENDOR_IE_EPIGRAM_VHTTYPE2 0x0408 +#define VENDOR_IE_EPIGRAM_VHTTYPE3 0x0418 + +/* Cisco IE */ +#define VENDOR_IE_CISCO_OUI 0x004096 +#define VENDOR_IE_CISCO_TYPE 0x2C + +#if CFG_SUPPORT_PASSPOINT +#define VENDOR_OUI_TYPE_HS20 16 +#endif /* CFG_SUPPORT_PASSPOINT */ + +/* Length of OUI and Type */ +#define VENDOR_OUI_TYPE_LEN 4 + +/* VERSION(2 octets for WPA) / SUBTYPE(1 octet)-VERSION(1 octet) + * fields for WMM in WFA IE + */ +/* Little Endian Format */ +#define VERSION_WPA 0x0001 +#define VENDOR_OUI_SUBTYPE_VERSION_WMM_INFO 0x0100 +#define VENDOR_OUI_SUBTYPE_VERSION_WMM_PARAM 0x0101 + +/* SUBTYPE(1 octet) for WMM */ +/* WMM Spec version 1.1 */ +#define VENDOR_OUI_SUBTYPE_WMM_INFO 0x00 +#define VENDOR_OUI_SUBTYPE_WMM_PARAM 0x01 +#define VENDOR_OUI_SUBTYPE_WMM_TSPEC 0x02 + +/* VERSION(1 octet) for WMM */ +/* WMM Spec version 1.1 */ +#define VERSION_WMM 0x01 + +/* WMM-2.1.6 QoS Control Field */ +#define WMM_QC_UP_MASK BITS(0, 2) +#define WMM_QC_EOSP BIT(4) +#define WMM_QC_ACK_POLICY_MASK BITS(5, 6) +#define WMM_QC_ACK_POLICY_OFFSET 5 +#define WMM_QC_ACK_POLICY_ACKNOWLEDGE 0 +#define WMM_QC_ACK_POLICY_NOT_ACKNOWLEDGE \ + (1 << WMM_QC_ACK_POLICY_OFFSET) + +/* WMM-2.2.1 WMM Information Element */ +#define ELEM_MIN_LEN_WFA_OUI_TYPE_SUBTYPE 6 + +/* 3 Control frame body */ +/* 7.2.1.7 BlockAckReq */ +#define CTRL_BAR_BAR_CONTROL_OFFSET 16 +#define CTRL_BAR_BAR_CONTROL_TID_OFFSET 12 +#define CTRL_BAR_BAR_INFORMATION_OFFSET 18 +#define CTRL_BAR_BAR_INFORMATION_SSN_OFFSET 4 + +/* 802.11-2012, 8.5.7 Radio Measurement action fields, table 8-206 */ +#define RM_ACTION_RM_REQUEST 0 +#define RM_ACTION_RM_REPORT 1 +#define RM_ACTION_LM_REQUEST 2 +#define RM_ACTION_LM_REPORT 3 +#define RM_ACTION_NEIGHBOR_REQUEST 4 +#define RM_ACTION_REIGHBOR_RESPONSE 5 + +#if (CFG_SUPPORT_TWT == 1) +/* TWT element */ +#define TWT_CTRL_NDP_PAGING_INDICATOR BIT(0) +#define TWT_CTRL_RESPONDER_PM_MODE BIT(1) +#define TWT_CTRL_BROADCAST BIT(2) +#define TWT_CTRL_WAKE_TBTT_NEGOTIATION BIT(3) + +#define TWT_REQ_TYPE_TWT_REQUEST BIT(0) +#define TWT_REQ_TYPE_TWT_SETUP_COMMAND BITS(1, 3) +#define TWT_REQ_TYPE_TRIGGER BIT(4) +#define TWT_REQ_TYPE_IMPLICIT_LAST_BCAST_PARAM BIT(5) +#define TWT_REQ_TYPE_FLOWTYPE BIT(6) +#define TWT_REQ_TYPE_TWT_FLOW_IDENTIFIER BITS(7, 9) +#define TWT_REQ_TYPE_TWT_WAKE_INTVAL_EXP BITS(10, 14) +#define TWT_REQ_TYPE_TWT_PROTECTION BIT(15) + +#define TWT_REQ_TYPE_TWT_REQUEST_OFFSET 0 +#define TWT_REQ_TYPE_TWT_SETUP_COMMAND_OFFSET 1 +#define TWT_REQ_TYPE_TRIGGER_OFFSET 4 +#define TWT_REQ_TYPE_IMPLICIT_LAST_BCAST_PARAM_OFFSET 5 +#define TWT_REQ_TYPE_FLOWTYPE_OFFSET 6 +#define TWT_REQ_TYPE_TWT_FLOW_IDENTIFIER_OFFSET 7 +#define TWT_REQ_TYPE_TWT_WAKE_INTVAL_EXP_OFFSET 10 +#define TWT_REQ_TYPE_TWT_PROTECTION_OFFSET 15 + +#define TWT_SETUP_CMD_REQUEST 0 +#define TWT_SETUP_CMD_SUGGEST 1 +#define TWT_SETUP_CMD_DEMAND 2 +#define TWT_SETUP_CMD_GROUPING 3 +#define TWT_SETUP_CMD_ACCEPT 4 +#define TWT_SETUP_CMD_ALTERNATE 5 +#define TWT_SETUP_CMD_DICTATE 6 +#define TWT_SETUP_CMD_REJECT 7 + +/* TWT Flow Field in teardown frame */ +#define TWT_TEARDOWN_FLOW_ID BITS(0, 2) + +/* TWT Information Field */ +#define TWT_INFO_FLOW_ID BITS(0, 2) +#define TWT_INFO_RESP_REQUESTED BIT(3) +#define TWT_INFO_NEXT_TWT_REQ BIT(4) +#define TWT_INFO_NEXT_TWT_SIZE BITS(5, 6) +#define TWT_INFO_BCAST_RESCHED BIT(7) + +#define TWT_INFO_FLOW_ID_OFFSET 0 +#define TWT_INFO_RESP_REQUESTED_OFFSET 3 +#define TWT_INFO_NEXT_TWT_REQ_OFFSET 4 +#define TWT_INFO_NEXT_TWT_SIZE_OFFSET 5 +#define TWT_INFO_BCAST_RESCHED_OFFSET 7 + +#define NEXT_TWT_SUBFIELD_ZERO_BIT 0 +#define NEXT_TWT_SUBFIELD_32_BITS 1 +#define NEXT_TWT_SUBFIELD_48_BITS 2 +#define NEXT_TWT_SUBFIELD_64_BITS 3 +#endif + +/* 9.4.2.46 Multiple BSSID element */ +/* Nontransmitted BSSID Profile */ +#define NON_TX_BSSID_PROFILE 0 + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +#if defined(WINDOWS_DDK) || defined(WINDOWS_CE) +#pragma pack(1) +#endif + +struct LLC_SNAP_HEADER { + uint8_t ucDSAP; + uint8_t ucSSAP; + uint8_t ucControl; + uint8_t aucCode[3]; + uint16_t u2Type; +} __KAL_ATTRIB_PACKED__; + +/* 3 MAC Header. */ +/* Ethernet Frame Header */ +struct ETH_FRAME_HEADER { + uint8_t aucDestAddr[MAC_ADDR_LEN]; + uint8_t aucSrcAddr[MAC_ADDR_LEN]; + uint16_t u2TypeLen; +} __KAL_ATTRIB_PACKED__; + +/* Ethernet Frame Structure */ +struct ETH_FRAME { + uint8_t aucDestAddr[MAC_ADDR_LEN]; + uint8_t aucSrcAddr[MAC_ADDR_LEN]; + uint16_t u2TypeLen; + uint8_t aucData[1]; +} __KAL_ATTRIB_PACKED__; + +struct BOOTP_PROTOCOL { + uint8_t ucOperation; + uint8_t ucHdrType; + uint8_t ucHdrLen; + uint8_t ucHops; + uint32_t u4TransId; + uint16_t u2Seconds; + uint16_t u2Flags; + uint32_t u4CIAddr; + uint32_t u4YIAddr; + uint32_t u4SIAddr; + uint32_t u4GIAddr; + uint8_t aucCHAddr[16]; + uint8_t aucServerName[64]; + uint8_t aucFileName[128]; + uint8_t aucOptions[0]; +} __KAL_ATTRIB_PACKED__; + +/* IEEE 802.11 WLAN Frame Structure */ +/* WLAN MAC Header (without Address 4 and QoS Control fields) */ +struct WLAN_MAC_HEADER { + uint16_t u2FrameCtrl; + uint16_t u2DurationID; + uint8_t aucAddr1[MAC_ADDR_LEN]; + uint8_t aucAddr2[MAC_ADDR_LEN]; + uint8_t aucAddr3[MAC_ADDR_LEN]; + uint16_t u2SeqCtrl; +} __KAL_ATTRIB_PACKED__; + +/* WLAN MAC Header (QoS Control fields included) */ +struct WLAN_MAC_HEADER_QOS { + uint16_t u2FrameCtrl; + uint16_t u2DurationID; + uint8_t aucAddr1[MAC_ADDR_LEN]; + uint8_t aucAddr2[MAC_ADDR_LEN]; + uint8_t aucAddr3[MAC_ADDR_LEN]; + uint16_t u2SeqCtrl; + uint16_t u2QosCtrl; +} __KAL_ATTRIB_PACKED__; + +/* WLAN MAC Header (HT Control fields included) */ +struct WLAN_MAC_HEADER_HT { + uint16_t u2FrameCtrl; + uint16_t u2DurationID; + uint8_t aucAddr1[MAC_ADDR_LEN]; + uint8_t aucAddr2[MAC_ADDR_LEN]; + uint8_t aucAddr3[MAC_ADDR_LEN]; + uint16_t u2SeqCtrl; + uint16_t u2QosCtrl; + uint32_t u4HtCtrl; +} __KAL_ATTRIB_PACKED__; + +/* WLAN MAC Header (Address 4 included) */ +struct WLAN_MAC_HEADER_A4 { + uint16_t u2FrameCtrl; + uint16_t u2DurationID; + uint8_t aucAddr1[MAC_ADDR_LEN]; + uint8_t aucAddr2[MAC_ADDR_LEN]; + uint8_t aucAddr3[MAC_ADDR_LEN]; + uint16_t u2SeqCtrl; + uint8_t aucAddr4[MAC_ADDR_LEN]; +} __KAL_ATTRIB_PACKED__; + +/* WLAN MAC Header (Address 4 and QoS Control fields included) */ +struct WLAN_MAC_HEADER_A4_QOS { + uint16_t u2FrameCtrl; + uint16_t u2DurationID; + uint8_t aucAddr1[MAC_ADDR_LEN]; + uint8_t aucAddr2[MAC_ADDR_LEN]; + uint8_t aucAddr3[MAC_ADDR_LEN]; + uint16_t u2SeqCtrl; + uint8_t aucAddr4[MAC_ADDR_LEN]; + uint16_t u2QosCtrl; +} __KAL_ATTRIB_PACKED__; + +struct WLAN_MAC_HEADER_A4_HT { + uint16_t u2FrameCtrl; + uint16_t u2DurationID; + uint8_t aucAddr1[MAC_ADDR_LEN]; + uint8_t aucAddr2[MAC_ADDR_LEN]; + uint8_t aucAddr3[MAC_ADDR_LEN]; + uint16_t u2SeqCtrl; + uint8_t aucAddr4[MAC_ADDR_LEN]; + uint16_t u2QosCtrl; + uint32_t u4HtCtrl; +} __KAL_ATTRIB_PACKED__; + +/* 7.2.3 WLAN MAC Header for Management Frame - MMPDU */ +struct WLAN_MAC_MGMT_HEADER { + uint16_t u2FrameCtrl; + uint16_t u2Duration; + uint8_t aucDestAddr[MAC_ADDR_LEN]; + uint8_t aucSrcAddr[MAC_ADDR_LEN]; + uint8_t aucBSSID[MAC_ADDR_LEN]; + uint16_t u2SeqCtrl; +} __KAL_ATTRIB_PACKED__; + +/* WLAN MAC Header for Management Frame (HT Control fields included) */ +struct WLAN_MAC_MGMT_HEADER_HT { + uint16_t u2FrameCtrl; + uint16_t u2DurationID; + uint8_t aucAddr1[MAC_ADDR_LEN]; + uint8_t aucAddr2[MAC_ADDR_LEN]; + uint8_t aucAddr3[MAC_ADDR_LEN]; + uint16_t u2SeqCtrl; + uint32_t u4HtCtrl; +} __KAL_ATTRIB_PACKED__; + +/* 3 WLAN CONTROL Frame */ +/* 7.2.1.4 WLAN Control Frame - PS-POLL Frame */ +struct CTRL_PSPOLL_FRAME { + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2AID; /* AID */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint8_t aucTA[MAC_ADDR_LEN]; /* TA */ +} __KAL_ATTRIB_PACKED__; + +/* BAR */ +struct CTRL_BAR_FRAME { + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2DurationID; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* RA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* TA */ + uint16_t u2BarControl; + uint8_t aucBarInfo[2]; /* Variable size */ +} __KAL_ATTRIB_PACKED__; + +/* 3 WLAN Management Frame. */ +/* 7.2.3.1 WLAN Management Frame - Beacon Frame */ +struct WLAN_BEACON_FRAME { + /* Beacon header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2DurationID; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* Beacon frame body */ + uint32_t au4Timestamp[2]; /* Timestamp */ + uint16_t u2BeaconInterval; /* Beacon Interval */ + uint16_t u2CapInfo; /* Capability */ + uint8_t aucInfoElem[1]; /* Various IEs, start from SSID */ +} __KAL_ATTRIB_PACKED__; + +struct WLAN_BEACON_FRAME_BODY { + /* Beacon frame body */ + uint32_t au4Timestamp[2]; /* Timestamp */ + uint16_t u2BeaconInterval; /* Beacon Interval */ + uint16_t u2CapInfo; /* Capability */ + uint8_t aucInfoElem[1]; /* Various IEs, start from SSID */ +} __KAL_ATTRIB_PACKED__; + +/* 7.2.3.3 WLAN Management Frame - Disassociation Frame */ +struct WLAN_DISASSOC_FRAME { + /* Authentication MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2DurationID; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* Disassociation frame body */ + uint16_t u2ReasonCode; /* Reason code */ + uint8_t aucInfoElem[1]; /* Various IEs, possible no. */ +} __KAL_ATTRIB_PACKED__; + +/* 7.2.3.4 WLAN Management Frame - Association Request frame */ +struct WLAN_ASSOC_REQ_FRAME { + /* Association Request MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2DurationID; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* Association Request frame body */ + uint16_t u2CapInfo; /* Capability information */ + uint16_t u2ListenInterval; /* Listen interval */ + uint8_t aucInfoElem[1]; /* Information elements, include WPA IE */ +} __KAL_ATTRIB_PACKED__; + +/* 7.2.3.5 WLAN Management Frame - Association Response frame */ +struct WLAN_ASSOC_RSP_FRAME { + /* Association Response MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2DurationID; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* Association Response frame body */ + uint16_t u2CapInfo; /* Capability information */ + uint16_t u2StatusCode; /* Status code */ + uint16_t u2AssocId; /* Association ID */ + uint8_t aucInfoElem[1]; /* Information elements, such as */ + /* supported rates, and etc. */ +} __KAL_ATTRIB_PACKED__; + +/* 7.2.3.6 WLAN Management Frame - Reassociation Request frame */ +struct WLAN_REASSOC_REQ_FRAME { + /* Reassociation Request MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2DurationID; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* Reassociation Request frame body */ + uint16_t u2CapInfo; /* Capability information */ + uint16_t u2ListenInterval; /* Listen interval */ + uint8_t aucCurrentAPAddr[MAC_ADDR_LEN]; /* Current AP address */ + uint8_t aucInfoElem[1]; /* Information elements, include WPA IE */ +} __KAL_ATTRIB_PACKED__; + +/* 7.2.3.7 WLAN Management Frame - Reassociation Response frame */ +/* (the same as Association Response frame) */ + +/* 7.2.3.9 WLAN Management Frame - Probe Response Frame */ + +/* 7.2.3.10 WLAN Management Frame - Authentication Frame */ +struct WLAN_AUTH_FRAME { + /* Authentication MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2DurationID; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* Authentication frame body */ + uint16_t u2AuthAlgNum; /* Authentication algorithm number */ + /* Authentication transaction sequence number */ + uint16_t u2AuthTransSeqNo; + uint16_t u2StatusCode; /* Status code */ + uint8_t aucInfoElem[1]; /* Various IEs for Fast BSS Transition */ +} __KAL_ATTRIB_PACKED__; + +/* 7.2.3.11 WLAN Management Frame - Deauthentication Frame */ +struct WLAN_DEAUTH_FRAME { + /* Authentication MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2DurationID; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* Deauthentication frame body */ + uint16_t u2ReasonCode; /* Reason code */ + uint8_t aucInfoElem[1]; /* Various IEs, possible no. */ +} __KAL_ATTRIB_PACKED__; + +/* 3 Information Elements. */ +/* 7.3.2 Generic element format */ +struct IE_HDR { + uint8_t ucId; + uint8_t ucLength; + uint8_t aucInfo[1]; +} __KAL_ATTRIB_PACKED__; + +/* 7.3.2.1 SSID element */ +struct IE_SSID { + uint8_t ucId; + uint8_t ucLength; + uint8_t aucSSID[ELEM_MAX_LEN_SSID]; +} __KAL_ATTRIB_PACKED__; + +/* 7.3.2.2 Supported Rates element */ +struct IE_SUPPORTED_RATE { + uint8_t ucId; + uint8_t ucLength; + uint8_t aucSupportedRates[ELEM_MAX_LEN_SUP_RATES]; +} __KAL_ATTRIB_PACKED__; + +/* Some IOT AP will carry Rates > 8*/ +struct IE_SUPPORTED_RATE_IOT { + uint8_t ucId; + uint8_t ucLength; + uint8_t aucSupportedRates[ELEM_MAX_LEN_SUP_RATES_IOT]; +} __KAL_ATTRIB_PACKED__; + +/* 7.3.2.4 DS Parameter Set element */ +struct IE_DS_PARAM_SET { + uint8_t ucId; + uint8_t ucLength; + uint8_t ucCurrChnl; +} __KAL_ATTRIB_PACKED__; + +/* 7.3.2.5 CF Parameter Set element */ +struct IE_CF_PARAM_SET { + uint8_t ucId; + uint8_t ucLength; + uint8_t ucCFPCount; + uint8_t ucCFPPeriod; + uint16_t u2CFPMaxDur; + uint16_t u2DurRemaining; +} __KAL_ATTRIB_PACKED__; + +/* 7.3.2.6 TIM */ +struct IE_TIM { + uint8_t ucId; + uint8_t ucLength; + uint8_t ucDTIMCount; + uint8_t ucDTIMPeriod; + uint8_t ucBitmapControl; + uint8_t aucPartialVirtualMap[1]; +} __KAL_ATTRIB_PACKED__; + +/* 7.3.2.7 IBSS Parameter Set element */ +struct IE_IBSS_PARAM_SET { + uint8_t ucId; + uint8_t ucLength; + uint16_t u2ATIMWindow; +} __KAL_ATTRIB_PACKED__; + +/* 7.3.2.8 Challenge Text element */ +struct IE_CHALLENGE_TEXT { + uint8_t ucId; + uint8_t ucLength; + uint8_t aucChallengeText[ELEM_MAX_LEN_CHALLENGE_TEXT]; +} __KAL_ATTRIB_PACKED__; + +/* 7.3.2.9 Country information element */ +#if CFG_SUPPORT_802_11D +/*! \brief COUNTRY_INFO_TRIPLET + * is defined for the COUNTRY_INFO_ELEM structure. + */ +struct COUNTRY_INFO_TRIPLET { + /*!< If param1 >= 201, this triplet is referred to as + * Regulatory Triplet in 802_11J. + */ + uint8_t ucParam1; + uint8_t ucParam2; + uint8_t ucParam3; +} __KAL_ATTRIB_PACKED__; + +struct COUNTRY_INFO_SUBBAND_TRIPLET { + uint8_t ucFirstChnlNum; /*!< First Channel Number */ + uint8_t ucNumOfChnl; /*!< Number of Channels */ + int8_t cMaxTxPwrLv; /*!< Maximum Transmit Power Level */ +} __KAL_ATTRIB_PACKED__; + +struct COUNTRY_INFO_REGULATORY_TRIPLET { + uint8_t ucRegExtId; /*!< Regulatory Extension Identifier, should */ + /* be greater than or equal to 201 */ + uint8_t ucRegClass; /*!< Regulatory Class */ + /*!< Coverage Class, unsigned 1-octet value 0~31 */ + uint8_t ucCoverageClass; + /* , 32~255 reserved */ +} __KAL_ATTRIB_PACKED__; + +struct IE_COUNTRY { + uint8_t ucId; + uint8_t ucLength; + uint8_t aucCountryStr[3]; + struct COUNTRY_INFO_SUBBAND_TRIPLET arCountryStr[1]; +} __KAL_ATTRIB_PACKED__; +#endif /* CFG_SUPPORT_802_11D */ + +/* 7.3.2.13 ERP element */ +struct IE_ERP { + uint8_t ucId; + uint8_t ucLength; + uint8_t ucERP; +} __KAL_ATTRIB_PACKED__; + +/* 7.3.2.14 Extended Supported Rates element */ +struct IE_EXT_SUPPORTED_RATE { + uint8_t ucId; + uint8_t ucLength; + uint8_t aucExtSupportedRates[ELEM_MAX_LEN_EXTENDED_SUP_RATES]; +} __KAL_ATTRIB_PACKED__; + +/* 7.3.2.15 Power Constraint element */ +struct IE_POWER_CONSTRAINT { + uint8_t ucId; + uint8_t ucLength; + uint8_t ucLocalPowerConstraint; /* Unit: dBm */ +} __KAL_ATTRIB_PACKED__; + +/* 7.3.2.16 Power Capability element */ +struct IE_POWER_CAP { + uint8_t ucId; + uint8_t ucLength; + int8_t cMinTxPowerCap; /* Unit: dBm */ + int8_t cMaxTxPowerCap; /* Unit: dBm */ +} __KAL_ATTRIB_PACKED__; + +/* 7.3.2.17 TPC request element */ +struct IE_TPC_REQ { + uint8_t ucId; + uint8_t ucLength; +} __KAL_ATTRIB_PACKED__; + +/* 7.3.2.18 TPC report element */ +struct IE_TPC_REPORT { + uint8_t ucId; + uint8_t ucLength; + int8_t cTxPower; /* Unit: dBm */ + int8_t cLinkMargin; /* Unit: dB */ +} __KAL_ATTRIB_PACKED__; + +/* 7.3.2.19 Supported Channels element*/ +struct IE_SUPPORTED_CHANNELS { + uint8_t ucId; + uint8_t ucLength; + uint8_t ucChannelNum[0]; +} __KAL_ATTRIB_PACKED__; + +/* 7.3.2.20 Channel Switch Announcement element*/ +struct IE_CHANNEL_SWITCH { + uint8_t ucId; + uint8_t ucLength; + uint8_t ucChannelSwitchMode; + uint8_t ucNewChannelNum; + uint8_t ucChannelSwitchCount; +} __KAL_ATTRIB_PACKED__; + +struct IE_TIMEOUT_INTERVAL { + uint8_t ucId; + uint8_t ucLength; +#define IE_TIMEOUT_INTERVAL_TYPE_RESERVED 0 +#define IE_TIMEOUT_INTERVAL_TYPE_REASSOC 1 +#define IE_TIMEOUT_INTERVAL_TYPE_KEY_LIFETIME 43200 +#define IE_TIMEOUT_INTERVAL_TYPE_ASSOC_COMEBACK 3 + uint8_t ucType; + uint32_t u4Value; +} __KAL_ATTRIB_PACKED__; + +/* 7.3.2.20 Channel Switch Announcement element */ +struct IE_CHNL_SWITCH { + uint8_t ucId; + uint8_t ucLength; + uint8_t ucSwitchMode; + uint8_t ucNewChannel; + uint8_t ucSwitchCount; +} __KAL_ATTRIB_PACKED__; + +/* 7.3.2.21 Measurement Request element */ +struct IE_MEASUREMENT_REQ { + uint8_t ucId; + uint8_t ucLength; + uint8_t ucToken; + uint8_t ucRequestMode; + uint8_t ucMeasurementType; + uint8_t aucRequestFields[0]; +} __KAL_ATTRIB_PACKED__; + +/* 7.3.2.60 20/40 BSS Coexistence element */ +struct IE_SUP_OPERATING_CLASS { + uint8_t ucId; + uint8_t ucLength; + uint8_t ucCur; + uint8_t ucSup[255]; +} __KAL_ATTRIB_PACKED__; + +/* 8.4.2.30 BSS Load element */ +struct IE_BSS_LOAD { + uint8_t ucId; + uint8_t ucLength; + uint16_t u2StaCnt; + uint8_t ucChnlUtilizaion; + uint16_t u2AvailabeAC; +} __KAL_ATTRIB_PACKED__; + +/* 8.4.2.39 Neighbor Report Element */ +struct IE_NEIGHBOR_REPORT { + uint8_t ucId; /* Element ID */ + uint8_t ucLength; /* Length */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* OUI */ + uint32_t u4BSSIDInfo; /* Type */ + uint8_t ucOperClass; /* Hotspot Configuration */ + uint8_t ucChnlNumber; + uint8_t ucPhyType; + uint8_t aucSubElem[0]; +} __KAL_ATTRIB_PACKED__; + +struct IE_MBO_OCE { + uint8_t ucId; + uint8_t ucLength; + uint8_t aucOui[3]; + uint8_t ucOuiType; + uint8_t aucSubElements[1]; +} __KAL_ATTRIB_PACKED__; + +/* 8.5.7.6/8.5.7.7 Neighbor Report Request/Response frame format */ +struct ACTION_NEIGHBOR_REPORT_FRAME { + /* Neighbor Report Request/Response MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2Duration; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* Neighbor Report Request/Response frame body */ + uint8_t ucCategory; /* Category */ + uint8_t ucAction; /* Action Value */ + uint8_t ucDialogToken; /* Dialog Token */ + uint8_t aucInfoElem[1]; /* subelements */ +} __KAL_ATTRIB_PACKED__; + +struct SUB_ELEMENT { + uint8_t ucSubID; + uint8_t ucLength; + uint8_t aucOptInfo[1]; +} __KAL_ATTRIB_PACKED__; + +struct SM_BASIC_REQ { + uint8_t ucChannel; + uint32_t au4StartTime[2]; + uint16_t u2Duration; +} __KAL_ATTRIB_PACKED__; + +/* SM_COMMON_REQ_T is not specified in Spec. Use it as common structure of SM */ + +struct RM_CHNL_LOAD_REQ { + uint8_t ucRegulatoryClass; + uint8_t ucChannel; + uint16_t u2RandomInterval; + uint16_t u2Duration; + uint8_t aucSubElements[1]; +} __KAL_ATTRIB_PACKED__; + + +struct RM_BCN_REQ { + uint8_t ucRegulatoryClass; + uint8_t ucChannel; + uint16_t u2RandomInterval; + uint16_t u2Duration; + uint8_t ucMeasurementMode; + uint8_t aucBssid[6]; + uint8_t aucSubElements[1]; +} __KAL_ATTRIB_PACKED__; + +struct RM_FRAME_REQ { + uint8_t ucRegulatoryClass; + uint8_t ucChannel; + uint16_t u2RandomInterval; + uint16_t u2Duration; + uint8_t ucFrameReqType; + uint8_t aucMacAddr[6]; + uint8_t aucSubElements[1]; +} __KAL_ATTRIB_PACKED__; + +struct RM_STA_STATS_REQ { + uint8_t aucPeerMacAddr[6]; + uint16_t u2RandomInterval; + uint16_t u2Duration; + uint8_t ucGroupID; + uint8_t aucSubElements[1]; +} __KAL_ATTRIB_PACKED__; + +struct RM_LCI_REQ { + uint8_t ucLocationSubject; + uint8_t ucLatitudeResolution; + uint8_t ucLongitudeResolution; + uint8_t ucAltitudeResolution; + uint8_t aucSubElements[1]; +} __KAL_ATTRIB_PACKED__; + +struct RM_TS_MEASURE_REQ { + uint16_t u2RandomInterval; + uint16_t u2Duration; + uint8_t aucPeerStaAddr[6]; + uint8_t ucTrafficID; + uint8_t ucBin0Range; + uint8_t aucSubElements[1]; +} __KAL_ATTRIB_PACKED__; + +struct RM_MEASURE_PAUSE_REQ { + uint16_t u2PauseTime; + uint8_t aucSubElements[1]; +} __KAL_ATTRIB_PACKED__; + +/* 7.3.2.22 Measurement Report element */ +struct IE_MEASUREMENT_REPORT { + uint8_t ucId; + uint8_t ucLength; + uint8_t ucToken; + uint8_t ucReportMode; + uint8_t ucMeasurementType; + uint8_t aucReportFields[0]; +} __KAL_ATTRIB_PACKED__; + +struct SM_BASIC_REPORT { + uint8_t ucChannel; + uint32_t u4StartTime[2]; + uint16_t u2Duration; + uint8_t ucMap; +} __KAL_ATTRIB_PACKED__; + +struct SM_CCA_REPORT { + uint8_t ucChannel; + uint32_t u4StartTime[2]; + uint16_t u2Duration; + uint8_t ucCcaBusyFraction; +} __KAL_ATTRIB_PACKED__; + +struct SM_RPI_REPORT { + uint8_t ucChannel; + uint32_t u4StartTime[2]; + uint16_t u2Duration; + uint8_t aucRPI[8]; +} __KAL_ATTRIB_PACKED__; + +struct RM_CHNL_LOAD_REPORT { + uint8_t ucRegulatoryClass; + uint8_t ucChannel; + uint32_t u4StartTime[2]; + uint16_t u2Duration; + uint8_t ucChnlLoad; +} __KAL_ATTRIB_PACKED__; + +struct RM_IPI_REPORT { + uint8_t ucRegulatoryClass; + uint8_t ucChannel; + uint32_t u4StartTime[2]; + uint16_t u2Duration; + uint8_t ucAntennaId; + int8_t cANPI; + uint8_t aucIPI[11]; +} __KAL_ATTRIB_PACKED__; + +struct RM_BCN_REPORT { + uint8_t ucRegulatoryClass; + uint8_t ucChannel; + uint8_t aucStartTime[8]; + uint16_t u2Duration; + uint8_t ucReportInfo; + uint8_t ucRCPI; + uint8_t ucRSNI; + uint8_t aucBSSID[MAC_ADDR_LEN]; + uint8_t ucAntennaID; + uint8_t aucParentTSF[4]; + uint8_t aucOptElem[0]; +} __KAL_ATTRIB_PACKED__; + +struct RM_TSM_REPORT { + uint64_t u8ActualStartTime; + uint16_t u2Duration; + uint8_t aucPeerAddress[MAC_ADDR_LEN]; + uint8_t ucTID; + uint8_t ucReason; + uint32_t u4TransmittedMsduCnt; + uint32_t u4DiscardedMsduCnt; + uint32_t u4FailedMsduCnt; + uint32_t u4MultiRetryCnt; + uint32_t u4CfPollLostCnt; + uint32_t u4AvgQueDelay; + uint32_t u4AvgDelay; + uint8_t ucBin0Range; + uint32_t u4Bin[6]; + uint8_t aucOptSubElems[0]; +} __KAL_ATTRIB_PACKED__; + +/* 7.3.2.23 Quiet element */ +struct IE_QUIET { + uint8_t ucId; + uint8_t ucLength; + uint8_t ucCount; + uint8_t ucPeriod; + uint16_t u2Duration; + uint16_t u2Offset; +} __KAL_ATTRIB_PACKED__; + +/* 7.3.2.27 Extended Capabilities element */ +struct IE_EXT_CAP { + uint8_t ucId; + uint8_t ucLength; + uint8_t aucCapabilities[1]; +} __KAL_ATTRIB_PACKED__; + +/* 7.3.2.27 hs20 Extended Capabilities element */ +struct IE_HS20_EXT_CAP_T { + uint8_t ucId; + uint8_t ucLength; + uint8_t aucCapabilities[6]; +}; + +/* 7.3.2.27 Extended Capabilities element */ +struct IE_RRM_ENABLED_CAP { + uint8_t ucId; + uint8_t ucLength; + uint8_t aucCap[5]; +} __KAL_ATTRIB_PACKED__; + +/* 7.3.2.56 HT Capabilities element */ +struct SUP_MCS_SET_FIELD { + uint8_t aucRxMcsBitmask[SUP_MCS_RX_BITMASK_OCTET_NUM]; + uint16_t u2RxHighestSupportedRate; + uint32_t u4TxRateInfo; +} __KAL_ATTRIB_PACKED__; + +struct IE_HT_CAP { + uint8_t ucId; + uint8_t ucLength; + uint16_t u2HtCapInfo; + uint8_t ucAmpduParam; + struct SUP_MCS_SET_FIELD rSupMcsSet; + uint16_t u2HtExtendedCap; + uint32_t u4TxBeamformingCap; + uint8_t ucAselCap; +} __KAL_ATTRIB_PACKED__; + +/* 7.3.2.57 HT Operation element */ +struct IE_HT_OP { + uint8_t ucId; + uint8_t ucLength; + uint8_t ucPrimaryChannel; + uint8_t ucInfo1; + uint16_t u2Info2; + uint16_t u2Info3; + uint8_t aucBasicMcsSet[16]; +} __KAL_ATTRIB_PACKED__; + +/*8.4.2.160.3 VHT Supported MCS Set field*/ +struct VHT_SUPPORTED_MCS_FIELD { + uint16_t u2RxMcsMap; + uint16_t u2RxHighestSupportedDataRate; + uint16_t u2TxMcsMap; + uint16_t u2TxHighestSupportedDataRate; +} __KAL_ATTRIB_PACKED__; + +struct IE_VHT_CAP { + uint8_t ucId; + uint8_t ucLength; + uint32_t u4VhtCapInfo; + struct VHT_SUPPORTED_MCS_FIELD rVhtSupportedMcsSet; +} __KAL_ATTRIB_PACKED__; + +/*8.4.2.161 VHT Operation element*/ +struct IE_VHT_OP { + uint8_t ucId; + uint8_t ucLength; + uint8_t ucVhtOperation[3]; + uint16_t u2VhtBasicMcsSet; +} __KAL_ATTRIB_PACKED__; + +struct IE_VENDOR_EPIGRAM_IE { + uint8_t ucId; + uint8_t ucLength; + uint8_t aucOui[3]; + uint8_t aucVendorType[2]; + uint8_t pucData[1]; +} __KAL_ATTRIB_PACKED__; + +struct IE_VENDOR_ADAPTIVE_11R_IE { + uint8_t ucId; + uint8_t ucLength; + uint8_t aucOui[3]; + uint8_t aucVendorType[1]; + uint8_t pucData[1]; +} __KAL_ATTRIB_PACKED__; + +/*8.4.1.50 Operating Mode field*/ +struct IE_VHT_OP_MODE_NOTIFICATION { + uint8_t ucId; + uint8_t ucLength; + uint8_t ucOperatingMode; +} __KAL_ATTRIB_PACKED__; + + +/*8.4.2.22 Secondary Channel Offset element*/ +struct IE_SECONDARY_OFFSET { + uint8_t ucId; + uint8_t ucLength; + uint8_t ucSecondaryOffset; +} __KAL_ATTRIB_PACKED__; + +/*8.4.2.105 Mesh Channel Switch Parameters element*/ +struct IE_MESH_CHANNEL { + uint8_t ucId; + uint8_t ucLength; + uint8_t ucTimetoLive; + uint8_t ucFlags; + uint16_t u2ReasonCodes; + uint16_t u2ProcedenceValue; +} __KAL_ATTRIB_PACKED__; + +/*8.4.2.163 Wide Bandwidth Channel Switch element*/ +struct IE_WIDE_BAND_CHANNEL { + uint8_t ucId; + uint8_t ucLength; + uint8_t ucNewChannelWidth; + uint8_t ucChannelS1; + uint8_t ucChannelS2; +} __KAL_ATTRIB_PACKED__; + +/*8.4.2.168 Operating Mode Notification element*/ +struct IE_OP_MODE_NOTIFICATION { + uint8_t ucId; + uint8_t ucLength; + uint8_t ucOpMode; +} __KAL_ATTRIB_PACKED__; + +/* 7.3.2.25 RSN Information element format */ +struct RSN_INFO_ELEM { + uint8_t ucElemId; + uint8_t ucLength; + uint16_t u2Version; + uint32_t u4GroupKeyCipherSuite; + uint16_t u2PairwiseKeyCipherSuiteCount; + uint8_t aucPairwiseKeyCipherSuite1[4]; +} __KAL_ATTRIB_PACKED__; + +/* 7.3.2.26 WPA Information element format */ +struct WPA_INFO_ELEM { + uint8_t ucElemId; + uint8_t ucLength; + uint8_t aucOui[3]; + uint8_t ucOuiType; + uint16_t u2Version; + uint32_t u4GroupKeyCipherSuite; + uint16_t u2PairwiseKeyCipherSuiteCount; + uint8_t aucPairwiseKeyCipherSuite1[4]; +} __KAL_ATTRIB_PACKED__; + +/* 7.3.2.58 20/40 BSS Intolerant Channel Report element */ +struct IE_INTOLERANT_CHNL_REPORT { + uint8_t ucId; + uint8_t ucLength; + uint8_t ucRegulatoryClass; + uint8_t aucChannelList[1]; +} __KAL_ATTRIB_PACKED__; + +/* 7.3.2.59 OBSS Scan Parameters element */ +struct IE_OBSS_SCAN_PARAM { + uint8_t ucId; + uint8_t ucLength; + uint16_t u2ScanPassiveDwell; + uint16_t u2ScanActiveDwell; + uint16_t u2TriggerScanInterval; + uint16_t u2ScanPassiveTotalPerChnl; + uint16_t u2ScanActiveTotalPerChnl; + uint16_t u2WidthTransDelayFactor; + uint16_t u2ScanActivityThres; +} __KAL_ATTRIB_PACKED__; + +/* 7.3.2.60 20/40 BSS Coexistence element */ +struct IE_20_40_COEXIST { + uint8_t ucId; + uint8_t ucLength; + uint8_t ucData; +} __KAL_ATTRIB_PACKED__; + +#if (CFG_SUPPORT_TWT == 1) +/* 11ax TWT element */ +struct _IE_TWT_T { + uint8_t ucId; + uint8_t ucLength; + uint8_t ucCtrl; /* Control */ + uint16_t u2ReqType; /* Request Type */ + uint64_t u8TWT; /* Target Wake Time 64 bits */ + uint8_t ucMinWakeDur; /* Nominal Minimum TWT Wake Duration */ + uint16_t u2WakeIntvalMantiss; /* TWT Wake Interval Mantissa */ + uint8_t ucReserved; /* TWT Channel for 11ah. Reserved for 11ax */ +} __KAL_ATTRIB_PACKED__; +#endif + +/* 3 7.4 Action Frame. */ +/* 7.4 Action frame format */ +struct WLAN_ACTION_FRAME { + /* Action MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2DurationID; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* Action frame body */ + uint8_t ucCategory; /* Category */ + uint8_t ucAction; /* Action Value */ + uint8_t ucActionDetails[1]; /* Action details */ +} __KAL_ATTRIB_PACKED__; + +/* public Action frame format */ +struct WLAN_PUBLIC_VENDOR_ACTION_FRAME { + /* Action MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2DurationID; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* Action frame body */ + uint8_t ucCategory; /* Category: should be 0x4 */ + uint8_t ucAction; /* Action Value: should be 0x9 */ + uint8_t ucOUI[3]; + uint8_t ucSubType; + uint8_t ucPubSubType; +} __KAL_ATTRIB_PACKED__; + + +/* 7.4.1.1 Spectrum Measurement Request frame format */ +struct ACTION_SM_REQ_FRAME { + /* ADDTS Request MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2Duration; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* ADDTS Request frame body */ + uint8_t ucCategory; /* Category */ + uint8_t ucAction; /* Action Value */ + uint8_t ucDialogToken; /* Dialog Token */ + uint8_t aucInfoElem[1]; /* Information elements */ +} __KAL_ATTRIB_PACKED__; + +/* 7.4.1.2 Spectrum Measurement Report frame format */ + +/* 7.4.1.3 Spectrum TPC Request frame format */ +struct ACTION_TPC_REQ_FRAME { + /* ADDTS Request MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2Duration; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* ADDTS Request frame body */ + uint8_t ucCategory; /* Category */ + uint8_t ucAction; /* Action Value */ + uint8_t ucDialogToken; /* Dialog Token */ + uint8_t ucElemId; /* Element ID */ + uint8_t ucLength; /* Length */ +} __KAL_ATTRIB_PACKED__; + +/* 7.4.1.4 Spectrum TPC Report frame format */ +struct ACTION_TPC_REPORT_FRAME { + /* ADDTS Request MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2Duration; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* ADDTS Request frame body */ + uint8_t ucCategory; /* Category */ + uint8_t ucAction; /* Action Value */ + uint8_t ucDialogToken; /* Dialog Token */ + uint8_t ucElemId; /* Element ID */ + uint8_t ucLength; /* Length */ + uint8_t ucTransPwr; /* Transmit Power */ + uint8_t ucLinkMargin; /* Link Margin */ +} __KAL_ATTRIB_PACKED__; + +/* 7.4.1.5 Channel Switch Announcement frame format */ +struct ACTION_CHANNEL_SWITCH_FRAME { + /* ADDTS Request MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2Duration; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* ADDTS Request frame body */ + uint8_t ucCategory; /* Category */ + uint8_t ucAction; /* Action Value */ + uint8_t aucInfoElem[5]; /* Information elements */ +} __KAL_ATTRIB_PACKED__; + +/* 7.4.2.1 ADDTS Request frame format */ +struct ACTION_ADDTS_REQ_FRAME { + /* ADDTS Request MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2Duration; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* ADDTS Request frame body */ + uint8_t ucCategory; /* Category */ + uint8_t ucAction; /* Action Value */ + uint8_t ucDialogToken; /* Dialog Token */ + uint8_t aucInfoElem[1]; /* Information elements, such as */ + /* TS Delay, and etc. */ +} __KAL_ATTRIB_PACKED__; + +/* 7.4.2.2 ADDTS Response frame format */ +struct ACTION_ADDTS_RSP_FRAME { + /* ADDTS Response MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2Duration; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* ADDTS Response frame body */ + uint8_t ucCategory; /* Category */ + uint8_t ucAction; /* Action Value */ + uint8_t ucDialogToken; /* Dialog Token */ + uint8_t ucStatusCode; /* WMM Status Code is of one byte */ + uint8_t aucInfoElem[1]; /* Information elements, such as */ + /* TS Delay, and etc. */ +} __KAL_ATTRIB_PACKED__; + +/* 7.4.2.3 DELTS frame format */ +struct ACTION_DELTS_FRAME { + /* DELTS MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2DurationID; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* DELTS frame body */ + uint8_t ucCategory; /* Category */ + uint8_t ucAction; /* Action Value */ + uint8_t aucTsInfo[3]; /* TS Info */ +} __KAL_ATTRIB_PACKED__; + +/* 7.4.2.3 QOSMAPSET CONFIGURATE frame format */ +struct _ACTION_QOS_MAP_CONFIGURE_FRAME { + /* QOSMAP CONFIGURE MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2DurationID; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* DELTS frame body */ + uint8_t ucCategory; /* Category */ + uint8_t ucAction; /* Action Value */ + uint8_t qosMapSet[1]; /* qosmapset IE */ +}; + +/* 7.4.4.1 ADDBA Request frame format */ +struct ACTION_ADDBA_REQ_FRAME { + /* Action MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2DurationID; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* Action frame body */ + uint8_t ucCategory; /* Category */ + uint8_t ucAction; /* Action Value */ + uint8_t ucDialogToken; /* Dialog Token chosen by the sender */ + uint8_t aucBAParameterSet[2]; /* BA policy, TID, buffer size */ + uint8_t aucBATimeoutValue[2]; + uint8_t aucBAStartSeqCtrl[2]; /* SSN */ +} __KAL_ATTRIB_PACKED__; + +struct ACTION_ADDBA_REQ_BODY { + uint16_t u2BAParameterSet; /* BA policy, TID, buffer size */ + uint16_t u2BATimeoutValue; + uint16_t u2BAStartSeqCtrl; /* SSN */ +} __KAL_ATTRIB_PACKED__; + +/* 7.4.4.2 ADDBA Response frame format */ +struct ACTION_ADDBA_RSP_FRAME { + /* Action MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2DurationID; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* Action frame body */ + uint8_t ucCategory; /* Category */ + uint8_t ucAction; /* Action Value */ + uint8_t ucDialogToken; /* Dialog Token chosen by the sender */ + uint8_t aucStatusCode[2]; + uint8_t aucBAParameterSet[2]; /* BA policy, TID, buffer size */ + uint8_t aucBATimeoutValue[2]; +} __KAL_ATTRIB_PACKED__; + +struct ACTION_ADDBA_RSP_BODY { + uint16_t u2StatusCode; + uint16_t u2BAParameterSet; /* BA policy, TID, buffer size */ + uint16_t u2BATimeoutValue; +} __KAL_ATTRIB_PACKED__; + +/* 7.4.4.3 DELBA frame format */ +struct ACTION_DELBA_FRAME { + /* Action MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2DurationID; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* Action frame body */ + uint8_t ucCategory; /* Category */ + uint8_t ucAction; /* Action Value */ + uint16_t u2DelBaParameterSet; /* Bit 11 Initiator, Bits 12-15 TID */ + uint16_t u2ReasonCode; /* 7.3.1.7 */ +} __KAL_ATTRIB_PACKED__; + +#if CFG_SUPPORT_NCHO +/* 7.4.5.1 vendor-specific frame format */ +struct _ACTION_VENDOR_SPEC_FRAME_T { + /* Action MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2Duration; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + uint8_t aucElemInfo[0]; /* Pointer to frame data */ +}; +#endif + +/* 7.4.6.1 Radio Measurement Request frame format */ +struct ACTION_RM_REQ_FRAME { + /* MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2Duration; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* Radio Measurement Request frame body */ + uint8_t ucCategory; /* Category */ + uint8_t ucAction; /* Action Value */ + uint8_t ucDialogToken; /* Dialog Token */ + uint16_t u2Repetitions; /* Number of repetitions */ + uint8_t aucInfoElem[1]; /* Measurement Request elements, such as */ + /* channel load request, and etc. */ +} __KAL_ATTRIB_PACKED__; + +/* 7.4.6.2 Radio Measurement Report frame format */ +struct ACTION_RM_REPORT_FRAME { + /* MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2Duration; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* Radio Measurement Report frame body */ + uint8_t ucCategory; /* Category */ + uint8_t ucAction; /* Action Value */ + uint8_t ucDialogToken; /* Dialog Token */ + uint8_t aucInfoElem[0]; /* Measurement Report elements, such as */ + /* channel load report, and etc. */ +} __KAL_ATTRIB_PACKED__; + +/* 7.4.7.1a 20/40 BSS Coexistence Management frame format */ +struct ACTION_20_40_COEXIST_FRAME { + /* MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2Duration; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* BSS Coexistence Management frame body */ + uint8_t ucCategory; /* Category */ + uint8_t ucAction; /* Action Value */ + + /* 20/40 BSS coexistence element */ + struct IE_20_40_COEXIST rBssCoexist; + /* Intolerant channel report */ + struct IE_INTOLERANT_CHNL_REPORT rChnlReport; + +} __KAL_ATTRIB_PACKED__; + +#if CFG_SUPPORT_802_11W +/* 7.4.9 SA Query Management frame format */ +struct ACTION_SA_QUERY_FRAME { + /* MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2Duration; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* BSS Coexistence Management frame body */ + uint8_t ucCategory; /* Category */ + uint8_t ucAction; /* Action Value */ + + uint8_t ucTransId[ACTION_SA_QUERY_TR_ID_LEN]; /* Transaction id */ + +} __KAL_ATTRIB_PACKED__; +#endif + +/* 7.4.10 Notify Channel Width Management frame format */ +struct ACTION_NOTIFY_CHNL_WIDTH_FRAME { + /* MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2Duration; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* BSS Coexistence Management frame body */ + uint8_t ucCategory; /* Category */ + uint8_t ucAction; /* Action Value */ + uint8_t ucChannelWidth; /* Channel Width */ +} __KAL_ATTRIB_PACKED__; + +/* 802.11v Wireless Network Management: Timing Measurement Request */ +struct ACTION_WNM_TIMING_MEAS_REQ_FRAME { + /* MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2Duration; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* Timing Measurement Request Management frame body */ + uint8_t ucCategory; /* Category */ + uint8_t ucAction; /* Action Value */ + uint8_t ucTrigger; /* Trigger */ +} __KAL_ATTRIB_PACKED__; + +/* 802.11v Wireless Network Management: Timing Measurement */ +struct ACTION_UNPROTECTED_WNM_TIMING_MEAS_FRAME { + /* MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2Duration; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* Timing Measurement Management frame body */ + uint8_t ucCategory; /* Category */ + uint8_t ucAction; /* Action Value */ + uint8_t ucDialogToken; /* Dialog Token */ + uint8_t ucFollowUpDialogToken; /* Follow Up Dialog Token */ + uint32_t u4ToD; /* Timestamp of Departure [10ns] */ + uint32_t u4ToA; /* Timestamp of Arrival [10ns] */ + uint8_t ucMaxToDErr; /* Maximum of ToD Error [10ns] */ + uint8_t ucMaxToAErr; /* Maximum of ToA Error [10ns] */ +} __KAL_ATTRIB_PACKED__; + +struct IE_WFA_OSEN { + uint8_t ucId; + uint8_t ucLength; + uint8_t aucOui[3]; + uint8_t ucOuiType; + uint32_t u4GroupKeyCipherSuite; + uint16_t u2PairwiseKeyCipherSuiteCount; + uint8_t aucPairwiseKeyCipherSuite1[4]; +}; + +/* 8.5.23.4 Operating Mode Notification frame format */ +struct ACTION_OP_MODE_NOTIFICATION_FRAME { + /* MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2Duration; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* Operating Mode Notification frame body */ + uint8_t ucCategory; /* Category */ + uint8_t ucAction; /* Action Value */ + uint8_t ucOperatingMode; /* Operating Mode */ +} __KAL_ATTRIB_PACKED__; + +/* 8.5.12.3 SM Power Save frame format */ +struct ACTION_SM_POWER_SAVE_FRAME { + /* MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2Duration; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* SM power save frame body */ + uint8_t ucCategory; /* Category */ + uint8_t ucAction; /* Action Value */ + uint8_t ucSmPowerCtrl; /* SM Power Control (see 8.4.1.22) */ +} __KAL_ATTRIB_PACKED__; + +/* 8.5.12.2 Notify Channel Width frame format */ +struct ACTION_NOTIFY_CHANNEL_WIDTH_FRAME { + /* MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2Duration; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* SM power save frame body */ + uint8_t ucCategory; /* Category */ + uint8_t ucAction; /* Action Value */ + uint8_t ucChannelWidth; /* Channel Width (see 8.4.1.21) */ +} __KAL_ATTRIB_PACKED__; + +#if (CFG_SUPPORT_TWT == 1) +/* 11ax TWT Setup frame format */ +struct _ACTION_TWT_SETUP_FRAME { + /* MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2Duration; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* TWT Setup frame body */ + uint8_t ucCategory; /* Category */ + uint8_t ucAction; /* Action Value */ + uint8_t ucDialogToken; /* Dialog Token */ + struct _IE_TWT_T rTWT; /* TWT element */ +} __KAL_ATTRIB_PACKED__; + +/* 11ax TWT Teardown frame format */ +struct _ACTION_TWT_TEARDOWN_FRAME { + /* MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2Duration; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* TWT Teardown frame body */ + uint8_t ucCategory; /* Category */ + uint8_t ucAction; /* Action Value */ + uint8_t ucTWTFlow; /* TWT Flow */ +} __KAL_ATTRIB_PACKED__; + +/* 11ax TWT Information frame format */ +struct _ACTION_TWT_INFO_FRAME { + /* MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2Duration; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* TWT Information frame body */ + uint8_t ucCategory; /* Category */ + uint8_t ucAction; /* Action Value */ + uint8_t ucNextTWTCtrl; + uint8_t aucNextTWT[0]; +} __KAL_ATTRIB_PACKED__; +#endif + +/* 3 Information Elements from WFA. */ +struct IE_WFA { + uint8_t ucId; + uint8_t ucLength; + uint8_t aucOui[3]; + uint8_t ucOuiType; + uint8_t aucOuiSubTypeVersion[2]; + /*!< Please be noted. WPA defines a 16 bit field version */ + /* instead of one subtype field and one version field */ +} __KAL_ATTRIB_PACKED__; + +#if CFG_SUPPORT_PASSPOINT +/* HS20 3.1 - HS 2.0 Indication Information Element */ +struct IE_HS20_INDICATION { + uint8_t ucId; /* Element ID */ + uint8_t ucLength; /* Length */ + uint8_t aucOui[3]; /* OUI */ + uint8_t ucType; /* Type */ + uint8_t ucHotspotConfig; /* Hotspot Configuration */ +} __KAL_ATTRIB_PACKED__; +#endif /* CFG_SUPPORT_PASSPOINT */ + +/* WAPI Information element format */ +struct WAPI_INFO_ELEM { + uint8_t ucElemId; + uint8_t ucLength; + uint16_t u2Version; + uint16_t u2AKMSuiteCount; + uint32_t u4AKMSuite; + uint16_t u2PairSuiteCount; + uint32_t u4PairSuite; + uint32_t u4GroupSuite; + uint16_t u2WapiCap; +} __KAL_ATTRIB_PACKED__; + +/* Information Elements from MTK Synergies.*/ +struct IE_MTK_OUI { + uint8_t ucId; + uint8_t ucLength; + uint8_t aucOui[3]; + uint8_t aucCapability[4]; + uint8_t aucInfoElem[1]; +} __KAL_ATTRIB_PACKED__; + +struct SUB_IE_BSS_TERM_DURATION { + uint8_t ucSubId; + uint8_t ucLength; + uint8_t aucTermTsf[8]; + uint16_t u2Duration; +} __KAL_ATTRIB_PACKED__; + +struct SUB_IE_BSS_CAND_PREFERENCE { + uint8_t ucSubId; + uint8_t ucLength; + uint8_t ucPreference; +} __KAL_ATTRIB_PACKED__; + +struct ACTION_BTM_QUERY_FRAME { + /* MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2Duration; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* BSS Coexistence Management frame body */ + uint8_t ucCategory; /* Category */ + uint8_t ucAction; /* Action Value */ + + uint8_t ucDialogToken; + uint8_t ucQueryReason; + uint8_t *pucNeighborBss; +} __KAL_ATTRIB_PACKED__; + +struct ACTION_BTM_REQ_FRAME { + /* MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2Duration; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* BSS Coexistence Management frame body */ + uint8_t ucCategory; /* Category */ + uint8_t ucAction; /* Action Value */ + + uint8_t ucDialogToken; + uint8_t ucRequestMode; + uint16_t u2DisassocTimer; + uint8_t ucValidityInterval; + uint8_t aucOptInfo[0]; + /* Optional: Bss Termination Duration(0~12 bytes), + ** Session Information URL, Bss Transition Candidate List + */ +} __KAL_ATTRIB_PACKED__; + +struct ACTION_BTM_RSP_FRAME { + /* MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2Duration; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* BSS Coexistence Management frame body */ + uint8_t ucCategory; /* Category */ + uint8_t ucAction; /* Action Value */ + + uint8_t ucDialogToken; + uint8_t ucStatusCode; + uint8_t ucBssTermDelay; + uint8_t aucOptInfo[0]; + /* Optional Target BSSID and Transition Candidate Entry list */ +} __KAL_ATTRIB_PACKED__; + +struct IE_MOBILITY_DOMAIN { + uint8_t ucId; /* Element ID = 54 */ + uint8_t ucLength; /* Length is 3 */ + uint16_t u2MDID; + /* Bit 0: FT over DS; Bit 1: Resource Request Protocol Capbility, + ** others: reserved + */ + uint8_t ucBitMap; +} __KAL_ATTRIB_PACKED__; + +struct IE_FAST_TRANSITION { + uint8_t ucId; /* Element ID = 55 */ + uint8_t ucLength; /* Length is variable */ + /* Bit 0 ~ Bit 7: reserved; Bit 8 ~ Bit 15: IE count + ** used to calculate MIC, 0 means No MIC + */ + uint8_t ucMicCtrl; + uint8_t aucMic[16]; /* */ + uint8_t aucANonce[32]; /* Nonce of R1KH */ + uint8_t aucSNonce[32]; /* Nonce of S1KH */ + uint8_t aucOptParam[0]; +} __KAL_ATTRIB_PACKED__; + +struct SUB_IE_FAST_TRANSITION { + uint8_t ucSubId; /* 0, 4-255: reserved; 1: R1KH-ID; 2: GTK; 3: R0KH-ID + */ + uint8_t ucLength; /* bytes, R1KH-ID: 6; GTK: 15-42; R0KH-ID: 1-48 */ + uint8_t aucData[1]; +} __KAL_ATTRIB_PACKED__; + +struct SUB_IE_GTK { + uint8_t ucSubId; /* subId=2 */ + uint8_t ucLength; /* length is 15-42 */ + uint16_t u2KeyInfo; /* Bit0-Bit1: Key ID; Bit2-Bit15: reserved */ + uint8_t ucKeyLength; + uint8_t aucRsc[8]; + uint8_t aucKey[5]; +} __KAL_ATTRIB_PACKED__; + +/* 8.5.7.4 Link Measurement Request frame format */ +struct ACTION_LM_REQUEST_FRAME { + /* Link Measurement Request MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2Duration; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* Link Measurement Request frame body */ + uint8_t ucCategory; /* Category */ + uint8_t ucAction; /* Action Value */ + uint8_t ucDialogToken; /* Dialog Token */ + uint8_t ucTxPowerUsed; /* */ + uint8_t ucTxPowerMax; /* */ + uint8_t aucInfoElem[1]; /* subelements */ +} __KAL_ATTRIB_PACKED__; + +/* 8.5.7.5 Link Measurement Report frame format */ +struct ACTION_LM_REPORT_FRAME { + /* Link Measurement Report MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2Duration; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* Link Measurement Report frame body */ + uint8_t ucCategory; /* Category */ + uint8_t ucAction; /* Action Value */ + uint8_t ucDialogToken; /* Dialog Token */ + uint8_t aucTpcReportIE[4]; /* */ + uint8_t ucRxAntennaID; + uint8_t ucTxAntennaID; + uint8_t ucRCPI; + uint8_t ucRSNI; + uint8_t aucInfoElem[1]; /* subelements */ +} __KAL_ATTRIB_PACKED__; + +struct IE_REQUEST { + uint8_t ucId; /* ELEM_ID_REQUEST */ + uint8_t ucLength; /* 0 to 237 */ + uint8_t aucReqIds[0]; +} __KAL_ATTRIB_PACKED__; + +struct IE_AP_CHNL_REPORT { + uint8_t ucId; /* ELEM_ID_AP_CHANNEL_REPORT */ + uint8_t ucLength; /* 1 to 237 */ + uint8_t ucOpClass; + uint8_t aucChnlList[0]; +} __KAL_ATTRIB_PACKED__; + +struct SUB_IE_REPORTING_DETAIL { + uint8_t ucSubID; /* 2 */ + uint8_t ucLength; + /* 0: No fixed length fields or elemets. 1: all fixed length fields and + ** requested IEs 2: + */ + uint8_t ucDetailValue; +} __KAL_ATTRIB_PACKED__; + +struct IE_TSPEC_BODY { + uint8_t aucTsInfo[3]; /* TS info field */ + uint16_t u2NominalMSDUSize; /* nominal MSDU size */ + uint16_t u2MaxMSDUsize; /* maximum MSDU size */ + uint32_t u4MinSvcIntv; /* minimum service interval */ + uint32_t u4MaxSvcIntv; /* maximum service interval */ + uint32_t u4InactIntv; /* inactivity interval */ + uint32_t u4SpsIntv; /* suspension interval */ + uint32_t u4SvcStartTime; /* service start time */ + uint32_t u4MinDataRate; /* minimum Data rate */ + uint32_t u4MeanDataRate; /* mean data rate */ + uint32_t u4PeakDataRate; /* peak data rate */ + uint32_t u4MaxBurstSize; /* maximum burst size */ + uint32_t u4DelayBound; /* delay bound */ + uint32_t u4MinPHYRate; /* minimum PHY rate */ + uint16_t u2Sba; /* surplus bandwidth allowance */ + uint16_t u2MediumTime; /* medium time */ +} __KAL_ATTRIB_PACKED__; + +struct WMM_ACTION_TSPEC_FRAME { + /* DELTS MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2DurationID; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* DELTS frame body */ + uint8_t ucCategory; /* Category, value is 17 */ + uint8_t ucAction; /* Action Value, value: 2, delts */ + uint8_t ucDlgToken; + uint8_t ucStatusCode; + uint8_t aucInfoElem[1]; +} __KAL_ATTRIB_PACKED__; + +/* 9.4.2.46 Multiple BSSID element */ +struct IE_MBSSID { + uint8_t ucId; + uint8_t ucLength; + uint8_t ucMaxBSSIDIndicator; + uint8_t ucSubelements[1]; +} __KAL_ATTRIB_PACKED__; + +/* 9.4.2.74 Multiple BSSID-Index element */ +struct IE_MBSSID_INDEX { + uint8_t ucId; + uint8_t ucLength; + uint8_t ucBSSIDIndex; + uint8_t ucDtimPeriod; + uint8_t ucDtimCount; +} __KAL_ATTRIB_PACKED__; + +#if defined(WINDOWS_DDK) || defined(WINDOWS_CE) +#pragma pack() +#endif + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ +/* Convert the ECWmin(max) to CWmin(max) */ +#define ECW_TO_CW(_ECW) ((1 << (_ECW)) - 1) + +/* Convert the RCPI to dBm */ +#define RCPI_TO_dBm(_rcpi) \ + ((int32_t)(((_rcpi) > RCPI_HIGH_BOUND ? \ + RCPI_HIGH_BOUND : (_rcpi)) >> 1) - NDBM_LOW_BOUND_FOR_RCPI) + +/* Convert the dBm to RCPI */ +#define dBm_TO_RCPI(_dbm) \ + (uint8_t)(((((int32_t)(_dbm) + NDBM_LOW_BOUND_FOR_RCPI) << 1) \ + > RCPI_HIGH_BOUND) ? RCPI_HIGH_BOUND : \ + ((((int32_t)(_dbm) + NDBM_LOW_BOUND_FOR_RCPI) << 1) \ + < RCPI_LOW_BOUND ? RCPI_LOW_BOUND : \ + (((int32_t)(_dbm) + NDBM_LOW_BOUND_FOR_RCPI) << 1))) + +/* Convert an unsigned char pointer to an information element pointer */ +#define IE_ID(fp) (((struct IE_HDR *) fp)->ucId) +#define IE_LEN(fp) (((struct IE_HDR *) fp)->ucLength) +#define IE_ID_EXT(fp) (((struct IE_HDR *) fp)->aucInfo[0]) +#define IE_SIZE(fp) (ELEM_HDR_LEN + IE_LEN(fp)) + +#define SSID_IE(fp) ((struct IE_SSID *) fp) + +#define SUP_RATES_IE(fp) ((struct IE_SUPPORTED_RATE *) fp) + +#define SUP_RATES_IOT_IE(fp) ((struct IE_SUPPORTED_RATE_IOT *) fp) + +#define DS_PARAM_IE(fp) ((struct IE_DS_PARAM_SET *) fp) + +#define TIM_IE(fp) ((struct IE_TIM *) fp) + +#define IBSS_PARAM_IE(fp) ((struct IE_IBSS_PARAM_SET *) fp) + +#define ERP_INFO_IE(fp) ((struct IE_ERP *) fp) + +#define EXT_SUP_RATES_IE(fp) ((struct IE_EXT_SUPPORTED_RATE *) fp) + +#define WFA_IE(fp) ((struct IE_WFA *) fp) + +#if CFG_SUPPORT_802_11D +#define COUNTRY_IE(fp) ((struct IE_COUNTRY *) fp) +#endif + +#define EXT_CAP_IE(fp) ((struct IE_EXT_CAP *) fp) + +#define HT_CAP_IE(fp) ((struct IE_HT_CAP *) fp) + +#define POWER_CAP_IE(fp) ((struct IE_POWER_CAP *) fp) + +#define SUP_CH_IE(fp) ((struct IE_SUPPORTED_CHANNELS *) fp) + +#define HT_OP_IE(fp) ((struct IE_HT_OP *) fp) + +#define VHT_CAP_IE(fp) ((struct IE_VHT_CAP *) fp) + +#define VHT_OP_IE(fp) ((struct IE_VHT_OP *) fp) + +#define OBSS_SCAN_PARAM_IE(fp) ((struct IE_OBSS_SCAN_PARAM *) fp) + +#define BSS_20_40_COEXIST_IE(fp) ((struct IE_20_40_COEXIST *) fp) + +#define SUP_OPERATING_CLASS_IE(fp) ((struct IE_SUP_OPERATING_CLASS *) fp) + +#define QUIET_IE(fp) ((struct IE_QUIET *) fp) + +#define MTK_OUI_IE(fp) ((struct IE_MTK_OUI *) fp) + +#define CSA_IE(fp) ((struct IE_CHANNEL_SWITCH *) fp) + +#define SUPPORTED_CHANNELS_IE(fp) ((struct IE_SUPPORTED_CHANNELS *)fp) +#define TIMEOUT_INTERVAL_IE(fp) ((struct IE_TIMEOUT_INTERVAL *)fp) + +#define SM_TPC_REQ_IE(fp) ((struct IE_TPC_REQ *) fp) +#define SM_TPC_REP_IE(fp) ((struct IE_TPC_REPORT *) fp) +#define SM_MEASUREMENT_REQ_IE(fp) ((struct IE_MEASUREMENT_REQ *) fp) +#define SM_MEASUREMENT_REP_IE(fp) ((struct IE_MEASUREMENT_REPORT *) fp) +#define SM_BASIC_REQ_IE(fp) ((struct SM_BASIC_REQ *) fp) + +#define MBSSID_IE(fp) ((struct IE_MBSSID *) fp) +#define MBSSID_INDEX_IE(fp) ((struct IE_MBSSID_INDEX *) fp) + +/* The macro to check if the MAC address is B/MCAST Address */ +#define IS_BMCAST_MAC_ADDR(_pucDestAddr) \ + ((u_int8_t) (((uint8_t *)(_pucDestAddr))[0] & BIT(0))) + +/* The macro to check if the MAC address is UCAST Address */ +#define IS_UCAST_MAC_ADDR(_pucDestAddr) \ + ((u_int8_t) !(((uint8_t *)(_pucDestAddr))[0] & BIT(0))) + +/* The macro to copy the MAC address */ +#define COPY_MAC_ADDR(_pucDestAddr, _pucSrcAddr) \ + kalMemCopy(_pucDestAddr, _pucSrcAddr, MAC_ADDR_LEN) + +/* The macro to check if two MAC addresses are equal */ +#define EQUAL_MAC_ADDR(_pucDestAddr, _pucSrcAddr) \ + (!kalMemCmp(_pucDestAddr, _pucSrcAddr, MAC_ADDR_LEN)) + +/* The macro to check if two MAC addresses are not equal */ +#define UNEQUAL_MAC_ADDR(_pucDestAddr, _pucSrcAddr) \ + (kalMemCmp(_pucDestAddr, _pucSrcAddr, MAC_ADDR_LEN)) + +/* The macro to check whether two SSIDs are equal */ +#define EQUAL_SSID(pucSsid1, ucSsidLen1, pucSsid2, ucSsidLen2) \ + ((ucSsidLen1 <= ELEM_MAX_LEN_SSID) && \ + (ucSsidLen2 <= ELEM_MAX_LEN_SSID) && \ + ((ucSsidLen1) == (ucSsidLen2)) && \ + !kalMemCmp(pucSsid1, pucSsid2, ucSsidLen1)) + +/* The macro to check whether two SSIDs are equal */ +#define UNEQUAL_SSID(pucSsid1, ucSsidLen1, pucSsid2, ucSsidLen2) \ + ((ucSsidLen1 > ELEM_MAX_LEN_SSID) || \ + (ucSsidLen2 > ELEM_MAX_LEN_SSID) || \ + ((ucSsidLen1) != (ucSsidLen2)) || \ + kalMemCmp(pucSsid1, pucSsid2, ucSsidLen1)) + +/* The macro to copy the SSID, the length of pucDestSsid + * should have at least 32 bytes + */ +#define COPY_SSID(pucDestSsid, ucDestSsidLen, pucSrcSsid, ucSrcSsidLen) \ + do { \ + ucDestSsidLen = (ucSrcSsidLen > ELEM_MAX_LEN_SSID) \ + ? ELEM_MAX_LEN_SSID : ucSrcSsidLen; \ + if (ucDestSsidLen) { \ + kalMemCopy(pucDestSsid, pucSrcSsid, ucDestSsidLen); \ + } \ + } while (FALSE) + +/* The macro to copy the IE */ +#define COPY_IE(pucDestIE, pucSrcIE) \ + do { \ + kalMemCopy((uint8_t *)pucDestIE, \ + (uint8_t *)pucSrcIE,\ + IE_SIZE(pucSrcIE)); \ + } while (FALSE) + +#define IE_FOR_EACH(_pucIEsBuf, _u2IEsBufLen, _u2Offset) \ +for ((_u2Offset) = 0; \ + ((((_u2Offset) + 2) <= (_u2IEsBufLen)) && \ + (((_u2Offset) + IE_SIZE(_pucIEsBuf)) <= (_u2IEsBufLen))); \ + (_u2Offset) += IE_SIZE(_pucIEsBuf), (_pucIEsBuf) += IE_SIZE(_pucIEsBuf)) + +#define SET_EXT_CAP(_aucField, _ucFieldLength, _ucBit) \ +do { \ + if ((_ucBit) < ((_ucFieldLength) * 8)) { \ + uint8_t *aucExtCap = (uint8_t *)(_aucField); \ + ((aucExtCap)[(_ucBit) / 8]) |= BIT((_ucBit) % 8); \ + } \ +} while (FALSE) + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#endif /* _MAC_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/mt66xx_reg.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/mt66xx_reg.h new file mode 100644 index 0000000000000000000000000000000000000000..c2c5184810a1672c64469269a5515a7de58ae049 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/mt66xx_reg.h @@ -0,0 +1,1438 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/*! \file "mt66xx_reg.h" + * \brief The common register definition of MT6630 + * + * N/A + */ + + + +#ifndef _MT66XX_REG_H +#define _MT66XX_REG_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#ifdef MT6632 +extern struct mt66xx_hif_driver_data mt66xx_driver_data_mt6632; +#endif /* MT6632 */ +#ifdef MT7668 +extern struct mt66xx_hif_driver_data mt66xx_driver_data_mt7668; +#endif /* MT7668 */ +#ifdef MT7663 +extern struct mt66xx_hif_driver_data mt66xx_driver_data_mt7663; +#endif /* MT7663 */ +#ifdef CONNAC +extern struct mt66xx_hif_driver_data mt66xx_driver_data_connac; +#endif /* CONNAC */ +#ifdef CONNAC2X2 +extern struct mt66xx_hif_driver_data mt66xx_driver_data_connac2x2; +#endif /* CONNAC2X2 */ +#ifdef UT_TEST_MODE +extern struct mt66xx_hif_driver_data mt66xx_driver_data_ut; +#endif /* UT_TEST_MODE */ +#ifdef MT7915 +extern struct mt66xx_hif_driver_data mt66xx_driver_data_mt7915; +#endif /* MT7915 */ +#ifdef SOC3_0 +extern struct mt66xx_hif_driver_data mt66xx_driver_data_soc3_0; +#endif /* SOC3_0 */ +#ifdef MT7961 +extern struct mt66xx_hif_driver_data mt66xx_driver_data_mt7961; +#endif /* MT7961 */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +/* 1 MT6630 MCR Definition */ + +/* 2 Host Interface */ + +/* #define TOP_CFG_BASE 0x0000 */ +#define TOP_CFG_BASE 0x80020000 +#define TOP_RGU_BASE 0x81020000 +#define TOP_CFG_AON_base 0x81021000 +#define MCU_CFG_BASE 0x80000000 + +#define TOP_HVR (TOP_CFG_BASE + 0x1000) +#define HW_VER_MASK (0xffff) +#define GET_HW_VER(p) (((p) & HW_VER_MASK)) +#define RESC_CID_MASK (0xf << 28) +#define GET_RESC_CID(p) (((p) & RESC_CID_MASK) >> 28) + +#define TOP_FVR (TOP_CFG_BASE + 0x1004) +#define FW_VER_MASK (0xffff) +#define GET_FW_VER(p) (((p) & FW_VER_MASK)) + +#define TOP_HCR (TOP_CFG_BASE + 0x1008) +#define HW_CODE_MASK (0xffff) +#define GET_HW_CODE(p) (((p) & HW_CODE_MASK)) + +#define STRAP_STA (TOP_CFG_BASE + 0x1010) +#define XTAL_SEL_MASK (0x3) +#define GET_XTAL_SEL(p) (((p) & XTAL_SEL_MASK)) +#define EEPROM_SEL (1 << 2) +#define GET_EEPROM_SEL(p) (((p) & EEPROM_SEL) >> 2) +#define CO_CLOCK_SEL (1 << 8) +#define GET_CO_CLOCK_SEL(p) (((p) & CO_CLOCK_SEL) >> 8) +#define ONE_ANT (1 << 24) +#define GET_ONE_ANT(p) (((p) & ONE_ANT) >> 24) +#define USB_MODE (1 << 25) +#define GET_USB_MODE(p) (((p) & USB_MODE) >> 25) + +#define TOP_MISC2 (TOP_CFG_BASE + 0x1134) + +#define TOP_CKGEN2_CR_PMIC_CK_MANUAL (TOP_CFG_AON_base + 0x00000108) +#define TOP_CKGEN2_CR_PMIC_CK_MANUAL_MASK 0x00080000 + +#define MTK_CHIP_REV 0x00006632 + +#define WIFI_RGU_SW_SYNC0 (TOP_RGU_BASE + 0x1250) +#define WIFI_RGU_SYNC0_RDY_OFFSET (0) +#define MCU_CFG_PCIE_REMAP1 (MCU_CFG_BASE + 0x0500) +#define PCIE_REMAP1_OFFSET (18) +#define PCIE_REMAP1_MASK (BITS(18, 31)) +#define PCIE_REMAP1_BUS_ADDR (0x40000) +#define MCU_CFG_PCIE_REMAP2 (MCU_CFG_BASE + 0x0504) +#define PCIE_REMAP2_OFFSET (19) +#define PCIE_REMAP2_MASK (BITS(19, 31)) +#define PCIE_REMAP2_BUS_ADDR (0x80000) + + + +/* UMAC Register */ +#define UMAC_PLE_CR_CFG_BASE_ADDR 0x82060000 +#define UMAC_PSE_CR_CFG_BASE_ADDR 0x82068000 + +#define UMAC_PSE_PLE_CR_ADDR_DIFF \ + (UMAC_PSE_CR_CFG_BASE_ADDR - UMAC_PLE_CR_CFG_BASE_ADDR) +#define UMAC_PSE_CR_BITMAP_OFFSET 15 +#define UMAC_PSE_PLE_ADDR_DIFF_MAR(_x) \ + (_x << UMAC_PSE_CR_BITMAP_OFFSET) + + +#define UMAC_PLE_BASE_ADDRESS (0xa << 28) + +#define UMAC_PSE_BASE_ADDRESS (0xb << 28) + +#define UMAC_FID_SHIFT_16_BIT_VM_MAP 16 + +#define UMAC_BASE(_x) \ + (UMAC_PLE_CR_CFG_BASE_ADDR | (_x << UMAC_PSE_CR_BITMAP_OFFSET)) + +#define UMAC_RESET(_x) (UMAC_BASE(_x) + 0x00000000) + +#define UMAC_INT_CR4_EN_MASK(_x) (UMAC_BASE(_x) + 0x00000004) +#define UMAC_INT_CR4_STS(_x) (UMAC_BASE(_x) + 0x00000008) +#define UMAC_INT_CR4_ERR_RES(_x) (UMAC_BASE(_x) + 0x0000000C) +#define UMAC_INT_CR4_ERR_MASK(_x) (UMAC_BASE(_x) + 0x00000010) + + + +#define UMAC_PBUF_CTRL(_x) (UMAC_BASE(_x) + 0x00000014) + +#define UMAC_CHIP_ID_VER(_x) (UMAC_BASE(_x) + 0x00000018) + +#define UMAC_TIMER_CNF(_x) (UMAC_BASE(_x) + 0x0000001C) + +#define UMAC_INT_N9_EN_MASK(_x) (UMAC_BASE(_x) + 0x00000020) +#define UMAC_INT_N9_STS(_x) (UMAC_BASE(_x) + 0x00000024) +#define UMAC_INT_N9_ERR_STS(_x) (UMAC_BASE(_x) + 0x00000028) +#define UMAC_INT_N9_ERR_MASK(_x) (UMAC_BASE(_x) + 0x0000002C) +#define UMAC_IGNORE_BUSY_EN_MASK(_x) (UMAC_BASE(_x) + 0x0000038C) + +#define UMAC_RELEASE_CTRL(_x) (UMAC_BASE(_x) + 0x00000030) + +#define UMAC_HIF_REPROT(_x) (UMAC_BASE(_x) + 0x00000034) + + +#define UMAC_C_GET_FID_0(_x) (UMAC_BASE(_x) + 0x00000040) +#define UMAC_C_GET_FID_1(_x) (UMAC_BASE(_x) + 0x00000044) + +#define UMAC_C_EN_QUEUE_0(_x) (UMAC_BASE(_x) + 0x00000060) +#define UMAC_C_EN_QUEUE_1(_x) (UMAC_BASE(_x) + 0x00000064) +#define UMAC_C_EN_QUEUE_2(_x) (UMAC_BASE(_x) + 0x00000068) + + +#define UMAC_C_DE_QUEUE_0(_x) (UMAC_BASE(_x) + 0x00000080) +#define UMAC_C_DE_QUEUE_1(_x) (UMAC_BASE(_x) + 0x00000084) +#define UMAC_C_DE_QUEUE_2(_x) (UMAC_BASE(_x) + 0x00000088) +#define UMAC_C_DE_QUEUE_3(_x) (UMAC_BASE(_x) + 0x0000008C) + +#define UMAC_ALLOCATE_0(_x) (UMAC_BASE(_x) + 0x000000A0) +#define UMAC_ALLOCATE_1(_x) (UMAC_BASE(_x) + 0x000000A4) +#define UMAC_ALLOCATE_2(_x) (UMAC_BASE(_x) + 0x000000A8) + +#define UMAC_QUEUE_EMPTY(_x) (UMAC_BASE(_x) + 0x000000B0) + +/* 0x820680B4 QUEUE_EMPTY_MASK Queue empty status mask register, + * 7615 E3 eco item only PSE with this setting, but ple + */ +#define UMAC_QUEUE_EMPTY_MASK \ + (UMAC_BASE(UMAC_PSE_CFG_POOL_INDEX) + 0x000000B4) + +#define UMAC_TO_CR4_INT(_x) (UMAC_BASE(_x) + 0x000000e0) +#define UMAC_TO_N9_INT(_x) (UMAC_BASE(_x) + 0x000000f0) + + +#define UMAC_FREEPG_CNT(_x) (UMAC_BASE(_x) + 0x00000100) + +#define UMAC_FREEPG_HEAD_TAIL(_x) (UMAC_BASE(_x) + 0x00000104) + + +#define UMAC_PG_HIF0_GROUP(_x) (UMAC_BASE(_x) + 0x00000110) +#define UMAC_HIF0_PG_INFO(_x) (UMAC_BASE(_x) + 0x00000114) + +#define UMAC_PG_HIF1_GROUP(_x) (UMAC_BASE(_x) + 0x00000118) +#define UMAC_HIF1_PG_INFO(_x) (UMAC_BASE(_x) + 0x0000011C) + +#define UMAC_PG_CPU_GROUP(_x) (UMAC_BASE(_x) + 0x00000150) +#define UMAC_CPU_PG_INFO(_x) (UMAC_BASE(_x) + 0x00000154) + + +#define UMAC_PG_LMAC0_GROUP(_x) (UMAC_BASE(_x) + 0x00000170) +#define UMAC_LMAC0_PG_INFO(_x) (UMAC_BASE(_x) + 0x00000174) + +#define UMAC_PG_LMAC1_GROUP(_x) (UMAC_BASE(_x) + 0x00000178) +#define UMAC_LMAC1_PG_INFO(_x) (UMAC_BASE(_x) + 0x0000017C) + + +#define UMAC_PG_LMAC2_GROUP(_x) (UMAC_BASE(_x) + 0x00000180) +#define UMAC_LMAC2_PG_INFO(_x) (UMAC_BASE(_x) + 0x00000184) + +#define UMAC_PG_PLE_GROUP(_x) (UMAC_BASE(_x) + 0x00000190) +#define UMAC_PLE_PG_INFO(_x) (UMAC_BASE(_x) + 0x00000194) + + +#define UMAC_RL_BUF_CTRL_0(_x) (UMAC_BASE(_x) + 0x000001A0) +#define UMAC_RL_BUF_CTRL_1(_x) (UMAC_BASE(_x) + 0x000001A4) + +#define UMAC_FL_QUE_CTRL_0(_x) (UMAC_BASE(_x) + 0x000001B0) +#define UMAC_FL_QUE_CTRL_1(_x) (UMAC_BASE(_x) + 0x000001B4) +#define UMAC_FL_QUE_CTRL_2(_x) (UMAC_BASE(_x) + 0x000001B8) +#define UMAC_FL_QUE_CTRL_3(_x) (UMAC_BASE(_x) + 0x000001BC) + +#define UMAC_HIF_ENQ_PKT_NUM(_x) (UMAC_BASE(_x) + 0x000001F0) +#define UMAC_CPU_ENQ_PKT_NUM(_x) (UMAC_BASE(_x) + 0x000001F4) +#define UMAC_RLS_MSDU_PKT_NUM(_x) (UMAC_BASE(_x) + 0x000001F8) +#define UMAC_HOST_REPORT_NUM(_x) (UMAC_BASE(_x) + 0x000001FC) + +#define UMAC_PL_QUE_CTRL_0(_x) (UMAC_BASE(_x) + 0x000001C0) + +#define UMAC_TP_HIF_EN(_x) (UMAC_BASE(_x) + 0x00000200) + +#define UMAC_TP_HIF_Q_CTRL0(_x) (UMAC_BASE(_x) + 0x00000204) +#define UMAC_TP_HIF_Q_CTRL1(_x) (UMAC_BASE(_x) + 0x00000208) +#define UMAC_TP_HIF_Q_CTRL2(_x) (UMAC_BASE(_x) + 0x0000020C) + +#define UMAC_TP_HIF_ALLOC0(_x) (UMAC_BASE(_x) + 0x00000210) +#define UMAC_TP_HIF_ALLOC1(_x) (UMAC_BASE(_x) + 0x00000214) + +#define UMAC_TP_HIF_OPER0(_x) (UMAC_BASE(_x) + 0x00000218) +#define UMAC_TP_HIF_OPER1(_x) (UMAC_BASE(_x) + 0x0000021C) + + +#define UMAC_TP_LMAC_EN(_x) (UMAC_BASE(_x) + 0x00000220) + +#define UMAC_TP_LMAC_Q_CTRL0(_x) (UMAC_BASE(_x) + 0x00000224) +#define UMAC_TP_LMAC_Q_CTRL1(_x) (UMAC_BASE(_x) + 0x00000228) +#define UMAC_TP_LMAC_Q_CTRL2(_x) (UMAC_BASE(_x) + 0x0000022C) + +#define UMAC_TP_LMAC_ALLOC0(_x) (UMAC_BASE(_x) + 0x00000230) +#define UMAC_TP_LMAC_ALLOC1(_x) (UMAC_BASE(_x) + 0x00000234) + +#define UMAC_TP_LMAC_OPER0(_x) (UMAC_BASE(_x) + 0x00000238) +#define UMAC_TP_LMAC_OPER1(_x) (UMAC_BASE(_x) + 0x0000023C) + +#define UMAC_STATE_IDLE_CTL(_x) (UMAC_BASE(_x) + 0x0000024C) + +#define UMAC_DIS_STA_MAP0(_x) (UMAC_BASE(_x) + 0x00000260) +#define UMAC_DIS_STA_MAP1(_x) (UMAC_BASE(_x) + 0x00000264) +#define UMAC_DIS_STA_MAP2(_x) (UMAC_BASE(_x) + 0x00000268) +#define UMAC_DIS_STA_MAP3(_x) (UMAC_BASE(_x) + 0x0000026c) + +#define UMAC_AC0_QUEUE_EMPTY0(_x) (UMAC_BASE(_x) + 0x00000300) +#define UMAC_AC0_QUEUE_EMPTY1(_x) (UMAC_BASE(_x) + 0x00000304) +#define UMAC_AC0_QUEUE_EMPTY2(_x) (UMAC_BASE(_x) + 0x00000308) +#define UMAC_AC0_QUEUE_EMPTY3(_x) (UMAC_BASE(_x) + 0x0000030C) + +#define UMAC_AC1_QUEUE_EMPTY0(_x) (UMAC_BASE(_x) + 0x00000310) +#define UMAC_AC1_QUEUE_EMPTY1(_x) (UMAC_BASE(_x) + 0x00000314) +#define UMAC_AC1_QUEUE_EMPTY2(_x) (UMAC_BASE(_x) + 0x00000318) +#define UMAC_AC1_QUEUE_EMPTY3(_x) (UMAC_BASE(_x) + 0x0000031C) + +#define UMAC_AC2_QUEUE_EMPTY0(_x) (UMAC_BASE(_x) + 0x00000320) +#define UMAC_AC2_QUEUE_EMPTY1(_x) (UMAC_BASE(_x) + 0x00000324) +#define UMAC_AC2_QUEUE_EMPTY2(_x) (UMAC_BASE(_x) + 0x00000328) +#define UMAC_AC2_QUEUE_EMPTY3(_x) (UMAC_BASE(_x) + 0x0000032C) + +#define UMAC_AC3_QUEUE_EMPTY0(_x) (UMAC_BASE(_x) + 0x00000330) +#define UMAC_AC3_QUEUE_EMPTY1(_x) (UMAC_BASE(_x) + 0x00000334) +#define UMAC_AC3_QUEUE_EMPTY2(_x) (UMAC_BASE(_x) + 0x00000338) +#define UMAC_AC3_QUEUE_EMPTY3(_x) (UMAC_BASE(_x) + 0x0000033C) + +#define UMAC_QUEUE_EMPTY_MASK \ + (UMAC_BASE(UMAC_PSE_CFG_POOL_INDEX) + 0x000000B4) + +/* BSS PS INT */ +#define UMAC_N9_BSS_PS_INT_EN \ + (UMAC_BASE(UMAC_PLE_CFG_POOL_INDEX) + 0x000000F4) +#define UMAC_N9_BSS_PS_INT_STS \ + (UMAC_BASE(UMAC_PLE_CFG_POOL_INDEX) + 0x000000F8) + +/* CR for VoW and BW Ctrl */ + +#define UMAC_DRR_TABLE_CTRL0 \ + (UMAC_BASE(UMAC_PLE_CFG_POOL_INDEX) + 0x00000388) + +#define UMAC_DRR_TABLE_WDATA0 \ + (UMAC_BASE(UMAC_PLE_CFG_POOL_INDEX) + 0x00000340) +#define UMAC_DRR_TABLE_WDATA1 \ + (UMAC_BASE(UMAC_PLE_CFG_POOL_INDEX) + 0x00000344) +#define UMAC_DRR_TABLE_WDATA2 \ + (UMAC_BASE(UMAC_PLE_CFG_POOL_INDEX) + 0x00000348) +#define UMAC_DRR_TABLE_WDATA3 \ + (UMAC_BASE(UMAC_PLE_CFG_POOL_INDEX) + 0x0000034C) + + +#define UMAC_DRR_TABLE_RDATA0 \ + (UMAC_BASE(UMAC_PLE_CFG_POOL_INDEX) + 0x00000350) +#define UMAC_DRR_TABLE_RDATA1 \ + (UMAC_BASE(UMAC_PLE_CFG_POOL_INDEX) + 0x00000354) +#define UMAC_DRR_TABLE_RDATA2 \ + (UMAC_BASE(UMAC_PLE_CFG_POOL_INDEX) + 0x00000358) +#define UMAC_DRR_TABLE_RDATA3 \ + (UMAC_BASE(UMAC_PLE_CFG_POOL_INDEX) + 0x0000035C) + + +#define UMAC_STATION_PAUSE_0 \ + (UMAC_BASE(UMAC_PLE_CFG_POOL_INDEX) + 0x00000360) +#define UMAC_STATION_PAUSE_1 \ + (UMAC_BASE(UMAC_PLE_CFG_POOL_INDEX) + 0x00000364) +#define UMAC_STATION_PAUSE_2 \ + (UMAC_BASE(UMAC_PLE_CFG_POOL_INDEX) + 0x00000368) +#define UMAC_STATION_PAUSE_3 \ + (UMAC_BASE(UMAC_PLE_CFG_POOL_INDEX) + 0x0000036C) +#define UMAC_VOW_ENABLE \ + (UMAC_BASE(UMAC_PLE_CFG_POOL_INDEX) + 0x00000370) +#define UMAC_AIR_TIME_DRR_SIZE \ + (UMAC_BASE(UMAC_PLE_CFG_POOL_INDEX) + 0x00000374) +#define UMAC_CHECK_TIME_TOKEN \ + (UMAC_BASE(UMAC_PLE_CFG_POOL_INDEX) + 0x00000378) +#define UMAC_CHECK_LENGTH_TOKEN \ + (UMAC_BASE(UMAC_PLE_CFG_POOL_INDEX) + 0x0000037C) +#define UMAC_WDRR0 \ + (UMAC_BASE(UMAC_PLE_CFG_POOL_INDEX) + 0x00000380) +#define UMAC_WDRR1 \ + (UMAC_BASE(UMAC_PLE_CFG_POOL_INDEX) + 0x00000384) + +#define UMAC_VOW_CTRL1 \ + (UMAC_BASE(UMAC_PLE_CFG_POOL_INDEX) + 0x0000038C) + +#define UMAC_VOW_DBG_MUX \ + (UMAC_BASE(UMAC_PLE_CFG_POOL_INDEX) + 0x000003A0) +#define UMAC_AIRTIME_DBG_INFO0 \ + (UMAC_BASE(UMAC_PLE_CFG_POOL_INDEX) + 0x000003A4) +#define UMAC_AIRTIME_DBG_INFO1 \ + (UMAC_BASE(UMAC_PLE_CFG_POOL_INDEX) + 0x000003A8) + +#define UMAC_BW_DBG_INFO \ + (UMAC_BASE(UMAC_PLE_CFG_POOL_INDEX) + 0x000003AC) + +#define UMAC_BW_WDRR0 \ + (UMAC_BASE(UMAC_PLE_CFG_POOL_INDEX) + 0x000003B0) +#define UMAC_BW_WDRR1 \ + (UMAC_BASE(UMAC_PLE_CFG_POOL_INDEX) + 0x000003B4) +#define UMAC_BW_WDRR2 \ + (UMAC_BASE(UMAC_PLE_CFG_POOL_INDEX) + 0x000003B8) +#define UMAC_BW_WDRR3 \ + (UMAC_BASE(UMAC_PLE_CFG_POOL_INDEX) + 0x000003BC) +/* UMAC Register */ + + +#if defined(_HIF_USB) + +#define WIFI_CFG_SW_SYNC0 (TOP_CFG_BASE + 0x1128) +#define WIFI_CFG_SYNC0_RDY_OFFSET (16) + +/* UDMA register */ +#define UDMA_BASE 0x50029000 +#define UDMA_TX_QSEL (UDMA_BASE + 0x8) +#define FW_DL_EN (1 << 3) + +#define UDMA_RESET (UDMA_BASE + 0x14) + +#define UDMA_WLCFG_1 (UDMA_BASE + 0xc) +#define UDMA_WLCFG_1_TX_TMOUT_LMT_MASK (0xfffff << 8) +#define UDMA_WLCFG_1_TX_TMOUT_LMT(p) (((p) & 0xfffff) << 8) +#define UDMA_WLCFG_1_RX_AGG_PKT_LMT_MASK (0xff << 0) +#define UDMA_WLCFG_1_RX_AGG_PKT_LMT(p) (((p) & 0xff) << 0) + +#define UDMA_WLCFG_0 (UDMA_BASE + 0x18) +#define UDMA_WLCFG_0_TX_BT_SIZE_MASK (0x07 << 27) +#define UDMA_WLCFG_0_TX_BT_SIZE(p) (((p) & 0x07) << 27) +#define UDMA_WLCFG_0_RX_BT_SIZE_MASK (0x07 << 24) +#define UDMA_WLCFG_0_RX_BT_SIZE(p) (((p) & 0x07) << 24) +#define UDMA_WLCFG_0_TX_EN_MASK (0x1 << 23) +#define UDMA_WLCFG_0_TX_EN(p) (((p) & 0x1) << 23) +#define UDMA_WLCFG_0_RX_EN_MASK (0x1 << 22) +#define UDMA_WLCFG_0_RX_EN(p) (((p) & 0x1) << 22) +#define UDMA_WLCFG_0_RX_AGG_EN_MASK (0x1 << 21) +#define UDMA_WLCFG_0_RX_AGG_EN(p) (((p) & 0x1) << 21) +#define UDMA_WLCFG_0_LPK_EN_MASK (0x1 << 20) +#define UDMA_WLCFG_0_LPK_EN(p) (((p) & 0x1) << 20) +#define UDMA_WLCFG_0_RX_MPSZ_PAD0_MASK (0x1 << 18) +#define UDMA_WLCFG_0_RX_MPSZ_PAD0(p) (((p) & 0x1) << 18) +#define UDMA_WLCFG_0_RX_AGG_LMT_MASK (0xff << 8) +#define UDMA_WLCFG_0_RX_AGG_LMT(p) (((p) & 0xff) << 8) +#define UDMA_WLCFG_0_RX_AGG_TO_MASK (0xff << 0) +#define UDMA_WLCFG_0_RX_AGG_TO(p) (((p) & 0xff) << 0) + +#define PP_R_RXCUTDISP0 (0x8206C054) +#define PP_R_RXCUTDISP0_CT_EN_MASK (0x1 << 0) +#define PP_R_RXCUTDISP0_CT_EN(p) (((p) & 0x1) << 0) +#define PP_R_RXCUTDISP0_CR4_EN_MASK (0x1 << 1) +#define PP_R_RXCUTDISP0_CR4_EN(p) (((p) & 0x1) << 1) +#define PP_R_RXCUTDISP0_START_OFFSET_MASK (0x3fff << 2) +#define PP_R_RXCUTDISP0_START_OFFSET(p) (((p) & 0x3fff) << 2) +#define PP_R_RXCUTDISP0_END_OFFSET_MASK (0x3fff << 18) +#define PP_R_RXCUTDISP0_END_OFFSET(p) (((p) & 0x3fff) << 18) + + +#elif defined(_HIF_PCIE) || defined(_HIF_AXI) +#define RTC_TOP_BASE 0x0000 + +#define RTC_TOP_MISC2 (RTC_TOP_BASE + 0x1128) + +#define TOP_HIF_BASE 0x0000 +#define TOP_HW_VERSION 0x1000 +#define TOP_HW_CONTROL 0x1008 + +#define WIFI_CFG_SW_SYNC0 RTC_TOP_MISC2 +#define WIFI_CFG_SYNC0_RDY_OFFSET (16) + +#define PCIE_HIF_BASE 0x4000 +#define PCIE_NEW_HIF_BASE 0x7c030000 + +/* HIF Sys Revision */ +#define HIF_SYS_REV (PCIE_HIF_BASE + 0x0000) + +/* Check Enter Slepp Mode Register */ +#define CONN_DUMMY_CR (PCIE_HIF_BASE + 0x00A8) + +#define CONN_HIF_RST (PCIE_HIF_BASE + 0x0100) + +#define WPDMA_FIFO_TEST_MOD (PCIE_HIF_BASE + 0x0140) + +#define WPDMA_APSRC_ACK_LOCK_SLPPROT (PCIE_HIF_BASE + 0x0160) + +/* HIF Low Power Control Host Register */ +#define CFG_PCIE_LPCR_HOST (PCIE_HIF_BASE + 0x01F0) + +/* HIF Low Power Control Fw Register */ +#define CFG_PCIE_LPCR_FW (PCIE_HIF_BASE + 0x01F4) + +/* Interrupt Status */ +#define WPDMA_INT_STA (PCIE_HIF_BASE + 0x0200) + +/* Interrupt Mask */ +#define WPDMA_INT_MSK (PCIE_HIF_BASE + 0x0204) + +/* Global Configuration */ +#define WPDMA_GLO_CFG (PCIE_HIF_BASE + 0x0208) + +/* Pointer Reset */ +#define WPDMA_RST_PTR (PCIE_HIF_BASE + 0x020C) + +/* Configuration for WPDMA Delayed Interrupt */ +#define WPDMA_DELAY_INT_CFG (PCIE_HIF_BASE + 0x0210) + +#define WPDMA_PAUSE_RX_Q_TH10 (PCIE_HIF_BASE + 0x0260) +#define WPDMA_PAUSE_RX_Q_TH32 (PCIE_HIF_BASE + 0x0264) +#define WPDMA_PAUSE_RX_Q_TH0 2 +#define WPDMA_PAUSE_RX_Q_TH1 2 +#define WPDMA_PAUSE_RX_Q_TH2 2 +#define WPDMA_PAUSE_RX_Q_TH3 2 +#define WPDMA_PAUSE_RX_Q_TH0_MASK 0x00000FFF +#define WPDMA_PAUSE_RX_Q_TH1_MASK 0x0FFF0000 +#define WPDMA_PAUSE_RX_Q_TH2_MASK 0x00000FFF +#define WPDMA_PAUSE_RX_Q_TH3_MASK 0x0FFF0000 +#define WPDMA_PAUSE_RX_Q_TH0_SHFT 0 +#define WPDMA_PAUSE_RX_Q_TH1_SHFT 16 +#define WPDMA_PAUSE_RX_Q_TH2_SHFT 0 +#define WPDMA_PAUSE_RX_Q_TH3_SHFT 16 + +/* TX Ring0 Control 0 */ +#define WPDMA_TX_RING0_CTRL0 (PCIE_HIF_BASE + 0x0300) + +/* TX Ring0 Control 1 */ +#define WPDMA_TX_RING0_CTRL1 (PCIE_HIF_BASE + 0x0304) + +/* TX Ring0 Control 2 */ +#define WPDMA_TX_RING0_CTRL2 (PCIE_HIF_BASE + 0x0308) + +/* TX Ring0 Control 3 */ +#define WPDMA_TX_RING0_CTRL3 (PCIE_HIF_BASE + 0x030C) + +/* RX Ring0 Control 0 */ +#define WPDMA_RX_RING0_CTRL0 (PCIE_HIF_BASE + 0x0400) + +/* RX Ring0 Control 1 */ +#define WPDMA_RX_RING0_CTRL1 (PCIE_HIF_BASE + 0x0404) + +/* RX Ring0 Control 2 */ +#define WPDMA_RX_RING0_CTRL2 (PCIE_HIF_BASE + 0x0408) + +/* RX Ring0 Control 3 */ +#define WPDMA_RX_RING0_CTRL3 (PCIE_HIF_BASE + 0x040C) + +/* TX RING more than 32bits extension */ +#define WPDMA_TX_RING0_BASE_PTR_EXT (PCIE_HIF_BASE + 0x0500) + +/* RX RING more than 32bits extension */ +#define WPDMA_RX_RING0_BASE_PTR_EXT (PCIE_HIF_BASE + 0x0580) + +#define MT_WPDMA_GLO_CFG_1 (PCIE_HIF_BASE + 0x0500) + +#define MT_WPDMA_TX_PRE_CFG (PCIE_HIF_BASE + 0x0510) + +#define MT_WPDMA_RX_PRE_CFG (PCIE_HIF_BASE + 0x0520) + +#define MT_WPDMA_ABT_CFG (PCIE_HIF_BASE + 0x0530) + +#define MT_WPDMA_ABT_CFG1 (PCIE_HIF_BASE + 0x0534) + +#define MT_PCIE_IRQ_ENABLE (PCIE_NEW_HIF_BASE + 0x0188) + +#define MD_INT_STA (PCIE_HIF_BASE + 0x01C0) +#define MD_WPDMA_GLO_CFG (PCIE_HIF_BASE + 0x01D0) +#define MD_INT_ENA (PCIE_HIF_BASE + 0x01D4) +#define MD_WPDMA_DLY_INIT_CFG (PCIE_HIF_BASE + 0x01D8) +#define MD_WPDMA_MISC (PCIE_HIF_BASE + 0x01DC) + +#define CONN_HIF_PDMA_CSR_PDMA_SLP_PROT_ADDR (PCIE_HIF_BASE + 0x154) +#define CONN_HIF_PDMA_CSR_PDMA_SLP_PROT_PDMA_AXI_SLPPROT_ENABLE_MASK BIT(0) +#define CONN_HIF_PDMA_CSR_PDMA_SLP_PROT_PDMA_AXI_SLPPROT_RDY_MASK BIT(16) + +/* WPDMA_INT_STA */ +union WPDMA_INT_STA_STRUCT { + struct { + uint32_t rx_done_0:1; + uint32_t rx_done_1:1; + uint32_t err_det_int_0:1; + uint32_t err_det_int_1:1; + uint32_t tx_done:16; + uint32_t rx_coherent:1; + uint32_t tx_coherent:1; + uint32_t rx_dly_int:1; + uint32_t tx_dly_int:1; + uint32_t wf_mac_int_0:1; + uint32_t wf_mac_int_1:1; + uint32_t wf_mac_int_2:1; + uint32_t wf_mac_int_3:1; + uint32_t wf_mac_int_4:1; + uint32_t wf_mac_int_5:1; + uint32_t mcu_cmd_int:1; + uint32_t fw_clr_own:1; + } field; + + struct { + uint32_t rx_done_0:1; + uint32_t rx_done_1:1; + uint32_t rx_done_2:1; + uint32_t rx_done_3:1; + uint32_t tx_done:16; + uint32_t rx_coherent:1; + uint32_t tx_coherent:1; + uint32_t reserved:2; + uint32_t wpdma2host_err_int_en:1; + uint32_t tx_done_20:1; + uint32_t tx_done_16:1; + uint32_t tx_done_17:1; + uint32_t subsys_int_en:1; + uint32_t mcu2host_sw_int_en:1; + uint32_t tx_done_18:1; + uint32_t tx_done_19:1; + } field_conn2x; + + struct { + uint32_t wfdma1_rx_done_0:1; + uint32_t wfdma1_rx_done_1:1; + uint32_t wfdma1_rx_done_2:1; + uint32_t wfdma1_rx_done_3:1; + uint32_t wfdma1_tx_done_0:1; + uint32_t wfdma1_tx_done_1:1; + uint32_t wfdma1_tx_done_2:1; + uint32_t wfdma1_tx_done_3:1; + uint32_t wfdma1_tx_done_4:1; + uint32_t wfdma1_tx_done_5:1; + uint32_t wfdma1_tx_done_6:1; + uint32_t wfdma1_tx_done_7:1; + uint32_t wfdma1_tx_done_8:1; + uint32_t reserved13:2; + uint32_t wfdma1_tx_done_20:1; + uint32_t wfdma0_rx_done_0:1; + uint32_t wfdma0_rx_done_1:1; + uint32_t wfdma0_rx_done_2:1; + uint32_t wfdma0_rx_done_3:1; + uint32_t wfdma1_rx_coherent:1; + uint32_t wfdma1_tx_coherent:1; + uint32_t wfdma0_rx_coherent:1; + uint32_t wfdma0_tx_coherent:1; + uint32_t wpdma2host1_err_int_en:1; + uint32_t wpdma2host0_err_int_en:1; + uint32_t wfdma1_tx_done_16:1; + uint32_t wfdma1_tx_done_17:1; + uint32_t wfdma1_subsys_int_en:1; + uint32_t wfdma1_mcu2host_sw_int_en:1; + uint32_t wfdma1_tx_done_18:1; + uint32_t wfdma1_tx_done_19:1; + } field_conn2x_ext; + + struct { + uint32_t wfdma0_rx_done_0:1; + uint32_t wfdma0_rx_done_1:1; + uint32_t wfdma0_rx_done_2:1; + uint32_t wfdma0_rx_done_3:1; + uint32_t wfdma0_tx_done_0:1; + uint32_t wfdma0_tx_done_1:1; + uint32_t wfdma0_tx_done_2:1; + uint32_t wfdma0_tx_done_3:1; + uint32_t wfdma0_tx_done_4:1; + uint32_t wfdma0_tx_done_5:1; + uint32_t wfdma0_tx_done_6:1; + uint32_t wfdma0_tx_done_7:1; + uint32_t wfdma0_tx_done_8:1; + uint32_t wfdma0_tx_done_9:1; + uint32_t wfdma0_tx_done_10:1; + uint32_t wfdma0_tx_done_11:1; + uint32_t wfdma0_tx_done_12:1; + uint32_t wfdma0_tx_done_13:1; + uint32_t wfdma0_tx_done_14:1; + uint32_t reserved19:1; + uint32_t wfdma0_rx_coherent:1; + uint32_t wfdma0_tx_coherent:1; + uint32_t wfdma0_rx_done_4:1; + uint32_t wfdma0_rx_done_5:1; + uint32_t wpdma2host0_err_int_en:1; + uint32_t reserved25:1; + uint32_t wfdma0_tx_done_16:1; + uint32_t wfdma0_tx_done_17:1; + uint32_t wfdma0_subsys_int_en:1; + uint32_t wfdma0_mcu2host_sw_int_en:1; + uint32_t wfdma0_tx_done_18:1; + uint32_t reserved31:1; + } field_conn2x_single; + + uint32_t word; +}; + +/* WPDMA_INT_MSK */ +union WPDMA_INT_MASK { + struct { + uint32_t rx_done_0:1; + uint32_t rx_done_1:1; + uint32_t err_det_int_0:1; + uint32_t err_det_int_1:1; + uint32_t tx_done:16; + uint32_t rx_coherent:1; + uint32_t tx_coherent:1; + uint32_t rx_dly_int:1; + uint32_t tx_dly_int:1; + uint32_t wf_mac_int_0:1; + uint32_t wf_mac_int_1:1; + uint32_t wf_mac_int_2:1; + uint32_t wf_mac_int_3:1; + uint32_t wf_mac_int_4:1; + uint32_t wf_mac_int_5:1; + uint32_t mcu_cmd_int:1; + uint32_t fw_clr_own:1; + } field; + + struct { + uint32_t rx_done_0:1; + uint32_t rx_done_1:1; + uint32_t err_det_int_0:1; + uint32_t err_det_int_1:1; + uint32_t tx_done:16; + uint32_t rx_coherent:1; + uint32_t tx_coherent:1; + uint32_t rx_dly_int:1; + uint32_t tx_dly_int:1; + uint32_t wpdma2host_err_int_ena:1; + uint32_t rsv_25_27:3; + uint32_t subsys_int_ena:1; + uint32_t mcu2host_sw_int_ena:1; + uint32_t rsv_30_31:2; + } field_conn; + + struct { + uint32_t rx_done_0:1; + uint32_t rx_done_1:1; + uint32_t rx_done_2:1; + uint32_t rx_done_3:1; + uint32_t tx_done:16; + uint32_t rx_coherent:1; + uint32_t tx_coherent:1; + uint32_t reserved:2; + uint32_t wpdma2host_err_int_en:1; + uint32_t tx_done_20:1; + uint32_t tx_done_16:1; + uint32_t tx_done_17:1; + uint32_t subsys_int_en:1; + uint32_t mcu2host_sw_int_en:1; + uint32_t tx_done_18:1; + uint32_t tx_done_19:1; + } field_conn2x; + + struct { + uint32_t wfdma1_rx_done_0:1; + uint32_t wfdma1_rx_done_1:1; + uint32_t wfdma1_rx_done_2:1; + uint32_t wfdma1_rx_done_3:1; + uint32_t wfdma1_tx_done_0:1; + uint32_t wfdma1_tx_done_1:1; + uint32_t wfdma1_tx_done_2:1; + uint32_t wfdma1_tx_done_3:1; + uint32_t wfdma1_tx_done_4:1; + uint32_t wfdma1_tx_done_5:1; + uint32_t wfdma1_tx_done_6:1; + uint32_t wfdma1_tx_done_7:1; + uint32_t wfdma1_tx_done_8:1; + uint32_t reserved13:2; + uint32_t wfdma1_tx_done_20:1; + uint32_t wfdma0_rx_done_0:1; + uint32_t wfdma0_rx_done_1:1; + uint32_t wfdma0_rx_done_2:1; + uint32_t wfdma0_rx_done_3:1; + uint32_t wfdma1_rx_coherent:1; + uint32_t wfdma1_tx_coherent:1; + uint32_t wfdma0_rx_coherent:1; + uint32_t wfdma0_tx_coherent:1; + uint32_t wpdma2host1_err_int_en:1; + uint32_t wpdma2host0_err_int_en:1; + uint32_t wfdma1_tx_done_16:1; + uint32_t wfdma1_tx_done_17:1; + uint32_t wfdma1_subsys_int_en:1; + uint32_t wfdma1_mcu2host_sw_int_en:1; + uint32_t wfdma1_tx_done_18:1; + uint32_t wfdma1_tx_done_19:1; + } field_conn2x_ext; + + struct { + uint32_t wfdma0_rx_done_0:1; + uint32_t wfdma0_rx_done_1:1; + uint32_t wfdma0_rx_done_2:1; + uint32_t wfdma0_rx_done_3:1; + uint32_t wfdma0_tx_done_0:1; + uint32_t wfdma0_tx_done_1:1; + uint32_t wfdma0_tx_done_2:1; + uint32_t wfdma0_tx_done_3:1; + uint32_t wfdma0_tx_done_4:1; + uint32_t wfdma0_tx_done_5:1; + uint32_t wfdma0_tx_done_6:1; + uint32_t wfdma0_tx_done_7:1; + uint32_t wfdma0_tx_done_8:1; + uint32_t wfdma0_tx_done_9:1; + uint32_t wfdma0_tx_done_10:1; + uint32_t wfdma0_tx_done_11:1; + uint32_t wfdma0_tx_done_12:1; + uint32_t wfdma0_tx_done_13:1; + uint32_t wfdma0_tx_done_14:1; + uint32_t reserved19:1; + uint32_t wfdma0_rx_coherent:1; + uint32_t wfdma0_tx_coherent:1; + uint32_t wfdma0_rx_done_4:1; + uint32_t wfdma0_rx_done_5:1; + uint32_t wpdma2host0_err_int_en:1; + uint32_t reserved25:1; + uint32_t wfdma0_tx_done_16:1; + uint32_t wfdma0_tx_done_17:1; + uint32_t wfdma0_subsys_int_en:1; + uint32_t wfdma0_mcu2host_sw_int_en:1; + uint32_t wfdma0_tx_done_18:1; + uint32_t reserved31:1; + } field_conn2x_single; + uint32_t word; +}; + +/* WPDMA_GLO_CFG */ +union WPDMA_GLO_CFG_STRUCT { + struct { + uint32_t EnableTxDMA:1; + uint32_t TxDMABusy:1; + uint32_t EnableRxDMA:1; + uint32_t RxDMABusy:1; + uint32_t WPDMABurstSIZE:2; + uint32_t EnTXWriteBackDDONE:1; + uint32_t BigEndian:1; + uint32_t Desc32BEn:1; + uint32_t share_fifo_en:1; + uint32_t multi_dma_en:2; + uint32_t fifo_little_endian:1; + uint32_t mi_depth:3; + uint32_t err_det_th:8; + uint32_t sw_rst:1; + uint32_t force_tx_eof:1; + uint32_t rsv_26:1; + uint32_t omit_rx_info:1; + uint32_t omit_tx_info:1; + uint32_t byte_swap:1; + uint32_t clk_gate_dis:1; + uint32_t rx_2b_offset:1; + } field; + + struct { + uint32_t EnableTxDMA:1; + uint32_t TxDMABusy:1; + uint32_t EnableRxDMA:1; + uint32_t RxDMABusy:1; + uint32_t WPDMABurstSIZE:2; + uint32_t EnTXWriteBackDDONE:1; + uint32_t BigEndian:1; + uint32_t dis_bt_size_align:1; + uint32_t tx_bt_size:1; + uint32_t multi_dma_en:2; + uint32_t fifo_little_endian:1; + uint32_t mi_depth:3; + uint32_t mi_depth_rd_3_5:3; + uint32_t mi_depth_rd_8_6:3; + uint32_t tx_bt_size_bit21:2; + uint32_t sw_rst:1; + uint32_t force_tx_eof:1; + uint32_t first_token:1; + uint32_t omit_rx_info:1; + uint32_t omit_tx_info:1; + uint32_t byte_swap:1; + uint32_t reserve_30:1; + uint32_t rx_2b_offset:1; + } field_1; + + struct { + uint32_t tx_dma_en:1; + uint32_t tx_dma_busy:1; + uint32_t rx_dma_en:1; + uint32_t rx_dma_busy:1; + uint32_t pdma_bt_size:2; + uint32_t tx_wb_ddone:1; + uint32_t big_endian:1; + uint32_t dmad_32b_en:1; + uint32_t bypass_dmashdl_txring3:1; + uint32_t multi_dma_en:2; + uint32_t fifo_little_endian:1; + uint32_t mi_depth:3; + uint32_t dfet_arb_mi_depth:3; + uint32_t pfet_arb_mi_depth:3; + uint32_t reserved22:3; + uint32_t force_tx_eof:1; + uint32_t pdma_addr_ext_en:1; + uint32_t omit_rx_info:1; + uint32_t omit_tx_info:1; + uint32_t byte_swap:1; + uint32_t clk_gate_dis:1; + uint32_t rx_2b_offset:1; + } field_conn; + + struct { + uint32_t tx_dma_en:1; + uint32_t tx_dma_busy:1; + uint32_t rx_dma_en:1; + uint32_t rx_dma_busy:1; + uint32_t pdma_bt_size:2; + uint32_t tx_wb_ddone:1; + uint32_t big_endian:1; + uint32_t dmad_32b_en:1; + uint32_t bypass_dmashdl_txring:1; + uint32_t reserved10:2; + uint32_t fifo_little_endian:1; + uint32_t csr_rx_wb_ddone:1; + uint32_t csr_pp_hif_txp_active_en:1; + uint32_t csr_disp_base_ptr_chain_en:1; + uint32_t csr_lbk_rx_q_sel:4; + uint32_t csr_lbk_rx_q_sel_en:1; + /* define after Buzzard (rsv before) */ + uint32_t omit_rx_info_pfet2:1; + uint32_t reserved22:2; + uint32_t csr_sw_rst:1; + uint32_t force_tx_eof:1; + uint32_t pdma_addr_ext_en:1; + uint32_t omit_rx_info:1; + uint32_t omit_tx_info:1; + uint32_t byte_swap:1; + uint32_t clk_gate_dis:1; + uint32_t rx_2b_offset:1; + } field_conn2x; + + uint32_t word; +}; + +/* WPDMA_RST_PTR */ +union WPDMA_RST_IDX_STRUCT { + struct { + uint32_t RST_DTX_IDX0:1; + uint32_t RST_DTX_IDX1:1; + uint32_t rsv_2_15:14; + uint32_t RST_DRX_IDX0:1; + uint32_t RST_DRX_IDX1:1; + uint32_t rsv_18_31:14; + } field; + + uint32_t word; +}; + +/* WPDMA_DELAY_INT_CFG */ +union DELAY_INT_CFG_STRUCT { + struct { + uint32_t RXMAX_PTIME:8; + uint32_t RXMAX_PINT:7; + uint32_t RXDLY_INT_EN:1; + uint32_t TXMAX_PTIME:8; + uint32_t TXMAX_PINT:7; + uint32_t TXDLY_INT_EN:1; + } field; + + uint32_t word; +}; + +/* RTC_TOP_MISC2 */ +#define TOP_MISC2_CR4_INIT_DONE BIT(18) +#define TOP_MISC2_N9_INIT_DONE BIT(17) +#define TOP_MISC2_FW_READY BIT(16) +#define WLAN_READY_BITS BITS(16, 18) + +/* HIF_SYS_REV */ +#define PCIE_HIF_SYS_PROJ BITS(16, 31) +#define PCIE_HIF_SYS_REV BITS(0, 15) + +/* CFG_PCIE_LPCR_HOST */ +#define PCIE_LPCR_AP_HOST_OWNER_STATE_SYNC BIT(2) +#define PCIE_LPCR_HOST_CLR_OWN BIT(1) +#define PCIE_LPCR_HOST_SET_OWN BIT(0) + +/* CFG_PCIE_LPCR_FW */ +#define PCIE_LPCR_FW_CLR_OWN BIT(0) + +/* WPDMA_INT_STA */ +#define WPDMA_FW_CLR_OWN_INT BIT(31) +#define WPDMA_TX_DONE_INT15 BIT(19) +#define WPDMA_TX_DONE_INT3 BIT(7) +#define WPDMA_TX_DONE_INT2 BIT(6) +#define WPDMA_TX_DONE_INT1 BIT(5) +#define WPDMA_TX_DONE_INT0 BIT(4) +#define WPDMA_RX_DONE_INT3 BIT(3) +#define WPDMA_RX_DONE_INT2 BIT(2) +#define WPDMA_RX_DONE_INT1 BIT(1) +#define WPDMA_RX_DONE_INT0 BIT(0) + +#else +#define WIFI_CFG_SW_SYNC0 0 +#define WIFI_CFG_SYNC0_RDY_OFFSET 0 +#endif + +/* 4 CHIP ID Register */ +#define MCR_WCIR 0x0000 + +/* 4 HIF Low Power Control Register */ +#define MCR_WHLPCR 0x0004 + +/* 4 Control Status Register */ +#define MCR_WSDIOCSR 0x0008 + +/* 4 HIF Control Register */ +#define MCR_WHCR 0x000C + +/* 4 HIF Interrupt Status Register */ +#define MCR_WHISR 0x0010 + +/* 4 HIF Interrupt Enable Register */ +#define MCR_WHIER 0x0014 + +/* 4 Abnormal Status Register */ +#define MCR_WASR 0x0020 + +/* 4 WLAN Software Interrupt Control Register */ +#define MCR_WSICR 0x0024 + +/* 4 WLAN TX Data Register 1 */ +#define MCR_WTDR1 0x0034 + +/* 4 WLAN RX Data Register 0 */ +#define MCR_WRDR0 0x0050 + +/* 4 WLAN RX Data Register 1 */ +#define MCR_WRDR1 0x0054 + +/* 4 Host to Device Send Mailbox 0 Register */ +#define MCR_H2DSM0R 0x0070 + +/* 4 Host to Device Send Mailbox 1 Register */ +#define MCR_H2DSM1R 0x0074 + +/* 4 Device to Host Receive Mailbox 0 Register */ +#define MCR_D2HRM0R 0x0078 + +/* 4 Device to Host Receive Mailbox 1 Register */ +#define MCR_D2HRM1R 0x007c + +/* 4 Device to Host Receive Mailbox 2 Register */ +#define MCR_D2HRM2R 0x0080 + +/* 4 WLAN RX Packet Length Register */ +#define MCR_WRPLR 0x0090 + +/* 4 Test Mode Data Port */ +#define MCR_WTMDR 0x00b0 + +/* 4 Test Mode Control Register */ +#define MCR_WTMCR 0x00b4 + +/* 4 Test Mode Data Pattern Control Register #0 */ +#define MCR_WTMDPCR0 0x00b8 + +/* 4 Test Mode Data Pattern Control Register #1 */ +#define MCR_WTMDPCR1 0x00bc + +/* 4 WLAN Packet Length Report Control Register */ +#define MCR_WPLRCR 0x00d4 + +/* 4 WLAN Snapshot Register */ +#define MCR_WSR 0x00D8 + +/* 4 Clock Pad Macro IO Control Register */ +#define MCR_CLKIOCR 0x0100 + +/* 4 Command Pad Macro IO Control Register */ +#define MCR_CMDIOCR 0x0104 + +/* 4 Data 0 Pad Macro IO Control Register */ +#define MCR_DAT0IOCR 0x0108 + +/* 4 Data 1 Pad Macro IO Control Register */ +#define MCR_DAT1IOCR 0x010C + +/* 4 Data 2 Pad Macro IO Control Register */ +#define MCR_DAT2IOCR 0x0110 + +/* 4 Data 3 Pad Macro IO Control Register */ +#define MCR_DAT3IOCR 0x0114 + +/* 4 Clock Pad Macro Delay Chain Control Register */ +#define MCR_CLKDLYCR 0x0118 + +/* 4 Command Pad Macro Delay Chain Control Register */ +#define MCR_CMDDLYCR 0x011C + +/* 4 SDIO Output Data Delay Chain Control Register */ +#define MCR_ODATDLYCR 0x0120 + +/* 4 SDIO Input Data Delay Chain Control Register 1 */ +#define MCR_IDATDLYCR1 0x0124 + +/* 4 SDIO Input Data Delay Chain Control Register 2 */ +#define MCR_IDATDLYCR2 0x0128 + +/* 4 SDIO Input Data Latch Time Control Register */ +#define MCR_ILCHCR 0x012C + +/* 4 WLAN TXQ Count Register 0 */ +#define MCR_WTQCR0 0x0130 + +/* 4 WLAN TXQ Count Register 1 */ +#define MCR_WTQCR1 0x0134 + +/* 4 WLAN TXQ Count Register 2 */ +#define MCR_WTQCR2 0x0138 + +/* 4 WLAN TXQ Count Register 3 */ +#define MCR_WTQCR3 0x013C + +/* 4 WLAN TXQ Count Register 4 */ +#define MCR_WTQCR4 0x0140 + +/* 4 WLAN TXQ Count Register 5 */ +#define MCR_WTQCR5 0x0144 + +/* 4 WLAN TXQ Count Register 6 */ +#define MCR_WTQCR6 0x0148 + +/* 4 WLAN TXQ Count Register 7 */ +#define MCR_WTQCR7 0x014C + +/* WLAN/Common PC value Debug registre */ +#define MCR_SWPCDBGR 0x0154 + +/* #if CFG_SDIO_INTR_ENHANCE */ +struct ENHANCE_MODE_DATA_STRUCT { + uint32_t u4WHISR; + union { + struct { + uint16_t u2TQ0Cnt; + uint16_t u2TQ1Cnt; + uint16_t u2TQ2Cnt; + uint16_t u2TQ3Cnt; + uint16_t u2TQ4Cnt; + uint16_t u2TQ5Cnt; + uint16_t u2TQ6Cnt; + uint16_t u2TQ7Cnt; + uint16_t u2TQ8Cnt; + uint16_t u2TQ9Cnt; + uint16_t u2TQ10Cnt; + uint16_t u2TQ11Cnt; + uint16_t u2TQ12Cnt; + uint16_t u2TQ13Cnt; + uint16_t u2TQ14Cnt; + uint16_t u2TQ15Cnt; + } u; + uint32_t au4WTSR[8]; + } rTxInfo; + union { + struct { + uint16_t u2NumValidRx0Len; + uint16_t u2NumValidRx1Len; + uint16_t au2Rx0Len[16]; + uint16_t au2Rx1Len[16]; + } u; + uint32_t au4RxStatusRaw[17]; + } rRxInfo; + uint32_t u4RcvMailbox0; + uint32_t u4RcvMailbox1; +}; +/* #endif *//* ENHANCE_MODE_DATA_STRUCT_T */ + +/* 2 Definition in each register */ +/* 3 WCIR 0x0000 */ +#define WCIR_WLAN_READY BIT(21) +#define WCIR_POR_INDICATOR BIT(20) +#define WCIR_REVISION_ID BITS(16, 19) +#define WCIR_CHIP_ID BITS(0, 15) + +#define MTK_CHIP_REV 0x00006632 +#define MTK_CHIP_MP_REVERSION_ID 0x0 + +/* 3 WHLPCR 0x0004 */ +#define WHLPCR_FW_OWN_REQ_CLR BIT(9) +#define WHLPCR_FW_OWN_REQ_SET BIT(8) +#define WHLPCR_IS_DRIVER_OWN BIT(8) +#define WHLPCR_INT_EN_CLR BIT(1) +#define WHLPCR_INT_EN_SET BIT(0) + +/* 3 WSDIOCSR 0x0008 */ +#define WSDIOCSR_DB_CMD7_RESELECT_DIS BIT(4) +#define WSDIOCSR_DB_WR_BUSY_EN BIT(3) +#define WSDIOCSR_DB_RD_BUSY_EN BIT(2) +#define WSDIOCSR_SDIO_INT_CTL BIT(1) +#define WSDIOCSR_SDIO_RE_INIT_EN BIT(0) + +/* 3 WHCR 0x000C */ +#define WHCR_RX_ENHANCE_MODE_EN BIT(16) +#define WHCR_MAX_HIF_RX_LEN_NUM BITS(8, 13) +#define WHCR_RPT_OWN_RX_PACKET_LEN BIT(3) +#define WHCR_RECV_MAILBOX_RD_CLR_EN BIT(2) +#define WHCR_W_INT_CLR_CTRL BIT(1) +#define WHCR_MCU_DBG_EN BIT(0) +#define WHCR_OFFSET_MAX_HIF_RX_LEN_NUM 8 + +/* 3 WHISR 0x0010 */ +#define WHISR_D2H_SW_INT BITS(8, 31) +#define WHISR_D2H_SW_ASSERT_INFO_INT BIT(31) +#define WHISR_D2H_WKUP_BY_RX_PACKET BIT(30) +#define WHISR_D2H_SW_RD_MAILBOX_INT BIT(29) +#define WHISR_FW_OWN_BACK_INT BIT(7) +#define WHISR_ABNORMAL_INT BIT(6) +#define WHISR_RX1_DONE_INT BIT(2) +#define WHISR_RX0_DONE_INT BIT(1) +#define WHISR_TX_DONE_INT BIT(0) + +/* 3 WHIER 0x0014 */ +#define WHIER_D2H_SW_INT BITS(8, 31) +#define WHIER_FW_OWN_BACK_INT_EN BIT(7) +#define WHIER_ABNORMAL_INT_EN BIT(6) +#define WHIER_RX1_DONE_INT_EN BIT(2) +#define WHIER_RX0_DONE_INT_EN BIT(1) +#define WHIER_TX_DONE_INT_EN BIT(0) +#define WHIER_DEFAULT (WHIER_RX0_DONE_INT_EN | \ + WHIER_RX1_DONE_INT_EN | \ + WHIER_TX_DONE_INT_EN | \ + WHIER_ABNORMAL_INT_EN | \ + WHIER_D2H_SW_INT \ + ) + +/* 3 WASR 0x0020 */ +#define WASR_FW_OWN_INVALID_ACCESS BIT(16) +#define WASR_RX1_UNDER_FLOW BIT(9) +#define WASR_RX0_UNDER_FLOW BIT(8) +#define WASR_TX1_OVER_FLOW BIT(1) + +/* 3 WSICR 0x0024 */ +#define WSICR_H2D_SW_INT_SET BITS(16, 31) + +/* 3 WRPLR 0x0090 */ +#define WRPLR_RX1_PACKET_LENGTH BITS(16, 31) +#define WRPLR_RX0_PACKET_LENGTH BITS(0, 15) + +/* 3 WTMCR 0x00b4 */ +#define WMTCR_TEST_MODE_FW_OWN BIT(24) +#define WMTCR_PRBS_INIT_VAL BITS(16, 23) +#define WMTCR_TEST_MODE_STATUS BIT(8) +#define WMTCR_TEST_MODE_SELECT BITS(0, 1) + + + +/* Support features */ +/* Options for VLAN-over-ethernet pkt to/from 802.11 LLC VLAN pkt. + * This should depend on the configurations of HW-header-translation. + */ +#define FEAT_BITS_LLC_VLAN_TX BIT(0) +#define FEAT_BITS_LLC_VLAN_RX BIT(1) + +/* Support features API */ +#define FEAT_SUP_LLC_VLAN_TX(__chip_info) \ + ((__chip_info)->features & FEAT_BITS_LLC_VLAN_TX) +#define FEAT_SUP_LLC_VLAN_RX(__chip_info) \ + ((__chip_info)->features & FEAT_BITS_LLC_VLAN_RX) + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +enum ENUM_WIFI_FUNC { + WIFI_FUNC_INIT_DONE = BIT(0), + WIFI_FUNC_N9_DONE = BIT(1), + WIFI_FUNC_NO_CR4_READY_BITS = BITS(0, 1), + WIFI_FUNC_CR4_READY = BIT(2), + WIFI_FUNC_READY_BITS = BITS(0, 2), + WIFI_FUNC_DUMMY_REQ = BIT(3) +}; + +enum enum_mt66xx_chip { + MT66XX_CHIP_6632 = 0, + MT66XX_CHIP_7666, + MT66XX_CHIP_7668, + MT66XX_CHIP_NUM +}; + +enum enum_workAround { + WORKAROUND_MT7663_BRINGUP_20171205 = 0, + WORKAROUND_NUM +}; + +struct mt66xx_chip_info { + struct BUS_INFO *bus_info; + struct FWDL_OPS_T *fw_dl_ops; + struct TX_DESC_OPS_T *prTxDescOps; + struct RX_DESC_OPS_T *prRxDescOps; +#if CFG_SUPPORT_QA_TOOL + struct ATE_OPS_T *prAteOps; +#endif + struct CHIP_DBG_OPS *prDebugOps; + + const unsigned int chip_id; /* chip id */ + const unsigned int should_verify_chip_id; /* verify chip id */ + const unsigned int sw_sync0; /* sw_sync0 address */ + const unsigned int sw_ready_bits; /* sw_sync0 ready bits */ + const unsigned int sw_ready_bit_offset; /* sw_sync0 ready bit offset */ + const unsigned int patch_addr; /* patch download start address */ + const unsigned int is_support_cr4; /* support CR4 */ + const unsigned int is_support_wacpu; /* support WA-CPU */ + const unsigned int txd_append_size; /* hw mac txd append */ + const unsigned int rxd_size; /* hw mac rxd size */ + const unsigned int init_evt_rxd_size; /* init event rxd size */ + const unsigned int pse_header_length; /* NIC_TX_PSE_HEADER_LENGTH */ + const unsigned int init_event_size; /* init event w/o rxd size */ + const unsigned int event_hdr_size; /* event w/o rxd size */ + const unsigned int isNicCapV1; + const unsigned int is_support_efuse; /* efuse support */ + const unsigned int top_hcr; /* TOP_HCR */ + const unsigned int top_hvr; /* TOP_HVR */ + const unsigned int top_fvr; /* TOP_FVR */ +#if (CFG_SUPPORT_802_11AX == 1) + const unsigned int arb_ac_mode_addr; +#endif /* CFG_SUPPORT_802_11AX == 1 */ + const unsigned int custom_oid_interface_version; + const unsigned int em_interface_version; + const unsigned int cmd_max_pkt_size; + + const struct ECO_INFO *eco_info; /* chip version table */ + uint8_t eco_ver; /* chip version */ + uint8_t ucPacketFormat; + + uint16_t u2TxInitCmdPort; + uint16_t u2TxFwDlPort; + uint16_t u2HifTxdSize; + uint16_t u2CmdTxHdrSize; + uint16_t u2RxSwPktBitMap; + uint16_t u2RxSwPktEvent; + uint16_t u2RxSwPktFrame; + + /* Extra TXD Size for TX Byte Count field (in unit of Byte) */ + uint32_t u4ExtraTxByteCount; + uint32_t u4HifDmaShdlBaseAddr; + /* chip ip version from FW */ + uint32_t u4ChipIpVersion; + uint32_t u4ChipIpConfig; + uint16_t u2ADieChipVersion; + + void (*asicCapInit)(IN struct ADAPTER *prAdapter); + void (*asicEnableFWDownload)(IN struct ADAPTER *prAdapter, + IN u_int8_t fgEnable); + void (*asicFillInitCmdTxd)(IN struct ADAPTER *prAdapter, + IN struct WIFI_CMD_INFO *prCmdInfo, + OUT uint16_t *pu2BufInfoLen, OUT uint8_t *pucSeqNum, + OUT void **pCmdBuf); + void (*asicFillCmdTxd)(IN struct ADAPTER *prAdapter, + IN struct WIFI_CMD_INFO *prCmdInfo, + OUT uint8_t *pucSeqNum, OUT void **pCmdBuf); + uint32_t (*asicGetChipID)(IN struct ADAPTER *prAdapter); + void (*fillHifTxDesc)(IN uint8_t **pDest, IN uint16_t *pInfoBufLen); + uint32_t (*downloadBufferBin)(IN struct ADAPTER *prAdapter); + void (*asicRxProcessRxvforMSP)(IN struct ADAPTER *prAdapter, + IN OUT struct SW_RFB *prRetSwRfb); + uint8_t (*asicRxGetRcpiValueFromRxv)( + IN uint8_t ucRcpiMode, + IN struct SW_RFB *prSwRfb); + void (*asicRxPerfIndProcessRXV)( + IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, + IN uint8_t ucBssIndex); + + const uint32_t features; /* feature bits */ + u_int8_t is_support_hw_amsdu; + uint8_t ucMaxSwAmsduNum; + uint8_t ucMaxSwapAntenna; + uint32_t workAround; + char *prTxPwrLimitFile; + uint8_t ucTxPwrLimitBatchSize; + u_int8_t is_support_asic_lp; + u_int8_t is_support_wfdma1; + u_int8_t is_support_dma_shdl; + u_int8_t get_rxv_from_rxrpt; + u_int8_t rx_event_port; +#if defined(_HIF_USB) + void (*asicUsbInit)(IN struct ADAPTER *prAdapter, + IN struct mt66xx_chip_info *prChipInfo); + void (*asicUsbInit_ic_specific)(IN struct ADAPTER *prAdapter, + IN struct mt66xx_chip_info *prChipInfo); + uint32_t u4SerUsbMcuEventAddr; + uint32_t u4SerUsbHostAckAddr; +#endif + void (*asicDumpSerDummyCR)(IN struct ADAPTER *prAdapter); + void (*asicWfdmaReInit)(IN struct ADAPTER *prAdapter); + void (*asicWfdmaReInit_handshakeInit)(IN struct ADAPTER *prAdapter); + void *pdev; + uint32_t group5_size; + void (*wlanCheckAsicCap)(IN struct ADAPTER *prAdapter); +#if (CFG_CHIP_RESET_SUPPORT == 1) && (CFG_WMT_RESET_API_SUPPORT == 0) + u_int8_t (*rst_L0_notify_step2)(void); +#endif + uint32_t u4LmacWtblDUAddr; + uint32_t u4UmacWtblDUAddr; + int (*wmmcupwron)(void); + int (*wmmcupwroff)(void); + uint32_t (*pwrondownload)(IN struct ADAPTER *prAdapter, + IN uint8_t ucDownloadItem); + int (*triggerfwassert)(void); + int (*coexpccifon)(void); + int (*coexpccifoff)(void); + void (*coantSetWiFi)(void); + void (*coantSetMD)(void); + void (*coantVFE28En)(IN struct ADAPTER *prAdapter); + void (*coantVFE28Dis)(void); + int (*trigger_wholechiprst)(char *reason); + void (*sw_interrupt_handler)(IN struct ADAPTER *prAdapter); + void (*conninra_cb_register)(void); + void (*dumpwfsyscpupcr)(IN struct ADAPTER *prAdapter); + uint8_t* (*getCalResult)(OUT uint32_t *prCalSize); + void (*calDebugCmd)(uint32_t cmd, uint32_t para); + u_int8_t is_support_nvram_fragment; + int (*checkbushang)(void *prAdapter, + uint8_t ucWfResetEnable); + void (*dumpBusHangCr)(IN struct ADAPTER *prAdapter); +}; + +struct mt66xx_hif_driver_data { + struct mt66xx_chip_info *chip_info; +}; + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/nic.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/nic.h new file mode 100644 index 0000000000000000000000000000000000000000..63e7dd64a4b141d58fc5b294143b9c40c6ced794 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/nic.h @@ -0,0 +1,484 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/ + * MT6620_WIFI_DRIVER_V2_3/include/nic/nic.h#1 + */ + +/*! \file "nic.h" + * \brief The declaration of nic functions + * + * Detail description. + */ + + +#ifndef _NIC_H +#define _NIC_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#define PS_SYNC_WITH_FW BIT(31) + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +struct REG_ENTRY { + uint32_t u4Offset; + uint32_t u4Value; +}; + +struct _TABLE_ENTRY_T { + struct REG_ENTRY *pu4TablePtr; + uint16_t u2Size; +}; + +/*! INT status to event map */ +struct INT_EVENT_MAP { + uint32_t u4Int; + uint32_t u4Event; +}; + +struct ECO_INFO { + uint8_t ucHwVer; + uint8_t ucRomVer; + uint8_t ucFactoryVer; + uint8_t ucEcoVer; +}; + +enum ENUM_INT_EVENT_T { + INT_EVENT_ABNORMAL, + INT_EVENT_SW_INT, + INT_EVENT_TX, + INT_EVENT_RX, + INT_EVENT_NUM +}; + +enum ENUM_IE_UPD_METHOD { + IE_UPD_METHOD_UPDATE_RANDOM, + IE_UPD_METHOD_UPDATE_ALL, + IE_UPD_METHOD_DELETE_ALL, +#if CFG_SUPPORT_P2P_GO_OFFLOAD_PROBE_RSP + IE_UPD_METHOD_UPDATE_PROBE_RSP, +#endif +}; + +enum ENUM_SER_STATE { + SER_IDLE_DONE, /* SER is idle or done */ + SER_STOP_HOST_TX, /* Host HIF Tx is stopped */ + SER_STOP_HOST_TX_RX, /* Host HIF Tx/Rx is stopped */ + SER_REINIT_HIF, /* Host HIF is reinit */ + + SER_STATE_NUM +}; + +/* The bit map for the caller to set the power save flag */ +enum POWER_SAVE_CALLER { + PS_CALLER_COMMON = 0, + PS_CALLER_CTIA, + PS_CALLER_SW_WRITE, + PS_CALLER_CTIA_CAM, + PS_CALLER_P2P, + PS_CALLER_CAMCFG, + PS_CALLER_GPU, + PS_CALLER_TP, + PS_CALLER_NO_TIM, + PS_CALLER_MAX_NUM = 24 +}; + +enum ENUM_ECO_VER { + ECO_VER_1 = 1, + ECO_VER_2, + ECO_VER_3 +}; + +enum ENUM_REMOVE_BY_MSDU_TPYE { + MSDU_REMOVE_BY_WLAN_INDEX = 0, + MSDU_REMOVE_BY_BSS_INDEX, + MSDU_REMOVE_BY_ALL, + ENUM_REMOVE_BY_MSDU_TPYE_NUM +}; + +/* Test mode bitmask of disable flag */ +#define TEST_MODE_DISABLE_ONLINE_SCAN BIT(0) +#define TEST_MODE_DISABLE_ROAMING BIT(1) +#define TEST_MODE_FIXED_CAM_MODE BIT(2) +#define TEST_MODE_DISABLE_BCN_LOST_DET BIT(3) +#define TEST_MODE_NONE 0 +#define TEST_MODE_THROUGHPUT \ + (TEST_MODE_DISABLE_ONLINE_SCAN | TEST_MODE_DISABLE_ROAMING | \ + TEST_MODE_FIXED_CAM_MODE | TEST_MODE_DISABLE_BCN_LOST_DET) +#define TEST_MODE_SIGMA_AC_N_PMF \ + (TEST_MODE_DISABLE_ONLINE_SCAN | TEST_MODE_FIXED_CAM_MODE) +#define TEST_MODE_SIGMA_WMM_PS (TEST_MODE_DISABLE_ONLINE_SCAN) +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ +#if (CFG_TWT_SMART_STA == 1) +extern struct _TWT_SMART_STA_T g_TwtSmartStaCtrl; +#endif + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +/*----------------------------------------------------------------------------*/ +/* Routines in nic.c */ +/*----------------------------------------------------------------------------*/ +uint32_t nicAllocateAdapterMemory(IN struct ADAPTER + *prAdapter); + +void nicReleaseAdapterMemory(IN struct ADAPTER *prAdapter); + +void nicDisableInterrupt(IN struct ADAPTER *prAdapter); + +void nicEnableInterrupt(IN struct ADAPTER *prAdapter); + +uint32_t nicProcessIST(IN struct ADAPTER *prAdapter); + +uint32_t nicProcessISTWithSpecifiedCount(IN struct ADAPTER *prAdapter, + IN uint32_t u4HifIstLoopCount); + +uint32_t nicProcessIST_impl(IN struct ADAPTER *prAdapter, + IN uint32_t u4IntStatus); + +uint32_t nicInitializeAdapter(IN struct ADAPTER *prAdapter); + +void nicMCRInit(IN struct ADAPTER *prAdapter); + +u_int8_t nicVerifyChipID(IN struct ADAPTER *prAdapter); + +void nicpmWakeUpWiFi(IN struct ADAPTER *prAdapter); + +u_int8_t nicpmSetDriverOwn(IN struct ADAPTER *prAdapter); + +void nicpmSetFWOwn(IN struct ADAPTER *prAdapter, + IN u_int8_t fgEnableGlobalInt); + +u_int8_t nicpmSetAcpiPowerD0(IN struct ADAPTER *prAdapter); + +u_int8_t nicpmSetAcpiPowerD3(IN struct ADAPTER *prAdapter); + +#if defined(_HIF_SPI) +void nicRestoreSpiDefMode(IN struct ADAPTER *prAdapter); +#endif + +void nicProcessSoftwareInterrupt(IN struct ADAPTER + *prAdapter); + +void nicProcessAbnormalInterrupt(IN struct ADAPTER + *prAdapter); + +void nicSetSwIntr(IN struct ADAPTER *prAdapter, + IN uint32_t u4SwIntrBitmap); + +struct CMD_INFO *nicGetPendingCmdInfo(IN struct ADAPTER + *prAdapter, IN uint8_t ucSeqNum); + +struct MSDU_INFO *nicGetPendingTxMsduInfo( + IN struct ADAPTER *prAdapter, IN uint8_t ucWlanIndex, + IN uint8_t ucSeqNum); + +void nicFreePendingTxMsduInfo(IN struct ADAPTER *prAdapter, + IN uint8_t ucIndex, IN enum ENUM_REMOVE_BY_MSDU_TPYE ucFreeType); + +uint8_t nicIncreaseCmdSeqNum(IN struct ADAPTER *prAdapter); + +uint8_t nicIncreaseTxSeqNum(IN struct ADAPTER *prAdapter); + +/* Media State Change */ +uint32_t +nicMediaStateChange(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN struct EVENT_CONNECTION_STATUS *prConnectionStatus); + +uint32_t nicMediaJoinFailure(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, IN uint32_t rStatus); + +/* Utility function for channel number conversion */ +uint32_t nicChannelNum2Freq(IN uint32_t u4ChannelNum); + +uint32_t nicFreq2ChannelNum(IN uint32_t u4FreqInKHz); + +uint8_t nicGetVhtS1(IN uint8_t ucPrimaryChannel, + IN uint8_t ucBandwidth); + +/* firmware command wrapper */ +/* NETWORK (WIFISYS) */ +uint32_t nicActivateNetwork(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +uint32_t nicDeactivateNetwork(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +/* BSS-INFO */ +uint32_t nicUpdateBss(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +/* BSS-INFO Indication (PM) */ +uint32_t nicPmIndicateBssCreated(IN struct ADAPTER + *prAdapter, IN uint8_t ucBssIndex); + +uint32_t nicPmIndicateBssConnected(IN struct ADAPTER + *prAdapter, IN uint8_t ucBssIndex); + +uint32_t nicPmIndicateBssAbort(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +/* Beacon Template Update */ +uint32_t +nicUpdateBeaconIETemplate(IN struct ADAPTER *prAdapter, + IN enum ENUM_IE_UPD_METHOD eIeUpdMethod, + IN uint8_t ucBssIndex, IN uint16_t u2Capability, + IN uint8_t *aucIe, IN uint16_t u2IELen); + +uint32_t nicQmUpdateWmmParms(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +#if (CFG_SUPPORT_802_11AX == 1) +uint32_t nicQmUpdateMUEdcaParams(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); +uint32_t nicRlmUpdateSRParams(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); +#endif + +uint32_t nicSetAutoTxPower(IN struct ADAPTER *prAdapter, + IN struct CMD_AUTO_POWER_PARAM *prAutoPwrParam); + +/*----------------------------------------------------------------------------*/ +/* Calibration Control */ +/*----------------------------------------------------------------------------*/ +uint32_t nicUpdateTxPower(IN struct ADAPTER *prAdapter, + IN struct CMD_TX_PWR *prTxPwrParam); + +uint32_t nicUpdate5GOffset(IN struct ADAPTER *prAdapter, + IN struct CMD_5G_PWR_OFFSET *pr5GPwrOffset); + +uint32_t nicUpdateDPD(IN struct ADAPTER *prAdapter, + IN struct CMD_PWR_PARAM *prDpdCalResult); + +/*----------------------------------------------------------------------------*/ +/* PHY configuration */ +/*----------------------------------------------------------------------------*/ +void nicSetAvailablePhyTypeSet(IN struct ADAPTER + *prAdapter); + +/*----------------------------------------------------------------------------*/ +/* MGMT and System Service Control */ +/*----------------------------------------------------------------------------*/ +void nicInitSystemService(IN struct ADAPTER *prAdapter, + IN const u_int8_t bAtResetFlow); + +void nicResetSystemService(IN struct ADAPTER *prAdapter); + +void nicUninitSystemService(IN struct ADAPTER *prAdapter); + +void nicInitMGMT(IN struct ADAPTER *prAdapter, + IN struct REG_INFO *prRegInfo); + +void nicUninitMGMT(IN struct ADAPTER *prAdapter); + +void +nicPowerSaveInfoMap(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, IN enum PARAM_POWER_MODE ePowerMode, + IN enum POWER_SAVE_CALLER ucCaller); + +uint32_t +nicConfigPowerSaveProfile(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, IN enum PARAM_POWER_MODE ePwrMode, + IN u_int8_t fgEnCmdEvent, IN enum POWER_SAVE_CALLER ucCaller); + +uint32_t +nicConfigProcSetCamCfgWrite(IN struct ADAPTER *prAdapter, + IN u_int8_t enabled, IN uint8_t ucBssIndex); + +uint32_t nicEnterCtiaMode(IN struct ADAPTER *prAdapter, + u_int8_t fgEnterCtia, u_int8_t fgEnCmdEvent); + +uint32_t nicEnterTPTestMode(IN struct ADAPTER *prAdapter, + IN uint8_t ucFuncMask); + +uint32_t nicEnterCtiaModeOfScan(IN struct ADAPTER + *prAdapter, u_int8_t fgEnterCtia, u_int8_t fgEnCmdEvent); + +uint32_t nicEnterCtiaModeOfRoaming(IN struct ADAPTER + *prAdapter, u_int8_t fgEnterCtia, u_int8_t fgEnCmdEvent); + +uint32_t nicEnterCtiaModeOfCAM(IN struct ADAPTER *prAdapter, + u_int8_t fgEnterCtia, u_int8_t fgEnCmdEvent); + +uint32_t nicEnterCtiaModeOfBCNTimeout(IN struct ADAPTER + *prAdapter, u_int8_t fgEnterCtia, u_int8_t fgEnCmdEvent); + +uint32_t nicEnterCtiaModeOfAutoTxPower(IN struct ADAPTER + *prAdapter, u_int8_t fgEnterCtia, u_int8_t fgEnCmdEvent); + +uint32_t nicEnterCtiaModeOfFIFOFullNoAck(IN struct ADAPTER + *prAdapter, u_int8_t fgEnterCtia, u_int8_t fgEnCmdEvent); +/*----------------------------------------------------------------------------*/ +/* Scan Result Processing */ +/*----------------------------------------------------------------------------*/ +void +nicAddScanResult(IN struct ADAPTER *prAdapter, + IN uint8_t rMacAddr[PARAM_MAC_ADDR_LEN], + IN struct PARAM_SSID *prSsid, + IN uint16_t u2CapInfo, + IN int32_t rRssi, + IN enum ENUM_PARAM_NETWORK_TYPE eNetworkType, + IN struct PARAM_802_11_CONFIG *prConfiguration, + IN enum ENUM_PARAM_OP_MODE eOpMode, + IN uint8_t rSupportedRates[PARAM_MAX_LEN_RATES_EX], + IN uint16_t u2IELength, IN uint8_t *pucIEBuf); + +void nicFreeScanResultIE(IN struct ADAPTER *prAdapter, + IN uint32_t u4Idx); + +/*----------------------------------------------------------------------------*/ +/* Fixed Rate Hacking */ +/*----------------------------------------------------------------------------*/ +uint32_t +nicUpdateRateParams(IN struct ADAPTER *prAdapter, + IN enum ENUM_REGISTRY_FIXED_RATE eRateSetting, + IN uint8_t *pucDesiredPhyTypeSet, + IN uint16_t *pu2DesiredNonHTRateSet, + IN uint16_t *pu2BSSBasicRateSet, + IN uint8_t *pucMcsSet, IN uint8_t *pucSupMcs32, + IN uint16_t *u2HtCapInfo); + +/*----------------------------------------------------------------------------*/ +/* Write registers */ +/*----------------------------------------------------------------------------*/ +uint32_t nicWriteMcr(IN struct ADAPTER *prAdapter, + IN uint32_t u4Address, IN uint32_t u4Value); + +/*----------------------------------------------------------------------------*/ +/* Update auto rate */ +/*----------------------------------------------------------------------------*/ +uint32_t +nicRlmArUpdateParms(IN struct ADAPTER *prAdapter, + IN uint32_t u4ArSysParam0, + IN uint32_t u4ArSysParam1, IN uint32_t u4ArSysParam2, + IN uint32_t u4ArSysParam3); + +/*----------------------------------------------------------------------------*/ +/* Link Quality Updating */ +/*----------------------------------------------------------------------------*/ +void +nicUpdateLinkQuality(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN struct EVENT_LINK_QUALITY *prEventLinkQuality); + +void nicUpdateRSSI(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, IN int8_t cRssi, + IN int8_t cLinkQuality); + +void nicUpdateLinkSpeed(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, IN uint16_t u2LinkSpeed); + +#if CFG_SUPPORT_RDD_TEST_MODE +uint32_t nicUpdateRddTestMode(IN struct ADAPTER *prAdapter, + IN struct CMD_RDD_CH *prRddChParam); +#endif + +/*----------------------------------------------------------------------------*/ +/* Address Setting Apply */ +/*----------------------------------------------------------------------------*/ +uint32_t nicApplyNetworkAddress(IN struct ADAPTER + *prAdapter); + +/*----------------------------------------------------------------------------*/ +/* ECO Version */ +/*----------------------------------------------------------------------------*/ +uint8_t nicGetChipEcoVer(IN struct ADAPTER *prAdapter); +u_int8_t nicIsEcoVerEqualTo(IN struct ADAPTER *prAdapter, + uint8_t ucEcoVer); +u_int8_t nicIsEcoVerEqualOrLaterTo(IN struct ADAPTER + *prAdapter, uint8_t ucEcoVer); +uint8_t nicSetChipHwVer(uint8_t value); +uint8_t nicSetChipSwVer(uint8_t value); +uint8_t nicSetChipFactoryVer(uint8_t value); + +void nicSerStopTxRx(IN struct ADAPTER *prAdapter); +void nicSerStopTx(IN struct ADAPTER *prAdapter); +void nicSerStartTxRx(IN struct ADAPTER *prAdapter); +u_int8_t nicSerIsWaitingReset(IN struct ADAPTER *prAdapter); +u_int8_t nicSerIsTxStop(IN struct ADAPTER *prAdapter); +u_int8_t nicSerIsRxStop(IN struct ADAPTER *prAdapter); +void nicSerReInitBeaconFrame(IN struct ADAPTER *prAdapter); +void nicSerInit(IN struct ADAPTER *prAdapter); +void nicSerDeInit(IN struct ADAPTER *prAdapter); + +#endif /* _NIC_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/nic_connac2x_rx.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/nic_connac2x_rx.h new file mode 100644 index 0000000000000000000000000000000000000000..a877b40abf7bab4e018f46610c4b1d9c1d01a833 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/nic_connac2x_rx.h @@ -0,0 +1,375 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ + +/*! \file nic_connac2x_rx.h +* \brief Functions that provide TX operation in NIC's point of view. +* +* This file provides TX functions which are responsible for both Hardware and +* Software Resource Management and keep their Synchronization. +* +*/ + + +#ifndef _NIC_CONNAC2X_RX_H +#define _NIC_CONNAC2X_RX_H + +#if (CFG_SUPPORT_CONNAC2X == 1) +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ +#define CONNAC2X_RX_STATUS_PKT_TYPE_SW_BITMAP 0x380F +#define CONNAC2X_RX_STATUS_PKT_TYPE_SW_EVENT 0x3800 +#define CONNAC2X_RX_STATUS_PKT_TYPE_SW_FRAME 0x3801 + +/*------------------------------------------------------------------------------ + * Bit fields for HW_MAC_RX_DESC_T + *------------------------------------------------------------------------------ +*/ + +/*! MAC CONNAC2X RX DMA Descriptor */ +/* DW 0*/ +#define CONNAC2X_RX_STATUS_RX_BYTE_COUNT_MASK BITS(0, 15) +#define CONNAC2X_RX_STATUS_RX_BYTE_COUNT_OFFSET 0 +#define CONNAC2X_RX_STATUS_ETH_TYPE_MASK BITS(16, 22) +#define CONNAC2X_RX_STATUS_ETH_TYPE_OFFSET 16 +#define CONNAC2X_RX_STATUS_IP_CHKSUM BIT(23) +#define CONNAC2X_RX_STATUS_UDP_TCP_CHKSUM BIT(24) +#define CONNAC2X_RX_STATUS_DW0_HW_INFO_MASK BITS(25, 26) +#define CONNAC2X_RX_STATUS_DW0_HW_INFO_OFFSET 25 +#define CONNAC2X_RX_STATUS_PKT_TYPE_MASK BITS(27, 31) +#define CONNAC2X_RX_STATUS_PKT_TYPE_OFFSET 27 + +/* DW 1 */ +#define CONNAC2X_RX_STATUS_WLAN_INDEX_MASK BITS(0, 9) +#define CONNAC2X_RX_STATUS_WLAN_INDEX_OFFSET 0 +#define CONNAC2X_RX_STATUS_GROUP_VLD_MASK BITS(11, 15) +#define CONNAC2X_RX_STATUS_GROUP_VLD_OFFSET 11 +#define CONNAC2X_RX_STATUS_SEC_MASK BITS(16, 20) +#define CONNAC2X_RX_STATUS_SEC_OFFSET 16 +#define CONNAC2X_RX_STATUS_KEYID_MASK BITS(21, 22) +#define CONNAC2X_RX_STATUS_KEYID_OFFSET 21 +#define CONNAC2X_RX_STATUS_FLAG_CIPHER_MISMATCH BIT(23) +#define CONNAC2X_RX_STATUS_FLAG_CIPHER_LENGTH_MISMATCH BIT(24) +#define CONNAC2X_RX_STATUS_FLAG_ICV_ERROR BIT(25) +#define CONNAC2X_RX_STATUS_FLAG_TKIPMIC_ERROR BIT(26) +#define CONNAC2X_RX_STATUS_FLAG_FCS_ERROR BIT(27) +#define CONNAC2X_RX_STATUS_DW1_HW_INFO_MASK BITS(29, 31) +#define CONNAC2X_RX_STATUS_DW1_HW_INFO_OFFSET 29 +#define CONNAC2X_RX_STATUS_DW1_BAND_MASK BIT(28) +#define CONNAC2X_RX_STATUS_DW1_BAND_OFFSET 28 + + +#define CONNAC2X_RX_STATUS_FLAG_ERROR_MASK (CONNAC2X_RX_STATUS_FLAG_FCS_ERROR\ + | CONNAC2X_RX_STATUS_FLAG_ICV_ERROR \ + | CONNAC2X_RX_STATUS_FLAG_CIPHER_LENGTH_MISMATCH)/* No TKIP MIC error */ + +/* DW 2 */ +#define CONNAC2X_RX_STATUS_BSSID_MASK BITS(0, 5) +#define CONNAC2X_RX_STATUS_BSSID_OFFSET 0 +#define CONNAC2X_RX_STATUS_FLAG_BF_CQI BIT(7) +#define CONNAC2X_RX_STATUS_HEADER_LEN_MASK BITS(8, 12) +#define CONNAC2X_RX_STATUS_HEADER_LEN_OFFSET 8 +#define CONNAC2X_RX_STATUS_FLAG_HEADER_TRAN BIT(13) +#define CONNAC2X_RX_STATUS_HEADER_OFFSET_MASK BITS(14, 15) +#define CONNAC2X_RX_STATUS_HEADER_OFFSET_OFFSET 14 +#define CONNAC2X_RX_STATUS_TID_MASK BITS(16, 19) +#define CONNAC2X_RX_STATUS_TID_OFFSET 16 +#define CONNAC2X_RX_STATUS_FLAG_SW_BIT BIT(22) +#define CONNAC2X_RX_STATUS_FLAG_DE_AMSDU_FAIL BIT(23) +#define CONNAC2X_RX_STATUS_FLAG_EXCEED_LEN BIT(24) +#define CONNAC2X_RX_STATUS_FLAG_TRANS_FAIL BIT(25) +#define CONNAC2X_RX_STATUS_FLAG_INTF BIT(26) +#define CONNAC2X_RX_STATUS_FLAG_FRAG BIT(27) +#define CONNAC2X_RX_STATUS_FLAG_NULL BIT(28) +#define CONNAC2X_RX_STATUS_FLAG_NDATA BIT(29) +#define CONNAC2X_RX_STATUS_FLAG_NAMP BIT(30) +#define CONNAC2X_RX_STATUS_FLAG_BF_RPT BIT(31) + +/* DW 3 */ +#define CONNAC2X_RX_STATUS_RXV_SEQ_NO_MASK BITS(0, 7) +#define CONNAC2X_RX_STATUS_RXV_SEQ_NO_OFFSET 0 +#define CONNAC2X_RX_STATUS_CH_FREQ_MASK BITS(8, 15) +#define CONNAC2X_RX_STATUS_CH_FREQ_OFFSET 8 +#define CONNAC2X_RX_STATUS_A1_TYPE_MASK BITS(16, 17) +#define CONNAC2X_RX_STATUS_A1_TYPE_OFFSET 16 +#define CONNAC2X_RX_STATUS_UC2ME BIT(16) +#define CONNAC2X_RX_STATUS_MC_FRAME BIT(17) +#define CONNAC2X_RX_STATUS_BC_FRAME BITS(16, 17) + +#define CONNAC2X_RX_STATUS_FLAG_HTC BIT(18) +#define CONNAC2X_RX_STATUS_FLAG_TCL BIT(19) +#define CONNAC2X_RX_STATUS_FLAG_BBM BIT(20) +#define CONNAC2X_RX_STATUS_FLAG_BU BIT(21) +#define CONNAC2X_RX_STATUS_DW3_HW_INFO_MASK BITS(22, 31) +#define CONNAC2X_RX_STATUS_DW3_HW_INFO_OFFSET 22 + +/* DW 4 */ +#define CONNAC2X_RX_STATUS_PF_MASK BITS(0, 1) +#define CONNAC2X_RX_STATUS_PF_OFFSET 0 +#define CONNAC2X_RX_STATUS_FLAG_DP BIT(9) +#define CONNAC2X_RX_STATUS_FLAG_CLS BIT(10) +#define CONNAC2X_RX_STATUS_OFLD_MASK BITS(11, 12) +#define CONNAC2X_RX_STATUS_OFLD_OFFSET 11 +#define CONNAC2X_RX_STATUS_FLAG_MGC BIT(13) +#define CONNAC2X_RX_STATUS_WOL_MASK BITS(14, 18) +#define CONNAC2X_RX_STATUS_WOL_OFFSET 14 +#define CONNAC2X_RX_STATUS_CLS_BITMAP_MASK BITS(19, 28) +#define CONNAC2X_RX_STATUS_CLS_BITMAP_OFFSET 19 +#define CONNAC2X_RX_STATUS_FLAG_PF_MODE BIT(29) +#define CONNAC2X_RX_STATUS_PF_STS_MASK BITS(30, 31) +#define CONNAC2X_RX_STATUS_PF_STS_OFFSET 30 + +/* DW 5 */ +#define CONNAC2X_RX_STATUS_DW5_CLS_BITMAP_MASK BITS(0, 9) +#define CONNAC2X_RX_STATUS_DW5_CLS_BITMAP_OFFSET 0 +#define CONNAC2X_RX_STATUS_MAC_MASK BIT(31) +#define CONNAC2X_RX_STATUS_MAC_OFFSET 31 + + +/* + * GROUP_VLD: RFB Group valid indicators + * Bit[0] indicates GROUP1 (DW10~DW13) + * Bit[1] indicates GROUP2 (DW14~DW15) + * Bit[2] indicates GROUP3 (DW16~DW17) + * Bit[3] indicates GROUP4 (DW6~DW9) + * Bit[4] indicates GROUP5 (DW18~DW33) + */ +#define CONNAC2X_RX_STATUS_GROUP1_VALID BIT(0) +#define CONNAC2X_RX_STATUS_GROUP2_VALID BIT(1) +#define CONNAC2X_RX_STATUS_GROUP3_VALID BIT(2) +#define CONNAC2X_RX_STATUS_GROUP4_VALID BIT(3) +#define CONNAC2X_RX_STATUS_GROUP5_VALID BIT(4) + +#define CONNAC2X_RX_STATUS_FIXED_LEN 24 + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/*! A data structure which is identical with MAC RX DMA Descriptor */ +struct HW_MAC_CONNAC2X_RX_DESC { + uint32_t u4DW0; + uint32_t u4DW1; + uint32_t u4DW2; + uint32_t u4DW3; + uint32_t u4DW4; + uint32_t u4DW5; +}; + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +#define RX_DESC_GET_FIELD(_rHwMacTxDescField, _mask, _offset) \ + (((_rHwMacTxDescField) & (_mask)) >> (_offset)) + +/*------------------------------------------------------------------------------ + * MACRO for HW_MAC_RX_DESC_T + *------------------------------------------------------------------------------ +*/ + +#define HAL_MAC_CONNAC2X_RX_STATUS_GET_RX_BYTE_CNT(_prHwMacRxDesc) \ + RX_DESC_GET_FIELD((_prHwMacRxDesc)->u4DW0, \ + CONNAC2X_RX_STATUS_RX_BYTE_COUNT_MASK, \ + CONNAC2X_RX_STATUS_RX_BYTE_COUNT_OFFSET) + +#define HAL_MAC_CONNAC2X_RX_STATUS_GET_ETH_TYPE_OFFSET(_prHwMacRxDesc) \ +RX_DESC_GET_FIELD((_prHwMacRxDesc)->u4DW0, \ +CONNAC2X_RX_STATUS_ETH_TYPE_MASK, CONNAC2X_RX_STATUS_ETH_TYPE_OFFSET) + +#define HAL_MAC_CONNAC2X_RX_STATUS_GET_PKT_TYPE(_prHwMacRxDesc) \ +RX_DESC_GET_FIELD((_prHwMacRxDesc)->u4DW0, \ +CONNAC2X_RX_STATUS_PKT_TYPE_MASK, CONNAC2X_RX_STATUS_PKT_TYPE_OFFSET) + +#define HAL_MAC_CONNAC2X_RX_STATUS_GET_WLAN_IDX(_prHwMacRxDesc) \ +RX_DESC_GET_FIELD((_prHwMacRxDesc)->u4DW1, \ +CONNAC2X_RX_STATUS_WLAN_INDEX_MASK, CONNAC2X_RX_STATUS_WLAN_INDEX_OFFSET) + +#define HAL_MAC_CONNAC2X_RX_STATUS_GET_GROUP_VLD(_prHwMacRxDesc) \ +RX_DESC_GET_FIELD((_prHwMacRxDesc)->u4DW1, \ +CONNAC2X_RX_STATUS_GROUP_VLD_MASK, CONNAC2X_RX_STATUS_GROUP_VLD_OFFSET) + +#define HAL_MAC_CONNAC2X_RX_STATUS_GET_SEC_MODE(_prHwMacRxDesc) \ +RX_DESC_GET_FIELD((_prHwMacRxDesc)->u4DW1, \ +CONNAC2X_RX_STATUS_SEC_MASK, CONNAC2X_RX_STATUS_SEC_OFFSET) + +#define HAL_MAC_CONNAC2X_RX_STATUS_GET_KID(_prHwMacRxDesc) \ +RX_DESC_GET_FIELD((_prHwMacRxDesc)->u4DW1, \ +CONNAC2X_RX_STATUS_KEYID_MASK, CONNAC2X_RX_STATUS_KEYID_OFFSET) + +#define HAL_MAC_CONNAC2X_RX_STATUS_IS_CIPHER_MISMATCH(_prHwMacRxDesc) \ +(((_prHwMacRxDesc)->u4DW1 & CONNAC2X_RX_STATUS_FLAG_CIPHER_MISMATCH) \ + ? TRUE : FALSE) +#define HAL_MAC_CONNAC2X_RX_STATUS_IS_CLM_ERROR(_prHwMacRxDesc) \ +(((_prHwMacRxDesc)->u4DW1 & CONNAC2X_RX_STATUS_FLAG_CIPHER_LENGTH_MISMATCH) \ + ? TRUE : FALSE) +#define HAL_MAC_CONNAC2X_RX_STATUS_IS_ICV_ERROR(_prHwMacRxDesc) \ +(((_prHwMacRxDesc)->u4DW1 & CONNAC2X_RX_STATUS_FLAG_ICV_ERROR)?TRUE:FALSE) + +#define HAL_MAC_CONNAC2X_RX_STATUS_IS_TKIP_MIC_ERROR(_prHwMacRxDesc) \ +(((_prHwMacRxDesc)->u4DW1 & CONNAC2X_RX_STATUS_FLAG_TKIPMIC_ERROR)?TRUE:FALSE) + +#define HAL_MAC_CONNAC2X_RX_STATUS_IS_FCS_ERROR(_prHwMacRxDesc) \ +(((_prHwMacRxDesc)->u4DW1 & CONNAC2X_RX_STATUS_FLAG_FCS_ERROR)?TRUE:FALSE) + +#define HAL_MAC_CONNAC2X_RX_STATUS_IS_ERROR(_prHwMacRxDesc) \ +(((_prHwMacRxDesc)->u4DW1 & CONNAC2X_RX_STATUS_FLAG_ERROR_MASK)?TRUE:FALSE) + +#define HAL_MAC_CONNAC2X_RX_STATUS_GET_HEADER_OFFSET(_prHwMacRxDesc) \ +((RX_DESC_GET_FIELD((_prHwMacRxDesc)->u4DW2, \ +CONNAC2X_RX_STATUS_HEADER_OFFSET_MASK, \ +CONNAC2X_RX_STATUS_HEADER_OFFSET_OFFSET)) << 1) + +#define HAL_MAC_CONNAC2X_RX_STATUS_GET_HEADER_LEN(_prHwMacRxDesc) \ +(RX_DESC_GET_FIELD((_prHwMacRxDesc)->u4DW2, \ +CONNAC2X_RX_STATUS_HEADER_LEN_MASK, CONNAC2X_RX_STATUS_HEADER_LEN_OFFSET) << 1) + +#define HAL_MAC_CONNAC2X_RX_STATUS_IS_HEADER_TRAN(_prHwMacRxDesc) \ +(((_prHwMacRxDesc)->u4DW2 & CONNAC2X_RX_STATUS_FLAG_HEADER_TRAN)?TRUE:FALSE) + +#define HAL_MAC_CONNAC2X_RX_STATUS_IS_DAF(_prHwMacRxDesc) \ +(((_prHwMacRxDesc)->u4DW2 & CONNAC2X_RX_STATUS_FLAG_DE_AMSDU_FAIL)?TRUE:FALSE) + +#define HAL_MAC_CONNAC2X_RX_STATUS_IS_FRAG(_prHwMacRxDesc) \ +(((_prHwMacRxDesc)->u4DW2 & CONNAC2X_RX_STATUS_FLAG_FRAG)?TRUE:FALSE) + +#define HAL_MAC_CONNAC2X_RX_STATUS_IS_NDATA(_prHwMacRxDesc) \ +(((_prHwMacRxDesc)->u4DW2 & CONNAC2X_RX_STATUS_FLAG_NDATA)?TRUE:FALSE) + +#define HAL_MAC_CONNAC2X_RX_STATUS_IS_NAMP(_prHwMacRxDesc) \ +(((_prHwMacRxDesc)->u4DW2 & CONNAC2X_RX_STATUS_FLAG_NAMP)?TRUE:FALSE) + +#define HAL_MAC_CONNAC2X_RX_STATUS_IS_SW_DEFINE_RX_CLASSERR(_prHwMacRxDesc) \ +(((_prHwMacRxDesc)->u4DW2 & CONNAC2X_RX_STATUS_FLAG_SW_BIT)?TRUE:FALSE) + +#define HAL_MAC_CONNAC2X_RX_STATUS_IS_LLC_MIS(_prHwMacRxDesc) \ +(((_prHwMacRxDesc)->u4DW2 & CONNAC2X_RX_STATUS_FLAG_TRANS_FAIL)?TRUE:FALSE) + +#define HAL_MAC_CONNAC2X_RX_STATUS_GET_TID(_prHwMacRxDesc) \ +RX_DESC_GET_FIELD((_prHwMacRxDesc)->u4DW2, \ +CONNAC2X_RX_STATUS_TID_MASK, CONNAC2X_RX_STATUS_TID_OFFSET) + +#define HAL_MAC_CONNAC2X_RX_STATUS_GET_RXV_SEQ_NO(_prHwMacRxDesc) \ +RX_DESC_GET_FIELD((_prHwMacRxDesc)->u4DW3, \ +CONNAC2X_RX_STATUS_RXV_SEQ_NO_MASK, CONNAC2X_RX_STATUS_RXV_SEQ_NO_OFFSET) + +#define HAL_MAC_CONNAC2X_RX_STATUS_IS_UC2ME(_prHwMacRxDesc) \ +(((_prHwMacRxDesc)->u4DW3 & CONNAC2X_RX_STATUS_UC2ME)?TRUE:FALSE) + +#define HAL_MAC_CONNAC2X_RX_STATUS_IS_MC(_prHwMacRxDesc) \ +(((_prHwMacRxDesc)->u4DW3 & CONNAC2X_RX_STATUS_MC_FRAME)?TRUE:FALSE) + +#define HAL_MAC_CONNAC2X_RX_STATUS_IS_BC(_prHwMacRxDesc) \ +(((_prHwMacRxDesc)->u4DW3 & CONNAC2X_RX_STATUS_BC_FRAME) \ + == CONNAC2X_RX_STATUS_BC_FRAME?TRUE:FALSE) + +#define HAL_RX_CONNAC2X_STATUS_GET_PAYLOAD_FORMAT(_prHwMacRxDesc) \ +RX_DESC_GET_FIELD((_prHwMacRxDesc)->u4DW4, \ +CONNAC2X_RX_STATUS_PF_MASK, CONNAC2X_RX_STATUS_PF_OFFSET) + +#define HAL_MAC_CONNAC2X_RX_STATUS_GET_RF_BAND(_prHwMacRxDesc) \ +(((RX_DESC_GET_FIELD((_prHwMacRxDesc)->u4DW3, \ +CONNAC2X_RX_STATUS_CH_FREQ_MASK, CONNAC2X_RX_STATUS_CH_FREQ_OFFSET)) \ +<= HW_CHNL_NUM_MAX_2G4) ? BAND_2G4 : BAND_5G) + +#define HAL_MAC_CONNAC2X_RX_STATUS_GET_CHNL_NUM(_prHwMacRxDesc) \ +(RX_DESC_GET_FIELD((_prHwMacRxDesc)->u4DW3, \ +CONNAC2X_RX_STATUS_CH_FREQ_MASK, CONNAC2X_RX_STATUS_CH_FREQ_OFFSET)) + +#define HAL_MAC_CONNAC2X_RX_STATUS_GET_TCL(_prHwMacRxDesc) \ +(((_prHwMacRxDesc)->u4DW3 & CONNAC2X_RX_STATUS_FLAG_TCL)?TRUE:FALSE) + +#define HAL_MAC_CONNAC2X_RX_STATUS_GET_PAYLOAD_FORMAT(_prHwMacRxDesc) \ +RX_DESC_GET_FIELD((_prHwMacRxDesc)->u4DW4, \ +CONNAC2X_RX_STATUS_PF_MASK, CONNAC2X_RX_STATUS_PF_OFFSET) + +#define HAL_MAC_CONNAC2X_RX_STATUS_GET_OFLD(_prHwMacRxDesc) \ +(((_prHwMacRxDesc)->u4DW4 & CONNAC2X_RX_STATUS_OFLD_MASK) >> \ +CONNAC2X_RX_STATUS_OFLD_OFFSET) + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* CFG_SUPPORT_CONNAC2X == 1 */ +#endif /* _NIC_CONNAC2X_RX_H */ + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/nic_connac2x_tx.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/nic_connac2x_tx.h new file mode 100644 index 0000000000000000000000000000000000000000..2fa626e0d958fb0e459cac2718631ccc25cd42e1 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/nic_connac2x_tx.h @@ -0,0 +1,871 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/*! \file nic_connac2x_tx.h +* \brief Functions that provide TX operation in NIC's point of view. +* +* This file provides TX functions which are responsible for both Hardware and +* Software Resource Management and keep their Synchronization. +* +*/ + + +#ifndef _NIC_CONNAC2X_TX_H +#define _NIC_CONNAC2X_TX_H + +#if (CFG_SUPPORT_CONNAC2X == 1) +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ +#define NORMAL_GI 0 +#define SHORT_GI 1 +#define CONNAC2X_TX_DESC_LIFE_TIME_UNIT_IN_POWER_OF_2 6 + +/*------------------------------------------------------------------------*/ +/* Tx descriptor field related information */ +/*------------------------------------------------------------------------*/ +/* DW 0 */ +#define CONNAC2X_TX_DESC_TX_BYTE_COUNT_MASK BITS(0, 15) +#define CONNAC2X_TX_DESC_TX_BYTE_COUNT_OFFSET 0 + +#define CONNAC2X_TX_DESC_ETHER_TYPE_OFFSET_MASK BITS(16, 22) +#define CONNAC2X_TX_DESC_ETHER_TYPE_OFFSET_OFFSET 16 + +#define CONNAC2X_TX_DESC_PACKET_FORMAT_MASK BITS(23, 24) +#define CONNAC2X_TX_DESC_PACKET_FORMAT_OFFSET 23 + +#define CONNAC2X_TX_DESC_QUEUE_INDEX_MASK BITS(25, 31) +#define CONNAC2X_TX_DESC_QUEUE_INDEX_OFFSET 25 + +/* DW 1 */ +#define CONNAC2X_TX_DESC_WLAN_INDEX_MASK BITS(0, 9) +#define CONNAC2X_TX_DESC_WLAN_INDEX_OFFSET 0 +#define CONNAC2X_TX_DESC_VTA_MASK BIT(10) +#define CONNAC2X_TX_DESC_VTA_OFFSET 10 + + +#define CONNAC2X_TX_DESC_HEADER_FORMAT_MASK BITS(16, 17) +#define CONNAC2X_TX_DESC_HEADER_FORMAT_OFFSET 16 + +#define CONNAC2X_TX_DESC_NON_802_11_MORE_DATA BIT(11) +#define CONNAC2X_TX_DESC_NON_802_11_EOSP BIT(12) +#define CONNAC2X_TX_DESC_NON_802_11_REMOVE_VLAN BIT(13) +#define CONNAC2X_TX_DESC_NON_802_11_VLAN_FIELD BIT(14) +#define CONNAC2X_TX_DESC_NON_802_11_ETHERNET_II BIT(15) +#define CONNAC2X_TX_DESC_NOR_802_11_HEADER_LENGTH_MASK BITS(11, 15) +#define CONNAC2X_TX_DESC_NOR_802_11_HEADER_LENGTH_OFFSET 11 +#define CONNAC2X_TX_DESC_ENH_802_11_EOSP BIT(12) +#define CONNAC2X_TX_DESC_ENH_802_11_AMSDU BIT(13) + +#define CONNAC2X_TX_DESC_HEADER_PADDING_LENGTH_MASK BIT(18) +#define CONNAC2X_TX_DESC_HEADER_PADDING_LENGTH_OFFSET 18 +#define CONNAC2X_TX_DESC_HEADER_PADDING_MODE BIT(19) + +#define CONNAC2X_TX_DESC_TID_MASK BITS(20, 22) +#define CONNAC2X_TX_DESC_TID_OFFSET 20 +#define CONNAC2X_TX_DESC_TID_NUM 8 + +#define CONNAC2X_TX_DESC_TXD_UTXB_AMSDU_MASK BIT(23) +#define CONNAC2X_TX_DESC_TXD_UTXB_AMSDU_OFFSET 23 + +#define CONNAC2X_TX_DESC_OWN_MAC_MASK BITS(24, 29) +#define CONNAC2X_TX_DESC_OWN_MAC_OFFSET 24 + + #define CONNAC2X_TX_DESC_TGID_MASK BIT(30) +#define CONNAC2X_TX_DESC_TGID_OFFSET 30 +#define CONNAC2X_TX_DESC_FORMAT BIT(31) + +/* DW 2 */ +#define CONNAC2X_TX_DESC_SUB_TYPE_MASK BITS(0, 3) +#define CONNAC2X_TX_DESC_SUB_TYPE_OFFSET 0 +#define CONNAC2X_TX_DESC_TYPE_MASK BITS(4, 5) +#define CONNAC2X_TX_DESC_TYPE_OFFSET 4 +#define CONNAC2X_TX_DESC_NDP BIT(6) +#define CONNAC2X_TX_DESC_NDPA BIT(7) + +#define CONNAC2X_TX_DESC_SOUNDING BIT(8) +#define CONNAC2X_TX_DESC_FORCE_RTS_CTS BIT(9) +#define CONNAC2X_TX_DESC_BROADCAST_MULTICAST BIT(10) +#define CONNAC2X_TX_DESC_BIP_PROTECTED BIT(11) +#define CONNAC2X_TX_DESC_DURATION_FIELD_CONTROL BIT(12) +#define CONNAC2X_TX_DESC_HTC_EXISTS BIT(13) +#define CONNAC2X_TX_DESC_FRAGMENT_MASK BITS(14, 15) +#define CONNAC2X_TX_DESC_FRAGMENT_OFFSET 14 + +#define CONNAC2X_TX_DESC_REMAINING_MAX_TX_TIME_MASK BITS(16, 23) +#define CONNAC2X_TX_DESC_REMAINING_MAX_TX_TIME_OFFSET 16 + +#define CONNAC2X_TX_DESC_POWER_OFFSET_MASK BITS(24, 29) +#define CONNAC2X_TX_DESC_POWER_OFFSET_OFFSET 24 +#define CONNAC2X_TX_DESC_FIXED_RATE_MODE BIT(30) +#define CONNAC2X_TX_DESC_FIXED_RATE BIT(31) + +/* DW 3 */ +#define CONNAC2X_TX_DESC_NO_ACK BIT(0) +#define CONNAC2X_TX_DESC_PROTECTED_FRAME BIT(1) +#define CONNAC2X_TX_DESC_EXTEND_MORE_DATA BIT(2) +#define CONNAC2X_TX_DESC_EXTEND_EOSP BIT(3) +#define CONNAC2X_TX_DESC_DA_SOURCE BIT(4) +#define CONNAC2X_TX_DESC_TIMING_MEASUREMENT BIT(5) +#define CONNAC2X_TX_DESC_TX_COUNT_MASK BITS(6, 10) +#define CONNAC2X_TX_DESC_TX_COUNT_OFFSET 6 +#define CONNAC2X_TX_DESC_REMAINING_TX_COUNT_MASK BITS(11, 15) +#define CONNAC2X_TX_DESC_REMAINING_TX_COUNT_OFFSET 11 +#define CONNAC2X_TX_DESC_SEQUENCE_NUMBER_MASK BITS(16, 27) +#define CONNAC2X_TX_DESC_SEQUENCE_NUMBER_MASK_OFFSET 16 +#define CONNAC2X_TX_DESC_BA_DISABLE BIT(28) +#define CONNAC2X_TX_DESC_POWER_MANAGEMENT_CONTROL BIT(29) +#define CONNAC2X_TX_DESC_PN_IS_VALID BIT(30) +#define CONNAC2X_TX_DESC_SN_IS_VALID BIT(31) + +/* DW 4 */ +#define CONNAC2X_TX_DESC_PN_PART1 BITS(0, 31) + +/* DW 5 */ +#define CONNAC2X_TX_DESC_PACKET_ID_MASK BITS(0, 7) +#define CONNAC2X_TX_DESC_PACKET_ID_OFFSET 0 +#define CONNAC2X_TX_DESC_TX_STATUS_FORMAT BIT(8) +#define CONNAC2X_TX_DESC_TX_STATUS_FORMAT_OFFSET 8 +#define CONNAC2X_TX_DESC_TX_STATUS_TO_MCU BIT(9) +#define CONNAC2X_TX_DESC_TX_STATUS_TO_HOST BIT(10) +#define CONNAC2X_TX_DESC_ADD_BA BIT(14) +#define CONNAC2X_TX_DESC_ADD_BA_OFFSET 14 +#define CONNAC2X_TX_DESC_MD_MASK BIT(15) +#define CONNAC2X_TX_DESC_MD_OFFSET 15 +#define CONNAC2X_TX_DESC_PN_PART2_MASK BITS(16, 31) +#define CONNAC2X_TX_DESC_PN_PART2__OFFSET 16 + +/* DW 6 *//* FR = 1 */ +#define CONNAC2X_TX_DESC_BANDWIDTH_MASK BITS(0, 2) +#define CONNAC2X_TX_DESC_BANDWIDTH_OFFSET 0 +#define CONNAC2X_TX_DESC_DYNAMIC_BANDWIDTH BIT(3) + #define CONNAC2X_TX_DESC_ANTENNA_INDEX_MASK BITS(4, 7) +#define CONNAC2X_TX_DESC_ANTENNA_INDEX_OFFSET 4 +#define CONNAC2X_TX_DESC_SPE_IDX_SEL BIT(10) +#define CONNAC2X_TX_DESC_SPE_IDX_SEL_OFFSET 10 +/* in DW5 for AXE : LDPC, HE_LTF, GI_TYPE*/ +#define CONNAC2X_TX_DESC_LDPC BIT(11) +#define CONNAC2X_TX_DESC_LDPC_OFFSET 11 +#define CONNAC2X_TX_DESC_HE_LTF_MASK BITS(12, 13) +#define CONNAC2X_TX_DESC_HE_LTF_OFFSET 12 +#define CONNAC2X_TX_DESC_GI_TYPE BITS(14, 15) +#define CONNAC2X_TX_DESC_GI_TYPE_OFFSET 14 +#define CONNAC2X_TX_DESC_FIXDE_RATE_MASK BITS(16, 29) +#define CONNAC2X_TX_DESC_FIXDE_RATE_OFFSET 16 +#define CONNAC2X_TX_DESC_TXE_BF BIT(30) +#define CONNAC2X_TX_DESC_TXI_BF BIT(31) + +/* DW 7 */ +#define CONNAC2X_TX_DESC_TXD_ARRIVAL_TIME_MASK BITS(0, 9) + +#define CONNAC2X_TX_DESC_HW_AMSDU BIT(10) +#define CONNAC2X_TX_DESC_SPE_EXT_IDX_MASK BITS(11, 15) +#define CONNAC2X_TX_DESC_SPE_EXT_IDX_OFFSET 11 +/* For cut-through only */ +#define CONNAC2X_TX_DESC7_SUB_TYPE_MASK BITS(16, 19) +#define CONNAC2X_TX_DESC7_SUB_TYPE_OFFSET 16 +/* For cut-through only */ +#define CONNAC2X_TX_DESC7_TYPE_MASK BITS(20, 21) +#define CONNAC2X_TX_DESC7_TYPE_OFFSET 20 + +#define CONNAC2X_TX_DESC_IP_CHKSUM_OFFLOAD BIT(28) +#define CONNAC2X_TX_DESC_TCP_UDP_CHKSUM_OFFLOAD BIT(29) +#define CONNAC2X_TX_DESC_TXD_LENGTH_MASK BITS(30, 31) +#define CONNAC2X_TX_DESC_TXD_LENGTH_OFFSET 30 + +/* For Debug Information Use */ +#define CONNAC2X_TX_DESC_PSE_FID_MASK BITS(16, 27) +#define CONNAC2X_TX_DESC_PSE_FID_OFFSET 16 +#define CONNAC2X_TX_DESC_CTXD_CNT_MASK BITS(23, 25) +#define CONNAC2X_TX_DESC_CTXD_CNT_OFFSET 23 +#define CONNAC2X_TX_DESC_CTXD BIT(26) + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +struct HW_MAC_CONNAC2X_TX_DESC { + uint32_t u4DW0; + uint32_t u4DW1; + uint32_t u4DW2; + uint32_t u4DW3; + uint32_t u4PN1; + uint16_t u2DW5_0; + uint16_t u2PN2; + uint32_t u4DW6; + uint32_t u4DW7; +}; + + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/*------------------------------------------------------------------------------ + * MACRO for HW_MAC_TX_DESC_T + *------------------------------------------------------------------------------ + */ + +#define HAL_MAC_CONNAC2X_TXD_GET_TX_BYTE_COUNT(_prHwMacTxDesc) \ +TX_DESC_GET_FIELD((_prHwMacTxDesc)->u4DW0, \ +CONNAC2X_TX_DESC_TX_BYTE_COUNT_MASK, CONNAC2X_TX_DESC_TX_BYTE_COUNT_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_SET_TX_BYTE_COUNT(_prHwMacTxD, _u2TxByteCount)\ +TX_DESC_SET_FIELD(((_prHwMacTxD)->u4DW0), ((uint16_t)_u2TxByteCount), \ +CONNAC2X_TX_DESC_TX_BYTE_COUNT_MASK, CONNAC2X_TX_DESC_TX_BYTE_COUNT_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_GET_ETHER_TYPE_OFFSET(_prHwMacTxDesc) \ +TX_DESC_GET_FIELD((_prHwMacTxDesc)->u4DW0, \ +CONNAC2X_TX_DESC_ETHER_TYPE_OFFSET_MASK, \ +CONNAC2X_TX_DESC_ETHER_TYPE_OFFSET_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_SET_ETHER_TYPE_OFFSET(_prHwMacTxD, _ucEthTypOff)\ +TX_DESC_SET_FIELD(((_prHwMacTxD)->u4DW0), ((uint8_t)_ucEthTypOff), \ +CONNAC2X_TX_DESC_ETHER_TYPE_OFFSET_MASK, \ +CONNAC2X_TX_DESC_ETHER_TYPE_OFFSET_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_IS_IP_CHKSUM_ENABLED(_prHwMacTxDesc) \ +(((_prHwMacTxDesc)->u4DW7 & CONNAC2X_TX_DESC_IP_CHKSUM_OFFLOAD)?FALSE:TRUE) + +#define HAL_MAC_CONNAC2X_TXD_SET_IP_CHKSUM(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW7 |= CONNAC2X_TX_DESC_IP_CHKSUM_OFFLOAD) + +#define HAL_MAC_CONNAC2X_TXD_UNSET_IP_CHKSUM(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW7 &= ~CONNAC2X_TX_DESC_IP_CHKSUM_OFFLOAD) + +#define HAL_MAC_CONNAC2X_TXD_IS_TCP_UDP_CHKSUM_ENABLED(_prHwMacTxDesc) \ +(((_prHwMacTxDesc)->u4DW7 & CONNAC2X_TX_DESC_TCP_UDP_CHKSUM_OFFLOAD)?FALSE:TRUE) + +#define HAL_MAC_CONNAC2X_TXD_SET_TCP_UDP_CHKSUM(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW7 |= CONNAC2X_TX_DESC_TCP_UDP_CHKSUM_OFFLOAD) + +#define HAL_MAC_CONNAC2X_TXD_UNSET_TCP_UDP_CHKSUM(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW7 &= ~CONNAC2X_TX_DESC_TCP_UDP_CHKSUM_OFFLOAD) + +#define HAL_MAC_CONNAC2X_TXD_GET_QUEUE_INDEX(_prHwMacTxDesc) \ +TX_DESC_GET_FIELD((_prHwMacTxDesc)->u4DW0,\ +CONNAC2X_TX_DESC_QUEUE_INDEX_MASK, CONNAC2X_TX_DESC_QUEUE_INDEX_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_SET_QUEUE_INDEX(_prHwMacTxDesc, _ucQueueIndex) \ +TX_DESC_SET_FIELD(((_prHwMacTxDesc)->u4DW0), ((uint8_t)_ucQueueIndex), \ +CONNAC2X_TX_DESC_QUEUE_INDEX_MASK, CONNAC2X_TX_DESC_QUEUE_INDEX_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_GET_WLAN_INDEX(_prHwMacTxDesc) \ +TX_DESC_GET_FIELD((_prHwMacTxDesc)->u4DW1,\ +CONNAC2X_TX_DESC_WLAN_INDEX_MASK, CONNAC2X_TX_DESC_WLAN_INDEX_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_SET_WLAN_INDEX(_prHwMacTxDesc, _ucWlanIdx) \ +TX_DESC_SET_FIELD(((_prHwMacTxDesc)->u4DW1), ((uint8_t)_ucWlanIdx), \ +CONNAC2X_TX_DESC_WLAN_INDEX_MASK, CONNAC2X_TX_DESC_WLAN_INDEX_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_IS_LONG_FORMAT(_prHwMacTxDesc) \ +(((_prHwMacTxDesc)->u4DW1 & CONNAC2X_TX_DESC_FORMAT)?TRUE:FALSE) + +#define HAL_MAC_CONNAC2X_TXD_SET_LONG_FORMAT(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW1 |= CONNAC2X_TX_DESC_FORMAT) + +#define HAL_MAC_CONNAC2X_TXD_SET_SHORT_FORMAT(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW1 &= ~CONNAC2X_TX_DESC_FORMAT) + +#define HAL_MAC_CONNAC2X_TXD_GET_HEADER_FORMAT(_prHwMacTxDesc) \ +TX_DESC_GET_FIELD((_prHwMacTxDesc)->u4DW1, \ +CONNAC2X_TX_DESC_HEADER_FORMAT_MASK, CONNAC2X_TX_DESC_HEADER_FORMAT_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_SET_HEADER_FORMAT(_prHwMacTxDesc, _ucHdrFormat) \ +TX_DESC_SET_FIELD(((_prHwMacTxDesc)->u4DW1), \ +((uint8_t)_ucHdrFormat), CONNAC2X_TX_DESC_HEADER_FORMAT_MASK,\ +CONNAC2X_TX_DESC_HEADER_FORMAT_OFFSET) + +/* HF = 0x00, 802.11 normal mode */ +#define HAL_MAC_CONNAC2X_TXD_IS_MORE_DATA(_prHwMacTxDesc) \ +(((_prHwMacTxDesc)->u4DW1 & CONNAC2X_TX_DESC_NON_802_11_MORE_DATA)?TRUE:FALSE) +#define HAL_MAC_CONNAC2X_TXD_SET_MORE_DATA(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW1 |= CONNAC2X_TX_DESC_NON_802_11_MORE_DATA) +#define HAL_MAC_CONNAC2X_TXD_UNSET_MORE_DATA(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW1 &= ~CONNAC2X_TX_DESC_NON_802_11_MORE_DATA) + +#define HAL_MAC_CONNAC2X_TXD_IS_REMOVE_VLAN(_prHwMacTxDesc) \ +(((_prHwMacTxDesc)->u4DW1 & CONNAC2X_TX_DESC_NON_802_11_REMOVE_VLAN)?TRUE:FALSE) +#define HAL_MAC_CONNAC2X_TXD_SET_REMOVE_VLAN(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW1 |= CONNAC2X_TX_DESC_NON_802_11_REMOVE_VLAN) +#define HAL_MAC_CONNAC2X_TXD_UNSET_REMOVE_VLAN(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW1 &= ~CONNAC2X_TX_DESC_NON_802_11_REMOVE_VLAN) + +#define HAL_MAC_CONNAC2X_TXD_IS_VLAN(_prHwMacTxDesc) \ +(((_prHwMacTxDesc)->u4DW1 & CONNAC2X_TX_DESC_NON_802_11_VLAN_FIELD)?TRUE:FALSE) +#define HAL_MAC_CONNAC2X_TXD_SET_VLAN(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW1 |= CONNAC2X_TX_DESC_NON_802_11_VLAN_FIELD) +#define HAL_MAC_CONNAC2X_TXD_UNSET_VLAN(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW1 &= ~CONNAC2X_TX_DESC_NON_802_11_VLAN_FIELD) + +#define HAL_MAC_CONNAC2X_TXD_IS_ETHERNET_II(_prHwMacTxDesc) \ +(((_prHwMacTxDesc)->u4DW1 & CONNAC2X_TX_DESC_NON_802_11_ETHERNET_II)?TRUE:FALSE) +#define HAL_MAC_CONNAC2X_TXD_SET_ETHERNET_II(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW1 |= CONNAC2X_TX_DESC_NON_802_11_ETHERNET_II) +#define HAL_MAC_CONNAC2X_TXD_UNSET_ETHERNET_II(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW1 &= ~CONNAC2X_TX_DESC_NON_802_11_ETHERNET_II) + +/* HF = 0x00/0x11, 802.11 normal/enhancement mode */ +#define HAL_MAC_CONNAC2X_TXD_IS_EOSP(_prHwMacTxDesc) \ +(((_prHwMacTxDesc)->u4DW1 & CONNAC2X_TX_DESC_NON_802_11_EOSP)?TRUE:FALSE) +#define HAL_MAC_CONNAC2X_TXD_SET_EOSP(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW1 |= CONNAC2X_TX_DESC_NON_802_11_EOSP) +#define HAL_MAC_CONNAC2X_TXD_UNSET_EOSP(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW1 &= ~CONNAC2X_TX_DESC_NON_802_11_EOSP) + +/* HF = 0x11, 802.11 enhancement mode */ +#define HAL_MAC_CONNAC2X_TXD_IS_AMSDU(_prHwMacTxDesc) \ +(((_prHwMacTxDesc)->u4DW1 & CONNAC2X_TX_DESC_ENH_802_11_AMSDU)?TRUE:FALSE) +#define HAL_MAC_CONNAC2X_TXD_SET_AMSDU(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW1 |= CONNAC2X_TX_DESC_ENH_802_11_AMSDU) +#define HAL_MAC_CONNAC2X_TXD_UNSET_AMSDU(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW1 &= ~CONNAC2X_TX_DESC_ENH_802_11_AMSDU) + +/* HF = 0x10, non-802.11 */ +#define HAL_MAC_CONNAC2X_TXD_GET_802_11_HEADER_LENGTH(_prHwMacTxDesc) \ +TX_DESC_GET_FIELD((_prHwMacTxDesc)->u4DW1, \ +CONNAC2X_TX_DESC_NOR_802_11_HEADER_LENGTH_MASK, \ +CONNAC2X_TX_DESC_NOR_802_11_HEADER_LENGTH_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_SET_802_11_HEADER_LENGTH(_prHwMacTxD, _ucHdrLen)\ +TX_DESC_SET_FIELD(((_prHwMacTxD)->u4DW1), ((uint8_t)_ucHdrLen), \ +CONNAC2X_TX_DESC_NOR_802_11_HEADER_LENGTH_MASK, \ +CONNAC2X_TX_DESC_NOR_802_11_HEADER_LENGTH_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_GET_TXD_LENGTH(_prHwMacTxDesc) \ +TX_DESC_GET_FIELD((_prHwMacTxDesc)->u4DW7, \ +CONNAC2X_TX_DESC_TXD_LENGTH_MASK, CONNAC2X_TX_DESC_TXD_LENGTH_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_SET_TXD_LENGTH(_prHwMacTxDesc, _ucHdrPadding) \ +TX_DESC_SET_FIELD(((_prHwMacTxDesc)->u4DW7), ((uint8_t)_ucHdrPadding), \ +CONNAC2X_TX_DESC_TXD_LENGTH_MASK, CONNAC2X_TX_DESC_TXD_LENGTH_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_GET_HEADER_PADDING(_prHwMacTxDesc) \ +TX_DESC_GET_FIELD((_prHwMacTxDesc)->u4DW1, \ +CONNAC2X_TX_DESC_HEADER_PADDING_LENGTH_MASK, \ +CONNAC2X_TX_DESC_HEADER_PADDING_LENGTH_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_SET_HEADER_PADDING(_prHwMacTxD, _ucHdrPadding) \ +TX_DESC_SET_FIELD(((_prHwMacTxD)->u4DW1), ((uint8_t)_ucHdrPadding), \ +CONNAC2X_TX_DESC_HEADER_PADDING_LENGTH_MASK, \ +CONNAC2X_TX_DESC_HEADER_PADDING_LENGTH_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_GET_UTXB_AMSDU(_prHwMacTxDesc) \ +TX_DESC_GET_FIELD((_prHwMacTxDesc)->u4DW1, \ +CONNAC2X_TX_DESC_TXD_UTXB_AMSDU_MASK, CONNAC2X_TX_DESC_TXD_UTXB_AMSDU_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_SET_UTXB_AMSDU(_prHwMacTxDesc, _ucHdrPadding) \ +TX_DESC_SET_FIELD(((_prHwMacTxDesc)->u4DW1), ((uint8_t)_ucHdrPadding), \ +CONNAC2X_TX_DESC_TXD_UTXB_AMSDU_MASK, CONNAC2X_TX_DESC_TXD_UTXB_AMSDU_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_IS_HEADER_PADDING_IN_THE_HEAD(_prHwMacTxDesc) \ +(((_prHwMacTxDesc)->u4DW1 & CONNAC2X_TX_DESC_HEADER_PADDING_MODE)?TRUE:FALSE) +#define HAL_MAC_CONNAC2X_TXD_SET_HEADER_PADDING_IN_THE_HEAD(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW1 |= CONNAC2X_TX_DESC_HEADER_PADDING_MODE) +#define HAL_MAC_CONNAC2X_TXD_SET_HEADER_PADDING_IN_THE_TAIL(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW1 &= ~CONNAC2X_TX_DESC_HEADER_PADDING_MODE) + +#define HAL_MAC_CONNAC2X_TXD_GET_TID(_prHwMacTxDesc) \ +TX_DESC_GET_FIELD((_prHwMacTxDesc)->u4DW1, CONNAC2X_TX_DESC_TID_MASK, \ +CONNAC2X_TX_DESC_TID_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_SET_TID(_prHwMacTxDesc, _ucTID) \ +TX_DESC_SET_FIELD(((_prHwMacTxDesc)->u4DW1), \ +((uint8_t)_ucTID), CONNAC2X_TX_DESC_TID_MASK, CONNAC2X_TX_DESC_TID_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_GET_PKT_FORMAT(_prHwMacTxDesc) \ +TX_DESC_GET_FIELD((_prHwMacTxDesc)->u4DW0, \ +CONNAC2X_TX_DESC_PACKET_FORMAT_MASK, CONNAC2X_TX_DESC_PACKET_FORMAT_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_SET_PKT_FORMAT(_prHwMacTxDesc, _ucPktFormat) \ +TX_DESC_SET_FIELD(((_prHwMacTxDesc)->u4DW0), ((uint8_t)_ucPktFormat), \ +CONNAC2X_TX_DESC_PACKET_FORMAT_MASK, CONNAC2X_TX_DESC_PACKET_FORMAT_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_GET_OWN_MAC_INDEX(_prHwMacTxDesc) \ +TX_DESC_GET_FIELD((_prHwMacTxDesc)->u4DW1, \ +CONNAC2X_TX_DESC_OWN_MAC_MASK, CONNAC2X_TX_DESC_OWN_MAC_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_SET_OWN_MAC_INDEX(_prHwMacTxDesc, _ucOwnMacIdx) \ +TX_DESC_SET_FIELD(((_prHwMacTxDesc)->u4DW1), ((uint8_t)_ucOwnMacIdx), \ +CONNAC2X_TX_DESC_OWN_MAC_MASK, CONNAC2X_TX_DESC_OWN_MAC_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_GET_SUB_TYPE(_prHwMacTxDesc) \ +TX_DESC_GET_FIELD((_prHwMacTxDesc)->u4DW2, \ +CONNAC2X_TX_DESC_SUB_TYPE_MASK, CONNAC2X_TX_DESC_SUB_TYPE_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_SET_SUB_TYPE(_prHwMacTxDesc, _ucSubType) \ +TX_DESC_SET_FIELD(((_prHwMacTxDesc)->u4DW2), ((uint8_t)_ucSubType), \ +CONNAC2X_TX_DESC_SUB_TYPE_MASK, CONNAC2X_TX_DESC_SUB_TYPE_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_GET_TYPE(_prHwMacTxDesc) \ +TX_DESC_GET_FIELD((_prHwMacTxDesc)->u4DW2, CONNAC2X_TX_DESC_TYPE_MASK, \ +CONNAC2X_TX_DESC_TYPE_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_SET_TYPE(_prHwMacTxDesc, _ucType) \ +TX_DESC_SET_FIELD(((_prHwMacTxDesc)->u4DW2), ((uint8_t)_ucType), \ +CONNAC2X_TX_DESC_TYPE_MASK, CONNAC2X_TX_DESC_TYPE_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_IS_NDP(_prHwMacTxDesc) \ +(((_prHwMacTxDesc)->u4DW2 & CONNAC2X_TX_DESC_NDP)?TRUE:FALSE) + +#define HAL_MAC_CONNAC2X_TXD_SET_NDP(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW2 |= CONNAC2X_TX_DESC_NDP) + +#define HAL_MAC_CONNAC2X_TXD_UNSET_NDP(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW2 &= ~CONNAC2X_TX_DESC_NDP) + +#define HAL_MAC_CONNAC2X_TXD_IS_NDPA(_prHwMacTxDesc) \ +(((_prHwMacTxDesc)->u4DW2 & CONNAC2X_TX_DESC_NDPA)?TRUE:FALSE) + +#define HAL_MAC_CONNAC2X_TXD_SET_NDPA(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW2 |= CONNAC2X_TX_DESC_NDPA) + +#define HAL_MAC_CONNAC2X_TXD_UNSET_NDPA(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW2 &= ~CONNAC2X_TX_DESC_NDPA) + +#define HAL_MAC_CONNAC2X_TXD_IS_SOUNDING_FRAME(_prHwMacTxDesc) \ +(((_prHwMacTxDesc)->u4DW2 & CONNAC2X_TX_DESC_SOUNDING)?TRUE:FALSE) + +#define HAL_MAC_CONNAC2X_TXD_SET_SOUNDING_FRAME(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW2 |= CONNAC2X_TX_DESC_SOUNDING) + +#define HAL_MAC_CONNAC2X_TXD_UNSET_SOUNDING_FRAME(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW2 &= ~CONNAC2X_TX_DESC_SOUNDING) + +#define HAL_MAC_CONNAC2X_TXD_IS_FORCE_RTS_CTS_EN(_prHwMacTxDesc) \ +(((_prHwMacTxDesc)->u4DW2 & CONNAC2X_TX_DESC_FORCE_RTS_CTS)?TRUE:FALSE) + +#define HAL_MAC_CONNAC2X_TXD_SET_FORCE_RTS_CTS(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW2 |= CONNAC2X_TX_DESC_FORCE_RTS_CTS) + +#define HAL_MAC_CONNAC2X_TXD_UNSET_FORCE_RTS_CTS(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW2 &= ~CONNAC2X_TX_DESC_FORCE_RTS_CTS) + +#define HAL_MAC_CONNAC2X_TXD_IS_BMC(_prHwMacTxDesc) \ +(((_prHwMacTxDesc)->u4DW2 & CONNAC2X_TX_DESC_BROADCAST_MULTICAST)?TRUE:FALSE) + +#define HAL_MAC_CONNAC2X_TXD_SET_BMC(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW2 |= CONNAC2X_TX_DESC_BROADCAST_MULTICAST) + +#define HAL_MAC_CONNAC2X_TXD_UNSET_BMC(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW2 &= ~CONNAC2X_TX_DESC_BROADCAST_MULTICAST) + +#define HAL_MAC_CONNAC2X_TXD_IS_BIP(_prHwMacTxDesc) \ +(((_prHwMacTxDesc)->u4DW2 & CONNAC2X_TX_DESC_BIP_PROTECTED)?TRUE:FALSE) + +#define HAL_MAC_CONNAC2X_TXD_SET_BIP(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW2 |= CONNAC2X_TX_DESC_BIP_PROTECTED) + +#define HAL_MAC_CONNAC2X_TXD_UNSET_BIP(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW2 &= ~CONNAC2X_TX_DESC_BIP_PROTECTED) + +#define HAL_MAC_CONNAC2X_TXD_IS_DURATION_CONTROL_BY_SW(_prHwMacTxDesc) \ +(((_prHwMacTxDesc)->u4DW2 & CONNAC2X_TX_DESC_DURATION_FIELD_CONTROL)?TRUE:FALSE) + +#define HAL_MAC_CONNAC2X_TXD_SET_DURATION_CONTROL_BY_SW(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW2 |= CONNAC2X_TX_DESC_DURATION_FIELD_CONTROL) + +#define HAL_MAC_CONNAC2X_TXD_SET_DURATION_CONTROL_BY_HW(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW2 &= ~CONNAC2X_TX_DESC_DURATION_FIELD_CONTROL) + +#define HAL_MAC_CONNAC2X_TXD_IS_HTC_EXIST(_prHwMacTxDesc) \ +(((_prHwMacTxDesc)->u4DW2 & CONNAC2X_TX_DESC_HTC_EXISTS)?TRUE:FALSE) + +#define HAL_MAC_CONNAC2X_TXD_SET_HTC_EXIST(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW2 |= CONNAC2X_TX_DESC_HTC_EXISTS) + +#define HAL_MAC_CONNAC2X_TXD_UNSET_HTC_EXIST(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW2 &= ~CONNAC2X_TX_DESC_HTC_EXISTS) + +#define HAL_MAC_CONNAC2X_TXD_IS_FRAG_PACKET(_prHwMacTxDesc) \ +(((_prHwMacTxDesc)->u4DW2 & CONNAC2X_TX_DESC_FRAGMENT_MASK)?TRUE:FALSE) + +#define HAL_MAC_CONNAC2X_TXD_GET_FRAG_PACKET_POS(_prHwMacTxDesc) \ +TX_DESC_GET_FIELD((_prHwMacTxDesc)->u4DW2, CONNAC2X_TX_DESC_FRAGMENT_MASK, \ +CONNAC2X_TX_DESC_FRAGMENT_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_SET_FRAG_PACKET_POS(_prHwMacTxDesc, _ucFragPos)\ +TX_DESC_SET_FIELD(((_prHwMacTxDesc)->u4DW2), ((uint8_t)_ucFragPos), \ +CONNAC2X_TX_DESC_FRAGMENT_MASK, CONNAC2X_TX_DESC_FRAGMENT_OFFSET) + +/* For driver */ +/* in unit of 32TU */ +#define HAL_MAC_CONNAC2X_TXD_GET_REMAINING_LIFE_TIME(_prHwMacTxDesc) \ +TX_DESC_GET_FIELD((_prHwMacTxDesc)->u4DW2, \ +CONNAC2X_TX_DESC_REMAINING_MAX_TX_TIME_MASK, \ +CONNAC2X_TX_DESC_REMAINING_MAX_TX_TIME_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_SET_REMAINING_LIFE_TIME(_prHwMacTxD, _LifeTime) \ +TX_DESC_SET_FIELD(((_prHwMacTxD)->u4DW2), ((uint8_t)_LifeTime), \ +CONNAC2X_TX_DESC_REMAINING_MAX_TX_TIME_MASK, \ +CONNAC2X_TX_DESC_REMAINING_MAX_TX_TIME_OFFSET) + +/* in unit of ms (minimal value is about 40ms) */ +#define HAL_MAC_CONNAC2X_TXD_GET_REMAINING_LIFE_TIME_IN_MS(_prHwMacTxDesc) \ +(TU_TO_MSEC(HAL_MAC_CONNAC2X_TXD_GET_REMAINING_LIFE_TIME(_prHwMacTxDesc)\ +<< CONNAC2X_TX_DESC_LIFE_TIME_UNIT_IN_POWER_OF_2)) + + +/* +* Remaining Life Time/ Max TX Time: This field indicates the remaining life +* time in unit of 64TU used for this packet. +* 8'h0: No life time for current packet, HW should NOT change this field +* 8'hN: N is not 0, HW will calculation a Max. TX time and replace remaining +* TX time with it. The Max. value is 127. +* The MSB bit is reserved for HW and SW should set to 0 +* Due to HW design issue, the remaining life time sometimes may have 32TU +* more than configured. +* PP will replace this field with "Max. TX Time". +* (SUM of (Remaining Life Time + Internal Free-run Timer)). +* If the SUM is 0, PP will add 1 to it. +*/ +#define HAL_MAC_CONNAC2X_TXD_SET_REMAINING_LIFE_TIME_IN_MS(_prHwTxD, _LifeMs)\ +do { \ +uint32_t u4LifeTimeInUnit = ((MSEC_TO_USEC(_LifeMs) / USEC_PER_TU) \ + >> CONNAC2X_TX_DESC_LIFE_TIME_UNIT_IN_POWER_OF_2); \ +if (u4LifeTimeInUnit >= BIT(7)) \ + u4LifeTimeInUnit = BITS(0, 6); \ +else if ((u4LifeTimeInUnit != TX_DESC_TX_TIME_NO_LIMIT) \ + && (u4LifeTimeInUnit == TX_DESC_TX_TIME_NO_LIMIT)) \ + u4LifeTimeInUnit = 1; \ +HAL_MAC_CONNAC2X_TXD_SET_REMAINING_LIFE_TIME(_prHwTxD, \ + (uint8_t)u4LifeTimeInUnit); \ +} while (0) + +#define HAL_MAC_CONNAC2X_TXD_GET_POWER_OFFSET(_prHwMacTxDesc) \ +TX_DESC_GET_FIELD((_prHwMacTxDesc)->u4DW2, \ +CONNAC2X_TX_DESC_POWER_OFFSET_MASK, CONNAC2X_TX_DESC_POWER_OFFSET_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_SET_POWER_OFFSET(_prHwTxD, _ucPowerOffset) \ +TX_DESC_SET_FIELD(((_prHwTxD)->u4DW2), ((uint8_t)_ucPowerOffset), \ +CONNAC2X_TX_DESC_POWER_OFFSET_MASK, CONNAC2X_TX_DESC_POWER_OFFSET_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_IS_CR_FIXED_RATE_MODE(_prHwMacTxDesc) \ +(((_prHwMacTxDesc)->u4DW2 & CONNAC2X_TX_DESC_FIXED_RATE_MODE)?TRUE:FALSE) +#define HAL_MAC_CONNAC2X_TXD_SET_FIXED_RATE_MODE_TO_DESC(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW2 &= ~CONNAC2X_TX_DESC_FIXED_RATE_MODE) +#define HAL_MAC_CONNAC2X_TXD_SET_FIXED_RATE_MODE_TO_CR(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW2 |= CONNAC2X_TX_DESC_FIXED_RATE_MODE) + +#define HAL_MAC_CONNAC2X_TXD_IS_FIXED_RATE_ENABLE(_prHwMacTxDesc) \ +(((_prHwMacTxDesc)->u4DW2 & CONNAC2X_TX_DESC_FIXED_RATE)?TRUE:FALSE) +#define HAL_MAC_CONNAC2X_TXD_SET_FIXED_RATE_ENABLE(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW2 |= CONNAC2X_TX_DESC_FIXED_RATE) +#define HAL_MAC_CONNAC2X_TXD_SET_FIXED_RATE_DISABLE(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW2 &= ~CONNAC2X_TX_DESC_FIXED_RATE) + +#define HAL_MAC_CONNAC2X_TXD_IS_BA_DISABLE(_prHwMacTxDesc) \ +(((_prHwMacTxDesc)->u4DW3 & CONNAC2X_TX_DESC_BA_DISABLE)?TRUE:FALSE) + +#define HAL_MAC_CONNAC2X_TXD_SET_BA_DISABLE(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW3 |= CONNAC2X_TX_DESC_BA_DISABLE) +#define HAL_MAC_CONNAC2X_TXD_SET_BA_ENABLE(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW3 &= ~CONNAC2X_TX_DESC_BA_DISABLE) + +#define HAL_MAC_CONNAC2X_TXD_IS_TIMING_MEASUREMENT(_prHwMacTxDesc) \ +(((_prHwMacTxDesc)->u4DW3 & CONNAC2X_TX_DESC_TIMING_MEASUREMENT)?TRUE:FALSE) +#define HAL_MAC_CONNAC2X_TXD_SET_TIMING_MEASUREMENT(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW3 |= CONNAC2X_TX_DESC_TIMING_MEASUREMENT) +#define HAL_MAC_CONNAC2X_TXD_UNSET_TIMING_MEASUREMENT(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW3 &= ~CONNAC2X_TX_DESC_TIMING_MEASUREMENT) + +#define HAL_MAC_CONNAC2X_TXD_IS_NO_ACK(_prHwMacTxDesc) \ +(((_prHwMacTxDesc)->u4DW3 & CONNAC2X_TX_DESC_NO_ACK)?TRUE:FALSE) +#define HAL_MAC_CONNAC2X_TXD_SET_NO_ACK(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW3 |= CONNAC2X_TX_DESC_NO_ACK) +#define HAL_MAC_CONNAC2X_TXD_UNSET_NO_ACK(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW3 &= ~CONNAC2X_TX_DESC_NO_ACK) + +#define HAL_MAC_CONNAC2X_TXD_IS_PROTECTION(_prHwMacTxDesc) \ +(((_prHwMacTxDesc)->u4DW3 & CONNAC2X_TX_DESC_PROTECTED_FRAME)?TRUE:FALSE) +#define HAL_MAC_CONNAC2X_TXD_SET_PROTECTION(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW3 |= CONNAC2X_TX_DESC_PROTECTED_FRAME) +#define HAL_MAC_CONNAC2X_TXD_UNSET_PROTECTION(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW3 &= ~CONNAC2X_TX_DESC_PROTECTED_FRAME) + +#define HAL_MAC_CONNAC2X_TXD_IS_EXTEND_MORE_DATA(_prHwMacTxDesc) \ +(((_prHwMacTxDesc)->u4DW3 & CONNAC2X_TX_DESC_EXTEND_MORE_DATA)?TRUE:FALSE) +#define HAL_MAC_CONNAC2X_TXD_SET_EXTEND_MORE_DATA(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW3 |= CONNAC2X_TX_DESC_EXTEND_MORE_DATA) +#define HAL_MAC_CONNAC2X_TXD_UNSET_EXTEND_MORE_DATA(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW3 &= ~CONNAC2X_TX_DESC_EXTEND_MORE_DATA) + +#define HAL_MAC_CONNAC2X_TXD_IS_EXTEND_EOSP(_prHwMacTxDesc) \ +(((_prHwMacTxDesc)->u4DW3 & CONNAC2X_TX_DESC_EXTEND_EOSP)?TRUE:FALSE) +#define HAL_MAC_CONNAC2X_TXD_SET_EXTEND_EOSP(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW3 |= CONNAC2X_TX_DESC_EXTEND_EOSP) +#define HAL_MAC_CONNAC2X_TXD_UNSET_EXTEND_EOSP(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW3 &= ~CONNAC2X_TX_DESC_EXTEND_EOSP) + +#define HAL_MAC_CONNAC2X_TXD_GET_TX_COUNT(_prHwMacTxDesc) \ +TX_DESC_GET_FIELD((_prHwMacTxDesc)->u4DW3, \ +CONNAC2X_TX_DESC_TX_COUNT_MASK, CONNAC2X_TX_DESC_TX_COUNT_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_SET_TX_COUNT(_prHwMacTxDesc, _ucTxCountLimit) \ +TX_DESC_SET_FIELD(((_prHwMacTxDesc)->u4DW3), ((uint8_t)_ucTxCountLimit), \ +CONNAC2X_TX_DESC_TX_COUNT_MASK, CONNAC2X_TX_DESC_TX_COUNT_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_GET_REMAINING_TX_COUNT(_prHwMacTxDesc) \ +TX_DESC_GET_FIELD((_prHwMacTxDesc)->u4DW3, \ +CONNAC2X_TX_DESC_REMAINING_TX_COUNT_MASK, \ +CONNAC2X_TX_DESC_REMAINING_TX_COUNT_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_SET_REMAINING_TX_COUNT(_prHwTxD, _ucTxCntLimit) \ +TX_DESC_SET_FIELD(((_prHwTxD)->u4DW3), ((uint8_t)_ucTxCntLimit), \ +CONNAC2X_TX_DESC_REMAINING_TX_COUNT_MASK, \ +CONNAC2X_TX_DESC_REMAINING_TX_COUNT_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_GET_SEQUENCE_NUMBER(_prHwMacTxDesc) \ +TX_DESC_GET_FIELD((_prHwMacTxDesc)->u4DW3, \ +CONNAC2X_TX_DESC_SEQUENCE_NUMBER_MASK, \ +CONNAC2X_TX_DESC_SEQUENCE_NUMBER_MASK_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_SET_SEQUENCE_NUMBER(_prHwMacTxDesc, _u2SN) \ +TX_DESC_SET_FIELD(((_prHwMacTxDesc)->u4DW3), \ +((uint16_t)_u2SN), CONNAC2X_TX_DESC_SEQUENCE_NUMBER_MASK, \ +CONNAC2X_TX_DESC_SEQUENCE_NUMBER_MASK_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_IS_TXD_SN_VALID(_prHwMacTxDesc) \ +(((_prHwMacTxDesc)->u4DW3 & CONNAC2X_TX_DESC_SN_IS_VALID)?TRUE:FALSE) +#define HAL_MAC_CONNAC2X_TXD_SET_TXD_SN_VALID(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW3 |= CONNAC2X_TX_DESC_SN_IS_VALID) +#define HAL_MAC_CONNAC2X_TXD_SET_TXD_SN_INVALID(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW3 &= ~CONNAC2X_TX_DESC_SN_IS_VALID) + +#define HAL_MAC_CONNAC2X_TXD_IS_TXD_PN_VALID(_prHwMacTxDesc) \ +(((_prHwMacTxDesc)->u4DW3 & CONNAC2X_TX_DESC_PN_IS_VALID)?TRUE:FALSE) +#define HAL_MAC_CONNAC2X_TXD_SET_TXD_PN_VALID(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW3 |= CONNAC2X_TX_DESC_PN_IS_VALID) +#define HAL_MAC_CONNAC2X_TXD_SET_TXD_PN_INVALID(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW3 &= ~CONNAC2X_TX_DESC_PN_IS_VALID) + +#define HAL_MAC_CONNAC2X_TXD_ASSIGN_SN_BY_SW(_prHwMacTxDesc, _u2SN) \ +{ \ + HAL_MAC_CONNAC2X_TXD_SET_SEQUENCE_NUMBER(_prHwMacTxDesc, _u2SN); \ + HAL_MAC_CONNAC2X_TXD_SET_TXD_SN_VALID(_prHwMacTxDesc); \ +} +#define HAL_MAC_CONNAC2X_TXD_ASSIGN_SN_BY_HW(_prHwMacTxDesc) \ +{ \ + HAL_MAC_CONNAC2X_TXD_SET_SEQUENCE_NUMBER(_prHwMacTxDesc, 0); \ + HAL_MAC_CONNAC2X_TXD_SET_TXD_SN_INVALID(_prHwMacTxDesc); \ +} + +#if 0 +#define HAL_MAC_FALCON_TX_DESC_GET_PN(_prHwMacTxDesc, _u4PN_0_31, _u2PN_32_47) \ +{ \ + ((UINT_32)_u4PN_0_31) = (_prHwMacTxDesc)->u4PN1; \ + ((UINT_16)_u2PN_32_47) = (_prHwMacTxDesc)->u2PN2; \ +} +#define HAL_MAC_FALCON_TX_DESC_SET_PN(_prHwMacTxDesc, _u4PN_0_31, _u2PN_32_47) \ +{ \ + (_prHwMacTxDesc)->u4PN1 = ((UINT_32)_u4PN_0_31); \ + (_prHwMacTxDesc)->u2PN2 = ((UINT_16)_u2PN_32_47); \ +} +#endif + +#define HAL_MAC_CONNAC2X_TXD_ASSIGN_PN_BY_SW(_prHwTxD, _u4PN0_31, _u2PN32_47)\ +{ \ + HAL_MAC_TX_DESC_SET_PN(_prHwTxD, _u4PN0_31, _u2PN32_47); \ + HAL_MAC_CONNAC2X_TXD_SET_TXD_PN_VALID(_prHwTxD); \ +} +#define HAL_MAC_CONNAC2X_TXD_ASSIGN_PSN_BY_HW(_prHwMacTxDesc) \ +{ \ + HAL_MAC_TX_DESC_SET_PN(_prHwMacTxDesc, 0, 0); \ + HAL_MAC_CONNAC2X_TXD_SET_TXD_PN_INVALID(_prHwMacTxDesc); \ +} + +#define HAL_MAC_CONNAC2X_TXD_GET_PID(_prHwMacTxDesc) \ +TX_DESC_GET_FIELD((_prHwMacTxDesc)->u2DW5_0, \ +CONNAC2X_TX_DESC_PACKET_ID_MASK, CONNAC2X_TX_DESC_PACKET_ID_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_SET_PID(_prHwMacTxDesc, _ucPID) \ +TX_DESC_SET_FIELD(((_prHwMacTxDesc)->u2DW5_0), ((uint8_t)_ucPID), \ +CONNAC2X_TX_DESC_PACKET_ID_MASK, CONNAC2X_TX_DESC_PACKET_ID_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_GET_TXS_FORMAT(_prHwMacTxDesc) \ +TX_DESC_GET_FIELD((_prHwMacTxDesc)->u2DW5_0, \ +CONNAC2X_TX_DESC_TX_STATUS_FORMAT, CONNAC2X_TX_DESC_TX_STATUS_FORMAT_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_SET_TXS_FORMAT(_prHwMacTxDesc, _ucTXSFormat) \ +TX_DESC_SET_FIELD(((_prHwMacTxDesc)->u2DW5_0), ((uint8_t)_ucTXSFormat), \ +CONNAC2X_TX_DESC_TX_STATUS_FORMAT, CONNAC2X_TX_DESC_TX_STATUS_FORMAT_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_IS_TXS_TO_MCU(_prHwMacTxDesc) \ +(((_prHwMacTxDesc)->u2DW5_0 & CONNAC2X_TX_DESC_TX_STATUS_TO_MCU)?TRUE:FALSE) +#define HAL_MAC_CONNAC2X_TXD_SET_TXS_TO_MCU(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u2DW5_0 |= CONNAC2X_TX_DESC_TX_STATUS_TO_MCU) +#define HAL_MAC_CONNAC2X_TXD_UNSET_TXS_TO_MCU(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u2DW5_0 &= ~CONNAC2X_TX_DESC_TX_STATUS_TO_MCU) + +#define HAL_MAC_CONNAC2X_TXD_IS_TXS_TO_HOST(_prHwMacTxDesc) \ +(((_prHwMacTxDesc)->u2DW5_0 & CONNAC2X_TX_DESC_TX_STATUS_TO_HOST)?TRUE:FALSE) +#define HAL_MAC_CONNAC2X_TXD_SET_TXS_TO_HOST(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u2DW5_0 |= CONNAC2X_TX_DESC_TX_STATUS_TO_HOST) +#define HAL_MAC_CONNAC2X_TXD_UNSET_TXS_TO_HOST(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u2DW5_0 &= ~CONNAC2X_TX_DESC_TX_STATUS_TO_HOST) + +#define HAL_MAC_CONNAC2X_TXD_IS_DA_FROM_WTBL(_prHwMacTxDesc) \ +(((_prHwMacTxDesc)->u2DW5_0 & TX_DESC_DA_SOURCE)?TRUE:FALSE) +#define HAL_MAC_CONNAC2X_TXD_SET_DA_FROM_WTBL(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u2DW5_0 |= TX_DESC_DA_SOURCE) +#define HAL_MAC_CONNAC2X_TXD_SET_DA_FROM_MSDU(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u2DW5_0 &= ~TX_DESC_DA_SOURCE) + +#define HAL_MAC_CONNAC2X_TXD_IS_SW_PM_CONTROL(_prHwMacTxDesc) \ +(((_prHwMacTxDesc)->u4DW3 & CONNAC2X_TX_DESC_POWER_MANAGEMENT_CONTROL) ?\ + TRUE : FALSE) + +#define HAL_MAC_CONNAC2X_TXD_SET_SW_PM_CONTROL(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW3 |= CONNAC2X_TX_DESC_POWER_MANAGEMENT_CONTROL) + +#define HAL_MAC_CONNAC2X_TXD_SET_HW_PM_CONTROL(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW3 &= ~CONNAC2X_TX_DESC_POWER_MANAGEMENT_CONTROL) + +#define HAL_MAC_CONNAC2X_TXD_SET_FR_BW(_prHwMacTxDesc, ucBw) \ +TX_DESC_SET_FIELD(((_prHwMacTxDesc)->u4DW6), ((uint8_t)ucBw), \ +CONNAC2X_TX_DESC_BANDWIDTH_MASK, CONNAC2X_TX_DESC_BANDWIDTH_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_SET_FR_DYNAMIC_BW_RTS(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW6 |= CONNAC2X_TX_DESC_DYNAMIC_BANDWIDTH) + +#define HAL_MAC_CONNAC2X_TXD_SET_FR_ANTENNA_ID(_prHwMacTxDesc, _ucAntId) \ +TX_DESC_SET_FIELD(((_prHwMacTxDesc)->u4DW6), ((uint8_t)_ucAntId), \ +CONNAC2X_TX_DESC_ANTENNA_INDEX_MASK, CONNAC2X_TX_DESC_ANTENNA_INDEX_OFFSET) +#define HAL_MAC_CONNAC2X_TXD_SET_SPE_IDX_SEL(_prHwMacTxDesc, _ucSpeIdxSel) \ +TX_DESC_SET_FIELD(((_prHwMacTxDesc)->u4DW6), ((uint8_t)_ucSpeIdxSel), \ +CONNAC2X_TX_DESC_SPE_IDX_SEL, CONNAC2X_TX_DESC_SPE_IDX_SEL_OFFSET) +#define HAL_MAC_CONNAC2X_TXD_SET_LDPC(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW6 |= CONNAC2X_TX_DESC_LDPC) + +#define HAL_MAC_CONNAC2X_TXD_SET_HE_LTF(_prHwMacTxDesc, _ucHeLtf) \ +TX_DESC_SET_FIELD(((_prHwMacTxDesc)->u4DW6), ((uint8_t)_ucHeLtf), \ +CONNAC2X_TX_DESC_HE_LTF_MASK, CONNAC2X_TX_DESC_HE_LTF_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_GET_HE_LTF(_prHwMacTxDesc) \ +TX_DESC_GET_FIELD(((_prHwMacTxDesc)->u4DW6), \ +CONNAC2X_TX_DESC_HE_LTF_MASK, CONNAC2X_TX_DESC_HE_LTF_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_SET_GI_TYPE(_prHwMacTxDesc, _ucGIType) \ +TX_DESC_SET_FIELD(((_prHwMacTxDesc)->u4DW6), ((uint8_t)_ucGIType), \ +CONNAC2X_TX_DESC_GI_TYPE, CONNAC2X_TX_DESC_GI_TYPE_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_GET_GI_TYPE(_prHwMacTxDesc) \ +TX_DESC_GET_FIELD(((_prHwMacTxDesc)->u4DW6), \ +CONNAC2X_TX_DESC_GI_TYPE, CONNAC2X_TX_DESC_GI_TYPE_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_SET_FR_RATE(_prHwMacTxDesc, _u2RatetoFixed) \ +TX_DESC_SET_FIELD(((_prHwMacTxDesc)->u4DW6), ((uint8_t)_u2RatetoFixed), \ +CONNAC2X_TX_DESC_FIXDE_RATE_MASK, CONNAC2X_TX_DESC_FIXDE_RATE_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_SET_SPE_IDX(_prHwMacTxDesc, _ucSpeIdx) \ +TX_DESC_SET_FIELD(((_prHwMacTxDesc)->u4DW7), ((uint16_t)_ucSpeIdx), \ +CONNAC2X_TX_DESC_SPE_EXT_IDX_MASK, CONNAC2X_TX_DESC_SPE_EXT_IDX_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD_IS_HW_AMSDU(_prHwMacTxDesc) \ +(((_prHwMacTxDesc)->u4DW7 & CONNAC2X_TX_DESC_HW_AMSDU)?TRUE:FALSE) +#define HAL_MAC_CONNAC2X_TXD_SET_HW_AMSDU(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW7 |= CONNAC2X_TX_DESC_HW_AMSDU) +#define HAL_MAC_CONNAC2X_TXD_UNSET_HW_AMSDU(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->u4DW7 &= ~CONNAC2X_TX_DESC_HW_AMSDU) + +#define HAL_MAC_CONNAC2X_TXD7_GET_SUB_TYPE(_prHwMacTxDesc) \ +TX_DESC_GET_FIELD((_prHwMacTxDesc)->u4DW7, \ +CONNAC2X_TX_DESC7_SUB_TYPE_MASK, CONNAC2X_TX_DESC7_SUB_TYPE_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD7_SET_SUB_TYPE(_prHwMacTxDesc, _ucSubType) \ +TX_DESC_SET_FIELD(((_prHwMacTxDesc)->u4DW7), ((uint8_t)_ucSubType), \ +CONNAC2X_TX_DESC7_SUB_TYPE_MASK, CONNAC2X_TX_DESC7_SUB_TYPE_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD7_GET_TYPE(_prHwMacTxDesc) \ +TX_DESC_GET_FIELD((_prHwMacTxDesc)->u4DW7, \ +CONNAC2X_TX_DESC7_TYPE_MASK, CONNAC2X_TX_DESC7_TYPE_OFFSET) + +#define HAL_MAC_CONNAC2X_TXD7_SET_TYPE(_prHwMacTxDesc, _ucType) \ +TX_DESC_SET_FIELD(((_prHwMacTxDesc)->u4DW7), ((uint8_t)_ucType), \ +CONNAC2X_TX_DESC7_TYPE_MASK, CONNAC2X_TX_DESC7_TYPE_OFFSET) + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* CFG_SUPPORT_CONNAC2X == 1 */ +#endif /* _NIC_CONNAC2X_TX_H */ + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/nic_rate.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/nic_rate.h new file mode 100644 index 0000000000000000000000000000000000000000..7fcf4a9b69f9f6687921f3a5ea14ef7f9cbfebf5 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/nic_rate.h @@ -0,0 +1,292 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/ + * MT6620_WIFI_DRIVER_V2_3/include/nic/nic_rate.h#1 + */ + +/*! \file nic_rate.h + * \brief This file contains the rate utility function of + * IEEE 802.11 family for MediaTek 802.11 Wireless LAN Adapters. + */ + + +#ifndef _NIC_RATE_H +#define _NIC_RATE_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +extern char *HW_TX_MODE_STR[]; +extern char *HW_TX_RATE_CCK_STR[]; +extern char *HW_TX_RATE_OFDM_STR[]; +extern char *HW_TX_RATE_BW[]; + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#define BW_20 0 +#define BW_40 1 +#define BW_80 2 +#define BW_160 3 +#define BW_10 4 +#define BW_5 6 +#define BW_8080 7 +#define BW_ALL 0xFF + +#define TX_RATE_MODE_CCK 0 +#define TX_RATE_MODE_OFDM 1 +#define TX_RATE_MODE_HTMIX 2 +#define TX_RATE_MODE_HTGF 3 +#define TX_RATE_MODE_VHT 4 +#define TX_RATE_MODE_PLR 5 +#define TX_RATE_MODE_HE_SU 8 +#define TX_RATE_MODE_HE_ER 9 +#define TX_RATE_MODE_HE_TRIG 10 +#define TX_RATE_MODE_HE_MU 11 + +#define RATE_VER_1 0 /* AC */ +#define RATE_VER_2 1 /* HE */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +enum ENUM_TX_MODE_STR_IDX { + ENUM_TX_MODE_CCK = 0, + ENUM_TX_MODE_OFDM, + ENUM_TX_MODE_MM, + ENUM_TX_MODE_GF, + ENUM_TX_MODE_VHT, +#if (CFG_SUPPORT_802_11AX == 1) + ENUM_TX_MODE_PLR, + ENUM_TX_MODE_HE_SU = 8, + ENUM_TX_MODE_HE_ER, + ENUM_TX_MODE_HE_TRIG, + ENUM_TX_MODE_HE_MU, +#endif + ENUM_TX_MODE_NUM +}; + +struct FIXED_RATE_INFO { + uint32_t u4Mode; + uint32_t u4Bw; + uint32_t u4Mcs; + uint32_t u4VhtNss; + uint32_t u4SGI; + uint32_t u4Preamble; + uint32_t u4STBC; + uint32_t u4LDPC; + uint32_t u4SpeEn; + uint32_t u4HeLTF; + uint32_t u4HeErDCM; + uint32_t u4HeEr106t; +}; + +enum GI_HE { + GI_HE_SGI = 0, + GI_HE_MGI, + GI_HE_LGI, + GI_HE_NUM +}; + +enum HE_LTF { + HE_LTF_1X = 0, + HE_LTF_2X, + HE_LTF_4X +}; + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ +#if (CFG_SUPPORT_CONNAC2X == 1) +#define HW_TX_RATE_TO_MODE(_x) CONNAC2X_HW_TX_RATE_TO_MODE(_x) +#define HW_TX_RATE_TO_NSS(_x) CONNAC2X_HW_TX_RATE_TO_NSS(_x) +#define HW_TX_RATE_TO_STBC(_x) CONNAC2X_HW_TX_RATE_TO_STBC(_x) +#else +#define HW_TX_RATE_TO_MODE(_x) (((_x) & (0x7 << 6)) >> 6) +#define HW_TX_RATE_TO_NSS(_x) (((_x) & (0x3 << 9)) >> 9) +#define HW_TX_RATE_TO_STBC(_x) (((_x) & (0x1 << 11)) >> 11) +#endif +#define HW_TX_RATE_TO_MCS(_x) ((_x) & (0x3f)) + +#if (CFG_SUPPORT_CONNAC2X == 1) +#define TX_VECTOR_GET_TX_RATE(_txv) CONNAC2X_TXV_GET_TX_RATE(_txv) +#define TX_VECTOR_GET_TX_LDPC(_txv) CONNAC2X_TXV_GET_TX_LDPC(_txv) +#define TX_VECTOR_GET_TX_STBC(_txv) CONNAC2X_TXV_GET_TX_STBC(_txv) +#define TX_VECTOR_GET_TX_FRMODE(_txv) CONNAC2X_TXV_GET_TX_FRMODE(_txv) +#define TX_VECTOR_GET_TX_MODE(_txv) CONNAC2X_TXV_GET_TX_MODE(_txv) +#define TX_VECTOR_GET_TX_NSTS(_txv) CONNAC2X_TXV_GET_TX_NSTS(_txv) +#define TX_VECTOR_GET_TX_PWR(_txv) CONNAC2X_TXV_GET_TX_PWR(_txv) +#define TX_VECTOR_GET_TX_SGI(_txv) CONNAC2X_TXV_GET_TX_SGI(_txv) +#else +#define TX_VECTOR_GET_TX_RATE(_txv) (((_txv)->u4TxV[0]) & BITS(0, 6)) +#define TX_VECTOR_GET_TX_LDPC(_txv) ((((_txv)->u4TxV[0]) >> 7) & BIT(0)) +#define TX_VECTOR_GET_TX_STBC(_txv) ((((_txv)->u4TxV[0]) >> 8) & \ + BITS(0, 1)) +#define TX_VECTOR_GET_TX_FRMODE(_txv) ((((_txv)->u4TxV[0]) >> 10) & \ + BITS(0, 1)) +#define TX_VECTOR_GET_TX_MODE(_txv) ((((_txv)->u4TxV[0]) >> 12) & \ + BITS(0, 2)) +#define TX_VECTOR_GET_TX_NSTS(_txv) ((((_txv)->u4TxV[0]) >> 21) & \ + BITS(0, 1)) +#define TX_VECTOR_GET_TX_PWR(_txv) ((((_txv)->u4TxV[0]) >> 24) & \ + BITS(0, 6)) +#define TX_VECTOR_GET_TX_SGI(_txv) ((((_txv)->u4TxV[2]) >> 27) & BIT(0)) +#endif + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +uint32_t +nicGetPhyRateByMcsRate( + IN uint8_t ucIdx, + IN uint8_t ucBw, + IN uint8_t ucGI +); + +uint32_t +nicGetHwRateByPhyRate( + IN uint8_t ucIdx +); + +uint32_t +nicSwIndex2RateIndex( + IN uint8_t ucRateSwIndex, + OUT uint8_t *pucRateIndex, + OUT uint8_t *pucPreambleOption +); + +uint32_t +nicRateIndex2RateCode( + IN uint8_t ucPreambleOption, + IN uint8_t ucRateIndex, + OUT uint16_t *pu2RateCode +); + +uint32_t +nicRateCode2PhyRate( + IN uint16_t u2RateCode, + IN uint8_t ucBandwidth, + IN uint8_t ucGI, + IN uint8_t ucRateNss +); + +uint32_t +nicRateCode2DataRate( + IN uint16_t u2RateCode, + IN uint8_t ucBandwidth, + IN uint8_t ucGI +); + +u_int8_t +nicGetRateIndexFromRateSetWithLimit( + IN uint16_t u2RateSet, + IN uint32_t u4PhyRateLimit, + IN u_int8_t fgGetLowest, + OUT uint8_t *pucRateSwIndex +); + +char *nicHwRateOfdmStr( + uint16_t ofdm_idx); + +uint32_t nicSetFixedRateData( + struct FIXED_RATE_INFO *pFixedRate, + uint32_t *pu4Data); + +uint32_t nicRateHeLtfCheckGi( + struct FIXED_RATE_INFO *pFixedRate); + +uint8_t nicGetTxSgiInfo( + IN struct PARAM_PEER_CAP *prWtblPeerCap, + IN uint8_t u1TxMode); + +uint8_t nicGetTxLdpcInfo( + IN struct PARAM_TX_CONFIG *prWtblTxConfig); + +int32_t nicGetTxRateInfo(IN char *pcCommand, IN int i4TotalLen, + u_int8_t fgDumpAll, + struct PARAM_HW_WLAN_INFO *prHwWlanInfo, + struct PARAM_GET_STA_STATISTICS *prQueryStaStatistics); + +int32_t nicGetRxRateInfo(struct ADAPTER *prAdapter, IN char *pcCommand, + IN int i4TotalLen, IN uint8_t ucWlanIdx); + +uint16_t nicGetStatIdxInfo(IN struct ADAPTER *prAdapter, + IN uint8_t ucWlanIdx); + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#endif /* _NIC_RATE_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/nic_rx.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/nic_rx.h new file mode 100644 index 0000000000000000000000000000000000000000..ea5f109f18365852caed26fea909bc5ee61c1836 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/nic_rx.h @@ -0,0 +1,1531 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/*! \file "nic_rx.h" + * \brief The declaration of the nic rx functions + * + */ + + +#ifndef _NIC_RX_H +#define _NIC_RX_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +#define UNIFIED_MAC_RX_FORMAT 1 + +#define MAX_SEQ_NO 4095 +#define MAX_SEQ_NO_COUNT 4096 +#define HALF_SEQ_NO_CNOUT 2048 + +#define HALF_SEQ_NO_COUNT 2048 +#define QUARTER_SEQ_NO_COUNT 1024 + +#define MT6620_FIXED_WIN_SIZE 64 +#define CFG_RX_MAX_BA_ENTRY 4 +#define CFG_RX_MAX_BA_TID_NUM 8 + +#define RX_STATUS_FLAG_MORE_PACKET BIT(30) +#define RX_STATUS_CHKSUM_MASK BITS(0, 10) + +#define RX_RFB_LEN_FIELD_LEN 4 +#define RX_HEADER_OFFSET 2 + +#define RX_RETURN_INDICATED_RFB_TIMEOUT_SEC 3 + +#define RX_PROCESS_TIMEOUT 1000 + +#if defined(_HIF_SDIO) && defined(WINDOWS_DDK) +/*! On XP, maximum Tx+Rx Statue <= 64-4(HISR)*/ +#define SDIO_MAXIMUM_RX_LEN_NUM 0 /*!< 0~15 (0: un-limited) */ +#else +#define SDIO_MAXIMUM_RX_LEN_NUM 0 /*!< 0~15 (0: un-limited) */ +#endif + +/* RXM Definitions */ +/* The payload format of a RX packet */ +#define RX_PAYLOAD_FORMAT_MSDU 0 +#define RX_PAYLOAD_FORMAT_FIRST_SUB_AMSDU 3 +#define RX_PAYLOAD_FORMAT_MIDDLE_SUB_AMSDU 2 +#define RX_PAYLOAD_FORMAT_LAST_SUB_AMSDU 1 + +/* RX Report Definition */ +/* Unit: DW */ +#define RX_RPT_HDR_LEN 8 +#define RX_RPT_USER_INFO_LEN 12 +#define RX_RPT_BLK_HDR_LEN 2 +#define RX_RPT_BLK_CRXV1_LEN 18 +#define RX_RPT_BLK_PRXV1_LEN 2 +#define RX_RPT_BLK_PRXV2_LEN 4 +#define RX_RPT_BLK_CRXV2_LEN 20 + +/*------------------------------------------------------------------------------ + * Bit fields for RX report + *------------------------------------------------------------------------------ + */ +/* DW0 */ +#define RX_RPT_RX_BYTE_COUNT_MASK BITS(0, 15) +#define RX_RPT_RX_BYTE_COUNT_SHIFT 0 +#define RX_RPT_RXV_MASK BIT(25) +#define RX_RPT_RXV_SHIFT 25 + +/* DW8 */ +#define RX_RPT_RX_WLAN_ID_MASK BITS(22, 31) +#define RX_RPT_RX_WLAN_ID_SHIFT 22 + +/* DW11 */ +#define RX_RPT_RX_DATA_TYPE_MASK BITS(27, 31) +#define RX_RPT_RX_DATA_TYPE_SHIFT 27 + +/* DW12 */ +#define RX_RPT_RX_RATE_MASK BITS(0, 15) + +/* DW20 */ +#define RX_RPT_RXV_PRXV_BYTE_COUNT_MASK BITS(7, 12) +#define RX_RPT_RXV_PRXV_BYTE_COUNT_SHIFT 7 +#define RX_RPT_RXV_TYPE_CRXV1_VLD_MASK BIT(16) +#define RX_RPT_RXV_TYPE_CRXV1_VLD_SHIFT 16 +#define RX_RPT_RXV_TYPE_PRXV1_VLD_MASK BIT(17) +#define RX_RPT_RXV_TYPE_PRXV1_VLD_SHIFT 17 +#define RX_RPT_RXV_TYPE_PRXV2_VLD_MASK BIT(18) +#define RX_RPT_RXV_TYPE_PRXV2_VLD_SHIFT 18 +#define RX_RPT_RXV_TYPE_CRXV2_VLD_MASK BIT(19) +#define RX_RPT_RXV_TYPE_CRXV2_VLD_SHIFT 19 + +/* HAL RX from hal_hw_def_rom.h */ +/*------------------------------------------------------------------------------ + * Cipher define + *------------------------------------------------------------------------------ + */ +#define CIPHER_SUITE_NONE 0 +#define CIPHER_SUITE_WEP40 1 +#define CIPHER_SUITE_TKIP 2 +#define CIPHER_SUITE_TKIP_WO_MIC 3 +#define CIPHER_SUITE_CCMP 4 +#define CIPHER_SUITE_WEP104 5 +#define CIPHER_SUITE_BIP 6 +#define CIPHER_SUITE_WEP128 7 +#define CIPHER_SUITE_WPI 8 +#define CIPHER_SUITE_CCMP_W_CCX 9 +#define CIPHER_SUITE_GCMP 10 + +/*------------------------------------------------------------------------------ + * Bit fields for HW_MAC_RX_DESC_T + *------------------------------------------------------------------------------ + */ + +/*! MAC RX DMA Descriptor */ +/* DW 0*/ +/* Word 0 */ +#define RX_STATUS_RX_BYTE_COUNT_MASK BITS(0, 16) +/* Word 1 */ +#define RX_STATUS_ETH_TYPE_OFFSET_MASK BITS(0, 6) +#define RX_STATUS_ETH_TYPE_OFFSET 0 +#define RX_STATUS_IP_CHKSUM BIT(7) +#define RX_STATUS_UDP_TCP_CHKSUM BIT(8) +#define RX_STATUS_GROUP_VLD_MASK BITS(9, 12) +#define RX_STATUS_GROUP_VLD_OFFSET 9 +#define RX_STATUS_PKT_TYPE_MASK BITS(13, 15) +#define RX_STATUS_PKT_TYPE_OFFSET 13 + +/* DW 1 */ +/* Byte 0 */ +#define RX_STATUS_HTC BIT(0) +#define RX_STATUS_UC2ME BIT(1) +#define RX_STATUS_MC_FRAME BIT(2) +#define RX_STATUS_BC_FRAME BIT(3) +#define RX_STATUS_BCN_WITH_BMC BIT(4) +#define RX_STATUS_BCN_WITH_UC BIT(5) +#define RX_STATUS_KEYID_MASK BITS(6, 7) +#define RX_STATUS_KEYID_OFFSET 6 + +/* Byte 1 */ +#define RX_STATUS_CHAN_FREQ_MASK BITS(0, 7) +/* Byte 2 */ +#define RX_STATUS_HEADER_LEN_MASK BITS(0, 5) +#define RX_STATUS_HEADER_OFFSET BIT(6) +#define RX_STATUS_HEADER_TRAN BIT(7) +/* Byte 3 */ +#define RX_STATUS_PAYLOAD_FORMAT_MASK BITS(0, 1) +#define RX_STATUS_PAYLOAD_FORMAT_OFFSET 0 +#define RX_STATUS_BSSID_MASK BITS(2, 7) +#define RX_STATUS_BSSID_OFFSET 2 + +/* DW 2 */ +/* Byte 1 */ +#define RX_STATUS_TID_MASK BITS(0, 3) +#define RX_STATUS_SEC_MASK BITS(4, 7) +#define RX_STATUS_SEC_OFFSET 4 +/* Byte 2-3 */ +#define RX_STATUS_SW_BIT BIT(0) +#define RX_STATUS_FLAG_FCS_ERROR BIT(1) +#define RX_STATUS_FLAG_CIPHER_MISMATCH BIT(2) +#define RX_STATUS_FLAG_CIPHER_LENGTH_MISMATCH BIT(3) +#define RX_STATUS_FLAG_ICV_ERROR BIT(4) +#define RX_STATUS_FLAG_TKIPMIC_ERROR BIT(5) +#define RX_STATUS_FLAG_LEN_MISMATCH BIT(6) +#define RX_STATUS_FLAG_DE_AMSDU_FAIL BIT(7) +#define RX_STATUS_FLAG_EXCEED_LEN BIT(8) +#define RX_STATUS_LLC_MIS BIT(9) +#define RX_STATUS_UDF_VLT BIT(10) +#define RX_STATUS_FRAG BIT(11) +#define RX_STATUS_NULL BIT(12) +#define RX_STATUS_DATA BIT(13) +#define RX_STATUS_AMPDU_SUB_FRAME BIT(14) +#define RX_STATUS_AMPDU_FORMAT BIT(15) +#define PAYLOAD_FORMAT_IS_MSDU_FRAME 0 +#define RX_STATUS_FLAG_ERROR_MASK \ + (RX_STATUS_FLAG_FCS_ERROR | RX_STATUS_FLAG_ICV_ERROR | \ + RX_STATUS_FLAG_CIPHER_LENGTH_MISMATCH) /* No TKIP MIC error */ + +/* DW 3 */ +#define RX_STATUS_RXV_SEQ_NO_MASK BITS(0, 7) +#define RX_STATUS_TCL BIT(8) +#define RX_STATUS_CLS BIT(11) +#define RX_STATUS_OFLD_MASK BITS(12, 13) +#define RX_STATUS_OFLD_OFFSET 12 +#define RX_STATUS_EAPOL_PACKET BIT(12) +#define RX_STATUS_ARP_NS_PACKET BIT(13) +#define RX_STATUS_TDLS_PACKET BITS(12, 13) +#define RX_STATUS_MGC BIT(14) +#define RX_STATUS_WOL_MASK BITS(15, 19) +#define RX_STATUS_WOL_OFFSET 15 +#define RX_STATUS_CLS_BITMAP_MASK BITS(20, 29) +#define RX_STATUS_CLS_BITMAP_OFFSET 20 +#define RX_STATUS_PF_MODE_BLACK_LIST BIT(30) +#define RX_STATUS_PF_STS_CHECKED BIT(31) + +/* DW 12 */ +#define RX_STATUS_FRAG_NUM_MASK BITS(0, 3) +#define RX_STATUS_SEQ_NUM_MASK BITS(4, 15) +#define RX_STATUS_SEQ_NUM_OFFSET 4 + +#define RX_STATUS_GROUP1_VALID BIT(0) +#define RX_STATUS_GROUP2_VALID BIT(1) +#define RX_STATUS_GROUP3_VALID BIT(2) +#define RX_STATUS_GROUP4_VALID BIT(3) + +#define RX_STATUS_FIXED_LEN 16 + +#define RX_STATUS_CHAN_FREQ_MASK_FOR_BY_PASS_MPDE BITS(0, 7) +#define RX_STATUS_FLAG_FCS_ERROR_FOR_BY_PASS_MODE BIT(16) + +/* Timing Measurement Report */ +/* DW0 Word 1 */ +#define RX_TMR_TOA_VALID BIT(11) +#define RX_TMR_TOD_VALID BIT(10) +#define RX_TMR_TYPE_MASK BITS(8, 9) +#define RX_TMR_TYPE_OFFSET 8 +#define RX_TMR_SUBTYPE_MASK BITS(4, 7) +#define RX_TMR_SUBTYPE_OFFSET 4 + +/* DW0 Byte 1*/ +#define RX_TMR_TM_FAILED BIT(2) +#define RX_TMR_NOISY_CHAN BIT(1) +#define RX_TMR_RESPONDER BIT(0) + +/* TBD */ +#define DMA_OWN_TO_HW BIT(0) +#define DMA_OWN_TO_FW_PENDING BIT(1) +#define STATUS_IS_OWN_TO_FW(flag) \ + (((flag) & DMA_OWN_TO_HW) ? FALSE : TRUE) +#define STATUS_IS_FW_PENDING(flag) \ + (((flag) & DMA_OWN_TO_FW_PENDING) ? TRUE : FALSE) + +/* DW 2 */ +#define RX_STATUS_PACKET_LENGTH_MASK BITS(0, 16) + +#define RX_STATUS_HEADER_TRAN_MASK BIT(7) +#define RX_STATUS_HEADER_TRAN_OFFSET 7 +#define RX_STATUS_HEADER_TRAN_BSS0_MASK BIT(6) +#define RX_STATUS_HEADER_TRAN_BSS0_OFFSET 6 +#define RX_STATUS_HEADER_TRAN_BSS1_MASK BIT(7) +#define RX_STATUS_HEADER_TRAN_BSS1_OFFSET 7 + +/* DW 4 */ +#define RX_STATUS_MATCH_PACKET BIT(4) + +#define RX_STATUS_HEADER_OFFSET_MASK 0xC0 +#define RX_STATUS_HEADER_OFFSET_OFFSET 6 + +/*------------------------------------------------------------------------------ + * Bit fields for HW_RX_VECTOR_DESC_T + *------------------------------------------------------------------------------ + */ +/* DW 2 */ +#define RX_VECTOR_FOR_BA_ACK BIT(7) + +/*! HIF RX DMA Descriptor */ +/* DW 2 */ +#define HIF_RX_DESC_BUFFER_LEN BITS(0, 15) +#define HIF_RX_DESC_ETHER_TYPE_OFFSET_MASK BITS(16, 23) +#define HIF_RX_DESC_ETHER_TYPE_OFFSET_OFFSET 16 +#define HIF_RX_DESC_IP_CHKSUM_CHECK BIT(24) +#define HIF_RX_DESC_TCP_UDP_CHKSUM_CHECK BIT(25) + +#define HIF_RX_DATA_QUEUE 0 +#define HIF_RX_EVENT_QUEUE 1 + +/*------------------------------------------------------------------------------ + * Bit fields for PHY Vector + *------------------------------------------------------------------------------ + */ + +/* RX Vector, 1st Cycle */ +#define RX_VT_RX_RATE_AC_MASK BITS(0, 3) +#define RX_VT_RX_RATE_MASK BITS(0, 6) +#define RX_VT_RX_RATE_OFFSET 0 +#define RX_VT_STBC_MASK BITS(7, 8) +#define RX_VT_STBC_OFFSET 7 +#define RX_VT_LDPC BIT(9) +#define RX_VT_NESS_MASK BITS(10, 11) +#define RX_VT_NESS_OFFSET 10 +#define RX_VT_RX_MODE_MASK BITS(12, 14) +#define RX_VT_RX_MODE_OFFSET 12 +#define RX_VT_RX_MODE_VHT BIT(14) +#define RX_VT_FR_MODE_MASK BITS(15, 16) +#define RX_VT_FR_MODE_OFFSET 15 +#define RX_VT_TXOP_PS_NOT_ALLOWED BIT(17) +#define RX_VT_AGGREGATION BIT(18) +#define RX_VT_SHORT_GI BIT(19) +#define RX_VT_SMOOTH BIT(20) +#define RX_VT_NO_SOUNDING BIT(21) +#define RX_VT_SOUNDING BIT(21) +#if 0 +/* VHT_SIG_A2[B1], not defined in MT6632 */ +#define RX_VT_SHORT_GI_NSYM BIT(22) +/* VHT_SIG_A2[B2:B3], not defined in MT6632 */ +#define RX_VT_CODING_MASK BITS(23, 24) +#define RX_VT_CODING_OFFSET 23 +#endif +#define RX_VT_NUM_RX_MASK BITS(22, 23) +#define RX_VT_NUM_RX_OFFSET 22 +#define RX_VT_LDPC_EXTRA_OFDM_SYM BIT(24) /* VHT_SIG_A2[B3] */ +#define RX_VT_SU_VHT_MU1_3_CODING BITS(25, 28) /* VHT_SIG_A2[B4:B7] */ +#define RX_VT_SU_VHT_MU1_3_CODING_OFFSET 25 +#define RX_VT_BEAMFORMED BIT(29) /* VHT_SIG_A2[B8] */ +#define RX_VT_ACID_DET_LOW BIT(30) +#define RX_VT_ACID_DET_HIGH BIT(31) + +#define RX_VT_RX_RATE_1M 0x0 +#define RX_VT_RX_RATE_2M 0x1 +#define RX_VT_RX_RATE_5M 0x2 +#define RX_VT_RX_RATE_11M 0x3 +#define RX_VT_RX_RATE_6M 0xB +#define RX_VT_RX_RATE_9M 0xF +#define RX_VT_RX_RATE_12M 0xA +#define RX_VT_RX_RATE_18M 0xE +#define RX_VT_RX_RATE_24M 0x9 +#define RX_VT_RX_RATE_36M 0xD +#define RX_VT_RX_RATE_48M 0x8 +#define RX_VT_RX_RATE_54M 0xC + +#define RX_VT_RX_RATE_MCS0 0 +#define RX_VT_RX_RATE_MCS1 1 +#define RX_VT_RX_RATE_MCS2 2 +#define RX_VT_RX_RATE_MCS3 3 +#define RX_VT_RX_RATE_MCS4 4 +#define RX_VT_RX_RATE_MCS5 5 +#define RX_VT_RX_RATE_MCS6 6 +#define RX_VT_RX_RATE_MCS7 7 +#define RX_VT_RX_RATE_MCS32 32 + +#define RX_VT_LEGACY_CCK 0 +#define RX_VT_LEGACY_OFDM 1 +#define RX_VT_MIXED_MODE 2 +#define RX_VT_GREEN_MODE 3 +#define RX_VT_VHT_MODE 4 + +#define RX_VT_LG20_HT20 0 +#define RX_VT_DL40_HT40 1 +#define RX_VT_U20 2 +#define RX_VT_L20 3 + +#define RX_VT_FR_MODE_20 0 +#define RX_VT_FR_MODE_40 1 +#define RX_VT_FR_MODE_80 2 +#define RX_VT_FR_MODE_160 3 /*BW160 or BW80+80*/ + +#define RX_VT_CCK_SHORT_PREAMBLE BIT(2) + +/* RX Vector, 2nd Cycle */ +#define RX_VT_RX_LEN_HT_MASK BITS(0, 15) +#define RX_VT_RX_LEN_LEACY_MASK BITS(0, 11) +#define RX_VT_RX_LEN_VHT_MASK BITS(0, 20) +#define RX_VT_GROUP_ID_MASK BITS(21, 26) +#define RX_VT_GROUP_ID_OFFSET 21 +#define RX_VT_GROUPID_0_MASK BITS(21, 22) /* VHT_SIG_A1[B4:B5] */ +#define RX_VT_GROUPID_0_OFFSET 21 +#define RX_VT_GROUPID_1_MASK BITS(23, 26) /* VHT_SIG_A1[B6:B9] */ +#define RX_VT_GROUPID_1_OFFSET 23 + +#define RX_VT_NSTS_MASK BITS(27, 29) +#define RX_VT_NSTS_OFFSET 27 +#define RX_VT_RX_INDICATOR BIT(30) +#define RX_VT_SEL_ANT BIT(31) /* Not use in MT7615 and MT6632 */ + +/* RX Vector, 3rd Cycle */ +#define RX_VT_PART_AID_MASK BITS(3, 11) +#define RX_VT_PART_AID_OFFSET 3 +#define RX_VT_AID_0_MASK BITS(3, 6) /* VHT_SIG_A1[B13:B16] */ +#define RX_VT_AID_0_OFFSET 3 +#define RX_VT_AID_1_MASK BITS(7, 11) /* VHT_SIG_A1[B17:B21] */ +#define RX_VT_AID_1_OFFSET 7 + + +#define RX_VT_NSTS_PART_AID_MASK BITS(0, 11) +#define RX_VT_NSTS_PART_AID_OFFSET 0 +#define RX_VT_POP_EVER_TRIG BIT(12) +#define RX_VT_FAGC_LNA_RX_MASK BITS(13, 15) +#define RX_VT_FAGC_LNA_RX_OFFSET 13 +#define RX_VT_IB_RSSI_MASK BITS(16, 23) +#define RX_VT_IB_RSSI_OFFSET 16 +#define RX_VT_WB_RSSI_MASK BITS(24, 31) +#define RX_VT_WB_RSSI_OFFSET 24 + +/* RX Vector, 4th Cycle */ +#define RX_VT_RCPI0_MASK BITS(0, 7) +#define RX_VT_RCPI0_OFFSET 0 +#define RX_VT_RCPI1_MASK BITS(8, 15) +#define RX_VT_RCPI1_OFFSET 8 +#define RX_VT_RCPI2_MASK BITS(16, 23) +#define RX_VT_RCPI2_OFFSET 16 +#define RX_VT_RCPI3_MASK BITS(24, 31) +#define RX_VT_RCPI3_OFFSET 24 + +/* RX Vector, 5th Cycle */ +#define RX_VT_FAGC_LNA_GAIN_MASK BITS(0, 2) +#define RX_VT_FAGC_LNA_GAIN_OFFSET 0 +#define RX_VT_FAGC_LPF_GAIN_MASK BITS(3, 6) +#define RX_VT_FAGC_LPF_GAIN_OFFSET 3 +#define RX_VT_OFDM_FOE_MASK BITS(7, 18) +#define RX_VT_OFDM_FOE_OFFSET 7 +#define RX_VT_LTF_PROC_TIME_MASK BITS(19, 25) +#define RX_VT_LTF_PROC_TIME_OFFSET 19 +#define RX_VT_LTF_SNR_MASK BITS(26, 31) +#define RX_VT_LTF_SNR_OFFSET 26 + +/*RX Vector, 6th Cycle*/ +#define RX_VT_NF0_MASK BITS(0, 7) +#define RX_VT_NF0_OFFSET 0 +#define RX_VT_NF1_MASK BITS(8, 15) +#define RX_VT_NF1_OFFSET 8 +#define RX_VT_NF2_MASK BITS(16, 23) +#define RX_VT_NF2_OFFSET 16 +#define RX_VT_NF3_MASK BITS(24, 31) +#define RX_VT_NF3_OFFSET 24 + +/* RX Vector Group 2, the 1st cycle */ +#define RX_VT_PRIM_ITFR_ENV BIT(0) +#define RX_VT_SEC_ITFR_ENV BIT(1) +#define RX_VT_SEC40_ITFR_ENV BIT(2) +#define RX_VT_SEC80_ITFR_ENV BIT(3) +#define RX_VT_OFDM_LQ_BPSK_MASK BITS(4, 10) +#define RX_VT_OFDM_LQ_BPSK_OFFSET 4 +#define RX_VT_OFDM_CAPACITY_LQ_MASK BITS(11, 17) +#define RX_VT_OFDM_CAPACITY_LQ_OFFSET 11 +#define RX_VT_CCK_LQ_MASK BITS(4, 13) +#define RX_VT_CCK_LQ_OFFSET 4 + +/* RX Vector Group 2, the 2nd cycle */ +#define RX_VT_DYNA_BW_IN_NON_HT_DYNA BIT(19) +#define RX_VT_CH_BW_IN_NON_HT_MASK BITS(20, 21) +#define RX_VT_CH_BW_IN_NON_HT_OFFSET 20 + +#define RX_VT_CH_BW_IN_NON_HT_CBW40 BIT(20) +#define RX_VT_CH_BW_IN_NON_HT_CBW80 BIT(21) +#define RX_VT_CH_BW_IN_NON_HT_CBW160 BITS(20, 21) + +/* RX Data Type */ +#define RX_DATA_TYPE_RX_VECTOR 0 +#define RX_DATA_TYPE_RX_DATA 1 +#define RX_DATA_TYPE_RX_EVM 2 +#define RX_DATA_TYPE_RX_AMBI 3 +#define RX_DATA_TYPE_RX_BT 4 + +/*------------------------------------------------------------------------------ + * Radiotap define + *------------------------------------------------------------------------------ + */ + +/*Radiotap VHT*/ +#define RADIOTAP_VHT_ALL_KNOWN BITS(0, 8) +#define RADIOTAP_VHT_STBC_KNOWN BIT(0) +#define RADIOTAP_VHT_TXOP_PS_NOT_ALLOWED_KNOWN BIT(1) +#define RADIOTAP_VHT_GI_KNOWN BIT(2) +#define RADIOTAP_VHT_SHORT_GI_NSYM_KNOWN BIT(3) +#define RADIOTAP_VHT_LDPC_EXTRA_OFDM_SYM_KNOWN BIT(4) +#define RADIOTAP_VHT_BEAMFORMED_KNOWN BIT(5) +#define RADIOTAP_VHT_BAND_WIDTH_KNOWN BIT(6) +#define RADIOTAP_VHT_BAND_GROUP_ID_KNOWN BIT(7) +#define RADIOTAP_VHT_BAND_PARTIAL_AID_KNOWN BIT(8) + +#if CFG_MTK_MCIF_WIFI_SUPPORT +#define NIC_RX_ROOM_SIZE (32 + 32) +#endif + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +enum ENUM_RX_STATISTIC_COUNTER { + RX_MPDU_TOTAL_COUNT = 0, + RX_SIZE_ERR_DROP_COUNT, + + RX_DATA_INDICATION_COUNT, + RX_DATA_RETURNED_COUNT, + RX_DATA_RETAINED_COUNT, + + RX_DATA_REORDER_TOTAL_COUNT, + RX_DATA_REORDER_MISS_COUNT, + RX_DATA_REORDER_WITHIN_COUNT, + RX_DATA_REORDER_AHEAD_COUNT, + RX_DATA_REORDER_BEHIND_COUNT, + + RX_DATA_MSDU_IN_AMSDU_COUNT, + RX_DATA_AMSDU_MISS_COUNT, + RX_DATA_AMSDU_COUNT, + + RX_DROP_TOTAL_COUNT, + + RX_NO_STA_DROP_COUNT, + RX_INACTIVE_BSS_DROP_COUNT, + RX_HS20_DROP_COUNT, + RX_LESS_SW_RFB_DROP_COUNT, + RX_DUPICATE_DROP_COUNT, + RX_MIC_ERROR_DROP_COUNT, + RX_BAR_DROP_COUNT, + RX_NO_INTEREST_DROP_COUNT, + RX_REORDER_BEHIND_DROP_COUNT, + RX_TYPE_ERR_DROP_COUNT, + RX_CLASS_ERR_DROP_COUNT, + RX_DST_NULL_DROP_COUNT, + +#if CFG_TCP_IP_CHKSUM_OFFLOAD || CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60 + RX_CSUM_TCP_FAILED_COUNT, + RX_CSUM_UDP_FAILED_COUNT, + RX_CSUM_IP_FAILED_COUNT, + RX_CSUM_TCP_SUCCESS_COUNT, + RX_CSUM_UDP_SUCCESS_COUNT, + RX_CSUM_IP_SUCCESS_COUNT, + RX_CSUM_UNKNOWN_L4_PKT_COUNT, + RX_CSUM_UNKNOWN_L3_PKT_COUNT, + RX_IP_V6_PKT_CCOUNT, +#endif + RX_STATISTIC_COUNTER_NUM +}; + +enum ENUM_RX_PKT_DESTINATION { + /* to OS */ + RX_PKT_DESTINATION_HOST, + /* to TX queue for forward, AP mode */ + RX_PKT_DESTINATION_FORWARD, + /* to both TX and OS, AP mode broadcast packet */ + RX_PKT_DESTINATION_HOST_WITH_FORWARD, + /* packet to be freed */ + RX_PKT_DESTINATION_NULL, + RX_PKT_DESTINATION_NUM +}; + +/* Used for MAC RX */ +enum ENUM_MAC_RX_PKT_TYPE { + RX_PKT_TYPE_TX_STATUS = 0, + RX_PKT_TYPE_RX_VECTOR, + RX_PKT_TYPE_RX_DATA, + RX_PKT_TYPE_DUP_RFB, + RX_PKT_TYPE_TM_REPORT, + RX_PKT_TYPE_MSDU_REPORT = 6, + RX_PKT_TYPE_SW_DEFINED = 7, + RX_PKT_TYPE_RX_REPORT = 11 +}; + +enum ENUM_MAC_RX_GROUP_VLD { + RX_GROUP_VLD_1 = 0, + RX_GROUP_VLD_2, + RX_GROUP_VLD_3, + RX_GROUP_VLD_4, +#if (CFG_SUPPORT_CONNAC2X == 1) + RX_GROUP_VLD_5, +#endif /* CFG_SUPPORT_CONNAC2X == 1 */ + RX_GROUP_VLD_NUM +}; + +enum ENUM_MAC_GI_INFO { + MAC_GI_NORMAL = 0, + MAC_GI_SHORT +}; + +enum ENUM_RXPI_MODE { + RCPI_MODE_WF0 = 0, + RCPI_MODE_WF1, + RCPI_MODE_WF2, + RCPI_MODE_WF3, + RCPI_MODE_AVG, + RCPI_MODE_MAX, + RCPI_MODE_MIN, + RCPI_MODE_NUM +}; + +#define RXM_RXD_PKT_TYPE_SW_BITMAP 0xE00F +#define RXM_RXD_PKT_TYPE_SW_EVENT 0xE000 +#define RXM_RXD_PKT_TYPE_SW_FRAME 0xE001 + +/* AMPDU data frame with no errors including + * FC/FM/I/T/LM/DAF/EL/LLC-MIS/ UDFVLT and Class 3 error + */ +#define RXS_DW2_AMPDU_nERR_BITMAP 0xFFFB /* ignore CM bit (2) 0xFFFF */ +#define RXS_DW2_AMPDU_nERR_VALUE 0x0000 +/* no error including FC/CLM/I/T/LM/DAF/EL/HTF */ +#define RXS_DW2_RX_nERR_BITMAP 0x03FA /* ignore CM bit (2) 0x03FE */ +#define RXS_DW2_RX_nERR_VALUE 0x0000 +/* Non-Data frames */ +#define RXS_DW2_RX_nDATA_BITMAP 0x3000 +#define RXS_DW2_RX_nDATA_VALUE 0x2000 +/* Claas Error */ +#define RXS_DW2_RX_CLASSERR_BITMAP 0x0001 +#define RXS_DW2_RX_CLASSERR_VALUE 0x0001 +/* Fragmentation */ +#define RXS_DW2_RX_FRAG_BITMAP 0x3800 +#define RXS_DW2_RX_FRAG_VALUE 0x0800 + + +/* TX Free Done Event Definition + * Format version of this tx done event. + * 0: MT7615 + * 1: MT7622, CONNAC (X18/P18/MT7663) + * 2: MT7619_AXE, MT7915 E1, Petrus + * 3: MT7915 E2, Buzzard + */ +enum { + TFD_EVT_VER_0, + TFD_EVT_VER_1, + TFD_EVT_VER_2, + TFD_EVT_VER_3, +}; + +#define RX_TFD_EVT_V3_PAIR_SHIFT 31 +#define RX_TFD_EVT_V3_PAIR_MASK BIT(31) +#define RX_TFD_EVT_V3_QID_SHIFT 24 +#define RX_TFD_EVT_V3_QID_MASK BITS(24, 30) +#define RX_TFD_EVT_V3_WLAN_ID_SHIFT 14 +#define RX_TFD_EVT_V3_WLAN_ID_MASK BITS(14, 23) +#define RX_TFD_EVT_V3_MSDU_ID_SHIFT 16 +#define RX_TFD_EVT_V3_MSDU_ID_MASK BITS(16, 30) + +#define RX_TFD_EVT_V3_GET_PAIR_BIT(_rField) \ + (((_rField) & (RX_TFD_EVT_V3_PAIR_MASK)) >> (RX_TFD_EVT_V3_PAIR_SHIFT)) +#define RX_TFD_EVT_V3_GET_MSDU_ID(_rField) \ + (((_rField) & (RX_TFD_EVT_V3_MSDU_ID_MASK)) \ + >> (RX_TFD_EVT_V3_MSDU_ID_SHIFT)) + + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/*! A data structure which is identical with MAC RX DMA Descriptor */ +struct HW_MAC_RX_DESC { + uint16_t u2RxByteCount; /* DW 0 */ + uint16_t u2PktTYpe; + uint8_t ucMatchPacket; /* DW 1 */ + uint8_t ucChanFreq; + uint8_t ucHeaderLen; + uint8_t ucBssid; + uint8_t ucWlanIdx; /* DW 2 */ + uint8_t ucTidSecMode; + uint16_t u2StatusFlag; + uint32_t u4PatternFilterInfo; /* DW 3 */ + uint32_t u4PatternFilterInfo2; /* DW 4 */ +}; + +struct HW_MAC_RX_STS_GROUP_1 { + uint8_t aucPN[16]; +}; + +struct HW_MAC_RX_STS_GROUP_2 { + uint32_t u4Timestamp; /* DW 12 */ + uint32_t u4CRC; /* DW 13 */ +}; + +struct HW_MAC_RX_STS_GROUP_4 { + /* For HDR_TRAN */ + uint16_t u2FrameCtl; /* DW 4 */ + uint8_t aucTA[6]; /* DW 4~5 */ + uint16_t u2SeqFrag; /* DW 6 */ + uint16_t u2Qos; /* DW 6 */ + uint32_t u4HTC; /* DW 7 */ +}; + +struct HW_MAC_RX_STS_GROUP_3 { + /*! RX Vector Info */ + uint32_t u4RxVector[6]; /* DW 14~19 */ +}; + +#if (CFG_SUPPORT_CONNAC2X == 1) +struct HW_MAC_RX_STS_GROUP_3_V2 { + /* PRXVector Info */ + uint32_t u4RxVector[2]; /* FALCON: DW 16~17 */ +}; + +struct HW_MAC_RX_STS_GROUP_5 { + /* CRXVector Info */ + /* FALCON: DW 18~33 for harrier E1, DW 18~35 for harrier E2 + * Other project: give group5_size in chip info, + * e.g Soc3_0.c +, + * or modify prChipInfo->group5_size when doing wlanCheckAsicCap, + * e.g. Harrier E1 + */ + uint32_t u4RxVector[18]; +}; + +struct HW_MAC_RX_STS_HARRIER_E1_GROUP_5 { + /* CRXVector Info */ + /* FALCON: DW 18~33 for harrier E1, DW 18~35 for harrier E2 */ + uint32_t u4RxVector[16]; +}; + + +#define CONNAC2X_RSSI_MASK BITS(0, 31) +#define CONNAC2X_SEL_ANT BITS(28, 30) +#endif /* CFG_SUPPORT_CONNAC2X == 1 */ + +struct HW_MAC_RX_TMRI_PKT_FORMAT { + uint8_t ucPID; + uint8_t ucStatus; + uint16_t u2PktTYpe; + uint32_t u4Reserved[2]; + uint32_t u4ToA; + uint32_t u4ToD; +}; + +struct HW_MAC_RX_TMRR_PKT_FORMAT { + uint8_t ucVtSeq; + uint8_t ucStatus; + uint16_t u2PktTYpe; + uint8_t aucTALow[2]; + uint16_t u2SnField; + uint8_t aucTAHigh[4]; + uint32_t u4ToA; + uint32_t u4ToD; +}; + +/*! A data structure which is identical with MAC RX Vector DMA Descriptor */ +struct HW_RX_VECTOR_DESC { + uint8_t aucTA[6]; /* DW 0~1 */ + uint8_t ucRxVtSeqNo; + /*! RX Vector Info */ + uint32_t u4RxVector[9]; /* DW 2~10 */ + +}; + +union HW_MAC_MSDU_TOKEN_T { + struct { + uint16_t u2MsduID[2]; + } rFormatV0; + struct { + uint16_t u2MsduID; + uint16_t u2WlanID:10; + uint16_t u2Rsv:1; + uint16_t u2QueIdx:5; + } rFormatV1; + struct { + uint32_t u2MsduID:15; + uint32_t u2WlanID:10; + uint32_t u2QueIdx:7; + } rFormatV2; + union { + struct { + uint32_t u4TxCnt:13; + uint32_t u4Stat:2; + uint32_t u4H:1; + uint32_t u4MsduID:15; + uint32_t u4Pair:1; + } rP0; + struct { + uint32_t u4BW:2; + uint32_t u4Rate:4; + uint32_t u4GI:2; + uint32_t u4TxMode:2; + uint32_t u4Nsts:3; + uint32_t u4DCM:1; + uint32_t u4WlanID:10; + uint32_t u4QID:7; + uint32_t u4Pair:1; + } rP1; + } rFormatV3; +}; + +struct HW_MAC_MSDU_REPORT { + /* DW 0 */ + union { + struct { + uint16_t u2BufByteCount; + uint16_t u2MsduCount:7; + uint16_t u2TxDoneInfo:9; + } field; + + struct { + uint16_t u2BufByteCount; + uint16_t u2MsduCount:10; + uint16_t u2Rsv:1; + uint16_t u2PktType:5; + } field_v3; + + uint32_t word; + } DW0; + + /* DW 1 */ + union { + struct { + uint32_t u4TxdCount:8; + uint32_t u4Rsv1:8; + uint32_t u4Ver:3; + uint32_t u4Rsv2:13; + } field; + + uint32_t word; + } DW1; + + /* DW 2 */ + /* MSDU token array */ + union HW_MAC_MSDU_TOKEN_T au4MsduToken[0]; +}; + +struct SW_RX_RPT_BLK_RXV { + uint32_t u4CRxv1[RX_RPT_BLK_CRXV1_LEN]; + uint32_t u4PRxv1[RX_RPT_BLK_PRXV1_LEN]; + uint32_t u4PRxv2[RX_RPT_BLK_PRXV2_LEN]; + uint32_t u4CRxv2[RX_RPT_BLK_CRXV2_LEN]; +}; + +struct HW_MAC_RX_RPT_BLK { + uint32_t u4Header[RX_RPT_BLK_HDR_LEN]; + uint32_t u4Rxv[0]; +}; + +struct HW_MAC_RX_REPORT { + uint32_t u4Header[RX_RPT_HDR_LEN]; + uint32_t u4UserInfo[RX_RPT_USER_INFO_LEN]; + struct HW_MAC_RX_RPT_BLK rRxvBlk[0]; +}; + +struct SW_RFB { + struct QUE_ENTRY rQueEntry; + void *pvPacket; /*!< ptr to rx Packet Descriptor */ + uint8_t *pucRecvBuff; /*!< ptr to receive data buffer */ + + /* add fot mt6630 */ + uint8_t ucGroupVLD; + uint16_t u2RxStatusOffst; + void *prRxStatus; + struct HW_MAC_RX_STS_GROUP_1 *prRxStatusGroup1; + struct HW_MAC_RX_STS_GROUP_2 *prRxStatusGroup2; + void *prRxStatusGroup3; + struct HW_MAC_RX_STS_GROUP_4 *prRxStatusGroup4; +#if (CFG_SUPPORT_CONNAC2X == 1) + struct HW_MAC_RX_STS_GROUP_5 *prRxStatusGroup5; +#endif /* CFG_SUPPORT_CONNAC2X == 1 */ + + /* rx data information */ + void *pvHeader; + uint16_t u2RxByteCount; + uint16_t u2PacketLen; + uint16_t u2HeaderLen; + + uint8_t *pucPayload; + uint16_t u2PayloadLength; + + struct STA_RECORD *prStaRec; + + uint8_t ucPacketType; + uint8_t ucPayloadFormat; + uint8_t ucSecMode; + uint8_t ucOFLD; + uint8_t ucKeyID; + uint8_t ucChanFreq; + uint8_t ucRxvSeqNo; + uint8_t ucChnlNum; + + /* rx sta record */ + uint8_t ucWlanIdx; + uint8_t ucStaRecIdx; + + u_int8_t fgReorderBuffer; + u_int8_t fgDataFrame; + u_int8_t fgFragFrame; + u_int8_t fgHdrTran; + u_int8_t fgIcvErr; + u_int8_t fgIsBC; + u_int8_t fgIsMC; + u_int8_t fgIsCipherMS; + u_int8_t fgIsCipherLenMS; + u_int8_t fgIsFrag; + u_int8_t fgIsFCS; + u_int8_t fgIsAmpdu; +#if CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION + u_int8_t fgIsFirstSubAMSDULLCMS; +#endif /* CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION */ + /* duplicate detection */ + uint16_t u2FrameCtrl; + uint16_t u2SequenceControl; + uint16_t u2SSN; + uint8_t ucTid; + +#if CFG_TCP_IP_CHKSUM_OFFLOAD + uint32_t u4TcpUdpIpCksStatus; +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ + + enum ENUM_CSUM_RESULT aeCSUM[CSUM_TYPE_NUM]; + enum ENUM_RX_PKT_DESTINATION eDst; + /* only valid when eDst == FORWARD */ + enum ENUM_TRAFFIC_CLASS_INDEX eTC; +#if 0 + /* RX reorder for one MSDU in AMSDU issue */ + /*QUE_T rAmsduQue;*/ +#endif + uint64_t rIntTime; +}; + +#if CFG_TCP_IP_CHKSUM_OFFLOAD +struct RX_CSO_REPORT_T { + uint32_t u4IpV4CksStatus:1; + uint32_t u4Reserved1:1; + uint32_t u4TcpCksStatus:1; + uint32_t u4UdpCksStatus:1; + uint32_t u4IpV4CksType:1; + uint32_t u4IpV6CksType:1; + uint32_t u4TcpCksType:1; + uint32_t u4UdpCksType:1; + uint32_t u4IpDataLenMismatch:1; + uint32_t u4IpFragPkg:1; + uint32_t u4UnknowNextHeader:1; + uint32_t u4Reserved2:21; +}; +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ + +/*! RX configuration type structure */ +struct RX_CTRL { + uint32_t u4RxCachedSize; + uint8_t *pucRxCached; + struct QUE rFreeSwRfbList; + struct QUE rReceivedRfbList; + struct QUE rIndicatedRfbList; + +#if CFG_SDIO_RX_AGG + uint8_t *pucRxCoalescingBufPtr; +#endif + + void *apvIndPacket[CFG_RX_MAX_PKT_NUM]; + void *apvRetainedPacket[CFG_RX_MAX_PKT_NUM]; + + uint8_t ucNumIndPacket; + uint8_t ucNumRetainedPacket; + /*!< RX Counters */ + uint64_t au8Statistics[RX_STATISTIC_COUNTER_NUM]; + +#if CFG_HIF_STATISTICS + uint32_t u4TotalRxAccessNum; + uint32_t u4TotalRxPacketNum; +#endif + +#if CFG_HIF_RX_STARVATION_WARNING + uint32_t u4QueuedCnt; + uint32_t u4DequeuedCnt; +#endif + +#if CFG_RX_PKTS_DUMP + uint32_t u4RxPktsDumpTypeMask; +#endif + +#if CFG_SUPPORT_SNIFFER + uint32_t u4AmpduRefNum; +#endif + + /* Store SysTime of Last Rx */ + uint32_t u4LastRxTime[MAX_BSSID_NUM]; +}; + +struct RX_MAILBOX { + uint32_t u4RxMailbox[2]; /* for Device-to-Host Mailbox */ +}; + +typedef uint32_t(*PROCESS_RX_MGT_FUNCTION) (struct ADAPTER *, struct SW_RFB *); + +typedef void(*PROCESS_RX_EVENT_FUNCTION) (struct ADAPTER *, + struct WIFI_EVENT *); + +struct RX_EVENT_HANDLER { + enum ENUM_EVENT_ID eEID; + PROCESS_RX_EVENT_FUNCTION pfnHandler; +}; + +struct EMU_MAC_RATE_INFO { + uint8_t ucPhyRateCode; + uint32_t u4PhyRate[4][2]; +}; + +struct RX_DESC_OPS_T { + uint16_t (*nic_rxd_get_rx_byte_count)( + void *prRxStatus); + uint8_t (*nic_rxd_get_pkt_type)( + void *prRxStatus); + uint8_t (*nic_rxd_get_wlan_idx)( + void *prRxStatus); + uint8_t (*nic_rxd_get_sec_mode)( + void *prRxStatus); + uint8_t (*nic_rxd_get_sw_class_error_bit)( + void *prRxStatus); + uint8_t (*nic_rxd_get_ch_num)( + void *prRxStatus); + uint8_t (*nic_rxd_get_rf_band)( + void *prRxStatus); + uint8_t (*nic_rxd_get_tcl)( + void *prRxStatus); + uint8_t (*nic_rxd_get_ofld)( + void *prRxStatus); + void (*nic_rxd_fill_rfb)( + struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb); + u_int8_t (*nic_rxd_sanity_check)( + struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb); +#if CFG_SUPPORT_WAKEUP_REASON_DEBUG + void (*nic_rxd_check_wakeup_reason)( + struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb); +#endif /* CFG_SUPPORT_WAKEUP_REASON_DEBUG */ +}; + +struct ACTION_FRAME_SIZE_MAP { + uint16_t u2Index; /* High byte for Action, low byte for Category */ + size_t len; +}; + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ +#define NIC_RX_GET_U2_SW_PKT_TYPE(__rx_status) \ + (uint16_t)((*(uint32_t *)(__rx_status) & (BITS(16, 31))) >> (16)) + +#define RATE_INFO(_RateCode, _Bw20, _Bw20SGI, _Bw40, _BW40SGI, \ + _Bw80, _Bw80SGI, _Bw160, _Bw160SGI) \ + { \ + .ucPhyRateCode = (_RateCode), \ + .u4PhyRate[RX_VT_FR_MODE_20][MAC_GI_NORMAL] = (_Bw20), \ + .u4PhyRate[RX_VT_FR_MODE_20][MAC_GI_SHORT] = (_Bw20SGI), \ + .u4PhyRate[RX_VT_FR_MODE_40][MAC_GI_NORMAL] = (_Bw40), \ + .u4PhyRate[RX_VT_FR_MODE_40][MAC_GI_SHORT] = (_BW40SGI), \ + .u4PhyRate[RX_VT_FR_MODE_80][MAC_GI_NORMAL] = (_Bw80), \ + .u4PhyRate[RX_VT_FR_MODE_80][MAC_GI_SHORT] = (_Bw80SGI), \ + .u4PhyRate[RX_VT_FR_MODE_160][MAC_GI_NORMAL] = (_Bw160), \ + .u4PhyRate[RX_VT_FR_MODE_160][MAC_GI_SHORT] = (_Bw160SGI), \ + } + +#define RX_INC_CNT(prRxCtrl, eCounter) \ + {((struct RX_CTRL *)prRxCtrl)->au8Statistics[eCounter]++; } + +#define RX_ADD_CNT(prRxCtrl, eCounter, u8Amount) \ + {((struct RX_CTRL *)prRxCtrl)->au8Statistics[eCounter] += \ + (uint64_t)u8Amount; } + +#define RX_GET_CNT(prRxCtrl, eCounter) \ + (((struct RX_CTRL *)prRxCtrl)->au8Statistics[eCounter]) + +#define RX_RESET_ALL_CNTS(prRxCtrl) \ + {kalMemZero(&prRxCtrl->au8Statistics[0], \ + sizeof(prRxCtrl->au8Statistics)); } + +#define RX_STATUS_TEST_MORE_FLAG(flag) \ + ((u_int8_t)((flag & RX_STATUS_FLAG_MORE_PACKET) ? TRUE : FALSE)) + +#define RX_STATUS_GET(__RxDescOps, __out_buf, __fn_name, __rx_status) { \ + if (__RxDescOps->nic_rxd_##__fn_name) \ + __out_buf = __RxDescOps->nic_rxd_##__fn_name(__rx_status); \ + else {\ + __out_buf = 0; \ + DBGLOG(RX, ERROR, "%s:: no hook api??\n", \ + __func__); \ + } \ +} \ + +/*------------------------------------------------------------------------------ + * MACRO for RX report + *------------------------------------------------------------------------------ + */ +/* DW0 */ +#define RX_RPT_GET_RX_BYTE_COUNT(_prRxReport) \ + ((((_prRxReport)->u4Header[0]) & \ + RX_RPT_RX_BYTE_COUNT_MASK) >> RX_RPT_RX_BYTE_COUNT_SHIFT) + +#define RX_RPT_GET_RXV_BLK_EXIST(_prRxReport) \ + ((((_prRxReport)->u4Header[0]) & \ + RX_RPT_RXV_MASK) >> RX_RPT_RXV_SHIFT) + +/* DW8 */ +#define RX_RPT_GET_WLAN_ID(_prRxReport) \ + ((((_prRxReport)->u4UserInfo[0]) & \ + RX_RPT_RX_WLAN_ID_MASK) >> RX_RPT_RX_WLAN_ID_SHIFT) + +/* DW11 */ +#define RX_RPT_GET_FRAME_TYPE(_prRxReport) \ + ((((_prRxReport)->u4UserInfo[3]) & \ + RX_RPT_RX_DATA_TYPE_MASK) >> RX_RPT_RX_DATA_TYPE_SHIFT) + +#define RX_RPT_IS_DATA_FRAME(_ucDataType) \ + ((_ucDataType & 0x9) ? TRUE : FALSE) + +/* DW20 */ +#define RX_RPT_GET_RXV_PRXV_BYTE_COUNT(_prRxReport) \ + ((((_prRxReport)->rRxvBlk[0].u4Header[0]) & \ + RX_RPT_RXV_PRXV_BYTE_COUNT_MASK) >> \ + RX_RPT_RXV_PRXV_BYTE_COUNT_SHIFT) + +#define RX_RPT_GET_RXV_TYPE_CRXV1_VLD(_prRxReport) \ + ((((_prRxReport)->rRxvBlk[0].u4Header[0]) & \ + RX_RPT_RXV_TYPE_CRXV1_VLD_MASK) >> \ + RX_RPT_RXV_TYPE_CRXV1_VLD_SHIFT) + +#define RX_RPT_GET_RXV_TYPE_PRXV1_VLD(_prRxReport) \ + ((((_prRxReport)->rRxvBlk[0].u4Header[0]) & \ + RX_RPT_RXV_TYPE_PRXV1_VLD_MASK) >> \ + RX_RPT_RXV_TYPE_PRXV1_VLD_SHIFT) + +#define RX_RPT_GET_RXV_TYPE_PRXV2_VLD(_prRxReport) \ + ((((_prRxReport)->rRxvBlk[0].u4Header[0]) & \ + RX_RPT_RXV_TYPE_PRXV2_VLD_MASK) >> \ + RX_RPT_RXV_TYPE_PRXV2_VLD_SHIFT) + +#define RX_RPT_GET_RXV_TYPE_CRXV2_VLD(_prRxReport) \ + ((((_prRxReport)->rRxvBlk[0].u4Header[0]) & \ + RX_RPT_RXV_TYPE_CRXV2_VLD_MASK) >> \ + RX_RPT_RXV_TYPE_CRXV2_VLD_SHIFT) + +/*------------------------------------------------------------------------------ + * MACRO for HW_MAC_RX_DESC_T + *------------------------------------------------------------------------------ + */ +/* DW 0 */ +#define HAL_RX_STATUS_GET_RX_BYTE_CNT(_prHwMacRxDesc) \ + ((_prHwMacRxDesc)->u2RxByteCount) +#define HAL_RX_STATUS_GET_ETH_TYPE_OFFSET(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->u2PktTYpe & RX_STATUS_ETH_TYPE_OFFSET_MASK) >> \ + RX_STATUS_ETH_TYPE_OFFSET) +#define HAL_RX_STATUS_GET_GROUP_VLD(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->u2PktTYpe & RX_STATUS_GROUP_VLD_MASK) >> \ + RX_STATUS_GROUP_VLD_OFFSET) +#define HAL_RX_STATUS_GET_PKT_TYPE(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->u2PktTYpe & RX_STATUS_PKT_TYPE_MASK) \ + >> RX_STATUS_PKT_TYPE_OFFSET) + +/* DW 1 */ +#define HAL_RX_STATUS_IS_HTC_EXIST(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->ucMatchPacket & RX_STATUS_HTC)?TRUE:FALSE) +#define HAL_RX_STATUS_IS_UC2ME(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->ucMatchPacket & RX_STATUS_UC2ME) \ + ? TRUE : FALSE) +#define HAL_RX_STATUS_IS_MC(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->ucMatchPacket & RX_STATUS_MC_FRAME)?TRUE:FALSE) +#define HAL_RX_STATUS_IS_BC(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->ucMatchPacket & RX_STATUS_BC_FRAME)?TRUE:FALSE) +#define HAL_RX_STATUS_IS_BCN_WITH_BMC(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->ucMatchPacket & RX_STATUS_BCN_WITH_BMC)?TRUE:FALSE) +#define HAL_RX_STATUS_IS_BCN_WITH_UC(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->ucMatchPacket & RX_STATUS_BCN_WITH_UC)?TRUE:FALSE) +#define HAL_RX_STATUS_GET_KEY_ID(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->ucMatchPacket & RX_STATUS_KEYID_MASK) >> \ + RX_STATUS_KEYID_OFFSET) +#define HAL_RX_STATUS_GET_CHAN_FREQ(_prHwMacRxDesc) \ + ((_prHwMacRxDesc)->ucChanFreq) +#define HAL_RX_STATUS_GET_HEADER_LEN(_prHwMacRxDesc) \ + ((_prHwMacRxDesc)->ucHeaderLen & RX_STATUS_HEADER_LEN_MASK) +#define HAL_RX_STATUS_IS_HEADER_OFFSET(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->ucHeaderLen & RX_STATUS_HEADER_OFFSET)?TRUE:FALSE) +#define HAL_RX_STATUS_GET_HEADER_OFFSET(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->ucHeaderLen & RX_STATUS_HEADER_OFFSET) ? 2 : 0) +#define HAL_RX_STATUS_IS_HEADER_TRAN(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->ucHeaderLen & RX_STATUS_HEADER_TRAN)?TRUE:FALSE) +#define HAL_RX_STATUS_GET_HEADER_TRAN(_prHwMacRxDesc) \ + HAL_RX_STATUS_IS_HEADER_TRAN(_prHwMacRxDesc) +#define HAL_RX_STATUS_GET_PAYLOAD_FORMAT(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->ucBssid & RX_STATUS_PAYLOAD_FORMAT_MASK) >> \ + RX_STATUS_PAYLOAD_FORMAT_OFFSET) +#define HAL_RX_STATUS_GET_BSSID(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->ucBssid & RX_STATUS_BSSID_MASK) >> \ + RX_STATUS_BSSID_OFFSET) + +/* DW 2 */ +#define HAL_RX_STATUS_GET_WLAN_IDX(_prHwMacRxDesc) \ + ((_prHwMacRxDesc)->ucWlanIdx) +#define HAL_RX_STATUS_GET_TID(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->ucTidSecMode & RX_STATUS_TID_MASK)) +#define HAL_RX_STATUS_GET_SEC_MODE(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->ucTidSecMode & RX_STATUS_SEC_MASK) >> \ + RX_STATUS_SEC_OFFSET) +#define HAL_RX_STATUS_GET_SW_BIT(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->u2StatusFlag & RX_STATUS_SW_BIT)?TRUE:FALSE) +#define HAL_RX_STATUS_IS_FCS_ERROR(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->u2StatusFlag & RX_STATUS_FLAG_FCS_ERROR)?TRUE:FALSE) +#define HAL_RX_STATUS_IS_CIPHER_MISMATCH(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->u2StatusFlag & RX_STATUS_FLAG_CIPHER_MISMATCH) \ + ? TRUE : FALSE) +#define HAL_RX_STATUS_IS_CLM_ERROR(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->u2StatusFlag & \ + RX_STATUS_FLAG_CIPHER_LENGTH_MISMATCH) \ + ? TRUE : FALSE) +#define HAL_RX_STATUS_IS_ICV_ERROR(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->u2StatusFlag & RX_STATUS_FLAG_ICV_ERROR)?TRUE:FALSE) +#define HAL_RX_STATUS_IS_TKIP_MIC_ERROR(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->u2StatusFlag & RX_STATUS_FLAG_TKIPMIC_ERROR) > 0 \ + ? TRUE : FALSE) +#define HAL_RX_STATUS_IS_ERROR(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->u2StatusFlag & RX_STATUS_FLAG_ERROR_MASK) \ + ? TRUE : FALSE) +#define HAL_RX_STATUS_IS_LEN_MISMATCH(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->u2StatusFlag & RX_STATUS_FLAG_LEN_MISMATCH) \ + ? TRUE : FALSE) +#define HAL_RX_STATUS_IS_DE_AMSDU_FAIL(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->u2StatusFlag & RX_STATUS_FLAG_DE_AMSDU_FAIL) \ + ? TRUE : FALSE) +#define HAL_RX_STATUS_IS_EXCEED_LEN(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->u2StatusFlag & RX_STATUS_FLAG_EXCEED_LEN) \ + ? TRUE : FALSE) +#define HAL_RX_STATUS_IS_LLC_MIS(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->u2StatusFlag & RX_STATUS_LLC_MIS)?TRUE:FALSE) +#define HAL_RX_STATUS_IS_UDF_VLT(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->u2StatusFlag & RX_STATUS_UDF_VLT)?TRUE:FALSE) +#define HAL_RX_STATUS_IS_FRAG(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->u2StatusFlag & RX_STATUS_FRAG)?TRUE:FALSE) +#define HAL_RX_STATUS_IS_NULL(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->u2StatusFlag & RX_STATUS_NULL)?TRUE:FALSE) +#define HAL_RX_STATUS_IS_DATA(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->u2StatusFlag & RX_STATUS_DATA)?FALSE:TRUE) +#define HAL_RX_STATUS_IS_AMPDU_SUB_FRAME(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->u2StatusFlag & RX_STATUS_AMPDU_SUB_FRAME) \ + ? FALSE : TRUE) +#define HAL_RX_STATUS_IS_AMPDU_FORMAT(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->u2StatusFlag & RX_STATUS_AMPDU_FORMAT)?FALSE:TRUE) + +/* DW 3 */ +#define HAL_RX_STATUS_IS_RV_VALID(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->u4PatternFilterInfo & RX_STATUS_RXV_SEQ_NO_MASK) \ + ? TRUE : FALSE) +#define HAL_RX_STATUS_GET_RXV_SEQ_NO(_prHwMacRxDesc) \ + ((_prHwMacRxDesc)->u4PatternFilterInfo & RX_STATUS_RXV_SEQ_NO_MASK) +#define HAL_RX_STATUS_GET_TCL(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->u4PatternFilterInfo & RX_STATUS_TCL)?TRUE:FALSE) +#define HAL_RX_STATUS_IS_CLS(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->u4PatternFilterInfo & RX_STATUS_CLS)?TRUE:FALSE) +#define HAL_RX_STATUS_GET_OFLD(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->u4PatternFilterInfo & RX_STATUS_OFLD_MASK) >> \ + RX_STATUS_OFLD_OFFSET) +#define HAL_RX_STATUS_IS_MGC(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->u4PatternFilterInfo & RX_STATUS_MGC)?TRUE:FALSE) +#define HAL_RX_STATUS_GET_WOL(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->u4PatternFilterInfo & RX_STATUS_WOL_MASK) >> \ + RX_STATUS_WOL_OFFSET) +#define HAL_RX_STATUS_GET_CLS_BITMAP(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->u4PatternFilterInfo & RX_STATUS_CLS_BITMAP_MASK) \ + >> RX_STATUS_CLS_BITMAP_OFFSET) +#define HAL_RX_STATUS_IS_PF_BLACK_LIST(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->u4PatternFilterInfo \ + & RX_STATUS_PF_MODE_BLACK_LIST) ? TRUE : FALSE) +#define HAL_RX_STATUS_IS_PF_CHECKED(_prHwMacRxDesc) \ + (((_prHwMacRxDesc)->u4PatternFilterInfo & RX_STATUS_PF_STS_CHECKED) \ + ? TRUE : FALSE) + +/* DW 4~7 */ +#define HAL_RX_STATUS_GET_FRAME_CTL_FIELD(_prHwMacRxStsGroup4) \ + ((_prHwMacRxStsGroup4)->u2FrameCtl) +#define HAL_RX_STATUS_GET_TA(_prHwMacRxStsGroup4, pucTA) \ +{\ + kalMemCopy(pucTA, &(_prHwMacRxStsGroup4)->aucTA[0], 6); \ +} +#define HAL_RX_STATUS_GET_SEQ_FRAG_NUM(_prHwMacRxStsGroup4) \ + ((_prHwMacRxStsGroup4)->u2SeqFrag) +#define HAL_RX_STATUS_GET_QOS_CTL_FIELD(_prHwMacRxStsGroup4) \ + ((_prHwMacRxStsGroup4)->u2Qos) + +#define HAL_RX_STATUS_GET_SEQFrag_NUM(_prHwMacRxStsGroup4) \ + ((_prHwMacRxStsGroup4)->u2SeqFrag) +#define HAL_RX_STATUS_GET_HTC(_prHwMacRxStsGroup4) \ + ((_prHwMacRxStsGroup4)->u4HTC) + +/* DW 8~11 */ +#define HAL_RX_STATUS_GET_RSC(_prHwMacRxStsGroup1, pucRSC) \ +{\ + kalMemCopy(pucRSC, &(_prHwMacRxStsGroup1)->aucPN[0], 6); \ +} + +#define HAL_RX_STATUS_GET_PN(_prHwMacRxStsGroup1, pucPN) \ +{\ + kalMemCopy(pucPN, &(_prHwMacRxStsGroup1)->aucPN[0], 16); \ +} + +/* DW 12~13 */ +#define HAL_RX_STATUS_GET_TIMESTAMP(_prHwMacRxStsGroup2, _ucIdx) \ + ((_prHwMacRxStsGroup2)->u4Timestamp) +#define HAL_RX_STATUS_GET_FCS32(_prHwMacRxStsGroup2) \ + ((_prHwMacRxStsGroup2)->u4CRC) + +/* DW 14~19 */ +#define HAL_RX_STATUS_GET_RX_VECTOR(_prHwMacRxStsGroup3, _ucIdx) \ + ((_prHwMacRxStsGroup3)->u4RxVector[_ucIdx]) + +#define HAL_RX_STATUS_GET_RX_NUM(_prHwMacRxStsGroup3) \ + (((_prHwMacRxStsGroup3)->u4RxVector[0] & RX_VT_NUM_RX_MASK) >> \ + RX_VT_NUM_RX_OFFSET) + +#if (CFG_SUPPORT_CONNAC2X == 1) +#define HAL_RX_STATUS_GET_RCPI0(_prHwMacRxStsGroup3) \ + (((_prHwMacRxStsGroup3)->u4RxVector[1] & RX_VT_RCPI0_MASK) >> \ + RX_VT_RCPI0_OFFSET) +#define HAL_RX_STATUS_GET_RCPI1(_prHwMacRxStsGroup3) \ + (((_prHwMacRxStsGroup3)->u4RxVector[1] & RX_VT_RCPI1_MASK) >> \ + RX_VT_RCPI1_OFFSET) +#define HAL_RX_STATUS_GET_RCPI2(_prHwMacRxStsGroup3) \ + (((_prHwMacRxStsGroup3)->u4RxVector[1] & RX_VT_RCPI2_MASK) >> \ + RX_VT_RCPI0_OFFSET) +#define HAL_RX_STATUS_GET_RCPI3(_prHwMacRxStsGroup3) \ + (((_prHwMacRxStsGroup3)->u4RxVector[1] & RX_VT_RCPI3_MASK) >> \ + RX_VT_RCPI1_OFFSET) +#else +#define HAL_RX_STATUS_GET_RCPI0(_prHwMacRxStsGroup3) \ + (((_prHwMacRxStsGroup3)->u4RxVector[3] & RX_VT_RCPI0_MASK) >> \ + RX_VT_RCPI0_OFFSET) +#define HAL_RX_STATUS_GET_RCPI1(_prHwMacRxStsGroup3) \ + (((_prHwMacRxStsGroup3)->u4RxVector[3] & RX_VT_RCPI1_MASK) >> \ + RX_VT_RCPI1_OFFSET) +#endif + +/* TBD */ +#define HAL_RX_STATUS_GET_RX_PACKET_LEN(_prHwMacRxDesc) +#define HAL_RX_STATUS_IS_MATCH_PACKET(_prHwMacRxDesc) + +#define HAL_RX_STATUS_GET_CHNL_NUM(_prHwMacRxDesc) \ + ((((_prHwMacRxDesc)->ucChanFreq) > HW_CHNL_NUM_MAX_4G_5G) ? \ + (((_prHwMacRxDesc)->ucChanFreq) - HW_CHNL_NUM_MAX_4G_5G) : \ + ((_prHwMacRxDesc)->ucChanFreq)) + +/* To do: support more bands other than 2.4G and 5G */ +#define HAL_RX_STATUS_GET_RF_BAND(_prHwMacRxDesc) \ + ((((_prHwMacRxDesc)->ucChanFreq) <= HW_CHNL_NUM_MAX_2G4) ? \ + BAND_2G4 : BAND_5G) + +/*------------------------------------------------------------------------------ + * MACRO for HW_RX_VECTOR_DESC_T + *------------------------------------------------------------------------------ + */ +#define HAL_RX_VECTOR_GET_TA(_prHwRxVector, pucTA) \ +{\ + kalMemCopy(pucTA, &(_prHwRxVector)->aucTA[0], 6); \ +} + +#define HAL_RX_VECTOR_GET_SEQ_NO(_prHwRxVector) \ + ((_prHwRxVector)->ucRxVtSeqNo & RX_STATUS_RXV_SEQ_NO_MASK) +#define HAL_RX_VECTOR_IS_FOR_BA_ACK(_prHwRxVector) \ + (((_prHwRxVector)->ucRxVtSeqNo & RX_VECTOR_FOR_BA_ACK)?TRUE:FALSE) +#define HAL_RX_VECTOR_GET_RX_VECTOR(_prHwRxVector, _ucIdx) \ + ((_prHwRxVector)->u4RxVector[_ucIdx]) + +#define RXM_IS_QOS_DATA_FRAME(_u2FrameCtrl) \ + (((_u2FrameCtrl & MASK_FRAME_TYPE) == MAC_FRAME_QOS_DATA) \ + ? TRUE : FALSE) + +#define RXM_IS_DATA_FRAME(_u2FrameCtrl) \ + (((_u2FrameCtrl & MASK_FC_TYPE) == MAC_FRAME_TYPE_DATA) ? TRUE : FALSE) + +#define RXM_IS_CTRL_FRAME(_u2FrameCtrl) \ + (((_u2FrameCtrl & MASK_FC_TYPE) == MAC_FRAME_TYPE_CTRL) ? TRUE : FALSE) + +#define RXM_IS_TRIGGER_FRAME(_u2FrameCtrl) \ + (((_u2FrameCtrl & MASK_FRAME_TYPE) == MAC_FRAME_HE_TRIGGER) ?\ + TRUE : FALSE) + +#define RXM_IS_BLOCK_ACK_FRAME(_u2FrameCtrl) \ + (((_u2FrameCtrl & MASK_FRAME_TYPE) == MAC_FRAME_BLOCK_ACK) ?\ + TRUE : FALSE) + +#define RXM_IS_MGMT_FRAME(_u2FrameCtrl) \ + (((_u2FrameCtrl & MASK_FC_TYPE) == MAC_FRAME_TYPE_MGT) ? TRUE : FALSE) + +#define RXM_IS_PROTECTED_FRAME(_u2FrameCtrl) \ + ((_u2FrameCtrl & MASK_FC_PROTECTED_FRAME) ? TRUE : FALSE) + +#define RXM_IS_TO_DS(_u2FrameCtrl) \ + (((_u2FrameCtrl & MASK_TO_DS_FROM_DS) == MASK_FC_TO_DS) ?\ + TRUE : FALSE) + +#define RXM_IS_FROM_DS(_u2FrameCtrl) \ + (((_u2FrameCtrl & MASK_TO_DS_FROM_DS) == MASK_FC_FROM_DS) ?\ + TRUE : FALSE) + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +void nicRxInitialize(IN struct ADAPTER *prAdapter); + +void nicRxUninitialize(IN struct ADAPTER *prAdapter); + +void nicRxProcessRFBs(IN struct ADAPTER *prAdapter); + +void nicRxProcessMsduReport(IN struct ADAPTER *prAdapter, + IN OUT struct SW_RFB *prSwRfb); + +void nicRxProcessRxReport(IN struct ADAPTER *prAdapter, + IN OUT struct SW_RFB *prSwRfb); + +uint32_t nicRxSetupRFB(IN struct ADAPTER *prAdapter, IN struct SW_RFB *prRfb); + +void nicRxReturnRFB(IN struct ADAPTER *prAdapter, IN struct SW_RFB *prRfb); + +void nicProcessRxInterrupt(IN struct ADAPTER *prAdapter); + +void nicRxProcessPktWithoutReorder(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb); + +u_int8_t nicRxCheckForwardPktResource( + IN struct ADAPTER *prAdapter, uint32_t ucTid); + +void nicRxProcessForwardPkt(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb); + +void nicRxProcessGOBroadcastPkt(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb); + +void nicRxFillRFB(IN struct ADAPTER *prAdapter, + IN OUT struct SW_RFB *prSwRfb); + +void nicRxClearFrag(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec); + +struct SW_RFB *nicRxDefragMPDU(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSWRfb, OUT struct QUE *prReturnedQue); + +u_int8_t nicRxIsDuplicateFrame(IN OUT struct SW_RFB *prSwRfb); + +void nicRxProcessMonitorPacket(IN struct ADAPTER *prAdapter, + IN OUT struct SW_RFB *prSwRfb); +#if CFG_SUPPORT_PERF_IND +void nicRxPerfIndProcessRXV(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, + IN uint8_t ucBssIndex); +#endif + +void nicRxProcessDataPacket(IN struct ADAPTER *prAdapter, + IN OUT struct SW_RFB *prSwRfb); + +void nicRxProcessEventPacket(IN struct ADAPTER *prAdapter, + IN OUT struct SW_RFB *prSwRfb); + +void nicRxProcessMgmtPacket(IN struct ADAPTER *prAdapter, + IN OUT struct SW_RFB *prSwRfb); + +#if CFG_TCP_IP_CHKSUM_OFFLOAD +void nicRxFillChksumStatus(IN struct ADAPTER *prAdapter, + IN OUT struct SW_RFB *prSwRfb); + +void nicRxUpdateCSUMStatistics(IN struct ADAPTER *prAdapter, + IN const enum ENUM_CSUM_RESULT aeCSUM[]); +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ + +void nicRxQueryStatus(IN struct ADAPTER *prAdapter, + IN uint8_t *pucBuffer, OUT uint32_t *pu4Count); + +void nicRxClearStatistics(IN struct ADAPTER *prAdapter); + +void nicRxQueryStatistics(IN struct ADAPTER *prAdapter, + IN uint8_t *pucBuffer, OUT uint32_t *pu4Count); + +uint32_t nicRxWaitResponse(IN struct ADAPTER *prAdapter, + IN uint8_t ucPortIdx, OUT uint8_t *pucRspBuffer, + IN uint32_t u4MaxRespBufferLen, OUT uint32_t *pu4Length); + +void nicRxEnablePromiscuousMode(IN struct ADAPTER *prAdapter); + +void nicRxDisablePromiscuousMode(IN struct ADAPTER *prAdapter); + +uint32_t nicRxFlush(IN struct ADAPTER *prAdapter); + +uint32_t nicRxProcessActionFrame(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb); + +uint8_t nicRxGetRcpiValueFromRxv( + IN struct ADAPTER *prAdapter, + IN uint8_t ucRcpiMode, + IN struct SW_RFB *prSwRfb); + +int32_t nicRxGetLastRxRssi(struct ADAPTER *prAdapter, IN char *pcCommand, + IN int i4TotalLen, IN uint8_t ucWlanIdx); + +#endif /* _NIC_RX_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/nic_rxd_v1.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/nic_rxd_v1.h new file mode 100644 index 0000000000000000000000000000000000000000..29e60db5206669f3c6c420a1c9ad7fe4b5ec1731 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/nic_rxd_v1.h @@ -0,0 +1,110 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/ + * MT6620_WIFI_DRIVER_V2_3/include/nic/nic_tx.h#1 + */ + +/*! \file nic_tx.h + * \brief Functions that provide TX operation in NIC's point of view. + * + * This file provides TX functions which are responsible for both Hardware + * and Software Resource Management and keep their Synchronization. + * + */ + + +#ifndef _NIC_RXD_V1_H +#define _NIC_RXD_V1_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +uint16_t nic_rxd_v1_get_rx_byte_count( + void *prRxStatus); +uint8_t nic_rxd_v1_get_packet_type( + void *prRxStatus); +uint8_t nic_rxd_v1_get_wlan_idx( + void *prRxStatus); +uint8_t nic_rxd_v1_get_sec_mode( + void *prRxStatus); +uint8_t nic_rxd_v1_get_sw_class_error_bit( + void *prRxStatus); +uint8_t nic_rxd_v1_get_ch_num( + void *prRxStatus); +uint8_t nic_rxd_v1_get_rf_band( + void *prRxStatus); +uint8_t nic_rxd_v1_get_tcl( + void *prRxStatus); +uint8_t nic_rxd_v1_get_ofld( + void *prRxStatus); +void nic_rxd_v1_fill_rfb( + struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb); +u_int8_t nic_rxd_v1_sanity_check( + struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb); + +#if CFG_SUPPORT_WAKEUP_REASON_DEBUG +void nic_rxd_v1_check_wakeup_reason( + struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb); +#endif /* CFG_SUPPORT_WAKEUP_REASON_DEBUG */ + +#endif /* _NIC_RXD_V1_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/nic_rxd_v2.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/nic_rxd_v2.h new file mode 100644 index 0000000000000000000000000000000000000000..cfd02d9f65caf7e7a239f09f8ea987e01f6647ba --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/nic_rxd_v2.h @@ -0,0 +1,112 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/ + * MT6620_WIFI_DRIVER_V2_3/include/nic/nic_tx.h#1 + */ + +/*! \file nic_tx.h + * \brief Functions that provide TX operation in NIC's point of view. + * + * This file provides TX functions which are responsible for both Hardware + * and Software Resource Management and keep their Synchronization. + * + */ + + +#ifndef _NIC_RXD_V2_H +#define _NIC_RXD_V2_H + +#if (CFG_SUPPORT_CONNAC2X == 1) +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +uint16_t nic_rxd_v2_get_rx_byte_count( + void *prRxStatus); +uint8_t nic_rxd_v2_get_packet_type( + void *prRxStatus); +uint8_t nic_rxd_v2_get_wlan_idx( + void *prRxStatus); +uint8_t nic_rxd_v2_get_sec_mode( + void *prRxStatus); +uint8_t nic_rxd_v2_get_sw_class_error_bit( + void *prRxStatus); +uint8_t nic_rxd_v2_get_ch_num( + void *prRxStatus); +uint8_t nic_rxd_v2_get_rf_band( + void *prRxStatus); +uint8_t nic_rxd_v2_get_tcl( + void *prRxStatus); +uint8_t nic_rxd_v2_get_ofld( + void *prRxStatus); +void nic_rxd_v2_fill_rfb( + struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb); +u_int8_t nic_rxd_v2_sanity_check( + struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb); + +#if CFG_SUPPORT_WAKEUP_REASON_DEBUG +void nic_rxd_v2_check_wakeup_reason( + struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb); +#endif /* CFG_SUPPORT_WAKEUP_REASON_DEBUG */ + +#endif /* CFG_SUPPORT_CONNAC2X == 1 */ +#endif /* _NIC_RXD_V2_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/nic_tx.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/nic_tx.h new file mode 100644 index 0000000000000000000000000000000000000000..53fc86899b38999cf651eeeaf0c56ad8a8275aa0 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/nic_tx.h @@ -0,0 +1,2038 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/ + * MT6620_WIFI_DRIVER_V2_3/include/nic/nic_tx.h#1 + */ + +/*! \file nic_tx.h + * \brief Functions that provide TX operation in NIC's point of view. + * + * This file provides TX functions which are responsible for both Hardware + * and Software Resource Management and keep their Synchronization. + * + */ + + +#ifndef _NIC_TX_H +#define _NIC_TX_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +#define UNIFIED_MAC_TX_FORMAT 1 + +#define MAC_TX_RESERVED_FIELD 0 + +#define NIC_TX_RESOURCE_POLLING_TIMEOUT 256 +#define NIC_TX_RESOURCE_POLLING_DELAY_MSEC 5 + +#define NIC_TX_CMD_INFO_RESERVED_COUNT 4 + +/* Maximum buffer count for individual HIF TCQ */ +#define NIC_TX_PAGE_COUNT_TC0 \ + (NIC_TX_BUFF_COUNT_TC0 * nicTxGetMaxPageCntPerFrame(prAdapter)) +#define NIC_TX_PAGE_COUNT_TC1 \ + (NIC_TX_BUFF_COUNT_TC1 * nicTxGetMaxPageCntPerFrame(prAdapter)) +#define NIC_TX_PAGE_COUNT_TC2 \ + (NIC_TX_BUFF_COUNT_TC2 * nicTxGetMaxPageCntPerFrame(prAdapter)) +#define NIC_TX_PAGE_COUNT_TC3 \ + (NIC_TX_BUFF_COUNT_TC3 * nicTxGetMaxPageCntPerFrame(prAdapter)) +#define NIC_TX_PAGE_COUNT_TC4 \ + (NIC_TX_BUFF_COUNT_TC4 * nicTxGetMaxPageCntPerFrame(prAdapter)) +#define NIC_TX_PAGE_COUNT_TC5 \ + (NIC_TX_BUFF_COUNT_TC5 * nicTxGetMaxPageCntPerFrame(prAdapter)) + +#define NIC_TX_BUFF_COUNT_TC0 HIF_TX_BUFF_COUNT_TC0 +#define NIC_TX_BUFF_COUNT_TC1 HIF_TX_BUFF_COUNT_TC1 +#define NIC_TX_BUFF_COUNT_TC2 HIF_TX_BUFF_COUNT_TC2 +#define NIC_TX_BUFF_COUNT_TC3 HIF_TX_BUFF_COUNT_TC3 +#define NIC_TX_BUFF_COUNT_TC4 HIF_TX_BUFF_COUNT_TC4 +#define NIC_TX_BUFF_COUNT_TC5 HIF_TX_BUFF_COUNT_TC5 + +#define NIC_TX_RESOURCE_CTRL \ + HIF_TX_RESOURCE_CTRL /* to enable/disable TX resource control */ +#define NIC_TX_RESOURCE_CTRL_PLE \ + HIF_TX_RESOURCE_CTRL_PLE /* to enable/disable TX resource control */ + + +#if CFG_ENABLE_FW_DOWNLOAD + +#define NIC_TX_INIT_BUFF_COUNT_TC0 8 +#define NIC_TX_INIT_BUFF_COUNT_TC1 0 +#define NIC_TX_INIT_BUFF_COUNT_TC2 0 +#define NIC_TX_INIT_BUFF_COUNT_TC3 0 +#define NIC_TX_INIT_BUFF_COUNT_TC4 8 +#define NIC_TX_INIT_BUFF_COUNT_TC5 0 + +#define NIC_TX_INIT_BUFF_SUM (NIC_TX_INIT_BUFF_COUNT_TC0 + \ + NIC_TX_INIT_BUFF_COUNT_TC1 + \ + NIC_TX_INIT_BUFF_COUNT_TC2 + \ + NIC_TX_INIT_BUFF_COUNT_TC3 + \ + NIC_TX_INIT_BUFF_COUNT_TC4 + \ + NIC_TX_INIT_BUFF_COUNT_TC5) + +#define NIC_TX_INIT_PAGE_COUNT_TC0 \ + (NIC_TX_INIT_BUFF_COUNT_TC0 * nicTxGetMaxPageCntPerFrame(prAdapter)) +#define NIC_TX_INIT_PAGE_COUNT_TC1 \ + (NIC_TX_INIT_BUFF_COUNT_TC1 * nicTxGetMaxPageCntPerFrame(prAdapter)) +#define NIC_TX_INIT_PAGE_COUNT_TC2 \ + (NIC_TX_INIT_BUFF_COUNT_TC2 * nicTxGetMaxPageCntPerFrame(prAdapter)) +#define NIC_TX_INIT_PAGE_COUNT_TC3 \ + (NIC_TX_INIT_BUFF_COUNT_TC3 * nicTxGetMaxPageCntPerFrame(prAdapter)) +#define NIC_TX_INIT_PAGE_COUNT_TC4 \ + (NIC_TX_INIT_BUFF_COUNT_TC4 * nicTxGetMaxPageCntPerFrame(prAdapter)) +#define NIC_TX_INIT_PAGE_COUNT_TC5 \ + (NIC_TX_INIT_BUFF_COUNT_TC5 * nicTxGetMaxPageCntPerFrame(prAdapter)) + +#endif + +/* 4 TODO: The following values shall be got from FW by query CMD */ +/*------------------------------------------------------------------------*/ +/* Resource Management related information */ +/*------------------------------------------------------------------------*/ +#define NIC_TX_PAGE_SIZE_IS_POWER_OF_2 TRUE +#define NIC_TX_PAGE_SIZE_IN_POWER_OF_2 HIF_TX_PAGE_SIZE_IN_POWER_OF_2 +#define NIC_TX_PAGE_SIZE HIF_TX_PAGE_SIZE + +/* For development only */ +/* calculated by MS native 802.11 format */ +#define NIC_TX_MAX_SIZE_PER_FRAME 1532 +#define NIC_TX_MAX_PAGE_PER_FRAME \ + ((NIC_TX_DESC_AND_PADDING_LENGTH + NIC_TX_DESC_HEADER_PADDING_LENGTH + \ + NIC_TX_MAX_SIZE_PER_FRAME + NIC_TX_PAGE_SIZE - 1) / NIC_TX_PAGE_SIZE) + +#define NIX_TX_PLE_PAGE_CNT_PER_FRAME 1 +#define NIC_TX_LEN_ADDING_LENGTH 8 /*0x8206_C000[15:8] x 4.*/ + +/*------------------------------------------------------------------------*/ +/* Tx descriptor related information */ +/*------------------------------------------------------------------------*/ + +/* Frame Buffer + * |<--Tx Descriptor-->|<--Tx descriptor padding-->| + * <--802.3/802.11 Header-->|<--Header padding-->|<--Payload-->| + */ + +/* Tx descriptor length by format (TXD.FT) */ +/* in unit of double word */ +#define NIC_TX_DESC_LONG_FORMAT_LENGTH_DW 8 +#define NIC_TX_DESC_LONG_FORMAT_LENGTH \ + DWORD_TO_BYTE(NIC_TX_DESC_LONG_FORMAT_LENGTH_DW) +/* in unit of double word */ +#define NIC_TX_DESC_SHORT_FORMAT_LENGTH_DW 3 +#define NIC_TX_DESC_SHORT_FORMAT_LENGTH \ + DWORD_TO_BYTE(NIC_TX_DESC_SHORT_FORMAT_LENGTH_DW) + +/* Tx descriptor padding length (DMA.MICR.TXDSCR_PAD) */ +#define NIC_TX_DESC_PADDING_LENGTH_DW 0 /* in unit of double word */ +#define NIC_TX_DESC_PADDING_LENGTH \ + DWORD_TO_BYTE(NIC_TX_DESC_PADDING_LENGTH_DW) + +#define NIC_TX_DESC_AND_PADDING_LENGTH \ + (NIC_TX_DESC_LONG_FORMAT_LENGTH + NIC_TX_DESC_PADDING_LENGTH) + +/* Tx header padding (TXD.HeaderPadding) */ +/* Warning!! To use MAC header padding, every Tx packet must be decomposed */ +#define NIC_TX_DESC_HEADER_PADDING_LENGTH 0 /* in unit of bytes */ + +#define NIC_TX_DESC_PID_RESERVED 0 +#define NIC_TX_DESC_DRIVER_PID_MIN 1 +#define NIC_TX_DESC_DRIVER_PID_MAX 127 + +#define NIC_TX_DATA_DEFAULT_RETRY_COUNT_LIMIT 30 +#define NIC_TX_MGMT_DEFAULT_RETRY_COUNT_LIMIT 30 + +/* in unit of ms */ +#define NIC_TX_AC_BE_REMAINING_TX_TIME TX_DESC_TX_TIME_NO_LIMIT +#define NIC_TX_AC_BK_REMAINING_TX_TIME TX_DESC_TX_TIME_NO_LIMIT +#define NIC_TX_AC_VO_REMAINING_TX_TIME TX_DESC_TX_TIME_NO_LIMIT +#define NIC_TX_AC_VI_REMAINING_TX_TIME TX_DESC_TX_TIME_NO_LIMIT +#define NIC_TX_MGMT_REMAINING_TX_TIME 2000 + +#define NIC_TX_CRITICAL_DATA_TID 7 +/*802.1d Voice Traffic,use AC_VO */ +#define NIC_TX_PRIORITY_DATA_TID 6 + +/*Customization: sk_buff mark for special packet that need raise priority */ +#define NIC_TX_SKB_PRIORITY_MARK1 0x5a /* customer special value*/ +#define NIC_TX_SKB_PRIORITY_MARK_BIT 31 /*Mediatek define, 0x80000000*/ +#define NIC_TX_SKB_DUP_DETECT_MARK_BIT 30 /*Mediatek define, 0x40000000*/ + +#define HW_MAC_TX_DESC_APPEND_T_LENGTH 44 +#define NIC_TX_HEAD_ROOM \ + (NIC_TX_DESC_LONG_FORMAT_LENGTH + NIC_TX_DESC_PADDING_LENGTH \ + + HW_MAC_TX_DESC_APPEND_T_LENGTH) + +#define NIC_MSDU_REPORT_DUMP_TIMEOUT 5 /* sec */ + +/*------------------------------------------------------------------------*/ +/* Tx status related information */ +/*------------------------------------------------------------------------*/ + +/* Tx status header & content length */ +#define NIC_TX_STATUS_HEADER_LENGTH_DW \ + 1 /* in unit of double word */ +#define NIC_TX_STATUS_HEADER_LENGTH \ + DWORD_TO_BYTE(NIC_TX_STATUS_HEADER_LENGTH_DW) +#define NIC_TX_STATUS_LENGTH_DW \ + 7 /* in unit of double word */ +#define NIC_TX_STATUS_LENGTH \ + DWORD_TO_BYTE(NIC_TX_STATUS_LENGTH_DW) + +/*------------------------------------------------------------------------*/ +/* Tx descriptor field related information */ +/*------------------------------------------------------------------------*/ +/* DW 0 */ +#define TX_DESC_TX_BYTE_COUNT_MASK BITS(0, 15) +#define TX_DESC_TX_BYTE_COUNT_OFFSET 0 + +#define TX_DESC_ETHER_TYPE_OFFSET_MASK BITS(0, 6) +#define TX_DESC_ETHER_TYPE_OFFSET_OFFSET 0 +#define TX_DESC_IP_CHKSUM_OFFLOAD BIT(7) +#define TX_DESC_TCP_UDP_CHKSUM_OFFLOAD BIT(0) +#define TX_DESC_QUEUE_INDEX_MASK BITS(2, 6) +#define TX_DESC_QUEUE_INDEX_OFFSET 2 +#define TX_DESC_PORT_INDEX BIT(7) +#define TX_DESC_PORT_INDEX_OFFSET 7 + +#define PORT_INDEX_LMAC 0 +#define PORT_INDEX_MCU 1 + +/* DW 1 */ +#define TX_DESC_WLAN_INDEX_MASK BITS(0, 7) +#define TX_DESC_WLAN_INDEX_OFFSET 0 +#define TX_DESC_HEADER_FORMAT_MASK BITS(5, 6) +#define TX_DESC_HEADER_FORMAT_OFFSET 5 + +#define HEADER_FORMAT_NON_802_11 0 /* Non-802.11 */ +#define HEADER_FORMAT_COMMAND 1 /* Command */ +#define HEADER_FORMAT_802_11_NORMAL_MODE \ + 2 /* 802.11 (normal mode) */ +#define HEADER_FORMAT_802_11_ENHANCE_MODE \ + 3 /* 802.11 (Enhancement mode) */ +#define HEADER_FORMAT_802_11_MASK BIT(1) + +#define TX_DESC_NON_802_11_MORE_DATA BIT(0) +#define TX_DESC_NON_802_11_EOSP BIT(1) +#define TX_DESC_NON_802_11_REMOVE_VLAN BIT(2) +#define TX_DESC_NON_802_11_VLAN_FIELD BIT(3) +#define TX_DESC_NON_802_11_ETHERNET_II BIT(4) +#define TX_DESC_NOR_802_11_HEADER_LENGTH_MASK BITS(0, 4) +#define TX_DESC_NOR_802_11_HEADER_LENGTH_OFFSET 0 +#define TX_DESC_ENH_802_11_EOSP BIT(1) +#define TX_DESC_ENH_802_11_AMSDU BIT(2) + +#define TX_DESC_FORMAT BIT(7) +#define TX_DESC_SHORT_FORMAT 0 +#define TX_DESC_LONG_FORMAT 1 + +#define TX_DESC_TXD_LENGTH_MASK BIT(0) +#define TX_DESC_TXD_LENGTH_OFFSET 0 + +#define TX_DESC_HEADER_PADDING_LENGTH_MASK BIT(1) +#define TX_DESC_HEADER_PADDING_LENGTH_OFFSET 1 +#define TX_DESC_HEADER_PADDING_MODE BIT(2) + +#define TX_DESC_TXD_EXTEND_LENGTH_MASK BIT(3) +#define TX_DESC_TXD_EXTEND_LENGTH_OFFSET 3 + +#define TX_DESC_TXD_UTXB_AMSDU_MASK BIT(4) +#define TX_DESC_TXD_UTXB_AMSDU_OFFSET 4 + +#define TX_DESC_TID_MASK BITS(5, 7) +#define TX_DESC_TID_OFFSET 5 +#define TX_DESC_TID_NUM 8 + +#define TX_DESC_PACKET_FORMAT_MASK BITS(0, 1) /* SW Field */ +#define TX_DESC_PACKET_FORMAT_OFFSET 0 +#define TX_DESC_OWN_MAC_MASK BITS(2, 7) +#define TX_DESC_OWN_MAC_OFFSET 2 + +/* DW 2 */ +#define TX_DESC_SUB_TYPE_MASK BITS(0, 3) +#define TX_DESC_SUB_TYPE_OFFSET 0 +#define TX_DESC_TYPE_MASK BITS(4, 5) +#define TX_DESC_TYPE_OFFSET 4 +#define TX_DESC_NDP BIT(6) +#define TX_DESC_NDPA BIT(7) + +#define TX_DESC_SOUNDING BIT(0) +#define TX_DESC_FORCE_RTS_CTS BIT(1) +#define TX_DESC_BROADCAST_MULTICAST BIT(2) +#define TX_DESC_BIP_PROTECTED BIT(3) +#define TX_DESC_DURATION_FIELD_CONTROL BIT(4) +#define TX_DESC_HTC_EXISTS BIT(5) +#define TX_DESC_FRAGMENT_MASK BITS(6, 7) +#define TX_DESC_FRAGMENT_OFFSET 6 +#define FRAGMENT_FISRT_PACKET 1 +#define FRAGMENT_MIDDLE_PACKET 2 +#define FRAGMENT_LAST_PACKET 3 + +#define TX_DESC_REMAINING_MAX_TX_TIME BITS(0, 7) +#define TX_DESC_TX_TIME_NO_LIMIT 0 +/* Unit of life time calculation of Tx descriptor */ +#define TX_DESC_LIFE_TIME_UNIT_IN_POWER_OF_2 5 +#define TX_DESC_LIFE_TIME_UNIT \ + POWER_OF_2(TX_DESC_LIFE_TIME_UNIT_IN_POWER_OF_2) +#define TX_DESC_POWER_OFFSET_MASK BITS(0, 4) +#define TX_DESC_BA_DISABLE BIT(5) +#define TX_DESC_TIMING_MEASUREMENT BIT(6) +#define TX_DESC_FIXED_RATE BIT(7) + +/* DW 3 */ +#define TX_DESC_NO_ACK BIT(0) +#define TX_DESC_PROTECTED_FRAME BIT(1) +#define TX_DESC_EXTEND_MORE_DATA BIT(2) +#define TX_DESC_EXTEND_EOSP BIT(3) + +#define TX_DESC_SW_RESERVED_MASK BITS(4, 5) +#define TX_DESC_SW_RESERVED_OFFSET 4 + +#define TX_DESC_TX_COUNT_MASK BITS(6, 10) +#define TX_DESC_TX_COUNT_OFFSET 6 +#define TX_DESC_TX_COUNT_NO_ATTEMPT 0 +#define TX_DESC_TX_COUNT_NO_LIMIT 31 +#define TX_DESC_REMAINING_TX_COUNT_MASK BITS(11, 15) +#define TX_DESC_REMAINING_TX_COUNT_OFFSET 11 +#define TX_DESC_SEQUENCE_NUMBER BITS(0, 11) +#define TX_DESC_HW_RESERVED_MASK BITS(12, 13) +#define TX_DESC_HW_RESERVED_OFFSET 12 +#define TX_DESC_PN_IS_VALID BIT(14) +#define TX_DESC_SN_IS_VALID BIT(15) + +/* DW 4 */ +#define TX_DESC_PN_PART1 BITS(0, 31) + +/* DW 5 */ +#define TX_DESC_PACKET_ID BIT(0, 7) +#define TX_DESC_TX_STATUS_FORMAT BIT(0) +#define TX_DESC_TX_STATUS_FORMAT_OFFSET 0 +#define TX_DESC_TX_STATUS_TO_MCU BIT(1) +#define TX_DESC_TX_STATUS_TO_HOST BIT(2) +#define TX_DESC_DA_SOURCE BIT(3) +#define TX_DESC_POWER_MANAGEMENT_CONTROL BIT(5) +#define TX_DESC_PN_PART2 BITS(0, 15) + +/* DW 6 *//* FR = 1 */ +#define TX_DESC_BANDWIDTH_MASK BITS(0, 2) +#define TX_DESC_BANDWIDTH_OFFSET 0 +#define TX_DESC_DYNAMIC_BANDWIDTH BIT(3) +#define TX_DESC_ANTENNA_INDEX_MASK BITS(4, 15) +#define TX_DESC_ANTENNA_INDEX_OFFSET 4 + +#define TX_DESC_FIXDE_RATE_MASK BITS(0, 11) +#define TX_DESC_FIXDE_RATE_OFFSET 0 +#define TX_DESC_TX_RATE BITS(0, 5) +#define TX_DESC_TX_RATE_OFFSET 0 +#define TX_DESC_TX_MODE BITS(6, 8) +#define TX_DESC_TX_MODE_OFFSET 6 +#define TX_DESC_NSTS_MASK BITS(9, 10) +#define TX_DESC_NSTS_OFFSET 9 +#define TX_DESC_STBC BIT(11) +#define TX_DESC_BF BIT(12) +#define TX_DESC_LDPC BIT(13) +#define TX_DESC_GUARD_INTERVAL BIT(14) +#define TX_DESC_FIXED_RATE_MODE BIT(15) + +/* DW 7 */ +#define TX_DESC_SPE_EXT_IDX_SEL_MASK BIT(10) +#define TX_DESC_SPE_EXT_IDX_SEL_OFFSET 10 +#define TX_DESC_SPE_EXT_IDX_MASK BITS(11, 15) +#define TX_DESC_SPE_EXT_IDX_OFFSET 11 +#define TX_DESC_PSE_FID_MASK BITS(0, 13) +#define TX_DESC_PSE_FID_OFFSET 0 +#define TX_DESC_HW_AMSDU BIT(14) +#define TX_DESC_HIF_ERR BIT(15) + +#if CFG_ENABLE_PKT_LIFETIME_PROFILE +#define NIC_TX_TIME_THRESHOLD 100 /* in unit of ms */ +#endif + +#define NIC_TX_INIT_CMD_PORT HIF_TX_INIT_CMD_PORT + +#define NIC_TX_REMAINING_LIFE_TIME 2000 /* in unit of ms */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +/* 3 *//* Session for TX QUEUES */ +/* The definition in this ENUM is used to categorize packet's Traffic + * Class according to the their TID(User Priority). + * In order to achieve QoS goal, a particular TC should not block the process of + * another packet with different TC. + * In current design we will have 5 categories(TCs) of SW resource. + */ +/* TXD_PKT_FORMAT options*/ +enum ENUM_TXD_PKT_FORMAT_OPTION { + TXD_PKT_FORMAT_TXD = 0, /* TXD only */ + TXD_PKT_FORMAT_TXD_PAYLOAD, /* TXD and paload */ + TXD_PKT_FORMAT_COMMAND, /* Command */ + TXD_PKT_FORMAT_FWDL, /* Firmware download */ + TXD_PKT_FORMAT_NUM, +}; + +/* HIF Tx interrupt status queue index*/ +enum ENUM_HIF_TX_INDEX { + HIF_TX_AC0_INDEX = 0, + HIF_TX_AC1_INDEX, + HIF_TX_AC2_INDEX, + HIF_TX_AC3_INDEX, + + HIF_TX_AC10_INDEX, + HIF_TX_AC11_INDEX, + HIF_TX_AC12_INDEX, + HIF_TX_AC13_INDEX, + + HIF_TX_AC20_INDEX, + HIF_TX_AC21_INDEX, + HIF_TX_AC22_INDEX, + HIF_TX_AC23_INDEX, + + HIF_TX_RSV0_INDEX, + HIF_TX_RSV1_INDEX, + HIF_TX_FFA_INDEX, + HIF_TX_CPU_INDEX, + + HIF_TX_NUM +}; + +/* LMAC Tx queue index */ +enum ENUM_MAC_TXQ_INDEX { + MAC_TXQ_AC0_INDEX = 0, + MAC_TXQ_AC1_INDEX, + MAC_TXQ_AC2_INDEX, + MAC_TXQ_AC3_INDEX, + + MAC_TXQ_AC10_INDEX, + MAC_TXQ_AC11_INDEX, + MAC_TXQ_AC12_INDEX, + MAC_TXQ_AC13_INDEX, + + MAC_TXQ_AC20_INDEX, + MAC_TXQ_AC21_INDEX, + MAC_TXQ_AC22_INDEX, + MAC_TXQ_AC23_INDEX, + + MAC_TXQ_AC30_INDEX, + MAC_TXQ_AC31_INDEX, + MAC_TXQ_AC32_INDEX, + MAC_TXQ_AC33_INDEX, + + MAC_TXQ_ALTX_0_INDEX, + MAC_TXQ_BMC_0_INDEX, + MAC_TXQ_BCN_0_INDEX, + MAC_TXQ_PSMP_0_INDEX, + + MAC_TXQ_ALTX_1_INDEX, + MAC_TXQ_BMC_1_INDEX, + MAC_TXQ_BCN_1_INDEX, + MAC_TXQ_PSMP_1_INDEX, + + MAC_TXQ_NAF_INDEX, + MAC_TXQ_NBCN_INDEX, + + MAC_TXQ_NUM +}; + +/* MCU quque index */ +enum ENUM_MCU_Q_INDEX { + MCU_Q0_INDEX = 0, + MCU_Q1_INDEX, + MCU_Q2_INDEX, + MCU_Q3_INDEX, + MCU_Q_NUM +}; + +/* +1 for DBDC */ +#define TX_PORT_NUM (TC_NUM + 1) + +#define TX_2G_WMM_PORT_NUM (TC_NUM) + +#define BMC_TC_INDEX TC1_INDEX + +/* per-Network Tc Resource index */ +enum ENUM_NETWORK_TC_RESOURCE_INDEX { + /* QoS Data frame, WMM AC index */ + NET_TC_WMM_AC_BE_INDEX = 0, + NET_TC_WMM_AC_BK_INDEX, + NET_TC_WMM_AC_VI_INDEX, + NET_TC_WMM_AC_VO_INDEX, + /* Mgmt frame */ + NET_TC_MGMT_INDEX, + /* nonQoS / non StaRec frame (BMC/non-associated frame) */ + NET_TC_BMC_INDEX, + + NET_TC_NUM +}; + +enum ENUM_TX_STATISTIC_COUNTER { + TX_MPDU_TOTAL_COUNT = 0, + TX_INACTIVE_BSS_DROP, + TX_INACTIVE_STA_DROP, + TX_FORWARD_OVERFLOW_DROP, + TX_AP_BORADCAST_DROP, + TX_STATISTIC_COUNTER_NUM +}; + +enum ENUM_FIX_BW { + FIX_BW_NO_FIXED = 0, + FIX_BW_20 = 4, + FIX_BW_40, + FIX_BW_80, + FIX_BW_160, + FIX_BW_NUM +}; + +enum ENUM_MSDU_OPTION { + MSDU_OPT_NO_ACK = BIT(0), + MSDU_OPT_NO_AGGREGATE = BIT(1), + MSDU_OPT_TIMING_MEASURE = BIT(2), + MSDU_OPT_RCPI_NOISE_STATUS = BIT(3), + + /* Option by Frame Format */ + /* Non-80211 */ + MSDU_OPT_MORE_DATA = BIT(4), + MSDU_OPT_REMOVE_VLAN = BIT(5), /* Remove VLAN tag if exists */ + + /* 80211-enhanced */ + MSDU_OPT_AMSDU = BIT(6), + + /* 80211-enhanced & Non-80211 */ + MSDU_OPT_EOSP = BIT(7), + + /* Beamform */ + MSDU_OPT_NDP = BIT(8), + MSDU_OPT_NDPA = BIT(9), + MSDU_OPT_SOUNDING = BIT(10), + + /* Protection */ + MSDU_OPT_FORCE_RTS = BIT(11), + + /* Security */ + MSDU_OPT_BIP = BIT(12), + MSDU_OPT_PROTECTED_FRAME = BIT(13), + + /* SW Field */ + MSDU_OPT_SW_DURATION = BIT(14), + MSDU_OPT_SW_PS_BIT = BIT(15), + MSDU_OPT_SW_HTC = BIT(16), + MSDU_OPT_SW_BAR_SN = BIT(17), + + /* Manual Mode */ + MSDU_OPT_MANUAL_FIRST_BIT = BIT(18), + + MSDU_OPT_MANUAL_LIFE_TIME = MSDU_OPT_MANUAL_FIRST_BIT, + MSDU_OPT_MANUAL_RETRY_LIMIT = BIT(19), + MSDU_OPT_MANUAL_POWER_OFFSET = BIT(20), + MSDU_OPT_MANUAL_TX_QUE = BIT(21), + MSDU_OPT_MANUAL_SN = BIT(22), + + MSDU_OPT_MANUAL_LAST_BIT = MSDU_OPT_MANUAL_SN +}; + +enum ENUM_MSDU_CONTROL_FLAG { + MSDU_CONTROL_FLAG_FORCE_TX = BIT(0) +}; + +enum ENUM_MSDU_RATE_MODE { + MSDU_RATE_MODE_AUTO = 0, + MSDU_RATE_MODE_MANUAL_DESC, + /* The following rate mode is not implemented yet */ + /* DON'T use!!! */ + MSDU_RATE_MODE_MANUAL_CR, + MSDU_RATE_MODE_LOWEST_RATE +}; + +enum ENUM_DATA_RATE_MODE { + DATA_RATE_MODE_AUTO = 0, + DATA_RATE_MODE_MANUAL, + DATA_RATE_MODE_BSS_LOWEST +}; + +struct TX_TCQ_STATUS { + /* HIF reported page count delta */ + uint32_t au4TxDonePageCount[TC_NUM]; /* other TC */ + uint32_t au4PreUsedPageCount[TC_NUM]; + uint32_t u4AvaliablePageCount; /* FFA */ + uint8_t ucNextTcIdx; /* For round-robin distribute free page count */ + + /* distributed page count */ + uint32_t au4FreePageCount[TC_NUM]; + uint32_t au4MaxNumOfPage[TC_NUM]; + + /* buffer count */ + uint32_t au4FreeBufferCount[TC_NUM]; + uint32_t au4MaxNumOfBuffer[TC_NUM]; + + /* + * PLE part + */ + + u_int8_t fgNeedPleCtrl; + + /* HIF reported page count delta */ + uint32_t au4TxDonePageCount_PLE[TC_NUM]; /* other TC */ + uint32_t au4PreUsedPageCoun_PLE[TC_NUM]; + uint32_t u4AvaliablePageCount_PLE; /* FFA */ + + /* distributed page count */ + uint32_t au4FreePageCount_PLE[TC_NUM]; + uint32_t au4MaxNumOfPage_PLE[TC_NUM]; + + /* buffer count */ + uint32_t au4FreeBufferCount_PLE[TC_NUM]; + uint32_t au4MaxNumOfBuffer_PLE[TC_NUM]; +}; + +struct TX_TCQ_ADJUST { + int32_t ai4Variation[TC_NUM]; +}; + +struct TX_CTRL { + uint32_t u4TxCachedSize; + uint8_t *pucTxCached; + + uint32_t u4PageSize; + + uint32_t u4TotalPageNum; + + uint32_t u4TotalPageNumPle; + uint32_t u4TotalTxRsvPageNum; + +/* Elements below is classified according to TC (Traffic Class) value. */ + + struct TX_TCQ_STATUS rTc; + + uint8_t *pucTxCoalescingBufPtr; + + uint32_t u4WrIdx; + + struct QUE rFreeMsduInfoList; + + /* Management Frame Tracking */ + /* number of management frames to be sent */ + int32_t i4TxMgmtPendingNum; + + /* to tracking management frames need TX done callback */ + struct QUE rTxMgmtTxingQueue; + +#if CFG_HIF_STATISTICS + uint32_t u4TotalTxAccessNum; + uint32_t u4TotalTxPacketNum; +#endif + uint32_t au4Statistics[TX_STATISTIC_COUNTER_NUM]; + + /* Number to track forwarding frames */ + int32_t i4PendingFwdFrameCount; + /* Number to track forwarding frames for WMM resource control */ + int32_t i4PendingFwdFrameWMMCount[TC_NUM]; + + /* enable/disable TX resource control */ + u_int8_t fgIsTxResourceCtrl; + /* page counts for a wifi frame */ + uint32_t u4MaxPageCntPerFrame; + + /* Store SysTime of Last TxDone successfully */ + uint32_t u4LastTxTime[MAX_BSSID_NUM]; +}; + +enum ENUM_TX_PACKET_TYPE { + TX_PACKET_TYPE_DATA = 0, + TX_PACKET_TYPE_MGMT, + /* TX_PACKET_TYPE_1X, */ + X_PACKET_TYPE_NUM +}; + +enum ENUM_TX_PACKET_SRC { + TX_PACKET_OS, + TX_PACKET_OS_OID, + TX_PACKET_FORWARDING, + TX_PACKET_MGMT, + TX_PACKET_NUM +}; + +/* TX Call Back Function */ +typedef uint32_t(*PFN_TX_DONE_HANDLER) (IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN enum ENUM_TX_RESULT_CODE rTxDoneStatus); + +typedef void(*PFN_HIF_TX_MSDU_DONE_CB) (IN struct ADAPTER + *prAdapter, IN struct MSDU_INFO *prMsduInfo); + +#if CFG_ENABLE_PKT_LIFETIME_PROFILE +struct PKT_PROFILE { + u_int8_t fgIsValid; +#if CFG_PRINT_PKT_LIFETIME_PROFILE + u_int8_t fgIsPrinted; + uint16_t u2IpSn; + uint16_t u2RtpSn; + uint8_t ucTcxFreeCount; +#endif + OS_SYSTIME rHardXmitArrivalTimestamp; + OS_SYSTIME rEnqueueTimestamp; + OS_SYSTIME rDequeueTimestamp; + OS_SYSTIME rHifTxDoneTimestamp; +}; +#endif + +enum ENUM_EAPOL_KEY_TYPE_T { + EAPOL_KEY_NOT_KEY = 0, + EAPOL_KEY_1_OF_4, + EAPOL_KEY_2_OF_4, + EAPOL_KEY_3_OF_4, + EAPOL_KEY_4_OF_4, + EAPOL_KEY_NUM +}; + +/* TX transactions could be divided into 4 kinds: + * + * 1) 802.1X / Bluetooth-over-Wi-Fi Security Frames + * [CMD_INFO_T] - [prPacket] - in skb or NDIS_PACKET form + * + * 2) MMPDU + * [CMD_INFO_T] - [prPacket] - [MSDU_INFO_T] - [prPacket] - direct + * buffer for frame body + * + * 3) Command Packets + * [CMD_INFO_T] - [pucInfoBuffer] - direct buffer for content + * of command packet + * + * 4) Normal data frame + * [MSDU_INFO_T] - [prPacket] - in skb or NDIS_PACKET form + */ + +/* PS_FORWARDING_TYPE_NON_PS means that the receiving STA is in Active Mode + * from the perspective of host driver + * (maybe not synchronized with FW --> SN is needed) + */ + +struct MSDU_INFO { + struct QUE_ENTRY rQueEntry; + void *prPacket; /* Pointer to packet buffer */ + + enum ENUM_TX_PACKET_SRC eSrc; /* specify OS/FORWARD packet */ + uint8_t ucUserPriority; /* QoS parameter, convert to TID */ + + /* For composing TX descriptor header */ + uint8_t ucTC; /* Traffic Class: 0~4 (HIF TX0), 5 (HIF TX1) */ + uint8_t ucPacketType; /* 0: Data, 1: Management Frame */ + uint8_t ucStaRecIndex; /* STA_REC index */ + uint8_t ucBssIndex; /* BSS_INFO_T index */ + uint8_t ucWlanIndex; /* Wlan entry index */ + uint8_t ucPacketFormat; /* TXD.DW1[25:24] Packet Format */ + + u_int8_t fgIs802_1x; /* TRUE: 802.1x frame */ + /* TRUE: 802.1x frame - Non-Protected */ + u_int8_t fgIs802_1x_NonProtected; + u_int8_t fgIs802_11; /* TRUE: 802.11 header is present */ + u_int8_t fgIs802_3; /* TRUE: 802.3 frame */ + u_int8_t fgIsVlanExists; /* TRUE: VLAN tag is exists */ + + /* Special Option */ + uint32_t u4Option; /* Special option in bitmask, no ACK, etc... */ + int8_t cPowerOffset; /* Per-packet power offset, in 2's complement */ + uint16_t u2SwSN; /* SW assigned sequence number */ + uint8_t ucRetryLimit; /* The retry limit */ + uint32_t u4RemainingLifetime; /* Remaining lifetime, unit:ms */ + + /* Control flag */ + uint8_t ucControlFlag; /* Control flag in bitmask */ + + /* Fixed Rate Option */ + uint8_t ucRateMode; /* Rate mode: AUTO, MANUAL_DESC, MANUAL_CR */ + /* The rate option, rate code, GI, etc... */ + uint32_t u4FixedRateOption; + + /* There is a valid Tx descriptor for this packet */ + u_int8_t fgIsTXDTemplateValid; + + /* flattened from PACKET_INFO_T */ + uint8_t ucMacHeaderLength; /* MAC header legth */ + uint8_t ucLlcLength; /* w/o EtherType */ + uint16_t u2FrameLength; /* Total frame length */ + /* Ethernet Destination Address */ + uint8_t aucEthDestAddr[MAC_ADDR_LEN]; + uint32_t u4PageCount; /* Required page count for this MSDU */ + + /* for TX done tracking */ + uint8_t ucTxSeqNum; /* MGMT frame serial number */ + uint8_t ucPID; /* PID */ + uint8_t ucWmmQueSet; /* WMM Set */ + PFN_TX_DONE_HANDLER pfTxDoneHandler; /* Tx done handler */ + PFN_HIF_TX_MSDU_DONE_CB pfHifTxMsduDoneCb; + uint32_t u4TxDoneTag; /* Tag for data frame Tx done log */ + uint8_t ucPktType; + +#if CFG_ENABLE_PKT_LIFETIME_PROFILE + struct PKT_PROFILE rPktProfile; +#endif + + /* To be removed */ + uint8_t ucFormatID; /* 0: MAUI, Linux, Windows NDIS 5.1 */ + /* UINT_16 u2PalLLH; */ /* PAL Logical Link Header (for BOW network) */ + /* UINT_16 u2AclSN; */ /* ACL Sequence Number (for BOW network) */ + uint8_t ucPsForwardingType; /* See ENUM_PS_FORWARDING_TYPE_T */ + /* PS Session ID specified by the FW for the STA */ + /* UINT_8 ucPsSessionID; */ + /* TRUE means this is the last packet of the burst for (STA, TID) */ + /* BOOLEAN fgIsBurstEnd; */ +#if CFG_M0VE_BA_TO_DRIVER + uint8_t ucTID; +#endif + +#if CFG_SUPPORT_MULTITHREAD + /* Compose TxDesc in main_thread and place here */ + uint8_t aucTxDescBuffer[NIC_TX_DESC_AND_PADDING_LENGTH]; +#endif + +#if defined(_HIF_PCIE) || defined(_HIF_AXI) + struct MSDU_TOKEN_ENTRY *prToken; + struct TX_DATA_REQ rTxReq; +#endif + enum ENUM_EAPOL_KEY_TYPE_T eEapolKeyType; +#if (CFG_SUPPORT_DMASHDL_SYSDVT) + uint8_t ucTarQueue; +#endif + uint8_t fgMgmtUseDataQ; +}; + +#define HIF_PKT_FLAGS_CT_INFO_APPLY_TXD BIT(0) +#define HIF_PKT_FLAGS_COPY_HOST_TXD_ALL BIT(1) +#define HIF_PKT_FLAGS_CT_INFO_MGN_FRAME BIT(2) +#define HIF_PKT_FLAGS_CT_INFO_NONE_CIPHER_FRAME BIT(3) +#define HIF_PKT_FLAGS_CT_INFO_HSR2_TX BIT(4) + +#define MAX_BUF_NUM_PER_PKT 6 + +#define NUM_OF_MSDU_ID_IN_TXD 4 +#define TXD_MAX_BUF_NUM 4 +#define TXD_MSDU_ID_VLD BIT(15) /* MSDU valid */ +#define TXD_LEN_AL BIT(15) /* A-MSDU last */ +#define TXD_LEN_ML BIT(14) /* MSDU last */ +#define TXD_LEN_ML_V2 BIT(15) /* MSDU last */ +#define TXD_LEN_MASK_V2 BITS(0, 11) +#define TXD_ADDR2_MASK BITS(12, 14) +#define TXD_ADDR2_OFFSET 20 + + +struct TXD_PTR_LEN { + uint32_t u4Ptr0; + uint16_t u2Len0; /* Bit15: AL, Bit14: ML */ + uint16_t u2Len1; /* Bit15: AL, Bit14: ML */ + uint32_t u4Ptr1; +}; + +union HW_MAC_TX_DESC_APPEND { + struct { + uint16_t u2PktFlags; + uint16_t u2MsduToken; + uint8_t ucBssIndex; + uint8_t ucWtblIndex; + uint8_t aucReserved[1]; + uint8_t ucBufNum; + uint32_t au4BufPtr[MAX_BUF_NUM_PER_PKT]; + uint16_t au2BufLen[MAX_BUF_NUM_PER_PKT]; + } CR4_APPEND; + + struct { + /* Bit15 indicate valid */ + uint16_t au2MsduId[NUM_OF_MSDU_ID_IN_TXD]; + struct TXD_PTR_LEN arPtrLen[TXD_MAX_BUF_NUM / 2]; + } CONNAC_APPEND; +}; + +/*!A data structure which is identical with HW MAC TX DMA Descriptor */ +struct HW_MAC_TX_DESC { + /* DW 0 */ + uint16_t u2TxByteCount; + uint8_t ucEtherOffset; /* Ether-Type Offset, IP checksum offload */ + /* UDP/TCP checksum offload, + * USB NextVLD/TxBURST, Queue index, Port index + */ + uint8_t ucPortIdx_QueueIdx; + /* DW 1 */ + uint8_t ucWlanIdx; + /* Header format, TX descriptor format */ + uint8_t ucHeaderFormat; + /* Header padding, no ACK, TID, Protect frame */ + uint8_t ucHeaderPadding; + uint8_t ucOwnMAC; + + /* Long Format, the following structure is for long format ONLY */ + /* DW 2 */ + uint8_t ucType_SubType; /* Type, Sub-type, NDP, NDPA */ + /* Sounding, force RTS/CTS, BMC, BIP, Duration, HTC exist, Fragment */ + uint8_t ucFrag; + uint8_t ucRemainingMaxTxTime; + /* Power offset, Disable BA, Timing measurement, Fixed rate */ + uint8_t ucPowerOffset; + /* DW 3 */ + uint16_t u2TxCountLimit; /* TX count limit */ + uint16_t u2SN; /* SN, HW own, PN valid, SN valid */ + /* DW 4 */ + uint32_t u4PN1; + /* DW 5 */ + uint8_t ucPID; + /* TXS format, TXS to mcu, + * TXS to host, DA source, BAR SSN, Power management + */ + uint8_t ucTxStatus; + uint16_t u2PN2; + /* DW 6 */ + uint16_t u2AntID; /* Fixed rate, Antenna ID */ + /* Explicit/implicit beamforming, Fixed rate table, LDPC, GI */ + uint16_t u2FixedRate; + /* DW 7 */ + uint16_t u2SwTxTime; /* Sw Tx time[9:0], SPE_IDX[15:11] */ + uint16_t u2PseFid; /* indicate frame ID in PSE for this TXD */ +}; + +struct TX_RESOURCE_CONTROL { + /* HW TX queue definition */ + uint8_t ucDestPortIndex; + uint8_t ucDestQueueIndex; + /* HIF Interrupt status index */ + uint8_t ucHifTxQIndex; +}; + +struct TX_TC_TRAFFIC_SETTING { + uint32_t u4TxDescLength; + uint32_t u4RemainingTxTime; + uint8_t ucTxCountLimit; +}; + +typedef void (*PFN_TX_DATA_DONE_CB) (IN struct GLUE_INFO *prGlueInfo, + IN struct QUE *prQue); + +struct tx_resource_info { + /* PSE */ + /* the total usable resource for MCU port */ + uint32_t u4CmdTotalResource; + /* the unit of a MCU resource */ + uint32_t u4CmdResourceUnit; + /* the total usable resource for LMAC port */ + uint32_t u4DataTotalResource; + /* the unit of a LMAC resource */ + uint32_t u4DataResourceUnit; + + /* PLE */ + /* the total usable resource for MCU port */ + uint32_t u4CmdTotalResourcePle; + /* the unit of a MCU resource */ + uint32_t u4CmdResourceUnitPle; + /* the total usable resource for LMAC port */ + uint32_t u4DataTotalResourcePle; + /* the unit of a LMAC resource */ + uint32_t u4DataResourceUnitPle; + + /* Packet Processor 0x8206C000[15:8] + * 4. Extra PSE resource is needed for HW. + */ + uint8_t ucPpTxAddCnt;/* in unit of byte */ + + /* update resource callback */ + void (*txResourceInit)(IN struct ADAPTER *prAdapter); +}; + +struct TX_DESC_OPS_T { + void (*fillNicAppend)(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + OUT uint8_t *prTxDescBuffer); + void (*fillHifAppend)(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, IN uint16_t u4MsduId, + IN dma_addr_t rDmaAddr, IN uint32_t u4Idx, IN u_int8_t fgIsLast, + OUT uint8_t *pucBuffer); + void (*fillTxByteCount)(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + void *prTxDesc); + + /* TXD Handle APIs */ + uint8_t (*nic_txd_long_format_op)( + void *prTxDesc, + uint8_t fgSet); + uint8_t (*nic_txd_tid_op)( + void *prTxDesc, + uint8_t ucTid, + uint8_t fgSet); + uint8_t (*nic_txd_queue_idx_op)( + void *prTxDesc, + uint8_t ucQueIdx, + uint8_t fgSet); +#if (CFG_TCP_IP_CHKSUM_OFFLOAD == 1) + void (*nic_txd_chksum_op)( + void *prTxDesc, + uint8_t ucChksumFlag); +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD == 1 */ + void (*nic_txd_header_format_op)( + void *prTxDesc, + struct MSDU_INFO *prMsduInfo); + void (*nic_txd_fill_by_pkt_option)( + struct MSDU_INFO *prMsduInfo, + void *prTxD); + void (*nic_txd_compose)( + struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo, + u_int32_t u4TxDescLength, + u_int8_t fgIsTemplate, + u_int8_t *prTxDescBuffer); + void (*nic_txd_compose_security_frame)( + struct ADAPTER *prAdapter, + struct CMD_INFO *prCmdInfo, + uint8_t *prTxDescBuffer, + uint8_t *pucTxDescLength); + void (*nic_txd_set_pkt_fixed_rate_option_full)( + struct MSDU_INFO *prMsduInfo, + uint16_t u2RateCode, + uint8_t ucBandwidth, + u_int8_t fgShortGI, + u_int8_t fgLDPC, + u_int8_t fgDynamicBwRts, u_int8_t fgBeamforming, + uint8_t ucAntennaIndex); + void (*nic_txd_set_pkt_fixed_rate_option)( + struct MSDU_INFO *prMsduInfo, + uint16_t u2RateCode, + uint8_t ucBandwidth, + u_int8_t fgShortGI, + u_int8_t fgDynamicBwRts); + void (*nic_txd_set_hw_amsdu_template)( + struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + uint8_t ucTid, + u_int8_t fgSet); + void (*nic_txd_change_data_port_by_ac)( + struct STA_RECORD *prStaRec, + uint8_t ucAci, + u_int8_t fgToMcu); +}; + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +extern PFN_TX_DATA_DONE_CB g_pfTxDataDoneCb; + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +#define TX_INC_CNT(prTxCtrl, eCounter) \ + {((struct TX_CTRL *)prTxCtrl)->au4Statistics[eCounter]++; } + +#define TX_ADD_CNT(prTxCtrl, eCounter, u8Amount) \ + {((struct TX_CTRL *)prTxCtrl)->au4Statistics[eCounter] += \ + (uint32_t)u8Amount; } + +#define TX_GET_CNT(prTxCtrl, eCounter) \ + (((struct TX_CTRL *)prTxCtrl)->au4Statistics[eCounter]) + +#define TX_RESET_ALL_CNTS(prTxCtrl) \ + {kalMemZero(&prTxCtrl->au4Statistics[0], \ + sizeof(prTxCtrl->au4Statistics)); } +#if CFG_ENABLE_PKT_LIFETIME_PROFILE + +#if CFG_PRINT_PKT_LIFETIME_PROFILE +#define PRINT_PKT_PROFILE(_pkt_profile, _note) \ +do { \ + if (!(_pkt_profile)->fgIsPrinted) { \ + DBGLOG(TX, TRACE, \ + "X[%lu] E[%lu] D[%lu] HD[%lu] B[%d] RTP[%d] %s\n", \ + (uint32_t)((_pkt_profile)->rHardXmitArrivalTimestamp), \ + (uint32_t)((_pkt_profile)->rEnqueueTimestamp), \ + (uint32_t)((_pkt_profile)->rDequeueTimestamp), \ + (uint32_t)((_pkt_profile)->rHifTxDoneTimestamp), \ + (uint8_t)((_pkt_profile)->ucTcxFreeCount), \ + (uint16_t)((_pkt_profile)->u2RtpSn), \ + (_note))); \ + (_pkt_profile)->fgIsPrinted = TRUE; \ + } \ +} while (0) +#else +#define PRINT_PKT_PROFILE(_pkt_profile, _note) +#endif + +#define CHK_PROFILES_DELTA(_pkt1, _pkt2, _delta) \ + (CHECK_FOR_TIMEOUT((_pkt1)->rHardXmitArrivalTimestamp, \ + (_pkt2)->rHardXmitArrivalTimestamp, (_delta)) || \ + CHECK_FOR_TIMEOUT((_pkt1)->rEnqueueTimestamp, \ + (_pkt2)->rEnqueueTimestamp, (_delta)) || \ + CHECK_FOR_TIMEOUT((_pkt1)->rDequeueTimestamp, \ + (_pkt2)->rDequeueTimestamp, (_delta)) || \ + CHECK_FOR_TIMEOUT((_pkt1)->rHifTxDoneTimestamp, \ + (_pkt2)->rHifTxDoneTimestamp, (_delta))) + +#define CHK_PROFILE_DELTA(_pkt, _delta) \ + (CHECK_FOR_TIMEOUT((_pkt)->rEnqueueTimestamp, \ + (_pkt)->rHardXmitArrivalTimestamp, (_delta)) || \ + CHECK_FOR_TIMEOUT((_pkt)->rDequeueTimestamp, \ + (_pkt)->rEnqueueTimestamp, (_delta)) || \ + CHECK_FOR_TIMEOUT((_pkt)->rHifTxDoneTimestamp, \ + (_pkt)->rDequeueTimestamp, (_delta))) +#endif + +/*------------------------------------------------------------------------------ + * MACRO for MSDU_INFO + *------------------------------------------------------------------------------ + */ +#define TX_SET_MMPDU nicTxSetMngPacket +#define TX_SET_DATA_PACKET nicTxSetDataPacket + +/*------------------------------------------------------------------------------ + * MACRO for HW_MAC_TX_DESC_T + *------------------------------------------------------------------------------ + */ +#define TX_DESC_GET_FIELD(_rHwMacTxDescField, _mask, _offset) \ + (((_rHwMacTxDescField) & (_mask)) >> (_offset)) +#define TX_DESC_SET_FIELD(_rHwMacTxDescField, _value, _mask, _offset) \ +{ \ + (_rHwMacTxDescField) &= ~(_mask); \ + (_rHwMacTxDescField) |= (((_value) << (_offset)) & (_mask)); \ +} + +#define HAL_MAC_TX_DESC_SET_DW(_prHwMacTxDesc, _ucOffsetInDw, \ + _ucLengthInDw, _pucValueAddr) \ + kalMemCopy((uint32_t *)(_prHwMacTxDesc) + (_ucOffsetInDw), \ + (uint8_t *)(_pucValueAddr), DWORD_TO_BYTE(_ucLengthInDw)) +#define HAL_MAC_TX_DESC_GET_DW(_prHwMacTxDesc, _ucOffsetInDw, \ + _ucLengthInDw, _pucValueAddr) \ + kalMemCopy((uint8_t *)(_pucValueAddr), \ + (uint32_t *)(_prHwMacTxDesc) + (_ucOffsetInDw), \ + DWORD_TO_BYTE(_ucLengthInDw)) + +/* DW 0 */ +#define HAL_MAC_TX_DESC_GET_TX_BYTE_COUNT(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->u2TxByteCount) +#define HAL_MAC_TX_DESC_SET_TX_BYTE_COUNT(_prHwMacTxDesc, _u2TxByteCount) \ + (((_prHwMacTxDesc)->u2TxByteCount) = ((uint16_t)_u2TxByteCount)) + +#define HAL_MAC_TX_DESC_GET_ETHER_TYPE_OFFSET(_prHwMacTxDesc) \ + TX_DESC_GET_FIELD((_prHwMacTxDesc)->ucEtherOffset, \ + TX_DESC_ETHER_TYPE_OFFSET_MASK, \ + TX_DESC_ETHER_TYPE_OFFSET_OFFSET) +#define HAL_MAC_TX_DESC_SET_ETHER_TYPE_OFFSET(_prHwMacTxDesc, \ + _ucEtherTypeOffset) \ + TX_DESC_SET_FIELD(((_prHwMacTxDesc)->ucEtherOffset), \ + ((uint8_t)_ucEtherTypeOffset), \ + TX_DESC_ETHER_TYPE_OFFSET_MASK, TX_DESC_ETHER_TYPE_OFFSET_OFFSET) + +#define HAL_MAC_TX_DESC_IS_IP_CHKSUM_ENABLED(_prHwMacTxDesc) \ + (((_prHwMacTxDesc)->ucEtherOffset & TX_DESC_IP_CHKSUM_OFFLOAD) \ + ? FALSE : TRUE) +#define HAL_MAC_TX_DESC_SET_IP_CHKSUM(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucEtherOffset |= TX_DESC_IP_CHKSUM_OFFLOAD) +#define HAL_MAC_TX_DESC_UNSET_IP_CHKSUM(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucEtherOffset &= ~TX_DESC_IP_CHKSUM_OFFLOAD) + +#define HAL_MAC_TX_DESC_IS_TCP_UDP_CHKSUM_ENABLED(_prHwMacTxDesc) \ + (((_prHwMacTxDesc)->ucPortIdx_QueueIdx & \ + TX_DESC_TCP_UDP_CHKSUM_OFFLOAD) ? FALSE : TRUE) +#define HAL_MAC_TX_DESC_SET_TCP_UDP_CHKSUM(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucPortIdx_QueueIdx |= TX_DESC_TCP_UDP_CHKSUM_OFFLOAD) +#define HAL_MAC_TX_DESC_UNSET_TCP_UDP_CHKSUM(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucPortIdx_QueueIdx &= \ + ~TX_DESC_TCP_UDP_CHKSUM_OFFLOAD) + +#if 0 /* USB HIF doesn't use this field. */ +#define HAL_MAC_TX_DESC_IS_USB_NEXT_VLD_ENABLED(_prHwMacTxDesc) \ + (((_prHwMacTxDesc)->ucPortIdx_QueueIdx & TX_DESC_USB_NEXT_VLD) \ + ? TRUE : FALSE) +#define HAL_MAC_TX_DESC_SET_USB_NEXT_VLD(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucPortIdx_QueueIdx |= TX_DESC_USB_NEXT_VLD) +#define HAL_MAC_TX_DESC_UNSET_USB_NEXT_VLD(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucPortIdx_QueueIdx &= ~TX_DESC_USB_NEXT_VLD) +#endif /* if 0 */ + +#define HAL_MAC_TX_DESC_GET_QUEUE_INDEX(_prHwMacTxDesc) \ + TX_DESC_GET_FIELD((_prHwMacTxDesc)->ucPortIdx_QueueIdx, \ + TX_DESC_QUEUE_INDEX_MASK, TX_DESC_QUEUE_INDEX_OFFSET) +#define HAL_MAC_TX_DESC_SET_QUEUE_INDEX(_prHwMacTxDesc, _ucQueueIndex) \ + TX_DESC_SET_FIELD(((_prHwMacTxDesc)->ucPortIdx_QueueIdx), \ + ((uint8_t)_ucQueueIndex), \ + TX_DESC_QUEUE_INDEX_MASK, TX_DESC_QUEUE_INDEX_OFFSET) + +#define HAL_MAC_TX_DESC_GET_PORT_INDEX(_prHwMacTxDesc) \ + TX_DESC_GET_FIELD((_prHwMacTxDesc)->ucPortIdx_QueueIdx, \ + TX_DESC_PORT_INDEX, TX_DESC_PORT_INDEX_OFFSET) +#define HAL_MAC_TX_DESC_SET_PORT_INDEX(_prHwMacTxDesc, _ucPortIndex) \ + TX_DESC_SET_FIELD(((_prHwMacTxDesc)->ucPortIdx_QueueIdx), \ + ((uint8_t)_ucPortIndex), \ + TX_DESC_PORT_INDEX, TX_DESC_PORT_INDEX_OFFSET) + +/* DW 1 */ +#define HAL_MAC_TX_DESC_GET_WLAN_INDEX(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucWlanIdx) +#define HAL_MAC_TX_DESC_SET_WLAN_INDEX(_prHwMacTxDesc, _ucWlanIdx) \ + (((_prHwMacTxDesc)->ucWlanIdx) = (_ucWlanIdx)) + +#define HAL_MAC_TX_DESC_IS_LONG_FORMAT(_prHwMacTxDesc) \ + (((_prHwMacTxDesc)->ucHeaderFormat & TX_DESC_FORMAT)?TRUE:FALSE) +#define HAL_MAC_TX_DESC_SET_LONG_FORMAT(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucHeaderFormat |= TX_DESC_FORMAT) +#define HAL_MAC_TX_DESC_SET_SHORT_FORMAT(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucHeaderFormat &= ~TX_DESC_FORMAT) + +#define HAL_MAC_TX_DESC_GET_HEADER_FORMAT(_prHwMacTxDesc) \ + TX_DESC_GET_FIELD((_prHwMacTxDesc)->ucHeaderFormat, \ + TX_DESC_HEADER_FORMAT_MASK, TX_DESC_HEADER_FORMAT_OFFSET) +#define HAL_MAC_TX_DESC_SET_HEADER_FORMAT(_prHwMacTxDesc, _ucHdrFormat) \ + TX_DESC_SET_FIELD(((_prHwMacTxDesc)->ucHeaderFormat), \ + ((uint8_t)_ucHdrFormat), TX_DESC_HEADER_FORMAT_MASK, \ + TX_DESC_HEADER_FORMAT_OFFSET) + +/* HF = 0x00, 802.11 normal mode */ +#define HAL_MAC_TX_DESC_IS_MORE_DATA(_prHwMacTxDesc) \ + (((_prHwMacTxDesc)->ucHeaderFormat & TX_DESC_NON_802_11_MORE_DATA) \ + ? TRUE : FALSE) +#define HAL_MAC_TX_DESC_SET_MORE_DATA(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucHeaderFormat |= TX_DESC_NON_802_11_MORE_DATA) +#define HAL_MAC_TX_DESC_UNSET_MORE_DATA(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucHeaderFormat &= ~TX_DESC_NON_802_11_MORE_DATA) + +#define HAL_MAC_TX_DESC_IS_REMOVE_VLAN(_prHwMacTxDesc) \ + (((_prHwMacTxDesc)->ucHeaderFormat & TX_DESC_NON_802_11_REMOVE_VLAN) \ + ? TRUE : FALSE) +#define HAL_MAC_TX_DESC_SET_REMOVE_VLAN(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucHeaderFormat |= TX_DESC_NON_802_11_REMOVE_VLAN) +#define HAL_MAC_TX_DESC_UNSET_REMOVE_VLAN(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucHeaderFormat &= ~TX_DESC_NON_802_11_REMOVE_VLAN) + +#define HAL_MAC_TX_DESC_IS_VLAN(_prHwMacTxDesc) \ + (((_prHwMacTxDesc)->ucHeaderFormat & TX_DESC_NON_802_11_VLAN_FIELD) \ + ? TRUE : FALSE) +#define HAL_MAC_TX_DESC_SET_VLAN(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucHeaderFormat |= TX_DESC_NON_802_11_VLAN_FIELD) +#define HAL_MAC_TX_DESC_UNSET_VLAN(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucHeaderFormat &= ~TX_DESC_NON_802_11_VLAN_FIELD) + +#define HAL_MAC_TX_DESC_IS_ETHERNET_II(_prHwMacTxDesc) \ + (((_prHwMacTxDesc)->ucHeaderFormat & TX_DESC_NON_802_11_ETHERNET_II) \ + ? TRUE : FALSE) +#define HAL_MAC_TX_DESC_SET_ETHERNET_II(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucHeaderFormat |= TX_DESC_NON_802_11_ETHERNET_II) +#define HAL_MAC_TX_DESC_UNSET_ETHERNET_II(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucHeaderFormat &= ~TX_DESC_NON_802_11_ETHERNET_II) + +/* HF = 0x00/0x11, 802.11 normal/enhancement mode */ +#define HAL_MAC_TX_DESC_IS_EOSP(_prHwMacTxDesc) \ + (((_prHwMacTxDesc)->ucHeaderFormat & TX_DESC_NON_802_11_EOSP) \ + ? TRUE : FALSE) +#define HAL_MAC_TX_DESC_SET_EOSP(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucHeaderFormat |= TX_DESC_NON_802_11_EOSP) +#define HAL_MAC_TX_DESC_UNSET_EOSP(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucHeaderFormat &= ~TX_DESC_NON_802_11_EOSP) + +/* HF = 0x11, 802.11 enhancement mode */ +#define HAL_MAC_TX_DESC_IS_AMSDU(_prHwMacTxDesc) \ + (((_prHwMacTxDesc)->ucHeaderFormat & TX_DESC_ENH_802_11_AMSDU) \ + ? TRUE : FALSE) +#define HAL_MAC_TX_DESC_SET_AMSDU(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucHeaderFormat |= TX_DESC_ENH_802_11_AMSDU) +#define HAL_MAC_TX_DESC_UNSET_AMSDU(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucHeaderFormat &= ~TX_DESC_ENH_802_11_AMSDU) + +/* HF = 0x10, non-802.11 */ +#define HAL_MAC_TX_DESC_GET_802_11_HEADER_LENGTH(_prHwMacTxDesc) \ + TX_DESC_GET_FIELD((_prHwMacTxDesc)->ucHeaderFormat, \ + TX_DESC_NOR_802_11_HEADER_LENGTH_MASK, \ + TX_DESC_NOR_802_11_HEADER_LENGTH_OFFSET) +#define HAL_MAC_TX_DESC_SET_802_11_HEADER_LENGTH(_prHwMacTxDesc, \ + _ucHdrLength) \ + TX_DESC_SET_FIELD(((_prHwMacTxDesc)->ucHeaderFormat), \ + ((uint8_t)_ucHdrLength), \ + TX_DESC_NOR_802_11_HEADER_LENGTH_MASK, \ + TX_DESC_NOR_802_11_HEADER_LENGTH_OFFSET) + +#define HAL_MAC_TX_DESC_GET_TXD_LENGTH(_prHwMacTxDesc) \ + TX_DESC_GET_FIELD((_prHwMacTxDesc)->ucHeaderPadding, \ + TX_DESC_TXD_LENGTH_MASK, TX_DESC_TXD_LENGTH_OFFSET) +#define HAL_MAC_TX_DESC_SET_TXD_LENGTH(_prHwMacTxDesc, _ucHdrPadding) \ + TX_DESC_SET_FIELD(((_prHwMacTxDesc)->ucHeaderPadding), \ + ((uint8_t)_ucHdrPadding), \ + TX_DESC_TXD_LENGTH_MASK, TX_DESC_TXD_LENGTH_OFFSET) + +#define HAL_MAC_TX_DESC_GET_TXD_EXTEND_LENGTH(_prHwMacTxDesc) \ + TX_DESC_GET_FIELD((_prHwMacTxDesc)->ucHeaderPadding, \ + TX_DESC_TXD_EXTEND_LENGTH_MASK, \ + TX_DESC_TXD_EXTEND_LENGTH_OFFSET) +#define HAL_MAC_TX_DESC_SET_TXD_EXTEND_LENGTH(_prHwMacTxDesc, _ucHdrPadding) \ + TX_DESC_SET_FIELD(((_prHwMacTxDesc)->ucHeaderPadding), \ + ((uint8_t)_ucHdrPadding), \ + TX_DESC_TXD_EXTEND_LENGTH_MASK, TX_DESC_TXD_EXTEND_LENGTH_OFFSET) + +#define HAL_MAC_TX_DESC_GET_HEADER_PADDING(_prHwMacTxDesc) \ + TX_DESC_GET_FIELD((_prHwMacTxDesc)->ucHeaderPadding, \ + TX_DESC_HEADER_PADDING_LENGTH_MASK, \ + TX_DESC_HEADER_PADDING_LENGTH_OFFSET) +#define HAL_MAC_TX_DESC_SET_HEADER_PADDING(_prHwMacTxDesc, _ucHdrPadding) \ + TX_DESC_SET_FIELD(((_prHwMacTxDesc)->ucHeaderPadding), \ + ((uint8_t)_ucHdrPadding), \ + TX_DESC_HEADER_PADDING_LENGTH_MASK, \ + TX_DESC_HEADER_PADDING_LENGTH_OFFSET) + +#define HAL_MAC_TX_DESC_GET_UTXB_AMSDU(_prHwMacTxDesc) \ + TX_DESC_GET_FIELD((_prHwMacTxDesc)->ucHeaderPadding, \ + TX_DESC_TXD_UTXB_AMSDU_MASK, TX_DESC_TXD_UTXB_AMSDU_OFFSET) +#define HAL_MAC_TX_DESC_SET_UTXB_AMSDU(_prHwMacTxDesc, _ucHdrPadding) \ + TX_DESC_SET_FIELD(((_prHwMacTxDesc)->ucHeaderPadding), \ + ((uint8_t)_ucHdrPadding), \ + TX_DESC_TXD_UTXB_AMSDU_MASK, TX_DESC_TXD_UTXB_AMSDU_OFFSET) + +#define HAL_MAC_TX_DESC_IS_HEADER_PADDING_IN_THE_HEAD(_prHwMacTxDesc) \ + (((_prHwMacTxDesc)->ucHeaderPadding & TX_DESC_HEADER_PADDING_MODE) \ + ? TRUE : FALSE) +#define HAL_MAC_TX_DESC_SET_HEADER_PADDING_IN_THE_HEAD(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucHeaderPadding |= TX_DESC_HEADER_PADDING_MODE) +#define HAL_MAC_TX_DESC_SET_HEADER_PADDING_IN_THE_TAIL(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucHeaderPadding &= ~TX_DESC_HEADER_PADDING_MODE) + +#define HAL_MAC_TX_DESC_GET_TID(_prHwMacTxDesc) \ + TX_DESC_GET_FIELD((_prHwMacTxDesc)->ucHeaderPadding, \ + TX_DESC_TID_MASK, TX_DESC_TID_OFFSET) +#define HAL_MAC_TX_DESC_SET_TID(_prHwMacTxDesc, _ucTID) \ + TX_DESC_SET_FIELD(((_prHwMacTxDesc)->ucHeaderPadding), \ + ((uint8_t)_ucTID), TX_DESC_TID_MASK, TX_DESC_TID_OFFSET) + +#define HAL_MAC_TX_DESC_GET_PKT_FORMAT(_prHwMacTxDesc) \ + TX_DESC_GET_FIELD((_prHwMacTxDesc)->ucOwnMAC, \ + TX_DESC_PACKET_FORMAT_MASK, \ + TX_DESC_PACKET_FORMAT_OFFSET) +#define HAL_MAC_TX_DESC_SET_PKT_FORMAT(_prHwMacTxDesc, _ucPktFormat) \ + TX_DESC_SET_FIELD(((_prHwMacTxDesc)->ucOwnMAC), \ + ((uint8_t)_ucPktFormat), \ + TX_DESC_PACKET_FORMAT_MASK, TX_DESC_PACKET_FORMAT_OFFSET) + +#define HAL_MAC_TX_DESC_GET_OWN_MAC_INDEX(_prHwMacTxDesc) \ + TX_DESC_GET_FIELD((_prHwMacTxDesc)->ucOwnMAC, \ + TX_DESC_OWN_MAC_MASK, TX_DESC_OWN_MAC_OFFSET) +#define HAL_MAC_TX_DESC_SET_OWN_MAC_INDEX(_prHwMacTxDesc, _ucOwnMacIdx) \ + TX_DESC_SET_FIELD(((_prHwMacTxDesc)->ucOwnMAC), \ + ((uint8_t)_ucOwnMacIdx), \ + TX_DESC_OWN_MAC_MASK, TX_DESC_OWN_MAC_OFFSET) + +/* DW 2 */ +#define HAL_MAC_TX_DESC_GET_SUB_TYPE(_prHwMacTxDesc) \ + TX_DESC_GET_FIELD((_prHwMacTxDesc)->ucType_SubType, \ + TX_DESC_SUB_TYPE_MASK, TX_DESC_SUB_TYPE_OFFSET) +#define HAL_MAC_TX_DESC_SET_SUB_TYPE(_prHwMacTxDesc, _ucSubType) \ + TX_DESC_SET_FIELD(((_prHwMacTxDesc)->ucType_SubType), \ + ((uint8_t)_ucSubType), \ + TX_DESC_SUB_TYPE_MASK, TX_DESC_SUB_TYPE_OFFSET) + +#define HAL_MAC_TX_DESC_GET_TYPE(_prHwMacTxDesc) \ + TX_DESC_GET_FIELD((_prHwMacTxDesc)->ucType_SubType, \ + TX_DESC_TYPE_MASK, TX_DESC_TYPE_OFFSET) +#define HAL_MAC_TX_DESC_SET_TYPE(_prHwMacTxDesc, _ucType) \ + TX_DESC_SET_FIELD(((_prHwMacTxDesc)->ucType_SubType), \ + ((uint8_t)_ucType), TX_DESC_TYPE_MASK, TX_DESC_TYPE_OFFSET) + +#define HAL_MAC_TX_DESC_IS_NDP(_prHwMacTxDesc) \ + (((_prHwMacTxDesc)->ucType_SubType & TX_DESC_NDP)?TRUE:FALSE) +#define HAL_MAC_TX_DESC_SET_NDP(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucType_SubType |= TX_DESC_NDP) +#define HAL_MAC_TX_DESC_UNSET_NDP(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucType_SubType &= ~TX_DESC_NDP) + +#define HAL_MAC_TX_DESC_IS_NDPA(_prHwMacTxDesc) \ + (((_prHwMacTxDesc)->ucType_SubType & TX_DESC_NDPA)?TRUE:FALSE) +#define HAL_MAC_TX_DESC_SET_NDPA(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucType_SubType |= TX_DESC_NDPA) +#define HAL_MAC_TX_DESC_UNSET_NDPA(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucType_SubType &= ~TX_DESC_NDPA) + +#define HAL_MAC_TX_DESC_IS_SOUNDING_FRAME(_prHwMacTxDesc) \ + (((_prHwMacTxDesc)->ucFrag & TX_DESC_SOUNDING)?TRUE:FALSE) +#define HAL_MAC_TX_DESC_SET_SOUNDING_FRAME(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucFrag |= TX_DESC_SOUNDING) +#define HAL_MAC_TX_DESC_UNSET_SOUNDING_FRAME(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucFrag &= ~TX_DESC_SOUNDING) + +#define HAL_MAC_TX_DESC_IS_FORCE_RTS_CTS_EN(_prHwMacTxDesc) \ + (((_prHwMacTxDesc)->ucFrag & TX_DESC_FORCE_RTS_CTS)?TRUE:FALSE) +#define HAL_MAC_TX_DESC_SET_FORCE_RTS_CTS(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucFrag |= TX_DESC_FORCE_RTS_CTS) +#define HAL_MAC_TX_DESC_UNSET_FORCE_RTS_CTS(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucFrag &= ~TX_DESC_FORCE_RTS_CTS) + +#define HAL_MAC_TX_DESC_IS_BMC(_prHwMacTxDesc) \ + (((_prHwMacTxDesc)->ucFrag & TX_DESC_BROADCAST_MULTICAST)?TRUE:FALSE) +#define HAL_MAC_TX_DESC_SET_BMC(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->ucFrag |= TX_DESC_BROADCAST_MULTICAST) +#define HAL_MAC_TX_DESC_UNSET_BMC(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucFrag &= ~TX_DESC_BROADCAST_MULTICAST) + +#define HAL_MAC_TX_DESC_IS_BIP(_prHwMacTxDesc) \ + (((_prHwMacTxDesc)->ucFrag & TX_DESC_BIP_PROTECTED)?TRUE:FALSE) +#define HAL_MAC_TX_DESC_SET_BIP(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucFrag |= TX_DESC_BIP_PROTECTED) +#define HAL_MAC_TX_DESC_UNSET_BIP(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucFrag &= ~TX_DESC_BIP_PROTECTED) + +#define HAL_MAC_TX_DESC_IS_DURATION_CONTROL_BY_SW(_prHwMacTxDesc) \ + (((_prHwMacTxDesc)->ucFrag & TX_DESC_DURATION_FIELD_CONTROL)?TRUE:FALSE) +#define HAL_MAC_TX_DESC_SET_DURATION_CONTROL_BY_SW(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucFrag |= TX_DESC_DURATION_FIELD_CONTROL) +#define HAL_MAC_TX_DESC_SET_DURATION_CONTROL_BY_HW(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucFrag &= ~TX_DESC_DURATION_FIELD_CONTROL) + +#define HAL_MAC_TX_DESC_IS_HTC_EXIST(_prHwMacTxDesc) \ + (((_prHwMacTxDesc)->ucFrag & TX_DESC_HTC_EXISTS)?TRUE:FALSE) +#define HAL_MAC_TX_DESC_SET_HTC_EXIST(_prHwMacTxDesc) \ +((_prHwMacTxDesc)->ucFrag |= TX_DESC_HTC_EXISTS) +#define HAL_MAC_TX_DESC_UNSET_HTC_EXIST(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucFrag &= ~TX_DESC_HTC_EXISTS) + +#define HAL_MAC_TX_DESC_IS_FRAG_PACKET(_prHwMacTxDesc) \ + (((_prHwMacTxDesc)->ucFrag & TX_DESC_FRAGMENT_MASK)?TRUE:FALSE) +#define HAL_MAC_TX_DESC_GET_FRAG_PACKET_POS(_prHwMacTxDesc) \ + TX_DESC_GET_FIELD((_prHwMacTxDesc)->ucFrag, \ + TX_DESC_FRAGMENT_MASK, TX_DESC_FRAGMENT_OFFSET) +#define HAL_MAC_TX_DESC_SET_FRAG_PACKET_POS(_prHwMacTxDesc, _ucFragPos) \ + TX_DESC_SET_FIELD(((_prHwMacTxDesc)->ucFrag), ((uint8_t)_ucFragPos), \ + TX_DESC_FRAGMENT_MASK, TX_DESC_FRAGMENT_OFFSET) + +/* For driver */ +/* in unit of 32TU */ +#define HAL_MAC_TX_DESC_GET_REMAINING_LIFE_TIME(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucRemainingMaxTxTime) +#define HAL_MAC_TX_DESC_SET_REMAINING_LIFE_TIME(_prHwMacTxDesc, _ucLifeTime) \ + ((_prHwMacTxDesc)->ucRemainingMaxTxTime = (_ucLifeTime)) +/* in unit of ms (minimal value is about 40ms) */ +#define HAL_MAC_TX_DESC_GET_REMAINING_LIFE_TIME_IN_MS(_prHwMacTxDesc) \ + (TU_TO_MSEC(HAL_MAC_TX_DESC_GET_REMAINING_LIFE_TIME(_prHwMacTxDesc) \ + << TX_DESC_LIFE_TIME_UNIT_IN_POWER_OF_2)) +#define HAL_MAC_TX_DESC_SET_REMAINING_LIFE_TIME_IN_MS(_prHwMacTxDesc, \ + _u4LifeTimeMs) \ +do { \ + uint32_t u4LifeTimeInUnit = \ + ((MSEC_TO_USEC(_u4LifeTimeMs) / USEC_PER_TU) \ + >> TX_DESC_LIFE_TIME_UNIT_IN_POWER_OF_2); \ + if (u4LifeTimeInUnit >= BIT(8)) \ + u4LifeTimeInUnit = BITS(0, 7); \ + else if ((_u4LifeTimeMs != TX_DESC_TX_TIME_NO_LIMIT) && \ + (u4LifeTimeInUnit == TX_DESC_TX_TIME_NO_LIMIT)) \ + u4LifeTimeInUnit = 1; \ + HAL_MAC_TX_DESC_SET_REMAINING_LIFE_TIME(_prHwMacTxDesc, \ + (uint8_t)u4LifeTimeInUnit); \ +} while (0) + +#define HAL_MAC_TX_DESC_GET_POWER_OFFSET(_prHwMacTxDesc) \ + TX_DESC_GET_FIELD((_prHwMacTxDesc)->ucPowerOffset, \ + TX_DESC_POWER_OFFSET_MASK, 0) +#define HAL_MAC_TX_DESC_SET_POWER_OFFSET(_prHwMacTxDesc, _ucPowerOffset) \ + TX_DESC_SET_FIELD(((_prHwMacTxDesc)->ucPowerOffset), \ + ((uint8_t)_ucPowerOffset), TX_DESC_POWER_OFFSET_MASK, 0) + +#define HAL_MAC_TX_DESC_IS_BA_DISABLE(_prHwMacTxDesc) \ + (((_prHwMacTxDesc)->ucPowerOffset & TX_DESC_BA_DISABLE)?TRUE:FALSE) +#define HAL_MAC_TX_DESC_SET_BA_DISABLE(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucPowerOffset |= TX_DESC_BA_DISABLE) +#define HAL_MAC_TX_DESC_SET_BA_ENABLE(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucPowerOffset &= ~TX_DESC_BA_DISABLE) + +#define HAL_MAC_TX_DESC_IS_TIMING_MEASUREMENT(_prHwMacTxDesc) \ + (((_prHwMacTxDesc)->ucPowerOffset & TX_DESC_TIMING_MEASUREMENT) \ + ? TRUE : FALSE) +#define HAL_MAC_TX_DESC_SET_TIMING_MEASUREMENT(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucPowerOffset |= TX_DESC_TIMING_MEASUREMENT) +#define HAL_MAC_TX_DESC_UNSET_TIMING_MEASUREMENT(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucPowerOffset &= ~TX_DESC_TIMING_MEASUREMENT) + +#define HAL_MAC_TX_DESC_IS_FIXED_RATE_ENABLE(_prHwMacTxDesc) \ + (((_prHwMacTxDesc)->ucPowerOffset & TX_DESC_FIXED_RATE)?TRUE:FALSE) +#define HAL_MAC_TX_DESC_SET_FIXED_RATE_ENABLE(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucPowerOffset |= TX_DESC_FIXED_RATE) +#define HAL_MAC_TX_DESC_SET_FIXED_RATE_DISABLE(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucPowerOffset &= ~TX_DESC_FIXED_RATE) + +/* DW 3 */ +#define HAL_MAC_TX_DESC_IS_NO_ACK(_prHwMacTxDesc) \ + (((_prHwMacTxDesc)->u2TxCountLimit & TX_DESC_NO_ACK)?TRUE:FALSE) +#define HAL_MAC_TX_DESC_SET_NO_ACK(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->u2TxCountLimit |= TX_DESC_NO_ACK) +#define HAL_MAC_TX_DESC_UNSET_NO_ACK(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->u2TxCountLimit &= ~TX_DESC_NO_ACK) + +#define HAL_MAC_TX_DESC_IS_PROTECTION(_prHwMacTxDesc) \ + (((_prHwMacTxDesc)->u2TxCountLimit & TX_DESC_PROTECTED_FRAME) \ + ? TRUE : FALSE) +#define HAL_MAC_TX_DESC_SET_PROTECTION(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->u2TxCountLimit |= TX_DESC_PROTECTED_FRAME) +#define HAL_MAC_TX_DESC_UNSET_PROTECTION(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->u2TxCountLimit &= ~TX_DESC_PROTECTED_FRAME) + +#define HAL_MAC_TX_DESC_IS_EXTEND_MORE_DATA(_prHwMacTxDesc) \ + (((_prHwMacTxDesc)->u2TxCountLimit & TX_DESC_EXTEND_MORE_DATA) \ + ? TRUE : FALSE) +#define HAL_MAC_TX_DESC_SET_EXTEND_MORE_DATA(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->u2TxCountLimit |= TX_DESC_EXTEND_MORE_DATA) +#define HAL_MAC_TX_DESC_UNSET_EXTEND_MORE_DATA(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->u2TxCountLimit &= ~TX_DESC_EXTEND_MORE_DATA) + +#define HAL_MAC_TX_DESC_IS_EXTEND_EOSP(_prHwMacTxDesc) \ + (((_prHwMacTxDesc)->u2TxCountLimit & TX_DESC_EXTEND_EOSP)?TRUE:FALSE) +#define HAL_MAC_TX_DESC_SET_EXTEND_EOSP(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->u2TxCountLimit |= TX_DESC_EXTEND_EOSP) +#define HAL_MAC_TX_DESC_UNSET_EXTEND_EOSP(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->u2TxCountLimit &= ~TX_DESC_EXTEND_EOSP) + +#define HAL_MAC_TX_DESC_GET_SW_RESERVED(_prHwMacTxDesc) \ + TX_DESC_GET_FIELD((_prHwMacTxDesc)->u2TxCountLimit, \ + TX_DESC_SW_RESERVED_MASK, TX_DESC_SW_RESERVED_OFFSET) +#define HAL_MAC_TX_DESC_SET_SW_RESERVED(_prHwMacTxDesc, _ucSwReserved) \ + TX_DESC_SET_FIELD(((_prHwMacTxDesc)->u2TxCountLimit), \ + ((uint8_t)_ucSwReserved), \ + TX_DESC_SW_RESERVED_MASK, TX_DESC_SW_RESERVED_OFFSET) +#define HAL_MAC_TX_DESC_GET_TX_COUNT(_prHwMacTxDesc) \ + TX_DESC_GET_FIELD((_prHwMacTxDesc)->u2TxCountLimit, \ + TX_DESC_TX_COUNT_MASK, TX_DESC_TX_COUNT_OFFSET) +#define HAL_MAC_TX_DESC_SET_TX_COUNT(_prHwMacTxDesc, _ucTxCountLimit) \ + TX_DESC_SET_FIELD(((_prHwMacTxDesc)->u2TxCountLimit), \ + ((uint8_t)_ucTxCountLimit), \ + TX_DESC_TX_COUNT_MASK, TX_DESC_TX_COUNT_OFFSET) +#define HAL_MAC_TX_DESC_GET_REMAINING_TX_COUNT(_prHwMacTxDesc) \ + TX_DESC_GET_FIELD((_prHwMacTxDesc)->u2TxCountLimit, \ + TX_DESC_REMAINING_TX_COUNT_MASK, \ + TX_DESC_REMAINING_TX_COUNT_OFFSET) +#define HAL_MAC_TX_DESC_SET_REMAINING_TX_COUNT(_prHwMacTxDesc, \ + _ucTxCountLimit) \ + TX_DESC_SET_FIELD(((_prHwMacTxDesc)->u2TxCountLimit), \ + ((uint8_t)_ucTxCountLimit), \ + TX_DESC_REMAINING_TX_COUNT_MASK, \ + TX_DESC_REMAINING_TX_COUNT_OFFSET) +#define HAL_MAC_TX_DESC_GET_SEQUENCE_NUMBER(_prHwMacTxDesc) \ + TX_DESC_GET_FIELD((_prHwMacTxDesc)->u2SN, TX_DESC_SEQUENCE_NUMBER, 0) +#define HAL_MAC_TX_DESC_SET_SEQUENCE_NUMBER(_prHwMacTxDesc, _u2SN) \ + TX_DESC_SET_FIELD(((_prHwMacTxDesc)->u2SN), ((uint16_t)_u2SN), \ + TX_DESC_SEQUENCE_NUMBER, 0) +#define HAL_MAC_TX_DESC_SET_HW_RESERVED(_prHwMacTxDesc, _ucHwReserved) \ + TX_DESC_SET_FIELD(((_prHwMacTxDesc)->u2SN), ((uint8_t)_ucHwReserved), \ + TX_DESC_HW_RESERVED_MASK, TX_DESC_HW_RESERVED_OFFSET) +#define HAL_MAC_TX_DESC_IS_TXD_SN_VALID(_prHwMacTxDesc) \ + (((_prHwMacTxDesc)->u2SN & TX_DESC_SN_IS_VALID)?TRUE:FALSE) +#define HAL_MAC_TX_DESC_SET_TXD_SN_VALID(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->u2SN |= TX_DESC_SN_IS_VALID) +#define HAL_MAC_TX_DESC_SET_TXD_SN_INVALID(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->u2SN &= ~TX_DESC_SN_IS_VALID) + +#define HAL_MAC_TX_DESC_IS_TXD_PN_VALID(_prHwMacTxDesc) \ + (((_prHwMacTxDesc)->u2SN & TX_DESC_PN_IS_VALID)?TRUE:FALSE) +#define HAL_MAC_TX_DESC_SET_TXD_PN_VALID(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->u2SN |= TX_DESC_PN_IS_VALID) +#define HAL_MAC_TX_DESC_SET_TXD_PN_INVALID(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->u2SN &= ~TX_DESC_PN_IS_VALID) + +#define HAL_MAC_TX_DESC_ASSIGN_SN_BY_SW(_prHwMacTxDesc, _u2SN) \ +{ \ + HAL_MAC_TX_DESC_SET_SEQUENCE_NUMBER(_prHwMacTxDesc, _u2SN); \ + HAL_MAC_TX_DESC_SET_TXD_SN_VALID(_prHwMacTxDesc); \ +} +#define HAL_MAC_TX_DESC_ASSIGN_SN_BY_HW(_prHwMacTxDesc) \ +{ \ + HAL_MAC_TX_DESC_SET_SEQUENCE_NUMBER(_prHwMacTxDesc, 0); \ + HAL_MAC_TX_DESC_SET_TXD_SN_INVALID(_prHwMacTxDesc); \ +} + +/* DW 4 */ +#define HAL_MAC_TX_DESC_GET_PN(_prHwMacTxDesc, _u4PN_0_31, _u2PN_32_47) \ +{ \ + ((uint32_t)_u4PN_0_31) = (_prHwMacTxDesc)->u4PN1; \ + ((uint16_t)_u2PN_32_47) = (_prHwMacTxDesc)->u2PN2; \ +} +#define HAL_MAC_TX_DESC_SET_PN(_prHwMacTxDesc, _u4PN_0_31, _u2PN_32_47) \ +{ \ + (_prHwMacTxDesc)->u4PN1 = ((uint32_t)_u4PN_0_31); \ + (_prHwMacTxDesc)->u2PN2 = ((uint16_t)_u2PN_32_47); \ +} + +#define HAL_MAC_TX_DESC_ASSIGN_PN_BY_SW(_prTxDesc, _u4PN_0_31, _u2PN_32_47) \ +{ \ + HAL_MAC_TX_DESC_SET_PN(_prTxDesc, _u4PN_0_31, _u2PN_32_47); \ + HAL_MAC_TX_DESC_SET_TXD_PN_VALID(_prTxDesc); \ +} +#define HAL_MAC_TX_DESC_ASSIGN_PSN_BY_HW(_prHwMacTxDesc) \ +{ \ + HAL_MAC_TX_DESC_SET_PN(_prHwMacTxDesc, 0, 0); \ + HAL_MAC_TX_DESC_SET_TXD_PN_INVALID(_prHwMacTxDesc); \ +} + +/* DW 5 */ +#define HAL_MAC_TX_DESC_GET_PID(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucPID) +#define HAL_MAC_TX_DESC_SET_PID(_prHwMacTxDesc, _ucPID) \ + (((_prHwMacTxDesc)->ucPID) = (_ucPID)) + +#define HAL_MAC_TX_DESC_GET_TXS_FORMAT(_prHwMacTxDesc) \ + TX_DESC_GET_FIELD((_prHwMacTxDesc)->ucTxStatus, \ + TX_DESC_TX_STATUS_FORMAT, TX_DESC_TX_STATUS_FORMAT_OFFSET) +#define HAL_MAC_TX_DESC_SET_TXS_FORMAT(_prHwMacTxDesc, _ucTXSFormat) \ + TX_DESC_SET_FIELD(((_prHwMacTxDesc)->ucTxStatus), \ + ((uint8_t)_ucTXSFormat), \ + TX_DESC_TX_STATUS_FORMAT, TX_DESC_TX_STATUS_FORMAT_OFFSET) + +#define HAL_MAC_TX_DESC_IS_TXS_TO_MCU(_prHwMacTxDesc) \ + (((_prHwMacTxDesc)->ucTxStatus & TX_DESC_TX_STATUS_TO_MCU)?TRUE:FALSE) +#define HAL_MAC_TX_DESC_SET_TXS_TO_MCU(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucTxStatus |= TX_DESC_TX_STATUS_TO_MCU) +#define HAL_MAC_TX_DESC_UNSET_TXS_TO_MCU(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucTxStatus &= ~TX_DESC_TX_STATUS_TO_MCU) + +#define HAL_MAC_TX_DESC_IS_TXS_TO_HOST(_prHwMacTxDesc) \ + (((_prHwMacTxDesc)->ucTxStatus & TX_DESC_TX_STATUS_TO_HOST)?TRUE:FALSE) +#define HAL_MAC_TX_DESC_SET_TXS_TO_HOST(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucTxStatus |= TX_DESC_TX_STATUS_TO_HOST) +#define HAL_MAC_TX_DESC_UNSET_TXS_TO_HOST(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucTxStatus &= ~TX_DESC_TX_STATUS_TO_HOST) + +#define HAL_MAC_TX_DESC_IS_DA_FROM_WTBL(_prHwMacTxDesc) \ + (((_prHwMacTxDesc)->ucPowerOffset & TX_DESC_DA_SOURCE)?TRUE:FALSE) +#define HAL_MAC_TX_DESC_SET_DA_FROM_WTBL(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucPowerOffset |= TX_DESC_DA_SOURCE) +#define HAL_MAC_TX_DESC_SET_DA_FROM_MSDU(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucPowerOffset &= ~TX_DESC_DA_SOURCE) + +#define HAL_MAC_TX_DESC_IS_SW_PM_CONTROL(_prHwMacTxDesc) \ + (((_prHwMacTxDesc)->ucPowerOffset & TX_DESC_POWER_MANAGEMENT_CONTROL) \ + ? TRUE : FALSE) +#define HAL_MAC_TX_DESC_SET_SW_PM_CONTROL(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucPowerOffset |= TX_DESC_POWER_MANAGEMENT_CONTROL) +#define HAL_MAC_TX_DESC_SET_HW_PM_CONTROL(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->ucPowerOffset &= ~TX_DESC_POWER_MANAGEMENT_CONTROL) + +/* DW 6 */ +#define HAL_MAC_TX_DESC_SET_FR_BW(_prHwMacTxDesc, ucBw) \ + TX_DESC_SET_FIELD(((_prHwMacTxDesc)->u2AntID), \ + ((uint8_t)ucBw), TX_DESC_BANDWIDTH_MASK, TX_DESC_BANDWIDTH_OFFSET) + +#define HAL_MAC_TX_DESC_SET_FR_DYNAMIC_BW_RTS(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->u2AntID |= TX_DESC_DYNAMIC_BANDWIDTH) + +#define HAL_MAC_TX_DESC_SET_FR_ANTENNA_ID(_prHwMacTxDesc, _ucAntId) \ + TX_DESC_SET_FIELD(((_prHwMacTxDesc)->u2AntID), \ + ((uint8_t)_ucAntId), \ + TX_DESC_ANTENNA_INDEX_MASK, TX_DESC_ANTENNA_INDEX_OFFSET) + +#define HAL_MAC_TX_DESC_SET_FR_RATE(_prHwMacTxDesc, _u2RatetoFixed) \ + TX_DESC_SET_FIELD(((_prHwMacTxDesc)->u2FixedRate), \ + ((uint8_t)_u2RatetoFixed), \ + TX_DESC_FIXDE_RATE_MASK, TX_DESC_FIXDE_RATE_OFFSET) + +#define HAL_MAC_TX_DESC_SET_FR_BF(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->u2FixedRate |= TX_DESC_BF) + +#define HAL_MAC_TX_DESC_SET_FR_LDPC(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->u2FixedRate |= TX_DESC_LDPC) + +#define HAL_MAC_TX_DESC_SET_FR_SHORT_GI(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->u2FixedRate |= TX_DESC_GUARD_INTERVAL) + +#define HAL_MAC_TX_DESC_SET_FR_NORMAL_GI(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->u2FixedRate &= ~TX_DESC_GUARD_INTERVAL) + +#define HAL_MAC_TX_DESC_IS_CR_FIXED_RATE_MODE(_prHwMacTxDesc) \ + (((_prHwMacTxDesc)->u2FixedRate & TX_DESC_FIXED_RATE_MODE)?TRUE:FALSE) + +#define HAL_MAC_TX_DESC_SET_FIXED_RATE_MODE_TO_DESC(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->u2FixedRate &= ~TX_DESC_FIXED_RATE_MODE) +#define HAL_MAC_TX_DESC_SET_FIXED_RATE_MODE_TO_CR(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->u2FixedRate |= TX_DESC_FIXED_RATE_MODE) + +/* DW 7 */ +#define HAL_MAC_TX_DESC_SET_SPE_IDX_SEL(_prHwMacTxDesc, _ucSpeIdxSel) \ + TX_DESC_SET_FIELD(((_prHwMacTxDesc)->u2SwTxTime), \ + ((uint16_t)_ucSpeIdxSel), \ + TX_DESC_SPE_EXT_IDX_SEL_MASK, TX_DESC_SPE_EXT_IDX_SEL_OFFSET) +#define HAL_MAC_TX_DESC_SET_SPE_IDX(_prHwMacTxDesc, _ucSpeIdx) \ + TX_DESC_SET_FIELD(((_prHwMacTxDesc)->u2SwTxTime), \ + ((uint16_t)_ucSpeIdx), \ + TX_DESC_SPE_EXT_IDX_MASK, TX_DESC_SPE_EXT_IDX_OFFSET) + +#define HAL_MAC_TX_DESC_IS_HW_AMSDU(_prHwMacTxDesc) \ + (((_prHwMacTxDesc)->u2PseFid & TX_DESC_HW_AMSDU)?TRUE:FALSE) +#define HAL_MAC_TX_DESC_SET_HW_AMSDU(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->u2PseFid |= TX_DESC_HW_AMSDU) +#define HAL_MAC_TX_DESC_UNSET_HW_AMSDU(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->u2PseFid &= ~TX_DESC_HW_AMSDU) + +#define HAL_MAC_TX_DESC_IS_HIF_ERR(_prHwMacTxDesc) \ + (((_prHwMacTxDesc)->u2PseFid & TX_DESC_HIF_ERR)?TRUE:FALSE) +#define HAL_MAC_TX_DESC_SET_HIF_ERR(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->u2PseFid |= TX_DESC_HIF_ERR) +#define HAL_MAC_TX_DESC_UNSET_HIF_ERR(_prHwMacTxDesc) \ + ((_prHwMacTxDesc)->u2PseFid &= ~TX_DESC_HIF_ERR) + + +#define nicTxReleaseResource_PSE(prAdapter, ucTc, u4PageCount, fgReqLock) \ + nicTxReleaseResource(prAdapter, ucTc, u4PageCount, fgReqLock, FALSE) + +#define nicTxReleaseResource_PLE(prAdapter, ucTc, u4PageCount, fgReqLock) \ + nicTxReleaseResource(prAdapter, ucTc, u4PageCount, fgReqLock, TRUE) + +#if (CFG_SUPPORT_802_11AX == 1) +#define NIC_TX_PPDU_ENABLE(__pAd) \ + HAL_MCR_WR( \ + __pAd, \ + __pAd->chip_info->arb_ac_mode_addr, \ + 0x0) + +#define NIC_TX_PPDU_DISABLE(__pAd) \ + HAL_MCR_WR( \ + __pAd, \ + __pAd->chip_info->arb_ac_mode_addr, \ + 0xFFFFFFFF) +#endif /* CFG_SUPPORT_802_11AX == 1 */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +void nicTxInitialize(IN struct ADAPTER *prAdapter); + +uint32_t nicTxAcquireResource(IN struct ADAPTER *prAdapter, + IN uint8_t ucTC, IN uint32_t u4PageCount, + IN u_int8_t fgReqLock); + +uint32_t nicTxPollingResource(IN struct ADAPTER *prAdapter, + IN uint8_t ucTC); + +u_int8_t nicTxReleaseResource(IN struct ADAPTER *prAdapter, + IN uint8_t ucTc, IN uint32_t u4PageCount, + IN u_int8_t fgReqLock, IN u_int8_t fgPLE); + +void nicTxReleaseMsduResource(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfoListHead); + +uint32_t nicTxResetResource(IN struct ADAPTER *prAdapter); + +#if defined(_HIF_SDIO) +uint32_t nicTxGetAdjustableResourceCnt(IN struct ADAPTER *prAdapter); +#endif + +uint16_t nicTxGetResource(IN struct ADAPTER *prAdapter, + IN uint8_t ucTC); + +uint8_t nicTxGetFrameResourceType(IN uint8_t eFrameType, + IN struct MSDU_INFO *prMsduInfo); + +uint8_t nicTxGetCmdResourceType(IN struct CMD_INFO *prCmdInfo); + +u_int8_t nicTxSanityCheckResource(IN struct ADAPTER *prAdapter); + +void nicTxFillDesc(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, OUT uint8_t *prTxDescBuffer, + OUT uint32_t *pu4TxDescLength); + +void nicTxFillDataDesc(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo); + +void nicTxComposeSecurityFrameDesc(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, + OUT uint8_t *prTxDescBuffer, OUT uint8_t *pucTxDescLength); + +uint32_t nicTxMsduInfoList(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfoListHead); + +uint8_t nicTxGetTxQByTc(IN struct ADAPTER *prAdapter, IN uint8_t ucTc); +uint8_t nicTxGetTxDestPortIdxByTc(IN uint8_t ucTc); +uint8_t nicTxGetTxDestQIdxByTc(IN uint8_t ucTc); +uint32_t nicTxGetRemainingTxTimeByTc(IN uint8_t ucTc); +uint8_t nicTxGetTxCountLimitByTc(IN uint8_t ucTc); +#if CFG_SUPPORT_MULTITHREAD +uint32_t nicTxMsduInfoListMthread(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfoListHead); + +uint32_t nicTxMsduQueueMthread(IN struct ADAPTER *prAdapter); + +void nicTxMsduQueueByPrio(struct ADAPTER *prAdapter); +void nicTxMsduQueueByRR(struct ADAPTER *prAdapter); + +uint32_t nicTxGetMsduPendingCnt(IN struct ADAPTER *prAdapter); +#endif + +uint32_t nicTxMsduQueue(IN struct ADAPTER *prAdapter, + uint8_t ucPortIdx, struct QUE *prQue); + +uint32_t nicTxCmd(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t ucTC); + +void nicTxRelease(IN struct ADAPTER *prAdapter, + IN u_int8_t fgProcTxDoneHandler); + +void nicProcessTxInterrupt(IN struct ADAPTER *prAdapter); + +void nicTxFreeMsduInfoPacket(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfoListHead); + +void nicTxReturnMsduInfo(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfoListHead); + +u_int8_t nicTxFillMsduInfo(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, IN void *prNdisPacket); + +uint32_t nicTxAdjustTcq(IN struct ADAPTER *prAdapter); + +uint32_t nicTxFlush(IN struct ADAPTER *prAdapter); + +#if CFG_ENABLE_FW_DOWNLOAD +uint32_t nicTxInitCmd(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint16_t u2Port); + +uint32_t nicTxInitResetResource(IN struct ADAPTER *prAdapter); +#endif + +u_int8_t nicTxProcessCmdDataPacket(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo); + +uint32_t nicTxEnqueueMsdu(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo); + +uint8_t nicTxGetWlanIdx(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIdx, IN uint8_t ucStaRecIdx); + +u_int8_t nicTxIsMgmtResourceEnough(IN struct ADAPTER *prAdapter); + +uint32_t nicTxGetFreeCmdCount(IN struct ADAPTER *prAdapter); + +uint32_t nicTxGetPageCount(IN struct ADAPTER *prAdapter, + IN uint32_t u4FrameLength, IN u_int8_t fgIncludeDesc); + +uint32_t nicTxGetCmdPageCount(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo); + +uint32_t nicTxGenerateDescTemplate(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec); + +void nicTxFreeDescTemplate(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec); + +void nicTxSetHwAmsduDescTemplate(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, + IN uint8_t ucTid, IN u_int8_t fgSet); + +void nicTxFreePacket(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, IN u_int8_t fgDrop); + +void nicTxSetMngPacket(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN uint8_t ucBssIndex, + IN uint8_t ucStaRecIndex, + IN uint8_t ucMacHeaderLength, + IN uint16_t u2FrameLength, + IN PFN_TX_DONE_HANDLER pfTxDoneHandler, + IN uint8_t ucRateMode); + +void nicTxSetDataPacket(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN uint8_t ucBssIndex, + IN uint8_t ucStaRecIndex, + IN uint8_t ucMacHeaderLength, + IN uint16_t u2FrameLength, + IN PFN_TX_DONE_HANDLER pfTxDoneHandler, + IN uint8_t ucRateMode, + IN enum ENUM_TX_PACKET_SRC eSrc, IN uint8_t ucTID, + IN u_int8_t fgIs802_11Frame, IN u_int8_t fgIs1xFrame); + +void nicTxFillDescByPktOption( + IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN void *prTxDesc); + +void nicTxConfigPktOption(IN struct MSDU_INFO *prMsduInfo, + IN uint32_t u4OptionMask, IN u_int8_t fgSetOption); + +void nicTxFillDescByPktControl(struct MSDU_INFO *prMsduInfo, + void *prTxDesc); + +void nicTxConfigPktControlFlag(IN struct MSDU_INFO *prMsduInfo, + IN uint8_t ucControlFlagMask, IN u_int8_t fgSetFlag); + +void nicTxSetPktLifeTime(IN struct MSDU_INFO *prMsduInfo, + IN uint32_t u4TxLifeTimeInMs); + +void nicTxSetPktRetryLimit(IN struct MSDU_INFO *prMsduInfo, + IN uint8_t ucRetryLimit); + +void nicTxSetForceRts(IN struct MSDU_INFO *prMsduInfo, + IN int8_t fgForceRts); + +void nicTxSetPktPowerOffset(IN struct MSDU_INFO *prMsduInfo, + IN int8_t cPowerOffset); + +void nicTxSetPktSequenceNumber(IN struct MSDU_INFO *prMsduInfo, + IN uint16_t u2SN); + +void nicTxSetPktMacTxQue(IN struct MSDU_INFO *prMsduInfo, + IN uint8_t ucMacTxQue); + +void nicTxSetPktFixedRateOptionFull( + struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo, + uint16_t u2RateCode, + uint8_t ucBandwidth, + u_int8_t fgShortGI, + u_int8_t fgLDPC, + u_int8_t fgDynamicBwRts, + u_int8_t fgBeamforming, + uint8_t ucAntennaIndex); + +void nicTxSetPktFixedRateOption( + struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo, + uint16_t u2RateCode, + uint8_t ucBandwidth, + u_int8_t fgShortGI, + u_int8_t fgDynamicBwRts); + +void nicTxSetPktLowestFixedRate(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo); + +void nicTxSetPktMoreData(IN struct MSDU_INFO *prCurrentMsduInfo, + IN u_int8_t fgSetMoreDataBit); + +void nicTxSetPktEOSP(IN struct MSDU_INFO *prCurrentMsduInfo, + IN u_int8_t fgSetEOSPBit); + +uint8_t nicTxAssignPID(IN struct ADAPTER *prAdapter, + IN uint8_t ucWlanIndex); + +uint32_t +nicTxDummyTxDone(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN enum ENUM_TX_RESULT_CODE rTxDoneStatus); + +void nicTxUpdateBssDefaultRate(IN struct BSS_INFO *prBssInfo); + +void nicTxUpdateStaRecDefaultRate(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec); + +void nicTxPrintMetRTP(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, IN void *prPacket, + IN uint32_t u4PacketLen, IN u_int8_t bFreeSkb); + +void nicTxProcessTxDoneEvent(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent); + +void nicTxChangeDataPortByAc( + struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + uint8_t ucAci, + u_int8_t fgToMcu); + +void nicTxHandleRoamingDone(struct ADAPTER *prAdapter, + struct STA_RECORD *prOldStaRec, + struct STA_RECORD *prNewStaRec); + +void nicTxMsduDoneCb(IN struct GLUE_INFO *prGlueInfo, IN struct QUE *prQue); + +void nicTxCancelSendingCmd(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo); +uint32_t nicTxGetMaxPageCntPerFrame(IN struct ADAPTER *prAdapter); + +/* TX Direct functions : BEGIN */ +void nicTxDirectStartCheckQTimer(IN struct ADAPTER *prAdapter); +void nicTxDirectClearSkbQ(IN struct ADAPTER *prAdapter); +void nicTxDirectClearHifQ(IN struct ADAPTER *prAdapter); +void nicTxDirectClearStaPsQ(IN struct ADAPTER *prAdapter, + uint8_t ucStaRecIndex); +void nicTxDirectClearBssAbsentQ(IN struct ADAPTER *prAdapter, + uint8_t ucBssIndex); +void nicTxDirectClearAllStaPsQ(IN struct ADAPTER *prAdapter); + +#if KERNEL_VERSION(4, 15, 0) <= LINUX_VERSION_CODE +void nicTxDirectTimerCheckSkbQ(struct timer_list *timer); +void nicTxDirectTimerCheckHifQ(struct timer_list *timer); +#else +void nicTxDirectTimerCheckSkbQ(unsigned long data); +void nicTxDirectTimerCheckHifQ(unsigned long data); +#endif + +uint32_t nicTxDirectStartXmit(struct sk_buff *prSkb, + struct GLUE_INFO *prGlueInfo); +/* TX Direct functions : END */ + +uint32_t nicTxResourceGetPleFreeCount(IN struct ADAPTER *prAdapter, + IN uint8_t ucTC); +u_int8_t nicTxResourceIsPleCtrlNeeded(IN struct ADAPTER *prAdapter, + IN uint8_t ucTC); +void nicTxResourceUpdate_v1(IN struct ADAPTER *prAdapter); + +int32_t nicTxGetVectorInfo(IN char *pcCommand, IN int i4TotalLen, + IN struct TX_VECTOR_BBP_LATCH *prTxV); + +void nicHifTxMsduDoneCb(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo); + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#endif /* _NIC_TX_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/nic_txd_v1.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/nic_txd_v1.h new file mode 100644 index 0000000000000000000000000000000000000000..e33e424c87a4f5e0f22cf78a002eaa999ebdf32c --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/nic_txd_v1.h @@ -0,0 +1,138 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/ + * MT6620_WIFI_DRIVER_V2_3/include/nic/nic_tx.h#1 + */ + +/*! \file nic_tx.h + * \brief Functions that provide TX operation in NIC's point of view. + * + * This file provides TX functions which are responsible for both Hardware + * and Software Resource Management and keep their Synchronization. + * + */ + + +#ifndef _NIC_TXD_V1_H +#define _NIC_TXD_V1_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +uint8_t nic_txd_v1_long_format_op( + void *prTxDesc, + uint8_t fgSet); +uint8_t nic_txd_v1_tid_op( + void *prTxDesc, + uint8_t ucTid, + uint8_t fgSet); +uint8_t nic_txd_v1_queue_idx_op( + void *prTxDesc, + uint8_t ucQueIdx, + uint8_t fgSet); +#if (CFG_TCP_IP_CHKSUM_OFFLOAD == 1) +void nic_txd_v1_chksum_op( + void *prTxDesc, + uint8_t ucChksumFlag); +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD == 1 */ +void nic_txd_v1_header_format_op( + void *prTxDesc, + struct MSDU_INFO *prMsduInfo); + +void nic_txd_v1_fill_by_pkt_option( + struct MSDU_INFO *prMsduInfo, + void *prTxD); + +void nic_txd_v1_compose( + struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo, + u_int32_t u4TxDescLength, + u_int8_t fgIsTemplate, + u_int8_t *prTxDescBuffer); +void nic_txd_v1_compose_security_frame( + struct ADAPTER *prAdapter, + struct CMD_INFO *prCmdInfo, + uint8_t *prTxDescBuffer, + uint8_t *pucTxDescLength); +void nic_txd_v1_set_pkt_fixed_rate_option_full( + struct MSDU_INFO *prMsduInfo, + uint16_t u2RateCode, + uint8_t ucBandwidth, + u_int8_t fgShortGI, + u_int8_t fgLDPC, + u_int8_t fgDynamicBwRts, + u_int8_t fgBeamforming, + uint8_t ucAntennaIndex); +void nic_txd_v1_set_pkt_fixed_rate_option( + struct MSDU_INFO *prMsduInfo, + uint16_t u2RateCode, + uint8_t ucBandwidth, + u_int8_t fgShortGI, + u_int8_t fgDynamicBwRts); +void nic_txd_v1_set_hw_amsdu_template( + struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + uint8_t ucTid, + u_int8_t fgSet); +void nic_txd_v1_change_data_port_by_ac( + struct STA_RECORD *prStaRec, + uint8_t ucAci, + u_int8_t fgToMcu); +#endif /* _NIC_TXD_V1_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/nic_txd_v2.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/nic_txd_v2.h new file mode 100644 index 0000000000000000000000000000000000000000..0f14ab374e235e1164f27ef85e42d9ee234b7dc6 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/nic_txd_v2.h @@ -0,0 +1,136 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/ + * MT6620_WIFI_DRIVER_V2_3/include/nic/nic_tx.h#1 + */ + +/*! \file nic_tx.h + * \brief Functions that provide TX operation in NIC's point of view. + * + * This file provides TX functions which are responsible for both Hardware + * and Software Resource Management and keep their Synchronization. + * + */ + + +#ifndef _NIC_TXD_V2_H +#define _NIC_TXD_V2_H + +#if (CFG_SUPPORT_CONNAC2X == 1) +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +uint8_t nic_txd_v2_long_format_op( + void *prTxDesc, + uint8_t fgSet); +uint8_t nic_txd_v2_tid_op( + void *prTxDesc, + uint8_t ucTid, + uint8_t fgSet); +uint8_t nic_txd_v2_queue_idx_op( + void *prTxDesc, + uint8_t ucQueIdx, + uint8_t fgSet); +#if (CFG_TCP_IP_CHKSUM_OFFLOAD == 1) +void nic_txd_v2_chksum_op( + void *prTxDesc, + uint8_t ucChksumFlag); +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD == 1 */ +void nic_txd_v2_header_format_op( + void *prTxDesc, + struct MSDU_INFO *prMsduInfo); + +void nic_txd_v2_fill_by_pkt_option( + struct MSDU_INFO *prMsduInfo, + void *prTxD); + +void nic_txd_v2_compose( + struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo, + u_int32_t u4TxDescLength, + u_int8_t fgIsTemplate, + u_int8_t *prTxDescBuffer); +void nic_txd_v2_compose_security_frame( + struct ADAPTER *prAdapter, + struct CMD_INFO *prCmdInfo, + uint8_t *prTxDescBuffer, + uint8_t *pucTxDescLength); +void nic_txd_v2_set_pkt_fixed_rate_option_full( + struct MSDU_INFO *prMsduInfo, + uint16_t u2RateCode, + uint8_t ucBandwidth, + u_int8_t fgShortGI, + u_int8_t fgLDPC, + u_int8_t fgDynamicBwRts, + u_int8_t fgBeamforming, + uint8_t ucAntennaIndex); +void nic_txd_v2_set_pkt_fixed_rate_option( + struct MSDU_INFO *prMsduInfo, + uint16_t u2RateCode, + uint8_t ucBandwidth, + u_int8_t fgShortGI, + u_int8_t fgDynamicBwRts); +void nic_txd_v2_set_hw_amsdu_template( + struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + uint8_t ucTid, + u_int8_t fgSet); +#endif /* CFG_SUPPORT_CONNAC2X == 1 */ +#endif /* _NIC_TXD_V2_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/nic_umac.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/nic_umac.h new file mode 100644 index 0000000000000000000000000000000000000000..a6a46f57668abfefdcc41abd744e007606a51833 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/nic_umac.h @@ -0,0 +1,140 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/ + * MT6620_WIFI_DRIVER_V2_3/include/nic/nic_umac.h#1 + */ + +/*! \file "nic_umac.h" + * \brief The declaration of the nic umac debug functions + * + */ + + +#ifndef _NIC_UMAC_H +#define _NIC_UMAC_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + + + + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + + + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +#define UMAC_FID_MASK 0xFFF + +#define UMAC_FID_FAULT 0xFFF + +#define UMAC_PLE_CFG_POOL_INDEX 0 +#define UMAC_PSE_CFG_POOL_INDEX 1 + +#define UMAC_PG_HIF0_GROUP_0 0 +#define UMAC_PG_HIF1_GROUP_1 1 +#define UMAC_PG_CPU_GROUP_2 2 +#define UMAC_PG_LMAC0_GROUP_3 3 +#define UMAC_PG_LMAC1_GROUP_4 4 +#define UMAC_PG_LMAC2_GROUP_5 5 +#define UMAC_PG_PLE_GROUP_6 6 + +#define UMAC_PBUF_CTRL_TOTAL_PAGE_NUM_MASK BITS(0, 11) +#define UMAC_PBUF_CTRL_TOTAL_PAGE_NUM_OFFSET 0 + +#define UMAC_FREEPG_CNT_FREEPAGE_CNT_MASK BITS(0, 11) +#define UMAC_FREEPG_CNT_FREEPAGE_CNT_OFFSET 0 + +#define UMAC_FREEPG_CNT_FFA_CNT_MASK BITS(16, 27) +#define UMAC_FREEPG_CNT_FFA_CNT_OFFSET 16 + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +OUT u_int8_t +halUmacInfoGetMiscStatus(IN struct ADAPTER *prAdapter, + IN struct UMAC_STAT2_GET *pUmacStat2Get); + +#endif /* _NIC_UMAC_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/p2p.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/p2p.h new file mode 100644 index 0000000000000000000000000000000000000000..b6ab98acfb46fec7a5ef2625e20d2baf651a8d27 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/p2p.h @@ -0,0 +1,409 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/nic/p2p.h#3 + */ + + +#ifndef _P2P_H +#define _P2P_H + +/****************************************************************************** + * C O M P I L E R F L A G S + ****************************************************************************** + */ + +/****************************************************************************** + * E X T E R N A L R E F E R E N C E S + ****************************************************************************** + */ + +/****************************************************************************** + * C O N S T A N T S + ****************************************************************************** + */ + +/* refer to 'Config Methods' in WPS */ +#define WPS_CONFIG_USBA 0x0001 +#define WPS_CONFIG_ETHERNET 0x0002 +#define WPS_CONFIG_LABEL 0x0004 +#define WPS_CONFIG_DISPLAY 0x0008 +#define WPS_CONFIG_EXT_NFC 0x0010 +#define WPS_CONFIG_INT_NFC 0x0020 +#define WPS_CONFIG_NFC 0x0040 +#define WPS_CONFIG_PBC 0x0080 +#define WPS_CONFIG_KEYPAD 0x0100 + +/* refer to 'Device Password ID' in WPS */ +#define WPS_DEV_PASSWORD_ID_PIN 0x0000 +#define WPS_DEV_PASSWORD_ID_USER 0x0001 +#define WPS_DEV_PASSWORD_ID_MACHINE 0x0002 +#define WPS_DEV_PASSWORD_ID_REKEY 0x0003 +#define WPS_DEV_PASSWORD_ID_PUSHBUTTON 0x0004 +#define WPS_DEV_PASSWORD_ID_REGISTRAR 0x0005 + +#define P2P_DEVICE_TYPE_NUM 2 +#define P2P_DEVICE_NAME_LENGTH 32 +#define P2P_NETWORK_NUM 8 +#define P2P_MEMBER_NUM 8 + +/* Device Capability Definition. */ +#define P2P_MAXIMUM_NOA_COUNT 8 + +#define P2P_MAX_AKM_SUITES 2 + +#define P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE 51 /* Contains 6 sub-band. */ + +/* Memory Size Definition. */ +#define P2P_MAXIMUM_ATTRIBUTES_CACHE_SIZE 768 +#define WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE 300 + +#define P2P_WILDCARD_SSID "DIRECT-" + +/* Device Charactoristic. */ +/* 1000 is too short , the deauth would block in the queue */ +#define P2P_AP_CHNL_HOLD_TIME_MS 5000 +#define P2P_DEFAULT_LISTEN_CHANNEL 1 + +#if (CFG_SUPPORT_DFS_MASTER == 1) +#define P2P_AP_CAC_WEATHER_CHNL_HOLD_TIME_MS (600*1000) +#endif + +#define P2P_DEAUTH_TIMEOUT_TIME_MS 1000 + +#define P2P_SAA_RETRY_COUNT 5 + +#define AP_DEFAULT_CHANNEL_2G 6 +#define AP_DEFAULT_CHANNEL_5G 36 + +/****************************************************************************** + * M A C R O S + ****************************************************************************** + */ + +#if DBG +#define ASSERT_BREAK(_exp) \ + { \ + if (!(_exp)) { \ + ASSERT(FALSE); \ + break; \ + } \ + } + +#else +#define ASSERT_BREAK(_exp) +#endif + +#define p2pChangeMediaState(_prAdapter, _prP2pBssInfo, _eNewMediaState) \ + (_prP2pBssInfo->eConnectionState = (_eNewMediaState)) + +/****************************************************************************** + * D A T A T Y P E S + ****************************************************************************** + */ +/* if driver need wait for a longger time when do p2p connection */ +enum ENUM_P2P_CONNECT_STATE { + P2P_CNN_NORMAL = 0, + P2P_CNN_GO_NEG_REQ, + P2P_CNN_GO_NEG_RESP, + P2P_CNN_GO_NEG_CONF, + P2P_CNN_INVITATION_REQ, + P2P_CNN_INVITATION_RESP, + P2P_CNN_DEV_DISC_REQ, + P2P_CNN_DEV_DISC_RESP, + P2P_CNN_PROV_DISC_REQ, + P2P_CNN_PROV_DISC_RESP +}; + +struct P2P_INFO { + uint32_t u4DeviceNum; + enum ENUM_P2P_CONNECT_STATE eConnState; + struct EVENT_P2P_DEV_DISCOVER_RESULT + arP2pDiscoverResult[CFG_MAX_NUM_BSS_LIST]; + uint8_t *pucCurrIePtr; + /* A common pool for IE of all scan results. */ + uint8_t aucCommIePool[CFG_MAX_COMMON_IE_BUF_LEN]; + uint8_t ucExtendChanFlag; +}; + +enum ENUM_P2P_PEER_TYPE { + ENUM_P2P_PEER_GROUP, + ENUM_P2P_PEER_DEVICE, + ENUM_P2P_PEER_NUM +}; + +struct P2P_DEVICE_INFO { + uint8_t aucDevAddr[PARAM_MAC_ADDR_LEN]; + uint8_t aucIfAddr[PARAM_MAC_ADDR_LEN]; + uint8_t ucDevCapabilityBitmap; + int32_t i4ConfigMethod; + uint8_t aucPrimaryDeviceType[8]; + uint8_t aucSecondaryDeviceType[8]; + uint8_t aucDeviceName[P2P_DEVICE_NAME_LENGTH]; +}; + +struct P2P_GROUP_INFO { + struct PARAM_SSID rGroupID; + struct P2P_DEVICE_INFO rGroupOwnerInfo; + uint8_t ucMemberNum; + struct P2P_DEVICE_INFO arMemberInfo[P2P_MEMBER_NUM]; +}; + +struct P2P_NETWORK_INFO { + enum ENUM_P2P_PEER_TYPE eNodeType; + + union { + struct P2P_GROUP_INFO rGroupInfo; + struct P2P_DEVICE_INFO rDeviceInfo; + } node; +}; + +struct P2P_NETWORK_LIST { + uint8_t ucNetworkNum; + struct P2P_NETWORK_INFO rP2PNetworkInfo[P2P_NETWORK_NUM]; +}; + +struct P2P_DISCONNECT_INFO { + uint8_t ucRole; + uint8_t ucRsv[3]; +}; + +struct P2P_SSID_STRUCT { + uint8_t aucSsid[32]; + uint8_t ucSsidLen; +}; + +enum ENUM_SCAN_REASON { + SCAN_REASON_UNKNOWN = 0, + SCAN_REASON_CONNECT, + SCAN_REASON_STARTAP, + SCAN_REASON_ACS, + SCAN_REASON_NUM, +}; + +struct P2P_SCAN_REQ_INFO { + enum ENUM_SCAN_TYPE eScanType; + enum ENUM_SCAN_CHANNEL eChannelSet; + uint16_t u2PassiveDewellTime; + uint8_t ucSeqNumOfScnMsg; + u_int8_t fgIsAbort; + u_int8_t fgIsScanRequest; + uint8_t ucNumChannelList; + struct RF_CHANNEL_INFO + arScanChannelList[MAXIMUM_OPERATION_CHANNEL_LIST]; + uint32_t u4BufLength; + uint8_t aucIEBuf[MAX_IE_LENGTH]; + uint8_t ucSsidNum; + enum ENUM_SCAN_REASON eScanReason; + /* Currently we can only take one SSID scan request */ + struct P2P_SSID_STRUCT arSsidStruct[SCN_SSID_MAX_NUM]; +}; + +enum P2P_VENDOR_ACS_HW_MODE { + P2P_VENDOR_ACS_HW_MODE_11B, + P2P_VENDOR_ACS_HW_MODE_11G, + P2P_VENDOR_ACS_HW_MODE_11A, + P2P_VENDOR_ACS_HW_MODE_11AD, + P2P_VENDOR_ACS_HW_MODE_11ANY +}; + +struct P2P_ACS_REQ_INFO { + uint8_t ucRoleIdx; + u_int8_t fgIsProcessing; + u_int8_t fgIsHtEnable; + u_int8_t fgIsHt40Enable; + u_int8_t fgIsVhtEnable; + enum ENUM_MAX_BANDWIDTH_SETTING eChnlBw; + enum P2P_VENDOR_ACS_HW_MODE eHwMode; + uint32_t u4LteSafeChnMask_2G; + uint32_t u4LteSafeChnMask_5G_1; + uint32_t u4LteSafeChnMask_5G_2; + + /* output only */ + uint8_t ucPrimaryCh; + uint8_t ucSecondCh; + uint8_t ucCenterFreqS1; + uint8_t ucCenterFreqS2; +}; + +struct P2P_CHNL_REQ_INFO { + struct LINK rP2pChnlReqLink; + u_int8_t fgIsChannelRequested; + uint8_t ucSeqNumOfChReq; + uint64_t u8Cookie; + uint8_t ucReqChnlNum; + enum ENUM_BAND eBand; + enum ENUM_CHNL_EXT eChnlSco; + uint8_t ucOriChnlNum; + enum ENUM_CHANNEL_WIDTH eChannelWidth; /*VHT operation ie */ + uint8_t ucCenterFreqS1; + uint8_t ucCenterFreqS2; + enum ENUM_BAND eOriBand; + enum ENUM_CHNL_EXT eOriChnlSco; + uint32_t u4MaxInterval; + enum ENUM_CH_REQ_TYPE eChnlReqType; +#if CFG_SUPPORT_NFC_BEAM_PLUS + uint32_t NFC_BEAM; /*NFC Beam + Indication */ +#endif +}; + +/* Glubal Connection Settings. */ +struct P2P_CONNECTION_SETTINGS { + /*UINT_8 ucRfChannelListSize;*/ +#if P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE + /*UINT_8 aucChannelEntriesField[P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE];*/ +#endif + + u_int8_t fgIsApMode; +#if CFG_SUPPORT_HOTSPOT_WPS_MANAGER + u_int8_t fgIsWPSMode; +#endif +}; + +struct NOA_TIMING { + u_int8_t fgIsInUse; /* Indicate if this entry is in use or not */ + uint8_t ucCount; /* Count */ + + uint8_t aucReserved[2]; + + uint32_t u4Duration; /* Duration */ + uint32_t u4Interval; /* Interval */ + uint32_t u4StartTime; /* Start Time */ +}; + +struct P2P_SPECIFIC_BSS_INFO { + /* For GO(AP) Mode - Compose TIM IE */ + /*UINT_16 u2SmallestAID;*//* TH3 multiple P2P */ + /*UINT_16 u2LargestAID;*//* TH3 multiple P2P */ + /*UINT_8 ucBitmapCtrl;*//* TH3 multiple P2P */ + /* UINT_8 aucPartialVirtualBitmap[MAX_LEN_TIM_PARTIAL_BMP]; */ + + /* For GC/GO OppPS */ + u_int8_t fgEnableOppPS; + uint16_t u2CTWindow; + + /* For GC/GO NOA */ + uint8_t ucNoAIndex; + uint8_t ucNoATimingCount; /* Number of NoA Timing */ + struct NOA_TIMING arNoATiming[P2P_MAXIMUM_NOA_COUNT]; + + u_int8_t fgIsNoaAttrExisted; + + /* For P2P Device */ + /* TH3 multiple P2P */ /* Regulatory Class for channel. */ + /*UINT_8 ucRegClass;*/ + /* Linten Channel only on channels 1, 6 and 11 in the 2.4 GHz. */ + /*UINT_8 ucListenChannel;*//* TH3 multiple P2P */ + + /* Operating Channel, should be one of channel */ + /* list in p2p connection settings. */ + uint8_t ucPreferredChannel; + enum ENUM_CHNL_EXT eRfSco; + enum ENUM_BAND eRfBand; + + /* Extended Listen Timing. */ + uint16_t u2AvailabilityPeriod; + uint16_t u2AvailabilityInterval; + + uint16_t u2AttributeLen; + uint8_t aucAttributesCache[P2P_MAXIMUM_ATTRIBUTES_CACHE_SIZE]; + + /*UINT_16 u2WscAttributeLen;*//* TH3 multiple P2P */ + /* TH3 multiple P2P */ + /*UINT_8 aucWscAttributesCache[WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE];*/ + + /*UINT_8 aucGroupID[MAC_ADDR_LEN];*//* TH3 multiple P2P */ + uint16_t u2GroupSsidLen; + uint8_t aucGroupSsid[ELEM_MAX_LEN_SSID]; + + struct PARAM_CUSTOM_NOA_PARAM_STRUCT rNoaParam; + struct PARAM_CUSTOM_OPPPS_PARAM_STRUCT rOppPsParam; + + uint32_t u4KeyMgtSuiteCount; + uint32_t au4KeyMgtSuite[P2P_MAX_AKM_SUITES]; + + uint16_t u2WpaIeLen; + uint8_t aucWpaIeBuffer[ELEM_HDR_LEN + ELEM_MAX_LEN_WPA]; + + uint16_t u2RsnIeLen; + uint8_t aucRsnIeBuffer[ELEM_HDR_LEN + ELEM_MAX_LEN_RSN]; +}; + +struct P2P_QUEUED_ACTION_FRAME { + uint8_t ucRoleIdx; + int32_t u4Freq; + uint8_t *prHeader; + uint16_t u2Length; +}; + +struct P2P_MGMT_TX_REQ_INFO { + struct LINK rTxReqLink; + struct MSDU_INFO *prMgmtTxMsdu; + u_int8_t fgIsWaitRsp; +}; + +/****************************************************************************** + * P U B L I C D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * P R I V A T E D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N D E C L A R A T I O N S + ****************************************************************************** + */ + +#endif /*_P2P_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/p2p_cmd_buf.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/p2p_cmd_buf.h new file mode 100644 index 0000000000000000000000000000000000000000..7dbf951a2078959010b78087ffd62ace38d00510 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/p2p_cmd_buf.h @@ -0,0 +1,121 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: + */ + +/*! \file "p2p_cmd_buf.h" + * \brief In this file we define the structure for Command Packet. + * + * In this file we define the structure for Command Packet and + * the control unit of MGMT Memory Pool. + */ + + +#ifndef _P2P_CMD_BUF_H +#define _P2P_CMD_BUF_H + +/****************************************************************************** + * C O M P I L E R F L A G S + ****************************************************************************** + */ + +/****************************************************************************** + * E X T E R N A L R E F E R E N C E S + ****************************************************************************** + */ + +/****************************************************************************** + * C O N S T A N T S + ****************************************************************************** + */ + +/****************************************************************************** + * M A C R O S + ****************************************************************************** + */ + +/****************************************************************************** + * D A T A T Y P E S + ****************************************************************************** + */ + +/****************************************************************************** + * P U B L I C D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * P R I V A T E D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N D E C L A R A T I O N S + ****************************************************************************** + */ + + +/*--------------------------------------------------------------*/ +/* Firmware Command Packer */ +/*--------------------------------------------------------------*/ +uint32_t +wlanoidSendSetQueryP2PCmd(IN struct ADAPTER *prAdapter, IN uint8_t ucCID, + IN uint8_t ucBssIdx, IN u_int8_t fgSetQuery, + IN u_int8_t fgNeedResp, IN u_int8_t fgIsOid, + IN PFN_CMD_DONE_HANDLER pfCmdDoneHandler, + IN PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler, + IN uint32_t u4SetQueryInfoLen, + IN uint8_t *pucInfoBuffer, OUT void *pvSetQueryBuffer, + IN uint32_t u4SetQueryBufferLen); + +#endif /* _P2P_CMD_BUF_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/p2p_mac.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/p2p_mac.h new file mode 100644 index 0000000000000000000000000000000000000000..46a54d5056913c1bff4075c6e93e0c853c902acd --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/p2p_mac.h @@ -0,0 +1,438 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/nic/p2p_mac.h#2 + */ + +/*! \file "p2p_mac.h" + * \brief Brief description. + * + * Detail description. + */ + +#ifndef _P2P_MAC_H +#define _P2P_MAC_H + +/****************************************************************************** + * C O M P I L E R F L A G S + ****************************************************************************** + */ + +/****************************************************************************** + * E X T E R N A L R E F E R E N C E S + ****************************************************************************** + */ + +/****************************************************************************** + * C O N S T A N T S + ****************************************************************************** + */ + +#define ACTION_PUBLIC_WIFI_DIRECT 9 +#define ACTION_GAS_INITIAL_REQUEST 10 +#define ACTION_GAS_INITIAL_RESPONSE 11 +#define ACTION_GAS_COMEBACK_REQUEST 12 +#define ACTION_GAS_COMEBACK_RESPONSE 13 + +/* P2P 4.2.8.1 - P2P Public Action Frame Type. */ +#define P2P_PUBLIC_ACTION_GO_NEGO_REQ 0 +#define P2P_PUBLIC_ACTION_GO_NEGO_RSP 1 +#define P2P_PUBLIC_ACTION_GO_NEGO_CFM 2 +#define P2P_PUBLIC_ACTION_INVITATION_REQ 3 +#define P2P_PUBLIC_ACTION_INVITATION_RSP 4 +#define P2P_PUBLIC_ACTION_DEV_DISCOVER_REQ 5 +#define P2P_PUBLIC_ACTION_DEV_DISCOVER_RSP 6 +#define P2P_PUBLIC_ACTION_PROV_DISCOVERY_REQ 7 +#define P2P_PUBLIC_ACTION_PROV_DISCOVERY_RSP 8 + +/* P2P 4.2.9.1 - P2P Action Frame Type */ +#define P2P_ACTION_NOTICE_OF_ABSENCE 0 +#define P2P_ACTION_P2P_PRESENCE_REQ 1 +#define P2P_ACTION_P2P_PRESENCE_RSP 2 +#define P2P_ACTION_GO_DISCOVER_REQ 3 + +#define P2P_PUBLIC_ACTION_FRAME_LEN (WLAN_MAC_MGMT_HEADER_LEN + 8) +#define P2P_ACTION_FRAME_LEN (WLAN_MAC_MGMT_HEADER_LEN + 7) + +/****************************************************************************** + * M A C R O S + ****************************************************************************** + */ + +/****************************************************************************** + * D A T A T Y P E S + ****************************************************************************** + */ + +/****************************************************************************** + * P U B L I C D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * P R I V A T E D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N D E C L A R A T I O N S + ****************************************************************************** + */ + +/* --------------- WPS Data Element Definitions --------------- */ +/* P2P 4.2.2 - General WSC Attribute */ +/* ID(2 octet) + Length(2 octets) */ +#define WSC_ATTRI_HDR_LEN 4 +#define WSC_ATTRI_MAX_LEN_VERSION 1 +#define WSC_ATTRI_MAX_LEN_DEVICE_PASSWORD_ID 2 +#define WSC_ATTRI_LEN_CONFIG_METHOD 2 + +/* --------------- WFA P2P IE --------------- */ +/* P2P 4.1.1 - P2P IE format */ +#define P2P_OUI_TYPE_LEN 4 +/* == OFFSET_OF(IE_P2P_T, aucP2PAttributes[0]) */ +#define P2P_IE_OUI_HDR (ELEM_HDR_LEN + P2P_OUI_TYPE_LEN) + +/* P2P 4.1.1 - General P2P Attribute */ +#define P2P_ATTRI_HDR_LEN 3 /* ID(1 octet) + Length(2 octets) */ + +/* P2P 4.1.1 - P2P Attribute ID definitions */ +#define P2P_ATTRI_ID_STATUS 0 +#define P2P_ATTRI_ID_REASON_CODE 1 +#define P2P_ATTRI_ID_P2P_CAPABILITY 2 +#define P2P_ATTRI_ID_P2P_DEV_ID 3 +#define P2P_ATTRI_ID_GO_INTENT 4 +#define P2P_ATTRI_ID_CFG_TIMEOUT 5 +#define P2P_ATTRI_ID_LISTEN_CHANNEL 6 +#define P2P_ATTRI_ID_P2P_GROUP_BSSID 7 +#define P2P_ATTRI_ID_EXT_LISTEN_TIMING 8 +#define P2P_ATTRI_ID_INTENDED_P2P_IF_ADDR 9 +#define P2P_ATTRI_ID_P2P_MANAGEABILITY 10 +#define P2P_ATTRI_ID_CHANNEL_LIST 11 +#define P2P_ATTRI_ID_NOTICE_OF_ABSENCE 12 +#define P2P_ATTRI_ID_P2P_DEV_INFO 13 +#define P2P_ATTRI_ID_P2P_GROUP_INFO 14 +#define P2P_ATTRI_ID_P2P_GROUP_ID 15 +#define P2P_ATTRI_ID_P2P_INTERFACE 16 +#define P2P_ATTRI_ID_OPERATING_CHANNEL 17 +#define P2P_ATTRI_ID_INVITATION_FLAG 18 +#define P2P_ATTRI_ID_VENDOR_SPECIFIC 221 + +/* Maximum Length of P2P Attributes */ +#define P2P_ATTRI_MAX_LEN_STATUS 1 /* 0 */ +#define P2P_ATTRI_MAX_LEN_REASON_CODE 1 /* 1 */ +#define P2P_ATTRI_MAX_LEN_P2P_CAPABILITY 2 /* 2 */ +#define P2P_ATTRI_MAX_LEN_P2P_DEV_ID 6 /* 3 */ +#define P2P_ATTRI_MAX_LEN_GO_INTENT 1 /* 4 */ +#define P2P_ATTRI_MAX_LEN_CFG_TIMEOUT 2 /* 5 */ +#define P2P_ATTRI_MAX_LEN_LISTEN_CHANNEL 5 /* 6 */ +#define P2P_ATTRI_MAX_LEN_P2P_GROUP_BSSID 6 /* 7 */ +#define P2P_ATTRI_MAX_LEN_EXT_LISTEN_TIMING 4 /* 8 */ +#define P2P_ATTRI_MAX_LEN_INTENDED_P2P_IF_ADDR 6 /* 9 */ +#define P2P_ATTRI_MAX_LEN_P2P_MANAGEABILITY 1 /* 10 */ +/* #define P2P_ATTRI_MAX_LEN_CHANNEL_LIST 3 + (n* (2 + num_of_ch)) *//* 11 */ +#define P2P_ATTRI_LEN_CHANNEL_LIST 3 /* 11 */ +#define P2P_ATTRI_LEN_CHANNEL_ENTRY 2 /* 11 */ + +#define P2P_MAXIMUM_ATTRIBUTE_LEN 251 + +/* P2P 4.1.2 - P2P Status definitions */ +#define P2P_STATUS_SUCCESS 0 +#define P2P_STATUS_FAIL_INFO_IS_CURRENTLY_UNAVAILABLE 1 +#define P2P_STATUS_FAIL_INCOMPATIBLE_PARAM 2 +#define P2P_STATUS_FAIL_LIMIT_REACHED 3 +#define P2P_STATUS_FAIL_INVALID_PARAM 4 +#define P2P_STATUS_FAIL_UNABLE_ACCOMMODATE_REQ 5 +#define P2P_STATUS_FAIL_PREVIOUS_PROTOCOL_ERR 6 +#define P2P_STATUS_FAIL_NO_COMMON_CHANNELS 7 +#define P2P_STATUS_FAIL_UNKNOWN_P2P_GROUP 8 +#define P2P_STATUS_FAIL_SAME_INTENT_VALUE_15 9 +#define P2P_STATUS_FAIL_INCOMPATIBLE_PROVISION_METHOD 10 +#define P2P_STATUS_FAIL_REJECTED_BY_USER 11 + +/* P2P 4.1.14 - CTWindow and OppPS Parameters definitions */ +#define P2P_CTW_OPPPS_PARAM_OPPPS_FIELD BIT(7) +#define P2P_CTW_OPPPS_PARAM_CTWINDOW_MASK BITS(0, 6) +/* Action frame categories (IEEE 802.11-2007, 7.3.1.11, Table 7-24) */ +#define WLAN_ACTION_SPECTRUM_MGMT 0 +#define WLAN_ACTION_QOS 1 +#define WLAN_ACTION_DLS 2 +#define WLAN_ACTION_BLOCK_ACK 3 +#define WLAN_ACTION_PUBLIC 4 +#define WLAN_ACTION_RADIO_MEASUREMENT 5 +#define WLAN_ACTION_FT 6 +#define WLAN_ACTION_HT 7 +#define WLAN_ACTION_SA_QUERY 8 +#define WLAN_ACTION_PROTECTED_DUAL 9 +#define WLAN_ACTION_WNM 10 +#define WLAN_ACTION_UNPROTECTED_WNM 11 +#define WLAN_ACTION_TDLS 12 +#define WLAN_ACTION_SELF_PROTECTED 15 +#define WLAN_ACTION_WMM 17 /* WMM Specification 1.1 */ +#define WLAN_ACTION_VENDOR_SPECIFIC 127 +#define P2P_IE_VENDOR_TYPE 0x506f9a09 +#define WFD_IE_VENDOR_TYPE 0x506f9a0a + +/* Public action codes */ +#define WLAN_PA_20_40_BSS_COEX 0 +#define WLAN_PA_VENDOR_SPECIFIC 9 +#define WLAN_PA_GAS_INITIAL_REQ 10 +#define WLAN_PA_GAS_INITIAL_RESP 11 +#define WLAN_PA_GAS_COMEBACK_REQ 12 +#define WLAN_PA_GAS_COMEBACK_RESP 13 +#define WLAN_TDLS_DISCOVERY_RESPONSE 14 + +/* P2P public action frames */ +enum ENUM_P2P_ACTION_FRAME_TYPE { + P2P_GO_NEG_REQ = 0, + P2P_GO_NEG_RESP = 1, + P2P_GO_NEG_CONF = 2, + P2P_INVITATION_REQ = 3, + P2P_INVITATION_RESP = 4, + P2P_DEV_DISC_REQ = 5, + P2P_DEV_DISC_RESP = 6, + P2P_PROV_DISC_REQ = 7, + P2P_PROV_DISC_RESP = 8 +}; + +/* --------------- WFA P2P IE and Attributes --------------- */ + +/* P2P 4.1.1 - P2P Information Element */ +struct IE_P2P { + uint8_t ucId; /* Element ID */ + uint8_t ucLength; /* Length */ + uint8_t aucOui[3]; /* OUI */ + uint8_t ucOuiType; /* OUI Type */ + uint8_t aucP2PAttributes[1]; /* P2P Attributes */ +} __KAL_ATTRIB_PACKED__; + +/* P2P 4.1.1 - General WSC Attribute */ +struct WSC_ATTRIBUTE { + uint16_t u2Id; /* Attribute ID */ + uint16_t u2Length; /* Length */ + uint8_t aucBody[1]; /* Body field */ +} __KAL_ATTRIB_PACKED__; + +/* P2P 4.1.2 - P2P Status Attribute */ +struct P2P_ATTRI_STATUS { + uint8_t ucId; /* Attribute ID */ + uint16_t u2Length; /* Length */ + uint8_t ucStatusCode; /* Status Code */ +} __KAL_ATTRIB_PACKED__; + +/* P2P 4.1.10 - Extended Listen Timing Attribute */ +struct P2P_ATTRI_EXT_LISTEN_TIMING { + uint8_t ucId; /* Attribute ID */ + uint16_t u2Length; /* Length */ + uint16_t u2AvailPeriod; /* Availability Period */ + uint16_t u2AvailInterval; /* Availability Interval */ +} __KAL_ATTRIB_PACKED__; + +/* P2P 4.2.8.2 P2P Public Action Frame Format */ +struct P2P_PUBLIC_ACTION_FRAME { + /* MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2Duration; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* P2P Public Action Frame Body */ + uint8_t ucCategory; /* Category, 0x04 */ + uint8_t ucAction; /* Action Value, 0x09 */ + uint8_t aucOui[3]; /* 0x50, 0x6F, 0x9A */ + uint8_t ucOuiType; /* 0x09 */ + /* GO Nego Req/Rsp/Cfm, P2P Invittion Req/Rsp, */ + uint8_t ucOuiSubtype; + /* Device Discovery Req/Rsp */ + uint8_t ucDialogToken; /* Dialog Token. */ + uint8_t aucInfoElem[1]; /* P2P IE, WSC IE. */ +} __KAL_ATTRIB_PACKED__; + +/* P2P 4.2.9.1 - General Action Frame Format. */ +struct P2P_ACTION_FRAME { + /* MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2Duration; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* P2P Action Frame Body */ + uint8_t ucCategory; /* 0x7F */ + uint8_t aucOui[3]; /* 0x50, 0x6F, 0x9A */ + uint8_t ucOuiType; /* 0x09 */ + uint8_t ucOuiSubtype; /* */ + uint8_t ucDialogToken; + uint8_t aucInfoElem[1]; +} __KAL_ATTRIB_PACKED__; + +/* P2P C.1 GAS Public Action Initial Request Frame Format */ +struct GAS_PUBLIC_ACTION_INITIAL_REQUEST_FRAME { + /* MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2Duration; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + /* P2P Public Action Frame Body */ + uint16_t u2SeqCtrl; /* Sequence Control */ + uint8_t ucCategory; /* Category, 0x04 */ + uint8_t ucAction; /* Action Value, 0x09 */ + uint8_t ucDialogToken; /* Dialog Token. */ + uint8_t aucInfoElem[1]; /* Advertisement IE. */ +} __KAL_ATTRIB_PACKED__; + +/* P2P C.2 GAS Public Action Initial Response Frame Format */ +struct GAS_PUBLIC_ACTION_INITIAL_RESPONSE_FRAME { + /* MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2Duration; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* P2P Public Action Frame Body */ + uint8_t ucCategory; /* Category, 0x04 */ + uint8_t ucAction; /* Action Value, 0x09 */ + uint8_t ucDialogToken; /* Dialog Token. */ + uint16_t u2StatusCode; /* Initial Response. */ + uint16_t u2ComebackDelay; + /* Initial Response. *//* In unit of TU. */ + uint8_t aucInfoElem[1]; /* Advertisement IE. */ +} __KAL_ATTRIB_PACKED__; + +/* P2P C.3-1 GAS Public Action Comeback Request Frame Format */ +struct GAS_PUBLIC_ACTION_COMEBACK_REQUEST_FRAME { + /* MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2Duration; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* P2P Public Action Frame Body */ + uint8_t ucCategory; /* Category, 0x04 */ + uint8_t ucAction; /* Action Value, 0x09 */ + uint8_t ucDialogToken; /* Dialog Token. */ +} __KAL_ATTRIB_PACKED__; + +/* P2P C.3-2 GAS Public Action Comeback Response Frame Format */ +struct GAS_PUBLIC_ACTION_COMEBACK_RESPONSE_FRAME { + /* MAC header */ + uint16_t u2FrameCtrl; /* Frame Control */ + uint16_t u2Duration; /* Duration */ + uint8_t aucDestAddr[MAC_ADDR_LEN]; /* DA */ + uint8_t aucSrcAddr[MAC_ADDR_LEN]; /* SA */ + uint8_t aucBSSID[MAC_ADDR_LEN]; /* BSSID */ + uint16_t u2SeqCtrl; /* Sequence Control */ + /* P2P Public Action Frame Body */ + uint8_t ucCategory; /* Category, 0x04 */ + uint8_t ucAction; /* Action Value, 0x09 */ + uint8_t ucDialogToken; /* Dialog Token. */ + uint16_t u2StatusCode; /* Comeback Response. */ + uint8_t ucFragmentID; /*Comeback Response. */ + uint16_t u2ComebackDelay; /* Comeback Response. */ + uint8_t aucInfoElem[1]; /* Advertisement IE. */ +} __KAL_ATTRIB_PACKED__; + +struct P2P_SD_VENDER_SPECIFIC_CONTENT { + /* Service Discovery Vendor-specific Content. */ + uint8_t ucOuiSubtype; /* 0x09 */ + uint16_t u2ServiceUpdateIndicator; + uint8_t aucServiceTLV[1]; +} __KAL_ATTRIB_PACKED__; + +struct P2P_SERVICE_REQUEST_TLV { + uint16_t u2Length; + uint8_t ucServiceProtocolType; + uint8_t ucServiceTransID; + uint8_t aucQueryData[1]; +} __KAL_ATTRIB_PACKED__; + +struct P2P_SERVICE_RESPONSE_TLV { + uint16_t u2Length; + uint8_t ucServiceProtocolType; + uint8_t ucServiceTransID; + uint8_t ucStatusCode; + uint8_t aucResponseData[1]; +} __KAL_ATTRIB_PACKED__; + +/* P2P 4.1.1 - General P2P Attribute */ +struct P2P_ATTRIBUTE { + uint8_t ucId; /* Attribute ID */ + uint16_t u2Length; /* Length */ + uint8_t aucBody[1]; /* Body field */ +} __KAL_ATTRIB_PACKED__; + +/* P2P 4.1.14 - Notice of Absence Attribute */ +struct P2P_ATTRI_NOA { + uint8_t ucId; /* Attribute ID */ + uint16_t u2Length; /* Length */ + uint8_t ucIndex; /* Index */ + uint8_t ucCTWOppPSParam; /* CTWindow and OppPS Parameters */ + uint8_t aucNoADesc[1]; /* NoA Descriptor */ +} __KAL_ATTRIB_PACKED__; + +struct NOA_DESCRIPTOR { + uint8_t ucCountType; /* Count/Type */ + uint32_t u4Duration; /* Duration */ + uint32_t u4Interval; /* Interval */ + uint32_t u4StartTime; /* Start Time */ +} __KAL_ATTRIB_PACKED__; +struct CHANNEL_ENTRY_FIELD { + uint8_t ucRegulatoryClass; /* Regulatory Class */ + uint8_t ucNumberOfChannels; /* Number Of Channels */ + uint8_t aucChannelList[1]; /* Channel List */ +} __KAL_ATTRIB_PACKED__; + +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/p2p_nic.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/p2p_nic.h new file mode 100644 index 0000000000000000000000000000000000000000..349c907fecf89f7cbf118094d5063575a1ea6f21 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/p2p_nic.h @@ -0,0 +1,116 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/nic/p2p_nic.h#1 + */ + +/*! \file "p2p_nic.h" + * \brief The declaration of nic functions + * + * Detail description. + */ + +#ifndef _P2P_NIC_H +#define _P2P_NIC_H + +/****************************************************************************** + * C O M P I L E R F L A G S + ****************************************************************************** + */ + +/****************************************************************************** + * E X T E R N A L R E F E R E N C E S + ****************************************************************************** + */ + +/****************************************************************************** + * C O N S T A N T S + ****************************************************************************** + */ + +/****************************************************************************** + * M A C R O S + ****************************************************************************** + */ + +/****************************************************************************** + * D A T A T Y P E S + ****************************************************************************** + */ + +/****************************************************************************** + * P U B L I C D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * P R I V A T E D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N D E C L A R A T I O N S + ****************************************************************************** + */ + +void +nicP2pMediaStateChange(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN struct EVENT_CONNECTION_STATUS *prConnectionStatus); + +void +nicRxAddP2pDevice(IN struct ADAPTER *prAdapter, + IN struct EVENT_P2P_DEV_DISCOVER_RESULT *prP2pResult, + IN uint8_t *pucRxIEBuf, + IN uint16_t u2RxIELength); + +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/p2p_nic_cmd_event.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/p2p_nic_cmd_event.h new file mode 100644 index 0000000000000000000000000000000000000000..0978fd0c1c6771c6b99e468198a095d345d0c763 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/p2p_nic_cmd_event.h @@ -0,0 +1,122 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: + * //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/nic/p2p_nic_cmd_event.h#1 + */ + +/*! \file p2p_nic_cmd_event.h + * \brief + */ + +#ifndef _P2P_NIC_CMD_EVENT_H +#define _P2P_NIC_CMD_EVENT_H + +/****************************************************************************** + * C O M P I L E R F L A G S + ****************************************************************************** + */ + +/****************************************************************************** + * E X T E R N A L R E F E R E N C E S + ****************************************************************************** + */ + +/****************************************************************************** + * C O N S T A N T S + ****************************************************************************** + */ + +/****************************************************************************** + * M A C R O S + ****************************************************************************** + */ + +/****************************************************************************** + * D A T A T Y P E S + ****************************************************************************** + */ + +/****************************************************************************** + * P U B L I C D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * P R I V A T E D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N D E C L A R A T I O N S + ****************************************************************************** + */ + +struct EVENT_P2P_DEV_DISCOVER_RESULT { +/* UINT_8 aucCommunicateAddr[MAC_ADDR_LEN]; // Deprecated. */ + uint8_t aucDeviceAddr[MAC_ADDR_LEN]; /* Device Address. */ + uint8_t aucInterfaceAddr[MAC_ADDR_LEN]; /* Device Address. */ + uint8_t ucDeviceCapabilityBitmap; + uint8_t ucGroupCapabilityBitmap; + uint16_t u2ConfigMethod; /* Configure Method. */ + struct P2P_DEVICE_TYPE rPriDevType; + uint8_t ucSecDevTypeNum; + struct P2P_DEVICE_TYPE arSecDevType[2]; + uint16_t u2NameLength; + uint8_t aucName[32]; + uint8_t *pucIeBuf; + uint16_t u2IELength; + uint8_t aucBSSID[MAC_ADDR_LEN]; + /* TODO: Service Information or PasswordID valid? */ +}; + +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/que_mgt.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/que_mgt.h new file mode 100644 index 0000000000000000000000000000000000000000..26f09beb3fa51a3fd7e9fdc42160392feb06bcd8 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/que_mgt.h @@ -0,0 +1,1256 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/ + MT6620_WIFI_DRIVER_V2_3/include/nic/que_mgt.h#2 + */ + +/*! \file "que_mgt.h" + * \brief TX/RX queues management header file + * + * The main tasks of queue management include TC-based HIF TX flow control, + * adaptive TC quota adjustment, HIF TX grant scheduling, Power-Save + * forwarding control, RX packet reordering, and RX BA agreement management. + */ + + +#ifndef _QUE_MGT_H +#define _QUE_MGT_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +extern uint8_t g_arTdlsLink[MAXNUM_TDLS_PEER]; +extern const uint8_t *apucACI2Str[4]; +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/* Queue Manager Features */ +/* 1: Indicate the last TX packet to the FW for each burst */ +#define QM_BURST_END_INFO_ENABLED 0 +/* 1: To fairly share TX resource among active STAs */ +#define QM_FORWARDING_FAIRNESS 1 +#if defined(_HIF_SDIO) +/* 1: To adaptively adjust resource for each TC */ +#define QM_ADAPTIVE_TC_RESOURCE_CTRL 1 +/* 1: To fast adjust resource for EMPTY TC (assigned resource is 0) */ +#define QM_FAST_TC_RESOURCE_CTRL 1 +#else +/* 1: To adaptively adjust resource for each TC */ +#define QM_ADAPTIVE_TC_RESOURCE_CTRL 0 +/* 1: To fast adjust resource for EMPTY TC (assigned resource is 0) */ +#define QM_FAST_TC_RESOURCE_CTRL 0 +#endif +/* 1: To print TC resource adjustment results */ +#define QM_PRINT_TC_RESOURCE_CTRL 0 +/* 1: If pkt with SSN is missing, auto advance the RX reordering window */ +#define QM_RX_WIN_SSN_AUTO_ADVANCING 1 +/* 1: Indicate the packets falling behind to OS + * before the frame with SSN is received + */ +#define QM_RX_INIT_FALL_BEHIND_PASS 1 +/* 1: Count times of TC resource empty happened */ +#define QM_TC_RESOURCE_EMPTY_COUNTER 1 + +/* Parameters */ +/* p: Update queue lengths when p TX packets are enqueued */ +#define QM_INIT_TIME_TO_UPDATE_QUE_LEN 256 +/* s: Adjust the TC resource every s updates of queue lengths */ +#define QM_INIT_TIME_TO_ADJUST_TC_RSC 2 +/* Factor for Que Len averaging */ +#define QM_QUE_LEN_MOVING_AVE_FACTOR 3 + +#define QM_MIN_RESERVED_TC0_RESOURCE 0 +#define QM_MIN_RESERVED_TC1_RESOURCE 1 +#define QM_MIN_RESERVED_TC2_RESOURCE 0 +#define QM_MIN_RESERVED_TC3_RESOURCE 0 +/* Resource for TC4 is not adjustable */ +#define QM_MIN_RESERVED_TC4_RESOURCE 2 +#define QM_MIN_RESERVED_TC5_RESOURCE 0 + +#define QM_GUARANTEED_TC0_RESOURCE 4 +#define QM_GUARANTEED_TC1_RESOURCE 4 +#define QM_GUARANTEED_TC2_RESOURCE 9 +#define QM_GUARANTEED_TC3_RESOURCE 11 +/* Resource for TC4 is not adjustable */ +#define QM_GUARANTEED_TC4_RESOURCE 2 +#define QM_GUARANTEED_TC5_RESOURCE 4 + +#define QM_EXTRA_RESERVED_RESOURCE_WHEN_BUSY 0 + +#define QM_AVERAGE_TC_RESOURCE 6 + +#define QM_ACTIVE_TC_NUM TC_NUM + +#define QM_MGMT_QUEUED_THRESHOLD 6 +#define QM_CMD_RESERVED_THRESHOLD 4 +#define QM_MGMT_QUEUED_TIMEOUT 1000 /* ms */ + +#define QM_TEST_MODE 0 +#define QM_TEST_TRIGGER_TX_COUNT 50 +#define QM_TEST_STA_REC_DETERMINATION 0 +#define QM_TEST_STA_REC_DEACTIVATION 0 +#define QM_TEST_FAIR_FORWARDING 0 + +#define QM_DEBUG_COUNTER 0 + +/* Per-STA Queues: [0] AC0, [1] AC1, [2] AC2, [3] AC3 */ +/* Per-Type Queues: [0] BMCAST */ +#define NUM_OF_PER_STA_TX_QUEUES 4 +#define NUM_OF_PER_TYPE_TX_QUEUES 1 + +/* TX Queue Index */ +/* Per-Type */ +#define TX_QUEUE_INDEX_BMCAST 0 +#define TX_QUEUE_INDEX_NO_STA_REC 0 + +/* Per-STA */ +#define TX_QUEUE_INDEX_AC0 0 +#define TX_QUEUE_INDEX_AC1 1 +#define TX_QUEUE_INDEX_AC2 2 +#define TX_QUEUE_INDEX_AC3 3 +#define TX_QUEUE_INDEX_NON_QOS TX_QUEUE_INDEX_AC1 + +#define QM_DEFAULT_USER_PRIORITY 0 + +#define QM_STA_FORWARD_COUNT_UNLIMITED 0xFFFFFFFF +/* Pending Forwarding Frame Threshold: + * + * A conservative estimated value, to reserve enough free MSDU resource for + * OS packet, rather than full consumed by the pending forwarding frame. + * + * Indeed, even if network subqueue is not stopped when no MSDU resource, the + * new arriving skb will be queued in prGlueInfo->rTxQueue and not be dropped. + */ +#define QM_FWD_PKT_QUE_THRESHOLD \ + (CFG_TX_MAX_PKT_NUM - 2 * CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD) + +/* 1 WMM-related */ +/* WMM FLAGS */ +#define WMM_FLAG_SUPPORT_WMM BIT(0) +#define WMM_FLAG_SUPPORT_WMMSA BIT(1) +#define WMM_FLAG_AC_PARAM_PRESENT BIT(2) +#define WMM_FLAG_SUPPORT_UAPSD BIT(3) + +/* WMM Admission Control Mandatory FLAGS */ +#define ACM_FLAG_ADM_NOT_REQUIRED 0 +#define ACM_FLAG_ADM_GRANTED BIT(0) +#define ACM_FLAG_ADM_REQUIRED BIT(1) + +/* WMM Power Saving FLAGS */ +#define AC_FLAG_TRIGGER_ENABLED BIT(1) +#define AC_FLAG_DELIVERY_ENABLED BIT(2) + +/* WMM-2.2.1 WMM Information Element */ +#define ELEM_MAX_LEN_WMM_INFO 7 + +/* WMM-2.2.2 WMM Parameter Element */ +#define ELEM_MAX_LEN_WMM_PARAM 24 + +/* WMM-2.2.1 WMM QoS Info field */ +#define WMM_QOS_INFO_PARAM_SET_CNT BITS(0, 3) /* Sent by AP */ +#define WMM_QOS_INFO_UAPSD BIT(7) + +#define WMM_QOS_INFO_VO_UAPSD BIT(0) /* Sent by non-AP STA */ +#define WMM_QOS_INFO_VI_UAPSD BIT(1) +#define WMM_QOS_INFO_BK_UAPSD BIT(2) +#define WMM_QOS_INFO_BE_UAPSD BIT(3) +#define WMM_QOS_INFO_MAX_SP_LEN_MASK BITS(5, 6) +#define WMM_QOS_INFO_MAX_SP_ALL 0 +#define WMM_QOS_INFO_MAX_SP_2 BIT(5) +#define WMM_QOS_INFO_MAX_SP_4 BIT(6) +#define WMM_QOS_INFO_MAX_SP_6 BITS(5, 6) + +/* -- definitions for Max SP length field */ +#define WMM_MAX_SP_LENGTH_ALL 0 +#define WMM_MAX_SP_LENGTH_2 2 +#define WMM_MAX_SP_LENGTH_4 4 +#define WMM_MAX_SP_LENGTH_6 6 + +/* WMM-2.2.2 WMM ACI/AIFSN field */ +/* -- subfields in the ACI/AIFSN field */ +#define WMM_ACIAIFSN_AIFSN BITS(0, 3) +#define WMM_ACIAIFSN_ACM BIT(4) +#define WMM_ACIAIFSN_ACI BITS(5, 6) +#define WMM_ACIAIFSN_ACI_OFFSET 5 + +/* -- definitions for ACI field */ +#define WMM_ACI_AC_BE 0 +#define WMM_ACI_AC_BK BIT(5) +#define WMM_ACI_AC_VI BIT(6) +#define WMM_ACI_AC_VO BITS(5, 6) + +#define WMM_ACI(_AC) (_AC << WMM_ACIAIFSN_ACI_OFFSET) + +/* -- definitions for ECWmin/ECWmax field */ +#define WMM_ECW_WMIN_MASK BITS(0, 3) +#define WMM_ECW_WMAX_MASK BITS(4, 7) +#define WMM_ECW_WMAX_OFFSET 4 + +#define TXM_DEFAULT_FLUSH_QUEUE_GUARD_TIME 0 /* Unit: 64 us */ + +#define QM_RX_BA_ENTRY_MISS_TIMEOUT_MS (200) +#if CFG_SUPPORT_LOWLATENCY_MODE +#define QM_RX_BA_ENTRY_MISS_TIMEOUT_MS_SHORT (50) +#endif /* CFG_SUPPORT_LOWLATENCY_MODE */ + +#if CFG_M0VE_BA_TO_DRIVER +/* MQM internal control bitmap per-bit usage + * (for operations on g_prMqm->u4FlagBitmap) + */ +#define MQM_FLAG_TSPEC_NEGO_ADD_IN_PROGRESS 0 +#define MQM_FLAG_IDLE_TX_BA_TIMER_STARTED 1 +#define MQM_FLAG_IDLE_RX_BA_TIMER_STARTED 2 + +#define MQM_IDLE_RX_BA_DETECTION 0 +#define MQM_IDLE_RX_BA_CHECK_INTERVAL 5000 /* in msec */ +#define MQM_DEL_IDLE_RXBA_THRESHOLD_BK 6 +#define MQM_DEL_IDLE_RXBA_THRESHOLD_BE 12 +#define MQM_DEL_IDLE_RXBA_THRESHOLD_VI 6 +#define MQM_DEL_IDLE_RXBA_THRESHOLD_VO 6 + +/* For indicating whether the role when generating a DELBA message */ +#define DELBA_ROLE_INITIATOR TRUE +#define DELBA_ROLE_RECIPIENT FALSE + +#define MQM_SET_FLAG(_Bitmap, _flag) { (_Bitmap) |= (BIT((_flag))); } +#define MQM_CLEAR_FLAG(_Bitmap, _flag) { (_Bitmap) &= (~BIT((_flag))); } +#define MQM_CHECK_FLAG(_Bitmap, _flag) ((_Bitmap) & (BIT((_flag)))) + +enum ENUM_BA_RESET_SEL { + MAC_ADDR_TID_MATCH = 0, + MAC_ADDR_MATCH, + ALWAYS_MATCH, + MATCH_NUM +}; + +#endif +/* BW80 NSS1 rate: MCS9 433 Mbps */ +#define QM_DEQUE_PERCENT_VHT80_NSS1 23 +/* BW40 NSS1 Max rate: 200 Mbps */ +#define QM_DEQUE_PERCENT_VHT40_NSS1 10 +/* BW20 NSS1 Max rate: 86.7Mbps */ +#define QM_DEQUE_PERCENT_VHT20_NSS1 5 + +/* BW40 NSS1 Max rate: 150 Mbps (MCS9 200Mbps)*/ +#define QM_DEQUE_PERCENT_HT40_NSS1 10 +/* BW20 NSS1 Max rate: 72.2Mbps (MCS8 86.7Mbps)*/ +#define QM_DEQUE_PERCENT_HT20_NSS1 5 + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +enum { + QM_DBG_CNT_00 = 0, + QM_DBG_CNT_01, + QM_DBG_CNT_02, + QM_DBG_CNT_03, + QM_DBG_CNT_04, + QM_DBG_CNT_05, + QM_DBG_CNT_06, + QM_DBG_CNT_07, + QM_DBG_CNT_08, + QM_DBG_CNT_09, + QM_DBG_CNT_10, + QM_DBG_CNT_11, + QM_DBG_CNT_12, + QM_DBG_CNT_13, + QM_DBG_CNT_14, + QM_DBG_CNT_15, + QM_DBG_CNT_16, + QM_DBG_CNT_17, + QM_DBG_CNT_18, + QM_DBG_CNT_19, + QM_DBG_CNT_20, + QM_DBG_CNT_21, + QM_DBG_CNT_22, + QM_DBG_CNT_23, + QM_DBG_CNT_24, + QM_DBG_CNT_25, + QM_DBG_CNT_26, + QM_DBG_CNT_27, + QM_DBG_CNT_28, + QM_DBG_CNT_29, + QM_DBG_CNT_30, + QM_DBG_CNT_31, + QM_DBG_CNT_NUM +}; + +/* Used for MAC TX */ +enum ENUM_MAC_TX_QUEUE_INDEX { + MAC_TX_QUEUE_AC0_INDEX = 0, + MAC_TX_QUEUE_AC1_INDEX, + MAC_TX_QUEUE_AC2_INDEX, + MAC_TX_QUEUE_AC3_INDEX, + MAC_TX_QUEUE_AC4_INDEX, + MAC_TX_QUEUE_AC5_INDEX, + MAC_TX_QUEUE_AC6_INDEX, + MAC_TX_QUEUE_BCN_INDEX, + MAC_TX_QUEUE_BMC_INDEX, + MAC_TX_QUEUE_NUM +}; + +struct RX_BA_ENTRY { + u_int8_t fgIsValid; + struct QUE rReOrderQue; + uint16_t u2WinStart; + uint16_t u2WinEnd; + uint16_t u2WinSize; + + /* For identifying the RX BA agreement */ + uint8_t ucStaRecIdx; + uint8_t ucTid; + + u_int8_t fgIsWaitingForPktWithSsn; + + struct TIMER rReorderBubbleTimer; + uint16_t u2FirstBubbleSn; + u_int8_t fgHasBubble; + +#if CFG_M0VE_BA_TO_DRIVER + uint8_t ucStatus; + uint8_t ucIdleCount; + uint16_t u2SnapShotSN; +#endif + /* UINT_8 ucTxBufferSize; */ + /* BOOL fgIsAcConstrain; */ + /* BOOL fgIsBaEnabled; */ +#if CFG_SUPPORT_RX_AMSDU + /* RX reorder for one MSDU in AMSDU issue */ + /* P_SW_RFB_T prMpduSwRfb; */ + uint32_t u4SeqNo; /* for statistic */ + u_int8_t fgAmsduNeedLastFrame; /* for statistic */ + uint8_t u8LastAmsduSubIdx; + u_int8_t fgIsAmsduDuplicated; + u_int8_t fgNoDrop; + uint32_t u4SNOverlapCount; +#endif +}; + +typedef uint32_t(*PFN_DEQUEUE_FUNCTION) (IN struct ADAPTER *prAdapter, + OUT struct QUE *prQue, IN uint8_t ucTC, + IN uint32_t u4CurrentQuota, + IN uint32_t *prPleCurrentQuota, IN uint32_t u4TotalQuota); + +/* The mailbox message + * (could be used for Host-To-Device or Device-To-Host Mailbox) + */ +struct MAILBOX_MSG { + /* [0]: D2HRM0R or H2DRM0R, [1]: D2HRM1R or H2DRM1R */ + uint32_t u4Msg[2]; +}; + +/* Used for adaptively adjusting TC resources */ +struct TC_RESOURCE_CTRL { + /* TC0, TC1, TC2, TC3, TC5 */ + uint32_t au4AverageQueLen[TC_NUM - 1]; +}; + +struct QUE_MGT { /* Queue Management Control Info */ + /* Per-Type Queues: [0] BMCAST or UNKNOWN-STA packets */ + struct QUE arTxQueue[NUM_OF_PER_TYPE_TX_QUEUES]; + +#if 0 + /* For TX Scheduling */ + uint8_t arRemainingTxOppt[NUM_OF_PER_STA_TX_QUEUES]; + uint8_t arCurrentTxStaIndex[NUM_OF_PER_STA_TX_QUEUES]; + +#endif + + /* Reordering Queue Parameters */ + struct RX_BA_ENTRY arRxBaTable[CFG_NUM_OF_RX_BA_AGREEMENTS]; + + /* Current number of activated + * RX BA agreements <= CFG_NUM_OF_RX_BA_AGREEMENTS + */ + uint8_t ucRxBaCount; + +#if QM_TEST_MODE + uint32_t u4PktCount; + struct ADAPTER *prAdapter; + +#if QM_TEST_FAIR_FORWARDING + uint32_t u4CurrentStaRecIndexToEnqueue; +#endif + +#endif + +#if QM_FORWARDING_FAIRNESS + /* The current resource used count + * for a STA with respect to a TC index + */ + uint32_t au4ResourceUsedCount[NUM_OF_PER_STA_TX_QUEUES]; + + /* The current serving STA with respect to a TC index */ + uint32_t au4HeadStaRecIndex[NUM_OF_PER_STA_TX_QUEUES]; + + /* For TC5 only */ + u_int8_t fgGlobalQFirst; + uint32_t u4GlobalResourceUsedCount; +#endif + +#if QM_ADAPTIVE_TC_RESOURCE_CTRL + uint32_t au4AverageQueLen[TC_NUM]; + uint32_t au4CurrentTcResource[TC_NUM]; /* unit: frame */ + /* The minimum amount of resource no matter busy or idle */ + uint32_t au4MinReservedTcResource[TC_NUM]; + /* The minimum amount of resource when extremely busy */ + uint32_t au4GuaranteedTcResource[TC_NUM]; + + uint32_t u4TimeToAdjustTcResource; + uint32_t u4TimeToUpdateQueLen; + + uint32_t u4QueLenMovingAverage; + uint32_t u4ExtraReservedTcResource; + uint32_t u4ResidualTcResource; + + /* Set to TRUE if the last TC adjustment has not been + * completely applied (i.e., waiting more TX-Done events + */ + /* to align the TC quotas to the TC resource assignment) */ + u_int8_t fgTcResourcePostAnnealing; + +#if QM_FAST_TC_RESOURCE_CTRL + u_int8_t fgTcResourceFastReaction; +#endif + + u_int8_t fgForceReassign; + +#endif + +#if QM_DEBUG_COUNTER + uint32_t au4QmDebugCounters[QM_DBG_CNT_NUM]; +#endif + + uint32_t u4TxAllowedStaCount; + +#if QM_TC_RESOURCE_EMPTY_COUNTER + uint32_t au4QmTcResourceEmptyCounter[MAX_BSSID_NUM][TC_NUM]; + uint32_t au4DequeueNoTcResourceCounter[TC_NUM]; + /* + * how many page count back during statistics intervals + */ + uint32_t au4QmTcResourceBackCounter[TC_NUM]; + /* + * how many page count used to TX frame during statistics intervals + */ + uint32_t au4QmTcUsedPageCounter[TC_NUM]; + uint32_t au4QmTcWantedPageCounter[TC_NUM]; + + uint32_t u4EnqueueCounter; + uint32_t u4DequeueCounter; +#endif + + uint32_t u4MaxForwardBufferCount; + + OS_SYSTIME rLastTxPktDumpTime; + u_int8_t fgIsTxResrouceControlEn; +}; + +struct EVENT_TX_ADDBA { + uint8_t ucStaRecIdx; + uint8_t ucTid; + uint8_t ucWinSize; + /* AMSDU in AMPDU is enabled or not (TID bitmap)*/ + uint8_t ucAmsduEnBitmap; + uint16_t u2SSN; + + /* + * AMSDU count/length limits by count *OR* length + * Count: MPDU count in an AMSDU shall not exceed ucMaxMpduCount + * Length: AMSDU length shall not exceed u4MaxMpduLen + */ + uint8_t + ucMaxMpduCount; /* Max MPDU count in an AMSDU */ + uint8_t aucReserved1[1]; + uint32_t u4MaxMpduLen; /* Max AMSDU length */ + + /* + * Note: If length of a packet < u4MinMpduLen then it shall not be + * aggregated in an AMSDU + */ + uint32_t + u4MinMpduLen; /* Min MPDU length to be AMSDU */ + uint8_t aucReserved2[16]; +}; + +struct EVENT_RX_ADDBA { + /* Fields not present in the received ADDBA_REQ */ + uint8_t ucStaRecIdx; + + /* Fields that are present in the received ADDBA_REQ */ + uint8_t ucDialogToken; /* Dialog Token chosen by the sender */ + uint16_t u2BAParameterSet; /* BA policy, TID, buffer size */ + uint16_t u2BATimeoutValue; + uint16_t u2BAStartSeqCtrl; /* SSN */ +}; + +struct EVENT_RX_DELBA { + /* Fields not present in the received ADDBA_REQ */ + uint8_t ucStaRecIdx; + uint8_t ucTid; + uint8_t aucReserved[2]; +}; + +struct EVENT_BSS_ABSENCE_PRESENCE { + /* Event Body */ + uint8_t ucBssIndex; + uint8_t ucIsAbsent; + uint8_t ucBssFreeQuota; + uint8_t aucReserved[1]; +}; + +struct EVENT_STA_CHANGE_PS_MODE { + /* Event Body */ + uint8_t ucStaRecIdx; + uint8_t ucIsInPs; + uint8_t ucUpdateMode; + uint8_t ucFreeQuota; +}; + +/* The free quota is used by PS only now */ +/* The event may be used by per STA flow conttrol in general */ +struct EVENT_STA_UPDATE_FREE_QUOTA { + /* Event Body */ + uint8_t ucStaRecIdx; + uint8_t ucUpdateMode; + uint8_t ucFreeQuota; + uint8_t aucReserved[1]; +}; + +struct EVENT_CHECK_REORDER_BUBBLE { + /* Event Body */ + uint8_t ucStaRecIdx; + uint8_t ucTid; +}; + +/* WMM-2.2.1 WMM Information Element */ +struct IE_WMM_INFO { + uint8_t ucId; /* Element ID */ + uint8_t ucLength; /* Length */ + uint8_t aucOui[3]; /* OUI */ + uint8_t ucOuiType; /* OUI Type */ + uint8_t ucOuiSubtype; /* OUI Subtype */ + uint8_t ucVersion; /* Version */ + uint8_t ucQosInfo; /* QoS Info field */ + uint8_t ucDummy[3]; /* Dummy for pack */ +}; + +struct WMM_AC_PARAM { + uint8_t ucAciAifsn; + uint8_t ucEcw; + uint16_t u2TxopLimit; +}; + +/* WMM-2.2.2 WMM Parameter Element */ +struct IE_WMM_PARAM { + uint8_t ucId; /* Element ID */ + uint8_t ucLength; /* Length */ + + /* IE Body */ + uint8_t aucOui[3]; /* OUI */ + uint8_t ucOuiType; /* OUI Type */ + uint8_t ucOuiSubtype; /* OUI Subtype */ + uint8_t ucVersion; /* Version */ + + /* WMM IE Body */ + uint8_t ucQosInfo; /* QoS Info field */ + uint8_t ucReserved; + + /* AC Parameters */ +#if 1 + struct WMM_AC_PARAM arAcParam[4]; +#else + uint8_t ucAciAifsn_BE; + uint8_t ucEcw_BE; + uint8_t aucTxopLimit_BE[2]; + + uint8_t ucAciAifsn_BG; + uint8_t ucEcw_BG; + uint8_t aucTxopLimit_BG[2]; + + uint8_t ucAciAifsn_VI; + uint8_t ucEcw_VI; + uint8_t aucTxopLimit_VI[2]; + + uint8_t ucAciAifsn_VO; + uint8_t ucEcw_VO; + uint8_t aucTxopLimit_VO[2]; +#endif +}; + +struct IE_WMM_TSPEC { + uint8_t ucId; /* Element ID */ + uint8_t ucLength; /* Length */ + uint8_t aucOui[3]; /* OUI */ + uint8_t ucOuiType; /* OUI Type */ + uint8_t ucOuiSubtype; /* OUI Subtype */ + uint8_t ucVersion; /* Version */ + /* WMM TSPEC body */ + uint8_t aucTsInfo[3]; /* TS Info */ + /* Note: Utilize PARAM_QOS_TSPEC to fill (memory copy) */ + uint8_t aucTspecBodyPart[1]; +}; + +struct IE_WMM_HDR { + uint8_t ucId; /* Element ID */ + uint8_t ucLength; /* Length */ + uint8_t aucOui[3]; /* OUI */ + uint8_t ucOuiType; /* OUI Type */ + uint8_t ucOuiSubtype; /* OUI Subtype */ + uint8_t ucVersion; /* Version */ + uint8_t aucBody[1]; /* IE body */ +}; + +struct AC_QUE_PARMS { + uint16_t u2CWmin; /*!< CWmin */ + uint16_t u2CWmax; /*!< CWmax */ + uint16_t u2TxopLimit; /*!< TXOP limit */ + uint16_t u2Aifsn; /*!< AIFSN */ + uint8_t ucGuradTime; /*!< GuardTime for STOP/FLUSH. */ + uint8_t ucIsACMSet; +}; + +#if (CFG_SUPPORT_802_11AX == 1) +/* MU EDCA parameters for each AC */ +struct _CMD_MU_EDCA_PARAMS_T { + uint8_t ucECWmin; /* CWmin */ + uint8_t ucECWmax; /* CWmax */ + uint8_t ucAifsn; /* AIFSN */ + uint8_t ucIsACMSet; + uint8_t ucMUEdcaTimer; + uint8_t aucPadding[3]; +}; +#endif + +/* WMM ACI (AC index) */ +enum ENUM_WMM_ACI { + WMM_AC_BE_INDEX = 0, + WMM_AC_BK_INDEX, + WMM_AC_VI_INDEX, + WMM_AC_VO_INDEX, + WMM_AC_INDEX_NUM +}; + +/* Used for CMD Queue Operation */ +enum ENUM_FRAME_ACTION { + FRAME_ACTION_DROP_PKT = 0, + FRAME_ACTION_QUEUE_PKT, + FRAME_ACTION_TX_PKT, + FRAME_ACTION_NUM +}; + +enum ENUM_FRAME_TYPE_IN_CMD_Q { + FRAME_TYPE_802_1X = 0, + FRAME_TYPE_MMPDU, + FRAME_TYPE_NUM +}; + +enum ENUM_FREE_QUOTA_MODET { + FREE_QUOTA_UPDATE_MODE_INIT = 0, + FREE_QUOTA_UPDATE_MODE_OVERWRITE, + FREE_QUOTA_UPDATE_MODE_INCREASE, + FREE_QUOTA_UPDATE_MODE_DECREASE +}; + +struct CMD_UPDATE_WMM_PARMS { + struct AC_QUE_PARMS arACQueParms[AC_NUM]; + uint8_t ucBssIndex; + uint8_t fgIsQBSS; + uint8_t ucWmmSet; + uint8_t aucReserved; +}; + +#if (CFG_SUPPORT_802_11AX == 1) +struct _CMD_MQM_UPDATE_MU_EDCA_PARMS_T { + /* DWORD_0 - Common Part */ + uint8_t ucCmdVer; + uint8_t aucPadding0[1]; + uint16_t u2CmdLen; /* Cmd size including common part and body */ + + /* DWORD_1 afterwards - Command Body */ + uint8_t ucBssIndex; + uint8_t fgIsQBSS; + uint8_t ucWmmSet; + uint8_t aucPadding1[1]; + + struct _CMD_MU_EDCA_PARAMS_T arMUEdcaParams[AC_NUM]; + uint8_t aucPadding[32]; +}; +#endif + +struct CMD_TX_AMPDU { + u_int8_t fgEnable; + uint8_t aucReserved[3]; +}; + +struct CMD_ADDBA_REJECT { + u_int8_t fgEnable; + uint8_t aucReserved[3]; +}; + +#if CFG_M0VE_BA_TO_DRIVER +/* The status of an TX/RX BA entry in FW + * (NEGO means the negotiation process is in progress) + */ +enum ENUM_BA_ENTRY_STATUS { + BA_ENTRY_STATUS_INVALID = 0, + BA_ENTRY_STATUS_NEGO, + BA_ENTRY_STATUS_ACTIVE, + BA_ENTRY_STATUS_DELETING +}; +#endif + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +#define QM_TX_SET_NEXT_MSDU_INFO(_prMsduInfoPreceding, _prMsduInfoNext) \ + ((((_prMsduInfoPreceding)->rQueEntry).prNext) = \ + (struct QUE_ENTRY *)(_prMsduInfoNext)) + +#define QM_TX_SET_NEXT_SW_RFB(_prSwRfbPreceding, _prSwRfbNext) \ + ((((_prSwRfbPreceding)->rQueEntry).prNext) = \ + (struct QUE_ENTRY *)(_prSwRfbNext)) + +#define QM_TX_GET_NEXT_MSDU_INFO(_prMsduInfo) \ + ((struct MSDU_INFO *)(((_prMsduInfo)->rQueEntry).prNext)) + +#define QM_RX_SET_NEXT_SW_RFB(_prSwRfbPreceding, _prSwRfbNext) \ + ((((_prSwRfbPreceding)->rQueEntry).prNext) = \ + (struct QUE_ENTRY *)(_prSwRfbNext)) + +#define QM_RX_GET_NEXT_SW_RFB(_prSwRfb) \ + ((struct SW_RFB *)(((_prSwRfb)->rQueEntry).prNext)) + +#if 0 +#define QM_GET_STA_REC_PTR_FROM_INDEX(_prAdapter, _ucIndex) \ + ((((_ucIndex) != STA_REC_INDEX_BMCAST) && \ + ((_ucIndex) != STA_REC_INDEX_NOT_FOUND)) ? \ + &(_prAdapter->arStaRec[_ucIndex]) : NULL) +#endif + +#define QM_GET_STA_REC_PTR_FROM_INDEX(_prAdapter, _ucIndex) \ + cnmGetStaRecByIndex(_prAdapter, _ucIndex) + +#if 0 +#define QM_TX_SET_MSDU_INFO_FOR_DATA_PACKET( \ + _prMsduInfo, \ + _ucTC, \ + _ucPacketType, \ + _ucFormatID, \ + _fgIs802_1x, \ + _fgIs802_11, \ + _u2PalLLH, \ + _u2AclSN, \ + _ucPsForwardingType, \ + _ucPsSessionID \ + ) \ + { \ + ASSERT(_prMsduInfo); \ + (_prMsduInfo)->ucTC = (_ucTC); \ + (_prMsduInfo)->ucPacketType = (_ucPacketType); \ + (_prMsduInfo)->ucFormatID = (_ucFormatID); \ + (_prMsduInfo)->fgIs802_1x = (_fgIs802_1x); \ + (_prMsduInfo)->fgIs802_11 = (_fgIs802_11); \ + (_prMsduInfo)->u2PalLLH = (_u2PalLLH); \ + (_prMsduInfo)->u2AclSN = (_u2AclSN); \ + (_prMsduInfo)->ucPsForwardingType = (_ucPsForwardingType); \ + (_prMsduInfo)->ucPsSessionID = (_ucPsSessionID); \ + (_prMsduInfo)->fgIsBurstEnd = (FALSE); \ + } +#else +#define QM_TX_SET_MSDU_INFO_FOR_DATA_PACKET( \ + _prMsduInfo, \ + _ucTC, \ + _ucPacketType, \ + _ucFormatID, \ + _fgIs802_1x, \ + _fgIs802_11, \ + _ucPsForwardingType \ + ) \ + { \ + ASSERT(_prMsduInfo); \ + (_prMsduInfo)->ucTC = (_ucTC); \ + (_prMsduInfo)->ucPacketType = (_ucPacketType); \ + (_prMsduInfo)->ucFormatID = (_ucFormatID); \ + (_prMsduInfo)->fgIs802_1x = (_fgIs802_1x); \ + (_prMsduInfo)->fgIs802_11 = (_fgIs802_11); \ + (_prMsduInfo)->ucPsForwardingType = (_ucPsForwardingType); \ + } +#endif + +#define QM_INIT_STA_REC( \ + _prStaRec, \ + _fgIsValid, \ + _fgIsQoS, \ + _pucMacAddr \ + ) \ + { \ + ASSERT(_prStaRec); \ + (_prStaRec)->fgIsValid = (_fgIsValid); \ + (_prStaRec)->fgIsQoS = (_fgIsQoS); \ + (_prStaRec)->fgIsInPS = FALSE; \ + (_prStaRec)->ucPsSessionID = 0xFF; \ + COPY_MAC_ADDR((_prStaRec)->aucMacAddr, (_pucMacAddr)); \ + } + +#if QM_ADAPTIVE_TC_RESOURCE_CTRL +#define QM_GET_TX_QUEUE_LEN(_prAdapter, _u4QueIdx) \ + (((_prAdapter)->rQM.au4AverageQueLen[(_u4QueIdx)] >> \ + (_prAdapter)->rQM.u4QueLenMovingAverage)) +#endif + +#define WMM_IE_OUI_TYPE(fp) (((struct IE_WMM_HDR *)(fp))->ucOuiType) +#define WMM_IE_OUI_SUBTYPE(fp) (((struct IE_WMM_HDR *)(fp))->ucOuiSubtype) +#define WMM_IE_OUI(fp) (((struct IE_WMM_HDR *)(fp))->aucOui) + +#if QM_DEBUG_COUNTER +#define QM_DBG_CNT_INC(_prQM, _index) \ + { (_prQM)->au4QmDebugCounters[(_index)]++; } +#else +#define QM_DBG_CNT_INC(_prQM, _index) {} +#endif + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +/*----------------------------------------------------------------------------*/ +/* Queue Management and STA_REC Initialization */ +/*----------------------------------------------------------------------------*/ + +void qmInit(IN struct ADAPTER *prAdapter, + IN u_int8_t isTxResrouceControlEn); + +#if QM_TEST_MODE +void qmTestCases(IN struct ADAPTER *prAdapter); +#endif + +void qmActivateStaRec(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec); + +void qmDeactivateStaRec(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec); + +void qmUpdateStaRec(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec); + +/*----------------------------------------------------------------------------*/ +/* TX-Related Queue Management */ +/*----------------------------------------------------------------------------*/ + +struct MSDU_INFO *qmFlushTxQueues(IN struct ADAPTER + *prAdapter); + +struct MSDU_INFO *qmFlushStaTxQueues(IN struct ADAPTER + *prAdapter, IN uint32_t u4StaRecIdx); + +struct MSDU_INFO *qmEnqueueTxPackets(IN struct ADAPTER + *prAdapter, IN struct MSDU_INFO *prMsduInfoListHead); + +struct MSDU_INFO *qmDequeueTxPackets(IN struct ADAPTER + *prAdapter, IN struct TX_TCQ_STATUS *prTcqStatus); + +#if CFG_SUPPORT_MULTITHREAD +struct MSDU_INFO *qmDequeueTxPacketsMthread( + IN struct ADAPTER *prAdapter, + IN struct TX_TCQ_STATUS *prTcqStatus); + +u_int8_t +qmAdjustTcQuotasMthread(IN struct ADAPTER *prAdapter, + OUT struct TX_TCQ_ADJUST *prTcqAdjust, + IN struct TX_TCQ_STATUS *prTcqStatus); +#endif + +u_int8_t qmAdjustTcQuotas(IN struct ADAPTER *prAdapter, + OUT struct TX_TCQ_ADJUST *prTcqAdjust, + IN struct TX_TCQ_STATUS *prTcqStatus); + +#if QM_ADAPTIVE_TC_RESOURCE_CTRL +void qmReassignTcResource(IN struct ADAPTER *prAdapter); + +void qmUpdateAverageTxQueLen(IN struct ADAPTER *prAdapter); + +void qmDoAdaptiveTcResourceCtrl(IN struct ADAPTER + *prAdapter); + +void qmCheckForFastTcResourceCtrl(IN struct ADAPTER + *prAdapter, IN uint8_t ucTc); + +#endif + +void qmDetermineStaRecIndex(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo); + +uint32_t qmDequeueTxPacketsFromPerStaQueues(IN struct ADAPTER + *prAdapter, OUT struct QUE *prQue, IN uint8_t ucTC, + IN uint32_t + u4CurrentQuota, + IN uint32_t + *prPleCurrentQuota, IN uint32_t u4TotalQuota); + +void qmDequeueTxPacketsFromPerTypeQueues(IN struct ADAPTER + *prAdapter, OUT struct QUE *prQue, IN uint8_t ucTC, + IN uint32_t + u4CurrentQuota, + IN uint32_t + *prPleCurrentQuota, IN uint32_t u4TotalQuota); + +uint32_t qmDequeueTxPacketsFromGlobalQueue(IN struct ADAPTER + *prAdapter, OUT struct QUE *prQue, IN uint8_t ucTC, + IN uint32_t + u4CurrentQuota, + IN uint32_t + *prPleCurrentQuota, IN uint32_t u4TotalQuota); + +void qmSetStaRecTxAllowed(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, IN u_int8_t fgIsTxAllowed); + +uint32_t gmGetDequeueQuota( + IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, + IN struct BSS_INFO *prBssInfo, + IN uint32_t u4TotalQuota +); + +/*----------------------------------------------------------------------------*/ +/* RX-Related Queue Management */ +/*----------------------------------------------------------------------------*/ + +void qmInitRxQueues(IN struct ADAPTER *prAdapter); + +struct SW_RFB *qmFlushRxQueues(IN struct ADAPTER + *prAdapter); + +struct QUE *qmDetermineStaTxQueue(IN struct ADAPTER + *prAdapter, IN struct MSDU_INFO *prMsduInfo, + IN uint8_t ucActiveTs, OUT uint8_t *pucTC); + +void qmSetTxPacketDescTemplate(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo); + +struct SW_RFB *qmHandleRxPackets(IN struct ADAPTER + *prAdapter, IN struct SW_RFB *prSwRfbListHead); + +void qmProcessPktWithReordering(IN struct ADAPTER + *prAdapter, IN struct SW_RFB *prSwRfb, + OUT struct QUE *prReturnedQue); + +void qmProcessBarFrame(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, OUT struct QUE *prReturnedQue); + +void qmInsertReorderPkt(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, + IN struct RX_BA_ENTRY *prReorderQueParm, + OUT struct QUE *prReturnedQue); + +void qmInsertFallWithinReorderPkt(IN struct ADAPTER + *prAdapter, IN struct SW_RFB *prSwRfb, + IN struct RX_BA_ENTRY *prReorderQueParm, + OUT struct QUE *prReturnedQue); + +void qmInsertFallAheadReorderPkt(IN struct ADAPTER + *prAdapter, IN struct SW_RFB *prSwRfb, + IN struct RX_BA_ENTRY *prReorderQueParm, + OUT struct QUE *prReturnedQue); + +void qmPopOutReorderPkt(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, OUT struct QUE *prReturnedQue, + IN enum ENUM_RX_STATISTIC_COUNTER eRxCounter); + +void qmPopOutDueToFallWithin(IN struct ADAPTER *prAdapter, + IN struct RX_BA_ENTRY *prReorderQueParm, + OUT struct QUE *prReturnedQue); + +void qmPopOutDueToFallAhead(IN struct ADAPTER *prAdapter, + IN struct RX_BA_ENTRY *prReorderQueParm, + OUT struct QUE *prReturnedQue); + +void qmHandleReorderBubbleTimeout(IN struct ADAPTER + *prAdapter, IN unsigned long ulParamPtr); + +void qmHandleEventCheckReorderBubble(IN struct ADAPTER *prAdapter, + struct RX_BA_ENTRY *prReorderQueParm); + +void qmHandleMailboxRxMessage(IN struct MAILBOX_MSG + prMailboxRxMsg); + +u_int8_t qmCompareSnIsLessThan(IN uint32_t u4SnLess, + IN uint32_t u4SnGreater); + +void qmHandleEventTxAddBa(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent); + +void qmHandleEventRxAddBa(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent); + +void qmHandleEventRxDelBa(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent); + +struct RX_BA_ENTRY *qmLookupRxBaEntry(IN struct ADAPTER + *prAdapter, IN uint8_t ucStaRecIdx, IN uint8_t ucTid); + +u_int8_t +qmAddRxBaEntry(IN struct ADAPTER *prAdapter, + IN uint8_t ucStaRecIdx, IN uint8_t ucTid, + IN uint16_t u2WinStart, IN uint16_t + u2WinSize); + +void qmDelRxBaEntry(IN struct ADAPTER *prAdapter, + IN uint8_t ucStaRecIdx, IN uint8_t ucTid, + IN u_int8_t fgFlushToHost); + +u_int8_t qmIsIndependentPkt(IN struct SW_RFB *prSwRfb); + +void mqmProcessAssocRsp(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, IN uint8_t *pucIE, + IN uint16_t u2IELength); + +void mqmProcessBcn(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, IN uint8_t *pucIE, + IN uint16_t u2IELength); + +#if (CFG_SUPPORT_802_11AX == 1) +u_int8_t mqmCompareMUEdcaParameters( + struct _IE_MU_EDCA_PARAM_T *prIeMUEdcaParam, + struct BSS_INFO *prBssInfo); + +u_int8_t +mqmParseMUEdcaParams( + struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb, + u_int8_t *pucIE, + u_int16_t u2IELength, + u_int8_t fgForceOverride); +#endif + +u_int8_t +mqmParseEdcaParameters(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, IN uint8_t *pucIE, + IN uint16_t u2IELength, IN + u_int8_t fgForceOverride); + +u_int8_t mqmCompareEdcaParameters(IN struct IE_WMM_PARAM + *prIeWmmParam, IN struct BSS_INFO *prBssInfo); + +void mqmFillAcQueParam(IN struct IE_WMM_PARAM *prIeWmmParam, + IN uint32_t u4AcOffset, + OUT struct AC_QUE_PARMS *prAcQueParams); + +void mqmProcessScanResult(IN struct ADAPTER *prAdapter, + IN struct BSS_DESC *prScanResult, + OUT struct STA_RECORD *prStaRec); + +uint32_t mqmFillWmmInfoIE(uint8_t *pucOutBuf, + u_int8_t fgSupportUAPSD, uint8_t ucBmpDeliveryAC, + uint8_t ucBmpTriggerAC, uint8_t ucUapsdSp); + +uint32_t mqmGenerateWmmInfoIEByStaRec(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, struct STA_RECORD *prStaRec, + uint8_t * + pucOutBuf); + +void mqmGenerateWmmInfoIE(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo); + +void mqmGenerateWmmParamIE(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo); + +#if CFG_SUPPORT_TDLS + +uint32_t mqmGenerateWmmParamIEByParam(struct ADAPTER + *prAdapter, struct BSS_INFO *prBssInfo, uint8_t *pOutBuf); +#endif + +enum ENUM_FRAME_ACTION qmGetFrameAction(IN struct ADAPTER + *prAdapter, + IN uint8_t ucBssIndex, IN uint8_t ucStaRecIdx, + IN struct MSDU_INFO *prMsduInfo, + IN enum ENUM_FRAME_TYPE_IN_CMD_Q eFrameType, + IN uint16_t u2FrameLength); + +void qmHandleEventBssAbsencePresence(IN struct ADAPTER + *prAdapter, IN struct WIFI_EVENT *prEvent); + +void qmHandleEventStaChangePsMode(IN struct ADAPTER + *prAdapter, IN struct WIFI_EVENT *prEvent); + +void mqmProcessAssocReq(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, IN uint8_t *pucIE, + IN uint16_t u2IELength); + +void qmHandleEventStaUpdateFreeQuota(IN struct ADAPTER + *prAdapter, IN struct WIFI_EVENT *prEvent); + +void +qmUpdateFreeQuota(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, IN uint8_t ucUpdateMode, + IN uint8_t ucFreeQuota); + +void qmFreeAllByBssIdx(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +uint32_t qmGetRxReorderQueuedBufferCount(IN struct ADAPTER + *prAdapter); + +uint32_t qmDumpQueueStatus(IN struct ADAPTER *prAdapter, + IN uint8_t *pucBuf, IN uint32_t u4MaxLen); + +#if CFG_M0VE_BA_TO_DRIVER +void +mqmSendDelBaFrame(IN struct ADAPTER *prAdapter, + IN u_int8_t fgIsInitiator, IN struct STA_RECORD *prStaRec, + IN uint32_t u4Tid, IN + uint32_t u4ReasonCode); + +uint32_t +mqmCallbackAddBaRspSent(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN enum ENUM_TX_RESULT_CODE rTxDoneStatus); + +void mqmTimeoutCheckIdleRxBa(IN struct ADAPTER *prAdapter, + IN unsigned long ulParamPtr); + +void +mqmRxModifyBaEntryStatus(IN struct ADAPTER *prAdapter, + IN struct RX_BA_ENTRY *prRxBaEntry, + IN enum ENUM_BA_ENTRY_STATUS eStatus); + +void mqmHandleAddBaReq(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb); + +void mqmHandleBaActionFrame(struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb); +#endif + +void qmResetTcControlResource(IN struct ADAPTER *prAdapter); +void qmAdjustTcQuotaPle(IN struct ADAPTER *prAdapter, + OUT struct TX_TCQ_ADJUST *prTcqAdjust, + IN struct TX_TCQ_STATUS *prTcqStatus); + +#if ARP_MONITER_ENABLE +void qmDetectArpNoResponse(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo); +void qmResetArpDetect(void); +void qmHandleRxArpPackets(struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb); +void qmHandleRxDhcpPackets(struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb); +#endif + +#if defined(CFG_SUPPORT_REPLAY_DETECTION) || \ + defined(CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION) +#define CCMPTSCPNNUM 6 +u_int8_t qmRxPNtoU64(uint8_t *pucPN, uint8_t uPNNum, + uint64_t *pu64Rets); +#endif + +#ifdef CFG_SUPPORT_REPLAY_DETECTION +u_int8_t qmHandleRxReplay(struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb); +#endif + +#if CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION +u_int8_t qmDetectRxInvalidEAPOL(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb); +#endif /* CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION */ + +#if CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION +u_int8_t qmAmsduAttackDetection(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb); +#endif /* CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION */ + +u_int8_t +qmIsNoDropPacket(IN struct ADAPTER *prAdapter, IN struct SW_RFB *prSwRfb); + +void qmMoveStaTxQueue(struct STA_RECORD *prSrcStaRec, + struct STA_RECORD *prDstStaRec); +void qmHandleDelTspec(struct ADAPTER *prAdapter, struct STA_RECORD *prStaRec, + enum ENUM_ACI eAci); +void qmReleaseCHAtFinishedDhcp(struct ADAPTER *prAdapter, + uint8_t ucBssIndex); +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#if QM_TEST_MODE +extern struct QUE_MGT g_rQM; +#endif +extern const uint8_t aucTid2ACI[TX_DESC_TID_NUM]; +extern const uint8_t aucACI2TxQIdx[WMM_AC_INDEX_NUM]; +extern const uint8_t arNetwork2TcResource[MAX_BSSID_NUM + + 1][NET_TC_NUM]; + +#endif /* _QUE_MGT_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/wlan_def.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/wlan_def.h new file mode 100644 index 0000000000000000000000000000000000000000..349d75bc871a1fe5613d0da957d2b88c9ff5d370 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic/wlan_def.h @@ -0,0 +1,1197 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/ + * MT6620_WIFI_DRIVER_V2_3/include/nic/wlan_def.h#1 + */ + +/*! \file "wlan_def.h" + * \brief This file includes the basic definition of WLAN + * + */ + + +#ifndef _WLAN_DEF_H +#define _WLAN_DEF_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +/* disconnect reason */ +#define DISCONNECT_REASON_CODE_RESERVED 0 +#define DISCONNECT_REASON_CODE_RADIO_LOST 1 +#define DISCONNECT_REASON_CODE_DEAUTHENTICATED 2 +#define DISCONNECT_REASON_CODE_DISASSOCIATED 3 +#define DISCONNECT_REASON_CODE_NEW_CONNECTION 4 +#define DISCONNECT_REASON_CODE_REASSOCIATION 5 +#define DISCONNECT_REASON_CODE_ROAMING 6 +#define DISCONNECT_REASON_CODE_CHIPRESET 7 +#define DISCONNECT_REASON_CODE_LOCALLY 8 +#define DISCONNECT_REASON_CODE_RADIO_LOST_TX_ERR 9 + +/* The rate definitions */ +#define TX_MODE_CCK 0x00 +#define TX_MODE_OFDM 0x40 +#define TX_MODE_HT_MM 0x80 +#define TX_MODE_HT_GF 0xC0 +#define TX_MODE_VHT 0x100 +#define TX_MODE_HE_SU 0x200 +#define TX_MODE_HE_ER_SU 0x240 +#define TX_MODE_HE_TB 0X280 + +#define RATE_CCK_SHORT_PREAMBLE 0x4 + +#define PHY_RATE_1M 0x0 +#define PHY_RATE_2M 0x1 +#define PHY_RATE_5_5M 0x2 +#define PHY_RATE_11M 0x3 +#define PHY_RATE_6M 0xB +#define PHY_RATE_9M 0xF +#define PHY_RATE_12M 0xA +#define PHY_RATE_18M 0xE +#define PHY_RATE_24M 0x9 +#define PHY_RATE_36M 0xD +#define PHY_RATE_48M 0x8 +#define PHY_RATE_54M 0xC + +#define PHY_RATE_MCS0 0x0 +#define PHY_RATE_MCS1 0x1 +#define PHY_RATE_MCS2 0x2 +#define PHY_RATE_MCS3 0x3 +#define PHY_RATE_MCS4 0x4 +#define PHY_RATE_MCS5 0x5 +#define PHY_RATE_MCS6 0x6 +#define PHY_RATE_MCS7 0x7 +#define PHY_RATE_MCS8 0x8 +#define PHY_RATE_MCS9 0x9 +#define PHY_RATE_MCS32 0x20 + +#define PHY_RATE_DCM 0x10 +#define PHY_RATE_TONE_106 0x20 + +#define RATE_CCK_1M_LONG (TX_MODE_CCK | PHY_RATE_1M) +#define RATE_CCK_2M_LONG (TX_MODE_CCK | PHY_RATE_2M) +#define RATE_CCK_5_5M_LONG (TX_MODE_CCK | PHY_RATE_5_5M) +#define RATE_CCK_11M_LONG (TX_MODE_CCK | PHY_RATE_11M) +#define RATE_CCK_2M_SHORT \ + (TX_MODE_CCK | PHY_RATE_2M | RATE_CCK_SHORT_PREAMBLE) +#define RATE_CCK_5_5M_SHORT \ + (TX_MODE_CCK | PHY_RATE_5_5M | RATE_CCK_SHORT_PREAMBLE) +#define RATE_CCK_11M_SHORT \ + (TX_MODE_CCK | PHY_RATE_11M | RATE_CCK_SHORT_PREAMBLE) +#define RATE_OFDM_6M (TX_MODE_OFDM | PHY_RATE_6M) +#define RATE_OFDM_9M (TX_MODE_OFDM | PHY_RATE_9M) +#define RATE_OFDM_12M (TX_MODE_OFDM | PHY_RATE_12M) +#define RATE_OFDM_18M (TX_MODE_OFDM | PHY_RATE_18M) +#define RATE_OFDM_24M (TX_MODE_OFDM | PHY_RATE_24M) +#define RATE_OFDM_36M (TX_MODE_OFDM | PHY_RATE_36M) +#define RATE_OFDM_48M (TX_MODE_OFDM | PHY_RATE_48M) +#define RATE_OFDM_54M (TX_MODE_OFDM | PHY_RATE_54M) + +#define RATE_MM_MCS_0 (TX_MODE_HT_MM | PHY_RATE_MCS0) +#define RATE_MM_MCS_1 (TX_MODE_HT_MM | PHY_RATE_MCS1) +#define RATE_MM_MCS_2 (TX_MODE_HT_MM | PHY_RATE_MCS2) +#define RATE_MM_MCS_3 (TX_MODE_HT_MM | PHY_RATE_MCS3) +#define RATE_MM_MCS_4 (TX_MODE_HT_MM | PHY_RATE_MCS4) +#define RATE_MM_MCS_5 (TX_MODE_HT_MM | PHY_RATE_MCS5) +#define RATE_MM_MCS_6 (TX_MODE_HT_MM | PHY_RATE_MCS6) +#define RATE_MM_MCS_7 (TX_MODE_HT_MM | PHY_RATE_MCS7) +#define RATE_MM_MCS_32 (TX_MODE_HT_MM | PHY_RATE_MCS32) + +#define RATE_GF_MCS_0 (TX_MODE_HT_GF | PHY_RATE_MCS0) +#define RATE_GF_MCS_1 (TX_MODE_HT_GF | PHY_RATE_MCS1) +#define RATE_GF_MCS_2 (TX_MODE_HT_GF | PHY_RATE_MCS2) +#define RATE_GF_MCS_3 (TX_MODE_HT_GF | PHY_RATE_MCS3) +#define RATE_GF_MCS_4 (TX_MODE_HT_GF | PHY_RATE_MCS4) +#define RATE_GF_MCS_5 (TX_MODE_HT_GF | PHY_RATE_MCS5) +#define RATE_GF_MCS_6 (TX_MODE_HT_GF | PHY_RATE_MCS6) +#define RATE_GF_MCS_7 (TX_MODE_HT_GF | PHY_RATE_MCS7) +#define RATE_GF_MCS_32 (TX_MODE_HT_GF | PHY_RATE_MCS32) + +#define RATE_VHT_MCS_0 (TX_MODE_VHT | PHY_RATE_MCS0) +#define RATE_VHT_MCS_1 (TX_MODE_VHT | PHY_RATE_MCS1) +#define RATE_VHT_MCS_2 (TX_MODE_VHT | PHY_RATE_MCS2) +#define RATE_VHT_MCS_3 (TX_MODE_VHT | PHY_RATE_MCS3) +#define RATE_VHT_MCS_4 (TX_MODE_VHT | PHY_RATE_MCS4) +#define RATE_VHT_MCS_5 (TX_MODE_VHT | PHY_RATE_MCS5) +#define RATE_VHT_MCS_6 (TX_MODE_VHT | PHY_RATE_MCS6) +#define RATE_VHT_MCS_7 (TX_MODE_VHT | PHY_RATE_MCS7) +#define RATE_VHT_MCS_8 (TX_MODE_VHT | PHY_RATE_MCS8) +#define RATE_VHT_MCS_9 (TX_MODE_VHT | PHY_RATE_MCS9) + +#define RATE_HE_ER_DCM_MCS_0 (TX_MODE_HE_ER_SU | PHY_RATE_DCM) +#define RATE_HE_ER_TONE_106_MCS_0 (TX_MODE_HE_ER_SU | PHY_RATE_TONE_106) + +#define RATE_NSTS_MASK BITS(9, 10) +#define RATE_NSTS_OFFSET 9 +#define RATE_TX_MODE_MASK BITS(6, 8) +#define RATE_TX_MODE_OFFSET 6 +#define RATE_CODE_GET_TX_MODE(_ucRateCode) \ + ((_ucRateCode & RATE_TX_MODE_MASK) >> RATE_TX_MODE_OFFSET) +#define RATE_PHY_RATE_MASK BITS(0, 5) +#define RATE_PHY_RATE_OFFSET 0 +#define RATE_CODE_GET_PHY_RATE(_ucRateCode) \ + ((_ucRateCode & RATE_PHY_RATE_MASK) >> RATE_PHY_RATE_OFFSET) +#define RATE_PHY_RATE_SHORT_PREAMBLE BIT(2) +#define RATE_CODE_IS_SHORT_PREAMBLE(_ucRateCode) \ + ((_ucRateCode & RATE_PHY_RATE_SHORT_PREAMBLE) ? TRUE : FALSE) + +#define CHNL_LIST_SZ_2G 14 +#define CHNL_LIST_SZ_5G 14 + +/*! CNM(STA_RECORD_T) related definition */ +#define CFG_STA_REC_NUM 27 + +/* PHY TYPE bit definitions */ +/* HR/DSSS PHY (clause 18) */ +#define PHY_TYPE_BIT_HR_DSSS BIT(PHY_TYPE_HR_DSSS_INDEX) +/* ERP PHY (clause 19) */ +#define PHY_TYPE_BIT_ERP BIT(PHY_TYPE_ERP_INDEX) +/* OFDM 5 GHz PHY (clause 17) */ +#define PHY_TYPE_BIT_OFDM BIT(PHY_TYPE_OFDM_INDEX) +/* HT PHY (clause 20) */ +#define PHY_TYPE_BIT_HT BIT(PHY_TYPE_HT_INDEX) +/* HT PHY (clause 22) */ +#define PHY_TYPE_BIT_VHT BIT(PHY_TYPE_VHT_INDEX) + +#if (CFG_SUPPORT_802_11AX == 1) +/* HE PHY */ +#define PHY_TYPE_BIT_HE BIT(PHY_TYPE_HE_INDEX) +#endif + +/* PHY TYPE set definitions */ +#define PHY_TYPE_SET_802_11ABGN (PHY_TYPE_BIT_OFDM | \ + PHY_TYPE_BIT_HR_DSSS | \ + PHY_TYPE_BIT_ERP | \ + PHY_TYPE_BIT_HT) + +#define PHY_TYPE_SET_802_11BGN (PHY_TYPE_BIT_HR_DSSS | \ + PHY_TYPE_BIT_ERP | \ + PHY_TYPE_BIT_HT) + +#define PHY_TYPE_SET_802_11GN (PHY_TYPE_BIT_ERP | \ + PHY_TYPE_BIT_HT) + +#define PHY_TYPE_SET_802_11AN (PHY_TYPE_BIT_OFDM | \ + PHY_TYPE_BIT_HT) + +#define PHY_TYPE_SET_802_11ABG (PHY_TYPE_BIT_OFDM | \ + PHY_TYPE_BIT_HR_DSSS | \ + PHY_TYPE_BIT_ERP) + +#define PHY_TYPE_SET_802_11BG (PHY_TYPE_BIT_HR_DSSS | \ + PHY_TYPE_BIT_ERP) + +#define PHY_TYPE_SET_802_11A (PHY_TYPE_BIT_OFDM) + +#define PHY_TYPE_SET_802_11G (PHY_TYPE_BIT_ERP) + +#define PHY_TYPE_SET_802_11B (PHY_TYPE_BIT_HR_DSSS) + +#define PHY_TYPE_SET_802_11N (PHY_TYPE_BIT_HT) + +#define PHY_TYPE_SET_802_11AC (PHY_TYPE_BIT_VHT) + +#define PHY_TYPE_SET_802_11ANAC (PHY_TYPE_BIT_OFDM | \ + PHY_TYPE_BIT_HT | \ + PHY_TYPE_BIT_VHT) + +#define PHY_TYPE_SET_802_11ABGNAC (PHY_TYPE_BIT_OFDM | \ + PHY_TYPE_BIT_HR_DSSS | \ + PHY_TYPE_BIT_ERP | \ + PHY_TYPE_BIT_HT | \ + PHY_TYPE_BIT_VHT) + +#if (CFG_SUPPORT_802_11AX == 1) +#define PHY_TYPE_SET_802_11AX (PHY_TYPE_BIT_HE) + +#define PHY_TYPE_SET_802_11ABGNACAX (PHY_TYPE_BIT_OFDM | \ + PHY_TYPE_BIT_HR_DSSS | \ + PHY_TYPE_BIT_ERP | \ + PHY_TYPE_BIT_HT | \ + PHY_TYPE_BIT_VHT | \ + PHY_TYPE_BIT_HE) +#endif /* CFG_SUPPORT_802_11AX == 1 */ + +/* Rate set bit definitions */ +#define RATE_SET_BIT_1M BIT(RATE_1M_SW_INDEX) /* Bit 0: 1M */ +#define RATE_SET_BIT_2M BIT(RATE_2M_SW_INDEX) /* Bit 1: 2M */ +#define RATE_SET_BIT_5_5M BIT(RATE_5_5M_SW_INDEX) /* Bit 2: 5.5M */ +#define RATE_SET_BIT_11M BIT(RATE_11M_SW_INDEX) /* Bit 3: 11M */ +#define RATE_SET_BIT_22M BIT(RATE_22M_SW_INDEX) /* Bit 4: 22M */ +#define RATE_SET_BIT_33M BIT(RATE_33M_SW_INDEX) /* Bit 5: 33M */ +#define RATE_SET_BIT_6M BIT(RATE_6M_SW_INDEX) /* Bit 6: 6M */ +#define RATE_SET_BIT_9M BIT(RATE_9M_SW_INDEX) /* Bit 7: 9M */ +#define RATE_SET_BIT_12M BIT(RATE_12M_SW_INDEX) /* Bit 8: 12M */ +#define RATE_SET_BIT_18M BIT(RATE_18M_SW_INDEX) /* Bit 9: 18M */ +#define RATE_SET_BIT_24M BIT(RATE_24M_SW_INDEX) /* Bit 10: 24M */ +#define RATE_SET_BIT_36M BIT(RATE_36M_SW_INDEX) /* Bit 11: 36M */ +#define RATE_SET_BIT_48M BIT(RATE_48M_SW_INDEX) /* Bit 12: 48M */ +#define RATE_SET_BIT_54M BIT(RATE_54M_SW_INDEX) /* Bit 13: 54M */ +/* Bit 14: BSS Selector */ +#define RATE_SET_BIT_VHT_PHY BIT(RATE_VHT_PHY_SW_INDEX) +/* Bit 15: BSS Selector */ +#define RATE_SET_BIT_HT_PHY BIT(RATE_HT_PHY_SW_INDEX) + +/* Rate set definitions */ +#define RATE_SET_HR_DSSS (RATE_SET_BIT_1M | \ + RATE_SET_BIT_2M | \ + RATE_SET_BIT_5_5M | \ + RATE_SET_BIT_11M) + +#define RATE_SET_ERP (RATE_SET_BIT_1M | \ + RATE_SET_BIT_2M | \ + RATE_SET_BIT_5_5M | \ + RATE_SET_BIT_11M | \ + RATE_SET_BIT_6M | \ + RATE_SET_BIT_9M | \ + RATE_SET_BIT_12M | \ + RATE_SET_BIT_18M | \ + RATE_SET_BIT_24M | \ + RATE_SET_BIT_36M | \ + RATE_SET_BIT_48M | \ + RATE_SET_BIT_54M) + +#define RATE_SET_ERP_P2P (RATE_SET_BIT_6M | \ + RATE_SET_BIT_9M | \ + RATE_SET_BIT_12M | \ + RATE_SET_BIT_18M | \ + RATE_SET_BIT_24M | \ + RATE_SET_BIT_36M | \ + RATE_SET_BIT_48M | \ + RATE_SET_BIT_54M) + +#define RATE_SET_OFDM (RATE_SET_BIT_6M | \ + RATE_SET_BIT_9M | \ + RATE_SET_BIT_12M | \ + RATE_SET_BIT_18M | \ + RATE_SET_BIT_24M | \ + RATE_SET_BIT_36M | \ + RATE_SET_BIT_48M | \ + RATE_SET_BIT_54M) + +#define RATE_SET_HT (RATE_SET_ERP) + +#define RATE_SET_ALL_ABG RATE_SET_ERP + +#define BASIC_RATE_SET_HR_DSSS (RATE_SET_BIT_1M | \ + RATE_SET_BIT_2M) + +#define BASIC_RATE_SET_HR_DSSS_ERP (RATE_SET_BIT_1M | \ + RATE_SET_BIT_2M | \ + RATE_SET_BIT_5_5M | \ + RATE_SET_BIT_11M) + +#define BASIC_RATE_SET_ERP (RATE_SET_BIT_1M | \ + RATE_SET_BIT_2M | \ + RATE_SET_BIT_5_5M | \ + RATE_SET_BIT_11M | \ + RATE_SET_BIT_6M | \ + RATE_SET_BIT_12M | \ + RATE_SET_BIT_24M) + +#define BASIC_RATE_SET_OFDM (RATE_SET_BIT_6M | \ + RATE_SET_BIT_12M | \ + RATE_SET_BIT_24M) + +#define BASIC_RATE_SET_ERP_P2P (RATE_SET_BIT_6M | \ + RATE_SET_BIT_12M | \ + RATE_SET_BIT_24M) + +#define INITIAL_RATE_SET_RCPI_100 RATE_SET_ALL_ABG + +#define INITIAL_RATE_SET_RCPI_80 (RATE_SET_BIT_1M | \ + RATE_SET_BIT_2M | \ + RATE_SET_BIT_5_5M | \ + RATE_SET_BIT_11M | \ + RATE_SET_BIT_6M | \ + RATE_SET_BIT_9M | \ + RATE_SET_BIT_12M | \ + RATE_SET_BIT_24M) + +#define INITIAL_RATE_SET_RCPI_60 (RATE_SET_BIT_1M | \ + RATE_SET_BIT_2M | \ + RATE_SET_BIT_5_5M | \ + RATE_SET_BIT_11M | \ + RATE_SET_BIT_6M) + +#define INITIAL_RATE_SET(_rcpi) (INITIAL_RATE_SET_ ## _rcpi) + +#define RCPI_100 100 /* -60 dBm */ +#define RCPI_80 80 /* -70 dBm */ +#define RCPI_60 60 /* -80 dBm */ + +/* The number of RCPI records used to calculate their average value */ +#define MAX_NUM_RCPI_RECORDS 10 + +/* The number of RCPI records used to calculate their average value */ +#define NO_RCPI_RECORDS -128 +#define MAX_RCPI_DBM 0 +#define MIN_RCPI_DBM -100 +/* Available AID: 1 ~ 20(STA_REC_NUM) */ +#define MAX_ASSOC_ID (CFG_STA_REC_NUM) +/* NOTE(Kevin): Used in auth.c */ +#define MAX_DEAUTH_INFO_COUNT 4 +/* The minimum interval if continuously send Deauth Frame */ +#define MIN_DEAUTH_INTERVAL_MSEC 500 + +/* Authentication Type */ +#define AUTH_TYPE_OPEN_SYSTEM \ + BIT(AUTH_ALGORITHM_NUM_OPEN_SYSTEM) +#define AUTH_TYPE_SHARED_KEY \ + BIT(AUTH_ALGORITHM_NUM_SHARED_KEY) +#define AUTH_TYPE_FAST_BSS_TRANSITION \ + BIT(AUTH_ALGORITHM_NUM_FAST_BSS_TRANSITION) +#define AUTH_TYPE_SAE \ + BIT(AUTH_ALGORITHM_NUM_SAE) + +/* Authentication Retry Limit */ +#define TX_AUTH_ASSOCI_RETRY_LIMIT 2 +#define TX_AUTH_ASSOCI_RETRY_LIMIT_FOR_ROAMING 1 + +/* WMM-2.2.1 WMM Information Element */ +#define ELEM_MAX_LEN_WMM_INFO 7 + +/* */ +#define RA_ER_Disable 0 +#define RA_DCM 1 +#define RA_ER_106 2 + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +enum ENUM_HW_BSSID { + BSSID_0 = 0, + BSSID_1, + BSSID_2, + BSSID_3, + BSSID_NUM +}; + +enum ENUM_HW_MAC_ADDR { + MAC_ADDR_0 = 0, + MAC_ADDR_1, + MAC_ADDR_NUM +}; + +enum ENUM_HW_OP_MODE { + HW_OP_MODE_STA = 0, + HW_OP_MODE_AP, + HW_OP_MODE_ADHOC, + HW_OP_MODE_NUM +}; + +enum ENUM_TSF { + ENUM_LOCAL_TSF_0, + ENUM_LOCAL_TSF_1, + ENUM_LOCAL_TSF_NUM +}; + +enum HAL_TS_HW_UPDATE_MODE { + HAL_TSF_HW_UPDATE_BY_TICK_AND_RECEIVED_FRAME, + HAL_TSF_HW_UPDATE_BY_TICK_ONLY, + HAL_TSF_HW_UPDATE_BY_RECEIVED_FRAME_ONLY, + HAL_TSF_HW_UPDATE_BY_TICK_AND_RECEIVED_FRAME_AD_HOC +}; + +enum ENUM_AC { + AC0 = 0, + AC1, + AC2, + AC3, + AC_NUM +}; + +enum ENUM_NETWORK_TYPE { + NETWORK_TYPE_AIS, + NETWORK_TYPE_P2P, + NETWORK_TYPE_BOW, + NETWORK_TYPE_MBSS, + NETWORK_TYPE_NUM +}; + +/* The Type of STA Type. */ +enum ENUM_STA_TYPE_INDEX { + STA_TYPE_LEGACY_INDEX = 0, + STA_TYPE_P2P_INDEX, + STA_TYPE_BOW_INDEX, + STA_TYPE_INDEX_NUM +}; + +enum ENUM_PHY_MODE_TYPE { + PHY_MODE_CCK = 0, + PHY_MODE_OFDM = 1, + PHY_MODE_HT20 = 2, + PHY_MODE_HT40 = 3, + PHY_MODE_VHT20 = 4, + PHY_MODE_VHT40 = 5, + PHY_MODE_VHT80 = 6, + PHY_MODE_VHT160 = 7, + PHY_MODE_SU20 = 8, + PHY_MODE_SU40 = 9, + PHY_MODE_SU80 = 10, + PHY_MODE_RU26 = 11, + PHY_MODE_RU52 = 12, + PHY_MODE_RU106 = 13, + PHY_MODE_RU242 = 14, + PHY_MODE_RU484 = 15, + PHY_MODE_RU996 = 16, + PHY_MODE_TYPE_NUM +}; + + +#define STA_ROLE_BASE_INDEX 4 + +enum ENUM_STA_ROLE_INDEX { + STA_ROLE_ADHOC_INDEX = STA_ROLE_BASE_INDEX, /* 4 */ + STA_ROLE_CLIENT_INDEX, + STA_ROLE_AP_INDEX, + STA_ROLE_DLS_INDEX, + STA_ROLE_MAX_INDEX +}; + +#define STA_ROLE_INDEX_NUM (STA_ROLE_MAX_INDEX - STA_ROLE_BASE_INDEX) + +/* The Power State of a specific Network */ +enum ENUM_PWR_STATE { + PWR_STATE_IDLE = 0, + PWR_STATE_ACTIVE, + PWR_STATE_PS, + PWR_STATE_NUM +}; + +enum ENUM_PHY_TYPE_INDEX { + /* PHY_TYPE_DSSS_INDEX, *//* DSSS PHY (clause 15) -- Not used anymore */ + PHY_TYPE_HR_DSSS_INDEX = 0, /* HR/DSSS PHY (clause 18) */ + PHY_TYPE_ERP_INDEX, /* ERP PHY (clause 19) */ + PHY_TYPE_ERP_P2P_INDEX, /* ERP PHY (clause 19) w/o HR/DSSS */ + PHY_TYPE_OFDM_INDEX, /* OFDM 5 GHz PHY (clause 17) */ + PHY_TYPE_HT_INDEX, /* HT PHY (clause 20) */ + PHY_TYPE_VHT_INDEX, /* HT PHY (clause 22) */ +#if (CFG_SUPPORT_802_11AX == 1) + PHY_TYPE_HE_INDEX, /* HE PHY */ +#endif /* CFG_SUPPORT_802_11AX == 1 */ + + PHY_TYPE_INDEX_NUM /* 6 */ +}; + +enum ENUM_SW_RATE_INDEX { + RATE_1M_SW_INDEX = 0, /* 1M */ + RATE_2M_SW_INDEX, /* 2M */ + RATE_5_5M_SW_INDEX, /* 5.5M */ + RATE_11M_SW_INDEX, /* 11M */ + RATE_22M_SW_INDEX, /* 22M */ + RATE_33M_SW_INDEX, /* 33M */ + RATE_6M_SW_INDEX, /* 6M */ + RATE_9M_SW_INDEX, /* 9M */ + RATE_12M_SW_INDEX, /* 12M */ + RATE_18M_SW_INDEX, /* 18M */ + RATE_24M_SW_INDEX, /* 24M */ + RATE_36M_SW_INDEX, /* 36M */ + RATE_48M_SW_INDEX, /* 48M */ + RATE_54M_SW_INDEX, /* 54M */ + RATE_VHT_PHY_SW_INDEX, /* BSS Selector - VHT PHY */ + RATE_HT_PHY_SW_INDEX, /* BSS Selector - HT PHY */ + RATE_NUM_SW /* 16 */ +}; + +enum ENUM_CCK_RATE_INDEX { + RATE_1M_INDEX = 0, /* 1M */ + RATE_2M_INDEX, /* 2M */ + RATE_5_5M_INDEX, /* 5.5M */ + RATE_11M_INDEX, /* 11M */ + CCK_RATE_NUM /* 4 */ +}; + +enum ENUM_OFDM_RATE_INDEX { + RATE_6M_INDEX = 0, /* 6M */ + RATE_9M_INDEX, /* 9M */ + RATE_12M_INDEX, /* 12M */ + RATE_18M_INDEX, /* 18M */ + RATE_24M_INDEX, /* 24M */ + RATE_36M_INDEX, /* 36M */ + RATE_48M_INDEX, /* 48M */ + RATE_54M_INDEX, /* 54M */ + OFDM_RATE_NUM /* 8 */ +}; + +enum ENUM_HT_RATE_INDEX { + HT_RATE_MCS32_INDEX = 0, + HT_RATE_MCS0_INDEX, + HT_RATE_MCS1_INDEX, + HT_RATE_MCS2_INDEX, + HT_RATE_MCS3_INDEX, + HT_RATE_MCS4_INDEX, + HT_RATE_MCS5_INDEX, + HT_RATE_MCS6_INDEX, + HT_RATE_MCS7_INDEX, + HT_RATE_MCS8_INDEX, + HT_RATE_MCS9_INDEX, + HT_RATE_MCS10_INDEX, + HT_RATE_MCS11_INDEX, + HT_RATE_MCS12_INDEX, + HT_RATE_MCS13_INDEX, + HT_RATE_MCS14_INDEX, + HT_RATE_MCS15_INDEX, + HT_RATE_NUM /* 16 */ +}; + +enum ENUM_VHT_RATE_INDEX { + VHT_RATE_MCS0_INDEX = 0, + VHT_RATE_MCS1_INDEX, + VHT_RATE_MCS2_INDEX, + VHT_RATE_MCS3_INDEX, + VHT_RATE_MCS4_INDEX, + VHT_RATE_MCS5_INDEX, + VHT_RATE_MCS6_INDEX, + VHT_RATE_MCS7_INDEX, + VHT_RATE_MCS8_INDEX, + VHT_RATE_MCS9_INDEX, + VHT_RATE_NUM /* 10 */ +}; + +enum ENUM_PREMABLE_OPTION { + /* LONG for PHY_TYPE_HR_DSSS, NONE for PHY_TYPE_OFDM */ + PREAMBLE_DEFAULT_LONG_NONE = 0, + /* SHORT mandatory for PHY_TYPE_ERP, + * SHORT option for PHY_TYPE_HR_DSSS + */ + PREAMBLE_OPTION_SHORT, + PREAMBLE_OFDM_MODE, + PREAMBLE_HT_MIXED_MODE, + PREAMBLE_HT_GREEN_FIELD, + PREAMBLE_VHT_FIELD, + PREAMBLE_OPTION_NUM +}; + +enum ENUM_MODULATION_SYSTEM { + MODULATION_SYSTEM_CCK = 0, + MODULATION_SYSTEM_OFDM, + MODULATION_SYSTEM_HT20, + MODULATION_SYSTEM_HT40, + MODULATION_SYSTEM_NUM +}; + +enum ENUM_MODULATION_TYPE { + MODULATION_TYPE_CCK_BPSK = 0, + MODULATION_TYPE_QPSK, + MODULATION_TYPE_16QAM, + MODULATION_TYPE_64QAM, + MODULATION_TYPE_NUM +}; + +enum ENUM_ACPI_STATE { + ACPI_STATE_D0 = 0, + ACPI_STATE_D1, + ACPI_STATE_D2, + ACPI_STATE_D3 +}; + +/* The operation mode of a specific Network */ +enum ENUM_OP_MODE { + OP_MODE_INFRASTRUCTURE = 0, /* Infrastructure/GC */ + OP_MODE_IBSS, /* AdHoc */ + OP_MODE_ACCESS_POINT, /* For GO */ + OP_MODE_P2P_DEVICE, /* P2P Device */ + OP_MODE_BOW, + OP_MODE_NUM +}; + +/* + * NL80211 interface type. + * Refer to the definition of nl80211_iftype in kernel/nl80211.h + */ +enum ENUM_IFTYPE { + IFTYPE_UNSPECIFIED = 0, + IFTYPE_ADHOC, + IFTYPE_STATION, + IFTYPE_AP, + IFTYPE_AP_VLAN, + IFTYPE_WDS, + IFTYPE_MONITOR, + IFTYPE_MESH_POINT, + IFTYPE_P2P_CLIENT, + IFTYPE_P2P_GO, + IFTYPE_P2P_DEVICE, + IFTYPE_OCB, + IFTYPE_NAN, + IFTYPE_NUM +}; + +/* Concurrency mode for p2p preferred freq list*/ +enum CONN_MODE_IFACE_TYPE { + CONN_MODE_IFACE_TYPE_STA = 0, + CONN_MODE_IFACE_TYPE_SAP, + CONN_MODE_IFACE_TYPE_P2P_GC, + CONN_MODE_IFACE_TYPE_P2P_GO, + CONN_MODE_IFACE_TYPE_IBSS, + CONN_MODE_IFACE_TYPE_TDLS, + CONN_MODE_IFACE_TYPE_NUM +}; + +enum ENUM_CHNL_EXT { + CHNL_EXT_SCN = 0, + CHNL_EXT_SCA = 1, + CHNL_EXT_RES = 2, + CHNL_EXT_SCB = 3 +}; + +enum ENUM_CHANNEL_WIDTH { + CW_20_40MHZ = 0, + CW_80MHZ = 1, + CW_160MHZ = 2, + CW_80P80MHZ = 3 +}; + +/* This starting freq of the band is unit of kHz */ +enum ENUM_BAND { + BAND_NULL, + BAND_2G4, + BAND_5G, + BAND_NUM +}; + +enum ENUM_CH_REQ_TYPE { + CH_REQ_TYPE_JOIN, + CH_REQ_TYPE_ROC, /* requested by remain on channel type */ + CH_REQ_TYPE_OFFCHNL_TX, + CH_REQ_TYPE_GO_START_BSS, +#if (CFG_SUPPORT_DFS_MASTER == 1) + CH_REQ_TYPE_DFS_CAC, +#endif + CH_REQ_TYPE_NUM +}; + +enum ENUM_DBDC_BN { + ENUM_BAND_0, + ENUM_BAND_1, + ENUM_BAND_NUM, + ENUM_BAND_ALL, + ENUM_BAND_AUTO /*Auto select by A/G band, Driver only*/ +}; + +/* Provide supported channel list to other components in array format */ +struct RF_CHANNEL_INFO { + enum ENUM_BAND eBand; + /* To record Channel Center Frequency Segment 0 (MHz) from CFG80211 */ + uint32_t u4CenterFreq1; + /* To record Channel Center Frequency Segment 1 (MHz) from CFG80211 */ + uint32_t u4CenterFreq2; + /* To record primary channel frequency (MHz) from CFG80211 */ + uint16_t u2PriChnlFreq; + /* To record channel bandwidth from CFG80211 */ + uint8_t ucChnlBw; + uint8_t ucChannelNum; + enum nl80211_dfs_state eDFS; +}; + +enum ENUM_PS_FORWARDING_TYPE { + PS_FORWARDING_TYPE_NON_PS = 0, + PS_FORWARDING_TYPE_DELIVERY_ENABLED, + PS_FORWARDING_TYPE_NON_DELIVERY_ENABLED, + PS_FORWARDING_MORE_DATA_ENABLED, + PS_FORWARDING_TYPE_NUM +}; + +enum ENUM_AR_SS { + AR_SS_NULL = 0, + AR_SS_1, + AR_SS_2, + AR_SS_3, + AR_SS_4, + AR_SS_NUM +}; + +enum ENUM_MAC_BANDWIDTH { + MAC_BW_20 = 0, + MAC_BW_40, + MAC_BW_80, + MAC_BW_160 +}; + +struct DEAUTH_INFO { + uint8_t aucRxAddr[MAC_ADDR_LEN]; + OS_SYSTIME rLastSendTime; +}; + +enum ENUM_CHNL_SWITCH_POLICY { + CHNL_SWITCH_POLICY_NONE, + CHNL_SWITCH_POLICY_DEAUTH, + CHNL_SWITCH_POLICY_CSA +}; + +enum ENUM_CHNL_SORT_POLICY { + CHNL_SORT_POLICY_NONE, + CHNL_SORT_POLICY_ALL_CN, + CHNL_SORT_POLICY_BY_CH_DOMAIN +}; + +/*----------------------------------------------------------------------------*/ +/* Information Element (IE) handlers */ +/*----------------------------------------------------------------------------*/ +typedef void(*PFN_APPEND_IE_FUNC) (struct ADAPTER *, + struct MSDU_INFO *); +typedef void(*PFN_HANDLE_IE_FUNC) (struct ADAPTER *, + struct SW_RFB *, struct IE_HDR *); +typedef void(*PFN_VERIFY_IE_FUNC) (struct ADAPTER *, + struct SW_RFB *, struct IE_HDR *, + uint16_t *); +typedef uint32_t(*PFN_CALCULATE_VAR_IE_LEN_FUNC) ( + struct ADAPTER *, uint8_t, struct STA_RECORD *); + +struct APPEND_IE_ENTRY { + uint16_t u2EstimatedIELen; + PFN_APPEND_IE_FUNC pfnAppendIE; +}; + +struct APPEND_VAR_IE_ENTRY { + uint16_t u2EstimatedFixedIELen; /* For Fixed Length */ + PFN_CALCULATE_VAR_IE_LEN_FUNC pfnCalculateVariableIELen; + PFN_APPEND_IE_FUNC pfnAppendIE; +}; + +struct HANDLE_IE_ENTRY { + uint8_t ucElemID; + PFN_HANDLE_IE_FUNC pfnHandleIE; +}; + +struct VERIFY_IE_ENTRY { + uint8_t ucElemID; + PFN_VERIFY_IE_FUNC pfnVarifyIE; +}; + +/*----------------------------------------------------------------------------*/ +/* Parameters of User Configuration */ +/*----------------------------------------------------------------------------*/ +enum ENUM_PARAM_CONNECTION_POLICY { + CONNECT_BY_SSID_BEST_RSSI = 0, + CONNECT_BY_SSID_GOOD_RSSI_MIN_CH_LOAD, + CONNECT_BY_SSID_ANY, /* NOTE(Kevin): Needed by WHQL */ + CONNECT_BY_BSSID, + CONNECT_BY_BSSID_HINT, + CONNECT_BY_CUSTOMIZED_RULE /* NOTE(Kevin): TBD */ +}; + +enum ENUM_PARAM_PREAMBLE_TYPE { + PREAMBLE_TYPE_LONG = 0, + PREAMBLE_TYPE_SHORT, + /*!< Try preamble short first, if fail tray preamble long. */ + PREAMBLE_TYPE_AUTO +}; + +/* This is enum defined for user to select a phy config listed in combo box */ +enum ENUM_PARAM_PHY_CONFIG { + /* Can associated with 802.11abg AP but without n capability, + * Scan dual band. + */ + PHY_CONFIG_802_11ABG = 0, + /* Can associated with 802_11bg AP, + * Scan single band and not report 5G BSSs. + */ + PHY_CONFIG_802_11BG, + /* Can associated with 802_11g only AP, + * Scan single band and not report 5G BSSs. + */ + PHY_CONFIG_802_11G, + /* Can associated with 802_11a only AP, + * Scan single band and not report 2.4G BSSs. + */ + PHY_CONFIG_802_11A, + /* Can associated with 802_11b only AP, + * Scan single band and not report 5G BSSs. + */ + PHY_CONFIG_802_11B, + /* Can associated with 802.11abgn AP, Scan dual band. */ + PHY_CONFIG_802_11ABGN, + /* Can associated with 802_11bgn AP, + * Scan single band and not report 5G BSSs. + */ + PHY_CONFIG_802_11BGN, + /* Can associated with 802_11an AP, + * Scan single band and not report 2.4G BSSs. + */ + PHY_CONFIG_802_11AN, + /* Can associated with 802_11gn AP, + * Scan single band and not report 5G BSSs. + */ + PHY_CONFIG_802_11GN, + PHY_CONFIG_802_11AC, + PHY_CONFIG_802_11ANAC, + PHY_CONFIG_802_11ABGNAC, +#if (CFG_SUPPORT_802_11AX == 1) + PHY_CONFIG_802_11ABGNACAX, +#endif + PHY_CONFIG_NUM /* 12 */ +}; + +/* This is enum defined for user to select an AP Mode */ +enum ENUM_PARAM_AP_MODE { + /* Create 11b BSS if we support 802.11abg/802.11bg. */ + AP_MODE_11B = 0, + /* Create 11bg mixed BSS if we support 802.11abg/802.11bg/802.11g. */ + AP_MODE_MIXED_11BG, + /* Create 11g only BSS if we support 802.11abg/802.11bg/802.11g. */ + AP_MODE_11G, + /* Create 11g only BSS for P2P + * if we support 802.11abg/802.11bg/802.11g. + */ + AP_MODE_11G_P2P, + /* Create 11a only BSS if we support 802.11abg. */ + AP_MODE_11A, + AP_MODE_NUM /* 4 */ +}; + +/* Masks for determining the Network Type + * or the Station Role, given the ENUM_STA_TYPE_T + */ +#define STA_TYPE_LEGACY_MASK BIT(STA_TYPE_LEGACY_INDEX) +#define STA_TYPE_P2P_MASK BIT(STA_TYPE_P2P_INDEX) +#define STA_TYPE_BOW_MASK BIT(STA_TYPE_BOW_INDEX) +#define STA_TYPE_ADHOC_MASK BIT(STA_ROLE_ADHOC_INDEX) +#define STA_TYPE_CLIENT_MASK BIT(STA_ROLE_CLIENT_INDEX) +#define STA_TYPE_AP_MASK BIT(STA_ROLE_AP_INDEX) +#define STA_TYPE_DLS_MASK BIT(STA_ROLE_DLS_INDEX) + +/* Macros for obtaining the Network Type + * or the Station Role, given the ENUM_STA_TYPE_T + */ +#define IS_STA_IN_AIS(_prStaRec) \ + (prAdapter->aprBssInfo[(_prStaRec)->ucBssIndex]->eNetworkType \ + == NETWORK_TYPE_AIS) +#define IS_STA_IN_P2P(_prStaRec) \ + (prAdapter->aprBssInfo[(_prStaRec)->ucBssIndex]->eNetworkType \ + == NETWORK_TYPE_P2P) +#define IS_STA_LEGACY_TYPE(_prStaRec) \ + ((_prStaRec->eStaType) & STA_TYPE_LEGACY_MASK) +#define IS_STA_P2P_TYPE(_prStaRec) \ + ((_prStaRec->eStaType) & STA_TYPE_P2P_MASK) +#define IS_STA_BOW_TYPE(_prStaRec) \ + ((_prStaRec->eStaType) & STA_TYPE_BOW_MASK) +#define IS_ADHOC_STA(_prStaRec) \ + ((_prStaRec->eStaType) & STA_TYPE_ADHOC_MASK) +#define IS_CLIENT_STA(_prStaRec) \ + ((_prStaRec->eStaType) & STA_TYPE_CLIENT_MASK) +#define IS_AP_STA(_prStaRec) \ + ((_prStaRec->eStaType) & STA_TYPE_AP_MASK) +#define IS_DLS_STA(_prStaRec) \ + ((_prStaRec->eStaType) & STA_TYPE_DLS_MASK) + +/* The ENUM_STA_TYPE_T accounts for + * ENUM_NETWORK_TYPE_T and ENUM_STA_ROLE_INDEX_T. + * It is a merged version of Network Type and STA Role. + */ +enum ENUM_STA_TYPE { + STA_TYPE_LEGACY_AP = (STA_TYPE_LEGACY_MASK | STA_TYPE_AP_MASK), + STA_TYPE_LEGACY_CLIENT = (STA_TYPE_LEGACY_MASK | STA_TYPE_CLIENT_MASK), + STA_TYPE_ADHOC_PEER = (STA_TYPE_LEGACY_MASK | STA_TYPE_ADHOC_MASK), +#if CFG_ENABLE_WIFI_DIRECT + STA_TYPE_P2P_GO = (STA_TYPE_P2P_MASK | STA_TYPE_AP_MASK), + STA_TYPE_P2P_GC = (STA_TYPE_P2P_MASK | STA_TYPE_CLIENT_MASK), +#endif +#if CFG_ENABLE_BT_OVER_WIFI + STA_TYPE_BOW_AP = (STA_TYPE_BOW_MASK | STA_TYPE_AP_MASK), + STA_TYPE_BOW_CLIENT = (STA_TYPE_BOW_MASK | STA_TYPE_CLIENT_MASK), +#endif + STA_TYPE_DLS_PEER = (STA_TYPE_LEGACY_MASK | STA_TYPE_DLS_MASK), +}; + +/* The type of BSS we discovered */ +enum ENUM_BSS_TYPE { + BSS_TYPE_INFRASTRUCTURE = 1, + BSS_TYPE_IBSS, + BSS_TYPE_P2P_DEVICE, + BSS_TYPE_BOW_DEVICE, + BSS_TYPE_NUM +}; + +enum ENUM_ANTENNA_NUM { + ANTENNA_WF0 = 0, + ANTENNA_WF1 = 1, + MAX_ANTENNA_NUM +}; + +/*----------------------------------------------------------------------------*/ +/* RSN structures */ +/*----------------------------------------------------------------------------*/ +/* #if defined(WINDOWS_DDK) || defined(WINDOWS_CE) */ +/* #pragma pack(1) */ +/* #endif */ + +/* max number of supported cipher suites */ +#define MAX_NUM_SUPPORTED_CIPHER_SUITES 10 +#if CFG_SUPPORT_802_11W +/* max number of supported AKM suites */ +#define MAX_NUM_SUPPORTED_AKM_SUITES 15 +#else +/* max number of supported AKM suites */ +#define MAX_NUM_SUPPORTED_AKM_SUITES 13 +#endif + +/* Structure of RSN Information */ +struct RSN_INFO { + uint8_t ucElemId; + uint16_t u2Version; + uint32_t u4GroupKeyCipherSuite; + uint32_t u4PairwiseKeyCipherSuiteCount; + uint32_t au4PairwiseKeyCipherSuite[MAX_NUM_SUPPORTED_CIPHER_SUITES]; + uint32_t u4AuthKeyMgtSuiteCount; + uint32_t au4AuthKeyMgtSuite[MAX_NUM_SUPPORTED_AKM_SUITES]; + uint16_t u2RsnCap; + u_int8_t fgRsnCapPresent; +} __KAL_ATTRIB_PACKED__; + +/* max number of supported AKM suites */ +#define MAX_NUM_SUPPORTED_WAPI_AKM_SUITES 1 +/* max number of supported cipher suites */ +#define MAX_NUM_SUPPORTED_WAPI_CIPHER_SUITES 1 + +/* Structure of WAPI Information */ +struct WAPI_INFO { + uint8_t ucElemId; + uint8_t ucLength; + uint16_t u2Version; + uint32_t u4AuthKeyMgtSuiteCount; + uint32_t au4AuthKeyMgtSuite[MAX_NUM_SUPPORTED_WAPI_AKM_SUITES]; + uint32_t u4PairwiseKeyCipherSuiteCount; + + uint32_t + au4PairwiseKeyCipherSuite[MAX_NUM_SUPPORTED_WAPI_CIPHER_SUITES]; + uint32_t u4GroupKeyCipherSuite; + uint16_t u2WapiCap; + uint16_t u2Bkid; + uint8_t aucBkid[1][16]; +} __KAL_ATTRIB_PACKED__; + +/* #if defined(WINDOWS_DDK) || defined(WINDOWS_CE) */ +/* #pragma pack() */ +/* #endif */ + +#if CFG_ENABLE_WIFI_DIRECT + +struct P2P_DEVICE_TYPE { + uint16_t u2CategoryID; + uint16_t u2SubCategoryID; +}; + +struct P2P_DEVICE_DESC { + struct LINK_ENTRY rLinkEntry; + u_int8_t fgDevInfoValid; + uint8_t aucDeviceAddr[MAC_ADDR_LEN]; /* Device Address. */ + uint8_t aucInterfaceAddr[MAC_ADDR_LEN]; /* Interface Address. */ + uint8_t ucDeviceCapabilityBitmap; + uint8_t ucGroupCapabilityBitmap; + uint16_t u2ConfigMethod; /* Configure Method support. */ + struct P2P_DEVICE_TYPE rPriDevType; + uint8_t ucSecDevTypeNum; + /* Reference to P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT */ + struct P2P_DEVICE_TYPE arSecDevType[8]; + uint16_t u2NameLength; + uint8_t aucName[32]; /* Reference to WPS_ATTRI_MAX_LEN_DEVICE_NAME */ + /* TODO: Service Information or PasswordID valid? */ +}; + +#endif + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ +/* Macros to get and set the wireless LAN frame fields + * those are 16/32 bits in length. + */ +#define WLAN_GET_FIELD_16(_memAddr_p, _value_p) \ + { \ + uint8_t *__cp = (uint8_t *)(_memAddr_p); \ + *(uint16_t *)(_value_p) = ((uint16_t)__cp[0]) | \ + ((uint16_t)__cp[1] << 8); \ + } + +#define WLAN_GET_FIELD_BE16(_memAddr_p, _value_p) \ + { \ + uint8_t *__cp = (uint8_t *)(_memAddr_p); \ + *(uint16_t *)(_value_p) = ((uint16_t)__cp[0] << 8) | \ + ((uint16_t)__cp[1]); \ + } + +#define WLAN_GET_FIELD_24(_memAddr_p, _value_p) \ + { \ + uint8_t *__cp = (uint8_t *)(_memAddr_p); \ + *(uint32_t *)(_value_p) = 0; \ + *(uint32_t *)(_value_p) = ((uint32_t)__cp[0]) | \ + ((uint32_t)__cp[1] << 8) | \ + ((uint32_t)__cp[2] << 16); \ + } + +#define WLAN_GET_FIELD_BE24(_memAddr_p, _value_p) \ + { \ + uint8_t *__cp = (uint8_t *)(_memAddr_p); \ + *(uint32_t *)(_value_p) = 0; \ + *(uint32_t *)(_value_p) = ((uint32_t)__cp[0] << 16) | \ + ((uint32_t)__cp[1] << 8) | (uint32_t)__cp[2]; \ + } + +#define WLAN_GET_FIELD_32(_memAddr_p, _value_p) \ + { \ + uint8_t *__cp = (uint8_t *)(_memAddr_p); \ + *(uint32_t *)(_value_p) = ((uint32_t)__cp[0]) | \ + ((uint32_t)__cp[1] << 8) | \ + ((uint32_t)__cp[2] << 16) | ((uint32_t)__cp[3] << 24); \ + } + +#define WLAN_GET_FIELD_BE32(_memAddr_p, _value_p) \ + { \ + uint8_t *__cp = (uint8_t *)(_memAddr_p); \ + *(uint32_t *)(_value_p) = ((uint32_t)__cp[0] << 24) | \ + ((uint32_t)__cp[1] << 16) | ((uint32_t)__cp[2] << 8) | \ + ((uint32_t)__cp[3]); \ + } + +#define WLAN_GET_FIELD_64(_memAddr_p, _value_p) \ + { \ + uint8_t *__cp = (uint8_t *)(_memAddr_p); \ + *(uint64_t *)(_value_p) = \ + ((uint64_t)__cp[0]) | ((uint64_t)__cp[1] << 8) | \ + ((uint64_t)__cp[2] << 16) | \ + ((uint64_t)__cp[3] << 24) | \ + ((uint64_t)__cp[4] << 32) | \ + ((uint64_t)__cp[5] << 40) | \ + ((uint64_t)__cp[6] << 48) | \ + ((uint64_t)__cp[7] << 56); \ + } + +#define WLAN_SET_FIELD_16(_memAddr_p, _value) \ + { \ + uint8_t *__cp = (uint8_t *)(_memAddr_p); \ + __cp[0] = (uint8_t)(_value); \ + __cp[1] = (uint8_t)((_value) >> 8); \ + } + +#define WLAN_SET_FIELD_64(_memAddr_p, _value) \ + { \ + uint8_t *__cp = (uint8_t *)(_memAddr_p); \ + __cp[0] = (uint8_t)((_value) & 0xff); \ + __cp[1] = (uint8_t)((_value) >> 8); \ + __cp[2] = (uint8_t)((_value) >> 16); \ + __cp[3] = (uint8_t)((_value) >> 24); \ + __cp[4] = (uint8_t)((_value) >> 32); \ + __cp[5] = (uint8_t)((_value) >> 40); \ + __cp[6] = (uint8_t)((_value) >> 48); \ + __cp[7] = (uint8_t)((_value) >> 56); \ + } + +#define WLAN_SET_FIELD_BE16(_memAddr_p, _value) \ + { \ + uint8_t *__cp = (uint8_t *)(_memAddr_p); \ + __cp[0] = (uint8_t)((_value) >> 8); \ + __cp[1] = (uint8_t)(_value); \ + } + +#define WLAN_SET_FIELD_32(_memAddr_p, _value) \ + { \ + uint8_t *__cp = (uint8_t *)(_memAddr_p); \ + __cp[0] = (uint8_t)(_value); \ + __cp[1] = (uint8_t)((_value) >> 8); \ + __cp[2] = (uint8_t)((_value) >> 16); \ + __cp[3] = (uint8_t)((_value) >> 24); \ + } + +#define WLAN_SET_FIELD_BE24(_memAddr_p, _value) \ + { \ + uint8_t *__cp = (uint8_t *)(_memAddr_p); \ + __cp[0] = (uint8_t)((_value) >> 16); \ + __cp[1] = (uint8_t)((_value) >> 8); \ + __cp[2] = (uint8_t)(_value); \ + } + +#define WLAN_SET_FIELD_BE32(_memAddr_p, _value) \ + { \ + uint8_t *__cp = (uint8_t *)(_memAddr_p); \ + __cp[0] = (uint8_t)((_value) >> 24); \ + __cp[1] = (uint8_t)((_value) >> 16); \ + __cp[2] = (uint8_t)((_value) >> 8); \ + __cp[3] = (uint8_t)(_value); \ + } + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#endif /* _WLAN_DEF_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic_cmd_event.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic_cmd_event.h new file mode 100644 index 0000000000000000000000000000000000000000..00254dbfed31d71fb883cd31005f8bc594d0f895 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic_cmd_event.h @@ -0,0 +1,3267 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/ + * MT6620_WIFI_DRIVER_V2_3/include/nic_cmd_event.h#1 + */ + +/*! \file "nic_cmd_event.h" + * \brief This file contains the declairation file of the WLAN OID processing + * routines of Windows driver for MediaTek Inc. + * 802.11 Wireless LAN Adapters. + */ + +#ifndef _NIC_CMD_EVENT_H +#define _NIC_CMD_EVENT_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "gl_vendor.h" + +#if (CFG_SUPPORT_802_11AX == 1) +#include "he_ie.h" +#endif + +#include "wsys_cmd_handler_fw.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#define CMD_PQ_ID (0x8000) +#define CMD_PACKET_TYPE_ID (0xA0) + +#define PKT_FT_CMD 0x2 + +#define CMD_STATUS_SUCCESS 0 +#define CMD_STATUS_REJECTED 1 +#define CMD_STATUS_UNKNOWN 2 + +#define MAX_IE_LENGTH (600) +#define MAX_WSC_IE_LENGTH (400) + +/* Action field in structure CMD_CH_PRIVILEGE_T */ +#define CMD_CH_ACTION_REQ 0 +#define CMD_CH_ACTION_ABORT 1 + +/* Status field in structure EVENT_CH_PRIVILEGE_T */ +#define EVENT_CH_STATUS_GRANT 0 + +/*CMD_POWER_OFFSET_T , follow 5G sub-band*/ +/* #define MAX_SUBBAND_NUM 8 */ +/* */ +/* */ +/* */ +/* */ +#define S2D_INDEX_CMD_H2N 0x0 +#define S2D_INDEX_CMD_C2N 0x1 +#define S2D_INDEX_CMD_H2C 0x2 +#define S2D_INDEX_CMD_H2N_H2C 0x3 + +#define S2D_INDEX_EVENT_N2H 0x0 +#define S2D_INDEX_EVENT_N2C 0x1 +#define S2D_INDEX_EVENT_C2H 0x2 +#define S2D_INDEX_EVENT_N2H_N2C 0x3 + +#define RDD_EVENT_HDR_SIZE 20 +#define RDD_ONEPLUSE_SIZE 8 /* size of one pulse is 8 bytes */ +#define RDD_PULSE_OFFSET0 0 +#define RDD_PULSE_OFFSET1 1 +#define RDD_PULSE_OFFSET2 2 +#define RDD_PULSE_OFFSET3 3 +#define RDD_PULSE_OFFSET4 4 +#define RDD_PULSE_OFFSET5 5 +#define RDD_PULSE_OFFSET6 6 +#define RDD_PULSE_OFFSET7 7 + +#if (CFG_SUPPORT_DFS_MASTER == 1) +#define RDD_IN_SEL_0 0 +#define RDD_IN_SEL_1 1 +#endif + +#if (CFG_SUPPORT_TXPOWER_INFO == 1) +#define TXPOWER_EVENT_SHOW_ALL_RATE_TXPOWER_INFO 0x5 +#endif + +#if CFG_SUPPORT_QA_TOOL +#define IQ_FILE_LINE_OFFSET 18 +#define IQ_FILE_IQ_STR_LEN 8 +#define RTN_IQ_DATA_LEN 1024 /* return 1k per packet */ + +#define MCAST_WCID_TO_REMOVE 0 + +/* Network type */ +#define NETWORK_INFRA BIT(16) +#define NETWORK_P2P BIT(17) +#define NETWORK_IBSS BIT(18) +#define NETWORK_MESH BIT(19) +#define NETWORK_BOW BIT(20) +#define NETWORK_WDS BIT(21) + +/* Station role */ +#define STA_TYPE_STA BIT(0) +#define STA_TYPE_AP BIT(1) +#define STA_TYPE_ADHOC BIT(2) +#define STA_TYPE_TDLS BIT(3) +#define STA_TYPE_WDS BIT(4) + +/* Connection type */ +#define CONNECTION_INFRA_STA (STA_TYPE_STA|NETWORK_INFRA) +#define CONNECTION_INFRA_AP (STA_TYPE_AP|NETWORK_INFRA) +#define CONNECTION_P2P_GC (STA_TYPE_STA|NETWORK_P2P) +#define CONNECTION_P2P_GO (STA_TYPE_AP|NETWORK_P2P) +#define CONNECTION_MESH_STA (STA_TYPE_STA|NETWORK_MESH) +#define CONNECTION_MESH_AP (STA_TYPE_AP|NETWORK_MESH) +#define CONNECTION_IBSS_ADHOC (STA_TYPE_ADHOC|NETWORK_IBSS) +#define CONNECTION_TDLS \ + (STA_TYPE_STA|NETWORK_INFRA|STA_TYPE_TDLS) +#define CONNECTION_WDS (STA_TYPE_WDS|NETWORK_WDS) + +#define ICAP_CONTENT_ADC 0x10000006 +#define ICAP_CONTENT_TOAE 0x7 +#define ICAP_CONTENT_SPECTRUM 0xB +#define ICAP_CONTENT_RBIST 0x10 +#define ICAP_CONTENT_DCOC 0x20 +#define ICAP_CONTENT_FIIQ 0x48 +#define ICAP_CONTENT_FDIQ 0x49 + +#if CFG_SUPPORT_BUFFER_MODE + +struct CMD_EFUSE_BUFFER_MODE { + uint8_t ucSourceMode; + uint8_t ucCount; + uint8_t ucCmdType; /* 0:6632, 1: 7668 */ + uint8_t ucReserved; + uint8_t aBinContent[MAX_EEPROM_BUFFER_SIZE]; +}; + +struct CMD_EFUSE_BUFFER_MODE_CONNAC_T { + uint8_t ucSourceMode; + uint8_t ucContentFormat; + uint16_t u2Count; + uint8_t aBinContent[MAX_EEPROM_BUFFER_SIZE]; +}; + +/*#if (CFG_EEPROM_PAGE_ACCESS == 1)*/ +struct CMD_ACCESS_EFUSE { + uint32_t u4Address; + uint32_t u4Valid; + uint8_t aucData[16]; +}; + +struct CMD_EFUSE_FREE_BLOCK { + uint8_t ucGetFreeBlock; + uint8_t aucReserved[3]; +}; + + +struct CMD_GET_TX_POWER { + uint8_t ucTxPwrType; + uint8_t ucCenterChannel; + uint8_t ucDbdcIdx; /* 0:Band 0, 1: Band1 */ + uint8_t ucBand; /* 0:G-band 1: A-band*/ + uint8_t ucReserved[4]; +}; + +/*#endif*/ + +#endif /* CFG_SUPPORT_BUFFER_MODE */ + + +struct CMD_SET_TX_TARGET_POWER { + int8_t cTxPwr2G4Cck; /* signed, in unit of 0.5dBm */ + int8_t cTxPwr2G4Dsss; /* signed, in unit of 0.5dBm */ + uint8_t ucTxTargetPwr; /* Tx target power base for all*/ + uint8_t ucReserved; + + int8_t cTxPwr2G4OFDM_BPSK; + int8_t cTxPwr2G4OFDM_QPSK; + int8_t cTxPwr2G4OFDM_16QAM; + int8_t cTxPwr2G4OFDM_Reserved; + int8_t cTxPwr2G4OFDM_48Mbps; + int8_t cTxPwr2G4OFDM_54Mbps; + + int8_t cTxPwr2G4HT20_BPSK; + int8_t cTxPwr2G4HT20_QPSK; + int8_t cTxPwr2G4HT20_16QAM; + int8_t cTxPwr2G4HT20_MCS5; + int8_t cTxPwr2G4HT20_MCS6; + int8_t cTxPwr2G4HT20_MCS7; + + int8_t cTxPwr2G4HT40_BPSK; + int8_t cTxPwr2G4HT40_QPSK; + int8_t cTxPwr2G4HT40_16QAM; + int8_t cTxPwr2G4HT40_MCS5; + int8_t cTxPwr2G4HT40_MCS6; + int8_t cTxPwr2G4HT40_MCS7; + + int8_t cTxPwr5GOFDM_BPSK; + int8_t cTxPwr5GOFDM_QPSK; + int8_t cTxPwr5GOFDM_16QAM; + int8_t cTxPwr5GOFDM_Reserved; + int8_t cTxPwr5GOFDM_48Mbps; + int8_t cTxPwr5GOFDM_54Mbps; + + int8_t cTxPwr5GHT20_BPSK; + int8_t cTxPwr5GHT20_QPSK; + int8_t cTxPwr5GHT20_16QAM; + int8_t cTxPwr5GHT20_MCS5; + int8_t cTxPwr5GHT20_MCS6; + int8_t cTxPwr5GHT20_MCS7; + + int8_t cTxPwr5GHT40_BPSK; + int8_t cTxPwr5GHT40_QPSK; + int8_t cTxPwr5GHT40_16QAM; + int8_t cTxPwr5GHT40_MCS5; + int8_t cTxPwr5GHT40_MCS6; + int8_t cTxPwr5GHT40_MCS7; +}; + + +/* + * Definitions for extension CMD_ID + */ +enum ENUM_EXT_CMD_ID { + EXT_CMD_ID_EFUSE_ACCESS = 0x01, + EXT_CMD_ID_RF_REG_ACCESS = 0x02, + EXT_CMD_ID_EEPROM_ACCESS = 0x03, + EXT_CMD_ID_RF_TEST = 0x04, + EXT_CMD_ID_RADIO_ON_OFF_CTRL = 0x05, + EXT_CMD_ID_WIFI_RX_DISABLE = 0x06, + EXT_CMD_ID_PM_STATE_CTRL = 0x07, + EXT_CMD_ID_CHANNEL_SWITCH = 0x08, + EXT_CMD_ID_NIC_CAPABILITY = 0x09, + EXT_CMD_ID_AP_PWR_SAVING_CLEAR = 0x0A, + EXT_CMD_ID_SET_WTBL2_RATETABLE = 0x0B, + EXT_CMD_ID_GET_WTBL_INFORMATION = 0x0C, + EXT_CMD_ID_ASIC_INIT_UNINIT_CTRL = 0x0D, + EXT_CMD_ID_MULTIPLE_REG_ACCESS = 0x0E, + EXT_CMD_ID_AP_PWR_SAVING_CAPABILITY = 0x0F, + EXT_CMD_ID_SECURITY_ADDREMOVE_KEY = 0x10, + EXT_CMD_ID_SET_TX_POWER_CONTROL = 0x11, + EXT_CMD_ID_SET_THERMO_CALIBRATION = 0x12, + EXT_CMD_ID_FW_LOG_2_HOST = 0x13, + EXT_CMD_ID_AP_PWR_SAVING_START = 0x14, + EXT_CMD_ID_MCC_OFFLOAD_START = 0x15, + EXT_CMD_ID_MCC_OFFLOAD_STOP = 0x16, + EXT_CMD_ID_LED = 0x17, + EXT_CMD_ID_PACKET_FILTER = 0x18, + EXT_CMD_ID_COEXISTENCE = 0x19, + EXT_CMD_ID_PWR_MGT_BIT_WIFI = 0x1B, + EXT_CMD_ID_GET_TX_POWER = 0x1C, + EXT_CMD_ID_BF_ACTION = 0x1E, + + EXT_CMD_ID_WMT_CMD_OVER_WIFI = 0x20, + EXT_CMD_ID_EFUSE_BUFFER_MODE = 0x21, + EXT_CMD_ID_OFFLOAD_CTRL = 0x22, + EXT_CMD_ID_THERMAL_PROTECT = 0x23, + EXT_CMD_ID_CLOCK_SWITCH_DISABLE = 0x24, + EXT_CMD_ID_STAREC_UPDATE = 0x25, + EXT_CMD_ID_BSSINFO_UPDATE = 0x26, + EXT_CMD_ID_EDCA_SET = 0x27, + EXT_CMD_ID_SLOT_TIME_SET = 0x28, + EXT_CMD_ID_DEVINFO_UPDATE = 0x2A, + EXT_CMD_ID_NOA_OFFLOAD_CTRL = 0x2B, + EXT_CMD_ID_GET_SENSOR_RESULT = 0x2C, + EXT_CMD_ID_TMR_CAL = 0x2D, + EXT_CMD_ID_WAKEUP_OPTION = 0x2E, + EXT_CMD_ID_OBTW = 0x2F, + + EXT_CMD_ID_GET_TX_STATISTICS = 0x30, + EXT_CMD_ID_AC_QUEUE_CONTROL = 0x31, + EXT_CMD_ID_WTBL_UPDATE = 0x32, + EXT_CMD_ID_BCN_UPDATE = 0x33, + + EXT_CMD_ID_DRR_CTRL = 0x36, + EXT_CMD_ID_BSSGROUP_CTRL = 0x37, + EXT_CMD_ID_VOW_FEATURE_CTRL = 0x38, + EXT_CMD_ID_PKT_PROCESSOR_CTRL = 0x39, + EXT_CMD_ID_PALLADIUM = 0x3A, + EXT_CMD_ID_GET_MAC_INFO = 0x3C, +#if CFG_SUPPORT_MU_MIMO + EXT_CMD_ID_MU_CTRL = 0x40, +#endif /* CFG_SUPPORT_MU_MIMO */ + + EXT_CMD_ID_EFUSE_FREE_BLOCK = 0x4F, + EXT_CMD_ID_DUMP_MEM = 0x57, + EXT_CMD_ID_TX_POWER_FEATURE_CTRL = 0x58, + EXT_CMD_ID_SER = 0x81, +#if (CFG_SUPPORT_TWT == 1) + EXT_CMD_ID_TWT_AGRT_UPDATE = 0x94, +#endif + EXT_CMD_ID_SYSDVT_TEST = 0x99, + EXT_CMD_ID_CR4_DMASHDL_DVT = 0xAB +}; + +enum NDIS_802_11_WEP_STATUS { + Ndis802_11WEPEnabled, + Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled, + Ndis802_11WEPDisabled, + Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled, + Ndis802_11WEPKeyAbsent, + Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent, + Ndis802_11WEPNotSupported, + Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported, + Ndis802_11TKIPEnable, + Ndis802_11Encryption2Enabled = Ndis802_11TKIPEnable, + Ndis802_11Encryption2KeyAbsent, + Ndis802_11AESEnable, + Ndis802_11Encryption3Enabled = Ndis802_11AESEnable, + Ndis802_11CCMP256Enable, + Ndis802_11GCMP128Enable, + Ndis802_11GCMP256Enable, + Ndis802_11Encryption3KeyAbsent, + Ndis802_11TKIPAESMix, + /* TKIP or AES mix */ + Ndis802_11Encryption4Enabled = Ndis802_11TKIPAESMix, + Ndis802_11Encryption4KeyAbsent, + Ndis802_11GroupWEP40Enabled, + Ndis802_11GroupWEP104Enabled, +#ifdef WAPI_SUPPORT + Ndis802_11EncryptionSMS4Enabled, /* WPI SMS4 support */ +#endif /* WAPI_SUPPORT */ +}; + +#if CFG_SUPPORT_MU_MIMO +enum { + /* debug commands */ + MU_SET_ENABLE = 0, + MU_GET_ENABLE, + MU_SET_MUPROFILE_ENTRY, + MU_GET_MUPROFILE_ENTRY, + MU_SET_GROUP_TBL_ENTRY, + MU_GET_GROUP_TBL_ENTRY, + MU_SET_CLUSTER_TBL_ENTRY, + MU_GET_CLUSTER_TBL_ENTRY, + MU_SET_GROUP_USER_THRESHOLD, + MU_GET_GROUP_USER_THRESHOLD, + MU_SET_GROUP_NSS_THRESHOLD, + MU_GET_GROUP_NSS_THRESHOLD, + MU_SET_TXREQ_MIN_TIME, + MU_GET_TXREQ_MIN_TIME, + MU_SET_SU_NSS_CHECK, + MU_GET_SU_NSS_CHECK, + MU_SET_CALC_INIT_MCS, + MU_GET_CALC_INIT_MCS, + MU_SET_TXOP_DEFAULT, + MU_GET_TXOP_DEFAULT, + MU_SET_SU_LOSS_THRESHOLD, + MU_GET_SU_LOSS_THRESHOLD, + MU_SET_MU_GAIN_THRESHOLD, + MU_GET_MU_GAIN_THRESHOLD, + MU_SET_SECONDARY_AC_POLICY, + MU_GET_SECONDARY_AC_POLICY, + MU_SET_GROUP_TBL_DMCS_MASK, + MU_GET_GROUP_TBL_DMCS_MASK, + MU_SET_MAX_GROUP_SEARCH_CNT, + MU_GET_MAX_GROUP_SEARCH_CNT, + MU_GET_MU_PROFILE_TX_STATUS_CNT, + MU_SET_TRIGGER_MU_TX, + /* F/W flow test commands */ + MU_SET_TRIGGER_GID_MGMT_FRAME, + /* HQA STA commands */ + MU_HQA_SET_STA_PARAM = 60, + /* HQA AP Commands*/ + MU_HQA_SET_ENABLE = 70, + MU_HQA_SET_SNR_OFFSET, + MU_HQA_SET_ZERO_NSS, + MU_HQA_SET_SPEED_UP_LQ, + MU_HQA_SET_GROUP, + MU_HQA_SET_MU_TABLE, + MU_HQA_SET_SU_TABLE, + MU_HQA_SET_CALC_LQ, + MU_HQA_GET_CALC_LQ, + MU_HQA_SET_CALC_INIT_MCS, + MU_HQA_GET_CALC_INIT_MCS, + MU_HQA_GET_QD, +}; +#endif /* CFG_SUPPORT_MU_MIMO */ +#endif /* CFG_SUPPORT_QA_TOOL */ + +#if CFG_WOW_SUPPORT + +/* Filter Flag */ +#define WOWLAN_FF_DROP_ALL BIT(0) +#define WOWLAN_FF_SEND_MAGIC_TO_HOST BIT(1) +#define WOWLAN_FF_ALLOW_ARP BIT(2) +#define WOWLAN_FF_ALLOW_BMC BIT(3) +#define WOWLAN_FF_ALLOW_UC BIT(4) +#define WOWLAN_FF_ALLOW_1X BIT(5) +#define WOWLAN_FF_ALLOW_ARP_REQ2ME BIT(6) + +/* wow detect type */ +#define WOWLAN_DETECT_TYPE_MAGIC BIT(0) +#define WOWLAN_DETECT_TYPE_ALLOW_NORMAL BIT(1) +#define WOWLAN_DETECT_TYPE_ONLY_PHONE_SUSPEND BIT(2) +#define WOWLAN_DETECT_TYPE_DISASSOCIATION BIT(3) +#define WOWLAN_DETECT_TYPE_BCN_LOST BIT(4) + +/* Wakeup command bit define */ +#define PF_WAKEUP_CMD_BIT0_OUTPUT_MODE_EN BIT(0) +#define PF_WAKEUP_CMD_BIT1_OUTPUT_DATA BIT(1) +#define PF_WAKEUP_CMD_BIT2_WAKEUP_LEVEL BIT(2) + +#define PM_WOWLAN_REQ_START 0x1 +#define PM_WOWLAN_REQ_STOP 0x2 + +struct EVENT_WOWLAN_NOTIFY { + uint8_t ucNetTypeIndex; + uint8_t aucReserved[3]; +}; + +/* PACKETFILTER CAPABILITY TYPE */ + +#define PACKETF_CAP_TYPE_ARP BIT(1) +#define PACKETF_CAP_TYPE_MAGIC BIT(2) +#define PACKETF_CAP_TYPE_BITMAP BIT(3) +#define PACKETF_CAP_TYPE_EAPOL BIT(4) +#define PACKETF_CAP_TYPE_TDLS BIT(5) +#define PACKETF_CAP_TYPE_CF BIT(6) +#define PACKETF_CAP_TYPE_HEARTBEAT BIT(7) +#define PACKETF_CAP_TYPE_TCP_SYN BIT(8) +#define PACKETF_CAP_TYPE_UDP_SYN BIT(9) +#define PACKETF_CAP_TYPE_BCAST_SYN BIT(10) +#define PACKETF_CAP_TYPE_MCAST_SYN BIT(11) +#define PACKETF_CAP_TYPE_V6 BIT(12) +#define PACKETF_CAP_TYPE_TDIM BIT(13) + + +enum _ENUM_FUNCTION_SELECT { + FUNCTION_PF = 1, + FUNCTION_BITMAP = 2, + FUNCTION_EAPOL = 3, + FUNCTION_TDLS = 4, + FUNCTION_ARPNS = 5, + FUNCTION_CF = 6, + FUNCTION_MODE = 7, + FUNCTION_BSSID = 8, + FUNCTION_MGMT = 9, + FUNCTION_BMC_DROP = 10, + FUNCTION_UC_DROP = 11, + FUNCTION_ALL_TOMCU = 12, +}; + +enum ENUM_PF_OPCODE { + PF_OPCODE_ADD = 0, + PF_OPCODE_DEL, + PF_OPCODE_ENABLE, + PF_OPCODE_DISABLE, + PF_OPCODE_NUM +}; + +enum ENUM_SCN_FUNC_MASK { + ENUM_SCN_RANDOM_MAC_EN = (1 << 0), + ENUM_SCN_DBDC_SCAN_DIS = (1 << 1), + ENUM_SCN_DBDC_SCAN_TYPE3 = (1 << 2), + ENUM_SCN_USE_PADDING_AS_BSSID = (1 << 3), + ENUM_SCN_RANDOM_SN_EN = (1 << 4), +}; + +struct CMD_PACKET_FILTER_CAP { + uint8_t ucCmd; + uint16_t packet_cap_type; + uint8_t aucReserved1[1]; + /* GLOBAL */ + uint32_t PFType; + uint32_t FunctionSelect; + uint32_t Enable; + /* MAGIC */ + uint8_t ucBssid; + uint16_t usEnableBits; + uint8_t aucReserved5[1]; + /* DTIM */ + uint8_t DtimEnable; + uint8_t DtimValue; + uint8_t aucReserved2[2]; + /* BITMAP_PATTERN_T */ + uint32_t Index; + uint32_t Offset; + uint32_t FeatureBits; + uint32_t Resv; + uint32_t PatternLength; + uint32_t Mask[4]; + uint32_t Pattern[32]; + /* COALESCE */ + uint32_t FilterID; + uint32_t PacketType; + uint32_t CoalesceOP; + uint8_t FieldLength; + uint8_t CompareOP; + uint8_t FieldID; + uint8_t aucReserved3[1]; + uint32_t Pattern3[4]; + /* TCPSYN */ + uint32_t AddressType; + uint32_t TCPSrcPort; + uint32_t TCPDstPort; + uint32_t SourceIP[4]; + uint32_t DstIP[4]; + uint8_t aucReserved4[64]; +}; +#endif /*CFG_WOW_SUPPORT*/ + +#if CFG_SUPPORT_WIFI_HOST_OFFLOAD +struct CMD_TCP_GENERATOR { + enum ENUM_PF_OPCODE eOpcode; + uint32_t u4ReplyId; + uint32_t u4Period; + uint32_t u4Timeout; + uint32_t u4IpId; + uint32_t u4DestPort; + uint32_t u4SrcPort; + uint32_t u4Seq; + uint8_t aucDestIp[4]; + uint8_t aucSrcIp[4]; + uint8_t aucDestMac[6]; + uint8_t ucBssId; + uint8_t aucReserved1[1]; + uint8_t aucReserved2[64]; +}; + +struct CMD_PATTERN_GENERATOR { + enum ENUM_PF_OPCODE eOpcode; + uint32_t u4ReplyId; + uint32_t u4EthernetLength; + uint32_t u4Period; + uint8_t aucEthernetFrame[128]; + uint8_t ucBssId; + uint8_t aucReserved1[3]; + uint8_t aucReserved2[64]; +}; + +struct CMD_BITMAP_FILTER { + enum ENUM_PF_OPCODE eOpcode; + uint32_t u4ReplyId; + uint32_t u4Offset; + uint32_t u4Length; + uint8_t aucPattern[64]; + uint8_t aucBitMask[64]; + u_int8_t fgIsEqual; + u_int8_t fgIsAccept; + uint8_t ucBssId; + uint8_t aucReserved1[1]; + uint8_t aucReserved2[64]; +}; + +#endif /*CFG_SUPPORT_WIFI_HOST_OFFLOAD*/ + +struct CMD_RX_PACKET_FILTER { + uint32_t u4RxPacketFilter; + uint8_t aucReserved[64]; +}; + + +#if defined(MT6632) +#define S2D_INDEX_CMD_H2N 0x0 +#define S2D_INDEX_CMD_C2N 0x1 +#define S2D_INDEX_CMD_H2C 0x2 +#define S2D_INDEX_CMD_H2N_H2C 0x3 + +#define S2D_INDEX_EVENT_N2H 0x0 +#define S2D_INDEX_EVENT_N2C 0x1 +#define S2D_INDEX_EVENT_C2H 0x2 +#define S2D_INDEX_EVENT_N2H_N2C 0x3 +#endif + +#define EXT_EVENT_TARGET_TX_POWER 0x1 + +#define EXT_EVENT_ID_CMD_RESULT 0x00 +#define EXT_EVENT_ID_EFUSE_ACCESS 0x01 +#define EXT_EVENT_ID_RF_REG_ACCESS 0x02 +#define EXT_EVENT_ID_EEPROM_ACCESS 0x03 +#define EXT_EVENT_ID_RF_TEST 0x04 +#define EXT_EVENT_ID_PS_SYNC 0x05 +#define EXT_EVENT_ID_SLEEPY_NOTIFY 0x06 +#define EXT_EVENT_ID_WLAN_ERROR 0x07 +#define EXT_EVENT_ID_NIC_CAPABILITY 0x09 +#define EXT_EVENT_ID_AP_PWR_SAVING_CLEAR 0x0A +#define EXT_EVENT_ID_SET_WTBL2_RATETABLE 0x0B +#define EXT_EVENT_ID_GET_WTBL2_INFORMATION 0x0C +#define EXT_EVENT_ID_MULTIPLE_REG_ACCESS 0x0E +#define EXT_EVENT_ID_AP_PWR_SAVING_CAPABILITY 0x0F +#define EXT_EVENT_ID_SECURITY_ADDREMOVE_KEY 0x10 +#define EXT_EVENT_ID_FW_LOG_2_HOST 0x13 +#define EXT_EVENT_ID_AP_PWR_SAVING_START 0x14 +#define EXT_EVENT_ID_PACKET_FILTER 0x18 +#define EXT_EVENT_ID_COEXISTENCE 0x19 +#define EXT_EVENT_ID_BEACON_LOSS 0x1A +#define EXT_EVENT_ID_PWR_MGT_BIT_WIFI 0x1B +#define EXT_EVENT_ID_GET_TX_POWER 0x1C + +#define EXT_EVENT_ID_WMT_EVENT_OVER_WIFI 0x20 +#define EXT_EVENT_ID_MCC_TRIGGER 0x21 +#define EXT_EVENT_ID_THERMAL_PROTECT 0x22 +#define EXT_EVENT_ID_ASSERT_DUMP 0x23 +#define EXT_EVENT_ID_GET_SENSOR_RESULT 0x2C +#define EXT_EVENT_ID_ROAMING_DETECT_NOTIFICATION 0x2D +#define EXT_EVENT_ID_TMR_CAL 0x2E +#define EXT_EVENT_ID_RA_THROUGHPUT_BURST 0x2F + +#define EXT_EVENT_ID_GET_TX_STATISTIC 0x30 +#define EXT_EVENT_ID_PRETBTT_INT 0x31 +#define EXT_EVENT_ID_WTBL_UPDATE 0x32 + +#define EXT_EVENT_ID_BF_STATUS_READ 0x35 +#define EXT_EVENT_ID_DRR_CTRL 0x36 +#define EXT_EVENT_ID_BSSGROUP_CTRL 0x37 +#define EXT_EVENT_ID_VOW_FEATURE_CTRL 0x38 +#define EXT_EVENT_ID_PKT_PROCESSOR_CTRL 0x39 +#define EXT_EVENT_ID_RDD_REPORT 0x3A +#define EXT_EVENT_ID_DEVICE_CAPABILITY 0x3B +#define EXT_EVENT_ID_MAC_INFO 0x3C +#define EXT_EVENT_ID_ATE_TEST_MODE 0x3D +#define EXT_EVENT_ID_CAC_END 0x3E +#define EXT_EVENT_ID_MU_CTRL 0x40 + +#define EXT_EVENT_ID_DBDC_CTRL 0x45 +#define EXT_EVENT_ID_CONFIG_MUAR 0x48 + +#define EXT_EVENT_ID_RX_AIRTIME_CTRL 0x4a +#define EXT_EVENT_ID_AT_PROC_MODULE 0x4b +#define EXT_EVENT_ID_MAX_AMSDU_LENGTH_UPDATE 0x4c +#define EXT_EVENT_ID_EFUSE_FREE_BLOCK 0x4d +#define EXT_EVENT_ID_MURA_CTRL 0x4d +#define EXT_EVENT_ID_CSA_NOTIFY 0x4F +#define EXT_EVENT_ID_WIFI_SPECTRUM 0x50 +#define EXT_EVENT_ID_TMR_CALCU_INFO 0x51 +#define EXT_EVENT_ID_DUMP_MEM 0x57 +#define EXT_EVENT_ID_TX_POWER_FEATURE_CTRL 0x58 + +#define EXT_EVENT_ID_G_BAND_256QAM_PROBE_RESULT 0x6B +#define EXT_EVENT_ID_MPDU_TIME_UPDATE 0x6F +#define EXT_EVENT_ID_SYSDVT_TEST 0x99 +/*#endif*/ + +#if (CFG_SUPPORT_TXPOWER_INFO == 1) +#define EXT_EVENT_ID_TX_POWER_FEATURE_CTRL 0x58 +#endif + +#define SCHED_SCAN_CHANNEL_TYPE_SPECIFIED (0) +#define SCHED_SCAN_CHANNEL_TYPE_DUAL_BAND (1) +#define SCHED_SCAN_CHANNEL_TYPE_2G4_ONLY (2) +#define SCHED_SCAN_CHANNEL_TYPE_5G_ONLY (3) + +#if (CFG_SUPPORT_TWT == 1) +/* TWT related definitions */ +#define TWT_AGRT_MAX_NUM 16 +#define TWT_GRP_MAX_NUM 8 +#define TWT_GRP_MAX_MEMBER_CNT 8 + +/* + * Bitmap definition for ucAgrtParaBitmap field + * in struct _EXT_CMD_TWT_ARGT_UPDATE_T + */ +#define TWT_AGRT_PARA_BITMAP_IS_TRIGGER BIT(0) +#define TWT_AGRT_PARA_BITMAP_IS_ANNOUNCE BIT(1) +#define TWT_AGRT_PARA_BITMAP_IS_PROTECT BIT(2) + +#define TWT_AGRT_PARA_BITMAP_TRIGGER_OFFSET 0 +#define TWT_AGRT_PARA_BITMAP_ANNCE_OFFSET 1 +#define TWT_AGRT_PARA_BITMAP_PROTECT_OFFSET 2 + +enum _TWT_AGRT_CTRL_CODE_T { + TWT_AGRT_CTRL_ADD = 0, + TWT_AGRT_CTRL_MODIFY, + TWT_AGRT_CTRL_DELETE, + TWT_AGRT_CTRL_TEARDOWN, + TWT_AGRT_CTRL_RESET +}; +#endif + +/* ID for different MAC Info */ +enum { + MAC_INFO_TYPE_RESERVE = 0, + MAC_INFO_TYPE_CHANNEL_BUSY_CNT = 0x1, + MAC_INFO_TYPE_TSF = 0x2, + MAC_INFO_TYPE_MIB = 0x3, + MAC_INFO_TYPE_EDCA = 0x4, + MAC_INFO_TYPE_WIFI_INT_CNT = 0x5, +}; + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +#ifndef LINUX +#endif +/* for Event Packet (via HIF-RX) */ +struct PSE_CMD_HDR { + /* DW0 */ + uint16_t u2TxByteCount; + uint16_t u2Reserved1: 10; + uint16_t u2Qidx: 5; + uint16_t u2Pidx: 1; + + /* DW1 */ + uint16_t u2Reserved2: 13; + uint16_t u2Hf: 2; + uint16_t u2Ft: 1; + uint16_t u2Reserved3: 8; + uint16_t u2PktFt: 2; + uint16_t u2Reserved4: 6; + + /* DW2~7 */ + uint32_t au4Reserved[6]; +}; + +struct WIFI_CMD { + uint16_t u2TxByteCount; /* Max value is over 2048 */ + uint16_t u2PQ_ID; /* Must be 0x8000 (Port1, Queue 0) */ + + uint8_t ucWlanIdx; + uint8_t ucHeaderFormat; + uint8_t ucHeaderPadding; + uint8_t ucPktFt: 2; + uint8_t ucOwnMAC: 6; + uint32_t au4Reserved1[6]; + + uint16_t u2Length; + uint16_t u2PqId; + + uint8_t ucCID; + uint8_t ucPktTypeID; /* Must be 0x20 (CMD Packet) */ + uint8_t ucSetQuery; + uint8_t ucSeqNum; + + /* padding fields, hw may auto modify this field */ + uint8_t ucD2B0Rev; + uint8_t ucExtenCID; /* Extend CID */ + uint8_t ucS2DIndex; /* Index for Src to Dst in CMD usage */ + uint8_t ucExtCmdOption; /* Extend CID option */ + + uint8_t ucCmdVersion; + uint8_t ucReserved2[3]; + uint32_t au4Reserved3[4]; /* padding fields */ + + uint8_t aucBuffer[0]; +}; + +/* for Command Packet (via HIF-TX) */ +/* following CM's documentation v0.7 */ +struct WIFI_EVENT { + uint16_t u2PacketLength; + uint16_t u2PacketType; /* Must be filled with 0xE000 (EVENT Packet) */ + uint8_t ucEID; + uint8_t ucSeqNum; + uint8_t ucEventVersion; + uint8_t aucReserved[1]; + + uint8_t ucExtenEID; + uint8_t aucReserved2[2]; + uint8_t ucS2DIndex; + + uint8_t aucBuffer[0]; +}; + +/* CMD_ID_TEST_CTRL */ +struct CMD_TEST_CTRL { + uint8_t ucAction; + uint8_t aucReserved[3]; + union { + uint32_t u4OpMode; + uint32_t u4ChannelFreq; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + } u; +}; + +struct CMD_TEST_CTRL_EXT_T { + uint8_t ucAction; + uint8_t ucIcapLen; + uint8_t aucReserved[2]; + union { + uint32_t u4OpMode; + uint32_t u4ChannelFreq; + struct PARAM_MTK_WIFI_TEST_STRUCT_EXT_T rRfATInfo; + } u; +}; + +/* EVENT_TEST_STATUS */ +struct PARAM_CUSTOM_RFTEST_TX_STATUS_STRUCT { + uint32_t u4PktSentStatus; + uint32_t u4PktSentCount; + uint16_t u2AvgAlc; + uint8_t ucCckGainControl; + uint8_t ucOfdmGainControl; +}; + +struct PARAM_CUSTOM_RFTEST_RX_STATUS_STRUCT { + /*!< number of packets that Rx ok from interrupt */ + uint32_t u4IntRxOk; + /*!< number of packets that CRC error from interrupt */ + uint32_t u4IntCrcErr; + /*!< number of packets that is short preamble from interrupt */ + uint32_t u4IntShort; + /*!< number of packets that is long preamble from interrupt */ + uint32_t u4IntLong; + /*!< number of packets that Rx ok from PAU */ + uint32_t u4PauRxPktCount; + /*!< number of packets that CRC error from PAU */ + uint32_t u4PauCrcErrCount; + /*!< number of packets that is short preamble from PAU */ + uint32_t u4PauRxFifoFullCount; + uint32_t u4PauCCACount; /*!< CCA rising edge count */ +}; + +union EVENT_TEST_STATUS { + struct PARAM_MTK_WIFI_TEST_STRUCT rATInfo; + /* PARAM_CUSTOM_RFTEST_TX_STATUS_STRUCT_T rTxStatus; */ + /* PARAM_CUSTOM_RFTEST_RX_STATUS_STRUCT_T rRxStatus; */ +}; + +/* CMD_ID_DEFAULT_KEY_ID */ +struct CMD_DEFAULT_KEY { + uint8_t ucBssIdx; + uint8_t ucKeyId; + uint8_t ucWlanIndex; + uint8_t ucMulticast; +}; + +/* WPA2 PMKID cache structure */ +struct PMKID_ENTRY { + struct LINK_ENTRY rLinkEntry; + struct PARAM_PMKID rBssidInfo; +}; + +struct CMD_802_11_PMKID { + uint32_t u4BSSIDInfoCount; + struct PMKID_ENTRY *arPMKIDInfo[1]; +}; + +struct CMD_GTK_REKEY_DATA { + uint8_t aucKek[16]; + uint8_t aucKck[16]; + uint8_t aucReplayCtr[8]; +}; + +struct CMD_CSUM_OFFLOAD { + uint16_t u2RxChecksum; /* bit0: IP, bit1: UDP, bit2: TCP */ + uint16_t u2TxChecksum; /* bit0: IP, bit1: UDP, bit2: TCP */ +}; + +/* CMD_BASIC_CONFIG */ +struct CMD_BASIC_CONFIG { + uint8_t ucNative80211; + uint8_t ucCtrlFlagAssertPath; + uint8_t ucCtrlFlagDebugLevel; + uint8_t aucReserved[1]; + struct CMD_CSUM_OFFLOAD rCsumOffload; + uint8_t ucCrlFlagSegememt; + uint8_t aucReserved2[3]; +}; + +/* CMD_MAC_MCAST_ADDR */ +struct CMD_MAC_MCAST_ADDR { + uint32_t u4NumOfGroupAddr; + uint8_t ucBssIndex; + uint8_t aucReserved[3]; + uint8_t arAddress[MAX_NUM_GROUP_ADDR][PARAM_MAC_ADDR_LEN]; +}; + +/* CMD_ACCESS_EEPROM */ +struct CMD_ACCESS_EEPROM { + uint16_t u2Offset; + uint16_t u2Data; +}; + +/* EVENT_CONNECTION_STATUS */ +struct EVENT_CONNECTION_STATUS { + uint8_t ucMediaStatus; + uint8_t ucReasonOfDisconnect; + + uint8_t ucInfraMode; + uint8_t ucSsidLen; + uint8_t aucSsid[PARAM_MAX_LEN_SSID]; + uint8_t aucBssid[PARAM_MAC_ADDR_LEN]; + uint8_t ucAuthenMode; + uint8_t ucEncryptStatus; + uint16_t u2BeaconPeriod; + uint16_t u2AID; + uint16_t u2ATIMWindow; + uint8_t ucNetworkType; + uint8_t aucReserved[1]; + uint32_t u4FreqInKHz; + +#if CFG_ENABLE_WIFI_DIRECT + uint8_t aucInterfaceAddr[PARAM_MAC_ADDR_LEN]; +#endif + +}; + +/* EVENT_NIC_CAPABILITY */ +#define FEATURE_FLAG0_NIC_CAPABILITY_V2 BIT(0) + +struct EVENT_NIC_CAPABILITY { + uint16_t u2ProductID; + uint16_t u2FwVersion; + uint16_t u2DriverVersion; + uint8_t ucHw5GBandDisabled; + uint8_t ucEepromUsed; + uint8_t aucMacAddr[6]; + uint8_t ucEndianOfMacAddrNumber; + uint8_t ucHwNotSupportAC; + + uint8_t ucRfVersion; + uint8_t ucPhyVersion; + uint8_t ucRfCalFail; + uint8_t ucBbCalFail; + uint8_t aucDateCode[16]; + uint32_t u4FeatureFlag0; + uint32_t u4FeatureFlag1; + uint32_t u4CompileFlag0; + uint32_t u4CompileFlag1; + uint8_t aucBranchInfo[4]; + uint8_t ucFwBuildNumber; + uint8_t ucHwSetNss1x1; + uint8_t ucHwNotSupportDBDC; + uint8_t ucHwBssIdNum; + uint8_t aucReserved1[56]; +}; + +struct EVENT_NIC_CAPABILITY_V2 { + uint16_t u2TotalElementNum; + uint8_t aucReserved[2]; + uint8_t aucBuffer[0]; +}; + +struct NIC_CAPABILITY_V2_ELEMENT { + uint32_t tag_type; /* NIC_CAPABILITY_V2_TAG_T */ + uint32_t body_len; + uint8_t aucbody[0]; +}; + +typedef uint32_t(*NIC_CAP_V2_ELEMENT_HDLR)( + struct ADAPTER *prAdapter, uint8_t *buff); +struct NIC_CAPABILITY_V2_REF_TABLE { + uint32_t tag_type; /* NIC_CAPABILITY_V2_TAG_T */ + NIC_CAP_V2_ELEMENT_HDLR hdlr; +}; + +enum NIC_CAPABILITY_V2_TAG { + TAG_CAP_TX_RESOURCE = 0x0, + TAG_CAP_TX_EFUSEADDRESS = 0x1, + TAG_CAP_COEX_FEATURE = 0x2, + TAG_CAP_SINGLE_SKU = 0x3, + TAG_CAP_CSUM_OFFLOAD = 0x4, + TAG_CAP_HW_VERSION = 0x5, + TAG_CAP_SW_VERSION = 0x6, + TAG_CAP_MAC_ADDR = 0x7, + TAG_CAP_PHY_CAP = 0x8, + TAG_CAP_MAC_CAP = 0x9, + TAG_CAP_FRAME_BUF_CAP = 0xa, + TAG_CAP_BEAMFORM_CAP = 0xb, + TAG_CAP_LOCATION_CAP = 0xc, + TAG_CAP_MUMIMO_CAP = 0xd, + TAG_CAP_BUFFER_MODE_INFO = 0xe, + TAG_CAP_HW_ADIE_VERSION = 0x14, +#if CFG_SUPPORT_ANT_SWAP + TAG_CAP_ANTSWP = 0x16, +#endif +#if (CFG_SUPPORT_P2PGO_ACS == 1) + TAG_CAP_P2P = 0x17, +#endif + TAG_CAP_HOST_STATUS_EMI_OFFSET = 0x19, + TAG_CAP_TOTAL +}; + +#if CFG_TCP_IP_CHKSUM_OFFLOAD +struct NIC_CSUM_OFFLOAD { + uint8_t ucIsSupportCsumOffload; /* 1: Support, 0: Not Support */ + uint8_t aucReseved[3]; +}; +#endif + +struct NIC_COEX_FEATURE { + uint32_t u4FddMode; /* TRUE for COEX FDD mode */ +}; + +struct NIC_EFUSE_ADDRESS { + uint32_t u4EfuseStartAddress; /* Efuse Start Address */ + uint32_t u4EfuseEndAddress; /* Efuse End Address */ +}; + +struct CAP_HW_VERSION { + uint16_t u2ProductID; /* CHIP ID */ + uint8_t ucEcoVersion; /* ECO version */ + uint8_t ucReserved; + uint32_t u4MacIpID; /* MAC IP version */ + uint32_t u4BBIpID; /* Baseband IP version */ + uint32_t u4TopIpID; /* TOP IP version */ + uint32_t u4ConfigId; /* Configuration ID */ +}; + +struct CAP_HW_ADIE_VERSION { + uint16_t u2ProductID; /* CHIP ID */ + uint16_t u2EcoVersion; /* ECO version */ + uint32_t aucReserved[4]; +}; + +struct CAP_SW_VERSION { + uint16_t u2FwVersion; /* FW version */ + uint16_t u2FwBuildNumber; /* FW build number */ + uint8_t aucBranchInfo[4]; /* Branch name in ASCII */ + uint8_t aucDateCode[16]; /* FW build data code */ +}; + +struct CAP_MAC_ADDR { + uint8_t aucMacAddr[6]; + uint8_t aucReserved[2]; +}; + +struct CAP_PHY_CAP { + uint8_t ucHt; /* 1:support, 0:not*/ + uint8_t ucVht; /* 1:support, 0:not*/ + uint8_t uc5gBand; /* 1:support, 0:not*/ + /* 0: BW20, 1:BW40, 2:BW80, 3:BW160, 4:BW80+80 */ + uint8_t ucMaxBandwidth; + uint8_t ucNss; /* 1:1x1, 2:2x2, ... */ + uint8_t ucDbdc; /* 1:support, 0:not*/ + uint8_t ucTxLdpc; /* 1:support, 0:not*/ + uint8_t ucRxLdpc; /* 1:support, 0:not*/ + uint8_t ucTxStbc; /* 1:support, 0:not*/ + uint8_t ucRxStbc; /* 1:support, 0:not*/ + /* BIT(0): WLAN_FLAG_2G4_WF0 + * BIT(1): WLAN_FLAG_5G_WF0 + * BIT(2): WLAN_FLAG_2G4_WF1 + * BIT(3): WLAN_FLAG_5G_WF1 + */ + uint8_t ucWifiPath; + uint8_t ucHe; /* 1:support, 0:not*/ +}; + +struct CAP_MAC_CAP { + uint8_t ucHwBssIdNum; /* HW BSSID number */ + uint8_t ucWmmSet; /* 1: AC0~3, 2: AC0~3 and AC10~13, ... */ + uint8_t ucWtblEntryNum; /* WTBL entry number */ + uint8_t ucReserved; +}; + +struct CAP_FRAME_BUF_CAP { + /* 1: support in-chip Tx AMSDU (HW or CR4) */ + uint8_t ucChipTxAmsdu; + /* 2: support 2 MSDU in AMSDU, 3:support 3 MSDU in AMSDU,...*/ + uint8_t ucTxAmsduNum; + /* Rx AMSDU size, 0:4K, 1:8K,2:12K */ + uint8_t ucRxAmsduSize; + uint8_t ucReserved; + /* Txd entry number */ + uint32_t u4TxdCount; + /* Txd and packet buffer in KB (cut through sysram size) */ + uint32_t u4PacketBufSize; +}; + +struct CAP_BEAMFORM_CAP { + uint8_t ucBFer; /* Tx beamformer, 1:support, 0:not*/ + uint8_t ucIBFer; /* Tx implicit beamformer 1:support, 0:not*/ + uint8_t ucBFee; /* Rx beamformee, 1:support, 0:not */ + uint8_t ucReserved; + uint32_t u4BFerCap; /* Tx beamformere cap */ + uint32_t u4BFeeCap; /* Rx beamformee cap */ +}; + +struct CAP_LOCATION_CAP { + uint8_t ucTOAE; /* 1:support, 0:not */ + uint8_t aucReserved[3]; +}; + +struct CAP_MUMIMO_CAP { + uint8_t ucMuMimoRx; /* 1:support, 0:not */ + uint8_t ucMuMimoTx; /* 1:support, 0:not */ + uint8_t aucReserved[2]; +}; + +#if CFG_SUPPORT_ANT_SWAP +struct CAP_ANTSWP { + uint8_t ucVersion; + uint8_t ucRsvd; + uint8_t ucIsSupported; /* 1:support, 0:not */ + uint8_t ucReserved[1]; +}; +#endif + +struct NIC_HOST_STATUS_EMI_OFFSET { + uint32_t u4EmiOffset; /* TRUE for COEX FDD mode */ +}; + +#define EFUSE_SECTION_TABLE_SIZE (10) /* It should not be changed. */ + +struct EFUSE_SECTION_T { + uint16_t u2StartOffset; + uint16_t u2Length; +}; + +struct CAP_BUFFER_MODE_INFO_T { + uint8_t ucVersion; /* Version */ + uint8_t ucFormatSupportBitmap; /* Format Support Bitmap*/ + uint16_t u2EfuseTotalSize; /* Total eFUSE Size */ + struct EFUSE_SECTION_T arSections[EFUSE_SECTION_TABLE_SIZE]; + /* NOTE: EFUSE_SECTION_TABLE_SIZE should be fixed to + * 10 so that driver don't change. + */ +}; + +/* + * NIC_TX_RESOURCE_REPORT_EVENT related definition + */ + +#define NIC_TX_RESOURCE_REPORT_VERSION_PREFIX (0x80000000) +#define NIC_TX_RESOURCE_REPORT_VERSION_1 \ + (NIC_TX_RESOURCE_REPORT_VERSION_PREFIX | 0x1) + +struct nicTxRsrcEvtHdlr { + uint32_t u4Version; + + uint32_t(*nicEventTxResource) + (IN struct ADAPTER *prAdapter, + IN uint8_t *pucEventBuf); + void (*nicTxResourceInit)(IN struct ADAPTER *prAdapter); +}; + +struct NIC_TX_RESOURCE { + /* the total usable resource for MCU port */ + uint32_t u4CmdTotalResource; + /* the unit of a MCU resource */ + uint32_t u4CmdResourceUnit; + /* the total usable resource for LMAC port */ + uint32_t u4DataTotalResource; + /* the unit of a LMAC resource */ + uint32_t u4DataResourceUnit; +}; + +struct tx_resource_report_v1 { + /* + * u4Version: NIC_TX_RESOURCE_REPORT_VERSION_1 + */ + uint32_t u4Version; + + /* + * the followings are content for u4Verion = 0x80000001 + */ + uint32_t u4HifDataPsePageQuota; + uint32_t u4HifCmdPsePageQuota; + uint32_t u4HifDataPlePageQuota; + uint32_t u4HifCmdPlePageQuota; + + /* + * u4PlePsePageSize: the unit of a page in PLE and PSE + * [31:16] PLE page size + * [15:0] PLE page size + */ + uint32_t u4PlePsePageSize; + + /* + * ucPpTxAddCnt: the extra pse resource needed by HW + */ + uint8_t ucPpTxAddCnt; + + uint8_t ucReserved[3]; +}; + + +/* modified version of WLAN_BEACON_FRAME_BODY_T for simplier buffering */ +struct WLAN_BEACON_FRAME_BODY_T_LOCAL { + /* Beacon frame body */ + uint32_t au4Timestamp[2]; /* Timestamp */ + uint16_t u2BeaconInterval; /* Beacon Interval */ + uint16_t u2CapInfo; /* Capability */ + /* Various IEs, start from SSID */ + uint8_t aucInfoElem[MAX_IE_LENGTH]; + /* This field is *NOT* carried by F/W but caculated by nic_rx */ + uint16_t u2IELength; +}; + +/* EVENT_SCAN_RESULT */ +struct EVENT_SCAN_RESULT { + int32_t i4RSSI; + uint32_t u4LinkQuality; + uint32_t u4DSConfig; /* Center frequency */ + uint32_t u4DomainInfo; /* Require CM opinion */ + uint32_t u4Reserved; + uint8_t ucNetworkType; + uint8_t ucOpMode; + uint8_t aucBssid[MAC_ADDR_LEN]; + uint8_t aucRatesEx[PARAM_MAX_LEN_RATES_EX]; + struct WLAN_BEACON_FRAME_BODY_T_LOCAL rBeaconFrameBody; +}; + +struct EVENT_PMKID_CANDIDATE_LIST { + uint32_t u4Version; /*!< Version */ + uint32_t u4NumCandidates; /*!< How many candidates follow */ + struct PARAM_PMKID_CANDIDATE arCandidateList[1]; +}; + +struct EVENT_CMD_RESULT { + uint8_t ucCmdID; + uint8_t ucStatus; + uint8_t aucReserved[2]; +}; + +/* CMD_ID_ACCESS_REG & EVENT_ID_ACCESS_REG */ +struct CMD_ACCESS_REG { + uint32_t u4Address; + uint32_t u4Data; +}; + +#if CFG_SUPPORT_CAL_RESULT_BACKUP_TO_HOST +/* CMD_ID_CAL_BACKUP_IN_HOST_V2 & EVENT_ID_CAL_BACKUP_IN_HOST_V2 */ +struct CMD_CAL_BACKUP_STRUCT_V2 { + uint8_t ucReason; + uint8_t ucAction; + uint8_t ucNeedResp; + uint8_t ucFragNum; + uint8_t ucRomRam; + uint32_t u4ThermalValue; + uint32_t u4Address; + uint32_t u4Length; + uint32_t u4RemainLength; + uint32_t au4Buffer[PARAM_CAL_DATA_DUMP_MAX_NUM]; +}; + +struct CMD_CAL_BACKUP_STRUCT { + uint8_t ucReason; + uint8_t ucAction; + uint8_t ucNeedResp; + uint8_t ucFragNum; + uint8_t ucRomRam; + uint32_t u4ThermalValue; + uint32_t u4Address; + uint32_t u4Length; + uint32_t u4RemainLength; +}; +#endif + +struct CMD_ACCESS_CHN_LOAD { + uint32_t u4Address; + uint32_t u4Data; + uint16_t u2Channel; + uint8_t aucReserved[2]; +}; + +struct CMD_GET_LTE_SAFE_CHN { + uint8_t ucIndex; + uint8_t ucFlags; + uint8_t aucReserved0[2]; + uint8_t aucReserved2[16]; +}; + +/* CMD_DUMP_MEMORY */ +struct CMD_DUMP_MEM { + uint32_t u4Address; + uint32_t u4Length; + uint32_t u4RemainLength; +#if CFG_SUPPORT_QA_TOOL + uint32_t u4IcapContent; +#endif /* CFG_SUPPORT_QA_TOOL */ + uint8_t ucFragNum; +}; + +struct EVENT_DUMP_MEM { + uint32_t u4Address; + uint32_t u4Length; + uint32_t u4RemainLength; +#if CFG_SUPPORT_QA_TOOL + uint32_t eIcapContent; +#endif /* CFG_SUPPORT_QA_TOOL */ + uint8_t ucFragNum; + uint8_t aucBuffer[1]; +}; + +#if CFG_SUPPORT_QA_TOOL +struct CMD_ACCESS_RX_STAT { + uint32_t u4SeqNum; + uint32_t u4TotalNum; +}; + +struct EVENT_ACCESS_RX_STAT { + uint32_t u4SeqNum; + uint32_t u4TotalNum; + uint32_t au4Buffer[1]; +}; + +#if CFG_SUPPORT_TX_BF +union CMD_TXBF_ACTION { + struct PROFILE_TAG_READ rProfileTagRead; + struct PROFILE_TAG_WRITE rProfileTagWrite; + struct PROFILE_DATA_READ rProfileDataRead; + struct PROFILE_DATA_WRITE rProfileDataWrite; + struct PROFILE_PN_READ rProfilePnRead; + struct PROFILE_PN_WRITE rProfilePnWrite; + struct TX_BF_SOUNDING_START rTxBfSoundingStart; + struct TX_BF_SOUNDING_STOP rTxBfSoundingStop; + struct TX_BF_TX_APPLY rTxBfTxApply; + struct TX_BF_PFMU_MEM_ALLOC rTxBfPfmuMemAlloc; + struct TX_BF_PFMU_MEM_RLS rTxBfPfmuMemRls; +#if CFG_SUPPORT_TX_BF_FPGA + struct TX_BF_PROFILE_SW_TAG_WRITE rTxBfProfileSwTagWrite; +#endif +}; + +#define CMD_DEVINFO_UPDATE_HDR_SIZE 8 +struct CMD_DEV_INFO_UPDATE { + uint8_t ucOwnMacIdx; + uint8_t ucReserve; + uint16_t u2TotalElementNum; + uint8_t ucAppendCmdTLV; + uint8_t aucReserve[3]; + uint8_t aucBuffer[0]; + /* CMD_DEVINFO_ACTIVE_T rCmdDevInfoActive; */ +}; + +#define CMD_BSSINFO_UPDATE_HDR_SIZE 8 +struct CMD_BSS_INFO_UPDATE { + uint8_t ucBssIndex; + uint8_t ucReserve; + uint16_t u2TotalElementNum; + uint32_t u4Reserve; + /* CMD_BSSINFO_BASIC_T rCmdBssInfoBasic; */ + uint8_t aucBuffer[0]; +}; + +/* STA record command */ +#define CMD_STAREC_UPDATE_HDR_SIZE 8 +struct CMD_STAREC_UPDATE { + uint8_t ucBssIndex; + uint8_t ucWlanIdx; + uint16_t u2TotalElementNum; + uint32_t u4Reserve; + uint8_t aucBuffer[0]; +}; + +struct EXT_EVENT_BF_STATUS_T { + uint8_t ucEventCategoryID; + uint8_t ucBw; + uint16_t u2SubCarrIdx; + u_int8_t fgBFer; + uint8_t aucReserved[3]; + uint8_t aucBuf[1000]; /* temp size */ +}; + +struct EVENT_PFMU_TAG_READ { + union PFMU_PROFILE_TAG1 ru4TxBfPFMUTag1; + union PFMU_PROFILE_TAG2 ru4TxBfPFMUTag2; +}; + +#if CFG_SUPPORT_MU_MIMO +struct EVENT_HQA_GET_QD { + uint32_t u4EventId; + uint32_t au4RawData[14]; +}; + +struct EVENT_HQA_GET_MU_CALC_LQ { + uint32_t u4EventId; + struct MU_STRUCT_LQ_REPORT rEntry; +}; + +struct EVENT_SHOW_GROUP_TBL_ENTRY { + uint32_t u4EventId; + uint8_t index; + uint8_t numUser: 2; + uint8_t BW: 2; + uint8_t NS0: 2; + uint8_t NS1: 2; + /* UINT_8 NS2:1; */ + /* UINT_8 NS3:1; */ + uint8_t PFIDUser0; + uint8_t PFIDUser1; + /* UINT_8 PFIDUser2; */ + /* UINT_8 PFIDUser3; */ + u_int8_t fgIsShortGI; + u_int8_t fgIsUsed; + u_int8_t fgIsDisable; + uint8_t initMcsUser0: 4; + uint8_t initMcsUser1: 4; + /* UINT_8 initMcsUser2:4; */ + /* UINT_8 initMcsUser3:4; */ + uint8_t dMcsUser0: 4; + uint8_t dMcsUser1: 4; + /* UINT_8 dMcsUser2:4; */ + /* UINT_8 dMcsUser3:4; */ +}; + +union CMD_MUMIMO_ACTION { + uint8_t ucMuMimoCategory; + uint8_t aucRsv[3]; + union { + struct MU_GET_CALC_INIT_MCS rMuGetCalcInitMcs; + struct MU_SET_INIT_MCS rMuSetInitMcs; + struct MU_SET_CALC_LQ rMuSetCalcLq; + struct MU_GET_LQ rMuGetLq; + struct MU_SET_SNR_OFFSET rMuSetSnrOffset; + struct MU_SET_ZERO_NSS rMuSetZeroNss; + struct MU_SPEED_UP_LQ rMuSpeedUpLq; + struct MU_SET_MU_TABLE rMuSetMuTable; + struct MU_SET_GROUP rMuSetGroup; + struct MU_GET_QD rMuGetQd; + struct MU_SET_ENABLE rMuSetEnable; + struct MU_SET_GID_UP rMuSetGidUp; + struct MU_TRIGGER_MU_TX rMuTriggerMuTx; + } unMuMimoParam; +}; +#endif /* CFG_SUPPORT_MU_MIMO */ +#endif /* CFG_SUPPORT_TX_BF */ +#endif /* CFG_SUPPORT_QA_TOOL */ + +struct CMD_SW_DBG_CTRL { + uint32_t u4Id; + uint32_t u4Data; + /* Debug Support */ + uint32_t u4DebugCnt[64]; +}; + +struct CMD_FW_LOG_2_HOST_CTRL { + uint8_t ucFwLog2HostCtrl; + uint8_t ucMcuDest; + uint8_t ucReserve[2]; +}; + +struct CMD_CHIP_CONFIG { + uint16_t u2Id; + uint8_t ucType; + uint8_t ucRespType; + uint16_t u2MsgSize; + uint8_t aucReserved0[2]; + uint8_t aucCmd[CHIP_CONFIG_RESP_SIZE]; +}; + +/* CMD_ID_LINK_ATTRIB */ +struct CMD_LINK_ATTRIB { + int8_t cRssiTrigger; + uint8_t ucDesiredRateLen; + uint16_t u2DesiredRate[32]; + uint8_t ucMediaStreamMode; + uint8_t aucReserved[1]; +}; + +/* CMD_ID_NIC_POWER_CTRL */ +struct CMD_NIC_POWER_CTRL { + uint8_t ucPowerMode; + uint8_t aucReserved[3]; +}; + +/* CMD_ID_POWER_SAVE_MODE */ +struct CMD_PS_PROFILE { + uint8_t ucBssIndex; + uint8_t ucPsProfile; + uint8_t aucReserved[2]; +}; + +#if CFG_SUPPORT_LOWLATENCY_MODE +/* CMD_ID_SET_LOW_LATENCY_MODE */ +struct LOW_LATENCY_MODE_SETTING { + u_int8_t fgEnable; /* Low Latency mode on/off */ + u_int8_t fgTxDupDetect; /* Start/stop Tx dup detect */ + u_int8_t fgTxDupCertQuery; /* Get Tx Dup Certificate */ + uint8_t aucReserved[5]; +}; + +struct CMD_LOW_LATENCY_MODE_HEADER { + uint8_t ucVersion; + uint8_t ucType; + uint8_t ucMagicCode; + uint8_t ucBufferLen; + struct LOW_LATENCY_MODE_SETTING rSetting; +}; +#endif + + +#if CFG_SUPPORT_P2P_RSSI_QUERY +/* EVENT_LINK_QUALITY */ +struct EVENT_LINK_QUALITY_EX { + int8_t cRssi; + int8_t cLinkQuality; + uint16_t u2LinkSpeed; + uint8_t ucMediumBusyPercentage; + uint8_t ucIsLQ0Rdy; + int8_t cRssiP2P; /* For P2P Network. */ + int8_t cLinkQualityP2P; + uint16_t u2LinkSpeedP2P; + uint8_t ucMediumBusyPercentageP2P; + uint8_t ucIsLQ1Rdy; +}; +#endif + +/* EVENT_ID_FW_SLEEPY_NOTIFY */ +struct EVENT_SLEEPY_INFO { + uint8_t ucSleepyState; + uint8_t aucReserved[3]; +}; + +/* CMD_BT_OVER_WIFI */ +struct CMD_BT_OVER_WIFI { + uint8_t ucAction; /* 0: query, 1: setup, 2: destroy */ + uint8_t ucChannelNum; + uint8_t rPeerAddr[PARAM_MAC_ADDR_LEN]; + uint16_t u2BeaconInterval; + uint8_t ucTimeoutDiscovery; + uint8_t ucTimeoutInactivity; + uint8_t ucRole; + uint8_t PAL_Capabilities; + uint8_t cMaxTxPower; + uint8_t ucChannelBand; + uint8_t ucReserved[1]; +}; + +#if (CFG_SUPPORT_DFS_MASTER == 1) +enum ENUM_REG_DOMAIN { + REG_DEFAULT = 0, + REG_JP_53, + REG_JP_56 +}; + +struct CMD_RDD_ON_OFF_CTRL { + uint8_t ucDfsCtrl; + uint8_t ucRddIdx; + uint8_t ucRddRxSel; + uint8_t ucSetVal; + uint8_t aucReserve[4]; +}; +#endif + +struct CMD_PERF_IND { + /* DWORD_0 - Common Part */ + uint8_t ucCmdVer; + uint8_t aucPadding0[1]; + uint16_t u2CmdLen; /* cmd size including common part and body. */ + /* DWORD_1 ~ x - Command Body */ + uint32_t u4VaildPeriod; /* in ms */ + /* Current State */ + uint32_t ulCurTxBytes[4]; /* in Bps */ + uint32_t ulCurRxBytes[4]; /* in Bps */ + uint16_t u2CurRxRate[4]; /* Unit 500 Kbps */ + uint8_t ucCurRxRCPI0[4]; + uint8_t ucCurRxRCPI1[4]; + uint8_t ucCurRxNss[4]; + uint32_t au4Reserve[63]; +}; + +#if CFG_SUPPORT_SMART_GEAR +struct CMD_SMART_GEAR_PARAM { + uint8_t ucSGEnable;/*0: disable, 1: Enable, 2: Action for ucSGSpcCmd*/ + uint8_t ucSGSpcCmd;/* 1: Force 1x1, 2: Force 2x2, 0: Automatic*/ + uint8_t ucNSSCap; /*NSS Capbility*/ + uint8_t ucSGCfg; /* DON'T SET, IT IS USED FOR WIFI.CFG WIFI*/ + /* DON'T SET, IT IS USED FOR WIFI.CFG WIFI 2.4G Favor ANT path*/ + uint8_t ucSG24GFavorANT; + /* DON'T SET, IT IS USED FOR WIFI.CFG WIFI 5G Favor ANT path*/ + uint8_t ucSG5GFavorANT; +}; + +struct EVENT_SMART_GEAT_STATE { + bool fgIsEnable; + uint32_t u4StateIdx; +}; +#endif + +/* EVENT_BT_OVER_WIFI */ +struct EVENT_BT_OVER_WIFI { + uint8_t ucLinkStatus; + uint8_t ucSelectedChannel; + int8_t cRSSI; + uint8_t ucReserved[1]; +}; + +/* Same with DOMAIN_SUBBAND_INFO */ +struct CMD_SUBBAND_INFO { + uint8_t ucRegClass; + uint8_t ucBand; + uint8_t ucChannelSpan; + uint8_t ucFirstChannelNum; + uint8_t ucNumChannels; + uint8_t aucReserved[3]; +}; + +/* CMD_SET_DOMAIN_INFO */ +struct CMD_SET_DOMAIN_INFO { + uint16_t u2CountryCode; + uint16_t u2IsSetPassiveScan; + struct CMD_SUBBAND_INFO rSubBand[6]; + + uint8_t uc2G4Bandwidth; /* CONFIG_BW_20_40M or CONFIG_BW_20M */ + uint8_t uc5GBandwidth; /* CONFIG_BW_20_40M or CONFIG_BW_20M */ + uint8_t aucReserved[2]; +}; + +#if CFG_SUPPORT_PWR_LIMIT_COUNTRY + +enum ENUM_PWR_LIMIT_TYPE { + PWR_LIMIT_TYPE_COMP_11AC = 0, + PWR_LIMIT_TYPE_COMP_11AG_11N = 1, + PWR_LIMIT_TYPE_COMP_11AX = 2, + PWR_LIMIT_TYPE_COMP_NUM, +}; + + +/* CMD_SET_PWR_LIMIT_TABLE */ +struct CMD_CHANNEL_POWER_LIMIT { + uint8_t ucCentralCh; + + int8_t cPwrLimitCCK; +#if (CFG_SUPPORT_DYNA_TX_PWR_CTRL_OFDM_SETTING == 1) + int8_t cPwrLimitOFDM_L; /* OFDM_L, 6M ~ 18M */ + int8_t cPwrLimitOFDM_H; /* OFDM_H, 24M ~ 54M */ +#endif /* CFG_SUPPORT_DYNA_TX_PWR_CTRL_OFDM_SETTING */ + int8_t cPwrLimit20L; /* MCS0~4 */ + int8_t cPwrLimit20H; /* MCS5~8 */ + int8_t cPwrLimit40L; /* MCS0~4 */ + int8_t cPwrLimit40H; /* MCS5~9 */ + int8_t cPwrLimit80L; /* MCS0~4 */ + int8_t cPwrLimit80H; /* MCS5~9 */ + int8_t cPwrLimit160L; /* MCS0~4 */ + int8_t cPwrLimit160H; /* MCS5~9 */ + + uint8_t ucFlag; /*Not used in driver*/ + uint8_t aucReserved[1]; +}; +struct CMD_CHANNEL_POWER_LIMIT_HE { /*HE SU design*/ + uint8_t ucCentralCh; + int8_t cPwrLimitRU26L; /* MCS0~4 */ + int8_t cPwrLimitRU26H; /* MCS5~9 */ + int8_t cPwrLimitRU26U; /* MCS10~11 */ + + int8_t cPwrLimitRU52L; /* MCS0~4 */ + int8_t cPwrLimitRU52H; /* MCS5~9 */ + int8_t cPwrLimitRU52U; /* MCS10~11 */ + + int8_t cPwrLimitRU106L; /* MCS0~4 */ + int8_t cPwrLimitRU106H; /* MCS5~9 */ + int8_t cPwrLimitRU106U; /* MCS10~11 */ + /*RU242/SU20*/ + int8_t cPwrLimitRU242L; /* MCS0~4 */ + int8_t cPwrLimitRU242H; /* MCS5~9 */ + int8_t cPwrLimitRU242U; /* MCS10~11 */ + /*RU484/SU40*/ + int8_t cPwrLimitRU484L; /* MCS0~4 */ + int8_t cPwrLimitRU484H; /* MCS5~9 */ + int8_t cPwrLimitRU484U; /* MCS10~11 */ + /*RU996/SU80*/ + int8_t cPwrLimitRU996L; /* MCS0~4 */ + int8_t cPwrLimitRU996H; /* MCS5~9 */ + int8_t cPwrLimitRU996U; /* MCS10~11 */ + + uint8_t ucFlag; + uint8_t ucValid; + +}; + +struct CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT { + /* D-WORD 0 */ + uint16_t u2CountryCode; + uint8_t ucCountryFlag; /*Not used in driver*/ + uint8_t ucNum; /*Numbers of channel to set power limit*/ + + /* D-WORD 1 */ + u_int8_t fgPwrTblKeep; + uint8_t ucBandIdx; + /* u1LimitType: enum ENUM_COUNTRY_CHANNEL_TXPOWER_LIMIT_FORMAT */ + uint8_t ucLimitType; + uint8_t au1Reserved[1]; + union { + /*Channel power limit entries to be set*/ + struct CMD_CHANNEL_POWER_LIMIT + rChannelPowerLimit[MAX_CMD_SUPPORT_CHANNEL_NUM]; + /*Channel HE power limit entries to be set*/ + struct CMD_CHANNEL_POWER_LIMIT_HE + rChPwrLimtHE[MAX_CMD_SUPPORT_CHANNEL_NUM]; + } u; + +}; + +#if (CFG_SUPPORT_SINGLE_SKU == 1) +struct CMD_CHANNEL_POWER_LIMIT_V2 { + uint8_t ucCentralCh; + uint8_t ucReserved[3]; + + uint8_t tx_pwr_dsss_cck; + uint8_t tx_pwr_dsss_bpsk; + + uint8_t tx_pwr_ofdm_bpsk; /* 6M, 9M */ + uint8_t tx_pwr_ofdm_qpsk; /* 12M, 18M */ + uint8_t tx_pwr_ofdm_16qam; /* 24M, 36M */ + uint8_t tx_pwr_ofdm_48m; + uint8_t tx_pwr_ofdm_54m; + + uint8_t tx_pwr_ht20_bpsk; /* MCS0*/ + uint8_t tx_pwr_ht20_qpsk; /* MCS1, MCS2*/ + uint8_t tx_pwr_ht20_16qam; /* MCS3, MCS4*/ + uint8_t tx_pwr_ht20_mcs5; /* MCS5*/ + uint8_t tx_pwr_ht20_mcs6; /* MCS6*/ + uint8_t tx_pwr_ht20_mcs7; /* MCS7*/ + + uint8_t tx_pwr_ht40_bpsk; /* MCS0*/ + uint8_t tx_pwr_ht40_qpsk; /* MCS1, MCS2*/ + uint8_t tx_pwr_ht40_16qam; /* MCS3, MCS4*/ + uint8_t tx_pwr_ht40_mcs5; /* MCS5*/ + uint8_t tx_pwr_ht40_mcs6; /* MCS6*/ + uint8_t tx_pwr_ht40_mcs7; /* MCS7*/ + uint8_t tx_pwr_ht40_mcs32; /* MCS32*/ + + uint8_t tx_pwr_vht20_bpsk; /* MCS0*/ + uint8_t tx_pwr_vht20_qpsk; /* MCS1, MCS2*/ + uint8_t tx_pwr_vht20_16qam; /* MCS3, MCS4*/ + uint8_t tx_pwr_vht20_64qam; /* MCS5, MCS6*/ + uint8_t tx_pwr_vht20_mcs7; + uint8_t tx_pwr_vht20_mcs8; + uint8_t tx_pwr_vht20_mcs9; + + uint8_t tx_pwr_vht_40; + uint8_t tx_pwr_vht_80; + uint8_t tx_pwr_vht_160c; + uint8_t tx_pwr_vht_160nc; + uint8_t tx_pwr_lg_40; + uint8_t tx_pwr_lg_80; + + uint8_t tx_pwr_1ss_delta; + uint8_t ucReserved_1[2]; +}; + +struct CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_V2 { + uint8_t ucNum; + uint8_t eband; /*ENUM_BAND_T*/ + uint8_t usReserved[2]; + uint32_t countryCode; + struct CMD_CHANNEL_POWER_LIMIT_V2 rChannelPowerLimit[0]; +}; + +#define BF_TX_PWR_LIMIT_SECTION_NUM 17 +#define BF_TX_PWR_LIMIT_ELEMENT_NUM 10 +#define TX_PWR_LIMIT_SECTION_NUM 9 +#define TX_PWR_LIMIT_ELEMENT_NUM 10 +#define TX_PWR_LIMIT_COUNTRY_STR_MAX_LEN 4 +#define TX_PWR_LIMIT_MAX_VAL 63 + +#define POWER_LIMIT_SKU_CCK_NUM 4 +#define POWER_LIMIT_SKU_OFDM_NUM 8 +#define POWER_LIMIT_SKU_HT20_NUM 8 +#define POWER_LIMIT_SKU_HT40_NUM 9 +#define POWER_LIMIT_SKU_VHT20_NUM 10 +#define POWER_LIMIT_SKU_VHT40_NUM 10 +#define POWER_LIMIT_SKU_VHT80_NUM 10 +#define POWER_LIMIT_SKU_VHT160_NUM 10 + +struct CHANNEL_TX_PWR_LIMIT { + uint8_t ucChannel; + int8_t rTxPwrLimitValue[TX_PWR_LIMIT_SECTION_NUM] + [TX_PWR_LIMIT_ELEMENT_NUM]; + int8_t rTxBfBackoff[POWER_LIMIT_TXBF_BACKOFF_PARAM_NUM]; +}; + +struct TX_PWR_LIMIT_DATA { + uint32_t countryCode; + uint32_t ucChNum; + struct CHANNEL_TX_PWR_LIMIT *rChannelTxPwrLimit; +}; + +#endif + +#endif + +struct PATTERN_DESCRIPTION { + uint8_t fgCheckBcA1; + uint8_t fgCheckMcA1; + uint8_t ePatternHeader; + uint8_t fgAndOp; + uint8_t fgNotOp; + uint8_t ucPatternMask; + uint16_t u2PatternOffset; + uint8_t aucPattern[8]; +}; + +struct CMD_RAW_PATTERN_CONFIGURATION { + struct PATTERN_DESCRIPTION arPatternDesc[4]; +}; + +struct CMD_PATTERN_FUNC_CONFIG { + u_int8_t fgBcA1En; + u_int8_t fgMcA1En; + u_int8_t fgBcA1MatchDrop; + u_int8_t fgMcA1MatchDrop; +}; + +struct EVENT_TX_DONE { + uint8_t ucPacketSeq; + uint8_t ucStatus; + uint16_t u2SequenceNumber; + + uint8_t ucWlanIndex; + uint8_t ucTxCount; + uint16_t u2TxRate; + + uint8_t ucFlag; + uint8_t ucTid; + uint8_t ucRspRate; + uint8_t ucRateTableIdx; + + uint8_t ucBandwidth; + uint8_t ucTxPower; + uint8_t ucFlushReason; + uint8_t aucReserved0[1]; + + uint32_t u4TxDelay; + uint32_t u4Timestamp; + uint32_t u4AppliedFlag; + + uint8_t aucRawTxS[28]; + + uint8_t aucReserved1[32]; +}; + +enum ENUM_TXS_APPLIED_FLAG { + TX_FRAME_IN_AMPDU_FORMAT = 0, + TX_FRAME_EXP_BF, + TX_FRAME_IMP_BF, + TX_FRAME_PS_BIT +}; + +enum ENUM_TXS_CONTROL_FLAG { + TXS_WITH_ADVANCED_INFO = 0, + TXS_IS_EXIST +}; + +#if (CFG_SUPPORT_DFS_MASTER == 1) +enum ENUM_DFS_CTRL { + RDD_STOP = 0, + RDD_START, + RDD_DET_MODE, + RDD_RADAR_EMULATE, + RDD_START_TXQ +}; +#endif + +struct CMD_BSS_ACTIVATE_CTRL { + uint8_t ucBssIndex; + uint8_t ucActive; + uint8_t ucNetworkType; + uint8_t ucOwnMacAddrIndex; + uint8_t aucBssMacAddr[6]; + uint8_t ucBMCWlanIndex; + uint8_t ucReserved; +}; + +enum ENUM_RTS_POLICY { + RTS_POLICY_AUTO, + RTS_POLICY_STATIC_BW, + RTS_POLICY_DYNAMIC_BW, + RTS_POLICY_LEGACY, + RTS_POLICY_NO_RTS +}; + +enum _ENUM_CMD_UPDATE_STA_RECORD_VER_T { + CMD_UPDATE_STAREC_VER0 = 0, + CMD_UPDATE_STAREC_VER1, + CMD_UPDATE_STAREC_VER_MAX +}; + +struct CMD_BEACON_TEMPLATE_UPDATE { + /* 0: update randomly, + * 1: update all, + * 2: delete all (1 and 2 will update directly without search) + */ + uint8_t ucUpdateMethod; + uint8_t ucBssIndex; + uint8_t aucReserved[2]; + uint16_t u2Capability; + uint16_t u2IELen; + uint8_t aucIE[MAX_IE_LENGTH]; +}; + +struct GSCN_CHANNEL_INFO { + uint8_t ucBand; + uint8_t ucChannelNumber; /* Channel Number */ + uint8_t ucPassive; /* 0:active, 1:passive scan; ignored for DFS */ + uint8_t aucReserved[1]; + uint32_t u4DwellTimeMs; /* dwell time hint */ +}; + +enum ENUM_WIFI_BAND { + WIFI_BAND_UNSPECIFIED, + WIFI_BAND_BG = 1, /* 2.4 GHz */ + WIFI_BAND_A = 2, /* 5 GHz without DFS */ + WIFI_BAND_A_DFS = 4, /* 5 GHz DFS only */ + WIFI_BAND_A_WITH_DFS = 6, /* 5 GHz with DFS */ + WIFI_BAND_ABG = 3, /* 2.4 GHz + 5 GHz; no DFS */ + WIFI_BAND_ABG_WITH_DFS = 7, /* 2.4 GHz + 5 GHz with DFS */ +}; + +struct GSCAN_BUCKET { + uint16_t u2BucketIndex; /* bucket index, 0 based */ + /* desired period, in millisecond; + * if this is too low, the firmware should choose to generate + * results as fast as it can instead of failing the command + */ + uint8_t ucBucketFreqMultiple; + /* report_events semantics - + * This is a bit field; which defines following bits - + * REPORT_EVENTS_EACH_SCAN + * report a scan completion event after scan. If this is not set + * then scan completion events should be reported if + * report_threshold_percent or report_threshold_num_scans is + * reached. + * REPORT_EVENTS_FULL_RESULTS + * forward scan results (beacons/probe responses + IEs) + * in real time to HAL, in addition to completion events + * Note: To keep backward compatibility, fire completion + * events regardless of REPORT_EVENTS_EACH_SCAN. + * REPORT_EVENTS_NO_BATCH + * controls if scans for this bucket should be placed in the + * history buffer + */ + uint8_t ucReportFlag; + uint8_t ucMaxBucketFreqMultiple; /* max_period / base_period */ + uint8_t ucStepCount; + uint8_t ucNumChannels; + uint8_t aucReserved[1]; + enum ENUM_WIFI_BAND + eBand; /* when UNSPECIFIED, use channel list */ + /* channels to scan; these may include DFS channels */ + struct GSCN_CHANNEL_INFO arChannelList[8]; +}; + +struct CMD_GSCN_REQ { + uint8_t ucFlags; + uint8_t ucNumScnToCache; + uint8_t aucReserved[2]; + uint32_t u4BufferThreshold; + uint32_t u4BasePeriod; /* base timer period in ms */ + uint32_t u4NumBuckets; + /* number of APs to store in each scan in the */ + uint32_t u4MaxApPerScan; + /* BSSID/RSSI history buffer (keep the highest RSSI APs) */ + struct GSCAN_BUCKET arBucket[8]; +}; + +struct CMD_GSCN_SCN_COFIG { + uint8_t ucNumApPerScn; /* GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN */ + uint32_t u4BufferThreshold; /* GSCAN_ATTRIBUTE_REPORT_THRESHOLD */ + uint32_t u4NumScnToCache; /* GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE */ +}; + +/* 20150107 Daniel Added complete channels number in the scan done event */ +/* before*/ +/* + * typedef struct EVENT_SCAN_DONE { + * UINT_8 ucSeqNum; + * UINT_8 ucSparseChannelValid; + * CHANNEL_INFO_T rSparseChannel; + * } EVENT_SCAN_DONE, *P_EVENT_SCAN_DONE; + */ +/* after */ + +struct CMD_BATCH_REQ { + uint8_t ucSeqNum; + uint8_t ucNetTypeIndex; + uint8_t ucCmd; /* Start/ Stop */ + /* an integer number of scans per batch */ + uint8_t ucMScan; + /* an integer number of the max AP to remember per scan */ + uint8_t ucBestn; + /* an integer number of highest-strength AP for which we'd */ + uint8_t ucRtt; + /* like approximate distance reported */ + uint8_t ucChannel; /* channels */ + uint8_t ucChannelType; + uint8_t ucChannelListNum; + uint8_t aucReserved[3]; + uint32_t u4Scanfreq; /* an integer number of seconds between scans */ + struct CHANNEL_INFO arChannelList[32]; /* channels */ +}; + +struct CMD_CH_PRIVILEGE { + uint8_t ucBssIndex; + uint8_t ucTokenID; + uint8_t ucAction; + uint8_t ucPrimaryChannel; + uint8_t ucRfSco; + uint8_t ucRfBand; + uint8_t ucRfChannelWidth; /* To support 80/160MHz bandwidth */ + uint8_t ucRfCenterFreqSeg1; /* To support 80/160MHz bandwidth */ + uint8_t ucRfCenterFreqSeg2; /* To support 80/160MHz bandwidth */ + uint8_t ucReqType; + uint8_t ucDBDCBand; + uint8_t aucReserved; + uint32_t u4MaxInterval; /* In unit of ms */ + uint8_t aucReserved2[8]; +}; + +struct CMD_TX_PWR { + int8_t cTxPwr2G4Cck; /* signed, in unit of 0.5dBm */ + int8_t cTxPwr2G4Dsss; /* signed, in unit of 0.5dBm */ + int8_t acReserved[2]; + + int8_t cTxPwr2G4OFDM_BPSK; + int8_t cTxPwr2G4OFDM_QPSK; + int8_t cTxPwr2G4OFDM_16QAM; + int8_t cTxPwr2G4OFDM_Reserved; + int8_t cTxPwr2G4OFDM_48Mbps; + int8_t cTxPwr2G4OFDM_54Mbps; + + int8_t cTxPwr2G4HT20_BPSK; + int8_t cTxPwr2G4HT20_QPSK; + int8_t cTxPwr2G4HT20_16QAM; + int8_t cTxPwr2G4HT20_MCS5; + int8_t cTxPwr2G4HT20_MCS6; + int8_t cTxPwr2G4HT20_MCS7; + + int8_t cTxPwr2G4HT40_BPSK; + int8_t cTxPwr2G4HT40_QPSK; + int8_t cTxPwr2G4HT40_16QAM; + int8_t cTxPwr2G4HT40_MCS5; + int8_t cTxPwr2G4HT40_MCS6; + int8_t cTxPwr2G4HT40_MCS7; + + int8_t cTxPwr5GOFDM_BPSK; + int8_t cTxPwr5GOFDM_QPSK; + int8_t cTxPwr5GOFDM_16QAM; + int8_t cTxPwr5GOFDM_Reserved; + int8_t cTxPwr5GOFDM_48Mbps; + int8_t cTxPwr5GOFDM_54Mbps; + + int8_t cTxPwr5GHT20_BPSK; + int8_t cTxPwr5GHT20_QPSK; + int8_t cTxPwr5GHT20_16QAM; + int8_t cTxPwr5GHT20_MCS5; + int8_t cTxPwr5GHT20_MCS6; + int8_t cTxPwr5GHT20_MCS7; + + int8_t cTxPwr5GHT40_BPSK; + int8_t cTxPwr5GHT40_QPSK; + int8_t cTxPwr5GHT40_16QAM; + int8_t cTxPwr5GHT40_MCS5; + int8_t cTxPwr5GHT40_MCS6; + int8_t cTxPwr5GHT40_MCS7; +}; + +struct CMD_TX_AC_PWR { + int8_t ucBand; +#if 0 + int8_t c11AcTxPwr_BPSK; + int8_t c11AcTxPwr_QPSK; + int8_t c11AcTxPwr_16QAM; + int8_t c11AcTxPwr_MCS5_MCS6; + int8_t c11AcTxPwr_MCS7; + int8_t c11AcTxPwr_MCS8; + int8_t c11AcTxPwr_MCS9; + int8_t c11AcTxPwrVht40_OFFSET; + int8_t c11AcTxPwrVht80_OFFSET; + int8_t c11AcTxPwrVht160_OFFSET; +#else + struct AC_PWR_SETTING_STRUCT rAcPwr; +#endif +}; + +struct CMD_RSSI_PATH_COMPASATION { + int8_t c2GRssiCompensation; + int8_t c5GRssiCompensation; +}; +struct CMD_5G_PWR_OFFSET { + int8_t cOffsetBand0; /* 4.915-4.980G */ + int8_t cOffsetBand1; /* 5.000-5.080G */ + int8_t cOffsetBand2; /* 5.160-5.180G */ + int8_t cOffsetBand3; /* 5.200-5.280G */ + int8_t cOffsetBand4; /* 5.300-5.340G */ + int8_t cOffsetBand5; /* 5.500-5.580G */ + int8_t cOffsetBand6; /* 5.600-5.680G */ + int8_t cOffsetBand7; /* 5.700-5.825G */ +}; + +struct CMD_PWR_PARAM { + uint32_t au4Data[28]; + uint32_t u4RefValue1; + uint32_t u4RefValue2; +}; + +struct CMD_PHY_PARAM { + uint8_t aucData[144]; /* eFuse content */ +}; + +struct CMD_AUTO_POWER_PARAM { + /* 0: Disable 1: Enalbe 0x10: Change parameters */ + uint8_t ucType; + uint8_t ucBssIndex; + uint8_t aucReserved[2]; + uint8_t aucLevelRcpiTh[3]; + uint8_t aucReserved2[1]; + int8_t aicLevelPowerOffset[3]; /* signed, in unit of 0.5dBm */ + uint8_t aucReserved3[1]; + uint8_t aucReserved4[8]; +}; + +/*for WMMAC, CMD_ID_UPDATE_AC_PARAMS*/ +struct CMD_UPDATE_AC_PARAMS { + uint8_t ucAcIndex; /*0 ~3, from AC0 to AC3*/ + uint8_t ucBssIdx; /*no use*/ + /* if 0, disable ACM for ACx specified by + ** ucAcIndex, otherwise in unit of 32us + */ + uint16_t u2MediumTime; + /* rate to be used to tx packet with priority + ** ucAcIndex , unit: bps + */ + uint32_t u4PhyRate; + uint16_t u2EDCALifeTime; /* msdu life time for this TC, unit: 2TU */ + /* if we use fix rate to tx packets, should tell + ** firmware the limited retries + */ + uint8_t ucRetryCount; + uint8_t aucReserved[5]; +}; + +/* S56 Traffic Stream Metrics */ +struct CMD_SET_TSM_STATISTICS_REQUEST { + uint8_t ucEnabled; /* 0, disable; 1, enable; */ + uint8_t ucBssIdx; /* always AIS Bss index now */ + uint8_t ucAcIndex; /* wmm ac index, the statistics should be on this TC + */ + uint8_t ucTid; + + uint8_t aucPeerAddr + [MAC_ADDR_LEN]; /* packet to the target address to be mesured */ + uint8_t ucBin0Range; + uint8_t aucReserved[3]; + + /* if this variable is 0, followed variables are meaningless + ** only report once for a same trigger condition in this time frame + ** for triggered mode: bit(0):average, bit(1):consecutive, + ** bit(2):delay + */ + uint8_t ucTriggerCondition; + uint8_t ucAvgErrThreshold; + uint8_t ucConsecutiveErrThreshold; + uint8_t ucDelayThreshold; + uint8_t ucMeasureCount; + uint8_t ucTriggerTimeout; /* unit: 100 TU*/ +}; + +struct CMD_GET_TSM_STATISTICS { + uint8_t ucBssIdx; /* always AIS Bss now */ + /* wmm ac index, the statistics should be on this TC or TS */ + uint8_t ucAcIndex; + uint8_t ucTid; /* */ + + uint8_t aucPeerAddr + [MAC_ADDR_LEN]; /* indicating the RA for the measured frames */ + /* for triggered mode: bit(0):average, bit(1):consecutive, + ** bit(2):delay + */ + uint8_t ucReportReason; + uint16_t u2Reserved; + + uint32_t u4PktTxDoneOK; + uint32_t u4PktDiscard; /* u2PktTotal - u2PktTxDoneOK */ + uint32_t u4PktFail; /* failed count for exceeding retry limit */ + uint32_t u4PktRetryTxDoneOK; + uint32_t u4PktQosCfPollLost; + + /* 802.11k - Average Packet Transmission delay for all packets per this + ** TC or TS + */ + uint32_t u4AvgPktTxDelay; + /* 802.11k - Average Packet Queue Delay */ + uint32_t u4AvgPktQueueDelay; + uint64_t u8StartTime; /* represented by TSF */ + /* sum of packets whose packet tx delay is less than Bi (i=0~6) range + ** value(unit: TU) + */ + uint32_t au4PktCntBin[6]; +}; + +struct CMD_DBDC_SETTING { + uint8_t ucDbdcEn; + uint8_t ucWmmBandBitmap; + uint8_t ucUpdateSettingNextChReq; + uint8_t aucPadding0[1]; + uint8_t ucCmdVer; + uint8_t aucPadding1[1]; + uint16_t u2CmdLen; + uint8_t ucPrimaryChannel; + uint8_t ucWmmQueIdx; + uint8_t aucPadding2[2]; + uint8_t aucPadding3[24]; +}; + +#if (CFG_SUPPORT_DFS_MASTER == 1) +struct LONG_PULSE_BUFFER { + uint32_t u4LongStartTime; + uint16_t u2LongPulseWidth; +}; + +struct PERIODIC_PULSE_BUFFER { + uint32_t u4PeriodicStartTime; + uint16_t u2PeriodicPulseWidth; + int16_t i2PeriodicPulsePower; +}; + +struct EVENT_RDD_REPORT { + /*0: Only report radar detected; 1: Add parameter reports*/ + uint8_t ucRadarReportMode; + uint8_t ucRddIdx; + uint8_t ucLongDetected; + uint8_t ucPeriodicDetected; + uint8_t ucLPBNum; + uint8_t ucPPBNum; + uint8_t ucLPBPeriodValid; + uint8_t ucLPBWidthValid; + uint8_t ucPRICountM1; + uint8_t ucPRICountM1TH; + uint8_t ucPRICountM2; + uint8_t ucPRICountM2TH; + uint32_t u4PRI1stUs; + struct LONG_PULSE_BUFFER arLpbContent[32]; + struct PERIODIC_PULSE_BUFFER arPpbContent[32]; +}; +#endif + +struct EVENT_DEBUG_MSG { + uint16_t u2DebugMsgId; + uint8_t ucMsgType; + uint8_t ucFlags; /* unused */ + uint32_t u4Value; /* memory addre or ... */ + uint16_t u2MsgSize; + uint8_t aucReserved0[2]; + uint8_t aucMsg[1]; +}; + +struct CMD_EDGE_TXPWR_LIMIT { + int8_t cBandEdgeMaxPwrCCK; + int8_t cBandEdgeMaxPwrOFDM20; + int8_t cBandEdgeMaxPwrOFDM40; + int8_t cBandEdgeMaxPwrOFDM80; +}; + +struct CMD_POWER_OFFSET { + uint8_t ucBand; /*1:2.4G ; 2:5G */ + /*the max num subband is 5G, devide with 8 subband */ + uint8_t ucSubBandOffset[MAX_SUBBAND_NUM_5G]; + uint8_t aucReverse[3]; + +}; + +struct CMD_NVRAM_SETTING { + + struct WIFI_CFG_PARAM_STRUCT rNvramSettings; + +}; +struct CMD_NVRAM_FRAGMENT { + /*restrict NVRAM TX CMD size to 1500 bytes*/ + /*because FW WFDMA MAX buf size is 1600 Byte*/ + uint8_t aucReverse[1500]; +}; +#if CFG_SUPPORT_TDLS +struct CMD_TDLS_CH_SW { + u_int8_t fgIsTDLSChSwProhibit; + /* uint8_t ucBssIndex; */ +}; +#endif + +struct CMD_SET_DEVICE_MODE { + uint16_t u2ChipID; + uint16_t u2Mode; +}; + +#if CFG_SUPPORT_RDD_TEST_MODE +struct CMD_RDD_CH { + uint8_t ucRddTestMode; + uint8_t ucRddShutCh; + uint8_t ucRddStartCh; + uint8_t ucRddStopCh; + uint8_t ucRddDfs; + uint8_t ucReserved; + uint8_t ucReserved1; + uint8_t ucReserved2; +}; +#endif + +struct EVENT_ICAP_STATUS { + uint8_t ucRddStatus; + uint8_t aucReserved[3]; + uint32_t u4StartAddress; + uint32_t u4IcapSieze; +#if CFG_SUPPORT_QA_TOOL + uint32_t u4IcapContent; +#endif /* CFG_SUPPORT_QA_TOOL */ +}; + +#if CFG_SUPPORT_QA_TOOL +struct ADC_BUS_FMT { + uint32_t u4Dcoc0Q: 14; /* [13:0] */ + uint32_t u4Dcoc0I: 14; /* [27:14] */ + uint32_t u4DbgData1: 4; /* [31:28] */ + + uint32_t u4Dcoc1Q: 14; /* [45:32] */ + uint32_t u4Dcoc1I: 14; /* [46:59] */ + uint32_t u4DbgData2: 4; /* [63:60] */ + + uint32_t u4DbgData3; /* [95:64] */ +}; + +struct IQC_BUS_FMT { + int32_t u4Iqc0Q: 12; /* [11:0] */ + int32_t u4Iqc0I: 12; /* [23:12] */ + int32_t u4Na1: 8; /* [31:24] */ + + int32_t u4Iqc1Q: 12; /* [43:32] */ + int32_t u4Iqc1I: 12; /* [55:44] */ + int32_t u4Na2: 8; /* [63:56] */ + + int32_t u4Na3; /* [95:64] */ +}; + +struct IQC_160_BUS_FMT { + int32_t u4Iqc0Q1: 12; /* [11:0] */ + int32_t u4Iqc0I1: 12; /* [23:12] */ + uint32_t u4Iqc0Q0P1: 8; /* [31:24] */ + + int32_t u4Iqc0Q0P2: 4; /* [35:32] */ + int32_t u4Iqc0I0: 12; /* [47:36] */ + int32_t u4Iqc1Q1: 12; /* [59:48] */ + uint32_t u4Iqc1I1P1: 4; /* [63:60] */ + + int32_t u4Iqc1I1P2: 8; /* [71:64] */ + int32_t u4Iqc1Q0: 12; /* [83:72] */ + int32_t u4Iqc1I0: 12; /* [95:84] */ +}; + +struct SPECTRUM_BUS_FMT { + int32_t u4DcocQ: 12; /* [11:0] */ + int32_t u4DcocI: 12; /* [23:12] */ + int32_t u4LpfGainIdx: 4; /* [27:24] */ + int32_t u4LnaGainIdx: 2; /* [29:28] */ + int32_t u4AssertData: 2; /* [31:30] */ +}; + +struct PACKED_ADC_BUS_FMT { + uint32_t u4AdcQ0T2: 4; /* [19:16] */ + uint32_t u4AdcQ0T1: 4; /* [11:8] */ + uint32_t u4AdcQ0T0: 4; /* [3:0] */ + + uint32_t u4AdcI0T2: 4; /* [23:20] */ + uint32_t u4AdcI0T1: 4; /* [15:12] */ + uint32_t u4AdcI0T0: 4; /* [7:4] */ + + uint32_t u4AdcQ0T5: 4; /* [43:40] */ + uint32_t u4AdcQ0T4: 4; /* [35:32] */ + uint32_t u4AdcQ0T3: 4; /* [27:24] */ + + uint32_t u4AdcI0T5: 4; /* [47:44] */ + uint32_t u4AdcI0T4: 4; /* [39:36] */ + uint32_t u4AdcI0T3: 4; /* [31:28] */ + + uint32_t u4AdcQ1T2: 4; /* [19:16] */ + uint32_t u4AdcQ1T1: 4; /* [11:8] */ + uint32_t u4AdcQ1T0: 4; /* [3:0] */ + + uint32_t u4AdcI1T2: 4; /* [23:20] */ + uint32_t u4AdcI1T1: 4; /* [15:12] */ + uint32_t u4AdcI1T0: 4; /* [7:4] */ + + uint32_t u4AdcQ1T5: 4; /* [43:40] */ + uint32_t u4AdcQ1T4: 4; /* [35:32] */ + uint32_t u4AdcQ1T3: 4; /* [27:24] */ + + uint32_t u4AdcI1T5: 4; /* [47:44] */ + uint32_t u4AdcI1T4: 4; /* [39:36] */ + uint32_t u4AdcI1T3: 4; /* [31:28] */ +}; + +union ICAP_BUS_FMT { + struct ADC_BUS_FMT rAdcBusData; /* 12 bytes */ + struct IQC_BUS_FMT rIqcBusData; /* 12 bytes */ + struct IQC_160_BUS_FMT rIqc160BusData; /* 12 bytes */ + struct SPECTRUM_BUS_FMT rSpectrumBusData; /* 4 bytes */ + struct PACKED_ADC_BUS_FMT rPackedAdcBusData; /* 12 bytes */ +}; +#endif /* CFG_SUPPORT_QA_TOOL */ + +struct CMD_SET_TXPWR_CTRL { + int8_t c2GLegacyStaPwrOffset; /* Unit: 0.5dBm, default: 0 */ + int8_t c2GHotspotPwrOffset; + int8_t c2GP2pPwrOffset; + int8_t c2GBowPwrOffset; + int8_t c5GLegacyStaPwrOffset; /* Unit: 0.5dBm, default: 0 */ + int8_t c5GHotspotPwrOffset; + int8_t c5GP2pPwrOffset; + int8_t c5GBowPwrOffset; + /* TX power policy when concurrence + * in the same channel + * 0: Highest power has priority + * 1: Lowest power has priority + */ + uint8_t ucConcurrencePolicy; + int8_t acReserved1[3]; /* Must be zero */ + + /* Power limit by channel for all data rates */ + int8_t acTxPwrLimit2G[14]; /* Channel 1~14, Unit: 0.5dBm */ + int8_t acTxPwrLimit5G[4]; /* UNII 1~4 */ + int8_t acReserved2[2]; /* Must be zero */ +}; + +struct SSID_MATCH_SETS { + int32_t i4RssiThresold; + uint8_t aucSsid[32]; + uint8_t ucSsidLen; + uint8_t aucPadding_1[3]; +}; + +struct CMD_SCHED_SCAN_REQ { + uint8_t ucVersion; + uint8_t ucSeqNum; + uint8_t fgStopAfterIndication; + uint8_t ucSsidNum; + uint8_t ucMatchSsidNum; + uint8_t aucPadding_0; + uint16_t u2IELen; + struct PARAM_SSID auSsid[10]; + struct SSID_MATCH_SETS auMatchSsid[16]; + uint8_t ucChannelType; + uint8_t ucChnlNum; + uint8_t ucMspEntryNum; + uint8_t ucScnFuncMask; + struct CHANNEL_INFO aucChannel[64]; + uint16_t au2MspList[10]; + uint8_t ucBssIndex; + uint32_t u4DelayStartInSec; + uint32_t u4FastScanIteration; + uint32_t u4FastScanPeriod; + uint32_t u4SlowScanPeriod; + uint8_t aucPadding_3[47]; + /* keep last */ + uint8_t aucIE[0]; /* MUST be the last for IE content */ +}; + +struct EVENT_SCHED_SCAN_DONE { + uint8_t ucSeqNum; + uint8_t ucStatus; + uint8_t aucReserved[2]; +}; + +enum ENUM_HIF_TYPE { + ENUM_HIF_TYPE_SDIO = 0x00, + ENUM_HIF_TYPE_USB = 0x01, + ENUM_HIF_TYPE_PCIE = 0x02, + ENUM_HIF_TYPE_GPIO = 0x03, +}; + +enum ENUM_HIF_DIRECTION { + ENUM_HIF_TX = 0x01, + ENUM_HIF_RX = 0x02, + ENUM_HIF_TRX = 0x03, +}; + +enum ENUM_HIF_TRAFFIC_STATUS { + ENUM_HIF_TRAFFIC_BUSY = 0x01, + ENUM_HIF_TRAFFIC_IDLE = 0x02, + ENUM_HIF_TRAFFIC_INVALID = 0x3, +}; + +struct EVENT_HIF_CTRL { + uint8_t ucHifType; + uint8_t ucHifTxTrafficStatus; + uint8_t ucHifRxTrafficStatus; + uint8_t ucHifSuspend; + uint8_t aucReserved2[32]; +}; + +#if CFG_SUPPORT_BUILD_DATE_CODE +struct CMD_GET_BUILD_DATE_CODE { + uint8_t aucReserved[4]; +}; +#endif + +struct CMD_GET_STA_STATISTICS { + uint8_t ucIndex; + uint8_t ucFlags; + uint8_t ucReadClear; + uint8_t ucLlsReadClear; + uint8_t aucMacAddr[MAC_ADDR_LEN]; + uint8_t ucResetCounter; + uint8_t aucReserved1[1]; + uint8_t aucReserved2[16]; +}; + +/* per access category statistics */ +struct WIFI_WMM_AC_STAT_GET_FROM_FW { + uint32_t u4TxFailMsdu; + uint32_t u4TxRetryMsdu; +}; + +/* CFG_SUPPORT_WFD */ +struct EVENT_STA_STATISTICS { + /* Event header */ + /* UINT_16 u2Length; */ + /* Must be filled with 0x0001 (EVENT Packet) */ + /* UINT_16 u2Reserved1; */ + /* UINT_8 ucEID; */ + /* UINT_8 ucSeqNum; */ + /* UINT_8 aucReserved2[2]; */ + + /* Event Body */ + uint8_t ucVersion; + uint8_t aucReserved1[3]; + uint32_t u4Flags; /* Bit0: valid */ + + uint8_t ucStaRecIdx; + uint8_t ucNetworkTypeIndex; + uint8_t ucWTEntry; + uint8_t aucReserved4[1]; + + uint8_t ucMacAddr[MAC_ADDR_LEN]; + uint8_t ucPer; /* base: 128 */ + uint8_t ucRcpi; + + uint32_t u4PhyMode; /* SGI BW */ + uint16_t u2LinkSpeed; /* unit is 0.5 Mbits */ + uint8_t ucLinkQuality; + uint8_t ucLinkReserved; + + uint32_t u4TxCount; + uint32_t u4TxFailCount; + uint32_t u4TxLifeTimeoutCount; + uint32_t u4TxDoneAirTime; + /* Transmit in the air (wtbl) */ + uint32_t u4TransmitCount; + /* Transmit without ack/ba in the air (wtbl) */ + uint32_t u4TransmitFailCount; + + struct WIFI_WMM_AC_STAT_GET_FROM_FW + arLinkStatistics[AC_NUM]; /*link layer statistics */ + + uint8_t ucTemperature; + uint8_t ucSkipAr; + uint8_t ucArTableIdx; + uint8_t ucRateEntryIdx; + uint8_t ucRateEntryIdxPrev; + uint8_t ucTxSgiDetectPassCnt; + uint8_t ucAvePer; +#if (CFG_SUPPORT_RA_GEN == 0) + uint8_t aucArRatePer[AR_RATE_TABLE_ENTRY_MAX]; + uint8_t aucRateEntryIndex[AUTO_RATE_NUM]; +#else + uint32_t u4AggRangeCtrl_0; + uint32_t u4AggRangeCtrl_1; + uint8_t ucRangeType; +#if (CFG_SUPPORT_CONNAC2X == 0) + uint8_t aucReserved5[24]; +#else + uint32_t u4AggRangeCtrl_2; + uint32_t u4AggRangeCtrl_3; + uint8_t aucReserved5[16]; +#endif +#endif + uint8_t ucArStateCurr; + uint8_t ucArStatePrev; + uint8_t ucArActionType; + uint8_t ucHighestRateCnt; + uint8_t ucLowestRateCnt; + uint16_t u2TrainUp; + uint16_t u2TrainDown; + uint32_t u4Rate1TxCnt; + uint32_t u4Rate1FailCnt; + struct TX_VECTOR_BBP_LATCH rTxVector[ENUM_BAND_NUM]; + struct MIB_INFO_STAT rMibInfo[ENUM_BAND_NUM]; + u_int8_t fgIsForceTxStream; + u_int8_t fgIsForceSeOff; +#if (CFG_SUPPORT_RA_GEN == 0) + uint8_t aucReserved6[17]; +#else + uint16_t u2RaRunningCnt; + uint8_t ucRaStatus; + uint8_t ucFlag; + uint8_t aucTxQuality[MAX_TX_QUALITY_INDEX]; + uint8_t ucTxRateUpPenalty; + uint8_t ucLowTrafficMode; + uint8_t ucLowTrafficCount; + uint8_t ucLowTrafficDashBoard; + uint8_t ucDynamicSGIState; + uint8_t ucDynamicSGIScore; + uint8_t ucDynamicBWState; + uint8_t ucDynamicGband256QAMState; + uint8_t ucVhtNonSpRateState; +#endif + uint8_t aucReserved[4]; +}; + +struct EVENT_LTE_SAFE_CHN { + uint8_t ucVersion; + uint8_t aucReserved[3]; + uint32_t u4Flags; /* Bit0: valid */ + struct LTE_SAFE_CHN_INFO rLteSafeChn; +}; + +#if CFG_SUPPORT_SNIFFER +struct CMD_MONITOR_SET_INFO { + uint8_t ucEnable; + uint8_t ucBand; + uint8_t ucPriChannel; + uint8_t ucSco; + uint8_t ucChannelWidth; + uint8_t ucChannelS1; + uint8_t ucChannelS2; + uint8_t aucResv[9]; +}; +#endif + +struct CMD_STATS_LOG { + uint32_t u4DurationInMs; + uint8_t aucReserved[32]; +}; + +struct EVENT_WIFI_RDD_TEST { + uint32_t u4FuncIndex; + uint32_t u4FuncLength; + uint32_t u4Prefix; + uint32_t u4Count; + uint8_t ucRddIdx; + uint8_t aucReserve[3]; + uint8_t aucBuffer[0]; +}; + +#if CFG_SUPPORT_MSP +/* EVENT_ID_WTBL_INFO */ +struct EVENT_WLAN_INFO { + + struct PARAM_TX_CONFIG rWtblTxConfig; + struct PARAM_SEC_CONFIG rWtblSecConfig; + struct PARAM_KEY_CONFIG rWtblKeyConfig; + struct PARAM_PEER_RATE_INFO rWtblRateInfo; + struct PARAM_PEER_BA_CONFIG rWtblBaConfig; + struct PARAM_PEER_CAP rWtblPeerCap; + struct PARAM_PEER_RX_COUNTER_ALL rWtblRxCounter; + struct PARAM_PEER_TX_COUNTER_ALL rWtblTxCounter; +}; + +/* EVENT_ID_MIB_INFO */ +struct EVENT_MIB_INFO { + struct HW_MIB_COUNTER rHwMibCnt; + struct HW_MIB2_COUNTER rHwMib2Cnt; + struct HW_TX_AMPDU_METRICS rHwTxAmpduMts; + +}; +#endif + +/*#if (CFG_EEPROM_PAGE_ACCESS == 1)*/ +struct EVENT_ACCESS_EFUSE { + + uint32_t u4Address; + uint32_t u4Valid; + uint8_t aucData[16]; + +}; + +struct EXT_EVENT_EFUSE_FREE_BLOCK { + uint16_t u2FreeBlockNum; + uint8_t aucReserved[2]; +}; + +struct EXT_EVENT_GET_TX_POWER { + + uint8_t ucTxPwrType; + uint8_t ucEfuseAddr; + uint8_t ucTx0TargetPower; + uint8_t ucDbdcIdx; + +}; + +struct EXT_EVENT_RF_TEST_RESULT_T { + uint32_t u4FuncIndex; + uint32_t u4PayloadLength; + uint8_t aucEvent[0]; +}; + +struct EXT_EVENT_RBIST_DUMP_DATA_T { + uint32_t u4FuncIndex; + uint32_t u4PktNum; + uint32_t u4Bank; + uint32_t u4DataLength; + uint32_t u4WFCnt; + uint32_t u4SmplCnt; + uint32_t u4Reserved[6]; + uint32_t u4Data[256]; +}; + +struct EXT_EVENT_RBIST_CAP_STATUS_T { + uint32_t u4FuncIndex; + uint32_t u4CapDone; + uint32_t u4Reserved[15]; +}; + +struct EXT_EVENT_RECAL_DATA_T { + uint32_t u4FuncIndex; + uint32_t u4Type; /* 0 for string, 1 for int data */ + union { + uint8_t ucData[32]; + uint32_t u4Data[3]; + } u; +}; + + +struct CMD_SUSPEND_MODE_SETTING { + uint8_t ucBssIndex; + uint8_t ucEnableSuspendMode; + uint8_t ucMdtim; /* LP parameter */ + uint8_t ucReserved1[1]; + uint8_t ucReserved2[64]; +}; + +struct EVENT_UPDATE_COEX_PHYRATE { + uint8_t ucVersion; + uint8_t aucReserved1[3]; /* 4 byte alignment */ + uint32_t u4Flags; + uint32_t au4PhyRateLimit[MAX_BSSID_NUM + 1]; + uint8_t ucSupportSisoOnly; + uint8_t ucWfPathSupport; + uint8_t aucReserved2[2]; /* 4 byte alignment */ +}; + +#if (CFG_SUPPORT_TWT == 1) +/* + * Important: Used for Communication between Host and WM-CPU, + * should be packed and DW-aligned and in little-endian format + */ +struct _EXT_CMD_TWT_ARGT_UPDATE_T { + /* DW0 */ + uint8_t ucAgrtTblIdx; + uint8_t ucAgrtCtrlFlag; + uint8_t ucOwnMacId; + uint8_t ucFlowId; + /* DW1 */ + /* Specify the peer ID (MSB=0) or group ID (MSB=1) + * (10 bits for StaIdx, MSB to identify if it is for groupId) + */ + uint16_t u2PeerIdGrpId; + + /* Same as SPEC definition. 8 bits, in unit of 256 us */ + uint8_t ucAgrtSpDuration; + /* So that we know which BSS TSF should be used for this AGRT */ + uint8_t ucBssIndex; + /* DW2, DW3, DW4 */ + uint32_t u4AgrtSpStartTsfLow; + uint32_t u4AgrtSpStartTsfHigh; + uint16_t u2AgrtSpWakeIntvlMantissa; + uint8_t ucAgrtSpWakeIntvlExponent; + uint8_t ucIsRoleAp; /* 1: AP, 0: STA */ + /* DW5 */ + /* For Bitmap definition, please refer to + * TWT_AGRT_PARA_BITMAP_IS_TRIGGER and etc + */ + uint8_t ucAgrtParaBitmap; + uint8_t ucReserved_a; + /* Following field is valid ONLY when peerIdGrpId is a group ID */ + uint16_t u2Reserved_b; + /* DW6 */ + uint8_t ucGrpMemberCnt; + uint8_t ucReserved_c; + uint16_t u2Reserved_d; + /* DW7 ~ DW10 */ + uint16_t au2StaList[TWT_GRP_MAX_MEMBER_CNT]; +}; +#endif + +#if (CFG_SUPPORT_802_11AX == 1) +struct _CMD_RLM_UPDATE_SR_PARMS_T { + /* DWORD_0 - Common Part */ + uint8_t ucCmdVer; + uint8_t aucPadding0[1]; + uint16_t u2CmdLen; /* Cmd size including common part and body */ + + /* DWORD_1 afterwards - Command Body */ + uint8_t ucBssIndex; + uint8_t ucSRControl; + uint8_t ucNonSRGObssPdMaxOffset; + uint8_t ucSRGObssPdMinOffset; + uint8_t ucSRGObssPdMaxOffset; + uint8_t aucPadding1[3]; + uint32_t u4SRGBSSColorBitmapLow; + uint32_t u4SRGBSSColorBitmapHigh; + uint32_t u4SRGPartialBSSIDBitmapLow; + uint32_t u4SRGPartialBSSIDBitmapHigh; + + uint8_t aucPadding2[32]; +}; + +struct _EXTRA_ARG_TSF_T { + uint8_t ucHwBssidIndex; + uint8_t aucReserved[3]; +}; + +union _EXTRA_ARG_MAC_INFO_T { + struct _EXTRA_ARG_TSF_T rTsfArg; +}; + +struct _EXT_CMD_GET_MAC_INFO_T { + uint16_t u2MacInfoId; + uint8_t aucReserved[2]; + union _EXTRA_ARG_MAC_INFO_T rExtraArgument; +}; +#endif + +struct TSF_RESULT_T { + uint32_t u4TsfBitsLow; + uint32_t u4TsfBitsHigh; +}; + +union MAC_INFO_RESULT_T { + struct TSF_RESULT_T rTsfResult; +}; + +struct EXT_EVENT_MAC_INFO_T { + uint16_t u2MacInfoId; + uint8_t aucReserved[2]; + union MAC_INFO_RESULT_T rMacInfoResult; +}; + +struct EXT_CMD_EVENT_DUMP_MEM_T { + uint32_t u4MemAddr; + uint8_t ucData[64]; +}; + +/*#endif*/ +struct CMD_TDLS_PS_T { + /* 0: disable tdls power save; 1: enable tdls power save */ + uint8_t ucIsEnablePs; + uint8_t aucReserved[3]; +}; + +/** struct for power rate control command **/ +struct CMD_POWER_RATE_TXPOWER_CTRL_T { + uint8_t u1PowerCtrlFormatId; + uint8_t u1PhyMode; + uint8_t u1TxRate; + uint8_t u1BW; + uint8_t u1BandIdx; + int8_t i1TxPower; + uint8_t u1Reserved[2]; +}; + + +#if (CFG_SUPPORT_TXPOWER_INFO == 1) +struct CMD_TX_POWER_SHOW_INFO_T { + uint8_t ucPowerCtrlFormatId; + uint8_t ucTxPowerInfoCatg; + uint8_t ucBandIdx; + uint8_t ucReserved; +}; + +struct EXT_EVENT_TXPOWER_ALL_RATE_POWER_INFO_T { + uint8_t ucTxPowerCategory; + uint8_t ucBandIdx; + uint8_t ucChBand; + uint8_t ucReserved; + + /* Rate power info */ + struct FRAME_POWER_CONFIG_INFO_T rRatePowerInfo; + + /* tx Power Max/Min Limit info */ + int8_t icPwrMaxBnd; + int8_t icPwrMinBnd; + uint8_t ucReserved2; +}; +#endif + +struct EXT_EVENT_MAX_AMSDU_LENGTH_UPDATE { + uint8_t ucWlanIdx; + uint8_t ucAmsduLen; +}; + +struct EVENT_LOW_LATENCY_INFO { + /* DWORD_0 - Common Part */ + uint8_t ucEvtVer; + uint8_t aucPadding0[1]; + uint16_t u2EvtLen; + + /* DWORD_1 - afterwards */ + u_int8_t fgTxDupCert; + u_int8_t fgTxDupEnable; + uint8_t aucPadding1[2]; + uint8_t aucPayload[1024]; +}; + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ +#define NIC_FILL_CMD_TX_HDR(__prAd, __pucInfoBuffer, __u2InfoBufLen, \ + __ucCID, __ucPktTypeID, __pucSeqNum, __fgSetQuery, __ppCmdBuf, \ + __bucInitCmd, __ucExtCID, __ucS2DIndex) \ +{ \ + struct mt66xx_chip_info *__prChipInfo; \ + struct WIFI_CMD_INFO __wifi_cmd_info; \ + __prChipInfo = __prAd->chip_info; \ + __wifi_cmd_info.pucInfoBuffer = __pucInfoBuffer; \ + __wifi_cmd_info.u2InfoBufLen = __u2InfoBufLen; \ + __wifi_cmd_info.ucCID = __ucCID; \ + __wifi_cmd_info.ucExtCID = __ucExtCID; \ + __wifi_cmd_info.ucPktTypeID = __ucPktTypeID; \ + __wifi_cmd_info.ucSetQuery = __fgSetQuery; \ + __wifi_cmd_info.ucS2DIndex = __ucS2DIndex; \ + if (__bucInitCmd) { \ + ASSERT(__prChipInfo->asicFillInitCmdTxd); \ + __prChipInfo->asicFillInitCmdTxd(__prAd, &(__wifi_cmd_info), \ + (&__u2InfoBufLen), __pucSeqNum, (void **)__ppCmdBuf); \ + } else { \ + ASSERT(__prChipInfo->asicFillCmdTxd); \ + __prChipInfo->asicFillCmdTxd(__prAd, &(__wifi_cmd_info), \ + __pucSeqNum, (void **)__ppCmdBuf); \ + } \ +} + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +void nicCmdEventQueryMcrRead(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf); + +void nicCmdEventQueryCfgRead(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf); + +#if CFG_SUPPORT_QA_TOOL +void nicCmdEventQueryRxStatistics(IN struct ADAPTER + *prAdapter, IN struct CMD_INFO *prCmdInfo, + IN uint8_t *pucEventBuf); + +uint32_t nicTsfRawData2IqFmt(struct EVENT_DUMP_MEM *prEventDumpMem, + struct ICAP_INFO_T *prIcap); +uint32_t nicExtTsfRawData2IqFmt( + struct EXT_EVENT_RBIST_DUMP_DATA_T *prEventDumpMem, + struct ICAP_INFO_T *prIcap); + +int32_t GetIQData(struct ADAPTER *prAdapter, + int32_t **prIQAry, uint32_t *prDataLen, uint32_t u4IQ, + uint32_t u4GetWf1); + +#if CFG_SUPPORT_TX_BF +void nicCmdEventPfmuDataRead(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf); + +void nicCmdEventPfmuTagRead(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf); +#endif /* CFG_SUPPORT_TX_BF */ +#if CFG_SUPPORT_MU_MIMO +void nicCmdEventGetQd(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf); +void nicCmdEventGetCalcLq(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf); +void nicCmdEventGetCalcInitMcs(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf); +#endif /* CFG_SUPPORT_MU_MIMO */ +#endif /* CFG_SUPPORT_QA_TOOL */ + +#if CFG_SUPPORT_CAL_RESULT_BACKUP_TO_HOST +void nicCmdEventQueryCalBackupV2(IN struct ADAPTER + *prAdapter, IN struct CMD_INFO *prCmdInfo, + IN uint8_t *pucEventBuf); +#endif +#if 0 +void nicEventQueryMemDump(IN struct ADAPTER *prAdapter, + IN uint8_t *pucEventBuf); +#endif + +void nicCmdEventQueryMemDump(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf); + +void nicCmdEventQuerySwCtrlRead(IN struct ADAPTER + *prAdapter, IN struct CMD_INFO *prCmdInfo, + IN uint8_t *pucEventBuf); + +void nicCmdEventQueryChipConfig(IN struct ADAPTER + *prAdapter, IN struct CMD_INFO *prCmdInfo, + IN uint8_t *pucEventBuf); + +void nicCmdEventQueryRfTestATInfo(IN struct ADAPTER + *prAdapter, IN struct CMD_INFO *prCmdInfo, + IN uint8_t *pucEventBuf); + +void nicCmdEventSetCommon(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf); + +void nicCmdEventSetIpAddress(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf); + +void nicCmdEventQueryLinkQuality(IN struct ADAPTER + *prAdapter, IN struct CMD_INFO *prCmdInfo, + IN uint8_t *pucEventBuf); + +void nicCmdEventQueryLinkSpeed(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf); + +void nicCmdEventQueryLinkSpeedEx(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf); + +void nicCmdEventQueryStatistics(IN struct ADAPTER + *prAdapter, IN struct CMD_INFO *prCmdInfo, + IN uint8_t *pucEventBuf); + +void nicCmdEventEnterRfTest(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf); + +void nicCmdEventLeaveRfTest(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf); + +void nicCmdEventQueryMcastAddr(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf); + +void nicCmdEventQueryEepromRead(IN struct ADAPTER + *prAdapter, IN struct CMD_INFO *prCmdInfo, + IN uint8_t *pucEventBuf); + +void nicCmdEventSetMediaStreamMode(IN struct ADAPTER + *prAdapter, IN struct CMD_INFO *prCmdInfo, + IN uint8_t *pucEventBuf); + +void nicCmdEventSetStopSchedScan(IN struct ADAPTER + *prAdapter, IN struct CMD_INFO *prCmdInfo, + IN uint8_t *pucEventBuf); + +/* for timeout check */ +void nicOidCmdTimeoutCommon(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo); + +void nicCmdTimeoutCommon(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo); + +void nicOidCmdEnterRFTestTimeout(IN struct ADAPTER + *prAdapter, IN struct CMD_INFO *prCmdInfo); + +#if CFG_SUPPORT_BUILD_DATE_CODE +void nicCmdEventBuildDateCode(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf); +#endif + +void nicCmdEventQueryStaStatistics(IN struct ADAPTER + *prAdapter, IN struct CMD_INFO *prCmdInfo, + IN uint8_t *pucEventBuf); + +void nicCmdEventQueryBugReport(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf); + +void nicCmdEventQueryLteSafeChn(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, + IN uint8_t *pucEventBuf); + +#if CFG_SUPPORT_BATCH_SCAN +void nicCmdEventBatchScanResult(IN struct ADAPTER + *prAdapter, IN struct CMD_INFO *prCmdInfo, + IN uint8_t *pucEventBuf); +#endif + +void nicEventRddPulseDump(IN struct ADAPTER *prAdapter, + IN uint8_t *pucEventBuf); + +#if (CFG_SUPPORT_TXPOWER_INFO == 1) +void nicCmdEventQueryTxPowerInfo(IN struct ADAPTER + *prAdapter, IN struct CMD_INFO *prCmdInfo, + IN uint8_t *pucEventBuf); +#endif + +void nicCmdEventQueryWlanInfo(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf); + +void nicCmdEventQueryMibInfo(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf); + +void nicCmdEventQueryNicCapabilityV2(IN struct ADAPTER + *prAdapter, IN uint8_t *pucEventBuf); + +uint32_t nicCmdEventQueryNicTxResource(IN struct ADAPTER + *prAdapter, IN uint8_t *pucEventBuf); +uint32_t nicCmdEventQueryNicEfuseAddr(IN struct ADAPTER + *prAdapter, IN uint8_t *pucEventBuf); +uint32_t nicCmdEventQueryNicCoexFeature(IN struct ADAPTER + *prAdapter, IN uint8_t *pucEventBuf); +#if CFG_TCP_IP_CHKSUM_OFFLOAD +uint32_t nicCmdEventQueryNicCsumOffload(IN struct ADAPTER + *prAdapter, IN uint8_t *pucEventBuf); +#endif +uint32_t nicCfgChipCapHwVersion(IN struct ADAPTER + *prAdapter, IN uint8_t *pucEventBuf); +uint32_t nicCfgChipCapSwVersion(IN struct ADAPTER + *prAdapter, IN uint8_t *pucEventBuf); +uint32_t nicCfgChipCapMacAddr(IN struct ADAPTER *prAdapter, + IN uint8_t *pucEventBuf); +uint32_t nicCfgChipCapPhyCap(IN struct ADAPTER *prAdapter, + IN uint8_t *pucEventBuf); +uint32_t nicCfgChipCapMacCap(IN struct ADAPTER *prAdapter, + IN uint8_t *pucEventBuf); +uint32_t nicCfgChipCapFrameBufCap(IN struct ADAPTER + *prAdapter, IN uint8_t *pucEventBuf); +uint32_t nicCfgChipCapBeamformCap(IN struct ADAPTER + *prAdapter, IN uint8_t *pucEventBuf); +uint32_t nicCfgChipCapLocationCap(IN struct ADAPTER + *prAdapter, IN uint8_t *pucEventBuf); +uint32_t nicCfgChipCapMuMimoCap(IN struct ADAPTER + *prAdapter, IN uint8_t *pucEventBuf); +uint32_t nicCfgChipAdieHwVersion(IN struct ADAPTER *prAdapter, + IN uint8_t *pucEventBuf); +#if CFG_SUPPORT_ANT_SWAP +uint32_t nicCfgChipCapAntSwpCap(IN struct ADAPTER *prAdapter, + IN uint8_t *pucEventBuf); +#endif + +#if (CFG_SUPPORT_P2PGO_ACS == 1) + uint32_t nicCfgChipP2PCap(IN struct ADAPTER *prAdapter, + IN uint8_t *pucEventBuf); + +#endif + +uint32_t nicCmdEventHostStatusEmiOffset(IN struct ADAPTER *prAdapter, + IN uint8_t *pucEventBuf); + +void nicExtEventICapIQData(IN struct ADAPTER *prAdapter, + IN uint8_t *pucEventBuf); +void nicExtEventQueryMemDump(IN struct ADAPTER *prAdapter, + IN uint8_t *pucEventBuf); +void nicEventLinkQuality(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent); +void nicEventLayer0ExtMagic(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent); +void nicEventMicErrorInfo(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent); +void nicEventScanDone(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent); +void nicEventSchedScanDone(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent); +void nicEventSleepyNotify(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent); +void nicEventBtOverWifi(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent); +void nicEventStatistics(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent); +void nicEventWlanInfo(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent); +void nicEventMibInfo(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent); +void nicEventBeaconTimeout(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent); +void nicEventUpdateNoaParams(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent); +void nicEventStaAgingTimeout(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent); +void nicEventApObssStatus(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent); +void nicEventRoamingStatus(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent); +void nicEventSendDeauth(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent); +void nicEventUpdateRddStatus(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent); +void nicEventUpdateBwcsStatus(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent); +void nicEventUpdateBcmDebug(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent); +void nicEventAddPkeyDone(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent); +void nicEventIcapDone(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent); +#if CFG_SUPPORT_CAL_RESULT_BACKUP_TO_HOST +void nicEventCalAllDone(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent); +#endif + +void nicEventDebugMsg(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent); +void nicEventTdls(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent); +void nicEventRssiMonitor(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent); +void nicEventDumpMem(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent); +void nicEventAssertDump(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent); +void nicEventHifCtrl(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent); +void nicEventRddSendPulse(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent); +void nicEventUpdateCoexPhyrate(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent); +uint32_t nicEventQueryTxResource_v1(IN struct ADAPTER + *prAdapter, IN uint8_t *pucEventBuf); +uint32_t nicEventQueryTxResourceEntry(IN struct ADAPTER + *prAdapter, IN uint8_t *pucEventBuf); +uint32_t nicEventQueryTxResource(IN struct ADAPTER + *prAdapter, IN uint8_t *pucEventBuf); +void nicCmdEventQueryCnmInfo(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf); +void nicEventCnmInfo(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent); +#if CFG_SUPPORT_REPLAY_DETECTION +void nicCmdEventSetAddKey(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf); +void nicOidCmdTimeoutSetAddKey(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo); +#endif + +#if CFG_SUPPORT_LOWLATENCY_MODE +void nicEventUpdateLowLatencyInfoStatus(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent); +#endif + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#endif /* _NIC_CMD_EVENT_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic_ext_cmd_event.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic_ext_cmd_event.h new file mode 100644 index 0000000000000000000000000000000000000000..e0b00c13c8a8e47c5c99ebea40140b7361ab1c47 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic_ext_cmd_event.h @@ -0,0 +1,215 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/*! \file "nic_ext_cmd_event.h" + * \brief This file contains the declairation file of the WLAN OID processing + * routines of Windows driver for MediaTek Inc. + * 802.11 Wireless LAN Adapters. + */ + +#ifndef _NIC_EXT_CMD_EVENT_H +#define _NIC_EXT_CMD_EVENT_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ +#if (CFG_SUPPORT_CONNAC2X == 1) + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "gl_typedef.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#define STAREC_COMMON_EXTRAINFO_V2 BIT(0) +#define STAREC_COMMON_EXTRAINFO_NEWSTAREC BIT(1) + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ +struct STAREC_COMMON_T { + /* Basic STA record (Group0) */ + uint16_t u2Tag; /* Tag = 0x00 */ + uint16_t u2Length; + uint32_t u4ConnectionType; + uint8_t ucConnectionState; + uint8_t ucIsQBSS; + uint16_t u2AID; + uint8_t aucPeerMacAddr[6]; + uint16_t u2ExtraInfo; +} __KAL_ATTRIB_PACKED__; + +struct CMD_STAREC_UPDATE_T { + uint8_t ucBssIndex; + uint8_t ucWlanIdx; + uint16_t u2TotalElementNum; + uint8_t ucAppendCmdTLV; + uint8_t ucMuarIdx; + uint8_t aucReserve[2]; + uint8_t aucBuffer[]; +} __KAL_ATTRIB_PACKED__; + +struct STAREC_HANDLE_T { + uint32_t StaRecTag; + uint32_t StaRecTagLen; + int32_t (*StaRecTagHandler)( + struct ADAPTER *pAd, uint8_t *pMsgBuf, void *args); +}; + +#if (CFG_SUPPORT_DMASHDL_SYSDVT) +struct EXT_CMD_CR4_DMASHDL_DVT_T { + uint8_t ucItemNo; + uint8_t ucSubItemNo; + uint8_t ucReserve[2]; +}; +#endif /* CFG_SUPPORT_DMASHDL_SYSDVT */ + +struct CMD_BSSINFO_UPDATE_T { + uint8_t ucBssIndex; + uint8_t ucReserve; + uint16_t u2TotalElementNum; + uint32_t u4Reserve; + uint8_t aucBuffer[]; +} __KAL_ATTRIB_PACKED__; + + +/* TAG ID 0x00: */ +struct BSSINFO_CONNECT_OWN_DEV_T { + /* BSS connect to own dev (Tag0) */ + uint16_t u2Tag; /* Tag = 0x00 */ + uint16_t u2Length; + uint8_t ucHwBSSIndex; + uint8_t ucOwnMacIdx; + uint8_t aucReserve[2]; + uint32_t ucConnectionType; + uint32_t u4Reserved; +} __KAL_ATTRIB_PACKED__; + +/* TAG ID 0x01: */ +struct BSSINFO_BASIC_T { + /* Basic BSS information (Tag1) */ + uint16_t u2Tag; /* Tag = 0x01 */ + uint16_t u2Length; + uint32_t u4NetworkType; + uint8_t ucActive; + uint8_t ucReserve0; + uint16_t u2BcnInterval; + uint8_t aucBSSID[6]; + uint8_t ucWmmIdx; + uint8_t ucDtimPeriod; +/* indicate which wlan-idx used for MC/BC transmission */ + uint8_t ucBcMcWlanidx; + uint8_t ucCipherSuit; + uint8_t acuReserve[6]; +} __KAL_ATTRIB_PACKED__; + + +struct CMD_DEVINFO_UPDATE_T { + uint8_t ucOwnMacIdx; + uint8_t ucReserve; + uint16_t u2TotalElementNum; + uint32_t aucReserve; + uint8_t aucBuffer[]; +} __KAL_ATTRIB_PACKED__; + +struct CMD_DEVINFO_ACTIVE_T { + uint16_t u2Tag; /* Tag = 0x00 */ + uint16_t u2Length; + uint8_t ucActive; + uint8_t ucDbdcIdx; + uint8_t aucOwnMacAddr[6]; + uint8_t aucReserve[4]; +} __KAL_ATTRIB_PACKED__; + + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +uint32_t CmdExtStaRecUpdate2WA( + struct ADAPTER *pAd, + struct STA_RECORD *pStaRecCfg); + +#if (CFG_SUPPORT_DMASHDL_SYSDVT) +uint32_t CmdExtDmaShdlDvt2WA( + struct ADAPTER *pAd, + uint8_t ucItemNo, + uint8_t ucSubItemNo); +#endif /* CFG_SUPPORT_DMASHDL_SYSDVT */ + +uint32_t CmdExtBssInfoUpdate2WA( + struct ADAPTER *pAd, + uint8_t ucBssIndex); + +uint32_t CmdExtDevInfoUpdate2WA( + struct ADAPTER *pAd, + uint8_t ucBssIndex); + +#endif /* CFG_SUPPORT_CONNAC2X == 1 */ + +#endif /* _NIC_EXT_CMD_EVENT_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic_init_cmd_event.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic_init_cmd_event.h new file mode 100644 index 0000000000000000000000000000000000000000..ff4c704f3a1a4f4678474b6e8b7db7d36a899a1a --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/nic_init_cmd_event.h @@ -0,0 +1,326 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/ + * MT6620_WIFI_DRIVER_V2_3/include/nic_init_cmd_event.h#1 + */ + +/*! \file "nic_init_cmd_event.h" + * \brief This file contains the declairation file of the WLAN + * initialization routines for MediaTek Inc. 802.11 Wireless LAN Adapters. + */ + +#ifndef _NIC_INIT_CMD_EVENT_H +#define _NIC_INIT_CMD_EVENT_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +#include "gl_typedef.h" +#include "wsys_cmd_handler_fw.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#define INIT_CMD_STATUS_SUCCESS 0 +#define INIT_CMD_STATUS_REJECTED_INVALID_PARAMS 1 +#define INIT_CMD_STATUS_REJECTED_CRC_ERROR 2 +#define INIT_CMD_STATUS_REJECTED_DECRYPT_FAIL 3 +#define INIT_CMD_STATUS_UNKNOWN 4 + +#define INIT_PKT_FT_CMD 0x2 +#define INIT_PKT_FT_PDA_FWDL 0x3 + +#define INIT_CMD_PQ_ID (0x8000) +#define INIT_CMD_PACKET_TYPE_ID (0xA0) + +#define INIT_CMD_PDA_PQ_ID (0xF800) +#define INIT_CMD_PDA_PACKET_TYPE_ID (0xA0) + +#if (CFG_UMAC_GENERATION >= 0x20) +#define TXD_Q_IDX_MCU_RQ0 0 +#define TXD_Q_IDX_MCU_RQ1 1 +#define TXD_Q_IDX_MCU_RQ2 2 +#define TXD_Q_IDX_MCU_RQ3 3 + +#define TXD_Q_IDX_PDA_FW_DL 0x1E + +/* DW0 Bit31 */ +#define TXD_P_IDX_LMAC 0 +#define TXD_P_IDX_MCU 1 + +/* DW1 Bit 14:13 */ +#define TXD_HF_NON_80211_FRAME 0x0 +#define TXD_HF_CMD 0x1 +#define TXD_HF_80211_NORMAL 0x2 +#define TXD_HF_80211_ENHANCEMENT 0x3 + +/* DW1 Bit 15 */ +#define TXD_FT_OFFSET 15 +#define TXD_FT_SHORT_FORMAT 0x0 +#define TXD_FT_LONG_FORMAT 0x1 + +/* DW1 Bit 16 */ +#define TXD_TXDLEN_OFFSET 16 +#define TXD_TXDLEN_1PAGE 0x0 +#define TXD_TXDLEN_2PAGE 0x1 + +/* DW1 Bit 25:24 */ +#define TXD_PKT_FT_CUT_THROUGH 0x0 +#define TXD_PKT_FT_STORE_FORWARD 0X1 +#define TXD_PKT_FT_CMD 0X2 +#define TXD_PKT_FT_PDA_FW 0X3 +#endif + +enum ENUM_INIT_CMD_ID { + INIT_CMD_ID_DOWNLOAD_CONFIG = 1, + INIT_CMD_ID_WIFI_START, + INIT_CMD_ID_ACCESS_REG, + INIT_CMD_ID_QUERY_PENDING_ERROR, + INIT_CMD_ID_PATCH_START, + INIT_CMD_ID_PATCH_WRITE, + INIT_CMD_ID_PATCH_FINISH, + INIT_CMD_ID_PHY_ACTION, + + INIT_CMD_ID_PATCH_SEMAPHORE_CONTROL = 0x10, + INIT_CMD_ID_HIF_LOOPBACK = 0x20, + +#if (CFG_DOWNLOAD_DYN_MEMORY_MAP == 1) + INIT_CMD_ID_DYN_MEM_MAP_PATCH_FINISH = 0x40, + INIT_CMD_ID_DYN_MEM_MAP_FW_FINISH = 0x41, +#endif + +#if CFG_SUPPORT_COMPRESSION_FW_OPTION + INIT_CMD_ID_DECOMPRESSED_WIFI_START = 0xFF, +#endif + INIT_CMD_ID_NUM +}; + +enum ENUM_INIT_EVENT_ID { + INIT_EVENT_ID_CMD_RESULT = 1, + INIT_EVENT_ID_ACCESS_REG, + INIT_EVENT_ID_PENDING_ERROR, + INIT_EVENT_ID_PATCH_SEMA_CTRL, + INIT_EVENT_ID_PHY_ACTION +}; + +enum ENUM_INIT_PATCH_STATUS { + PATCH_STATUS_NO_SEMA_NEED_PATCH = 0, /* no SEMA, need patch */ + PATCH_STATUS_NO_NEED_TO_PATCH, /* patch is DL & ready */ + PATCH_STATUS_GET_SEMA_NEED_PATCH, /* get SEMA, need patch */ + PATCH_STATUS_RELEASE_SEMA /* release SEMA */ +}; + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +struct WIFI_CMD_INFO { + uint16_t u2InfoBufLen; + uint8_t *pucInfoBuffer; + uint8_t ucCID; + uint8_t ucExtCID; + uint8_t ucPktTypeID; + uint8_t ucSetQuery; + uint8_t ucS2DIndex; +}; + +/* commands */ +struct INIT_CMD_DOWNLOAD_CONFIG { + uint32_t u4Address; + uint32_t u4Length; + uint32_t u4DataMode; +}; + +#define START_OVERRIDE_START_ADDRESS BIT(0) +#define START_DELAY_CALIBRATION BIT(1) +#define START_WORKING_PDA_OPTION BIT(2) +#define START_CRC_CHECK BIT(3) +#define CHANGE_DECOMPRESSION_TMP_ADDRESS BIT(4) + +#if CFG_SUPPORT_COMPRESSION_FW_OPTION +#define WIFI_FW_DECOMPRESSION_FAILED 0xFF +struct INIT_CMD_WIFI_DECOMPRESSION_START { + uint32_t u4Override; + uint32_t u4Address; + uint32_t u4Region1length; + uint32_t u4Region2length; + uint32_t u4Region1Address; + uint32_t u4Region2Address; + uint32_t u4BlockSize; + uint32_t u4Region1CRC; + uint32_t u4Region2CRC; + uint32_t u4DecompressTmpAddress; +}; +#endif + +struct INIT_CMD_WIFI_START { + uint32_t u4Override; + uint32_t u4Address; +}; + +#define PATCH_GET_SEMA_CONTROL 1 +#define PATCH_RELEASE_SEMA_CONTROL 0 +struct INIT_CMD_PATCH_SEMA_CONTROL { + uint8_t ucGetSemaphore; + uint8_t aucReserved[3]; +}; + +struct INIT_CMD_PATCH_FINISH { + uint8_t ucCheckCrc; + uint8_t aucReserved[3]; +}; + +struct INIT_CMD_ACCESS_REG { + uint8_t ucSetQuery; + uint8_t aucReserved[3]; + uint32_t u4Address; + uint32_t u4Data; +}; + +#if (CFG_SUPPORT_PRE_ON_PHY_ACTION == 1) +#define HAL_PHY_ACTION_MAGIC_NUM 0x556789AA +#define HAL_PHY_ACTION_VERSION 0x01 + +#define HAL_PHY_ACTION_CAL_FORCE_CAL_REQ 0x01 +#define HAL_PHY_ACTION_CAL_FORCE_CAL_RSP 0x81 +#define HAL_PHY_ACTION_CAL_USE_BACKUP_REQ 0x02 +#define HAL_PHY_ACTION_CAL_USE_BACKUP_RSP 0x82 +#define HAL_PHY_ACTION_ERROR 0xff + +enum ENUM_HAL_PHY_ACTION_STATUS { + HAL_PHY_ACTION_STATUS_SUCCESS = 0x00, + HAL_PHY_ACTION_STATUS_FAIL, + HAL_PHY_ACTION_STATUS_RECAL, + HAL_PHY_ACTION_STATUS_EPA_ELNA, +}; + +struct INIT_CMD_PHY_ACTION_CAL { + uint8_t ucCmd; + uint8_t aucReserved[3]; +}; + +struct INIT_EVENT_PHY_ACTION_RSP { + uint8_t ucEvent; + uint8_t ucStatus; + uint8_t aucReserved[2]; + uint32_t u4EmiAddress; + uint32_t u4EmiLength; + uint32_t u4Temperatue; +}; + +enum ENUM_HAL_PHY_ACTION_TAG { + HAL_PHY_ACTION_TAG_FEM, + HAL_PHY_ACTION_TAG_CAL, + + HAL_PHY_ACTION_TAG_NUM, +}; + +struct HAL_PHY_ACTION_TLV { + uint16_t u2Tag; + uint16_t u2BufLength; + uint8_t aucBuffer[0]; +}; + +struct HAL_PHY_ACTION_TLV_HEADER { + uint32_t u4MagicNum; + uint8_t ucTagNums; + uint8_t ucVersion; + uint16_t u2BufLength; + uint8_t aucBuffer[0]; +}; +#endif /* (CFG_SUPPORT_PRE_ON_PHY_ACTION == 1) */ + +/* Events */ +struct INIT_HIF_RX_HEADER { + struct INIT_WIFI_EVENT rInitWifiEvent; +}; + +struct INIT_EVENT_ACCESS_REG { + uint32_t u4Address; + uint32_t u4Data; +}; + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#endif /* _NIC_INIT_CMD_EVENT_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/p2p_precomp.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/p2p_precomp.h new file mode 100644 index 0000000000000000000000000000000000000000..b4cfd5c45c28235c35c2513ed5bcdd8b35d79e70 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/p2p_precomp.h @@ -0,0 +1,247 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/p2p_precomp.h#1 + */ + +/*! \file p2p_precomp.h + * \brief Collection of most compiler flags + * for p2p driver are described here. + * + * In this file we collect all compiler flags and detail + * the p2p driver behavior if enable/disable such switch + * or adjust numeric parameters. + */ + +#ifndef _P2P_PRECOMP_H +#define _P2P_PRECOMP_H + +/****************************************************************************** + * C O M P I L E R F L A G S + ****************************************************************************** + */ + +/****************************************************************************** + * E X T E R N A L R E F E R E N C E S + ****************************************************************************** + */ +#include "gl_os.h" /* Include "config.h" */ + +#include "gl_p2p_os.h" + +#include "debug.h" + +#include "link.h" +#include "queue.h" + +/*----------------------------------------------------------------------------- + * .\include\mgmt + *----------------------------------------------------------------------------- + */ +#include "wlan_typedef.h" + +#include "mac.h" + +/* Dependency: mac.h (MAC_ADDR_LEN) */ +#include "wlan_def.h" + +#include "roaming_fsm.h" + +/*----------------------------------------------------------------------------- + * .\include\nic + *----------------------------------------------------------------------------- + */ +/* Dependency: wlan_def.h (ENUM_NETWORK_TYPE_T) */ +#include "cmd_buf.h" + +/* Dependency: mac.h (MAC_ADDR_LEN) */ +#include "nic_cmd_event.h" + +/* Dependency: nic_cmd_event.h (P_EVENT_CONNECTION_STATUS) */ +#include "nic.h" + +#include "nic_init_cmd_event.h" + +#include "hif_rx.h" +#include "hif_tx.h" + +#include "nic_tx.h" + +/* Dependency: hif_rx.h (P_HIF_RX_HEADER_T) */ +#include "nic_rx.h" + +#include "que_mgt.h" + +#include "nic_rate.h" + +#if CFG_ENABLE_WIFI_DIRECT +#include "p2p_typedef.h" +#include "p2p_cmd_buf.h" +#include "p2p_nic_cmd_event.h" +#include "p2p_mac.h" +#include "p2p_nic.h" +#endif + +/*----------------------------------------------------------------------------- + * .\include\mgmt + *----------------------------------------------------------------------------- + */ + +#include "hem_mbox.h" + +#include "scan.h" +#include "bss.h" + +#include "wlan_lib.h" +#include "wlan_oid.h" +#include "wlan_bow.h" + +#include "wlan_p2p.h" + +#include "hal.h" + +#include "mt66xx_reg.h" + +#include "rlm.h" +#include "rlm_domain.h" +#include "rlm_protection.h" +#include "rlm_obss.h" +#include "rate.h" +#include "wnm.h" + +#include "aa_fsm.h" + +#include "cnm_timer.h" +#include "que_mgt.h" +#include "wmm.h" +#if CFG_ENABLE_BT_OVER_WIFI +#include "bow.h" +#include "bow_fsm.h" +#endif + +#include "pwr_mgt.h" + +#include "cnm.h" +/* Dependency: */ +/* aa_fsm.h (ENUM_AA_STATE_T), p2p_fsm.h (WPS_ATTRI_MAX_LEN_DEVICE_NAME) */ +#include "cnm_mem.h" +#include "cnm_scan.h" + +#include "p2p_rlm_obss.h" +#include "p2p_bss.h" +#include "p2p.h" +/* Dependency: cnm_timer.h (TIMER_T) */ +#include "p2p_fsm.h" +#include "p2p_scan.h" +#include "p2p_func.h" +#include "p2p_rlm.h" +#include "p2p_assoc.h" +#include "p2p_ie.h" + +#include "privacy.h" + +#include "mib.h" + +#include "auth.h" +#include "assoc.h" + +#include "ais_fsm.h" + +#include "adapter.h" + +#include "rftest.h" + +#include "rsn.h" + +#if CFG_SUPPORT_WAPI +#include "wapi.h" +#endif + +/*----------------------------------------------------------------------------- + * NVRAM structure + *----------------------------------------------------------------------------- + */ +#include "CFG_Wifi_File.h" + +#include "gl_p2p_kal.h" + +/****************************************************************************** + * C O N S T A N T S + ****************************************************************************** + */ + +/****************************************************************************** + * M A C R O S + ****************************************************************************** + */ + +/****************************************************************************** + * D A T A T Y P E S + ****************************************************************************** + */ + +/****************************************************************************** + * P U B L I C D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * P R I V A T E D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N D E C L A R A T I O N S + ****************************************************************************** + */ + +#endif /*_P2P_PRECOMP_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/p2p_typedef.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/p2p_typedef.h new file mode 100644 index 0000000000000000000000000000000000000000..f8a5cf91869c8a2ab74394fea92bab05df605e1e --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/p2p_typedef.h @@ -0,0 +1,246 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/ + * include/p2p_typedef.h#1 + */ + +/*! \file p2p_typedef.h + * \brief Declaration of data type and return values of + * internal protocol stack. + * + * In this file we declare the data type and return values + * which will be exported to all MGMT Protocol Stack. + */ + +#ifndef _P2P_TYPEDEF_H +#define _P2P_TYPEDEF_H + +#if CFG_ENABLE_WIFI_DIRECT + +/****************************************************************************** + * C O M P I L E R F L A G S + ****************************************************************************** + */ + +/****************************************************************************** + * E X T E R N A L R E F E R E N C E S + ****************************************************************************** + */ + +/****************************************************************************** + * C O N S T A N T S + ****************************************************************************** + */ + +/****************************************************************************** + * M A C R O S + ****************************************************************************** + */ + +/****************************************************************************** + * D A T A T Y P E S + ****************************************************************************** + */ + +/* + * type definition of pointer to p2p structure + */ +/* typedef struct GL_P2P_INFO GL_P2P_INFO_T, *P_GL_P2P_INFO_T; */ +struct P2P_INFO; /* declare P2P_INFO_T */ + +struct P2P_FSM_INFO; /* declare P2P_FSM_INFO_T */ + +struct P2P_DEV_FSM_INFO; /* declare P2P_DEV_FSM_INFO_T */ + +struct P2P_ROLE_FSM_INFO; /* declare P2P_ROLE_FSM_INFO_T */ + +struct P2P_CONNECTION_SETTINGS; /* declare P2P_CONNECTION_SETTINGS_T */ + +/* Type definition for function pointer to p2p function*/ +typedef u_int8_t(*P2P_LAUNCH) (struct GLUE_INFO *prGlueInfo); + +typedef u_int8_t(*P2P_REMOVE) (struct GLUE_INFO *prGlueInfo, + u_int8_t fgIsWlanLaunched); + +typedef u_int8_t(*KAL_P2P_GET_CIPHER) (IN struct GLUE_INFO *prGlueInfo); + +typedef u_int8_t(*KAL_P2P_GET_TKIP_CIPHER) (IN struct GLUE_INFO *prGlueInfo); + +typedef u_int8_t(*KAL_P2P_GET_CCMP_CIPHER) (IN struct GLUE_INFO *prGlueInfo); + +typedef u_int8_t(*KAL_P2P_GET_WSC_MODE) (IN struct GLUE_INFO *prGlueInfo); + +typedef struct net_device *(*KAL_P2P_GET_DEV_HDLR) ( + struct GLUE_INFO *prGlueInfo); + +typedef void(*KAL_P2P_SET_MULTICAST_WORK_ITEM) (struct GLUE_INFO *prGlueInfo); + +typedef void(*P2P_NET_REGISTER) (struct GLUE_INFO *prGlueInfo); + +typedef void(*P2P_NET_UNREGISTER) (struct GLUE_INFO *prGlueInfo); + +typedef void(*KAL_P2P_UPDATE_ASSOC_INFO) (IN struct GLUE_INFO *prGlueInfo, + IN uint8_t *pucFrameBody, + IN uint32_t u4FrameBodyLen, + IN u_int8_t fgReassocRequest); + +typedef u_int8_t(*P2P_VALIDATE_AUTH) (IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, + IN struct STA_RECORD **pprStaRec, + OUT uint16_t *pu2StatusCode); + +typedef u_int8_t(*P2P_VALIDATE_ASSOC_REQ) (IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, + OUT uint16_t *pu4ControlFlags); + +typedef void(*P2P_RUN_EVENT_AAA_TX_FAIL) (IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec); + +typedef u_int8_t(*P2P_PARSE_CHECK_FOR_P2P_INFO_ELEM) ( + IN struct ADAPTER *prAdapter, + IN uint8_t *pucBuf, + OUT uint8_t *pucOuiType); + +typedef uint32_t(*P2P_RUN_EVENT_AAA_COMPLETE) (IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec); + +typedef void(*P2P_PROCESS_EVENT_UPDATE_NOA_PARAM) ( + IN struct ADAPTER *prAdapter, + uint8_t ucNetTypeIndex, + struct EVENT_UPDATE_NOA_PARAMS *prEventUpdateNoaParam); + +typedef void(*SCAN_P2P_PROCESS_BEACON_AND_PROBE_RESP) ( + IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, + IN uint32_t *prStatus, + IN struct BSS_DESC *prBssDesc, + IN struct WLAN_BEACON_FRAME *prWlanBeaconFrame); + +typedef void(*P2P_RX_PUBLIC_ACTION_FRAME) (struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb); + +typedef void(*RLM_RSP_GENERATE_OBSS_SCAN_IE) (struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo); + +typedef void(*RLM_UPDATE_BW_BY_CH_LIST_FOR_AP) (struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo); + +typedef void(*RLM_PROCESS_PUBLIC_ACTION) (struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb); + +typedef void(*RLM_PROCESS_HT_ACTION) (struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb); + +typedef void(*RLM_UPDATE_PARAMS_FOR_AP) (struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, u_int8_t fgUpdateBeacon); + +typedef void(*RLM_HANDLE_OBSS_STATUS_EVENT_PKT) (struct ADAPTER *prAdapter, + struct EVENT_AP_OBSS_STATUS *prObssStatus); + +typedef u_int8_t(*P2P_FUNC_VALIDATE_PROBE_REQ) (IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, + OUT uint32_t *pu4ControlFlags); + +typedef void(*RLM_BSS_INIT_FOR_AP) (struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo); + +typedef uint32_t(*P2P_GET_PROB_RSP_IE_TABLE_SIZE) (void); + +typedef uint8_t *(*P2P_BUILD_REASSOC_REQ_FRAME_COMMON_IES) ( + IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, IN uint8_t *pucBuffer); + +typedef void(*P2P_FUNC_DISCONNECT) (IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, + IN u_int8_t fgSendDeauth, IN uint16_t u2ReasonCode); + +typedef void(*P2P_FSM_RUN_EVENT_RX_DEAUTH) (IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, + IN struct SW_RFB *prSwRfb); + +typedef void(*P2P_FSM_RUN_EVENT_RX_DISASSOC) (IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, + IN struct SW_RFB *prSwRfb); + +typedef u_int8_t(*P2P_FUN_IS_AP_MODE) (IN struct P2P_FSM_INFO *prP2pFsmInfo); + +typedef void(*P2P_FSM_RUN_EVENT_BEACON_TIMEOUT) (IN struct ADAPTER *prAdapter); + +typedef void(*P2P_FUNC_STORE_ASSOC_RSP_IE_BUFFER) ( + IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb); + +typedef void(*P2P_GENERATE_P2P_IE) (IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo); + +typedef uint32_t(*P2P_CALCULATE_P2P_IE_LEN) (IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, IN struct STA_RECORD *prStaRec); + +/****************************************************************************** + * P U B L I C D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * P R I V A T E D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N D E C L A R A T I O N S + ****************************************************************************** + */ + +#endif /*CFG_ENABLE_WIFI_DIRECT */ + +#endif /* _P2P_TYPEDEF_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/precomp.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/precomp.h new file mode 100644 index 0000000000000000000000000000000000000000..b0b6cfa87e020b900686dbb0c198ecef5b3e4387 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/precomp.h @@ -0,0 +1,342 @@ +/******************************************************************************* + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ +/* + * Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/precomp.h#2 + */ + +/*! \file precomp.h + * \brief Collection of most compiler flags are described here. + * + * In this file we collect all compiler flags and detail the driver behavior + * if enable/disable such switch or adjust numeric parameters. + */ + +#ifndef _PRECOMP_H +#define _PRECOMP_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +#ifdef __GNUC__ +#if (DBG == 0) +#pragma GCC diagnostic ignored "-Wformat" +#endif +#endif + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "hif_cmm.h" +#include "gl_os.h" /* Include "config.h" */ +#include "gl_cfg80211.h" + +#if CFG_ENABLE_WIFI_DIRECT +#include "gl_p2p_os.h" +#endif + +#include "debug.h" + +#include "link.h" +#include "queue.h" + +/*------------------------------------------------------------------------------ + * .\include\mgmt + *------------------------------------------------------------------------------ + */ +#include "wlan_typedef.h" + +#include "mac.h" + +/* Dependency: mac.h (MAC_ADDR_LEN) */ +#include "wlan_def.h" + +#if (CFG_SUPPORT_802_11AX == 1) +#include "he_ie.h" +#endif + +#if CFG_SUPPORT_SWCR +#include "swcr.h" +#endif + +#include "rlm_obss.h" +#include "cnm_timer.h" + +/*------------------------------------------------------------------------------ + * .\include\nic + *------------------------------------------------------------------------------ + */ +/* Dependency: wlan_def.h (ENUM_NETWORK_TYPE_T) */ +#include "cmd_buf.h" + +/* Dependency: mac.h (MAC_ADDR_LEN) */ +#include "nic_cmd_event.h" +#include "nic_ext_cmd_event.h" + +/* Dependency: nic_cmd_event.h (P_EVENT_CONNECTION_STATUS) */ +#include "nic.h" + +#include "nic_init_cmd_event.h" + +#include "hif_rx.h" +#include "hif_tx.h" + +#include "nic_connac2x_tx.h" +#include "nic_tx.h" +#include "nic_txd_v1.h" +#include "nic_txd_v2.h" +#include "nic_rxd_v1.h" +#include "nic_rxd_v2.h" + +#include "nic_connac2x_rx.h" +/* Dependency: hif_rx.h (P_HIF_RX_HEADER_T) */ +#include "nic_rx.h" + +#include "nic_umac.h" + +#include "bss.h" + +#include "nic_rate.h" + +#if CFG_ENABLE_WIFI_DIRECT +#include "p2p_typedef.h" +#include "p2p_cmd_buf.h" +#include "p2p_nic_cmd_event.h" +#include "p2p_mac.h" +#include "p2p_nic.h" +#endif + +/*------------------------------------------------------------------------------ + * .\include\mgmt + *------------------------------------------------------------------------------ + */ +#if (CFG_SUPPORT_TWT == 1) +#include "twt.h" +#endif /* CFG_SUPPORT_802_11AX */ + +#include "hem_mbox.h" + +#include "scan.h" + +#include "wlan_lib.h" +#include "wlan_oid.h" +#include "wlan_bow.h" + +#include "fw_dl.h" + +#if CFG_ENABLE_WIFI_DIRECT +#include "wlan_p2p.h" +#endif + +#include "hal.h" + +#include "mt66xx_reg.h" + +#include "connac_reg.h" +#include "connac_dmashdl.h" +#include "cmm_asic_connac.h" +#include "cmm_asic_connac2x.h" + +#if (CFG_SUPPORT_802_11AX == 1) +#include "he_rlm.h" +#include "wlan_he.h" +#endif /* CFG_SUPPORT_802_11AX == 1 */ + +#if (CFG_SUPPORT_TWT == 1) +#include "twt_req_fsm.h" +#include "twt_planner.h" +#endif + +#include "rlm.h" +#include "rlm_domain.h" +#include "rlm_protection.h" +#include "rlm_obss.h" +#include "rate.h" +#include "wnm.h" +#include "rrm.h" + +#include "qosmap.h" + +#include "aa_fsm.h" + +#include "que_mgt.h" + +#include "wmm.h" +#if CFG_ENABLE_BT_OVER_WIFI +#include "bow.h" +#include "bow_fsm.h" +#endif + +#include "pwr_mgt.h" + +#if (CFG_SUPPORT_STATISTICS == 1) +#include "stats.h" +#endif /* CFG_SUPPORT_STATISTICS */ + +#include "cnm.h" +/* Dependency: aa_fsm.h (ENUM_AA_STATE_T), p2p_fsm.h + * (WPS_ATTRI_MAX_LEN_DEVICE_NAME) + */ +#include "cnm_mem.h" +#include "cnm_scan.h" + +#if CFG_ENABLE_WIFI_DIRECT +#include "p2p_rlm_obss.h" +#include "p2p_bss.h" +#include "p2p.h" + +#include "p2p_rlm.h" +#include "p2p_assoc.h" +#include "p2p_ie.h" +#include "p2p_role.h" + +#include "p2p_func.h" +#include "p2p_scan.h" +#include "p2p_dev.h" +#include "p2p_fsm.h" +#endif + +#include "privacy.h" + +#include "mib.h" + +#include "auth.h" +#include "assoc.h" + +#if CFG_SUPPORT_ROAMING +#include "roaming_fsm.h" +#endif /* CFG_SUPPORT_ROAMING */ + +#include "ais_fsm.h" + +#include "adapter.h" + +#include "que_mgt.h" +#include "rftest.h" + +#include "rsn.h" + +#if CFG_SUPPORT_WAPI +#include "wapi.h" +#endif + +/* Support AP Selection */ +#include "ap_selection.h" + +/*------------------------------------------------------------------------------ + * NVRAM structure + *------------------------------------------------------------------------------ + */ +#include "CFG_Wifi_File.h" + +#if CFG_ENABLE_WIFI_DIRECT +#include "gl_p2p_kal.h" +#endif + +#if CFG_SUPPORT_TDLS +#include "tdls.h" +#endif + +#if CFG_SUPPORT_QA_TOOL +#include "gl_qa_agent.h" +#include "gl_ate_agent.h" +#endif + +#if CFG_SUPPORT_WIFI_SYSDVT +#include "dvt_common.h" +#if (CFG_SUPPORT_DMASHDL_SYSDVT) +#include "dvt_dmashdl.h" +#endif +#endif + +#ifdef UT_TEST_MODE +#include "ut_lib.h" +#endif + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#endif /* _PRECOMP_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/pwr_mgt.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/pwr_mgt.h new file mode 100644 index 0000000000000000000000000000000000000000..d7a93239e6e0b9ad0a700746e8b00bbab0a44013 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/pwr_mgt.h @@ -0,0 +1,156 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/ + * MT6620_WIFI_DRIVER_V2_3/include/pwr_mgt.h#1 + */ + +/*! \file "pwr_mgt.h" + * \brief In this file we define the STATE and EVENT for Power + * Management FSM. + * + * The SCAN FSM is responsible for performing SCAN behavior when the Arbiter + * enter ARB_STATE_SCAN. The STATE and EVENT for SCAN FSM are defined here + * with detail description. + */ + +#ifndef _PWR_MGT_H +#define _PWR_MGT_H +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#define PM_UAPSD_AC0 (BIT(0)) +#define PM_UAPSD_AC1 (BIT(1)) +#define PM_UAPSD_AC2 (BIT(2)) +#define PM_UAPSD_AC3 (BIT(3)) + +#define PM_UAPSD_ALL \ + (PM_UAPSD_AC0 | PM_UAPSD_AC1 | PM_UAPSD_AC2 | PM_UAPSD_AC3) +#define PM_UAPSD_NONE 0 + +#define LP_OWN_BACK_TOTAL_DELAY_MS 2048 /* exponential of 2 */ +#define LP_OWN_BACK_LOOP_DELAY_MS 1 /* exponential of 2 */ +#define LP_OWN_REQ_CLR_INTERVAL_MS 200 +#define LP_OWN_BACK_FAILED_RETRY_CNT 5 +#define LP_OWN_BACK_FAILED_LOG_SKIP_MS 2000 +#define LP_OWN_BACK_FAILED_RESET_CNT 5 +#define LP_OWN_BACK_FAILED_DBGCR_POLL_ROUND 5 +#define LP_DBGCR_POLL_ROUND 1 +#define LP_OWN_BACK_LOOP_DELAY_MIN_US 900 +#define LP_OWN_BACK_LOOP_DELAY_MAX_US 1000 + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +struct PM_PROFILE_SETUP_INFO { + /* Profile setup */ + /* 0: AC_BE, 1: AC_BK, 2: AC_VI, 3: AC_VO */ + uint8_t ucBmpDeliveryAC; + /* 0: AC_BE, 1: AC_BK, 2: AC_VI, 3: AC_VO */ + uint8_t ucBmpTriggerAC; + + uint8_t ucUapsdSp; /* Number of triggered packets in UAPSD */ + +}; + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ +#if !CFG_ENABLE_FULL_PM +#define ACQUIRE_POWER_CONTROL_FROM_PM(_prAdapter) +#define RECLAIM_POWER_CONTROL_TO_PM(_prAdapter, _fgEnableGINT_in_IST) +#else +#define ACQUIRE_POWER_CONTROL_FROM_PM(_prAdapter) \ + { \ + nicpmSetDriverOwn(_prAdapter); \ + } + +#define RECLAIM_POWER_CONTROL_TO_PM(_prAdapter, _fgEnableGINT_in_IST) \ + { \ + nicpmSetFWOwn(_prAdapter, _fgEnableGINT_in_IST); \ + } +#endif + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#endif /* _PWR_MGT_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/queue.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/queue.h new file mode 100644 index 0000000000000000000000000000000000000000..facc628e459d6b5c97e432b20c2dbf66fd547bac --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/queue.h @@ -0,0 +1,241 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/ + * MT6620_WIFI_DRIVER_V2_3/include/queue.h#1 + */ + +/*! \file queue.h + * \brief Definition for singly queue operations. + * + * In this file we define the singly queue data structure and its + * queue operation MACROs. + */ + +#ifndef _QUEUE_H +#define _QUEUE_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "gl_typedef.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +/* Singly Queue Structures - Entry Part */ +struct QUE_ENTRY { + struct QUE_ENTRY *prNext; + struct QUE_ENTRY + *prPrev; /* For Rx buffer reordering used only */ +}; + +/* Singly Queue Structures - Queue Part */ +struct QUE { + struct QUE_ENTRY *prHead; + struct QUE_ENTRY *prTail; + uint32_t u4NumElem; +}; + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ +#define MAXNUM_TDLS_PEER 4 + +#define QUEUE_INITIALIZE(prQueue) \ + { \ + (prQueue)->prHead = (struct QUE_ENTRY *)NULL; \ + (prQueue)->prTail = (struct QUE_ENTRY *)NULL; \ + (prQueue)->u4NumElem = 0; \ + } + +#define QUEUE_IS_EMPTY(prQueue) \ + (((struct QUE *)(prQueue))->prHead == (struct QUE_ENTRY *)NULL) + +#define QUEUE_IS_NOT_EMPTY(prQueue) ((prQueue)->u4NumElem > 0) + +#define QUEUE_GET_HEAD(prQueue) ((prQueue)->prHead) + +#define QUEUE_GET_TAIL(prQueue) ((prQueue)->prTail) + +#define QUEUE_GET_NEXT_ENTRY(prQueueEntry) ((prQueueEntry)->prNext) + +#define QUEUE_INSERT_HEAD(prQueue, prQueueEntry) \ + { \ + ASSERT(prQueue); \ + ASSERT(prQueueEntry); \ + (prQueueEntry)->prNext = (prQueue)->prHead; \ + (prQueue)->prHead = (prQueueEntry); \ + if ((prQueue)->prTail == (struct QUE_ENTRY *)NULL) { \ + (prQueue)->prTail = (prQueueEntry); \ + } \ + ((prQueue)->u4NumElem)++; \ + } + +#define QUEUE_INSERT_TAIL(prQueue, prQueueEntry) \ + { \ + ASSERT(prQueue); \ + ASSERT(prQueueEntry); \ + (prQueueEntry)->prNext = (struct QUE_ENTRY *)NULL; \ + if ((prQueue)->prTail) { \ + ((prQueue)->prTail)->prNext = (prQueueEntry); \ + } else { \ + (prQueue)->prHead = (prQueueEntry); \ + } \ + (prQueue)->prTail = (prQueueEntry); \ + ((prQueue)->u4NumElem)++; \ + } + +/* NOTE: We assume the queue entry located at the beginning + * of "prQueueEntry Type", + * so that we can cast the queue entry to other data type without doubts. + * And this macro also decrease the total entry count at the same time. + */ +#define QUEUE_REMOVE_HEAD(prQueue, prQueueEntry, _P_TYPE) \ + { \ + ASSERT(prQueue); \ + prQueueEntry = (_P_TYPE)((prQueue)->prHead); \ + if (prQueueEntry) { \ + (prQueue)->prHead = \ + ((struct QUE_ENTRY *)(prQueueEntry))->prNext; \ + if ((prQueue)->prHead == (struct QUE_ENTRY *)NULL) { \ + (prQueue)->prTail = (struct QUE_ENTRY *)NULL; \ + } \ + ((struct QUE_ENTRY *)(prQueueEntry))->prNext = \ + (struct QUE_ENTRY *)NULL; \ + ((prQueue)->u4NumElem)--; \ + } \ + } + +#define QUEUE_MOVE_ALL(prDestQueue, prSrcQueue) \ + { \ + ASSERT(prDestQueue); \ + ASSERT(prSrcQueue); \ + *(struct QUE *)prDestQueue = *(struct QUE *)prSrcQueue; \ + QUEUE_INITIALIZE(prSrcQueue); \ + } + +#define QUEUE_CONCATENATE_QUEUES(prDestQueue, prSrcQueue) \ + { \ + ASSERT(prDestQueue); \ + ASSERT(prSrcQueue); \ + if ((prSrcQueue)->u4NumElem > 0) { \ + if ((prDestQueue)->prTail) { \ + ((prDestQueue)->prTail)->prNext = \ + (prSrcQueue)->prHead; \ + } else { \ + (prDestQueue)->prHead = (prSrcQueue)->prHead; \ + } \ + (prDestQueue)->prTail = (prSrcQueue)->prTail; \ + ((prDestQueue)->u4NumElem) += \ + ((prSrcQueue)->u4NumElem); \ + QUEUE_INITIALIZE(prSrcQueue); \ + } \ + } + +#define QUEUE_CONCATENATE_QUEUES_HEAD(prDestQueue, prSrcQueue) \ + { \ + ASSERT(prDestQueue); \ + ASSERT(prSrcQueue); \ + if ((prSrcQueue)->u4NumElem > 0 && (prSrcQueue)->prTail) { \ + ((prSrcQueue)->prTail)->prNext = \ + (prDestQueue)->prHead; \ + (prDestQueue)->prHead = (prSrcQueue)->prHead; \ + ((prDestQueue)->u4NumElem) += \ + ((prSrcQueue)->u4NumElem); \ + if ((prDestQueue)->prTail == NULL) { \ + (prDestQueue)->prTail = (prSrcQueue)->prTail; \ + } \ + QUEUE_INITIALIZE(prSrcQueue); \ + } \ + } + +/******************************************************************************* + * E X T E R N A L D A T A + ******************************************************************************* + */ +extern uint8_t g_arTdlsLink[MAXNUM_TDLS_PEER]; + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#endif /* _QUEUE_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/rftest.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/rftest.h new file mode 100644 index 0000000000000000000000000000000000000000..5b728261353589b7d883fd541cddd05ecb69c7de --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/rftest.h @@ -0,0 +1,438 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: include/rftest.h + */ + +/*! \file "rftest.h" + * \brief definitions for RF Productino test + * + */ + +#ifndef _RFTEST_H +#define _RFTEST_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +/* Table Version */ +#define RF_AUTO_TEST_FUNCTION_TABLE_VERSION 0x01000001 + +/* Power */ +#define RF_AT_PARAM_POWER_MASK BITS(0, 7) +#define RF_AT_PARAM_POWER_MAX RF_AT_PARAM_POWER_MASK + +/* Rate */ +#define RF_AT_PARAM_RATE_MCS_MASK BIT(31) +#define RF_AT_PARAM_RATE_MASK BITS(0, 7) +#define RF_AT_PARAM_RATE_CCK_MAX 3 +#define RF_AT_PARAM_RATE_1M 0 +#define RF_AT_PARAM_RATE_2M 1 +#define RF_AT_PARAM_RATE_5_5M 2 +#define RF_AT_PARAM_RATE_11M 3 +#define RF_AT_PARAM_RATE_6M 4 +#define RF_AT_PARAM_RATE_9M 5 +#define RF_AT_PARAM_RATE_12M 6 +#define RF_AT_PARAM_RATE_18M 7 +#define RF_AT_PARAM_RATE_24M 8 +#define RF_AT_PARAM_RATE_36M 9 +#define RF_AT_PARAM_RATE_48M 10 +#define RF_AT_PARAM_RATE_54M 11 + +/* Antenna */ +#define RF_AT_PARAM_ANTENNA_ID_MASK BITS(0, 7) +#define RF_AT_PARAM_ANTENNA_ID_MAX 1 + +/* Packet Length */ +#define RF_AT_PARAM_TX_80211HDR_BYTE_MAX (32) +#define RF_AT_PARAM_TX_80211PAYLOAD_BYTE_MAX (2048) + +#define RF_AT_PARAM_TX_PKTLEN_BYTE_DEFAULT 1024 +#define RF_AT_PARAM_TX_PKTLEN_BYTE_MAX \ + ((uint16_t)(RF_AT_PARAM_TX_80211HDR_BYTE_MAX + \ + RF_AT_PARAM_TX_80211PAYLOAD_BYTE_MAX)) + +/* Packet Count */ +#define RF_AT_PARAM_TX_PKTCNT_DEFAULT 1000 +#define RF_AT_PARAM_TX_PKTCNT_UNLIMITED 0 + +/* Packet Interval */ +#define RF_AT_PARAM_TX_PKT_INTERVAL_US_DEFAULT 50 + +/* ALC */ +#define RF_AT_PARAM_ALC_DISABLE 0 +#define RF_AT_PARAM_ALC_ENABLE 1 + +/* TXOP */ +#define RF_AT_PARAM_TXOP_DEFAULT 0 +#define RF_AT_PARAM_TXOPQUE_QMASK BITS(16, 31) +#define RF_AT_PARAM_TXOPQUE_TMASK BITS(0, 15) +#define RF_AT_PARAM_TXOPQUE_AC0 (0<<16) +#define RF_AT_PARAM_TXOPQUE_AC1 (1<<16) +#define RF_AT_PARAM_TXOPQUE_AC2 (2<<16) +#define RF_AT_PARAM_TXOPQUE_AC3 (3<<16) +#define RF_AT_PARAM_TXOPQUE_AC4 (4<<16) +#define RF_AT_PARAM_TXOPQUE_QOFFSET 16 + +/* Retry Limit */ +#define RF_AT_PARAM_TX_RETRY_DEFAULT 0 +#define RF_AT_PARAM_TX_RETRY_MAX 6 + +/* QoS Queue */ +#define RF_AT_PARAM_QOSQUE_AC0 0 +#define RF_AT_PARAM_QOSQUE_AC1 1 +#define RF_AT_PARAM_QOSQUE_AC2 2 +#define RF_AT_PARAM_QOSQUE_AC3 3 +#define RF_AT_PARAM_QOSQUE_AC4 4 +#define RF_AT_PARAM_QOSQUE_DEFAULT RF_AT_PARAM_QOSQUE_AC0 + +/* Bandwidth */ +#define RF_AT_PARAM_BANDWIDTH_20MHZ 0 +#define RF_AT_PARAM_BANDWIDTH_40MHZ 1 +#define RF_AT_PARAM_BANDWIDTH_U20_IN_40MHZ 2 +#define RF_AT_PARAM_BANDWIDTH_D20_IN_40MHZ 3 +#define RF_AT_PARAM_BANDWIDTH_DEFAULT RF_AT_PARAM_BANDWIDTH_20MHZ + +/* GI (Guard Interval) */ +#define RF_AT_PARAM_GI_800NS 0 +#define RF_AT_PARAM_GI_400NS 1 +#define RF_AT_PARAM_GI_DEFAULT RF_AT_PARAM_GI_800NS + +/* STBC */ +#define RF_AT_PARAM_STBC_DISABLE 0 +#define RF_AT_PARAM_STBC_ENABLE 1 + +/* RIFS */ +#define RF_AT_PARAM_RIFS_DISABLE 0 +#define RF_AT_PARAM_RIFS_ENABLE 1 + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +/* Function ID List */ +enum ENUM_RF_AT_FUNCID { + RF_AT_FUNCID_VERSION = 0, + RF_AT_FUNCID_COMMAND, + RF_AT_FUNCID_POWER, + RF_AT_FUNCID_RATE, + RF_AT_FUNCID_PREAMBLE, + RF_AT_FUNCID_ANTENNA, + RF_AT_FUNCID_PKTLEN, + RF_AT_FUNCID_PKTCNT, + RF_AT_FUNCID_PKTINTERVAL, + RF_AT_FUNCID_TEMP_COMPEN, + RF_AT_FUNCID_TXOPLIMIT, + RF_AT_FUNCID_ACKPOLICY, + RF_AT_FUNCID_PKTCONTENT, + RF_AT_FUNCID_RETRYLIMIT, + RF_AT_FUNCID_QUEUE, + RF_AT_FUNCID_BANDWIDTH, + RF_AT_FUNCID_GI, + RF_AT_FUNCID_STBC, + RF_AT_FUNCID_CHNL_FREQ, + RF_AT_FUNCID_RIFS, + RF_AT_FUNCID_TRSW_TYPE, + RF_AT_FUNCID_RF_SX_SHUTDOWN, + RF_AT_FUNCID_PLL_SHUTDOWN, + RF_AT_FUNCID_SLOW_CLK_MODE, + RF_AT_FUNCID_ADC_CLK_MODE, + RF_AT_FUNCID_MEASURE_MODE, + RF_AT_FUNCID_VOLT_COMPEN, + RF_AT_FUNCID_DPD_TX_GAIN, + RF_AT_FUNCID_DPD_MODE, + RF_AT_FUNCID_TSSI_MODE, + RF_AT_FUNCID_TX_GAIN_CODE, + RF_AT_FUNCID_TX_PWR_MODE, + + /* Query command */ + RF_AT_FUNCID_TXED_COUNT = 32, + RF_AT_FUNCID_TXOK_COUNT, + RF_AT_FUNCID_RXOK_COUNT, + RF_AT_FUNCID_RXERROR_COUNT, + RF_AT_FUNCID_RESULT_INFO, + RF_AT_FUNCID_TRX_IQ_RESULT, + RF_AT_FUNCID_TSSI_RESULT, + RF_AT_FUNCID_DPD_RESULT, + RF_AT_FUNCID_RXV_DUMP, + RF_AT_FUNCID_RX_PHY_STATIS, + RF_AT_FUNCID_MEASURE_RESULT, + RF_AT_FUNCID_TEMP_SENSOR, + RF_AT_FUNCID_VOLT_SENSOR, + RF_AT_FUNCID_READ_EFUSE, + RF_AT_FUNCID_RX_RSSI, + RF_AT_FUNCID_FW_INFO, + RF_AT_FUNCID_DRV_INFO, + RF_AT_FUNCID_PWR_DETECTOR, + RF_AT_FUNCID_WBRSSI_IBSSI, + + /* Set command */ + RF_AT_FUNCID_SET_DPD_RESULT = 64, + RF_AT_FUNCID_SET_CW_MODE, + RF_AT_FUNCID_SET_JAPAN_CH14_FILTER, + RF_AT_FUNCID_WRITE_EFUSE, + RF_AT_FUNCID_SET_MAC_ADDRESS, + RF_AT_FUNCID_SET_TA, + RF_AT_FUNCID_SET_RX_MATCH_RULE, + + /* 80211AC & Jmode */ + RF_AT_FUNCID_SET_CBW = 71, + RF_AT_FUNCID_SET_DBW, + RF_AT_FUNCID_SET_PRIMARY_CH, + RF_AT_FUNCID_SET_ENCODE_MODE, + RF_AT_FUNCID_SET_J_MODE, + + /* ICAP command */ + RF_AT_FUNCID_SET_ICAP_CONTENT = 80, + RF_AT_FUNCID_SET_ICAP_MODE, + RF_AT_FUNCID_SET_ICAP_STARTCAP, + RF_AT_FUNCID_SET_ICAP_SIZE = 83, + RF_AT_FUNCID_SET_ICAP_TRIGGER_OFFSET, + RF_AT_FUNCID_QUERY_ICAP_DUMP_FILE = 85, + +#if CFG_SUPPORT_QA_TOOL + /* 2G 5G Band */ + RF_AT_FUNCID_SET_BAND = 90, + + /* Reset Counter */ + RF_AT_FUNCID_RESETTXRXCOUNTER = 91, + + /* FAGC RSSI Path */ + RF_AT_FUNCID_FAGC_RSSI_PATH = 92, + + /* Set RX Filter Packet Length */ + RF_AT_FUNCID_RX_FILTER_PKT_LEN = 93, + + /* Tone */ + RF_AT_FUNCID_SET_TONE_RF_GAIN = 96, + RF_AT_FUNCID_SET_TONE_DIGITAL_GAIN = 97, + RF_AT_FUNCID_SET_TONE_TYPE = 98, + RF_AT_FUNCID_SET_TONE_DC_OFFSET = 99, + RF_AT_FUNCID_SET_TONE_BW = 100, + + /* MT6632 Add */ + RF_AT_FUNCID_SET_MAC_HEADER = 101, + RF_AT_FUNCID_SET_SEQ_CTRL = 102, + RF_AT_FUNCID_SET_PAYLOAD = 103, + RF_AT_FUNCID_SET_DBDC_BAND_IDX = 104, + RF_AT_FUNCID_SET_BYPASS_CAL_STEP = 105, + + /* Set RX Path */ + RF_AT_FUNCID_SET_RX_PATH = 106, + + /* Set Frequency Offset */ + RF_AT_FUNCID_SET_FRWQ_OFFSET = 107, + + /* Get Frequency Offset */ + RF_AT_FUNCID_GET_FREQ_OFFSET = 108, + + /* Set RXV Debug Index */ + RF_AT_FUNCID_SET_RXV_INDEX = 109, + + /* Set Test Mode DBDC Enable */ + RF_AT_FUNCID_SET_DBDC_ENABLE = 110, + + /* Get Test Mode DBDC Enable */ + RF_AT_FUNCID_GET_DBDC_ENABLE = 111, + + /* Set ICAP Ring Capture */ + RF_AT_FUNCID_SET_ICAP_RING = 112, + + /* Set TX Path */ + RF_AT_FUNCID_SET_TX_PATH = 113, + + /* Set Nss */ + RF_AT_FUNCID_SET_NSS = 114, + + /* Set TX Antenna Mask */ + RF_AT_FUNCID_SET_ANTMASK = 115, + + /* TMR set command */ + RF_AT_FUNCID_SET_TMR_ROLE = 116, + RF_AT_FUNCID_SET_TMR_MODULE = 117, + RF_AT_FUNCID_SET_TMR_DBM = 118, + RF_AT_FUNCID_SET_TMR_ITER = 119, + + /* Set ADC For IRR Feature */ + RF_AT_FUNCID_SET_ADC = 120, + + /* Set RX Gain For IRR Feature */ + RF_AT_FUNCID_SET_RX_GAIN = 121, + + /* Set TTG For IRR Feature */ + RF_AT_FUNCID_SET_TTG = 122, + + /* Set TTG ON/OFF For IRR Feature */ + RF_AT_FUNCID_TTG_ON_OFF = 123, + + /* Set TSSI for QA Tool Setting */ + RF_AT_FUNCID_SET_TSSI = 124, + + /* Set Recal Cal Step */ + RF_AT_FUNCID_SET_RECAL_CAL_STEP = 125, + + /* Set iBF/eBF enable */ + RF_AT_FUNCID_SET_IBF_ENABLE = 126, + RF_AT_FUNCID_SET_EBF_ENABLE = 127, + + /* Set MPS Setting */ + RF_AT_FUNCID_SET_MPS_SIZE = 128, + RF_AT_FUNCID_SET_MPS_SEQ_DATA = 129, + RF_AT_FUNCID_SET_MPS_PAYLOAD_LEN = 130, + RF_AT_FUNCID_SET_MPS_PKT_CNT = 131, + RF_AT_FUNCID_SET_MPS_PWR_GAIN = 132, + RF_AT_FUNCID_SET_MPS_NSS = 133, + RF_AT_FUNCID_SET_MPS_PACKAGE_BW = 134, +#endif +#if CFG_SUPPORT_ANT_SWAP + /* Antenna swap feature*/ + RF_AT_FUNCID_SET_ANT_SWP = 153, +#endif + +}; + +/* Command */ +enum ENUM_RF_AT_COMMAND { + RF_AT_COMMAND_STOPTEST = 0, + RF_AT_COMMAND_STARTTX, + RF_AT_COMMAND_STARTRX, + RF_AT_COMMAND_RESET, + RF_AT_COMMAND_OUTPUT_POWER, /* Payload */ + /* Local freq is renamed to Local leakage */ + RF_AT_COMMAND_LO_LEAKAGE, + /* OFDM (LTF/STF), CCK (PI,PI/2) */ + RF_AT_COMMAND_CARRIER_SUPPR, + RF_AT_COMMAND_TRX_IQ_CAL, + RF_AT_COMMAND_TSSI_CAL, + RF_AT_COMMAND_DPD_CAL, + RF_AT_COMMAND_CW, + RF_AT_COMMAND_ICAP, + RF_AT_COMMAND_RDD, + RF_AT_COMMAND_CH_SWITCH_FOR_ICAP, + RF_AT_COMMAND_RESET_DUMP_NAME, + RF_AT_COMMAND_SINGLE_TONE, + RF_AT_COMMAND_RDD_OFF, + RF_AT_COMMAND_NUM +}; + +/* Preamble */ +enum ENUM_RF_AT_PREAMBLE { + RF_AT_PREAMBLE_NORMAL = 0, + RF_AT_PREAMBLE_CCK_SHORT, + RF_AT_PREAMBLE_11N_MM, + RF_AT_PREAMBLE_11N_GF, + RF_AT_PREAMBLE_11AC, + RF_AT_PREAMBLE_NUM +}; + +/* Ack Policy */ +enum ENUM_RF_AT_ACK_POLICY { + RF_AT_ACK_POLICY_NORMAL = 0, + RF_AT_ACK_POLICY_NOACK, + RF_AT_ACK_POLICY_NOEXPLICTACK, + RF_AT_ACK_POLICY_BLOCKACK, + RF_AT_ACK_POLICY_NUM +}; + +enum ENUM_RF_AUTOTEST_STATE { + RF_AUTOTEST_STATE_STANDBY = 0, + RF_AUTOTEST_STATE_TX, + RF_AUTOTEST_STATE_RX, + RF_AUTOTEST_STATE_RESET, + RF_AUTOTEST_STATE_OUTPUT_POWER, + RF_AUTOTEST_STATE_LOCA_FREQUENCY, + RF_AUTOTEST_STATE_CARRIER_SUPRRESION, + RF_AUTOTEST_STATE_NUM +}; + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +uint32_t rftestSetATInfo(IN struct ADAPTER *prAdapter, + uint32_t u4FuncIndex, uint32_t u4FuncData); + +uint32_t rftestQueryATInfo(IN struct ADAPTER *prAdapter, + uint32_t u4FuncIndex, uint32_t u4FuncData, + OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen); + +uint32_t rftestSetFrequency(IN struct ADAPTER *prAdapter, + IN uint32_t u4FreqInKHz, IN uint32_t *pu4SetInfoLen); + +#endif /* _RFTEST_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/typedef.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/typedef.h new file mode 100644 index 0000000000000000000000000000000000000000..2fb0ff00bde7ce6ec4a9b330bf57af5cdc22892c --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/typedef.h @@ -0,0 +1,204 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: include/typedef.h + */ + +/*! \file typedef.h + * \brief Declaration of data type and return values of + * internal protocol stack. + * + * In this file we declare the data type and return values + * which will be exported to the GLUE Layer. + */ + +#ifndef _TYPEDEF_H +#define _TYPEDEF_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/* ieee80211.h of linux has duplicated definitions */ +#if defined(WLAN_STATUS_SUCCESS) +#undef WLAN_STATUS_SUCCESS +#endif + +#define WLAN_STATUS_SUCCESS ((uint32_t) 0x00000000L) +#define WLAN_STATUS_PENDING ((uint32_t) 0x00000103L) +#define WLAN_STATUS_NOT_ACCEPTED ((uint32_t) 0x00010003L) + +#define WLAN_STATUS_MEDIA_CONNECT ((uint32_t) 0x4001000BL) +#define WLAN_STATUS_MEDIA_DISCONNECT ((uint32_t) 0x4001000CL) +#define WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY ((uint32_t) 0x4001000DL) +#define WLAN_STATUS_MEDIA_SPECIFIC_INDICATION ((uint32_t) 0x40010012L) + +#define WLAN_STATUS_SCAN_COMPLETE ((uint32_t) 0x60010001L) +#define WLAN_STATUS_MSDU_OK ((uint32_t) 0x60010002L) + +/* TODO(Kevin): double check if 0x60010001 & 0x60010002 is proprietary */ +#define WLAN_STATUS_ROAM_OUT_FIND_BEST ((uint32_t) 0x60010101L) +#define WLAN_STATUS_ROAM_DISCOVERY ((uint32_t) 0x60010102L) + +#define WLAN_STATUS_FAILURE ((uint32_t) 0xC0000001L) +#define WLAN_STATUS_RESOURCES ((uint32_t) 0xC000009AL) +#define WLAN_STATUS_NOT_SUPPORTED ((uint32_t) 0xC00000BBL) + +#define WLAN_STATUS_MULTICAST_FULL ((uint32_t) 0xC0010009L) +#define WLAN_STATUS_INVALID_PACKET ((uint32_t) 0xC001000FL) +#define WLAN_STATUS_ADAPTER_NOT_READY ((uint32_t) 0xC0010011L) +#define WLAN_STATUS_NOT_INDICATING ((uint32_t) 0xC0010013L) +#define WLAN_STATUS_INVALID_LENGTH ((uint32_t) 0xC0010014L) +#define WLAN_STATUS_INVALID_DATA ((uint32_t) 0xC0010015L) +#define WLAN_STATUS_BUFFER_TOO_SHORT ((uint32_t) 0xC0010016L) +#define WLAN_STATUS_BWCS_UPDATE ((uint32_t) 0xC0010017L) + +#define WLAN_STATUS_JOIN_FAILURE ((uint32_t) 0xc0010018L) + +/* NIC status flags */ +#define ADAPTER_FLAG_HW_ERR 0x00400000 + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +/* Type definition for GLUE_INFO structure */ +struct GLUE_INFO; /* declare GLUE_INFO_T */ + +/* Type definition for WLAN STATUS */ + +/* Type definition for ADAPTER structure */ +struct ADAPTER; /* declare ADAPTER_T */ + +/* Type definition for MESSAGE HEADER structure */ +struct MSG_HDR; /* declare MSG_HDR_T */ + +/* Type definition for Pointer to OS Native Packet */ + +/* Type definition for WLAN configuration */ +struct WLAN_CFG; /* declare WLAN_CFG_T */ + +struct WLAN_CFG_REC; /* declare WLAN_CFG_REC_T */ + + +/* Type definition for WLAN configuration entry */ +struct WLAN_CFG_ENTRY; /* declare WLAN_CFG_ENTRY_T */ + +/* Type definition for WLAN configuration callback */ +typedef uint32_t(*WLAN_CFG_SET_CB) (struct ADAPTER + *prAdapter, + uint8_t *pucKey, + uint8_t *pucValue, + void *pPrivate, + uint32_t u4Flags); + +/* Type definition for STA_RECORD_T structure to handle the connectivity + * and packet reception for a particular STA. + */ +struct STA_RECORD; /* declare STA_RECORD_T */ + +/* CMD_INFO_T is used by Glue Layer to send a cluster of Command(OID) + * information to the TX Path to reduce the parameters of a function call. + */ +struct CMD_INFO; /* declare CMD_INFO_T */ + +/* Following typedef should be removed later, because Glue Layer + * should not be aware of following data type. + */ +struct SW_RFB; /* declare SW_RFB_T */ + +struct MSDU_INFO; /* declare MSDU_INFO_T */ + +struct REG_ENTRY; /* declare REG_ENTRY_T */ + +/* IST handler definition */ +typedef void(*IST_EVENT_FUNCTION) (struct ADAPTER *); + +/* Type definition for function pointer of timer handler */ +typedef void(*PFN_TIMER_CALLBACK) (IN struct GLUE_INFO *); + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +#endif /* _TYPEDEF_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/wlan_bow.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/wlan_bow.h new file mode 100644 index 0000000000000000000000000000000000000000..1c8a63625264e8d43cdbae0db7aa2669018e6d57 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/wlan_bow.h @@ -0,0 +1,302 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* +** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/wlan_bow.h#1 +*/ + +/*! \file "wlan_bow.h" +* \brief This file contains the declairations of 802.11 PAL +* command processing routines for +* MediaTek Inc. 802.11 Wireless LAN Adapters. +*/ + + +#ifndef _WLAN_BOW_H +#define _WLAN_BOW_H + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include "nic/bow.h" +#include "nic/cmd_buf.h" + +#if CFG_ENABLE_BT_OVER_WIFI + +extern uint32_t g_arBowRevPalPacketTime[32]; + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ +#define BOWCMD_STATUS_SUCCESS 0 +#define BOWCMD_STATUS_FAILURE 1 +#define BOWCMD_STATUS_UNACCEPTED 2 +#define BOWCMD_STATUS_INVALID 3 +#define BOWCMD_STATUS_TIMEOUT 4 + +#define BOW_WILDCARD_SSID "AMP" +#define BOW_WILDCARD_SSID_LEN 3 +#define BOW_SSID_LEN 21 + + /* 0: query, 1: setup, 2: destroy */ +#define BOW_QUERY_CMD 0 +#define BOW_SETUP_CMD 1 +#define BOW_DESTROY_CMD 2 + +#define BOW_INITIATOR 0 +#define BOW_RESPONDER 1 + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +struct BOW_TABLE { + uint8_t ucAcquireID; + u_int8_t fgIsValid; + enum ENUM_BOW_DEVICE_STATE eState; + uint8_t aucPeerAddress[6]; + /* UINT_8 ucRole; */ + /* UINT_8 ucChannelNum; */ + uint16_t u2Reserved; +}; + +typedef uint32_t(*PFN_BOW_CMD_HANDLE) (struct ADAPTER *, struct BT_OVER_WIFI_COMMAND *); + +struct BOW_CMD { + uint8_t uCmdID; + PFN_BOW_CMD_HANDLE pfCmdHandle; +}; + +struct BOW_EVENT_ACTIVITY_REPORT { + uint8_t ucReason; + uint8_t aucReserved; + uint8_t aucPeerAddress[6]; +}; + +/* +*ucReason: 0: success +* 1: general failure +* 2: too much time (> 2/3 second totally) requested for scheduling. +* Others: reserved. +*/ + +struct BOW_EVENT_SYNC_TSF { + uint64_t u4TsfTime; + uint32_t u4TsfSysTime; + uint32_t u4ScoTime; + uint32_t u4ScoSysTime; +}; + +struct BOW_ACTIVITY_REPORT_BODY { + uint32_t u4StartTime; + uint32_t u4Duration; + uint32_t u4Periodicity; +}; + +struct BOW_ACTIVITY_REPORT { + uint8_t aucPeerAddress[6]; + uint8_t ucScheduleKnown; + uint8_t ucNumReports; + struct BOW_ACTIVITY_REPORT_BODY arBowActivityReportBody[MAX_ACTIVITY_REPORT]; +}; + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +/*--------------------------------------------------------------*/ +/* Firmware Command Packer */ +/*--------------------------------------------------------------*/ +uint32_t +wlanoidSendSetQueryBowCmd(IN struct ADAPTER *prAdapter, + uint8_t ucCID, + IN uint8_t ucBssIdx, + u_int8_t fgSetQuery, + u_int8_t fgNeedResp, + PFN_CMD_DONE_HANDLER pfCmdDoneHandler, + PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler, + uint32_t u4SetQueryInfoLen, uint8_t *pucInfoBuffer, IN uint8_t ucSeqNumber); + +/*--------------------------------------------------------------*/ +/* Command Dispatcher */ +/*--------------------------------------------------------------*/ +uint32_t wlanbowHandleCommand(IN struct ADAPTER *prAdapter, IN struct BT_OVER_WIFI_COMMAND *prCmd); + +/*--------------------------------------------------------------*/ +/* Routines to handle command */ +/*--------------------------------------------------------------*/ +uint32_t bowCmdGetMacStatus(IN struct ADAPTER *prAdapter, IN struct BT_OVER_WIFI_COMMAND *prCmd); + +uint32_t bowCmdSetupConnection(IN struct ADAPTER *prAdapter, IN struct BT_OVER_WIFI_COMMAND *prCmd); + +uint32_t bowCmdDestroyConnection(IN struct ADAPTER *prAdapter, IN struct BT_OVER_WIFI_COMMAND *prCmd); + +uint32_t bowCmdSetPTK(IN struct ADAPTER *prAdapter, IN struct BT_OVER_WIFI_COMMAND *prCmd); + +uint32_t bowCmdReadRSSI(IN struct ADAPTER *prAdapter, IN struct BT_OVER_WIFI_COMMAND *prCmd); + +uint32_t bowCmdReadLinkQuality(IN struct ADAPTER *prAdapter, IN struct BT_OVER_WIFI_COMMAND *prCmd); + +uint32_t bowCmdShortRangeMode(IN struct ADAPTER *prAdapter, IN struct BT_OVER_WIFI_COMMAND *prCmd); + +uint32_t bowCmdGetChannelList(IN struct ADAPTER *prAdapter, IN struct BT_OVER_WIFI_COMMAND *prCmd); + +void wlanbowCmdEventSetStatus(IN struct ADAPTER *prAdapter, IN struct BT_OVER_WIFI_COMMAND *prCmd, IN uint8_t ucEventBuf); + +/*--------------------------------------------------------------*/ +/* Callbacks for event indication */ +/*--------------------------------------------------------------*/ +void wlanbowCmdEventSetCommon(IN struct ADAPTER *prAdapter, IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf); + +void wlanbowCmdEventLinkConnected(IN struct ADAPTER *prAdapter, IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf); + +void wlanbowCmdEventLinkDisconnected(IN struct ADAPTER *prAdapter, IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf); + +void wlanbowCmdEventSetSetupConnection(IN struct ADAPTER *prAdapter, IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf); + +void wlanbowCmdEventReadLinkQuality(IN struct ADAPTER *prAdapter, IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf); + +void wlanbowCmdEventReadRssi(IN struct ADAPTER *prAdapter, IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf); + +uint8_t bowInit(IN struct ADAPTER *prAdapter); + +void bowUninit(IN struct ADAPTER *prAdapter); + +void wlanbowCmdTimeoutHandler(IN struct ADAPTER *prAdapter, IN struct CMD_INFO *prCmdInfo); + +void bowStopping(IN struct ADAPTER *prAdapter); + +void bowStarting(IN struct ADAPTER *prAdapter); + +void bowAssignSsid(IN uint8_t *pucSsid, IN uint8_t *pucSsidLen); + +u_int8_t bowValidateProbeReq(IN struct ADAPTER *prAdapter, IN struct SW_RFB *prSwRfb, OUT uint32_t *pu4ControlFlags); + +void bowSendBeacon(IN struct ADAPTER *prAdapter, unsigned long ulParamPtr); + +void bowResponderScan(IN struct ADAPTER *prAdapter); + +void bowResponderScanDone(IN struct ADAPTER *prAdapter, IN struct MSG_HDR *prMsgHdr); + +void bowResponderCancelScan(IN struct ADAPTER *prAdapter, IN u_int8_t fgIsChannelExtention); + +void bowResponderJoin(IN struct ADAPTER *prAdapter, struct BSS_DESC *prBssDesc); + +void bowFsmRunEventJoinComplete(IN struct ADAPTER *prAdapter, IN struct MSG_HDR *prMsgHdr); + +void +bowIndicationOfMediaStateToHost(IN struct ADAPTER *prAdapter, + enum ENUM_PARAM_MEDIA_STATE eConnectionState, u_int8_t fgDelayIndication); + +void bowRunEventAAATxFail(IN struct ADAPTER *prAdapter, IN struct STA_RECORD *prStaRec); + +uint32_t bowRunEventAAAComplete(IN struct ADAPTER *prAdapter, IN struct STA_RECORD *prStaRec); + +uint32_t bowRunEventRxDeAuth(IN struct ADAPTER *prAdapter, IN struct STA_RECORD *prStaRec, IN struct SW_RFB *prSwRfb); + +void bowDisconnectLink(IN struct ADAPTER *prAdapter, IN struct MSDU_INFO *prMsduInfo, IN enum ENUM_TX_RESULT_CODE rTxDoneStatus); + +u_int8_t bowValidateAssocReq(IN struct ADAPTER *prAdapter, IN struct SW_RFB *prSwRfb, OUT uint16_t *pu2StatusCode); + +u_int8_t +bowValidateAuth(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, IN struct STA_RECORD **pprStaRec, OUT uint16_t *pu2StatusCode); + +void bowRunEventChGrant(IN struct ADAPTER *prAdapter, IN struct MSG_HDR *prMsgHdr); + +void bowRequestCh(IN struct ADAPTER *prAdapter); + +void bowReleaseCh(IN struct ADAPTER *prAdapter); + +void bowChGrantedTimeout(IN struct ADAPTER *prAdapter, IN unsigned long ulParamPtr); + +u_int8_t bowNotifyAllLinkDisconnected(IN struct ADAPTER *prAdapter); + +u_int8_t bowCheckBowTableIfVaild(IN struct ADAPTER *prAdapter, IN uint8_t aucPeerAddress[6]); + +u_int8_t bowGetBowTableContent(IN struct ADAPTER *prAdapter, IN uint8_t ucBowTableIdx, OUT struct BOW_TABLE *prBowTable); + +u_int8_t +bowGetBowTableEntryByPeerAddress(IN struct ADAPTER *prAdapter, IN uint8_t aucPeerAddress[6], OUT uint8_t *pucBowTableIdx); + +u_int8_t bowGetBowTableFreeEntry(IN struct ADAPTER *prAdapter, OUT uint8_t *pucBowTableIdx); + +enum ENUM_BOW_DEVICE_STATE bowGetBowTableState(IN struct ADAPTER *prAdapter, IN uint8_t aucPeerAddress[6]); + +u_int8_t bowSetBowTableState(IN struct ADAPTER *prAdapter, IN uint8_t aucPeerAddress[6], IN enum ENUM_BOW_DEVICE_STATE eState); + +u_int8_t bowSetBowTableContent(IN struct ADAPTER *prAdapter, IN uint8_t ucBowTableIdx, IN struct BOW_TABLE *prBowTable); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif +#endif /* _WLAN_BOW_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/wlan_he.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/wlan_he.h new file mode 100644 index 0000000000000000000000000000000000000000..f0ff14f764be495095012748db91d7e21a8e24d1 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/wlan_he.h @@ -0,0 +1,107 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/*! \file "wlan_he.h" +* \brief This file contains the declairations of HE(802.11ax) +* processing routines for MediaTek Inc. 802.11 Wireless LAN Adapters. +*/ + + +#ifndef _WLAN_HE_H +#define _WLAN_HE_H + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +extern uint8_t fgEfuseCtrlAxOn; + +#if (CFG_SUPPORT_802_11AX == 1) +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* CFG_SUPPORT_802_11AX == 1 */ +#endif /* _WLAN_HE_H */ + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/wlan_lib.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/wlan_lib.h new file mode 100644 index 0000000000000000000000000000000000000000..fabb4f30767371f4e8a881eff02b0348b0d03083 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/wlan_lib.h @@ -0,0 +1,1851 @@ +/******************************************************************************* + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include + * /wlan_lib.h#3 + */ + +/*! \file "wlan_lib.h" + * \brief The declaration of the functions of the wlanAdpater objects + * + * Detail description. + */ + +#ifndef _WLAN_LIB_H +#define _WLAN_LIB_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "CFG_Wifi_File.h" +#include "rlm_domain.h" +#include "nic_init_cmd_event.h" +#include "fw_dl.h" +#include "queue.h" +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +/* These values must sync from Wifi HAL + * /hardware/libhardware_legacy/include/hardware_legacy/wifi_hal.h + */ +/* Basic infrastructure mode */ +#define WIFI_FEATURE_INFRA (0x0001) +/* Support for 5 GHz Band */ +#define WIFI_FEATURE_INFRA_5G (0x0002) +/* Support for GAS/ANQP */ +#define WIFI_FEATURE_HOTSPOT (0x0004) +/* Wifi-Direct */ +#define WIFI_FEATURE_P2P (0x0008) +/* Soft AP */ +#define WIFI_FEATURE_SOFT_AP (0x0010) +/* Google-Scan APIs */ +#define WIFI_FEATURE_GSCAN (0x0020) +/* Neighbor Awareness Networking */ +#define WIFI_FEATURE_NAN (0x0040) +/* Device-to-device RTT */ +#define WIFI_FEATURE_D2D_RTT (0x0080) +/* Device-to-AP RTT */ +#define WIFI_FEATURE_D2AP_RTT (0x0100) +/* Batched Scan (legacy) */ +#define WIFI_FEATURE_BATCH_SCAN (0x0200) +/* Preferred network offload */ +#define WIFI_FEATURE_PNO (0x0400) +/* Support for two STAs */ +#define WIFI_FEATURE_ADDITIONAL_STA (0x0800) +/* Tunnel directed link setup */ +#define WIFI_FEATURE_TDLS (0x1000) +/* Support for TDLS off channel */ +#define WIFI_FEATURE_TDLS_OFFCHANNEL (0x2000) +/* Enhanced power reporting */ +#define WIFI_FEATURE_EPR (0x4000) +/* Support for AP STA Concurrency */ +#define WIFI_FEATURE_AP_STA (0x8000) +/* Link layer stats collection */ +#define WIFI_FEATURE_LINK_LAYER_STATS (0x10000) +/* WiFi Logger */ +#define WIFI_FEATURE_LOGGER (0x20000) +/* WiFi PNO enhanced */ +#define WIFI_FEATURE_HAL_EPNO (0x40000) +/* RSSI Monitor */ +#define WIFI_FEATURE_RSSI_MONITOR (0x80000) +/* WiFi mkeep_alive */ +#define WIFI_FEATURE_MKEEP_ALIVE (0x100000) +/* ND offload configure */ +#define WIFI_FEATURE_CONFIG_NDO (0x200000) +/* Capture Tx transmit power levels */ +#define WIFI_FEATURE_TX_TRANSMIT_POWER (0x400000) +/* Enable/Disable firmware roaming */ +#define WIFI_FEATURE_CONTROL_ROAMING (0x800000) +/* Support Probe IE white listing */ +#define WIFI_FEATURE_IE_WHITELIST (0x1000000) +/* Support MAC & Probe Sequence Number randomization */ +#define WIFI_FEATURE_SCAN_RAND (0x2000000) +/* Support Tx Power Limit setting */ +#define WIFI_FEATURE_SET_TX_POWER_LIMIT (0x4000000) +/* Support Using Body/Head Proximity for SAR */ +#define WIFI_FEATURE_USE_BODY_HEAD_SAR (0x8000000) +/* Support Random P2P MAC */ +#define WIFI_FEATURE_P2P_RAND_MAC (0x80000000) + +/* note: WIFI_FEATURE_GSCAN be enabled just for ACTS test item: scanner */ +#define WIFI_HAL_FEATURE_SET ((WIFI_FEATURE_P2P) |\ + (WIFI_FEATURE_SOFT_AP) |\ + (WIFI_FEATURE_PNO) |\ + (WIFI_FEATURE_TDLS) |\ + (WIFI_FEATURE_RSSI_MONITOR) |\ + (WIFI_FEATURE_CONTROL_ROAMING) |\ + (WIFI_FEATURE_SET_TX_POWER_LIMIT) |\ + (WIFI_FEATURE_P2P_RAND_MAC)\ + ) + +#define MAX_NUM_GROUP_ADDR 32 /* max number of group addresses */ +#define AUTO_RATE_NUM 8 +#define AR_RATE_TABLE_ENTRY_MAX 25 +#define AR_RATE_ENTRY_INDEX_NULL 0x80 +#define MAX_TX_QUALITY_INDEX 4 + +#define TX_CS_TCP_UDP_GEN BIT(1) +#define TX_CS_IP_GEN BIT(0) + +#define CSUM_OFFLOAD_EN_TX_TCP BIT(0) +#define CSUM_OFFLOAD_EN_TX_UDP BIT(1) +#define CSUM_OFFLOAD_EN_TX_IP BIT(2) +#define CSUM_OFFLOAD_EN_RX_TCP BIT(3) +#define CSUM_OFFLOAD_EN_RX_UDP BIT(4) +#define CSUM_OFFLOAD_EN_RX_IPv4 BIT(5) +#define CSUM_OFFLOAD_EN_RX_IPv6 BIT(6) +#define CSUM_OFFLOAD_EN_TX_MASK BITS(0, 2) +#define CSUM_OFFLOAD_EN_ALL BITS(0, 6) + +/* TCP, UDP, IP Checksum */ +#define RX_CS_TYPE_UDP BIT(7) +#define RX_CS_TYPE_TCP BIT(6) +#define RX_CS_TYPE_IPv6 BIT(5) +#define RX_CS_TYPE_IPv4 BIT(4) + +#define RX_CS_STATUS_UDP BIT(3) +#define RX_CS_STATUS_TCP BIT(2) +#define RX_CS_STATUS_IP BIT(0) + +#define CSUM_NOT_SUPPORTED 0x0 + +#define TXPWR_USE_PDSLOPE 0 + +/* NVRAM error code definitions */ +#define NVRAM_ERROR_VERSION_MISMATCH BIT(1) +#define NVRAM_ERROR_INVALID_TXPWR BIT(2) +#define NVRAM_ERROR_INVALID_DPD BIT(3) +#define NVRAM_ERROR_INVALID_MAC_ADDR BIT(4) +#if CFG_SUPPORT_PWR_LIMIT_COUNTRY +#define NVRAM_POWER_LIMIT_TABLE_INVALID BIT(5) +#endif + +#define NUM_TC_RESOURCE_TO_STATISTICS 4 +#if CFG_SUPPORT_NCHO +#define WLAN_CFG_ARGV_MAX 64 +#else +#define WLAN_CFG_ARGV_MAX 20 +#endif +#define WLAN_CFG_ARGV_MAX_LONG 22 /* for WOW, 2+20 */ +#define WLAN_CFG_ENTRY_NUM_MAX 400 /* 128 */ +#define WLAN_CFG_KEY_LEN_MAX 32 /* include \x00 EOL */ +#define WLAN_CFG_VALUE_LEN_MAX 128 /* include \x00 EOL */ +#define WLAN_CFG_FLAG_SKIP_CB BIT(0) +#define WLAN_CFG_FILE_BUF_SIZE 2048 + +#define WLAN_CFG_REC_ENTRY_NUM_MAX 400 + + + +#define WLAN_CFG_SET_CHIP_LEN_MAX 10 +#define WLAN_CFG_SET_DEBUG_LEVEL_LEN_MAX 10 +#define WLAN_CFG_SET_SW_CTRL_LEN_MAX 10 + +/* OID timeout (in ms) */ +#define WLAN_OID_TIMEOUT_THRESHOLD 2000 + +/* OID timeout during chip-resetting (in ms) */ +#define WLAN_OID_TIMEOUT_THRESHOLD_IN_RESETTING 300 + +#define WLAN_OID_NO_ACK_THRESHOLD 3 + + +/* If not setting the priority, 0 is the default */ +#define WLAN_THREAD_TASK_PRIORITY 0 + +/* If not setting the nice, -10 is the default */ +#define WLAN_THREAD_TASK_NICE (-10) + +#define WLAN_TX_STATS_LOG_TIMEOUT 30000 +#define WLAN_TX_STATS_LOG_DURATION 1500 + +/* Define for wifi path usage */ +#define WLAN_FLAG_2G4_WF0 BIT(0) /*1: support, 0: NOT support */ +#define WLAN_FLAG_5G_WF0 BIT(1) /*1: support, 0: NOT support */ +#define WLAN_FLAG_2G4_WF1 BIT(2) /*1: support, 0: NOT support */ +#define WLAN_FLAG_5G_WF1 BIT(3) /*1: support, 0: NOT support */ +#define WLAN_FLAG_2G4_COANT_SUPPORT BIT(4) /*1: support, 0: NOT support */ +#define WLAN_FLAG_2G4_COANT_PATH BIT(5) /*1: WF1, 0:WF0 */ +#define WLAN_FLAG_5G_COANT_SUPPORT BIT(6) /*1: support, 0: NOT support */ +#define WLAN_FLAG_5G_COANT_PATH BIT(7) /*1: WF1, 0:WF0 */ + +/* Define concurrent network channel number, using by CNM/CMD */ +#define MAX_OP_CHNL_NUM 3 + +/* Stat CMD will have different format due to different algorithm support */ +#if (defined(MT6632) || defined(MT7668)) +#define CFG_SUPPORT_RA_GEN 0 +#define CFG_SUPPORT_TXPOWER_INFO 0 +#else +#define CFG_SUPPORT_RA_GEN 1 +#define CFG_SUPPORT_TXPOWER_INFO 1 +#endif + +#if (CFG_SUPPORT_CONNAC2X == 1) +#define AGG_RANGE_SEL_NUM 15 +#else +#define AGG_RANGE_SEL_NUM 7 +#endif + +#if CFG_SUPPORT_EASY_DEBUG + +#define MAX_CMD_ITEM_MAX 4 /* Max item per cmd. */ +#define MAX_CMD_NAME_MAX_LENGTH 32 /* Max name string length */ +#define MAX_CMD_VALUE_MAX_LENGTH 32 /* Max value string length */ +#define MAX_CMD_TYPE_LENGTH 1 +#define MAX_CMD_STRING_LENGTH 1 +#define MAX_CMD_VALUE_LENGTH 1 +#define MAX_CMD_RESERVE_LENGTH 1 + +#define CMD_FORMAT_V1_LENGTH \ + (MAX_CMD_NAME_MAX_LENGTH + MAX_CMD_VALUE_MAX_LENGTH + \ + MAX_CMD_TYPE_LENGTH + MAX_CMD_STRING_LENGTH + MAX_CMD_VALUE_LENGTH + \ + MAX_CMD_RESERVE_LENGTH) + +#define MAX_CMD_BUFFER_LENGTH (CMD_FORMAT_V1_LENGTH * MAX_CMD_ITEM_MAX) + +#if 1 +#define ED_STRING_SITE 0 +#define ED_VALUE_SITE 1 + + +#else +#define ED_ITEMTYPE_SITE 0 +#define ED_STRING_SITE 1 +#define ED_VALUE_SITE 2 +#endif + +#define ACS_AP_RSSI_LEVEL_HIGH -50 +#define ACS_AP_RSSI_LEVEL_LOW -80 +#define ACS_DIRTINESS_LEVEL_HIGH 52 +#define ACS_DIRTINESS_LEVEL_MID 40 +#define ACS_DIRTINESS_LEVEL_LOW 32 + + +enum CMD_VER { + CMD_VER_1, /* Type[2]+String[32]+Value[32] */ + CMD_VER_1_EXT +}; + + +#if 0 +enum ENUM_AIS_REQUEST_TYPE { + AIS_REQUEST_SCAN, + AIS_REQUEST_RECONNECT, + AIS_REQUEST_ROAMING_SEARCH, + AIS_REQUEST_ROAMING_CONNECT, + AIS_REQUEST_REMAIN_ON_CHANNEL, + AIS_REQUEST_NUM +}; +#endif +enum CMD_TYPE { + CMD_TYPE_QUERY, + CMD_TYPE_SET +}; + +enum WLAN_CFG_TPYE { + WLAN_CFG_DEFAULT = 0x00, + WLAN_CFG_REC = 0x01, + WLAN_CFG_EM = 0x02, + WLAN_CFG_NUM +}; + +enum POWER_ACTION_CATEGORY { + SKU_POWER_LIMIT_CTRL = 0x0, + PERCENTAGE_CTRL = 0x1, + PERCENTAGE_DROP_CTRL = 0x2, + BACKOFF_POWER_LIMIT_CTRL = 0x3, + POWER_LIMIT_TABLE_CTRL = 0x4, + RF_TXANT_CTRL = 0x5, + ATEMODE_CTRL = 0x6, + TX_POWER_SHOW_INFO = 0x7, + TPC_FEATURE_CTRL = 0x8, + MU_TX_POWER_CTRL = 0x9, + BF_NDPA_TXD_CTRL = 0xa, + TSSI_WORKAROUND = 0xb, + THERMAL_COMPENSATION_CTRL = 0xc, + TX_RATE_POWER_CTRL = 0xd, + TXPOWER_UP_TABLE_CTRL = 0xe, + TX_POWER_SET_TARGET_POWER = 0xf, + TX_POWER_GET_TARGET_POWER = 0x10, + POWER_ACTION_NUM +}; + +#define ITEM_TYPE_DEC 1 +#define ITEM_TYPE_HEX 2 +#define ITEM_TYPE_STR 3 + +enum CMD_DEFAULT_SETTING_VALUE { + CMD_PNO_ENABLE, + CMD_PNO_SCAN_PERIOD, + CMD_SCN_CHANNEL_PLAN, + CMD_SCN_DWELL_TIME, + CMD_SCN_STOP_SCAN, + CMD_MAX, +}; + +enum CMD_DEFAULT_STR_SETTING_VALUE { + CMD_STR_TEST_STR, + CMD_STR_MAX, +}; + +struct CMD_FORMAT_V1 { + uint8_t itemType; + uint8_t itemStringLength; + uint8_t itemValueLength; + uint8_t Reserved; + uint8_t itemString[MAX_CMD_NAME_MAX_LENGTH]; + uint8_t itemValue[MAX_CMD_VALUE_MAX_LENGTH]; +}; + +struct CMD_HEADER { + enum CMD_VER cmdVersion; + enum CMD_TYPE cmdType; + uint8_t itemNum; + uint16_t cmdBufferLen; + uint8_t buffer[MAX_CMD_BUFFER_LENGTH]; +}; + +struct CFG_DEFAULT_SETTING_TABLE { + uint32_t itemNum; + const char *String; + uint8_t itemType; + uint32_t defaultValue; + uint32_t minValue; + uint32_t maxValue; +}; + +struct CFG_DEFAULT_SETTING_STR_TABLE { + uint32_t itemNum; + const char *String; + uint8_t itemType; + const char *DefString; + uint16_t minLen; + uint16_t maxLen; +}; + +struct CFG_QUERY_FORMAT { + uint32_t Length; + uint32_t Value; + uint32_t Type; + uint32_t *ptr; +}; + +/*Globol Configure define */ +struct CFG_SETTING { + uint8_t PnoEnable; + uint32_t PnoScanPeriod; + uint8_t ScnChannelPlan; + uint16_t ScnDwellTime; + uint8_t ScnStopScan; + uint8_t TestStr[80]; +}; + +#endif + +#if CFG_SUPPORT_NCHO +#define FW_CFG_KEY_NCHO_ENABLE "NCHOEnable" +#define FW_CFG_KEY_NCHO_ROAM_RCPI "RoamingRCPIValue" +#define FW_CFG_KEY_NCHO_SCN_CHANNEL_TIME "NCHOScnChannelTime" +#define FW_CFG_KEY_NCHO_SCN_HOME_TIME "NCHOScnHomeTime" +#define FW_CFG_KEY_NCHO_SCN_HOME_AWAY_TIME "NCHOScnHomeAwayTime" +#define FW_CFG_KEY_NCHO_SCN_NPROBES "NCHOScnNumProbs" +#define FW_CFG_KEY_NCHO_WES_MODE "NCHOWesMode" +#define FW_CFG_KEY_NCHO_SCAN_DFS_MODE "NCHOScnDfsMode" +#define FW_CFG_KEY_NCHO_SCAN_PERIOD "NCHOScnPeriod" +#endif + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +typedef uint32_t(*PFN_OID_HANDLER_FUNC) (IN struct ADAPTER *prAdapter, + IN void *pvBuf, IN uint32_t u4BufLen, + OUT uint32_t *pu4OutInfoLen); + +enum ENUM_CSUM_TYPE { + CSUM_TYPE_IPV4, + CSUM_TYPE_IPV6, + CSUM_TYPE_TCP, + CSUM_TYPE_UDP, + CSUM_TYPE_NUM +}; + +enum ENUM_CSUM_RESULT { + CSUM_RES_NONE, + CSUM_RES_SUCCESS, + CSUM_RES_FAILED, + CSUM_RES_NUM +}; + +enum ENUM_PHY_MODE { + ENUM_PHY_2G4_CCK, + ENUM_PHY_2G4_OFDM_BPSK, + ENUM_PHY_2G4_OFDM_QPSK, + ENUM_PHY_2G4_OFDM_16QAM, + ENUM_PHY_2G4_OFDM_48M, + ENUM_PHY_2G4_OFDM_54M, + ENUM_PHY_2G4_HT20_BPSK, + ENUM_PHY_2G4_HT20_QPSK, + ENUM_PHY_2G4_HT20_16QAM, + ENUM_PHY_2G4_HT20_MCS5, + ENUM_PHY_2G4_HT20_MCS6, + ENUM_PHY_2G4_HT20_MCS7, + ENUM_PHY_2G4_HT40_BPSK, + ENUM_PHY_2G4_HT40_QPSK, + ENUM_PHY_2G4_HT40_16QAM, + ENUM_PHY_2G4_HT40_MCS5, + ENUM_PHY_2G4_HT40_MCS6, + ENUM_PHY_2G4_HT40_MCS7, + ENUM_PHY_5G_OFDM_BPSK, + ENUM_PHY_5G_OFDM_QPSK, + ENUM_PHY_5G_OFDM_16QAM, + ENUM_PHY_5G_OFDM_48M, + ENUM_PHY_5G_OFDM_54M, + ENUM_PHY_5G_HT20_BPSK, + ENUM_PHY_5G_HT20_QPSK, + ENUM_PHY_5G_HT20_16QAM, + ENUM_PHY_5G_HT20_MCS5, + ENUM_PHY_5G_HT20_MCS6, + ENUM_PHY_5G_HT20_MCS7, + ENUM_PHY_5G_HT40_BPSK, + ENUM_PHY_5G_HT40_QPSK, + ENUM_PHY_5G_HT40_16QAM, + ENUM_PHY_5G_HT40_MCS5, + ENUM_PHY_5G_HT40_MCS6, + ENUM_PHY_5G_HT40_MCS7, + ENUM_PHY_MODE_NUM +}; + +enum ENUM_POWER_SAVE_POLL_MODE { + ENUM_POWER_SAVE_POLL_DISABLE, + ENUM_POWER_SAVE_POLL_LEGACY_NULL, + ENUM_POWER_SAVE_POLL_QOS_NULL, + ENUM_POWER_SAVE_POLL_NUM +}; + +enum ENUM_AC_TYPE { + ENUM_AC_TYPE_AC0, + ENUM_AC_TYPE_AC1, + ENUM_AC_TYPE_AC2, + ENUM_AC_TYPE_AC3, + ENUM_AC_TYPE_AC4, + ENUM_AC_TYPE_AC5, + ENUM_AC_TYPE_AC6, + ENUM_AC_TYPE_BMC, + ENUM_AC_TYPE_NUM +}; + +enum ENUM_ADV_AC_TYPE { + ENUM_ADV_AC_TYPE_RX_NSW, + ENUM_ADV_AC_TYPE_RX_PTA, + ENUM_ADV_AC_TYPE_RX_SP, + ENUM_ADV_AC_TYPE_TX_PTA, + ENUM_ADV_AC_TYPE_TX_RSP, + ENUM_ADV_AC_TYPE_NUM +}; + +enum ENUM_REG_CH_MAP { + REG_CH_MAP_COUNTRY_CODE, + REG_CH_MAP_TBL_IDX, + REG_CH_MAP_CUSTOMIZED, + REG_CH_MAP_NUM +}; + +enum ENUM_FEATURE_OPTION { + FEATURE_DISABLED, + FEATURE_ENABLED, + FEATURE_FORCE_ENABLED +}; + +/* This enum is for later added feature options which use command reserved field + * as option switch + */ +enum ENUM_FEATURE_OPTION_IN_CMD { + FEATURE_OPT_CMD_AUTO, + FEATURE_OPT_CMD_DISABLED, + FEATURE_OPT_CMD_ENABLED, + FEATURE_OPT_CMD_FORCE_ENABLED +}; + +#define DEBUG_MSG_SIZE_MAX 1200 +enum { + DEBUG_MSG_ID_UNKNOWN = 0x00, + DEBUG_MSG_ID_PRINT = 0x01, + DEBUG_MSG_ID_FWLOG = 0x02, + DEBUG_MSG_ID_END +}; + +enum { + DEBUG_MSG_TYPE_UNKNOWN = 0x00, + DEBUG_MSG_TYPE_MEM8 = 0x01, + DEBUG_MSG_TYPE_MEM32 = 0x02, + DEBUG_MSG_TYPE_ASCII = 0x03, + DEBUG_MSG_TYPE_BINARY = 0x04, + DEBUG_MSG_TYPE_DRIVER = 0x05, + DEBUG_MSG_TYPE_END +}; + +#define CHIP_CONFIG_RESP_SIZE 320 +enum { + CHIP_CONFIG_TYPE_WO_RESPONSE = 0x00, + CHIP_CONFIG_TYPE_MEM8 = 0x01, + CHIP_CONFIG_TYPE_MEM32 = 0x02, + CHIP_CONFIG_TYPE_ASCII = 0x03, + CHIP_CONFIG_TYPE_BINARY = 0x04, + CHIP_CONFIG_TYPE_DRV_PASSTHROUGH = 0x05, + CHIP_CONFIG_TYPE_END +}; + +struct SET_TXPWR_CTRL { + int8_t c2GLegacyStaPwrOffset; /* Unit: 0.5dBm, default: 0 */ + int8_t c2GHotspotPwrOffset; + int8_t c2GP2pPwrOffset; + int8_t c2GBowPwrOffset; + int8_t c5GLegacyStaPwrOffset; /* Unit: 0.5dBm, default: 0 */ + int8_t c5GHotspotPwrOffset; + int8_t c5GP2pPwrOffset; + int8_t c5GBowPwrOffset; + uint8_t ucConcurrencePolicy; /* TX power policy when concurrence + * in the same channel + * 0: Highest power has priority + * 1: Lowest power has priority + */ + + int8_t acReserved1[3]; /* Must be zero */ + + /* Power limit by channel for all data rates */ + int8_t acTxPwrLimit2G[14]; /* Channel 1~14, Unit: 0.5dBm */ + int8_t acTxPwrLimit5G[4]; /* UNII 1~4 */ + int8_t acReserved2[2]; /* Must be zero */ +}; + +#if CFG_WOW_SUPPORT + +struct WOW_WAKE_HIF { + /* use in-band signal to wakeup system, ENUM_HIF_TYPE */ + uint8_t ucWakeupHif; + + /* GPIO Pin */ + uint8_t ucGpioPin; + + /* refer to PF_WAKEUP_CMD_BIT0_OUTPUT_MODE_EN */ + uint8_t ucTriggerLvl; + + /* non-zero means output reverse wakeup signal after delay time */ + uint32_t u4GpioInterval; + + uint8_t aucResv[5]; +}; + +struct WOW_CTRL { + uint8_t fgWowEnable; /* 0: disable, 1: wow enable */ + uint8_t ucScenarioId; /* just a profile ID */ + uint8_t ucBlockCount; + uint8_t aucReserved1[1]; + struct WOW_WAKE_HIF astWakeHif[2]; + struct WOW_PORT stWowPort; +}; + +#endif + +#if (CFG_SUPPORT_TWT == 1) +enum _TWT_GET_TSF_REASON { + TWT_GET_TSF_FOR_ADD_AGRT_BYPASS = 1, + TWT_GET_TSF_FOR_ADD_AGRT = 2, + TWT_GET_TSF_FOR_RESUME_AGRT = 3, + TWT_GET_TSF_REASON_MAX +}; + +struct _TWT_PARAMS_T { + uint8_t fgReq; + uint8_t fgTrigger; + uint8_t fgProtect; + uint8_t fgUnannounced; + uint8_t ucSetupCmd; + uint8_t ucMinWakeDur; + uint8_t ucWakeIntvalExponent; + uint16_t u2WakeIntvalMantiss; + uint64_t u8TWT; +}; + +struct _NEXT_TWT_INFO_T { + uint64_t u8NextTWT; + uint8_t ucNextTWTSize; +}; + +struct _TWT_CTRL_T { + uint8_t ucBssIdx; + uint8_t ucCtrlAction; + uint8_t ucTWTFlowId; + struct _TWT_PARAMS_T rTWTParams; +}; + +struct _TWT_GET_TSF_CONTEXT_T { + enum _TWT_GET_TSF_REASON ucReason; + uint8_t ucBssIdx; + uint8_t ucTWTFlowId; + uint8_t fgIsOid; + struct _TWT_PARAMS_T rTWTParams; +}; + +#endif + +enum ENUM_NVRAM_MTK_FEATURE { + MTK_FEATURE_2G_256QAM_DISABLED = 0, + MTK_FEATURE_NUM +}; + +/* For storing driver initialization value from glue layer */ +struct REG_INFO { + uint32_t u4SdBlockSize; /* SDIO block size */ + uint32_t u4SdBusWidth; /* SDIO bus width. 1 or 4 */ + uint32_t u4SdClockRate; /* SDIO clock rate. (in unit of HZ) */ + + /* Start Frequency for Ad-Hoc network : in unit of KHz */ + uint32_t u4StartFreq; + + /* Default mode for Ad-Hoc network : ENUM_PARAM_AD_HOC_MODE_T */ + uint32_t u4AdhocMode; + + uint32_t u4RddStartFreq; + uint32_t u4RddStopFreq; + uint32_t u4RddTestMode; + uint32_t u4RddShutFreq; + uint32_t u4RddDfs; + int32_t i4HighRssiThreshold; + int32_t i4MediumRssiThreshold; + int32_t i4LowRssiThreshold; + int32_t au4TxPriorityTag[ENUM_AC_TYPE_NUM]; + int32_t au4RxPriorityTag[ENUM_AC_TYPE_NUM]; + int32_t au4AdvPriorityTag[ENUM_ADV_AC_TYPE_NUM]; + uint32_t u4FastPSPoll; + uint32_t u4PTA; /* 0: disable, 1: enable */ + uint32_t u4TXLimit; /* 0: disable, 1: enable */ + uint32_t u4SilenceWindow; /* range: 100 - 625, unit: us */ + uint32_t u4TXLimitThreshold; /* range: 250 - 1250, unit: us */ + uint32_t u4PowerMode; + uint32_t fgEnArpFilter; + uint32_t u4PsCurrentMeasureEn; + uint32_t u4UapsdAcBmp; + uint32_t u4MaxSpLen; + + /* 0: enable online scan, non-zero: disable online scan */ + uint32_t fgDisOnlineScan; + + /* 0: enable online scan, non-zero: disable online scan */ + uint32_t fgDisBcnLostDetection; + + /* 0: automatic, non-zero: fixed rate */ + uint32_t u4FixedRate; + + uint32_t u4ArSysParam0; + uint32_t u4ArSysParam1; + uint32_t u4ArSysParam2; + uint32_t u4ArSysParam3; + + /* 0:enable roaming 1:disable */ + uint32_t fgDisRoaming; + + /* NVRAM - MP Data -START- */ +#if 1 + uint16_t u2Part1OwnVersion; + uint16_t u2Part1PeerVersion; +#endif + uint8_t aucMacAddr[6]; + /* Country code (in ISO 3166-1 expression, ex: "US", "TW") */ + uint16_t au2CountryCode[4]; + uint8_t ucSupport5GBand; + + enum ENUM_REG_CH_MAP eRegChannelListMap; + uint8_t ucRegChannelListIndex; + struct DOMAIN_INFO_ENTRY rDomainInfo; + struct RSSI_PATH_COMPASATION rRssiPathCompasation; + uint8_t ucRssiPathCompasationUsed; + /* NVRAM - MP Data -END- */ + + /* NVRAM - Functional Data -START- */ + uint8_t ucEnable5GBand; + /* NVRAM - Functional Data -END- */ + + struct NEW_EFUSE_MAPPING2NVRAM *prOldEfuseMapping; + + uint8_t aucNvram[512]; + struct WIFI_CFG_PARAM_STRUCT *prNvramSettings; +}; + +/* for divided firmware loading */ +struct FWDL_SECTION_INFO { +#if 0 + uint32_t u4Offset; + uint32_t u4Reserved; + uint32_t u4Length; + uint32_t u4DestAddr; +#endif + uint32_t u4DestAddr; + uint8_t ucChipInfo; + uint8_t ucFeatureSet; + uint8_t ucEcoCode; + uint8_t aucReserved[9]; + uint8_t aucBuildDate[16]; + uint32_t u4Length; +}; + +struct FIRMWARE_DIVIDED_DOWNLOAD { +#if 0 + uint32_t u4Signature; + + /* CRC calculated without first 8 bytes included */ + uint32_t u4CRC; + + uint32_t u4NumOfEntries; + uint32_t u4Reserved; + struct FWDL_SECTION_INFO arSection[]; +#endif + struct FWDL_SECTION_INFO arSection[2]; +}; + +struct PARAM_MCR_RW_STRUCT { + uint32_t u4McrOffset; + uint32_t u4McrData; +}; + +/* per access category statistics */ +struct WIFI_WMM_AC_STAT { + uint32_t u4TxMsdu; + uint32_t u4RxMsdu; + uint32_t u4TxDropMsdu; + uint32_t u4TxFailMsdu; + uint32_t u4TxRetryMsdu; +}; + +struct TX_VECTOR_BBP_LATCH { + uint32_t u4TxV[3]; +}; + +struct MIB_INFO_STAT { + uint32_t u4RxMpduCnt; + uint32_t u4FcsError; + uint32_t u4RxFifoFull; + uint32_t u4AmpduTxSfCnt; + uint32_t u4AmpduTxAckSfCnt; + uint16_t au2TxRangeAmpduCnt[AGG_RANGE_SEL_NUM + 1]; +}; + +struct PARAM_GET_STA_STATISTICS { + /* Per-STA statistic */ + uint8_t ucInvalid; + uint8_t ucVersion; + uint8_t aucMacAddr[MAC_ADDR_LEN]; + + uint32_t u4LinkScore; + uint32_t u4Flag; + + uint8_t ucReadClear; + uint8_t ucLlsReadClear; + + /* From driver */ + uint32_t u4TxTotalCount; + uint32_t u4TxExceedThresholdCount; + + uint32_t u4TxMaxTime; + uint32_t u4TxAverageProcessTime; + + uint32_t u4TxMaxHifTime; + uint32_t u4TxAverageHifTime; + + uint32_t u4RxTotalCount; + + /* + * How many packages Enqueue/Deqeue during statistics interval + */ + uint32_t u4EnqueueCounter; + uint32_t u4DequeueCounter; + + uint32_t u4EnqueueStaCounter; + uint32_t u4DequeueStaCounter; + + uint32_t IsrCnt; + uint32_t IsrPassCnt; + uint32_t TaskIsrCnt; + + uint32_t IsrAbnormalCnt; + uint32_t IsrSoftWareCnt; + uint32_t IsrRxCnt; + uint32_t IsrTxCnt; + + uint32_t au4TcResourceEmptyCount[NUM_TC_RESOURCE_TO_STATISTICS]; + uint32_t au4DequeueNoTcResource[NUM_TC_RESOURCE_TO_STATISTICS]; + uint32_t au4TcResourceBackCount[NUM_TC_RESOURCE_TO_STATISTICS]; + uint32_t au4TcResourceUsedPageCount[NUM_TC_RESOURCE_TO_STATISTICS]; + uint32_t au4TcResourceWantedPageCount[NUM_TC_RESOURCE_TO_STATISTICS]; + + uint32_t au4TcQueLen[NUM_TC_RESOURCE_TO_STATISTICS]; + + /* From FW */ + uint8_t ucPer; /* base: 128 */ + uint8_t ucRcpi; + uint32_t u4PhyMode; + uint16_t u2LinkSpeed; /* unit is 0.5 Mbits */ + + uint32_t u4TxFailCount; + uint32_t u4TxLifeTimeoutCount; + + uint32_t u4TxAverageAirTime; + + /* Transmit in the air (wtbl) */ + uint32_t u4TransmitCount; + + /* Transmit without ack/ba in the air (wtbl) */ + uint32_t u4TransmitFailCount; + + /*link layer statistics */ + struct WIFI_WMM_AC_STAT arLinkStatistics[AC_NUM]; + + /* Global queue management statistic */ + uint32_t au4TcAverageQueLen[NUM_TC_RESOURCE_TO_STATISTICS]; + uint32_t au4TcCurrentQueLen[NUM_TC_RESOURCE_TO_STATISTICS]; + + uint8_t ucTemperature; + uint8_t ucSkipAr; + uint8_t ucArTableIdx; + uint8_t ucRateEntryIdx; + uint8_t ucRateEntryIdxPrev; + uint8_t ucTxSgiDetectPassCnt; + uint8_t ucAvePer; +#if (CFG_SUPPORT_RA_GEN == 0) + uint8_t aucArRatePer[AR_RATE_TABLE_ENTRY_MAX]; + uint8_t aucRateEntryIndex[AUTO_RATE_NUM]; +#else + uint32_t u4AggRangeCtrl_0; + uint32_t u4AggRangeCtrl_1; + uint8_t ucRangeType; +#if (CFG_SUPPORT_CONNAC2X == 0) + uint8_t aucReserved5[24]; +#else + uint32_t u4AggRangeCtrl_2; + uint32_t u4AggRangeCtrl_3; + uint8_t aucReserved5[16]; +#endif +#endif + uint8_t ucArStateCurr; + uint8_t ucArStatePrev; + uint8_t ucArActionType; + uint8_t ucHighestRateCnt; + uint8_t ucLowestRateCnt; + uint16_t u2TrainUp; + uint16_t u2TrainDown; + uint32_t u4Rate1TxCnt; + uint32_t u4Rate1FailCnt; + struct TX_VECTOR_BBP_LATCH rTxVector[ENUM_BAND_NUM]; + struct MIB_INFO_STAT rMibInfo[ENUM_BAND_NUM]; + uint8_t ucResetCounter; + u_int8_t fgIsForceTxStream; + u_int8_t fgIsForceSeOff; +#if (CFG_SUPPORT_RA_GEN == 0) + uint8_t aucReserved6[17]; +#else + uint16_t u2RaRunningCnt; + uint8_t ucRaStatus; + uint8_t ucFlag; + uint8_t aucTxQuality[MAX_TX_QUALITY_INDEX]; + uint8_t ucTxRateUpPenalty; + uint8_t ucLowTrafficMode; + uint8_t ucLowTrafficCount; + uint8_t ucLowTrafficDashBoard; + uint8_t ucDynamicSGIState; + uint8_t ucDynamicSGIScore; + uint8_t ucDynamicBWState; + uint8_t ucDynamicGband256QAMState; + uint8_t ucVhtNonSpRateState; +#endif + /* Reserved fields */ + uint8_t au4Reserved[3]; +}; + +struct PARAM_GET_BSS_STATISTICS { + /* Per-STA statistic */ + uint8_t aucMacAddr[MAC_ADDR_LEN]; + + uint32_t u4Flag; + + uint8_t ucReadClear; + + uint8_t ucLlsReadClear; + + uint8_t ucBssIndex; + + /* From driver */ + uint32_t u4TxTotalCount; + uint32_t u4TxExceedThresholdCount; + + uint32_t u4TxMaxTime; + uint32_t u4TxAverageProcessTime; + + uint32_t u4RxTotalCount; + + uint32_t au4TcResourceEmptyCount[NUM_TC_RESOURCE_TO_STATISTICS]; + uint32_t au4TcQueLen[NUM_TC_RESOURCE_TO_STATISTICS]; + + /* From FW */ + uint8_t ucPer; /* base: 128 */ + uint8_t ucRcpi; + uint32_t u4PhyMode; + uint16_t u2LinkSpeed; /* unit is 0.5 Mbits */ + + uint32_t u4TxFailCount; + uint32_t u4TxLifeTimeoutCount; + + uint32_t u4TxAverageAirTime; + + /* Transmit in the air (wtbl) */ + uint32_t u4TransmitCount; + + /* Transmit without ack/ba in the air (wtbl) */ + uint32_t u4TransmitFailCount; + + /*link layer statistics */ + struct WIFI_WMM_AC_STAT arLinkStatistics[AC_NUM]; + + /* Global queue management statistic */ + uint32_t au4TcAverageQueLen[NUM_TC_RESOURCE_TO_STATISTICS]; + uint32_t au4TcCurrentQueLen[NUM_TC_RESOURCE_TO_STATISTICS]; + + /* Reserved fields */ + uint8_t au4Reserved[32]; /* insufficient for LLS?? */ +}; + +struct PARAM_GET_DRV_STATISTICS { + int32_t i4TxPendingFrameNum; + int32_t i4TxPendingSecurityFrameNum; + int32_t i4TxPendingCmdNum; + + /* sync i4PendingFwdFrameCount in _TX_CTRL_T */ + int32_t i4PendingFwdFrameCount; + + /* sync pad->rTxCtrl.rFreeMsduInfoList.u4NumElem */ + uint32_t u4MsduNumElem; + + /* sync pad->rTxCtrl.rTxMgmtTxingQueue.u4NumElem */ + uint32_t u4TxMgmtTxringQueueNumElem; + + /* sync pad->prRxCtrl.rFreeSwRfbList.u4NumElem */ + uint32_t u4RxFreeSwRfbMsduNumElem; + + /* sync pad->prRxCtrl.rReceivedRfbList.u4NumElem */ + uint32_t u4RxReceivedRfbNumElem; + + /* sync pad->prRxCtrl.rIndicatedRfbList.u4NumElem */ + uint32_t u4RxIndicatedNumElem; +}; + +struct NET_INTERFACE_INFO { + uint8_t ucBssIndex; + void *pvNetInterface; +}; + +enum ENUM_TX_RESULT_CODE { + TX_RESULT_SUCCESS = 0, + TX_RESULT_LIFE_TIMEOUT, + TX_RESULT_RTS_ERROR, + TX_RESULT_MPDU_ERROR, + TX_RESULT_AGING_TIMEOUT, + TX_RESULT_FLUSHED, + TX_RESULT_BIP_ERROR, + TX_RESULT_UNSPECIFIED_ERROR, + TX_RESULT_DROPPED_IN_DRIVER = 32, + TX_RESULT_DROPPED_IN_FW, + TX_RESULT_QUEUE_CLEARANCE, + TX_RESULT_INACTIVE_BSS, + TX_RESULT_NUM +}; + +/* enum of BEACON_TIMEOUT_REASON */ +enum _ENUM_PM_BEACON_TIME_OUT_REACON_CODE_T { + BEACON_TIMEOUT_DUE_2_HW_BEACON_LOST_NONADHOC, + BEACON_TIMEOUT_DUE_2_HW_BEACON_LOST_ADHOC, + BEACON_TIMEOUT_DUE_2_HW_TSF_DRIFT, + BEACON_TIMEOUT_DUE_2_NULL_FRAME_THRESHOLD, + BEACON_TIMEOUT_DUE_2_AGING_THRESHOLD, + BEACON_TIMEOUT_DUE_2_BSSID_BEACON_PEIROD_NOT_ILLIGAL, + BEACON_TIMEOUT_DUE_2_CONNECTION_FAIL, + BEACON_TIMEOUT_DUE_2_ALLOCAT_NULL_PKT_FAIL_THRESHOLD, + BEACON_TIMEOUT_DUE_2_NO_TX_DONE_EVENT, + BEACON_TIMEOUT_DUE_2_UNSPECIF_REASON, + BEACON_TIMEOUT_DUE_2_SET_CHIP, + BEACON_TIMEOUT_DUE_2_KEEP_SCAN_AP_MISS_CHECK_FAIL, + BEACON_TIMEOUT_DUE_2_KEEP_UNCHANGED_LOW_RSSI_CHECK_FAIL, + BEACON_TIMEOUT_DUE_2_NULL_FRAME_LIFE_TIMEOUT, + BEACON_TIMEOUT_DUE_2_APR_NO_RESPONSE, + BEACON_TIMEOUT_DUE_2_NUM +}; + +struct WLAN_CFG_ENTRY { + uint8_t aucKey[WLAN_CFG_KEY_LEN_MAX]; + uint8_t aucValue[WLAN_CFG_VALUE_LEN_MAX]; + WLAN_CFG_SET_CB pfSetCb; + void *pPrivate; + uint32_t u4Flags; +}; + +struct WLAN_CFG { + uint32_t u4WlanCfgEntryNumMax; + uint32_t u4WlanCfgKeyLenMax; + uint32_t u4WlanCfgValueLenMax; + struct WLAN_CFG_ENTRY arWlanCfgBuf[WLAN_CFG_ENTRY_NUM_MAX]; +}; + +struct WLAN_CFG_REC { + uint32_t u4WlanCfgEntryNumMax; + uint32_t u4WlanCfgKeyLenMax; + uint32_t u4WlanCfgValueLenMax; + struct WLAN_CFG_ENTRY arWlanCfgBuf[WLAN_CFG_REC_ENTRY_NUM_MAX]; +}; + +enum ENUM_MAX_BANDWIDTH_SETTING { + MAX_BW_20MHZ = 0, + MAX_BW_40MHZ, + MAX_BW_80MHZ, + MAX_BW_160MHZ, + MAX_BW_80_80_MHZ, + MAX_BW_UNKNOWN +}; + +struct TX_PACKET_INFO { + uint8_t ucPriorityParam; + uint32_t u4PacketLen; + uint8_t aucEthDestAddr[MAC_ADDR_LEN]; + uint16_t u2Flag; + +#if 0 + u_int8_t fgIs1X; + u_int8_t fgIsPAL; + u_int8_t fgIs802_3; + u_int8_t fgIsVlanExists; + u_int8_t fgIsDhcp; + u_int8_t fgIsArp; +#endif +}; + +enum ENUM_TX_PROFILING_TAG { + TX_PROF_TAG_OS_TO_DRV = 0, + TX_PROF_TAG_DRV_ENQUE, + TX_PROF_TAG_DRV_DEQUE, + TX_PROF_TAG_DRV_TX_DONE, + TX_PROF_TAG_DRV_FREE +}; + +#if (CFG_SUPPORT_SPE_IDX_CONTROL == 1) +enum ENUM_WF_PATH_FAVOR_T { + ENUM_WF_NON_FAVOR = 0xff, + ENUM_WF_0_ONE_STREAM_PATH_FAVOR = 0, + ENUM_WF_1_ONE_STREAM_PATH_FAVOR = 1, + ENUM_WF_0_1_TWO_STREAM_PATH_FAVOR = 2, + ENUM_WF_0_1_DUP_STREAM_PATH_FAVOR = 3, +}; + +enum ENUM_SPE_SEL_BY_T { + ENUM_SPE_SEL_BY_TXD = 0, + ENUM_SPE_SEL_BY_WTBL = 1, +}; +#endif + +struct PARAM_GET_CNM_T { + uint8_t fgIsDbdcEnable; + + uint8_t ucOpChNum[ENUM_BAND_NUM]; + uint8_t ucChList[ENUM_BAND_NUM][MAX_OP_CHNL_NUM]; + uint8_t ucChBw[ENUM_BAND_NUM][MAX_OP_CHNL_NUM]; + uint8_t ucChSco[ENUM_BAND_NUM][MAX_OP_CHNL_NUM]; + uint8_t ucChNetNum[ENUM_BAND_NUM][MAX_OP_CHNL_NUM]; + uint8_t ucChBssList[ENUM_BAND_NUM][MAX_OP_CHNL_NUM][BSSID_NUM]; + + uint8_t ucBssInuse[BSSID_NUM + 1]; + uint8_t ucBssActive[BSSID_NUM + 1]; + uint8_t ucBssConnectState[BSSID_NUM + 1]; + + uint8_t ucBssCh[BSSID_NUM + 1]; + uint8_t ucBssDBDCBand[BSSID_NUM + 1]; + uint8_t ucBssWmmSet[BSSID_NUM + 1]; + uint8_t ucBssWmmDBDCBand[BSSID_NUM + 1]; + uint8_t ucBssOMACSet[BSSID_NUM + 1]; + uint8_t ucBssOMACDBDCBand[BSSID_NUM + 1]; + + /* Reserved fields */ + uint8_t au4Reserved[65]; /*Total 160 byte*/ +}; + +#ifdef CFG_SUPPORT_LINK_QUALITY_MONITOR +struct WIFI_LINK_QUALITY_INFO { + uint32_t u4CurTxRate; /* current tx link speed */ + uint64_t u8TxTotalCount; /* tx total accumulated count */ + uint64_t u8TxRetryCount; /* tx retry count */ + uint64_t u8TxFailCount; /* tx fail count */ + uint64_t u8TxRtsFailCount; /* tx RTS fail count */ + uint64_t u8TxAckFailCount; /* tx ACK fail count */ + + uint32_t u4CurRxRate; /* current rx link speed */ + uint64_t u8RxTotalCount; /* rx total packages */ + uint32_t u4RxDupCount; /* rx duplicate package count */ + uint64_t u8RxErrCount; /* rx fcs fail count */ + + uint32_t u4CurTxPer; /* current Tx PER */ + uint64_t u8MdrdyCount; + uint64_t u8IdleSlotCount; /* congestion stats: idle slot */ + uint64_t u8DiffIdleSlotCount; + uint32_t u4HwMacAwakeDuration; + uint16_t u2FlagScanning; + + uint32_t u4PhyMode; + uint16_t u2LinkSpeed; + + uint64_t u8LastTxTotalCount; + uint64_t u8LastTxFailCount; + uint64_t u8LastIdleSlotCount; +}; +#endif /* CFG_SUPPORT_LINK_QUALITY_MONITOR */ + +#if CFG_SUPPORT_IOT_AP_BLACKLIST +enum ENUM_WLAN_IOT_AP_FLAG_T { + WLAN_IOT_AP_FG_VERSION = 0, + WLAN_IOT_AP_FG_OUI, + WLAN_IOT_AP_FG_DATA, + WLAN_IOT_AP_FG_DATA_MASK, + WLAN_IOT_AP_FG_BSSID, + WLAN_IOT_AP_FG_BSSID_MASK, + WLAN_IOT_AP_FG_NSS, + WLAN_IOT_AP_FG_HT, + WLAN_IOT_AP_FG_BAND, + WLAN_IOT_AP_FG_ACTION, + WLAN_IOT_AP_FG_MAX +}; + +enum ENUM_WLAN_IOT_AP_HANDLE_ACTION { + WLAN_IOT_AP_VOID = 0, + WLAN_IOT_AP_DBDC_1SS, + WLAN_IOT_AP_DIS_SG, + WLAN_IOT_AP_COEX_CTS2SELF, + WLAN_IOT_AP_FIX_MODE, + WLAN_IOT_AP_DIS_2GHT40, + WLAN_IOT_AP_KEEP_EDCA_PARAM = 6, + WLAN_IOT_AP_ACT_MAX +}; + +struct WLAN_IOT_AP_RULE_T { + uint16_t u2MatchFlag; + uint8_t ucDataLen; + uint8_t ucDataMaskLen; + uint8_t ucVersion; + uint8_t aVendorOui[MAC_OUI_LEN]; + uint8_t aVendorData[CFG_IOT_AP_DATA_MAX_LEN]; + uint8_t aVendorDataMask[CFG_IOT_AP_DATA_MAX_LEN]; + uint8_t aBssid[MAC_ADDR_LEN]; + uint8_t aBssidMask[MAC_ADDR_LEN]; + uint8_t ucNss; + uint8_t ucHtType; + uint8_t ucBand; + uint8_t ucAction; +}; +#endif +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ +#define BUILD_SIGN(ch0, ch1, ch2, ch3) \ + ((uint32_t)(uint8_t)(ch0) | ((uint32_t)(uint8_t)(ch1) << 8) | \ + ((uint32_t)(uint8_t)(ch2) << 16) | ((uint32_t)(uint8_t)(ch3) << 24)) + +#define MTK_WIFI_SIGNATURE BUILD_SIGN('M', 'T', 'K', 'W') + +#define IS_FEATURE_ENABLED(_ucFeature) \ + (((_ucFeature) == FEATURE_ENABLED) || \ + ((_ucFeature) == FEATURE_FORCE_ENABLED)) +#define IS_FEATURE_FORCE_ENABLED(_ucFeature) \ + ((_ucFeature) == FEATURE_FORCE_ENABLED) +#define IS_FEATURE_DISABLED(_ucFeature) ((_ucFeature) == FEATURE_DISABLED) + +/* This macro is for later added feature options which use command reserved + * field as option switch + */ +/* 0: AUTO + * 1: Disabled + * 2: Enabled + * 3: Force disabled + */ +#define FEATURE_OPT_IN_COMMAND(_ucFeature) ((_ucFeature) + 1) + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +struct ADAPTER *wlanAdapterCreate(IN struct GLUE_INFO *prGlueInfo); + +void wlanAdapterDestroy(IN struct ADAPTER *prAdapter); + +void wlanCardEjected(IN struct ADAPTER *prAdapter); + +void wlanIST(IN struct ADAPTER *prAdapter, bool fgEnInt); + +u_int8_t wlanISR(IN struct ADAPTER *prAdapter, IN u_int8_t fgGlobalIntrCtrl); + +uint32_t wlanProcessCommandQueue(IN struct ADAPTER *prAdapter, + IN struct QUE *prCmdQue); + +uint32_t wlanSendCommand(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo); + +#if CFG_SUPPORT_MULTITHREAD +uint32_t wlanSendCommandMthread(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo); + +uint32_t wlanTxCmdMthread(IN struct ADAPTER *prAdapter); + +uint32_t wlanTxCmdDoneMthread(IN struct ADAPTER *prAdapter); + +void wlanClearTxCommandQueue(IN struct ADAPTER *prAdapter); + +void wlanClearTxCommandDoneQueue(IN struct ADAPTER *prAdapter); + +void wlanClearDataQueue(IN struct ADAPTER *prAdapter); + +void wlanClearRxToOsQueue(IN struct ADAPTER *prAdapter); +#endif + +void wlanClearPendingCommandQueue(IN struct ADAPTER *prAdapter); + +void wlanReleaseCommand(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, + IN enum ENUM_TX_RESULT_CODE rTxDoneStatus); + +void wlanReleasePendingOid(IN struct ADAPTER *prAdapter, + IN unsigned long ulParamPtr); + +void wlanReleasePendingCMDbyBssIdx(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +void wlanReturnPacketDelaySetupTimeout(IN struct ADAPTER *prAdapter, + IN unsigned long ulParamPtr); + +void wlanReturnPacket(IN struct ADAPTER *prAdapter, IN void *pvPacket); + +uint32_t +wlanQueryInformation(IN struct ADAPTER *prAdapter, + IN PFN_OID_HANDLER_FUNC pfOidQryHandler, + IN void *pvInfoBuf, IN uint32_t u4InfoBufLen, + OUT uint32_t *pu4QryInfoLen); + +uint32_t +wlanSetInformation(IN struct ADAPTER *prAdapter, + IN PFN_OID_HANDLER_FUNC pfOidSetHandler, + IN void *pvInfoBuf, IN uint32_t u4InfoBufLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t wlanAdapterStart(IN struct ADAPTER *prAdapter, + IN struct REG_INFO *prRegInfo, + IN const u_int8_t bAtResetFlow); + +uint32_t wlanAdapterStop(IN struct ADAPTER *prAdapter, + IN const u_int8_t bAtResetFlow); + +void wlanCheckAsicCap(IN struct ADAPTER *prAdapter); + +uint32_t wlanCheckWifiFunc(IN struct ADAPTER *prAdapter, + IN u_int8_t fgRdyChk); + +void wlanReturnRxPacket(IN void *pvAdapter, IN void *pvPacket); + +void wlanRxSetBroadcast(IN struct ADAPTER *prAdapter, + IN u_int8_t fgEnableBroadcast); + +u_int8_t wlanIsHandlerNeedHwAccess(IN PFN_OID_HANDLER_FUNC pfnOidHandler, + IN u_int8_t fgSetInfo); + +void wlanSetPromiscuousMode(IN struct ADAPTER *prAdapter, + IN u_int8_t fgEnablePromiscuousMode); + +uint32_t wlanSendDummyCmd(IN struct ADAPTER *prAdapter, + IN u_int8_t fgIsReqTxRsrc); + +uint32_t wlanSendNicPowerCtrlCmd(IN struct ADAPTER *prAdapter, + IN uint8_t ucPowerMode); + +u_int8_t wlanIsHandlerAllowedInRFTest(IN PFN_OID_HANDLER_FUNC pfnOidHandler, + IN u_int8_t fgSetInfo); + +uint32_t wlanProcessQueuedSwRfb(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfbListHead); + +uint32_t wlanProcessQueuedMsduInfo(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfoListHead); + +u_int8_t wlanoidTimeoutCheck(IN struct ADAPTER *prAdapter, + IN PFN_OID_HANDLER_FUNC pfnOidHandler); + +void wlanoidClearTimeoutCheck(IN struct ADAPTER *prAdapter); + +uint32_t wlanUpdateNetworkAddress(IN struct ADAPTER *prAdapter); + +uint32_t wlanUpdateBasicConfig(IN struct ADAPTER *prAdapter); + +u_int8_t wlanQueryTestMode(IN struct ADAPTER *prAdapter); + +u_int8_t wlanProcessTxFrame(IN struct ADAPTER *prAdapter, + IN void *prPacket); + +/* Security Frame Handling */ +u_int8_t wlanProcessSecurityFrame(IN struct ADAPTER *prAdapter, + IN void *prPacket); + +uint32_t wlanProcessCmdDataFrame(IN struct ADAPTER + *prAdapter, IN void *prPacket); + +void wlanSecurityFrameTxDone(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, + IN uint8_t *pucEventBuf); + +void wlanSecurityAndCmdDataFrameTxTimeout(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo); + +void wlanCmdDataFrameTxDone(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, + IN uint8_t *pucEventBuf); + + +/*----------------------------------------------------------------------------*/ +/* OID/IOCTL Handling */ +/*----------------------------------------------------------------------------*/ +void wlanClearScanningResult(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +void wlanClearBssInScanningResult(IN struct ADAPTER *prAdapter, + IN uint8_t *arBSSID); + +#if CFG_TEST_WIFI_DIRECT_GO +void wlanEnableP2pFunction(IN struct ADAPTER *prAdapter); + +void wlanEnableATGO(IN struct ADAPTER *prAdapter); +#endif + +/*----------------------------------------------------------------------------*/ +/* NIC Capability Retrieve by Polling */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanQueryNicCapability(IN struct ADAPTER *prAdapter); + +/*----------------------------------------------------------------------------*/ +/* PD MCR Retrieve by Polling */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanQueryPdMcr(IN struct ADAPTER *prAdapter, + IN struct PARAM_MCR_RW_STRUCT *prMcrRdInfo); + +/*----------------------------------------------------------------------------*/ +/* Get minimal tx power setting from NVRAM */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanGetMiniTxPower(IN struct ADAPTER *prAdapter, + IN enum ENUM_BAND eBand, + IN enum ENUM_PHY_MODE_TYPE ePhyMode, + OUT int8_t *pTxPwr); +/*----------------------------------------------------------------------------*/ +/* Loading Manufacture Data */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanLoadManufactureData(IN struct ADAPTER *prAdapter, + IN struct REG_INFO *prRegInfo); + +/*----------------------------------------------------------------------------*/ +/* Media Stream Mode */ +/*----------------------------------------------------------------------------*/ +u_int8_t wlanResetMediaStreamMode(IN struct ADAPTER *prAdapter); + +/*----------------------------------------------------------------------------*/ +/* Timer Timeout Check (for Glue Layer) */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanTimerTimeoutCheck(IN struct ADAPTER *prAdapter); + +/*----------------------------------------------------------------------------*/ +/* Mailbox Message Check (for Glue Layer) */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanProcessMboxMessage(IN struct ADAPTER *prAdapter); + +/*----------------------------------------------------------------------------*/ +/* TX Pending Packets Handling (for Glue Layer) */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanEnqueueTxPacket(IN struct ADAPTER *prAdapter, + IN void *prNativePacket); + +uint32_t wlanFlushTxPendingPackets(IN struct ADAPTER *prAdapter); + +uint32_t wlanTxPendingPackets(IN struct ADAPTER *prAdapter, + IN OUT u_int8_t *pfgHwAccess); + +/*----------------------------------------------------------------------------*/ +/* Low Power Acquire/Release (for Glue Layer) */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanAcquirePowerControl(IN struct ADAPTER *prAdapter); + +uint32_t wlanReleasePowerControl(IN struct ADAPTER *prAdapter); + +/*----------------------------------------------------------------------------*/ +/* Pending Packets Number Reporting (for Glue Layer) */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanGetTxPendingFrameCount(IN struct ADAPTER *prAdapter); + +/*----------------------------------------------------------------------------*/ +/* ACPI state inquiry (for Glue Layer) */ +/*----------------------------------------------------------------------------*/ +enum ENUM_ACPI_STATE wlanGetAcpiState(IN struct ADAPTER *prAdapter); + +void wlanSetAcpiState(IN struct ADAPTER *prAdapter, + IN enum ENUM_ACPI_STATE ePowerState); + + +/*----------------------------------------------------------------------------*/ +/* get ECO version from Revision ID register (for Win32) */ +/*----------------------------------------------------------------------------*/ +uint8_t wlanGetEcoVersion(IN struct ADAPTER *prAdapter); + +/*----------------------------------------------------------------------------*/ +/* set preferred band configuration corresponding to network type */ +/*----------------------------------------------------------------------------*/ +void wlanSetPreferBandByNetwork(IN struct ADAPTER *prAdapter, + IN enum ENUM_BAND eBand, IN uint8_t ucBssIndex); + +/*----------------------------------------------------------------------------*/ +/* get currently operating channel information */ +/*----------------------------------------------------------------------------*/ +uint8_t wlanGetChannelNumberByNetwork(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +/*----------------------------------------------------------------------------*/ +/* check for system configuration to generate message on scan list */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanCheckSystemConfiguration(IN struct ADAPTER *prAdapter); + +/*----------------------------------------------------------------------------*/ +/* query bss statistics information from driver and firmware */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryBssStatistics(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +/*----------------------------------------------------------------------------*/ +/* dump per-BSS statistics */ +/*----------------------------------------------------------------------------*/ +void wlanDumpBssStatistics(IN struct ADAPTER *prAdapter, uint8_t ucBssIndex); + +/*----------------------------------------------------------------------------*/ +/* query sta statistics information from driver and firmware */ +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidQueryStaStatistics(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanQueryStaStatistics(IN struct ADAPTER *prAdapter, IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen, + u_int8_t fgIsOid); + +uint32_t +wlanQueryStatistics(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen, IN uint8_t fgIsOid); + +/*----------------------------------------------------------------------------*/ +/* query NIC resource information from chip and reset Tx resource for normal */ +/* operation */ +/*----------------------------------------------------------------------------*/ +void wlanQueryNicResourceInformation(IN struct ADAPTER *prAdapter); + +uint32_t wlanQueryNicCapabilityV2(IN struct ADAPTER *prAdapter); + +void wlanUpdateNicResourceInformation(IN struct ADAPTER *prAdapter); + +/*----------------------------------------------------------------------------*/ +/* GET/SET BSS index mapping for network interfaces */ +/*----------------------------------------------------------------------------*/ +void wlanBindNetInterface(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucNetInterfaceIndex, + IN void *pvNetInterface); + +void wlanBindBssIdxToNetInterface(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucBssIndex, + IN void *pvNetInterface); + +uint8_t wlanGetBssIdxByNetInterface(IN struct GLUE_INFO *prGlueInfo, + IN void *pvNetInterface); + +void *wlanGetNetInterfaceByBssIdx(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucBssIndex); + +/* for windows as windows glue cannot see through P_ADAPTER_T */ + +void wlanInitFeatureOption(IN struct ADAPTER *prAdapter); + +void wlanCfgSetSwCtrl(IN struct ADAPTER *prAdapter); + +void wlanCfgSetChip(IN struct ADAPTER *prAdapter); + +#if (CFG_SUPPORT_CONNINFRA == 1) +void wlanCfgSetChipSyncTime(IN struct ADAPTER *prAdapter); +#endif + +void wlanCfgSetDebugLevel(IN struct ADAPTER *prAdapter); + +void wlanCfgSetCountryCode(IN struct ADAPTER *prAdapter); + +struct WLAN_CFG_ENTRY *wlanCfgGetEntry(IN struct ADAPTER *prAdapter, + const int8_t *pucKey, + uint32_t u4Flags); + +uint32_t +wlanCfgGet(IN struct ADAPTER *prAdapter, const int8_t *pucKey, int8_t *pucValue, + int8_t *pucValueDef, uint32_t u4Flags); + +uint32_t wlanCfgGetUint32(IN struct ADAPTER *prAdapter, const int8_t *pucKey, + uint32_t u4ValueDef); + +int32_t wlanCfgGetInt32(IN struct ADAPTER *prAdapter, const int8_t *pucKey, + int32_t i4ValueDef); + +uint32_t wlanCfgSetUint32(IN struct ADAPTER *prAdapter, const int8_t *pucKey, + uint32_t u4Value); + +uint32_t wlanCfgSet(IN struct ADAPTER *prAdapter, const int8_t *pucKey, + int8_t *pucValue, uint32_t u4Flags); + +uint32_t wlanCfgSetCb(IN struct ADAPTER *prAdapter, const int8_t *pucKey, + WLAN_CFG_SET_CB pfSetCb, void *pPrivate, + uint32_t u4Flags); + +#if CFG_SUPPORT_EASY_DEBUG + +uint32_t wlanCfgParse(IN struct ADAPTER *prAdapter, uint8_t *pucConfigBuf, + uint32_t u4ConfigBufLen, u_int8_t isFwConfig); +void wlanFeatureToFw(IN struct ADAPTER *prAdapter, uint32_t u4Flag); +#endif + +void wlanLoadDefaultCustomerSetting(IN struct ADAPTER *prAdapter); + +uint32_t wlanCfgInit(IN struct ADAPTER *prAdapter, uint8_t *pucConfigBuf, + uint32_t u4ConfigBufLen, uint32_t u4Flags); + +uint32_t wlanCfgParseArgument(int8_t *cmdLine, int32_t *argc, int8_t *argv[]); + +#if CFG_WOW_SUPPORT +uint32_t wlanCfgParseArgumentLong(int8_t *cmdLine, int32_t *argc, + int8_t *argv[]); +#endif + +#if CFG_SUPPORT_IOT_AP_BLACKLIST +void wlanCfgLoadIotApRule(IN struct ADAPTER *prAdapter); +void wlanCfgDumpIotApRule(IN struct ADAPTER *prAdapter); +#endif + +int32_t wlanHexToNum(int8_t c); + +int32_t wlanHexToByte(int8_t *hex); + +int32_t wlanHexToArray(int8_t *hexString, int8_t *hexArray, uint8_t arrayLen); +int32_t wlanHexToArrayR(int8_t *hexString, int8_t *hexArray, uint8_t arrayLen); + + +int32_t wlanHwAddrToBin(int8_t *txt, uint8_t *addr); + +u_int8_t wlanIsChipNoAck(IN struct ADAPTER *prAdapter); + +u_int8_t wlanIsChipRstRecEnabled(IN struct ADAPTER *prAdapter); + +u_int8_t wlanIsChipAssert(IN struct ADAPTER *prAdapter); + +void wlanChipRstPreAct(IN struct ADAPTER *prAdapter); + +void wlanTxProfilingTagPacket(IN struct ADAPTER *prAdapter, IN void *prPacket, + IN enum ENUM_TX_PROFILING_TAG eTag); + +void wlanTxProfilingTagMsdu(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN enum ENUM_TX_PROFILING_TAG eTag); + +void wlanTxLifetimeTagPacket(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfoListHead, + IN enum ENUM_TX_PROFILING_TAG eTag); + +#if CFG_ASSERT_DUMP +void wlanCorDumpTimerInit(IN struct ADAPTER *prAdapter, u_int8_t fgIsResetN9); + +void wlanCorDumpTimerReset(IN struct ADAPTER *prAdapter, u_int8_t fgIsResetN9); + +void wlanN9CorDumpTimeOut(IN struct ADAPTER *prAdapter, + IN unsigned long ulParamPtr); + +void wlanCr4CorDumpTimeOut(IN struct ADAPTER *prAdapter, + IN unsigned long ulParamPtr); +#endif +#endif /* _WLAN_LIB_H */ + + +u_int8_t wlanGetWlanIdxByAddress(IN struct ADAPTER *prAdapter, + IN uint8_t *pucAddr, OUT uint8_t *pucIndex); + +uint8_t *wlanGetStaAddrByWlanIdx(IN struct ADAPTER *prAdapter, + IN uint8_t ucIndex); + +struct WLAN_CFG_ENTRY *wlanCfgGetEntryByIndex(IN struct ADAPTER *prAdapter, + const uint8_t ucIdx, + uint32_t flag); + +uint32_t wlanCfgGetTotalCfgNum( + IN struct ADAPTER *prAdapter, uint32_t flag); + + +uint32_t wlanGetStaIdxByWlanIdx(IN struct ADAPTER *prAdapter, + IN uint8_t ucIndex, OUT uint8_t *pucStaIdx); + +uint8_t wlanGetBssIdx(struct net_device *ndev); + +struct net_device *wlanGetNetDev(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucBssIndex); + +struct wiphy *wlanGetWiphy(void); + +u_int8_t wlanIsAisDev(struct net_device *prDev); + +/*----------------------------------------------------------------------------*/ +/* update per-AC statistics for LLS */ +/*----------------------------------------------------------------------------*/ +void wlanUpdateTxStatistics(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, u_int8_t fgTxDrop); + +void wlanUpdateRxStatistics(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb); + +uint32_t wlanTriggerStatsLog(IN struct ADAPTER *prAdapter, + IN uint32_t u4DurationInMs); + +uint32_t wlanPktTxDone(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN enum ENUM_TX_RESULT_CODE rTxDoneStatus); + +uint32_t wlanPowerOffWifi(IN struct ADAPTER *prAdapter); + +void wlanPrintVersion(struct ADAPTER *prAdapter); + +uint32_t wlanAccessRegister(IN struct ADAPTER *prAdapter, + IN uint32_t u4Addr, IN uint32_t *pru4Result, + IN uint32_t u4Data, + IN uint8_t ucSetQuery); + +uint32_t wlanAccessRegisterStatus(IN struct ADAPTER + *prAdapter, IN uint8_t ucCmdSeqNum, + IN uint8_t ucSetQuery, IN void *prEvent, + IN uint32_t u4EventLen); + +uint32_t wlanSetChipEcoInfo(IN struct ADAPTER *prAdapter); + +void wlanNotifyFwSuspend(struct GLUE_INFO *prGlueInfo, + struct net_device *prDev, u_int8_t fgSuspend); + +void wlanClearPendingInterrupt(IN struct ADAPTER *prAdapter); + +#if CFG_WMT_WIFI_PATH_SUPPORT +extern int32_t mtk_wcn_wmt_wifi_fem_cfg_report(void *pvInfoBuf); +#endif + +#if ((CFG_SISO_SW_DEVELOP == 1) || (CFG_SUPPORT_SPE_IDX_CONTROL == 1)) +uint8_t wlanGetAntPathType(IN struct ADAPTER *prAdapter, + IN enum ENUM_WF_PATH_FAVOR_T eWfPathFavor); +#endif + +uint8_t wlanGetSpeIdx(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN enum ENUM_WF_PATH_FAVOR_T eWfPathFavor); + +uint8_t wlanGetSupportNss(IN struct ADAPTER *prAdapter, IN uint8_t ucBssIndex); + +#if CFG_SUPPORT_LOWLATENCY_MODE +uint32_t wlanAdapterStartForLowLatency(IN struct ADAPTER *prAdapter); +uint32_t wlanProbeSuccessForLowLatency(IN struct ADAPTER *prAdapter); +uint32_t wlanConnectedForLowLatency(IN struct ADAPTER *prAdapter); +uint32_t wlanSetLowLatencyCommand(IN struct ADAPTER *prAdapter, + IN u_int8_t fgEnLowLatencyMode, + IN u_int8_t fgEnTxDupDetect, + IN u_int8_t fgTxDupCertQuery); +uint32_t wlanSetLowLatencyMode(IN struct ADAPTER *prAdapter, + IN uint32_t u4Events); +#endif /* CFG_SUPPORT_LOWLATENCY_MODE */ +int32_t wlanGetFileContent(struct ADAPTER *prAdapter, + const uint8_t *pcFileName, uint8_t *pucBuf, + uint32_t u4MaxFileLen, uint32_t *pu4ReadFileLen, u_int8_t bReqFw); + +#if CFG_SUPPORT_EASY_DEBUG +uint32_t wlanFwCfgParse(IN struct ADAPTER *prAdapter, uint8_t *pucConfigBuf); +#endif /* CFG_SUPPORT_EASY_DEBUG */ + +void wlanReleasePendingCmdById(struct ADAPTER *prAdapter, uint8_t ucCid); + +uint32_t wlanDecimalStr2Hexadecimals(uint8_t *pucDecimalStr, uint16_t *pu2Out); + +uint64_t wlanGetSupportedFeatureSet(IN struct GLUE_INFO *prGlueInfo); + +uint32_t +wlanQueryLteSafeChannel(IN struct ADAPTER *prAdapter, + IN uint8_t ucRoleIndex); + +uint32_t +wlanCalculateAllChannelDirtiness(IN struct ADAPTER *prAdapter); + +void +wlanInitChnLoadInfoChannelList(IN struct ADAPTER *prAdapter); + +uint8_t +wlanGetChannelIndex(IN uint8_t channel); + +uint8_t +wlanGetChannelNumFromIndex(IN uint8_t ucIdx); + +void +wlanSortChannel(IN struct ADAPTER *prAdapter, + IN enum ENUM_CHNL_SORT_POLICY ucSortType); + +void wlanSuspendPmHandle(struct GLUE_INFO *prGlueInfo); +void wlanResumePmHandle(struct GLUE_INFO *prGlueInfo); + +#if defined(CFG_REPORT_MAX_TX_RATE) && (CFG_REPORT_MAX_TX_RATE == 1) +int wlanGetMaxTxRate(IN struct ADAPTER *prAdapter, + IN void *prBssPtr, IN struct STA_RECORD *prStaRec, + OUT uint32_t *pu4CurRate, OUT uint32_t *pu4MaxRate); +#endif /* CFG_REPORT_MAX_TX_RATE */ + +#ifdef CFG_SUPPORT_LINK_QUALITY_MONITOR +int wlanGetRxRate(IN struct GLUE_INFO *prGlueInfo, + OUT uint32_t *pu4CurRate, OUT uint32_t *pu4MaxRate); +uint32_t wlanLinkQualityMonitor(struct GLUE_INFO *prGlueInfo, bool bFgIsOid); +void wlanFinishCollectingLinkQuality(struct GLUE_INFO *prGlueInfo); +#endif /* CFG_SUPPORT_LINK_QUALITY_MONITOR */ +u_int8_t wlanIsDriverReady(IN struct GLUE_INFO *prGlueInfo); +void wlanOffUninitNicModule(IN struct ADAPTER *prAdapter, + IN const u_int8_t bAtResetFlow); +void wlanOffClearAllQueues(IN struct ADAPTER *prAdapter); +uint8_t wlanGetBssIdx(struct net_device *ndev); +int wlanQueryRateByTable(uint32_t txmode, uint32_t rate, + uint32_t frmode, uint32_t sgi, uint32_t nsts, + uint32_t *pu4CurRate, uint32_t *pu4MaxRate); + +#if CFG_SUPPORT_DATA_STALL +void wlanCustomMonitorFunction(struct ADAPTER *prAdapter, + struct WIFI_LINK_QUALITY_INFO *prLinkQualityInfo, uint8_t ucBssIdx); +#endif /* CFG_SUPPORT_DATA_STALL */ +uint32_t wlanSetForceRTS(IN struct ADAPTER *prAdapter, + IN u_int8_t fgEnForceRTS); + +void +wlanBackupEmCfgSetting(IN struct ADAPTER *prAdapter); + +void +wlanResoreEmCfgSetting(IN struct ADAPTER *prAdapter); + +void +wlanCleanAllEmCfgSetting(IN struct ADAPTER *prAdapter); + +#if CFG_SUPPORT_NCHO +void wlanNchoInit(IN struct ADAPTER *prAdapter, IN uint8_t fgFwSync); +uint32_t wlanNchoSetFWEnable(IN struct ADAPTER *prAdapter, IN uint8_t fgEnable); +uint32_t wlanNchoSetFWRssiTrigger(IN struct ADAPTER *prAdapter, + IN int32_t i4RoamTriggerRssi); +uint32_t wlanNchoSetFWScanPeriod(IN struct ADAPTER *prAdapter, + IN uint32_t u4RoamScanPeriod); +#endif + +u_int8_t wlanWfdEnabled(struct ADAPTER *prAdapter); + +int wlanChipConfig(struct ADAPTER *prAdapter, + char *pcCommand, int i4TotalLen); diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/wlan_oid.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/wlan_oid.h new file mode 100644 index 0000000000000000000000000000000000000000..ca6b94fc8cb2bb636f20ba08e192eca04c4d1f4a --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/wlan_oid.h @@ -0,0 +1,4195 @@ +/******************************************************************************* + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include + * /wlan_oid.h#4 + */ + +/*! \file "wlan_oid.h" + * \brief This file contains the declairation file of the WLAN OID processing + * routines of Windows driver for MediaTek Inc. + * 802.11 Wireless LAN Adapters. + */ + +#ifndef _WLAN_OID_H +#define _WLAN_OID_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +#define PARAM_MAX_LEN_SSID 32 + +#define PARAM_MAC_ADDR_LEN 6 + +#define ETHERNET_HEADER_SZ 14 +#define ETHERNET_MIN_PKT_SZ 60 +#define ETHERNET_MAX_PKT_SZ 1514 + +#define PARAM_MAX_LEN_RATES 8 +#define PARAM_MAX_LEN_RATES_EX 16 + +#define PARAM_AUTH_REQUEST_REAUTH 0x01 +#define PARAM_AUTH_REQUEST_KEYUPDATE 0x02 +#define PARAM_AUTH_REQUEST_PAIRWISE_ERROR 0x06 +#define PARAM_AUTH_REQUEST_GROUP_ERROR 0x0E + + +#define PARAM_EEPROM_READ_METHOD_GETSIZE 0 +#define PARAM_EEPROM_READ_METHOD_READ 1 +#define PARAM_EEPROM_READ_NVRAM 2 +#define PARAM_EEPROM_WRITE_NVRAM 3 + + +#define PARAM_WHQL_RSSI_MAX_DBM (-10) +#define PARAM_WHQL_RSSI_INITIAL_DBM (-50) +#define PARAM_WHQL_RSSI_MIN_DBM (-200) + +#define PARAM_DEVICE_WAKE_UP_ENABLE 0x00000001 +#define PARAM_DEVICE_WAKE_ON_PATTERN_MATCH_ENABLE 0x00000002 +#define PARAM_DEVICE_WAKE_ON_MAGIC_PACKET_ENABLE 0x00000004 + +#define PARAM_WAKE_UP_MAGIC_PACKET 0x00000001 +#define PARAM_WAKE_UP_PATTERN_MATCH 0x00000002 +#define PARAM_WAKE_UP_LINK_CHANGE 0x00000004 + +/* Packet filter bit definitioin (UINT_32 bit-wise definition) */ +#define PARAM_PACKET_FILTER_DIRECTED 0x00000001 +#define PARAM_PACKET_FILTER_MULTICAST 0x00000002 +#define PARAM_PACKET_FILTER_ALL_MULTICAST 0x00000004 +#define PARAM_PACKET_FILTER_BROADCAST 0x00000008 +#define PARAM_PACKET_FILTER_PROMISCUOUS 0x00000020 +#define PARAM_PACKET_FILTER_ALL_LOCAL 0x00000080 +#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 +#define PARAM_PACKET_FILTER_P2P_MASK 0xF0000000 +#define PARAM_PACKET_FILTER_PROBE_REQ 0x80000000 +#define PARAM_PACKET_FILTER_ACTION_FRAME 0x40000000 +#define PARAM_PACKET_FILTER_AUTH 0x20000000 +#define PARAM_PACKET_FILTER_ASSOC_REQ 0x10000000 +#endif + +#if CFG_SLT_SUPPORT +#define PARAM_PACKET_FILTER_SUPPORTED (PARAM_PACKET_FILTER_DIRECTED | \ + PARAM_PACKET_FILTER_MULTICAST | \ + PARAM_PACKET_FILTER_BROADCAST | \ + PARAM_PACKET_FILTER_ALL_MULTICAST) +#else +#define PARAM_PACKET_FILTER_SUPPORTED (PARAM_PACKET_FILTER_DIRECTED | \ + PARAM_PACKET_FILTER_MULTICAST | \ + PARAM_PACKET_FILTER_BROADCAST | \ + PARAM_PACKET_FILTER_ALL_MULTICAST) +#endif + +#define PARAM_MEM_DUMP_MAX_SIZE 1536 + +#if CFG_SUPPORT_CAL_RESULT_BACKUP_TO_HOST +#define PARAM_CAL_DATA_DUMP_MAX_SIZE 1200 +#define PARAM_CAL_DATA_DUMP_MAX_NUM 300 +#endif + +#define BT_PROFILE_PARAM_LEN 8 + +/* Based on EEPROM layout 20160120 */ +#define EFUSE_ADDR_MAX 0x3BF +#if CFG_SUPPORT_BUFFER_MODE + +/* For MT7668 */ +#define EFUSE_CONTENT_BUFFER_START 0x03A +#define EFUSE_CONTENT_BUFFER_END 0x1D9 +#define EFUSE_CONTENT_BUFFER_SIZE (EFUSE_CONTENT_BUFFER_END - \ + EFUSE_CONTENT_BUFFER_START + 1) + +/* For MT6632 */ +#define EFUSE_CONTENT_SIZE 16 + +#define EFUSE_BLOCK_SIZE 16 +#define EEPROM_SIZE 1184 +#define MAX_EEPROM_BUFFER_SIZE 1450 +#endif /* CFG_SUPPORT_BUFFER_MODE */ + +#if CFG_SUPPORT_TX_BF +#define TXBF_CMD_NEED_TO_RESPONSE(u4TxBfCmdId) \ + (u4TxBfCmdId == BF_PFMU_TAG_READ || \ + u4TxBfCmdId == BF_PROFILE_READ) +#endif /* CFG_SUPPORT_TX_BF */ +#define MU_CMD_NEED_TO_RESPONSE(u4MuCmdId) \ + (u4MuCmdId == MU_GET_CALC_INIT_MCS || \ + u4MuCmdId == MU_HQA_GET_QD || \ + u4MuCmdId == MU_HQA_GET_CALC_LQ) +#if CFG_SUPPORT_MU_MIMO +/* @NITESH: MACROS For Init MCS calculation (MU Metric Table) */ +#define NUM_MUT_FEC 2 +#define NUM_MUT_MCS 10 +#define NUM_MUT_NR_NUM 3 +#define NUM_MUT_INDEX 8 + +#define NUM_OF_USER 2 +#define NUM_OF_MODUL 5 +#endif /* CFG_SUPPORT_MU_MIMO */ + +#define SER_ACTION_QUERY 0 +#define SER_ACTION_SET 1 +#define SER_ACTION_SET_ENABLE_MASK 2 +#define SER_ACTION_RECOVER 3 + +/* SER_ACTION_SET sub action */ +#define SER_SET_DISABLE 0 +#define SER_SET_ENABLE 1 + +/* SER_ACTION_SET_ENABLE_MASK mask define */ +#define SER_ENABLE_TRACKING BIT(0) +#define SER_ENABLE_L1_RECOVER BIT(1) +#define SER_ENABLE_L2_RECOVER BIT(2) +#define SER_ENABLE_L3_RX_ABORT BIT(3) +#define SER_ENABLE_L3_TX_ABORT BIT(4) +#define SER_ENABLE_L3_TX_DISABLE BIT(5) +#define SER_ENABLE_L3_BF_RECOVER BIT(6) + +/* SER_ACTION_RECOVER recover method */ +#define SER_SET_L0_RECOVER 0 +#define SER_SET_L1_RECOVER 1 +#define SER_SET_L2_RECOVER 2 +#define SER_SET_L3_RX_ABORT 3 +#define SER_SET_L3_TX_ABORT 4 +#define SER_SET_L3_TX_DISABLE 5 +#define SER_SET_L3_BF_RECOVER 6 + + +/* SER user command */ +#define SER_USER_CMD_DISABLE 0 +#define SER_USER_CMD_ENABLE 1 + +#define SER_USER_CMD_ENABLE_MASK_TRACKING_ONLY (200) +#define SER_USER_CMD_ENABLE_MASK_L1_RECOVER_ONLY (201) +#define SER_USER_CMD_ENABLE_MASK_L2_RECOVER_ONLY (202) +#define SER_USER_CMD_ENABLE_MASK_L3_RX_ABORT_ONLY (203) +#define SER_USER_CMD_ENABLE_MASK_L3_TX_ABORT_ONLY (204) +#define SER_USER_CMD_ENABLE_MASK_L3_TX_DISABLE_ONLY (205) +#define SER_USER_CMD_ENABLE_MASK_L3_BFRECOVER_ONLY (206) +#define SER_USER_CMD_ENABLE_MASK_RECOVER_ALL (207) + + +/* Use a magic number to prevent human mistake */ +#define SER_USER_CMD_L0_RECOVER 956 +#define SER_USER_CMD_L1_RECOVER 995 + +#define SER_USER_CMD_L2_BN0_RECOVER (300) +#define SER_USER_CMD_L2_BN1_RECOVER (301) +#define SER_USER_CMD_L3_RX0_ABORT (302) +#define SER_USER_CMD_L3_RX1_ABORT (303) +#define SER_USER_CMD_L3_TX0_ABORT (304) +#define SER_USER_CMD_L3_TX1_ABORT (305) +#define SER_USER_CMD_L3_TX0_DISABLE (306) +#define SER_USER_CMD_L3_TX1_DISABLE (307) +#define SER_USER_CMD_L3_BF_RECOVER (308) + + +#define TXPOWER_MAN_SET_INPUT_ARG_NUM 4 + +#if (CFG_SUPPORT_TXPOWER_INFO == 1) +#define TXPOWER_INFO_INPUT_ARG_NUM 2 +#define TXPOWER_FORMAT_LEGACY 0 +#define TXPOWER_FORMAT_HE 1 + +/* 1M, 2M, 5.5M, 11M */ +#define MODULATION_SYSTEM_CCK_NUM 4 + +/* 6M, 9M, 12M, 18M, 24M, 36M, 48M, 54M */ +#define MODULATION_SYSTEM_OFDM_NUM 8 + +#define MODULATION_SYSTEM_HT20_NUM 8 /* MCS0~7 */ +#define MODULATION_SYSTEM_HT40_NUM 9 /* MCS0~7, MCS32 */ +#define MODULATION_SYSTEM_VHT20_NUM 10 /* MCS0~9 */ +#define MODULATION_SYSTEM_VHT40_NUM MODULATION_SYSTEM_VHT20_NUM +#define MODULATION_SYSTEM_VHT80_NUM MODULATION_SYSTEM_VHT20_NUM +#define MODULATION_SYSTEM_VHT160_NUM MODULATION_SYSTEM_VHT20_NUM + +#define MODULATION_SYSTEM_HE_26_MCS_NUM 12 +#define MODULATION_SYSTEM_HE_52_MCS_NUM 12 +#define MODULATION_SYSTEM_HE_106_MCS_NUM 12 +#define MODULATION_SYSTEM_HE_242_MCS_NUM 12 +#define MODULATION_SYSTEM_HE_484_MCS_NUM 12 +#define MODULATION_SYSTEM_HE_996_MCS_NUM 12 +#define MODULATION_SYSTEM_HE_996X2_MCS_NUM 12 + +#define TXPOWER_RATE_CCK_OFFSET (0) +#define TXPOWER_RATE_OFDM_OFFSET (TXPOWER_RATE_CCK_OFFSET + \ + MODULATION_SYSTEM_CCK_NUM) +#define TXPOWER_RATE_HT20_OFFSET (TXPOWER_RATE_OFDM_OFFSET + \ + MODULATION_SYSTEM_OFDM_NUM) +#define TXPOWER_RATE_HT40_OFFSET (TXPOWER_RATE_HT20_OFFSET + \ + MODULATION_SYSTEM_HT20_NUM) +#define TXPOWER_RATE_VHT20_OFFSET (TXPOWER_RATE_HT40_OFFSET + \ + MODULATION_SYSTEM_HT40_NUM) +#define TXPOWER_RATE_VHT40_OFFSET (TXPOWER_RATE_VHT20_OFFSET + \ + MODULATION_SYSTEM_VHT20_NUM) +#define TXPOWER_RATE_VHT80_OFFSET (TXPOWER_RATE_VHT40_OFFSET + \ + MODULATION_SYSTEM_VHT40_NUM) +#define TXPOWER_RATE_VHT160_OFFSET (TXPOWER_RATE_VHT80_OFFSET + \ + MODULATION_SYSTEM_VHT80_NUM) + +#define TXPOWER_RATE_HE26_OFFSET (TXPOWER_RATE_VHT160_OFFSET) +#define TXPOWER_RATE_HE52_OFFSET (TXPOWER_RATE_HE26_OFFSET + \ + MODULATION_SYSTEM_HE_26_MCS_NUM) +#define TXPOWER_RATE_HE106_OFFSET (TXPOWER_RATE_HE52_OFFSET + \ + MODULATION_SYSTEM_HE_52_MCS_NUM) +#define TXPOWER_RATE_HE242_OFFSET (TXPOWER_RATE_HE106_OFFSET + \ + MODULATION_SYSTEM_HE_106_MCS_NUM) +#define TXPOWER_RATE_HE484_OFFSET (TXPOWER_RATE_HE242_OFFSET + \ + MODULATION_SYSTEM_HE_242_MCS_NUM) +#define TXPOWER_RATE_HE996_OFFSET (TXPOWER_RATE_HE484_OFFSET + \ + MODULATION_SYSTEM_HE_484_MCS_NUM) +#define TXPOWER_RATE_HE996X2_OFFSET (TXPOWER_RATE_HE996_OFFSET + \ + MODULATION_SYSTEM_HE_996_MCS_NUM) +#define TXPOWER_RATE_NUM (TXPOWER_RATE_HE996X2_OFFSET + \ + MODULATION_SYSTEM_HE_996X2_MCS_NUM) +#endif + +#if CFG_SUPPORT_LOWLATENCY_MODE +#define GED_EVENT_GAS (1 << 4) +#define GED_EVENT_NETWORK (1 << 11) +#define GED_EVENT_DOPT_WIFI_SCAN (1 << 12) +#define GED_EVENT_TX_DUP_DETECT (1 << 13) + +#define LOW_LATENCY_MODE_MAGIC_CODE 0x86 +#define LOW_LATENCY_MODE_CMD_V2 0x2 +#endif /* CFG_SUPPORT_LOWLATENCY_MODE */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +/*----------------------------------------------------------------------------*/ +/* Parameters of User Configuration which match to NDIS5.1 */ +/*----------------------------------------------------------------------------*/ + +enum ENUM_PARAM_PHY_TYPE { + PHY_TYPE_802_11ABG = 0, /*!< Can associated with 802.11abg AP, + * Scan dual band. + */ + PHY_TYPE_802_11BG, /*!< Can associated with 802_11bg AP, + * Scan single band and not report 802_11a + * BSSs. + */ + PHY_TYPE_802_11G, /*!< Can associated with 802_11g only AP, + * Scan single band and not report 802_11ab + * BSSs. + */ + PHY_TYPE_802_11A, /*!< Can associated with 802_11a only AP, + * Scan single band and not report 802_11bg + * BSSs. + */ + PHY_TYPE_802_11B, /*!< Can associated with 802_11b only AP + * Scan single band and not report 802_11ag + * BSSs. + */ + PHY_TYPE_NUM /* 5 */ +}; + +enum ENUM_PARAM_OP_MODE { + NET_TYPE_IBSS = 0, /*!< Try to merge/establish an AdHoc, + * do periodic SCAN for merging. + */ + NET_TYPE_INFRA, /*!< Try to join an Infrastructure, + * do periodic SCAN for joining. + */ + NET_TYPE_AUTO_SWITCH, /*!< Try to join an Infrastructure, + * if fail then try to merge or + */ + /* establish an AdHoc, do periodic SCAN for joining or merging. */ + NET_TYPE_DEDICATED_IBSS,/*!< Try to merge an AdHoc first, */ + /* if fail then establish AdHoc permanently, no more SCAN. */ + NET_TYPE_NUM /* 4 */ +}; + +struct PARAM_CONNECT { + uint32_t u4SsidLen; /*!< SSID length in bytes. + * Zero length is broadcast(any) SSID + */ + uint8_t *pucSsid; + uint8_t *pucBssid; + uint8_t *pucBssidHint; + uint32_t u4CenterFreq; + uint8_t ucBssIdx; + uint8_t *pucIEs; + uint32_t u4IesLen; +}; + +struct PARAM_EXTERNAL_AUTH { + uint8_t bssid[PARAM_MAC_ADDR_LEN]; + uint16_t status; + uint8_t ucBssIdx; +}; + +struct PARAM_OP_MODE { + enum ENUM_PARAM_OP_MODE eOpMode; + uint8_t ucBssIdx; +}; + +/* This is enum defined for user to select an AdHoc Mode */ +enum ENUM_PARAM_AD_HOC_MODE { + AD_HOC_MODE_11B = 0, /*!< Create 11b IBSS if we support + * 802.11abg/802.11bg. + */ + AD_HOC_MODE_MIXED_11BG, /*!< Create 11bg mixed IBSS if we support + * 802.11abg/802.11bg/802.11g. + */ + AD_HOC_MODE_11G, /*!< Create 11g only IBSS if we support + * 802.11abg/802.11bg/802.11g. + */ + AD_HOC_MODE_11A, /*!< Create 11a only IBSS if we support + * 802.11abg. + */ + AD_HOC_MODE_NUM /* 4 */ +}; + +enum ENUM_PARAM_NETWORK_TYPE { + PARAM_NETWORK_TYPE_FH, + PARAM_NETWORK_TYPE_DS, + PARAM_NETWORK_TYPE_OFDM5, + PARAM_NETWORK_TYPE_OFDM24, + PARAM_NETWORK_TYPE_AUTOMODE, + PARAM_NETWORK_TYPE_NUM /*!< Upper bound, not real case */ +}; + +struct PARAM_NETWORK_TYPE_LIST { + uint32_t NumberOfItems; /*!< At least 1 */ + enum ENUM_PARAM_NETWORK_TYPE eNetworkType[1]; +}; + +enum ENUM_PARAM_PRIVACY_FILTER { + PRIVACY_FILTER_ACCEPT_ALL, + PRIVACY_FILTER_8021xWEP, + PRIVACY_FILTER_NUM +}; + +enum ENUM_RELOAD_DEFAULTS { + ENUM_RELOAD_WEP_KEYS +}; + +struct PARAM_PM_PACKET_PATTERN { + uint32_t Priority; /* Importance of the given pattern. */ + uint32_t Reserved; /* Context information for transports. */ + uint32_t MaskSize; /* Size in bytes of the pattern mask. */ + uint32_t PatternOffset; /* Offset from beginning of this */ + /* structure to the pattern bytes. */ + uint32_t PatternSize; /* Size in bytes of the pattern. */ + uint32_t PatternFlags; /* Flags (TBD). */ +}; + + +/* Combine ucTpTestMode and ucSigmaTestMode in one flag */ +/* ucTpTestMode == 0, for normal driver */ +/* ucTpTestMode == 1, for pure throughput test mode (ex: RvR) */ +/* ucTpTestMode == 2, for sigma TGn/TGac/PMF */ +/* ucTpTestMode == 3, for sigma WMM PS */ +enum ENUM_TP_TEST_MODE { + ENUM_TP_TEST_MODE_NORMAL = 0, + ENUM_TP_TEST_MODE_THROUGHPUT, + ENUM_TP_TEST_MODE_SIGMA_AC_N_PMF, + ENUM_TP_TEST_MODE_SIGMA_WMM_PS, + ENUM_TP_TEST_MODE_NUM +}; + +/*--------------------------------------------------------------*/ +/*! \brief Struct definition to indicate specific event. */ +/*--------------------------------------------------------------*/ +enum ENUM_STATUS_TYPE { + ENUM_STATUS_TYPE_AUTHENTICATION, + ENUM_STATUS_TYPE_MEDIA_STREAM_MODE, + ENUM_STATUS_TYPE_CANDIDATE_LIST, + ENUM_STATUS_TYPE_FT_AUTH_STATUS, + ENUM_STATUS_TYPE_NUM /*!< Upper bound, not real case */ +}; + +struct PARAM_802_11_CONFIG_FH { + uint32_t u4Length; /*!< Length of structure */ + uint32_t u4HopPattern; /*!< Defined as 802.11 */ + uint32_t u4HopSet; /*!< to one if non-802.11 */ + uint32_t u4DwellTime; /*!< In unit of Kusec */ +}; + +struct PARAM_802_11_CONFIG { + uint32_t u4Length; /*!< Length of structure */ + uint32_t u4BeaconPeriod; /*!< In unit of Kusec */ + uint32_t u4ATIMWindow; /*!< In unit of Kusec */ + uint32_t u4DSConfig; /*!< Channel frequency in unit of kHz */ + struct PARAM_802_11_CONFIG_FH rFHConfig; +}; + +struct PARAM_STATUS_INDICATION { + enum ENUM_STATUS_TYPE eStatusType; +}; + +struct PARAM_AUTH_REQUEST { + uint32_t u4Length; /*!< Length of this struct */ + uint8_t arBssid[PARAM_MAC_ADDR_LEN]; + uint32_t u4Flags; /*!< Definitions are as follows */ +}; + +struct PARAM_PMKID { + uint8_t arBSSID[PARAM_MAC_ADDR_LEN]; + uint8_t arPMKID[IW_PMKID_LEN]; + uint8_t ucBssIdx; +}; + +struct PARAM_PMKID_CANDIDATE { + uint8_t arBSSID[PARAM_MAC_ADDR_LEN]; + uint32_t u4Flags; +}; + +struct PARAM_INDICATION_EVENT { + struct PARAM_STATUS_INDICATION rStatus; + union { + struct PARAM_AUTH_REQUEST rAuthReq; + struct PARAM_PMKID_CANDIDATE rCandi; + }; +}; + +/*! \brief Capabilities, privacy, rssi and IEs of each BSSID */ +struct PARAM_BSSID_EX { + uint32_t u4Length; /*!< Length of structure */ + uint8_t arMacAddress[PARAM_MAC_ADDR_LEN]; /*!< BSSID */ + uint8_t Reserved[2]; + struct PARAM_SSID rSsid; /*!< SSID */ + uint32_t u4Privacy; /*!< Need WEP encryption */ + int32_t rRssi; /*!< in dBm */ + enum ENUM_PARAM_NETWORK_TYPE eNetworkTypeInUse; + struct PARAM_802_11_CONFIG rConfiguration; + enum ENUM_PARAM_OP_MODE eOpMode; + uint8_t rSupportedRates[PARAM_MAX_LEN_RATES_EX]; + uint32_t u4IELength; + uint8_t aucIEs[1]; +}; + +struct PARAM_BSSID_LIST_EX { + uint32_t u4NumberOfItems; /*!< at least 1 */ + struct PARAM_BSSID_EX arBssid[1]; +}; + +struct PARAM_WEP { + uint32_t u4Length; /*!< Length of structure */ + uint32_t u4KeyIndex; /*!< 0: pairwise key, others group keys */ + uint32_t u4KeyLength; /*!< Key length in bytes */ + uint8_t aucKeyMaterial[32]; /*!< Key content by above setting */ +}; + +/*! \brief Key mapping of BSSID */ +struct PARAM_KEY { + uint32_t u4Length; /*!< Length of structure */ + uint32_t u4KeyIndex; /*!< KeyID */ + uint32_t u4KeyLength; /*!< Key length in bytes */ + uint8_t arBSSID[PARAM_MAC_ADDR_LEN]; /*!< MAC address */ + uint64_t rKeyRSC; + uint8_t ucBssIdx; + uint8_t ucCipher; + uint8_t aucKeyMaterial[32]; /*!< Key content by above setting */ + /* Following add to change the original windows structure */ +}; + +struct PARAM_REMOVE_KEY { + uint32_t u4Length; /*!< Length of structure */ + uint32_t u4KeyIndex; /*!< KeyID */ + uint8_t arBSSID[PARAM_MAC_ADDR_LEN]; /*!< MAC address */ + uint8_t ucBssIdx; +}; + +/*! \brief Default key */ +struct PARAM_DEFAULT_KEY { + uint8_t ucKeyID; + uint8_t ucUnicast; + uint8_t ucMulticast; + uint8_t ucBssIdx; +}; + +#if CFG_SUPPORT_WAPI +enum ENUM_KEY_TYPE { + ENUM_WPI_PAIRWISE_KEY = 0, + ENUM_WPI_GROUP_KEY +}; + +enum ENUM_WPI_PROTECT_TYPE { + ENUM_WPI_NONE, + ENUM_WPI_RX, + ENUM_WPI_TX, + ENUM_WPI_RX_TX +}; + +struct PARAM_WPI_KEY { + enum ENUM_KEY_TYPE eKeyType; + enum ENUM_WPI_PROTECT_TYPE eDirection; + uint8_t ucKeyID; + uint8_t aucRsv[3]; + uint8_t aucAddrIndex[12]; + uint32_t u4LenWPIEK; + uint8_t aucWPIEK[256]; + uint32_t u4LenWPICK; + uint8_t aucWPICK[256]; + uint8_t aucPN[16]; + uint8_t ucBssIdx; +}; +#endif + +enum PARAM_POWER_MODE { + Param_PowerModeCAM, + Param_PowerModeMAX_PSP, + Param_PowerModeFast_PSP, + Param_PowerModeMax /* Upper bound, not real case */ +}; + +enum PARAM_DEVICE_POWER_STATE { + ParamDeviceStateUnspecified = 0, + ParamDeviceStateD0, + ParamDeviceStateD1, + ParamDeviceStateD2, + ParamDeviceStateD3, + ParamDeviceStateMaximum +}; + +struct PARAM_POWER_MODE_ { + uint8_t ucBssIdx; + enum PARAM_POWER_MODE ePowerMode; +}; + +#if CFG_SUPPORT_802_11D + +/*! \brief The enumeration definitions for OID_IPN_MULTI_DOMAIN_CAPABILITY */ +enum PARAM_MULTI_DOMAIN_CAPABILITY { + ParamMultiDomainCapDisabled, + ParamMultiDomainCapEnabled +}; +#endif + +struct COUNTRY_STRING_ENTRY { + uint8_t aucCountryCode[2]; + uint8_t aucEnvironmentCode[2]; +}; + +/* Power management related definition and enumerations */ +#define UAPSD_NONE 0 +#define UAPSD_AC0 (BIT(0) | BIT(4)) +#define UAPSD_AC1 (BIT(1) | BIT(5)) +#define UAPSD_AC2 (BIT(2) | BIT(6)) +#define UAPSD_AC3 (BIT(3) | BIT(7)) +#define UAPSD_ALL (UAPSD_AC0 | UAPSD_AC1 | UAPSD_AC2 | UAPSD_AC3) + +enum ENUM_POWER_SAVE_PROFILE { + ENUM_PSP_CONTINUOUS_ACTIVE = 0, + ENUM_PSP_CONTINUOUS_POWER_SAVE, + ENUM_PSP_FAST_SWITCH, + ENUM_PSP_NUM +}; + +struct LINK_SPEED_EX_ { + int8_t cRssi; + + uint8_t fgIsLinkQualityValid; + OS_SYSTIME rLinkQualityUpdateTime; + int8_t cLinkQuality; + + uint8_t fgIsLinkRateValid; + OS_SYSTIME rLinkRateUpdateTime; + uint32_t u2LinkSpeed; + + uint8_t ucMediumBusyPercentage; + uint8_t ucIsLQ0Rdy; +}; + +struct PARAM_LINK_SPEED_EX { + struct LINK_SPEED_EX_ rLq[BSSID_NUM]; +}; + +/*--------------------------------------------------------------*/ +/*! \brief Set/Query authentication and encryption capability. */ +/*--------------------------------------------------------------*/ +struct PARAM_AUTH_ENCRYPTION { + enum ENUM_PARAM_AUTH_MODE eAuthModeSupported; + enum ENUM_WEP_STATUS eEncryptStatusSupported; +}; + +struct PARAM_CAPABILITY { + uint32_t u4Length; + uint32_t u4Version; + uint32_t u4NoOfAuthEncryptPairsSupported; + struct PARAM_AUTH_ENCRYPTION + arAuthenticationEncryptionSupported[1]; +}; + +#define NL80211_KCK_LEN 16 +#define NL80211_KEK_LEN 16 +#define NL80211_REPLAY_CTR_LEN 8 + +struct PARAM_GTK_REKEY_DATA { + uint8_t aucKek[NL80211_KEK_LEN]; + uint8_t aucKck[NL80211_KCK_LEN]; + uint8_t aucReplayCtr[NL80211_REPLAY_CTR_LEN]; + uint8_t ucBssIndex; + uint8_t ucRsv[3]; + uint32_t u4Proto; + uint32_t u4PairwiseCipher; + uint32_t u4GroupCipher; + uint32_t u4KeyMgmt; + uint32_t u4MgmtGroupCipher; +}; + +struct PARAM_CUSTOM_MCR_RW_STRUCT { + uint32_t u4McrOffset; + uint32_t u4McrData; +}; + +#if CFG_SUPPORT_CAL_RESULT_BACKUP_TO_HOST +/* + * Description of Each Parameters : + * ucReason : + * 0 : Query Information of Thermal or Cal Data Length + * 1 : Trigger FW do or don't All Cal + * 2 : Dump Data to Host + * 3 : Send Backupped Cal Data to FW + * 4 : For Debug Use, Tell FW Print Cal Data (Rom or Ram) + * ucAction : + * 0 : Read Thermal Value + * 1 : Ask the Cal Data Total Length (Rom and Ram) + * 2 : Tell FW do All Cal + * 3 : Tell FW don't do Cal + * 4 : Dump Data to Host (Rom or Ram) + * 5 : Send Backupped Cal Data to FW (Rom or Ram) + * 6 : For Debug Use, Tell FW Print Cal Data (Rom or Ram) + * ucNeedResp : + * 0 : FW No Need to Response an EVENT + * 1 : FW Need to Response an EVENT + * ucFragNum : + * Sequence Number + * ucRomRam : + * 0 : Operation for Rom Cal Data + * 1 : Operation for Ram Cal Data + * u4ThermalValue : + * Field for filling the Thermal Value in FW + * u4Address : + * Dumpped Starting Address + * Used for Dump and Send Cal Data Between Driver and FW + * u4Length : + * Memory Size need to allocated in Driver or Data Size in an EVENT + * Used for Dump and Send Cal Data Between Driver and FW + * u4RemainLength : + * Remain Length need to Dump + * Used for Dump and Send Cal Data Between Driver and FW + */ +struct PARAM_CAL_BACKUP_STRUCT_V2 { + uint8_t ucReason; + uint8_t ucAction; + uint8_t ucNeedResp; + uint8_t ucFragNum; + uint8_t ucRomRam; + uint32_t u4ThermalValue; + uint32_t u4Address; + uint32_t u4Length; + uint32_t u4RemainLength; +}; +#endif + +#if CFG_SUPPORT_QA_TOOL +#if CFG_SUPPORT_BUFFER_MODE +struct BIN_CONTENT { + uint16_t u2Addr; + uint8_t ucValue; + uint8_t ucReserved; +}; + +struct PARAM_CUSTOM_EFUSE_BUFFER_MODE { + uint8_t ucSourceMode; + uint8_t ucCount; + uint8_t ucCmdType; + uint8_t ucReserved; + uint8_t aBinContent[MAX_EEPROM_BUFFER_SIZE]; +}; + +struct PARAM_CUSTOM_EFUSE_BUFFER_MODE_CONNAC_T { + uint8_t ucSourceMode; + uint8_t ucContentFormat; + uint16_t u2Count; + uint8_t aBinContent[MAX_EEPROM_BUFFER_SIZE]; +}; + +/*#if (CFG_EEPROM_PAGE_ACCESS == 1)*/ +struct PARAM_CUSTOM_ACCESS_EFUSE { + uint32_t u4Address; + uint32_t u4Valid; + uint8_t aucData[16]; +}; + +struct PARAM_CUSTOM_EFUSE_FREE_BLOCK { + uint8_t ucGetFreeBlock; + uint8_t aucReserved[3]; +}; + +struct PARAM_CUSTOM_GET_TX_POWER { + uint8_t ucTxPwrType; + uint8_t ucCenterChannel; + uint8_t ucDbdcIdx; /* 0:Band 0, 1: Band1 */ + uint8_t ucBand; /* 0:G-band 1: A-band*/ + uint8_t ucReserved[4]; +}; + +/*#endif*/ + +#endif /* CFG_SUPPORT_BUFFER_MODE */ + +struct PARAM_CUSTOM_SET_TX_TARGET_POWER { + int8_t cTxPwr2G4Cck; /* signed, in unit of 0.5dBm */ + int8_t cTxPwr2G4Dsss; /* signed, in unit of 0.5dBm */ + uint8_t ucTxTargetPwr; /* Tx target power base for all*/ + uint8_t ucReserved; + + int8_t cTxPwr2G4OFDM_BPSK; + int8_t cTxPwr2G4OFDM_QPSK; + int8_t cTxPwr2G4OFDM_16QAM; + int8_t cTxPwr2G4OFDM_Reserved; + int8_t cTxPwr2G4OFDM_48Mbps; + int8_t cTxPwr2G4OFDM_54Mbps; + + int8_t cTxPwr2G4HT20_BPSK; + int8_t cTxPwr2G4HT20_QPSK; + int8_t cTxPwr2G4HT20_16QAM; + int8_t cTxPwr2G4HT20_MCS5; + int8_t cTxPwr2G4HT20_MCS6; + int8_t cTxPwr2G4HT20_MCS7; + + int8_t cTxPwr2G4HT40_BPSK; + int8_t cTxPwr2G4HT40_QPSK; + int8_t cTxPwr2G4HT40_16QAM; + int8_t cTxPwr2G4HT40_MCS5; + int8_t cTxPwr2G4HT40_MCS6; + int8_t cTxPwr2G4HT40_MCS7; + + int8_t cTxPwr5GOFDM_BPSK; + int8_t cTxPwr5GOFDM_QPSK; + int8_t cTxPwr5GOFDM_16QAM; + int8_t cTxPwr5GOFDM_Reserved; + int8_t cTxPwr5GOFDM_48Mbps; + int8_t cTxPwr5GOFDM_54Mbps; + + int8_t cTxPwr5GHT20_BPSK; + int8_t cTxPwr5GHT20_QPSK; + int8_t cTxPwr5GHT20_16QAM; + int8_t cTxPwr5GHT20_MCS5; + int8_t cTxPwr5GHT20_MCS6; + int8_t cTxPwr5GHT20_MCS7; + + int8_t cTxPwr5GHT40_BPSK; + int8_t cTxPwr5GHT40_QPSK; + int8_t cTxPwr5GHT40_16QAM; + int8_t cTxPwr5GHT40_MCS5; + int8_t cTxPwr5GHT40_MCS6; + int8_t cTxPwr5GHT40_MCS7; +}; + +#if (CFG_SUPPORT_DFS_MASTER == 1) +struct PARAM_CUSTOM_SET_RDD_REPORT { + uint8_t ucDbdcIdx; /* 0:Band 0, 1: Band1 */ +}; + +struct PARAM_CUSTOM_SET_RADAR_DETECT_MODE { + /* 0:Switch channel, 1: Don't switch channel */ + uint8_t ucRadarDetectMode; +}; +#endif + +struct PARAM_CUSTOM_ACCESS_RX_STAT { + uint32_t u4SeqNum; + uint32_t u4TotalNum; +}; + +/* Ext DevInfo Tag */ +enum EXT_ENUM_DEVINFO_TAG_HANDLE { + DEV_INFO_ACTIVE = 0, + DEV_INFO_BSSID, + DEV_INFO_MAX_NUM +}; + +/* STA record TLV tag */ +enum EXT_ENUM_STAREC_TAG_HANDLE { + STA_REC_BASIC = 0, + STA_REC_RA, + STA_REC_RA_COMMON_INFO, + STA_REC_RA_UPDATE, + STA_REC_BF, + STA_REC_MAUNAL_ASSOC, + STA_REC_BA = 6, + STA_REC_MAX_NUM +}; + +#if CFG_SUPPORT_TX_BF +enum BF_ACTION_CATEGORY { + BF_SOUNDING_OFF = 0, + BF_SOUNDING_ON, + BF_DATA_PACKET_APPLY, + BF_PFMU_MEM_ALLOCATE, + BF_PFMU_MEM_RELEASE, + BF_PFMU_TAG_READ, + BF_PFMU_TAG_WRITE, + BF_PROFILE_READ, + BF_PROFILE_WRITE, + BF_PN_READ, + BF_PN_WRITE, + BF_PFMU_MEM_ALLOC_MAP_READ, +#if CFG_SUPPORT_TX_BF_FPGA + BF_PFMU_SW_TAG_WRITE = 23 +#endif +}; + +enum { + DEVINFO_ACTIVE = 0, + DEVINFO_MAX_NUM = 1, +}; + +enum { + DEVINFO_ACTIVE_FEATURE = (1 << DEVINFO_ACTIVE), + DEVINFO_MAX_NUM_FEATURE = (1 << DEVINFO_MAX_NUM) +}; + +enum { + BSS_INFO_OWN_MAC = 0, + BSS_INFO_BASIC = 1, + BSS_INFO_RF_CH = 2, + BSS_INFO_PM = 3, + BSS_INFO_UAPSD = 4, + BSS_INFO_ROAM_DETECTION = 5, + BSS_INFO_LQ_RM = 6, + BSS_INFO_EXT_BSS = 7, + BSS_INFO_BROADCAST_INFO = 8, + BSS_INFO_SYNC_MODE = 9, + BSS_INFO_MAX_NUM +}; + +union PFMU_PROFILE_TAG1 { + struct { + /* [6:0] : 0 ~ 63 */ + uint32_t ucProfileID: 7; + + /* [7] : 0: iBF, 1: eBF */ + uint32_t ucTxBf: 1; + + /* [9:8] : 0/1/2/3: DW20/40/80/160NC */ + uint32_t ucDBW: 2; + + /* [10] : 0:SU, 1: MU */ + uint32_t ucSU_MU: 1; + + /* [11] : 0: default, 1: This profile number is invalid by SW */ + uint32_t ucInvalidProf: 1; + + /* [14:12] : RMSD value from CE */ + uint32_t ucRMSD: 3; + + /* [17 : 15] : column index : 0 ~ 5 */ + uint32_t ucMemAddr1ColIdx: 3; + + /* [23 : 18] : row index : 0 ~ 63 */ + uint32_t ucMemAddr1RowIdx: 6; + + /* [26 : 24] : column index : 0 ~ 5 */ + uint32_t ucMemAddr2ColIdx: 3; + + /* [31 : 27] : row index : 0 ~ 63 */ + uint32_t ucMemAddr2RowIdx: 5; + + /* [32] : MSB of row index */ + uint32_t ucMemAddr2RowIdxMsb: 1; + + /* [35 : 33] : column index : 0 ~ 5 */ + uint32_t ucMemAddr3ColIdx: 3; + + /* [41 : 36] : row index : 0 ~ 63 */ + uint32_t ucMemAddr3RowIdx: 6; + + /* [44 : 42] : column index : 0 ~ 5 */ + uint32_t ucMemAddr4ColIdx: 3; + + /* [50 : 45] : row index : 0 ~ 63 */ + uint32_t ucMemAddr4RowIdx: 6; + + /* [51] : Reserved */ + uint32_t ucReserved: 1; + + /* [53 : 52] : Nrow */ + uint32_t ucNrow: 2; + + /* [55 : 54] : Ncol */ + uint32_t ucNcol: 2; + + /* [57 : 56] : Ngroup */ + uint32_t ucNgroup: 2; + + /* [59 : 58] : 0/1/2 */ + uint32_t ucLM: 2; + + /* [61:60] : Code book */ + uint32_t ucCodeBook: 2; + + /* [62] : HtcExist */ + uint32_t ucHtcExist: 1; + + /* [63] : Reserved */ + uint32_t ucReserved1: 1; + + /* [71:64] : SNR_STS0 */ + uint32_t ucSNR_STS0: 8; + + /* [79:72] : SNR_STS1 */ + uint32_t ucSNR_STS1: 8; + + /* [87:80] : SNR_STS2 */ + uint32_t ucSNR_STS2: 8; + + /* [95:88] : SNR_STS3 */ + uint32_t ucSNR_STS3: 8; + + /* [103:96] : iBF LNA index */ + uint32_t ucIBfLnaIdx: 8; + } rField; + uint32_t au4RawData[4]; +}; + +union PFMU_PROFILE_TAG2 { + struct { + uint32_t u2SmartAnt: 12;/* [11:0] : Smart Ant config */ + uint32_t ucReserved0: 3;/* [14:12] : Reserved */ + uint32_t ucSEIdx: 5; /* [19:15] : SE index */ + uint32_t ucRMSDThd: 3; /* [22:20] : RMSD Threshold */ + uint32_t ucReserved1: 1;/* [23] : Reserved */ + uint32_t ucMCSThL1SS: 4;/* [27:24] : MCS TH long 1SS */ + uint32_t ucMCSThS1SS: 4;/* [31:28] : MCS TH short 1SS */ + uint32_t ucMCSThL2SS: 4;/* [35:32] : MCS TH long 2SS */ + uint32_t ucMCSThS2SS: 4;/* [39:36] : MCS TH short 2SS */ + uint32_t ucMCSThL3SS: 4;/* [43:40] : MCS TH long 3SS */ + uint32_t ucMCSThS3SS: 4;/* [47:44] : MCS TH short 3SS */ + uint32_t uciBfTimeOut: 8;/* [55:48] : iBF timeout limit */ + uint32_t ucReserved2: 8;/* [63:56] : Reserved */ + uint32_t ucReserved3: 8;/* [71:64] : Reserved */ + uint32_t ucReserved4: 8;/* [79:72] : Reserved */ + uint32_t uciBfDBW: 2; /* [81:80] : iBF desired DBW 0/1/2/3 : + * BW20/40/80/160NC + */ + uint32_t uciBfNcol: 2; /* [83:82] : iBF desired Ncol = 1 ~ 3 */ + uint32_t uciBfNrow: 2; /* [85:84] : iBF desired Nrow = 1 ~ 4 */ + uint32_t u2Reserved5: 10;/* [95:86] : Reserved */ + } rField; + uint32_t au4RawData[3]; +}; + +union PFMU_DATA { + struct { + uint32_t u2Phi11: 9; + uint32_t ucPsi21: 7; + uint32_t u2Phi21: 9; + uint32_t ucPsi31: 7; + uint32_t u2Phi31: 9; + uint32_t ucPsi41: 7; + uint32_t u2Phi22: 9; + uint32_t ucPsi32: 7; + uint32_t u2Phi32: 9; + uint32_t ucPsi42: 7; + uint32_t u2Phi33: 9; + uint32_t ucPsi43: 7; + uint32_t u2dSNR00: 4; + uint32_t u2dSNR01: 4; + uint32_t u2dSNR02: 4; + uint32_t u2dSNR03: 4; + uint32_t u2Reserved: 16; + } rField; + uint32_t au4RawData[5]; +}; + +struct PROFILE_TAG_READ { + uint8_t ucTxBfCategory; + uint8_t ucProfileIdx; + u_int8_t fgBfer; + uint8_t ucRsv; +}; + +struct PROFILE_TAG_WRITE { + uint8_t ucTxBfCategory; + uint8_t ucPfmuId; + uint8_t ucBuffer[28]; +}; + +struct PROFILE_DATA_READ { + uint8_t ucTxBfCategory; + uint8_t ucPfmuIdx; + u_int8_t fgBFer; + uint8_t ucReserved[3]; + uint8_t ucSubCarrIdxLsb; + uint8_t ucSubCarrIdxMsb; +}; + +struct PROFILE_DATA_WRITE { + uint8_t ucTxBfCategory; + uint8_t ucPfmuIdx; + uint8_t u2SubCarrIdxLsb; + uint8_t u2SubCarrIdxMsb; + union PFMU_DATA rTxBfPfmuData; +}; + +struct PROFILE_PN_READ { + uint8_t ucTxBfCategory; + uint8_t ucPfmuIdx; + uint8_t ucReserved[2]; +}; + +struct PROFILE_PN_WRITE { + uint8_t ucTxBfCategory; + uint8_t ucPfmuIdx; + uint16_t u2bw; + uint8_t ucBuf[32]; +}; + +enum BF_SOUNDING_MODE { + SU_SOUNDING = 0, + MU_SOUNDING, + SU_PERIODIC_SOUNDING, + MU_PERIODIC_SOUNDING +}; + +struct EXT_CMD_ETXBf_SND_PERIODIC_TRIGGER_CTRL { + uint8_t ucCmdCategoryID; + uint8_t ucSuMuSndMode; + uint8_t ucWlanIdx; + uint32_t u4SoundingInterval; /* By ms */ +}; + +struct EXT_CMD_ETXBf_MU_SND_PERIODIC_TRIGGER_CTRL { + uint8_t ucCmdCategoryID; + uint8_t ucSuMuSndMode; + uint8_t ucWlanId[4]; + uint8_t ucStaNum; + uint32_t u4SoundingInterval; /* By ms */ +}; + +/* Device information (Tag0) */ +struct CMD_DEVINFO_ACTIVE { + uint16_t u2Tag; /* Tag = 0x00 */ + uint16_t u2Length; + uint8_t ucActive; + uint8_t ucBandNum; + uint8_t aucOwnMacAddr[6]; + uint8_t aucReserve[4]; +}; + +struct BSSINFO_BASIC { + /* Basic BSS information (Tag1) */ + uint16_t u2Tag; /* Tag = 0x01 */ + uint16_t u2Length; + uint32_t u4NetworkType; + uint8_t ucActive; + uint8_t ucReserve0; + uint16_t u2BcnInterval; + uint8_t aucBSSID[6]; + uint8_t ucWmmIdx; + uint8_t ucDtimPeriod; + uint8_t ucBcMcWlanidx; /* indicate which wlan-idx used for MC/BC + * transmission. + */ + uint8_t ucCipherSuit; + uint8_t acuReserve[6]; +}; + +struct TXBF_PFMU_STA_INFO { + uint16_t u2PfmuId; /* 0xFFFF means no access right for PFMU */ + uint8_t fgSU_MU; /* 0 : SU, 1 : MU */ + uint8_t fgETxBfCap; /* 0 : ITxBf, 1 : ETxBf */ + uint8_t ucSoundingPhy; /* 0: legacy, 1: OFDM, 2: HT, 4: VHT */ + uint8_t ucNdpaRate; + uint8_t ucNdpRate; + uint8_t ucReptPollRate; + uint8_t ucTxMode; /* 0: legacy, 1: OFDM, 2: HT, 4: VHT */ + uint8_t ucNc; + uint8_t ucNr; + uint8_t ucCBW; /* 0 : 20M, 1 : 40M, 2 : 80M, 3 : 80 + 80M */ + uint8_t ucTotMemRequire; + uint8_t ucMemRequire20M; + uint8_t ucMemRow0; + uint8_t ucMemCol0; + uint8_t ucMemRow1; + uint8_t ucMemCol1; + uint8_t ucMemRow2; + uint8_t ucMemCol2; + uint8_t ucMemRow3; + uint8_t ucMemCol3; + uint16_t u2SmartAnt; + uint8_t ucSEIdx; + uint8_t uciBfTimeOut; + uint8_t uciBfDBW; + uint8_t uciBfNcol; + uint8_t uciBfNrow; + uint8_t aucReserved[3]; +}; + +struct STA_REC_UPD_ENTRY { + struct TXBF_PFMU_STA_INFO rTxBfPfmuStaInfo; + uint8_t aucAddr[PARAM_MAC_ADDR_LEN]; + uint8_t ucAid; + uint8_t ucRsv; +}; + +struct STAREC_COMMON { + /* Basic STA record (Group0) */ + uint16_t u2Tag; /* Tag = 0x00 */ + uint16_t u2Length; + uint32_t u4ConnectionType; + uint8_t ucConnectionState; + uint8_t ucIsQBSS; + uint16_t u2AID; + uint8_t aucPeerMacAddr[6]; + uint16_t u2Reserve1; +}; + +struct CMD_STAREC_BF { + uint16_t u2Tag; /* Tag = 0x02 */ + uint16_t u2Length; + struct TXBF_PFMU_STA_INFO rTxBfPfmuInfo; + uint8_t ucReserved[3]; +}; + +/* QA tool: maunal assoc */ +struct CMD_MANUAL_ASSOC_STRUCT { + /* + * uint8_t ucBssIndex; + * uint8_t ucWlanIdx; + * uint16_t u2TotalElementNum; + * uint32_t u4Reserve; + */ + /* extension */ + uint16_t u2Tag; /* Tag = 0x05 */ + uint16_t u2Length; + uint8_t aucMac[MAC_ADDR_LEN]; + uint8_t ucType; + uint8_t ucWtbl; + uint8_t ucOwnmac; + uint8_t ucMode; + uint8_t ucBw; + uint8_t ucNss; + uint8_t ucPfmuId; + uint8_t ucMarate; + uint8_t ucSpeIdx; + uint8_t ucaid; +}; + +struct TX_BF_SOUNDING_START { + union { + struct EXT_CMD_ETXBf_SND_PERIODIC_TRIGGER_CTRL + rExtCmdExtBfSndPeriodicTriggerCtrl; + struct EXT_CMD_ETXBf_MU_SND_PERIODIC_TRIGGER_CTRL + rExtCmdExtBfMuSndPeriodicTriggerCtrl; + } rTxBfSounding; +}; + +struct TX_BF_SOUNDING_STOP { + uint8_t ucTxBfCategory; + uint8_t ucSndgStop; + uint8_t ucReserved[2]; +}; + +struct TX_BF_TX_APPLY { + uint8_t ucTxBfCategory; + uint8_t ucWlanId; + uint8_t fgETxBf; + uint8_t fgITxBf; + uint8_t fgMuTxBf; + uint8_t ucReserved[3]; +}; + +struct TX_BF_PFMU_MEM_ALLOC { + uint8_t ucTxBfCategory; + uint8_t ucSuMuMode; + uint8_t ucWlanIdx; + uint8_t ucReserved; +}; + +struct TX_BF_PFMU_MEM_RLS { + uint8_t ucTxBfCategory; + uint8_t ucWlanId; + uint8_t ucReserved[2]; +}; + +#if CFG_SUPPORT_TX_BF_FPGA +struct TX_BF_PROFILE_SW_TAG_WRITE { + uint8_t ucTxBfCategory; + uint8_t ucLm; + uint8_t ucNr; + uint8_t ucNc; + uint8_t ucBw; + uint8_t ucCodebook; + uint8_t ucgroup; + uint8_t ucReserved; +}; +#endif + +union PARAM_CUSTOM_TXBF_ACTION_STRUCT { + struct PROFILE_TAG_READ rProfileTagRead; + struct PROFILE_TAG_WRITE rProfileTagWrite; + struct PROFILE_DATA_READ rProfileDataRead; + struct PROFILE_DATA_WRITE rProfileDataWrite; + struct PROFILE_PN_READ rProfilePnRead; + struct PROFILE_PN_WRITE rProfilePnWrite; + struct TX_BF_SOUNDING_START rTxBfSoundingStart; + struct TX_BF_SOUNDING_STOP rTxBfSoundingStop; + struct TX_BF_TX_APPLY rTxBfTxApply; + struct TX_BF_PFMU_MEM_ALLOC rTxBfPfmuMemAlloc; + struct TX_BF_PFMU_MEM_RLS rTxBfPfmuMemRls; +#if CFG_SUPPORT_TX_BF_FPGA + struct TX_BF_PROFILE_SW_TAG_WRITE rTxBfProfileSwTagWrite; +#endif +}; + +struct PARAM_CUSTOM_STA_REC_UPD_STRUCT { + uint8_t ucBssIndex; + uint8_t ucWlanIdx; + uint16_t u2TotalElementNum; + uint8_t ucAppendCmdTLV; + uint8_t ucMuarIdx; + uint8_t aucReserve[2]; + uint32_t *prStaRec; + struct CMD_STAREC_BF rCmdStaRecBf; +}; + +struct BSSINFO_ARGUMENT { + uint8_t OwnMacIdx; + uint8_t ucBssIndex; + uint8_t Bssid[PARAM_MAC_ADDR_LEN]; + uint8_t ucBcMcWlanIdx; + uint8_t ucPeerWlanIdx; + uint32_t NetworkType; + uint32_t u4ConnectionType; + uint8_t CipherSuit; + uint8_t Active; + uint8_t WmmIdx; + uint32_t u4BssInfoFeature; + uint8_t aucBuffer[0]; +}; + +struct PARAM_CUSTOM_PFMU_TAG_READ_STRUCT { + union PFMU_PROFILE_TAG1 ru4TxBfPFMUTag1; + union PFMU_PROFILE_TAG2 ru4TxBfPFMUTag2; +}; + +#if CFG_SUPPORT_MU_MIMO +struct PARAM_CUSTOM_SHOW_GROUP_TBL_ENTRY_STRUCT { + uint32_t u4EventId; + uint8_t index; + uint8_t numUser: 2; + uint8_t BW: 2; + uint8_t NS0: 2; + uint8_t NS1: 2; + /* UINT_8 NS2:1; */ + /* UINT_8 NS3:1; */ + uint8_t PFIDUser0; + uint8_t PFIDUser1; + /* UINT_8 PFIDUser2; */ + /* UINT_8 PFIDUser3; */ + u_int8_t fgIsShortGI; + u_int8_t fgIsUsed; + u_int8_t fgIsDisable; + uint8_t initMcsUser0: 4; + uint8_t initMcsUser1: 4; + /* UINT_8 initMcsUser2:4; */ + /* UINT_8 initMcsUser3:4; */ + uint8_t dMcsUser0: 4; + uint8_t dMcsUser1: 4; + /* UINT_8 dMcsUser2:4; */ + /* UINT_8 dMcsUser3:4; */ +}; + +struct PARAM_CUSTOM_GET_QD_STRUCT { + uint32_t u4EventId; + uint32_t au4RawData[14]; +}; + +struct MU_STRUCT_LQ_REPORT { + int lq_report[NUM_OF_USER][NUM_OF_MODUL]; +}; + +struct PARAM_CUSTOM_GET_MU_CALC_LQ_STRUCT { + uint32_t u4EventId; + struct MU_STRUCT_LQ_REPORT rEntry; +}; + +struct MU_GET_CALC_INIT_MCS { + uint8_t ucgroupIdx; + uint8_t ucRsv[3]; +}; + +struct MU_SET_INIT_MCS { + uint8_t ucNumOfUser; /* zero-base: 0~3: means 1~2 users */ + uint8_t ucBandwidth; /* zero-base: 0:20 hz 1:40 hz 2: 80 hz 3: 160 */ + uint8_t ucNssOfUser0; /* zero-base: 0~1 means uesr0 use 1~2 ss, + * if no use keep 0 + */ + uint8_t ucNssOfUser1; /* zero-base: 0~1 means uesr0 use 1~2 ss, + * if no use keep 0 + */ + uint8_t ucPfMuIdOfUser0;/* zero-base: for now, uesr0 use pf mu id 0 */ + uint8_t ucPfMuIdOfUser1;/* zero-base: for now, uesr1 use pf mu id 1 */ + uint8_t ucNumOfTxer; /* 0~3: mean use 1~4 anntain, for now, + * should fix 3 + */ + uint8_t ucSpeIndex; /* add new field to fill"special extension + * index" which replace reserve + */ + uint32_t u4GroupIndex; /* 0~ :the index of group table entry for + * calculation + */ +}; + +struct MU_SET_CALC_LQ { + uint8_t ucNumOfUser; /* zero-base: 0~3: means 1~2 users */ + uint8_t ucBandwidth; /* zero-base: 0:20 hz 1:40 hz 2: 80 hz 3: 160 */ + uint8_t ucNssOfUser0; /* zero-base: 0~1 means uesr0 use 1~2 ss, + * if no use keep 0 + */ + uint8_t ucNssOfUser1; /* zero-base: 0~1 means uesr0 use 1~2 ss, + * if no use keep 0 + */ + uint8_t ucPfMuIdOfUser0;/* zero-base: for now, uesr0 use pf mu id 0 */ + uint8_t ucPfMuIdOfUser1;/* zero-base: for now, uesr1 use pf mu id 1 */ + uint8_t ucNumOfTxer; /* 0~3: mean use 1~4 anntain, for now, + * should fix 3 + */ + uint8_t ucSpeIndex; /* add new field to fill"special extension + * index" which replace reserve + */ + uint32_t u4GroupIndex; /* 0~ : the index of group table entry for + * calculation + */ +}; + +struct MU_GET_LQ { + uint8_t ucType; + uint8_t ucRsv[3]; +}; + +struct MU_SET_SNR_OFFSET { + uint8_t ucVal; + uint8_t ucRsv[3]; +}; + +struct MU_SET_ZERO_NSS { + uint8_t ucVal; + uint8_t ucRsv[3]; +}; + +struct MU_SPEED_UP_LQ { + uint32_t u4Val; +}; + +struct MU_SET_MU_TABLE { + /* UINT_16 u2Type; */ + /* UINT_32 u4Length; */ + uint8_t aucMetricTable[NUM_MUT_NR_NUM * NUM_MUT_FEC * + NUM_MUT_MCS * NUM_MUT_INDEX]; +}; + +struct MU_SET_GROUP { + uint32_t u4GroupIndex; /* Group Table Idx */ + uint32_t u4NumOfUser; + uint32_t u4User0Ldpc; + uint32_t u4User1Ldpc; + uint32_t u4ShortGI; + uint32_t u4Bw; + uint32_t u4User0Nss; + uint32_t u4User1Nss; + uint32_t u4GroupId; + uint32_t u4User0UP; + uint32_t u4User1UP; + uint32_t u4User0MuPfId; + uint32_t u4User1MuPfId; + uint32_t u4User0InitMCS; + uint32_t u4User1InitMCS; + uint8_t aucUser0MacAddr[PARAM_MAC_ADDR_LEN]; + uint8_t aucUser1MacAddr[PARAM_MAC_ADDR_LEN]; +}; + +struct MU_GET_QD { + uint8_t ucSubcarrierIndex; + /* UINT_32 u4Length; */ + /* UINT_8 *prQd; */ +}; + +struct MU_SET_ENABLE { + uint8_t ucVal; + uint8_t ucRsv[3]; +}; + +struct MU_SET_GID_UP { + uint32_t au4Gid[2]; + uint32_t au4Up[4]; +}; + +struct MU_TRIGGER_MU_TX { + uint8_t fgIsRandomPattern; /* is random pattern or not */ + uint32_t u4MsduPayloadLength0; /* payload length of the MSDU for + * user 0 + */ + uint32_t u4MsduPayloadLength1; /* payload length of the MSDU for + * user 1 + */ + uint32_t u4MuPacketCount; /* MU TX count */ + uint32_t u4NumOfSTAs; /* number of user in the MU TX */ + uint8_t aucMacAddrs[2][6]; /* MAC address of users*/ +}; + +struct PARAM_CUSTOM_MUMIMO_ACTION_STRUCT { + uint8_t ucMuMimoCategory; + uint8_t aucRsv[3]; + union { + struct MU_GET_CALC_INIT_MCS rMuGetCalcInitMcs; + struct MU_SET_INIT_MCS rMuSetInitMcs; + struct MU_SET_CALC_LQ rMuSetCalcLq; + struct MU_GET_LQ rMuGetLq; + struct MU_SET_SNR_OFFSET rMuSetSnrOffset; + struct MU_SET_ZERO_NSS rMuSetZeroNss; + struct MU_SPEED_UP_LQ rMuSpeedUpLq; + struct MU_SET_MU_TABLE rMuSetMuTable; + struct MU_SET_GROUP rMuSetGroup; + struct MU_GET_QD rMuGetQd; + struct MU_SET_ENABLE rMuSetEnable; + struct MU_SET_GID_UP rMuSetGidUp; + struct MU_TRIGGER_MU_TX rMuTriggerMuTx; + } unMuMimoParam; +}; +#endif /* CFG_SUPPORT_MU_MIMO */ +#endif /* CFG_SUPPORT_TX_BF */ +#endif /* CFG_SUPPORT_QA_TOOL */ + +struct PARAM_CUSTOM_MEM_DUMP_STRUCT { + uint32_t u4Address; + uint32_t u4Length; + uint32_t u4RemainLength; +#if CFG_SUPPORT_QA_TOOL + uint32_t u4IcapContent; +#endif /* CFG_SUPPORT_QA_TOOL */ + uint8_t ucFragNum; +}; + +struct PARAM_CUSTOM_SW_CTRL_STRUCT { + uint32_t u4Id; + uint32_t u4Data; +}; + +struct PARAM_CUSTOM_CHIP_CONFIG_STRUCT { + uint16_t u2Id; + uint8_t ucType; + uint8_t ucRespType; + uint16_t u2MsgSize; + uint8_t aucReserved0[2]; + uint8_t aucCmd[CHIP_CONFIG_RESP_SIZE]; +}; + +struct PARAM_CUSTOM_KEY_CFG_STRUCT { + uint8_t aucKey[WLAN_CFG_KEY_LEN_MAX]; + uint8_t aucValue[WLAN_CFG_VALUE_LEN_MAX]; + uint32_t u4Flag; +}; + +struct EEPROM_RW_INFO { + uint8_t ucEepromIndex; + uint8_t reserved; + uint16_t u2EepromData; +}; +struct NVRAM_RW_INFO { + uint16_t u2NvIndex; + uint16_t u2NvData; +}; + +struct PARAM_CUSTOM_EEPROM_RW_STRUCT { + uint8_t ucMethod; + union { + struct EEPROM_RW_INFO rEeprom; + struct NVRAM_RW_INFO rNvram; + } info; +}; + +struct PARAM_CUSTOM_WMM_PS_TEST_STRUCT { + uint8_t bmfgApsdEnAc; /* b0~3: trigger-en AC0~3. + * b4~7: delivery-en AC0~3 + */ + uint8_t ucIsEnterPsAtOnce; /* enter PS immediately without 5 second + * guard after connected + */ + uint8_t ucIsDisableUcTrigger; /* not to trigger UC on beacon TIM is + * matched (under U-APSD) + */ + uint8_t reserved; + uint8_t ucBssIdx; +}; + +struct PARAM_CUSTOM_NOA_PARAM_STRUCT { + uint32_t u4NoaDurationMs; + uint32_t u4NoaIntervalMs; + uint32_t u4NoaCount; + uint8_t ucBssIdx; +}; + +struct PARAM_CUSTOM_OPPPS_PARAM_STRUCT { + uint32_t u4CTwindowMs; + uint8_t ucBssIdx; +}; + +struct PARAM_CUSTOM_UAPSD_PARAM_STRUCT { + uint8_t ucBssIdx; + uint8_t fgEnAPSD; + uint8_t fgEnAPSD_AcBe; + uint8_t fgEnAPSD_AcBk; + uint8_t fgEnAPSD_AcVo; + uint8_t fgEnAPSD_AcVi; + uint8_t ucMaxSpLen; + uint8_t aucResv[2]; +}; + +struct PARAM_CUSTOM_P2P_SET_STRUCT { + uint32_t u4Enable; + uint32_t u4Mode; +}; + +#define MAX_NUMBER_OF_ACL 20 + +enum ENUM_PARAM_CUSTOM_ACL_POLICY { + PARAM_CUSTOM_ACL_POLICY_DISABLE, + PARAM_CUSTOM_ACL_POLICY_ACCEPT, + PARAM_CUSTOM_ACL_POLICY_DENY, + PARAM_CUSTOM_ACL_POLICY_NUM +}; + +struct PARAM_CUSTOM_ACL_ENTRY { + uint8_t aucAddr[MAC_ADDR_LEN]; + uint16_t u2Rsv; +}; + +struct PARAM_CUSTOM_ACL { + enum ENUM_PARAM_CUSTOM_ACL_POLICY ePolicy; + uint32_t u4Num; + struct PARAM_CUSTOM_ACL_ENTRY rEntry[MAX_NUMBER_OF_ACL]; +}; + +enum ENUM_CFG_SRC_TYPE { + CFG_SRC_TYPE_EEPROM, + CFG_SRC_TYPE_NVRAM, + CFG_SRC_TYPE_UNKNOWN, + CFG_SRC_TYPE_NUM +}; + +enum ENUM_EEPROM_TYPE { + EEPROM_TYPE_NO, + EEPROM_TYPE_PRESENT, + EEPROM_TYPE_NUM +}; + +enum ENUM_ICAP_STATE { + ICAP_STATE_INIT = 0, + ICAP_STATE_START = 1, + ICAP_STATE_QUERY_STATUS = 2, + ICAP_STATE_FW_DUMPING = 3, + ICAP_STATE_FW_DUMP_DONE = 4, + ICAP_STATE_QA_TOOL_CAPTURE = 5, + ICAP_STATE_NUM +}; + + +struct PARAM_QOS_TSINFO { + uint8_t ucTrafficType; /* Traffic Type: 1 for isochronous 0 for + * asynchronous + */ + uint8_t ucTid; /* TSID: must be between 8 ~ 15 */ + uint8_t ucDirection; /* direction */ + uint8_t ucAccessPolicy; /* access policy */ + uint8_t ucAggregation; /* aggregation */ + uint8_t ucApsd; /* APSD */ + uint8_t ucuserPriority; /* user priority */ + uint8_t ucTsInfoAckPolicy; /* TSINFO ACK policy */ + uint8_t ucSchedule; /* Schedule */ +}; + +struct PARAM_QOS_TSPEC { + struct PARAM_QOS_TSINFO rTsInfo; /* TS info field */ + uint16_t u2NominalMSDUSize; /* nominal MSDU size */ + uint16_t u2MaxMSDUsize; /* maximum MSDU size */ + uint32_t u4MinSvcIntv; /* minimum service interval */ + uint32_t u4MaxSvcIntv; /* maximum service interval */ + uint32_t u4InactIntv; /* inactivity interval */ + uint32_t u4SpsIntv; /* suspension interval */ + uint32_t u4SvcStartTime; /* service start time */ + uint32_t u4MinDataRate; /* minimum Data rate */ + uint32_t u4MeanDataRate; /* mean data rate */ + uint32_t u4PeakDataRate; /* peak data rate */ + uint32_t u4MaxBurstSize; /* maximum burst size */ + uint32_t u4DelayBound; /* delay bound */ + uint32_t u4MinPHYRate; /* minimum PHY rate */ + uint16_t u2Sba; /* surplus bandwidth allowance */ + uint16_t u2MediumTime; /* medium time */ + uint8_t ucDialogToken; +}; + +struct PARAM_QOS_ADDTS_REQ_INFO { + struct PARAM_QOS_TSPEC rTspec; +}; + +struct PARAM_VOIP_CONFIG { + uint32_t u4VoipTrafficInterval; /* 0: disable VOIP configuration */ +}; + +/*802.11 Statistics Struct*/ +struct PARAM_802_11_STATISTICS_STRUCT { + uint8_t ucInvalid; + union LARGE_INTEGER rTransmittedFragmentCount; + union LARGE_INTEGER rMulticastTransmittedFrameCount; + union LARGE_INTEGER rFailedCount; + union LARGE_INTEGER rRetryCount; + union LARGE_INTEGER rMultipleRetryCount; + union LARGE_INTEGER rRTSSuccessCount; + union LARGE_INTEGER rRTSFailureCount; + union LARGE_INTEGER rACKFailureCount; + union LARGE_INTEGER rFrameDuplicateCount; + union LARGE_INTEGER rReceivedFragmentCount; + union LARGE_INTEGER rMulticastReceivedFrameCount; + union LARGE_INTEGER rFCSErrorCount; + union LARGE_INTEGER rMdrdyCnt; + union LARGE_INTEGER rChnlIdleCnt; + uint32_t u4HwAwakeDuration; + uint32_t u4RstReason; + uint64_t u8RstTime; + uint32_t u4RoamFailCnt; + uint64_t u8RoamFailTime; + uint8_t u2TxDoneDelayIsARP; + uint32_t u4ArriveDrvTick; + uint32_t u4EnQueTick; + uint32_t u4DeQueTick; + uint32_t u4LeaveDrvTick; + uint32_t u4CurrTick; + uint64_t u8CurrTime; +}; + +/* Linux Network Device Statistics Struct */ +struct PARAM_LINUX_NETDEV_STATISTICS { + uint32_t u4RxPackets; + uint32_t u4TxPackets; + uint32_t u4RxBytes; + uint32_t u4TxBytes; + uint32_t u4RxErrors; + uint32_t u4TxErrors; + uint32_t u4Multicast; +}; + +struct PARAM_MTK_WIFI_TEST_STRUCT { + uint32_t u4FuncIndex; + uint32_t u4FuncData; +}; + +struct _RBIST_IQ_DATA_T { + int32_t u4IQArray[4][2]; /* IQ_Array[WF][IQ] */ +}; + +struct RECAL_DATA_T { + uint32_t u4CalId; + uint32_t u4CalAddr; + uint32_t u4CalValue; +}; + +struct RECAL_INFO_T { + u_int8_t fgDumped; + uint32_t u4Count; + struct RECAL_DATA_T *prCalArray; +}; + +struct ICAP_INFO_T { + enum ENUM_ICAP_STATE eIcapState; + uint32_t u4CapNode; + +#if CFG_SUPPORT_QA_TOOL + /* for MT6632/MT7668 file dump mode */ + uint16_t u2DumpIndex; + uint32_t au4Offset[2][2]; + uint32_t au4IQData[256]; + + /* for MT7663/Connad FW parser mode */ + uint32_t u4IQArrayIndex; + uint32_t u4ICapEventCnt; /* Count of packet getting from FW */ + uint32_t au4ICapDumpIndex[4][2];/* Count of packet sent to QA Tool, + * 4 WF * 2 I/Q + */ + struct _RBIST_IQ_DATA_T *prIQArray; +#endif +}; + +struct RF_TEST_CALIBRATION_T { + uint32_t u4FuncData; + uint8_t ucDbdcIdx; + uint8_t aucReserved[3]; +}; + +struct TX_TONE_PARAM_T { + uint8_t ucAntIndex; + uint8_t ucToneType; + uint8_t ucToneFreq; + uint8_t ucDbdcIdx; + int32_t i4DcOffsetI; + int32_t i4DcOffsetQ; + uint32_t u4Band; +}; + +struct CONTINUOUS_TX_PARAM_T { + uint8_t ucCtrlCh; + uint8_t ucCentralCh; + uint8_t ucBW; + uint8_t ucAntIndex; + uint16_t u2RateCode; + uint8_t ucBand; + uint8_t ucTxfdMode; +}; + +struct TX_TONE_POWER_GAIN_T { + uint8_t ucAntIndex; + uint8_t ucTonePowerGain; + uint8_t ucBand; + uint8_t aucReserved[1]; +}; + +struct EXT_CMD_RDD_ON_OFF_CTRL_T { + uint8_t ucDfsCtrl; + uint8_t ucRddIdx; + uint8_t ucRddRxSel; + uint8_t ucSetVal; + uint8_t aucReserved[4]; +}; + +struct SET_ADC_T { + uint32_t u4ChannelFreq; + uint8_t ucAntIndex; + uint8_t ucBW; + uint8_t ucSX; + uint8_t ucDbdcIdx; + uint8_t ucRunType; + uint8_t ucFType; + uint8_t aucReserved[2]; /* Reserving For future */ +}; + +struct SET_RX_GAIN_T { + uint8_t ucLPFG; + uint8_t ucLNA; + uint8_t ucDbdcIdx; + uint8_t ucAntIndex; +}; + +struct SET_TTG_T { + uint32_t u4ChannelFreq; + uint32_t u4ToneFreq; + uint8_t ucTTGPwrIdx; + uint8_t ucDbdcIdx; + uint8_t ucXtalFreq; + uint8_t aucReserved[1]; +}; + +struct TTG_ON_OFF_T { + uint8_t ucTTGEnable; + uint8_t ucDbdcIdx; + uint8_t ucAntIndex; + uint8_t aucReserved[1]; +}; + +struct RBIST_CAP_START_T { + uint32_t u4Trigger; + uint32_t u4RingCapEn; + uint32_t u4TriggerEvent; + uint32_t u4CaptureNode; + uint32_t u4CaptureLen; /* Unit : IQ Sample */ + uint32_t u4CapStopCycle; /* Unit : IQ Sample */ + uint32_t u4MacTriggerEvent; + uint32_t u4SourceAddressLSB; + uint32_t u4SourceAddressMSB; + uint32_t u4BandIdx; + uint32_t u4BW; + uint32_t u4EnBitWidth;/* 0:32bit, 1:96bit, 2:128bit */ + uint32_t u4Architech;/* 0:on-chip, 1:on-the-fly */ + uint32_t u4PhyIdx; + uint32_t u4EmiStartAddress; + uint32_t u4EmiEndAddress; + uint32_t u4EmiMsbAddress; + uint32_t u4CapSource; + uint32_t u4Reserved[2]; +}; + +struct RBIST_DUMP_IQ_T { + uint32_t u4WfNum; + uint32_t u4IQType; + uint32_t u4IcapCnt; /*IQ Sample Count*/ + uint32_t u4IcapDataLen; + uint8_t *pucIcapData; +}; + + +struct RBIST_DUMP_RAW_DATA_T { + uint32_t u4Address; + uint32_t u4AddrOffset; + uint32_t u4Bank; + uint32_t u4BankSize;/* Uint:Kbytes */ + uint32_t u4Reserved[8]; +}; + +/* FuncIndex */ +enum FUNC_IDX { + RE_CALIBRATION = 0x01, + CALIBRATION_BYPASS = 0x02, + TX_TONE_START = 0x03, + TX_TONE_STOP = 0x04, + CONTINUOUS_TX_START = 0x05, + CONTINUOUS_TX_STOP = 0x06, + RF_AT_EXT_FUNCID_TX_TONE_RF_GAIN = 0x07, + RF_AT_EXT_FUNCID_TX_TONE_DIGITAL_GAIN = 0x08, + CAL_RESULT_DUMP_FLAG = 0x09, + RDD_TEST_MODE = 0x0A, + SET_ICAP_CAPTURE_START = 0x0B, + GET_ICAP_CAPTURE_STATUS = 0x0C, + SET_ADC = 0x0D, + SET_RX_GAIN = 0x0E, + SET_TTG = 0x0F, + TTG_ON_OFF = 0x10, + GET_ICAP_RAW_DATA = 0x11 +}; + +struct PARAM_MTK_WIFI_TEST_STRUCT_EXT_T { + uint32_t u4FuncIndex; + union { + uint32_t u4FuncData; + uint32_t u4CalDump; + struct RF_TEST_CALIBRATION_T rCalParam; + struct TX_TONE_PARAM_T rTxToneParam; + struct CONTINUOUS_TX_PARAM_T rConTxParam; + struct TX_TONE_POWER_GAIN_T rTxToneGainParam; + struct RBIST_CAP_START_T rICapInfo; + struct RBIST_DUMP_RAW_DATA_T rICapDump; + struct EXT_CMD_RDD_ON_OFF_CTRL_T rRDDParam; + struct SET_ADC_T rSetADC; + struct SET_RX_GAIN_T rSetRxGain; + struct SET_TTG_T rSetTTG; + struct TTG_ON_OFF_T rTTGOnOff; + } Data; +}; + +/* 802.11 Media stream constraints */ +enum ENUM_MEDIA_STREAM_MODE { + ENUM_MEDIA_STREAM_OFF, + ENUM_MEDIA_STREAM_ON +}; + +/* for NDIS 5.1 Media Streaming Change */ +struct PARAM_MEDIA_STREAMING_INDICATION { + struct PARAM_STATUS_INDICATION rStatus; + enum ENUM_MEDIA_STREAM_MODE eMediaStreamMode; +}; + +#define PARAM_PROTOCOL_ID_DEFAULT 0x00 +#define PARAM_PROTOCOL_ID_TCP_IP 0x02 +#define PARAM_PROTOCOL_ID_IPX 0x06 +#define PARAM_PROTOCOL_ID_NBF 0x07 +#define PARAM_PROTOCOL_ID_MAX 0x0F +#define PARAM_PROTOCOL_ID_MASK 0x0F + +/* for NDIS OID_GEN_NETWORK_LAYER_ADDRESSES */ +struct PARAM_NETWORK_ADDRESS_IP { + uint16_t sin_port; + uint32_t in_addr; + uint8_t sin_zero[8]; +}; + +struct PARAM_NETWORK_ADDRESS { + uint16_t u2AddressLength;/* length in bytes of Address[] in this */ + uint16_t u2AddressType; /* type of this address + * (PARAM_PROTOCOL_ID_XXX above) + */ + uint8_t aucAddress[1]; /* actually AddressLength bytes long */ +}; + +/* The following is used with OID_GEN_NETWORK_LAYER_ADDRESSES to set network + * layer addresses on an interface + */ + +struct PARAM_NETWORK_ADDRESS_LIST { + uint8_t ucBssIdx; + uint32_t u4AddressCount;/* number of addresses following */ + uint16_t u2AddressType; /* type of this address + * (NDIS_PROTOCOL_ID_XXX above) + */ + struct PARAM_NETWORK_ADDRESS + arAddress[1]; /* actually AddressCount elements long */ +}; + +#if CFG_SLT_SUPPORT + +#define FIXED_BW_LG20 0x0000 +#define FIXED_BW_UL20 0x2000 +#define FIXED_BW_DL40 0x3000 + +#define FIXED_EXT_CHNL_U20 0x4000 /* For AGG register. */ +#define FIXED_EXT_CHNL_L20 0xC000 /* For AGG regsiter. */ + +enum ENUM_MTK_LP_TEST_MODE { + ENUM_MTK_LP_TEST_NORMAL, + ENUM_MTK_LP_TEST_GOLDEN_SAMPLE, + ENUM_MTK_LP_TEST_DUT, + ENUM_MTK_LP_TEST_MODE_NUM +}; + +enum ENUM_MTK_SLT_FUNC_IDX { + ENUM_MTK_SLT_FUNC_DO_NOTHING, + ENUM_MTK_SLT_FUNC_INITIAL, + ENUM_MTK_SLT_FUNC_RATE_SET, + ENUM_MTK_SLT_FUNC_LP_SET, + ENUM_MTK_SLT_FUNC_NUM +}; + +struct PARAM_MTK_SLT_LP_TEST_STRUCT { + enum ENUM_MTK_LP_TEST_MODE rLpTestMode; + uint32_t u4BcnRcvNum; +}; + +struct PARAM_MTK_SLT_TR_TEST_STRUCT { + enum ENUM_PARAM_NETWORK_TYPE + rNetworkType; /* Network Type OFDM5G or OFDM2.4G */ + uint32_t u4FixedRate; /* Fixed Rate including BW */ +}; + +struct PARAM_MTK_SLT_INITIAL_STRUCT { + uint8_t aucTargetMacAddr[PARAM_MAC_ADDR_LEN]; + uint16_t u2SiteID; +}; + +struct PARAM_MTK_SLT_TEST_STRUCT { + enum ENUM_MTK_SLT_FUNC_IDX rSltFuncIdx; + uint32_t u4Length; /* Length of structure, */ + /* including myself */ + uint32_t u4FuncInfoLen; /* Include following content */ + /* field and myself */ + union { + struct PARAM_MTK_SLT_INITIAL_STRUCT rMtkInitTest; + struct PARAM_MTK_SLT_LP_TEST_STRUCT rMtkLpTest; + struct PARAM_MTK_SLT_TR_TEST_STRUCT rMtkTRTest; + } unFuncInfoContent; + +}; + +#endif + +#if CFG_SUPPORT_MSP +/* Should by chip */ +struct PARAM_SEC_CONFIG { + u_int8_t fgWPIFlag; + u_int8_t fgRV; + u_int8_t fgIKV; + u_int8_t fgRKV; + + u_int8_t fgRCID; + u_int8_t fgRCA1; + u_int8_t fgRCA2; + u_int8_t fgEvenPN; + + uint8_t ucKeyID; + uint8_t ucMUARIdx; + uint8_t ucCipherSuit; + uint8_t aucReserved[1]; +}; + +struct PARAM_TX_CONFIG { + uint8_t aucPA[6]; + u_int8_t fgSW; + u_int8_t fgDisRxHdrTran; + + u_int8_t fgAADOM; + uint8_t ucPFMUIdx; + uint16_t u2PartialAID; + + u_int8_t fgTIBF; + u_int8_t fgTEBF; + u_int8_t fgIsHT; + u_int8_t fgIsVHT; + + u_int8_t fgMesh; + u_int8_t fgBAFEn; + u_int8_t fgCFAck; + u_int8_t fgRdgBA; + + u_int8_t fgRDG; + u_int8_t fgIsPwrMgt; + u_int8_t fgRTS; + u_int8_t fgSMPS; + + u_int8_t fgTxopPS; + u_int8_t fgDonotUpdateIPSM; + u_int8_t fgSkipTx; + u_int8_t fgLDPC; + + u_int8_t fgIsQoS; + u_int8_t fgIsFromDS; + u_int8_t fgIsToDS; + u_int8_t fgDynBw; + + u_int8_t fgIsAMSDUCrossLG; + u_int8_t fgCheckPER; + u_int8_t fgIsGID63; + u_int8_t fgIsHE; + + u_int8_t fgVhtTIBF; + u_int8_t fgVhtTEBF; + u_int8_t fgVhtLDPC; + u_int8_t fgHeLDPC; +}; + +struct PARAM_KEY_CONFIG { + uint8_t aucKey[32]; +}; + +struct PARAM_PEER_RATE_INFO { + uint8_t ucCounterMPDUFail; + uint8_t ucCounterMPDUTx; + uint8_t ucRateIdx; + uint8_t ucReserved[1]; + + uint16_t au2RateCode[AUTO_RATE_NUM]; +}; + +struct PARAM_PEER_BA_CONFIG { + uint8_t ucBaEn; + uint8_t ucRsv[3]; + uint32_t u4BaWinSize; +}; + +struct PARAM_ANT_ID_CONFIG { + uint8_t ucANTIDSts0; + uint8_t ucANTIDSts1; + uint8_t ucANTIDSts2; + uint8_t ucANTIDSts3; +}; + +struct PARAM_PEER_CAP { + struct PARAM_ANT_ID_CONFIG rAntIDConfig; + + uint8_t ucTxPowerOffset; + uint8_t ucCounterBWSelector; + uint8_t ucChangeBWAfterRateN; + uint8_t ucFrequencyCapability; + uint8_t ucSpatialExtensionIndex; + + u_int8_t fgG2; + u_int8_t fgG4; + u_int8_t fgG8; + u_int8_t fgG16; + + uint8_t ucMMSS; + uint8_t ucAmpduFactor; + uint8_t ucReserved[1]; +}; + +struct PARAM_PEER_RX_COUNTER_ALL { + uint8_t ucRxRcpi0; + uint8_t ucRxRcpi1; + uint8_t ucRxRcpi2; + uint8_t ucRxRcpi3; + + uint8_t ucRxCC0; + uint8_t ucRxCC1; + uint8_t ucRxCC2; + uint8_t ucRxCC3; + + u_int8_t fgRxCCSel; + uint8_t ucCeRmsd; + uint8_t aucReserved[2]; +}; + +struct PARAM_PEER_TX_COUNTER_ALL { + uint16_t u2Rate1TxCnt; + uint16_t u2Rate1FailCnt; + uint16_t u2Rate2OkCnt; + uint16_t u2Rate3OkCnt; + uint16_t u2CurBwTxCnt; + uint16_t u2CurBwFailCnt; + uint16_t u2OtherBwTxCnt; + uint16_t u2OtherBwFailCnt; +}; + +struct PARAM_HW_WLAN_INFO { + uint32_t u4Index; + struct PARAM_TX_CONFIG rWtblTxConfig; + struct PARAM_SEC_CONFIG rWtblSecConfig; + struct PARAM_KEY_CONFIG rWtblKeyConfig; + struct PARAM_PEER_RATE_INFO rWtblRateInfo; + struct PARAM_PEER_BA_CONFIG rWtblBaConfig; + struct PARAM_PEER_CAP rWtblPeerCap; + struct PARAM_PEER_RX_COUNTER_ALL rWtblRxCounter; + struct PARAM_PEER_TX_COUNTER_ALL rWtblTxCounter; +}; + +struct HW_TX_AMPDU_METRICS { + uint32_t u4TxSfCnt; + uint32_t u4TxAckSfCnt; + uint32_t u2TxAmpduCnt; + uint32_t u2TxRspBaCnt; + uint16_t u2TxEarlyStopCnt; + uint16_t u2TxRange1AmpduCnt; + uint16_t u2TxRange2AmpduCnt; + uint16_t u2TxRange3AmpduCnt; + uint16_t u2TxRange4AmpduCnt; + uint16_t u2TxRange5AmpduCnt; + uint16_t u2TxRange6AmpduCnt; + uint16_t u2TxRange7AmpduCnt; + uint16_t u2TxRange8AmpduCnt; + uint16_t u2TxRange9AmpduCnt; +#if (CFG_SUPPORT_802_11AX == 1) + uint16_t u2TxRange10AmpduCnt; + uint16_t u2TxRange11AmpduCnt; + uint16_t u2TxRange12AmpduCnt; + uint16_t u2TxRange13AmpduCnt; + uint16_t u2TxRange14AmpduCnt; + uint16_t u2TxRange15AmpduCnt; + uint16_t u2TxRange16AmpduCnt; +#endif +}; + +struct HW_MIB_COUNTER { + uint32_t u4RxFcsErrCnt; + uint32_t u4RxFifoFullCnt; + uint32_t u4RxMpduCnt; + uint32_t u4RxAMPDUCnt; + uint32_t u4RxTotalByte; + uint32_t u4RxValidAMPDUSF; + uint32_t u4RxValidByte; + uint32_t u4ChannelIdleCnt; + uint32_t u4RxVectorDropCnt; + uint32_t u4DelimiterFailedCnt; + uint32_t u4RxVectorMismatchCnt; + uint32_t u4MdrdyCnt; + uint32_t u4CCKMdrdyCnt; + uint32_t u4OFDMLGMixMdrdy; + uint32_t u4OFDMGreenMdrdy; + uint32_t u4PFDropCnt; + uint32_t u4RxLenMismatchCnt; + uint32_t u4PCcaTime; + uint32_t u4SCcaTime; + uint32_t u4CcaNavTx; + uint32_t u4PEDTime; + uint32_t u4BeaconTxCnt; + uint32_t au4BaMissedCnt[BSSID_NUM]; + uint32_t au4RtsTxCnt[BSSID_NUM]; + uint32_t au4FrameRetryCnt[BSSID_NUM]; + uint32_t au4FrameRetry2Cnt[BSSID_NUM]; + uint32_t au4RtsRetryCnt[BSSID_NUM]; + uint32_t au4AckFailedCnt[BSSID_NUM]; +}; + +struct HW_MIB2_COUNTER { + uint32_t u4Tx40MHzCnt; + uint32_t u4Tx80MHzCnt; + uint32_t u4Tx160MHzCnt; +}; + +struct PARAM_HW_MIB_INFO { + uint32_t u4Index; + struct HW_MIB_COUNTER rHwMibCnt; + struct HW_MIB2_COUNTER rHwMib2Cnt; + struct HW_TX_AMPDU_METRICS rHwTxAmpduMts; +}; +#endif + + +/*--------------------------------------------------------------*/ +/*! \brief For Fixed Rate Configuration (Registry) */ +/*--------------------------------------------------------------*/ +enum ENUM_REGISTRY_FIXED_RATE { + FIXED_RATE_NONE, + FIXED_RATE_1M, + FIXED_RATE_2M, + FIXED_RATE_5_5M, + FIXED_RATE_11M, + FIXED_RATE_6M, + FIXED_RATE_9M, + FIXED_RATE_12M, + FIXED_RATE_18M, + FIXED_RATE_24M, + FIXED_RATE_36M, + FIXED_RATE_48M, + FIXED_RATE_54M, + FIXED_RATE_MCS0_20M_800NS, + FIXED_RATE_MCS1_20M_800NS, + FIXED_RATE_MCS2_20M_800NS, + FIXED_RATE_MCS3_20M_800NS, + FIXED_RATE_MCS4_20M_800NS, + FIXED_RATE_MCS5_20M_800NS, + FIXED_RATE_MCS6_20M_800NS, + FIXED_RATE_MCS7_20M_800NS, + FIXED_RATE_MCS0_20M_400NS, + FIXED_RATE_MCS1_20M_400NS, + FIXED_RATE_MCS2_20M_400NS, + FIXED_RATE_MCS3_20M_400NS, + FIXED_RATE_MCS4_20M_400NS, + FIXED_RATE_MCS5_20M_400NS, + FIXED_RATE_MCS6_20M_400NS, + FIXED_RATE_MCS7_20M_400NS, + FIXED_RATE_MCS0_40M_800NS, + FIXED_RATE_MCS1_40M_800NS, + FIXED_RATE_MCS2_40M_800NS, + FIXED_RATE_MCS3_40M_800NS, + FIXED_RATE_MCS4_40M_800NS, + FIXED_RATE_MCS5_40M_800NS, + FIXED_RATE_MCS6_40M_800NS, + FIXED_RATE_MCS7_40M_800NS, + FIXED_RATE_MCS32_800NS, + FIXED_RATE_MCS0_40M_400NS, + FIXED_RATE_MCS1_40M_400NS, + FIXED_RATE_MCS2_40M_400NS, + FIXED_RATE_MCS3_40M_400NS, + FIXED_RATE_MCS4_40M_400NS, + FIXED_RATE_MCS5_40M_400NS, + FIXED_RATE_MCS6_40M_400NS, + FIXED_RATE_MCS7_40M_400NS, + FIXED_RATE_MCS32_400NS, + FIXED_RATE_NUM +}; + +enum ENUM_BT_CMD { + BT_CMD_PROFILE = 0, + BT_CMD_UPDATE, + BT_CMD_NUM +}; + +enum ENUM_BT_PROFILE { + BT_PROFILE_CUSTOM = 0, + BT_PROFILE_SCO, + BT_PROFILE_ACL, + BT_PROFILE_MIXED, + BT_PROFILE_NO_CONNECTION, + BT_PROFILE_NUM +}; + +struct PTA_PROFILE { + enum ENUM_BT_PROFILE eBtProfile; + union { + uint8_t aucBTPParams[BT_PROFILE_PARAM_LEN]; + /* 0: sco reserved slot time, + * 1: sco idle slot time, + * 2: acl throughput, + * 3: bt tx power, + * 4: bt rssi + * 5: VoIP interval + * 6: BIT(0) Use this field, BIT(1) 0 apply single/ 1 dual PTA + * setting. + */ + uint32_t au4Btcr[4]; + } u; +}; + +struct PTA_IPC { + uint8_t ucCmd; + uint8_t ucLen; + union { + struct PTA_PROFILE rProfile; + uint8_t aucBTPParams[BT_PROFILE_PARAM_LEN]; + } u; +}; + +/*--------------------------------------------------------------*/ +/*! \brief CFG80211 Scan Request Container */ +/*--------------------------------------------------------------*/ +struct PARAM_SCAN_REQUEST_EXT { + struct PARAM_SSID rSsid; + uint32_t u4IELength; + uint8_t *pucIE; + uint8_t ucBssIndex; +}; + +struct PARAM_SCAN_REQUEST_ADV { + uint32_t u4SsidNum; + struct PARAM_SSID rSsid[CFG_SCAN_SSID_MAX_NUM]; + uint8_t ucScanType; + uint32_t u4IELength; + uint8_t *pucIE; + uint32_t u4ChannelNum; + struct RF_CHANNEL_INFO + arChannel[MAXIMUM_OPERATION_CHANNEL_LIST]; + uint8_t ucScnFuncMask; + uint8_t aucRandomMac[MAC_ADDR_LEN]; + uint8_t ucBssIndex; + uint32_t u4Flags; +}; + +/*--------------------------------------------------------------*/ +/*! \brief CFG80211 Scheduled Scan Request Container */ +/*--------------------------------------------------------------*/ +#if CFG_SUPPORT_SCHED_SCAN +struct PARAM_SCHED_SCAN_REQUEST { + uint32_t u4SsidNum; /* passed in the probe_reqs */ + struct PARAM_SSID arSsid[CFG_SCAN_HIDDEN_SSID_MAX_NUM]; + uint32_t u4MatchSsidNum; /* matched for a scan request */ + struct PARAM_SSID arMatchSsid[CFG_SCAN_SSID_MATCH_MAX_NUM]; + int32_t ai4RssiThold[CFG_SCAN_SSID_MATCH_MAX_NUM]; + int32_t i4MinRssiThold; + uint8_t ucScnFuncMask; + uint8_t aucRandomMac[MAC_ADDR_LEN]; + uint8_t aucRandomMacMask[MAC_ADDR_LEN]; + uint32_t u4IELength; + uint8_t *pucIE; + uint16_t u2ScanInterval; /* in second */ + uint8_t ucChnlNum; + uint8_t *pucChannels; + uint8_t ucBssIndex; +}; +#endif /* CFG_SUPPORT_SCHED_SCAN */ + +#if CFG_SUPPORT_PASSPOINT +struct PARAM_HS20_SET_BSSID_POOL { + u_int8_t fgIsEnable; + uint8_t ucNumBssidPool; + uint8_t arBSSID[8][PARAM_MAC_ADDR_LEN]; + uint8_t ucBssIndex; +}; + +#endif /* CFG_SUPPORT_PASSPOINT */ + +#if CFG_SUPPORT_SNIFFER +struct PARAM_CUSTOM_MONITOR_SET_STRUCT { + uint8_t ucEnable; + uint8_t ucBand; + uint8_t ucPriChannel; + uint8_t ucSco; + uint8_t ucChannelWidth; + uint8_t ucChannelS1; + uint8_t ucChannelS2; + uint8_t aucResv[9]; +}; +#endif + +/*--------------------------------------------------------------*/ +/*! \brief MTK Auto Channel Selection related Container */ +/*--------------------------------------------------------------*/ +enum ENUM_SAFE_CH_MASK { + ENUM_SAFE_CH_MASK_BAND_2G4 = 0, + ENUM_SAFE_CH_MASK_BAND_5G_0 = 1, + ENUM_SAFE_CH_MASK_BAND_5G_1 = 2, + ENUM_SAFE_CH_MASK_BAND_5G_2 = 3, + ENUM_SAFE_CH_MASK_MAX_NUM = 4, +}; + +struct LTE_SAFE_CHN_INFO { + /* ENUM_SAFE_CH_MASK_MAX_NUM */ + uint32_t au4SafeChannelBitmask[ENUM_SAFE_CH_MASK_MAX_NUM]; +}; + +struct PARAM_CHN_LOAD_INFO { + /* Per-CHN Load */ + uint8_t ucChannel; + uint16_t u2APNum; + uint32_t u4Dirtiness; + uint8_t ucReserved; +}; + +struct PARAM_CHN_RANK_INFO { + uint8_t ucChannel; + uint32_t u4Dirtiness; + uint8_t ucReserved; +}; + +struct PARAM_GET_CHN_INFO { + uint8_t ucRoleIndex; + struct LTE_SAFE_CHN_INFO rLteSafeChnList; + struct PARAM_CHN_LOAD_INFO rEachChnLoad[MAX_CHN_NUM]; + struct PARAM_CHN_RANK_INFO rChnRankList[MAX_CHN_NUM]; + uint8_t aucReserved[3]; +}; + +struct PARAM_PREFER_CHN_INFO { + uint8_t ucChannel; + uint8_t aucReserved[3]; + uint32_t u4Dirtiness; +}; + +struct UMAC_STAT2_GET { + uint16_t u2PleRevPgHif0Group0; + uint16_t u2PleRevPgCpuGroup2; + + uint16_t u2PseRevPgHif0Group0; + uint16_t u2PseRevPgHif1Group1; + uint16_t u2PseRevPgCpuGroup2; + uint16_t u2PseRevPgLmac0Group3; + uint16_t u2PseRevPgLmac1Group4; + uint16_t u2PseRevPgLmac2Group5; + uint16_t u2PseRevPgPleGroup6; + + uint16_t u2PleSrvPgHif0Group0; + uint16_t u2PleSrvPgCpuGroup2; + + uint16_t u2PseSrvPgHif0Group0; + uint16_t u2PseSrvPgHif1Group1; + uint16_t u2PseSrvPgCpuGroup2; + uint16_t u2PseSrvPgLmac0Group3; + uint16_t u2PseSrvPgLmac1Group4; + uint16_t u2PseSrvPgLmac2Group5; + uint16_t u2PseSrvPgPleGroup6; + + uint16_t u2PleTotalPageNum; + uint16_t u2PleFreePageNum; + uint16_t u2PleFfaNum; + + uint16_t u2PseTotalPageNum; + uint16_t u2PseFreePageNum; + uint16_t u2PseFfaNum; +}; + +struct CNM_STATUS { + uint8_t fgDbDcModeEn; + uint8_t ucChNumB0; + uint8_t ucChNumB1; + uint8_t usReserved; +}; + +struct CNM_CH_LIST { + uint8_t ucChNum[4]; +}; + +struct EXT_CMD_SER_T { + uint8_t ucAction; + uint8_t ucSerSet; + uint8_t ucDbdcIdx; + uint8_t aucReserve[1]; +}; + +#if (CFG_SUPPORT_TXPOWER_INFO == 1) +struct HAL_FRAME_POWER_SET_T { + int8_t icFramePowerDbm; +}; + +struct FRAME_POWER_CONFIG_INFO_T { + struct HAL_FRAME_POWER_SET_T + aicFramePowerConfig[TXPOWER_RATE_NUM][ENUM_BAND_NUM]; +}; + +struct PARAM_TXPOWER_ALL_RATE_POWER_INFO_T { + uint8_t ucTxPowerCategory; + uint8_t ucBandIdx; + uint8_t ucChBand; + uint8_t u1Format;/*0:Legacy,1:HE format*/ + + /* Rate power info */ + struct FRAME_POWER_CONFIG_INFO_T rRatePowerInfo; + + /* tx Power Max/Min Limit info */ + int8_t icPwrMaxBnd; + int8_t icPwrMinBnd; + int8_t ucReserved2; +}; +#endif + + +struct PARAM_TXPOWER_BY_RATE_SET_T { + uint8_t u1PhyMode; + uint8_t u1TxRate; + uint8_t u1BW; + int8_t i1TxPower; +}; + +#if CFG_SUPPORT_OSHARE +/* OSHARE Mode */ +#define MAX_OSHARE_MODE_LENGTH 64 +#define OSHARE_MODE_MAGIC_CODE 0x18 +#define OSHARE_MODE_CMD_V1 0x1 + +struct OSHARE_MODE_T { + uint8_t cmdVersion; /* CMD version = OSHARE_MODE_CMD_V1 */ + uint8_t cmdType; /* 1-set 0-query */ + uint8_t magicCode; /* It's like CRC, OSHARE_MODE_MAGIC_CODE */ + uint8_t cmdBufferLen; /* buffer length <= 64 */ + uint8_t buffer[MAX_OSHARE_MODE_LENGTH]; +}; + +struct OSHARE_MODE_SETTING_V1_T { + uint8_t osharemode; /* 0: disable, 1:Enable */ + uint8_t reserved[7]; +}; +#endif + +struct PARAM_WIFI_LOG_LEVEL_UI { + uint32_t u4Version; + uint32_t u4Module; + uint32_t u4Enable; +}; + +struct PARAM_WIFI_LOG_LEVEL { + uint32_t u4Version; + uint32_t u4Module; + uint32_t u4Level; +}; + +struct PARAM_GET_WIFI_TYPE { + struct net_device *prNetDev; + uint8_t arWifiTypeName[8]; +}; + +enum ENUM_WIFI_LOG_LEVEL_VERSION_T { + ENUM_WIFI_LOG_LEVEL_VERSION_V1 = 1, + ENUM_WIFI_LOG_LEVEL_VERSION_NUM +}; + +enum ENUM_WIFI_LOG_LEVEL_T { + ENUM_WIFI_LOG_LEVEL_DEFAULT = 0, + ENUM_WIFI_LOG_LEVEL_MORE, + ENUM_WIFI_LOG_LEVEL_EXTREME, + ENUM_WIFI_LOG_LEVEL_NUM +}; + +enum ENUM_WIFI_LOG_MODULE_T { + ENUM_WIFI_LOG_MODULE_DRIVER = 0, + ENUM_WIFI_LOG_MODULE_FW, + ENUM_WIFI_LOG_MODULE_NUM, +}; + +enum ENUM_WIFI_LOG_LEVEL_SUPPORT_T { + ENUM_WIFI_LOG_LEVEL_SUPPORT_DISABLE = 0, + ENUM_WIFI_LOG_LEVEL_SUPPORT_ENABLE, + ENUM_WIFI_LOG_LEVEL_SUPPORT_NUM +}; + +#ifdef CFG_SUPPORT_LINK_QUALITY_MONITOR +struct PARAM_GET_LINK_QUALITY_INFO { + uint8_t ucBssIdx; + struct WIFI_LINK_QUALITY_INFO *prLinkQualityInfo; +}; +#endif /* CFG_SUPPORT_LINK_QUALITY_MONITOR */ + +#if CFG_SUPPORT_MBO +struct PARAM_BSS_DISALLOWED_LIST { + uint32_t u4NumBssDisallowed; + /* MAX_FW_ROAMING_BLACKLIST_SIZE */ + uint8_t aucList[MAC_ADDR_LEN * 16]; +}; +#endif +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +/*--------------------------------------------------------------*/ +/* Routines to set parameters or query information. */ +/*--------------------------------------------------------------*/ +/***** Routines in wlan_oid.c *****/ +uint32_t +wlanoidQueryNetworkTypesSupported(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidQueryNetworkTypeInUse(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetNetworkTypeInUse(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryBssid(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetBssidListScan(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidSetBssidListScanExt(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidSetBssidListScanAdv(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryBssidList(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetBssid(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidSetConnect(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidSetSsid(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQuerySsid(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidQueryInfrastructureMode(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetInfrastructureMode(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryAuthMode(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetAuthMode(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidSetAuthorized(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +#if 0 +uint32_t +wlanoidQueryPrivacyFilter(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetPrivacyFilter(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); +#endif + +uint32_t +wlanoidSetEncryptionStatus(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryEncryptionStatus(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetAddWep(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidSetRemoveWep(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidSetAddKey(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidSetRemoveKey(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanSetRemoveKey(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen, IN uint8_t fgIsOid); + +uint32_t +wlanoidSetReloadDefaults(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryCapability(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidQueryFrequency(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetFrequency(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryAtimWindow(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetAtimWindow(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidSetChannel(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidRssiMonitor(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidQueryRssi(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidQueryRssiTrigger(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetRssiTrigger(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryRtsThreshold(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetRtsThreshold(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQuery802dot11PowerSaveProfile(IN struct ADAPTER + *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSet802dot11PowerSaveProfile(IN struct ADAPTER + *prAdapter, + IN void *prSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidSetPmkid(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidDelPmkid(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidFlushPmkid(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQuerySupportedRates(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidQueryDesiredRates(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetDesiredRates(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryPermanentAddr(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuf, + IN uint32_t u4QueryBufLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidQueryCurrentAddr(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuf, + IN uint32_t u4QueryBufLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidQueryPermanentAddr(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuf, + IN uint32_t u4QueryBufLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidQueryMaxLinkSpeed(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidQueryLinkSpeed(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanQueryLinkSpeed(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen, + IN uint8_t fgIsOid); + +uint32_t +wlanoidQueryLinkSpeedEx(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +#if CFG_SUPPORT_QA_TOOL +#if CFG_SUPPORT_BUFFER_MODE +uint32_t wlanoidSetEfusBufferMode(IN struct ADAPTER + *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t wlanoidConnacSetEfusBufferMode(IN struct ADAPTER + *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +/* #if (CFG_EEPROM_PAGE_ACCESS == 1) */ +uint32_t +wlanoidQueryProcessAccessEfuseRead(IN struct ADAPTER + *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryProcessAccessEfuseWrite(IN struct ADAPTER + *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryEfuseFreeBlock(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryGetTxPower(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); +/*#endif*/ + +#endif /* CFG_SUPPORT_BUFFER_MODE */ +uint32_t +wlanoidQueryRxStatistics(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidBssInfoBasic(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidDevInfoActive(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidManualAssoc(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +#if CFG_SUPPORT_TX_BF +uint32_t +wlanoidTxBfAction(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t wlanoidMuMimoAction(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t wlanoidStaRecUpdate(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t wlanoidStaRecBFUpdate(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); +#endif /* CFG_SUPPORT_TX_BF */ +#endif /* CFG_SUPPORT_QA_TOOL */ + +#if CFG_SUPPORT_CAL_RESULT_BACKUP_TO_HOST +uint32_t +wlanoidSendCalBackupV2Cmd(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen); + +uint32_t +wlanoidSetCalBackup(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryCalBackupV2(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); +#endif + +#if CFG_SUPPORT_SMART_GEAR +uint32_t +wlandioSetSGStatus(IN struct ADAPTER *prAdapter, + IN uint8_t ucSGEnable, + IN uint8_t ucSGSpcCmd, + IN uint8_t ucNSS); +#endif + +uint32_t +wlanoidQueryMcrRead(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidQueryMemDump(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetMcrWrite(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryDrvMcrRead(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetDrvMcrWrite(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQuerySwCtrlRead(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetSwCtrlWrite(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidSetChipConfig(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryChipConfig(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetKeyCfg(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryEepromRead(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetEepromWrite(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryRfTestRxStatus(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidQueryRfTestTxStatus(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidQueryOidInterfaceVersion(IN struct ADAPTER + *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidQueryVendorId(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidQueryMulticastList(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetMulticastList(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryRcvError(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidQueryRcvNoBuffer(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidQueryRcvCrcError(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidQueryStatistics(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidQueryBugReport(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +#ifdef LINUX + +uint32_t +wlanoidQueryStatisticsForLinux(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +#endif + +uint32_t +wlanoidQueryMediaStreamMode(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetMediaStreamMode(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryRcvOk(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidQueryXmitOk(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidQueryXmitError(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidQueryXmitOneCollision(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidQueryXmitMoreCollisions(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidQueryXmitMaxCollisions(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetCurrentPacketFilter(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t wlanoidSetPacketFilter(struct ADAPTER *prAdapter, + void *pvPacketFiltr, + u_int8_t fgIsOid, + void *pvSetBuffer, + uint32_t u4SetBufferLen); + +uint32_t +wlanoidQueryCurrentPacketFilter(IN struct ADAPTER + *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetAcpiDevicePowerState(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryAcpiDevicePowerState(IN struct ADAPTER + *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetDisassociate(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryFragThreshold(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetFragThreshold(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryAdHocMode(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetAdHocMode(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryBeaconInterval(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetBeaconInterval(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidSetCurrentAddr(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +#if CFG_TCP_IP_CHKSUM_OFFLOAD +uint32_t +wlanoidSetCSUMOffload(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ + +uint32_t +wlanoidSetNetworkAddress(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryMaxFrameSize(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidQueryMaxTotalSize(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetCurrentLookahead(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +/* RF Test related APIs */ +uint32_t +wlanoidRftestSetTestMode(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidRftestSetTestIcapMode(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidRftestSetAbortTestMode(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidRftestQueryAutoTest(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidRftestSetAutoTest(IN struct ADAPTER *prAdapter, + OUT void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); +uint32_t +wlanoidExtRfTestICapStart(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); +uint32_t +wlanoidExtRfTestICapStatus(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +void wlanoidRfTestICapRawDataProc(IN struct ADAPTER *prAdapter, + uint32_t u4CapStartAddr, + uint32_t u4TotalBufferSize); + +#if CFG_SUPPORT_WAPI +uint32_t +wlanoidSetWapiMode(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidSetWapiAssocInfo(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidSetWapiKey(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); +#endif + +#if CFG_ENABLE_WAKEUP_ON_LAN +uint32_t +wlanoidSetAddWakeupPattern(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidSetRemoveWakeupPattern(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryEnableWakeup(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *u4QueryInfoLen); + +uint32_t +wlanoidSetEnableWakeup(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); +#endif + +uint32_t +wlanoidSetWiFiWmmPsTest(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidSetTxAmpdu(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidSetAddbaReject(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryNvramRead(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetNvramWrite(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryCfgSrcType(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidQueryEepromType(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetCountryCode(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidSetScanMacOui(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t wlanSendMemDumpCmd(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen); + +#if CFG_SLT_SUPPORT + +uint32_t +wlanoidQuerySLTStatus(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidUpdateSLTMode(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +#endif + +uint32_t +wlanoidQueryWlanInfo(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanQueryWlanInfo(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen, + IN uint8_t fgIsOid); + +uint32_t +wlanoidQueryMibInfo(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanQueryMibInfo(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen, + IN uint8_t fgIsOid); + +uint32_t +wlanoidSetFwLog2Host(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +#if 0 +uint32_t +wlanoidSetNoaParam(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidSetOppPsParam(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidSetUApsdParam(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); +#endif + +/*----------------------------------------------------------------------------*/ +uint32_t +wlanoidSetBT(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryBT(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetTxPower(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +#if 0 +uint32_t +wlanoidQueryBtSingleAntenna( + IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetBtSingleAntenna( + IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidSetPta( + IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryPta( + IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); +#endif + +#if CFG_ENABLE_WIFI_DIRECT +uint32_t +wlanoidSetP2pMode(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); +#endif + +uint32_t +wlanoidSetDefaultKey(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidSetGtkRekeyData(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +#if CFG_SUPPORT_SCHED_SCAN +uint32_t +wlanoidSetStartSchedScan(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidSetStopSchedScan(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); +#endif /* CFG_SUPPORT_SCHED_SCAN */ + +#if CFG_M0VE_BA_TO_DRIVER +uint32_t wlanoidResetBAScoreboard(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen); +#endif + +#if CFG_SUPPORT_BATCH_SCAN +uint32_t +wlanoidSetBatchScanReq(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryBatchScanResult(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); +#endif + +#if CFG_SUPPORT_PASSPOINT +uint32_t +wlanoidSetHS20Info(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidSetHS20BssidPool(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); +#endif /* CFG_SUPPORT_PASSPOINT */ + +#if CFG_SUPPORT_SNIFFER +uint32_t wlanoidSetMonitor(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); +#endif + +uint32_t +wlanoidNotifyFwSuspend(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryCnm( + IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidPacketKeepAlive(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +#if CFG_SUPPORT_DBDC +uint32_t +wlanoidSetDbdcEnable(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); +#endif /*#if CFG_SUPPORT_DBDC*/ + +uint32_t +wlanoidQuerySetTxTargetPower(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +#if (CFG_SUPPORT_DFS_MASTER == 1) +uint32_t +wlanoidQuerySetRddReport(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQuerySetRadarDetectMode(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); +#endif + +uint32_t +wlanoidLinkDown(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidDisableTdlsPs(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t wlanoidSetSer(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t wlanoidSerExtCmd(IN struct ADAPTER *prAdapter, + uint8_t ucAction, + uint8_t ucSerSet, + uint8_t ucDbdcIdx); + +#if CFG_SUPPORT_NCHO +#define NCHO_CMD_MAX_LENGTH 128 + +uint32_t +wlanoidSetNchoRoamTrigger(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryNchoRoamTrigger(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetNchoRoamDelta(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryNchoRoamDelta(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetNchoRoamScnPeriod(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryNchoRoamScnPeriod(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetNchoRoamScnChnl(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidAddNchoRoamScnChnl(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryNchoRoamScnChnl(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetNchoRoamScnCtrl(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryNchoRoamScnCtrl(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetNchoScnChnlTime(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryNchoScnChnlTime(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetNchoScnHomeTime(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryNchoScnHomeTime(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetNchoScnHomeAwayTime(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryNchoScnHomeAwayTime(IN struct ADAPTER + *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetNchoScnNprobes(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryNchoScnNprobes(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidGetNchoReassocInfo(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSendNchoActionFrameStart(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidSendNchoActionFrameEnd(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidSetNchoWesMode(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryNchoWesMode(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetNchoBand(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryNchoBand(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetNchoDfsScnMode(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryNchoDfsScnMode(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetNchoEnable(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryNchoEnable(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +#endif /* CFG_SUPPORT_NCHO */ + +uint32_t +wlanoidAddRoamScnChnl(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidAbortScan(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t wlanoidSetDrvSer(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); +uint32_t wlanoidSetAmsduNum(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); +uint32_t wlanoidSetAmsduSize(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +/* Show Consys debug information*/ +uint32_t +wlanoidShowPdmaInfo(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); +uint32_t +wlanoidShowPseInfo(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); +uint32_t +wlanoidShowPleInfo(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); +uint32_t +wlanoidShowCsrInfo(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); +uint32_t +wlanoidShowDmaschInfo(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); +/* end Show Consys debug information*/ + +uint32_t +wlanoidSetTxPowerByRateManual(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +#if (CFG_SUPPORT_TXPOWER_INFO == 1) +uint32_t +wlanoidQueryTxPowerInfo(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); +#endif + +#if CFG_SUPPORT_MBO +uint32_t wlanoidBssDisallowedList(IN struct ADAPTER + *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +#endif + +uint32_t wlanoidSetDrvRoamingPolicy(IN struct ADAPTER + *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +#if CFG_SUPPORT_OSHARE +uint32_t +wlanoidSetOshareMode(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); +#endif + +uint32_t +wlanoidQueryWifiLogLevelSupport(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidQueryWifiLogLevel(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetWifiLogLevel(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +#if CFG_SUPPORT_LOWLATENCY_MODE +uint32_t +wlanoidSetLowLatencyMode(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); +#endif /* CFG_SUPPORT_LOWLATENCY_MODE */ + +#if CFG_SUPPORT_ANT_SWAP +uint32_t wlanoidQueryAntennaSwap(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); +#endif + + +#if CFG_SUPPORT_EASY_DEBUG +uint32_t wlanoidSetFwParam(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); +#endif /* CFG_SUPPORT_EASY_DEBUG */ + +uint32_t wlanoidUpdateFtIes(IN struct ADAPTER *prAdapter, IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t wlanoidSync11kCapabilities(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t wlanoidSendNeighborRequest(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t wlanoidSendBTMQuery(IN struct ADAPTER *prAdapter, IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t wlanoidPktProcessIT(struct ADAPTER *prAdapter, void *pvBuffer, + uint32_t u4BufferLen, uint32_t *pu4InfoLen); + +uint32_t wlanoidFwEventIT(struct ADAPTER *prAdapter, void *pvBuffer, + uint32_t u4BufferLen, uint32_t *pu4InfoLen); + +uint32_t wlanoidTspecOperation(IN struct ADAPTER *prAdapter, IN void *pvBuffer, + IN uint32_t u4BufferLen, + OUT uint32_t *pu4InfoLen); + +uint32_t wlanoidDumpUapsdSetting(struct ADAPTER *prAdapter, void *pvBuffer, + uint32_t u4BufferLen, uint32_t *pu4InfoLen); + +uint32_t wlanoidGetWifiType(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t wlanoidRfTestICapGetIQData(IN struct ADAPTER *prAdapter, + OUT void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + + +#ifdef CFG_SUPPORT_LINK_QUALITY_MONITOR +uint32_t wlanoidGetLinkQualityInfo(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); +#endif /* CFG_SUPPORT_LINK_QUALITY_MONITOR */ + +#if CFG_SUPPORT_DYNAMIC_PWR_LIMIT +/* dynamic tx power control */ +uint32_t wlanoidTxPowerControl(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); +#endif + +uint32_t +wlanoidExternalAuthDone(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); +uint32_t +wlanoidIndicateBssInfo(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +#endif /* _WLAN_OID_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/wlan_p2p.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/wlan_p2p.h new file mode 100644 index 0000000000000000000000000000000000000000..bad8fdd0cd06e8817ac4a9541190f2fd685d8143 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/wlan_p2p.h @@ -0,0 +1,318 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/wlan_p2p.h#3 + */ + +/*! \file "wlan_p2p.h" + * \brief This file contains the declairations of Wi-Fi Direct command + * processing routines for MediaTek Inc. 802.11 Wireless LAN Adapters. + */ + + +#ifndef _WLAN_P2P_H +#define _WLAN_P2P_H + +/****************************************************************************** + * C O M P I L E R F L A G S + ****************************************************************************** + */ + +/****************************************************************************** + * E X T E R N A L R E F E R E N C E S + ****************************************************************************** + */ + +#if CFG_ENABLE_WIFI_DIRECT +/****************************************************************************** + * C O N S T A N T S + ****************************************************************************** + */ + +/****************************************************************************** + * P U B L I C D A T A + ****************************************************************************** + */ + +/* Service Discovery */ +struct PARAM_P2P_SEND_SD_RESPONSE { + uint8_t rReceiverAddr[PARAM_MAC_ADDR_LEN]; + uint8_t fgNeedTxDoneIndication; + uint8_t ucChannelNum; + uint16_t u2PacketLength; + uint8_t aucPacketContent[0]; /*native 802.11 */ +}; + +struct PARAM_P2P_GET_SD_REQUEST { + uint8_t rTransmitterAddr[PARAM_MAC_ADDR_LEN]; + uint16_t u2PacketLength; + uint8_t aucPacketContent[0]; /*native 802.11 */ +}; + +struct PARAM_P2P_GET_SD_REQUEST_EX { + uint8_t rTransmitterAddr[PARAM_MAC_ADDR_LEN]; + uint16_t u2PacketLength; + /* Channel Number Where SD Request is received. */ + uint8_t ucChannelNum; + uint8_t ucSeqNum; /* Get SD Request by sequence number. */ + uint8_t aucPacketContent[0]; /*native 802.11 */ +}; + +struct PARAM_P2P_SEND_SD_REQUEST { + uint8_t rReceiverAddr[PARAM_MAC_ADDR_LEN]; + uint8_t fgNeedTxDoneIndication; + /* Indicate the Service Discovery Supplicant Version. */ + uint8_t ucVersionNum; + uint16_t u2PacketLength; + uint8_t aucPacketContent[0]; /*native 802.11 */ +}; + +/* Service Discovery 1.0. */ +struct PARAM_P2P_GET_SD_RESPONSE { + uint8_t rTransmitterAddr[PARAM_MAC_ADDR_LEN]; + uint16_t u2PacketLength; + uint8_t aucPacketContent[0]; /*native 802.11 */ +}; + +/* Service Discovery 2.0. */ +struct PARAM_P2P_GET_SD_RESPONSE_EX { + uint8_t rTransmitterAddr[PARAM_MAC_ADDR_LEN]; + uint16_t u2PacketLength; + uint8_t ucSeqNum; /* Get SD Response by sequence number. */ + uint8_t aucPacketContent[0]; /*native 802.11 */ +}; + +struct PARAM_P2P_TERMINATE_SD_PHASE { + uint8_t rPeerAddr[PARAM_MAC_ADDR_LEN]; +}; + +/*! \brief Key mapping of BSSID */ +struct P2P_PARAM_KEY { + uint32_t u4Length; /*!< Length of structure */ + uint32_t u4KeyIndex; /*!< KeyID */ + uint32_t u4KeyLength; /*!< Key length in bytes */ + uint8_t arBSSID[PARAM_MAC_ADDR_LEN]; /*!< MAC address */ + uint64_t rKeyRSC; + /* Following add to change the original windows structure */ + uint8_t ucBssIdx; /* for specific P2P BSS interface. */ + uint8_t ucCipher; + uint8_t aucKeyMaterial[32]; /*!< Key content by above setting */ +}; + +/****************************************************************************** + * P R I V A T E D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * M A C R O S + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N D E C L A R A T I O N S + ****************************************************************************** + */ + +/*--------------------------------------------------------------*/ +/* Routines to handle command */ +/*--------------------------------------------------------------*/ +/* WLAN_STATUS */ +/* wlanoidSetAddP2PKey(IN P_ADAPTER_T prAdapter, */ +/* IN PVOID pvSetBuffer, + * IN UINT_32 u4SetBufferLen, + * OUT PUINT_32 pu4SetInfoLen); + */ + +/* WLAN_STATUS */ +/* wlanoidSetRemoveP2PKey(IN P_ADAPTER_T prAdapter, */ +/* IN PVOID pvSetBuffer, + * IN UINT_32 u4SetBufferLen, + * OUT PUINT_32 pu4SetInfoLen); + */ + +uint32_t +wlanoidSetNetworkAddress(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidSetP2PMulticastList(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +/*--------------------------------------------------------------*/ +/* Service Discovery Subroutines */ +/*--------------------------------------------------------------*/ +uint32_t +wlanoidSendP2PSDRequest(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidSendP2PSDResponse(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidGetP2PSDRequest(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidGetP2PSDResponse(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *puQueryInfoLen); + +uint32_t +wlanoidSetP2PTerminateSDPhase(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +#if CFG_SUPPORT_ANTI_PIRACY +uint32_t +wlanoidSetSecCheckRequest(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +/*WLAN_STATUS + *wlanoidGetSecCheckResponse(IN P_ADAPTER_T prAdapter, + * IN PVOID pvQueryBuffer, + * IN UINT_32 u4QueryBufferLen, + * OUT PUINT_32 pu4QueryInfoLen); + */ +#endif + +uint32_t +wlanoidSetNoaParam(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidSetOppPsParam(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidSetUApsdParam(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryP2pPowerSaveProfile(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetP2pPowerSaveProfile(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidSetP2pSetNetworkAddress(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +uint32_t +wlanoidQueryP2pVersion(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +uint32_t +wlanoidSetP2pSupplicantVersion(IN struct ADAPTER *prAdapter, + IN void *pvSetBuffer, + IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +#if CFG_SUPPORT_HOTSPOT_WPS_MANAGER +uint32_t +wlanoidSetP2pWPSmode(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); +#endif + +#if CFG_SUPPORT_P2P_RSSI_QUERY +uint32_t +wlanoidQueryP2pRssi(IN struct ADAPTER *prAdapter, + IN void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); +#endif + +uint32_t +wlanoidAbortP2pScan(IN struct ADAPTER *prAdapter, + OUT void *pvQueryBuffer, + IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +/*--------------------------------------------------------------*/ +/* Callbacks for event indication */ +/*--------------------------------------------------------------*/ + +#endif +#endif /* _WLAN_P2P_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/wsys_cmd_handler_fw.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/wsys_cmd_handler_fw.h new file mode 100644 index 0000000000000000000000000000000000000000..5d878c730bde5c5a86b95c63a3f2e5c46af0b554 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/include/wsys_cmd_handler_fw.h @@ -0,0 +1,2033 @@ + +/*! \file wsys_cmd_handler.h +*/ + +/***************************************************************************** +* Copyright (c) 2017 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +****************************************************************************** +*/ + +/***************************************************************************** +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +****************************************************************************** +*/ + +#ifndef _WSYS_CMD_HANDLER_FW_H +#define _WSYS_CMD_HANDLER_FW_H + +/***************************************************************************** +* C O M P I L E R F L A G S +****************************************************************************** +*/ + +/***************************************************************************** +* E X T E R N A L R E F E R E N C E S +****************************************************************************** +*/ +#include "mac.h" + +/***************************************************************************** +* C O N S T A N T S +****************************************************************************** +*/ +#define EVENT_PACKET_TYPE (0xE000) + +#define PARAM_MAX_LEN_RATES_EX 16 + + +#define BKSCAN_CHANNEL_NUM_MAX 64 + +#define DISCONNECT_REASON_CODE_RESERVED 0 +#define DISCONNECT_REASON_CODE_RADIO_LOST 1 +#define DISCONNECT_REASON_CODE_DEAUTHENTICATED 2 +#define DISCONNECT_REASON_CODE_DISASSOCIATED 3 +#define DISCONNECT_REASON_CODE_NEW_CONNECTION 4 + + +/* Define bandwidth, band, channel and SCO configurations from host command, + * whose CMD ID is 0x13. + */ +#define CONFIG_BW_20_40M 0 +#define CONFIG_BW_20M 1 /* 20MHz only */ +#define CONFIG_BW_20_40_80M 2 +#define CONFIG_BW_20_40_80_160M 3 +#define CONFIG_BW_20_40_80_8080M 4 + +/* Band definition in CMD EVENT */ +#define CMD_BAND_NULL 0 +#define CMD_BAND_2G4 1 +#define CMD_BAND_5G 2 + + +/* Action field in structure CMD_CH_PRIVILEGE_T */ +#define CMD_CH_ACTION_REQ 0 +#define CMD_CH_ACTION_ABORT 1 + +/* Status field in structure EVENT_CH_PRIVILEGE_T */ +#define EVENT_CH_STATUS_GRANT 0 +#define EVENT_CH_STATUS_REJECT 1 +#define EVENT_CH_STATUS_RECOVER 2 +#define EVENT_CH_STATUS_REMOVE_REQ 3 + +#define WIFI_RESTART_DOWNLOAD_STATUS_NO_ERROR 0 +#define WIFI_RESTART_DOWNLOAD_STATUS_ERROR 1 + +#define PM_WOWLAN_REQ_START 0x1 +#define PM_WOWLAN_REQ_STOP 0x2 + + +#define PACKETF_CAP_TYPE_ARP BIT(1) +#define PACKETF_CAP_TYPE_MAGIC BIT(2) +#define PACKETF_CAP_TYPE_BITMAP BIT(3) +#define PACKETF_CAP_TYPE_EAPOL BIT(4) +#define PACKETF_CAP_TYPE_TDLS BIT(5) +#define PACKETF_CAP_TYPE_CF BIT(6) +#define PACKETF_CAP_TYPE_HEARTBEAT BIT(7) +#define PACKETF_CAP_TYPE_TCP_SYN BIT(8) +#define PACKETF_CAP_TYPE_UDP_SYN BIT(9) +#define PACKETF_CAP_TYPE_BCAST_SYN BIT(10) +#define PACKETF_CAP_TYPE_MCAST_SYN BIT(11) +#define PACKETF_CAP_TYPE_V6 BIT(12) +#define PACKETF_CAP_TYPE_TDIM BIT(13) + +/*--------------------------------------------------------------------------- + * Config for scan global controls + *--------------------------------------------------------------------------- + */ + +#define PSCAN_MAX_CHANNELS 8 +#define PSCAN_MAX_BUCKETS 8 + +#define PSCAN_MAX_SCAN_CACHE_SIZE 8 +/*GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE*/ +#define PSCAN_MAX_AP_CACHE_PER_SCAN 64 +#define PSCAN_MAX_SCAN_REPORTING_THRETHOLD 8 +#define PSCAN_MAX_BUFFER_THRETHOLD 80 + +#define PSCAN_SCAN_HISTORY_MAX_NUM PSCAN_MAX_AP_CACHE_PER_SCAN +/*Broadcom is 64*/ + +#define PSCAN_SWC_MAX_NUM 8 /*PFN_SWC_MAX_NUM_APS*/ +#define PSCAN_SWC_RSSI_WIN_MAX 8 /*PFN_SWC_RSSI_WINDOW_MAX*/ +#define PSCAN_SWC_LOSTAP_WIN_MAX 8 + +/** + * If there is no bucket base freq setting from pscan->gscan + * we will set this value as default pscan bucket base freq + */ +#define PSCAN_PNO_BUCKET_BASE_FREQ 30000 + +#define PSCAN_HOTLIST_MAX_NUM 8 /*PFN_HOTLIST_MAX_NUM_APS*/ +#define PSCAN_HOTLIST_LOST_AP_WINDOW_DEFAULT 8 +/*GSCAN_LOST_AP_WINDOW_DEFAULT*/ +#define PSCAN_HOTLIST_REPORT_MAX_NUM 8 /**/ + +#define SCAN_DONE_EVENT_MAX_CHANNEL_NUM 64 +#define SCAN_INFO_CHANNEL_NUM_MAX 64 + +/* PF TCP/UDP max port number */ +#define MAX_TCP_UDP_PORT 20 + +#define HE_OP_BYTE_NUM 3 +#define HE_MAC_CAP_BYTE_NUM 6 +#define HE_PHY_CAP_BYTE_NUM 11 + +/***************************************************************************** +* D A T A T Y P E S +****************************************************************************** +*/ + +/* Define CMD ID from Host to firmware (v0.07) */ +enum ENUM_CMD_ID { + CMD_ID_DUMMY_RSV = 0x00, /* 0x00 (Set) */ + CMD_ID_TEST_CTRL = 0x01, /* 0x01 (Set) */ + CMD_ID_BASIC_CONFIG, /* 0x02 (Set) */ + CMD_ID_SCAN_REQ_V2, /* 0x03 (Set) */ + CMD_ID_NIC_POWER_CTRL, /* 0x04 (Set) */ + CMD_ID_POWER_SAVE_MODE, /* 0x05 (Set) */ + CMD_ID_LINK_ATTRIB, /* 0x06 (Set) */ + CMD_ID_ADD_REMOVE_KEY, /* 0x07 (Set) */ + CMD_ID_DEFAULT_KEY_ID, /* 0x08 (Set) */ + CMD_ID_INFRASTRUCTURE, /* 0x09 (Set) */ + CMD_ID_SET_RX_FILTER, /* 0x0a (Set) */ + CMD_ID_DOWNLOAD_BUF, /* 0x0b (Set) */ + CMD_ID_WIFI_START, /* 0x0c (Set) */ + CMD_ID_CMD_BT_OVER_WIFI, /* 0x0d (Set) */ + CMD_ID_SET_MEDIA_CHANGE_DELAY_TIME, /* 0x0e (Set) */ + CMD_ID_SET_DOMAIN_INFO, /* 0x0f (Set) */ + CMD_ID_SET_IP_ADDRESS, /* 0x10 (Set) */ + CMD_ID_BSS_ACTIVATE_CTRL, /* 0x11 (Set) */ + CMD_ID_SET_BSS_INFO, /* 0x12 (Set) */ + CMD_ID_UPDATE_STA_RECORD, /* 0x13 (Set) */ + CMD_ID_REMOVE_STA_RECORD, /* 0x14 (Set) */ + CMD_ID_INDICATE_PM_BSS_CREATED, /* 0x15 (Set) */ + CMD_ID_INDICATE_PM_BSS_CONNECTED, /* 0x16 (Set) */ + CMD_ID_INDICATE_PM_BSS_ABORT, /* 0x17 (Set) */ + CMD_ID_UPDATE_BEACON_CONTENT, /* 0x18 (Set) */ + CMD_ID_SET_BSS_RLM_PARAM, /* 0x19 (Set) */ + CMD_ID_SCAN_REQ, /* 0x1a (Set) */ + CMD_ID_SCAN_CANCEL, /* 0x1b (Set) */ + CMD_ID_CH_PRIVILEGE, /* 0x1c (Set) */ + CMD_ID_UPDATE_WMM_PARMS, /* 0x1d (Set) */ + CMD_ID_SET_WMM_PS_TEST_PARMS, /* 0x1e (Set) */ + CMD_ID_TX_AMPDU, /* 0x1f (Set) */ + CMD_ID_ADDBA_REJECT, /* 0x20 (Set) */ + CMD_ID_SET_PS_PROFILE_ADV, /* 0x21 (Set) */ + CMD_ID_SET_RAW_PATTERN, /* 0x22 (Set) */ + CMD_ID_CONFIG_PATTERN_FUNC, /* 0x23 (Set) */ + CMD_ID_SET_TX_PWR, /* 0x24 (Set) */ + CMD_ID_SET_PWR_PARAM, /* 0x25 (Set) */ + CMD_ID_P2P_ABORT, /* 0x26 (Set) */ + CMD_ID_SET_TX_EXTEND_PWR, /* 0x27 (Set) */ + CMD_ID_SET_DBDC_PARMS, /* 0x28 (Set) */ + CMD_ID_SET_FILTER_COEFFICIENT, /* 0x29 (Set) */ + + /* SLT commands */ + CMD_ID_RANDOM_RX_RESET_EN = 0x2C, /* 0x2C (Set ) */ + CMD_ID_RANDOM_RX_RESET_DE = 0x2D, /* 0x2D (Set ) */ + CMD_ID_SAPP_EN = 0x2E, /* 0x2E (Set ) */ + CMD_ID_SAPP_DE = 0x2F, /* 0x2F (Set ) */ + + CMD_ID_ROAMING_TRANSIT = 0x30, /* 0x30 (Set) */ + CMD_ID_SET_PHY_PARAM, /* 0x31 (Set) */ + CMD_ID_SET_NOA_PARAM, /* 0x32 (Set) */ + CMD_ID_SET_OPPPS_PARAM, /* 0x33 (Set) */ + CMD_ID_SET_UAPSD_PARAM, /* 0x34 (Set) */ + CMD_ID_SET_SIGMA_STA_SLEEP, /* 0x35 (Set) */ + CMD_ID_SET_EDGE_TXPWR_LIMIT, /* 0x36 (Set) */ + CMD_ID_SET_DEVICE_MODE, /* 0x37 (Set) */ + CMD_ID_SET_TXPWR_CTRL, /* 0x38 (Set) */ + CMD_ID_SET_AUTOPWR_CTRL, /* 0x39 (Set) */ + CMD_ID_SET_WFD_CTRL, /* 0x3a (Set) */ + CMD_ID_SET_NLO_REQ, /* 0x3b (Set), NO USE */ + CMD_ID_SET_NLO_CANCEL, /* 0x3c (Set), NO USE */ + CMD_ID_SET_GTK_REKEY_DATA, /* 0x3d (Set) */ + CMD_ID_ROAMING_CONTROL, /* 0x3e (Set) */ + CMD_ID_RESET_BA_SCOREBOARD = 0x3f, /* 0x3f (Set) */ + CMD_ID_SET_EDGE_TXPWR_LIMIT_5G = 0x40, /* 0x40 (Set) */ + CMD_ID_SET_CHANNEL_PWR_OFFSET, /* 0x41 (Set) */ + CMD_ID_SET_80211AC_TX_PWR, /* 0x42 (Set) */ + CMD_ID_SET_PATH_COMPASATION, /* 0x43 (Set) */ + CMD_ID_SET_RTT_REQ = 0x44, /* 0x44 (Set) */ + CMD_ID_SET_RTT_CALIBR, /* 0x45 (Set) */ + CMD_ID_GET_RTT_RANGE_UPDATE, /* 0x46 (Set) */ + CMD_ID_SET_BATCH_REQ, /* 0x47 (Set), NO USE */ + CMD_ID_SET_NVRAM_SETTINGS, /* 0x48 (Set) */ + CMD_ID_SET_COUNTRY_POWER_LIMIT, /* 0x49 (Set) */ + CMD_ID_SET_WOWLAN = 0x4A, /* 0x4A (Set) */ + CMD_ID_SET_IPV6_ADDRESS, /* 0x4B (Set) */ + + CMD_ID_SET_SLTINFO = 0x50, /* 0x50 (Set) */ + CMD_ID_UART_ACK, /* 0x51 (Set) */ + CMD_ID_UART_NAK, /* 0x52 (Set) */ + CMD_ID_GET_CHIPID, + + CMD_ID_SET_MDDP_FILTER_RULE = 0x54, /* 0x54 (Set) */ + CMD_ID_SET_AM_FILTER = 0x55, /* 0x55 (Set) */ + CMD_ID_SET_AM_HEARTBEAT, /* 0x56 (Set) */ + CMD_ID_SET_AM_TCP, /* 0x57 (Set) */ + CMD_ID_SET_SUSPEND_MODE = 0x58, /* 0x58 (Set) */ + CMD_ID_SET_PF_CAPABILITY = 0x59, /* 0x59 (Set) */ + CMD_ID_SET_RRM_CAPABILITY = 0x5A, /* 0x5A (Set) */ + CMD_ID_SET_AP_CONSTRAINT_PWR_LIMIT = 0x5B, /* 0x5B (Set) */ + CMD_ID_SET_COUNTRY_POWER_LIMIT_PER_RATE = 0x5D, /* 0x5D (Set) */ + CMD_ID_SET_TSM_STATISTICS_REQUEST = 0x5E, + CMD_ID_GET_TSM_STATISTICS = 0x5F, + /* CFG_SUPPORT_GSCN */ + CMD_ID_GET_PSCAN_CAPABILITY = 0x60, /* 0x60 (Set), NO USE */ + CMD_ID_SET_SCAN_SCHED_ENABLE, /* 0x61 (Set) */ + CMD_ID_SET_SCAN_SCHED_REQ, /* 0x62 (Set) */ + CMD_ID_SET_GSCAN_ADD_HOTLIST_BSSID, /* 0x63 (Set), NO USE */ + CMD_ID_SET_GSCAN_ADD_SWC_BSSID, /* 0x64 (Set), NO USE */ + CMD_ID_SET_GSCAN_MAC_ADDR, /* 0x65 (Set), NO USE */ + CMD_ID_GET_GSCAN_RESULT, /* 0x66 (Get), NO USE */ + CMD_ID_SET_PSCAN_MAC_ADDR, /* 0x67 (Get), NO USE */ + CMD_ID_FAST_SCAN_DUMMY2, /* 0x68 (Get), NO USE */ + CMD_ID_FAST_SCAN_DUMMY3, /* 0x69 (Get), NO USE */ + + CMD_ID_UPDATE_AC_PARMS = 0x6A, /* 0x6A (Set) */ + CMD_ID_SET_ROAMING_SKIP = 0x6D, + /* 0x6D (Set) used to setting roaming skip*/ + CMD_ID_SET_DROP_PACKET_CFG = 0x6E, + /* 0x6E (Set/Query) used to setting drop packet */ + + /*CFG_SUPPORT_EASY_DEBUG*/ + CMD_ID_GET_SET_CUSTOMER_CFG = 0x70, /* 0x70 (Set/Query) */ + CMD_ID_SET_ALWAYS_SCAN_PARAM = 0x73,/* 0x73 (Set) */ + CMD_ID_TDLS_PS = 0x75, /* 0x75 (Set) */ + + CMD_ID_GET_CNM = 0x79, + + CMD_ID_FRM_IND_FROM_HOST = 0x7D, /* 0x7D (Set) */ + CMD_ID_PERF_IND = 0x7E, /* 0x7E(Set) */ +#if CFG_SUPPORT_SMART_GEAR + CMD_ID_SG_PARAM = 0x7F, /* 0x7F(Set) */ +#endif + CMD_ID_GET_NIC_CAPABILITY = 0x80, /* 0x80 (Query) */ + CMD_ID_GET_LINK_QUALITY, /* 0x81 (Query) */ + CMD_ID_GET_STATISTICS, /* 0x82 (Query) */ + CMD_ID_GET_CONNECTION_STATUS, /* 0x83 (Query) */ + CMD_ID_GET_STA_STATISTICS = 0x85, /* 0x85 (Query) */ + CMD_ID_GET_LTE_CHN = 0x87, /* 0x87 (Query) */ + CMD_ID_GET_BUG_REPORT = 0x89, /* 0x89 (Query) */ + CMD_ID_GET_NIC_CAPABILITY_V2 = 0x8A,/* 0x8A (Query) */ +#if CFG_SUPPORT_LOWLATENCY_MODE + CMD_ID_SET_LOW_LATENCY_MODE = 0x8B, /* 0x8B (Set) */ +#endif + CMD_ID_LOG_UI_INFO = 0x8D, /* 0x8D (Set / Query) */ + /* Oshare mode*/ + CMD_ID_SET_OSHARE_MODE = 0x8E, + CMD_ID_RDD_ON_OFF_CTRL = 0x8F, /* 0x8F(Set) */ + CMD_ID_SET_FORCE_RTS = 0x90, + CMD_ID_WFC_KEEP_ALIVE = 0xA0, /* 0xA0 (Set) */ + CMD_ID_RSSI_MONITOR = 0xA1, /* 0xA1 (Set) */ + CMD_ID_CAL_BACKUP_IN_HOST_V2 = 0xAE, /* 0xAE (Set / Query) */ + + CMD_ID_MQM_UPDATE_MU_EDCA_PARMS = 0xB0, /* 0xB0 (Set) */ + CMD_ID_RLM_UPDATE_SR_PARAMS = 0xB1, /* 0xB1 (Set) */ + + CMD_ID_ACCESS_REG = 0xc0, /* 0xc0 (Set / Query) */ + CMD_ID_MAC_MCAST_ADDR, /* 0xc1 (Set / Query) */ + CMD_ID_802_11_PMKID, /* 0xc2 (Set / Query) */ + CMD_ID_ACCESS_EEPROM, /* 0xc3 (Set / Query) */ + CMD_ID_SW_DBG_CTRL, /* 0xc4 (Set / Query) */ + CMD_ID_FW_LOG_2_HOST, /* 0xc5 (Set) */ + CMD_ID_DUMP_MEM, /* 0xc6 (Query) */ + CMD_ID_RESOURCE_CONFIG, /* 0xc7 (Set / Query) */ + CMD_ID_ACCESS_RX_STAT, /* 0xc8 (Query) */ + + CMD_ID_CHIP_CONFIG = 0xCA, /* 0xca (Set / Query) */ + CMD_ID_STATS_LOG = 0xCB, + + CMD_ID_WTBL_INFO = 0xCD, /* 0xcd (Query) */ + CMD_ID_MIB_INFO = 0xCE, /* 0xce (Query) */ + + CMD_ID_SET_TXBF_BACKOFF = 0xD1, + + CMD_ID_SET_RDD_CH = 0xE1, + + CMD_ID_LAYER_0_EXT_MAGIC_NUM = 0xED, + /* magic number for Extending MT6630 original CMD header */ + /*CMD_ID_LAYER_1_MAGIC_NUM = 0xEE, */ + /* magic number for backward compatible with MT76xx CMD */ + CMD_ID_INIT_CMD_WIFI_RESTART = 0xEF, + /* 0xef (reload firmware use) wayne_note 2013.09.26 */ + + CMD_ID_SET_BWCS = 0xF1, + CMD_ID_SET_OSC = 0xF2, + CMD_ID_HIF_CTRL = 0xF6, + /* 0xF6 (Set) USB suspend/resume */ + CMD_ID_GET_BUILD_DATE_CODE = 0xF8, /* 0xf8 (Query) */ + CMD_ID_GET_BSS_INFO = 0xF9, /* 0xF9 (Query) */ + CMD_ID_SET_HOTSPOT_OPTIMIZATION = 0xFA, /* 0xFA (Set) */ + + CMD_ID_SET_TDLS_CH_SW = 0xFB, + + CMD_ID_SET_MONITOR = 0xFC, /* 0xfc (Set) */ + CMD_ID_SET_CCK_1M_PWR = 0xFD, /* 0xFC (Set) */ + CMD_ID_END +}; + +/* Define EVENT ID from firmware to Host (v0.09) */ +enum ENUM_EVENT_ID { + EVENT_ID_NIC_CAPABILITY = 0x01, /* 0x01 (Query) */ + EVENT_ID_LINK_QUALITY, /* 0x02 (Query / Unsolicited) */ + EVENT_ID_STATISTICS, /* 0x03 (Query) */ + EVENT_ID_MIC_ERR_INFO, /* 0x04 (Unsolicited) */ + EVENT_ID_ACCESS_REG, + /* 0x05 (Query - CMD_ID_ACCESS_REG) */ + EVENT_ID_ACCESS_EEPROM, + /* 0x06 (Query - CMD_ID_ACCESS_EEPROM) */ + EVENT_ID_SLEEPY_INFO, /* 0x07 (Unsolicited) */ + EVENT_ID_BT_OVER_WIFI, /* 0x08 (Unsolicited) */ + EVENT_ID_TEST_STATUS, + /* 0x09 (Query - CMD_ID_TEST_CTRL) */ + EVENT_ID_RX_ADDBA, /* 0x0a (Unsolicited) */ + EVENT_ID_RX_DELBA, /* 0x0b (Unsolicited) */ + EVENT_ID_ACTIVATE_STA_REC, /* 0x0c (Response) */ + EVENT_ID_SCAN_DONE, /* 0x0d (Unsoiicited) */ + EVENT_ID_RX_FLUSH, /* 0x0e (Unsolicited) */ + EVENT_ID_TX_DONE, /* 0x0f (Unsolicited) */ + EVENT_ID_CH_PRIVILEGE, /* 0x10 (Unsolicited) */ + EVENT_ID_BSS_ABSENCE_PRESENCE, /* 0x11 (Unsolicited) */ + EVENT_ID_STA_CHANGE_PS_MODE, /* 0x12 (Unsolicited) */ + EVENT_ID_BSS_BEACON_TIMEOUT, /* 0x13 (Unsolicited) */ + EVENT_ID_UPDATE_NOA_PARAMS, /* 0x14 (Unsolicited) */ + EVENT_ID_AP_OBSS_STATUS, /* 0x15 (Unsolicited) */ + EVENT_ID_STA_UPDATE_FREE_QUOTA, /* 0x16 (Unsolicited) */ + EVENT_ID_SW_DBG_CTRL, + /* 0x17 (Query - CMD_ID_SW_DBG_CTRL) */ + EVENT_ID_ROAMING_STATUS, /* 0x18 (Unsolicited) */ + EVENT_ID_STA_AGING_TIMEOUT, /* 0x19 (Unsolicited) */ + EVENT_ID_SEC_CHECK_RSP, + /* 0x1a (Query - CMD_ID_SEC_CHECK) */ + EVENT_ID_SEND_DEAUTH, /* 0x1b (Unsolicited) */ + EVENT_ID_UPDATE_RDD_STATUS, /* 0x1c (Unsolicited) */ + EVENT_ID_UPDATE_BWCS_STATUS, /* 0x1d (Unsolicited) */ + EVENT_ID_UPDATE_BCM_DEBUG, /* 0x1e (Unsolicited) */ + EVENT_ID_RX_ERR, /* 0x1f (Unsolicited) */ + EVENT_ID_DUMP_MEM = 0x20, + /* 0x20 (Query - CMD_ID_DUMP_MEM) */ + EVENT_ID_STA_STATISTICS, /* 0x21 (Query ) */ + EVENT_ID_STA_STATISTICS_UPDATE, /* 0x22 (Unsolicited) */ + EVENT_ID_SCHED_SCAN_DONE, /* 0x23 (Unsoiicited) */ + EVENT_ID_ADD_PKEY_DONE, /* 0x24 (Unsoiicited) */ + EVENT_ID_ICAP_DONE, /* 0x25 (Unsoiicited) */ + EVENT_ID_RESOURCE_CONFIG = 0x26, + /* 0x26 (Query - CMD_ID_RESOURCE_CONFIG) */ + EVENT_ID_DEBUG_MSG = 0x27, /* 0x27 (Unsoiicited) */ + EVENT_ID_RTT_DISCOVER_PEER = 0x28, /* 0x28 (Unsoiicited) */ + EVENT_ID_RTT_UPDATE_RANGE = 0x29, /* 0x29 (Unsoiicited) */ + EVENT_ID_CHECK_REORDER_BUBBLE = 0x2a, /* 0x2a (Unsoiicited) */ + EVENT_ID_BATCH_RESULT = 0x2b, /* 0x2b (Query) */ + EVENT_ID_STA_ABSENCE_TX = 0x2c, /* 0x2c (Unsoiicited) */ + EVENT_ID_RTT_UPDATE_LOCATION = 0x2d, /* 0x2c (Unsoiicited) */ + EVENT_ID_TX_ADDBA = 0x2e, + EVENT_ID_LTE_SAFE_CHN = 0x2f, /* 0x2f (Query ) */ + + + + /* CFG_SUPPORT_GSCN */ + EVENT_ID_GSCAN_CAPABILITY = 0x30, + EVENT_ID_GSCAN_SCAN_COMPLETE = 0x31, + EVENT_ID_GSCAN_FULL_RESULT = 0x32, + EVENT_ID_GSCAN_SIGNIFICANT_CHANGE = 0x33, + EVENT_ID_GSCAN_GEOFENCE_FOUND = 0x34, + EVENT_ID_GSCAN_SCAN_AVAILABLE = 0x35, + EVENT_ID_GSCAN_RESULT = 0x36, + EVENT_ID_GSCAN_HOTLIST_RESULTS_FOUND = 0x37, + EVENT_ID_GSCAN_HOTLIST_RESULTS_LOST = 0x38, + EVENT_ID_FAST_SCAN_DUMMY1 = 0x39, + EVENT_ID_FAST_SCAN_DUMMY2 = 0x3a, + EVENT_ID_FAST_SCAN_DUMMY3 = 0x3b, + + EVENT_ID_UART_ACK = 0x40, /* 0x40 (Unsolicited) */ + EVENT_ID_UART_NAK, /* 0x41 (Unsolicited) */ + EVENT_ID_GET_CHIPID, + /* 0x42 (Query - CMD_ID_GET_CHIPID) */ + EVENT_ID_SLT_STATUS, + /* 0x43 (Query - CMD_ID_SET_SLTINFO) */ + EVENT_ID_CHIP_CONFIG, + /* 0x44 (Query - CMD_ID_CHIP_CONFIG) */ + EVENT_ID_ACCESS_RX_STAT = 0x45, + /* 0x45 (Query - CMD_ID_ACCESS_RX_STAT) */ + + EVENT_ID_RDD_SEND_PULSE = 0x50, + EVENT_ID_PFMU_TAG_READ = 0x51, + EVENT_ID_PFMU_DATA_READ = 0x52, + EVENT_ID_MU_GET_QD = 0x53, + EVENT_ID_MU_GET_LQ = 0x54, + EVENT_ID_AM_FILTER = 0x55, + /* 0x55 (Query - CMD_ID_SET_AM_FILTER) */ + EVENT_ID_AM_HEARTBEAT = 0x56, + /* 0x56 (Query - CMD_ID_SET_AM_HEARTBEAT) */ + EVENT_ID_AM_TCP = 0x57, + /* 0x57 (Query - CMD_ID_SET_AM_TCP) */ + EVENT_ID_HEARTBEAT_INFO = 0x58, /* 0x58 (Unsolicited) */ + EVENT_ID_MDDP_FILTER_RULE = 0x59, + /* 0x59 (Query - CMD_ID_SET_MDDP_FILTER_RULE) */ + EVENT_ID_BA_FW_DROP_SN = 0x5A, /* 0x5A (Unsolicited) */ + EVENT_ID_LOW_LATENCY_INFO = 0x5B, /* 0x5B (Unsolicited) */ + EVENT_ID_RDD_REPORT = 0x60, + EVENT_ID_CSA_DONE = 0x61, + + EVENT_ID_OPMODE_CHANGE = 0x63, +#if CFG_SUPPORT_IDC_CH_SWITCH + EVENT_ID_LTE_IDC_REPORT = 0x64, +#endif + +#if CFG_SUPPORT_SMART_GEAR + EVENT_ID_SG_STATUS = 0x65, +#endif + +#if CFG_SUPPORT_HE_ER + EVENT_ID_BSS_ER_TX_MODE = 0x66, /* 0x66 BSS Extend Rage (ER) mode */ +#endif + + EVENT_ID_GET_CMD_INFO = 0x70, + /* 0x70 (Query - EVENT_ID_GET_CMD_INFO) */ + /*query info from cmd.*/ + EVENT_ID_DBDC_SWITCH_DONE = 0x78, + EVENT_ID_GET_CNM = 0x79, + + EVENT_ID_FRM_IND_FROM_HOST = 0x7D, + + EVENT_ID_TDLS = 0x80, + + EVENT_ID_LOG_UI_INFO = 0x8D, /* 0x8D (Set / Query) */ + EVENT_ID_UPDATE_COEX_PHYRATE = 0x90, /* 0x90 (Unsolicited) */ + + EVENT_ID_RSSI_MONITOR = 0xA1, /* Event ID for Rssi monitoring */ + EVENT_ID_CAL_BACKUP_IN_HOST_V2 = 0xAE, + /* 0xAE (Query - CMD_ID_CAL_BACKUP) */ + EVENT_ID_CAL_ALL_DONE = 0xAF, /* 0xAF (FW Cal All Done Event) */ + + EVENT_ID_WTBL_INFO = 0xCD, /* 0xCD (Query) */ + EVENT_ID_MIB_INFO = 0xCE, /* 0xCE (Query) */ + + EVENT_ID_NIC_CAPABILITY_V2 = 0xEC, + /* 0xEC (Query - CMD_ID_GET_NIC_CAPABILITY_V2) */ + EVENT_ID_LAYER_0_EXT_MAGIC_NUM = 0xED, + /* magic number for Extending MT6630 original EVENT header */ + EVENT_ID_ASSERT_DUMP = 0xF0, + EVENT_ID_HIF_CTRL = 0xF6, + EVENT_ID_BUILD_DATE_CODE = 0xF8, + EVENT_ID_GET_AIS_BSS_INFO = 0xF9, + EVENT_ID_DEBUG_CODE = 0xFB, + EVENT_ID_RFTEST_READY = 0xFC, /* 0xFC */ + + EVENT_ID_INIT_EVENT_CMD_RESULT = 0xFD, + /* 0xFD (Generic event for cmd not found, added by CONNAC) */ + + EVENT_ID_END +}; + +/* commands */ + +/* already define at wifi_task.h!!! */ +/*chiahsuan: ReStart Download Firmware + *Request/Response Start. (duplicated one. + * it is copy from ROM) + */ +struct INIT_WIFI_CMD { + uint8_t ucCID; + uint8_t ucPktTypeID; /* Must be 0xA0 (CMD Packet) */ + uint8_t ucReserved; + uint8_t ucSeqNum; + uint32_t u4Reserved; + /* add one DW to compatible with normal TXD format. */ + uint32_t au4D3toD7Rev[5]; + /* add 5 DW to compatible with normal TXD format. */ + uint8_t aucBuffer[0]; +}; + +struct INIT_WIFI_EVENT { + uint16_t u2RxByteCount; + uint16_t u2PacketType; + /* Must be filled with 0xE000 (EVENT Packet) */ + uint8_t ucEID; + uint8_t ucSeqNum; + uint8_t aucReserved[2]; + + uint8_t aucBuffer[0]; +}; + +struct INIT_HIF_TX_HEADER { + uint16_t u2TxByteCount; + uint16_t u2PQ_ID; /* Must be 0x8000 (Port1, Queue 0) */ + struct INIT_WIFI_CMD rInitWifiCmd; +}; + +struct INIT_HIF_TX_HEADER_PENDING_FOR_HW_32BYTES { + uint16_t u2TxByteCount; + uint16_t u2PQ_ID; /* Must be 0x8000 (Port1, Queue 0) */ + + uint8_t ucWlanIdx; + uint8_t ucHeaderFormat; + uint8_t ucHeaderPadding; + uint8_t ucPktFt: 2; + uint8_t ucOwnMAC: 6; + uint32_t au4D2toD7Rev[6]; +}; + +struct INIT_EVENT_CMD_RESULT { + uint8_t ucStatus; + /* 0: success, 0xFE command not support, others: failure */ + uint8_t ucCID; + uint8_t aucReserved[2]; +}; + +/*---------------------------------------------------------------------------*/ +/* Parameters of User Configuration which match to NDIS5.1 */ +/*---------------------------------------------------------------------------*/ +typedef int32_t PARAM_RSSI; + +/* NDIS_802_11_RATES_EX */ +typedef uint8_t PARAM_RATES_EX[PARAM_MAX_LEN_RATES_EX]; + +/* NDIS_802_11_NETWORK_TYPE */ +enum ENUM_PARAM_PHY_NET_TYPE { + PHY_NET_TYPE_FH, + PHY_NET_TYPE_DS, + PHY_NET_TYPE_OFDM5, + PHY_NET_TYPE_OFDM24, + PHY_NET_TYPE_AUTOMODE, + PHY_NET_TYPE_NUM /*!< Upper bound, not real case */ +}; + +/* NDIS_802_11_AUTHENTICATION_MODE */ +enum ENUM_PARAM_AUTH_MODE { + AUTH_MODE_OPEN = 0, /*!< Open system */ + AUTH_MODE_SHARED, /*!< Shared key */ + AUTH_MODE_AUTO_SWITCH, + /*!< Either open system or shared key */ + AUTH_MODE_WPA, + AUTH_MODE_WPA_PSK, + AUTH_MODE_WPA_NONE, /*!< For Ad hoc */ + AUTH_MODE_WPA2, + AUTH_MODE_WPA2_PSK, + AUTH_MODE_WPA2_FT, /* 802.11r */ + AUTH_MODE_WPA2_FT_PSK, /* 802.11r */ + AUTH_MODE_WPA_OSEN, + AUTH_MODE_WPA3_SAE, + AUTH_MODE_WPA3_OWE, + AUTH_MODE_NUM /*!< Upper bound, not real case */ +}; + +/* NDIS_802_11_ENCRYPTION_STATUS */ +enum ENUM_WEP_STATUS { + ENUM_WEP_ENABLED, + ENUM_ENCRYPTION1_ENABLED = ENUM_WEP_ENABLED, /* WEP */ + ENUM_WEP_DISABLED, + ENUM_ENCRYPTION_DISABLED = ENUM_WEP_DISABLED, /* OPEN */ + ENUM_WEP_KEY_ABSENT, + ENUM_ENCRYPTION1_KEY_ABSENT = ENUM_WEP_KEY_ABSENT, + ENUM_WEP_NOT_SUPPORTED, + ENUM_ENCRYPTION_NOT_SUPPORTED = ENUM_WEP_NOT_SUPPORTED, + ENUM_ENCRYPTION2_ENABLED, /* TKIP(WPA/WPA2) */ + ENUM_ENCRYPTION2_KEY_ABSENT, + ENUM_ENCRYPTION3_ENABLED, /* CCMP(WPA/WPA2) */ + ENUM_ENCRYPTION3_KEY_ABSENT, + ENUM_ENCRYPTION4_ENABLED, /* GCMP256(WPA2/WPA3) */ + ENUM_ENCRYPTION4_KEY_ABSENT, + ENUM_ENCRYPTION_NUM +}; + +/*---------------------------------------------------------------------------*/ +/* CMD Packets */ +/*---------------------------------------------------------------------------*/ +struct CMD_BUILD_CONNECTION { + uint8_t ucInfraMode; + uint8_t ucAuthMode; + uint8_t ucEncryptStatus; + uint8_t ucSsidLen; + uint8_t aucSsid[32]; + uint8_t aucBssid[6]; + + /* The following parameters are for Ad-hoc network */ + uint16_t u2BeaconPeriod; + uint16_t u2ATIMWindow; + uint8_t ucJoinOnly; + uint8_t ucReserved; + uint32_t u4FreqInKHz; + +}; + +struct CMD_802_11_KEY { + uint8_t ucAddRemove; + uint8_t ucTxKey; /* 1 : Tx key */ + uint8_t ucKeyType; /* 0 : group Key, 1 : Pairwise key */ + uint8_t ucIsAuthenticator; /* 1 : authenticator */ + uint8_t aucPeerAddr[6]; + uint8_t ucBssIdx; /* the BSS index */ + uint8_t ucAlgorithmId; + uint8_t ucKeyId; + uint8_t ucKeyLen; + uint8_t ucWlanIndex; + uint8_t ucMgmtProtection; + uint8_t aucKeyMaterial[32]; + uint8_t aucKeyRsc[16]; +}; + +struct CMD_DEFAULT_KEY_ID { + uint8_t ucBssIdx; + uint8_t ucKeyId; + uint8_t ucUnicast; + uint8_t ucMulticast; +}; + + +/* CMD for PMKID and related structure */ +typedef uint8_t PARAM_PMKID_VALUE[16]; + +struct PARAM_BSSID_INFO { + uint8_t aucBssid[MAC_ADDR_LEN]; /* MAC address */ + PARAM_PMKID_VALUE arPMKID; +}; + +/* This struct only uses uint16_t, + * compiler will use 2-byte alignment. + * sizeof(struct CMD_SET_BSS_RLM_PARAM) is 22 + */ +struct CMD_SET_BSS_RLM_PARAM { + uint8_t ucBssIndex; + uint8_t ucRfBand; + uint8_t ucPrimaryChannel; + uint8_t ucRfSco; + uint8_t ucErpProtectMode; + uint8_t ucHtProtectMode; + uint8_t ucGfOperationMode; + uint8_t ucTxRifsMode; + uint16_t u2HtOpInfo3; + uint16_t u2HtOpInfo2; + uint8_t ucHtOpInfo1; + uint8_t ucUseShortPreamble; + uint8_t ucUseShortSlotTime; + uint8_t ucVhtChannelWidth; + uint8_t ucVhtChannelFrequencyS1; + uint8_t ucVhtChannelFrequencyS2; + uint16_t u2VhtBasicMcsSet; + uint8_t ucTxNss; + uint8_t ucRxNss; +}; + +/*CMD_ID_FRM_IND_FROM_HOST 0x7D*/ + +/*ver 1 structure*/ +struct CMD_FRM_IND_FROM_HOST { + /* DWORD_0 - Common Part*/ + uint8_t ucCmdVer; + uint8_t aucPadding0[1]; + uint16_t u2CmdLen; /* cmd size including common part and body.*/ + + /* DWORD_1 ~ x - Command Body*/ + uint8_t ucStaIdx; + uint8_t ucBssIdx; + /** TX/RX/TXS(future used) ENUM_CMD_FRM_IND_FROM_HOST_TRANSMIT_TYPE */ + uint8_t ucTransmitType; + /** ENUM_CMD_FRM_IND_FROM_HOST_PROTOCOL_TYPE */ + uint8_t ucProtocolType; + /** ENUM_CMD_FRM_IND_FROM_HOST_EAP_MSG_TYPE, + * ENUM_CMD_M_IND_FROM_HOST_DHCP_MSG_TYPE + */ + /** depend on ucProtocolType */ + uint8_t ucProtocolSubType; + uint8_t ucRateValid; + uint8_t aucPadding1[2]; + /** TX Rate, Rx Rate, TxS Rate */ + uint32_t u4Rate; + uint32_t u4Len; + /** Only TXS type value in txS*/ + uint8_t TxS; + uint8_t aucPadding3[3]; + uint8_t aucPadding4[64]; +}; + +enum ENUM_FRM_IND_FROM_HOST_VER { + CMD_FRM_IND_FROM_HOST_VER_INIT = 0x0, + CMD_FRM_IND_FROM_HOST_VER_1ST = 0x1, + CMD_FRM_IND_FROM_HOST_VER_MAX = 0x2, +}; + +enum ENUM_CMD_FRM_IND_FROM_HOST_TRANSMIT_TYPE { + CMD_FRM_IND_FROM_HOST_TRANSMIT_TYPE_TX = 0x00, + CMD_FRM_IND_FROM_HOST_TRANSMIT_TYPE_RX = 0x01, + CMD_FRM_IND_FROM_HOST_TRANSMIT_TYPE_TXS = 0x02, + CMD_FRM_IND_FROM_HOST_TRANSMIT_TYPE_MAX = 0x03, +}; + +enum ENUM_CMD_FRM_IND_FROM_HOST_PROTOCOL_TYPE { + CMD_FRM_IND_FROM_HOST_PROTOCOL_TYPE_NON_SPECIFIC = 0x00, + CMD_FRM_IND_FROM_HOST_PROTOCOL_TYPE_EAP = 0x01, + CMD_FRM_IND_FROM_HOST_PROTOCOL_TYPE_DHCP = 0x02, + CMD_FRM_IND_FROM_HOST_PROTOCOL_TYPE_MAX = 0x03, +}; + +enum ENUM_CMD_FRM_IND_FROM_HOST_EAP_MSG_TYPE { + CMD_FRM_IND_FROM_HOST_EAP_MSG_NON_SPECIFIC = 0x00, + CMD_FRM_IND_FROM_HOST_EAP_MSG_4WAY_1 = 0x01, + CMD_FRM_IND_FROM_HOST_EAP_MSG_4WAY_2 = 0x02, + CMD_FRM_IND_FROM_HOST_EAP_MSG_4WAY_3 = 0x03, + CMD_FRM_IND_FROM_HOST_EAP_MSG_4WAY_4 = 0x04, + CMD_FRM_IND_FROM_HOST_EAP_MSG_GROUP_1 = 0x05, + CMD_FRM_IND_FROM_HOST_EAP_MSG_GROUP_2 = 0x06, + CMD_FRM_IND_FROM_HOST_EAP_MSG_MAX = 0x07, +}; + +enum ENUM_CMD_FRM_IND_FROM_HOST_DHCP_MSG_TYPE { + CMD_FRM_IND_FROM_HOST_DHCP_MSG_NON_SPECIFIC = 0x00, + CMD_FRM_IND_FROM_HOST_DHCP_MSG_DISCOVER = 0x01, + CMD_FRM_IND_FROM_HOST_DHCP_MSG_OFFER = 0x02, + CMD_FRM_IND_FROM_HOST_DHCP_MSG_REQUEST = 0x03, + CMD_FRM_IND_FROM_HOST_DHCP_MSG_ACK = 0x04, + CMD_FRM_IND_FROM_HOST_DHCP_MSG_MAX = 0x05, +}; + +/* This struct uses uint32_t, compiler will use 4-byte alignment. + * sizeof(struct CMD_SET_BSS_INFO) is 116 + */ +struct CMD_SET_BSS_INFO { + uint8_t ucBssIndex; + uint8_t ucConnectionState; + uint8_t ucCurrentOPMode; + uint8_t ucSSIDLen; + uint8_t aucSSID[32]; + uint8_t aucBSSID[6]; + uint8_t ucIsQBSS; + uint8_t ucVersion; + uint16_t u2OperationalRateSet; + uint16_t u2BSSBasicRateSet; + uint8_t ucStaRecIdxOfAP; + uint8_t aucPadding0[1]; + uint16_t u2HwDefaultFixedRateCode; + uint8_t ucNonHTBasicPhyType; /* For Slot Time and CWmin */ + uint8_t ucAuthMode; + uint8_t ucEncStatus; + uint8_t ucPhyTypeSet; + uint8_t ucWapiMode; + uint8_t ucIsApMode; + uint8_t ucBMCWlanIndex; + uint8_t ucHiddenSsidMode; + uint8_t ucDisconnectDetectThreshold; + uint8_t ucIotApAct; + uint8_t aucPadding1[2]; + uint32_t u4PrivateData; + struct CMD_SET_BSS_RLM_PARAM rBssRlmParam; /*68*/ + uint8_t ucDBDCBand; /*90, ENUM_CMD_REQ_DBDC_BAND_T*/ + uint8_t ucWmmSet; + uint8_t ucDBDCAction; + uint8_t ucNss; + uint8_t aucPadding2[2]; + uint8_t ucHeOpParams[HE_OP_BYTE_NUM]; + uint8_t ucBssColorInfo; + uint16_t u2HeBasicMcsSet; + uint8_t ucMaxBSSIDIndicator; + uint8_t ucMBSSIDIndex; + uint8_t aucPadding[12]; +}; + +struct CMD_HTVHT_BA_SIZE { + uint8_t ucTxBaSize; + uint8_t ucRxBaSize; + uint8_t aucReserved[2]; +}; + +struct CMD_HE_BA_SIZE { + uint16_t u2TxBaSize; + uint16_t u2RxBaSize; +}; + +struct CMD_UPDATE_STA_RECORD { + uint8_t ucStaIndex; + uint8_t ucStaType; + uint8_t aucMacAddr[MAC_ADDR_LEN]; + /* This field should assign at create and keep consistency for update + * usage + */ + + uint16_t u2AssocId; + uint16_t u2ListenInterval; + uint8_t ucBssIndex; + /* This field should assign at create and keep consistency for update + * usage + */ + uint8_t ucDesiredPhyTypeSet; + uint16_t u2DesiredNonHTRateSet; + + uint16_t u2BSSBasicRateSet; + uint8_t ucIsQoS; + uint8_t ucIsUapsdSupported; + uint8_t ucStaState; + uint8_t ucMcsSet; + uint8_t ucSupMcs32; + uint8_t ucVersion; + /* Original padding is used for version now */ + + uint8_t aucRxMcsBitmask[10]; + uint16_t u2RxHighestSupportedRate; + uint32_t u4TxRateInfo; + + uint16_t u2HtCapInfo; + uint16_t u2HtExtendedCap; + uint32_t u4TxBeamformingCap; + + uint8_t ucAmpduParam; + uint8_t ucAselCap; + uint8_t ucRCPI; + uint8_t ucNeedResp; + uint8_t ucUapsdAc; + /* b0~3: Trigger enabled, b4~7: Delivery enabled */ + uint8_t ucUapsdSp; + /* 0: all, 1: max 2, 2: max 4, 3: max 6 */ + uint8_t ucWlanIndex; + /* This field should assign at create and keep consistency for update + * usage + */ + uint8_t ucBMCWlanIndex; + /* This field should assign at create and keep consistency for update + * usage + */ + + uint32_t u4VhtCapInfo; + uint16_t u2VhtRxMcsMap; + uint16_t u2VhtRxHighestSupportedDataRate; + uint16_t u2VhtTxMcsMap; + uint16_t u2VhtTxHighestSupportedDataRate; + uint8_t ucRtsPolicy; + /* 0: auto 1: Static BW 2: Dynamic BW 3: Legacy 7: WoRts */ + uint8_t ucVhtOpMode; + /* VHT operting mode, bit 7: Rx NSS Type, bit 4-6: Rx NSS, bit 0-1: + * Channel Width + */ + + uint8_t ucTrafficDataType; + uint8_t ucTxGfMode; /* ENUM_FEATURE_OPTION */ + uint8_t ucTxSgiMode; /* ENUM_FEATURE_OPTION */ + uint8_t ucTxStbcMode; /* ENUM_FEATURE_OPTION unused */ + uint16_t u2HwDefaultFixedRateCode; + uint8_t ucTxAmpdu; + uint8_t ucRxAmpdu; + uint32_t u4FixedPhyRate; + /* 0: desable BIT(31)==1,BITS(0,15) rate code */ + uint16_t u2MaxLinkSpeed; + /* 0: unlimit ohter: unit is 0.5 Mbps */ + uint16_t u2MinLinkSpeed; + + uint32_t u4Flags; + + union BA_SIZE { + struct CMD_HTVHT_BA_SIZE rHtVhtBaSize; + struct CMD_HE_BA_SIZE rHeBaSize; + } rBaSize; + + uint16_t u2PfmuId; /* 0xFFFF means no access right for PFMU*/ + uint8_t fgSU_MU; /* 0 : SU, 1 : MU*/ + uint8_t fgETxBfCap; /* 0 : ITxBf, 1 : ETxBf*/ + uint8_t ucSoundingPhy; + uint8_t ucNdpaRate; + uint8_t ucNdpRate; + uint8_t ucReptPollRate; + uint8_t ucTxMode; + uint8_t ucNc; + uint8_t ucNr; + uint8_t ucCBW; /* 0 : 20M, 1 : 40M, 2 : 80M, 3 : 80 + 80M*/ + uint8_t ucTotMemRequire; + uint8_t ucMemRequire20M; + uint8_t ucMemRow0; + uint8_t ucMemCol0; + uint8_t ucMemRow1; + uint8_t ucMemCol1; + uint8_t ucMemRow2; + uint8_t ucMemCol2; + uint8_t ucMemRow3; + uint8_t ucMemCol3; + uint16_t u2SmartAnt; + uint8_t ucSEIdx; + uint8_t uciBfTimeOut; + uint8_t uciBfDBW; + uint8_t uciBfNcol; + uint8_t uciBfNrow; + uint8_t aucPadding1[3]; + + uint8_t ucTxAmsduInAmpdu; + uint8_t ucRxAmsduInAmpdu; + uint8_t aucPadding2[2]; + uint32_t u4TxMaxAmsduInAmpduLen; + +#if CFG_SUPPORT_802_11AX + /* These fields can only be accessed if ucVersion = 1*/ + uint8_t ucHeMacCapInfo[HE_MAC_CAP_BYTE_NUM]; + uint8_t ucHePhyCapInfo[HE_PHY_CAP_BYTE_NUM]; + uint8_t aucPadding3[2]; + uint16_t u2HeRxMcsMapBW80; + uint16_t u2HeTxMcsMapBW80; + uint16_t u2HeRxMcsMapBW160; + uint16_t u2HeTxMcsMapBW160; + uint16_t u2HeRxMcsMapBW80P80; + uint16_t u2HeTxMcsMapBW80P80; +#endif + uint8_t aucPadding4[32]; +}; + +struct CMD_REMOVE_STA_RECORD { + uint8_t ucActionType; + uint8_t ucStaIndex; + uint8_t ucBssIndex; + uint8_t ucReserved; +}; + +struct CMD_INDICATE_PM_BSS_CREATED { + uint8_t ucBssIndex; + uint8_t ucDtimPeriod; + uint16_t u2BeaconInterval; + uint16_t u2AtimWindow; + uint8_t aucReserved[2]; +}; + +struct CMD_INDICATE_PM_BSS_CONNECTED { + uint8_t ucBssIndex; + uint8_t ucDtimPeriod; + uint16_t u2AssocId; + uint16_t u2BeaconInterval; + uint16_t u2AtimWindow; + uint8_t fgIsUapsdConnection; + uint8_t ucBmpDeliveryAC; + uint8_t ucBmpTriggerAC; + uint8_t aucReserved[1]; +}; + +struct CMD_INDICATE_PM_BSS_ABORT { + uint8_t ucBssIndex; + uint8_t aucReserved[3]; +}; + +struct CMD_SET_WMM_PS_TEST_STRUCT { + uint8_t ucBssIndex; + uint8_t bmfgApsdEnAc; + /* b0~3: trigger-en AC0~3. b4~7: delivery-en AC0~3 */ + uint8_t ucIsEnterPsAtOnce; + /* enter PS immediately without 5 second guard after connected */ + uint8_t ucIsDisableUcTrigger; + /* not to trigger UC on beacon TIM is matched (under U-APSD) */ +}; + +struct CMD_CUSTOM_NOA_PARAM_STRUCT { + uint32_t u4NoaDurationMs; /* unit: msec*/ + uint32_t u4NoaIntervalMs; /* unit: msec*/ + uint32_t u4NoaCount; + uint8_t ucBssIdx; + uint8_t aucReserved[3]; +}; + +struct CMD_CUSTOM_OPPPS_PARAM_STRUCT { + uint32_t u4CTwindowMs; + /* bit0~6 : CTWindow(unit: TU), bit7:OppPS bit (1:enable, 0:disable)*/ + uint8_t ucBssIdx; + uint8_t aucReserved[3]; +}; + +struct CMD_CUSTOM_UAPSD_PARAM_STRUCT { + uint8_t fgEnAPSD; + uint8_t fgEnAPSD_AcBe; + uint8_t fgEnAPSD_AcBk; + uint8_t fgEnAPSD_AcVo; + uint8_t fgEnAPSD_AcVi; + uint8_t ucMaxSpLen; + uint8_t aucResv[2]; +}; + +/* Definition for CHANNEL_INFO.ucBand: + * 0: Reserved + * 1: BAND_2G4 + * 2: BAND_5G + * Others: Reserved + */ +struct CHANNEL_INFO { + uint8_t ucBand; + uint8_t ucChannelNum; +}; + +struct CMD_SCAN_REQ { + uint8_t ucSeqNum; + uint8_t ucBssIndex; + uint8_t ucScanType; + uint8_t ucSSIDType; + uint8_t ucSSIDLength; + uint8_t ucNumProbeReq; + uint16_t u2ChannelMinDwellTime; + uint16_t u2ChannelDwellTime; + uint16_t u2TimeoutValue; + uint8_t aucSSID[32]; + uint8_t ucChannelType; + uint8_t ucChannelListNum; + uint8_t aucReserved[2]; + struct CHANNEL_INFO arChannelList[32]; + uint16_t u2IELen; + uint8_t aucIE[0]; /*depends on u2IELen*/ +}; + +struct PARAM_SSID { + uint32_t u4SsidLen; + /*!< SSID length in bytes. Zero length is broadcast(any) SSID */ + uint8_t aucSsid[ELEM_MAX_LEN_SSID]; +}; + +#define CMD_SCAN_REQ_V2_FUNC_RANDOM_MAC_MASK BIT(0) +#define CMD_SCAN_REQ_V2_FUNC_DIS_DBDC_SCAN_MASK BIT(1) +#define CMD_SCAN_REQ_V2_FUNC_DBDC_SCAN_TYPE_3_MASK BIT(2) +/* use 6*4 = 24 bytes as bssid of being scanned ap */ +#define CMD_SCAN_REQ_V2_FUNC_USE_PADDING_AS_BSSID BIT(3) +#define CMD_SCAN_REQ_V2_FUNC_RANDOM_PROBE_REQ_SN_MASK BIT(4) + +struct CMD_SCAN_REQ_V2 { + uint8_t ucSeqNum; + uint8_t ucBssIndex; + uint8_t ucScanType; + uint8_t ucSSIDType; + uint8_t ucSSIDNum; + uint8_t ucNumProbeReq; + uint8_t ucScnFuncMask; + uint8_t auVersion[1]; + struct PARAM_SSID arSSID[4]; + uint16_t u2ProbeDelayTime; + uint16_t u2ChannelDwellTime; + uint16_t u2TimeoutValue; + uint8_t ucChannelType; + uint8_t ucChannelListNum; + struct CHANNEL_INFO arChannelList[32]; + uint16_t u2IELen; + uint8_t aucIE[600]; /*depends on u2IELen*/ + uint8_t ucChannelListExtNum; + uint8_t ucSSIDExtNum; + uint16_t u2ChannelMinDwellTime; + struct CHANNEL_INFO arChannelListExtend[32]; + struct PARAM_SSID arSSIDExtend[6]; + uint8_t aucBSSID[MAC_ADDR_LEN]; + uint8_t aucRandomMac[MAC_ADDR_LEN]; + uint8_t aucPadding_3[64]; +}; + +/* TLV for CMD_ID_SCAN_REQ_V2*/ +enum ENUM_CMD_ID_SCAN_REQ_V2_TAG_ID { + CMD_ID_SCAN_REQ_V2_TAG_00_TBD = 0, + CMD_ID_SCAN_REQ_V2_TAG_01_BSSID_AND_RANDOM_MAC = 1, + CMD_ID_SCAN_REQ_V2_TAG_ID_NUM +}; + +struct CMD_ID_SCAN_REQ_V2_TAG_01_BSSID_AND_RANDOM_MAC { + uint8_t aucRandomMacAddr[6]; + uint8_t aucBSSID[6]; +}; + + +struct CMD_SCAN_CANCEL { + uint8_t ucSeqNum; + uint8_t ucIsExtChannel; /* For P2P channel extension. */ + uint8_t aucReserved[2]; +}; + +struct CMD_P2P_SEC_CHECK { + uint32_t u4KeyId; + uint8_t aucBuffer[32]; +}; + + +struct CMD_RESET_BA_SCOREBOARD { + uint8_t ucflag; + uint8_t ucTID; + uint8_t aucMacAddr[MAC_ADDR_LEN]; +}; + + +struct CMD_IPV4_NETWORK_ADDRESS_V0 { + uint8_t aucIpAddr[IPV4_ADDR_LEN]; +}; + +struct CMD_IPV4_NETWORK_ADDRESS { + uint8_t aucIpAddr[IPV4_ADDR_LEN]; + uint8_t aucIpMask[IPV4_ADDR_LEN]; +}; + +struct CMD_SET_NETWORK_ADDRESS_LIST { + uint8_t ucBssIndex; + uint8_t ucAddressCount; + uint8_t ucVersion; + uint8_t ucReserved[1]; + struct CMD_IPV4_NETWORK_ADDRESS arNetAddress[1]; +}; + +struct CMD_IPV6_NETWORK_ADDRESS { + uint8_t aucIpAddr[IPV6_ADDR_LEN]; +}; + +struct CMD_IPV6_NETWORK_ADDRESS_LIST { + uint8_t ucBssIndex; + uint8_t ucAddressCount; + uint8_t ucReserved[2]; + struct CMD_IPV6_NETWORK_ADDRESS arNetAddress[1]; +}; + +struct CMD_SET_RRM_CAPABILITY { + /* DWORD_0 - Common Part*/ + uint8_t ucCmdVer; + uint8_t aucPadding0[1]; + uint16_t u2CmdLen; + /* Cmd size including common part and body */ + + /* DWORD_1 afterwards - Command Body*/ + uint8_t ucBssIndex; + uint8_t ucRrmEnable; /* 802.11k rrm flag */ + uint8_t ucCapabilities[5]; + /* Table 7-43e, RRM Enabled Capabilities Field */ + uint8_t aucPadding1[1]; + + uint8_t aucPadding2[32]; /* for new param in the future */ +}; + +struct CMD_SET_AP_CONSTRAINT_PWR_LIMIT { + /* DWORD_0 - Common Part*/ + uint8_t ucCmdVer; + uint8_t aucPadding0[1]; + uint16_t u2CmdLen; + /* Cmd size including common part and body */ + + /* DWORD_1 afterwards - Command Body*/ + uint8_t ucBssIndex; + uint8_t ucPwrSetEnable; + int8_t cMaxTxPwr; /* In unit of 0.5 dBm (signed) */ + int8_t cMinTxPwr; /* In unit of 0.5 dBm (signed) */ + + uint8_t aucPadding1[32]; /* for new param in the future */ +}; + +/* RTT */ +struct CMD_RTT_REQ { + uint8_t ucSeqNum; + uint8_t ucBssIndex; + uint8_t ucRttType; + uint8_t ucRttRole; + bool fgRttTrigger; + uint8_t ucNumRttReq; + uint16_t u2UpdatePeriodIn10MS; +}; + +struct CMD_RTT_CALIBR { + uint8_t aucMacAddr[MAC_ADDR_LEN]; + uint8_t ucNumRttMeas; + uint8_t ucReserved; +}; + +struct CMD_SET_SCHED_SCAN_ENABLE { + uint8_t ucSchedScanAct; /*ENUM_SCHED_SCAN_ACT*/ + uint8_t aucReserved[3]; +}; + +struct SCAN_SCHED_SSID_MATCH_SETS { + uint32_t cRssiThresold; + uint8_t aucSsid[32]; + uint8_t u4SsidLen; + uint8_t aucPadding_1[3]; +}; + +struct CMD_SCAN_SCHED_REQ { + uint8_t ucVersion; + uint8_t ucSeqNum; + /* Fw SCHED SCAN DONE after stop */ + uint8_t fgStopAfterIndication; + uint8_t ucSsidNum; + uint8_t ucMatchSsidNum; + uint8_t aucPadding_0; + uint16_t u2IELen; + /* Send prob request SSID set */ + struct PARAM_SSID auSsid[10]; + /* Match SSID set */ + struct SCAN_SCHED_SSID_MATCH_SETS auMatchSsid[16]; + uint8_t ucChannelType; + uint8_t ucChnlNum; + uint8_t ucMspEntryNum; + uint8_t ScnFuncMask; + struct CHANNEL_INFO aucChannel[64]; + /* SCHED SCN Interval */ + uint16_t au2MspList[10]; + uint8_t aucPadding_3[64]; + uint8_t aucIE[0]; +}; + +enum WIFI_SCAN_EVENT { + WIFI_SCAN_BUFFER_FULL = 0, + WIFI_SCAN_COMPLETE, +}; + +struct CMD_HIF_CTRL { + uint8_t ucHifType; + uint8_t ucHifDirection; + uint8_t ucHifStop; + uint8_t ucHifSuspend; + uint8_t aucReserved2[32]; +}; + +struct CMD_MU_EDCA_PARAMS { + uint8_t ucECWmin; + uint8_t ucECWmax; + uint8_t ucAifsn; + uint8_t ucIsACMSet; + uint8_t ucMUEdcaTimer; + uint8_t aucPadding[3]; +}; + +struct CMD_MQM_UPDATE_MU_EDCA_PARMS { + /* DWORD_0 - Common Part*/ + uint8_t ucCmdVer; + uint8_t aucPadding0[1]; + uint16_t u2CmdLen; /* Cmd size including common part and body */ + + /* DWORD_1 afterwards - Command Body*/ + uint8_t ucBssIndex; + uint8_t fgIsQBSS; + uint8_t ucWmmSet; + uint8_t aucPadding1[1]; + + struct CMD_MU_EDCA_PARAMS arMUEdcaParams[4]; /* number of ACs */ + uint8_t aucPadding2[32]; +}; + +struct CMD_RLM_UPDATE_SR_PARMS { + /* DWORD_0 - Common Part*/ + uint8_t ucCmdVer; + uint8_t aucPadding0[1]; + uint16_t u2CmdLen; /* Cmd size including common part and body */ + + /* DWORD_1 afterwards - Command Body*/ + uint8_t ucBssIndex; + uint8_t ucSRControl; + uint8_t ucNonSRGObssPdMaxOffset; + uint8_t ucSRGObssPdMinOffset; + uint8_t ucSRGObssPdMaxOffset; + uint8_t aucPadding1[3]; + uint32_t u4SRGBSSColorBitmapLow; + uint32_t u4SRGBSSColorBitmapHigh; + uint32_t u4SRGPartialBSSIDBitmapLow; + uint32_t u4SRGPartialBSSIDBitmapHigh; + + uint8_t aucPadding2[32]; +}; + +struct CMD_MDDP_FILTER_RULE { + /* DWORD_0 - Common Part*/ + uint8_t ucCmdVer; + uint8_t aucPadding0[1]; + uint16_t u2CmdLen; /* Cmd size including common part and body */ + + /* DWORD_1 afterwards - Command Body*/ + uint8_t ucPfType; + uint8_t ucPfNum; + uint8_t aucPadding1[2]; + uint8_t aucWhPfClsFilterMddp[0]; +}; + +/*---------------------------------------------------------------------------*/ +/* EVENT Packets */ +/*---------------------------------------------------------------------------*/ + +/* event of tkip mic error */ +struct EVENT_MIC_ERR_INFO { + uint32_t u4Flags; + uint8_t aucStaAddr[6]; +}; + +/* event of add key done for port control */ +struct EVENT_ADD_KEY_DONE_INFO { + uint8_t ucBSSIndex; + uint8_t ucReserved; + uint8_t aucStaAddr[6]; +}; + +struct LINK_QUALITY { + int8_t cRssi; /* AIS Network. */ + int8_t cLinkQuality; + uint16_t u2LinkSpeed; /* TX rate1 */ + uint8_t ucMediumBusyPercentage; /* Read clear */ + uint8_t ucIsLQ0Rdy; + /* Link Quality BSS0 Ready. */ + uint8_t aucReserve[2]; +}; + +struct EVENT_LINK_QUALITY { + struct LINK_QUALITY rLq[4]; + /*Refer to BSS_INFO_NUM, but event should not use HW realted + * definition + */ +}; + +struct EVENT_ACTIVATE_STA_REC { + uint8_t aucMacAddr[6]; + uint8_t ucStaRecIdx; + uint8_t ucBssIndex; +}; + +struct EVENT_DEACTIVATE_STA_REC { + uint8_t ucStaRecIdx; + uint8_t aucReserved[3]; +}; + +struct EVENT_BUG_REPORT { + + /* BugReportVersion */ + uint32_t u4BugReportVersion; + + /* FW Module State */ + uint32_t u4FWState; /*LP, roaming*/ + uint32_t u4FWScanState; + uint32_t u4FWCnmState; + + /* Scan Counter */ + uint32_t u4ReceivedBeaconCount; + uint32_t u4ReceivedProbeResponseCount; + uint32_t u4SentProbeRequestCount; + uint32_t u4SentProbeRequestFailCount; + + /* Roaming Counter */ + uint32_t u4RoamingDebugFlag; + uint32_t u4RoamingThreshold; + uint32_t u4RoamingCurrentRcpi; + + /* RF Counter */ + uint32_t u4RFPriChannel; + uint32_t u4RFChannelS1; + uint32_t u4RFChannelS2; + uint32_t u4RFChannelWidth; + uint32_t u4RFSco; + + /* Coex Counter */ + uint32_t u4BTProfile; + uint32_t u4BTOn; + uint32_t u4LTEOn; + + /* Low Power Counter */ + uint32_t u4LPTxUcPktNum; + uint32_t u4LPRxUcPktNum; + uint32_t u4LPPSProfile; + + /* Base Band Counter */ + uint32_t u4OfdmPdCnt; + uint32_t u4CckPdCnt; + uint32_t u4CckSigErrorCnt; + uint32_t u4CckSfdErrorCnt; + uint32_t u4OfdmSigErrorCnt; + uint32_t u4OfdmTaqErrorCnt; + uint32_t u4OfdmFcsErrorCnt; + uint32_t u4CckFcsErrorCnt; + uint32_t u4OfdmMdrdyCnt; + uint32_t u4CckMdrdyCnt; + uint32_t u4PhyCcaStatus; + uint32_t u4WifiFastSpiStatus; + + /* Mac RX Counter */ + uint32_t u4RxMdrdyCount; + uint32_t u4RxFcsErrorCount; + uint32_t u4RxbFifoFullCount; + uint32_t u4RxMpduCount; + uint32_t u4RxLengthMismatchCount; + uint32_t u4RxCcaPrimCount; + uint32_t u4RxEdCount; + + uint32_t u4LmacFreeRunTimer; + uint32_t u4WtblReadPointer; + uint32_t u4RmacWritePointer; + uint32_t u4SecWritePointer; + uint32_t u4SecReadPointer; + uint32_t u4DmaReadPointer; + + /* Mac TX Counter */ + uint32_t u4TxChannelIdleCount; + uint32_t u4TxCcaNavTxTime; + +}; + +struct CMD_GET_STATISTICS { +/* DWORD_0 - Common Part*/ + uint8_t ucCmdVer; + /* if the structure size is changed, the ucCmdVer shall be increased.*/ + uint8_t aucPadding0[1]; + uint16_t u2CmdLen; /* cmd size including common part and body.*/ + /** general use */ + uint8_t ucGeneralFlags; + /** TRUE: ucBssIndex is valid */ + uint8_t ucBssIndexValid; + uint8_t ucBssIndex; + uint8_t aucPadding1[1]; + /** Request the value for specific BSS */ + uint8_t aucPadding2[64]; +}; + +struct EVENT_STATISTICS { + /* Link quality for customer */ + union LARGE_INTEGER rTransmittedFragmentCount; + union LARGE_INTEGER rMulticastTransmittedFrameCount; + union LARGE_INTEGER rFailedCount; + union LARGE_INTEGER rRetryCount; + union LARGE_INTEGER rMultipleRetryCount; + union LARGE_INTEGER rRTSSuccessCount; + union LARGE_INTEGER rRTSFailureCount; + union LARGE_INTEGER rACKFailureCount; + union LARGE_INTEGER rFrameDuplicateCount; + union LARGE_INTEGER rReceivedFragmentCount; + union LARGE_INTEGER rMulticastReceivedFrameCount; + union LARGE_INTEGER rFCSErrorCount; + union LARGE_INTEGER rMdrdyCnt; + union LARGE_INTEGER rChnlIdleCnt; + uint32_t u4HwMacAwakeDuration; + uint32_t au4Padding3[15]; + + /* wifi_radio_stat */ + int32_t i4RadioIdx; + uint32_t u4OnTime; + uint32_t u4TxTime; + uint32_t u4NumTxLevels; /* for au4TxTimePerLevels */ + uint32_t u4RxTime; + uint32_t u4OnTimeScan; + uint32_t u4OnTimeNbd; + uint32_t u4OnTimeGscan; + uint32_t u4OnTimeRoamScan; + uint32_t u4OnTimePnoScan; + uint32_t u4OnTimeHs20; + uint32_t u4NumChannels; + uint32_t au4TxTimePerLevels[78]; + + /* wifi_iface_stat */ + int32_t i4IfaceIdx; + uint32_t u4NumWifiInterfaceLinkLayerInfo; + uint32_t u4BeaconRx; + uint32_t u4AverageTsfOffsetHigh; + uint32_t u4AverageTsfOffsetLow; + uint32_t u4LeakyApDetected; + uint32_t u4LeakyApAvgNumFramesLeaked; + uint32_t u4Leaky_ap_guard_time; + uint32_t u4MgmtRx; + uint32_t u4MgmtActionRx; + uint32_t u4MgmtActionTx; + int32_t i4RssiMgmt; + int32_t i4RssiData; + int32_t i4RssiAck; + uint32_t u4NumAc; + uint32_t u4NumPeers; + + /* wifi_interface_link_layer_info */ + int16_t i2Mode; + uint8_t aucMacAddr[6]; + int16_t i2State; + int16_t i2Roaming; + uint32_t u4Capabilities; + uint8_t aucSsid[33]; + uint8_t aucPadding4[1]; + uint8_t aucBssid[6]; + uint8_t aucPadding5[2]; + uint8_t aucApCountryStr[3]; + uint8_t aucPadding6[1]; + uint8_t aucCountryStr[3]; + uint8_t aucPadding7[1]; + + /* wifi_wmm_ac_stat: VO */ + uint32_t u4VoTxMpdu; + uint32_t u4VoRxMpdu; + uint32_t u4VoTxMcast; + uint32_t u4VoRxMcast; + uint32_t u4VoRxAmpdu; + uint32_t u4VoTxAmpdu; + uint32_t u4VoMpduLost; + uint32_t u4VoRetries; + uint32_t u4VoRetriesShort; + uint32_t u4VoRetriesLong; + uint32_t u4VoContentionTimeMin; + uint32_t u4VoContentionTimeMax; + uint32_t u4VoContentionTimeAvg; + uint32_t u4VoContentionNumSamples; + + /* wifi_wmm_ac_stat: VI */ + uint32_t u4ViTxMpdu; + uint32_t u4ViRxMpdu; + uint32_t u4ViTxMcast; + uint32_t u4ViRxMcast; + uint32_t u4ViRxAmpdu; + uint32_t u4ViTxAmpdu; + uint32_t u4ViMpduLost; + uint32_t u4ViRetries; + uint32_t u4ViRetriesShort; + uint32_t u4ViRetriesLong; + uint32_t u4ViContentionTimeMin; + uint32_t u4ViContentionTimeMax; + uint32_t u4ViContentionTimeAvg; + uint32_t u4ViContentionNumSamples; + + /* wifi_wmm_ac_stat: BE */ + uint32_t u4BeTxMpdu; + uint32_t u4BeRxMpdu; + uint32_t u4BeTxMcast; + uint32_t u4BeRxMcast; + uint32_t u4BeRxAmpdu; + uint32_t u4BeTxAmpdu; + uint32_t u4BeMpduLost; + uint32_t u4BeRetries; + uint32_t u4BeRetriesShort; + uint32_t u4BeRetriesLong; + uint32_t u4BeContentionTimeMin; + uint32_t u4BeContentionTimeMax; + uint32_t u4BeContentionTimeAvg; + uint32_t u4BeContentionNumSamples; + + /* wifi_wmm_ac_stat: BK */ + uint32_t u4BkTxMpdu; + uint32_t u4BkRxMpdu; + uint32_t u4BkTxMcast; + uint32_t u4BkRxMcast; + uint32_t u4BkRxAmpdu; + uint32_t u4BkTxAmpdu; + uint32_t u4BkMpduLost; + uint32_t u4BkRetries; + uint32_t u4BkRetriesShort; + uint32_t u4BkRetriesLong; + uint32_t u4BkContentionTimeMin; + uint32_t u4BkContentionTimeMax; + uint32_t u4BkContentionTimeAvg; + uint32_t u4BkContentionNumSamples; + + uint32_t au4PaddingTail[128]; +}; + +struct EVENT_SCAN_DONE { + uint8_t ucSeqNum; + uint8_t ucSparseChannelValid; + struct CHANNEL_INFO rSparseChannel; + uint8_t ucCompleteChanCount; + uint8_t ucCurrentState; + uint8_t ucScanDoneVersion; + uint8_t ucReserved; + uint32_t u4ScanDurBcnCnt; + uint8_t fgIsPNOenabled; + uint8_t aucReserving[3]; + /*channel idle count # Mike */ + uint8_t ucSparseChannelArrayValidNum; + uint8_t aucReserved[3]; + uint8_t aucChannelNum[SCAN_DONE_EVENT_MAX_CHANNEL_NUM]; + /* Idle format for au2ChannelIdleTime */ + /* 0: first bytes: idle time(ms) 2nd byte: dwell time(ms) */ + /* 1: first bytes: idle time(8ms) 2nd byte: dwell time(8ms) */ + /* 2: dwell time (16us) */ + uint16_t au2ChannelIdleTime[SCAN_DONE_EVENT_MAX_CHANNEL_NUM]; + /* Beacon and Probe Response Count in each Channel */ + uint8_t aucChannelBAndPCnt[SCAN_DONE_EVENT_MAX_CHANNEL_NUM]; + /* Mdrdy Count in each Channel */ + uint8_t aucChannelMDRDYCnt[SCAN_DONE_EVENT_MAX_CHANNEL_NUM]; + uint32_t u4ScanDurBcnCnt2G4; + uint32_t u4ScanDurBcnCnt5G; + uint16_t au2ChannelScanTime[SCAN_DONE_EVENT_MAX_CHANNEL_NUM]; +}; + +struct EVENT_CH_PRIVILEGE { + uint8_t ucBssIndex; + uint8_t ucTokenID; + uint8_t ucStatus; + uint8_t ucPrimaryChannel; + uint8_t ucRfSco; + uint8_t ucRfBand; + uint8_t ucRfChannelWidth; + /* To support 80/160MHz bandwidth */ + uint8_t ucRfCenterFreqSeg1; + /* To support 80/160MHz bandwidth */ + uint8_t ucRfCenterFreqSeg2; + /* To support 80/160MHz bandwidth */ + uint8_t ucReqType; + uint8_t ucDBDCBand; /* ENUM_CMD_REQ_DBDC_BAND_T*/ + uint8_t aucReserved; + uint32_t u4GrantInterval; /* In unit of ms */ + uint8_t aucReserved2[8]; +}; + +enum ENUM_BEACON_TIMEOUT_REASON { + BEACON_TIMEOUT_REASON_HW_BEACON_LOST_NONADHOC, + BEACON_TIMEOUT_REASON_HW_BEACON_LOST_ADHOC, + BEACON_TIMEOUT_REASON_HW_TSF_DRIFT, + BEACON_TIMEOUT_REASON_NULL_FRAME_THRESHOLD, + BEACON_TIMEOUT_REASON_AGING_THRESHOLD, + BEACON_TIMEOUT_REASON_BSSID_BEACON_PEIROD_NOT_ILLIGAL, + BEACON_TIMEOUT_REASON_CONNECTION_FAIL, + BEACON_TIMEOUT_REASON_ALLOCAT_NULL_PKT_FAIL_THRESHOLD, + BEACON_TIMEOUT_REASON_NO_TX_DONE_EVENT, + BEACON_TIMEOUT_REASON_UNSPECIF_REASON, + BEACON_TIMEOUT_REASON_SET_CHIP, + BEACON_TIMEOUT_REASON_KEEP_SCAN_AP_MISS_CHECK_FAIL, + BEACON_TIMEOUT_REASON_KEEP_UNCHANGED_LOW_RSSI_CHECK_FAIL, + BEACON_TIMEOUT_REASON_NULL_FRAME_LIFE_TIMEOUT, + BEACON_TIMEOUT_REASON_HIGH_PER, + BEACON_TIMEOUT_REASON_NUM +}; + +struct EVENT_BSS_BEACON_TIMEOUT { + uint8_t ucBssIndex; + uint8_t ucReasonCode; + uint8_t aucReserved[2]; +}; + +struct EVENT_STA_AGING_TIMEOUT { + uint8_t ucStaRecIdx; + uint8_t aucReserved[3]; +}; + +struct EVENT_NOA_TIMING { + uint8_t ucIsInUse; + /* Indicate if this entry is in use or not */ + uint8_t ucCount; /* Count */ + uint8_t aucReserved[2]; + + uint32_t u4Duration; /* Duration */ + uint32_t u4Interval; /* Interval */ + uint32_t u4StartTime; /* Start Time */ +}; + +struct EVENT_UPDATE_NOA_PARAMS { + uint8_t ucBssIndex; + uint8_t aucReserved[2]; + uint8_t ucEnableOppPS; + uint16_t u2CTWindow; + + uint8_t ucNoAIndex; + uint8_t ucNoATimingCount; /* Number of NoA Timing */ + struct EVENT_NOA_TIMING arEventNoaTiming[8/*P2P_MAXIMUM_NOA_COUNT*/]; +}; + +struct EVENT_AP_OBSS_STATUS { + uint8_t ucBssIndex; + uint8_t ucObssErpProtectMode; + uint8_t ucObssHtProtectMode; + uint8_t ucObssGfOperationMode; + uint8_t ucObssRifsOperationMode; + uint8_t ucObssBeaconForcedTo20M; + uint8_t aucReserved[2]; +}; + +struct EVENT_RDD_STATUS { + uint8_t ucRddStatus; + uint8_t aucReserved[3]; +}; + +struct EVENT_NLO_DONE { + uint8_t ucSeqNum; + uint8_t ucStatus; /* 0: Found / other: reserved */ + uint8_t aucReserved[2]; +}; + +/* RTT */ +struct RTT_PEER { + uint8_t aucBssid[MAC_ADDR_LEN]; + uint16_t u2CalibrInNS; + uint32_t u4RangeInNS; + uint32_t u4AccuracyInNS; + + uint32_t u4RangeInCM; + uint32_t u4AccuracyInCM; + uint32_t *pu4APLon; + uint32_t *pu4APLat; + PARAM_RSSI rRssi; +}; + +#define PARAM_MAX_RTT_PEERS 8 +struct EVENT_RTT_UPDATE_RANGE { + uint8_t ucNumPeer; + uint8_t aucReserved[3]; + struct RTT_PEER arPeers[PARAM_MAX_RTT_PEERS]; + uint16_t au2Event[25]; + uint16_t u2Timer; +}; +struct EVENT_RTT_UPDATE_LOCATION { + uint8_t ucNumPeer; + uint8_t aucReserved[3]; + struct RTT_PEER arPeers[PARAM_MAX_RTT_PEERS]; + uint16_t au2Event[25]; + uint16_t u2Timer; +}; + +struct EVENT_RTT_DISCOVER_PEER { + uint16_t au2Event[25]; + uint16_t u2Timer; +}; + +struct EVENT_BUILD_DATE_CODE { + uint8_t aucDateCode[16]; +}; + +struct EVENT_BATCH_RESULT_ENTRY { + uint8_t aucBssid[MAC_ADDR_LEN]; + uint8_t aucSSID[ELEM_MAX_LEN_SSID]; + uint8_t ucSSIDLen; + int8_t cRssi; + uint32_t ucFreq; + uint32_t u4Age; + uint32_t u4Dist; + uint32_t u4Distsd; +}; + +struct EVENT_BATCH_RESULT { + uint8_t ucScanCount; + uint8_t aucReserved[3]; + struct EVENT_BATCH_RESULT_ENTRY arBatchResult[12]; + /* Must be the same with SCN_BATCH_STORE_MAX_NUM*/ +}; + +struct CMD_SET_FILTER_COEFFICIENT { + uint32_t u4BssIndex; + int32_t i4FilterCoefficient; + uint8_t aucReserved[8]; +}; + +#define BA_FW_DROP_SN_BMAP_SZ 8 +struct EVENT_BA_FW_DROP_RECORD { + uint8_t ucStaRecIdx; + uint8_t ucTid; + uint16_t u2DropSnStart; + uint32_t u4DropReason; + uint8_t aucSnBmap[BA_FW_DROP_SN_BMAP_SZ]; + uint8_t aucDropLastAmsduSnBmap[BA_FW_DROP_SN_BMAP_SZ]; + uint8_t aucReserved[4]; +}; + +struct EVENT_BA_FW_DROP_SN { + uint8_t ucEvtVer; + uint8_t aucPadding0[1]; + uint16_t ucEvtLen; + uint8_t ucRecordNum; + uint8_t aucPadding1[3]; + struct EVENT_BA_FW_DROP_RECORD arBaFwDropRecord[8]; + /*CFG_NUM_OF_RX_BA_AGREEMENTS*/ +}; + +/* NDIS_MEDIA_STATE */ +enum ENUM_PARAM_MEDIA_STATE { + MEDIA_STATE_CONNECTED = 0, + MEDIA_STATE_DISCONNECTED, + MEDIA_STATE_ROAMING_DISC_PREV, + /* transient disconnected state for normal/fast roamming purpose */ + MEDIA_STATE_TO_BE_INDICATED, + MEDIA_STATE_NUM +}; + +enum ENUM_LOG_UI_LVL { + ENUM_LOG_UI_LVL_DEFAULT = 0, + ENUM_LOG_UI_LVL_MORE = 1, + ENUM_LOG_UI_LVL_EXTREME = 2, +}; + +struct CMD_EVENT_LOG_UI_INFO { + uint32_t ucVersion; /* default is 1*/ + uint32_t ucLogLevel; /* 0: Default, 1: More, 2: Extreme*/ + uint8_t aucReserved[4]; /*reserved*/ +}; + +struct CMD_WAKE_HIF { + /* use in-band signal to wakeup system, ENUM_HIF_TYPE */ + uint8_t ucWakeupHif; + uint8_t ucGpioPin; /* GPIO Pin */ + uint8_t ucTriggerLvl; /* GPIO Pin */ + uint8_t aucResv1[1]; + /* 0: low to high, 1: high to low */ + uint32_t u4GpioInterval; + uint8_t aucResv2[4]; +}; + +struct WOW_PORT { + uint8_t ucIPv4UdpPortCnt; + uint8_t ucIPv4TcpPortCnt; + uint8_t ucIPv6UdpPortCnt; + uint8_t ucIPv6TcpPortCnt; + uint16_t ausIPv4UdpPort[MAX_TCP_UDP_PORT]; + uint16_t ausIPv4TcpPort[MAX_TCP_UDP_PORT]; + uint16_t ausIPv6UdpPort[MAX_TCP_UDP_PORT]; + uint16_t ausIPv6TcpPort[MAX_TCP_UDP_PORT]; +}; + +struct CMD_WOWLAN_PARAM { + uint8_t ucCmd; + uint8_t ucDetectType; + uint16_t u2FilterFlag; /* ARP/MC/DropExceptMagic/SendMagicToHost */ + uint8_t ucScenarioID; /* WOW/WOBLE/Proximity */ + uint8_t ucBlockCount; + uint8_t aucReserved1[2]; + struct CMD_WAKE_HIF astWakeHif[2]; + struct WOW_PORT stWowPort; + uint8_t aucReserved2[32]; +}; + +/*Oshare mode*/ +#define CMD_OSHARE_LENGTH_MAX 64 +struct CMD_OSHARE { + uint8_t ucCmdVersion; /* CMD version = OSHARE_CMD_V1*/ + uint8_t ucCmdType; + uint8_t ucMagicCode; + /* It's like CRC, OSHARE_MAGIC_CODE*/ + uint8_t ucCmdBufferLen; /*buffer length <= 64*/ + uint8_t aucBuffer[CMD_OSHARE_LENGTH_MAX]; +}; + +struct EVENT_MDDP_FILTER_RULE { + /* DWORD_0 - Common Part*/ + uint8_t ucEvtVer; + uint8_t aucPadding0[1]; + uint16_t u2EvtLen; + + /* DWORD_1 - afterwards*/ + uint8_t ucPfType; + uint8_t ucPfNum; + uint8_t aucPadding1[2]; + uint32_t au4PfStatusBitmap[64]; +}; + +struct CMD_DOMAIN_CHANNEL { + uint16_t u2ChNum; + uint8_t aucPadding[2]; + uint32_t eFlags; /*enum ieee80211_channel_flags*/ +}; + +struct CMD_DOMAIN_ACTIVE_CHANNEL_LIST { + uint8_t u1ActiveChNum2g; + uint8_t u1ActiveChNum5g; + uint8_t aucPadding[2]; + struct CMD_DOMAIN_CHANNEL arChannels[0]; +}; + +struct CMD_SET_DOMAIN_INFO_V2 { + /* DWORD_0 - Country code*/ + uint32_t u4CountryCode; + + /* DWORD_1 - 2.4G & 5G BW info*/ + uint8_t uc2G4Bandwidth; /* CONFIG_BW_20_40M or CONFIG_BW_20M */ + uint8_t uc5GBandwidth; /* CONFIG_BW_20_40M or CONFIG_BW_20M */ + uint8_t aucPadding[2]; + + /* DWORD_2 ~ - 2.4G & 5G active channel info*/ + struct CMD_DOMAIN_ACTIVE_CHANNEL_LIST arActiveChannels; +}; + +#define SINGLE_SKU_PARAM_NUM 69 +struct CMD_SKU_TABLE_TYPE { + int8_t i1PwrLimit[SINGLE_SKU_PARAM_NUM]; +}; + +struct CMD_TXPOWER_CHANNEL_POWER_LIMIT_PER_RATE { + uint8_t u1CentralCh; + struct CMD_SKU_TABLE_TYPE aucTxPwrLimit; +}; + +struct CMD_SET_TXPOWER_COUNTRY_TX_POWER_LIMIT_PER_RATE { + /* DWORD_0 - Common info*/ + uint8_t ucCmdVer; + uint8_t aucPadding0[1]; + uint16_t u2CmdLen; + + /* DWORD_1 - CMD hint*/ + uint8_t ucNum; /* channel #*/ + uint8_t eBand; /* 2.4g or 5g*/ + uint8_t bCmdFinished; + /* hint for whether 2.4g/5g tx power limit value all be sent*/ + uint8_t aucPadding1[1]; + + /* DWORD_2 - Country code*/ + uint32_t u4CountryCode; + + /* WORD_3 ~ 10 - Padding*/ + uint8_t aucPadding2[32]; + + /* DWORD_11 ~ - Tx power limit values*/ + struct CMD_TXPOWER_CHANNEL_POWER_LIMIT_PER_RATE rChannelPowerLimit[0]; +}; + +#define POWER_LIMIT_TXBF_BACKOFF_PARAM_NUM 6 +struct CMD_TXPWR_TXBF_CHANNEL_BACKOFF { + uint8_t ucCentralCh; + uint8_t aucPadding0[1]; + int8_t acTxBfBackoff[POWER_LIMIT_TXBF_BACKOFF_PARAM_NUM]; +}; + +#define CMD_POWER_LIMIT_TABLE_SUPPORT_CHANNEL_NUM 64 +struct CMD_TXPWR_TXBF_SET_BACKOFF { + uint8_t ucCmdVer; + uint8_t aucPadding0[1]; + uint16_t u2CmdLen; + uint8_t ucNum; + uint8_t ucBssIdx; + uint8_t aucPadding1[2]; + uint8_t aucPadding2[32]; + struct CMD_TXPWR_TXBF_CHANNEL_BACKOFF + rChannelTxBfBackoff[CMD_POWER_LIMIT_TABLE_SUPPORT_CHANNEL_NUM]; +}; + +/* The DBDC band request from driver. + * So far, the actual used DBDC band is decdied in firmware by channel. + * Driver should use ENUM_CMD_REQ_BAND_AUTO only. + */ +enum ENUM_CMD_REQ_DBDC_BAND { + ENUM_CMD_REQ_BAND_0 = 0, + ENUM_CMD_REQ_BAND_1 = 1, + ENUM_CMD_REQ_BAND_ALL = 3, + ENUM_CMD_REQ_BAND_AUTO = 4, + ENUM_CMD_REQ_BAND_NUM /*Just for checking.*/ +}; + +enum ENUM_EVENT_OPMODE_CHANGE_REASON { + EVENT_OPMODE_CHANGE_REASON_DBDC = 0, + EVENT_OPMODE_CHANGE_REASON_COANT = 1, + EVENT_OPMODE_CHANGE_REASON_DBDC_SCAN = 2, + EVENT_OPMODE_CHANGE_REASON_SMARTGEAR = 3, + EVENT_OPMODE_CHANGE_REASON_COEX = 4, + EVENT_OPMODE_CHANGE_REASON_SMARTGEAR_1T2R = 5, +}; + +struct EVENT_OPMODE_CHANGE { + /* DWORD_0 - Common Part*/ + uint8_t ucEvtVer; + uint8_t aucPadding0[1]; + uint16_t u2EvtLen; + + uint8_t ucBssBitmap; /*Bit[3:0]*/ + uint8_t ucEnable; /*Enable OpTxRx limitation/change*/ + uint8_t ucOpTxNss; /*0: don't care*/ + uint8_t ucOpRxNss; /*0: don't care*/ + + uint8_t ucReason; /* ENUM_EVENT_OPMODE_CHANGE_REASON_T*/ + uint8_t aucPadding1[63]; +}; + +#define EVENT_GET_CNM_BAND_NUM 2 /* ENUM_BAND_NUM*/ +#define EVENT_GET_CNM_MAX_OP_CHNL_NUM 3 /* MAX_OP_CHNL_NUM*/ +#define EVENT_GET_CNM_MAX_BSS_NUM 4 /* BSS_INFO_NUM*/ +#define EVENT_GET_CNM_AMX_BSS_FULL_NUM 5 /* BSS_INFO_FULL_NUM*/ +struct EVENT_GET_CNM { + uint8_t fgIsDbdcEnable; + + uint8_t ucOpChNum[EVENT_GET_CNM_BAND_NUM]; + uint8_t ucChList[EVENT_GET_CNM_BAND_NUM] + [EVENT_GET_CNM_MAX_OP_CHNL_NUM]; + uint8_t ucChBw[EVENT_GET_CNM_BAND_NUM] + [EVENT_GET_CNM_MAX_OP_CHNL_NUM]; + uint8_t ucChSco[EVENT_GET_CNM_BAND_NUM] + [EVENT_GET_CNM_MAX_OP_CHNL_NUM]; + uint8_t ucChNetNum[EVENT_GET_CNM_BAND_NUM] + [EVENT_GET_CNM_MAX_OP_CHNL_NUM]; + uint8_t ucChBssList[EVENT_GET_CNM_BAND_NUM] + [EVENT_GET_CNM_MAX_OP_CHNL_NUM][EVENT_GET_CNM_MAX_BSS_NUM]; + /* BAND/CH/BSS */ + + uint8_t ucBssInuse[EVENT_GET_CNM_AMX_BSS_FULL_NUM]; + uint8_t ucBssActive[EVENT_GET_CNM_AMX_BSS_FULL_NUM]; + uint8_t ucBssConnectState[EVENT_GET_CNM_AMX_BSS_FULL_NUM]; + + uint8_t ucBssCh[EVENT_GET_CNM_AMX_BSS_FULL_NUM]; + uint8_t ucBssDBDCBand[EVENT_GET_CNM_AMX_BSS_FULL_NUM]; + uint8_t ucBssWmmSet[EVENT_GET_CNM_AMX_BSS_FULL_NUM]; + uint8_t ucBssWmmDBDCBand[EVENT_GET_CNM_AMX_BSS_FULL_NUM]; + uint8_t ucBssOMACSet[EVENT_GET_CNM_AMX_BSS_FULL_NUM]; + uint8_t ucBssOMACDBDCBand[EVENT_GET_CNM_AMX_BSS_FULL_NUM]; + + /* Reserved fields */ + uint8_t au4Reserved[68]; /*Total 164 byte*/ +}; + +struct CMD_SET_FORCE_RTS { + uint8_t ucForceRtsEn; + uint8_t ucRtsPktNum; + uint8_t aucReserved[2]; +}; + +#endif /* _WSYS_CMD_HANDLER_FW_H */ + + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/aaa_fsm.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/aaa_fsm.c new file mode 100644 index 0000000000000000000000000000000000000000..549d94524473a8ddc85e05357183a24a0c7c4af2 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/aaa_fsm.c @@ -0,0 +1,1712 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/aaa_fsm.c#3 $ + */ + +/*! \file "aaa_fsm.c" + * \brief This file defines the FSM for AAA MODULE. + * + * This file defines the FSM for AAA MODULE. + */ + +/****************************************************************************** + * C O M P I L E R F L A G S + ****************************************************************************** + */ + +/****************************************************************************** + * E X T E R N A L R E F E R E N C E S + ****************************************************************************** + */ +#include "precomp.h" + +/****************************************************************************** + * C O N S T A N T S + ****************************************************************************** + */ + +/****************************************************************************** + * D A T A T Y P E S + ****************************************************************************** + */ + +/****************************************************************************** + * P U B L I C D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * P R I V A T E D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * M A C R O S + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N D E C L A R A T I O N S + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N S + ****************************************************************************** + */ +#if 0 +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will send Event to AIS/BOW/P2P + * + * @param[in] rJoinStatus To indicate JOIN success or failure. + * @param[in] prStaRec Pointer to the STA_RECORD_T + * @param[in] prSwRfb Pointer to the SW_RFB_T + + * @return none + */ +/*----------------------------------------------------------------------------*/ +uint32_t aaaFsmSendEventJoinComplete(uint32_t rJoinStatus, + struct STA_RECORD *prStaRec, struct SW_RFB *prSwRfb) +{ + P_MSG_SAA_JOIN_COMP_T prJoinCompMsg; + + ASSERT(prStaRec); + + prJoinCompMsg = cnmMemAlloc(RAM_TYPE_TCM, sizeof(MSG_SAA_JOIN_COMP_T)); + if (!prJoinCompMsg) + return WLAN_STATUS_RESOURCES; + + if (IS_STA_IN_AIS(prStaRec)) + prJoinCompMsg->rMsgHdr.eMsgId = MID_SAA_AIS_JOIN_COMPLETE; + else if (IS_STA_IN_P2P(prStaRec)) + prJoinCompMsg->rMsgHdr.eMsgId = MID_SAA_P2P_JOIN_COMPLETE; + else if (IS_STA_IN_BOW(prStaRec)) + prJoinCompMsg->rMsgHdr.eMsgId = MID_SAA_BOW_JOIN_COMPLETE; + else + ASSERT(0); + + prJoinCompMsg->rJoinStatus = rJoinStatus; + prJoinCompMsg->prStaRec = prStaRec; + prJoinCompMsg->prSwRfb = prSwRfb; + + mboxSendMsg(MBOX_ID_0, + (struct MSG_HDR *) prJoinCompMsg, + MSG_SEND_METHOD_BUF); + + return WLAN_STATUS_SUCCESS; + +} /* end of saaFsmSendEventJoinComplete() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will handle the Start Event to AAA FSM. + * + * @param[in] prMsgHdr Message of Join Request for a particular STA. + * + * @return none + */ +/*----------------------------------------------------------------------------*/ +void aaaFsmRunEventStart(IN struct MSG_HDR *prMsgHdr) +{ + P_MSG_SAA_JOIN_REQ_T prJoinReqMsg; + struct STA_RECORD *prStaRec; + struct BSS_INFO *prAisBssInfo; + + ASSERT(prMsgHdr); + + prJoinReqMsg = (P_MSG_SAA_JOIN_REQ_T) prMsgHdr; + prStaRec = prJoinReqMsg->prStaRec; + + ASSERT(prStaRec); + + DBGLOG(SAA, LOUD, "EVENT-START: Trigger SAA FSM\n"); + + cnmMemFree(prMsgHdr); + + /* 4 <1> Validation of SAA Start Event */ + if (!IS_AP_STA(prStaRec->eStaType)) { + + DBGLOG(SAA, ERROR, + "EVENT-START: STA Type - %d was not supported.\n", + prStaRec->eStaType); + + /* Ignore the return value because don't care the prSwRfb */ + saaFsmSendEventJoinComplete(WLAN_STATUS_FAILURE, + prStaRec, NULL); + + return; + } + /* 4 <2> The previous JOIN process is not completed ? */ + if (prStaRec->eAuthAssocState != AA_STATE_IDLE) { + DBGLOG(SAA, ERROR, "EVENT-START: Reentry of SAA Module.\n"); + prStaRec->eAuthAssocState = AA_STATE_IDLE; + } + /* 4 <3> Reset Status Code and Time */ + /* Update Station Record - Status/Reason Code */ + prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL; + + /* Update the record join time. */ + GET_CURRENT_SYSTIME(&prStaRec->rLastJoinTime); + + prStaRec->ucTxAuthAssocRetryCount = 0; + + if (prStaRec->prChallengeText) { + cnmMemFree(prStaRec->prChallengeText); + prStaRec->prChallengeText = (struct IE_CHALLENGE_TEXT *) NULL; + } + + cnmTimerStopTimer(&prStaRec->rTxReqDoneOrRxRespTimer); + + prStaRec->ucStaState = STA_STATE_1; + + /* Trigger SAA MODULE */ + saaFsmSteps(prStaRec, SAA_STATE_SEND_AUTH1, (struct SW_RFB *) NULL); +} /* end of saaFsmRunEventStart() */ +#endif + +#if CFG_SUPPORT_AAA + +void aaaFsmRunEventTxReqTimeOut(IN struct ADAPTER *prAdapter, + IN unsigned long plParamPtr) +{ + struct STA_RECORD *prStaRec = (struct STA_RECORD *) plParamPtr; + struct BSS_INFO *prBssInfo; + + if (!prStaRec) + return; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex); + + DBGLOG(AAA, LOUD, + "EVENT-TIMER: TX REQ TIMEOUT, Current Time = %d\n", + kalGetTimeTick()); + + /* Trigger statistics log if Auth/Assoc Tx timeout */ + wlanTriggerStatsLog(prAdapter, prAdapter->rWifiVar.u4StatsLogDuration); + + switch (prStaRec->eAuthAssocState) { + case AAA_STATE_SEND_AUTH2: + DBGLOG(AAA, ERROR, + "LOST EVENT ,Auth Tx done disappear for (%d)Ms\n", + TU_TO_MSEC(TX_AUTHENTICATION_RESPONSE_TIMEOUT_TU)); + + prStaRec->eAuthAssocState = AA_STATE_IDLE; + + /* NOTE(Kevin): Change to STATE_1 */ + cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); + +#if CFG_ENABLE_WIFI_DIRECT + if (prBssInfo->eNetworkType == NETWORK_TYPE_P2P) + p2pRoleFsmRunEventAAATxFail(prAdapter, + prStaRec, prBssInfo); +#endif /* CFG_ENABLE_WIFI_DIRECT */ + break; +#if 0 + /*state 2 to state 3 only check Assoc_req valid, no need for time out + *the fail case already handle at aaaFsmRunEventRxAssoc + */ + case AAA_STATE_SEND_ASSOC2: + DBGLOG(AAA, ERROR, + "LOST EVENT ,Assoc Tx done disappear for (%d)Ms\n", + TU_TO_MSEC(TX_AUTHENTICATION_RESPONSE_TIMEOUT_TU)); + + + prStaRec->eAuthAssocState = AAA_STATE_SEND_AUTH2; + + /* NOTE(Kevin): Change to STATE_2 */ + cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); + +#if CFG_ENABLE_WIFI_DIRECT + if (prBssInfo->eNetworkType == NETWORK_TYPE_P2P) + p2pRoleFsmRunEventAAATxFail(prAdapter, + prStaRec, prBssInfo); +#endif /* CFG_ENABLE_WIFI_DIRECT */ + break; +#endif + + default: + return; + } + + +} /* end of saaFsmRunEventTxReqTimeOut() */ + + + + + +/*---------------------------------------------------------------------------*/ +/*! + * @brief This function will process the Rx Auth Request Frame and then + * trigger AAA FSM. + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] prSwRfb Pointer to the SW_RFB_T structure. + * + * @return (none) + */ +/*---------------------------------------------------------------------------*/ +void aaaFsmRunEventRxAuth(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb) +{ + struct BSS_INFO *prBssInfo = (struct BSS_INFO *) NULL; + struct STA_RECORD *prStaRec = (struct STA_RECORD *) NULL; + uint16_t u2StatusCode; + u_int8_t fgReplyAuth = FALSE; + struct WLAN_AUTH_FRAME *prAuthFrame = (struct WLAN_AUTH_FRAME *) NULL; + + ASSERT(prAdapter); + + do { + prAuthFrame = (struct WLAN_AUTH_FRAME *) prSwRfb->pvHeader; + + DBGLOG(AAA, INFO, + "SA: " MACSTR ", bssid: " MACSTR ", %d %d sta: %d\n", + MAC2STR(prAuthFrame->aucSrcAddr), + MAC2STR(prAuthFrame->aucBSSID), + prAuthFrame->u2AuthTransSeqNo, + prAuthFrame->u2AuthAlgNum, + prSwRfb->ucStaRecIdx); + +#if CFG_ENABLE_WIFI_DIRECT + prBssInfo = p2pFuncBSSIDFindBssInfo(prAdapter, + prAuthFrame->aucBSSID); + + /* 4 <1> Check P2P network conditions */ + + /* if (prBssInfo && prAdapter->fgIsP2PRegistered) */ + /* modify coding sytle to reduce indent */ + + if (!prAdapter->fgIsP2PRegistered) + goto bow_proc; + + if (prBssInfo && prBssInfo->fgIsNetActive) { + + /* 4 <1.1> Validate Auth Frame + * by Auth Algorithm/Transation Seq + */ + if (WLAN_STATUS_SUCCESS == + authProcessRxAuthFrame(prAdapter, + prSwRfb, + prBssInfo, + &u2StatusCode)) { + + if (u2StatusCode == STATUS_CODE_SUCCESSFUL) { + DBGLOG(AAA, TRACE, + "process RxAuth status success\n"); + /* 4 <1.2> Validate Auth Frame + * for Network Specific Conditions + */ + fgReplyAuth = p2pFuncValidateAuth( + prAdapter, + prBssInfo, + prSwRfb, + &prStaRec, + &u2StatusCode); + +#if CFG_SUPPORT_802_11W + /* AP PMF, if PMF connection, + * ignore Rx auth + */ + /* Certification 4.3.3.4 */ + if (rsnCheckBipKeyInstalled(prAdapter, + prStaRec)) { + DBGLOG(AAA, INFO, + "Drop RxAuth\n"); + return; + } +#endif + } else { + fgReplyAuth = TRUE; + } + break; + } + } +#endif /* CFG_ENABLE_WIFI_DIRECT */ + +bow_proc: + + /* 4 <2> Check BOW network conditions */ +#if CFG_ENABLE_BT_OVER_WIFI + { + struct BOW_FSM_INFO *prBowFsmInfo = + (struct BOW_FSM_INFO *) NULL; + + prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prBowFsmInfo->ucBssIndex); + + if ((prBssInfo->fgIsNetActive) + && (prBssInfo->eCurrentOPMode == OP_MODE_BOW)) { + + /* 4 <2.1> Validate Auth Frame + * by Auth Algorithm/Transation Seq + */ + /* Check if for this BSSID */ + if (WLAN_STATUS_SUCCESS == + authProcessRxAuth1Frame(prAdapter, + prSwRfb, + prBssInfo->aucBSSID, + AUTH_ALGORITHM_NUM_OPEN_SYSTEM, + AUTH_TRANSACTION_SEQ_1, + &u2StatusCode)) { + + if (u2StatusCode + == STATUS_CODE_SUCCESSFUL) { + + /* 4 <2.2> Validate Auth Frame + * for Network Specific + * Conditions + */ + fgReplyAuth = + bowValidateAuth(prAdapter, + prSwRfb, + &prStaRec, + &u2StatusCode); + + } else { + + fgReplyAuth = TRUE; + } + /* TODO(Kevin): Allocate a STA_RECORD_T + * for new client + */ + break; + } + } + } +#endif /* CFG_ENABLE_BT_OVER_WIFI */ + + return; + } while (FALSE); + + if (prStaRec) { + /* update RCPI */ + ASSERT(prSwRfb->prRxStatusGroup3); + prStaRec->ucRCPI = nicRxGetRcpiValueFromRxv( + prAdapter, + RCPI_MODE_MAX, + prSwRfb); + } + /* 4 <3> Update STA_RECORD_T and + * reply Auth_2(Response to Auth_1) Frame + */ + if (fgReplyAuth) { + + if (prStaRec) { + + if (u2StatusCode == STATUS_CODE_SUCCESSFUL) { + if (prStaRec->eAuthAssocState + != AA_STATE_IDLE) { + + DBGLOG(AAA, WARN, + "Previous AuthAssocState (%d) != IDLE.\n", + prStaRec->eAuthAssocState); + } + + prStaRec->eAuthAssocState = + AAA_STATE_SEND_AUTH2; + } else { + prStaRec->eAuthAssocState = AA_STATE_IDLE; + + /* NOTE(Kevin): Change to STATE_1 */ + cnmStaRecChangeState(prAdapter, + prStaRec, STA_STATE_1); + } + + /* Update the record join time. */ + GET_CURRENT_SYSTIME(&prStaRec->rUpdateTime); + + /* Update Station Record - Status/Reason Code */ + prStaRec->u2StatusCode = u2StatusCode; + + prStaRec->ucAuthAlgNum = prAuthFrame->u2AuthAlgNum; + } else { + /* NOTE(Kevin): We should have STA_RECORD_T + * if the status code was successful + */ + ASSERT(!(u2StatusCode == STATUS_CODE_SUCCESSFUL)); + } + + if (prBssInfo->u4RsnSelectedAKMSuite == + RSN_AKM_SUITE_SAE) { + kalP2PIndicateRxMgmtFrame( + prAdapter->prGlueInfo, + prSwRfb, + FALSE, + (uint8_t)prBssInfo->u4PrivateData); + DBGLOG(AAA, INFO, "Forward RxAuth\n"); + return; + } + + /* NOTE: Ignore the return status for AAA */ + /* 4 <4> Reply Auth */ + authSendAuthFrame(prAdapter, + prStaRec, + prBssInfo->ucBssIndex, + prSwRfb, + AUTH_TRANSACTION_SEQ_2, + u2StatusCode); + + + /*sta_rec might be removed + * when client list full, skip timer setting + */ + /* + * check if prStaRec valid as authSendAuthFrame may free + * StaRec when TX resource is not enough + */ + if (prStaRec && prStaRec->fgIsInUse) { + cnmTimerStopTimer(prAdapter, + &prStaRec->rTxReqDoneOrRxRespTimer); + /*ToDo:Init Timer to check get + * Auth Txdone avoid sta_rec not clear + */ + cnmTimerInitTimer(prAdapter, + &prStaRec->rTxReqDoneOrRxRespTimer, + (PFN_MGMT_TIMEOUT_FUNC) + aaaFsmRunEventTxReqTimeOut, + (unsigned long) prStaRec); + + cnmTimerStartTimer(prAdapter, + &prStaRec->rTxReqDoneOrRxRespTimer, + TU_TO_MSEC( + TX_AUTHENTICATION_RESPONSE_TIMEOUT_TU)); + } + + + + } else if (prStaRec) + cnmStaRecFree(prAdapter, prStaRec); +} /* end of aaaFsmRunEventRxAuth() */ + +/*---------------------------------------------------------------------------*/ +/*! + * @brief This function will process + * the Rx (Re)Association Request Frame and then + * trigger AAA FSM. + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] prSwRfb Pointer to the SW_RFB_T structure. + * + * @retval WLAN_STATUS_SUCCESS Always return success + */ +/*---------------------------------------------------------------------------*/ +uint32_t aaaFsmRunEventRxAssoc(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb) +{ + struct BSS_INFO *prBssInfo; + struct STA_RECORD *prStaRec = (struct STA_RECORD *) NULL; + uint16_t u2StatusCode = STATUS_CODE_RESERVED; + u_int8_t fgReplyAssocResp = FALSE; + u_int8_t fgSendSAQ = FALSE; + struct WLAN_ASSOC_REQ_FRAME *prAssocReqFrame = + (struct WLAN_ASSOC_REQ_FRAME *) NULL; + + ASSERT(prAdapter); + ASSERT(prSwRfb); + + do { + prAssocReqFrame = + (struct WLAN_ASSOC_REQ_FRAME *) prSwRfb->pvHeader; + + /* 4 <1> Check if we have the STA_RECORD_T + * for incoming Assoc Req + */ + prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); + + /* No Wtbl handling */ + if (!prStaRec) { + secHandleNoWtbl(prAdapter, prSwRfb); + prStaRec = prSwRfb->prStaRec; + } + + /* We should have the corresponding Sta Record. */ + if ((!prStaRec) || (!prStaRec->fgIsInUse)) { + /* Not to reply association response + * with failure code due to lack of STA_REC + */ + DBGLOG(AAA, TRACE, + "get sta fail, wlan idx: %d, sta index: %d\n", + prSwRfb->ucWlanIdx, + prSwRfb->ucStaRecIdx); + break; + } + + DBGLOG(AAA, INFO, + "SA: " MACSTR ", bssid: " MACSTR ", sta idx: %d\n", + MAC2STR(prAssocReqFrame->aucSrcAddr), + MAC2STR(prAssocReqFrame->aucBSSID), + prSwRfb->ucStaRecIdx); + + if (!IS_CLIENT_STA(prStaRec)) { + DBGLOG(AAA, ERROR, + "error sta type, skip process rx assoc\n"); + cnmDumpStaRec(prAdapter, prSwRfb->ucStaRecIdx); + break; + } + + DBGLOG(AAA, TRACE, + "RxAssoc enter ucStaState:%d, eAuthassocState:%d\n", + prStaRec->ucStaState, prStaRec->eAuthAssocState); + + if (prStaRec->ucStaState == STA_STATE_3) { + /* Do Reassocation */ + } else if ((prStaRec->ucStaState == STA_STATE_2) && + (prStaRec->eAuthAssocState == AAA_STATE_SEND_AUTH2)) { + /* Normal case */ + } else { + DBGLOG(AAA, WARN, + "Previous AuthAssocState (%d) != SEND_AUTH2.\n", + prStaRec->eAuthAssocState); + + /* Maybe Auth Response TX fail, + * but actually it success. + */ + cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); + } + + /* update RCPI */ + ASSERT(prSwRfb->prRxStatusGroup3); + prStaRec->ucRCPI = + nicRxGetRcpiValueFromRxv( + prAdapter, RCPI_MODE_MAX, prSwRfb); + + /* 4 <2> Check P2P network conditions */ +#if CFG_ENABLE_WIFI_DIRECT + if ((prAdapter->fgIsP2PRegistered) + && (IS_STA_IN_P2P(prStaRec))) { + + prBssInfo = + GET_BSS_INFO_BY_INDEX(prAdapter, + prStaRec->ucBssIndex); + + if (prBssInfo->fgIsNetActive) { + + /* 4 <2.1> Validate Assoc Req Frame and + * get Status Code + */ + /* Check if for this BSSID */ + if (WLAN_STATUS_SUCCESS == + assocProcessRxAssocReqFrame(prAdapter, + prSwRfb, &u2StatusCode)) { + + if (u2StatusCode + == STATUS_CODE_SUCCESSFUL) { + /* 4 <2.2> + * Validate Assoc Req Frame + * for Network Specific + * Conditions + */ + fgReplyAssocResp = + p2pFuncValidateAssocReq( + prAdapter, + prSwRfb, + (uint16_t *) + &u2StatusCode); + } else { + fgReplyAssocResp = TRUE; + } + + break; + } + } + } +#endif /* CFG_ENABLE_WIFI_DIRECT */ + + /* 4 <3> Check BOW network conditions */ +#if CFG_ENABLE_BT_OVER_WIFI + if (IS_STA_BOW_TYPE(prStaRec)) { + + prBssInfo = + GET_BSS_INFO_BY_INDEX(prAdapter, + prStaRec->ucBssIndex); + + if ((prBssInfo->fgIsNetActive) + && (prBssInfo->eCurrentOPMode == OP_MODE_BOW)) { + + /* 4 <3.1> Validate Auth Frame + * by Auth Algorithm/Transation Seq + */ + /* Check if for this BSSID */ + if (WLAN_STATUS_SUCCESS == + assocProcessRxAssocReqFrame(prAdapter, + prSwRfb, &u2StatusCode)) { + + if (u2StatusCode + == STATUS_CODE_SUCCESSFUL) { + + /* 4 <3.2> + * Validate Auth Frame for + * Network Specific Conditions + */ + fgReplyAssocResp = + bowValidateAssocReq( + prAdapter, + prSwRfb, + &u2StatusCode); + } else { + + fgReplyAssocResp = TRUE; + } + + /* TODO(Kevin): + * Allocate a STA_RECORD_T + * for new client + */ + break; + } + } + } +#endif /* CFG_ENABLE_BT_OVER_WIFI */ + + return WLAN_STATUS_SUCCESS; /* To release the SW_RFB_T */ + } while (FALSE); + + /* 4 <4> Update STA_RECORD_T and reply Assoc Resp Frame */ + if (fgReplyAssocResp) { + uint16_t u2IELength; + uint8_t *pucIE; + + cnmTimerStopTimer(prAdapter, + &prStaRec->rTxReqDoneOrRxRespTimer); + + if ((((struct WLAN_ASSOC_REQ_FRAME *) + (prSwRfb->pvHeader))->u2FrameCtrl & MASK_FRAME_TYPE) == + MAC_FRAME_REASSOC_REQ) { + + u2IELength = prSwRfb->u2PacketLen - + (uint16_t) + OFFSET_OF(struct WLAN_REASSOC_REQ_FRAME, + aucInfoElem[0]); + + pucIE = ((struct WLAN_REASSOC_REQ_FRAME *) + (prSwRfb->pvHeader))->aucInfoElem; + } else { + u2IELength = prSwRfb->u2PacketLen - + (uint16_t) + OFFSET_OF(struct WLAN_ASSOC_REQ_FRAME, + aucInfoElem[0]); + + pucIE = ((struct WLAN_ASSOC_REQ_FRAME *) + (prSwRfb->pvHeader))->aucInfoElem; + } + + rlmProcessAssocReq(prAdapter, prSwRfb, pucIE, u2IELength); + + /* 4 <4.1> Assign Association ID */ + if (u2StatusCode == STATUS_CODE_SUCCESSFUL) { + +#if CFG_ENABLE_WIFI_DIRECT + if ((prAdapter->fgIsP2PRegistered) + && (IS_STA_IN_P2P(prStaRec))) { + prBssInfo = + GET_BSS_INFO_BY_INDEX(prAdapter, + prStaRec->ucBssIndex); + if (p2pRoleFsmRunEventAAAComplete(prAdapter, + prStaRec, prBssInfo) + == WLAN_STATUS_SUCCESS) { + prStaRec->u2AssocId = + bssAssignAssocID(prStaRec); + /* prStaRec->eAuthAssocState + * = AA_STATE_IDLE; + */ + /* NOTE(Kevin): for TX done */ + prStaRec->eAuthAssocState = + AAA_STATE_SEND_ASSOC2; + /* NOTE(Kevin): + * Method A: + * Change to STATE_3 + * before handle TX Done + */ + /* cnmStaRecChangeState(prAdapter, + * prStaRec, STA_STATE_3); + */ + } else { + /* Client List FULL. */ + u2StatusCode = STATUS_CODE_REQ_DECLINED; + + /* Invalid Association ID */ + prStaRec->u2AssocId = 0; + + /* If(Re)association fail, + * remove sta record and + * use class error to handle sta + */ + prStaRec->eAuthAssocState = + AA_STATE_IDLE; + + /* NOTE(Kevin): + * Better to change state here, + * not at TX Done + */ + cnmStaRecChangeState(prAdapter, + prStaRec, STA_STATE_2); + } + } +#endif + +#if CFG_ENABLE_BT_OVER_WIFI + if ((IS_STA_BOW_TYPE(prStaRec))) { + /* if (bowRunEventAAAComplete(prAdapter, + * prStaRec) == WLAN_STATUS_SUCCESS) { + */ + prStaRec->u2AssocId = + bssAssignAssocID(prStaRec); + + /* NOTE(Kevin): for TX done */ + prStaRec->eAuthAssocState = + AAA_STATE_SEND_ASSOC2; + + /* NOTE(Kevin): + * Method A: Change to STATE_3 + * before handle TX Done + */ + /* cnmStaRecChangeState(prAdapter, + * prStaRec, STA_STATE_3); + */ + } +#endif + } else { + +#if CFG_SUPPORT_802_11W + /* AP PMF */ + /* don't change state, + * just send assoc resp + * (NO need TX done, TIE + code30) + * and then SAQ + */ + if (u2StatusCode + == STATUS_CODE_ASSOC_REJECTED_TEMPORARILY) { + DBGLOG(AAA, INFO, "AP send SAQ\n"); + fgSendSAQ = TRUE; + } else +#endif + { + /* Invalid Association ID */ + prStaRec->u2AssocId = 0; + + /* If (Re)association fail, remove sta record + * and use class error to handle sta + */ + prStaRec->eAuthAssocState = AA_STATE_IDLE; + /* Remove from client list if it was previously + * associated + */ + if ((prStaRec->ucStaState > STA_STATE_1) && + prAdapter->fgIsP2PRegistered && + (IS_STA_IN_P2P(prStaRec))) { + struct BSS_INFO *prBssInfo = NULL; + + prBssInfo = GET_BSS_INFO_BY_INDEX( + prAdapter, + prStaRec->ucBssIndex); + if (prBssInfo) { + DBGLOG(AAA, INFO, + "Remove client\n"); + bssRemoveClient( + prAdapter, + prBssInfo, + prStaRec); + } + } + + /* NOTE(Kevin): + * Better to change state here, not at TX Done + */ + cnmStaRecChangeState(prAdapter, + prStaRec, STA_STATE_2); + } + } + + /* Update the record join time. */ + GET_CURRENT_SYSTIME(&prStaRec->rUpdateTime); + + /* Update Station Record - Status/Reason Code */ + prStaRec->u2StatusCode = u2StatusCode; + + /* NOTE: Ignore the return status for AAA */ + /* 4 <4.2> Reply Assoc Resp */ + assocSendReAssocRespFrame(prAdapter, prStaRec); + +#if CFG_SUPPORT_802_11W + /* AP PMF */ + if (fgSendSAQ) { + /* if PMF connection, and return code 30, send SAQ */ + rsnApStartSaQuery(prAdapter, prStaRec); + } +#endif + + } + + return WLAN_STATUS_SUCCESS; + +} /* end of aaaFsmRunEventRxAssoc() */ + +/*---------------------------------------------------------------------------*/ +/*! + * @brief This function will handle TxDone(Auth2/AssocReq) Event of AAA FSM. + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] prMsduInfo Pointer to the MSDU_INFO_T. + * @param[in] rTxDoneStatus Return TX status of the Auth1/Auth3/AssocReq frame. + * + * @retval WLAN_STATUS_SUCCESS + */ +/*---------------------------------------------------------------------------*/ +uint32_t +aaaFsmRunEventTxDone(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN enum ENUM_TX_RESULT_CODE rTxDoneStatus) +{ + struct STA_RECORD *prStaRec; + struct BSS_INFO *prBssInfo; + + ASSERT(prAdapter); + ASSERT(prMsduInfo); + + + DBGLOG(AAA, INFO, + "EVENT-TX DONE [status: %d][seq: %d]: Current Time = %d\n", + rTxDoneStatus, + prMsduInfo->ucTxSeqNum, + kalGetTimeTick()); + + prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); + + /* For the case of replying ERROR STATUS CODE */ + if ((!prStaRec) || (!prStaRec->fgIsInUse)) + return WLAN_STATUS_SUCCESS; + + ASSERT(prStaRec->ucBssIndex <= prAdapter->ucHwBssIdNum); + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex); + + DBGLOG(AAA, TRACE, "TxDone ucStaState:%d, eAuthAssocState:%d\n", + prStaRec->ucStaState, prStaRec->eAuthAssocState); + + /* Trigger statistics log if Auth/Assoc Tx failed */ + if (rTxDoneStatus != TX_RESULT_SUCCESS) + wlanTriggerStatsLog(prAdapter, + prAdapter->rWifiVar.u4StatsLogDuration); + + switch (prStaRec->eAuthAssocState) { + case AAA_STATE_SEND_AUTH2: + /* Strictly check the outgoing frame is matched + * with current AA STATE + */ + if (authCheckTxAuthFrame(prAdapter, + prMsduInfo, AUTH_TRANSACTION_SEQ_2) + != WLAN_STATUS_SUCCESS) + break; + + cnmTimerStopTimer(prAdapter, + &prStaRec->rTxReqDoneOrRxRespTimer); + + if (prStaRec->u2StatusCode == STATUS_CODE_SUCCESSFUL) { + if (rTxDoneStatus == TX_RESULT_SUCCESS) { + + /* NOTE(Kevin): + * Change to STATE_2 at TX Done + */ + cnmStaRecChangeState(prAdapter, + prStaRec, STA_STATE_2); + /* Error handle if can not + * complete the ASSOC flow + */ + cnmTimerStartTimer(prAdapter, + &prStaRec->rTxReqDoneOrRxRespTimer, + TU_TO_MSEC(TX_ASSOCIATE_TIMEOUT_TU)); + } else { + + prStaRec->eAuthAssocState = + AA_STATE_IDLE; + + /* NOTE(Kevin): Change to STATE_1 */ + cnmStaRecChangeState(prAdapter, + prStaRec, STA_STATE_1); + +#if CFG_ENABLE_WIFI_DIRECT + if (prBssInfo->eNetworkType + == NETWORK_TYPE_P2P) + p2pRoleFsmRunEventAAATxFail( + prAdapter, + prStaRec, prBssInfo); +#endif /* CFG_ENABLE_WIFI_DIRECT */ +#if CFG_ENABLE_BT_OVER_WIFI + if (IS_STA_BOW_TYPE(prStaRec)) + bowRunEventAAATxFail(prAdapter, + prStaRec); + +#endif /* CFG_ENABLE_BT_OVER_WIFI */ + } + + } + /* NOTE(Kevin): Ignore the TX Done Event of + * Auth Frame with Error Status Code + */ + + break; + + case AAA_STATE_SEND_ASSOC2: + { + /* Strictly check the outgoing frame is matched + * with current SAA STATE + */ + if (assocCheckTxReAssocRespFrame(prAdapter, + prMsduInfo) != WLAN_STATUS_SUCCESS) + break; + + if (prStaRec->u2StatusCode == STATUS_CODE_SUCCESSFUL) { + if (rTxDoneStatus == TX_RESULT_SUCCESS) { + + prStaRec->eAuthAssocState = + AA_STATE_IDLE; + + /* NOTE(Kevin): + * Change to STATE_3 at TX Done + */ +#if CFG_ENABLE_WIFI_DIRECT + if (prBssInfo->eNetworkType + == NETWORK_TYPE_P2P) + p2pRoleFsmRunEventAAASuccess( + prAdapter, + prStaRec, + prBssInfo); +#endif /* CFG_ENABLE_WIFI_DIRECT */ + +#if CFG_ENABLE_BT_OVER_WIFI + + if (IS_STA_BOW_TYPE(prStaRec)) + bowRunEventAAAComplete( + prAdapter, + prStaRec); + +#endif /* CFG_ENABLE_BT_OVER_WIFI */ + + } else { + + prStaRec->eAuthAssocState = + AAA_STATE_SEND_AUTH2; + + /* NOTE(Kevin): Change to STATE_2 */ + cnmStaRecChangeState(prAdapter, + prStaRec, STA_STATE_2); + +#if CFG_ENABLE_WIFI_DIRECT + if (prBssInfo->eNetworkType + == NETWORK_TYPE_P2P) + p2pRoleFsmRunEventAAATxFail( + prAdapter, + prStaRec, + prBssInfo); +#endif /* CFG_ENABLE_WIFI_DIRECT */ + +#if CFG_ENABLE_BT_OVER_WIFI + if (IS_STA_BOW_TYPE(prStaRec)) + bowRunEventAAATxFail(prAdapter, + prStaRec); + +#endif /* CFG_ENABLE_BT_OVER_WIFI */ + + } + } + /* NOTE(Kevin): Ignore the TX Done Event of + * Auth Frame with Error Status Code + */ + } + break; + + case AA_STATE_IDLE: + /* 2013-08-27 frog: Do nothing. + * Somtimes we may send Assoc Resp twice. + * (Rx Assoc Req before the first Assoc TX Done) + * The AssocState is changed to IDLE after first TX done. + * Free station record when IDLE is seriously wrong. + */ + /* 2017-01-12 Do nothing only when STA is in state 3 */ + /* Free the StaRec if found any unexpected status */ + if (prStaRec->ucStaState != STA_STATE_3) + cnmStaRecFree(prAdapter, prStaRec); + break; + + default: + break; /* Ignore other cases */ + } + + DBGLOG(AAA, TRACE, "TxDone end ucStaState:%d, eAuthAssocState:%d\n", + prStaRec->ucStaState, prStaRec->eAuthAssocState); + + return WLAN_STATUS_SUCCESS; + +} /* end of aaaFsmRunEventTxDone() */ +#endif /* CFG_SUPPORT_AAA */ + +#if 0 +/* TODO(Kevin): for abort event, just reset the STA_RECORD_T. */ +/*---------------------------------------------------------------------------*/ +/*! + * \brief This function will send ABORT Event to JOIN FSM. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * + * \return none + */ +/*---------------------------------------------------------------------------*/ +void saaFsmRunEventAbort(IN struct MSG_HDR *prMsgHdr) +{ + P_JOIN_INFO_T prJoinInfo; + struct STA_RECORD *prStaRec; + + DEBUGFUNC("joinFsmRunEventAbort"); + + ASSERT(prAdapter); + prJoinInfo = &prAdapter->rJoinInfo; + + DBGLOG(JOIN, EVENT, "JOIN EVENT: ABORT\n"); + + /* NOTE(Kevin): when reach here, + * the ARB_STATE should be in ARB_STATE_JOIN. + */ + ASSERT(prJoinInfo->prBssDesc); + + /* 4 <1> Update Flags and Elements of JOIN Module. */ + /* Reset Send Auth/(Re)Assoc Frame Count */ + prJoinInfo->ucTxAuthAssocRetryCount = 0; + + /* Cancel all JOIN relative Timer */ + ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rTxRequestTimer); + + ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rRxResponseTimer); + + ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rJoinTimer); + + /* 4 <2> Update the associated + * STA_RECORD_T during JOIN. + */ + /* Get a Station Record if possible, TA == BSSID for AP */ + prStaRec = staRecGetStaRecordByAddr(prAdapter, + prJoinInfo->prBssDesc->aucBSSID); + if (prStaRec) + prStaRec->ucStaState = STA_STATE_1; + /* Update Station Record - Class 1 Flag */ +#if DBG + else + ASSERT(0); + /* Shouldn't happened, because we already + * add this STA_RECORD_T at JOIN_STATE_INIT + */ + +#endif /* DBG */ + + /* 4 <3> Pull back to IDLE. */ + joinFsmSteps(prAdapter, JOIN_STATE_IDLE); + + /* 4 <4> If we are in Roaming, recover the settings of previous BSS. */ + /* NOTE: JOIN FAIL - + * Restore original setting from current struct BSS_INFO. + */ + if (prAdapter->eConnectionState == MEDIA_STATE_CONNECTED) + joinAdoptParametersFromCurrentBss(prAdapter); +} /* end of joinFsmRunEventAbort() */ +#endif + +/* TODO(Kevin): following code will be modified and move to AIS FSM */ +#if 0 +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function will send Join Timeout Event to JOIN FSM. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * + * \retval WLAN_STATUS_FAILURE Fail because of Join Timeout + */ +/*----------------------------------------------------------------------------*/ +uint32_t joinFsmRunEventJoinTimeOut(IN struct ADAPTER *prAdapter) +{ + P_JOIN_INFO_T prJoinInfo; + struct STA_RECORD *prStaRec; + + DEBUGFUNC("joinFsmRunEventJoinTimeOut"); + + ASSERT(prAdapter); + prJoinInfo = &prAdapter->rJoinInfo; + + DBGLOG(JOIN, EVENT, "JOIN EVENT: JOIN TIMEOUT\n"); + + /* Get a Station Record if possible, TA == BSSID for AP */ + prStaRec = staRecGetStaRecordByAddr(prAdapter, + prJoinInfo->prBssDesc->aucBSSID); + + /* We have renew this Sta Record when in JOIN_STATE_INIT */ + ASSERT(prStaRec); + + /* Record the Status Code of Authentication Request */ + prStaRec->u2StatusCode = STATUS_CODE_JOIN_TIMEOUT; + + /* Increase Failure Count */ + prStaRec->ucJoinFailureCount++; + + /* Reset Send Auth/(Re)Assoc Frame Count */ + prJoinInfo->ucTxAuthAssocRetryCount = 0; + + /* Cancel other JOIN relative Timer */ + ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rTxRequestTimer); + + ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rRxResponseTimer); + + /* Restore original setting from current BSS_INFO_T */ + if (prAdapter->eConnectionState == MEDIA_STATE_CONNECTED) + joinAdoptParametersFromCurrentBss(prAdapter); + + /* Pull back to IDLE */ + joinFsmSteps(prAdapter, JOIN_STATE_IDLE); + + return WLAN_STATUS_FAILURE; + +} /* end of joinFsmRunEventJoinTimeOut() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function will adopt the parameters from Peer BSS. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void joinAdoptParametersFromPeerBss(IN struct ADAPTER *prAdapter) +{ + P_JOIN_INFO_T prJoinInfo; + struct BSS_DESC *prBssDesc; + + DEBUGFUNC("joinAdoptParametersFromPeerBss"); + + ASSERT(prAdapter); + prJoinInfo = &prAdapter->rJoinInfo; + prBssDesc = prJoinInfo->prBssDesc; + + /* 4 <1> Adopt Peer BSS' PHY TYPE */ + prAdapter->eCurrentPhyType = prBssDesc->ePhyType; + + DBGLOG(JOIN, INFO, "Target BSS[%s]'s PhyType = %s\n", + prBssDesc->aucSSID, + (prBssDesc->ePhyType == PHY_TYPE_ERP_INDEX) ? "ERP" : "HR_DSSS"); + + /* 4 <2> Adopt Peer BSS' Frequency(Band/Channel) */ + DBGLOG(JOIN, INFO, + "Target BSS's Channel = %d, Band = %d\n", + prBssDesc->ucChannelNum, prBssDesc->eBand); + + nicSwitchChannel(prAdapter, + prBssDesc->eBand, prBssDesc->ucChannelNum, 10); + + prJoinInfo->fgIsParameterAdopted = TRUE; +} /* end of joinAdoptParametersFromPeerBss() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function will adopt the parameters from current associated BSS. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void joinAdoptParametersFromCurrentBss(IN struct ADAPTER *prAdapter) +{ + /* P_JOIN_INFO_T prJoinInfo = &prAdapter->rJoinInfo; */ + struct BSS_INFO *prBssInfo; + + ASSERT(prAdapter); + prBssInfo = &prAdapter->rBssInfo; + + /* 4 <1> Adopt current BSS' PHY TYPE */ + prAdapter->eCurrentPhyType = prBssInfo->ePhyType; + + /* 4 <2> Adopt current BSS' Frequency(Band/Channel) */ + DBGLOG(JOIN, INFO, + "Current BSS's Channel = %d, Band = %d\n", + prBssInfo->ucChnl, prBssInfo->eBand); + + nicSwitchChannel(prAdapter, prBssInfo->eBand, prBssInfo->ucChnl, 10); +} /* end of joinAdoptParametersFromCurrentBss() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function will update all the SW variables and + * HW MCR registers after + * the association with target BSS. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void joinComplete(IN struct ADAPTER *prAdapter) +{ + P_JOIN_INFO_T prJoinInfo; + struct BSS_DESC *prBssDesc; + P_PEER_BSS_INFO_T prPeerBssInfo; + struct BSS_INFO *prBssInfo; + struct CONNECTION_SETTINGS *prConnSettings; + struct STA_RECORD *prStaRec; + struct TX_CTRL *prTxCtrl; +#if CFG_SUPPORT_802_11D + struct IE_COUNTRY *prIECountry; +#endif + + DEBUGFUNC("joinComplete"); + + ASSERT(prAdapter); + prJoinInfo = &prAdapter->rJoinInfo; + prBssDesc = prJoinInfo->prBssDesc; + prPeerBssInfo = &prAdapter->rPeerBssInfo; + prBssInfo = &prAdapter->rBssInfo; + prConnSettings = &prAdapter->rConnSettings; + prTxCtrl = &prAdapter->rTxCtrl; + +/* 4 <1> Update Connecting & Connected Flag of BSS_DESC_T. */ + /* Remove previous AP's Connection Flags if have */ + scanRemoveConnectionFlagOfBssDescByBssid(prAdapter, + prBssInfo->aucBSSID); + + prBssDesc->fgIsConnected = TRUE; /* Mask as Connected */ + + if (prBssDesc->fgIsHiddenSSID) { + /* NOTE(Kevin): This is for the case of Passive Scan + * and the target BSS didn't + * broadcast SSID on its Beacon Frame. + */ + COPY_SSID(prBssDesc->aucSSID, + prBssDesc->ucSSIDLen, + prAdapter->rConnSettings.aucSSID, + prAdapter->rConnSettings.ucSSIDLen); + + if (prBssDesc->ucSSIDLen) + prBssDesc->fgIsHiddenSSID = FALSE; + +#if DBG + else + ASSERT(0); + +#endif /* DBG */ + + DBGLOG(JOIN, INFO, + "Hidden SSID! - Update SSID : %s\n", + prBssDesc->aucSSID); + } + +/* 4 <2> Update BSS_INFO_T from BSS_DESC_T */ + /* 4 <2.A> PHY Type */ + prBssInfo->ePhyType = prBssDesc->ePhyType; + + /* 4 <2.B> BSS Type */ + prBssInfo->eBSSType = BSS_TYPE_INFRASTRUCTURE; + + /* 4 <2.C> BSSID */ + COPY_MAC_ADDR(prBssInfo->aucBSSID, prBssDesc->aucBSSID); + + DBGLOG(JOIN, INFO, + "JOIN to BSSID: [" MACSTR "]\n", + MAC2STR(prBssDesc->aucBSSID)); + + /* 4 <2.D> SSID */ + COPY_SSID(prBssInfo->aucSSID, + prBssInfo->ucSSIDLen, + prBssDesc->aucSSID, + prBssDesc->ucSSIDLen); + + /* 4 <2.E> Channel / Band information. */ + prBssInfo->eBand = prBssDesc->eBand; + prBssInfo->ucChnl = prBssDesc->ucChannelNum; + + /* 4 <2.F> RSN/WPA information. */ + secFsmRunEventStart(prAdapter); + prBssInfo->u4RsnSelectedPairwiseCipher = + prBssDesc->u4RsnSelectedPairwiseCipher; + prBssInfo->u4RsnSelectedGroupCipher = + prBssDesc->u4RsnSelectedGroupCipher; + prBssInfo->u4RsnSelectedAKMSuite = + prBssDesc->u4RsnSelectedAKMSuite; + + if (secRsnKeyHandshakeEnabled()) + prBssInfo->fgIsWPAorWPA2Enabled = TRUE; + else + prBssInfo->fgIsWPAorWPA2Enabled = FALSE; + + /* 4 <2.G> Beacon interval. */ + prBssInfo->u2BeaconInterval = prBssDesc->u2BeaconInterval; + + /* 4 <2.H> DTIM period. */ + prBssInfo->ucDtimPeriod = prBssDesc->ucDTIMPeriod; + + /* 4 <2.I> ERP Information */ + /* Our BSS's PHY_TYPE is ERP now. */ + if ((prBssInfo->ePhyType == PHY_TYPE_ERP_INDEX) && + (prBssDesc->fgIsERPPresent)) { + + prBssInfo->fgIsERPPresent = TRUE; + /* Save the ERP for later check */ + prBssInfo->ucERP = prBssDesc->ucERP; + } else { + /* Some AP, may send ProbeResp without ERP IE. + * Thus prBssDesc->fgIsERPPresent is FALSE. + */ + prBssInfo->fgIsERPPresent = FALSE; + prBssInfo->ucERP = 0; + } + +#if CFG_SUPPORT_802_11D + /* 4 <2.J> Country inforamtion of the associated AP */ + if (prConnSettings->fgMultiDomainCapabilityEnabled) { + struct DOMAIN_INFO_ENTRY rDomainInfo; + + if (domainGetDomainInfoByScanResult(prAdapter, &rDomainInfo)) { + if (prBssDesc->prIECountry) { + prIECountry = prBssDesc->prIECountry; + + domainParseCountryInfoElem(prIECountry, + &prBssInfo->rDomainInfo); + + /* use the domain get from the BSS info */ + prBssInfo->fgIsCountryInfoPresent = TRUE; + nicSetupOpChnlList(prAdapter, + prBssInfo->rDomainInfo.u2CountryCode, + FALSE); + } else { + /* use the domain get from the scan result */ + prBssInfo->fgIsCountryInfoPresent = TRUE; + nicSetupOpChnlList(prAdapter, + rDomainInfo.u2CountryCode, FALSE); + } + } + } +#endif + + /* 4 <2.K> Signal Power of the associated AP */ + prBssInfo->rRcpi = prBssDesc->rRcpi; + prBssInfo->rRssi = RCPI_TO_dBm(prBssInfo->rRcpi); + GET_CURRENT_SYSTIME(&prBssInfo->rRssiLastUpdateTime); + + /* 4 <2.L> Capability Field of the associated AP */ + prBssInfo->u2CapInfo = prBssDesc->u2CapInfo; + + DBGLOG(JOIN, INFO, + "prBssInfo-> fgIsERPPresent = %d, ucERP = %02x, rRcpi = %d, rRssi = %ld\n", + prBssInfo->fgIsERPPresent, + prBssInfo->ucERP, + prBssInfo->rRcpi, + prBssInfo->rRssi); + +/* 4 <3> Update BSS_INFO_T from PEER_BSS_INFO_T & NIC RATE FUNC */ + /* 4 <3.A> Association ID */ + prBssInfo->u2AssocId = prPeerBssInfo->u2AssocId; + + /* 4 <3.B> WMM Information */ + if (prAdapter->fgIsEnableWMM + && (prPeerBssInfo->rWmmInfo.ucWmmFlag & WMM_FLAG_SUPPORT_WMM)) { + + prBssInfo->fgIsWmmAssoc = TRUE; + prTxCtrl->rTxQForVoipAccess = TXQ_AC3; + + qosWmmInfoInit(&prBssInfo->rWmmInfo, + (prBssInfo->ePhyType == PHY_TYPE_HR_DSSS_INDEX) + ? TRUE : FALSE); + + if (prPeerBssInfo->rWmmInfo.ucWmmFlag + & WMM_FLAG_AC_PARAM_PRESENT) { + kalMemCopy(&prBssInfo->rWmmInfo, + &prPeerBssInfo->rWmmInfo, sizeof(WMM_INFO_T)); + } else { + kalMemCopy(&prBssInfo->rWmmInfo, + &prPeerBssInfo->rWmmInfo, + sizeof(WMM_INFO_T) - + sizeof(prPeerBssInfo->rWmmInfo.arWmmAcParams)); + } + } else { + prBssInfo->fgIsWmmAssoc = FALSE; + prTxCtrl->rTxQForVoipAccess = TXQ_AC1; + + kalMemZero(&prBssInfo->rWmmInfo, sizeof(WMM_INFO_T)); + } + + /* 4 <3.C> Operational Rate Set & BSS Basic Rate Set */ + prBssInfo->u2OperationalRateSet = prPeerBssInfo->u2OperationalRateSet; + prBssInfo->u2BSSBasicRateSet = prPeerBssInfo->u2BSSBasicRateSet; + + /* 4 <3.D> Short Preamble */ + if (prBssInfo->fgIsERPPresent) { + +/* NOTE(Kevin 2007/12/24): Truth Table. + *Short Preamble Bit in + * Final Driver Setting(Short) + *TRUE FALSE FALSE FALSE(shouldn't have such case, + * use the AssocResp) + *TRUE FALSE TRUE FALSE + *FALSE FALSE FALSE FALSE(shouldn't have such case, + * use the AssocResp) + *FALSE FALSE TRUE FALSE + *TRUE TRUE FALSE TRUE(follow ERP) + *TRUE TRUE TRUE FALSE(follow ERP) + *FALSE TRUE FALSE FALSE(shouldn't have such case, + * and we should set to FALSE) + *FALSE TRUE TRUE FALSE(we should set to FALSE) + */ + if ((prPeerBssInfo->fgIsShortPreambleAllowed) && + ((prConnSettings->ePreambleType == PREAMBLE_TYPE_SHORT) || + /* Short Preamble Option Enable is TRUE */ + ((prConnSettings->ePreambleType == PREAMBLE_TYPE_AUTO) + && (prBssDesc->u2CapInfo & CAP_INFO_SHORT_PREAMBLE)))) { + + prBssInfo->fgIsShortPreambleAllowed = TRUE; + + if (prBssInfo->ucERP & ERP_INFO_BARKER_PREAMBLE_MODE) + prBssInfo->fgUseShortPreamble = FALSE; + else + prBssInfo->fgUseShortPreamble = TRUE; + + } else { + prBssInfo->fgIsShortPreambleAllowed = FALSE; + prBssInfo->fgUseShortPreamble = FALSE; + } + } else { + /* NOTE(Kevin 2007/12/24): Truth Table. + * Short Preamble Bit in + * Final Driver Setting(Short) + * TRUE FALSE FALSE + * FALSE FALSE FALSE + * TRUE TRUE TRUE + * FALSE TRUE(status success) TRUE + * --> Honor the result of prPeerBssInfo. + */ + + prBssInfo->fgIsShortPreambleAllowed = + prBssInfo->fgUseShortPreamble = + prPeerBssInfo->fgIsShortPreambleAllowed; + } + + DBGLOG(JOIN, INFO, + "prBssInfo->fgIsShortPreambleAllowed = %d, prBssInfo->fgUseShortPreamble = %d\n", + prBssInfo->fgIsShortPreambleAllowed, + prBssInfo->fgUseShortPreamble); + + /* 4 <3.E> Short Slot Time */ + /* AP support Short Slot Time */ + prBssInfo->fgUseShortSlotTime = + prPeerBssInfo->fgUseShortSlotTime; + + DBGLOG(JOIN, INFO, + "prBssInfo->fgUseShortSlotTime = %d\n", + prBssInfo->fgUseShortSlotTime); + + nicSetSlotTime(prAdapter, + prBssInfo->ePhyType, + ((prConnSettings->fgIsShortSlotTimeOptionEnable && + prBssInfo->fgUseShortSlotTime) ? TRUE : FALSE)); + + /* 4 <3.F> Update Tx Rate for Control Frame */ + bssUpdateTxRateForControlFrame(prAdapter); + + /* 4 <3.G> Save the available Auth Types + * during Roaming (Design for Fast BSS Transition). + */ + /* if (prAdapter->fgIsEnableRoaming) */ + /* NOTE(Kevin): Always prepare info for roaming */ + { + + if (prJoinInfo->ucCurrAuthAlgNum + == AUTH_ALGORITHM_NUM_OPEN_SYSTEM) + prJoinInfo->ucRoamingAuthTypes |= AUTH_TYPE_OPEN_SYSTEM; + else if (prJoinInfo->ucCurrAuthAlgNum + == AUTH_ALGORITHM_NUM_SHARED_KEY) + prJoinInfo->ucRoamingAuthTypes |= AUTH_TYPE_SHARED_KEY; + + prBssInfo->ucRoamingAuthTypes = prJoinInfo->ucRoamingAuthTypes; + + /* Set the stable time of the associated BSS. + * We won't do roaming decision + * during the stable time. + */ + SET_EXPIRATION_TIME(prBssInfo->rRoamingStableExpirationTime, + SEC_TO_SYSTIME(ROAMING_STABLE_TIMEOUT_SEC)); + } + + /* 4 <3.H> Update Parameter for TX Fragmentation Threshold */ +#if CFG_TX_FRAGMENT + txFragInfoUpdate(prAdapter); +#endif /* CFG_TX_FRAGMENT */ + +/* 4 <4> Update STA_RECORD_T */ + /* Get a Station Record if possible */ + prStaRec = staRecGetStaRecordByAddr(prAdapter, prBssDesc->aucBSSID); + + if (prStaRec) { + uint16_t u2OperationalRateSet, u2DesiredRateSet; + + /* 4 <4.A> Desired Rate Set */ + u2OperationalRateSet = + (rPhyAttributes + [prBssInfo->ePhyType].u2SupportedRateSet & + prBssInfo->u2OperationalRateSet); + + u2DesiredRateSet = + (u2OperationalRateSet + & prConnSettings->u2DesiredRateSet); + if (u2DesiredRateSet) { + prStaRec->u2DesiredRateSet = u2DesiredRateSet; + } else { + /* For Error Handling - The Desired Rate Set is + * not covered in Operational Rate Set. + */ + prStaRec->u2DesiredRateSet = u2OperationalRateSet; + } + + /* Try to set the best initial rate for this entry */ + if (!rateGetBestInitialRateIndex(prStaRec->u2DesiredRateSet, + prStaRec->rRcpi, &prStaRec->ucCurrRate1Index)) { + + if (!rateGetLowestRateIndexFromRateSet( + prStaRec->u2DesiredRateSet, + &prStaRec->ucCurrRate1Index)) + ASSERT(0); + } + + DBGLOG(JOIN, INFO, + "prStaRec->ucCurrRate1Index = %d\n", + prStaRec->ucCurrRate1Index); + + /* 4 <4.B> Preamble Mode */ + prStaRec->fgIsShortPreambleOptionEnable = + prBssInfo->fgUseShortPreamble; + + /* 4 <4.C> QoS Flag */ + prStaRec->fgIsQoS = prBssInfo->fgIsWmmAssoc; + } +#if DBG + else + ASSERT(0); + +#endif /* DBG */ + +/* 4 <5> Update NIC */ + /* 4 <5.A> Update BSSID & Operation Mode */ + nicSetupBSS(prAdapter, prBssInfo); + + /* 4 <5.B> Update WLAN Table. */ + if (nicSetHwBySta(prAdapter, prStaRec) == FALSE) + ASSERT(FALSE); + + /* 4 <5.C> Update Desired Rate Set for BT. */ +#if CFG_TX_FRAGMENT + if (prConnSettings->fgIsEnableTxAutoFragmentForBT) + txRateSetInitForBT(prAdapter, prStaRec); + +#endif /* CFG_TX_FRAGMENT */ + + /* 4 <5.D> TX AC Parameter and TX/RX Queue Control */ + if (prBssInfo->fgIsWmmAssoc) { + +#if CFG_TX_AGGREGATE_HW_FIFO + nicTxAggregateTXQ(prAdapter, FALSE); +#endif /* CFG_TX_AGGREGATE_HW_FIFO */ + + qosUpdateWMMParametersAndAssignAllowedACI(prAdapter, + &prBssInfo->rWmmInfo); + } else { + +#if CFG_TX_AGGREGATE_HW_FIFO + nicTxAggregateTXQ(prAdapter, TRUE); +#endif /* CFG_TX_AGGREGATE_HW_FIFO */ + + nicTxNonQoSAssignDefaultAdmittedTXQ(prAdapter); + + nicTxNonQoSUpdateTXQParameters(prAdapter, + prBssInfo->ePhyType); + } + +#if CFG_TX_STOP_WRITE_TX_FIFO_UNTIL_JOIN + { + prTxCtrl->fgBlockTxDuringJoin = FALSE; + +#if !CFG_TX_AGGREGATE_HW_FIFO /* TX FIFO AGGREGATE already do flush once */ + nicTxFlushStopQueues(prAdapter, + (uint8_t) TXQ_DATA_MASK, (uint8_t) NULL); +#endif /* CFG_TX_AGGREGATE_HW_FIFO */ + + nicTxRetransmitOfSendWaitQue(prAdapter); + + if (prTxCtrl->fgIsPacketInOsSendQueue) + nicTxRetransmitOfOsSendQue(prAdapter); + +#if CFG_SDIO_TX_ENHANCE + halTxLeftClusteredMpdu(prAdapter); +#endif /* CFG_SDIO_TX_ENHANCE */ + + } +#endif /* CFG_TX_STOP_WRITE_TX_FIFO_UNTIL_JOIN */ + +/* 4 <6> Setup CONNECTION flag. */ + prAdapter->eConnectionState = MEDIA_STATE_CONNECTED; + prAdapter->eConnectionStateIndicated = MEDIA_STATE_CONNECTED; + + if (prJoinInfo->fgIsReAssoc) + prAdapter->fgBypassPortCtrlForRoaming = TRUE; + else + prAdapter->fgBypassPortCtrlForRoaming = FALSE; + + kalIndicateStatusAndComplete(prAdapter->prGlueInfo, + WLAN_STATUS_MEDIA_CONNECT, (void *) NULL, 0); +} /* end of joinComplete() */ +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/ais_fsm.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/ais_fsm.c new file mode 100644 index 0000000000000000000000000000000000000000..bfc948ebe8c27622a82ef766b36f5d7c2d1424c1 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/ais_fsm.c @@ -0,0 +1,7032 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/ais_fsm.c#4 + */ + +/*! \file "aa_fsm.c" + * \brief This file defines the FSM for SAA and AAA MODULE. + * + * This file defines the FSM for SAA and AAA MODULE. + */ + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" +#if CFG_MTK_MCIF_WIFI_SUPPORT +#include "mddp.h" +#endif +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#define AIS_ROAMING_CONNECTION_TRIAL_LIMIT 2 +#define AIS_JOIN_TIMEOUT 7 + +#if (CFG_SUPPORT_HE_ER == 1) +#define AP_TX_POWER 20 +#endif + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ +static uint8_t *apucDebugAisState[AIS_STATE_NUM] = { + (uint8_t *) DISP_STRING("IDLE"), + (uint8_t *) DISP_STRING("SEARCH"), + (uint8_t *) DISP_STRING("SCAN"), + (uint8_t *) DISP_STRING("ONLINE_SCAN"), + (uint8_t *) DISP_STRING("LOOKING_FOR"), + (uint8_t *) DISP_STRING("WAIT_FOR_NEXT_SCAN"), + (uint8_t *) DISP_STRING("REQ_CHANNEL_JOIN"), + (uint8_t *) DISP_STRING("JOIN"), + (uint8_t *) DISP_STRING("JOIN_FAILURE"), + (uint8_t *) DISP_STRING("IBSS_ALONE"), + (uint8_t *) DISP_STRING("IBSS_MERGE"), + (uint8_t *) DISP_STRING("NORMAL_TR"), + (uint8_t *) DISP_STRING("DISCONNECTING"), + (uint8_t *) DISP_STRING("REQ_REMAIN_ON_CHANNEL"), + (uint8_t *) DISP_STRING("REMAIN_ON_CHANNEL"), + (uint8_t *) DISP_STRING("OFF_CHNL_TX") +}; + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +static void aisFsmRunEventScanDoneTimeOut(IN struct ADAPTER *prAdapter, + unsigned long ulParam); +static void aisRemoveDeauthBlacklist(struct ADAPTER *prAdapter); + +static void aisFunClearAllTxReq(IN struct ADAPTER *prAdapter, + IN struct AIS_MGMT_TX_REQ_INFO *prAisMgmtTxInfo); +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +static void aisResetBssTranstionMgtParam(struct AIS_SPECIFIC_BSS_INFO + *prSpecificBssInfo) +{ +#if CFG_SUPPORT_802_11V_BSS_TRANSITION_MGT + struct BSS_TRANSITION_MGT_PARAM_T *prBtmParam = + &prSpecificBssInfo->rBTMParam; + + if (prBtmParam->u2OurNeighborBssLen > 0) { + kalMemFree(prBtmParam->pucOurNeighborBss, VIR_MEM_TYPE, + prBtmParam->u2OurNeighborBssLen); + prBtmParam->u2OurNeighborBssLen = 0; + } + kalMemZero(prBtmParam, sizeof(*prBtmParam)); +#endif +} + +#if (CFG_SUPPORT_HE_ER == 1) +uint8_t aisCheckPowerMatchERCondition(IN struct ADAPTER *prAdapter, + IN struct BSS_DESC *prBssDesc) +{ + int8_t txpwr = 0; + int8_t icBeaconRSSI; + + icBeaconRSSI = RCPI_TO_dBm(prBssDesc->ucRCPI); + wlanGetMiniTxPower(prAdapter, prBssDesc->eBand, PHY_MODE_OFDM, &txpwr); + + DBGLOG(AIS, INFO, "ER: STA Tx power:%x, AP Tx power:%x, Bcon RSSI:%x\n", + txpwr, AP_TX_POWER, icBeaconRSSI); + + return ((txpwr - (AP_TX_POWER - icBeaconRSSI)) < -95); +} + +bool aisCheckUsingERRate(IN struct ADAPTER *prAdapter, + IN struct BSS_DESC *prBssDesc) +{ + bool fgIsStaUseERRate = false; + + if ((prBssDesc->fgIsERSUDisable == 0) && + (prBssDesc->ucDCMMaxConRx > 0) && + (prBssDesc->eBand == BAND_5G) && + (aisCheckPowerMatchERCondition(prAdapter, prBssDesc))) { + fgIsStaUseERRate = TRUE; + } + + DBGLOG(AIS, INFO, "ER: ER disable:%x, max rx:%x, band:%x, use ER:%x\n", + prBssDesc->fgIsERSUDisable, prBssDesc->ucDCMMaxConRx, + prBssDesc->eBand, fgIsStaUseERRate); + + return fgIsStaUseERRate; +} +#endif +/*----------------------------------------------------------------------------*/ +/*! + * @brief the function is used to initialize the value of the connection + * settings for AIS network + * + * @param (none) + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void aisInitializeConnectionSettings(IN struct ADAPTER *prAdapter, + IN struct REG_INFO *prRegInfo, IN uint8_t ucBssIndex) +{ + struct CONNECTION_SETTINGS *prConnSettings; + uint8_t aucAnyBSSID[] = BC_BSSID; + uint8_t aucZeroMacAddr[] = NULL_MAC_ADDR; + int i = 0; + + prConnSettings = aisGetConnSettings(prAdapter, ucBssIndex); + + /* Setup default values for operation */ + COPY_MAC_ADDR(prConnSettings->aucMacAddress, aucZeroMacAddr); + + prConnSettings->ucDelayTimeOfDisconnectEvent = + AIS_DELAY_TIME_OF_DISCONNECT_SEC; + + COPY_MAC_ADDR(prConnSettings->aucBSSID, aucAnyBSSID); + prConnSettings->fgIsConnByBssidIssued = FALSE; + + prConnSettings->ucSSIDLen = 0; + + prConnSettings->eOPMode = NET_TYPE_INFRA; + + prConnSettings->eConnectionPolicy = CONNECT_BY_SSID_BEST_RSSI; + + if (prRegInfo) { + prConnSettings->ucAdHocChannelNum = 0; + prConnSettings->eAdHocBand = + prRegInfo->u4StartFreq < 5000000 ? BAND_2G4 : BAND_5G; + prConnSettings->eAdHocMode = + (enum ENUM_PARAM_AD_HOC_MODE)(prRegInfo->u4AdhocMode); + } + + prConnSettings->eAuthMode = AUTH_MODE_OPEN; + + prConnSettings->eEncStatus = ENUM_ENCRYPTION_DISABLED; + + prConnSettings->fgIsScanReqIssued = FALSE; + + /* MIB attributes */ + prConnSettings->u2BeaconPeriod = DOT11_BEACON_PERIOD_DEFAULT; + + prConnSettings->u2RTSThreshold = DOT11_RTS_THRESHOLD_DEFAULT; + + prConnSettings->u2DesiredNonHTRateSet = RATE_SET_ALL_ABG; + + /* prConnSettings->u4FreqInKHz; *//* Center frequency */ + + /* Set U-APSD AC */ + prConnSettings->bmfgApsdEnAc = PM_UAPSD_NONE; + + secInit(prAdapter, ucBssIndex); + + /* Features */ + prConnSettings->fgIsEnableRoaming = FALSE; + +#if CFG_SUPPORT_DETECT_SECURITY_MODE_CHANGE + prConnSettings->fgSecModeChangeStartTimer = FALSE; +#endif + +#if CFG_SUPPORT_ROAMING +#if 0 + if (prRegInfo) + prConnSettings->fgIsEnableRoaming = + ((prRegInfo->fgDisRoaming > 0) ? (FALSE) : (TRUE)); +#else + if (prAdapter->rWifiVar.fgDisRoaming) + prConnSettings->fgIsEnableRoaming = FALSE; + else + prConnSettings->fgIsEnableRoaming = TRUE; +#endif +#endif /* CFG_SUPPORT_ROAMING */ + + prConnSettings->fgIsAdHocQoSEnable = FALSE; + +#if CFG_SUPPORT_802_11AC + prAdapter->rWifiVar.eDesiredPhyConfig + = PHY_CONFIG_802_11ABGNAC; +#else + prAdapter->rWifiVar.eDesiredPhyConfig + = PHY_CONFIG_802_11ABGN; +#endif + +#if (CFG_SUPPORT_802_11AX == 1) + if (fgEfuseCtrlAxOn == 1) { + prAdapter->rWifiVar.eDesiredPhyConfig + = PHY_CONFIG_802_11ABGNACAX; + } +#endif + + /* Set default bandwidth modes */ + prAdapter->rWifiVar.uc2G4BandwidthMode = + (prAdapter->rWifiVar.ucSta2gBandwidth == MAX_BW_40MHZ) + ? CONFIG_BW_20_40M + : CONFIG_BW_20M; + prAdapter->rWifiVar.uc5GBandwidthMode = CONFIG_BW_20_40M; + + prConnSettings->rRsnInfo.ucElemId = 0x30; + prConnSettings->rRsnInfo.u2Version = 0x0001; + prConnSettings->rRsnInfo.u4GroupKeyCipherSuite = 0; + prConnSettings->rRsnInfo.u4PairwiseKeyCipherSuiteCount = 0; + for (i = 0; i < MAX_NUM_SUPPORTED_CIPHER_SUITES; i++) + prConnSettings->rRsnInfo.au4PairwiseKeyCipherSuite[i] = 0; + prConnSettings->rRsnInfo.u4AuthKeyMgtSuiteCount = 0; + for (i = 0; i < MAX_NUM_SUPPORTED_AKM_SUITES; i++) + prConnSettings->rRsnInfo.au4AuthKeyMgtSuite[i] = 0; + prConnSettings->rRsnInfo.u2RsnCap = 0; + prConnSettings->rRsnInfo.fgRsnCapPresent = FALSE; +} /* end of aisFsmInitializeConnectionSettings() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief the function is used to initialize the value in AIS_FSM_INFO_T for + * AIS FSM operation + * + * @param (none) + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void aisFsmInit(IN struct ADAPTER *prAdapter, uint8_t ucBssIndex) +{ + struct AIS_FSM_INFO *prAisFsmInfo; + struct BSS_INFO *prAisBssInfo; + struct AIS_SPECIFIC_BSS_INFO *prAisSpecificBssInfo; + struct CONNECTION_SETTINGS *prConnSettings; + struct AIS_MGMT_TX_REQ_INFO *prMgmtTxReqInfo = + (struct AIS_MGMT_TX_REQ_INFO *) NULL; + uint8_t i; + + DEBUGFUNC("aisFsmInit()"); + DBGLOG(SW1, INFO, "->aisFsmInit(%d)\n", ucBssIndex); + + /* avoid that the prAisBssInfo is realloc */ + if (prAdapter->prAisBssInfo[ucBssIndex] != NULL) { + DBGLOG(SW1, INFO, "-> realloc(%d)\n", ucBssIndex); + return; + } + + prAdapter->prAisBssInfo[ucBssIndex] = prAisBssInfo = + cnmGetBssInfoAndInit(prAdapter, NETWORK_TYPE_AIS, FALSE); + if (!prAisBssInfo) { + DBGLOG(AIS, ERROR, + "aisFsmInit failed because prAisBssInfo is NULL, return.\n"); + return; + } + + /* update MAC address */ + COPY_MAC_ADDR(prAisBssInfo->aucOwnMacAddr, + prAdapter->rMyMacAddr); + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + prAisSpecificBssInfo = + aisGetAisSpecBssInfo(prAdapter, ucBssIndex); + prConnSettings = aisGetConnSettings(prAdapter, ucBssIndex); + + /* 4 <1> Initiate FSM */ + prAisFsmInfo->ePreviousState = AIS_STATE_IDLE; + prAisFsmInfo->eCurrentState = AIS_STATE_IDLE; + + prAisFsmInfo->ucAvailableAuthTypes = 0; + + prAisFsmInfo->prTargetBssDesc = (struct BSS_DESC *)NULL; + + prAisFsmInfo->ucSeqNumOfReqMsg = 0; + prAisFsmInfo->ucSeqNumOfChReq = 0; + prAisFsmInfo->ucSeqNumOfScanReq = 0; + prAisFsmInfo->u2SeqNumOfScanReport = AIS_SCN_REPORT_SEQ_NOT_SET; + prAisFsmInfo->fgIsChannelRequested = FALSE; + prAisFsmInfo->fgIsChannelGranted = FALSE; + prAisFsmInfo->u4PostponeIndStartTime = 0; + /* Support AP Selection */ + prAisFsmInfo->ucJoinFailCntAfterScan = 0; + + prAisFsmInfo->fgIsScanOidAborted = FALSE; + + prAisFsmInfo->fgIsScanning = FALSE; + + /* 4 <1.1> Initiate FSM - Timer INIT */ + cnmTimerInitTimer(prAdapter, + &prAisFsmInfo->rBGScanTimer, + (PFN_MGMT_TIMEOUT_FUNC) aisFsmRunEventBGSleepTimeOut, + (unsigned long)ucBssIndex); + + cnmTimerInitTimer(prAdapter, + &prAisFsmInfo->rIbssAloneTimer, + (PFN_MGMT_TIMEOUT_FUNC) + aisFsmRunEventIbssAloneTimeOut, + (unsigned long)ucBssIndex); + + cnmTimerInitTimer(prAdapter, + &prAisFsmInfo->rScanDoneTimer, + (PFN_MGMT_TIMEOUT_FUNC) aisFsmRunEventScanDoneTimeOut, + (unsigned long)ucBssIndex); + + cnmTimerInitTimer(prAdapter, + &prAisFsmInfo->rJoinTimeoutTimer, + (PFN_MGMT_TIMEOUT_FUNC) aisFsmRunEventJoinTimeout, + (unsigned long)ucBssIndex); + + cnmTimerInitTimer(prAdapter, + &prAisFsmInfo->rChannelTimeoutTimer, + (PFN_MGMT_TIMEOUT_FUNC) aisFsmRunEventChannelTimeout, + (unsigned long)ucBssIndex); + + cnmTimerInitTimer(prAdapter, + &prAisFsmInfo->rDeauthDoneTimer, + (PFN_MGMT_TIMEOUT_FUNC) aisFsmRunEventDeauthTimeout, + (unsigned long)ucBssIndex); + +#if CFG_SUPPORT_DETECT_SECURITY_MODE_CHANGE + cnmTimerInitTimer(prAdapter, + &prAisFsmInfo->rSecModeChangeTimer, + (PFN_MGMT_TIMEOUT_FUNC) + aisFsmRunEventSecModeChangeTimeout, + (unsigned long)ucBssIndex); +#endif + + prMgmtTxReqInfo = &prAisFsmInfo->rMgmtTxInfo; + LINK_INITIALIZE(&prMgmtTxReqInfo->rTxReqLink); + + /* 4 <1.2> Initiate PWR STATE */ + SET_NET_PWR_STATE_IDLE(prAdapter, prAisBssInfo->ucBssIndex); + + /* 4 <2> Initiate BSS_INFO_T - common part */ + BSS_INFO_INIT(prAdapter, prAisBssInfo); + if (ucBssIndex == AIS_DEFAULT_INDEX) + COPY_MAC_ADDR(prAisBssInfo->aucOwnMacAddr, + prAdapter->rWifiVar.aucMacAddress); + else + COPY_MAC_ADDR(prAisBssInfo->aucOwnMacAddr, + prAdapter->rWifiVar.aucMacAddress1); + + /* 4 <3> Initiate BSS_INFO_T - private part */ + /* TODO */ + prAisBssInfo->eBand = BAND_2G4; + prAisBssInfo->ucPrimaryChannel = 1; + prAisBssInfo->prStaRecOfAP = (struct STA_RECORD *) NULL; + prAisBssInfo->ucOpRxNss = prAisBssInfo->ucOpTxNss = + wlanGetSupportNss(prAdapter, prAisBssInfo->ucBssIndex); +#if (CFG_HW_WMM_BY_BSS == 0) + prAisBssInfo->ucWmmQueSet = + (prAdapter->rWifiVar.eDbdcMode == ENUM_DBDC_MODE_DISABLED) ? + DBDC_5G_WMM_INDEX : DBDC_2G_WMM_INDEX; +#endif + /* 4 <4> Allocate MSDU_INFO_T for Beacon */ + prAisBssInfo->prBeacon = cnmMgtPktAlloc(prAdapter, + OFFSET_OF(struct WLAN_BEACON_FRAME, + aucInfoElem[0]) + MAX_IE_LENGTH); + + if (prAisBssInfo->prBeacon) { + prAisBssInfo->prBeacon->eSrc = TX_PACKET_MGMT; + /* NULL STA_REC */ + prAisBssInfo->prBeacon->ucStaRecIndex = 0xFF; + } + + prAisBssInfo->ucBMCWlanIndex = WTBL_RESERVED_ENTRY; + + for (i = 0; i < MAX_KEY_NUM; i++) { + prAisBssInfo->ucBMCWlanIndexS[i] = WTBL_RESERVED_ENTRY; + prAisBssInfo->ucBMCWlanIndexSUsed[i] = FALSE; + prAisBssInfo->wepkeyUsed[i] = FALSE; + } +#if 0 + prAisBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC = PM_UAPSD_ALL; + prAisBssInfo->rPmProfSetupInfo.ucBmpTriggerAC = PM_UAPSD_ALL; + prAisBssInfo->rPmProfSetupInfo.ucUapsdSp = WMM_MAX_SP_LENGTH_2; +#else + if (prAdapter->u4UapsdAcBmp == 0) { + prAdapter->u4UapsdAcBmp = CFG_INIT_UAPSD_AC_BMP; + } + prAisBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC = + (uint8_t) prAdapter->u4UapsdAcBmp; + prAisBssInfo->rPmProfSetupInfo.ucBmpTriggerAC = + (uint8_t) prAdapter->u4UapsdAcBmp; + prAisBssInfo->rPmProfSetupInfo.ucUapsdSp = + (uint8_t) prAdapter->u4MaxSpLen; +#endif + + /* request list initialization */ + LINK_INITIALIZE(&prAisFsmInfo->rPendingReqList); + + /* Support AP Selection */ + LINK_MGMT_INIT(&prAdapter->rWifiVar.rBlackList); + kalMemZero(&prAisSpecificBssInfo->arCurEssChnlInfo[0], + sizeof(prAisSpecificBssInfo->arCurEssChnlInfo)); + LINK_INITIALIZE(&prAisSpecificBssInfo->rCurEssLink); + /* end Support AP Selection */ + LINK_INITIALIZE(&prAisSpecificBssInfo->rPmkidCache); + /* 11K, 11V */ + LINK_MGMT_INIT(&prAisSpecificBssInfo->rNeighborApList); + kalMemZero(&prAisSpecificBssInfo->rBTMParam, + sizeof(prAisSpecificBssInfo->rBTMParam)); + + rrmParamInit(prAdapter, ucBssIndex); +#if CFG_SUPPORT_802_11W + init_completion(&prAisBssInfo->rDeauthComp); + prAisBssInfo->encryptedDeauthIsInProcess = FALSE; +#endif + /* DBGPRINTF("[2] ucBmpDeliveryAC:0x%x, + * ucBmpTriggerAC:0x%x, ucUapsdSp:0x%x", + */ + /* prAisBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC, */ + /* prAisBssInfo->rPmProfSetupInfo.ucBmpTriggerAC, */ + /* prAisBssInfo->rPmProfSetupInfo.ucUapsdSp); */ + + /* Bind NetDev & BssInfo */ + /* wlanBindBssIdxToNetInterface(prAdapter->prGlueInfo, + * NET_DEV_WLAN_IDX, prAisBssInfo->ucBssIndex); + */ +} /* end of aisFsmInit() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief the function is used to uninitialize the value in AIS_FSM_INFO_T for + * AIS FSM operation + * + * @param (none) + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void aisFsmUninit(IN struct ADAPTER *prAdapter, uint8_t ucBssIndex) +{ + struct AIS_FSM_INFO *prAisFsmInfo; + struct BSS_INFO *prAisBssInfo; + struct AIS_SPECIFIC_BSS_INFO *prAisSpecificBssInfo; + struct CONNECTION_SETTINGS *prConnSettings; + u_int8_t fgHalted = kalIsHalted(); + GLUE_SPIN_LOCK_DECLARATION(); + + DEBUGFUNC("aisFsmUninit()"); + DBGLOG(SW1, INFO, "->aisFsmUninit(%d)\n", ucBssIndex); + + /* avoid that the prAisBssInfo is double freed */ + if (aisGetAisBssInfo(prAdapter, ucBssIndex) == NULL) + return; + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + prAisBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + prAisSpecificBssInfo = + aisGetAisSpecBssInfo(prAdapter, ucBssIndex); + prConnSettings = aisGetConnSettings(prAdapter, ucBssIndex); + + /* 4 <1> Stop all timers */ + cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rBGScanTimer); + cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rIbssAloneTimer); + cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rJoinTimeoutTimer); + if (timerPendingTimer(&(prAisFsmInfo->rScanDoneTimer))) { + /* call aisFsmRunEventScanDoneTimeOut() + * to reset scan fsm + */ + if (!fgHalted) { + aisFsmRunEventScanDoneTimeOut(prAdapter, + (unsigned long)ucBssIndex); + if (prAdapter->prGlueInfo->prScanRequest != NULL) { + GLUE_ACQUIRE_SPIN_LOCK(prAdapter->prGlueInfo, + SPIN_LOCK_NET_DEV); + kalCfg80211ScanDone(prAdapter->prGlueInfo + ->prScanRequest, TRUE); + prAdapter->prGlueInfo->prScanRequest = NULL; + prAisFsmInfo->u2SeqNumOfScanReport = + AIS_SCN_REPORT_SEQ_NOT_SET; + GLUE_RELEASE_SPIN_LOCK(prAdapter->prGlueInfo, + SPIN_LOCK_NET_DEV); + } + } + cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer); + } + cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rChannelTimeoutTimer); +#if CFG_SUPPORT_DETECT_SECURITY_MODE_CHANGE + cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rSecModeChangeTimer); +#endif + /* 4 <2> flush pending request */ + aisFsmFlushRequest(prAdapter, ucBssIndex); + aisResetBssTranstionMgtParam(prAisSpecificBssInfo); + + aisFunClearAllTxReq(prAdapter, &(prAisFsmInfo->rMgmtTxInfo)); + + /* 4 <3> Reset driver-domain BSS-INFO */ + if (prAisBssInfo) { + /* Deactivate BSS. */ + UNSET_NET_ACTIVE(prAdapter, + prAisBssInfo->ucBssIndex); + if (!fgHalted) + nicDeactivateNetwork(prAdapter, + prAisBssInfo->ucBssIndex); + + if (prAisBssInfo->prBeacon) { + cnmMgtPktFree(prAdapter, prAisBssInfo->prBeacon); + prAisBssInfo->prBeacon = NULL; + } + + cnmFreeBssInfo(prAdapter, prAisBssInfo); + prAdapter->prAisBssInfo[ucBssIndex] = NULL; + } +#if CFG_SUPPORT_802_11W + rsnStopSaQuery(prAdapter, ucBssIndex); +#endif + /* Support AP Selection */ + LINK_MGMT_UNINIT(&prAdapter->rWifiVar.rBlackList, + struct AIS_BLACKLIST_ITEM, VIR_MEM_TYPE); + /* end Support AP Selection */ + LINK_MGMT_UNINIT(&prAisSpecificBssInfo->rNeighborApList, + struct NEIGHBOR_AP_T, VIR_MEM_TYPE); + + /* make sure pmkid cached is empty after uninit*/ + rsnFlushPmkid(prAdapter, ucBssIndex); + + rrmParamInit(prAdapter, ucBssIndex); +} /* end of aisFsmUninit() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Check if ais is processing beacon timeout + * + * @return true if processing + */ +/*----------------------------------------------------------------------------*/ +bool aisFsmIsInProcessPostpone(IN struct ADAPTER *prAdapter, + uint8_t ucBssIndex) +{ + struct AIS_FSM_INFO *fsm = aisGetAisFsmInfo(prAdapter, ucBssIndex); + struct BSS_INFO *bss = aisGetAisBssInfo(prAdapter, ucBssIndex); + struct CONNECTION_SETTINGS *set = + aisGetConnSettings(prAdapter, ucBssIndex); + + return bss->eConnectionState == MEDIA_STATE_DISCONNECTED && + fsm->u4PostponeIndStartTime > 0 && + !CHECK_FOR_TIMEOUT(kalGetTimeTick(), fsm->u4PostponeIndStartTime, + SEC_TO_MSEC(set->ucDelayTimeOfDisconnectEvent)); +} + +bool aisFsmIsBeaconTimeout(IN struct ADAPTER *prAdapter, + uint8_t ucBssIndex) +{ + struct BSS_INFO *prAisBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + + return aisFsmIsInProcessPostpone(prAdapter, ucBssIndex) && + (prAisBssInfo->ucReasonOfDisconnect == + DISCONNECT_REASON_CODE_RADIO_LOST || + prAisBssInfo->ucReasonOfDisconnect == + DISCONNECT_REASON_CODE_RADIO_LOST_TX_ERR); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Initialization of JOIN STATE + * + * @param[in] prBssDesc The pointer of BSS_DESC_T which is the BSS we will + * try to join with. + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void aisFsmStateInit_JOIN(IN struct ADAPTER *prAdapter, + struct BSS_DESC *prBssDesc, uint8_t ucBssIndex) +{ + struct AIS_FSM_INFO *prAisFsmInfo; + struct BSS_INFO *prAisBssInfo; + struct AIS_SPECIFIC_BSS_INFO *prAisSpecificBssInfo; + struct CONNECTION_SETTINGS *prConnSettings; + struct STA_RECORD *prStaRec; + struct MSG_SAA_FSM_START *prJoinReqMsg; + struct GL_WPA_INFO *prWpaInfo; +#if (CFG_SUPPORT_HE_ER == 1) + struct WIFI_VAR *prWifiVar = &prAdapter->rWifiVar; +#endif + struct AIS_BLACKLIST_ITEM *prBlackList; + + DEBUGFUNC("aisFsmStateInit_JOIN()"); + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + prAisBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + prAisSpecificBssInfo = + aisGetAisSpecBssInfo(prAdapter, ucBssIndex); + prConnSettings = aisGetConnSettings(prAdapter, ucBssIndex); + prWpaInfo = aisGetWpaInfo(prAdapter, + ucBssIndex); + + /* 4 <1> We are going to connect to this BSS. */ + prBssDesc->fgIsConnecting |= BIT(ucBssIndex); + + /* 4 <2> Setup corresponding STA_RECORD_T */ + prStaRec = bssCreateStaRecFromBssDesc(prAdapter, + STA_TYPE_LEGACY_AP, + prAisBssInfo->ucBssIndex, + prBssDesc); + + if (!prStaRec) { + DBGLOG(AIS, ERROR, + "aisFsmStateInit_JOIN failed because prStaRec is NULL, return.\n"); + return; + } + + prAisFsmInfo->prTargetStaRec = prStaRec; + + /* 4 <2.1> sync. to firmware domain */ + if (prStaRec->ucStaState == STA_STATE_1) + cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); + + /* 4 <3> Update ucAvailableAuthTypes which we can choice during SAA */ + if (prAisBssInfo->eConnectionState == MEDIA_STATE_DISCONNECTED + /* Not in case of beacon timeout*/ + && !aisFsmIsBeaconTimeout(prAdapter, ucBssIndex)) { + + prStaRec->fgIsReAssoc = FALSE; + + switch (prConnSettings->eAuthMode) { + case AUTH_MODE_WPA2_FT: + case AUTH_MODE_WPA2_FT_PSK: + case AUTH_MODE_OPEN: /* Note: Omit break here. */ + case AUTH_MODE_WPA: + case AUTH_MODE_WPA_PSK: + case AUTH_MODE_WPA2: + case AUTH_MODE_WPA2_PSK: + case AUTH_MODE_WPA_OSEN: + case AUTH_MODE_WPA3_OWE: + prAisFsmInfo->ucAvailableAuthTypes = + (uint8_t) AUTH_TYPE_OPEN_SYSTEM; + break; + + case AUTH_MODE_SHARED: + prAisFsmInfo->ucAvailableAuthTypes = + (uint8_t) AUTH_TYPE_SHARED_KEY; + break; + + case AUTH_MODE_AUTO_SWITCH: + DBGLOG(AIS, LOUD, + "JOIN INIT: eAuthMode == AUTH_MODE_AUTO_SWITCH\n"); + prAisFsmInfo->ucAvailableAuthTypes = + (uint8_t) (AUTH_TYPE_OPEN_SYSTEM | + AUTH_TYPE_SHARED_KEY); + break; + + case AUTH_MODE_WPA3_SAE: + DBGLOG(AIS, LOUD, + "JOIN INIT: eAuthMode == AUTH_MODE_SAE\n"); + prAisFsmInfo->ucAvailableAuthTypes = + (uint8_t) AUTH_TYPE_SAE; + break; + + default: + DBGLOG(AIS, ERROR, + "JOIN INIT: Auth Algorithm : %d was not supported by JOIN\n", + prConnSettings->eAuthMode); + /* TODO(Kevin): error handling ? */ + return; + } + + /* TODO(tyhsu): Assume that Roaming Auth Type + * is equal to ConnSettings eAuthMode + */ + prAisSpecificBssInfo->ucRoamingAuthTypes = + prAisFsmInfo->ucAvailableAuthTypes; + + prStaRec->ucTxAuthAssocRetryLimit = TX_AUTH_ASSOCI_RETRY_LIMIT; + /* reset BTM Params when do first connection */ + aisResetBssTranstionMgtParam(prAisSpecificBssInfo); + + /* Update Bss info before join */ + prAisBssInfo->eBand = prBssDesc->eBand; + prAisBssInfo->ucPrimaryChannel = prBssDesc->ucChannelNum; + +#if (CFG_SUPPORT_HE_ER == 1) + prStaRec->fgIsExtendedRange = FALSE; + + if (IS_FEATURE_ENABLED(prWifiVar->u4ExtendedRange)) { + /* check using the ER rate or not */ + prStaRec->fgIsExtendedRange = + aisCheckUsingERRate(prAdapter, prBssDesc); + } +#endif + } else { + DBGLOG(AIS, LOUD, "JOIN INIT: AUTH TYPE = %d for Roaming\n", + prAisSpecificBssInfo->ucRoamingAuthTypes); + + /* We do roaming while the medium is connected */ + prStaRec->fgIsReAssoc = TRUE; + + /* TODO(Kevin): We may call a sub function to + * acquire the Roaming Auth Type + */ + switch (prConnSettings->eAuthMode) { + case AUTH_MODE_OPEN: + if (prWpaInfo->u4WpaVersion == + IW_AUTH_WPA_VERSION_DISABLED + && prWpaInfo->u4AuthAlg == + IW_AUTH_ALG_FT) { + prAisFsmInfo->ucAvailableAuthTypes = + (uint8_t) AUTH_TYPE_FAST_BSS_TRANSITION; + DBGLOG(AIS, INFO, "FT: Non-RSN FT roaming\n"); + } else { + prAisFsmInfo->ucAvailableAuthTypes = + prAisSpecificBssInfo-> + ucRoamingAuthTypes; + } + break; + case AUTH_MODE_WPA2_FT: + case AUTH_MODE_WPA2_FT_PSK: + prAisFsmInfo->ucAvailableAuthTypes = + (uint8_t) AUTH_TYPE_FAST_BSS_TRANSITION; + DBGLOG(AIS, TRACE, "FT: RSN FT roaming\n"); + break; + case AUTH_MODE_WPA3_SAE: + prBlackList = + aisQueryBlackList(prAdapter, prBssDesc); + if (rsnSearchPmkidEntry(prAdapter, prBssDesc->aucBSSID, + ucBssIndex) + && + (!prBlackList || prBlackList->u2AuthStatus + != STATUS_INVALID_PMKID)) { + prAisFsmInfo->ucAvailableAuthTypes = + (uint8_t) AUTH_TYPE_OPEN_SYSTEM; + DBGLOG(AIS, INFO, + "SAE: change AUTH to OPEN when roaming with PMK\n"); + } else { + prAisFsmInfo->ucAvailableAuthTypes = + (uint8_t) AUTH_TYPE_SAE; + } + break; + default: + prAisFsmInfo->ucAvailableAuthTypes = + prAisSpecificBssInfo->ucRoamingAuthTypes; + break; + } + + prStaRec->ucTxAuthAssocRetryLimit = + TX_AUTH_ASSOCI_RETRY_LIMIT_FOR_ROAMING; + } + + /* 4 <4> Use an appropriate Authentication Algorithm + * Number among the ucAvailableAuthTypes + */ + if (prAisFsmInfo->ucAvailableAuthTypes & + (uint8_t) AUTH_TYPE_SHARED_KEY) { + + DBGLOG(AIS, LOUD, + "JOIN INIT: Try to do Authentication with AuthType == SHARED_KEY.\n"); + + prAisFsmInfo->ucAvailableAuthTypes &= + ~(uint8_t) AUTH_TYPE_SHARED_KEY; + + prStaRec->ucAuthAlgNum = + (uint8_t) AUTH_ALGORITHM_NUM_SHARED_KEY; + } else if (prAisFsmInfo->ucAvailableAuthTypes & (uint8_t) + AUTH_TYPE_OPEN_SYSTEM) { + + DBGLOG(AIS, LOUD, + "JOIN INIT: Try to do Authentication with AuthType == OPEN_SYSTEM.\n"); + prAisFsmInfo->ucAvailableAuthTypes &= + ~(uint8_t) AUTH_TYPE_OPEN_SYSTEM; + + prStaRec->ucAuthAlgNum = + (uint8_t) AUTH_ALGORITHM_NUM_OPEN_SYSTEM; + } else if (prAisFsmInfo->ucAvailableAuthTypes & (uint8_t) + AUTH_TYPE_FAST_BSS_TRANSITION) { + + DBGLOG(AIS, LOUD, + "JOIN INIT: Try to do Authentication with AuthType == FAST_BSS_TRANSITION.\n"); + + prAisFsmInfo->ucAvailableAuthTypes &= + ~(uint8_t) AUTH_TYPE_FAST_BSS_TRANSITION; + + prStaRec->ucAuthAlgNum = + (uint8_t) AUTH_ALGORITHM_NUM_FAST_BSS_TRANSITION; + } else if (prAisFsmInfo->ucAvailableAuthTypes & (uint8_t) + AUTH_TYPE_SAE) { + DBGLOG(AIS, LOUD, + "JOIN INIT: Try to do Authentication with AuthType == SAE.\n"); + + prStaRec->ucAuthAlgNum = + (uint8_t) AUTH_ALGORITHM_NUM_SAE; + } else { + DBGLOG(AIS, ERROR, + "JOIN INIT: Unsupported auth type %d\n", + prAisFsmInfo->ucAvailableAuthTypes); + return; + } + + /* 4 <5> Overwrite Connection Setting for eConnectionPolicy + * == ANY (Used by Assoc Req) + */ + if (prBssDesc->ucSSIDLen) + COPY_SSID(prConnSettings->aucSSID, prConnSettings->ucSSIDLen, + prBssDesc->aucSSID, prBssDesc->ucSSIDLen); + /* 4 <6> Send a Msg to trigger SAA to start JOIN process. */ + prJoinReqMsg = + (struct MSG_SAA_FSM_START *)cnmMemAlloc(prAdapter, RAM_TYPE_MSG, + sizeof(struct + MSG_SAA_FSM_START)); + if (!prJoinReqMsg) { + DBGLOG(AIS, ERROR, "Can't trigger SAA FSM\n"); + return; + } + + prJoinReqMsg->rMsgHdr.eMsgId = MID_AIS_SAA_FSM_START; + prJoinReqMsg->ucSeqNum = ++prAisFsmInfo->ucSeqNumOfReqMsg; + prJoinReqMsg->prStaRec = prStaRec; + + nicRxClearFrag(prAdapter, prStaRec); + +#if CFG_SUPPORT_802_11K + rlmSetMaxTxPwrLimit(prAdapter, + (prBssDesc->cPowerLimit != RLM_INVALID_POWER_LIMIT) + ? prBssDesc->cPowerLimit : RLM_MAX_TX_PWR, 1); +#endif + mboxSendMsg(prAdapter, MBOX_ID_0, (struct MSG_HDR *)prJoinReqMsg, + MSG_SEND_METHOD_BUF); +} /* end of aisFsmInit_JOIN() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Retry JOIN for AUTH_MODE_AUTO_SWITCH + * + * @param[in] prStaRec Pointer to the STA_RECORD_T + * + * @retval TRUE We will retry JOIN + * @retval FALSE We will not retry JOIN + */ +/*----------------------------------------------------------------------------*/ +u_int8_t aisFsmStateInit_RetryJOIN(IN struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, uint8_t ucBssIndex) +{ + struct AIS_FSM_INFO *prAisFsmInfo; + struct MSG_SAA_FSM_START *prJoinReqMsg; + + DEBUGFUNC("aisFsmStateInit_RetryJOIN()"); + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + + /* Retry other AuthType if possible */ + if (!prAisFsmInfo->ucAvailableAuthTypes) + return FALSE; + + if ((prStaRec->u2StatusCode != + STATUS_CODE_AUTH_ALGORITHM_NOT_SUPPORTED) && + (prStaRec->u2StatusCode != + STATUS_CODE_AUTH_TIMEOUT)) { + prAisFsmInfo->ucAvailableAuthTypes = 0; + return FALSE; + } + + if (prAisFsmInfo->ucAvailableAuthTypes & (uint8_t) + AUTH_TYPE_OPEN_SYSTEM) { + + DBGLOG(AIS, INFO, + "RETRY JOIN INIT: Retry Authentication with AuthType == OPEN_SYSTEM.\n"); + + prAisFsmInfo->ucAvailableAuthTypes &= + ~(uint8_t) AUTH_TYPE_OPEN_SYSTEM; + + prStaRec->ucAuthAlgNum = + (uint8_t) AUTH_ALGORITHM_NUM_OPEN_SYSTEM; + } else { + DBGLOG(AIS, ERROR, + "RETRY JOIN INIT: Retry Authentication with Unexpected AuthType: %d.\n", + prAisFsmInfo->ucAvailableAuthTypes); + return FALSE; + } + + /* No more available Auth Types */ + prAisFsmInfo->ucAvailableAuthTypes = 0; + + /* Trigger SAA to start JOIN process. */ + prJoinReqMsg = + (struct MSG_SAA_FSM_START *)cnmMemAlloc(prAdapter, RAM_TYPE_MSG, + sizeof(struct + MSG_SAA_FSM_START)); + if (!prJoinReqMsg) { + DBGLOG(AIS, ERROR, "Can't trigger SAA FSM\n"); + return FALSE; + } + + prJoinReqMsg->rMsgHdr.eMsgId = MID_AIS_SAA_FSM_START; + prJoinReqMsg->ucSeqNum = ++prAisFsmInfo->ucSeqNumOfReqMsg; + prJoinReqMsg->prStaRec = prStaRec; + + mboxSendMsg(prAdapter, MBOX_ID_0, (struct MSG_HDR *)prJoinReqMsg, + MSG_SEND_METHOD_BUF); + + return TRUE; + +} /* end of aisFsmRetryJOIN() */ + +#if CFG_SUPPORT_ADHOC +/*----------------------------------------------------------------------------*/ +/*! + * @brief State Initialization of AIS_STATE_IBSS_ALONE + * + * @param (none) + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void aisFsmStateInit_IBSS_ALONE(IN struct ADAPTER *prAdapter, + uint8_t ucBssIndex) +{ + struct AIS_FSM_INFO *prAisFsmInfo; + struct CONNECTION_SETTINGS *prConnSettings; + struct BSS_INFO *prAisBssInfo; + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + prConnSettings = aisGetConnSettings(prAdapter, ucBssIndex); + prAisBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + + /* 4 <1> Check if IBSS was created before ? */ + if (prAisBssInfo->fgIsBeaconActivated) { + + /* 4 <2> Start IBSS Alone Timer for periodic SCAN and then SEARCH */ +#if !CFG_SLT_SUPPORT + cnmTimerStartTimer(prAdapter, &prAisFsmInfo->rIbssAloneTimer, + SEC_TO_MSEC(AIS_IBSS_ALONE_TIMEOUT_SEC)); +#endif + } + + aisFsmCreateIBSS(prAdapter, ucBssIndex); +} /* end of aisFsmStateInit_IBSS_ALONE() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief State Initialization of AIS_STATE_IBSS_MERGE + * + * @param[in] prBssDesc The pointer of BSS_DESC_T which is the IBSS we will + * try to merge with. + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void aisFsmStateInit_IBSS_MERGE(IN struct ADAPTER *prAdapter, + struct BSS_DESC *prBssDesc, uint8_t ucBssIndex) +{ + struct AIS_FSM_INFO *prAisFsmInfo; + struct CONNECTION_SETTINGS *prConnSettings; + struct BSS_INFO *prAisBssInfo; + struct STA_RECORD *prStaRec = (struct STA_RECORD *)NULL; + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + prConnSettings = aisGetConnSettings(prAdapter, ucBssIndex); + prAisBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + + /* 4 <1> We will merge with to this BSS immediately. */ + prBssDesc->fgIsConnecting &= ~BIT(ucBssIndex); + prBssDesc->fgIsConnected |= BIT(ucBssIndex); + + /* 4 <2> Setup corresponding STA_RECORD_T */ + prStaRec = bssCreateStaRecFromBssDesc(prAdapter, + STA_TYPE_ADHOC_PEER, + prAisBssInfo->ucBssIndex, + prBssDesc); + + if (!prStaRec) { + DBGLOG(AIS, ERROR, + "aisFsmStateInit_IBSS_MERGE failed because prStaRec is NULL, return.\n"); + return; + } + + prStaRec->fgIsMerging = TRUE; + + prAisFsmInfo->prTargetStaRec = prStaRec; + + /* 4 <2.1> sync. to firmware domain */ + cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); + + /* 4 <3> IBSS-Merge */ + aisFsmMergeIBSS(prAdapter, prStaRec); +} /* end of aisFsmStateInit_IBSS_MERGE() */ + +#endif /* CFG_SUPPORT_ADHOC */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Process of JOIN Abort + * + * @param (none) + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void aisFsmStateAbort_JOIN(IN struct ADAPTER *prAdapter, + uint8_t ucBssIndex) +{ + struct AIS_FSM_INFO *prAisFsmInfo; + struct MSG_SAA_FSM_ABORT *prJoinAbortMsg; + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + + /* 1. Abort JOIN process */ + prJoinAbortMsg = + (struct MSG_SAA_FSM_ABORT *)cnmMemAlloc(prAdapter, RAM_TYPE_MSG, + sizeof(struct + MSG_SAA_FSM_ABORT)); + if (!prJoinAbortMsg) { + DBGLOG(AIS, ERROR, "Can't abort SAA FSM\n"); + return; + } + + prJoinAbortMsg->rMsgHdr.eMsgId = MID_AIS_SAA_FSM_ABORT; + prJoinAbortMsg->ucSeqNum = prAisFsmInfo->ucSeqNumOfReqMsg; + prJoinAbortMsg->prStaRec = prAisFsmInfo->prTargetStaRec; + + prAisFsmInfo->prTargetBssDesc->fgIsConnected &= ~BIT(ucBssIndex); + prAisFsmInfo->prTargetBssDesc->fgIsConnecting &= ~BIT(ucBssIndex); + + mboxSendMsg(prAdapter, MBOX_ID_0, (struct MSG_HDR *)prJoinAbortMsg, + MSG_SEND_METHOD_BUF); + + /* 2. Return channel privilege */ + aisFsmReleaseCh(prAdapter, ucBssIndex); + + /* 3.1 stop join timeout timer */ + cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rJoinTimeoutTimer); +} /* end of aisFsmAbortJOIN() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Process of SCAN Abort + * + * @param (none) + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void aisFsmStateAbort_SCAN(IN struct ADAPTER *prAdapter, + uint8_t ucBssIndex) +{ + struct AIS_FSM_INFO *prAisFsmInfo; + struct MSG_SCN_SCAN_CANCEL *prScanCancelMsg; + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + + DBGLOG(AIS, STATE, "[%d] aisFsmStateAbort_SCAN\n", + ucBssIndex); + + /* Abort JOIN process. */ + prScanCancelMsg = + (struct MSG_SCN_SCAN_CANCEL *)cnmMemAlloc(prAdapter, RAM_TYPE_MSG, + sizeof(struct MSG_SCN_SCAN_CANCEL)); + if (!prScanCancelMsg) { + DBGLOG(AIS, ERROR, "Can't abort SCN FSM\n"); + return; + } + kalMemZero(prScanCancelMsg, sizeof(struct MSG_SCN_SCAN_CANCEL)); + prScanCancelMsg->rMsgHdr.eMsgId = MID_AIS_SCN_SCAN_CANCEL; + prScanCancelMsg->ucSeqNum = prAisFsmInfo->ucSeqNumOfScanReq; + prScanCancelMsg->ucBssIndex = ucBssIndex; + prScanCancelMsg->fgIsChannelExt = FALSE; + if (prAisFsmInfo->fgIsScanOidAborted) { + prScanCancelMsg->fgIsOidRequest = TRUE; + prAisFsmInfo->fgIsScanOidAborted = FALSE; + } + + /* unbuffered message to guarantee scan is cancelled in sequence */ + mboxSendMsg(prAdapter, MBOX_ID_0, (struct MSG_HDR *)prScanCancelMsg, + MSG_SEND_METHOD_UNBUF); +} /* end of aisFsmAbortSCAN() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Process of NORMAL_TR Abort + * + * @param (none) + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void aisFsmStateAbort_NORMAL_TR(IN struct ADAPTER *prAdapter, + uint8_t ucBssIndex) +{ + struct AIS_FSM_INFO *prAisFsmInfo; + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + + /* TODO(Kevin): Do abort other MGMT func */ + + /* 1. Release channel to CNM */ + aisFsmReleaseCh(prAdapter, ucBssIndex); + + /* 2.1 stop join timeout timer */ + cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rJoinTimeoutTimer); +} /* end of aisFsmAbortNORMAL_TR() */ + +#if CFG_SUPPORT_ADHOC +/*----------------------------------------------------------------------------*/ +/*! + * @brief Process of NORMAL_TR Abort + * + * @param (none) + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void aisFsmStateAbort_IBSS(IN struct ADAPTER *prAdapter, + uint8_t ucBssIndex) +{ + struct AIS_FSM_INFO *prAisFsmInfo; + struct BSS_DESC *prBssDesc; + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + + /* reset BSS-DESC */ + if (prAisFsmInfo->prTargetStaRec) { + prBssDesc = + scanSearchBssDescByTA(prAdapter, + prAisFsmInfo-> + prTargetStaRec->aucMacAddr); + + if (prBssDesc) { + prBssDesc->fgIsConnected &= ~BIT(ucBssIndex); + prBssDesc->fgIsConnecting &= ~BIT(ucBssIndex); + } + } + /* release channel privilege */ + aisFsmReleaseCh(prAdapter, ucBssIndex); +} +#endif /* CFG_SUPPORT_ADHOC */ + +static u_int8_t +aisState_OFF_CHNL_TX(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) +{ + struct AIS_MGMT_TX_REQ_INFO *prMgmtTxInfo = + (struct AIS_MGMT_TX_REQ_INFO *) NULL; + struct AIS_OFF_CHNL_TX_REQ_INFO *prOffChnlTxPkt = + (struct AIS_OFF_CHNL_TX_REQ_INFO *) NULL; + struct AIS_FSM_INFO *prAisFsmInfo = + aisGetAisFsmInfo(prAdapter, ucBssIndex); + + prMgmtTxInfo = &prAisFsmInfo->rMgmtTxInfo; + + if (LINK_IS_EMPTY(&(prMgmtTxInfo->rTxReqLink))) { + cnmTimerStopTimer(prAdapter, + &prAisFsmInfo->rChannelTimeoutTimer); + aisFsmReleaseCh(prAdapter, ucBssIndex); + /* Link is empty, return back to IDLE. */ + return FALSE; + } + + prOffChnlTxPkt = + LINK_PEEK_HEAD(&(prMgmtTxInfo->rTxReqLink), + struct AIS_OFF_CHNL_TX_REQ_INFO, + rLinkEntry); + + if (prOffChnlTxPkt == NULL) { + DBGLOG(AIS, ERROR, + "Fatal Error, Link not empty but get NULL pointer.\n"); + aisFsmReleaseCh(prAdapter, ucBssIndex); + return FALSE; + } + + if (timerPendingTimer(&prAisFsmInfo->rChannelTimeoutTimer)) { + cnmTimerStopTimer(prAdapter, + &prAisFsmInfo->rChannelTimeoutTimer); + } + + cnmTimerStartTimer(prAdapter, + &prAisFsmInfo->rChannelTimeoutTimer, + prOffChnlTxPkt->u4Duration); + aisFuncTxMgmtFrame(prAdapter, + prMgmtTxInfo, + prOffChnlTxPkt->prMgmtTxMsdu, + prOffChnlTxPkt->u8Cookie, + ucBssIndex); + LINK_REMOVE_HEAD(&(prAisFsmInfo->rMgmtTxInfo.rTxReqLink), + prOffChnlTxPkt, + struct AIS_OFF_CHNL_TX_REQ_INFO *); + cnmMemFree(prAdapter, prOffChnlTxPkt); + + return TRUE; +} + + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Remove roaming requests including search and connect + * + * @param[in] + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void aisFsmRemoveRoamingRequest( + IN struct ADAPTER *prAdapter, IN uint8_t ucBssIndex) +{ + /* clear pending roaming connection request */ + aisFsmClearRequest(prAdapter, AIS_REQUEST_ROAMING_SEARCH, ucBssIndex); + aisFsmClearRequest(prAdapter, AIS_REQUEST_ROAMING_CONNECT, ucBssIndex); +} + +struct BSS_DESC *aisSearchBssDescByScore( + IN struct ADAPTER *prAdapter, IN uint8_t ucBssIndex) +{ + struct ROAMING_INFO *roam = aisGetRoamingInfo(prAdapter, ucBssIndex); + + return scanSearchBssDescByScoreForAis(prAdapter, + roam->eReason, ucBssIndex); +} + +uint8_t aisNeedTargetScan(IN struct ADAPTER *prAdapter, IN uint8_t ucBssIndex) +{ + struct AIS_FSM_INFO *ais = NULL; + struct BSS_INFO *bss = NULL; + struct ROAMING_INFO *roam = NULL; + uint8_t discovering = FALSE; + uint8_t postponing = FALSE; + uint8_t issued = FALSE; + uint8_t trial = 0; + + ais = aisGetAisFsmInfo(prAdapter, ucBssIndex); + bss = aisGetAisBssInfo(prAdapter, ucBssIndex); + roam = aisGetRoamingInfo(prAdapter, ucBssIndex); + discovering = bss->eConnectionState == MEDIA_STATE_CONNECTED && + (roam->eCurrentState == ROAMING_STATE_DISCOVERY || + roam->eCurrentState == ROAMING_STATE_ROAM); + postponing = aisFsmIsInProcessPostpone(prAdapter, ucBssIndex); + trial = ais->ucConnTrialCount; + +#if CFG_SUPPORT_NCHO + issued = ais->fgTargetChnlScanIssued || + prAdapter->rNchoInfo.u4RoamScanControl; +#else + issued = ais->fgTargetChnlScanIssued; +#endif + + return (discovering && issued) || + (postponing && trial < AIS_ROAMING_CONNECTION_TRIAL_LIMIT); +} + +enum ENUM_AIS_STATE aisSearchHandleBssDesc(IN struct ADAPTER *prAdapter, + struct BSS_DESC *prBssDesc, IN uint8_t ucBssIndex) +{ + + struct AIS_FSM_INFO *prAisFsmInfo; + struct BSS_INFO *prAisBssInfo; + struct CONNECTION_SETTINGS *prConnSettings; + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + prAisBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + prConnSettings = aisGetConnSettings(prAdapter, ucBssIndex); + + /* 4 <2> We are not under Roaming Condition. */ + if (prAisBssInfo->eConnectionState == MEDIA_STATE_DISCONNECTED) { + /* 4 <2.a> If we have the matched one */ + if (prBssDesc) { + /* 4 Stored the Selected BSS security cipher. or + * later asoc req compose IE + */ + prAisBssInfo->u4RsnSelectedGroupCipher = + prBssDesc->u4RsnSelectedGroupCipher; + prAisBssInfo->u4RsnSelectedPairwiseCipher = + prBssDesc->u4RsnSelectedPairwiseCipher; + prAisBssInfo->u4RsnSelectedAKMSuite = + prBssDesc->u4RsnSelectedAKMSuite; + prAisBssInfo->eBand = prBssDesc->eBand; + if (prAisBssInfo->fgIsWmmInited == FALSE) + prAisBssInfo->ucWmmQueSet = + cnmWmmIndexDecision(prAdapter, prAisBssInfo); +#if CFG_SUPPORT_DBDC + /* DBDC decsion.may change OpNss */ + cnmDbdcPreConnectionEnableDecision( + prAdapter, + prAisBssInfo->ucBssIndex, + prBssDesc->eBand, + prBssDesc->ucChannelNum, + prAisBssInfo->ucWmmQueSet); +#endif /*CFG_SUPPORT_DBDC*/ + + /* 4 Do STATE transition and update current + * Operation Mode. + */ + if (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) { + prAisBssInfo->eCurrentOPMode = + OP_MODE_INFRASTRUCTURE; + prAisFsmInfo->prTargetBssDesc = prBssDesc; + prAisFsmInfo->ucConnTrialCount++; + return AIS_STATE_REQ_CHANNEL_JOIN; +#if CFG_SUPPORT_ADHOC + } else if (prBssDesc->eBSSType == BSS_TYPE_IBSS) { + prAisBssInfo->eCurrentOPMode = OP_MODE_IBSS; + prAisFsmInfo->prTargetBssDesc = prBssDesc; + return AIS_STATE_IBSS_MERGE; +#endif /* CFG_SUPPORT_ADHOC */ + } else { + return AIS_STATE_WAIT_FOR_NEXT_SCAN; + } + } else { + /* 4 <2.b> If we don't have the matched one */ + if (prAisFsmInfo->rJoinReqTime != 0 && + CHECK_FOR_TIMEOUT(kalGetTimeTick(), + prAisFsmInfo->rJoinReqTime, + SEC_TO_SYSTIME(AIS_JOIN_TIMEOUT))) { + return AIS_STATE_JOIN_FAILURE; + } + + return aisFsmStateSearchAction(prAdapter, ucBssIndex); + } + } else { + /* 4 <3> We are under Roaming Condition. */ + if (prAisFsmInfo->ucConnTrialCount > + AIS_ROAMING_CONNECTION_TRIAL_LIMIT) { +#if CFG_SUPPORT_ROAMING + DBGLOG(AIS, STATE, "Roaming retry :%d fail!\n", + prAisFsmInfo->ucConnTrialCount); + roamingFsmRunEventFail(prAdapter, + ROAMING_FAIL_REASON_CONNLIMIT, ucBssIndex); +#endif /* CFG_SUPPORT_ROAMING */ + + /* reset retry count */ + prAisFsmInfo->ucConnTrialCount = 0; + + return AIS_STATE_NORMAL_TR; + } + +#define BSS_DESC_BAD_CASE \ + (!prBssDesc || ((prBssDesc->fgIsConnected & BIT(ucBssIndex)) && \ + prConnSettings->eConnectionPolicy != CONNECT_BY_BSSID) || \ + prBssDesc->eBSSType != BSS_TYPE_INFRASTRUCTURE) + /* 4 <3.a> Following cases will go back to NORMAL_TR. + * Precondition: not user space triggered roaming + * + * CASE I: During Roaming, APP(WZC/NDISTEST) change the + * connection settings. That make we can NOT match + * the original AP, so the prBssDesc is NULL. + * + * CASE II: The same reason as CASE I. + * Because APP change the eOPMode to other network type in + * connection setting (e.g. NET_TYPE_IBSS), so the BssDesc + * become the IBSS node. + * (For CASE I/II, before WZC/NDISTEST set the OID_SSID, + * it will change other parameters in connection setting first. + * if we do roaming at the same time, it will hit these cases.) + * + * CASE III: Normal case, we can't find other candidate to roam + * out, so only the current AP will be matched. + * however, if the connection policy is BSSID, means upper layer + * order driver connect to specific AP, we need still do connect + */ + if (prAisBssInfo->ucReasonOfDisconnect != + DISCONNECT_REASON_CODE_REASSOCIATION && + prAisBssInfo->ucReasonOfDisconnect != + DISCONNECT_REASON_CODE_ROAMING && BSS_DESC_BAD_CASE) { + if (prBssDesc) { + DBGLOG(ROAMING, INFO, + "fgIsConnected=%d, prBssDesc " MACSTR + ", prAisBssInfo " MACSTR "\n", + prBssDesc->fgIsConnected, + MAC2STR(prBssDesc->aucBSSID), + MAC2STR(prAisBssInfo->aucBSSID)); + } + if (prAisFsmInfo->fgTargetChnlScanIssued) { + /* if target channel scan has issued, and no + * roaming target is found, need to do full scan + */ + DBGLOG(AIS, INFO, + "[Roaming] No target found, try to full scan again\n"); + + prAisFsmInfo->fgTargetChnlScanIssued = FALSE; + return AIS_STATE_LOOKING_FOR; + } + +#if CFG_SUPPORT_ROAMING + roamingFsmRunEventFail(prAdapter, + ROAMING_FAIL_REASON_NOCANDIDATE, ucBssIndex); +#endif /* CFG_SUPPORT_ROAMING */ + + /* We already associated with it go back to NORMAL_TR */ + return AIS_STATE_NORMAL_TR; + } + + /* 4 <3.b> Try to roam out for JOIN this BSS_DESC_T. */ + if (BSS_DESC_BAD_CASE) + return aisFsmStateSearchAction(prAdapter, ucBssIndex); + + prAisFsmInfo->prTargetBssDesc = prBssDesc; + prAisFsmInfo->ucConnTrialCount++; + prAisFsmInfo->fgTargetChnlScanIssued = FALSE; + + return AIS_STATE_REQ_CHANNEL_JOIN; + } +} + +u_int8_t aisScanChannelFixed(struct ADAPTER *prAdapter, enum ENUM_BAND *prBand, + uint8_t *pucPrimaryChannel, IN uint8_t ucBssIndex) +{ + struct CONNECTION_SETTINGS *setting; + struct AIS_FSM_INFO *ais; + + ais = aisGetAisFsmInfo(prAdapter, ucBssIndex); + setting = aisGetConnSettings(prAdapter, ucBssIndex); + if (ais->eCurrentState == AIS_STATE_LOOKING_FOR && + setting->eConnectionPolicy == CONNECT_BY_BSSID && + setting->u4FreqInKHz != 0) { + *pucPrimaryChannel = + nicFreq2ChannelNum(setting->u4FreqInKHz * 1000); + if (*pucPrimaryChannel > 0) { + if (*pucPrimaryChannel <= 14) + *prBand = BAND_2G4; + else + *prBand = BAND_5G; + DBGLOG(AIS, INFO, "fixed channel %d, band %d\n", + *pucPrimaryChannel, *prBand); + return TRUE; + } + } else { + return cnmAisInfraChannelFixed(prAdapter, + prBand, pucPrimaryChannel); + } + return FALSE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief The Core FSM engine of AIS(Ad-hoc, Infra STA) + * + * @param[in] eNextState Enum value of next AIS STATE + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void aisFsmSteps(IN struct ADAPTER *prAdapter, + enum ENUM_AIS_STATE eNextState, uint8_t ucBssIndex) +{ + struct AIS_FSM_INFO *prAisFsmInfo; + struct BSS_INFO *prAisBssInfo; + struct AIS_SPECIFIC_BSS_INFO *prAisSpecificBssInfo; + struct CONNECTION_SETTINGS *prConnSettings; + struct BSS_DESC *prBssDesc; + struct MSG_CH_REQ *prMsgChReq; + struct MSG_SCN_SCAN_REQ_V2 *prScanReqMsg; + struct PARAM_SCAN_REQUEST_ADV *prScanRequest; + struct AIS_REQ_HDR *prAisReq; + struct ROAMING_INFO *prRoamingFsmInfo = NULL; + enum ENUM_BAND eBand = BAND_2G4; + uint8_t ucChannel = 1; + uint16_t u2ScanIELen; + u_int8_t fgIsTransition = (u_int8_t) FALSE; + uint8_t ucRfBw; + enum ENUM_AIS_STATE eNewState; + + DEBUGFUNC("aisFsmSteps()"); + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + prAisBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + prAisSpecificBssInfo = + aisGetAisSpecBssInfo(prAdapter, ucBssIndex); + prConnSettings = aisGetConnSettings(prAdapter, ucBssIndex); + prRoamingFsmInfo = + aisGetRoamingInfo(prAdapter, ucBssIndex); + + do { + + /* Do entering Next State */ + prAisFsmInfo->ePreviousState = prAisFsmInfo->eCurrentState; + + DBGLOG(AIS, STATE, "[AIS%d] TRANSITION: [%s] -> [%s]\n", + ucBssIndex, + aisGetFsmState(prAisFsmInfo->eCurrentState), + aisGetFsmState(eNextState)); + + /* NOTE(Kevin): This is the only place to change the + * eCurrentState(except initial) + */ + prAisFsmInfo->eCurrentState = eNextState; + + fgIsTransition = (u_int8_t) FALSE; + + aisPostponedEventOfDisconnTimeout(prAdapter, ucBssIndex); + + /* Do tasks of the State that we just entered */ + switch (prAisFsmInfo->eCurrentState) { + /* NOTE(Kevin): we don't have to rearrange the + * sequence of following switch case. Instead + * I would like to use a common lookup table of array + * of function pointer to speed up state search. + */ + case AIS_STATE_IDLE: + + prAisReq = aisFsmGetNextRequest(prAdapter, ucBssIndex); + if (prAisFsmInfo->ePreviousState == + AIS_STATE_OFF_CHNL_TX) + aisFunClearAllTxReq(prAdapter, + &(prAisFsmInfo->rMgmtTxInfo)); + + if (prAisReq) + DBGLOG(AIS, INFO, + "eReqType=%d", prAisReq->eReqType); + else + DBGLOG(AIS, INFO, "No req anymore"); + + if (prAisReq == NULL || + prAisReq->eReqType == AIS_REQUEST_RECONNECT) { + if (IS_NET_ACTIVE(prAdapter, + prAisBssInfo->ucBssIndex)) { + UNSET_NET_ACTIVE(prAdapter, + prAisBssInfo->ucBssIndex); + nicDeactivateNetwork(prAdapter, + prAisBssInfo->ucBssIndex); + } + if (prAisReq != NULL) { + SET_NET_ACTIVE(prAdapter, + prAisBssInfo-> + ucBssIndex); + /* sync with firmware */ + nicActivateNetwork(prAdapter, + prAisBssInfo->ucBssIndex); + + SET_NET_PWR_STATE_ACTIVE(prAdapter, + prAisBssInfo->ucBssIndex); + + eNextState = AIS_STATE_SEARCH; + fgIsTransition = TRUE; + } else { + SET_NET_PWR_STATE_IDLE(prAdapter, + prAisBssInfo->ucBssIndex); + + if (prAdapter->rWifiVar. + rScanInfo.fgSchedScanning) { + SET_NET_ACTIVE(prAdapter, + prAisBssInfo->ucBssIndex); + nicActivateNetwork(prAdapter, + prAisBssInfo->ucBssIndex); + } + } + + if (prAisReq) { + /* free the message */ + cnmMemFree(prAdapter, prAisReq); + } + } else if (prAisReq->eReqType == AIS_REQUEST_SCAN) { + wlanClearScanningResult(prAdapter, ucBssIndex); + + eNextState = AIS_STATE_SCAN; + fgIsTransition = TRUE; + + /* free the message */ + cnmMemFree(prAdapter, prAisReq); + } else if (prAisReq->eReqType == + AIS_REQUEST_ROAMING_CONNECT + || prAisReq->eReqType == + AIS_REQUEST_ROAMING_SEARCH) { + fgIsTransition = TRUE; + /* ignore */ + /* free the message */ + cnmMemFree(prAdapter, prAisReq); + } else if (prAisReq->eReqType == + AIS_REQUEST_REMAIN_ON_CHANNEL) { + eNextState = AIS_STATE_REQ_REMAIN_ON_CHANNEL; + fgIsTransition = TRUE; + + /* free the message */ + cnmMemFree(prAdapter, prAisReq); + } + + prAisFsmInfo->u4SleepInterval = + AIS_BG_SCAN_INTERVAL_MIN_SEC; + + break; + + case AIS_STATE_SEARCH: + /* 4 <1> Search for a matched candidate and save + * it to prTargetBssDesc. + * changing the state, + * ATTENTION: anyone can't leave this case without + * except BTM, otherwise, may cause BtmResponseTimer's + * handler run worngly + */ +#if CFG_SLT_SUPPORT + prBssDesc = + prAdapter->rWifiVar.rSltInfo.prPseudoBssDesc; +#else + /* Support AP Selection */ + if (prAisFsmInfo->ucJoinFailCntAfterScan >= + SCN_BSS_JOIN_FAIL_THRESOLD) { + prBssDesc = NULL; + DBGLOG(AIS, STATE, + "Failed to connect %s more than 4 times after last scan, scan again\n", + prConnSettings->aucSSID); + } else { +#if CFG_SELECT_BSS_BASE_ON_MULTI_PARAM + prBssDesc = aisSearchBssDescByScore( + prAdapter, ucBssIndex); +#else + prBssDesc = scanSearchBssDescByPolicy + (prAdapter, prAisBssInfo->ucBssIndex); +#endif + } +#endif + + eNewState = aisSearchHandleBssDesc( + prAdapter, prBssDesc, ucBssIndex); + + if (eNewState != eNextState) { + eNextState = eNewState; + fgIsTransition = TRUE; + } + + break; + + case AIS_STATE_WAIT_FOR_NEXT_SCAN: + + DBGLOG(AIS, LOUD, + "SCAN: Idle Begin - Current Time = %u\n", + kalGetTimeTick()); + + cnmTimerStartTimer(prAdapter, + &prAisFsmInfo->rBGScanTimer, + SEC_TO_MSEC + (prAisFsmInfo->u4SleepInterval)); + + SET_NET_PWR_STATE_IDLE(prAdapter, + prAisBssInfo->ucBssIndex); + + if (prAisFsmInfo->u4SleepInterval < + AIS_BG_SCAN_INTERVAL_MAX_SEC) + prAisFsmInfo->u4SleepInterval <<= 1; + + break; + + case AIS_STATE_SCAN: + case AIS_STATE_ONLINE_SCAN: + case AIS_STATE_LOOKING_FOR: + + if (!IS_NET_ACTIVE + (prAdapter, prAisBssInfo->ucBssIndex)) { + SET_NET_ACTIVE(prAdapter, + prAisBssInfo->ucBssIndex); + + /* sync with firmware */ + nicActivateNetwork(prAdapter, + prAisBssInfo->ucBssIndex); + } + prScanRequest = &(prAisFsmInfo->rScanRequest); + + /* IE length decision */ + if (prScanRequest->u4IELength > 0) { + u2ScanIELen = + (uint16_t) prScanRequest->u4IELength; + } else { +#if CFG_SUPPORT_WPS2 + u2ScanIELen = prConnSettings->u2WSCIELen; +#else + u2ScanIELen = 0; +#endif + } + + prScanReqMsg = + (struct MSG_SCN_SCAN_REQ_V2 *)cnmMemAlloc(prAdapter, + RAM_TYPE_MSG, + OFFSET_OF + (struct + MSG_SCN_SCAN_REQ_V2, + aucIE) + + u2ScanIELen); + if (!prScanReqMsg) { + DBGLOG(AIS, ERROR, "Can't trigger SCAN FSM\n"); + return; + } + kalMemZero(prScanReqMsg, OFFSET_OF + (struct MSG_SCN_SCAN_REQ_V2, + aucIE)+u2ScanIELen); + prScanReqMsg->rMsgHdr.eMsgId = MID_AIS_SCN_SCAN_REQ_V2; + prScanReqMsg->ucSeqNum = + ++prAisFsmInfo->ucSeqNumOfScanReq; + if (prAisFsmInfo->u2SeqNumOfScanReport == + AIS_SCN_REPORT_SEQ_NOT_SET) { + prAisFsmInfo->u2SeqNumOfScanReport = + (uint16_t) prScanReqMsg->ucSeqNum; + } + prScanReqMsg->ucBssIndex = + prAisBssInfo->ucBssIndex; +#if CFG_SUPPORT_802_11K + if (rrmFillScanMsg(prAdapter, prScanReqMsg)) { + mboxSendMsg(prAdapter, MBOX_ID_0, + (struct MSG_HDR *)prScanReqMsg, + MSG_SEND_METHOD_BUF); + break; + } + COPY_MAC_ADDR(prScanReqMsg->aucBSSID, + "\xff\xff\xff\xff\xff\xff"); +#endif + +#if CFG_SUPPORT_RDD_TEST_MODE + prScanReqMsg->eScanType = SCAN_TYPE_PASSIVE_SCAN; +#else + if (prAisFsmInfo->eCurrentState == AIS_STATE_SCAN + || prAisFsmInfo->eCurrentState == + AIS_STATE_ONLINE_SCAN) { + uint8_t ucScanSSIDNum; + enum ENUM_SCAN_TYPE eScanType; + + ucScanSSIDNum = prScanRequest->u4SsidNum; + eScanType = prScanRequest->ucScanType; + + if (eScanType == SCAN_TYPE_ACTIVE_SCAN + && ucScanSSIDNum == 0) { + prScanReqMsg->eScanType = eScanType; + + prScanReqMsg->ucSSIDType + = SCAN_REQ_SSID_WILDCARD; + prScanReqMsg->ucSSIDNum = 0; + } else if (eScanType == SCAN_TYPE_PASSIVE_SCAN + && ucScanSSIDNum == 0) { + prScanReqMsg->eScanType = eScanType; + + prScanReqMsg->ucSSIDType = 0; + prScanReqMsg->ucSSIDNum = 0; + } else { + prScanReqMsg->eScanType = + SCAN_TYPE_ACTIVE_SCAN; + + prScanReqMsg->ucSSIDType = + SCAN_REQ_SSID_SPECIFIED; + prScanReqMsg->ucSSIDNum = ucScanSSIDNum; + prScanReqMsg->prSsid = + prScanRequest->rSsid; + } + kalMemCopy(prScanReqMsg->aucRandomMac, + prScanRequest->aucRandomMac, + MAC_ADDR_LEN); + prScanReqMsg->ucScnFuncMask |= + prScanRequest->ucScnFuncMask; + + } else { + prScanReqMsg->eScanType = SCAN_TYPE_ACTIVE_SCAN; + + COPY_SSID(prAisFsmInfo->rRoamingSSID.aucSsid, + prAisFsmInfo->rRoamingSSID.u4SsidLen, + prConnSettings->aucSSID, + prConnSettings->ucSSIDLen); + + /* Scan for determined SSID */ + prScanReqMsg->ucSSIDType = + SCAN_REQ_SSID_SPECIFIED_ONLY; + prScanReqMsg->ucSSIDNum = 1; + prScanReqMsg->prSsid = + &(prAisFsmInfo->rRoamingSSID); +#if CFG_SUPPORT_SCAN_RANDOM_MAC + prScanReqMsg->ucScnFuncMask |= + ENUM_SCN_RANDOM_MAC_EN; +#endif + } +#endif + + /* using default channel dwell time/timeout value */ + prScanReqMsg->u2ProbeDelay = 0; + prScanReqMsg->u2ChannelDwellTime = 0; + prScanReqMsg->u2ChannelMinDwellTime = 0; + prScanReqMsg->u2TimeoutValue = 0; + /* Reduce APP scan's dwell time, prevent it affecting + * TX/RX performance + */ + if (prScanRequest->u4Flags & + NL80211_SCAN_FLAG_LOW_SPAN) { + prScanReqMsg->u2ChannelDwellTime = + SCAN_CHANNEL_DWELL_TIME_MSEC_APP; + prScanReqMsg->u2ChannelMinDwellTime = + SCAN_CHANNEL_MIN_DWELL_TIME_MSEC_APP; + } + /* check if tethering is running and need to fix on + * specific channel + */ + if (aisScanChannelFixed(prAdapter, &eBand, + &ucChannel, ucBssIndex)) { + prScanReqMsg->eScanChannel = + SCAN_CHANNEL_SPECIFIED; + prScanReqMsg->ucChannelListNum = 1; + prScanReqMsg->arChnlInfoList[0].eBand = eBand; + prScanReqMsg->arChnlInfoList[0].ucChannelNum = + ucChannel; + } else if (aisNeedTargetScan(prAdapter, + prAisBssInfo->ucBssIndex)) { + struct RF_CHANNEL_INFO *prChnlInfo = + &prScanReqMsg->arChnlInfoList[0]; + uint8_t ucChannelNum = 0; + uint8_t i = 0; + uint8_t essChnlNum = + prAisSpecificBssInfo->ucCurEssChnlInfoNum; + + for (i = 0; i < essChnlNum; i++) { + ucChannelNum = + prAisSpecificBssInfo-> + arCurEssChnlInfo[i].ucChannel; + if ((ucChannelNum >= 1) + && (ucChannelNum <= 14)) + prChnlInfo[i].eBand = BAND_2G4; + else + prChnlInfo[i].eBand = BAND_5G; + prChnlInfo[i].ucChannelNum + = ucChannelNum; + } + prScanReqMsg->ucChannelListNum = essChnlNum; + prScanReqMsg->eScanChannel = + SCAN_CHANNEL_SPECIFIED; + DBGLOG(AIS, INFO, + "[Roaming] Target Scan: Total number of scan channel(s)=%d\n", + prScanReqMsg->ucChannelListNum); + } else + if (prAdapter->aePreferBand + [KAL_NETWORK_TYPE_AIS_INDEX] == + BAND_NULL) { + if (prAdapter->fgEnable5GBand == TRUE) + prScanReqMsg->eScanChannel = + SCAN_CHANNEL_FULL; + else + prScanReqMsg->eScanChannel = + SCAN_CHANNEL_2G4; + + } else + if (prAdapter->aePreferBand + [KAL_NETWORK_TYPE_AIS_INDEX] == + BAND_2G4) { + prScanReqMsg->eScanChannel = SCAN_CHANNEL_2G4; + } else + if (prAdapter->aePreferBand + [KAL_NETWORK_TYPE_AIS_INDEX] == + BAND_5G) { + prScanReqMsg->eScanChannel = SCAN_CHANNEL_5G; + } else { + prScanReqMsg->eScanChannel = SCAN_CHANNEL_FULL; + } + + switch (prScanReqMsg->eScanChannel) { + case SCAN_CHANNEL_FULL: + case SCAN_CHANNEL_2G4: + case SCAN_CHANNEL_5G: + scanSetRequestChannel(prAdapter, + prScanRequest->u4ChannelNum, + prScanRequest->arChannel, + prScanRequest->u4Flags, + prAisFsmInfo->eCurrentState == + AIS_STATE_ONLINE_SCAN || + wlanWfdEnabled(prAdapter), + prScanReqMsg); + break; + default: + break; + } + + + if (u2ScanIELen > 0) { + kalMemCopy(prScanReqMsg->aucIE, + prScanRequest->pucIE, u2ScanIELen); + } else { +#if CFG_SUPPORT_WPS2 + if (prConnSettings->u2WSCIELen > 0) { + kalMemCopy(prScanReqMsg->aucIE, + &prConnSettings->aucWSCIE, + prConnSettings->u2WSCIELen); + } + } +#endif + prScanReqMsg->u2IELen = u2ScanIELen; + + mboxSendMsg(prAdapter, MBOX_ID_0, + (struct MSG_HDR *)prScanReqMsg, + MSG_SEND_METHOD_BUF); + + /* reset prAisFsmInfo->rScanRequest */ + kalMemZero(prAisFsmInfo->aucScanIEBuf, + sizeof(prAisFsmInfo->aucScanIEBuf)); + prScanRequest->u4SsidNum = 0; + prScanRequest->ucScanType = SCAN_TYPE_ACTIVE_SCAN; + prScanRequest->u4IELength = 0; + prScanRequest->u4ChannelNum = 0; + prScanRequest->ucScnFuncMask = 0; + kalMemZero(prScanRequest->aucRandomMac, MAC_ADDR_LEN); + prAisFsmInfo->fgIsScanning = TRUE; + + /* Support AP Selection */ + prAisFsmInfo->ucJoinFailCntAfterScan = 0; + /* Scan flags will be set in next scan triggered by + * upper layer, reset to 0 to avoid next scan + * is triggered by Driver + */ + prScanRequest->u4Flags = 0; + break; + + case AIS_STATE_REQ_CHANNEL_JOIN: + /* stop Tx due to we need to connect a new AP. even the + ** new AP is operating on the same channel with current + ** , we still need to stop Tx, because firmware should + ** ensure all mgmt and dhcp packets are Tx in time, + ** and may cause normal data packets was queued and + ** eventually flushed in firmware + */ + if (prAisBssInfo->prStaRecOfAP && + prAisBssInfo->ucReasonOfDisconnect != + DISCONNECT_REASON_CODE_REASSOCIATION) + prAisBssInfo-> + prStaRecOfAP->fgIsTxAllowed = FALSE; + + /* send message to CNM for acquiring channel */ + prMsgChReq = + (struct MSG_CH_REQ *)cnmMemAlloc(prAdapter, + RAM_TYPE_MSG, + sizeof(struct MSG_CH_REQ)); + if (!prMsgChReq) { + DBGLOG(AIS, ERROR, "Can't indicate CNM\n"); + return; + } + + prMsgChReq->rMsgHdr.eMsgId = MID_MNY_CNM_CH_REQ; + prMsgChReq->ucBssIndex = + prAisBssInfo->ucBssIndex; + prMsgChReq->ucTokenID = ++prAisFsmInfo->ucSeqNumOfChReq; + prMsgChReq->eReqType = CH_REQ_TYPE_JOIN; + prMsgChReq->u4MaxInterval = + AIS_JOIN_CH_REQUEST_INTERVAL; + prMsgChReq->ucPrimaryChannel = + prAisFsmInfo->prTargetBssDesc->ucChannelNum; + prMsgChReq->eRfSco = + prAisFsmInfo->prTargetBssDesc->eSco; + prMsgChReq->eRfBand = + prAisFsmInfo->prTargetBssDesc->eBand; +#if CFG_SUPPORT_DBDC + prMsgChReq->eDBDCBand = ENUM_BAND_AUTO; +#endif /*CFG_SUPPORT_DBDC */ + /* To do: check if 80/160MHz bandwidth is needed here */ + /* Decide RF BW by own OP and Peer OP BW */ + ucRfBw = + cnmGetDbdcBwCapability(prAdapter, + prAisBssInfo->ucBssIndex); + /* Revise to VHT OP BW */ + ucRfBw = rlmGetVhtOpBwByBssOpBw(ucRfBw); + if (ucRfBw > + prAisFsmInfo->prTargetBssDesc->eChannelWidth) + ucRfBw = + prAisFsmInfo-> + prTargetBssDesc->eChannelWidth; + + prMsgChReq->eRfChannelWidth = ucRfBw; + /* TODO: BW80+80 support */ + prMsgChReq->ucRfCenterFreqSeg1 = + nicGetVhtS1(prMsgChReq->ucPrimaryChannel, + prMsgChReq->eRfChannelWidth); + DBGLOG(RLM, INFO, + "AIS req CH for CH:%d, Bw:%d, s1=%d\n", + prAisBssInfo->ucPrimaryChannel, + prMsgChReq->eRfChannelWidth, + prMsgChReq->ucRfCenterFreqSeg1); + prMsgChReq->ucRfCenterFreqSeg2 = 0; + + rlmReviseMaxBw(prAdapter, prAisBssInfo->ucBssIndex, + &prMsgChReq->eRfSco, + (enum ENUM_CHANNEL_WIDTH *) + &prMsgChReq->eRfChannelWidth, + &prMsgChReq->ucRfCenterFreqSeg1, + &prMsgChReq->ucPrimaryChannel); + + mboxSendMsg(prAdapter, MBOX_ID_0, + (struct MSG_HDR *)prMsgChReq, + MSG_SEND_METHOD_BUF); + + prAisFsmInfo->fgIsChannelRequested = TRUE; + break; + + case AIS_STATE_JOIN: + aisFsmStateInit_JOIN(prAdapter, + prAisFsmInfo->prTargetBssDesc, + ucBssIndex); + break; + + case AIS_STATE_JOIN_FAILURE: + nicMediaJoinFailure(prAdapter, + prAisBssInfo->ucBssIndex, + WLAN_STATUS_JOIN_FAILURE); + + prAisFsmInfo->prTargetBssDesc = NULL; + prAisFsmInfo->ucConnTrialCountLimit = 0; + eNextState = AIS_STATE_IDLE; + fgIsTransition = TRUE; + + break; + +#if CFG_SUPPORT_ADHOC + case AIS_STATE_IBSS_ALONE: + aisFsmStateInit_IBSS_ALONE(prAdapter, + ucBssIndex); + break; + + case AIS_STATE_IBSS_MERGE: + aisFsmStateInit_IBSS_MERGE(prAdapter, + prAisFsmInfo->prTargetBssDesc, + ucBssIndex); + break; +#endif /* CFG_SUPPORT_ADHOC */ + + case AIS_STATE_NORMAL_TR: + /* Renew op trx nss */ + cnmOpModeGetTRxNss(prAdapter, + prAisBssInfo->ucBssIndex, + &prAisBssInfo->ucOpRxNss, + &prAisBssInfo->ucOpTxNss); + + /* Don't do anything when rJoinTimeoutTimer + * is still ticking + */ + if (timerPendingTimer(&prAisFsmInfo->rJoinTimeoutTimer)) + break; + + if (prAisFsmInfo->ePreviousState == + AIS_STATE_OFF_CHNL_TX) + aisFunClearAllTxReq(prAdapter, + &(prAisFsmInfo->rMgmtTxInfo)); + + /* 1. Process for pending roaming scan */ + if (aisFsmIsRequestPending(prAdapter, + AIS_REQUEST_ROAMING_SEARCH, TRUE, + ucBssIndex) == TRUE) { + eNextState = AIS_STATE_LOOKING_FOR; + fgIsTransition = TRUE; + } + /* 2. Process for pending roaming connect */ + else if (aisFsmIsRequestPending(prAdapter, + AIS_REQUEST_ROAMING_CONNECT, TRUE, + ucBssIndex) + == TRUE) { + eNextState = AIS_STATE_SEARCH; + fgIsTransition = TRUE; + } + /* 3. Process for pending scan */ + else if (aisFsmIsRequestPending(prAdapter, + AIS_REQUEST_SCAN, TRUE, + ucBssIndex) == TRUE) { + wlanClearScanningResult(prAdapter, ucBssIndex); + eNextState = AIS_STATE_ONLINE_SCAN; + fgIsTransition = TRUE; + } else if (aisFsmIsRequestPending(prAdapter, + AIS_REQUEST_REMAIN_ON_CHANNEL, TRUE, + ucBssIndex) + == TRUE) { + eNextState = AIS_STATE_REQ_REMAIN_ON_CHANNEL; + fgIsTransition = TRUE; + } + + break; + + case AIS_STATE_DISCONNECTING: + /* send for deauth frame for disconnection */ + authSendDeauthFrame(prAdapter, + prAisBssInfo, + prAisBssInfo->prStaRecOfAP, + (struct SW_RFB *)NULL, + REASON_CODE_DEAUTH_LEAVING_BSS, + aisDeauthXmitComplete); + /* If it is scanning or BSS absent, HW may go away from + * serving channel, which may cause driver be not able + * to TX mgmt frame. So we need to start a longer timer + * to wait HW return to serving channel. + * We set the time out value to 1 second because + * it is long enough to return to serving channel + * in most cases, and disconnection delay is seamless + * to end-user even time out. + */ + cnmTimerStartTimer(prAdapter, + &prAisFsmInfo->rDeauthDoneTimer, + (prAisFsmInfo->fgIsScanning + || prAisBssInfo->fgIsNetAbsent) ? + 1000 : 100); + break; + + case AIS_STATE_REQ_REMAIN_ON_CHANNEL: + /* send message to CNM for acquiring channel */ + prMsgChReq = + (struct MSG_CH_REQ *)cnmMemAlloc(prAdapter, + RAM_TYPE_MSG, + sizeof(struct MSG_CH_REQ)); + if (!prMsgChReq) { + DBGLOG(AIS, ERROR, "Can't indicate CNM\n"); + return; + } + + /* release channel */ + aisFsmReleaseCh(prAdapter, ucBssIndex); + + /* zero-ize */ + kalMemZero(prMsgChReq, sizeof(struct MSG_CH_REQ)); + + /* filling */ + prMsgChReq->rMsgHdr.eMsgId = MID_MNY_CNM_CH_REQ; + prMsgChReq->ucBssIndex = + prAisBssInfo->ucBssIndex; + prMsgChReq->ucTokenID = ++prAisFsmInfo->ucSeqNumOfChReq; + prMsgChReq->eReqType = + prAisFsmInfo->rChReqInfo.eReqType; + prMsgChReq->u4MaxInterval = + prAisFsmInfo->rChReqInfo.u4DurationMs; + prMsgChReq->ucPrimaryChannel = + prAisFsmInfo->rChReqInfo.ucChannelNum; + prMsgChReq->eRfSco = prAisFsmInfo->rChReqInfo.eSco; + prMsgChReq->eRfBand = prAisFsmInfo->rChReqInfo.eBand; +#if CFG_SUPPORT_DBDC + prMsgChReq->eDBDCBand = ENUM_BAND_AUTO; +#endif + mboxSendMsg(prAdapter, MBOX_ID_0, + (struct MSG_HDR *)prMsgChReq, + MSG_SEND_METHOD_BUF); + + prAisFsmInfo->fgIsChannelRequested = TRUE; + + break; + + case AIS_STATE_REMAIN_ON_CHANNEL: + if (!IS_NET_ACTIVE(prAdapter, + prAisBssInfo->ucBssIndex)) { + SET_NET_ACTIVE(prAdapter, + prAisBssInfo->ucBssIndex); + + /* sync with firmware */ + nicActivateNetwork(prAdapter, + prAisBssInfo->ucBssIndex); + } + + break; + + case AIS_STATE_OFF_CHNL_TX: + if (!IS_NET_ACTIVE(prAdapter, + prAisBssInfo->ucBssIndex)) { + SET_NET_ACTIVE(prAdapter, + prAisBssInfo->ucBssIndex); + + /* sync with firmware */ + nicActivateNetwork(prAdapter, + prAisBssInfo->ucBssIndex); + } + if (!aisState_OFF_CHNL_TX(prAdapter, ucBssIndex)) { + if (prAisBssInfo->eConnectionState == + MEDIA_STATE_CONNECTED) + eNextState = AIS_STATE_NORMAL_TR; + else + eNextState = AIS_STATE_IDLE; + fgIsTransition = TRUE; + } + break; + + default: + /* Make sure we have handle all STATEs */ + ASSERT(0); + break; + + } + } while (fgIsTransition); + + return; + +} /* end of aisFsmSteps() */ + +enum ENUM_AIS_STATE aisFsmStateSearchAction( + IN struct ADAPTER *prAdapter, uint8_t ucBssIndex) +{ + struct CONNECTION_SETTINGS *prConnSettings; + struct BSS_INFO *prAisBssInfo; + struct AIS_FSM_INFO *prAisFsmInfo; + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + prAisBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + prConnSettings = aisGetConnSettings(prAdapter, ucBssIndex); + + if (prConnSettings->eOPMode == NET_TYPE_INFRA) + prAisFsmInfo->ucConnTrialCount++; + +#if CFG_SUPPORT_ADHOC + if (prConnSettings->eOPMode == NET_TYPE_IBSS || + prConnSettings->eOPMode == NET_TYPE_AUTO_SWITCH || + prConnSettings->eOPMode == NET_TYPE_DEDICATED_IBSS) { + prAisBssInfo->eCurrentOPMode = OP_MODE_IBSS; + prAisFsmInfo->prTargetBssDesc = NULL; + return AIS_STATE_IBSS_ALONE; + } +#endif /* CFG_SUPPORT_ADHOC */ + + return AIS_STATE_LOOKING_FOR; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void aisFsmRunEventScanDone(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct MSG_SCN_SCAN_DONE *prScanDoneMsg; + struct AIS_FSM_INFO *prAisFsmInfo; + enum ENUM_AIS_STATE eNextState; + uint8_t ucSeqNumOfCompMsg; + struct CONNECTION_SETTINGS *prConnSettings; + enum ENUM_SCAN_STATUS eStatus = SCAN_STATUS_DONE; + struct RADIO_MEASUREMENT_REQ_PARAMS *prRmReq; + struct BCN_RM_PARAMS *prBcnRmParam; + struct ROAMING_INFO *prRoamingFsmInfo = NULL; + uint8_t ucBssIndex = 0; + + DEBUGFUNC("aisFsmRunEventScanDone()"); + + prScanDoneMsg = (struct MSG_SCN_SCAN_DONE *)prMsgHdr; + ucBssIndex = prScanDoneMsg->ucBssIndex; + + DBGLOG(AIS, LOUD, "[%d] EVENT-SCAN DONE: Current Time = %u\n", + ucBssIndex, + kalGetTimeTick()); + + if (aisGetAisBssInfo(prAdapter, ucBssIndex) == NULL) { + /* This case occurs when the AIS isn't done, but the wlan0 */ + /* has changed to AP mode. And the prAisBssInfo is freed. */ + DBGLOG(AIS, WARN, "prAisBssInfo is NULL, and then return\n"); + return; + } + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + prConnSettings = aisGetConnSettings(prAdapter, ucBssIndex); + prRoamingFsmInfo = + aisGetRoamingInfo(prAdapter, ucBssIndex); + prRmReq = aisGetRmReqParam(prAdapter, ucBssIndex); + prBcnRmParam = &prRmReq->rBcnRmParam; + + ucSeqNumOfCompMsg = prScanDoneMsg->ucSeqNum; + eStatus = prScanDoneMsg->eScanStatus; + cnmMemFree(prAdapter, prMsgHdr); + + DBGLOG(AIS, INFO, "ScanDone %u, status(%d) native req(%u)\n", + ucSeqNumOfCompMsg, eStatus, prAisFsmInfo->u2SeqNumOfScanReport); + + eNextState = prAisFsmInfo->eCurrentState; + + if ((uint16_t) ucSeqNumOfCompMsg == + prAisFsmInfo->u2SeqNumOfScanReport) { + prAisFsmInfo->u2SeqNumOfScanReport = AIS_SCN_REPORT_SEQ_NOT_SET; + prConnSettings->fgIsScanReqIssued = FALSE; + kalScanDone(prAdapter->prGlueInfo, ucBssIndex, + (eStatus == SCAN_STATUS_DONE) ? + WLAN_STATUS_SUCCESS : WLAN_STATUS_FAILURE); + } + if (ucSeqNumOfCompMsg != prAisFsmInfo->ucSeqNumOfScanReq) { + DBGLOG(AIS, WARN, + "SEQ NO of AIS SCN DONE MSG is not matched %u %u\n", + ucSeqNumOfCompMsg, prAisFsmInfo->ucSeqNumOfScanReq); + } else { + prAisFsmInfo->fgIsScanning = FALSE; + cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer); + switch (prAisFsmInfo->eCurrentState) { + case AIS_STATE_SCAN: + eNextState = AIS_STATE_IDLE; +#if CFG_SUPPORT_AGPS_ASSIST + scanReportScanResultToAgps(prAdapter); +#endif + break; + + case AIS_STATE_ONLINE_SCAN: + scanGetCurrentEssChnlList(prAdapter, ucBssIndex); + +#if CFG_SUPPORT_ROAMING + eNextState = aisFsmRoamingScanResultsUpdate(prAdapter, + ucBssIndex); +#else + eNextState = AIS_STATE_NORMAL_TR; +#endif /* CFG_SUPPORT_ROAMING */ +#if CFG_SUPPORT_AGPS_ASSIST + scanReportScanResultToAgps(prAdapter); +#endif +/* Support AP Selection */ + +/* end Support AP Selection */ + break; + + case AIS_STATE_LOOKING_FOR: + scanGetCurrentEssChnlList(prAdapter, ucBssIndex); + +#if CFG_SUPPORT_ROAMING + eNextState = aisFsmRoamingScanResultsUpdate(prAdapter, + ucBssIndex); +#else + eNextState = AIS_STATE_SEARCH; +#endif /* CFG_SUPPORT_ROAMING */ + break; + + default: + break; + + } + } + if (eNextState != prAisFsmInfo->eCurrentState) + aisFsmSteps(prAdapter, eNextState, ucBssIndex); + if (prBcnRmParam->eState == RM_NO_REQUEST) + return; + /* normal mode scan done, and beacon measurement is pending, + ** schedule to do measurement + */ + if (prBcnRmParam->eState == RM_WAITING) { + rrmDoBeaconMeasurement(prAdapter, ucBssIndex); + /* pending normal scan here, should schedule it on time */ + } else if (prBcnRmParam->rNormalScan.fgExist) { + struct NORMAL_SCAN_PARAMS *prParam = &prBcnRmParam->rNormalScan; + + DBGLOG(AIS, INFO, + "BCN REQ: Schedule normal scan after a beacon measurement done\n"); + prBcnRmParam->eState = RM_WAITING; + prBcnRmParam->rNormalScan.fgExist = FALSE; + cnmTimerStartTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer, + SEC_TO_MSEC(AIS_SCN_DONE_TIMEOUT_SEC)); + + aisFsmScanRequestAdv(prAdapter, &prParam->rScanRequest); + /* Radio Measurement is on-going, schedule to next Measurement + ** Element + */ + } else { +#if CFG_SUPPORT_802_11K + struct LINK *prBSSDescList = + &prAdapter->rWifiVar.rScanInfo.rBSSDescList; + struct BSS_DESC *prBssDesc = NULL; + uint32_t count = 0; + + /* collect updated bss for beacon request measurement */ + LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, + struct BSS_DESC) + { + if (TIME_BEFORE(prRmReq->rScanStartTime, + prBssDesc->rUpdateTime)) { + rrmCollectBeaconReport( + prAdapter, prBssDesc, ucBssIndex); + count++; + } + } + DBGLOG(RRM, INFO, "BCN report Active Mode, total: %d\n", count); +#endif + rrmStartNextMeasurement(prAdapter, FALSE, ucBssIndex); + } +} /* end of aisFsmRunEventScanDone() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void aisFsmRunEventAbort(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct MSG_AIS_ABORT *prAisAbortMsg; + struct AIS_FSM_INFO *prAisFsmInfo; + struct BSS_INFO *prAisBssInfo; + uint8_t ucReasonOfDisconnect; + u_int8_t fgDelayIndication; + struct CONNECTION_SETTINGS *prConnSettings; + uint8_t ucBssIndex = 0; + + DEBUGFUNC("aisFsmRunEventAbort()"); + + /* 4 <1> Extract information of Abort Message and then free memory. */ + prAisAbortMsg = (struct MSG_AIS_ABORT *)prMsgHdr; + ucReasonOfDisconnect = prAisAbortMsg->ucReasonOfDisconnect; + fgDelayIndication = prAisAbortMsg->fgDelayIndication; + ucBssIndex = prAisAbortMsg->ucBssIndex; + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + prAisBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + prConnSettings = aisGetConnSettings(prAdapter, ucBssIndex); + + cnmMemFree(prAdapter, prMsgHdr); + + DBGLOG(AIS, STATE, + "[%d] EVENT-ABORT: Current State %s, ucReasonOfDisconnect:%d\n", + ucBssIndex, + aisGetFsmState(prAisFsmInfo->eCurrentState), + ucReasonOfDisconnect); + + /* record join request time */ + GET_CURRENT_SYSTIME(&(prAisFsmInfo->rJoinReqTime)); + + /* 4 <2> clear previous pending connection request and insert new one */ + if (ucReasonOfDisconnect == DISCONNECT_REASON_CODE_DEAUTHENTICATED || + ucReasonOfDisconnect == DISCONNECT_REASON_CODE_DISASSOCIATED) { + struct STA_RECORD *prSta = prAisFsmInfo->prTargetStaRec; + struct BSS_DESC *prBss = prAisFsmInfo->prTargetBssDesc; + + if (prSta && prBss) { + struct AIS_BLACKLIST_ITEM *blk = + aisAddBlacklist(prAdapter, prBss); + + if (blk) { + blk->u2DeauthReason = prSta->u2ReasonCode; + blk->fgDeauthLastTime = TRUE; + } + } + } + + /* to support user space triggered roaming */ + if (ucReasonOfDisconnect == DISCONNECT_REASON_CODE_ROAMING && + prAisFsmInfo->eCurrentState != AIS_STATE_DISCONNECTING) { +#if CFG_SUPPORT_DETECT_SECURITY_MODE_CHANGE + cnmTimerStopTimer(prAdapter, + &prAisFsmInfo->rSecModeChangeTimer); +#endif + prAisBssInfo->ucReasonOfDisconnect = ucReasonOfDisconnect; + if (prAisFsmInfo->eCurrentState == AIS_STATE_NORMAL_TR) { + /* 1. release channel */ + aisFsmReleaseCh(prAdapter, ucBssIndex); + /* 2.1 stop join timeout timer */ + cnmTimerStopTimer(prAdapter, + &prAisFsmInfo->rJoinTimeoutTimer); + aisFsmSteps(prAdapter, AIS_STATE_SEARCH, ucBssIndex); + } else { + aisFsmRemoveRoamingRequest(prAdapter, ucBssIndex); + aisFsmInsertRequest(prAdapter, + AIS_REQUEST_ROAMING_CONNECT, + ucBssIndex); + } + return; + } + /* Support AP Selection */ +#if CFG_SELECT_BSS_BASE_ON_MULTI_PARAM + scanGetCurrentEssChnlList(prAdapter, ucBssIndex); +#endif + /* end Support AP Selection */ + + aisFsmClearRequest(prAdapter, AIS_REQUEST_RECONNECT, ucBssIndex); + if (ucReasonOfDisconnect == DISCONNECT_REASON_CODE_NEW_CONNECTION || + ucReasonOfDisconnect == DISCONNECT_REASON_CODE_REASSOCIATION || + ucReasonOfDisconnect == DISCONNECT_REASON_CODE_ROAMING) + aisFsmInsertRequestToHead(prAdapter, + AIS_REQUEST_RECONNECT, ucBssIndex); + + if (prAisFsmInfo->eCurrentState != AIS_STATE_DISCONNECTING) { + if (ucReasonOfDisconnect != + DISCONNECT_REASON_CODE_REASSOCIATION) { + /* 4 <3> invoke abort handler */ + aisFsmStateAbort(prAdapter, ucReasonOfDisconnect, + fgDelayIndication, ucBssIndex); + } else { + /* 1. release channel */ + aisFsmReleaseCh(prAdapter, ucBssIndex); + /* 2.1 stop join timeout timer */ + cnmTimerStopTimer(prAdapter, + &prAisFsmInfo->rJoinTimeoutTimer); + + prAisBssInfo->ucReasonOfDisconnect = + ucReasonOfDisconnect; + aisFsmSteps(prAdapter, AIS_STATE_IDLE, ucBssIndex); + } + } +} /* end of aisFsmRunEventAbort() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function handles AIS-FSM abort event/command + * + * \param[in] prAdapter Pointer of ADAPTER_T + * ucReasonOfDisconnect Reason for disonnection + * fgDelayIndication Option to delay disconnection indication + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void aisFsmStateAbort(IN struct ADAPTER *prAdapter, + uint8_t ucReasonOfDisconnect, u_int8_t fgDelayIndication, + uint8_t ucBssIndex) +{ + struct AIS_FSM_INFO *prAisFsmInfo; + struct BSS_INFO *prAisBssInfo; + struct CONNECTION_SETTINGS *prConnSettings; + u_int8_t fgIsCheckConnected; + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + prAisBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + + /* XXX: The wlan0 may has been changed to AP mode. */ + if (prAisBssInfo == NULL) + return; + + prConnSettings = aisGetConnSettings(prAdapter, ucBssIndex); + fgIsCheckConnected = FALSE; + + DBGLOG(AIS, STATE, + "[%d] aisFsmStateAbort DiscReason[%d], CurState[%d], delayIndi[%d]\n", + ucBssIndex, ucReasonOfDisconnect, + prAisFsmInfo->eCurrentState, fgDelayIndication); + + /* 4 <1> Save information of Abort Message and then free memory. */ + prAisBssInfo->ucReasonOfDisconnect = ucReasonOfDisconnect; + if (prAisBssInfo->eConnectionState == MEDIA_STATE_CONNECTED && + prAisFsmInfo->eCurrentState != AIS_STATE_DISCONNECTING && + ucReasonOfDisconnect != DISCONNECT_REASON_CODE_REASSOCIATION && + ucReasonOfDisconnect != DISCONNECT_REASON_CODE_ROAMING) + wmmNotifyDisconnected(prAdapter, ucBssIndex); + + + if (fgDelayIndication) { + uint8_t p2p = cnmP2pIsActive(prAdapter); + uint8_t join = timerPendingTimer( + &prAisFsmInfo->rJoinTimeoutTimer); + + if (p2p || join) { + fgDelayIndication = FALSE; + DBGLOG(AIS, INFO, + "delay indication not allowed due to p2p=%d, join=%d", + p2p, join); + } + } + + /* 4 <2> Abort current job. */ + switch (prAisFsmInfo->eCurrentState) { + case AIS_STATE_IDLE: + case AIS_STATE_SEARCH: + case AIS_STATE_JOIN_FAILURE: + break; + + case AIS_STATE_WAIT_FOR_NEXT_SCAN: + /* Do cancel timer */ + cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rBGScanTimer); + + /* in case roaming is triggered */ + fgIsCheckConnected = TRUE; + break; + + case AIS_STATE_ONLINE_SCAN: + fgIsCheckConnected = TRUE; + case AIS_STATE_SCAN: + /* Do abort SCAN */ + aisFsmStateAbort_SCAN(prAdapter, ucBssIndex); + break; + case AIS_STATE_LOOKING_FOR: + /* Do abort SCAN */ + aisFsmStateAbort_SCAN(prAdapter, ucBssIndex); + + /* in case roaming is triggered */ + fgIsCheckConnected = TRUE; + break; + + case AIS_STATE_REQ_CHANNEL_JOIN: + /* Release channel to CNM */ + aisFsmReleaseCh(prAdapter, ucBssIndex); + + /* in case roaming is triggered */ + fgIsCheckConnected = TRUE; + break; + + case AIS_STATE_JOIN: + /* Do abort JOIN */ + aisFsmStateAbort_JOIN(prAdapter, ucBssIndex); + + /* in case roaming is triggered */ + fgIsCheckConnected = TRUE; + break; + +#if CFG_SUPPORT_ADHOC + case AIS_STATE_IBSS_ALONE: + case AIS_STATE_IBSS_MERGE: + aisFsmStateAbort_IBSS(prAdapter, ucBssIndex); + break; +#endif /* CFG_SUPPORT_ADHOC */ + case AIS_STATE_NORMAL_TR: + fgIsCheckConnected = TRUE; + break; + + case AIS_STATE_DISCONNECTING: + /* Do abort NORMAL_TR */ + aisFsmStateAbort_NORMAL_TR(prAdapter, ucBssIndex); + + break; + + case AIS_STATE_REQ_REMAIN_ON_CHANNEL: + /* release channel */ + aisFsmReleaseCh(prAdapter, ucBssIndex); + break; + + case AIS_STATE_REMAIN_ON_CHANNEL: + case AIS_STATE_OFF_CHNL_TX: + fgIsCheckConnected = TRUE; + /* 1. release channel */ + aisFsmReleaseCh(prAdapter, ucBssIndex); + + /* 2. stop channel timeout timer */ + cnmTimerStopTimer(prAdapter, + &prAisFsmInfo->rChannelTimeoutTimer); + + break; + + default: + break; + } + + if (fgIsCheckConnected + && (prAisBssInfo->eConnectionState == + MEDIA_STATE_CONNECTED)) { + + /* switch into DISCONNECTING state for sending DEAUTH + * if necessary + */ + if (prAisBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE && + (prAisBssInfo->ucReasonOfDisconnect == + DISCONNECT_REASON_CODE_NEW_CONNECTION || + prAisBssInfo->ucReasonOfDisconnect == + DISCONNECT_REASON_CODE_LOCALLY) + && prAisBssInfo->prStaRecOfAP + && prAisBssInfo->prStaRecOfAP->fgIsInUse) { + aisFsmSteps(prAdapter, AIS_STATE_DISCONNECTING, + ucBssIndex); + + return; + } + /* Do abort NORMAL_TR */ + aisFsmStateAbort_NORMAL_TR(prAdapter, ucBssIndex); + } + rrmFreeMeasurementResources(prAdapter, ucBssIndex); + aisFsmDisconnect(prAdapter, fgDelayIndication, ucBssIndex); + + return; + +} /* end of aisFsmStateAbort() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will handle the Join Complete Event from SAA FSM + * for AIS FSM + * @param[in] prMsgHdr Message of Join Complete of SAA FSM. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void aisFsmRunEventJoinComplete(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct MSG_SAA_FSM_COMP *prJoinCompMsg; + struct AIS_FSM_INFO *prAisFsmInfo; + enum ENUM_AIS_STATE eNextState; + struct SW_RFB *prAssocRspSwRfb; + struct STA_RECORD *prStaRec; + uint8_t ucBssIndex = 0; + + DEBUGFUNC("aisFsmRunEventJoinComplete()"); + + prJoinCompMsg = (struct MSG_SAA_FSM_COMP *)prMsgHdr; + prAssocRspSwRfb = prJoinCompMsg->prSwRfb; + prStaRec = prJoinCompMsg->prStaRec; + if (prStaRec) + ucBssIndex = prStaRec->ucBssIndex; + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + + eNextState = prAisFsmInfo->eCurrentState; + + /* Check State and SEQ NUM */ + if (prAisFsmInfo->eCurrentState == AIS_STATE_JOIN) { + /* Check SEQ NUM */ + if (prJoinCompMsg->ucSeqNum == prAisFsmInfo->ucSeqNumOfReqMsg) + eNextState = + aisFsmJoinCompleteAction(prAdapter, prMsgHdr); + else { + eNextState = AIS_STATE_JOIN_FAILURE; + DBGLOG(AIS, WARN, + "SEQ NO of AIS JOIN COMP MSG is not matched.\n"); + } + } + + if (eNextState != prAisFsmInfo->eCurrentState) + aisFsmSteps(prAdapter, eNextState, ucBssIndex); + + if (prAssocRspSwRfb) + nicRxReturnRFB(prAdapter, prAssocRspSwRfb); + + cnmMemFree(prAdapter, prMsgHdr); +} /* end of aisFsmRunEventJoinComplete() */ + +enum ENUM_AIS_STATE aisFsmJoinCompleteAction(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct MSG_SAA_FSM_COMP *prJoinCompMsg; + struct AIS_FSM_INFO *prAisFsmInfo; + struct ROAMING_INFO *roam; + enum ENUM_AIS_STATE eNextState; + struct STA_RECORD *prStaRec; + struct SW_RFB *prAssocRspSwRfb; + struct BSS_INFO *prAisBssInfo; + OS_SYSTIME rCurrentTime; + struct CONNECTION_SETTINGS *prConnSettings; + uint8_t ucBssIndex = 0; + + DEBUGFUNC("aisFsmJoinCompleteAction()"); + + GET_CURRENT_SYSTIME(&rCurrentTime); + + prJoinCompMsg = (struct MSG_SAA_FSM_COMP *)prMsgHdr; + prStaRec = prJoinCompMsg->prStaRec; + prAssocRspSwRfb = prJoinCompMsg->prSwRfb; + + ucBssIndex = prStaRec->ucBssIndex; + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + prAisBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + prConnSettings = aisGetConnSettings(prAdapter, ucBssIndex); + eNextState = prAisFsmInfo->eCurrentState; + roam = aisGetRoamingInfo(prAdapter, ucBssIndex); + + do { + /* 4 <1> JOIN was successful */ + if (prJoinCompMsg->rJoinStatus == WLAN_STATUS_SUCCESS) { +#if CFG_SUPPORT_DETECT_SECURITY_MODE_CHANGE + prConnSettings->fgSecModeChangeStartTimer = FALSE; +#endif + + /* 1. Reset retry count */ + prAisFsmInfo->ucConnTrialCount = 0; + + /* Completion of roaming */ + if (prAisBssInfo->eConnectionState == + MEDIA_STATE_CONNECTED) { + +#if CFG_SUPPORT_ROAMING + /* 2. Deactivate previous BSS */ + aisFsmRoamingDisconnectPrevAP(prAdapter, + prStaRec); + + /* 3. Update bss based on roaming staRec */ + aisUpdateBssInfoForRoamingAP(prAdapter, + prStaRec, + prAssocRspSwRfb); +#endif /* CFG_SUPPORT_ROAMING */ + } else { + kalResetStats( + wlanGetNetDev( + prAdapter->prGlueInfo, + ucBssIndex)); + + /* 4 <1.1> Change FW's Media State + * immediately. + */ + aisChangeMediaState(prAisBssInfo, + MEDIA_STATE_CONNECTED); + + /* 4 <1.2> Deactivate previous AP's STA_RECORD_T + * in Driver if have. + */ + if ((prAisBssInfo->prStaRecOfAP) && + (prAisBssInfo->prStaRecOfAP != prStaRec) && + (prAisBssInfo->prStaRecOfAP->fgIsInUse) && + (prAisBssInfo->prStaRecOfAP->ucBssIndex == + prAisBssInfo->ucBssIndex)) { + + cnmStaRecChangeState(prAdapter, + prAisBssInfo->prStaRecOfAP, + STA_STATE_1); + cnmStaRecFree(prAdapter, + prAisBssInfo->prStaRecOfAP); + } + + /* For temp solution, need to refine */ + /* 4 <1.4> Update BSS_INFO_T */ + aisUpdateBssInfoForJOIN(prAdapter, prStaRec, + prAssocRspSwRfb); + + /* 4 <1.3> Activate current AP's STA_RECORD_T + * in Driver. + */ + cnmStaRecChangeState(prAdapter, prStaRec, + STA_STATE_3); + + /* 4 <1.5> Update RSSI if necessary */ + nicUpdateRSSI(prAdapter, + prAisBssInfo->ucBssIndex, + (int8_t) (RCPI_TO_dBm + (prStaRec->ucRCPI)), 0); + + /* 4 <1.6> Indicate Connected Event to Host + * immediately. + */ + /* Require BSSID, Association ID, + * Beacon Interval + */ + /* .. from AIS_BSS_INFO_T */ + aisIndicationOfMediaStateToHost(prAdapter, + MEDIA_STATE_CONNECTED, + FALSE, + ucBssIndex); + + if (prAdapter->rWifiVar.ucTpTestMode == + ENUM_TP_TEST_MODE_THROUGHPUT) + nicEnterTPTestMode(prAdapter, + TEST_MODE_THROUGHPUT); + else if (prAdapter->rWifiVar.ucTpTestMode == + ENUM_TP_TEST_MODE_SIGMA_AC_N_PMF) + nicEnterTPTestMode(prAdapter, + TEST_MODE_SIGMA_AC_N_PMF); + else if (prAdapter->rWifiVar.ucTpTestMode == + ENUM_TP_TEST_MODE_SIGMA_WMM_PS) + nicEnterTPTestMode(prAdapter, + TEST_MODE_SIGMA_WMM_PS); + } + +#if CFG_SUPPORT_ROAMING + /* if roaming fsm is monitoring old AP, abort it*/ + if (roam->eCurrentState >= ROAMING_STATE_DECISION) + roamingFsmRunEventAbort(prAdapter, ucBssIndex); + + /* if user space roaming is enabled, we should + * disable driver/fw roaming + */ + if (prConnSettings->eConnectionPolicy != + CONNECT_BY_BSSID && roam->fgDrvRoamingAllow) { + prConnSettings->eConnectionPolicy = + CONNECT_BY_SSID_BEST_RSSI; + roamingFsmRunEventStart(prAdapter, ucBssIndex); + } +#endif /* CFG_SUPPORT_ROAMING */ + if (aisFsmIsRequestPending + (prAdapter, AIS_REQUEST_ROAMING_CONNECT, + FALSE, ucBssIndex) == FALSE) + prAisFsmInfo->rJoinReqTime = 0; + + /* remove all deauthing AP from blacklist */ + aisRemoveDeauthBlacklist(prAdapter); + prAisFsmInfo->ucJoinFailCntAfterScan = 0; + +#if CFG_SUPPORT_802_11K + aisResetNeighborApList(prAdapter, ucBssIndex); + if (prAisFsmInfo->prTargetBssDesc->aucRrmCap[0] & + BIT(RRM_CAP_INFO_NEIGHBOR_REPORT_BIT)) + aisSendNeighborRequest(prAdapter, + ucBssIndex); +#endif + + /* 4 <1.7> Set the Next State of AIS FSM */ + eNextState = AIS_STATE_NORMAL_TR; + } + /* 4 <2> JOIN was not successful */ + else { + /* 4 <2.1> Redo JOIN process with other Auth Type + * if possible + */ + if (aisFsmStateInit_RetryJOIN(prAdapter, prStaRec, + ucBssIndex) == FALSE) { + struct BSS_DESC *prBssDesc; + struct PARAM_SSID rSsid; + struct CONNECTION_SETTINGS *prConnSettings; + + prConnSettings = + aisGetConnSettings(prAdapter, + ucBssIndex); + prBssDesc = prAisFsmInfo->prTargetBssDesc; + + /* 1. Increase Failure Count */ + prStaRec->ucJoinFailureCount++; + + /* 2. release channel */ + aisFsmReleaseCh(prAdapter, ucBssIndex); + + /* 3.1 stop join timeout timer */ + cnmTimerStopTimer(prAdapter, + &prAisFsmInfo->rJoinTimeoutTimer); + + /* Support AP Selection */ + prAisFsmInfo->ucJoinFailCntAfterScan++; + + kalMemZero(&rSsid, sizeof(struct PARAM_SSID)); + if (prBssDesc) + COPY_SSID(rSsid.aucSsid, + rSsid.u4SsidLen, + prBssDesc->aucSSID, + prBssDesc->ucSSIDLen); + else + COPY_SSID(rSsid.aucSsid, + rSsid.u4SsidLen, + prConnSettings->aucSSID, + prConnSettings->ucSSIDLen); + + prBssDesc = + scanSearchBssDescByBssidAndSsid(prAdapter, + prStaRec->aucMacAddr, + TRUE, + &rSsid); + + if (prBssDesc == NULL) { + eNextState = AIS_STATE_JOIN_FAILURE; + DBGLOG(AIS, ERROR, + "Can't get bss descriptor\n"); + break; + } + + DBGLOG(AIS, INFO, + "ucJoinFailureCount=%d %d, Status=%d Reason=%d, eConnectionState=%d", + prStaRec->ucJoinFailureCount, + prBssDesc->ucJoinFailureCount, + prStaRec->u2StatusCode, + prStaRec->u2ReasonCode, + prAisBssInfo->eConnectionState); + + prBssDesc->u2JoinStatus = + prStaRec->u2StatusCode; + prBssDesc->ucJoinFailureCount++; + if (prBssDesc->ucJoinFailureCount >= + SCN_BSS_JOIN_FAIL_THRESOLD || + scanApOverload(prStaRec->u2StatusCode, + prStaRec->u2ReasonCode)) { + /* Support AP Selection */ + aisAddBlacklist(prAdapter, prBssDesc); + + GET_CURRENT_SYSTIME + (&prBssDesc->rJoinFailTime); + DBGLOG(AIS, INFO, + "Bss " MACSTR + " join fail %d times, temp disable it at time: %u\n", + MAC2STR(prBssDesc->aucBSSID), + prBssDesc->ucJoinFailureCount, + prBssDesc->rJoinFailTime); + } + + if (prStaRec->u2StatusCode + == STATUS_INVALID_PMKID) { + struct AIS_BLACKLIST_ITEM *prBlackList = + aisAddBlacklist(prAdapter, + prBssDesc); + if (prBlackList) { + prBlackList->u2AuthStatus = + prStaRec->u2StatusCode; + DBGLOG(AIS, INFO, + "Add blacklist due to STATUS_INVALID_PMKID\n"); + } + } + + /* Support AP Selection */ + if (prBssDesc->prBlack) + prBssDesc->prBlack->u2AuthStatus = + prStaRec->u2StatusCode; + + if (prBssDesc) + prBssDesc->fgIsConnecting &= + ~BIT(ucBssIndex); + + /* 3.3 Free STA-REC */ + if (prStaRec != prAisBssInfo->prStaRecOfAP) + cnmStaRecFree(prAdapter, prStaRec); + + if (prAisBssInfo->eConnectionState == + MEDIA_STATE_CONNECTED || + prStaRec->u2StatusCode == + STATUS_CODE_ASSOC_REJECTED_TEMPORARILY) { + struct PARAM_SSID rSsid; + + /* roaming fail count and time */ + prAdapter->prGlueInfo->u4RoamFailCnt++; + prAdapter->prGlueInfo->u8RoamFailTime = + sched_clock(); +#if CFG_SUPPORT_ROAMING + eNextState = + AIS_STATE_WAIT_FOR_NEXT_SCAN; +#endif /* CFG_SUPPORT_ROAMING */ + + if (prAisBssInfo->prStaRecOfAP) + prAisBssInfo-> + prStaRecOfAP->fgIsTxAllowed + = TRUE; + + COPY_SSID(rSsid.aucSsid, + rSsid.u4SsidLen, + prAisBssInfo->aucSSID, + prAisBssInfo->ucSSIDLen); + prAisFsmInfo->prTargetBssDesc = + scanSearchBssDescByBssidAndSsid + (prAdapter, prAisBssInfo->aucBSSID, + TRUE, &rSsid); + prAisFsmInfo->prTargetStaRec = + prAisBssInfo->prStaRecOfAP; + if (!prAisFsmInfo->prTargetBssDesc) + DBGLOG(AIS, ERROR, + "Can't retrieve target bss descriptor\n"); + } else if (prAisFsmInfo->rJoinReqTime != 0 + && CHECK_FOR_TIMEOUT(rCurrentTime, + prAisFsmInfo->rJoinReqTime, + SEC_TO_SYSTIME + (AIS_JOIN_TIMEOUT))) { + /* 4.a temrminate join operation */ + eNextState = AIS_STATE_JOIN_FAILURE; + } else if (prAisFsmInfo->rJoinReqTime != 0 + && prBssDesc->ucJoinFailureCount >= + SCN_BSS_JOIN_FAIL_THRESOLD + && prBssDesc->u2JoinStatus) { + /* AP reject STA for + * STATUS_CODE_ASSOC_DENIED_AP_OVERLOAD + * , or AP block STA + */ + eNextState = AIS_STATE_JOIN_FAILURE; + } else { + /* 4.b send reconnect request */ + aisFsmInsertRequest(prAdapter, + AIS_REQUEST_RECONNECT, + ucBssIndex); + + eNextState = AIS_STATE_IDLE; + } + } + } + } while (0); + return eNextState; +} + +#if CFG_SUPPORT_ADHOC +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will handle the Grant Msg of IBSS Create which was + * sent by CNM to indicate that channel was changed for creating IBSS. + * + * @param[in] prAdapter Pointer of ADAPTER_T + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void aisFsmCreateIBSS(IN struct ADAPTER *prAdapter, uint8_t ucBssIndex) +{ + struct AIS_FSM_INFO *prAisFsmInfo; + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + + do { + /* Check State */ + if (prAisFsmInfo->eCurrentState == AIS_STATE_IBSS_ALONE) + aisUpdateBssInfoForCreateIBSS(prAdapter, ucBssIndex); + + } while (FALSE); +} /* end of aisFsmCreateIBSS() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will handle the Grant Msg of IBSS Merge which was + * sent by CNM to indicate that channel was changed for merging IBSS. + * + * @param[in] prAdapter Pointer of ADAPTER_T + * @param[in] prStaRec Pointer of STA_RECORD_T for merge + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void aisFsmMergeIBSS(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec) +{ + struct AIS_FSM_INFO *prAisFsmInfo; + enum ENUM_AIS_STATE eNextState; + struct BSS_INFO *prAisBssInfo; + uint8_t ucBssIndex = 0; + + ucBssIndex = prStaRec->ucBssIndex; + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + prAisBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + + do { + + eNextState = prAisFsmInfo->eCurrentState; + + switch (prAisFsmInfo->eCurrentState) { + case AIS_STATE_IBSS_MERGE: + { + struct BSS_DESC *prBssDesc; + + /* 4 <1.1> Change FW's Media State + * immediately. + */ + aisChangeMediaState(prAisBssInfo, + MEDIA_STATE_CONNECTED); + + /* 4 <1.2> Deactivate previous Peers' + * STA_RECORD_T in Driver if have. + */ + bssInitializeClientList(prAdapter, + prAisBssInfo); + + /* 4 <1.3> Unmark connection flag of previous + * BSS_DESC_T. + */ + prBssDesc = + scanSearchBssDescByBssid(prAdapter, + prAisBssInfo->aucBSSID); + if (prBssDesc != NULL) { + prBssDesc->fgIsConnecting &= + ~BIT(ucBssIndex); + prBssDesc->fgIsConnected &= + ~BIT(ucBssIndex); + } + /* 4 <1.4> Add Peers' STA_RECORD_T to + * Client List + */ + bssAddClient(prAdapter, prAisBssInfo, prStaRec); + + /* 4 <1.5> Activate current Peer's STA_RECORD_T + * in Driver. + */ + cnmStaRecChangeState(prAdapter, prStaRec, + STA_STATE_3); + prStaRec->fgIsMerging = FALSE; + + /* 4 <1.6> Update BSS_INFO_T */ + aisUpdateBssInfoForMergeIBSS(prAdapter, + prStaRec); + + /* 4 <1.7> Enable other features */ + + /* 4 <1.8> Indicate Connected Event to Host + * immediately. + */ + aisIndicationOfMediaStateToHost(prAdapter, + MEDIA_STATE_CONNECTED, + FALSE, + ucBssIndex); + + /* 4 <1.9> Set the Next State of AIS FSM */ + eNextState = AIS_STATE_NORMAL_TR; + + /* 4 <1.10> Release channel privilege */ + aisFsmReleaseCh(prAdapter, ucBssIndex); + +#if CFG_SLT_SUPPORT + prAdapter->rWifiVar.rSltInfo.prPseudoStaRec = + prStaRec; +#endif + } + break; + + default: + break; + } + + if (eNextState != prAisFsmInfo->eCurrentState) + aisFsmSteps(prAdapter, eNextState, ucBssIndex); + + } while (FALSE); +} /* end of aisFsmMergeIBSS() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will handle the Notification of existing IBSS was found + * from SCN. + * + * @param[in] prMsgHdr Message of Notification of an IBSS was present. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void aisFsmRunEventFoundIBSSPeer(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct MSG_AIS_IBSS_PEER_FOUND *prAisIbssPeerFoundMsg; + struct AIS_FSM_INFO *prAisFsmInfo; + enum ENUM_AIS_STATE eNextState; + struct STA_RECORD *prStaRec; + struct BSS_INFO *prAisBssInfo; + struct BSS_DESC *prBssDesc; + u_int8_t fgIsMergeIn; + uint8_t ucBssIndex = 0; + + prAisIbssPeerFoundMsg = (struct MSG_AIS_IBSS_PEER_FOUND *)prMsgHdr; + ucBssIndex = prAisIbssPeerFoundMsg->ucBssIndex; + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + prAisBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + + prStaRec = prAisIbssPeerFoundMsg->prStaRec; + + fgIsMergeIn = prAisIbssPeerFoundMsg->fgIsMergeIn; + + cnmMemFree(prAdapter, prMsgHdr); + + eNextState = prAisFsmInfo->eCurrentState; + switch (prAisFsmInfo->eCurrentState) { + case AIS_STATE_IBSS_ALONE: + { + /* 4 <1> An IBSS Peer 'merged in'. */ + if (fgIsMergeIn) { + + /* 4 <1.1> Change FW's Media State + * immediately. + */ + aisChangeMediaState(prAisBssInfo, + MEDIA_STATE_CONNECTED); + + /* 4 <1.2> Add Peers' STA_RECORD_T to + * Client List + */ + bssAddClient(prAdapter, prAisBssInfo, prStaRec); + +#if CFG_SLT_SUPPORT + /* 4 <1.3> Mark connection flag of + * BSS_DESC_T. + */ + prBssDesc = + scanSearchBssDescByTA(prAdapter, + prStaRec->aucMacAddr); + + if (prBssDesc != NULL) { + prBssDesc->fgIsConnecting &= + ~BIT(ucBssIndex); + prBssDesc->fgIsConnected |= + BIT(ucBssIndex); + } + + /* 4 <1.4> Activate current Peer's + * STA_RECORD_T in Driver. + */ + /* TODO(Kevin): TBD */ + prStaRec->fgIsQoS = TRUE; +#else + /* 4 <1.3> Mark connection flag + * of BSS_DESC_T. + */ + prBssDesc = + scanSearchBssDescByBssid(prAdapter, + prAisBssInfo->aucBSSID); + + if (prBssDesc != NULL) { + prBssDesc->fgIsConnecting &= + ~BIT(ucBssIndex); + prBssDesc->fgIsConnected |= + BIT(ucBssIndex); + } + + /* 4 <1.4> Activate current Peer's STA_RECORD_T + * in Driver. + */ + /* TODO(Kevin): TBD */ + prStaRec->fgIsQoS = FALSE; + +#endif + + cnmStaRecChangeState(prAdapter, prStaRec, + STA_STATE_3); + prStaRec->fgIsMerging = FALSE; + + /* 4 <1.6> sync. to firmware */ + nicUpdateBss(prAdapter, + prAisBssInfo->ucBssIndex); + + /* 4 <1.7> Indicate Connected Event to Host + * immediately. + */ + aisIndicationOfMediaStateToHost(prAdapter, + MEDIA_STATE_CONNECTED, + FALSE, + ucBssIndex); + + /* 4 <1.8> indicate PM for connected */ + nicPmIndicateBssConnected(prAdapter, + prAisBssInfo->ucBssIndex); + + /* 4 <1.9> Set the Next State of AIS FSM */ + eNextState = AIS_STATE_NORMAL_TR; + + /* 4 <1.10> Release channel privilege */ + aisFsmReleaseCh(prAdapter, ucBssIndex); + } + /* 4 <2> We need 'merge out' to this IBSS */ + else { + + /* 4 <2.1> Get corresponding BSS_DESC_T */ + prBssDesc = + scanSearchBssDescByTA(prAdapter, + prStaRec->aucMacAddr); + + prAisFsmInfo->prTargetBssDesc = prBssDesc; + + /* 4 <2.2> Set the Next State of AIS FSM */ + eNextState = AIS_STATE_IBSS_MERGE; + } + } + break; + + case AIS_STATE_NORMAL_TR: + { + + /* 4 <3> An IBSS Peer 'merged in'. */ + if (fgIsMergeIn) { + + /* 4 <3.1> Add Peers' STA_RECORD_T to + * Client List + */ + bssAddClient(prAdapter, prAisBssInfo, prStaRec); + +#if CFG_SLT_SUPPORT + /* 4 <3.2> Activate current Peer's STA_RECORD_T + * in Driver. + */ + /* TODO(Kevin): TBD */ + prStaRec->fgIsQoS = TRUE; +#else + /* 4 <3.2> Activate current Peer's STA_RECORD_T + * in Driver. + */ + /* TODO(Kevin): TBD */ + prStaRec->fgIsQoS = FALSE; +#endif + + cnmStaRecChangeState(prAdapter, prStaRec, + STA_STATE_3); + prStaRec->fgIsMerging = FALSE; + + } + /* 4 <4> We need 'merge out' to this IBSS */ + else { + + /* 4 <4.1> Get corresponding BSS_DESC_T */ + prBssDesc = + scanSearchBssDescByTA(prAdapter, + prStaRec->aucMacAddr); + + prAisFsmInfo->prTargetBssDesc = prBssDesc; + + /* 4 <4.2> Set the Next State of AIS FSM */ + eNextState = AIS_STATE_IBSS_MERGE; + + } + } + break; + + default: + break; + } + + if (eNextState != prAisFsmInfo->eCurrentState) + aisFsmSteps(prAdapter, eNextState, ucBssIndex); +} /* end of aisFsmRunEventFoundIBSSPeer() */ +#endif /* CFG_SUPPORT_ADHOC */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will indicate the Media State to HOST + * + * @param[in] eConnectionState Current Media State + * @param[in] fgDelayIndication Set TRUE for postponing the Disconnect + * Indication. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void +aisIndicationOfMediaStateToHost(IN struct ADAPTER *prAdapter, + enum ENUM_PARAM_MEDIA_STATE eConnectionState, + u_int8_t fgDelayIndication, + uint8_t ucBssIndex) +{ + struct EVENT_CONNECTION_STATUS rEventConnStatus; + struct CONNECTION_SETTINGS *prConnSettings; + struct BSS_INFO *prAisBssInfo; + struct AIS_FSM_INFO *prAisFsmInfo; + struct ROAMING_INFO *prRoamingFsmInfo; + + DEBUGFUNC("aisIndicationOfMediaStateToHost()"); + + prConnSettings = aisGetConnSettings(prAdapter, ucBssIndex); + prAisBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + prRoamingFsmInfo = aisGetRoamingInfo(prAdapter, ucBssIndex); + + DBGLOG(AIS, LOUD, + "AIS%d indicate Media State to Host Current State [%d]\n", + ucBssIndex, + prAisBssInfo->eConnectionState); + + /* NOTE(Kevin): Move following line to aisChangeMediaState() + * macro per CM's request. + */ + /* prAisBssInfo->eConnectionState = eConnectionState; */ + + /* For indicating the Disconnect Event only if current media state is + * disconnected and we didn't do indication yet. + */ + DBGLOG(AIS, INFO, + "[%d] Current state: %d, connection state indicated: %d\n", + ucBssIndex, + prAisFsmInfo->eCurrentState, + prAisBssInfo->eConnectionStateIndicated); + + if (prAisBssInfo->eConnectionState == MEDIA_STATE_DISCONNECTED && + /* if receive DEAUTH in JOIN state, report disconnect*/ + !(prAisBssInfo->ucReasonOfDisconnect == + DISCONNECT_REASON_CODE_DEAUTHENTICATED && + prAisFsmInfo->eCurrentState == AIS_STATE_JOIN)) { + if (prAisBssInfo->eConnectionStateIndicated == eConnectionState) + return; + } + + if (!fgDelayIndication) { + /* 4 <0> Cancel Delay Timer */ + prAisFsmInfo->u4PostponeIndStartTime = 0; + + /* 4 <1> Fill EVENT_CONNECTION_STATUS */ + rEventConnStatus.ucMediaStatus = (uint8_t) eConnectionState; + + if (eConnectionState == MEDIA_STATE_CONNECTED) { + rEventConnStatus.ucReasonOfDisconnect = + DISCONNECT_REASON_CODE_RESERVED; + + if (prAisBssInfo->eCurrentOPMode == + OP_MODE_INFRASTRUCTURE) { + rEventConnStatus.ucInfraMode = + (uint8_t) NET_TYPE_INFRA; + rEventConnStatus.u2AID = + prAisBssInfo->u2AssocId; + rEventConnStatus.u2ATIMWindow = 0; + } else if (prAisBssInfo->eCurrentOPMode == + OP_MODE_IBSS) { + rEventConnStatus.ucInfraMode = + (uint8_t) NET_TYPE_IBSS; + rEventConnStatus.u2AID = 0; + rEventConnStatus.u2ATIMWindow = + prAisBssInfo->u2ATIMWindow; + } + + COPY_SSID(rEventConnStatus.aucSsid, + rEventConnStatus.ucSsidLen, + prConnSettings->aucSSID, + prConnSettings->ucSSIDLen); + + COPY_MAC_ADDR(rEventConnStatus.aucBssid, + prAisBssInfo->aucBSSID); + + rEventConnStatus.u2BeaconPeriod = + prAisBssInfo->u2BeaconInterval; + rEventConnStatus.u4FreqInKHz = + nicChannelNum2Freq(prAisBssInfo->ucPrimaryChannel); + + switch (prAisBssInfo->ucNonHTBasicPhyType) { + case PHY_TYPE_HR_DSSS_INDEX: + rEventConnStatus.ucNetworkType = + (uint8_t) PARAM_NETWORK_TYPE_DS; + break; + + case PHY_TYPE_ERP_INDEX: + rEventConnStatus.ucNetworkType = + (uint8_t) PARAM_NETWORK_TYPE_OFDM24; + break; + + case PHY_TYPE_OFDM_INDEX: + rEventConnStatus.ucNetworkType = + (uint8_t) PARAM_NETWORK_TYPE_OFDM5; + break; + + default: + rEventConnStatus.ucNetworkType = + (uint8_t) PARAM_NETWORK_TYPE_DS; + break; + } + } else { + rEventConnStatus.ucReasonOfDisconnect = + prAisBssInfo->ucReasonOfDisconnect; + } + + /* 4 <2> Indication */ + nicMediaStateChange(prAdapter, + prAisBssInfo->ucBssIndex, + &rEventConnStatus); + prAisBssInfo->eConnectionStateIndicated = eConnectionState; + if (eConnectionState == MEDIA_STATE_DISCONNECTED) { + aisRemoveDeauthBlacklist(prAdapter); + prAisFsmInfo->prTargetBssDesc = NULL; + prAisFsmInfo->prTargetStaRec = NULL; + prAisFsmInfo->ucConnTrialCount = 0; + prAdapter->rAddRoamScnChnl.ucChannelListNum = 0; + prRoamingFsmInfo->eReason = ROAMING_REASON_POOR_RCPI; +#if CFG_SUPPORT_NCHO + wlanNchoInit(prAdapter, TRUE); +#endif + } + } else { + DBGLOG(AIS, INFO, + "Postpone the indication of Disconnect for %d seconds\n", + prConnSettings->ucDelayTimeOfDisconnectEvent); + + prAisFsmInfo->u4PostponeIndStartTime = kalGetTimeTick(); + } +} /* end of aisIndicationOfMediaStateToHost() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will indicate an Event of "Media Disconnect" to HOST + * + * @param[in] u4Param Unused timer parameter + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void aisPostponedEventOfDisconnTimeout(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) +{ + struct BSS_INFO *prAisBssInfo; + struct CONNECTION_SETTINGS *prConnSettings; + struct AIS_FSM_INFO *prAisFsmInfo; + bool fgFound = TRUE; + bool fgIsPostponeTimeout; + enum ENUM_PARAM_CONNECTION_POLICY policy; + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + /* firstly, check if we have started postpone indication. + ** otherwise, give a chance to do join before indicate to host + **/ + if (prAisFsmInfo->u4PostponeIndStartTime == 0) + return; + + /* if we're in req channel/join/search state, + * don't report disconnect. + */ + if (prAisFsmInfo->eCurrentState == AIS_STATE_JOIN || + prAisFsmInfo->eCurrentState == AIS_STATE_SEARCH || + prAisFsmInfo->eCurrentState == AIS_STATE_REQ_CHANNEL_JOIN) + return; + + prAisBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + prConnSettings = aisGetConnSettings(prAdapter, ucBssIndex); + fgIsPostponeTimeout = !aisFsmIsInProcessPostpone(prAdapter, ucBssIndex); + policy = prConnSettings->eConnectionPolicy; + + DBGLOG(AIS, EVENT, "policy %d, timeout %d, trial %d, limit %d\n", + policy, fgIsPostponeTimeout, prAisFsmInfo->ucConnTrialCount, + prAisFsmInfo->ucConnTrialCountLimit); + + /* only retry connect once when beacon timeout */ + if (policy != CONNECT_BY_BSSID && !fgIsPostponeTimeout && + !(prAisFsmInfo->ucConnTrialCount > + prAisFsmInfo->ucConnTrialCountLimit)) { + DBGLOG(AIS, INFO, + "DelayTimeOfDisconnect, don't report disconnect\n"); + return; + } + + /* 4 <2> Remove all connection request */ + while (fgFound) + fgFound = aisFsmClearRequest(prAdapter, + AIS_REQUEST_RECONNECT, ucBssIndex); + if (prAisFsmInfo->eCurrentState == AIS_STATE_LOOKING_FOR) + prAisFsmInfo->eCurrentState = AIS_STATE_IDLE; + + /* 4 <3> Indicate Disconnected Event to Host immediately. */ + aisIndicationOfMediaStateToHost(prAdapter, + MEDIA_STATE_DISCONNECTED, FALSE, + ucBssIndex); +} /* end of aisPostponedEventOfDisconnTimeout() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will update the contain of BSS_INFO_T for AIS + * network once the association was completed. + * + * @param[in] prStaRec Pointer to the STA_RECORD_T + * @param[in] prAssocRspSwRfb Pointer to SW RFB of ASSOC RESP FRAME. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void aisUpdateBssInfoForJOIN(IN struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + struct SW_RFB *prAssocRspSwRfb) +{ + struct AIS_FSM_INFO *prAisFsmInfo; + struct BSS_INFO *prAisBssInfo; + struct AIS_SPECIFIC_BSS_INFO *prAisSpecBssInfo; + struct CONNECTION_SETTINGS *prConnSettings; + struct WLAN_ASSOC_RSP_FRAME *prAssocRspFrame; + struct BSS_DESC *prBssDesc; + uint16_t u2IELength; + uint8_t *pucIE; + struct PARAM_SSID rSsid; + uint8_t ucBssIndex = 0; + + DEBUGFUNC("aisUpdateBssInfoForJOIN()"); + + ucBssIndex = prStaRec->ucBssIndex; + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + prAisBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + prConnSettings = aisGetConnSettings(prAdapter, ucBssIndex); + prAisSpecBssInfo = aisGetAisSpecBssInfo(prAdapter, ucBssIndex); + prAssocRspFrame = + (struct WLAN_ASSOC_RSP_FRAME *)prAssocRspSwRfb->pvHeader; + + DBGLOG(AIS, INFO, + "[%d] Update AIS_BSS_INFO_T and apply settings to MAC\n", + ucBssIndex); + + /* 3 <1> Update BSS_INFO_T from AIS_FSM_INFO_T or User Settings */ + /* 4 <1.1> Setup Operation Mode */ + prAisBssInfo->eCurrentOPMode = OP_MODE_INFRASTRUCTURE; + + /* 4 <1.2> Setup SSID */ + COPY_SSID(prAisBssInfo->aucSSID, prAisBssInfo->ucSSIDLen, + prConnSettings->aucSSID, prConnSettings->ucSSIDLen); + + /* 4 <1.3> Setup Channel, Band */ + prAisBssInfo->ucPrimaryChannel = + prAisFsmInfo->prTargetBssDesc->ucChannelNum; + prAisBssInfo->eBand = prAisFsmInfo->prTargetBssDesc->eBand; + + /* 3 <2> Update BSS_INFO_T from STA_RECORD_T */ + /* 4 <2.1> Save current AP's STA_RECORD_T and current AID */ + prAisBssInfo->prStaRecOfAP = prStaRec; + prAisBssInfo->u2AssocId = prStaRec->u2AssocId; + + /* 4 <2.2> Setup Capability */ + /* Use AP's Cap Info as BSS Cap Info */ + prAisBssInfo->u2CapInfo = prStaRec->u2CapInfo; + + if (prAisBssInfo->u2CapInfo & CAP_INFO_SHORT_PREAMBLE) + prAisBssInfo->fgIsShortPreambleAllowed = TRUE; + else + prAisBssInfo->fgIsShortPreambleAllowed = FALSE; + +#if CFG_SUPPORT_TDLS + prAisBssInfo->fgTdlsIsProhibited = prStaRec->fgTdlsIsProhibited; + prAisBssInfo->fgTdlsIsChSwProhibited = prStaRec->fgTdlsIsChSwProhibited; +#endif /* CFG_SUPPORT_TDLS */ + + /* 4 <2.3> Setup PHY Attributes and Basic Rate Set/Operational + * Rate Set + */ + prAisBssInfo->ucPhyTypeSet = prStaRec->ucDesiredPhyTypeSet; + + prAisBssInfo->ucNonHTBasicPhyType = prStaRec->ucNonHTBasicPhyType; + + prAisBssInfo->u2OperationalRateSet = prStaRec->u2OperationalRateSet; + prAisBssInfo->u2BSSBasicRateSet = prStaRec->u2BSSBasicRateSet; + + nicTxUpdateBssDefaultRate(prAisBssInfo); + + /* 3 <3> Update BSS_INFO_T from SW_RFB_T (Association Resp Frame) */ + /* 4 <3.1> Setup BSSID */ + COPY_MAC_ADDR(prAisBssInfo->aucBSSID, prAssocRspFrame->aucBSSID); + + u2IELength = + (uint16_t) ((prAssocRspSwRfb->u2PacketLen - + prAssocRspSwRfb->u2HeaderLen) - + (OFFSET_OF(struct WLAN_ASSOC_RSP_FRAME, aucInfoElem[0]) + - WLAN_MAC_MGMT_HEADER_LEN)); + pucIE = prAssocRspFrame->aucInfoElem; + + /* 4 <3.2> Parse WMM and setup QBSS flag */ + /* Parse WMM related IEs and configure HW CRs accordingly */ + mqmProcessAssocRsp(prAdapter, prAssocRspSwRfb, pucIE, u2IELength); + + prAisBssInfo->fgIsQBSS = prStaRec->fgIsQoS; + + /* 3 <4> Update BSS_INFO_T from BSS_DESC_T */ + prBssDesc = prAisFsmInfo->prTargetBssDesc; + if (prBssDesc) + COPY_SSID(rSsid.aucSsid, rSsid.u4SsidLen, + prBssDesc->aucSSID, prBssDesc->ucSSIDLen); + else + COPY_SSID(rSsid.aucSsid, rSsid.u4SsidLen, + prConnSettings->aucSSID, prConnSettings->ucSSIDLen); + + prBssDesc = + scanSearchBssDescByBssidAndSsid(prAdapter, + prAssocRspFrame->aucBSSID, TRUE, + &rSsid); + if (prBssDesc) { + prBssDesc->fgIsConnecting &= ~BIT(ucBssIndex); + prBssDesc->fgIsConnected |= BIT(ucBssIndex); + + prBssDesc->ucJoinFailureCount = 0; + + aisRemoveBlackList(prAdapter, prBssDesc); + /* 4 <4.1> Setup MIB for current BSS */ + prAisBssInfo->u2BeaconInterval = prBssDesc->u2BeaconInterval; +#if (CFG_SUPPORT_802_11V_MBSSID == 1) + prAisBssInfo->ucMaxBSSIDIndicator = + prBssDesc->ucMaxBSSIDIndicator; + prAisBssInfo->ucMBSSIDIndex = prBssDesc->ucMBSSIDIndex; +#endif + } + + /* NOTE: Defer ucDTIMPeriod updating to when beacon is received + * after connection + */ + prAisBssInfo->ucDTIMPeriod = 0; + prAisBssInfo->fgTIMPresent = TRUE; + prAisBssInfo->u2ATIMWindow = 0; + + prAisBssInfo->ucBeaconTimeoutCount = AIS_BEACON_TIMEOUT_COUNT_INFRA; + +#if CFG_SUPPORT_ROAMING_SKIP_ONE_AP + prAisSpecBssInfo->ucRoamSkipTimes = ROAMING_ONE_AP_SKIP_TIMES; + prAisSpecBssInfo->fgGoodRcpiArea = FALSE; + prAisSpecBssInfo->fgPoorRcpiArea = FALSE; +#endif + + /* 4 <4.2> Update HT information and set channel */ + /* Record HT related parameters in rStaRec and rBssInfo + * Note: it shall be called before nicUpdateBss() + */ + rlmProcessAssocRsp(prAdapter, prAssocRspSwRfb, pucIE, u2IELength); + + secPostUpdateAddr(prAdapter, + aisGetAisBssInfo(prAdapter, ucBssIndex)); + + /* 4 <4.3> Sync with firmware for BSS-INFO */ + nicUpdateBss(prAdapter, ucBssIndex); + + /* 4 <4.4> *DEFER OPERATION* nicPmIndicateBssConnected() + * will be invoked + */ + /* inside scanProcessBeaconAndProbeResp() after 1st beacon + * is received + */ +} /* end of aisUpdateBssInfoForJOIN() */ + +#if CFG_SUPPORT_ADHOC +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will create an Ad-Hoc network and start sending + * Beacon Frames. + * @param (none) + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void aisUpdateBssInfoForCreateIBSS(IN struct ADAPTER *prAdapter, + uint8_t ucBssIndex) +{ + struct AIS_FSM_INFO *prAisFsmInfo; + struct BSS_INFO *prAisBssInfo; + struct CONNECTION_SETTINGS *prConnSettings; + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + prAisBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + prConnSettings = aisGetConnSettings(prAdapter, ucBssIndex); + + if (prAisBssInfo->fgIsBeaconActivated) + return; + + /* 3 <1> Update BSS_INFO_T per Network Basis */ + /* 4 <1.1> Setup Operation Mode */ + prAisBssInfo->eCurrentOPMode = OP_MODE_IBSS; + + /* 4 <1.2> Setup SSID */ + COPY_SSID(prAisBssInfo->aucSSID, prAisBssInfo->ucSSIDLen, + prConnSettings->aucSSID, prConnSettings->ucSSIDLen); + + /* 4 <1.3> Clear current AP's STA_RECORD_T and current AID */ + prAisBssInfo->prStaRecOfAP = (struct STA_RECORD *)NULL; + prAisBssInfo->u2AssocId = 0; + + /* 4 <1.4> Setup Channel, Band and Phy Attributes */ + prAisBssInfo->ucPrimaryChannel = prConnSettings->ucAdHocChannelNum; + prAisBssInfo->eBand = prConnSettings->eAdHocBand; + + if (prAisBssInfo->eBand == BAND_2G4) { + /* Depend on eBand */ + prAisBssInfo->ucPhyTypeSet = + prAdapter-> + rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11BGN; + /* Depend on eCurrentOPMode and ucPhyTypeSet */ + prAisBssInfo->ucConfigAdHocAPMode = AD_HOC_MODE_MIXED_11BG; + } else { + /* Depend on eBand */ + prAisBssInfo->ucPhyTypeSet = + prAdapter-> + rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11ANAC; + /* Depend on eCurrentOPMode and ucPhyTypeSet */ + prAisBssInfo->ucConfigAdHocAPMode = AD_HOC_MODE_11A; + } + + /* 4 <1.5> Setup MIB for current BSS */ + prAisBssInfo->u2BeaconInterval = prConnSettings->u2BeaconPeriod; + prAisBssInfo->ucDTIMPeriod = 0; + prAisBssInfo->u2ATIMWindow = prConnSettings->u2AtimWindow; + + prAisBssInfo->ucBeaconTimeoutCount = AIS_BEACON_TIMEOUT_COUNT_ADHOC; + + if (prConnSettings->eEncStatus == ENUM_ENCRYPTION1_ENABLED || + prConnSettings->eEncStatus == ENUM_ENCRYPTION2_ENABLED || + prConnSettings->eEncStatus == ENUM_ENCRYPTION3_ENABLED) { + prAisBssInfo->fgIsProtection = TRUE; + } else { + prAisBssInfo->fgIsProtection = FALSE; + } + + /* 3 <2> Update BSS_INFO_T common part */ + ibssInitForAdHoc(prAdapter, prAisBssInfo); + /* 4 <2.1> Initialize client list */ + bssInitializeClientList(prAdapter, prAisBssInfo); + + /* 3 <3> Set MAC HW */ + /* 4 <3.1> Setup channel and bandwidth */ + rlmBssInitForAPandIbss(prAdapter, prAisBssInfo); + + /* 4 <3.2> use command packets to inform firmware */ + nicUpdateBss(prAdapter, prAisBssInfo->ucBssIndex); + + /* 4 <3.3> enable beaconing */ + bssUpdateBeaconContent(prAdapter, prAisBssInfo->ucBssIndex); + + /* 4 <3.4> Update AdHoc PM parameter */ + nicPmIndicateBssCreated(prAdapter, prAisBssInfo->ucBssIndex); + + /* 3 <4> Set ACTIVE flag. */ + prAisBssInfo->fgIsBeaconActivated = TRUE; + prAisBssInfo->fgHoldSameBssidForIBSS = TRUE; + + /* 3 <5> Start IBSS Alone Timer */ + cnmTimerStartTimer(prAdapter, &prAisFsmInfo->rIbssAloneTimer, + SEC_TO_MSEC(AIS_IBSS_ALONE_TIMEOUT_SEC)); +} /* end of aisCreateIBSS() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will update the contain of BSS_INFO_T for + * AIS network once the existing IBSS was found. + * + * @param[in] prStaRec Pointer to the STA_RECORD_T + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void aisUpdateBssInfoForMergeIBSS(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec) +{ + struct AIS_FSM_INFO *prAisFsmInfo; + struct BSS_INFO *prAisBssInfo; + struct CONNECTION_SETTINGS *prConnSettings; + struct BSS_DESC *prBssDesc; + uint8_t ucBssIndex = 0; + + ucBssIndex = prStaRec->ucBssIndex; + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + prAisBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + prConnSettings = aisGetConnSettings(prAdapter, ucBssIndex); + + cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rIbssAloneTimer); + + if (!prAisBssInfo->fgIsBeaconActivated) { + + /* 3 <1> Update BSS_INFO_T per Network Basis */ + /* 4 <1.1> Setup Operation Mode */ + prAisBssInfo->eCurrentOPMode = OP_MODE_IBSS; + + /* 4 <1.2> Setup SSID */ + COPY_SSID(prAisBssInfo->aucSSID, + prAisBssInfo->ucSSIDLen, prConnSettings->aucSSID, + prConnSettings->ucSSIDLen); + + /* 4 <1.3> Clear current AP's STA_RECORD_T and current AID */ + prAisBssInfo->prStaRecOfAP = (struct STA_RECORD *)NULL; + prAisBssInfo->u2AssocId = 0; + } + /* 3 <2> Update BSS_INFO_T from STA_RECORD_T */ + /* 4 <2.1> Setup Capability */ + /* Use Peer's Cap Info as IBSS Cap Info */ + prAisBssInfo->u2CapInfo = prStaRec->u2CapInfo; + + if (prAisBssInfo->u2CapInfo & CAP_INFO_SHORT_PREAMBLE) { + prAisBssInfo->fgIsShortPreambleAllowed = TRUE; + prAisBssInfo->fgUseShortPreamble = TRUE; + } else { + prAisBssInfo->fgIsShortPreambleAllowed = FALSE; + prAisBssInfo->fgUseShortPreamble = FALSE; + } + + /* 7.3.1.4 For IBSS, the Short Slot Time subfield shall be set to 0. */ + /* Set to FALSE for AdHoc */ + prAisBssInfo->fgUseShortSlotTime = FALSE; + prAisBssInfo->u2CapInfo &= ~CAP_INFO_SHORT_SLOT_TIME; + + if (prAisBssInfo->u2CapInfo & CAP_INFO_PRIVACY) + prAisBssInfo->fgIsProtection = TRUE; + else + prAisBssInfo->fgIsProtection = FALSE; + + /* 4 <2.2> Setup PHY Attributes and Basic Rate Set/Operational + * Rate Set + */ + prAisBssInfo->ucPhyTypeSet = prStaRec->ucDesiredPhyTypeSet; + + prAisBssInfo->ucNonHTBasicPhyType = prStaRec->ucNonHTBasicPhyType; + + prAisBssInfo->u2OperationalRateSet = prStaRec->u2OperationalRateSet; + prAisBssInfo->u2BSSBasicRateSet = prStaRec->u2BSSBasicRateSet; + + rateGetDataRatesFromRateSet(prAisBssInfo->u2OperationalRateSet, + prAisBssInfo->u2BSSBasicRateSet, + prAisBssInfo->aucAllSupportedRates, + &prAisBssInfo->ucAllSupportedRatesLen); + + /* 3 <3> X Update BSS_INFO_T from SW_RFB_T (Association Resp Frame) */ + + /* 3 <4> Update BSS_INFO_T from BSS_DESC_T */ + prBssDesc = scanSearchBssDescByTA(prAdapter, prStaRec->aucMacAddr); + if (prBssDesc) { + prBssDesc->fgIsConnecting &= ~BIT(ucBssIndex); + prBssDesc->fgIsConnected |= BIT(ucBssIndex); + + /* Support AP Selection */ + aisRemoveBlackList(prAdapter, prBssDesc); + + /* 4 <4.1> Setup BSSID */ + COPY_MAC_ADDR(prAisBssInfo->aucBSSID, prBssDesc->aucBSSID); + + /* 4 <4.2> Setup Channel, Band */ + prAisBssInfo->ucPrimaryChannel = prBssDesc->ucChannelNum; + prAisBssInfo->eBand = prBssDesc->eBand; + + /* 4 <4.3> Setup MIB for current BSS */ + prAisBssInfo->u2BeaconInterval = prBssDesc->u2BeaconInterval; + prAisBssInfo->ucDTIMPeriod = 0; + prAisBssInfo->u2ATIMWindow = 0; /* TBD(Kevin) */ + + prAisBssInfo->ucBeaconTimeoutCount = + AIS_BEACON_TIMEOUT_COUNT_ADHOC; + } + + /* 3 <5> Set MAC HW */ + /* 4 <5.1> Find Lowest Basic Rate Index for default TX Rate of MMPDU */ + nicTxUpdateBssDefaultRate(prAisBssInfo); + + /* 4 <5.2> Setup channel and bandwidth */ + rlmBssInitForAPandIbss(prAdapter, prAisBssInfo); + + /* 4 <5.3> use command packets to inform firmware */ + nicUpdateBss(prAdapter, prAisBssInfo->ucBssIndex); + + /* 4 <5.4> enable beaconing */ + bssUpdateBeaconContent(prAdapter, prAisBssInfo->ucBssIndex); + + /* 4 <5.5> Update AdHoc PM parameter */ + nicPmIndicateBssConnected(prAdapter, + prAisBssInfo->ucBssIndex); + + /* 3 <6> Set ACTIVE flag. */ + prAisBssInfo->fgIsBeaconActivated = TRUE; + prAisBssInfo->fgHoldSameBssidForIBSS = TRUE; +} /* end of aisUpdateBssInfoForMergeIBSS() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will validate the Rx Probe Request Frame and then return + * result to BSS to indicate if need to send the corresponding + * Probe Response Frame if the specified conditions were matched. + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] prSwRfb Pointer to SW RFB data structure. + * @param[out] pu4ControlFlags Control flags for replying the Probe Response + * + * @retval TRUE Reply the Probe Response + * @retval FALSE Don't reply the Probe Response + */ +/*----------------------------------------------------------------------------*/ +u_int8_t aisValidateProbeReq(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, + IN uint8_t ucBssIndex, + OUT uint32_t *pu4ControlFlags) +{ + struct WLAN_MAC_MGMT_HEADER *prMgtHdr; + struct BSS_INFO *prBssInfo; + struct IE_SSID *prIeSsid = (struct IE_SSID *)NULL; + uint8_t *pucIE; + uint16_t u2IELength; + uint16_t u2Offset = 0; + u_int8_t fgReplyProbeResp = FALSE; + + prBssInfo = aisGetAisBssInfo(prAdapter, + ucBssIndex); + + /* 4 <1> Parse Probe Req IE and Get IE ptr + * (SSID, Supported Rate IE, ...) + */ + prMgtHdr = (struct WLAN_MAC_MGMT_HEADER *)prSwRfb->pvHeader; + + u2IELength = prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen; + pucIE = + (uint8_t *) ((unsigned long)prSwRfb->pvHeader + + prSwRfb->u2HeaderLen); + + IE_FOR_EACH(pucIE, u2IELength, u2Offset) { + if (IE_ID(pucIE) == ELEM_ID_SSID) { + if ((!prIeSsid) && (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) + prIeSsid = (struct IE_SSID *)pucIE; + + break; + } + } /* end of IE_FOR_EACH */ + + /* 4 <2> Check network conditions */ + + if (prBssInfo->eCurrentOPMode == OP_MODE_IBSS) { + + if ((prIeSsid) && ((prIeSsid->ucLength == + BC_SSID_LEN) || /* WILDCARD SSID */ + EQUAL_SSID(prBssInfo->aucSSID, + prBssInfo->ucSSIDLen, /* CURRENT SSID */ + prIeSsid->aucSSID, + prIeSsid->ucLength))) { + fgReplyProbeResp = TRUE; + } + } + + return fgReplyProbeResp; + +} /* end of aisValidateProbeReq() */ + +#endif /* CFG_SUPPORT_ADHOC */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will modify and update necessary information to firmware + * for disconnection handling + * + * @param[in] prAdapter Pointer to the Adapter structure. + * + * @retval None + */ +/*----------------------------------------------------------------------------*/ +void aisFsmDisconnect(IN struct ADAPTER *prAdapter, + IN u_int8_t fgDelayIndication, IN uint8_t ucBssIndex) +{ + struct BSS_INFO *prAisBssInfo; + uint16_t u2ReasonCode = REASON_CODE_UNSPECIFIED; + struct BSS_DESC *prBssDesc = NULL; + struct AIS_FSM_INFO *prAisFsmInfo = NULL; + + prAisBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + +#if (CFG_SUPPORT_TWT == 1) + twtPlannerReset(prAdapter, prAisBssInfo); +#endif + +#if CFG_SUPPORT_DETECT_SECURITY_MODE_CHANGE + cnmTimerStopTimer(prAdapter, + aisGetSecModeChangeTimer(prAdapter, ucBssIndex)); +#endif + nicPmIndicateBssAbort(prAdapter, prAisBssInfo->ucBssIndex); + +#if CFG_SUPPORT_ADHOC + if (prAisBssInfo->fgIsBeaconActivated) { + nicUpdateBeaconIETemplate(prAdapter, + IE_UPD_METHOD_DELETE_ALL, + prAisBssInfo->ucBssIndex, + 0, NULL, 0); + + prAisBssInfo->fgIsBeaconActivated = FALSE; + } +#endif + + rlmBssAborted(prAdapter, prAisBssInfo); + + /* 4 <3> Unset the fgIsConnected flag of BSS_DESC_T and send Deauth + * if needed. + */ + if (prAisBssInfo->eConnectionState == MEDIA_STATE_CONNECTED) { + + { + if (prAdapter->rWifiVar.ucTpTestMode != + ENUM_TP_TEST_MODE_NORMAL) + nicEnterTPTestMode(prAdapter, TEST_MODE_NONE); + +#if 0 + if (prAdapter->rWifiVar.ucSigmaTestMode) + nicEnterTPTestMode(prAdapter, TEST_MODE_NONE); +#endif + } + /* for NO TIM IE case */ + if (!prAisBssInfo->fgTIMPresent) { + nicConfigPowerSaveProfile(prAdapter, + prAisBssInfo->ucBssIndex, + Param_PowerModeFast_PSP, + FALSE, PS_CALLER_NO_TIM); + } + + if (prAisBssInfo->prStaRecOfAP) { + u2ReasonCode = + prAisBssInfo->prStaRecOfAP->u2ReasonCode; + } + if (prAisBssInfo->ucReasonOfDisconnect == + DISCONNECT_REASON_CODE_RADIO_LOST || + prAisBssInfo->ucReasonOfDisconnect == + DISCONNECT_REASON_CODE_RADIO_LOST_TX_ERR) { + scanRemoveBssDescByBssid(prAdapter, + prAisBssInfo->aucBSSID); + + /* remove from scanning results as well */ + wlanClearBssInScanningResult(prAdapter, + prAisBssInfo->aucBSSID); + } else { + scanRemoveConnFlagOfBssDescByBssid(prAdapter, + prAisBssInfo->aucBSSID, ucBssIndex); + prBssDesc = aisGetTargetBssDesc(prAdapter, ucBssIndex); + if (prBssDesc) { + prBssDesc->fgIsConnected &= ~BIT(ucBssIndex); + prBssDesc->fgIsConnecting &= ~BIT(ucBssIndex); + } + } + + if (fgDelayIndication) { + struct ROAMING_INFO *roam = + aisGetRoamingInfo(prAdapter, ucBssIndex); + + /* + * There is a chance that roaming failed before + * beacon timeout, so reset trial count here to + * ensure the new reconnection runs correctly. + */ + prAisFsmInfo->ucConnTrialCount = 0; + + switch (prAisBssInfo->ucReasonOfDisconnect) { + case DISCONNECT_REASON_CODE_RADIO_LOST: + roam->eReason = ROAMING_REASON_BEACON_TIMEOUT; + prAisFsmInfo->ucConnTrialCountLimit = 2; + break; + case DISCONNECT_REASON_CODE_RADIO_LOST_TX_ERR: + roam->eReason = ROAMING_REASON_TX_ERR; + prAisFsmInfo->ucConnTrialCountLimit = 2; + break; + case DISCONNECT_REASON_CODE_DEAUTHENTICATED: + case DISCONNECT_REASON_CODE_DISASSOCIATED: + roam->eReason = ROAMING_REASON_SAA_FAIL; + prAisFsmInfo->ucConnTrialCountLimit = 1; + break; + default: + DBGLOG(AIS, ERROR, "wrong reason %d", + prAisBssInfo->ucReasonOfDisconnect); + } + aisFsmClearRequest(prAdapter, + AIS_REQUEST_RECONNECT, ucBssIndex); + aisFsmInsertRequest(prAdapter, + AIS_REQUEST_RECONNECT, ucBssIndex); + + if (prAisBssInfo->eCurrentOPMode != OP_MODE_IBSS) + prAisBssInfo->fgHoldSameBssidForIBSS = FALSE; + } else { + prAisBssInfo->fgHoldSameBssidForIBSS = FALSE; + } + } else { + prAisBssInfo->fgHoldSameBssidForIBSS = FALSE; + } + + /* 4 <4> Change Media State immediately. */ + if (prAisBssInfo->ucReasonOfDisconnect != + DISCONNECT_REASON_CODE_REASSOCIATION) { + aisChangeMediaState(prAisBssInfo, + MEDIA_STATE_DISCONNECTED); + + /* 4 <4.1> sync. with firmware */ + nicUpdateBss(prAdapter, prAisBssInfo->ucBssIndex); + prAisBssInfo->prStaRecOfAP = (struct STA_RECORD *)NULL; + } + +#if CFG_SUPPORT_ROAMING + roamingFsmRunEventAbort(prAdapter, ucBssIndex); + aisFsmRemoveRoamingRequest(prAdapter, ucBssIndex); +#endif /* CFG_SUPPORT_ROAMING */ + + /* 4 <6> Indicate Disconnected Event to Host */ + aisIndicationOfMediaStateToHost(prAdapter, + MEDIA_STATE_DISCONNECTED, + fgDelayIndication, + ucBssIndex); + + /* 4 <7> Trigger AIS FSM */ + aisFsmSteps(prAdapter, AIS_STATE_IDLE, ucBssIndex); +} /* end of aisFsmDisconnect() */ + +static void aisFsmRunEventScanDoneTimeOut(IN struct ADAPTER *prAdapter, + unsigned long ulParam) +{ + struct AIS_FSM_INFO *prAisFsmInfo; + struct CONNECTION_SETTINGS *prConnSettings; + uint8_t ucBssIndex = (uint8_t) ulParam; + + DEBUGFUNC("aisFsmRunEventScanDoneTimeOut()"); + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + prConnSettings = aisGetConnSettings(prAdapter, ucBssIndex); + + DBGLOG(AIS, STATE, + "[%d] aisFsmRunEventScanDoneTimeOut Current[%d] Seq=%u\n", + ucBssIndex, + prAisFsmInfo->eCurrentState, prAisFsmInfo->ucSeqNumOfScanReq); + + prAdapter->u4HifDbgFlag |= DEG_HIF_DEFAULT_DUMP; + kalSetHifDbgEvent(prAdapter->prGlueInfo); + + /* try to stop scan in CONNSYS */ + aisFsmStateAbort_SCAN(prAdapter, ucBssIndex); +} /* end of aisFsmBGSleepTimeout() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will indicate an Event of "Background Scan Time-Out" + * to AIS FSM. + * @param[in] u4Param Unused timer parameter + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void aisFsmRunEventBGSleepTimeOut(IN struct ADAPTER *prAdapter, + unsigned long ulParamPtr) +{ + struct AIS_FSM_INFO *prAisFsmInfo; + enum ENUM_AIS_STATE eNextState; + uint8_t ucBssIndex = (uint8_t) ulParamPtr; + + DEBUGFUNC("aisFsmRunEventBGSleepTimeOut()"); + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + + eNextState = prAisFsmInfo->eCurrentState; + + switch (prAisFsmInfo->eCurrentState) { + case AIS_STATE_WAIT_FOR_NEXT_SCAN: + DBGLOG(AIS, LOUD, + "[%d] EVENT - SCAN TIMER: Idle End - Current Time = %u\n", + ucBssIndex, + kalGetTimeTick()); + + eNextState = AIS_STATE_LOOKING_FOR; + + SET_NET_PWR_STATE_ACTIVE(prAdapter, + ucBssIndex); + + break; + + default: + break; + } + + /* Call aisFsmSteps() when we are going to change AIS STATE */ + if (eNextState != prAisFsmInfo->eCurrentState) + aisFsmSteps(prAdapter, eNextState, ucBssIndex); +} /* end of aisFsmBGSleepTimeout() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will indicate an Event of "IBSS ALONE Time-Out" to + * AIS FSM. + * @param[in] u4Param Unused timer parameter + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void aisFsmRunEventIbssAloneTimeOut(IN struct ADAPTER *prAdapter, + unsigned long ulParamPtr) +{ + struct AIS_FSM_INFO *prAisFsmInfo; + enum ENUM_AIS_STATE eNextState; + uint8_t ucBssIndex = (uint8_t) ulParamPtr; + + DEBUGFUNC("aisFsmRunEventIbssAloneTimeOut()"); + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + eNextState = prAisFsmInfo->eCurrentState; + + switch (prAisFsmInfo->eCurrentState) { + case AIS_STATE_IBSS_ALONE: + + /* There is no one participate in our AdHoc during this + * TIMEOUT Interval so go back to search for a valid + * IBSS again. + */ + + DBGLOG(AIS, LOUD, + "[%d] EVENT-IBSS ALONE TIMER: Start pairing\n", + ucBssIndex); + + /* abort timer */ + aisFsmReleaseCh(prAdapter, ucBssIndex); + + /* Pull back to SEARCH to find candidate again */ + eNextState = AIS_STATE_SEARCH; + + break; + + default: + break; + } + + /* Call aisFsmSteps() when we are going to change AIS STATE */ + if (eNextState != prAisFsmInfo->eCurrentState) + aisFsmSteps(prAdapter, eNextState, ucBssIndex); +} /* end of aisIbssAloneTimeOut() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will indicate an Event of "Join Time-Out" to AIS FSM. + * + * @param[in] u4Param Unused timer parameter + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void aisFsmRunEventJoinTimeout(IN struct ADAPTER *prAdapter, + unsigned long ulParamPtr) +{ + struct BSS_INFO *prAisBssInfo; + struct AIS_FSM_INFO *prAisFsmInfo; + enum ENUM_AIS_STATE eNextState; + OS_SYSTIME rCurrentTime; + uint8_t ucBssIndex = (uint8_t) ulParamPtr; + + DEBUGFUNC("aisFsmRunEventJoinTimeout()"); + + prAisBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + + eNextState = prAisFsmInfo->eCurrentState; + + GET_CURRENT_SYSTIME(&rCurrentTime); + + switch (prAisFsmInfo->eCurrentState) { + case AIS_STATE_JOIN: + DBGLOG(AIS, WARN, "EVENT- JOIN TIMEOUT\n"); + + /* 1. Do abort JOIN */ + aisFsmStateAbort_JOIN(prAdapter, ucBssIndex); + + /* 2. Increase Join Failure Count */ + /* Support AP Selection */ + aisAddBlacklist(prAdapter, prAisFsmInfo->prTargetBssDesc); + prAisFsmInfo->prTargetBssDesc->ucJoinFailureCount++; + + if (prAisFsmInfo->prTargetBssDesc->ucJoinFailureCount < + JOIN_MAX_RETRY_FAILURE_COUNT) { + /* 3.1 Retreat to AIS_STATE_SEARCH state for next try */ + eNextState = AIS_STATE_SEARCH; + } else if (prAisBssInfo->eConnectionState == + MEDIA_STATE_CONNECTED) { + /* roaming cases */ + /* 3.2 Retreat to AIS_STATE_WAIT_FOR_NEXT_SCAN state for + * next try + */ + eNextState = AIS_STATE_WAIT_FOR_NEXT_SCAN; + } else + if (prAisFsmInfo->rJoinReqTime != 0 && !CHECK_FOR_TIMEOUT + (rCurrentTime, prAisFsmInfo->rJoinReqTime, + SEC_TO_SYSTIME(AIS_JOIN_TIMEOUT))) { + /* 3.3 Retreat to AIS_STATE_WAIT_FOR_NEXT_SCAN state + * for next try + */ + eNextState = AIS_STATE_WAIT_FOR_NEXT_SCAN; + } else { + /* 3.4 Retreat to AIS_STATE_JOIN_FAILURE to + * terminate join operation + */ + eNextState = AIS_STATE_JOIN_FAILURE; + } + + break; + + case AIS_STATE_NORMAL_TR: + /* 1. release channel */ + aisFsmReleaseCh(prAdapter, ucBssIndex); + + /* 2. process if there is pending scan */ + if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_SCAN, + TRUE, ucBssIndex) == TRUE) { + wlanClearScanningResult(prAdapter, ucBssIndex); + eNextState = AIS_STATE_ONLINE_SCAN; + } + /* 3. Process for pending roaming scan */ + else if (aisFsmIsRequestPending + (prAdapter, AIS_REQUEST_ROAMING_SEARCH, + TRUE, ucBssIndex) == TRUE) + eNextState = AIS_STATE_LOOKING_FOR; + /* 4. Process for pending roaming scan */ + else if (aisFsmIsRequestPending + (prAdapter, AIS_REQUEST_ROAMING_CONNECT, + TRUE, ucBssIndex) == TRUE) + eNextState = AIS_STATE_SEARCH; + else if (aisFsmIsRequestPending + (prAdapter, AIS_REQUEST_REMAIN_ON_CHANNEL, + TRUE, ucBssIndex) == TRUE) + eNextState = AIS_STATE_REQ_REMAIN_ON_CHANNEL; + +#if CFG_SUPPORT_LOWLATENCY_MODE + /* 5. Check if need to set low latency after connected. */ + wlanConnectedForLowLatency(prAdapter); +#endif + + break; + + default: + /* release channel */ + aisFsmReleaseCh(prAdapter, ucBssIndex); + break; + + } + + /* Call aisFsmSteps() when we are going to change AIS STATE */ + if (eNextState != prAisFsmInfo->eCurrentState) + aisFsmSteps(prAdapter, eNextState, ucBssIndex); +} /* end of aisFsmRunEventJoinTimeout() */ + +void aisFsmRunEventDeauthTimeout(IN struct ADAPTER *prAdapter, + unsigned long ulParamPtr) +{ + uint8_t ucBssIndex = (uint8_t) ulParamPtr; + + aisDeauthXmitCompleteBss(prAdapter, ucBssIndex, TX_RESULT_LIFE_TIMEOUT); +} + +#if CFG_SUPPORT_DETECT_SECURITY_MODE_CHANGE +void aisFsmRunEventSecModeChangeTimeout(IN struct ADAPTER *prAdapter, + unsigned long ulParamPtr) +{ + uint8_t ucBssIndex = (uint8_t) ulParamPtr; + + DBGLOG(AIS, INFO, + "[%d] Beacon security mode change timeout, trigger disconnect!\n", + ucBssIndex); + + aisBssSecurityChanged(prAdapter, ucBssIndex); +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is used to handle OID_802_11_BSSID_LIST_SCAN + * + * \param[in] prAdapter Pointer of ADAPTER_T + * \param[in] prSsid Pointer of SSID_T if specified + * \param[in] pucIe Pointer to buffer of extra information elements + * to be attached + * \param[in] u4IeLength Length of information elements + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void aisFsmScanRequest(IN struct ADAPTER *prAdapter, + IN struct PARAM_SSID *prSsid, IN uint8_t *pucIe, + IN uint32_t u4IeLength, + IN uint8_t ucBssIndex) +{ + struct CONNECTION_SETTINGS *prConnSettings; + struct BSS_INFO *prAisBssInfo; + struct AIS_FSM_INFO *prAisFsmInfo; + struct PARAM_SCAN_REQUEST_ADV *prScanRequest; + + DEBUGFUNC("aisFsmScanRequest()"); + + ASSERT(u4IeLength <= MAX_IE_LENGTH); + + prAisBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + prConnSettings = aisGetConnSettings(prAdapter, ucBssIndex); + prScanRequest = &(prAisFsmInfo->rScanRequest); + + DBGLOG(SCN, TRACE, + "[AIS%d] eCurrentState=%d, fgIsScanReqIssued=%d\n", + ucBssIndex, + prAisFsmInfo->eCurrentState, prConnSettings->fgIsScanReqIssued); + if (!prConnSettings->fgIsScanReqIssued) { + prConnSettings->fgIsScanReqIssued = TRUE; + kalMemZero(prScanRequest, + sizeof(struct PARAM_SCAN_REQUEST_ADV)); + prScanRequest->pucIE = prAisFsmInfo->aucScanIEBuf; + + if (prSsid == NULL) { + prScanRequest->u4SsidNum = 0; + } else { + prScanRequest->u4SsidNum = 1; + + COPY_SSID(prScanRequest->rSsid[0].aucSsid, + prScanRequest->rSsid[0].u4SsidLen, + prSsid->aucSsid, prSsid->u4SsidLen); + } + + if (u4IeLength > 0 && u4IeLength <= MAX_IE_LENGTH) { + prScanRequest->u4IELength = u4IeLength; + kalMemCopy(prScanRequest->pucIE, pucIe, u4IeLength); + } else { + prScanRequest->u4IELength = 0; + } + prScanRequest->ucScanType = SCAN_TYPE_ACTIVE_SCAN; + if (prAisFsmInfo->eCurrentState == AIS_STATE_NORMAL_TR) { + if (prAisBssInfo->eCurrentOPMode == + OP_MODE_INFRASTRUCTURE && + timerPendingTimer(&prAisFsmInfo-> + rJoinTimeoutTimer)) { + /* 802.1x might not finished yet, pend it for + * later handling .. + */ + aisFsmInsertRequest(prAdapter, + AIS_REQUEST_SCAN, + ucBssIndex); + } else { + if (prAisFsmInfo->fgIsChannelGranted == TRUE) { + DBGLOG(SCN, WARN, + "Scan Request with channel granted for join operation: %d, %d", + prAisFsmInfo->fgIsChannelGranted, + prAisFsmInfo->fgIsChannelRequested); + } + + /* start online scan */ + wlanClearScanningResult(prAdapter, ucBssIndex); + aisFsmSteps(prAdapter, AIS_STATE_ONLINE_SCAN, + ucBssIndex); + } + } else if (prAisFsmInfo->eCurrentState == AIS_STATE_IDLE) { + wlanClearScanningResult(prAdapter, ucBssIndex); + aisFsmSteps(prAdapter, AIS_STATE_SCAN, + ucBssIndex); + } else { + aisFsmInsertRequest(prAdapter, AIS_REQUEST_SCAN, + ucBssIndex); + } + } else { + DBGLOG(SCN, WARN, "Scan Request dropped. (state: %d)\n", + prAisFsmInfo->eCurrentState); + } + +} /* end of aisFsmScanRequest() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is used to handle OID_802_11_BSSID_LIST_SCAN + * + * \param[in] prAdapter Pointer of ADAPTER_T + * \param[in] prRequestIn scan request + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void +aisFsmScanRequestAdv(IN struct ADAPTER *prAdapter, + IN struct PARAM_SCAN_REQUEST_ADV *prRequestIn) +{ + struct CONNECTION_SETTINGS *prConnSettings; + struct BSS_INFO *prAisBssInfo; + struct AIS_FSM_INFO *prAisFsmInfo; + struct PARAM_SCAN_REQUEST_ADV *prScanRequest; + struct RADIO_MEASUREMENT_REQ_PARAMS *prRmReq; + uint8_t ucBssIndex = 0; + + DEBUGFUNC("aisFsmScanRequestAdv()"); + + if (!prRequestIn) { + log_dbg(SCN, WARN, "Scan request is NULL\n"); + return; + } + ucBssIndex = prRequestIn->ucBssIndex; + prConnSettings = aisGetConnSettings(prAdapter, ucBssIndex); + prAisBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + prRmReq = aisGetRmReqParam(prAdapter, ucBssIndex); + prScanRequest = &(prAisFsmInfo->rScanRequest); + + DBGLOG(SCN, TRACE, "[AIS%d] eCurrentState=%d, fgIsScanReqIssued=%d\n", + ucBssIndex, + prAisFsmInfo->eCurrentState, prConnSettings->fgIsScanReqIssued); + + if (!prConnSettings->fgIsScanReqIssued) { + prConnSettings->fgIsScanReqIssued = TRUE; + + kalMemCopy(prScanRequest, prRequestIn, + sizeof(struct PARAM_SCAN_REQUEST_ADV)); + prScanRequest->pucIE = prAisFsmInfo->aucScanIEBuf; + + if (prRequestIn->u4IELength > 0 && + prRequestIn->u4IELength <= MAX_IE_LENGTH) { + prScanRequest->u4IELength = prRequestIn->u4IELength; + kalMemCopy(prScanRequest->pucIE, prRequestIn->pucIE, + prScanRequest->u4IELength); + } else { + prScanRequest->u4IELength = 0; + } + + if (prAisFsmInfo->eCurrentState == AIS_STATE_NORMAL_TR) { + if (prAisBssInfo->eCurrentOPMode == + OP_MODE_INFRASTRUCTURE && + timerPendingTimer(&prAisFsmInfo-> + rJoinTimeoutTimer)) { + /* 802.1x might not finished yet, pend it for + * later handling .. + */ + aisFsmInsertRequest(prAdapter, + AIS_REQUEST_SCAN, + ucBssIndex); + } else { + if (prAisFsmInfo->fgIsChannelGranted == TRUE) { + DBGLOG(SCN, WARN, + "Scan Request with channel granted for join operation: %d, %d", + prAisFsmInfo->fgIsChannelGranted, + prAisFsmInfo->fgIsChannelRequested); + } + + /* start online scan */ + wlanClearScanningResult(prAdapter, ucBssIndex); + aisFsmSteps(prAdapter, AIS_STATE_ONLINE_SCAN, + ucBssIndex); + } + } else if (prAisFsmInfo->eCurrentState == AIS_STATE_IDLE) { + wlanClearScanningResult(prAdapter, ucBssIndex); + aisFsmSteps(prAdapter, AIS_STATE_SCAN, + ucBssIndex); + } else { + aisFsmInsertRequest(prAdapter, AIS_REQUEST_SCAN, + ucBssIndex); + } + } else if (prRmReq->rBcnRmParam.eState == + RM_ON_GOING) { + struct NORMAL_SCAN_PARAMS *prNormalScan = + &prRmReq->rBcnRmParam.rNormalScan; + + prNormalScan->fgExist = TRUE; + kalMemCopy(&(prNormalScan->rScanRequest), prRequestIn, + sizeof(struct PARAM_SCAN_REQUEST_ADV)); + prNormalScan->rScanRequest.pucIE = prNormalScan->aucScanIEBuf; + if (prRequestIn->u4IELength > 0 && + prRequestIn->u4IELength <= MAX_IE_LENGTH) { + prNormalScan->rScanRequest.u4IELength = + prRequestIn->u4IELength; + kalMemCopy(prNormalScan->rScanRequest.pucIE, + prRequestIn->pucIE, prRequestIn->u4IELength); + } else { + prNormalScan->rScanRequest.u4IELength = 0; + } + + cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer); + DBGLOG(AIS, INFO, + "BCN REQ: Buffer normal scan while Beacon request is scanning\n"); + } else { + DBGLOG(SCN, WARN, "Scan Request dropped. (state: %d)\n", + prAisFsmInfo->eCurrentState); + } + +} /* end of aisFsmScanRequestAdv() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is invoked when CNM granted channel privilege + * + * \param[in] prAdapter Pointer of ADAPTER_T + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void aisFsmRunEventChGrant(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct BSS_INFO *prAisBssInfo; + struct AIS_FSM_INFO *prAisFsmInfo; + struct AIS_SPECIFIC_BSS_INFO *prAisSpecificBssInfo; + struct CONNECTION_SETTINGS *prConnSettings; + struct MSG_CH_GRANT *prMsgChGrant; + uint8_t ucTokenID; + uint32_t u4GrantInterval; + uint8_t ucBssIndex = 0; + + prMsgChGrant = (struct MSG_CH_GRANT *)prMsgHdr; + + ucTokenID = prMsgChGrant->ucTokenID; + u4GrantInterval = prMsgChGrant->u4GrantInterval; + ucBssIndex = prMsgChGrant->ucBssIndex; + + prAisBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + prAisSpecificBssInfo = + aisGetAisSpecBssInfo(prAdapter, ucBssIndex); + prConnSettings = aisGetConnSettings(prAdapter, ucBssIndex); + +#if CFG_SISO_SW_DEVELOP + /* Driver record granted CH in BSS info */ + prAisBssInfo->fgIsGranted = TRUE; + prAisBssInfo->eBandGranted = prMsgChGrant->eRfBand; + prAisBssInfo->ucPrimaryChannelGranted = prMsgChGrant->ucPrimaryChannel; +#endif + + /* 1. free message */ + cnmMemFree(prAdapter, prMsgHdr); + + if (prAisFsmInfo->eCurrentState == AIS_STATE_REQ_CHANNEL_JOIN + && prAisFsmInfo->ucSeqNumOfChReq == ucTokenID) { + /* 2. channel privilege has been approved */ + prAisFsmInfo->u4ChGrantedInterval = u4GrantInterval; + + /* 3. state transition to join/ibss-alone/ibss-merge */ + /* 3.1 set timeout timer in cases join could not be completed */ + cnmTimerStartTimer(prAdapter, + &prAisFsmInfo->rJoinTimeoutTimer, + prAisFsmInfo->u4ChGrantedInterval - + AIS_JOIN_CH_GRANT_THRESHOLD); + DBGLOG(AIS, INFO, "Start JOIN Timer!"); + aisFsmSteps(prAdapter, AIS_STATE_JOIN, ucBssIndex); + + prAisFsmInfo->fgIsChannelGranted = TRUE; + } else if (prAisFsmInfo->eCurrentState == + AIS_STATE_REQ_REMAIN_ON_CHANNEL + && prAisFsmInfo->ucSeqNumOfChReq == ucTokenID) { + /* 2. channel privilege has been approved */ + prAisFsmInfo->u4ChGrantedInterval = u4GrantInterval; + +#if CFG_SUPPORT_NCHO + if (prAdapter->rNchoInfo.fgNCHOEnabled == TRUE && + prAdapter->rNchoInfo.fgIsSendingAF == TRUE && + prAdapter->rNchoInfo.fgChGranted == FALSE) { + DBGLOG(INIT, TRACE, + "NCHO complete rAisChGrntComp trace time is %u\n", + kalGetTimeTick()); + prAdapter->rNchoInfo.fgChGranted = TRUE; + complete(&prAdapter->prGlueInfo->rAisChGrntComp); + } +#endif + if (prAisFsmInfo->rChReqInfo.eReqType == + CH_REQ_TYPE_OFFCHNL_TX) { + aisFsmSteps(prAdapter, AIS_STATE_OFF_CHNL_TX, + ucBssIndex); + } else { + /* + * 3.1 set timeout timer in cases upper layer + * cancel_remain_on_channel never comes + */ + cnmTimerStartTimer(prAdapter, + &prAisFsmInfo->rChannelTimeoutTimer, + prAisFsmInfo->u4ChGrantedInterval); + + /* 3.2 switch to remain_on_channel state */ + aisFsmSteps(prAdapter, AIS_STATE_REMAIN_ON_CHANNEL, + ucBssIndex); + + /* 3.3. indicate upper layer for channel ready */ + kalReadyOnChannel(prAdapter->prGlueInfo, + prAisFsmInfo->rChReqInfo.u8Cookie, + prAisFsmInfo->rChReqInfo.eBand, + prAisFsmInfo->rChReqInfo.eSco, + prAisFsmInfo->rChReqInfo.ucChannelNum, + prAisFsmInfo->rChReqInfo.u4DurationMs, + ucBssIndex); + } + + prAisFsmInfo->fgIsChannelGranted = TRUE; + } else { /* mismatched grant */ + /* 2. return channel privilege to CNM immediately */ + /* aisFsmReleaseCh(prAdapter, ucBssIndex); */ + DBGLOG(AIS, WARN, "channel grant token mismatch\n"); + } +} /* end of aisFsmRunEventChGrant() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is to inform CNM that channel privilege + * has been released + * + * \param[in] prAdapter Pointer of ADAPTER_T + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void aisFsmReleaseCh(IN struct ADAPTER *prAdapter, IN uint8_t ucBssIndex) +{ + struct AIS_FSM_INFO *prAisFsmInfo; + struct MSG_CH_ABORT *prMsgChAbort; + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + + if (prAisFsmInfo->fgIsChannelGranted == TRUE + || prAisFsmInfo->fgIsChannelRequested == TRUE) { + + prAisFsmInfo->fgIsChannelRequested = FALSE; + prAisFsmInfo->fgIsChannelGranted = FALSE; + + /* 1. return channel privilege to CNM immediately */ + prMsgChAbort = + (struct MSG_CH_ABORT *)cnmMemAlloc(prAdapter, RAM_TYPE_MSG, + sizeof(struct + MSG_CH_ABORT)); + if (!prMsgChAbort) { + DBGLOG(AIS, ERROR, "Can't release Channel to CNM\n"); + return; + } + + prMsgChAbort->rMsgHdr.eMsgId = MID_MNY_CNM_CH_ABORT; + prMsgChAbort->ucBssIndex = ucBssIndex; + prMsgChAbort->ucTokenID = prAisFsmInfo->ucSeqNumOfChReq; +#if CFG_SUPPORT_DBDC + prMsgChAbort->eDBDCBand = ENUM_BAND_AUTO; +#endif /*CFG_SUPPORT_DBDC */ + mboxSendMsg(prAdapter, MBOX_ID_0, + (struct MSG_HDR *)prMsgChAbort, + MSG_SEND_METHOD_BUF); + } +} /* end of aisFsmReleaseCh() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is to inform AIS that corresponding beacon has not + * been received for a while and probing is not successful + * + * \param[in] prAdapter Pointer of ADAPTER_T + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void aisBssBeaconTimeout(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) + +{ + /* trigger by driver, use dummy reason code */ + aisBssBeaconTimeout_impl(prAdapter, BEACON_TIMEOUT_REASON_NUM, + DISCONNECT_REASON_CODE_RADIO_LOST, ucBssIndex); +} + +void aisBssBeaconTimeout_impl(IN struct ADAPTER *prAdapter, + IN uint8_t ucBcnTimeoutReason, IN uint8_t ucDisconnectReason, + IN uint8_t ucBssIndex) +{ + struct BSS_INFO *prAisBssInfo; + u_int8_t fgDoAbortIndication = FALSE; + u_int8_t fgIsReasonPER = + (ucBcnTimeoutReason == BEACON_TIMEOUT_REASON_HIGH_PER); + struct CONNECTION_SETTINGS *prConnSettings; + + prAisBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + prConnSettings = aisGetConnSettings(prAdapter, ucBssIndex); + + /* 4 <1> Diagnose Connection for Beacon Timeout Event */ + if (prAisBssInfo->eConnectionState == MEDIA_STATE_CONNECTED) { + if (prAisBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) { + struct STA_RECORD *prStaRec = + prAisBssInfo->prStaRecOfAP; + + if (prStaRec) + fgDoAbortIndication = TRUE; + + } else if (prAisBssInfo->eCurrentOPMode == OP_MODE_IBSS) { + fgDoAbortIndication = TRUE; + } + } + /* 4 <2> invoke abort handler */ + if (fgDoAbortIndication) { + prAisBssInfo->u2DeauthReason = + REASON_CODE_BEACON_TIMEOUT*100 + + ucBcnTimeoutReason; + + DBGLOG(AIS, EVENT, "aisBssBeaconTimeout\n"); + aisFsmStateAbort(prAdapter, + ucDisconnectReason, + !fgIsReasonPER, + ucBssIndex); + } +} /* end of aisBssBeaconTimeout() */ + +#if CFG_SUPPORT_DETECT_SECURITY_MODE_CHANGE +void aisBssSecurityChanged(struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) +{ + + aisFsmStateAbort(prAdapter, DISCONNECT_REASON_CODE_DEAUTHENTICATED, + FALSE, ucBssIndex); +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is to inform AIS that corresponding beacon has not + * been received for a while and probing is not successful + * + * \param[in] prAdapter Pointer of ADAPTER_T + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void aisBssLinkDown(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) +{ + struct BSS_INFO *prAisBssInfo; + u_int8_t fgDoAbortIndication = FALSE; + struct CONNECTION_SETTINGS *prConnSettings; + + prAisBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + prConnSettings = aisGetConnSettings(prAdapter, ucBssIndex); + + /* 4 <1> Diagnose Connection for Beacon Timeout Event */ + if (prAisBssInfo->eConnectionState == MEDIA_STATE_CONNECTED) { + if (prAisBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) { + struct STA_RECORD *prStaRec = + prAisBssInfo->prStaRecOfAP; + + if (prStaRec) + fgDoAbortIndication = TRUE; + + } else if (prAisBssInfo->eCurrentOPMode == OP_MODE_IBSS) { + fgDoAbortIndication = TRUE; + } + } + /* 4 <2> invoke abort handler */ + if (fgDoAbortIndication) { + DBGLOG(AIS, EVENT, "aisBssLinkDown\n"); + aisFsmStateAbort(prAdapter, + DISCONNECT_REASON_CODE_DISASSOCIATED, FALSE, + ucBssIndex); + } + + /* kalIndicateStatusAndComplete(prAdapter->prGlueInfo, + * WLAN_STATUS_SCAN_COMPLETE, NULL, 0); + */ +} /* end of aisBssLinkDown() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is to inform AIS that DEAUTH frame has been + * sent and thus state machine could go ahead + * + * \param[in] prAdapter Pointer of ADAPTER_T + * \param[in] prMsduInfo Pointer of MSDU_INFO_T for DEAUTH frame + * \param[in] prAdapter Pointer of ADAPTER_T + * + * \return WLAN_STATUS_SUCCESS + */ +/*----------------------------------------------------------------------------*/ +uint32_t +aisDeauthXmitCompleteBss(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN enum ENUM_TX_RESULT_CODE rTxDoneStatus) +{ + struct AIS_FSM_INFO *prAisFsmInfo; + struct BSS_INFO *prAisBssInfo; + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + prAisBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); +#if CFG_SUPPORT_802_11W + /* Notify completion after encrypted deauth frame tx done */ + if (prAisBssInfo->encryptedDeauthIsInProcess == TRUE) { + if (!completion_done(&prAisBssInfo->rDeauthComp)) { + DBGLOG(AIS, EVENT, "Complete rDeauthComp\n"); + complete(&prAisBssInfo->rDeauthComp); + } + } + prAisBssInfo->encryptedDeauthIsInProcess = FALSE; +#endif + if (rTxDoneStatus == TX_RESULT_SUCCESS) + cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rDeauthDoneTimer); + + if (prAisFsmInfo->eCurrentState == AIS_STATE_DISCONNECTING) { + DBGLOG(AIS, EVENT, "aisDeauthXmitComplete\n"); + if (rTxDoneStatus != TX_RESULT_DROPPED_IN_DRIVER + && rTxDoneStatus != TX_RESULT_QUEUE_CLEARANCE) + aisFsmStateAbort(prAdapter, + prAisBssInfo->ucReasonOfDisconnect, + FALSE, ucBssIndex); + } else { + DBGLOG(AIS, WARN, + "DEAUTH frame transmitted without further handling"); + } + + return WLAN_STATUS_SUCCESS; + +} /* end of aisDeauthXmitComplete() */ + +uint32_t +aisDeauthXmitComplete(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN enum ENUM_TX_RESULT_CODE rTxDoneStatus) +{ + return aisDeauthXmitCompleteBss(prAdapter, + prMsduInfo->ucBssIndex, rTxDoneStatus); +} + +#if CFG_SUPPORT_ROAMING +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will indicate an Event of "Looking for a candidate + * due to weak signal" to AIS FSM. + * @param[in] u4ReqScan Requesting Scan or not + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void aisFsmRunEventRoamingDiscovery(IN struct ADAPTER *prAdapter, + uint32_t u4ReqScan, uint8_t ucBssIndex) +{ + struct AIS_FSM_INFO *prAisFsmInfo; + struct CONNECTION_SETTINGS *prConnSettings; + enum ENUM_AIS_REQUEST_TYPE eAisRequest = AIS_REQUEST_NUM; + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + prConnSettings = aisGetConnSettings(prAdapter, ucBssIndex); + + /* search candidates by best rssi */ + prConnSettings->eConnectionPolicy = CONNECT_BY_SSID_BEST_RSSI; + + /* TODO: Stop roaming event in FW */ +#if CFG_SUPPORT_WFD +#if CFG_ENABLE_WIFI_DIRECT + { + /* Check WFD is running */ + struct WFD_CFG_SETTINGS *prWfdCfgSettings = + (struct WFD_CFG_SETTINGS *)NULL; + + prWfdCfgSettings = &(prAdapter->rWifiVar.rWfdConfigureSettings); + if ((prWfdCfgSettings->ucWfdEnable != 0)) { + DBGLOG(ROAMING, INFO, + "WFD is running. Stop roaming.\n"); + roamingFsmRunEventRoam(prAdapter, ucBssIndex); + roamingFsmRunEventFail(prAdapter, + ROAMING_FAIL_REASON_NOCANDIDATE, + ucBssIndex); + return; + } + } +#endif +#endif + + /* results are still new */ + if (!u4ReqScan) { + roamingFsmRunEventRoam(prAdapter, ucBssIndex); + eAisRequest = AIS_REQUEST_ROAMING_CONNECT; + } else { + if (prAisFsmInfo->eCurrentState == AIS_STATE_ONLINE_SCAN + || prAisFsmInfo->eCurrentState == AIS_STATE_LOOKING_FOR) { + eAisRequest = AIS_REQUEST_ROAMING_CONNECT; + } else { + eAisRequest = AIS_REQUEST_ROAMING_SEARCH; + } + } + + if (prAisFsmInfo->eCurrentState == AIS_STATE_NORMAL_TR + && !timerPendingTimer(&prAisFsmInfo->rJoinTimeoutTimer)) { + if (eAisRequest == AIS_REQUEST_ROAMING_SEARCH) { + prAisFsmInfo->fgTargetChnlScanIssued = TRUE; + aisFsmSteps(prAdapter, AIS_STATE_LOOKING_FOR, + ucBssIndex); + } else + aisFsmSteps(prAdapter, AIS_STATE_SEARCH, + ucBssIndex); + } else { + aisFsmRemoveRoamingRequest(prAdapter, ucBssIndex); + aisFsmInsertRequest(prAdapter, eAisRequest, ucBssIndex); + } +} /* end of aisFsmRunEventRoamingDiscovery() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Update the time of ScanDone for roaming and transit to Roam state. + * + * @param (none) + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +enum ENUM_AIS_STATE aisFsmRoamingScanResultsUpdate(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) +{ + struct AIS_FSM_INFO *prAisFsmInfo; + struct ROAMING_INFO *prRoamingFsmInfo; + enum ENUM_AIS_STATE eNextState; + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + prRoamingFsmInfo = + aisGetRoamingInfo(prAdapter, ucBssIndex); + + roamingFsmScanResultsUpdate(prAdapter, ucBssIndex); + + eNextState = prAisFsmInfo->eCurrentState; + if (prRoamingFsmInfo->eCurrentState == ROAMING_STATE_DISCOVERY) { + aisFsmRemoveRoamingRequest(prAdapter, ucBssIndex); + roamingFsmRunEventRoam(prAdapter, ucBssIndex); + eNextState = AIS_STATE_SEARCH; + } else if (prAisFsmInfo->eCurrentState == AIS_STATE_LOOKING_FOR) { + eNextState = AIS_STATE_SEARCH; + } else if (prAisFsmInfo->eCurrentState == AIS_STATE_ONLINE_SCAN) { + eNextState = AIS_STATE_NORMAL_TR; + } + + return eNextState; +} /* end of aisFsmRoamingScanResultsUpdate() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will modify and update necessary information to firmware + * for disconnection of last AP before switching to roaming bss. + * + * @param IN prAdapter Pointer to the Adapter structure. + * prTargetStaRec Target of StaRec of roaming + * + * @retval None + */ +/*----------------------------------------------------------------------------*/ +void aisFsmRoamingDisconnectPrevAP(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prTargetStaRec) +{ + struct BSS_INFO *prAisBssInfo; + uint8_t ucBssIndex = prTargetStaRec->ucBssIndex; + + prAisBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + if (prAisBssInfo->prStaRecOfAP != prTargetStaRec) + wmmNotifyDisconnected(prAdapter, ucBssIndex); + + nicPmIndicateBssAbort(prAdapter, prAisBssInfo->ucBssIndex); + + /* Not invoke rlmBssAborted() here to avoid prAisBssInfo->fg40mBwAllowed + * to be reset. RLM related parameters will be reset again when handling + * association response in rlmProcessAssocRsp(). 20110413 + */ + /* rlmBssAborted(prAdapter, prAisBssInfo); */ + + /* 4 <3> Unset the fgIsConnected flag of BSS_DESC_T and + * send Deauth if needed. + */ + if (prAisBssInfo->eConnectionState == MEDIA_STATE_CONNECTED) { + struct PARAM_SSID rSsid; + struct BSS_DESC *prBssDesc = NULL; + + COPY_SSID(rSsid.aucSsid, rSsid.u4SsidLen, prAisBssInfo->aucSSID, + prAisBssInfo->ucSSIDLen); + prBssDesc = + scanSearchBssDescByBssidAndSsid(prAdapter, + prAisBssInfo->aucBSSID, + TRUE, &rSsid); + if (prBssDesc) { + prBssDesc->fgIsConnected &= ~BIT(ucBssIndex); + prBssDesc->fgIsConnecting &= ~BIT(ucBssIndex); + } + } + + /* 4 <4> Change Media State immediately. */ + aisChangeMediaState(prAisBssInfo, MEDIA_STATE_ROAMING_DISC_PREV); + + /* 4 <4.1> sync. with firmware */ + /* Virtial BSSID */ + prTargetStaRec->ucBssIndex = (prAdapter->ucHwBssIdNum + 1); + nicUpdateBss(prAdapter, prAisBssInfo->ucBssIndex); + + secRemoveBssBcEntry(prAdapter, prAisBssInfo, TRUE); + prTargetStaRec->ucBssIndex = prAisBssInfo->ucBssIndex; + /* before deactivate previous AP, should move its pending MSDUs + ** to the new AP + */ + if (prAisBssInfo->prStaRecOfAP) + if (prAisBssInfo->prStaRecOfAP != prTargetStaRec && + prAisBssInfo->prStaRecOfAP->fgIsInUse) { + qmMoveStaTxQueue(prAisBssInfo->prStaRecOfAP, + prTargetStaRec); + /* Currently, firmware just drop all previous AP's + ** data packets, need to handle waiting tx done + ** status packets so driver no + */ +#if 0 + nicTxHandleRoamingDone(prAdapter, + prAisBssInfo->prStaRecOfAP, + prTargetStaRec); +#endif + cnmStaRecFree(prAdapter, prAisBssInfo->prStaRecOfAP); + } else + DBGLOG(AIS, WARN, "prStaRecOfAP is in use %d\n", + prAisBssInfo->prStaRecOfAP->fgIsInUse); + else + DBGLOG(AIS, WARN, + "NULL pointer of prAisBssInfo->prStaRecOfAP\n"); +} /* end of aisFsmRoamingDisconnectPrevAP() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will update the contain of BSS_INFO_T for AIS + * network once the roaming was completed. + * + * @param IN prAdapter Pointer to the Adapter structure. + * prStaRec StaRec of roaming AP + * prAssocRspSwRfb + * + * @retval None + */ +/*----------------------------------------------------------------------------*/ +void aisUpdateBssInfoForRoamingAP(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, + IN struct SW_RFB *prAssocRspSwRfb) +{ + struct BSS_INFO *prAisBssInfo; + uint8_t ucBssIndex = prStaRec->ucBssIndex; + + prAisBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + + /* 4 <1.1> Change FW's Media State immediately. */ + aisChangeMediaState(prAisBssInfo, MEDIA_STATE_CONNECTED); + + /* 4 <1.2> Deactivate previous AP's STA_RECORD_T in Driver if have. */ + if ((prAisBssInfo->prStaRecOfAP) && + (prAisBssInfo->prStaRecOfAP != prStaRec) + && (prAisBssInfo->prStaRecOfAP->fgIsInUse)) { + /* before deactivate previous AP, should move its pending MSDUs + ** to the new AP + */ + qmMoveStaTxQueue(prAisBssInfo->prStaRecOfAP, prStaRec); + /* cnmStaRecChangeState(prAdapter, prAisBssInfo->prStaRecOfAP, + ** STA_STATE_1); + */ + cnmStaRecFree(prAdapter, prAisBssInfo->prStaRecOfAP); + } + + /* 4 <1.4> Update BSS_INFO_T */ + aisUpdateBssInfoForJOIN(prAdapter, prStaRec, prAssocRspSwRfb); + + /* 4 <1.3> Activate current AP's STA_RECORD_T in Driver. */ + cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); + + /* 4 <1.6> Indicate Connected Event to Host immediately. */ + /* Require BSSID, Association ID, Beacon Interval.. + * from AIS_BSS_INFO_T + */ + aisIndicationOfMediaStateToHost(prAdapter, MEDIA_STATE_CONNECTED, + FALSE, ucBssIndex); +} /* end of aisFsmRoamingUpdateBss() */ + +#endif /* CFG_SUPPORT_ROAMING */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Check if there is any pending request and remove it (optional) + * + * @param prAdapter + * eReqType + * bRemove + * + * @return TRUE + * FALSE + */ +/*----------------------------------------------------------------------------*/ +u_int8_t aisFsmIsRequestPending(IN struct ADAPTER *prAdapter, + IN enum ENUM_AIS_REQUEST_TYPE eReqType, + IN u_int8_t bRemove, + IN uint8_t ucBssIndex) +{ + struct AIS_FSM_INFO *prAisFsmInfo; + struct AIS_REQ_HDR *prPendingReqHdr, *prPendingReqHdrNext; + u_int8_t found = FALSE; + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + + /* traverse through pending request list */ + LINK_FOR_EACH_ENTRY_SAFE(prPendingReqHdr, + prPendingReqHdrNext, + &(prAisFsmInfo->rPendingReqList), rLinkEntry, + struct AIS_REQ_HDR) { + /* check for specified type */ + if (prPendingReqHdr->eReqType == eReqType) { + found = TRUE; + + /* check if need to remove */ + if (bRemove == TRUE) { + LINK_REMOVE_KNOWN_ENTRY(&(prAisFsmInfo-> + rPendingReqList), + &(prPendingReqHdr->rLinkEntry)); + + cnmMemFree(prAdapter, prPendingReqHdr); + DBGLOG(AIS, INFO, "Remove req=%d\n", eReqType); + } else + break; + } + } + + return found; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Clear any pending request + * + * @param prAdapter + * eReqType + * + * @return TRUE + * FALSE + */ +/*----------------------------------------------------------------------------*/ +u_int8_t aisFsmClearRequest(IN struct ADAPTER *prAdapter, + IN enum ENUM_AIS_REQUEST_TYPE eReqType, + IN uint8_t ucBssIndex) +{ + return aisFsmIsRequestPending(prAdapter, eReqType, TRUE, ucBssIndex); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Get next pending request + * + * @param prAdapter + * + * @return P_AIS_REQ_HDR_T + */ +/*----------------------------------------------------------------------------*/ +struct AIS_REQ_HDR *aisFsmGetNextRequest(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) +{ + struct AIS_FSM_INFO *prAisFsmInfo; + struct AIS_REQ_HDR *prPendingReqHdr; + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + + LINK_REMOVE_HEAD(&(prAisFsmInfo->rPendingReqList), prPendingReqHdr, + struct AIS_REQ_HDR *); + + return prPendingReqHdr; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Insert a new request + * + * @param prAdapter + * eReqType + * + * @return TRUE + * FALSE + */ +/*----------------------------------------------------------------------------*/ +u_int8_t aisFsmInsertRequest(IN struct ADAPTER *prAdapter, + IN enum ENUM_AIS_REQUEST_TYPE eReqType, + IN uint8_t ucBssIndex) +{ + struct AIS_REQ_HDR *prAisReq; + struct AIS_FSM_INFO *prAisFsmInfo; + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + + prAisReq = + (struct AIS_REQ_HDR *)cnmMemAlloc(prAdapter, RAM_TYPE_MSG, + sizeof(struct AIS_REQ_HDR)); + + if (!prAisReq) { + DBGLOG(AIS, ERROR, "Can't generate new message\n"); + return FALSE; + } + + prAisReq->eReqType = eReqType; + + /* attach request into pending request list */ + LINK_INSERT_TAIL(&prAisFsmInfo->rPendingReqList, &prAisReq->rLinkEntry); + + DBGLOG(AIS, INFO, "eCurrentState=%d, eReqType=%d, u4NumElem=%d\n", + prAisFsmInfo->eCurrentState, eReqType, + prAisFsmInfo->rPendingReqList.u4NumElem); + + return TRUE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Insert a new request to head + * + * @param prAdapter + * eReqType + * + * @return TRUE + * FALSE + */ +/*----------------------------------------------------------------------------*/ +u_int8_t aisFsmInsertRequestToHead(IN struct ADAPTER *prAdapter, + IN enum ENUM_AIS_REQUEST_TYPE eReqType, + IN uint8_t ucBssIndex) +{ + struct AIS_REQ_HDR *prAisReq; + struct AIS_FSM_INFO *prAisFsmInfo; + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + + prAisReq = + (struct AIS_REQ_HDR *)cnmMemAlloc(prAdapter, RAM_TYPE_MSG, + sizeof(struct AIS_REQ_HDR)); + + if (!prAisReq) { + DBGLOG(AIS, ERROR, "Can't generate new message\n"); + return FALSE; + } + + prAisReq->eReqType = eReqType; + + /* attach request into pending request list */ + LINK_INSERT_HEAD(&prAisFsmInfo->rPendingReqList, &prAisReq->rLinkEntry); + + DBGLOG(AIS, INFO, "eCurrentState=%d, eReqType=%d, u4NumElem=%d\n", + prAisFsmInfo->eCurrentState, eReqType, + prAisFsmInfo->rPendingReqList.u4NumElem); + + return TRUE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Flush all pending requests + * + * @param prAdapter + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void aisFsmFlushRequest(IN struct ADAPTER *prAdapter, IN uint8_t ucBssIndex) +{ + struct AIS_REQ_HDR *prAisReq; + struct AIS_FSM_INFO *prAisFsmInfo; + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + + DBGLOG(AIS, INFO, "aisFsmFlushRequest %d\n", + prAisFsmInfo->rPendingReqList.u4NumElem); + + while ((prAisReq = aisFsmGetNextRequest(prAdapter, ucBssIndex)) != NULL) + cnmMemFree(prAdapter, prAisReq); +} + +void aisFsmRunEventRemainOnChannel(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct MSG_REMAIN_ON_CHANNEL *prRemainOnChannel; + struct AIS_FSM_INFO *prAisFsmInfo; + struct CONNECTION_SETTINGS *prConnSettings; + uint8_t ucBssIndex = 0; + + DEBUGFUNC("aisFsmRunEventRemainOnChannel()"); + + prRemainOnChannel = (struct MSG_REMAIN_ON_CHANNEL *)prMsgHdr; + + ucBssIndex = prRemainOnChannel->ucBssIdx; + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + prConnSettings = aisGetConnSettings(prAdapter, ucBssIndex); + + /* record parameters */ + prAisFsmInfo->rChReqInfo.eBand = prRemainOnChannel->eBand; + prAisFsmInfo->rChReqInfo.eSco = prRemainOnChannel->eSco; + prAisFsmInfo->rChReqInfo.ucChannelNum = prRemainOnChannel->ucChannelNum; + prAisFsmInfo->rChReqInfo.u4DurationMs = prRemainOnChannel->u4DurationMs; + prAisFsmInfo->rChReqInfo.u8Cookie = prRemainOnChannel->u8Cookie; + prAisFsmInfo->rChReqInfo.eReqType = prRemainOnChannel->eReqType; + + if ((prAisFsmInfo->eCurrentState == AIS_STATE_IDLE) || + (prAisFsmInfo->eCurrentState == AIS_STATE_NORMAL_TR + && !timerPendingTimer(&prAisFsmInfo->rJoinTimeoutTimer))) { + /* transit to next state */ + aisFsmSteps(prAdapter, AIS_STATE_REQ_REMAIN_ON_CHANNEL, + ucBssIndex); + } else { + aisFsmInsertRequest(prAdapter, AIS_REQUEST_REMAIN_ON_CHANNEL, + ucBssIndex); + } + + /* free messages */ + cnmMemFree(prAdapter, prMsgHdr); +} + +void aisFsmRunEventCancelRemainOnChannel(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct AIS_FSM_INFO *prAisFsmInfo; + struct BSS_INFO *prAisBssInfo; + struct MSG_CANCEL_REMAIN_ON_CHANNEL *prCancelRemainOnChannel; + u_int8_t rReturn = TRUE; + uint8_t ucBssIndex = 0; + + prCancelRemainOnChannel = + (struct MSG_CANCEL_REMAIN_ON_CHANNEL *)prMsgHdr; + + ucBssIndex = prCancelRemainOnChannel->ucBssIdx; + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + prAisBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + + /* 1. Check the cookie first */ + if (prCancelRemainOnChannel->u8Cookie == + prAisFsmInfo->rChReqInfo.u8Cookie) { + + /* 2. release channel privilege/request */ + if (prAisFsmInfo->eCurrentState == + AIS_STATE_REQ_REMAIN_ON_CHANNEL) { + /* 2.1 elease channel */ + aisFsmReleaseCh(prAdapter, ucBssIndex); + } else if (prAisFsmInfo->eCurrentState == + AIS_STATE_REMAIN_ON_CHANNEL) { + /* 2.1 release channel */ + aisFsmReleaseCh(prAdapter, ucBssIndex); + + /* 2.2 stop channel timeout timer */ + cnmTimerStopTimer(prAdapter, + &prAisFsmInfo->rChannelTimeoutTimer); + } + + /* 3. clear pending request of remain_on_channel */ + rReturn = aisFsmClearRequest(prAdapter, + AIS_REQUEST_REMAIN_ON_CHANNEL, ucBssIndex); + + DBGLOG(AIS, TRACE, + "rReturn of aisFsmIsRequestPending is %d", rReturn); + + /* 4. decide which state to retreat */ + if (prAisFsmInfo->eCurrentState == + AIS_STATE_REQ_REMAIN_ON_CHANNEL + || prAisFsmInfo->eCurrentState == + AIS_STATE_REMAIN_ON_CHANNEL) { + if (prAisBssInfo->eConnectionState == + MEDIA_STATE_CONNECTED) + aisFsmSteps(prAdapter, AIS_STATE_NORMAL_TR, + ucBssIndex); + else + aisFsmSteps(prAdapter, AIS_STATE_IDLE, + ucBssIndex); + } + } + + /* 5. free message */ + cnmMemFree(prAdapter, prMsgHdr); +} + +static u_int8_t +aisFunChnlReqByOffChnl(IN struct ADAPTER *prAdapter, + IN struct AIS_OFF_CHNL_TX_REQ_INFO *prOffChnlTxReq, + IN uint8_t ucBssIndex) +{ + struct MSG_REMAIN_ON_CHANNEL *prMsgChnlReq = + (struct MSG_REMAIN_ON_CHANNEL *) NULL; + + prMsgChnlReq = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, + sizeof(struct MSG_REMAIN_ON_CHANNEL)); + if (prMsgChnlReq == NULL) { + DBGLOG(AIS, ERROR, "channel request buffer allocate fails.\n"); + return FALSE; + } + + prMsgChnlReq->u8Cookie = prOffChnlTxReq->u8Cookie; + prMsgChnlReq->u4DurationMs = prOffChnlTxReq->u4Duration; + prMsgChnlReq->ucChannelNum = prOffChnlTxReq->rChannelInfo.ucChannelNum; + prMsgChnlReq->eBand = prOffChnlTxReq->rChannelInfo.eBand; + prMsgChnlReq->eSco = prOffChnlTxReq->eChnlExt; + prMsgChnlReq->eReqType = CH_REQ_TYPE_OFFCHNL_TX; + + prMsgChnlReq->ucBssIdx = ucBssIndex; + + aisFsmRunEventRemainOnChannel(prAdapter, + (struct MSG_HDR *) prMsgChnlReq); + return TRUE; +} + +static u_int8_t +aisFunAddTxReq2Queue(IN struct ADAPTER *prAdapter, + IN struct AIS_MGMT_TX_REQ_INFO *prMgmtTxReqInfo, + IN struct MSG_MGMT_TX_REQUEST *prMgmtTxMsg, + OUT struct AIS_OFF_CHNL_TX_REQ_INFO **pprOffChnlTxReq) +{ + struct AIS_OFF_CHNL_TX_REQ_INFO *prTmpOffChnlTxReq = + (struct AIS_OFF_CHNL_TX_REQ_INFO *) NULL; + + prTmpOffChnlTxReq = cnmMemAlloc(prAdapter, + RAM_TYPE_MSG, + sizeof(struct AIS_OFF_CHNL_TX_REQ_INFO)); + + if (prTmpOffChnlTxReq == NULL) { + DBGLOG(AIS, ERROR, "Allocate TX request buffer fails.\n"); + return FALSE; + } + + prTmpOffChnlTxReq->u8Cookie = prMgmtTxMsg->u8Cookie; + prTmpOffChnlTxReq->prMgmtTxMsdu = prMgmtTxMsg->prMgmtMsduInfo; + prTmpOffChnlTxReq->fgNoneCckRate = prMgmtTxMsg->fgNoneCckRate; + kalMemCopy(&prTmpOffChnlTxReq->rChannelInfo, + &prMgmtTxMsg->rChannelInfo, + sizeof(struct RF_CHANNEL_INFO)); + prTmpOffChnlTxReq->eChnlExt = prMgmtTxMsg->eChnlExt; + prTmpOffChnlTxReq->fgIsWaitRsp = prMgmtTxMsg->fgIsWaitRsp; + prTmpOffChnlTxReq->u4Duration = prMgmtTxMsg->u4Duration; + + LINK_INSERT_TAIL(&prMgmtTxReqInfo->rTxReqLink, + &prTmpOffChnlTxReq->rLinkEntry); + + *pprOffChnlTxReq = prTmpOffChnlTxReq; + + return TRUE; +} + +static void +aisFunHandleOffchnlTxReq(IN struct ADAPTER *prAdapter, + IN struct AIS_FSM_INFO *prAisFsmInfo, + IN struct MSG_MGMT_TX_REQUEST *prMgmtTxMsg, + IN uint8_t ucBssIndex) +{ + struct AIS_OFF_CHNL_TX_REQ_INFO *prOffChnlTxReq = + (struct AIS_OFF_CHNL_TX_REQ_INFO *) NULL; + struct AIS_MGMT_TX_REQ_INFO *prMgmtTxReqInfo = + (struct AIS_MGMT_TX_REQ_INFO *) NULL; + + prMgmtTxReqInfo = &(prAisFsmInfo->rMgmtTxInfo); + + if (prMgmtTxMsg->u4Duration < MIN_TX_DURATION_TIME_MS) + prMgmtTxMsg->u4Duration = MIN_TX_DURATION_TIME_MS; + + if (aisFunAddTxReq2Queue(prAdapter, prMgmtTxReqInfo, + prMgmtTxMsg, &prOffChnlTxReq) == FALSE) + goto error; + + if (prOffChnlTxReq == NULL) + return; + + switch (prAisFsmInfo->eCurrentState) { + case AIS_STATE_OFF_CHNL_TX: + if (prAisFsmInfo->fgIsChannelGranted && + prAisFsmInfo->rChReqInfo.ucChannelNum == + prMgmtTxMsg->rChannelInfo.ucChannelNum && + prMgmtTxReqInfo->rTxReqLink.u4NumElem == 1) { + aisFsmSteps(prAdapter, AIS_STATE_OFF_CHNL_TX, + ucBssIndex); + } else { + log_dbg(P2P, INFO, "tx ch: %d, current ch: %d, granted: %d, tx link num: %d", + prMgmtTxMsg->rChannelInfo.ucChannelNum, + prAisFsmInfo->rChReqInfo.ucChannelNum, + prAisFsmInfo->fgIsChannelGranted, + prMgmtTxReqInfo->rTxReqLink.u4NumElem); + } + break; + default: + if (!aisFunChnlReqByOffChnl(prAdapter, prOffChnlTxReq, + ucBssIndex)) + goto error; + break; + } + + return; + +error: + LINK_REMOVE_KNOWN_ENTRY( + &(prMgmtTxReqInfo->rTxReqLink), + &prOffChnlTxReq->rLinkEntry); + cnmPktFree(prAdapter, prOffChnlTxReq->prMgmtTxMsdu); + cnmMemFree(prAdapter, prOffChnlTxReq); +} + +static u_int8_t +aisFunNeedOffchnlTx(IN struct ADAPTER *prAdapter, + IN struct MSG_MGMT_TX_REQUEST *prMgmtTxMsg) +{ + struct BSS_INFO *prAisBssInfo = (struct BSS_INFO *) NULL; + struct AIS_FSM_INFO *prAisFsmInfo; + uint8_t ucBssIndex = 0; + + ucBssIndex = prMgmtTxMsg->ucBssIdx; + + prAisBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + + if (!prMgmtTxMsg->fgIsOffChannel) + return FALSE; + + /* tx channel == op channel */ + if (prAisBssInfo->eConnectionState == MEDIA_STATE_CONNECTED && + prAisBssInfo->ucPrimaryChannel == + prMgmtTxMsg->rChannelInfo.ucChannelNum) + return FALSE; + + /* tx channel == roc channel */ + if (prAisFsmInfo->fgIsChannelGranted && + prAisFsmInfo->rChReqInfo.ucChannelNum == + prMgmtTxMsg->rChannelInfo.ucChannelNum) + return FALSE; + + DBGLOG(REQ, INFO, "Use offchannel to TX.\n"); + + return TRUE; +} + +void aisFsmRunEventMgmtFrameTx(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct AIS_FSM_INFO *prAisFsmInfo; + struct MSG_MGMT_TX_REQUEST *prMgmtTxMsg = + (struct MSG_MGMT_TX_REQUEST *) NULL; + uint8_t ucBssIndex = 0; + + if (!prAdapter || !prMsgHdr) + return; + + prMgmtTxMsg = (struct MSG_MGMT_TX_REQUEST *) prMsgHdr; + ucBssIndex = prMgmtTxMsg->ucBssIdx; + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + + if (prAisFsmInfo == NULL) + goto exit; + + if (!aisFunNeedOffchnlTx(prAdapter, prMgmtTxMsg)) + aisFuncTxMgmtFrame(prAdapter, + &prAisFsmInfo->rMgmtTxInfo, + prMgmtTxMsg->prMgmtMsduInfo, + prMgmtTxMsg->u8Cookie, + ucBssIndex); + else + aisFunHandleOffchnlTxReq(prAdapter, + prAisFsmInfo, + prMgmtTxMsg, + ucBssIndex); + +exit: + cnmMemFree(prAdapter, prMsgHdr); +} /* aisFsmRunEventMgmtFrameTx */ + +#if CFG_SUPPORT_NCHO +void aisFsmRunEventNchoActionFrameTx(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct AIS_FSM_INFO *prAisFsmInfo; + struct BSS_INFO *prAisBssInfo = (struct BSS_INFO *)NULL; + struct MSG_MGMT_TX_REQUEST *prMgmtTxMsg = + (struct MSG_MGMT_TX_REQUEST *)NULL; + struct MSDU_INFO *prMgmtFrame = (struct MSDU_INFO *)NULL; + struct _ACTION_VENDOR_SPEC_FRAME_T *prVendorSpec = NULL; + uint8_t *pucFrameBuf = (uint8_t *) NULL; + struct NCHO_INFO *prNchoInfo = NULL; + uint16_t u2PktLen = 0; + uint8_t ucBssIndex = 0; + + do { + prMgmtTxMsg = (struct MSG_MGMT_TX_REQUEST *)prMsgHdr; + + ucBssIndex = prMgmtTxMsg->ucBssIdx; + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + prNchoInfo = &(prAdapter->rNchoInfo); + prAisBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + + if (prAisFsmInfo == NULL) + break; + + u2PktLen = + (uint16_t) OFFSET_OF(struct _ACTION_VENDOR_SPEC_FRAME_T, + aucElemInfo[0]) + + prNchoInfo->rParamActionFrame.i4len + MAC_TX_RESERVED_FIELD; + prMgmtFrame = cnmMgtPktAlloc(prAdapter, u2PktLen); + if (prMgmtFrame == NULL) { + DBGLOG(REQ, ERROR, + "NCHO there is no memory for prMgmtFrame\n"); + break; + } + prMgmtTxMsg->prMgmtMsduInfo = prMgmtFrame; + + pucFrameBuf = + (uint8_t *) ((unsigned long)prMgmtFrame->prPacket + + MAC_TX_RESERVED_FIELD); + prVendorSpec = + (struct _ACTION_VENDOR_SPEC_FRAME_T *)pucFrameBuf; + prVendorSpec->u2FrameCtrl = MAC_FRAME_ACTION; + prVendorSpec->u2Duration = 0; + prVendorSpec->u2SeqCtrl = 0; + COPY_MAC_ADDR(prVendorSpec->aucDestAddr, + prNchoInfo->rParamActionFrame.aucBssid); + COPY_MAC_ADDR(prVendorSpec->aucSrcAddr, + prAisBssInfo->aucOwnMacAddr); + COPY_MAC_ADDR(prVendorSpec->aucBSSID, prAisBssInfo->aucBSSID); + + kalMemCopy(prVendorSpec->aucElemInfo, + prNchoInfo->rParamActionFrame.aucData, + prNchoInfo->rParamActionFrame.i4len); + + prMgmtFrame->u2FrameLength = u2PktLen; + + aisFuncTxMgmtFrame(prAdapter, + &prAisFsmInfo->rMgmtTxInfo, + prMgmtTxMsg->prMgmtMsduInfo, + prMgmtTxMsg->u8Cookie, + ucBssIndex); + + } while (FALSE); + + if (prMsgHdr) + cnmMemFree(prAdapter, prMsgHdr); + +} /* aisFsmRunEventNchoActionFrameTx */ +#endif + +void aisFsmRunEventChannelTimeout(IN struct ADAPTER *prAdapter, + unsigned long ulParamPtr) +{ + struct AIS_FSM_INFO *prAisFsmInfo; + struct BSS_INFO *prAisBssInfo; + uint8_t ucBssIndex = (uint8_t) ulParamPtr; + + DEBUGFUNC("aisFsmRunEventRemainOnChannel()"); + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + prAisBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + + if (prAisFsmInfo->eCurrentState == AIS_STATE_REMAIN_ON_CHANNEL) { + /* 1. release channel */ + aisFsmReleaseCh(prAdapter, ucBssIndex); + + /* 2. stop channel timeout timer */ + cnmTimerStopTimer(prAdapter, + &prAisFsmInfo->rChannelTimeoutTimer); + + /* 3. expiration indication to upper layer */ + kalRemainOnChannelExpired(prAdapter->prGlueInfo, + prAisFsmInfo->rChReqInfo.u8Cookie, + prAisFsmInfo->rChReqInfo.eBand, + prAisFsmInfo->rChReqInfo.eSco, + prAisFsmInfo->rChReqInfo.ucChannelNum, + ucBssIndex); + + /* 4. decide which state to retreat */ + if (prAisBssInfo->eConnectionState == + MEDIA_STATE_CONNECTED) + aisFsmSteps(prAdapter, AIS_STATE_NORMAL_TR, + ucBssIndex); + else + aisFsmSteps(prAdapter, AIS_STATE_IDLE, + ucBssIndex); + + } else if (prAisFsmInfo->eCurrentState == AIS_STATE_OFF_CHNL_TX) { + aisFsmSteps(prAdapter, AIS_STATE_OFF_CHNL_TX, + ucBssIndex); + } else { + DBGLOG(AIS, WARN, + "Unexpected remain_on_channel timeout event\n"); + DBGLOG(AIS, STATE, "CURRENT State: [%s]\n", + aisGetFsmState(prAisFsmInfo->eCurrentState)); + } +} + +uint32_t +aisFsmRunEventMgmtFrameTxDone(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN enum ENUM_TX_RESULT_CODE rTxDoneStatus) +{ + struct AIS_FSM_INFO *prAisFsmInfo; + struct AIS_MGMT_TX_REQ_INFO *prMgmtTxReqInfo = + (struct AIS_MGMT_TX_REQ_INFO *)NULL; + u_int8_t fgIsSuccess = FALSE; + uint64_t *pu8GlCookie = (uint64_t *) NULL; + uint8_t ucBssIndex = 0; + + do { + ucBssIndex = prMsduInfo->ucBssIndex; + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + prMgmtTxReqInfo = &(prAisFsmInfo->rMgmtTxInfo); + pu8GlCookie = + (uint64_t *) ((unsigned long) prMsduInfo->prPacket + + (unsigned long) prMsduInfo->u2FrameLength + + MAC_TX_RESERVED_FIELD); + + if (rTxDoneStatus != TX_RESULT_SUCCESS) { + DBGLOG(AIS, ERROR, "Mgmt Frame TX Fail, Status:%d.\n", + rTxDoneStatus); + } else { + fgIsSuccess = TRUE; + DBGLOG(AIS, INFO, + "Mgmt Frame TX Success, cookie: 0x%llx.\n", + *pu8GlCookie); +#if CFG_SUPPORT_NCHO + if (prAdapter->rNchoInfo.fgNCHOEnabled == TRUE && + prAdapter->rNchoInfo.fgIsSendingAF == TRUE && + prAdapter->rNchoInfo.fgChGranted == TRUE) { + prAdapter->rNchoInfo.fgIsSendingAF = FALSE; + DBGLOG(AIS, TRACE, "NCHO action frame tx done"); + } +#endif + } + + if (prMgmtTxReqInfo->prMgmtTxMsdu == prMsduInfo) { + kalIndicateMgmtTxStatus(prAdapter->prGlueInfo, + prMgmtTxReqInfo->u8Cookie, + fgIsSuccess, + prMsduInfo->prPacket, + (uint32_t) + prMsduInfo->u2FrameLength, + ucBssIndex); + + prMgmtTxReqInfo->prMgmtTxMsdu = NULL; + } + + } while (FALSE); + + return WLAN_STATUS_SUCCESS; + +} /* aisFsmRunEventMgmtFrameTxDone */ + +uint32_t +aisFuncTxMgmtFrame(IN struct ADAPTER *prAdapter, + IN struct AIS_MGMT_TX_REQ_INFO *prMgmtTxReqInfo, + IN struct MSDU_INFO *prMgmtTxMsdu, IN uint64_t u8Cookie, + IN uint8_t ucBssIndex) +{ + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + struct MSDU_INFO *prTxMsduInfo = (struct MSDU_INFO *)NULL; + struct WLAN_MAC_HEADER *prWlanHdr = (struct WLAN_MAC_HEADER *)NULL; + struct STA_RECORD *prStaRec = (struct STA_RECORD *)NULL; + uint32_t ucStaRecIdx = STA_REC_INDEX_NOT_FOUND; + + do { + if (prMgmtTxReqInfo->fgIsMgmtTxRequested) { + + /* 1. prMgmtTxReqInfo->prMgmtTxMsdu != NULL */ + /* Packet on driver, not done yet, drop it. */ + prTxMsduInfo = prMgmtTxReqInfo->prMgmtTxMsdu; + if (prTxMsduInfo != NULL) { + + kalIndicateMgmtTxStatus(prAdapter->prGlueInfo, + prMgmtTxReqInfo->u8Cookie, + FALSE, + prTxMsduInfo->prPacket, + (uint32_t) + prTxMsduInfo->u2FrameLength, + ucBssIndex); + + /* Leave it to TX Done handler. */ + /* cnmMgtPktFree(prAdapter, prTxMsduInfo); */ + prMgmtTxReqInfo->prMgmtTxMsdu = NULL; + } + /* 2. prMgmtTxReqInfo->prMgmtTxMsdu == NULL */ + /* Packet transmitted, wait tx done. (cookie issue) */ + } + + prWlanHdr = + (struct WLAN_MAC_HEADER *)((unsigned long) + prMgmtTxMsdu->prPacket + + MAC_TX_RESERVED_FIELD); + prStaRec = + cnmGetStaRecByAddress(prAdapter, + ucBssIndex, + prWlanHdr->aucAddr1); + + if (IS_BMCAST_MAC_ADDR(prWlanHdr->aucAddr1)) + ucStaRecIdx = STA_REC_INDEX_BMCAST; + + if (prStaRec) + ucStaRecIdx = prStaRec->ucIndex; + + TX_SET_MMPDU(prAdapter, + prMgmtTxMsdu, + (prStaRec != + NULL) ? (prStaRec-> + ucBssIndex) + : (ucBssIndex), + ucStaRecIdx, + WLAN_MAC_MGMT_HEADER_LEN, + prMgmtTxMsdu->u2FrameLength, + aisFsmRunEventMgmtFrameTxDone, + MSDU_RATE_MODE_AUTO); + prMgmtTxReqInfo->u8Cookie = u8Cookie; + prMgmtTxReqInfo->prMgmtTxMsdu = prMgmtTxMsdu; + prMgmtTxReqInfo->fgIsMgmtTxRequested = TRUE; + + + nicTxConfigPktControlFlag(prMgmtTxMsdu, + MSDU_CONTROL_FLAG_FORCE_TX, TRUE); + + /* send to TX queue */ + nicTxEnqueueMsdu(prAdapter, prMgmtTxMsdu); + + } while (FALSE); + + return rWlanStatus; +} /* aisFuncTxMgmtFrame */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will validate the Rx Action Frame and indicate to uppoer + * layer if the specified conditions were matched. + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] prSwRfb Pointer to SW RFB data structure. + * @param[out] pu4ControlFlags Control flags for replying the Probe Response + * + * @retval none + */ +/*----------------------------------------------------------------------------*/ +void aisFuncValidateRxActionFrame(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb) +{ + struct AIS_FSM_INFO *prAisFsmInfo = (struct AIS_FSM_INFO *)NULL; + uint8_t ucBssIndex = 0; + + DEBUGFUNC("aisFuncValidateRxActionFrame"); + + do { + if (prSwRfb->prStaRec) + ucBssIndex = prSwRfb->prStaRec->ucBssIndex; + + prAisFsmInfo + = aisGetAisFsmInfo(prAdapter, ucBssIndex); + + if (1 + /* prAisFsmInfo->u4AisPacketFilter & + * PARAM_PACKET_FILTER_ACTION_FRAME + */ + ) { + /* Leave the action frame to wpa_supplicant. */ + kalIndicateRxMgmtFrame(prAdapter->prGlueInfo, prSwRfb, + ucBssIndex); + } + + } while (FALSE); + + return; + +} /* aisFuncValidateRxActionFrame */ + +/* Support AP Selection */ +void aisRefreshFWKBlacklist(struct ADAPTER *prAdapter) +{ + struct AIS_BLACKLIST_ITEM *prEntry = NULL; + struct LINK *prBlackList = &prAdapter->rWifiVar.rBlackList.rUsingLink; + + DBGLOG(AIS, INFO, + "Refresh all the BSSes' fgIsInFWKBlacklist to FALSE\n"); + + LINK_FOR_EACH_ENTRY(prEntry, prBlackList, rLinkEntry, + struct AIS_BLACKLIST_ITEM) { + prEntry->fgIsInFWKBlacklist = FALSE; + } +} + +struct AIS_BLACKLIST_ITEM *aisAddBlacklist(struct ADAPTER *prAdapter, + struct BSS_DESC *prBssDesc) +{ + struct AIS_BLACKLIST_ITEM *prEntry = NULL; + struct LINK_MGMT *prBlackList = &prAdapter->rWifiVar.rBlackList; + + if (!prBssDesc) { + DBGLOG(AIS, ERROR, "bss descriptor is NULL\n"); + return NULL; + } + if (prBssDesc->prBlack) { + GET_CURRENT_SYSTIME(&prBssDesc->prBlack->rAddTime); + prBssDesc->prBlack->ucCount++; + if (prBssDesc->prBlack->ucCount > 10) + prBssDesc->prBlack->ucCount = 10; + DBGLOG(AIS, INFO, "update blacklist for " MACSTR + ", count %d\n", + MAC2STR(prBssDesc->aucBSSID), + prBssDesc->prBlack->ucCount); + return prBssDesc->prBlack; + } + + prEntry = aisQueryBlackList(prAdapter, prBssDesc); + + if (prEntry) { + GET_CURRENT_SYSTIME(&prEntry->rAddTime); + prBssDesc->prBlack = prEntry; + prEntry->ucCount++; + if (prEntry->ucCount > 10) + prEntry->ucCount = 10; + DBGLOG(AIS, INFO, "update blacklist for " MACSTR + ", count %d\n", + MAC2STR(prBssDesc->aucBSSID), prEntry->ucCount); + return prEntry; + } + LINK_MGMT_GET_ENTRY(prBlackList, prEntry, struct AIS_BLACKLIST_ITEM, + VIR_MEM_TYPE); + if (!prEntry) { + DBGLOG(AIS, WARN, "No memory to allocate\n"); + return NULL; + } + prEntry->ucCount = 1; + /* Support AP Selection */ + prEntry->fgIsInFWKBlacklist = FALSE; + COPY_MAC_ADDR(prEntry->aucBSSID, prBssDesc->aucBSSID); + COPY_SSID(prEntry->aucSSID, prEntry->ucSSIDLen, prBssDesc->aucSSID, + prBssDesc->ucSSIDLen); + GET_CURRENT_SYSTIME(&prEntry->rAddTime); + prBssDesc->prBlack = prEntry; + + DBGLOG(AIS, INFO, "Add " MACSTR " to black List\n", + MAC2STR(prBssDesc->aucBSSID)); + return prEntry; +} + +void aisRemoveBlackList(struct ADAPTER *prAdapter, struct BSS_DESC *prBssDesc) +{ + struct AIS_BLACKLIST_ITEM *prEntry = NULL; + + prEntry = aisQueryBlackList(prAdapter, prBssDesc); + if (!prEntry) + return; + LINK_MGMT_RETURN_ENTRY(&prAdapter->rWifiVar.rBlackList, prEntry); + prBssDesc->prBlack = NULL; + DBGLOG(AIS, INFO, "Remove " MACSTR " from blacklist\n", + MAC2STR(prBssDesc->aucBSSID)); +} + +struct AIS_BLACKLIST_ITEM *aisQueryBlackList(struct ADAPTER *prAdapter, + struct BSS_DESC *prBssDesc) +{ + struct AIS_BLACKLIST_ITEM *prEntry = NULL; + struct LINK *prBlackList = &prAdapter->rWifiVar.rBlackList.rUsingLink; + + if (!prBssDesc) + return NULL; + else if (prBssDesc->prBlack) + return prBssDesc->prBlack; + + LINK_FOR_EACH_ENTRY(prEntry, prBlackList, rLinkEntry, + struct AIS_BLACKLIST_ITEM) { + if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prEntry) && + EQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen, + prEntry->aucSSID, prEntry->ucSSIDLen)) { + prBssDesc->prBlack = prEntry; + return prEntry; + } + } + DBGLOG(AIS, TRACE, MACSTR " is not in blacklist\n", + MAC2STR(prBssDesc->aucBSSID)); + return NULL; +} + +void aisRemoveTimeoutBlacklist(struct ADAPTER *prAdapter) +{ + struct AIS_BLACKLIST_ITEM *prEntry = NULL; + struct AIS_BLACKLIST_ITEM *prNextEntry = NULL; + struct LINK *prBlackList = &prAdapter->rWifiVar.rBlackList.rUsingLink; + OS_SYSTIME rCurrent; + struct BSS_DESC *prBssDesc = NULL; + + GET_CURRENT_SYSTIME(&rCurrent); + + LINK_FOR_EACH_ENTRY_SAFE(prEntry, prNextEntry, prBlackList, rLinkEntry, + struct AIS_BLACKLIST_ITEM) { + if (prEntry->fgIsInFWKBlacklist || + !CHECK_FOR_TIMEOUT(rCurrent, prEntry->rAddTime, + SEC_TO_MSEC(AIS_BLACKLIST_TIMEOUT))) + continue; + prBssDesc = scanSearchBssDescByBssid(prAdapter, + prEntry->aucBSSID); + if (prBssDesc) { + prBssDesc->prBlack = NULL; + prBssDesc->ucJoinFailureCount = 0; + DBGLOG(AIS, INFO, + "Remove Timeout "MACSTR" from blacklist\n", + MAC2STR(prBssDesc->aucBSSID)); + } + LINK_MGMT_RETURN_ENTRY(&prAdapter->rWifiVar.rBlackList, + prEntry); + } +} + +static void aisRemoveDeauthBlacklist(struct ADAPTER *prAdapter) +{ + struct AIS_BLACKLIST_ITEM *prEntry = NULL; + struct AIS_BLACKLIST_ITEM *prNextEntry = NULL; + struct LINK *prBlackList = &prAdapter->rWifiVar.rBlackList.rUsingLink; + struct BSS_DESC *prBssDesc = NULL; + + LINK_FOR_EACH_ENTRY_SAFE(prEntry, prNextEntry, prBlackList, rLinkEntry, + struct AIS_BLACKLIST_ITEM) { + if (prEntry->fgIsInFWKBlacklist || + !prEntry->fgDeauthLastTime) + continue; + + prBssDesc = scanSearchBssDescByBssid(prAdapter, + prEntry->aucBSSID); + if (prBssDesc) { + prBssDesc->prBlack = NULL; + prBssDesc->ucJoinFailureCount = 0; + DBGLOG(AIS, INFO, + "Remove deauth "MACSTR" from blacklist\n", + MAC2STR(prBssDesc->aucBSSID)); + } + LINK_MGMT_RETURN_ENTRY(&prAdapter->rWifiVar.rBlackList, + prEntry); + } +} + +void aisFsmRunEventBssTransition(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct MSG_AIS_BSS_TRANSITION_T *prMsg = + (struct MSG_AIS_BSS_TRANSITION_T *)prMsgHdr; + struct AIS_SPECIFIC_BSS_INFO *prAisSpecificBssInfo; + struct BSS_TRANSITION_MGT_PARAM_T *prBtmParam; + enum WNM_AIS_BSS_TRANSITION eTransType = BSS_TRANSITION_MAX_NUM; + struct BSS_DESC *prBssDesc; + struct ROAMING_INFO *prRoamingFsmInfo = NULL; + u_int8_t fgNeedBtmResponse = FALSE; + uint8_t ucStatus = BSS_TRANSITION_MGT_STATUS_UNSPECIFIED; + uint8_t ucRcvToken = 0; + static uint8_t aucChnlList[MAXIMUM_OPERATION_CHANNEL_LIST]; + uint8_t ucBssIndex = 0; + + if (!prMsg) { + DBGLOG(AIS, WARN, "Msg Header is NULL\n"); + return; + } + + ucBssIndex = prMsg->ucBssIndex; + + prAisSpecificBssInfo = + aisGetAisSpecBssInfo(prAdapter, ucBssIndex); + prBtmParam = + &prAisSpecificBssInfo->rBTMParam; + prBssDesc = + aisGetTargetBssDesc(prAdapter, ucBssIndex); + prRoamingFsmInfo = + aisGetRoamingInfo(prAdapter, ucBssIndex); + eTransType = prMsg->eTransitionType; + fgNeedBtmResponse = prMsg->fgNeedResponse; + ucRcvToken = prMsg->ucToken; + + DBGLOG(AIS, INFO, "Transition Type: %d\n", eTransType); +#if CFG_SUPPORT_802_11K + aisCollectNeighborAP(prAdapter, prMsg->pucCandList, + prMsg->u2CandListLen, prMsg->ucValidityInterval, + ucBssIndex); +#endif + cnmMemFree(prAdapter, prMsgHdr); + /* Solicited BTM request: the case we're waiting btm request + ** after send btm query before roaming scan + */ + if (prBtmParam->ucDialogToken == ucRcvToken) { + prBtmParam->fgPendingResponse = fgNeedBtmResponse; + prBtmParam->fgUnsolicitedReq = FALSE; + + switch (prRoamingFsmInfo->eCurrentState) { + case ROAMING_STATE_REQ_CAND_LIST: + roamingFsmSteps(prAdapter, ROAMING_STATE_DISCOVERY, + ucBssIndex); + return; + case ROAMING_STATE_DISCOVERY: + /* this case need to fall through */ + case ROAMING_STATE_ROAM: + ucStatus = BSS_TRANSITION_MGT_STATUS_UNSPECIFIED; + goto send_response; + default: + /* not solicited btm request, but dialog token matches + ** occasionally. + */ + break; + } + } + prBtmParam->fgUnsolicitedReq = TRUE; + /* Unsolicited BTM request */ + switch (eTransType) { + case BSS_TRANSITION_DISASSOC: + ucStatus = BSS_TRANSITION_MGT_STATUS_ACCEPT; + break; + case BSS_TRANSITION_REQ_ROAMING: + { + struct NEIGHBOR_AP_T *prNeiAP = NULL; + struct LINK *prUsingLink = + &prAisSpecificBssInfo->rNeighborApList.rUsingLink; + uint8_t i = 0; + uint8_t ucChannel = 0; + uint8_t ucChnlCnt = 0; + uint16_t u2LeftTime = 0; + + if (!prBssDesc) { + DBGLOG(AIS, ERROR, "Target Bss Desc is NULL\n"); + break; + } + prBtmParam->fgPendingResponse = fgNeedBtmResponse; + kalMemZero(aucChnlList, sizeof(aucChnlList)); + LINK_FOR_EACH_ENTRY(prNeiAP, prUsingLink, rLinkEntry, + struct NEIGHBOR_AP_T) + { + ucChannel = prNeiAP->ucChannel; + for (i = 0; + i < ucChnlCnt && ucChannel != aucChnlList[i]; i++) + ; + if (i == ucChnlCnt) + ucChnlCnt++; + } + /* reserve 1 second for association */ + u2LeftTime = prBtmParam->u2DisassocTimer * + prBssDesc->u2BeaconInterval - + 1000; + /* check if left time is enough to do partial scan, if not + ** enought, reject directly + */ + if (u2LeftTime < ucChnlCnt * prBssDesc->u2BeaconInterval) { + ucStatus = BSS_TRANSITION_MGT_STATUS_UNSPECIFIED; + goto send_response; + } + roamingFsmSteps(prAdapter, ROAMING_STATE_DISCOVERY, + ucBssIndex); + return; + } + default: + ucStatus = BSS_TRANSITION_MGT_STATUS_ACCEPT; + break; + } +send_response: + if (fgNeedBtmResponse && + aisGetAisBssInfo(prAdapter, ucBssIndex) && + aisGetStaRecOfAP(prAdapter, ucBssIndex)) { + prBtmParam->ucStatusCode = ucStatus; + prBtmParam->ucTermDelay = 0; + kalMemZero(prBtmParam->aucTargetBssid, MAC_ADDR_LEN); + prBtmParam->u2OurNeighborBssLen = 0; + prBtmParam->fgPendingResponse = FALSE; + wnmSendBTMResponseFrame(prAdapter, + aisGetStaRecOfAP(prAdapter, ucBssIndex)); + } +} + +#if CFG_SUPPORT_802_11K +void aisSendNeighborRequest(struct ADAPTER *prAdapter, + uint8_t ucBssIndex) +{ + struct SUB_ELEMENT_LIST *prSSIDIE; + uint8_t aucBuffer[sizeof(*prSSIDIE) + 31]; + struct BSS_INFO *prBssInfo + = aisGetAisBssInfo(prAdapter, ucBssIndex); + + kalMemZero(aucBuffer, sizeof(aucBuffer)); + prSSIDIE = (struct SUB_ELEMENT_LIST *)&aucBuffer[0]; + prSSIDIE->rSubIE.ucSubID = ELEM_ID_SSID; + COPY_SSID(&prSSIDIE->rSubIE.aucOptInfo[0], prSSIDIE->rSubIE.ucLength, + prBssInfo->aucSSID, prBssInfo->ucSSIDLen); + rrmTxNeighborReportRequest(prAdapter, prBssInfo->prStaRecOfAP, + prSSIDIE); +} + +static u_int8_t aisCandPrefIEIsExist(uint8_t *pucSubIe, uint8_t ucLength) +{ + uint16_t u2Offset = 0; + + IE_FOR_EACH(pucSubIe, ucLength, u2Offset) { + if (IE_ID(pucSubIe) == ELEM_ID_NR_BSS_TRANSITION_CAND_PREF) + return TRUE; + } + return FALSE; +} + +static uint8_t aisGetNeighborApPreference(uint8_t *pucSubIe, uint8_t ucLength) +{ + uint16_t u2Offset = 0; + + IE_FOR_EACH(pucSubIe, ucLength, u2Offset) { + if (IE_ID(pucSubIe) == ELEM_ID_NR_BSS_TRANSITION_CAND_PREF) + return pucSubIe[2]; + } + /* If no preference element is presence, give default value(lowest) 0, + */ + /* but it will not be used as a reference. */ + return 0; +} + +static uint64_t aisGetBssTermTsf(uint8_t *pucSubIe, uint8_t ucLength) +{ + uint16_t u2Offset = 0; + + IE_FOR_EACH(pucSubIe, ucLength, u2Offset) { + if (IE_ID(pucSubIe) == ELEM_ID_NR_BSS_TERMINATION_DURATION) + return *(uint64_t *) &pucSubIe[2]; + } + /* If no preference element is presence, give default value(lowest) 0 */ + return 0; +} + +void aisCollectNeighborAP(struct ADAPTER *prAdapter, uint8_t *pucApBuf, + uint16_t u2ApBufLen, uint8_t ucValidInterval, + uint8_t ucBssIndex) +{ + struct NEIGHBOR_AP_T *prNeighborAP = NULL; + struct AIS_SPECIFIC_BSS_INFO *prAisSpecBssInfo = + aisGetAisSpecBssInfo(prAdapter, ucBssIndex); + struct LINK_MGMT *prAPlist = &prAisSpecBssInfo->rNeighborApList; + struct IE_NEIGHBOR_REPORT *prIe = (struct IE_NEIGHBOR_REPORT *)pucApBuf; + int16_t c2BufLen; + uint16_t u2PrefIsZeroCount = 0; + + if (!prIe || !u2ApBufLen || u2ApBufLen < prIe->ucLength) + return; + LINK_MERGE_TO_TAIL(&prAPlist->rFreeLink, &prAPlist->rUsingLink); + for (c2BufLen = u2ApBufLen; c2BufLen > 0; c2BufLen -= IE_SIZE(prIe), + prIe = (struct IE_NEIGHBOR_REPORT *)((uint8_t *) prIe + + IE_SIZE(prIe))) { + /* BIT0-1: AP reachable, BIT2: same security with current + ** setting, + ** BIT3: same authenticator with current AP + */ + if (prIe->ucId != ELEM_ID_NEIGHBOR_REPORT || + (prIe->u4BSSIDInfo & 0x7) != 0x7) + continue; + LINK_MGMT_GET_ENTRY(prAPlist, prNeighborAP, + struct NEIGHBOR_AP_T, VIR_MEM_TYPE); + if (!prNeighborAP) + break; + prNeighborAP->fgHT = !!(prIe->u4BSSIDInfo & BIT(11)); + prNeighborAP->fgFromBtm = !!ucValidInterval; + prNeighborAP->fgRmEnabled = !!(prIe->u4BSSIDInfo & BIT(7)); + prNeighborAP->fgQoS = !!(prIe->u4BSSIDInfo & BIT(5)); + prNeighborAP->fgSameMD = !!(prIe->u4BSSIDInfo & BIT(10)); + prNeighborAP->ucChannel = prIe->ucChnlNumber; + prNeighborAP->fgPrefPresence = aisCandPrefIEIsExist( + prIe->aucSubElem, + IE_SIZE(prIe) - OFFSET_OF(struct IE_NEIGHBOR_REPORT, + aucSubElem)); + prNeighborAP->ucPreference = aisGetNeighborApPreference( + prIe->aucSubElem, + IE_SIZE(prIe) - OFFSET_OF(struct IE_NEIGHBOR_REPORT, + aucSubElem)); + prNeighborAP->u8TermTsf = aisGetBssTermTsf( + prIe->aucSubElem, + IE_SIZE(prIe) - OFFSET_OF(struct IE_NEIGHBOR_REPORT, + aucSubElem)); + COPY_MAC_ADDR(prNeighborAP->aucBssid, prIe->aucBSSID); + DBGLOG(AIS, INFO, + "Bssid" MACSTR + ", PrefPresence %d, Pref %d, Chnl %d, BssidInfo 0x%08x\n", + MAC2STR(prNeighborAP->aucBssid), + prNeighborAP->fgPrefPresence, + prNeighborAP->ucPreference, prIe->ucChnlNumber, + prIe->u4BSSIDInfo); + /* No need to save neighbor ap list with decendant preference + ** for (prTemp = LINK_ENTRY(prAPlist->rUsingLink.prNext, struct + ** NEIGHBOR_AP_T, rLinkEntry); + ** prTemp != prNeighborAP; + ** prTemp = LINK_ENTRY(prTemp->rLinkEntry.prNext, struct + ** NEIGHBOR_AP_T, rLinkEntry)) { + ** if (prTemp->ucPreference < prNeighborAP->ucPreference) { + ** __linkDel(prNeighborAP->rLinkEntry.prPrev, + ** prNeighborAP->rLinkEntry.prNext); + ** __linkAdd(&prNeighborAP->rLinkEntry, + ** prTemp->rLinkEntry.prPrev, &prTemp->rLinkEntry); + ** break; + ** } + ** } + */ + if (prNeighborAP->fgPrefPresence && + prNeighborAP->ucPreference == 0) + u2PrefIsZeroCount++; + + if (c2BufLen < IE_SIZE(prIe)) { + DBGLOG(AIS, WARN, "Truncated neighbor report\n"); + break; + } + } + prAisSpecBssInfo->rNeiApRcvTime = kalGetTimeTick(); + prAisSpecBssInfo->u4NeiApValidInterval = + !ucValidInterval + ? 0xffffffff + : TU_TO_MSEC(ucValidInterval * + aisGetAisBssInfo(prAdapter, ucBssIndex) + ->u2BeaconInterval); + + if (prAPlist->rUsingLink.u4NumElem > 0 && + prAPlist->rUsingLink.u4NumElem == u2PrefIsZeroCount) + DBGLOG(AIS, INFO, + "The number of valid neighbors is equal to the number of perf value is 0.\n"); +} + +void aisResetNeighborApList(IN struct ADAPTER *prAdapter, + uint8_t ucBssIndex) +{ + struct AIS_SPECIFIC_BSS_INFO *prAisSpecBssInfo = + aisGetAisSpecBssInfo(prAdapter, ucBssIndex); + struct LINK_MGMT *prAPlist = &prAisSpecBssInfo->rNeighborApList; + + LINK_MERGE_TO_TAIL(&prAPlist->rFreeLink, &prAPlist->rUsingLink); +} +#endif + +void aisFsmRunEventCancelTxWait(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct AIS_FSM_INFO *prAisFsmInfo = + (struct AIS_FSM_INFO *) NULL; + struct MSG_CANCEL_TX_WAIT_REQUEST *prCancelTxWaitMsg = + (struct MSG_CANCEL_TX_WAIT_REQUEST *) NULL; + struct BSS_INFO *prAisBssInfo = (struct BSS_INFO *) NULL; + struct AIS_MGMT_TX_REQ_INFO *prMgmtTxInfo = + (struct AIS_MGMT_TX_REQ_INFO *) NULL; + struct AIS_OFF_CHNL_TX_REQ_INFO *prOffChnlTxPkt = + (struct AIS_OFF_CHNL_TX_REQ_INFO *) NULL; + u_int8_t fgIsCookieFound = FALSE; + uint8_t ucBssIndex = 0; + + if (prAdapter == NULL || prMsgHdr == NULL) + goto exit; + + prCancelTxWaitMsg = (struct MSG_CANCEL_TX_WAIT_REQUEST *) prMsgHdr; + + ucBssIndex = prCancelTxWaitMsg->ucBssIdx; + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + prAisBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + prMgmtTxInfo = &prAisFsmInfo->rMgmtTxInfo; + + if (prAisFsmInfo == NULL || + prAisBssInfo == NULL || prMgmtTxInfo == NULL) + goto exit; + + LINK_FOR_EACH_ENTRY(prOffChnlTxPkt, + &(prMgmtTxInfo->rTxReqLink), + rLinkEntry, + struct AIS_OFF_CHNL_TX_REQ_INFO) { + if (!prOffChnlTxPkt) + break; + if (prOffChnlTxPkt->u8Cookie == prCancelTxWaitMsg->u8Cookie) { + fgIsCookieFound = TRUE; + break; + } + } + + if (fgIsCookieFound == FALSE && prAisFsmInfo->eCurrentState != + AIS_STATE_OFF_CHNL_TX) + goto exit; + + cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rChannelTimeoutTimer); + aisFunClearAllTxReq(prAdapter, &(prAisFsmInfo->rMgmtTxInfo)); + aisFsmReleaseCh(prAdapter, ucBssIndex); + + if (prAisBssInfo->eConnectionState == + MEDIA_STATE_CONNECTED) + aisFsmSteps(prAdapter, AIS_STATE_NORMAL_TR, ucBssIndex); + else + aisFsmSteps(prAdapter, AIS_STATE_IDLE, ucBssIndex); + +exit: + if (prMsgHdr) + cnmMemFree(prAdapter, prMsgHdr); +} + +static void +aisFunClearAllTxReq(IN struct ADAPTER *prAdapter, + IN struct AIS_MGMT_TX_REQ_INFO *prAisMgmtTxInfo) +{ + struct AIS_OFF_CHNL_TX_REQ_INFO *prOffChnlTxPkt = + (struct AIS_OFF_CHNL_TX_REQ_INFO *) NULL; + + while (!LINK_IS_EMPTY(&(prAisMgmtTxInfo->rTxReqLink))) { + LINK_REMOVE_HEAD(&(prAisMgmtTxInfo->rTxReqLink), + prOffChnlTxPkt, + struct AIS_OFF_CHNL_TX_REQ_INFO *); + if (!prOffChnlTxPkt) + continue; + kalIndicateMgmtTxStatus(prAdapter->prGlueInfo, + prOffChnlTxPkt->u8Cookie, + FALSE, + prOffChnlTxPkt->prMgmtTxMsdu->prPacket, + (uint32_t) prOffChnlTxPkt->prMgmtTxMsdu->u2FrameLength, + prOffChnlTxPkt->prMgmtTxMsdu->ucBssIndex); + cnmPktFree(prAdapter, prOffChnlTxPkt->prMgmtTxMsdu); + cnmMemFree(prAdapter, prOffChnlTxPkt); + } +} + +struct AIS_FSM_INFO *aisGetAisFsmInfo( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) { + + if (!IS_BSS_INDEX_AIS(prAdapter, ucBssIndex)) { + DBGLOG(AIS, LOUD, + "Use default, invalid index = %d\n", ucBssIndex); + ucBssIndex = AIS_DEFAULT_INDEX; + } + + return &(prAdapter->rWifiVar.rAisFsmInfo[ucBssIndex]); +} + +struct AIS_SPECIFIC_BSS_INFO *aisGetAisSpecBssInfo( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) { + + if (!IS_BSS_INDEX_AIS(prAdapter, ucBssIndex)) { + DBGLOG(AIS, LOUD, + "Use default, invalid index = %d\n", ucBssIndex); + ucBssIndex = AIS_DEFAULT_INDEX; + } + + return &(prAdapter->rWifiVar.rAisSpecificBssInfo[ucBssIndex]); +} + +struct BSS_TRANSITION_MGT_PARAM_T * + aisGetBTMParam( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) { + + if (!IS_BSS_INDEX_AIS(prAdapter, ucBssIndex)) { + DBGLOG(AIS, LOUD, + "Use default, invalid index = %d\n", ucBssIndex); + ucBssIndex = AIS_DEFAULT_INDEX; + } + + return &prAdapter->rWifiVar. + rAisSpecificBssInfo[ucBssIndex].rBTMParam; +} + +struct BSS_INFO *aisGetConnectedBssInfo( + IN struct ADAPTER *prAdapter) { + + struct BSS_INFO *prBssInfo; + uint8_t i; + + if (!prAdapter) + return NULL; + + for (i = 0; i < prAdapter->ucHwBssIdNum; i++) { + prBssInfo = prAdapter->aprBssInfo[i]; + + if (prBssInfo && + IS_BSS_AIS(prBssInfo) && + kalGetMediaStateIndicated( + prAdapter->prGlueInfo, + prBssInfo->ucBssIndex) == + MEDIA_STATE_CONNECTED) { + return prBssInfo; + } + } + + return NULL; +} + +struct BSS_INFO *aisGetAisBssInfo( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) { + + if (!IS_BSS_INDEX_AIS(prAdapter, ucBssIndex)) { + DBGLOG(AIS, LOUD, + "Use default, invalid index = %d\n", ucBssIndex); + ucBssIndex = AIS_DEFAULT_INDEX; + } + + return prAdapter->aprBssInfo[ucBssIndex]; +} + +struct STA_RECORD *aisGetStaRecOfAP( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) { + + if (!IS_BSS_INDEX_AIS(prAdapter, ucBssIndex)) { + DBGLOG(AIS, LOUD, + "Use default, invalid index = %d\n", ucBssIndex); + ucBssIndex = AIS_DEFAULT_INDEX; + } + + if (prAdapter->aprBssInfo[ucBssIndex]) + return prAdapter->aprBssInfo[ucBssIndex]->prStaRecOfAP; + + DBGLOG(AIS, WARN, "prStaRecOfAP is Null\n"); + return NULL; +} + +struct BSS_DESC *aisGetTargetBssDesc( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) { + + if (!IS_BSS_INDEX_AIS(prAdapter, ucBssIndex)) { + DBGLOG(AIS, LOUD, + "Use default, invalid index = %d\n", ucBssIndex); + ucBssIndex = AIS_DEFAULT_INDEX; + } + + return prAdapter->rWifiVar + .rAisFsmInfo[ucBssIndex].prTargetBssDesc; +} + +struct STA_RECORD *aisGetTargetStaRec( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) { + + if (!IS_BSS_INDEX_AIS(prAdapter, ucBssIndex)) { + DBGLOG(AIS, LOUD, + "Use default, invalid index = %d\n", ucBssIndex); + ucBssIndex = AIS_DEFAULT_INDEX; + } + + return prAdapter->rWifiVar.rAisFsmInfo[ucBssIndex].prTargetStaRec; +} + +uint8_t aisGetTargetBssDescChannel( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) { + + if (!IS_BSS_INDEX_AIS(prAdapter, ucBssIndex)) { + DBGLOG(AIS, LOUD, + "Use default, invalid index = %d\n", ucBssIndex); + ucBssIndex = AIS_DEFAULT_INDEX; + } + + return prAdapter->rWifiVar + .rAisFsmInfo[ucBssIndex].prTargetBssDesc->ucChannelNum; +} + +#if CFG_SUPPORT_DETECT_SECURITY_MODE_CHANGE +struct TIMER *aisGetSecModeChangeTimer( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) { + + if (!IS_BSS_INDEX_AIS(prAdapter, ucBssIndex)) { + DBGLOG(AIS, LOUD, + "Use default, invalid index = %d\n", ucBssIndex); + ucBssIndex = AIS_DEFAULT_INDEX; + } + + return + &prAdapter->rWifiVar + .rAisFsmInfo[ucBssIndex].rSecModeChangeTimer; +} +#endif + +struct TIMER *aisGetScanDoneTimer( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) { + + if (!IS_BSS_INDEX_AIS(prAdapter, ucBssIndex)) { + DBGLOG(AIS, LOUD, + "Use default, invalid index = %d\n", ucBssIndex); + ucBssIndex = AIS_DEFAULT_INDEX; + } + + return + &prAdapter->rWifiVar + .rAisFsmInfo[ucBssIndex].rScanDoneTimer; +} + +enum ENUM_AIS_STATE aisGetCurrState( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) { + + if (!IS_BSS_INDEX_AIS(prAdapter, ucBssIndex)) { + DBGLOG(AIS, LOUD, + "Use default, invalid index = %d\n", ucBssIndex); + ucBssIndex = AIS_DEFAULT_INDEX; + } + + return + prAdapter->rWifiVar + .rAisFsmInfo[ucBssIndex].eCurrentState; +} + +struct CONNECTION_SETTINGS * + aisGetConnSettings( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) { + + if (!IS_BSS_INDEX_AIS(prAdapter, ucBssIndex)) { + DBGLOG(AIS, LOUD, + "Use default, invalid index = %d\n", ucBssIndex); + ucBssIndex = AIS_DEFAULT_INDEX; + } + + return &(prAdapter->rWifiVar.rConnSettings[ucBssIndex]); +} + +struct GL_WPA_INFO *aisGetWpaInfo( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) { + + if (!IS_BSS_INDEX_AIS(prAdapter, ucBssIndex)) { + DBGLOG(AIS, LOUD, + "Use default, invalid index = %d\n", ucBssIndex); + ucBssIndex = AIS_DEFAULT_INDEX; + } + + return &prAdapter->prGlueInfo->rWpaInfo[ucBssIndex]; +} + +u_int8_t aisGetWapiMode( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) { + + if (!IS_BSS_INDEX_AIS(prAdapter, ucBssIndex)) { + DBGLOG(AIS, LOUD, + "Use default, invalid index = %d\n", ucBssIndex); + ucBssIndex = AIS_DEFAULT_INDEX; + } + + return prAdapter->rWifiVar.rConnSettings[ucBssIndex].fgWapiMode; +} + +enum ENUM_PARAM_AUTH_MODE aisGetAuthMode( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) { + + if (!IS_BSS_INDEX_AIS(prAdapter, ucBssIndex)) { + DBGLOG(AIS, LOUD, + "Use default, invalid index = %d\n", ucBssIndex); + ucBssIndex = AIS_DEFAULT_INDEX; + } + + return prAdapter->rWifiVar.rConnSettings[ucBssIndex].eAuthMode; +} + +enum ENUM_PARAM_OP_MODE aisGetOPMode( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) { + + if (!IS_BSS_INDEX_AIS(prAdapter, ucBssIndex)) { + DBGLOG(AIS, LOUD, + "Use default, invalid index = %d\n", ucBssIndex); + ucBssIndex = AIS_DEFAULT_INDEX; + } + + return prAdapter->rWifiVar.rConnSettings[ucBssIndex].eOPMode; +} + +enum ENUM_WEP_STATUS aisGetEncStatus( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) { + + if (!IS_BSS_INDEX_AIS(prAdapter, ucBssIndex)) { + DBGLOG(AIS, LOUD, + "Use default, invalid index = %d\n", ucBssIndex); + ucBssIndex = AIS_DEFAULT_INDEX; + } + + return prAdapter->rWifiVar.rConnSettings[ucBssIndex].eEncStatus; +} + +struct IEEE_802_11_MIB *aisGetMib( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) { + + if (!IS_BSS_INDEX_AIS(prAdapter, ucBssIndex)) { + DBGLOG(AIS, LOUD, + "Use default, invalid index = %d\n", ucBssIndex); + ucBssIndex = AIS_DEFAULT_INDEX; + } + + return &prAdapter->rMib[ucBssIndex]; +} + +struct ROAMING_INFO *aisGetRoamingInfo( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) { + + if (!IS_BSS_INDEX_AIS(prAdapter, ucBssIndex)) { + DBGLOG(AIS, LOUD, + "Use default, invalid index = %d\n", ucBssIndex); + ucBssIndex = AIS_DEFAULT_INDEX; + } + + return &(prAdapter->rWifiVar.rRoamingInfo[ucBssIndex]); +} + +struct PARAM_BSSID_EX *aisGetCurrBssId( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) { + + if (!IS_BSS_INDEX_AIS(prAdapter, ucBssIndex)) { + DBGLOG(AIS, LOUD, + "Use default, invalid index = %d\n", ucBssIndex); + ucBssIndex = AIS_DEFAULT_INDEX; + } + + return &(prAdapter->rWlanInfo.rCurrBssId[ucBssIndex]); +} + +#if CFG_SUPPORT_PASSPOINT +struct HS20_INFO *aisGetHS20Info( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) { + + if (!IS_BSS_INDEX_AIS(prAdapter, ucBssIndex)) { + DBGLOG(AIS, LOUD, + "Use default, invalid index = %d\n", ucBssIndex); + ucBssIndex = AIS_DEFAULT_INDEX; + } + + return &(prAdapter->rWifiVar.rHS20Info[ucBssIndex]); +} +#endif + +struct RADIO_MEASUREMENT_REQ_PARAMS *aisGetRmReqParam( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) { + + if (!IS_BSS_INDEX_AIS(prAdapter, ucBssIndex)) { + DBGLOG(AIS, LOUD, + "Use default, invalid index = %d\n", ucBssIndex); + ucBssIndex = AIS_DEFAULT_INDEX; + } + + return &(prAdapter->rWifiVar.rRmReqParams[ucBssIndex]); +} + +struct RADIO_MEASUREMENT_REPORT_PARAMS * + aisGetRmReportParam( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) { + + if (!IS_BSS_INDEX_AIS(prAdapter, ucBssIndex)) { + DBGLOG(AIS, LOUD, + "Use default, invalid index = %d\n", ucBssIndex); + ucBssIndex = AIS_DEFAULT_INDEX; + } + + return &(prAdapter->rWifiVar.rRmRepParams[ucBssIndex]); +} + +struct WMM_INFO * + aisGetWMMInfo( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) { + + if (!IS_BSS_INDEX_AIS(prAdapter, ucBssIndex)) { + DBGLOG(AIS, LOUD, + "Use default, invalid index = %d\n", ucBssIndex); + ucBssIndex = AIS_DEFAULT_INDEX; + } + + return &(prAdapter->rWifiVar.rWmmInfo[ucBssIndex]); +} + +#ifdef CFG_SUPPORT_REPLAY_DETECTION +struct GL_DETECT_REPLAY_INFO * + aisGetDetRplyInfo( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) { + + if (!IS_BSS_INDEX_AIS(prAdapter, ucBssIndex)) { + DBGLOG(AIS, LOUD, + "Use default, invalid index = %d\n", ucBssIndex); + ucBssIndex = AIS_DEFAULT_INDEX; + } + + return &(prAdapter->prGlueInfo->prDetRplyInfo[ucBssIndex]); +} +#endif + +struct FT_IES * + aisGetFtIe( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) { + + if (!IS_BSS_INDEX_AIS(prAdapter, ucBssIndex)) { + DBGLOG(AIS, LOUD, + "Use default, invalid index = %d\n", ucBssIndex); + ucBssIndex = AIS_DEFAULT_INDEX; + } + + return &(prAdapter->rWifiVar.rConnSettings[ucBssIndex].rFtIeForTx); +} + +struct cfg80211_ft_event_params * + aisGetFtEventParam( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) { + + if (!IS_BSS_INDEX_AIS(prAdapter, ucBssIndex)) { + DBGLOG(AIS, LOUD, + "Use default, invalid index = %d\n", ucBssIndex); + ucBssIndex = AIS_DEFAULT_INDEX; + } + + return &(prAdapter->rWifiVar.rConnSettings[ucBssIndex].rFtEventParam); +} + +uint8_t * + aisGetFsmState( + IN enum ENUM_AIS_STATE eCurrentState) { + if (eCurrentState >= 0 && eCurrentState < AIS_STATE_NUM) + return apucDebugAisState[eCurrentState]; + + ASSERT(0); + return (uint8_t *) NULL; +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/ap_selection.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/ap_selection.c new file mode 100644 index 0000000000000000000000000000000000000000..e96e403262a48613a0f22ae6eb8ddad274d0759f --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/ap_selection.c @@ -0,0 +1,1379 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ + +#include "precomp.h" + +/* + * definition for AP selection algrithm + */ +#define BSS_FULL_SCORE (100) +#define CHNL_BSS_NUM_THRESOLD 100 +#define BSS_STA_CNT_THRESOLD 30 +#define SCORE_PER_AP 1 +#define ROAMING_NO_SWING_SCORE_STEP 100 +/* MCS9 at BW 160 requires rssi at least -48dbm */ +#define BEST_RSSI -48 +/* MCS7 at 20BW, MCS5 at 40BW, MCS4 at 80BW, MCS3 at 160BW */ +#define GOOD_RSSI_FOR_HT_VHT -64 +/* Link speed 1Mbps need at least rssi -94dbm for 2.4G */ +#define MINIMUM_RSSI_2G4 -94 +/* Link speed 6Mbps need at least rssi -86dbm for 5G */ +#define MINIMUM_RSSI_5G -86 + +/* level of rssi range on StatusBar */ +#define RSSI_MAX_LEVEL -55 +#define RSSI_SECOND_LEVEL -66 + +#if CFG_TC10_FEATURE +#define RCPI_FOR_DONT_ROAM 80 /*-70dbm*/ +#else +#define RCPI_FOR_DONT_ROAM 60 /*-80dbm*/ +#endif + +/* Real Rssi of a Bss may range in current_rssi - 5 dbm + *to current_rssi + 5 dbm + */ +#define RSSI_DIFF_BETWEEN_BSS 10 /* dbm */ +#define LOW_RSSI_FOR_5G_BAND -70 /* dbm */ +#define HIGH_RSSI_FOR_5G_BAND -60 /* dbm */ + +/* Support driver triggers roaming */ +#define RCPI_DIFF_DRIVER_ROAM 20 /* 10 dbm */ + +/* In case 2.4G->5G, the trigger rssi is RSSI_BAD_NEED_ROAM_24G_TO_5G + * In other case(2.4G->2.4G/5G->2.4G/5G->5G), the trigger + * rssi is RSSI_BAD_NEED_ROAM + * + * The reason of using two rssi threshold is that we only + * want to benifit 2.4G->5G case, and keep original logic in + * other cases. + */ +#define RSSI_BAD_NEED_ROAM_24G_TO_5G -40 /* dbm */ +#define RSSI_BAD_NEED_ROAM -80 /* dbm */ + +#define CHNL_DWELL_TIME_DEFAULT 100 +#define CHNL_DWELL_TIME_ONLINE 50 + +/* When roam to 5G AP, the AP's rcpi should great than + * RCPI_THRESHOLD_ROAM_2_5G dbm + */ +#define RCPI_THRESHOLD_ROAM_TO_5G 90 /* rssi -65 */ + +#define WEIGHT_IDX_CHNL_UTIL 0 +#define WEIGHT_IDX_RSSI 2 +#define WEIGHT_IDX_SCN_MISS_CNT 2 +#define WEIGHT_IDX_PROBE_RSP 1 +#define WEIGHT_IDX_CLIENT_CNT 0 +#define WEIGHT_IDX_AP_NUM 0 +#define WEIGHT_IDX_5G_BAND 2 +#define WEIGHT_IDX_BAND_WIDTH 1 +#define WEIGHT_IDX_STBC 1 +#define WEIGHT_IDX_DEAUTH_LAST 1 +#define WEIGHT_IDX_BLACK_LIST 2 +#define WEIGHT_IDX_SAA 0 +#define WEIGHT_IDX_CHNL_IDLE 0 +#define WEIGHT_IDX_OPCHNL 0 + +#define WEIGHT_IDX_CHNL_UTIL_PER 0 +#define WEIGHT_IDX_RSSI_PER 4 +#define WEIGHT_IDX_SCN_MISS_CNT_PER 4 +#define WEIGHT_IDX_PROBE_RSP_PER 1 +#define WEIGHT_IDX_CLIENT_CNT_PER 1 +#define WEIGHT_IDX_AP_NUM_PER 6 +#define WEIGHT_IDX_5G_BAND_PER 4 +#define WEIGHT_IDX_BAND_WIDTH_PER 1 +#define WEIGHT_IDX_STBC_PER 1 +#define WEIGHT_IDX_DEAUTH_LAST_PER 1 +#define WEIGHT_IDX_BLACK_LIST_PER 4 +#define WEIGHT_IDX_SAA_PER 1 +#define WEIGHT_IDX_CHNL_IDLE_PER 6 +#define WEIGHT_IDX_OPCHNL_PER 6 + +struct WEIGHT_CONFIG { + uint8_t ucChnlUtilWeight; + uint8_t ucSnrWeight; + uint8_t ucRssiWeight; + uint8_t ucScanMissCntWeight; + uint8_t ucProbeRespWeight; + uint8_t ucClientCntWeight; + uint8_t ucApNumWeight; + uint8_t ucBandWeight; + uint8_t ucBandWidthWeight; + uint8_t ucStbcWeight; + uint8_t ucLastDeauthWeight; + uint8_t ucBlackListWeight; + uint8_t ucSaaWeight; + uint8_t ucChnlIdleWeight; + uint8_t ucOpchnlWeight; +}; + +struct WEIGHT_CONFIG gasMtkWeightConfig[ROAM_TYPE_NUM] = { + [ROAM_TYPE_RCPI] = { + .ucChnlUtilWeight = WEIGHT_IDX_CHNL_UTIL, + .ucRssiWeight = WEIGHT_IDX_RSSI, + .ucScanMissCntWeight = WEIGHT_IDX_SCN_MISS_CNT, + .ucProbeRespWeight = WEIGHT_IDX_PROBE_RSP, + .ucClientCntWeight = WEIGHT_IDX_CLIENT_CNT, + .ucApNumWeight = WEIGHT_IDX_AP_NUM, + .ucBandWeight = WEIGHT_IDX_5G_BAND, + .ucBandWidthWeight = WEIGHT_IDX_BAND_WIDTH, + .ucStbcWeight = WEIGHT_IDX_STBC, + .ucLastDeauthWeight = WEIGHT_IDX_DEAUTH_LAST, + .ucBlackListWeight = WEIGHT_IDX_BLACK_LIST, + .ucSaaWeight = WEIGHT_IDX_SAA, + .ucChnlIdleWeight = WEIGHT_IDX_CHNL_IDLE, + .ucOpchnlWeight = WEIGHT_IDX_OPCHNL + }, + [ROAM_TYPE_PER] = { + .ucChnlUtilWeight = WEIGHT_IDX_CHNL_UTIL_PER, + .ucRssiWeight = WEIGHT_IDX_RSSI_PER, + .ucScanMissCntWeight = WEIGHT_IDX_SCN_MISS_CNT_PER, + .ucProbeRespWeight = WEIGHT_IDX_PROBE_RSP_PER, + .ucClientCntWeight = WEIGHT_IDX_CLIENT_CNT_PER, + .ucApNumWeight = WEIGHT_IDX_AP_NUM_PER, + .ucBandWeight = WEIGHT_IDX_5G_BAND_PER, + .ucBandWidthWeight = WEIGHT_IDX_BAND_WIDTH_PER, + .ucStbcWeight = WEIGHT_IDX_STBC_PER, + .ucLastDeauthWeight = WEIGHT_IDX_DEAUTH_LAST_PER, + .ucBlackListWeight = WEIGHT_IDX_BLACK_LIST_PER, + .ucSaaWeight = WEIGHT_IDX_SAA_PER, + .ucChnlIdleWeight = WEIGHT_IDX_CHNL_IDLE_PER, + .ucOpchnlWeight = WEIGHT_IDX_OPCHNL_PER + } +}; + +uint8_t mtk_reason_to_type[ROAMING_REASON_NUM] = { + [0 ... ROAMING_REASON_NUM - 1] = ROAM_TYPE_RCPI, + [ROAMING_REASON_TX_ERR] = ROAM_TYPE_PER, +}; + +#if (CFG_SUPPORT_802_11AX == 1) +#define CALCULATE_SCORE_BY_AX_AP(prAdapter, prBssDesc, eRoamType) \ + ((eRoamType == ROAM_TYPE_PER) ? \ + ((prAdapter->rWifiVar).ucApSelAxWeight * \ + (prBssDesc->fgIsHEPresent ? \ + (BSS_FULL_SCORE/(prAdapter->rWifiVar).ucApSelAxScoreDiv) : 0)):0) +#endif + +#define CALCULATE_SCORE_BY_PROBE_RSP(prBssDesc, eRoamType) \ + (gasMtkWeightConfig[eRoamType].ucProbeRespWeight * \ + (prBssDesc->fgSeenProbeResp ? BSS_FULL_SCORE : 0)) + +#define CALCULATE_SCORE_BY_MISS_CNT(prAdapter, prBssDesc, eRoamType) \ + (gasMtkWeightConfig[eRoamType].ucScanMissCntWeight * \ + (prAdapter->rWifiVar.rScanInfo.u4ScanUpdateIdx - \ + prBssDesc->u4UpdateIdx > 3 ? 0 : \ + (BSS_FULL_SCORE - (prAdapter->rWifiVar.rScanInfo.u4ScanUpdateIdx - \ + prBssDesc->u4UpdateIdx) * 25))) + +#define CALCULATE_SCORE_BY_BAND(prAdapter, prBssDesc, cRssi, eRoamType) \ + (gasMtkWeightConfig[eRoamType].ucBandWeight * \ + ((prBssDesc->eBand == BAND_5G && prAdapter->fgEnable5GBand && \ + cRssi > -70) ? BSS_FULL_SCORE : 0)) + +#define CALCULATE_SCORE_BY_STBC(prAdapter, prBssDesc, eRoamType) \ + (gasMtkWeightConfig[eRoamType].ucStbcWeight * \ + (prBssDesc->fgMultiAnttenaAndSTBC ? BSS_FULL_SCORE:0)) + +#define CALCULATE_SCORE_BY_DEAUTH(prBssDesc, eRoamType) \ + (gasMtkWeightConfig[eRoamType].ucLastDeauthWeight * \ + (prBssDesc->prBlack && prBssDesc->prBlack->fgDeauthLastTime ? 0 : \ + BSS_FULL_SCORE)) + +#if CFG_SUPPORT_RSN_SCORE +#define CALCULATE_SCORE_BY_RSN(prBssDesc) \ + (WEIGHT_IDX_RSN * (prBssDesc->fgIsRSNSuitableBss ? BSS_FULL_SCORE:0)) +#endif + +#if 0 +static uint16_t scanCaculateScoreBySTBC(struct ADAPTER *prAdapter, + struct BSS_DESC *prBssDesc, enum ROAM_TYPE eRoamType) +{ + uint16_t u2Score = 0; + uint8_t ucSpatial = 0; + + ucSpatial = prBssDesc->ucSpatial; + + if (prBssDesc->fgMultiAnttenaAndSTBC) { + ucSpatial = (ucSpatial >= 4)?4:ucSpatial; + u2Score = (BSS_FULL_SCORE-50)*ucSpatial; + } else { + u2Score = 0; + } + return u2Score*mtk_weight_config[eRoamType].ucStbcWeight; +} +#endif + +/* Channel Utilization: weight index will be */ +static uint16_t scanCalculateScoreByChnlInfo( + struct AIS_SPECIFIC_BSS_INFO *prAisSpecificBssInfo, uint8_t ucChannel, + enum ROAM_TYPE eRoamType) +{ + struct ESS_CHNL_INFO *prEssChnlInfo = &prAisSpecificBssInfo-> + arCurEssChnlInfo[0]; + uint8_t i = 0; + uint16_t u2Score = 0; + uint8_t weight = gasMtkWeightConfig[eRoamType].ucApNumWeight; + + for (; i < prAisSpecificBssInfo->ucCurEssChnlInfoNum; i++) { + if (ucChannel == prEssChnlInfo[i].ucChannel) { +#if 0 /* currently, we don't take channel utilization into account */ + /* the channel utilization max value is 255. + *great utilization means little weight value. + * the step of weight value is 2.6 + */ + u2Score = mtk_weight_config[eRoamType]. + ucChnlUtilWeight * (BSS_FULL_SCORE - + (prEssChnlInfo[i].ucUtilization * 10 / 26)); +#endif + /* if AP num on this channel is greater than 100, + * the weight will be 0. + * otherwise, the weight value decrease 1 + * if AP number increase 1 + */ + if (prEssChnlInfo[i].ucApNum <= CHNL_BSS_NUM_THRESOLD) + u2Score += weight * + (BSS_FULL_SCORE - prEssChnlInfo[i].ucApNum * + SCORE_PER_AP); + log_dbg(SCN, TRACE, "channel %d, AP num %d\n", + ucChannel, prEssChnlInfo[i].ucApNum); + break; + } + } + return u2Score; +} + +static uint16_t scanCalculateScoreByBandwidth(struct ADAPTER *prAdapter, + struct BSS_DESC *prBssDesc, enum ROAM_TYPE eRoamType) +{ + uint16_t u2Score = 0; + enum ENUM_CHANNEL_WIDTH eChannelWidth = prBssDesc->eChannelWidth; + uint8_t ucSta5GBW = prAdapter->rWifiVar.ucSta5gBandwidth; + uint8_t ucSta2GBW = prAdapter->rWifiVar.ucSta2gBandwidth; + uint8_t ucStaBW = prAdapter->rWifiVar.ucStaBandwidth; + + if (prBssDesc->fgIsVHTPresent && prAdapter->fgEnable5GBand) { + if (ucSta5GBW > ucStaBW) + ucSta5GBW = ucStaBW; + switch (ucSta5GBW) { + case MAX_BW_20MHZ: + case MAX_BW_40MHZ: + eChannelWidth = CW_20_40MHZ; + break; + case MAX_BW_80MHZ: + eChannelWidth = CW_80MHZ; + break; + } + switch (eChannelWidth) { + case CW_20_40MHZ: + u2Score = 60; + break; + case CW_80MHZ: + u2Score = 80; + break; + case CW_160MHZ: + case CW_80P80MHZ: + u2Score = BSS_FULL_SCORE; + break; + } + } else if (prBssDesc->fgIsHTPresent) { + if (prBssDesc->eBand == BAND_2G4) { + if (ucSta2GBW > ucStaBW) + ucSta2GBW = ucStaBW; + u2Score = (prBssDesc->eSco == 0 || + ucSta2GBW == MAX_BW_20MHZ) ? 40:60; + } else if (prBssDesc->eBand == BAND_5G) { + if (ucSta5GBW > ucStaBW) + ucSta5GBW = ucStaBW; + u2Score = (prBssDesc->eSco == 0 || + ucSta5GBW == MAX_BW_20MHZ) ? 40:60; + } + } else if (prBssDesc->u2BSSBasicRateSet & RATE_SET_OFDM) + u2Score = 20; + else + u2Score = 10; + + return u2Score * gasMtkWeightConfig[eRoamType].ucBandWidthWeight; +} + +static uint16_t scanCalculateScoreByClientCnt(struct BSS_DESC *prBssDesc, + enum ROAM_TYPE eRoamType) +{ + uint16_t u2Score = 0; + uint16_t u2StaCnt = 0; +#define BSS_STA_CNT_NORMAL_SCORE 50 +#define BSS_STA_CNT_GOOD_THRESOLD 10 + + log_dbg(SCN, TRACE, "Exist bss load %d, sta cnt %d\n", + prBssDesc->fgExsitBssLoadIE, prBssDesc->u2StaCnt); + + if (!prBssDesc->fgExsitBssLoadIE) { + u2Score = BSS_STA_CNT_NORMAL_SCORE; + return u2Score * + gasMtkWeightConfig[eRoamType].ucClientCntWeight; + } + + u2StaCnt = prBssDesc->u2StaCnt; + if (u2StaCnt > BSS_STA_CNT_THRESOLD) + u2Score = 0; + else if (u2StaCnt < BSS_STA_CNT_GOOD_THRESOLD) + u2Score = BSS_FULL_SCORE - u2StaCnt; + else + u2Score = BSS_STA_CNT_NORMAL_SCORE; + + return u2Score * gasMtkWeightConfig[eRoamType].ucClientCntWeight; +} + +#if CFG_SUPPORT_802_11V_BSS_TRANSITION_MGT +struct NEIGHBOR_AP_T *scanGetNeighborAPEntry(struct LINK *prNeighborApLink, + uint8_t *pucBssid) +{ + struct NEIGHBOR_AP_T *prNeighborAP = NULL; + + LINK_FOR_EACH_ENTRY(prNeighborAP, prNeighborApLink, rLinkEntry, + struct NEIGHBOR_AP_T) + { + if (EQUAL_MAC_ADDR(prNeighborAP->aucBssid, pucBssid)) + return prNeighborAP; + } + return NULL; +} + +u_int8_t scanPreferenceIsZero(struct ADAPTER *prAdapter, uint8_t *pucBssid, + uint8_t ucBssIndex) +{ + struct LINK *prNeighborAPLink = + &aisGetAisSpecBssInfo(prAdapter, ucBssIndex) + ->rNeighborApList.rUsingLink; + struct NEIGHBOR_AP_T *prNeighborAP = NULL; + + if (prNeighborAPLink->u4NumElem == 0) + return FALSE; + + prNeighborAP = scanGetNeighborAPEntry(prNeighborAPLink, pucBssid); + + if (prNeighborAP == NULL) + return FALSE; + if (!prNeighborAP->fgPrefPresence) + return FALSE; + if (prNeighborAP->ucPreference > 0) + return FALSE; + + return TRUE; +} +#endif + +static u_int8_t scanNeedReplaceCandidate(struct ADAPTER *prAdapter, + struct BSS_DESC *prCandBss, struct BSS_DESC *prCurrBss, + uint16_t u2CandScore, uint16_t u2CurrScore, + enum ROAM_TYPE eRoamType, uint8_t ucBssIndex) +{ + int8_t cCandRssi = RCPI_TO_dBm(prCandBss->ucRCPI); + int8_t cCurrRssi = RCPI_TO_dBm(prCurrBss->ucRCPI); + uint32_t u4UpdateIdx = prAdapter->rWifiVar.rScanInfo.u4ScanUpdateIdx; + uint16_t u2CandMiss = u4UpdateIdx - prCandBss->u4UpdateIdx; + uint16_t u2CurrMiss = u4UpdateIdx - prCurrBss->u4UpdateIdx; + struct BSS_DESC *prBssDesc = NULL; + int8_t ucOpChannelNum = 0; + + prBssDesc = aisGetTargetBssDesc(prAdapter, ucBssIndex); + if (prBssDesc) + ucOpChannelNum = prBssDesc->ucChannelNum; + +#if CFG_SUPPORT_NCHO + if (prAdapter->rNchoInfo.fgNCHOEnabled) + return cCurrRssi >= cCandRssi ? TRUE : FALSE; +#endif + + /* 1. No need check score case + * 1.1 Scan missing count of CurrBss is too more, + * but Candidate is suitable, don't replace + */ + if (u2CurrMiss > 2 && u2CurrMiss > u2CandMiss) { + log_dbg(SCN, INFO, "Scan Miss count of CurrBss > 2, and Candidate <= 2\n"); + return FALSE; + } + /* 1.2 Scan missing count of Candidate is too more, + * but CurrBss is suitable, replace + */ + if (u2CandMiss > 2 && u2CandMiss > u2CurrMiss) { + log_dbg(SCN, INFO, "Scan Miss count of Candidate > 2, and CurrBss <= 2\n"); + return TRUE; + } + /* 1.3 Hard connecting RSSI check */ + if ((prCurrBss->eBand == BAND_5G && cCurrRssi < MINIMUM_RSSI_5G) || + (prCurrBss->eBand == BAND_2G4 && cCurrRssi < MINIMUM_RSSI_2G4)) + return FALSE; + else if ((prCandBss->eBand == BAND_5G && cCandRssi < MINIMUM_RSSI_5G) || + (prCandBss->eBand == BAND_2G4 && cCandRssi < MINIMUM_RSSI_2G4)) + return TRUE; + + /* 1.4 prefer to select 5G Bss if Rssi of a 5G band BSS is good */ + if (eRoamType != ROAM_TYPE_PER) { + if (prCandBss->eBand != prCurrBss->eBand) { + if (prCandBss->eBand == BAND_5G) { + /* Candidate AP is 5G, don't replace it + * if it's good enough. + */ + if (cCandRssi >= GOOD_RSSI_FOR_HT_VHT) + return FALSE; + if (cCandRssi < LOW_RSSI_FOR_5G_BAND && + (cCurrRssi > cCandRssi + 5)) + return TRUE; + } else { + /* Current AP is 5G, replace candidate + * AP if current AP is good. + */ + if (cCurrRssi >= GOOD_RSSI_FOR_HT_VHT) + return TRUE; + if (cCurrRssi < LOW_RSSI_FOR_5G_BAND && + (cCandRssi > cCurrRssi + 5)) + return FALSE; + } + } + } + + /* 1.5 RSSI of Current Bss is lower than Candidate, don't replace + * If the lower Rssi is greater than -59dbm, + * then no need check the difference + * Otherwise, if difference is greater than 10dbm, select the good RSSI + */ + do { + if ((eRoamType == ROAM_TYPE_PER) && + cCandRssi >= RSSI_SECOND_LEVEL && + cCurrRssi >= RSSI_SECOND_LEVEL) + break; + if (cCandRssi - cCurrRssi >= RSSI_DIFF_BETWEEN_BSS) + return FALSE; + if (cCurrRssi - cCandRssi >= RSSI_DIFF_BETWEEN_BSS) + return TRUE; + } while (FALSE); + +#if CFG_SUPPORT_802_11V_BSS_TRANSITION_MGT + if (scanPreferenceIsZero(prAdapter, prCurrBss->aucBSSID, + ucBssIndex)) { + log_dbg(SCN, INFO, + "BTM: %s[" MACSTR "] preference value is 0, skip it\n", + prCurrBss->aucSSID, MAC2STR(prCurrBss->aucBSSID)); + return FALSE; + } +#endif + if (eRoamType == ROAM_TYPE_PER) { + if (prCandBss->ucChannelNum == ucOpChannelNum) { + log_dbg(SCN, INFO, "CandBss in opchnl,add CurBss Score\n"); + u2CurrScore += BSS_FULL_SCORE * + gasMtkWeightConfig[eRoamType].ucOpchnlWeight; + } + if (prCurrBss->ucChannelNum == ucOpChannelNum) { + log_dbg(SCN, INFO, "CurrBss in opchnl,add CandBss Score\n"); + u2CandScore += BSS_FULL_SCORE * + gasMtkWeightConfig[eRoamType].ucOpchnlWeight; + } + } + + /* 2. Check Score */ + /* 2.1 Cases that no need to replace candidate */ + if (prCandBss->fgIsConnected) { + if ((u2CandScore + ROAMING_NO_SWING_SCORE_STEP) >= u2CurrScore) + return FALSE; + } else if (prCurrBss->fgIsConnected) { + if (u2CandScore >= (u2CurrScore + ROAMING_NO_SWING_SCORE_STEP)) + return FALSE; + } else if (u2CandScore >= u2CurrScore) + return FALSE; + /* 2.2 other cases, replace candidate */ + return TRUE; +} + +static u_int8_t scanSanityCheckBssDesc(struct ADAPTER *prAdapter, + struct BSS_DESC *prBssDesc, enum ENUM_BAND eBand, uint8_t ucChannel, + u_int8_t fgIsFixedChannel, enum ENUM_ROAMING_REASON eRoamReason, + uint8_t ucBssIndex) +{ + struct BSS_INFO *prAisBssInfo; + struct BSS_DESC *target; + +#if CFG_SUPPORT_MBO + struct PARAM_BSS_DISALLOWED_LIST *disallow; + uint32_t i = 0; + + disallow = &prAdapter->rWifiVar.rBssDisallowedList; + for (i = 0; i < disallow->u4NumBssDisallowed; ++i) { + uint32_t index = i * MAC_ADDR_LEN; + + if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, + &disallow->aucList[index])) { + log_dbg(SCN, WARN, MACSTR" disallowed list\n", + MAC2STR(prBssDesc->aucBSSID)); + return FALSE; + } + } + + if (prBssDesc->fgIsDisallowed) { + log_dbg(SCN, WARN, MACSTR" disallowed\n", + MAC2STR(prBssDesc->aucBSSID)); + return FALSE; + } +#endif + + + prAisBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + target = aisGetTargetBssDesc(prAdapter, ucBssIndex); + if (prBssDesc->prBlack) { + if (prBssDesc->prBlack->fgIsInFWKBlacklist) { + log_dbg(SCN, WARN, MACSTR" in FWK blacklist\n", + MAC2STR(prBssDesc->aucBSSID)); + return FALSE; + } + + if (prBssDesc->prBlack->fgDeauthLastTime) { + log_dbg(SCN, WARN, MACSTR " is sending deauth.\n", + MAC2STR(prBssDesc->aucBSSID)); + return FALSE; + } + + if (prBssDesc->prBlack->ucCount >= 10) { + log_dbg(SCN, WARN, + MACSTR + " Skip AP that add toblacklist count >= 10\n", + MAC2STR(prBssDesc->aucBSSID)); + return FALSE; + } + } + + /* roaming case */ + if (target && + (prAisBssInfo->eConnectionState == MEDIA_STATE_CONNECTED || + aisFsmIsInProcessPostpone(prAdapter, ucBssIndex))) { + int32_t r1, r2; + + r1 = RCPI_TO_dBm(target->ucRCPI); + r2 = RCPI_TO_dBm(prBssDesc->ucRCPI); + if (prBssDesc->ucRCPI < RCPI_FOR_DONT_ROAM +#if CFG_SUPPORT_NCHO + || (prAdapter->rNchoInfo.fgNCHOEnabled && + (eRoamReason == ROAMING_REASON_POOR_RCPI || + eRoamReason == ROAMING_REASON_RETRY) && + r1 - r2 <= prAdapter->rNchoInfo.i4RoamDelta) +#endif + ) { + log_dbg(SCN, INFO, MACSTR " low rssi %d (cur=%d)\n", + MAC2STR(prBssDesc->aucBSSID), r2, r1); + return FALSE; + } + } + + if (ucBssIndex != AIS_DEFAULT_INDEX) { + struct BSS_DESC *target = + aisGetTargetBssDesc(prAdapter, AIS_DEFAULT_INDEX); + + if (target && prBssDesc->eBand == target->eBand) { + log_dbg(SCN, WARN, MACSTR" band %d used by main\n", + MAC2STR(prBssDesc->aucBSSID)); + return FALSE; + } + } + + if (!(prBssDesc->ucPhyTypeSet & + (prAdapter->rWifiVar.ucAvailablePhyTypeSet))) { + log_dbg(SCN, WARN, + MACSTR" ignore unsupported ucPhyTypeSet = %x\n", + MAC2STR(prBssDesc->aucBSSID), + prBssDesc->ucPhyTypeSet); + return FALSE; + } + if (prBssDesc->fgIsUnknownBssBasicRate) { + log_dbg(SCN, WARN, MACSTR" unknown bss basic rate\n", + MAC2STR(prBssDesc->aucBSSID)); + return FALSE; + } + if (fgIsFixedChannel && (eBand != prBssDesc->eBand || ucChannel != + prBssDesc->ucChannelNum)) { + log_dbg(SCN, WARN, + MACSTR" fix channel required band %d, channel %d\n", + MAC2STR(prBssDesc->aucBSSID), eBand, ucChannel); + return FALSE; + } + +#if CFG_SUPPORT_WIFI_SYSDVT + if (!IS_SKIP_CH_CHECK(prAdapter)) +#endif + if (!rlmDomainIsLegalChannel(prAdapter, prBssDesc->eBand, + prBssDesc->ucChannelNum)) { + log_dbg(SCN, WARN, MACSTR" band %d channel %d is not legal\n", + MAC2STR(prBssDesc->aucBSSID), prBssDesc->eBand, + prBssDesc->ucChannelNum); + return FALSE; + } + + if (CHECK_FOR_TIMEOUT(kalGetTimeTick(), prBssDesc->rUpdateTime, + SEC_TO_SYSTIME(wlanWfdEnabled(prAdapter) ? + SCN_BSS_DESC_STALE_SEC_WFD : SCN_BSS_DESC_STALE_SEC))) { + log_dbg(SCN, WARN, MACSTR " description is too old.\n", + MAC2STR(prBssDesc->aucBSSID)); + return FALSE; + } + +#if CFG_SUPPORT_WAPI + if (aisGetWapiMode(prAdapter, ucBssIndex)) { + if (!wapiPerformPolicySelection(prAdapter, prBssDesc, + ucBssIndex)) { + log_dbg(SCN, WARN, MACSTR " wapi policy select fail.\n", + MAC2STR(prBssDesc->aucBSSID)); + return FALSE; + } + } else +#endif + if (!rsnPerformPolicySelection(prAdapter, prBssDesc, + ucBssIndex)) { + log_dbg(SCN, WARN, MACSTR " rsn policy select fail.\n", + MAC2STR(prBssDesc->aucBSSID)); + return FALSE; + } + if (aisGetAisSpecBssInfo(prAdapter, + ucBssIndex)->fgCounterMeasure) { + log_dbg(SCN, WARN, MACSTR " Skip in counter measure period.\n", + MAC2STR(prBssDesc->aucBSSID)); + return FALSE; + } + + return TRUE; +} + +static uint16_t scanCalculateScoreByRssi(struct BSS_DESC *prBssDesc, + enum ROAM_TYPE eRoamType) +{ + uint16_t u2Score = 0; + int8_t cRssi = RCPI_TO_dBm(prBssDesc->ucRCPI); + + if (cRssi >= BEST_RSSI) + u2Score = 100; + else if (cRssi <= -98) + u2Score = 0; + else + u2Score = (cRssi + 98) * 2; + u2Score *= gasMtkWeightConfig[eRoamType].ucRssiWeight; + + return u2Score; +} + +static uint16_t scanCalculateScoreBySaa(struct ADAPTER *prAdapter, + struct BSS_DESC *prBssDesc, enum ROAM_TYPE eRoamType) +{ + uint16_t u2Score = 0; + struct STA_RECORD *prStaRec = (struct STA_RECORD *) NULL; + + prStaRec = cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_AIS, + prBssDesc->aucSrcAddr); + if (prStaRec) + u2Score = gasMtkWeightConfig[eRoamType].ucSaaWeight * + (prStaRec->ucTxAuthAssocRetryCount ? 0 : BSS_FULL_SCORE); + else + u2Score = gasMtkWeightConfig[eRoamType].ucSaaWeight * + BSS_FULL_SCORE; + + return u2Score; +} + +static uint16_t scanCalculateScoreByIdleTime(struct ADAPTER *prAdapter, + uint8_t ucChannel, enum ROAM_TYPE eRoamType, uint8_t ucBssIndex) +{ + uint8_t u4ChCnt = 0; + uint16_t u2Score = 0; + uint16_t u2ChIdleSlot; + uint16_t u2ChIdleTime; + uint16_t u2ChIdleUtil; + uint16_t u2ChDwellTime; + struct SCAN_INFO *prScanInfo; + struct SCAN_PARAM *prScanParam; + struct BSS_INFO *prAisBssInfo; + + prAisBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + prScanInfo = &(prAdapter->rWifiVar.rScanInfo); + prScanParam = &(prScanInfo->rScanParam); + + if (prScanParam->u2ChannelDwellTime > 0) + u2ChDwellTime = prScanParam->u2ChannelDwellTime; + else if (prAisBssInfo->eConnectionState == MEDIA_STATE_CONNECTED) + u2ChDwellTime = CHNL_DWELL_TIME_ONLINE; + else + u2ChDwellTime = CHNL_DWELL_TIME_DEFAULT; + + for (u4ChCnt = 0; u4ChCnt < prScanInfo + ->ucSparseChannelArrayValidNum; u4ChCnt++) { + if (ucChannel == prScanInfo->aucChannelNum[u4ChCnt]) { + u2ChIdleSlot = + prScanInfo->au2ChannelIdleTime[u4ChCnt]; + u2ChIdleTime = u2ChIdleSlot * 9; + u2ChIdleUtil = + (u2ChIdleTime * 100) / (u2ChDwellTime * 1000); + if (u2ChIdleUtil > BSS_FULL_SCORE) + u2ChIdleUtil = BSS_FULL_SCORE; + u2Score = u2ChIdleUtil * + gasMtkWeightConfig[eRoamType].ucChnlIdleWeight; + break; + } + } + + return u2Score; +} + +u_int8_t scanApOverload(uint16_t status, uint16_t reason) +{ + switch (status) { + case STATUS_CODE_ASSOC_DENIED_AP_OVERLOAD: + case STATUS_CODE_ASSOC_DENIED_BANDWIDTH: + case STATUS_CODE_ASSOC_DENIED_OUTSIDE_STANDARD: + case STATUS_CODE_AUTH_TIMEOUT: + case STATUS_CODE_ASSOC_TIMEOUT: + return TRUE; + } + switch (reason) { + case REASON_CODE_DISASSOC_LACK_OF_BANDWIDTH: + case REASON_CODE_DISASSOC_AP_OVERLOAD: + return TRUE; + } + return FALSE; +} + +uint16_t scanCalculateScoreByBlackList(struct ADAPTER *prAdapter, + struct BSS_DESC *prBssDesc, enum ROAM_TYPE eRoamType) +{ + uint16_t u2Score = 0; + + if (!prBssDesc->prBlack) + u2Score = 100; + else if (scanApOverload(prBssDesc->prBlack->u2AuthStatus, + prBssDesc->prBlack->u2DeauthReason) || + prBssDesc->prBlack->ucCount >= 10) + u2Score = 0; + else + u2Score = 100 - prBssDesc->prBlack->ucCount * 10; + + return u2Score * gasMtkWeightConfig[eRoamType].ucBlackListWeight; +} + +uint16_t scanCalculateTotalScore(struct ADAPTER *prAdapter, + struct BSS_DESC *prBssDesc, enum ROAM_TYPE eRoamType, + uint8_t ucBssIndex) +{ + struct AIS_SPECIFIC_BSS_INFO *prAisSpecificBssInfo = NULL; + uint16_t u2ScoreStaCnt = 0; + uint16_t u2ScoreBandwidth = 0; + uint16_t u2ScoreSTBC = 0; + uint16_t u2ScoreChnlInfo = 0; + uint16_t u2ScoreSnrRssi = 0; + uint16_t u2ScoreDeauth = 0; + uint16_t u2ScoreProbeRsp = 0; + uint16_t u2ScoreScanMiss = 0; + uint16_t u2ScoreBand = 0; + uint16_t u2ScoreSaa = 0; + uint16_t u2ScoreIdleTime = 0; + uint16_t u2ScoreTotal = 0; + uint16_t u2BlackListScore = 0; +#if (CFG_SUPPORT_802_11AX == 1) + uint16_t u2AxApScore = 0; +#endif + int8_t cRssi = -128; + + prAisSpecificBssInfo = + aisGetAisSpecBssInfo(prAdapter, ucBssIndex); + cRssi = RCPI_TO_dBm(prBssDesc->ucRCPI); + + u2ScoreBandwidth = + scanCalculateScoreByBandwidth(prAdapter, prBssDesc, eRoamType); + u2ScoreStaCnt = scanCalculateScoreByClientCnt(prBssDesc, eRoamType); + u2ScoreSTBC = CALCULATE_SCORE_BY_STBC(prAdapter, prBssDesc, eRoamType); + u2ScoreChnlInfo = + scanCalculateScoreByChnlInfo(prAisSpecificBssInfo, + prBssDesc->ucChannelNum, eRoamType); + u2ScoreSnrRssi = scanCalculateScoreByRssi(prBssDesc, eRoamType); + u2ScoreDeauth = CALCULATE_SCORE_BY_DEAUTH(prBssDesc, eRoamType); + u2ScoreProbeRsp = CALCULATE_SCORE_BY_PROBE_RSP(prBssDesc, eRoamType); + u2ScoreScanMiss = CALCULATE_SCORE_BY_MISS_CNT(prAdapter, + prBssDesc, eRoamType); + u2ScoreBand = CALCULATE_SCORE_BY_BAND(prAdapter, prBssDesc, + cRssi, eRoamType); + u2ScoreSaa = scanCalculateScoreBySaa(prAdapter, prBssDesc, eRoamType); + u2ScoreIdleTime = scanCalculateScoreByIdleTime(prAdapter, + prBssDesc->ucChannelNum, eRoamType, ucBssIndex); + u2BlackListScore = + scanCalculateScoreByBlackList(prAdapter, prBssDesc, eRoamType); + +#if (CFG_SUPPORT_802_11AX == 1) + u2AxApScore = CALCULATE_SCORE_BY_AX_AP(prAdapter, prBssDesc, eRoamType); +#endif + u2ScoreTotal = u2ScoreBandwidth + u2ScoreChnlInfo + + u2ScoreDeauth + u2ScoreProbeRsp + u2ScoreScanMiss + + u2ScoreSnrRssi + u2ScoreStaCnt + u2ScoreSTBC + + u2ScoreBand + u2BlackListScore + u2ScoreSaa + + u2ScoreIdleTime; +#if (CFG_SUPPORT_802_11AX == 1) + u2ScoreTotal += u2AxApScore; +#endif + +#if (CFG_SUPPORT_802_11AX == 1) +#define TEMP_LOG_TEMPLATE\ + MACSTR" cRSSI[%d] 5G[%d] Score,Total %d,DE[%d]"\ + ", PR[%d], SM[%d], RSSI[%d],BD[%d],BL[%d],SAA[%d]"\ + ", BW[%d], SC[%d],ST[%d],CI[%d],IT[%d],CU[%d,%d]"\ + ", HE[%d], AxWeight[%d], AxScoreDiv[%d], AxScore[%d]\n" +#else +#define TEMP_LOG_TEMPLATE\ + MACSTR" cRSSI[%d] 5G[%d] Score,Total %d,DE[%d]"\ + ", PR[%d], SM[%d], RSSI[%d],BD[%d],BL[%d],SAA[%d]"\ + ", BW[%d], SC[%d],ST[%d],CI[%d],IT[%d],CU[%d,%d]\n" +#endif + + log_dbg(SCN, INFO, + TEMP_LOG_TEMPLATE, + MAC2STR(prBssDesc->aucBSSID), cRssi, + (prBssDesc->eBand == BAND_5G ? 1 : 0), u2ScoreTotal, + u2ScoreDeauth, u2ScoreProbeRsp, u2ScoreScanMiss, + u2ScoreSnrRssi, u2ScoreBand, u2BlackListScore, + u2ScoreSaa, u2ScoreBandwidth, u2ScoreStaCnt, + u2ScoreSTBC, u2ScoreChnlInfo, u2ScoreIdleTime, + prBssDesc->fgExsitBssLoadIE, + prBssDesc->ucChnlUtilization +#if (CFG_SUPPORT_802_11AX == 1) + , prBssDesc->fgIsHEPresent + , (prAdapter->rWifiVar).ucApSelAxWeight + , (prAdapter->rWifiVar).ucApSelAxScoreDiv + , u2AxApScore +#endif + ); +#undef TEMP_LOG_TEMPLATE + + return u2ScoreTotal; +} +/* + * Bss Characteristics to be taken into account when calculate Score: + * Channel Loading Group: + * 1. Client Count (in BSS Load IE). + * 2. AP number on the Channel. + * + * RF Group: + * 1. Channel utilization. + * 2. SNR. + * 3. RSSI. + * + * Misc Group: + * 1. Deauth Last time. + * 2. Scan Missing Count. + * 3. Has probe response in scan result. + * + * Capability Group: + * 1. Prefer 5G band. + * 2. Bandwidth. + * 3. STBC and Multi Anttena. + */ +struct BSS_DESC *scanSearchBssDescByScoreForAis(struct ADAPTER *prAdapter, + enum ENUM_ROAMING_REASON eRoamReason, uint8_t ucBssIndex) +{ + struct AIS_SPECIFIC_BSS_INFO *prAisSpecificBssInfo = NULL; + struct ROAMING_INFO *prRoamingFsmInfo = NULL; + struct BSS_INFO *prAisBssInfo = NULL; + struct LINK *prEssLink = NULL; + struct CONNECTION_SETTINGS *prConnSettings = NULL; + struct BSS_DESC *prBssDesc = NULL; + struct BSS_DESC *prCandBssDesc = NULL; + struct BSS_DESC *prCandBssDescForLowRssi = NULL; + uint16_t u2ScoreTotal = 0; + uint16_t u2CandBssScore = 0; + uint16_t u2CandBssScoreForLowRssi = 0; + u_int8_t fgSearchBlackList = FALSE; + u_int8_t fgIsFixedChnl = FALSE; + enum ENUM_BAND eBand = BAND_2G4; + uint8_t ucChannel = 0; + enum ENUM_PARAM_CONNECTION_POLICY policy; + struct ROAMING_INFO *roam; + enum ROAM_TYPE eRoamType; + + if (!prAdapter || + eRoamReason >= ROAMING_REASON_NUM || eRoamReason < 0) { + log_dbg(SCN, ERROR, + "prAdapter %p, reason %d!\n", prAdapter, eRoamReason); + return NULL; + } + prAisSpecificBssInfo = aisGetAisSpecBssInfo(prAdapter, ucBssIndex); + prConnSettings = aisGetConnSettings(prAdapter, ucBssIndex); + prEssLink = &prAisSpecificBssInfo->rCurEssLink; + prRoamingFsmInfo = aisGetRoamingInfo(prAdapter, ucBssIndex); + prAisBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + roam = aisGetRoamingInfo(prAdapter, ucBssIndex); + eRoamType = mtk_reason_to_type[eRoamReason]; +#if CFG_SUPPORT_CHNL_CONFLICT_REVISE + fgIsFixedChnl = cnmAisDetectP2PChannel(prAdapter, &eBand, &ucChannel); +#else + fgIsFixedChnl = cnmAisInfraChannelFixed(prAdapter, &eBand, &ucChannel); +#endif + aisRemoveTimeoutBlacklist(prAdapter); + log_dbg(SCN, INFO, "ConnectionPolicy = %d, reason = %d\n", + prConnSettings->eConnectionPolicy, eRoamReason); + policy = prConnSettings->eConnectionPolicy; +try_again: + LINK_FOR_EACH_ENTRY(prBssDesc, prEssLink, rLinkEntryEss[ucBssIndex], + struct BSS_DESC) { + /* update blacklist info */ + if (!fgSearchBlackList) + prBssDesc->prBlack = + aisQueryBlackList(prAdapter, prBssDesc); + /* + * Skip if + * 1. sanity check fail or + * 2. bssid is in driver's blacklist in the first round + */ + if (!scanSanityCheckBssDesc(prAdapter, prBssDesc, eBand, + ucChannel, fgIsFixedChnl, eRoamReason, ucBssIndex) || + (!fgSearchBlackList && prBssDesc->prBlack)) + continue; + + /* pick by bssid first */ + if (policy == CONNECT_BY_BSSID) { + if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, + prConnSettings->aucBSSID)) { + log_dbg(SCN, INFO, MACSTR" match bssid\n", + MAC2STR(prBssDesc->aucBSSID)); + prCandBssDesc = prBssDesc; + break; + } + /* skip when bssid unmatched if conn by bssid */ + log_dbg(SCN, INFO, MACSTR" unmatch bssid\n", + MAC2STR(prBssDesc->aucBSSID)); + continue; + } else if (policy == CONNECT_BY_BSSID_HINT) { + if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, + prConnSettings->aucBSSIDHint)) { + log_dbg(SCN, INFO, MACSTR" match bssid_hint\n", + MAC2STR(prBssDesc->aucBSSID)); + prCandBssDesc = prBssDesc; + break; + } + } + + u2ScoreTotal = scanCalculateTotalScore(prAdapter, prBssDesc, + eRoamType, ucBssIndex); + if (!prCandBssDesc || + scanNeedReplaceCandidate(prAdapter, prCandBssDesc, + prBssDesc, u2CandBssScore, u2ScoreTotal, eRoamType, + ucBssIndex)) { + prCandBssDesc = prBssDesc; + u2CandBssScore = u2ScoreTotal; + } + } + + if (prCandBssDesc) { + if (prCandBssDesc->fgIsConnected && !fgSearchBlackList && + prEssLink->u4NumElem > 0) { + fgSearchBlackList = TRUE; + log_dbg(SCN, INFO, "Can't roam out, try blacklist\n"); + goto try_again; + } + + if (prConnSettings->eConnectionPolicy == CONNECT_BY_BSSID) + log_dbg(SCN, INFO, "Selected " + MACSTR + " %d base on ssid,when find %s, " + MACSTR + " in %d bssid,fix channel %d.\n", + MAC2STR(prCandBssDesc->aucBSSID), + RCPI_TO_dBm(prCandBssDesc->ucRCPI), + HIDE(prConnSettings->aucSSID), + MAC2STR(prConnSettings->aucBSSID), + prEssLink->u4NumElem, ucChannel); + else + log_dbg(SCN, INFO, + "Selected " + MACSTR + ", cRSSI[%d] 5G[%d] Score %d when find %s, " + MACSTR + " in %d BSSes, fix channel %d.\n", + MAC2STR(prCandBssDesc->aucBSSID), + RCPI_TO_dBm(prCandBssDesc->ucRCPI), + (prCandBssDesc->eBand == BAND_5G ? 1 : 0), + u2CandBssScore, prConnSettings->aucSSID, + MAC2STR(prConnSettings->aucBSSID), + prEssLink->u4NumElem, ucChannel); + + return prCandBssDesc; + } else if (prCandBssDescForLowRssi) { + log_dbg(SCN, INFO, "Selected " MACSTR + ", Score %d when find %s, " MACSTR + " in %d BSSes, fix channel %d.\n", + MAC2STR(prCandBssDescForLowRssi->aucBSSID), + u2CandBssScoreForLowRssi, prConnSettings->aucSSID, + MAC2STR(prConnSettings->aucBSSID), prEssLink->u4NumElem, + ucChannel); + return prCandBssDescForLowRssi; + } + + /* if No Candidate BSS is found, try BSSes which are in blacklist */ + if (!fgSearchBlackList && prEssLink->u4NumElem > 0) { + fgSearchBlackList = TRUE; + log_dbg(SCN, INFO, "No Bss is found, Try blacklist\n"); + goto try_again; + } + log_dbg(SCN, INFO, "Selected None when find %s, " MACSTR + " in %d BSSes, fix channel %d.\n", + prConnSettings->aucSSID, MAC2STR(prConnSettings->aucBSSID), + prEssLink->u4NumElem, ucChannel); + return NULL; +} + +uint8_t scanUpdateChannelList(uint8_t channel, + uint8_t *bitmap, uint8_t *count, struct ESS_CHNL_INFO *info) +{ + uint8_t byteNum = 0; + uint8_t bitNum = 0; + + byteNum = channel / 8; + bitNum = channel % 8; + if (bitmap[byteNum] & BIT(bitNum)) + return 1; + bitmap[byteNum] |= BIT(bitNum); + info[*count].ucChannel = channel; + *count += 1; + if (*count >= CFG_MAX_NUM_OF_CHNL_INFO) + return 0; + + return 1; +} + +void scanGetCurrentEssChnlList(struct ADAPTER *prAdapter, + uint8_t ucBssIndex) +{ + struct BSS_DESC *prBssDesc = NULL; + struct LINK *prBSSDescList = + &prAdapter->rWifiVar.rScanInfo.rBSSDescList; + struct CONNECTION_SETTINGS *prConnSettings = + aisGetConnSettings(prAdapter, ucBssIndex); + struct ESS_CHNL_INFO *prEssChnlInfo; + struct LINK *prCurEssLink; + struct AIS_SPECIFIC_BSS_INFO *prAisSpecBssInfo; + uint8_t aucChnlBitMap[30] = {0,}; + uint8_t aucChnlApNum[215] = {0,}; + uint8_t aucChnlUtil[215] = {0,}; + uint8_t ucChnlCount = 0; + uint32_t i; + uint8_t j = 0; +#if CFG_SUPPORT_802_11K + struct LINK *prNeighborAPLink; +#endif + struct CFG_SCAN_CHNL *prRoamScnChnl = &prAdapter->rAddRoamScnChnl; + + if (!prConnSettings) { + log_dbg(SCN, INFO, "No prConnSettings\n"); + return; + } + + if (prConnSettings->ucSSIDLen == 0) { + log_dbg(SCN, INFO, "No Ess are expected to connect\n"); + return; + } + + prAisSpecBssInfo = + aisGetAisSpecBssInfo(prAdapter, ucBssIndex); + if (!prAisSpecBssInfo) { + log_dbg(SCN, INFO, "No prAisSpecBssInfo\n"); + return; + } + prEssChnlInfo = + &prAisSpecBssInfo->arCurEssChnlInfo[0]; + if (!prEssChnlInfo) { + log_dbg(SCN, INFO, "No prEssChnlInfo\n"); + return; + } + prCurEssLink = + &prAisSpecBssInfo->rCurEssLink; + if (!prCurEssLink) { + log_dbg(SCN, INFO, "No prCurEssLink\n"); + return; + } + + kalMemZero(prEssChnlInfo, CFG_MAX_NUM_OF_CHNL_INFO * + sizeof(struct ESS_CHNL_INFO)); + + while (!LINK_IS_EMPTY(prCurEssLink)) { + prBssDesc = LINK_PEEK_HEAD(prCurEssLink, + struct BSS_DESC, rLinkEntryEss[ucBssIndex]); + LINK_REMOVE_KNOWN_ENTRY(prCurEssLink, + &prBssDesc->rLinkEntryEss[ucBssIndex]); + } + LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, + struct BSS_DESC) { + if (prBssDesc->ucChannelNum > 214) + continue; + /* Statistic AP num for each channel */ + if (aucChnlApNum[prBssDesc->ucChannelNum] < 255) + aucChnlApNum[prBssDesc->ucChannelNum]++; + if (aucChnlUtil[prBssDesc->ucChannelNum] < + prBssDesc->ucChnlUtilization) + aucChnlUtil[prBssDesc->ucChannelNum] = + prBssDesc->ucChnlUtilization; + if (!EQUAL_SSID(prConnSettings->aucSSID, + prConnSettings->ucSSIDLen, + prBssDesc->aucSSID, prBssDesc->ucSSIDLen)) + continue; + /* Record same BSS list */ + LINK_INSERT_HEAD(prCurEssLink, + &prBssDesc->rLinkEntryEss[ucBssIndex]); + +#if CFG_SUPPORT_NCHO + /* scan control is 1: use NCHO channel list only */ + if (prAdapter->rNchoInfo.u4RoamScanControl) + continue; +#endif + if (!scanUpdateChannelList(prBssDesc->ucChannelNum, + aucChnlBitMap, &ucChnlCount, prEssChnlInfo)) + goto updated; + } + +#if CFG_SUPPORT_NCHO + if (prAdapter->rNchoInfo.fgNCHOEnabled) { + struct CFG_NCHO_SCAN_CHNL *ncho; + + if (prAdapter->rNchoInfo.u4RoamScanControl) + ncho = &prAdapter->rNchoInfo.rRoamScnChnl; + else + ncho = &prAdapter->rNchoInfo.rAddRoamScnChnl; + + /* handle user-specefied scan channel info */ + for (i = 0; ucChnlCount < CFG_MAX_NUM_OF_CHNL_INFO && + i < ncho->ucChannelListNum; i++) { + uint8_t chnl; + + chnl = ncho->arChnlInfoList[i].ucChannelNum; + if (!scanUpdateChannelList(chnl, + aucChnlBitMap, &ucChnlCount, prEssChnlInfo)) + goto updated; + } + + if (prAdapter->rNchoInfo.u4RoamScanControl) + goto updated; + } +#endif + +#if CFG_SUPPORT_802_11K + prNeighborAPLink = &prAisSpecBssInfo->rNeighborApList.rUsingLink; + if (!LINK_IS_EMPTY(prNeighborAPLink)) { + /* Add channels provided by Neighbor Report to + ** channel list for roaming scanning. + */ + struct NEIGHBOR_AP_T *prNeiAP = NULL; + enum ENUM_BAND eBand; + uint8_t ucChannel; + + LINK_FOR_EACH_ENTRY(prNeiAP, prNeighborAPLink, + rLinkEntry, struct NEIGHBOR_AP_T) { + ucChannel = prNeiAP->ucChannel; + eBand = ucChannel <= 14 ? BAND_2G4 : BAND_5G; + if (!rlmDomainIsLegalChannel( + prAdapter, eBand, ucChannel)) + continue; + if (!scanUpdateChannelList(ucChannel, + aucChnlBitMap, &ucChnlCount, prEssChnlInfo)) + goto updated; + } + } +#endif + + /* handle user-specefied scan channel info */ + for (i = 0; ucChnlCount < CFG_MAX_NUM_OF_CHNL_INFO && + i < prRoamScnChnl->ucChannelListNum; i++) { + uint8_t chnl; + + chnl = prRoamScnChnl->arChnlInfoList[i].ucChannelNum; + if (!scanUpdateChannelList(chnl, + aucChnlBitMap, &ucChnlCount, prEssChnlInfo)) + goto updated; + } + +updated: + + prAisSpecBssInfo->ucCurEssChnlInfoNum = ucChnlCount; + for (j = 0; j < ucChnlCount; j++) { + uint8_t ucChnl = prEssChnlInfo[j].ucChannel; + + prEssChnlInfo[j].ucApNum = aucChnlApNum[ucChnl]; + prEssChnlInfo[j].ucUtilization = aucChnlUtil[ucChnl]; + } +#if 0 + /* Sort according to AP number */ + for (j = 0; j < ucChnlCount; j++) { + for (i = j + 1; i < ucChnlCount; i++) + if (prEssChnlInfo[j].ucApNum > + prEssChnlInfo[i].ucApNum) { + struct ESS_CHNL_INFO rTemp = prEssChnlInfo[j]; + + prEssChnlInfo[j] = prEssChnlInfo[i]; + prEssChnlInfo[i] = rTemp; + } + } +#endif + log_dbg(SCN, INFO, "Find %s in %d BSSes, result %d\n", + prConnSettings->aucSSID, prBSSDescList->u4NumElem, + prCurEssLink->u4NumElem); +} + +uint8_t scanInDecidingRoaming(struct ADAPTER *prAdapter, uint8_t ucBssIndex) +{ + struct ROAMING_INFO *roam; + enum ENUM_PARAM_CONNECTION_POLICY policy; + struct CONNECTION_SETTINGS *setting; + struct BSS_DESC *target; + + roam = aisGetRoamingInfo(prAdapter, ucBssIndex); + setting = aisGetConnSettings(prAdapter, ucBssIndex); + policy = setting->eConnectionPolicy; + target = aisGetTargetBssDesc(prAdapter, ucBssIndex); + + return IS_BSS_INDEX_AIS(prAdapter, ucBssIndex) && + roam->fgIsEnableRoaming && + roam->eCurrentState == ROAMING_STATE_DECISION && + policy != CONNECT_BY_BSSID && + target; + +} + +uint8_t scanCheckNeedDriverRoaming( + struct ADAPTER *prAdapter, uint8_t ucBssIndex) +{ + struct ROAMING_INFO *roam; + struct AIS_FSM_INFO *ais; + struct CONNECTION_SETTINGS *setting; + int8_t rssi; + + roam = aisGetRoamingInfo(prAdapter, ucBssIndex); + ais = aisGetAisFsmInfo(prAdapter, ucBssIndex); + setting = aisGetConnSettings(prAdapter, ucBssIndex); + rssi = prAdapter->rLinkQuality.rLq[ucBssIndex].cRssi; + + GET_CURRENT_SYSTIME(&roam->rRoamingDiscoveryUpdateTime); + +#if CFG_SUPPORT_DRIVER_ROAMING + /* + * try to select AP only when roaming is enabled and rssi is bad + */ + if (scanInDecidingRoaming(prAdapter, ucBssIndex) && + ais->eCurrentState == AIS_STATE_ONLINE_SCAN && + CHECK_FOR_TIMEOUT(roam->rRoamingDiscoveryUpdateTime, + roam->rRoamingLastDecisionTime, + SEC_TO_SYSTIME(prAdapter->rWifiVar.u4InactiveTimeout))) { + struct BSS_DESC *target; + struct BSS_DESC *bss; + + target = aisGetTargetBssDesc(prAdapter, ucBssIndex); + + bss = scanSearchBssDescByScoreForAis(prAdapter, + ROAMING_REASON_INACTIVE, ucBssIndex); + + if (bss == NULL) + return FALSE; + /* 2.4 -> 5 */ + if (bss->eBand == BAND_5G && target->eBand == BAND_2G4) { + if (rssi > RSSI_BAD_NEED_ROAM_24G_TO_5G) + return FALSE; + if (bss->ucRCPI >= RCPI_THRESHOLD_ROAM_TO_5G || + bss->ucRCPI - target->ucRCPI > RCPI_DIFF_DRIVER_ROAM) { + log_dbg(SCN, INFO, + "Driver trigger roaming to 5G band.\n"); + return TRUE; + } + } else { + if (rssi > RSSI_BAD_NEED_ROAM) + return FALSE; + if (bss->ucRCPI - target->ucRCPI > + RCPI_DIFF_DRIVER_ROAM) { + log_dbg(SCN, INFO, + "Driver trigger roaming for other cases.\n"); + return TRUE; + } + } + } +#endif + + return FALSE; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function is to decide if we can roam out by this beacon time +* +* \param[in] prAdapter Pointer of ADAPTER_T +* +* \return true if we can roam out +* false others +*/ +/*----------------------------------------------------------------------------*/ +uint8_t scanBeaconTimeoutFilterPolicyForAis(struct ADAPTER *prAdapter, + uint8_t ucBssIndex) +{ + int8_t rssi; + + rssi = prAdapter->rLinkQuality.rLq[ucBssIndex].cRssi; + if (scanInDecidingRoaming(prAdapter, ucBssIndex) && + rssi > GOOD_RSSI_FOR_HT_VHT - 5) { + struct BSS_DESC *target; + struct BSS_DESC *bss; + + /* Good rssi but beacon timeout happened => PER */ + target = aisGetTargetBssDesc(prAdapter, ucBssIndex); + bss = scanSearchBssDescByScoreForAis(prAdapter, + ROAMING_REASON_TX_ERR, ucBssIndex); + if (bss && UNEQUAL_MAC_ADDR(bss->aucBSSID, target->aucBSSID)) { + log_dbg(SCN, INFO, "Better AP for beacon timeout"); + return TRUE; + } + } + + return FALSE; +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/assoc.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/assoc.c new file mode 100644 index 0000000000000000000000000000000000000000..0b2938d22f9b5d9bfec97fcb73da7709585ae2b6 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/assoc.c @@ -0,0 +1,2146 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/assoc.c#5 + */ + +/*! \file "assoc.c" + * \brief This file includes the association-related functions. + * + * This file includes the association-related functions. + */ + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ +struct APPEND_VAR_IE_ENTRY txAssocReqIETable[] = { + {0, assocCalculateConnIELen, assocGenerateConnIE} + , /* supplicant connect IE including rsn */ +#if CFG_SUPPORT_SPEC_MGMT || CFG_SUPPORT_802_11K + {(ELEM_HDR_LEN + ELEM_MAX_LEN_POWER_CAP), + NULL, rlmReqGeneratePowerCapIE} + , /* 33 */ +#endif +#if CFG_SUPPORT_SPEC_MGMT + {(ELEM_HDR_LEN + ELEM_MAX_LEN_SUPPORTED_CHANNELS), + NULL, rlmReqGenerateSupportedChIE} + , /* 36 */ +#endif + {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP), NULL, rlmReqGenerateHtCapIE} + , /* 45 */ +#if CFG_SUPPORT_802_11R + {(ELEM_HDR_LEN + 1), NULL, assocGenerateMDIE}, /* Element ID: 54 */ + {0, rsnCalculateFTIELen, rsnGenerateFTIE}, /* Element ID: 55 */ +#endif +#if CFG_SUPPORT_802_11K + {(ELEM_HDR_LEN + 5), NULL, + rrmGenerateRRMEnabledCapIE}, /* Element ID: 70 */ +#endif + {(ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP), NULL, rlmReqGenerateExtCapIE} + , /* 127 */ + {(ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_INFO), NULL, mqmGenerateWmmInfoIE} + , /* 221 */ + {(ELEM_HDR_LEN + ELEM_MAX_LEN_RSN + 4), NULL, rsnGenerateRSNIE} + , /* 48 */ +#if CFG_SUPPORT_802_11AC + {(ELEM_HDR_LEN + ELEM_MAX_LEN_VHT_CAP), NULL, rlmReqGenerateVhtCapIE} + , /*191 */ + {(ELEM_HDR_LEN + ELEM_MAX_LEN_VHT_OP_MODE_NOTIFICATION), NULL, + rlmReqGenerateVhtOpNotificationIE} + , /*199 */ +#endif +#if (CFG_SUPPORT_802_11AX == 1) + {(0), heRlmCalculateHeCapIELen, heRlmReqGenerateHeCapIE} + , /* 255, EXT 35 */ +#endif +#if CFG_SUPPORT_MTK_SYNERGY + {(ELEM_HDR_LEN + ELEM_MIN_LEN_MTK_OUI), NULL, rlmGenerateMTKOuiIE} + , /* 221 */ +#endif + {(ELEM_HDR_LEN + ELEM_MAX_LEN_WPA), NULL, rsnGenerateWPAIE} + /* 221 */ +}; + +#if CFG_SUPPORT_AAA +struct VERIFY_IE_ENTRY rxAssocReqIETable[] = { + {ELEM_ID_RESERVED, NULL} /* 255 */ +}; + +struct APPEND_VAR_IE_ENTRY txAssocRespIETable[] = { + {(ELEM_HDR_LEN + ELEM_MAX_LEN_ERP), NULL, rlmRspGenerateErpIE} + , /* 42 */ + {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP), NULL, rlmRspGenerateHtCapIE} + , /* 45 */ + {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP), NULL, rlmRspGenerateHtOpIE} + , /* 61 */ +#if CFG_ENABLE_WIFI_DIRECT + {(ELEM_HDR_LEN + ELEM_MAX_LEN_OBSS_SCAN), NULL, + rlmRspGenerateObssScanIE} + , /* 74 */ + {(0), p2pFuncCalculateP2p_IELenForAssocRsp, + p2pFuncGenerateP2p_IEForAssocRsp} + , /* 221 */ +#if (CFG_SUPPORT_WFD) + {(0), wfdFuncCalculateWfdIELenForAssocRsp, + wfdFuncGenerateWfdIEForAssocRsp} + , /* 221 */ +#endif +#endif + {(ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP), NULL, rlmRspGenerateExtCapIE} + , /* 127 */ +#if CFG_SUPPORT_802_11AC + {(ELEM_HDR_LEN + ELEM_MAX_LEN_VHT_CAP), NULL, rlmRspGenerateVhtCapIE} + , /*191 */ + {(ELEM_HDR_LEN + ELEM_MAX_LEN_VHT_OP), NULL, rlmRspGenerateVhtOpIE} + , /*192 */ + {(ELEM_HDR_LEN + ELEM_MAX_LEN_VHT_OP_MODE_NOTIFICATION), NULL, + rlmRspGenerateVhtOpNotificationIE} + , /*199 */ +#endif +#if CFG_SUPPORT_802_11AX + {0, heRlmCalculateHeCapIELen, heRlmRspGenerateHeCapIE} + , /* 255, EXT 35 */ + {0, heRlmCalculateHeOpIELen, heRlmRspGenerateHeOpIE} + , /* 255, EXT 36 */ +#endif + {(ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_PARAM), NULL, mqmGenerateWmmParamIE} + , /* 221 */ + {(ELEM_HDR_LEN + ELEM_MAX_LEN_ASSOC_RSP_WSC_IE), NULL, + rsnGenerateWSCIEForAssocRsp} + , /* 221 */ +#if CFG_SUPPORT_MTK_SYNERGY + {(ELEM_HDR_LEN + ELEM_MIN_LEN_MTK_OUI), NULL, rlmGenerateMTKOuiIE} + /* 221 */ +#endif + , +#if CFG_SUPPORT_802_11W + {(ELEM_HDR_LEN + ELEM_MAX_LEN_TIMEOUT_IE), NULL, + rsnPmfGenerateTimeoutIE} + /* 56 */ +#endif + +}; +#endif /* CFG_SUPPORT_AAA */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is used to compose the Capability Info Field. + * + * @param[in] prStaRec Pointer to the STA_RECORD_T + * + * @retval Capability Info Field + */ +/*----------------------------------------------------------------------------*/ + +uint16_t assocBuildCapabilityInfo(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec) +{ + uint32_t u4NonHTPhyType; + uint16_t u2CapInfo; + struct BSS_INFO *prBssInfo; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex); + + /* Set up our requested capabilities. */ + u2CapInfo = CAP_INFO_ESS; + u2CapInfo |= CAP_CF_STA_NOT_POLLABLE; +#if CFG_SUPPORT_802_11K + u2CapInfo |= CAP_INFO_RADIO_MEASUREMENT; +#endif + + if (prStaRec->u2CapInfo & CAP_INFO_PRIVACY) + u2CapInfo |= CAP_INFO_PRIVACY; + + /* 7.3.1.4 */ + if (prStaRec->fgHasBasicPhyType) { + u4NonHTPhyType = prStaRec->ucNonHTBasicPhyType; + + if ((rNonHTPhyAttributes + [u4NonHTPhyType].fgIsShortPreambleOptionImplemented) && + /* Short Preamble Option Enable is TRUE */ + ((prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_SHORT) + || + ((prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_AUTO) + && (prStaRec->u2CapInfo & CAP_INFO_SHORT_PREAMBLE)))) { + + /* Case I: Implemented == TRUE + * and Short Preamble Option Enable == TRUE. + * Case II: Implemented == TRUE + * and Short Preamble == AUTO (depends on + * struct BSS_DESC's capability) + */ + u2CapInfo |= CAP_INFO_SHORT_PREAMBLE; + } +#if CFG_SUPPORT_SPEC_MGMT + /* 802.11h spectrum management is for 5G band, so + * now we only enable spectrum management bit for 5G case. + * In TGn 5.2.22, spectrum management bit should set to 1 + * to pass the UCC's check. + */ + if (prBssInfo && prBssInfo->eBand == BAND_5G) + u2CapInfo |= CAP_INFO_SPEC_MGT; +#endif + + if (rNonHTPhyAttributes + [u4NonHTPhyType].fgIsShortSlotTimeOptionImplemented + && prAdapter->rWifiVar.fgIsShortSlotTimeOptionEnable) { + u2CapInfo |= CAP_INFO_SHORT_SLOT_TIME; + } + } + + DBGLOG(SAA, LOUD, + "ASSOC REQ: Compose Capability = 0x%04x for Target BSS [" MACSTR + "].\n", u2CapInfo, MAC2STR(prStaRec->aucMacAddr)); + + return u2CapInfo; + +} /* end of assocBuildCapabilityInfo() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is used to compose Common Information Elements for + * Association Request Frame. + * + * @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +static __KAL_INLINE__ void assocBuildReAssocReqFrameCommonIEs( + IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo) +{ + struct CONNECTION_SETTINGS *prConnSettings; + struct STA_RECORD *prStaRec; + uint8_t *pucBuffer; + uint16_t u2SupportedRateSet; + uint8_t aucAllSupportedRates[RATE_NUM_SW] = { 0 }; + uint8_t ucAllSupportedRatesLen; + uint8_t ucSupRatesLen; + uint8_t ucExtSupRatesLen; + + prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); + + if (!prStaRec) + return; + + pucBuffer = + (uint8_t *) ((unsigned long)prMsduInfo->prPacket + + (unsigned long)prMsduInfo->u2FrameLength); + + prConnSettings = + aisGetConnSettings(prAdapter, prStaRec->ucBssIndex); + + if (IS_STA_IN_AIS(prStaRec)) { + + /* Fill the SSID element. */ + SSID_IE(pucBuffer)->ucId = ELEM_ID_SSID; + + /* NOTE(Kevin): We copy the SSID from CONNECTION_SETTINGS + * for the case of Passive Scan and + * the target BSS didn't broadcast SSID on its Beacon Frame. + */ + COPY_SSID(SSID_IE(pucBuffer)->aucSSID, + SSID_IE(pucBuffer)->ucLength, + prConnSettings->aucSSID, + prConnSettings->ucSSIDLen); + + prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); + pucBuffer += IE_SIZE(pucBuffer); + + } +#if CFG_ENABLE_WIFI_DIRECT + else if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) + pucBuffer = + p2pBuildReAssocReqFrameCommonIEs(prAdapter, prMsduInfo, + pucBuffer); + +#endif +#if CFG_ENABLE_BT_OVER_WIFI + else if (IS_STA_BOW_TYPE(prStaRec)) { + + SSID_IE(pucBuffer)->ucId = ELEM_ID_SSID; + + /* NOTE(Kevin): We copy the SSID from CONNECTION_SETTINGS + * for the case of Passive Scan and + * the target BSS didn't broadcast SSID on its Beacon Frame. + */ + COPY_SSID(SSID_IE(pucBuffer)->aucSSID, + SSID_IE(pucBuffer)->ucLength, + prConnSettings->aucSSID, + prConnSettings->ucSSIDLen); + + prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); + pucBuffer += IE_SIZE(pucBuffer); + } +#endif + + /* NOTE(Kevin 2008/12/19): 16.3.6.3 MLME-ASSOCIATE.indication - + * SupportedRates - The set of data rates that are supported by the STA + * that is requesting association. + * Original(Portable Driver): Only send the Rates that we'll support. + * New: Send the Phy Rates if the result of following + * & operation == NULL. + */ + /* rateGetDataRatesFromRateSet((prBssDesc->u2OperationalRateSet & */ + /* rPhyAttributes[prBssDesc->ePhyType].u2SupportedRateSet), */ + + if (prStaRec->ucDesiredPhyTypeSet) { + uint32_t u4NonHTPhyType; + + u4NonHTPhyType = prStaRec->ucNonHTBasicPhyType; + + u2SupportedRateSet = (prStaRec->u2OperationalRateSet & + rNonHTPhyAttributes + [u4NonHTPhyType].u2SupportedRateSet); + + if (!u2SupportedRateSet) { + DBGLOG(SAA, INFO, + "RateSet NonHTPhyType=%d OperationalRateSet=%d\n", + u4NonHTPhyType, prStaRec->u2OperationalRateSet); + u2SupportedRateSet = + rNonHTPhyAttributes + [u4NonHTPhyType].u2SupportedRateSet; + } + + /* TODO(Kevin): + * For P2P, we shouldn't send support rate set + * which contains 11b rate + */ + + rateGetDataRatesFromRateSet(u2SupportedRateSet, 0, + aucAllSupportedRates, + &ucAllSupportedRatesLen); + + ucSupRatesLen = + ((ucAllSupportedRatesLen > + ELEM_MAX_LEN_SUP_RATES) ? ELEM_MAX_LEN_SUP_RATES : + ucAllSupportedRatesLen); + + ucExtSupRatesLen = ucAllSupportedRatesLen - ucSupRatesLen; + + /* Fill the Supported Rates element. */ + if (ucSupRatesLen) { + SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_SUP_RATES; + SUP_RATES_IE(pucBuffer)->ucLength = ucSupRatesLen; + kalMemCopy(SUP_RATES_IE(pucBuffer)->aucSupportedRates, + aucAllSupportedRates, ucSupRatesLen); + + prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); + pucBuffer += IE_SIZE(pucBuffer); + } + + /* Fill the Extended Supported Rates element. */ + if (ucExtSupRatesLen) { + + EXT_SUP_RATES_IE(pucBuffer)->ucId = + ELEM_ID_EXTENDED_SUP_RATES; + EXT_SUP_RATES_IE(pucBuffer)->ucLength = + ucExtSupRatesLen; + + kalMemCopy(EXT_SUP_RATES_IE + (pucBuffer)->aucExtSupportedRates, + &aucAllSupportedRates[ucSupRatesLen], + ucExtSupRatesLen); + + prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); + pucBuffer += IE_SIZE(pucBuffer); + } + } +} /* end of assocBuildReAssocReqFrameCommonIEs() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will compose the (Re)Association Request frame header + * and its fixed fields + * + * @param[in] prStaRec Pointer to the STA_RECORD_T + * @param[in] pucBuffer Pointer to the frame buffer. + * @param[in] aucMACAddress Given Our MAC Address. + * @param[in out] pu2PayloadLen Return the length of the composed + * fixed fields + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void +assocComposeReAssocReqFrameHeaderAndFF(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, + IN uint8_t *pucBuffer, + IN uint8_t aucMACAddress[], + IN OUT uint16_t *pu2PayloadLen) +{ + struct WLAN_ASSOC_REQ_FRAME *prAssocFrame; + u_int8_t fgIsReAssoc; + + uint16_t u2FrameCtrl; + uint16_t u2CapInfo; + uint16_t u2ListenInterval; + + prAssocFrame = (struct WLAN_ASSOC_REQ_FRAME *)pucBuffer; + fgIsReAssoc = prStaRec->fgIsReAssoc; + + /* 4 <1> Compose the frame header of the (Re)Association + * Request frame. + */ + /* Fill the Frame Control field. */ + if (fgIsReAssoc) + u2FrameCtrl = MAC_FRAME_REASSOC_REQ; + else + u2FrameCtrl = MAC_FRAME_ASSOC_REQ; + + WLAN_SET_FIELD_16(&prAssocFrame->u2FrameCtrl, u2FrameCtrl); + + /* Fill the DA field with Target BSSID. */ + COPY_MAC_ADDR(prAssocFrame->aucDestAddr, prStaRec->aucMacAddr); + + /* Fill the SA field with our MAC Address. */ + COPY_MAC_ADDR(prAssocFrame->aucSrcAddr, aucMACAddress); + + /* Fill the BSSID field with Target BSSID. */ + COPY_MAC_ADDR(prAssocFrame->aucBSSID, prStaRec->aucMacAddr); + + /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, + * so we need to clear it). + */ + prAssocFrame->u2SeqCtrl = 0; + + /* 4 <2> Compose the frame body's common fixed field part of + * the (Re)Association Request frame. + */ + u2CapInfo = assocBuildCapabilityInfo(prAdapter, prStaRec); + + /* Fill the Capability Information field. */ + WLAN_SET_FIELD_16(&prAssocFrame->u2CapInfo, u2CapInfo); + + /* Calculate the listen interval for the maximum power mode. Currently, + * we set it to the value 2 times DTIM period. + */ + if (prStaRec->ucDTIMPeriod) { + u2ListenInterval = + prStaRec->ucDTIMPeriod * + DEFAULT_LISTEN_INTERVAL_BY_DTIM_PERIOD; + } else { + DBGLOG(SAA, TRACE, "Use default listen interval\n"); + u2ListenInterval = DEFAULT_LISTEN_INTERVAL; + } + prStaRec->u2ListenInterval = u2ListenInterval; + + /* Fill the Listen Interval field. */ + WLAN_SET_FIELD_16(&prAssocFrame->u2ListenInterval, u2ListenInterval); + + /* 4 <3> Compose the Current AP Address field for ReAssociation + * Request frame. + */ + /* Fill the Current AP Address field. */ + if (prStaRec->fgIsReAssoc) { + if (IS_STA_IN_AIS(prStaRec)) { + + struct BSS_INFO *prAisBssInfo = + aisGetAisBssInfo(prAdapter, + prStaRec->ucBssIndex); + struct WLAN_REASSOC_REQ_FRAME *prReAssocFrame = + (struct WLAN_REASSOC_REQ_FRAME *)prAssocFrame; + + COPY_MAC_ADDR(prReAssocFrame->aucCurrentAPAddr, + prAisBssInfo->aucBSSID); + } else { + ASSERT(0); + /* We don't support ReAssociation for other network */ + } + + *pu2PayloadLen = + (CAP_INFO_FIELD_LEN + LISTEN_INTERVAL_FIELD_LEN + + CURR_AP_ADDR_FIELD_LEN); + } else { + *pu2PayloadLen = + (CAP_INFO_FIELD_LEN + LISTEN_INTERVAL_FIELD_LEN); + } +} /* end of assocComposeReAssocReqFrame() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will send the (Re)Association Request frame + * + * @param[in] prStaRec Pointer to the STA_RECORD_T + * + * @retval WLAN_STATUS_RESOURCES No available resource for frame composing. + * @retval WLAN_STATUS_SUCCESS Successfully send frame to TX Module + */ +/*----------------------------------------------------------------------------*/ +uint32_t assocSendReAssocReqFrame(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec) +{ + struct MSDU_INFO *prMsduInfo; + struct BSS_INFO *prBssInfo; + + uint16_t u2PayloadLen; + uint16_t u2EstimatedFrameLen; + uint16_t u2EstimatedExtraIELen; + u_int8_t fgIsReAssoc; + uint32_t i; + uint16_t txAssocReqIENums; + + /* 4 <1> Allocate a PKT_INFO_T for Authentication Frame */ + fgIsReAssoc = prStaRec->fgIsReAssoc; + + /* Init with MGMT Header Length + Length of Fixed Fields + * + Common IE Length + */ + if (fgIsReAssoc) { + u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + + WLAN_MAC_MGMT_HEADER_LEN + + CAP_INFO_FIELD_LEN + + LISTEN_INTERVAL_FIELD_LEN + + CURR_AP_ADDR_FIELD_LEN + + (ELEM_HDR_LEN + ELEM_MAX_LEN_SSID) + + (ELEM_HDR_LEN + ELEM_MAX_LEN_SUP_RATES) + (ELEM_HDR_LEN + + (RATE_NUM_SW - ELEM_MAX_LEN_SUP_RATES)); + } else { + u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + + WLAN_MAC_MGMT_HEADER_LEN + + CAP_INFO_FIELD_LEN + + LISTEN_INTERVAL_FIELD_LEN + + (ELEM_HDR_LEN + ELEM_MAX_LEN_SSID) + + (ELEM_HDR_LEN + ELEM_MAX_LEN_SUP_RATES) + (ELEM_HDR_LEN + + (RATE_NUM_SW - ELEM_MAX_LEN_SUP_RATES)); + } + + /* + Extra IE Length */ + u2EstimatedExtraIELen = 0; + txAssocReqIENums = sizeof(txAssocReqIETable) / + sizeof(struct APPEND_VAR_IE_ENTRY); + +#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 && CFG_ENABLE_WIFI_DIRECT + if (IS_STA_IN_P2P(prStaRec)) { + if ((prAdapter->fgIsP2PRegistered)) { + u2EstimatedExtraIELen = + p2pCalculate_IEForAssocReq(prAdapter, + prStaRec->ucBssIndex, + prStaRec); + } else { + DBGLOG(P2P, TRACE, "Function Linker Lost.\n"); + ASSERT(FALSE); + } + } else { + for (i = 0; i < txAssocReqIENums; i++) { + if (txAssocReqIETable[i].u2EstimatedFixedIELen != 0) { + u2EstimatedExtraIELen += + txAssocReqIETable[i].u2EstimatedFixedIELen; + } else { + u2EstimatedExtraIELen += (uint16_t) + txAssocReqIETable + [i].pfnCalculateVariableIELen(prAdapter, + prStaRec->ucBssIndex, prStaRec); + } + } + /* Calculate non-wfa vendor specific ie len */ + u2EstimatedExtraIELen += + assoc_get_nonwfa_vend_ie_len(prAdapter, + prStaRec->ucBssIndex); + } +#else + for (i = 0; i < txAssocReqIENums; i++) { + if (txAssocReqIETable[i].u2EstimatedFixedIELen != 0) { + u2EstimatedExtraIELen += + txAssocReqIETable[i].u2EstimatedFixedIELen; + } else { + u2EstimatedExtraIELen += (uint16_t) + txAssocReqIETable[i].pfnCalculateVariableIELen + (prAdapter, prStaRec->ucBssIndex, prStaRec); + } + } + /* Calculate non-wfa vendor specific ie len */ + u2EstimatedExtraIELen += assoc_get_nonwfa_vend_ie_len(prAdapter, + prStaRec->ucBssIndex); +#endif + u2EstimatedFrameLen += u2EstimatedExtraIELen; + + /* Allocate a MSDU_INFO_T */ + prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); + if (prMsduInfo == NULL) { + DBGLOG(SAA, WARN, + "No PKT_INFO_T for sending (Re)Assoc Request.\n"); + return WLAN_STATUS_RESOURCES; + } + /* 4 <2> Compose (Re)Association Request frame header and fixed fields + * in MSDU_INfO_T. + */ + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex); + + /* Compose Header and Fixed Field */ + assocComposeReAssocReqFrameHeaderAndFF(prAdapter, + prStaRec, + (uint8_t + *) ((unsigned + long)(prMsduInfo->prPacket) + + MAC_TX_RESERVED_FIELD), + prBssInfo->aucOwnMacAddr, + &u2PayloadLen); + + /* 4 <3> Update information of MSDU_INFO_T */ + nicTxSetPktLifeTime(prMsduInfo, 100); + nicTxSetPktRetryLimit(prMsduInfo, TX_DESC_TX_COUNT_NO_LIMIT); + nicTxSetForceRts(prMsduInfo, TRUE); + + TX_SET_MMPDU(prAdapter, + prMsduInfo, + prStaRec->ucBssIndex, + prStaRec->ucIndex, + WLAN_MAC_MGMT_HEADER_LEN, + WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen, + saaFsmRunEventTxDone, MSDU_RATE_MODE_AUTO); + + /* 4 <4> Compose the frame body's IEs of the (Re)Association Request + * frame. + */ + assocBuildReAssocReqFrameCommonIEs(prAdapter, prMsduInfo); + + /* 4 <5> Compose IEs in MSDU_INFO_T */ +#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 && CFG_ENABLE_WIFI_DIRECT + if (IS_STA_IN_P2P(prStaRec)) { + if ((prAdapter->fgIsP2PRegistered)) { + p2pGenerate_IEForAssocReq(prAdapter, prMsduInfo); + } else { + DBGLOG(P2P, TRACE, "Function Linker Lost.\n"); + ASSERT(FALSE); + } + } else { + /* Append IE */ + for (i = 0; i < txAssocReqIENums; i++) { + if (txAssocReqIETable[i].pfnAppendIE) + txAssocReqIETable[i].pfnAppendIE(prAdapter, + prMsduInfo); + } + /* Append non-wfa vendor specific ies for AIS mode */ + assoc_build_nonwfa_vend_ie(prAdapter, prMsduInfo); + } +#else + /* Append IE */ + for (i = 0; i < txAssocReqIENums; i++) { + if (txAssocReqIETable[i].pfnAppendIE) + txAssocReqIETable[i].pfnAppendIE(prAdapter, prMsduInfo); + } + /* Append non-wfa vendor specific ies for AIS mode */ + assoc_build_nonwfa_vend_ie(prAdapter, prMsduInfo); +#endif + + /* 4 <6> Update the (Re)association request information */ + if (IS_STA_IN_AIS(prStaRec)) { + struct WLAN_ASSOC_REQ_FRAME *prAssocFrame; + + prAssocFrame = + (struct WLAN_ASSOC_REQ_FRAME + *)((unsigned long)(prMsduInfo->prPacket) + + MAC_TX_RESERVED_FIELD); + + kalUpdateReAssocReqInfo(prAdapter->prGlueInfo, + (uint8_t *) &prAssocFrame->u2CapInfo, + prMsduInfo->u2FrameLength - + offsetof(struct WLAN_ASSOC_REQ_FRAME, + u2CapInfo), fgIsReAssoc, + prStaRec->ucBssIndex); + } +#if CFG_ENABLE_WIFI_DIRECT + if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) { + struct WLAN_ASSOC_REQ_FRAME *prAssocFrame; + + prAssocFrame = + (struct WLAN_ASSOC_REQ_FRAME + *)((unsigned long)(prMsduInfo->prPacket) + + MAC_TX_RESERVED_FIELD); + + kalP2PUpdateAssocInfo(prAdapter->prGlueInfo, + (uint8_t *) &prAssocFrame->u2CapInfo, + prMsduInfo->u2FrameLength - + offsetof(struct WLAN_ASSOC_REQ_FRAME, + u2CapInfo), fgIsReAssoc, + prStaRec->ucBssIndex); + } +#endif + + /* TODO(Kevin): Also release the unused tail room of the composed MMPDU + */ + + nicTxConfigPktControlFlag(prMsduInfo, MSDU_CONTROL_FLAG_FORCE_TX, TRUE); + + /* 4 <6> Enqueue the frame to send this (Re)Association request frame. + */ + nicTxEnqueueMsdu(prAdapter, prMsduInfo); + + return WLAN_STATUS_SUCCESS; +} /* end of assocSendReAssocReqFrame() */ + + +uint32_t assocCalculateConnIELen(struct ADAPTER *prAdapter, uint8_t ucBssIdx, + struct STA_RECORD *prStaRec) +{ + struct CONNECTION_SETTINGS *prConnSettings; + uint8_t ucBssIndex; + const uint8_t *rsnConn; + + ucBssIndex = prStaRec->ucBssIndex; + prConnSettings = aisGetConnSettings(prAdapter, ucBssIndex); + + if (IS_STA_IN_AIS(prStaRec) && prConnSettings->assocIeLen > 0) { + prConnSettings = aisGetConnSettings(prAdapter, ucBssIdx); + rsnConn = kalFindIeMatchMask(ELEM_ID_RSN, + prConnSettings->pucAssocIEs, + prConnSettings->assocIeLen, + NULL, 0, 0, NULL); + /* cut out RSN IE */ + if (rsnConn) + return prConnSettings->assocIeLen - + ELEM_HDR_LEN - RSN_IE(rsnConn)->ucLength; + else + return prConnSettings->assocIeLen; + } + + return 0; +} + +void assocGenerateConnIE(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo) +{ + struct CONNECTION_SETTINGS *prConnSettings; + struct STA_RECORD *prStaRec; + uint8_t *pucBuffer, *cp; + const uint8_t *rsnConn; + const uint8_t *extCapConn; + uint8_t ucBssIndex; + uint32_t len, rsnIeLen; + uint32_t extCapIeLen; + + prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); + if (!prStaRec) + return; + + pucBuffer = (uint8_t *) ((unsigned long) + prMsduInfo->prPacket + (unsigned long) + prMsduInfo->u2FrameLength); + cp = pucBuffer; + ucBssIndex = prStaRec->ucBssIndex; + prConnSettings = aisGetConnSettings(prAdapter, ucBssIndex); + + if (IS_STA_IN_AIS(prStaRec) && prConnSettings->assocIeLen > 0) { + kalMemCopy(cp, prConnSettings->pucAssocIEs, + prConnSettings->assocIeLen); + cp += prConnSettings->assocIeLen; + + rsnConn = kalFindIeMatchMask(ELEM_ID_RSN, + pucBuffer, + cp - pucBuffer, + NULL, 0, 0, NULL); + + if (rsnConn) { + rsnIeLen = IE_SIZE(rsnConn); + + len = cp - rsnConn - rsnIeLen; + /* copy to the start of RSN IE*/ + cp = (char *) rsnConn; + /* jump to the end of RSN IE to copy Remaing IEs*/ + kalMemCopy(cp, rsnConn + rsnIeLen, len); + cp += len; + } + + extCapConn = kalFindIeMatchMask(ELEM_ID_EXTENDED_CAP, + pucBuffer, + cp - pucBuffer, + NULL, 0, 0, NULL); + + if (extCapConn) { + extCapIeLen = IE_SIZE(extCapConn); + + len = cp - extCapConn - extCapIeLen; + /* copy to the start of EXT CAP IE*/ + cp = (char *) extCapConn; + /* jump to the end of EXT CAP IE to copy remaing IEs */ + kalMemCopy(cp, extCapConn + extCapIeLen, len); + cp += len; + } + + } + prMsduInfo->u2FrameLength += cp - pucBuffer; + DBGLOG_MEM8(SAA, INFO, pucBuffer, cp - pucBuffer); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will strictly check the TX (Re)Association Request + * frame for SAA event handling. + * + * @param[in] prMsduInfo Pointer of MSDU_INFO_T + * + * @retval WLAN_STATUS_FAILURE This is not the frame we should handle + * at current state. + * @retval WLAN_STATUS_SUCCESS This is the frame we should handle. + */ +/*----------------------------------------------------------------------------*/ +uint32_t assocCheckTxReAssocReqFrame(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo) +{ + struct WLAN_ASSOC_REQ_FRAME *prAssocReqFrame; + struct STA_RECORD *prStaRec; + uint16_t u2TxFrameCtrl; + + prAssocReqFrame = (struct WLAN_ASSOC_REQ_FRAME *)(prMsduInfo->prPacket); + prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); + if (!prStaRec) + return WLAN_STATUS_INVALID_PACKET; + + /* WLAN_GET_FIELD_16(&prAssocReqFrame->u2FrameCtrl, &u2TxFrameCtrl) */ + u2TxFrameCtrl = prAssocReqFrame->u2FrameCtrl; + /* NOTE(Kevin): Optimized for ARM */ + u2TxFrameCtrl &= MASK_FRAME_TYPE; + if (prStaRec->fgIsReAssoc) { + if (u2TxFrameCtrl != MAC_FRAME_REASSOC_REQ) + return WLAN_STATUS_FAILURE; + + } else { + if (u2TxFrameCtrl != MAC_FRAME_ASSOC_REQ) + return WLAN_STATUS_FAILURE; + + } + + return WLAN_STATUS_SUCCESS; + +} /* end of assocCheckTxReAssocReqFrame() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will strictly check the TX (Re)Association Response + * frame for AAA event handling. + * + * @param[in] prMsduInfo Pointer of MSDU_INFO_T + * + * @retval WLAN_STATUS_FAILURE This is not the frame we should handle + * at current state. + * @retval WLAN_STATUS_SUCCESS This is the frame we should handle. + */ +/*----------------------------------------------------------------------------*/ +uint32_t assocCheckTxReAssocRespFrame(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo) +{ + struct WLAN_ASSOC_RSP_FRAME *prAssocRspFrame; + struct STA_RECORD *prStaRec; + uint16_t u2TxFrameCtrl; + + prAssocRspFrame = (struct WLAN_ASSOC_RSP_FRAME *)(prMsduInfo->prPacket); + prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); + if (!prStaRec) + return WLAN_STATUS_INVALID_PACKET; + + /* WLAN_GET_FIELD_16(&prAssocFrame->u2FrameCtrl, &u2TxFrameCtrl) */ + u2TxFrameCtrl = prAssocRspFrame->u2FrameCtrl; + /* NOTE(Kevin): Optimized for ARM */ + u2TxFrameCtrl &= MASK_FRAME_TYPE; + if (prStaRec->fgIsReAssoc) { + if (u2TxFrameCtrl != MAC_FRAME_REASSOC_RSP) + return WLAN_STATUS_FAILURE; + + } else { + if (u2TxFrameCtrl != MAC_FRAME_ASSOC_RSP) + return WLAN_STATUS_FAILURE; + + } + + return WLAN_STATUS_SUCCESS; + +} /* end of assocCheckTxReAssocRespFrame() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will validate the incoming (Re)Association Frame + * and take out the status code. + * + * @param[in] prSwRfb Pointer to SW RFB data structure. + * @param[out] pu2StatusCode Pointer to store the Status Code + * from Authentication. + * + * @retval WLAN_STATUS_FAILURE This is not the frame we should handle + * at current state. + * @retval WLAN_STATUS_SUCCESS This is the frame we should handle. + */ +/*----------------------------------------------------------------------------*/ +uint32_t +assocCheckRxReAssocRspFrameStatus(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, + OUT uint16_t *pu2StatusCode) +{ + struct STA_RECORD *prStaRec; + struct WLAN_ASSOC_RSP_FRAME *prAssocRspFrame; + uint16_t u2RxFrameCtrl; + uint16_t u2RxCapInfo; + uint16_t u2RxStatusCode; + uint16_t u2RxAssocId; + + if (!prSwRfb || !pu2StatusCode) { + DBGLOG(SAA, ERROR, "Invalid parameter, ignore!\n"); + return WLAN_STATUS_FAILURE; + } + + if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < + (CAP_INFO_FIELD_LEN + + STATUS_CODE_FIELD_LEN + + AID_FIELD_LEN)) { + DBGLOG(SAA, WARN, "Invalid AssocRsp length!"); + return WLAN_STATUS_FAILURE; + } + + DBGLOG(SAA, LOUD, "prSwRfb->u2PayloadLength = %d\n", + prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen); + + prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); + if (!prStaRec) { + DBGLOG(SAA, ERROR, "Invalid prStaRec, ignore!\n"); + return WLAN_STATUS_INVALID_PACKET; + } + + /* 4 <1> locate the (Re)Association Resp Frame. */ + prAssocRspFrame = (struct WLAN_ASSOC_RSP_FRAME *)prSwRfb->pvHeader; + + /* If Association Response's BSSID doesn't match + * our target, ignore. + */ + if (!EQUAL_MAC_ADDR(prAssocRspFrame->aucBSSID, + prStaRec->aucMacAddr)) { + DBGLOG(SAA, INFO, "Unknown BSSID\n"); + return WLAN_STATUS_FAILURE; + } + + /* 4 <2> Parse the Header of (Re)Association Resp Frame. */ + /* WLAN_GET_FIELD_16(&prAssocRspFrame->u2FrameCtrl, &u2RxFrameCtrl); */ + u2RxFrameCtrl = prAssocRspFrame->u2FrameCtrl; + /* NOTE(Kevin): Optimized for ARM */ + u2RxFrameCtrl &= MASK_FRAME_TYPE; + if (prStaRec->fgIsReAssoc) { + if (u2RxFrameCtrl != MAC_FRAME_REASSOC_RSP) + return WLAN_STATUS_FAILURE; + + } else { + if (u2RxFrameCtrl != MAC_FRAME_ASSOC_RSP) + return WLAN_STATUS_FAILURE; + + } + + /* 4 <3> Parse the Fixed Fields of (Re)Association Resp Frame Body. */ + /* WLAN_GET_FIELD_16(&prAssocRspFrame->u2CapInfo, &u2RxCapInfo); */ + u2RxCapInfo = prAssocRspFrame->u2CapInfo; + /* NOTE(Kevin): Optimized for ARM */ + + /* WLAN_GET_FIELD_16(&prAssocRspFrame->u2StatusCode, &u2RxStatusCode); + */ + u2RxStatusCode = prAssocRspFrame->u2StatusCode; + /* NOTE(Kevin): Optimized for ARM */ + + /* 4 <4> Check CAP_INFO */ + /* NOTE(Kevin): CM suggest to add MGMT workaround for those APs + * didn't check the CAP Privacy Bit to overcome a corner case + * that the Privacy Bit of our SCAN result didn't consist with + * AP's Association Resp. + */ + if (u2RxStatusCode == STATUS_CODE_SUCCESSFUL) { +#if CFG_SUPPORT_WAPI + if (aisGetWapiMode(prAdapter, prStaRec->ucBssIndex)) { + /* WAPI AP allow the customer use WZC to join mode, + * the privacy bit is 0 even at WAI & WAPI_PSK mode, + * but the assoc respose set the privacy bit set 1 + */ + DBGLOG(SEC, TRACE, + "Workaround the WAPI AP allow the customer to use WZC to join\n"); + } else +#endif +#if CFG_ENABLE_WIFI_DIRECT + if (prAdapter->fgIsP2PRegistered && 1) { + /* Todo:: Fixed this */ + } else +#endif + { + } + +#if CFG_STRICT_CHECK_CAPINFO_PRIVACY + if ((prStaRec->u2CapInfo & CAP_INFO_PRIVACY) ^ + (u2RxCapInfo & CAP_INFO_PRIVACY)) + u2RxStatusCode = STATUS_CODE_CAP_NOT_SUPPORTED; + +#endif + } + + if (u2RxStatusCode == STATUS_CODE_SUCCESSFUL) { + /* Update the information in the structure used to query and set + * OID_802_11_ASSOCIATION_INFORMATION. + */ + + kalUpdateReAssocRspInfo(prAdapter->prGlueInfo, + (uint8_t *) & + prAssocRspFrame->u2CapInfo, + prSwRfb->u2PacketLen - + prSwRfb->u2HeaderLen, + prStaRec->ucBssIndex); + } + /* 4 <5> Update CAP_INFO and ASSOC_ID */ + if (u2RxStatusCode == STATUS_CODE_SUCCESSFUL) { + prStaRec->u2CapInfo = u2RxCapInfo; + + /* WLAN_GET_FIELD_16(&prAssocRspFrame->u2AssocId, + * &u2RxAssocId); + */ + u2RxAssocId = prAssocRspFrame->u2AssocId; + /* NOTE(Kevin): Optimized for ARM */ + + /* 20110715 Workaround for Kingnet 710 AP (Realtek 8186) + * This AP raises the bit 6&7 not bit 14&15 in AID field. + * It cause wrong AID assignment. + * For AID = 2 + * Normal case: 0xC002(1100 0000 0000 0010) => 2 + * Kingnet 710: 0x00C2(0000 0000 1100 0010) => 194 + * workaround: mask bit 6&7 for this AP + */ + if ((u2RxAssocId & BIT(6)) && (u2RxAssocId & BIT(7)) + && !(u2RxAssocId & BITS(8, 15))) { + prStaRec->u2AssocId = u2RxAssocId & ~BITS(6, 7); + } else { + prStaRec->u2AssocId = u2RxAssocId & ~AID_MSB; +#if CFG_SUPPORT_802_11W + if (prStaRec->eStaType == STA_TYPE_LEGACY_AP) { + struct AIS_SPECIFIC_BSS_INFO *prBssSpecInfo; + + prBssSpecInfo = + aisGetAisSpecBssInfo(prAdapter, + prStaRec->ucBssIndex); + prBssSpecInfo->ucSaQueryTimedOut = 0; + } +#endif + } + } +#if CFG_SUPPORT_802_11W + if (u2RxStatusCode == STATUS_CODE_AUTH_ALGORITHM_NOT_SUPPORTED) { + DBGLOG(SAA, INFO, + "AP rejected due the authentication algorithm not support\n"); + } else if (u2RxStatusCode == STATUS_CODE_ASSOC_REJECTED_TEMPORARILY) { + uint8_t *pucIE, *pucTime; + uint16_t u2IELength; + uint16_t u2Offset = 0; + + u2IELength = prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen; + pucIE = + (uint8_t *) ((unsigned long)prSwRfb->pvHeader + + prSwRfb->u2HeaderLen); + + IE_FOR_EACH(pucIE, u2IELength, u2Offset) { + if (IE_ID(pucIE) == ELEM_ID_TIMEOUT_INTERVAL + && IE_LEN(pucIE) == 5) { + pucTime = ((struct IE_HDR *)pucIE)->aucInfo; + if (pucTime[0] == + ACTION_SA_TIMEOUT_ASSOC_COMEBACK) { + uint32_t tu; + + WLAN_GET_FIELD_32(pucTime + 1, &tu); + DBGLOG(SAA, INFO, + "AP rejected association temporarily;comeback duration %u TU (%u ms)\n", + tu, TU_TO_MSEC(tu)); + if (tu > + TX_ASSOCIATION_RETRY_TIMEOUT_TU) { + DBGLOG(SAA, INFO, + "Update timer based on comeback duration\n"); + /* ieee80211_reschedule_timer( + * wpa_s, ms); + */ + } + } + break; + } + } /* end of IE_FOR_EACH */ + } +#endif + *pu2StatusCode = u2RxStatusCode; + + return WLAN_STATUS_SUCCESS; + +} /* end of assocCheckRxReAssocRspFrameStatus() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function will compose the Disassociation frame + * + * @param[in] prStaRec Pointer to the STA_RECORD_T + * @param[in] pucBuffer Pointer to the frame buffer. + * @param[in] aucMACAddress Given Our MAC Address. + * @param[in] u2ReasonCode The reason code of disassociation + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +static __KAL_INLINE__ void +assocComposeDisassocFrame(IN struct STA_RECORD *prStaRec, + IN uint8_t *pucBuffer, IN uint8_t aucMACAddress[], + IN uint16_t u2ReasonCode) +{ + struct WLAN_DISASSOC_FRAME *prDisAssocFrame; + uint16_t u2FrameCtrl; + + prDisAssocFrame = (struct WLAN_DISASSOC_FRAME *)pucBuffer; + + /* 4 <1> Compose the frame header of the DisAssociation frame. */ + /* Fill the Frame Control field. */ + u2FrameCtrl = MAC_FRAME_DISASSOC; + + WLAN_SET_FIELD_16(&prDisAssocFrame->u2FrameCtrl, u2FrameCtrl); + + /* Fill the DA field with Target BSSID. */ + COPY_MAC_ADDR(prDisAssocFrame->aucDestAddr, prStaRec->aucMacAddr); + + /* Fill the SA field with our MAC Address. */ + COPY_MAC_ADDR(prDisAssocFrame->aucSrcAddr, aucMACAddress); + + /* Fill the BSSID field with Target BSSID. */ + COPY_MAC_ADDR(prDisAssocFrame->aucBSSID, prStaRec->aucMacAddr); + + /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, + * so we need to clear it). + */ + prDisAssocFrame->u2SeqCtrl = 0; + + /* 4 <2> Compose the frame body's fixed field part of + * the Disassociation frame. + */ + /* Fill the Reason Code field. */ + WLAN_SET_FIELD_16(&prDisAssocFrame->u2ReasonCode, u2ReasonCode); +} /* end of assocComposeDisassocFrame() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will send the Disassociation frame + * + * @param[in] prStaRec Pointer to the STA_RECORD_T + * @param[in] u2ReasonCode The reason code of disassociation + * + * @retval WLAN_STATUS_RESOURCES No available resource for frame composing. + * @retval WLAN_STATUS_SUCCESS Successfully send frame to TX Module + */ +/*----------------------------------------------------------------------------*/ +uint32_t assocSendDisAssocFrame(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, + IN uint16_t u2ReasonCode) +{ + uint8_t *pucMacAddress; + struct MSDU_INFO *prMsduInfo; + uint16_t u2PayloadLen; + uint16_t u2EstimatedFrameLen; + /* UINT_32 u4Status = WLAN_STATUS_SUCCESS; */ + + DBGLOG(RSN, INFO, "assocSendDisAssocFrame\n"); + + /* 4 <1> Allocate a PKT_INFO_T for Disassociation Frame */ + /* Init with MGMT Header Length + Length of Fixed Fields + IE Length */ + u2EstimatedFrameLen = + MAC_TX_RESERVED_FIELD + WLAN_MAC_MGMT_HEADER_LEN + + REASON_CODE_FIELD_LEN; + + /* Allocate a MSDU_INFO_T */ + prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); + if (prMsduInfo == NULL) { + DBGLOG(SAA, WARN, "No PKT_INFO_T for sending DisAssoc.\n"); + return WLAN_STATUS_RESOURCES; + } + /* 4 <2> Compose Disassociation frame header and fixed fields + * in MSDU_INfO_T. + */ + pucMacAddress = + GET_BSS_INFO_BY_INDEX(prAdapter, + prStaRec->ucBssIndex)->aucOwnMacAddr; + + /* Compose Header and Fixed Field */ + assocComposeDisassocFrame(prStaRec, + (uint8_t + *) ((unsigned long)(prMsduInfo->prPacket) + + MAC_TX_RESERVED_FIELD), pucMacAddress, + u2ReasonCode); + +#if CFG_SUPPORT_802_11W + /* AP PMF */ + if (rsnCheckBipKeyInstalled(prAdapter, prStaRec)) { + /* PMF certification 4.3.3.1, 4.3.3.2 send unprotected + * deauth reason 6/7 + */ + if (prStaRec->rPmfCfg.fgRxDeauthResp != TRUE) { + + struct WLAN_DISASSOC_FRAME *prDisassocFrame; + + prDisassocFrame = + (struct WLAN_DISASSOC_FRAME + *)((unsigned long)(prMsduInfo->prPacket) + + MAC_TX_RESERVED_FIELD); + + prDisassocFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME; + } + } +#endif + + u2PayloadLen = REASON_CODE_FIELD_LEN; + + /* 4 <3> Update information of MSDU_INFO_T */ + nicTxSetPktLifeTime(prMsduInfo, 100); + nicTxSetPktRetryLimit(prMsduInfo, TX_DESC_TX_COUNT_NO_LIMIT); + nicTxSetForceRts(prMsduInfo, TRUE); + + TX_SET_MMPDU(prAdapter, + prMsduInfo, + prStaRec->ucBssIndex, + prStaRec->ucIndex, + WLAN_MAC_MGMT_HEADER_LEN, + WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen, NULL, + MSDU_RATE_MODE_AUTO); + +#if CFG_SUPPORT_802_11W + /* AP PMF */ + /* caution: access prStaRec only if true */ + if (rsnCheckBipKeyInstalled(prAdapter, prStaRec)) { + /* 4.3.3.1 send unprotected deauth reason 6/7 */ + if (prStaRec->rPmfCfg.fgRxDeauthResp != TRUE) { + DBGLOG(RSN, INFO, + "Disassoc Set MSDU_OPT_PROTECTED_FRAME\n"); + nicTxConfigPktOption(prMsduInfo, + MSDU_OPT_PROTECTED_FRAME, TRUE); + } + + prStaRec->rPmfCfg.fgRxDeauthResp = FALSE; + } +#endif + DBGLOG(SAA, INFO, "ucTxSeqNum=%d ucStaRecIndex=%d u2ReasonCode=%d\n", + prMsduInfo->ucTxSeqNum, prMsduInfo->ucStaRecIndex, u2ReasonCode); + + /* 4 <4> Enqueue the frame to send this (Re)Association request frame. + */ + nicTxEnqueueMsdu(prAdapter, prMsduInfo); + + return WLAN_STATUS_SUCCESS; +} /* end of assocSendDisAssocFrame() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will parse and process the incoming Disassociation + * frame if the given BSSID is matched. + * + * @param[in] prSwRfb Pointer to SW RFB data structure. + * @param[in] aucBSSID Given BSSID + * @param[out] pu2ReasonCode Pointer to store the Reason Code from + * Deauthentication. + * + * @retval WLAN_STATUS_FAILURE This is not the frame we should handle + * at current state. + * @retval WLAN_STATUS_SUCCESS This is the frame we should handle. + */ +/*----------------------------------------------------------------------------*/ +uint32_t +assocProcessRxDisassocFrame(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, IN uint8_t aucBSSID[], + OUT uint16_t *pu2ReasonCode) +{ + struct WLAN_DISASSOC_FRAME *prDisassocFrame; + uint16_t u2RxReasonCode; + + if (!prSwRfb || !aucBSSID || !pu2ReasonCode) { + DBGLOG(SAA, WARN, "Invalid parameters, ignore pkt!\n"); + return WLAN_STATUS_FAILURE; + } + + /* 4 <1> locate the Disassociation Frame. */ + prDisassocFrame = (struct WLAN_DISASSOC_FRAME *)prSwRfb->pvHeader; + + /* 4 <2> Parse the Header of Disassociation Frame. */ + if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < + REASON_CODE_FIELD_LEN) { + DBGLOG(SAA, LOUD, "Invalid DisAssoc packet length!"); + return WLAN_STATUS_FAILURE; + } + + /* Check if this Disassoc Frame is coming from Target BSSID */ + if (UNEQUAL_MAC_ADDR(prDisassocFrame->aucBSSID, aucBSSID)) { + DBGLOG(SAA, LOUD, + "Ignore Disassoc Frame from other BSS [" MACSTR "]\n", + MAC2STR(prDisassocFrame->aucSrcAddr)); + return WLAN_STATUS_FAILURE; + } + + /* 4 <3> Parse the Fixed Fields of Deauthentication Frame Body. */ + WLAN_GET_FIELD_16(&prDisassocFrame->u2ReasonCode, &u2RxReasonCode); + *pu2ReasonCode = u2RxReasonCode; + + return WLAN_STATUS_SUCCESS; + +} /* end of assocProcessRxDisassocFrame() */ + +#if CFG_SUPPORT_AAA +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will parse and process the incoming Association Req + * frame and return a Status Code. + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] prSwRfb Pointer to SW RFB data structure. + * @param[out] pu2StatusCode Pointer to store the Status Code for carried + * in Association Response. + * + * @retval WLAN_STATUS_FAILURE This is not the frame we should handle + * at current state. + * @retval WLAN_STATUS_SUCCESS This is the frame we should handle. + */ +/*----------------------------------------------------------------------------*/ +uint32_t assocProcessRxAssocReqFrame(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, + OUT uint16_t *pu2StatusCode) +{ + struct WLAN_ASSOC_REQ_FRAME *prAssocReqFrame; + struct STA_RECORD *prStaRec; + struct BSS_INFO *prBssInfo; + struct IE_SSID *prIeSsid = (struct IE_SSID *)NULL; + struct RSN_INFO_ELEM *prIeRsn = (struct RSN_INFO_ELEM *)NULL; + struct IE_SUPPORTED_RATE_IOT *prIeSupportedRate = + (struct IE_SUPPORTED_RATE_IOT *)NULL; + struct IE_EXT_SUPPORTED_RATE *prIeExtSupportedRate = + (struct IE_EXT_SUPPORTED_RATE *)NULL; + struct WIFI_VAR *prWifiVar = NULL; + uint8_t *pucIE, *pucIEStart; + uint16_t u2IELength; + uint16_t u2Offset = 0; + uint16_t u2StatusCode = STATUS_CODE_SUCCESSFUL; + uint16_t u2RxFrameCtrl; + uint16_t u2BSSBasicRateSet; + uint8_t ucFixedFieldLength; + u_int8_t fgIsUnknownBssBasicRate; + uint32_t i; + u_int8_t fgIsTKIP = FALSE; + enum ENUM_BAND eBand = 0; + struct RX_DESC_OPS_T *prRxDescOps; + + if (!prAdapter || !prSwRfb || !pu2StatusCode) { + DBGLOG(SAA, WARN, "Invalid parameters, ignore pkt!\n"); + return WLAN_STATUS_FAILURE; + } + + prWifiVar = &(prAdapter->rWifiVar); + prRxDescOps = prAdapter->chip_info->prRxDescOps; + prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); + + if (prStaRec == NULL) + return WLAN_STATUS_FAILURE; + + /* 4 <1> locate the Association Req Frame. */ + prAssocReqFrame = (struct WLAN_ASSOC_REQ_FRAME *)prSwRfb->pvHeader; + + /* WLAN_GET_FIELD_16(&prAssocReqFrame->u2FrameCtrl, + * &u2RxFrameCtrl); + */ + u2RxFrameCtrl = prAssocReqFrame->u2FrameCtrl; + /* NOTE(Kevin): Optimized for ARM */ + u2RxFrameCtrl &= MASK_FRAME_TYPE; + + /* 4 <2> Parse the Header of Association Req Frame. */ + if (u2RxFrameCtrl == MAC_FRAME_REASSOC_REQ) + ucFixedFieldLength = + CAP_INFO_FIELD_LEN + LISTEN_INTERVAL_FIELD_LEN + + CURR_AP_ADDR_FIELD_LEN; + else + ucFixedFieldLength = + CAP_INFO_FIELD_LEN + LISTEN_INTERVAL_FIELD_LEN; + + if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) + <= ucFixedFieldLength) { + /* Length of this (re)association req is invalid, ignore it */ + return WLAN_STATUS_FAILURE; + } + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex); + + /* Check if this Disassoc Frame is coming from Target BSSID */ + if (UNEQUAL_MAC_ADDR(prAssocReqFrame->aucBSSID, prBssInfo->aucBSSID)) + return WLAN_STATUS_FAILURE; /* Just Ignore this MMPDU */ + + if (u2RxFrameCtrl == MAC_FRAME_REASSOC_REQ) { + prStaRec->fgIsReAssoc = TRUE; + + u2IELength = prSwRfb->u2PacketLen - + (uint16_t) OFFSET_OF(struct WLAN_REASSOC_REQ_FRAME, + aucInfoElem[0]); + + pucIEStart = pucIE = + ((struct WLAN_REASSOC_REQ_FRAME *)(prSwRfb-> + pvHeader))->aucInfoElem; + } else { + prStaRec->fgIsReAssoc = FALSE; + + u2IELength = prSwRfb->u2PacketLen - + (uint16_t) OFFSET_OF(struct WLAN_ASSOC_REQ_FRAME, + aucInfoElem[0]); + + pucIEStart = pucIE = prAssocReqFrame->aucInfoElem; + } + + /* 4 <3> Parse the Fixed Fields of Assoc Req Frame Body. */ + prStaRec->u2CapInfo = prAssocReqFrame->u2CapInfo; + +#if 0 +/* CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_HOTSPOT_PRIVACY_CHECK */ + if (prAdapter->fgIsP2PRegistered && IS_STA_P2P_TYPE(prStaRec)) { + if (((prStaRec->u2CapInfo & CAP_INFO_PRIVACY) + && !kalP2PGetCipher(prAdapter->prGlueInfo))) { + u2StatusCode = STATUS_CODE_CAP_NOT_SUPPORTED; + DBGLOG(RSN, TRACE, + "STA Assoc req privacy bit check fail\n"); + return WLAN_STATUS_SUCCESS; + } + } +#endif + + prStaRec->u2ListenInterval = prAssocReqFrame->u2ListenInterval; + prStaRec->ucPhyTypeSet = 0; + + /* Might be legacy client or p2p gc. */ + prStaRec->eStaType = STA_TYPE_LEGACY_CLIENT; + + /* 4 <4> Parse the IE of Assoc Req Frame Body. */ + IE_FOR_EACH(pucIE, u2IELength, u2Offset) { + switch (IE_ID(pucIE)) { + case ELEM_ID_SSID: + if ((!prIeSsid) && /* NOTE(Kevin): Get SSID once */ + (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) { + prIeSsid = (struct IE_SSID *)pucIE; + } + break; + + case ELEM_ID_SUP_RATES: + if ((!prIeSupportedRate) + && (IE_LEN(pucIE) <= RATE_NUM_SW)) + prIeSupportedRate = SUP_RATES_IOT_IE(pucIE); + + break; + + case ELEM_ID_EXTENDED_SUP_RATES: + if (!prIeExtSupportedRate) + prIeExtSupportedRate = EXT_SUP_RATES_IE(pucIE); + break; + case ELEM_ID_HT_CAP: + prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_HT; + break; + case ELEM_ID_VHT_CAP: + prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_VHT; + break; + case ELEM_ID_RSN: +#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_HOTSPOT_PRIVACY_CHECK + if (prAdapter->fgIsP2PRegistered + && IS_STA_IN_P2P(prStaRec)) { + prIeRsn = RSN_IE(pucIE); + rsnParserCheckForRSNCCMPPSK(prAdapter, prIeRsn, + prStaRec, + &u2StatusCode); + if (u2StatusCode != STATUS_CODE_SUCCESSFUL) { + *pu2StatusCode = u2StatusCode; + return WLAN_STATUS_SUCCESS; + } + } +#endif + break; + case ELEM_ID_VENDOR: + if (p2pFuncParseCheckForTKIPInfoElem(pucIE)) + fgIsTKIP = TRUE; + +#if CFG_ENABLE_WIFI_DIRECT + { + if ((prAdapter->fgIsP2PRegistered)) { + uint8_t ucOuiType = 0; + + p2pFuncParseCheckForP2PInfoElem + (prAdapter, pucIE, &ucOuiType); + + if (ucOuiType == VENDOR_OUI_TYPE_P2P) { + DBGLOG(P2P, TRACE, + "Target Client is a P2P group client\n"); + prStaRec->eStaType = + STA_TYPE_P2P_GC; + } + } + } +#endif + break; + case ELEM_ID_IBSS_PARAM_SET: + /* Check IBSS parameter set length to avoid + * abnormal content + */ + if (IE_LEN(pucIE) != ELEM_MAX_LEN_IBSS_PARAMETER_SET) { + *pu2StatusCode = + STATUS_CODE_UNSPECIFIED_FAILURE; + DBGLOG(SAA, WARN, + "Invalid IBSS Parameter IE length!\n"); + return WLAN_STATUS_FAILURE; + } + break; +#if (CFG_SUPPORT_802_11AX == 1) + case ELEM_ID_RESERVED: + if (IE_ID_EXT(pucIE) == ELEM_EXT_ID_HE_CAP) + prStaRec->ucPhyTypeSet |= PHY_TYPE_SET_802_11AX; + break; +#endif + default: + for (i = 0; + i < + (sizeof(rxAssocReqIETable) / + sizeof(struct VERIFY_IE_ENTRY)); i++) { + + if (((IE_ID(pucIE)) == + rxAssocReqIETable[i].ucElemID) + && (rxAssocReqIETable[i].pfnVarifyIE != + NULL)) { + rxAssocReqIETable[i].pfnVarifyIE + (prAdapter, prSwRfb, + (struct IE_HDR *)pucIE, + &u2StatusCode); + + if (u2StatusCode != + STATUS_CODE_SUCCESSFUL) { + *pu2StatusCode = u2StatusCode; + return WLAN_STATUS_SUCCESS; + } + } + } + + break; + } + } /* end of IE_FOR_EACH */ + + /* + * According to TGn & TGac 4.2.44, AP should not bring HT/VHT Cap IE in + * the IE of Assoc resp, if the STA request to use TKIP cipher + */ + if (fgIsTKIP && !prWifiVar->ucApAllowHtVhtTkip) + prStaRec->ucPhyTypeSet &= ~(PHY_TYPE_BIT_VHT | PHY_TYPE_BIT_HT); + + /* parsing for WMM related information (2010/12/21) */ + mqmProcessAssocReq(prAdapter, prSwRfb, pucIEStart, u2IELength); + + do { + if (prIeSsid) { + if (UNEQUAL_SSID + (prBssInfo->aucSSID, prBssInfo->ucSSIDLen, + prIeSsid->aucSSID, prIeSsid->ucLength)) { + + u2StatusCode = STATUS_CODE_UNSPECIFIED_FAILURE; + break; + } + } else { + u2StatusCode = STATUS_CODE_UNSPECIFIED_FAILURE; + break; + } + + prStaRec->u2OperationalRateSet = 0; + prStaRec->u2BSSBasicRateSet = 0; + + if (!prIeSupportedRate) { + DBGLOG(SAA, WARN, "Supported Rate not present!\n"); + u2StatusCode = + STATUS_CODE_ASSOC_DENIED_RATE_NOT_SUPPORTED; + break; + } + /* Ignore any Basic Bit */ + rateGetRateSetFromIEs(prIeSupportedRate, + prIeExtSupportedRate, + &prStaRec->u2OperationalRateSet, + &u2BSSBasicRateSet, + &fgIsUnknownBssBasicRate); + + if ((prBssInfo-> + u2BSSBasicRateSet & prStaRec->u2OperationalRateSet) + != prBssInfo->u2BSSBasicRateSet) { + u2StatusCode = + STATUS_CODE_ASSOC_DENIED_RATE_NOT_SUPPORTED; + DBGLOG(SAA, WARN, "Basic rate not supported!\n"); + break; + } + + /* Accpet the Sta, update BSSBasicRateSet from Bss */ + prStaRec->u2BSSBasicRateSet = + prBssInfo->u2BSSBasicRateSet; + + prStaRec->u2DesiredNonHTRateSet = + (prStaRec->u2OperationalRateSet & RATE_SET_ALL_ABG); + + RX_STATUS_GET( + prRxDescOps, + eBand, + get_rf_band, + prSwRfb->prRxStatus); + if (eBand == BAND_2G4) { + if (prStaRec->u2OperationalRateSet & + RATE_SET_OFDM) + prStaRec->ucPhyTypeSet |= + PHY_TYPE_BIT_ERP; + if (prStaRec->u2OperationalRateSet & + RATE_SET_HR_DSSS) + prStaRec->ucPhyTypeSet |= + PHY_TYPE_BIT_HR_DSSS; + } else { /* (BAND_5G == prBssDesc->eBande) */ + if (prStaRec->u2OperationalRateSet & + RATE_SET_OFDM) + prStaRec->ucPhyTypeSet |= + PHY_TYPE_BIT_OFDM; + } + + /* Update default Tx rate */ + nicTxUpdateStaRecDefaultRate(prAdapter, prStaRec); + +#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_HOTSPOT_PRIVACY_CHECK + if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) { + if (prIeRsn) { + if (!kalP2PGetCipher + (prAdapter->prGlueInfo, + (uint8_t) prBssInfo->u4PrivateData)) { + u2StatusCode = + STATUS_CODE_CIPHER_SUITE_REJECTED; + break; + } + } else { + /* prStaRec->rSecInfo.fgAllowOnly1x = FALSE; */ + /* if (kalP2PGetCipher( + * prAdapter->prGlueInfo)) { + * // Only Allow 1x + * prStaRec->rSecInfo.fgAllowOnly1x = + * TRUE; + * break; + * } + */ + } + } +#endif + + } while (FALSE); + +#if CFG_ENABLE_WIFI_DIRECT + if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) { +#if 1 /* ICS */ + { + uint8_t *cp = (uint8_t *) &prAssocReqFrame->u2CapInfo; + + if (prStaRec->fgIsReAssoc) + cp += 10; + else + cp += 4; + if (prStaRec->pucAssocReqIe) { + kalMemFree(prStaRec->pucAssocReqIe, + VIR_MEM_TYPE, + prStaRec->u2AssocReqIeLen); + prStaRec->pucAssocReqIe = NULL; + } + prStaRec->u2AssocReqIeLen = u2IELength; + if (u2IELength) { + prStaRec->pucAssocReqIe = + kalMemAlloc(u2IELength, + VIR_MEM_TYPE); + + if (prStaRec->pucAssocReqIe) { + kalMemCopy(prStaRec->pucAssocReqIe, + cp, u2IELength); + } else { + DBGLOG(SAA, LOUD, + "allocate memory for prStaRec->pucAssocReqIe failed!\n"); + return WLAN_STATUS_RESOURCES; + } + } + } +#endif + kalP2PUpdateAssocInfo(prAdapter->prGlueInfo, + (uint8_t *) &prAssocReqFrame->u2CapInfo, + u2IELength + + (prStaRec->fgIsReAssoc ? 10 : 4), + prStaRec->fgIsReAssoc, + prStaRec->ucBssIndex); + } +#endif + + *pu2StatusCode = u2StatusCode; + + return WLAN_STATUS_SUCCESS; + +} /* end of assocProcessRxAssocReqFrame() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is used to compose Common Information Elements for + * Association Response Frame. + * + * @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. + * @param[in] prBssInfo Pointer to the BSS_INFO_T. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +static __KAL_INLINE__ void +assocBuildReAssocRespFrameCommonIEs(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN struct BSS_INFO *prBssInfo) +{ + uint8_t *pucBuffer; + struct STA_RECORD *prStaRec; + uint8_t ucSupRatesLen; + uint8_t ucExtSupRatesLen; + + prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); + pucBuffer = + (uint8_t *) ((unsigned long)prMsduInfo->prPacket + + (unsigned long)prMsduInfo->u2FrameLength); + + if (prBssInfo->ucAllSupportedRatesLen > ELEM_MAX_LEN_SUP_RATES) { + ucSupRatesLen = ELEM_MAX_LEN_SUP_RATES; + ucExtSupRatesLen = + prBssInfo->ucAllSupportedRatesLen - ELEM_MAX_LEN_SUP_RATES; + } else { + ucSupRatesLen = prBssInfo->ucAllSupportedRatesLen; + ucExtSupRatesLen = 0; + } + + /* Fill the Supported Rates element. */ + if (ucSupRatesLen) { + SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_SUP_RATES; + SUP_RATES_IE(pucBuffer)->ucLength = ucSupRatesLen; + kalMemCopy(SUP_RATES_IE(pucBuffer)->aucSupportedRates, + prBssInfo->aucAllSupportedRates, ucSupRatesLen); + + prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); + pucBuffer += IE_SIZE(pucBuffer); + } + + /* Fill the Extended Supported Rates element. */ + if (ucExtSupRatesLen) { + + EXT_SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_EXTENDED_SUP_RATES; + EXT_SUP_RATES_IE(pucBuffer)->ucLength = ucExtSupRatesLen; + + kalMemCopy(EXT_SUP_RATES_IE(pucBuffer)->aucExtSupportedRates, + &prBssInfo->aucAllSupportedRates[ucSupRatesLen], + ucExtSupRatesLen); + + prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); + } +} /* end of assocBuildReAssocRespFrameCommonIEs() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will compose the (Re)Association Response frame + * + * @param[in] prStaRec Pointer to the STA_RECORD_T + * @param[in] pucBuffer Pointer to the frame buffer. + * @param[in] aucBssid Given BSSID. + * @param[in] u2CapInfo Capability Field of current BSS. + * @param[in out] pu2PayloadLen Return the length of the composed + * fixed fields + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +static __KAL_INLINE__ void +assocComposeReAssocRespFrameHeaderAndFF(IN struct STA_RECORD *prStaRec, + IN uint8_t *pucBuffer, + IN uint8_t aucBSSID[], + IN uint16_t u2CapInfo, + IN OUT uint16_t *pu2PayloadLen) +{ + struct WLAN_ASSOC_RSP_FRAME *prAssocRspFrame; + u_int8_t fgIsReAssoc; + + uint16_t u2FrameCtrl; + + prAssocRspFrame = (struct WLAN_ASSOC_RSP_FRAME *)pucBuffer; + fgIsReAssoc = prStaRec->fgIsReAssoc; + + /* 4 <1> Compose the frame header of the (Re)Association Request frame. + */ + /* Fill the Frame Control field. */ + if (fgIsReAssoc) + u2FrameCtrl = MAC_FRAME_REASSOC_RSP; + else + u2FrameCtrl = MAC_FRAME_ASSOC_RSP; + + /* WLAN_SET_FIELD_16(&prAssocFrame->u2FrameCtrl, u2FrameCtrl); */ + prAssocRspFrame->u2FrameCtrl = u2FrameCtrl; + /* NOTE(Kevin): Optimized for ARM */ + + /* Fill the DA field with Target MAC Address. */ + COPY_MAC_ADDR(prAssocRspFrame->aucDestAddr, prStaRec->aucMacAddr); + + /* Fill the SA field with current BSSID. */ + COPY_MAC_ADDR(prAssocRspFrame->aucSrcAddr, aucBSSID); + + /* Fill the BSSID field with current BSSID. */ + COPY_MAC_ADDR(prAssocRspFrame->aucBSSID, aucBSSID); + + /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, + * so we need to clear it). + */ + prAssocRspFrame->u2SeqCtrl = 0; + + /* 4 <2> Compose the frame body's common fixed field part of + * the (Re)Association Request frame. + */ + /* Fill the Capability Information field. */ + /* WLAN_SET_FIELD_16(&prAssocFrame->u2CapInfo, u2CapInfo); */ + prAssocRspFrame->u2CapInfo = u2CapInfo; + /* NOTE(Kevin): Optimized for ARM */ + + /* WLAN_SET_FIELD_16(&prAssocFrame->u2StatusCode, + * prStaRec->u2StatusCode); + */ + prAssocRspFrame->u2StatusCode = prStaRec->u2StatusCode; + /* NOTE(Kevin): Optimized for ARM */ + + /* WLAN_SET_FIELD_16(&prAssocFrame->u2AssocId, + * ((prStaRec->u2AssocId & AID_MASK) | AID_MSB)); + */ + /* NOTE(Kevin): Optimized for ARM */ + prAssocRspFrame->u2AssocId = + ((prStaRec->u2AssocId & AID_MASK) | AID_MSB); + + *pu2PayloadLen = + (CAP_INFO_FIELD_LEN + STATUS_CODE_FIELD_LEN + AID_FIELD_LEN); +} /* end of assocComposeReAssocRespFrameHeaderAndFF() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will send the (Re)Association Resp frame + * + * @param[in] prStaRec Pointer to the STA_RECORD_T + * + * @retval WLAN_STATUS_RESOURCES No available resource for frame composing. + * @retval WLAN_STATUS_SUCCESS Successfully send frame to TX Module + */ +/*----------------------------------------------------------------------------*/ +uint32_t assocSendReAssocRespFrame(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec) +{ + struct BSS_INFO *prBssInfo; + struct MSDU_INFO *prMsduInfo; + + uint16_t u2PayloadLen; + uint16_t u2EstimatedFrameLen; + uint16_t u2EstimatedExtraIELen; + u_int8_t fgIsReAssoc; + uint32_t i; + + /* 4 <1> Allocate a PKT_INFO_T for Authentication Frame */ + fgIsReAssoc = prStaRec->fgIsReAssoc; + + /* Init with MGMT Header Length + Length of Fixed Fields + * + Common IE Length + */ + u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + + WLAN_MAC_MGMT_HEADER_LEN + + CAP_INFO_FIELD_LEN + + STATUS_CODE_FIELD_LEN + + AID_FIELD_LEN + + (ELEM_HDR_LEN + ELEM_MAX_LEN_SUP_RATES) + (ELEM_HDR_LEN + + (RATE_NUM_SW - ELEM_MAX_LEN_SUP_RATES)); + + /* + Extra IE Length */ + u2EstimatedExtraIELen = 0; + + for (i = 0; + i < + sizeof(txAssocRespIETable) / sizeof(struct APPEND_VAR_IE_ENTRY); + i++) { + if (txAssocRespIETable[i].u2EstimatedFixedIELen != 0) { + u2EstimatedExtraIELen += + txAssocRespIETable[i].u2EstimatedFixedIELen; + } else if (txAssocRespIETable[i].pfnCalculateVariableIELen != + NULL) { + u2EstimatedExtraIELen += (uint16_t) + txAssocRespIETable[i].pfnCalculateVariableIELen + (prAdapter, prStaRec->ucBssIndex, prStaRec); + } + + } + + u2EstimatedFrameLen += u2EstimatedExtraIELen; + + /* Allocate a MSDU_INFO_T */ + prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); + if (prMsduInfo == NULL) { + DBGLOG(AAA, WARN, + "No PKT_INFO_T for sending (Re)Assoc Response.\n"); + return WLAN_STATUS_RESOURCES; + } + /* 4 <2> Compose (Re)Association Request frame header and fixed fields + * in MSDU_INfO_T. + */ + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex); + + /* Compose Header and Fixed Field */ + assocComposeReAssocRespFrameHeaderAndFF(prStaRec, + (uint8_t *) ((unsigned long) + (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), + prBssInfo->aucBSSID, prBssInfo->u2CapInfo, + &u2PayloadLen); + + /* 4 <3> Update information of MSDU_INFO_T */ + nicTxSetPktLifeTime(prMsduInfo, 100); + nicTxSetPktRetryLimit(prMsduInfo, TX_DESC_TX_COUNT_NO_LIMIT); + nicTxSetForceRts(prMsduInfo, TRUE); + + TX_SET_MMPDU(prAdapter, + prMsduInfo, + prStaRec->ucBssIndex, + prStaRec->ucIndex, + WLAN_MAC_MGMT_HEADER_LEN, + WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen, + aaaFsmRunEventTxDone, MSDU_RATE_MODE_AUTO); + + /* 4 <4> Compose the frame body's IEs of the (Re)Association Request + * frame. + */ + assocBuildReAssocRespFrameCommonIEs(prAdapter, prMsduInfo, prBssInfo); + + /* 4 <5> Compose IEs in MSDU_INFO_T */ + + /* Append IE */ + for (i = 0; + i < + sizeof(txAssocRespIETable) / sizeof(struct APPEND_VAR_IE_ENTRY); + i++) { + if (txAssocRespIETable[i].pfnAppendIE) + txAssocRespIETable[i].pfnAppendIE(prAdapter, + prMsduInfo); + + } + + DBGLOG(AAA, TRACE, "Dump assoc response frame\n"); + + if (aucDebugModule[DBG_P2P_IDX] & DBG_CLASS_TRACE) { + dumpMemory8((uint8_t *) prMsduInfo->prPacket, + (uint32_t) prMsduInfo->u2FrameLength); + } + +#if CFG_SUPPORT_WFD + /* TODO put WFD IE in assoc resp if driver will send assoc resp */ + +#endif + + /* TODO(Kevin): Also release the unused tail room of the composed MMPDU + */ + + nicTxConfigPktControlFlag(prMsduInfo, MSDU_CONTROL_FLAG_FORCE_TX, TRUE); + + /* 4 <6> Enqueue the frame to send this (Re)Association request frame. + */ + nicTxEnqueueMsdu(prAdapter, prMsduInfo); + + DBGLOG(SAA, INFO, + "Send Assoc Resp to " MACSTR ", Seq: %d, status: %d\n", + MAC2STR(prStaRec->aucMacAddr), + prMsduInfo->ucTxSeqNum, + prStaRec->u2StatusCode); + + return WLAN_STATUS_SUCCESS; + +} /* end of assocSendReAssocRespFrame() */ + +/*-----------------------------------------------------------------------*/ +/*! + * @brief Get the non-wfa vendor ie length that was previously set + * by wpa_supplicant for association request frame. + * + * @param prAdapter pointer to driver adapter + * + * @retval length of the non-wfa vendor ie + */ +/*-----------------------------------------------------------------------*/ +uint16_t assoc_get_nonwfa_vend_ie_len(struct ADAPTER *prAdapter, + uint8_t ucBssIndex) +{ + struct CONNECTION_SETTINGS *prConnSettings; + + if (!prAdapter || !prAdapter->prGlueInfo) + return 0; + + prConnSettings = + aisGetConnSettings(prAdapter, ucBssIndex); + if (!prConnSettings) + return 0; + + return prConnSettings->non_wfa_vendor_ie_len; +} + +/*-----------------------------------------------------------------------*/ +/*! + * @brief Builds the non-wfa vendor specific ies into association + * request frame. + * + * @param prAdapter pointer to driver adapter + * prMsduInfo pointer to the msdu frame body + * + * @retval void + */ +/*-----------------------------------------------------------------------*/ +void assoc_build_nonwfa_vend_ie(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo) +{ + struct CONNECTION_SETTINGS *prConnSettings; + uint8_t ucBssIndex = 0; + uint8_t *ptr = NULL; + uint16_t len = 0; + + if (!prAdapter || !prMsduInfo) + return; + + ucBssIndex = prMsduInfo->ucBssIndex; + prConnSettings = + aisGetConnSettings(prAdapter, ucBssIndex); + if (!prConnSettings) + return; + + len = prConnSettings->non_wfa_vendor_ie_len; + if (!len) + return; + + ptr = (uint8_t *)prMsduInfo->prPacket + + (uint16_t)prMsduInfo->u2FrameLength; + kalMemCopy(ptr, prConnSettings->non_wfa_vendor_ie_buf, + len); + prMsduInfo->u2FrameLength += len; +} + +void assocGenerateMDIE(IN struct ADAPTER *prAdapter, + IN OUT struct MSDU_INFO *prMsduInfo) +{ + uint8_t *pucBuffer = + (uint8_t *)prMsduInfo->prPacket + prMsduInfo->u2FrameLength; + uint8_t ucBssIndex = prMsduInfo->ucBssIndex; + enum ENUM_PARAM_AUTH_MODE eAuthMode = + aisGetAuthMode(prAdapter, ucBssIndex); + struct FT_IES *prFtIEs = aisGetFtIe(prAdapter, ucBssIndex); + struct GL_WPA_INFO *prWpaInfo = aisGetWpaInfo(prAdapter, + ucBssIndex); + + /* don't include MDIE in assoc request frame if auth mode is not FT + * related + */ + if (eAuthMode != AUTH_MODE_WPA2_FT && + eAuthMode != AUTH_MODE_WPA2_FT_PSK && + !(eAuthMode == AUTH_MODE_OPEN && + prWpaInfo->u4WpaVersion == + IW_AUTH_WPA_VERSION_DISABLED && + prWpaInfo->u4AuthAlg == + IW_AUTH_ALG_FT)) /* Non-RSN FT */ + return; + + if (!prFtIEs->prMDIE) { + struct BSS_DESC *prBssDesc = + aisGetTargetBssDesc(prAdapter, ucBssIndex); + uint8_t *pucIE = &prBssDesc->aucIEBuf[0]; + uint16_t u2IeLen = prBssDesc->u2IELength; + uint16_t u2IeOffSet = 0; + + IE_FOR_EACH(pucIE, u2IeLen, u2IeOffSet) + { + if (IE_ID(pucIE) == ELEM_ID_MOBILITY_DOMAIN) { + /* IE size for MD IE is fixed, it is 5 */ + prMsduInfo->u2FrameLength += 5; + kalMemCopy(pucBuffer, pucIE, 5); + break; + } + } + return; + } + prMsduInfo->u2FrameLength += + 5; /* IE size for MD IE is fixed, it is 5 */ + kalMemCopy(pucBuffer, prFtIEs->prMDIE, 5); + DBGLOG(SAA, TRACE, "FT: Generate MD IE\n"); +} + +#endif /* CFG_SUPPORT_AAA */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/auth.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/auth.c new file mode 100644 index 0000000000000000000000000000000000000000..bede4a93b012226938733362ab61252eca1bc1de --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/auth.c @@ -0,0 +1,1386 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/auth.c#1 + */ + +/*! \file "auth.c" + * \brief This file includes the authentication-related functions. + * + * This file includes the authentication-related functions. + */ + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ +struct APPEND_VAR_IE_ENTRY txAuthIETable[] = { + {(ELEM_HDR_LEN + ELEM_MAX_LEN_CHALLENGE_TEXT), NULL, + authAddIEChallengeText}, + {0, authCalculateRSNIELen, authAddRSNIE}, /* Element ID: 48 */ + {(ELEM_HDR_LEN + 1), NULL, authAddMDIE}, /* Element ID: 54 */ + {0, rsnCalculateFTIELen, rsnGenerateFTIE}, /* Element ID: 55 */ +}; + +struct HANDLE_IE_ENTRY rxAuthIETable[] = { + {ELEM_ID_CHALLENGE_TEXT, authHandleIEChallengeText} +}; + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will compose the Authentication frame header and + * fixed fields. + * + * @param[in] pucBuffer Pointer to the frame buffer. + * @param[in] aucPeerMACAddress Given Peer MAC Address. + * @param[in] aucMACAddress Given Our MAC Address. + * @param[in] u2AuthAlgNum Authentication Algorithm Number + * @param[in] u2TransactionSeqNum Transaction Sequence Number + * @param[in] u2StatusCode Status Code + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +static __KAL_INLINE__ void +authComposeAuthFrameHeaderAndFF(IN uint8_t *pucBuffer, + IN uint8_t aucPeerMACAddress[], + IN uint8_t aucMACAddress[], + IN uint16_t u2AuthAlgNum, + IN uint16_t u2TransactionSeqNum, + IN uint16_t u2StatusCode) +{ + struct WLAN_AUTH_FRAME *prAuthFrame; + uint16_t u2FrameCtrl; + + prAuthFrame = (struct WLAN_AUTH_FRAME *)pucBuffer; + + /* 4 <1> Compose the frame header of the Authentication frame. */ + /* Fill the Frame Control field. */ + u2FrameCtrl = MAC_FRAME_AUTH; + + /* If this frame is the third frame in the shared key authentication + * sequence, it shall be encrypted. + */ + if ((u2AuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY) + && (u2TransactionSeqNum == AUTH_TRANSACTION_SEQ_3)) + u2FrameCtrl |= MASK_FC_PROTECTED_FRAME; + /* HW will also detect this bit for applying encryption */ + /* WLAN_SET_FIELD_16(&prAuthFrame->u2FrameCtrl, u2FrameCtrl); */ + prAuthFrame->u2FrameCtrl = u2FrameCtrl; + /* NOTE(Kevin): Optimized for ARM */ + + /* Fill the DA field with Target BSSID. */ + COPY_MAC_ADDR(prAuthFrame->aucDestAddr, aucPeerMACAddress); + + /* Fill the SA field with our MAC Address. */ + COPY_MAC_ADDR(prAuthFrame->aucSrcAddr, aucMACAddress); + + switch (u2TransactionSeqNum) { + case AUTH_TRANSACTION_SEQ_1: + case AUTH_TRANSACTION_SEQ_3: + + /* Fill the BSSID field with Target BSSID. */ + COPY_MAC_ADDR(prAuthFrame->aucBSSID, aucPeerMACAddress); + break; + + case AUTH_TRANSACTION_SEQ_2: + case AUTH_TRANSACTION_SEQ_4: + + /* Fill the BSSID field with Current BSSID. */ + COPY_MAC_ADDR(prAuthFrame->aucBSSID, aucMACAddress); + break; + + default: + ASSERT(0); + } + + /* Clear the SEQ/FRAG_NO field. */ + prAuthFrame->u2SeqCtrl = 0; + + /* 4 <2> Compose the frame body's fixed field part of + * the Authentication frame. + */ + /* Fill the Authentication Algorithm Number field. */ + /* WLAN_SET_FIELD_16(&prAuthFrame->u2AuthAlgNum, u2AuthAlgNum); */ + prAuthFrame->u2AuthAlgNum = u2AuthAlgNum; + /* NOTE(Kevin): Optimized for ARM */ + + /* Fill the Authentication Transaction Sequence Number field. */ + /* WLAN_SET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, + * u2TransactionSeqNum); + */ + prAuthFrame->u2AuthTransSeqNo = u2TransactionSeqNum; + /* NOTE(Kevin): Optimized for ARM */ + + /* Fill the Status Code field. */ + /* WLAN_SET_FIELD_16(&prAuthFrame->u2StatusCode, u2StatusCode); */ + prAuthFrame->u2StatusCode = u2StatusCode; + /* NOTE(Kevin): Optimized for ARM */ +} /* end of authComposeAuthFrameHeaderAndFF() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will append Challenge Text IE to the Authentication + * frame + * + * @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void authAddIEChallengeText(IN struct ADAPTER *prAdapter, + IN OUT struct MSDU_INFO *prMsduInfo) +{ + struct WLAN_AUTH_FRAME *prAuthFrame; + struct STA_RECORD *prStaRec; + uint16_t u2TransactionSeqNum; + + prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); + + if (!prStaRec) + return; + + /* For Management, frame header and payload are in a continuous + * buffer + */ + prAuthFrame = (struct WLAN_AUTH_FRAME *)prMsduInfo->prPacket; + + WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2TransactionSeqNum) + + /* Only consider SEQ_3 for Challenge Text */ + if ((u2TransactionSeqNum == AUTH_TRANSACTION_SEQ_3) && + (prStaRec->ucAuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY) + && (prStaRec->prChallengeText != NULL)) { + + COPY_IE(((unsigned long)(prMsduInfo->prPacket) + + prMsduInfo->u2FrameLength), + (prStaRec->prChallengeText)); + + prMsduInfo->u2FrameLength += IE_SIZE(prStaRec->prChallengeText); + } + + return; + +} /* end of authAddIEChallengeText() */ + +#if !CFG_SUPPORT_AAA +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will send the Authenticiation frame + * + * @param[in] prStaRec Pointer to the STA_RECORD_T + * @param[in] u2TransactionSeqNum Transaction Sequence Number + * + * @retval WLAN_STATUS_RESOURCES No available resource for frame composing. + * @retval WLAN_STATUS_SUCCESS Successfully send frame to TX Module + */ +/*----------------------------------------------------------------------------*/ +uint32_t authSendAuthFrame(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, + IN uint16_t u2TransactionSeqNum) +{ + struct MSDU_INFO *prMsduInfo; + struct BSS_INFO *prBssInfo; + uint16_t u2EstimatedFrameLen; + uint16_t u2EstimatedExtraIELen; + uint16_t u2PayloadLen; + uint32_t i; + + DBGLOG(SAA, LOUD, "Send Auth Frame\n"); + + /* 4 <1> Allocate a PKT_INFO_T for Authentication Frame */ + /* Init with MGMT Header Length + Length of Fixed Fields */ + u2EstimatedFrameLen = (MAC_TX_RESERVED_FIELD + + WLAN_MAC_MGMT_HEADER_LEN + + AUTH_ALGORITHM_NUM_FIELD_LEN + + AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + + STATUS_CODE_FIELD_LEN); + + /* + Extra IE Length */ + u2EstimatedExtraIELen = 0; + + for (i = 0; + i < sizeof(txAuthIETable) / sizeof(struct APPEND_VAR_IE_ENTRY); + i++) { + if (txAssocRespIETable[i].u2EstimatedFixedIELen != 0) + u2EstimatedExtraIELen += + txAssocRespIETable[i].u2EstimatedFixedIELen; + else if (txAssocRespIETable[i].pfnCalculateVariableIELen != + NULL) + u2EstimatedExtraIELen += + (uint16_t)txAssocRespIETable[i] + .pfnCalculateVariableIELen( + prAdapter, prStaRec->ucBssIndex, + prStaRec); + } + + u2EstimatedFrameLen += u2EstimatedExtraIELen; + + /* Allocate a MSDU_INFO_T */ + prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); + if (prMsduInfo == NULL) { + DBGLOG(SAA, WARN, "No PKT_INFO_T for sending Auth Frame.\n"); + return WLAN_STATUS_RESOURCES; + } + /* 4 <2> Compose Authentication Request frame header and fixed fields + * in MSDU_INfO_T. + */ + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex) + + /* Compose Header and some Fixed Fields */ + authComposeAuthFrameHeaderAndFF((uint8_t *) + ((uint32_t) (prMsduInfo->prPacket) + + MAC_TX_RESERVED_FIELD), + prStaRec->aucMacAddr, + prBssInfo->aucOwnMacAddr, + prStaRec->ucAuthAlgNum, + u2TransactionSeqNum, + STATUS_CODE_RESERVED); + + u2PayloadLen = + (AUTH_ALGORITHM_NUM_FIELD_LEN + + AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN); + + /* 4 <3> Update information of MSDU_INFO_T */ + TX_SET_MMPDU(prAdapter, + prMsduInfo, + prStaRec->ucBssIndex, + prStaRec->ucIndex, + WLAN_MAC_MGMT_HEADER_LEN, + WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen, + saaFsmRunEventTxDone, MSDU_RATE_MODE_AUTO); + + /* 4 <4> Compose IEs in MSDU_INFO_T */ + for (i = 0; i < sizeof(txAuthIETable) / sizeof(struct APPEND_IE_ENTRY); + i++) { + if (txAuthIETable[i].pfnAppendIE) + txAuthIETable[i].pfnAppendIE(prAdapter, prMsduInfo); + + } + + /* TODO(Kevin): + * Also release the unused tail room of the composed MMPDU + */ + + nicTxConfigPktControlFlag(prMsduInfo, MSDU_CONTROL_FLAG_FORCE_TX, TRUE); + + /* 4 <6> Inform TXM to send this Authentication frame. */ + nicTxEnqueueMsdu(prAdapter, prMsduInfo); + + return WLAN_STATUS_SUCCESS; +} /* end of authSendAuthFrame() */ + +#else + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will send the Authenticiation frame + * + * @param[in] prStaRec Pointer to the STA_RECORD_T + * @param[in] u2TransactionSeqNum Transaction Sequence Number + * + * @retval WLAN_STATUS_RESOURCES No available resource for frame composing. + * @retval WLAN_STATUS_SUCCESS Successfully send frame to TX Module + */ +/*----------------------------------------------------------------------------*/ +uint32_t +authSendAuthFrame(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, + IN uint8_t ucBssIndex, + IN struct SW_RFB *prFalseAuthSwRfb, + IN uint16_t u2TransactionSeqNum, IN uint16_t u2StatusCode) +{ + uint8_t *pucReceiveAddr; + uint8_t *pucTransmitAddr; + struct MSDU_INFO *prMsduInfo; + struct BSS_INFO *prBssInfo; + /*get from input parameter */ + /* ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex = NETWORK_TYPE_AIS_INDEX; */ + PFN_TX_DONE_HANDLER pfTxDoneHandler = (PFN_TX_DONE_HANDLER) NULL; + uint16_t u2EstimatedFrameLen; + uint16_t u2EstimatedExtraIELen; + uint16_t u2PayloadLen; + uint16_t ucAuthAlgNum; + uint32_t i; + + /* 4 <1> Allocate a PKT_INFO_T for Authentication Frame */ + /* Init with MGMT Header Length + Length of Fixed Fields */ + u2EstimatedFrameLen = (MAC_TX_RESERVED_FIELD + + WLAN_MAC_MGMT_HEADER_LEN + + AUTH_ALGORITHM_NUM_FIELD_LEN + + AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + + STATUS_CODE_FIELD_LEN); + + /* + Extra IE Length */ + u2EstimatedExtraIELen = 0; + + for (i = 0; + i < sizeof(txAuthIETable) / sizeof(struct APPEND_VAR_IE_ENTRY); + i++) { + if (txAuthIETable[i].u2EstimatedFixedIELen != 0) + u2EstimatedExtraIELen += + txAuthIETable[i].u2EstimatedFixedIELen; + else + u2EstimatedExtraIELen += + txAuthIETable[i].pfnCalculateVariableIELen( + prAdapter, ucBssIndex, prStaRec); + } + + u2EstimatedFrameLen += u2EstimatedExtraIELen; + + /* Allocate a MSDU_INFO_T */ + prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); + if (prMsduInfo == NULL) { + DBGLOG(SAA, WARN, "No PKT_INFO_T for sending Auth Frame.\n"); + return WLAN_STATUS_RESOURCES; + } + /* 4 <2> Compose Authentication Request frame header and + * fixed fields in MSDU_INfO_T. + */ + if (prStaRec) { + prBssInfo = + GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex); + + pucTransmitAddr = prBssInfo->aucOwnMacAddr; + + pucReceiveAddr = prStaRec->aucMacAddr; + + ucAuthAlgNum = prStaRec->ucAuthAlgNum; + + switch (u2TransactionSeqNum) { + case AUTH_TRANSACTION_SEQ_1: + case AUTH_TRANSACTION_SEQ_3: + pfTxDoneHandler = saaFsmRunEventTxDone; + break; + + case AUTH_TRANSACTION_SEQ_2: + case AUTH_TRANSACTION_SEQ_4: + pfTxDoneHandler = aaaFsmRunEventTxDone; + break; + } + + } else { /* For Error Status Code */ + struct WLAN_AUTH_FRAME *prFalseAuthFrame; + + prFalseAuthFrame = + (struct WLAN_AUTH_FRAME *)prFalseAuthSwRfb->pvHeader; + + pucTransmitAddr = prFalseAuthFrame->aucDestAddr; + + pucReceiveAddr = prFalseAuthFrame->aucSrcAddr; + + ucAuthAlgNum = prFalseAuthFrame->u2AuthAlgNum; + + u2TransactionSeqNum = (prFalseAuthFrame->u2AuthTransSeqNo + 1); + } + + /* Compose Header and some Fixed Fields */ + authComposeAuthFrameHeaderAndFF((uint8_t *) + ((unsigned long)(prMsduInfo->prPacket) + + MAC_TX_RESERVED_FIELD), pucReceiveAddr, + pucTransmitAddr, ucAuthAlgNum, + u2TransactionSeqNum, u2StatusCode); + + u2PayloadLen = + (AUTH_ALGORITHM_NUM_FIELD_LEN + + AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN); + + /* 4 <3> Update information of MSDU_INFO_T */ + nicTxSetPktLifeTime(prMsduInfo, 100); + nicTxSetPktRetryLimit(prMsduInfo, TX_DESC_TX_COUNT_NO_LIMIT); + nicTxSetForceRts(prMsduInfo, TRUE); + + TX_SET_MMPDU(prAdapter, + prMsduInfo, + ucBssIndex, + (prStaRec != + NULL) ? (prStaRec->ucIndex) : (STA_REC_INDEX_NOT_FOUND), + WLAN_MAC_MGMT_HEADER_LEN, + WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen, pfTxDoneHandler, + MSDU_RATE_MODE_AUTO); + + if ((ucAuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY) + && (u2TransactionSeqNum == AUTH_TRANSACTION_SEQ_3)) + nicTxConfigPktOption(prMsduInfo, MSDU_OPT_PROTECTED_FRAME, + TRUE); + /* 4 <4> Compose IEs in MSDU_INFO_T */ + for (i = 0; + i < sizeof(txAuthIETable) / sizeof(struct APPEND_VAR_IE_ENTRY); + i++) { + if (txAuthIETable[i].pfnAppendIE) + txAuthIETable[i].pfnAppendIE(prAdapter, prMsduInfo); + } + + /* TODO(Kevin): + * Also release the unused tail room of the composed MMPDU + */ + + nicTxConfigPktControlFlag(prMsduInfo, MSDU_CONTROL_FLAG_FORCE_TX, TRUE); + + /* 4 <6> Inform TXM to send this Authentication frame. */ + nicTxEnqueueMsdu(prAdapter, prMsduInfo); + + DBGLOG(SAA, INFO, + "Send Auth Frame, TranSeq: %d, Status: %d, Seq: %d\n", + u2TransactionSeqNum, u2StatusCode, prMsduInfo->ucTxSeqNum); + + return WLAN_STATUS_SUCCESS; +} /* end of authSendAuthFrame() */ + +#endif /* CFG_SUPPORT_AAA */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will strictly check the TX Authentication frame + * for SAA/AAA event handling. + * + * @param[in] prMsduInfo Pointer of MSDU_INFO_T + * @param[in] u2TransactionSeqNum Transaction Sequence Number + * + * @retval WLAN_STATUS_FAILURE This is not the frame we should handle + * at current state. + * @retval WLAN_STATUS_SUCCESS This is the frame we should handle. + */ +/*----------------------------------------------------------------------------*/ +uint32_t authCheckTxAuthFrame(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN uint16_t u2TransactionSeqNum) +{ + struct WLAN_AUTH_FRAME *prAuthFrame; + struct STA_RECORD *prStaRec; + uint16_t u2TxFrameCtrl; + uint16_t u2TxAuthAlgNum; + uint16_t u2TxTransactionSeqNum; + + prAuthFrame = (struct WLAN_AUTH_FRAME *)(prMsduInfo->prPacket); + prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); + + if (!prStaRec) + return WLAN_STATUS_INVALID_PACKET; + + /* WLAN_GET_FIELD_16(&prAuthFrame->u2FrameCtrl, &u2TxFrameCtrl) */ + u2TxFrameCtrl = prAuthFrame->u2FrameCtrl; + /* NOTE(Kevin): Optimized for ARM */ + u2TxFrameCtrl &= MASK_FRAME_TYPE; + if (u2TxFrameCtrl != MAC_FRAME_AUTH) + return WLAN_STATUS_FAILURE; + + /* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthAlgNum, &u2TxAuthAlgNum) */ + u2TxAuthAlgNum = prAuthFrame->u2AuthAlgNum; + /* NOTE(Kevin): Optimized for ARM */ + if (u2TxAuthAlgNum != (uint16_t) (prStaRec->ucAuthAlgNum)) + return WLAN_STATUS_FAILURE; + + /* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, + * &u2TxTransactionSeqNum) + */ + u2TxTransactionSeqNum = prAuthFrame->u2AuthTransSeqNo; + /* NOTE(Kevin): Optimized for ARM */ + if (u2TxTransactionSeqNum != u2TransactionSeqNum) + return WLAN_STATUS_FAILURE; + + return WLAN_STATUS_SUCCESS; + +} /* end of authCheckTxAuthFrame() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will check the incoming Auth Frame's Transaction + * Sequence Number before delivering it to the corresponding + * SAA or AAA Module. + * + * @param[in] prSwRfb Pointer to the SW_RFB_T structure. + * + * @retval WLAN_STATUS_SUCCESS Always not retain authentication frames + */ +/*----------------------------------------------------------------------------*/ +uint32_t authCheckRxAuthFrameTransSeq(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb) +{ + struct WLAN_AUTH_FRAME *prAuthFrame; + uint16_t u2RxTransactionSeqNum; + uint16_t u2MinPayloadLen; + struct STA_RECORD *prStaRec; + + /* 4 <1> locate the Authentication Frame. */ + prAuthFrame = (struct WLAN_AUTH_FRAME *)prSwRfb->pvHeader; + + /* 4 <2> Parse the Header of Authentication Frame. */ + u2MinPayloadLen = (AUTH_ALGORITHM_NUM_FIELD_LEN + + AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + + STATUS_CODE_FIELD_LEN); + if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < u2MinPayloadLen) { + DBGLOG(SAA, WARN, + "Rx Auth payload: len[%u] < min expected len[%u]\n", + (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen), + u2MinPayloadLen); + DBGLOG(SAA, WARN, "=== Dump Rx Auth ===\n"); + DBGLOG_MEM8(SAA, WARN, prAuthFrame, prSwRfb->u2PacketLen); + return WLAN_STATUS_SUCCESS; + } + + prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); + if (prStaRec && IS_STA_IN_AIS(prStaRec)) { + if (prStaRec->eAuthAssocState == SAA_STATE_EXTERNAL_AUTH) { + saaFsmRunEventRxAuth(prAdapter, prSwRfb); + return WLAN_STATUS_SUCCESS; + } + } + + /* 4 <3> Parse the Fixed Fields of Authentication Frame Body. */ + /* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, + * &u2RxTransactionSeqNum); + */ + u2RxTransactionSeqNum = prAuthFrame->u2AuthTransSeqNo; + /* NOTE(Kevin): Optimized for ARM */ + + DBGLOG(SAA, LOUD, + "Authentication Packet: Auth Trans Seq No = %d\n", + u2RxTransactionSeqNum); + + switch (u2RxTransactionSeqNum) { + case AUTH_TRANSACTION_SEQ_2: + case AUTH_TRANSACTION_SEQ_4: + if (prStaRec && IS_STA_IN_P2P(prStaRec) && + !IS_AP_STA(prStaRec)) + aaaFsmRunEventRxAuth(prAdapter, prSwRfb); + else + saaFsmRunEventRxAuth(prAdapter, prSwRfb); + break; + + case AUTH_TRANSACTION_SEQ_1: + case AUTH_TRANSACTION_SEQ_3: +#if CFG_SUPPORT_AAA + aaaFsmRunEventRxAuth(prAdapter, prSwRfb); +#endif /* CFG_SUPPORT_AAA */ + break; + + default: + DBGLOG(SAA, WARN, + "Strange Authentication Packet: Auth Trans Seq No = %d, Error Status Code = %d\n", + u2RxTransactionSeqNum, prAuthFrame->u2StatusCode); +#if CFG_IGNORE_INVALID_AUTH_TSN + prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); + if (!prStaRec) + return WLAN_STATUS_SUCCESS; + switch (prStaRec->eAuthAssocState) { + case SAA_STATE_SEND_AUTH1: + case SAA_STATE_WAIT_AUTH2: + case SAA_STATE_SEND_AUTH3: + case SAA_STATE_WAIT_AUTH4: + saaFsmRunEventRxAuth(prAdapter, prSwRfb); + break; + default: + break; + } +#endif + + break; + } + + return WLAN_STATUS_SUCCESS; + +} /* end of authCheckRxAuthFrameTransSeq() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will validate the incoming Authentication Frame and + * take the status code out. + * + * @param[in] prSwRfb Pointer to SW RFB data structure. + * @param[in] u2TransactionSeqNum Transaction Sequence Number + * @param[out] pu2StatusCode Pointer to store the Status Code from + * Authentication. + * + * @retval WLAN_STATUS_FAILURE This is not the frame we should handle + * at current state. + * @retval WLAN_STATUS_SUCCESS This is the frame we should handle. + */ +/*----------------------------------------------------------------------------*/ +uint32_t +authCheckRxAuthFrameStatus(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, + IN uint16_t u2TransactionSeqNum, + OUT uint16_t *pu2StatusCode) +{ + struct STA_RECORD *prStaRec; + struct WLAN_AUTH_FRAME *prAuthFrame; + uint16_t u2RxAuthAlgNum; + uint16_t u2RxTransactionSeqNum; + /* UINT_16 u2RxStatusCode; // NOTE(Kevin): Optimized for ARM */ + + prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); + if (!prStaRec) + return WLAN_STATUS_INVALID_PACKET; + + /* 4 <1> locate the Authentication Frame. */ + prAuthFrame = (struct WLAN_AUTH_FRAME *)prSwRfb->pvHeader; + + /* 4 <2> Parse the Fixed Fields of Authentication Frame Body. */ + /* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthAlgNum, &u2RxAuthAlgNum); */ + u2RxAuthAlgNum = prAuthFrame->u2AuthAlgNum; + /* NOTE(Kevin): Optimized for ARM */ + if (u2RxAuthAlgNum != (uint16_t) prStaRec->ucAuthAlgNum) { + DBGLOG(SAA, WARN, + "Discard Auth frame with auth type = %d, current = %d\n", + u2RxAuthAlgNum, prStaRec->ucAuthAlgNum); + *pu2StatusCode = STATUS_CODE_AUTH_ALGORITHM_NOT_SUPPORTED; + return WLAN_STATUS_SUCCESS; + } + /* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, + * &u2RxTransactionSeqNum); + */ + u2RxTransactionSeqNum = prAuthFrame->u2AuthTransSeqNo; + /* NOTE(Kevin): Optimized for ARM */ + if (u2RxTransactionSeqNum != u2TransactionSeqNum) { + DBGLOG(SAA, WARN, + "Discard Auth frame with Transaction Seq No = %d\n", + u2RxTransactionSeqNum); + *pu2StatusCode = STATUS_CODE_AUTH_OUT_OF_SEQ; + return WLAN_STATUS_FAILURE; + } + /* 4 <3> Get the Status code */ + /* WLAN_GET_FIELD_16(&prAuthFrame->u2StatusCode, &u2RxStatusCode); */ + /* *pu2StatusCode = u2RxStatusCode; */ + *pu2StatusCode = prAuthFrame->u2StatusCode; + /* NOTE(Kevin): Optimized for ARM */ + + return WLAN_STATUS_SUCCESS; + +} /* end of authCheckRxAuthFrameStatus() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will handle the Challenge Text IE from + * the Authentication frame + * + * @param[in] prSwRfb Pointer to SW RFB data structure. + * @param[in] prIEHdr Pointer to start address of IE + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void authHandleIEChallengeText(struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb, struct IE_HDR *prIEHdr) +{ + struct WLAN_AUTH_FRAME *prAuthFrame; + struct STA_RECORD *prStaRec; + uint16_t u2TransactionSeqNum; + + prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); + if (!prStaRec) + return; + + /* For Management, frame header and payload are in + * a continuous buffer + */ + prAuthFrame = (struct WLAN_AUTH_FRAME *)prSwRfb->pvHeader; + + /* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, + * &u2TransactionSeqNum) + */ + u2TransactionSeqNum = prAuthFrame->u2AuthTransSeqNo; + /* NOTE(Kevin): Optimized for ARM */ + + /* Only consider SEQ_2 for Challenge Text */ + if ((u2TransactionSeqNum == AUTH_TRANSACTION_SEQ_2) && + (prStaRec->ucAuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY)) { + + /* Free previous allocated TCM memory */ + if (prStaRec->prChallengeText) { + cnmMemFree(prAdapter, prStaRec->prChallengeText); + prStaRec->prChallengeText = + (struct IE_CHALLENGE_TEXT *)NULL; + } + prStaRec->prChallengeText = + cnmMemAlloc(prAdapter, RAM_TYPE_MSG, IE_SIZE(prIEHdr)); + if (prStaRec->prChallengeText == NULL) + return; + + /* Save the Challenge Text from Auth Seq 2 Frame, + * before sending Auth Seq 3 Frame + */ + COPY_IE(prStaRec->prChallengeText, prIEHdr); + } + + return; + +} /* end of authAddIEChallengeText() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will parse and process the incoming Authentication + * frame. + * + * @param[in] prSwRfb Pointer to SW RFB data structure. + * + * @retval WLAN_STATUS_SUCCESS This is the frame we should handle. + */ +/*----------------------------------------------------------------------------*/ +uint32_t authProcessRxAuth2_Auth4Frame(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb) +{ + struct WLAN_AUTH_FRAME *prAuthFrame; + uint8_t *pucIEsBuffer; + uint16_t u2IEsLen; + uint16_t u2Offset; + uint8_t ucIEID; + uint32_t i; + + prAuthFrame = (struct WLAN_AUTH_FRAME *)prSwRfb->pvHeader; + + pucIEsBuffer = &prAuthFrame->aucInfoElem[0]; + u2IEsLen = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) - + (AUTH_ALGORITHM_NUM_FIELD_LEN + + AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN); + + IE_FOR_EACH(pucIEsBuffer, u2IEsLen, u2Offset) { + ucIEID = IE_ID(pucIEsBuffer); + + for (i = 0; + i < + (sizeof(rxAuthIETable) / sizeof(struct HANDLE_IE_ENTRY)); + i++) { + if ((ucIEID == rxAuthIETable[i].ucElemID) + && (rxAuthIETable[i].pfnHandleIE != NULL)) + rxAuthIETable[i].pfnHandleIE(prAdapter, + prSwRfb, + (struct IE_HDR *)pucIEsBuffer); + } + } + if (prAuthFrame->u2AuthAlgNum == + AUTH_ALGORITHM_NUM_FAST_BSS_TRANSITION) { + if (prAuthFrame->u2AuthTransSeqNo == AUTH_TRANSACTION_SEQ_4) { + /* todo: check MIC, if mic error, return + * WLAN_STATUS_FAILURE + */ + } else if (prAuthFrame->u2AuthTransSeqNo == + AUTH_TRANSACTION_SEQ_2) { + struct cfg80211_ft_event_params *prFtEvent = + aisGetFtEventParam(prAdapter, + secGetBssIdxByRfb(prAdapter, + prSwRfb)); + + prFtEvent->ies = + &prAuthFrame->aucInfoElem[0]; + prFtEvent->ies_len = u2IEsLen; + } + } + + return WLAN_STATUS_SUCCESS; + +} /* end of authProcessRxAuth2_Auth4Frame() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will compose the Deauthentication frame + * + * @param[in] pucBuffer Pointer to the frame buffer. + * @param[in] aucPeerMACAddress Given Peer MAC Address. + * @param[in] aucMACAddress Given Our MAC Address. + * @param[in] u2StatusCode Status Code + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +static __KAL_INLINE__ void +authComposeDeauthFrameHeaderAndFF(IN uint8_t *pucBuffer, + IN uint8_t aucPeerMACAddress[], + IN uint8_t aucMACAddress[], + IN uint8_t aucBssid[], + IN uint16_t u2ReasonCode) +{ + struct WLAN_DEAUTH_FRAME *prDeauthFrame; + uint16_t u2FrameCtrl; + + prDeauthFrame = (struct WLAN_DEAUTH_FRAME *)pucBuffer; + + /* 4 <1> Compose the frame header of the Deauthentication frame. */ + /* Fill the Frame Control field. */ + u2FrameCtrl = MAC_FRAME_DEAUTH; + + /* WLAN_SET_FIELD_16(&prDeauthFrame->u2FrameCtrl, u2FrameCtrl); */ + prDeauthFrame->u2FrameCtrl = u2FrameCtrl; + /* NOTE(Kevin): Optimized for ARM */ + + /* Fill the DA field with Target BSSID. */ + COPY_MAC_ADDR(prDeauthFrame->aucDestAddr, aucPeerMACAddress); + + /* Fill the SA field with our MAC Address. */ + COPY_MAC_ADDR(prDeauthFrame->aucSrcAddr, aucMACAddress); + + /* Fill the BSSID field with Target BSSID. */ + COPY_MAC_ADDR(prDeauthFrame->aucBSSID, aucBssid); + + /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, + * so we need to clear it). + */ + prDeauthFrame->u2SeqCtrl = 0; + + /* 4 <2> Compose the frame body's fixed field part of + * the Authentication frame. + */ + /* Fill the Status Code field. */ + /* WLAN_SET_FIELD_16(&prDeauthFrame->u2ReasonCode, u2ReasonCode); */ + prDeauthFrame->u2ReasonCode = u2ReasonCode; + /* NOTE(Kevin): Optimized for ARM */ +} /* end of authComposeDeauthFrameHeaderAndFF() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will send the Deauthenticiation frame + * + * @param[in] prStaRec Pointer to the STA_RECORD_T + * @param[in] prClassErrSwRfb Pointer to the SW_RFB_T which is Class Error. + * @param[in] u2ReasonCode A reason code to indicate why to leave BSS. + * @param[in] pfTxDoneHandler TX Done call back function + * + * @retval WLAN_STATUS_RESOURCES No available resource for frame composing. + * @retval WLAN_STATUS_SUCCESS Successfully send frame to TX Module + * @retval WLAN_STATUS_FAILURE Didn't send Deauth frame for various reasons. + */ +/*----------------------------------------------------------------------------*/ +uint32_t +authSendDeauthFrame(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo, + IN struct STA_RECORD *prStaRec, + IN struct SW_RFB *prClassErrSwRfb, IN uint16_t u2ReasonCode, + IN PFN_TX_DONE_HANDLER pfTxDoneHandler) +{ + uint8_t *pucReceiveAddr; + uint8_t *pucTransmitAddr; + uint8_t *pucBssid = NULL; + struct MSDU_INFO *prMsduInfo; + uint16_t u2EstimatedFrameLen; + + struct DEAUTH_INFO *prDeauthInfo; + OS_SYSTIME rCurrentTime; + int32_t i4NewEntryIndex, i; + uint8_t ucStaRecIdx = STA_REC_INDEX_NOT_FOUND; + uint8_t ucBssIndex = prAdapter->ucHwBssIdNum; + uint8_t aucBMC[] = BC_MAC_ADDR; + + /* NOTE(Kevin): The best way to reply the Deauth is according to + * the incoming data frame + */ + /* 4 <1.1> Find the Receiver Address */ + if (prClassErrSwRfb) { + u_int8_t fgIsAbleToSendDeauth = FALSE; + uint16_t u2RxFrameCtrl; + struct WLAN_MAC_HEADER_A4 *prWlanMacHeader = NULL; + + prWlanMacHeader = + (struct WLAN_MAC_HEADER_A4 *)prClassErrSwRfb->pvHeader; + + /* WLAN_GET_FIELD_16(&prWlanMacHeader->u2FrameCtrl, + * &u2RxFrameCtrl); + */ + u2RxFrameCtrl = prWlanMacHeader->u2FrameCtrl; + /* NOTE(Kevin): Optimized for ARM */ + + /* TODO(Kevin): Currently we won't send Deauth for IBSS node. + * How about DLS ? + */ + if ((prWlanMacHeader->u2FrameCtrl & MASK_TO_DS_FROM_DS) == 0) + return WLAN_STATUS_FAILURE; + + DBGLOG(SAA, INFO, + "u2FrameCtrl=0x%x, DestAddr=" MACSTR + " srcAddr=" MACSTR " BSSID=" MACSTR + ", u2SeqCtrl=0x%x\n", + prWlanMacHeader->u2FrameCtrl, + MAC2STR(prWlanMacHeader->aucAddr1), + MAC2STR(prWlanMacHeader->aucAddr2), + MAC2STR(prWlanMacHeader->aucAddr3), + prWlanMacHeader->u2SeqCtrl); + /* Check if corresponding BSS is able to send Deauth */ + for (i = 0; i < prAdapter->ucHwBssIdNum; i++) { + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, i); + + if (IS_NET_ACTIVE(prAdapter, i) && + (EQUAL_MAC_ADDR + (prWlanMacHeader->aucAddr1, + prBssInfo->aucOwnMacAddr))) { + + fgIsAbleToSendDeauth = TRUE; + ucBssIndex = (uint8_t) i; + break; + } + } + + if (!fgIsAbleToSendDeauth) + return WLAN_STATUS_FAILURE; + + pucReceiveAddr = prWlanMacHeader->aucAddr2; + } else if (prStaRec) { + prBssInfo = + GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex); + ucStaRecIdx = prStaRec->ucIndex; + ucBssIndex = prBssInfo->ucBssIndex; + + pucReceiveAddr = prStaRec->aucMacAddr; + } else if (prBssInfo) { + ucBssIndex = prBssInfo->ucBssIndex; + ucStaRecIdx = STA_REC_INDEX_BMCAST; + + pucReceiveAddr = aucBMC; + } else { + DBGLOG(SAA, WARN, "Not to send Deauth, invalid data!\n"); + return WLAN_STATUS_INVALID_DATA; + } + + /* 4 <1.2> Find Transmitter Address and BSSID. */ + pucTransmitAddr = prBssInfo->aucOwnMacAddr; + pucBssid = prBssInfo->aucBSSID; + + if (ucStaRecIdx != STA_REC_INDEX_BMCAST) { + /* 4 <2> Check if already send a Deauth frame in + * MIN_DEAUTH_INTERVAL_MSEC + */ + GET_CURRENT_SYSTIME(&rCurrentTime); + + i4NewEntryIndex = -1; + for (i = 0; i < MAX_DEAUTH_INFO_COUNT; i++) { + prDeauthInfo = &(prAdapter->rWifiVar.arDeauthInfo[i]); + + /* For continuously sending Deauth frame, the minimum + * interval is MIN_DEAUTH_INTERVAL_MSEC. + */ + if (CHECK_FOR_TIMEOUT(rCurrentTime, + prDeauthInfo->rLastSendTime, + MSEC_TO_SYSTIME + (MIN_DEAUTH_INTERVAL_MSEC))) { + + i4NewEntryIndex = i; + } else + if (EQUAL_MAC_ADDR + (pucReceiveAddr, prDeauthInfo->aucRxAddr) + && (!pfTxDoneHandler)) { + + return WLAN_STATUS_FAILURE; + } + } + + /* 4 <3> Update information. */ + if (i4NewEntryIndex > 0) { + + prDeauthInfo = + &(prAdapter-> + rWifiVar.arDeauthInfo[i4NewEntryIndex]); + + COPY_MAC_ADDR(prDeauthInfo->aucRxAddr, pucReceiveAddr); + prDeauthInfo->rLastSendTime = rCurrentTime; + } else { + /* NOTE(Kevin): for the case of AP mode, we may + * encounter this case + * if deauth all the associated clients. + */ + DBGLOG(SAA, WARN, "No unused DEAUTH_INFO_T !\n"); + } + } + /* 4 <5> Allocate a PKT_INFO_T for Deauthentication Frame */ + /* Init with MGMT Header Length + Length of Fixed Fields + IE Length */ + u2EstimatedFrameLen = + (MAC_TX_RESERVED_FIELD + WLAN_MAC_MGMT_HEADER_LEN + + REASON_CODE_FIELD_LEN); + + /* Allocate a MSDU_INFO_T */ + prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); + if (prMsduInfo == NULL) { + DBGLOG(SAA, WARN, + "No PKT_INFO_T for sending Deauth Request.\n"); + return WLAN_STATUS_RESOURCES; + } + /* 4 <6> compose Deauthentication frame header and some fixed fields */ + authComposeDeauthFrameHeaderAndFF((uint8_t *) + ((unsigned long)(prMsduInfo->prPacket) + + MAC_TX_RESERVED_FIELD), + pucReceiveAddr, pucTransmitAddr, + pucBssid, u2ReasonCode); + +#if CFG_SUPPORT_802_11W + /* AP PMF */ + if (rsnCheckBipKeyInstalled(prAdapter, prStaRec)) { + /* PMF certification 4.3.3.1, 4.3.3.2 send unprotected + * deauth reason 6/7 + * if (AP mode & not for PMF reply case) OR (STA PMF) + */ + if (((GET_BSS_INFO_BY_INDEX + (prAdapter, + prStaRec->ucBssIndex)->eCurrentOPMode == + OP_MODE_ACCESS_POINT) + && (prStaRec->rPmfCfg.fgRxDeauthResp != TRUE)) + || + (GET_BSS_INFO_BY_INDEX + (prAdapter, + prStaRec->ucBssIndex)->eNetworkType == + (uint8_t) NETWORK_TYPE_AIS)) { + + struct WLAN_DEAUTH_FRAME *prDeauthFrame; + + prDeauthFrame = (struct WLAN_DEAUTH_FRAME *)(uint8_t *) + ((unsigned long)(prMsduInfo->prPacket) + + MAC_TX_RESERVED_FIELD); + + prDeauthFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME; + if (GET_BSS_INFO_BY_INDEX(prAdapter, + prStaRec->ucBssIndex)->eNetworkType == + (uint8_t) NETWORK_TYPE_AIS) { + GET_BSS_INFO_BY_INDEX(prAdapter, + prStaRec->ucBssIndex) + ->encryptedDeauthIsInProcess + = TRUE; + } + DBGLOG(SAA, INFO, + "Reason=%d, DestAddr=" MACSTR + " srcAddr=" MACSTR " BSSID=" MACSTR "\n", + prDeauthFrame->u2ReasonCode, + MAC2STR(prDeauthFrame->aucDestAddr), + MAC2STR(prDeauthFrame->aucSrcAddr), + MAC2STR(prDeauthFrame->aucBSSID)); + } + } +#endif + nicTxSetPktLifeTime(prMsduInfo, 100); + nicTxSetPktRetryLimit(prMsduInfo, TX_DESC_TX_COUNT_NO_LIMIT); + nicTxSetForceRts(prMsduInfo, TRUE); + + /* 4 <7> Update information of MSDU_INFO_T */ + TX_SET_MMPDU(prAdapter, + prMsduInfo, + ucBssIndex, + ucStaRecIdx, + WLAN_MAC_MGMT_HEADER_LEN, + WLAN_MAC_MGMT_HEADER_LEN + REASON_CODE_FIELD_LEN, + pfTxDoneHandler, MSDU_RATE_MODE_AUTO); + +#if CFG_SUPPORT_802_11W + /* AP PMF */ + /* caution: access prStaRec only if true */ + if (rsnCheckBipKeyInstalled(prAdapter, prStaRec)) { + /* 4.3.3.1 send unprotected deauth reason 6/7 */ + if (prStaRec->rPmfCfg.fgRxDeauthResp != TRUE) { + DBGLOG(RSN, INFO, + "Deauth Set MSDU_OPT_PROTECTED_FRAME\n"); + nicTxConfigPktOption(prMsduInfo, + MSDU_OPT_PROTECTED_FRAME, TRUE); + } + + prStaRec->rPmfCfg.fgRxDeauthResp = FALSE; + } +#endif + DBGLOG(SAA, INFO, "ucTxSeqNum=%d ucStaRecIndex=%d u2ReasonCode=%d\n", + prMsduInfo->ucTxSeqNum, prMsduInfo->ucStaRecIndex, u2ReasonCode); + + /* 4 <8> Inform TXM to send this Deauthentication frame. */ + nicTxEnqueueMsdu(prAdapter, prMsduInfo); + + return WLAN_STATUS_SUCCESS; +} /* end of authSendDeauthFrame() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will parse and process the incoming Deauthentication + * frame if the given BSSID is matched. + * + * @param[in] prSwRfb Pointer to SW RFB data structure. + * @param[in] aucBSSID Given BSSID + * @param[out] pu2ReasonCode Pointer to store the Reason Code from + * Deauthentication. + * + * @retval WLAN_STATUS_FAILURE This is not the frame we should handle at + * current state. + * @retval WLAN_STATUS_SUCCESS This is the frame we should handle. + */ +/*----------------------------------------------------------------------------*/ +uint32_t authProcessRxDeauthFrame(IN struct SW_RFB *prSwRfb, + IN uint8_t aucBSSID[], + OUT uint16_t *pu2ReasonCode) +{ + struct WLAN_DEAUTH_FRAME *prDeauthFrame; + uint16_t u2RxReasonCode; + + if (!prSwRfb || !aucBSSID || !pu2ReasonCode) { + DBGLOG(SAA, WARN, "Invalid parameters, ignore pkt!\n"); + return WLAN_STATUS_FAILURE; + } + + /* 4 <1> locate the Deauthentication Frame. */ + prDeauthFrame = (struct WLAN_DEAUTH_FRAME *)prSwRfb->pvHeader; + + /* 4 <2> Parse the Header of Deauthentication Frame. */ +#if 0 /* Kevin: Seems redundant */ + WLAN_GET_FIELD_16(&prDeauthFrame->u2FrameCtrl, &u2RxFrameCtrl) + u2RxFrameCtrl &= MASK_FRAME_TYPE; + if (u2RxFrameCtrl != MAC_FRAME_DEAUTH) + return WLAN_STATUS_FAILURE; + +#endif + + if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < + REASON_CODE_FIELD_LEN) { + DBGLOG(SAA, WARN, "Invalid Deauth packet length"); + return WLAN_STATUS_FAILURE; + } + + /* Check if this Deauth Frame is coming from Target BSSID */ + if (UNEQUAL_MAC_ADDR(prDeauthFrame->aucBSSID, aucBSSID)) { + DBGLOG(SAA, LOUD, + "Ignore Deauth Frame from other BSS [" MACSTR "]\n", + MAC2STR(prDeauthFrame->aucSrcAddr)); + return WLAN_STATUS_FAILURE; + } + /* 4 <3> Parse the Fixed Fields of Deauthentication Frame Body. */ + WLAN_GET_FIELD_16(&prDeauthFrame->u2ReasonCode, &u2RxReasonCode); + *pu2ReasonCode = u2RxReasonCode; + + return WLAN_STATUS_SUCCESS; + +} /* end of authProcessRxDeauthFrame() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will parse and process the incoming Authentication + * frame. + * + * @param[in] prSwRfb Pointer to SW RFB data structure. + * @param[in] aucExpectedBSSID Given Expected BSSID. + * @param[in] u2ExpectedAuthAlgNum Given Expected Authentication Algorithm + * Number + * @param[in] u2ExpectedTransSeqNum Given Expected Transaction Sequence Number. + * @param[out] pu2ReturnStatusCode Return Status Code. + * + * @retval WLAN_STATUS_SUCCESS This is the frame we should handle. + * @retval WLAN_STATUS_FAILURE The frame we will ignore. + */ +/*----------------------------------------------------------------------------*/ +uint32_t +authProcessRxAuth1Frame(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, + IN uint8_t aucExpectedBSSID[], + IN uint16_t u2ExpectedAuthAlgNum, + IN uint16_t u2ExpectedTransSeqNum, + OUT uint16_t *pu2ReturnStatusCode) +{ + struct WLAN_AUTH_FRAME *prAuthFrame; + uint16_t u2ReturnStatusCode = STATUS_CODE_SUCCESSFUL; + + /* 4 <1> locate the Authentication Frame. */ + prAuthFrame = (struct WLAN_AUTH_FRAME *)prSwRfb->pvHeader; + + /* 4 <2> Check the BSSID */ + if (UNEQUAL_MAC_ADDR(prAuthFrame->aucBSSID, aucExpectedBSSID)) + return WLAN_STATUS_FAILURE; /* Just Ignore this MMPDU */ + + /* 4 <3> Check the SA, which should not be MC/BC */ + if (prAuthFrame->aucSrcAddr[0] & BIT(0)) { + DBGLOG(P2P, WARN, + "Invalid STA MAC with MC/BC bit set: " MACSTR "\n", + MAC2STR(prAuthFrame->aucSrcAddr)); + return WLAN_STATUS_FAILURE; + } + + /* 4 <4> Parse the Fixed Fields of Authentication Frame Body. */ + if (prAuthFrame->u2AuthAlgNum != u2ExpectedAuthAlgNum) + u2ReturnStatusCode = STATUS_CODE_AUTH_ALGORITHM_NOT_SUPPORTED; + + if (prAuthFrame->u2AuthTransSeqNo != u2ExpectedTransSeqNum) + u2ReturnStatusCode = STATUS_CODE_AUTH_OUT_OF_SEQ; + + *pu2ReturnStatusCode = u2ReturnStatusCode; + + return WLAN_STATUS_SUCCESS; + +} /* end of authProcessRxAuth1Frame() */ + +uint32_t +authProcessRxAuthFrame(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, + IN struct BSS_INFO *prBssInfo, + OUT uint16_t *pu2ReturnStatusCode) +{ + struct WLAN_AUTH_FRAME *prAuthFrame; + uint16_t u2ReturnStatusCode = STATUS_CODE_SUCCESSFUL; + + if (!prBssInfo) + return WLAN_STATUS_FAILURE; + + /* 4 <1> locate the Authentication Frame. */ + prAuthFrame = (struct WLAN_AUTH_FRAME *)prSwRfb->pvHeader; + + /* 4 <2> Check the BSSID */ + if (UNEQUAL_MAC_ADDR(prAuthFrame->aucBSSID, + prBssInfo->aucBSSID)) + return WLAN_STATUS_FAILURE; /* Just Ignore this MMPDU */ + + /* 4 <3> Check the SA, which should not be MC/BC */ + if (prAuthFrame->aucSrcAddr[0] & BIT(0)) { + DBGLOG(P2P, WARN, + "Invalid STA MAC with MC/BC bit set: " MACSTR "\n", + MAC2STR(prAuthFrame->aucSrcAddr)); + return WLAN_STATUS_FAILURE; + } + + /* 4 <4> Parse the Fixed Fields of Authentication Frame Body. */ + if (prAuthFrame->u2AuthAlgNum != AUTH_ALGORITHM_NUM_OPEN_SYSTEM && + prAuthFrame->u2AuthAlgNum != AUTH_ALGORITHM_NUM_SAE) + u2ReturnStatusCode = STATUS_CODE_AUTH_ALGORITHM_NOT_SUPPORTED; + else if (prAuthFrame->u2AuthAlgNum == AUTH_ALGORITHM_NUM_OPEN_SYSTEM && + prAuthFrame->u2AuthTransSeqNo != AUTH_TRANSACTION_SEQ_1) + u2ReturnStatusCode = STATUS_CODE_AUTH_OUT_OF_SEQ; + else if (prAuthFrame->u2AuthAlgNum == AUTH_ALGORITHM_NUM_SAE && + prAuthFrame->u2AuthTransSeqNo != AUTH_TRANSACTION_SEQ_1 && + prAuthFrame->u2AuthTransSeqNo != AUTH_TRANSACTION_SEQ_2) + u2ReturnStatusCode = STATUS_CODE_AUTH_OUT_OF_SEQ; + + DBGLOG(AAA, LOUD, "u2ReturnStatusCode = %d\n", u2ReturnStatusCode); + + *pu2ReturnStatusCode = u2ReturnStatusCode; + + return WLAN_STATUS_SUCCESS; + +} + +/* ToDo: authAddRicIE, authHandleFtIEs, authAddTimeoutIE */ + +void authAddMDIE(IN struct ADAPTER *prAdapter, + IN OUT struct MSDU_INFO *prMsduInfo) +{ + uint8_t *pucBuffer = + (uint8_t *)prMsduInfo->prPacket + prMsduInfo->u2FrameLength; + uint8_t ucBssIdx = prMsduInfo->ucBssIndex; + struct FT_IES *prFtIEs = aisGetFtIe(prAdapter, ucBssIdx); + + if (!prFtIEs->prMDIE || + !rsnIsFtOverTheAir(prAdapter, ucBssIdx, prMsduInfo->ucStaRecIndex)) + return; + prMsduInfo->u2FrameLength += + 5; /* IE size for MD IE is fixed, it is 5 */ + kalMemCopy(pucBuffer, prFtIEs->prMDIE, 5); +} + +uint32_t authCalculateRSNIELen(struct ADAPTER *prAdapter, uint8_t ucBssIdx, + struct STA_RECORD *prStaRec) +{ + struct FT_IES *prFtIEs = aisGetFtIe(prAdapter, ucBssIdx); + + if (!prFtIEs->prRsnIE || + !rsnIsFtOverTheAir(prAdapter, ucBssIdx, prStaRec->ucIndex)) + return 0; + return IE_SIZE(prFtIEs->prRsnIE); +} + +void authAddRSNIE(IN struct ADAPTER *prAdapter, + IN OUT struct MSDU_INFO *prMsduInfo) +{ + authAddRSNIE_impl(prAdapter, prMsduInfo); +} + +uint32_t authAddRSNIE_impl(IN struct ADAPTER *prAdapter, + IN OUT struct MSDU_INFO *prMsduInfo) +{ + uint8_t *pucBuffer = + (uint8_t *)prMsduInfo->prPacket + prMsduInfo->u2FrameLength; + uint32_t ucRSNIeSize = 0; + uint8_t ucBssIdx = prMsduInfo->ucBssIndex; + struct FT_IES *prFtIEs = aisGetFtIe(prAdapter, ucBssIdx); + + if (!prFtIEs->prRsnIE || + !rsnIsFtOverTheAir(prAdapter, ucBssIdx, prMsduInfo->ucStaRecIndex)) + return FALSE; + + ucRSNIeSize = IE_SIZE(prFtIEs->prRsnIE); + prMsduInfo->u2FrameLength += ucRSNIeSize; + kalMemCopy(pucBuffer, prFtIEs->prRsnIE, ucRSNIeSize); + return TRUE; +} + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/bss.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/bss.c new file mode 100644 index 0000000000000000000000000000000000000000..4056fd79e35887e0cba4e39a437ed283b04ea480 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/bss.c @@ -0,0 +1,2588 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/bss.c#7 + */ + +/*! \file "bss.c" + * \brief This file contains the functions for creating BSS(AP)/IBSS(AdHoc) + * + * This file contains the functions for BSS(AP)/IBSS(AdHoc). + * We may create a BSS/IBSS network, or merge with exist IBSS network + * and sending Beacon Frame or reply the Probe Response Frame + * for received Probe Request Frame. + */ + +/****************************************************************************** + * C O M P I L E R F L A G S + ****************************************************************************** + */ + +/****************************************************************************** + * E X T E R N A L R E F E R E N C E S + ****************************************************************************** + */ +#include "precomp.h" + +/****************************************************************************** + * C O N S T A N T S + ****************************************************************************** + */ + +/****************************************************************************** + * D A T A T Y P E S + ****************************************************************************** + */ +/****************************************************************************** + * P U B L I C D A T A + ****************************************************************************** + */ + +const uint8_t *apucNetworkType[NETWORK_TYPE_NUM] = { + (uint8_t *) "AIS", + (uint8_t *) "P2P", + (uint8_t *) "BOW", + (uint8_t *) "MBSS" +}; + +const uint8_t *apucNetworkOpMode[] = { + (uint8_t *) "INFRASTRUCTURE", + (uint8_t *) "IBSS", + (uint8_t *) "ACCESS_POINT", + (uint8_t *) "P2P_DEVICE", + (uint8_t *) "BOW" +}; + +#if (CFG_SUPPORT_ADHOC) || (CFG_SUPPORT_AAA) +struct APPEND_VAR_IE_ENTRY txBcnIETable[] = { + {(ELEM_HDR_LEN + (RATE_NUM_SW - ELEM_MAX_LEN_SUP_RATES)), NULL, + bssGenerateExtSuppRate_IE} /* 50 */ + , {(ELEM_HDR_LEN + ELEM_MAX_LEN_ERP), NULL, + rlmRspGenerateErpIE} /* 42 */ + , {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP), NULL, + rlmRspGenerateHtCapIE} /* 45 */ + , {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP), NULL, + rlmRspGenerateHtOpIE} /* 61 */ +#if CFG_ENABLE_WIFI_DIRECT + , {(ELEM_HDR_LEN + ELEM_MAX_LEN_OBSS_SCAN), NULL, + rlmRspGenerateObssScanIE} /* 74 */ +#endif + , {(ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP), NULL, + rlmRspGenerateExtCapIE} /* 127 */ + , {(ELEM_HDR_LEN + ELEM_MAX_LEN_WPA), NULL, + rsnGenerateWpaNoneIE} /* 221 */ + , {(ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_PARAM), NULL, + mqmGenerateWmmParamIE} /* 221 */ +#if CFG_ENABLE_WIFI_DIRECT + , {(ELEM_HDR_LEN + ELEM_MAX_LEN_WPA), NULL, + rsnGenerateWPAIE} /* 221 */ + , {(ELEM_HDR_LEN + ELEM_MAX_LEN_RSN), NULL, + rsnGenerateRSNIE} /* 48 */ + , {0, p2pFuncCalculateP2p_IELenForBeacon, + p2pFuncGenerateP2p_IEForBeacon} /* 221 */ + , {0, p2pFuncCalculateWSC_IELenForBeacon, + p2pFuncGenerateWSC_IEForBeacon} /* 221 */ + , {0, p2pFuncCalculateP2P_IE_NoA, + p2pFuncGenerateP2P_IE_NoA} /* 221 */ +#endif /* CFG_ENABLE_WIFI_DIRECT */ +#if CFG_SUPPORT_802_11AC + , {(ELEM_HDR_LEN + ELEM_MAX_LEN_VHT_CAP), NULL, + rlmRspGenerateVhtCapIE} /*191 */ + , {(ELEM_HDR_LEN + ELEM_MAX_LEN_VHT_OP), NULL, + rlmRspGenerateVhtOpIE} /*192 */ + , {(ELEM_HDR_LEN + ELEM_MAX_LEN_VHT_OP_MODE_NOTIFICATION), NULL, + rlmRspGenerateVhtOpNotificationIE} /*199 */ +#endif +#if CFG_SUPPORT_802_11AX + , {0, heRlmCalculateHeCapIELen, + heRlmRspGenerateHeCapIE} /* 255, EXT 35 */ + , {0, heRlmCalculateHeOpIELen, + heRlmRspGenerateHeOpIE} /* 255, EXT 36 */ +#endif +#if CFG_SUPPORT_MTK_SYNERGY + , {(ELEM_HDR_LEN + ELEM_MIN_LEN_MTK_OUI), NULL, + rlmGenerateMTKOuiIE} /* 221 */ +#endif +#if (CFG_SUPPORT_DFS_MASTER == 1) + , {(ELEM_HDR_LEN + ELEM_MIN_LEN_CSA), NULL, + rlmGenerateCsaIE} /* 37 */ +#endif + +}; + +struct APPEND_VAR_IE_ENTRY txProbRspIETable[] = { + {(ELEM_HDR_LEN + (RATE_NUM_SW - ELEM_MAX_LEN_SUP_RATES)), NULL, + bssGenerateExtSuppRate_IE} /* 50 */ + , {(ELEM_HDR_LEN + ELEM_MAX_LEN_ERP), NULL, + rlmRspGenerateErpIE} /* 42 */ + , {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP), NULL, + rlmRspGenerateHtCapIE} /* 45 */ + , {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP), NULL, + rlmRspGenerateHtOpIE} /* 61 */ +#if CFG_ENABLE_WIFI_DIRECT + , {(ELEM_HDR_LEN + ELEM_MAX_LEN_WPA), NULL, + rsnGenerateWPAIE} /* 221 */ + , {(ELEM_HDR_LEN + ELEM_MAX_LEN_RSN), NULL, + rsnGenerateRSNIE} /* 48 */ + , {(ELEM_HDR_LEN + ELEM_MAX_LEN_OBSS_SCAN), NULL, + rlmRspGenerateObssScanIE} /* 74 */ +#endif + , {(ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP), NULL, + rlmRspGenerateExtCapIE} /* 127 */ + , {(ELEM_HDR_LEN + ELEM_MAX_LEN_WPA), NULL, + rsnGenerateWpaNoneIE} /* 221 */ + , {(ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_PARAM), NULL, + mqmGenerateWmmParamIE} /* 221 */ +#if CFG_SUPPORT_802_11AC + , {(ELEM_HDR_LEN + ELEM_MAX_LEN_VHT_CAP), NULL, + rlmRspGenerateVhtCapIE} /*191 */ + , {(ELEM_HDR_LEN + ELEM_MAX_LEN_VHT_OP), NULL, + rlmRspGenerateVhtOpIE} /*192 */ + , {(ELEM_HDR_LEN + ELEM_MAX_LEN_VHT_OP_MODE_NOTIFICATION), NULL, + rlmRspGenerateVhtOpNotificationIE} /*199 */ +#endif +#if CFG_SUPPORT_802_11AX + , {0, heRlmCalculateHeCapIELen, + heRlmRspGenerateHeCapIE} /* 255, EXT 35 */ + , {0, heRlmCalculateHeOpIELen, + heRlmRspGenerateHeOpIE} /* 255, EXT 36 */ +#endif +#if CFG_SUPPORT_MTK_SYNERGY + , {(ELEM_HDR_LEN + ELEM_MIN_LEN_MTK_OUI), NULL, + rlmGenerateMTKOuiIE} /* 221 */ +#endif + +}; + +#endif /* CFG_SUPPORT_ADHOC || CFG_SUPPORT_AAA */ + +/****************************************************************************** + * P R I V A T E D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * M A C R O S + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N D E C L A R A T I O N S + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N S + ****************************************************************************** + */ +/*---------------------------------------------------------------------------*/ +/* Routines for all Operation Modes */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/*! + * @brief This function will decide PHY type set of STA_RECORD_T by given + * BSS_DESC_T for Infrastructure or AdHoc Mode. + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] prBssDesc Received Beacon/ProbeResp from this STA + * @param[out] prStaRec StaRec to be decided PHY type set + * + * @retval VOID + */ +/*---------------------------------------------------------------------------*/ +void bssDetermineStaRecPhyTypeSet(IN struct ADAPTER *prAdapter, + IN struct BSS_DESC *prBssDesc, + OUT struct STA_RECORD *prStaRec) +{ + struct WIFI_VAR *prWifiVar = &prAdapter->rWifiVar; + uint8_t ucHtOption = FEATURE_ENABLED; + uint8_t ucVhtOption = FEATURE_ENABLED; + struct BSS_INFO *prBssInfo; +#if (CFG_SUPPORT_802_11AX == 1) + uint8_t ucHeOption = FEATURE_ENABLED; +#endif + + prStaRec->ucPhyTypeSet = prBssDesc->ucPhyTypeSet; +#if CFG_SUPPORT_BFEE + prStaRec->ucVhtCapNumSoundingDimensions = + prBssDesc->ucVhtCapNumSoundingDimensions; +#endif + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prStaRec->ucBssIndex); + + /* Decide AIS PHY type set */ + if (prStaRec->eStaType == STA_TYPE_LEGACY_AP) { + struct CONNECTION_SETTINGS *prConnSettings; + enum ENUM_WEP_STATUS eEncStatus; + + prConnSettings = + aisGetConnSettings(prAdapter, prStaRec->ucBssIndex); + + eEncStatus = prConnSettings->eEncStatus; + + if (!(eEncStatus == ENUM_ENCRYPTION3_ENABLED || + eEncStatus == ENUM_ENCRYPTION3_KEY_ABSENT || + eEncStatus == ENUM_ENCRYPTION_DISABLED || + eEncStatus == ENUM_ENCRYPTION4_ENABLED || + eEncStatus == ENUM_ENCRYPTION4_KEY_ABSENT + )) { + DBGLOG(BSS, INFO, + "Ignore the HT/VHT Bit for TKIP as pairwise cipher configed!\n"); + prStaRec->ucPhyTypeSet &= + ~(PHY_TYPE_BIT_HT | PHY_TYPE_BIT_VHT); +#if (CFG_SUPPORT_802_11AX == 1) + prStaRec->ucPhyTypeSet &= ~(PHY_TYPE_BIT_HE); +#endif + } + + ucHtOption = prWifiVar->ucStaHt; + ucVhtOption = prWifiVar->ucStaVht; +#if (CFG_SUPPORT_802_11AX == 1) + if (fgEfuseCtrlAxOn == 1) + ucHeOption = prWifiVar->ucStaHe; +#endif + + } + /* Decide P2P GC PHY type set */ + else if (prStaRec->eStaType == STA_TYPE_P2P_GO) { + ucHtOption = prWifiVar->ucP2pGcHt; + ucVhtOption = prWifiVar->ucP2pGcVht; +#if (CFG_SUPPORT_802_11AX == 1) + ucHeOption = prWifiVar->ucP2pGcHe; +#endif + + } + + /* Set HT/VHT capability from Feature Option */ + if (IS_FEATURE_DISABLED(ucHtOption)) + prStaRec->ucPhyTypeSet &= ~PHY_TYPE_BIT_HT; + else if (IS_FEATURE_FORCE_ENABLED(ucHtOption)) + prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_HT; + + if (IS_FEATURE_DISABLED(ucVhtOption)) + prStaRec->ucPhyTypeSet &= ~PHY_TYPE_BIT_VHT; + else if (IS_FEATURE_FORCE_ENABLED(ucVhtOption)) + prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_VHT; + else if (prBssInfo->eBand == BAND_2G4 && + IS_FEATURE_DISABLED(prWifiVar->ucVhtIeIn2g)) { + prStaRec->ucPhyTypeSet &= ~PHY_TYPE_BIT_VHT; + } + +#if (CFG_SUPPORT_802_11AX == 1) + if (fgEfuseCtrlAxOn == 1) { + if (IS_FEATURE_DISABLED(ucHeOption)) + prStaRec->ucPhyTypeSet &= ~PHY_TYPE_BIT_HE; + else if (IS_FEATURE_FORCE_ENABLED(ucHeOption)) + prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_HE; + } +#endif + + prStaRec->ucDesiredPhyTypeSet = + prStaRec->ucPhyTypeSet & prAdapter->rWifiVar.ucAvailablePhyTypeSet; + +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will decide PHY type set of BSS_INFO for + * AP Mode. + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] fgIsApMode Legacy AP mode or P2P GO + * @param[out] prBssInfo BssInfo to be decided PHY type set + * + * @retval VOID + */ +/*----------------------------------------------------------------------------*/ +void bssDetermineApBssInfoPhyTypeSet(IN struct ADAPTER *prAdapter, + IN u_int8_t fgIsPureAp, + OUT struct BSS_INFO *prBssInfo) +{ + struct WIFI_VAR *prWifiVar = &prAdapter->rWifiVar; + uint8_t ucHtOption = FEATURE_ENABLED; + uint8_t ucVhtOption = FEATURE_ENABLED; +#if (CFG_SUPPORT_802_11AX == 1) + uint8_t ucHeOption = FEATURE_ENABLED; +#endif + + /* Decide AP mode PHY type set */ + if (fgIsPureAp) { + ucHtOption = prWifiVar->ucApHt; + ucVhtOption = prWifiVar->ucApVht; +#if (CFG_SUPPORT_802_11AX == 1) + ucHeOption = prWifiVar->ucApHe; +#endif + } + /* Decide P2P GO PHY type set */ + else { + ucHtOption = prWifiVar->ucP2pGoHt; + ucVhtOption = prWifiVar->ucP2pGoVht; +#if (CFG_SUPPORT_802_11AX == 1) + ucHeOption = prWifiVar->ucP2pGoHe; +#endif + } + + /* Set HT/VHT capability from Feature Option */ + if (IS_FEATURE_DISABLED(ucHtOption)) + prBssInfo->ucPhyTypeSet &= ~PHY_TYPE_BIT_HT; + else if (IS_FEATURE_FORCE_ENABLED(ucHtOption)) + prBssInfo->ucPhyTypeSet |= PHY_TYPE_BIT_HT; + else if (!fgIsPureAp && IS_FEATURE_ENABLED(ucHtOption)) + prBssInfo->ucPhyTypeSet |= PHY_TYPE_BIT_HT; + + if (IS_FEATURE_DISABLED(ucVhtOption)) { + prBssInfo->ucPhyTypeSet &= ~PHY_TYPE_BIT_VHT; + } else if (IS_FEATURE_FORCE_ENABLED(ucVhtOption)) { + prBssInfo->ucPhyTypeSet |= PHY_TYPE_BIT_VHT; + } else if (IS_FEATURE_ENABLED(ucVhtOption) && + prBssInfo->eBand == BAND_2G4 && + prWifiVar->ucVhtIeIn2g && + (prBssInfo->ucPhyTypeSet & PHY_TYPE_SET_802_11N)) { + prBssInfo->ucPhyTypeSet |= PHY_TYPE_BIT_VHT; + } else if (!fgIsPureAp && + IS_FEATURE_ENABLED(ucVhtOption) && + (prBssInfo->eBand == BAND_5G)) { + prBssInfo->ucPhyTypeSet |= PHY_TYPE_BIT_VHT; + } + +#if (CFG_SUPPORT_802_11AX == 1) + if (IS_FEATURE_DISABLED(ucHeOption)) + prBssInfo->ucPhyTypeSet &= ~PHY_TYPE_BIT_HE; + else if (IS_FEATURE_FORCE_ENABLED(ucHeOption)) + prBssInfo->ucPhyTypeSet |= PHY_TYPE_BIT_HE; + else if (!fgIsPureAp && IS_FEATURE_ENABLED(ucHeOption)) + prBssInfo->ucPhyTypeSet |= PHY_TYPE_BIT_HE; +#endif + + prBssInfo->ucPhyTypeSet &= prAdapter->rWifiVar.ucAvailablePhyTypeSet; + +} + +/*---------------------------------------------------------------------------*/ +/*! + * @brief This function will create or reset a STA_RECORD_T by given BSS_DESC_T + * for Infrastructure or AdHoc Mode. + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] eStaType Assign STA Type for this STA_RECORD_T + * @param[in] eNetTypeIndex Assign Net Type Index for this + * STA_RECORD_T + * @param[in] prBssDesc Received Beacon/ProbeResp from this STA + * + * @retval Pointer to STA_RECORD_T + */ +/*---------------------------------------------------------------------------*/ +struct STA_RECORD *bssCreateStaRecFromBssDesc(IN struct ADAPTER *prAdapter, + IN enum ENUM_STA_TYPE eStaType, + IN uint8_t ucBssIndex, + IN struct BSS_DESC *prBssDesc) +{ + struct STA_RECORD *prStaRec; + uint8_t ucNonHTPhyTypeSet; + struct CONNECTION_SETTINGS *prConnSettings; + + prConnSettings = aisGetConnSettings(prAdapter, ucBssIndex); + + /* 4 <1> Get a valid STA_RECORD_T */ + prStaRec = + cnmGetStaRecByAddress(prAdapter, ucBssIndex, prBssDesc->aucSrcAddr); + if (!prStaRec) { + prStaRec = + cnmStaRecAlloc(prAdapter, eStaType, ucBssIndex, + prBssDesc->aucSrcAddr); + + if (!prStaRec) { + DBGLOG(BSS, WARN, + "STA_REC entry is full, cannot acquire new entry for [" + MACSTR "]!!\n", MAC2STR(prBssDesc->aucSrcAddr)); + return NULL; + } + + prStaRec->ucStaState = STA_STATE_1; + prStaRec->ucJoinFailureCount = 0; + /* TODO(Kevin): If this is an old entry, + * we may also reset the ucJoinFailureCount to 0. + */ + } + /* 4 <2> Update information from BSS_DESC_T to current P_STA_RECORD_T */ + prStaRec->u2CapInfo = prBssDesc->u2CapInfo; + + prStaRec->u2OperationalRateSet = prBssDesc->u2OperationalRateSet; + prStaRec->u2BSSBasicRateSet = prBssDesc->u2BSSBasicRateSet; + +#if 1 + bssDetermineStaRecPhyTypeSet(prAdapter, prBssDesc, prStaRec); +#else + prStaRec->ucPhyTypeSet = prBssDesc->ucPhyTypeSet; + + if (IS_STA_IN_AIS(prStaRec)) { + if (! + ((prConnSettings->eEncStatus == + ENUM_ENCRYPTION3_ENABLED) + || (prConnSettings->eEncStatus == + ENUM_ENCRYPTION3_KEY_ABSENT) + || (prConnSettings->eEncStatus == + ENUM_ENCRYPTION_DISABLED) + || (prAdapter->prGlueInfo->u2WSCAssocInfoIELen) +#if CFG_SUPPORT_WAPI + || (prAdapter->prGlueInfo->u2WapiAssocInfoIESz) +#endif +)) { + DBGLOG(BSS, INFO, + "Ignore the HT Bit for TKIP as pairwise cipher configed!\n"); + prStaRec->ucPhyTypeSet &= ~PHY_TYPE_BIT_HT; + } + } + + prStaRec->ucDesiredPhyTypeSet = + prStaRec->ucPhyTypeSet & prAdapter->rWifiVar.ucAvailablePhyTypeSet; +#endif + + ucNonHTPhyTypeSet = + prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_SET_802_11ABG; + + /* Check for Target BSS's non HT Phy Types */ + if (ucNonHTPhyTypeSet) { + + if (ucNonHTPhyTypeSet & PHY_TYPE_BIT_ERP) { + prStaRec->ucNonHTBasicPhyType = PHY_TYPE_ERP_INDEX; + } else if (ucNonHTPhyTypeSet & PHY_TYPE_BIT_OFDM) { + prStaRec->ucNonHTBasicPhyType = PHY_TYPE_OFDM_INDEX; + } else {/* if (ucNonHTPhyTypeSet & PHY_TYPE_HR_DSSS_INDEX) */ + + prStaRec->ucNonHTBasicPhyType = PHY_TYPE_HR_DSSS_INDEX; + } + + prStaRec->fgHasBasicPhyType = TRUE; + } else { + /* Use mandatory for 11N only BSS */ + { + /* TODO(Kevin): which value should we set + * for 11n ? ERP ? + */ + prStaRec->ucNonHTBasicPhyType = PHY_TYPE_HR_DSSS_INDEX; + } + + prStaRec->fgHasBasicPhyType = FALSE; + } + + /* Update non HT Desired Rate Set */ + prStaRec->u2DesiredNonHTRateSet = + (prStaRec-> + u2OperationalRateSet & prConnSettings->u2DesiredNonHTRateSet); + + /* 4 <3> Update information from BSS_DESC_T to current P_STA_RECORD_T */ + if (IS_AP_STA(prStaRec)) { + /* do not need to parse IE for DTIM, + * which have been parsed before inserting into struct BSS_DESC + */ + if (prBssDesc->ucDTIMPeriod) + prStaRec->ucDTIMPeriod = prBssDesc->ucDTIMPeriod; + else + prStaRec->ucDTIMPeriod = 0; + /* Means that TIM was not parsed. */ + + } + /* 4 <4> Update default value */ + prStaRec->fgDiagnoseConnection = FALSE; + + /* 4 <5> Update default value for other Modules */ + /* Determine WMM related parameters for STA_REC */ + mqmProcessScanResult(prAdapter, prBssDesc, prStaRec); + + /* 4 <6> Update Tx Rate */ + /* Update default Tx rate */ + nicTxUpdateStaRecDefaultRate(prAdapter, prStaRec); + + return prStaRec; + +} /* end of bssCreateStaRecFromBssDesc() */ + +/*---------------------------------------------------------------------------*/ +/*! + * @brief This function will compose the Null Data frame. + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] pucBuffer Pointer to the frame buffer. + * @param[in] prStaRec Pointer to the STA_RECORD_T. + * + * @return (none) + */ +/*---------------------------------------------------------------------------*/ +void bssComposeNullFrame(IN struct ADAPTER *prAdapter, IN uint8_t *pucBuffer, + IN struct STA_RECORD *prStaRec) +{ + struct WLAN_MAC_HEADER *prNullFrame; + struct BSS_INFO *prBssInfo; + uint16_t u2FrameCtrl; + uint8_t ucBssIndex; + + ucBssIndex = prStaRec->ucBssIndex; + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + prNullFrame = (struct WLAN_MAC_HEADER *)pucBuffer; + + /* 4 <1> Decide the Frame Control Field */ + u2FrameCtrl = MAC_FRAME_NULL; + + if (IS_AP_STA(prStaRec)) { + u2FrameCtrl |= MASK_FC_TO_DS; + + if (prStaRec->fgSetPwrMgtBit) + u2FrameCtrl |= MASK_FC_PWR_MGT; + + } else if (IS_CLIENT_STA(prStaRec)) { + u2FrameCtrl |= MASK_FC_FROM_DS; + } else if (IS_DLS_STA(prStaRec)) { + /* TODO(Kevin) */ + } else { + /* NOTE(Kevin): We won't send Null frame for IBSS */ + ASSERT(0); + return; + } + + /* 4 <2> Compose the Null frame */ + /* Fill the Frame Control field. */ + /* WLAN_SET_FIELD_16(&prNullFrame->u2FrameCtrl, u2FrameCtrl); */ + prNullFrame->u2FrameCtrl = u2FrameCtrl; + /* NOTE(Kevin): Optimized for ARM */ + + /* Fill the Address 1 field with Target Peer Address. */ + COPY_MAC_ADDR(prNullFrame->aucAddr1, prStaRec->aucMacAddr); + + /* Fill the Address 2 field with our MAC Address. */ + COPY_MAC_ADDR(prNullFrame->aucAddr2, prBssInfo->aucOwnMacAddr); + + /* Fill the Address 3 field with Target BSSID. */ + COPY_MAC_ADDR(prNullFrame->aucAddr3, prBssInfo->aucBSSID); + + /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, + * so we need to clear it). + */ + prNullFrame->u2SeqCtrl = 0; + + return; + +} /* end of bssComposeNullFrameHeader() */ + +/*---------------------------------------------------------------------------*/ +/*! + * @brief This function will compose the QoS Null Data frame. + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] pucBuffer Pointer to the frame buffer. + * @param[in] prStaRec Pointer to the STA_RECORD_T. + * @param[in] ucUP User Priority. + * @param[in] fgSetEOSP Set the EOSP bit. + * + * @return (none) + */ +/*---------------------------------------------------------------------------*/ +void +bssComposeQoSNullFrame(IN struct ADAPTER *prAdapter, + IN uint8_t *pucBuffer, IN struct STA_RECORD *prStaRec, + IN uint8_t ucUP, IN u_int8_t fgSetEOSP) +{ + struct WLAN_MAC_HEADER_QOS *prQoSNullFrame; + struct BSS_INFO *prBssInfo; + uint16_t u2FrameCtrl; + uint16_t u2QosControl; + uint8_t ucBssIndex; + + ucBssIndex = prStaRec->ucBssIndex; + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + prQoSNullFrame = (struct WLAN_MAC_HEADER_QOS *)pucBuffer; + + /* 4 <1> Decide the Frame Control Field */ + u2FrameCtrl = MAC_FRAME_QOS_NULL; + + if (IS_AP_STA(prStaRec)) { + u2FrameCtrl |= MASK_FC_TO_DS; + + if (prStaRec->fgSetPwrMgtBit) + u2FrameCtrl |= MASK_FC_PWR_MGT; + + } else if (IS_CLIENT_STA(prStaRec)) { + u2FrameCtrl |= MASK_FC_FROM_DS; + } else if (IS_DLS_STA(prStaRec)) { + /* TODO(Kevin) */ + } else { + /* NOTE(Kevin): We won't send QoS Null frame for IBSS */ + ASSERT(0); + return; + } + + /* 4 <2> Compose the QoS Null frame */ + /* Fill the Frame Control field. */ + /* WLAN_SET_FIELD_16(&prQoSNullFrame->u2FrameCtrl, u2FrameCtrl); */ + prQoSNullFrame->u2FrameCtrl = u2FrameCtrl; + /* NOTE(Kevin): Optimized for ARM */ + + /* Fill the Address 1 field with Target Peer Address. */ + COPY_MAC_ADDR(prQoSNullFrame->aucAddr1, prStaRec->aucMacAddr); + + /* Fill the Address 2 field with our MAC Address. */ + COPY_MAC_ADDR(prQoSNullFrame->aucAddr2, prBssInfo->aucOwnMacAddr); + + /* Fill the Address 3 field with Target BSSID. */ + COPY_MAC_ADDR(prQoSNullFrame->aucAddr3, prBssInfo->aucBSSID); + + /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, + * so we need to clear it). + */ + prQoSNullFrame->u2SeqCtrl = 0; + + u2QosControl = (uint16_t) (ucUP & WMM_QC_UP_MASK); + + if (fgSetEOSP) + u2QosControl |= WMM_QC_EOSP; + + /* WLAN_SET_FIELD_16(&prQoSNullFrame->u2QosCtrl, u2QosControl); */ + prQoSNullFrame->u2QosCtrl = u2QosControl; + /* NOTE(Kevin): Optimized for ARM */ + + return; + +} /* end of bssComposeQoSNullFrameHeader() */ + +/*---------------------------------------------------------------------------*/ +/*! + * @brief Send the Null Frame + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] prStaRec Pointer to the STA_RECORD_T + * @param[in] pfTxDoneHandler TX Done call back function + * + * @retval WLAN_STATUS_RESOURCE No available resources to send frame. + * @retval WLAN_STATUS_SUCCESS Succe]ss. + */ +/*---------------------------------------------------------------------------*/ +uint32_t +bssSendNullFrame(IN struct ADAPTER *prAdapter, IN struct STA_RECORD *prStaRec, + IN PFN_TX_DONE_HANDLER pfTxDoneHandler) +{ + struct MSDU_INFO *prMsduInfo; + uint16_t u2EstimatedFrameLen; + + /* 4 <1> Allocate a PKT_INFO_T for Null Frame */ + /* Init with MGMT Header Length */ + u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + WLAN_MAC_HEADER_LEN; + + /* Allocate a MSDU_INFO_T */ + prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); + if (prMsduInfo == NULL) { + DBGLOG(BSS, WARN, "No PKT_INFO_T for sending Null Frame.\n"); + return WLAN_STATUS_RESOURCES; + } + /* 4 <2> Compose Null frame in MSDU_INfO_T. */ + bssComposeNullFrame(prAdapter, + (uint8_t *) ((unsigned long)prMsduInfo->prPacket + + MAC_TX_RESERVED_FIELD), prStaRec); + TX_SET_MMPDU(prAdapter, + prMsduInfo, + prStaRec->ucBssIndex, + prStaRec->ucIndex, WLAN_MAC_HEADER_LEN, + WLAN_MAC_HEADER_LEN, pfTxDoneHandler, MSDU_RATE_MODE_AUTO); + + /* 4 <4> Inform TXM to send this Null frame. */ + nicTxEnqueueMsdu(prAdapter, prMsduInfo); + + return WLAN_STATUS_SUCCESS; + +} /* end of bssSendNullFrame() */ + +/*---------------------------------------------------------------------------*/ +/*! + * @brief Send the QoS Null Frame + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] prStaRec Pointer to the STA_RECORD_T + * @param[in] pfTxDoneHandler TX Done call back function + * + * @retval WLAN_STATUS_RESOURCE No available resources to send frame. + * @retval WLAN_STATUS_SUCCESS Success. + */ +/*---------------------------------------------------------------------------*/ +uint32_t +bssSendQoSNullFrame(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, IN uint8_t ucUP, + IN PFN_TX_DONE_HANDLER pfTxDoneHandler) +{ + struct MSDU_INFO *prMsduInfo; + uint16_t u2EstimatedFrameLen; + + /* 4 <1> Allocate a PKT_INFO_T for Null Frame */ + /* Init with MGMT Header Length */ + u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + WLAN_MAC_HEADER_QOS_LEN; + + /* Allocate a MSDU_INFO_T */ + prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); + if (prMsduInfo == NULL) { + DBGLOG(BSS, WARN, "No PKT_INFO_T for sending Null Frame.\n"); + return WLAN_STATUS_RESOURCES; + } + /* 4 <2> Compose Null frame in MSDU_INfO_T. */ + bssComposeQoSNullFrame(prAdapter, + (uint8_t + *) ((unsigned long)(prMsduInfo->prPacket) + + MAC_TX_RESERVED_FIELD), prStaRec, ucUP, + FALSE); + + TX_SET_MMPDU(prAdapter, + prMsduInfo, + prStaRec->ucBssIndex, + prStaRec->ucIndex, + WLAN_MAC_HEADER_QOS_LEN, WLAN_MAC_HEADER_QOS_LEN, + pfTxDoneHandler, MSDU_RATE_MODE_AUTO); + + /* 4 <4> Inform TXM to send this Null frame. */ + nicTxEnqueueMsdu(prAdapter, prMsduInfo); + + return WLAN_STATUS_SUCCESS; + +} /* end of bssSendQoSNullFrame() */ + +#if (CFG_SUPPORT_ADHOC) || (CFG_SUPPORT_AAA) +/*---------------------------------------------------------------------------*/ +/* Routines for both IBSS(AdHoc) and BSS(AP) */ +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +/*! + * @brief This function is used to generate Information Elements of Extended + * Support Rate + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. + * + * @return (none) + */ +/*---------------------------------------------------------------------------*/ +void bssGenerateExtSuppRate_IE(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo) +{ + struct BSS_INFO *prBssInfo; + uint8_t *pucBuffer; + uint8_t ucExtSupRatesLen; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prMsduInfo->ucBssIndex); + pucBuffer = + (uint8_t *) ((unsigned long)prMsduInfo->prPacket + + (unsigned long)prMsduInfo->u2FrameLength); + + if (prBssInfo->ucAllSupportedRatesLen > ELEM_MAX_LEN_SUP_RATES) + + ucExtSupRatesLen = + prBssInfo->ucAllSupportedRatesLen - ELEM_MAX_LEN_SUP_RATES; + else + ucExtSupRatesLen = 0; + + /* Fill the Extended Supported Rates element. */ + if (ucExtSupRatesLen) { + + EXT_SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_EXTENDED_SUP_RATES; + EXT_SUP_RATES_IE(pucBuffer)->ucLength = ucExtSupRatesLen; + + kalMemCopy(EXT_SUP_RATES_IE(pucBuffer)->aucExtSupportedRates, + &prBssInfo->aucAllSupportedRates + [ELEM_MAX_LEN_SUP_RATES], ucExtSupRatesLen); + + prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); + } +} /* end of bssGenerateExtSuppRate_IE() */ + +/*---------------------------------------------------------------------------*/ +/*! + * @brief This function is used to compose Common Information Elements for + * Beacon or Probe Response Frame. + * + * @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. + * @param[in] prBssInfo Pointer to the BSS_INFO_T. + * @param[in] pucDestAddr Pointer to the Destination Address, + * if NULL, means Beacon. + * + * @return (none) + */ +/*---------------------------------------------------------------------------*/ +void +bssBuildBeaconProbeRespFrameCommonIEs(IN struct MSDU_INFO *prMsduInfo, + IN struct BSS_INFO *prBssInfo, + IN uint8_t *pucDestAddr) +{ + uint8_t *pucBuffer; + uint8_t ucSupRatesLen; + + pucBuffer = + (uint8_t *) ((unsigned long)prMsduInfo->prPacket + + (unsigned long)prMsduInfo->u2FrameLength); + /* 4 <1> Fill the SSID element. */ + SSID_IE(pucBuffer)->ucId = ELEM_ID_SSID; + + if ((!pucDestAddr) + && (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT)) { + /* For Beacon */ + if (prBssInfo->eHiddenSsidType == + ENUM_HIDDEN_SSID_ZERO_CONTENT) { + /* clear the data, but keep the correct + * length of the SSID + */ + SSID_IE(pucBuffer)->ucLength = prBssInfo->ucSSIDLen; + kalMemZero(SSID_IE(pucBuffer)->aucSSID, + prBssInfo->ucSSIDLen); + } else if (prBssInfo->eHiddenSsidType == + ENUM_HIDDEN_SSID_ZERO_LEN) { + /* empty SSID */ + SSID_IE(pucBuffer)->ucLength = 0; + } else { + SSID_IE(pucBuffer)->ucLength = prBssInfo->ucSSIDLen; + if (prBssInfo->ucSSIDLen) + kalMemCopy(SSID_IE(pucBuffer)->aucSSID, + prBssInfo->aucSSID, + prBssInfo->ucSSIDLen); + } + } else { /* Probe response */ + SSID_IE(pucBuffer)->ucLength = prBssInfo->ucSSIDLen; + if (prBssInfo->ucSSIDLen) + kalMemCopy(SSID_IE(pucBuffer)->aucSSID, + prBssInfo->aucSSID, prBssInfo->ucSSIDLen); + } + + prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); + pucBuffer += IE_SIZE(pucBuffer); + + /* 4 <2> Fill the Supported Rates element. */ + if (prBssInfo->ucAllSupportedRatesLen > ELEM_MAX_LEN_SUP_RATES) + + ucSupRatesLen = ELEM_MAX_LEN_SUP_RATES; + else + ucSupRatesLen = prBssInfo->ucAllSupportedRatesLen; + + if (ucSupRatesLen) { + SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_SUP_RATES; + SUP_RATES_IE(pucBuffer)->ucLength = ucSupRatesLen; + kalMemCopy(SUP_RATES_IE(pucBuffer)->aucSupportedRates, + prBssInfo->aucAllSupportedRates, ucSupRatesLen); + + prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); + pucBuffer += IE_SIZE(pucBuffer); + } + + /* 4 <3> Fill the DS Parameter Set element. */ + if (prBssInfo->eBand == BAND_2G4) { + DS_PARAM_IE(pucBuffer)->ucId = ELEM_ID_DS_PARAM_SET; + DS_PARAM_IE(pucBuffer)->ucLength = + ELEM_MAX_LEN_DS_PARAMETER_SET; + DS_PARAM_IE(pucBuffer)->ucCurrChnl = + prBssInfo->ucPrimaryChannel; + + prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); + pucBuffer += IE_SIZE(pucBuffer); + } + + /* 4 <4> IBSS Parameter Set element, ID: 6 */ + if (prBssInfo->eCurrentOPMode == OP_MODE_IBSS) { + IBSS_PARAM_IE(pucBuffer)->ucId = ELEM_ID_IBSS_PARAM_SET; + IBSS_PARAM_IE(pucBuffer)->ucLength = + ELEM_MAX_LEN_IBSS_PARAMETER_SET; + WLAN_SET_FIELD_16(&(IBSS_PARAM_IE(pucBuffer)->u2ATIMWindow), + prBssInfo->u2ATIMWindow); + + prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); + pucBuffer += IE_SIZE(pucBuffer); + } + + /* 4 <5> TIM element, ID: 5 */ + if ((!pucDestAddr) && /* For Beacon only. */ + (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT)) { +#if CFG_ENABLE_WIFI_DIRECT + /*no fgIsP2PRegistered protect */ + if (prBssInfo->eNetworkType == NETWORK_TYPE_P2P) { + /* IEEE 802.11 2007 - 7.3.2.6 */ + TIM_IE(pucBuffer)->ucId = ELEM_ID_TIM; + /* NOTE: fixed PVB length + * (AID is allocated from 8 ~ 15 only) + */ + TIM_IE(pucBuffer)->ucLength = + (3 + + MAX_LEN_TIM_PARTIAL_BMP) /*((u4N2 - u4N1) + 4) */; + TIM_IE(pucBuffer)->ucDTIMCount = + 0 /*prBssInfo->ucDTIMCount */; + /* will be overwritten by FW */ + TIM_IE(pucBuffer)->ucDTIMPeriod = + prBssInfo->ucDTIMPeriod; + /* will be overwritten by FW */ + TIM_IE(pucBuffer)->ucBitmapControl = + 0 /*ucBitmapControl | (uint8_t)u4N1 */; + + prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); + pucBuffer += IE_SIZE(pucBuffer); + } else +#endif /* CFG_ENABLE_WIFI_DIRECT */ + { + /* NOTE(Kevin): 1. AIS - Didn't Support AP Mode. + * 2. BOW - Didn't Support BCAST and PS. + */ + } + } + + /* 4 <6> Fill the DS Parameter Set element. */ + if (prBssInfo->ucCountryIELen != 0) { + COUNTRY_IE(pucBuffer)->ucId = ELEM_ID_COUNTRY_INFO; + COUNTRY_IE(pucBuffer)->ucLength = prBssInfo->ucCountryIELen; + COUNTRY_IE(pucBuffer)->aucCountryStr[0] = + prBssInfo->aucCountryStr[0]; + COUNTRY_IE(pucBuffer)->aucCountryStr[1] = + prBssInfo->aucCountryStr[1]; + COUNTRY_IE(pucBuffer)->aucCountryStr[2] = + prBssInfo->aucCountryStr[2]; + kalMemCopy(COUNTRY_IE(pucBuffer)->arCountryStr, + prBssInfo->aucSubbandTriplet, + prBssInfo->ucCountryIELen - 3); + + prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); + } +} /* end of bssBuildBeaconProbeRespFrameCommonIEs() */ + +/*---------------------------------------------------------------------------*/ +/*! + * @brief This function will compose the Beacon/Probe Response frame header + * and its fixed fields. + * + * @param[in] pucBuffer Pointer to the frame buffer. + * @param[in] pucDestAddr Pointer to the Destination Address, + * if NULL, means Beacon. + * @param[in] pucOwnMACAddress Given Our MAC Address. + * @param[in] pucBSSID Given BSSID of the BSS. + * @param[in] u2BeaconInterval Given Beacon Interval. + * @param[in] u2CapInfo Given Capability Info. + * + * @return (none) + */ +/*---------------------------------------------------------------------------*/ +void +bssComposeBeaconProbeRespFrameHeaderAndFF(IN uint8_t *pucBuffer, + IN uint8_t *pucDestAddr, + IN uint8_t *pucOwnMACAddress, + IN uint8_t *pucBSSID, + IN uint16_t u2BeaconInterval, + IN uint16_t u2CapInfo) +{ + struct WLAN_BEACON_FRAME *prBcnProbRspFrame; + uint8_t aucBCAddr[] = BC_MAC_ADDR; + uint16_t u2FrameCtrl; + + DEBUGFUNC("bssComposeBeaconProbeRespFrameHeaderAndFF"); + /* DBGLOG(INIT, LOUD, ("\n")); */ + + prBcnProbRspFrame = (struct WLAN_BEACON_FRAME *)pucBuffer; + + /* 4 <1> Compose the frame header of the Beacon /ProbeResp frame. */ + /* Fill the Frame Control field. */ + if (pucDestAddr) { + u2FrameCtrl = MAC_FRAME_PROBE_RSP; + } else { + u2FrameCtrl = MAC_FRAME_BEACON; + pucDestAddr = aucBCAddr; + } + /* WLAN_SET_FIELD_16(&prBcnProbRspFrame->u2FrameCtrl, u2FrameCtrl); */ + prBcnProbRspFrame->u2FrameCtrl = u2FrameCtrl; + /* NOTE(Kevin): Optimized for ARM */ + + /* Fill the DA field with BCAST MAC ADDR or TA of ProbeReq. */ + COPY_MAC_ADDR(prBcnProbRspFrame->aucDestAddr, pucDestAddr); + + /* Fill the SA field with our MAC Address. */ + COPY_MAC_ADDR(prBcnProbRspFrame->aucSrcAddr, pucOwnMACAddress); + + /* Fill the BSSID field with current BSSID. */ + COPY_MAC_ADDR(prBcnProbRspFrame->aucBSSID, pucBSSID); + + /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, + * so we need to clear it). + */ + prBcnProbRspFrame->u2SeqCtrl = 0; + + /* 4 <2> Compose the frame body's common fixed field part of the Beacon + * / ProbeResp frame. + */ + /* MAC will update TimeStamp field */ + + /* Fill the Beacon Interval field. */ + /* WLAN_SET_FIELD_16(&prBcnProbRspFrame->u2BeaconInterval, + * u2BeaconInterval); + */ + prBcnProbRspFrame->u2BeaconInterval = u2BeaconInterval; + /* NOTE(Kevin): Optimized for ARM */ + + /* Fill the Capability Information field. */ + /* WLAN_SET_FIELD_16(&prBcnProbRspFrame->u2CapInfo, u2CapInfo); */ + prBcnProbRspFrame->u2CapInfo = u2CapInfo; + /* NOTE(Kevin): Optimized for ARM */ +} /* end of bssComposeBeaconProbeRespFrameHeaderAndFF() */ + +/*---------------------------------------------------------------------------*/ +/*! + * @brief Update the Beacon Frame Template to FW for AIS AdHoc and P2P GO. + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] ucBssIndex Specify which network reply the Probe Response. + * + * @retval WLAN_STATUS_SUCCESS Success. + */ +/*---------------------------------------------------------------------------*/ +uint32_t bssUpdateBeaconContent(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) +{ + struct BSS_INFO *prBssInfo; + struct MSDU_INFO *prMsduInfo; + struct WLAN_BEACON_FRAME *prBcnFrame; + uint32_t i; + + DEBUGFUNC("bssUpdateBeaconContent"); + DBGLOG(INIT, LOUD, "\n"); + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + + /* 4 <1> Allocate a PKT_INFO_T for Beacon Frame */ + /* Allocate a MSDU_INFO_T */ + /* For Beacon */ + prMsduInfo = prBssInfo->prBeacon; + + /* beacon prMsduInfo will be NULLify once BSS deactivated, + * so skip if it is + */ + if (prMsduInfo == NULL) + return WLAN_STATUS_SUCCESS; + + /* 4 <2> Compose header */ + bssComposeBeaconProbeRespFrameHeaderAndFF((uint8_t *) + ((unsigned + long)(prMsduInfo->prPacket) + + MAC_TX_RESERVED_FIELD), + NULL, + prBssInfo->aucOwnMacAddr, + prBssInfo->aucBSSID, + prBssInfo->u2BeaconInterval, + prBssInfo->u2CapInfo); + + prMsduInfo->u2FrameLength = (WLAN_MAC_MGMT_HEADER_LEN + + (TIMESTAMP_FIELD_LEN + + BEACON_INTERVAL_FIELD_LEN + + CAP_INFO_FIELD_LEN)); + + prMsduInfo->ucBssIndex = ucBssIndex; + + /* 4 <3> Compose the frame body's Common IEs of the Beacon frame. */ + bssBuildBeaconProbeRespFrameCommonIEs(prMsduInfo, prBssInfo, NULL); + + /* 4 <4> Compose IEs in MSDU_INFO_T */ + + /* Append IE for Beacon */ + for (i = 0; + i < sizeof(txBcnIETable) / sizeof(struct APPEND_VAR_IE_ENTRY); + i++) { + if (txBcnIETable[i].pfnAppendIE) + txBcnIETable[i].pfnAppendIE(prAdapter, prMsduInfo); + + } + + prBcnFrame = (struct WLAN_BEACON_FRAME *)prMsduInfo->prPacket; + + DBGLOG(P2P, TRACE, "Dump beacon content to FW.\n"); + if (aucDebugModule[DBG_P2P_IDX] & DBG_CLASS_TRACE) { + dumpMemory8((uint8_t *) prMsduInfo->prPacket, + (uint32_t) prMsduInfo->u2FrameLength); + } + + return nicUpdateBeaconIETemplate(prAdapter, + IE_UPD_METHOD_UPDATE_ALL, + ucBssIndex, + prBssInfo->u2CapInfo, + (uint8_t *) prBcnFrame->aucInfoElem, + prMsduInfo->u2FrameLength - + OFFSET_OF(struct WLAN_BEACON_FRAME, + aucInfoElem)); + +} /* end of bssUpdateBeaconContent() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Send the Beacon Frame(for BOW) or Probe Response Frame according to + * the given Destination Address. + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] ucBssIndex Specify which network reply the Probe Response. + * @param[in] pucDestAddr Pointer to the Destination Address to reply + * @param[in] u4ControlFlags Control flags for information on + * Probe Response. + * + * @retval WLAN_STATUS_RESOURCE No available resources to send frame. + * @retval WLAN_STATUS_SUCCESS Success. + */ +/*----------------------------------------------------------------------------*/ +uint32_t +bssSendBeaconProbeResponse(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, IN uint8_t *pucDestAddr, + IN uint32_t u4ControlFlags) +{ + struct BSS_INFO *prBssInfo; + struct MSDU_INFO *prMsduInfo; + uint16_t u2EstimatedFrameLen; + uint16_t u2EstimatedFixedIELen; + uint16_t u2EstimatedExtraIELen; + struct APPEND_VAR_IE_ENTRY *prIeArray = NULL; + uint32_t u4IeArraySize = 0; + uint32_t i; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + + if (!pucDestAddr) { /* For Beacon */ + prIeArray = &txBcnIETable[0]; + u4IeArraySize = + sizeof(txBcnIETable) / sizeof(struct APPEND_VAR_IE_ENTRY); + } else { + prIeArray = &txProbRspIETable[0]; + u4IeArraySize = + sizeof(txProbRspIETable) / + sizeof(struct APPEND_VAR_IE_ENTRY); + } + + /* 4 <1> Allocate a PKT_INFO_T for Beacon /Probe Response Frame */ + /* Allocate a MSDU_INFO_T */ + + /* Init with MGMT Header Length + Length of Fixed Fields + * + Common IE Fields + */ + u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + + WLAN_MAC_MGMT_HEADER_LEN + + TIMESTAMP_FIELD_LEN + + BEACON_INTERVAL_FIELD_LEN + + CAP_INFO_FIELD_LEN + + (ELEM_HDR_LEN + ELEM_MAX_LEN_SSID) + + (ELEM_HDR_LEN + ELEM_MAX_LEN_SUP_RATES) + + (ELEM_HDR_LEN + ELEM_MAX_LEN_DS_PARAMETER_SET) + + (ELEM_HDR_LEN + ELEM_MAX_LEN_IBSS_PARAMETER_SET) + + (ELEM_HDR_LEN + (3 + MAX_LEN_TIM_PARTIAL_BMP)); + + /* + Extra IE Length */ + u2EstimatedExtraIELen = 0; + + for (i = 0; i < u4IeArraySize; i++) { + u2EstimatedFixedIELen = prIeArray[i].u2EstimatedFixedIELen; + + if (u2EstimatedFixedIELen) { + u2EstimatedExtraIELen += u2EstimatedFixedIELen; + } else { + ASSERT(prIeArray[i].pfnCalculateVariableIELen); + + u2EstimatedExtraIELen += (uint16_t) + prIeArray[i].pfnCalculateVariableIELen(prAdapter, + ucBssIndex, + NULL); + } + } + + u2EstimatedFrameLen += u2EstimatedExtraIELen; + prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); + if (prMsduInfo == NULL) { + DBGLOG(BSS, WARN, "No PKT_INFO_T for sending %s.\n", + ((!pucDestAddr) ? "Beacon" : "Probe Response")); + return WLAN_STATUS_RESOURCES; + } + + /* 4 <2> Compose Beacon/Probe Response frame header + * and fixed fields in MSDU_INfO_T. + */ + /* Compose Header and Fixed Field */ +#if CFG_ENABLE_WIFI_DIRECT + if (u4ControlFlags & BSS_PROBE_RESP_USE_P2P_DEV_ADDR) { + if (prAdapter->fgIsP2PRegistered) { + bssComposeBeaconProbeRespFrameHeaderAndFF((uint8_t *) + ((unsigned long) + (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), + pucDestAddr, + prAdapter->rWifiVar.aucDeviceAddress, + prAdapter->rWifiVar.aucDeviceAddress, + DOT11_BEACON_PERIOD_DEFAULT, + (prBssInfo->u2CapInfo & ~(CAP_INFO_ESS + | CAP_INFO_IBSS))); + } + } else +#endif /* CFG_ENABLE_WIFI_DIRECT */ + { + bssComposeBeaconProbeRespFrameHeaderAndFF((uint8_t *) + ((unsigned long) + (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), + pucDestAddr, prBssInfo->aucOwnMacAddr, + prBssInfo->aucBSSID, + prBssInfo->u2BeaconInterval, prBssInfo->u2CapInfo); + } + + /* 4 <3> Update information of MSDU_INFO_T */ + + TX_SET_MMPDU(prAdapter, + prMsduInfo, + ucBssIndex, + STA_REC_INDEX_NOT_FOUND, + WLAN_MAC_MGMT_HEADER_LEN, + (WLAN_MAC_MGMT_HEADER_LEN + TIMESTAMP_FIELD_LEN + + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN), NULL, + MSDU_RATE_MODE_AUTO); + + /* 4 <4> Compose the frame body's Common IEs of + * the Beacon/ProbeResp frame. + */ + bssBuildBeaconProbeRespFrameCommonIEs(prMsduInfo, prBssInfo, + pucDestAddr); + + /* 4 <5> Compose IEs in MSDU_INFO_T */ + + /* Append IE */ + for (i = 0; i < u4IeArraySize; i++) { + if (prIeArray[i].pfnAppendIE) + prIeArray[i].pfnAppendIE(prAdapter, prMsduInfo); + + } + + /* Set limited retry count and lifetime for Probe Resp is reasonable */ + nicTxSetPktLifeTime(prMsduInfo, 100); + nicTxSetPktRetryLimit(prMsduInfo, 2); + + /* TODO(Kevin): + * Also release the unused tail room of the composed MMPDU + */ + + /* 4 <6> Inform TXM to send this Beacon /Probe Response frame. */ + nicTxEnqueueMsdu(prAdapter, prMsduInfo); + + return WLAN_STATUS_SUCCESS; + +} /* end of bssSendBeaconProbeResponse() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will process the Rx Probe Request Frame and then send + * back the corresponding Probe Response Frame if the specified + * conditions were matched. + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] prSwRfb Pointer to SW RFB data structure. + * + * @retval WLAN_STATUS_SUCCESS Always return success + */ +/*----------------------------------------------------------------------------*/ +uint32_t bssProcessProbeRequest(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb) +{ + struct WLAN_MAC_MGMT_HEADER *prMgtHdr; + struct BSS_INFO *prBssInfo; + uint8_t ucBssIndex; + uint8_t aucBCBSSID[] = BC_BSSID; + u_int8_t fgIsBcBssid; + u_int8_t fgReplyProbeResp; + uint32_t u4CtrlFlagsForProbeResp = 0; + enum ENUM_BAND eBand = 0; + uint8_t ucHwChannelNum = 0; + struct RX_DESC_OPS_T *prRxDescOps; + + prRxDescOps = prAdapter->chip_info->prRxDescOps; + /* 4 <1> Parse Probe Req and Get BSSID */ + prMgtHdr = (struct WLAN_MAC_MGMT_HEADER *)prSwRfb->pvHeader; + + if (EQUAL_MAC_ADDR(aucBCBSSID, prMgtHdr->aucBSSID)) + fgIsBcBssid = TRUE; + else + fgIsBcBssid = FALSE; + + /* 4 <2> Check network conditions before reply Probe Response Frame + * (Consider Concurrent) + */ + for (ucBssIndex = 0; ucBssIndex <= prAdapter->ucP2PDevBssIdx; + ucBssIndex++) { + + if (!IS_NET_ACTIVE(prAdapter, ucBssIndex)) + continue; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + + if ((!fgIsBcBssid) + && UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, + prMgtHdr->aucBSSID)) + continue; + + RX_STATUS_GET( + prRxDescOps, + eBand, + get_rf_band, + prSwRfb->prRxStatus); + + RX_STATUS_GET( + prRxDescOps, + ucHwChannelNum, + get_ch_num, + prSwRfb->prRxStatus); + + if (prBssInfo->eBand != eBand) + continue; + + if (prBssInfo->ucPrimaryChannel != ucHwChannelNum) + continue; + + fgReplyProbeResp = FALSE; + + if (prBssInfo->eNetworkType == NETWORK_TYPE_AIS) { + +#if CFG_SUPPORT_ADHOC + fgReplyProbeResp = + aisValidateProbeReq(prAdapter, prSwRfb, + ucBssIndex, + &u4CtrlFlagsForProbeResp); +#endif + } +#if CFG_ENABLE_WIFI_DIRECT + else if ((prAdapter->fgIsP2PRegistered) + && (prBssInfo->eNetworkType == NETWORK_TYPE_P2P)) { + + fgReplyProbeResp = + p2pFuncValidateProbeReq(prAdapter, prSwRfb, + &u4CtrlFlagsForProbeResp, + (prBssInfo->ucBssIndex == + prAdapter->ucP2PDevBssIdx), + (uint8_t) + prBssInfo->u4PrivateData); + } +#endif +#if CFG_ENABLE_BT_OVER_WIFI + else if (prBssInfo->eNetworkType == NETWORK_TYPE_BOW) + fgReplyProbeResp = + bowValidateProbeReq(prAdapter, prSwRfb, + &u4CtrlFlagsForProbeResp); +#endif + + if (fgReplyProbeResp) { + if (nicTxGetFreeCmdCount(prAdapter) > + (CFG_TX_MAX_CMD_PKT_NUM / 2)) { + /* Resource margin is enough */ + bssSendBeaconProbeResponse(prAdapter, + ucBssIndex, + prMgtHdr->aucSrcAddr, + u4CtrlFlagsForProbeResp); + } + } + } + + return WLAN_STATUS_SUCCESS; + +} /* end of bssProcessProbeRequest() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is used to initialize the client list for + * AdHoc or AP Mode + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] prBssInfo Given related BSS_INFO_T. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void bssInitializeClientList(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo) +{ + struct LINK *prStaRecOfClientList; + + prStaRecOfClientList = &prBssInfo->rStaRecOfClientList; + + if (!LINK_IS_EMPTY(prStaRecOfClientList)) + LINK_INITIALIZE(prStaRecOfClientList); + + DBGLOG(BSS, INFO, "Init BSS[%u] Client List\n", prBssInfo->ucBssIndex); + + bssCheckClientList(prAdapter, prBssInfo); +} /* end of bssClearClientList() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is used to Add a STA_RECORD_T to the client list + * for AdHoc or AP Mode + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] prBssInfo Given related BSS_INFO_T. + * @param[in] prStaRec Pointer to the STA_RECORD_T + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void bssAddClient(IN struct ADAPTER *prAdapter, IN struct BSS_INFO *prBssInfo, + IN struct STA_RECORD *prStaRec) +{ + struct LINK *prClientList; + struct STA_RECORD *prCurrStaRec; + + prClientList = &prBssInfo->rStaRecOfClientList; + + LINK_FOR_EACH_ENTRY(prCurrStaRec, prClientList, rLinkEntry, + struct STA_RECORD) { + + if (!prCurrStaRec) + break; + + if (prCurrStaRec == prStaRec) { + DBGLOG(BSS, WARN, + "Current Client List already contains that struct STA_RECORD[" + MACSTR "]\n", MAC2STR(prStaRec->aucMacAddr)); + return; + } + } + + LINK_INSERT_TAIL(prClientList, &prStaRec->rLinkEntry); + + bssCheckClientList(prAdapter, prBssInfo); +} /* end of bssAddStaRecToClientList() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is used to Remove a STA_RECORD_T from the client list + * for AdHoc or AP Mode + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] prStaRec Pointer to the STA_RECORD_T + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +u_int8_t bssRemoveClient(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo, + IN struct STA_RECORD *prStaRec) +{ + struct LINK *prClientList; + struct STA_RECORD *prCurrStaRec; + + prClientList = &prBssInfo->rStaRecOfClientList; + + LINK_FOR_EACH_ENTRY(prCurrStaRec, prClientList, rLinkEntry, + struct STA_RECORD) { + + /* Break to check client list */ + if (!prCurrStaRec) + break; + + if (prCurrStaRec == prStaRec) { + + LINK_REMOVE_KNOWN_ENTRY(prClientList, + &prStaRec->rLinkEntry); + + return TRUE; + } + } + + DBGLOG(BSS, INFO, + "Current Client List didn't contain that struct STA_RECORD[" + MACSTR "] before removing.\n", MAC2STR(prStaRec->aucMacAddr)); + + bssCheckClientList(prAdapter, prBssInfo); + + return FALSE; +} /* end of bssRemoveStaRecFromClientList() */ + +struct STA_RECORD *bssRemoveClientByMac(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo, + IN uint8_t *pucMac) +{ + struct LINK *prClientList; + struct STA_RECORD *prCurrStaRec; + + prClientList = &prBssInfo->rStaRecOfClientList; + + LINK_FOR_EACH_ENTRY(prCurrStaRec, prClientList, rLinkEntry, + struct STA_RECORD) { + + if (!prCurrStaRec) + break; + + if (EQUAL_MAC_ADDR(prCurrStaRec->aucMacAddr, pucMac)) { + + LINK_REMOVE_KNOWN_ENTRY(prClientList, + &prCurrStaRec->rLinkEntry); + + return prCurrStaRec; + } + } + + DBGLOG(BSS, INFO, + "Current Client List didn't contain that struct STA_RECORD[" + MACSTR "] before removing.\n", MAC2STR(pucMac)); + + bssCheckClientList(prAdapter, prBssInfo); + + return NULL; +} + +struct STA_RECORD *bssGetClientByMac(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo, + IN uint8_t *pucMac) +{ + struct LINK *prClientList; + struct STA_RECORD *prCurrStaRec; + + prClientList = &prBssInfo->rStaRecOfClientList; + + LINK_FOR_EACH_ENTRY(prCurrStaRec, prClientList, rLinkEntry, + struct STA_RECORD) { + + if (!prCurrStaRec) + break; + + if (EQUAL_MAC_ADDR(prCurrStaRec->aucMacAddr, pucMac)) + return prCurrStaRec; + } + + DBGLOG(BSS, INFO, + "Current Client List didn't contain that struct STA_RECORD[" + MACSTR "] before removing.\n", MAC2STR(pucMac)); + + bssCheckClientList(prAdapter, prBssInfo); + + return NULL; +} + +struct STA_RECORD *bssRemoveHeadClient(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo) +{ + struct LINK *prStaRecOfClientList; + struct STA_RECORD *prStaRec = NULL; + + prStaRecOfClientList = &prBssInfo->rStaRecOfClientList; + + if (!LINK_IS_EMPTY(prStaRecOfClientList)) + LINK_REMOVE_HEAD(prStaRecOfClientList, prStaRec, + struct STA_RECORD *); + + bssCheckClientList(prAdapter, prBssInfo); + + return prStaRec; +} + +uint32_t bssGetClientCount(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo) +{ + return prBssInfo->rStaRecOfClientList.u4NumElem; +} + +void bssDumpClientList(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo) +{ + struct LINK *prClientList; + struct STA_RECORD *prCurrStaRec; + uint8_t ucCount = 0; + + prClientList = &prBssInfo->rStaRecOfClientList; + + DBGLOG(SW4, INFO, "Dump BSS[%u] Client List NUM[%u]\n", + prBssInfo->ucBssIndex, prClientList->u4NumElem); + + LINK_FOR_EACH_ENTRY(prCurrStaRec, prClientList, rLinkEntry, + struct STA_RECORD) { + + if (!prCurrStaRec) { + DBGLOG(SW4, INFO, "[%2u] is NULL STA_REC\n", ucCount); + break; + } + DBGLOG(SW4, INFO, "[%2u] STA[%u] [" MACSTR "]\n", ucCount, + prCurrStaRec->ucIndex, + MAC2STR(prCurrStaRec->aucMacAddr)); + + ucCount++; + } +} + +void bssCheckClientList(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo) +{ + struct LINK *prClientList; + struct STA_RECORD *prCurrStaRec; + uint8_t ucCount = 0; + u_int8_t fgError = FALSE; + + prClientList = &prBssInfo->rStaRecOfClientList; + + /* Check MAX number */ + if (prClientList->u4NumElem > P2P_MAXIMUM_CLIENT_COUNT) { + DBGLOG(SW4, INFO, "BSS[%u] Client List NUM[%u] ERR\n", + prBssInfo->ucBssIndex, prClientList->u4NumElem); + + fgError = TRUE; + } + + /* Check default list status */ + if (prClientList->u4NumElem == 0) { + if ((void *)prClientList->prNext != (void *)prClientList) + fgError = TRUE; + if ((void *)prClientList->prPrev != (void *)prClientList) + fgError = TRUE; + + if (fgError) { + DBGLOG(SW4, INFO, + "BSS[%u] Client List PTR next/prev[%p/%p] ERR\n", + prBssInfo->ucBssIndex, prClientList->prNext, + prClientList->prPrev); + } + } + + /* Traverse list */ + LINK_FOR_EACH_ENTRY(prCurrStaRec, prClientList, rLinkEntry, + struct STA_RECORD) { + if (!prCurrStaRec) { + fgError = TRUE; + DBGLOG(SW4, INFO, "BSS[%u] Client List NULL PTR ERR\n", + prBssInfo->ucBssIndex); + + break; + } + + ucCount++; + } + + /* Check real count and list number */ + if (ucCount != prClientList->u4NumElem) { + DBGLOG(SW4, INFO, + "BSS[%u] Client List NUM[%u] REAL CNT[%u] ERR\n", + prBssInfo->ucBssIndex, prClientList->u4NumElem, ucCount); + + fgError = TRUE; + } + + if (fgError) + bssDumpClientList(prAdapter, prBssInfo); + +} + +#endif /* CFG_SUPPORT_ADHOC || CFG_SUPPORT_AAA */ + +#if CFG_SUPPORT_ADHOC +/*----------------------------------------------------------------------------*/ +/* Routines for IBSS(AdHoc) only */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is used to process Beacons from current Ad-Hoc network + * peers. We also process Beacons from other Ad-Hoc network during SCAN. + * If it has the same SSID and we'll decide to merge into it + * if it has a larger TSF. + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] prBssInfo Pointer to the BSS_INFO_T. + * @param[in] prBSSDesc Pointer to the BSS Descriptor. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void +ibssProcessMatchedBeacon(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo, + IN struct BSS_DESC *prBssDesc, IN uint8_t ucRCPI) +{ + struct STA_RECORD *prStaRec = NULL; + + u_int8_t fgIsCheckCapability = FALSE; + u_int8_t fgIsCheckTSF = FALSE; + u_int8_t fgIsGoingMerging = FALSE; + u_int8_t fgIsSameBSSID; + + /* 4 <1> Process IBSS Beacon only after we create or merge + * with other IBSS. + */ + if (!prBssInfo->fgIsBeaconActivated) + return; + + /* 4 <2> Get the STA_RECORD_T of TA. */ + prStaRec = + cnmGetStaRecByAddress(prAdapter, + prBssInfo->ucBssIndex, + prBssDesc->aucSrcAddr); + + fgIsSameBSSID = + UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, + prBssDesc->aucBSSID) ? FALSE : TRUE; + + /* 4 <3> IBSS Merge Decision Flow for Processing Beacon. */ + if (fgIsSameBSSID) { + + /* Same BSSID: + * Case I. + * This is a new TA and it has decide to merged with us. + * a) If fgIsMerging == FALSE + * - we will send msg to notify AIS. + * b) If fgIsMerging == TRUE + * - already notify AIS. + * Case II. + * This is an old TA and we've already merged together. + */ + if (!prStaRec) { + /* For Case I - + * Check this IBSS's capability first before + * adding this Sta Record. + */ + fgIsCheckCapability = TRUE; + + /* If check is passed, then we perform merging + * with this new IBSS + */ + fgIsGoingMerging = TRUE; + + } else { + if (prStaRec->ucStaState != STA_STATE_3) { + + if (!prStaRec->fgIsMerging) { + + /* For Case I - + * Check this IBSS's capability first + * before adding this Sta Record. + */ + fgIsCheckCapability = TRUE; + + /* If check is passed, then we perform + * merging with this new IBSS + */ + fgIsGoingMerging = TRUE; + } else { + /* For Case II - Update rExpirationTime + * of Sta Record + */ + GET_CURRENT_SYSTIME + (&prStaRec->rUpdateTime); + } + } else { + /* For Case II + * - Update rExpirationTime of Sta Record + */ + GET_CURRENT_SYSTIME(&prStaRec->rUpdateTime); + } + + } + } else { + + /* Unequal BSSID: + * Case III. This is a new TA and we need to compare + * the TSF and get the winner. + * Case IV. This is an old TA and it merge into + * a new IBSS before we do the same thing. + * We need to compare the TSF to get the winner. + * Case V. This is an old TA and it restart a new IBSS. + * We also need to compare the TSF to + * get the winner. + */ + + /* For Case III, IV & V - We'll always check this new IBSS's + * capability first before merging into new IBSS. + */ + fgIsCheckCapability = TRUE; + + /* If check is passed, we need to perform TSF check to + * decide the major BSSID + */ + fgIsCheckTSF = TRUE; + + /* For Case IV & V - We won't update rExpirationTime + * of Sta Record + */ + } + + /* 4 <7> Check this BSS_DESC_T's capability. */ + if (fgIsCheckCapability) { + u_int8_t fgIsCapabilityMatched = FALSE; + + do { + if (! + (prBssDesc->ucPhyTypeSet & + (prAdapter->rWifiVar.ucAvailablePhyTypeSet))) { + DBGLOG(BSS, LOUD, + "IBSS MERGE: Ignore Peer MAC: " MACSTR + " - Unsupported Phy.\n", + MAC2STR(prBssDesc->aucSrcAddr)); + + break; + } + + if (prBssDesc->fgIsUnknownBssBasicRate) { + DBGLOG(BSS, LOUD, + "IBSS MERGE: Ignore Peer MAC: " MACSTR + " - Unknown Basic Rate.\n", + MAC2STR(prBssDesc->aucSrcAddr)); + + break; + } + + if (ibssCheckCapabilityForAdHocMode + (prAdapter, prBssDesc, + prBssInfo->ucBssIndex) + == WLAN_STATUS_FAILURE) { + DBGLOG(BSS, LOUD, + "IBSS MERGE: Ignore Peer MAC: " MACSTR + " - Capability is not matched.\n", + MAC2STR(prBssDesc->aucSrcAddr)); + + break; + } + + fgIsCapabilityMatched = TRUE; + } while (FALSE); + + if (!fgIsCapabilityMatched) { + + if (prStaRec) { + /* Case II - + * We merge this STA_RECORD in RX Path. + * Case IV & V - + * They change their BSSID after + * we merge with them. + */ + + DBGLOG(BSS, LOUD, + "IBSS MERGE: Ignore Peer MAC: " MACSTR + " - Capability is not matched.\n", + MAC2STR(prBssDesc->aucSrcAddr)); + } + + return; + } + + DBGLOG(BSS, LOUD, + "IBSS MERGE: Peer MAC: " MACSTR + " - Check capability was passed.\n", + MAC2STR(prBssDesc->aucSrcAddr)); + } + + if (fgIsCheckTSF) { +#if CFG_SLT_SUPPORT + fgIsGoingMerging = TRUE; +#else + if (prBssDesc->fgIsLargerTSF) + fgIsGoingMerging = TRUE; + else + return; + +#endif + } + + if (fgIsGoingMerging) { + struct MSG_AIS_IBSS_PEER_FOUND *prAisIbssPeerFoundMsg; + + /* 4 <1> We will merge with to this BSS immediately. */ + prBssDesc->fgIsConnecting |= BIT(prBssInfo->ucBssIndex); + prBssDesc->fgIsConnected &= ~BIT(prBssInfo->ucBssIndex); + + /* 4 <2> Setup corresponding STA_RECORD_T */ + prStaRec = bssCreateStaRecFromBssDesc(prAdapter, + STA_TYPE_ADHOC_PEER, + prBssInfo->ucBssIndex, + prBssDesc); + + if (!prStaRec) { + /* no memory ? */ + return; + } + + prStaRec->fgIsMerging = TRUE; + + /* update RCPI */ + prStaRec->ucRCPI = ucRCPI; + + /* 4 <3> Send Merge Msg to CNM to obtain + * the channel privilege. + */ + prAisIbssPeerFoundMsg = (struct MSG_AIS_IBSS_PEER_FOUND *) + cnmMemAlloc(prAdapter, RAM_TYPE_MSG, + sizeof(struct MSG_AIS_IBSS_PEER_FOUND)); + + if (!prAisIbssPeerFoundMsg) { + DBGLOG(AIS, ERROR, "Can't send Merge Msg\n"); + return; + } + + prAisIbssPeerFoundMsg->rMsgHdr.eMsgId = MID_SCN_AIS_FOUND_IBSS; + prAisIbssPeerFoundMsg->ucBssIndex = + prBssInfo->ucBssIndex; + prAisIbssPeerFoundMsg->prStaRec = prStaRec; + + /* Inform AIS to do STATE TRANSITION + * For Case I - If AIS in IBSS_ALONE, let it jump to + * NORMAL_TR after we know the new member. + * For Case III, IV - Now this new BSSID wins the TSF, + * follow it. + */ + if (fgIsSameBSSID) { + prAisIbssPeerFoundMsg->fgIsMergeIn = TRUE; + } else { +#if CFG_SLT_SUPPORT + prAisIbssPeerFoundMsg->fgIsMergeIn = TRUE; +#else + prAisIbssPeerFoundMsg->fgIsMergeIn = + (prBssDesc->fgIsLargerTSF) ? FALSE : TRUE; +#endif + } + + mboxSendMsg(prAdapter, MBOX_ID_0, + (struct MSG_HDR *)prAisIbssPeerFoundMsg, + MSG_SEND_METHOD_BUF); + + } +} /* end of ibssProcessMatchedBeacon() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will check the Capability for Ad-Hoc to decide + * if we are able to merge with(same capability). + * + * @param[in] prBSSDesc Pointer to the BSS Descriptor. + * + * @retval WLAN_STATUS_FAILURE Can't pass the check of Capability. + * @retval WLAN_STATUS_SUCCESS Pass the check of Capability. + */ +/*----------------------------------------------------------------------------*/ +uint32_t ibssCheckCapabilityForAdHocMode(IN struct ADAPTER *prAdapter, + IN struct BSS_DESC *prBssDesc, + IN uint8_t ucBssIndex) +{ + struct CONNECTION_SETTINGS *prConnSettings; + uint32_t rStatus = WLAN_STATUS_FAILURE; + + prConnSettings = aisGetConnSettings(prAdapter, ucBssIndex); + + do { + /* 4 <1> Check the BSS Basic Rate Set for current AdHoc Mode */ + if ((prConnSettings->eAdHocMode == AD_HOC_MODE_11B) && + (prBssDesc->u2BSSBasicRateSet & ~RATE_SET_HR_DSSS)) { + break; + } else if ((prConnSettings->eAdHocMode == AD_HOC_MODE_11A) && + (prBssDesc->u2BSSBasicRateSet & ~RATE_SET_OFDM)) { + break; + } + /* 4 <2> Check the Short Slot Time. */ +#if 0 +/* Do not check ShortSlotTime until Wi-Fi define such policy */ + if (prConnSettings->eAdHocMode == AD_HOC_MODE_11G) { + if (((prConnSettings->fgIsShortSlotTimeOptionEnable) && + !(prBssDesc->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME)) + || (!(prConnSettings->fgIsShortSlotTimeOptionEnable) + && (prBssDesc->u2CapInfo & + CAP_INFO_SHORT_SLOT_TIME))) { + break; + } + } +#endif + + /* 4 <3> Check the ATIM window setting. */ + if (prBssDesc->u2ATIMWindow) { + DBGLOG(BSS, INFO, + "AdHoc PS was not supported(ATIM Window: %d)\n", + prBssDesc->u2ATIMWindow); + break; + } + /* 4 <4> Check the Security setting. */ + if (!rsnPerformPolicySelection(prAdapter, prBssDesc, + ucBssIndex)) + break; + + rStatus = WLAN_STATUS_SUCCESS; + } while (FALSE); + + return rStatus; + +} /* end of ibssCheckCapabilityForAdHocMode() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will initial the BSS_INFO_T for IBSS Mode. + * + * @param[in] prBssInfo Pointer to the BSS_INFO_T. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void ibssInitForAdHoc(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo) +{ + uint8_t aucBSSID[MAC_ADDR_LEN]; + uint16_t *pu2BSSID = (uint16_t *) &aucBSSID[0]; + uint32_t i; + + /* 4 <1> Setup PHY Attributes and Basic Rate Set/Operational Rate Set */ + prBssInfo->ucNonHTBasicPhyType = (uint8_t) + rNonHTAdHocModeAttributes[prBssInfo-> + ucConfigAdHocAPMode].ePhyTypeIndex; + prBssInfo->u2BSSBasicRateSet = + rNonHTAdHocModeAttributes[prBssInfo-> + ucConfigAdHocAPMode].u2BSSBasicRateSet; + + prBssInfo->u2OperationalRateSet = + rNonHTPhyAttributes[prBssInfo-> + ucNonHTBasicPhyType].u2SupportedRateSet; + + rateGetDataRatesFromRateSet(prBssInfo->u2OperationalRateSet, + prBssInfo->u2BSSBasicRateSet, + prBssInfo->aucAllSupportedRates, + &prBssInfo->ucAllSupportedRatesLen); + + /* 4 <2> Setup BSSID */ + if (!prBssInfo->fgHoldSameBssidForIBSS) { + + for (i = 0; i < sizeof(aucBSSID) / sizeof(uint16_t); i++) + pu2BSSID[i] = (uint16_t) (kalRandomNumber() & 0xFFFF); + + /* 7.1.3.3.3 - + * The individual/group bit of the address is set to 0. + */ + aucBSSID[0] &= ~0x01; + /* 7.1.3.3.3 - + * The universal/local bit of the address is set to 1. + */ + aucBSSID[0] |= 0x02; + + COPY_MAC_ADDR(prBssInfo->aucBSSID, aucBSSID); + } + + /* 4 <3> Setup Capability - Short Preamble */ + if (rNonHTPhyAttributes + [prBssInfo->ucNonHTBasicPhyType].fgIsShortPreambleOptionImplemented + && + /* Short Preamble Option Enable is TRUE */ + ((prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_SHORT) || + (prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_AUTO))) { + + prBssInfo->fgIsShortPreambleAllowed = TRUE; + prBssInfo->fgUseShortPreamble = TRUE; + } else { + prBssInfo->fgIsShortPreambleAllowed = FALSE; + prBssInfo->fgUseShortPreamble = FALSE; + } + + /* 4 <4> Setup Capability - Short Slot Time */ + /* 7.3.1.4 For IBSS, the Short Slot Time subfield shall be set to 0. */ + prBssInfo->fgUseShortSlotTime = FALSE; /* Set to FALSE for AdHoc */ + + /* 4 <5> Compoase Capability */ + prBssInfo->u2CapInfo = CAP_INFO_IBSS; + + if (prBssInfo->fgIsProtection) + prBssInfo->u2CapInfo |= CAP_INFO_PRIVACY; + + if (prBssInfo->fgIsShortPreambleAllowed) + prBssInfo->u2CapInfo |= CAP_INFO_SHORT_PREAMBLE; + + if (prBssInfo->fgUseShortSlotTime) + prBssInfo->u2CapInfo |= CAP_INFO_SHORT_SLOT_TIME; + + /* 4 <6> Find Lowest Basic Rate Index for default TX Rate of MMPDU */ + nicTxUpdateBssDefaultRate(prBssInfo); +} /* end of ibssInitForAdHoc() */ + +#endif /* CFG_SUPPORT_ADHOC */ + +#if CFG_SUPPORT_AAA + +/*----------------------------------------------------------------------------*/ +/* Routines for BSS(AP) only */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will initial the BSS_INFO_T for AP Mode. + * + * @param[in] prBssInfo Given related BSS_INFO_T. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void bssInitForAP(IN struct ADAPTER *prAdapter, IN struct BSS_INFO *prBssInfo, + IN u_int8_t fgIsRateUpdate) +{ + struct AC_QUE_PARMS *prACQueParms; + + enum ENUM_WMM_ACI eAci; + + uint8_t auCWminLog2ForBcast[WMM_AC_INDEX_NUM] = { 4, 4, 3, 2 }; + uint8_t auCWmaxLog2ForBcast[WMM_AC_INDEX_NUM] = { 10, 10, 4, 3 }; + uint8_t auAifsForBcast[WMM_AC_INDEX_NUM] = { 3, 7, 2, 2 }; + /* If the AP is OFDM */ + uint8_t auTxopForBcast[WMM_AC_INDEX_NUM] = { 0, 0, 94, 47 }; + + uint8_t auCWminLog2[WMM_AC_INDEX_NUM] = { 4, 4, 3, 2 }; + uint8_t auCWmaxLog2[WMM_AC_INDEX_NUM] = { 6, 10, 4, 3 }; + uint8_t auAifs[WMM_AC_INDEX_NUM] = { 3, 7, 1, 1 }; + /* If the AP is OFDM */ + uint8_t auTxop[WMM_AC_INDEX_NUM] = { 0, 0, 94, 47 }; + + DEBUGFUNC("bssInitForAP"); + +#if 0 + prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled = TRUE; + prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode = CONFIG_BW_20M; + prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode = CONFIG_BW_20M; +#endif + + /* 4 <1> Setup PHY Attributes and Basic Rate Set/Operational Rate Set */ + prBssInfo->ucNonHTBasicPhyType = (uint8_t) + rNonHTApModeAttributes[prBssInfo-> + ucConfigAdHocAPMode].ePhyTypeIndex; + prBssInfo->u2BSSBasicRateSet = + rNonHTApModeAttributes[prBssInfo-> + ucConfigAdHocAPMode].u2BSSBasicRateSet; + + prBssInfo->u2OperationalRateSet = + rNonHTPhyAttributes[prBssInfo-> + ucNonHTBasicPhyType].u2SupportedRateSet; + + if (fgIsRateUpdate) { + rateGetDataRatesFromRateSet(prBssInfo->u2OperationalRateSet, + prBssInfo->u2BSSBasicRateSet, + prBssInfo->aucAllSupportedRates, + &prBssInfo->ucAllSupportedRatesLen); + } + /* 4 <2> Setup BSSID */ + COPY_MAC_ADDR(prBssInfo->aucBSSID, prBssInfo->aucOwnMacAddr); + + /* 4 <3> Setup Capability - Short Preamble */ + if (rNonHTPhyAttributes + [prBssInfo->ucNonHTBasicPhyType].fgIsShortPreambleOptionImplemented + && + /* Short Preamble Option Enable is TRUE */ + ((prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_SHORT) || + (prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_AUTO))) { + + prBssInfo->fgIsShortPreambleAllowed = TRUE; + prBssInfo->fgUseShortPreamble = TRUE; + } else { + prBssInfo->fgIsShortPreambleAllowed = FALSE; + prBssInfo->fgUseShortPreamble = FALSE; + } + + /* 4 <4> Setup Capability - Short Slot Time */ + prBssInfo->fgUseShortSlotTime = TRUE; +#ifdef CFG_SET_BCN_CAPINFO_BY_DRIVER + /* 4 <5> Compoase Capability */ + prBssInfo->u2CapInfo = CAP_INFO_ESS; + + if (prBssInfo->fgIsProtection) + prBssInfo->u2CapInfo |= CAP_INFO_PRIVACY; + + if (prBssInfo->fgIsShortPreambleAllowed) + prBssInfo->u2CapInfo |= CAP_INFO_SHORT_PREAMBLE; + + if (prBssInfo->fgUseShortSlotTime) + prBssInfo->u2CapInfo |= CAP_INFO_SHORT_SLOT_TIME; +#endif + /* 4 <6> Find Lowest Basic Rate Index for default TX Rate of MMPDU */ + nicTxUpdateBssDefaultRate(prBssInfo); + + /* 4 <7> Fill the EDCA */ + + prACQueParms = prBssInfo->arACQueParmsForBcast; + + for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { + + prACQueParms[eAci].ucIsACMSet = FALSE; + prACQueParms[eAci].u2Aifsn = auAifsForBcast[eAci]; + prACQueParms[eAci].u2CWmin = BIT(auCWminLog2ForBcast[eAci]) - 1; + prACQueParms[eAci].u2CWmax = BIT(auCWmaxLog2ForBcast[eAci]) - 1; + prACQueParms[eAci].u2TxopLimit = auTxopForBcast[eAci]; + + /* used to send WMM IE */ + prBssInfo->aucCWminLog2ForBcast[eAci] = + auCWminLog2ForBcast[eAci]; + prBssInfo->aucCWmaxLog2ForBcast[eAci] = + auCWmaxLog2ForBcast[eAci]; + } + + DBGLOG(BSS, INFO, + "Bcast: ACM[%d,%d,%d,%d] Aifsn[%d,%d,%d,%d] CWmin/max[%d/%d,%d/%d,%d/%d,%d/%d] TxopLimit[%d,%d,%d,%d]\n", + prACQueParms[0].ucIsACMSet, prACQueParms[1].ucIsACMSet, + prACQueParms[2].ucIsACMSet, prACQueParms[3].ucIsACMSet, + prACQueParms[0].u2Aifsn, prACQueParms[1].u2Aifsn, + prACQueParms[2].u2Aifsn, prACQueParms[3].u2Aifsn, + prACQueParms[0].u2CWmin, prACQueParms[0].u2CWmax, + prACQueParms[1].u2CWmin, prACQueParms[1].u2CWmax, + prACQueParms[2].u2CWmin, prACQueParms[2].u2CWmax, + prACQueParms[3].u2CWmin, prACQueParms[3].u2CWmax, + prACQueParms[0].u2TxopLimit, prACQueParms[1].u2TxopLimit, + prACQueParms[2].u2TxopLimit, prACQueParms[3].u2TxopLimit); + + prACQueParms = prBssInfo->arACQueParms; + + for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { + + prACQueParms[eAci].ucIsACMSet = FALSE; + prACQueParms[eAci].u2Aifsn = auAifs[eAci]; + prACQueParms[eAci].u2CWmin = BIT(auCWminLog2[eAci]) - 1; + prACQueParms[eAci].u2CWmax = BIT(auCWmaxLog2[eAci]) - 1; + prACQueParms[eAci].u2TxopLimit = auTxop[eAci]; + } + + DBGLOG(BSS, INFO, + "ACM[%d,%d,%d,%d] Aifsn[%d,%d,%d,%d] CWmin/max[%d/%d,%d/%d,%d/%d,%d/%d] TxopLimit[%d,%d,%d,%d]\n", + prACQueParms[0].ucIsACMSet, prACQueParms[1].ucIsACMSet, + prACQueParms[2].ucIsACMSet, prACQueParms[3].ucIsACMSet, + prACQueParms[0].u2Aifsn, prACQueParms[1].u2Aifsn, + prACQueParms[2].u2Aifsn, prACQueParms[3].u2Aifsn, + prACQueParms[0].u2CWmin, prACQueParms[0].u2CWmax, + prACQueParms[1].u2CWmin, prACQueParms[1].u2CWmax, + prACQueParms[2].u2CWmin, prACQueParms[2].u2CWmax, + prACQueParms[3].u2CWmin, prACQueParms[3].u2CWmax, + prACQueParms[0].u2TxopLimit, prACQueParms[1].u2TxopLimit, + prACQueParms[2].u2TxopLimit, prACQueParms[3].u2TxopLimit); + + /* Note: Caller should update the EDCA setting to HW by + * nicQmUpdateWmmParms() it there is no AIS network + * Note: In E2, only 4 HW queues. + * The the Edca parameters should be folow by AIS network + * Note: In E3, 8 HW queues. + * the Wmm parameters should be updated to right queues + * according to BSS + */ +} /* end of bssInitForAP() */ + +#endif /* CFG_SUPPORT_AAA */ + +void bssCreateStaRecFromAuth(IN struct ADAPTER *prAdapter) +{ + +} + +void bssUpdateStaRecFromAssocReq(IN struct ADAPTER *prAdapter) +{ + +} + +void bssDumpBssInfo(IN struct ADAPTER *prAdapter, IN uint8_t ucBssIndex) +{ + struct BSS_INFO *prBssInfo; + /* P_LINK_T prStaRecOfClientList = (P_LINK_T) NULL; */ + /* P_STA_RECORD_T prCurrStaRec = (P_STA_RECORD_T) NULL; */ + + if (ucBssIndex > prAdapter->ucHwBssIdNum) { + DBGLOG(SW4, INFO, "Invalid BssInfo index[%u], skip dump!\n", + ucBssIndex); + return; + } + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + + if (!prBssInfo) { + DBGLOG(SW4, INFO, "Invalid BssInfo index[%u], skip dump!\n", + ucBssIndex); + return; + } + + DBGLOG(SW4, INFO, "OWNMAC[" MACSTR "] BSSID[" MACSTR "] SSID[%s]\n", + MAC2STR(prBssInfo->aucOwnMacAddr), MAC2STR(prBssInfo->aucBSSID), + HIDE(prBssInfo->aucSSID)); + + if (prBssInfo->eNetworkType >= 0 + && prBssInfo->eNetworkType < NETWORK_TYPE_NUM + && prBssInfo->eCurrentOPMode >= 0 + && prBssInfo->eCurrentOPMode < OP_MODE_NUM) { + DBGLOG(SW4, INFO, + "BSS IDX[%u] Type[%s] OPMode[%s] ConnState[%u] Absent[%u]\n", + prBssInfo->ucBssIndex, + apucNetworkType[prBssInfo->eNetworkType], + apucNetworkOpMode[prBssInfo->eCurrentOPMode], + prBssInfo->eConnectionState, prBssInfo->fgIsNetAbsent); + } + + DBGLOG(SW4, INFO, + "Channel[%u] Band[%u] SCO[%u] Assoc40mBwAllowed[%u] 40mBwAllowed[%u]\n", + prBssInfo->ucPrimaryChannel, prBssInfo->eBand, + prBssInfo->eBssSCO, prBssInfo->fgAssoc40mBwAllowed, + prBssInfo->fg40mBwAllowed); + + DBGLOG(SW4, INFO, "MaxBw[%u] OpRxNss[%u] OpTxNss[%u]\n", + cnmGetBssMaxBw(prAdapter, prBssInfo->ucBssIndex), + prBssInfo->ucOpRxNss, prBssInfo->ucOpTxNss); + + DBGLOG(SW4, INFO, "QBSS[%u] CapInfo[0x%04x] AID[%u]\n", + prBssInfo->fgIsQBSS, prBssInfo->u2CapInfo, prBssInfo->u2AssocId); + + DBGLOG(SW4, INFO, + "ShortPreamble Allowed[%u] EN[%u], ShortSlotTime[%u]\n", + prBssInfo->fgIsShortPreambleAllowed, + prBssInfo->fgUseShortPreamble, prBssInfo->fgUseShortSlotTime); + + DBGLOG(SW4, INFO, "PhyTypeSet: Basic[0x%02x] NonHtBasic[0x%02x]\n", + prBssInfo->ucPhyTypeSet, prBssInfo->ucNonHTBasicPhyType); + + DBGLOG(SW4, INFO, "RateSet: BssBasic[0x%04x] Operational[0x%04x]\n", + prBssInfo->u2BSSBasicRateSet, prBssInfo->u2OperationalRateSet); + + DBGLOG(SW4, INFO, "ATIMWindow[%u] DTIM Period[%u] Count[%u]\n", + prBssInfo->u2ATIMWindow, prBssInfo->ucDTIMPeriod, + prBssInfo->ucDTIMCount); + + DBGLOG(SW4, INFO, + "HT Operation Info1[0x%02x] Info2[0x%04x] Info3[0x%04x]\n", + prBssInfo->ucHtOpInfo1, prBssInfo->u2HtOpInfo2, + prBssInfo->u2HtOpInfo3); + + DBGLOG(SW4, INFO, + "ProtectMode HT[%u] ERP[%u], OperationMode GF[%u] RIFS[%u]\n", + prBssInfo->eHtProtectMode, prBssInfo->fgErpProtectMode, + prBssInfo->eGfOperationMode, prBssInfo->eRifsOperationMode); + + DBGLOG(SW4, INFO, + "(OBSS) ProtectMode HT[%u] ERP[%u], OperationMode GF[%u] RIFS[%u]\n", + prBssInfo->eObssHtProtectMode, prBssInfo->fgObssErpProtectMode, + prBssInfo->eObssGfOperationMode, + prBssInfo->fgObssRifsOperationMode); + + DBGLOG(SW4, INFO, + "VhtChannelWidth[%u] OpChangeChannelWidth[%u], IsOpChangeChannelWidth[%u]\n", + prBssInfo->ucVhtChannelWidth, prBssInfo->ucOpChangeChannelWidth, + prBssInfo->fgIsOpChangeChannelWidth); + + DBGLOG(SW4, INFO, "======== Dump Connected Client ========\n"); + +#if 0 + DBGLOG(SW4, INFO, "NumOfClient[%u]\n", + bssGetClientCount(prAdapter, prBssInfo)); + + prStaRecOfClientList = &prBssInfo->rStaRecOfClientList; + + LINK_FOR_EACH_ENTRY(prCurrStaRec, prStaRecOfClientList, rLinkEntry, + struct STA_RECORD) { + DBGLOG(SW4, INFO, "STA[%u] [" MACSTR "]\n", + prCurrStaRec->ucIndex, + MAC2STR(prCurrStaRec->aucMacAddr)); + } +#else + bssDumpClientList(prAdapter, prBssInfo); +#endif + + DBGLOG(SW4, INFO, "============== Dump Done ==============\n"); +} + +int8_t bssGetRxNss(IN struct ADAPTER *prAdapter, + IN struct BSS_DESC *prBssDesc) +{ + uint8_t ucIeByte = 0; + int8_t ucBssNss = 0; + uint8_t *pucRxMcsBitMaskIe; + const uint8_t *pucIe; + + if (!prAdapter || !prBssDesc) { + DBGLOG(BSS, INFO, "GetRxNss Param Error!\n"); + return -EINVAL; + } + + pucIe = kalFindIeMatchMask( + ELEM_ID_HT_CAP, + &prBssDesc->aucIEBuf[0], + prBssDesc->u2IELength, + NULL, 0, 0, NULL); + + if (!pucIe) + return 1; + + pucRxMcsBitMaskIe = + &((struct IE_HT_CAP *)pucIe)-> + rSupMcsSet.aucRxMcsBitmask[0]; + do { + ucIeByte = pucRxMcsBitMaskIe[ucBssNss]; + if (ucIeByte) + ucBssNss++; + if (ucBssNss == 8) + return ucBssNss; + } while (ucIeByte != 0); + + return ucBssNss; +} + + +#if (CFG_SUPPORT_HE_ER == 1) +void bssProcessErTxModeEvent(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ + struct BSS_INFO *prBssInfo; + struct EVENT_ER_TX_MODE *prErTxMode; + + prErTxMode = (struct EVENT_ER_TX_MODE *) (prEvent->aucBuffer); + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prErTxMode->ucBssInfoIdx); + + prBssInfo->ucErMode = prErTxMode->ucErMode; + + DBGLOG_LIMITED(BSS, WARN, + "Receive ER Tx mode event,BSS[%d],Mode[0x%x]\n", + prErTxMode->ucBssInfoIdx, prErTxMode->ucErMode); +} +#endif + +#if CFG_SUPPORT_IOT_AP_BLACKLIST +/*----------------------------------------------------------------------------*/ +/*! + * @brief get IOT AP handle action. + * + * @param[in] prBssDesc + * + * @return ENUM_WLAN_IOT_AP_HANDLE_ACTION + */ +/*----------------------------------------------------------------------------*/ +uint32_t bssGetIotApAction(IN struct ADAPTER *prAdapter, + IN struct BSS_DESC *prBssDesc) +{ + uint8_t ucCnt = 0; + int8_t ucBssNss; + uint8_t *pucMask; + uint16_t u2MatchFlag; + const uint8_t *pucIes; + const uint8_t *pucIe; + struct WLAN_IOT_AP_RULE_T *prIotApRule; + + if (!prAdapter || !prBssDesc) { + DBGLOG(BSS, INFO, "GetIotApAction Param Error!\n"); + return -EINVAL; + } + /*To make sure one Bss only parse once*/ + if (prBssDesc->fgIotApActionValid) + return prBssDesc->ucIotApAct; + + + prBssDesc->fgIotApActionValid = TRUE; + prBssDesc->ucIotApAct = WLAN_IOT_AP_VOID; + + pucIes = &prBssDesc->aucIEBuf[0]; + for (ucCnt = 0; ucCnt < CFG_IOT_AP_RULE_MAX_CNT; ucCnt++) { + prIotApRule = &prAdapter->rIotApRule[ucCnt]; + u2MatchFlag = prIotApRule->u2MatchFlag; + + /*No need to match empty rule*/ + if (prIotApRule->u2MatchFlag == 0) + continue; + + /*Check if default rule is allowed*/ + if (!prAdapter->rWifiVar.fgEnDefaultIotApRule && + (prIotApRule->ucVersion & BIT(7))) + continue; + + /*Match Vendor OUI*/ + if (u2MatchFlag & BIT(WLAN_IOT_AP_FG_OUI)) { + pucIe = kalFindIeMatchMask( + WLAN_EID_VENDOR_SPECIFIC, + pucIes, prBssDesc->u2IELength, + prIotApRule->aVendorOui, + MAC_OUI_LEN, 2, NULL); + if (!pucIe) + continue; + /*Match!, Fall through*/ + } + + /*Match Vendor Data rule*/ + if (u2MatchFlag & BIT(WLAN_IOT_AP_FG_DATA)) { + pucMask = + u2MatchFlag & BIT(WLAN_IOT_AP_FG_DATA_MASK) ? + &prIotApRule->aVendorDataMask[0] : NULL; + pucIe = kalFindIeMatchMask( + WLAN_EID_VENDOR_SPECIFIC, + pucIes, prBssDesc->u2IELength, + prIotApRule->aVendorData, + prIotApRule->ucDataLen, 5, pucMask); + if (!pucIe) + continue; + /*Match!, Fall through*/ + } + + /*Match BSSID rule*/ + if (u2MatchFlag & BIT(WLAN_IOT_AP_FG_BSSID)) { + pucMask = + u2MatchFlag & BIT(WLAN_IOT_AP_FG_BSSID_MASK) ? + &prIotApRule->aBssidMask[0] : NULL; + if (kalMaskMemCmp(&prBssDesc->aucBSSID, + &prIotApRule->aBssid, + pucMask, + MAC_ADDR_LEN)) + continue; + /*Match!, Fall through*/ + } + + /*Match Rx NSS rule*/ + if (u2MatchFlag & BIT(WLAN_IOT_AP_FG_NSS)) { + ucBssNss = bssGetRxNss(prAdapter, prBssDesc); + if (ucBssNss < 0) + DBGLOG(BSS, TRACE, + "IOTAP Nss=%d invalid", ucBssNss); + if (ucBssNss != prIotApRule->ucNss) + continue; + /*Match!, Fall through*/ + } + + /*Match HT type rule*/ + if (u2MatchFlag & BIT(WLAN_IOT_AP_FG_HT)) { + if (prBssDesc->fgIsVHTPresent) { + if (prIotApRule->ucHtType != 2) + continue; + } else if (prBssDesc->fgIsHTPresent) { + if (prIotApRule->ucHtType != 1) + continue; + } else { + if (prIotApRule->ucHtType != 0) + continue; + } + /*Matched, Fall through*/ + } + + /*Match Band Rule*/ + if (u2MatchFlag & BIT(WLAN_IOT_AP_FG_BAND)) { + if (prBssDesc->eBand != prIotApRule->ucBand) + continue; + /*Matched, Fall through*/ + } + /*All match, set the actions*/ + prBssDesc->ucIotApAct = prIotApRule->ucAction; + } + return prBssDesc->ucIotApAct; +} +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/cnm.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/cnm.c new file mode 100644 index 0000000000000000000000000000000000000000..0bb8128afb8717b01cb2177a440fa59abee776bc --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/cnm.c @@ -0,0 +1,4355 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/cnm.c#2 + */ + +/*! \file "cnm.c" + * \brief Module of Concurrent Network Management + * + * Module of Concurrent Network Management + */ + + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" +#include "wsys_cmd_handler_fw.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#if CFG_SUPPORT_DBDC +#define DBDC_ENABLE_GUARD_TIME (4*1000) /* ms */ +#define DBDC_DISABLE_GUARD_TIME (1*1000) /* ms */ +#define DBDC_DISABLE_COUNTDOWN_TIME (2*1000) /* ms */ +#define DBDC_WMM_TX_QUOTA (0x90) +#endif /* CFG_SUPPORT_DBDC */ + +#if CFG_SUPPORT_IDC_CH_SWITCH +#define IDC_CSA_GUARD_TIME (60) /* 60 Sec */ +#endif + +#define CNM_WMM_QUOTA_RETRIGGER_TIME_MS (200) /* ms */ +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +#if CFG_SUPPORT_DBDC +enum ENUM_DBDC_GUARD_TIMER_T { + ENUM_DBDC_GUARD_TIMER_NONE, + + /* Prevent switch too quick */ + ENUM_DBDC_GUARD_TIMER_SWITCH_GUARD_TIME, + + /* Prevent continuously trigger by reconnection */ + ENUM_DBDC_GUARD_TIMER_DISABLE_COUNT_DOWN, + + ENUM_DBDC_GUARD_TIMER_NUM +}; + +enum ENUM_DBDC_FSM_STATE_T { + ENUM_DBDC_FSM_STATE_DISABLE_IDLE, + ENUM_DBDC_FSM_STATE_WAIT_PROTOCOL_ENABLE, + ENUM_DBDC_FSM_STATE_WAIT_HW_ENABLE, + ENUM_DBDC_FSM_STATE_ENABLE_GUARD, + ENUM_DBDC_FSM_STATE_ENABLE_IDLE, + ENUM_DBDC_FSM_STATE_WAIT_HW_DISABLE, + ENUM_DBDC_FSM_STATE_DISABLE_GUARD, + ENUM_DBDC_FSM_STATE_WAIT_PROTOCOL_DISABLE, + ENUM_DBDC_FSM_STATE_NUM +}; + +enum ENUM_OPMODE_STATE_T { + ENUM_OPMODE_STATE_DONE, + ENUM_OPMODE_STATE_FAIL, + ENUM_OPMODE_STATE_WAIT, + ENUM_OPMODE_STATE_NUM +}; + +struct DBDC_INFO_T { + enum ENUM_DBDC_FSM_STATE_T eDbdcFsmCurrState; + enum ENUM_DBDC_FSM_STATE_T eDbdcFsmPrevState; + enum ENUM_DBDC_FSM_STATE_T eDbdcFsmNextState; + + struct TIMER rDbdcGuardTimer; + enum ENUM_DBDC_GUARD_TIMER_T eDdbcGuardTimerType; + + uint8_t fgReqPrivelegeLock; + struct LINK rPendingMsgList; + + bool fgDbdcDisableOpmodeChangeDone; + enum ENUM_OPMODE_STATE_T eBssOpModeState[BSSID_NUM]; + + /* Set DBDC setting for incoming network */ + uint8_t ucPrimaryChannel; + uint8_t ucWmmQueIdx; + + /* Used for iwpriv to force enable DBDC*/ + bool fgHasSentCmd; + bool fgCmdEn; + + /* Used to queue enter/leave A+G event */ + bool fgPostpondEnterAG; + bool fgPostpondLeaveAG; + + /* For debug */ + OS_SYSTIME rPeivilegeLockTime; +}; + +enum ENUM_DBDC_FSM_EVENT_T { + DBDC_FSM_EVENT_BSS_DISCONNECT_LEAVE_AG, + DBDC_FSM_EVENT_BSS_CONNECTING_ENTER_AG, + DBDC_FSM_EVENT_SWITCH_GUARD_TIME_TO, + DBDC_FSM_EVENT_DISABLE_COUNT_DOWN_TO, + DBDC_FSM_EVENT_ACTION_FRAME_ALL_SUCCESS, + DBDC_FSM_EVENT_ACTION_FRAME_SOME_FAIL, + DBDC_FSM_EVENT_DBDC_HW_SWITCH_DONE, + DBDC_FSM_EVENT_ERR, + DBDC_FSM_EVENT_NUM +}; + +enum ENUM_DBDC_PROTOCOL_STATUS_T { + ENUM_DBDC_PROTOCOL_STATUS_DONE_SUCCESS = 0, + ENUM_DBDC_PROTOCOL_STATUS_DONE_FAIL, + ENUM_DBDC_PROTOCOL_STATUS_WAIT, + ENUM_DBDC_PROTOCOL_STATUS_NUM +}; + +typedef void (*DBDC_ENTRY_FUNC)(struct ADAPTER *); +typedef void (*DBDC_EVENT_HNDL_FUNC)(struct ADAPTER *, + enum ENUM_DBDC_FSM_EVENT_T); +typedef void (*DBDC_EXIT_FUNC)(struct ADAPTER *); + +struct DBDC_FSM_T { + DBDC_ENTRY_FUNC pfEntryFunc; + DBDC_EVENT_HNDL_FUNC pfEventHandlerFunc; + DBDC_EXIT_FUNC pfExitFunc; +}; +#endif /*CFG_SUPPORT_DBDC*/ + +/* Priority Order !!!! */ +enum ENUM_CNM_OPMODE_REQ_T { + CNM_OPMODE_REQ_DBDC = 0, + CNM_OPMODE_REQ_DBDC_SCAN = 1, + CNM_OPMODE_REQ_COEX = 2, + CNM_OPMODE_REQ_SMARTGEAR = 3, + CNM_OPMODE_REQ_SMARTGEAR_1T2R = 4, + CNM_OPMODE_REQ_COANT = 5, + CNM_OPMODE_REQ_NUM = 6, + CNM_OPMODE_REQ_MAX_CAP = 7 /* just for coding */ +}; + +enum ENUM_CNM_OPMODE_REQ_STATUS { + CNM_OPMODE_REQ_STATUS_SUCCESS, + CNM_OPMODE_REQ_STATUS_INVALID_PARAM, + CNM_OPMODE_REQ_STATUS_RUNNING, + CNM_OPMODE_REQ_STATUS_DEFER, + CNM_OPMODE_REQ_STATUS_NUM +}; + +struct CNM_OPMODE_BSS_REQ { + bool fgEnable; + bool fgNewRequest; + uint8_t ucOpRxNss; + uint8_t ucOpTxNss; +}; + +struct CNM_OPMODE_BSS_RUNNING_REQ { + /* Initiator */ + enum ENUM_CNM_OPMODE_REQ_T eReqIdx; + /* Highest prioirty req */ + enum ENUM_CNM_OPMODE_REQ_T eRunReq; + bool fgIsRunning; + uint8_t ucOpRxNss; + uint8_t ucOpTxNss; +}; + +struct CNM_OPMODE_BSS_CONTROL_T { + struct CNM_OPMODE_BSS_RUNNING_REQ + rRunning; + struct CNM_OPMODE_BSS_REQ + arReqPool[CNM_OPMODE_REQ_NUM]; +}; + +enum ENUM_CNM_WMM_QUOTA_REQ_T { + CNM_WMM_REQ_DBDC = 0, + CNM_WMM_REQ_NUM = 1, + CNM_WMM_REQ_DEFAULT = 2 /* just for coding */ +}; + +struct CNM_WMM_QUOTA_REQ { + bool fgEnable; + uint32_t u4ReqQuota; +}; + +struct CNM_WMM_QUOTA_RUNNING_REQ { + /* Initiator */ + enum ENUM_CNM_WMM_QUOTA_REQ_T eReqIdx; + /* Highest prioirty req */ + enum ENUM_CNM_WMM_QUOTA_REQ_T eRunReq; + bool fgIsRunning; + uint32_t u4ReqQuota; +}; + +struct CNM_WMM_QUOTA_CONTROL_T { + struct CNM_WMM_QUOTA_RUNNING_REQ + rRunning; + struct CNM_WMM_QUOTA_REQ + arReqPool[CNM_WMM_REQ_NUM]; + struct TIMER rTimer; +}; + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ +#if CFG_SUPPORT_IDC_CH_SWITCH +struct EVENT_LTE_SAFE_CHN g_rLteSafeChInfo; +#endif + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +#if CFG_SUPPORT_DBDC +#define DBDC_SET_GUARD_TIME(_prAdapter, _u4TimeoutMs) { \ + cnmTimerStartTimer(_prAdapter, \ + &g_rDbdcInfo.rDbdcGuardTimer, \ + _u4TimeoutMs); \ + g_rDbdcInfo.eDdbcGuardTimerType = \ + ENUM_DBDC_GUARD_TIMER_SWITCH_GUARD_TIME; \ +} + +#define DBDC_SET_DISABLE_COUNTDOWN(_prAdapter) { \ + cnmTimerStartTimer(_prAdapter, \ + &g_rDbdcInfo.rDbdcGuardTimer, \ + DBDC_DISABLE_COUNTDOWN_TIME); \ + g_rDbdcInfo.eDdbcGuardTimerType = \ + ENUM_DBDC_GUARD_TIMER_DISABLE_COUNT_DOWN; \ + } + +#define DBDC_FSM_MSG_WRONG_EVT(_eEvent) \ + log_dbg(CNM, WARN, \ + "[DBDC] Should not reveice evt %u during state %u\n", \ + _eEvent, \ + g_rDbdcInfo.eDbdcFsmCurrState) + +#define DBDC_FSM_MSG_ERROR_EVT(_eEvent) \ + log_dbg(CNM, ERROR, "[DBDC] Reveice evt %u during state %u\n", \ + _eEvent, \ + g_rDbdcInfo.eDbdcFsmCurrState) + +#define USE_DBDC_CAPABILITY() \ + ((g_rDbdcInfo.eDbdcFsmCurrState \ + == ENUM_DBDC_FSM_STATE_WAIT_PROTOCOL_ENABLE || \ + g_rDbdcInfo.eDbdcFsmCurrState \ + == ENUM_DBDC_FSM_STATE_WAIT_HW_ENABLE || \ + g_rDbdcInfo.eDbdcFsmCurrState \ + == ENUM_DBDC_FSM_STATE_ENABLE_GUARD || \ + g_rDbdcInfo.eDbdcFsmCurrState \ + == ENUM_DBDC_FSM_STATE_ENABLE_IDLE)?TRUE:FALSE) + +#define DBDC_SET_WMMBAND_FW_AUTO_BY_CHNL(_ucPrimaryChannel, _ucWmmQueIdx) \ + { \ + g_rDbdcInfo.ucPrimaryChannel = (_ucPrimaryChannel);\ + g_rDbdcInfo.ucWmmQueIdx = (_ucWmmQueIdx);\ + } + +#define DBDC_SET_WMMBAND_FW_AUTO_DEFAULT() \ + { \ + g_rDbdcInfo.ucPrimaryChannel = 0; \ + g_rDbdcInfo.ucWmmQueIdx = 0;\ + } + +#define DBDC_UPDATE_CMD_WMMBAND_FW_AUTO(_prCmdBody) \ + { \ + (_prCmdBody)->ucPrimaryChannel = g_rDbdcInfo.ucPrimaryChannel; \ + (_prCmdBody)->ucWmmQueIdx = g_rDbdcInfo.ucWmmQueIdx; \ + DBDC_SET_WMMBAND_FW_AUTO_DEFAULT(); \ + } + +#endif + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +static void +cnmDbdcFsmEntryFunc_DISABLE_IDLE( + IN struct ADAPTER *prAdapter +); + +static void +cnmDbdcFsmEntryFunc_WAIT_PROTOCOL_ENABLE( + IN struct ADAPTER *prAdapter +); + +static void +cnmDbdcFsmEntryFunc_WAIT_HW_ENABLE( + IN struct ADAPTER *prAdapter +); + +static void +cnmDbdcFsmEntryFunc_ENABLE_GUARD( + IN struct ADAPTER *prAdapter +); + +static void +cnmDbdcFsmEntryFunc_WAIT_HW_DISABLE( + IN struct ADAPTER *prAdapter +); + +static void +cnmDbdcFsmEntryFunc_ENABLE_IDLE( + IN struct ADAPTER *prAdapter +); + +static void +cnmDbdcFsmEntryFunc_DISABLE_GUARD( + IN struct ADAPTER *prAdapter +); + +static void +cnmDbdcFsmEventHandler_DISABLE_IDLE( + IN struct ADAPTER *prAdapter, + IN enum ENUM_DBDC_FSM_EVENT_T eEvent +); + +static void +cnmDbdcFsmEventHandler_WAIT_PROTOCOL_ENABLE( + IN struct ADAPTER *prAdapter, + IN enum ENUM_DBDC_FSM_EVENT_T eEvent +); + +static void +cnmDbdcFsmEventHandler_WAIT_HW_ENABLE( + IN struct ADAPTER *prAdapter, + IN enum ENUM_DBDC_FSM_EVENT_T eEvent +); + +static void +cnmDbdcFsmEventHandler_ENABLE_GUARD( + IN struct ADAPTER *prAdapter, + IN enum ENUM_DBDC_FSM_EVENT_T eEvent +); + +static void +cnmDbdcFsmEventHandler_ENABLE_IDLE( + IN struct ADAPTER *prAdapter, + IN enum ENUM_DBDC_FSM_EVENT_T eEvent +); + +static void +cnmDbdcFsmEventHandler_WAIT_HW_DISABLE( + IN struct ADAPTER *prAdapter, + IN enum ENUM_DBDC_FSM_EVENT_T eEvent +); + +static void +cnmDbdcFsmEventHandler_DISABLE_GUARD( + IN struct ADAPTER *prAdapter, + IN enum ENUM_DBDC_FSM_EVENT_T eEvent +); + +static void +cnmDbdcFsmEventHandler_WAIT_PROTOCOL_DISABLE( + IN struct ADAPTER *prAdapter, + IN enum ENUM_DBDC_FSM_EVENT_T eEvent +); + +static void +cnmDbdcFsmExitFunc_WAIT_HW_ENABLE( + IN struct ADAPTER *prAdapter +); + +static void +cnmDbdcFsmExitFunc_WAIT_HW_DISABLE( + IN struct ADAPTER *prAdapter +); + +static void +cnmDbdcOpModeChangeDoneCallback( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN bool fgSuccess +); + +static enum ENUM_CNM_OPMODE_REQ_STATUS +cnmOpModeSetTRxNss( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN enum ENUM_CNM_OPMODE_REQ_T eNewReq, + IN bool fgEnable, + IN uint8_t ucOpRxNss, + IN uint8_t ucOpTxNss +); + +static void +cnmWmmQuotaCallback( + IN struct ADAPTER *prAdapter, + IN unsigned long plParamPtr +); + +static void +cnmWmmQuotaSetMaxQuota( + IN struct ADAPTER *prAdapter, + IN uint8_t ucWmmIndex, + IN enum ENUM_CNM_WMM_QUOTA_REQ_T eNewReq, + IN bool fgEnable, + IN uint32_t u4ReqQuota +); + +/******************************************************************************* + * P R I V A T E D A T A 2 + ******************************************************************************* + */ +static struct DBDC_FSM_T arDdbcFsmActionTable[] = { + /* ENUM_DBDC_FSM_STATE_DISABLE_IDLE */ + { + cnmDbdcFsmEntryFunc_DISABLE_IDLE, + cnmDbdcFsmEventHandler_DISABLE_IDLE, + NULL + }, + + /* ENUM_DBDC_FSM_STATE_WAIT_PROTOCOL_ENABLE */ + { + cnmDbdcFsmEntryFunc_WAIT_PROTOCOL_ENABLE, + cnmDbdcFsmEventHandler_WAIT_PROTOCOL_ENABLE, + NULL + }, + + /* ENUM_DBDC_FSM_STATE_WAIT_HW_ENABLE */ + { + cnmDbdcFsmEntryFunc_WAIT_HW_ENABLE, + cnmDbdcFsmEventHandler_WAIT_HW_ENABLE, + cnmDbdcFsmExitFunc_WAIT_HW_ENABLE + }, + + /* ENUM_DBDC_FSM_STATE_ENABLE_GUARD */ + { + cnmDbdcFsmEntryFunc_ENABLE_GUARD, + cnmDbdcFsmEventHandler_ENABLE_GUARD, + NULL + }, + + /* ENUM_DBDC_FSM_STATE_ENABLE_IDLE */ + { + cnmDbdcFsmEntryFunc_ENABLE_IDLE, + cnmDbdcFsmEventHandler_ENABLE_IDLE, + NULL + }, + + /* ENUM_DBDC_FSM_STATE_WAIT_HW_DISABLE */ + { + cnmDbdcFsmEntryFunc_WAIT_HW_DISABLE, + cnmDbdcFsmEventHandler_WAIT_HW_DISABLE, + cnmDbdcFsmExitFunc_WAIT_HW_DISABLE + }, + + /* ENUM_DBDC_FSM_STATE_DISABLE_GUARD */ + { + cnmDbdcFsmEntryFunc_DISABLE_GUARD, + cnmDbdcFsmEventHandler_DISABLE_GUARD, + NULL + }, + + /* ENUM_DBDC_FSM_STATE_WAIT_PROTOCOL_DISABLE */ + { + NULL, + cnmDbdcFsmEventHandler_WAIT_PROTOCOL_DISABLE, + NULL + }, +}; + +#if CFG_SUPPORT_DBDC +static struct DBDC_INFO_T g_rDbdcInfo; +#endif + +#if CFG_SUPPORT_IDC_CH_SWITCH +OS_SYSTIME g_rLastCsaSysTime; +#endif + +static struct CNM_OPMODE_BSS_CONTROL_T g_arBssOpControl[BSS_DEFAULT_NUM]; +static uint8_t *apucCnmOpModeReq[CNM_OPMODE_REQ_MAX_CAP+1] = { + (uint8_t *) DISP_STRING("DBDC"), + (uint8_t *) DISP_STRING("DBDC Scan"), + (uint8_t *) DISP_STRING("COEX"), + (uint8_t *) DISP_STRING("SmartGear"), + (uint8_t *) DISP_STRING("SmartGear_1T2R"), + (uint8_t *) DISP_STRING("CoAnt"), + (uint8_t *) DISP_STRING("N/A"), + (uint8_t *) DISP_STRING("MAX_CAP") +}; + +static uint8_t *apucCnmOpModeReqStatus[CNM_OPMODE_REQ_STATUS_NUM+1] = { + (uint8_t *) DISP_STRING("Success"), + (uint8_t *) DISP_STRING("Invalid"), + (uint8_t *) DISP_STRING("Running"), + (uint8_t *) DISP_STRING("Defer"), + (uint8_t *) DISP_STRING("N/A") +}; + +static struct CNM_WMM_QUOTA_CONTROL_T g_arWmmQuotaControl[BSS_DEFAULT_NUM]; +static uint8_t *apucCnmWmmQuotaReq[CNM_WMM_REQ_DEFAULT+1] = { + (uint8_t *) DISP_STRING("DBDC"), + (uint8_t *) DISP_STRING("N/A"), + (uint8_t *) DISP_STRING("Default") +}; + +/******************************************************************************* + * M A C R O S 2 + ******************************************************************************* + */ +#define DBDC_FSM_EVENT_HANDLER(_prAdapter, _event) { \ + arDdbcFsmActionTable[g_rDbdcInfo.eDbdcFsmCurrState] \ + .pfEventHandlerFunc(_prAdapter, _event); \ + } + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is used to initialize variables in CNM_INFO_T. + * + * @param (none) + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void cnmInit(struct ADAPTER *prAdapter) +{ + struct CNM_INFO *prCnmInfo; + struct CNM_OPMODE_BSS_CONTROL_T *prBssOpCtrl; + struct CNM_WMM_QUOTA_CONTROL_T *prWmmQuotaCtrl; + enum ENUM_CNM_OPMODE_REQ_T eReqIdx; + enum ENUM_CNM_WMM_QUOTA_REQ_T eReqIdxWmm; + uint8_t ucBssIndex, ucWmmIndex; + + ASSERT(prAdapter); + + prCnmInfo = &prAdapter->rCnmInfo; + prCnmInfo->fgChGranted = FALSE; + + if (prAdapter->ucHwBssIdNum > BSS_DEFAULT_NUM) { + /* Unexpected! out of bounds access may happen... */ + DBGLOG(CNM, WARN, + "HwBssNum(%d) > BSS_DEFAULT_NUM !!!\n", + prAdapter->ucHwBssIdNum); + } + + for (ucBssIndex = 0; ucBssIndex < prAdapter->ucHwBssIdNum; + ucBssIndex++) { + prBssOpCtrl = &(g_arBssOpControl[ucBssIndex]); + prBssOpCtrl->rRunning.fgIsRunning = false; + for (eReqIdx = CNM_OPMODE_REQ_DBDC; + eReqIdx < CNM_OPMODE_REQ_NUM; eReqIdx++) + prBssOpCtrl->arReqPool[eReqIdx].fgEnable = false; + } + + if (prAdapter->ucHwBssIdNum > MAX_BSSID_NUM || + prAdapter->ucWmmSetNum > MAX_BSSID_NUM) { + /* Unexpected! out of bounds access may happen... */ + DBGLOG(CNM, WARN, + "HwBssNum(%d)WmmNum(%d) > BSS_DEFAULT_NUM !!!\n", + prAdapter->ucHwBssIdNum, + prAdapter->ucWmmSetNum); + ASSERT(0); + } + + for (ucWmmIndex = 0; ucWmmIndex < prAdapter->ucWmmSetNum; + ucWmmIndex++) { + prWmmQuotaCtrl = &(g_arWmmQuotaControl[ucWmmIndex]); + prWmmQuotaCtrl->rRunning.fgIsRunning = false; + cnmTimerInitTimer(prAdapter, + &(prWmmQuotaCtrl->rTimer), + (PFN_MGMT_TIMEOUT_FUNC) + cnmWmmQuotaCallback, + (unsigned long) + ucWmmIndex); + for (eReqIdxWmm = CNM_WMM_REQ_DBDC; + eReqIdxWmm < CNM_WMM_REQ_NUM; eReqIdxWmm++) + prWmmQuotaCtrl->arReqPool[eReqIdxWmm].fgEnable = false; + } + +#if CFG_SUPPORT_IDC_CH_SWITCH + g_rLastCsaSysTime = 0; +#endif +} /* end of cnmInit()*/ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is used to initialize variables in CNM_INFO_T. + * + * @param (none) + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void cnmUninit(struct ADAPTER *prAdapter) +{ + struct CNM_WMM_QUOTA_CONTROL_T *prWmmQuotaCtrl; + uint8_t ucWmmIndex; + + cnmTimerStopTimer(prAdapter, + &g_rDbdcInfo.rDbdcGuardTimer); + + for (ucWmmIndex = 0; ucWmmIndex < prAdapter->ucWmmSetNum; + ucWmmIndex++) { + prWmmQuotaCtrl = &(g_arWmmQuotaControl[ucWmmIndex]); + cnmTimerStopTimer(prAdapter, &(prWmmQuotaCtrl->rTimer)); + } +} /* end of cnmUninit()*/ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Before handle the message from other module, it need to obtain + * the Channel privilege from Channel Manager + * + * @param[in] prMsgHdr The message need to be handled. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void cnmChMngrRequestPrivilege(struct ADAPTER + *prAdapter, + struct MSG_HDR *prMsgHdr) +{ + struct MSG_CH_REQ *prMsgChReq; + struct CMD_CH_PRIVILEGE *prCmdBody; + struct BSS_INFO *prBssInfo = (struct BSS_INFO *) NULL; + uint32_t rStatus; +#if CFG_SUPPORT_DBDC + OS_SYSTIME rChReqQueueTime; +#endif + + ASSERT(prAdapter); + ASSERT(prMsgHdr); + + prMsgChReq = (struct MSG_CH_REQ *)prMsgHdr; + +#if CFG_SUPPORT_DBDC + if (cnmDBDCIsReqPeivilegeLock()) { + LINK_INSERT_TAIL(&g_rDbdcInfo.rPendingMsgList, + &prMsgHdr->rLinkEntry); + log_dbg(CNM, INFO, + "[DBDC] ChReq: queued BSS %u Token %u REQ\n", + prMsgChReq->ucBssIndex, prMsgChReq->ucTokenID); + + /* Trigger EE dump if PeivilegeLock was held for more than 5s */ + rChReqQueueTime = kalGetTimeTick(); + if ((g_rDbdcInfo.rPeivilegeLockTime != 0) && + (rChReqQueueTime > g_rDbdcInfo.rPeivilegeLockTime) && + ((rChReqQueueTime - + g_rDbdcInfo.rPeivilegeLockTime) > 5000)) { + log_dbg(CNM, WARN, + "[DBDC] ChReq: long peivilege lock at %d, %d\n", + g_rDbdcInfo.rPeivilegeLockTime, + rChReqQueueTime); + GL_RESET_TRIGGER(prAdapter, RST_FLAG_CHIP_RESET); + } + return; + } +#endif + + prCmdBody = (struct CMD_CH_PRIVILEGE *) + cnmMemAlloc(prAdapter, RAM_TYPE_BUF, + sizeof(struct CMD_CH_PRIVILEGE)); + ASSERT(prCmdBody); + + /* To do: exception handle */ + if (!prCmdBody) { + log_dbg(CNM, ERROR, + "ChReq: fail to get buf (net=%d, token=%d)\n", + prMsgChReq->ucBssIndex, prMsgChReq->ucTokenID); + + cnmMemFree(prAdapter, prMsgHdr); + return; + } + + /* Activate network if it's not activated yet */ + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prMsgChReq->ucBssIndex); + + if (!IS_BSS_ACTIVE(prBssInfo)) { + SET_NET_ACTIVE(prAdapter, prBssInfo->ucBssIndex); + nicActivateNetwork(prAdapter, prBssInfo->ucBssIndex); + } + + log_dbg(CNM, INFO, + "ChReq net=%d token=%d b=%d c=%d s=%d w=%d s1=%d s2=%d d=%d t=%d\n", + prMsgChReq->ucBssIndex, prMsgChReq->ucTokenID, + prMsgChReq->eRfBand, prMsgChReq->ucPrimaryChannel, + prMsgChReq->eRfSco, prMsgChReq->eRfChannelWidth, + prMsgChReq->ucRfCenterFreqSeg1, + prMsgChReq->ucRfCenterFreqSeg2, + prMsgChReq->u4MaxInterval, + prMsgChReq->eReqType); + + prCmdBody->ucBssIndex = prMsgChReq->ucBssIndex; + prCmdBody->ucTokenID = prMsgChReq->ucTokenID; + prCmdBody->ucAction = CMD_CH_ACTION_REQ; /* Request */ + prCmdBody->ucPrimaryChannel = + prMsgChReq->ucPrimaryChannel; + prCmdBody->ucRfSco = (uint8_t)prMsgChReq->eRfSco; + prCmdBody->ucRfBand = (uint8_t)prMsgChReq->eRfBand; + prCmdBody->ucRfChannelWidth = (uint8_t) + prMsgChReq->eRfChannelWidth; + prCmdBody->ucRfCenterFreqSeg1 = (uint8_t) + prMsgChReq->ucRfCenterFreqSeg1; + prCmdBody->ucRfCenterFreqSeg2 = (uint8_t) + prMsgChReq->ucRfCenterFreqSeg2; + prCmdBody->ucReqType = (uint8_t)prMsgChReq->eReqType; + prCmdBody->ucDBDCBand = (uint8_t)prMsgChReq->eDBDCBand; + prCmdBody->aucReserved = 0; + prCmdBody->u4MaxInterval = prMsgChReq->u4MaxInterval; + prCmdBody->aucReserved2[0] = 0; + prCmdBody->aucReserved2[1] = 0; + prCmdBody->aucReserved2[2] = 0; + prCmdBody->aucReserved2[3] = 0; + prCmdBody->aucReserved2[4] = 0; + prCmdBody->aucReserved2[5] = 0; + prCmdBody->aucReserved2[6] = 0; + prCmdBody->aucReserved2[7] = 0; + + ASSERT(prCmdBody->ucBssIndex <= + prAdapter->ucHwBssIdNum); + + /* For monkey testing 20110901 */ + if (prCmdBody->ucBssIndex > prAdapter->ucHwBssIdNum) + log_dbg(CNM, ERROR, + "CNM: ChReq with wrong netIdx=%d\n\n", + prCmdBody->ucBssIndex); + + rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ + CMD_ID_CH_PRIVILEGE, /* ucCID */ + TRUE, /* fgSetQuery */ + FALSE, /* fgNeedResp */ + FALSE, /* fgIsOid */ + NULL, /* pfCmdDoneHandler */ + NULL, /* pfCmdTimeoutHandler */ + + /* u4SetQueryInfoLen */ + sizeof(struct CMD_CH_PRIVILEGE), + + /* pucInfoBuffer */ + (uint8_t *)prCmdBody, + + NULL, /* pvSetQueryBuffer */ + 0 /* u4SetQueryBufferLen */ + ); + + /* ASSERT(rStatus == WLAN_STATUS_PENDING); */ + + cnmMemFree(prAdapter, prCmdBody); + cnmMemFree(prAdapter, prMsgHdr); +} /* end of cnmChMngrRequestPrivilege()*/ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Before deliver the message to other module, it need to release + * the Channel privilege to Channel Manager. + * + * @param[in] prMsgHdr The message need to be delivered + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void cnmChMngrAbortPrivilege(struct ADAPTER *prAdapter, + struct MSG_HDR *prMsgHdr) +{ + struct MSG_CH_ABORT *prMsgChAbort; + struct CMD_CH_PRIVILEGE *prCmdBody; + struct CNM_INFO *prCnmInfo; + uint32_t rStatus; +#if CFG_SISO_SW_DEVELOP + struct BSS_INFO *prBssInfo; +#endif +#if CFG_SUPPORT_DBDC + struct LINK_ENTRY *prLinkEntry_pendingMsg; + struct MSG_CH_REQ *prPendingMsg; +#endif + + ASSERT(prAdapter); + ASSERT(prMsgHdr); + + prMsgChAbort = (struct MSG_CH_ABORT *)prMsgHdr; + +#if CFG_SUPPORT_DBDC + if (cnmDBDCIsReqPeivilegeLock()) { + LINK_FOR_EACH(prLinkEntry_pendingMsg, + &g_rDbdcInfo.rPendingMsgList) { + prPendingMsg = (struct MSG_CH_REQ *) + LINK_ENTRY(prLinkEntry_pendingMsg, + struct MSG_HDR, rLinkEntry); + + /* Find matched request and check + * if it is being served. + */ + if (prPendingMsg->ucBssIndex == prMsgChAbort->ucBssIndex + && prPendingMsg->ucTokenID + == prMsgChAbort->ucTokenID) { + + LINK_REMOVE_KNOWN_ENTRY( + &g_rDbdcInfo.rPendingMsgList, + &prPendingMsg->rMsgHdr.rLinkEntry); + + log_dbg(CNM, INFO, "[DBDC] ChAbort: remove BSS %u Token %u REQ)\n", + prPendingMsg->ucBssIndex, + prPendingMsg->ucTokenID); + + cnmMemFree(prAdapter, prPendingMsg); + cnmMemFree(prAdapter, prMsgHdr); + + return; + } + } + } +#endif + + /* Check if being granted channel privilege is aborted */ + prCnmInfo = &prAdapter->rCnmInfo; + if (prCnmInfo->fgChGranted && + prCnmInfo->ucBssIndex == prMsgChAbort->ucBssIndex + && prCnmInfo->ucTokenID == prMsgChAbort->ucTokenID) { + + prCnmInfo->fgChGranted = FALSE; + } + + prCmdBody = (struct CMD_CH_PRIVILEGE *) + cnmMemAlloc(prAdapter, RAM_TYPE_BUF, + sizeof(struct CMD_CH_PRIVILEGE)); + if (!prCmdBody) { + log_dbg(CNM, ERROR, + "ChAbort: fail to get buf (net=%d, token=%d)\n", + prMsgChAbort->ucBssIndex, prMsgChAbort->ucTokenID); + + cnmMemFree(prAdapter, prMsgHdr); + return; + } + + prCmdBody->ucBssIndex = prMsgChAbort->ucBssIndex; + prCmdBody->ucTokenID = prMsgChAbort->ucTokenID; + prCmdBody->ucAction = CMD_CH_ACTION_ABORT; /* Abort */ + prCmdBody->ucDBDCBand = (uint8_t) + prMsgChAbort->eDBDCBand; + + log_dbg(CNM, INFO, "ChAbort net=%d token=%d dbdc=%u\n", + prCmdBody->ucBssIndex, prCmdBody->ucTokenID, + prCmdBody->ucDBDCBand); + + ASSERT(prCmdBody->ucBssIndex <= + prAdapter->ucHwBssIdNum); + + /* For monkey testing 20110901 */ + if (prCmdBody->ucBssIndex > prAdapter->ucHwBssIdNum) + log_dbg(CNM, ERROR, + "CNM: ChAbort with wrong netIdx=%d\n\n", + prCmdBody->ucBssIndex); + + rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ + CMD_ID_CH_PRIVILEGE, /* ucCID */ + TRUE, /* fgSetQuery */ + FALSE, /* fgNeedResp */ + FALSE, /* fgIsOid */ + NULL, /* pfCmdDoneHandler */ + NULL, /* pfCmdTimeoutHandler */ + + /* u4SetQueryInfoLen */ + sizeof(struct CMD_CH_PRIVILEGE), + + /* pucInfoBuffer */ + (uint8_t *)prCmdBody, + + NULL, /* pvSetQueryBuffer */ + 0 /* u4SetQueryBufferLen */ + ); + + /* ASSERT(rStatus == WLAN_STATUS_PENDING); */ + +#if CFG_SISO_SW_DEVELOP + prBssInfo = + prAdapter->aprBssInfo[prMsgChAbort->ucBssIndex]; + /* Driver clear granted CH in BSS info */ + prBssInfo->fgIsGranted = FALSE; + prBssInfo->eBandGranted = BAND_NULL; + prBssInfo->ucPrimaryChannelGranted = 0; +#endif + + cnmMemFree(prAdapter, prCmdBody); + cnmMemFree(prAdapter, prMsgHdr); +} /* end of cnmChMngrAbortPrivilege()*/ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief + * + * @param (none) + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void cnmChMngrHandleChEvent(struct ADAPTER *prAdapter, + struct WIFI_EVENT *prEvent) +{ + struct EVENT_CH_PRIVILEGE *prEventBody; + struct MSG_CH_GRANT *prChResp; + struct BSS_INFO *prBssInfo; + struct CNM_INFO *prCnmInfo; + + ASSERT(prAdapter); + ASSERT(prEvent); + + prEventBody = (struct EVENT_CH_PRIVILEGE *)( + prEvent->aucBuffer); + prChResp = (struct MSG_CH_GRANT *) + cnmMemAlloc(prAdapter, RAM_TYPE_MSG, + sizeof(struct MSG_CH_GRANT)); + if (!prChResp) { + log_dbg(CNM, ERROR, + "ChGrant: fail to get buf (net=%d, token=%d)\n", + prEventBody->ucBssIndex, prEventBody->ucTokenID); + + return; + } + + log_dbg(CNM, INFO, + "ChGrant net=%d token=%d ch=%d sco=%d u4GrantInterval=%d\n", + prEventBody->ucBssIndex, prEventBody->ucTokenID, + prEventBody->ucPrimaryChannel, + prEventBody->ucRfSco, prEventBody->u4GrantInterval); + + ASSERT(prEventBody->ucBssIndex <= + prAdapter->ucHwBssIdNum); + ASSERT(prEventBody->ucStatus == EVENT_CH_STATUS_GRANT); + + prBssInfo = + prAdapter->aprBssInfo[prEventBody->ucBssIndex]; + + /* Decide message ID based on network and response status */ + if (IS_BSS_AIS(prBssInfo)) + prChResp->rMsgHdr.eMsgId = MID_CNM_AIS_CH_GRANT; +#if CFG_ENABLE_WIFI_DIRECT + else if (prAdapter->fgIsP2PRegistered + && IS_BSS_P2P(prBssInfo)) + prChResp->rMsgHdr.eMsgId = MID_CNM_P2P_CH_GRANT; +#endif +#if CFG_ENABLE_BT_OVER_WIFI + else if (IS_BSS_BOW(prBssInfo)) + prChResp->rMsgHdr.eMsgId = MID_CNM_BOW_CH_GRANT; +#endif + else { + cnmMemFree(prAdapter, prChResp); + return; + } + + prChResp->ucBssIndex = prEventBody->ucBssIndex; + prChResp->ucTokenID = prEventBody->ucTokenID; + prChResp->ucPrimaryChannel = + prEventBody->ucPrimaryChannel; + prChResp->eRfSco = (enum ENUM_CHNL_EXT) + prEventBody->ucRfSco; + prChResp->eRfBand = (enum ENUM_BAND) + prEventBody->ucRfBand; + prChResp->eRfChannelWidth = (enum ENUM_CHANNEL_WIDTH) + prEventBody->ucRfChannelWidth; + prChResp->ucRfCenterFreqSeg1 = + prEventBody->ucRfCenterFreqSeg1; + prChResp->ucRfCenterFreqSeg2 = + prEventBody->ucRfCenterFreqSeg2; + prChResp->eReqType = (enum ENUM_CH_REQ_TYPE) + prEventBody->ucReqType; + prChResp->eDBDCBand = (enum ENUM_DBDC_BN) + prEventBody->ucDBDCBand; + prChResp->u4GrantInterval = + prEventBody->u4GrantInterval; + + mboxSendMsg(prAdapter, MBOX_ID_0, + (struct MSG_HDR *)prChResp, MSG_SEND_METHOD_BUF); + + /* Record current granted BSS for TXM's reference */ + prCnmInfo = &prAdapter->rCnmInfo; + prCnmInfo->ucBssIndex = prEventBody->ucBssIndex; + prCnmInfo->ucTokenID = prEventBody->ucTokenID; + prCnmInfo->fgChGranted = TRUE; +} + +#if (CFG_SUPPORT_DFS_MASTER == 1) +void cnmRadarDetectEvent(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ + struct EVENT_RDD_REPORT *prEventBody; + struct BSS_INFO *prBssInfo; + struct MSG_P2P_RADAR_DETECT *prP2pRddDetMsg; + uint8_t ucBssIndex; + + log_dbg(CNM, INFO, "cnmRadarDetectEvent.\n"); + + prEventBody = (struct EVENT_RDD_REPORT *)( + prEvent->aucBuffer); + + prP2pRddDetMsg = (struct MSG_P2P_RADAR_DETECT *) + cnmMemAlloc(prAdapter, + RAM_TYPE_MSG, sizeof(*prP2pRddDetMsg)); + + if (!prP2pRddDetMsg) { + log_dbg(CNM, ERROR, + "cnmMemAlloc for prP2pRddDetMsg failed!\n"); + return; + } + + prP2pRddDetMsg->rMsgHdr.eMsgId = + MID_CNM_P2P_RADAR_DETECT; + + for (ucBssIndex = 0; ucBssIndex < BSS_DEFAULT_NUM; + ucBssIndex++) { + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + ucBssIndex); + + if (prBssInfo && prBssInfo->fgIsDfsActive) { + prP2pRddDetMsg->ucBssIndex = ucBssIndex; + break; + } + } + + p2pFuncSetDfsState(DFS_STATE_DETECTED); + + p2pFuncRadarInfoInit(); + + g_rP2pRadarInfo.ucRadarReportMode = + prEventBody->ucRadarReportMode; + g_rP2pRadarInfo.ucRddIdx = prEventBody->ucRddIdx; + g_rP2pRadarInfo.ucLongDetected = + prEventBody->ucLongDetected; + g_rP2pRadarInfo.ucPeriodicDetected = + prEventBody->ucPeriodicDetected; + g_rP2pRadarInfo.ucLPBNum = prEventBody->ucLPBNum; + g_rP2pRadarInfo.ucPPBNum = prEventBody->ucPPBNum; + g_rP2pRadarInfo.ucLPBPeriodValid = + prEventBody->ucLPBPeriodValid; + g_rP2pRadarInfo.ucLPBWidthValid = + prEventBody->ucLPBWidthValid; + g_rP2pRadarInfo.ucPRICountM1 = + prEventBody->ucPRICountM1; + g_rP2pRadarInfo.ucPRICountM1TH = + prEventBody->ucPRICountM1TH; + g_rP2pRadarInfo.ucPRICountM2 = + prEventBody->ucPRICountM2; + g_rP2pRadarInfo.ucPRICountM2TH = + prEventBody->ucPRICountM2TH; + g_rP2pRadarInfo.u4PRI1stUs = prEventBody->u4PRI1stUs; + kalMemCopy(&g_rP2pRadarInfo.arLpbContent[0], + &prEventBody->arLpbContent[0], + prEventBody->ucLPBNum * sizeof(struct + LONG_PULSE_BUFFER)); + kalMemCopy(&g_rP2pRadarInfo.arPpbContent[0], + &prEventBody->arPpbContent[0], + prEventBody->ucPPBNum * sizeof(struct + PERIODIC_PULSE_BUFFER)); + + mboxSendMsg(prAdapter, MBOX_ID_0, + (struct MSG_HDR *)prP2pRddDetMsg, MSG_SEND_METHOD_BUF); +} + +void cnmCsaDoneEvent(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ + DBGLOG(CNM, INFO, "cnmCsaDoneEvent.\n"); + + if (prAdapter->rWifiVar.fgCsaInProgress == FALSE) { + DBGLOG(CNM, WARN, "Receive duplicate cnmCsaDoneEvent.\n"); + return; + } + + prAdapter->rWifiVar.fgCsaInProgress = FALSE; + + p2pFunChnlSwitchNotifyDone(prAdapter); +} +#endif + +#define CFG_SUPPORT_IDC_CROSS_BAND_SWITCH 1 + +#if CFG_SUPPORT_IDC_CH_SWITCH +uint8_t cnmDecideSapNewChannel( + IN struct GLUE_INFO *prGlueInfo, + IN struct BSS_INFO *prBssInfo) +{ + uint8_t ucSwitchMode; + uint32_t u4LteSafeChnBitMask_2G = 0, u4LteSafeChnBitMask_5G_1 = 0, + u4LteSafeChnBitMask_5G_2 = 0; + uint8_t ucCurrentChannel = 0; + + if (!prGlueInfo || !prBssInfo) { + DBGLOG(P2P, ERROR, "prGlueInfo or prBssInfo is NULL\n"); + return -EFAULT; + } + + ucCurrentChannel = prBssInfo->ucPrimaryChannel; + + ASSERT(ucCurrentChannel); + + if (ucCurrentChannel <= 14) + ucSwitchMode = CH_SWITCH_2G; + else { + ucSwitchMode = CH_SWITCH_5G; + DBGLOG(P2P, WARN, + "Switch to 5G channel instead\n"); + } + /* + * Get LTE safe channels + */ + if (g_rLteSafeChInfo.u4Flags & BIT(0)) { + u4LteSafeChnBitMask_2G = g_rLteSafeChInfo + .rLteSafeChn.au4SafeChannelBitmask[0]; + u4LteSafeChnBitMask_5G_1 = g_rLteSafeChInfo + .rLteSafeChn.au4SafeChannelBitmask[1]; + u4LteSafeChnBitMask_5G_2 = g_rLteSafeChInfo + .rLteSafeChn.au4SafeChannelBitmask[2]; + } + + if (ucSwitchMode == CH_SWITCH_2G) { + if (!(u4LteSafeChnBitMask_2G & BITS(1, 14))) { + DBGLOG(P2P, WARN, + "FW report 2.4G all channels unsafe!?\n"); +#if CFG_SUPPORT_IDC_CROSS_BAND_SWITCH + /* Choose 5G non-RDD Channel */ + if ((u4LteSafeChnBitMask_5G_1 || u4LteSafeChnBitMask_5G_2) + && prGlueInfo->prAdapter->rWifiVar + .fgCrossBandSwitchEn) { + ucSwitchMode = CH_SWITCH_5G; + DBGLOG(P2P, WARN, + "Switch to 5G channel instead\n"); + } else { + /* not to switch channel*/ + return 0; + } +#endif + } + } else { /*ucSwitchMode == CH_SWITCH_5G*/ + if ((!(u4LteSafeChnBitMask_5G_1 & BITS(0, 27))) && + (!(u4LteSafeChnBitMask_5G_2 & BITS(0, 8)))) { + DBGLOG(P2P, WARN, + "FW report 5G all channels unsafe!?\n"); +#if CFG_SUPPORT_IDC_CROSS_BAND_SWITCH + /* Choose 2.4G non-RDD Channel */ + if (u4LteSafeChnBitMask_2G + && prGlueInfo->prAdapter->rWifiVar + .fgCrossBandSwitchEn) { + ucSwitchMode = CH_SWITCH_2G; + DBGLOG(P2P, WARN, + "Switch to 2.4G channel instead\n"); + } else { + /* not to switch channel*/ + return 0; + } +#endif + } + } + + return p2pFunGetAcsBestCh(prGlueInfo->prAdapter, + ucSwitchMode == CH_SWITCH_2G ? BAND_2G4 : BAND_5G, + rlmGetBssOpBwByVhtAndHtOpInfo(prBssInfo), + u4LteSafeChnBitMask_2G, + u4LteSafeChnBitMask_5G_1, + u4LteSafeChnBitMask_5G_2); +} + +uint8_t cnmIdcCsaReq(IN struct ADAPTER *prAdapter, + IN uint8_t ch_num, IN uint8_t ucRoleIdx) +{ + struct BSS_INFO *prBssInfo = NULL; + uint8_t ucBssIdx = 0; + struct RF_CHANNEL_INFO rRfChnlInfo; + + ASSERT(ch_num); + + if (p2pFuncRoleToBssIdx( + prAdapter, ucRoleIdx, &ucBssIdx) != + WLAN_STATUS_SUCCESS) + return -1; + + DBGLOG(REQ, INFO, + "[CSA]RoleIdx = %d ,CH = %d BssIdx = %d\n", + ucRoleIdx, ch_num, ucBssIdx); + + prBssInfo = prAdapter->aprBssInfo[ucBssIdx]; + + + if (prBssInfo->ucPrimaryChannel != ch_num) { + rRfChnlInfo.ucChannelNum = ch_num; + rRfChnlInfo.eBand = + (rRfChnlInfo.ucChannelNum <= 14) + ? BAND_2G4 : BAND_5G; + rRfChnlInfo.ucChnlBw = + rlmGetBssOpBwByVhtAndHtOpInfo(prBssInfo); + rRfChnlInfo.u2PriChnlFreq = + nicChannelNum2Freq(ch_num) / 1000; + rRfChnlInfo.u4CenterFreq1 = + rRfChnlInfo.u2PriChnlFreq; + rRfChnlInfo.u4CenterFreq2 = 0; + + DBGLOG(REQ, INFO, + "[CSA]CH=%d,Band=%d,BW=%d,PriFreq=%d,S1=%d\n", + rRfChnlInfo.ucChannelNum, + rRfChnlInfo.eBand, + rRfChnlInfo.ucChnlBw, + rRfChnlInfo.u2PriChnlFreq, + rRfChnlInfo.u4CenterFreq1); + + cnmSapChannelSwitchReq(prAdapter, &rRfChnlInfo, ucRoleIdx); + + /* Record Last Channel Switch Time */ + GET_CURRENT_SYSTIME(&g_rLastCsaSysTime); + + return 0; /* Return Success */ + + } else { + DBGLOG(CNM, INFO, + "[CSA]Req CH = cur CH:%d, Stop Req\n", + prBssInfo->ucPrimaryChannel); + return -1; + } +} + +void cnmIdcDetectHandler(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ + + struct EVENT_LTE_SAFE_CHN *prEventBody; + uint8_t ucIdx; + struct BSS_INFO *prBssInfo; + struct GLUE_INFO *prGlueInfo = prAdapter->prGlueInfo; + uint8_t ucNewChannel = 0; + uint32_t u4Ret = 0; + OS_SYSTIME rCurrentTime = 0; + bool fgCsaCoolDown = FALSE; + uint8_t ucColdDownTime = 0; + struct WIFI_VAR *prWifiVar = + (struct WIFI_VAR *)NULL; + + prEventBody = (struct EVENT_LTE_SAFE_CHN *)( + prEvent->aucBuffer); + + g_rLteSafeChInfo.ucVersion = prEventBody->ucVersion; + g_rLteSafeChInfo.u4Flags = prEventBody->u4Flags; + + /* Statistics from FW is valid */ + if (prEventBody->u4Flags & BIT(0)) { + for (ucIdx = 0; + ucIdx < ENUM_SAFE_CH_MASK_MAX_NUM; + ucIdx++) { + g_rLteSafeChInfo.rLteSafeChn. + au4SafeChannelBitmask[ucIdx] + = prEventBody->rLteSafeChn. + au4SafeChannelBitmask[ucIdx]; + + DBGLOG(P2P, INFO, + "[CSA]LTE safe channels[%d]=0x%08x\n", + ucIdx, + prEventBody->rLteSafeChn. + au4SafeChannelBitmask[ucIdx]); + } + } + prWifiVar = &prAdapter->rWifiVar; + if (prWifiVar->ucChannelSwtichColdownTime) + ucColdDownTime = prWifiVar->ucChannelSwtichColdownTime; + else + ucColdDownTime = IDC_CSA_GUARD_TIME; + + + /* Only allow to switch channel once each minute*/ + GET_CURRENT_SYSTIME(&rCurrentTime); + if ((CHECK_FOR_TIMEOUT(rCurrentTime, + g_rLastCsaSysTime, + SEC_TO_SYSTIME(ucColdDownTime))) + || (g_rLastCsaSysTime == 0)) { + fgCsaCoolDown = TRUE; + } + + if (!fgCsaCoolDown) { + DBGLOG(CNM, INFO, + "[CSA]CsaCoolDown not Finish yet,rCurrentTime=%d,g_rLastCsaSysTime=%d,IDC_CSA_GUARD_TIME=%d\n", + rCurrentTime, + g_rLastCsaSysTime, + SEC_TO_SYSTIME(ucColdDownTime)); + return; + } + + /* Choose New Ch & Start CH Swtich*/ + prBssInfo = cnmGetSapBssInfo(prAdapter); + if (prBssInfo) { + DBGLOG(CNM, INFO, "[CSA]BssIdx=%d,CurCH=%d\n", + prBssInfo->ucBssIndex, + prBssInfo->ucPrimaryChannel); + ucNewChannel = cnmDecideSapNewChannel(prGlueInfo, + prBssInfo); + if (ucNewChannel) { + u4Ret = cnmIdcCsaReq(prAdapter, ucNewChannel, + prBssInfo->u4PrivateData); + DBGLOG(CNM, INFO, "[CSA]BssIdx=%d,NewCH=%d\n", + prBssInfo->ucBssIndex, ucNewChannel); + } else { + DBGLOG(CNM, INFO, + "[CSA]No Safe channel,not switch CH\n"); + } + } else { + DBGLOG(CNM, WARN, + "[CSA]SoftAp Not Exist\n"); + } + +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is invoked for P2P or BOW networks + * + * @param (none) + * + * @return TRUE: suggest to adopt the returned preferred channel + * FALSE: No suggestion. Caller should adopt its preference + */ +/*----------------------------------------------------------------------------*/ +u_int8_t +cnmPreferredChannel(struct ADAPTER *prAdapter, + enum ENUM_BAND *prBand, uint8_t *pucPrimaryChannel, + enum ENUM_CHNL_EXT *prBssSCO) +{ + struct BSS_INFO *prBssInfo; + uint8_t i; + + ASSERT(prAdapter); + ASSERT(prBand); + ASSERT(pucPrimaryChannel); + ASSERT(prBssSCO); + + for (i = 0; i < prAdapter->ucHwBssIdNum; i++) { + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, i); + + if (prBssInfo) { + if (IS_BSS_AIS(prBssInfo) + && RLM_NET_PARAM_VALID(prBssInfo)) { + *prBand = prBssInfo->eBand; + *pucPrimaryChannel + = prBssInfo->ucPrimaryChannel; + *prBssSCO = prBssInfo->eBssSCO; + + return TRUE; + } + } + } + + return FALSE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief + * + * @param (none) + * + * @return TRUE: available channel is limited to return value + * FALSE: no limited + */ +/*----------------------------------------------------------------------------*/ +u_int8_t cnmAisInfraChannelFixed(struct ADAPTER + *prAdapter, + enum ENUM_BAND *prBand, + uint8_t *pucPrimaryChannel) +{ + struct BSS_INFO *prBssInfo; + uint8_t i; + struct WIFI_VAR *prWifiVar; + + ASSERT(prAdapter); + + prWifiVar = &prAdapter->rWifiVar; + + if (prWifiVar->u4ScanCtrl & + SCN_CTRL_DEFAULT_SCAN_CTRL) { + /* log_dbg(CNM, INFO, "ByPass AIS channel Fix check\n");*/ + return FALSE; + } + + for (i = 0; i < prAdapter->ucHwBssIdNum; i++) { + prBssInfo = prAdapter->aprBssInfo[i]; + +#if 0 + log_dbg(INIT, INFO, + "%s BSS[%u] active[%u] netType[%u]\n", + __func__, i, prBssInfo->fgIsNetActive, + prBssInfo->eNetworkType); +#endif + + if (!IS_NET_ACTIVE(prAdapter, i)) + continue; + +#if CFG_ENABLE_WIFI_DIRECT + if (prBssInfo->eNetworkType == NETWORK_TYPE_P2P + && !cnmSapIsConcurrent(prAdapter)) { + u_int8_t fgFixedChannel = + p2pFuncIsAPMode( + prAdapter->rWifiVar.prP2PConnSettings[ + prBssInfo->u4PrivateData]); + + if (fgFixedChannel) { + + *prBand = prBssInfo->eBand; + *pucPrimaryChannel + = prBssInfo->ucPrimaryChannel; + + return TRUE; + + } + } +#endif + +#if CFG_ENABLE_BT_OVER_WIFI && CFG_BOW_LIMIT_AIS_CHNL + if (prBssInfo->eNetworkType == NETWORK_TYPE_BOW) { + *prBand = prBssInfo->eBand; + *pucPrimaryChannel = prBssInfo->ucPrimaryChannel; + + return TRUE; + } +#endif + + } + + return FALSE; +} + +#if CFG_SUPPORT_CHNL_CONFLICT_REVISE +u_int8_t cnmAisDetectP2PChannel(struct ADAPTER + *prAdapter, + enum ENUM_BAND *prBand, + uint8_t *pucPrimaryChannel) +{ + uint8_t i = 0; + struct BSS_INFO *prBssInfo; + + ASSERT(prAdapter); + +#if CFG_ENABLE_WIFI_DIRECT + for (; i < prAdapter->ucHwBssIdNum; i++) { + prBssInfo = prAdapter->aprBssInfo[i]; + if (prBssInfo->eNetworkType != NETWORK_TYPE_P2P) + continue; + if (prBssInfo->eConnectionState == + MEDIA_STATE_CONNECTED || + (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT + && prBssInfo->eIntendOPMode == OP_MODE_NUM)) { + *prBand = prBssInfo->eBand; + *pucPrimaryChannel = prBssInfo->ucPrimaryChannel; + return TRUE; + } + } +#endif + return FALSE; +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * @brief + * + * @param (none) + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void cnmAisInfraConnectNotify(struct ADAPTER *prAdapter) +{ +#if CFG_ENABLE_BT_OVER_WIFI + struct BSS_INFO *prBssInfo, *prAisBssInfo, *prBowBssInfo; + uint8_t i; + + ASSERT(prAdapter); + + prAisBssInfo = NULL; + prBowBssInfo = NULL; + + for (i = 0; i < prAdapter->ucHwBssIdNum; i++) { + prBssInfo = prAdapter->aprBssInfo[i]; + + if (prBssInfo && IS_BSS_ACTIVE(prBssInfo)) { + if (IS_BSS_AIS(prBssInfo)) + prAisBssInfo = prBssInfo; + else if (IS_BSS_BOW(prBssInfo)) + prBowBssInfo = prBssInfo; + } + } + + if (prAisBssInfo && prBowBssInfo + && RLM_NET_PARAM_VALID(prAisBssInfo) + && RLM_NET_PARAM_VALID(prBowBssInfo)) { + if (prAisBssInfo->eBand != prBowBssInfo->eBand || + prAisBssInfo->ucPrimaryChannel != + prBowBssInfo->ucPrimaryChannel) { + + /* Notify BOW to do deactivation */ + bowNotifyAllLinkDisconnected(prAdapter); + } + } +#endif +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief + * + * @param (none) + * + * @return TRUE: permitted + * FALSE: Not permitted + */ +/*----------------------------------------------------------------------------*/ +u_int8_t cnmAisIbssIsPermitted(struct ADAPTER + *prAdapter) +{ + struct BSS_INFO *prBssInfo; + uint8_t i; + + ASSERT(prAdapter); + + /* P2P device network shall be included */ + for (i = 0; i <= prAdapter->ucHwBssIdNum; i++) { + prBssInfo = prAdapter->aprBssInfo[i]; + + if (prBssInfo && IS_BSS_ACTIVE(prBssInfo) + && !IS_BSS_AIS(prBssInfo)) + return FALSE; + } + + return TRUE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief + * + * @param (none) + * + * @return TRUE: permitted + * FALSE: Not permitted + */ +/*----------------------------------------------------------------------------*/ +u_int8_t cnmP2PIsPermitted(struct ADAPTER *prAdapter) +{ + struct BSS_INFO *prBssInfo; + uint8_t i; + u_int8_t fgBowIsActive; + + ASSERT(prAdapter); + + fgBowIsActive = FALSE; + + for (i = 0; i < prAdapter->ucHwBssIdNum; i++) { + prBssInfo = prAdapter->aprBssInfo[i]; + + if (prBssInfo && IS_BSS_ACTIVE(prBssInfo)) { + if (prBssInfo->eCurrentOPMode == OP_MODE_IBSS) + return FALSE; + else if (IS_BSS_BOW(prBssInfo)) + fgBowIsActive = TRUE; + } + } + +#if CFG_ENABLE_BT_OVER_WIFI + if (fgBowIsActive) { + /* Notify BOW to do deactivation */ + bowNotifyAllLinkDisconnected(prAdapter); + } +#endif + + return TRUE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief + * + * @param (none) + * + * @return TRUE: permitted + * FALSE: Not permitted + */ +/*----------------------------------------------------------------------------*/ +u_int8_t cnmBowIsPermitted(struct ADAPTER *prAdapter) +{ + struct BSS_INFO *prBssInfo; + uint8_t i; + + ASSERT(prAdapter); + + /* P2P device network shall be included */ + for (i = 0; i <= prAdapter->ucHwBssIdNum; i++) { + prBssInfo = prAdapter->aprBssInfo[i]; + + if (prBssInfo && IS_BSS_ACTIVE(prBssInfo) && + (IS_BSS_P2P(prBssInfo) + || prBssInfo->eCurrentOPMode == OP_MODE_IBSS)) { + return FALSE; + } + } + + return TRUE; +} + + + +static uint8_t cnmGetAPBwPermitted(struct ADAPTER + *prAdapter, uint8_t ucBssIndex) +{ + struct BSS_INFO *prBssInfo; + uint8_t ucAPBandwidth = MAX_BW_160MHZ; + struct BSS_DESC *prBssDesc = NULL; + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *)NULL; + uint8_t i = 0; + uint8_t ucOffset = (MAX_BW_80MHZ - CW_80MHZ); + + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + ucBssIndex); + + + if (IS_BSS_AIS(prBssInfo)) { + /*AIS station mode*/ + prBssDesc + = aisGetTargetBssDesc(prAdapter, ucBssIndex); + } else if (IS_BSS_P2P(prBssInfo)) { + /* P2P mode */ + + for (i = 0 ; i < BSS_P2P_NUM; i++) { + + if (!prAdapter->rWifiVar.aprP2pRoleFsmInfo[i]) + continue; + + if (prAdapter->rWifiVar.aprP2pRoleFsmInfo[i]->ucBssIndex + == + ucBssIndex) + break; + + } + + if (i >= BSS_P2P_NUM) { + prP2pRoleFsmInfo = NULL; + } else { + prP2pRoleFsmInfo = + prAdapter->rWifiVar.aprP2pRoleFsmInfo[i]; + + /*only GC need to consider GO's BW*/ + if (!p2pFuncIsAPMode( + prAdapter->rWifiVar.prP2PConnSettings[ + prBssInfo->u4PrivateData])) { + prBssDesc = prP2pRoleFsmInfo->rJoinInfo + .prTargetBssDesc; + } + + } + + + } + + if (prBssDesc) { + if (prBssDesc->eChannelWidth == CW_20_40MHZ) { + if ((prBssDesc->eSco == CHNL_EXT_SCA) + || (prBssDesc->eSco == CHNL_EXT_SCB)) + ucAPBandwidth = MAX_BW_40MHZ; + else + ucAPBandwidth = MAX_BW_20MHZ; + } else { + ucAPBandwidth = prBssDesc->eChannelWidth + ucOffset; + } + + } + + return ucAPBandwidth; +} + + +/*----------------------------------------------------------------------------*/ +/*! + * @brief + * + * @param (none) + * + * @return TRUE: permitted + * FALSE: Not permitted + */ +/*----------------------------------------------------------------------------*/ +u_int8_t cnmBss40mBwPermitted(struct ADAPTER *prAdapter, + uint8_t ucBssIndex) +{ + ASSERT(prAdapter); + + /* Note: To support real-time decision instead of current + * activated-time, the STA roaming case shall be considered + * about synchronization problem. Another variable + * fgAssoc40mBwAllowed is added to represent HT capability + * when association + */ + + /* Decide max bandwidth by feature option */ + if (cnmGetBssMaxBw(prAdapter, + ucBssIndex) < MAX_BW_40MHZ) + return FALSE; + + /*check AP or GO capbility for Station or GC */ + if (cnmGetAPBwPermitted(prAdapter, + ucBssIndex) < MAX_BW_40MHZ) + return FALSE; +#if 0 + /* Decide max by other BSS */ + for (i = 0; i < prAdapter->ucHwBssIdNum; i++) { + if (i != ucBssIndex) { + prBssInfo = prAdapter->aprBssInfo[i]; + + if (prBssInfo && IS_BSS_ACTIVE(prBssInfo) && + (prBssInfo->fg40mBwAllowed + || prBssInfo->fgAssoc40mBwAllowed)) + return FALSE; + } + } +#endif + + return TRUE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief + * + * @param (none) + * + * @return TRUE: permitted + * FALSE: Not permitted + */ +/*----------------------------------------------------------------------------*/ +u_int8_t cnmBss80mBwPermitted(struct ADAPTER *prAdapter, + uint8_t ucBssIndex) +{ + ASSERT(prAdapter); + + /* Note: To support real-time decision instead of current + * activated-time, the STA roaming case shall be considered + * about synchronization problem. Another variable + * fgAssoc40mBwAllowed is added to represent HT capability + * when association + */ + + /* Check 40Mhz first */ + if (!cnmBss40mBwPermitted(prAdapter, ucBssIndex)) + return FALSE; + + /* Decide max bandwidth by feature option */ + if (cnmGetBssMaxBw(prAdapter, + ucBssIndex) < MAX_BW_80MHZ) + return FALSE; + + /*check AP or GO capbility for Station or GC */ + if (cnmGetAPBwPermitted(prAdapter, + ucBssIndex) < MAX_BW_80MHZ) + return FALSE; + + return TRUE; +} + +uint8_t cnmGetBssMaxBw(struct ADAPTER *prAdapter, + uint8_t ucBssIndex) +{ + struct BSS_INFO *prBssInfo; + uint8_t ucMaxBandwidth = + MAX_BW_80_80_MHZ; /*chip capability*/ + struct BSS_DESC *prBssDesc = NULL; + enum ENUM_BAND eBand = BAND_NULL; + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *) NULL; + struct P2P_CONNECTION_REQ_INFO *prP2pConnReqInfo = + (struct P2P_CONNECTION_REQ_INFO *) NULL; +#if (CFG_SUPPORT_SINGLE_SKU == 1) + uint8_t ucChannelBw = MAX_BW_80_80_MHZ; +#endif + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + ucBssIndex); + + if (IS_BSS_AIS(prBssInfo)) { + /* STA mode */ + + + /* should check Bss_info could be used or not + *the info might not be trustable before state3 + */ + + prBssDesc = + aisGetTargetBssDesc(prAdapter, ucBssIndex); + if (prBssDesc) + eBand = prBssDesc->eBand; + else + eBand = prBssInfo->eBand; + + + ASSERT(eBand != BAND_NULL); + + if (eBand == BAND_2G4) + ucMaxBandwidth = prAdapter->rWifiVar.ucSta2gBandwidth; + else + ucMaxBandwidth = prAdapter->rWifiVar.ucSta5gBandwidth; + + if (ucMaxBandwidth > prAdapter->rWifiVar.ucStaBandwidth) + ucMaxBandwidth = prAdapter->rWifiVar.ucStaBandwidth; + } else if (IS_BSS_P2P(prBssInfo)) { + prP2pRoleFsmInfo = p2pFuncGetRoleByBssIdx(prAdapter, + ucBssIndex); + if (!prAdapter->rWifiVar.ucApChnlDefFromCfg + && prP2pRoleFsmInfo + && prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) { + prP2pConnReqInfo = &(prP2pRoleFsmInfo->rConnReqInfo); + ucMaxBandwidth = prP2pConnReqInfo->eChnlBw; + } else { + /* AP mode */ + if (p2pFuncIsAPMode( + prAdapter->rWifiVar.prP2PConnSettings[ + prBssInfo->u4PrivateData])) { + if (prBssInfo->eBand == BAND_2G4) + ucMaxBandwidth = prAdapter->rWifiVar + .ucAp2gBandwidth; + else + ucMaxBandwidth = prAdapter->rWifiVar + .ucAp5gBandwidth; + + if (ucMaxBandwidth + > prAdapter->rWifiVar.ucApBandwidth) + ucMaxBandwidth = prAdapter->rWifiVar + .ucApBandwidth; + } + /* P2P mode */ + else { + if (prBssInfo->eBand == BAND_2G4) + ucMaxBandwidth = prAdapter->rWifiVar + .ucP2p2gBandwidth; + else + ucMaxBandwidth = prAdapter->rWifiVar + .ucP2p5gBandwidth; + } + + } + + } + +#if (CFG_SUPPORT_SINGLE_SKU == 1) + if (IS_BSS_AIS(prBssInfo) && prBssDesc) + ucChannelBw = rlmDomainGetChannelBw(prBssDesc->ucChannelNum); + else + ucChannelBw = + rlmDomainGetChannelBw(prBssInfo->ucPrimaryChannel); + if (ucMaxBandwidth > ucChannelBw) + ucMaxBandwidth = ucChannelBw; +#endif + DBGLOG_LIMITED(CNM, TRACE, "pCH=%d, BW=%d\n", + prBssInfo->ucPrimaryChannel, ucMaxBandwidth); + + return ucMaxBandwidth; +} + + +uint8_t cnmGetBssMaxBwToChnlBW(struct ADAPTER + *prAdapter, + uint8_t ucBssIndex) +{ + uint8_t ucMaxBandwidth = cnmGetBssMaxBw(prAdapter, + ucBssIndex); + return ucMaxBandwidth == MAX_BW_20MHZ ? ucMaxBandwidth : + (ucMaxBandwidth - 1); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Search available HW ID and BSS_INFO structure and initialize + * these parameters, i.e., fgIsNetActive, ucBssIndex, eNetworkType + * and ucOwnMacIndex + * + * @param (none) + * + * @return + */ +/*----------------------------------------------------------------------------*/ +struct BSS_INFO *cnmGetBssInfoAndInit(struct ADAPTER *prAdapter, + enum ENUM_NETWORK_TYPE eNetworkType, + u_int8_t fgIsP2pDevice) +{ + struct BSS_INFO *prBssInfo; + uint8_t i, ucBssIndex, ucOwnMacIdx; + + ASSERT(prAdapter); + + /*specific case for p2p device scan*/ + if (eNetworkType == NETWORK_TYPE_P2P && fgIsP2pDevice) { + prBssInfo = + prAdapter->aprBssInfo[prAdapter->ucP2PDevBssIdx]; + + prBssInfo->fgIsInUse = TRUE; + prBssInfo->ucBssIndex = prAdapter->ucP2PDevBssIdx; + prBssInfo->eNetworkType = eNetworkType; + prBssInfo->ucOwnMacIndex = prAdapter->ucHwBssIdNum; + + /* initialize wlan id and status for keys */ + prBssInfo->ucBMCWlanIndex = WTBL_RESERVED_ENTRY; + prBssInfo->wepkeyWlanIdx = WTBL_RESERVED_ENTRY; + for (i = 0; i < MAX_KEY_NUM; i++) { + prBssInfo->ucBMCWlanIndexSUsed[i] = FALSE; + prBssInfo->ucBMCWlanIndexS[i] = WTBL_RESERVED_ENTRY; + prBssInfo->wepkeyUsed[i] = FALSE; + } + + return prBssInfo; + } + + /*reserve ownMAC0 for MBSS*/ + ucOwnMacIdx = (eNetworkType == NETWORK_TYPE_MBSS) ? 0 : + 1; + + /* Find available HW set with the order 1,2,..*/ + do { + for (ucBssIndex = 0; + ucBssIndex < prAdapter->ucHwBssIdNum; + ucBssIndex++) { + prBssInfo = prAdapter->aprBssInfo[ucBssIndex]; + + if (prBssInfo && prBssInfo->fgIsInUse + && ucOwnMacIdx == prBssInfo->ucOwnMacIndex) + break; + } + + if (ucBssIndex >= prAdapter->ucHwBssIdNum) { + /* No hit the ucOwnMacIndex could be + * assigned to this new bss + */ + break; + } + } while (++ucOwnMacIdx < prAdapter->ucHwBssIdNum); + + + /* should not dispatch P2P_DEV_BSS_INDEX (prAdapter->ucHwBssIdNum) + * to general bss. It means total BSS_INFO_NUM BSS are created, + * no more reseve for MBSS + */ + if (ucOwnMacIdx == prAdapter->ucHwBssIdNum) { + + for (ucBssIndex = 0; + ucBssIndex < prAdapter->ucHwBssIdNum; + ucBssIndex++) { + prBssInfo = prAdapter->aprBssInfo[ucBssIndex]; + + /*If the Bss was alredy assigned, and in use*/ + if (prBssInfo && prBssInfo->fgIsInUse + && prBssInfo->ucOwnMacIndex == 0) + break; + } + + if (ucBssIndex >= prAdapter->ucHwBssIdNum) { + /* there is no NETWORK_TYPE_MBSS used before */ + + log_dbg(INIT, WARN, "[Warning] too much Bss in use, take reserve OwnMac(%d)for usage!\n", + ucOwnMacIdx); + ucOwnMacIdx = 0; + } + + } + + /* Find available BSS_INFO */ + for (ucBssIndex = 0; + ucBssIndex < prAdapter->ucHwBssIdNum; + ucBssIndex++) { + prBssInfo = prAdapter->aprBssInfo[ucBssIndex]; + + if (prBssInfo && !prBssInfo->fgIsInUse) { + prBssInfo->fgIsInUse = TRUE; + prBssInfo->ucBssIndex = ucBssIndex; + prBssInfo->eNetworkType = eNetworkType; + prBssInfo->ucOwnMacIndex = ucOwnMacIdx; +#if (CFG_HW_WMM_BY_BSS == 1) + prBssInfo->ucWmmQueSet = DEFAULT_HW_WMM_INDEX; + prBssInfo->fgIsWmmInited = FALSE; +#endif + break; + } + } + + if (ucOwnMacIdx >= prAdapter->ucHwBssIdNum + || ucBssIndex >= prAdapter->ucHwBssIdNum) + prBssInfo = NULL; + if (prBssInfo) { + /* initialize wlan id and status for keys */ + prBssInfo->ucBMCWlanIndex = WTBL_RESERVED_ENTRY; + prBssInfo->wepkeyWlanIdx = WTBL_RESERVED_ENTRY; + for (i = 0; i < MAX_KEY_NUM; i++) { + prBssInfo->ucBMCWlanIndexSUsed[i] = FALSE; + prBssInfo->ucBMCWlanIndexS[i] = WTBL_RESERVED_ENTRY; + prBssInfo->wepkeyUsed[i] = FALSE; + } + } + return prBssInfo; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Search available HW ID and BSS_INFO structure and initialize + * these parameters, i.e., ucBssIndex, eNetworkType and ucOwnMacIndex + * + * @param (none) + * + * @return + */ +/*----------------------------------------------------------------------------*/ +void cnmFreeBssInfo(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo) +{ + ASSERT(prAdapter); + ASSERT(prBssInfo); + + prBssInfo->fgIsInUse = FALSE; +} + +#if CFG_SUPPORT_DBDC +/*----------------------------------------------------------------------------*/ +/*! + * @brief Init DBDC + * + * @param (none) + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void cnmInitDbdcSetting(IN struct ADAPTER *prAdapter) +{ + struct CNM_OPMODE_BSS_REQ *prOpModeReq; + uint8_t ucBssLoopIndex; + + DBDC_SET_WMMBAND_FW_AUTO_DEFAULT(); + g_rDbdcInfo.fgHasSentCmd = FALSE; + g_rDbdcInfo.fgPostpondEnterAG = FALSE; + g_rDbdcInfo.fgPostpondLeaveAG = FALSE; + g_rDbdcInfo.rPeivilegeLockTime = 0; + + /* Parameter decision */ + switch (prAdapter->rWifiVar.eDbdcMode) { + case ENUM_DBDC_MODE_DISABLED: + cnmUpdateDbdcSetting(prAdapter, FALSE); + break; + + case ENUM_DBDC_MODE_DYNAMIC: + g_rDbdcInfo.eDbdcFsmCurrState = + ENUM_DBDC_FSM_STATE_DISABLE_IDLE; + g_rDbdcInfo.eDbdcFsmPrevState = + ENUM_DBDC_FSM_STATE_DISABLE_IDLE; + g_rDbdcInfo.eDbdcFsmNextState = + ENUM_DBDC_FSM_STATE_DISABLE_IDLE; + + cnmTimerInitTimer(prAdapter, + &g_rDbdcInfo.rDbdcGuardTimer, + (PFN_MGMT_TIMEOUT_FUNC)cnmDbdcGuardTimerCallback, + (unsigned long) NULL); + + g_rDbdcInfo.eDdbcGuardTimerType = + ENUM_DBDC_GUARD_TIMER_NONE; + g_rDbdcInfo.fgReqPrivelegeLock = FALSE; + LINK_INITIALIZE(&g_rDbdcInfo.rPendingMsgList); + g_rDbdcInfo.fgDbdcDisableOpmodeChangeDone = TRUE; + + for (ucBssLoopIndex = 0; + ucBssLoopIndex < prAdapter->ucHwBssIdNum; + ucBssLoopIndex++) + g_rDbdcInfo.eBssOpModeState[ucBssLoopIndex] = + ENUM_OPMODE_STATE_DONE; + + cnmUpdateDbdcSetting(prAdapter, FALSE); + break; + + case ENUM_DBDC_MODE_STATIC: + for (ucBssLoopIndex = 0; + ucBssLoopIndex < prAdapter->ucHwBssIdNum; + ucBssLoopIndex++) { + prOpModeReq = + &(g_arBssOpControl[ucBssLoopIndex]. + arReqPool[CNM_OPMODE_REQ_DBDC]); + prOpModeReq->fgEnable = TRUE; + prOpModeReq->ucOpRxNss = 1; + prOpModeReq->ucOpTxNss = 1; + } + cnmUpdateDbdcSetting(prAdapter, TRUE); + + /* Just resue dynamic DBDC FSM handler. */ + cnmDbdcFsmEntryFunc_ENABLE_IDLE(prAdapter); + break; + + default: + log_dbg(CNM, ERROR, "[DBDC]Incorrect DBDC mode %u\n", + prAdapter->rWifiVar.eDbdcMode); + break; + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Check A+G Condition + * + * @param (none) + * + * @return TRUE: A+G, FALSE: NOT A+G + */ +/*----------------------------------------------------------------------------*/ +static u_int8_t cnmDbdcIsAGConcurrent( + IN struct ADAPTER *prAdapter, + IN enum ENUM_BAND eRfBand_Connecting) +{ + struct BSS_INFO *prBssInfo; + uint8_t ucBssIndex; + enum ENUM_BAND eBandCompare = eRfBand_Connecting; + u_int8_t fgAGConcurrent = FALSE; + enum ENUM_BAND eBssBand[BSSID_NUM] = {BAND_NULL}; + + for (ucBssIndex = 0; + ucBssIndex < prAdapter->ucHwBssIdNum; ucBssIndex++) { + + prBssInfo = prAdapter->aprBssInfo[ucBssIndex]; + + if (IS_BSS_NOT_ALIVE(prAdapter, prBssInfo)) + continue; + + if (prBssInfo->eBand != BAND_2G4 + && prBssInfo->eBand != BAND_5G) + continue; + + eBssBand[ucBssIndex] = prBssInfo->eBand; + + if (eBandCompare != BAND_2G4 && eBandCompare != BAND_5G) + eBandCompare = prBssInfo->eBand; + + if (eBandCompare != prBssInfo->eBand) + fgAGConcurrent = TRUE; /*A+G*/ + } + + log_dbg(CNM, INFO, "[DBDC] BSS AG[%u.%u.%u.%u][%u]\n", + eBssBand[BSSID_0], + eBssBand[BSSID_1], + eBssBand[BSSID_2], + eBssBand[BSSID_3], + eRfBand_Connecting); + + return fgAGConcurrent; /*NOT A+G*/ +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief MT6632 HW capability will change between BW160+NSS2 and BW80+NSS1 + * + * @param (none) + * + * @return TRUE: WAIT/WAIT FAIL/Done Success/Done Fail + */ +/*----------------------------------------------------------------------------*/ +static enum ENUM_DBDC_PROTOCOL_STATUS_T cnmDbdcOpmodeChangeAndWait( + IN struct ADAPTER *prAdapter, + IN u_int8_t fgDbdcEn) +{ + uint8_t ucBssIndex; + uint8_t ucTRxNss; + struct BSS_INFO *prBssInfo; + enum ENUM_CNM_OPMODE_REQ_STATUS eStatus; + enum ENUM_DBDC_PROTOCOL_STATUS_T eRetVar = + ENUM_DBDC_PROTOCOL_STATUS_DONE_SUCCESS; + +#define IS_BSS_CLIENT(_prBssInfo) \ +(_prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) + + /* Always there are only up to 4 (BSSID_NUM) connected BSS. */ + for (ucBssIndex = 0; + ucBssIndex < prAdapter->ucHwBssIdNum && ucBssIndex < BSSID_NUM; + ucBssIndex++) { + prBssInfo = prAdapter->aprBssInfo[ucBssIndex]; + ucTRxNss = fgDbdcEn ? + 1 : wlanGetSupportNss(prAdapter, ucBssIndex); + + if (IS_BSS_ALIVE(prAdapter, prBssInfo)) { + eStatus = cnmOpModeSetTRxNss(prAdapter, + ucBssIndex, + CNM_OPMODE_REQ_DBDC, + fgDbdcEn, + ucTRxNss, /* [DBDC] RxNss = TxNss */ + ucTRxNss); + + log_dbg(CNM, INFO, "[DBDC] BSS index[%u] to TRxNSS %u Mode:%s, status %u\n", + ucBssIndex, + ucTRxNss, + IS_BSS_CLIENT(prBssInfo) ? "Client" : "Master", + eStatus); + + switch (eStatus) { + case CNM_OPMODE_REQ_STATUS_RUNNING: + case CNM_OPMODE_REQ_STATUS_DEFER: + g_rDbdcInfo.fgDbdcDisableOpmodeChangeDone + = FALSE; + g_rDbdcInfo.eBssOpModeState[ucBssIndex] + = ENUM_OPMODE_STATE_WAIT; + eRetVar = ENUM_DBDC_PROTOCOL_STATUS_WAIT; + + break; + + case CNM_OPMODE_REQ_STATUS_SUCCESS: + g_rDbdcInfo.eBssOpModeState[ucBssIndex] + = ENUM_OPMODE_STATE_DONE; + break; + + case CNM_OPMODE_REQ_STATUS_INVALID_PARAM: + g_rDbdcInfo.eBssOpModeState[ucBssIndex] + = ENUM_OPMODE_STATE_FAIL; + +#define __SUCCESS__ ENUM_DBDC_PROTOCOL_STATUS_DONE_SUCCESS +#define __FAIL__ ENUM_DBDC_PROTOCOL_STATUS_DONE_FAIL + if (eRetVar == __SUCCESS__) + eRetVar = __FAIL__; +#undef __SUCCESS__ +#undef __FAIL__ + + break; + + default: + ASSERT(0); + break; + } + } else { + /* When DBDC is enabled, we limit all BSSes' OpTRxNss. + * Use the same API to update control table for + * inactive BSS. + */ + cnmOpModeSetTRxNss(prAdapter, + ucBssIndex, + CNM_OPMODE_REQ_DBDC, + fgDbdcEn, + ucTRxNss, /* [DBDC] RxNss = TxNss */ + ucTRxNss); + g_rDbdcInfo.eBssOpModeState[ucBssIndex] + = ENUM_OPMODE_STATE_DONE; + } + } + + return eRetVar; +} + + +void cnmDbdcOpModeChangeDoneCallback( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN bool fgSuccess) +{ + uint8_t ucBssLoopIndex; + bool fgIsAllActionFrameSuccess = true; + + if (fgSuccess) + g_rDbdcInfo.eBssOpModeState[ucBssIndex] = + ENUM_OPMODE_STATE_DONE; + else + g_rDbdcInfo.eBssOpModeState[ucBssIndex] = + ENUM_OPMODE_STATE_FAIL; + + log_dbg(CNM, INFO, "[DBDC] OPMODE STATE [%u/%u/%u/%u]\n", + g_rDbdcInfo.eBssOpModeState[BSSID_0], + g_rDbdcInfo.eBssOpModeState[BSSID_1], + g_rDbdcInfo.eBssOpModeState[BSSID_2], + g_rDbdcInfo.eBssOpModeState[BSSID_3]); + + for (ucBssLoopIndex = 0; + ucBssLoopIndex < prAdapter->ucHwBssIdNum; + ucBssLoopIndex++) { + + if (g_rDbdcInfo.eBssOpModeState[ucBssLoopIndex] == + ENUM_OPMODE_STATE_WAIT) + return; + + if (g_rDbdcInfo.eBssOpModeState[ucBssLoopIndex] == + ENUM_OPMODE_STATE_FAIL && + fgIsAllActionFrameSuccess == true) { + /* Some OP mode change FAIL */ + fgIsAllActionFrameSuccess = false; + } + } + + if (!g_rDbdcInfo.fgDbdcDisableOpmodeChangeDone) { + if (fgIsAllActionFrameSuccess) { + DBDC_FSM_EVENT_HANDLER(prAdapter, + DBDC_FSM_EVENT_ACTION_FRAME_ALL_SUCCESS); + } else { + DBDC_FSM_EVENT_HANDLER(prAdapter, + DBDC_FSM_EVENT_ACTION_FRAME_SOME_FAIL); + } + + g_rDbdcInfo.fgDbdcDisableOpmodeChangeDone = true; + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Send DBDC Enable/Disable command to FW + * + * @param (none) + * + * @return (uint32_t) + */ +/*----------------------------------------------------------------------------*/ +uint32_t cnmUpdateDbdcSetting(IN struct ADAPTER *prAdapter, + IN u_int8_t fgDbdcEn) +{ + struct CMD_DBDC_SETTING rDbdcSetting; + struct CMD_DBDC_SETTING *prCmdBody; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + + log_dbg(CNM, INFO, "[DBDC] %s\n", + fgDbdcEn ? "Enable" : "Disable"); + + /* Send event to FW */ + prCmdBody = (struct CMD_DBDC_SETTING *)&rDbdcSetting; + + kalMemZero(prCmdBody, sizeof(struct CMD_DBDC_SETTING)); + + prCmdBody->ucDbdcEn = fgDbdcEn; + + /* Parameter decision */ +#if (CFG_HW_WMM_BY_BSS == 1) + if (fgDbdcEn) { + u_int8_t ucWmmSetBitmapPerBSS; + struct BSS_INFO *prBssInfo; + u_int8_t ucBssIndex; + /* + * As DBDC enabled, for BSS use 2.4g Band, assign related + * WmmGroupSet bitmask to 1. + * This is used to indicate the WmmGroupSet is associated + * to Band#1 (otherwise, use for band#0) + */ + for (ucBssIndex = 0; ucBssIndex < prAdapter->ucHwBssIdNum; + ucBssIndex++) { + prBssInfo = prAdapter->aprBssInfo[ucBssIndex]; + + if (!prBssInfo || prBssInfo->fgIsInUse == FALSE) + continue; + + if (prBssInfo->eBand == BAND_2G4) { + ucWmmSetBitmapPerBSS = prBssInfo->ucWmmQueSet; + prCmdBody->ucWmmBandBitmap |= + BIT(ucWmmSetBitmapPerBSS); + } + } + /* For P2P Device, we force it to use WMM3 */ + prBssInfo = prAdapter->aprBssInfo[P2P_DEV_BSS_INDEX]; + if (prBssInfo->eBand == BAND_2G4) + prCmdBody->ucWmmBandBitmap |= BIT(MAX_HW_WMM_INDEX); + } +#else + if (fgDbdcEn) + prCmdBody->ucWmmBandBitmap |= BIT(DBDC_2G_WMM_INDEX); +#endif + + /* FW uses ucWmmBandBitmap from driver if it does not support ver 1*/ + prCmdBody->ucCmdVer = 0x1; + prCmdBody->u2CmdLen = sizeof(struct CMD_DBDC_SETTING); + DBDC_UPDATE_CMD_WMMBAND_FW_AUTO(prCmdBody); + + if (g_rDbdcInfo.fgHasSentCmd == TRUE) + log_dbg(CNM, WARN, "Not event came back for DBDC\n"); + + g_rDbdcInfo.fgHasSentCmd = TRUE; + g_rDbdcInfo.fgCmdEn = fgDbdcEn; + + rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ + CMD_ID_SET_DBDC_PARMS, /* ucCID */ + TRUE, /* fgSetQuery */ + FALSE, /* fgNeedResp */ + FALSE, /* fgIsOid */ + NULL, /* pfCmdDoneHandler */ + NULL, /* pfCmdTimeoutHandler */ + + /* u4SetQueryInfoLen */ + sizeof(struct CMD_DBDC_SETTING), + + /* pucInfoBuffer */ + (uint8_t *)prCmdBody, + + NULL, /* pvSetQueryBuffer */ + 0 /* u4SetQueryBufferLen */); + + if (rStatus != WLAN_STATUS_PENDING) + DBGLOG(CNM, WARN, + "cnmUpdateDbdcSetting set cmd fail %d\n", rStatus); + + return rStatus; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief DBDC FSM Entry + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +static void +cnmDbdcFsmSteps( + IN struct ADAPTER *prAdapter, + IN enum ENUM_DBDC_FSM_STATE_T eNextState, + IN enum ENUM_DBDC_FSM_EVENT_T eEvent) +{ + /* Do entering Next State and do its initial function. */ + g_rDbdcInfo.eDbdcFsmPrevState = g_rDbdcInfo.eDbdcFsmCurrState; + g_rDbdcInfo.eDbdcFsmCurrState = eNextState; + g_rDbdcInfo.eDbdcFsmNextState = eNextState; + + log_dbg(CNM, INFO, "[DBDC] event %d state %d->%d\n", + eEvent, + g_rDbdcInfo.eDbdcFsmPrevState, + g_rDbdcInfo.eDbdcFsmCurrState); + + if (g_rDbdcInfo.eDbdcFsmPrevState != g_rDbdcInfo.eDbdcFsmCurrState) { + /* state change, call exit function of previous state */ + if (arDdbcFsmActionTable[g_rDbdcInfo.eDbdcFsmPrevState] + .pfExitFunc) { + arDdbcFsmActionTable[g_rDbdcInfo.eDbdcFsmPrevState] + .pfExitFunc(prAdapter); + } + + /* state change, call entry function of current state */ + if (arDdbcFsmActionTable[g_rDbdcInfo.eDbdcFsmCurrState] + .pfEntryFunc) { + arDdbcFsmActionTable[g_rDbdcInfo.eDbdcFsmCurrState] + .pfEntryFunc(prAdapter); + } + } +} + +u_int8_t +cnmDBDCIsReqPeivilegeLock(void) +{ + return g_rDbdcInfo.fgReqPrivelegeLock; +} + +static void +cnmDBDCFsmActionReqPeivilegeLock(void) +{ + g_rDbdcInfo.fgReqPrivelegeLock = TRUE; + g_rDbdcInfo.rPeivilegeLockTime = kalGetTimeTick(); + log_dbg(CNM, INFO, "[DBDC] ReqPrivelege Lock!!\n"); +} + +static void +cnmDBDCFsmActionReqPeivilegeUnLock(IN struct ADAPTER *prAdapter) +{ + struct MSG_CH_REQ *prPendingMsg; + struct MSG_HDR *prMsgHdr; + + g_rDbdcInfo.fgReqPrivelegeLock = FALSE; + g_rDbdcInfo.rPeivilegeLockTime = 0; + log_dbg(CNM, INFO, "[DBDC] ReqPrivelege Unlock!!\n"); + + while (!LINK_IS_EMPTY(&g_rDbdcInfo.rPendingMsgList)) { + + LINK_REMOVE_HEAD(&g_rDbdcInfo.rPendingMsgList, prMsgHdr, + struct MSG_HDR *); + + if (prMsgHdr) { + prPendingMsg = (struct MSG_CH_REQ *)prMsgHdr; + + log_dbg(CNM, INFO, "[DBDC] ChReq: send queued REQ of BSS %u Token %u\n", + prPendingMsg->ucBssIndex, + prPendingMsg->ucTokenID); + + cnmChMngrRequestPrivilege(prAdapter, + &prPendingMsg->rMsgHdr); + } else { + ASSERT(0); + } + } +} + +static void +cnmDbdcFsmEntryFunc_DISABLE_IDLE(IN struct ADAPTER *prAdapter) +{ + uint8_t ucWmmIndex; + uint8_t ucBssIndex; + struct CNM_OPMODE_BSS_CONTROL_T *prBssOpCtrl; + + if (cnmDBDCIsReqPeivilegeLock()) { + cnmDBDCFsmActionReqPeivilegeUnLock(prAdapter); + } + + for (ucBssIndex = 0; ucBssIndex < prAdapter->ucHwBssIdNum; + ucBssIndex++) { + prBssOpCtrl = &(g_arBssOpControl[ucBssIndex]); + prBssOpCtrl->rRunning.fgIsRunning = false; + prBssOpCtrl->arReqPool[CNM_OPMODE_REQ_DBDC].fgEnable = false; + } + + for (ucWmmIndex = 0; ucWmmIndex < prAdapter->ucWmmSetNum; + ucWmmIndex++) { + cnmWmmQuotaSetMaxQuota( + prAdapter, + ucWmmIndex, + CNM_WMM_REQ_DBDC, + false, + 0 /* don't care */); + } +} + +static void +cnmDbdcFsmEntryFunc_WAIT_PROTOCOL_ENABLE(IN struct ADAPTER *prAdapter) +{ + if (!cnmDBDCIsReqPeivilegeLock()) + cnmDBDCFsmActionReqPeivilegeLock(); +} + +static void +cnmDbdcFsmEntryFunc_WAIT_HW_ENABLE(IN struct ADAPTER *prAdapter) +{ + uint32_t rStatus; + + if (!cnmDBDCIsReqPeivilegeLock()) + cnmDBDCFsmActionReqPeivilegeLock(); + + rStatus = cnmUpdateDbdcSetting(prAdapter, TRUE); + + if (rStatus != WLAN_STATUS_PENDING) { + cnmDBDCFsmActionReqPeivilegeUnLock(prAdapter); + DBDC_FSM_EVENT_HANDLER(prAdapter, + DBDC_FSM_EVENT_ERR); + } +} + +static void +cnmDbdcFsmEntryFunc_ENABLE_GUARD(IN struct ADAPTER *prAdapter) +{ + if (timerPendingTimer(&g_rDbdcInfo.rDbdcGuardTimer)) { + log_dbg(CNM, WARN, + "[DBDC] Guard Timer type %u should not exist, stop it\n", + g_rDbdcInfo.eDdbcGuardTimerType); + cnmTimerStopTimer(prAdapter, + &g_rDbdcInfo.rDbdcGuardTimer); + g_rDbdcInfo.eDdbcGuardTimerType = + ENUM_DBDC_GUARD_TIMER_NONE; + } + DBDC_SET_GUARD_TIME(prAdapter, DBDC_ENABLE_GUARD_TIME); +} + +static void +cnmDbdcFsmEntryFunc_ENABLE_IDLE( + IN struct ADAPTER *prAdapter +) +{ + uint8_t ucWmmIndex; + + for (ucWmmIndex = 0; ucWmmIndex < prAdapter->ucWmmSetNum; + ucWmmIndex++) { + cnmWmmQuotaSetMaxQuota( + prAdapter, + ucWmmIndex, + CNM_WMM_REQ_DBDC, + true, + DBDC_WMM_TX_QUOTA); + } +} + + +static void +cnmDbdcFsmEntryFunc_WAIT_HW_DISABLE(IN struct ADAPTER *prAdapter) +{ + uint32_t rStatus; + +#if (CFG_SUPPORT_DBDC_NO_BLOCKING_OPMODE) + if (!cnmDBDCIsReqPeivilegeLock()) + cnmDBDCFsmActionReqPeivilegeLock(); +#endif + + rStatus = cnmUpdateDbdcSetting(prAdapter, FALSE); + + if (rStatus != WLAN_STATUS_PENDING) { + cnmDBDCFsmActionReqPeivilegeUnLock(prAdapter); + DBDC_FSM_EVENT_HANDLER(prAdapter, + DBDC_FSM_EVENT_ERR); + } +} + +static void +cnmDbdcFsmEntryFunc_DISABLE_GUARD(IN struct ADAPTER *prAdapter) +{ + /* Do nothing if we will enter A+G immediately */ + if (g_rDbdcInfo.fgPostpondEnterAG) + return; + + if (timerPendingTimer(&g_rDbdcInfo.rDbdcGuardTimer)) { + log_dbg(CNM, WARN, + "[DBDC] Guard Timer type %u should not exist, stop it\n", + g_rDbdcInfo.eDdbcGuardTimerType); + cnmTimerStopTimer(prAdapter, + &g_rDbdcInfo.rDbdcGuardTimer); + g_rDbdcInfo.eDdbcGuardTimerType = + ENUM_DBDC_GUARD_TIMER_NONE; + } + DBDC_SET_GUARD_TIME(prAdapter, DBDC_DISABLE_GUARD_TIME); + + cnmDbdcOpmodeChangeAndWait(prAdapter, FALSE); +} + +static void +cnmDbdcFsmEventHandler_DISABLE_IDLE( + IN struct ADAPTER *prAdapter, + IN enum ENUM_DBDC_FSM_EVENT_T eEvent) +{ + switch (eEvent) { + case DBDC_FSM_EVENT_BSS_DISCONNECT_LEAVE_AG: + /* Do Nothing */ + break; + + case DBDC_FSM_EVENT_BSS_CONNECTING_ENTER_AG: + /* Enable DBDC */ + switch (cnmDbdcOpmodeChangeAndWait(prAdapter, TRUE)) { + case ENUM_DBDC_PROTOCOL_STATUS_WAIT: + g_rDbdcInfo.eDbdcFsmNextState = + ENUM_DBDC_FSM_STATE_WAIT_PROTOCOL_ENABLE; + break; + + case ENUM_DBDC_PROTOCOL_STATUS_DONE_SUCCESS: + g_rDbdcInfo.eDbdcFsmNextState = + ENUM_DBDC_FSM_STATE_WAIT_HW_ENABLE; + break; + + case ENUM_DBDC_PROTOCOL_STATUS_DONE_FAIL: +#if (CFG_SUPPORT_DBDC_NO_BLOCKING_OPMODE) + log_dbg(CNM, WARN, + "[DBDC] OPMode Fail, ForceEn at state %d\n", + g_rDbdcInfo.eDbdcFsmCurrState); + g_rDbdcInfo.eDbdcFsmNextState = + ENUM_DBDC_FSM_STATE_WAIT_HW_ENABLE; + break; +#endif + + default: + break; + } + break; + + case DBDC_FSM_EVENT_SWITCH_GUARD_TIME_TO: + case DBDC_FSM_EVENT_DISABLE_COUNT_DOWN_TO: + case DBDC_FSM_EVENT_ACTION_FRAME_ALL_SUCCESS: + case DBDC_FSM_EVENT_ACTION_FRAME_SOME_FAIL: + case DBDC_FSM_EVENT_DBDC_HW_SWITCH_DONE: + /* ABNORMAL CASE*/ + DBDC_FSM_MSG_WRONG_EVT(eEvent); + break; + default: + /* WRONG EVENT */ + DBDC_FSM_MSG_ERROR_EVT(eEvent); + break; + } + + cnmDbdcFsmSteps(prAdapter, g_rDbdcInfo.eDbdcFsmNextState, eEvent); +} + +static void +cnmDbdcFsmEventHandler_WAIT_PROTOCOL_ENABLE( + IN struct ADAPTER *prAdapter, + IN enum ENUM_DBDC_FSM_EVENT_T eEvent) +{ + switch (eEvent) { + case DBDC_FSM_EVENT_BSS_DISCONNECT_LEAVE_AG: + /* Stop Enabling DBDC */ + g_rDbdcInfo.eDbdcFsmNextState = + ENUM_DBDC_FSM_STATE_DISABLE_IDLE; + break; + + case DBDC_FSM_EVENT_BSS_CONNECTING_ENTER_AG: + /* IGNORE */ + break; + + case DBDC_FSM_EVENT_SWITCH_GUARD_TIME_TO: + case DBDC_FSM_EVENT_DISABLE_COUNT_DOWN_TO: + /* ABNORMAL CASE*/ + DBDC_FSM_MSG_WRONG_EVT(eEvent); + break; + + case DBDC_FSM_EVENT_ACTION_FRAME_ALL_SUCCESS: + g_rDbdcInfo.eDbdcFsmNextState = + ENUM_DBDC_FSM_STATE_WAIT_HW_ENABLE; + break; + + case DBDC_FSM_EVENT_ACTION_FRAME_SOME_FAIL: +#if (CFG_SUPPORT_DBDC_NO_BLOCKING_OPMODE) + g_rDbdcInfo.eDbdcFsmNextState = + ENUM_DBDC_FSM_STATE_WAIT_HW_ENABLE; + log_dbg(CNM, WARN, + "[DBDC] OPMode Fail, ForceEn at state %d\n", + g_rDbdcInfo.eDbdcFsmCurrState); +#else + /* Not recover anything. Stop Enable DBDC */ + g_rDbdcInfo.eDbdcFsmNextState = + ENUM_DBDC_FSM_STATE_DISABLE_IDLE; +#endif + + break; + + case DBDC_FSM_EVENT_DBDC_HW_SWITCH_DONE: + /* ABNORMAL CASE*/ + DBDC_FSM_MSG_WRONG_EVT(eEvent); + break; + + default: + /* WRONG EVENT */ + DBDC_FSM_MSG_ERROR_EVT(eEvent); + break; + } + + cnmDbdcFsmSteps(prAdapter, g_rDbdcInfo.eDbdcFsmNextState, eEvent); +} + +static void +cnmDbdcFsmEventHandler_WAIT_HW_ENABLE( + IN struct ADAPTER *prAdapter, + IN enum ENUM_DBDC_FSM_EVENT_T eEvent) +{ + /* Prepare to Enable DBDC */ + + switch (eEvent) { + case DBDC_FSM_EVENT_BSS_DISCONNECT_LEAVE_AG: + g_rDbdcInfo.fgPostpondLeaveAG = TRUE; + break; + + case DBDC_FSM_EVENT_BSS_CONNECTING_ENTER_AG: + g_rDbdcInfo.fgPostpondLeaveAG = FALSE; + break; + + case DBDC_FSM_EVENT_SWITCH_GUARD_TIME_TO: + case DBDC_FSM_EVENT_DISABLE_COUNT_DOWN_TO: + case DBDC_FSM_EVENT_ACTION_FRAME_ALL_SUCCESS: + case DBDC_FSM_EVENT_ACTION_FRAME_SOME_FAIL: + /* ABNORMAL CASE*/ + DBDC_FSM_MSG_WRONG_EVT(eEvent); + break; + + case DBDC_FSM_EVENT_DBDC_HW_SWITCH_DONE: + g_rDbdcInfo.eDbdcFsmNextState = + ENUM_DBDC_FSM_STATE_ENABLE_GUARD; + break; + + case DBDC_FSM_EVENT_ERR: + g_rDbdcInfo.eDbdcFsmNextState = + ENUM_DBDC_FSM_STATE_DISABLE_IDLE; + g_rDbdcInfo.fgPostpondLeaveAG = FALSE; + break; + + default: + /* WRONG EVENT */ + DBDC_FSM_MSG_ERROR_EVT(eEvent); + break; + } + + cnmDbdcFsmSteps(prAdapter, g_rDbdcInfo.eDbdcFsmNextState, eEvent); + + /* Leave A+G immediately */ + if (eEvent == DBDC_FSM_EVENT_DBDC_HW_SWITCH_DONE && + g_rDbdcInfo.fgPostpondLeaveAG) { + DBDC_FSM_EVENT_HANDLER(prAdapter, + DBDC_FSM_EVENT_BSS_DISCONNECT_LEAVE_AG); + + g_rDbdcInfo.fgPostpondLeaveAG = FALSE; + } +} + + +static void +cnmDbdcFsmEventHandler_ENABLE_GUARD( + IN struct ADAPTER *prAdapter, + IN enum ENUM_DBDC_FSM_EVENT_T eEvent) +{ + switch (eEvent) { + case DBDC_FSM_EVENT_BSS_DISCONNECT_LEAVE_AG: + /* stop guard timer */ + if (timerPendingTimer(&g_rDbdcInfo.rDbdcGuardTimer)) { + log_dbg(CNM, WARN, "[DBDC] Stop Guard Timer type %u\n", + g_rDbdcInfo.eDdbcGuardTimerType); + cnmTimerStopTimer(prAdapter, + &g_rDbdcInfo.rDbdcGuardTimer); + g_rDbdcInfo.eDdbcGuardTimerType = + ENUM_DBDC_GUARD_TIMER_NONE; + } + /* directly enter HW disable state */ + if (!cnmDbdcIsAGConcurrent(prAdapter, BAND_NULL)) + g_rDbdcInfo.eDbdcFsmNextState = + ENUM_DBDC_FSM_STATE_WAIT_HW_DISABLE; + break; + + case DBDC_FSM_EVENT_BSS_CONNECTING_ENTER_AG: + /* IGNORE */ + break; + + case DBDC_FSM_EVENT_SWITCH_GUARD_TIME_TO: + /* Exit DBDC if non A+G */ + if (!cnmDbdcIsAGConcurrent(prAdapter, BAND_NULL)) { + g_rDbdcInfo.eDbdcFsmNextState = + ENUM_DBDC_FSM_STATE_WAIT_HW_DISABLE; + } else { + g_rDbdcInfo.eDbdcFsmNextState = + ENUM_DBDC_FSM_STATE_ENABLE_IDLE; + } + break; + + case DBDC_FSM_EVENT_DISABLE_COUNT_DOWN_TO: + case DBDC_FSM_EVENT_ACTION_FRAME_ALL_SUCCESS: + case DBDC_FSM_EVENT_ACTION_FRAME_SOME_FAIL: + case DBDC_FSM_EVENT_DBDC_HW_SWITCH_DONE: + /* ABNORMAL CASE*/ + DBDC_FSM_MSG_WRONG_EVT(eEvent); + break; + + default: + /* WRONG EVENT */ + DBDC_FSM_MSG_ERROR_EVT(eEvent); + break; + } + + cnmDbdcFsmSteps(prAdapter, g_rDbdcInfo.eDbdcFsmNextState, eEvent); +} + +static void +cnmDbdcFsmEventHandler_ENABLE_IDLE( + IN struct ADAPTER *prAdapter, + IN enum ENUM_DBDC_FSM_EVENT_T eEvent) +{ + switch (eEvent) { + case DBDC_FSM_EVENT_BSS_DISCONNECT_LEAVE_AG: + /* stop guard timer */ + if (timerPendingTimer(&g_rDbdcInfo.rDbdcGuardTimer)) { + log_dbg(CNM, WARN, "[DBDC] Guard Timer type %u should not exist, stop it\n", + g_rDbdcInfo.eDdbcGuardTimerType); + cnmTimerStopTimer(prAdapter, + &g_rDbdcInfo.rDbdcGuardTimer); + g_rDbdcInfo.eDdbcGuardTimerType = + ENUM_DBDC_GUARD_TIMER_NONE; + } + /* directly enter HW disable state */ + if (!cnmDbdcIsAGConcurrent(prAdapter, BAND_NULL)) + g_rDbdcInfo.eDbdcFsmNextState = + ENUM_DBDC_FSM_STATE_WAIT_HW_DISABLE; + break; + + case DBDC_FSM_EVENT_BSS_CONNECTING_ENTER_AG: + /* cancel DBDC disable countdown if exist */ + if (timerPendingTimer(&g_rDbdcInfo.rDbdcGuardTimer) && + g_rDbdcInfo.eDdbcGuardTimerType == + ENUM_DBDC_GUARD_TIMER_DISABLE_COUNT_DOWN) { + cnmTimerStopTimer(prAdapter, + &g_rDbdcInfo.rDbdcGuardTimer); + } + break; + + case DBDC_FSM_EVENT_SWITCH_GUARD_TIME_TO: + /* ABNORMAL CASE*/ + DBDC_FSM_MSG_WRONG_EVT(eEvent); + break; + + case DBDC_FSM_EVENT_DISABLE_COUNT_DOWN_TO: + if (!cnmDbdcIsAGConcurrent(prAdapter, BAND_NULL)) + g_rDbdcInfo.eDbdcFsmNextState = + ENUM_DBDC_FSM_STATE_WAIT_HW_DISABLE; + break; + + case DBDC_FSM_EVENT_ACTION_FRAME_ALL_SUCCESS: + case DBDC_FSM_EVENT_ACTION_FRAME_SOME_FAIL: + case DBDC_FSM_EVENT_DBDC_HW_SWITCH_DONE: + /* ABNORMAL CASE*/ + DBDC_FSM_MSG_WRONG_EVT(eEvent); + break; + + default: + /* WRONG EVENT */ + DBDC_FSM_MSG_ERROR_EVT(eEvent); + break; + } + + cnmDbdcFsmSteps(prAdapter, g_rDbdcInfo.eDbdcFsmNextState, eEvent); +} + +static void +cnmDbdcFsmEventHandler_WAIT_HW_DISABLE( + IN struct ADAPTER *prAdapter, + IN enum ENUM_DBDC_FSM_EVENT_T eEvent) +{ + switch (eEvent) { + case DBDC_FSM_EVENT_BSS_DISCONNECT_LEAVE_AG: + g_rDbdcInfo.fgPostpondEnterAG = FALSE; + break; + + case DBDC_FSM_EVENT_BSS_CONNECTING_ENTER_AG: + g_rDbdcInfo.fgPostpondEnterAG = TRUE; + break; + + case DBDC_FSM_EVENT_SWITCH_GUARD_TIME_TO: + case DBDC_FSM_EVENT_DISABLE_COUNT_DOWN_TO: + case DBDC_FSM_EVENT_ACTION_FRAME_ALL_SUCCESS: + case DBDC_FSM_EVENT_ACTION_FRAME_SOME_FAIL: + /* ABNORMAL CASE*/ + DBDC_FSM_MSG_WRONG_EVT(eEvent); + break; + + case DBDC_FSM_EVENT_DBDC_HW_SWITCH_DONE: + g_rDbdcInfo.eDbdcFsmNextState = + ENUM_DBDC_FSM_STATE_DISABLE_GUARD; + break; + + case DBDC_FSM_EVENT_ERR: + g_rDbdcInfo.eDbdcFsmNextState = + ENUM_DBDC_FSM_STATE_ENABLE_IDLE; + g_rDbdcInfo.fgPostpondEnterAG = FALSE; + break; + + default: + /* WRONG EVENT */ + DBDC_FSM_MSG_ERROR_EVT(eEvent); + break; + } + + cnmDbdcFsmSteps(prAdapter, g_rDbdcInfo.eDbdcFsmNextState, eEvent); + + /* Enter A+G immediately */ + if (eEvent == DBDC_FSM_EVENT_DBDC_HW_SWITCH_DONE && + g_rDbdcInfo.fgPostpondEnterAG) { + DBDC_FSM_EVENT_HANDLER(prAdapter, + DBDC_FSM_EVENT_BSS_CONNECTING_ENTER_AG); + + g_rDbdcInfo.fgPostpondEnterAG = FALSE; + } +} + +static void +cnmDbdcFsmEventHandler_DISABLE_GUARD( + IN struct ADAPTER *prAdapter, + IN enum ENUM_DBDC_FSM_EVENT_T eEvent) +{ + switch (eEvent) { + case DBDC_FSM_EVENT_BSS_DISCONNECT_LEAVE_AG: + /* IGNORE */ + break; + + case DBDC_FSM_EVENT_BSS_CONNECTING_ENTER_AG: + /* Enable DBDC */ + switch (cnmDbdcOpmodeChangeAndWait(prAdapter, TRUE)) { + case ENUM_DBDC_PROTOCOL_STATUS_WAIT: + g_rDbdcInfo.eDbdcFsmNextState = + ENUM_DBDC_FSM_STATE_WAIT_PROTOCOL_ENABLE; + break; + + case ENUM_DBDC_PROTOCOL_STATUS_DONE_SUCCESS: + g_rDbdcInfo.eDbdcFsmNextState = + ENUM_DBDC_FSM_STATE_WAIT_HW_ENABLE; + break; + + case ENUM_DBDC_PROTOCOL_STATUS_DONE_FAIL: +#if (CFG_SUPPORT_DBDC_NO_BLOCKING_OPMODE) + log_dbg(CNM, WARN, + "[DBDC] OPMode Fail, ForceEn at state %d\n", + g_rDbdcInfo.eDbdcFsmCurrState); + g_rDbdcInfo.eDbdcFsmNextState = + ENUM_DBDC_FSM_STATE_WAIT_HW_ENABLE; + break; +#endif + + default: + break; + } + break; + + case DBDC_FSM_EVENT_SWITCH_GUARD_TIME_TO: + +#define __PRO_ENABLE__ ENUM_DBDC_FSM_STATE_WAIT_PROTOCOL_ENABLE +#define __PRO_DISABLE__ ENUM_DBDC_FSM_STATE_WAIT_PROTOCOL_DISABLE +#define __HW_ENABLE__ ENUM_DBDC_FSM_STATE_WAIT_HW_ENABLE +#define __DISABLE__ ENUM_DBDC_FSM_STATE_DISABLE_IDLE +#define __STAT_WAIT__ ENUM_DBDC_PROTOCOL_STATUS_WAIT + + if (g_rDbdcInfo.fgDbdcDisableOpmodeChangeDone) { + if (cnmDbdcIsAGConcurrent(prAdapter, BAND_NULL)) { + switch (cnmDbdcOpmodeChangeAndWait( + prAdapter, TRUE)) { + case ENUM_DBDC_PROTOCOL_STATUS_WAIT: + g_rDbdcInfo.eDbdcFsmNextState = + __PRO_ENABLE__; + break; + case ENUM_DBDC_PROTOCOL_STATUS_DONE_SUCCESS: + g_rDbdcInfo.eDbdcFsmNextState = + __HW_ENABLE__; + break; + case ENUM_DBDC_PROTOCOL_STATUS_DONE_FAIL: +#if (CFG_SUPPORT_DBDC_NO_BLOCKING_OPMODE) + g_rDbdcInfo.eDbdcFsmNextState = + __HW_ENABLE__; + log_dbg(CNM, WARN, + "[DBDC] OPMode Fail, ForceEn at state %d\n", + g_rDbdcInfo.eDbdcFsmCurrState); +#else + if (cnmDbdcOpmodeChangeAndWait( + prAdapter, FALSE) + == __STAT_WAIT__) + g_rDbdcInfo.eDbdcFsmNextState = + __PRO_DISABLE__; + else + g_rDbdcInfo.eDbdcFsmNextState = + __DISABLE__; +#endif + break; + default: + break; + } + } else { + g_rDbdcInfo.eDbdcFsmNextState = + __DISABLE__; + } + } else { + g_rDbdcInfo.eDbdcFsmNextState = + __PRO_DISABLE__; + } + +#undef __PRO_ENABLE__ +#undef __PRO_DISABLE__ +#undef __HW_ENABLE__ +#undef __DISABLE__ +#undef __STAT_WAIT__ + + break; + + case DBDC_FSM_EVENT_DISABLE_COUNT_DOWN_TO: + /* ABNORMAL CASE */ + DBDC_FSM_MSG_WRONG_EVT(eEvent); + break; + + case DBDC_FSM_EVENT_ACTION_FRAME_ALL_SUCCESS: + case DBDC_FSM_EVENT_ACTION_FRAME_SOME_FAIL: + /* Do nothing */ + break; + + case DBDC_FSM_EVENT_DBDC_HW_SWITCH_DONE: + /* ABNORMAL CASE */ + DBDC_FSM_MSG_WRONG_EVT(eEvent); + break; + + default: + /* WRONG EVENT */ + DBDC_FSM_MSG_ERROR_EVT(eEvent); + break; + } + + cnmDbdcFsmSteps(prAdapter, g_rDbdcInfo.eDbdcFsmNextState, eEvent); +} + +static void +cnmDbdcFsmEventHandler_WAIT_PROTOCOL_DISABLE( + IN struct ADAPTER *prAdapter, + IN enum ENUM_DBDC_FSM_EVENT_T eEvent) +{ + /* Prepare to Enable DBDC */ + + switch (eEvent) { + case DBDC_FSM_EVENT_BSS_DISCONNECT_LEAVE_AG: + /* Return to idle state to prevent getting stuck */ + g_rDbdcInfo.eDbdcFsmNextState = + ENUM_DBDC_FSM_STATE_DISABLE_IDLE; + break; + case DBDC_FSM_EVENT_BSS_CONNECTING_ENTER_AG: + /* IGNORE */ + break; + + case DBDC_FSM_EVENT_SWITCH_GUARD_TIME_TO: + case DBDC_FSM_EVENT_DISABLE_COUNT_DOWN_TO: + /* ABNORMAL CASE*/ + DBDC_FSM_MSG_WRONG_EVT(eEvent); + break; + +#define __PRO_ENABLE__ ENUM_DBDC_FSM_STATE_WAIT_PROTOCOL_ENABLE + + case DBDC_FSM_EVENT_ACTION_FRAME_ALL_SUCCESS: + case DBDC_FSM_EVENT_ACTION_FRAME_SOME_FAIL: + if (cnmDbdcIsAGConcurrent(prAdapter, BAND_NULL)) { + switch (cnmDbdcOpmodeChangeAndWait(prAdapter, TRUE)) { + case ENUM_DBDC_PROTOCOL_STATUS_WAIT: + g_rDbdcInfo.eDbdcFsmNextState = + __PRO_ENABLE__; + break; + case ENUM_DBDC_PROTOCOL_STATUS_DONE_SUCCESS: + g_rDbdcInfo.eDbdcFsmNextState = + ENUM_DBDC_FSM_STATE_WAIT_HW_ENABLE; + break; + case ENUM_DBDC_PROTOCOL_STATUS_DONE_FAIL: +#if (CFG_SUPPORT_DBDC_NO_BLOCKING_OPMODE) + g_rDbdcInfo.eDbdcFsmNextState = + ENUM_DBDC_FSM_STATE_WAIT_HW_ENABLE; + log_dbg(CNM, WARN, + "[DBDC] OPMode Fail, ForceEn at state %d\n", + g_rDbdcInfo.eDbdcFsmCurrState); +#else + g_rDbdcInfo.eDbdcFsmNextState = + ENUM_DBDC_FSM_STATE_DISABLE_IDLE; +#endif + break; + default: + break; + } + } else + g_rDbdcInfo.eDbdcFsmNextState = + ENUM_DBDC_FSM_STATE_DISABLE_IDLE; + break; + +#undef __PRO_ENABLE__ + + case DBDC_FSM_EVENT_DBDC_HW_SWITCH_DONE: + /* ABNORMAL CASE*/ + DBDC_FSM_MSG_WRONG_EVT(eEvent); + break; + + default: + /* WRONG EVENT */ + DBDC_FSM_MSG_ERROR_EVT(eEvent); + break; + } + + cnmDbdcFsmSteps(prAdapter, g_rDbdcInfo.eDbdcFsmNextState, eEvent); +} + +static void +cnmDbdcFsmExitFunc_WAIT_HW_ENABLE( + IN struct ADAPTER *prAdapter) +{ + cnmDBDCFsmActionReqPeivilegeUnLock(prAdapter); +} + +static void +cnmDbdcFsmExitFunc_WAIT_HW_DISABLE( + IN struct ADAPTER *prAdapter) +{ + /* Do not release privilege lock if we will enter A+G immediately */ + if (!g_rDbdcInfo.fgPostpondEnterAG) + cnmDBDCFsmActionReqPeivilegeUnLock(prAdapter); +} + + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Get maximum bandwidth capability with considering DBDC mode + * + * @param (none) + * + * @return + */ +/*----------------------------------------------------------------------------*/ +uint8_t cnmGetDbdcBwCapability(IN struct ADAPTER + *prAdapter, + IN uint8_t ucBssIndex) +{ + uint8_t ucMaxBw = MAX_BW_20MHZ; + + ucMaxBw = cnmGetBssMaxBw(prAdapter, ucBssIndex); + + /* Can't use BW160 when DBDC enabled */ + if (USE_DBDC_CAPABILITY() && (ucMaxBw >= MAX_BW_160MHZ)) + ucMaxBw = MAX_BW_80MHZ; + + /* TODO: BW80+80 support */ + if (ucMaxBw == MAX_BW_80_80_MHZ) + ucMaxBw = MAX_BW_80MHZ; /* VHT should default support BW80 */ + + return ucMaxBw; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Run-time check if DBDC Need enable or update guard time. + * The WmmQ is set to the correct DBDC band before connetcting. + * It could make sure the TxPath is correct after connected. + * + * @param (none) + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void cnmDbdcPreConnectionEnableDecision( + IN struct ADAPTER *prAdapter, + IN uint8_t ucChangedBssIndex, + IN enum ENUM_BAND eRfBand, + IN uint8_t ucPrimaryChannel, + IN uint8_t ucWmmQueIdx) +{ + log_dbg(CNM, INFO, "[DBDC] BSS %u Rf %u", ucChangedBssIndex, eRfBand); + + if (prAdapter->rWifiVar.eDbdcMode != ENUM_DBDC_MODE_DYNAMIC && + (prAdapter->rWifiVar.eDbdcMode != ENUM_DBDC_MODE_STATIC)) { + log_dbg(CNM, INFO, "[DBDC Debug] DBDC Mode %u Return", + prAdapter->rWifiVar.eDbdcMode); + return; + } + + if (prAdapter->rWifiVar.eDbdcMode == ENUM_DBDC_MODE_STATIC && + prAdapter->rWifiVar.fgDbDcModeEn) { + if (timerPendingTimer(&g_rDbdcInfo.rDbdcGuardTimer) && + g_rDbdcInfo.eDdbcGuardTimerType == + ENUM_DBDC_GUARD_TIMER_SWITCH_GUARD_TIME) { + /* update timer for connection retry */ + log_dbg(CNM, INFO, "[DBDC] DBDC guard time extend\n"); + cnmTimerStopTimer(prAdapter, + &g_rDbdcInfo.rDbdcGuardTimer); + cnmTimerStartTimer(prAdapter, + &g_rDbdcInfo.rDbdcGuardTimer, + DBDC_ENABLE_GUARD_TIME); + } + /* The DBDC is already ON, so renew WMM band information only */ + DBDC_SET_WMMBAND_FW_AUTO_BY_CHNL(ucPrimaryChannel, ucWmmQueIdx); + cnmUpdateDbdcSetting(prAdapter, TRUE); + return; + } + + if (timerPendingTimer(&g_rDbdcInfo.rDbdcGuardTimer) && + g_rDbdcInfo.eDdbcGuardTimerType + == ENUM_DBDC_GUARD_TIMER_SWITCH_GUARD_TIME) { + log_dbg(CNM, INFO, "[DBDC Debug] Guard Time Check"); + + if ((cnmDbdcIsAGConcurrent(prAdapter, eRfBand) && + !prAdapter->rWifiVar.fgDbDcModeEn) || + (!cnmDbdcIsAGConcurrent(prAdapter, eRfBand) && + prAdapter->rWifiVar.fgDbDcModeEn)) { + /* cancel Guard Time and change DBDC mode */ + cnmTimerStopTimer(prAdapter, + &g_rDbdcInfo.rDbdcGuardTimer); + g_rDbdcInfo.eDdbcGuardTimerType = + ENUM_DBDC_GUARD_TIMER_NONE; + } else { + log_dbg(CNM, INFO, "[DBDC Debug] Guard Time Return"); + return; + } + } + + if (eRfBand != BAND_2G4 && eRfBand != BAND_5G) { + log_dbg(CNM, INFO, "[DBDC Debug] Wrong RF band Return"); + return; + } + + if (cnmDbdcIsAGConcurrent(prAdapter, eRfBand)) { + DBDC_SET_WMMBAND_FW_AUTO_BY_CHNL(ucPrimaryChannel, ucWmmQueIdx); + DBDC_FSM_EVENT_HANDLER(prAdapter, + DBDC_FSM_EVENT_BSS_CONNECTING_ENTER_AG); + } else { + DBDC_FSM_EVENT_HANDLER(prAdapter, + DBDC_FSM_EVENT_BSS_DISCONNECT_LEAVE_AG); + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Run-time check if we need enable/disable DBDC or update guard time. + * + * @param (none) + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void cnmDbdcRuntimeCheckDecision(IN struct ADAPTER + *prAdapter, + IN uint8_t ucChangedBssIndex) +{ + bool fgIsAgConcurrent; + + log_dbg(CNM, INFO, "[DBDC Debug] BSS %u", + ucChangedBssIndex); + + /* Only allow runtime switch for dynamic DBDC */ + if (prAdapter->rWifiVar.eDbdcMode != + ENUM_DBDC_MODE_DYNAMIC) { + log_dbg(CNM, INFO, "[DBDC Debug] DBDC Mode %u Return", + prAdapter->rWifiVar.eDbdcMode); + return; + } + + /* AGConcurrent status sync with DBDC satus. Do nothing. */ + fgIsAgConcurrent = cnmDbdcIsAGConcurrent(prAdapter, BAND_NULL); + if (fgIsAgConcurrent == prAdapter->rWifiVar.fgDbDcModeEn) + return; + + /* Only need to extend in DISABLE_GUARD for connection retry. + * If AGConcurrent status changes in ENABLE_GUARD, the FSM + * will go through DISABLE_GUARD state. It could make sure + * the interval of successive OPChange is larger than 4 sec + * (DBDC_ENABLE_GUARD_TIME). + */ + if (timerPendingTimer(&g_rDbdcInfo.rDbdcGuardTimer) && + g_rDbdcInfo.eDdbcGuardTimerType == + ENUM_DBDC_GUARD_TIMER_SWITCH_GUARD_TIME) { + + if (g_rDbdcInfo.eDbdcFsmCurrState == + ENUM_DBDC_FSM_STATE_DISABLE_GUARD) { + log_dbg(CNM, INFO, + "[DBDC] DBDC guard time extend, state %d\n", + g_rDbdcInfo.eDbdcFsmCurrState); + cnmTimerStopTimer(prAdapter, + &g_rDbdcInfo.rDbdcGuardTimer); + cnmTimerStartTimer(prAdapter, + &g_rDbdcInfo.rDbdcGuardTimer, + DBDC_ENABLE_GUARD_TIME); + } else + log_dbg(CNM, INFO, + "[DBDC] DBDC guard time, state %d\n", + g_rDbdcInfo.eDbdcFsmCurrState); + return; + } + + /* After COUNT_DOWN timeout in ENABLE_IDLE state, FSM will check + * AGConcurrent status agin. + */ + if (timerPendingTimer(&g_rDbdcInfo.rDbdcGuardTimer) && + g_rDbdcInfo.eDdbcGuardTimerType == + ENUM_DBDC_GUARD_TIMER_DISABLE_COUNT_DOWN) { + log_dbg(CNM, INFO, + "[DBDC Debug] Disable Countdown Return, state %d\n", + g_rDbdcInfo.eDbdcFsmCurrState); + return; + } + + if (cnmDbdcIsAGConcurrent(prAdapter, BAND_NULL)) { + DBDC_FSM_EVENT_HANDLER(prAdapter, + DBDC_FSM_EVENT_BSS_CONNECTING_ENTER_AG); + } else + DBDC_FSM_EVENT_HANDLER(prAdapter, + DBDC_FSM_EVENT_BSS_DISCONNECT_LEAVE_AG); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief DBDC Guard Time/Countdown Callback + * + * @param (none) + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void cnmDbdcGuardTimerCallback(IN struct ADAPTER + *prAdapter, + IN unsigned long plParamPtr) +{ + log_dbg(CNM, INFO, "[DBDC Debug] Timer %u", + g_rDbdcInfo.eDdbcGuardTimerType); + + if (prAdapter->rWifiVar.eDbdcMode != + ENUM_DBDC_MODE_DYNAMIC) { + log_dbg(CNM, INFO, "[DBDC Debug] DBDC Mode %u Return", + prAdapter->rWifiVar.eDbdcMode); + return; + } + + if (g_rDbdcInfo.eDdbcGuardTimerType == + ENUM_DBDC_GUARD_TIMER_SWITCH_GUARD_TIME) { + + g_rDbdcInfo.eDdbcGuardTimerType = + ENUM_DBDC_GUARD_TIMER_NONE; + DBDC_FSM_EVENT_HANDLER(prAdapter, + DBDC_FSM_EVENT_SWITCH_GUARD_TIME_TO); + + } else if (g_rDbdcInfo.eDdbcGuardTimerType == + ENUM_DBDC_GUARD_TIMER_DISABLE_COUNT_DOWN) { + + g_rDbdcInfo.eDdbcGuardTimerType = + ENUM_DBDC_GUARD_TIMER_NONE; + DBDC_FSM_EVENT_HANDLER(prAdapter, + DBDC_FSM_EVENT_DISABLE_COUNT_DOWN_TO); + + } else + log_dbg(CNM, ERROR, "[DBDC] WRONG DBDC TO TYPE %u\n", + g_rDbdcInfo.eDdbcGuardTimerType); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief DBDC HW Switch done event + * + * @param (none) + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void cnmDbdcEventHwSwitchDone(IN struct ADAPTER + *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ + struct CMD_INFO *prCmdInfo; + u_int8_t fgDbdcEn; + + /* command response handling */ + prCmdInfo = nicGetPendingCmdInfo(prAdapter, + prEvent->ucSeqNum); + + if (prCmdInfo != NULL) { + if (prCmdInfo->pfCmdDoneHandler) + prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, + prEvent->aucBuffer); + else if (prCmdInfo->fgIsOid) + kalOidComplete(prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, + 0, WLAN_STATUS_SUCCESS); + /* return prCmdInfo */ + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + } + + /* Check DBDC state by FSM */ + if (g_rDbdcInfo.eDbdcFsmCurrState == + ENUM_DBDC_FSM_STATE_WAIT_HW_ENABLE) { + fgDbdcEn = true; + g_rDbdcInfo.fgHasSentCmd = false; + } else if (g_rDbdcInfo.eDbdcFsmCurrState == + ENUM_DBDC_FSM_STATE_WAIT_HW_DISABLE) { + fgDbdcEn = false; + g_rDbdcInfo.fgHasSentCmd = false; + } else if (g_rDbdcInfo.fgHasSentCmd == true) { + /* The "set_dbdc" test cmd may confuse original FSM. + * Besides, we do not config TxQuota for the testing cmd. + */ + log_dbg(CNM, INFO, + "[DBDC] switch event from cmd happen in state %u\n", + g_rDbdcInfo.eDbdcFsmCurrState); + g_rDbdcInfo.fgHasSentCmd = FALSE; + prAdapter->rWifiVar.fgDbDcModeEn = g_rDbdcInfo.fgCmdEn; + return; + } else { + log_dbg(CNM, ERROR, + "[DBDC] switch event happen in state %u\n", + g_rDbdcInfo.eDbdcFsmCurrState); + return; + } + + /* Change DBDC state */ + prAdapter->rWifiVar.fgDbDcModeEn = fgDbdcEn; + DBDC_FSM_EVENT_HANDLER(prAdapter, + DBDC_FSM_EVENT_DBDC_HW_SWITCH_DONE); +} + +#endif /*CFG_SUPPORT_DBDC*/ + + +enum ENUM_CNM_NETWORK_TYPE_T cnmGetBssNetworkType( + struct BSS_INFO *prBssInfo) +{ + if (prBssInfo->eNetworkType == NETWORK_TYPE_AIS) + return ENUM_CNM_NETWORK_TYPE_AIS; + else if (prBssInfo->eNetworkType == NETWORK_TYPE_P2P) { + if (prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) + return ENUM_CNM_NETWORK_TYPE_P2P_GC; + else if (prBssInfo->eCurrentOPMode == + OP_MODE_ACCESS_POINT) + return ENUM_CNM_NETWORK_TYPE_P2P_GO; + } + return ENUM_CNM_NETWORK_TYPE_OTHER; +} + +u_int8_t cnmSapIsConcurrent(IN struct ADAPTER *prAdapter) +{ + if (prAdapter) + return (prAdapter->u4P2pMode == RUNNING_P2P_AP_MODE); + else + return FALSE; +} + +u_int8_t cnmSapIsActive(IN struct ADAPTER *prAdapter) +{ + return (cnmGetSapBssInfo(prAdapter) != NULL); +} + +struct BSS_INFO *cnmGetSapBssInfo(IN struct ADAPTER *prAdapter) +{ + struct BSS_INFO *prBssInfo; + uint8_t i; + + if (!prAdapter) + return NULL; + + for (i = 0; i < prAdapter->ucHwBssIdNum; i++) { + prBssInfo = prAdapter->aprBssInfo[i]; + + if (prBssInfo && + IS_BSS_P2P(prBssInfo) && + p2pFuncIsAPMode( + prAdapter->rWifiVar.prP2PConnSettings + [prBssInfo->u4PrivateData]) && + IS_NET_PWR_STATE_ACTIVE( + prAdapter, + prBssInfo->ucBssIndex)) + return prBssInfo; + } + + return NULL; +} + +uint8_t cnmSapChannelSwitchReq(IN struct ADAPTER *prAdapter, + IN struct RF_CHANNEL_INFO *prRfChannelInfo, + IN uint8_t ucRoleIdx) +{ + struct GLUE_INFO *prGlueInfo = prAdapter->prGlueInfo; + struct GL_P2P_INFO *prGlueP2pInfo = NULL; + struct MSG_P2P_SET_NEW_CHANNEL *prP2pSetNewChannelMsg = + (struct MSG_P2P_SET_NEW_CHANNEL *) NULL; + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *) NULL; + struct P2P_CONNECTION_REQ_INFO *prP2pConnReqInfo = + (struct P2P_CONNECTION_REQ_INFO *) NULL; + uint8_t ucBssIdx = 0; + + DBGLOG(P2P, INFO, + "role(%d) c=%d b=%d opw=%d\n", + ucRoleIdx, + prRfChannelInfo->ucChannelNum, + prRfChannelInfo->eBand, + prRfChannelInfo->ucChnlBw); + + /* Free chandef buffer */ + if (!prGlueInfo) { + DBGLOG(P2P, WARN, "glue info is not active\n"); + goto error; + } + prGlueP2pInfo = prGlueInfo->prP2PInfo[ucRoleIdx]; + if (!prGlueP2pInfo) { + DBGLOG(P2P, WARN, "p2p glue info is not active\n"); + goto error; + } + if (prGlueP2pInfo->chandef != NULL) { + if (prGlueP2pInfo->chandef->chan) { + cnmMemFree(prGlueInfo->prAdapter, + prGlueP2pInfo->chandef->chan); + prGlueP2pInfo->chandef->chan = NULL; + } + cnmMemFree(prGlueInfo->prAdapter, + prGlueP2pInfo->chandef); + prGlueP2pInfo->chandef = NULL; + } + + /* Fill conn info */ + prP2pRoleFsmInfo = + P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, ucRoleIdx); + if (!prP2pRoleFsmInfo) + goto error; + prP2pConnReqInfo = &(prP2pRoleFsmInfo->rConnReqInfo); + if (!prP2pConnReqInfo) + goto error; + + prP2pConnReqInfo->rChannelInfo.ucChannelNum = + prRfChannelInfo->ucChannelNum; + prP2pConnReqInfo->rChannelInfo.eBand = + prRfChannelInfo->eBand; + prP2pConnReqInfo->eChnlBw = + prRfChannelInfo->ucChnlBw; + + p2pFuncSetDfsState(DFS_STATE_INACTIVE); + + if (p2pFuncRoleToBssIdx( + prAdapter, ucRoleIdx, &ucBssIdx) != + WLAN_STATUS_SUCCESS) { + DBGLOG(P2P, WARN, "Incorrect role index"); + goto error; + } + + /* Set new channel */ + prP2pSetNewChannelMsg = (struct MSG_P2P_SET_NEW_CHANNEL *) + cnmMemAlloc(prAdapter, + RAM_TYPE_MSG, sizeof(*prP2pSetNewChannelMsg)); + if (prP2pSetNewChannelMsg == NULL) { + DBGLOG(P2P, WARN, + "prP2pSetNewChannelMsg alloc fail\n"); + goto error; + } + + prP2pSetNewChannelMsg->rMsgHdr.eMsgId = + MID_MNY_P2P_SET_NEW_CHANNEL; + prP2pSetNewChannelMsg->eChannelWidth = + (enum ENUM_CHANNEL_WIDTH) + rlmGetVhtOpBwByBssOpBw(prRfChannelInfo->ucChnlBw); + prP2pSetNewChannelMsg->ucRoleIdx = ucRoleIdx; + prP2pSetNewChannelMsg->ucBssIndex = ucBssIdx; + mboxSendMsg(prAdapter, + MBOX_ID_0, + (struct MSG_HDR *) prP2pSetNewChannelMsg, + MSG_SEND_METHOD_BUF); + + kalP2PSetRole(prGlueInfo, 2, ucRoleIdx); + + prGlueInfo->prP2PInfo[ucRoleIdx]->eChnlSwitchPolicy = + p2pFunDetermineChnlSwitchPolicy(prAdapter, ucBssIdx, + prRfChannelInfo); + + p2pFunNotifyChnlSwitch(prAdapter, ucBssIdx, + prGlueInfo->prP2PInfo[ucRoleIdx]->eChnlSwitchPolicy, + prRfChannelInfo); + + return 0; + +error: + + return -1; +} + +/*----------------------------------------------------------------------------*/ +/*! +* @brief Search available HW WMM index. +* +* @param (none) +* +* @return +*/ +/*----------------------------------------------------------------------------*/ +u_int8_t cnmWmmIndexDecision( + IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo) +{ +#if (CFG_HW_WMM_BY_BSS == 1) + u_int8_t ucWmmIndex; + + for (ucWmmIndex = 0; ucWmmIndex < HW_WMM_NUM; ucWmmIndex++) { + if (prBssInfo && prBssInfo->fgIsInUse && + prBssInfo->fgIsWmmInited == FALSE) { + if (!(prAdapter->ucHwWmmEnBit & BIT(ucWmmIndex))) { + prAdapter->ucHwWmmEnBit |= BIT(ucWmmIndex); + prBssInfo->fgIsWmmInited = TRUE; + break; + } + } + } + return (ucWmmIndex < HW_WMM_NUM) ? ucWmmIndex : MAX_HW_WMM_INDEX; + +#else + /* Follow the same rule with cnmUpdateDbdcSetting */ + if (prBssInfo->eBand == BAND_5G) + return DBDC_5G_WMM_INDEX; + else + return (prAdapter->rWifiVar.eDbdcMode == + ENUM_DBDC_MODE_DISABLED) ? + DBDC_5G_WMM_INDEX : DBDC_2G_WMM_INDEX; +#endif +} +/*----------------------------------------------------------------------------*/ +/*! +* @brief Free BSS HW WMM index. +* +* @param (none) +* +* @return None +*/ +/*----------------------------------------------------------------------------*/ +void cnmFreeWmmIndex( + IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo) +{ +#if (CFG_HW_WMM_BY_BSS == 1) + prAdapter->ucHwWmmEnBit &= (~BIT(prBssInfo->ucWmmQueSet)); +#endif + prBssInfo->ucWmmQueSet = DEFAULT_HW_WMM_INDEX; + prBssInfo->fgIsWmmInited = FALSE; +} + +enum ENUM_CNM_OPMODE_REQ_T +cnmOpModeMapEvtReason( + enum ENUM_EVENT_OPMODE_CHANGE_REASON eEvt +) +{ + enum ENUM_CNM_OPMODE_REQ_T eReqIdx; + + switch (eEvt) { + case EVENT_OPMODE_CHANGE_REASON_DBDC: + eReqIdx = CNM_OPMODE_REQ_DBDC; + break; + case EVENT_OPMODE_CHANGE_REASON_COANT: + eReqIdx = CNM_OPMODE_REQ_COANT; + break; + case EVENT_OPMODE_CHANGE_REASON_DBDC_SCAN: + eReqIdx = CNM_OPMODE_REQ_DBDC_SCAN; + break; + case EVENT_OPMODE_CHANGE_REASON_SMARTGEAR: + eReqIdx = CNM_OPMODE_REQ_SMARTGEAR; + break; + case EVENT_OPMODE_CHANGE_REASON_SMARTGEAR_1T2R: + eReqIdx = CNM_OPMODE_REQ_SMARTGEAR_1T2R; + break; + case EVENT_OPMODE_CHANGE_REASON_COEX: + eReqIdx = CNM_OPMODE_REQ_COEX; + break; + default: + eReqIdx = CNM_OPMODE_REQ_NUM; + break; + } + return eReqIdx; +} + +void cnmOpModeDump( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex +) +{ + struct BSS_INFO *prBssInfo; + + prBssInfo = prAdapter->aprBssInfo[ucBssIndex]; + DBGLOG(CNM, INFO, + "BSS[%d] DumpOpMode Tx(Cur:%x,Run:%x), Rx(Cur:%x,Run:%x)\n", + ucBssIndex, + prBssInfo->ucOpTxNss, + prBssInfo->fgIsOpChangeTxNss ? + prBssInfo->ucOpChangeTxNss : 0xFF, + prBssInfo->ucOpRxNss, + prBssInfo->fgIsOpChangeRxNss ? + prBssInfo->ucOpChangeRxNss : 0xFF); +} + +void cnmOpModeCallbackDispatcher( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN bool fgSuccess) +{ + struct CNM_OPMODE_BSS_CONTROL_T *prBssOpCtrl; + struct CNM_OPMODE_BSS_REQ *prReq; + enum ENUM_CNM_OPMODE_REQ_T eReqIdx; + + ASSERT(prAdapter); + if (ucBssIndex >= BSS_DEFAULT_NUM) { + DBGLOG(CNM, WARN, + "CbOpMode, invalid,B[%d]\n", + ucBssIndex); + return; + } + + /* Step 1. Run callback function */ + prBssOpCtrl = &g_arBssOpControl[ucBssIndex]; + if (!prBssOpCtrl->rRunning.fgIsRunning) { + /* GO/AP run cb immediately. */ + DBGLOG(CNM, INFO, + "CbOpMode, BSS[%d] none running, OpModeState[%d]\n", + ucBssIndex, + g_rDbdcInfo.eBssOpModeState[ucBssIndex]); + /* We have to callback op mode change done. + * Otherwise, DBDC state machine won't continue. + */ + if (g_rDbdcInfo.eBssOpModeState[ucBssIndex] == + ENUM_OPMODE_STATE_WAIT) { + cnmDbdcOpModeChangeDoneCallback( + prAdapter, ucBssIndex, fgSuccess); + } + } else { + switch (prBssOpCtrl->rRunning.eReqIdx) { + case CNM_OPMODE_REQ_DBDC: + cnmDbdcOpModeChangeDoneCallback( + prAdapter, ucBssIndex, fgSuccess); + break; + default: + break; + } + DBGLOG(CNM, INFO, + "CbOpMode,%s,Run,%s,T:%u,R:%u,%s\n", + apucCnmOpModeReq[prBssOpCtrl->rRunning.eReqIdx], + apucCnmOpModeReq[prBssOpCtrl->rRunning.eRunReq], + prBssOpCtrl->rRunning.ucOpTxNss, + prBssOpCtrl->rRunning.ucOpRxNss, + fgSuccess ? "OK" : "FAIL"); + } + prBssOpCtrl->rRunning.fgIsRunning = false; + + /* Step 2. Check pending request */ + for (eReqIdx = CNM_OPMODE_REQ_DBDC; + eReqIdx < CNM_OPMODE_REQ_NUM; + eReqIdx++) { + prReq = &(prBssOpCtrl->arReqPool[eReqIdx]); + if (prReq->fgNewRequest) + break; + } + + if (eReqIdx != CNM_OPMODE_REQ_NUM) { + DBGLOG(CNM, INFO, + "CbOpMode,ReTrigger:%s,En,%u,Tx:%u,Rx:%u\n", + apucCnmOpModeReq[eReqIdx], + prReq->fgEnable, + prReq->ucOpTxNss, + prReq->ucOpRxNss); + cnmOpModeSetTRxNss( + prAdapter, + ucBssIndex, + eReqIdx, + prReq->fgEnable, + prReq->ucOpRxNss, + prReq->ucOpTxNss); + } +} + +static enum ENUM_CNM_OPMODE_REQ_T +cnmOpModeReqDispatcher( + struct CNM_OPMODE_BSS_CONTROL_T *prBssOpCtrl +) +{ + struct CNM_OPMODE_BSS_REQ *prReq; + enum ENUM_CNM_OPMODE_REQ_T eReqIdx; + enum ENUM_CNM_OPMODE_REQ_T eReqFinal = CNM_OPMODE_REQ_MAX_CAP; + + if (prBssOpCtrl->rRunning.fgIsRunning) { + DBGLOG(CNM, INFO, + "OpMode %s (Tx:%d,Rx:%d) is running %s, defer new request\n", + apucCnmOpModeReq[prBssOpCtrl->rRunning.eReqIdx], + prBssOpCtrl->rRunning.ucOpTxNss, + prBssOpCtrl->rRunning.ucOpRxNss, + apucCnmOpModeReq[prBssOpCtrl->rRunning.eRunReq] + ); + return CNM_OPMODE_REQ_NUM; + } + + for (eReqIdx = CNM_OPMODE_REQ_DBDC; + eReqIdx < CNM_OPMODE_REQ_NUM; eReqIdx++) { + prReq = &(prBssOpCtrl->arReqPool[eReqIdx]); + prReq->fgNewRequest = false; + if (prReq->fgEnable && eReqIdx < eReqFinal) + eReqFinal = eReqIdx; + } + + return eReqFinal; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Set the operating TRx Nss. + * If failed to change OpRxNss, the OpTxNss will not change. + * If the BSS is not alive, just update to control table. + * + * @param prAdapter + * @param ucBssIndex + * @param eNewReq + * @param fgEnable + * @param ucOpRxNss + * @param ucOpTxNss + * + * @return ENUM_CNM_OPMODE_REQ_STATUS + */ +/*----------------------------------------------------------------------------*/ +enum ENUM_CNM_OPMODE_REQ_STATUS +cnmOpModeSetTRxNss( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN enum ENUM_CNM_OPMODE_REQ_T eNewReq, + IN bool fgEnable, + IN uint8_t ucOpRxNss, + IN uint8_t ucOpTxNss +) +{ + struct BSS_INFO *prBssInfo; + struct CNM_OPMODE_BSS_CONTROL_T *prBssOpCtrl; + struct CNM_OPMODE_BSS_REQ *prReq; + enum ENUM_OP_CHANGE_STATUS_T eRlmStatus; + enum ENUM_CNM_OPMODE_REQ_STATUS eStatus + = CNM_OPMODE_REQ_STATUS_SUCCESS; + uint8_t ucOpRxNssFinal, ucOpTxNssFinal, ucOpBwFinal; + enum ENUM_CNM_OPMODE_REQ_T eRunReq; + + ASSERT(prAdapter); + if (ucBssIndex > prAdapter->ucHwBssIdNum || + ucBssIndex >= BSS_DEFAULT_NUM) { + DBGLOG(CNM, WARN, "SetOpMode invalid BSS[%d]\n", ucBssIndex); + return CNM_OPMODE_REQ_STATUS_INVALID_PARAM; + } + + prBssInfo = prAdapter->aprBssInfo[ucBssIndex]; + prBssOpCtrl = &g_arBssOpControl[ucBssIndex]; + prReq = &(prBssOpCtrl->arReqPool[eNewReq]); + + /* Step 1 Update req pool */ + prReq->fgEnable = fgEnable; + prReq->fgNewRequest = true; + prReq->ucOpRxNss = ucOpRxNss; + prReq->ucOpTxNss = ucOpTxNss; + + /* Step 2 Select the highest priority req */ + eRunReq = cnmOpModeReqDispatcher(prBssOpCtrl); + if (eRunReq == CNM_OPMODE_REQ_NUM) { + return CNM_OPMODE_REQ_STATUS_DEFER; + } else if (eRunReq == CNM_OPMODE_REQ_MAX_CAP) { + ucOpRxNssFinal = ucOpTxNssFinal = + wlanGetSupportNss(prAdapter, ucBssIndex); + } else { + prReq = &prBssOpCtrl->arReqPool[eRunReq]; + ucOpRxNssFinal = prReq->ucOpRxNss; + ucOpTxNssFinal = prReq->ucOpTxNss; + } + + if (IS_BSS_ALIVE(prAdapter, prBssInfo)) { + /* Step 3. Special rule for BW change (DBDC) + * We only bound OpBw @ BW80 for DBDC. + * This function colud not restore to current peer's + * OpBw. It's fine because below reasons(2018/08): + * 1) No DBDC project supports BW160 or NW80+80. + * 2) No feature wants to change OpBw. + * + * If you want to change OpBw in the future, please + * make sure you can restore to current peer's OpBw. + */ + ucOpBwFinal = rlmGetBssOpBwByVhtAndHtOpInfo(prBssInfo); + if ((eRunReq == CNM_OPMODE_REQ_DBDC || + eRunReq == CNM_OPMODE_REQ_DBDC_SCAN) && + ucOpBwFinal > MAX_BW_80MHZ) { + DBGLOG(CNM, INFO, + "SetOpMode Bss[%d] %s override BW %d to MAX_BW_80MHZ\n", + ucBssIndex, + apucCnmOpModeReq[eRunReq], + ucOpBwFinal); + ucOpBwFinal = MAX_BW_80MHZ; + } + + /* Step 4. Execute OpMode change function for alive BSS */ + eRlmStatus = rlmChangeOperationMode(prAdapter, + ucBssIndex, + ucOpBwFinal, + ucOpRxNssFinal, + ucOpTxNssFinal, + #if CFG_SUPPORT_SMART_GEAR + eNewReq, + #endif + cnmOpModeCallbackDispatcher + ); + + switch (eRlmStatus) { + case OP_CHANGE_STATUS_VALID_NO_CHANGE: + case OP_CHANGE_STATUS_VALID_CHANGE_CALLBACK_DONE: + eStatus = CNM_OPMODE_REQ_STATUS_SUCCESS; + break; + case OP_CHANGE_STATUS_VALID_CHANGE_CALLBACK_WAIT: + eStatus = CNM_OPMODE_REQ_STATUS_RUNNING; + prBssOpCtrl->rRunning.fgIsRunning = true; + prBssOpCtrl->rRunning.eReqIdx = eNewReq; + prBssOpCtrl->rRunning.eRunReq = eRunReq; + prBssOpCtrl->rRunning.ucOpTxNss = ucOpTxNssFinal; + prBssOpCtrl->rRunning.ucOpRxNss = ucOpRxNssFinal; + break; + case OP_CHANGE_STATUS_INVALID: + default: + eStatus = CNM_OPMODE_REQ_STATUS_INVALID_PARAM; + break; + } + } + + /* Step 5. Dump result */ + DBGLOG(CNM, INFO, + "SetOpMode Bss[%d] alive[%d] NewReq:%s %s RunReq:%s,%s\n", + ucBssIndex, IS_BSS_ALIVE(prAdapter, prBssInfo), + apucCnmOpModeReq[eNewReq], + fgEnable ? "En" : "Dis", + apucCnmOpModeReq[eRunReq], + apucCnmOpModeReqStatus[eStatus]); + cnmOpModeDump(prAdapter, ucBssIndex); + + return eStatus; +} + + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Get the operation TRx Nss. + * If DBDC is goning to enable or already enabled, return 1. + * Else return MaxCapability. + * + * @param prAdapter + * @param ucBssIndex + * @param pucOpRxNss + * @param pucOpTxNss + * + * @return ucOpTRxNss + */ +/*----------------------------------------------------------------------------*/ +void cnmOpModeGetTRxNss( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + OUT uint8_t *pucOpRxNss, + OUT uint8_t *pucOpTxNss) +{ + struct CNM_OPMODE_BSS_CONTROL_T *prBssOpCtrl; + struct CNM_OPMODE_BSS_REQ *prReq; + enum ENUM_CNM_OPMODE_REQ_T eReqIdx; + enum ENUM_CNM_OPMODE_REQ_T eCurrMaxIdx = CNM_OPMODE_REQ_MAX_CAP; + uint8_t ucOpRxNss, ucOpTxNss; + + if (pucOpRxNss == NULL || pucOpTxNss == NULL || + ucBssIndex >= BSS_DEFAULT_NUM) { + DBGLOG(CNM, WARN, + "GetOpMode invalid param B[%d]\n", + ucBssIndex); + return; + } + + ucOpRxNss = ucOpTxNss = wlanGetSupportNss(prAdapter, ucBssIndex); + prBssOpCtrl = &g_arBssOpControl[ucBssIndex]; + + *pucOpTxNss = ucOpTxNss; + *pucOpRxNss = ucOpRxNss; + + if (prBssOpCtrl->rRunning.fgIsRunning) { + eCurrMaxIdx = prBssOpCtrl->rRunning.eRunReq; + *pucOpTxNss = prBssOpCtrl->rRunning.ucOpTxNss; + *pucOpRxNss = prBssOpCtrl->rRunning.ucOpRxNss; + DBGLOG(CNM, INFO, + "GetOpMode,use running %s from %s\n", + apucCnmOpModeReq[eCurrMaxIdx], + apucCnmOpModeReq[prBssOpCtrl->rRunning.eReqIdx]); + } else { + for (eReqIdx = CNM_OPMODE_REQ_DBDC; + eReqIdx < CNM_OPMODE_REQ_NUM; + eReqIdx++) { + prReq = &(prBssOpCtrl->arReqPool[eReqIdx]); + if (prReq->fgEnable && !prReq->fgNewRequest) { + eCurrMaxIdx = eReqIdx; + *pucOpTxNss = (ucOpTxNss > prReq->ucOpTxNss) ? + prReq->ucOpTxNss : ucOpTxNss; + *pucOpRxNss = (ucOpRxNss > prReq->ucOpRxNss) ? + prReq->ucOpRxNss : ucOpRxNss; + break; + } + } + } + + DBGLOG(CNM, INFO, + "GetOpMode BSS[%u](%s) T:%d R:%u\n", + ucBssIndex, apucCnmOpModeReq[eCurrMaxIdx], + *pucOpTxNss, *pucOpRxNss); +} + +#if CFG_SUPPORT_SMART_GEAR +/*----------------------------------------------------------------------------*/ +/*! + * @brief Handle Smart Gear Status Change event from FW. + * + * @param prAdapter + * @param prEvent + * + * @return + */ +/*----------------------------------------------------------------------------*/ +void cnmEventSGStatus( + IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ +#if CFG_SUPPORT_DATA_STALL + struct EVENT_SMART_GEAT_STATE *prSGState; + enum ENUM_VENDOR_DRIVER_EVENT eEvent; + + ASSERT(prAdapter); + prSGState = (struct EVENT_SMART_GEAT_STATE *) (prEvent->aucBuffer); + + if (prSGState->fgIsEnable == 0x01) { + if (prSGState->u4StateIdx == 0x00) + eEvent = EVENT_SG_1T1R; + else + eEvent = EVENT_SG_2T2R; + } else if (prSGState->fgIsEnable == 0x00) { + eEvent = EVENT_SG_DISABLE; + } else { + ;/* Not correction value, juste reture;*/ + return; + } + + DBGLOG(CNM, INFO, + "[SG]cnmEventSGStatus,%u,%u,%u\n", + prSGState->fgIsEnable, prSGState->u4StateIdx, eEvent); + KAL_REPORT_ERROR_EVENT(prAdapter, + eEvent, (uint16_t)sizeof(u_int8_t), + 0, + TRUE); +#endif /* CFG_SUPPORT_DATA_STALL */ +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Event handler for EVENT_ID_OPMODE_CHANGE + * + * @param prAdapter + * @param prEvent + * + * @return + */ +/*----------------------------------------------------------------------------*/ +void cnmOpmodeEventHandler( + IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ + struct EVENT_OPMODE_CHANGE *prEvtOpMode; + enum ENUM_CNM_OPMODE_REQ_T eReqIdx; + uint8_t ucBssIndex; + + ASSERT(prAdapter); + prEvtOpMode = (struct EVENT_OPMODE_CHANGE *) + (prEvent->aucBuffer); + + eReqIdx = cnmOpModeMapEvtReason( + (enum ENUM_EVENT_OPMODE_CHANGE_REASON) + prEvtOpMode->ucReason); + + if (eReqIdx >= CNM_OPMODE_REQ_NUM) { + DBGLOG(CNM, WARN, + "EvtOpMode,WrongReaosn,%u,Evt,%u,igonre\n", + eReqIdx, prEvtOpMode->ucReason); + return; + } + + DBGLOG(CNM, INFO, + "EvtOpMode, Req:%s BssBitmap:0x%x, En:%u T:%u R:%u\n", + apucCnmOpModeReq[eReqIdx], + prEvtOpMode->ucBssBitmap, + prEvtOpMode->ucEnable, + prEvtOpMode->ucOpTxNss, + prEvtOpMode->ucOpRxNss); + + for (ucBssIndex = 0; + ucBssIndex < prAdapter->ucHwBssIdNum; + ucBssIndex++) { + if (prEvtOpMode->ucBssBitmap & BIT(ucBssIndex)) { + cnmOpModeSetTRxNss( + prAdapter, + ucBssIndex, + eReqIdx, + prEvtOpMode->ucEnable, + prEvtOpMode->ucOpRxNss, + prEvtOpMode->ucOpTxNss + ); + } + } +} + +enum ENUM_CNM_WMM_QUOTA_REQ_T +cnmWmmQuotaReqDispatcher( + struct CNM_WMM_QUOTA_CONTROL_T *prWmmQuotaCtrl +) +{ + struct CNM_WMM_QUOTA_REQ *prReq; + enum ENUM_CNM_WMM_QUOTA_REQ_T eReqIdx; + enum ENUM_CNM_WMM_QUOTA_REQ_T eReqFinal = CNM_WMM_REQ_DEFAULT; + + if (prWmmQuotaCtrl->rRunning.fgIsRunning) { + DBGLOG(CNM, WARN, + "WmmQuota,PreReq,%s,RunningReq,%s\n", + apucCnmWmmQuotaReq[prWmmQuotaCtrl->rRunning.eReqIdx], + apucCnmWmmQuotaReq[prWmmQuotaCtrl->rRunning.eRunReq]); + } + + for (eReqIdx = CNM_WMM_REQ_DBDC; + eReqIdx < CNM_WMM_REQ_NUM; eReqIdx++) { + prReq = &(prWmmQuotaCtrl->arReqPool[eReqIdx]); + if (prReq->fgEnable && eReqIdx < eReqFinal) + eReqFinal = eReqIdx; + } + return eReqFinal; +} + +void +cnmWmmQuotaCallback( + IN struct ADAPTER *prAdapter, + IN unsigned long plParamPtr +) +{ + struct CNM_WMM_QUOTA_CONTROL_T *prWmmQuotaCtrl; + bool fgRun; + uint8_t ucWmmIndex; + + KAL_SPIN_LOCK_DECLARATION(); + + ucWmmIndex = (uint8_t)plParamPtr; + prWmmQuotaCtrl = &(g_arWmmQuotaControl[ucWmmIndex]); + + if (!prWmmQuotaCtrl->rRunning.fgIsRunning) { + DBGLOG(CNM, WARN, + "WmmQuotaCb,%d,None runnig\n", + ucWmmIndex); + return; + } + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_UPDATE_WMM_QUOTA); + fgRun = prAdapter->rWmmQuotaReqCS[ucWmmIndex].fgRun; + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_UPDATE_WMM_QUOTA); + + if (fgRun) { + DBGLOG(CNM, INFO, + "WmmQuotaCb,%d,Req,%s,Run,%s,Quota,%u,WakeUpHIF\n", + ucWmmIndex, + apucCnmWmmQuotaReq[prWmmQuotaCtrl->rRunning.eReqIdx], + apucCnmWmmQuotaReq[prWmmQuotaCtrl->rRunning.eRunReq], + prWmmQuotaCtrl->rRunning.u4ReqQuota + ); + kalSetWmmUpdateEvent(prAdapter->prGlueInfo); + if (!timerPendingTimer(&(prWmmQuotaCtrl->rTimer))) { + cnmTimerStartTimer( + prAdapter, &(prWmmQuotaCtrl->rTimer), + CNM_WMM_QUOTA_RETRIGGER_TIME_MS); + } + } else { + prWmmQuotaCtrl->rRunning.fgIsRunning = false; + DBGLOG(CNM, INFO, + "WmmQuotaCb,%u,%s,Run,%s,Quota,%u,Finish\n", + ucWmmIndex, + apucCnmWmmQuotaReq[prWmmQuotaCtrl->rRunning.eReqIdx], + apucCnmWmmQuotaReq[prWmmQuotaCtrl->rRunning.eRunReq], + prWmmQuotaCtrl->rRunning.u4ReqQuota); + } +} + +void cnmWmmQuotaSetMaxQuota( + IN struct ADAPTER *prAdapter, + IN uint8_t ucWmmIndex, + IN enum ENUM_CNM_WMM_QUOTA_REQ_T eNewReq, + IN bool fgEnable, + IN uint32_t u4ReqQuota +) +{ + struct CNM_WMM_QUOTA_CONTROL_T *prWmmQuotaCtrl; + enum ENUM_CNM_WMM_QUOTA_REQ_T eRunReq; + uint32_t u4QuotaFinal; + + KAL_SPIN_LOCK_DECLARATION(); + + ASSERT(prAdapter); + + prWmmQuotaCtrl = &(g_arWmmQuotaControl[ucWmmIndex]); + prWmmQuotaCtrl->arReqPool[eNewReq].fgEnable = fgEnable; + prWmmQuotaCtrl->arReqPool[eNewReq].u4ReqQuota = u4ReqQuota; + + eRunReq = cnmWmmQuotaReqDispatcher(prWmmQuotaCtrl); + if (eRunReq == CNM_WMM_REQ_DEFAULT) { + /* unlimit */ + u4QuotaFinal = -1; + } else { + u4QuotaFinal = prWmmQuotaCtrl->arReqPool[eRunReq].u4ReqQuota; + } + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_UPDATE_WMM_QUOTA); + prAdapter->rWmmQuotaReqCS[ucWmmIndex].u4Quota = u4QuotaFinal; + prAdapter->rWmmQuotaReqCS[ucWmmIndex].fgRun = true; + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_UPDATE_WMM_QUOTA); + + prWmmQuotaCtrl->rRunning.fgIsRunning = true; + prWmmQuotaCtrl->rRunning.eReqIdx = eNewReq; + prWmmQuotaCtrl->rRunning.eRunReq = eRunReq; + prWmmQuotaCtrl->rRunning.u4ReqQuota = u4QuotaFinal; + DBGLOG(CNM, INFO, + "SetWmmQuota,%u,%s %s,Run,%s,Quota,0x%x\n", + ucWmmIndex, + apucCnmWmmQuotaReq[prWmmQuotaCtrl->rRunning.eReqIdx], + fgEnable ? "En" : "Dis", + apucCnmWmmQuotaReq[prWmmQuotaCtrl->rRunning.eRunReq], + prWmmQuotaCtrl->rRunning.u4ReqQuota); + + cnmWmmQuotaCallback(prAdapter, ucWmmIndex); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief check if p2p is active + * + * @param prAdapter + * + * @return + */ +/*----------------------------------------------------------------------------*/ +u_int8_t cnmP2pIsActive(IN struct ADAPTER *prAdapter) +{ + uint8_t ret; + + ret = (cnmGetP2pBssInfo(prAdapter) != NULL); + DBGLOG(CNM, TRACE, "P2p is %s\n", ret ? "ACTIVE" : "INACTIVE"); + return ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief get p2p bss info + * + * @param prAdapter + * + * @return + */ +/*----------------------------------------------------------------------------*/ +struct BSS_INFO *cnmGetP2pBssInfo(IN struct ADAPTER *prAdapter) +{ + struct BSS_INFO *prBssInfo; + uint8_t i; + + if (!prAdapter) + return NULL; + + for (i = 0; i < prAdapter->ucHwBssIdNum; i++) { + prBssInfo = prAdapter->aprBssInfo[i]; + + if (prBssInfo && + IS_BSS_P2P(prBssInfo) && + !p2pFuncIsAPMode( + prAdapter->rWifiVar.prP2PConnSettings + [prBssInfo->u4PrivateData]) && + IS_BSS_ALIVE(prAdapter, prBssInfo)) + return prBssInfo; + } + + return NULL; +} + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/cnm_mem.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/cnm_mem.c new file mode 100644 index 0000000000000000000000000000000000000000..31aa69f4baf8f884c745e98151bf10a81d485b4f --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/cnm_mem.c @@ -0,0 +1,1868 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/cnm_mem.c#2 + */ + +/*! \file "cnm_mem.c" + * \brief This file contain the management function of packet buffers and + * generic memory alloc/free functioin for mailbox message. + * + * A data packet has a fixed size of buffer, but a management + * packet can be equipped with a variable size of buffer. + */ + + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +static uint8_t *apucStaRecType[STA_TYPE_INDEX_NUM] = { + (uint8_t *) "LEGACY", + (uint8_t *) "P2P", + (uint8_t *) "BOW" +}; + +static uint8_t *apucStaRecRole[STA_ROLE_INDEX_NUM] = { + (uint8_t *) "ADHOC", + (uint8_t *) "CLIENT", + (uint8_t *) "AP", + (uint8_t *) "DLS" +}; + +#if CFG_SUPPORT_TDLS +/* The list of valid data rates. */ +const uint8_t aucValidDataRate[] = { + RATE_1M, /* RATE_1M_INDEX = 0 */ + RATE_2M, /* RATE_2M_INDEX */ + RATE_5_5M, /* RATE_5_5M_INDEX */ + RATE_11M, /* RATE_11M_INDEX */ + RATE_22M, /* RATE_22M_INDEX */ + RATE_33M, /* RATE_33M_INDEX */ + RATE_6M, /* RATE_6M_INDEX */ + RATE_9M, /* RATE_9M_INDEX */ + RATE_12M, /* RATE_12M_INDEX */ + RATE_18M, /* RATE_18M_INDEX */ + RATE_24M, /* RATE_24M_INDEX */ + RATE_36M, /* RATE_36M_INDEX */ + RATE_48M, /* RATE_48M_INDEX */ + RATE_54M, /* RATE_54M_INDEX */ + RATE_VHT_PHY, /* RATE_VHT_PHY_INDEX */ + RATE_HT_PHY /* RATE_HT_PHY_INDEX */ +}; +#endif + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +static void cnmStaRoutinesForAbort(struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec); + +static void cnmStaRecHandleEventPkt(struct ADAPTER *prAdapter, + struct CMD_INFO *prCmdInfo, uint8_t *pucEventBuf); + +static void +cnmStaSendRemoveCmd(struct ADAPTER *prAdapter, + enum ENUM_STA_REC_CMD_ACTION eActionType, uint8_t ucStaRecIndex, + uint8_t ucBssIndex); + +#if (CFG_SUPPORT_802_11AX == 1) +static void cnmStaRecCmdHeContentFill( + struct STA_RECORD *prStaRec, + struct CMD_UPDATE_STA_RECORD *prCmdContent); +#endif + + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +struct MSDU_INFO *cnmPktAllocWrapper(struct ADAPTER *prAdapter, + uint32_t u4Length, uint8_t *pucStr) +{ + struct MSDU_INFO *prMsduInfo; + + prMsduInfo = cnmPktAlloc(prAdapter, u4Length); + log_dbg(MEM, LOUD, "Alloc MSDU_INFO[0x%p] by [%s]\n", + prMsduInfo, pucStr); + + return prMsduInfo; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void cnmPktFreeWrapper(struct ADAPTER *prAdapter, struct MSDU_INFO *prMsduInfo, + uint8_t *pucStr) +{ + log_dbg(MEM, LOUD, "Free MSDU_INFO[0x%p] by [%s]\n", + prMsduInfo, pucStr); + + cnmPktFree(prAdapter, prMsduInfo); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +struct MSDU_INFO *cnmPktAlloc(struct ADAPTER *prAdapter, uint32_t u4Length) +{ + struct MSDU_INFO *prMsduInfo; + struct QUE *prQueList; + + KAL_SPIN_LOCK_DECLARATION(); + + ASSERT(prAdapter); + prQueList = &prAdapter->rTxCtrl.rFreeMsduInfoList; + + /* Get a free MSDU_INFO_T */ + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); + QUEUE_REMOVE_HEAD(prQueList, prMsduInfo, struct MSDU_INFO *); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); + + if (prMsduInfo) { + if (u4Length) { + prMsduInfo->prPacket = cnmMemAlloc(prAdapter, + RAM_TYPE_BUF, u4Length); + prMsduInfo->eSrc = TX_PACKET_MGMT; + + if (prMsduInfo->prPacket == NULL) { + KAL_ACQUIRE_SPIN_LOCK(prAdapter, + SPIN_LOCK_TX_MSDU_INFO_LIST); + QUEUE_INSERT_TAIL(prQueList, + &prMsduInfo->rQueEntry); + KAL_RELEASE_SPIN_LOCK(prAdapter, + SPIN_LOCK_TX_MSDU_INFO_LIST); + prMsduInfo = NULL; + } + } else { + prMsduInfo->prPacket = NULL; + } + } +#if DBG + if (prMsduInfo == NULL) { + log_dbg(MEM, WARN, "\n"); + log_dbg(MEM, WARN, "MgtDesc#=%ld\n", prQueList->u4NumElem); + +#if CFG_DBG_MGT_BUF + log_dbg(MEM, WARN, "rMgtBufInfo: alloc#=%ld, free#=%ld, null#=%ld\n", + prAdapter->rMgtBufInfo.u4AllocCount, + prAdapter->rMgtBufInfo.u4FreeCount, + prAdapter->rMgtBufInfo.u4AllocNullCount); +#endif + + log_dbg(MEM, WARN, "\n"); + } +#endif + + return prMsduInfo; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void cnmPktFree(struct ADAPTER *prAdapter, struct MSDU_INFO *prMsduInfo) +{ + struct QUE *prQueList; + + KAL_SPIN_LOCK_DECLARATION(); + + ASSERT(prAdapter); + + if (!prMsduInfo) + return; + + prQueList = &prAdapter->rTxCtrl.rFreeMsduInfoList; + + /* ASSERT(prMsduInfo->prPacket); */ + if (prMsduInfo->prPacket) { + cnmMemFree(prAdapter, prMsduInfo->prPacket); + prMsduInfo->prPacket = NULL; + } + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); + QUEUE_INSERT_TAIL(prQueList, &prMsduInfo->rQueEntry); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is used to initial the MGMT/MSG memory pool. + * + * \param (none) + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void cnmMemInit(struct ADAPTER *prAdapter) +{ + struct BUF_INFO *prBufInfo; + + /* Initialize Management buffer pool */ + prBufInfo = &prAdapter->rMgtBufInfo; + kalMemZero(prBufInfo, sizeof(prAdapter->rMgtBufInfo)); + prBufInfo->pucBuf = prAdapter->pucMgtBufCached; + + /* Setup available memory blocks. 1 indicates FREE */ + prBufInfo->rFreeBlocksBitmap = (uint32_t) BITS(0, + MAX_NUM_OF_BUF_BLOCKS - 1); + + /* Initialize Message buffer pool */ + prBufInfo = &prAdapter->rMsgBufInfo; + kalMemZero(prBufInfo, sizeof(prAdapter->rMsgBufInfo)); + prBufInfo->pucBuf = &prAdapter->aucMsgBuf[0]; + + /* Setup available memory blocks. 1 indicates FREE */ + prBufInfo->rFreeBlocksBitmap = (uint32_t) BITS(0, + MAX_NUM_OF_BUF_BLOCKS - 1); + + return; + +} /* end of cnmMemInit() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Allocate MGMT/MSG memory pool. + * + * \param[in] eRamType Target RAM type. + * TCM blk_sz= 16bytes, BUF blk_sz= 256bytes + * \param[in] u4Length Length of the buffer to allocate. + * + * \retval !NULL Pointer to the start address of allocated memory. + * \retval NULL Fail to allocat memory + */ +/*----------------------------------------------------------------------------*/ +#if CFG_DBG_MGT_BUF +void *cnmMemAllocX(IN struct ADAPTER *prAdapter, IN enum ENUM_RAM_TYPE eRamType, + IN uint32_t u4Length, uint8_t *fileAndLine) +#else +void *cnmMemAlloc(IN struct ADAPTER *prAdapter, IN enum ENUM_RAM_TYPE eRamType, + IN uint32_t u4Length) +#endif +{ + struct BUF_INFO *prBufInfo; + uint32_t rRequiredBitmap; + uint32_t u4BlockNum; + uint32_t i, u4BlkSzInPower; + void *pvMemory; + enum ENUM_SPIN_LOCK_CATEGORY_E eLockBufCat; + + KAL_SPIN_LOCK_DECLARATION(); + + ASSERT(prAdapter); + + if (u4Length == 0) { + log_dbg(MEM, WARN, + "%s: Length to be allocated is ZERO, skip!\n", + __func__); + return NULL; + } + + if (eRamType == RAM_TYPE_MSG && u4Length <= 256) { + prBufInfo = &prAdapter->rMsgBufInfo; + u4BlkSzInPower = MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2; + + u4BlockNum = (u4Length + MSG_BUF_BLOCK_SIZE - 1) + >> MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2; + + ASSERT(u4BlockNum <= MAX_NUM_OF_BUF_BLOCKS); + } else { + eRamType = RAM_TYPE_BUF; + + prBufInfo = &prAdapter->rMgtBufInfo; + u4BlkSzInPower = MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2; + + u4BlockNum = (u4Length + MGT_BUF_BLOCK_SIZE - 1) + >> MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2; + + ASSERT(u4BlockNum <= MAX_NUM_OF_BUF_BLOCKS); + } + + if (eRamType == RAM_TYPE_MSG) + eLockBufCat = SPIN_LOCK_MSG_BUF; + else + eLockBufCat = SPIN_LOCK_MGT_BUF; + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, eLockBufCat); + +#if CFG_DBG_MGT_BUF + prBufInfo->u4AllocCount++; +#endif + + if ((u4BlockNum > 0) && (u4BlockNum <= MAX_NUM_OF_BUF_BLOCKS)) { + + /* Convert number of block into bit cluster */ + rRequiredBitmap = BITS(0, u4BlockNum - 1); + + for (i = 0; i <= (MAX_NUM_OF_BUF_BLOCKS - u4BlockNum); i++) { + + /* Have available memory blocks */ + if ((prBufInfo->rFreeBlocksBitmap & rRequiredBitmap) + == rRequiredBitmap) { + + /* Clear corresponding bits of allocated + * memory blocks + */ + prBufInfo->rFreeBlocksBitmap + &= ~rRequiredBitmap; + + /* Store how many blocks be allocated */ + prBufInfo->aucAllocatedBlockNum[i] + = (uint8_t) u4BlockNum; + + KAL_RELEASE_SPIN_LOCK(prAdapter, eLockBufCat); + + /* Return the start address of + * allocated memory + */ + return (void *) (prBufInfo->pucBuf + + (i << u4BlkSzInPower)); + } + + rRequiredBitmap <<= 1; + } + } + +#if CFG_DBG_MGT_BUF + prBufInfo->u4AllocNullCount++; +#endif + + /* kalMemAlloc() shall not included in spin_lock */ + KAL_RELEASE_SPIN_LOCK(prAdapter, eLockBufCat); + +#ifdef LINUX +#if CFG_DBG_MGT_BUF + pvMemory = (void *) kalMemAlloc(u4Length + sizeof(struct MEM_TRACK), + PHY_MEM_TYPE); + if (pvMemory) { + struct MEM_TRACK *prMemTrack = (struct MEM_TRACK *)pvMemory; + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_MGT_BUF); + LINK_INSERT_TAIL( + &prAdapter->rMemTrackLink, &prMemTrack->rLinkEntry); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_MGT_BUF); + prMemTrack->pucFileAndLine = fileAndLine; + prMemTrack->u2CmdIdAndWhere = 0x0000; + pvMemory = (void *)(prMemTrack + 1); + kalMemZero(pvMemory, u4Length); + } +#else + pvMemory = (void *) kalMemAlloc(u4Length, PHY_MEM_TYPE); + if (!pvMemory) + DBGLOG(MEM, WARN, "kmalloc fail: %u\n", u4Length); +#endif +#else + pvMemory = (void *) NULL; +#endif + +#if CFG_DBG_MGT_BUF + if (pvMemory) + GLUE_INC_REF_CNT(prAdapter->u4MemAllocDynamicCount); +#endif + + return pvMemory; + +} /* end of cnmMemAlloc() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Release memory to MGT/MSG memory pool. + * + * \param pucMemory Start address of previous allocated memory + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void cnmMemFree(IN struct ADAPTER *prAdapter, IN void *pvMemory) +{ + struct BUF_INFO *prBufInfo; + uint32_t u4BlockIndex; + uint32_t rAllocatedBlocksBitmap; + enum ENUM_RAM_TYPE eRamType; + enum ENUM_SPIN_LOCK_CATEGORY_E eLockBufCat; + + KAL_SPIN_LOCK_DECLARATION(); + + ASSERT(prAdapter); + + if (!pvMemory) + return; + + /* Judge it belongs to which RAM type */ + if (((unsigned long) pvMemory + >= (unsigned long)&prAdapter->aucMsgBuf[0]) + && ((unsigned long) pvMemory + <= (unsigned long)&prAdapter->aucMsgBuf[MSG_BUFFER_SIZE - 1])) { + + prBufInfo = &prAdapter->rMsgBufInfo; + u4BlockIndex = ((unsigned long) pvMemory + - (unsigned long) prBufInfo->pucBuf) + >> MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2; + ASSERT(u4BlockIndex < MAX_NUM_OF_BUF_BLOCKS); + eRamType = RAM_TYPE_MSG; + } else if (((unsigned long) pvMemory + >= (unsigned long) prAdapter->pucMgtBufCached) + && ((unsigned long) pvMemory + <= ((unsigned long) prAdapter->pucMgtBufCached + + MGT_BUFFER_SIZE - 1))) { + prBufInfo = &prAdapter->rMgtBufInfo; + u4BlockIndex = ((unsigned long) pvMemory + - (unsigned long) prBufInfo->pucBuf) + >> MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2; + ASSERT(u4BlockIndex < MAX_NUM_OF_BUF_BLOCKS); + eRamType = RAM_TYPE_BUF; + } else { +#ifdef LINUX +#if CFG_DBG_MGT_BUF + struct MEM_TRACK *prTrack = (struct MEM_TRACK *) + ((uint8_t *)pvMemory - sizeof(struct MEM_TRACK)); + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_MGT_BUF); + LINK_REMOVE_KNOWN_ENTRY( + &prAdapter->rMemTrackLink, &prTrack->rLinkEntry); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_MGT_BUF); + kalMemFree(prTrack, PHY_MEM_TYPE, 0); +#else + /* For Linux, it is supported because size is not needed */ + kalMemFree(pvMemory, PHY_MEM_TYPE, 0); +#endif +#else + /* For Windows, it is not supported because of + * no size argument + */ + ASSERT(0); +#endif + +#if CFG_DBG_MGT_BUF + GLUE_INC_REF_CNT(prAdapter->u4MemFreeDynamicCount); +#endif + return; + } + + if (eRamType == RAM_TYPE_MSG) + eLockBufCat = SPIN_LOCK_MSG_BUF; + else + eLockBufCat = SPIN_LOCK_MGT_BUF; + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, eLockBufCat); + +#if CFG_DBG_MGT_BUF + prBufInfo->u4FreeCount++; +#endif + + /* Convert number of block into bit cluster */ + ASSERT(prBufInfo->aucAllocatedBlockNum[u4BlockIndex] > 0); + + rAllocatedBlocksBitmap + = BITS(0, prBufInfo->aucAllocatedBlockNum[u4BlockIndex] - 1); + rAllocatedBlocksBitmap <<= u4BlockIndex; + + /* Clear saved block count for this memory segment */ + prBufInfo->aucAllocatedBlockNum[u4BlockIndex] = 0; + + /* Set corresponding bit of released memory block */ + prBufInfo->rFreeBlocksBitmap |= rAllocatedBlocksBitmap; + + KAL_RELEASE_SPIN_LOCK(prAdapter, eLockBufCat); + + return; + +} /* end of cnmMemFree() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void cnmStaRecInit(struct ADAPTER *prAdapter) +{ + struct STA_RECORD *prStaRec; + uint16_t i; + + for (i = 0; i < CFG_STA_REC_NUM; i++) { + prStaRec = &prAdapter->arStaRec[i]; + + prStaRec->ucIndex = (uint8_t) i; + prStaRec->fgIsInUse = FALSE; + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +struct STA_RECORD *cnmStaRecAlloc(struct ADAPTER *prAdapter, + enum ENUM_STA_TYPE eStaType, uint8_t ucBssIndex, uint8_t *pucMacAddr) +{ + struct STA_RECORD *prStaRec; + uint16_t i, k; + + ASSERT(prAdapter); + + for (i = 0; i < CFG_STA_REC_NUM; i++) { + prStaRec = &prAdapter->arStaRec[i]; + + if (!prStaRec->fgIsInUse) { + kalMemZero(prStaRec, sizeof(struct STA_RECORD)); + prStaRec->ucIndex = (uint8_t) i; + prStaRec->ucBssIndex = ucBssIndex; + prStaRec->fgIsInUse = TRUE; + + prStaRec->eStaType = eStaType; + prStaRec->ucBssIndex = ucBssIndex; + + /* Initialize the SN caches for duplicate detection */ + for (k = 0; k < TID_NUM + 1; k++) { + prStaRec->au2CachedSeqCtrl[k] = 0xFFFF; + prStaRec->afgIsIgnoreAmsduDuplicate[k] = FALSE; +#if CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION + prStaRec->au2AmsduInvalidSN[k] = 0xFFFF; + prStaRec->afgIsAmsduInvalid[k] = FALSE; +#endif /* CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION */ + } + + /* Initialize SW TX queues in STA_REC */ + for (k = 0; k < STA_WAIT_QUEUE_NUM; k++) + LINK_INITIALIZE(&prStaRec->arStaWaitQueue[k]); + +#if CFG_ENABLE_PER_STA_STATISTICS && CFG_ENABLE_PKT_LIFETIME_PROFILE + prStaRec->u4TotalTxPktsNumber = 0; + prStaRec->u4TotalTxPktsTime = 0; + prStaRec->u4TotalRxPktsNumber = 0; + prStaRec->u4MaxTxPktsTime = 0; +#endif + + for (k = 0; k < NUM_OF_PER_STA_TX_QUEUES; k++) { + QUEUE_INITIALIZE( + &prStaRec->arTxQueue[k]); + QUEUE_INITIALIZE( + &prStaRec->arPendingTxQueue[k]); + prStaRec->aprTargetQueue[k] + = &prStaRec->arPendingTxQueue[k]; + } + + prStaRec->ucAmsduEnBitmap = 0; + prStaRec->ucMaxMpduCount = 0; + prStaRec->u4MaxMpduLen = 0; + prStaRec->u4MinMpduLen = 0; + +#if DSCP_SUPPORT + qosMapSetInit(prStaRec); +#endif + break; + } + } + + /* Sync to chip to allocate WTBL resource */ + if (i < CFG_STA_REC_NUM) { + COPY_MAC_ADDR(prStaRec->aucMacAddr, pucMacAddr); + if (secPrivacySeekForEntry(prAdapter, prStaRec)) + cnmStaSendUpdateCmd(prAdapter, prStaRec, NULL, FALSE); +#if DBG + else { + prStaRec->fgIsInUse = FALSE; + prStaRec = NULL; + ASSERT(FALSE); + } +#endif + } else { + prStaRec = NULL; + } + + return prStaRec; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void cnmStaRecFree(struct ADAPTER *prAdapter, struct STA_RECORD *prStaRec) +{ + uint8_t ucStaRecIndex, ucBssIndex; + + ASSERT(prAdapter); + + if (!prStaRec) + return; + + log_dbg(RSN, INFO, "cnmStaRecFree %d\n", prStaRec->ucIndex); + + ucStaRecIndex = prStaRec->ucIndex; + ucBssIndex = prStaRec->ucBssIndex; + + nicFreePendingTxMsduInfo(prAdapter, prStaRec->ucWlanIndex, + MSDU_REMOVE_BY_WLAN_INDEX); + + cnmStaRoutinesForAbort(prAdapter, prStaRec); + + cnmStaSendRemoveCmd(prAdapter, STA_REC_CMD_ACTION_STA, + ucStaRecIndex, ucBssIndex); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +static void cnmStaRoutinesForAbort(struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec) +{ + ASSERT(prAdapter); + + if (!prStaRec) + return; + + /* To do: free related resources, e.g. timers, buffers, etc */ + cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); + cnmTimerStopTimer(prAdapter, &prStaRec->rDeauthTxDoneTimer); + prStaRec->fgTransmitKeyExist = FALSE; + + prStaRec->fgSetPwrMgtBit = FALSE; + + if (prStaRec->pucAssocReqIe) { + kalMemFree(prStaRec->pucAssocReqIe, + VIR_MEM_TYPE, prStaRec->u2AssocReqIeLen); + prStaRec->pucAssocReqIe = NULL; + prStaRec->u2AssocReqIeLen = 0; + } + + qmDeactivateStaRec(prAdapter, prStaRec); + + /* Update the driver part table setting */ + secPrivacyFreeSta(prAdapter, prStaRec); + + prStaRec->fgIsInUse = FALSE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void cnmStaFreeAllStaByNetwork(struct ADAPTER *prAdapter, uint8_t ucBssIndex, + uint8_t ucStaRecIndexExcluded) +{ +#if CFG_ENABLE_WIFI_DIRECT + struct BSS_INFO *prBssInfo; +#endif + struct STA_RECORD *prStaRec; + uint16_t i; + enum ENUM_STA_REC_CMD_ACTION eAction; + + if (ucBssIndex > prAdapter->ucHwBssIdNum) + return; + + for (i = 0; i < CFG_STA_REC_NUM; i++) { + prStaRec = (struct STA_RECORD *) &prAdapter->arStaRec[i]; + + if (prStaRec->fgIsInUse && prStaRec->ucBssIndex == ucBssIndex + && i != ucStaRecIndexExcluded) + cnmStaRoutinesForAbort(prAdapter, prStaRec); + } /* end of for loop */ + + if (ucStaRecIndexExcluded < CFG_STA_REC_NUM) + eAction = STA_REC_CMD_ACTION_BSS_EXCLUDE_STA; + else + eAction = STA_REC_CMD_ACTION_BSS; + + cnmStaSendRemoveCmd(prAdapter, + eAction, + ucStaRecIndexExcluded, ucBssIndex); + +#if CFG_ENABLE_WIFI_DIRECT + /* To do: Confirm if it is invoked here or other location, but it should + * be invoked after state sync of STA_REC + * Update system operation parameters for AP mode + */ + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + if (prAdapter->fgIsP2PRegistered + && prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) { + rlmUpdateParamsForAP(prAdapter, prBssInfo, FALSE); + } +#endif +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +struct STA_RECORD *cnmGetStaRecByIndex(struct ADAPTER *prAdapter, + uint8_t ucIndex) +{ + struct STA_RECORD *prStaRec; + + ASSERT(prAdapter); + + if (ucIndex < CFG_STA_REC_NUM) + prStaRec = &prAdapter->arStaRec[ucIndex]; + else + prStaRec = NULL; + + if (prStaRec && prStaRec->fgIsInUse == FALSE) + prStaRec = NULL; + + return prStaRec; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Get STA_RECORD_T by Peer MAC Address(Usually TA). + * + * @param[in] pucPeerMacAddr Given Peer MAC Address. + * + * @retval Pointer to STA_RECORD_T, if found. NULL, if not found + */ +/*----------------------------------------------------------------------------*/ +struct STA_RECORD *cnmGetStaRecByAddress(struct ADAPTER *prAdapter, + uint8_t ucBssIndex, uint8_t *pucPeerMacAddr) +{ + struct STA_RECORD *prStaRec; + uint16_t i; + + ASSERT(prAdapter); + + if (!pucPeerMacAddr) + return NULL; + + for (i = 0; i < CFG_STA_REC_NUM; i++) { + prStaRec = &prAdapter->arStaRec[i]; + + if (prStaRec->fgIsInUse + && prStaRec->ucBssIndex == ucBssIndex + && EQUAL_MAC_ADDR( + prStaRec->aucMacAddr, pucPeerMacAddr)) { + break; + } + } + + return (i < CFG_STA_REC_NUM) ? prStaRec : NULL; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will change the ucStaState of STA_RECORD_T and also do + * event indication to HOST to sync the STA_RECORD_T in driver. + * + * @param[in] prStaRec Pointer to the STA_RECORD_T + * @param[in] u4NewState New STATE to change. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void cnmStaRecChangeState(struct ADAPTER *prAdapter, struct STA_RECORD *prStaRec + , uint8_t ucNewState) +{ + u_int8_t fgNeedResp; + + if (!prAdapter) + return; + + if (!prStaRec) { + log_dbg(MEM, WARN, "%s: StaRec is NULL, skip!\n", __func__); + return; + } + + if (!prStaRec->fgIsInUse) { + log_dbg(MEM, WARN, "%s: StaRec[%u] is not in use, skip!\n", + __func__, prStaRec->ucIndex); + return; + } + + /* Do nothing when following state transitions happen, + * other 6 conditions should be sync to FW, including 1-->1, 3-->3 + */ + if ((ucNewState == STA_STATE_2 && prStaRec->ucStaState != STA_STATE_3) + || (ucNewState == STA_STATE_1 + && prStaRec->ucStaState == STA_STATE_2)) { + prStaRec->ucStaState = ucNewState; + return; + } + + fgNeedResp = FALSE; + if (ucNewState == STA_STATE_3) { + /* secFsmEventStart(prAdapter, prStaRec); */ + if (ucNewState != prStaRec->ucStaState) { + fgNeedResp = TRUE; + cnmDumpStaRec(prAdapter, prStaRec->ucIndex); + } + } else { + if (ucNewState != prStaRec->ucStaState + && prStaRec->ucStaState == STA_STATE_3) + qmDeactivateStaRec(prAdapter, prStaRec); + fgNeedResp = FALSE; + } + prStaRec->ucStaState = ucNewState; + + cnmStaSendUpdateCmd(prAdapter, prStaRec, NULL, fgNeedResp); + +#if 1 /* Marked for MT6630 */ +#if CFG_ENABLE_WIFI_DIRECT + /* To do: Confirm if it is invoked here or other location, but it should + * be invoked after state sync of STA_REC + * Update system operation parameters for AP mode + */ + if (prAdapter->fgIsP2PRegistered && (IS_STA_IN_P2P(prStaRec))) { + struct BSS_INFO *prBssInfo; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prStaRec->ucBssIndex); + + if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) + rlmUpdateParamsForAP(prAdapter, prBssInfo, FALSE); + } +#endif +#endif +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief + * + * @param[in] + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +static void cnmStaRecHandleEventPkt(struct ADAPTER *prAdapter, + struct CMD_INFO *prCmdInfo, uint8_t *pucEventBuf) +{ + struct EVENT_ACTIVATE_STA_REC *prEventContent; + struct STA_RECORD *prStaRec; + + prEventContent = (struct EVENT_ACTIVATE_STA_REC *) pucEventBuf; + prStaRec = cnmGetStaRecByIndex(prAdapter, prEventContent->ucStaRecIdx); + + if (prStaRec && prStaRec->ucStaState == STA_STATE_3 && + !kalMemCmp(&prStaRec->aucMacAddr[0], + &prEventContent->aucMacAddr[0], MAC_ADDR_LEN)) { + + qmActivateStaRec(prAdapter, prStaRec); + } + +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief + * + * @param[in] + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void cnmStaSendUpdateCmd(struct ADAPTER *prAdapter, struct STA_RECORD *prStaRec, + struct TXBF_PFMU_STA_INFO *prTxBfPfmuStaInfo, u_int8_t fgNeedResp) +{ + struct CMD_UPDATE_STA_RECORD *prCmdContent; + uint32_t rStatus; + + if (!prAdapter) + return; + + if (!prStaRec) { + log_dbg(MEM, WARN, "%s: StaRec is NULL, skip!\n", __func__); + return; + } + + if (!prStaRec->fgIsInUse) { + log_dbg(MEM, WARN, "%s: StaRec[%u] is not in use, skip!\n", + __func__, prStaRec->ucIndex); + return; + } + + /* To do: come out a mechanism to limit one STA_REC sync once for AP + * mode to avoid buffer empty case when many STAs are associated + * simultaneously. + */ + + /* To do: how to avoid 2 times of allocated memory. Use Stack? + * One is here, the other is in wlanSendQueryCmd() + */ + prCmdContent = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, + sizeof(struct CMD_UPDATE_STA_RECORD)); + + /* To do: exception handle */ + if (!prCmdContent) { + log_dbg(MEM, WARN, "%s: CMD_ID_UPDATE_STA_RECORD command allocation failed\n", + __func__); + + return; + } + + /* Reset command buffer */ + kalMemZero(prCmdContent, sizeof(struct CMD_UPDATE_STA_RECORD)); + + if (prTxBfPfmuStaInfo) { + memcpy(&prCmdContent->u2PfmuId, prTxBfPfmuStaInfo, + sizeof(struct TXBF_PFMU_STA_INFO)); + } + + prCmdContent->ucStaIndex = prStaRec->ucIndex; + prCmdContent->ucStaType = (uint8_t) prStaRec->eStaType; + kalMemCopy(&prCmdContent->aucMacAddr[0], &prStaRec->aucMacAddr[0], + MAC_ADDR_LEN); + prCmdContent->u2AssocId = prStaRec->u2AssocId; + prCmdContent->u2ListenInterval = prStaRec->u2ListenInterval; + prCmdContent->ucBssIndex = prStaRec->ucBssIndex; + + prCmdContent->ucDesiredPhyTypeSet = prStaRec->ucDesiredPhyTypeSet; + prCmdContent->u2DesiredNonHTRateSet = prStaRec->u2DesiredNonHTRateSet; + prCmdContent->u2BSSBasicRateSet = prStaRec->u2BSSBasicRateSet; + prCmdContent->ucMcsSet = prStaRec->ucMcsSet; + prCmdContent->ucSupMcs32 = (uint8_t) prStaRec->fgSupMcs32; + prCmdContent->u2HwDefaultFixedRateCode + = prStaRec->u2HwDefaultFixedRateCode; + + /* Size is SUP_MCS_RX_BITMASK_OCTET_NUM */ + kalMemCopy(prCmdContent->aucRxMcsBitmask, prStaRec->aucRxMcsBitmask, + sizeof(prCmdContent->aucRxMcsBitmask)); + prCmdContent->u2RxHighestSupportedRate + = prStaRec->u2RxHighestSupportedRate; + prCmdContent->u4TxRateInfo = prStaRec->u4TxRateInfo; + + prCmdContent->u2HtCapInfo = prStaRec->u2HtCapInfo; + prCmdContent->ucNeedResp = (uint8_t) fgNeedResp; + +#if !CFG_SLT_SUPPORT + if (prAdapter->rWifiVar.eRateSetting != FIXED_RATE_NONE) { + /* override rate configuration */ + nicUpdateRateParams(prAdapter, + prAdapter->rWifiVar.eRateSetting, + &(prCmdContent->ucDesiredPhyTypeSet), + &(prCmdContent->u2DesiredNonHTRateSet), + &(prCmdContent->u2BSSBasicRateSet), + &(prCmdContent->ucMcsSet), + &(prCmdContent->ucSupMcs32), + &(prCmdContent->u2HtCapInfo)); + } +#endif + + prCmdContent->ucIsQoS = prStaRec->fgIsQoS; + prCmdContent->ucIsUapsdSupported = prStaRec->fgIsUapsdSupported; + prCmdContent->ucStaState = prStaRec->ucStaState; + prCmdContent->ucAmpduParam = prStaRec->ucAmpduParam; + prCmdContent->u2HtExtendedCap = prStaRec->u2HtExtendedCap; + prCmdContent->u4TxBeamformingCap = prStaRec->u4TxBeamformingCap; + prCmdContent->ucAselCap = prStaRec->ucAselCap; + prCmdContent->ucRCPI = prStaRec->ucRCPI; + + prCmdContent->u4VhtCapInfo = prStaRec->u4VhtCapInfo; + prCmdContent->u2VhtRxMcsMap = prStaRec->u2VhtRxMcsMap; + prCmdContent->u2VhtRxHighestSupportedDataRate + = prStaRec->u2VhtRxHighestSupportedDataRate; + prCmdContent->u2VhtTxMcsMap = prStaRec->u2VhtTxMcsMap; + prCmdContent->u2VhtTxHighestSupportedDataRate + = prStaRec->u2VhtTxHighestSupportedDataRate; + prCmdContent->ucVhtOpMode = prStaRec->ucVhtOpMode; + + prCmdContent->ucUapsdAc + = prStaRec->ucBmpTriggerAC | (prStaRec->ucBmpDeliveryAC << 4); + prCmdContent->ucUapsdSp = prStaRec->ucUapsdSp; + + prCmdContent->ucWlanIndex = prStaRec->ucWlanIndex; + prCmdContent->ucBMCWlanIndex = WTBL_RESERVED_ENTRY; + + prCmdContent->ucTrafficDataType = prStaRec->ucTrafficDataType; + prCmdContent->ucTxGfMode = prStaRec->ucTxGfMode; + prCmdContent->ucTxSgiMode = prStaRec->ucTxSgiMode; + prCmdContent->ucTxStbcMode = prStaRec->ucTxStbcMode; + prCmdContent->u4FixedPhyRate = prStaRec->u4FixedPhyRate; + prCmdContent->u2MaxLinkSpeed = prStaRec->u2MaxLinkSpeed; + prCmdContent->u2MinLinkSpeed = prStaRec->u2MinLinkSpeed; + prCmdContent->u4Flags = prStaRec->u4Flags; +#if CFG_SUPPORT_MTK_SYNERGY + if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucMtkOui)) { + if (IS_FEATURE_ENABLED( + prAdapter->rWifiVar.ucGbandProbe256QAM)) { + prCmdContent->u4Flags + |= MTK_SYNERGY_CAP_SUPPORT_24G_MCS89_PROBING; + } + } +#endif + prCmdContent->ucTxAmpdu = prAdapter->rWifiVar.ucAmpduTx; + prCmdContent->ucRxAmpdu = prAdapter->rWifiVar.ucAmpduRx; + + /* AMSDU in AMPDU global configuration */ + prCmdContent->ucTxAmsduInAmpdu = prAdapter->rWifiVar.ucAmsduInAmpduTx; + prCmdContent->ucRxAmsduInAmpdu = prAdapter->rWifiVar.ucAmsduInAmpduRx; +#if (CFG_SUPPORT_802_11AX == 1) + /* prStaRec->ucDesiredPhyTypeSet firm in */ + /* bssDetermineStaRecPhyTypeSet() in advance */ + if (prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_SET_802_11AX) { + /* HE peer AMSDU in AMPDU configuration */ + prCmdContent->ucTxAmsduInAmpdu &= + prAdapter->rWifiVar.ucHeAmsduInAmpduTx; + prCmdContent->ucRxAmsduInAmpdu &= + prAdapter->rWifiVar.ucHeAmsduInAmpduRx; + } else +#endif + if ((prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_SET_802_11AC) || + (prStaRec->u4Flags & MTK_SYNERGY_CAP_SUPPORT_24G_MCS89)) { + /* VHT pear AMSDU in AMPDU configuration */ + prCmdContent->ucTxAmsduInAmpdu + &= prAdapter->rWifiVar.ucVhtAmsduInAmpduTx; + prCmdContent->ucRxAmsduInAmpdu + &= prAdapter->rWifiVar.ucVhtAmsduInAmpduRx; + } else if (prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_SET_802_11N) { + /* HT peer AMSDU in AMPDU configuration */ + prCmdContent->ucTxAmsduInAmpdu + &= prAdapter->rWifiVar.ucHtAmsduInAmpduTx; + prCmdContent->ucRxAmsduInAmpdu + &= prAdapter->rWifiVar.ucHtAmsduInAmpduRx; + } + + prCmdContent->u4TxMaxAmsduInAmpduLen + = prAdapter->rWifiVar.u4TxMaxAmsduInAmpduLen; +#if (CFG_SUPPORT_802_11AX == 1) + if (prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_SET_802_11AX) { + prCmdContent->rBaSize.rHeBaSize.u2RxBaSize = + prAdapter->rWifiVar.u2RxHeBaSize; + prCmdContent->rBaSize.rHeBaSize.u2TxBaSize = + prAdapter->rWifiVar.u2TxHeBaSize; + } else +#endif + { + prCmdContent->rBaSize.rHtVhtBaSize.ucTxBaSize + = prAdapter->rWifiVar.ucTxBaSize; + + if (prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_SET_802_11AC) + prCmdContent->rBaSize.rHtVhtBaSize.ucTxBaSize + = prAdapter->rWifiVar.ucRxVhtBaSize; + else + prCmdContent->rBaSize.rHeBaSize.u2TxBaSize + = prAdapter->rWifiVar.ucRxHtBaSize; + } + + /* RTS Policy */ + if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucSigTaRts)) { + if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucDynBwRts)) + prCmdContent->ucRtsPolicy = RTS_POLICY_DYNAMIC_BW; + else + prCmdContent->ucRtsPolicy = RTS_POLICY_STATIC_BW; + } else + prCmdContent->ucRtsPolicy = RTS_POLICY_LEGACY; + +#if (CFG_SUPPORT_802_11AX == 1) + if (fgEfuseCtrlAxOn == 1) { + cnmStaRecCmdHeContentFill(prStaRec, prCmdContent); + } +#endif + + log_dbg(REQ, TRACE, "Update StaRec[%u] WIDX[%u] State[%u] Type[%u] BssIdx[%u] AID[%u]\n", + prCmdContent->ucStaIndex, + prCmdContent->ucWlanIndex, + prCmdContent->ucStaState, + prCmdContent->ucStaType, + prCmdContent->ucBssIndex, + prCmdContent->u2AssocId); + + log_dbg(REQ, TRACE, "Update StaRec[%u] QoS[%u] UAPSD[%u]\n", + prCmdContent->ucStaIndex, + prCmdContent->ucIsQoS, + prCmdContent->ucIsUapsdSupported); + + rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ + CMD_ID_UPDATE_STA_RECORD, /* ucCID */ + TRUE, /* fgSetQuery */ + fgNeedResp, /* fgNeedResp */ + FALSE, /* fgIsOid */ + fgNeedResp ? cnmStaRecHandleEventPkt : NULL, NULL, + /* pfCmdTimeoutHandler */ + sizeof(struct CMD_UPDATE_STA_RECORD), /* u4SetQueryInfoLen */ + (uint8_t *) prCmdContent, /* pucInfoBuffer */ + NULL, /* pvSetQueryBuffer */ + 0 /* u4SetQueryBufferLen */ + ); + + cnmMemFree(prAdapter, prCmdContent); + + if (rStatus != WLAN_STATUS_PENDING) { + log_dbg(MEM, WARN, + "%s: CMD_ID_UPDATE_STA_RECORD result 0x%08x\n", + __func__, rStatus); + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief + * + * @param[in] + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +static void +cnmStaSendRemoveCmd(struct ADAPTER *prAdapter, + enum ENUM_STA_REC_CMD_ACTION eActionType, + uint8_t ucStaRecIndex, uint8_t ucBssIndex) +{ + struct CMD_REMOVE_STA_RECORD rCmdContent; + uint32_t rStatus; + + ASSERT(prAdapter); + + rCmdContent.ucActionType = (uint8_t) eActionType; + rCmdContent.ucStaIndex = ucStaRecIndex; + rCmdContent.ucBssIndex = ucBssIndex; + rCmdContent.ucReserved = 0; + + rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ + CMD_ID_REMOVE_STA_RECORD, /* ucCID */ + TRUE, /* fgSetQuery */ + FALSE, /* fgNeedResp */ + FALSE, /* fgIsOid */ + NULL, /* pfCmdDoneHandler */ + NULL, /* pfCmdTimeoutHandler */ + sizeof(struct CMD_REMOVE_STA_RECORD), /* u4SetQueryInfoLen */ + (uint8_t *) &rCmdContent, /* pucInfoBuffer */ + NULL, /* pvSetQueryBuffer */ + 0 /* u4SetQueryBufferLen */ + ); + + if (rStatus != WLAN_STATUS_PENDING) { + log_dbg(MEM, WARN, + "%s: CMD_ID_REMOVE_STA_RECORD result 0x%08x\n", + __func__, rStatus); + } +} + +uint8_t *cnmStaRecGetTypeString(enum ENUM_STA_TYPE eStaType) +{ + uint8_t *pucTypeString = NULL; + + if (eStaType & STA_TYPE_LEGACY_MASK) + pucTypeString = apucStaRecType[STA_TYPE_LEGACY_INDEX]; + if (eStaType & STA_TYPE_P2P_MASK) + pucTypeString = apucStaRecType[STA_TYPE_P2P_INDEX]; + if (eStaType & STA_TYPE_BOW_MASK) + pucTypeString = apucStaRecType[STA_TYPE_BOW_INDEX]; + + return pucTypeString; +} + +uint8_t *cnmStaRecGetRoleString(enum ENUM_STA_TYPE eStaType) +{ + uint8_t *pucRoleString = NULL; + + if (eStaType & STA_TYPE_ADHOC_MASK) { + pucRoleString = apucStaRecRole[ + STA_ROLE_ADHOC_INDEX - STA_ROLE_BASE_INDEX]; + } + if (eStaType & STA_TYPE_CLIENT_MASK) { + pucRoleString = apucStaRecRole[ + STA_ROLE_CLIENT_INDEX - STA_ROLE_BASE_INDEX]; + } + if (eStaType & STA_TYPE_AP_MASK) { + pucRoleString = apucStaRecRole[ + STA_ROLE_AP_INDEX - STA_ROLE_BASE_INDEX]; + } + if (eStaType & STA_TYPE_DLS_MASK) { + pucRoleString = apucStaRecRole[ + STA_ROLE_DLS_INDEX - STA_ROLE_BASE_INDEX]; + } + + return pucRoleString; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief + * + * @param[in] + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void cnmDumpStaRec(IN struct ADAPTER *prAdapter, IN uint8_t ucStaRecIdx) +{ + uint8_t ucWTEntry; + uint32_t i; + struct BSS_INFO *prBssInfo; + struct STA_RECORD *prStaRec; + + DEBUGFUNC("cnmDumpStaRec"); + + prStaRec = cnmGetStaRecByIndex(prAdapter, ucStaRecIdx); + + if (!prStaRec) { + log_dbg(SW4, INFO, "Invalid StaRec index[%u], skip dump!\n", + ucStaRecIdx); + return; + } + + ucWTEntry = prStaRec->ucWlanIndex; + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex); + + ASSERT(prBssInfo); + + log_dbg(SW4, INFO, "============= DUMP STA[%u] ===========\n", + ucStaRecIdx); + /* [1]STA_IDX [2]BSS_IDX + * [3]MAC [4]TYPE + * [5]WTBL [6]USED + * [7]State [8]QoS + * [9]HT/VHT [10]AID + * [11]WMM [12]UAPSD + * [13]SEC [14]PhyTypeSet + * [15]Desired [16]NonHtBasic + * [17]BssBasic [18]Operational + * [19]DesiredNonHT [20]Df FixedRate + * [21]HT Cap [22]ExtCap + * [23]BeemCap [24]MCS + * [25]MCS32 [26]VHT Cap + * [27]TxMCS [28]RxMCS + * [29]VhtOpMode [30]RCPI + * [31]InPS [32]TxAllowed + * [33]KeyRdy [34]AMPDU + * [35]TxQLEN TC [36]BMP AC Delivery/Trigger + * [37]FreeQuota:Total [38]Delivery/NonDelivery + * [39]aucRxMcsBitmask + */ + + log_dbg(SW4, INFO, "[1][%u],[2][%u],[3][" MACSTR + "],[4][%s %s],[5][%u],[6][%u],[7][%u],[8][%u],[9][%u/%u],[10][%u]\n", + prStaRec->ucIndex, + prStaRec->ucBssIndex, + MAC2STR(prStaRec->aucMacAddr), + cnmStaRecGetTypeString(prStaRec->eStaType), + cnmStaRecGetRoleString(prStaRec->eStaType), + ucWTEntry, prStaRec->fgIsInUse, + prStaRec->ucStaState, prStaRec->fgIsQoS, + (prStaRec->ucDesiredPhyTypeSet + & PHY_TYPE_SET_802_11N) ? TRUE : FALSE, + (prStaRec->ucDesiredPhyTypeSet + & PHY_TYPE_SET_802_11AC) ? TRUE : FALSE, + prStaRec->u2AssocId); + + log_dbg(SW4, INFO, "[11][%u],[12][%u],[13][%u],[14][0x%x],[15][0x%x],[16][0x%x],[17][0x%x],[18][0x%x],[19][0x%x],[20][0x%x]\n", + prStaRec->fgIsWmmSupported, + prStaRec->fgIsUapsdSupported, + secIsProtectedBss(prAdapter, prBssInfo), + prBssInfo->ucPhyTypeSet, + prStaRec->ucDesiredPhyTypeSet, + prStaRec->ucNonHTBasicPhyType, + prBssInfo->u2BSSBasicRateSet, + prStaRec->u2OperationalRateSet, + prStaRec->u2DesiredNonHTRateSet, + prStaRec->u2HwDefaultFixedRateCode); + + log_dbg(SW4, INFO, "[21][0x%x],[22][0x%x],[23][0x%x],[24][0x%x],[25][%u],[26][0x%x],[27][0x%x],[28][0x%x],[29][0x%x],[30][%u]\n", + prStaRec->u2HtCapInfo, + prStaRec->u2HtExtendedCap, + prStaRec->u4TxBeamformingCap, + prStaRec->ucMcsSet, + prStaRec->fgSupMcs32, + prStaRec->u4VhtCapInfo, + prStaRec->u2VhtTxMcsMap, + prStaRec->u2VhtRxMcsMap, + prStaRec->ucVhtOpMode, + prStaRec->ucRCPI); + + log_dbg(SW4, INFO, "[31][%u],[32][%u],[33][%u],[34][%u/%u],[35][%u:%u:%u:%u],[36][%x/%x],[37][%u],[38][%u/%u],[39][0x%x][0x%x]\n", + prStaRec->fgIsInPS, + prStaRec->fgIsTxAllowed, + prStaRec->fgIsTxKeyReady, + prStaRec->fgTxAmpduEn, + prStaRec->fgRxAmpduEn, + prStaRec->aprTargetQueue[0]->u4NumElem, + prStaRec->aprTargetQueue[1]->u4NumElem, + prStaRec->aprTargetQueue[2]->u4NumElem, + prStaRec->aprTargetQueue[3]->u4NumElem, + prStaRec->ucBmpDeliveryAC, + prStaRec->ucBmpTriggerAC, + prStaRec->ucFreeQuota, + prStaRec->ucFreeQuotaForDelivery, + prStaRec->ucFreeQuotaForNonDelivery, + prStaRec->aucRxMcsBitmask[0], + prStaRec->aucRxMcsBitmask[1]); + + for (i = 0; i < CFG_RX_MAX_BA_TID_NUM; i++) { + if (prStaRec->aprRxReorderParamRefTbl[i]) { + log_dbg(SW4, INFO, "TID[%u],Valid[%u],WinStart/End[%u/%u],WinSize[%u],ReOrderQueLen[%u],Bubble Exist[%u],SN[%u]\n", + prStaRec->aprRxReorderParamRefTbl[i] + ->ucTid, + prStaRec->aprRxReorderParamRefTbl[i] + ->fgIsValid, + prStaRec->aprRxReorderParamRefTbl[i] + ->u2WinStart, + prStaRec->aprRxReorderParamRefTbl[i] + ->u2WinEnd, + prStaRec->aprRxReorderParamRefTbl[i] + ->u2WinSize, + prStaRec->aprRxReorderParamRefTbl[i] + ->rReOrderQue.u4NumElem, + prStaRec->aprRxReorderParamRefTbl[i] + ->fgHasBubble, + prStaRec->aprRxReorderParamRefTbl[i] + ->u2FirstBubbleSn); + } + } + log_dbg(SW4, INFO, "============= DUMP END ===========\n"); +} + +uint32_t cnmDumpMemoryStatus(IN struct ADAPTER *prAdapter, IN uint8_t *pucBuf, + IN uint32_t u4Max) +{ + uint32_t u4Len = 0; +#if CFG_DBG_MGT_BUF + struct BUF_INFO *prBufInfo; + + LOGBUF(pucBuf, u4Max, u4Len, "\n"); + LOGBUF(pucBuf, u4Max, u4Len, + "============= DUMP Memory Status =============\n"); + + LOGBUF(pucBuf, u4Max, u4Len, + "Dynamic alloc OS memory count: alloc[%u] free[%u]\n", + prAdapter->u4MemAllocDynamicCount, + prAdapter->u4MemFreeDynamicCount); + + prBufInfo = &prAdapter->rMsgBufInfo; + + LOGBUF(pucBuf, u4Max, u4Len, + "MSG memory count: alloc[%u] free[%u] null[%u] bitmap[0x%08x]\n" + , + prBufInfo->u4AllocCount, + prBufInfo->u4FreeCount, + prBufInfo->u4AllocNullCount, + (uint32_t) prBufInfo->rFreeBlocksBitmap); + + prBufInfo = &prAdapter->rMgtBufInfo; + + LOGBUF(pucBuf, u4Max, u4Len, + "MGT memory count: alloc[%u] free[%u] null[%u] bitmap[0x%08x]\n" + , + prBufInfo->u4AllocCount, + prBufInfo->u4FreeCount, + prBufInfo->u4AllocNullCount, + (uint32_t) prBufInfo->rFreeBlocksBitmap); + + LOGBUF(pucBuf, u4Max, u4Len, "============= DUMP END =============\n"); + +#endif + + return u4Len; +} + +#if CFG_SUPPORT_TDLS +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to add a peer record. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * \param[out] pvQueryBuf A pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the call + * failed due to invalid length of the query buffer, + * returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t /* TDLS_STATUS, prStaRec->ucNetTypeIndex */ +cnmPeerAdd(struct ADAPTER *prAdapter, void *pvSetBuffer, + uint32_t u4SetBufferLen, uint32_t *pu4SetInfoLen) +{ + struct CMD_PEER_ADD *prCmd; + struct BSS_INFO *prBssInfo; + struct STA_RECORD *prStaRec, *prStaRecOfAp; + + /* sanity check */ + + if ((prAdapter == NULL) || (pvSetBuffer == NULL) + || (pu4SetInfoLen == NULL)) + return TDLS_STATUS_FAIL; + + /* init */ + *pu4SetInfoLen = sizeof(struct CMD_PEER_ADD); + prCmd = (struct CMD_PEER_ADD *) pvSetBuffer; + + prBssInfo + = GET_BSS_INFO_BY_INDEX(prAdapter, prCmd->ucBssIdx); + if (prBssInfo == NULL) { + log_dbg(MEM, ERROR, "prBssInfo %d is NULL!\n" + , prCmd->ucBssIdx); + return TDLS_STATUS_FAIL; + } + + prStaRec = cnmGetStaRecByAddress(prAdapter, + (uint8_t) prBssInfo->ucBssIndex, + prCmd->aucPeerMac); + + if (prStaRec == NULL) { + prStaRec = + cnmStaRecAlloc(prAdapter, STA_TYPE_DLS_PEER, + (uint8_t) prBssInfo->ucBssIndex, + prCmd->aucPeerMac); + + if (prStaRec == NULL) + return TDLS_STATUS_RESOURCES; + + if (prBssInfo->ucBssIndex) + prStaRec->ucBssIndex = prBssInfo->ucBssIndex; + + /* init the prStaRec */ + /* prStaRec will be zero first in cnmStaRecAlloc() */ + COPY_MAC_ADDR(prStaRec->aucMacAddr, prCmd->aucPeerMac); + + prStaRec->u2BSSBasicRateSet = prBssInfo->u2BSSBasicRateSet; + prStaRec->ucDesiredPhyTypeSet + = prAdapter->rWifiVar.ucAvailablePhyTypeSet; + prStaRec->u2DesiredNonHTRateSet + = prAdapter->rWifiVar.ucAvailablePhyTypeSet; + + prStaRec->u2OperationalRateSet + = prBssInfo->u2OperationalRateSet; + prStaRec->ucPhyTypeSet = prBssInfo->ucPhyTypeSet; + prStaRec->eStaType = prCmd->eStaType; + + /* align setting with AP */ + prStaRecOfAp = prBssInfo->prStaRecOfAP; + if (prStaRecOfAp) { + prStaRec->u2DesiredNonHTRateSet + = prStaRecOfAp->u2DesiredNonHTRateSet; + } + + /* Init lowest rate to prevent CCK in 5G band */ + nicTxUpdateStaRecDefaultRate(prAdapter, prStaRec); + + /* Better to change state here, not at TX Done */ + cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); + + } else { + if ((prStaRec->ucStaState > STA_STATE_1) + && (IS_DLS_STA(prStaRec))) { + /* TODO: Teardown the peer */ + cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); + } + } + return TDLS_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to update a peer record. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * \param[out] pvQueryBuf A pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number of + * bytes written into the query buffer. If the call + * failed due to invalid length of the query buffer, + * returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t /* TDLS_STATUS */ +cnmPeerUpdate(struct ADAPTER *prAdapter, void *pvSetBuffer, + uint32_t u4SetBufferLen, uint32_t *pu4SetInfoLen) +{ + + struct CMD_PEER_UPDATE *prCmd; + struct BSS_INFO *prBssInfo; + struct STA_RECORD *prStaRec; + uint8_t ucNonHTPhyTypeSet; + + uint16_t u2OperationalRateSet = 0; + + uint8_t ucRate; + uint16_t i, j; + + /* sanity check */ + if ((!prAdapter) || (!pvSetBuffer) || (!pu4SetInfoLen)) + return TDLS_STATUS_FAIL; + + /* init */ + *pu4SetInfoLen = sizeof(struct CMD_PEER_ADD); + prCmd = (struct CMD_PEER_UPDATE *) pvSetBuffer; + + prBssInfo + = GET_BSS_INFO_BY_INDEX(prAdapter, prCmd->ucBssIdx); + + if (prBssInfo == NULL) { + log_dbg(MEM, ERROR, "prBssInfo %d is NULL!\n" + , prCmd->ucBssIdx); + return TDLS_STATUS_FAIL; + } + prStaRec = cnmGetStaRecByAddress(prAdapter, + (uint8_t) prBssInfo->ucBssIndex, + prCmd->aucPeerMac); + + if ((!prStaRec) || !(prStaRec->fgIsInUse)) + return TDLS_STATUS_FAIL; + + if (!IS_DLS_STA(prStaRec)) + return TDLS_STATUS_FAIL; + + if (prBssInfo) { + if (prBssInfo->ucBssIndex) + prStaRec->ucBssIndex = prBssInfo->ucBssIndex; + } + + /* update the record join time. */ + GET_CURRENT_SYSTIME(&prStaRec->rUpdateTime); + + /* update Station Record - Status/Reason Code */ + prStaRec->u2StatusCode = prCmd->u2StatusCode; + prStaRec->u2AssocId = 0; /* no use */ + prStaRec->u2ListenInterval = 0; /* unknown */ + prStaRec->fgIsQoS = TRUE; + prStaRec->fgIsUapsdSupported + = ((1 << 4) & prCmd->aucExtCap[3]) ? TRUE : FALSE; + prStaRec->u4TxBeamformingCap = 0; /* no use */ + prStaRec->ucAselCap = 0; /* no use */ + prStaRec->ucRCPI = 120; + prStaRec->ucBmpTriggerAC = prCmd->UapsdBitmap; + prStaRec->ucBmpDeliveryAC = prCmd->UapsdBitmap; + prStaRec->ucUapsdSp = prCmd->UapsdMaxSp; + prStaRec->eStaType = prCmd->eStaType; + + /* ++ support rate */ + if (prCmd->u2SupRateLen) { + for (i = 0; i < prCmd->u2SupRateLen; i++) { + if (prCmd->aucSupRate[i]) { + ucRate = prCmd->aucSupRate[i] & RATE_MASK; + /* Search all valid data rates */ + for (j = 0; j < sizeof(aucValidDataRate) + / sizeof(uint8_t); j++) { + if (ucRate == aucValidDataRate[j]) { + u2OperationalRateSet |= BIT(j); + break; + } + } + } + + } + + prStaRec->u2OperationalRateSet = u2OperationalRateSet; + prStaRec->u2BSSBasicRateSet = prBssInfo->u2BSSBasicRateSet; + + /* 4 <5> PHY type setting */ + + prStaRec->ucPhyTypeSet = 0; + + if (prBssInfo->eBand == BAND_2G4) { + if (prCmd->fgIsSupHt) + prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_HT; + + /* if not 11n only */ + if (!(prStaRec->u2BSSBasicRateSet + & RATE_SET_BIT_HT_PHY)) { + /* check if support 11g */ + if ((prStaRec->u2OperationalRateSet + & RATE_SET_OFDM)) { + prStaRec->ucPhyTypeSet + |= PHY_TYPE_BIT_ERP; + } + + /* if not 11g only */ + if (!(prStaRec->u2BSSBasicRateSet + & RATE_SET_OFDM)) { + /* check if support 11b */ + if ((prStaRec->u2OperationalRateSet + & RATE_SET_HR_DSSS)) { + prStaRec->ucPhyTypeSet + |= PHY_TYPE_BIT_HR_DSSS; + } + } + } + } else { + if (prCmd->rVHtCap.u2CapInfo) + prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_VHT; + + if (prCmd->fgIsSupHt) + prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_HT; + + /* if not 11n only */ + if (!(prStaRec->u2BSSBasicRateSet + & RATE_SET_BIT_HT_PHY)) { + /* Support 11a definitely */ + prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_OFDM; + } + } + + if (IS_STA_IN_AIS(prStaRec)) { + struct CONNECTION_SETTINGS *prConnSettings; + enum ENUM_WEP_STATUS eEncStatus; + + prConnSettings = + aisGetConnSettings(prAdapter, + prStaRec->ucBssIndex); + + eEncStatus = prConnSettings->eEncStatus; + + if (!((eEncStatus == ENUM_ENCRYPTION3_ENABLED) + || (eEncStatus == ENUM_ENCRYPTION3_KEY_ABSENT) + || (eEncStatus == ENUM_ENCRYPTION_DISABLED) + )) { + + prStaRec->ucPhyTypeSet &= ~PHY_TYPE_BIT_HT; + } + } + + prStaRec->ucDesiredPhyTypeSet = prStaRec->ucPhyTypeSet + & prAdapter->rWifiVar.ucAvailablePhyTypeSet; + ucNonHTPhyTypeSet = prStaRec->ucDesiredPhyTypeSet + & PHY_TYPE_SET_802_11ABG; + + /* Check for Target BSS's non HT Phy Types */ + if (ucNonHTPhyTypeSet) { + if (ucNonHTPhyTypeSet & PHY_TYPE_BIT_ERP) + prStaRec->ucNonHTBasicPhyType + = PHY_TYPE_ERP_INDEX; + else if (ucNonHTPhyTypeSet & PHY_TYPE_BIT_OFDM) + prStaRec->ucNonHTBasicPhyType + = PHY_TYPE_OFDM_INDEX; + else + prStaRec->ucNonHTBasicPhyType + = PHY_TYPE_HR_DSSS_INDEX; + + prStaRec->fgHasBasicPhyType = TRUE; + } else { + /* Use mandatory for 11N only BSS */ + ASSERT(prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N); + { + /* TODO(Kevin): which value should we set + * for 11n ? ERP ? + */ + prStaRec->ucNonHTBasicPhyType + = PHY_TYPE_HR_DSSS_INDEX; + } + + prStaRec->fgHasBasicPhyType = FALSE; + } + + } + + /* ++HT capability */ + + if (prCmd->fgIsSupHt) { + prAdapter->rWifiVar.eRateSetting = FIXED_RATE_NONE; + prStaRec->ucDesiredPhyTypeSet |= PHY_TYPE_BIT_HT; + prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_HT; + prStaRec->u2HtCapInfo = prCmd->rHtCap.u2CapInfo; + if (!IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucRxLdpc)) + prStaRec->u2HtCapInfo &= ~HT_CAP_INFO_LDPC_CAP; + prStaRec->ucAmpduParam = prCmd->rHtCap.ucAmpduParamsInfo; + prStaRec->u2HtExtendedCap = prCmd->rHtCap.u2ExtHtCapInfo; + prStaRec->u4TxBeamformingCap = prCmd->rHtCap.u4TxBfCapInfo; + prStaRec->ucAselCap = prCmd->rHtCap.ucAntennaSelInfo; + prStaRec->ucMcsSet = prCmd->rHtCap.rMCS.arRxMask[0]; + if (prCmd->rHtCap.rMCS.arRxMask[32 / 8] & BIT(0)) + prStaRec->fgSupMcs32 = TRUE; + else + prStaRec->fgSupMcs32 = FALSE; + kalMemCopy(prStaRec->aucRxMcsBitmask, + prCmd->rHtCap.rMCS.arRxMask, + sizeof(prStaRec->aucRxMcsBitmask)); + } + /* TODO ++VHT */ + + cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); + + return TDLS_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Get TDLS peer STA_RECORD_T by Peer MAC Address(Usually TA). + * + * @param[in] pucPeerMacAddr Given Peer MAC Address. + * + * @retval Pointer to STA_RECORD_T, if found. NULL, if not found + */ +/*----------------------------------------------------------------------------*/ +struct STA_RECORD *cnmGetTdlsPeerByAddress(struct ADAPTER *prAdapter, + uint8_t ucBssIndex, uint8_t aucPeerMACAddress[]) +{ + struct STA_RECORD *prStaRec; + uint16_t i; + + ASSERT(prAdapter); + ASSERT(aucPeerMACAddress); + + for (i = 0; i < CFG_STA_REC_NUM; i++) { + prStaRec = &prAdapter->arStaRec[i]; + if (prStaRec) { + if (prStaRec->fgIsInUse + && prStaRec->eStaType == STA_TYPE_DLS_PEER + && EQUAL_MAC_ADDR(prStaRec->aucMacAddr, + aucPeerMACAddress)) { + break; + } + } + } + + return prStaRec; +} + +#endif + +#if (CFG_SUPPORT_802_11AX == 1) +static void cnmStaRecCmdHeContentFill( + struct STA_RECORD *prStaRec, + struct CMD_UPDATE_STA_RECORD *prCmdContent) +{ + prCmdContent->ucVersion = CMD_UPDATE_STAREC_VER1; + memcpy(prCmdContent->ucHeMacCapInfo, prStaRec->ucHeMacCapInfo, + HE_MAC_CAP_BYTE_NUM); + memcpy(prCmdContent->ucHePhyCapInfo, prStaRec->ucHePhyCapInfo, + HE_PHY_CAP_BYTE_NUM); + + prCmdContent->u2HeRxMcsMapBW80 = + CPU_TO_LE16(prStaRec->u2HeRxMcsMapBW80); + prCmdContent->u2HeTxMcsMapBW80 = + CPU_TO_LE16(prStaRec->u2HeTxMcsMapBW80); + prCmdContent->u2HeRxMcsMapBW160 = + CPU_TO_LE16(prStaRec->u2HeRxMcsMapBW160); + prCmdContent->u2HeTxMcsMapBW160 = + CPU_TO_LE16(prStaRec->u2HeTxMcsMapBW160); + prCmdContent->u2HeRxMcsMapBW80P80 = + CPU_TO_LE16(prStaRec->u2HeRxMcsMapBW80P80); + prCmdContent->u2HeTxMcsMapBW80P80 = + CPU_TO_LE16(prStaRec->u2HeTxMcsMapBW80P80); +} +#endif + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/cnm_timer.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/cnm_timer.c new file mode 100644 index 0000000000000000000000000000000000000000..d891110fb35d543b820599cf665e4c13b2c5aa70 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/cnm_timer.c @@ -0,0 +1,745 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/cnm_timer.c#1 + */ + +/*! \file "cnm_timer.c" + * \brief + * + */ + + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +static void cnmTimerStopTimer_impl(IN struct ADAPTER *prAdapter, + IN struct TIMER *prTimer, IN u_int8_t fgAcquireSpinlock); +static u_int8_t cnmTimerIsTimerValid(IN struct ADAPTER *prAdapter, + IN struct TIMER *prTimer); + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine dump timer list for debug purpose + * + * \param[in] + * + * \retval + * + */ +/*----------------------------------------------------------------------------*/ +static void cnmTimerDumpTimer(IN struct ADAPTER *prAdapter) +{ + struct ROOT_TIMER *prRootTimer; + struct LINK_ENTRY *prLinkEntry; + struct TIMER *prTimerEntry; + struct LINK *prTimerList; + + prRootTimer = &prAdapter->rRootTimer; + prTimerList = &prRootTimer->rLinkHead; + + log_dbg(CNM, INFO, "Current time:%u\n", kalGetTimeTick()); + + LINK_FOR_EACH(prLinkEntry, prTimerList) { + if (prLinkEntry == NULL) + break; + + prTimerEntry = LINK_ENTRY(prLinkEntry, + struct TIMER, rLinkEntry); + + log_dbg(CNM, INFO, "timer:%p, func:%pf, ExpiredSysTime:%u\n", + prTimerEntry, + prTimerEntry->pfMgmtTimeOutFunc, + prTimerEntry->rExpiredSysTime); + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to check if a timer exists in timer list. + * + * \param[in] prTimer The timer to check + * + * \retval TRUE Valid timer + * FALSE Invalid timer + * + */ +/*----------------------------------------------------------------------------*/ +static u_int8_t cnmTimerIsTimerValid(IN struct ADAPTER *prAdapter, + IN struct TIMER *prTimer) +{ + struct ROOT_TIMER *prRootTimer; + struct LINK *prTimerList; + struct LINK_ENTRY *prLinkEntry; + struct TIMER *prPendingTimer; + + ASSERT(prAdapter); + + prRootTimer = &prAdapter->rRootTimer; + + /* Check if the timer is in timer list */ + prTimerList = &(prAdapter->rRootTimer.rLinkHead); + + LINK_FOR_EACH(prLinkEntry, prTimerList) { + if (prLinkEntry == NULL) + break; + + prPendingTimer = LINK_ENTRY(prLinkEntry, + struct TIMER, rLinkEntry); + + if (prPendingTimer == prTimer) + return TRUE; + } + + log_dbg(CNM, WARN, "invalid pending timer %p func %pf\n", + prTimer, prTimer->pfMgmtTimeOutFunc); + return FALSE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set the time to do the time out check. + * + * \param[in] rTimeout Time out interval from current time. + * + * \retval TRUE Success. + * + */ +/*----------------------------------------------------------------------------*/ +static u_int8_t cnmTimerSetTimer(IN struct ADAPTER *prAdapter, + IN OS_SYSTIME rTimeout, + IN enum ENUM_TIMER_WAKELOCK_TYPE_T eType) +{ + struct ROOT_TIMER *prRootTimer; + u_int8_t fgNeedWakeLock; + + ASSERT(prAdapter); + + prRootTimer = &prAdapter->rRootTimer; + + kalSetTimer(prAdapter->prGlueInfo, rTimeout); + + if ((eType == TIMER_WAKELOCK_REQUEST) + || (rTimeout <= SEC_TO_SYSTIME(WAKE_LOCK_MAX_TIME) + && (eType == TIMER_WAKELOCK_AUTO))) { + fgNeedWakeLock = TRUE; + + if (!prRootTimer->fgWakeLocked) { + KAL_WAKE_LOCK(prAdapter, prRootTimer->rWakeLock); + prRootTimer->fgWakeLocked = TRUE; + } + } else { + fgNeedWakeLock = FALSE; + } + + return fgNeedWakeLock; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routines is called to initialize a root timer. + * + * \param[in] prAdapter + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void cnmTimerInitialize(IN struct ADAPTER *prAdapter) +{ + struct ROOT_TIMER *prRootTimer; + struct LINK *prTimerList; + struct LINK_ENTRY *prLinkEntry; + struct TIMER *prPendingTimer; + + KAL_SPIN_LOCK_DECLARATION(); + + ASSERT(prAdapter); + + prRootTimer = &prAdapter->rRootTimer; + + /* Note: glue layer have configured timer */ + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); + + log_dbg(CNM, WARN, "reset timer list\n"); + + /* Remove all pending timers */ + prTimerList = &(prAdapter->rRootTimer.rLinkHead); + + LINK_FOR_EACH(prLinkEntry, prTimerList) { + if (prLinkEntry == NULL) + break; + + prPendingTimer = LINK_ENTRY(prLinkEntry, + struct TIMER, rLinkEntry); + + /* Remove timer to prevent collapsing timer structure */ + cnmTimerStopTimer_impl(prAdapter, prPendingTimer, FALSE); + } + + LINK_INITIALIZE(&prRootTimer->rLinkHead); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); + + KAL_WAKE_LOCK_INIT(prAdapter, prRootTimer->rWakeLock, "WLAN Timer"); + prRootTimer->fgWakeLocked = FALSE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routines is called to destroy a root timer. + * When WIFI is off, the token shall be returned back to system. + * + * \param[in] + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void cnmTimerDestroy(IN struct ADAPTER *prAdapter) +{ + struct ROOT_TIMER *prRootTimer; + + KAL_SPIN_LOCK_DECLARATION(); + + ASSERT(prAdapter); + + prRootTimer = &prAdapter->rRootTimer; + + if (prRootTimer->fgWakeLocked) { + KAL_WAKE_UNLOCK(prAdapter, prRootTimer->rWakeLock); + prRootTimer->fgWakeLocked = FALSE; + } + KAL_WAKE_LOCK_DESTROY(prAdapter, prRootTimer->rWakeLock); + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); + LINK_INITIALIZE(&prRootTimer->rLinkHead); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); + + /* Note: glue layer will be responsible for timer destruction */ +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routines is called to initialize a timer. + * + * \param[in] prTimer Pointer to a timer structure. + * \param[in] pfnFunc Pointer to the call back function. + * \param[in] u4Data Parameter for call back function. + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void +cnmTimerInitTimerOption(IN struct ADAPTER *prAdapter, + IN struct TIMER *prTimer, + IN PFN_MGMT_TIMEOUT_FUNC pfFunc, + IN unsigned long ulDataPtr, + IN enum ENUM_TIMER_WAKELOCK_TYPE_T eType) +{ + struct LINK *prTimerList; + struct LINK_ENTRY *prLinkEntry; + struct LINK_ENTRY *prTempLinkEntry; + /* Previous valid timer before the dangling timer */ + struct LINK_ENTRY *prPrevLinkEntry = NULL; + /* Next valid timer after the dangling timer */ + struct LINK_ENTRY *prNextLinkEntry = NULL; + struct TIMER *prPendingTimer; + + KAL_SPIN_LOCK_DECLARATION(); + ASSERT(prAdapter); + + ASSERT(prTimer); + + ASSERT((eType >= TIMER_WAKELOCK_AUTO) && (eType < TIMER_WAKELOCK_NUM)); + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); + + /* Remove pending timer */ + prTimerList = &(prAdapter->rRootTimer.rLinkHead); + + LINK_FOR_EACH(prLinkEntry, prTimerList) { + if (prLinkEntry == NULL) + break; + + prPendingTimer = LINK_ENTRY(prLinkEntry, + struct TIMER, rLinkEntry); + + if (prPendingTimer == prTimer) { + log_dbg(CNM, WARN, "re-init timer, timer %p func %pf\n", + prTimer, pfFunc); + + if (timerPendingTimer(prTimer)) { + /* Remove pending timer to prevent + * collapsing timer list. + */ + cnmTimerStopTimer_impl(prAdapter, + prTimer, FALSE); + continue; + } + + /* Timer structure was collapsed. Try to fix it. */ + log_dbg(CNM, WARN, "timer was collapsed. fix it!\n"); + LINK_FOR_EACH_PREV(prTempLinkEntry, prTimerList) { + if (prTempLinkEntry == NULL) + break; + + prPendingTimer = LINK_ENTRY( + prTempLinkEntry, + struct TIMER, rLinkEntry); + + if (prPendingTimer == prTimer) { + if (prNextLinkEntry == NULL) { + /* Link to head */ + prNextLinkEntry = + (struct LINK_ENTRY *) + prTimerList; + } + + /* Link to head */ + if (prPrevLinkEntry == NULL) { + prTimerList->prNext = + prNextLinkEntry; + prNextLinkEntry->prPrev = + (struct LINK_ENTRY *) + prTimerList; + prTimerList->u4NumElem--; + } else { /* Link to previous entry */ + prPrevLinkEntry->prNext = + prNextLinkEntry; + prNextLinkEntry->prPrev = + prPrevLinkEntry; + prTimerList->u4NumElem--; + } + + /* Dump timer */ + cnmTimerDumpTimer(prAdapter); + break; + } + /* Record next pending timer entry */ + prNextLinkEntry = prTempLinkEntry; + } + } + /* Record previous pending timer entry */ + prPrevLinkEntry = prLinkEntry; + } + + LINK_ENTRY_INITIALIZE(&prTimer->rLinkEntry); + + prTimer->pfMgmtTimeOutFunc = pfFunc; + prTimer->ulDataPtr = ulDataPtr; + prTimer->eType = eType; + + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routines is called to stop a timer. + * + * \param[in] prTimer Pointer to a timer structure. + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +static void cnmTimerStopTimer_impl(IN struct ADAPTER *prAdapter, + IN struct TIMER *prTimer, IN u_int8_t fgAcquireSpinlock) +{ + struct ROOT_TIMER *prRootTimer; + + KAL_SPIN_LOCK_DECLARATION(); + + ASSERT(prAdapter); + ASSERT(prTimer); + + prRootTimer = &prAdapter->rRootTimer; + + if (fgAcquireSpinlock) + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); + + if (timerPendingTimer(prTimer)) { + LINK_REMOVE_KNOWN_ENTRY(&prRootTimer->rLinkHead, + &prTimer->rLinkEntry); + + /* Reduce dummy timeout for power saving, + * especially HIF activity. If two or more timers + * exist and being removed timer is smallest, + * this dummy timeout will still happen, but it is OK. + */ + if (LINK_IS_EMPTY(&prRootTimer->rLinkHead)) { + kalCancelTimer(prAdapter->prGlueInfo); + + if (fgAcquireSpinlock && prRootTimer->fgWakeLocked) { + KAL_WAKE_UNLOCK(prAdapter, + prRootTimer->rWakeLock); + prRootTimer->fgWakeLocked = FALSE; + } + } + } + + if (fgAcquireSpinlock) + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routines is called to stop a timer. + * + * \param[in] prTimer Pointer to a timer structure. + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void cnmTimerStopTimer(IN struct ADAPTER *prAdapter, IN struct TIMER *prTimer) +{ + ASSERT(prAdapter); + ASSERT(prTimer); + + log_dbg(CNM, TRACE, "stop timer, timer %p func %pf\n", + prTimer, prTimer->pfMgmtTimeOutFunc); + + cnmTimerStopTimer_impl(prAdapter, prTimer, TRUE); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routines is called to start a timer with wake_lock. + * + * \param[in] prTimer Pointer to a timer structure. + * \param[in] u4TimeoutMs Timeout to issue the timer and call back function + * (unit: ms). + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void cnmTimerStartTimer(IN struct ADAPTER *prAdapter, IN struct TIMER *prTimer, + IN uint32_t u4TimeoutMs) +{ + struct ROOT_TIMER *prRootTimer; + struct LINK *prTimerList; + OS_SYSTIME rCurSysTime, rExpiredSysTime, rTimeoutSystime; + struct TIMER *prPendingTimer; + struct LINK_ENTRY *prLinkEntry; + + KAL_SPIN_LOCK_DECLARATION(); + + ASSERT(prAdapter); + ASSERT(prTimer); + + log_dbg(CNM, TRACE, "start timer, timer %p func %pf %d ms\n", + prTimer, prTimer->pfMgmtTimeOutFunc, u4TimeoutMs); + +#if (CFG_SUPPORT_STATISTICS == 1) + /* Do not print oid timer to avoid log too much. + * We can deduce existence of OID timer from cmd and event. + */ + if ((prTimer != NULL) && (&(prAdapter->rOidTimeoutTimer) != prTimer) + && (wlan_fb_power_down == TRUE)) { + DBGLOG_LIMITED(CNM, INFO, + "[WLAN-LP] Start timer %p %u ms -handler(%pf)\n", + prTimer, + u4TimeoutMs, + prTimer->pfMgmtTimeOutFunc); + } +#endif + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); + + prRootTimer = &prAdapter->rRootTimer; + prTimerList = &prRootTimer->rLinkHead; + + /* If timeout interval is larger than 1 minute, the mod value is set + * to the timeout value first, then per minutue. + */ + if (u4TimeoutMs > MSEC_PER_MIN) { + ASSERT(u4TimeoutMs <= ((uint32_t) 0xFFFF * MSEC_PER_MIN)); + + prTimer->u2Minutes = (uint16_t) (u4TimeoutMs / MSEC_PER_MIN); + u4TimeoutMs -= (prTimer->u2Minutes * MSEC_PER_MIN); + if (u4TimeoutMs == 0) { + u4TimeoutMs = MSEC_PER_MIN; + prTimer->u2Minutes--; + } + } else { + prTimer->u2Minutes = 0; + } + + /* The assertion check if MSEC_TO_SYSTIME() may be overflow. */ + ASSERT(u4TimeoutMs < (((uint32_t) 0x80000000 - MSEC_PER_SEC) / KAL_HZ)); + rTimeoutSystime = MSEC_TO_SYSTIME(u4TimeoutMs); + if (rTimeoutSystime == 0) + rTimeoutSystime = 1; + rCurSysTime = kalGetTimeTick(); + rExpiredSysTime = rCurSysTime + rTimeoutSystime; + + /* Remove out-of-date timers */ + if (TIME_BEFORE(prRootTimer->rNextExpiredSysTime, rCurSysTime)) { + log_dbg(CNM, WARN, "Invalid NextExpiredSysTime: %u, currentSysTime: %u\n", + prRootTimer->rNextExpiredSysTime, rCurSysTime); + + /* Dump timers */ + cnmTimerDumpTimer(prAdapter); + + LINK_FOR_EACH(prLinkEntry, prTimerList) { + if (prLinkEntry == NULL) + break; + + prPendingTimer = LINK_ENTRY(prLinkEntry, + struct TIMER, rLinkEntry); + + if (TIME_BEFORE(prPendingTimer->rExpiredSysTime, + rCurSysTime)) { + log_dbg(CNM, WARN, "remove out-of-date timer, timer %p func %pf\n", + prPendingTimer, + prPendingTimer->pfMgmtTimeOutFunc); + + cnmTimerStopTimer_impl(prAdapter, + prPendingTimer, FALSE); + } + } + /* Set max timeout */ + prRootTimer->rNextExpiredSysTime + = rCurSysTime + MGMT_MAX_TIMEOUT_INTERVAL; + } + + /* If no timer pending or the fast time interval is used. */ + if (LINK_IS_EMPTY(prTimerList) + || TIME_BEFORE(rExpiredSysTime, + prRootTimer->rNextExpiredSysTime)) { + + prRootTimer->rNextExpiredSysTime = rExpiredSysTime; + cnmTimerSetTimer(prAdapter, rTimeoutSystime, prTimer->eType); + } + + /* Add this timer to checking list */ + prTimer->rExpiredSysTime = rExpiredSysTime; + + if (!timerPendingTimer(prTimer)) { + LINK_INSERT_TAIL(prTimerList, &prTimer->rLinkEntry); + } else { + /* If the pending timer is not in timer list, we will have + * to add the timer to timer list anyway. Otherwise, the timer + * will never timeout. + */ + if (!cnmTimerIsTimerValid(prAdapter, prTimer)) + LINK_INSERT_TAIL(prTimerList, &prTimer->rLinkEntry); + } + + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routines is called to check the timer list. + * + * \param[in] + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void cnmTimerDoTimeOutCheck(IN struct ADAPTER *prAdapter) +{ + struct ROOT_TIMER *prRootTimer; + struct LINK *prTimerList; + struct LINK_ENTRY *prLinkEntry; + struct TIMER *prTimer; + OS_SYSTIME rCurSysTime; + PFN_MGMT_TIMEOUT_FUNC pfMgmtTimeOutFunc; + unsigned long ulTimeoutDataPtr; + u_int8_t fgNeedWakeLock; + enum ENUM_TIMER_WAKELOCK_TYPE_T eType = TIMER_WAKELOCK_NONE; + + KAL_SPIN_LOCK_DECLARATION(); + + ASSERT(prAdapter); + + /* acquire spin lock */ + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); + + prRootTimer = &prAdapter->rRootTimer; + prTimerList = &prRootTimer->rLinkHead; + + rCurSysTime = kalGetTimeTick(); + + /* Set the permitted max timeout value for new one */ + prRootTimer->rNextExpiredSysTime + = rCurSysTime + MGMT_MAX_TIMEOUT_INTERVAL; + + LINK_FOR_EACH(prLinkEntry, prTimerList) { + if (prLinkEntry == NULL) + break; + + prTimer = LINK_ENTRY(prLinkEntry, struct TIMER, rLinkEntry); + ASSERT(prTimer); + + /* Check if this entry is timeout. */ + if (!TIME_BEFORE(rCurSysTime, prTimer->rExpiredSysTime)) { + if (timerPendingTimer(prTimer)) { + cnmTimerStopTimer_impl(prAdapter, + prTimer, FALSE); + + pfMgmtTimeOutFunc = prTimer->pfMgmtTimeOutFunc; + ulTimeoutDataPtr = prTimer->ulDataPtr; + + if (prTimer->u2Minutes > 0) { + prTimer->u2Minutes--; + prTimer->rExpiredSysTime = rCurSysTime + + MSEC_TO_SYSTIME(MSEC_PER_MIN); + LINK_INSERT_TAIL(prTimerList, + &prTimer->rLinkEntry); + } else if (pfMgmtTimeOutFunc) { + KAL_RELEASE_SPIN_LOCK(prAdapter, + SPIN_LOCK_TIMER); + #ifdef UT_TEST_MODE + if (testTimerTimeout(prAdapter, + pfMgmtTimeOutFunc, + ulTimeoutDataPtr)) + #endif + log_dbg(CNM, TRACE, "timer timeout, timer %p func %pf\n", + prTimer, prTimer->pfMgmtTimeOutFunc); + + (pfMgmtTimeOutFunc) (prAdapter, + ulTimeoutDataPtr); + KAL_ACQUIRE_SPIN_LOCK(prAdapter, + SPIN_LOCK_TIMER); + } + } else { + log_dbg(CNM, WARN, "timer was re-inited, timer %p func %pf\n", + prTimer, prTimer->pfMgmtTimeOutFunc); + break; + } + + /* Search entire list again because of nest del and add + * timers and current MGMT_TIMER could be volatile after + * stopped + */ + prLinkEntry = (struct LINK_ENTRY *) prTimerList; + if (prLinkEntry == NULL) + break; + + prRootTimer->rNextExpiredSysTime + = rCurSysTime + MGMT_MAX_TIMEOUT_INTERVAL; + } else if (TIME_BEFORE(prTimer->rExpiredSysTime, + prRootTimer->rNextExpiredSysTime)) { + prRootTimer->rNextExpiredSysTime + = prTimer->rExpiredSysTime; + + if (prTimer->eType == TIMER_WAKELOCK_REQUEST) + eType = TIMER_WAKELOCK_REQUEST; + else if ((eType != TIMER_WAKELOCK_REQUEST) + && (prTimer->eType == TIMER_WAKELOCK_AUTO)) + eType = TIMER_WAKELOCK_AUTO; + } + } /* end of for loop */ + + /* Setup the prNext timeout event. It is possible the timer was already + * set in the above timeout callback function. + */ + fgNeedWakeLock = FALSE; + if (!LINK_IS_EMPTY(prTimerList)) { + ASSERT(TIME_AFTER( + prRootTimer->rNextExpiredSysTime, rCurSysTime)); + + fgNeedWakeLock = cnmTimerSetTimer(prAdapter, + (OS_SYSTIME)((int32_t) prRootTimer->rNextExpiredSysTime + - (int32_t) rCurSysTime), + eType); + } + + if (prRootTimer->fgWakeLocked && !fgNeedWakeLock) { + KAL_WAKE_UNLOCK(prAdapter, prRootTimer->rWakeLock); + prRootTimer->fgWakeLocked = FALSE; + } + + /* release spin lock */ + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/he_ie.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/he_ie.c new file mode 100644 index 0000000000000000000000000000000000000000..9a7cc8dd7386f69296f63a5981ea8d27a449c63a --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/he_ie.c @@ -0,0 +1,104 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* +** Id: @(#) he_rlm.c@@ +*/ + +/*! \file "he_ie.c" +* \brief This file contains HE IE processing routines. +* +*/ + +#include "precomp.h" + +#if (CFG_SUPPORT_802_11AX == 1) +#include "he_ie.h" + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + + +#endif /* CFG_SUPPORT_802_11AX == 1 */ + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/he_rlm.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/he_rlm.c new file mode 100644 index 0000000000000000000000000000000000000000..8ff053aee37cfd0b9d2b4db2156ad12d7d2356c4 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/he_rlm.c @@ -0,0 +1,1163 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* +** Id: @(#) he_rlm.c@@ +*/ + +/*! \file "he_rlm.c" +* \brief This file contains HE Phy processing routines. +* +*/ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +#include "precomp.h" + +#if (CFG_SUPPORT_802_11AX == 1) +#include "he_rlm.h" + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/* + * Ignore PPE Threshold (Optional) currently + * PPE threshold should be filled based on HW RX capability + */ +#define CFG_RX_PPE_THRESHOLD 1 + +/* + * NSS: 3 bits + * RU Index Bitmask: 4 bits + * PPET8 & PPET16 info for 2NSS and 4 RU index size: 6 * 2 * 4 = 48 bits + * PPE pad: 1 bit + * Total = 56 bits = 7 bytes + */ +#define MAX_PPE_THRESHOLD_LEN_2NSS 7 +#define MAX_PPE_THRESHOLD_LEN_1NSS 4 + +#if (CFG_SUPPORT_HE_ER == 1) +#define MAX_SUPPORT_CONSTELLATION_DCM_QPSK 2 +#endif + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ +/* TBD: where/what is the proper place/way to store this config */ +uint8_t g_au8RlmHeCfgContellIdx[4][4][2] = { + /* NSS1 */ + {{CONSTELL_IDX_BPSK, CONSTELL_IDX_NONE}, /* RU idx 0 */ + {CONSTELL_IDX_BPSK, CONSTELL_IDX_NONE}, /* RU idx 1 */ + {CONSTELL_IDX_BPSK, CONSTELL_IDX_NONE}, /* RU idx 2 */ + {CONSTELL_IDX_BPSK, CONSTELL_IDX_NONE} }, /* RU idx 3 */ + /* NSS2 */ + {{CONSTELL_IDX_BPSK, CONSTELL_IDX_NONE}, /* RU idx 0 */ + {CONSTELL_IDX_BPSK, CONSTELL_IDX_NONE}, /* RU idx 1 */ + {CONSTELL_IDX_BPSK, CONSTELL_IDX_NONE}, /* RU idx 2 */ + {CONSTELL_IDX_BPSK, CONSTELL_IDX_NONE} }, /* RU idx 3 */ + /* NSS3 */ + {{CONSTELL_IDX_BPSK, CONSTELL_IDX_NONE}, /* RU idx 0 */ + {CONSTELL_IDX_BPSK, CONSTELL_IDX_NONE}, /* RU idx 1 */ + {CONSTELL_IDX_BPSK, CONSTELL_IDX_NONE}, /* RU idx 2 */ + {CONSTELL_IDX_BPSK, CONSTELL_IDX_NONE} }, /* RU idx 3 */ + /* NSS4 */ + {{CONSTELL_IDX_BPSK, CONSTELL_IDX_NONE}, /* RU idx 0 */ + {CONSTELL_IDX_BPSK, CONSTELL_IDX_NONE}, /* RU idx 1 */ + {CONSTELL_IDX_BPSK, CONSTELL_IDX_NONE}, /* RU idx 2 */ + {CONSTELL_IDX_BPSK, CONSTELL_IDX_NONE} } /* RU idx 3 */ +}; + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +#define PPET_SUBFIELD_MASK 0x7 +#define BIT64(n) ((u_int64_t) 1UL << (n)) +#define BITS64(m, n) (~(BIT64(m)-1) & ((BIT64(n) - 1) | BIT64(n))) + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +uint32_t heRlmCalculateHeCapIELen( + struct ADAPTER *prAdapter, + uint8_t ucBssIndex, + struct STA_RECORD *prStaRec) +{ + uint8_t ucMaxBw; + struct BSS_INFO *prBssInfo = (struct BSS_INFO *) NULL; + uint32_t u4OverallLen = OFFSET_OF(struct _IE_HE_CAP_T, aucVarInfo[0]); + + if (fgEfuseCtrlAxOn == 1) { + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + ucMaxBw = cnmGetBssMaxBw(prAdapter, prBssInfo->ucBssIndex); + + u4OverallLen += 4; + + if (ucMaxBw >= MAX_BW_160MHZ) + u4OverallLen += 4; + + if (ucMaxBw >= MAX_BW_80_80_MHZ) + u4OverallLen += 4; + +#if (CFG_RX_PPE_THRESHOLD == 1) + u4OverallLen += sizeof(struct _PPE_THRESHOLD_FIELD); +#endif + } else { + u4OverallLen = 0; + } + + return u4OverallLen; +} + +uint32_t heRlmCalculateHeOpIELen( + struct ADAPTER *prAdapter, + uint8_t ucBssIndex, + struct STA_RECORD *prStaRec) +{ + uint32_t u4OverallLen = OFFSET_OF(struct _IE_HE_OP_T, aucVarInfo[0]); + + return u4OverallLen; +} + +static void heRlmFillMCSMap( + struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, + struct _HE_SUPPORTED_MCS_FIELD *prHeSupportedMcsSet) +{ + uint8_t i, ucSupportedNss; + + kalMemZero((void *) prHeSupportedMcsSet, + sizeof(struct _HE_SUPPORTED_MCS_FIELD)); + ucSupportedNss = wlanGetSupportNss(prAdapter, prBssInfo->ucBssIndex); + + for (i = 0; i < 8; i++) { + uint8_t ucOffset = i * 2; + uint8_t ucMcsMap; + + if (i < ucSupportedNss) { + if (prAdapter->fgMcsMapBeenSet) + ucMcsMap = prAdapter->ucMcsMapSetFromSigma; + else + ucMcsMap = HE_CAP_INFO_MCS_MAP_MCS11; + } else { + ucMcsMap = HE_CAP_INFO_MCS_NOT_SUPPORTED; + } + + prHeSupportedMcsSet->u2RxMcsMap |= (ucMcsMap << ucOffset); + prHeSupportedMcsSet->u2TxMcsMap |= (ucMcsMap << ucOffset); + } + + prHeSupportedMcsSet->u2RxMcsMap = + CPU_TO_LE32(prHeSupportedMcsSet->u2RxMcsMap); + prHeSupportedMcsSet->u2TxMcsMap = + CPU_TO_LE32(prHeSupportedMcsSet->u2TxMcsMap); +} + +/* + * ucBitPos: bit position (starting from 0) for setting 3-bit PPE value + * ucVal has to be 3-bit value (i.e. no greater than 7) + */ +static void heRlmSet3BitPPE(uint8_t *pMem, uint8_t ucBitPos, uint8_t ucVal) +{ + uint8_t ucValidBits, ucPosInCurByte; + uint8_t *pucCurByte = pMem + (ucBitPos >> 3); + + ucPosInCurByte = (ucBitPos & 0x7); + ucValidBits = 8 - ucPosInCurByte; + if (ucValidBits >= 3) { + (*pucCurByte) |= (ucVal << ucPosInCurByte); + } else { + (*pucCurByte) |= (((uint8_t)(ucVal << ucPosInCurByte)) & + BITS(ucPosInCurByte, 7)); + (*(pucCurByte + 1)) |= (ucVal >> ucValidBits); + } +} + +/* ucBitPos: bit position (starting from 0) for getting 3-bit PPE value */ +static uint8_t heRlmGet3BitPPE(uint8_t *pMem, uint8_t ucBitPos) +{ + /* ucValidBits: valid bit counts in current byte */ + uint8_t ucValidBits, ucPosInCurByte, ucPPE; + uint8_t *pucCurByte; + + /* Get the pointer of the byte that contains the ucBitPos */ + pucCurByte = pMem + (ucBitPos >> 3); /* divided by 8 */ + ucPosInCurByte = (ucBitPos & 0x7); + /* get the remaining bits in this byte */ + ucValidBits = 8 - ucPosInCurByte; + if (ucValidBits >= 3) { /* enough bits for getting 3-bit PPE */ + ucPPE = ((*pucCurByte) & + BITS(ucPosInCurByte, ucPosInCurByte + 2)) >> + ucPosInCurByte; + } else { + uint8_t ucLSb, ucMSb; + + ucLSb = ((*pucCurByte) & BITS(ucPosInCurByte, 7)) >> + ucPosInCurByte; + ucMSb = (*(pucCurByte + 1)) & BITS(0, 2 - ucValidBits); + ucPPE = ucLSb | (ucMSb << ucValidBits); + } + + return ucPPE; +} + +/* Note: ucSupportedNss is (actual NSS - 1) */ +static uint8_t heRlmFillPPEThresholdInfo( + uint8_t ucSupportedNss, + uint8_t ucRUIdxSize, + uint8_t *pMem +) +{ + uint8_t ucNssIdx, ucRUIdx; + uint8_t ucT16Pos = HE_CAP_PPE_PPET16_NSS1_RU0_SHFT; + uint8_t ucT8Pos = HE_CAP_PPE_PPET8_NSS1_RU0_SHFT; + uint8_t ucMaxSupportNss = (sizeof(g_au8RlmHeCfgContellIdx) / + sizeof(g_au8RlmHeCfgContellIdx[0])); + + /* Coverity: + * due to ucSupportedNss is Supported Nss - 1 + * if it > first dimention of g_au8RlmHeCfgContellIdx - 1 + * assign it to first dimention of g_au8RlmHeCfgContellIdx - 1 + */ + ucSupportedNss = (ucSupportedNss > (ucMaxSupportNss - 1)) ? + (ucMaxSupportNss - 1) : ucSupportedNss; + + for (ucNssIdx = 0; ucNssIdx <= ucSupportedNss; ucNssIdx++) { + for (ucRUIdx = 0; ucRUIdx < ucRUIdxSize; ucRUIdx++) { + heRlmSet3BitPPE(pMem, ucT16Pos, + g_au8RlmHeCfgContellIdx[ucNssIdx][ucRUIdx][0]); + heRlmSet3BitPPE(pMem, ucT8Pos, + g_au8RlmHeCfgContellIdx[ucNssIdx][ucRUIdx][1]); + ucT16Pos += PPE_SUBFIELD_BITS_NUM; + ucT8Pos += PPE_SUBFIELD_BITS_NUM; + } + } + + return ucT16Pos; +} + +static uint8_t heRlmFillPPEThreshold( + struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, + uint8_t *pPPEThreshold) +{ + uint8_t ucRUIdxSize = 0, ucLen; + uint8_t ucSupportedNss = + wlanGetSupportNss(prAdapter, prBssInfo->ucBssIndex) - 1; + uint8_t ucMaxBw = + cnmGetBssMaxBw(prAdapter, prBssInfo->ucBssIndex); + + kalMemZero((void *) pPPEThreshold, sizeof(struct _PPE_THRESHOLD_FIELD)); + + /* Note: this field in spec is (actual NSS - 1) */ + (*pPPEThreshold) = ucSupportedNss; + + switch (ucMaxBw) { + case MAX_BW_20MHZ: + (*pPPEThreshold) |= HE_CAP_PPE_242_RU_IDX; + ucRUIdxSize = 1; + break; + case MAX_BW_40MHZ: + (*pPPEThreshold) |= HE_CAP_PPE_484_RU_IDX; + ucRUIdxSize = 2; + break; + case MAX_BW_80MHZ: + (*pPPEThreshold) |= HE_CAP_PPE_996_RU_IDX; + ucRUIdxSize = 3; + break; + case MAX_BW_160MHZ: + case MAX_BW_80_80_MHZ: + (*pPPEThreshold) |= HE_CAP_PPE_996X2_RU_IDX; + ucRUIdxSize = 4; + break; + default: + /* should never come here */ + ASSERT(0); + } + + ucLen = heRlmFillPPEThresholdInfo(ucSupportedNss, + ucRUIdxSize, pPPEThreshold); + + ucLen = (ucLen % 8) ? (ucLen / 8 + 1) : (ucLen / 8); + + return ucLen; +} + +static void heRlmFillHeCapIE( + struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, + struct MSDU_INFO *prMsduInfo) +{ + struct _IE_HE_CAP_T *prHeCap; + struct _HE_SUPPORTED_MCS_FIELD *prHeSupportedMcsSet; + uint32_t u4OverallLen = OFFSET_OF(struct _IE_HE_CAP_T, aucVarInfo[0]); + uint16_t ucMaxBw; + u_int8_t fgBfEn = TRUE; + + struct WIFI_VAR *prWifiVar = &prAdapter->rWifiVar; +#if (CFG_RX_PPE_THRESHOLD == 1) + uint8_t *pPPEThreshold; +#endif + uint8_t ucSupportedNss = + wlanGetSupportNss(prAdapter, prBssInfo->ucBssIndex) - 1; + struct AIS_FSM_INFO *prAisFsmInfo = + aisGetAisFsmInfo(prAdapter, prBssInfo->ucBssIndex); + struct BSS_DESC *prBssDesc; + + ASSERT(prAdapter); + ASSERT(prBssInfo); + ASSERT(prMsduInfo); + + prHeCap = (struct _IE_HE_CAP_T *) + (((uint8_t *)prMsduInfo->prPacket)+prMsduInfo->u2FrameLength); + + prHeCap->ucId = ELEM_ID_RESERVED; + prHeCap->ucExtId = ELEM_EXT_ID_HE_CAP; + + /* MAC capabilities */ + HE_RESET_MAC_CAP(prHeCap->ucHeMacCap); + + HE_SET_MAC_CAP_TRIGGER_PAD_DURATION(prHeCap->ucHeMacCap, + prWifiVar->ucTrigMacPadDur); + + HE_SET_MAC_CAP_HTC_HE(prHeCap->ucHeMacCap); + HE_SET_MAC_CAP_OM_CTRL(prHeCap->ucHeMacCap); + +#if (CFG_SUPPORT_TWT == 1) + if (IS_FEATURE_ENABLED(prWifiVar->ucTWTRequester)) + HE_SET_MAC_CAP_TWT_REQ(prHeCap->ucHeMacCap); +#endif + + /* PHY capabilities */ + HE_RESET_PHY_CAP(prHeCap->ucHePhyCap); + + if (prWifiVar->ucSta2gBandwidth >= MAX_BW_40MHZ + && prBssInfo->fgAssoc40mBwAllowed) + HE_SET_PHY_CAP_CHAN_WIDTH_SET_BW40_2G(prHeCap->ucHePhyCap); + + if (prWifiVar->ucSta5gBandwidth >= MAX_BW_40MHZ) + HE_SET_PHY_CAP_CHAN_WIDTH_SET_BW40_BW80_5G( + prHeCap->ucHePhyCap); + + if (prWifiVar->ucSta5gBandwidth >= MAX_BW_160MHZ) + HE_SET_PHY_CAP_CHAN_WIDTH_SET_BW160_5G(prHeCap->ucHePhyCap); + + if (prWifiVar->ucSta5gBandwidth >= MAX_BW_80_80_MHZ) + HE_SET_PHY_CAP_CHAN_WIDTH_SET_BW80P80_5G(prHeCap->ucHePhyCap); + + if (IS_FEATURE_ENABLED(prWifiVar->ucRxLdpc) && + IS_FEATURE_ENABLED(prWifiVar->ucTxLdpc)) + HE_SET_PHY_CAP_LDPC_CODING_IN_PAYLOAD(prHeCap->ucHePhyCap); + + if (IS_FEATURE_ENABLED(prWifiVar->ucTxStbc)) { + HE_SET_PHY_CAP_STBC_TX_LT_OR_EQ_80M(prHeCap->ucHePhyCap); + HE_SET_PHY_CAP_STBC_TX_GT_80M(prHeCap->ucHePhyCap); + } + + if (IS_FEATURE_ENABLED(prWifiVar->ucRxStbc)) { + HE_SET_PHY_CAP_STBC_RX_LT_OR_EQ_80M(prHeCap->ucHePhyCap); + HE_SET_PHY_CAP_STBC_RX_GT_80M(prHeCap->ucHePhyCap); + } + +#if CFG_SUPPORT_BFEE +#if CFG_SUPPORT_CONDITIONAL_BFEE + if ((prAdapter->rWifiVar.u4SwTestMode != ENUM_SW_TEST_MODE_SIGMA_AX) && + (IS_BSS_AIS(prBssInfo) && prAisFsmInfo != NULL)) { + prBssDesc = prAisFsmInfo->prTargetBssDesc; + if (prBssDesc != NULL && (bssGetRxNss(prAdapter, prBssDesc) == + wlanGetSupportNss(prAdapter, prBssInfo->ucBssIndex))) { + fgBfEn = FALSE; + DBGLOG(SW4, ERROR, + "Disable Bfee due to same Nss between STA and AP\n"); + } else { + fgBfEn = TRUE; + } + } +#endif + if ((fgBfEn == TRUE) && (IS_FEATURE_ENABLED(prWifiVar->ucStaHeBfee))) { + HE_SET_PHY_CAP_SU_BFMEE(prHeCap->ucHePhyCap); + HE_SET_PHY_CAP_BFMEE_STS_LT_OR_EQ_80M(prHeCap->ucHePhyCap, 3); + HE_SET_PHY_CAP_NG_16_SU_FB(prHeCap->ucHePhyCap); + HE_SET_PHY_CAP_NG_16_MU_FB(prHeCap->ucHePhyCap); + HE_SET_PHY_CAP_CODE_BOOK_4_2_SU_FB(prHeCap->ucHePhyCap); + HE_SET_PHY_CAP_CODE_BOOK_7_5_MU_FB(prHeCap->ucHePhyCap); + HE_SET_PHY_CAP_TRIG_SU_BF_FB(prHeCap->ucHePhyCap); + HE_SET_PHY_CAP_TRIG_MU_BF_PARTIAL_BW_FB(prHeCap->ucHePhyCap); + HE_SET_PHY_CAP_MAX_NC(prHeCap->ucHePhyCap, ucSupportedNss); + } +#endif + +#if (CFG_SUPPORT_HE_ER == 1) + if (IS_FEATURE_ENABLED(prWifiVar->u4ExtendedRange)) { + HE_SET_PHY_CAP_DCM_MAX_CONSTELLATION_TX(prHeCap->ucHePhyCap, + MAX_SUPPORT_CONSTELLATION_DCM_QPSK); + HE_SET_PHY_CAP_DCM_MAX_CONSTELLATION_RX(prHeCap->ucHePhyCap, + MAX_SUPPORT_CONSTELLATION_DCM_QPSK); + HE_SET_PHY_CAP_PARTIAL_BW_EXTENDED_RANGE(prHeCap->ucHePhyCap); + HE_SET_PHY_CAP_ER_SU_4X_HE_LTF(prHeCap->ucHePhyCap); + HE_SET_PHY_CAP_ER_SU_PPDU_1X_HE_LTF(prHeCap->ucHePhyCap); + + DBGLOG(RLM, INFO, "ER: Set ER Phy capabilities\n"); + } +#endif + + /* Set MCS map */ + prHeSupportedMcsSet = (struct _HE_SUPPORTED_MCS_FIELD *) + (((uint8_t *) prHeCap) + u4OverallLen); + heRlmFillMCSMap(prAdapter, prBssInfo, prHeSupportedMcsSet); + u4OverallLen += sizeof(struct _HE_SUPPORTED_MCS_FIELD); + + ucMaxBw = cnmGetBssMaxBw(prAdapter, prBssInfo->ucBssIndex); + if (ucMaxBw >= MAX_BW_160MHZ) { + prHeSupportedMcsSet = (struct _HE_SUPPORTED_MCS_FIELD *) + (((uint8_t *) prHeCap) + u4OverallLen); + heRlmFillMCSMap(prAdapter, prBssInfo, prHeSupportedMcsSet); + u4OverallLen += sizeof(struct _HE_SUPPORTED_MCS_FIELD); + } + + if (ucMaxBw >= MAX_BW_80_80_MHZ) { + prHeSupportedMcsSet = (struct _HE_SUPPORTED_MCS_FIELD *) + (((uint8_t *) prHeCap) + u4OverallLen); + heRlmFillMCSMap(prAdapter, prBssInfo, prHeSupportedMcsSet); + u4OverallLen += sizeof(struct _HE_SUPPORTED_MCS_FIELD); + } + +#if (CFG_RX_PPE_THRESHOLD == 1) + pPPEThreshold = ((uint8_t *) prHeCap) + u4OverallLen; + u4OverallLen += + heRlmFillPPEThreshold(prAdapter, prBssInfo, pPPEThreshold); +#endif + /* The Element ID Extension byte is included in length calculation */ + prHeCap->ucLength = u4OverallLen - ELEM_HDR_LEN; + + prMsduInfo->u2FrameLength += IE_SIZE(prHeCap); +} + +void heRlmReqGenerateHeCapIE( + struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo) +{ + struct BSS_INFO *prBssInfo; + struct STA_RECORD *prStaRec; + + if (fgEfuseCtrlAxOn == 1) { + + ASSERT(prAdapter); + ASSERT(prMsduInfo); + + prBssInfo = prAdapter->aprBssInfo[prMsduInfo->ucBssIndex]; + if (!prBssInfo) + return; + + prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); + + if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11AX) + && (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11AX))) + heRlmFillHeCapIE(prAdapter, prBssInfo, prMsduInfo); + } +} + +void heRlmRspGenerateHeCapIE( + struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo) +{ + struct BSS_INFO *prBssInfo; + struct STA_RECORD *prStaRec; + uint8_t ucPhyTypeSet; + + ASSERT(prAdapter); + ASSERT(prMsduInfo); + + prBssInfo = prAdapter->aprBssInfo[prMsduInfo->ucBssIndex]; + if (!prBssInfo) + return; + + if (!IS_BSS_ACTIVE(prBssInfo)) + return; + + prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); + + /* Decide PHY type set source */ + if (prStaRec) { + /* Get PHY type set from target STA */ + ucPhyTypeSet = prStaRec->ucPhyTypeSet; + } else { + /* Get PHY type set from current BSS */ + ucPhyTypeSet = prBssInfo->ucPhyTypeSet; + } + + if (RLM_NET_IS_11AX(prBssInfo) && + (ucPhyTypeSet & PHY_TYPE_SET_802_11AX)) + heRlmFillHeCapIE(prAdapter, prBssInfo, prMsduInfo); +} + +static void heRlmFillHeOpIE( + struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, + struct MSDU_INFO *prMsduInfo) +{ + struct _IE_HE_OP_T *prHeOp; + uint32_t u4OverallLen = OFFSET_OF(struct _IE_HE_OP_T, aucVarInfo[0]); + + ASSERT(prAdapter); + ASSERT(prBssInfo); + ASSERT(prMsduInfo); + + prHeOp = (struct _IE_HE_OP_T *) + (((uint8_t *)prMsduInfo->prPacket)+prMsduInfo->u2FrameLength); + + prHeOp->ucId = ELEM_ID_RESERVED; + prHeOp->ucExtId = ELEM_EXT_ID_HE_OP; + + memcpy(prHeOp->ucHeOpParams, prBssInfo->ucHeOpParams, HE_OP_BYTE_NUM); + prHeOp->ucBssColorInfo = prBssInfo->ucBssColorInfo; + prHeOp->u2HeBasicMcsSet = CPU_TO_LE16(prBssInfo->u2HeBasicMcsSet); + + prHeOp->ucLength = u4OverallLen - ELEM_HDR_LEN; + prMsduInfo->u2FrameLength += IE_SIZE(prHeOp); +} + +void heRlmRspGenerateHeOpIE( + struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo) +{ + struct BSS_INFO *prBssInfo; + struct STA_RECORD *prStaRec; + uint8_t ucPhyTypeSet; + + ASSERT(prAdapter); + ASSERT(prMsduInfo); + + prBssInfo = prAdapter->aprBssInfo[prMsduInfo->ucBssIndex]; + if (!prBssInfo) + return; + + if (!IS_BSS_ACTIVE(prBssInfo)) + return; + + prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); + + /* Decide PHY type set source */ + if (prStaRec) { + /* Get PHY type set from target STA */ + ucPhyTypeSet = prStaRec->ucPhyTypeSet; + } else { + /* Get PHY type set from current BSS */ + ucPhyTypeSet = prBssInfo->ucPhyTypeSet; + } + + if (RLM_NET_IS_11AX(prBssInfo) && + (ucPhyTypeSet & PHY_TYPE_SET_802_11AX)) + heRlmFillHeOpIE(prAdapter, prBssInfo, prMsduInfo); +} + +static uint16_t heRlmGetHeMcsMap(uint8_t *pSrc) +{ + uint16_t u2McsMap; + + kalMemCopy(&u2McsMap, pSrc, sizeof(u2McsMap)); + u2McsMap = LE16_TO_CPU(u2McsMap); + + return u2McsMap; +} + +static uint32_t heRlmRecHeMcsMap( + struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + struct _IE_HE_CAP_T *prHeCap) +{ + uint32_t u4McsMapOffset; + uint16_t u2McsMap; + struct BSS_INFO *prBssInfo; + uint8_t ucHeCapMcsOwnNotSupportOffset = 0, ucMaxBw; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex); + ucMaxBw = cnmGetBssMaxBw(prAdapter, prBssInfo->ucBssIndex); + + /* BW 80Mhz */ + u4McsMapOffset = OFFSET_OF(struct _IE_HE_CAP_T, aucVarInfo[0]); + + u2McsMap = heRlmGetHeMcsMap(((uint8_t *)prHeCap) + u4McsMapOffset); + prStaRec->u2HeRxMcsMapBW80 = u2McsMap; + + if (wlanGetSupportNss(prAdapter, prStaRec->ucBssIndex) < 8) { + ucHeCapMcsOwnNotSupportOffset = + wlanGetSupportNss(prAdapter, prStaRec->ucBssIndex) * 2; + /* Mark Rx Mcs Map which we don't support */ + prStaRec->u2HeRxMcsMapBW80 |= + BITS(ucHeCapMcsOwnNotSupportOffset, 15); + } + if (prStaRec->u2HeRxMcsMapBW80 != u2McsMap) + DBGLOG(RLM, TRACE, "Change HeRxMcsMapBW80 from 0x%x to 0x%x\n", + u2McsMap, prStaRec->u2HeRxMcsMapBW80); + + u4McsMapOffset += sizeof(uint16_t); + + u2McsMap = heRlmGetHeMcsMap(((uint8_t *)prHeCap) + u4McsMapOffset); + prStaRec->u2HeTxMcsMapBW80 = u2McsMap; + + u4McsMapOffset += sizeof(uint16_t); + + /* BW 160Mhz */ + if (HE_IS_PHY_CAP_CHAN_WIDTH_SET_BW160_5G(prStaRec->ucHePhyCapInfo)) { + u2McsMap = heRlmGetHeMcsMap(((uint8_t *)prHeCap) + + u4McsMapOffset); + prStaRec->u2HeRxMcsMapBW160 = u2McsMap; + + if (ucMaxBw >= MAX_BW_160MHZ) { + /* Mark Rx Mcs Map which we don't support */ + prStaRec->u2HeRxMcsMapBW160 |= + BITS(ucHeCapMcsOwnNotSupportOffset, 15); + + if (prStaRec->u2HeRxMcsMapBW160 != u2McsMap) + DBGLOG(RLM, TRACE, + "Change McsMapBW160 from 0x%x to 0x%x\n", + u2McsMap, prStaRec->u2HeRxMcsMapBW160); + } else { + /* BW160 is not supported locally */ + prStaRec->u2HeRxMcsMapBW160 = BITS(0, 15); + } + + u4McsMapOffset += sizeof(uint16_t); + u2McsMap = heRlmGetHeMcsMap(((uint8_t *)prHeCap) + + u4McsMapOffset); + prStaRec->u2HeTxMcsMapBW160 = u2McsMap; + u4McsMapOffset += sizeof(uint16_t); + } else { + prStaRec->u2HeRxMcsMapBW160 = BITS(0, 15); + prStaRec->u2HeTxMcsMapBW160 = BITS(0, 15); + } + + /* BW 80+80 */ + if (HE_IS_PHY_CAP_CHAN_WIDTH_SET_BW80P80_5G(prStaRec->ucHePhyCapInfo)) { + u2McsMap = heRlmGetHeMcsMap(((uint8_t *)prHeCap) + + u4McsMapOffset); + prStaRec->u2HeRxMcsMapBW80P80 = u2McsMap; + + if (ucMaxBw >= MAX_BW_80_80_MHZ) { + /* Mark Rx Mcs Map which we don't support */ + prStaRec->u2HeRxMcsMapBW80P80 |= + BITS(ucHeCapMcsOwnNotSupportOffset, 15); + + if (prStaRec->u2HeRxMcsMapBW80P80 != u2McsMap) + DBGLOG(RLM, TRACE, + "Change McsMapBW80P80 from 0x%x to 0x%x\n", + u2McsMap, prStaRec->u2HeRxMcsMapBW80P80); + } else { + /* BW 80+80 is not supported locally */ + prStaRec->u2HeRxMcsMapBW80P80 = BITS(0, 15); + } + + u4McsMapOffset += sizeof(uint16_t); + u2McsMap = heRlmGetHeMcsMap(((uint8_t *)prHeCap) + + u4McsMapOffset); + prStaRec->u2HeTxMcsMapBW80P80 = u2McsMap; + u4McsMapOffset += sizeof(uint16_t); + } else { + prStaRec->u2HeRxMcsMapBW80P80 = BITS(0, 15); + prStaRec->u2HeTxMcsMapBW80P80 = BITS(0, 15); + } + + return u4McsMapOffset; +} + +static void heRlmRecHePPEThresholds(struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + struct _IE_HE_CAP_T *prHeCap, + uint32_t u4Offset) +{ + /* To store subfiled values in peer's PPE threshold */ + uint8_t i, j, k, ucNSS, ucRUIdxBMP, ucRUIdxBMPTmp, ucPPEInfo[32], ucPos; + uint8_t *pucMem = ((uint8_t *)prHeCap) + u4Offset; + + ucNSS = (*pucMem) & HE_CAP_PPE_NSS; + ucRUIdxBMP = ((*pucMem) & HE_CAP_PPE_RU_IDX_BMP) >> + HE_CAP_PPE_RU_IDX_BMP_SHFT; + + k = 0; + ucPos = HE_CAP_PPE_PPET16_NSS1_RU0_SHFT; + for (i = 0; i <= ucNSS; i++) { + ucRUIdxBMPTmp = ucRUIdxBMP; + for (j = 0; j < PPE_RU_IDX_SIZE * 2; j++) { + if (ucRUIdxBMPTmp & 0x1) { + ucPPEInfo[k] = heRlmGet3BitPPE(pucMem, ucPos); + ucPos += 3; + } else { + ucPPEInfo[k] = 0; + } + k++; + ucRUIdxBMPTmp = (ucRUIdxBMPTmp >> 1); + } + } +} + +void heRlmRecHeCapInfo( + struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + uint8_t *pucIE) +{ + uint32_t u4Offset; + struct WIFI_VAR *prWifiVar = &prAdapter->rWifiVar; + struct _IE_HE_CAP_T *prHeCap = (struct _IE_HE_CAP_T *) pucIE; + + /* if payload not contain any aucVarInfo, + * IE size = sizeof(struct _IE_HE_CAP_T) + */ + if (IE_SIZE(prHeCap) < (sizeof(struct _IE_HE_CAP_T))) { + DBGLOG(SCN, WARN, "HE_CAP IE_LEN err(%d)!\n", IE_LEN(prHeCap)); + return; + } + + memcpy(prStaRec->ucHeMacCapInfo, prHeCap->ucHeMacCap, + HE_MAC_CAP_BYTE_NUM); + memcpy(prStaRec->ucHePhyCapInfo, prHeCap->ucHePhyCap, + HE_PHY_CAP_BYTE_NUM); + +#if (CFG_SUPPORT_HE_ER == 1) + DBGLOG(RLM, INFO, "ER: TX:%d, RX:%d, bw:%d, 4x LTF:%d, 1X LTF:%d\n", + HE_GET_PHY_CAP_DCM_MAX_CONSTELLATION_TX( + prStaRec->ucHePhyCapInfo), + HE_GET_PHY_CAP_DCM_MAX_CONSTELLATION_RX( + prStaRec->ucHePhyCapInfo), + HE_GET_PHY_CAP_PARTIAL_BW_EXTENDED_RANGE( + prStaRec->ucHePhyCapInfo), + HE_GET_PHY_CAP_ER_SU_4X_HE_LTF( + prStaRec->ucHePhyCapInfo), + HE_GET_PHY_CAP_ER_SU_PPDU_1X_HE_LTF( + prStaRec->ucHePhyCapInfo)); +#endif + + /* Disable peer bfer cap indication to FW + * if our bfee feature is not on + */ + if (IS_FEATURE_DISABLED(prWifiVar->ucStaHeBfee)) { + HE_UNSET_PHY_CAP_SU_BFMER(prStaRec->ucHePhyCapInfo); + HE_UNSET_PHY_CAP_MU_BFMER(prStaRec->ucHePhyCapInfo); + } + + /* Set HE Rx Mcs Map upon peer's capability and our capability */ + u4Offset = heRlmRecHeMcsMap(prAdapter, prStaRec, prHeCap); + + /* Set HE PPE Thresholds if it exists */ + if (HE_IS_PHY_CAP_PPE_THRESHOLD(prStaRec->ucHePhyCapInfo)) + heRlmRecHePPEThresholds(prAdapter, prStaRec, prHeCap, u4Offset); +} + +void heRlmRecHeOperation( + struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, + uint8_t *pucIE) +{ + struct _IE_HE_OP_T *prHeOp = (struct _IE_HE_OP_T *) pucIE; +#if (CFG_SUPPORT_HE_ER == 1) + struct WIFI_VAR *prWifiVar = &prAdapter->rWifiVar; + /* if payload not contain any aucVarInfo, + * IE size = sizeof(struct _IE_HE_OP_T) + */ + if (IE_SIZE(prHeOp) < (sizeof(struct _IE_HE_OP_T))) { + DBGLOG(SCN, WARN, "HE_OP IE_LEN err(%d)!\n", IE_LEN(prHeOp)); + return; + } + + if (IS_FEATURE_DISABLED(prWifiVar->u4ExtendedRange)) { + HE_SET_OP_PARAM_ER_SU_DISABLE(prHeOp->ucHeOpParams); + + DBGLOG(RLM, INFO, "ER: is ER SU: %d\n", + HE_IS_ER_SU_DISABLE(prHeOp->ucHeOpParams)); + } +#endif + + memcpy(prBssInfo->ucHeOpParams, prHeOp->ucHeOpParams, HE_OP_BYTE_NUM); + prBssInfo->ucBssColorInfo = prHeOp->ucBssColorInfo; + prBssInfo->u2HeBasicMcsSet = LE16_TO_CPU(prHeOp->u2HeBasicMcsSet); +} + +uint8_t heRlmUpdateSRParams( + struct BSS_INFO *prBssInfo, + uint8_t *pucIE) +{ + struct _IE_SR_PARAM_T *prSRParam = (struct _IE_SR_PARAM_T *) pucIE; + uint32_t u4IEOffset; + uint8_t fgIsNew = FALSE; + + if (prBssInfo->ucSRControl != prSRParam->ucSRControl) { + fgIsNew = TRUE; + prBssInfo->ucSRControl = prSRParam->ucSRControl; + } + + u4IEOffset = OFFSET_OF(struct _IE_SR_PARAM_T, aucVarInfo[0]); + + if (prBssInfo->ucSRControl & SR_PARAM_NON_SRG_OFFSET_PRESENT) { + struct _NON_SRG_SR_INFO_T *prNonSRGInfo = + (struct _NON_SRG_SR_INFO_T *) + (((uint8_t *) pucIE) + u4IEOffset); + + if (prBssInfo->ucNonSRGObssPdMaxOffset != + prNonSRGInfo->ucObssPdMaxOffset) { + + fgIsNew = TRUE; + prBssInfo->ucNonSRGObssPdMaxOffset = + prNonSRGInfo->ucObssPdMaxOffset; + } + + u4IEOffset += sizeof(struct _NON_SRG_SR_INFO_T); + } else + prBssInfo->ucNonSRGObssPdMaxOffset = 0; + + if (prBssInfo->ucSRControl & SR_PARAM_SRG_INFO_PRESENT) { + struct _SRG_SR_INFO_T *prSRGInfo = (struct _SRG_SR_INFO_T *) + (((uint8_t *) pucIE) + u4IEOffset); + + if (prBssInfo->ucSRGObssPdMinOffset != + prSRGInfo->ucObssPdMinOffset) { + fgIsNew = TRUE; + prBssInfo->ucSRGObssPdMinOffset = + prSRGInfo->ucObssPdMinOffset; + } + if (prBssInfo->ucSRGObssPdMaxOffset != + prSRGInfo->ucObssPdMaxOffset) { + fgIsNew = TRUE; + prBssInfo->ucSRGObssPdMaxOffset = + prSRGInfo->ucObssPdMaxOffset; + } + if (prBssInfo->u8SRGBSSColorBitmap != + LE64_TO_CPU(prSRGInfo->u8BSSColorBitmap)) { + fgIsNew = TRUE; + prBssInfo->u8SRGBSSColorBitmap = + LE64_TO_CPU(prSRGInfo->u8BSSColorBitmap); + } + if (prBssInfo->u8SRGPartialBSSIDBitmap != + LE64_TO_CPU(prSRGInfo->u8PartialBSSIDBitmap)) { + fgIsNew = TRUE; + prBssInfo->u8SRGPartialBSSIDBitmap = + LE64_TO_CPU(prSRGInfo->u8PartialBSSIDBitmap); + } + } else { + prBssInfo->ucSRGObssPdMinOffset = 0; + prBssInfo->ucSRGObssPdMaxOffset = 0; + prBssInfo->u8SRGBSSColorBitmap = 0; + prBssInfo->u8SRGPartialBSSIDBitmap = 0; + } + + return fgIsNew; +} + +uint8_t +heRlmRecHeSRParams( + struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, + struct SW_RFB *prSwRfb, + uint8_t *pucIE, + uint16_t u2IELength) +{ + uint16_t u2Offset; + uint8_t fgNewParameter = FALSE; + + DEBUGFUNC("rlmParseHeSRParams"); + + if (!pucIE) + return FALSE; + + /* Obtain the SR parameters */ + IE_FOR_EACH(pucIE, u2IELength, u2Offset) { + switch (IE_ID(pucIE)) { + case ELEM_ID_RESERVED: + if (IE_ID_EXT(pucIE) == ELEM_EXT_ID_SR_PARAM) { + fgNewParameter = + heRlmUpdateSRParams(prBssInfo, pucIE); + } + break; + default: + break; + } + } + + return fgNewParameter; +} + +void heRlmInitHeHtcACtrlOMAndUPH( + struct ADAPTER *prAdapter) +{ + HE_SET_HTC_HE_VARIANT(prAdapter->u4HeHtcOM); + HE_SET_HTC_1ST_A_CTRL_ID(prAdapter->u4HeHtcOM, HTC_HE_A_CTRL_OM); + HE_SET_HTC_HE_OM_RX_NSS(prAdapter->u4HeHtcOM, 1); + HE_SET_HTC_HE_OM_TX_NSTS(prAdapter->u4HeHtcOM, 1); + HE_SET_HTC_HE_OM_CH_WIDTH(prAdapter->u4HeHtcOM, CH_BW_80); + HE_SET_HTC_HE_OM_UL_MU_DISABLE(prAdapter->u4HeHtcOM, 0); + HE_SET_HTC_HE_OM_UL_MU_DATA_DISABLE(prAdapter->u4HeHtcOM, 0); + HE_SET_HTC_2ND_A_CTRL_ID(prAdapter->u4HeHtcOM, HTC_HE_A_CTRL_UPH); + HE_SET_HTC_HE_UPH(prAdapter->u4HeHtcOM, 10); + HE_SET_HTC_HE_UPH_MIN_TX_PWR_FLAG(prAdapter->u4HeHtcOM, 0); +} + +void heRlmReqGenerateHeHtcACtrlOM( + IN struct HE_A_CTRL_OM_T *prHeActrlOM, + OUT uint32_t *pHtc) +{ + uint32_t u4HTC = 0; + + if (!pHtc || !prHeActrlOM) { + DBGLOG(RLM, WARN, + "heRlmReqGenerateHeHtcACtrlOM:: Please check function parameters.\n"); + return; + } + + HE_SET_HTC_1ST_A_CTRL_ID(u4HTC, HTC_HE_A_CTRL_OM); + HE_SET_HTC_HE_OM_RX_NSS(u4HTC, prHeActrlOM->ucRxNss); + HE_SET_HTC_HE_OM_TX_NSTS(u4HTC, prHeActrlOM->ucTxNsts); + HE_SET_HTC_HE_OM_CH_WIDTH(u4HTC, prHeActrlOM->ucBW); + HE_SET_HTC_HE_OM_UL_MU_DISABLE(u4HTC, prHeActrlOM->fgDisMuUL); + HE_SET_HTC_HE_OM_UL_MU_DATA_DISABLE(u4HTC, prHeActrlOM->fgDisMuULData); + *pHtc = u4HTC; + DBGLOG(RLM, STATE, "heRlmReqGenerateHeHtcACtrlOM:: u4HTC = 0x%08x\n"); +} + +void heRlmParseHeHtcACtrlOM( + uint32_t u4Htc, + struct HE_A_CTRL_OM_T *prHeActrlOM) +{ + DBGLOG(RLM, STATE, + "heRlmParseHeHtcACtrlOM:: HTC Control Field = 0x%08x\n", + u4Htc); + if (HE_GET_HTC_1ST_A_CTRL_ID(u4Htc) == HTC_HE_A_CTRL_OM) { + prHeActrlOM->ucRxNss = HE_GET_HTC_HE_OM_RX_NSS(u4Htc); + prHeActrlOM->ucTxNsts = HE_GET_HTC_HE_OM_TX_NSTS(u4Htc); + prHeActrlOM->ucBW = HE_GET_HTC_HE_OM_CH_WIDTH(u4Htc); + prHeActrlOM->fgDisMuUL = HE_GET_HTC_HE_OM_UL_MU_DISABLE(u4Htc); + prHeActrlOM->fgDisMuULData = + HE_GET_HTC_HE_OM_UL_MU_DATA_DISABLE(u4Htc); + } else + DBGLOG(RLM, WARN, "This is not Operating mode (OM).\n"); +} + + +/*----------------------------------------------------------------------------*/ +/*! +* @brief This function will compose the QoS Null + HTC Data frame. +* +* @param[in] prAdapter Pointer to the Adapter structure. +* @param[in] pucBuffer Pointer to the frame buffer. +* @param[in] prStaRec Pointer to the STA_RECORD_T. +* @param[in] ucUP User Priority. +* @param[in] fgSetEOSP Set the EOSP bit. +* +* @return (none) +*/ +/*----------------------------------------------------------------------------*/ +void +heRlmComposeHtcNullFrame( + IN struct ADAPTER *prAdapter, + IN uint8_t *pucBuffer, + IN struct STA_RECORD *prStaRec, + IN uint8_t ucUP, + IN u_int8_t fgSetEOSP) +{ + struct WLAN_MAC_HEADER_HT *prQoSNullFrame; + struct BSS_INFO *prBssInfo; + uint16_t u2FrameCtrl; + uint16_t u2QosControl; + uint8_t ucBssIndex; + + ASSERT(prStaRec); + ucBssIndex = prStaRec->ucBssIndex; + + ASSERT(ucBssIndex <= prAdapter->ucHwBssIdNum); + + ASSERT(pucBuffer); + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + ASSERT(prBssInfo); + + prQoSNullFrame = (struct WLAN_MAC_HEADER_HT *) pucBuffer; + + /* 4 <1> Decide the Frame Control Field */ +#if 0 + u2FrameCtrl = MAC_FRAME_QOS_DATA | MASK_FC_ORDER; +#else + u2FrameCtrl = MAC_FRAME_QOS_NULL | MASK_FC_ORDER; +#endif + + if (IS_AP_STA(prStaRec)) { + u2FrameCtrl |= MASK_FC_TO_DS; + } else if (IS_CLIENT_STA(prStaRec)) { + u2FrameCtrl |= MASK_FC_FROM_DS; + } else if (IS_DLS_STA(prStaRec)) { + /* TODO(Kevin) */ + } else { + /* NOTE(Kevin): We won't send QoS Null frame for IBSS */ + ASSERT(0); + return; + } + + /* 4 <2> Compose the QoS Null frame */ + /* Fill the Frame Control field. */ + /* WLAN_SET_FIELD_16(&prQoSNullFrame->u2FrameCtrl, u2FrameCtrl); */ + prQoSNullFrame->u2FrameCtrl = u2FrameCtrl; + + /* Fill the Address 1 field with Target Peer Address. */ + COPY_MAC_ADDR(prQoSNullFrame->aucAddr1, prStaRec->aucMacAddr); + + /* Fill the Address 2 field with our MAC Address. */ + COPY_MAC_ADDR(prQoSNullFrame->aucAddr2, prBssInfo->aucOwnMacAddr); + + /* Fill the Address 3 field with Target BSSID. */ + COPY_MAC_ADDR(prQoSNullFrame->aucAddr3, prBssInfo->aucBSSID); + + /* Clear the SEQ/FRAG_NO field */ + /* (HW won't overide the FRAG_NO, so we need to clear it). */ + prQoSNullFrame->u2SeqCtrl = 0; + + u2QosControl = (uint16_t) (ucUP & WMM_QC_UP_MASK); + + if (fgSetEOSP) + u2QosControl |= WMM_QC_EOSP; + + prQoSNullFrame->u2QosCtrl = u2QosControl; + +#ifdef CFG_AX_CERT_WKR + HE_SET_HTC_2ND_A_CTRL_ID(prAdapter->u4HeHtcOM, HTC_HE_A_CTRL_UPH); + HE_SET_HTC_HE_UPH(prAdapter->u4HeHtcOM, 10); + HE_SET_HTC_HE_UPH_MIN_TX_PWR_FLAG(prAdapter->u4HeHtcOM, 0); +#endif + + prQoSNullFrame->u4HtCtrl = prAdapter->u4HeHtcOM; + + return; + +} /* end of bssComposeQoSNullFrameHeader() */ + +uint32_t heRlmSendHtcNullFrame( + IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, + IN uint8_t ucUP, + IN PFN_TX_DONE_HANDLER pfTxDoneHandler) +{ + struct MSDU_INFO *prMsduInfo; + uint16_t u2EstimatedFrameLen; + + /* 4 <1> Allocate a PKT_INFO_T for Null Frame */ + /* Init with MGMT Header Length */ + u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + + WLAN_MAC_HEADER_QOS_HTC_LEN; + + /* Allocate a MSDU_INFO_T */ + prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); + if (prMsduInfo == NULL) { + DBGLOG(RLM, WARN, "No PKT_INFO_T for sending Null Frame.\n"); + return WLAN_STATUS_RESOURCES; + } + /* 4 <2> Compose Null frame in MSDU_INfO_T. */ + heRlmComposeHtcNullFrame(prAdapter, + (uint8_t *)((unsigned long)(prMsduInfo->prPacket) + + MAC_TX_RESERVED_FIELD), + prStaRec, ucUP, FALSE); + + TX_SET_MMPDU(prAdapter, + prMsduInfo, + prStaRec->ucBssIndex, + prStaRec->ucIndex, + WLAN_MAC_HEADER_QOS_HTC_LEN, + WLAN_MAC_HEADER_QOS_HTC_LEN, + pfTxDoneHandler, + MSDU_RATE_MODE_AUTO); + + prMsduInfo->fgMgmtUseDataQ = TRUE; + /* prMsduInfo->ucUserPriority = 0;*/ + prMsduInfo->u4Option |= MSDU_OPT_NO_AGGREGATE; + prMsduInfo->u4Option |= MSDU_OPT_SW_HTC; + /* 4 <4> Inform TXM to send this Null frame. */ + nicTxEnqueueMsdu(prAdapter, prMsduInfo); + + return WLAN_STATUS_SUCCESS; + +} /* end of bssSendQoSNullFrame() */ + +void heRlmInit( + struct ADAPTER *prAdapter) +{ + struct __HE_CFG_INFO_T *prHeCfg; + + prHeCfg = &prAdapter->rHeCfg; + prHeCfg->fgHeSupport = TRUE; + /* It can be disabled by wifi.cfg or iwpriv command */ + prHeCfg->fgHeEnable = TRUE; + /* It can be disabled by wifi.cfg or iwpriv command */ + prHeCfg->fgTwtRequesterEnable = TRUE; +} +#endif /* CFG_SUPPORT_802_11AX == 1 */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/hem_mbox.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/hem_mbox.c new file mode 100644 index 0000000000000000000000000000000000000000..ae0ec4574c6e96292ebef469b2a449ef6d7b91f1 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/hem_mbox.c @@ -0,0 +1,643 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: mgmt/hem_mbox.c + */ + +/*! \file "hem_mbox.c" + * \brief + * + */ + + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ +#if DBG +/*lint -save -e64 Type mismatch */ +static uint8_t *apucDebugMsg[] = { + (uint8_t *) DISP_STRING("MID_MNY_CNM_CH_REQ"), + (uint8_t *) DISP_STRING("MID_MNY_CNM_CH_ABORT"), + (uint8_t *) DISP_STRING("MID_CNM_AIS_CH_GRANT"), + (uint8_t *) DISP_STRING("MID_CNM_P2P_CH_GRANT"), + (uint8_t *) DISP_STRING("MID_CNM_BOW_CH_GRANT"), + +#if (CFG_SUPPORT_DFS_MASTER == 1) + (uint8_t *) DISP_STRING("MID_CNM_P2P_RADAR_DETECT"), + (uint8_t *) DISP_STRING("MID_CNM_P2P_CSA_DONE"), +#endif + (uint8_t *) DISP_STRING("MID_AIS_SCN_SCAN_REQ"), + (uint8_t *) DISP_STRING("MID_AIS_SCN_SCAN_REQ_V2"), + (uint8_t *) DISP_STRING("MID_AIS_SCN_SCAN_CANCEL"), + (uint8_t *) DISP_STRING("MID_P2P_SCN_SCAN_REQ"), + (uint8_t *) DISP_STRING("MID_P2P_SCN_SCAN_REQ_V2"), + (uint8_t *) DISP_STRING("MID_P2P_SCN_SCAN_CANCEL"), + (uint8_t *) DISP_STRING("MID_BOW_SCN_SCAN_REQ"), + (uint8_t *) DISP_STRING("MID_BOW_SCN_SCAN_REQ_V2"), + (uint8_t *) DISP_STRING("MID_BOW_SCN_SCAN_CANCEL"), + (uint8_t *) DISP_STRING("MID_RLM_SCN_SCAN_REQ"), + (uint8_t *) DISP_STRING("MID_RLM_SCN_SCAN_REQ_V2"), + (uint8_t *) DISP_STRING("MID_RLM_SCN_SCAN_CANCEL"), + (uint8_t *) DISP_STRING("MID_SCN_AIS_SCAN_DONE"), + (uint8_t *) DISP_STRING("MID_SCN_P2P_SCAN_DONE"), + (uint8_t *) DISP_STRING("MID_SCN_BOW_SCAN_DONE"), + (uint8_t *) DISP_STRING("MID_SCN_RLM_SCAN_DONE"), + + (uint8_t *) DISP_STRING("MID_OID_AIS_FSM_JOIN_REQ"), + (uint8_t *) DISP_STRING("MID_OID_AIS_FSM_ABORT"), + (uint8_t *) DISP_STRING("MID_AIS_SAA_FSM_START"), + (uint8_t *) DISP_STRING("MID_OID_SAA_FSM_CONTINUE"), + (uint8_t *) DISP_STRING("MID_OID_SAA_FSM_EXTERNAL_AUTH"), + (uint8_t *) DISP_STRING("MID_AIS_SAA_FSM_ABORT"), + (uint8_t *) DISP_STRING("MID_SAA_AIS_JOIN_COMPLETE"), + +#if CFG_ENABLE_BT_OVER_WIFI + (uint8_t *) DISP_STRING("MID_BOW_SAA_FSM_START"), + (uint8_t *) DISP_STRING("MID_BOW_SAA_FSM_ABORT"), + (uint8_t *) DISP_STRING("MID_SAA_BOW_JOIN_COMPLETE"), +#endif + +#if CFG_ENABLE_WIFI_DIRECT + (uint8_t *) DISP_STRING("MID_P2P_SAA_FSM_START"), + (uint8_t *) DISP_STRING("MID_P2P_SAA_FSM_ABORT"), + (uint8_t *) DISP_STRING("MID_SAA_P2P_JOIN_COMPLETE"), + + (uint8_t *) DISP_STRING("MID_MNY_P2P_FUN_SWITCH"), + (uint8_t *) DISP_STRING("MID_MNY_P2P_DEVICE_DISCOVERY"), + (uint8_t *) DISP_STRING("MID_MNY_P2P_CONNECTION_REQ"), + (uint8_t *) DISP_STRING("MID_MNY_P2P_CONNECTION_ABORT"), + (uint8_t *) DISP_STRING("MID_MNY_P2P_BEACON_UPDATE"), + (uint8_t *) DISP_STRING("MID_MNY_P2P_STOP_AP"), + (uint8_t *) DISP_STRING("MID_MNY_P2P_CHNL_REQ"), + (uint8_t *) DISP_STRING("MID_MNY_P2P_CHNL_ABORT"), + (uint8_t *) DISP_STRING("MID_MNY_P2P_MGMT_TX"), + (uint8_t *) DISP_STRING("MID_MNY_P2P_MGMT_TX_CANCEL_WAIT"), + (uint8_t *) DISP_STRING("MID_MNY_P2P_GROUP_DISSOLVE"), + (uint8_t *) DISP_STRING("MID_MNY_P2P_MGMT_FRAME_REGISTER"), + (uint8_t *) DISP_STRING("MID_MNY_P2P_NET_DEV_REGISTER"), + (uint8_t *) DISP_STRING("MID_MNY_P2P_START_AP"), + (uint8_t *) DISP_STRING("MID_MNY_P2P_DEL_IFACE"), + (uint8_t *) DISP_STRING("MID_MNY_P2P_MGMT_FRAME_UPDATE"), +#if (CFG_SUPPORT_DFS_MASTER == 1) + (uint8_t *) DISP_STRING("MID_MNY_P2P_DFS_CAC"), + (uint8_t *) DISP_STRING("MID_MNY_P2P_SET_NEW_CHANNEL"), +#endif +#if CFG_SUPPORT_WFD + (uint8_t *) DISP_STRING("MID_MNY_P2P_WFD_CFG_UPDATE"), +#endif + (uint8_t *) DISP_STRING("MID_MNY_P2P_ACTIVE_BSS"), +#endif + +#if CFG_SUPPORT_ADHOC + (uint8_t *) DISP_STRING("MID_SCN_AIS_FOUND_IBSS"), +#endif /* CFG_SUPPORT_ADHOC */ + + (uint8_t *) DISP_STRING("MID_SAA_AIS_FSM_ABORT"), + (uint8_t *) DISP_STRING("MID_MNY_AIS_REMAIN_ON_CHANNEL"), + (uint8_t *) DISP_STRING("MID_MNY_AIS_CANCEL_REMAIN_ON_CHANNEL"), + (uint8_t *) DISP_STRING("MID_MNY_AIS_MGMT_TX"), + (uint8_t *) DISP_STRING("MID_MNY_AIS_MGMT_TX_CANCEL_WAIT"), + (uint8_t *) DISP_STRING("MID_WNM_AIS_BSS_TRANSITION"), +#if CFG_SUPPORT_NCHO + (uint8_t *) DISP_STRING("MID_MNY_AIS_NCHO_ACTION_FRAME") +#endif + (uint8_t *) DISP_STRING("MID_MNY_P2P_ACS"), + +#if (CFG_SUPPORT_TWT == 1) + (uint8_t *) DISP_STRING("MID_TWT_REQ_FSM_START"), + (uint8_t *) DISP_STRING("MID_TWT_REQ_FSM_TEARDOWN"), + (uint8_t *) DISP_STRING("MID_TWT_REQ_FSM_SUSPEND"), + (uint8_t *) DISP_STRING("MID_TWT_REQ_FSM_RESUME"), + (uint8_t *) DISP_STRING("MID_TWT_REQ_IND_RESULT"), + (uint8_t *) DISP_STRING("MID_TWT_REQ_IND_SUSPEND_DONE"), + (uint8_t *) DISP_STRING("MID_TWT_REQ_IND_RESUME_DONE"), + (uint8_t *) DISP_STRING("MID_TWT_REQ_IND_TEARDOWN_DONE"), + (uint8_t *) DISP_STRING("MID_TWT_REQ_IND_INFOFRM"), + (uint8_t *) DISP_STRING("MID_TWT_PARAMS_SET"), +#endif + +}; + +/*lint -restore */ +#endif /* DBG */ + +/* This message entry will be re-ordered based on the message ID order + * by invoking mboxInitMsgMap() + */ +static struct MSG_HNDL_ENTRY arMsgMapTable[] = { + {MID_MNY_CNM_CH_REQ, cnmChMngrRequestPrivilege}, + {MID_MNY_CNM_CH_ABORT, cnmChMngrAbortPrivilege}, + {MID_CNM_AIS_CH_GRANT, aisFsmRunEventChGrant}, +#if CFG_ENABLE_WIFI_DIRECT + /*set in gl_p2p_init.c */ + {MID_CNM_P2P_CH_GRANT, p2pFsmRunEventChGrant}, +#else + {MID_CNM_P2P_CH_GRANT, mboxDummy}, +#endif + +#if (CFG_SUPPORT_DFS_MASTER == 1) + {MID_CNM_P2P_RADAR_DETECT, p2pRoleFsmRunEventRadarDet}, + {MID_CNM_P2P_CSA_DONE, p2pRoleFsmRunEventCsaDone}, +#endif + +#if CFG_ENABLE_BT_OVER_WIFI + {MID_CNM_BOW_CH_GRANT, bowRunEventChGrant}, +#else + {MID_CNM_BOW_CH_GRANT, mboxDummy}, +#endif + + /*--------------------------------------------------*/ + /* SCN Module Mailbox Messages */ + /*--------------------------------------------------*/ + {MID_AIS_SCN_SCAN_REQ, scnFsmMsgStart}, + {MID_AIS_SCN_SCAN_REQ_V2, scnFsmMsgStart}, + {MID_AIS_SCN_SCAN_CANCEL, scnFsmMsgAbort}, + {MID_P2P_SCN_SCAN_REQ, scnFsmMsgStart}, + {MID_P2P_SCN_SCAN_REQ_V2, scnFsmMsgStart}, + {MID_P2P_SCN_SCAN_CANCEL, scnFsmMsgAbort}, + {MID_BOW_SCN_SCAN_REQ, scnFsmMsgStart}, + {MID_BOW_SCN_SCAN_REQ_V2, scnFsmMsgStart}, + {MID_BOW_SCN_SCAN_CANCEL, scnFsmMsgAbort}, + {MID_RLM_SCN_SCAN_REQ, scnFsmMsgStart}, + {MID_RLM_SCN_SCAN_REQ_V2, scnFsmMsgStart}, + {MID_RLM_SCN_SCAN_CANCEL, scnFsmMsgAbort}, + {MID_SCN_AIS_SCAN_DONE, aisFsmRunEventScanDone}, +#if CFG_ENABLE_WIFI_DIRECT + /*set in gl_p2p_init.c */ + {MID_SCN_P2P_SCAN_DONE, p2pFsmRunEventScanDone}, +#else + {MID_SCN_P2P_SCAN_DONE, mboxDummy}, +#endif + +#if CFG_ENABLE_BT_OVER_WIFI + {MID_SCN_BOW_SCAN_DONE, bowResponderScanDone}, +#else + {MID_SCN_BOW_SCAN_DONE, mboxDummy}, +#endif + {MID_SCN_RLM_SCAN_DONE, rlmObssScanDone}, + + /*--------------------------------------------------*/ + /* AIS Module Mailbox Messages */ + /*--------------------------------------------------*/ + {MID_OID_AIS_FSM_JOIN_REQ, aisFsmRunEventAbort}, + {MID_OID_AIS_FSM_ABORT, aisFsmRunEventAbort}, + {MID_AIS_SAA_FSM_START, saaFsmRunEventStart}, + {MID_OID_SAA_FSM_CONTINUE, saaFsmRunEventFTContinue}, + {MID_OID_SAA_FSM_EXTERNAL_AUTH, saaFsmRunEventExternalAuthDone}, + {MID_AIS_SAA_FSM_ABORT, saaFsmRunEventAbort}, + {MID_SAA_AIS_JOIN_COMPLETE, aisFsmRunEventJoinComplete}, + +#if CFG_ENABLE_BT_OVER_WIFI + /*--------------------------------------------------*/ + /* BOW Module Mailbox Messages */ + /*--------------------------------------------------*/ + {MID_BOW_SAA_FSM_START, saaFsmRunEventStart}, + {MID_BOW_SAA_FSM_ABORT, saaFsmRunEventAbort}, + {MID_SAA_BOW_JOIN_COMPLETE, bowFsmRunEventJoinComplete}, +#endif + +#if CFG_ENABLE_WIFI_DIRECT /*set in gl_p2p_init.c */ + {MID_P2P_SAA_FSM_START, saaFsmRunEventStart}, + {MID_P2P_SAA_FSM_ABORT, saaFsmRunEventAbort}, + {MID_SAA_P2P_JOIN_COMPLETE, p2pRoleFsmRunEventJoinComplete}, /* V */ + + {MID_MNY_P2P_FUN_SWITCH, p2pRoleFsmRunEventSwitchOPMode}, + {MID_MNY_P2P_DEVICE_DISCOVERY, p2pFsmRunEventScanRequest}, /* V */ + {MID_MNY_P2P_CONNECTION_REQ, p2pRoleFsmRunEventConnectionRequest}, + {MID_MNY_P2P_CONNECTION_ABORT, p2pRoleFsmRunEventConnectionAbort}, + {MID_MNY_P2P_BEACON_UPDATE, p2pRoleFsmRunEventBeaconUpdate}, + {MID_MNY_P2P_STOP_AP, p2pRoleFsmRunEventStopAP}, + {MID_MNY_P2P_CHNL_REQ, p2pDevFsmRunEventChannelRequest}, /* V */ + {MID_MNY_P2P_CHNL_ABORT, p2pDevFsmRunEventChannelAbort}, /* V */ + {MID_MNY_P2P_MGMT_TX, p2pFsmRunEventMgmtFrameTx}, /* V */ + {MID_MNY_P2P_MGMT_TX_CANCEL_WAIT, p2pFsmRunEventTxCancelWait}, + {MID_MNY_P2P_GROUP_DISSOLVE, p2pRoleFsmRunEventDissolve}, + {MID_MNY_P2P_MGMT_FRAME_REGISTER, + p2pDevFsmRunEventMgmtFrameRegister}, + {MID_MNY_P2P_NET_DEV_REGISTER, p2pFsmRunEventNetDeviceRegister}, + {MID_MNY_P2P_START_AP, p2pRoleFsmRunEventStartAP}, + {MID_MNY_P2P_DEL_IFACE, p2pRoleFsmRunEventDelIface}, + {MID_MNY_P2P_MGMT_FRAME_UPDATE, p2pFsmRunEventUpdateMgmtFrame}, +#if (CFG_SUPPORT_DFS_MASTER == 1) + {MID_MNY_P2P_DFS_CAC, p2pRoleFsmRunEventDfsCac}, + {MID_MNY_P2P_SET_NEW_CHANNEL, p2pRoleFsmRunEventSetNewChannel}, +#endif +#if CFG_SUPPORT_WFD + {MID_MNY_P2P_WFD_CFG_UPDATE, p2pFsmRunEventWfdSettingUpdate}, +#endif + {MID_MNY_P2P_ACTIVE_BSS, p2pDevFsmRunEventActiveDevBss}, +#endif + +#if CFG_SUPPORT_ADHOC + {MID_SCN_AIS_FOUND_IBSS, aisFsmRunEventFoundIBSSPeer}, +#endif /* CFG_SUPPORT_ADHOC */ + + {MID_SAA_AIS_FSM_ABORT, aisFsmRunEventAbort}, + {MID_MNY_AIS_REMAIN_ON_CHANNEL, + aisFsmRunEventRemainOnChannel}, + {MID_MNY_AIS_CANCEL_REMAIN_ON_CHANNEL, + aisFsmRunEventCancelRemainOnChannel}, + {MID_MNY_AIS_MGMT_TX, aisFsmRunEventMgmtFrameTx}, + {MID_MNY_AIS_MGMT_TX_CANCEL_WAIT, aisFsmRunEventCancelTxWait}, + {MID_WNM_AIS_BSS_TRANSITION, aisFsmRunEventBssTransition}, + {MID_OID_WMM_TSPEC_OPERATE, wmmRunEventTSOperate}, + {MID_RRM_REQ_SCHEDULE, rrmRunEventProcessNextRm}, +#if CFG_SUPPORT_NCHO + {MID_MNY_AIS_NCHO_ACTION_FRAME, + aisFsmRunEventNchoActionFrameTx}, +#endif + {MID_MNY_P2P_ACS, p2pRoleFsmRunEventAcs}, + +#if (CFG_SUPPORT_TWT == 1) + {MID_TWT_REQ_FSM_START, twtReqFsmRunEventStart}, + {MID_TWT_REQ_FSM_TEARDOWN, twtReqFsmRunEventTeardown}, + {MID_TWT_REQ_FSM_SUSPEND, twtReqFsmRunEventSuspend}, + {MID_TWT_REQ_FSM_RESUME, twtReqFsmRunEventResume}, + {MID_TWT_REQ_IND_RESULT, twtPlannerRxNegoResult}, + {MID_TWT_REQ_IND_SUSPEND_DONE, twtPlannerSuspendDone}, + {MID_TWT_REQ_IND_RESUME_DONE, twtPlannerResumeDone}, + {MID_TWT_REQ_IND_TEARDOWN_DONE, twtPlannerTeardownDone}, + {MID_TWT_REQ_IND_INFOFRM, twtPlannerRxInfoFrm}, + {MID_TWT_PARAMS_SET, twtPlannerSetParams}, +#endif + +}; + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +#if DBG +#define MBOX_HNDL_MSG(prAdapter, prMsg) do { \ + if (prMsg->eMsgId >= 0 && prMsg->eMsgId < MID_TOTAL_NUM) { \ + ASSERT(arMsgMapTable[prMsg->eMsgId].pfMsgHndl); \ + if (arMsgMapTable[prMsg->eMsgId].pfMsgHndl) { \ + DBGLOG(CNM, LOUD, \ + "DO MSG [%d: %s]\n", \ + prMsg->eMsgId, apucDebugMsg[prMsg->eMsgId]); \ + arMsgMapTable[prMsg->eMsgId].pfMsgHndl( \ + prAdapter, prMsg); \ + } \ + else { \ + DBGLOG(CNM, ERROR, "NULL fptr for MSG [%d]\n", \ + prMsg->eMsgId); \ + cnmMemFree(prAdapter, prMsg); \ + } \ + } \ + else { \ + DBGLOG(CNM, ERROR, "Invalid MSG ID [%d]\n", prMsg->eMsgId); \ + cnmMemFree(prAdapter, prMsg); \ + } \ +} while (0) +#else +#define MBOX_HNDL_MSG(prAdapter, prMsg) do { \ + if (prMsg->eMsgId >= 0 && prMsg->eMsgId < MID_TOTAL_NUM) { \ + ASSERT(arMsgMapTable[prMsg->eMsgId].pfMsgHndl); \ + if (arMsgMapTable[prMsg->eMsgId].pfMsgHndl) { \ + DBGLOG(CNM, LOUD, "DO MSG [%d]\n", prMsg->eMsgId); \ + arMsgMapTable[prMsg->eMsgId].pfMsgHndl( \ + prAdapter, prMsg); \ + } \ + else { \ + DBGLOG(CNM, ERROR, "NULL fptr for MSG [%d]\n", \ + prMsg->eMsgId); \ + cnmMemFree(prAdapter, prMsg); \ + } \ + } \ + else { \ + DBGLOG(CNM, ERROR, "Invalid MSG ID [%d]\n", prMsg->eMsgId); \ + cnmMemFree(prAdapter, prMsg); \ + } \ +} while (0) +#endif +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void mboxInitMsgMap(void) +{ + uint32_t i, idx; + struct MSG_HNDL_ENTRY rTempEntry; + + ASSERT((sizeof(arMsgMapTable) / sizeof(struct + MSG_HNDL_ENTRY)) == MID_TOTAL_NUM); + + for (i = 0; i < MID_TOTAL_NUM; i++) { + if (arMsgMapTable[i].eMsgId == (enum ENUM_MSG_ID) i) + continue; + for (idx = i + 1; idx < MID_TOTAL_NUM; idx++) { + if (arMsgMapTable[idx].eMsgId == (enum ENUM_MSG_ID) i) + break; + } + ASSERT(idx < MID_TOTAL_NUM); + if (idx >= MID_TOTAL_NUM) + continue; + + /* Swap target entry and current entry */ + rTempEntry.eMsgId = arMsgMapTable[idx].eMsgId; + rTempEntry.pfMsgHndl = arMsgMapTable[idx].pfMsgHndl; + + arMsgMapTable[idx].eMsgId = arMsgMapTable[i].eMsgId; + arMsgMapTable[idx].pfMsgHndl = arMsgMapTable[i].pfMsgHndl; + + arMsgMapTable[i].eMsgId = rTempEntry.eMsgId; + arMsgMapTable[i].pfMsgHndl = rTempEntry.pfMsgHndl; + } + + /* Verify the correctness of final message map */ + for (i = 0; i < MID_TOTAL_NUM; i++) { + ASSERT(arMsgMapTable[i].eMsgId == (enum ENUM_MSG_ID) i); + while (arMsgMapTable[i].eMsgId != (enum ENUM_MSG_ID) i) + ; + } + +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void mboxSetup(IN struct ADAPTER *prAdapter, + IN enum ENUM_MBOX_ID eMboxId) +{ + struct MBOX *prMbox; + + KAL_SPIN_LOCK_DECLARATION(); + + ASSERT(eMboxId < MBOX_ID_TOTAL_NUM); + ASSERT(prAdapter); + + prMbox = &(prAdapter->arMbox[eMboxId]); + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); + LINK_INITIALIZE(&prMbox->rLinkHead); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void +mboxSendMsg(IN struct ADAPTER *prAdapter, + IN enum ENUM_MBOX_ID eMboxId, IN struct MSG_HDR *prMsg, + IN enum EUNM_MSG_SEND_METHOD eMethod) +{ + struct MBOX *prMbox; + + KAL_SPIN_LOCK_DECLARATION(); + + ASSERT(eMboxId < MBOX_ID_TOTAL_NUM); + ASSERT(prMsg); + if (!prMsg) { + DBGLOG(CNM, ERROR, "prMsg is NULL\n"); + return; + } + + ASSERT(prAdapter); + if (!prAdapter) { + DBGLOG(CNM, ERROR, "prAdapter is NULL\n"); + return; + } + + prMbox = &(prAdapter->arMbox[eMboxId]); + + switch (eMethod) { + case MSG_SEND_METHOD_BUF: + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); + LINK_INSERT_TAIL(&prMbox->rLinkHead, &prMsg->rLinkEntry); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); + + /* to wake up main service thread */ + GLUE_SET_EVENT(prAdapter->prGlueInfo); + + break; + + case MSG_SEND_METHOD_UNBUF: + MBOX_HNDL_MSG(prAdapter, prMsg); + break; + + default: + ASSERT(0); + break; + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void mboxRcvAllMsg(IN struct ADAPTER *prAdapter, + enum ENUM_MBOX_ID eMboxId) +{ + struct MBOX *prMbox; + struct MSG_HDR *prMsg; + + KAL_SPIN_LOCK_DECLARATION(); + + ASSERT(eMboxId < MBOX_ID_TOTAL_NUM); + ASSERT(prAdapter); + + prMbox = &(prAdapter->arMbox[eMboxId]); + + while (!LINK_IS_EMPTY(&prMbox->rLinkHead)) { + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); + LINK_REMOVE_HEAD(&prMbox->rLinkHead, prMsg, + struct MSG_HDR *); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); + + ASSERT(prMsg); + if (!prMsg) { + DBGLOG(CNM, ERROR, "prMsg is NULL\n"); + continue; + } +#ifdef UT_TEST_MODE + if (testMBoxRcv(prAdapter, prMsg)) +#endif + MBOX_HNDL_MSG(prAdapter, prMsg); + } + +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void mboxInitialize(IN struct ADAPTER *prAdapter) +{ + uint32_t i; + + ASSERT(prAdapter); + + /* Initialize Mailbox */ + mboxInitMsgMap(); + + /* Setup/initialize each mailbox */ + for (i = 0; i < MBOX_ID_TOTAL_NUM; i++) + mboxSetup(prAdapter, i); + +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void mboxDestroy(IN struct ADAPTER *prAdapter) +{ + struct MBOX *prMbox; + struct MSG_HDR *prMsg; + uint8_t i; + + KAL_SPIN_LOCK_DECLARATION(); + + ASSERT(prAdapter); + + for (i = 0; i < MBOX_ID_TOTAL_NUM; i++) { + prMbox = &(prAdapter->arMbox[i]); + + while (!LINK_IS_EMPTY(&prMbox->rLinkHead)) { + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); + LINK_REMOVE_HEAD(&prMbox->rLinkHead, prMsg, + struct MSG_HDR *); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); + + ASSERT(prMsg); + cnmMemFree(prAdapter, prMsg); + } + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This is dummy function to prevent empty arMsgMapTable[] + * for compiling. + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void mboxDummy(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + ASSERT(prAdapter); + + cnmMemFree(prAdapter, prMsgHdr); +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/hs20.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/hs20.c new file mode 100644 index 0000000000000000000000000000000000000000..71deac15d69daa053e3ea5eee9e6f0f9126dc0ee --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/hs20.c @@ -0,0 +1,601 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/HS2_DEV_SW/ + * MT6620_WIFI_DRIVER_V2_1_HS_2_0/mgmt/hs20.c#2 + */ + +/*! \file "hs20.c" + * \brief This file including the hotspot 2.0 related function. + * + * This file provided the macros and functions library support for the + * protocol layer hotspot 2.0 related function. + * + */ + + +/****************************************************************************** + * C O M P I L E R F L A G S + ****************************************************************************** + */ + +/****************************************************************************** + * E X T E R N A L R E F E R E N C E S + ****************************************************************************** + */ +#include "precomp.h" + +#if CFG_SUPPORT_PASSPOINT + +/****************************************************************************** + * C O N S T A N T S + ****************************************************************************** + */ + +/****************************************************************************** + * D A T A T Y P E S + ****************************************************************************** + */ + +/****************************************************************************** + * P U B L I C D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * P R I V A T E D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * M A C R O S + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N D E C L A R A T I O N S + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N S + ****************************************************************************** + */ + +void hs20FillExtCapIE(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, struct MSDU_INFO *prMsduInfo) +{ + struct IE_EXT_CAP *prExtCap; + struct HS20_INFO *prHS20Info; + uint8_t ucBssIndex = 0; + + ASSERT(prAdapter); + ASSERT(prMsduInfo); + + ucBssIndex = prMsduInfo->ucBssIndex; + prHS20Info = aisGetHS20Info(prAdapter, ucBssIndex); + if (!prHS20Info) + return; + + /* Add Extended Capabilities IE */ + prExtCap = (struct IE_EXT_CAP *) + (((uint8_t *) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength); + + prExtCap->ucId = ELEM_ID_EXTENDED_CAP; + if (prHS20Info->fgConnectHS20AP == TRUE) + prExtCap->ucLength = ELEM_MAX_LEN_EXT_CAP; + else + prExtCap->ucLength = 3 - ELEM_HDR_LEN; + + kalMemZero(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP); + + prExtCap->aucCapabilities[0] = ELEM_EXT_CAP_DEFAULT_VAL; + + if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) + prExtCap->aucCapabilities[0] &= ~ELEM_EXT_CAP_PSMP_CAP; + + if (prHS20Info->fgConnectHS20AP == TRUE) { + SET_EXT_CAP(prExtCap->aucCapabilities, + ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_BSS_TRANSITION_BIT); + SET_EXT_CAP(prExtCap->aucCapabilities, + ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_UTC_TSF_OFFSET_BIT); + SET_EXT_CAP(prExtCap->aucCapabilities, + ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_INTERWORKING_BIT); + SET_EXT_CAP(prExtCap->aucCapabilities, + ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_QOSMAPSET_BIT); + + /* For R2 WNM-Notification */ + SET_EXT_CAP(prExtCap->aucCapabilities, + ELEM_MAX_LEN_EXT_CAP, + ELEM_EXT_CAP_WNM_NOTIFICATION_BIT); + } + + pr_info("IE_SIZE(prExtCap) = %d, %d %d\n", + IE_SIZE(prExtCap), ELEM_HDR_LEN, ELEM_MAX_LEN_EXT_CAP); + + ASSERT(IE_SIZE(prExtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP)); + + prMsduInfo->u2FrameLength += IE_SIZE(prExtCap); +} + +/*---------------------------------------------------------------------------*/ +/*! + * \brief This function is called to fill up + * the content of Ext Cap IE bit 31. + * + * \param[in] prAdapter Pointer of ADAPTER_T + * \param[out] pucIE Pointer of the IE buffer + * + * \return VOID + */ +/*---------------------------------------------------------------------------*/ +void hs20FillProreqExtCapIE(IN struct ADAPTER *prAdapter, OUT uint8_t *pucIE) +{ + struct IE_EXT_CAP *prExtCap; + struct HS20_INFO *prHS20Info; + + ASSERT(prAdapter); + + prHS20Info = aisGetHS20Info(prAdapter, + AIS_DEFAULT_INDEX); + if (!prHS20Info) + return; + + /* Add Extended Capabilities IE */ + prExtCap = (struct IE_EXT_CAP *) pucIE; + + prExtCap->ucId = ELEM_ID_EXTENDED_CAP; + if (prHS20Info->fgConnectHS20AP == TRUE) + prExtCap->ucLength = ELEM_MAX_LEN_EXT_CAP; + else + prExtCap->ucLength = 3 - ELEM_HDR_LEN; + + kalMemZero(prExtCap->aucCapabilities, prExtCap->ucLength); + + prExtCap->aucCapabilities[0] = ELEM_EXT_CAP_DEFAULT_VAL; + + if (prHS20Info->fgConnectHS20AP == TRUE) { + SET_EXT_CAP(prExtCap->aucCapabilities, + ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_BSS_TRANSITION_BIT); + SET_EXT_CAP(prExtCap->aucCapabilities, + ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_UTC_TSF_OFFSET_BIT); + SET_EXT_CAP(prExtCap->aucCapabilities, + ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_INTERWORKING_BIT); + SET_EXT_CAP(prExtCap->aucCapabilities, + ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_QOSMAPSET_BIT); + + /* For R2 WNM-Notification */ + SET_EXT_CAP(prExtCap->aucCapabilities, + ELEM_MAX_LEN_EXT_CAP, + ELEM_EXT_CAP_WNM_NOTIFICATION_BIT); + } +} + +/*---------------------------------------------------------------------------*/ +/*! + * \brief This function is called to fill up the content of HS2.0 IE. + * + * \param[in] prAdapter Pointer of ADAPTER_T + * \param[out] pucIE Pointer of the IE buffer + * + * \return VOID + */ +/*---------------------------------------------------------------------------*/ +void hs20FillHS20IE(IN struct ADAPTER *prAdapter, OUT uint8_t *pucIE) +{ + struct IE_HS20_INDICATION *prHS20IndicationIe; + /* P_HS20_INFO_T prHS20Info; */ + uint8_t aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC; + + /* prHS20Info = &(prAdapter->rWifiVar.rHS20Info); */ + + prHS20IndicationIe = (struct IE_HS20_INDICATION *) pucIE; + + prHS20IndicationIe->ucId = ELEM_ID_VENDOR; + prHS20IndicationIe->ucLength = + sizeof(struct IE_HS20_INDICATION) - ELEM_HDR_LEN; + prHS20IndicationIe->aucOui[0] = aucWfaOui[0]; + prHS20IndicationIe->aucOui[1] = aucWfaOui[1]; + prHS20IndicationIe->aucOui[2] = aucWfaOui[2]; + prHS20IndicationIe->ucType = VENDOR_OUI_TYPE_HS20; + + /* For PASSPOINT_R1 */ + /* prHS20IndicationIe->ucHotspotConfig = 0x00; */ + + /* For PASSPOINT_R2 */ + prHS20IndicationIe->ucHotspotConfig = 0x10; + +} + +/*---------------------------------------------------------------------------*/ +/*! + * \brief This function is called while calculating length of + * hotspot 2.0 indication IE for Probe Request. + * + * \param[in] prAdapter Pointer of ADAPTER_T + * \param[in] pucTargetBSSID Pointer of target HESSID + * + * \return the length of composed HS20 IE + */ +/*---------------------------------------------------------------------------*/ +uint32_t hs20CalculateHS20RelatedIEForProbeReq(IN struct ADAPTER *prAdapter, + IN uint8_t *pucTargetBSSID) +{ + uint32_t u4IeLength; + + if (0) /* Todo:: Not HS20 STA */ + return 0; + + u4IeLength = sizeof(struct IE_HS20_INDICATION) + + /* sizeof(IE_INTERWORKING_T) */ + + (ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP); + + if (!pucTargetBSSID) { + /* Todo:: Nothing */ + /* u4IeLength -= MAC_ADDR_LEN; */ + } + + return u4IeLength; +} + +/*---------------------------------------------------------------------------*/ +/*! + * \brief This function is called while composing + * hotspot 2.0 indication IE for Probe Request. + * + * \param[in] prAdapter Pointer of ADAPTER_T + * \param[in] pucTargetBSSID Pointer of target HESSID + * \param[out] prIE Pointer of the IE buffer + * + * \return the wlan status + */ +/*---------------------------------------------------------------------------*/ +uint32_t hs20GenerateHS20RelatedIEForProbeReq(IN struct ADAPTER *prAdapter, + IN uint8_t *pucTargetBSSID, OUT uint8_t *prIE) +{ + if (0) /* Todo:: Not HS20 STA */ + return 0; +#if 0 + struct HS20_INFO *prHS20Info; + + prHS20Info = &(prAdapter->rWifiVar.rHS20Info); + + /* + * Generate 802.11u Interworking IE (107) + */ + hs20FillInterworkingIE(prAdapter, + prHS20Info->ucAccessNetworkOptions, + prHS20Info->ucVenueGroup, + prHS20Info->ucVenueType, + pucTargetBSSID, prIE); + prIE += IE_SIZE(prIE); +#endif + /* + * Generate Ext Cap IE (127) + */ + hs20FillProreqExtCapIE(prAdapter, prIE); + prIE += IE_SIZE(prIE); + + /* + * Generate HS2.0 Indication IE (221) + */ + hs20FillHS20IE(prAdapter, prIE); + prIE += IE_SIZE(prIE); + + return WLAN_STATUS_SUCCESS; +} + +u_int8_t hs20IsGratuitousArp(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prCurrSwRfb) +{ + uint8_t *pucSenderIP = + prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + ARP_SENDER_IP_OFFSET; + uint8_t *pucTargetIP = + prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + ARP_TARGET_IP_OFFSET; + uint8_t *pucSenderMac = ((uint8_t *) + prCurrSwRfb->pvHeader + + ETHER_HEADER_LEN + ARP_SENDER_MAC_OFFSET); + +#if CFG_HS20_DEBUG && 0 +/* UINT_8 aucIpAllZero[4] = {0,0,0,0}; */ +/* UINT_8 aucMACAllZero[MAC_ADDR_LEN] = {0,0,0,0,0,0}; */ + uint8_t *pucTargetMac = ((uint8_t *) + prCurrSwRfb->pvHeader + + ETHER_HEADER_LEN + ARP_TARGET_MAC_OFFSET); +#endif + +#if CFG_HS20_DEBUG && 0 + uint16_t *pu2ArpOper = (uint16_t *) ((uint8_t *) + prCurrSwRfb->pvHeader + + ETHER_HEADER_LEN + ARP_OPERATION_OFFSET); + + kalPrint("Recv ARP 0x%04X\n", htons(*pu2ArpOper)); + kalPrint("SENDER[" MACSTR "] [%d:%d:%d:%d]\n", + MAC2STR(pucSenderMac), *pucSenderIP, + *(pucSenderIP + 1), *(pucSenderIP + 2), *(pucSenderIP + 3)); + kalPrint("TARGET[" MACSTR "] [%d:%d:%d:%d]\n", + MAC2STR(pucTargetMac), *pucTargetIP, + *(pucTargetIP + 1), *(pucTargetIP + 2), *(pucTargetIP + 3)); +#endif + + /* IsGratuitousArp */ + if (!kalMemCmp(pucSenderIP, pucTargetIP, 4)) { + kalPrint( + "Drop Gratuitous ARP from [" MACSTR "] [%d:%d:%d:%d]\n", + MAC2STR(pucSenderMac), *pucTargetIP, *(pucTargetIP + 1), + *(pucTargetIP + 2), *(pucTargetIP + 3)); + return TRUE; + } + return FALSE; +} + +u_int8_t hs20IsUnsolicitedNeighborAdv(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prCurrSwRfb) +{ + uint8_t *pucIpv6Protocol = ((uint8_t *) + prCurrSwRfb->pvHeader + + ETHER_HEADER_LEN + IPV6_HDR_IP_PROTOCOL_OFFSET); + + /* kalPrint("pucIpv6Protocol [%02X:%02X]\n", + * *pucIpv6Protocol, IPV6_PROTOCOL_ICMPV6); + */ + if (*pucIpv6Protocol == IPV6_PROTOCOL_ICMPV6) { + uint8_t *pucICMPv6Type = + ((uint8_t *) prCurrSwRfb->pvHeader + + ETHER_HEADER_LEN + IPV6_HDR_LEN + ICMPV6_TYPE_OFFSET); + /* kalPrint("pucICMPv6Type [%02X:%02X]\n", + * *pucICMPv6Type, ICMPV6_TYPE_NEIGHBOR_ADVERTISEMENT); + */ + if (*pucICMPv6Type == ICMPV6_TYPE_NEIGHBOR_ADVERTISEMENT) { + uint8_t *pucICMPv6Flag = + ((uint8_t *) prCurrSwRfb->pvHeader + + ETHER_HEADER_LEN + + IPV6_HDR_LEN + ICMPV6_FLAG_OFFSET); + uint8_t *pucSrcMAC = ((uint8_t *) + prCurrSwRfb->pvHeader + MAC_ADDR_LEN); + +#if CFG_HS20_DEBUG + kalPrint("NAdv Flag [%02X] [R(%d)\\S(%d)\\O(%d)]\n", + *pucICMPv6Flag, + (uint8_t) (*pucICMPv6Flag + & ICMPV6_FLAG_ROUTER_BIT) >> 7, + (uint8_t) (*pucICMPv6Flag + & ICMPV6_FLAG_SOLICITED_BIT) >> 6, + (uint8_t) (*pucICMPv6Flag + & ICMPV6_FLAG_OVERWRITE_BIT) >> 5); +#endif + if (!(*pucICMPv6Flag & ICMPV6_FLAG_SOLICITED_BIT)) { + kalPrint( + "Drop Unsolicited Neighbor Advertisement from [" + MACSTR "]\n", MAC2STR(pucSrcMAC)); + return TRUE; + } + } + } + + return FALSE; +} + +#if CFG_ENABLE_GTK_FRAME_FILTER +u_int8_t hs20IsForgedGTKFrame(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo, IN struct SW_RFB *prCurrSwRfb) +{ + struct CONNECTION_SETTINGS *prConnSettings = + aisGetConnSettings(prAdapter, prBssInfo->ucBssIndex); + uint8_t *pucEthDestAddr = prCurrSwRfb->pvHeader; + + /* 3 TODO: Need to verify this function before enable it */ + return FALSE; + + if ((prConnSettings->eEncStatus != ENUM_ENCRYPTION_DISABLED) + && IS_BMCAST_MAC_ADDR(pucEthDestAddr)) { + uint8_t ucIdx = 0; + uint32_t *prIpAddr, *prPacketDA; + uint16_t *pu2PktIpVer = + (uint16_t *) ((uint8_t *) + prCurrSwRfb->pvHeader + + (ETHER_HEADER_LEN - ETHER_TYPE_LEN)); + + if (*pu2PktIpVer == htons(ETH_P_IPV4)) { + if (!prBssInfo->prIpV4NetAddrList) + return FALSE; + for (ucIdx = 0; + ucIdx < prBssInfo + ->prIpV4NetAddrList->ucAddrCount; + ucIdx++) { + prIpAddr = (uint32_t *) + &prBssInfo->prIpV4NetAddrList + ->arNetAddr[ucIdx].aucIpAddr[0]; + prPacketDA = + (uint32_t *) ((uint8_t *) + prCurrSwRfb->pvHeader + + ETHER_HEADER_LEN + + IPV4_HDR_IP_DST_ADDR_OFFSET); + + if (kalMemCmp(prIpAddr, prPacketDA, 4) == 0) { + kalPrint("Drop FORGED IPv4 packet\n"); + return TRUE; + } + } + } +#ifdef CONFIG_IPV6 + else if (*pu2PktIpVer == htons(ETH_P_IPV6)) { + uint8_t aucIPv6Mac[MAC_ADDR_LEN]; + uint8_t *pucIdx = + prCurrSwRfb->pvHeader + + ETHER_HEADER_LEN + + IPV6_HDR_IP_DST_ADDR_MAC_HIGH_OFFSET; + + kalMemCopy(&aucIPv6Mac[0], pucIdx, 3); + pucIdx += 5; + kalMemCopy(&aucIPv6Mac[3], pucIdx, 3); + kalPrint( + "Get IPv6 frame Dst IP MAC part " MACSTR "\n", + MAC2STR(aucIPv6Mac)); + + if (EQUAL_MAC_ADDR(aucIPv6Mac, + prBssInfo->aucOwnMacAddr)) { + kalPrint("Drop FORGED IPv6 packet\n"); + return TRUE; + } + } +#endif + } + + return FALSE; +} +#endif + +u_int8_t hs20IsUnsecuredFrame(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo, IN struct SW_RFB *prCurrSwRfb) +{ + uint16_t *pu2PktIpVer = (uint16_t *) ((uint8_t *) + prCurrSwRfb->pvHeader + (ETHER_HEADER_LEN - ETHER_TYPE_LEN)); + + /* kalPrint("IPVER 0x%4X\n", htons(*pu2PktIpVer)); */ +#if CFG_HS20_DEBUG & 0 + uint8_t i = 0; + + kalPrint("==============================================="); + for (i = 0; i < 96; i++) { + if (!(i % 16)) + kalPrint("\n"); + kalPrint("%02X ", *((uint8_t *) prCurrSwRfb->pvHeader + i)); + } + kalPrint("\n"); +#endif + +#if CFG_ENABLE_GTK_FRAME_FILTER + if (hs20IsForgedGTKFrame(prAdapter, prBssInfo, prCurrSwRfb)) + return TRUE; +#endif + if (*pu2PktIpVer == htons(ETH_P_ARP)) + return hs20IsGratuitousArp(prAdapter, prCurrSwRfb); + else if (*pu2PktIpVer == htons(ETH_P_IPV6)) + return hs20IsUnsolicitedNeighborAdv(prAdapter, prCurrSwRfb); + + return FALSE; +} + +u_int8_t hs20IsFrameFilterEnabled(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo) +{ +#if 1 + struct HS20_INFO *prHS20Info; + + prHS20Info = aisGetHS20Info(prAdapter, + prBssInfo->ucBssIndex); + + if (prHS20Info && prHS20Info->fgConnectHS20AP) + return TRUE; +#else + struct PARAM_SSID rParamSsid; + struct BSS_DESC *prBssDesc; + + rParamSsid.u4SsidLen = prBssInfo->ucSSIDLen; + COPY_SSID(rParamSsid.aucSsid, + rParamSsid.u4SsidLen, prBssInfo->aucSSID, prBssInfo->ucSSIDLen); + + prBssDesc = scanSearchBssDescByBssidAndSsid(prAdapter, + prBssInfo->aucBSSID, TRUE, &rParamSsid); + + if (!prBssDesc) + return FALSE; + + if (prBssDesc->fgIsSupportHS20) { + if (!(prBssDesc->ucHotspotConfig + & ELEM_HS_CONFIG_DGAF_DISABLED_MASK)) + return TRUE; + /* Disable frame filter only if DGAF == 1 */ + return FALSE; + } +#endif + + /* For Now, always return true to run hs20 check even for legacy AP */ + return TRUE; +} + +uint32_t hs20SetBssidPool(IN struct ADAPTER *prAdapter, + IN void *pvBuffer, + IN uint8_t ucBssIndex) +{ + struct PARAM_HS20_SET_BSSID_POOL *prParamBssidPool = + (struct PARAM_HS20_SET_BSSID_POOL *) pvBuffer; + struct HS20_INFO *prHS20Info; + uint8_t ucIdx; + + prHS20Info = aisGetHS20Info(prAdapter, ucBssIndex); + + pr_info("[%s]Set Bssid Pool! enable[%d] num[%d]\n", + __func__, prParamBssidPool->fgIsEnable, + prParamBssidPool->ucNumBssidPool); + + for (ucIdx = 0; ucIdx < prParamBssidPool->ucNumBssidPool; ucIdx++) { + COPY_MAC_ADDR( + prHS20Info->arBssidPool[ucIdx].aucBSSID, + &prParamBssidPool->arBSSID[ucIdx]); + + pr_info("[%s][%d][" MACSTR "]\n", + __func__, ucIdx, + MAC2STR(prHS20Info->arBssidPool[ucIdx].aucBSSID)); + } + prHS20Info->fgIsHS2SigmaMode = prParamBssidPool->fgIsEnable; + prHS20Info->ucNumBssidPoolEntry = prParamBssidPool->ucNumBssidPool; + +#if 0 + wlanClearScanningResult(prAdapter); +#endif + + return WLAN_STATUS_SUCCESS; +} + +#endif /* CFG_SUPPORT_PASSPOINT */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/mddp.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/mddp.c new file mode 100644 index 0000000000000000000000000000000000000000..e23e1c01ae05cddeae90a1713dbd36470c2b35ca --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/mddp.c @@ -0,0 +1,873 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +/* +** Id: @(#) mddp.c@@ +*/ + +/*! \file mddp.c +* \brief Main routines for modem direct path handling +* +* This file contains the support routines of modem direct path operation. +*/ + + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include "precomp.h" + +#if CFG_MTK_MCIF_WIFI_SUPPORT + +#include "gl_os.h" +#include "mddp_export.h" +#include "mddp.h" + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ +struct mddpw_drv_handle_t gMddpWFunc = { + mddpMdNotifyInfo, + NULL, + NULL, + NULL, + NULL, +}; + +struct mddp_drv_conf_t gMddpDrvConf = { + .app_type = MDDP_APP_TYPE_WH, +}; + +struct mddp_drv_handle_t gMddpFunc = { +#if CFG_MTK_MDDP_WH_SUPPORT + .change_state = mddpChangeState, +#endif +}; + +#define MD_ON_OFF_TIMEOUT 1000 +#ifdef SOC3_0 +#define MD_STATUS_SYNC_CR 0x180600F4 +#else +#define MD_STATUS_SYNC_CR 0x1800701C +#endif +#define MD_SUPPORT_MDDP_STATUS_SYNC_CR_BIT BIT(0) +#define MD_STATUS_OFF_SYNC_BIT BIT(1) +#define MD_STATUS_ON_SYNC_BIT BIT(2) + +#if (CFG_SUPPORT_CONNAC2X == 0) +/* Use SER dummy register for mddp support flag */ +#define MDDP_SUPPORT_CR 0x820600d0 +#define MDDP_SUPPORT_CR_BIT BIT(23) +#endif + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ +#define MAC_ADDR_LEN 6 + +struct mddp_txd_t { +uint8_t version; +uint8_t wlan_idx; +uint8_t sta_idx; +uint8_t nw_if_name[8]; +uint8_t sta_mode; +uint8_t bss_id; +uint8_t wmmset; +uint8_t aucMacAddr[MAC_ADDR_LEN]; +uint8_t txd_length; +uint8_t txd[0]; +} __packed; + +struct tag_bootmode { + u32 size; + u32 tag; + u32 bootmode; + u32 boottype; +}; + +enum BOOTMODE { + NORMAL_BOOT = 0, + META_BOOT = 1, + RECOVERY_BOOT = 2, + SW_REBOOT = 3, + FACTORY_BOOT = 4, + ADVMETA_BOOT = 5, + ATE_FACTORY_BOOT = 6, + ALARM_BOOT = 7, + KERNEL_POWER_OFF_CHARGING_BOOT = 8, + LOW_POWER_OFF_CHARGING_BOOT = 9, + FASTBOOT = 99, + DOWNLOAD_BOOT = 100, + UNKNOWN_BOOT +}; + +enum BOOTMODE g_wifi_boot_mode = NORMAL_BOOT; +u_int8_t g_fgMddpEnabled = TRUE; + +struct mddpw_net_stat_ext_t stats; + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +static void clear_md_wifi_off_bit(void); +static void clear_md_wifi_on_bit(void); +static bool wait_for_md_on_complete(void); +static void save_mddp_stats(void); + +static int32_t mddpRegisterCb(void) +{ + int32_t ret = 0; + + switch (g_wifi_boot_mode) { + case RECOVERY_BOOT: + g_fgMddpEnabled = FALSE; + break; + default: + g_fgMddpEnabled = TRUE; + break; + } + gMddpFunc.wifi_handle = &gMddpWFunc; + + ret = mddp_drv_attach(&gMddpDrvConf, &gMddpFunc); + +#if (CFG_SUPPORT_CONNAC2X == 0) + mtk_ccci_register_md_state_cb(&mddpMdStateChangedCb); +#endif + + DBGLOG(INIT, INFO, "mddp_drv_attach ret: %d, g_fgMddpEnabled: %d\n", + ret, g_fgMddpEnabled); + + kalMemZero(&stats, sizeof(struct mddpw_net_stat_ext_t)); + + return ret; +} + +static void mddpUnregisterCb(void) +{ + DBGLOG(INIT, INFO, "mddp_drv_detach\n"); + mddp_drv_detach(&gMddpDrvConf, &gMddpFunc); + gMddpFunc.wifi_handle = NULL; +} + +int32_t mddpGetMdStats(IN struct net_device *prDev) +{ + struct NETDEV_PRIVATE_GLUE_INFO *prNetDevPrivate; + struct net_device_stats *prStats; + struct GLUE_INFO *prGlueInfo; + struct mddpw_net_stat_ext_t mddpNetStats; + int32_t ret; + uint8_t i = 0; + + if (!gMddpWFunc.get_net_stat_ext) + return 0; + + prNetDevPrivate = (struct NETDEV_PRIVATE_GLUE_INFO *) + netdev_priv(prDev); + prStats = &prNetDevPrivate->stats; + prGlueInfo = prNetDevPrivate->prGlueInfo; + + if (!prGlueInfo || (prGlueInfo->u4ReadyFlag == 0) || + !prGlueInfo->prAdapter) + return 0; + + if (!prNetDevPrivate->ucMddpSupport) + return 0; + + ret = gMddpWFunc.get_net_stat_ext(&mddpNetStats); + if (ret != 0) { + DBGLOG(INIT, ERROR, "get_net_stat fail, ret: %d.\n", ret); + return 0; + } + for (i = 0; i < NW_IF_NUM_MAX; i++) { + struct mddpw_net_stat_elem_ext_t *element, *prev; + + element = &mddpNetStats.ifs[0][i]; + prev = &stats.ifs[0][i]; + if (kalStrnCmp(element->nw_if_name, prDev->name, + IFNAMSIZ) != 0) + continue; + + prStats->rx_packets += + element->rx_packets + prev->rx_packets; + prStats->tx_packets += + element->tx_packets + prev->tx_packets; + prStats->rx_bytes += + element->rx_bytes + prev->rx_bytes; + prStats->tx_bytes += + element->tx_bytes + prev->tx_bytes; + prStats->rx_errors += + element->rx_errors + prev->rx_errors; + prStats->tx_errors += + element->tx_errors + prev->tx_errors; + prStats->rx_dropped += + element->rx_dropped + prev->rx_dropped; + prStats->tx_dropped += + element->tx_dropped + prev->tx_dropped; + } + + return 0; +} + +int32_t mddpSetTxDescTemplate(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, + IN uint8_t fgActivate) +{ + struct mddpw_txd_t *prMddpTxd; + uint32_t u32BufSize = 0; + uint8_t *buff = NULL; + + if (gMddpWFunc.add_txd) { + int32_t ret; + + u32BufSize = (sizeof(struct mddpw_txd_t) + + NIC_TX_DESC_LONG_FORMAT_LENGTH); + buff = kalMemAlloc(u32BufSize, VIR_MEM_TYPE); + + if (buff == NULL) { + DBGLOG(NIC, ERROR, "Can't allocate TXD buffer.\n"); + return -1; + } + prMddpTxd = (struct mddpw_txd_t *) buff; + prMddpTxd->version = 0; + prMddpTxd->sta_idx = prStaRec->ucIndex; + prMddpTxd->wlan_idx = prStaRec->ucWlanIndex; + memcpy(prMddpTxd->aucMacAddr, + prStaRec->aucMacAddr, MAC_ADDR_LEN); + if (fgActivate) + prMddpTxd->txd_length = NIC_TX_DESC_LONG_FORMAT_LENGTH; + else + prMddpTxd->txd_length = 0; + memcpy(prMddpTxd->txd, + prStaRec->aprTxDescTemplate[0], prMddpTxd->txd_length); + ret = gMddpWFunc.add_txd(prMddpTxd); + DBGLOG(NIC, INFO, "ret: %d\n", ret); + kalMemFree(buff, VIR_MEM_TYPE, u32BufSize); + } else { + DBGLOG(INIT, ERROR, "add_txd is NULL.\n"); + } + + return 0; +} + +static bool mddpIsSsnSent(struct ADAPTER *prAdapter, + uint8_t *prReorderBuf, uint16_t u2SSN) +{ + uint8_t ucSent = 0; + uint16_t u2Idx = u2SSN / 8; + uint8_t ucBit = u2SSN % 8; + + ucSent = (prReorderBuf[u2Idx] & BIT(ucBit)) != 0; + prReorderBuf[u2Idx] &= ~(BIT(ucBit)); + + return ucSent; +} + +static void mddpGetRxReorderBuffer(struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb, + struct mddpw_md_virtual_buf_t **prMdBuf, + struct mddpw_ap_virtual_buf_t **prApBuf) +{ + struct mddpw_md_reorder_sync_table_t *prMdTable = NULL; + struct mddpw_ap_reorder_sync_table_t *prApTable = NULL; + uint8_t ucStaRecIdx = prSwRfb->ucStaRecIdx; + uint8_t ucTid = prSwRfb->ucTid; + int32_t u4Idx = 0; + + if (gMddpWFunc.get_md_rx_reorder_buf && + gMddpWFunc.get_ap_rx_reorder_buf) { + if (!gMddpWFunc.get_md_rx_reorder_buf(&prMdTable) && + !gMddpWFunc.get_ap_rx_reorder_buf(&prApTable)) { + u4Idx = prMdTable->reorder_info[ucStaRecIdx].buf_idx; + *prMdBuf = &prMdTable->virtual_buf[u4Idx][ucTid]; + *prApBuf = &prApTable->virtual_buf[u4Idx][ucTid]; + } + } +} + +void mddpUpdateReorderQueParm(struct ADAPTER *prAdapter, + struct RX_BA_ENTRY *prReorderQueParm, + struct SW_RFB *prSwRfb) +{ + struct mddpw_md_virtual_buf_t *prMdBuf = NULL; + struct mddpw_ap_virtual_buf_t *prApBuf = NULL; + uint16_t u2SSN = prReorderQueParm->u2WinStart, u2Idx; + + mddpGetRxReorderBuffer(prAdapter, prSwRfb, &prMdBuf, &prApBuf); + if (!prMdBuf || !prApBuf) { + DBGLOG(QM, ERROR, "Can't get reorder buffer.\n"); + return; + } + + for (u2Idx = 0; u2Idx < prReorderQueParm->u2WinSize; u2Idx++) { + if (prReorderQueParm->u2WinStart == prSwRfb->u2SSN || + !mddpIsSsnSent(prAdapter, prMdBuf->virtual_buf, u2SSN)) + break; + + prReorderQueParm->u2WinStart = + (u2SSN % MAX_SEQ_NO_COUNT); + prReorderQueParm->u2WinEnd = + (((prReorderQueParm->u2WinStart) + + (prReorderQueParm->u2WinSize) - 1) % + MAX_SEQ_NO_COUNT); + u2SSN = (u2SSN + 1) % MAX_SEQ_NO_COUNT; + DBGLOG(QM, TRACE, + "Update reorder window: SSN: %d, start: %d, end: %d.\n", + u2SSN, + prReorderQueParm->u2WinStart, + prReorderQueParm->u2WinEnd); + } + + prApBuf->start_idx = prReorderQueParm->u2WinStart; + prApBuf->end_idx = prReorderQueParm->u2WinEnd; +} + +int32_t mddpNotifyDrvTxd(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, + IN uint8_t fgActivate) +{ + struct mddpw_drv_notify_info_t *prNotifyInfo; + struct mddpw_drv_info_t *prDrvInfo; + struct mddp_txd_t *prMddpTxd; + struct BSS_INFO *prBssInfo = (struct BSS_INFO *) NULL; + struct net_device *prNetdev; + struct NETDEV_PRIVATE_GLUE_INFO *prNetDevPrivate; + uint32_t u32BufSize = 0; + uint8_t *buff = NULL; + int32_t ret = 0; + + if (!gMddpWFunc.notify_drv_info) { + DBGLOG(NIC, ERROR, "notify_drv_info callback NOT exist.\n"); + ret = -1; + goto exit; + } + if (!prStaRec) { + DBGLOG(NIC, ERROR, "sta NOT valid\n"); + ret = -1; + goto exit; + } + if (prStaRec->ucBssIndex >= MAX_BSSID_NUM) { + DBGLOG(NIC, ERROR, "sta bssid NOT valid: %d.\n", + prStaRec->ucBssIndex); + ret = -1; + goto exit; + } + if (fgActivate && !prStaRec->aprTxDescTemplate[0]) { + DBGLOG(NIC, INFO, + "sta[%d]'s TXD NOT generated done, maybe wait.\n", + prStaRec->ucBssIndex); + ret = -1; + goto exit; + } + + prBssInfo = prAdapter->aprBssInfo[prStaRec->ucBssIndex]; + prNetdev = (struct net_device *) wlanGetNetInterfaceByBssIdx( + prAdapter->prGlueInfo, prStaRec->ucBssIndex); + prNetDevPrivate = (struct NETDEV_PRIVATE_GLUE_INFO *) + netdev_priv(prNetdev); + + if (!prNetDevPrivate->ucMddpSupport) { + goto exit; + } + + u32BufSize = (sizeof(struct mddpw_drv_notify_info_t) + + sizeof(struct mddpw_drv_info_t) + + sizeof(struct mddp_txd_t) + + NIC_TX_DESC_LONG_FORMAT_LENGTH); + buff = kalMemAlloc(u32BufSize, VIR_MEM_TYPE); + + if (buff == NULL) { + DBGLOG(NIC, ERROR, "buffer allocation failed.\n"); + ret = -1; + goto exit; + } + prNotifyInfo = (struct mddpw_drv_notify_info_t *) buff; + prNotifyInfo->version = 0; + prNotifyInfo->buf_len = sizeof(struct mddpw_drv_info_t) + + sizeof(struct mddp_txd_t) + + NIC_TX_DESC_LONG_FORMAT_LENGTH; + prNotifyInfo->info_num = 1; + prDrvInfo = (struct mddpw_drv_info_t *) &(prNotifyInfo->buf[0]); + prDrvInfo->info_id = 3; /* MDDPW_DRV_INFO_TXD; */ + prDrvInfo->info_len = (sizeof(struct mddpw_txd_t) + + NIC_TX_DESC_LONG_FORMAT_LENGTH); + prMddpTxd = (struct mddp_txd_t *) &(prDrvInfo->info[0]); + prMddpTxd->version = 0; + prMddpTxd->sta_idx = prStaRec->ucIndex; + prMddpTxd->wlan_idx = prStaRec->ucWlanIndex; + prMddpTxd->sta_mode = prStaRec->eStaType; + prMddpTxd->bss_id = prStaRec->ucBssIndex; + prMddpTxd->wmmset = prBssInfo->ucWmmQueSet; + kalMemCopy(prMddpTxd->nw_if_name, prNetdev->name, + sizeof(prMddpTxd->nw_if_name)); + kalMemCopy(prMddpTxd->aucMacAddr, prStaRec->aucMacAddr, MAC_ADDR_LEN); + if (fgActivate) { + prMddpTxd->txd_length = NIC_TX_DESC_LONG_FORMAT_LENGTH; + kalMemCopy(prMddpTxd->txd, prStaRec->aprTxDescTemplate[0], + prMddpTxd->txd_length); + } else { + prMddpTxd->txd_length = 0; + } + + ret = gMddpWFunc.notify_drv_info(prNotifyInfo); + +#define TEMP_LOG_TEMPLATE "ver:%d,idx:%d,w_idx:%d,mod:%d,bss:%d,wmm:%d," \ + "name:%s,act:%d,ret:%d" + DBGLOG(NIC, INFO, TEMP_LOG_TEMPLATE, + prMddpTxd->version, + prMddpTxd->sta_idx, + prMddpTxd->wlan_idx, + prMddpTxd->sta_mode, + prMddpTxd->bss_id, + prMddpTxd->wmmset, + prMddpTxd->nw_if_name, + fgActivate, + ret); +#undef TEMP_LOG_TEMPLATE + +exit: + if (buff) + kalMemFree(buff, VIR_MEM_TYPE, u32BufSize); + return ret; +} + +int32_t mddpNotifyDrvMac(IN struct ADAPTER *prAdapter) +{ + struct mddpw_drv_notify_info_t *prNotifyInfo; + struct mddpw_drv_info_t *prDrvInfo; + uint32_t u32BufSize = 0; + uint8_t *buff = NULL; + struct BSS_INFO *prAisBssInfo = (struct BSS_INFO *) NULL; + + if (gMddpWFunc.notify_drv_info) { + int32_t ret; + + u32BufSize = (sizeof(struct mddpw_drv_notify_info_t) + + sizeof(struct mddpw_drv_info_t) + MAC_ADDR_LEN); + buff = kalMemAlloc(u32BufSize, VIR_MEM_TYPE); + + if (buff == NULL) { + DBGLOG(NIC, ERROR, "Can't allocate TXD buffer.\n"); + return -1; + } + prNotifyInfo = (struct mddpw_drv_notify_info_t *) buff; + prNotifyInfo->version = 0; + prNotifyInfo->buf_len = sizeof(struct mddpw_drv_info_t) + + MAC_ADDR_LEN; + prNotifyInfo->info_num = 1; + prDrvInfo = (struct mddpw_drv_info_t *) &(prNotifyInfo->buf[0]); + prDrvInfo->info_id = MDDPW_DRV_INFO_DEVICE_MAC; + prDrvInfo->info_len = MAC_ADDR_LEN; + /*SY MCIF TBC 0916*/ + prAisBssInfo = prAdapter->prAisBssInfo[0]; + COPY_MAC_ADDR(prDrvInfo->info, prAisBssInfo->aucOwnMacAddr); + + ret = gMddpWFunc.notify_drv_info(prNotifyInfo); + DBGLOG(INIT, INFO, "ret: %d.\n", ret); + kalMemFree(buff, VIR_MEM_TYPE, u32BufSize); + } else { + DBGLOG(INIT, ERROR, "notify_drv_info is NULL.\n"); + } + + return 0; +} + +int32_t mddpNotifyWifiStatus(IN enum mddp_drv_onoff_status wifiOnOffStatus) +{ + struct mddpw_drv_notify_info_t *prNotifyInfo; + struct mddpw_drv_info_t *prDrvInfo; + uint32_t u32BufSize = 0; + uint8_t *buff = NULL; + int32_t ret = 0; + + if (gMddpWFunc.notify_drv_info) { + int32_t ret; + + u32BufSize = (sizeof(struct mddpw_drv_notify_info_t) + + sizeof(struct mddpw_drv_info_t) + sizeof(bool)); + buff = kalMemAlloc(u32BufSize, VIR_MEM_TYPE); + + if (buff == NULL) { + DBGLOG(NIC, ERROR, "Can't allocate buffer.\n"); + return -1; + } + prNotifyInfo = (struct mddpw_drv_notify_info_t *) buff; + prNotifyInfo->version = 0; + prNotifyInfo->buf_len = sizeof(struct mddpw_drv_info_t) + + sizeof(bool); + prNotifyInfo->info_num = 1; + prDrvInfo = (struct mddpw_drv_info_t *) &(prNotifyInfo->buf[0]); + prDrvInfo->info_id = MDDPW_DRV_INFO_NOTIFY_WIFI_ONOFF; + prDrvInfo->info_len = WIFI_ONOFF_NOTIFICATION_LEN; + prDrvInfo->info[0] = wifiOnOffStatus; + + ret = gMddpWFunc.notify_drv_info(prNotifyInfo); + DBGLOG(INIT, INFO, "power: %d, ret: %d.\n", + wifiOnOffStatus, ret); + kalMemFree(buff, VIR_MEM_TYPE, u32BufSize); + } else { + DBGLOG(INIT, ERROR, "notify_drv_info is NULL.\n"); + ret = -1; + } + + return ret; +} + +void mddpNotifyWifiOnStart(void) +{ + mddpRegisterCb(); + mddpNotifyWifiStatus(MDDPW_DRV_INFO_WLAN_ON_START); +} + +int32_t mddpNotifyWifiOnEnd(void) +{ + int32_t ret; + + clear_md_wifi_on_bit(); + ret = mddpNotifyWifiStatus(MDDPW_DRV_INFO_WLAN_ON_END); + if (ret == 0) + ret = wait_for_md_on_complete() ? + WLAN_STATUS_SUCCESS : + WLAN_STATUS_FAILURE; + return ret; +} + +void mddpNotifyWifiOffStart(void) +{ + int32_t ret; + +#if (CFG_SUPPORT_CONNAC2X == 0) + mtk_ccci_register_md_state_cb(NULL); +#endif + clear_md_wifi_off_bit(); + ret = mddpNotifyWifiStatus(MDDPW_DRV_INFO_WLAN_OFF_START); +} + +void mddpNotifyWifiOffEnd(void) +{ + mddpNotifyWifiStatus(MDDPW_DRV_INFO_WLAN_OFF_END); + mddpUnregisterCb(); +} + +int32_t mddpMdNotifyInfo(struct mddpw_md_notify_info_t *prMdInfo) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + u_int8_t fgHalted = kalIsHalted(); + + DBGLOG(INIT, INFO, "MD notify mddpMdNotifyInfo.\n"); + + if (gPrDev == NULL) { + DBGLOG(INIT, ERROR, "gPrDev is NULL.\n"); + return 0; + } + + prGlueInfo = *((struct GLUE_INFO **)netdev_priv(gPrDev)); + if (prGlueInfo == NULL) { + DBGLOG(INIT, ERROR, "prGlueInfo is NULL.\n"); + return 0; + } + prAdapter = prGlueInfo->prAdapter; + if (prAdapter == NULL) { + DBGLOG(INIT, ERROR, "prAdapter is NULL.\n"); + return 0; + } + + if (fgHalted || !prGlueInfo->u4ReadyFlag) { + DBGLOG(INIT, INFO, + "Skip update info. to MD, fgHalted: %d, u4ReadyFlag: %d\n", + fgHalted, prGlueInfo->u4ReadyFlag); + return 0; + } + + if (prMdInfo->info_type == 1) { + uint32_t i; + struct BSS_INFO *prP2pBssInfo = (struct BSS_INFO *) NULL; + int32_t ret; + + save_mddp_stats(); + mddpNotifyWifiOnStart(); + ret = mddpNotifyWifiOnEnd(); + if (ret != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, INFO, "mddpNotifyWifiOnEnd failed.\n"); + return 0; + } + mddpNotifyDrvMac(prAdapter); + + /* Notify STA's TXD to MD */ + for (i = 0; i < KAL_AIS_NUM; i++) { + struct BSS_INFO *prAisBssInfo = aisGetAisBssInfo( + prAdapter, + i); + + if (prAisBssInfo && prAisBssInfo->eConnectionState == + MEDIA_STATE_CONNECTED) + mddpNotifyDrvTxd(prAdapter, + prAisBssInfo->prStaRecOfAP, + TRUE); + } + /* Notify SAP clients' TXD to MD */ + prP2pBssInfo = cnmGetSapBssInfo(prAdapter); + if (prP2pBssInfo) { + struct LINK *prClientList; + struct STA_RECORD *prCurrStaRec; + + prClientList = &prP2pBssInfo->rStaRecOfClientList; + LINK_FOR_EACH_ENTRY(prCurrStaRec, prClientList, + rLinkEntry, struct STA_RECORD) { + if (!prCurrStaRec) + break; + mddpNotifyDrvTxd(prAdapter, + prCurrStaRec, + TRUE); + } + } + } + return 0; +} + +#if CFG_MTK_MDDP_WH_SUPPORT +int32_t mddpChangeState(enum mddp_state_e event, void *buf, uint32_t *buf_len) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + u_int8_t fgHalted = kalIsHalted(); + + if (gPrDev == NULL) { + DBGLOG(INIT, ERROR, "gPrDev is NULL.\n"); + return 0; + } + + prGlueInfo = *((struct GLUE_INFO **)netdev_priv(gPrDev)); + if (prGlueInfo == NULL) { + DBGLOG(INIT, ERROR, "prGlueInfo is NULL.\n"); + return 0; + } + + if (fgHalted || !prGlueInfo->u4ReadyFlag) { + DBGLOG(INIT, ERROR, "fgHalted: %d, u4ReadyFlag: %d\n", + fgHalted, prGlueInfo->u4ReadyFlag); + return 0; + } + + prAdapter = prGlueInfo->prAdapter; + if (prAdapter == NULL) { + DBGLOG(INIT, ERROR, "prAdapter is NULL.\n"); + return 0; + } + + switch (event) { + case MDDP_STATE_ENABLING: + break; + + case MDDP_STATE_ACTIVATING: + break; + + case MDDP_STATE_ACTIVATED: + DBGLOG(INIT, INFO, "Mddp activated.\n"); + prAdapter->fgMddpActivated = true; + break; + + case MDDP_STATE_DEACTIVATING: + break; + + case MDDP_STATE_DEACTIVATED: + DBGLOG(INIT, INFO, "Mddp deactivated.\n"); + prAdapter->fgMddpActivated = false; + break; + + case MDDP_STATE_DISABLING: + case MDDP_STATE_UNINIT: + case MDDP_STATE_CNT: + case MDDP_STATE_DUMMY: + default: + break; + } + + return 0; + +} +#endif + +static void clear_md_wifi_off_bit(void) +{ + uint32_t u4Value = 0; + + DBGLOG(INIT, INFO, "md off start.\n"); + wf_ioremap_read(MD_STATUS_SYNC_CR, &u4Value); + u4Value |= MD_STATUS_OFF_SYNC_BIT; + wf_ioremap_write(MD_STATUS_SYNC_CR, u4Value); +} + +static void clear_md_wifi_on_bit(void) +{ + uint32_t u4Value = 0; + + wf_ioremap_read(MD_STATUS_SYNC_CR, &u4Value); + u4Value &= ~MD_STATUS_ON_SYNC_BIT; + wf_ioremap_write(MD_STATUS_SYNC_CR, u4Value); +} + +static bool wait_for_md_on_complete(void) +{ + uint32_t u4Value = 0; + uint32_t u4StartTime, u4CurTime; + bool fgCompletion = false; + struct GLUE_INFO *prGlueInfo = NULL; + + u4StartTime = kalGetTimeTick(); + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(gPrDev)); + if (!prGlueInfo) { + DBGLOG(INIT, ERROR, "prGlueInfo is NULL.\n"); + return false; + } + + do { + wf_ioremap_read(MD_STATUS_SYNC_CR, &u4Value); + + if ((u4Value & MD_STATUS_ON_SYNC_BIT) > 0) { + DBGLOG(INIT, INFO, "md on end.\n"); + fgCompletion = true; + break; + } else if (!prGlueInfo->u4ReadyFlag) { + DBGLOG(INIT, WARN, "Skip waiting due to ready flag.\n"); + fgCompletion = false; + break; + } + + u4CurTime = kalGetTimeTick(); + if (CHECK_FOR_TIMEOUT(u4CurTime, u4StartTime, + MD_ON_OFF_TIMEOUT)) { + DBGLOG(INIT, ERROR, "wait for md on timeout\n"); + fgCompletion = false; + break; + } + + kalMsleep(CFG_RESPONSE_POLLING_DELAY); + } while (TRUE); + + return fgCompletion; +} + +void setMddpSupportRegister(IN struct ADAPTER *prAdapter) +{ +#if (CFG_SUPPORT_CONNAC2X == 0) + uint32_t u4Val = 0; + + HAL_MCR_RD(prAdapter, MDDP_SUPPORT_CR, &u4Val); + if (g_fgMddpEnabled) + u4Val |= MDDP_SUPPORT_CR_BIT; + else + u4Val &= ~MDDP_SUPPORT_CR_BIT; + HAL_MCR_WR(prAdapter, MDDP_SUPPORT_CR, u4Val); +#endif +} + +void mddpInit(void) +{ + struct device_node *np_chosen; + struct tag_bootmode *tag = NULL; + + np_chosen = of_find_node_by_path("/chosen"); + if (!np_chosen) + np_chosen = of_find_node_by_path("/chosen@0"); + + if (!np_chosen) + return; + + tag = (struct tag_bootmode *) of_get_property(np_chosen, "atag,boot", + NULL); + + if (!tag) + return; + + DBGLOG(INIT, INFO, "bootmode: 0x%x\n", tag->bootmode); + g_wifi_boot_mode = tag->bootmode; +} + +static void notifyMdCrash2FW(void) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + if (gPrDev == NULL) { + DBGLOG(INIT, ERROR, "gPrDev is NULL.\n"); + return; + } + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(gPrDev)); + if (!prGlueInfo || !prGlueInfo->u4ReadyFlag) { + DBGLOG(INIT, ERROR, "Invalid drv state.\n"); + return; + } + kalSetMdCrashEvent(prGlueInfo); +} + +void mddpMdStateChangedCb(enum MD_STATE old_state, + enum MD_STATE new_state) +{ + DBGLOG(INIT, TRACE, "old_state: %d, new_state: %d.\n", + old_state, new_state); + + switch (new_state) { + case GATED: /* MD off */ + case EXCEPTION: /* MD crash */ + notifyMdCrash2FW(); + break; + default: + break; + } +} + +static void save_mddp_stats(void) +{ + struct mddpw_net_stat_ext_t temp; + uint8_t i = 0; + int32_t ret; + + if (!gMddpWFunc.get_net_stat_ext) + return; + + ret = gMddpWFunc.get_net_stat_ext(&temp); + if (ret != 0) { + DBGLOG(INIT, ERROR, "get_net_stat fail, ret: %d.\n", ret); + return; + } + + for (i = 0; i < NW_IF_NUM_MAX; i++) { + struct mddpw_net_stat_elem_ext_t *element, *curr; + + element = &temp.ifs[0][i]; + curr = &stats.ifs[0][i]; + + curr->rx_packets += element->rx_packets; + curr->tx_packets += element->tx_packets; + curr->rx_bytes += element->rx_bytes; + curr->tx_bytes += element->tx_bytes; + curr->rx_errors += element->rx_errors; + curr->tx_errors += element->tx_errors; + curr->rx_dropped += element->rx_dropped; + curr->tx_dropped += element->tx_dropped; + } +} + +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/mib.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/mib.c new file mode 100644 index 0000000000000000000000000000000000000000..33e39063f03ca3107af55b43104856312d995a8b --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/mib.c @@ -0,0 +1,138 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/mib.c#1 + */ + +/*! \file "mib.c" + * \brief This file includes the mib default vale and functions. + */ + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ +const struct NON_HT_PHY_ATTRIBUTE rNonHTPhyAttributes[] = { + {RATE_SET_HR_DSSS, TRUE, FALSE} + , /* For PHY_TYPE_HR_DSSS_INDEX(0) */ + {RATE_SET_ERP, TRUE, TRUE} + , /* For PHY_TYPE_ERP_INDEX(1) */ + {RATE_SET_ERP_P2P, TRUE, TRUE} + , /* For PHY_TYPE_ERP_P2P_INDEX(2) */ + {RATE_SET_OFDM, FALSE, FALSE} + , /* For PHY_TYPE_OFDM_INDEX(3) */ +}; + +const struct NON_HT_ATTRIBUTE rNonHTAdHocModeAttributes[AD_HOC_MODE_NUM] = { + {PHY_TYPE_HR_DSSS_INDEX, BASIC_RATE_SET_HR_DSSS} + , /* For AD_HOC_MODE_11B(0) */ + {PHY_TYPE_ERP_INDEX, BASIC_RATE_SET_HR_DSSS_ERP} + , /* For AD_HOC_MODE_MIXED_11BG(1) */ + {PHY_TYPE_ERP_INDEX, BASIC_RATE_SET_ERP} + , /* For AD_HOC_MODE_11G(2) */ + {PHY_TYPE_OFDM_INDEX, BASIC_RATE_SET_OFDM} + , /* For AD_HOC_MODE_11A(3) */ +}; + +const struct NON_HT_ATTRIBUTE rNonHTApModeAttributes[AP_MODE_NUM] = { + {PHY_TYPE_HR_DSSS_INDEX, BASIC_RATE_SET_HR_DSSS} + , /* For AP_MODE_11B(0) */ + {PHY_TYPE_ERP_INDEX, BASIC_RATE_SET_HR_DSSS_ERP} + , /* For AP_MODE_MIXED_11BG(1) */ + {PHY_TYPE_ERP_INDEX, BASIC_RATE_SET_ERP} + , /* For AP_MODE_11G(2) */ + {PHY_TYPE_ERP_P2P_INDEX, BASIC_RATE_SET_ERP_P2P} + , /* For AP_MODE_11G_P2P(3) */ + {PHY_TYPE_OFDM_INDEX, BASIC_RATE_SET_OFDM} + , /* For AP_MODE_11A(4) */ +}; + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/p2p_assoc.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/p2p_assoc.c new file mode 100644 index 0000000000000000000000000000000000000000..861f971ae9eb74074ea1daaf76dcafb2f39f64fa --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/p2p_assoc.c @@ -0,0 +1,143 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: @(#) p2p_assoc.c@@ + */ + +/*! \file "p2p_assoc.c" + * \brief This file includes the Wi-Fi Direct association-related functions. + * + * This file includes the association-related functions. + */ + +/****************************************************************************** + * C O M P I L E R F L A G S + ****************************************************************************** + */ + +/****************************************************************************** + * E X T E R N A L R E F E R E N C E S + ****************************************************************************** + */ + +#include "precomp.h" + +/****************************************************************************** + * C O N S T A N T S + ****************************************************************************** + */ + +/****************************************************************************** + * D A T A T Y P E S + ****************************************************************************** + */ + +/****************************************************************************** + * P U B L I C D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * P R I V A T E D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * M A C R O S + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N D E C L A R A T I O N S + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N S + ****************************************************************************** + */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is used to compose Common Information Elements + * for P2P Association Request Frame. + * + * @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +uint8_t *p2pBuildReAssocReqFrameCommonIEs(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN uint8_t *pucBuffer) +{ + struct BSS_INFO *prP2pBssInfo = (struct BSS_INFO *) NULL; + + prP2pBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prMsduInfo->ucBssIndex); + + /* Fill the SSID element. */ + SSID_IE(pucBuffer)->ucId = ELEM_ID_SSID; + + /* NOTE(Kevin): We copy the SSID from CONNECTION_SETTINGS + * for the case of Passive Scan and the target BSS didn't broadcast SSID + * on its Beacon Frame. + */ + + COPY_SSID(SSID_IE(pucBuffer)->aucSSID, + SSID_IE(pucBuffer)->ucLength, + prP2pBssInfo->aucSSID, + prP2pBssInfo->ucSSIDLen); + + prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); + pucBuffer += IE_SIZE(pucBuffer); + return pucBuffer; +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/p2p_bss.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/p2p_bss.c new file mode 100644 index 0000000000000000000000000000000000000000..e6a53df326de87eb251d38698bf7b6034db5aa88 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/p2p_bss.c @@ -0,0 +1,109 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: @(#) p2p_bss.c@@ + */ + +/*! \file "p2p_bss.c" + * \brief This file contains the functions for creating p2p BSS(AP). + * + * This file contains the functions for BSS(AP). We may create a BSS + * network, or merge with exist IBSS network and sending Beacon Frame or reply + * the Probe Response Frame for received Probe Request Frame. + */ + +/****************************************************************************** + * C O M P I L E R F L A G S + ****************************************************************************** + */ + +/****************************************************************************** + * E X T E R N A L R E F E R E N C E S + ****************************************************************************** + */ + +#include "precomp.h" + +/****************************************************************************** + * C O N S T A N T S + ****************************************************************************** + */ + +/****************************************************************************** + * D A T A T Y P E S + ****************************************************************************** + */ + +/****************************************************************************** + * P U B L I C D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * P R I V A T E D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * M A C R O S + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N D E C L A R A T I O N S + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N S + ****************************************************************************** + */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/p2p_dev_fsm.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/p2p_dev_fsm.c new file mode 100644 index 0000000000000000000000000000000000000000..8eb080615870c88268701362c1b439e1f597810e --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/p2p_dev_fsm.c @@ -0,0 +1,1442 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +#include "precomp.h" +#include "p2p_dev_state.h" +#if CFG_ENABLE_WIFI_DIRECT + +#if 1 +/*lint -save -e64 Type mismatch */ +static uint8_t *apucDebugP2pDevState[P2P_DEV_STATE_NUM] = { + (uint8_t *) DISP_STRING("P2P_DEV_STATE_IDLE"), + (uint8_t *) DISP_STRING("P2P_DEV_STATE_SCAN"), + (uint8_t *) DISP_STRING("P2P_DEV_STATE_REQING_CHANNEL"), + (uint8_t *) DISP_STRING("P2P_DEV_STATE_CHNL_ON_HAND"), + (uint8_t *) DISP_STRING("P2P_DEV_STATE_OFF_CHNL_TX") +}; + +/*lint -restore */ +#endif /* DBG */ + +uint8_t p2pDevFsmInit(IN struct ADAPTER *prAdapter) +{ + struct P2P_DEV_FSM_INFO *prP2pDevFsmInfo = + (struct P2P_DEV_FSM_INFO *) NULL; + struct P2P_CHNL_REQ_INFO *prP2pChnlReqInfo = + (struct P2P_CHNL_REQ_INFO *) NULL; + struct P2P_MGMT_TX_REQ_INFO *prP2pMgmtTxReqInfo = + (struct P2P_MGMT_TX_REQ_INFO *) NULL; + struct BSS_INFO *prP2pBssInfo = (struct BSS_INFO *) NULL; + + do { + ASSERT_BREAK(prAdapter != NULL); + + prP2pDevFsmInfo = prAdapter->rWifiVar.prP2pDevFsmInfo; + + ASSERT_BREAK(prP2pDevFsmInfo != NULL); + + kalMemZero(prP2pDevFsmInfo, sizeof(struct P2P_DEV_FSM_INFO)); + + prP2pDevFsmInfo->eCurrentState = P2P_DEV_STATE_IDLE; + + cnmTimerInitTimer(prAdapter, + &(prP2pDevFsmInfo->rP2pFsmTimeoutTimer), + (PFN_MGMT_TIMEOUT_FUNC) p2pDevFsmRunEventTimeout, + (unsigned long) prP2pDevFsmInfo); + + prP2pBssInfo = + cnmGetBssInfoAndInit(prAdapter, NETWORK_TYPE_P2P, TRUE); + + if (prP2pBssInfo != NULL) { + COPY_MAC_ADDR(prP2pBssInfo->aucOwnMacAddr, + prAdapter->rWifiVar.aucDeviceAddress); + DBGLOG(INIT, INFO, "Set p2p dev mac to " MACSTR "\n", + MAC2STR(prP2pBssInfo->aucOwnMacAddr)); + + prP2pDevFsmInfo->ucBssIndex = prP2pBssInfo->ucBssIndex; + + prP2pBssInfo->eCurrentOPMode = OP_MODE_P2P_DEVICE; + prP2pBssInfo->ucConfigAdHocAPMode = AP_MODE_11G_P2P; + prP2pBssInfo->u2HwDefaultFixedRateCode = RATE_OFDM_6M; + + prP2pBssInfo->eBand = BAND_2G4; +#if (CFG_HW_WMM_BY_BSS == 1) + prP2pBssInfo->ucWmmQueSet = MAX_HW_WMM_INDEX; +#else + if (prAdapter->rWifiVar.eDbdcMode + == ENUM_DBDC_MODE_DISABLED) + prP2pBssInfo->ucWmmQueSet = DBDC_5G_WMM_INDEX; + else + prP2pBssInfo->ucWmmQueSet = DBDC_2G_WMM_INDEX; +#endif + +#if CFG_SUPPORT_VHT_IE_IN_2G + if (prAdapter->rWifiVar.ucVhtIeIn2g) + prP2pBssInfo->ucPhyTypeSet = + prAdapter->rWifiVar. + ucAvailablePhyTypeSet + & (PHY_TYPE_SET_802_11GN | + PHY_TYPE_SET_802_11AC); + else +#endif + prP2pBssInfo->ucPhyTypeSet = + prAdapter->rWifiVar. + ucAvailablePhyTypeSet + & PHY_TYPE_SET_802_11GN; + + prP2pBssInfo->ucNonHTBasicPhyType = (uint8_t) + rNonHTApModeAttributes + [prP2pBssInfo->ucConfigAdHocAPMode] + .ePhyTypeIndex; + + prP2pBssInfo->u2BSSBasicRateSet = + rNonHTApModeAttributes + [prP2pBssInfo->ucConfigAdHocAPMode] + .u2BSSBasicRateSet; + + prP2pBssInfo->u2OperationalRateSet = + rNonHTPhyAttributes + [prP2pBssInfo->ucNonHTBasicPhyType] + .u2SupportedRateSet; + + prP2pBssInfo->u4PrivateData = 0;/* TH3 Huang */ + + rateGetDataRatesFromRateSet( + prP2pBssInfo->u2OperationalRateSet, + prP2pBssInfo->u2BSSBasicRateSet, + prP2pBssInfo->aucAllSupportedRates, + &prP2pBssInfo->ucAllSupportedRatesLen); + } + prP2pChnlReqInfo = &prP2pDevFsmInfo->rChnlReqInfo; + LINK_INITIALIZE(&prP2pChnlReqInfo->rP2pChnlReqLink); + + prP2pMgmtTxReqInfo = &prP2pDevFsmInfo->rMgmtTxInfo; + LINK_INITIALIZE(&prP2pMgmtTxReqInfo->rTxReqLink); + + p2pDevFsmStateTransition(prAdapter, + prP2pDevFsmInfo, + P2P_DEV_STATE_IDLE); + } while (FALSE); + + if (prP2pBssInfo) + return prP2pBssInfo->ucBssIndex; + else + return prAdapter->ucP2PDevBssIdx + 1; + +#if 0 + do { + ASSERT_BREAK(prAdapter != NULL); + + prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; + prP2pBssInfo = + &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); + + ASSERT_BREAK(prP2pFsmInfo != NULL); + + LINK_INITIALIZE(&(prP2pFsmInfo->rMsgEventQueue)); + + prP2pFsmInfo->eCurrentState = + prP2pFsmInfo->ePreviousState = P2P_STATE_IDLE; + + prP2pFsmInfo->prTargetBss = NULL; + + cnmTimerInitTimer(prAdapter, + &(prP2pFsmInfo->rP2pFsmTimeoutTimer), + (PFN_MGMT_TIMEOUT_FUNC) p2pFsmRunEventFsmTimeout, + (unsigned long) prP2pFsmInfo); + + /* 4 <2> Initiate BSS_INFO_T - common part */ + BSS_INFO_INIT(prAdapter, NETWORK_TYPE_P2P_INDEX); + + /* 4 <2.1> Initiate BSS_INFO_T - Setup HW ID */ + prP2pBssInfo->ucConfigAdHocAPMode = AP_MODE_11G_P2P; + prP2pBssInfo->ucHwDefaultFixedRateCode = RATE_OFDM_6M; + + prP2pBssInfo->ucNonHTBasicPhyType = (uint8_t) + rNonHTApModeAttributes[prP2pBssInfo->ucConfigAdHocAPMode] + .ePhyTypeIndex; + + prP2pBssInfo->u2BSSBasicRateSet = + rNonHTApModeAttributes[prP2pBssInfo->ucConfigAdHocAPMode] + .u2BSSBasicRateSet; + + prP2pBssInfo->u2OperationalRateSet = + rNonHTPhyAttributes[prP2pBssInfo->ucNonHTBasicPhyType] + .u2SupportedRateSet; + + rateGetDataRatesFromRateSet(prP2pBssInfo->u2OperationalRateSet, + prP2pBssInfo->u2BSSBasicRateSet, + prP2pBssInfo->aucAllSupportedRates, + &prP2pBssInfo->ucAllSupportedRatesLen); + + prP2pBssInfo->prBeacon = cnmMgtPktAlloc(prAdapter, + OFFSET_OF(struct WLAN_BEACON_FRAME, aucInfoElem[0]) + + MAX_IE_LENGTH); + + if (prP2pBssInfo->prBeacon) { + prP2pBssInfo->prBeacon->eSrc = TX_PACKET_MGMT; + /* NULL STA_REC */ + prP2pBssInfo->prBeacon->ucStaRecIndex = 0xFF; + prP2pBssInfo->prBeacon->ucNetworkType = + NETWORK_TYPE_P2P_INDEX; + } else { + /* Out of memory. */ + ASSERT(FALSE); + } + + prP2pBssInfo->eCurrentOPMode = OP_MODE_NUM; + + prP2pBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC = PM_UAPSD_ALL; + prP2pBssInfo->rPmProfSetupInfo.ucBmpTriggerAC = PM_UAPSD_ALL; + prP2pBssInfo->rPmProfSetupInfo.ucUapsdSp = WMM_MAX_SP_LENGTH_2; + prP2pBssInfo->ucPrimaryChannel = P2P_DEFAULT_LISTEN_CHANNEL; + prP2pBssInfo->eBand = BAND_2G4; + prP2pBssInfo->eBssSCO = CHNL_EXT_SCN; + + if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucQoS)) + prP2pBssInfo->fgIsQBSS = TRUE; + else + prP2pBssInfo->fgIsQBSS = FALSE; + + SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX); + + p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); + } while (FALSE); + + return; +#endif +} /* p2pDevFsmInit */ + +void p2pDevFsmUninit(IN struct ADAPTER *prAdapter) +{ + struct P2P_DEV_FSM_INFO *prP2pDevFsmInfo = + (struct P2P_DEV_FSM_INFO *) NULL; + struct BSS_INFO *prP2pBssInfo = (struct BSS_INFO *) NULL; + + do { + ASSERT_BREAK(prAdapter != NULL); + + prP2pDevFsmInfo = prAdapter->rWifiVar.prP2pDevFsmInfo; + + ASSERT_BREAK(prP2pDevFsmInfo != NULL); + + prP2pBssInfo = + prAdapter->aprBssInfo[prP2pDevFsmInfo->ucBssIndex]; + + cnmTimerStopTimer(prAdapter, + &(prP2pDevFsmInfo->rP2pFsmTimeoutTimer)); + + p2pFunCleanQueuedMgmtFrame(prAdapter, + &prP2pDevFsmInfo->rQueuedActionFrame); + + p2pFunClearAllTxReq(prAdapter, &(prP2pDevFsmInfo->rMgmtTxInfo)); + + /* Abort device FSM */ + p2pDevFsmStateTransition(prAdapter, + prP2pDevFsmInfo, + P2P_DEV_STATE_IDLE); + p2pDevFsmRunEventAbort(prAdapter, prP2pDevFsmInfo); + + SET_NET_PWR_STATE_IDLE(prAdapter, prP2pBssInfo->ucBssIndex); + + /* Clear CmdQue */ + kalClearMgmtFramesByBssIdx(prAdapter->prGlueInfo, + prP2pBssInfo->ucBssIndex); + kalClearSecurityFramesByBssIdx(prAdapter->prGlueInfo, + prP2pBssInfo->ucBssIndex); + /* Clear PendingCmdQue */ + wlanReleasePendingCMDbyBssIdx(prAdapter, + prP2pBssInfo->ucBssIndex); + /* Clear PendingTxMsdu */ + nicFreePendingTxMsduInfo(prAdapter, + prP2pBssInfo->ucBssIndex, MSDU_REMOVE_BY_BSS_INDEX); + + /* Deactivate BSS. */ + UNSET_NET_ACTIVE(prAdapter, prP2pBssInfo->ucBssIndex); + + nicDeactivateNetwork(prAdapter, prP2pBssInfo->ucBssIndex); + + cnmFreeBssInfo(prAdapter, prP2pBssInfo); + } while (FALSE); + +#if 0 + struct P2P_FSM_INFO *prP2pFsmInfo = (struct P2P_FSM_INFO *) NULL; + struct BSS_INFO *prP2pBssInfo = (struct BSS_INFO *) NULL; + + do { + ASSERT_BREAK(prAdapter != NULL); + + DEBUGFUNC("p2pFsmUninit()"); + DBGLOG(P2P, INFO, "->p2pFsmUninit()\n"); + + prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; + prP2pBssInfo = + &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); + + p2pFuncSwitchOPMode(prAdapter, prP2pBssInfo, + OP_MODE_P2P_DEVICE, TRUE); + + p2pFsmRunEventAbort(prAdapter, prP2pFsmInfo); + + p2pStateAbort_IDLE(prAdapter, prP2pFsmInfo, P2P_STATE_NUM); + + UNSET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); + + wlanAcquirePowerControl(prAdapter); + + /* Release all pending CMD queue. */ + DBGLOG(P2P, TRACE, + "p2pFsmUninit: wlanProcessCommandQueue, num of element:%d\n", + prAdapter->prGlueInfo->rCmdQueue.u4NumElem); + wlanProcessCommandQueue(prAdapter, + &prAdapter->prGlueInfo->rCmdQueue); + + wlanReleasePowerControl(prAdapter); + + /* Release pending mgmt frame, + * mgmt frame may be pending by CMD without resource. + */ + kalClearMgmtFramesByBssIdx(prAdapter->prGlueInfo, + NETWORK_TYPE_P2P_INDEX); + + /* Clear PendingCmdQue */ + wlanReleasePendingCMDbyBssIdx(prAdapter, + NETWORK_TYPE_P2P_INDEX); + + if (prP2pBssInfo->prBeacon) { + cnmMgtPktFree(prAdapter, prP2pBssInfo->prBeacon); + prP2pBssInfo->prBeacon = NULL; + } + } while (FALSE); + + return; +#endif +} /* p2pDevFsmUninit */ + +void +p2pDevFsmStateTransition(IN struct ADAPTER *prAdapter, + IN struct P2P_DEV_FSM_INFO *prP2pDevFsmInfo, + IN enum ENUM_P2P_DEV_STATE eNextState) +{ + u_int8_t fgIsLeaveState = (u_int8_t) FALSE; + + ASSERT(prP2pDevFsmInfo); + if (!prP2pDevFsmInfo) { + DBGLOG(P2P, ERROR, "prP2pDevFsmInfo is NULL!\n"); + return; + } + + ASSERT(prP2pDevFsmInfo->ucBssIndex == prAdapter->ucP2PDevBssIdx); + if (prP2pDevFsmInfo->ucBssIndex != prAdapter->ucP2PDevBssIdx) { + log_dbg(P2P, ERROR, + "prP2pDevFsmInfo->ucBssIndex %d should be prAdapter->ucP2PDevBssIdx(%d)!\n", + prP2pDevFsmInfo->ucBssIndex, prAdapter->ucP2PDevBssIdx); + return; + } + + do { + if (!IS_BSS_ACTIVE( + prAdapter->aprBssInfo[prP2pDevFsmInfo->ucBssIndex])) { + if (!cnmP2PIsPermitted(prAdapter)) + return; + + SET_NET_ACTIVE(prAdapter, prP2pDevFsmInfo->ucBssIndex); + nicActivateNetwork(prAdapter, + prP2pDevFsmInfo->ucBssIndex); + } + + fgIsLeaveState = fgIsLeaveState ? FALSE : TRUE; + + if (!fgIsLeaveState) { + /* Print log with state changed */ + if (prP2pDevFsmInfo->eCurrentState != eNextState) + DBGLOG(P2P, STATE, + "[P2P_DEV]TRANSITION: [%s] -> [%s]\n", + apucDebugP2pDevState + [prP2pDevFsmInfo->eCurrentState], + apucDebugP2pDevState[eNextState]); + + /* Transition into current state. */ + prP2pDevFsmInfo->eCurrentState = eNextState; + } + + switch (prP2pDevFsmInfo->eCurrentState) { + case P2P_DEV_STATE_IDLE: + if (!fgIsLeaveState) { + fgIsLeaveState = p2pDevStateInit_IDLE(prAdapter, + &prP2pDevFsmInfo->rChnlReqInfo, + &eNextState); + } else { + p2pDevStateAbort_IDLE(prAdapter); + } + break; + case P2P_DEV_STATE_SCAN: + if (!fgIsLeaveState) { + p2pDevStateInit_SCAN(prAdapter, + prP2pDevFsmInfo->ucBssIndex, + &prP2pDevFsmInfo->rScanReqInfo); + } else { + p2pDevStateAbort_SCAN(prAdapter, + prP2pDevFsmInfo); + } + break; + case P2P_DEV_STATE_REQING_CHANNEL: + if (!fgIsLeaveState) { + fgIsLeaveState = p2pDevStateInit_REQING_CHANNEL( + prAdapter, + prP2pDevFsmInfo->ucBssIndex, + &(prP2pDevFsmInfo->rChnlReqInfo), + &eNextState); + } else { + p2pDevStateAbort_REQING_CHANNEL(prAdapter, + &(prP2pDevFsmInfo->rChnlReqInfo), + eNextState); + } + break; + case P2P_DEV_STATE_CHNL_ON_HAND: + if (!fgIsLeaveState) { + p2pDevStateInit_CHNL_ON_HAND(prAdapter, + prAdapter->aprBssInfo + [prP2pDevFsmInfo->ucBssIndex], + prP2pDevFsmInfo, + &(prP2pDevFsmInfo->rChnlReqInfo)); + } else { + p2pDevStateAbort_CHNL_ON_HAND(prAdapter, + prAdapter->aprBssInfo + [prP2pDevFsmInfo->ucBssIndex], + prP2pDevFsmInfo, + &(prP2pDevFsmInfo->rChnlReqInfo), + eNextState); + } + break; + case P2P_DEV_STATE_OFF_CHNL_TX: + if (!fgIsLeaveState) { + fgIsLeaveState = p2pDevStateInit_OFF_CHNL_TX( + prAdapter, + prP2pDevFsmInfo, + &(prP2pDevFsmInfo->rChnlReqInfo), + &(prP2pDevFsmInfo->rMgmtTxInfo), + &eNextState); + } else { + p2pDevStateAbort_OFF_CHNL_TX( + prAdapter, + prP2pDevFsmInfo, + &(prP2pDevFsmInfo->rMgmtTxInfo), + &(prP2pDevFsmInfo->rChnlReqInfo), + eNextState); + } + break; + default: + /* Unexpected state. */ + ASSERT(FALSE); + break; + } + } while (fgIsLeaveState); +} /* p2pDevFsmStateTransition */ + +void p2pDevFsmRunEventAbort(IN struct ADAPTER *prAdapter, + IN struct P2P_DEV_FSM_INFO *prP2pDevFsmInfo) +{ + do { + ASSERT_BREAK((prAdapter != NULL) + && (prP2pDevFsmInfo != NULL)); + + if (prP2pDevFsmInfo->eCurrentState != P2P_DEV_STATE_IDLE) { + /* Get into IDLE state. */ + p2pDevFsmStateTransition(prAdapter, + prP2pDevFsmInfo, + P2P_DEV_STATE_IDLE); + } + + /* Abort IDLE. */ + p2pDevStateAbort_IDLE(prAdapter); + } while (FALSE); +} /* p2pDevFsmRunEventAbort */ + +void p2pDevFsmRunEventTimeout(IN struct ADAPTER *prAdapter, + IN unsigned long ulParamPtr) +{ + struct P2P_DEV_FSM_INFO *prP2pDevFsmInfo = + (struct P2P_DEV_FSM_INFO *) ulParamPtr; + + do { + ASSERT_BREAK((prAdapter != NULL) && (prP2pDevFsmInfo != NULL)); + + switch (prP2pDevFsmInfo->eCurrentState) { + case P2P_DEV_STATE_IDLE: + /* TODO: IDLE timeout for low power mode. */ + break; + case P2P_DEV_STATE_CHNL_ON_HAND: + if (prAdapter->prP2pInfo->ucExtendChanFlag) { + prAdapter->prP2pInfo->ucExtendChanFlag = 0; + p2pDevFsmStateTransition(prAdapter, + prP2pDevFsmInfo, P2P_DEV_STATE_IDLE); + break; + } + if (p2pFuncNeedWaitRsp(prAdapter, + prAdapter->prP2pInfo->eConnState)) { + DBGLOG(P2P, INFO, + "P2P: re-enter CHNL_ON_HAND with state: %d\n", + prAdapter->prP2pInfo->eConnState); + prAdapter->prP2pInfo->ucExtendChanFlag = 1; + p2pDevFsmStateTransition(prAdapter, + prP2pDevFsmInfo, + P2P_DEV_STATE_CHNL_ON_HAND); + } else { + p2pDevFsmStateTransition(prAdapter, + prP2pDevFsmInfo, + P2P_DEV_STATE_IDLE); + } + break; + case P2P_DEV_STATE_OFF_CHNL_TX: + p2pDevFsmStateTransition(prAdapter, prP2pDevFsmInfo, + P2P_DEV_STATE_OFF_CHNL_TX); + break; + default: + ASSERT(FALSE); + log_dbg(P2P, ERROR, + "Current P2P Dev State %d is unexpected for FSM timeout event.\n", + prP2pDevFsmInfo->eCurrentState); + break; + } + } while (FALSE); +} /* p2pDevFsmRunEventTimeout */ + +/*================ Message Event =================*/ +void p2pDevFsmRunEventScanRequest(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct MSG_P2P_SCAN_REQUEST *prP2pScanReqMsg = + (struct MSG_P2P_SCAN_REQUEST *) NULL; + struct P2P_DEV_FSM_INFO *prP2pDevFsmInfo = + (struct P2P_DEV_FSM_INFO *) NULL; + struct P2P_SCAN_REQ_INFO *prScanReqInfo = + (struct P2P_SCAN_REQ_INFO *) NULL; + uint32_t u4ChnlListSize = 0; + struct P2P_SSID_STRUCT *prP2pSsidStruct = + (struct P2P_SSID_STRUCT *) NULL; + + do { + ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); + + prP2pDevFsmInfo = prAdapter->rWifiVar.prP2pDevFsmInfo; + + if (prP2pDevFsmInfo == NULL) + break; + + if (prP2pDevFsmInfo->eCurrentState != P2P_DEV_STATE_IDLE) + p2pDevFsmRunEventAbort(prAdapter, prP2pDevFsmInfo); + + prP2pScanReqMsg = (struct MSG_P2P_SCAN_REQUEST *) prMsgHdr; + prScanReqInfo = &(prP2pDevFsmInfo->rScanReqInfo); + + DBGLOG(P2P, TRACE, "p2pDevFsmRunEventScanRequest\n"); + + /* Do we need to be in IDLE state? */ + /* p2pDevFsmRunEventAbort(prAdapter, prP2pDevFsmInfo); */ + + ASSERT(prScanReqInfo->fgIsScanRequest == FALSE); + + prScanReqInfo->fgIsAbort = TRUE; + prScanReqInfo->eScanType = prP2pScanReqMsg->eScanType; + prScanReqInfo->u2PassiveDewellTime = 0; + + if (prP2pScanReqMsg->u4NumChannel) { + prScanReqInfo->eChannelSet = SCAN_CHANNEL_SPECIFIED; + + /* Channel List */ + prScanReqInfo->ucNumChannelList = + prP2pScanReqMsg->u4NumChannel; + DBGLOG(P2P, TRACE, + "Scan Request Channel List Number: %d\n", + prScanReqInfo->ucNumChannelList); + if (prScanReqInfo->ucNumChannelList + > MAXIMUM_OPERATION_CHANNEL_LIST) { + DBGLOG(P2P, TRACE, + "Channel List Number Overloaded: %d, change to: %d\n", + prScanReqInfo->ucNumChannelList, + MAXIMUM_OPERATION_CHANNEL_LIST); + prScanReqInfo->ucNumChannelList = + MAXIMUM_OPERATION_CHANNEL_LIST; + } + + u4ChnlListSize = sizeof(struct RF_CHANNEL_INFO) + * prScanReqInfo->ucNumChannelList; + kalMemCopy(prScanReqInfo->arScanChannelList, + prP2pScanReqMsg->arChannelListInfo, + u4ChnlListSize); + } else { + /* If channel number is ZERO. + * It means do a FULL channel scan. + */ + prScanReqInfo->eChannelSet = SCAN_CHANNEL_FULL; + } + + /* SSID */ + prP2pSsidStruct = prP2pScanReqMsg->prSSID; + for (prScanReqInfo->ucSsidNum = 0; + prScanReqInfo->ucSsidNum + < prP2pScanReqMsg->i4SsidNum; + prScanReqInfo->ucSsidNum++) { + kalMemCopy( + prScanReqInfo->arSsidStruct + [prScanReqInfo->ucSsidNum].aucSsid, + prP2pSsidStruct->aucSsid, + prP2pSsidStruct->ucSsidLen); + + prScanReqInfo->arSsidStruct + [prScanReqInfo->ucSsidNum].ucSsidLen = + prP2pSsidStruct->ucSsidLen; + + prP2pSsidStruct++; + } + + /* IE Buffer */ + kalMemCopy(prScanReqInfo->aucIEBuf, + prP2pScanReqMsg->pucIEBuf, + prP2pScanReqMsg->u4IELen); + + prScanReqInfo->u4BufLength = prP2pScanReqMsg->u4IELen; + + p2pDevFsmStateTransition(prAdapter, + prP2pDevFsmInfo, + P2P_DEV_STATE_SCAN); + } while (FALSE); + + if (prMsgHdr) + cnmMemFree(prAdapter, prMsgHdr); +} /* p2pDevFsmRunEventScanRequest */ + +void p2pDevFsmRunEventScanAbort(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIdx) +{ + struct P2P_DEV_FSM_INFO *prP2pDevFsmInfo = + (struct P2P_DEV_FSM_INFO *) NULL; + + do { + ASSERT_BREAK(prAdapter != NULL); + + DBGLOG(P2P, TRACE, "p2pDevFsmRunEventScanAbort\n"); + + prP2pDevFsmInfo = prAdapter->rWifiVar.prP2pDevFsmInfo; + + if (prP2pDevFsmInfo->eCurrentState == P2P_DEV_STATE_SCAN) { + struct P2P_SCAN_REQ_INFO *prScanReqInfo = + &(prP2pDevFsmInfo->rScanReqInfo); + + prScanReqInfo->fgIsAbort = TRUE; + + p2pDevFsmStateTransition(prAdapter, + prP2pDevFsmInfo, + P2P_DEV_STATE_IDLE); + } + + } while (FALSE); +} /* p2pDevFsmRunEventScanAbort */ + +void +p2pDevFsmRunEventScanDone(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr, + IN struct P2P_DEV_FSM_INFO *prP2pDevFsmInfo) +{ + struct MSG_SCN_SCAN_DONE *prScanDoneMsg = + (struct MSG_SCN_SCAN_DONE *) prMsgHdr; + struct P2P_SCAN_REQ_INFO *prP2pScanReqInfo = + (struct P2P_SCAN_REQ_INFO *) NULL; + + do { + ASSERT_BREAK((prAdapter != NULL) + && (prMsgHdr != NULL) + && (prP2pDevFsmInfo != NULL)); + + if (!prP2pDevFsmInfo) { + DBGLOG(P2P, ERROR, + "prP2pDevFsmInfo is null, maybe remove p2p already\n"); + break; + } + + prP2pScanReqInfo = &(prP2pDevFsmInfo->rScanReqInfo); + + if (prScanDoneMsg->ucSeqNum + != prP2pScanReqInfo->ucSeqNumOfScnMsg) { + DBGLOG(P2P, TRACE, + "P2P Scan Done SeqNum:%d <-> P2P Dev FSM Scan SeqNum:%d", + prScanDoneMsg->ucSeqNum, + prP2pScanReqInfo->ucSeqNumOfScnMsg); + break; + } + + ASSERT_BREAK(prScanDoneMsg->ucBssIndex + == prP2pDevFsmInfo->ucBssIndex); + + prP2pScanReqInfo->fgIsAbort = FALSE; + prP2pScanReqInfo->fgIsScanRequest = FALSE; + + p2pDevFsmStateTransition(prAdapter, + prP2pDevFsmInfo, + P2P_DEV_STATE_IDLE); + } while (FALSE); + + if (prMsgHdr) + cnmMemFree(prAdapter, prMsgHdr); +} /* p2pDevFsmRunEventScanDone */ + +void p2pDevFsmRunEventChannelRequest(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct P2P_DEV_FSM_INFO *prP2pDevFsmInfo = + (struct P2P_DEV_FSM_INFO *) NULL; + struct P2P_CHNL_REQ_INFO *prChnlReqInfo = + (struct P2P_CHNL_REQ_INFO *) NULL; + u_int8_t fgIsChnlFound = FALSE; + + do { + ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); + + prP2pDevFsmInfo = prAdapter->rWifiVar.prP2pDevFsmInfo; + + if (prP2pDevFsmInfo == NULL) { + DBGLOG(P2P, WARN, "uninitialized p2p Dev fsm\n"); + break; + } + + prChnlReqInfo = &(prP2pDevFsmInfo->rChnlReqInfo); + + DBGLOG(P2P, TRACE, "p2pDevFsmRunEventChannelRequest\n"); + + /* printk( + * "p2pDevFsmRunEventChannelRequest check cookie =%lld\n", + * prChnlReqInfo->u8Cookie); + */ + + if (!LINK_IS_EMPTY(&prChnlReqInfo->rP2pChnlReqLink)) { + struct LINK_ENTRY *prLinkEntry = + (struct LINK_ENTRY *) NULL; + struct MSG_P2P_CHNL_REQUEST *prP2pMsgChnlReq = + (struct MSG_P2P_CHNL_REQUEST *) NULL; + + LINK_FOR_EACH(prLinkEntry, + &prChnlReqInfo->rP2pChnlReqLink) { + + prP2pMsgChnlReq = + (struct MSG_P2P_CHNL_REQUEST *) + LINK_ENTRY(prLinkEntry, + struct MSG_HDR, rLinkEntry); + + if (prP2pMsgChnlReq->eChnlReqType + == CH_REQ_TYPE_ROC) { + LINK_REMOVE_KNOWN_ENTRY( + &prChnlReqInfo->rP2pChnlReqLink, + prLinkEntry); + cnmMemFree(prAdapter, prP2pMsgChnlReq); + /* DBGLOG(P2P, TRACE, */ + /* ("p2pDevFsmRunEventChannelAbort: + * Channel Abort, cookie found:%d\n", + */ + /* prChnlAbortMsg->u8Cookie)); */ + fgIsChnlFound = TRUE; + break; + } + } + } + + /* Queue the channel request. */ + LINK_INSERT_TAIL(&(prChnlReqInfo->rP2pChnlReqLink), + &(prMsgHdr->rLinkEntry)); + prMsgHdr = NULL; + + /* If channel is not requested, + * it may due to channel is released. + */ + if ((!fgIsChnlFound) + && (prChnlReqInfo->eChnlReqType + == CH_REQ_TYPE_ROC) + && (prChnlReqInfo->fgIsChannelRequested)) { + + ASSERT( + (prP2pDevFsmInfo->eCurrentState + == P2P_DEV_STATE_REQING_CHANNEL) || + (prP2pDevFsmInfo->eCurrentState + == P2P_DEV_STATE_CHNL_ON_HAND)); + + p2pDevFsmRunEventAbort(prAdapter, prP2pDevFsmInfo); + + break; + } + + if (prP2pDevFsmInfo->eCurrentState == P2P_DEV_STATE_IDLE) { + /* Re-enter IDLE state would trigger channel request. */ + p2pDevFsmStateTransition(prAdapter, + prP2pDevFsmInfo, P2P_DEV_STATE_IDLE); + } + } while (FALSE); + + if (prMsgHdr) + cnmMemFree(prAdapter, prMsgHdr); +} /* p2pDevFsmRunEventChannelRequest */ + +void p2pDevFsmRunEventChannelAbort(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct P2P_DEV_FSM_INFO *prP2pDevFsmInfo = + (struct P2P_DEV_FSM_INFO *) NULL; + struct MSG_P2P_CHNL_ABORT *prChnlAbortMsg = + (struct MSG_P2P_CHNL_ABORT *) NULL; + struct P2P_CHNL_REQ_INFO *prChnlReqInfo = + (struct P2P_CHNL_REQ_INFO *) NULL; + + do { + ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); + + prChnlAbortMsg = (struct MSG_P2P_CHNL_ABORT *) prMsgHdr; + + prP2pDevFsmInfo = prAdapter->rWifiVar.prP2pDevFsmInfo; + + if (prP2pDevFsmInfo == NULL) + break; + + prChnlReqInfo = &(prP2pDevFsmInfo->rChnlReqInfo); + + DBGLOG(P2P, TRACE, "p2pDevFsmRunEventChannelAbort\n"); + + p2pFunCleanQueuedMgmtFrame(prAdapter, + &prP2pDevFsmInfo->rQueuedActionFrame); + + /* If channel is not requested, + * it may due to channel is released. + */ + if ((prChnlAbortMsg->u8Cookie == prChnlReqInfo->u8Cookie) + && (prChnlReqInfo->fgIsChannelRequested) && + prChnlReqInfo->eChnlReqType == CH_REQ_TYPE_ROC) { + ASSERT( + (prP2pDevFsmInfo->eCurrentState + == P2P_DEV_STATE_REQING_CHANNEL) || + (prP2pDevFsmInfo->eCurrentState + == P2P_DEV_STATE_CHNL_ON_HAND)); + + /* + * If cancel-roc cmd is called from Supplicant + * while driver is waiting for FW's channel grant event, + * roc event must be returned to Supplicant + * first to reset Supplicant's variables + * and then transition to idle state. + */ + if (prP2pDevFsmInfo->eCurrentState + == P2P_DEV_STATE_REQING_CHANNEL) { + kalP2PIndicateChannelReady( + prAdapter->prGlueInfo, + prChnlReqInfo->u8Cookie, + prChnlReqInfo->ucReqChnlNum, + prChnlReqInfo->eBand, + prChnlReqInfo->eChnlSco, + prChnlReqInfo->u4MaxInterval); + kalP2PIndicateChannelExpired( + prAdapter->prGlueInfo, + prChnlReqInfo->u8Cookie, + prChnlReqInfo->ucReqChnlNum, + prChnlReqInfo->eBand, + prChnlReqInfo->eChnlSco); + } + p2pDevFsmRunEventAbort(prAdapter, prP2pDevFsmInfo); + + break; + } else if (!LINK_IS_EMPTY(&prChnlReqInfo->rP2pChnlReqLink)) { + struct LINK_ENTRY *prLinkEntry = + (struct LINK_ENTRY *) NULL; + struct MSG_P2P_CHNL_REQUEST *prP2pMsgChnlReq = + (struct MSG_P2P_CHNL_REQUEST *) NULL; + + LINK_FOR_EACH(prLinkEntry, + &prChnlReqInfo->rP2pChnlReqLink) { + prP2pMsgChnlReq = + (struct MSG_P2P_CHNL_REQUEST *) + LINK_ENTRY(prLinkEntry, + struct MSG_HDR, rLinkEntry); + + if (prP2pMsgChnlReq->u8Cookie + == prChnlAbortMsg->u8Cookie) { + LINK_REMOVE_KNOWN_ENTRY( + &prChnlReqInfo->rP2pChnlReqLink, + prLinkEntry); + log_dbg(P2P, TRACE, + "p2pDevFsmRunEventChannelAbort: Channel Abort, cookie found:0x%llx\n", + prChnlAbortMsg->u8Cookie); + kalP2PIndicateChannelReady( + prAdapter->prGlueInfo, + prP2pMsgChnlReq->u8Cookie, + prP2pMsgChnlReq->rChannelInfo + .ucChannelNum, + prP2pMsgChnlReq->rChannelInfo + .eBand, + prP2pMsgChnlReq->eChnlSco, + prP2pMsgChnlReq->u4Duration); + kalP2PIndicateChannelExpired( + prAdapter->prGlueInfo, + prP2pMsgChnlReq->u8Cookie, + prP2pMsgChnlReq->rChannelInfo + .ucChannelNum, + prP2pMsgChnlReq->rChannelInfo + .eBand, + prP2pMsgChnlReq->eChnlSco); + cnmMemFree(prAdapter, prP2pMsgChnlReq); + break; + } + } + } else { + log_dbg(P2P, WARN, + "p2pDevFsmRunEventChannelAbort: Channel Abort Fail, cookie not found:0x%llx\n", + prChnlAbortMsg->u8Cookie); + } + } while (FALSE); + + if (prMsgHdr) + cnmMemFree(prAdapter, prMsgHdr); +} /* p2pDevFsmRunEventChannelAbort */ + +void +p2pDevFsmRunEventChnlGrant(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr, + IN struct P2P_DEV_FSM_INFO *prP2pDevFsmInfo) +{ + struct MSG_CH_GRANT *prMsgChGrant = (struct MSG_CH_GRANT *) NULL; + struct P2P_CHNL_REQ_INFO *prChnlReqInfo = + (struct P2P_CHNL_REQ_INFO *) NULL; + + do { + ASSERT((prAdapter != NULL) + && (prMsgHdr != NULL) + && (prP2pDevFsmInfo != NULL)); + + if ((prAdapter == NULL) + || (prMsgHdr == NULL) + || (prP2pDevFsmInfo == NULL)) + break; + + prMsgChGrant = (struct MSG_CH_GRANT *) prMsgHdr; + prChnlReqInfo = &(prP2pDevFsmInfo->rChnlReqInfo); + + if ((prMsgChGrant->ucTokenID + != prChnlReqInfo->ucSeqNumOfChReq) + || (!prChnlReqInfo->fgIsChannelRequested)) { + break; + } + + ASSERT(prMsgChGrant->ucPrimaryChannel + == prChnlReqInfo->ucReqChnlNum); + ASSERT(prMsgChGrant->eReqType + == prChnlReqInfo->eChnlReqType); + ASSERT(prMsgChGrant->u4GrantInterval + == prChnlReqInfo->u4MaxInterval); + + prChnlReqInfo->u4MaxInterval = prMsgChGrant->u4GrantInterval; + + if (prMsgChGrant->eReqType == CH_REQ_TYPE_ROC) { + p2pDevFsmStateTransition(prAdapter, + prP2pDevFsmInfo, + P2P_DEV_STATE_CHNL_ON_HAND); + } else { + ASSERT(prMsgChGrant->eReqType + == CH_REQ_TYPE_OFFCHNL_TX); + + p2pDevFsmStateTransition(prAdapter, + prP2pDevFsmInfo, + P2P_DEV_STATE_OFF_CHNL_TX); + } + } while (FALSE); + + if (prAdapter && prMsgHdr) + cnmMemFree(prAdapter, prMsgHdr); +} /* p2pDevFsmRunEventChnlGrant */ + +static u_int8_t +p2pDevChnlReqByOffChnl(IN struct ADAPTER *prAdapter, + IN struct P2P_DEV_FSM_INFO *prP2pDevFsmInfo, + IN struct P2P_OFF_CHNL_TX_REQ_INFO *prOffChnlTxReq) +{ + struct MSG_P2P_CHNL_REQUEST *prMsgChnlReq = + (struct MSG_P2P_CHNL_REQUEST *) NULL; + + if (prAdapter == NULL || prP2pDevFsmInfo == NULL || + prOffChnlTxReq == NULL) + return FALSE; + + prMsgChnlReq = cnmMemAlloc(prAdapter, + RAM_TYPE_MSG, + sizeof(struct MSG_P2P_CHNL_REQUEST)); + + if (prMsgChnlReq == NULL) { + DBGLOG(P2P, ERROR, + "Not enough MSG buffer for chnl request.\n"); + return FALSE; + } + + prMsgChnlReq->eChnlReqType = CH_REQ_TYPE_OFFCHNL_TX; + prMsgChnlReq->rMsgHdr.eMsgId = MID_MNY_P2P_CHNL_REQ; + prMsgChnlReq->u8Cookie = prOffChnlTxReq->u8Cookie; + prMsgChnlReq->u4Duration = prOffChnlTxReq->u4Duration; + kalMemCopy(&prMsgChnlReq->rChannelInfo, + &prOffChnlTxReq->rChannelInfo, + sizeof(struct RF_CHANNEL_INFO)); + prMsgChnlReq->eChnlSco = prOffChnlTxReq->eChnlExt; + p2pDevFsmRunEventChannelRequest(prAdapter, + (struct MSG_HDR *) prMsgChnlReq); + + return TRUE; +} /* p2pDevChnlReqByOffChnl */ + +static void +p2pDevAbortChlReqIfNeed(IN struct ADAPTER *prAdapter, + IN struct P2P_DEV_FSM_INFO *prP2pDevFsmInfo, + IN struct P2P_CHNL_REQ_INFO *prChnlReqInfo) +{ + struct MSG_P2P_CHNL_ABORT *prMsgChnlAbort = + (struct MSG_P2P_CHNL_ABORT *) NULL; + + if (prAdapter == NULL || prChnlReqInfo == NULL || + prP2pDevFsmInfo == NULL) + return; + + /* Cancel ongoing channel request whose type is not offchannel-tx*/ + if (prP2pDevFsmInfo->eCurrentState != P2P_DEV_STATE_REQING_CHANNEL || + prChnlReqInfo->eChnlReqType == CH_REQ_TYPE_OFFCHNL_TX) + return; + + prMsgChnlAbort = cnmMemAlloc(prAdapter, + RAM_TYPE_MSG, sizeof(struct MSG_P2P_CHNL_ABORT)); + + if (prMsgChnlAbort == NULL) { + DBGLOG(P2P, ERROR, "Memory allocate failed.\n"); + return; + } + + prMsgChnlAbort->u8Cookie = prChnlReqInfo->u8Cookie; + p2pDevFsmRunEventChannelAbort(prAdapter, + (struct MSG_HDR *) prMsgChnlAbort); +} + +static void +p2pDevAdjustChnlTime(IN struct MSG_MGMT_TX_REQUEST *prMgmtTxMsg, + IN struct P2P_OFF_CHNL_TX_REQ_INFO *prOffChnlTxReq) +{ + enum ENUM_P2P_CONNECT_STATE eP2pActionFrameType = P2P_CNN_NORMAL; + uint32_t u4ExtendedTime = 0; + + if (prMgmtTxMsg == NULL || prOffChnlTxReq == NULL) + return; + + if (!prMgmtTxMsg->fgIsOffChannel) + return; + + if (prMgmtTxMsg->u4Duration < MIN_TX_DURATION_TIME_MS) { + /* + * The wait time requested from Supplicant may be too short + * to TX a frame, eg. nego.conf.. Overwrite the wait time + * as driver's min TX time. + */ + DBGLOG(P2P, INFO, "Overwrite channel duration from %d to %d\n", + prMgmtTxMsg->u4Duration, + MIN_TX_DURATION_TIME_MS); + prOffChnlTxReq->u4Duration = MIN_TX_DURATION_TIME_MS; + } else { + prOffChnlTxReq->u4Duration = prMgmtTxMsg->u4Duration; + } + + eP2pActionFrameType = p2pFuncGetP2pActionFrameType( + prMgmtTxMsg->prMgmtMsduInfo); + switch (eP2pActionFrameType) { + case P2P_CNN_GO_NEG_RESP: + u4ExtendedTime = P2P_DEV_EXTEND_CHAN_TIME; + break; + default: + break; + } + + if (u4ExtendedTime) { + DBGLOG(P2P, INFO, "Extended channel duration from %d to %d\n", + prOffChnlTxReq->u4Duration, + prOffChnlTxReq->u4Duration + u4ExtendedTime); + prOffChnlTxReq->u4Duration += u4ExtendedTime; + } +} /* p2pDevAdjustChnlTime */ + +static u_int8_t +p2pDevAddTxReq2Queue(IN struct ADAPTER *prAdapter, + IN struct P2P_MGMT_TX_REQ_INFO *prP2pMgmtTxReqInfo, + IN struct MSG_MGMT_TX_REQUEST *prMgmtTxMsg, + OUT struct P2P_OFF_CHNL_TX_REQ_INFO **pprOffChnlTxReq) +{ + struct P2P_OFF_CHNL_TX_REQ_INFO *prTmpOffChnlTxReq = + (struct P2P_OFF_CHNL_TX_REQ_INFO *) NULL; + + prTmpOffChnlTxReq = cnmMemAlloc(prAdapter, + RAM_TYPE_MSG, + sizeof(struct P2P_OFF_CHNL_TX_REQ_INFO)); + + if (prTmpOffChnlTxReq == NULL) { + DBGLOG(P2P, ERROR, + "Allocate TX request buffer fails.\n"); + return FALSE; + } + + prTmpOffChnlTxReq->ucBssIndex = prMgmtTxMsg->ucBssIdx; + prTmpOffChnlTxReq->u8Cookie = prMgmtTxMsg->u8Cookie; + prTmpOffChnlTxReq->prMgmtTxMsdu = prMgmtTxMsg->prMgmtMsduInfo; + prTmpOffChnlTxReq->fgNoneCckRate = prMgmtTxMsg->fgNoneCckRate; + kalMemCopy(&prTmpOffChnlTxReq->rChannelInfo, + &prMgmtTxMsg->rChannelInfo, + sizeof(struct RF_CHANNEL_INFO)); + prTmpOffChnlTxReq->eChnlExt = prMgmtTxMsg->eChnlExt; + prTmpOffChnlTxReq->fgIsWaitRsp = prMgmtTxMsg->fgIsWaitRsp; + + p2pDevAdjustChnlTime(prMgmtTxMsg, prTmpOffChnlTxReq); + + LINK_INSERT_TAIL(&prP2pMgmtTxReqInfo->rTxReqLink, + &prTmpOffChnlTxReq->rLinkEntry); + + *pprOffChnlTxReq = prTmpOffChnlTxReq; + + return TRUE; +} + +static void +p2pDevHandleOffchnlTxReq(IN struct ADAPTER *prAdapter, + IN struct MSG_MGMT_TX_REQUEST *prMgmtTxMsg) +{ + struct P2P_DEV_FSM_INFO *prP2pDevFsmInfo = + (struct P2P_DEV_FSM_INFO *) NULL; + struct P2P_MGMT_TX_REQ_INFO *prP2pMgmtTxReqInfo = + (struct P2P_MGMT_TX_REQ_INFO *) NULL; + struct P2P_OFF_CHNL_TX_REQ_INFO *prOffChnlTxReq = + (struct P2P_OFF_CHNL_TX_REQ_INFO *) NULL; + struct P2P_CHNL_REQ_INFO *prChnlReqInfo = + (struct P2P_CHNL_REQ_INFO *) NULL; + + if (prAdapter == NULL || prMgmtTxMsg == NULL) + return; + + prP2pDevFsmInfo = prAdapter->rWifiVar.prP2pDevFsmInfo; + + if (prP2pDevFsmInfo == NULL) + return; + + prP2pMgmtTxReqInfo = &(prP2pDevFsmInfo->rMgmtTxInfo); + prChnlReqInfo = &(prP2pDevFsmInfo->rChnlReqInfo); + + if (prP2pMgmtTxReqInfo == NULL || prChnlReqInfo == NULL) + return; + + p2pDevAbortChlReqIfNeed(prAdapter, prP2pDevFsmInfo, prChnlReqInfo); + + if (p2pDevAddTxReq2Queue(prAdapter, prP2pMgmtTxReqInfo, + prMgmtTxMsg, &prOffChnlTxReq) == FALSE) + goto error; + + if (prOffChnlTxReq == NULL) + return; + + switch (prP2pDevFsmInfo->eCurrentState) { + case P2P_DEV_STATE_IDLE: + if (!p2pDevChnlReqByOffChnl(prAdapter, prP2pDevFsmInfo, + prOffChnlTxReq)) + goto error; + break; + case P2P_DEV_STATE_REQING_CHANNEL: + if (prChnlReqInfo->eChnlReqType != CH_REQ_TYPE_OFFCHNL_TX) { + DBGLOG(P2P, WARN, + "channel already requested by others\n"); + goto error; + } + break; + case P2P_DEV_STATE_OFF_CHNL_TX: + if (p2pFuncCheckOnRocChnl(&(prMgmtTxMsg->rChannelInfo), + prChnlReqInfo) && + prP2pMgmtTxReqInfo->rTxReqLink.u4NumElem <= 1) { + p2pDevFsmStateTransition(prAdapter, + prP2pDevFsmInfo, + P2P_DEV_STATE_OFF_CHNL_TX); + } else { + log_dbg(P2P, INFO, "tx ch: %d, current ch: %d, isRequested: %d, tx link num: %d", + prMgmtTxMsg->rChannelInfo.ucChannelNum, + prChnlReqInfo->ucReqChnlNum, + prChnlReqInfo->fgIsChannelRequested, + prP2pMgmtTxReqInfo->rTxReqLink.u4NumElem); + } + break; + default: + /* do nothing & wait for IDLE state to handle TX request */ + break; + } + + return; + +error: + LINK_REMOVE_KNOWN_ENTRY( + &(prP2pMgmtTxReqInfo->rTxReqLink), + &prOffChnlTxReq->rLinkEntry); + cnmMgtPktFree(prAdapter, prOffChnlTxReq->prMgmtTxMsdu); + cnmMemFree(prAdapter, prOffChnlTxReq); +} /* p2pDevHandleOffchnlTxReq */ + +static u_int8_t +p2pDevNeedOffchnlTx(IN struct ADAPTER *prAdapter, + IN struct MSG_MGMT_TX_REQUEST *prMgmtTxMsg) +{ + struct P2P_DEV_FSM_INFO *prP2pDevFsmInfo = + (struct P2P_DEV_FSM_INFO *) NULL; + struct P2P_CHNL_REQ_INFO *prChnlReqInfo = + (struct P2P_CHNL_REQ_INFO *) NULL; + struct WLAN_MAC_HEADER *prWlanHdr = (struct WLAN_MAC_HEADER *) NULL; + + if (prAdapter == NULL || prMgmtTxMsg == NULL) + return FALSE; + + if (!prMgmtTxMsg->fgIsOffChannel) + return FALSE; + + prP2pDevFsmInfo = prAdapter->rWifiVar.prP2pDevFsmInfo; + prChnlReqInfo = prP2pDevFsmInfo != NULL ? + &(prP2pDevFsmInfo->rChnlReqInfo) : NULL; + + if (prChnlReqInfo == NULL) + return FALSE; + + prWlanHdr = (struct WLAN_MAC_HEADER *) + ((unsigned long) prMgmtTxMsg->prMgmtMsduInfo->prPacket + + MAC_TX_RESERVED_FIELD); + /* Probe response can only be sent during roc channel or op channel */ + if ((prWlanHdr->u2FrameCtrl & MASK_FRAME_TYPE) == MAC_FRAME_PROBE_RSP) + return FALSE; + + if (prP2pDevFsmInfo->eCurrentState == P2P_DEV_STATE_CHNL_ON_HAND && + p2pFuncCheckOnRocChnl(&(prMgmtTxMsg->rChannelInfo), + prChnlReqInfo)) + return FALSE; + + return TRUE; +} /* p2pDevNeedOffchnlTx */ + +void p2pDevFsmRunEventMgmtTx(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct MSG_MGMT_TX_REQUEST *prMgmtTxMsg = + (struct MSG_MGMT_TX_REQUEST *) NULL; + u_int8_t fgNeedOffchnlTx; + + prMgmtTxMsg = (struct MSG_MGMT_TX_REQUEST *) prMsgHdr; + + fgNeedOffchnlTx = p2pDevNeedOffchnlTx(prAdapter, prMgmtTxMsg); + DBGLOG(P2P, INFO, "fgNeedOffchnlTx: %d\n", fgNeedOffchnlTx); + + if (!fgNeedOffchnlTx) + p2pFuncTxMgmtFrame(prAdapter, + prAdapter->ucP2PDevBssIdx, + prMgmtTxMsg->prMgmtMsduInfo, + prMgmtTxMsg->fgNoneCckRate); + else + p2pDevHandleOffchnlTxReq(prAdapter, prMgmtTxMsg); + + cnmMemFree(prAdapter, prMsgHdr); +} /* p2pDevFsmRunEventMgmtTx */ + +uint32_t +p2pDevFsmRunEventMgmtFrameTxDone(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN enum ENUM_TX_RESULT_CODE rTxDoneStatus) +{ + u_int8_t fgIsSuccess = FALSE; + uint64_t *pu8GlCookie = (uint64_t *) NULL; + + do { + ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); + + if (!prMsduInfo->prPacket) { + DBGLOG(P2P, WARN, + "Freed Msdu, do not indicate to host\n"); + break; + } + + pu8GlCookie = + (uint64_t *) ((unsigned long) prMsduInfo->prPacket + + (unsigned long) prMsduInfo->u2FrameLength + + MAC_TX_RESERVED_FIELD); + + if (rTxDoneStatus != TX_RESULT_SUCCESS) { + DBGLOG(P2P, INFO, + "Mgmt Frame TX Fail, Status: %d. cookie: 0x%llx\n", + rTxDoneStatus, *pu8GlCookie); + } else { + fgIsSuccess = TRUE; + DBGLOG(P2P, INFO, + "Mgmt Frame TX Done. cookie: 0x%llx\n", + *pu8GlCookie); + } + + kalP2PIndicateMgmtTxStatus(prAdapter->prGlueInfo, + prMsduInfo, + fgIsSuccess); + } while (FALSE); + + return WLAN_STATUS_SUCCESS; +} /* p2pDevFsmRunEventMgmtFrameTxDone */ + +void p2pDevFsmRunEventMgmtFrameRegister(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + /* TODO: RX Filter Management. */ + + if (prMsgHdr) + cnmMemFree(prAdapter, prMsgHdr); +} /* p2pDevFsmRunEventMgmtFrameRegister */ + +void p2pDevFsmRunEventActiveDevBss(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct P2P_DEV_FSM_INFO *prP2pDevFsmInfo = + (struct P2P_DEV_FSM_INFO *) NULL; + + do { + ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); + prP2pDevFsmInfo = prAdapter->rWifiVar.prP2pDevFsmInfo; + + if (prP2pDevFsmInfo->eCurrentState + == P2P_DEV_STATE_IDLE) { + /* Get into IDLE state to let BSS be active + * and do not Deactive. + */ + p2pDevFsmStateTransition(prAdapter, + prP2pDevFsmInfo, + P2P_DEV_STATE_IDLE); + } + + } while (FALSE); + + if (prMsgHdr) + cnmMemFree(prAdapter, prMsgHdr); +} /* p2pDevFsmRunEventActiveDevBss */ + +void +p2pDevFsmNotifyP2pRx(IN struct ADAPTER *prAdapter, uint8_t p2pFrameType, + u_int8_t *prFgBufferFrame) +{ + struct P2P_DEV_FSM_INFO *prP2pDevFsmInfo = + (struct P2P_DEV_FSM_INFO *) NULL; + u_int8_t fgNeedWaitRspFrame = FALSE; + + prP2pDevFsmInfo = prAdapter->rWifiVar.prP2pDevFsmInfo; + fgNeedWaitRspFrame = p2pFuncNeedWaitRsp(prAdapter, p2pFrameType + 1); + + if (prP2pDevFsmInfo->eCurrentState == P2P_DEV_STATE_SCAN) { + if (fgNeedWaitRspFrame) + *prFgBufferFrame = TRUE; + return; + } + + if (prAdapter->prP2pInfo->eConnState != P2P_CNN_NORMAL) + return; + + if (fgNeedWaitRspFrame) { + DBGLOG(P2P, INFO, + "Extend channel duration, p2pFrameType: %d.\n", + p2pFrameType); + prAdapter->prP2pInfo->eConnState = p2pFrameType + 1; + } +} + +void p2pDevFsmRunEventTxCancelWait(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct P2P_DEV_FSM_INFO *prP2pDevFsmInfo = + (struct P2P_DEV_FSM_INFO *) NULL; + struct MSG_CANCEL_TX_WAIT_REQUEST *prCancelTxWaitMsg = + (struct MSG_CANCEL_TX_WAIT_REQUEST *) NULL; + struct P2P_MGMT_TX_REQ_INFO *prP2pMgmtTxInfo = + (struct P2P_MGMT_TX_REQ_INFO *) NULL; + struct P2P_OFF_CHNL_TX_REQ_INFO *prOffChnlTxPkt = + (struct P2P_OFF_CHNL_TX_REQ_INFO *) NULL; + u_int8_t fgIsCookieFound = FALSE; + + if (prAdapter == NULL || prMsgHdr == NULL) + goto exit; + + prCancelTxWaitMsg = (struct MSG_CANCEL_TX_WAIT_REQUEST *) prMsgHdr; + prP2pDevFsmInfo = prAdapter->rWifiVar.prP2pDevFsmInfo; + prP2pMgmtTxInfo = prP2pDevFsmInfo != NULL ? + &(prP2pDevFsmInfo->rMgmtTxInfo) : NULL; + + if (prCancelTxWaitMsg == NULL || prP2pDevFsmInfo == NULL || + prP2pMgmtTxInfo == NULL) + goto exit; + + LINK_FOR_EACH_ENTRY(prOffChnlTxPkt, + &(prP2pMgmtTxInfo->rTxReqLink), + rLinkEntry, + struct P2P_OFF_CHNL_TX_REQ_INFO) { + if (!prOffChnlTxPkt) + break; + if (prOffChnlTxPkt->u8Cookie == prCancelTxWaitMsg->u8Cookie) { + fgIsCookieFound = TRUE; + break; + } + } + + if (fgIsCookieFound == TRUE || prP2pDevFsmInfo->eCurrentState == + P2P_DEV_STATE_OFF_CHNL_TX) { + p2pFunClearAllTxReq(prAdapter, + &(prP2pDevFsmInfo->rMgmtTxInfo)); + p2pDevFsmRunEventAbort(prAdapter, prP2pDevFsmInfo); + } + +exit: + if (prMsgHdr) + cnmMemFree(prAdapter, prMsgHdr); +} /* p2pDevFsmRunEventTxCancelWait */ + +#endif /* CFG_ENABLE_WIFI_DIRECT */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/p2p_dev_state.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/p2p_dev_state.c new file mode 100644 index 0000000000000000000000000000000000000000..34e78cc6a8cac12fc8d38e6a554424815ba0ce45 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/p2p_dev_state.c @@ -0,0 +1,424 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +#include "precomp.h" + +u_int8_t +p2pDevStateInit_IDLE(IN struct ADAPTER *prAdapter, + IN struct P2P_CHNL_REQ_INFO *prChnlReqInfo, + OUT enum ENUM_P2P_DEV_STATE *peNextState) +{ + u_int8_t fgIsTransition = FALSE, fgIsShareInterface = TRUE; + uint32_t u4Idx = 0; + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *) NULL; + struct P2P_DEV_FSM_INFO *prP2pDevFsmInfo; + struct P2P_MGMT_TX_REQ_INFO *prP2pMgmtTxInfo; + + do { + ASSERT_BREAK((prAdapter != NULL) + && (prChnlReqInfo) && (peNextState != NULL)); + + if (!LINK_IS_EMPTY(&(prChnlReqInfo->rP2pChnlReqLink))) { + fgIsTransition = TRUE; + *peNextState = P2P_DEV_STATE_REQING_CHANNEL; + break; + } + + prP2pDevFsmInfo = prAdapter->rWifiVar.prP2pDevFsmInfo; + prP2pMgmtTxInfo = prP2pDevFsmInfo != NULL ? + &(prP2pDevFsmInfo->rMgmtTxInfo) : NULL; + if (prP2pDevFsmInfo && prP2pMgmtTxInfo && !LINK_IS_EMPTY( + &(prP2pMgmtTxInfo->rTxReqLink))) { + fgIsTransition = TRUE; + *peNextState = P2P_DEV_STATE_OFF_CHNL_TX; + break; + } + + /* Check the interface shared by P2P_DEV and P2P_ROLE or not? */ + /* If not shared, we shall let BSSID4 alive + * to receive PROVISION REQUEST from GC + */ + prGlueInfo = prAdapter->prGlueInfo; + if (prGlueInfo) { + for (u4Idx = 0; u4Idx < KAL_P2P_NUM; u4Idx++) { + if ((prGlueInfo->prP2PInfo[u4Idx] != NULL) && + (prGlueInfo->prP2PInfo[u4Idx]->aprRoleHandler + != NULL) && + (prGlueInfo->prP2PInfo[u4Idx]->aprRoleHandler + != + prGlueInfo->prP2PInfo[u4Idx]->prDevHandler)) { + fgIsShareInterface = FALSE; + break; + } + } + } + /************************* End *************************/ + + if (fgIsShareInterface) { + /* Stay in IDLE state. */ + UNSET_NET_ACTIVE(prAdapter, prAdapter->ucP2PDevBssIdx); + nicDeactivateNetwork(prAdapter, + prAdapter->ucP2PDevBssIdx); + } + } while (FALSE); + + return fgIsTransition; +} /* p2pDevStateInit_IDLE */ + +void p2pDevStateAbort_IDLE(IN struct ADAPTER *prAdapter) +{ + /* Currently Aobrt IDLE do nothing. */ +} /* p2pDevStateAbort_IDLE */ + +u_int8_t +p2pDevStateInit_REQING_CHANNEL(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIdx, + IN struct P2P_CHNL_REQ_INFO *prChnlReqInfo, + OUT enum ENUM_P2P_DEV_STATE *peNextState) +{ + u_int8_t fgIsTransition = FALSE; + struct MSG_P2P_CHNL_REQUEST *prP2pMsgChnlReq = + (struct MSG_P2P_CHNL_REQUEST *) NULL; + struct BSS_INFO *prBssInfo = (struct BSS_INFO *) NULL; + + do { + ASSERT_BREAK((prAdapter != NULL) + && (prChnlReqInfo != NULL) && (peNextState != NULL)); + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIdx); + + if (LINK_IS_EMPTY(&(prChnlReqInfo->rP2pChnlReqLink))) { + /* NO Channel Request Pending. */ + DBGLOG(P2P, ERROR, + "NO Pending Channel Request, but enter Req Channel State\n"); + fgIsTransition = TRUE; + *peNextState = P2P_DEV_STATE_IDLE; + break; + } + + LINK_REMOVE_HEAD(&(prChnlReqInfo->rP2pChnlReqLink), + prP2pMsgChnlReq, struct MSG_P2P_CHNL_REQUEST *); + + if (prP2pMsgChnlReq == NULL) { + ASSERT(FALSE); + break; + } + + if (prBssInfo->fgIsWmmInited == FALSE) + prBssInfo->ucWmmQueSet = MAX_HW_WMM_INDEX; + prBssInfo->eBand = prP2pMsgChnlReq->rChannelInfo.eBand; + cnmOpModeGetTRxNss( + prAdapter, prBssInfo->ucBssIndex, + &prBssInfo->ucOpRxNss, &prBssInfo->ucOpTxNss); + prChnlReqInfo->u4MaxInterval = prP2pMsgChnlReq->u4Duration; + prChnlReqInfo->ucReqChnlNum = + prP2pMsgChnlReq->rChannelInfo.ucChannelNum; + prChnlReqInfo->eChnlSco = prP2pMsgChnlReq->eChnlSco; + prChnlReqInfo->eBand = prP2pMsgChnlReq->rChannelInfo.eBand; + prChnlReqInfo->u8Cookie = prP2pMsgChnlReq->u8Cookie; + prChnlReqInfo->eChnlReqType = prP2pMsgChnlReq->eChnlReqType; + prChnlReqInfo->eChannelWidth = prBssInfo->ucVhtChannelWidth; + prChnlReqInfo->ucCenterFreqS1 = + prBssInfo->ucVhtChannelFrequencyS1; + prChnlReqInfo->ucCenterFreqS2 = + prBssInfo->ucVhtChannelFrequencyS2; + + p2pFuncAcquireCh(prAdapter, ucBssIdx, prChnlReqInfo); + } while (FALSE); + + if (prP2pMsgChnlReq) + cnmMemFree(prAdapter, prP2pMsgChnlReq); + + return fgIsTransition; +} /* p2pDevStateInit_REQING_CHANNEL */ + +void +p2pDevStateAbort_REQING_CHANNEL(IN struct ADAPTER *prAdapter, + IN struct P2P_CHNL_REQ_INFO *prChnlReqInfo, + IN enum ENUM_P2P_DEV_STATE eNextState) +{ + do { + ASSERT_BREAK((prAdapter != NULL) + && (prChnlReqInfo != NULL) + && (eNextState < P2P_DEV_STATE_NUM)); + + switch (eNextState) { + case P2P_DEV_STATE_IDLE: + /* Channel abort case. */ + p2pFuncReleaseCh(prAdapter, + prAdapter->ucP2PDevBssIdx, prChnlReqInfo); + break; + case P2P_DEV_STATE_CHNL_ON_HAND: + /* Channel on hand case. */ + break; + case P2P_DEV_STATE_OFF_CHNL_TX: + /* OffChannel TX case. */ + break; + default: + /* Un-expected state transition. */ + DBGLOG(P2P, ERROR, + "Unexpected State Transition(eNextState=%d)\n", + eNextState); + ASSERT(FALSE); + break; + } + } while (FALSE); +} /* p2pDevStateAbort_REQING_CHANNEL */ + +void +p2pDevStateInit_CHNL_ON_HAND(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prP2pBssInfo, + IN struct P2P_DEV_FSM_INFO *prP2pDevFsmInfo, + IN struct P2P_CHNL_REQ_INFO *prChnlReqInfo) +{ + do { + uint32_t u4TimeoutMs = 0; + + ASSERT_BREAK((prAdapter != NULL) + && (prP2pDevFsmInfo != NULL) + && (prChnlReqInfo != NULL)); + + ASSERT(prChnlReqInfo->eChnlReqType == CH_REQ_TYPE_ROC); + + prChnlReqInfo->ucOriChnlNum = prP2pBssInfo->ucPrimaryChannel; + prChnlReqInfo->eOriBand = prP2pBssInfo->eBand; + prChnlReqInfo->eOriChnlSco = prP2pBssInfo->eBssSCO; + + prP2pBssInfo->ucPrimaryChannel = prChnlReqInfo->ucReqChnlNum; + prP2pBssInfo->eBand = prChnlReqInfo->eBand; + prP2pBssInfo->eBssSCO = prChnlReqInfo->eChnlSco; + + if (prAdapter->prP2pInfo->ucExtendChanFlag) + u4TimeoutMs = P2P_DEV_EXTEND_CHAN_TIME; + else + u4TimeoutMs = prChnlReqInfo->u4MaxInterval; + + log_dbg(P2P, INFO, + "Start channel on hand timer, Cookie: 0x%llx, Interval: %d\n", + prChnlReqInfo->u8Cookie, u4TimeoutMs); + + cnmTimerStartTimer(prAdapter, + &(prP2pDevFsmInfo->rP2pFsmTimeoutTimer), + u4TimeoutMs); + + /* Do NOT report channel ready event again for extension case */ + if (!prAdapter->prP2pInfo->ucExtendChanFlag) { + kalP2PIndicateChannelReady(prAdapter->prGlueInfo, + prChnlReqInfo->u8Cookie, + prChnlReqInfo->ucReqChnlNum, + prChnlReqInfo->eBand, + prChnlReqInfo->eChnlSco, + prChnlReqInfo->u4MaxInterval); + if (prP2pDevFsmInfo->rQueuedActionFrame.u2Length > 0) { + kalP2pIndicateQueuedMgmtFrame( + prAdapter->prGlueInfo, + &prP2pDevFsmInfo->rQueuedActionFrame); + p2pFunCleanQueuedMgmtFrame(prAdapter, + &prP2pDevFsmInfo->rQueuedActionFrame); + } + } + } while (FALSE); +} /* p2pDevStateInit_CHNL_ON_HAND */ + +void +p2pDevStateAbort_CHNL_ON_HAND(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prP2pBssInfo, + IN struct P2P_DEV_FSM_INFO *prP2pDevFsmInfo, + IN struct P2P_CHNL_REQ_INFO *prChnlReqInfo, + IN enum ENUM_P2P_DEV_STATE eNextState) +{ + do { + ASSERT_BREAK((prAdapter != NULL) || (prChnlReqInfo != NULL)); + + cnmTimerStopTimer(prAdapter, + &(prP2pDevFsmInfo->rP2pFsmTimeoutTimer)); + + prP2pBssInfo->ucPrimaryChannel = prChnlReqInfo->ucOriChnlNum; + prP2pBssInfo->eBand = prChnlReqInfo->eOriBand; + prP2pBssInfo->eBssSCO = prChnlReqInfo->eOriChnlSco; + + if (eNextState != P2P_DEV_STATE_CHNL_ON_HAND) { + kalP2PIndicateChannelExpired(prAdapter->prGlueInfo, + prChnlReqInfo->u8Cookie, + prChnlReqInfo->ucReqChnlNum, + prChnlReqInfo->eBand, + prChnlReqInfo->eChnlSco); + + p2pFuncReleaseCh(prAdapter, + prP2pDevFsmInfo->ucBssIndex, prChnlReqInfo); + p2pFunCleanQueuedMgmtFrame(prAdapter, + &prP2pDevFsmInfo->rQueuedActionFrame); + } + } while (FALSE); +} /* p2pDevStateAbort_CHNL_ON_HAND */ + +void p2pDevStateInit_SCAN(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN struct P2P_SCAN_REQ_INFO *prScanReqInfo) +{ + do { + ASSERT_BREAK((prAdapter != NULL) && (prScanReqInfo != NULL)); + + prScanReqInfo->fgIsScanRequest = TRUE; + + p2pFuncRequestScan(prAdapter, ucBssIndex, prScanReqInfo); + } while (FALSE); +} /* p2pDevStateInit_CHNL_ON_HAND */ + +void p2pDevStateAbort_SCAN(IN struct ADAPTER *prAdapter, + IN struct P2P_DEV_FSM_INFO *prP2pDevFsmInfo) +{ + struct P2P_SCAN_REQ_INFO *prScanInfo = + (struct P2P_SCAN_REQ_INFO *) NULL; + + do { + ASSERT_BREAK((prAdapter != NULL) + && (prP2pDevFsmInfo != NULL)); + + prScanInfo = &(prP2pDevFsmInfo->rScanReqInfo); + + p2pFuncCancelScan(prAdapter, + prP2pDevFsmInfo->ucBssIndex, + prScanInfo); + + kalP2PIndicateScanDone(prAdapter->prGlueInfo, + 0xFF, + prScanInfo->fgIsAbort); + } while (FALSE); +} /* p2pDevStateAbort_CHNL_ON_HAND */ + +u_int8_t +p2pDevStateInit_OFF_CHNL_TX(IN struct ADAPTER *prAdapter, + IN struct P2P_DEV_FSM_INFO *prP2pDevFsmInfo, + IN struct P2P_CHNL_REQ_INFO *prChnlReqInfo, + IN struct P2P_MGMT_TX_REQ_INFO *prP2pMgmtTxInfo, + OUT enum ENUM_P2P_DEV_STATE *peNextState) +{ + struct P2P_OFF_CHNL_TX_REQ_INFO *prOffChnlTxPkt = + (struct P2P_OFF_CHNL_TX_REQ_INFO *) NULL; + + if (prAdapter == NULL || prP2pMgmtTxInfo == NULL || peNextState == NULL) + return FALSE; + + if (LINK_IS_EMPTY(&(prP2pMgmtTxInfo->rTxReqLink))) { + p2pFuncReleaseCh(prAdapter, + prAdapter->ucP2PDevBssIdx, + prChnlReqInfo); + /* Link is empty, return back to IDLE. */ + *peNextState = P2P_DEV_STATE_IDLE; + return TRUE; + } + + prOffChnlTxPkt = + LINK_PEEK_HEAD(&(prP2pMgmtTxInfo->rTxReqLink), + struct P2P_OFF_CHNL_TX_REQ_INFO, + rLinkEntry); + + if (prOffChnlTxPkt == NULL) { + DBGLOG(P2P, ERROR, + "Fatal Error, Link not empty but get NULL pointer.\n"); + ASSERT(FALSE); + return FALSE; + } + + if (!p2pFuncCheckOnRocChnl(&(prOffChnlTxPkt->rChannelInfo), + prChnlReqInfo)) { + DBGLOG(P2P, WARN, + "req channel(%d) != TX channel(%d), request chnl again", + prChnlReqInfo->ucReqChnlNum, + prOffChnlTxPkt->rChannelInfo.ucChannelNum); + + prChnlReqInfo->u8Cookie = prOffChnlTxPkt->u8Cookie; + prChnlReqInfo->eChnlReqType = CH_REQ_TYPE_OFFCHNL_TX; + prChnlReqInfo->eBand = prOffChnlTxPkt->rChannelInfo.eBand; + prChnlReqInfo->ucReqChnlNum = + prOffChnlTxPkt->rChannelInfo.ucChannelNum; + prChnlReqInfo->eChnlSco = prOffChnlTxPkt->eChnlExt; + prChnlReqInfo->u4MaxInterval = prOffChnlTxPkt->u4Duration; + + p2pFuncAcquireCh(prAdapter, + prP2pDevFsmInfo->ucBssIndex, + prChnlReqInfo); + } else { + cnmTimerStartTimer(prAdapter, + &(prP2pDevFsmInfo->rP2pFsmTimeoutTimer), + prOffChnlTxPkt->u4Duration); + p2pFuncTxMgmtFrame(prAdapter, + prP2pDevFsmInfo->ucBssIndex, + prOffChnlTxPkt->prMgmtTxMsdu, + prOffChnlTxPkt->fgNoneCckRate); + + LINK_REMOVE_HEAD(&(prP2pMgmtTxInfo->rTxReqLink), + prOffChnlTxPkt, + struct P2P_OFF_CHNL_TX_REQ_INFO *); + cnmMemFree(prAdapter, prOffChnlTxPkt); + } + + return FALSE; +} /* p2pDevSateInit_OFF_CHNL_TX */ + +void +p2pDevStateAbort_OFF_CHNL_TX(IN struct ADAPTER *prAdapter, + IN struct P2P_DEV_FSM_INFO *prP2pDevFsmInfo, + IN struct P2P_MGMT_TX_REQ_INFO *prP2pMgmtTxInfo, + IN struct P2P_CHNL_REQ_INFO *prChnlReqInfo, + IN enum ENUM_P2P_DEV_STATE eNextState) +{ + cnmTimerStopTimer(prAdapter, &(prP2pDevFsmInfo->rP2pFsmTimeoutTimer)); + + if (eNextState == P2P_DEV_STATE_OFF_CHNL_TX) + return; + + p2pFunClearAllTxReq(prAdapter, prP2pMgmtTxInfo); + p2pFuncReleaseCh(prAdapter, + prAdapter->ucP2PDevBssIdx, + prChnlReqInfo); +} /* p2pDevSateAbort_OFF_CHNL_TX */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/p2p_fsm.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/p2p_fsm.c new file mode 100644 index 0000000000000000000000000000000000000000..a2164bdfec278d29371eb0477ef7ca0fc0fc65d1 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/p2p_fsm.c @@ -0,0 +1,472 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/mgmt/p2p_fsm.c#61 + */ + +/*! \file "p2p_fsm.c" + * \brief This file defines the FSM for P2P Module. + * + * This file defines the FSM for P2P Module. + */ + + +/****************************************************************************** + * C O M P I L E R F L A G S + ****************************************************************************** + */ + +/****************************************************************************** + * E X T E R N A L R E F E R E N C E S + ****************************************************************************** + */ +#include "precomp.h" + +#if CFG_ENABLE_WIFI_DIRECT + +/****************************************************************************** + * C O N S T A N T S + ****************************************************************************** + */ + +/****************************************************************************** + * D A T A T Y P E S + ****************************************************************************** + */ + +/****************************************************************************** + * P U B L I C D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * P R I V A T E D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * M A C R O S + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N D E C L A R A T I O N S + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N S + ****************************************************************************** + */ +static u_int8_t p2pFsmUseRoleIf(IN struct ADAPTER *prAdapter, + uint8_t ucBssIdx) +{ + u_int8_t fgUseRoleInterface = FALSE; + struct BSS_INFO *prBssInfo = (struct BSS_INFO *) NULL; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIdx); + + if (prBssInfo == NULL) { + DBGLOG(P2P, ERROR, "can not get bss info by bssIdx: %d", + ucBssIdx); + return FALSE; + } + + if (ucBssIdx != prAdapter->ucP2PDevBssIdx) { + if (IS_NET_ACTIVE(prAdapter, ucBssIdx)) { + fgUseRoleInterface = TRUE; + if (prBssInfo->eIftype != IFTYPE_P2P_CLIENT && + prBssInfo->eIftype != IFTYPE_P2P_GO && + !p2pFuncIsAPMode( + prAdapter->rWifiVar + .prP2PConnSettings + [prBssInfo->u4PrivateData])) { + DBGLOG(P2P, TRACE, + "force use dev interface.\n"); + fgUseRoleInterface = FALSE; + } + } else { + fgUseRoleInterface = FALSE; + } + } else { + fgUseRoleInterface = FALSE; + } + + DBGLOG(P2P, TRACE, "bss[%d %d], role: %d, use_role_if: %d\n", + ucBssIdx, + IS_NET_ACTIVE(prAdapter, ucBssIdx), + prBssInfo->eIftype, + fgUseRoleInterface); + + return fgUseRoleInterface; +} + +void p2pFsmRunEventScanRequest(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct MSG_P2P_SCAN_REQUEST *prP2pScanReqMsg = + (struct MSG_P2P_SCAN_REQUEST *) NULL; + + do { + ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); + if ((prAdapter == NULL) || (prMsgHdr == NULL)) + break; + + prP2pScanReqMsg = (struct MSG_P2P_SCAN_REQUEST *) prMsgHdr; + + prAdapter->prP2pInfo->eConnState = P2P_CNN_NORMAL; + + if (prP2pScanReqMsg->ucBssIdx == prAdapter->ucP2PDevBssIdx) + p2pDevFsmRunEventScanRequest(prAdapter, prMsgHdr); + else + p2pRoleFsmRunEventScanRequest(prAdapter, prMsgHdr); + + prMsgHdr = NULL; + /* Both p2pDevFsmRunEventScanRequest and + * p2pRoleFsmRunEventScanRequest + * free prMsgHdr before return, + * so prMsgHdr is needed to be NULL. + */ + } while (FALSE); + + /* + * if (prAdapter && prMsgHdr) + * cnmMemFree(prAdapter, prMsgHdr); + */ +} /* p2pDevFsmRunEventScanRequest */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is call when channel is granted + * by CNM module from FW. + * + * \param[in] prAdapter Pointer of ADAPTER_T + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void p2pFsmRunEventChGrant(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct MSG_CH_GRANT *prMsgChGrant = (struct MSG_CH_GRANT *) NULL; + struct BSS_INFO *prP2pBssInfo = (struct BSS_INFO *) NULL; + + do { + ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); + + prMsgChGrant = (struct MSG_CH_GRANT *) prMsgHdr; + + prP2pBssInfo = + GET_BSS_INFO_BY_INDEX(prAdapter, + prMsgChGrant->ucBssIndex); + + prAdapter->prP2pInfo->eConnState = P2P_CNN_NORMAL; + prAdapter->prP2pInfo->ucExtendChanFlag = 0; + + DBGLOG(P2P, TRACE, "P2P Run Event Channel Grant\n"); + +#if CFG_SISO_SW_DEVELOP + /* Driver record granted CH in BSS info */ + prP2pBssInfo->fgIsGranted = TRUE; + prP2pBssInfo->eBandGranted = prMsgChGrant->eRfBand; + prP2pBssInfo->ucPrimaryChannelGranted = + prMsgChGrant->ucPrimaryChannel; +#endif + + switch (prP2pBssInfo->eCurrentOPMode) { + case OP_MODE_P2P_DEVICE: + ASSERT(prP2pBssInfo->ucBssIndex + == prAdapter->ucP2PDevBssIdx); + + p2pDevFsmRunEventChnlGrant(prAdapter, + prMsgHdr, + prAdapter->rWifiVar.prP2pDevFsmInfo); + break; + case OP_MODE_INFRASTRUCTURE: + case OP_MODE_ACCESS_POINT: + ASSERT(prP2pBssInfo->ucBssIndex + < prAdapter->ucP2PDevBssIdx); + + p2pRoleFsmRunEventChnlGrant(prAdapter, prMsgHdr, + P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, + prP2pBssInfo->u4PrivateData)); + break; + default: + ASSERT(FALSE); + break; + } + } while (FALSE); +} /* p2pFsmRunEventChGrant */ + +void p2pFsmRunEventNetDeviceRegister(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct MSG_P2P_NETDEV_REGISTER *prNetDevRegisterMsg = + (struct MSG_P2P_NETDEV_REGISTER *) NULL; + + DBGLOG(P2P, TRACE, "p2pFsmRunEventNetDeviceRegister\n"); + + prNetDevRegisterMsg = (struct MSG_P2P_NETDEV_REGISTER *) prMsgHdr; + + if (prNetDevRegisterMsg->fgIsEnable) { + p2pSetMode((prNetDevRegisterMsg->ucMode == 1) ? TRUE : FALSE); + if (p2pLaunch(prAdapter->prGlueInfo)) + ASSERT(prAdapter->fgIsP2PRegistered); + } else { + if (prAdapter->fgIsP2PRegistered) + p2pRemove(prAdapter->prGlueInfo); + } + + cnmMemFree(prAdapter, prMsgHdr); +} /* p2pFsmRunEventNetDeviceRegister */ + +void p2pFsmRunEventUpdateMgmtFrame(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct MSG_P2P_MGMT_FRAME_UPDATE *prP2pMgmtFrameUpdateMsg = + (struct MSG_P2P_MGMT_FRAME_UPDATE *) NULL; + + DBGLOG(P2P, TRACE, "p2pFsmRunEventUpdateMgmtFrame\n"); + + prP2pMgmtFrameUpdateMsg = (struct MSG_P2P_MGMT_FRAME_UPDATE *) prMsgHdr; + + switch (prP2pMgmtFrameUpdateMsg->eBufferType) { + case ENUM_FRAME_TYPE_EXTRA_IE_BEACON: + break; + case ENUM_FRAME_TYPE_EXTRA_IE_ASSOC_RSP: + break; + case ENUM_FRAME_TYPE_EXTRA_IE_PROBE_RSP: + break; + case ENUM_FRAME_TYPE_PROBE_RSP_TEMPLATE: + break; + case ENUM_FRAME_TYPE_BEACON_TEMPLATE: + break; + default: + break; + } + + cnmMemFree(prAdapter, prMsgHdr); +} /* p2pFsmRunEventUpdateMgmtFrame */ + +#if CFG_SUPPORT_WFD +void p2pFsmRunEventWfdSettingUpdate(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct WFD_CFG_SETTINGS *prWfdCfgSettings = + (struct WFD_CFG_SETTINGS *) NULL; + struct MSG_WFD_CONFIG_SETTINGS_CHANGED *prMsgWfdCfgSettings = + (struct MSG_WFD_CONFIG_SETTINGS_CHANGED *) NULL; + uint32_t i; + + /* WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; */ + + DBGLOG(P2P, INFO, "p2pFsmRunEventWfdSettingUpdate\n"); + + do { + ASSERT_BREAK((prAdapter != NULL)); + + if (prMsgHdr != NULL) { + prMsgWfdCfgSettings = + (struct MSG_WFD_CONFIG_SETTINGS_CHANGED *) + prMsgHdr; + prWfdCfgSettings = + prMsgWfdCfgSettings->prWfdCfgSettings; + } else { + prWfdCfgSettings = + &prAdapter->rWifiVar.rWfdConfigureSettings; + } + + DBGLOG(P2P, INFO, + "WFD Enalbe %x info %x state %x flag %x adv %x\n", + prWfdCfgSettings->ucWfdEnable, + prWfdCfgSettings->u2WfdDevInfo, + (uint32_t) prWfdCfgSettings->u4WfdState, + (uint32_t) prWfdCfgSettings->u4WfdFlag, + (uint32_t) prWfdCfgSettings->u4WfdAdvancedFlag); + + if (prWfdCfgSettings->ucWfdEnable == 0) + for (i = 0; i < KAL_P2P_NUM; i++) { + if (prAdapter->prGlueInfo->prP2PInfo[i]) + prAdapter->prGlueInfo->prP2PInfo[i] + ->u2WFDIELen = 0; + } + +#if CFG_ENABLE_PER_STA_STATISTICS_LOG + if (prAdapter->rWifiVar.aprP2pRoleFsmInfo[0]) { + /* Assume role 0 */ + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *) + prAdapter->rWifiVar.aprP2pRoleFsmInfo[0]; + + if (prWfdCfgSettings->ucWfdEnable == 1) + cnmTimerStartTimer(prAdapter, + &(prP2pRoleFsmInfo + ->rP2pRoleFsmGetStatisticsTimer), + (3 * P2P_ROLE_GET_STATISTICS_TIME)); + else { + cnmTimerStopTimer(prAdapter, + &prP2pRoleFsmInfo + ->rP2pRoleFsmGetStatisticsTimer); + /* Reset linkscore */ + prWfdCfgSettings->u4LinkScore = 0; + } + } +#endif + + } while (FALSE); + + if (prMsgHdr) + cnmMemFree(prAdapter, prMsgHdr); +} + +/* p2pFsmRunEventWfdSettingUpdate */ + +#endif /* CFG_SUPPORT_WFD */ + + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is used to handle scan done event + * during Device Discovery. + * + * \param[in] prAdapter Pointer of ADAPTER_T + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void p2pFsmRunEventScanDone(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct MSG_SCN_SCAN_DONE *prScanDoneMsg = + (struct MSG_SCN_SCAN_DONE *) NULL; + struct BSS_INFO *prP2pBssInfo = (struct BSS_INFO *) NULL; + + prScanDoneMsg = (struct MSG_SCN_SCAN_DONE *) prMsgHdr; + + prP2pBssInfo = + GET_BSS_INFO_BY_INDEX(prAdapter, prScanDoneMsg->ucBssIndex); + + if (prAdapter->fgIsP2PRegistered == FALSE) { + DBGLOG(P2P, TRACE, + "P2P BSS Info is removed, break p2pFsmRunEventScanDone\n"); + + cnmMemFree(prAdapter, prMsgHdr); + return; + } + + DBGLOG(P2P, TRACE, "P2P Scan Done Event\n"); + + switch (prP2pBssInfo->eCurrentOPMode) { + case OP_MODE_P2P_DEVICE: + ASSERT(prP2pBssInfo->ucBssIndex == prAdapter->ucP2PDevBssIdx); + p2pDevFsmRunEventScanDone(prAdapter, + prMsgHdr, + prAdapter->rWifiVar.prP2pDevFsmInfo); + break; + case OP_MODE_INFRASTRUCTURE: + case OP_MODE_ACCESS_POINT: + ASSERT(prP2pBssInfo->ucBssIndex < prAdapter->ucP2PDevBssIdx); + p2pRoleFsmRunEventScanDone(prAdapter, prMsgHdr, + P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, + prP2pBssInfo->u4PrivateData)); + break; + default: + ASSERT(FALSE); + break; + } +} /* p2pFsmRunEventScanDone */ + +void p2pFsmRunEventMgmtFrameTx(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct MSG_MGMT_TX_REQUEST *prMgmtTxMsg = + (struct MSG_MGMT_TX_REQUEST *) NULL; + + do { + if ((prAdapter == NULL) || (prMsgHdr == NULL)) + break; + + prMgmtTxMsg = (struct MSG_MGMT_TX_REQUEST *) prMsgHdr; + + if (p2pFsmUseRoleIf(prAdapter, prMgmtTxMsg->ucBssIdx)) { + p2pRoleFsmRunEventMgmtTx(prAdapter, prMsgHdr); + } else { + prMgmtTxMsg->ucBssIdx = prAdapter->ucP2PDevBssIdx; + p2pDevFsmRunEventMgmtTx(prAdapter, prMsgHdr); + } + } while (FALSE); +} /* p2pFsmRunEventMgmtFrameTx */ + +void p2pFsmRunEventTxCancelWait(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct MSG_CANCEL_TX_WAIT_REQUEST *prCancelTxWaitMsg = + (struct MSG_CANCEL_TX_WAIT_REQUEST *) NULL; + + do { + if ((prAdapter == NULL) || (prMsgHdr == NULL)) + break; + + prCancelTxWaitMsg = + (struct MSG_CANCEL_TX_WAIT_REQUEST *) prMsgHdr; + + if (p2pFsmUseRoleIf(prAdapter, prCancelTxWaitMsg->ucBssIdx)) { + p2pRoleFsmRunEventTxCancelWait(prAdapter, prMsgHdr); + } else { + prCancelTxWaitMsg->ucBssIdx = prAdapter->ucP2PDevBssIdx; + p2pDevFsmRunEventTxCancelWait(prAdapter, prMsgHdr); + } + } while (FALSE); + +} /* p2pFsmRunEventTxCancelWait */ + +#endif /* CFG_ENABLE_WIFI_DIRECT */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/p2p_func.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/p2p_func.c new file mode 100644 index 0000000000000000000000000000000000000000..8c78b12ae064ded04f66ebb638ed597117531c87 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/p2p_func.c @@ -0,0 +1,7231 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ + +#include "precomp.h" + +struct APPEND_VAR_ATTRI_ENTRY txAssocRspAttributesTable[] = { + {(P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_STATUS), NULL, + p2pFuncAppendAttriStatusForAssocRsp} + /* 0 *//* Status */ + , {(P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_EXT_LISTEN_TIMING), NULL, + p2pFuncAppendAttriExtListenTiming} /* 8 */ +}; + +struct APPEND_VAR_IE_ENTRY txProbeRspIETable[] = { + {(ELEM_HDR_LEN + (RATE_NUM_SW - ELEM_MAX_LEN_SUP_RATES)), NULL, + bssGenerateExtSuppRate_IE} /* 50 */ + , {(ELEM_HDR_LEN + ELEM_MAX_LEN_ERP), NULL, + rlmRspGenerateErpIE} /* 42 */ + , {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP), NULL, + rlmRspGenerateHtCapIE} /* 45 */ + , {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP), NULL, + rlmRspGenerateHtOpIE} /* 61 */ + , {(ELEM_HDR_LEN + ELEM_MAX_LEN_RSN), NULL, + rsnGenerateRSNIE} /* 48 */ + , {(ELEM_HDR_LEN + ELEM_MAX_LEN_OBSS_SCAN), NULL, + rlmRspGenerateObssScanIE} /* 74 */ + , {(ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP), NULL, + rlmRspGenerateExtCapIE} /* 127 */ + , {(ELEM_HDR_LEN + ELEM_MAX_LEN_WPA), NULL, + rsnGenerateWpaNoneIE} /* 221 */ + , {(ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_PARAM), NULL, + mqmGenerateWmmParamIE} /* 221 */ +#if CFG_SUPPORT_802_11AC + , {(ELEM_HDR_LEN + ELEM_MAX_LEN_VHT_CAP), NULL, + rlmRspGenerateVhtCapIE} /*191 */ + , {(ELEM_HDR_LEN + ELEM_MAX_LEN_VHT_OP), NULL, + rlmRspGenerateVhtOpIE} /*192 */ + , {(ELEM_HDR_LEN + ELEM_MAX_LEN_VHT_OP_MODE_NOTIFICATION), NULL, + rlmRspGenerateVhtOpNotificationIE} /*199 */ +#endif +#if CFG_SUPPORT_802_11AX + , {0, heRlmCalculateHeCapIELen, + heRlmRspGenerateHeCapIE} /* 255, EXT 35 */ + , {0, heRlmCalculateHeOpIELen, + heRlmRspGenerateHeOpIE} /* 255, EXT 36 */ +#endif +#if CFG_SUPPORT_MTK_SYNERGY + , {(ELEM_HDR_LEN + ELEM_MIN_LEN_MTK_OUI), NULL, + rlmGenerateMTKOuiIE} /* 221 */ +#endif + , {(ELEM_HDR_LEN + ELEM_MAX_LEN_WPA), NULL, + rsnGenerateWPAIE} /* 221 */ +}; + +#if (CFG_SUPPORT_DFS_MASTER == 1) +u_int8_t g_fgManualCac = FALSE; +uint32_t g_u4DriverCacTime; +uint32_t g_u4CacStartBootTime; +uint8_t g_ucRadarDetectMode = FALSE; +struct P2P_RADAR_INFO g_rP2pRadarInfo; +uint8_t g_ucDfsState = DFS_STATE_INACTIVE; +static uint8_t *apucDfsState[DFS_STATE_NUM] = { + (uint8_t *) DISP_STRING("DFS_STATE_INACTIVE"), + (uint8_t *) DISP_STRING("DFS_STATE_CHECKING"), + (uint8_t *) DISP_STRING("DFS_STATE_ACTIVE"), + (uint8_t *) DISP_STRING("DFS_STATE_DETECTED") +}; + +uint8_t *apucW53RadarType[3] = { + (uint8_t *) DISP_STRING("Unknown Type"), + (uint8_t *) DISP_STRING("Type 1 (short pulse)"), + (uint8_t *) DISP_STRING("Type 2 (short pulse)") +}; +uint8_t *apucW56RadarType[12] = { + (uint8_t *) DISP_STRING("Unknown Type"), + (uint8_t *) DISP_STRING("Type 1 (short pulse)"), + (uint8_t *) DISP_STRING("Type 2 (short pulse)"), + (uint8_t *) DISP_STRING("Type 3 (short pulse)"), + (uint8_t *) DISP_STRING("Type 4 (short pulse)"), + (uint8_t *) DISP_STRING("Type 5 (short pulse)"), + (uint8_t *) DISP_STRING("Type 6 (short pulse)"), + (uint8_t *) DISP_STRING("Type 7 (long pulse)"), + (uint8_t *) DISP_STRING("Type 8 (short pulse)"), + (uint8_t *) DISP_STRING("Type 4 or Type 5 or Type 6 (short pulse)"), + (uint8_t *) DISP_STRING("Type 5 or Type 6 or Type 8 (short pulse)"), + (uint8_t *) DISP_STRING("Type 5 or Type 6 (short pulse)") +}; +#endif + +static void +p2pFuncParseBeaconVenderId(IN struct ADAPTER *prAdapter, IN uint8_t *pucIE, + IN struct P2P_SPECIFIC_BSS_INFO *prP2pSpecificBssInfo, + IN uint8_t ucRoleIndex); +#if 0 +static void +p2pFuncGetAttriListAction(IN struct ADAPTER *prAdapter, + IN struct IE_P2P *prIe, + IN uint8_t ucOuiType, + OUT uint8_t **pucAttriListStart, + OUT uint16_t *u2AttriListLen, + OUT u_int8_t *fgIsAllocMem, + OUT u_int8_t *fgBackupAttributes, + OUT uint16_t *u2BufferSize); +#endif + +static void +p2pFuncProcessP2pProbeRspAction(IN struct ADAPTER *prAdapter, + IN uint8_t *pucIEBuf, IN uint8_t ucElemIdType, + OUT uint8_t *ucBssIdx, OUT struct BSS_INFO **prP2pBssInfo, + OUT u_int8_t *fgIsWSCIE, + OUT u_int8_t *fgIsP2PIE, + OUT u_int8_t *fgIsWFDIE, + OUT u_int8_t *fgIsVenderIE); + +static void +p2pFuncGetSpecAttriAction(IN struct IE_P2P *prP2pIE, + IN uint8_t ucOuiType, + IN uint8_t ucAttriID, + OUT struct P2P_ATTRIBUTE **prTargetAttri); + +/*---------------------------------------------------------------------------*/ +/*! + * @brief Function for requesting scan. + * There is an option to do ACTIVE or PASSIVE scan. + * + * @param eScanType - Specify the scan type of the scan request. + * It can be an ACTIVE/PASSIVE + * Scan. + * eChannelSet - Specify the preferred channel set. + * A FULL scan would request a legacy + * full channel normal scan.(usually ACTIVE). + * A P2P_SOCIAL scan would scan + * 1+6+11 channels.(usually ACTIVE) + * A SPECIFIC scan would + * only 1/6/11 channels scan. + * (Passive Listen/Specific Search) + * ucChannelNum - A specific channel number. + * (Only when channel is specified) + * eBand - A specific band. (Only when channel is specified) + * + * + * @return (none) + */ +/*---------------------------------------------------------------------------*/ +void p2pFuncRequestScan(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN struct P2P_SCAN_REQ_INFO *prScanReqInfo) +{ + struct MSG_SCN_SCAN_REQ_V2 *prScanReqV2 = + (struct MSG_SCN_SCAN_REQ_V2 *) NULL; + +#ifdef CFG_SUPPORT_BEAM_PLUS + /*NFC Beam + Indication */ + struct P2P_FSM_INFO *prP2pFsmInfo = (struct P2P_FSM_INFO *) NULL; +#endif + + DEBUGFUNC("p2pFuncRequestScan()"); + + do { + ASSERT_BREAK((prAdapter != NULL) && (prScanReqInfo != NULL)); + + if (prScanReqInfo->eChannelSet == SCAN_CHANNEL_SPECIFIED) { + ASSERT_BREAK(prScanReqInfo->ucNumChannelList > 0); + DBGLOG(P2P, LOUD, + "P2P Scan Request Channel:%d\n", + prScanReqInfo->arScanChannelList + [0].ucChannelNum); + } + + prScanReqV2 = (struct MSG_SCN_SCAN_REQ_V2 *) + cnmMemAlloc(prAdapter, RAM_TYPE_MSG, + (sizeof(struct MSG_SCN_SCAN_REQ_V2) + + (sizeof(struct PARAM_SSID) * + prScanReqInfo->ucSsidNum))); + if (!prScanReqV2) { + DBGLOG(P2P, ERROR, + "p2pFuncRequestScan: Memory allocation fail, can not send SCAN MSG to scan module\n"); + break; + } + + prScanReqV2->rMsgHdr.eMsgId = MID_P2P_SCN_SCAN_REQ_V2; + prScanReqV2->ucSeqNum = ++prScanReqInfo->ucSeqNumOfScnMsg; + prScanReqV2->ucBssIndex = ucBssIndex; + prScanReqV2->eScanType = prScanReqInfo->eScanType; + prScanReqV2->eScanChannel = prScanReqInfo->eChannelSet; + prScanReqV2->u2IELen = 0; + prScanReqV2->prSsid = (struct PARAM_SSID *) + ((unsigned long) prScanReqV2 + + sizeof(struct MSG_SCN_SCAN_REQ_V2)); + + /* Copy IE for Probe Request. */ + kalMemCopy(prScanReqV2->aucIE, + prScanReqInfo->aucIEBuf, prScanReqInfo->u4BufLength); + prScanReqV2->u2IELen = (uint16_t) prScanReqInfo->u4BufLength; + + prScanReqV2->u2ChannelDwellTime = + prScanReqInfo->u2PassiveDewellTime; + prScanReqV2->u2ChannelMinDwellTime = + SCAN_CHANNEL_DWELL_TIME_MIN_MSEC; + COPY_MAC_ADDR(prScanReqV2->aucBSSID, + "\xff\xff\xff\xff\xff\xff"); + + prScanReqV2->u2TimeoutValue = 0; + prScanReqV2->u2ProbeDelay = 0; + + switch (prScanReqInfo->eChannelSet) { + case SCAN_CHANNEL_SPECIFIED: + { + uint32_t u4Idx = 0; + struct RF_CHANNEL_INFO *prDomainInfo = + (struct RF_CHANNEL_INFO *) + prScanReqInfo->arScanChannelList; + + if (prScanReqInfo->ucNumChannelList + > MAXIMUM_OPERATION_CHANNEL_LIST) + prScanReqInfo->ucNumChannelList = + MAXIMUM_OPERATION_CHANNEL_LIST; + + for (u4Idx = 0; + u4Idx < prScanReqInfo->ucNumChannelList; + u4Idx++) { + prScanReqV2->arChnlInfoList + [u4Idx].ucChannelNum = + prDomainInfo->ucChannelNum; + prScanReqV2->arChnlInfoList + [u4Idx].eBand = + prDomainInfo->eBand; + prDomainInfo++; + } + + prScanReqV2->ucChannelListNum = + prScanReqInfo->ucNumChannelList; + } + /* fallthrough */ + case SCAN_CHANNEL_FULL: + /* fallthrough */ + case SCAN_CHANNEL_2G4: + /* fallthrough */ + case SCAN_CHANNEL_P2P_SOCIAL: + { + /* UINT_8 aucP2pSsid[] = P2P_WILDCARD_SSID; */ + struct PARAM_SSID *prParamSsid = + (struct PARAM_SSID *) NULL; + + prParamSsid = prScanReqV2->prSsid; + + for (prScanReqV2->ucSSIDNum = 0; + prScanReqV2->ucSSIDNum + < prScanReqInfo->ucSsidNum; + prScanReqV2->ucSSIDNum++) { + + COPY_SSID(prParamSsid->aucSsid, + prParamSsid->u4SsidLen, + prScanReqInfo->arSsidStruct + [prScanReqV2->ucSSIDNum] + .aucSsid, + prScanReqInfo->arSsidStruct + [prScanReqV2->ucSSIDNum] + .ucSsidLen); + + prParamSsid++; + } + + /* For compatible. (in FW?) need to check. */ + if (prScanReqV2->ucSSIDNum == 0) + prScanReqV2->ucSSIDType = + SCAN_REQ_SSID_P2P_WILDCARD; + else + prScanReqV2->ucSSIDType = + SCAN_REQ_SSID_SPECIFIED; + } + break; + default: + /* Currently there is no other scan channel set. */ + ASSERT(FALSE); + break; + } + + prScanReqInfo->fgIsScanRequest = TRUE; + + mboxSendMsg(prAdapter, + MBOX_ID_0, + (struct MSG_HDR *) prScanReqV2, + MSG_SEND_METHOD_BUF); + + } while (FALSE); +} /* p2pFuncRequestScan */ + +void p2pFuncCancelScan(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN struct P2P_SCAN_REQ_INFO *prScanInfo) +{ + struct MSG_SCN_SCAN_CANCEL *prScanCancelMsg = + (struct MSG_SCN_SCAN_CANCEL *) NULL; + + do { + ASSERT_BREAK((prAdapter != NULL) + && (prScanInfo != NULL)); + + if (!prScanInfo->fgIsScanRequest) + break; + + DBGLOG(P2P, TRACE, "P2P Cancel Scan\n"); + + prScanCancelMsg = (struct MSG_SCN_SCAN_CANCEL *) + cnmMemAlloc(prAdapter, RAM_TYPE_MSG, + sizeof(struct MSG_SCN_SCAN_CANCEL)); + if (!prScanCancelMsg) { + /* Buffer not enough, + * can not cancel scan request. + */ + DBGLOG(P2P, TRACE, + "Buffer not enough, can not cancel scan.\n"); + break; + } + kalMemZero(prScanCancelMsg, + sizeof(struct MSG_SCN_SCAN_CANCEL)); + + prScanCancelMsg->rMsgHdr.eMsgId = + MID_P2P_SCN_SCAN_CANCEL; + prScanCancelMsg->ucBssIndex = ucBssIndex; + prScanCancelMsg->ucSeqNum = + prScanInfo->ucSeqNumOfScnMsg++; + prScanCancelMsg->fgIsChannelExt = FALSE; + prScanInfo->fgIsScanRequest = FALSE; + + mboxSendMsg(prAdapter, + MBOX_ID_0, + (struct MSG_HDR *) prScanCancelMsg, + MSG_SEND_METHOD_BUF); + } while (FALSE); +} /* p2pFuncCancelScan */ + +void p2pFuncGCJoin(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prP2pBssInfo, + IN struct P2P_JOIN_INFO *prP2pJoinInfo) +{ + struct MSG_SAA_FSM_START *prJoinReqMsg = + (struct MSG_SAA_FSM_START *) NULL; + struct STA_RECORD *prStaRec = (struct STA_RECORD *) NULL; + struct BSS_DESC *prBssDesc = (struct BSS_DESC *) NULL; + + do { + ASSERT_BREAK((prAdapter != NULL) + && (prP2pBssInfo != NULL) + && (prP2pJoinInfo != NULL)); + + prBssDesc = prP2pJoinInfo->prTargetBssDesc; + if ((prBssDesc) == NULL) { + DBGLOG(P2P, ERROR, + "p2pFuncGCJoin: NO Target BSS Descriptor\n"); + ASSERT(FALSE); + break; + } + + if (prBssDesc->ucSSIDLen) { + COPY_SSID(prP2pBssInfo->aucSSID, + prP2pBssInfo->ucSSIDLen, + prBssDesc->aucSSID, + prBssDesc->ucSSIDLen); + } + + /* 2 <1> We are goin to connect to this BSS */ + prBssDesc->fgIsConnecting |= BIT(prP2pBssInfo->ucBssIndex); + + /* 2 <2> Setup corresponding STA_RECORD_T */ + prStaRec = bssCreateStaRecFromBssDesc(prAdapter, +#if CFG_P2P_CONNECT_ALL_BSS + (STA_TYPE_P2P_GO), +#else + (prBssDesc->fgIsP2PPresent + ? (STA_TYPE_P2P_GO) + : (STA_TYPE_LEGACY_AP)), +#endif + prP2pBssInfo->ucBssIndex, prBssDesc); + + if (prStaRec == NULL) { + DBGLOG(P2P, TRACE, "Create station record fail\n"); + ASSERT(FALSE); + break; + } + + prP2pJoinInfo->prTargetStaRec = prStaRec; + prP2pJoinInfo->fgIsJoinComplete = FALSE; + prP2pJoinInfo->u4BufLength = 0; + + /* 2 <2.1> Sync. to FW domain */ + cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); + + if (prP2pBssInfo->eConnectionState + == MEDIA_STATE_DISCONNECTED) { + prStaRec->fgIsReAssoc = FALSE; + prP2pJoinInfo->ucAvailableAuthTypes = + (uint8_t) AUTH_TYPE_OPEN_SYSTEM; + prStaRec->ucTxAuthAssocRetryLimit = + TX_AUTH_ASSOCI_RETRY_LIMIT; + } else { + DBGLOG(P2P, ERROR, + "JOIN INIT: Join Request when connected.\n"); + break; + } + + /* 2 <4> Use an appropriate Authentication Algorithm Number + * among the ucAvailableAuthTypes. + */ + if (prP2pJoinInfo->ucAvailableAuthTypes + & (uint8_t) AUTH_TYPE_OPEN_SYSTEM) { + + DBGLOG(P2P, TRACE, + "JOIN INIT: Try to do Authentication with AuthType == OPEN_SYSTEM.\n"); + + prP2pJoinInfo->ucAvailableAuthTypes &= + ~(uint8_t) AUTH_TYPE_OPEN_SYSTEM; + + prStaRec->ucAuthAlgNum = + (uint8_t) AUTH_ALGORITHM_NUM_OPEN_SYSTEM; + } else { + DBGLOG(P2P, ERROR, + "JOIN INIT: ucAvailableAuthTypes Error.\n"); + ASSERT(FALSE); + break; + } + + /* 4 <5> Overwrite Connection Setting + * for eConnectionPolicy == ANY (Used by Assoc Req) + */ + + /* 2 <5> Backup desired channel. */ + + /* 2 <6> Send a Msg to trigger SAA to start JOIN process. */ + prJoinReqMsg = (struct MSG_SAA_FSM_START *) + cnmMemAlloc(prAdapter, + RAM_TYPE_MSG, sizeof(struct MSG_SAA_FSM_START)); + + if (!prJoinReqMsg) { + DBGLOG(P2P, TRACE, "Allocation Join Message Fail\n"); + return; + } + + prJoinReqMsg->rMsgHdr.eMsgId = MID_P2P_SAA_FSM_START; + prJoinReqMsg->ucSeqNum = ++prP2pJoinInfo->ucSeqNumOfReqMsg; + prJoinReqMsg->prStaRec = prStaRec; + + /* TODO: Consider fragmentation info in station record. */ + + mboxSendMsg(prAdapter, + MBOX_ID_0, + (struct MSG_HDR *) prJoinReqMsg, + MSG_SEND_METHOD_BUF); + + } while (FALSE); + +} /* p2pFuncGCJoin */ + +/*---------------------------------------------------------------------------*/ +/*! + * @brief This function will update the contain of BSS_INFO_T + * for AIS network once the association was completed. + * + * @param[in] prStaRec Pointer to the STA_RECORD_T + * @param[in] prAssocRspSwRfb Pointer to SW RFB of ASSOC RESP FRAME. + * + * @return (none) + */ +/*---------------------------------------------------------------------------*/ +void +p2pFuncUpdateBssInfoForJOIN(IN struct ADAPTER *prAdapter, + IN struct BSS_DESC *prBssDesc, + IN struct STA_RECORD *prStaRec, + IN struct BSS_INFO *prP2pBssInfo, + IN struct SW_RFB *prAssocRspSwRfb) +{ + struct WLAN_ASSOC_RSP_FRAME *prAssocRspFrame = + (struct WLAN_ASSOC_RSP_FRAME *) NULL; + uint16_t u2IELength; + uint8_t *pucIE; + + DEBUGFUNC("p2pUpdateBssInfoForJOIN()"); + + do { + ASSERT_BREAK((prAdapter != NULL) + && (prStaRec != NULL) + && (prP2pBssInfo != NULL) + && (prAssocRspSwRfb != NULL)); + + prAssocRspFrame = (struct WLAN_ASSOC_RSP_FRAME *) + prAssocRspSwRfb->pvHeader; + + if (prBssDesc == NULL) { + /* Target BSS NULL. */ + DBGLOG(P2P, TRACE, "Target BSS NULL\n"); + break; + } + + DBGLOG(P2P, INFO, + "Update P2P_BSS_INFO_T and apply settings to MAC\n"); + + /* 3 <1> Update BSS_INFO_T from AIS_FSM_INFO_T + * or User Settings + */ + /* 4 <1.1> Setup Operation Mode */ + ASSERT_BREAK(prP2pBssInfo->eCurrentOPMode + == OP_MODE_INFRASTRUCTURE); + + /* 4 <1.2> Setup SSID */ + COPY_SSID(prP2pBssInfo->aucSSID, + prP2pBssInfo->ucSSIDLen, + prBssDesc->aucSSID, + prBssDesc->ucSSIDLen); + + /* 4 <1.3> Setup Channel, Band */ + prP2pBssInfo->ucPrimaryChannel = prBssDesc->ucChannelNum; + prP2pBssInfo->eBand = prBssDesc->eBand; + + /* 3 <2> Update BSS_INFO_T from STA_RECORD_T */ + /* 4 <2.1> Save current AP's STA_RECORD_T and current AID */ + prP2pBssInfo->prStaRecOfAP = prStaRec; + prP2pBssInfo->u2AssocId = prStaRec->u2AssocId; + + /* 4 <2.2> Setup Capability */ + /* Use AP's Cap Info as BSS Cap Info */ + prP2pBssInfo->u2CapInfo = prStaRec->u2CapInfo; + + if (prP2pBssInfo->u2CapInfo & CAP_INFO_SHORT_PREAMBLE) + prP2pBssInfo->fgIsShortPreambleAllowed = TRUE; + else + prP2pBssInfo->fgIsShortPreambleAllowed = FALSE; + + /* 4 <2.3> Setup PHY Attributes and + * Basic Rate Set/Operational Rate Set + */ + prP2pBssInfo->ucPhyTypeSet = prStaRec->ucDesiredPhyTypeSet; + + prP2pBssInfo->ucNonHTBasicPhyType = + prStaRec->ucNonHTBasicPhyType; + + prP2pBssInfo->u2OperationalRateSet = + prStaRec->u2OperationalRateSet; + prP2pBssInfo->u2BSSBasicRateSet = prStaRec->u2BSSBasicRateSet; + + nicTxUpdateBssDefaultRate(prP2pBssInfo); + + /* 3 <3> Update BSS_INFO_T from SW_RFB_T + * (Association Resp Frame) + */ + /* 4 <3.1> Setup BSSID */ + if (UNEQUAL_MAC_ADDR(prBssDesc->aucBSSID, + prAssocRspFrame->aucBSSID)) { + DBGLOG(P2P, WARN, "Assoc BSSID " MACSTR "\n", + MAC2STR(prAssocRspFrame->aucBSSID)); + COPY_MAC_ADDR(prP2pBssInfo->aucBSSID, + prBssDesc->aucBSSID); + } else + COPY_MAC_ADDR(prP2pBssInfo->aucBSSID, + prAssocRspFrame->aucBSSID); + + u2IELength = + (uint16_t) ((prAssocRspSwRfb->u2PacketLen - + prAssocRspSwRfb->u2HeaderLen) - + (OFFSET_OF(struct WLAN_ASSOC_RSP_FRAME, + aucInfoElem[0]) - + WLAN_MAC_MGMT_HEADER_LEN)); + + pucIE = prAssocRspFrame->aucInfoElem; + + /* 4 <3.2> Parse WMM and setup QBSS flag */ + /* Parse WMM related IEs and configure HW CRs accordingly */ + mqmProcessAssocRsp(prAdapter, + prAssocRspSwRfb, pucIE, u2IELength); + + prP2pBssInfo->fgIsQBSS = prStaRec->fgIsQoS; + + /* 3 <4> Update BSS_INFO_T from BSS_DESC_T */ + + prBssDesc->fgIsConnecting &= ~BIT(prP2pBssInfo->ucBssIndex); + prBssDesc->fgIsConnected |= BIT(prP2pBssInfo->ucBssIndex); + + /* 4 <4.1> Setup MIB for current BSS */ + prP2pBssInfo->u2BeaconInterval = prBssDesc->u2BeaconInterval; + /* NOTE: Defer ucDTIMPeriod updating to + * when beacon is received after connection + */ + prP2pBssInfo->ucDTIMPeriod = 0; + prP2pBssInfo->u2ATIMWindow = 0; + + prP2pBssInfo->ucBeaconTimeoutCount = + AIS_BEACON_TIMEOUT_COUNT_INFRA; + + /* 4 <4.2> Update HT information and set channel */ + /* Record HT related parameters in rStaRec and rBssInfo + * Note: it shall be called before nicUpdateBss() + */ + rlmProcessAssocRsp(prAdapter, + prAssocRspSwRfb, pucIE, u2IELength); + + /* 4 <4.3> Sync with firmware for BSS-INFO */ + nicUpdateBss(prAdapter, prP2pBssInfo->ucBssIndex); + + /* 4 <4.4> *DEFER OPERATION* + * nicPmIndicateBssConnected() will be invoked + * inside scanProcessBeaconAndProbeResp() + * after 1st beacon is received + */ + + } while (FALSE); +} /* end of p2pUpdateBssInfoForJOIN() */ + +uint32_t +p2pFunMgmtFrameTxDone(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN enum ENUM_TX_RESULT_CODE rTxDoneStatus) +{ + u_int8_t fgIsSuccess = FALSE; + + do { + ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); + + if (rTxDoneStatus != TX_RESULT_SUCCESS) { + DBGLOG(P2P, TRACE, + "Mgmt Frame TX Fail, Status:%d.\n", + rTxDoneStatus); + } else { + fgIsSuccess = TRUE; + DBGLOG(P2P, TRACE, "Mgmt Frame TX Done.\n"); + } + + kalP2PIndicateMgmtTxStatus(prAdapter->prGlueInfo, + prMsduInfo, fgIsSuccess); + + } while (FALSE); + + return WLAN_STATUS_SUCCESS; + +} /* p2pFunMgmtFrameTxDone */ + +const char * +p2pActionFrameToString(enum ENUM_P2P_ACTION_FRAME_TYPE eP2pAction) +{ + switch (eP2pAction) { + case P2P_GO_NEG_REQ: + return "GO_NEG_REQ"; + case P2P_GO_NEG_RESP: + return "GO_NEG_RESP"; + case P2P_GO_NEG_CONF: + return "GO_NEG_CONF"; + case P2P_INVITATION_REQ: + return "INVITATION_REQ"; + case P2P_INVITATION_RESP: + return "INVITATION_RESP"; + case P2P_DEV_DISC_REQ: + return "DEV_DISC_REQ"; + case P2P_DEV_DISC_RESP: + return "DEV_DISC_RESP"; + case P2P_PROV_DISC_REQ: + return "PROV_DISC_REQ"; + case P2P_PROV_DISC_RESP: + return "PROV_DISC_RESP"; + } + + return "UNKNOWN P2P Public Action"; +} + +const char * +paToString(int32_t u4PaAction) +{ + switch (u4PaAction) { + case WLAN_PA_20_40_BSS_COEX: + return "PA_20_40_BSS_COEX"; + case WLAN_PA_VENDOR_SPECIFIC: + return "PA_VENDOR_SPECIFIC"; + case WLAN_PA_GAS_INITIAL_REQ: + return "PA_GAS_INITIAL_REQ"; + case WLAN_PA_GAS_INITIAL_RESP: + return "PA_GAS_INITIAL_RESP"; + case WLAN_PA_GAS_COMEBACK_REQ: + return "PA_GAS_COMEBACK_REQ"; + case WLAN_PA_GAS_COMEBACK_RESP: + return "PA_GAS_COMEBACK_RESP"; + case WLAN_TDLS_DISCOVERY_RESPONSE: + return "TDLS_DISCOVERY_RESPONSE"; + } + + return "UNKNOWN Public Action"; +} + + +const char * +actionToString(int32_t u4WlanAction) +{ + switch (u4WlanAction) { + case WLAN_ACTION_SPECTRUM_MGMT: + return "SPECTRUM_MGMT"; + case WLAN_ACTION_QOS: + return "QOS"; + case WLAN_ACTION_DLS: + return "DLS"; + case WLAN_ACTION_BLOCK_ACK: + return "BLOCK_ACK"; + case WLAN_ACTION_PUBLIC: + return "PUBLIC"; + case WLAN_ACTION_RADIO_MEASUREMENT: + return "RADIO_MEASUREMENT"; + case WLAN_ACTION_FT: + return "FT"; + case WLAN_ACTION_HT: + return "HT"; + case WLAN_ACTION_SA_QUERY: + return "SA_QUERY"; + case WLAN_ACTION_PROTECTED_DUAL: + return "PROTECTED_DUAL"; + case WLAN_ACTION_WNM: + return "WNM"; + case WLAN_ACTION_UNPROTECTED_WNM: + return "UNPROTECTED_WNM"; + case WLAN_ACTION_TDLS: + return "TDLS"; + case WLAN_ACTION_SELF_PROTECTED: + return "SELF_PROTECTED"; + case WLAN_ACTION_WMM: + return "WMM"; + case WLAN_ACTION_VENDOR_SPECIFIC: + return "VENDOR_SPECIFIC"; + } + + return "UNKNOWN Action Frame"; +} + + +enum ENUM_P2P_CONNECT_STATE +p2pFuncTagActionActionP2PFrame(IN struct MSDU_INFO *prMgmtTxMsdu, + IN struct WLAN_ACTION_FRAME *prActFrame, + IN uint8_t ucP2pAction, IN uint64_t u8Cookie) +{ + DBGLOG(P2P, INFO, + "Found P2P_%s, SA: " MACSTR + " - DA: " MACSTR ", cookie: 0x%llx, SeqNO: %d\n", + p2pActionFrameToString(ucP2pAction), + MAC2STR(prActFrame->aucSrcAddr), + MAC2STR(prActFrame->aucDestAddr), + u8Cookie, + prMgmtTxMsdu->ucTxSeqNum); + return ucP2pAction + 1; +} + +enum ENUM_P2P_CONNECT_STATE +p2pFuncTagActionActionFrame(IN struct MSDU_INFO *prMgmtTxMsdu, + IN struct WLAN_ACTION_FRAME *prActFrame, + IN uint8_t ucAction, IN uint64_t u8Cookie) +{ + uint8_t *pucVendor = NULL; + enum ENUM_P2P_CONNECT_STATE eCNNState = P2P_CNN_NORMAL; + + DBGLOG(P2P, INFO, + "Found WLAN_%s, SA: " MACSTR + " - DA: " MACSTR ", cookie: 0x%llx, SeqNo: %d\n", + paToString(ucAction), + MAC2STR(prActFrame->aucSrcAddr), + MAC2STR(prActFrame->aucDestAddr), + u8Cookie, + prMgmtTxMsdu->ucTxSeqNum); + + if (ucAction != WLAN_PA_VENDOR_SPECIFIC) + return P2P_CNN_NORMAL; + + pucVendor = (uint8_t *)prActFrame + 26; + if (*(pucVendor + 0) == 0x50 && + *(pucVendor + 1) == 0x6f && + *(pucVendor + 2) == 0x9a) { + if (*(pucVendor + 3) == 0x09) + /* found p2p IE */ + eCNNState = p2pFuncTagActionActionP2PFrame(prMgmtTxMsdu, + prActFrame, *(pucVendor + 4), u8Cookie); + else if (*(pucVendor + 3) == 0x0a) + /* found WFD IE */ + DBGLOG(P2P, INFO, "Found WFD IE, SA: " MACSTR + " - DA: " MACSTR "\n", + MAC2STR(prActFrame->aucSrcAddr), + MAC2STR(prActFrame->aucDestAddr)); + else + DBGLOG(P2P, INFO, + "Found Other vendor 0x%x, SA: " MACSTR + " - DA: " MACSTR "\n", + *(pucVendor + 3), + MAC2STR(prActFrame->aucSrcAddr), + MAC2STR(prActFrame->aucDestAddr)); + } + return eCNNState; +} + +enum ENUM_P2P_CONNECT_STATE +p2pFuncTagActionCategoryFrame(IN struct MSDU_INFO *prMgmtTxMsdu, + struct WLAN_ACTION_FRAME *prActFrame, + IN uint8_t ucCategory, + IN uint64_t u8Cookie) +{ + uint8_t ucAction = 0; + enum ENUM_P2P_CONNECT_STATE eCNNState = P2P_CNN_NORMAL; + + DBGLOG(P2P, TRACE, + "Found WLAN_ACTION_%s, SA: " MACSTR + " BSSID: " MACSTR + " DA: " MACSTR ", u8Cookie: 0x%llx, SeqNO: %d\n", + actionToString(ucCategory), + MAC2STR(prActFrame->aucSrcAddr), + MAC2STR(prActFrame->aucBSSID), + MAC2STR(prActFrame->aucDestAddr), + u8Cookie, + prMgmtTxMsdu->ucTxSeqNum); + + if (ucCategory == WLAN_ACTION_PUBLIC) { + ucAction = prActFrame->ucAction; + eCNNState = p2pFuncTagActionActionFrame(prMgmtTxMsdu, + prActFrame, ucAction, u8Cookie); + } + return eCNNState; +} + +void p2pProcessActionResponse(IN struct ADAPTER *prAdapter, + enum ENUM_P2P_ACTION_FRAME_TYPE eType) +{ + u_int8_t fgIdle = FALSE; + + if (!prAdapter || !prAdapter->prP2pInfo) + return; + + switch (prAdapter->prP2pInfo->eConnState) { + case P2P_CNN_GO_NEG_REQ: + if (eType == P2P_GO_NEG_RESP) + fgIdle = TRUE; + break; + case P2P_CNN_GO_NEG_RESP: + if (eType == P2P_GO_NEG_CONF || eType == P2P_GO_NEG_REQ) + fgIdle = TRUE; + break; + case P2P_CNN_INVITATION_REQ: + if (eType == P2P_INVITATION_RESP) + fgIdle = TRUE; + break; + case P2P_CNN_DEV_DISC_REQ: + if (eType == P2P_DEV_DISC_RESP) + fgIdle = TRUE; + break; + case P2P_CNN_PROV_DISC_REQ: + if (eType == P2P_PROV_DISC_RESP) + fgIdle = TRUE; + break; + default: + break; + } + + DBGLOG(P2P, INFO, "eConnState: %d, eType: %d\n", + prAdapter->prP2pInfo->eConnState, eType); + + if (fgIdle) + prAdapter->prP2pInfo->eConnState = P2P_CNN_NORMAL; +} + +/* + * used to debug p2p mgmt frame: + * GO Nego Req + * GO Nego Res + * GO Nego Confirm + * GO Invite Req + * GO Invite Res + * Device Discoverability Req + * Device Discoverability Res + * Provision Discovery Req + * Provision Discovery Res + */ +enum ENUM_P2P_CONNECT_STATE +p2pFuncTagMgmtFrame(IN struct MSDU_INFO *prMgmtTxMsdu, + IN uint64_t u8Cookie) +{ + /* P_MSDU_INFO_T prTxMsduInfo = (P_MSDU_INFO_T)NULL; */ + struct WLAN_MAC_HEADER *prWlanHdr = (struct WLAN_MAC_HEADER *) NULL; + struct WLAN_BEACON_FRAME *prProbRspHdr = + (struct WLAN_BEACON_FRAME *)NULL; + uint16_t u2TxFrameCtrl; + struct WLAN_ACTION_FRAME *prActFrame; + uint8_t ucCategory; + enum ENUM_P2P_CONNECT_STATE eCNNState = P2P_CNN_NORMAL; + + prWlanHdr = (struct WLAN_MAC_HEADER *) + ((unsigned long) prMgmtTxMsdu->prPacket + + MAC_TX_RESERVED_FIELD); + /* + * mgmt frame MASK_FC_TYPE = 0 + * use MASK_FRAME_TYPE is oK for frame type/subtype judge + */ + u2TxFrameCtrl = prWlanHdr->u2FrameCtrl & MASK_FRAME_TYPE; + + switch (u2TxFrameCtrl) { + case MAC_FRAME_PROBE_RSP: + prProbRspHdr = (struct WLAN_BEACON_FRAME *) prWlanHdr; + DBGLOG(P2P, INFO, + "TX Probe Response, SA: " MACSTR + " BSSID: " MACSTR + " DA: " MACSTR ", cookie: 0x%llx, seqNo: %d\n", + MAC2STR(prProbRspHdr->aucSrcAddr), + MAC2STR(prProbRspHdr->aucBSSID), + MAC2STR(prProbRspHdr->aucDestAddr), + u8Cookie, + prMgmtTxMsdu->ucTxSeqNum); + + break; + + case MAC_FRAME_ACTION: + prActFrame = (struct WLAN_ACTION_FRAME *)prWlanHdr; + ucCategory = prActFrame->ucCategory; + eCNNState = p2pFuncTagActionCategoryFrame(prMgmtTxMsdu, + prActFrame, ucCategory, u8Cookie); + + break; + default: + DBGLOG(P2P, INFO, + "Untagged frame type: 0x%x, A1: " MACSTR + ", A2: " MACSTR + ", A3: " MACSTR " seqNo: %d\n", + u2TxFrameCtrl, + MAC2STR(prWlanHdr->aucAddr1), + MAC2STR(prWlanHdr->aucAddr2), + MAC2STR(prWlanHdr->aucAddr3), + prMgmtTxMsdu->ucTxSeqNum); + break; + } + return eCNNState; +} + +uint32_t +p2pFuncTxMgmtFrame(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN struct MSDU_INFO *prMgmtTxMsdu, + IN u_int8_t fgNonCckRate) +{ + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + /* P_MSDU_INFO_T prTxMsduInfo = (P_MSDU_INFO_T)NULL; */ + struct WLAN_MAC_HEADER *prWlanHdr = (struct WLAN_MAC_HEADER *) NULL; + struct STA_RECORD *prStaRec = (struct STA_RECORD *) NULL; + uint8_t ucRetryLimit = 30; /* TX_DESC_TX_COUNT_NO_LIMIT; */ + u_int8_t fgDrop = FALSE; + struct BSS_INFO *prBssInfo; + uint64_t *pu8GlCookie = (uint64_t *) NULL; + uint64_t u8GlCookie; + enum ENUM_P2P_CONNECT_STATE eConnState = P2P_CNN_NORMAL; + + do { + ASSERT_BREAK(prAdapter != NULL); + + /* Drop this frame if BSS inactive */ + if (!IS_NET_ACTIVE(prAdapter, ucBssIndex)) { + p2pDevFsmRunEventMgmtFrameTxDone(prAdapter, + prMgmtTxMsdu, TX_RESULT_INACTIVE_BSS); + cnmMgtPktFree(prAdapter, prMgmtTxMsdu); + fgDrop = TRUE; + break; + } + pu8GlCookie = + (uint64_t *) ((unsigned long) prMgmtTxMsdu->prPacket + + (unsigned long) prMgmtTxMsdu->u2FrameLength + + MAC_TX_RESERVED_FIELD); + + u8GlCookie = *pu8GlCookie; + + prWlanHdr = (struct WLAN_MAC_HEADER *) + ((unsigned long) prMgmtTxMsdu->prPacket + + MAC_TX_RESERVED_FIELD); + prStaRec = cnmGetStaRecByAddress(prAdapter, + ucBssIndex, prWlanHdr->aucAddr1); + /* prMgmtTxMsdu->ucBssIndex = ucBssIndex; */ + + switch (prWlanHdr->u2FrameCtrl & MASK_FRAME_TYPE) { + case MAC_FRAME_PROBE_RSP: + DBGLOG(P2P, TRACE, "TX Probe Resposne Frame\n"); + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + ucBssIndex); + if ((!nicTxIsMgmtResourceEnough(prAdapter)) + || (prBssInfo->fgIsNetAbsent)) { + DBGLOG(P2P, INFO, + "Drop Tx probe response due to resource issue\n"); + fgDrop = TRUE; + + break; + } + prMgmtTxMsdu->ucStaRecIndex = + (prStaRec != NULL) + ? (prStaRec->ucIndex) : (STA_REC_INDEX_NOT_FOUND); + DBGLOG(P2P, TRACE, + "Dump probe response content from supplicant.\n"); + if (aucDebugModule[DBG_P2P_IDX] & DBG_CLASS_TRACE) { + dumpMemory8((uint8_t *) prMgmtTxMsdu->prPacket, + (uint32_t) prMgmtTxMsdu->u2FrameLength); + } + + /* Modifiy Lie time to 100 mS due + * to the STA only wait 30-50mS + */ + /* and AP do not need send it after STA left */ + nicTxSetPktLifeTime(prMgmtTxMsdu, 100); + prMgmtTxMsdu = p2pFuncProcessP2pProbeRsp(prAdapter, + ucBssIndex, prMgmtTxMsdu); + + /* + * Not check prMsduInfo sanity + * as p2pFuncProcessP2pProbeRsp will always + * return a MsduInfo + */ + pu8GlCookie = + (uint64_t *) ((unsigned long) + prMgmtTxMsdu->prPacket + + (unsigned long) + prMgmtTxMsdu->u2FrameLength + + MAC_TX_RESERVED_FIELD); + /* Restore cookie as it will be corrupted + * in p2pFuncProcessP2pProbeRsp + */ + *pu8GlCookie = u8GlCookie; + ucRetryLimit = 6; + DBGLOG(P2P, TRACE, + "Dump probe response content to FW.\n"); + if (aucDebugModule[DBG_P2P_IDX] & DBG_CLASS_TRACE) { + dumpMemory8((uint8_t *) prMgmtTxMsdu->prPacket, + (uint32_t) prMgmtTxMsdu->u2FrameLength); + } + break; + default: + prMgmtTxMsdu->ucBssIndex = ucBssIndex; + break; + } + + if (fgDrop) { + /* Drop this frame */ + p2pDevFsmRunEventMgmtFrameTxDone(prAdapter, + prMgmtTxMsdu, TX_RESULT_DROPPED_IN_DRIVER); + cnmMgtPktFree(prAdapter, prMgmtTxMsdu); + + break; + } + + TX_SET_MMPDU(prAdapter, + prMgmtTxMsdu, + prMgmtTxMsdu->ucBssIndex, + (prStaRec != NULL) + ? (prStaRec->ucIndex) : (STA_REC_INDEX_NOT_FOUND), + WLAN_MAC_MGMT_HEADER_LEN, + prMgmtTxMsdu->u2FrameLength, + p2pDevFsmRunEventMgmtFrameTxDone, + MSDU_RATE_MODE_AUTO); + + nicTxSetPktRetryLimit(prMgmtTxMsdu, ucRetryLimit); + + eConnState = p2pFuncTagMgmtFrame(prMgmtTxMsdu, u8GlCookie); + + if (p2pFuncNeedWaitRsp(prAdapter, + prAdapter->prP2pInfo->eConnState)) + prAdapter->prP2pInfo->eConnState = eConnState; + + /* Bufferable MMPDUs are suggested to be queued */ + /* when GC is sleeping according to SPEC, */ + /* instead of being sent to ALTX Q. */ + + /* GO discoverability REQ needs to be sent to GC */ + /* when GC is awake due to P2P-6.1.10 cert fail */ + + if (!p2pFuncIsBufferableMMPDU(prAdapter, + eConnState, prMgmtTxMsdu)) + nicTxConfigPktControlFlag(prMgmtTxMsdu, + MSDU_CONTROL_FLAG_FORCE_TX, TRUE); + + /* Optimization for timing critical p2p frames */ + if (p2pFuncIsTimingCriticalFrames(prAdapter, + eConnState, prMgmtTxMsdu)) { + nicTxSetPktLifeTime(prMgmtTxMsdu, 100); + nicTxSetPktRetryLimit(prMgmtTxMsdu, + TX_DESC_TX_COUNT_NO_LIMIT); + nicTxSetForceRts(prMgmtTxMsdu, TRUE); + } + + nicTxEnqueueMsdu(prAdapter, prMgmtTxMsdu); + + + } while (FALSE); + + return rWlanStatus; +} /* p2pFuncTxMgmtFrame */ + +void p2pFuncStopComplete(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prP2pBssInfo) +{ + do { + ASSERT_BREAK((prAdapter != NULL) && (prP2pBssInfo != NULL)); + + DBGLOG(P2P, TRACE, "p2pFuncStopComplete\n"); + + /* GO: It would stop Beacon TX. + * GC: Stop all BSS related PS function. + */ + nicPmIndicateBssAbort(prAdapter, prP2pBssInfo->ucBssIndex); + /* Reset RLM related field of BSSINFO. */ + rlmBssAborted(prAdapter, prP2pBssInfo); + + UNSET_NET_ACTIVE(prAdapter, prP2pBssInfo->ucBssIndex); + nicDeactivateNetwork(prAdapter, prP2pBssInfo->ucBssIndex); + /* Release CNM channel */ + nicUpdateBss(prAdapter, prP2pBssInfo->ucBssIndex); + + /* Reset current OPMode */ + prP2pBssInfo->eCurrentOPMode = OP_MODE_INFRASTRUCTURE; + + /* Point StaRecOfAP to NULL when GC role stop Complete */ + prP2pBssInfo->prStaRecOfAP = NULL; + + kalP2pNotifyStopApComplete(prAdapter, + prP2pBssInfo->u4PrivateData); + } while (FALSE); + +} /* p2pFuncStopComplete */ + +/*---------------------------------------------------------------------------*/ +/*! + * @brief This function will start a P2P Group Owner and send Beacon Frames. + * + * @param (none) + * + * @return (none) + */ +/*---------------------------------------------------------------------------*/ +void +p2pFuncStartGO(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo, + IN struct P2P_CONNECTION_REQ_INFO *prP2pConnReqInfo, + IN struct P2P_CHNL_REQ_INFO *prP2pChnlReqInfo) +{ +#if (CFG_SUPPORT_DFS_MASTER == 1) + struct CMD_RDD_ON_OFF_CTRL *prCmdRddOnOffCtrl; +#endif + + do { + ASSERT_BREAK((prAdapter != NULL) && (prBssInfo != NULL)); + + if (prBssInfo->ucBssIndex >= prAdapter->ucHwBssIdNum) { + DBGLOG(P2P, ERROR, + "P2P BSS exceed the number of P2P interface number."); + ASSERT(FALSE); + break; + } + + DBGLOG(P2P, TRACE, "p2pFuncStartGO:\n"); + +#if (CFG_SUPPORT_DFS_MASTER == 1) + prCmdRddOnOffCtrl = (struct CMD_RDD_ON_OFF_CTRL *) + cnmMemAlloc(prAdapter, RAM_TYPE_MSG, + sizeof(*prCmdRddOnOffCtrl)); + + if (!prCmdRddOnOffCtrl) { + break; + } + + prCmdRddOnOffCtrl->ucDfsCtrl = RDD_START_TXQ; + + /* + * FIX ME: Mobile driver can't get correct band. + * There is only 5G in DFS channel, + * which is on band_0. So it assigned to ENUM_BAND_0 + * as temp solution. + * Remember to fix it when driver could get + * the correct band from firmware. + */ + prCmdRddOnOffCtrl->ucRddIdx = ENUM_BAND_0; + + DBGLOG(P2P, INFO, + "p2pFuncStartGO: Start TXQ - DFS ctrl: %.d\n", + prCmdRddOnOffCtrl->ucDfsCtrl); + + wlanSendSetQueryCmd(prAdapter, + CMD_ID_RDD_ON_OFF_CTRL, + TRUE, + FALSE, + FALSE, + NULL, + NULL, + sizeof(*prCmdRddOnOffCtrl), + (uint8_t *) prCmdRddOnOffCtrl, NULL, 0); + + cnmMemFree(prAdapter, prCmdRddOnOffCtrl); +#endif + + /* Re-start AP mode. */ + p2pFuncSwitchOPMode(prAdapter, + prBssInfo, prBssInfo->eIntendOPMode, FALSE); + + prBssInfo->eIntendOPMode = OP_MODE_NUM; + + /* 4 <1.1> Assign SSID */ + COPY_SSID(prBssInfo->aucSSID, + prBssInfo->ucSSIDLen, + prP2pConnReqInfo->rSsidStruct.aucSsid, + prP2pConnReqInfo->rSsidStruct.ucSsidLen); + + DBGLOG(P2P, TRACE, "GO SSID:%s\n", HIDE(prBssInfo->aucSSID)); + + /* 4 <1.2> Clear current AP's STA_RECORD_T and current AID */ + prBssInfo->prStaRecOfAP = (struct STA_RECORD *) NULL; + prBssInfo->u2AssocId = 0; + + /* 4 <1.3> Setup Channel, Band and Phy Attributes */ + prBssInfo->ucPrimaryChannel = prP2pChnlReqInfo->ucReqChnlNum; + prBssInfo->eBand = prP2pChnlReqInfo->eBand; + prBssInfo->eBssSCO = prP2pChnlReqInfo->eChnlSco; + + DBGLOG(P2P, TRACE, + "GO Channel:%d\n", + prBssInfo->ucPrimaryChannel); + + if (prBssInfo->eBand == BAND_5G) { + /* Depend on eBand */ + prBssInfo->ucPhyTypeSet |= PHY_TYPE_SET_802_11A; + /* Depend on eCurrentOPMode and ucPhyTypeSet */ + prBssInfo->ucConfigAdHocAPMode = AP_MODE_11A; + } else if (prP2pConnReqInfo->eConnRequest + == P2P_CONNECTION_TYPE_PURE_AP) { + prBssInfo->ucPhyTypeSet |= PHY_TYPE_SET_802_11BG; + /* Depend on eCurrentOPMode and ucPhyTypeSet */ + prBssInfo->ucConfigAdHocAPMode = AP_MODE_MIXED_11BG; + } else { + ASSERT(prP2pConnReqInfo->eConnRequest + == P2P_CONNECTION_TYPE_GO); + prBssInfo->ucPhyTypeSet |= PHY_TYPE_SET_802_11G; + /* Depend on eCurrentOPMode and ucPhyTypeSet */ + prBssInfo->ucConfigAdHocAPMode = AP_MODE_11G_P2P; + } + + /* Overwrite BSS PHY type set by Feature Options */ + bssDetermineApBssInfoPhyTypeSet(prAdapter, + (prP2pConnReqInfo->eConnRequest == + P2P_CONNECTION_TYPE_PURE_AP) ? TRUE : FALSE, prBssInfo); + + DBGLOG(P2P, TRACE, "Phy type: 0x%x\n", prBssInfo->ucPhyTypeSet); + + prBssInfo->ucNonHTBasicPhyType = (uint8_t) + rNonHTApModeAttributes + [prBssInfo->ucConfigAdHocAPMode] + .ePhyTypeIndex; + prBssInfo->u2BSSBasicRateSet = + rNonHTApModeAttributes + [prBssInfo->ucConfigAdHocAPMode] + .u2BSSBasicRateSet; + prBssInfo->u2OperationalRateSet = + rNonHTPhyAttributes + [prBssInfo->ucNonHTBasicPhyType] + .u2SupportedRateSet; + + if (prBssInfo->ucAllSupportedRatesLen == 0) { + rateGetDataRatesFromRateSet( + prBssInfo->u2OperationalRateSet, + prBssInfo->u2BSSBasicRateSet, + prBssInfo->aucAllSupportedRates, + &prBssInfo->ucAllSupportedRatesLen); + } + /* 4 <1.5> Setup MIB for current BSS */ + prBssInfo->u2ATIMWindow = 0; + prBssInfo->ucBeaconTimeoutCount = 0; + + /* 3 <2> Update BSS_INFO_T common part */ +#if CFG_SUPPORT_AAA + prBssInfo->fgIsProtection = FALSE; + if (prP2pConnReqInfo->eConnRequest == P2P_CONNECTION_TYPE_GO) { + /* Always enable protection at P2P GO */ + prBssInfo->fgIsProtection = TRUE; + } else { + ASSERT(prP2pConnReqInfo->eConnRequest + == P2P_CONNECTION_TYPE_PURE_AP); + if (kalP2PGetCipher(prAdapter->prGlueInfo, + (uint8_t) prBssInfo->u4PrivateData)) + prBssInfo->fgIsProtection = TRUE; + } + + bssInitForAP(prAdapter, prBssInfo, TRUE); + +#if 0 + if (prBssInfo->ucBMCWlanIndex >= WTBL_SIZE) { + prBssInfo->ucBMCWlanIndex = + secPrivacySeekForBcEntry(prAdapter, + prBssInfo->ucBssIndex, + prBssInfo->aucBSSID, 0xff, + CIPHER_SUITE_NONE, 0xff); + } +#endif + nicQmUpdateWmmParms(prAdapter, prBssInfo->ucBssIndex); +#endif /* CFG_SUPPORT_AAA */ + + /* 3 <3> Set MAC HW */ + /* 4 <3.1> Setup channel and bandwidth */ + rlmBssInitForAPandIbss(prAdapter, prBssInfo); + + /* 4 <3.2> Reset HW TSF Update Mode and Beacon Mode */ + nicUpdateBss(prAdapter, prBssInfo->ucBssIndex); + + /* 4 <3.3> Update Beacon again + * for network phy type confirmed. + */ + bssUpdateBeaconContent(prAdapter, prBssInfo->ucBssIndex); + + /* 4 <3.4> Setup BSSID */ + nicPmIndicateBssCreated(prAdapter, prBssInfo->ucBssIndex); + + } while (FALSE); +} /* p2pFuncStartGO() */ + +void p2pFuncStopGO(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prP2pBssInfo) +{ + uint32_t u4ClientCount = 0; + + do { + ASSERT_BREAK((prAdapter != NULL) && (prP2pBssInfo != NULL)); + + DBGLOG(P2P, TRACE, "p2pFuncStopGO\n"); + + u4ClientCount = bssGetClientCount(prAdapter, prP2pBssInfo); + + if ((prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) + && (prP2pBssInfo->eIntendOPMode == OP_MODE_NUM)) { + /* AP is created, Beacon Updated. */ + p2pFuncDissolve(prAdapter, + prP2pBssInfo, TRUE, + REASON_CODE_DEAUTH_LEAVING_BSS); + prP2pBssInfo->eIntendOPMode = OP_MODE_P2P_DEVICE; + } + + /* Do not Deactivate Network if any Client existed, + * we'll deactive it after Deauth Tx done + */ + if (u4ClientCount == 0) { + DBGLOG(P2P, INFO, + "No client! Deactive GO immediately.\n"); + p2pChangeMediaState(prAdapter, + prP2pBssInfo, MEDIA_STATE_DISCONNECTED); + p2pFuncStopComplete(prAdapter, prP2pBssInfo); + } + + } while (FALSE); + +} /* p2pFuncStopGO */ + +uint32_t p2pFuncRoleToBssIdx(IN struct ADAPTER *prAdapter, + IN uint8_t ucRoleIdx, OUT uint8_t *pucBssIdx) +{ + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + + do { + ASSERT_BREAK((prAdapter != NULL) && (pucBssIdx != NULL)); + + if (ucRoleIdx >= BSS_P2P_NUM) { + rWlanStatus = WLAN_STATUS_FAILURE; + break; + } + if (!prAdapter->rWifiVar.aprP2pRoleFsmInfo[ucRoleIdx]) { + DBGLOG(P2P, WARN, + "%s, invalid aprP2pRoleFsmInfo, ignore\n", + __func__); + rWlanStatus = WLAN_STATUS_FAILURE; + } else + *pucBssIdx = prAdapter->rWifiVar + .aprP2pRoleFsmInfo[ucRoleIdx]->ucBssIndex; + + } while (FALSE); + + return rWlanStatus; +} /* p2pFuncRoleToBssIdx */ + +struct P2P_ROLE_FSM_INFO *p2pFuncGetRoleByBssIdx(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) +{ + int32_t i = 0; + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *)NULL; + + do { + ASSERT_BREAK((prAdapter != NULL)); + + for (i = 0 ; i < BSS_P2P_NUM; i++) { + if (!prAdapter->rWifiVar.aprP2pRoleFsmInfo[i]) + continue; + + if (prAdapter->rWifiVar.aprP2pRoleFsmInfo[i]->ucBssIndex + == ucBssIndex) + break; + } + if (i < BSS_P2P_NUM) + prP2pRoleFsmInfo = + prAdapter->rWifiVar.aprP2pRoleFsmInfo[i]; + + } while (FALSE); + + return prP2pRoleFsmInfo; +} + + +void +p2pFuncSwitchOPMode(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prP2pBssInfo, + IN enum ENUM_OP_MODE eOpMode, + IN u_int8_t fgSyncToFW) +{ + do { + ASSERT_BREAK((prAdapter != NULL) + && (prP2pBssInfo != NULL) + && (eOpMode < OP_MODE_NUM)); + + if (prP2pBssInfo->eCurrentOPMode != eOpMode) { + DBGLOG(P2P, TRACE, + "p2pFuncSwitchOPMode: Switch to from %d, to %d.\n", + prP2pBssInfo->eCurrentOPMode, eOpMode); + + switch (prP2pBssInfo->eCurrentOPMode) { + case OP_MODE_ACCESS_POINT: + /* p2pFuncDissolve will be done + * in p2pFuncStopGO(). + */ + /* p2pFuncDissolve(prAdapter, + * prP2pBssInfo, TRUE, + * REASON_CODE_DEAUTH_LEAVING_BSS); + */ + if (prP2pBssInfo->eIntendOPMode + != OP_MODE_P2P_DEVICE) { + p2pFuncStopGO(prAdapter, prP2pBssInfo); + + SET_NET_PWR_STATE_IDLE(prAdapter, + prP2pBssInfo->ucBssIndex); + } + break; + default: + break; + } + + prP2pBssInfo->eIntendOPMode = eOpMode; + + /* The state is in disconnecting and + * can not change any BSS status + */ + if (IS_NET_PWR_STATE_IDLE(prAdapter, + prP2pBssInfo->ucBssIndex) && + IS_NET_ACTIVE(prAdapter, + prP2pBssInfo->ucBssIndex)) { + DBGLOG(P2P, TRACE, + "under deauth procedure, Quit.\n"); + break; + } + + prP2pBssInfo->eCurrentOPMode = eOpMode; + switch (eOpMode) { + case OP_MODE_INFRASTRUCTURE: + DBGLOG(P2P, TRACE, + "p2pFuncSwitchOPMode: Switch to Client.\n"); + /* fall through */ + case OP_MODE_ACCESS_POINT: + /* Change interface address. */ + if (eOpMode == OP_MODE_ACCESS_POINT) { + DBGLOG(P2P, TRACE, + "p2pFuncSwitchOPMode: Switch to AP.\n"); + prP2pBssInfo->ucSSIDLen = 0; + } + +#if CFG_DUAL_P2PLIKE_INTERFACE + /*avoid ap1 Bss have diff A2 & A3, */ + /*ToDo : fix for P2P case*/ + +#else + COPY_MAC_ADDR(prP2pBssInfo->aucOwnMacAddr, + prAdapter->rWifiVar + .aucInterfaceAddress[ + prP2pBssInfo->u4PrivateData]); + COPY_MAC_ADDR(prP2pBssInfo->aucBSSID, + prAdapter->rWifiVar + .aucInterfaceAddress[ + prP2pBssInfo->u4PrivateData]); +#endif + break; + case OP_MODE_P2P_DEVICE: + { + /* Change device address. */ + DBGLOG(P2P, TRACE, + "p2pFuncSwitchOPMode: Switch back to P2P Device.\n"); + + p2pChangeMediaState(prAdapter, + prP2pBssInfo, + MEDIA_STATE_DISCONNECTED); + + COPY_MAC_ADDR( + prP2pBssInfo->aucOwnMacAddr, + prAdapter->rWifiVar + .aucDeviceAddress); + COPY_MAC_ADDR( + prP2pBssInfo->aucBSSID, + prAdapter->rWifiVar + .aucDeviceAddress); + + } + break; + default: + ASSERT(FALSE); + break; + } + + if (1) { + struct P2P_DISCONNECT_INFO rP2PDisInfo; + + rP2PDisInfo.ucRole = 2; + wlanSendSetQueryCmd(prAdapter, + CMD_ID_P2P_ABORT, + TRUE, + FALSE, + FALSE, + NULL, + NULL, + sizeof(struct P2P_DISCONNECT_INFO), + (uint8_t *) &rP2PDisInfo, NULL, 0); + } + + DBGLOG(P2P, TRACE, + "The device address is changed to " MACSTR "\n", + MAC2STR(prP2pBssInfo->aucOwnMacAddr)); + DBGLOG(P2P, TRACE, + "The BSSID is changed to " MACSTR "\n", + MAC2STR(prP2pBssInfo->aucBSSID)); + + /* Update BSS INFO to FW. */ + if ((fgSyncToFW) && (eOpMode != OP_MODE_ACCESS_POINT)) + nicUpdateBss(prAdapter, + prP2pBssInfo->ucBssIndex); + } else if (prP2pBssInfo->eCurrentOPMode == eOpMode && + eOpMode == OP_MODE_INFRASTRUCTURE) { + /* + * Sometimes the interface is changed from P2P_CLIENT + * to STATION, but GC's connection flow is still in + * processing. We must force stop previous connection + * request to avoid unexpected behavior. + */ + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *) NULL; + struct P2P_CONNECTION_REQ_INFO *prConnReqInfo = + (struct P2P_CONNECTION_REQ_INFO *) NULL; + + prP2pRoleFsmInfo = P2P_ROLE_INDEX_2_ROLE_FSM_INFO( + prAdapter, prP2pBssInfo->u4PrivateData); + if (prP2pRoleFsmInfo == NULL) + break; + + prConnReqInfo = &(prP2pRoleFsmInfo->rConnReqInfo); + if (prConnReqInfo == NULL) + break; + + if (prConnReqInfo->eConnRequest == + P2P_CONNECTION_TYPE_GC) { + log_dbg(P2P, INFO, "Force stop connection request since mode switch.\n"); + prConnReqInfo->eConnRequest = + P2P_CONNECTION_TYPE_IDLE; + p2pRoleFsmRunEventAbort(prAdapter, + prP2pRoleFsmInfo); + } + } + + } while (FALSE); +} /* p2pFuncSwitchOPMode */ + +/*---------------------------------------------------------------------------*/ +/*! + * \brief This function is to inform CNM that channel privilege + * has been released + * + * \param[in] prAdapter Pointer of ADAPTER_T + * + * \return none + */ +/*---------------------------------------------------------------------------*/ +void p2pFuncReleaseCh(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIdx, + IN struct P2P_CHNL_REQ_INFO *prChnlReqInfo) +{ + struct MSG_CH_ABORT *prMsgChRelease = (struct MSG_CH_ABORT *) NULL; + + DEBUGFUNC("p2pFuncReleaseCh()"); + + do { + ASSERT_BREAK((prAdapter != NULL) && (prChnlReqInfo != NULL)); + + if (!prChnlReqInfo->fgIsChannelRequested) + break; + DBGLOG(P2P, TRACE, "P2P Release Channel\n"); + prChnlReqInfo->fgIsChannelRequested = FALSE; + + /* 1. return channel privilege to CNM immediately */ + prMsgChRelease = (struct MSG_CH_ABORT *) + cnmMemAlloc(prAdapter, + RAM_TYPE_MSG, sizeof(struct MSG_CH_ABORT)); + if (!prMsgChRelease) { + break; + } + + prMsgChRelease->rMsgHdr.eMsgId = MID_MNY_CNM_CH_ABORT; + prMsgChRelease->ucBssIndex = ucBssIdx; + prMsgChRelease->ucTokenID = prChnlReqInfo->ucSeqNumOfChReq++; +#if CFG_SUPPORT_DBDC + prMsgChRelease->eDBDCBand = ENUM_BAND_AUTO; + + DBGLOG(P2P, INFO, + "p2pFuncReleaseCh: P2P abort channel on band %u.\n", + prMsgChRelease->eDBDCBand); +#endif /*CFG_SUPPORT_DBDC*/ + mboxSendMsg(prAdapter, + MBOX_ID_0, + (struct MSG_HDR *) prMsgChRelease, + MSG_SEND_METHOD_BUF); + + } while (FALSE); +} /* p2pFuncReleaseCh */ + +/*---------------------------------------------------------------------------*/ +/*! + * @brief Process of CHANNEL_REQ_JOIN Initial. Enter CHANNEL_REQ_JOIN State. + * + * @param (none) + * + * @return (none) + */ +/*---------------------------------------------------------------------------*/ +void p2pFuncAcquireCh(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIdx, IN struct P2P_CHNL_REQ_INFO *prChnlReqInfo) +{ + struct MSG_CH_REQ *prMsgChReq = (struct MSG_CH_REQ *) NULL; + + do { + ASSERT_BREAK((prAdapter != NULL) && (prChnlReqInfo != NULL)); + + p2pFuncReleaseCh(prAdapter, ucBssIdx, prChnlReqInfo); + + /* send message to CNM for acquiring channel */ + prMsgChReq = (struct MSG_CH_REQ *) + cnmMemAlloc(prAdapter, + RAM_TYPE_MSG, sizeof(struct MSG_CH_REQ)); + + if (!prMsgChReq) { + /* Can't indicate CNM for channel acquiring */ + break; + } + + prMsgChReq->rMsgHdr.eMsgId = MID_MNY_CNM_CH_REQ; + prMsgChReq->ucBssIndex = ucBssIdx; + prMsgChReq->ucTokenID = ++prChnlReqInfo->ucSeqNumOfChReq; + prMsgChReq->eReqType = prChnlReqInfo->eChnlReqType; + prMsgChReq->u4MaxInterval = prChnlReqInfo->u4MaxInterval; + prMsgChReq->ucPrimaryChannel = prChnlReqInfo->ucReqChnlNum; + prMsgChReq->eRfSco = prChnlReqInfo->eChnlSco; + prMsgChReq->eRfBand = prChnlReqInfo->eBand; + prMsgChReq->eRfChannelWidth = prChnlReqInfo->eChannelWidth; + prMsgChReq->ucRfCenterFreqSeg1 = prChnlReqInfo->ucCenterFreqS1; + prMsgChReq->ucRfCenterFreqSeg2 = prChnlReqInfo->ucCenterFreqS2; +#if CFG_SUPPORT_DBDC + prMsgChReq->eDBDCBand = ENUM_BAND_AUTO; + + DBGLOG(P2P, INFO, + "p2pFuncAcquireCh: P2P Request channel on band %u, tokenID: %d, cookie: 0x%llx.\n", + prMsgChReq->eDBDCBand, + prMsgChReq->ucTokenID, + prChnlReqInfo->u8Cookie); + +#endif /*CFG_SUPPORT_DBDC*/ + /* Channel request join BSSID. */ + + mboxSendMsg(prAdapter, + MBOX_ID_0, + (struct MSG_HDR *) prMsgChReq, + MSG_SEND_METHOD_BUF); + + prChnlReqInfo->fgIsChannelRequested = TRUE; + + } while (FALSE); +} /* p2pFuncAcquireCh */ + +#if (CFG_SUPPORT_DFS_MASTER == 1) +void p2pFuncStartRdd(IN struct ADAPTER *prAdapter, IN uint8_t ucBssIdx) +{ + struct CMD_RDD_ON_OFF_CTRL *prCmdRddOnOffCtrl; + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *) NULL; + uint8_t ucReqChnlNum; + + DEBUGFUNC("p2pFuncStartRdd()"); + + + prP2pRoleFsmInfo = P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, + prAdapter->aprBssInfo[ucBssIdx]->u4PrivateData); + + ucReqChnlNum = prP2pRoleFsmInfo->rChnlReqInfo.ucReqChnlNum; + + prCmdRddOnOffCtrl = (struct CMD_RDD_ON_OFF_CTRL *) + cnmMemAlloc(prAdapter, RAM_TYPE_MSG, + sizeof(*prCmdRddOnOffCtrl)); + + if (!prCmdRddOnOffCtrl) { + DBGLOG(P2P, ERROR, + "cnmMemAlloc for prCmdRddOnOffCtrl failed!\n"); + return; + } + + prCmdRddOnOffCtrl->ucDfsCtrl = RDD_START; + + /* + * FIX ME: Mobile driver can't get correct band. + * There is only 5G in DFS channel, + * which is on band_0. So it assigned to ENUM_BAND_0 as temp solution. + * Remember to fix it when driver could get + * the correct band from firmware. + */ + prCmdRddOnOffCtrl->ucRddIdx = ENUM_BAND_0; + +#if (CFG_SUPPORT_SINGLE_SKU == 1) + if (rlmDomainGetDfsRegion() == NL80211_DFS_JP) { + if (ucReqChnlNum >= 52 && ucReqChnlNum <= 64) + prCmdRddOnOffCtrl->ucSetVal = REG_JP_53; + else if (ucReqChnlNum >= 100 && ucReqChnlNum <= 140) + prCmdRddOnOffCtrl->ucSetVal = REG_JP_56; + } else { + prCmdRddOnOffCtrl->ucSetVal = REG_DEFAULT; + } +#else + prCmdRddOnOffCtrl->ucSetVal = REG_DEFAULT; +#endif + + if (prCmdRddOnOffCtrl->ucRddIdx) + prCmdRddOnOffCtrl->ucRddRxSel = RDD_IN_SEL_1; + else + prCmdRddOnOffCtrl->ucRddRxSel = RDD_IN_SEL_0; + + DBGLOG(P2P, INFO, + "p2pFuncStartRdd: Start Radar detection - DFS ctrl: %d, RDD index: %d\n", + prCmdRddOnOffCtrl->ucDfsCtrl, prCmdRddOnOffCtrl->ucRddIdx); + + wlanSendSetQueryCmd(prAdapter, + CMD_ID_RDD_ON_OFF_CTRL, + TRUE, + FALSE, + FALSE, + NULL, + NULL, + sizeof(*prCmdRddOnOffCtrl), + (uint8_t *) prCmdRddOnOffCtrl, NULL, 0); + + cnmMemFree(prAdapter, prCmdRddOnOffCtrl); +} /* p2pFuncStartRdd */ + +void p2pFuncStopRdd(IN struct ADAPTER *prAdapter, IN uint8_t ucBssIdx) +{ + struct CMD_RDD_ON_OFF_CTRL *prCmdRddOnOffCtrl; + + DEBUGFUNC("p2pFuncStopRdd()"); + + prCmdRddOnOffCtrl = (struct CMD_RDD_ON_OFF_CTRL *) + cnmMemAlloc(prAdapter, RAM_TYPE_MSG, + sizeof(*prCmdRddOnOffCtrl)); + + if (!prCmdRddOnOffCtrl) { + DBGLOG(P2P, ERROR, + "cnmMemAlloc for prCmdRddOnOffCtrl failed!\n"); + return; + } + + prCmdRddOnOffCtrl->ucDfsCtrl = RDD_STOP; + + /* + * FIX ME: Mobile driver can't get correct band. + * There is only 5G in DFS channel, + * which is on band_0. So it assigned to ENUM_BAND_0 as temp solution. + * Remember to fix it when driver could get + * the correct band from firmware. + */ + prCmdRddOnOffCtrl->ucRddIdx = ENUM_BAND_0; + + if (prCmdRddOnOffCtrl->ucRddIdx) + prCmdRddOnOffCtrl->ucRddRxSel = RDD_IN_SEL_1; + else + prCmdRddOnOffCtrl->ucRddRxSel = RDD_IN_SEL_0; + + DBGLOG(P2P, INFO, + "p2pFuncStopRdd: Stop Radar detection - DFS ctrl: %d, RDD index: %d\n", + prCmdRddOnOffCtrl->ucDfsCtrl, prCmdRddOnOffCtrl->ucRddIdx); + + wlanSendSetQueryCmd(prAdapter, + CMD_ID_RDD_ON_OFF_CTRL, + TRUE, + FALSE, + FALSE, + NULL, + NULL, + sizeof(*prCmdRddOnOffCtrl), + (uint8_t *) prCmdRddOnOffCtrl, NULL, 0); + + cnmMemFree(prAdapter, prCmdRddOnOffCtrl); + +} /* p2pFuncStopRdd */ + + +void p2pFuncDfsSwitchCh(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo, + IN struct P2P_CHNL_REQ_INFO rP2pChnlReqInfo) +{ + + struct GLUE_INFO *prGlueInfo; + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *) NULL; + struct CMD_RDD_ON_OFF_CTRL *prCmdRddOnOffCtrl; + uint8_t role_idx = 0; + u_int8_t fgIsCrossBand = FALSE; + + DEBUGFUNC("p2pFuncDfsSwitchCh()"); + + if (!prBssInfo) { + DBGLOG(P2P, ERROR, "prBssInfo shouldn't be NULL!\n"); + return; + } + + if (prBssInfo->eBand != rP2pChnlReqInfo.eBand) + fgIsCrossBand = TRUE; + + /* Setup Channel, Band */ + prBssInfo->ucPrimaryChannel = rP2pChnlReqInfo.ucReqChnlNum; + prBssInfo->eBand = rP2pChnlReqInfo.eBand; + prBssInfo->eBssSCO = rP2pChnlReqInfo.eChnlSco; + +/* To Support Cross Band Channel Swtich */ +#if CFG_SUPPORT_IDC_CH_SWITCH + if (prBssInfo->eBand == BAND_5G) { + /* Depend on eBand */ + prBssInfo->ucPhyTypeSet |= PHY_TYPE_SET_802_11A; + /* Depend on eCurrentOPMode and ucPhyTypeSet */ + prBssInfo->ucConfigAdHocAPMode = AP_MODE_11A; + } else { /* Only SAP mode should enter this function */ + prBssInfo->ucPhyTypeSet |= PHY_TYPE_SET_802_11BG; + /* Depend on eCurrentOPMode and ucPhyTypeSet */ + prBssInfo->ucConfigAdHocAPMode = AP_MODE_MIXED_11BG; + } + + /* Overwrite BSS PHY type set by Feature Options */ + bssDetermineApBssInfoPhyTypeSet(prAdapter, + TRUE, prBssInfo); + + prBssInfo->ucNonHTBasicPhyType = (uint8_t) + rNonHTApModeAttributes + [prBssInfo->ucConfigAdHocAPMode] + .ePhyTypeIndex; + prBssInfo->u2BSSBasicRateSet = + rNonHTApModeAttributes + [prBssInfo->ucConfigAdHocAPMode] + .u2BSSBasicRateSet; + prBssInfo->u2OperationalRateSet = + rNonHTPhyAttributes + [prBssInfo->ucNonHTBasicPhyType] + .u2SupportedRateSet; + kalMemZero(prBssInfo->aucAllSupportedRates, RATE_NUM_SW); + rateGetDataRatesFromRateSet( + prBssInfo->u2OperationalRateSet, + prBssInfo->u2BSSBasicRateSet, + prBssInfo->aucAllSupportedRates, + &prBssInfo->ucAllSupportedRatesLen); +#endif + + /* Setup channel and bandwidth */ + rlmBssInitForAPandIbss(prAdapter, prBssInfo); + + /* Update Beacon again for network phy type confirmed. */ + bssUpdateBeaconContent(prAdapter, prBssInfo->ucBssIndex); + + /* Reset HW TSF Update Mode and Beacon Mode */ + nicUpdateBss(prAdapter, prBssInfo->ucBssIndex); + + if (fgIsCrossBand) + nicPmIndicateBssCreated(prAdapter, + prBssInfo->ucBssIndex); + + prCmdRddOnOffCtrl = (struct CMD_RDD_ON_OFF_CTRL *) + cnmMemAlloc(prAdapter, RAM_TYPE_MSG, + sizeof(*prCmdRddOnOffCtrl)); + + if (!prCmdRddOnOffCtrl) { + DBGLOG(P2P, ERROR, + "cnmMemAlloc for prCmdRddOnOffCtrl failed!\n"); + return; + } + + prCmdRddOnOffCtrl->ucDfsCtrl = RDD_START_TXQ; + + DBGLOG(P2P, TRACE, + "p2pFuncDfsSwitchCh: Start TXQ - DFS ctrl: %.d\n", + prCmdRddOnOffCtrl->ucDfsCtrl); + + wlanSendSetQueryCmd(prAdapter, + CMD_ID_RDD_ON_OFF_CTRL, + TRUE, + FALSE, + FALSE, + NULL, + NULL, + sizeof(*prCmdRddOnOffCtrl), + (uint8_t *) prCmdRddOnOffCtrl, + NULL, 0); + + cnmMemFree(prAdapter, prCmdRddOnOffCtrl); + + prP2pRoleFsmInfo = + P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, + prBssInfo->u4PrivateData); + + prGlueInfo = prAdapter->prGlueInfo; + role_idx = prP2pRoleFsmInfo->ucRoleIndex; + +#if CFG_SUPPORT_SAP_DFS_CHANNEL + wlanUpdateDfsChannelTable(prGlueInfo, + role_idx, + prBssInfo->ucPrimaryChannel, + prBssInfo->ucVhtChannelWidth, + prBssInfo->eBssSCO, + nicChannelNum2Freq(prBssInfo->ucVhtChannelFrequencyS1) / 1000); +#endif + + kalP2pIndicateChnlSwitch(prAdapter, prBssInfo); + + /* Down the flag */ + prAdapter->rWifiVar.ucChannelSwitchMode = 0; + + /* Check DBDC status */ + cnmDbdcRuntimeCheckDecision(prAdapter, prBssInfo->ucBssIndex); +} /* p2pFuncDfsSwitchCh */ + +u_int8_t p2pFuncCheckWeatherRadarBand( + IN struct P2P_CHNL_REQ_INFO *prChnlReqInfo) +{ + uint8_t ucReqChnlNum; + uint8_t ucCenterFreqS1; + enum ENUM_CHANNEL_WIDTH eChannelWidth; + enum ENUM_CHNL_EXT eChnlSco; + + + ucReqChnlNum = prChnlReqInfo->ucReqChnlNum; + ucCenterFreqS1 = prChnlReqInfo->ucCenterFreqS1; + eChannelWidth = prChnlReqInfo->eChannelWidth; + eChnlSco = prChnlReqInfo->eChnlSco; + +#if (CFG_SUPPORT_SINGLE_SKU == 1) + if (rlmDomainGetDfsRegion() == NL80211_DFS_ETSI) { + if (eChannelWidth == VHT_OP_CHANNEL_WIDTH_80) { + if (ucCenterFreqS1 >= 120 && ucCenterFreqS1 <= 128) + return TRUE; + } else { + if ((ucReqChnlNum >= 120 && ucReqChnlNum <= 128)) + return TRUE; + else if (ucReqChnlNum == 116 + && eChnlSco == CHNL_EXT_SCA) + return TRUE; /* ch116, 120 BW40 */ + } + } +#endif + + return FALSE; +} + +int32_t p2pFuncSetDriverCacTime(IN uint32_t u4CacTime) +{ + uint32_t i4Status = WLAN_STATUS_SUCCESS; + + g_u4DriverCacTime = u4CacTime; + + DBGLOG(P2P, INFO, + "p2pFuncSetDriverCacTime: g_u4ManualCacTime = %dsec\n", + g_u4DriverCacTime); + + return i4Status; +} + +void p2pFuncEnableManualCac(void) +{ + g_fgManualCac = TRUE; +} + +uint32_t p2pFuncGetDriverCacTime(void) +{ + return g_u4DriverCacTime; +} + +u_int8_t p2pFuncIsManualCac(void) +{ + return g_fgManualCac; +} + +void p2pFuncRadarInfoInit(void) +{ + kalMemZero(&g_rP2pRadarInfo, sizeof(g_rP2pRadarInfo)); +} + +void p2pFuncShowRadarInfo(IN struct ADAPTER *prAdapter, IN uint8_t ucBssIdx) +{ + uint8_t ucCnt = 0; + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *) NULL; + uint8_t ucReqChnlNum; + + if (g_rP2pRadarInfo.ucRadarReportMode == 1) { + + prP2pRoleFsmInfo = P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, + prAdapter->aprBssInfo[ucBssIdx]->u4PrivateData); + + ucReqChnlNum = prP2pRoleFsmInfo->rChnlReqInfo.ucReqChnlNum; + + DBGLOG(P2P, INFO, "-----Radar Detected Event-----\n"); + DBGLOG(P2P, INFO, + "Radar detected in DBDC band%d\n", + g_rP2pRadarInfo.ucRddIdx); + +#if (CFG_SUPPORT_SINGLE_SKU == 1) + switch (rlmDomainGetDfsRegion()) { + case NL80211_DFS_FCC: + DBGLOG(P2P, INFO, "Regulation domain: FCC\n"); + break; + case NL80211_DFS_ETSI: + DBGLOG(P2P, INFO, "Regulation domain: ETSI\n"); + break; + case NL80211_DFS_JP: + DBGLOG(P2P, INFO, "Regulation domain: JP\n"); + + if (ucReqChnlNum >= 52 && ucReqChnlNum <= 64) + DBGLOG(P2P, INFO, + "Radar type: W53 - %s\n", + p2pFuncJpW53RadarType()); + else if (ucReqChnlNum >= 100 && ucReqChnlNum <= 140) + DBGLOG(P2P, INFO, + "Radar type: W56 - %s\n", + p2pFuncJpW56RadarType()); + break; + default: + break; + } +#endif + + DBGLOG(P2P, INFO, "Radar Content:\n"); + + DBGLOG(P2P, INFO, "start time pulse width PRI\n"); + + if (g_rP2pRadarInfo.ucPeriodicDetected) { + DBGLOG(P2P, INFO, "%-10d %-11d -\n" + , g_rP2pRadarInfo.arPpbContent + [ucCnt].u4PeriodicStartTime + , g_rP2pRadarInfo.arPpbContent + [ucCnt].u2PeriodicPulseWidth); + + for (ucCnt = 1; + ucCnt < g_rP2pRadarInfo.ucPPBNum; ucCnt++) { + DBGLOG(P2P, INFO, "%-10d %-11d %d\n" + , g_rP2pRadarInfo.arPpbContent + [ucCnt].u4PeriodicStartTime + , g_rP2pRadarInfo.arPpbContent + [ucCnt].u2PeriodicPulseWidth + , (g_rP2pRadarInfo.arPpbContent + [ucCnt].u4PeriodicStartTime + - g_rP2pRadarInfo.arPpbContent + [ucCnt-1].u4PeriodicStartTime) + * 2 / 5); + } + } else if (g_rP2pRadarInfo.ucLongDetected) { + DBGLOG(P2P, INFO, "%-10d %-11d -\n" + , g_rP2pRadarInfo.arLpbContent + [ucCnt].u4LongStartTime + , g_rP2pRadarInfo.arLpbContent + [ucCnt].u2LongPulseWidth); + + for (ucCnt = 1; + ucCnt < g_rP2pRadarInfo.ucLPBNum; ucCnt++) { + DBGLOG(P2P, INFO, "%-10d %-11d %d\n" + , g_rP2pRadarInfo.arLpbContent + [ucCnt].u4LongStartTime + , g_rP2pRadarInfo.arLpbContent + [ucCnt].u2LongPulseWidth + , (g_rP2pRadarInfo.arLpbContent + [ucCnt].u4LongStartTime + - g_rP2pRadarInfo.arLpbContent + [ucCnt-1].u4LongStartTime) + * 2 / 5); + } + } + } +} + +void p2pFuncGetRadarInfo(IN struct P2P_RADAR_INFO *prP2pRadarInfo) +{ + kalMemCopy(prP2pRadarInfo, &g_rP2pRadarInfo, sizeof(*prP2pRadarInfo)); +} + +uint8_t *p2pFuncJpW53RadarType(void) +{ + uint32_t u4Type1Diff; + uint32_t u4Type2Diff; + + if (g_rP2pRadarInfo.u4PRI1stUs >= 1428) + u4Type1Diff = g_rP2pRadarInfo.u4PRI1stUs - 1428; + else + u4Type1Diff = 1428 - g_rP2pRadarInfo.u4PRI1stUs; + + if (g_rP2pRadarInfo.u4PRI1stUs >= 3846) + u4Type2Diff = g_rP2pRadarInfo.u4PRI1stUs - 3846; + else + u4Type2Diff = 3846 - g_rP2pRadarInfo.u4PRI1stUs; + + if (u4Type1Diff < u4Type2Diff) + return apucW53RadarType[1]; + else + return apucW53RadarType[2]; +} + +uint8_t *p2pFuncJpW56RadarType(void) +{ + uint32_t u4Type1Diff; + uint32_t u4Type2Diff; + + if (g_rP2pRadarInfo.ucLongDetected) + return apucW56RadarType[7]; + + if (g_rP2pRadarInfo.u4PRI1stUs >= 3980 + && g_rP2pRadarInfo.u4PRI1stUs <= 4020) + return apucW56RadarType[3]; + + if (g_rP2pRadarInfo.u4PRI1stUs >= 1368 + && g_rP2pRadarInfo.u4PRI1stUs <= 1448) { + + if (g_rP2pRadarInfo.u4PRI1stUs >= 1388) + u4Type1Diff = g_rP2pRadarInfo.u4PRI1stUs - 1388; + else + u4Type1Diff = 1388 - g_rP2pRadarInfo.u4PRI1stUs; + + if (g_rP2pRadarInfo.u4PRI1stUs >= 1428) + u4Type2Diff = g_rP2pRadarInfo.u4PRI1stUs - 1428; + else + u4Type2Diff = 1428 - g_rP2pRadarInfo.u4PRI1stUs; + + if (u4Type1Diff < u4Type2Diff) + return apucW56RadarType[1]; + else + return apucW56RadarType[2]; + + } + + if (g_rP2pRadarInfo.u4PRI1stUs >= 130 + && g_rP2pRadarInfo.u4PRI1stUs < 200) + return apucW56RadarType[4]; + + if (g_rP2pRadarInfo.u4PRI1stUs >= 200 + && g_rP2pRadarInfo.u4PRI1stUs <= 520) { + + if (g_rP2pRadarInfo.u4PRI1stUs <= 230) + return apucW56RadarType[9]; + + if (g_rP2pRadarInfo.u4PRI1stUs >= 323 + && g_rP2pRadarInfo.u4PRI1stUs <= 343) + return apucW56RadarType[10]; + + return apucW56RadarType[11]; + } + + return apucW56RadarType[0]; +} + +void p2pFuncSetRadarDetectMode(IN uint8_t ucRadarDetectMode) +{ + g_ucRadarDetectMode = ucRadarDetectMode; + + DBGLOG(P2P, INFO, + "p2pFuncSetRadarDetectMode: g_ucRadarDetectMode: %d\n", + g_ucRadarDetectMode); +} + +uint8_t p2pFuncGetRadarDetectMode(void) +{ + return g_ucRadarDetectMode; +} + +void p2pFuncSetDfsState(IN uint8_t ucDfsState) +{ + DBGLOG(P2P, INFO, + "[DFS_STATE] TRANSITION: [%s] -> [%s]\n", + apucDfsState[g_ucDfsState], apucDfsState[ucDfsState]); + + g_ucDfsState = ucDfsState; +} + +uint8_t p2pFuncGetDfsState(void) +{ + return g_ucDfsState; +} + +uint8_t *p2pFuncShowDfsState(void) +{ + return apucDfsState[g_ucDfsState]; +} + +void p2pFuncRecordCacStartBootTime(void) +{ + g_u4CacStartBootTime = kalGetBootTime(); +} + +uint32_t p2pFuncGetCacRemainingTime(void) +{ + uint32_t u4CurrentBootTime; + uint32_t u4CacRemainingTime; + + u4CurrentBootTime = kalGetBootTime(); + + u4CacRemainingTime = g_u4DriverCacTime - + (u4CurrentBootTime - g_u4CacStartBootTime)/1000000; + + return u4CacRemainingTime; +} +#endif + +#if 0 +uint32_t +p2pFuncBeaconUpdate(IN struct ADAPTER *prAdapter, + IN uint8_t *pucBcnHdr, + IN uint32_t u4HdrLen, + IN uint8_t *pucBcnBody, + IN uint32_t u4BodyLen, + IN uint32_t u4DtimPeriod, + IN uint32_t u4BcnInterval) +{ + uint32_t rResultStatus = WLAN_STATUS_INVALID_DATA; + struct WLAN_BEACON_FRAME *prBcnFrame = + (struct WLAN_BEACON_FRAME *) NULL; + struct BSS_INFO *prP2pBssInfo = (struct BSS_INFO *) NULL; + struct MSDU_INFO *prBcnMsduInfo = (struct MSDU_INFO *) NULL; + uint8_t *pucTIMBody = (uint8_t *) NULL; + uint16_t u2FrameLength = 0, uint16_t u2OldBodyLen = 0; + uint8_t aucIEBuf[MAX_IE_LENGTH]; + + do { + ASSERT_BREAK(prAdapter != NULL); + + prP2pBssInfo = + &(prAdapter->rWifiVar + .arBssInfo[NETWORK_TYPE_P2P_INDEX]); + prBcnMsduInfo = prP2pBssInfo->prBeacon; + ASSERT_BREAK(prBcnMsduInfo != NULL); + + /* TODO: Find TIM IE pointer. */ + prBcnFrame = prBcnMsduInfo->prPacket; + + ASSERT_BREAK(prBcnFrame != NULL); + + do { + /* Ori header. */ + uint16_t u2IELength = 0, u2Offset = 0; + uint8_t *pucIEBuf = prBcnFrame->aucInfoElem; + + u2IELength = prBcnMsduInfo->u2FrameLength - + prBcnMsduInfo->ucMacHeaderLength; + + IE_FOR_EACH(pucIEBuf, u2IELength, u2Offset) { + if ((IE_ID(pucIEBuf) == ELEM_ID_TIM) + || ((IE_ID(pucIEBuf) + > ELEM_ID_IBSS_PARAM_SET))) { + pucTIMBody = pucIEBuf; + break; + } + u2FrameLength += IE_SIZE(pucIEBuf); + } + + if (pucTIMBody == NULL) + pucTIMBody = pucIEBuf; + + /* Body not change. */ + u2OldBodyLen = (uint16_t) ((uint32_t) pucTIMBody - + (uint32_t) prBcnFrame->aucInfoElem); + /* Move body. */ + kalMemCmp(aucIEBuf, pucTIMBody, u2OldBodyLen); + } while (FALSE); + if (pucBcnHdr) { + kalMemCopy(prBcnMsduInfo->prPacket, + pucBcnHdr, u4HdrLen); + pucTIMBody = (uint8_t *) + ((uint32_t) prBcnMsduInfo->prPacket + u4HdrLen); + prBcnMsduInfo->ucMacHeaderLength = + (WLAN_MAC_MGMT_HEADER_LEN + + (TIMESTAMP_FIELD_LEN + + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN)); + /* Header + Partial Body. */ + u2FrameLength = u4HdrLen; + } else { + /* Header not change. */ + u2FrameLength += prBcnMsduInfo->ucMacHeaderLength; + } + + if (pucBcnBody) { + kalMemCopy(pucTIMBody, pucBcnBody, u4BodyLen); + u2FrameLength += (uint16_t) u4BodyLen; + } else { + kalMemCopy(pucTIMBody, aucIEBuf, u2OldBodyLen); + u2FrameLength += u2OldBodyLen; + } + + /* Frame Length */ + prBcnMsduInfo->u2FrameLength = u2FrameLength; + prBcnMsduInfo->fgIs802_11 = TRUE; + prBcnMsduInfo->ucNetworkType = NETWORK_TYPE_P2P_INDEX; + prP2pBssInfo->u2BeaconInterval = (uint16_t) u4BcnInterval; + prP2pBssInfo->ucDTIMPeriod = (uint8_t) u4DtimPeriod; + prP2pBssInfo->u2CapInfo = prBcnFrame->u2CapInfo; + prBcnMsduInfo->ucPacketType = 3; + rResultStatus = nicUpdateBeaconIETemplate(prAdapter, + IE_UPD_METHOD_UPDATE_ALL, + NETWORK_TYPE_P2P_INDEX, + prP2pBssInfo->u2CapInfo, + (uint8_t *) prBcnFrame->aucInfoElem, + prBcnMsduInfo->u2FrameLength - + OFFSET_OF(struct WLAN_BEACON_FRAME, aucInfoElem)); + if (prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) { + /* AP is created, Beacon Update. */ + nicPmIndicateBssAbort(prAdapter, + NETWORK_TYPE_P2P_INDEX); + nicPmIndicateBssCreated(prAdapter, + NETWORK_TYPE_P2P_INDEX); + } + + } while (FALSE); + return rResultStatus; +} /* p2pFuncBeaconUpdate */ + +#else +uint32_t +p2pFuncBeaconUpdate(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prP2pBssInfo, + IN struct P2P_BEACON_UPDATE_INFO *prBcnUpdateInfo, + IN uint8_t *pucNewBcnHdr, + IN uint32_t u4NewHdrLen, + IN uint8_t *pucNewBcnBody, + IN uint32_t u4NewBodyLen) +{ + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + struct WLAN_BEACON_FRAME *prBcnFrame = + (struct WLAN_BEACON_FRAME *) NULL; + struct MSDU_INFO *prBcnMsduInfo = (struct MSDU_INFO *) NULL; + uint8_t *pucIEBuf = (uint8_t *) NULL; + uint8_t aucIEBuf[MAX_IE_LENGTH]; + + do { + ASSERT_BREAK((prAdapter != NULL) + && (prP2pBssInfo != NULL) + && (prBcnUpdateInfo != NULL)); + + prBcnMsduInfo = prP2pBssInfo->prBeacon; + +#if DBG + if (prBcnUpdateInfo->pucBcnHdr != NULL) { + ASSERT((uint32_t) prBcnUpdateInfo->pucBcnHdr == + ((uint32_t) prBcnMsduInfo->prPacket + + MAC_TX_RESERVED_FIELD)); + } + + if (prBcnUpdateInfo->pucBcnBody != NULL) { + ASSERT((uint32_t) prBcnUpdateInfo->pucBcnBody == + ((uint32_t) prBcnUpdateInfo->pucBcnHdr + + (uint32_t) prBcnUpdateInfo->u4BcnHdrLen)); + } +#endif + prBcnFrame = (struct WLAN_BEACON_FRAME *) + ((unsigned long) prBcnMsduInfo->prPacket + + MAC_TX_RESERVED_FIELD); + + if (!pucNewBcnBody) { + /* Old body. */ + pucNewBcnBody = prBcnUpdateInfo->pucBcnBody; + ASSERT(u4NewBodyLen == 0); + u4NewBodyLen = prBcnUpdateInfo->u4BcnBodyLen; + } else { + prBcnUpdateInfo->u4BcnBodyLen = u4NewBodyLen; + } + + /* Temp buffer body part. */ + kalMemCopy(aucIEBuf, pucNewBcnBody, u4NewBodyLen); + + if (pucNewBcnHdr) { + kalMemCopy(prBcnFrame, pucNewBcnHdr, u4NewHdrLen); + prBcnUpdateInfo->pucBcnHdr = (uint8_t *) prBcnFrame; + prBcnUpdateInfo->u4BcnHdrLen = u4NewHdrLen; + } + + pucIEBuf = (uint8_t *) + ((unsigned long) prBcnUpdateInfo->pucBcnHdr + + (unsigned long) prBcnUpdateInfo->u4BcnHdrLen); + kalMemCopy(pucIEBuf, aucIEBuf, u4NewBodyLen); + prBcnUpdateInfo->pucBcnBody = pucIEBuf; + + /* Frame Length */ + prBcnMsduInfo->u2FrameLength = (uint16_t) + (prBcnUpdateInfo->u4BcnHdrLen + + prBcnUpdateInfo->u4BcnBodyLen); + + prBcnMsduInfo->ucPacketType = TX_PACKET_TYPE_MGMT; + prBcnMsduInfo->fgIs802_11 = TRUE; + prBcnMsduInfo->ucBssIndex = prP2pBssInfo->ucBssIndex; + + /* Update BSS INFO related information. */ + COPY_MAC_ADDR(prP2pBssInfo->aucOwnMacAddr, + prBcnFrame->aucSrcAddr); + COPY_MAC_ADDR(prP2pBssInfo->aucBSSID, prBcnFrame->aucBSSID); + prP2pBssInfo->u2CapInfo = prBcnFrame->u2CapInfo; + + p2pFuncParseBeaconContent(prAdapter, + prP2pBssInfo, + (uint8_t *) prBcnFrame->aucInfoElem, + (prBcnMsduInfo->u2FrameLength - + OFFSET_OF(struct WLAN_BEACON_FRAME, aucInfoElem))); + +#if 1 + /* bssUpdateBeaconContent(prAdapter, NETWORK_TYPE_P2P_INDEX); */ +#else + nicUpdateBeaconIETemplate(prAdapter, + IE_UPD_METHOD_UPDATE_ALL, + NETWORK_TYPE_P2P_INDEX, + prBcnFrame->u2CapInfo, + (uint8_t *) prBcnFrame->aucInfoElem, + (prBcnMsduInfo->u2FrameLength - + OFFSET_OF(struct WLAN_BEACON_FRAME, aucInfoElem))); +#endif + } while (FALSE); + + return rWlanStatus; +} /* p2pFuncBeaconUpdate */ + +/*---------------------------------------------------------------------------*/ +/*! + * \brief This function is to update extra IEs (ex: WPS) for assoc resp. + * Caller should sanity check the params. + * + * \param[in] prAdapter Pointer of ADAPTER_T + * \param[in] prP2pBssInfo Pointer to BSS_INFO_T structure + * \param[in] AssocRespIE Pointer to extra IEs for assoc resp + * \param[in] u4AssocRespLen Length of extra IEs for assoc resp + * + * \return WLAN_STATUS + */ +/*---------------------------------------------------------------------------*/ + +uint32_t +p2pFuncAssocRespUpdate(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prP2pBssInfo, + IN uint8_t *AssocRespIE, IN uint32_t u4AssocRespLen) +{ + uint8_t ucOuiType = 0; + uint16_t u2SubTypeVersion = 0; + + if (!rsnParseCheckForWFAInfoElem(prAdapter, + AssocRespIE, &ucOuiType, &u2SubTypeVersion)) + return WLAN_STATUS_FAILURE; + + if (ucOuiType == VENDOR_OUI_TYPE_WPS) { + kalP2PUpdateWSC_IE(prAdapter->prGlueInfo, 3, + (uint8_t *)AssocRespIE, IE_SIZE(AssocRespIE), + (uint8_t) (prP2pBssInfo->u4PrivateData)); + } + + return WLAN_STATUS_SUCCESS; +} + +#endif + +#if 0 +/* TODO: We do not apply IE in deauth frame set from upper layer now. */ +uint32_t +p2pFuncDeauth(IN struct ADAPTER *prAdapter, + IN uint8_t *pucPeerMacAddr, + IN uint16_t u2ReasonCode, + IN uint8_t *pucIEBuf, + IN uint16_t u2IELen, + IN u_int8_t fgSendDeauth) +{ + uint32_t rWlanStatus = WLAN_STATUS_FAILURE; + struct STA_RECORD *prCliStaRec = (struct STA_RECORD *) NULL; + struct BSS_INFO *prP2pBssInfo = (struct BSS_INFO *) NULL; + u_int8_t fgIsStaFound = FALSE; + + do { + ASSERT_BREAK((prAdapter != NULL) && (pucPeerMacAddr != NULL)); + + prP2pBssInfo = + &(prAdapter->rWifiVar + .arBssInfo[NETWORK_TYPE_P2P_INDEX]); + + prCliStaRec = cnmGetStaRecByAddress(prAdapter, + NETWORK_TYPE_P2P_INDEX, pucPeerMacAddr); + + switch (prP2pBssInfo->eCurrentOPMode) { + case OP_MODE_ACCESS_POINT: + { + struct LINK *prStaRecOfClientList = + (struct LINK *) NULL; + struct LINK_ENTRY *prLinkEntry = + (struct LINK_ENTRY *) NULL; + + prStaRecOfClientList = + &(prP2pBssInfo->rStaRecOfClientList); + + LINK_FOR_EACH(prLinkEntry, + prStaRecOfClientList) { + if ((uint32_t) prCliStaRec + == (uint32_t) prLinkEntry) { + LINK_REMOVE_KNOWN_ENTRY( + prStaRecOfClientList, + &prCliStaRec->rLinkEntry); + fgIsStaFound = TRUE; + break; + } + } + + } + break; + case OP_MODE_INFRASTRUCTURE: + ASSERT(prCliStaRec == prP2pBssInfo->prStaRecOfAP); + if (prCliStaRec != prP2pBssInfo->prStaRecOfAP) + break; + prP2pBssInfo->prStaRecOfAP = NULL; + fgIsStaFound = TRUE; + break; + default: + break; + } + + if (fgIsStaFound) + p2pFuncDisconnect(prAdapter, + prCliStaRec, fgSendDeauth, u2ReasonCode); + + rWlanStatus = WLAN_STATUS_SUCCESS; + } while (FALSE); + + return rWlanStatus; +} /* p2pFuncDeauth */ + +/* TODO: We do not apply IE in disassoc frame set from upper layer now. */ +uint32_t +p2pFuncDisassoc(IN struct ADAPTER *prAdapter, + IN uint8_t *pucPeerMacAddr, + IN uint16_t u2ReasonCode, + IN uint8_t *pucIEBuf, + IN uint16_t u2IELen, + IN u_int8_t fgSendDisassoc) +{ + uint32_t rWlanStatus = WLAN_STATUS_FAILURE; + struct STA_RECORD *prCliStaRec = (struct STA_RECORD *) NULL; + struct BSS_INFO *prP2pBssInfo = (struct BSS_INFO *) NULL; + u_int8_t fgIsStaFound = FALSE; + + do { + ASSERT_BREAK((prAdapter != NULL) + && (pucPeerMacAddr != NULL)); + + prP2pBssInfo = + &(prAdapter->rWifiVar + .arBssInfo[NETWORK_TYPE_P2P_INDEX]); + + prCliStaRec = cnmGetStaRecByAddress(prAdapter, + NETWORK_TYPE_P2P_INDEX, pucPeerMacAddr); + + switch (prP2pBssInfo->eCurrentOPMode) { + case OP_MODE_ACCESS_POINT: + { + struct LINK *prStaRecOfClientList = + (struct LINK *) NULL; + struct LINK_ENTRY *prLinkEntry = + (struct LINK_ENTRY *) NULL; + + prStaRecOfClientList = + &(prP2pBssInfo->rStaRecOfClientList); + + LINK_FOR_EACH(prLinkEntry, + prStaRecOfClientList) { + if ((uint32_t) prCliStaRec + == (uint32_t) prLinkEntry) { + LINK_REMOVE_KNOWN_ENTRY( + prStaRecOfClientList, + &prCliStaRec->rLinkEntry); + fgIsStaFound = TRUE; + /* p2pFuncDisconnect(prAdapter, + * prCliStaRec, + */ + /* fgSendDisassoc, + * u2ReasonCode); + */ + break; + } + } + + } + break; + case OP_MODE_INFRASTRUCTURE: + ASSERT(prCliStaRec == prP2pBssInfo->prStaRecOfAP); + if (prCliStaRec != prP2pBssInfo->prStaRecOfAP) + break; + /* p2pFuncDisconnect(prAdapter, + * prCliStaRec, fgSendDisassoc, u2ReasonCode); + */ + prP2pBssInfo->prStaRecOfAP = NULL; + fgIsStaFound = TRUE; + break; + default: + break; + } + + if (fgIsStaFound) { + + p2pFuncDisconnect(prAdapter, + prCliStaRec, fgSendDisassoc, u2ReasonCode); + /* 20120830 moved into p2pFuncDisconnect(). */ + /* cnmStaRecFree(prAdapter, prCliStaRec); */ + + } + + rWlanStatus = WLAN_STATUS_SUCCESS; + } while (FALSE); + + return rWlanStatus; +} /* p2pFuncDisassoc */ + +#endif + +#if CFG_SUPPORT_P2P_GO_OFFLOAD_PROBE_RSP +uint32_t +p2pFuncProbeRespUpdate(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prP2pBssInfo, + IN uint8_t *ProbeRespIE, IN uint32_t u4ProbeRespLen) + +{ + struct MSDU_INFO *prMsduInfo = (struct MSDU_INFO *) NULL; + uint32_t u4IeArraySize = 0, u4Idx = 0; + uint8_t *pucP2pIe = (uint8_t *) NULL; + uint8_t *pucWpsIe = (uint8_t *) NULL; + uint8_t *pucWfdIe = (uint8_t *) NULL; + + if (prP2pBssInfo == NULL) + return WLAN_STATUS_FAILURE; + + /* reuse beacon MsduInfo */ + prMsduInfo = prP2pBssInfo->prBeacon; + + /* beacon prMsduInfo will be NULLify + * once BSS deactivated, so skip if it is + */ + if (!prMsduInfo) + return WLAN_STATUS_SUCCESS; + + if (!ProbeRespIE) { + DBGLOG(BSS, INFO, + "change beacon: has no extra probe response IEs\n"); + return WLAN_STATUS_SUCCESS; + } + if (p2pFuncIsAPMode( + prAdapter->rWifiVar + .prP2PConnSettings[prP2pBssInfo->u4PrivateData])) { + DBGLOG(BSS, INFO, + "change beacon: pure Ap mode do not add extra probe response IEs\n"); + return WLAN_STATUS_SUCCESS; + } + prMsduInfo->u2FrameLength = 0; + + bssBuildBeaconProbeRespFrameCommonIEs(prMsduInfo, + prP2pBssInfo, ProbeRespIE); + + u4IeArraySize = + sizeof(txProbeRspIETable) / sizeof(struct APPEND_VAR_IE_ENTRY); + + for (u4Idx = 0; u4Idx < u4IeArraySize; u4Idx++) { + if (txProbeRspIETable[u4Idx].pfnAppendIE) + txProbeRspIETable[u4Idx] + .pfnAppendIE(prAdapter, prMsduInfo); + } + + /* process probe response IE from supplicant */ + pucP2pIe = (uint8_t *) cfg80211_find_vendor_ie(WLAN_OUI_WFA, + WLAN_OUI_TYPE_WFA_P2P, + ProbeRespIE, + u4ProbeRespLen); + + pucWfdIe = (uint8_t *) cfg80211_find_vendor_ie(WLAN_OUI_WFA, + WLAN_OUI_TYPE_WFA_P2P + 1, + ProbeRespIE, + u4ProbeRespLen); + + pucWpsIe = (uint8_t *) cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT, + WLAN_OUI_TYPE_MICROSOFT_WPS, + ProbeRespIE, + u4ProbeRespLen); + + if (pucP2pIe) { + kalMemCopy(prMsduInfo->prPacket + prMsduInfo->u2FrameLength, + pucP2pIe, IE_SIZE(pucP2pIe)); + prMsduInfo->u2FrameLength += IE_SIZE(pucP2pIe); + } + + if (pucWfdIe) { + kalMemCopy(prMsduInfo->prPacket + prMsduInfo->u2FrameLength, + pucWfdIe, IE_SIZE(pucWfdIe)); + prMsduInfo->u2FrameLength += IE_SIZE(pucWfdIe); + } + + if (pucWpsIe) { + kalMemCopy(prMsduInfo->prPacket + prMsduInfo->u2FrameLength, + pucWpsIe, IE_SIZE(pucWpsIe)); + prMsduInfo->u2FrameLength += IE_SIZE(pucWpsIe); + } + + DBGLOG(BSS, INFO, + "update probe response for bss index: %d, IE len: %d\n", + prP2pBssInfo->ucBssIndex, prMsduInfo->u2FrameLength); + /* dumpMemory8(prMsduInfo->prPacket, prMsduInfo->u2FrameLength); */ + + return nicUpdateBeaconIETemplate(prAdapter, + IE_UPD_METHOD_UPDATE_PROBE_RSP, + prP2pBssInfo->ucBssIndex, + prP2pBssInfo->u2CapInfo, + prMsduInfo->prPacket, + prMsduInfo->u2FrameLength); +} +#endif + +/*---------------------------------------------------------------------------*/ +/*! + * @brief This function is called to dissolve from group or one group. + * (Would not change P2P FSM.) + * 1. GC: Disconnect from AP. (Send Deauth) + * 2. GO: Disconnect all STA + * + * @param[in] prAdapter Pointer to the adapter structure. + * + * @return (none) + */ +/*---------------------------------------------------------------------------*/ +void +p2pFuncDissolve(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prP2pBssInfo, + IN u_int8_t fgSendDeauth, + IN uint16_t u2ReasonCode) +{ + struct STA_RECORD *prCurrStaRec, *prStaRecNext; + struct LINK *prClientList; + + DEBUGFUNC("p2pFuncDissolve()"); + + do { + + ASSERT_BREAK((prAdapter != NULL) && (prP2pBssInfo != NULL)); + + switch (prP2pBssInfo->eCurrentOPMode) { + case OP_MODE_INFRASTRUCTURE: + /* Reset station record status. */ + if (prP2pBssInfo->prStaRecOfAP) { +#if CFG_WPS_DISCONNECT || (KERNEL_VERSION(4, 4, 0) <= CFG80211_VERSION_CODE) + kalP2PGCIndicateConnectionStatus( + prAdapter->prGlueInfo, + (uint8_t) prP2pBssInfo->u4PrivateData, + NULL, NULL, 0, + REASON_CODE_DEAUTH_LEAVING_BSS, + WLAN_STATUS_MEDIA_DISCONNECT); +#else + kalP2PGCIndicateConnectionStatus( + prAdapter->prGlueInfo, + (uint8_t) prP2pBssInfo->u4PrivateData, + NULL, NULL, 0, + REASON_CODE_DEAUTH_LEAVING_BSS); +#endif + + /* 2012/02/14 frog: + * After formation before join group, + * prStaRecOfAP is NULL. + */ + p2pFuncDisconnect(prAdapter, + prP2pBssInfo, + prP2pBssInfo->prStaRecOfAP, + fgSendDeauth, + u2ReasonCode); + } + + /* Fix possible KE when RX Beacon & + * call nicPmIndicateBssConnected(). + * hit prStaRecOfAP == NULL. + */ + p2pChangeMediaState(prAdapter, + prP2pBssInfo, + MEDIA_STATE_DISCONNECTED); + + prP2pBssInfo->prStaRecOfAP = NULL; + + break; + case OP_MODE_ACCESS_POINT: + /* Under AP mode, we would net + * send deauthentication frame to each STA. + * We only stop the Beacon & let all stations timeout. + */ + /* Send deauth. */ + authSendDeauthFrame(prAdapter, + prP2pBssInfo, + NULL, (struct SW_RFB *) NULL, + u2ReasonCode, (PFN_TX_DONE_HANDLER) NULL); + + prClientList = &prP2pBssInfo->rStaRecOfClientList; + + /* This case may let LINK_FOR_EACH_ENTRY_SAFE crash */ + if (prClientList == NULL) + break; + LINK_FOR_EACH_ENTRY_SAFE(prCurrStaRec, prStaRecNext, + prClientList, rLinkEntry, struct STA_RECORD) { + if (!prCurrStaRec) + break; + p2pFuncDisconnect(prAdapter, + prP2pBssInfo, prCurrStaRec, + TRUE, u2ReasonCode); + } + break; + default: + return; /* 20110420 -- alreay in Device Mode. */ + } + + /* Make the deauth frame send to FW ASAP. */ +#if !CFG_SUPPORT_MULTITHREAD + wlanAcquirePowerControl(prAdapter); +#endif + wlanProcessCommandQueue(prAdapter, + &prAdapter->prGlueInfo->rCmdQueue); +#if !CFG_SUPPORT_MULTITHREAD + wlanReleasePowerControl(prAdapter); +#endif + + /* Change Connection Status. */ + /* 20161025, can not set DISCONNECTED if clientcount > 0 */ + /*p2pChangeMediaState(prAdapter, + * prP2pBssInfo, MEDIA_STATE_DISCONNECTED); + */ + + } while (FALSE); +} /* p2pFuncDissolve */ + +/*---------------------------------------------------------------------------*/ +/*! + * @brief This function is called to dissolve from group or one group. + * (Would not change P2P FSM.) + * 1. GC: Disconnect from AP. (Send Deauth) + * 2. GO: Disconnect all STA + * + * @param[in] prAdapter Pointer to the adapter structure. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void +p2pFuncDisconnect(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prP2pBssInfo, + IN struct STA_RECORD *prStaRec, + IN u_int8_t fgSendDeauth, IN uint16_t u2ReasonCode) +{ + enum ENUM_PARAM_MEDIA_STATE eOriMediaStatus; + + do { + ASSERT_BREAK((prAdapter != NULL) + && (prStaRec != NULL) && (prP2pBssInfo != NULL)); + + ASSERT_BREAK(prP2pBssInfo->eNetworkType == NETWORK_TYPE_P2P); + + ASSERT_BREAK(prP2pBssInfo->ucBssIndex + < prAdapter->ucP2PDevBssIdx); + + eOriMediaStatus = prP2pBssInfo->eConnectionState; + + /* Indicate disconnect. */ + if (prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) { + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, + prP2pBssInfo->u4PrivateData); + + kalP2PGOStationUpdate(prAdapter->prGlueInfo, + prP2pRoleFsmInfo->ucRoleIndex, prStaRec, FALSE); + } else { + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, + prP2pBssInfo->u4PrivateData); + + prP2pRoleFsmInfo->rJoinInfo.prTargetBssDesc = NULL; + + scanRemoveConnFlagOfBssDescByBssid(prAdapter, + prP2pBssInfo->aucBSSID, + prP2pBssInfo->ucBssIndex); + } + + DBGLOG(P2P, INFO, + "p2pFuncDisconnect(): BssMode: %d, reason: %d, SendDeauth %s\n", + prP2pBssInfo->eCurrentOPMode, u2ReasonCode, + fgSendDeauth == TRUE ? "TRUE" : "FALSE"); + + if (fgSendDeauth) { + /* Send deauth. */ + authSendDeauthFrame(prAdapter, + prP2pBssInfo, + prStaRec, + (struct SW_RFB *) NULL, + u2ReasonCode, + (PFN_TX_DONE_HANDLER) + p2pRoleFsmRunEventDeauthTxDone); + + /* Make the deauth frame send to FW ASAP. */ +#if !CFG_SUPPORT_MULTITHREAD + wlanAcquirePowerControl(prAdapter); +#endif + wlanProcessCommandQueue(prAdapter, + &prAdapter->prGlueInfo->rCmdQueue); +#if !CFG_SUPPORT_MULTITHREAD + wlanReleasePowerControl(prAdapter); +#endif + } else { + /* Change station state. */ + cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); + + /* Reset Station Record Status. */ + p2pFuncResetStaRecStatus(prAdapter, prStaRec); + + cnmStaRecFree(prAdapter, prStaRec); + + if ((prP2pBssInfo->eCurrentOPMode + != OP_MODE_ACCESS_POINT) || + (bssGetClientCount(prAdapter, prP2pBssInfo) == 0)) { + DBGLOG(P2P, TRACE, + "No More Client, Media Status DISCONNECTED\n"); + p2pChangeMediaState(prAdapter, + prP2pBssInfo, + MEDIA_STATE_DISCONNECTED); + } + + if (eOriMediaStatus != prP2pBssInfo->eConnectionState) { + /* Update Disconnected state to FW. */ + nicUpdateBss(prAdapter, + prP2pBssInfo->ucBssIndex); + } + + } + } while (FALSE); + + return; + +} /* p2pFuncDisconnect */ + +void p2pFuncSetChannel(IN struct ADAPTER *prAdapter, + IN uint8_t ucRoleIdx, + IN struct RF_CHANNEL_INFO *prRfChannelInfo) +{ + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *) NULL; + struct P2P_CONNECTION_REQ_INFO *prP2pConnReqInfo = + (struct P2P_CONNECTION_REQ_INFO *) NULL; + + do { + ASSERT_BREAK((prAdapter != NULL) && (prRfChannelInfo != NULL)); + + prP2pRoleFsmInfo = + P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, ucRoleIdx); + if (!prP2pRoleFsmInfo) + break; + prP2pConnReqInfo = &(prP2pRoleFsmInfo->rConnReqInfo); + + prP2pConnReqInfo->rChannelInfo.ucChannelNum = + prRfChannelInfo->ucChannelNum; + prP2pConnReqInfo->rChannelInfo.eBand = prRfChannelInfo->eBand; + prP2pConnReqInfo->eChnlBw = prRfChannelInfo->ucChnlBw; + prP2pConnReqInfo->u2PriChnlFreq = + prRfChannelInfo->u2PriChnlFreq; + prP2pConnReqInfo->u4CenterFreq1 = + prRfChannelInfo->u4CenterFreq1; + prP2pConnReqInfo->u4CenterFreq2 = + prRfChannelInfo->u4CenterFreq2; + + } while (FALSE); +} /* p2pFuncSetChannel */ + +/*---------------------------------------------------------------------------*/ +/*! + * @brief Retry JOIN for AUTH_MODE_AUTO_SWITCH + * + * @param[in] prStaRec Pointer to the STA_RECORD_T + * + * @retval TRUE We will retry JOIN + * @retval FALSE We will not retry JOIN + */ +/*---------------------------------------------------------------------------*/ +u_int8_t p2pFuncRetryJOIN(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, + IN struct P2P_JOIN_INFO *prJoinInfo) +{ + struct MSG_SAA_FSM_START *prJoinReqMsg = + (struct MSG_SAA_FSM_START *) NULL; + u_int8_t fgRetValue = FALSE; + + do { + ASSERT_BREAK((prAdapter != NULL) + && (prStaRec != NULL) + && (prJoinInfo != NULL)); + + /* Retry other AuthType if possible */ + if (!prJoinInfo->ucAvailableAuthTypes) + break; + + if (prJoinInfo->ucAvailableAuthTypes + & (uint8_t) AUTH_TYPE_SHARED_KEY) { + + DBGLOG(P2P, INFO, + "RETRY JOIN INIT: Retry Authentication with AuthType == SHARED_KEY.\n"); + + prJoinInfo->ucAvailableAuthTypes &= + ~(uint8_t) AUTH_TYPE_SHARED_KEY; + + prStaRec->ucAuthAlgNum = + (uint8_t) AUTH_ALGORITHM_NUM_SHARED_KEY; + } else { + DBGLOG(P2P, ERROR, + "RETRY JOIN INIT: Retry Authentication with Unexpected AuthType.\n"); + ASSERT(0); + break; + } + + /* No more available Auth Types */ + prJoinInfo->ucAvailableAuthTypes = 0; + + /* Trigger SAA to start JOIN process. */ + prJoinReqMsg = (struct MSG_SAA_FSM_START *) + cnmMemAlloc(prAdapter, RAM_TYPE_MSG, + sizeof(struct MSG_SAA_FSM_START)); + if (!prJoinReqMsg) { + break; + } + + prJoinReqMsg->rMsgHdr.eMsgId = MID_P2P_SAA_FSM_START; + prJoinReqMsg->ucSeqNum = ++prJoinInfo->ucSeqNumOfReqMsg; + prJoinReqMsg->prStaRec = prStaRec; + + mboxSendMsg(prAdapter, + MBOX_ID_0, + (struct MSG_HDR *) prJoinReqMsg, + MSG_SEND_METHOD_BUF); + + fgRetValue = TRUE; + } while (FALSE); + + return fgRetValue; + +} /* end of p2pFuncRetryJOIN() */ + +struct BSS_INFO *p2pFuncBSSIDFindBssInfo(IN struct ADAPTER *prAdapter, + IN uint8_t *pucBSSID) +{ + struct BSS_INFO *prBssInfo = (struct BSS_INFO *) NULL; + uint8_t ucBssIdx = 0; + + do { + ASSERT_BREAK((prAdapter != NULL) && (pucBSSID != NULL)); + + for (ucBssIdx = 0; + ucBssIdx < prAdapter->ucHwBssIdNum; ucBssIdx++) { + if (!IS_NET_ACTIVE(prAdapter, ucBssIdx)) + continue; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIdx); + + if (EQUAL_MAC_ADDR(prBssInfo->aucBSSID, pucBSSID) + && IS_BSS_P2P(prBssInfo)) + break; + + prBssInfo = NULL; + } + + } while (FALSE); + + return prBssInfo; +} /* p2pFuncBSSIDFindBssInfo */ + +/*---------------------------------------------------------------------------*/ +/*! + * @brief This function will validate the Rx Auth Frame and then return + * the status code to AAA to indicate + * if need to perform following actions + * when the specified conditions were matched. + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] prSwRfb Pointer to SW RFB data structure. + * @param[in] pprStaRec Pointer to pointer of STA_RECORD_T structure. + * @param[out] pu2StatusCode The Status Code of Validation Result + * + * @retval TRUE Reply the Auth + * @retval FALSE Don't reply the Auth + */ +/*---------------------------------------------------------------------------*/ +u_int8_t +p2pFuncValidateAuth(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prP2pBssInfo, + IN struct SW_RFB *prSwRfb, + IN struct STA_RECORD **pprStaRec, + OUT uint16_t *pu2StatusCode) +{ + u_int8_t fgPmfConn = FALSE; + struct STA_RECORD *prStaRec = (struct STA_RECORD *) NULL; + struct WLAN_AUTH_FRAME *prAuthFrame = (struct WLAN_AUTH_FRAME *) NULL; + + DBGLOG(P2P, TRACE, "p2pValidate Authentication Frame\n"); + + + /* P2P 3.2.8 */ + *pu2StatusCode = STATUS_CODE_REQ_DECLINED; + prAuthFrame = (struct WLAN_AUTH_FRAME *) prSwRfb->pvHeader; + + if ((prP2pBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) || + (prP2pBssInfo->eIntendOPMode != OP_MODE_NUM)) { + /* We are not under AP Mode yet. */ + DBGLOG(P2P, WARN, + "Current OP mode is not under AP mode. (%d)\n", + prP2pBssInfo->eCurrentOPMode); + return FALSE; + } + + prStaRec = cnmGetStaRecByAddress(prAdapter, + prP2pBssInfo->ucBssIndex, prAuthFrame->aucSrcAddr); + + if (!prStaRec) { + prStaRec = cnmStaRecAlloc(prAdapter, STA_TYPE_P2P_GC, + prP2pBssInfo->ucBssIndex, + prAuthFrame->aucSrcAddr); + + /* TODO(Kevin): Error handling of allocation of + * struct STA_RECORD for + * exhausted case and do removal of unused struct STA_RECORD. + */ + /* Sent a message event to clean un-used STA_RECORD_T. */ + /* ASSERT(prStaRec); */ + if (!prStaRec) { + DBGLOG(P2P, WARN, + "StaRec Full. (%d)\n", CFG_STA_REC_NUM); + return TRUE; + } + + prSwRfb->ucStaRecIdx = prStaRec->ucIndex; + + prStaRec->u2BSSBasicRateSet = prP2pBssInfo->u2BSSBasicRateSet; + + prStaRec->u2DesiredNonHTRateSet = RATE_SET_ERP_P2P; + + prStaRec->u2OperationalRateSet = RATE_SET_ERP_P2P; + prStaRec->ucPhyTypeSet = PHY_TYPE_SET_802_11GN; + + /* Update default Tx rate */ + nicTxUpdateStaRecDefaultRate(prAdapter, prStaRec); + + /* NOTE(Kevin): Better to change state here, not at TX Done */ + cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); + } else { +#if CFG_SUPPORT_802_11W + /* AP PMF. if PMF connection, do not reset state & FSM */ + fgPmfConn = rsnCheckBipKeyInstalled(prAdapter, prStaRec); + if (fgPmfConn) { + DBGLOG(P2P, WARN, "PMF Connction, return false\n"); + return FALSE; + } +#endif + + prSwRfb->ucStaRecIdx = prStaRec->ucIndex; + + if ((prStaRec->ucStaState > STA_STATE_1) + && (IS_STA_IN_P2P(prStaRec))) { + + cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); + + p2pFuncResetStaRecStatus(prAdapter, prStaRec); + + bssRemoveClient(prAdapter, prP2pBssInfo, prStaRec); + + p2pFuncDisconnect(prAdapter, + prP2pBssInfo, prStaRec, FALSE, + REASON_CODE_DISASSOC_INACTIVITY); + } + + } + + if (bssGetClientCount(prAdapter, prP2pBssInfo) + >= P2P_MAXIMUM_CLIENT_COUNT +#if CFG_SUPPORT_HOTSPOT_WPS_MANAGER + || kalP2PMaxClients(prAdapter->prGlueInfo, + bssGetClientCount(prAdapter, prP2pBssInfo), + (uint8_t) prP2pBssInfo->u4PrivateData) +#endif + ) { + /* GROUP limit full. */ + /* P2P 3.2.8 */ + DBGLOG(P2P, WARN, + "Group Limit Full. (%d)\n", + bssGetClientCount(prAdapter, prP2pBssInfo)); + cnmStaRecFree(prAdapter, prStaRec); + *pu2StatusCode = STATUS_CODE_ASSOC_DENIED_AP_OVERLOAD; + return TRUE; + } +#if CFG_SUPPORT_HOTSPOT_WPS_MANAGER + else { + /* Hotspot Blacklist */ + if (kalP2PCmpBlackList(prAdapter->prGlueInfo, + prAuthFrame->aucSrcAddr, + (uint8_t) prP2pBssInfo->u4PrivateData) + || !p2pRoleProcessACLInspection(prAdapter, + prStaRec->aucMacAddr, prP2pBssInfo->ucBssIndex)) { + DBGLOG(P2P, WARN, "in black list.\n"); + cnmStaRecFree(prAdapter, prStaRec); + *pu2StatusCode + = STATUS_CODE_ASSOC_DENIED_OUTSIDE_STANDARD; + return FALSE; + } + + } +#endif + /* prStaRec->eStaType = STA_TYPE_INFRA_CLIENT; */ + prStaRec->eStaType = STA_TYPE_P2P_GC; + + /* Update Station Record - Status/Reason Code */ + prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL; + + prStaRec->ucJoinFailureCount = 0; + + *pprStaRec = prStaRec; + + *pu2StatusCode = STATUS_CODE_SUCCESSFUL; + + + return TRUE; + +} /* p2pFuncValidateAuth */ + +void p2pFuncResetStaRecStatus(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec) +{ + do { + if ((prAdapter == NULL) || (prStaRec == NULL)) { + break; + } + + prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL; + prStaRec->u2ReasonCode = REASON_CODE_RESERVED; + prStaRec->ucJoinFailureCount = 0; + prStaRec->fgTransmitKeyExist = FALSE; + + prStaRec->fgSetPwrMgtBit = FALSE; + + } while (FALSE); +} /* p2pFuncResetStaRecStatus */ + +/*---------------------------------------------------------------------------*/ +/*! + * @brief The function is used to initialize the value + * of the connection settings for P2P network + * + * @param (none) + * + * @return (none) + */ +/*---------------------------------------------------------------------------*/ +void +p2pFuncInitConnectionSettings(IN struct ADAPTER *prAdapter, + IN struct P2P_CONNECTION_SETTINGS *prP2PConnSettings, + IN u_int8_t fgIsApMode) +{ + struct WIFI_VAR *prWifiVar = NULL; + + ASSERT(prP2PConnSettings); + + prWifiVar = &(prAdapter->rWifiVar); + ASSERT(prWifiVar); + + prP2PConnSettings->fgIsApMode = fgIsApMode; + +#if CFG_SUPPORT_HOTSPOT_WPS_MANAGER + prP2PConnSettings->fgIsWPSMode = prWifiVar->ucApWpsMode; +#endif +} /* p2pFuncInitConnectionSettings */ + +/*---------------------------------------------------------------------------*/ +/*! + * @brief This function will validate the Rx Assoc Req Frame and then return + * the status code to AAA to indicate if need + * to perform following actions + * when the specified conditions were matched. + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] prSwRfb Pointer to SW RFB data structure. + * @param[out] pu2StatusCode The Status Code of Validation Result + * + * @retval TRUE Reply the Assoc Resp + * @retval FALSE Don't reply the Assoc Resp + */ +/*---------------------------------------------------------------------------*/ +u_int8_t p2pFuncValidateAssocReq(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, + OUT uint16_t *pu2StatusCode) +{ + u_int8_t fgReplyAssocResp = TRUE; + struct WLAN_ASSOC_REQ_FRAME *prAssocReqFrame = + (struct WLAN_ASSOC_REQ_FRAME *) NULL; + struct STA_RECORD *prStaRec = (struct STA_RECORD *) NULL; + struct BSS_INFO *prP2pBssInfo = (struct BSS_INFO *) NULL; + + /* TODO(Kevin): Call P2P functions to check .. + * 2. Check we can accept connection from thsi peer + * a. If we are in PROVISION state, + * only accept the peer we do the GO formation previously. + * b. If we are in OPERATION state, only accept + * the other peer when P2P_GROUP_LIMIT is 0. + * 3. Check Black List here. + */ + + do { + ASSERT_BREAK((prAdapter != NULL) + && (prSwRfb != NULL) && (pu2StatusCode != NULL)); + + *pu2StatusCode = STATUS_CODE_REQ_DECLINED; + prAssocReqFrame = + (struct WLAN_ASSOC_REQ_FRAME *) prSwRfb->pvHeader; + + prP2pBssInfo = + p2pFuncBSSIDFindBssInfo(prAdapter, + prAssocReqFrame->aucBSSID); + + if (prP2pBssInfo == NULL) { + DBGLOG(P2P, ERROR, + "RX ASSOC frame without BSS active / BSSID match\n"); + break; + } + + prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); + + if (prStaRec == NULL) { + /* Station record should be ready + * while RX AUTH frame. + */ + fgReplyAssocResp = FALSE; + break; + } + ASSERT(prSwRfb->prRxStatusGroup3); + prStaRec->ucRCPI = + nicRxGetRcpiValueFromRxv( + prAdapter, RCPI_MODE_MAX, prSwRfb); + + prStaRec->u2DesiredNonHTRateSet &= + prP2pBssInfo->u2OperationalRateSet; + prStaRec->ucDesiredPhyTypeSet = + prStaRec->ucPhyTypeSet & prP2pBssInfo->ucPhyTypeSet; + + if (prStaRec->ucDesiredPhyTypeSet == 0) { + /* The station only support 11B rate. */ + *pu2StatusCode = + STATUS_CODE_ASSOC_DENIED_RATE_NOT_SUPPORTED; + break; + } + + *pu2StatusCode = STATUS_CODE_SUCCESSFUL; + + } while (FALSE); + + return fgReplyAssocResp; + +} /* p2pFuncValidateAssocReq */ + +/*---------------------------------------------------------------------------*/ +/*! +* @brief This function is used to check the TKIP IE +* +* +* @return none +*/ +/*----------------------------------------------------------------------------*/ +u_int8_t p2pFuncParseCheckForTKIPInfoElem(IN uint8_t *pucBuf) +{ + uint8_t aucWfaOui[] = VENDOR_OUI_WFA; + struct WPA_INFO_ELEM *prWpaIE = (struct WPA_INFO_ELEM *) NULL; + uint32_t u4GroupKeyCipher = 0; + + if (pucBuf == NULL) + return FALSE; + + prWpaIE = (struct WPA_INFO_ELEM *) pucBuf; + + if (prWpaIE->ucLength <= ELEM_MIN_LEN_WFA_OUI_TYPE_SUBTYPE) + return FALSE; + + if (kalMemCmp(prWpaIE->aucOui, aucWfaOui, sizeof(aucWfaOui))) + return FALSE; + + WLAN_GET_FIELD_32(&prWpaIE->u4GroupKeyCipherSuite, &u4GroupKeyCipher); + + if (prWpaIE->ucOuiType == VENDOR_OUI_TYPE_WPA && + u4GroupKeyCipher == WPA_CIPHER_SUITE_TKIP) + return TRUE; + else + return FALSE; +} /* p2pFuncParseCheckForP2PInfoElem */ + +/*---------------------------------------------------------------------------*/ +/*! + * @brief This function is used to check the P2P IE + * + * + * @return none + */ +/*---------------------------------------------------------------------------*/ +u_int8_t p2pFuncParseCheckForP2PInfoElem(IN struct ADAPTER *prAdapter, + IN uint8_t *pucBuf, OUT uint8_t *pucOuiType) +{ + uint8_t aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC; + struct IE_WFA *prWfaIE = (struct IE_WFA *) NULL; + + do { + ASSERT_BREAK((prAdapter != NULL) + && (pucBuf != NULL) && (pucOuiType != NULL)); + + prWfaIE = (struct IE_WFA *) pucBuf; + + if (IE_LEN(pucBuf) <= ELEM_MIN_LEN_WFA_OUI_TYPE_SUBTYPE) { + break; + } else if (prWfaIE->aucOui[0] != aucWfaOui[0] || + prWfaIE->aucOui[1] != aucWfaOui[1] || + prWfaIE->aucOui[2] != aucWfaOui[2]) { + break; + } + + *pucOuiType = prWfaIE->ucOuiType; + + return TRUE; + } while (FALSE); + + return FALSE; +} /* p2pFuncParseCheckForP2PInfoElem */ + +/*---------------------------------------------------------------------------*/ +/*! + * @brief This function will validate the Rx Probe Request Frame and then return + * result to BSS to indicate if need to send + * the corresponding Probe Response Frame + * if the specified conditions were matched. + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] prSwRfb Pointer to SW RFB data structure. + * @param[out] pu4ControlFlags Control flags for replying the Probe Response + * + * @retval TRUE Reply the Probe Response + * @retval FALSE Don't reply the Probe Response + */ +/*---------------------------------------------------------------------------*/ +u_int8_t +p2pFuncValidateProbeReq(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, + OUT uint32_t *pu4ControlFlags, + IN u_int8_t fgIsDevInterface, + IN uint8_t ucRoleIdx) +{ + u_int8_t fgIsReplyProbeRsp = FALSE; + u_int8_t fgApplyp2PDevFilter = FALSE; + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *) NULL; + + DEBUGFUNC("p2pFuncValidateProbeReq"); + + do { + + ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL)); + + prP2pRoleFsmInfo = + prAdapter->rWifiVar.aprP2pRoleFsmInfo[ucRoleIdx]; + + /* Process both cases that with amd without add p2p interface */ + if (fgIsDevInterface) + fgApplyp2PDevFilter = TRUE; + else { + if (prAdapter->prGlueInfo->prP2PInfo[0]->prDevHandler == + prAdapter->prGlueInfo->prP2PInfo + [ucRoleIdx]->aprRoleHandler) + fgApplyp2PDevFilter = TRUE; + else + fgApplyp2PDevFilter = FALSE; + } + /* TODO: */ + if ((fgApplyp2PDevFilter && + (prAdapter->u4OsPacketFilter + & PARAM_PACKET_FILTER_PROBE_REQ)) + || (!fgApplyp2PDevFilter && + (prP2pRoleFsmInfo->u4P2pPacketFilter + & PARAM_PACKET_FILTER_PROBE_REQ))) { + /* Leave the probe response to p2p_supplicant. */ + kalP2PIndicateRxMgmtFrame(prAdapter->prGlueInfo, + prSwRfb, fgIsDevInterface, ucRoleIdx); + } + + } while (FALSE); + + return fgIsReplyProbeRsp; + +} /* end of p2pFuncValidateProbeReq() */ + +static void +p2pFunAbortOngoingScan(IN struct ADAPTER *prAdapter) +{ + struct SCAN_INFO *prScanInfo; + + if (!prAdapter) + return; + + prScanInfo = &(prAdapter->rWifiVar.rScanInfo); + + if (!prScanInfo || (prScanInfo->eCurrentState != SCAN_STATE_SCANNING)) + return; + + if (IS_BSS_INDEX_AIS(prAdapter, + prScanInfo->rScanParam.ucBssIndex)) + aisFsmStateAbort_SCAN(prAdapter, + prScanInfo->rScanParam.ucBssIndex); +} + +static void p2pFunBufferP2pActionFrame(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, + IN uint8_t ucRoleIdx) +{ + struct P2P_DEV_FSM_INFO *prP2pDevFsmInfo = + (struct P2P_DEV_FSM_INFO *) NULL; + struct P2P_QUEUED_ACTION_FRAME *prFrame; + + prP2pDevFsmInfo = prAdapter->rWifiVar.prP2pDevFsmInfo; + + if (prP2pDevFsmInfo == NULL) + return; + + prFrame = &prP2pDevFsmInfo->rQueuedActionFrame; + + if (prFrame->u2Length > 0) { + DBGLOG(P2P, WARN, "p2p action frames are pending, drop it.\n"); + return; + } + + DBGLOG(P2P, INFO, "Buffer the p2p action frame.\n"); + prFrame->ucRoleIdx = ucRoleIdx; + prFrame->u4Freq = nicChannelNum2Freq(prSwRfb->ucChnlNum) / 1000; + prFrame->u2Length = prSwRfb->u2PacketLen; + prFrame->prHeader = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, + prSwRfb->u2PacketLen); + if (prFrame->prHeader == NULL) { + DBGLOG(P2P, WARN, "Allocate buffer fail.\n"); + p2pFunCleanQueuedMgmtFrame(prAdapter, prFrame); + return; + } + kalMemCopy(prFrame->prHeader, prSwRfb->pvHeader, prSwRfb->u2PacketLen); +} + +/*---------------------------------------------------------------------------*/ +/*! + * @brief This function will validate the Rx Probe Request Frame and then return + * result to BSS to indicate if need to send + * the corresponding Probe Response + * Frame if the specified conditions were matched. + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] prSwRfb Pointer to SW RFB data structure. + * @param[out] pu4ControlFlags Control flags for replying the Probe Response + * + * @retval TRUE Reply the Probe Response + * @retval FALSE Don't reply the Probe Response + */ +/*--------------------------------------------------------------------------*/ +void p2pFuncValidateRxActionFrame(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, IN u_int8_t fgIsDevInterface, + IN uint8_t ucRoleIdx) +{ + struct WLAN_ACTION_FRAME *prActFrame; + struct WLAN_PUBLIC_VENDOR_ACTION_FRAME *prActPubVenFrame; + uint32_t u4OUI; + u_int8_t fgBufferFrame = FALSE; + struct P2P_DEV_FSM_INFO *prP2pDevFsmInfo = NULL; + + DEBUGFUNC("p2pFuncValidateRxActionFrame"); + + if (prAdapter == NULL || prSwRfb == NULL) { + DBGLOG(P2P, ERROR, "Invalid parameter.\n"); + return; + } + prActFrame = (struct WLAN_ACTION_FRAME *) prSwRfb->pvHeader; + + prP2pDevFsmInfo = prAdapter->rWifiVar.prP2pDevFsmInfo; + + /* In case channel is not granted yet, we should ignore action + * frames which may come from unexpected channels. + */ + if (fgIsDevInterface && prP2pDevFsmInfo && + prP2pDevFsmInfo->eCurrentState == + P2P_DEV_STATE_REQING_CHANNEL) { + DBGLOG(P2P, INFO, + "ignore rx action frame %d on state:%d\n", + prActFrame->ucCategory, + prP2pDevFsmInfo->eCurrentState); + return; + } + + switch (prActFrame->ucCategory) { + case CATEGORY_PUBLIC_ACTION: + if (prActFrame->ucAction != 0x9 || + prSwRfb->u2PacketLen < + sizeof(struct WLAN_PUBLIC_VENDOR_ACTION_FRAME)) + break; + WLAN_GET_FIELD_BE32(prActFrame->ucActionDetails, &u4OUI); + DBGLOG(P2P, TRACE, "Action: oui: 0x%x\n", u4OUI); + if (u4OUI != P2P_IE_VENDOR_TYPE) + break; + + prActPubVenFrame = + (struct WLAN_PUBLIC_VENDOR_ACTION_FRAME *) + prActFrame; + p2pProcessActionResponse(prAdapter, + prActPubVenFrame->ucPubSubType); + if (prActPubVenFrame->ucPubSubType == P2P_GO_NEG_REQ) + p2pFunAbortOngoingScan(prAdapter); + if (fgIsDevInterface) { + p2pDevFsmNotifyP2pRx(prAdapter, + prActPubVenFrame->ucPubSubType, + &fgBufferFrame); + } + /* Fall through */ + default: + break; + } + + if (fgBufferFrame) { + p2pFunBufferP2pActionFrame(prAdapter, + prSwRfb, + ucRoleIdx); + return; + } + + if (prAdapter->u4OsPacketFilter + & PARAM_PACKET_FILTER_ACTION_FRAME) { + /* Leave the Action frame to p2p_supplicant. */ + kalP2PIndicateRxMgmtFrame(prAdapter->prGlueInfo, + prSwRfb, fgIsDevInterface, ucRoleIdx); + } else { + DBGLOG(P2P, INFO, + "do not indicate action frame as filter closed\n"); + } + + return; + +} /* p2pFuncValidateRxMgmtFrame */ + +u_int8_t p2pFuncIsAPMode(IN struct P2P_CONNECTION_SETTINGS *prP2pConnSettings) +{ + if (prP2pConnSettings) { + if (prP2pConnSettings->fgIsWPSMode == 1) + return FALSE; + return prP2pConnSettings->fgIsApMode; + } else { + return FALSE; + } +} + +/* p2pFuncIsAPMode */ + +void +p2pFuncParseBeaconContent(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prP2pBssInfo, + IN uint8_t *pucIEInfo, IN uint32_t u4IELen) +{ + uint8_t *pucIE = (uint8_t *) NULL; + uint16_t u2Offset = 0; + struct P2P_SPECIFIC_BSS_INFO *prP2pSpecificBssInfo = + (struct P2P_SPECIFIC_BSS_INFO *) NULL; + uint8_t i = 0; + struct RSN_INFO rRsnIe; + + do { + ASSERT_BREAK((prAdapter != NULL) && (prP2pBssInfo != NULL)); + + if (u4IELen == 0) + break; + + prP2pSpecificBssInfo = + prAdapter->rWifiVar.prP2pSpecificBssInfo + [prP2pBssInfo->u4PrivateData]; + prP2pSpecificBssInfo->u2AttributeLen = 0; + prP2pSpecificBssInfo->u2WpaIeLen = 0; + prP2pSpecificBssInfo->u2RsnIeLen = 0; + + ASSERT_BREAK(pucIEInfo != NULL); + + pucIE = pucIEInfo; + + if (prP2pBssInfo->u2CapInfo & CAP_INFO_PRIVACY) + kalP2PSetCipher(prAdapter->prGlueInfo, + IW_AUTH_CIPHER_WEP40, + (uint8_t) prP2pBssInfo->u4PrivateData); + else + kalP2PSetCipher(prAdapter->prGlueInfo, + IW_AUTH_CIPHER_NONE, + (uint8_t) prP2pBssInfo->u4PrivateData); + + prP2pBssInfo->ucCountryIELen = 0; + + IE_FOR_EACH(pucIE, u4IELen, u2Offset) { + switch (IE_ID(pucIE)) { + case ELEM_ID_SSID: /* 0 *//* V *//* Done */ + { + + /* DBGLOG(P2P, TRACE, ("SSID update\n")); */ + /* SSID is saved when start AP/GO */ + /* SSID IE set in beacon from supplicant + * will not always be + * the true since hidden SSID case + */ +#if 0 + COPY_SSID( + prP2pBssInfo->aucSSID, + prP2pBssInfo->ucSSIDLen, + SSID_IE(pucIE)->aucSSID, + SSID_IE(pucIE)->ucLength); + + COPY_SSID( + prP2pSpecificBssInfo->aucGroupSsid, + prP2pSpecificBssInfo->u2GroupSsidLen, + SSID_IE(pucIE)->aucSSID, + SSID_IE(pucIE)->ucLength); +#endif + + } + break; + case ELEM_ID_SUP_RATES: /* 1 *//* V *//* Done */ + { + DBGLOG(P2P, TRACE, "Support Rate IE\n"); + if ((SUP_RATES_IE(pucIE)->ucLength) + > ELEM_MAX_LEN_SUP_RATES) + SUP_RATES_IE(pucIE)->ucLength = + ELEM_MAX_LEN_SUP_RATES; + kalMemCopy( + prP2pBssInfo->aucAllSupportedRates, + SUP_RATES_IE(pucIE)->aucSupportedRates, + SUP_RATES_IE(pucIE)->ucLength); + prP2pBssInfo->ucAllSupportedRatesLen = + SUP_RATES_IE(pucIE)->ucLength; + DBGLOG_MEM8(P2P, TRACE, + SUP_RATES_IE(pucIE)->aucSupportedRates, + SUP_RATES_IE(pucIE)->ucLength); + } + break; + case ELEM_ID_DS_PARAM_SET: /* 3 *//* V *//* Done */ + { + DBGLOG(P2P, TRACE, + "DS PARAM IE: %d.\n", + DS_PARAM_IE(pucIE)->ucCurrChnl); + + /* prP2pBssInfo->ucPrimaryChannel = + * DS_PARAM_IE(pucIE)->ucCurrChnl; + */ + + /* prP2pBssInfo->eBand = BAND_2G4; */ + } + break; + case ELEM_ID_TIM: /* 5 *//* V */ + TIM_IE(pucIE)->ucDTIMPeriod = + prP2pBssInfo->ucDTIMPeriod; + DBGLOG(P2P, TRACE, + "TIM IE, Len:%d, DTIM:%d\n", + IE_LEN(pucIE), + TIM_IE(pucIE)->ucDTIMPeriod); + break; + case ELEM_ID_COUNTRY_INFO: /* 7 */ + if (COUNTRY_IE(pucIE)->ucLength + >= ELEM_MIN_LEN_COUNTRY_INFO) { + prP2pBssInfo->ucCountryIELen = + COUNTRY_IE(pucIE)->ucLength; + kalMemCopy( + prP2pBssInfo->aucCountryStr, + COUNTRY_IE(pucIE)->aucCountryStr, 3); + kalMemCopy( + prP2pBssInfo->aucSubbandTriplet, + COUNTRY_IE(pucIE)->arCountryStr, + COUNTRY_IE(pucIE)->ucLength - 3); + } + break; + case ELEM_ID_ERP_INFO: /* 42 *//* V */ + { +#if 1 + /* This IE would dynamic change due to + * FW detection change is required. + */ + DBGLOG(P2P, TRACE, + "ERP IE will be over write by driver\n"); + DBGLOG(P2P, TRACE, + " ucERP: %x.\n", + ERP_INFO_IE(pucIE)->ucERP); + + prP2pBssInfo->ucPhyTypeSet |= + PHY_TYPE_SET_802_11G; +#else + /* This IE would dynamic change due to + * FW detection change is required. + */ + DBGLOG(P2P, TRACE, "ERP IE.\n"); + + prP2pBssInfo->ucPhyTypeSet |= + PHY_TYPE_SET_802_11GN; + + ASSERT(prP2pBssInfo->eBand == BAND_2G4); + + prP2pBssInfo->fgObssErpProtectMode = + ((ERP_INFO_IE(pucIE)->ucERP + & ERP_INFO_USE_PROTECTION) + ? TRUE : FALSE); + + prP2pBssInfo->fgErpProtectMode = + ((ERP_INFO_IE(pucIE)->ucERP + & (ERP_INFO_USE_PROTECTION | + ERP_INFO_NON_ERP_PRESENT)) + ? TRUE : FALSE); +#endif + + } + break; + case ELEM_ID_HT_CAP: /* 45 *//* V */ + { +#if 1 + DBGLOG(P2P, TRACE, + "HT CAP IE would be overwritten by driver\n"); + + DBGLOG(P2P, TRACE, + "HT Cap Info:%x, AMPDU Param:%x\n", + HT_CAP_IE(pucIE)->u2HtCapInfo, + HT_CAP_IE(pucIE)->ucAmpduParam); + + DBGLOG(P2P, TRACE, + "HT Extended Cap:%x, TX Beamforming Cap:%x, Ant Selection Cap:%x\n", + HT_CAP_IE(pucIE) + ->u2HtExtendedCap, + HT_CAP_IE(pucIE) + ->u4TxBeamformingCap, + HT_CAP_IE(pucIE)->ucAselCap); + + prP2pBssInfo->ucPhyTypeSet |= + PHY_TYPE_SET_802_11N; +#else + prP2pBssInfo->ucPhyTypeSet |= + PHY_TYPE_SET_802_11N; + + /* u2HtCapInfo */ + if ((HT_CAP_IE(pucIE)->u2HtCapInfo & + (HT_CAP_INFO_SUP_CHNL_WIDTH | + HT_CAP_INFO_SHORT_GI_40M | + HT_CAP_INFO_DSSS_CCK_IN_40M)) + == 0) { + prP2pBssInfo + ->fgAssoc40mBwAllowed = + FALSE; + } else { + prP2pBssInfo + ->fgAssoc40mBwAllowed = + TRUE; + } + + if ((HT_CAP_IE(pucIE)->u2HtCapInfo & + (HT_CAP_INFO_SHORT_GI_20M | + HT_CAP_INFO_SHORT_GI_40M)) + == 0) { + prAdapter->rWifiVar + .rConnSettings + .fgRxShortGIDisabled = + TRUE; + } else { + prAdapter->rWifiVar + .rConnSettings + .fgRxShortGIDisabled = + FALSE; + } + + /* ucAmpduParam */ + DBGLOG(P2P, TRACE, + "AMPDU setting from supplicant:0x%x, & default value:0x%x\n", + (uint8_t) + HT_CAP_IE(pucIE)->ucAmpduParam, + (uint8_t) + AMPDU_PARAM_DEFAULT_VAL); + + /* rSupMcsSet */ + /* Can do nothing. + * the field is default value + * from other configuration. + */ + /* HT_CAP_IE(pucIE)->rSupMcsSet; */ + + /* u2HtExtendedCap */ + ASSERT( + HT_CAP_IE(pucIE)->u2HtExtendedCap == + (HT_EXT_CAP_DEFAULT_VAL & + ~(HT_EXT_CAP_PCO | + HT_EXT_CAP_PCO_TRANS_TIME_NONE))); + + /* u4TxBeamformingCap */ + ASSERT( + HT_CAP_IE(pucIE)->u4TxBeamformingCap + == TX_BEAMFORMING_CAP_DEFAULT_VAL); + + /* ucAselCap */ + ASSERT( + HT_CAP_IE(pucIE)->ucAselCap + == ASEL_CAP_DEFAULT_VAL); +#endif + } + break; + case ELEM_ID_RSN: /* 48 *//* V */ + + DBGLOG(P2P, TRACE, "RSN IE\n"); + kalP2PSetCipher(prAdapter->prGlueInfo, + IW_AUTH_CIPHER_CCMP, + (uint8_t) prP2pBssInfo->u4PrivateData); + if (IE_LEN(pucIE) > ELEM_MAX_LEN_RSN) { + DBGLOG(P2P, ERROR, + "RSN IE length is unexpected !!\n"); + return; + } + kalMemCopy(prP2pSpecificBssInfo->aucRsnIeBuffer, + pucIE, IE_SIZE(pucIE)); + prP2pSpecificBssInfo->u2RsnIeLen + = IE_SIZE(pucIE); + if (rsnParseRsnIE(prAdapter, + RSN_IE(pucIE), &rRsnIe)) { + prP2pBssInfo->u4RsnSelectedGroupCipher = + RSN_CIPHER_SUITE_CCMP; + prP2pBssInfo + ->u4RsnSelectedPairwiseCipher = + RSN_CIPHER_SUITE_CCMP; + prP2pBssInfo->u4RsnSelectedAKMSuite = + RSN_AKM_SUITE_PSK; + prP2pBssInfo->u2RsnSelectedCapInfo = + rRsnIe.u2RsnCap; + DBGLOG(RSN, TRACE, + "RsnIe CAP:0x%x\n", + rRsnIe.u2RsnCap); + } + +#if CFG_SUPPORT_802_11W + /* AP PMF */ + prP2pBssInfo->rApPmfCfg.fgMfpc = + (rRsnIe.u2RsnCap + & ELEM_WPA_CAP_MFPC) ? 1 : 0; + prP2pBssInfo->rApPmfCfg.fgMfpr = + (rRsnIe.u2RsnCap + & ELEM_WPA_CAP_MFPR) ? 1 : 0; + prP2pSpecificBssInfo->u4KeyMgtSuiteCount + = (rRsnIe.u4AuthKeyMgtSuiteCount + < P2P_MAX_AKM_SUITES) + ? rRsnIe.u4AuthKeyMgtSuiteCount + : P2P_MAX_AKM_SUITES; + for (i = 0; + i < rRsnIe.u4AuthKeyMgtSuiteCount; + i++) { + if ((rRsnIe.au4AuthKeyMgtSuite[i] + == RSN_AKM_SUITE_PSK_SHA256) || + (rRsnIe.au4AuthKeyMgtSuite[i] + == RSN_AKM_SUITE_802_1X_SHA256)) { + DBGLOG(RSN, INFO, + "SHA256 support\n"); + /* over-write + * u4RsnSelectedAKMSuite + * by SHA256 AKM + */ + prP2pBssInfo + ->u4RsnSelectedAKMSuite + = rRsnIe.au4AuthKeyMgtSuite[i]; + prP2pBssInfo + ->rApPmfCfg.fgSha256 + = TRUE; + break; + } else if (rRsnIe.au4AuthKeyMgtSuite[i] + == RSN_AKM_SUITE_SAE) + prP2pBssInfo + ->u4RsnSelectedAKMSuite + = rRsnIe.au4AuthKeyMgtSuite[i]; + + if (i < P2P_MAX_AKM_SUITES) { + prP2pSpecificBssInfo + ->au4KeyMgtSuite[i] + = rRsnIe.au4AuthKeyMgtSuite[i]; + } + } + DBGLOG(RSN, ERROR, + "bcn mfpc:%d, mfpr:%d, sha256:%d, 0x%04x\n", + prP2pBssInfo->rApPmfCfg.fgMfpc, + prP2pBssInfo->rApPmfCfg.fgMfpr, + prP2pBssInfo->rApPmfCfg.fgSha256, + prP2pBssInfo->u4RsnSelectedAKMSuite); +#endif + + break; + case ELEM_ID_EXTENDED_SUP_RATES: /* 50 *//* V */ + /* ELEM_ID_SUP_RATES should be placed + * before ELEM_ID_EXTENDED_SUP_RATES. + */ + DBGLOG(P2P, TRACE, "Ex Support Rate IE\n"); + kalMemCopy(& + (prP2pBssInfo->aucAllSupportedRates + [prP2pBssInfo->ucAllSupportedRatesLen]), + EXT_SUP_RATES_IE(pucIE) + ->aucExtSupportedRates, + EXT_SUP_RATES_IE(pucIE) + ->ucLength); + + DBGLOG_MEM8(P2P, TRACE, + EXT_SUP_RATES_IE(pucIE) + ->aucExtSupportedRates, + EXT_SUP_RATES_IE(pucIE) + ->ucLength); + + prP2pBssInfo->ucAllSupportedRatesLen += + EXT_SUP_RATES_IE(pucIE)->ucLength; + break; + case ELEM_ID_HT_OP: + /* 61 *//* V *//* TODO: */ + { +#if 1 + DBGLOG(P2P, TRACE, + "HT OP IE would be overwritten by driver\n"); + + DBGLOG(P2P, TRACE, + " Primary Channel: %x, Info1: %x, Info2: %x, Info3: %x\n", + HT_OP_IE(pucIE) + ->ucPrimaryChannel, + HT_OP_IE(pucIE)->ucInfo1, + HT_OP_IE(pucIE)->u2Info2, + HT_OP_IE(pucIE)->u2Info3); + + prP2pBssInfo->ucPhyTypeSet |= + PHY_TYPE_SET_802_11N; +#else + uint16_t u2Info2 = 0; + + prP2pBssInfo->ucPhyTypeSet |= + PHY_TYPE_SET_802_11N; + + DBGLOG(P2P, TRACE, "HT OP IE\n"); + + /* ucPrimaryChannel. */ + ASSERT( + HT_OP_IE(pucIE)->ucPrimaryChannel + == prP2pBssInfo->ucPrimaryChannel); + + /* ucInfo1 */ + prP2pBssInfo->ucHtOpInfo1 = + HT_OP_IE(pucIE)->ucInfo1; + + /* u2Info2 */ + u2Info2 = HT_OP_IE(pucIE)->u2Info2; + + if (u2Info2 + & HT_OP_INFO2_NON_GF_HT_STA_PRESENT) { + ASSERT( + prP2pBssInfo->eGfOperationMode + != GF_MODE_NORMAL); + u2Info2 &= + ~HT_OP_INFO2_NON_GF_HT_STA_PRESENT; + } + + if (u2Info2 + & HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT) { + prP2pBssInfo->eObssHtProtectMode = + HT_PROTECT_MODE_NON_MEMBER; + u2Info2 &= + ~HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT; + } + + switch (u2Info2 + & HT_OP_INFO2_HT_PROTECTION) { + case HT_PROTECT_MODE_NON_HT: + prP2pBssInfo->eHtProtectMode = + HT_PROTECT_MODE_NON_HT; + break; + case HT_PROTECT_MODE_NON_MEMBER: + prP2pBssInfo->eHtProtectMode = + HT_PROTECT_MODE_NONE; + prP2pBssInfo + ->eObssHtProtectMode = + HT_PROTECT_MODE_NON_MEMBER; + break; + default: + prP2pBssInfo->eHtProtectMode = + HT_OP_IE(pucIE)->u2Info2; + break; + } + + /* u2Info3 */ + prP2pBssInfo->u2HtOpInfo3 = + HT_OP_IE(pucIE)->u2Info3; + + /* aucBasicMcsSet */ + DBGLOG_MEM8(P2P, TRACE, + HT_OP_IE(pucIE)->aucBasicMcsSet, 16); +#endif + } + break; + case ELEM_ID_OBSS_SCAN_PARAMS: /* 74 *//* V */ + { + DBGLOG(P2P, TRACE, + "ELEM_ID_OBSS_SCAN_PARAMS IE would be replaced by driver\n"); + } + break; + case ELEM_ID_EXTENDED_CAP: /* 127 *//* V */ + { + DBGLOG(P2P, TRACE, + "ELEM_ID_EXTENDED_CAP IE would be replaced by driver\n"); + } + break; + case ELEM_ID_VENDOR: /* 221 *//* V */ + DBGLOG(P2P, TRACE, "Vender Specific IE\n"); + { + p2pFuncParseBeaconVenderId(prAdapter, + pucIE, prP2pSpecificBssInfo, + (uint8_t) + prP2pBssInfo->u4PrivateData); + /* TODO: Store other Vender IE + * except for WMM Param. + */ + } + break; + case ELEM_ID_VHT_CAP: + prP2pBssInfo->ucPhyTypeSet |= + PHY_TYPE_SET_802_11AC; + break; + case ELEM_ID_VHT_OP: + prP2pBssInfo->ucPhyTypeSet |= + PHY_TYPE_SET_802_11AC; + break; +#if (CFG_SUPPORT_802_11AX == 1) + case ELEM_ID_RESERVED: + if (IE_ID_EXT(pucIE) == ELEM_EXT_ID_HE_CAP) + prP2pBssInfo->ucPhyTypeSet |= + PHY_TYPE_SET_802_11AX; + break; +#endif + default: + DBGLOG(P2P, TRACE, + "Unprocessed element ID:%d\n", + IE_ID(pucIE)); + break; + } + } + + } while (FALSE); +} /* p2pFuncParseBeaconContent */ + +/* Code refactoring for AOSP */ +static void +p2pFuncParseBeaconVenderId(IN struct ADAPTER *prAdapter, + IN uint8_t *pucIE, + IN struct P2P_SPECIFIC_BSS_INFO *prP2pSpecificBssInfo, + IN uint8_t ucRoleIndex) +{ + do { + uint8_t ucOuiType; + uint16_t u2SubTypeVersion; + + if (rsnParseCheckForWFAInfoElem( + prAdapter, pucIE, &ucOuiType, &u2SubTypeVersion)) { + if ((ucOuiType == VENDOR_OUI_TYPE_WPA) + && (u2SubTypeVersion == VERSION_WPA)) { + if (!kalP2PGetCcmpCipher(prAdapter->prGlueInfo, + ucRoleIndex)) + kalP2PSetCipher(prAdapter->prGlueInfo, + IW_AUTH_CIPHER_TKIP, + ucRoleIndex); + if (IE_LEN(pucIE) > ELEM_MAX_LEN_WPA) { + DBGLOG(P2P, ERROR, + "WPA IE length is unexpected !!\n"); + return; + } + kalMemCopy( + prP2pSpecificBssInfo + ->aucWpaIeBuffer, + pucIE, IE_SIZE(pucIE)); + prP2pSpecificBssInfo->u2WpaIeLen = + IE_SIZE(pucIE); + DBGLOG(P2P, TRACE, "WPA IE in supplicant\n"); + } else if (ucOuiType == VENDOR_OUI_TYPE_WPS) { + kalP2PUpdateWSC_IE(prAdapter->prGlueInfo, + 0, pucIE, IE_SIZE(pucIE), ucRoleIndex); + DBGLOG(P2P, TRACE, "WPS IE in supplicant\n"); + } else if (ucOuiType == VENDOR_OUI_TYPE_WMM) { + DBGLOG(P2P, TRACE, "WMM IE in supplicant\n"); + } + /* WMM here. */ + } else if (p2pFuncParseCheckForP2PInfoElem( + prAdapter, pucIE, &ucOuiType)) { + /* TODO Store the whole P2P IE & generate later. */ + /* Be aware that there may be one or more P2P IE. */ + if (ucOuiType == VENDOR_OUI_TYPE_P2P) { + kalMemCopy(&prP2pSpecificBssInfo + ->aucAttributesCache + [prP2pSpecificBssInfo->u2AttributeLen], + pucIE, IE_SIZE(pucIE)); + prP2pSpecificBssInfo->u2AttributeLen += + IE_SIZE(pucIE); + DBGLOG(P2P, TRACE, "P2P IE in supplicant\n"); + } else if (ucOuiType == VENDOR_OUI_TYPE_WFD) { + + kalMemCopy(&prP2pSpecificBssInfo + ->aucAttributesCache + [prP2pSpecificBssInfo->u2AttributeLen], + pucIE, IE_SIZE(pucIE)); + + prP2pSpecificBssInfo->u2AttributeLen += + IE_SIZE(pucIE); + } else { + DBGLOG(P2P, TRACE, + "Unknown 50-6F-9A-%d IE.\n", + ucOuiType); + } + } else { + kalMemCopy(&prP2pSpecificBssInfo->aucAttributesCache + [prP2pSpecificBssInfo->u2AttributeLen], + pucIE, IE_SIZE(pucIE)); + + prP2pSpecificBssInfo->u2AttributeLen += + IE_SIZE(pucIE); + DBGLOG(P2P, TRACE, + "Driver unprocessed Vender Specific IE\n"); + } + } while (0); +} + +struct BSS_DESC * +p2pFuncKeepOnConnection(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo, + IN struct P2P_CONNECTION_REQ_INFO *prConnReqInfo, + IN struct P2P_CHNL_REQ_INFO *prChnlReqInfo, + IN struct P2P_SCAN_REQ_INFO *prScanReqInfo) +{ + struct BSS_DESC *prTargetBss = (struct BSS_DESC *) NULL; + + do { + ASSERT_BREAK((prAdapter != NULL) && (prBssInfo != NULL) && + (prConnReqInfo != NULL) && (prChnlReqInfo != NULL) && + (prScanReqInfo != NULL)); + + if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) + break; + /* Update connection request information. */ + ASSERT(prConnReqInfo->eConnRequest == P2P_CONNECTION_TYPE_GC); + + /* Find BSS Descriptor first. */ + prTargetBss = scanP2pSearchDesc(prAdapter, prConnReqInfo); + + if (prTargetBss == NULL) { + /* Update scan parameter... to scan target device. */ + /* TODO: Need refine. */ + prScanReqInfo->ucNumChannelList = 1; + prScanReqInfo->eScanType = SCAN_TYPE_ACTIVE_SCAN; + prScanReqInfo->eChannelSet = SCAN_CHANNEL_FULL; + /* Prevent other P2P ID in IE. */ + prScanReqInfo->u4BufLength = 0; + prScanReqInfo->fgIsAbort = TRUE; + } else { + prChnlReqInfo->u8Cookie = 0; + prChnlReqInfo->ucReqChnlNum = prTargetBss->ucChannelNum; + prChnlReqInfo->eBand = prTargetBss->eBand; + prChnlReqInfo->eChnlSco = prTargetBss->eSco; + prChnlReqInfo->u4MaxInterval = + AIS_JOIN_CH_REQUEST_INTERVAL; + prChnlReqInfo->eChnlReqType = CH_REQ_TYPE_JOIN; + + prChnlReqInfo->eChannelWidth = + prTargetBss->eChannelWidth; + prChnlReqInfo->ucCenterFreqS1 = + prTargetBss->ucCenterFreqS1; + prChnlReqInfo->ucCenterFreqS2 = + prTargetBss->ucCenterFreqS2; + } + + } while (FALSE); + + return prTargetBss; +} /* p2pFuncKeepOnConnection */ + +/* Currently Only for ASSOC Response Frame. */ +void p2pFuncStoreAssocRspIEBuffer(IN struct ADAPTER *prAdapter, + IN struct P2P_JOIN_INFO *prP2pJoinInfo, + IN struct SW_RFB *prSwRfb) +{ + struct WLAN_ASSOC_RSP_FRAME *prAssocRspFrame = + (struct WLAN_ASSOC_RSP_FRAME *) NULL; + int16_t i2IELen = 0; + + do { + ASSERT_BREAK((prAdapter != NULL) + && (prP2pJoinInfo != NULL) && (prSwRfb != NULL)); + + prAssocRspFrame = + (struct WLAN_ASSOC_RSP_FRAME *) prSwRfb->pvHeader; + + if (prAssocRspFrame->u2FrameCtrl != MAC_FRAME_ASSOC_RSP) + break; + + i2IELen = prSwRfb->u2PacketLen - + (WLAN_MAC_HEADER_LEN + + CAP_INFO_FIELD_LEN + + STATUS_CODE_FIELD_LEN + AID_FIELD_LEN); + + if (i2IELen <= 0) + break; + + prP2pJoinInfo->u4BufLength = (uint32_t) i2IELen; + + kalMemCopy(prP2pJoinInfo->aucIEBuf, + prAssocRspFrame->aucInfoElem, + prP2pJoinInfo->u4BufLength); + + } while (FALSE); +} /* p2pFuncStoreAssocRspIEBuffer */ + +/*---------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set Packet Filter. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] pvSetBuffer Pointer to the buffer + * that holds the data to be set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + * \retval WLAN_STATUS_NOT_SUPPORTED + * \retval WLAN_STATUS_ADAPTER_NOT_READY + */ +/*---------------------------------------------------------------------------*/ +void +p2pFuncMgmtFrameRegister(IN struct ADAPTER *prAdapter, + IN uint16_t u2FrameType, + IN u_int8_t fgIsRegistered, + OUT uint32_t *pu4P2pPacketFilter) +{ + uint32_t u4NewPacketFilter = 0; + struct CMD_RX_PACKET_FILTER rSetRxPacketFilter; + + DEBUGFUNC("p2pFuncMgmtFrameRegister"); + + do { + ASSERT_BREAK(prAdapter != NULL); + + if (pu4P2pPacketFilter) + u4NewPacketFilter = *pu4P2pPacketFilter; + + switch (u2FrameType) { + case MAC_FRAME_PROBE_REQ: + if (fgIsRegistered) { + u4NewPacketFilter |= + PARAM_PACKET_FILTER_PROBE_REQ; + DBGLOG(P2P, TRACE, + "Open packet filer probe request\n"); + } else { + u4NewPacketFilter &= + ~PARAM_PACKET_FILTER_PROBE_REQ; + DBGLOG(P2P, TRACE, + "Close packet filer probe request\n"); + } + break; + case MAC_FRAME_ACTION: + if (fgIsRegistered) { + u4NewPacketFilter |= + PARAM_PACKET_FILTER_ACTION_FRAME; + DBGLOG(P2P, TRACE, + "Open packet filer action frame.\n"); + } else { + u4NewPacketFilter &= + ~PARAM_PACKET_FILTER_ACTION_FRAME; + DBGLOG(P2P, TRACE, + "Close packet filer action frame.\n"); + } + break; + default: + DBGLOG(P2P, TRACE, + "Ask frog to add code for mgmt:%x\n", + u2FrameType); + break; + } + + if (pu4P2pPacketFilter) + *pu4P2pPacketFilter = u4NewPacketFilter; + + /* u4NewPacketFilter |= prAdapter->u4OsPacketFilter; */ + + prAdapter->u4OsPacketFilter &= ~PARAM_PACKET_FILTER_P2P_MASK; + prAdapter->u4OsPacketFilter |= u4NewPacketFilter; + + DBGLOG(P2P, TRACE, + "P2P Set PACKET filter:0x%x\n", + prAdapter->u4OsPacketFilter); + + rSetRxPacketFilter.u4RxPacketFilter = + prAdapter->u4OsPacketFilter; + wlanoidSetPacketFilter(prAdapter, + &rSetRxPacketFilter, + FALSE, + &u4NewPacketFilter, + sizeof(u4NewPacketFilter)); + + } while (FALSE); +} /* p2pFuncMgmtFrameRegister */ + +void p2pFuncUpdateMgmtFrameRegister(IN struct ADAPTER *prAdapter, + IN uint32_t u4OsFilter) +{ + struct CMD_RX_PACKET_FILTER rSetRxPacketFilter; + + do { + + /* TODO: Filter need to be done. */ + /* prAdapter->rWifiVar + * .prP2pFsmInfo->u4P2pPacketFilter = u4OsFilter; + */ + + if ((prAdapter->u4OsPacketFilter + & PARAM_PACKET_FILTER_P2P_MASK) ^ u4OsFilter) { + + prAdapter->u4OsPacketFilter &= + ~PARAM_PACKET_FILTER_P2P_MASK; + + prAdapter->u4OsPacketFilter |= + (u4OsFilter & PARAM_PACKET_FILTER_P2P_MASK); + + rSetRxPacketFilter.u4RxPacketFilter = + prAdapter->u4OsPacketFilter; + wlanoidSetPacketFilter(prAdapter, + &rSetRxPacketFilter, + FALSE, + &u4OsFilter, + sizeof(u4OsFilter)); + DBGLOG(P2P, TRACE, + "P2P Set PACKET filter:0x%x\n", + prAdapter->u4OsPacketFilter); + } + + } while (FALSE); +} /* p2pFuncUpdateMgmtFrameRegister */ + +void p2pFuncGetStationInfo(IN struct ADAPTER *prAdapter, + IN uint8_t *pucMacAddr, + OUT struct P2P_STATION_INFO *prStaInfo) +{ + + do { + ASSERT_BREAK((prAdapter != NULL) + && (pucMacAddr != NULL) && (prStaInfo != NULL)); + + prStaInfo->u4InactiveTime = 0; + prStaInfo->u4RxBytes = 0; + prStaInfo->u4TxBytes = 0; + prStaInfo->u4RxPackets = 0; + prStaInfo->u4TxPackets = 0; + /* TODO: */ + + } while (FALSE); +} /* p2pFuncGetStationInfo */ + +#if 0 +u_int8_t +p2pFuncGetAttriList(IN struct ADAPTER *prAdapter, + IN uint8_t ucOuiType, + IN uint8_t *pucIE, + IN uint16_t u2IELength, + OUT uint8_t **ppucAttriList, + OUT uint16_t *pu2AttriListLen) +{ + u_int8_t fgIsAllocMem = FALSE; + uint8_t aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC; + uint16_t u2Offset = 0; + struct IE_P2P *prIe = (struct IE_P2P *) NULL; + uint8_t *pucAttriListStart = (uint8_t *) NULL; + uint16_t u2AttriListLen = 0, u2BufferSize; + u_int8_t fgBackupAttributes = FALSE; + + u2BufferSize = 0; + + do { + ASSERT_BREAK((prAdapter != NULL) && + (pucIE != NULL) && + (u2IELength != 0) && + (ppucAttriList != NULL) && + (pu2AttriListLen != NULL)); + + if (ppucAttriList) + *ppucAttriList = NULL; + if (pu2AttriListLen) + *pu2AttriListLen = 0; + + if (ucOuiType == VENDOR_OUI_TYPE_WPS) { + aucWfaOui[0] = 0x00; + aucWfaOui[1] = 0x50; + aucWfaOui[2] = 0xF2; + } else if ((ucOuiType != VENDOR_OUI_TYPE_P2P) +#if CFG_SUPPORT_WFD + && (ucOuiType != VENDOR_OUI_TYPE_WFD) +#endif + ) { + DBGLOG(P2P, INFO, + "Not supported OUI Type to parsing 0x%x\n", + ucOuiType); + break; + } + + IE_FOR_EACH(pucIE, u2IELength, u2Offset) { + if (IE_ID(pucIE) == ELEM_ID_VENDOR) { + prIe = (struct IE_P2P *) pucIE; + + if (prIe->ucLength <= P2P_OUI_TYPE_LEN) + continue; + + if ((prIe->aucOui[0] == aucWfaOui[0]) && + (prIe->aucOui[1] == aucWfaOui[1]) && + (prIe->aucOui[2] == aucWfaOui[2]) && + (ucOuiType == prIe->ucOuiType)) { + p2pFuncGetAttriListAction(prAdapter, + prIe, ucOuiType, + &pucAttriListStart, + &u2AttriListLen, + &fgIsAllocMem, + &fgBackupAttributes, + &u2BufferSize); + } /* prIe->aucOui */ + } /* ELEM_ID_VENDOR */ + } /* IE_FOR_EACH */ + + } while (FALSE); + + if (pucAttriListStart) { + uint8_t *pucAttribute = pucAttriListStart; + + DBGLOG(P2P, LOUD, "Checking Attribute Length.\n"); + if (ucOuiType == VENDOR_OUI_TYPE_P2P) { + P2P_ATTRI_FOR_EACH(pucAttribute, + u2AttriListLen, u2Offset); + } else if (ucOuiType == VENDOR_OUI_TYPE_WFD) { + /* Todo:: Nothing */ + } else if (ucOuiType == VENDOR_OUI_TYPE_WPS) { + /* Big Endian: WSC, WFD. */ + WSC_ATTRI_FOR_EACH(pucAttribute, + u2AttriListLen, u2Offset) { + DBGLOG(P2P, LOUD, + "Attribute ID:%d, Length:%d.\n", + WSC_ATTRI_ID(pucAttribute), + WSC_ATTRI_LEN(pucAttribute)); + } + } else { + } + + ASSERT(u2Offset == u2AttriListLen); + + *ppucAttriList = pucAttriListStart; + *pu2AttriListLen = u2AttriListLen; + + } else { + *ppucAttriList = (uint8_t *) NULL; + *pu2AttriListLen = 0; + } + + return fgIsAllocMem; +} /* p2pFuncGetAttriList */ + +/* Code refactoring for AOSP */ +static void +p2pFuncGetAttriListAction(IN struct ADAPTER *prAdapter, + IN struct IE_P2P *prIe, + IN uint8_t ucOuiType, + OUT uint8_t **pucAttriListStart, + OUT uint16_t *u2AttriListLen, + OUT u_int8_t *fgIsAllocMem, + OUT u_int8_t *fgBackupAttributes, + OUT uint16_t *u2BufferSize) +{ + do { + if (!(*pucAttriListStart)) { + *pucAttriListStart = &prIe->aucP2PAttributes[0]; + if (prIe->ucLength > P2P_OUI_TYPE_LEN) + *u2AttriListLen = + (uint16_t) + (prIe->ucLength - P2P_OUI_TYPE_LEN); + else + ASSERT(FALSE); + } else { + /* More than 2 attributes. */ + uint16_t u2CopyLen; + + if (*fgBackupAttributes == FALSE) { + struct P2P_SPECIFIC_BSS_INFO + *prP2pSpecificBssInfo = + prAdapter->rWifiVar.prP2pSpecificBssInfo; + + *fgBackupAttributes = TRUE; + if (ucOuiType == VENDOR_OUI_TYPE_P2P) { + kalMemCopy(&prP2pSpecificBssInfo + ->aucAttributesCache[0], + *pucAttriListStart, *u2AttriListLen); + + *pucAttriListStart = + &prP2pSpecificBssInfo + ->aucAttributesCache[0]; + *u2BufferSize = + P2P_MAXIMUM_ATTRIBUTE_LEN; + } else if (ucOuiType == VENDOR_OUI_TYPE_WPS) { + kalMemCopy(&prP2pSpecificBssInfo + ->aucWscAttributesCache[0], + *pucAttriListStart, *u2AttriListLen); + *pucAttriListStart = + &prP2pSpecificBssInfo + ->aucWscAttributesCache[0]; + *u2BufferSize = + WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE; + } +#if CFG_SUPPORT_WFD + else if (ucOuiType == VENDOR_OUI_TYPE_WFD) { + uint8_t *pucTmpBuf = (uint8_t *) NULL; + + pucTmpBuf = (uint8_t *) kalMemAlloc + (WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE, + VIR_MEM_TYPE); + + if (pucTmpBuf != NULL) { + *fgIsAllocMem = TRUE; + } else { + /* Can't alloca memory + * for WFD IE relocate. + */ + ASSERT(FALSE); + break; + } + + kalMemCopy(pucTmpBuf, + *pucAttriListStart, + *u2AttriListLen); + *pucAttriListStart = pucTmpBuf; + *u2BufferSize = + WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE; + } +#endif + else + *fgBackupAttributes = FALSE; + } + u2CopyLen = + (uint16_t) (prIe->ucLength - P2P_OUI_TYPE_LEN); + + if (((*u2AttriListLen) + u2CopyLen) > (*u2BufferSize)) { + u2CopyLen = (*u2BufferSize) - (*u2AttriListLen); + DBGLOG(P2P, WARN, + "Length of received P2P attributes > maximum cache size.\n"); + } + + if (u2CopyLen) { + kalMemCopy((uint8_t *) + ((unsigned long) (*pucAttriListStart) + + (unsigned long) (*u2AttriListLen)), + &prIe->aucP2PAttributes[0], u2CopyLen); + *u2AttriListLen += u2CopyLen; + } + + } + } while (0); +} +#endif + +struct MSDU_INFO *p2pFuncProcessP2pProbeRsp(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIdx, IN struct MSDU_INFO *prMgmtTxMsdu) +{ + struct MSDU_INFO *prRetMsduInfo = prMgmtTxMsdu; + struct WLAN_BEACON_FRAME *prProbeRspFrame = + (struct WLAN_BEACON_FRAME *) NULL; + uint8_t *pucIEBuf = (uint8_t *) NULL; + uint16_t u2Offset = 0, u2IELength = 0, u2ProbeRspHdrLen = 0; + u_int8_t fgIsWSCIE = FALSE; + u_int8_t fgIsWFDIE = FALSE; + u_int8_t fgIsVenderIE = FALSE; + struct BSS_INFO *prP2pBssInfo = (struct BSS_INFO *) NULL; + uint16_t u2EstimateSize = 0, u2EstimatedExtraIELen = 0; + uint32_t u4IeArraySize = 0, u4Idx = 0; + u_int8_t u4P2PIEIdx = 0; + + do { + ASSERT_BREAK((prAdapter != NULL) && (prMgmtTxMsdu != NULL)); + + prP2pBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIdx); + + /* 3 Make sure this is probe response frame. */ + prProbeRspFrame = (struct WLAN_BEACON_FRAME *) + ((unsigned long) prMgmtTxMsdu->prPacket + + MAC_TX_RESERVED_FIELD); + ASSERT_BREAK((prProbeRspFrame->u2FrameCtrl & MASK_FRAME_TYPE) + == MAC_FRAME_PROBE_RSP); + + /* 3 Get the importent P2P IE. */ + u2ProbeRspHdrLen = + (WLAN_MAC_MGMT_HEADER_LEN + + TIMESTAMP_FIELD_LEN + + BEACON_INTERVAL_FIELD_LEN + + CAP_INFO_FIELD_LEN); + pucIEBuf = prProbeRspFrame->aucInfoElem; + u2IELength = prMgmtTxMsdu->u2FrameLength - u2ProbeRspHdrLen; + +#if 0 /*CFG_SUPPORT_WFD*/ + /* Reset in each time ?? */ + prAdapter->prGlueInfo + ->prP2PInfo[prP2pBssInfo->u4PrivateData] + ->u2WFDIELen = 0; +#endif +#if CFG_SUPPORT_CUSTOM_VENDOR_IE + prAdapter->prGlueInfo + ->prP2PInfo[prP2pBssInfo->u4PrivateData] + ->u2VenderIELen = 0; +#endif + + + IE_FOR_EACH(pucIEBuf, u2IELength, u2Offset) { + switch (IE_ID(pucIEBuf)) { + case ELEM_ID_SSID: + { + p2pFuncProcessP2pProbeRspAction( + prAdapter, + pucIEBuf, ELEM_ID_SSID, + &ucBssIdx, + &prP2pBssInfo, + &fgIsWSCIE, + &u4P2PIEIdx, + &fgIsWFDIE, + &fgIsVenderIE); + } + break; + case ELEM_ID_VENDOR: + { + p2pFuncProcessP2pProbeRspAction( + prAdapter, + pucIEBuf, ELEM_ID_VENDOR, + &ucBssIdx, + &prP2pBssInfo, + &fgIsWSCIE, + &u4P2PIEIdx, + &fgIsWFDIE, + &fgIsVenderIE); + } + break; + default: + break; + } + + } + + /* 3 Check the total size & current frame. */ + u2EstimateSize = WLAN_MAC_MGMT_HEADER_LEN + + TIMESTAMP_FIELD_LEN + + BEACON_INTERVAL_FIELD_LEN + + CAP_INFO_FIELD_LEN + + (ELEM_HDR_LEN + ELEM_MAX_LEN_SSID) + + (ELEM_HDR_LEN + ELEM_MAX_LEN_SUP_RATES) + + (ELEM_HDR_LEN + ELEM_MAX_LEN_DS_PARAMETER_SET); + + u2EstimatedExtraIELen = 0; + + u4IeArraySize = + sizeof(txProbeRspIETable) / + sizeof(struct APPEND_VAR_IE_ENTRY); + for (u4Idx = 0; u4Idx < u4IeArraySize; u4Idx++) { + if (txProbeRspIETable[u4Idx].u2EstimatedFixedIELen) { + u2EstimatedExtraIELen += + txProbeRspIETable[u4Idx] + .u2EstimatedFixedIELen; + } + + else { + ASSERT(txProbeRspIETable[u4Idx] + .pfnCalculateVariableIELen); + + u2EstimatedExtraIELen += + (uint16_t) ( + txProbeRspIETable[u4Idx] + .pfnCalculateVariableIELen( + prAdapter, + ucBssIdx, NULL)); + } + + } + + if (fgIsWSCIE) + u2EstimatedExtraIELen += + kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 2, + (uint8_t) prP2pBssInfo->u4PrivateData); + + if (u4P2PIEIdx > 0) { + for (u4Idx = 0; u4Idx < u4P2PIEIdx; u4Idx++) + u2EstimatedExtraIELen += + kalP2PCalP2P_IELen( + prAdapter->prGlueInfo, + u4Idx, + (uint8_t) + prP2pBssInfo->u4PrivateData); + u2EstimatedExtraIELen += + p2pFuncCalculateP2P_IE_NoA(prAdapter, + ucBssIdx, NULL); + } +#if CFG_SUPPORT_WFD + ASSERT(sizeof(prAdapter->prGlueInfo + ->prP2PInfo[prP2pBssInfo->u4PrivateData]->aucWFDIE) + >= + prAdapter->prGlueInfo + ->prP2PInfo[prP2pBssInfo->u4PrivateData]->u2WFDIELen); + + if (fgIsWFDIE) + u2EstimatedExtraIELen += + prAdapter->prGlueInfo + ->prP2PInfo[prP2pBssInfo->u4PrivateData] + ->u2WFDIELen; +#endif +#if CFG_SUPPORT_CUSTOM_VENDOR_IE + if (fgIsVenderIE) + u2EstimatedExtraIELen += + prAdapter->prGlueInfo + ->prP2PInfo[prP2pBssInfo->u4PrivateData] + ->u2VenderIELen; +#endif + + u2EstimateSize += u2EstimatedExtraIELen; + if ((u2EstimateSize) > (prRetMsduInfo->u2FrameLength)) { + /* add sizeof(UINT_64) for Cookie */ + prRetMsduInfo = cnmMgtPktAlloc(prAdapter, + u2EstimateSize + sizeof(uint64_t)); + + if (prRetMsduInfo == NULL) { + DBGLOG(P2P, WARN, + "No packet for sending new probe response, use original one\n"); + prRetMsduInfo = prMgmtTxMsdu; + break; + } + + } + + prRetMsduInfo->ucBssIndex = ucBssIdx; + + /* 3 Compose / Re-compose probe response frame. */ + bssComposeBeaconProbeRespFrameHeaderAndFF((uint8_t *) + ((unsigned long) (prRetMsduInfo->prPacket) + + MAC_TX_RESERVED_FIELD), + prProbeRspFrame->aucDestAddr, + prProbeRspFrame->aucSrcAddr, + prProbeRspFrame->aucBSSID, + prProbeRspFrame->u2BeaconInterval, + prProbeRspFrame->u2CapInfo); + + prRetMsduInfo->u2FrameLength = + (WLAN_MAC_MGMT_HEADER_LEN + + TIMESTAMP_FIELD_LEN + + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN); + + bssBuildBeaconProbeRespFrameCommonIEs(prRetMsduInfo, + prP2pBssInfo, prProbeRspFrame->aucDestAddr); + + prRetMsduInfo->ucStaRecIndex = prMgmtTxMsdu->ucStaRecIndex; + + for (u4Idx = 0; u4Idx < u4IeArraySize; u4Idx++) { + if (txProbeRspIETable[u4Idx].pfnAppendIE) + txProbeRspIETable[u4Idx] + .pfnAppendIE(prAdapter, prRetMsduInfo); + + } + + if (fgIsWSCIE) { + kalP2PGenWSC_IE(prAdapter->prGlueInfo, + 2, + (uint8_t *) + ((unsigned long) prRetMsduInfo->prPacket + + (unsigned long) prRetMsduInfo->u2FrameLength), + (uint8_t) prP2pBssInfo->u4PrivateData); + + prRetMsduInfo->u2FrameLength += (uint16_t) + kalP2PCalWSC_IELen(prAdapter->prGlueInfo, + 2, + (uint8_t) prP2pBssInfo->u4PrivateData); + } + + if (u4P2PIEIdx > 0) { + for (u4Idx = 0; u4Idx < u4P2PIEIdx; u4Idx++) { + kalP2PGenP2P_IE(prAdapter->prGlueInfo, + u4Idx, + (uint8_t *) + ((unsigned long) + prRetMsduInfo->prPacket + + (unsigned long) + prRetMsduInfo->u2FrameLength), + (uint8_t) prP2pBssInfo->u4PrivateData); + + prRetMsduInfo->u2FrameLength += + (uint16_t) + kalP2PCalP2P_IELen( + prAdapter->prGlueInfo, + u4Idx, + (uint8_t) prP2pBssInfo->u4PrivateData); + } + p2pFuncGenerateP2P_IE_NoA(prAdapter, prRetMsduInfo); + + } +#if CFG_SUPPORT_WFD + if (fgIsWFDIE > 0) { + ASSERT(prAdapter->prGlueInfo + ->prP2PInfo[prP2pBssInfo->u4PrivateData] + ->u2WFDIELen > 0); + kalMemCopy((uint8_t *) + ((unsigned long) prRetMsduInfo->prPacket + + (unsigned long) prRetMsduInfo->u2FrameLength), + prAdapter->prGlueInfo->prP2PInfo + [prP2pBssInfo->u4PrivateData]->aucWFDIE, + prAdapter->prGlueInfo->prP2PInfo + [prP2pBssInfo->u4PrivateData] + ->u2WFDIELen); + prRetMsduInfo->u2FrameLength += + (uint16_t) prAdapter->prGlueInfo + ->prP2PInfo[prP2pBssInfo->u4PrivateData] + ->u2WFDIELen; + + } +#endif /* CFG_SUPPORT_WFD */ +#if CFG_SUPPORT_CUSTOM_VENDOR_IE + if (fgIsVenderIE && + prAdapter->prGlueInfo + ->prP2PInfo[prP2pBssInfo->u4PrivateData] + ->u2VenderIELen > 0) { + kalMemCopy((uint8_t *) + ((unsigned long) prRetMsduInfo->prPacket + + (unsigned long) prRetMsduInfo->u2FrameLength), + prAdapter->prGlueInfo->prP2PInfo + [prP2pBssInfo->u4PrivateData] + ->aucVenderIE, + prAdapter->prGlueInfo->prP2PInfo + [prP2pBssInfo->u4PrivateData] + ->u2VenderIELen); + prRetMsduInfo->u2FrameLength += + (uint16_t) prAdapter->prGlueInfo + ->prP2PInfo[prP2pBssInfo->u4PrivateData] + ->u2VenderIELen; + } +#endif + + } while (FALSE); + + if (prRetMsduInfo != prMgmtTxMsdu) + cnmMgtPktFree(prAdapter, prMgmtTxMsdu); + + return prRetMsduInfo; +} /* p2pFuncProcessP2pProbeRsp */ + +/* Code refactoring for AOSP */ +static void +p2pFuncProcessP2pProbeRspAction(IN struct ADAPTER *prAdapter, + IN uint8_t *pucIEBuf, + IN uint8_t ucElemIdType, + OUT uint8_t *ucBssIdx, + OUT struct BSS_INFO **prP2pBssInfo, + OUT u_int8_t *fgIsWSCIE, + OUT u_int8_t *u4P2PIEIdx, + OUT u_int8_t *fgIsWFDIE, + OUT u_int8_t *fgIsVenderIE) +{ + uint8_t ucOuiType = 0; + uint16_t u2SubTypeVersion = 0; + /* Do not compare P2P SSID with AIS SSID to avoid changing + * p2p bss index unexpectedly. + */ + uint8_t ucP2pStartIdx = KAL_AIS_NUM; + + switch (ucElemIdType) { + case ELEM_ID_SSID: + { + if (SSID_IE(pucIEBuf)->ucLength > 7) { + for ((*ucBssIdx) = ucP2pStartIdx; + (*ucBssIdx) < prAdapter->ucHwBssIdNum; + (*ucBssIdx)++) { + *prP2pBssInfo = + GET_BSS_INFO_BY_INDEX( + prAdapter, *ucBssIdx); + if (!(*prP2pBssInfo)) + continue; + if (EQUAL_SSID( + (*prP2pBssInfo)->aucSSID, + (*prP2pBssInfo)->ucSSIDLen, + SSID_IE(pucIEBuf)->aucSSID, + SSID_IE(pucIEBuf)->ucLength)) { + break; + } + } + if ((*ucBssIdx) == prAdapter->ucP2PDevBssIdx) + *prP2pBssInfo = + GET_BSS_INFO_BY_INDEX( + prAdapter, *ucBssIdx); + } else { + *prP2pBssInfo = + GET_BSS_INFO_BY_INDEX( + prAdapter, + prAdapter->ucP2PDevBssIdx); + COPY_SSID( + (*prP2pBssInfo)->aucSSID, + (*prP2pBssInfo)->ucSSIDLen, + SSID_IE(pucIEBuf)->aucSSID, + SSID_IE(pucIEBuf)->ucLength); + + } + } + break; + case ELEM_ID_VENDOR: + if (rsnParseCheckForWFAInfoElem(prAdapter, + pucIEBuf, &ucOuiType, &u2SubTypeVersion)) { + if (ucOuiType == VENDOR_OUI_TYPE_WPS) { + kalP2PUpdateWSC_IE(prAdapter->prGlueInfo, + 2, pucIEBuf, + IE_SIZE(pucIEBuf), + (uint8_t) + ((struct BSS_INFO *)*prP2pBssInfo) + ->u4PrivateData); + *fgIsWSCIE = TRUE; + } + + } else if (p2pFuncParseCheckForP2PInfoElem(prAdapter, + pucIEBuf, &ucOuiType)) { + if (ucOuiType == VENDOR_OUI_TYPE_P2P) { + /* 2 Note(frog): I use WSC IE buffer + * for Probe Request + * to store the P2P IE for Probe Response. + */ + if (*u4P2PIEIdx < MAX_P2P_IE_SIZE) { + kalP2PUpdateP2P_IE( + prAdapter->prGlueInfo, + *u4P2PIEIdx, + pucIEBuf, + IE_SIZE(pucIEBuf), + (uint8_t) + ((struct BSS_INFO *) + *prP2pBssInfo) + ->u4PrivateData); + *u4P2PIEIdx = *u4P2PIEIdx + 1; + } else + DBGLOG(P2P, WARN, + "Too much P2P IE for ProbeResp, skip update\n"); + } +#if CFG_SUPPORT_WFD + else if (ucOuiType == VENDOR_OUI_TYPE_WFD) { + DBGLOG(P2P, INFO, + "WFD IE is found in probe resp (supp). Len %u\n", + IE_SIZE(pucIEBuf)); + if ((sizeof(prAdapter->prGlueInfo->prP2PInfo + [((struct BSS_INFO *)*prP2pBssInfo) + ->u4PrivateData]->aucWFDIE) + >= IE_SIZE(pucIEBuf))) { + *fgIsWFDIE = TRUE; + kalMemCopy(prAdapter->prGlueInfo + ->prP2PInfo + [((struct BSS_INFO *) + *prP2pBssInfo) + ->u4PrivateData]->aucWFDIE, + pucIEBuf, IE_SIZE(pucIEBuf)); + prAdapter->prGlueInfo + ->prP2PInfo + [((struct BSS_INFO *) + *prP2pBssInfo) + ->u4PrivateData]->u2WFDIELen = + IE_SIZE(pucIEBuf); + } + } /* VENDOR_OUI_TYPE_WFD */ +#endif + } else { + DBGLOG(P2P, INFO, + "Other vender IE is found in probe resp (supp). Len %u\n", + IE_SIZE(pucIEBuf)); +#if CFG_SUPPORT_CUSTOM_VENDOR_IE + if ((prAdapter->prGlueInfo->prP2PInfo + [((struct BSS_INFO *)*prP2pBssInfo) + ->u4PrivateData]->u2VenderIELen + + IE_SIZE(pucIEBuf)) < 1024) { + *fgIsVenderIE = TRUE; + kalMemCopy(prAdapter->prGlueInfo + ->prP2PInfo + [((struct BSS_INFO *) + *prP2pBssInfo) + ->u4PrivateData]->aucVenderIE + + prAdapter->prGlueInfo + ->prP2PInfo + [((struct BSS_INFO *) + *prP2pBssInfo) + ->u4PrivateData]->u2VenderIELen, + pucIEBuf, IE_SIZE(pucIEBuf)); + prAdapter->prGlueInfo + ->prP2PInfo + [((struct BSS_INFO *) + *prP2pBssInfo) + ->u4PrivateData]->u2VenderIELen += + IE_SIZE(pucIEBuf); + } +#endif + } + break; + default: + break; + } +} + +#if 0 /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) */ +uint32_t +p2pFuncCalculateExtra_IELenForBeacon(IN struct ADAPTER *prAdapter, + IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, + IN struct STA_RECORD *prStaRec) +{ + + struct P2P_SPECIFIC_BSS_INFO *prP2pSpeBssInfo = + (struct P2P_SPECIFIC_BSS_INFO *) NULL; + uint32_t u4IELen = 0; + + do { + ASSERT_BREAK((prAdapter != NULL) + && (eNetTypeIndex == NETWORK_TYPE_P2P_INDEX)); + + if (p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) + break; + + prP2pSpeBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; + + u4IELen = prP2pSpeBssInfo->u2IELenForBCN; + + } while (FALSE); + + return u4IELen; +} /* p2pFuncCalculateP2p_IELenForBeacon */ + +void p2pFuncGenerateExtra_IEForBeacon(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo) +{ + struct P2P_SPECIFIC_BSS_INFO *prP2pSpeBssInfo = + (struct P2P_SPECIFIC_BSS_INFO *) NULL; + uint8_t *pucIEBuf = (uint8_t *) NULL; + + do { + ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); + + prP2pSpeBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; + + if (p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) + break; + + pucIEBuf = (uint8_t *) ((uint32_t) prMsduInfo->prPacket + + (uint32_t) prMsduInfo->u2FrameLength); + + kalMemCopy(pucIEBuf, + prP2pSpeBssInfo->aucBeaconIECache, + prP2pSpeBssInfo->u2IELenForBCN); + + prMsduInfo->u2FrameLength += prP2pSpeBssInfo->u2IELenForBCN; + + } while (FALSE); +} /* p2pFuncGenerateExtra_IEForBeacon */ + +#else +uint32_t p2pFuncCalculateP2p_IELenForBeacon(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIdx, IN struct STA_RECORD *prStaRec) +{ + struct P2P_SPECIFIC_BSS_INFO *prP2pSpeBssInfo = + (struct P2P_SPECIFIC_BSS_INFO *) NULL; + uint32_t u4IELen = 0; + struct BSS_INFO *prBssInfo; + + do { + ASSERT_BREAK((prAdapter != NULL) + && (ucBssIdx < prAdapter->ucHwBssIdNum)); + + prBssInfo = prAdapter->aprBssInfo[ucBssIdx]; + + if (!prAdapter->fgIsP2PRegistered) + break; + + if (p2pFuncIsAPMode( + prAdapter->rWifiVar.prP2PConnSettings + [prBssInfo->u4PrivateData])) + break; + + prP2pSpeBssInfo = + prAdapter->rWifiVar.prP2pSpecificBssInfo + [prBssInfo->u4PrivateData]; + + u4IELen = prP2pSpeBssInfo->u2AttributeLen; + + } while (FALSE); + + return u4IELen; +} /* p2pFuncCalculateP2p_IELenForBeacon */ + +void p2pFuncGenerateP2p_IEForBeacon(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo) +{ + struct P2P_SPECIFIC_BSS_INFO *prP2pSpeBssInfo = + (struct P2P_SPECIFIC_BSS_INFO *) NULL; + uint8_t *pucIEBuf = (uint8_t *) NULL; + struct BSS_INFO *prBssInfo; + + do { + ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); + + if (!prAdapter->fgIsP2PRegistered) + break; + + prBssInfo = prAdapter->aprBssInfo[prMsduInfo->ucBssIndex]; + + prP2pSpeBssInfo = + prAdapter->rWifiVar.prP2pSpecificBssInfo + [prBssInfo->u4PrivateData]; + + if (p2pFuncIsAPMode( + prAdapter->rWifiVar.prP2PConnSettings + [prBssInfo->u4PrivateData])) + break; + + pucIEBuf = (uint8_t *) ((unsigned long) prMsduInfo->prPacket + + (unsigned long) prMsduInfo->u2FrameLength); + + kalMemCopy(pucIEBuf, + prP2pSpeBssInfo->aucAttributesCache, + prP2pSpeBssInfo->u2AttributeLen); + + prMsduInfo->u2FrameLength += prP2pSpeBssInfo->u2AttributeLen; + + } while (FALSE); +} /* p2pFuncGenerateP2p_IEForBeacon */ + +uint32_t p2pFuncCalculateWSC_IELenForBeacon(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIdx, IN struct STA_RECORD *prStaRec) +{ + struct BSS_INFO *prP2pBssInfo = (struct BSS_INFO *) NULL; + + prP2pBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIdx); + + if (prP2pBssInfo->eNetworkType != NETWORK_TYPE_P2P) + return 0; + + return kalP2PCalWSC_IELen(prAdapter->prGlueInfo, + 0, (uint8_t) prP2pBssInfo->u4PrivateData); +} /* p2pFuncCalculateP2p_IELenForBeacon */ + +void p2pFuncGenerateWSC_IEForBeacon(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo) +{ + uint8_t *pucBuffer; + uint16_t u2IELen = 0; + struct BSS_INFO *prP2pBssInfo = (struct BSS_INFO *) NULL; + + ASSERT(prAdapter); + ASSERT(prMsduInfo); + + prP2pBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prMsduInfo->ucBssIndex); + + if (prP2pBssInfo->eNetworkType != NETWORK_TYPE_P2P) + return; + + u2IELen = (uint16_t) kalP2PCalWSC_IELen(prAdapter->prGlueInfo, + 0, (uint8_t) prP2pBssInfo->u4PrivateData); + + pucBuffer = (uint8_t *) ((unsigned long) prMsduInfo->prPacket + + (unsigned long) prMsduInfo->u2FrameLength); + + ASSERT(pucBuffer); + + /* TODO: Check P2P FSM State. */ + kalP2PGenWSC_IE(prAdapter->prGlueInfo, + 0, pucBuffer, (uint8_t) prP2pBssInfo->u4PrivateData); + + prMsduInfo->u2FrameLength += u2IELen; +} /* p2pFuncGenerateP2p_IEForBeacon */ + +#endif +/*---------------------------------------------------------------------------*/ +/*! + * @brief This function is used to calculate P2P IE length for Beacon frame. + * + * @param[in] eNetTypeIndex Specify which network + * @param[in] prStaRec Pointer to the STA_RECORD_T + * + * @return The length of P2P IE added + */ +/*---------------------------------------------------------------------------*/ +uint32_t p2pFuncCalculateP2p_IELenForAssocRsp(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, IN struct STA_RECORD *prStaRec) +{ + struct BSS_INFO *prBssInfo = (struct BSS_INFO *) NULL; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + + if (prBssInfo->eNetworkType != NETWORK_TYPE_P2P) + return 0; + + return p2pFuncCalculateP2P_IELen(prAdapter, + ucBssIndex, + prStaRec, + txAssocRspAttributesTable, + sizeof(txAssocRspAttributesTable) / + sizeof(struct APPEND_VAR_ATTRI_ENTRY)); + +} /* p2pFuncCalculateP2p_IELenForAssocRsp */ + +/*---------------------------------------------------------------------------*/ +/*! + * @brief This function is used to generate P2P IE for Beacon frame. + * + * @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. + * + * @return none + */ +/*---------------------------------------------------------------------------*/ +void p2pFuncGenerateP2p_IEForAssocRsp(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo) +{ + struct STA_RECORD *prStaRec = (struct STA_RECORD *) NULL; + + + prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); + + if (!prStaRec) { + DBGLOG(P2P, ERROR, "prStaRec of ucStaRecIndex %d is NULL!\n", + prMsduInfo->ucStaRecIndex); + return; + } + + if (IS_STA_IN_P2P(prStaRec)) { + DBGLOG(P2P, TRACE, "Generate NULL P2P IE for Assoc Rsp.\n"); + + p2pFuncGenerateP2P_IE(prAdapter, + prMsduInfo->ucBssIndex, + TRUE, + &prMsduInfo->u2FrameLength, + prMsduInfo->prPacket, + 1500, + txAssocRspAttributesTable, + sizeof(txAssocRspAttributesTable) / + sizeof(struct APPEND_VAR_ATTRI_ENTRY)); + } else { + + DBGLOG(P2P, TRACE, "Legacy device, no P2P IE.\n"); + } +} /* p2pFuncGenerateP2p_IEForAssocRsp */ + +uint32_t +p2pFuncCalculateP2P_IELen(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN struct STA_RECORD *prStaRec, + IN struct APPEND_VAR_ATTRI_ENTRY arAppendAttriTable[], + IN uint32_t u4AttriTableSize) +{ + + uint32_t u4OverallAttriLen, u4Dummy; + uint16_t u2EstimatedFixedAttriLen; + uint32_t i; + + /* Overall length of all Attributes */ + u4OverallAttriLen = 0; + + for (i = 0; i < u4AttriTableSize; i++) { + u2EstimatedFixedAttriLen = + arAppendAttriTable[i].u2EstimatedFixedAttriLen; + + if (u2EstimatedFixedAttriLen) { + u4OverallAttriLen += u2EstimatedFixedAttriLen; + } else { + ASSERT(arAppendAttriTable[i] + .pfnCalculateVariableAttriLen); + + u4OverallAttriLen += arAppendAttriTable[i] + .pfnCalculateVariableAttriLen + (prAdapter, prStaRec); + } + } + + u4Dummy = u4OverallAttriLen; + u4OverallAttriLen += P2P_IE_OUI_HDR; + + for (; (u4Dummy > P2P_MAXIMUM_ATTRIBUTE_LEN);) { + u4OverallAttriLen += P2P_IE_OUI_HDR; + u4Dummy -= P2P_MAXIMUM_ATTRIBUTE_LEN; + } + + return u4OverallAttriLen; +} /* p2pFuncCalculateP2P_IELen */ + +void +p2pFuncGenerateP2P_IE(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN u_int8_t fgIsAssocFrame, + IN uint16_t *pu2Offset, + IN uint8_t *pucBuf, + IN uint16_t u2BufSize, + IN struct APPEND_VAR_ATTRI_ENTRY arAppendAttriTable[], + IN uint32_t u4AttriTableSize) +{ + uint8_t *pucBuffer = (uint8_t *) NULL; + struct IE_P2P *prIeP2P = (struct IE_P2P *) NULL; + uint32_t u4OverallAttriLen; + uint32_t u4AttriLen; + uint8_t aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC; + uint8_t aucTempBuffer[P2P_MAXIMUM_ATTRIBUTE_LEN]; + uint32_t i; + + do { + ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL)); + + pucBuffer = (uint8_t *) ((unsigned long) pucBuf + (*pu2Offset)); + + ASSERT_BREAK(pucBuffer != NULL); + + /* Check buffer length is still enough. */ + ASSERT_BREAK((u2BufSize - (*pu2Offset)) >= P2P_IE_OUI_HDR); + + prIeP2P = (struct IE_P2P *) pucBuffer; + + prIeP2P->ucId = ELEM_ID_P2P; + + prIeP2P->aucOui[0] = aucWfaOui[0]; + prIeP2P->aucOui[1] = aucWfaOui[1]; + prIeP2P->aucOui[2] = aucWfaOui[2]; + prIeP2P->ucOuiType = VENDOR_OUI_TYPE_P2P; + + (*pu2Offset) += P2P_IE_OUI_HDR; + + /* Overall length of all Attributes */ + u4OverallAttriLen = 0; + + for (i = 0; i < u4AttriTableSize; i++) { + + if (arAppendAttriTable[i].pfnAppendAttri) { + u4AttriLen = + arAppendAttriTable[i] + .pfnAppendAttri(prAdapter, + ucBssIndex, fgIsAssocFrame, + pu2Offset, pucBuf, u2BufSize); + + u4OverallAttriLen += u4AttriLen; + + if (u4OverallAttriLen + > P2P_MAXIMUM_ATTRIBUTE_LEN) { + u4OverallAttriLen -= + P2P_MAXIMUM_ATTRIBUTE_LEN; + + prIeP2P->ucLength = + (VENDOR_OUI_TYPE_LEN + + P2P_MAXIMUM_ATTRIBUTE_LEN); + + pucBuffer = (uint8_t *) + ((unsigned long) + prIeP2P + + (VENDOR_OUI_TYPE_LEN + + P2P_MAXIMUM_ATTRIBUTE_LEN)); + + prIeP2P = (struct IE_P2P *) + ((unsigned long) prIeP2P + + (ELEM_HDR_LEN + + (VENDOR_OUI_TYPE_LEN + + P2P_MAXIMUM_ATTRIBUTE_LEN))); + + kalMemCopy(aucTempBuffer, + pucBuffer, u4OverallAttriLen); + + prIeP2P->ucId = ELEM_ID_P2P; + + prIeP2P->aucOui[0] = aucWfaOui[0]; + prIeP2P->aucOui[1] = aucWfaOui[1]; + prIeP2P->aucOui[2] = aucWfaOui[2]; + prIeP2P->ucOuiType = + VENDOR_OUI_TYPE_P2P; + + kalMemCopy(prIeP2P->aucP2PAttributes, + aucTempBuffer, + u4OverallAttriLen); + + (*pu2Offset) += P2P_IE_OUI_HDR; + } + + } + + } + + prIeP2P->ucLength = + (uint8_t) (VENDOR_OUI_TYPE_LEN + u4OverallAttriLen); + + } while (FALSE); +} /* p2pFuncGenerateP2P_IE */ + +uint32_t +p2pFuncAppendAttriStatusForAssocRsp(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN u_int8_t fgIsAssocFrame, + IN uint16_t *pu2Offset, + IN uint8_t *pucBuf, + IN uint16_t u2BufSize) +{ + uint8_t *pucBuffer; + struct P2P_ATTRI_STATUS *prAttriStatus; + uint32_t u4AttriLen = 0; + + ASSERT(prAdapter); + ASSERT(pucBuf); + + if (fgIsAssocFrame) + return u4AttriLen; + /* TODO: For assoc request P2P IE check in driver & + * return status in P2P IE. + */ + + pucBuffer = (uint8_t *) + ((unsigned long) pucBuf + + (unsigned long) (*pu2Offset)); + + ASSERT(pucBuffer); + prAttriStatus = (struct P2P_ATTRI_STATUS *) pucBuffer; + + ASSERT(u2BufSize >= ((*pu2Offset) + (uint16_t) u4AttriLen)); + + prAttriStatus->ucId = P2P_ATTRI_ID_STATUS; + WLAN_SET_FIELD_16(&prAttriStatus->u2Length, P2P_ATTRI_MAX_LEN_STATUS); + + prAttriStatus->ucStatusCode = P2P_STATUS_SUCCESS; + + u4AttriLen = (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_STATUS); + + (*pu2Offset) += (uint16_t) u4AttriLen; + + return u4AttriLen; +} /* p2pFuncAppendAttriStatusForAssocRsp */ + +uint32_t +p2pFuncAppendAttriExtListenTiming(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN u_int8_t fgIsAssocFrame, + IN uint16_t *pu2Offset, + IN uint8_t *pucBuf, + IN uint16_t u2BufSize) +{ + uint32_t u4AttriLen = 0; + struct P2P_ATTRI_EXT_LISTEN_TIMING *prP2pExtListenTiming = + (struct P2P_ATTRI_EXT_LISTEN_TIMING *) NULL; + struct P2P_SPECIFIC_BSS_INFO *prP2pSpecificBssInfo = + (struct P2P_SPECIFIC_BSS_INFO *) NULL; + uint8_t *pucBuffer = NULL; + struct BSS_INFO *prBssInfo = NULL; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + + ASSERT(prAdapter); + ASSERT(pucBuf); + ASSERT(prBssInfo); + + if (fgIsAssocFrame) + return u4AttriLen; + /* TODO: For extend listen timing. */ + + prP2pSpecificBssInfo = + prAdapter->rWifiVar.prP2pSpecificBssInfo + [prBssInfo->u4PrivateData]; + + u4AttriLen = (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_EXT_LISTEN_TIMING); + + ASSERT(u2BufSize >= ((*pu2Offset) + (uint16_t) u4AttriLen)); + + pucBuffer = (uint8_t *) + ((unsigned long) pucBuf + + (unsigned long) (*pu2Offset)); + + ASSERT(pucBuffer); + + prP2pExtListenTiming = (struct P2P_ATTRI_EXT_LISTEN_TIMING *) pucBuffer; + + prP2pExtListenTiming->ucId = P2P_ATTRI_ID_EXT_LISTEN_TIMING; + WLAN_SET_FIELD_16(&prP2pExtListenTiming->u2Length, + P2P_ATTRI_MAX_LEN_EXT_LISTEN_TIMING); + WLAN_SET_FIELD_16(&prP2pExtListenTiming->u2AvailInterval, + prP2pSpecificBssInfo->u2AvailabilityInterval); + WLAN_SET_FIELD_16(&prP2pExtListenTiming->u2AvailPeriod, + prP2pSpecificBssInfo->u2AvailabilityPeriod); + + (*pu2Offset) += (uint16_t) u4AttriLen; + + return u4AttriLen; +} /* p2pFuncAppendAttriExtListenTiming */ + +struct IE_HDR * +p2pFuncGetSpecIE(IN struct ADAPTER *prAdapter, + IN uint8_t *pucIEBuf, + IN uint16_t u2BufferLen, + IN uint8_t ucElemID, + IN u_int8_t *pfgIsMore) +{ + struct IE_HDR *prTargetIE = (struct IE_HDR *) NULL; + uint8_t *pucIE = (uint8_t *) NULL; + uint16_t u2Offset = 0; + + do { + ASSERT_BREAK((prAdapter != NULL) + && (pucIEBuf != NULL)); + + pucIE = pucIEBuf; + + if (pfgIsMore) + *pfgIsMore = FALSE; + + IE_FOR_EACH(pucIE, u2BufferLen, u2Offset) { + if (IE_ID(pucIE) == ucElemID) { + if ((prTargetIE) && (pfgIsMore)) { + + *pfgIsMore = TRUE; + break; + } + prTargetIE = (struct IE_HDR *) pucIE; + + if (pfgIsMore == NULL) + break; + + } + } + + } while (FALSE); + + return prTargetIE; +} /* p2pFuncGetSpecIE */ + +struct P2P_ATTRIBUTE * +p2pFuncGetSpecAttri(IN struct ADAPTER *prAdapter, + IN uint8_t ucOuiType, + IN uint8_t *pucIEBuf, + IN uint16_t u2BufferLen, + IN uint8_t ucAttriID) +{ + struct IE_P2P *prP2pIE = (struct IE_P2P *) NULL; + struct P2P_ATTRIBUTE *prTargetAttri = (struct P2P_ATTRIBUTE *) NULL; + u_int8_t fgIsMore = FALSE; + uint8_t *pucIE = (uint8_t *) NULL; + uint16_t u2BufferLenLeft = 0; + + DBGLOG(P2P, INFO, + "Check AssocReq Oui type %u attri %u for len %u\n", + ucOuiType, ucAttriID, u2BufferLen); + + do { + ASSERT_BREAK((prAdapter != NULL) + && (pucIEBuf != NULL)); + + u2BufferLenLeft = u2BufferLen; + pucIE = pucIEBuf; + + do { + fgIsMore = FALSE; + prP2pIE = (struct IE_P2P *) p2pFuncGetSpecIE(prAdapter, + pucIE, u2BufferLenLeft, + ELEM_ID_VENDOR, &fgIsMore); + if (prP2pIE) { + ASSERT((unsigned long) prP2pIE + >= (unsigned long) pucIE); + u2BufferLenLeft = u2BufferLen - + (uint16_t) (((unsigned long) prP2pIE) - + ((unsigned long) pucIEBuf)); + + DBGLOG(P2P, INFO, + "Find vendor id %u len %u oui %u more %u LeftLen %u\n", + IE_ID(prP2pIE), IE_LEN(prP2pIE), + prP2pIE->ucOuiType, fgIsMore, + u2BufferLenLeft); + + if (IE_LEN(prP2pIE) > P2P_OUI_TYPE_LEN) + p2pFuncGetSpecAttriAction(prP2pIE, + ucOuiType, ucAttriID, + &prTargetAttri); + /* P2P_OUI_TYPE_LEN */ + pucIE = (uint8_t *) + (((unsigned long) prP2pIE) + + IE_SIZE(prP2pIE)); + } + /* prP2pIE */ + } while (prP2pIE && fgIsMore && u2BufferLenLeft); + + } while (FALSE); + + return prTargetAttri; +} + +/* p2pFuncGetSpecAttri */ + +/* Code refactoring for AOSP */ +static void +p2pFuncGetSpecAttriAction(IN struct IE_P2P *prP2pIE, + IN uint8_t ucOuiType, + IN uint8_t ucAttriID, + OUT struct P2P_ATTRIBUTE **prTargetAttri) +{ + uint8_t *pucAttri = (uint8_t *) NULL; + uint16_t u2OffsetAttri = 0; + uint8_t aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC; + + if (prP2pIE->ucOuiType == ucOuiType) { + switch (ucOuiType) { + case VENDOR_OUI_TYPE_WPS: + aucWfaOui[0] = 0x00; + aucWfaOui[1] = 0x50; + aucWfaOui[2] = 0xF2; + break; + case VENDOR_OUI_TYPE_P2P: + break; + case VENDOR_OUI_TYPE_WPA: + case VENDOR_OUI_TYPE_WMM: + case VENDOR_OUI_TYPE_WFD: + default: + break; + } + + if ((prP2pIE->aucOui[0] == aucWfaOui[0]) && + (prP2pIE->aucOui[1] == aucWfaOui[1]) && + (prP2pIE->aucOui[2] == aucWfaOui[2])) { + + u2OffsetAttri = 0; + pucAttri = prP2pIE->aucP2PAttributes; + + if (ucOuiType == VENDOR_OUI_TYPE_WPS) { + WSC_ATTRI_FOR_EACH(pucAttri, + (IE_LEN(prP2pIE) - P2P_IE_OUI_HDR), + u2OffsetAttri) { + if (WSC_ATTRI_ID(pucAttri) + == ucAttriID) { + *prTargetAttri = + (struct P2P_ATTRIBUTE *) + pucAttri; + break; + } + + } + + } else if (ucOuiType == VENDOR_OUI_TYPE_P2P) { + P2P_ATTRI_FOR_EACH(pucAttri, + (IE_LEN(prP2pIE) - P2P_IE_OUI_HDR), + u2OffsetAttri) { + if (ATTRI_ID(pucAttri) + == ucAttriID) { + *prTargetAttri = + (struct P2P_ATTRIBUTE *) + pucAttri; + break; + } + } + + } +#if CFG_SUPPORT_WFD + else if (ucOuiType == VENDOR_OUI_TYPE_WFD) { + WFD_ATTRI_FOR_EACH(pucAttri, + (IE_LEN(prP2pIE) - P2P_IE_OUI_HDR), + u2OffsetAttri) { + if (ATTRI_ID(pucAttri) + == (uint8_t) ucAttriID) { + *prTargetAttri = + (struct P2P_ATTRIBUTE *) + pucAttri; + break; + } + } + } +#endif + else { + /* Todo:: Nothing */ + /* Possible or else. */ + } + } + } /* ucOuiType */ +} + +uint32_t +p2pFuncGenerateBeaconProbeRsp(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo, + IN struct MSDU_INFO *prMsduInfo, + IN u_int8_t fgIsProbeRsp) +{ + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + struct WLAN_BEACON_FRAME *prBcnFrame = + (struct WLAN_BEACON_FRAME *) NULL; + /* P_APPEND_VAR_IE_ENTRY_T prAppendIeTable = + * (P_APPEND_VAR_IE_ENTRY_T)NULL; + */ + + do { + + ASSERT_BREAK((prAdapter != NULL) + && (prBssInfo != NULL) + && (prMsduInfo != NULL)); + + /* txBcnIETable */ + + /* txProbeRspIETable */ + + prBcnFrame = (struct WLAN_BEACON_FRAME *) prMsduInfo->prPacket; + + return nicUpdateBeaconIETemplate(prAdapter, + IE_UPD_METHOD_UPDATE_ALL, + prBssInfo->ucBssIndex, + prBssInfo->u2CapInfo, + (uint8_t *) prBcnFrame->aucInfoElem, + prMsduInfo->u2FrameLength - + OFFSET_OF(struct WLAN_BEACON_FRAME, aucInfoElem)); + + } while (FALSE); + + return rWlanStatus; +} /* p2pFuncGenerateBeaconProbeRsp */ + +uint32_t +p2pFuncComposeBeaconProbeRspTemplate(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prP2pBssInfo, + IN uint8_t *pucBcnBuffer, + IN uint32_t u4BcnBufLen, + IN u_int8_t fgIsProbeRsp, + IN struct P2P_PROBE_RSP_UPDATE_INFO *prP2pProbeRspInfo, + IN u_int8_t fgSynToFW) +{ + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + struct MSDU_INFO *prMsduInfo = (struct MSDU_INFO *) NULL; + struct WLAN_MAC_HEADER *prWlanBcnFrame = + (struct WLAN_MAC_HEADER *) NULL; + + uint8_t *pucBuffer = (uint8_t *) NULL; + + do { + ASSERT_BREAK((prAdapter != NULL) + && (pucBcnBuffer != NULL) + && (prP2pBssInfo != NULL)); + + prWlanBcnFrame = (struct WLAN_MAC_HEADER *) pucBcnBuffer; + + if ((prWlanBcnFrame->u2FrameCtrl != MAC_FRAME_BEACON) + && (!fgIsProbeRsp)) { + rWlanStatus = WLAN_STATUS_INVALID_DATA; + break; + } + + else if (prWlanBcnFrame->u2FrameCtrl != MAC_FRAME_PROBE_RSP) { + rWlanStatus = WLAN_STATUS_INVALID_DATA; + break; + } + + if (fgIsProbeRsp) { + ASSERT_BREAK(prP2pProbeRspInfo != NULL); + + if (!prP2pProbeRspInfo->prProbeRspMsduTemplate) + cnmMgtPktFree(prAdapter, + prP2pProbeRspInfo->prProbeRspMsduTemplate); + + prP2pProbeRspInfo->prProbeRspMsduTemplate = + cnmMgtPktAlloc(prAdapter, u4BcnBufLen); + + prMsduInfo = prP2pProbeRspInfo->prProbeRspMsduTemplate; + + if (prMsduInfo == NULL) { + rWlanStatus = WLAN_STATUS_FAILURE; + break; + } + + prMsduInfo->eSrc = TX_PACKET_MGMT; + prMsduInfo->ucStaRecIndex = 0xFF; + prMsduInfo->ucBssIndex = prP2pBssInfo->ucBssIndex; + + } else { + prMsduInfo = prP2pBssInfo->prBeacon; + + if (prMsduInfo == NULL) { + rWlanStatus = WLAN_STATUS_FAILURE; + break; + } + + if (u4BcnBufLen > + (OFFSET_OF(struct WLAN_BEACON_FRAME, + aucInfoElem[0]) + MAX_IE_LENGTH)) { + /* Unexpected error, buffer overflow. */ + ASSERT(FALSE); + break; + } + + } + + pucBuffer = (uint8_t *) + ((unsigned long) (prMsduInfo->prPacket) + + MAC_TX_RESERVED_FIELD); + + kalMemCopy(pucBuffer, pucBcnBuffer, u4BcnBufLen); + + prMsduInfo->fgIs802_11 = TRUE; + prMsduInfo->u2FrameLength = (uint16_t) u4BcnBufLen; + + if (fgSynToFW) + rWlanStatus = p2pFuncGenerateBeaconProbeRsp(prAdapter, + prP2pBssInfo, prMsduInfo, fgIsProbeRsp); + + } while (FALSE); + + return rWlanStatus; + +} /* p2pFuncComposeBeaconTemplate */ + +uint32_t wfdFuncCalculateWfdIELenForAssocRsp(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN struct STA_RECORD *prStaRec) +{ + +#if CFG_SUPPORT_WFD_COMPOSE_IE + uint16_t u2EstimatedExtraIELen = 0; + struct BSS_INFO *prBssInfo = (struct BSS_INFO *) NULL; + struct WFD_CFG_SETTINGS *prWfdCfgSettings = + (struct WFD_CFG_SETTINGS *) NULL; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + prWfdCfgSettings = &(prAdapter->rWifiVar.rWfdConfigureSettings); + + if (prBssInfo->eNetworkType != NETWORK_TYPE_P2P) + return 0; + + if (!IS_STA_P2P_TYPE(prStaRec) || !prWfdCfgSettings->ucWfdEnable) + return 0; + + u2EstimatedExtraIELen = prAdapter->prGlueInfo-> + prP2PInfo[prBssInfo->u4PrivateData]->u2WFDIELen; + + if (u2EstimatedExtraIELen < VENDOR_SPECIFIC_IE_LENGTH) + return u2EstimatedExtraIELen; + else + return 0; +#else + return 0; +#endif +} /* wfdFuncCalculateWfdIELenForAssocRsp */ + +void wfdFuncGenerateWfdIEForAssocRsp(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo) +{ + +#if CFG_SUPPORT_WFD_COMPOSE_IE + struct STA_RECORD *prStaRec; + uint16_t u2EstimatedExtraIELen; + struct BSS_INFO *prP2pBssInfo = (struct BSS_INFO *) NULL; + struct GLUE_INFO *prGlueInfo; + struct GL_P2P_INFO *prP2PInfo; + struct WFD_CFG_SETTINGS *prWfdCfgSettings = + (struct WFD_CFG_SETTINGS *) NULL; + + if (!prAdapter || !prMsduInfo) + return; + + prGlueInfo = prAdapter->prGlueInfo; + if (!prGlueInfo) + return; + + prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); + if (!prStaRec) + return; + + if (!IS_STA_P2P_TYPE(prStaRec)) + return; + + prP2pBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prMsduInfo->ucBssIndex); + if (!prP2pBssInfo) + return; + + prP2PInfo = prGlueInfo->prP2PInfo[prP2pBssInfo->u4PrivateData]; + if (!prP2PInfo) + return; + + prWfdCfgSettings = &(prAdapter->rWifiVar.rWfdConfigureSettings); + if (!prWfdCfgSettings->ucWfdEnable) + return; + + u2EstimatedExtraIELen = prP2PInfo->u2WFDIELen; + if (u2EstimatedExtraIELen > 0 && + u2EstimatedExtraIELen < VENDOR_SPECIFIC_IE_LENGTH) { + kalMemCopy(prMsduInfo->prPacket + prMsduInfo->u2FrameLength, + prP2PInfo->aucWFDIE, u2EstimatedExtraIELen); + prMsduInfo->u2FrameLength += u2EstimatedExtraIELen; + } + + return; +#else + + return; +#endif +} /* wfdFuncGenerateWfdIEForAssocRsp */ + +void +p2pFuncComposeNoaAttribute(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + OUT uint8_t *aucNoaAttrArray, + OUT uint32_t *pu4Len) +{ + struct BSS_INFO *prBssInfo = NULL; + struct P2P_ATTRI_NOA *prNoaAttr = NULL; + struct P2P_SPECIFIC_BSS_INFO *prP2pSpecificBssInfo = NULL; + struct NOA_DESCRIPTOR *prNoaDesc = NULL; + uint32_t u4NumOfNoaDesc = 0; + uint32_t i = 0; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + prP2pSpecificBssInfo = + prAdapter->rWifiVar + .prP2pSpecificBssInfo[prBssInfo->u4PrivateData]; + + prNoaAttr = (struct P2P_ATTRI_NOA *) aucNoaAttrArray; + + prNoaAttr->ucId = P2P_ATTRI_ID_NOTICE_OF_ABSENCE; + prNoaAttr->ucIndex = prP2pSpecificBssInfo->ucNoAIndex; + + if (prP2pSpecificBssInfo->fgEnableOppPS) { + prNoaAttr->ucCTWOppPSParam = + P2P_CTW_OPPPS_PARAM_OPPPS_FIELD | + (prP2pSpecificBssInfo->u2CTWindow & + P2P_CTW_OPPPS_PARAM_CTWINDOW_MASK); + } else { + prNoaAttr->ucCTWOppPSParam = 0; + } + + for (i = 0; i < prP2pSpecificBssInfo->ucNoATimingCount; i++) { + if (prP2pSpecificBssInfo->arNoATiming[i].fgIsInUse) { + prNoaDesc = (struct NOA_DESCRIPTOR *) + &prNoaAttr->aucNoADesc + [i * sizeof(struct NOA_DESCRIPTOR)]; + + prNoaDesc->ucCountType = + prP2pSpecificBssInfo->arNoATiming[i].ucCount; + prNoaDesc->u4Duration = + prP2pSpecificBssInfo->arNoATiming[i].u4Duration; + prNoaDesc->u4Interval = + prP2pSpecificBssInfo->arNoATiming[i].u4Interval; + prNoaDesc->u4StartTime = + prP2pSpecificBssInfo->arNoATiming[i] + .u4StartTime; + + u4NumOfNoaDesc++; + } + } + + /* include "index" + "OppPs Params" + "NOA descriptors" */ + prNoaAttr->u2Length = 2 + + u4NumOfNoaDesc * sizeof(struct NOA_DESCRIPTOR); + + /* include "Attribute ID" + "Length" + "index" + + * "OppPs Params" + "NOA descriptors" + */ + *pu4Len = P2P_ATTRI_HDR_LEN + prNoaAttr->u2Length; +} + +uint32_t p2pFuncCalculateP2P_IE_NoA(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIdx, + IN struct STA_RECORD *prStaRec) +{ + struct P2P_SPECIFIC_BSS_INFO *prP2pSpecificBssInfo = NULL; + uint8_t ucIdx; + uint32_t u4NumOfNoaDesc = 0; + struct BSS_INFO *prBssInfo; + + prBssInfo = prAdapter->aprBssInfo[ucBssIdx]; + + if (p2pFuncIsAPMode( + prAdapter->rWifiVar.prP2PConnSettings + [prBssInfo->u4PrivateData])) + return 0; + + prP2pSpecificBssInfo = + prAdapter->rWifiVar.prP2pSpecificBssInfo + [prBssInfo->u4PrivateData]; + + for (ucIdx = 0; + ucIdx < prP2pSpecificBssInfo->ucNoATimingCount; ucIdx++) { + if (prP2pSpecificBssInfo->arNoATiming[ucIdx].fgIsInUse) + u4NumOfNoaDesc++; + } + + /* include "index" + "OppPs Params" + "NOA descriptors" */ + /* include "Attribute ID" + "Length" + "index" + + * "OppPs Params" + "NOA descriptors" + */ + return P2P_ATTRI_HDR_LEN + 2 + + (u4NumOfNoaDesc * sizeof(struct NOA_DESCRIPTOR)); +} + +void p2pFuncGenerateP2P_IE_NoA(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo) +{ + struct IE_P2P *prIeP2P; + uint8_t aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC; + uint32_t u4AttributeLen; + struct BSS_INFO *prBssInfo; + + prBssInfo = + prAdapter->aprBssInfo[prMsduInfo->ucBssIndex]; + + if (p2pFuncIsAPMode( + prAdapter->rWifiVar.prP2PConnSettings + [prBssInfo->u4PrivateData])) + return; + + prIeP2P = (struct IE_P2P *) + ((unsigned long) prMsduInfo->prPacket + + (uint32_t) prMsduInfo->u2FrameLength); + + prIeP2P->ucId = ELEM_ID_P2P; + prIeP2P->aucOui[0] = aucWfaOui[0]; + prIeP2P->aucOui[1] = aucWfaOui[1]; + prIeP2P->aucOui[2] = aucWfaOui[2]; + prIeP2P->ucOuiType = VENDOR_OUI_TYPE_P2P; + + /* Compose NoA attribute */ + p2pFuncComposeNoaAttribute(prAdapter, + prMsduInfo->ucBssIndex, + prIeP2P->aucP2PAttributes, + &u4AttributeLen); + + prIeP2P->ucLength = VENDOR_OUI_TYPE_LEN + u4AttributeLen; + + prMsduInfo->u2FrameLength += (ELEM_HDR_LEN + prIeP2P->ucLength); + +} + +void p2pFunCleanQueuedMgmtFrame(IN struct ADAPTER *prAdapter, + IN struct P2P_QUEUED_ACTION_FRAME *prFrame) +{ + if (prAdapter == NULL || prFrame == NULL || prFrame->u2Length == 0 || + prFrame->prHeader == NULL) + return; + + DBGLOG(P2P, INFO, "Clean queued p2p action frame.\n"); + + prFrame->ucRoleIdx = 0; + prFrame->u4Freq = 0; + prFrame->u2Length = 0; + cnmMemFree(prAdapter, prFrame->prHeader); + prFrame->prHeader = NULL; +} + +#if CFG_TC1_FEATURE +static u_int8_t p2pFuncSwitchSapChannelToDbdc( + struct ADAPTER *prAdapter, + struct BSS_INFO *prP2pBssInfo, + uint8_t ucStaChannelNum, + uint8_t ucSapChannelNum, + enum ENUM_BAND eStaBand, + enum ENUM_BAND eSapBand) +{ +#if CFG_SUPPORT_DBDC + if (prAdapter->rWifiVar.eDbdcMode == + ENUM_DBDC_MODE_DISABLED) + return FALSE; + + if (eStaBand == eSapBand && + eSapBand == BAND_5G && + ucStaChannelNum != 149) { + + struct RF_CHANNEL_INFO rRfChnlInfo; + + rRfChnlInfo.ucChannelNum = 6; + rRfChnlInfo.eBand = BAND_2G4; + rRfChnlInfo.ucChnlBw = + rlmGetBssOpBwByVhtAndHtOpInfo(prP2pBssInfo); + + DBGLOG(P2P, INFO, + "[DBDC] StaCH(%d), SapCH(%d)\n", + ucStaChannelNum, + ucSapChannelNum); + + cnmSapChannelSwitchReq(prAdapter, + &rRfChnlInfo, + prP2pBssInfo->u4PrivateData); + + return TRUE; + + } +#endif + + return FALSE; +} +#endif + +void p2pFuncSwitchSapChannel( + IN struct ADAPTER *prAdapter) +{ + u_int8_t fgEnable = FALSE; + u_int8_t fgDbDcModeEn = FALSE; + u_int8_t fgIsSapDfs = FALSE; + struct BSS_INFO *prP2pBssInfo = + (struct BSS_INFO *) NULL; + struct BSS_INFO *prAisBssInfo = + (struct BSS_INFO *) NULL; + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *) NULL; + uint8_t ucStaChannelNum = 0; + uint8_t ucSapChannelNum = 0; + enum ENUM_BAND eStaBand = BAND_NULL; + enum ENUM_BAND eSapBand = BAND_NULL; + +#if CFG_SUPPORT_DFS_MASTER && CFG_SUPPORT_IDC_CH_SWITCH + fgEnable = TRUE; +#endif + + if (!prAdapter + || !cnmSapIsConcurrent(prAdapter) + || !fgEnable) { + DBGLOG(P2P, TRACE, "Not support concurrent STA + SAP\n"); + goto exit; + } + + prAisBssInfo = aisGetConnectedBssInfo(prAdapter); + if (!prAisBssInfo) { + ucStaChannelNum = 0; +#if CFG_SUPPORT_SAP_DFS_CHANNEL + /* restore DFS channels table */ + wlanUpdateDfsChannelTable(prAdapter->prGlueInfo, + -1, /* p2p role index */ + 0, /* primary channel */ + 0, /* bandwidth */ + 0, /* sco */ + 0 /* center frequency */); +#endif + } else { + /* Get current channel info */ + ucStaChannelNum = prAisBssInfo->ucPrimaryChannel; + eStaBand = (prAisBssInfo->ucPrimaryChannel <= 14) + ? BAND_2G4 : BAND_5G; +#if CFG_SUPPORT_SAP_DFS_CHANNEL + /* restore DFS channels table */ + wlanUpdateDfsChannelTable(prAdapter->prGlueInfo, + -1, /* p2p role index */ + ucStaChannelNum, /* primary channel */ + 0, /* bandwidth */ + 0, /* sco */ + 0 /* center frequency */); +#endif + if (eStaBand != BAND_2G4 && eStaBand != BAND_5G) { + DBGLOG(P2P, WARN, "STA has invalid band\n"); + goto exit; + } + } + + /* Assume only one sap bss info */ + prP2pBssInfo = cnmGetSapBssInfo(prAdapter); + if (!prP2pBssInfo) { + DBGLOG(P2P, TRACE, "SAP is not active\n"); + goto exit; + } + if (prP2pBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) { + DBGLOG(P2P, TRACE, "SAP is during initialization\n"); + goto exit; + } + prP2pRoleFsmInfo = + P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, + prP2pBssInfo->u4PrivateData); + if (!prP2pRoleFsmInfo) { + DBGLOG(P2P, WARN, "SAP is not active\n"); + goto exit; + } + + ucSapChannelNum = prP2pBssInfo->ucPrimaryChannel; + eSapBand = prP2pBssInfo->eBand; + if (eSapBand != BAND_2G4 && eSapBand != BAND_5G) { + DBGLOG(P2P, WARN, "SAP has invalid band\n"); + goto exit; + } + + if (eSapBand == BAND_5G) + fgIsSapDfs = rlmDomainIsLegalDfsChannel(prAdapter, + eSapBand, ucSapChannelNum); + + /* STA is not connected */ + if (ucStaChannelNum == 0) { + if (fgIsSapDfs) { + /* Choose one 5G channel */ + ucStaChannelNum = 36; + eStaBand = BAND_5G; + DBGLOG(P2P, INFO, "[SCC] Choose a channel\n"); + } else { + DBGLOG(P2P, WARN, "STA is not connected\n"); + goto exit; + } + } + +#if CFG_TC1_FEATURE + if (p2pFuncSwitchSapChannelToDbdc( + prAdapter, prP2pBssInfo, + ucStaChannelNum, ucSapChannelNum, + eStaBand, eSapBand)) { + goto exit; + } +#endif + +#if CFG_SUPPORT_DBDC + fgDbDcModeEn = prAdapter->rWifiVar.fgDbDcModeEn; +#endif + + /* Check channel no */ + if (ucStaChannelNum == ucSapChannelNum) { + /* Do nothing, i.e. SCC */ + DBGLOG(P2P, INFO, "[SCC] Keep StaCH(%d)\n", ucStaChannelNum); + goto exit; + } else if (fgDbDcModeEn == TRUE + && (eStaBand != eSapBand) && !fgIsSapDfs) { + /* Do nothing, i.e. DBDC */ + DBGLOG(P2P, INFO, + "[DBDC] Keep StaCH(%d), SapCH(%d)(dfs: %u)\n", + ucStaChannelNum, ucSapChannelNum, fgIsSapDfs); + goto exit; + } else { + /* Otherwise, switch to STA channel, i.e. SCC */ + + struct RF_CHANNEL_INFO rRfChnlInfo; + + /* Use sta ch info to do sap ch switch */ + rRfChnlInfo.ucChannelNum = ucStaChannelNum; + rRfChnlInfo.eBand = eStaBand; + rRfChnlInfo.ucChnlBw = + rlmGetBssOpBwByVhtAndHtOpInfo(prP2pBssInfo); + + DBGLOG(P2P, INFO, + "[SCC] StaCH(%d), SapCH(%d)(dfs: %u)\n", + ucStaChannelNum, ucSapChannelNum, fgIsSapDfs); + + cnmSapChannelSwitchReq(prAdapter, + &rRfChnlInfo, + prP2pBssInfo->u4PrivateData); + + } + +exit: + + DBGLOG(P2P, TRACE, "Check done\n"); + /* return; */ +} + +uint32_t +p2pFunGetPreferredFreqList(IN struct ADAPTER *prAdapter, + IN enum ENUM_IFTYPE eIftype, OUT uint32_t *freq_list, + OUT uint32_t *num_freq_list) +{ + struct BSS_INFO *prAisBssInfo; + uint8_t ucNumOfChannel; + uint32_t i; + struct RF_CHANNEL_INFO *aucChannelList; +#if (CFG_SUPPORT_P2PGO_ACS == 1) + struct WIFI_VAR *prWifiVar = &prAdapter->rWifiVar; +#endif + prAisBssInfo = aisGetConnectedBssInfo(prAdapter); + + aucChannelList = (struct RF_CHANNEL_INFO *) kalMemAlloc( + sizeof(struct RF_CHANNEL_INFO) * MAX_CHN_NUM, + VIR_MEM_TYPE); + if (!aucChannelList) { + DBGLOG(P2P, ERROR, + "Allocate buffer for channel list fail\n"); + return -ENOMEM; + } + kalMemZero(aucChannelList, + sizeof(struct RF_CHANNEL_INFO) * MAX_CHN_NUM); + + + DBGLOG(P2P, INFO, "iftype: %d\n", eIftype); + + if (!prAisBssInfo) { + /* Prefer 5G if STA is NOT connected */ +#if (CFG_SUPPORT_P2PGO_ACS == 1) + if (prWifiVar->ucP2pGoACS == TRUE) { + p2pFunGetAcsBestChList(prAdapter, + BIT(BAND_2G4) | BIT(BAND_5G) + , MAX_BW_20MHZ, BITS(0, 14) + , BITS(0, 14), BITS(0, 14), + &ucNumOfChannel, aucChannelList); + + } else +#endif + { + rlmDomainGetChnlList(prAdapter, BAND_5G, TRUE, + MAX_CHN_NUM, &ucNumOfChannel, aucChannelList); + } + DBGLOG(P2P, INFO, + "ucNumOfChannel: %d\n", + ucNumOfChannel); + for (i = 0; i < ucNumOfChannel; i++) { + freq_list[i] = nicChannelNum2Freq( + aucChannelList[i].ucChannelNum) / 1000; + (*num_freq_list)++; + } + } else if (prAdapter->rWifiVar.eDbdcMode == + ENUM_DBDC_MODE_DISABLED) { + /* DBDC disabled */ + DBGLOG(P2P, INFO, + "Prefer SCC, STA operating channel: %d, conn state: %d", + prAisBssInfo->ucPrimaryChannel, + prAisBssInfo->eConnectionState); + freq_list[0] = nicChannelNum2Freq( + prAisBssInfo->ucPrimaryChannel) / 1000; + (*num_freq_list)++; + } else { + /* DBDC enabled */ + DBGLOG(P2P, INFO, + "STA operating channel: %d, band: %d, conn state: %d", + prAisBssInfo->ucPrimaryChannel, + prAisBssInfo->eBand, + prAisBssInfo->eConnectionState); + if (prAisBssInfo->eBand == BAND_2G4) { + /* Prefer 5G if STA is connected at 2G band */ + rlmDomainGetChnlList(prAdapter, BAND_5G, TRUE, + MAX_CHN_NUM, + &ucNumOfChannel, + aucChannelList); + for (i = 0; i < ucNumOfChannel; i++) { + freq_list[i] = nicChannelNum2Freq( + aucChannelList[i].ucChannelNum) / 1000; + (*num_freq_list)++; + } + + /* Add SCC channel */ + freq_list[i] = nicChannelNum2Freq( + prAisBssInfo->ucPrimaryChannel) / 1000; + (*num_freq_list)++; + } else { + /* Prefer SCC if STA is connected at 5G band */ + freq_list[0] = nicChannelNum2Freq( + prAisBssInfo->ucPrimaryChannel) / 1000; + (*num_freq_list)++; +#if (CFG_SUPPORT_P2PGO_ACS == 1) + if (prWifiVar->ucP2pGoACS == TRUE) { + p2pFunGetAcsBestChList(prAdapter, + BAND_2G4, MAX_BW_20MHZ, + BITS(0, 14), BITS(0, 14), + BITS(0, 14), + &ucNumOfChannel, aucChannelList); + } else +#endif + /* Add 2G channels */ + rlmDomainGetChnlList(prAdapter, BAND_2G4, TRUE, + MAX_CHN_NUM, + &ucNumOfChannel, + aucChannelList); + for (i = 0; i < ucNumOfChannel; i++) { + freq_list[i + 1] = nicChannelNum2Freq( + aucChannelList[i].ucChannelNum) / 1000; + (*num_freq_list)++; + } + } + } + + kalMemFree(aucChannelList, VIR_MEM_TYPE, + sizeof(struct RF_CHANNEL_INFO) * MAX_CHN_NUM); + + return WLAN_STATUS_SUCCESS; +} + +enum ENUM_P2P_CONNECT_STATE +p2pFuncGetP2pActionFrameType(IN struct MSDU_INFO *prMgmtMsdu) +{ + struct WLAN_MAC_HEADER *prWlanHdr = (struct WLAN_MAC_HEADER *) NULL; + struct WLAN_ACTION_FRAME *prActFrame; + uint8_t *pucVendor = NULL; + + prWlanHdr = (struct WLAN_MAC_HEADER *) + ((unsigned long) prMgmtMsdu->prPacket + + MAC_TX_RESERVED_FIELD); + if ((prWlanHdr->u2FrameCtrl & MASK_FRAME_TYPE) != MAC_FRAME_ACTION) + return P2P_CNN_NORMAL; + prActFrame = (struct WLAN_ACTION_FRAME *) prWlanHdr; + if (prActFrame->ucCategory != WLAN_ACTION_PUBLIC) + return P2P_CNN_NORMAL; + if (prActFrame->ucAction != WLAN_PA_VENDOR_SPECIFIC) + return P2P_CNN_NORMAL; + pucVendor = (uint8_t *) prActFrame + 26; + if (*(pucVendor + 0) == 0x50 && + *(pucVendor + 1) == 0x6f && + *(pucVendor + 2) == 0x9a && + *(pucVendor + 3) == 0x09) + return ((uint8_t) *(pucVendor + 4)) + 1; + else + return P2P_CNN_NORMAL; +} + +u_int8_t +p2pFuncCheckOnRocChnl(IN struct RF_CHANNEL_INFO *prTxChnl, + IN struct P2P_CHNL_REQ_INFO *prChnlReqInfo) +{ + if (prTxChnl == NULL || prChnlReqInfo == NULL) + return FALSE; + + if (prTxChnl->ucChannelNum == prChnlReqInfo->ucReqChnlNum && + prChnlReqInfo->fgIsChannelRequested) + return TRUE; + + return FALSE; +} + +u_int8_t +p2pFuncNeedWaitRsp(IN struct ADAPTER *prAdapter, + IN enum ENUM_P2P_CONNECT_STATE eConnState) +{ + switch (eConnState) { + case P2P_CNN_GO_NEG_REQ: + case P2P_CNN_GO_NEG_RESP: + case P2P_CNN_INVITATION_REQ: + case P2P_CNN_INVITATION_RESP: + case P2P_CNN_DEV_DISC_REQ: + case P2P_CNN_PROV_DISC_REQ: + return TRUE; + default: + return FALSE; + } +} + +void +p2pFunClearAllTxReq(IN struct ADAPTER *prAdapter, + IN struct P2P_MGMT_TX_REQ_INFO *prP2pMgmtTxInfo) +{ + struct P2P_OFF_CHNL_TX_REQ_INFO *prOffChnlTxPkt = + (struct P2P_OFF_CHNL_TX_REQ_INFO *) NULL; + + while (!LINK_IS_EMPTY(&(prP2pMgmtTxInfo->rTxReqLink))) { + LINK_REMOVE_HEAD(&(prP2pMgmtTxInfo->rTxReqLink), + prOffChnlTxPkt, + struct P2P_OFF_CHNL_TX_REQ_INFO *); + if (!prOffChnlTxPkt) + continue; + kalP2PIndicateMgmtTxStatus( + prAdapter->prGlueInfo, + prOffChnlTxPkt->prMgmtTxMsdu, + FALSE); + cnmPktFree(prAdapter, prOffChnlTxPkt->prMgmtTxMsdu); + cnmMemFree(prAdapter, prOffChnlTxPkt); + } +} + +uint8_t p2pFunGetAcsBestCh(IN struct ADAPTER *prAdapter, + IN enum ENUM_BAND eBand, + IN enum ENUM_MAX_BANDWIDTH_SETTING eChnlBw, + IN uint32_t u4LteSafeChnMask_2G, + IN uint32_t u4LteSafeChnMask_5G_1, + IN uint32_t u4LteSafeChnMask_5G_2) +{ + struct RF_CHANNEL_INFO aucChannelList[MAX_CHN_NUM]; + uint8_t ucNumOfChannel; + struct PARAM_GET_CHN_INFO *prGetChnLoad; + uint8_t i; + struct PARAM_PREFER_CHN_INFO rPreferChannel; + + /* reset */ + rPreferChannel.ucChannel = 0; + rPreferChannel.u4Dirtiness = 0xFFFFFFFF; + + kalMemZero(aucChannelList, + sizeof(struct RF_CHANNEL_INFO) * MAX_CHN_NUM); + + rlmDomainGetChnlList(prAdapter, eBand, TRUE, MAX_CHN_NUM, + &ucNumOfChannel, aucChannelList); + + /* + * 2. Calculate each channel's dirty score + */ + prGetChnLoad = &(prAdapter->rWifiVar.rChnLoadInfo); + + DBGLOG(P2P, INFO, "acs chnl mask=[0x%08x][0x%08x][0x%08x]\n", + u4LteSafeChnMask_2G, + u4LteSafeChnMask_5G_1, + u4LteSafeChnMask_5G_2); + + for (i = 0; i < ucNumOfChannel; i++) { + uint8_t ucIdx; + + ucIdx = wlanGetChannelIndex(aucChannelList[i].ucChannelNum); + if (ucIdx >= MAX_CHN_NUM) + continue; + + DBGLOG(P2P, TRACE, "idx: %u, ch: %u, d: %d\n", + ucIdx, + aucChannelList[i].ucChannelNum, + prGetChnLoad->rEachChnLoad[ucIdx].u4Dirtiness); + + if (aucChannelList[i].ucChannelNum <= 14) { + if (!(u4LteSafeChnMask_2G & BIT( + aucChannelList[i].ucChannelNum))) + continue; + } else if ((aucChannelList[i].ucChannelNum >= 36) && + (aucChannelList[i].ucChannelNum <= 144)) { + if (!(u4LteSafeChnMask_5G_1 & BIT( + (aucChannelList[i].ucChannelNum - 36) / 4))) + continue; + } else if ((aucChannelList[i].ucChannelNum >= 149) && + (aucChannelList[i].ucChannelNum <= 181)) { + if (!(u4LteSafeChnMask_5G_2 & BIT( + (aucChannelList[i].ucChannelNum - 149) / 4))) + continue; + } + + if (eBand == BAND_5G && eChnlBw >= MAX_BW_80MHZ && + nicGetVhtS1(aucChannelList[i].ucChannelNum, + VHT_OP_CHANNEL_WIDTH_80) == 0) + continue; + + if (rPreferChannel.u4Dirtiness > + prGetChnLoad->rEachChnLoad[ucIdx].u4Dirtiness) { + rPreferChannel.ucChannel = + prGetChnLoad->rEachChnLoad[ucIdx].ucChannel; + rPreferChannel.u4Dirtiness = + prGetChnLoad->rEachChnLoad[ucIdx].u4Dirtiness; + } + } + + return rPreferChannel.ucChannel; +} +#if (CFG_SUPPORT_P2PGO_ACS == 1) + +void p2pFunGetAcsBestChList(IN struct ADAPTER *prAdapter, + IN uint8_t eBandSel, + IN enum ENUM_MAX_BANDWIDTH_SETTING eChnlBw, + IN uint32_t u4LteSafeChnMask_2G, + IN uint32_t u4LteSafeChnMask_5G_1, + IN uint32_t u4LteSafeChnMask_5G_2, + OUT uint8_t *pucSortChannelNumber, + OUT struct RF_CHANNEL_INFO *paucSortChannelList) +{ + struct PARAM_GET_CHN_INFO *prGetChnLoad; + uint8_t i, ucInUsedCHNumber = 0, ucBandIdx = BAND_2G4; + bool bIs2Gsupport = FALSE, bIs5Gsupport = FALSE; + /* + *Set 2G/5G support + */ + bIs2Gsupport = (eBandSel & BIT(BAND_2G4)) >> 1 ? TRUE : FALSE; + bIs5Gsupport = (eBandSel & BIT(BAND_5G)) >> 2 ? TRUE : FALSE; + /* + * 1. Sort all channels (which are support by current domain) + */ + wlanSortChannel(prAdapter, CHNL_SORT_POLICY_BY_CH_DOMAIN); + /* + * 2. Calculate each channel's dirty score + */ + prGetChnLoad = &(prAdapter->rWifiVar.rChnLoadInfo); + DBGLOG(P2P, INFO, "acs Band=5G[%d]2G[%d]", + bIs5Gsupport, bIs2Gsupport); + DBGLOG(P2P, INFO, "[0x%08x][0x%08x][0x%08x]\n", + u4LteSafeChnMask_2G, + u4LteSafeChnMask_5G_1, + u4LteSafeChnMask_5G_2); + /* + * 3. Skip some un-safe channels + */ + for (i = 0; i < MAX_CHN_NUM; i++) { + DBGLOG(P2P, TRACE, "idx:%x ch: %u, d: %d\n", + i, + prGetChnLoad->rChnRankList[i].ucChannel, + prGetChnLoad->rChnRankList[i].u4Dirtiness); + if ((bIs2Gsupport == TRUE) && + (prGetChnLoad->rChnRankList[i].ucChannel <= 14)) { + ucBandIdx = BAND_2G4; + if (!(u4LteSafeChnMask_2G & BIT( + prGetChnLoad-> + rChnRankList[i].ucChannel))) + continue; + } else if ((bIs5Gsupport == TRUE) && + (prGetChnLoad->rChnRankList[i].ucChannel >= 36) && + (prGetChnLoad->rChnRankList[i].ucChannel <= 144)) { + ucBandIdx = BAND_5G; + if (!(u4LteSafeChnMask_5G_1 & BIT( + (prGetChnLoad-> + rChnRankList[i].ucChannel - 36) / 4))) + continue; + } else if ((bIs5Gsupport == TRUE) && + (prGetChnLoad->rChnRankList[i].ucChannel >= 149) && + (prGetChnLoad->rChnRankList[i].ucChannel <= 181)) { + ucBandIdx = BAND_5G; + if (!(u4LteSafeChnMask_5G_2 & BIT( + (prGetChnLoad-> + rChnRankList[i].ucChannel - 149) / 4))) + continue; + } else { + continue; + } + + if (ucBandIdx == BAND_5G && eChnlBw >= MAX_BW_80MHZ && + nicGetVhtS1(prGetChnLoad->rChnRankList[i].ucChannel, + VHT_OP_CHANNEL_WIDTH_80) == 0) + continue; + (paucSortChannelList+ucInUsedCHNumber)-> + ucChannelNum = + prGetChnLoad-> + rChnRankList[i].ucChannel; + (paucSortChannelList+ucInUsedCHNumber)-> + eBand = ucBandIdx; + DBGLOG(P2P, TRACE, "ACS Usedidx=%d,ch[%d] Dirty=%x\n", + ucInUsedCHNumber, + (paucSortChannelList+ucInUsedCHNumber)-> + ucChannelNum, + prGetChnLoad-> + rChnRankList[i].u4Dirtiness); + ucInUsedCHNumber++; + } + /* + * 4. Dump the Result + */ + *pucSortChannelNumber = ucInUsedCHNumber; + for (i = 0; i < ucInUsedCHNumber; i++) { + DBGLOG(P2P, INFO, "ACS idx=%d,ch[%d] Dirty=%x\n", + i, + (paucSortChannelList+i)->ucChannelNum, + prGetChnLoad->rChnRankList[i].u4Dirtiness); + } + /*return rPreferChannel.ucChannel*/ +} +#endif + +void p2pFunProcessAcsReport(IN struct ADAPTER *prAdapter, + IN uint8_t ucRoleIndex, + IN struct PARAM_GET_CHN_INFO *prLteSafeChnInfo, + IN struct P2P_ACS_REQ_INFO *prAcsReqInfo) +{ + enum ENUM_BAND eBand; + uint32_t u4LteSafeChnMask_2G = -1; + + if (!prAdapter || !prAcsReqInfo) + return; + + if (prAcsReqInfo->eHwMode == P2P_VENDOR_ACS_HW_MODE_11B || + prAcsReqInfo->eHwMode == P2P_VENDOR_ACS_HW_MODE_11G) + eBand = BAND_2G4; + else + eBand = BAND_5G; + + if (prLteSafeChnInfo && (eBand == BAND_2G4)) { + struct LTE_SAFE_CHN_INFO *prLteSafeChnList; + struct RF_CHANNEL_INFO aucChannelList[MAX_2G_BAND_CHN_NUM]; + uint8_t ucNumOfChannel; + uint8_t i; + u_int8_t fgIsMaskValid = FALSE; + + kalMemZero(aucChannelList, + sizeof(struct RF_CHANNEL_INFO) * MAX_2G_BAND_CHN_NUM); + + rlmDomainGetChnlList(prAdapter, eBand, TRUE, + MAX_2G_BAND_CHN_NUM, &ucNumOfChannel, aucChannelList); + + prLteSafeChnList = &prLteSafeChnInfo->rLteSafeChnList; + u4LteSafeChnMask_2G = prLteSafeChnList->au4SafeChannelBitmask[ + ENUM_SAFE_CH_MASK_BAND_2G4]; + + prAcsReqInfo->u4LteSafeChnMask_2G &= u4LteSafeChnMask_2G; + for (i = 0; i < ucNumOfChannel; i++) { + if ((prAcsReqInfo->u4LteSafeChnMask_2G & + BIT(aucChannelList[i].ucChannelNum))) + fgIsMaskValid = TRUE; + } + if (!fgIsMaskValid) { + DBGLOG(P2P, WARN, + "All mask invalid, mark all as valid\n"); + prAcsReqInfo->u4LteSafeChnMask_2G = BITS(1, 14); + } +#if CFG_TC1_FEATURE + /* Restrict 2.4G band channel selection range + * to 1/6/11 per customer's request + */ + prAcsReqInfo->u4LteSafeChnMask_2G &= 0x0842; +#elif CFG_TC10_FEATURE + /* Restrict 2.4G band channel selection range + * to 1~11 per customer's request + */ + prAcsReqInfo->u4LteSafeChnMask_2G &= 0x0FFE; +#endif + } else if (prLteSafeChnInfo && (eBand == BAND_5G)) { + /* Add support for 5G FW mask */ + struct LTE_SAFE_CHN_INFO *prLteSafeChnList = + &prLteSafeChnInfo->rLteSafeChnList; + uint32_t u4LteSafeChnMask_5G_1 = + prLteSafeChnList->au4SafeChannelBitmask + [ENUM_SAFE_CH_MASK_BAND_5G_0]; + uint32_t u4LteSafeChnMask_5G_2 = + prLteSafeChnList->au4SafeChannelBitmask + [ENUM_SAFE_CH_MASK_BAND_5G_1]; + + prAcsReqInfo->u4LteSafeChnMask_5G_1 &= u4LteSafeChnMask_5G_1; + prAcsReqInfo->u4LteSafeChnMask_5G_1 &= u4LteSafeChnMask_5G_2; + } + + prAcsReqInfo->ucPrimaryCh = p2pFunGetAcsBestCh(prAdapter, + eBand, + prAcsReqInfo->eChnlBw, + prAcsReqInfo->u4LteSafeChnMask_2G, + prAcsReqInfo->u4LteSafeChnMask_5G_1, + prAcsReqInfo->u4LteSafeChnMask_5G_2); + + p2pFunIndicateAcsResult(prAdapter->prGlueInfo, + prAcsReqInfo); +} + +enum ENUM_CHNL_EXT p2pFunGetSco(IN struct ADAPTER *prAdapter, + enum ENUM_BAND eBand, uint8_t ucPrimaryCh) { + enum ENUM_CHNL_EXT eSCO = CHNL_EXT_SCN; + + if (eBand == BAND_2G4) { + if (ucPrimaryCh != 14) + eSCO = (ucPrimaryCh > 7) ? CHNL_EXT_SCB : CHNL_EXT_SCA; + } else { + if (regd_is_single_sku_en()) { + if (rlmDomainIsLegalChannel(prAdapter, + eBand, + ucPrimaryCh)) + eSCO = rlmSelectSecondaryChannelType(prAdapter, + eBand, + ucPrimaryCh); + } else { + struct DOMAIN_INFO_ENTRY *prDomainInfo = + rlmDomainGetDomainInfo(prAdapter); + struct DOMAIN_SUBBAND_INFO *prSubband; + uint8_t i, j; + + for (i = 0; i < MAX_SUBBAND_NUM; i++) { + prSubband = &prDomainInfo->rSubBand[i]; + if (prSubband->ucBand != eBand) + continue; + for (j = 0; j < prSubband->ucNumChannels; j++) { + if ((prSubband->ucFirstChannelNum + + j * prSubband->ucChannelSpan) == + ucPrimaryCh) { + eSCO = (j & 1) ? + CHNL_EXT_SCB : + CHNL_EXT_SCA; + break; + } + } + + if (j < prSubband->ucNumChannels) + break; /* Found */ + } + } + } + + return eSCO; +} + +uint8_t p2pFunGetSecCh(IN struct ADAPTER *prAdapter, + IN enum ENUM_BAND eBand, + IN enum ENUM_CHNL_EXT eSCO, + IN uint8_t ucPrimaryCh) +{ + uint8_t ucSecondCh; + + if (eSCO == CHNL_EXT_SCN) + return 0; + + if (eSCO == CHNL_EXT_SCA) + ucSecondCh = ucPrimaryCh + CHNL_SPAN_20; + else + ucSecondCh = ucPrimaryCh - CHNL_SPAN_20; + + if (!rlmDomainIsLegalChannel(prAdapter, eBand, ucSecondCh)) + ucSecondCh = 0; + + return ucSecondCh; +} + +void p2pFunIndicateAcsResult(IN struct GLUE_INFO *prGlueInfo, + IN struct P2P_ACS_REQ_INFO *prAcsReqInfo) +{ + uint8_t ucVhtBw = VHT_OP_CHANNEL_WIDTH_20_40; + + if (prAcsReqInfo->ucPrimaryCh == 0) { + if (prAcsReqInfo->eHwMode == P2P_VENDOR_ACS_HW_MODE_11B || + prAcsReqInfo->eHwMode == + P2P_VENDOR_ACS_HW_MODE_11G) { + prAcsReqInfo->ucPrimaryCh = AP_DEFAULT_CHANNEL_2G; + } else { + prAcsReqInfo->ucPrimaryCh = AP_DEFAULT_CHANNEL_5G; + } + DBGLOG(P2P, WARN, "No chosed channel, use default channel %d\n", + prAcsReqInfo->ucPrimaryCh); + } + + if (prAcsReqInfo->eChnlBw > MAX_BW_20MHZ) { + enum ENUM_BAND eBand; + enum ENUM_CHNL_EXT eSCO; + + eBand = prAcsReqInfo->ucPrimaryCh <= 14 ? BAND_2G4 : BAND_5G; + eSCO = p2pFunGetSco(prGlueInfo->prAdapter, + eBand, + prAcsReqInfo->ucPrimaryCh); + + prAcsReqInfo->ucSecondCh = p2pFunGetSecCh( + prGlueInfo->prAdapter, + eBand, + eSCO, + prAcsReqInfo->ucPrimaryCh); + } + + switch (prAcsReqInfo->eChnlBw) { + case MAX_BW_20MHZ: + case MAX_BW_40MHZ: + ucVhtBw = VHT_OP_CHANNEL_WIDTH_20_40; + break; + case MAX_BW_80MHZ: + ucVhtBw = VHT_OP_CHANNEL_WIDTH_80; + break; + case MAX_BW_160MHZ: + ucVhtBw = VHT_OP_CHANNEL_WIDTH_160; + break; + case MAX_BW_80_80_MHZ: + ucVhtBw = VHT_OP_CHANNEL_WIDTH_80P80; + break; + default: + ucVhtBw = VHT_OP_CHANNEL_WIDTH_20_40; + break; + } + prAcsReqInfo->ucCenterFreqS1 = nicGetVhtS1( + prAcsReqInfo->ucPrimaryCh, + ucVhtBw); + + if (prAcsReqInfo->eChnlBw != VHT_OP_CHANNEL_WIDTH_80P80) + prAcsReqInfo->ucCenterFreqS2 = 0; + else + DBGLOG(P2P, ERROR, "Not support 80+80 bw.\n"); + + prAcsReqInfo->fgIsProcessing = FALSE; + kalP2pIndicateAcsResult(prGlueInfo, + prAcsReqInfo->ucRoleIdx, + prAcsReqInfo->ucPrimaryCh, + prAcsReqInfo->ucSecondCh, + prAcsReqInfo->ucCenterFreqS1, + prAcsReqInfo->ucCenterFreqS2, + prAcsReqInfo->eChnlBw); +} + +void p2pFunCalAcsChnScores(IN struct ADAPTER *prAdapter) +{ + struct BSS_DESC *prBssDesc = NULL; + struct PARAM_GET_CHN_INFO *prChnLoadInfo; + struct LINK *prBSSDescList = NULL; + struct SCAN_INFO *prgScanInfo = NULL; + + if (!prAdapter) + return; + + prgScanInfo = &(prAdapter->rWifiVar.rScanInfo); + prBSSDescList = &prgScanInfo->rBSSDescList; + prChnLoadInfo = &prAdapter->rWifiVar.rChnLoadInfo; + + /* Clear old ACS data (APNum, Dirtiness, ...) + * and initialize the ch number + */ + kalMemZero(&(prAdapter->rWifiVar.rChnLoadInfo), + sizeof(prAdapter->rWifiVar.rChnLoadInfo)); + wlanInitChnLoadInfoChannelList(prAdapter); + + LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, + rLinkEntry, struct BSS_DESC) { + uint8_t ucIdx = wlanGetChannelIndex( + prBssDesc->ucChannelNum); + + if (ucIdx >= MAX_CHN_NUM) + continue; + prChnLoadInfo->rEachChnLoad[ucIdx].u2APNum++; + } + + wlanCalculateAllChannelDirtiness(prAdapter); + wlanSortChannel(prAdapter, CHNL_SORT_POLICY_ALL_CN); +} + +enum ENUM_CHNL_SWITCH_POLICY +p2pFunDetermineChnlSwitchPolicy(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIdx, + IN struct RF_CHANNEL_INFO *prNewChannelInfo) +{ + enum ENUM_CHNL_SWITCH_POLICY ePolicy = CHNL_SWITCH_POLICY_CSA; + +#if CFG_SEND_DEAUTH_DURING_CHNL_SWITCH + struct BSS_INFO *prBssInfo; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIdx); + + /* Send deauth frame to clients: + * 1. Cross band + * 2. BW > 20MHz + */ + if (prNewChannelInfo->eBand == BAND_5G || + (prBssInfo && prBssInfo->eBand == BAND_5G && + prNewChannelInfo->eBand == BAND_2G4)) + ePolicy = CHNL_SWITCH_POLICY_DEAUTH; +#endif + + return ePolicy; +} + +void +p2pFunNotifyChnlSwitch(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIdx, + enum ENUM_CHNL_SWITCH_POLICY ePolicy, + IN struct RF_CHANNEL_INFO *prNewChannelInfo) +{ + struct BSS_INFO *prBssInfo; + struct LINK *prClientList; + struct STA_RECORD *prCurrStaRec; + + DBGLOG(P2P, INFO, "bss index: %d, policy: %d\n", ucBssIdx, ePolicy); + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIdx); + prClientList = &prBssInfo->rStaRecOfClientList; + + switch (ePolicy) { + case CHNL_SWITCH_POLICY_DEAUTH: + if (prClientList && prClientList->u4NumElem > 0) { + LINK_FOR_EACH_ENTRY(prCurrStaRec, prClientList, + rLinkEntry, struct STA_RECORD) { + struct TIMER *prTimer; + + if (!prCurrStaRec) + break; + + prTimer = &(prCurrStaRec->rDeauthTxDoneTimer); + + p2pFuncDisconnect(prAdapter, prBssInfo, + prCurrStaRec, TRUE, + REASON_CODE_DEAUTH_LEAVING_BSS); + + if (!timerPendingTimer(prTimer)) { + cnmTimerInitTimer(prAdapter, + prTimer, + (PFN_MGMT_TIMEOUT_FUNC) + p2pRoleFsmDeauthTimeout, + (unsigned long) prCurrStaRec); + cnmTimerStartTimer(prAdapter, + prTimer, + P2P_DEAUTH_TIMEOUT_TIME_MS); + } + } + /* wait for deauth TX done & switch channel */ + } else { + p2pFunChnlSwitchNotifyDone(prAdapter); + } + break; + case CHNL_SWITCH_POLICY_CSA: + /* Set CSA IE */ + prAdapter->rWifiVar.fgCsaInProgress = TRUE; + prAdapter->rWifiVar.ucChannelSwitchMode = 1; + prAdapter->rWifiVar.ucNewChannelNumber = + prNewChannelInfo->ucChannelNum; + prAdapter->rWifiVar.ucChannelSwitchCount = 5; + + /* Send Action Frame */ + rlmSendChannelSwitchFrame(prAdapter, prBssInfo->ucBssIndex); + + /* Update Beacon */ + bssUpdateBeaconContent(prAdapter, prBssInfo->ucBssIndex); + break; + default: + DBGLOG(P2P, WARN, "invalid policy for channel switch: %d\n", + ePolicy); + break; + } +} + +void +p2pFunChnlSwitchNotifyDone(IN struct ADAPTER *prAdapter) +{ + struct BSS_INFO *prBssInfo; + struct MSG_P2P_CSA_DONE *prP2pCsaDoneMsg; + + if (!prAdapter) + return; + + prBssInfo = cnmGetSapBssInfo(prAdapter); + if (!prBssInfo) + return; + + prP2pCsaDoneMsg = (struct MSG_P2P_CSA_DONE *) cnmMemAlloc(prAdapter, + RAM_TYPE_MSG, + sizeof(*prP2pCsaDoneMsg)); + + if (!prP2pCsaDoneMsg) { + log_dbg(CNM, ERROR, "allocate for prP2pCsaDoneMsg failed!\n"); + return; + } + + DBGLOG(CNM, INFO, "ucBssIndex = %d\n", prBssInfo->ucBssIndex); + + prP2pCsaDoneMsg->rMsgHdr.eMsgId = MID_CNM_P2P_CSA_DONE; + prP2pCsaDoneMsg->ucBssIndex = prBssInfo->ucBssIndex; + mboxSendMsg(prAdapter, MBOX_ID_0, (struct MSG_HDR *) prP2pCsaDoneMsg, + MSG_SEND_METHOD_BUF); +} + +uint8_t p2pFuncIsBufferableMMPDU(IN struct ADAPTER *prAdapter, + IN enum ENUM_P2P_CONNECT_STATE eConnState, + IN struct MSDU_INFO *prMgmtTxMsdu) +{ + struct WLAN_MAC_HEADER *prWlanHdr = (struct WLAN_MAC_HEADER *) NULL; + uint16_t u2TxFrameCtrl; + uint8_t fgIsBufferableMMPDU = FALSE; + + prWlanHdr = (struct WLAN_MAC_HEADER *) + ((unsigned long) prMgmtTxMsdu->prPacket + + MAC_TX_RESERVED_FIELD); + + if (!prWlanHdr) { + DBGLOG(P2P, ERROR, "prWlanHdr is NULL\n"); + return FALSE; + } + u2TxFrameCtrl = prWlanHdr->u2FrameCtrl & MASK_FRAME_TYPE; + + switch (u2TxFrameCtrl) { + case MAC_FRAME_ACTION: + switch (eConnState) { + case P2P_CNN_GO_NEG_REQ: + case P2P_CNN_GO_NEG_RESP: + case P2P_CNN_GO_NEG_CONF: + case P2P_CNN_INVITATION_REQ: + case P2P_CNN_INVITATION_RESP: + fgIsBufferableMMPDU = FALSE; + break; + default: + fgIsBufferableMMPDU = TRUE; + break; + } + break; + case MAC_FRAME_DISASSOC: + case MAC_FRAME_DEAUTH: + fgIsBufferableMMPDU = TRUE; + break; + default: + fgIsBufferableMMPDU = FALSE; + break; + } + DBGLOG(P2P, TRACE, "fgIsBufferableMMPDU = %u\n", fgIsBufferableMMPDU); + return fgIsBufferableMMPDU; +} + +uint8_t p2pFuncIsTimingCriticalFrames( + IN struct ADAPTER *prAdapter, + IN enum ENUM_P2P_CONNECT_STATE eConnState, + IN struct MSDU_INFO *prMgmtTxMsdu) +{ + struct WLAN_MAC_HEADER *prWlanHdr = (struct WLAN_MAC_HEADER *) NULL; + uint16_t u2TxFrameCtrl; + uint8_t fgIsTimingCritical = FALSE; + + prWlanHdr = (struct WLAN_MAC_HEADER *) + ((unsigned long) prMgmtTxMsdu->prPacket + + MAC_TX_RESERVED_FIELD); + + if (!prWlanHdr) { + DBGLOG(P2P, ERROR, "prWlanHdr is NULL\n"); + return FALSE; + } + u2TxFrameCtrl = prWlanHdr->u2FrameCtrl & MASK_FRAME_TYPE; + + switch (u2TxFrameCtrl) { + case MAC_FRAME_ACTION: + switch (eConnState) { + case P2P_CNN_GO_NEG_REQ: + case P2P_CNN_INVITATION_REQ: + fgIsTimingCritical = TRUE; + break; + default: + break; + } + break; + case MAC_FRAME_PROBE_REQ: + fgIsTimingCritical = TRUE; + break; + default: + break; + } + + return fgIsTimingCritical; +} + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/p2p_ie.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/p2p_ie.c new file mode 100644 index 0000000000000000000000000000000000000000..b780c05164def862bba4d240b0801461cfe7910d --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/p2p_ie.c @@ -0,0 +1,238 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +#include "precomp.h" + +uint32_t p2pCalculate_IEForAssocReq(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN struct STA_RECORD *prStaRec) +{ + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *) NULL; + struct BSS_INFO *prP2pBssInfo = (struct BSS_INFO *) NULL; + struct P2P_CONNECTION_REQ_INFO *prConnReqInfo = + (struct P2P_CONNECTION_REQ_INFO *) NULL; + uint32_t u4RetValue = 0; + + do { + ASSERT_BREAK((prStaRec != NULL) && (prAdapter != NULL)); + + prP2pBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + + prP2pRoleFsmInfo = + P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, + (uint8_t) prP2pBssInfo->u4PrivateData); + + prConnReqInfo = &(prP2pRoleFsmInfo->rConnReqInfo); + + u4RetValue = prConnReqInfo->u4BufLength; + + /* ADD WMM Information Element */ + u4RetValue += (ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_INFO); + + /* ADD HT Capability */ + if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet + & PHY_TYPE_SET_802_11N) + && (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)) { + u4RetValue += (ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP); + } +#if CFG_SUPPORT_802_11AC + /* ADD VHT Capability */ + if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet + & PHY_TYPE_SET_802_11AC) + && (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11AC)) { + u4RetValue += (ELEM_HDR_LEN + ELEM_MAX_LEN_VHT_CAP); + } +#endif + +#if CFG_SUPPORT_802_11AX + /* ADD HE Capability */ + if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet + & PHY_TYPE_SET_802_11AX) + && (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11AX)) { + u4RetValue += heRlmCalculateHeCapIELen(prAdapter, + prStaRec->ucBssIndex, prStaRec); + } +#endif + +#if CFG_SUPPORT_MTK_SYNERGY + if (prAdapter->rWifiVar.ucMtkOui == FEATURE_ENABLED) + u4RetValue += (ELEM_HDR_LEN + ELEM_MIN_LEN_MTK_OUI); +#endif + } while (FALSE); + + return u4RetValue; +} /* p2pCalculate_IEForAssocReq */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is used to generate P2P IE for Beacon frame. + * + * @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. + * + * @return none + */ +/*----------------------------------------------------------------------------*/ +void p2pGenerate_IEForAssocReq(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo) +{ + struct BSS_INFO *prBssInfo = (struct BSS_INFO *) NULL; + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *) NULL; + struct P2P_CONNECTION_REQ_INFO *prConnReqInfo = + (struct P2P_CONNECTION_REQ_INFO *) NULL; + uint8_t *pucIEBuf = (uint8_t *) NULL; + + do { + ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); + + prBssInfo = + GET_BSS_INFO_BY_INDEX(prAdapter, + prMsduInfo->ucBssIndex); + + prP2pRoleFsmInfo = + P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, + (uint8_t) prBssInfo->u4PrivateData); + + prConnReqInfo = &(prP2pRoleFsmInfo->rConnReqInfo); + + pucIEBuf = (uint8_t *) ((unsigned long) prMsduInfo->prPacket + + (unsigned long) prMsduInfo->u2FrameLength); + + kalMemCopy(pucIEBuf, prConnReqInfo->aucIEBuf, + prConnReqInfo->u4BufLength); + + prMsduInfo->u2FrameLength += prConnReqInfo->u4BufLength; + + /* Add WMM IE */ + mqmGenerateWmmInfoIE(prAdapter, prMsduInfo); + + /* Add HT IE */ + rlmReqGenerateHtCapIE(prAdapter, prMsduInfo); + +#if CFG_SUPPORT_802_11AC + /* Add VHT IE */ + rlmReqGenerateVhtCapIE(prAdapter, prMsduInfo); +#endif + +#if CFG_SUPPORT_802_11AX + /* Add HE IE */ + heRlmReqGenerateHeCapIE(prAdapter, prMsduInfo); +#endif + +#if CFG_SUPPORT_MTK_SYNERGY + rlmGenerateMTKOuiIE(prAdapter, prMsduInfo); +#endif + } while (FALSE); + + return; + +} /* p2pGenerate_IEForAssocReq */ + +uint32_t +wfdFuncAppendAttriDevInfo(IN struct ADAPTER *prAdapter, + IN u_int8_t fgIsAssocFrame, + IN uint16_t *pu2Offset, + IN uint8_t *pucBuf, + IN uint16_t u2BufSize) +{ + uint32_t u4AttriLen = 0; + uint8_t *pucBuffer = NULL; + struct WFD_DEVICE_INFORMATION_IE *prWfdDevInfo = + (struct WFD_DEVICE_INFORMATION_IE *) NULL; + struct WFD_CFG_SETTINGS *prWfdCfgSettings = + (struct WFD_CFG_SETTINGS *) NULL; + + do { + ASSERT_BREAK((prAdapter != NULL) + && (pucBuf != NULL) && (pu2Offset != NULL)); + + prWfdCfgSettings = &(prAdapter->rWifiVar.rWfdConfigureSettings); + + ASSERT_BREAK((prWfdCfgSettings != NULL)); + + if ((prWfdCfgSettings->ucWfdEnable == 0) || + ((prWfdCfgSettings->u4WfdFlag + & WFD_FLAGS_DEV_INFO_VALID) == 0)) { + break; + } + + pucBuffer = (uint8_t *) ((unsigned long) pucBuf + + (unsigned long) (*pu2Offset)); + + ASSERT_BREAK(pucBuffer != NULL); + + prWfdDevInfo = (struct WFD_DEVICE_INFORMATION_IE *) pucBuffer; + + prWfdDevInfo->ucElemID = WFD_ATTRI_ID_DEV_INFO; + + WLAN_SET_FIELD_BE16(&prWfdDevInfo->u2WfdDevInfo, + prWfdCfgSettings->u2WfdDevInfo); + + WLAN_SET_FIELD_BE16(&prWfdDevInfo->u2SessionMgmtCtrlPort, + prWfdCfgSettings->u2WfdControlPort); + + WLAN_SET_FIELD_BE16(&prWfdDevInfo->u2WfdDevMaxSpeed, + prWfdCfgSettings->u2WfdMaximumTp); + + WLAN_SET_FIELD_BE16(&prWfdDevInfo->u2Length, + WFD_ATTRI_MAX_LEN_DEV_INFO); + + u4AttriLen = WFD_ATTRI_MAX_LEN_DEV_INFO + WFD_ATTRI_HDR_LEN; + + } while (FALSE); + + (*pu2Offset) += (uint16_t) u4AttriLen; + + return u4AttriLen; +} + +/* wfdFuncAppendAttriDevInfo */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/p2p_rlm.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/p2p_rlm.c new file mode 100644 index 0000000000000000000000000000000000000000..5cf9c2edeef0872232ec5a8143677fe073ac1c98 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/p2p_rlm.c @@ -0,0 +1,1396 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: @(#) p2p_rlm.c@@ + */ + +/*! \file "p2p_rlm.c" + * \brief + * + */ + +/****************************************************************************** + * C O M P I L E R F L A G S + ****************************************************************************** + */ + +/****************************************************************************** + * E X T E R N A L R E F E R E N C E S + ****************************************************************************** + */ + +#include "precomp.h" +#include "rlm.h" + +/****************************************************************************** + * C O N S T A N T S + ****************************************************************************** + */ + +/****************************************************************************** + * D A T A T Y P E S + ****************************************************************************** + */ + +/****************************************************************************** + * P U B L I C D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * P R I V A T E D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * M A C R O S + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N D E C L A R A T I O N S + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N S + ****************************************************************************** + */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Init AP Bss + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rlmBssInitForAP(struct ADAPTER *prAdapter, struct BSS_INFO *prBssInfo) +{ + uint8_t i; + uint8_t ucMaxBw = 0; + + ASSERT(prAdapter); + ASSERT(prBssInfo); + + if (prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) + return; + + /* Operation band, channel shall be ready before invoking this function. + * Bandwidth may be ready if other network is connected + */ + prBssInfo->fg40mBwAllowed = FALSE; + prBssInfo->fgAssoc40mBwAllowed = FALSE; + prBssInfo->eBssSCO = CHNL_EXT_SCN; + + /* Check if AP can set its bw to 40MHz + * But if any of BSS is setup in 40MHz, + * the second BSS would prefer to use 20MHz + * in order to remain in SCC case + */ + if (cnmBss40mBwPermitted(prAdapter, prBssInfo->ucBssIndex)) { + + prBssInfo->eBssSCO = rlmGetScoForAP(prAdapter, prBssInfo); + + if (prBssInfo->eBssSCO != CHNL_EXT_SCN) { + prBssInfo->fg40mBwAllowed = TRUE; + prBssInfo->fgAssoc40mBwAllowed = TRUE; + + prBssInfo->ucHtOpInfo1 = (uint8_t) + (((uint32_t) prBssInfo->eBssSCO) + | HT_OP_INFO1_STA_CHNL_WIDTH); + + rlmUpdateBwByChListForAP(prAdapter, prBssInfo); + } + } + + /* Filled the VHT BW/S1/S2 and MCS rate set */ + if (prBssInfo->ucPhyTypeSet & PHY_TYPE_BIT_VHT) { + for (i = 0; i < 8; i++) + prBssInfo->u2VhtBasicMcsSet |= BITS(2 * i, (2 * i + 1)); + prBssInfo->u2VhtBasicMcsSet &= + (VHT_CAP_INFO_MCS_MAP_MCS9 + << VHT_CAP_INFO_MCS_1SS_OFFSET); + + ucMaxBw = cnmGetDbdcBwCapability(prAdapter, + prBssInfo->ucBssIndex); + rlmFillVhtOpInfoByBssOpBw(prBssInfo, ucMaxBw); + + /* If the S1 is invalid, force to change bandwidth */ + if (prBssInfo->ucVhtChannelFrequencyS1 == 0) + prBssInfo->ucVhtChannelWidth = + VHT_OP_CHANNEL_WIDTH_20_40; + } else { + prBssInfo->ucVhtChannelWidth = VHT_OP_CHANNEL_WIDTH_20_40; + prBssInfo->ucVhtChannelFrequencyS1 = 0; + prBssInfo->ucVhtChannelFrequencyS2 = 0; + } + +#if (CFG_SUPPORT_802_11AX == 1) + /* Filled the HE Operation IE */ + if (prBssInfo->ucPhyTypeSet & PHY_TYPE_BIT_HE) { + memset(prBssInfo->ucHeOpParams, 0, HE_OP_BYTE_NUM); + + /* Disable BSS color support*/ + prBssInfo->ucBssColorInfo |= + BIT(HE_OP_BSSCOLOR_BSS_COLOR_DISABLE_SHFT); + + prBssInfo->u2HeBasicMcsSet |= (HE_CAP_INFO_MCS_MAP_MCS11 << 0); + for (i = 1; i < 8; i++) + prBssInfo->u2HeBasicMcsSet |= + (HE_CAP_INFO_MCS_NOT_SUPPORTED << 2 * i); + } else { + memset(prBssInfo->ucHeOpParams, 0, HE_OP_BYTE_NUM); + prBssInfo->ucBssColorInfo = 0; + prBssInfo->u2HeBasicMcsSet = 0; + } +#endif + + /*ERROR HANDLE*/ + if ((prBssInfo->ucVhtChannelWidth == VHT_OP_CHANNEL_WIDTH_80) + || (prBssInfo->ucVhtChannelWidth + == VHT_OP_CHANNEL_WIDTH_160) + || (prBssInfo->ucVhtChannelWidth + == VHT_OP_CHANNEL_WIDTH_80P80)) { + + if (prBssInfo->ucVhtChannelFrequencyS1 == 0) { + DBGLOG(RLM, INFO, + "Wrong AP S1 parameter setting, back to BW20!!!\n"); + + prBssInfo->ucVhtChannelWidth = + VHT_OP_CHANNEL_WIDTH_20_40; + prBssInfo->ucVhtChannelFrequencyS1 = 0; + prBssInfo->ucVhtChannelFrequencyS2 = 0; + } + } + + /* We may limit AP/GO Nss by RfBand in some case, ex CoAnt. + * Recalculte Nss when channel is selected. + */ + cnmOpModeGetTRxNss(prAdapter, + prBssInfo->ucBssIndex, + &prBssInfo->ucOpRxNss, + &prBssInfo->ucOpTxNss); + + DBGLOG(RLM, INFO, + "WLAN AP SCO=%d BW=%d S1=%d S2=%d CH=%d Band=%d TxN=%d RxN=%d\n", + prBssInfo->eBssSCO, + prBssInfo->ucVhtChannelWidth, + prBssInfo->ucVhtChannelFrequencyS1, + prBssInfo->ucVhtChannelFrequencyS2, + prBssInfo->ucPrimaryChannel, + prBssInfo->eBand, + prBssInfo->ucOpTxNss, + prBssInfo->ucOpRxNss); + +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief For probe response (GO, IBSS) and association response + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rlmRspGenerateObssScanIE(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo) +{ + struct BSS_INFO *prBssInfo; + struct IE_OBSS_SCAN_PARAM *prObssScanIe; + struct STA_RECORD *prStaRec = + (struct STA_RECORD *) NULL; + + ASSERT(prAdapter); + ASSERT(prMsduInfo); + + prStaRec = cnmGetStaRecByIndex(prAdapter, + prMsduInfo->ucStaRecIndex); + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prMsduInfo->ucBssIndex); + + if (!prBssInfo) + return; + + if (!IS_BSS_ACTIVE(prBssInfo)) + return; + + /* !RLM_NET_IS_BOW(prBssInfo) && FIXME. */ + if (RLM_NET_IS_11N(prBssInfo) && + prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT && + (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)) && + prBssInfo->eBand == BAND_2G4 && + prBssInfo->eBssSCO != CHNL_EXT_SCN) { + + prObssScanIe = (struct IE_OBSS_SCAN_PARAM *) + (((uint8_t *) prMsduInfo->prPacket) + + prMsduInfo->u2FrameLength); + + /* Add 20/40 BSS coexistence IE */ + prObssScanIe->ucId = ELEM_ID_OBSS_SCAN_PARAMS; + prObssScanIe->ucLength = + sizeof(struct IE_OBSS_SCAN_PARAM) - ELEM_HDR_LEN; + + prObssScanIe->u2ScanPassiveDwell = + dot11OBSSScanPassiveDwell; + prObssScanIe->u2ScanActiveDwell = + dot11OBSSScanActiveDwell; + prObssScanIe->u2TriggerScanInterval = + dot11BSSWidthTriggerScanInterval; + prObssScanIe->u2ScanPassiveTotalPerChnl = + dot11OBSSScanPassiveTotalPerChannel; + prObssScanIe->u2ScanActiveTotalPerChnl = + dot11OBSSScanActiveTotalPerChannel; + prObssScanIe->u2WidthTransDelayFactor = + dot11BSSWidthChannelTransitionDelayFactor; + prObssScanIe->u2ScanActivityThres = + dot11OBSSScanActivityThreshold; + + ASSERT( + IE_SIZE(prObssScanIe) + <= (ELEM_HDR_LEN + ELEM_MAX_LEN_OBSS_SCAN)); + + prMsduInfo->u2FrameLength += IE_SIZE(prObssScanIe); + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief P2P GO. + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +u_int8_t rlmUpdateBwByChListForAP(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo) +{ + uint8_t ucLevel; + u_int8_t fgBwChange; + + ASSERT(prAdapter); + ASSERT(prBssInfo); + + fgBwChange = FALSE; + + if (prBssInfo->eBssSCO == CHNL_EXT_SCN) + return fgBwChange; + + ucLevel = rlmObssChnlLevel(prBssInfo, + prBssInfo->eBand, + prBssInfo->ucPrimaryChannel, + prBssInfo->eBssSCO); + + if (ucLevel == CHNL_LEVEL0) { + /* Forced to 20MHz, + * so extended channel is SCN and STA width is zero + */ + prBssInfo->fgObssActionForcedTo20M = TRUE; + + if (prBssInfo->ucHtOpInfo1 != (uint8_t) CHNL_EXT_SCN) { + prBssInfo->ucHtOpInfo1 = (uint8_t) CHNL_EXT_SCN; + fgBwChange = TRUE; + } + + cnmTimerStartTimer(prAdapter, + &prBssInfo->rObssScanTimer, + OBSS_20_40M_TIMEOUT * MSEC_PER_SEC); + } + + /* Clear up all channel lists */ + prBssInfo->auc2G_20mReqChnlList[0] = 0; + prBssInfo->auc2G_NonHtChnlList[0] = 0; + prBssInfo->auc2G_PriChnlList[0] = 0; + prBssInfo->auc2G_SecChnlList[0] = 0; + prBssInfo->auc5G_20mReqChnlList[0] = 0; + prBssInfo->auc5G_NonHtChnlList[0] = 0; + prBssInfo->auc5G_PriChnlList[0] = 0; + prBssInfo->auc5G_SecChnlList[0] = 0; + + return fgBwChange; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rlmProcessPublicAction(struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb) +{ + struct ACTION_20_40_COEXIST_FRAME *prRxFrame; + struct IE_20_40_COEXIST *prCoexist; + struct IE_INTOLERANT_CHNL_REPORT *prChnlReport; + struct BSS_INFO *prBssInfo; + struct STA_RECORD *prStaRec; + uint8_t *pucIE; + uint16_t u2IELength, u2Offset; + uint8_t i, j; + + ASSERT(prAdapter); + ASSERT(prSwRfb); + + prRxFrame = (struct ACTION_20_40_COEXIST_FRAME *) prSwRfb->pvHeader; + prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); + + if (!(prSwRfb->prStaRec)) { + return; + } + + if (prRxFrame->ucAction != ACTION_PUBLIC_20_40_COEXIST + || !prStaRec + || prStaRec->ucStaState != STA_STATE_3 + || prSwRfb->u2PacketLen < (WLAN_MAC_MGMT_HEADER_LEN + 5) + || prSwRfb->prStaRec->ucBssIndex != + /* HIF_RX_HDR_GET_NETWORK_IDX(prSwRfb->prHifRxHdr) != */ + prStaRec->ucBssIndex) { + return; + } + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prStaRec->ucBssIndex); + ASSERT(prBssInfo); + + if (!IS_BSS_ACTIVE(prBssInfo) || + prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT + || prBssInfo->eBssSCO == CHNL_EXT_SCN) { + return; + } + + prCoexist = &prRxFrame->rBssCoexist; + if (prCoexist->ucData + & (BSS_COEXIST_40M_INTOLERANT + | BSS_COEXIST_20M_REQ)) { + + ASSERT(prBssInfo->auc2G_20mReqChnlList[0] + <= CHNL_LIST_SZ_2G); + + for (i = 1; i <= prBssInfo->auc2G_20mReqChnlList[0] + && i <= CHNL_LIST_SZ_2G; i++) { + + if (prBssInfo->auc2G_20mReqChnlList[i] + == prBssInfo->ucPrimaryChannel) + break; + } + if ((i > prBssInfo->auc2G_20mReqChnlList[0]) + && (i <= CHNL_LIST_SZ_2G)) { + prBssInfo->auc2G_20mReqChnlList[i] = + prBssInfo->ucPrimaryChannel; + prBssInfo->auc2G_20mReqChnlList[0]++; + } + } + + /* Process intolerant channel report IE */ + pucIE = (uint8_t *) &prRxFrame->rChnlReport; + u2IELength = prSwRfb->u2PacketLen - (WLAN_MAC_MGMT_HEADER_LEN + 5); + + IE_FOR_EACH(pucIE, u2IELength, u2Offset) { + switch (IE_ID(pucIE)) { + case ELEM_ID_20_40_INTOLERANT_CHNL_REPORT: + prChnlReport = + (struct IE_INTOLERANT_CHNL_REPORT *) pucIE; + + if (prChnlReport->ucLength <= 1) + break; + + /* To do: process regulatory class. + * Now we assume 2.4G band + */ + + for (j = 0; j < prChnlReport->ucLength - 1; j++) { + /* Update non-HT channel list */ + ASSERT(prBssInfo->auc2G_NonHtChnlList[0] + <= CHNL_LIST_SZ_2G); + for (i = 1; + i <= prBssInfo->auc2G_NonHtChnlList[0] + && i <= CHNL_LIST_SZ_2G; i++) { + + if (prBssInfo->auc2G_NonHtChnlList[i] + == + prChnlReport->aucChannelList[j]) + break; + } + if ((i > prBssInfo->auc2G_NonHtChnlList[0]) + && (i <= CHNL_LIST_SZ_2G)) { + prBssInfo->auc2G_NonHtChnlList[i] = + prChnlReport->aucChannelList[j]; + prBssInfo->auc2G_NonHtChnlList[0]++; + } + } + break; + + default: + break; + } + } /* end of IE_FOR_EACH */ + + if (rlmUpdateBwByChListForAP(prAdapter, prBssInfo)) { + bssUpdateBeaconContent(prAdapter, prBssInfo->ucBssIndex); + rlmSyncOperationParams(prAdapter, prBssInfo); + } + + /* Check if OBSS scan exemption response should be sent */ + if (prCoexist->ucData & BSS_COEXIST_OBSS_SCAN_EXEMPTION_REQ) + rlmObssScanExemptionRsp(prAdapter, prBssInfo, prSwRfb); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rlmHandleObssStatusEventPkt(struct ADAPTER *prAdapter, + struct EVENT_AP_OBSS_STATUS *prObssStatus) +{ + struct BSS_INFO *prBssInfo; + + ASSERT(prAdapter); + ASSERT(prObssStatus); + ASSERT(prObssStatus->ucBssIndex + < prAdapter->ucHwBssIdNum); + + prBssInfo = + GET_BSS_INFO_BY_INDEX(prAdapter, prObssStatus->ucBssIndex); + + if (prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) + return; + + prBssInfo->fgObssErpProtectMode = + (u_int8_t) prObssStatus->ucObssErpProtectMode; + prBssInfo->eObssHtProtectMode = + (enum ENUM_HT_PROTECT_MODE) prObssStatus->ucObssHtProtectMode; + prBssInfo->eObssGfOperationMode = + (enum ENUM_GF_MODE) prObssStatus->ucObssGfOperationMode; + prBssInfo->fgObssRifsOperationMode = + (u_int8_t) prObssStatus->ucObssRifsOperationMode; + prBssInfo->fgObssBeaconForcedTo20M = + (u_int8_t) prObssStatus->ucObssBeaconForcedTo20M; + + /* Check if Beacon content need to be updated */ + rlmUpdateParamsForAP(prAdapter, prBssInfo, TRUE); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief It is only for AP mode in NETWORK_TYPE_P2P_INDEX. + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rlmUpdateParamsForAP(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, + u_int8_t fgUpdateBeacon) +{ + struct LINK *prStaList; + struct STA_RECORD *prStaRec; + u_int8_t fgErpProtectMode, fgSta40mIntolerant; + u_int8_t fgUseShortPreamble, fgUseShortSlotTime; + enum ENUM_HT_PROTECT_MODE eHtProtectMode; + enum ENUM_GF_MODE eGfOperationMode; + uint8_t ucHtOpInfo1; + + ASSERT(prAdapter); + ASSERT(prBssInfo); + + if (!IS_BSS_ACTIVE(prBssInfo) + || prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) + return; + + fgErpProtectMode = FALSE; + eHtProtectMode = HT_PROTECT_MODE_NONE; + eGfOperationMode = GF_MODE_NORMAL; + fgSta40mIntolerant = FALSE; + fgUseShortPreamble = prBssInfo->fgIsShortPreambleAllowed; + fgUseShortSlotTime = TRUE; + ucHtOpInfo1 = (uint8_t) CHNL_EXT_SCN; + + prStaList = &prBssInfo->rStaRecOfClientList; + + LINK_FOR_EACH_ENTRY(prStaRec, + prStaList, rLinkEntry, struct STA_RECORD) { + if (!prStaRec) { + DBGLOG(P2P, WARN, + "NULL STA_REC ptr in BSS client list\n"); + bssDumpClientList(prAdapter, prBssInfo); + break; + } + + if (prStaRec->fgIsInUse + && prStaRec->ucStaState == STA_STATE_3 + && prStaRec->ucBssIndex == prBssInfo->ucBssIndex) { + if (!(prStaRec->ucPhyTypeSet + & (PHY_TYPE_SET_802_11GN + | PHY_TYPE_SET_802_11A))) { + /* B-only mode, so mode 1 (ERP protection) */ + fgErpProtectMode = TRUE; + } + + if (!(prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)) { + /* BG-only or A-only */ + eHtProtectMode = HT_PROTECT_MODE_NON_HT; + } else if (prBssInfo->fg40mBwAllowed && + !(prStaRec->u2HtCapInfo + & HT_CAP_INFO_SUP_CHNL_WIDTH)) { + /* 20MHz-only */ + if (eHtProtectMode == HT_PROTECT_MODE_NONE) + eHtProtectMode = HT_PROTECT_MODE_20M; + } + + if (!(prStaRec->u2HtCapInfo & HT_CAP_INFO_HT_GF)) + eGfOperationMode = GF_MODE_PROTECT; + + if (!(prStaRec->u2CapInfo & CAP_INFO_SHORT_PREAMBLE)) + fgUseShortPreamble = FALSE; +#if 1 + /* ap mode throughput enhancement + * only 2.4G with B mode client connecion + * use long slot time + */ + if ((!(prStaRec->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME)) + && fgErpProtectMode + && prBssInfo->eBand == BAND_2G4) + fgUseShortSlotTime = FALSE; +#else + if (!(prStaRec->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME)) + fgUseShortSlotTime = FALSE; +#endif + if (prStaRec->u2HtCapInfo & HT_CAP_INFO_40M_INTOLERANT) + fgSta40mIntolerant = TRUE; + } + } /* end of LINK_FOR_EACH_ENTRY */ + + /* Check if HT operation IE + * about 20/40M bandwidth shall be updated + */ + if (prBssInfo->eBssSCO != CHNL_EXT_SCN) { + if (/*!LINK_IS_EMPTY(prStaList) && */ !fgSta40mIntolerant && + !prBssInfo->fgObssActionForcedTo20M + && !prBssInfo->fgObssBeaconForcedTo20M) { + + ucHtOpInfo1 = (uint8_t) + (((uint32_t) prBssInfo->eBssSCO) + | HT_OP_INFO1_STA_CHNL_WIDTH); + } + } + + /* Check if any new parameter may be updated */ + if (prBssInfo->fgErpProtectMode != fgErpProtectMode || + prBssInfo->eHtProtectMode != eHtProtectMode || + prBssInfo->eGfOperationMode != eGfOperationMode || + prBssInfo->ucHtOpInfo1 != ucHtOpInfo1 || + prBssInfo->fgUseShortPreamble != fgUseShortPreamble || + prBssInfo->fgUseShortSlotTime != fgUseShortSlotTime) { + + prBssInfo->fgErpProtectMode = fgErpProtectMode; + prBssInfo->eHtProtectMode = eHtProtectMode; + prBssInfo->eGfOperationMode = eGfOperationMode; + prBssInfo->ucHtOpInfo1 = ucHtOpInfo1; + prBssInfo->fgUseShortPreamble = fgUseShortPreamble; + prBssInfo->fgUseShortSlotTime = fgUseShortSlotTime; + + if (fgUseShortSlotTime) + prBssInfo->u2CapInfo |= CAP_INFO_SHORT_SLOT_TIME; + else + prBssInfo->u2CapInfo &= ~CAP_INFO_SHORT_SLOT_TIME; + + rlmSyncOperationParams(prAdapter, prBssInfo); + fgUpdateBeacon = TRUE; + } + + /* Update Beacon content if related IE content is changed */ + if (fgUpdateBeacon) + bssUpdateBeaconContent(prAdapter, prBssInfo->ucBssIndex); +} +#if 0 +/*----------------------------------------------------------------------------*/ +/*! + * \brief Initial the channel list from the domain information. + * This function is called after P2P initial + * and Domain information changed. + * Make sure the device is disconnected + * while changing domain information. + * + * \param[in] prAdapter Pointer of ADAPTER_T + * + * \return boolean value if probe response frame is + */ +/*----------------------------------------------------------------------------*/ +void rlmFuncInitialChannelList(IN struct ADAPTER *prAdapter) +{ + struct P2P_CONNECTION_SETTINGS *prP2pConnSetting = + (struct P2P_CONNECTION_SETTINGS *) NULL; + struct DOMAIN_INFO_ENTRY *prDomainInfoEntry = + (struct DOMAIN_INFO_ENTRY *) NULL; + struct DOMAIN_SUBBAND_INFO *prDomainSubBand = + (struct DOMAIN_SUBBAND_INFO *) NULL; + struct CHANNEL_ENTRY_FIELD *prChannelEntryField = + (struct CHANNEL_ENTRY_FIELD *) NULL; + uint32_t u4Idx = 0, u4IdxII = 0; + uint8_t ucBufferSize = P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE; +#if 0 + uint8_t ucSocialChnlSupport = 0, ucAutoChnl = 0; +#endif + + do { + ASSERT_BREAK(prAdapter != NULL); + + prP2pConnSetting = prAdapter->rWifiVar.prP2PConnSettings; +#if 0 + ucAutoChnl = prP2pConnSetting->ucOperatingChnl; +#endif + + prDomainInfoEntry = rlmDomainGetDomainInfo(prAdapter); + + ASSERT_BREAK((prDomainInfoEntry != NULL) + && (prP2pConnSetting != NULL)); + + prChannelEntryField = + (struct CHANNEL_ENTRY_FIELD *) + prP2pConnSetting->aucChannelEntriesField; + + for (u4Idx = 0; u4Idx < MAX_SUBBAND_NUM; u4Idx++) { + prDomainSubBand = &prDomainInfoEntry->rSubBand[u4Idx]; + + if (((prDomainSubBand->ucBand == BAND_5G) + && (!prAdapter->fgEnable5GBand)) + || (prDomainSubBand->ucBand == BAND_NULL)) { + continue; + } + + if (ucBufferSize < + (P2P_ATTRI_LEN_CHANNEL_ENTRY + + prDomainSubBand->ucNumChannels)) { + /* Buffer is not enough + * to include all supported channels. + */ + break; /* for */ + } + + prChannelEntryField->ucRegulatoryClass = + prDomainSubBand->ucRegClass; + prChannelEntryField->ucNumberOfChannels = + prDomainSubBand->ucNumChannels; + + for (u4IdxII = 0; + u4IdxII < prDomainSubBand->ucNumChannels; + u4IdxII++) { + prChannelEntryField + ->aucChannelList[u4IdxII] = + prDomainSubBand->ucFirstChannelNum + + (u4IdxII + * prDomainSubBand->ucChannelSpan); + +#if 0 + switch (prChannelEntryField + ->aucChannelList[u4IdxII]) { + case 1: + ucSocialChnlSupport = 1; + break; + case 6: + ucSocialChnlSupport = 6; + break; + case 11: + ucSocialChnlSupport = 11; + break; + default: + break; + } + +#endif + } + + if (ucBufferSize >= (P2P_ATTRI_LEN_CHANNEL_ENTRY + + prChannelEntryField->ucNumberOfChannels)) + ucBufferSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + + prChannelEntryField->ucNumberOfChannels); + else + break; + + prChannelEntryField = + (struct CHANNEL_ENTRY_FIELD *) + ((unsigned long) prChannelEntryField + + P2P_ATTRI_LEN_CHANNEL_ENTRY + + (unsigned long) + prChannelEntryField->ucNumberOfChannels); + + } + +#if 0 + if (prP2pConnSetting->ucListenChnl == 0) { + prP2pConnSetting->ucListenChnl = + P2P_DEFAULT_LISTEN_CHANNEL; + + if (ucSocialChnlSupport != 0) { + /* 1. User Not Set LISTEN channel. + * 2. Social channel is not empty. + */ + prP2pConnSetting->ucListenChnl = + ucSocialChnlSupport; + } + } +#endif + + /* TODO: 20110921 frog - */ + /* If LISTEN channel is not set, + * a random supported channel would be set. + * If no social channel is supported, + * DEFAULT channel would be set. + */ + + prP2pConnSetting->ucRfChannelListSize = + P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE - ucBufferSize; + +#if 0 + /* User not set OPERATE channel. */ + if (prP2pConnSetting->ucOperatingChnl == 0) { + + if (scnQuerySparseChannel(prAdapter, NULL, &ucAutoChnl)) + break; /* while */ + + ucBufferSize = prP2pConnSetting->ucRfChannelListSize; + + prChannelEntryField = + (struct CHANNEL_ENTRY_FIELD *) + prP2pConnSetting->aucChannelEntriesField; + + while (ucBufferSize != 0) { + if (prChannelEntryField + ->ucNumberOfChannels != 0) { + ucAutoChnl = + prChannelEntryField->aucChannelList[0]; + break; /* while */ + } + + else { + prChannelEntryField = + (struct CHANNEL_ENTRY_FIELD *) + ((uint32_t) prChannelEntryField + + P2P_ATTRI_LEN_CHANNEL_ENTRY + + (uint32_t) + prChannelEntryField + ->ucNumberOfChannels); + + ucBufferSize -= + (P2P_ATTRI_LEN_CHANNEL_ENTRY + + + prChannelEntryField + ->ucNumberOfChannels); + } + + } + + } +#endif + /* We assume user would not set a channel + * not in the channel list. + * If so, the operating channel still depends + * on target device supporting capability. + */ + + /* TODO: 20110921 frog - */ + /* If the Operating channel is not set, + * a channel from supported channel list is set automatically. + * If there is no supported channel in channel list, + * a DEFAULT channel is set. + */ + + } while (FALSE); + +#if 0 + prP2pConnSetting->ucOperatingChnl = ucAutoChnl; +#endif +} /* rlmFuncInitialChannelList */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Find a common channel list from the local channel list info + * & target channel list info. + * + * \param[in] prAdapter Pointer of ADAPTER_T + * + * \return boolean value if probe response frame is + */ +/*----------------------------------------------------------------------------*/ +void +rlmFuncCommonChannelList(IN struct ADAPTER *prAdapter, + IN struct CHANNEL_ENTRY_FIELD *prChannelEntryII, + IN uint8_t ucChannelListSize) +{ + struct P2P_CONNECTION_SETTINGS *prP2pConnSetting = + (struct P2P_CONNECTION_SETTINGS *) NULL; + struct CHANNEL_ENTRY_FIELD *prChannelEntryI = + (struct CHANNEL_ENTRY_FIELD *) NULL, + prChannelEntryIII = (struct CHANNEL_ENTRY_FIELD *) NULL; + uint8_t aucCommonChannelList[P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE]; + uint8_t ucOriChnlSize = 0, ucNewChnlSize = 0; + + do { + + ASSERT_BREAK(prAdapter != NULL); + + prP2pConnSetting = prAdapter->rWifiVar.prP2PConnSettings; + + prChannelEntryIII = + (struct CHANNEL_ENTRY_FIELD *) aucCommonChannelList; + + while (ucChannelListSize > 0) { + + prChannelEntryI = + (struct CHANNEL_ENTRY_FIELD *) + prP2pConnSetting->aucChannelEntriesField; + ucOriChnlSize = prP2pConnSetting->ucRfChannelListSize; + + while (ucOriChnlSize > 0) { + if (prChannelEntryI->ucRegulatoryClass == + prChannelEntryII->ucRegulatoryClass) { + + prChannelEntryIII->ucRegulatoryClass = + prChannelEntryI->ucRegulatoryClass; + + /* TODO: Currently we assume + * that the regulatory class the same, + * the channels are the same. + */ + kalMemCopy( + prChannelEntryIII->aucChannelList, + prChannelEntryII->aucChannelList, + prChannelEntryII->ucNumberOfChannels); + + prChannelEntryIII->ucNumberOfChannels = + prChannelEntryII->ucNumberOfChannels; + + ucNewChnlSize += + P2P_ATTRI_LEN_CHANNEL_ENTRY + + prChannelEntryIII->ucNumberOfChannels; + + prChannelEntryIII = + (struct CHANNEL_ENTRY_FIELD *) + ((unsigned long) + prChannelEntryIII + + P2P_ATTRI_LEN_CHANNEL_ENTRY + + (unsigned long) + prChannelEntryIII + ->ucNumberOfChannels); + } + + ucOriChnlSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + + prChannelEntryI->ucNumberOfChannels); + + prChannelEntryI = + (struct CHANNEL_ENTRY_FIELD *) + ((unsigned long) prChannelEntryI + + P2P_ATTRI_LEN_CHANNEL_ENTRY + + (unsigned long) + prChannelEntryI->ucNumberOfChannels); + + } + + ucChannelListSize -= + (P2P_ATTRI_LEN_CHANNEL_ENTRY + + prChannelEntryII->ucNumberOfChannels); + + prChannelEntryII = (struct CHANNEL_ENTRY_FIELD *) + ((unsigned long) prChannelEntryII + + P2P_ATTRI_LEN_CHANNEL_ENTRY + + (unsigned long) + prChannelEntryII->ucNumberOfChannels); + + } + + kalMemCopy(prP2pConnSetting->aucChannelEntriesField, + aucCommonChannelList, + ucNewChnlSize); + prP2pConnSetting->ucRfChannelListSize = ucNewChnlSize; + + } while (FALSE); +} /* rlmFuncCommonChannelList */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +uint8_t rlmFuncFindOperatingClass(IN struct ADAPTER *prAdapter, + IN uint8_t ucChannelNum) +{ + uint8_t ucRegulatoryClass = 0, ucBufferSize = 0; + struct P2P_CONNECTION_SETTINGS *prP2pConnSetting = + (struct P2P_CONNECTION_SETTINGS *) NULL; + struct CHANNEL_ENTRY_FIELD *prChannelEntryField = + (struct CHANNEL_ENTRY_FIELD *) NULL; + uint32_t u4Idx = 0; + + do { + ASSERT_BREAK(prAdapter != NULL); + + prP2pConnSetting = prAdapter->rWifiVar.prP2PConnSettings; + ucBufferSize = prP2pConnSetting->ucRfChannelListSize; + prChannelEntryField = + (struct CHANNEL_ENTRY_FIELD *) + prP2pConnSetting->aucChannelEntriesField; + + while (ucBufferSize != 0) { + + for (u4Idx = 0; + u4Idx < prChannelEntryField->ucNumberOfChannels; + u4Idx++) { + if (prChannelEntryField->aucChannelList[u4Idx] + == ucChannelNum) { + ucRegulatoryClass = + prChannelEntryField + ->ucRegulatoryClass; + break; + } + + } + + if (ucRegulatoryClass != 0) + break; /* while */ + + prChannelEntryField = + (struct CHANNEL_ENTRY_FIELD *) + ((unsigned long) prChannelEntryField + + P2P_ATTRI_LEN_CHANNEL_ENTRY + + (unsigned long) + prChannelEntryField->ucNumberOfChannels); + + ucBufferSize -= + (P2P_ATTRI_LEN_CHANNEL_ENTRY + + prChannelEntryField->ucNumberOfChannels); + + } + + } while (FALSE); + + return ucRegulatoryClass; +} /* rlmFuncFindOperatingClass */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +u_int8_t +rlmFuncFindAvailableChannel(IN struct ADAPTER *prAdapter, + IN uint8_t ucCheckChnl, + IN uint8_t *pucSuggestChannel, + IN u_int8_t fgIsSocialChannel, + IN u_int8_t fgIsDefaultChannel) +{ + u_int8_t fgIsResultAvailable = FALSE; + struct CHANNEL_ENTRY_FIELD *prChannelEntry = + (struct CHANNEL_ENTRY_FIELD *) NULL; + struct P2P_CONNECTION_SETTINGS *prP2pConnSetting = + (struct P2P_CONNECTION_SETTINGS *) NULL; + uint8_t ucBufferSize = 0, ucIdx = 0, ucChannelSelected = 0; + + do { + ASSERT_BREAK(prAdapter != NULL); + + if (fgIsDefaultChannel) + ucChannelSelected = P2P_DEFAULT_LISTEN_CHANNEL; + + prP2pConnSetting = prAdapter->rWifiVar.prP2PConnSettings; + ucBufferSize = prP2pConnSetting->ucRfChannelListSize; + prChannelEntry = + (struct CHANNEL_ENTRY_FIELD *) + prP2pConnSetting->aucChannelEntriesField; + + while ((ucBufferSize != 0) && (!fgIsResultAvailable)) { + + for (ucIdx = 0; + ucIdx < prChannelEntry->ucNumberOfChannels; + ucIdx++) { + + if ((!fgIsSocialChannel) || + (prChannelEntry->aucChannelList[ucIdx] + == 1) || + (prChannelEntry->aucChannelList[ucIdx] + == 6) || + (prChannelEntry->aucChannelList[ucIdx] + == 11)) { + + if (prChannelEntry + ->aucChannelList[ucIdx] <= 11) { + /* 2.4G. */ + ucChannelSelected = + prChannelEntry + ->aucChannelList[ucIdx]; + } else if (( + prChannelEntry + ->aucChannelList[ucIdx] < 52) + && + (prChannelEntry + ->aucChannelList[ucIdx] > 14)) { + + /* 2.4G + 5G. */ + ucChannelSelected = + prChannelEntry + ->aucChannelList[ucIdx]; + } + + if (ucChannelSelected == ucCheckChnl) { + fgIsResultAvailable = TRUE; + break; + } + } + + } + + ucBufferSize -= + (P2P_ATTRI_LEN_CHANNEL_ENTRY + + prChannelEntry->ucNumberOfChannels); + + prChannelEntry = + (struct CHANNEL_ENTRY_FIELD *) + ((unsigned long) prChannelEntry + + P2P_ATTRI_LEN_CHANNEL_ENTRY + + (unsigned long) + prChannelEntry->ucNumberOfChannels); + + } + + if ((!fgIsResultAvailable) + && (pucSuggestChannel != NULL)) { + log_dbg(P2P, TRACE, + "The request channel %d is not available, sugguested channel:%d\n", + ucCheckChnl, ucChannelSelected); + + /* Given a suggested channel. */ + *pucSuggestChannel = ucChannelSelected; + } + + } while (FALSE); + + return fgIsResultAvailable; +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +enum ENUM_CHNL_EXT rlmDecideScoForAP(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo) +{ + struct DOMAIN_SUBBAND_INFO *prSubband; + struct DOMAIN_INFO_ENTRY *prDomainInfo; + uint8_t ucSecondChannel, i, j; + enum ENUM_CHNL_EXT eSCO; + enum ENUM_CHNL_EXT eTempSCO; + /*chip capability*/ + uint8_t ucMaxBandwidth = MAX_BW_80_80_MHZ; + + eSCO = CHNL_EXT_SCN; + eTempSCO = CHNL_EXT_SCN; + + if (prBssInfo->eBand == BAND_2G4) { + if (prBssInfo->ucPrimaryChannel != 14) + eSCO = (prBssInfo->ucPrimaryChannel > 7) + ? CHNL_EXT_SCB : CHNL_EXT_SCA; + } else { + if (regd_is_single_sku_en()) { + if (rlmDomainIsLegalChannel(prAdapter, + prBssInfo->eBand, + prBssInfo->ucPrimaryChannel)) + eSCO = rlmSelectSecondaryChannelType(prAdapter, + prBssInfo->eBand, + prBssInfo->ucPrimaryChannel); + } else { + prDomainInfo = rlmDomainGetDomainInfo(prAdapter); + ASSERT(prDomainInfo); + + for (i = 0; i < MAX_SUBBAND_NUM; i++) { + prSubband = &prDomainInfo->rSubBand[i]; + if (prSubband->ucBand == prBssInfo->eBand) { + for (j = 0; j < prSubband->ucNumChannels; j++) { + if ((prSubband->ucFirstChannelNum + + j * prSubband->ucChannelSpan) + == prBssInfo->ucPrimaryChannel) { + eSCO = (j & 1) + ? CHNL_EXT_SCB + : CHNL_EXT_SCA; + break; + } + } + + if (j < prSubband->ucNumChannels) + break; /* Found */ + } + } + } + } + + /* Check if it is boundary channel + * and 40MHz BW is permitted + */ + if (eSCO != CHNL_EXT_SCN) { + ucSecondChannel = (eSCO == CHNL_EXT_SCA) + ? (prBssInfo->ucPrimaryChannel + CHNL_SPAN_20) + : (prBssInfo->ucPrimaryChannel - CHNL_SPAN_20); + + if (!rlmDomainIsLegalChannel(prAdapter, + prBssInfo->eBand, + ucSecondChannel)) + eSCO = CHNL_EXT_SCN; + } + + /* Overwrite SCO settings by wifi cfg */ + if (IS_BSS_P2P(prBssInfo)) { + /* AP mode */ + if (p2pFuncIsAPMode(prAdapter->rWifiVar + .prP2PConnSettings[prBssInfo->u4PrivateData])) { + if (prAdapter->rWifiVar.ucApSco == CHNL_EXT_SCA + || prAdapter->rWifiVar.ucApSco == CHNL_EXT_SCB) + eTempSCO = + (enum ENUM_CHNL_EXT) + prAdapter->rWifiVar.ucApSco; + } + /* P2P mode */ + else { + if (prAdapter->rWifiVar.ucP2pGoSco == CHNL_EXT_SCA || + prAdapter->rWifiVar.ucP2pGoSco == CHNL_EXT_SCB) { + eTempSCO = + (enum ENUM_CHNL_EXT) + prAdapter->rWifiVar.ucP2pGoSco; + } + } + + /* Check again if it is boundary channel + * and 40MHz BW is permitted + */ + if (eTempSCO != CHNL_EXT_SCN) { + ucSecondChannel = (eTempSCO == CHNL_EXT_SCA) + ? (prBssInfo->ucPrimaryChannel + 4) + : (prBssInfo->ucPrimaryChannel - 4); + if (rlmDomainIsLegalChannel(prAdapter, + prBssInfo->eBand, + ucSecondChannel)) + eSCO = eTempSCO; + } + } + + /* Overwrite SCO settings by wifi cfg bandwidth setting */ + if (IS_BSS_P2P(prBssInfo)) { + /* AP mode */ + if (p2pFuncIsAPMode(prAdapter->rWifiVar + .prP2PConnSettings[prBssInfo->u4PrivateData])) { + if (prBssInfo->eBand == BAND_2G4) + ucMaxBandwidth = + prAdapter->rWifiVar.ucAp2gBandwidth; + else + ucMaxBandwidth = + prAdapter->rWifiVar.ucAp5gBandwidth; + } + /* P2P mode */ + else { + if (prBssInfo->eBand == BAND_2G4) + ucMaxBandwidth = + prAdapter->rWifiVar.ucP2p2gBandwidth; + else + ucMaxBandwidth = + prAdapter->rWifiVar.ucP2p5gBandwidth; + } + + if (ucMaxBandwidth < MAX_BW_40MHZ) + eSCO = CHNL_EXT_SCN; + } + + return eSCO; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief: Get AP secondary channel offset from cfg80211 or wifi.cfg + * + * \param[in] prAdapter Pointer of ADAPTER_T, prBssInfo Pointer of BSS_INFO_T, + * + * \return ENUM_CHNL_EXT_T AP secondary channel offset + */ +/*----------------------------------------------------------------------------*/ +enum ENUM_CHNL_EXT rlmGetScoForAP(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo) +{ + enum ENUM_BAND eBand; + uint8_t ucChannel; + enum ENUM_CHNL_EXT eSCO; + int32_t i4DeltaBw; + uint32_t u4AndOneSCO; + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *) NULL; + struct P2P_CONNECTION_REQ_INFO *prP2pConnReqInfo = + (struct P2P_CONNECTION_REQ_INFO *) NULL; + + prP2pRoleFsmInfo = p2pFuncGetRoleByBssIdx(prAdapter, + prBssInfo->ucBssIndex); + + if (!prAdapter->rWifiVar.ucApChnlDefFromCfg + && prP2pRoleFsmInfo) { + + prP2pConnReqInfo = &(prP2pRoleFsmInfo->rConnReqInfo); + eSCO = CHNL_EXT_SCN; + + if (cnmGetBssMaxBw(prAdapter, + prBssInfo->ucBssIndex) == MAX_BW_40MHZ) { + /* If BW 40, compare S0 and primary channel freq */ + if (prP2pConnReqInfo->u4CenterFreq1 + > prP2pConnReqInfo->u2PriChnlFreq) + eSCO = CHNL_EXT_SCA; + else + eSCO = CHNL_EXT_SCB; + } else if (cnmGetBssMaxBw(prAdapter, + prBssInfo->ucBssIndex) > MAX_BW_40MHZ) { + /* P: PriChnlFreq, + * A:CHNL_EXT_SCA, + * B: CHNL_EXT_SCB, -:BW SPAN 5M + */ + /* --|----|--CenterFreq1--|----|-- */ + /* --|----|--CenterFreq1--B----P-- */ + /* --|----|--CenterFreq1--P----A-- */ + i4DeltaBw = prP2pConnReqInfo->u2PriChnlFreq + - prP2pConnReqInfo->u4CenterFreq1; + u4AndOneSCO = CHNL_EXT_SCB; + eSCO = CHNL_EXT_SCA; + if (i4DeltaBw < 0) { + /* --|----|--CenterFreq1--|----|-- */ + /* --P----A--CenterFreq1--|----|-- */ + /* --B----P--CenterFreq1--|----|-- */ + u4AndOneSCO = CHNL_EXT_SCA; + eSCO = CHNL_EXT_SCB; + i4DeltaBw = -i4DeltaBw; + } + i4DeltaBw = i4DeltaBw - (CHANNEL_SPAN_20 >> 1); + if ((i4DeltaBw/CHANNEL_SPAN_20) & 1) + eSCO = u4AndOneSCO; + } + } else { + /* In this case, the first BSS's SCO is 40MHz + * and known, so AP can apply 40MHz bandwidth, + * but the first BSS's SCO may be changed + * later if its Beacon lost timeout occurs + */ + if (!(cnmPreferredChannel(prAdapter, + &eBand, &ucChannel, &eSCO) + && eSCO != CHNL_EXT_SCN + && ucChannel == prBssInfo->ucPrimaryChannel + && eBand == prBssInfo->eBand)) + eSCO = rlmDecideScoForAP(prAdapter, prBssInfo); + } + return eSCO; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief: Get AP channel number of Channel Center Frequency Segment 0 + * from cfg80211 or wifi.cfg + * + * \param[in] prAdapter Pointer of ADAPTER_T, prBssInfo Pointer of BSS_INFO_T, + * + * \return UINT_8 AP channel number of Channel Center Frequency Segment 0 + */ +/*----------------------------------------------------------------------------*/ +uint8_t rlmGetVhtS1ForAP(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo) +{ + uint32_t ucFreq1Channel; + uint8_t ucPrimaryChannel = prBssInfo->ucPrimaryChannel; + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *) NULL; + struct P2P_CONNECTION_REQ_INFO *prP2pConnReqInfo = + (struct P2P_CONNECTION_REQ_INFO *) NULL; + + prP2pRoleFsmInfo = + p2pFuncGetRoleByBssIdx(prAdapter, prBssInfo->ucBssIndex); + + if (prBssInfo->ucVhtChannelWidth == VHT_OP_CHANNEL_WIDTH_20_40) + return 0; + + if (!prAdapter->rWifiVar.ucApChnlDefFromCfg && prP2pRoleFsmInfo) { + prP2pConnReqInfo = &(prP2pRoleFsmInfo->rConnReqInfo); + ucFreq1Channel = + nicFreq2ChannelNum( + prP2pConnReqInfo->u4CenterFreq1 * 1000); + } else + ucFreq1Channel = + nicGetVhtS1(ucPrimaryChannel, + prBssInfo->ucVhtChannelWidth); + + return ucFreq1Channel; +} + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/p2p_rlm_obss.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/p2p_rlm_obss.c new file mode 100644 index 0000000000000000000000000000000000000000..548c0043663969b9a0b668349d93ea5d202b4295 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/p2p_rlm_obss.c @@ -0,0 +1,396 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: @(#) gl_p2p_cfg80211.c@@ + */ + +/*! \file gl_p2p_cfg80211.c + * \brief Main routines of Linux driver interface for Wi-Fi Direct + * using cfg80211 interface + * + * This file contains the main routines of Linux driver + * for MediaTek Inc. 802.11 + * Wireless LAN Adapters. + */ + +/****************************************************************************** + * C O M P I L E R F L A G S + ****************************************************************************** + */ + +/****************************************************************************** + * E X T E R N A L R E F E R E N C E S + ****************************************************************************** + */ + +/****************************************************************************** + * C O N S T A N T S + ****************************************************************************** + */ + +/****************************************************************************** + * D A T A T Y P E S + ****************************************************************************** + */ + +/****************************************************************************** + * P U B L I C D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * P R I V A T E D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * M A C R O S + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N D E C L A R A T I O N S + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N S + ****************************************************************************** + */ + +#include "precomp.h" + +static uint8_t rlmObssChnlLevelIn2G4(struct BSS_INFO *prBssInfo, + uint8_t ucPriChannel, enum ENUM_CHNL_EXT eExtend); + +static uint8_t rlmObssChnlLevelIn5G(struct BSS_INFO *prBssInfo, + uint8_t ucPriChannel, enum ENUM_CHNL_EXT eExtend); + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Different concurrent network has itself channel lists, and + * concurrent networks should have been recorded in channel lists. + * If role of active P2P is GO, assume associated AP of AIS will + * record our Beacon for P2P GO because of same channel. + * + * Note: If we have scenario of different channel in the future, + * the internal FW communication channel shall be established. + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +uint8_t rlmObssChnlLevel(struct BSS_INFO *prBssInfo, + enum ENUM_BAND eBand, + uint8_t ucPriChannel, + enum ENUM_CHNL_EXT eExtend) +{ + uint8_t ucChannelLevel; + + ASSERT(prBssInfo); + + if (eBand == BAND_2G4) { + ucChannelLevel = + rlmObssChnlLevelIn2G4(prBssInfo, ucPriChannel, eExtend); + + /* (TBD) If concurrent networks permit different channel, extra + * channel judgement should be added. Please refer to + * previous version of this file. + */ + } else if (eBand == BAND_5G) { + ucChannelLevel = + rlmObssChnlLevelIn5G(prBssInfo, ucPriChannel, eExtend); + + /* (TBD) If concurrent networks permit different channel, extra + * channel judgement should be added. Please refer to + * previous version of this file. + */ + } else { + ucChannelLevel = CHNL_LEVEL0; + } + + return ucChannelLevel; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +static uint8_t rlmObssChnlLevelIn2G4(struct BSS_INFO *prBssInfo, + uint8_t ucPriChannel, + enum ENUM_CHNL_EXT eExtend) +{ + uint8_t i, ucChannelLevel; + uint8_t ucSecChannel, ucCenterChannel; + uint8_t ucAffectedChnl_L, ucAffectedChnl_H; + + ASSERT(prBssInfo); + + ucChannelLevel = CHNL_LEVEL2; + + /* Calculate center channel for 2.4G band */ + if (eExtend == CHNL_EXT_SCA) { + ucCenterChannel = ucPriChannel + 2; + ucSecChannel = ucPriChannel + 4; + } else if (eExtend == CHNL_EXT_SCB) { + ucCenterChannel = ucPriChannel - 2; + ucSecChannel = ucPriChannel - 4; + } else { + return CHNL_LEVEL0; + } + ASSERT(ucCenterChannel >= 1 && ucCenterChannel <= 14); + + /* Calculated low/upper channels in affected freq range */ + ucAffectedChnl_L = + (ucCenterChannel <= AFFECTED_CHNL_OFFSET) + ? 1 + : (ucCenterChannel - AFFECTED_CHNL_OFFSET); + + ucAffectedChnl_H = (ucCenterChannel >= (14 - AFFECTED_CHNL_OFFSET)) + ? 14 + : (ucCenterChannel + AFFECTED_CHNL_OFFSET); + + /* Check intolerant (Non-HT) channel list */ + ASSERT(prBssInfo->auc2G_NonHtChnlList[0] <= CHNL_LIST_SZ_2G); + for (i = 1; i <= prBssInfo->auc2G_NonHtChnlList[0] + && i <= CHNL_LIST_SZ_2G; i++) { + if ((prBssInfo->auc2G_NonHtChnlList[i] >= ucAffectedChnl_L + && + prBssInfo->auc2G_NonHtChnlList[i] <= ucAffectedChnl_H) + && + prBssInfo->auc2G_NonHtChnlList[i] != ucPriChannel) { + + ucChannelLevel = CHNL_LEVEL0; + goto L_2G4_level_end; + } + } + + /* Check 20M BW request channel list */ + ASSERT(prBssInfo->auc2G_20mReqChnlList[0] <= CHNL_LIST_SZ_2G); + for (i = 1; i <= prBssInfo->auc2G_20mReqChnlList[0] + && i <= CHNL_LIST_SZ_2G; i++) { + if ((prBssInfo->auc2G_20mReqChnlList[i] >= ucAffectedChnl_L + && + prBssInfo->auc2G_20mReqChnlList[i] + <= ucAffectedChnl_H)) { + + ucChannelLevel = CHNL_LEVEL0; + goto L_2G4_level_end; + } + } + + /* Check 2.4G primary channel list */ + ASSERT(prBssInfo->auc2G_PriChnlList[0] <= CHNL_LIST_SZ_2G); + for (i = 1; i <= prBssInfo->auc2G_PriChnlList[0] + && i <= CHNL_LIST_SZ_2G; i++) { + if ((prBssInfo->auc2G_PriChnlList[i] >= ucAffectedChnl_L + && prBssInfo->auc2G_PriChnlList[i] <= ucAffectedChnl_H) + && prBssInfo->auc2G_PriChnlList[i] != ucPriChannel) { + + ucChannelLevel = CHNL_LEVEL0; + goto L_2G4_level_end; + } + } + + /* Check 2.4G secondary channel list */ + ASSERT(prBssInfo->auc2G_SecChnlList[0] <= CHNL_LIST_SZ_2G); + for (i = 1; i <= prBssInfo->auc2G_SecChnlList[0] + && i <= CHNL_LIST_SZ_2G; i++) { + if ((prBssInfo->auc2G_SecChnlList[i] >= ucAffectedChnl_L + && prBssInfo->auc2G_SecChnlList[i] <= ucAffectedChnl_H) + && prBssInfo->auc2G_SecChnlList[i] != ucSecChannel) { + + ucChannelLevel = CHNL_LEVEL0; + goto L_2G4_level_end; + } + } + +L_2G4_level_end: + + return ucChannelLevel; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +static uint8_t rlmObssChnlLevelIn5G(struct BSS_INFO *prBssInfo, + uint8_t ucPriChannel, + enum ENUM_CHNL_EXT eExtend) +{ + uint8_t i, ucChannelLevel; + uint8_t ucSecChannel; + + ASSERT(prBssInfo); + + ucChannelLevel = CHNL_LEVEL2; + + /* Calculate center channel for 2.4G band */ + if (eExtend == CHNL_EXT_SCA) + ucSecChannel = ucPriChannel + 4; + else if (eExtend == CHNL_EXT_SCB) + ucSecChannel = ucPriChannel - 4; + else + return CHNL_LEVEL0; + ASSERT(ucSecChannel >= 36); + + /* Check 5G primary channel list */ + ASSERT(prBssInfo->auc5G_PriChnlList[0] <= CHNL_LIST_SZ_5G); + for (i = 1; i <= prBssInfo->auc5G_PriChnlList[0] + && i <= CHNL_LIST_SZ_5G; i++) { + if (prBssInfo->auc5G_PriChnlList[i] == ucSecChannel) { + + ucChannelLevel = CHNL_LEVEL0; + goto L_5G_level_end; + } else if (prBssInfo->auc5G_PriChnlList[i] == ucPriChannel) { + ucChannelLevel = CHNL_LEVEL1; + } + } + + /* Check non-HT channel list */ + ASSERT(prBssInfo->auc5G_NonHtChnlList[0] <= CHNL_LIST_SZ_5G); + for (i = 1; i <= prBssInfo->auc5G_NonHtChnlList[0] + && i <= CHNL_LIST_SZ_5G; i++) { + if (prBssInfo->auc5G_NonHtChnlList[i] == ucSecChannel) { + + ucChannelLevel = CHNL_LEVEL0; + goto L_5G_level_end; + } else if (prBssInfo->auc5G_NonHtChnlList[i] == ucPriChannel) { + ucChannelLevel = CHNL_LEVEL1; + } + } + + /* Check secondary channel list */ + ASSERT(prBssInfo->auc5G_SecChnlList[0] <= CHNL_LIST_SZ_5G); + for (i = 1; i <= prBssInfo->auc5G_SecChnlList[0] + && i <= CHNL_LIST_SZ_5G; i++) { + if (prBssInfo->auc5G_SecChnlList[i] == ucPriChannel) { + + ucChannelLevel = CHNL_LEVEL0; + goto L_5G_level_end; + } + } + +L_5G_level_end: + + return ucChannelLevel; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rlmObssScanExemptionRsp(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, + struct SW_RFB *prSwRfb) +{ + struct MSDU_INFO *prMsduInfo; + struct ACTION_20_40_COEXIST_FRAME *prTxFrame; + + /* To do: need an algorithm to do judgement. + * Now always reject request + */ + + prMsduInfo = (struct MSDU_INFO *) + cnmMgtPktAlloc(prAdapter, PUBLIC_ACTION_MAX_LEN); + if (prMsduInfo == NULL) + return; + + DBGLOG(RLM, INFO, "Send 20/40 coexistence rsp frame!\n"); + + prTxFrame = (struct ACTION_20_40_COEXIST_FRAME *) prMsduInfo->prPacket; + + prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; + COPY_MAC_ADDR(prTxFrame->aucDestAddr, + ((struct ACTION_20_40_COEXIST_FRAME *) + prSwRfb->pvHeader)->aucSrcAddr); + COPY_MAC_ADDR(prTxFrame->aucSrcAddr, + prBssInfo->aucOwnMacAddr); + COPY_MAC_ADDR(prTxFrame->aucBSSID, + prBssInfo->aucBSSID); + + prTxFrame->ucCategory = CATEGORY_PUBLIC_ACTION; + prTxFrame->ucAction = ACTION_PUBLIC_20_40_COEXIST; + + /* To do: find correct algorithm */ + prTxFrame->rBssCoexist.ucId = ELEM_ID_20_40_BSS_COEXISTENCE; + prTxFrame->rBssCoexist.ucLength = 1; + prTxFrame->rBssCoexist.ucData = 0; + + ASSERT((WLAN_MAC_HEADER_LEN + 5) <= PUBLIC_ACTION_MAX_LEN); + + TX_SET_MMPDU(prAdapter, + prMsduInfo, + prBssInfo->ucBssIndex, + prSwRfb->ucStaRecIdx, + WLAN_MAC_MGMT_HEADER_LEN, WLAN_MAC_MGMT_HEADER_HTC_LEN + 5, + NULL, MSDU_RATE_MODE_AUTO); + + /* Send them to HW queue */ + nicTxEnqueueMsdu(prAdapter, prMsduInfo); +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/p2p_role_fsm.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/p2p_role_fsm.c new file mode 100644 index 0000000000000000000000000000000000000000..1ac94ada4d16229660e19c36e6a2d7cfc25a06b3 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/p2p_role_fsm.c @@ -0,0 +1,4204 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +#include "precomp.h" +#include "p2p_role_state.h" +#include "gl_p2p_os.h" + +#if 1 +/*lint -save -e64 Type mismatch */ +static uint8_t *apucDebugP2pRoleState[P2P_ROLE_STATE_NUM] = { + (uint8_t *) DISP_STRING("P2P_ROLE_STATE_IDLE"), + (uint8_t *) DISP_STRING("P2P_ROLE_STATE_SCAN"), + (uint8_t *) DISP_STRING("P2P_ROLE_STATE_REQING_CHANNEL"), + (uint8_t *) DISP_STRING("P2P_ROLE_STATE_AP_CHNL_DETECTION"), + (uint8_t *) DISP_STRING("P2P_ROLE_STATE_GC_JOIN"), + (uint8_t *) DISP_STRING("P2P_ROLE_STATE_OFF_CHNL_TX"), +#if (CFG_SUPPORT_DFS_MASTER == 1) + (uint8_t *) DISP_STRING("P2P_ROLE_STATE_DFS_CAC"), + (uint8_t *) DISP_STRING("P2P_ROLE_STATE_SWITCH_CHANNEL"), +#endif +}; + +uint8_t * + p2pRoleFsmGetFsmState( + IN enum ENUM_P2P_ROLE_STATE eCurrentState) { + if (eCurrentState >= 0 && eCurrentState < P2P_ROLE_STATE_NUM) + return apucDebugP2pRoleState[eCurrentState]; + + return (uint8_t *) DISP_STRING("UNKNOWN"); +} + +/*lint -restore */ +#endif /* DBG */ + +void +p2pRoleFsmStateTransition(IN struct ADAPTER *prAdapter, + IN struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo, + IN enum ENUM_P2P_ROLE_STATE eNextState); +static u_int8_t +p2pRoleFsmIsAcsProcessing(IN struct ADAPTER *prAdapter, + uint8_t ucRoleIdx); +static void +p2pRoleFsmAbortCurrentAcsReq(IN struct ADAPTER *prAdapter, + IN struct MSG_P2P_ACS_REQUEST *prMsgAcsRequest); + +uint8_t p2pRoleFsmInit(IN struct ADAPTER *prAdapter, + IN uint8_t ucRoleIdx) +{ + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *) NULL; + struct BSS_INFO *prP2pBssInfo = (struct BSS_INFO *) NULL; + struct P2P_CHNL_REQ_INFO *prP2pChnlReqInfo = + (struct P2P_CHNL_REQ_INFO *) NULL; + struct P2P_MGMT_TX_REQ_INFO *prP2pMgmtTxReqInfo = + (struct P2P_MGMT_TX_REQ_INFO *) NULL; + struct GL_P2P_INFO *prP2PInfo = NULL; + + do { + ASSERT_BREAK(prAdapter != NULL); + + ASSERT_BREAK( + P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, ucRoleIdx) + == NULL); + + prP2pRoleFsmInfo = kalMemAlloc( + sizeof(struct P2P_ROLE_FSM_INFO), + VIR_MEM_TYPE); + + P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, ucRoleIdx) = + prP2pRoleFsmInfo; + + if (!prP2pRoleFsmInfo) { + DBGLOG(P2P, ERROR, + "Error allocating fsm Info Structure\n"); + break; + } + + kalMemZero(prP2pRoleFsmInfo, sizeof(struct P2P_ROLE_FSM_INFO)); + + prP2pRoleFsmInfo->ucRoleIndex = ucRoleIdx; + + prP2pRoleFsmInfo->eCurrentState = P2P_ROLE_STATE_IDLE; + + prP2pRoleFsmInfo->u4P2pPacketFilter = + PARAM_PACKET_FILTER_SUPPORTED; + + prP2pChnlReqInfo = &prP2pRoleFsmInfo->rChnlReqInfo; + LINK_INITIALIZE(&(prP2pChnlReqInfo->rP2pChnlReqLink)); + + prP2pMgmtTxReqInfo = &prP2pRoleFsmInfo->rMgmtTxInfo; + LINK_INITIALIZE(&prP2pMgmtTxReqInfo->rTxReqLink); + + cnmTimerInitTimer(prAdapter, + &(prP2pRoleFsmInfo->rP2pRoleFsmTimeoutTimer), + (PFN_MGMT_TIMEOUT_FUNC) p2pRoleFsmRunEventTimeout, + (unsigned long) prP2pRoleFsmInfo); + +#if CFG_ENABLE_PER_STA_STATISTICS_LOG + cnmTimerInitTimer(prAdapter, + &(prP2pRoleFsmInfo->rP2pRoleFsmGetStatisticsTimer), + (PFN_MGMT_TIMEOUT_FUNC) p2pRoleFsmGetStaStatistics, + (unsigned long) prP2pRoleFsmInfo); +#endif + +#if (CFG_SUPPORT_DFS_MASTER == 1) + cnmTimerInitTimer(prAdapter, + &(prP2pRoleFsmInfo->rDfsShutDownTimer), + (PFN_MGMT_TIMEOUT_FUNC) + p2pRoleFsmRunEventDfsShutDownTimeout, + (unsigned long) prP2pRoleFsmInfo); +#endif + + prP2pBssInfo = cnmGetBssInfoAndInit(prAdapter, + NETWORK_TYPE_P2P, + FALSE); + + if (!prP2pBssInfo) { + DBGLOG(P2P, ERROR, + "Error allocating BSS Info Structure\n"); + break; + } + + BSS_INFO_INIT(prAdapter, prP2pBssInfo); + prP2pRoleFsmInfo->ucBssIndex = prP2pBssInfo->ucBssIndex; + + /* For state identify, not really used. */ + prP2pBssInfo->eIntendOPMode = OP_MODE_P2P_DEVICE; + + /* glRegisterP2P has setup the mac address */ + /* For wlan0 as AP mode case, this function will be called when + * changing interface type. And the MAC Addr overwrite by Role + * isn't expected. + * Maybe only using ucRoleIdx to calc MAC addr is better than + * using Role type. + */ + prP2PInfo = prAdapter->prGlueInfo->prP2PInfo[ucRoleIdx]; + COPY_MAC_ADDR(prP2pBssInfo->aucOwnMacAddr, + prP2PInfo->prDevHandler->dev_addr); + + /* For BSS_INFO back trace to P2P Role & get Role FSM. */ + prP2pBssInfo->u4PrivateData = ucRoleIdx; + + if (p2pFuncIsAPMode( + prAdapter->rWifiVar.prP2PConnSettings[ucRoleIdx])) { + prP2pBssInfo->ucConfigAdHocAPMode = AP_MODE_11G; + prP2pBssInfo->u2HwDefaultFixedRateCode = + RATE_CCK_1M_LONG; + } else { + prP2pBssInfo->ucConfigAdHocAPMode = AP_MODE_11G_P2P; + prP2pBssInfo->u2HwDefaultFixedRateCode = RATE_OFDM_6M; + } + + prP2pBssInfo->ucNonHTBasicPhyType = (uint8_t) + rNonHTApModeAttributes + [prP2pBssInfo->ucConfigAdHocAPMode] + .ePhyTypeIndex; + + prP2pBssInfo->u2BSSBasicRateSet = + rNonHTApModeAttributes + [prP2pBssInfo->ucConfigAdHocAPMode] + .u2BSSBasicRateSet; + prP2pBssInfo->u2OperationalRateSet = + rNonHTPhyAttributes + [prP2pBssInfo->ucNonHTBasicPhyType] + .u2SupportedRateSet; + + rateGetDataRatesFromRateSet(prP2pBssInfo->u2OperationalRateSet, + prP2pBssInfo->u2BSSBasicRateSet, + prP2pBssInfo->aucAllSupportedRates, + &prP2pBssInfo->ucAllSupportedRatesLen); + + prP2pBssInfo->prBeacon = cnmMgtPktAlloc(prAdapter, + OFFSET_OF(struct WLAN_BEACON_FRAME, aucInfoElem[0]) + + MAX_IE_LENGTH); + + if (prP2pBssInfo->prBeacon) { + prP2pBssInfo->prBeacon->eSrc = TX_PACKET_MGMT; + /* NULL STA_REC */ + prP2pBssInfo->prBeacon->ucStaRecIndex = + STA_REC_INDEX_BMCAST; + prP2pBssInfo->prBeacon->ucBssIndex = + prP2pBssInfo->ucBssIndex; + } else { + /* Out of memory. */ + ASSERT(FALSE); + } + + prP2pBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC = PM_UAPSD_ALL; + prP2pBssInfo->rPmProfSetupInfo.ucBmpTriggerAC = PM_UAPSD_ALL; + prP2pBssInfo->rPmProfSetupInfo.ucUapsdSp = WMM_MAX_SP_LENGTH_2; + prP2pBssInfo->ucPrimaryChannel = P2P_DEFAULT_LISTEN_CHANNEL; + prP2pBssInfo->eBand = BAND_2G4; + prP2pBssInfo->eBssSCO = CHNL_EXT_SCN; + prP2pBssInfo->ucOpRxNss = prP2pBssInfo->ucOpTxNss = + wlanGetSupportNss(prAdapter, prP2pBssInfo->ucBssIndex); +#if (CFG_HW_WMM_BY_BSS == 0) + prP2pBssInfo->ucWmmQueSet = (prAdapter->rWifiVar.eDbdcMode == + ENUM_DBDC_MODE_DISABLED) + ? DBDC_5G_WMM_INDEX + : DBDC_2G_WMM_INDEX; +#endif + if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucQoS)) + prP2pBssInfo->fgIsQBSS = TRUE; + else + prP2pBssInfo->fgIsQBSS = FALSE; + +#if (CFG_SUPPORT_DFS_MASTER == 1) + p2pFuncRadarInfoInit(); +#endif + } while (FALSE); + + if (prP2pBssInfo) + return prP2pBssInfo->ucBssIndex; + else + return prAdapter->ucP2PDevBssIdx; +} /* p2pFsmInit */ + +void p2pRoleFsmUninit(IN struct ADAPTER *prAdapter, IN uint8_t ucRoleIdx) +{ + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *) NULL; + struct BSS_INFO *prP2pBssInfo = (struct BSS_INFO *) NULL; + + do { + ASSERT_BREAK(prAdapter != NULL); + + DEBUGFUNC("p2pRoleFsmUninit()"); + DBGLOG(P2P, INFO, "->p2pRoleFsmUninit()\n"); + + prP2pRoleFsmInfo = + P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, ucRoleIdx); + + ASSERT_BREAK(prP2pRoleFsmInfo != NULL); + + if (!prP2pRoleFsmInfo) + return; + + prP2pBssInfo = + prAdapter->aprBssInfo[prP2pRoleFsmInfo->ucBssIndex]; + + p2pFuncDissolve(prAdapter, + prP2pBssInfo, TRUE, + REASON_CODE_DEAUTH_LEAVING_BSS); + + SET_NET_PWR_STATE_IDLE(prAdapter, prP2pBssInfo->ucBssIndex); + + /* Function Dissolve should already enter IDLE state. */ + p2pRoleFsmStateTransition(prAdapter, + prP2pRoleFsmInfo, + P2P_ROLE_STATE_IDLE); + + p2pRoleFsmRunEventAbort(prAdapter, prP2pRoleFsmInfo); + + p2pFunClearAllTxReq(prAdapter, + &(prP2pRoleFsmInfo->rMgmtTxInfo)); + + /* Clear CmdQue */ + kalClearMgmtFramesByBssIdx(prAdapter->prGlueInfo, + prP2pBssInfo->ucBssIndex); + kalClearSecurityFramesByBssIdx(prAdapter->prGlueInfo, + prP2pBssInfo->ucBssIndex); + /* Clear PendingCmdQue */ + wlanReleasePendingCMDbyBssIdx(prAdapter, + prP2pBssInfo->ucBssIndex); + /* Clear PendingTxMsdu */ + nicFreePendingTxMsduInfo(prAdapter, + prP2pBssInfo->ucBssIndex, MSDU_REMOVE_BY_BSS_INDEX); + + /* Deactivate BSS. */ + UNSET_NET_ACTIVE(prAdapter, prP2pRoleFsmInfo->ucBssIndex); + + nicDeactivateNetwork(prAdapter, prP2pRoleFsmInfo->ucBssIndex); + + P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, ucRoleIdx) = NULL; + + if (prP2pBssInfo->prBeacon) { + cnmMgtPktFree(prAdapter, prP2pBssInfo->prBeacon); + prP2pBssInfo->prBeacon = NULL; + } + + cnmFreeBssInfo(prAdapter, prP2pBssInfo); + + /* ensure the timer be stopped */ + cnmTimerStopTimer(prAdapter, + &(prP2pRoleFsmInfo->rP2pRoleFsmTimeoutTimer)); + +#if CFG_ENABLE_PER_STA_STATISTICS_LOG + cnmTimerStopTimer(prAdapter, + &prP2pRoleFsmInfo->rP2pRoleFsmGetStatisticsTimer); +#endif + +#if (CFG_SUPPORT_DFS_MASTER == 1) + cnmTimerStopTimer(prAdapter, + &(prP2pRoleFsmInfo->rDfsShutDownTimer)); +#endif + + if (prP2pRoleFsmInfo) + kalMemFree(prP2pRoleFsmInfo, VIR_MEM_TYPE, + sizeof(struct P2P_ROLE_FSM_INFO)); + + } while (FALSE); + + return; +#if 0 + struct P2P_FSM_INFO *prP2pFsmInfo = (struct P2P_FSM_INFO *) NULL; + struct BSS_INFO *prP2pBssInfo = (struct BSS_INFO *) NULL; + + do { + ASSERT_BREAK(prAdapter != NULL); + + DEBUGFUNC("p2pFsmUninit()"); + DBGLOG(P2P, INFO, "->p2pFsmUninit()\n"); + + prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; + prP2pBssInfo = + &(prAdapter->rWifiVar + .arBssInfo[NETWORK_TYPE_P2P_INDEX]); + + p2pFuncSwitchOPMode(prAdapter, + prP2pBssInfo, + OP_MODE_P2P_DEVICE, + TRUE); + + p2pFsmRunEventAbort(prAdapter, prP2pFsmInfo); + + p2pStateAbort_IDLE(prAdapter, prP2pFsmInfo, P2P_STATE_NUM); + + UNSET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); + + wlanAcquirePowerControl(prAdapter); + + /* Release all pending CMD queue. */ + DBGLOG(P2P, TRACE, + "p2pFsmUninit: wlanProcessCommandQueue, num of element:%d\n", + prAdapter->prGlueInfo->rCmdQueue.u4NumElem); + wlanProcessCommandQueue(prAdapter, + &prAdapter->prGlueInfo->rCmdQueue); + + wlanReleasePowerControl(prAdapter); + + /* Release pending mgmt frame, + * mgmt frame may be pending by CMD without resource. + */ + kalClearMgmtFramesByBssIdx(prAdapter->prGlueInfo, + NETWORK_TYPE_P2P_INDEX); + + /* Clear PendingCmdQue */ + wlanReleasePendingCMDbyBssIdx(prAdapter, + NETWORK_TYPE_P2P_INDEX); + + if (prP2pBssInfo->prBeacon) { + cnmMgtPktFree(prAdapter, prP2pBssInfo->prBeacon); + prP2pBssInfo->prBeacon = NULL; + } + + } while (FALSE); + + return; +#endif +} /* p2pRoleFsmUninit */ + +void +p2pRoleFsmStateTransition(IN struct ADAPTER *prAdapter, + IN struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo, + IN enum ENUM_P2P_ROLE_STATE eNextState) +{ + u_int8_t fgIsTransitionOut = (u_int8_t) FALSE; + struct BSS_INFO *prP2pRoleBssInfo = (struct BSS_INFO *) NULL; + struct P2P_CHNL_REQ_INFO *prChnlReqInfo = + (struct P2P_CHNL_REQ_INFO *) NULL; + + prP2pRoleBssInfo = + GET_BSS_INFO_BY_INDEX(prAdapter, prP2pRoleFsmInfo->ucBssIndex); + prChnlReqInfo = &(prP2pRoleFsmInfo->rChnlReqInfo); + + do { + if (!IS_BSS_ACTIVE(prP2pRoleBssInfo)) { + if (!cnmP2PIsPermitted(prAdapter)) + return; + +#if CFG_SUPPORT_DBDC + if (cnmDBDCIsReqPeivilegeLock() && + ((eNextState == P2P_ROLE_STATE_REQING_CHANNEL && + (prChnlReqInfo->eChnlReqType == + CH_REQ_TYPE_GO_START_BSS || + prChnlReqInfo->eChnlReqType == + CH_REQ_TYPE_JOIN)) + || (eNextState == P2P_ROLE_STATE_IDLE && + prP2pRoleFsmInfo->eCurrentState == + P2P_ROLE_STATE_IDLE) +#if (CFG_SUPPORT_DFS_MASTER == 1) + || eNextState == P2P_ROLE_STATE_SWITCH_CHANNEL +#endif + )) { + /* Do not activate network ruring DBDC HW + * switch. Otherwise, BSS may use incorrect + * CR and result in TRx problems. + */ + DBGLOG(P2P, STATE, + "[P2P_ROLE][%d](Bss%d): Skip activate network [%s]\n", + prP2pRoleFsmInfo->ucRoleIndex, + prP2pRoleFsmInfo->ucBssIndex, + p2pRoleFsmGetFsmState(eNextState)); + } else +#endif + { + SET_NET_ACTIVE(prAdapter, + prP2pRoleBssInfo->ucBssIndex); + nicActivateNetwork(prAdapter, + prP2pRoleBssInfo->ucBssIndex); + } + } + + fgIsTransitionOut = fgIsTransitionOut ? FALSE : TRUE; + + if (!fgIsTransitionOut) { + /* Print log with state changed */ + if (prP2pRoleFsmInfo->eCurrentState != eNextState) + DBGLOG(P2P, STATE, + "[P2P_ROLE][%d]TRANSITION(Bss%d): [%s] -> [%s]\n", + prP2pRoleFsmInfo->ucRoleIndex, + prP2pRoleFsmInfo->ucBssIndex, + p2pRoleFsmGetFsmState + (prP2pRoleFsmInfo->eCurrentState), + p2pRoleFsmGetFsmState(eNextState)); + + /* Transition into current state. */ + prP2pRoleFsmInfo->eCurrentState = eNextState; + } + + switch (prP2pRoleFsmInfo->eCurrentState) { + case P2P_ROLE_STATE_IDLE: + if (!fgIsTransitionOut) + p2pRoleStateInit_IDLE(prAdapter, + prP2pRoleFsmInfo, + prP2pRoleBssInfo); + else + p2pRoleStateAbort_IDLE(prAdapter, + prP2pRoleFsmInfo, + &(prP2pRoleFsmInfo->rChnlReqInfo)); + break; + case P2P_ROLE_STATE_SCAN: + if (!fgIsTransitionOut) { + p2pRoleStateInit_SCAN(prAdapter, + prP2pRoleFsmInfo->ucBssIndex, + &(prP2pRoleFsmInfo->rScanReqInfo)); + } else { + p2pRoleStateAbort_SCAN(prAdapter, + prP2pRoleFsmInfo); + } + break; + case P2P_ROLE_STATE_REQING_CHANNEL: + if (!fgIsTransitionOut) { + p2pRoleStateInit_REQING_CHANNEL(prAdapter, + prP2pRoleFsmInfo->ucBssIndex, + &(prP2pRoleFsmInfo->rChnlReqInfo)); + } else { + p2pRoleStateAbort_REQING_CHANNEL(prAdapter, + prP2pRoleBssInfo, + prP2pRoleFsmInfo, eNextState); + } + break; + case P2P_ROLE_STATE_AP_CHNL_DETECTION: + if (!fgIsTransitionOut) { + p2pRoleStateInit_AP_CHNL_DETECTION(prAdapter, + prP2pRoleFsmInfo->ucBssIndex, + &(prP2pRoleFsmInfo->rScanReqInfo), + &(prP2pRoleFsmInfo->rConnReqInfo)); + } else { + p2pRoleStateAbort_AP_CHNL_DETECTION(prAdapter, + prP2pRoleFsmInfo->ucBssIndex, + &(prP2pRoleFsmInfo->rConnReqInfo), + &(prP2pRoleFsmInfo->rChnlReqInfo), + &(prP2pRoleFsmInfo->rScanReqInfo), + eNextState); + } + break; + case P2P_ROLE_STATE_GC_JOIN: + if (!fgIsTransitionOut) { + p2pRoleStateInit_GC_JOIN(prAdapter, + prP2pRoleFsmInfo, + &(prP2pRoleFsmInfo->rChnlReqInfo)); + } else { + p2pRoleStateAbort_GC_JOIN(prAdapter, + prP2pRoleFsmInfo, + &(prP2pRoleFsmInfo->rJoinInfo), + eNextState); + } + break; + case P2P_ROLE_STATE_OFF_CHNL_TX: + if (!fgIsTransitionOut) { + fgIsTransitionOut = + p2pRoleStateInit_OFF_CHNL_TX(prAdapter, + prP2pRoleFsmInfo, + &(prP2pRoleFsmInfo->rChnlReqInfo), + &(prP2pRoleFsmInfo->rMgmtTxInfo), + &eNextState); + } else { + p2pRoleStateAbort_OFF_CHNL_TX(prAdapter, + prP2pRoleFsmInfo, + &(prP2pRoleFsmInfo->rMgmtTxInfo), + &(prP2pRoleFsmInfo->rChnlReqInfo), + eNextState); + } + break; + +#if (CFG_SUPPORT_DFS_MASTER == 1) + case P2P_ROLE_STATE_DFS_CAC: + if (!fgIsTransitionOut) { + p2pRoleStateInit_DFS_CAC(prAdapter, + prP2pRoleFsmInfo->ucBssIndex, + &(prP2pRoleFsmInfo->rChnlReqInfo)); + } else { + p2pRoleStateAbort_DFS_CAC(prAdapter, + prP2pRoleBssInfo, + prP2pRoleFsmInfo, + eNextState); + } + break; + case P2P_ROLE_STATE_SWITCH_CHANNEL: + if (!fgIsTransitionOut) { + p2pRoleStateInit_SWITCH_CHANNEL(prAdapter, + prP2pRoleFsmInfo->ucBssIndex, + &(prP2pRoleFsmInfo->rChnlReqInfo)); + } else { + p2pRoleStateAbort_SWITCH_CHANNEL(prAdapter, + prP2pRoleBssInfo, + prP2pRoleFsmInfo, + eNextState); + } + break; +#endif + default: + ASSERT(FALSE); + break; + } + } while (fgIsTransitionOut); + +} /* p2pRoleFsmStateTransition */ + +void p2pRoleFsmRunEventTimeout(IN struct ADAPTER *prAdapter, + IN unsigned long ulParamPtr) +{ + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *) ulParamPtr; + struct P2P_CHNL_REQ_INFO *prP2pChnlReqInfo = + (struct P2P_CHNL_REQ_INFO *) NULL; + + do { + ASSERT_BREAK((prAdapter != NULL) && (prP2pRoleFsmInfo != NULL)); + + switch (prP2pRoleFsmInfo->eCurrentState) { + case P2P_ROLE_STATE_IDLE: + prP2pChnlReqInfo = &(prP2pRoleFsmInfo->rChnlReqInfo); + if (prP2pChnlReqInfo->fgIsChannelRequested) { + p2pFuncReleaseCh(prAdapter, + prP2pRoleFsmInfo->ucBssIndex, + prP2pChnlReqInfo); + if (IS_NET_PWR_STATE_IDLE(prAdapter, + prP2pRoleFsmInfo->ucBssIndex)) + DBGLOG(P2P, ERROR, + "Power state was reset while request channel\n"); + } + + if (IS_NET_PWR_STATE_IDLE(prAdapter, + prP2pRoleFsmInfo->ucBssIndex) && + IS_NET_ACTIVE(prAdapter, + prP2pRoleFsmInfo->ucBssIndex)) { + DBGLOG(P2P, TRACE, + "Role BSS IDLE, deactive network.\n"); + UNSET_NET_ACTIVE(prAdapter, + prP2pRoleFsmInfo->ucBssIndex); + nicDeactivateNetwork(prAdapter, + prP2pRoleFsmInfo->ucBssIndex); + nicUpdateBss(prAdapter, + prP2pRoleFsmInfo->ucBssIndex); + } + break; + case P2P_ROLE_STATE_GC_JOIN: + p2pRoleFsmStateTransition(prAdapter, + prP2pRoleFsmInfo, + P2P_ROLE_STATE_IDLE); + break; + case P2P_ROLE_STATE_OFF_CHNL_TX: + p2pRoleFsmStateTransition(prAdapter, prP2pRoleFsmInfo, + P2P_ROLE_STATE_OFF_CHNL_TX); + break; +#if (CFG_SUPPORT_DFS_MASTER == 1) + case P2P_ROLE_STATE_DFS_CAC: + p2pRoleFsmStateTransition(prAdapter, + prP2pRoleFsmInfo, + P2P_ROLE_STATE_IDLE); + kalP2PCacFinishedUpdate(prAdapter->prGlueInfo, + prP2pRoleFsmInfo->ucRoleIndex); + p2pFuncSetDfsState(DFS_STATE_ACTIVE); + cnmTimerStartTimer(prAdapter, + &(prP2pRoleFsmInfo->rDfsShutDownTimer), + 5000); + break; +#endif + default: + DBGLOG(P2P, ERROR, + "Current P2P Role State %d is unexpected for FSM timeout event.\n", + prP2pRoleFsmInfo->eCurrentState); + ASSERT(FALSE); + break; + } + } while (FALSE); +} /* p2pRoleFsmRunEventTimeout */ + +static void +p2pRoleFsmDeauthComplete(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec) +{ + struct BSS_INFO *prP2pBssInfo = (struct BSS_INFO *) NULL; + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *) NULL; + enum ENUM_PARAM_MEDIA_STATE eOriMediaStatus; + struct GL_P2P_INFO *prP2PInfo; + + DBGLOG(P2P, INFO, "Deauth TX Complete!\n"); + + if (!prAdapter) { + DBGLOG(P2P, ERROR, "prAdapter shouldn't be NULL!\n"); + return; + } + + if (!prStaRec) { + DBGLOG(P2P, ERROR, "prStaRec shouldn't be NULL!\n"); + return; + } + + prP2pBssInfo = prAdapter->aprBssInfo[prStaRec->ucBssIndex]; + if (!prP2pBssInfo) { + DBGLOG(P2P, ERROR, "prP2pBssInfo shouldn't be NULL!\n"); + return; + } + + eOriMediaStatus = prP2pBssInfo->eConnectionState; + prP2pRoleFsmInfo = + P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, + prP2pBssInfo->u4PrivateData); + + if (!prP2pRoleFsmInfo) { + DBGLOG(P2P, ERROR, "prP2pRoleFsmInfo shouldn't be NULL!\n"); + return; + } + + prP2PInfo = prAdapter->prGlueInfo->prP2PInfo[ + prP2pRoleFsmInfo->ucRoleIndex]; + + if (!prP2PInfo) { + DBGLOG(P2P, ERROR, "prP2PInfo shouldn't be NULL!\n"); + return; + } + + /* + * After EAP exchange, GO/GC will disconnect + * and re-connect in short time. + * GC's new station record will be removed unexpectedly at GO's side + * if new GC's connection happens + * when previous GO's disconnection flow is + * processing. 4-way handshake will NOT be triggered. + */ + if ((prStaRec->eAuthAssocState == AAA_STATE_SEND_AUTH2 || + prStaRec->eAuthAssocState == AAA_STATE_SEND_ASSOC2) && + (prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) && + (p2pFuncIsAPMode(prAdapter->rWifiVar + .prP2PConnSettings[prP2pBssInfo->u4PrivateData]) == FALSE)) { + DBGLOG(P2P, WARN, + "Skip deauth tx done since AAA fsm is in progress.\n"); + return; + } else if (prStaRec->eAuthAssocState == SAA_STATE_SEND_AUTH1 || + prStaRec->eAuthAssocState == SAA_STATE_SEND_ASSOC1) { + DBGLOG(P2P, WARN, + "Skip deauth tx done since SAA fsm is in progress.\n"); + return; + } + + /* Change station state. */ + cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); + + /* Reset Station Record Status. */ + p2pFuncResetStaRecStatus(prAdapter, prStaRec); + + /* Try to remove StaRec in BSS client list before free it */ + bssRemoveClient(prAdapter, prP2pBssInfo, prStaRec); + + /* STA_RECORD free */ + cnmStaRecFree(prAdapter, prStaRec); + + if ((prP2pBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) || + (bssGetClientCount(prAdapter, prP2pBssInfo) == 0)) { + if (prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) + DBGLOG(P2P, TRACE, + "No More Client, Media Status DISCONNECTED\n"); + else + DBGLOG(P2P, TRACE, + "Deauth done, Media Status DISCONNECTED\n"); + p2pChangeMediaState(prAdapter, + prP2pBssInfo, + MEDIA_STATE_DISCONNECTED); + if (prP2pBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) { +#if CFG_WPS_DISCONNECT || (KERNEL_VERSION(4, 4, 0) <= CFG80211_VERSION_CODE) + kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, + prP2pRoleFsmInfo->ucRoleIndex, + NULL, NULL, 0, 0, + WLAN_STATUS_MEDIA_DISCONNECT); +#else + kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, + prP2pRoleFsmInfo->ucRoleIndex, + NULL, NULL, 0, 0); +#endif + } + if (prP2PInfo && prP2PInfo->eChnlSwitchPolicy == + CHNL_SWITCH_POLICY_DEAUTH) { + prP2PInfo->eChnlSwitchPolicy = CHNL_SWITCH_POLICY_NONE; + p2pFunChnlSwitchNotifyDone(prAdapter); + } + } + + /* STOP BSS if power is IDLE */ + if (prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) { + if (IS_NET_PWR_STATE_IDLE(prAdapter, + prP2pRoleFsmInfo->ucBssIndex) + && (bssGetClientCount(prAdapter, prP2pBssInfo) == 0)) { + /* All Peer disconnected !! Stop BSS now!! */ + p2pFuncStopComplete(prAdapter, prP2pBssInfo); + + p2pRoleFsmStateTransition(prAdapter, + prP2pRoleFsmInfo, + P2P_ROLE_STATE_IDLE); + } else if (eOriMediaStatus != prP2pBssInfo->eConnectionState) + /* Update the Media State if necessary */ + nicUpdateBss(prAdapter, prP2pBssInfo->ucBssIndex); + } else /* GC : Stop BSS when Deauth done */ + p2pFuncStopComplete(prAdapter, prP2pBssInfo); + +} + +void p2pRoleFsmDeauthTimeout(IN struct ADAPTER *prAdapter, + IN unsigned long ulParamPtr) +{ + struct STA_RECORD *prStaRec = (struct STA_RECORD *) ulParamPtr; + + p2pRoleFsmDeauthComplete(prAdapter, prStaRec); +} /* p2pRoleFsmRunEventTimeout */ + +void p2pRoleFsmRunEventAbort(IN struct ADAPTER *prAdapter, + IN struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo) +{ + + do { + ASSERT_BREAK((prAdapter != NULL) && (prP2pRoleFsmInfo != NULL)); + + if (prP2pRoleFsmInfo->eCurrentState != P2P_ROLE_STATE_IDLE) { + /* Get into IDLE state. */ + p2pRoleFsmStateTransition(prAdapter, + prP2pRoleFsmInfo, + P2P_ROLE_STATE_IDLE); + } + + /* Abort IDLE. */ + p2pRoleStateAbort_IDLE(prAdapter, + prP2pRoleFsmInfo, + &(prP2pRoleFsmInfo->rChnlReqInfo)); + + } while (FALSE); +} /* p2pRoleFsmRunEventAbort */ + +uint32_t +p2pRoleFsmRunEventDeauthTxDone(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN enum ENUM_TX_RESULT_CODE rTxDoneStatus) +{ + struct STA_RECORD *prStaRec = (struct STA_RECORD *) NULL; + + do { + ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); + + DBGLOG(P2P, INFO, + "Deauth TX Done, seq = %d, sta = %d, status = %d\n", + prMsduInfo->ucTxSeqNum, + prMsduInfo->ucStaRecIndex, + rTxDoneStatus); + + prStaRec = cnmGetStaRecByIndex(prAdapter, + prMsduInfo->ucStaRecIndex); + + if (prStaRec == NULL) { + DBGLOG(P2P, TRACE, + "Station Record NULL, Index:%d\n", + prMsduInfo->ucStaRecIndex); + break; + } + + p2pRoleFsmDeauthComplete(prAdapter, prStaRec); + /* Avoid re-entry */ + cnmTimerStopTimer(prAdapter, &(prStaRec->rDeauthTxDoneTimer)); + + } while (FALSE); + + return WLAN_STATUS_SUCCESS; + +} /* p2pRoleFsmRunEventDeauthTxDone */ + +void p2pRoleFsmRunEventRxDeauthentication(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, + IN struct SW_RFB *prSwRfb) +{ + struct BSS_INFO *prP2pBssInfo = (struct BSS_INFO *) NULL; + uint16_t u2ReasonCode = 0; + /* flag to send deauth when rx sta disassc/deauth */ + u_int8_t fgSendDeauth = FALSE; + + do { + ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL)); + + if (prStaRec == NULL) + prStaRec = cnmGetStaRecByIndex(prAdapter, + prSwRfb->ucStaRecIdx); + + if (!prStaRec) + break; + + prP2pBssInfo = prAdapter->aprBssInfo[prStaRec->ucBssIndex]; + + if (prStaRec->ucStaState == STA_STATE_1) + break; + + DBGLOG(P2P, TRACE, "RX Deauth\n"); + + switch (prP2pBssInfo->eCurrentOPMode) { + case OP_MODE_INFRASTRUCTURE: + if (authProcessRxDeauthFrame(prSwRfb, + prStaRec->aucMacAddr, + &u2ReasonCode) == WLAN_STATUS_SUCCESS) { + struct WLAN_DEAUTH_FRAME *prDeauthFrame = + (struct WLAN_DEAUTH_FRAME *) + prSwRfb->pvHeader; + uint16_t u2IELength = 0; + + if (prP2pBssInfo->prStaRecOfAP != prStaRec) + break; + + prStaRec->u2ReasonCode = u2ReasonCode; + u2IELength = prSwRfb->u2PacketLen + - (WLAN_MAC_HEADER_LEN + + REASON_CODE_FIELD_LEN); + +#if CFG_WPS_DISCONNECT || (KERNEL_VERSION(4, 4, 0) <= CFG80211_VERSION_CODE) +/* Indicate disconnect to Host. */ + kalP2PGCIndicateConnectionStatus( + prAdapter->prGlueInfo, + (uint8_t) prP2pBssInfo->u4PrivateData, + NULL, + prDeauthFrame->aucInfoElem, + u2IELength, + u2ReasonCode, + WLAN_STATUS_MEDIA_DISCONNECT); + +#else +/* Indicate disconnect to Host. */ + kalP2PGCIndicateConnectionStatus( + prAdapter->prGlueInfo, + (uint8_t) prP2pBssInfo->u4PrivateData, + NULL, + prDeauthFrame->aucInfoElem, + u2IELength, + u2ReasonCode); +#endif + + prP2pBssInfo->prStaRecOfAP = NULL; + + p2pFuncDisconnect(prAdapter, + prP2pBssInfo, + prStaRec, + FALSE, + u2ReasonCode); + + SET_NET_PWR_STATE_IDLE(prAdapter, + prP2pBssInfo->ucBssIndex); + + p2pRoleFsmStateTransition(prAdapter, + P2P_ROLE_INDEX_2_ROLE_FSM_INFO( + prAdapter, + prP2pBssInfo->u4PrivateData), + P2P_ROLE_STATE_IDLE); + + p2pFuncStopComplete(prAdapter, prP2pBssInfo); + } + break; + case OP_MODE_ACCESS_POINT: + /* Delete client from client list. */ + if (authProcessRxDeauthFrame(prSwRfb, + prP2pBssInfo->aucBSSID, + &u2ReasonCode) == WLAN_STATUS_SUCCESS) { +#if CFG_SUPPORT_802_11W + /* AP PMF */ + if (rsnCheckBipKeyInstalled(prAdapter, + prStaRec)) { + if (prSwRfb->fgIsCipherMS || + prSwRfb->fgIsCipherLenMS) { + /* if cipher mismatch, + * or incorrect encrypt, + * just drop + */ + DBGLOG(P2P, ERROR, + "Rx deauth CM/CLM=1\n"); + return; + } + + /* 4.3.3.1 send unprotected deauth + * reason 6/7 + */ + DBGLOG(P2P, INFO, "deauth reason=6\n"); + fgSendDeauth = TRUE; + u2ReasonCode = REASON_CODE_CLASS_2_ERR; + prStaRec->rPmfCfg.fgRxDeauthResp = TRUE; + } +#endif + + if (bssRemoveClient(prAdapter, + prP2pBssInfo, prStaRec)) { + /* Indicate disconnect to Host. */ + p2pFuncDisconnect(prAdapter, + prP2pBssInfo, + prStaRec, + fgSendDeauth, + u2ReasonCode); + /* Deactive BSS + * if PWR is IDLE and no peer + */ + if (IS_NET_PWR_STATE_IDLE(prAdapter, + prP2pBssInfo->ucBssIndex) && + (bssGetClientCount(prAdapter, + prP2pBssInfo) == 0)) { + /* All Peer disconnected !! + * Stop BSS now!! + */ + p2pFuncStopComplete(prAdapter, + prP2pBssInfo); + } + } + } + break; + case OP_MODE_P2P_DEVICE: + default: + /* Findout why someone + * sent deauthentication frame to us. + */ + ASSERT(FALSE); + break; + } + + DBGLOG(P2P, TRACE, "Deauth Reason:%d\n", u2ReasonCode); + + } while (FALSE); +} /* p2pRoleFsmRunEventRxDeauthentication */ + +void p2pRoleFsmRunEventRxDisassociation(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, + IN struct SW_RFB *prSwRfb) +{ + struct BSS_INFO *prP2pBssInfo = (struct BSS_INFO *) NULL; + uint16_t u2ReasonCode = 0; + /* flag to send deauth when rx sta disassc/deauth */ + u_int8_t fgSendDeauth = FALSE; + + + if (prStaRec == NULL) + prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); + + if (!prStaRec) { + DBGLOG(P2P, ERROR, + "prStaRec of prSwRfb->ucStaRecIdx %d is NULL!\n", + prSwRfb->ucStaRecIdx); + return; + } + + prP2pBssInfo = prAdapter->aprBssInfo[prStaRec->ucBssIndex]; + + if (prStaRec->ucStaState == STA_STATE_1) + return; + + DBGLOG(P2P, TRACE, "RX Disassoc\n"); + + switch (prP2pBssInfo->eCurrentOPMode) { + case OP_MODE_INFRASTRUCTURE: + if (assocProcessRxDisassocFrame(prAdapter, + prSwRfb, + prStaRec->aucMacAddr, + &prStaRec->u2ReasonCode) == WLAN_STATUS_SUCCESS) { + + struct WLAN_DISASSOC_FRAME *prDisassocFrame = + (struct WLAN_DISASSOC_FRAME *) + prSwRfb->pvHeader; + uint16_t u2IELength = 0; + + if (prP2pBssInfo->prStaRecOfAP != prStaRec) + break; + + u2IELength = prSwRfb->u2PacketLen + - (WLAN_MAC_HEADER_LEN + REASON_CODE_FIELD_LEN); + +#if CFG_WPS_DISCONNECT || (KERNEL_VERSION(4, 4, 0) <= CFG80211_VERSION_CODE) + /* Indicate disconnect to Host. */ + kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, + (uint8_t) prP2pBssInfo->u4PrivateData, NULL, + prDisassocFrame->aucInfoElem, + u2IELength, prStaRec->u2ReasonCode, + WLAN_STATUS_MEDIA_DISCONNECT); + +#else + /* Indicate disconnect to Host. */ + kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, + (uint8_t) prP2pBssInfo->u4PrivateData, NULL, + prDisassocFrame->aucInfoElem, + u2IELength, prStaRec->u2ReasonCode); +#endif + + prP2pBssInfo->prStaRecOfAP = NULL; + + p2pFuncDisconnect(prAdapter, + prP2pBssInfo, + prStaRec, + FALSE, + prStaRec->u2ReasonCode); + + SET_NET_PWR_STATE_IDLE(prAdapter, + prP2pBssInfo->ucBssIndex); + + p2pRoleFsmStateTransition(prAdapter, + P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, + prP2pBssInfo->u4PrivateData), + P2P_ROLE_STATE_IDLE); + + p2pFuncStopComplete(prAdapter, prP2pBssInfo); + } + break; + case OP_MODE_ACCESS_POINT: + /* Delete client from client list. */ + if (assocProcessRxDisassocFrame(prAdapter, + prSwRfb, + prP2pBssInfo->aucBSSID, + &u2ReasonCode) == WLAN_STATUS_SUCCESS) { + +#if CFG_SUPPORT_802_11W + /* AP PMF */ + if (rsnCheckBipKeyInstalled(prAdapter, prStaRec)) { + if (prSwRfb->fgIsCipherMS || + prSwRfb->fgIsCipherLenMS) { + /* if cipher mismatch, + * or incorrect encrypt, just drop + */ + DBGLOG(P2P, ERROR, + "Rx disassoc CM/CLM=1\n"); + return; + } + + /* 4.3.3.1 send unprotected deauth + * reason 6/7 + */ + DBGLOG(P2P, INFO, "deauth reason=6\n"); + fgSendDeauth = TRUE; + u2ReasonCode = REASON_CODE_CLASS_2_ERR; + prStaRec->rPmfCfg.fgRxDeauthResp = TRUE; + } +#endif + + if (bssRemoveClient(prAdapter, + prP2pBssInfo, prStaRec)) { + /* Indicate disconnect to Host. */ + p2pFuncDisconnect(prAdapter, + prP2pBssInfo, + prStaRec, + fgSendDeauth, + u2ReasonCode); + /* Deactive BSS if PWR is IDLE and no peer */ + if (IS_NET_PWR_STATE_IDLE(prAdapter, + prP2pBssInfo->ucBssIndex) && + (bssGetClientCount(prAdapter, + prP2pBssInfo) == 0)) { + /* All Peer disconnected !! + * Stop BSS now!! + */ + p2pFuncStopComplete(prAdapter, + prP2pBssInfo); + } + + } + } + break; + case OP_MODE_P2P_DEVICE: + default: + ASSERT(FALSE); + break; + } + +} /* p2pRoleFsmRunEventRxDisassociation */ + +void p2pRoleFsmRunEventBeaconTimeout(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prP2pBssInfo) +{ + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *) NULL; + + do { + ASSERT_BREAK((prAdapter != NULL) && (prP2pBssInfo != NULL)); + + prP2pRoleFsmInfo = + P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, + prP2pBssInfo->u4PrivateData); + + /* Only client mode would have beacon lost event. */ + if (prP2pBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) { + DBGLOG(P2P, ERROR, + "Error case, P2P BSS %d not INFRA mode but beacon timeout\n", + prP2pRoleFsmInfo->ucRoleIndex); + break; + } + + DBGLOG(P2P, TRACE, + "p2pFsmRunEventBeaconTimeout: BSS %d Beacon Timeout\n", + prP2pRoleFsmInfo->ucRoleIndex); + + if (prP2pBssInfo->eConnectionState + == MEDIA_STATE_CONNECTED) { + +#if CFG_WPS_DISCONNECT || (KERNEL_VERSION(4, 4, 0) <= CFG80211_VERSION_CODE) + /* Indicate disconnect to Host. */ + kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, + prP2pRoleFsmInfo->ucRoleIndex, + NULL, NULL, 0, + REASON_CODE_DEAUTH_LEAVING_BSS, + WLAN_STATUS_MEDIA_DISCONNECT); + + +#else + /* Indicate disconnect to Host. */ + kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, + prP2pRoleFsmInfo->ucRoleIndex, + NULL, NULL, 0, + REASON_CODE_DEAUTH_LEAVING_BSS); +#endif + + if (prP2pBssInfo->prStaRecOfAP != NULL) { + struct STA_RECORD *prStaRec = + prP2pBssInfo->prStaRecOfAP; + + prP2pBssInfo->prStaRecOfAP = NULL; + + p2pFuncDisconnect(prAdapter, + prP2pBssInfo, + prStaRec, FALSE, + REASON_CODE_DISASSOC_LEAVING_BSS); + + SET_NET_PWR_STATE_IDLE(prAdapter, + prP2pBssInfo->ucBssIndex); + /* 20120830 moved into p2pFuncDisconnect() */ + /* cnmStaRecFree(prAdapter, + * prP2pBssInfo->prStaRecOfAP); + */ + p2pRoleFsmStateTransition(prAdapter, + prP2pRoleFsmInfo, + P2P_ROLE_STATE_IDLE); + + p2pFuncStopComplete(prAdapter, prP2pBssInfo); + } + } + } while (FALSE); +} /* p2pFsmRunEventBeaconTimeout */ + +/*================== Message Event ==================*/ +void p2pRoleFsmRunEventStartAP(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *) NULL; + struct MSG_P2P_START_AP *prP2pStartAPMsg = + (struct MSG_P2P_START_AP *) NULL; + struct P2P_CONNECTION_REQ_INFO *prP2pConnReqInfo = + (struct P2P_CONNECTION_REQ_INFO *) NULL; + struct BSS_INFO *prP2pBssInfo = (struct BSS_INFO *) NULL; + struct P2P_SPECIFIC_BSS_INFO *prP2pSpecificBssInfo = + (struct P2P_SPECIFIC_BSS_INFO *) NULL; + + DBGLOG(P2P, TRACE, "p2pRoleFsmRunEventStartAP\n"); + + prP2pStartAPMsg = (struct MSG_P2P_START_AP *) prMsgHdr; + + prP2pRoleFsmInfo = + P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, + prP2pStartAPMsg->ucRoleIdx); + + prAdapter->prP2pInfo->eConnState = P2P_CNN_NORMAL; + + DBGLOG(P2P, TRACE, + "p2pRoleFsmRunEventStartAP with Role(%d)\n", + prP2pStartAPMsg->ucRoleIdx); + + + if (!prP2pRoleFsmInfo) { + DBGLOG(P2P, ERROR, + "p2pRoleFsmRunEventStartAP: Corresponding P2P Role FSM empty: %d.\n", + prP2pStartAPMsg->ucRoleIdx); + goto error; + } + + prP2pBssInfo = prAdapter->aprBssInfo[prP2pRoleFsmInfo->ucBssIndex]; + prP2pSpecificBssInfo = + prAdapter->rWifiVar + .prP2pSpecificBssInfo[prP2pBssInfo->u4PrivateData]; + prP2pConnReqInfo = &(prP2pRoleFsmInfo->rConnReqInfo); + + if (prP2pStartAPMsg->u4BcnInterval) { + DBGLOG(P2P, TRACE, + "Beacon interval updated to :%u\n", + prP2pStartAPMsg->u4BcnInterval); + prP2pBssInfo->u2BeaconInterval = + (uint16_t) prP2pStartAPMsg->u4BcnInterval; + } else if (prP2pBssInfo->u2BeaconInterval == 0) { + prP2pBssInfo->u2BeaconInterval = DOT11_BEACON_PERIOD_DEFAULT; + } + + if (prP2pStartAPMsg->u4DtimPeriod) { + DBGLOG(P2P, TRACE, + "DTIM interval updated to :%u\n", + prP2pStartAPMsg->u4DtimPeriod); + prP2pBssInfo->ucDTIMPeriod = + (uint8_t) prP2pStartAPMsg->u4DtimPeriod; + } else if (prP2pBssInfo->ucDTIMPeriod == 0) { + prP2pBssInfo->ucDTIMPeriod = DOT11_DTIM_PERIOD_DEFAULT; + } + + if (prP2pStartAPMsg->u2SsidLen != 0) { + kalMemCopy(prP2pConnReqInfo->rSsidStruct.aucSsid, + prP2pStartAPMsg->aucSsid, + prP2pStartAPMsg->u2SsidLen); + prP2pConnReqInfo->rSsidStruct.ucSsidLen = + prP2pSpecificBssInfo->u2GroupSsidLen = + prP2pStartAPMsg->u2SsidLen; + kalMemCopy(prP2pSpecificBssInfo->aucGroupSsid, + prP2pStartAPMsg->aucSsid, + prP2pStartAPMsg->u2SsidLen); + } + + if (p2pFuncIsAPMode(prAdapter->rWifiVar + .prP2PConnSettings[prP2pStartAPMsg->ucRoleIdx])) { + prP2pConnReqInfo->eConnRequest = P2P_CONNECTION_TYPE_PURE_AP; + + /* Overwrite AP channel */ + if (prAdapter->rWifiVar.ucApChannel && + prAdapter->rWifiVar.ucApChnlDefFromCfg) { + prP2pConnReqInfo->rChannelInfo.ucChannelNum = + prAdapter->rWifiVar.ucApChannel; + + if (prAdapter->rWifiVar.ucApChannel <= 14) + prP2pConnReqInfo->rChannelInfo.eBand = BAND_2G4; + else + prP2pConnReqInfo->rChannelInfo.eBand = BAND_5G; + } + } else { + prP2pConnReqInfo->eConnRequest = P2P_CONNECTION_TYPE_GO; +#if CFG_P2P_DEFAULT_CLIENT_COUNT + kalP2PSetMaxClients(prAdapter->prGlueInfo, + P2P_DEFAULT_CLIENT_COUNT, + prP2pStartAPMsg->ucRoleIdx); +#endif + } + + /* Clear list to ensure no client staRec */ + if (bssGetClientCount(prAdapter, prP2pBssInfo) != 0) { + DBGLOG(P2P, WARN, + "Clear list to ensure no empty/client staRec\n"); + bssInitializeClientList(prAdapter, prP2pBssInfo); + } + + /* The supplicant may start AP + * before rP2pRoleFsmTimeoutTimer is time out + */ + /* We need to make sure the BSS was deactivated + * and all StaRec can be free + */ + if (timerPendingTimer(&(prP2pRoleFsmInfo->rP2pRoleFsmTimeoutTimer))) { + /* call p2pRoleFsmRunEventTimeout() + * to deactive BSS and free channel + */ + p2pRoleFsmRunEventTimeout(prAdapter, + (unsigned long)prP2pRoleFsmInfo); + cnmTimerStopTimer(prAdapter, + &(prP2pRoleFsmInfo->rP2pRoleFsmTimeoutTimer)); + } + +#if (CFG_SUPPORT_DFS_MASTER == 1) + if (timerPendingTimer(&(prP2pRoleFsmInfo->rDfsShutDownTimer))) { + DBGLOG(P2P, INFO, + "p2pRoleFsmRunEventStartAP: Stop DFS shut down timer.\n"); + cnmTimerStopTimer(prAdapter, + &(prP2pRoleFsmInfo->rDfsShutDownTimer)); + } +#endif + + prP2pBssInfo->eBand = prP2pConnReqInfo->rChannelInfo.eBand; + if (prP2pBssInfo->fgIsWmmInited == FALSE) + prP2pBssInfo->ucWmmQueSet = cnmWmmIndexDecision(prAdapter, + prP2pBssInfo); +#if CFG_SUPPORT_DBDC + /* DBDC decsion.may change OpNss */ + cnmDbdcPreConnectionEnableDecision(prAdapter, + prP2pBssInfo->ucBssIndex, + prP2pConnReqInfo->rChannelInfo.eBand, + prP2pConnReqInfo->rChannelInfo.ucChannelNum, + prP2pBssInfo->ucWmmQueSet); +#endif /*CFG_SUPPORT_DBDC*/ + + cnmOpModeGetTRxNss( + prAdapter, prP2pBssInfo->ucBssIndex, + &prP2pBssInfo->ucOpRxNss, &prP2pBssInfo->ucOpTxNss); + prP2pBssInfo->eHiddenSsidType = prP2pStartAPMsg->ucHiddenSsidType; + + DBGLOG(P2P, TRACE, + "p2pRoleFsmRunEventStartAP: start AP CH[%u]", + prP2pConnReqInfo->rChannelInfo.ucChannelNum); + DBGLOG(P2P, TRACE, "RxNSS[%u]TxNss[%u].\n", + prP2pBssInfo->ucOpRxNss, prP2pBssInfo->ucOpTxNss); + /* + * beacon content is related with Nss number , + * need to update because of modification + */ + bssUpdateBeaconContent(prAdapter, prP2pBssInfo->ucBssIndex); + + if ((prP2pBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) || + (prP2pBssInfo->eIntendOPMode != OP_MODE_NUM)) { + /* 1. No switch to AP mode. + * 2. Not started yet. + */ + + if (prP2pRoleFsmInfo->eCurrentState + != P2P_ROLE_STATE_AP_CHNL_DETECTION + && + prP2pRoleFsmInfo->eCurrentState + != P2P_ROLE_STATE_IDLE) { + /* Make sure the state is in IDLE state. */ + p2pRoleFsmRunEventAbort(prAdapter, prP2pRoleFsmInfo); + } else if (prP2pRoleFsmInfo->eCurrentState + == P2P_ROLE_STATE_AP_CHNL_DETECTION) { + goto error; + } + + /* Leave IDLE state. */ + SET_NET_PWR_STATE_ACTIVE(prAdapter, prP2pBssInfo->ucBssIndex); + + prP2pBssInfo->eIntendOPMode = OP_MODE_ACCESS_POINT; + +#if 0 + prP2pRoleFsmInfo->rConnReqInfo.rChannelInfo.ucChannelNum = 8; + prP2pRoleFsmInfo->rConnReqInfo.rChannelInfo.eBand = BAND_2G4; + /* prP2pRoleFsmInfo->rConnReqInfo.rChannelInfo.ucBandwidth = + * 0; + */ + /* prP2pRoleFsmInfo->rConnReqInfo.rChannelInfo.eSCO = + * CHNL_EXT_SCN; + */ +#endif + + if (prP2pRoleFsmInfo->rConnReqInfo + .rChannelInfo.ucChannelNum != 0) { + DBGLOG(P2P, INFO, + "Role(%d) StartAP at CH[%u]RxNSS[%u]TxNss[%u]\n", + prP2pStartAPMsg->ucRoleIdx, + prP2pRoleFsmInfo->rConnReqInfo + .rChannelInfo.ucChannelNum, + prP2pBssInfo->ucOpRxNss, + prP2pBssInfo->ucOpTxNss); + + p2pRoleStatePrepare_To_REQING_CHANNEL_STATE( + prAdapter, + GET_BSS_INFO_BY_INDEX(prAdapter, + prP2pRoleFsmInfo->ucBssIndex), + &(prP2pRoleFsmInfo->rConnReqInfo), + &(prP2pRoleFsmInfo->rChnlReqInfo)); + p2pRoleFsmStateTransition(prAdapter, + prP2pRoleFsmInfo, + P2P_ROLE_STATE_REQING_CHANNEL); + } else { + DBGLOG(P2P, INFO, + "Role(%d) StartAP Scan for working channel\n", + prP2pStartAPMsg->ucRoleIdx); + + /* For AP/GO mode with specific channel + * or non-specific channel. + */ + p2pRoleFsmStateTransition(prAdapter, + prP2pRoleFsmInfo, + P2P_ROLE_STATE_AP_CHNL_DETECTION); + } + } + +error: + cnmMemFree(prAdapter, prMsgHdr); +} /* p2pRoleFsmRunEventStartAP */ + + +void p2pRoleFsmRunEventDelIface(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *) NULL; + struct BSS_INFO *prP2pBssInfo = (struct BSS_INFO *) NULL; + struct MSG_P2P_DEL_IFACE *prP2pDelIfaceMsg = + (struct MSG_P2P_DEL_IFACE *) NULL; + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *) NULL; + uint8_t ucRoleIdx; + struct GL_P2P_INFO *prP2pInfo = (struct GL_P2P_INFO *) NULL; + + + DBGLOG(P2P, INFO, "p2pRoleFsmRunEventDelIface\n"); + + prGlueInfo = prAdapter->prGlueInfo; + if (prGlueInfo == NULL) { + DBGLOG(P2P, ERROR, "prGlueInfo shouldn't be NULL!\n"); + goto error; + } + + prP2pDelIfaceMsg = (struct MSG_P2P_DEL_IFACE *) prMsgHdr; + ucRoleIdx = prP2pDelIfaceMsg->ucRoleIdx; + prAdapter = prGlueInfo->prAdapter; + prP2pInfo = prGlueInfo->prP2PInfo[ucRoleIdx]; + prP2pRoleFsmInfo = P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, ucRoleIdx); + if (!prP2pRoleFsmInfo) { + DBGLOG(P2P, ERROR, + "p2pRoleFsmRunEventDelIface: Corresponding P2P Role FSM empty: %d.\n", + prP2pDelIfaceMsg->ucRoleIdx); + goto error; + } + + prP2pBssInfo = prAdapter->aprBssInfo[prP2pRoleFsmInfo->ucBssIndex]; + + /* The state is in disconnecting and can not change any BSS status */ + if (IS_NET_PWR_STATE_IDLE(prAdapter, prP2pBssInfo->ucBssIndex) && + IS_NET_ACTIVE(prAdapter, prP2pBssInfo->ucBssIndex) && + prP2pBssInfo->eConnectionState == MEDIA_STATE_CONNECTED) { + DBGLOG(P2P, INFO, "under deauth procedure, Quit.\n"); + } else { + /*p2pFuncDissolve(prAdapter, + * prP2pBssInfo, TRUE, + * REASON_CODE_DEAUTH_LEAVING_BSS); + */ + + SET_NET_PWR_STATE_IDLE(prAdapter, prP2pBssInfo->ucBssIndex); + + /* Function Dissolve should already enter IDLE state. */ + p2pRoleFsmStateTransition(prAdapter, + prP2pRoleFsmInfo, + P2P_ROLE_STATE_IDLE); + + p2pRoleFsmRunEventAbort(prAdapter, prP2pRoleFsmInfo); + + /* Clear CmdQue */ + kalClearMgmtFramesByBssIdx(prAdapter->prGlueInfo, + prP2pBssInfo->ucBssIndex); + kalClearSecurityFramesByBssIdx(prAdapter->prGlueInfo, + prP2pBssInfo->ucBssIndex); + /* Clear PendingCmdQue */ + wlanReleasePendingCMDbyBssIdx(prAdapter, + prP2pBssInfo->ucBssIndex); + /* Clear PendingTxMsdu */ + nicFreePendingTxMsduInfo(prAdapter, + prP2pBssInfo->ucBssIndex, MSDU_REMOVE_BY_BSS_INDEX); + + /* Deactivate BSS. */ + UNSET_NET_ACTIVE(prAdapter, prP2pRoleFsmInfo->ucBssIndex); + + nicDeactivateNetwork(prAdapter, prP2pRoleFsmInfo->ucBssIndex); + nicUpdateBss(prAdapter, prP2pRoleFsmInfo->ucBssIndex); + } + +error: + cnmMemFree(prAdapter, prMsgHdr); +} /* p2pRoleFsmRunEventStartAP */ + + +void p2pRoleFsmRunEventStopAP(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct BSS_INFO *prP2pBssInfo = (struct BSS_INFO *) NULL; + struct MSG_P2P_STOP_AP *prP2pStopApMsg; + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *) NULL; + struct STA_RECORD *prCurrStaRec; + struct LINK *prClientList; + + prP2pStopApMsg = (struct MSG_P2P_STOP_AP *) prMsgHdr; + + prP2pRoleFsmInfo = + P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, + prP2pStopApMsg->ucRoleIdx); + + if (!prP2pRoleFsmInfo) { + DBGLOG(P2P, ERROR, + "p2pRoleFsmRunEventStopAP: Corresponding P2P Role FSM empty: %d.\n", + prP2pStopApMsg->ucRoleIdx); + goto error; + } + + prP2pBssInfo = prAdapter->aprBssInfo[prP2pRoleFsmInfo->ucBssIndex]; + + if (!prP2pBssInfo) { + DBGLOG(P2P, ERROR, + "prP2pBssInfo of prP2pRoleFsmInfo->ucBssIndex %d is NULL!\n", + prP2pRoleFsmInfo->ucBssIndex); + goto error; + } + +#if (CFG_SUPPORT_DFS_MASTER == 1) + p2pFuncSetDfsState(DFS_STATE_INACTIVE); + p2pFuncStopRdd(prAdapter, prP2pBssInfo->ucBssIndex); +#endif + + kalP2PResetBlackList(prAdapter->prGlueInfo, + prP2pStopApMsg->ucRoleIdx); + + if (prP2pRoleFsmInfo->eCurrentState != P2P_ROLE_STATE_REQING_CHANNEL) { + p2pFuncStopGO(prAdapter, prP2pBssInfo); + + /* Start all Deauth done timer for all client */ + prClientList = &prP2pBssInfo->rStaRecOfClientList; + + LINK_FOR_EACH_ENTRY(prCurrStaRec, + prClientList, rLinkEntry, struct STA_RECORD) { + if (!prCurrStaRec) + break; + /* Do not restart timer if the timer is pending, */ + /* (start in p2pRoleFsmRunEventConnectionAbort()) */ + if (!timerPendingTimer( + &(prCurrStaRec->rDeauthTxDoneTimer))) { + cnmTimerInitTimer(prAdapter, + &(prCurrStaRec->rDeauthTxDoneTimer), + (PFN_MGMT_TIMEOUT_FUNC) + p2pRoleFsmDeauthTimeout, + (unsigned long) prCurrStaRec); + + cnmTimerStartTimer(prAdapter, + &(prCurrStaRec->rDeauthTxDoneTimer), + P2P_DEAUTH_TIMEOUT_TIME_MS); + } + } + } + + SET_NET_PWR_STATE_IDLE(prAdapter, prP2pBssInfo->ucBssIndex); + + /* Postpone entering idle state if sending deauth frames. This is to + * prevent releasing channel too early and cause unnecessary cnm + * time when starting and stopping AP quickly. + */ + if (IS_NET_ACTIVE(prAdapter, prP2pBssInfo->ucBssIndex) && + prP2pBssInfo->eConnectionState == MEDIA_STATE_CONNECTED) { + DBGLOG(P2P, INFO, + "postpone entering idle state for deauth process\n"); + } else { + p2pRoleFsmStateTransition(prAdapter, + prP2pRoleFsmInfo, + P2P_ROLE_STATE_IDLE); + } + +error: + cnmMemFree(prAdapter, prMsgHdr); + +} /* p2pRoleFsmRunEventStopAP */ + +#if (CFG_SUPPORT_DFS_MASTER == 1) +void p2pRoleFsmRunEventDfsCac(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *) NULL; + struct MSG_P2P_DFS_CAC *prP2pDfsCacMsg = + (struct MSG_P2P_DFS_CAC *) NULL; + struct P2P_CONNECTION_REQ_INFO *prP2pConnReqInfo = + (struct P2P_CONNECTION_REQ_INFO *) NULL; + struct BSS_INFO *prP2pBssInfo = (struct BSS_INFO *) NULL; + enum ENUM_CHANNEL_WIDTH rChannelWidth; + + DBGLOG(P2P, INFO, "p2pRoleFsmRunEventDfsCac\n"); + + prP2pDfsCacMsg = (struct MSG_P2P_DFS_CAC *) prMsgHdr; + + rChannelWidth = prP2pDfsCacMsg->eChannelWidth; + + prP2pRoleFsmInfo = + P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, + prP2pDfsCacMsg->ucRoleIdx); + + DBGLOG(P2P, INFO, + "p2pRoleFsmRunEventDfsCac with Role(%d)\n", + prP2pDfsCacMsg->ucRoleIdx); + + if (!prP2pRoleFsmInfo) { + DBGLOG(P2P, ERROR, + "p2pRoleFsmRunEventDfsCac: Corresponding P2P Role FSM empty: %d.\n", + prP2pDfsCacMsg->ucRoleIdx); + goto error; + } + + if (timerPendingTimer(&(prP2pRoleFsmInfo->rDfsShutDownTimer))) { + DBGLOG(P2P, INFO, + "p2pRoleFsmRunEventDfsCac: Stop DFS shut down timer.\n"); + cnmTimerStopTimer(prAdapter, + &(prP2pRoleFsmInfo->rDfsShutDownTimer)); + } + + prP2pBssInfo = prAdapter->aprBssInfo[prP2pRoleFsmInfo->ucBssIndex]; + + prP2pConnReqInfo = &(prP2pRoleFsmInfo->rConnReqInfo); + + if (p2pFuncIsAPMode(prAdapter->rWifiVar + .prP2PConnSettings[prP2pDfsCacMsg->ucRoleIdx])) + prP2pConnReqInfo->eConnRequest = P2P_CONNECTION_TYPE_PURE_AP; + else + prP2pConnReqInfo->eConnRequest = P2P_CONNECTION_TYPE_GO; + + prP2pBssInfo->eBand = prP2pConnReqInfo->rChannelInfo.eBand; + if (prP2pBssInfo->fgIsWmmInited == FALSE) + prP2pBssInfo->ucWmmQueSet = cnmWmmIndexDecision(prAdapter, + prP2pBssInfo); + +#if CFG_SUPPORT_DBDC + /* DBDC decsion.may change OpNss */ + cnmDbdcPreConnectionEnableDecision(prAdapter, + prP2pBssInfo->ucBssIndex, + prP2pConnReqInfo->rChannelInfo.eBand, + prP2pConnReqInfo->rChannelInfo.ucChannelNum, + prP2pBssInfo->ucWmmQueSet + ); +#endif /*CFG_SUPPORT_DBDC*/ + + cnmOpModeGetTRxNss( + prAdapter, prP2pBssInfo->ucBssIndex, + &prP2pBssInfo->ucOpRxNss, &prP2pBssInfo->ucOpTxNss); + + DBGLOG(P2P, INFO, + "p2pRoleFsmRunEventDfsCac: CH[%u]RxNSS[%u]TxNss[%u].\n", + prP2pConnReqInfo->rChannelInfo.ucChannelNum, + prP2pBssInfo->ucOpRxNss, + prP2pBssInfo->ucOpTxNss); + + if (prP2pRoleFsmInfo->eCurrentState != P2P_ROLE_STATE_IDLE) { + /* Make sure the state is in IDLE state. */ + p2pRoleFsmRunEventAbort(prAdapter, prP2pRoleFsmInfo); + } + + /* Leave IDLE state. */ + SET_NET_PWR_STATE_ACTIVE(prAdapter, prP2pBssInfo->ucBssIndex); + + prP2pBssInfo->eIntendOPMode = OP_MODE_ACCESS_POINT; + prP2pBssInfo->fgIsDfsActive = TRUE; + + if (prP2pRoleFsmInfo->rConnReqInfo.rChannelInfo.ucChannelNum != 0) { + DBGLOG(P2P, INFO, "Role(%d) Set channel at CH(%d)\n", + prP2pDfsCacMsg->ucRoleIdx, + prP2pRoleFsmInfo->rConnReqInfo + .rChannelInfo.ucChannelNum); + + p2pRoleStatePrepare_To_DFS_CAC_STATE(prAdapter, + GET_BSS_INFO_BY_INDEX(prAdapter, + prP2pRoleFsmInfo->ucBssIndex), + rChannelWidth, + &(prP2pRoleFsmInfo->rConnReqInfo), + &(prP2pRoleFsmInfo->rChnlReqInfo)); + p2pRoleFsmStateTransition(prAdapter, + prP2pRoleFsmInfo, + P2P_ROLE_STATE_DFS_CAC); + } else { + DBGLOG(P2P, ERROR, + "prP2pRoleFsmInfo->rConnReqInfo.rChannelInfo.ucChannelNum shouldn't be 0\n"); + } + +error: + cnmMemFree(prAdapter, prMsgHdr); +} /*p2pRoleFsmRunEventDfsCac*/ + +void p2pRoleFsmRunEventRadarDet(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *) NULL; + struct BSS_INFO *prP2pBssInfo = (struct BSS_INFO *) NULL; + struct MSG_P2P_RADAR_DETECT *prMsgP2pRddDetMsg; + + + DBGLOG(P2P, INFO, "p2pRoleFsmRunEventRadarDet\n"); + + prMsgP2pRddDetMsg = (struct MSG_P2P_RADAR_DETECT *) prMsgHdr; + + prP2pBssInfo = + GET_BSS_INFO_BY_INDEX(prAdapter, + prMsgP2pRddDetMsg->ucBssIndex); + + prP2pRoleFsmInfo = + P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, + prP2pBssInfo->u4PrivateData); + + DBGLOG(P2P, INFO, + "p2pRoleFsmRunEventRadarDet with Role(%d)\n", + prP2pRoleFsmInfo->ucRoleIndex); + + if (prP2pRoleFsmInfo->eCurrentState != P2P_ROLE_STATE_DFS_CAC && + prP2pRoleFsmInfo->eCurrentState != P2P_ROLE_STATE_IDLE) { + DBGLOG(P2P, ERROR, + "Wrong prP2pRoleFsmInfo->eCurrentState \"%s\"!", + (prP2pRoleFsmInfo->eCurrentState < P2P_ROLE_STATE_NUM + ? (const char *) + p2pRoleFsmGetFsmState(prP2pRoleFsmInfo->eCurrentState) + : "")); + goto error; + } + + if (p2pFuncGetRadarDetectMode()) { + DBGLOG(P2P, INFO, + "p2pRoleFsmRunEventRadarDet: Ignore radar event\n"); + if (prP2pRoleFsmInfo->eCurrentState == P2P_ROLE_STATE_DFS_CAC) + p2pFuncSetDfsState(DFS_STATE_CHECKING); + else + p2pFuncSetDfsState(DFS_STATE_ACTIVE); + } else { + if (prP2pRoleFsmInfo->eCurrentState == P2P_ROLE_STATE_DFS_CAC) + p2pRoleFsmStateTransition(prAdapter, + prP2pRoleFsmInfo, + P2P_ROLE_STATE_IDLE); + + kalP2PRddDetectUpdate(prAdapter->prGlueInfo, + prP2pRoleFsmInfo->ucRoleIndex); + cnmTimerStartTimer(prAdapter, + &(prP2pRoleFsmInfo->rDfsShutDownTimer), + 5000); + } + + p2pFuncShowRadarInfo(prAdapter, prMsgP2pRddDetMsg->ucBssIndex); + +error: + cnmMemFree(prAdapter, prMsgHdr); +} /*p2pRoleFsmRunEventRadarDet*/ + +void p2pRoleFsmRunEventSetNewChannel(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *) NULL; + struct BSS_INFO *prP2pBssInfo = (struct BSS_INFO *) NULL; + struct MSG_P2P_SET_NEW_CHANNEL *prMsgP2pSetNewChannelMsg; + + + DBGLOG(P2P, INFO, "p2pRoleFsmRunEventSetNewChannel\n"); + + prMsgP2pSetNewChannelMsg = (struct MSG_P2P_SET_NEW_CHANNEL *) prMsgHdr; + + prP2pBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prMsgP2pSetNewChannelMsg->ucBssIndex); + + prP2pRoleFsmInfo = + P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, + prMsgP2pSetNewChannelMsg->ucRoleIdx); + + if (!prP2pRoleFsmInfo) { + DBGLOG(P2P, ERROR, + "Corresponding P2P Role FSM empty: %d.\n", + prMsgP2pSetNewChannelMsg->ucRoleIdx); + goto error; + } + + prP2pRoleFsmInfo->rChnlReqInfo.ucReqChnlNum = + prP2pRoleFsmInfo->rConnReqInfo.rChannelInfo.ucChannelNum; + prP2pRoleFsmInfo->rChnlReqInfo.eBand = + prP2pRoleFsmInfo->rConnReqInfo.rChannelInfo.eBand; + prP2pRoleFsmInfo->rChnlReqInfo.eChannelWidth = + prMsgP2pSetNewChannelMsg->eChannelWidth; + + prP2pRoleFsmInfo->rChnlReqInfo.ucCenterFreqS1 = + nicGetVhtS1(prP2pRoleFsmInfo->rChnlReqInfo.ucReqChnlNum, + prP2pRoleFsmInfo->rChnlReqInfo.eChannelWidth); + + prP2pRoleFsmInfo->rChnlReqInfo.ucCenterFreqS2 = 0; + +error: + cnmMemFree(prAdapter, prMsgHdr); +} /*p2pRoleFsmRunEventSetNewChannel*/ + +void p2pRoleFsmRunEventCsaDone(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct GLUE_INFO *prGlueInfo; + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *) NULL; + struct BSS_INFO *prP2pBssInfo = (struct BSS_INFO *) NULL; + struct MSG_P2P_CSA_DONE *prMsgP2pCsaDoneMsg; + uint8_t role_idx = 0; + struct BSS_INFO *prAisBssInfo; + struct GL_P2P_INFO *prP2PInfo = (struct GL_P2P_INFO *) NULL; + + DBGLOG(P2P, TRACE, "p2pRoleFsmRunEventCsaDone\n"); + + prMsgP2pCsaDoneMsg = (struct MSG_P2P_CSA_DONE *) prMsgHdr; + + prP2pBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prMsgP2pCsaDoneMsg->ucBssIndex); + prAisBssInfo = aisGetConnectedBssInfo(prAdapter); + + prP2pRoleFsmInfo = + P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, + prP2pBssInfo->u4PrivateData); + prP2PInfo = prAdapter->prGlueInfo->prP2PInfo[ + prP2pRoleFsmInfo->ucRoleIndex]; + + if (prP2PInfo) + prP2PInfo->eChnlSwitchPolicy = CHNL_SWITCH_POLICY_NONE; + + if (prAdapter->rWifiVar.eDbdcMode != ENUM_DBDC_MODE_DISABLED && + prP2pBssInfo->eBand != prP2pRoleFsmInfo->rChnlReqInfo.eBand) { + nicDeactivateNetwork(prAdapter, prP2pBssInfo->ucBssIndex); + nicUpdateBss(prAdapter, prP2pBssInfo->ucBssIndex); + nicActivateNetwork(prAdapter, prP2pBssInfo->ucBssIndex); + +#if CFG_SUPPORT_DBDC + cnmDbdcPreConnectionEnableDecision(prAdapter, + prP2pBssInfo->ucBssIndex, + prP2pRoleFsmInfo->rChnlReqInfo.eBand, + prP2pRoleFsmInfo->rChnlReqInfo.ucReqChnlNum, + prP2pBssInfo->ucWmmQueSet); +#endif /*CFG_SUPPORT_DBDC*/ + + p2pRoleFsmStateTransition(prAdapter, + prP2pRoleFsmInfo, + P2P_ROLE_STATE_SWITCH_CHANNEL); + } else { + prGlueInfo = prAdapter->prGlueInfo; + role_idx = prP2pRoleFsmInfo->ucRoleIndex; + /* Skip channel request/abort for STA+SAP/MCC concurrent case */ + if (prAisBssInfo && + (prAisBssInfo->ucPrimaryChannel != + prP2pBssInfo->ucPrimaryChannel) && + (prAisBssInfo->eConnectionState == + MEDIA_STATE_CONNECTED)) { + p2pFuncDfsSwitchCh(prAdapter, + prP2pBssInfo, + prP2pRoleFsmInfo->rChnlReqInfo); + } else { + p2pRoleFsmStateTransition(prAdapter, + prP2pRoleFsmInfo, + P2P_ROLE_STATE_SWITCH_CHANNEL); + } + } + + cnmMemFree(prAdapter, prMsgHdr); +} /*p2pRoleFsmRunEventCsaDone*/ + +void p2pRoleFsmRunEventDfsShutDownTimeout(IN struct ADAPTER *prAdapter, + IN unsigned long ulParamPtr) +{ + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *) ulParamPtr; + + DBGLOG(P2P, INFO, + "p2pRoleFsmRunEventDfsShutDownTimeout: DFS shut down.\n"); + + p2pFuncSetDfsState(DFS_STATE_INACTIVE); + p2pFuncStopRdd(prAdapter, prP2pRoleFsmInfo->ucBssIndex); + +} /* p2pRoleFsmRunEventDfsShutDownTimeout */ + +#endif + +void +p2pRoleFsmScanTargetBss(IN struct ADAPTER *prAdapter, + IN struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo, + IN uint8_t ucChannelNum, + IN struct P2P_SSID_STRUCT *prSsid) +{ + /* Update scan parameter... to scan target device. */ + struct P2P_SCAN_REQ_INFO *prScanReqInfo = + &(prP2pRoleFsmInfo->rScanReqInfo); + + prScanReqInfo->ucNumChannelList = 1; + prScanReqInfo->eScanType = SCAN_TYPE_ACTIVE_SCAN; + prScanReqInfo->eChannelSet = SCAN_CHANNEL_SPECIFIED; + prScanReqInfo->arScanChannelList[0].ucChannelNum = ucChannelNum; + prScanReqInfo->ucSsidNum = 1; + kalMemCopy(&(prScanReqInfo->arSsidStruct[0]), prSsid, + sizeof(struct P2P_SSID_STRUCT)); + /* Prevent other P2P ID in IE. */ + prScanReqInfo->u4BufLength = 0; + prScanReqInfo->fgIsAbort = TRUE; + + p2pRoleFsmStateTransition(prAdapter, + prP2pRoleFsmInfo, + P2P_ROLE_STATE_SCAN); +} + +void p2pRoleFsmRunEventConnectionRequest(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct BSS_INFO *prP2pBssInfo = (struct BSS_INFO *) NULL; + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *) NULL; + struct MSG_P2P_CONNECTION_REQUEST *prP2pConnReqMsg = + (struct MSG_P2P_CONNECTION_REQUEST *) NULL; + struct STA_RECORD *prStaRec = (struct STA_RECORD *) NULL; + + struct P2P_CONNECTION_REQ_INFO *prConnReqInfo = + (struct P2P_CONNECTION_REQ_INFO *) NULL; + struct P2P_CHNL_REQ_INFO *prChnlReqInfo = + (struct P2P_CHNL_REQ_INFO *) NULL; + struct P2P_JOIN_INFO *prJoinInfo = (struct P2P_JOIN_INFO *) NULL; + uint8_t ucRfBw; + + prP2pConnReqMsg = (struct MSG_P2P_CONNECTION_REQUEST *) prMsgHdr; + + prP2pRoleFsmInfo = + P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, + prP2pConnReqMsg->ucRoleIdx); + + prAdapter->prP2pInfo->eConnState = P2P_CNN_NORMAL; + + + if (!prP2pRoleFsmInfo) { + DBGLOG(P2P, ERROR, + "Corresponding P2P Role FSM empty: %d.\n", + prP2pConnReqMsg->ucRoleIdx); + goto error; + } + + prP2pBssInfo = prAdapter->aprBssInfo[prP2pRoleFsmInfo->ucBssIndex]; + + if (!prP2pBssInfo) { + DBGLOG(P2P, ERROR, + "prP2pRoleFsmInfo->ucBssIndex %d of prAdapter->aprBssInfo is NULL!\n", + prP2pRoleFsmInfo->ucBssIndex); + goto error; + } + + prConnReqInfo = &(prP2pRoleFsmInfo->rConnReqInfo); + prChnlReqInfo = &(prP2pRoleFsmInfo->rChnlReqInfo); + prJoinInfo = &(prP2pRoleFsmInfo->rJoinInfo); + + DBGLOG(P2P, TRACE, "p2pFsmRunEventConnectionRequest\n"); + + if (prP2pBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) + goto error; + + SET_NET_PWR_STATE_ACTIVE(prAdapter, prP2pBssInfo->ucBssIndex); + + /* In P2P GC case, the interval of + * two ASSOC flow could be very short, + * we must start to connect directly before Deauth done + */ + prStaRec = prP2pBssInfo->prStaRecOfAP; + if (prStaRec) { + if (timerPendingTimer(&prStaRec->rDeauthTxDoneTimer)) { + cnmTimerStopTimer(prAdapter, + &(prStaRec->rDeauthTxDoneTimer)); + /* Force to stop */ + p2pRoleFsmDeauthComplete(prAdapter, prStaRec); + } + } + /* Make sure the state is in IDLE state. */ + if (prP2pRoleFsmInfo->eCurrentState != P2P_ROLE_STATE_IDLE) + p2pRoleFsmRunEventAbort(prAdapter, prP2pRoleFsmInfo); + /* Update connection request information. */ + prConnReqInfo->eConnRequest = P2P_CONNECTION_TYPE_GC; + COPY_MAC_ADDR(prConnReqInfo->aucBssid, + prP2pConnReqMsg->aucBssid); + COPY_MAC_ADDR(prP2pBssInfo->aucOwnMacAddr, + prP2pConnReqMsg->aucSrcMacAddr); + kalMemCopy(&(prConnReqInfo->rSsidStruct), + &(prP2pConnReqMsg->rSsid), + sizeof(struct P2P_SSID_STRUCT)); + kalMemCopy(prConnReqInfo->aucIEBuf, + prP2pConnReqMsg->aucIEBuf, + prP2pConnReqMsg->u4IELen); + prConnReqInfo->u4BufLength = prP2pConnReqMsg->u4IELen; + + /* Find BSS Descriptor first. */ + prJoinInfo->prTargetBssDesc = + scanP2pSearchDesc(prAdapter, prConnReqInfo); + + if (prJoinInfo->prTargetBssDesc == NULL) { + p2pRoleFsmScanTargetBss(prAdapter, + prP2pRoleFsmInfo, + prP2pConnReqMsg->rChannelInfo.ucChannelNum, + &(prP2pConnReqMsg->rSsid)); + } else { + prChnlReqInfo->u8Cookie = 0; + prChnlReqInfo->ucReqChnlNum = + prP2pConnReqMsg->rChannelInfo.ucChannelNum; + prChnlReqInfo->eBand = prP2pConnReqMsg->rChannelInfo.eBand; + prChnlReqInfo->eChnlSco = prP2pConnReqMsg->eChnlSco; + prChnlReqInfo->u4MaxInterval = AIS_JOIN_CH_REQUEST_INTERVAL; + prChnlReqInfo->eChnlReqType = CH_REQ_TYPE_JOIN; + + rlmReviseMaxBw(prAdapter, + prP2pBssInfo->ucBssIndex, + &prChnlReqInfo->eChnlSco, + (enum ENUM_CHANNEL_WIDTH *) + &prChnlReqInfo->eChannelWidth, + &prChnlReqInfo->ucCenterFreqS1, + &prChnlReqInfo->ucReqChnlNum); + + prP2pBssInfo->eBand = prChnlReqInfo->eBand; + if (prP2pBssInfo->fgIsWmmInited == FALSE) + prP2pBssInfo->ucWmmQueSet = + cnmWmmIndexDecision(prAdapter, prP2pBssInfo); + +#if CFG_SUPPORT_DBDC + /* DBDC decsion.may change OpNss */ + cnmDbdcPreConnectionEnableDecision(prAdapter, + prP2pBssInfo->ucBssIndex, + prChnlReqInfo->eBand, + prChnlReqInfo->ucReqChnlNum, + prP2pBssInfo->ucWmmQueSet); +#endif /* CFG_SUPPORT_DBDC */ + + cnmOpModeGetTRxNss( + prAdapter, prP2pBssInfo->ucBssIndex, + &prP2pBssInfo->ucOpRxNss, &prP2pBssInfo->ucOpTxNss); + + DBGLOG(P2P, INFO, + "p2pRoleFsmRunEventConnectionRequest: start GC CH[%u]RxNSS[%u]TxNss[%u]\n", + prChnlReqInfo->ucReqChnlNum, + prP2pBssInfo->ucOpRxNss, + prP2pBssInfo->ucOpTxNss); + + + /* Decide RF BW by own OP and Peer OP BW */ + ucRfBw = cnmGetDbdcBwCapability(prAdapter, + prP2pBssInfo->ucBssIndex); + /* Revise to VHT OP BW */ + ucRfBw = rlmGetVhtOpBwByBssOpBw(ucRfBw); + if (ucRfBw > prJoinInfo->prTargetBssDesc->eChannelWidth) + ucRfBw = prJoinInfo->prTargetBssDesc->eChannelWidth; + + prChnlReqInfo->eChannelWidth = ucRfBw; + /* TODO: BW80+80 support */ + prChnlReqInfo->ucCenterFreqS1 = + nicGetVhtS1(prChnlReqInfo->ucReqChnlNum, + prChnlReqInfo->eChannelWidth); + prChnlReqInfo->ucCenterFreqS2 = 0; + + p2pRoleFsmStateTransition(prAdapter, + prP2pRoleFsmInfo, + P2P_ROLE_STATE_REQING_CHANNEL); + } + +error: + cnmMemFree(prAdapter, prMsgHdr); +} /* p2pRoleFsmRunEventConnectionRequest */ + +void p2pRoleFsmRunEventConnectionAbort(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct BSS_INFO *prP2pBssInfo = (struct BSS_INFO *) NULL; + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *) NULL; + struct MSG_P2P_CONNECTION_ABORT *prDisconnMsg = + (struct MSG_P2P_CONNECTION_ABORT *) NULL; + struct STA_RECORD *prStaRec = (struct STA_RECORD *) NULL; + + + prDisconnMsg = (struct MSG_P2P_CONNECTION_ABORT *) prMsgHdr; + + prP2pRoleFsmInfo = + P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, + prDisconnMsg->ucRoleIdx); + + DBGLOG(P2P, TRACE, + "p2pFsmRunEventConnectionAbort: Connection Abort.\n"); + + if (!prP2pRoleFsmInfo) { + DBGLOG(P2P, ERROR, + "p2pRoleFsmRunEventConnectionAbort: Corresponding P2P Role FSM empty: %d.\n", + prDisconnMsg->ucRoleIdx); + goto error; + } + + prP2pBssInfo = prAdapter->aprBssInfo[prP2pRoleFsmInfo->ucBssIndex]; + + if (!prP2pBssInfo) { + DBGLOG(P2P, ERROR, + "prAdapter->aprBssInfo[prP2pRoleFsmInfo->ucBssIndex(%d)] is NULL!", + prP2pRoleFsmInfo->ucBssIndex); + goto error; + } + + switch (prP2pBssInfo->eCurrentOPMode) { + case OP_MODE_INFRASTRUCTURE: + { + uint8_t aucBCBSSID[] = BC_BSSID; + + if (!prP2pBssInfo->prStaRecOfAP) { + struct P2P_JOIN_INFO *prJoinInfo; + + DBGLOG(P2P, TRACE, "GO's StaRec is NULL\n"); + /* Receive disconnection request during GC join. + * Abort GC join to prevent STA record leak. + */ + prJoinInfo = &(prP2pRoleFsmInfo->rJoinInfo); + if (prJoinInfo->prTargetStaRec) { + p2pFuncDisconnect(prAdapter, + prP2pBssInfo, + prJoinInfo->prTargetStaRec, + FALSE, + REASON_CODE_DEAUTH_LEAVING_BSS); + + p2pRoleFsmStateTransition(prAdapter, + prP2pRoleFsmInfo, + P2P_ROLE_STATE_IDLE); + } + break; + } + if (UNEQUAL_MAC_ADDR( + prP2pBssInfo->prStaRecOfAP->aucMacAddr, + prDisconnMsg->aucTargetID) && + UNEQUAL_MAC_ADDR(prDisconnMsg->aucTargetID, + aucBCBSSID)) { + DBGLOG(P2P, TRACE, + "Unequal MAC ADDR [" MACSTR ":" MACSTR "]\n", + MAC2STR( + prP2pBssInfo->prStaRecOfAP->aucMacAddr), + MAC2STR(prDisconnMsg->aucTargetID)); + break; + } + + prStaRec = prP2pBssInfo->prStaRecOfAP; + + /* Stop rejoin timer if it is started. */ + /* TODO: If it has. */ + + p2pFuncDisconnect(prAdapter, prP2pBssInfo, + prStaRec, + prDisconnMsg->fgSendDeauth, + prDisconnMsg->u2ReasonCode); + + cnmTimerStopTimer(prAdapter, + &(prStaRec->rDeauthTxDoneTimer)); + + cnmTimerInitTimer(prAdapter, + &(prStaRec->rDeauthTxDoneTimer), + (PFN_MGMT_TIMEOUT_FUNC) p2pRoleFsmDeauthTimeout, + (unsigned long) prStaRec); + + cnmTimerStartTimer(prAdapter, + &(prStaRec->rDeauthTxDoneTimer), + P2P_DEAUTH_TIMEOUT_TIME_MS); + + SET_NET_PWR_STATE_IDLE(prAdapter, + prP2pBssInfo->ucBssIndex); + + p2pRoleFsmStateTransition(prAdapter, + prP2pRoleFsmInfo, + P2P_ROLE_STATE_IDLE); + } + break; + case OP_MODE_ACCESS_POINT: + { + /* Search specific client device, and disconnect. */ + /* 1. Send deauthentication frame. */ + /* 2. Indication: Device disconnect. */ + struct STA_RECORD *prCurrStaRec = + (struct STA_RECORD *) NULL; + + DBGLOG(P2P, TRACE, + "Disconnecting with Target ID: " MACSTR "\n", + MAC2STR(prDisconnMsg->aucTargetID)); + + prCurrStaRec = bssGetClientByMac(prAdapter, + prP2pBssInfo, + prDisconnMsg->aucTargetID); + + if (prCurrStaRec) { + DBGLOG(P2P, TRACE, + "Disconnecting: " MACSTR "\n", + MAC2STR(prCurrStaRec->aucMacAddr)); + + /* Glue layer indication. */ + /* kalP2PGOStationUpdate(prAdapter->prGlueInfo, + * prCurrStaRec, FALSE); + */ + + /* Send deauth & do indication. */ + p2pFuncDisconnect(prAdapter, + prP2pBssInfo, + prCurrStaRec, + prDisconnMsg->fgSendDeauth, + prDisconnMsg->u2ReasonCode); + + cnmTimerStopTimer(prAdapter, + &(prCurrStaRec->rDeauthTxDoneTimer)); + + cnmTimerInitTimer(prAdapter, + &(prCurrStaRec->rDeauthTxDoneTimer), + (PFN_MGMT_TIMEOUT_FUNC) + p2pRoleFsmDeauthTimeout, + (unsigned long) prCurrStaRec); + + cnmTimerStartTimer(prAdapter, + &(prCurrStaRec->rDeauthTxDoneTimer), + P2P_DEAUTH_TIMEOUT_TIME_MS); + } +#if 0 + LINK_FOR_EACH(prLinkEntry, prStaRecOfClientList) { + prCurrStaRec = LINK_ENTRY(prLinkEntry, + struct STA_RECORD, rLinkEntry); + + ASSERT(prCurrStaRec); + + if (EQUAL_MAC_ADDR(prCurrStaRec->aucMacAddr, + prDisconnMsg->aucTargetID)) { + + DBGLOG(P2P, TRACE, + "Disconnecting: " MACSTR "\n", + MAC2STR( + prCurrStaRec->aucMacAddr)); + + /* Remove STA from client list. */ + LINK_REMOVE_KNOWN_ENTRY( + prStaRecOfClientList, + &prCurrStaRec->rLinkEntry); + + /* Glue layer indication. */ + /* kalP2PGOStationUpdate( + * prAdapter->prGlueInfo, + * prCurrStaRec, FALSE); + */ + + /* Send deauth & do indication. */ + p2pFuncDisconnect(prAdapter, + prP2pBssInfo, + prCurrStaRec, + prDisconnMsg->fgSendDeauth, + prDisconnMsg->u2ReasonCode); + + /* prTargetStaRec = prCurrStaRec; */ + + break; + } + } +#endif + + } + break; + case OP_MODE_P2P_DEVICE: + default: + ASSERT(FALSE); + break; + } + +error: + cnmMemFree(prAdapter, prMsgHdr); +} /* p2pRoleFsmRunEventConnectionAbort */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is called when JOIN complete message event + * is received from SAA. + * + * \param[in] prAdapter Pointer of ADAPTER_T + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void p2pRoleFsmRunEventJoinComplete(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *) NULL; + struct P2P_JOIN_INFO *prJoinInfo = + (struct P2P_JOIN_INFO *) NULL; + struct MSG_SAA_FSM_COMP *prJoinCompMsg = + (struct MSG_SAA_FSM_COMP *) NULL; + struct SW_RFB *prAssocRspSwRfb = (struct SW_RFB *) NULL; + struct STA_RECORD *prStaRec = (struct STA_RECORD *) NULL; + struct BSS_INFO *prP2pBssInfo = (struct BSS_INFO *) NULL; + + prJoinCompMsg = (struct MSG_SAA_FSM_COMP *) prMsgHdr; + prStaRec = prJoinCompMsg->prStaRec; + prAssocRspSwRfb = prJoinCompMsg->prSwRfb; + + ASSERT(prStaRec); + if (!prStaRec) { + DBGLOG(P2P, ERROR, "prJoinCompMsg->prStaRec is NULL!\n"); + goto error; + } + + DBGLOG(P2P, INFO, + "P2P BSS %d [" MACSTR "], Join Complete, status: %d\n", + prStaRec->ucBssIndex, + MAC2STR(prStaRec->aucMacAddr), + prJoinCompMsg->rJoinStatus); + + ASSERT(prStaRec->ucBssIndex < prAdapter->ucP2PDevBssIdx); + if (!(prStaRec->ucBssIndex < prAdapter->ucP2PDevBssIdx)) { + DBGLOG(P2P, ERROR, + "prStaRec->ucBssIndex %d should < prAdapter->ucP2PDevBssIdx(%d)!\n", + prStaRec->ucBssIndex, prAdapter->ucP2PDevBssIdx); + goto error; + } + + prP2pBssInfo = + GET_BSS_INFO_BY_INDEX(prAdapter, + prStaRec->ucBssIndex); + + if (prP2pBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) { + DBGLOG(P2P, ERROR, + "prP2pBssInfo->eCurrentOPMode %d != OP_MODE_INFRASTRUCTURE(%d)!\n", + prP2pBssInfo->eCurrentOPMode, + OP_MODE_INFRASTRUCTURE); + goto error; + } + + ASSERT(prP2pBssInfo->u4PrivateData < BSS_P2P_NUM); + if (!(prP2pBssInfo->u4PrivateData < BSS_P2P_NUM)) { + DBGLOG(P2P, ERROR, + "prP2pBssInfo->u4PrivateData %d should < BSS_P2P_NUM(%d)!\n", + prP2pBssInfo->u4PrivateData, + BSS_P2P_NUM); + goto error; + } + + prP2pRoleFsmInfo = + P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, + prP2pBssInfo->u4PrivateData); + + prJoinInfo = &(prP2pRoleFsmInfo->rJoinInfo); + + /* Check SEQ NUM */ + if (prJoinCompMsg->ucSeqNum == prJoinInfo->ucSeqNumOfReqMsg) { + ASSERT(prStaRec == prJoinInfo->prTargetStaRec); + prJoinInfo->fgIsJoinComplete = TRUE; + + if (prJoinCompMsg->rJoinStatus == WLAN_STATUS_SUCCESS) { + + /* 4 <1.1> Change FW's Media State immediately. */ + p2pChangeMediaState(prAdapter, + prP2pBssInfo, + MEDIA_STATE_CONNECTED); + + /* 4 <1.2> Deactivate previous AP's STA_RECORD_T + * in Driver if have. + */ + if ((prP2pBssInfo->prStaRecOfAP) + && (prP2pBssInfo->prStaRecOfAP != prStaRec)) { + cnmStaRecChangeState(prAdapter, + prP2pBssInfo->prStaRecOfAP, + STA_STATE_1); + + cnmStaRecFree(prAdapter, + prP2pBssInfo->prStaRecOfAP); + + prP2pBssInfo->prStaRecOfAP = NULL; + } + /* 4 <1.3> Update BSS_INFO_T */ + if (prAssocRspSwRfb) { + p2pFuncUpdateBssInfoForJOIN(prAdapter, + prJoinInfo->prTargetBssDesc, + prStaRec, prP2pBssInfo, prAssocRspSwRfb); + } else { + DBGLOG(P2P, INFO, + "prAssocRspSwRfb is NULL! Skip p2pFuncUpdateBssInfoForJOIN\n"); + } + + /* 4 <1.4> Activate current AP's STA_RECORD_T + * in Driver. + */ + cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); + +#if CFG_SUPPORT_P2P_RSSI_QUERY + /* <1.5> Update RSSI if necessary */ + nicUpdateRSSI(prAdapter, prP2pBssInfo->ucBssIndex, + (int8_t) (RCPI_TO_dBm(prStaRec->ucRCPI)), 0); +#endif + + /* 4 <1.6> Indicate Connected Event to + * Host immediately. + * Require BSSID, Association ID, Beacon Interval.. + * from AIS_BSS_INFO_T + * p2pIndicationOfMediaStateToHost(prAdapter, + * MEDIA_STATE_CONNECTED, + * prStaRec->aucMacAddr); + */ + if (prJoinInfo->prTargetBssDesc) + scanReportBss2Cfg80211(prAdapter, + BSS_TYPE_P2P_DEVICE, + prJoinInfo->prTargetBssDesc); +#if CFG_WPS_DISCONNECT || (KERNEL_VERSION(4, 4, 0) <= CFG80211_VERSION_CODE) + kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, + prP2pRoleFsmInfo->ucRoleIndex, + &prP2pRoleFsmInfo->rConnReqInfo, + prJoinInfo->aucIEBuf, + prJoinInfo->u4BufLength, + prStaRec->u2StatusCode, + WLAN_STATUS_MEDIA_DISCONNECT); +#else + kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, + prP2pRoleFsmInfo->ucRoleIndex, + &prP2pRoleFsmInfo->rConnReqInfo, + prJoinInfo->aucIEBuf, + prJoinInfo->u4BufLength, + prStaRec->u2StatusCode); + +#endif + + + + } else { + /* Join Fail */ + /* 4 <2.1> Redo JOIN process + * with other Auth Type if possible + */ + if (p2pFuncRetryJOIN(prAdapter, + prStaRec, prJoinInfo) == FALSE) { + + struct BSS_DESC *prBssDesc; + + prBssDesc = prJoinInfo->prTargetBssDesc; + + if (!prBssDesc) { + DBGLOG(P2P, WARN, + "prTargetBssDesc is NULL! Skip retry join\n"); + goto error; + } + + ASSERT(prBssDesc->fgIsConnecting); + prBssDesc->fgIsConnecting &= + ~BIT(prP2pBssInfo->ucBssIndex); + + /* Increase Failure Count */ + prStaRec->ucJoinFailureCount++; + + if (prStaRec->ucJoinFailureCount >= + P2P_SAA_RETRY_COUNT) { +#if CFG_WPS_DISCONNECT || (KERNEL_VERSION(4, 4, 0) <= CFG80211_VERSION_CODE) + kalP2PGCIndicateConnectionStatus( + prAdapter->prGlueInfo, + prP2pRoleFsmInfo->ucRoleIndex, + &prP2pRoleFsmInfo->rConnReqInfo, + prJoinInfo->aucIEBuf, + prJoinInfo->u4BufLength, + prStaRec->u2StatusCode, + WLAN_STATUS_MEDIA_DISCONNECT); +#else + kalP2PGCIndicateConnectionStatus( + prAdapter->prGlueInfo, + prP2pRoleFsmInfo->ucRoleIndex, + &prP2pRoleFsmInfo->rConnReqInfo, + prJoinInfo->aucIEBuf, + prJoinInfo->u4BufLength, + prStaRec->u2StatusCode); +#endif + } + + } + + } + } + + if (prP2pRoleFsmInfo->eCurrentState == P2P_ROLE_STATE_GC_JOIN) { + if (prP2pBssInfo->eConnectionState == + MEDIA_STATE_CONNECTED) { + /* do nothing & wait for timeout or EAPOL 4/4 TX done */ + } else { + struct BSS_DESC *prBssDesc; + struct P2P_SSID_STRUCT rSsid; + + prBssDesc = prJoinInfo->prTargetBssDesc; + + COPY_SSID(rSsid.aucSsid, + rSsid.ucSsidLen, + prBssDesc->aucSSID, + prBssDesc->ucSSIDLen); + p2pRoleFsmScanTargetBss(prAdapter, + prP2pRoleFsmInfo, + prBssDesc->ucChannelNum, + &rSsid); + } + } + +error: + if (prAssocRspSwRfb) + nicRxReturnRFB(prAdapter, prAssocRspSwRfb); + + cnmMemFree(prAdapter, prMsgHdr); +} /* p2pRoleFsmRunEventJoinComplete */ + +void p2pRoleFsmRunEventScanRequest(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct MSG_P2P_SCAN_REQUEST *prP2pScanReqMsg = + (struct MSG_P2P_SCAN_REQUEST *) NULL; + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *) NULL; + struct P2P_SCAN_REQ_INFO *prScanReqInfo = + (struct P2P_SCAN_REQ_INFO *) NULL; + uint32_t u4ChnlListSize = 0; + struct P2P_SSID_STRUCT *prP2pSsidStruct = + (struct P2P_SSID_STRUCT *) NULL; + struct BSS_INFO *prP2pBssInfo = NULL; + + + prP2pScanReqMsg = (struct MSG_P2P_SCAN_REQUEST *) prMsgHdr; + + prP2pBssInfo = prAdapter->aprBssInfo[prP2pScanReqMsg->ucBssIdx]; + + prP2pRoleFsmInfo = + P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, + prP2pBssInfo->u4PrivateData); + + if (!prP2pRoleFsmInfo) { + DBGLOG(P2P, ERROR, "prP2pRoleFsmInfo is NULL!"); + goto error; + } + + prP2pScanReqMsg = (struct MSG_P2P_SCAN_REQUEST *) prMsgHdr; + prScanReqInfo = &(prP2pRoleFsmInfo->rScanReqInfo); + + DBGLOG(P2P, TRACE, "p2pDevFsmRunEventScanRequest\n"); + + /* Do we need to be in IDLE state? */ + /* p2pDevFsmRunEventAbort(prAdapter, prP2pDevFsmInfo); */ + + ASSERT(prScanReqInfo->fgIsScanRequest == FALSE); + + prScanReqInfo->fgIsAbort = TRUE; + prScanReqInfo->eScanType = prP2pScanReqMsg->eScanType; + + if (prP2pScanReqMsg->u4NumChannel) { + prScanReqInfo->eChannelSet = SCAN_CHANNEL_SPECIFIED; + + /* Channel List */ + prScanReqInfo->ucNumChannelList = prP2pScanReqMsg->u4NumChannel; + DBGLOG(P2P, TRACE, + "Scan Request Channel List Number: %d\n", + prScanReqInfo->ucNumChannelList); + if (prScanReqInfo->ucNumChannelList + > MAXIMUM_OPERATION_CHANNEL_LIST) { + DBGLOG(P2P, TRACE, + "Channel List Number Overloaded: %d, change to: %d\n", + prScanReqInfo->ucNumChannelList, + MAXIMUM_OPERATION_CHANNEL_LIST); + prScanReqInfo->ucNumChannelList = + MAXIMUM_OPERATION_CHANNEL_LIST; + } + + u4ChnlListSize = + sizeof(struct RF_CHANNEL_INFO) + * prScanReqInfo->ucNumChannelList; + kalMemCopy(prScanReqInfo->arScanChannelList, + prP2pScanReqMsg->arChannelListInfo, u4ChnlListSize); + } else { + /* If channel number is ZERO. + * It means do a FULL channel scan. + */ + prScanReqInfo->eChannelSet = SCAN_CHANNEL_FULL; + } + + /* SSID */ + prP2pSsidStruct = prP2pScanReqMsg->prSSID; + for (prScanReqInfo->ucSsidNum = 0; + prScanReqInfo->ucSsidNum < prP2pScanReqMsg->i4SsidNum; + prScanReqInfo->ucSsidNum++) { + + kalMemCopy( + prScanReqInfo->arSsidStruct[prScanReqInfo->ucSsidNum] + .aucSsid, + prP2pSsidStruct->aucSsid, prP2pSsidStruct->ucSsidLen); + + prScanReqInfo->arSsidStruct[prScanReqInfo->ucSsidNum] + .ucSsidLen = + prP2pSsidStruct->ucSsidLen; + + prP2pSsidStruct++; + } + + /* IE Buffer */ + kalMemCopy(prScanReqInfo->aucIEBuf, + prP2pScanReqMsg->pucIEBuf, + prP2pScanReqMsg->u4IELen); + + prScanReqInfo->u4BufLength = prP2pScanReqMsg->u4IELen; + prScanReqInfo->eScanReason = prP2pScanReqMsg->eScanReason; + + p2pRoleFsmStateTransition(prAdapter, + prP2pRoleFsmInfo, + P2P_ROLE_STATE_SCAN); + +error: + cnmMemFree(prAdapter, prMsgHdr); +} /* p2pDevFsmRunEventScanRequest */ + +void +p2pRoleFsmRunEventScanDone(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr, + IN struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo) +{ + struct MSG_SCN_SCAN_DONE *prScanDoneMsg = + (struct MSG_SCN_SCAN_DONE *) prMsgHdr; + struct P2P_SCAN_REQ_INFO *prScanReqInfo = + (struct P2P_SCAN_REQ_INFO *) NULL; + enum ENUM_P2P_ROLE_STATE eNextState = P2P_ROLE_STATE_NUM; + struct P2P_CONNECTION_REQ_INFO *prConnReqInfo = + &(prP2pRoleFsmInfo->rConnReqInfo); + struct P2P_JOIN_INFO *prP2pJoinInfo = + &(prP2pRoleFsmInfo->rJoinInfo); + struct BSS_INFO *prP2pBssInfo = (struct BSS_INFO *) NULL; + struct P2P_CHNL_REQ_INFO *prChnlReqInfo = + (struct P2P_CHNL_REQ_INFO *) NULL; + struct P2P_SCAN_REQ_INFO *prScanInfo; + + if (!prP2pRoleFsmInfo) { + DBGLOG(P2P, TRACE, "prP2pRoleFsmInfo is NULL\n"); + goto error; + } + + DBGLOG(P2P, TRACE, "P2P Role Scan Done Event\n"); + + prScanReqInfo = &(prP2pRoleFsmInfo->rScanReqInfo); + prScanDoneMsg = (struct MSG_SCN_SCAN_DONE *) prMsgHdr; + prScanInfo = &prP2pRoleFsmInfo->rScanReqInfo; + + if (prScanDoneMsg->ucSeqNum != prScanReqInfo->ucSeqNumOfScnMsg) { + /* Scan Done message sequence number mismatch. + * Ignore this event. (P2P FSM issue two scan events.) + */ + /* The scan request has been cancelled. + * Ignore this message. It is possible. + */ + DBGLOG(P2P, TRACE, + "P2P Role Scan Don SeqNum Received:%d <-> P2P Role Fsm SCAN Seq Issued:%d\n", + prScanDoneMsg->ucSeqNum, + prScanReqInfo->ucSeqNumOfScnMsg); + + goto error; + } + + switch (prP2pRoleFsmInfo->eCurrentState) { + case P2P_ROLE_STATE_SCAN: + prScanReqInfo->fgIsAbort = FALSE; + + if (prConnReqInfo->eConnRequest == P2P_CONNECTION_TYPE_GC) { + + prP2pJoinInfo->prTargetBssDesc = + p2pFuncKeepOnConnection(prAdapter, + prAdapter->aprBssInfo + [prP2pRoleFsmInfo->ucBssIndex], + prConnReqInfo, + &prP2pRoleFsmInfo->rChnlReqInfo, + &prP2pRoleFsmInfo->rScanReqInfo); + if ((prP2pJoinInfo->prTargetBssDesc) == NULL) { + eNextState = P2P_ROLE_STATE_SCAN; + } else { + prP2pBssInfo = + prAdapter->aprBssInfo + [prP2pRoleFsmInfo->ucBssIndex]; + if (!prP2pBssInfo) + break; + prChnlReqInfo = + &(prP2pRoleFsmInfo->rChnlReqInfo); + if (!prChnlReqInfo) + break; + + prP2pBssInfo->eBand = prChnlReqInfo->eBand; + if (prP2pBssInfo->fgIsWmmInited == FALSE) + prP2pBssInfo->ucWmmQueSet = + cnmWmmIndexDecision(prAdapter, + prP2pBssInfo); +#if CFG_SUPPORT_DBDC + /* DBDC decsion.may change OpNss */ + cnmDbdcPreConnectionEnableDecision(prAdapter, + prP2pRoleFsmInfo->ucBssIndex, + prChnlReqInfo->eBand, + prChnlReqInfo->ucReqChnlNum, + prP2pBssInfo->ucWmmQueSet); +#endif /* CFG_SUPPORT_DBDC */ + + cnmOpModeGetTRxNss( + prAdapter, prP2pRoleFsmInfo->ucBssIndex, + &prP2pBssInfo->ucOpRxNss, + &prP2pBssInfo->ucOpTxNss); + + DBGLOG(P2P, INFO, + "p2pRoleFsmRunEventScanDone: start GC CH[%u]RxNSS[%u]TxNss[%u]\n", + prChnlReqInfo->ucReqChnlNum, + prP2pBssInfo->ucOpRxNss, + prP2pBssInfo->ucOpTxNss); + + /* For GC join. */ + eNextState = P2P_ROLE_STATE_REQING_CHANNEL; + } + } else if (prScanInfo->eScanReason == SCAN_REASON_ACS) { + struct P2P_ACS_REQ_INFO *prAcsReqInfo; + + prAcsReqInfo = &prP2pRoleFsmInfo->rAcsReqInfo; + prScanInfo->eScanReason = SCAN_REASON_UNKNOWN; + p2pFunCalAcsChnScores(prAdapter); + if (wlanQueryLteSafeChannel(prAdapter, + prP2pRoleFsmInfo->ucRoleIndex) == + WLAN_STATUS_SUCCESS) { + /* do nothing & wait for FW event */ + } else { + DBGLOG(P2P, WARN, "query safe chn fail.\n"); + p2pFunProcessAcsReport(prAdapter, + prP2pRoleFsmInfo->ucRoleIndex, + NULL, + prAcsReqInfo); + } + eNextState = P2P_ROLE_STATE_IDLE; + } else { + eNextState = P2P_ROLE_STATE_IDLE; + } + break; + case P2P_ROLE_STATE_AP_CHNL_DETECTION: + eNextState = P2P_ROLE_STATE_REQING_CHANNEL; + break; + default: + /* Unexpected channel scan done event + * without being chanceled. + */ + ASSERT(FALSE); + break; + } + + prScanReqInfo->fgIsScanRequest = FALSE; + + p2pRoleFsmStateTransition(prAdapter, prP2pRoleFsmInfo, eNextState); + +error: + cnmMemFree(prAdapter, prMsgHdr); + +} /* p2pRoleFsmRunEventScanDone */ + +void +p2pRoleFsmRunEventChnlGrant(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr, + IN struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo) +{ + struct P2P_CHNL_REQ_INFO *prChnlReqInfo = + (struct P2P_CHNL_REQ_INFO *) NULL; + struct MSG_CH_GRANT *prMsgChGrant = (struct MSG_CH_GRANT *) NULL; +#if (CFG_SUPPORT_DFS_MASTER == 1) + struct BSS_INFO *prP2pBssInfo = (struct BSS_INFO *) NULL; + uint32_t u4CacTimeMs; +#endif + uint8_t ucTokenID = 0; + + + if (!prP2pRoleFsmInfo) { + DBGLOG(P2P, ERROR, "prP2pRoleFsmInfo is NULL!\n"); + goto error; + } + + DBGLOG(P2P, TRACE, "P2P Run Event Role Channel Grant\n"); + + prMsgChGrant = (struct MSG_CH_GRANT *) prMsgHdr; + ucTokenID = prMsgChGrant->ucTokenID; + prChnlReqInfo = &(prP2pRoleFsmInfo->rChnlReqInfo); + +#if (CFG_SUPPORT_DFS_MASTER == 1) + prP2pBssInfo = + GET_BSS_INFO_BY_INDEX(prAdapter, + prMsgChGrant->ucBssIndex); +#endif + if (prChnlReqInfo->u4MaxInterval != prMsgChGrant->u4GrantInterval) { + DBGLOG(P2P, WARN, + "P2P Role:%d Request Channel Interval:%d, Grant Interval:%d\n", + prP2pRoleFsmInfo->ucRoleIndex, + prChnlReqInfo->u4MaxInterval, + prMsgChGrant->u4GrantInterval); + prChnlReqInfo->u4MaxInterval = prMsgChGrant->u4GrantInterval; + } + + if (ucTokenID == prChnlReqInfo->ucSeqNumOfChReq) { + enum ENUM_P2P_ROLE_STATE eNextState = P2P_ROLE_STATE_NUM; + + switch (prP2pRoleFsmInfo->eCurrentState) { + case P2P_ROLE_STATE_REQING_CHANNEL: + switch (prChnlReqInfo->eChnlReqType) { + case CH_REQ_TYPE_JOIN: + eNextState = P2P_ROLE_STATE_GC_JOIN; + break; + case CH_REQ_TYPE_GO_START_BSS: + eNextState = P2P_ROLE_STATE_IDLE; + break; + case CH_REQ_TYPE_OFFCHNL_TX: + eNextState = P2P_ROLE_STATE_OFF_CHNL_TX; + break; + default: + DBGLOG(P2P, WARN, + "p2pRoleFsmRunEventChnlGrant: Invalid Channel Request Type:%d\n", + prChnlReqInfo->eChnlReqType); + GL_RESET_TRIGGER(prAdapter, + RST_FLAG_CHIP_RESET); + break; + } + + p2pRoleFsmStateTransition(prAdapter, + prP2pRoleFsmInfo, eNextState); + break; + +#if (CFG_SUPPORT_DFS_MASTER == 1) + case P2P_ROLE_STATE_DFS_CAC: + p2pFuncStartRdd(prAdapter, prMsgChGrant->ucBssIndex); + + if (p2pFuncCheckWeatherRadarBand(prChnlReqInfo)) + u4CacTimeMs = + P2P_AP_CAC_WEATHER_CHNL_HOLD_TIME_MS; + else + u4CacTimeMs = + prP2pRoleFsmInfo->rChnlReqInfo + .u4MaxInterval; + + if (p2pFuncIsManualCac()) + u4CacTimeMs = p2pFuncGetDriverCacTime() * 1000; + else + p2pFuncSetDriverCacTime(u4CacTimeMs/1000); + + cnmTimerStartTimer(prAdapter, + &(prP2pRoleFsmInfo->rP2pRoleFsmTimeoutTimer), + u4CacTimeMs); + + p2pFuncRecordCacStartBootTime(); + + p2pFuncSetDfsState(DFS_STATE_CHECKING); + + DBGLOG(P2P, INFO, + "p2pRoleFsmRunEventChnlGrant: CAC time = %ds\n", + u4CacTimeMs/1000); + break; + case P2P_ROLE_STATE_SWITCH_CHANNEL: + p2pFuncDfsSwitchCh(prAdapter, + prP2pBssInfo, + prP2pRoleFsmInfo->rChnlReqInfo); + p2pRoleFsmStateTransition(prAdapter, + prP2pRoleFsmInfo, + P2P_ROLE_STATE_IDLE); + break; +#endif + case P2P_ROLE_STATE_OFF_CHNL_TX: + if (prMsgChGrant->eReqType == CH_REQ_TYPE_OFFCHNL_TX) { + p2pRoleFsmStateTransition(prAdapter, + prP2pRoleFsmInfo, + P2P_ROLE_STATE_OFF_CHNL_TX); + } else { + p2pRoleFsmStateTransition(prAdapter, + prP2pRoleFsmInfo, + P2P_ROLE_STATE_IDLE); + } + break; + default: + /* Channel is granted under unexpected state. + * Driver should cancel channel privileagea + * before leaving the states. + */ + if (IS_BSS_ACTIVE( + prAdapter->aprBssInfo + [prP2pRoleFsmInfo->ucBssIndex])) { + DBGLOG(P2P, WARN, + "p2pRoleFsmRunEventChnlGrant: Invalid CurrentState:%d\n", + prP2pRoleFsmInfo->eCurrentState); + GL_RESET_TRIGGER(prAdapter, + RST_FLAG_CHIP_RESET); + } + break; + } + } else { + DBGLOG(P2P, ERROR, + "p2pRoleFsmRunEventChnlGrant: Token mismatch, Chreq: %d, ChGrant: %d\n", + prChnlReqInfo->ucSeqNumOfChReq, ucTokenID); + } + +error: + cnmMemFree(prAdapter, prMsgHdr); +} /* p2pRoleFsmRunEventChnlGrant */ + +/* ////////////////////////////////////// */ +void p2pRoleFsmRunEventDissolve(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + /* TODO: */ + + if (prMsgHdr) + cnmMemFree(prAdapter, prMsgHdr); +} /* p2pRoleFsmRunEventDissolve */ + +/*----------------------------------------------------------------------------*/ +/*! + * @ This routine update the current MAC table based on the current ACL. + * If ACL change causing an associated STA become un-authorized. This STA + * will be kicked out immediately. + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] ucBssIdx Bss index. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void p2pRoleUpdateACLEntry(IN struct ADAPTER *prAdapter, IN uint8_t ucBssIdx) +{ + u_int8_t bMatchACL = FALSE; + int32_t i = 0; + struct LINK *prClientList; + struct STA_RECORD *prCurrStaRec, *prNextStaRec; + struct BSS_INFO *prP2pBssInfo; + + ASSERT(prAdapter); + + if ((!prAdapter) || (ucBssIdx > prAdapter->ucHwBssIdNum)) + return; + + DBGLOG(P2P, TRACE, "Update ACL Entry ucBssIdx = %d\n", ucBssIdx); + prP2pBssInfo = prAdapter->aprBssInfo[ucBssIdx]; + + /* ACL is disabled. Do nothing about the MAC table. */ + if (prP2pBssInfo->rACL.ePolicy == PARAM_CUSTOM_ACL_POLICY_DISABLE) + return; + + prClientList = &prP2pBssInfo->rStaRecOfClientList; + + LINK_FOR_EACH_ENTRY_SAFE(prCurrStaRec, + prNextStaRec, prClientList, rLinkEntry, struct STA_RECORD) { + if (!prCurrStaRec) + break; + bMatchACL = FALSE; + for (i = 0; i < prP2pBssInfo->rACL.u4Num; i++) { + if (EQUAL_MAC_ADDR(prCurrStaRec->aucMacAddr, + prP2pBssInfo->rACL.rEntry[i].aucAddr)) { + bMatchACL = TRUE; + break; + } + } + + if (((!bMatchACL) && + (prP2pBssInfo->rACL.ePolicy + == PARAM_CUSTOM_ACL_POLICY_ACCEPT)) + || ((bMatchACL) && + (prP2pBssInfo->rACL.ePolicy + == PARAM_CUSTOM_ACL_POLICY_DENY))) { + struct MSG_P2P_CONNECTION_ABORT *prDisconnectMsg = + (struct MSG_P2P_CONNECTION_ABORT *) NULL; + + DBGLOG(P2P, TRACE, + "ucBssIdx=%d, ACL Policy=%d\n", + ucBssIdx, prP2pBssInfo->rACL.ePolicy); + + prDisconnectMsg = + (struct MSG_P2P_CONNECTION_ABORT *) + cnmMemAlloc(prAdapter, RAM_TYPE_MSG, + sizeof(struct MSG_P2P_CONNECTION_ABORT)); + if (prDisconnectMsg == NULL) + return; + prDisconnectMsg->rMsgHdr.eMsgId + = MID_MNY_P2P_CONNECTION_ABORT; + prDisconnectMsg->ucRoleIdx + = (uint8_t) prP2pBssInfo->u4PrivateData; + COPY_MAC_ADDR(prDisconnectMsg->aucTargetID, + prCurrStaRec->aucMacAddr); + prDisconnectMsg->u2ReasonCode + = STATUS_CODE_REQ_DECLINED; + prDisconnectMsg->fgSendDeauth = TRUE; + mboxSendMsg(prAdapter, + MBOX_ID_0, + (struct MSG_HDR *) prDisconnectMsg, + MSG_SEND_METHOD_BUF); + } + } +} /* p2pRoleUpdateACLEntry */ + +/*----------------------------------------------------------------------------*/ +/*! + * @ Check if the specified STA pass the Access Control List inspection. + * If fails to pass the checking, + * then no authentication or association is allowed. + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] pMacAddr Pointer to the mac address. + * @param[in] ucBssIdx Bss index. + * + * @return TRUE - pass ACL inspection, FALSE - ACL inspection fail + */ +/*----------------------------------------------------------------------------*/ +u_int8_t p2pRoleProcessACLInspection(IN struct ADAPTER *prAdapter, + IN uint8_t *pMacAddr, + IN uint8_t ucBssIdx) +{ + u_int8_t bPassACL = TRUE; + int32_t i = 0; + struct BSS_INFO *prP2pBssInfo; + + ASSERT(prAdapter); + + if ((!prAdapter) || (!pMacAddr) || (ucBssIdx > prAdapter->ucHwBssIdNum)) + return FALSE; + + prP2pBssInfo = prAdapter->aprBssInfo[ucBssIdx]; + + if (prP2pBssInfo->rACL.ePolicy == PARAM_CUSTOM_ACL_POLICY_DISABLE) + return TRUE; + + if (prP2pBssInfo->rACL.ePolicy == PARAM_CUSTOM_ACL_POLICY_ACCEPT) + bPassACL = FALSE; + else + bPassACL = TRUE; + + for (i = 0; i < prP2pBssInfo->rACL.u4Num; i++) { + if (EQUAL_MAC_ADDR(pMacAddr, + prP2pBssInfo->rACL.rEntry[i].aucAddr)) { + bPassACL = !bPassACL; + break; + } + } + + if (bPassACL == FALSE) + DBGLOG(P2P, WARN, + "this mac [" MACSTR "] is fail to pass ACL inspection.\n", + MAC2STR(pMacAddr)); + + return bPassACL; +} /* p2pRoleProcessACLInspection */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will indicate the Event + * of Successful Completion of AAA Module. + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] prStaRec Pointer to the STA_RECORD_T + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +uint32_t +p2pRoleFsmRunEventAAAComplete(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, + IN struct BSS_INFO *prP2pBssInfo) +{ + uint32_t rStatus = WLAN_STATUS_SUCCESS; + enum ENUM_PARAM_MEDIA_STATE eOriMediaState; + + do { + ASSERT_BREAK((prAdapter != NULL) + && (prStaRec != NULL) && (prP2pBssInfo != NULL)); + + eOriMediaState = prP2pBssInfo->eConnectionState; + + bssRemoveClient(prAdapter, prP2pBssInfo, prStaRec); + + if (prP2pBssInfo->rStaRecOfClientList.u4NumElem + >= P2P_MAXIMUM_CLIENT_COUNT + || !p2pRoleProcessACLInspection(prAdapter, + prStaRec->aucMacAddr, + prP2pBssInfo->ucBssIndex) +#if CFG_SUPPORT_HOTSPOT_WPS_MANAGER + || kalP2PMaxClients(prAdapter->prGlueInfo, + prP2pBssInfo->rStaRecOfClientList.u4NumElem, + (uint8_t) prP2pBssInfo->u4PrivateData) +#endif + ) { + rStatus = WLAN_STATUS_RESOURCES; + break; + } + + bssAddClient(prAdapter, prP2pBssInfo, prStaRec); + + prStaRec->u2AssocId = bssAssignAssocID(prStaRec); + + cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); + + p2pChangeMediaState(prAdapter, + prP2pBssInfo, + MEDIA_STATE_CONNECTED); + + /* Update Connected state to FW. */ + if (eOriMediaState != prP2pBssInfo->eConnectionState) + nicUpdateBss(prAdapter, prP2pBssInfo->ucBssIndex); + + } while (FALSE); + + return rStatus; +} /* p2pRunEventAAAComplete */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will indicate the Event + * of Successful Completion of AAA Module. + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] prStaRec Pointer to the STA_RECORD_T + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +uint32_t +p2pRoleFsmRunEventAAASuccess(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, + IN struct BSS_INFO *prP2pBssInfo) +{ + uint32_t rStatus = WLAN_STATUS_SUCCESS; + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *) NULL; + + do { + ASSERT_BREAK((prAdapter != NULL) + && (prStaRec != NULL) && (prP2pBssInfo != NULL)); + + if ((prP2pBssInfo->eNetworkType != NETWORK_TYPE_P2P) + || (prP2pBssInfo->u4PrivateData >= BSS_P2P_NUM)) { + ASSERT(FALSE); + rStatus = WLAN_STATUS_INVALID_DATA; + break; + } + + ASSERT(prP2pBssInfo->ucBssIndex < prAdapter->ucP2PDevBssIdx); + + prP2pRoleFsmInfo = + P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, + prP2pBssInfo->u4PrivateData); + + /* Glue layer indication. */ + kalP2PGOStationUpdate(prAdapter->prGlueInfo, + prP2pRoleFsmInfo->ucRoleIndex, prStaRec, TRUE); + + } while (FALSE); + + return rStatus; +} /* p2pRoleFsmRunEventAAASuccess */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will indicate the Event + * of Tx Fail of AAA Module. + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] prStaRec Pointer to the STA_RECORD_T + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void p2pRoleFsmRunEventAAATxFail(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, + IN struct BSS_INFO *prP2pBssInfo) +{ + ASSERT(prAdapter); + ASSERT(prStaRec); + + bssRemoveClient(prAdapter, prP2pBssInfo, prStaRec); + + p2pFuncDisconnect(prAdapter, + prP2pBssInfo, prStaRec, FALSE, + prStaRec->eAuthAssocState == AAA_STATE_SEND_AUTH2 + ? STATUS_CODE_AUTH_TIMEOUT + : STATUS_CODE_ASSOC_TIMEOUT); + + /* 20120830 moved into p2puUncDisconnect. */ + /* cnmStaRecFree(prAdapter, prStaRec); */ +} /* p2pRoleFsmRunEventAAATxFail */ + +void p2pRoleFsmRunEventSwitchOPMode(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct BSS_INFO *prP2pBssInfo = (struct BSS_INFO *) NULL; + struct MSG_P2P_SWITCH_OP_MODE *prSwitchOpMode = + (struct MSG_P2P_SWITCH_OP_MODE *) prMsgHdr; + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *) NULL; + struct P2P_CONNECTION_REQ_INFO *prConnReqInfo = + (struct P2P_CONNECTION_REQ_INFO *) NULL; + + ASSERT(prSwitchOpMode->ucRoleIdx < BSS_P2P_NUM); + if (!(prSwitchOpMode->ucRoleIdx < BSS_P2P_NUM)) { + DBGLOG(P2P, ERROR, + "prSwitchOpMode->ucRoleIdx %d should < BSS_P2P_NUM(%d)\n", + prSwitchOpMode->ucRoleIdx, BSS_P2P_NUM); + goto error; + } + + prP2pRoleFsmInfo = + prAdapter->rWifiVar + .aprP2pRoleFsmInfo[prSwitchOpMode->ucRoleIdx]; + prConnReqInfo = &(prP2pRoleFsmInfo->rConnReqInfo); + + ASSERT(prP2pRoleFsmInfo->ucBssIndex < prAdapter->ucP2PDevBssIdx); + if (!(prP2pRoleFsmInfo->ucBssIndex < prAdapter->ucP2PDevBssIdx)) { + DBGLOG(P2P, ERROR, + "prP2pRoleFsmInfo->ucBssIndex %d should < prAdapter->ucP2PDevBssIdx(%d)\n", + prP2pRoleFsmInfo->ucBssIndex, + prAdapter->ucP2PDevBssIdx); + goto error; + } + + prP2pBssInfo = + GET_BSS_INFO_BY_INDEX(prAdapter, + prP2pRoleFsmInfo->ucBssIndex); + + if (!(prSwitchOpMode->eOpMode < OP_MODE_NUM)) { + DBGLOG(P2P, ERROR, + "prSwitchOpMode->eOpMode %d should < OP_MODE_NUM(%d)\n", + prSwitchOpMode->eOpMode, OP_MODE_NUM); + goto error; + } + + /* P2P Device / GC. */ + p2pFuncSwitchOPMode(prAdapter, + prP2pBssInfo, + prSwitchOpMode->eOpMode, + TRUE); + + if (prP2pBssInfo->eIftype == IFTYPE_P2P_CLIENT && + prSwitchOpMode->eIftype == IFTYPE_STATION) { + kalP2pUnlinkBss(prAdapter->prGlueInfo, prConnReqInfo->aucBssid); + } + prP2pBssInfo->eIftype = prSwitchOpMode->eIftype; + +error: + cnmMemFree(prAdapter, prMsgHdr); +} /* p2pRoleFsmRunEventSwitchOPMode */ + +/* /////////////////////////////// TO BE REFINE //////////////////////////// */ + +void p2pRoleFsmRunEventBeaconUpdate(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct P2P_ROLE_FSM_INFO *prRoleP2pFsmInfo = + (struct P2P_ROLE_FSM_INFO *) NULL; + struct BSS_INFO *prP2pBssInfo = (struct BSS_INFO *) NULL; + struct MSG_P2P_BEACON_UPDATE *prBcnUpdateMsg = + (struct MSG_P2P_BEACON_UPDATE *) NULL; + struct P2P_BEACON_UPDATE_INFO *prBcnUpdateInfo = + (struct P2P_BEACON_UPDATE_INFO *) NULL; + + + DBGLOG(P2P, TRACE, "p2pRoleFsmRunEventBeaconUpdate\n"); + + prBcnUpdateMsg = (struct MSG_P2P_BEACON_UPDATE *) prMsgHdr; + if (prBcnUpdateMsg->ucRoleIndex >= BSS_P2P_NUM) + goto error; + + prRoleP2pFsmInfo = + P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, + prBcnUpdateMsg->ucRoleIndex); + if (!prRoleP2pFsmInfo) + goto error; + + prP2pBssInfo = + GET_BSS_INFO_BY_INDEX(prAdapter, + prRoleP2pFsmInfo->ucBssIndex); + + prP2pBssInfo->fgIsWepCipherGroup = prBcnUpdateMsg->fgIsWepCipher; + + prBcnUpdateInfo = &(prRoleP2pFsmInfo->rBeaconUpdateInfo); + + DBGLOG(P2P, TRACE, "Dump beacon content from supplicant.\n"); + if (aucDebugModule[DBG_P2P_IDX] & DBG_CLASS_TRACE) { + dumpMemory8((uint8_t *) prBcnUpdateMsg->pucBcnBody, + (uint32_t) prBcnUpdateMsg->u4BcnBodyLen); + } + + p2pFuncBeaconUpdate(prAdapter, + prP2pBssInfo, + prBcnUpdateInfo, + prBcnUpdateMsg->pucBcnHdr, + prBcnUpdateMsg->u4BcnHdrLen, + prBcnUpdateMsg->pucBcnBody, + prBcnUpdateMsg->u4BcnBodyLen); + + if (prBcnUpdateMsg->pucAssocRespIE != NULL + && prBcnUpdateMsg->u4AssocRespLen > 0) { + DBGLOG(P2P, TRACE, + "Copy extra IEs for assoc resp (Length= %d)\n", + prBcnUpdateMsg->u4AssocRespLen); + DBGLOG_MEM8(P2P, TRACE, + prBcnUpdateMsg->pucAssocRespIE, + prBcnUpdateMsg->u4AssocRespLen); + + if (p2pFuncAssocRespUpdate(prAdapter, + prP2pBssInfo, + prBcnUpdateMsg->pucAssocRespIE, + prBcnUpdateMsg->u4AssocRespLen) == WLAN_STATUS_FAILURE) + DBGLOG(P2P, ERROR, + "Update extra IEs for asso resp fail!\n"); + } + + + if ((prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) && + (prP2pBssInfo->eIntendOPMode == OP_MODE_NUM)) { + /* AP is created, Beacon Update. */ + /* nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_P2P_INDEX); */ + + + DBGLOG(P2P, TRACE, + "p2pRoleFsmRunEventBeaconUpdate with Bssidex(%d)\n", + prRoleP2pFsmInfo->ucBssIndex); + + bssUpdateBeaconContent(prAdapter, prRoleP2pFsmInfo->ucBssIndex); + +#if CFG_SUPPORT_P2P_GO_OFFLOAD_PROBE_RSP + if (p2pFuncProbeRespUpdate(prAdapter, + prP2pBssInfo, + prBcnUpdateMsg->pucProbeRespIE, + prBcnUpdateMsg->u4ProbeRespLen) == WLAN_STATUS_FAILURE) + DBGLOG(P2P, ERROR, + "Update extra IEs for probe resp fail!\n"); +#endif + /* nicPmIndicateBssCreated(prAdapter, + * NETWORK_TYPE_P2P_INDEX); + */ + } +error: + cnmMemFree(prAdapter, prMsgHdr); + +} /* p2pRoleFsmRunEventBeaconUpdate */ + +void +p2pProcessEvent_UpdateNOAParam(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIdx, + IN struct EVENT_UPDATE_NOA_PARAMS *prEventUpdateNoaParam) +{ + struct BSS_INFO *prBssInfo = (struct BSS_INFO *) NULL; + struct P2P_SPECIFIC_BSS_INFO *prP2pSpecificBssInfo; + uint32_t i; + u_int8_t fgNoaAttrExisted = FALSE; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIdx); + prP2pSpecificBssInfo = + prAdapter->rWifiVar + .prP2pSpecificBssInfo[prBssInfo->u4PrivateData]; + + prP2pSpecificBssInfo->fgEnableOppPS = + prEventUpdateNoaParam->ucEnableOppPS; + prP2pSpecificBssInfo->u2CTWindow = prEventUpdateNoaParam->u2CTWindow; + prP2pSpecificBssInfo->ucNoAIndex = prEventUpdateNoaParam->ucNoAIndex; + prP2pSpecificBssInfo->ucNoATimingCount = + prEventUpdateNoaParam->ucNoATimingCount; + + fgNoaAttrExisted |= prP2pSpecificBssInfo->fgEnableOppPS; + + ASSERT(prP2pSpecificBssInfo->ucNoATimingCount <= P2P_MAXIMUM_NOA_COUNT); + + for (i = 0; i < prP2pSpecificBssInfo->ucNoATimingCount; i++) { + /* in used */ + prP2pSpecificBssInfo->arNoATiming[i].fgIsInUse = + prEventUpdateNoaParam->arEventNoaTiming[i].ucIsInUse; + /* count */ + prP2pSpecificBssInfo->arNoATiming[i].ucCount = + prEventUpdateNoaParam->arEventNoaTiming[i].ucCount; + /* duration */ + prP2pSpecificBssInfo->arNoATiming[i].u4Duration = + prEventUpdateNoaParam->arEventNoaTiming[i].u4Duration; + /* interval */ + prP2pSpecificBssInfo->arNoATiming[i].u4Interval = + prEventUpdateNoaParam->arEventNoaTiming[i].u4Interval; + /* start time */ + prP2pSpecificBssInfo->arNoATiming[i].u4StartTime = + prEventUpdateNoaParam->arEventNoaTiming[i].u4StartTime; + + fgNoaAttrExisted |= + prP2pSpecificBssInfo->arNoATiming[i].fgIsInUse; + } + + prP2pSpecificBssInfo->fgIsNoaAttrExisted = fgNoaAttrExisted; + + DBGLOG(P2P, INFO, "Update NoA param, count=%d, ucBssIdx=%d\n", + prEventUpdateNoaParam->ucNoATimingCount, + ucBssIdx); + + /* update beacon content by the change */ + bssUpdateBeaconContent(prAdapter, ucBssIdx); +} /* p2pProcessEvent_UpdateNOAParam */ + +#if CFG_ENABLE_PER_STA_STATISTICS_LOG +void +p2pRoleFsmGetStaStatistics(IN struct ADAPTER *prAdapter, + IN unsigned long ulParamPtr) +{ + uint32_t u4BufLen; + struct PARAM_GET_STA_STATISTICS *prQueryStaStatistics; + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *) ulParamPtr; + struct BSS_INFO *prP2pBssInfo = (struct BSS_INFO *) NULL; + + if ((!prAdapter) || (!prP2pRoleFsmInfo)) { + DBGLOG(P2P, ERROR, "prAdapter=NULL || prP2pRoleFsmInfo=NULL\n"); + return; + } + + prP2pBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prP2pRoleFsmInfo->ucBssIndex); + if (!prP2pBssInfo) { + DBGLOG(P2P, ERROR, "prP2pBssInfo=NULL\n"); + return; + } + + prQueryStaStatistics = + prAdapter->rWifiVar.prP2pQueryStaStatistics + [prP2pRoleFsmInfo->ucRoleIndex]; + if (!prQueryStaStatistics) { + DBGLOG(P2P, ERROR, "prQueryStaStatistics=NULL\n"); + return; + } + + if (prP2pBssInfo->eConnectionState == MEDIA_STATE_CONNECTED) { + if ((prP2pBssInfo->eCurrentOPMode + != OP_MODE_INFRASTRUCTURE) && + (prP2pBssInfo->eCurrentOPMode + != OP_MODE_ACCESS_POINT)) { + DBGLOG(P2P, ERROR, "Invalid OPMode=%d\n", + prP2pBssInfo->eCurrentOPMode); + return; + } + if (prP2pBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE + && prP2pBssInfo->prStaRecOfAP) { + COPY_MAC_ADDR( + prQueryStaStatistics->aucMacAddr, + prP2pBssInfo->prStaRecOfAP->aucMacAddr); + } else if (prP2pBssInfo->eCurrentOPMode + == OP_MODE_ACCESS_POINT) { + struct STA_RECORD *prCurrStaRec; + struct LINK *prClientList = + &prP2pBssInfo->rStaRecOfClientList; + if (!prClientList) { + DBGLOG(P2P, ERROR, "prClientList=NULL\n"); + return; + } + LINK_FOR_EACH_ENTRY(prCurrStaRec, + prClientList, rLinkEntry, struct STA_RECORD) { + if (!prCurrStaRec) + break; + COPY_MAC_ADDR( + prQueryStaStatistics->aucMacAddr, + prCurrStaRec->aucMacAddr); + /* break for LINK_FOR_EACH_ENTRY */ + break; + } + } + + prQueryStaStatistics->ucReadClear = TRUE; + wlanQueryStaStatistics(prAdapter, + prQueryStaStatistics, + sizeof(struct PARAM_GET_STA_STATISTICS), + &u4BufLen, + FALSE); + + } + + /* Make sure WFD is still enabled */ + if (prAdapter->rWifiVar.rWfdConfigureSettings.ucWfdEnable) { + cnmTimerStartTimer(prAdapter, + &(prP2pRoleFsmInfo->rP2pRoleFsmGetStatisticsTimer), + P2P_ROLE_GET_STATISTICS_TIME); + } +} +#endif + +void p2pRoleFsmNotifyEapolTxStatus(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN enum ENUM_EAPOL_KEY_TYPE_T rEapolKeyType, + IN enum ENUM_TX_RESULT_CODE rTxDoneStatus) +{ +#if 0 /* finish GC join process when dhcp is done */ + struct BSS_INFO *prBssInfo = (struct BSS_INFO *) NULL; + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *) NULL; + + if (prAdapter == NULL) + return; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + + if (prBssInfo == NULL || prBssInfo->eNetworkType != NETWORK_TYPE_P2P) + return; + + prP2pRoleFsmInfo = P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, + prBssInfo->u4PrivateData); + + if (prP2pRoleFsmInfo == NULL) + return; + + if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) + return; + if (prP2pRoleFsmInfo->eCurrentState != P2P_ROLE_STATE_GC_JOIN) + return; + + if (rEapolKeyType == EAPOL_KEY_4_OF_4 && + rTxDoneStatus == TX_RESULT_SUCCESS) { + /* Finish GC connection process. */ + p2pRoleFsmStateTransition(prAdapter, + prP2pRoleFsmInfo, + P2P_ROLE_STATE_IDLE); + } +#endif +} + +void p2pRoleFsmNotifyDhcpDone(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) +{ + struct BSS_INFO *prBssInfo = (struct BSS_INFO *) NULL; + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *) NULL; + + if (prAdapter == NULL) + return; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + + if (prBssInfo == NULL || prBssInfo->eNetworkType != NETWORK_TYPE_P2P) + return; + + prP2pRoleFsmInfo = P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, + prBssInfo->u4PrivateData); + + if (prP2pRoleFsmInfo == NULL) + return; + + if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) + return; + if (prP2pRoleFsmInfo->eCurrentState != P2P_ROLE_STATE_GC_JOIN) + return; + + /* Finish GC connection process. */ + p2pRoleFsmStateTransition(prAdapter, + prP2pRoleFsmInfo, + P2P_ROLE_STATE_IDLE); +} + +static u_int8_t +p2pRoleNeedOffchnlTx(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo, + IN struct MSG_MGMT_TX_REQUEST *prMgmtTxMsg) +{ + u_int8_t fgNeedOffchnlTx = FALSE; + struct WLAN_MAC_HEADER *prWlanHdr = (struct WLAN_MAC_HEADER *) NULL; + + if (prAdapter == NULL || prBssInfo == NULL || prMgmtTxMsg == NULL) + return FALSE; + + fgNeedOffchnlTx = prMgmtTxMsg->fgIsOffChannel; + + if (fgNeedOffchnlTx) { + prWlanHdr = (struct WLAN_MAC_HEADER *) + ((unsigned long) prMgmtTxMsg->prMgmtMsduInfo->prPacket + + MAC_TX_RESERVED_FIELD); + if (prMgmtTxMsg->rChannelInfo.ucChannelNum == + prBssInfo->ucPrimaryChannel) + fgNeedOffchnlTx = FALSE; + else if ((prWlanHdr->u2FrameCtrl & MASK_FRAME_TYPE) == + MAC_FRAME_PROBE_RSP) + fgNeedOffchnlTx = FALSE; + } + + return fgNeedOffchnlTx; +} /* p2pRoleNeedOffchnlTx */ + + +static void +p2pRoleAdjustChnlTime(IN struct MSG_MGMT_TX_REQUEST *prMgmtTxMsg, + IN struct P2P_OFF_CHNL_TX_REQ_INFO *prOffChnlTxReq) +{ + if (prMgmtTxMsg == NULL || prOffChnlTxReq == NULL) + return; + + if (!prMgmtTxMsg->fgIsOffChannel) + return; + + if (prMgmtTxMsg->u4Duration < MIN_TX_DURATION_TIME_MS) { + /* + * The wait time requested from Supplicant is too short + * to TX a frame, eg. nego.conf.. Overwrite the wait time + * as driver's min TX time. + */ + DBGLOG(P2P, INFO, "Overwrite channel duration from %d to %d\n", + prMgmtTxMsg->u4Duration, + MIN_TX_DURATION_TIME_MS); + prOffChnlTxReq->u4Duration = MIN_TX_DURATION_TIME_MS; + } else { + prOffChnlTxReq->u4Duration = prMgmtTxMsg->u4Duration; + } +} /* p2pRoleAdjustChnlTime */ + +static void +p2pRoleChnlReqByOffChnl(IN struct ADAPTER *prAdapter, + IN struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo, + struct P2P_OFF_CHNL_TX_REQ_INFO *prOffChnlTxReq) +{ + struct P2P_CHNL_REQ_INFO *prP2pChnlReqInfo = + (struct P2P_CHNL_REQ_INFO *) NULL; + + if (prAdapter == NULL || prP2pRoleFsmInfo == NULL || + prOffChnlTxReq == NULL) + return; + + prP2pChnlReqInfo = &(prP2pRoleFsmInfo->rChnlReqInfo); + + prP2pChnlReqInfo->u8Cookie = prOffChnlTxReq->u8Cookie; + prP2pChnlReqInfo->eChnlReqType = CH_REQ_TYPE_OFFCHNL_TX; + prP2pChnlReqInfo->eBand = prOffChnlTxReq->rChannelInfo.eBand; + prP2pChnlReqInfo->ucReqChnlNum = + prOffChnlTxReq->rChannelInfo.ucChannelNum; + prP2pChnlReqInfo->eChnlSco = prOffChnlTxReq->eChnlExt; + prP2pChnlReqInfo->u4MaxInterval = prOffChnlTxReq->u4Duration; + prP2pChnlReqInfo->eChannelWidth = prOffChnlTxReq->rChannelInfo.ucChnlBw; + prP2pChnlReqInfo->ucCenterFreqS1 = + prOffChnlTxReq->rChannelInfo.u4CenterFreq1; + prP2pChnlReqInfo->ucCenterFreqS2 = + prOffChnlTxReq->rChannelInfo.u4CenterFreq2; + + p2pRoleFsmStateTransition(prAdapter, prP2pRoleFsmInfo, + P2P_ROLE_STATE_REQING_CHANNEL); +} /* p2pRoleChnlReqByOffChnl */ + +static u_int8_t +p2pRoleAddTxReq2Queue(IN struct ADAPTER *prAdapter, + IN struct P2P_MGMT_TX_REQ_INFO *prP2pMgmtTxReqInfo, + IN struct MSG_MGMT_TX_REQUEST *prMgmtTxMsg, + OUT struct P2P_OFF_CHNL_TX_REQ_INFO **pprOffChnlTxReq) +{ + struct P2P_OFF_CHNL_TX_REQ_INFO *prTmpOffChnlTxReq = + (struct P2P_OFF_CHNL_TX_REQ_INFO *) NULL; + + prTmpOffChnlTxReq = cnmMemAlloc(prAdapter, + RAM_TYPE_MSG, + sizeof(struct P2P_OFF_CHNL_TX_REQ_INFO)); + + if (prTmpOffChnlTxReq == NULL) { + DBGLOG(P2P, ERROR, + "Allocate TX request buffer fails.\n"); + return FALSE; + } + + prTmpOffChnlTxReq->ucBssIndex = prMgmtTxMsg->ucBssIdx; + prTmpOffChnlTxReq->u8Cookie = prMgmtTxMsg->u8Cookie; + prTmpOffChnlTxReq->prMgmtTxMsdu = prMgmtTxMsg->prMgmtMsduInfo; + prTmpOffChnlTxReq->fgNoneCckRate = prMgmtTxMsg->fgNoneCckRate; + kalMemCopy(&prTmpOffChnlTxReq->rChannelInfo, + &prMgmtTxMsg->rChannelInfo, + sizeof(struct RF_CHANNEL_INFO)); + prTmpOffChnlTxReq->eChnlExt = prMgmtTxMsg->eChnlExt; + prTmpOffChnlTxReq->fgIsWaitRsp = prMgmtTxMsg->fgIsWaitRsp; + + p2pRoleAdjustChnlTime(prMgmtTxMsg, prTmpOffChnlTxReq); + + LINK_INSERT_TAIL(&prP2pMgmtTxReqInfo->rTxReqLink, + &prTmpOffChnlTxReq->rLinkEntry); + + *pprOffChnlTxReq = prTmpOffChnlTxReq; + + return TRUE; +} + +static void +p2pRoleAbortChlReqIfNeed(IN struct ADAPTER *prAdapter, + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo, + struct P2P_CHNL_REQ_INFO *prChnlReqInfo) +{ + if (prAdapter == NULL || prP2pRoleFsmInfo == NULL || + prChnlReqInfo == NULL) + return; + + /* Cancel ongoing channel request whose type is not offchannel-tx*/ + if (prP2pRoleFsmInfo->eCurrentState != P2P_ROLE_STATE_REQING_CHANNEL || + prChnlReqInfo->eChnlReqType == CH_REQ_TYPE_OFFCHNL_TX) + return; + + p2pRoleFsmRunEventAbort(prAdapter, prP2pRoleFsmInfo); +} + +static void +p2pRoleHandleOffchnlTxReq(IN struct ADAPTER *prAdapter, + IN struct MSG_MGMT_TX_REQUEST *prMgmtTxMsg) +{ + struct BSS_INFO *prP2pRoleBssInfo = (struct BSS_INFO *) NULL; + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *) NULL; + struct P2P_MGMT_TX_REQ_INFO *prP2pMgmtTxReqInfo = + (struct P2P_MGMT_TX_REQ_INFO *) NULL; + struct P2P_OFF_CHNL_TX_REQ_INFO *prOffChnlTxReq = + (struct P2P_OFF_CHNL_TX_REQ_INFO *) NULL; + struct P2P_CHNL_REQ_INFO *prChnlReqInfo = + (struct P2P_CHNL_REQ_INFO *) NULL; + + if (prAdapter == NULL || prMgmtTxMsg == NULL) + return; + + prP2pRoleBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prMgmtTxMsg->ucBssIdx); + prP2pRoleFsmInfo = prP2pRoleBssInfo != NULL ? + P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, + prP2pRoleBssInfo->u4PrivateData) : NULL; + + if (prP2pRoleFsmInfo == NULL) + return; + + prP2pMgmtTxReqInfo = &(prP2pRoleFsmInfo->rMgmtTxInfo); + prChnlReqInfo = &(prP2pRoleFsmInfo->rChnlReqInfo); + + if (prP2pMgmtTxReqInfo == NULL || prChnlReqInfo == NULL) + + p2pRoleAbortChlReqIfNeed(prAdapter, prP2pRoleFsmInfo, prChnlReqInfo); + + if (p2pRoleAddTxReq2Queue(prAdapter, prP2pMgmtTxReqInfo, + prMgmtTxMsg, &prOffChnlTxReq) == FALSE) + goto error; + + switch (prP2pRoleFsmInfo->eCurrentState) { + case P2P_ROLE_STATE_IDLE: + p2pRoleChnlReqByOffChnl(prAdapter, prP2pRoleFsmInfo, + prOffChnlTxReq); + break; + case P2P_ROLE_STATE_REQING_CHANNEL: + if (prChnlReqInfo->eChnlReqType != CH_REQ_TYPE_OFFCHNL_TX) { + DBGLOG(P2P, WARN, + "channel already requested by others\n"); + goto error; + } + break; + case P2P_ROLE_STATE_OFF_CHNL_TX: + if (p2pFuncCheckOnRocChnl(&(prMgmtTxMsg->rChannelInfo), + prChnlReqInfo) && + prP2pMgmtTxReqInfo->rTxReqLink.u4NumElem == 1) { + p2pRoleFsmStateTransition(prAdapter, + prP2pRoleFsmInfo, + P2P_ROLE_STATE_OFF_CHNL_TX); + } else { + log_dbg(P2P, INFO, "tx ch: %d, current ch: %d, requested: %d, tx link num: %d", + prMgmtTxMsg->rChannelInfo.ucChannelNum, + prChnlReqInfo->ucReqChnlNum, + prChnlReqInfo->fgIsChannelRequested, + prP2pMgmtTxReqInfo->rTxReqLink.u4NumElem); + } + break; + default: + DBGLOG(P2P, WARN, "Unknown state (%s) for offchannel-tx.\n", + p2pRoleFsmGetFsmState( + prP2pRoleFsmInfo->eCurrentState)); + goto error; + } + + return; + +error: + LINK_REMOVE_KNOWN_ENTRY( + &(prP2pMgmtTxReqInfo->rTxReqLink), + &prOffChnlTxReq->rLinkEntry); + cnmMgtPktFree(prAdapter, prOffChnlTxReq->prMgmtTxMsdu); + cnmMemFree(prAdapter, prOffChnlTxReq); +} /* p2pRoleHandleOffchnlTxReq */ + +void p2pRoleFsmRunEventMgmtTx(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct BSS_INFO *prP2pRoleBssInfo = (struct BSS_INFO *) NULL; + struct MSG_MGMT_TX_REQUEST *prMgmtTxMsg = + (struct MSG_MGMT_TX_REQUEST *) NULL; + u_int8_t fgNeedOffchnlTx; + + if (prAdapter == NULL || prMsgHdr == NULL) + goto error; + + prMgmtTxMsg = (struct MSG_MGMT_TX_REQUEST *) prMsgHdr; + prP2pRoleBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prMgmtTxMsg->ucBssIdx); + + fgNeedOffchnlTx = p2pRoleNeedOffchnlTx(prAdapter, prP2pRoleBssInfo, + prMgmtTxMsg); + DBGLOG(P2P, INFO, "fgNeedOffchnlTx: %d\n", fgNeedOffchnlTx); + + if (!fgNeedOffchnlTx) + p2pFuncTxMgmtFrame(prAdapter, + prMgmtTxMsg->ucBssIdx, + prMgmtTxMsg->prMgmtMsduInfo, + prMgmtTxMsg->fgNoneCckRate); + else + p2pRoleHandleOffchnlTxReq(prAdapter, prMgmtTxMsg); + +error: + cnmMemFree(prAdapter, prMsgHdr); +} /* p2pRoleFsmRunEventMgmtTx */ + +void p2pRoleFsmRunEventTxCancelWait(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct BSS_INFO *prP2pRoleBssInfo = (struct BSS_INFO *) NULL; + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *) NULL; + struct P2P_MGMT_TX_REQ_INFO *prP2pMgmtTxInfo = + (struct P2P_MGMT_TX_REQ_INFO *) NULL; + struct MSG_CANCEL_TX_WAIT_REQUEST *prCancelTxWaitMsg = + (struct MSG_CANCEL_TX_WAIT_REQUEST *) NULL; + struct P2P_OFF_CHNL_TX_REQ_INFO *prOffChnlTxPkt = + (struct P2P_OFF_CHNL_TX_REQ_INFO *) NULL; + u_int8_t fgIsCookieFound = FALSE; + + if (prAdapter == NULL || prMsgHdr == NULL) + goto exit; + + prCancelTxWaitMsg = (struct MSG_CANCEL_TX_WAIT_REQUEST *) prMsgHdr; + prP2pRoleBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prCancelTxWaitMsg->ucBssIdx); + prP2pRoleFsmInfo = P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, + prP2pRoleBssInfo->u4PrivateData); + prP2pMgmtTxInfo = prP2pRoleFsmInfo != NULL ? + &(prP2pRoleFsmInfo->rMgmtTxInfo) : NULL; + + if (prCancelTxWaitMsg == NULL || prP2pRoleFsmInfo == NULL || + prP2pMgmtTxInfo == NULL || prP2pMgmtTxInfo == NULL) + goto exit; + + LINK_FOR_EACH_ENTRY(prOffChnlTxPkt, + &(prP2pMgmtTxInfo->rTxReqLink), + rLinkEntry, + struct P2P_OFF_CHNL_TX_REQ_INFO) { + if (!prOffChnlTxPkt) + break; + if (prOffChnlTxPkt->u8Cookie == prCancelTxWaitMsg->u8Cookie) { + fgIsCookieFound = TRUE; + break; + } + } + + if (fgIsCookieFound || prP2pRoleFsmInfo->eCurrentState == + P2P_ROLE_STATE_OFF_CHNL_TX) { + p2pFunClearAllTxReq(prAdapter, + &(prP2pRoleFsmInfo->rMgmtTxInfo)); + p2pRoleFsmRunEventAbort(prAdapter, prP2pRoleFsmInfo); + } + +exit: + if (prMsgHdr) + cnmMemFree(prAdapter, prMsgHdr); +} /* p2pRoleFsmRunEventTxCancelWait */ + +static void initAcsParams(IN struct ADAPTER *prAdapter, + IN struct MSG_P2P_ACS_REQUEST *prMsgAcsRequest, + IN struct P2P_ACS_REQ_INFO *prAcsReqInfo) { + struct RF_CHANNEL_INFO *prRfChannelInfo; + uint8_t i; + + if (!prAdapter || !prMsgAcsRequest || !prAcsReqInfo) + return; + + kalMemSet(prAcsReqInfo, 0, sizeof(struct P2P_ACS_REQ_INFO)); + prAcsReqInfo->fgIsProcessing = TRUE; + prAcsReqInfo->ucRoleIdx = prMsgAcsRequest->ucRoleIdx; + prAcsReqInfo->fgIsHtEnable = prMsgAcsRequest->fgIsHtEnable; + prAcsReqInfo->fgIsHt40Enable = prMsgAcsRequest->fgIsHt40Enable; + prAcsReqInfo->fgIsVhtEnable = prMsgAcsRequest->fgIsVhtEnable; + prAcsReqInfo->eChnlBw = prMsgAcsRequest->eChnlBw; + prAcsReqInfo->eHwMode = prMsgAcsRequest->eHwMode; + + if (prAcsReqInfo->eChnlBw == MAX_BW_UNKNOWN) { + if (prAcsReqInfo->fgIsHtEnable && + prAcsReqInfo->fgIsHt40Enable) { + prAcsReqInfo->eChnlBw = MAX_BW_40MHZ; + } else { + prAcsReqInfo->eChnlBw = MAX_BW_20MHZ; + } + } + if (!prAcsReqInfo->fgIsVhtEnable && + (prAcsReqInfo->eChnlBw == MAX_BW_80MHZ || + prAcsReqInfo->eChnlBw == MAX_BW_160MHZ)) { + if (prAcsReqInfo->fgIsHtEnable && + prAcsReqInfo->fgIsHt40Enable) { + prAcsReqInfo->eChnlBw = MAX_BW_40MHZ; + } else { + prAcsReqInfo->eChnlBw = MAX_BW_20MHZ; + } + } + + DBGLOG(P2P, INFO, "idx=%d, ht=%d, ht40=%d, vht=%d, bw=%d, m=%d, c=%d", + prMsgAcsRequest->ucRoleIdx, + prMsgAcsRequest->fgIsHtEnable, + prMsgAcsRequest->fgIsHt40Enable, + prMsgAcsRequest->fgIsVhtEnable, + prMsgAcsRequest->eChnlBw, + prMsgAcsRequest->eHwMode, + prMsgAcsRequest->u4NumChannel); + if (prMsgAcsRequest->u4NumChannel) { + for (i = 0; i < prMsgAcsRequest->u4NumChannel; i++) { + prRfChannelInfo = + &(prMsgAcsRequest->arChannelListInfo[i]); + DBGLOG(REQ, INFO, "[%d] band=%d, ch=%d\n", i, + prRfChannelInfo->eBand, + prRfChannelInfo->ucChannelNum); + prRfChannelInfo++; + } + } +} + +static void indicateAcsResultByAisCh(IN struct ADAPTER *prAdapter, + IN struct P2P_ACS_REQ_INFO *prAcsReqInfo, + IN struct BSS_INFO *prAisBssInfo) +{ + if (!prAdapter || !prAcsReqInfo) + return; + + prAcsReqInfo->ucPrimaryCh = prAisBssInfo->ucPrimaryChannel; + if (prAisBssInfo->ucVhtChannelWidth == VHT_OP_CHANNEL_WIDTH_20_40) { + if (prAisBssInfo->eBssSCO == CHNL_EXT_SCN) + prAcsReqInfo->eChnlBw = MAX_BW_20MHZ; + else + prAcsReqInfo->eChnlBw = MAX_BW_40MHZ; + } else if (prAisBssInfo->ucVhtChannelWidth == VHT_OP_CHANNEL_WIDTH_80) { + prAcsReqInfo->eChnlBw = MAX_BW_80MHZ; + } else if (prAisBssInfo->ucVhtChannelWidth == + VHT_OP_CHANNEL_WIDTH_160) { + prAcsReqInfo->eChnlBw = MAX_BW_160MHZ; + } else if (prAisBssInfo->ucVhtChannelWidth == + VHT_OP_CHANNEL_WIDTH_80P80) { + prAcsReqInfo->eChnlBw = MAX_BW_80_80_MHZ; + } else { + prAcsReqInfo->eChnlBw = MAX_BW_20MHZ; + } + p2pFunIndicateAcsResult(prAdapter->prGlueInfo, + prAcsReqInfo); +} + +static void trimAcsScanList(IN struct ADAPTER *prAdapter, + IN struct MSG_P2P_ACS_REQUEST *prMsgAcsRequest, + IN struct P2P_ACS_REQ_INFO *prAcsReqInfo, + IN enum ENUM_BAND eDesiredBand) +{ + uint32_t u4NumChannel = 0; + uint8_t i; + struct RF_CHANNEL_INFO *prRfChannelInfo1; + struct RF_CHANNEL_INFO *prRfChannelInfo2; + + if (!prAdapter || !prAcsReqInfo) + return; + + for (i = 0; i < prMsgAcsRequest->u4NumChannel; i++) { + prRfChannelInfo1 = + &(prMsgAcsRequest->arChannelListInfo[i]); + if (eDesiredBand != prRfChannelInfo1->eBand) + continue; + DBGLOG(P2P, INFO, "acs trim scan list, [%d]=%d %d\n", + u4NumChannel, + prRfChannelInfo1->eBand, + prRfChannelInfo1->ucChannelNum); + prRfChannelInfo2 = &(prMsgAcsRequest->arChannelListInfo[ + u4NumChannel]); + prRfChannelInfo2->eBand = prRfChannelInfo1->eBand; + prRfChannelInfo2->u4CenterFreq1 = + prRfChannelInfo1->u4CenterFreq1; + prRfChannelInfo2->u4CenterFreq2 = + prRfChannelInfo1->u4CenterFreq2; + prRfChannelInfo2->u2PriChnlFreq = + prRfChannelInfo1->u2PriChnlFreq; + prRfChannelInfo2->ucChnlBw = prRfChannelInfo1->ucChnlBw; + prRfChannelInfo2->ucChannelNum = + prRfChannelInfo1->ucChannelNum; + u4NumChannel++; + prRfChannelInfo1++; + } + prMsgAcsRequest->u4NumChannel = u4NumChannel; +} + +static void initAcsChnlMask(IN struct ADAPTER *prAdapter, + IN struct MSG_P2P_ACS_REQUEST *prMsgAcsRequest, + IN struct P2P_ACS_REQ_INFO *prAcsReqInfo) +{ + uint8_t i; + struct RF_CHANNEL_INFO *prRfChannelInfo; + + prAcsReqInfo->u4LteSafeChnMask_2G = 0; + prAcsReqInfo->u4LteSafeChnMask_5G_1 = 0; + prAcsReqInfo->u4LteSafeChnMask_5G_2 = 0; + + for (i = 0; i < prMsgAcsRequest->u4NumChannel; i++) { + prRfChannelInfo = &(prMsgAcsRequest->arChannelListInfo[i]); + if (prRfChannelInfo->ucChannelNum <= 14) { + prAcsReqInfo->u4LteSafeChnMask_2G |= BIT( + prRfChannelInfo->ucChannelNum); + } else if (prRfChannelInfo->ucChannelNum >= 36 && + prRfChannelInfo->ucChannelNum <= 144) { + prAcsReqInfo->u4LteSafeChnMask_5G_1 |= BIT( + (prRfChannelInfo->ucChannelNum - 36) / 4); + } else if (prRfChannelInfo->ucChannelNum >= 149 && + prRfChannelInfo->ucChannelNum <= 181) { + prAcsReqInfo->u4LteSafeChnMask_5G_2 |= BIT( + (prRfChannelInfo->ucChannelNum - 149) / 4); + } + } + + DBGLOG(P2P, INFO, "acs chnl mask=[0x%08x][0x%08x][0x%08x]\n", + prAcsReqInfo->u4LteSafeChnMask_2G, + prAcsReqInfo->u4LteSafeChnMask_5G_1, + prAcsReqInfo->u4LteSafeChnMask_5G_2); +} + +void p2pRoleFsmRunEventAcs(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct MSG_P2P_ACS_REQUEST *prMsgAcsRequest; + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo; + struct MSG_P2P_SCAN_REQUEST *prP2pScanReqMsg; + struct P2P_ACS_REQ_INFO *prAcsReqInfo; + uint32_t u4MsgSize = 0; + + if (!prAdapter || !prMsgHdr) + return; + + prMsgAcsRequest = (struct MSG_P2P_ACS_REQUEST *) prMsgHdr; + prP2pRoleFsmInfo = P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, + prMsgAcsRequest->ucRoleIdx); + prAcsReqInfo = &prP2pRoleFsmInfo->rAcsReqInfo; + + p2pRoleFsmAbortCurrentAcsReq(prAdapter, prMsgAcsRequest); + + initAcsParams(prAdapter, prMsgAcsRequest, prAcsReqInfo); + +#if CFG_HOTSPOT_SUPPORT_FORCE_ACS_SCC + if (prAdapter->rWifiVar.eDbdcMode == ENUM_DBDC_MODE_DISABLED) { + struct BSS_INFO *prAisBssInfo; + + DBGLOG(P2P, INFO, "Report SCC channel\n"); + + prAisBssInfo = aisGetConnectedBssInfo(prAdapter); + if (prAisBssInfo) { + /* Force SCC, indicate channel directly */ + indicateAcsResultByAisCh(prAdapter, prAcsReqInfo, + prAisBssInfo); + goto exit; + } + } +#endif + + if (prAcsReqInfo->eHwMode == P2P_VENDOR_ACS_HW_MODE_11ANY) { + struct BSS_INFO *prAisBssInfo; + + prAisBssInfo = aisGetAisBssInfo(prAdapter, + AIS_DEFAULT_INDEX); + if (prAisBssInfo->eConnectionState == MEDIA_STATE_CONNECTED) { + /* Force SCC, indicate channel directly */ + indicateAcsResultByAisCh(prAdapter, prAcsReqInfo, + prAisBssInfo); + goto exit; + } else if (prAdapter->fgEnable5GBand) { + /* Prefer 5G band first */ + trimAcsScanList(prAdapter, prMsgAcsRequest, + prAcsReqInfo, BAND_5G); + prAcsReqInfo->eHwMode = P2P_VENDOR_ACS_HW_MODE_11A; + } else { + trimAcsScanList(prAdapter, prMsgAcsRequest, + prAcsReqInfo, BAND_2G4); + prAcsReqInfo->eHwMode = P2P_VENDOR_ACS_HW_MODE_11G; + } + } + + initAcsChnlMask(prAdapter, prMsgAcsRequest, prAcsReqInfo); + + u4MsgSize = sizeof(struct MSG_P2P_SCAN_REQUEST) + ( + prMsgAcsRequest->u4NumChannel * + sizeof(struct RF_CHANNEL_INFO)); + + prP2pScanReqMsg = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, u4MsgSize); + if (prP2pScanReqMsg == NULL) { + DBGLOG(P2P, ERROR, "alloc scan req. fail\n"); + return; + } + kalMemSet(prP2pScanReqMsg, 0, u4MsgSize); + prP2pScanReqMsg->eScanType = SCAN_TYPE_ACTIVE_SCAN; + prP2pScanReqMsg->ucBssIdx = prP2pRoleFsmInfo->ucBssIndex; + prP2pScanReqMsg->i4SsidNum = 0; + prP2pScanReqMsg->u4NumChannel = prMsgAcsRequest->u4NumChannel; + prP2pScanReqMsg->u4IELen = 0; + prP2pScanReqMsg->eScanReason = SCAN_REASON_ACS; + kalMemCopy(&(prP2pScanReqMsg->arChannelListInfo), + &(prMsgAcsRequest->arChannelListInfo), + (prMsgAcsRequest->u4NumChannel * + sizeof(struct RF_CHANNEL_INFO))); + p2pRoleFsmRunEventScanRequest(prAdapter, + (struct MSG_HDR *) prP2pScanReqMsg); + +exit: + if (prMsgHdr) + cnmMemFree(prAdapter, prMsgHdr); +} + +static u_int8_t +p2pRoleFsmIsAcsProcessing(IN struct ADAPTER *prAdapter, + uint8_t ucRoleIdx) +{ + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo; + struct P2P_ACS_REQ_INFO *prAcsReqInfo; + + if (!prAdapter) + return FALSE; + + prP2pRoleFsmInfo = P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, + ucRoleIdx); + if (!prP2pRoleFsmInfo) + return FALSE; + + prAcsReqInfo = &prP2pRoleFsmInfo->rAcsReqInfo; + if (!prAcsReqInfo) + return FALSE; + + return prAcsReqInfo->fgIsProcessing; +} + +static void +p2pRoleFsmAbortCurrentAcsReq(IN struct ADAPTER *prAdapter, + IN struct MSG_P2P_ACS_REQUEST *prMsgAcsRequest) +{ + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = NULL; + struct P2P_SCAN_REQ_INFO *prScanReqInfo = NULL; + + if (!prAdapter || !prMsgAcsRequest) + return; + + prP2pRoleFsmInfo = P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, + prMsgAcsRequest->ucRoleIdx); + prScanReqInfo = &(prP2pRoleFsmInfo->rScanReqInfo); + + if (!p2pRoleFsmIsAcsProcessing(prAdapter, prMsgAcsRequest->ucRoleIdx)) + return; + + if (prP2pRoleFsmInfo->eCurrentState == P2P_ROLE_STATE_SCAN && + prScanReqInfo->eScanReason == SCAN_REASON_ACS) { + DBGLOG(P2P, INFO, "Cancel current ACS scan.\n"); + p2pRoleFsmRunEventAbort(prAdapter, prP2pRoleFsmInfo); + } +} + +void p2pRoleFsmRunEventScanAbort(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIdx) +{ + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = NULL; + struct BSS_INFO *prP2pBssInfo = NULL; + + do { + ASSERT_BREAK(prAdapter != NULL); + + DBGLOG(P2P, TRACE, "p2pRoleFsmRunEventScanAbort\n"); + + prP2pBssInfo = prAdapter->aprBssInfo[ucBssIdx]; + prP2pRoleFsmInfo = P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, + prP2pBssInfo->u4PrivateData); + + if (prP2pRoleFsmInfo->eCurrentState == P2P_ROLE_STATE_SCAN) { + struct P2P_SCAN_REQ_INFO *prScanReqInfo = + &(prP2pRoleFsmInfo->rScanReqInfo); + + prScanReqInfo->fgIsAbort = TRUE; + + p2pRoleFsmStateTransition(prAdapter, + prP2pRoleFsmInfo, + P2P_ROLE_STATE_IDLE); + } + } while (FALSE); +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/p2p_role_state.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/p2p_role_state.c new file mode 100644 index 0000000000000000000000000000000000000000..18716640a9efc0d932758bf39b7775b57713a4b5 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/p2p_role_state.c @@ -0,0 +1,750 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +#include "precomp.h" + +void +p2pRoleStateInit_IDLE(IN struct ADAPTER *prAdapter, + IN struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo, + IN struct BSS_INFO *prP2pBssInfo) +{ + cnmTimerStartTimer(prAdapter, + &(prP2pRoleFsmInfo->rP2pRoleFsmTimeoutTimer), + P2P_AP_CHNL_HOLD_TIME_MS); +} /* p2pRoleStateInit_IDLE */ + +void +p2pRoleStateAbort_IDLE(IN struct ADAPTER *prAdapter, + IN struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo, + IN struct P2P_CHNL_REQ_INFO *prP2pChnlReqInfo) +{ + + /* AP mode channel hold time. */ + if (prP2pChnlReqInfo->fgIsChannelRequested) + p2pFuncReleaseCh(prAdapter, + prP2pRoleFsmInfo->ucBssIndex, + prP2pChnlReqInfo); + + DBGLOG(P2P, TRACE, "stop role idle timer.\n"); + cnmTimerStopTimer(prAdapter, + &(prP2pRoleFsmInfo->rP2pRoleFsmTimeoutTimer)); +} /* p2pRoleStateAbort_IDLE */ + +void p2pRoleStateInit_SCAN(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN struct P2P_SCAN_REQ_INFO *prScanReqInfo) +{ + struct P2P_DEV_FSM_INFO *prP2pDevFsmInfo = + (struct P2P_DEV_FSM_INFO *) NULL; + struct P2P_SCAN_REQ_INFO *prDevScanReqInfo = NULL; + + do { + ASSERT_BREAK((prAdapter != NULL) + && (prScanReqInfo != NULL)); + + prScanReqInfo->fgIsScanRequest = TRUE; + if (prScanReqInfo->u4BufLength == 0) { + /* If we let u4BufLength be zero, + * scan module will copy the IE buf from ScanParam + * Sometime this content is from AIS, + * so we need copy it from P2Pdev + */ + prP2pDevFsmInfo = prAdapter->rWifiVar.prP2pDevFsmInfo; + if (prP2pDevFsmInfo) { + prDevScanReqInfo = + &(prP2pDevFsmInfo->rScanReqInfo); + if (prDevScanReqInfo->u4BufLength != 0) { + /* IE Buffer */ + kalMemCopy(prScanReqInfo->aucIEBuf, + prDevScanReqInfo->aucIEBuf, + prDevScanReqInfo->u4BufLength); + prScanReqInfo->u4BufLength = + prDevScanReqInfo->u4BufLength; + DBGLOG(P2P, TRACE, + "p2pRoleStateInit_SCAN Copy p2p IE from P2P dev\n"); + } + } else + DBGLOG(P2P, ERROR, "No prP2pDevFsmInfo ptr\n"); + } + p2pFuncRequestScan(prAdapter, ucBssIndex, prScanReqInfo); + } while (FALSE); +} /* p2pRoleStateInit_SCAN */ + +void p2pRoleStateAbort_SCAN(IN struct ADAPTER *prAdapter, + IN struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo) +{ + struct P2P_SCAN_REQ_INFO *prScanInfo = + (struct P2P_SCAN_REQ_INFO *) NULL; + + do { + prScanInfo = &prP2pRoleFsmInfo->rScanReqInfo; + + p2pFuncCancelScan(prAdapter, + prP2pRoleFsmInfo->ucBssIndex, + prScanInfo); + + /* TODO: May need indicate port index to upper layer. */ + kalP2PIndicateScanDone(prAdapter->prGlueInfo, + prP2pRoleFsmInfo->ucRoleIndex, + prScanInfo->fgIsAbort); + + } while (FALSE); +} /* p2pRoleStateAbort_SCAN */ + +void +p2pRoleStateInit_REQING_CHANNEL(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIdx, + IN struct P2P_CHNL_REQ_INFO *prChnlReqInfo) +{ + + do { + ASSERT_BREAK((prAdapter != NULL) && (prChnlReqInfo != NULL)); + + p2pFuncAcquireCh(prAdapter, ucBssIdx, prChnlReqInfo); + + } while (FALSE); +} /* p2pRoleStateInit_REQING_CHANNEL */ + +void +p2pRoleStateAbort_REQING_CHANNEL(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prP2pRoleBssInfo, + IN struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo, + IN enum ENUM_P2P_ROLE_STATE eNextState) +{ + u_int8_t fgIsStartGO = FALSE; + + do { + ASSERT_BREAK((prAdapter != NULL) + && (prP2pRoleBssInfo != NULL) + && (prP2pRoleFsmInfo != NULL)); + + if (eNextState == P2P_ROLE_STATE_IDLE) { + if (prP2pRoleBssInfo->eIntendOPMode + == OP_MODE_ACCESS_POINT) { + struct P2P_CHNL_REQ_INFO *prP2pChnlReqInfo = + &(prP2pRoleFsmInfo->rChnlReqInfo); + + if (IS_NET_PWR_STATE_ACTIVE(prAdapter, + prP2pRoleFsmInfo->ucBssIndex)) { + p2pFuncStartGO(prAdapter, + prP2pRoleBssInfo, + &(prP2pRoleFsmInfo->rConnReqInfo), + &(prP2pRoleFsmInfo->rChnlReqInfo)); + fgIsStartGO = TRUE; + } else if (prP2pChnlReqInfo-> + fgIsChannelRequested) + p2pFuncReleaseCh(prAdapter, + prP2pRoleFsmInfo->ucBssIndex, + prP2pChnlReqInfo); + } else { + p2pFuncReleaseCh(prAdapter, + prP2pRoleFsmInfo->ucBssIndex, + &(prP2pRoleFsmInfo->rChnlReqInfo)); + } + } else if (eNextState == P2P_ROLE_STATE_SCAN) { + /* Abort channel anyway */ + p2pFuncReleaseCh(prAdapter, + prP2pRoleFsmInfo->ucBssIndex, + &(prP2pRoleFsmInfo->rChnlReqInfo)); + } + } while (FALSE); + +#if CFG_HOTSPOT_SUPPORT_ADJUST_SCC + if (fgIsStartGO && p2pFuncIsAPMode(prAdapter->rWifiVar. + prP2PConnSettings[prP2pRoleFsmInfo->ucRoleIndex])) { + struct GL_P2P_INFO *prP2PInfo = prAdapter->prGlueInfo + ->prP2PInfo[prP2pRoleFsmInfo->ucRoleIndex]; + struct P2P_CHNL_REQ_INFO *prP2pChnlReqInfo = + &(prP2pRoleFsmInfo->rChnlReqInfo); + + prP2PInfo->eChnlSwitchPolicy = CHNL_SWITCH_POLICY_NONE; + p2pFuncSwitchSapChannel(prAdapter); + if (prP2PInfo->eChnlSwitchPolicy != CHNL_SWITCH_POLICY_NONE) { + if (prP2pChnlReqInfo->fgIsChannelRequested) { + p2pFuncReleaseCh(prAdapter, + prP2pRoleFsmInfo->ucBssIndex, + prP2pChnlReqInfo); + } + cnmTimerStopTimer(prAdapter, + &(prP2pRoleFsmInfo->rP2pRoleFsmTimeoutTimer)); + } + } +#endif +} /* p2pRoleStateAbort_REQING_CHANNEL */ + +void +p2pRoleStateInit_AP_CHNL_DETECTION(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN struct P2P_SCAN_REQ_INFO *prScanReqInfo, + IN struct P2P_CONNECTION_REQ_INFO *prConnReqInfo) +{ + struct P2P_SPECIFIC_BSS_INFO *prP2pSpecificBssInfo = + (struct P2P_SPECIFIC_BSS_INFO *) NULL; + struct BSS_INFO *prBssInfo = NULL; + uint8_t ucPreferedChnl = 0; + enum ENUM_BAND eBand = BAND_NULL; + enum ENUM_CHNL_EXT eSco = CHNL_EXT_SCN; + + do { + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + ASSERT_BREAK((prAdapter != NULL) && (prScanReqInfo != NULL) + && (prConnReqInfo != NULL) && (prBssInfo != NULL)); + + prP2pSpecificBssInfo = + prAdapter->rWifiVar + .prP2pSpecificBssInfo[prBssInfo->u4PrivateData]; + + if ((cnmPreferredChannel(prAdapter, + &eBand, + &ucPreferedChnl, + &eSco) == FALSE) + && (prConnReqInfo->rChannelInfo.ucChannelNum == 0)) { + + /* Sparse channel detection. */ + prP2pSpecificBssInfo->ucPreferredChannel = 0; + + prScanReqInfo->eScanType = SCAN_TYPE_PASSIVE_SCAN; + /* 50ms for passive channel load detection */ + prScanReqInfo->u2PassiveDewellTime = 50; + } else { + /* Active scan to shorten scan time. */ + prScanReqInfo->eScanType = SCAN_TYPE_ACTIVE_SCAN; + prScanReqInfo->u2PassiveDewellTime = 0; + + if (prConnReqInfo->rChannelInfo.ucChannelNum != 0) { + prP2pSpecificBssInfo->ucPreferredChannel = + prConnReqInfo->rChannelInfo + .ucChannelNum; + prP2pSpecificBssInfo->eRfBand = + prConnReqInfo->rChannelInfo + .eBand; + prP2pSpecificBssInfo->eRfSco = CHNL_EXT_SCN; + } else { + prP2pSpecificBssInfo->ucPreferredChannel = + ucPreferedChnl; + prP2pSpecificBssInfo->eRfBand = eBand; + prP2pSpecificBssInfo->eRfSco = eSco; + } + + } + + /* TODO: See if channel set to include 5G or only 2.4G */ + prScanReqInfo->eChannelSet = SCAN_CHANNEL_2G4; + + prScanReqInfo->fgIsAbort = TRUE; + prScanReqInfo->fgIsScanRequest = TRUE; + prScanReqInfo->ucNumChannelList = 0; + prScanReqInfo->u4BufLength = 0; + prScanReqInfo->ucSsidNum = 1; + prScanReqInfo->arSsidStruct[0].ucSsidLen = 0; + + p2pFuncRequestScan(prAdapter, ucBssIndex, prScanReqInfo); + + } while (FALSE); + + return; + +} /* p2pRoleStateInit_AP_CHNL_DETECTION */ + +void +p2pRoleStateAbort_AP_CHNL_DETECTION(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN struct P2P_CONNECTION_REQ_INFO *prP2pConnReqInfo, + IN struct P2P_CHNL_REQ_INFO *prChnlReqInfo, + IN struct P2P_SCAN_REQ_INFO *prP2pScanReqInfo, + IN enum ENUM_P2P_ROLE_STATE eNextState) +{ + struct P2P_SPECIFIC_BSS_INFO *prP2pSpecificBssInfo = + (struct P2P_SPECIFIC_BSS_INFO *) NULL; + struct BSS_INFO *prBssInfo = NULL; + + do { + if (eNextState == P2P_ROLE_STATE_REQING_CHANNEL) { + prBssInfo = + GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + prP2pSpecificBssInfo = + prAdapter->rWifiVar + .prP2pSpecificBssInfo[prBssInfo->u4PrivateData]; + + if (prP2pSpecificBssInfo->ucPreferredChannel == 0) { + if (scnQuerySparseChannel(prAdapter, + &prP2pSpecificBssInfo + ->eRfBand, + &prP2pSpecificBssInfo + ->ucPreferredChannel)) { + prP2pSpecificBssInfo->eRfSco = + CHNL_EXT_SCN; + } else { + DBGLOG(P2P, ERROR, + "Sparse Channel Error, use default settings\n"); + /* Sparse channel false. */ + prP2pSpecificBssInfo->ucPreferredChannel + = P2P_DEFAULT_LISTEN_CHANNEL; + prP2pSpecificBssInfo->eRfBand + = BAND_2G4; + prP2pSpecificBssInfo->eRfSco + = CHNL_EXT_SCN; + } + } + + prChnlReqInfo->u8Cookie = 0; + prChnlReqInfo->ucReqChnlNum = + prP2pSpecificBssInfo->ucPreferredChannel; + prChnlReqInfo->eBand = prP2pSpecificBssInfo->eRfBand; + prChnlReqInfo->eChnlSco = prP2pSpecificBssInfo->eRfSco; + prChnlReqInfo->u4MaxInterval = P2P_AP_CHNL_HOLD_TIME_MS; + prChnlReqInfo->eChnlReqType = CH_REQ_TYPE_GO_START_BSS; + + prChnlReqInfo->eChannelWidth = CW_20_40MHZ; + prChnlReqInfo->ucCenterFreqS1 = 0; + prChnlReqInfo->ucCenterFreqS2 = 0; + + } else { + p2pFuncCancelScan(prAdapter, + ucBssIndex, + prP2pScanReqInfo); + } + } while (FALSE); +} + +void +p2pRoleStateInit_GC_JOIN(IN struct ADAPTER *prAdapter, + IN struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo, + IN struct P2P_CHNL_REQ_INFO *prChnlReqInfo) +{ + /* P_MSG_JOIN_REQ_T prJoinReqMsg = (P_MSG_JOIN_REQ_T)NULL; */ + struct BSS_INFO *prP2pBssInfo = (struct BSS_INFO *) NULL; + + do { + ASSERT_BREAK((prAdapter != NULL) + && (prP2pRoleFsmInfo != NULL) + && (prChnlReqInfo != NULL)); + + prP2pBssInfo = + GET_BSS_INFO_BY_INDEX(prAdapter, + prP2pRoleFsmInfo->ucBssIndex); + + /* Setup a join timer. */ + DBGLOG(P2P, TRACE, "Start a join init timer\n"); + cnmTimerStartTimer(prAdapter, + &(prP2pRoleFsmInfo->rP2pRoleFsmTimeoutTimer), + (prChnlReqInfo->u4MaxInterval + - AIS_JOIN_CH_GRANT_THRESHOLD)); + + p2pFuncGCJoin(prAdapter, + prP2pBssInfo, + &(prP2pRoleFsmInfo->rJoinInfo)); + + } while (FALSE); +} /* p2pRoleStateInit_GC_JOIN */ + +void +p2pRoleStateAbort_GC_JOIN(IN struct ADAPTER *prAdapter, + IN struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo, + IN struct P2P_JOIN_INFO *prJoinInfo, + IN enum ENUM_P2P_ROLE_STATE eNextState) +{ + do { + + if (prJoinInfo->fgIsJoinComplete == FALSE) { + struct MSG_SAA_FSM_ABORT *prJoinAbortMsg = + (struct MSG_SAA_FSM_ABORT *) NULL; + struct BSS_DESC *prBssDesc = + (struct BSS_DESC *) NULL; + + prJoinAbortMsg = + (struct MSG_SAA_FSM_ABORT *) cnmMemAlloc( + prAdapter, + RAM_TYPE_MSG, + sizeof(struct MSG_SAA_FSM_ABORT)); + if (!prJoinAbortMsg) { + DBGLOG(P2P, TRACE, + "Fail to allocate join abort message buffer\n"); + ASSERT(FALSE); + return; + } + + prJoinAbortMsg->rMsgHdr.eMsgId = MID_P2P_SAA_FSM_ABORT; + prJoinAbortMsg->ucSeqNum = prJoinInfo->ucSeqNumOfReqMsg; + prJoinAbortMsg->prStaRec = prJoinInfo->prTargetStaRec; + + /* Reset the flag to clear target BSS state */ + prBssDesc = prJoinInfo->prTargetBssDesc; + if (prBssDesc != NULL) { + prBssDesc->fgIsConnecting &= + ~BIT(prP2pRoleFsmInfo->ucBssIndex); + } + + mboxSendMsg(prAdapter, + MBOX_ID_0, + (struct MSG_HDR *) prJoinAbortMsg, + MSG_SEND_METHOD_BUF); + + } + + /* Stop Join Timer. */ + cnmTimerStopTimer(prAdapter, + &(prP2pRoleFsmInfo->rP2pRoleFsmTimeoutTimer)); + + /* Release channel requested. */ + p2pFuncReleaseCh(prAdapter, + prP2pRoleFsmInfo->ucBssIndex, + &(prP2pRoleFsmInfo->rChnlReqInfo)); + + } while (FALSE); +} + +#if (CFG_SUPPORT_DFS_MASTER == 1) +void +p2pRoleStateInit_DFS_CAC(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIdx, + IN struct P2P_CHNL_REQ_INFO *prChnlReqInfo) +{ + + do { + ASSERT_BREAK((prAdapter != NULL) && (prChnlReqInfo != NULL)); + + p2pFuncAcquireCh(prAdapter, ucBssIdx, prChnlReqInfo); + } while (FALSE); +} /* p2pRoleStateInit_DFS_CAC */ + +void +p2pRoleStateAbort_DFS_CAC(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prP2pRoleBssInfo, + IN struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo, + IN enum ENUM_P2P_ROLE_STATE eNextState) +{ + do { + cnmTimerStopTimer(prAdapter, + &(prP2pRoleFsmInfo->rP2pRoleFsmTimeoutTimer)); + + p2pFuncReleaseCh(prAdapter, + prP2pRoleFsmInfo->ucBssIndex, + &(prP2pRoleFsmInfo->rChnlReqInfo)); + + } while (FALSE); +} /* p2pRoleStateAbort_DFS_CAC */ + +void +p2pRoleStateInit_SWITCH_CHANNEL(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIdx, + IN struct P2P_CHNL_REQ_INFO *prChnlReqInfo) +{ + + do { + ASSERT_BREAK((prAdapter != NULL) && (prChnlReqInfo != NULL)); + + p2pFuncAcquireCh(prAdapter, ucBssIdx, prChnlReqInfo); + } while (FALSE); +} /* p2pRoleStateInit_SWITCH_CHANNEL */ + +void +p2pRoleStateAbort_SWITCH_CHANNEL(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prP2pRoleBssInfo, + IN struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo, + IN enum ENUM_P2P_ROLE_STATE eNextState) +{ + do { + p2pFuncReleaseCh(prAdapter, + prP2pRoleFsmInfo->ucBssIndex, + &(prP2pRoleFsmInfo->rChnlReqInfo)); + } while (FALSE); +} /* p2pRoleStateAbort_SWITCH_CHANNEL */ +#endif + +void +p2pRoleStatePrepare_To_REQING_CHANNEL_STATE(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo, + IN struct P2P_CONNECTION_REQ_INFO *prConnReqInfo, + OUT struct P2P_CHNL_REQ_INFO *prChnlReqInfo) +{ + enum ENUM_BAND eBandBackup; + uint8_t ucChannelBackup; + enum ENUM_CHNL_EXT eSCOBackup; + uint8_t ucRfBw; + + do { + /* P2P BSS info is for temporarily use + * Request a 80MHz channel before starting AP/GO + * to prevent from STA/GC connected too early (before CH abort) + * Therefore, STA/GC Rate will drop during DHCP exchange packets + */ + + /* Previous issue: + * Always request 20MHz channel, + * but carry 40MHz HT cap/80MHz VHT cap, + * then if GC/STA connected before CH abort, + * GO/AP cannot listen to GC/STA's 40MHz/80MHz packets. + */ + + eBandBackup = prBssInfo->eBand; + ucChannelBackup = prBssInfo->ucPrimaryChannel; + eSCOBackup = prBssInfo->eBssSCO; + + prBssInfo->ucPrimaryChannel = + prConnReqInfo->rChannelInfo.ucChannelNum; + prBssInfo->eBand = prConnReqInfo->rChannelInfo.eBand; + + prBssInfo->eBssSCO = rlmGetScoForAP(prAdapter, prBssInfo); + + ASSERT_BREAK((prAdapter != NULL) + && (prConnReqInfo != NULL) + && (prChnlReqInfo != NULL)); + + prChnlReqInfo->u8Cookie = 0; + prChnlReqInfo->ucReqChnlNum = + prConnReqInfo->rChannelInfo.ucChannelNum; + prChnlReqInfo->eBand = prConnReqInfo->rChannelInfo.eBand; + prChnlReqInfo->eChnlSco = prBssInfo->eBssSCO; + prChnlReqInfo->u4MaxInterval = P2P_AP_CHNL_HOLD_TIME_MS; + prChnlReqInfo->eChnlReqType = CH_REQ_TYPE_GO_START_BSS; + + if (prBssInfo->eBand == BAND_5G) { + /* Decide RF BW by own OP BW */ + ucRfBw = cnmGetDbdcBwCapability(prAdapter, + prBssInfo->ucBssIndex); + /* Revise to VHT OP BW */ + ucRfBw = rlmGetVhtOpBwByBssOpBw(ucRfBw); + prChnlReqInfo->eChannelWidth = ucRfBw; + } else + prChnlReqInfo->eChannelWidth = CW_20_40MHZ; + + /* TODO: BW80+80 support */ + prChnlReqInfo->ucCenterFreqS1 = + nicGetVhtS1(prBssInfo->ucPrimaryChannel, + prChnlReqInfo->eChannelWidth); + prChnlReqInfo->ucCenterFreqS2 = 0; + + /* If the S1 is invalid, force to change bandwidth */ + if ((prBssInfo->eBand == BAND_5G) && + (prChnlReqInfo->ucCenterFreqS1 == 0)) + prChnlReqInfo->eChannelWidth = + VHT_OP_CHANNEL_WIDTH_20_40; + + DBGLOG(P2P, TRACE, + "p2pRoleStatePrepare_To_REQING_CHANNEL_STATE\n"); + + /* Reset */ + prBssInfo->ucPrimaryChannel = ucChannelBackup; + prBssInfo->eBand = eBandBackup; + prBssInfo->eBssSCO = eSCOBackup; + } while (FALSE); +} + +#if (CFG_SUPPORT_DFS_MASTER == 1) +void +p2pRoleStatePrepare_To_DFS_CAC_STATE(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo, + IN enum ENUM_CHANNEL_WIDTH rChannelWidth, + IN struct P2P_CONNECTION_REQ_INFO *prConnReqInfo, + OUT struct P2P_CHNL_REQ_INFO *prChnlReqInfo) +{ + enum ENUM_BAND eBandBackup; + uint8_t ucChannelBackup; + enum ENUM_CHNL_EXT eSCOBackup; + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *) NULL; + + do { + + eBandBackup = prBssInfo->eBand; + ucChannelBackup = prBssInfo->ucPrimaryChannel; + eSCOBackup = prBssInfo->eBssSCO; + + prBssInfo->ucPrimaryChannel = + prConnReqInfo->rChannelInfo.ucChannelNum; + prBssInfo->eBand = prConnReqInfo->rChannelInfo.eBand; + + prBssInfo->eBssSCO = rlmGetScoForAP(prAdapter, prBssInfo); + + prP2pRoleFsmInfo = + P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, + prBssInfo->u4PrivateData); + + ASSERT_BREAK((prAdapter != NULL) + && (prConnReqInfo != NULL) + && (prChnlReqInfo != NULL)); + + prChnlReqInfo->u8Cookie = 0; + prChnlReqInfo->ucReqChnlNum = + prConnReqInfo->rChannelInfo.ucChannelNum; + prChnlReqInfo->eBand = prConnReqInfo->rChannelInfo.eBand; + prChnlReqInfo->eChnlSco = prBssInfo->eBssSCO; + prChnlReqInfo->u4MaxInterval = + prAdapter->prGlueInfo + ->prP2PInfo[prP2pRoleFsmInfo->ucRoleIndex] + ->cac_time_ms; + prChnlReqInfo->eChnlReqType = CH_REQ_TYPE_DFS_CAC; + + prBssInfo->ucVhtChannelWidth = + cnmGetBssMaxBwToChnlBW(prAdapter, + prBssInfo->ucBssIndex); + prChnlReqInfo->eChannelWidth = prBssInfo->ucVhtChannelWidth; + + if (prChnlReqInfo->eChannelWidth + == VHT_OP_CHANNEL_WIDTH_80P80) { + /* TODO: BW80+80 support */ + log_dbg(RLM, WARN, "BW80+80 not support. Fallback to VHT_OP_CHANNEL_WIDTH_20_40\n"); + prChnlReqInfo->eChannelWidth = + VHT_OP_CHANNEL_WIDTH_20_40; + prChnlReqInfo->ucCenterFreqS1 = 0; + prChnlReqInfo->ucCenterFreqS2 = 0; + } else { + prChnlReqInfo->ucCenterFreqS1 = + rlmGetVhtS1ForAP(prAdapter, prBssInfo); + prChnlReqInfo->ucCenterFreqS2 = 0; + } + + DBGLOG(P2P, TRACE, + "p2pRoleStatePrepare_To_REQING_CHANNEL_STATE\n"); + + /* Reset */ + prBssInfo->ucPrimaryChannel = ucChannelBackup; + prBssInfo->eBand = eBandBackup; + prBssInfo->eBssSCO = eSCOBackup; + } while (FALSE); +} +#endif + +u_int8_t +p2pRoleStateInit_OFF_CHNL_TX(IN struct ADAPTER *prAdapter, + IN struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo, + IN struct P2P_CHNL_REQ_INFO *prChnlReqInfo, + IN struct P2P_MGMT_TX_REQ_INFO *prP2pMgmtTxInfo, + OUT enum ENUM_P2P_ROLE_STATE *peNextState) +{ + struct P2P_OFF_CHNL_TX_REQ_INFO *prOffChnlTxPkt = + (struct P2P_OFF_CHNL_TX_REQ_INFO *) NULL; + + if (prAdapter == NULL || prP2pMgmtTxInfo == NULL || peNextState == NULL) + return FALSE; + + if (LINK_IS_EMPTY(&(prP2pMgmtTxInfo->rTxReqLink))) { + p2pFuncReleaseCh(prAdapter, + prP2pRoleFsmInfo->ucBssIndex, + prChnlReqInfo); + /* Link is empty, return back to IDLE. */ + *peNextState = P2P_ROLE_STATE_IDLE; + return TRUE; + } + + prOffChnlTxPkt = + LINK_PEEK_HEAD(&(prP2pMgmtTxInfo->rTxReqLink), + struct P2P_OFF_CHNL_TX_REQ_INFO, + rLinkEntry); + + if (prOffChnlTxPkt == NULL) { + DBGLOG(P2P, ERROR, + "Fatal Error, Link not empty but get NULL pointer.\n"); + ASSERT(FALSE); + return FALSE; + } + + if (!p2pFuncCheckOnRocChnl(&(prOffChnlTxPkt->rChannelInfo), + prChnlReqInfo)) { + DBGLOG(P2P, WARN, + "req channel(%d) != TX channel(%d), request chnl again", + prChnlReqInfo->ucReqChnlNum, + prOffChnlTxPkt->rChannelInfo.ucChannelNum); + + prChnlReqInfo->u8Cookie = prOffChnlTxPkt->u8Cookie; + prChnlReqInfo->eChnlReqType = CH_REQ_TYPE_OFFCHNL_TX; + prChnlReqInfo->eBand = prOffChnlTxPkt->rChannelInfo.eBand; + prChnlReqInfo->ucReqChnlNum = + prOffChnlTxPkt->rChannelInfo.ucChannelNum; + prChnlReqInfo->eChnlSco = prOffChnlTxPkt->eChnlExt; + prChnlReqInfo->u4MaxInterval = prOffChnlTxPkt->u4Duration; + prChnlReqInfo->eChannelWidth = + prOffChnlTxPkt->rChannelInfo.ucChnlBw; + prChnlReqInfo->ucCenterFreqS1 = + prOffChnlTxPkt->rChannelInfo.u4CenterFreq1; + prChnlReqInfo->ucCenterFreqS2 = + prOffChnlTxPkt->rChannelInfo.u4CenterFreq2; + + p2pFuncAcquireCh(prAdapter, + prP2pRoleFsmInfo->ucBssIndex, + prChnlReqInfo); + } else { + cnmTimerStartTimer(prAdapter, + &(prP2pRoleFsmInfo->rP2pRoleFsmTimeoutTimer), + prOffChnlTxPkt->u4Duration); + p2pFuncTxMgmtFrame(prAdapter, + prOffChnlTxPkt->ucBssIndex, + prOffChnlTxPkt->prMgmtTxMsdu, + prOffChnlTxPkt->fgNoneCckRate); + + LINK_REMOVE_HEAD(&(prP2pMgmtTxInfo->rTxReqLink), + prOffChnlTxPkt, + struct P2P_OFF_CHNL_TX_REQ_INFO *); + cnmMemFree(prAdapter, prOffChnlTxPkt); + } + + return FALSE; +} + +void +p2pRoleStateAbort_OFF_CHNL_TX(IN struct ADAPTER *prAdapter, + IN struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo, + IN struct P2P_MGMT_TX_REQ_INFO *prP2pMgmtTxInfo, + IN struct P2P_CHNL_REQ_INFO *prChnlReqInfo, + IN enum ENUM_P2P_ROLE_STATE eNextState) +{ + cnmTimerStopTimer(prAdapter, + &(prP2pRoleFsmInfo->rP2pRoleFsmTimeoutTimer)); + + if (eNextState == P2P_ROLE_STATE_OFF_CHNL_TX) + return; + + p2pFunClearAllTxReq(prAdapter, prP2pMgmtTxInfo); + p2pFuncReleaseCh(prAdapter, + prP2pRoleFsmInfo->ucBssIndex, + prChnlReqInfo); +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/p2p_scan.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/p2p_scan.c new file mode 100644 index 0000000000000000000000000000000000000000..bbc43254ab5be1ec19c213e5c6b949ecad74715d --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/p2p_scan.c @@ -0,0 +1,348 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: @(#) p2p_scan.c@@ + */ + +/*! \file "p2p_scan.c" + * \brief This file defines the p2p scan profile and + * the processing function of scan result for SCAN Module. + * + * The SCAN Profile selection is part of SCAN MODULE and + * responsible for defining SCAN Parameters - + * e.g. MIN_CHANNEL_TIME, number of scan channels. + * In this file we also define the process of SCAN Result + * including adding, searching and removing SCAN record from the list. + */ + +/******************************************************************************* + * C O M P I L E R F L A G S + ****************************************************************************** + */ + +/****************************************************************************** + * E X T E R N A L R E F E R E N C E S + ****************************************************************************** + */ + +#include "precomp.h" + +/******************************************************************************* + * C O N S T A N T S + ****************************************************************************** + */ + +/****************************************************************************** + * D A T A T Y P E S + ****************************************************************************** + */ + +/****************************************************************************** + * P U B L I C D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * P R I V A T E D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * M A C R O S + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N D E C L A R A T I O N S + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N S + ****************************************************************************** + */ + +void +scanP2pProcessBeaconAndProbeResp(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, + IN uint32_t *prStatus, + IN struct BSS_DESC *prBssDesc, + IN struct WLAN_BEACON_FRAME *prWlanBeaconFrame) +{ + u_int8_t fgIsBeacon = FALSE; + u_int8_t fgIsSkipThisBeacon = FALSE; + + /* Indicate network to kernel for P2P interface when: + * 1. This is P2P network + * 2. Driver is configured to report all bss networks + */ + if (!prBssDesc->fgIsP2PPresent && + !prAdapter->p2p_scan_report_all_bss) + return; + + fgIsBeacon = (prWlanBeaconFrame->u2FrameCtrl & MASK_FRAME_TYPE) == + MAC_FRAME_BEACON; + + if (prBssDesc->fgIsConnected && fgIsBeacon) { + uint32_t u4Idx = 0; + struct BSS_INFO *prP2pBssInfo = + (struct BSS_INFO *) NULL; + + for (u4Idx = 0; u4Idx < prAdapter->ucHwBssIdNum; u4Idx++) { + /* Check BSS for P2P. */ + /* Check BSSID. */ + prP2pBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + (uint8_t) u4Idx); + + if (!IS_BSS_ACTIVE(prP2pBssInfo)) + continue; + + if ((prP2pBssInfo->eNetworkType != NETWORK_TYPE_P2P) || + (UNEQUAL_MAC_ADDR(prP2pBssInfo->aucBSSID, + prBssDesc->aucBSSID) || + (!EQUAL_SSID(prP2pBssInfo->aucSSID, + prP2pBssInfo->ucSSIDLen, + prBssDesc->aucSSID, + prBssDesc->ucSSIDLen)))) { + continue; + } + /* P2P GC */ + /* Connected */ + if ((prP2pBssInfo->eCurrentOPMode == + OP_MODE_INFRASTRUCTURE) && + (prP2pBssInfo->eConnectionState == + MEDIA_STATE_CONNECTED)) { + fgIsSkipThisBeacon = TRUE; + /* First Time. */ + if ((!prP2pBssInfo->ucDTIMPeriod)) { + prP2pBssInfo->ucDTIMPeriod = + prBssDesc->ucDTIMPeriod; + nicPmIndicateBssConnected( + prAdapter, + prP2pBssInfo->ucBssIndex); + } + } + + } + + } + + /* Skip report beacon to upper layer if no p2p scan */ + if (prAdapter->prGlueInfo->prP2PDevInfo->prScanRequest == NULL && + fgIsBeacon) + fgIsSkipThisBeacon = TRUE; + + if (fgIsBeacon && fgIsSkipThisBeacon) { + /* Only report Probe Response frame + * to supplicant except passive scan. + */ + /* Probe response collect + * much more information. + */ + DBGLOG(P2P, TRACE, "Skip beacon [" MACSTR "][%s][ch %d]\n", + MAC2STR(prWlanBeaconFrame->aucBSSID), + prBssDesc->aucSSID, + prBssDesc->ucChannelNum); + return; + } + + do { + struct RF_CHANNEL_INFO rChannelInfo; + + ASSERT_BREAK((prSwRfb != NULL) && (prBssDesc != NULL)); + + rChannelInfo.ucChannelNum = prBssDesc->ucChannelNum; + rChannelInfo.eBand = prBssDesc->eBand; + prBssDesc->fgIsP2PReport = TRUE; + + DBGLOG(P2P, INFO, + "indicate [" MACSTR "][%s][%s][ch %d][r %d][t %u]\n", + MAC2STR(prWlanBeaconFrame->aucBSSID), + fgIsBeacon ? "Beacon" : "Probe Response", + prBssDesc->aucSSID, + prBssDesc->ucChannelNum, + prBssDesc->ucRCPI, + prBssDesc->rUpdateTime); + + kalP2PIndicateBssInfo(prAdapter->prGlueInfo, + (uint8_t *) prSwRfb->pvHeader, + (uint32_t) prSwRfb->u2PacketLen, + &rChannelInfo, + RCPI_TO_dBm(prBssDesc->ucRCPI)); + + } while (FALSE); +} + +void scnEventReturnChannel(IN struct ADAPTER *prAdapter, + IN uint8_t ucScnSeqNum) +{ + + struct CMD_SCAN_CANCEL rCmdScanCancel; + + /* send cancel message to firmware domain */ + rCmdScanCancel.ucSeqNum = ucScnSeqNum; + rCmdScanCancel.ucIsExtChannel = (uint8_t) FALSE; + + wlanSendSetQueryCmd(prAdapter, + CMD_ID_SCAN_CANCEL, + TRUE, + FALSE, FALSE, NULL, NULL, + sizeof(struct CMD_SCAN_CANCEL), + (uint8_t *)&rCmdScanCancel, NULL, 0); +} /* scnEventReturnChannel */ + +void scanRemoveAllP2pBssDesc(IN struct ADAPTER *prAdapter) +{ + struct LINK *prBSSDescList; + struct BSS_DESC *prBssDesc; + struct BSS_DESC *prBSSDescNext; + + ASSERT(prAdapter); + + prBSSDescList = &(prAdapter->rWifiVar.rScanInfo.rBSSDescList); + + /* Search BSS Desc from current SCAN result list. */ + LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, + rLinkEntry, struct BSS_DESC) { + scanRemoveP2pBssDesc(prAdapter, prBssDesc); + } +} /* scanRemoveAllP2pBssDesc */ + +void scanRemoveP2pBssDesc(IN struct ADAPTER *prAdapter, + IN struct BSS_DESC *prBssDesc) +{ +} /* scanRemoveP2pBssDesc */ + +struct BSS_DESC *scanP2pSearchDesc(IN struct ADAPTER *prAdapter, + IN struct P2P_CONNECTION_REQ_INFO *prConnReqInfo) +{ + struct BSS_DESC *prCandidateBssDesc = (struct BSS_DESC *) NULL, + *prBssDesc = (struct BSS_DESC *) NULL; + struct LINK *prBssDescList = (struct LINK *) NULL; + + do { + if ((prAdapter == NULL) || (prConnReqInfo == NULL)) + break; + + prBssDescList = &(prAdapter->rWifiVar.rScanInfo.rBSSDescList); + + DBGLOG(P2P, LOUD, + "Connecting to BSSID: " MACSTR "\n", + MAC2STR(prConnReqInfo->aucBssid)); + DBGLOG(P2P, LOUD, + "Connecting to SSID:%s, length:%d\n", + HIDE(prConnReqInfo->rSsidStruct.aucSsid), + prConnReqInfo->rSsidStruct.ucSsidLen); + + LINK_FOR_EACH_ENTRY(prBssDesc, prBssDescList, + rLinkEntry, struct BSS_DESC) { + DBGLOG(P2P, LOUD, + "Checking BSS: " MACSTR "\n", + MAC2STR(prBssDesc->aucBSSID)); + + if (prBssDesc->eBSSType != BSS_TYPE_INFRASTRUCTURE) { + DBGLOG(P2P, LOUD, + "Ignore mismatch BSS type.\n"); + continue; + } + + if (UNEQUAL_MAC_ADDR(prBssDesc->aucBSSID, + prConnReqInfo->aucBssid)) { + DBGLOG(P2P, LOUD, "Ignore mismatch BSSID.\n"); + continue; + } + + /* SSID should be the same? + * SSID is vary for each connection. so... + */ + if (UNEQUAL_SSID(prConnReqInfo->rSsidStruct.aucSsid, + prConnReqInfo->rSsidStruct.ucSsidLen, + prBssDesc->aucSSID, + prBssDesc->ucSSIDLen)) { + + DBGLOG(P2P, TRACE, + "Connecting to BSSID: " MACSTR "\n", + MAC2STR(prConnReqInfo->aucBssid)); + DBGLOG(P2P, TRACE, + "Connecting to SSID:%s, length:%d\n", + HIDE( + prConnReqInfo->rSsidStruct.aucSsid), + prConnReqInfo->rSsidStruct.ucSsidLen); + DBGLOG(P2P, TRACE, + "Checking SSID:%s, length:%d\n", + HIDE(prBssDesc->aucSSID), + prBssDesc->ucSSIDLen); + DBGLOG(P2P, TRACE, + "Ignore mismatch SSID, (But BSSID match).\n"); + /* ASSERT(FALSE); *//*let p2p re-scan again */ + continue; + } + + if (!prBssDesc->fgIsP2PPresent) { + DBGLOG(P2P, ERROR, + "SSID, BSSID, BSSTYPE match, but no P2P IE present.\n"); +#if CFG_P2P_CONNECT_ALL_BSS + /* Force return */ +#else + continue; +#endif + } + + /* Final decision. */ + prCandidateBssDesc = prBssDesc; + break; + } + + } while (FALSE); + + return prCandidateBssDesc; +} /* scanP2pSearchDesc */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/privacy.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/privacy.c new file mode 100644 index 0000000000000000000000000000000000000000..784152ebbab927035c3721a56c616a083b85cc35 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/privacy.c @@ -0,0 +1,1440 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: mgmt/privacy.c#1 + */ + +/*! \file "privacy.c" + * \brief This file including the protocol layer privacy function. + * + * This file provided the macros and functions library support for the + * protocol layer security setting from rsn.c and nic_privacy.c + * + */ + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to initialize the privacy-related + * parameters. + * + * \param[in] prAdapter Pointer to the Adapter structure + * \param[in] ucNetTypeIdx Pointer to netowrk type index + * + * \retval NONE + */ +/*----------------------------------------------------------------------------*/ +void secInit(IN struct ADAPTER *prAdapter, IN uint8_t ucBssIndex) +{ + uint8_t i; + struct CONNECTION_SETTINGS *prConnSettings; + struct BSS_INFO *prBssInfo; + struct AIS_SPECIFIC_BSS_INFO *prAisSpecBssInfo; + struct IEEE_802_11_MIB *prMib; + + DEBUGFUNC("secInit"); + + prConnSettings = aisGetConnSettings(prAdapter, ucBssIndex); + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + prAisSpecBssInfo = + aisGetAisSpecBssInfo(prAdapter, ucBssIndex); + prMib = aisGetMib(prAdapter, ucBssIndex); + + prBssInfo->u4RsnSelectedGroupCipher = 0; + prBssInfo->u4RsnSelectedPairwiseCipher = 0; + prBssInfo->u4RsnSelectedAKMSuite = 0; + +#if 0 /* CFG_ENABLE_WIFI_DIRECT */ + prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P]; + + prBssInfo->u4RsnSelectedGroupCipher = RSN_CIPHER_SUITE_CCMP; + prBssInfo->u4RsnSelectedPairwiseCipher = RSN_CIPHER_SUITE_CCMP; + prBssInfo->u4RsnSelectedAKMSuite = RSN_AKM_SUITE_PSK; +#endif + +#if 0 /* CFG_ENABLE_BT_OVER_WIFI */ + prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW]; + + prBssInfo->u4RsnSelectedGroupCipher = RSN_CIPHER_SUITE_CCMP; + prBssInfo->u4RsnSelectedPairwiseCipher = RSN_CIPHER_SUITE_CCMP; + prBssInfo->u4RsnSelectedAKMSuite = RSN_AKM_SUITE_PSK; +#endif + + prMib-> + dot11RSNAConfigPairwiseCiphersTable[0].dot11RSNAConfigPairwiseCipher + = WPA_CIPHER_SUITE_WEP40; + prMib-> + dot11RSNAConfigPairwiseCiphersTable[1].dot11RSNAConfigPairwiseCipher + = WPA_CIPHER_SUITE_TKIP; + prMib-> + dot11RSNAConfigPairwiseCiphersTable[2].dot11RSNAConfigPairwiseCipher + = WPA_CIPHER_SUITE_CCMP; + prMib-> + dot11RSNAConfigPairwiseCiphersTable[3].dot11RSNAConfigPairwiseCipher + = WPA_CIPHER_SUITE_WEP104; + + prMib-> + dot11RSNAConfigPairwiseCiphersTable[4].dot11RSNAConfigPairwiseCipher + = RSN_CIPHER_SUITE_WEP40; + prMib-> + dot11RSNAConfigPairwiseCiphersTable[5].dot11RSNAConfigPairwiseCipher + = RSN_CIPHER_SUITE_TKIP; + prMib-> + dot11RSNAConfigPairwiseCiphersTable[6].dot11RSNAConfigPairwiseCipher + = RSN_CIPHER_SUITE_CCMP; + prMib-> + dot11RSNAConfigPairwiseCiphersTable[7].dot11RSNAConfigPairwiseCipher + = RSN_CIPHER_SUITE_WEP104; + prMib-> + dot11RSNAConfigPairwiseCiphersTable[8].dot11RSNAConfigPairwiseCipher + = RSN_CIPHER_SUITE_GROUP_NOT_USED; + prMib-> + dot11RSNAConfigPairwiseCiphersTable[9].dot11RSNAConfigPairwiseCipher + = RSN_CIPHER_SUITE_GCMP_256; + + for (i = 0; i < MAX_NUM_SUPPORTED_CIPHER_SUITES; i++) + prMib->dot11RSNAConfigPairwiseCiphersTable + [i].dot11RSNAConfigPairwiseCipherEnabled = FALSE; + + prMib->dot11RSNAConfigAuthenticationSuitesTable + [0].dot11RSNAConfigAuthenticationSuite = WPA_AKM_SUITE_NONE; + prMib->dot11RSNAConfigAuthenticationSuitesTable + [1].dot11RSNAConfigAuthenticationSuite = WPA_AKM_SUITE_802_1X; + prMib->dot11RSNAConfigAuthenticationSuitesTable + [2].dot11RSNAConfigAuthenticationSuite = WPA_AKM_SUITE_PSK; + prMib->dot11RSNAConfigAuthenticationSuitesTable + [3].dot11RSNAConfigAuthenticationSuite = RSN_AKM_SUITE_NONE; + prMib->dot11RSNAConfigAuthenticationSuitesTable + [4].dot11RSNAConfigAuthenticationSuite = RSN_AKM_SUITE_802_1X; + prMib->dot11RSNAConfigAuthenticationSuitesTable + [5].dot11RSNAConfigAuthenticationSuite = RSN_AKM_SUITE_PSK; + + prMib->dot11RSNAConfigAuthenticationSuitesTable + [6].dot11RSNAConfigAuthenticationSuite = RSN_AKM_SUITE_FT_802_1X; + prMib->dot11RSNAConfigAuthenticationSuitesTable + [7].dot11RSNAConfigAuthenticationSuite = RSN_AKM_SUITE_FT_PSK; + prMib->dot11RSNAConfigAuthenticationSuitesTable + [8].dot11RSNAConfigAuthenticationSuite = WFA_AKM_SUITE_OSEN; + +#if CFG_SUPPORT_802_11W + prMib->dot11RSNAConfigAuthenticationSuitesTable + [9].dot11RSNAConfigAuthenticationSuite = + RSN_AKM_SUITE_802_1X_SHA256; + prMib->dot11RSNAConfigAuthenticationSuitesTable + [10].dot11RSNAConfigAuthenticationSuite = RSN_AKM_SUITE_PSK_SHA256; + prMib->dot11RSNAConfigAuthenticationSuitesTable + [11].dot11RSNAConfigAuthenticationSuite = RSN_AKM_SUITE_SAE; + prMib->dot11RSNAConfigAuthenticationSuitesTable + [12].dot11RSNAConfigAuthenticationSuite = RSN_AKM_SUITE_OWE; +#endif + + for (i = 0; i < MAX_NUM_SUPPORTED_AKM_SUITES; i++) { + prMib->dot11RSNAConfigAuthenticationSuitesTable + [i].dot11RSNAConfigAuthenticationSuiteEnabled = FALSE; + } + +#if CFG_SUPPORT_802_11W + cnmTimerInitTimer(prAdapter, + &prAisSpecBssInfo->rSaQueryTimer, + (PFN_MGMT_TIMEOUT_FUNC) rsnStartSaQueryTimer, + (unsigned long)ucBssIndex); +#endif + + prAisSpecBssInfo->fgCounterMeasure = FALSE; + prBssInfo->ucBcDefaultKeyIdx = 0xff; + prBssInfo->fgBcDefaultKeyExist = FALSE; + +#if 0 + for (i = 0; i < WTBL_SIZE; i++) { + g_prWifiVar->arWtbl[i].ucUsed = FALSE; + g_prWifiVar->arWtbl[i].prSta = NULL; + g_prWifiVar->arWtbl[i].ucNetTypeIdx = NETWORK_TYPE_INDEX_NUM; + + } + nicPrivacyInitialize((uint8_t) NETWORK_TYPE_INDEX_NUM); +#endif + +} /* secInit */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function will indicate an Event of "Rx Class Error" to SEC_FSM + * for JOIN Module. + * + * \param[in] prAdapter Pointer to the Adapter structure + * \param[in] prSwRfb Pointer to the SW RFB. + * + * \return FALSE Class Error + */ +/*----------------------------------------------------------------------------*/ +u_int8_t secCheckClassError(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, + IN struct STA_RECORD *prStaRec) +{ + void *prRxStatus; + struct RX_DESC_OPS_T *prRxDescOps; + + prRxDescOps = prAdapter->chip_info->prRxDescOps; + prRxStatus = prSwRfb->prRxStatus; + + if (prRxDescOps->nic_rxd_get_sw_class_error_bit(prRxStatus) + || (IS_STA_IN_AIS(prStaRec) + && aisGetAisBssInfo(prAdapter, + prStaRec->ucBssIndex)->eConnectionState == + MEDIA_STATE_DISCONNECTED)) { + + DBGLOG_LIMITED(RSN, WARN, + "RX_CLASSERR: prStaRec=%p PktTYpe=0x%x, WlanIdx=%d,", + prStaRec, + prSwRfb->ucPacketType, prSwRfb->ucWlanIdx); + DBGLOG_LIMITED(RSN, WARN, + "StaRecIdx=%d, eDst=%d, prStaRec->eStaType=%d\n", + prSwRfb->ucStaRecIdx, + prSwRfb->eDst, prStaRec->eStaType); + + DBGLOG_MEM8(RX, ERROR, prSwRfb->pucRecvBuff, + (prSwRfb->u2RxByteCount > 64) ? 64 : + prSwRfb->u2RxByteCount); + + if (prSwRfb->ucGroupVLD & BIT(RX_GROUP_VLD_4)) { + DBGLOG(RX, ERROR, + "secchk:%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", + prSwRfb->prRxStatusGroup4->u2FrameCtl, + prSwRfb->prRxStatusGroup4->aucTA[0], + prSwRfb->prRxStatusGroup4->aucTA[1], + prSwRfb->prRxStatusGroup4->aucTA[2], + prSwRfb->prRxStatusGroup4->aucTA[3], + prSwRfb->prRxStatusGroup4->aucTA[4], + prSwRfb->prRxStatusGroup4->aucTA[5], + prSwRfb->prRxStatusGroup4->u2SeqFrag, + prSwRfb->prRxStatusGroup4->u2Qos, + prSwRfb->prRxStatusGroup4->u4HTC); + } + + if (EAPOL_KEY_NOT_KEY != + secGetEapolKeyType((uint8_t *) prSwRfb->pvHeader)) { + DBGLOG(RSN, WARN, + "EAPOL key found, return TRUE back"); + + return TRUE; + } + + /* if (IS_NET_ACTIVE(prAdapter, ucBssIndex)) { */ + authSendDeauthFrame(prAdapter, + NULL, NULL, prSwRfb, + REASON_CODE_CLASS_3_ERR, + (PFN_TX_DONE_HANDLER) NULL); + return FALSE; + /* } */ + } + + return TRUE; + +} /* end of secCheckClassError() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used to setting the sta port status. + * + * \param[in] prAdapter Pointer to the Adapter structure + * \param[in] prSta Pointer to the sta + * \param[in] fgPortBlock The port status + * + * \retval none + * + */ +/*----------------------------------------------------------------------------*/ +void secSetPortBlocked(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prSta, IN u_int8_t fgPortBlock) +{ +#if 0 /* Marked for MT6630 */ + if (prSta == NULL) + return; + + prSta->fgPortBlock = fgPortBlock; + + DBGLOG(RSN, TRACE, + "The STA " MACSTR " port %s\n", MAC2STR(prSta->aucMacAddr), + fgPortBlock == TRUE ? "BLOCK" : " OPEN"); +#endif +} + +#if 0 /* Marked for MT6630 */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used to report the sta port status. + * + * \param[in] prAdapter Pointer to the Adapter structure + * \param[in] prSta Pointer to the sta + * \param[out] fgPortBlock The port status + * + * \return TRUE sta exist, FALSE sta not exist + * + */ +/*----------------------------------------------------------------------------*/ +u_int8_t secGetPortStatus(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prSta, + OUT u_int8_t *pfgPortStatus) +{ + if (prSta == NULL) + return FALSE; + + *pfgPortStatus = prSta->fgPortBlock; + + return TRUE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to handle Peer device Tx Security process MSDU. + * + * \param[in] prMsduInfo pointer to the packet info pointer + * + * \retval TRUE Accept the packet + * \retval FALSE Refuse the MSDU packet due port blocked + * + */ +/*----------------------------------------------------------------------------*/ +u_int8_t /* ENUM_PORT_CONTROL_RESULT */ +secTxPortControlCheck(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN struct STA_RECORD *prStaRec) +{ + ASSERT(prAdapter); + ASSERT(prMsduInfo); + ASSERT(prStaRec); + + if (prStaRec) { + + /* Todo:: */ + if (prMsduInfo->fgIs802_1x) + return TRUE; + + if (prStaRec->fgPortBlock == TRUE) { + DBGLOG(INIT, TRACE, + "Drop Tx packet due Port Control!\n"); + return FALSE; + } +#if CFG_SUPPORT_WAPI + if (prAdapter->rWifiVar.rConnSettings.fgWapiMode) + return TRUE; +#endif + if (IS_STA_IN_AIS(prStaRec)) { + if (!prAdapter->rWifiVar. + rAisSpecificBssInfo.fgTransmitKeyExist + && (prAdapter->rWifiVar.rConnSettings.eEncStatus == + ENUM_ENCRYPTION1_ENABLED)) { + DBGLOG(INIT, TRACE, + "Drop Tx packet due the key is removed!!!\n"); + return FALSE; + } + } + } + + return TRUE; +} +#endif /* Marked for MT6630 */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to handle The Rx Security process MSDU. + * + * \param[in] prAdapter Pointer to the Adapter structure + * \param[in] prSWRfb SW rfb pinter + * + * \retval TRUE Accept the packet + * \retval FALSE Refuse the MSDU packet due port control + */ +/*----------------------------------------------------------------------------*/ +u_int8_t secRxPortControlCheck(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSWRfb) +{ + ASSERT(prSWRfb); + + return TRUE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine will enable/disable the cipher suite + * + * \param[in] prAdapter Pointer to the adapter object data area. + * \param[in] u4CipherSuitesFlags flag for cipher suite + * + * \retval none + */ +/*----------------------------------------------------------------------------*/ +void secSetCipherSuite(IN struct ADAPTER *prAdapter, + IN uint32_t u4CipherSuitesFlags, + IN uint8_t ucBssIndex) +{ + + uint32_t i; + struct DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY *prEntry; + struct IEEE_802_11_MIB *prMib; + + prMib = aisGetMib(prAdapter, ucBssIndex); + + if (u4CipherSuitesFlags == CIPHER_FLAG_NONE) { + /* Disable all the pairwise cipher suites. */ + for (i = 0; i < MAX_NUM_SUPPORTED_CIPHER_SUITES; i++) + prMib->dot11RSNAConfigPairwiseCiphersTable + [i].dot11RSNAConfigPairwiseCipherEnabled = FALSE; + + /* Update the group cipher suite. */ + prMib->dot11RSNAConfigGroupCipher = WPA_CIPHER_SUITE_NONE; + + return; + } + + for (i = 0; i < MAX_NUM_SUPPORTED_CIPHER_SUITES; i++) { + prEntry = &prMib->dot11RSNAConfigPairwiseCiphersTable[i]; + + switch (prEntry->dot11RSNAConfigPairwiseCipher) { + case RSN_CIPHER_SUITE_GCMP_256: + if (u4CipherSuitesFlags & CIPHER_FLAG_GCMP256) + prEntry->dot11RSNAConfigPairwiseCipherEnabled = + TRUE; + else + prEntry->dot11RSNAConfigPairwiseCipherEnabled = + FALSE; + break; + + case WPA_CIPHER_SUITE_WEP40: + case RSN_CIPHER_SUITE_WEP40: + if (u4CipherSuitesFlags & CIPHER_FLAG_WEP40) + prEntry->dot11RSNAConfigPairwiseCipherEnabled = + TRUE; + else + prEntry->dot11RSNAConfigPairwiseCipherEnabled = + FALSE; + break; + + case WPA_CIPHER_SUITE_TKIP: + case RSN_CIPHER_SUITE_TKIP: + if (u4CipherSuitesFlags & CIPHER_FLAG_TKIP) + prEntry->dot11RSNAConfigPairwiseCipherEnabled = + TRUE; + else + prEntry->dot11RSNAConfigPairwiseCipherEnabled = + FALSE; + break; + + case WPA_CIPHER_SUITE_CCMP: + case RSN_CIPHER_SUITE_CCMP: + if (u4CipherSuitesFlags & CIPHER_FLAG_CCMP) + prEntry->dot11RSNAConfigPairwiseCipherEnabled = + TRUE; + else + prEntry->dot11RSNAConfigPairwiseCipherEnabled = + FALSE; + break; + + case RSN_CIPHER_SUITE_GROUP_NOT_USED: + if (u4CipherSuitesFlags & + (CIPHER_FLAG_CCMP | CIPHER_FLAG_TKIP)) + prEntry->dot11RSNAConfigPairwiseCipherEnabled = + TRUE; + else + prEntry->dot11RSNAConfigPairwiseCipherEnabled = + FALSE; + break; + + case WPA_CIPHER_SUITE_WEP104: + case RSN_CIPHER_SUITE_WEP104: + if (u4CipherSuitesFlags & CIPHER_FLAG_WEP104) + prEntry->dot11RSNAConfigPairwiseCipherEnabled = + TRUE; + else + prEntry->dot11RSNAConfigPairwiseCipherEnabled = + FALSE; + break; + default: + break; + } + } + + /* Update the group cipher suite. */ + if (rsnSearchSupportedCipher(prAdapter, + WPA_CIPHER_SUITE_CCMP, &i, ucBssIndex)) + prMib->dot11RSNAConfigGroupCipher = WPA_CIPHER_SUITE_CCMP; + else if (rsnSearchSupportedCipher(prAdapter, + WPA_CIPHER_SUITE_TKIP, &i, ucBssIndex)) + prMib->dot11RSNAConfigGroupCipher = WPA_CIPHER_SUITE_TKIP; + else if (rsnSearchSupportedCipher(prAdapter, + WPA_CIPHER_SUITE_WEP104, &i, ucBssIndex)) + prMib->dot11RSNAConfigGroupCipher = WPA_CIPHER_SUITE_WEP104; + else if (rsnSearchSupportedCipher(prAdapter, + WPA_CIPHER_SUITE_WEP40, &i, ucBssIndex)) + prMib->dot11RSNAConfigGroupCipher = WPA_CIPHER_SUITE_WEP40; + else if (rsnSearchSupportedCipher(prAdapter, + RSN_CIPHER_SUITE_GROUP_NOT_USED, &i, ucBssIndex)) + prMib->dot11RSNAConfigGroupCipher = + RSN_CIPHER_SUITE_GROUP_NOT_USED; + else if (rsnSearchSupportedCipher(prAdapter, + RSN_CIPHER_SUITE_GCMP_256, &i, ucBssIndex)) + prMib->dot11RSNAConfigGroupCipher = + RSN_CIPHER_SUITE_GCMP_256; + else + prMib->dot11RSNAConfigGroupCipher = WPA_CIPHER_SUITE_NONE; + +} /* secSetCipherSuite */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Whether 802.11 privacy is enabled. + * + * \param[in] prAdapter Pointer to the Adapter structure + * + * \retval BOOLEAN + */ +/*----------------------------------------------------------------------------*/ +u_int8_t secEnabledInAis(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) +{ + enum ENUM_WEP_STATUS eEncStatus; + + eEncStatus = aisGetEncStatus(prAdapter, ucBssIndex); + + DEBUGFUNC("secEnabledInAis"); + + switch (eEncStatus) { + case ENUM_ENCRYPTION_DISABLED: + return FALSE; + case ENUM_ENCRYPTION1_ENABLED: + case ENUM_ENCRYPTION2_ENABLED: + case ENUM_ENCRYPTION3_ENABLED: + case ENUM_ENCRYPTION4_ENABLED: + return TRUE; + default: + DBGLOG(RSN, TRACE, "Unknown encryption setting %d\n", + eEncStatus); + break; + } + return FALSE; + +} /* secEnabledInAis */ + +u_int8_t secIsProtected1xFrame(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec) +{ + struct BSS_INFO *prBssInfo; + + if (prStaRec) { + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prStaRec->ucBssIndex); + if (prBssInfo && prBssInfo->eNetworkType == NETWORK_TYPE_AIS) { +#if CFG_SUPPORT_WAPI + if (aisGetWapiMode(prAdapter, + prStaRec->ucBssIndex)) + return FALSE; +#endif + } + + return prStaRec->fgTransmitKeyExist; + } + return FALSE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set the privacy bit at mac header for TxM + * + * \param[in] prAdapter Pointer to the Adapter structure + * \param[in] prMsdu the msdu for known the sta record + * + * \return TRUE the privacy need to set + * FALSE the privacy no need to set + */ +/*----------------------------------------------------------------------------*/ +u_int8_t secIsProtectedFrame(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsdu, + IN struct STA_RECORD *prStaRec) +{ +#if CFG_SUPPORT_802_11W + if (rsnCheckBipKeyInstalled(prAdapter, prStaRec) && + (secIsRobustActionFrame(prAdapter, prMsdu->prPacket) + || (IS_BSS_INDEX_AIS(prAdapter, prMsdu->ucBssIndex) && + secIsRobustMgmtFrame(prAdapter, prMsdu->prPacket)))) + return TRUE; +#endif + if (prMsdu->ucPacketType == TX_PACKET_TYPE_MGMT) + return FALSE; + + return secIsProtectedBss(prAdapter, + GET_BSS_INFO_BY_INDEX(prAdapter, + prMsdu->ucBssIndex)); +} + +u_int8_t secIsProtectedBss(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo) +{ + uint8_t ucBssIndex = 0; + + ucBssIndex = prBssInfo->ucBssIndex; + + if (prBssInfo->eNetworkType == NETWORK_TYPE_AIS) { +#if CFG_SUPPORT_WAPI + if (aisGetWapiMode(prAdapter, ucBssIndex)) + return TRUE; +#endif + return secEnabledInAis(prAdapter, + ucBssIndex); + } +#if CFG_ENABLE_WIFI_DIRECT + else if (prBssInfo->eNetworkType == NETWORK_TYPE_P2P) + return kalP2PGetCipher(prAdapter->prGlueInfo, + (uint8_t) prBssInfo->u4PrivateData); +#endif + else if (prBssInfo->eNetworkType == NETWORK_TYPE_BOW) + return TRUE; + + return FALSE; +} + +u_int8_t secIsRobustMgmtFrame(IN struct ADAPTER *prAdapter, IN void *prPacket) +{ + struct WLAN_MAC_HEADER *prWlanHeader = NULL; + uint16_t u2TxFrameCtrl; + + if (!prPacket) + return FALSE; + + prWlanHeader = (struct WLAN_MAC_HEADER *) + ((unsigned long) prPacket + MAC_TX_RESERVED_FIELD); + u2TxFrameCtrl = prWlanHeader->u2FrameCtrl & MASK_FRAME_TYPE; + if (u2TxFrameCtrl == MAC_FRAME_DISASSOC + || u2TxFrameCtrl == MAC_FRAME_DEAUTH) + return TRUE; + return FALSE; +} + +u_int8_t secIsRobustActionFrame(IN struct ADAPTER *prAdapter, IN void *prPacket) +{ + struct WLAN_MAC_HEADER *prWlanHeader = NULL; + struct WLAN_ACTION_FRAME *prActFrame = NULL; + uint8_t ucCategory; + uint16_t u2TxFrameCtrl; + + if (!prPacket) + return FALSE; + + prWlanHeader = (struct WLAN_MAC_HEADER *) + ((unsigned long) prPacket + MAC_TX_RESERVED_FIELD); + u2TxFrameCtrl = prWlanHeader->u2FrameCtrl & MASK_FRAME_TYPE; + if (u2TxFrameCtrl != MAC_FRAME_ACTION) + return FALSE; + + prActFrame = (struct WLAN_ACTION_FRAME *)prWlanHeader; + ucCategory = prActFrame->ucCategory; + return ucCategory == CATEGORY_SPEC_MGT || + ucCategory == CATEGORY_QOS_ACTION || + ucCategory == CATEGORY_DLS_ACTION || + ucCategory == CATEGORY_BLOCK_ACK_ACTION || + ucCategory == CATEGORY_RM_ACTION || + ucCategory == CATEGORY_FT_ACTION || + ucCategory == CATEGORY_SA_QUERY_ACTION || + ucCategory == CATEGORY_PROTECTED_DUAL_OF_PUBLIC_ACTION || + ucCategory == CATEGORY_WNM_ACTION || + ucCategory == CATEGORY_TDLS_ACTION || + ucCategory == CATEGORY_MESH_ACTION || + ucCategory == CATEGORY_MULTIHOP_ACTION || + ucCategory == CATEGORY_DMG_ACTION || + ucCategory == CATEGORY_FST_ACTION || + ucCategory == CATEGORY_ROBUST_AV_STREAMING_ACTION || + ucCategory == CATEGORY_VENDOR_SPECIFIC_PROTECTED_ACTION + ? TRUE : FALSE; +} + +u_int8_t secIsWepBss(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo) +{ + enum ENUM_WEP_STATUS eEncStatus; + + eEncStatus = aisGetEncStatus(prAdapter, + prBssInfo->ucBssIndex); + + if (prBssInfo->eNetworkType == NETWORK_TYPE_AIS) { + if (eEncStatus == + ENUM_ENCRYPTION1_ENABLED) + return TRUE; + } +#if CFG_ENABLE_WIFI_DIRECT + else if (prBssInfo->eNetworkType == NETWORK_TYPE_P2P) + return kalP2PGetWepCipher(prAdapter->prGlueInfo, + (uint8_t) prBssInfo->u4PrivateData); +#endif + + return FALSE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used before add/update a WLAN entry. + * Info the WLAN Table has available entry for this request + * + * \param[in] prAdapter Pointer to the Adapter structure + * \param[in] prSta the P_STA_RECORD_T for store + * + * \return TRUE Free Wlan table is reserved for this request + * FALSE No free entry for this request + * + * \note + */ +/*----------------------------------------------------------------------------*/ +u_int8_t secPrivacySeekForEntry( + IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prSta) +{ + struct BSS_INFO *prP2pBssInfo; + uint8_t ucEntry = WTBL_RESERVED_ENTRY; + uint8_t i; + uint8_t ucStartIDX = 0, ucMaxIDX = 0; + struct WLAN_TABLE *prWtbl; + uint8_t ucRoleIdx = 0; + + if (!prSta->fgIsInUse) { + DBGLOG(RSN, ERROR, "sta is not in use\n"); + return FALSE; + } + + prP2pBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prSta->ucBssIndex); + ucRoleIdx = prP2pBssInfo->u4PrivateData; + + prWtbl = prAdapter->rWifiVar.arWtbl; + + ucStartIDX = 0; + ucMaxIDX = prAdapter->ucTxDefaultWlanIndex - 1; + + for (i = ucStartIDX; i <= ucMaxIDX; i++) { +#if CFG_WIFI_SW_WTBL_SEARCH_FAIL + if (i % 8 == 0) + continue; +#endif + if (prWtbl[i].ucUsed + && EQUAL_MAC_ADDR(prSta->aucMacAddr, prWtbl[i].aucMacAddr) + && prWtbl[i].ucPairwise + /* This function for ucPairwise only */ + && prWtbl[i].ucBssIndex == prSta->ucBssIndex) { + ucEntry = i; + DBGLOG(RSN, TRACE, + "[Wlan index]: Reuse entry #%d\n", i); + break; + } + } + + if (i == (ucMaxIDX + 1)) { + for (i = ucStartIDX; i <= ucMaxIDX; i++) { +#if CFG_WIFI_SW_WTBL_SEARCH_FAIL + if (i % 8 == 0) + continue; +#endif + if (prWtbl[i].ucUsed == FALSE) { + ucEntry = i; + DBGLOG(RSN, TRACE, + "[Wlan index]: Assign entry #%d\n", i); + break; + } + } + } + + /* Save to the driver maintain table */ + if (ucEntry < prAdapter->ucTxDefaultWlanIndex) { + + prWtbl[ucEntry].ucUsed = TRUE; + prWtbl[ucEntry].ucBssIndex = prSta->ucBssIndex; + prWtbl[ucEntry].ucKeyId = 0xFF; + prWtbl[ucEntry].ucPairwise = 1; + COPY_MAC_ADDR(prWtbl[ucEntry].aucMacAddr, prSta->aucMacAddr); + prWtbl[ucEntry].ucStaIndex = prSta->ucIndex; + + prSta->ucWlanIndex = ucEntry; + + { + struct BSS_INFO *prBssInfo = + GET_BSS_INFO_BY_INDEX(prAdapter, prSta->ucBssIndex); + /* for AP mode , if wep key exist, peer sta should also + * fgTransmitKeyExist + */ + if (IS_BSS_P2P(prBssInfo) + && kalP2PGetRole(prAdapter->prGlueInfo, + ucRoleIdx) == 2) { + if (prBssInfo->fgBcDefaultKeyExist + && + !(kalP2PGetCcmpCipher + (prAdapter->prGlueInfo, ucRoleIdx) + || + kalP2PGetTkipCipher(prAdapter->prGlueInfo, + ucRoleIdx))) { + prSta->fgTransmitKeyExist = TRUE; + prWtbl[ucEntry].ucKeyId = + prBssInfo->ucBcDefaultKeyIdx; + DBGLOG(RSN, INFO, + "peer sta set fgTransmitKeyExist\n"); + } + } + } + + DBGLOG(RSN, INFO, + "[Wlan index] BSS#%d keyid#%d P=%d use WlanIndex#%d STAIdx=%d " + MACSTR + " staType=%x\n", prSta->ucBssIndex, 0, + prWtbl[ucEntry].ucPairwise, ucEntry, + prSta->ucIndex, MAC2STR(prSta->aucMacAddr), + prSta->eStaType); +#if 1 /* DBG */ + secCheckWTBLAssign(prAdapter); +#endif + return TRUE; + } +#if DBG + secCheckWTBLAssign(prAdapter); +#endif + DBGLOG(RSN, WARN, + "[Wlan index] No more wlan table entry available!!!!\n"); + return FALSE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used free a WLAN entry. + * + * \param[in] prAdapter Pointer to the Adapter structure + * \param[in] ucEntry the wlan table index to free + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void secPrivacyFreeForEntry(IN struct ADAPTER *prAdapter, IN uint8_t ucEntry) +{ + struct WLAN_TABLE *prWtbl; + + if (ucEntry >= WTBL_SIZE) + return; + + DBGLOG(RSN, TRACE, "secPrivacyFreeForEntry %d", ucEntry); + + prWtbl = prAdapter->rWifiVar.arWtbl; + + if (prWtbl[ucEntry].ucUsed) { + prWtbl[ucEntry].ucUsed = FALSE; + prWtbl[ucEntry].ucKeyId = 0xff; + prWtbl[ucEntry].ucBssIndex = prAdapter->ucHwBssIdNum + 1; + prWtbl[ucEntry].ucPairwise = 0; + kalMemZero(prWtbl[ucEntry].aucMacAddr, MAC_ADDR_LEN); + prWtbl[ucEntry].ucStaIndex = STA_REC_INDEX_NOT_FOUND; + } + +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used free a STA WLAN entry. + * + * \param[in] prAdapter Pointer to the Adapter structure + * \param[in] prStaRec the sta which want to free + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void secPrivacyFreeSta(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec) +{ + uint32_t entry; + struct WLAN_TABLE *prWtbl; + + if (!prStaRec) + return; + + prWtbl = prAdapter->rWifiVar.arWtbl; + + for (entry = 0; entry < WTBL_SIZE; entry++) { + /* Consider GTK case !! */ + if (prWtbl[entry].ucUsed && + EQUAL_MAC_ADDR(prStaRec->aucMacAddr, + prWtbl[entry].aucMacAddr) + && prWtbl[entry].ucPairwise + && prWtbl[entry].ucBssIndex == prStaRec->ucBssIndex) { +#if 1 /* DBG */ + DBGLOG(RSN, INFO, "Free STA entry (%d)!\n", entry); +#endif + secPrivacyFreeForEntry(prAdapter, entry); + prStaRec->ucWlanIndex = WTBL_RESERVED_ENTRY; + /* prStaRec->ucBMCWlanIndex = WTBL_RESERVED_ENTRY; */ + } + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used for remove the BC entry of the BSS + * + * \param[in] prAdapter Pointer to the Adapter structure + * \param[in] ucBssIndex The BSS index + * + * \note + */ +/*----------------------------------------------------------------------------*/ +void secRemoveBssBcEntry(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo, IN u_int8_t fgRoam) +{ + int i; + + if (!prBssInfo) + return; + + DBGLOG_LIMITED(RSN, TRACE, "remove all the key related with BSS!"); + + if (fgRoam) { + struct CONNECTION_SETTINGS *prConnSettings = + aisGetConnSettings(prAdapter, + prBssInfo->ucBssIndex); + + if (IS_BSS_AIS(prBssInfo) && + prBssInfo->prStaRecOfAP + && (prConnSettings->eAuthMode >= AUTH_MODE_WPA && + prConnSettings->eAuthMode != AUTH_MODE_WPA_NONE)) { + + for (i = 0; i < MAX_KEY_NUM; i++) { + if (prBssInfo->ucBMCWlanIndexSUsed[i]) + secPrivacyFreeForEntry(prAdapter, + prBssInfo->ucBMCWlanIndexS[i]); + + prBssInfo->ucBMCWlanIndexSUsed[i] = FALSE; + prBssInfo->ucBMCWlanIndexS[i] = WTBL_RESERVED_ENTRY; + + } + + prBssInfo->fgBcDefaultKeyExist = FALSE; + prBssInfo->ucBcDefaultKeyIdx = 0xff; + } + } else { + /* According to discussion, it's ok to change to + * reserved_entry here so that the entry is _NOT_ freed at all. + * In this way, the same BSS(ucBssIndex) could reuse the same + * entry next time in secPrivacySeekForBcEntry(), and we could + * see the following log: "[Wlan index]: Reuse entry ...". + */ + prBssInfo->ucBMCWlanIndex = WTBL_RESERVED_ENTRY; + secPrivacyFreeForEntry(prAdapter, prBssInfo->ucBMCWlanIndex); + + for (i = 0; i < MAX_KEY_NUM; i++) { + if (prBssInfo->ucBMCWlanIndexSUsed[i]) + secPrivacyFreeForEntry(prAdapter, + prBssInfo->ucBMCWlanIndexS[i]); + + } + for (i = 0; i < MAX_KEY_NUM; i++) { + if (prBssInfo->wepkeyUsed[i]) + secPrivacyFreeForEntry(prAdapter, + prBssInfo->wepkeyWlanIdx); + } + prBssInfo->fgBcDefaultKeyExist = FALSE; + prBssInfo->ucBcDefaultKeyIdx = 0xff; + } + +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used for adding the broadcast key used, to assign + * a wlan table entry for reserved the specific entry for these key for + * + * \param[in] prAdapter Pointer to the Adapter structure + * \param[in] ucBssIndex The BSS index + * \param[in] ucNetTypeIdx The Network index + * \param[in] ucAlg the entry assign related with algorithm + * \param[in] ucKeyId The key id + * \param[in] ucTxRx The Type of the key + * + * \return ucEntryIndex The entry to be used, WTBL_ALLOC_FAIL for allocation + * fail + * + * \note + */ +/*----------------------------------------------------------------------------*/ +uint8_t +secPrivacySeekForBcEntry(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN uint8_t *pucAddr, IN uint8_t ucStaIdx, + IN uint8_t ucAlg, IN uint8_t ucKeyId) +{ + uint8_t ucEntry = WTBL_ALLOC_FAIL; + uint8_t ucStartIDX = 0, ucMaxIDX = 0; + uint8_t i; + u_int8_t fgCheckKeyId = TRUE; + struct WLAN_TABLE *prWtbl; + struct BSS_INFO *prBSSInfo = + GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + + prWtbl = prAdapter->rWifiVar.arWtbl; + + if (ucAlg == CIPHER_SUITE_WPI || /* CIPHER_SUITE_GCM_WPI || */ + ucAlg == CIPHER_SUITE_WEP40 || + ucAlg == CIPHER_SUITE_WEP104 + || ucAlg == CIPHER_SUITE_WEP128 || ucAlg == CIPHER_SUITE_NONE) + fgCheckKeyId = FALSE; + + if (ucKeyId == 0xFF || ucAlg == CIPHER_SUITE_BIP) + fgCheckKeyId = FALSE; + + if (prBSSInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) + fgCheckKeyId = FALSE; + + ucStartIDX = 0; + ucMaxIDX = prAdapter->ucTxDefaultWlanIndex - 1; + + DBGLOG_LIMITED(INIT, INFO, "OpMode:%d, NetworkType:%d, CheckKeyId:%d\n", + prBSSInfo->eCurrentOPMode, prBSSInfo->eNetworkType, + fgCheckKeyId); + + for (i = ucStartIDX; i <= ucMaxIDX; i++) { + + if (prWtbl[i].ucUsed && !prWtbl[i].ucPairwise + && prWtbl[i].ucBssIndex == ucBssIndex) { + + if (!fgCheckKeyId) { + ucEntry = i; + DBGLOG(RSN, TRACE, + "[Wlan index]: Reuse entry #%d for open/wep/wpi\n", + i); + break; + } + + if (fgCheckKeyId && (prWtbl[i].ucKeyId == ucKeyId + || prWtbl[i].ucKeyId == 0xFF)) { + ucEntry = i; + DBGLOG(RSN, TRACE, + "[Wlan index]: Reuse entry #%d\n", i); + break; + } + } + } + + if (i == (ucMaxIDX + 1)) { + for (i = ucStartIDX; i <= ucMaxIDX; i++) { + if (prWtbl[i].ucUsed == FALSE) { + ucEntry = i; + DBGLOG(RSN, TRACE, + "[Wlan index]: Assign entry #%d\n", i); + break; + } + } + } + + if (ucEntry < prAdapter->ucTxDefaultWlanIndex) { + if (ucAlg != CIPHER_SUITE_BIP) { + prWtbl[ucEntry].ucUsed = TRUE; + prWtbl[ucEntry].ucKeyId = ucKeyId; + prWtbl[ucEntry].ucBssIndex = ucBssIndex; + prWtbl[ucEntry].ucPairwise = 0; + kalMemCopy(prWtbl[ucEntry].aucMacAddr, pucAddr, + MAC_ADDR_LEN); + prWtbl[ucEntry].ucStaIndex = ucStaIdx; + } else { + /* BIP no need to dump secCheckWTBLAssign */ + return ucEntry; + } + + DBGLOG_LIMITED(RSN, INFO, + "[Wlan index] BSS#%d keyid#%d P=%d use WlanIndex#%d STAIdx=%d " + MACSTR + "\n", ucBssIndex, ucKeyId, prWtbl[ucEntry].ucPairwise, + ucEntry, ucStaIdx, MAC2STR(pucAddr)); + + /* DBG */ + secCheckWTBLAssign(prAdapter); + + } else { + secCheckWTBLAssign(prAdapter); + DBGLOG(RSN, ERROR, + "[Wlan index] No more wlan entry available!!!!\n"); + } + + return ucEntry; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] prAdapter Pointer to the Adapter structure + * + * \return ucEntryIndex The entry to be used, WTBL_ALLOC_FAIL for allocation + * fail + * + * \note + */ +/*----------------------------------------------------------------------------*/ +u_int8_t secCheckWTBLAssign(IN struct ADAPTER *prAdapter) +{ + secPrivacyDumpWTBL(prAdapter); + return TRUE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Got the STA record index by wlan index + * + * \param[in] prAdapter Pointer to the Adapter structure + * \param[in] ucWlanIdx The Rx wlan index + * + * \return The STA record index, 0xff for invalid sta index + */ +/*----------------------------------------------------------------------------*/ +uint8_t secGetStaIdxByWlanIdx(struct ADAPTER *prAdapter, uint8_t ucWlanIdx) +{ + struct WLAN_TABLE *prWtbl; + + if (ucWlanIdx >= WTBL_SIZE) + return STA_REC_INDEX_NOT_FOUND; + + prWtbl = prAdapter->rWifiVar.arWtbl; + + /* DBGLOG(RSN, TRACE, ("secGetStaIdxByWlanIdx=%d "MACSTR" used=%d\n", + * ucWlanIdx, MAC2STR(prWtbl[ucWlanIdx].aucMacAddr), + * prWtbl[ucWlanIdx].ucUsed)); + */ + + if (prWtbl[ucWlanIdx].ucUsed) + return prWtbl[ucWlanIdx].ucStaIndex; + else + return STA_REC_INDEX_NOT_FOUND; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief At Sw wlan table, got the BSS index by wlan index + * + * \param[in] prAdapter Pointer to the Adapter structure + * \param[in] ucWlanIdx The Rx wlan index + * + * \return The BSS index, 0xff for invalid bss index + */ +/*----------------------------------------------------------------------------*/ +uint8_t secGetBssIdxByWlanIdx(struct ADAPTER *prAdapter, uint8_t ucWlanIdx) +{ + struct WLAN_TABLE *prWtbl; + + if (ucWlanIdx >= WTBL_SIZE) + return WTBL_RESERVED_ENTRY; + + prWtbl = prAdapter->rWifiVar.arWtbl; + + if (prWtbl[ucWlanIdx].ucUsed) + return prWtbl[ucWlanIdx].ucBssIndex; + else + return WTBL_RESERVED_ENTRY; +} + +uint8_t secGetBssIdxByRfb(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb) { + + if (prAdapter && prSwRfb) { + uint8_t ucBssIndex = + secGetBssIdxByWlanIdx(prAdapter, + prSwRfb->ucWlanIdx); + struct STA_RECORD *prStaRec = + cnmGetStaRecByIndex(prAdapter, + prSwRfb->ucStaRecIdx); + + + if (ucBssIndex != WTBL_RESERVED_ENTRY) + return ucBssIndex; + + + if (prStaRec) { + DBGLOG(RSN, LOUD, + "prStaRec->ucBssIndex = %d\n", + prStaRec->ucBssIndex); + return prStaRec->ucBssIndex; + } + } + + DBGLOG(RSN, LOUD, "Return default index\n"); + + return AIS_DEFAULT_INDEX; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Got the STA record index by mac addr + * + * \param[in] prAdapter Pointer to the Adapter structure + * \param[in] pucMacAddress MAC Addr + * + * \return The STA record index, 0xff for invalid sta index + */ +/*----------------------------------------------------------------------------*/ +uint8_t secLookupStaRecIndexFromTA( + struct ADAPTER *prAdapter, uint8_t *pucMacAddress) +{ + int i; + struct WLAN_TABLE *prWtbl; + + prWtbl = prAdapter->rWifiVar.arWtbl; + + for (i = 0; i < WTBL_SIZE; i++) { + if (prWtbl[i].ucUsed) { + if (EQUAL_MAC_ADDR(pucMacAddress, prWtbl[i].aucMacAddr) + && prWtbl[i].ucPairwise) + return prWtbl[i].ucStaIndex; + } + } + + return STA_REC_INDEX_NOT_FOUND; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] prAdapter Pointer to the Adapter structure + * + * \note + */ +/*----------------------------------------------------------------------------*/ +void secPrivacyDumpWTBL(IN struct ADAPTER *prAdapter) +{ + struct WLAN_TABLE *prWtbl; + uint8_t i; + + prWtbl = prAdapter->rWifiVar.arWtbl; + + DBGLOG(RSN, TRACE, "The Wlan index\n"); + + for (i = 0; i < WTBL_SIZE; i++) { + if (prWtbl[i].ucUsed) + DBGLOG(RSN, TRACE, + "#%d Used=%d BSSIdx=%d keyid=%d P=%d STA=%d Addr=" + MACSTR "\n", i, prWtbl[i].ucUsed, + prWtbl[i].ucBssIndex, prWtbl[i].ucKeyId, + prWtbl[i].ucPairwise, prWtbl[i].ucStaIndex, + MAC2STR(prWtbl[i].aucMacAddr)); + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Assin the wlan table with the join AP info + * + * \param[in] prAdapter Pointer to the Adapter structure + * + * \note + */ +/*----------------------------------------------------------------------------*/ +void secPostUpdateAddr(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo) +{ + struct WLAN_TABLE *prWtbl; + + if (IS_BSS_AIS(prBssInfo) && prBssInfo->prStaRecOfAP) { + struct CONNECTION_SETTINGS *prConnSettings = + aisGetConnSettings(prAdapter, + prBssInfo->ucBssIndex); + + if (prConnSettings->eEncStatus == ENUM_ENCRYPTION1_ENABLED) { + + if (prBssInfo->fgBcDefaultKeyExist) { + + prWtbl = + &prAdapter->rWifiVar. + arWtbl[prBssInfo->wepkeyWlanIdx]; + + kalMemCopy(prWtbl->aucMacAddr, + prBssInfo->prStaRecOfAP->aucMacAddr, + MAC_ADDR_LEN); + prWtbl->ucStaIndex = + prBssInfo->prStaRecOfAP->ucIndex; + DBGLOG(RSN, INFO, + "secPostUpdateAddr at [%d] " MACSTR + "= STA Index=%d\n", + prBssInfo->wepkeyWlanIdx, + MAC2STR(prWtbl->aucMacAddr), + prBssInfo->prStaRecOfAP->ucIndex); + + /* Update the wlan table of the prStaRecOfAP */ + prWtbl = + &prAdapter->rWifiVar.arWtbl + [prBssInfo->prStaRecOfAP->ucWlanIndex]; + prWtbl->ucKeyId = prBssInfo->ucBcDefaultKeyIdx; + prBssInfo->prStaRecOfAP->fgTransmitKeyExist = + TRUE; + } + } + if (prConnSettings->eEncStatus == ENUM_ENCRYPTION_DISABLED) { + prWtbl = + &prAdapter->rWifiVar. + arWtbl[prBssInfo->ucBMCWlanIndex]; + + kalMemCopy(prWtbl->aucMacAddr, + prBssInfo->prStaRecOfAP->aucMacAddr, + MAC_ADDR_LEN); + prWtbl->ucStaIndex = prBssInfo->prStaRecOfAP->ucIndex; + DBGLOG(RSN, INFO, "secPostUpdateAddr at [%d] " MACSTR + "= STA Index=%d\n", + prBssInfo->ucBMCWlanIndex, + MAC2STR(prWtbl->aucMacAddr), + prBssInfo->prStaRecOfAP->ucIndex); + } + } +} + +/* return the type of Eapol frame. */ +enum ENUM_EAPOL_KEY_TYPE_T secGetEapolKeyType(uint8_t *pucPkt) +{ + uint8_t *pucEthBody = NULL; + uint8_t ucEapolType; + uint16_t u2EtherTypeLen; + uint8_t ucEthTypeLenOffset = ETHER_HEADER_LEN - ETHER_TYPE_LEN; + uint16_t u2KeyInfo = 0; + + do { + ASSERT_BREAK(pucPkt != NULL); + WLAN_GET_FIELD_BE16(&pucPkt[ucEthTypeLenOffset], + &u2EtherTypeLen); + if (u2EtherTypeLen == ETH_P_VLAN) { + ucEthTypeLenOffset += ETH_802_1Q_HEADER_LEN; + WLAN_GET_FIELD_BE16(&pucPkt[ucEthTypeLenOffset], + &u2EtherTypeLen); + } + if (u2EtherTypeLen != ETH_P_1X) + break; + pucEthBody = &pucPkt[ucEthTypeLenOffset + ETHER_TYPE_LEN]; + ucEapolType = pucEthBody[1]; + if (ucEapolType != 3) /* eapol key type */ + break; + u2KeyInfo = *((uint16_t *) (&pucEthBody[5])); + switch (u2KeyInfo) { + case 0x8a00: + return EAPOL_KEY_1_OF_4; + case 0x0a01: + return EAPOL_KEY_2_OF_4; + case 0xca13: + return EAPOL_KEY_3_OF_4; + case 0x0a03: + return EAPOL_KEY_4_OF_4; + } + } while (FALSE); + + return EAPOL_KEY_NOT_KEY; +} + +void secHandleNoWtbl(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb) +{ + /* Wtbl error handling. if no Wtbl */ + struct WLAN_ACTION_FRAME *prMgmtHdr = + (struct WLAN_ACTION_FRAME *)prSwRfb->pvHeader; + + prSwRfb->ucStaRecIdx = + secLookupStaRecIndexFromTA(prAdapter, prMgmtHdr->aucSrcAddr); + + prSwRfb->prStaRec = + cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); + + if (prSwRfb->prStaRec) { + prSwRfb->ucWlanIdx = prSwRfb->prStaRec->ucWlanIndex; + DBGLOG(RX, INFO, + "[%d] current wlan index is %d\n", + prSwRfb->ucStaRecIdx, + prSwRfb->ucWlanIdx); + } else + DBGLOG(RX, TRACE, + "not find station record base on TA\n"); +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/qosmap.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/qosmap.c new file mode 100644 index 0000000000000000000000000000000000000000..b5239eabf63b47164bbb957be04522575f67ac74 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/qosmap.c @@ -0,0 +1,281 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/*! \file "qosmap.c" + * \brief This file including the qosmap related function. + * + * This file provided the macros and functions library support for the + * protocol layer qosmap related function. + * + */ + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" + +#if CFG_SUPPORT_PPR2 + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + + + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +/*----------------------------------------------------------------------------*/ +/*! + * + * \brief This routine is called to process the qos category action frame. + * + * + * \note + * Called by: Handle Rx mgmt request + */ +/*----------------------------------------------------------------------------*/ +void handleQosMapConf(IN struct ADAPTER *prAdapter, IN struct SW_RFB *prSwRfb) +{ + struct WLAN_ACTION_FRAME *prRxFrame; + + ASSERT(prAdapter); + ASSERT(prSwRfb); + + prRxFrame = (struct WLAN_ACTION_FRAME *) prSwRfb->pvHeader; + + switch (prRxFrame->ucAction) { + case ACTION_ADDTS_REQ: + case ACTION_ADDTS_RSP: + case ACTION_SCHEDULE: + log_dbg(INIT, INFO, "qos action frame received, action: %d\n", + prRxFrame->ucAction); + break; + case ACTION_QOS_MAP_CONFIGURE: + qosHandleQosMapConfigure(prAdapter, prSwRfb); + log_dbg(INIT, INFO, "qos map configure frame received, action: %d\n", + prRxFrame->ucAction); + break; + default: + log_dbg(INIT, INFO, "qos action frame: %d, try to send to supplicant\n", + prRxFrame->ucAction); + break; + } +} + +int qosHandleQosMapConfigure(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb) +{ + struct _ACTION_QOS_MAP_CONFIGURE_FRAME *prRxFrame = NULL; + struct STA_RECORD *prStaRec; + + prRxFrame = + (struct _ACTION_QOS_MAP_CONFIGURE_FRAME *) prSwRfb->pvHeader; + if (!prRxFrame) + return -1; + + prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); + if ((!prStaRec) || (!prStaRec->fgIsInUse)) + return -1; + + log_dbg(INIT, INFO, + "IEEE 802.11: Received Qos Map Configure Frame from " MACSTR "\n", + MAC2STR(prStaRec->aucMacAddr)); + + qosParseQosMapSet(prAdapter, prStaRec, prRxFrame->qosMapSet); + + return 0; +} + +void qosParseQosMapSet(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, + IN uint8_t *qosMapSet) +{ + uint8_t dscpExcNum = 0; + int i = 0; + uint8_t *tempq = qosMapSet + 2; + uint8_t *qosmapping = prStaRec->qosMapSet; + uint8_t excTable[64]; + + if (IE_ID(qosMapSet) != ELEM_ID_QOS_MAP_SET) { + DBGLOG(INIT, WARN, + "Wrong QosMapSet IE ID: %d\n", IE_ID(qosMapSet)); + return; + } + if ((IE_LEN(qosMapSet) < 16) || (IE_LEN(qosMapSet) > 58)) { + DBGLOG(INIT, WARN, + "Error in QosMapSet IE len: %d\n", IE_LEN(qosMapSet)); + return; + } + + qosMapSetInit(prStaRec); + kalMemSet(excTable, 0, 64); + + dscpExcNum = (IE_LEN(qosMapSet) - WMM_UP_INDEX_NUM * 2) / 2; + for (i = 0; i < dscpExcNum; i++) { + uint8_t dscp = *tempq++; + uint8_t up = *tempq++; + + if (dscp < 64 && up < WMM_UP_INDEX_NUM) { + qosmapping[dscp] = up; + excTable[dscp] = TRUE; + } + } + + for (i = 0; i < WMM_UP_INDEX_NUM; i++) { + uint8_t lDscp = *tempq++; + uint8_t hDscp = *tempq++; + uint8_t dscp; + + if (lDscp == 255 && hDscp == 255) { + log_dbg(INIT, WARN, "UP %d is not used\n", i); + continue; + } + + if (hDscp < lDscp) { + log_dbg(INIT, WARN, "CHECK: UP %d, h %d, l %d\n", + i, hDscp, lDscp); + continue; + } + + for (dscp = lDscp; dscp < 64 && dscp <= hDscp; dscp++) { + if (!excTable[dscp]) + qosmapping[dscp] = i; + } + } + + DBGLOG(INIT, INFO, "QosMapSet DSCP Exception number: %d\n", dscpExcNum); +} + +void qosMapSetInit(IN struct STA_RECORD *prStaRec) +{ + /* DSCP to UP maaping based on RFC8325 in the range 0 to 63 */ + static uint8_t dscp2up[64] = { + [0 ... 63] = 0xFF, + [0] = WMM_UP_BE_INDEX, + [8] = WMM_UP_BK_INDEX, + [10] = WMM_UP_BE_INDEX, + [12] = WMM_UP_BE_INDEX, + [14] = WMM_UP_BE_INDEX, + [16] = WMM_UP_BE_INDEX, + [18] = WMM_UP_EE_INDEX, + [20] = WMM_UP_EE_INDEX, + [22] = WMM_UP_EE_INDEX, + [24] = WMM_UP_CL_INDEX, + [26] = WMM_UP_CL_INDEX, + [28] = WMM_UP_CL_INDEX, + [30] = WMM_UP_CL_INDEX, + [32] = WMM_UP_CL_INDEX, + [34] = WMM_UP_CL_INDEX, + [36] = WMM_UP_CL_INDEX, + [38] = WMM_UP_CL_INDEX, + [40] = WMM_UP_VI_INDEX, + [44] = WMM_UP_VO_INDEX, + [46] = WMM_UP_VO_INDEX, + [48] = WMM_UP_VO_INDEX, + [56] = WMM_UP_NC_INDEX, + }; + + kalMemCopy(prStaRec->qosMapSet, dscp2up, 64); +} + +uint8_t getUpFromDscp(IN struct GLUE_INFO *prGlueInfo, IN int type, IN int dscp) +{ + struct BSS_INFO *prAisBssInfo; + struct STA_RECORD *prStaRec; + + prAisBssInfo = aisGetAisBssInfo( + prGlueInfo->prAdapter, type); + if (prAisBssInfo) + prStaRec = prAisBssInfo->prStaRecOfAP; + else + return 0xFF; + + if (prStaRec && dscp >= 0 && dscp < 64) + return prStaRec->qosMapSet[dscp]; + + return 0xFF; +} +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/rate.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/rate.c new file mode 100644 index 0000000000000000000000000000000000000000..2f0c9c75fbeee9e10cad6fea6a8e15b568f45ee3 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/rate.c @@ -0,0 +1,364 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rate.c#1 + */ + +/*! \file "rate.c" + * \brief This file contains the transmission rate handling routines. + * + * This file contains the transmission rate handling routines for setting up + * ACK/CTS Rate, Highest Tx Rate, Lowest Tx Rate, Initial Tx Rate and do + * conversion between Rate Set and Data Rates. + */ + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +/* The list of valid data rates. */ +const uint8_t aucDataRate[] = { + RATE_1M, /* RATE_1M_INDEX = 0 */ + RATE_2M, /* RATE_2M_INDEX */ + RATE_5_5M, /* RATE_5_5M_INDEX */ + RATE_11M, /* RATE_11M_INDEX */ + RATE_22M, /* RATE_22M_INDEX */ + RATE_33M, /* RATE_33M_INDEX */ + RATE_6M, /* RATE_6M_INDEX */ + RATE_9M, /* RATE_9M_INDEX */ + RATE_12M, /* RATE_12M_INDEX */ + RATE_18M, /* RATE_18M_INDEX */ + RATE_24M, /* RATE_24M_INDEX */ + RATE_36M, /* RATE_36M_INDEX */ + RATE_48M, /* RATE_48M_INDEX */ + RATE_54M, /* RATE_54M_INDEX */ + RATE_VHT_PHY, /* RATE_VHT_PHY_INDEX */ + RATE_HT_PHY /* RATE_HT_PHY_INDEX */ +}; + +static const uint8_t aucDefaultAckCtsRateIndex[RATE_NUM_SW] = { + RATE_1M_SW_INDEX, /* RATE_1M_SW_INDEX = 0 */ + RATE_2M_SW_INDEX, /* RATE_2M_SW_INDEX */ + RATE_5_5M_SW_INDEX, /* RATE_5_5M_SW_INDEX */ + RATE_11M_SW_INDEX, /* RATE_11M_SW_INDEX */ + RATE_1M_SW_INDEX, /* RATE_22M_SW_INDEX - Not supported */ + RATE_1M_SW_INDEX, /* RATE_33M_SW_INDEX - Not supported */ + RATE_6M_SW_INDEX, /* RATE_6M_SW_INDEX */ + RATE_6M_SW_INDEX, /* RATE_9M_SW_INDEX */ + RATE_12M_SW_INDEX, /* RATE_12M_SW_INDEX */ + RATE_12M_SW_INDEX, /* RATE_18M_SW_INDEX */ + RATE_24M_SW_INDEX, /* RATE_24M_SW_INDEX */ + RATE_24M_SW_INDEX, /* RATE_36M_SW_INDEX */ + RATE_24M_SW_INDEX, /* RATE_48M_SW_INDEX */ + RATE_24M_SW_INDEX /* RATE_54M_SW_INDEX */ +}; + +const u_int8_t afgIsOFDMRate[RATE_NUM_SW] = { + FALSE, /* RATE_1M_INDEX = 0 */ + FALSE, /* RATE_2M_INDEX */ + FALSE, /* RATE_5_5M_INDEX */ + FALSE, /* RATE_11M_INDEX */ + FALSE, /* RATE_22M_INDEX - Not supported */ + FALSE, /* RATE_33M_INDEX - Not supported */ + TRUE, /* RATE_6M_INDEX */ + TRUE, /* RATE_9M_INDEX */ + TRUE, /* RATE_12M_INDEX */ + TRUE, /* RATE_18M_INDEX */ + TRUE, /* RATE_24M_INDEX */ + TRUE, /* RATE_36M_INDEX */ + TRUE, /* RATE_48M_INDEX */ + TRUE /* RATE_54M_INDEX */ +}; + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +/*----------------------------------------------------------------------------*/ +/*! + * @brief Convert the given Supported Rate & Extended Supported Rate IE to the + * Operational Rate Set and Basic Rate Set, and also check if any Basic + * Rate Code is unknown by driver. + * + * @param[in] prIeSupportedRate Pointer to the Supported Rate IE + * @param[in] prIeExtSupportedRate Pointer to the Ext Supported Rate IE + * @param[out] pu2OperationalRateSet Pointer to the Operational Rate Set + * @param[out] pu2BSSBasicRateSet Pointer to the Basic Rate Set + * @param[out] pfgIsUnknownBSSBasicRate Pointer to a Flag to indicate + that + * Basic Rate Set has unknown Rate Code + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void +rateGetRateSetFromIEs( + IN struct IE_SUPPORTED_RATE_IOT *prIeSupportedRate, + IN struct IE_EXT_SUPPORTED_RATE *prIeExtSupportedRate, + OUT uint16_t *pu2OperationalRateSet, + OUT uint16_t *pu2BSSBasicRateSet, + OUT u_int8_t *pfgIsUnknownBSSBasicRate) +{ + uint16_t u2OperationalRateSet = 0; + uint16_t u2BSSBasicRateSet = 0; + u_int8_t fgIsUnknownBSSBasicRate = FALSE; + uint8_t ucRate; + uint32_t i, j; + + if (prIeSupportedRate) { + /* NOTE(Kevin): Buffalo WHR-G54S's supported rate set + * IE exceed 8. + * IE_LEN(pucIE) == 12, "1(B), 2(B), 5.5(B), 6(B), 9(B), 11(B), + * 12(B), 18(B), 24(B), 36(B), 48(B), 54(B)" + */ + /* ASSERT(prIeSupportedRate->ucLength + * <= ELEM_MAX_LEN_SUP_RATES); + */ + ASSERT(prIeSupportedRate->ucLength <= RATE_NUM_SW); + + for (i = 0; i < prIeSupportedRate->ucLength; i++) { + ucRate = + prIeSupportedRate->aucSupportedRates[i] & RATE_MASK; + + /* Search all valid data rates */ + for (j = 0; j < sizeof(aucDataRate) / sizeof(uint8_t); + j++) { + if (ucRate == aucDataRate[j]) { + u2OperationalRateSet |= BIT(j); + + if (prIeSupportedRate->aucSupportedRates + [i] & RATE_BASIC_BIT) + u2BSSBasicRateSet |= BIT(j); + + break; + } + } + + if ((j == sizeof(aucDataRate) / sizeof(uint8_t)) && + (prIeSupportedRate->aucSupportedRates[i] & + RATE_BASIC_BIT)) { + fgIsUnknownBSSBasicRate = TRUE; + /* A data rate not list in the aucDataRate[] */ + } + } + } + + if (prIeExtSupportedRate) { + /* ASSERT(prIeExtSupportedRate->ucLength + * <= ELEM_MAX_LEN_EXTENDED_SUP_RATES); + */ + + for (i = 0; i < prIeExtSupportedRate->ucLength; i++) { + ucRate = + prIeExtSupportedRate->aucExtSupportedRates[i] & + RATE_MASK; + + /* Search all valid data rates */ + for (j = 0; j < sizeof(aucDataRate) / sizeof(uint8_t); + j++) { + if (ucRate == aucDataRate[j]) { + u2OperationalRateSet |= BIT(j); + + if (prIeExtSupportedRate-> + aucExtSupportedRates[i] + & RATE_BASIC_BIT) + u2BSSBasicRateSet |= BIT(j); + + break; + } + } + + if ((j == sizeof(aucDataRate) / sizeof(uint8_t)) && + (prIeExtSupportedRate->aucExtSupportedRates[i] & + RATE_BASIC_BIT)) { + fgIsUnknownBSSBasicRate = TRUE; + /* A data rate not list in the aucDataRate[] */ + } + } + } + + *pu2OperationalRateSet = u2OperationalRateSet; + *pu2BSSBasicRateSet = u2BSSBasicRateSet; + *pfgIsUnknownBSSBasicRate = fgIsUnknownBSSBasicRate; + + return; + +} /* end of rateGetRateSetFromIEs() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Convert the given Operational Rate Set & Basic Rate Set to the Rate + * Code Format for used in (Ext)Supportec Rate IE. + * + * @param[in] u2OperationalRateSet Operational Rate Set + * @param[in] u2BSSBasicRateSet Basic Rate Set + * @param[out] pucDataRates Pointer to the Data Rate Buffer + * @param[out] pucDataRatesLen Pointer to the Data Rate Buffer Length + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void +rateGetDataRatesFromRateSet(IN uint16_t u2OperationalRateSet, + IN uint16_t u2BSSBasicRateSet, + OUT uint8_t *pucDataRates, + OUT uint8_t *pucDataRatesLen) +{ + uint32_t i, j; + + for (i = RATE_1M_SW_INDEX, j = 0; i < RATE_NUM_SW; i++) { + if (u2OperationalRateSet & BIT(i)) { + + *(pucDataRates + j) = aucDataRate[i]; + + if (u2BSSBasicRateSet & BIT(i)) + *(pucDataRates + j) |= RATE_BASIC_BIT; + + j++; + } + } + + *pucDataRatesLen = (uint8_t) j; + + return; + +} /* end of rateGetDataRatesFromRateSet() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Get the highest rate from given Rate Set. + * + * \param[in] u2RateSet Rate Set + * \param[out] pucHighestRateIndex Pointer to buffer of the Highest Rate Index + * + * \retval TRUE Highest Rate Index was found + * \retval FALSE Highest Rate Index was not found + */ +/*----------------------------------------------------------------------------*/ +u_int8_t rateGetHighestRateIndexFromRateSet(IN uint16_t u2RateSet, + OUT uint8_t *pucHighestRateIndex) +{ + int32_t i; + + for (i = RATE_54M_SW_INDEX; i >= RATE_1M_SW_INDEX; i--) { + if (u2RateSet & BIT(i)) { + *pucHighestRateIndex = (uint8_t) i; + return TRUE; + } + } + + return FALSE; + +} /* end of rateGetHighestRateIndexFromRateSet() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Get the lowest rate from given Rate Set. + * + * \param[in] u2RateSet Rate Set + * \param[out] pucLowestRateIndex Pointer to buffer of the Lowest Rate Index + * + * \retval TRUE Lowest Rate Index was found + * \retval FALSE Lowest Rate Index was not found + */ +/*----------------------------------------------------------------------------*/ +u_int8_t rateGetLowestRateIndexFromRateSet(IN uint16_t u2RateSet, + OUT uint8_t *pucLowestRateIndex) +{ + uint32_t i; + + for (i = RATE_1M_SW_INDEX; i <= RATE_54M_SW_INDEX; i++) { + if (u2RateSet & BIT(i)) { + *pucLowestRateIndex = (uint8_t) i; + return TRUE; + } + } + + return FALSE; + +} /* end of rateGetLowestRateIndexFromRateSet() */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/reg_rule.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/reg_rule.c new file mode 100644 index 0000000000000000000000000000000000000000..ebf60705de6289781c712f90a47e1b895c58ac8a --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/reg_rule.c @@ -0,0 +1,336 @@ +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +#include "precomp.h" + +#if (CFG_SUPPORT_SINGLE_SKU == 1) +#if (CFG_SUPPORT_SINGLE_SKU_LOCAL_DB == 1) +#include "rlm_domain.h" + +#if 0 +/** + * enum ieee80211_channel_flags - channel flags + * + * Channel flags set by the regulatory control code. + * + * @IEEE80211_CHAN_DISABLED: This channel is disabled. + * @IEEE80211_CHAN_NO_IR: do not initiate radiation, this includes + * sending probe requests or beaconing. + * @IEEE80211_CHAN_RADAR: Radar detection is required on this channel. + * @IEEE80211_CHAN_NO_HT40PLUS: extension channel above this channel + * is not permitted. + * @IEEE80211_CHAN_NO_HT40MINUS: extension channel below this channel + * is not permitted. + * @IEEE80211_CHAN_NO_OFDM: OFDM is not allowed on this channel. + * @IEEE80211_CHAN_NO_80MHZ: If the driver supports 80 MHz on the band, + * this flag indicates that an 80 MHz channel cannot use this + * channel as the control or any of the secondary channels. + * This may be due to the driver or due to regulatory bandwidth + * restrictions. + * @IEEE80211_CHAN_NO_160MHZ: If the driver supports 160 MHz on the band, + * this flag indicates that an 160 MHz channel cannot use this + * channel as the control or any of the secondary channels. + * This may be due to the driver or due to regulatory bandwidth + * restrictions. + * @IEEE80211_CHAN_INDOOR_ONLY: see %NL80211_FREQUENCY_ATTR_INDOOR_ONLY + * @IEEE80211_CHAN_GO_CONCURRENT: see %NL80211_FREQUENCY_ATTR_GO_CONCURRENT + * @IEEE80211_CHAN_NO_20MHZ: 20 MHz bandwidth is not permitted + * on this channel. + * @IEEE80211_CHAN_NO_10MHZ: 10 MHz bandwidth is not permitted + * on this channel. + * + */ +enum ieee80211_channel_flags { + IEEE80211_CHAN_DISABLED = 1<<0, + IEEE80211_CHAN_NO_IR = 1<<1, + /* hole at 1<<2 */ + IEEE80211_CHAN_RADAR = 1<<3, + IEEE80211_CHAN_NO_HT40PLUS = 1<<4, + IEEE80211_CHAN_NO_HT40MINUS = 1<<5, + IEEE80211_CHAN_NO_OFDM = 1<<6, + IEEE80211_CHAN_NO_80MHZ = 1<<7, + IEEE80211_CHAN_NO_160MHZ = 1<<8, + IEEE80211_CHAN_INDOOR_ONLY = 1<<9, + IEEE80211_CHAN_GO_CONCURRENT = 1<<10, + IEEE80211_CHAN_NO_20MHZ = 1<<11, + IEEE80211_CHAN_NO_10MHZ = 1<<12, +}; + +#define IEEE80211_CHAN_NO_HT40 \ + (IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS) + + +struct ieee80211_freq_range { + u32 start_freq_khz; + u32 end_freq_khz; + u32 max_bandwidth_khz; +}; + +struct ieee80211_power_rule { + u32 max_antenna_gain; + u32 max_eirp; +}; + +/** + * enum reg_flags (the same as nl80211_reg_rule_flags) - regulatory rule flags + * + * @NL80211_RRF_NO_OFDM: OFDM modulation not allowed + * @NL80211_RRF_NO_CCK: CCK modulation not allowed + * @NL80211_RRF_NO_INDOOR: indoor operation not allowed + * @NL80211_RRF_NO_OUTDOOR: outdoor operation not allowed + * @NL80211_RRF_DFS: DFS support is required to be used + * @NL80211_RRF_PTP_ONLY: this is only for Point To Point links + * @NL80211_RRF_PTMP_ONLY: this is only for Point To Multi Point links + * @NL80211_RRF_NO_IR: no mechanisms that initiate radiation are allowed, + * this includes probe requests or modes of operation that + * require beaconing. + * @NL80211_RRF_AUTO_BW: maximum available bandwidth should be calculated + * base on contiguous rules and wider channels will be + * allowed to cross multiple contiguous/overlapping + * frequency ranges. + * @NL80211_RRF_IR_CONCURRENT: See &NL80211_FREQUENCY_ATTR_IR_CONCURRENT + * @NL80211_RRF_NO_HT40MINUS: channels can't be used in HT40- operation + * @NL80211_RRF_NO_HT40PLUS: channels can't be used in HT40+ operation + * @NL80211_RRF_NO_80MHZ: 80MHz operation not allowed + * @NL80211_RRF_NO_160MHZ: 160MHz operation not allowed + */ +enum reg_flags { + NL80211_RRF_NO_OFDM = 1<<0, + NL80211_RRF_NO_CCK = 1<<1, + NL80211_RRF_NO_INDOOR = 1<<2, + NL80211_RRF_NO_OUTDOOR = 1<<3, + NL80211_RRF_DFS = 1<<4, + NL80211_RRF_PTP_ONLY = 1<<5, + NL80211_RRF_PTMP_ONLY = 1<<6, + NL80211_RRF_NO_IR = 1<<7, + NL80211_RRF_NO_IBSS = 1<<8, + NL80211_RRF_AUTO_BW = 1<<11, + NL80211_RRF_IR_CONCURRENT = 1<<12, + NL80211_RRF_NO_HT40MINUS = 1<<13, + NL80211_RRF_NO_HT40PLUS = 1<<14, + NL80211_RRF_NO_80MHZ = 1<<15, + NL80211_RRF_NO_160MHZ = 1<<16, +}; + +#define NL80211_RRF_PASSIVE_SCAN NL80211_RRF_NO_IR +#define NL80211_RRF_NO_IBSS NL80211_RRF_NO_IR +#define NL80211_RRF_NO_IR NL80211_RRF_NO_IR +#define NL80211_RRF_NO_HT40 (NL80211_RRF_NO_HT40MINUS | \ + NL80211_RRF_NO_HT40PLUS) +#define NL80211_RRF_GO_CONCURRENT NL80211_RRF_IR_CONCURRENT + +/* For backport compatibility with older userspace */ +#define NL80211_RRF_NO_IR_ALL (NL80211_RRF_NO_IR | \ + __NL80211_RRF_NO_IBSS) + +struct ieee80211_reg_rule { + struct ieee80211_freq_range freq_range; + struct ieee80211_power_rule power_rule; + u32 reg_flags; /*enum reg_flags*/ + u32 dfs_cac_ms; +}; + +#define MAX_NUMER_REG_RULES 6 + +struct ieee80211_regdomain { + char alpha2[3]; + u32 n_reg_rules; + enum nl80211_dfs_regions dfs_region; + struct ieee80211_reg_rule reg_rules[MAX_NUMER_REG_RULES]; +}; + + +#define MHZ_TO_KHZ(freq) ((freq) * 1000) +#define KHZ_TO_MHZ(freq) ((freq) / 1000) +#define DBI_TO_MBI(gain) ((gain) * 100) +#define MBI_TO_DBI(gain) ((gain) / 100) +#define DBM_TO_MBM(gain) ((gain) * 100) +#define MBM_TO_DBM(gain) ((gain) / 100) + +#define REG_RULE_EXT(start, end, bw, gain, eirp, dfs_cac, reg_flags) \ +{ \ + .freq_range.start_freq_khz = MHZ_TO_KHZ(start), \ + .freq_range.end_freq_khz = MHZ_TO_KHZ(end), \ + .freq_range.max_bandwidth_khz = MHZ_TO_KHZ(bw), \ + .power_rule.max_eirp = DBM_TO_MBM(eirp), \ + .flags = reg_flags, \ + .dfs_cac_ms = dfs_cac, \ +} + +#define REG_RULE(start, end, bw, gain, eirp, reg_flags) \ +{ \ + .freq_range.start_freq_khz = MHZ_TO_KHZ(start), \ + .freq_range.end_freq_khz = MHZ_TO_KHZ(end), \ + .freq_range.max_bandwidth_khz = MHZ_TO_KHZ(bw), \ + .power_rule.max_antenna_gain = DBI_TO_MBI(gain),\ + .power_rule.max_eirp = DBM_TO_MBM(eirp), \ + .flags = reg_flags, \ +} +#endif + +/*************************************************** + * Here to describe the regulatory rules of yours. + *************************************************** + */ + +/* + * Step1. Decclare struct ieee80211_regdomain + */ +const struct ieee80211_regdomain regdom_us01 = { + .n_reg_rules = 6, + .reg_rules = { + /* channels 1..11 */ + REG_RULE_LIGHT(2412-10, 2462+10, 40, 0), + /* channels 36..48 */ + REG_RULE_LIGHT(5180-10, 5240+10, 40, 0), + /* channels 56..64 */ + REG_RULE_LIGHT(5260-10, 5320+10, 40, KAL_RRF_DFS), + /* channels 100..118 */ + REG_RULE_LIGHT(5500-10, 5590+10, 40, KAL_RRF_DFS), + /* channels 132..140 */ + REG_RULE_LIGHT(5660-10, 5700+10, 40, KAL_RRF_DFS), + /* channels 149..165 */ + REG_RULE_LIGHT(5745-10, 5825+10, 40, 0) } +}; + +const struct ieee80211_regdomain regdom_us = { + .n_reg_rules = 5, + .dfs_region = NL80211_DFS_FCC, + .reg_rules = { + /* channels 1..11 */ + REG_RULE_LIGHT(2412-10, 2462+10, 40, 0), + /* channels 36..48 */ + REG_RULE_LIGHT(5180-10, 5240+10, 80, KAL_RRF_AUTO_BW), + /* channels 52..64 */ + REG_RULE_LIGHT(5260-10, 5320+10, 80, KAL_RRF_DFS | KAL_RRF_AUTO_BW), + /* channels 100..140 */ + REG_RULE_LIGHT(5500-10, 5720+10, 160, KAL_RRF_DFS), + /* channels 149..165 */ + REG_RULE_LIGHT(5745-10, 5825+10, 80, 0) } +}; + +const struct ieee80211_regdomain regdom_cn = { + .n_reg_rules = 4, + .dfs_region = NL80211_DFS_FCC, + .reg_rules = { + /* channels 1..13 */ + REG_RULE_LIGHT(2412-10, 2472+10, 40, 0), + /* channels 36..48 */ + REG_RULE_LIGHT(5180-10, 5240+10, 80, KAL_RRF_AUTO_BW), + /* channels 52..64 */ + REG_RULE_LIGHT(5260-10, 5320+10, 80, KAL_RRF_DFS | KAL_RRF_AUTO_BW), + /* channels 149..165 */ + REG_RULE_LIGHT(5745-10, 5825+10, 80, 0) } +}; + +const struct ieee80211_regdomain regdom_cz_nl = { + .n_reg_rules = 5, + .reg_rules = { + /* channels 1..11 */ + REG_RULE_LIGHT(2412-10, 2462+10, 40, 0), + /* channels 12,13 */ + REG_RULE_LIGHT(2467-10, 2472+10, 40, 0), + /* channels 36..48 */ + REG_RULE_LIGHT(5180-10, 5240+10, 80, 0), + /* channels 52..64 */ + REG_RULE_LIGHT(5260-10, 5320+10, 80, KAL_RRF_DFS), + /* channels 100..140 */ + REG_RULE_LIGHT(5500-10, 5700+10, 160, KAL_RRF_DFS) } +}; + +const struct ieee80211_regdomain regdom_jp = { + .n_reg_rules = 7, + .dfs_region = NL80211_DFS_JP, + .reg_rules = { + /* channels 1..13 */ + REG_RULE_LIGHT(2412-10, 2472+10, 40, 0), + /* channels 14 */ + REG_RULE_LIGHT(2484-10, 2484+10, 20, KAL_RRF_NO_OFDM), + /* channels 184..196 */ + REG_RULE_LIGHT(4920-10, 4980+10, 40, 0), + /* channels 8..16 */ + REG_RULE_LIGHT(5040-10, 5080+10, 40, 0), + /* channels 36..48 */ + REG_RULE_LIGHT(5180-10, 5240+10, 80, KAL_RRF_AUTO_BW), + /* channels 52..64 */ + REG_RULE_LIGHT(5260-10, 5320+10, 80, KAL_RRF_DFS | KAL_RRF_AUTO_BW), + /* channels 100..140 */ + REG_RULE_LIGHT(5500-10, 5700+10, 160, KAL_RRF_DFS) } +}; + +const struct ieee80211_regdomain regdom_tr = { + .n_reg_rules = 4, + .dfs_region = NL80211_DFS_ETSI, + .reg_rules = { + /* channels 1..13 */ + REG_RULE_LIGHT(2412-10, 2472+10, 40, 0), + /* channels 36..48 */ + REG_RULE_LIGHT(5180-10, 5240+10, 80, KAL_RRF_AUTO_BW), + /* channels 52..64 */ + REG_RULE_LIGHT(5260-10, 5320+10, 80, KAL_RRF_DFS | KAL_RRF_AUTO_BW), + /* channels 100..140 */ + REG_RULE_LIGHT(5500-10, 5700+10, 160, KAL_RRF_DFS) } +}; + +/* + * Step2. Decclare struct mtk_regdomain + */ +const struct mtk_regdomain my_regdom_us01 = { + .country_code = "US01", + .prRegdRules = ®dom_us01 +}; + +const struct mtk_regdomain my_regdom_us = { + .country_code = "US", + .prRegdRules = ®dom_us +}; + +const struct mtk_regdomain my_regdom_cn = { + .country_code = "CN", + .prRegdRules = ®dom_cn +}; + +const struct mtk_regdomain my_regdom_nl = { + .country_code = "NL", + .prRegdRules = ®dom_cz_nl +}; + +const struct mtk_regdomain my_regdom_cz = { + .country_code = "CZ", + .prRegdRules = ®dom_cz_nl +}; + +const struct mtk_regdomain my_regdom_jp = { + .country_code = "JP", + .prRegdRules = ®dom_jp +}; + +const struct mtk_regdomain my_regdom_tr = { + .country_code = "TR", + .prRegdRules = ®dom_tr +}; + +/* + * Step3. Register to table + */ +const struct mtk_regdomain *g_prRegRuleTable[] = { + &my_regdom_us01, + &my_regdom_us, + &my_regdom_cn, + &my_regdom_nl, + &my_regdom_cz, + &my_regdom_jp, + &my_regdom_tr, + NULL /* this NULL SHOULD be at the end of the array */ +}; + +#endif +#endif + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/rlm.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/rlm.c new file mode 100644 index 0000000000000000000000000000000000000000..661041cbbe49118b7219ca05c151f43ce8d810d4 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/rlm.c @@ -0,0 +1,6588 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rlm.c#3 + */ + +/*! \file "rlm.c" + * \brief + * + */ + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/* Retry limit of sending operation notification frame */ +#define OPERATION_NOTICATION_TX_LIMIT 2 + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +enum ENUM_OP_NOTIFY_STATE_T { + OP_NOTIFY_STATE_KEEP = 0, /* Won't change OP mode */ + OP_NOTIFY_STATE_SENDING, /* Sending OP notification frame */ + OP_NOTIFY_STATE_SUCCESS, /* OP notification Tx success */ + OP_NOTIFY_STATE_FAIL, /* OP notification Tx fail(over retry limit)*/ + OP_NOTIFY_STATE_NUM +}; + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ +/* +** Should Not Force to BW 20 after Channel Switch. +** Enable for DFS Certification +*/ +#ifdef CFG_DFS_CHSW_FORCE_BW20 +u_int8_t g_fgHasChannelSwitchIE = FALSE; +#endif +u_int8_t g_fgHasStopTx = FALSE; + +#if CFG_SUPPORT_CAL_RESULT_BACKUP_TO_HOST +struct RLM_CAL_RESULT_ALL_V2 g_rBackupCalDataAllV2; +#endif + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +static void rlmFillHtCapIE(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, + struct MSDU_INFO *prMsduInfo); + +static void rlmFillExtCapIE(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, + struct MSDU_INFO *prMsduInfo); + +static void rlmFillHtOpIE(struct ADAPTER *prAdapter, struct BSS_INFO *prBssInfo, + struct MSDU_INFO *prMsduInfo); + +static uint8_t rlmRecIeInfoForClient(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, uint8_t *pucIE, + uint16_t u2IELength); + +static u_int8_t rlmRecBcnFromNeighborForClient(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, + struct SW_RFB *prSwRfb, + uint8_t *pucIE, + uint16_t u2IELength); + +static u_int8_t rlmRecBcnInfoForClient(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, + struct SW_RFB *prSwRfb, uint8_t *pucIE, + uint16_t u2IELength); + +static void rlmBssReset(struct ADAPTER *prAdapter, struct BSS_INFO *prBssInfo); + +#if CFG_SUPPORT_802_11AC +static void rlmFillVhtCapIE(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, + struct MSDU_INFO *prMsduInfo); +static void rlmFillVhtOpNotificationIE(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, + struct MSDU_INFO *prMsduInfo, + u_int8_t fgIsMaxCap); + +#endif + +/* Operating BW/Nss change and notification */ +static void rlmOpModeTxDoneHandler(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo, + uint8_t ucOpChangeType, + u_int8_t fgIsSuccess); +static void rlmChangeOwnOpInfo(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo); +static void rlmCompleteOpModeChange(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, + u_int8_t fgIsSuccess); +static void rlmRollbackOpChangeParam(struct BSS_INFO *prBssInfo, + u_int8_t fgIsRollbackBw, + u_int8_t fgIsRollbackNss); +static uint8_t rlmGetOpModeBwByVhtAndHtOpInfo(struct BSS_INFO *prBssInfo); +static u_int8_t rlmCheckOpChangeParamValid(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, + uint8_t ucChannelWidth, + uint8_t ucOpRxNss, + uint8_t ucOpTxNss); +static void rlmRecOpModeBwForClient(uint8_t ucVhtOpModeChannelWidth, + struct BSS_INFO *prBssInfo); + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rlmFsmEventInit(struct ADAPTER *prAdapter) +{ + ASSERT(prAdapter); + + /* Note: assume struct TIMER structures are reset to zero or stopped + * before invoking this function. + */ + + /* Initialize OBSS FSM */ + rlmObssInit(prAdapter); + +#if CFG_SUPPORT_PWR_LIMIT_COUNTRY + rlmDomainCheckCountryPowerLimitTable(prAdapter); +#endif + +#ifdef CFG_DFS_CHSW_FORCE_BW20 + g_fgHasChannelSwitchIE = FALSE; +#endif +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rlmFsmEventUninit(struct ADAPTER *prAdapter) +{ + struct BSS_INFO *prBssInfo; + uint8_t i; + + ASSERT(prAdapter); + + for (i = 0; i < prAdapter->ucHwBssIdNum; i++) { + prBssInfo = prAdapter->aprBssInfo[i]; + + /* Note: all RLM timers will also be stopped. + * Now only one OBSS scan timer. + */ + rlmBssReset(prAdapter, prBssInfo); + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief For association request, power capability + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rlmReqGeneratePowerCapIE(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo) +{ + uint8_t *pucBuffer; + + ASSERT(prAdapter); + ASSERT(prMsduInfo); + + pucBuffer = + (uint8_t *)(prMsduInfo->prPacket + prMsduInfo->u2FrameLength); + + POWER_CAP_IE(pucBuffer)->ucId = ELEM_ID_PWR_CAP; + POWER_CAP_IE(pucBuffer)->ucLength = ELEM_MAX_LEN_POWER_CAP; + POWER_CAP_IE(pucBuffer)->cMinTxPowerCap = RLM_MIN_TX_PWR; + POWER_CAP_IE(pucBuffer)->cMaxTxPowerCap = RLM_MAX_TX_PWR; + + prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief For association request, supported channels + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rlmReqGenerateSupportedChIE(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo) +{ + uint8_t *pucBuffer; + struct BSS_INFO *prBssInfo; + struct RF_CHANNEL_INFO auc2gChannelList[MAX_2G_BAND_CHN_NUM]; + struct RF_CHANNEL_INFO auc5gChannelList[MAX_5G_BAND_CHN_NUM]; + uint8_t ucNumOf2gChannel = 0; + uint8_t ucNumOf5gChannel = 0; + uint8_t ucChIdx = 0; + uint8_t ucIdx = 0; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prMsduInfo->ucBssIndex); + kalMemZero(&auc2gChannelList[0], sizeof(auc2gChannelList)); + kalMemZero(&auc5gChannelList[0], sizeof(auc5gChannelList)); + + /* We should add supported channels IE in assoc/reassoc request + * if the spectrum management bit is set to 1 in Capability Info + * field, or the connection will be rejected by Marvell APs in + * some TGn items. (e.g. 5.2.3). Spectrum management related + * feature (802.11h) is for 5G band. + */ + if (!prBssInfo || prBssInfo->eBand != BAND_5G) + return; + + pucBuffer = + (uint8_t *)(prMsduInfo->prPacket + prMsduInfo->u2FrameLength); + + rlmDomainGetChnlList(prAdapter, BAND_2G4, TRUE, MAX_2G_BAND_CHN_NUM, + &ucNumOf2gChannel, auc2gChannelList); + rlmDomainGetChnlList(prAdapter, BAND_5G, TRUE, MAX_5G_BAND_CHN_NUM, + &ucNumOf5gChannel, auc5gChannelList); + + SUP_CH_IE(pucBuffer)->ucId = ELEM_ID_SUP_CHS; + SUP_CH_IE(pucBuffer)->ucLength = + (ucNumOf2gChannel + ucNumOf5gChannel) * 2; + + for (ucIdx = 0; ucIdx < ucNumOf2gChannel; ucIdx++, ucChIdx += 2) { + SUP_CH_IE(pucBuffer)->ucChannelNum[ucChIdx] = + auc2gChannelList[ucIdx].ucChannelNum; + SUP_CH_IE(pucBuffer)->ucChannelNum[ucChIdx + 1] = 1; + } + + for (ucIdx = 0; ucIdx < ucNumOf5gChannel; ucIdx++, ucChIdx += 2) { + SUP_CH_IE(pucBuffer)->ucChannelNum[ucChIdx] = + auc5gChannelList[ucIdx].ucChannelNum; + SUP_CH_IE(pucBuffer)->ucChannelNum[ucChIdx + 1] = 1; + } + + prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief For probe request, association request + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rlmReqGenerateHtCapIE(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo) +{ + struct BSS_INFO *prBssInfo; + struct STA_RECORD *prStaRec; + + ASSERT(prAdapter); + ASSERT(prMsduInfo); + + prBssInfo = prAdapter->aprBssInfo[prMsduInfo->ucBssIndex]; + if (!prBssInfo) + return; + + prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); + + if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & + PHY_TYPE_SET_802_11N) && + (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N))) + rlmFillHtCapIE(prAdapter, prBssInfo, prMsduInfo); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief For probe request, association request + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rlmReqGenerateExtCapIE(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo) +{ + struct BSS_INFO *prBssInfo; + struct STA_RECORD *prStaRec; +#if CFG_SUPPORT_PASSPOINT + struct HS20_INFO *prHS20Info; +#endif + + ASSERT(prAdapter); + ASSERT(prMsduInfo); + + prBssInfo = prAdapter->aprBssInfo[prMsduInfo->ucBssIndex]; + if (!prBssInfo) + return; + +#if CFG_SUPPORT_PASSPOINT + prHS20Info = aisGetHS20Info(prAdapter, + prBssInfo->ucBssIndex); + if (!prHS20Info) + return; +#endif + + prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); + + if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & + PHY_TYPE_SET_802_11N) && + (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N))) + rlmFillExtCapIE(prAdapter, prBssInfo, prMsduInfo); +#if CFG_SUPPORT_PASSPOINT + else if (prHS20Info->fgConnectHS20AP == TRUE) + hs20FillExtCapIE(prAdapter, prBssInfo, prMsduInfo); +#endif /* CFG_SUPPORT_PASSPOINT */ +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief For probe response (GO, IBSS) and association response + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rlmRspGenerateHtCapIE(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo) +{ + struct BSS_INFO *prBssInfo; + struct STA_RECORD *prStaRec; + uint8_t ucPhyTypeSet; + + ASSERT(prAdapter); + ASSERT(prMsduInfo); + + prBssInfo = prAdapter->aprBssInfo[prMsduInfo->ucBssIndex]; + if (!prBssInfo) + return; + + if (!IS_BSS_ACTIVE(prBssInfo)) + return; + + prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); + + /* Decide PHY type set source */ + if (prStaRec) { + /* Get PHY type set from target STA */ + ucPhyTypeSet = prStaRec->ucPhyTypeSet; + } else { + /* Get PHY type set from current BSS */ + ucPhyTypeSet = prBssInfo->ucPhyTypeSet; + } + + if (RLM_NET_IS_11N(prBssInfo) && + (ucPhyTypeSet & PHY_TYPE_SET_802_11N) && + (!prBssInfo->fgIsWepCipherGroup)) + rlmFillHtCapIE(prAdapter, prBssInfo, prMsduInfo); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief For probe response (GO, IBSS) and association response + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rlmRspGenerateExtCapIE(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo) +{ + struct BSS_INFO *prBssInfo; + struct STA_RECORD *prStaRec; + uint8_t ucPhyTypeSet; + + ASSERT(prAdapter); + ASSERT(prMsduInfo); + + prBssInfo = prAdapter->aprBssInfo[prMsduInfo->ucBssIndex]; + if (!prBssInfo) + return; + + if (!IS_BSS_ACTIVE(prBssInfo)) + return; + + prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); + + /* Decide PHY type set source */ + if (prStaRec) { + /* Get PHY type set from target STA */ + ucPhyTypeSet = prStaRec->ucPhyTypeSet; + } else { + /* Get PHY type set from current BSS */ + ucPhyTypeSet = prBssInfo->ucPhyTypeSet; + } + + if (RLM_NET_IS_11N(prBssInfo) && (ucPhyTypeSet & PHY_TYPE_SET_802_11N)) + rlmFillExtCapIE(prAdapter, prBssInfo, prMsduInfo); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief For probe response (GO, IBSS) and association response + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rlmRspGenerateHtOpIE(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo) +{ + struct BSS_INFO *prBssInfo; + struct STA_RECORD *prStaRec; + uint8_t ucPhyTypeSet; + + ASSERT(prAdapter); + ASSERT(prMsduInfo); + + prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); + + prBssInfo = prAdapter->aprBssInfo[prMsduInfo->ucBssIndex]; + if (!prBssInfo) + return; + + if (!IS_BSS_ACTIVE(prBssInfo)) + return; + + /* Decide PHY type set source */ + if (prStaRec) { + /* Get PHY type set from target STA */ + ucPhyTypeSet = prStaRec->ucPhyTypeSet; + } else { + /* Get PHY type set from current BSS */ + ucPhyTypeSet = prBssInfo->ucPhyTypeSet; + } + + if (RLM_NET_IS_11N(prBssInfo) && + (ucPhyTypeSet & PHY_TYPE_SET_802_11N) && + (!prBssInfo->fgIsWepCipherGroup)) + rlmFillHtOpIE(prAdapter, prBssInfo, prMsduInfo); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief For probe response (GO, IBSS) and association response + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rlmRspGenerateErpIE(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo) +{ + struct BSS_INFO *prBssInfo; + struct STA_RECORD *prStaRec; + struct IE_ERP *prErpIe; + uint8_t ucPhyTypeSet; + + ASSERT(prAdapter); + ASSERT(prMsduInfo); + + prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); + + prBssInfo = prAdapter->aprBssInfo[prMsduInfo->ucBssIndex]; + if (!prBssInfo) + return; + + if (!IS_BSS_ACTIVE(prBssInfo)) + return; + + /* Decide PHY type set source */ + if (prStaRec) { + /* Get PHY type set from target STA */ + ucPhyTypeSet = prStaRec->ucPhyTypeSet; + } else { + /* Get PHY type set from current BSS */ + ucPhyTypeSet = prBssInfo->ucPhyTypeSet; + } + + if (RLM_NET_IS_11GN(prBssInfo) && prBssInfo->eBand == BAND_2G4 && + (ucPhyTypeSet & PHY_TYPE_SET_802_11GN)) { + prErpIe = (struct IE_ERP *)(((uint8_t *)prMsduInfo->prPacket) + + prMsduInfo->u2FrameLength); + + /* Add ERP IE */ + prErpIe->ucId = ELEM_ID_ERP_INFO; + prErpIe->ucLength = 1; + + prErpIe->ucERP = prBssInfo->fgObssErpProtectMode + ? ERP_INFO_USE_PROTECTION + : 0; + + if (prBssInfo->fgErpProtectMode) + prErpIe->ucERP |= (ERP_INFO_NON_ERP_PRESENT | + ERP_INFO_USE_PROTECTION); + + /* Handle barker preamble */ + if (!prBssInfo->fgUseShortPreamble) + prErpIe->ucERP |= ERP_INFO_BARKER_PREAMBLE_MODE; + + ASSERT(IE_SIZE(prErpIe) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_ERP)); + + prMsduInfo->u2FrameLength += IE_SIZE(prErpIe); + } +} + +#if CFG_SUPPORT_MTK_SYNERGY +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is used to generate MTK Vendor Specific OUI + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rlmGenerateMTKOuiIE(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo) +{ + struct BSS_INFO *prBssInfo; + uint8_t *pucBuffer; + uint8_t aucMtkOui[] = VENDOR_OUI_MTK; + + ASSERT(prAdapter); + ASSERT(prMsduInfo); + + if (prAdapter->rWifiVar.ucMtkOui == FEATURE_DISABLED) + return; + + prBssInfo = prAdapter->aprBssInfo[prMsduInfo->ucBssIndex]; + if (!prBssInfo) + return; + + pucBuffer = (uint8_t *)((unsigned long)prMsduInfo->prPacket + + (unsigned long)prMsduInfo->u2FrameLength); + + MTK_OUI_IE(pucBuffer)->ucId = ELEM_ID_VENDOR; + MTK_OUI_IE(pucBuffer)->ucLength = ELEM_MIN_LEN_MTK_OUI; + MTK_OUI_IE(pucBuffer)->aucOui[0] = aucMtkOui[0]; + MTK_OUI_IE(pucBuffer)->aucOui[1] = aucMtkOui[1]; + MTK_OUI_IE(pucBuffer)->aucOui[2] = aucMtkOui[2]; + MTK_OUI_IE(pucBuffer)->aucCapability[0] = + MTK_SYNERGY_CAP0 & (prAdapter->rWifiVar.aucMtkFeature[0]); + MTK_OUI_IE(pucBuffer)->aucCapability[1] = + MTK_SYNERGY_CAP1 & (prAdapter->rWifiVar.aucMtkFeature[1]); + MTK_OUI_IE(pucBuffer)->aucCapability[2] = + MTK_SYNERGY_CAP2 & (prAdapter->rWifiVar.aucMtkFeature[2]); + MTK_OUI_IE(pucBuffer)->aucCapability[3] = + MTK_SYNERGY_CAP3 & (prAdapter->rWifiVar.aucMtkFeature[3]); + + /* Disable the 2.4G 256QAM feature bit if chip doesn't support AC*/ + if (prAdapter->rWifiVar.ucHwNotSupportAC) { + MTK_OUI_IE(pucBuffer)->aucCapability[0] &= + ~(MTK_SYNERGY_CAP_SUPPORT_24G_MCS89); + DBGLOG(INIT, WARN, + "Disable 2.4G 256QAM support if N only chip\n"); + } + + prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); + pucBuffer += IE_SIZE(pucBuffer); +} /* rlmGenerateMTKOuiIE */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is used to check MTK Vendor Specific OUI + * + * + * @return true: correct MTK OUI + * false: incorrect MTK OUI + */ +/*----------------------------------------------------------------------------*/ +u_int8_t rlmParseCheckMTKOuiIE(IN struct ADAPTER *prAdapter, IN uint8_t *pucBuf, + IN uint32_t *pu4Cap) +{ + uint8_t aucMtkOui[] = VENDOR_OUI_MTK; + struct IE_MTK_OUI *prMtkOuiIE = (struct IE_MTK_OUI *)NULL; + + do { + ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL)); + + prMtkOuiIE = (struct IE_MTK_OUI *)pucBuf; + + if (prAdapter->rWifiVar.ucMtkOui == FEATURE_DISABLED) + break; + else if (IE_LEN(pucBuf) < ELEM_MIN_LEN_MTK_OUI) + break; + else if (prMtkOuiIE->aucOui[0] != aucMtkOui[0] || + prMtkOuiIE->aucOui[1] != aucMtkOui[1] || + prMtkOuiIE->aucOui[2] != aucMtkOui[2]) + break; + /* apply NvRam setting */ + prMtkOuiIE->aucCapability[0] = + prMtkOuiIE->aucCapability[0] & + (prAdapter->rWifiVar.aucMtkFeature[0]); + prMtkOuiIE->aucCapability[1] = + prMtkOuiIE->aucCapability[1] & + (prAdapter->rWifiVar.aucMtkFeature[1]); + prMtkOuiIE->aucCapability[2] = + prMtkOuiIE->aucCapability[2] & + (prAdapter->rWifiVar.aucMtkFeature[2]); + prMtkOuiIE->aucCapability[3] = + prMtkOuiIE->aucCapability[3] & + (prAdapter->rWifiVar.aucMtkFeature[3]); + + /* Disable the 2.4G 256QAM feature bit if chip doesn't support + * AC. Otherwise, FW would choose wrong max rate of auto rate. + */ + if (prAdapter->rWifiVar.ucHwNotSupportAC) { + prMtkOuiIE->aucCapability[0] &= + ~(MTK_SYNERGY_CAP_SUPPORT_24G_MCS89); + DBGLOG(INIT, WARN, + "Disable 2.4G 256QAM support if N only chip\n"); + } + + kalMemCopy(pu4Cap, prMtkOuiIE->aucCapability, sizeof(uint32_t)); + + return TRUE; + } while (FALSE); + + return FALSE; +} /* rlmParseCheckMTKOuiIE */ + +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rlmGenerateCsaIE(struct ADAPTER *prAdapter, struct MSDU_INFO *prMsduInfo) +{ + uint8_t *pucBuffer; + + ASSERT(prAdapter); + ASSERT(prMsduInfo); + + if (prAdapter->rWifiVar.fgCsaInProgress) { + + pucBuffer = + (uint8_t *)((unsigned long)prMsduInfo->prPacket + + (unsigned long)prMsduInfo->u2FrameLength); + + CSA_IE(pucBuffer)->ucId = ELEM_ID_CH_SW_ANNOUNCEMENT; + CSA_IE(pucBuffer)->ucLength = ELEM_MIN_LEN_CSA; + CSA_IE(pucBuffer)->ucChannelSwitchMode = + prAdapter->rWifiVar.ucChannelSwitchMode; + CSA_IE(pucBuffer)->ucNewChannelNum = + prAdapter->rWifiVar.ucNewChannelNumber; + CSA_IE(pucBuffer)->ucChannelSwitchCount = + prAdapter->rWifiVar.ucChannelSwitchCount; + + prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); + pucBuffer += IE_SIZE(pucBuffer); + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +static void rlmFillHtCapIE(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, + struct MSDU_INFO *prMsduInfo) +{ + struct IE_HT_CAP *prHtCap; + struct SUP_MCS_SET_FIELD *prSupMcsSet; + u_int8_t fg40mAllowed; + uint8_t ucIdx; + + ASSERT(prAdapter); + ASSERT(prBssInfo); + ASSERT(prMsduInfo); + + fg40mAllowed = prBssInfo->fgAssoc40mBwAllowed; + + prHtCap = (struct IE_HT_CAP *)(((uint8_t *)prMsduInfo->prPacket) + + prMsduInfo->u2FrameLength); + + /* Add HT capabilities IE */ + prHtCap->ucId = ELEM_ID_HT_CAP; + prHtCap->ucLength = sizeof(struct IE_HT_CAP) - ELEM_HDR_LEN; + + prHtCap->u2HtCapInfo = HT_CAP_INFO_DEFAULT_VAL; + + if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucRxShortGI)) + prHtCap->u2HtCapInfo |= + (HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M); + + if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucRxLdpc)) + prHtCap->u2HtCapInfo |= HT_CAP_INFO_LDPC_CAP; + + if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucTxStbc) && + prBssInfo->ucOpTxNss >= 2) + prHtCap->u2HtCapInfo |= HT_CAP_INFO_TX_STBC; + + if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucRxStbc)) { + + uint8_t tempRxStbcNss; + + tempRxStbcNss = prAdapter->rWifiVar.ucRxStbcNss; + tempRxStbcNss = + (tempRxStbcNss > + wlanGetSupportNss(prAdapter, prBssInfo->ucBssIndex)) + ? wlanGetSupportNss(prAdapter, + prBssInfo->ucBssIndex) + : (tempRxStbcNss); + if (tempRxStbcNss != prAdapter->rWifiVar.ucRxStbcNss) { + DBGLOG(RLM, WARN, "Apply Nss:%d as RxStbcNss in HT Cap", + wlanGetSupportNss(prAdapter, + prBssInfo->ucBssIndex)); + DBGLOG(RLM, WARN, + " due to set RxStbcNss more than Nss is not appropriate.\n"); + } + if (tempRxStbcNss == 1) + prHtCap->u2HtCapInfo |= HT_CAP_INFO_RX_STBC_1_SS; + else if (tempRxStbcNss == 2) + prHtCap->u2HtCapInfo |= HT_CAP_INFO_RX_STBC_2_SS; + else if (tempRxStbcNss >= 3) + prHtCap->u2HtCapInfo |= HT_CAP_INFO_RX_STBC_3_SS; + } + + if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucRxGf)) + prHtCap->u2HtCapInfo |= HT_CAP_INFO_HT_GF; + + if (prAdapter->rWifiVar.ucRxMaxMpduLen > VHT_CAP_INFO_MAX_MPDU_LEN_3K) + prHtCap->u2HtCapInfo |= HT_CAP_INFO_MAX_AMSDU_LEN; + + if (!fg40mAllowed) + prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | + HT_CAP_INFO_SHORT_GI_40M | + HT_CAP_INFO_DSSS_CCK_IN_40M); + + /* SM power saving (IEEE 802.11, 2016, 10.2.4) + * A non-AP HT STA may also use SM Power Save bits in the HT + * Capabilities element of its Association Request to achieve + * the same purpose. The latter allows the STA to use only a + * single receive chain immediately after association. + */ + if (prBssInfo->ucOpRxNss < + wlanGetSupportNss(prAdapter, prBssInfo->ucBssIndex)) + prHtCap->u2HtCapInfo &= + ~HT_CAP_INFO_SM_POWER_SAVE; /*Set as static power save*/ + + prHtCap->ucAmpduParam = AMPDU_PARAM_DEFAULT_VAL; + + prSupMcsSet = &prHtCap->rSupMcsSet; + kalMemZero((void *)&prSupMcsSet->aucRxMcsBitmask[0], + SUP_MCS_RX_BITMASK_OCTET_NUM); + + for (ucIdx = 0; + ucIdx < wlanGetSupportNss(prAdapter, prBssInfo->ucBssIndex); + ucIdx++) + prSupMcsSet->aucRxMcsBitmask[ucIdx] = BITS(0, 7); + + /* prSupMcsSet->aucRxMcsBitmask[0] = BITS(0, 7); */ + + if (fg40mAllowed && IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucMCS32)) + prSupMcsSet->aucRxMcsBitmask[32 / 8] = BIT(0); /* MCS32 */ + prSupMcsSet->u2RxHighestSupportedRate = SUP_MCS_RX_DEFAULT_HIGHEST_RATE; + prSupMcsSet->u4TxRateInfo = SUP_MCS_TX_DEFAULT_VAL; + + prHtCap->u2HtExtendedCap = HT_EXT_CAP_DEFAULT_VAL; + if (!fg40mAllowed || + prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) + prHtCap->u2HtExtendedCap &= + ~(HT_EXT_CAP_PCO | HT_EXT_CAP_PCO_TRANS_TIME_NONE); + + prHtCap->u4TxBeamformingCap = TX_BEAMFORMING_CAP_DEFAULT_VAL; + if ((prAdapter->rWifiVar.eDbdcMode == ENUM_DBDC_MODE_DISABLED) || + (prBssInfo->eBand == BAND_5G)) { + if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucStaHtBfee)) + prHtCap->u4TxBeamformingCap = TX_BEAMFORMING_CAP_BFEE; + if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucStaHtBfer)) + prHtCap->u4TxBeamformingCap |= TX_BEAMFORMING_CAP_BFER; + } + + prHtCap->ucAselCap = ASEL_CAP_DEFAULT_VAL; + + ASSERT(IE_SIZE(prHtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP)); + + prMsduInfo->u2FrameLength += IE_SIZE(prHtCap); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +static void rlmFillExtCapIE(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, + struct MSDU_INFO *prMsduInfo) +{ +#if CFG_SUPPORT_PASSPOINT + struct IE_HS20_EXT_CAP_T *prHsExtCap; + struct HS20_INFO *prHS20Info; +#else + struct IE_EXT_CAP *prExtCap; +#endif + u_int8_t fg40mAllowed, fgAppendVhtCap; + struct STA_RECORD *prStaRec; + struct CONNECTION_SETTINGS *prConnSettings; + const uint8_t *extCapConn; + uint32_t extCapIeLen = 0; + + ASSERT(prAdapter); + ASSERT(prMsduInfo); + + fg40mAllowed = prBssInfo->fgAssoc40mBwAllowed; + prConnSettings = aisGetConnSettings(prAdapter, prBssInfo->ucBssIndex); + extCapConn = kalFindIeMatchMask(ELEM_ID_EXTENDED_CAP, + prConnSettings->pucAssocIEs, + prConnSettings->assocIeLen, + NULL, 0, 0, NULL); + if (extCapConn) { + extCapIeLen = ELEM_HDR_LEN + RSN_IE(extCapConn)->ucLength; + DBGLOG_MEM8(SAA, INFO, extCapConn, extCapIeLen); + } + +#if CFG_SUPPORT_PASSPOINT + prHS20Info = aisGetHS20Info(prAdapter, + prBssInfo->ucBssIndex); + if (!prHS20Info) + return; + + prHsExtCap = + (struct IE_HS20_EXT_CAP_T *)(((uint8_t *)prMsduInfo->prPacket) + + prMsduInfo->u2FrameLength); + prHsExtCap->ucId = ELEM_ID_EXTENDED_CAP; + + if (prHS20Info->fgConnectHS20AP == TRUE) + prHsExtCap->ucLength = ELEM_MAX_LEN_EXT_CAP; + else + prHsExtCap->ucLength = 3 - ELEM_HDR_LEN; + + kalMemZero(prHsExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP); + + prHsExtCap->aucCapabilities[0] = ELEM_EXT_CAP_DEFAULT_VAL; + + if (!fg40mAllowed) + prHsExtCap->aucCapabilities[0] &= + ~ELEM_EXT_CAP_20_40_COEXIST_SUPPORT; + + if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) + prHsExtCap->aucCapabilities[0] &= ~ELEM_EXT_CAP_PSMP_CAP; + +#if CFG_SUPPORT_802_11AC + prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); + fgAppendVhtCap = FALSE; + + /* Check append rule */ + if (prAdapter->rWifiVar.ucAvailablePhyTypeSet + & PHY_TYPE_SET_802_11AC) { + /* Note: For AIS connecting state, + * structure in BSS_INFO will not be inited + * So, we check StaRec instead of BssInfo + */ + if (prStaRec) { + if (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11AC) + fgAppendVhtCap = TRUE; + } else if (RLM_NET_IS_11AC(prBssInfo) && + ((prBssInfo->eCurrentOPMode == + OP_MODE_INFRASTRUCTURE) || + (prBssInfo->eCurrentOPMode == + OP_MODE_ACCESS_POINT))) { + fgAppendVhtCap = TRUE; + } + + } + + if (fgAppendVhtCap) { + if (prHsExtCap->ucLength < ELEM_MAX_LEN_EXT_CAP) + prHsExtCap->ucLength = ELEM_MAX_LEN_EXT_CAP; + + SET_EXT_CAP(prHsExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, + ELEM_EXT_CAP_OP_MODE_NOTIFICATION_BIT); + } +#endif + + if (prHS20Info->fgConnectHS20AP == TRUE) { + SET_EXT_CAP(prHsExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, + ELEM_EXT_CAP_INTERWORKING_BIT); + SET_EXT_CAP(prHsExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, + ELEM_EXT_CAP_QOSMAPSET_BIT); + SET_EXT_CAP(prHsExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, + ELEM_EXT_CAP_BSS_TRANSITION_BIT); + /* For R2 WNM-Notification */ + SET_EXT_CAP(prHsExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, + ELEM_EXT_CAP_WNM_NOTIFICATION_BIT); + } + +#if CFG_SUPPORT_802_11V_BSS_TRANSITION_MGT + prHsExtCap->ucLength = ELEM_MAX_LEN_EXT_CAP; + SET_EXT_CAP(prHsExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, + ELEM_EXT_CAP_BSS_TRANSITION_BIT); +#endif + +#if (CFG_SUPPORT_802_11V_MBSSID == 1) + if (prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) { + prExtCap->ucLength = ELEM_MAX_LEN_EXT_CAP; + SET_EXT_CAP(prHsExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, + ELEM_EXT_CAP_MBSSID_BIT); + } +#endif + + if ((extCapIeLen - ELEM_HDR_LEN) > prHsExtCap->ucLength) + prHsExtCap->ucLength = ELEM_MAX_LEN_EXT_CAP; + + if (extCapConn) + rlmSyncExtCapIEwithSupplicant(prHsExtCap->aucCapabilities, + extCapConn, extCapIeLen); + else + DBGLOG(RLM, WARN, "extCapConn = NULL!"); + + ASSERT(IE_SIZE(prHsExtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP)); + + prMsduInfo->u2FrameLength += IE_SIZE(prHsExtCap); + +#else + /* Add Extended Capabilities IE */ + prExtCap = (struct IE_EXT_CAP *)(((uint8_t *)prMsduInfo->prPacket) + + prMsduInfo->u2FrameLength); + + prExtCap->ucId = ELEM_ID_EXTENDED_CAP; + + prExtCap->ucLength = 3 - ELEM_HDR_LEN; + kalMemZero(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP); + + prExtCap->aucCapabilities[0] = ELEM_EXT_CAP_DEFAULT_VAL; + + if (!fg40mAllowed) + prExtCap->aucCapabilities[0] &= + ~ELEM_EXT_CAP_20_40_COEXIST_SUPPORT; + + if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) + prExtCap->aucCapabilities[0] &= ~ELEM_EXT_CAP_PSMP_CAP; + +#if CFG_SUPPORT_802_11AC + prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); + fgAppendVhtCap = FALSE; + + /* Check append rule */ + if (prAdapter->rWifiVar.ucAvailablePhyTypeSet + & PHY_TYPE_SET_802_11AC) { + /* Note: For AIS connecting state, + * structure in BSS_INFO will not be inited + * So, we check StaRec instead of BssInfo + */ + if (prStaRec) { + if (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11AC) + fgAppendVhtCap = TRUE; + } else if (RLM_NET_IS_11AC(prBssInfo) && + ((prBssInfo->eCurrentOPMode == + OP_MODE_INFRASTRUCTURE) || + (prBssInfo->eCurrentOPMode == + OP_MODE_ACCESS_POINT))) { + fgAppendVhtCap = TRUE; + } + } + + if (fgAppendVhtCap) { + if (prExtCap->ucLength < ELEM_MAX_LEN_EXT_CAP) + prExtCap->ucLength = ELEM_MAX_LEN_EXT_CAP; + + SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, + ELEM_EXT_CAP_OP_MODE_NOTIFICATION_BIT); + } +#endif + +#if (CFG_SUPPORT_TWT == 1) + prExtCap->aucCapabilities[ELEM_EXT_CAP_TWT_REQUESTER_BIT >> 3] |= + BIT(ELEM_EXT_CAP_TWT_REQUESTER_BIT % 8); +#endif + +#if CFG_SUPPORT_802_11V_BSS_TRANSITION_MGT + prExtCap->ucLength = ELEM_MAX_LEN_EXT_CAP; + SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, + ELEM_EXT_CAP_BSS_TRANSITION_BIT); +#endif + +#if (CFG_SUPPORT_802_11V_MBSSID == 1) + if (prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) { + prExtCap->ucLength = ELEM_MAX_LEN_EXT_CAP; + SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, + ELEM_EXT_CAP_MBSSID_BIT); + } +#endif + +#if (CFG_SUPPORT_802_11AX == 1) + if ((prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) + && (prBssInfo->eBand == BAND_2G4) + && !RLM_NET_IS_11AX(prBssInfo)) + prExtCap->ucLength = ELEM_MAX_LEN_EXT_CAP_11ABGNAC; +#endif + + if ((extCapIeLen - ELEM_HDR_LEN) > prExtCap->ucLength) + prExtCap->ucLength = ELEM_MAX_LEN_EXT_CAP; + + if (extCapConn) + rlmSyncExtCapIEwithSupplicant(prExtCap->aucCapabilities, + extCapConn, extCapIeLen); + else + DBGLOG(RLM, WARN, "extCapConn = NULL!"); + + ASSERT(IE_SIZE(prExtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP)); + + prMsduInfo->u2FrameLength += IE_SIZE(prExtCap); +#endif +} + +void rlmSyncExtCapIEwithSupplicant(uint8_t *aucCapabilities, + const uint8_t *supExtCapIEs, size_t IElen) { + uint32_t i; + + for (i = ELEM_HDR_LEN * 8; i < IElen * 8; i++) { + if (supExtCapIEs[i / 8] & BIT(i % 8)) { + SET_EXT_CAP(aucCapabilities, ELEM_MAX_LEN_EXT_CAP, + i-ELEM_HDR_LEN*8); + } + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +static void rlmFillHtOpIE(struct ADAPTER *prAdapter, struct BSS_INFO *prBssInfo, + struct MSDU_INFO *prMsduInfo) +{ + struct IE_HT_OP *prHtOp; + uint16_t i; + + ASSERT(prAdapter); + ASSERT(prBssInfo); + ASSERT(prMsduInfo); + + prHtOp = (struct IE_HT_OP *)(((uint8_t *)prMsduInfo->prPacket) + + prMsduInfo->u2FrameLength); + + /* Add HT operation IE */ + prHtOp->ucId = ELEM_ID_HT_OP; + prHtOp->ucLength = sizeof(struct IE_HT_OP) - ELEM_HDR_LEN; + + /* RIFS and 20/40 bandwidth operations are included */ + prHtOp->ucPrimaryChannel = prBssInfo->ucPrimaryChannel; + prHtOp->ucInfo1 = prBssInfo->ucHtOpInfo1; + + /* Decide HT protection mode field */ + if (prBssInfo->eHtProtectMode == HT_PROTECT_MODE_NON_HT) + prHtOp->u2Info2 = (uint8_t)HT_PROTECT_MODE_NON_HT; + else if (prBssInfo->eObssHtProtectMode == HT_PROTECT_MODE_NON_MEMBER) + prHtOp->u2Info2 = (uint8_t)HT_PROTECT_MODE_NON_MEMBER; + else { + /* It may be SYS_PROTECT_MODE_NONE or SYS_PROTECT_MODE_20M */ + prHtOp->u2Info2 = (uint8_t)prBssInfo->eHtProtectMode; + } + + if (prBssInfo->eGfOperationMode != GF_MODE_NORMAL) { + /* It may be GF_MODE_PROTECT or GF_MODE_DISALLOWED + * Note: it will also be set in ad-hoc network + */ + prHtOp->u2Info2 |= HT_OP_INFO2_NON_GF_HT_STA_PRESENT; + } + + if (0 /* Regulatory class 16 */ && + prBssInfo->eObssHtProtectMode == HT_PROTECT_MODE_NON_MEMBER) { + /* (TBD) It is HT_PROTECT_MODE_NON_MEMBER, so require protection + * although it is possible to have no protection by spec. + */ + prHtOp->u2Info2 |= HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT; + } + + prHtOp->u2Info3 = prBssInfo->u2HtOpInfo3; /* To do: handle L-SIG TXOP */ + + /* No basic MCSx are needed temporarily */ + for (i = 0; i < 16; i++) + prHtOp->aucBasicMcsSet[i] = 0; + + ASSERT(IE_SIZE(prHtOp) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP)); + + prMsduInfo->u2FrameLength += IE_SIZE(prHtOp); +} + +#if CFG_SUPPORT_802_11AC + +/*----------------------------------------------------------------------------*/ +/*! + * \brief For probe request, association request + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rlmReqGenerateVhtCapIE(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo) +{ + struct BSS_INFO *prBssInfo; + struct STA_RECORD *prStaRec; +#if CFG_SUPPORT_VHT_IE_IN_2G + struct BSS_DESC *prBssDesc = NULL; + u_int8_t fgIsVHTPresent = FALSE; +#endif + + ASSERT(prAdapter); + ASSERT(prMsduInfo); + + if (prAdapter) { + prBssInfo = prAdapter->aprBssInfo[prMsduInfo->ucBssIndex]; +#if CFG_SUPPORT_VHT_IE_IN_2G + prBssDesc = aisGetTargetBssDesc(prAdapter, + prMsduInfo->ucBssIndex); + if (prBssDesc) { + fgIsVHTPresent = prBssDesc->fgIsVHTPresent; + DBGLOG(RLM, TRACE, + "fgIsVHTPresent=%d", fgIsVHTPresent); + } +#endif + } else { + DBGLOG(RLM, ERROR, "prAdapter is NULL, return!"); + return; + } + + if (!prBssInfo) { + DBGLOG(RLM, ERROR, "prBssInfo is NULL, return!"); + return; + } + + prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); + + if (!prStaRec) { + DBGLOG(RLM, ERROR, "prStaRec is NULL, return!"); + return; + } + + if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11AC) + && (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11AC)) + rlmFillVhtCapIE(prAdapter, prBssInfo, prMsduInfo); +#if CFG_SUPPORT_VHT_IE_IN_2G + else if ((prBssInfo->eBand == BAND_2G4) && + (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N) && + ((prAdapter->rWifiVar.ucVhtIeIn2g + == FEATURE_FORCE_ENABLED) || + ((prAdapter->rWifiVar.ucVhtIeIn2g + == FEATURE_ENABLED) && fgIsVHTPresent))) { + DBGLOG(RLM, TRACE, + "Add VHT IE in 2.4G, ucPhyTypeSet=%02x, ucVhtIeIn2g=%02x", + prStaRec->ucPhyTypeSet, + prAdapter->rWifiVar.ucVhtIeIn2g); + rlmFillVhtCapIE(prAdapter, prBssInfo, prMsduInfo); + } +#endif +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief For probe response (GO, IBSS) and association response + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rlmRspGenerateVhtCapIE(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo) +{ + struct BSS_INFO *prBssInfo; + struct STA_RECORD *prStaRec; + uint8_t ucPhyTypeSet; + + ASSERT(prAdapter); + ASSERT(prMsduInfo); + + prBssInfo = prAdapter->aprBssInfo[prMsduInfo->ucBssIndex]; + if (!prBssInfo) + return; + + if (!IS_BSS_ACTIVE(prBssInfo)) + return; + + prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); + + /* Decide PHY type set source */ + if (prStaRec) { + /* Get PHY type set from target STA */ + ucPhyTypeSet = prStaRec->ucPhyTypeSet; + } else { + /* Get PHY type set from current BSS */ + ucPhyTypeSet = prBssInfo->ucPhyTypeSet; + } + + if (RLM_NET_IS_11AC(prBssInfo) && + (ucPhyTypeSet & PHY_TYPE_SET_802_11AC)) + rlmFillVhtCapIE(prAdapter, prBssInfo, prMsduInfo); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rlmRspGenerateVhtOpIE(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo) +{ + struct BSS_INFO *prBssInfo; + struct STA_RECORD *prStaRec; + uint8_t ucPhyTypeSet; + + ASSERT(prAdapter); + ASSERT(prMsduInfo); + + prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); + + prBssInfo = prAdapter->aprBssInfo[prMsduInfo->ucBssIndex]; + if (!prBssInfo) + return; + + if (!IS_BSS_ACTIVE(prBssInfo)) + return; + + /* Decide PHY type set source */ + if (prStaRec) { + /* Get PHY type set from target STA */ + ucPhyTypeSet = prStaRec->ucPhyTypeSet; + } else { + /* Get PHY type set from current BSS */ + ucPhyTypeSet = prBssInfo->ucPhyTypeSet; + } + + if (RLM_NET_IS_11AC(prBssInfo) && + (ucPhyTypeSet & PHY_TYPE_SET_802_11AC)) + rlmFillVhtOpIE(prAdapter, prBssInfo, prMsduInfo); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief For probe request, association request + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rlmReqGenerateVhtOpNotificationIE(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo) +{ + struct BSS_INFO *prBssInfo; + struct STA_RECORD *prStaRec; + + ASSERT(prAdapter); + ASSERT(prMsduInfo); + + prBssInfo = prAdapter->aprBssInfo[prMsduInfo->ucBssIndex]; + if (!prBssInfo) + return; + /* [TGac 5.2.46 STBC Receive Test with UCC 9.2.x] + * Operating Notification IE of Nss=2 will make Ralink testbed send data + * frames without STBC + * Enable the Operating Notification IE only for DBDC enable case. + */ + if (!prAdapter->rWifiVar.fgDbDcModeEn) + return; + prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); + + if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & + PHY_TYPE_SET_802_11AC) && + (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11AC))) { + /* Fill own capability in channel width field in OP mode element + * since we haven't filled in channel width info in BssInfo at + * current state + */ + rlmFillVhtOpNotificationIE(prAdapter, prBssInfo, prMsduInfo, + TRUE); + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rlmRspGenerateVhtOpNotificationIE(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo) +{ + struct BSS_INFO *prBssInfo; + struct STA_RECORD *prStaRec; + uint8_t ucPhyTypeSet; + + ASSERT(prAdapter); + ASSERT(prMsduInfo); + + prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); + + prBssInfo = prAdapter->aprBssInfo[prMsduInfo->ucBssIndex]; + if (!prBssInfo) + return; + + if (!IS_BSS_ACTIVE(prBssInfo)) + return; + + if (!prBssInfo->fgIsOpChangeRxNss) + return; + + /* Decide PHY type set source */ + if (prStaRec) { + /* Get PHY type set from target STA */ + ucPhyTypeSet = prStaRec->ucPhyTypeSet; + } else { + /* Get PHY type set from current BSS */ + ucPhyTypeSet = prBssInfo->ucPhyTypeSet; + } + + if (RLM_NET_IS_11AC(prBssInfo) && + (ucPhyTypeSet & PHY_TYPE_SET_802_11AC)) + rlmFillVhtOpNotificationIE(prAdapter, prBssInfo, prMsduInfo, + FALSE); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * add VHT operation notification IE for VHT-BW40 case specific + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +static void rlmFillVhtOpNotificationIE(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, + struct MSDU_INFO *prMsduInfo, + u_int8_t fgIsOwnCap) +{ + struct IE_VHT_OP_MODE_NOTIFICATION *prVhtOpMode; + uint8_t ucOpModeBw = VHT_OP_MODE_CHANNEL_WIDTH_20; + + ASSERT(prAdapter); + ASSERT(prBssInfo); + ASSERT(prMsduInfo); + + prVhtOpMode = (struct IE_VHT_OP_MODE_NOTIFICATION + *)(((uint8_t *)prMsduInfo->prPacket) + + prMsduInfo->u2FrameLength); + + kalMemZero((void *)prVhtOpMode, + sizeof(struct IE_VHT_OP_MODE_NOTIFICATION)); + + prVhtOpMode->ucId = ELEM_ID_OP_MODE; + prVhtOpMode->ucLength = + sizeof(struct IE_VHT_OP_MODE_NOTIFICATION) - ELEM_HDR_LEN; + + DBGLOG(RLM, TRACE, "rlmFillVhtOpNotificationIE(%d) %u %u\n", + prBssInfo->ucBssIndex, fgIsOwnCap, prBssInfo->ucOpRxNss); + + if (fgIsOwnCap) { + ucOpModeBw = cnmGetDbdcBwCapability(prAdapter, + prBssInfo->ucBssIndex); + + /*handle 80P80 case*/ + if (ucOpModeBw >= MAX_BW_160MHZ) + ucOpModeBw = VHT_OP_MODE_CHANNEL_WIDTH_160_80P80; + + prVhtOpMode->ucOperatingMode |= ucOpModeBw; + prVhtOpMode->ucOperatingMode |= + (((prBssInfo->ucOpRxNss - 1) + << VHT_OP_MODE_RX_NSS_OFFSET) & + VHT_OP_MODE_RX_NSS); + + } else { + + ucOpModeBw = rlmGetOpModeBwByVhtAndHtOpInfo(prBssInfo); + + prVhtOpMode->ucOperatingMode |= ucOpModeBw; + prVhtOpMode->ucOperatingMode |= + (((prBssInfo->ucOpRxNss - 1) + << VHT_OP_MODE_RX_NSS_OFFSET) & + VHT_OP_MODE_RX_NSS); + } + + prMsduInfo->u2FrameLength += IE_SIZE(prVhtOpMode); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +static void rlmFillVhtCapIE(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, + struct MSDU_INFO *prMsduInfo) +{ + struct IE_VHT_CAP *prVhtCap; + struct VHT_SUPPORTED_MCS_FIELD *prVhtSupportedMcsSet; + uint8_t i; + uint8_t ucMaxBw; + struct STA_RECORD *prStaRec; + + ASSERT(prAdapter); + ASSERT(prBssInfo); + ASSERT(prMsduInfo); + + prVhtCap = (struct IE_VHT_CAP *)(((uint8_t *)prMsduInfo->prPacket) + + prMsduInfo->u2FrameLength); + + prVhtCap->ucId = ELEM_ID_VHT_CAP; + prVhtCap->ucLength = sizeof(struct IE_VHT_CAP) - ELEM_HDR_LEN; + prVhtCap->u4VhtCapInfo = VHT_CAP_INFO_DEFAULT_VAL; + + ucMaxBw = cnmGetBssMaxBw(prAdapter, prBssInfo->ucBssIndex); + + prVhtCap->u4VhtCapInfo |= (prAdapter->rWifiVar.ucRxMaxMpduLen & + VHT_CAP_INFO_MAX_MPDU_LEN_MASK); +#if CFG_SUPPORT_VHT_IE_IN_2G + if (prBssInfo->eBand == BAND_2G4) { + prVhtCap->u4VhtCapInfo |= + VHT_CAP_INFO_MAX_SUP_CHANNEL_WIDTH_SET_NONE; + } else { +#endif + if (ucMaxBw == MAX_BW_160MHZ) + prVhtCap->u4VhtCapInfo |= + VHT_CAP_INFO_MAX_SUP_CHANNEL_WIDTH_SET_160; + else if (ucMaxBw == MAX_BW_80_80_MHZ) + prVhtCap->u4VhtCapInfo |= + VHT_CAP_INFO_MAX_SUP_CHANNEL_WIDTH_SET_160_80P80; + + if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucStaVhtBfee)) { + prVhtCap->u4VhtCapInfo |= FIELD_VHT_CAP_INFO_BFEE; +#if CFG_SUPPORT_BFEE + prStaRec = cnmGetStaRecByIndex(prAdapter, + prMsduInfo->ucStaRecIndex); + + if (prStaRec && + (prStaRec->ucVhtCapNumSoundingDimensions == 0x2) && + !prAdapter->rWifiVar.fgForceSTSNum) { + /* For the compatibility with netgear R7000 AP */ + prVhtCap->u4VhtCapInfo |= + (((uint32_t)prStaRec->ucVhtCapNumSoundingDimensions) +<< VHT_CAP_INFO_COMPRESSED_STEERING_NUMBER_OF_BEAMFORMER_ANTENNAS_SUP_OFF); + DBGLOG(RLM, INFO, "Set VHT Cap BFEE STS CAP=%d\n", + prStaRec->ucVhtCapNumSoundingDimensions); + } else { + /* For 11ac cert. VHT-5.2.63C MU-BFee step3, + * it requires STAUT to set its maximum STS capability here + */ + prVhtCap->u4VhtCapInfo |= +VHT_CAP_INFO_COMPRESSED_STEERING_NUMBER_OF_BEAMFORMER_ANTENNAS_4_SUP; + DBGLOG(RLM, TRACE, "Set VHT Cap BFEE STS CAP=%d\n", + VHT_CAP_INFO_BEAMFORMEE_STS_CAP_MAX); + } +/* DBGLOG(RLM, INFO, "VhtCapInfo=%x\n", prVhtCap->u4VhtCapInfo); */ +#endif + if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucStaVhtMuBfee)) + prVhtCap->u4VhtCapInfo |= + VHT_CAP_INFO_MU_BEAMFOMEE_CAPABLE; + } + + if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucStaVhtBfer)) + prVhtCap->u4VhtCapInfo |= FIELD_VHT_CAP_INFO_BFER; +#if CFG_SUPPORT_VHT_IE_IN_2G + } +#endif + if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucRxShortGI)) { + if (ucMaxBw >= MAX_BW_80MHZ) + prVhtCap->u4VhtCapInfo |= VHT_CAP_INFO_SHORT_GI_80; + + if (ucMaxBw >= MAX_BW_160MHZ) + prVhtCap->u4VhtCapInfo |= + VHT_CAP_INFO_SHORT_GI_160_80P80; + } + + if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucRxLdpc)) + prVhtCap->u4VhtCapInfo |= VHT_CAP_INFO_RX_LDPC; + + if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucRxStbc)) { + uint8_t tempRxStbcNss; + + if (prAdapter->rWifiVar.u4SwTestMode == + ENUM_SW_TEST_MODE_SIGMA_AC) { + tempRxStbcNss = 1; + DBGLOG(RLM, INFO, + "Set RxStbcNss to 1 for 11ac certification.\n"); + } else { + tempRxStbcNss = prAdapter->rWifiVar.ucRxStbcNss; + tempRxStbcNss = + (tempRxStbcNss > + wlanGetSupportNss(prAdapter, + prBssInfo->ucBssIndex)) + ? wlanGetSupportNss( + prAdapter, + prBssInfo->ucBssIndex) + : (tempRxStbcNss); + if (tempRxStbcNss != prAdapter->rWifiVar.ucRxStbcNss) { + DBGLOG(RLM, WARN, + "Apply Nss:%d as RxStbcNss in VHT Cap", + wlanGetSupportNss( + prAdapter, + prBssInfo->ucBssIndex)); + DBGLOG(RLM, WARN, + "due to set RxStbcNss more than Nss is not appropriate.\n"); + } + } + prVhtCap->u4VhtCapInfo |= + ((tempRxStbcNss << VHT_CAP_INFO_RX_STBC_OFFSET) & + VHT_CAP_INFO_RX_STBC_MASK); + } + + if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucTxStbc) && + prBssInfo->ucOpTxNss >= 2) + prVhtCap->u4VhtCapInfo |= VHT_CAP_INFO_TX_STBC; + + /*set MCS map */ + prVhtSupportedMcsSet = &prVhtCap->rVhtSupportedMcsSet; + kalMemZero((void *)prVhtSupportedMcsSet, + sizeof(struct VHT_SUPPORTED_MCS_FIELD)); + + for (i = 0; i < 8; i++) { + uint8_t ucOffset = i * 2; + uint8_t ucMcsMap; + + if (i < wlanGetSupportNss(prAdapter, prBssInfo->ucBssIndex)) + ucMcsMap = VHT_CAP_INFO_MCS_MAP_MCS9; + else + ucMcsMap = VHT_CAP_INFO_MCS_NOT_SUPPORTED; + + prVhtSupportedMcsSet->u2RxMcsMap |= (ucMcsMap << ucOffset); + prVhtSupportedMcsSet->u2TxMcsMap |= (ucMcsMap << ucOffset); + } + +#if 0 + for (i = 0; i < wlanGetSupportNss(prAdapter, + prBssInfo->ucBssIndex); i++) { + uint8_t ucOffset = i * 2; + + prVhtSupportedMcsSet->u2RxMcsMap &= + ((VHT_CAP_INFO_MCS_MAP_MCS9 << ucOffset) & + BITS(ucOffset, ucOffset + 1)); + prVhtSupportedMcsSet->u2TxMcsMap &= + ((VHT_CAP_INFO_MCS_MAP_MCS9 << ucOffset) & + BITS(ucOffset, ucOffset + 1)); + } +#endif + + prVhtSupportedMcsSet->u2RxHighestSupportedDataRate = + VHT_CAP_INFO_DEFAULT_HIGHEST_DATA_RATE; + prVhtSupportedMcsSet->u2TxHighestSupportedDataRate = + VHT_CAP_INFO_DEFAULT_HIGHEST_DATA_RATE; + + ASSERT(IE_SIZE(prVhtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_VHT_CAP)); + + prMsduInfo->u2FrameLength += IE_SIZE(prVhtCap); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rlmFillVhtOpIE(struct ADAPTER *prAdapter, struct BSS_INFO *prBssInfo, + struct MSDU_INFO *prMsduInfo) +{ + struct IE_VHT_OP *prVhtOp; + + ASSERT(prAdapter); + ASSERT(prBssInfo); + ASSERT(prMsduInfo); + + prVhtOp = (struct IE_VHT_OP *)(((uint8_t *)prMsduInfo->prPacket) + + prMsduInfo->u2FrameLength); + + /* Add HT operation IE */ + prVhtOp->ucId = ELEM_ID_VHT_OP; + prVhtOp->ucLength = sizeof(struct IE_VHT_OP) - ELEM_HDR_LEN; + + ASSERT(IE_SIZE(prVhtOp) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_VHT_OP)); + + /* (UINT8)VHT_OP_CHANNEL_WIDTH_80; */ + prVhtOp->ucVhtOperation[0] = prBssInfo->ucVhtChannelWidth; + prVhtOp->ucVhtOperation[1] = prBssInfo->ucVhtChannelFrequencyS1; + prVhtOp->ucVhtOperation[2] = prBssInfo->ucVhtChannelFrequencyS2; + +#if 0 + if (cnmGetBssMaxBw(prAdapter, prBssInfo->ucBssIndex) < MAX_BW_80MHZ) { + prVhtOp->ucVhtOperation[0] = VHT_OP_CHANNEL_WIDTH_20_40; + prVhtOp->ucVhtOperation[1] = 0; + prVhtOp->ucVhtOperation[2] = 0; + } else if (cnmGetBssMaxBw(prAdapter, prBssInfo->ucBssIndex) == + MAX_BW_80MHZ) { + prVhtOp->ucVhtOperation[0] = VHT_OP_CHANNEL_WIDTH_80; + prVhtOp->ucVhtOperation[1] = + nicGetVhtS1(prBssInfo->ucPrimaryChannel); + prVhtOp->ucVhtOperation[2] = 0; + } else { + /* TODO: BW80 + 80/160 support */ + } +#endif + + prVhtOp->u2VhtBasicMcsSet = prBssInfo->u2VhtBasicMcsSet; + + prMsduInfo->u2FrameLength += IE_SIZE(prVhtOp); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Get RxNss from VHT CAP IE. + * + * \param[in] prVhtCap + * + * \return ucRxNss + */ +/*----------------------------------------------------------------------------*/ +uint8_t +rlmGetSupportRxNssInVhtCap(struct IE_VHT_CAP *prVhtCap) +{ + uint8_t ucRxNss = 1; + + if (prVhtCap) { + if (((prVhtCap->rVhtSupportedMcsSet.u2RxMcsMap & + VHT_CAP_INFO_MCS_2SS_MASK) >> + VHT_CAP_INFO_MCS_2SS_OFFSET) + != VHT_CAP_INFO_MCS_NOT_SUPPORTED) + ucRxNss = 2; + if (((prVhtCap->rVhtSupportedMcsSet.u2RxMcsMap & + VHT_CAP_INFO_MCS_3SS_MASK) + >> VHT_CAP_INFO_MCS_3SS_OFFSET) + != VHT_CAP_INFO_MCS_NOT_SUPPORTED) + ucRxNss = 3; + if (((prVhtCap->rVhtSupportedMcsSet.u2RxMcsMap & + VHT_CAP_INFO_MCS_4SS_MASK) + >> VHT_CAP_INFO_MCS_4SS_OFFSET) + != VHT_CAP_INFO_MCS_NOT_SUPPORTED) + ucRxNss = 4; + if (((prVhtCap->rVhtSupportedMcsSet.u2RxMcsMap & + VHT_CAP_INFO_MCS_5SS_MASK) + >> VHT_CAP_INFO_MCS_5SS_OFFSET) + != VHT_CAP_INFO_MCS_NOT_SUPPORTED) + ucRxNss = 5; + if (((prVhtCap->rVhtSupportedMcsSet.u2RxMcsMap & + VHT_CAP_INFO_MCS_6SS_MASK) + >> VHT_CAP_INFO_MCS_6SS_OFFSET) + != VHT_CAP_INFO_MCS_NOT_SUPPORTED) + ucRxNss = 6; + if (((prVhtCap->rVhtSupportedMcsSet.u2RxMcsMap & + VHT_CAP_INFO_MCS_7SS_MASK) + >> VHT_CAP_INFO_MCS_7SS_OFFSET) + != VHT_CAP_INFO_MCS_NOT_SUPPORTED) + ucRxNss = 7; + if (((prVhtCap->rVhtSupportedMcsSet.u2RxMcsMap & + VHT_CAP_INFO_MCS_8SS_MASK) + >> VHT_CAP_INFO_MCS_8SS_OFFSET) + != VHT_CAP_INFO_MCS_NOT_SUPPORTED) + ucRxNss = 8; + } else + DBGLOG(RLM, WARN, "null prVhtCap, assume RxNss=1\n"); + + return ucRxNss; +} + +#endif + + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rlmGenerateCountryIE(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo) +{ + struct BSS_INFO *prBssInfo = + prAdapter->aprBssInfo[prMsduInfo->ucBssIndex]; + unsigned char *pucBuf = + (((unsigned char *) prMsduInfo->prPacket) + + prMsduInfo->u2FrameLength); + + if (prBssInfo->aucCountryStr[0] == 0) + return; + + COUNTRY_IE(pucBuf)->ucId = ELEM_ID_COUNTRY_INFO; + COUNTRY_IE(pucBuf)->ucLength = prBssInfo->ucCountryIELen; + COUNTRY_IE(pucBuf)->aucCountryStr[0] = prBssInfo->aucCountryStr[0]; + COUNTRY_IE(pucBuf)->aucCountryStr[1] = prBssInfo->aucCountryStr[1]; + COUNTRY_IE(pucBuf)->aucCountryStr[2] = prBssInfo->aucCountryStr[2]; + kalMemCopy(COUNTRY_IE(pucBuf)->arCountryStr, + prBssInfo->aucSubbandTriplet, + prBssInfo->ucCountryIELen - 3); + + prMsduInfo->u2FrameLength += IE_SIZE(pucBuf); +} + +#if CFG_SUPPORT_CAL_RESULT_BACKUP_TO_HOST +uint32_t rlmCalBackup(struct ADAPTER *prAdapter, uint8_t ucReason, + uint8_t ucAction, uint8_t ucRomRam) +{ + uint32_t rStatus = WLAN_STATUS_FAILURE; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_CAL_BACKUP_STRUCT_V2 rCalBackupDataV2; + uint32_t u4BufLen = 0; + + ASSERT(prAdapter); + ASSERT(prAdapter->prGlueInfo); + + prGlueInfo = prAdapter->prGlueInfo; + + rCalBackupDataV2.ucReason = ucReason; + rCalBackupDataV2.ucAction = ucAction; + rCalBackupDataV2.ucNeedResp = 1; + rCalBackupDataV2.ucFragNum = 0; + rCalBackupDataV2.ucRomRam = ucRomRam; + rCalBackupDataV2.u4ThermalValue = 0; + rCalBackupDataV2.u4Address = 0; + rCalBackupDataV2.u4Length = 0; + rCalBackupDataV2.u4RemainLength = 0; + + if (ucReason == 0 && ucAction == 0) { + DBGLOG(RFTEST, INFO, "RLM CMD : Get Thermal Temp from FW.\n"); + /* Step 1 : Get Thermal Temp from FW */ + + rStatus = kalIoctl(prGlueInfo, wlanoidQueryCalBackupV2, + &rCalBackupDataV2, + sizeof(struct PARAM_CAL_BACKUP_STRUCT_V2), + TRUE, TRUE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(RFTEST, INFO, + "RLM CMD : Get Thermal Temp from FW Return Fail (0x%08x)!!!!!!!!!!!\n", + rStatus); + return rStatus; + } + + DBGLOG(RFTEST, INFO, + "CMD : Get Thermal Temp (%d) from FW. Finish!!!!!!!!!!!\n", + rCalBackupDataV2.u4ThermalValue); + } else if (ucReason == 1 && ucAction == 2) { + DBGLOG(RFTEST, INFO, "RLM CMD : Trigger FW Do All Cal.\n"); + /* Step 2 : Trigger All Cal Function */ + + rStatus = kalIoctl(prGlueInfo, wlanoidSetCalBackup, + &rCalBackupDataV2, + sizeof(struct PARAM_CAL_BACKUP_STRUCT_V2), + FALSE, FALSE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(RFTEST, INFO, + "RLM CMD : Trigger FW Do All Cal Return Fail (0x%08x)!!!!!!!!!!!\n", + rStatus); + return rStatus; + } + + DBGLOG(RFTEST, INFO, + "CMD : Trigger FW Do All Cal. Finish!!!!!!!!!!!\n"); + } else if (ucReason == 0 && ucAction == 1) { + DBGLOG(RFTEST, INFO, + "RLM CMD : Get Cal Data (%s) Size from FW.\n", + ucRomRam == 0 ? "ROM" : "RAM"); + /* Step 3 : Get Cal Data Size from FW */ + + rStatus = kalIoctl(prGlueInfo, wlanoidQueryCalBackupV2, + &rCalBackupDataV2, + sizeof(struct PARAM_CAL_BACKUP_STRUCT_V2), + TRUE, TRUE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(RFTEST, INFO, + "RLM CMD : Get Cal Data (%s) Size from FW Return Fail (0x%08x)!!!!!!!!!!!\n", + ucRomRam == 0 ? "ROM" : "RAM", rStatus); + return rStatus; + } + + DBGLOG(RFTEST, INFO, + "CMD : Get Cal Data (%s) Size from FW. Finish!!!!!!!!!!!\n", + ucRomRam == 0 ? "ROM" : "RAM"); + } else if (ucReason == 2 && ucAction == 4) { + DBGLOG(RFTEST, INFO, + "RLM CMD : Get Cal Data from FW (%s). Start!!!!!!!!!!!!!!!!\n", + ucRomRam == 0 ? "ROM" : "RAM"); + DBGLOG(RFTEST, INFO, "Thermal Temp = %d\n", + g_rBackupCalDataAllV2.u4ThermalInfo); + /* Step 4 : Get Cal Data from FW */ + + rStatus = kalIoctl(prGlueInfo, wlanoidQueryCalBackupV2, + &rCalBackupDataV2, + sizeof(struct PARAM_CAL_BACKUP_STRUCT_V2), + TRUE, TRUE, TRUE, &u4BufLen); + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(RFTEST, INFO, + "RLM CMD : Get Cal Data (%s) Size from FW Return Fail (0x%08x)!!!!!!!!!!!\n", + ucRomRam == 0 ? "ROM" : "RAM", rStatus); + return rStatus; + } + + DBGLOG(RFTEST, INFO, + "CMD : Get Cal Data from FW (%s). Finish!!!!!!!!!!!\n", + ucRomRam == 0 ? "ROM" : "RAM"); + + if (ucRomRam == 0) { + DBGLOG(RFTEST, INFO, + "Check some of elements (0x%08x), (0x%08x), (0x%08x), (0x%08x), (0x%08x)\n", + g_rBackupCalDataAllV2.au4RomCalData[670], + g_rBackupCalDataAllV2.au4RomCalData[671], + g_rBackupCalDataAllV2.au4RomCalData[672], + g_rBackupCalDataAllV2.au4RomCalData[673], + g_rBackupCalDataAllV2.au4RomCalData[674]); + DBGLOG(RFTEST, INFO, + "Check some of elements (0x%08x), (0x%08x), (0x%08x), (0x%08x), (0x%08x)\n", + g_rBackupCalDataAllV2.au4RomCalData[675], + g_rBackupCalDataAllV2.au4RomCalData[676], + g_rBackupCalDataAllV2.au4RomCalData[677], + g_rBackupCalDataAllV2.au4RomCalData[678], + g_rBackupCalDataAllV2.au4RomCalData[679]); + } + } else if (ucReason == 4 && ucAction == 6) { + DBGLOG(RFTEST, INFO, "RLM CMD : Print Cal Data in FW (%s).\n", + ucRomRam == 0 ? "ROM" : "RAM"); + /* Debug Use : Print Cal Data in FW */ + + rStatus = kalIoctl(prGlueInfo, wlanoidSetCalBackup, + &rCalBackupDataV2, + sizeof(struct PARAM_CAL_BACKUP_STRUCT_V2), + TRUE, TRUE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(RFTEST, INFO, + "RLM CMD : Print Cal Data in FW (%s) Return Fail (0x%08x)!!!!!!!!!!!\n", + ucRomRam == 0 ? "ROM" : "RAM", rStatus); + return rStatus; + } + + DBGLOG(RFTEST, INFO, + "CMD : Print Cal Data in FW (%s). Finish!!!!!!!!!!!\n", + ucRomRam == 0 ? "ROM" : "RAM"); + } else if (ucReason == 3 && ucAction == 5) { + DBGLOG(RFTEST, INFO, "RLM CMD : Send Cal Data to FW (%s).\n", + ucRomRam == 0 ? "ROM" : "RAM"); + /* Send Cal Data to FW */ + + rStatus = kalIoctl(prGlueInfo, wlanoidSetCalBackup, + &rCalBackupDataV2, + sizeof(struct PARAM_CAL_BACKUP_STRUCT_V2), + TRUE, TRUE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(RFTEST, INFO, + "RLM CMD : Send Cal Data to FW (%s) Return Fail (0x%08x)!!!!!!!!!!!\n", + ucRomRam == 0 ? "ROM" : "RAM", rStatus); + return rStatus; + } + + DBGLOG(RFTEST, INFO, + "CMD : Send Cal Data to FW (%s). Finish!!!!!!!!!!!\n", + ucRomRam == 0 ? "ROM" : "RAM"); + } else { + DBGLOG(RFTEST, INFO, + "CMD : Undefined Reason (%d) and Action (%d) for Cal Backup in Host Side!\n", + ucReason, ucAction); + + return rStatus; + } + + return rStatus; +} + +uint32_t rlmTriggerCalBackup(struct ADAPTER *prAdapter, + u_int8_t fgIsCalDataBackuped) +{ + uint32_t rStatus = WLAN_STATUS_SUCCESS; + + if (!fgIsCalDataBackuped) { + DBGLOG(RFTEST, INFO, + "======== Boot Time Wi-Fi Enable........\n"); + DBGLOG(RFTEST, INFO, + "Step 0 : Reset All Cal Data in Driver.\n"); + memset(&g_rBackupCalDataAllV2, 1, + sizeof(struct RLM_CAL_RESULT_ALL_V2)); + g_rBackupCalDataAllV2.u4MagicNum1 = 6632; + g_rBackupCalDataAllV2.u4MagicNum2 = 6632; + + DBGLOG(RFTEST, INFO, "Step 1 : Get Thermal Temp from FW.\n"); + if (rlmCalBackup(prAdapter, 0, 0, 0) == WLAN_STATUS_FAILURE) { + DBGLOG(RFTEST, INFO, "Step 1 : Return Failure.\n"); + return WLAN_STATUS_FAILURE; + } + + DBGLOG(RFTEST, INFO, + "Step 2 : Get Rom Cal Data Size from FW.\n"); + if (rlmCalBackup(prAdapter, 0, 1, 0) == WLAN_STATUS_FAILURE) { + DBGLOG(RFTEST, INFO, "Step 2 : Return Failure.\n"); + return WLAN_STATUS_FAILURE; + } + + DBGLOG(RFTEST, INFO, + "Step 3 : Get Ram Cal Data Size from FW.\n"); + if (rlmCalBackup(prAdapter, 0, 1, 1) == WLAN_STATUS_FAILURE) { + DBGLOG(RFTEST, INFO, "Step 3 : Return Failure.\n"); + return WLAN_STATUS_FAILURE; + } + + DBGLOG(RFTEST, INFO, "Step 4 : Trigger FW Do Full Cal.\n"); + if (rlmCalBackup(prAdapter, 1, 2, 0) == WLAN_STATUS_FAILURE) { + DBGLOG(RFTEST, INFO, "Step 4 : Return Failure.\n"); + return WLAN_STATUS_FAILURE; + } + } else { + DBGLOG(RFTEST, INFO, "======== Normal Wi-Fi Enable........\n"); + DBGLOG(RFTEST, INFO, "Step 0 : Sent Rom Cal data to FW.\n"); + if (rlmCalBackup(prAdapter, 3, 5, 0) == WLAN_STATUS_FAILURE) { + DBGLOG(RFTEST, INFO, "Step 0 : Return Failure.\n"); + return WLAN_STATUS_FAILURE; + } + + DBGLOG(RFTEST, INFO, "Step 1 : Sent Ram Cal data to FW.\n"); + if (rlmCalBackup(prAdapter, 3, 5, 1) == WLAN_STATUS_FAILURE) { + DBGLOG(RFTEST, INFO, "Step 1 : Return Failure.\n"); + return WLAN_STATUS_FAILURE; + } + } + + return rStatus; +} +#endif + +void rlmModifyVhtBwPara(uint8_t *pucVhtChannelFrequencyS1, + uint8_t *pucVhtChannelFrequencyS2, + uint8_t *pucVhtChannelWidth) +{ + uint8_t i = 0, ucTempS = 0; + + if ((*pucVhtChannelFrequencyS1 != 0) && + (*pucVhtChannelFrequencyS2 != 0)) { + + uint8_t ucBW160Inteval = 8; + + if (((*pucVhtChannelFrequencyS2 - *pucVhtChannelFrequencyS1) == + ucBW160Inteval) || + ((*pucVhtChannelFrequencyS1 - *pucVhtChannelFrequencyS2) == + ucBW160Inteval)) { + /*C160 case*/ + + /* NEW spec should set central ch of bw80 at S1, + * set central ch of bw160 at S2 + */ + for (i = 0; i < 2; i++) { + + if (i == 0) + ucTempS = *pucVhtChannelFrequencyS1; + else + ucTempS = *pucVhtChannelFrequencyS2; + + if ((ucTempS == 50) || (ucTempS == 82) || + (ucTempS == 114) || (ucTempS == 163)) + break; + } + + if (ucTempS == 0) { + DBGLOG(RLM, WARN, + "please check BW160 setting, find central freq fail\n"); + return; + } + + *pucVhtChannelFrequencyS1 = ucTempS; + *pucVhtChannelFrequencyS2 = 0; + *pucVhtChannelWidth = CW_160MHZ; + } else { + /*real 80P80 case*/ + } + } +} + +static void rlmRevisePreferBandwidthNss(struct ADAPTER *prAdapter, + uint8_t ucBssIndex, + struct STA_RECORD *prStaRec) +{ + enum ENUM_CHANNEL_WIDTH eChannelWidth = CW_20_40MHZ; + struct BSS_INFO *prBssInfo; + +#define VHT_MCS_TX_RX_MAX_2SS BITS(2, 3) +#define VHT_MCS_TX_RX_MAX_2SS_SHIFT 2 + +#define AR_STA_2AC_MCS(prStaRec) \ + (((prStaRec)->u2VhtRxMcsMap & VHT_MCS_TX_RX_MAX_2SS) >> \ + VHT_MCS_TX_RX_MAX_2SS_SHIFT) + +#define AR_IS_STA_2SS_AC(prStaRec) ((AR_STA_2AC_MCS(prStaRec) != BITS(0, 1))) + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + + eChannelWidth = prBssInfo->ucVhtChannelWidth; + + /* + * Prefer setting modification + * 80+80 1x1 and 80 2x2 have the same phy rate, choose the 80 2x2 + */ + + if (AR_IS_STA_2SS_AC(prStaRec)) { + /* + * DBGLOG(RLM, WARN, "support 2ss\n"); + */ + + if ((eChannelWidth == CW_80P80MHZ && + prBssInfo->ucVhtChannelFrequencyS2 != 0)) { + DBGLOG(RLM, WARN, "support (2Nss) and (80+80)\n"); + DBGLOG(RLM, WARN, + "choose (2Nss) and (80) for Bss_info\n"); + prBssInfo->ucVhtChannelWidth = CW_80MHZ; + prBssInfo->ucVhtChannelFrequencyS2 = 0; + } + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Revise operating BW by own maximum bandwidth capability + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rlmReviseMaxBw(struct ADAPTER *prAdapter, uint8_t ucBssIndex, + enum ENUM_CHNL_EXT *peExtend, + enum ENUM_CHANNEL_WIDTH *peChannelWidth, uint8_t *pucS1, + uint8_t *pucPrimaryCh) +{ + uint8_t ucMaxBandwidth = MAX_BW_80MHZ; + uint8_t ucCurrentBandwidth = MAX_BW_20MHZ; + uint8_t ucOffset = (MAX_BW_80MHZ - CW_80MHZ); + + ucMaxBandwidth = cnmGetDbdcBwCapability(prAdapter, ucBssIndex); + + if (*peChannelWidth > CW_20_40MHZ) { + /*case BW > 80 , 160 80P80 */ + ucCurrentBandwidth = (uint8_t)*peChannelWidth + ucOffset; + } else { + /*case BW20 BW40 */ + if (*peExtend != CHNL_EXT_SCN) { + /*case BW40 */ + ucCurrentBandwidth = MAX_BW_40MHZ; + } + } + + if (ucCurrentBandwidth > ucMaxBandwidth) { + DBGLOG(RLM, INFO, "Decreasse the BW to (%d)\n", ucMaxBandwidth); + + if (ucMaxBandwidth <= MAX_BW_40MHZ) { + /*BW20 * BW40*/ + *peChannelWidth = CW_20_40MHZ; + + if (ucMaxBandwidth == MAX_BW_20MHZ) + *peExtend = CHNL_EXT_SCN; + } else { + /* BW80, BW160, BW80P80 + * ucMaxBandwidth Must be + * MAX_BW_80MHZ,MAX_BW_160MHZ,MAX_BW_80MHZ + * peExtend should not change + */ + *peChannelWidth = (ucMaxBandwidth - ucOffset); + + if (ucMaxBandwidth == MAX_BW_80MHZ) { + /* modify S1 for Bandwidth 160 downgrade 80 case + */ + if (ucCurrentBandwidth == MAX_BW_160MHZ) { + if ((*pucPrimaryCh >= 36) && + (*pucPrimaryCh <= 48)) + *pucS1 = 42; + else if ((*pucPrimaryCh >= 52) && + (*pucPrimaryCh <= 64)) + *pucS1 = 58; + else if ((*pucPrimaryCh >= 100) && + (*pucPrimaryCh <= 112)) + *pucS1 = 106; + else if ((*pucPrimaryCh >= 116) && + (*pucPrimaryCh <= 128)) + *pucS1 = 122; + else if ((*pucPrimaryCh >= 132) && + (*pucPrimaryCh <= 144)) + /* 160 downgrade should not in + * this case + */ + *pucS1 = 138; + else if ((*pucPrimaryCh >= 149) && + (*pucPrimaryCh <= 161)) + /* 160 downgrade should not in + * this case + */ + *pucS1 = 155; + else + DBGLOG(RLM, INFO, + "Check connect 160 downgrde (%d) case\n", + ucMaxBandwidth); + + DBGLOG(RLM, INFO, + "Decreasse the BW160 to BW80, shift S1 to (%d)\n", + *pucS1); + } + } + } + + DBGLOG(RLM, INFO, "Modify ChannelWidth (%d) and Extend (%d)\n", + *peChannelWidth, *peExtend); + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Fill VHT Operation Information(VHT BW, S1, S2) by BSS operating + * channel width + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rlmFillVhtOpInfoByBssOpBw(struct BSS_INFO *prBssInfo, uint8_t ucBssOpBw) +{ + ASSERT(prBssInfo); + + if (ucBssOpBw < MAX_BW_80MHZ || prBssInfo->eBand == BAND_2G4) { + prBssInfo->ucVhtChannelWidth = VHT_OP_CHANNEL_WIDTH_20_40; + prBssInfo->ucVhtChannelFrequencyS1 = 0; + prBssInfo->ucVhtChannelFrequencyS2 = 0; + } else if (ucBssOpBw == MAX_BW_80MHZ) { + prBssInfo->ucVhtChannelWidth = VHT_OP_CHANNEL_WIDTH_80; + prBssInfo->ucVhtChannelFrequencyS1 = nicGetVhtS1( + prBssInfo->ucPrimaryChannel, VHT_OP_CHANNEL_WIDTH_80); + prBssInfo->ucVhtChannelFrequencyS2 = 0; + } else if (ucBssOpBw == MAX_BW_160MHZ) { + prBssInfo->ucVhtChannelWidth = VHT_OP_CHANNEL_WIDTH_160; + prBssInfo->ucVhtChannelFrequencyS1 = nicGetVhtS1( + prBssInfo->ucPrimaryChannel, VHT_OP_CHANNEL_WIDTH_160); + prBssInfo->ucVhtChannelFrequencyS2 = 0; + } else { + /* 4 TODO: / BW80+80 support */ + DBGLOG(RLM, INFO, "Unsupport BW setting, back to VHT20_40\n"); + + prBssInfo->ucVhtChannelWidth = VHT_OP_CHANNEL_WIDTH_20_40; + prBssInfo->ucVhtChannelFrequencyS1 = 0; + prBssInfo->ucVhtChannelFrequencyS2 = 0; + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function should be invoked to update parameters of associated AP. + * (Association response and Beacon) + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +static uint8_t rlmRecIeInfoForClient(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, uint8_t *pucIE, + uint16_t u2IELength) +{ + uint16_t u2Offset; + struct STA_RECORD *prStaRec; + struct IE_HT_CAP *prHtCap; + struct IE_HT_OP *prHtOp; + struct IE_OBSS_SCAN_PARAM *prObssScnParam; + uint8_t ucERP, ucPrimaryChannel; + struct WIFI_VAR *prWifiVar = &prAdapter->rWifiVar; +#if CFG_SUPPORT_QUIET && 0 + u_int8_t fgHasQuietIE = FALSE; +#endif + u_int8_t IsfgHtCapChange = FALSE; + +#if CFG_SUPPORT_802_11AC + struct IE_VHT_OP *prVhtOp; + struct IE_VHT_CAP *prVhtCap = NULL; + struct IE_OP_MODE_NOTIFICATION *prOPNotif; + uint8_t fgHasOPModeIE = FALSE; + uint8_t fgHasNewOPModeIE = FALSE; + uint8_t ucVhtOpModeChannelWidth = 0; + uint8_t ucVhtOpModeRxNss = 0; + uint8_t ucMaxBwAllowed; + uint8_t ucInitVhtOpMode = 0; +#endif + +#if CFG_SUPPORT_DFS + u_int8_t fgHasWideBandIE = FALSE; + u_int8_t fgHasSCOIE = FALSE; + u_int8_t fgHasChannelSwitchIE = FALSE; + u_int8_t fgNeedSwitchChannel = FALSE; + uint8_t ucChannelAnnouncePri; + enum ENUM_CHNL_EXT eChannelAnnounceSco; + uint8_t ucChannelAnnounceChannelS1 = 0; + uint8_t ucChannelAnnounceChannelS2 = 0; + uint8_t ucChannelAnnounceVhtBw; + struct IE_CHANNEL_SWITCH *prChannelSwitchAnnounceIE; + struct IE_SECONDARY_OFFSET *prSecondaryOffsetIE; + struct IE_WIDE_BAND_CHANNEL *prWideBandChannelIE; +#endif + uint8_t *pucDumpIE; + + ASSERT(prAdapter); + ASSERT(prBssInfo); + ASSERT(pucIE); + + prStaRec = prBssInfo->prStaRecOfAP; + if (!prStaRec) + return 0; + + prBssInfo->fgUseShortPreamble = prBssInfo->fgIsShortPreambleAllowed; + ucPrimaryChannel = 0; + prObssScnParam = NULL; + ucMaxBwAllowed = cnmGetBssMaxBw(prAdapter, prBssInfo->ucBssIndex); + pucDumpIE = pucIE; + + /* Note: HT-related members in staRec may not be zero before, so + * if following IE does not exist, they are still not zero. + * These HT-related parameters are valid only when the + * corresponding + * BssInfo supports 802.11n, i.e., RLM_NET_IS_11N() + */ + IE_FOR_EACH(pucIE, u2IELength, u2Offset) + { + switch (IE_ID(pucIE)) { + case ELEM_ID_HT_CAP: + if (!RLM_NET_IS_11N(prBssInfo) || + IE_LEN(pucIE) != (sizeof(struct IE_HT_CAP) - 2)) + break; + prHtCap = (struct IE_HT_CAP *)pucIE; + prStaRec->ucMcsSet = + prHtCap->rSupMcsSet.aucRxMcsBitmask[0]; + prStaRec->fgSupMcs32 = + (prHtCap->rSupMcsSet.aucRxMcsBitmask[32 / 8] & + BIT(0)) + ? TRUE + : FALSE; + + kalMemCopy( + prStaRec->aucRxMcsBitmask, + prHtCap->rSupMcsSet.aucRxMcsBitmask, + /*SUP_MCS_RX_BITMASK_OCTET_NUM */ + sizeof(prStaRec->aucRxMcsBitmask)); + + prStaRec->u2RxHighestSupportedRate = + prHtCap->rSupMcsSet.u2RxHighestSupportedRate; + prStaRec->u4TxRateInfo = + prHtCap->rSupMcsSet.u4TxRateInfo; + + if ((prStaRec->u2HtCapInfo & + HT_CAP_INFO_SM_POWER_SAVE) != + (prHtCap->u2HtCapInfo & HT_CAP_INFO_SM_POWER_SAVE)) + /* Purpose : To detect SMPS change */ + IsfgHtCapChange = TRUE; + + prStaRec->u2HtCapInfo = prHtCap->u2HtCapInfo; + /* Set LDPC Tx capability */ + if (IS_FEATURE_FORCE_ENABLED(prWifiVar->ucTxLdpc)) + prStaRec->u2HtCapInfo |= HT_CAP_INFO_LDPC_CAP; + else if (IS_FEATURE_DISABLED(prWifiVar->ucTxLdpc)) + prStaRec->u2HtCapInfo &= ~HT_CAP_INFO_LDPC_CAP; + + /* Set STBC Tx capability */ + if (IS_FEATURE_FORCE_ENABLED(prWifiVar->ucTxStbc)) + prStaRec->u2HtCapInfo |= HT_CAP_INFO_RX_STBC; + else if (IS_FEATURE_DISABLED(prWifiVar->ucTxStbc)) + prStaRec->u2HtCapInfo &= ~HT_CAP_INFO_RX_STBC; + + /* Set Short GI Tx capability */ + if (IS_FEATURE_FORCE_ENABLED(prWifiVar->ucTxShortGI)) { + prStaRec->u2HtCapInfo |= + HT_CAP_INFO_SHORT_GI_20M; + prStaRec->u2HtCapInfo |= + HT_CAP_INFO_SHORT_GI_40M; + } else if (IS_FEATURE_DISABLED( + prWifiVar->ucTxShortGI)) { + prStaRec->u2HtCapInfo &= + ~HT_CAP_INFO_SHORT_GI_20M; + prStaRec->u2HtCapInfo &= + ~HT_CAP_INFO_SHORT_GI_40M; + } + + /* Set HT Greenfield Tx capability */ + if (IS_FEATURE_FORCE_ENABLED(prWifiVar->ucTxGf)) + prStaRec->u2HtCapInfo |= HT_CAP_INFO_HT_GF; + else if (IS_FEATURE_DISABLED(prWifiVar->ucTxGf)) + prStaRec->u2HtCapInfo &= ~HT_CAP_INFO_HT_GF; + + prStaRec->ucAmpduParam = prHtCap->ucAmpduParam; + prStaRec->u2HtExtendedCap = prHtCap->u2HtExtendedCap; + prStaRec->u4TxBeamformingCap = + prHtCap->u4TxBeamformingCap; + prStaRec->ucAselCap = prHtCap->ucAselCap; + break; + + case ELEM_ID_HT_OP: + if (!RLM_NET_IS_11N(prBssInfo) || + IE_LEN(pucIE) != (sizeof(struct IE_HT_OP) - 2)) + break; + prHtOp = (struct IE_HT_OP *)pucIE; + /* Workaround that some APs fill primary channel field + * by its + * secondary channel, but its DS IE is correct 20110610 + */ + if (ucPrimaryChannel == 0) + ucPrimaryChannel = prHtOp->ucPrimaryChannel; + prBssInfo->ucHtOpInfo1 = prHtOp->ucInfo1; + prBssInfo->u2HtOpInfo2 = prHtOp->u2Info2; + prBssInfo->u2HtOpInfo3 = prHtOp->u2Info3; + + /*Backup peer HT OP Info*/ + prStaRec->ucHtPeerOpInfo1 = prHtOp->ucInfo1; + + if (!prBssInfo->fg40mBwAllowed) + prBssInfo->ucHtOpInfo1 &= + ~(HT_OP_INFO1_SCO | + HT_OP_INFO1_STA_CHNL_WIDTH); + + if ((prBssInfo->ucHtOpInfo1 & HT_OP_INFO1_SCO) != + CHNL_EXT_RES) + prBssInfo->eBssSCO = (enum ENUM_CHNL_EXT)( + prBssInfo->ucHtOpInfo1 & + HT_OP_INFO1_SCO); + + /* Revise by own OP BW */ + if (prBssInfo->fgIsOpChangeChannelWidth && + prBssInfo->ucOpChangeChannelWidth == MAX_BW_20MHZ) { + prBssInfo->ucHtOpInfo1 &= + ~(HT_OP_INFO1_SCO | + HT_OP_INFO1_STA_CHNL_WIDTH); + prBssInfo->eBssSCO = CHNL_EXT_SCN; + } + + prBssInfo->eHtProtectMode = (enum ENUM_HT_PROTECT_MODE)( + prBssInfo->u2HtOpInfo2 & + HT_OP_INFO2_HT_PROTECTION); + + /* To do: process regulatory class 16 */ + if ((prBssInfo->u2HtOpInfo2 & + HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT) && + 0 /* && regulatory class is 16 */) + prBssInfo->eGfOperationMode = + GF_MODE_DISALLOWED; + else if (prBssInfo->u2HtOpInfo2 & + HT_OP_INFO2_NON_GF_HT_STA_PRESENT) + prBssInfo->eGfOperationMode = GF_MODE_PROTECT; + else + prBssInfo->eGfOperationMode = GF_MODE_NORMAL; + + prBssInfo->eRifsOperationMode = + (prBssInfo->ucHtOpInfo1 & HT_OP_INFO1_RIFS_MODE) + ? RIFS_MODE_NORMAL + : RIFS_MODE_DISALLOWED; + + break; + +#if CFG_SUPPORT_802_11AC + case ELEM_ID_VHT_CAP: + if (!RLM_NET_IS_11AC(prBssInfo) || + IE_LEN(pucIE) != (sizeof(struct IE_VHT_CAP) - 2)) + break; + + prVhtCap = (struct IE_VHT_CAP *)pucIE; + + prStaRec->u4VhtCapInfo = prVhtCap->u4VhtCapInfo; + /* Set Tx LDPC capability */ + if (IS_FEATURE_FORCE_ENABLED(prWifiVar->ucTxLdpc)) + prStaRec->u4VhtCapInfo |= VHT_CAP_INFO_RX_LDPC; + else if (IS_FEATURE_DISABLED(prWifiVar->ucTxLdpc)) + prStaRec->u4VhtCapInfo &= ~VHT_CAP_INFO_RX_LDPC; + + /* Set Tx STBC capability */ + if (IS_FEATURE_FORCE_ENABLED(prWifiVar->ucTxStbc)) + prStaRec->u4VhtCapInfo |= + VHT_CAP_INFO_RX_STBC_MASK; + else if (IS_FEATURE_DISABLED(prWifiVar->ucTxStbc)) + prStaRec->u4VhtCapInfo &= + ~VHT_CAP_INFO_RX_STBC_MASK; + + /* Set Tx TXOP PS capability */ + if (IS_FEATURE_FORCE_ENABLED(prWifiVar->ucTxopPsTx)) + prStaRec->u4VhtCapInfo |= + VHT_CAP_INFO_VHT_TXOP_PS; + else if (IS_FEATURE_DISABLED(prWifiVar->ucTxopPsTx)) + prStaRec->u4VhtCapInfo &= + ~VHT_CAP_INFO_VHT_TXOP_PS; + + /* Set Tx Short GI capability */ + if (IS_FEATURE_FORCE_ENABLED(prWifiVar->ucTxShortGI)) { + prStaRec->u4VhtCapInfo |= + VHT_CAP_INFO_SHORT_GI_80; + prStaRec->u4VhtCapInfo |= + VHT_CAP_INFO_SHORT_GI_160_80P80; + } else if (IS_FEATURE_DISABLED( + prWifiVar->ucTxShortGI)) { + prStaRec->u4VhtCapInfo &= + ~VHT_CAP_INFO_SHORT_GI_80; + prStaRec->u4VhtCapInfo &= + ~VHT_CAP_INFO_SHORT_GI_160_80P80; + } + + prStaRec->u2VhtRxMcsMap = + prVhtCap->rVhtSupportedMcsSet.u2RxMcsMap; + prStaRec->u2VhtRxMcsMapAssoc = + prStaRec->u2VhtRxMcsMap; + + prStaRec->u2VhtRxHighestSupportedDataRate = + prVhtCap->rVhtSupportedMcsSet + .u2RxHighestSupportedDataRate; + prStaRec->u2VhtTxMcsMap = + prVhtCap->rVhtSupportedMcsSet.u2TxMcsMap; + prStaRec->u2VhtTxHighestSupportedDataRate = + prVhtCap->rVhtSupportedMcsSet + .u2TxHighestSupportedDataRate; + + break; + + case ELEM_ID_VHT_OP: + if (!RLM_NET_IS_11AC(prBssInfo) || + IE_LEN(pucIE) != (sizeof(struct IE_VHT_OP) - 2)) + break; + + prVhtOp = (struct IE_VHT_OP *)pucIE; + + /*Backup peer VHT OpInfo*/ + prStaRec->ucVhtOpChannelWidth = + prVhtOp->ucVhtOperation[0]; + prStaRec->ucVhtOpChannelFrequencyS1 = + prVhtOp->ucVhtOperation[1]; + prStaRec->ucVhtOpChannelFrequencyS2 = + prVhtOp->ucVhtOperation[2]; + + rlmModifyVhtBwPara(&prStaRec->ucVhtOpChannelFrequencyS1, + &prStaRec->ucVhtOpChannelFrequencyS2, + &prStaRec->ucVhtOpChannelWidth); + + prBssInfo->ucVhtChannelWidth = + prVhtOp->ucVhtOperation[0]; + prBssInfo->ucVhtChannelFrequencyS1 = + prVhtOp->ucVhtOperation[1]; + prBssInfo->ucVhtChannelFrequencyS2 = + prVhtOp->ucVhtOperation[2]; + prBssInfo->u2VhtBasicMcsSet = prVhtOp->u2VhtBasicMcsSet; + + rlmModifyVhtBwPara(&prBssInfo->ucVhtChannelFrequencyS1, + &prBssInfo->ucVhtChannelFrequencyS2, + &prBssInfo->ucVhtChannelWidth); + + /* Revise by own OP BW if needed */ + if ((prBssInfo->fgIsOpChangeChannelWidth) && + (rlmGetVhtOpBwByBssOpBw( + prBssInfo->ucOpChangeChannelWidth) < + prBssInfo->ucVhtChannelWidth)) { + rlmFillVhtOpInfoByBssOpBw( + prBssInfo, + prBssInfo->ucOpChangeChannelWidth); + } + + break; + case ELEM_ID_OP_MODE: + if (!RLM_NET_IS_11AC(prBssInfo) || + IE_LEN(pucIE) != + (sizeof(struct IE_OP_MODE_NOTIFICATION) - + 2)) + break; + prOPNotif = (struct IE_OP_MODE_NOTIFICATION *) pucIE; + + /* NOTE: An AP always sets this field to 0, + * so break it if this bit is set. + */ + if ((prOPNotif->ucOpMode & VHT_OP_MODE_RX_NSS_TYPE) + == VHT_OP_MODE_RX_NSS_TYPE) { + break; + } + fgHasOPModeIE = TRUE; + + /* Same OP mode, no need to update. + * Let the further flow not to update VhtOpMode. + */ + if (prStaRec->ucVhtOpMode == prOPNotif->ucOpMode) { + ucInitVhtOpMode = prStaRec->ucVhtOpMode; + break; + } + + fgHasNewOPModeIE = TRUE; + prStaRec->ucVhtOpMode = prOPNotif->ucOpMode; + ucVhtOpModeChannelWidth = + (prOPNotif->ucOpMode & + VHT_OP_MODE_CHANNEL_WIDTH); + ucVhtOpModeRxNss = + (prOPNotif->ucOpMode & VHT_OP_MODE_RX_NSS) + >> VHT_OP_MODE_RX_NSS_OFFSET; + + if (ucVhtOpModeRxNss == VHT_OP_MODE_NSS_2) { + prStaRec->u2VhtRxMcsMap = BITS(0, 15) & + (~(VHT_CAP_INFO_MCS_1SS_MASK | + VHT_CAP_INFO_MCS_2SS_MASK)); + + prStaRec->u2VhtRxMcsMap |= + (prStaRec->u2VhtRxMcsMapAssoc & + (VHT_CAP_INFO_MCS_1SS_MASK | + VHT_CAP_INFO_MCS_2SS_MASK)); + } else { + prStaRec->u2VhtRxMcsMap = BITS(0, 15) & + (~VHT_CAP_INFO_MCS_1SS_MASK); + + prStaRec->u2VhtRxMcsMap |= + (prStaRec->u2VhtRxMcsMapAssoc & + VHT_CAP_INFO_MCS_1SS_MASK); + } + DBGLOG(RLM, INFO, + "NSS=%x RxMcsMap:0x%x, McsMapAssoc:0x%x\n", + ucVhtOpModeRxNss, prStaRec->u2VhtRxMcsMap, + prStaRec->u2VhtRxMcsMapAssoc); + break; +#if CFG_SUPPORT_DFS + case ELEM_ID_WIDE_BAND_CHANNEL_SWITCH: + if (!RLM_NET_IS_11AC(prBssInfo) || + IE_LEN(pucIE) != + (sizeof(struct IE_WIDE_BAND_CHANNEL) - 2)) + break; + DBGLOG(RLM, INFO, + "[Channel Switch] ELEM_ID_WIDE_BAND_CHANNEL_SWITCH, 11AC\n"); + prWideBandChannelIE = + (struct IE_WIDE_BAND_CHANNEL *)pucIE; + ucChannelAnnounceVhtBw = + prWideBandChannelIE->ucNewChannelWidth; + ucChannelAnnounceChannelS1 = + prWideBandChannelIE->ucChannelS1; + ucChannelAnnounceChannelS2 = + prWideBandChannelIE->ucChannelS2; + fgHasWideBandIE = TRUE; + DBGLOG(RLM, INFO, "[Ch] BW=%d, s1=%d, s2=%d\n", + ucChannelAnnounceVhtBw, + ucChannelAnnounceChannelS1, + ucChannelAnnounceChannelS2); + break; +#endif + +#endif + case ELEM_ID_20_40_BSS_COEXISTENCE: + if (!RLM_NET_IS_11N(prBssInfo)) + break; + /* To do: store if scanning exemption grant to BssInfo + */ + break; + + case ELEM_ID_OBSS_SCAN_PARAMS: + if (!RLM_NET_IS_11N(prBssInfo) || + IE_LEN(pucIE) != + (sizeof(struct IE_OBSS_SCAN_PARAM) - 2)) + break; + /* Store OBSS parameters to BssInfo */ + prObssScnParam = (struct IE_OBSS_SCAN_PARAM *)pucIE; + break; + + case ELEM_ID_EXTENDED_CAP: + if (!RLM_NET_IS_11N(prBssInfo)) + break; + /* To do: store extended capability (PSMP, coexist) to + * BssInfo + */ + break; + + case ELEM_ID_ERP_INFO: + if (IE_LEN(pucIE) != (sizeof(struct IE_ERP) - 2) || + prBssInfo->eBand != BAND_2G4) + break; + ucERP = ERP_INFO_IE(pucIE)->ucERP; + prBssInfo->fgErpProtectMode = + (ucERP & ERP_INFO_USE_PROTECTION) ? TRUE + : FALSE; + + if (ucERP & ERP_INFO_BARKER_PREAMBLE_MODE) + prBssInfo->fgUseShortPreamble = FALSE; + break; + + case ELEM_ID_DS_PARAM_SET: + if (IE_LEN(pucIE) == ELEM_MAX_LEN_DS_PARAMETER_SET) + ucPrimaryChannel = + DS_PARAM_IE(pucIE)->ucCurrChnl; + break; +#if CFG_SUPPORT_DFS + case ELEM_ID_CH_SW_ANNOUNCEMENT: + if (IE_LEN(pucIE) != + (sizeof(struct IE_CHANNEL_SWITCH) - 2)) + break; + + prChannelSwitchAnnounceIE = + (struct IE_CHANNEL_SWITCH *)pucIE; + + DBGLOG(RLM, INFO, "[Ch] Count=%d\n", + prChannelSwitchAnnounceIE->ucChannelSwitchCount); + + if (prChannelSwitchAnnounceIE + ->ucChannelSwitchMode == 1) { + /* Need to stop data transmission immediately */ + fgHasChannelSwitchIE = TRUE; + if (!g_fgHasStopTx) { + g_fgHasStopTx = TRUE; + /* AP */ + qmSetStaRecTxAllowed(prAdapter, + prStaRec, + FALSE); + DBGLOG(RLM, EVENT, + "[Ch] TxAllowed = FALSE\n"); + } + + if (prChannelSwitchAnnounceIE + ->ucChannelSwitchCount <= 5) { + DBGLOG(RLM, INFO, + "[Ch] switch channel [%d]->[%d]\n", + prBssInfo->ucPrimaryChannel, + prChannelSwitchAnnounceIE + ->ucNewChannelNum); + ucChannelAnnouncePri = + prChannelSwitchAnnounceIE + ->ucNewChannelNum; + fgNeedSwitchChannel = TRUE; +#ifdef CFG_DFS_CHSW_FORCE_BW20 + g_fgHasChannelSwitchIE = TRUE; +#endif + } +#ifdef CFG_DFS_CHSW_FORCE_BW20 + if (RLM_NET_IS_11AC(prBssInfo)) { + DBGLOG(RLM, INFO, + "Send Operation Action Frame"); + rlmSendOpModeNotificationFrame( + prAdapter, prStaRec, + VHT_OP_MODE_CHANNEL_WIDTH_20, + 1); + } else { + DBGLOG(RLM, INFO, + "Skip Send Operation Action Frame"); + } +#endif + } + + break; + case ELEM_ID_SCO: + if (IE_LEN(pucIE) != + (sizeof(struct IE_SECONDARY_OFFSET) - 2)) + break; + + prSecondaryOffsetIE = + (struct IE_SECONDARY_OFFSET *)pucIE; + DBGLOG(RLM, INFO, "[Channel Switch] SCO [%d]->[%d]\n", + prBssInfo->eBssSCO, + prSecondaryOffsetIE->ucSecondaryOffset); + eChannelAnnounceSco = + (enum ENUM_CHNL_EXT) + prSecondaryOffsetIE->ucSecondaryOffset; + fgHasSCOIE = TRUE; + break; +#endif + +#if CFG_SUPPORT_QUIET && 0 + /* Note: RRM code should be moved to independent RRM function by + * component design rule. But we attach it to RLM + * temporarily + */ + case ELEM_ID_QUIET: + rrmQuietHandleQuietIE(prBssInfo, + (struct IE_QUIET *)pucIE); + fgHasQuietIE = TRUE; + break; +#endif + +#if (CFG_SUPPORT_802_11AX == 1) + case ELEM_ID_RESERVED: + if (fgEfuseCtrlAxOn == 1) { + if (IE_ID_EXT(pucIE) == ELEM_EXT_ID_HE_CAP) + heRlmRecHeCapInfo(prAdapter, prStaRec, pucIE); + else if (IE_ID_EXT(pucIE) == ELEM_EXT_ID_HE_OP) + heRlmRecHeOperation(prAdapter, + prBssInfo, pucIE); + } + break; +#endif + + default: + break; + } /* end of switch */ + } /* end of IE_FOR_EACH */ + + if (IsfgHtCapChange && (prStaRec->ucStaState == STA_STATE_3)) + cnmStaSendUpdateCmd(prAdapter, prStaRec, NULL, FALSE); + + /* Some AP will have wrong channel number (255) when running time. + * Check if correct channel number information. 20110501 + */ + if ((prBssInfo->eBand == BAND_2G4 && ucPrimaryChannel > 14) || + (prBssInfo->eBand != BAND_2G4 && + (ucPrimaryChannel >= 200 || ucPrimaryChannel <= 14))) + ucPrimaryChannel = 0; +#if CFG_SUPPORT_802_11AC + /* Check whether the Operation Mode IE is exist or not. + * If exists, then the channel bandwidth of VHT operation field is + * changed + * with the channel bandwidth setting of Operation Mode field. + * The channel bandwidth of OP Mode IE is 0, represent as 20MHz. + * The channel bandwidth of OP Mode IE is 1, represent as 40MHz. + * The channel bandwidth of OP Mode IE is 2, represent as 80MHz. + * The channel bandwidth of OP Mode IE is 3, represent as + * 160/80+80MHz. + */ + if (fgHasNewOPModeIE == TRUE) { + if (prStaRec->ucStaState == STA_STATE_3) { + /* 1. Modify channel width parameters */ + rlmRecOpModeBwForClient(ucVhtOpModeChannelWidth, + prBssInfo); + + /* 2. Update StaRec to FW (BssInfo will be updated after + * return from this function) + */ + DBGLOG(RLM, INFO, + "Update OpMode to 0x%x, to FW due to OpMode Notificaition", + prStaRec->ucVhtOpMode); + cnmStaSendUpdateCmd(prAdapter, prStaRec, NULL, FALSE); + + /* 3. Revise by own OP BW if needed */ + if ((prBssInfo->fgIsOpChangeChannelWidth)) { + /* VHT */ + if (rlmGetVhtOpBwByBssOpBw( + prBssInfo->ucOpChangeChannelWidth) < + prBssInfo->ucVhtChannelWidth) + rlmFillVhtOpInfoByBssOpBw( + prBssInfo, + prBssInfo + ->ucOpChangeChannelWidth); + /* HT */ + if (prBssInfo->fgIsOpChangeChannelWidth && + prBssInfo->ucOpChangeChannelWidth == + MAX_BW_20MHZ) { + prBssInfo->ucHtOpInfo1 &= + ~(HT_OP_INFO1_SCO | + HT_OP_INFO1_STA_CHNL_WIDTH); + prBssInfo->eBssSCO = CHNL_EXT_SCN; + } + } + } + } else { /* Set Default if the VHT OP mode field is not present */ + if (!fgHasOPModeIE) { + ucInitVhtOpMode |= + rlmGetOpModeBwByVhtAndHtOpInfo(prBssInfo); + ucInitVhtOpMode |= + ((rlmGetSupportRxNssInVhtCap(prVhtCap) - 1) + << VHT_OP_MODE_RX_NSS_OFFSET) & + VHT_OP_MODE_RX_NSS; + } + if ((prStaRec->ucVhtOpMode != ucInitVhtOpMode) && + (prStaRec->ucStaState == STA_STATE_3)) { + prStaRec->ucVhtOpMode = ucInitVhtOpMode; + DBGLOG(RLM, INFO, "Update OpMode to 0x%x", + prStaRec->ucVhtOpMode); + DBGLOG(RLM, INFO, + "to FW due to NO OpMode Notificaition\n"); + cnmStaSendUpdateCmd(prAdapter, prStaRec, NULL, FALSE); + } else + prStaRec->ucVhtOpMode = ucInitVhtOpMode; + } +#endif + +#if CFG_SUPPORT_DFS + /* Check whether Channel Announcement IE, Secondary Offset IE & + * Wide Bandwidth Channel Switch IE exist or not. If exist, the + * priority is + * the highest. + */ + + if (fgNeedSwitchChannel) { + struct BSS_DESC *prBssDesc; + struct PARAM_SSID rSsid; + + prBssInfo->ucPrimaryChannel = ucChannelAnnouncePri; + prBssInfo->eBand = + (prBssInfo->ucPrimaryChannel <= 14) + ? BAND_2G4 + : BAND_5G; + /* Change to BW20 for certification issue due to signal sidelope + * leakage + */ + prBssInfo->ucVhtChannelWidth = 0; + prBssInfo->ucVhtChannelFrequencyS1 = 0; + prBssInfo->ucVhtChannelFrequencyS2 = 0; + prBssInfo->eBssSCO = 0; + + if (fgHasWideBandIE != FALSE) { + prBssInfo->ucVhtChannelWidth = ucChannelAnnounceVhtBw; + prBssInfo->ucVhtChannelFrequencyS1 = + ucChannelAnnounceChannelS1; + prBssInfo->ucVhtChannelFrequencyS2 = + ucChannelAnnounceChannelS2; + + /* Revise by own OP BW if needed */ + if ((prBssInfo->fgIsOpChangeChannelWidth) && + (rlmGetVhtOpBwByBssOpBw( + prBssInfo->ucOpChangeChannelWidth) < + prBssInfo->ucVhtChannelWidth)) { + + DBGLOG(RLM, LOUD, + "Change to w:%d s1:%d s2:%d since own changed BW < peer's WideBand BW", + prBssInfo->ucVhtChannelWidth, + prBssInfo->ucVhtChannelFrequencyS1, + prBssInfo->ucVhtChannelFrequencyS2); + rlmFillVhtOpInfoByBssOpBw( + prBssInfo, + prBssInfo->ucOpChangeChannelWidth); + } + } + if (fgHasSCOIE != FALSE) + prBssInfo->eBssSCO = eChannelAnnounceSco; + + COPY_SSID(rSsid.aucSsid, rSsid.u4SsidLen, prBssInfo->aucSSID, + prBssInfo->ucSSIDLen); + prBssDesc = scanSearchBssDescByBssidAndSsid( + prAdapter, prBssInfo->aucBSSID, TRUE, &rSsid); + + if (prBssDesc) { + DBGLOG(RLM, INFO, + "DFS: BSS: " MACSTR + " Desc found, channel from %u to %u\n ", + MAC2STR(prBssInfo->aucBSSID), + prBssDesc->ucChannelNum, ucChannelAnnouncePri); + prBssDesc->ucChannelNum = ucChannelAnnouncePri; + prBssDesc->eChannelWidth = prBssInfo->ucVhtChannelWidth; + prBssDesc->ucCenterFreqS1 = + prBssInfo->ucVhtChannelFrequencyS1; + prBssDesc->ucCenterFreqS2 = + prBssInfo->ucVhtChannelFrequencyS2; + kalIndicateChannelSwitch( + prAdapter->prGlueInfo, + prBssInfo->eBssSCO, + prBssDesc->ucChannelNum); + } else { + DBGLOG(RLM, INFO, + "DFS: BSS: " MACSTR " Desc is not found\n ", + MAC2STR(prBssInfo->aucBSSID)); + } + } +#endif + + if (!fgHasChannelSwitchIE && g_fgHasStopTx) { + /* AP */ + qmSetStaRecTxAllowed(prAdapter, prStaRec, TRUE); + + DBGLOG(RLM, EVENT, "[Ch] TxAllowed = TRUE\n"); + g_fgHasStopTx = FALSE; + } + +#if CFG_SUPPORT_DFS +#ifdef CFG_DFS_CHSW_FORCE_BW20 + /*DFS Certification for Channel Bandwidth 20MHz */ + DBGLOG(RLM, INFO, "Ch : SwitchIE = %d\n", g_fgHasChannelSwitchIE); + if (g_fgHasChannelSwitchIE == TRUE) { + prBssInfo->eBssSCO = CHNL_EXT_SCN; + prBssInfo->ucVhtChannelWidth = CW_20_40MHZ; + prBssInfo->ucVhtChannelFrequencyS1 = 0; + prBssInfo->ucVhtChannelFrequencyS2 = 255; + prBssInfo->ucHtOpInfo1 &= + ~(HT_OP_INFO1_SCO | HT_OP_INFO1_STA_CHNL_WIDTH); + DBGLOG(RLM, INFO, "Ch : DFS has Appeared\n"); + } +#endif +#endif + rlmReviseMaxBw(prAdapter, prBssInfo->ucBssIndex, &prBssInfo->eBssSCO, + (enum ENUM_CHANNEL_WIDTH *)&prBssInfo->ucVhtChannelWidth, + &prBssInfo->ucVhtChannelFrequencyS1, + &prBssInfo->ucPrimaryChannel); + + rlmRevisePreferBandwidthNss(prAdapter, prBssInfo->ucBssIndex, prStaRec); + + /* printk("Modify ChannelWidth (%d) and Extend + * (%d)\n",prBssInfo->eBssSCO, + * prBssInfo->ucVhtChannelWidth); + */ + + if (!rlmDomainIsValidRfSetting( + prAdapter, prBssInfo->eBand, prBssInfo->ucPrimaryChannel, + prBssInfo->eBssSCO, prBssInfo->ucVhtChannelWidth, + prBssInfo->ucVhtChannelFrequencyS1, + prBssInfo->ucVhtChannelFrequencyS2)) { + + /*Dump IE Inforamtion */ + DBGLOG(RLM, WARN, "rlmRecIeInfoForClient IE Information\n"); + DBGLOG(RLM, WARN, "IE Length = %d\n", u2IELength); + DBGLOG_MEM8(RLM, WARN, pucDumpIE, u2IELength); + + /*Error Handling for Non-predicted IE - Fixed to set 20MHz */ + prBssInfo->ucVhtChannelWidth = CW_20_40MHZ; + prBssInfo->ucVhtChannelFrequencyS1 = 0; + prBssInfo->ucVhtChannelFrequencyS2 = 0; + prBssInfo->eBssSCO = CHNL_EXT_SCN; + prBssInfo->ucHtOpInfo1 &= + ~(HT_OP_INFO1_SCO | HT_OP_INFO1_STA_CHNL_WIDTH); + + /* Check SAP channel */ + p2pFuncSwitchSapChannel(prAdapter); + + } +#if CFG_SUPPORT_QUIET && 0 + if (!fgHasQuietIE) + rrmQuietIeNotExist(prAdapter, prBssInfo); +#endif + + /* Check if OBSS scan process will launch */ + if (!prAdapter->fgEnOnlineScan || !prObssScnParam || + !(prStaRec->u2HtCapInfo & HT_CAP_INFO_SUP_CHNL_WIDTH) || + prBssInfo->eBand != BAND_2G4 || !prBssInfo->fg40mBwAllowed) { + + /* Note: it is ok not to stop rObssScanTimer() here */ + prBssInfo->u2ObssScanInterval = 0; + } else { + if (prObssScnParam->u2TriggerScanInterval < + OBSS_SCAN_MIN_INTERVAL) + prObssScnParam->u2TriggerScanInterval = + OBSS_SCAN_MIN_INTERVAL; + if (prBssInfo->u2ObssScanInterval != + prObssScnParam->u2TriggerScanInterval) { + + prBssInfo->u2ObssScanInterval = + prObssScnParam->u2TriggerScanInterval; + + /* Start timer to trigger OBSS scanning */ + cnmTimerStartTimer( + prAdapter, &prBssInfo->rObssScanTimer, + prBssInfo->u2ObssScanInterval * MSEC_PER_SEC); + } + } + + return ucPrimaryChannel; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Update parameters from channel width field in OP Mode IE/action frame + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +static void rlmRecOpModeBwForClient(uint8_t ucVhtOpModeChannelWidth, + struct BSS_INFO *prBssInfo) +{ + + struct STA_RECORD *prStaRec = NULL; + + if (!prBssInfo) + return; + + prStaRec = prBssInfo->prStaRecOfAP; + if (!prStaRec) + return; + + switch (ucVhtOpModeChannelWidth) { + case VHT_OP_MODE_CHANNEL_WIDTH_20: + prBssInfo->ucVhtChannelWidth = VHT_OP_CHANNEL_WIDTH_20_40; + prBssInfo->ucHtOpInfo1 &= ~HT_OP_INFO1_STA_CHNL_WIDTH; + prStaRec->u2HtCapInfo &= ~HT_CAP_INFO_SUP_CHNL_WIDTH; + +#if CFG_OPMODE_CONFLICT_OPINFO + if (prBssInfo->eBssSCO != CHNL_EXT_SCN) { + DBGLOG(RLM, WARN, + "HT_OP_Info != OPmode_Notifify, follow OPmode_Notify to BW20.\n"); + prBssInfo->eBssSCO = CHNL_EXT_SCN; + } +#endif + break; + case VHT_OP_MODE_CHANNEL_WIDTH_40: + prBssInfo->ucVhtChannelWidth = VHT_OP_CHANNEL_WIDTH_20_40; + prBssInfo->ucHtOpInfo1 |= HT_OP_INFO1_STA_CHNL_WIDTH; + prStaRec->u2HtCapInfo |= HT_CAP_INFO_SUP_CHNL_WIDTH; + +#if CFG_OPMODE_CONFLICT_OPINFO + if (prBssInfo->eBssSCO == CHNL_EXT_SCN) { + prBssInfo->ucHtOpInfo1 &= ~HT_OP_INFO1_STA_CHNL_WIDTH; + prStaRec->u2HtCapInfo &= ~HT_CAP_INFO_SUP_CHNL_WIDTH; + DBGLOG(RLM, WARN, + "HT_OP_Info != OPmode_Notifify, follow HT_OP_Info to BW20.\n"); + } +#endif + break; + case VHT_OP_MODE_CHANNEL_WIDTH_80: +#if CFG_OPMODE_CONFLICT_OPINFO + if (prBssInfo->ucVhtChannelWidth != + VHT_OP_MODE_CHANNEL_WIDTH_80) { + DBGLOG(RLM, WARN, + "VHT_OP != OPmode:%d, follow VHT_OP to VHT_OP:%d HT_OP:%d\n", + ucVhtOpModeChannelWidth, + prBssInfo->ucVhtChannelWidth, + (uint8_t)(prBssInfo->ucHtOpInfo1 & + HT_OP_INFO1_STA_CHNL_WIDTH) >> + HT_OP_INFO1_STA_CHNL_WIDTH_OFFSET); + } else +#endif + { + prBssInfo->ucVhtChannelWidth = VHT_OP_CHANNEL_WIDTH_80; + prBssInfo->ucHtOpInfo1 |= HT_OP_INFO1_STA_CHNL_WIDTH; + prStaRec->u2HtCapInfo |= HT_CAP_INFO_SUP_CHNL_WIDTH; + } + break; + case VHT_OP_MODE_CHANNEL_WIDTH_160_80P80: +/* Determine BW160 or BW80+BW80 by VHT OP Info */ +#if CFG_OPMODE_CONFLICT_OPINFO + if ((prBssInfo->ucVhtChannelWidth != + VHT_OP_CHANNEL_WIDTH_160) && + (prBssInfo->ucVhtChannelWidth != + VHT_OP_CHANNEL_WIDTH_80P80)) { + DBGLOG(RLM, WARN, + "VHT_OP != OPmode:%d, follow VHT_OP to VHT_OP:%d HT_OP:%d\n", + ucVhtOpModeChannelWidth, + prBssInfo->ucVhtChannelWidth, + (uint8_t)(prBssInfo->ucHtOpInfo1 & + HT_OP_INFO1_STA_CHNL_WIDTH) >> + HT_OP_INFO1_STA_CHNL_WIDTH_OFFSET); + } else +#endif + { + prBssInfo->ucHtOpInfo1 |= HT_OP_INFO1_STA_CHNL_WIDTH; + prStaRec->u2HtCapInfo |= HT_CAP_INFO_SUP_CHNL_WIDTH; + } + break; + default: + break; + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Update parameters from Association Response frame + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +static void rlmRecAssocRespIeInfoForClient(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, + uint8_t *pucIE, uint16_t u2IELength) +{ + uint16_t u2Offset; + struct STA_RECORD *prStaRec; + u_int8_t fgIsHasHtCap = FALSE; + u_int8_t fgIsHasVhtCap = FALSE; +#if (CFG_SUPPORT_802_11AX == 1) + u_int8_t fgIsHasHeCap = FALSE; +#endif + struct BSS_DESC *prBssDesc; + struct PARAM_SSID rSsid; + + ASSERT(prAdapter); + ASSERT(prBssInfo); + ASSERT(pucIE); + + prStaRec = prBssInfo->prStaRecOfAP; + + if (!prStaRec) + return; + COPY_SSID(rSsid.aucSsid, rSsid.u4SsidLen, prBssInfo->aucSSID, + prBssInfo->ucSSIDLen); + prBssDesc = scanSearchBssDescByBssidAndSsid( + prAdapter, prStaRec->aucMacAddr, TRUE, &rSsid); + + IE_FOR_EACH(pucIE, u2IELength, u2Offset) + { + switch (IE_ID(pucIE)) { + case ELEM_ID_HT_CAP: + if (!RLM_NET_IS_11N(prBssInfo) || + IE_LEN(pucIE) != (sizeof(struct IE_HT_CAP) - 2)) + break; + fgIsHasHtCap = TRUE; + break; +#if CFG_SUPPORT_802_11AC + case ELEM_ID_VHT_CAP: + if (!RLM_NET_IS_11AC(prBssInfo) || + IE_LEN(pucIE) != (sizeof(struct IE_VHT_CAP) - 2)) + break; + fgIsHasVhtCap = TRUE; + break; +#endif +#if (CFG_SUPPORT_802_11AX == 1) + case ELEM_ID_RESERVED: + if (fgEfuseCtrlAxOn == 1) { + if (IE_ID_EXT(pucIE) != ELEM_EXT_ID_HE_CAP || + !RLM_NET_IS_11AX(prBssInfo)) + break; + fgIsHasHeCap = TRUE; + } + break; +#endif + + default: + break; + } /* end of switch */ + } /* end of IE_FOR_EACH */ + + if (!fgIsHasHtCap) { + prStaRec->ucDesiredPhyTypeSet &= ~PHY_TYPE_BIT_HT; + if (prBssDesc) { + if (prBssDesc->ucPhyTypeSet & PHY_TYPE_BIT_HT) { + DBGLOG(RLM, WARN, + "PhyTypeSet in Beacon and AssocResp are unsync. "); + DBGLOG(RLM, WARN, + "Follow AssocResp to disable HT.\n"); + } + } + } + if (!fgIsHasVhtCap) { + prStaRec->ucDesiredPhyTypeSet &= ~PHY_TYPE_BIT_VHT; + if (prBssDesc) { + if (prBssDesc->ucPhyTypeSet & PHY_TYPE_BIT_VHT) { + DBGLOG(RLM, WARN, + "PhyTypeSet in Beacon and AssocResp are unsync. "); + DBGLOG(RLM, WARN, + "Follow AssocResp to disable VHT.\n"); + } + } + } +#if (CFG_SUPPORT_802_11AX == 1) + if (fgEfuseCtrlAxOn == 1) { + if (!fgIsHasHeCap) { + prStaRec->ucDesiredPhyTypeSet &= ~PHY_TYPE_BIT_HE; + if (prBssDesc) { + if (prBssDesc->ucPhyTypeSet & PHY_TYPE_BIT_HE) { + DBGLOG(RLM, WARN, "PhyTypeSet are unsync. "); + DBGLOG(RLM, WARN, "Disable HE per assoc.\n"); + } + } + } + } +#endif +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief AIS or P2P GC. + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +static u_int8_t rlmRecBcnFromNeighborForClient(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, + struct SW_RFB *prSwRfb, + uint8_t *pucIE, + uint16_t u2IELength) +{ + uint16_t u2Offset, i; + uint8_t ucPriChannel, ucSecChannel; + enum ENUM_CHNL_EXT eSCO; + u_int8_t fgHtBss, fg20mReq; + enum ENUM_BAND eBand = 0; + struct RX_DESC_OPS_T *prRxDescOps; + + ASSERT(prAdapter); + ASSERT(prBssInfo && prSwRfb); + ASSERT(pucIE); + prRxDescOps = prAdapter->chip_info->prRxDescOps; + + /* Record it to channel list to change 20/40 bandwidth */ + ucPriChannel = 0; + eSCO = CHNL_EXT_SCN; + + fgHtBss = FALSE; + fg20mReq = FALSE; + + IE_FOR_EACH(pucIE, u2IELength, u2Offset) + { + switch (IE_ID(pucIE)) { + case ELEM_ID_HT_CAP: { + struct IE_HT_CAP *prHtCap; + + if (IE_LEN(pucIE) != (sizeof(struct IE_HT_CAP) - 2)) + break; + + prHtCap = (struct IE_HT_CAP *)pucIE; + if (prHtCap->u2HtCapInfo & HT_CAP_INFO_40M_INTOLERANT) + fg20mReq = TRUE; + fgHtBss = TRUE; + break; + } + case ELEM_ID_HT_OP: { + struct IE_HT_OP *prHtOp; + + if (IE_LEN(pucIE) != (sizeof(struct IE_HT_OP) - 2)) + break; + + prHtOp = (struct IE_HT_OP *)pucIE; + /* Workaround that some APs fill primary channel field + * by its + * secondary channel, but its DS IE is correct 20110610 + */ + if (ucPriChannel == 0) + ucPriChannel = prHtOp->ucPrimaryChannel; + + if ((prHtOp->ucInfo1 & HT_OP_INFO1_SCO) != CHNL_EXT_RES) + eSCO = (enum ENUM_CHNL_EXT)(prHtOp->ucInfo1 & + HT_OP_INFO1_SCO); + break; + } + case ELEM_ID_20_40_BSS_COEXISTENCE: { + struct IE_20_40_COEXIST *prCoexist; + + if (IE_LEN(pucIE) != + (sizeof(struct IE_20_40_COEXIST) - 2)) + break; + + prCoexist = (struct IE_20_40_COEXIST *)pucIE; + if (prCoexist->ucData & BSS_COEXIST_40M_INTOLERANT) + fg20mReq = TRUE; + break; + } + case ELEM_ID_DS_PARAM_SET: + if (IE_LEN(pucIE) != + (sizeof(struct IE_DS_PARAM_SET) - 2)) + break; + ucPriChannel = DS_PARAM_IE(pucIE)->ucCurrChnl; + break; + + default: + break; + } + } + + /* To do: Update channel list and 5G band. All channel lists have the + * same + * update procedure. We should give it the entry pointer of desired + * channel list. + */ + RX_STATUS_GET(prRxDescOps, eBand, get_rf_band, prSwRfb->prRxStatus); + if (eBand != BAND_2G4) + return FALSE; + + if (ucPriChannel == 0 || ucPriChannel > 14) { + RX_STATUS_GET( + prRxDescOps, + ucPriChannel, + get_ch_num, + prSwRfb->prRxStatus); + } + + if (fgHtBss) { + ASSERT(prBssInfo->auc2G_PriChnlList[0] <= CHNL_LIST_SZ_2G); + for (i = 1; i <= prBssInfo->auc2G_PriChnlList[0] && + i <= CHNL_LIST_SZ_2G; + i++) { + if (prBssInfo->auc2G_PriChnlList[i] == ucPriChannel) + break; + } + if ((i > prBssInfo->auc2G_PriChnlList[0]) && + (i <= CHNL_LIST_SZ_2G)) { + prBssInfo->auc2G_PriChnlList[i] = ucPriChannel; + prBssInfo->auc2G_PriChnlList[0]++; + } + + /* Update secondary channel */ + if (eSCO != CHNL_EXT_SCN) { + ucSecChannel = (eSCO == CHNL_EXT_SCA) + ? (ucPriChannel + 4) + : (ucPriChannel - 4); + + ASSERT(prBssInfo->auc2G_SecChnlList[0] <= + CHNL_LIST_SZ_2G); + for (i = 1; i <= prBssInfo->auc2G_SecChnlList[0] && + i <= CHNL_LIST_SZ_2G; + i++) { + if (prBssInfo->auc2G_SecChnlList[i] == + ucSecChannel) + break; + } + if ((i > prBssInfo->auc2G_SecChnlList[0]) && + (i <= CHNL_LIST_SZ_2G)) { + prBssInfo->auc2G_SecChnlList[i] = ucSecChannel; + prBssInfo->auc2G_SecChnlList[0]++; + } + } + + /* Update 20M bandwidth request channels */ + if (fg20mReq) { + ASSERT(prBssInfo->auc2G_20mReqChnlList[0] <= + CHNL_LIST_SZ_2G); + for (i = 1; i <= prBssInfo->auc2G_20mReqChnlList[0] && + i <= CHNL_LIST_SZ_2G; + i++) { + if (prBssInfo->auc2G_20mReqChnlList[i] == + ucPriChannel) + break; + } + if ((i > prBssInfo->auc2G_20mReqChnlList[0]) && + (i <= CHNL_LIST_SZ_2G)) { + prBssInfo->auc2G_20mReqChnlList[i] = + ucPriChannel; + prBssInfo->auc2G_20mReqChnlList[0]++; + } + } + } else { + /* Update non-HT channel list */ + ASSERT(prBssInfo->auc2G_NonHtChnlList[0] <= CHNL_LIST_SZ_2G); + for (i = 1; i <= prBssInfo->auc2G_NonHtChnlList[0] && + i <= CHNL_LIST_SZ_2G; + i++) { + if (prBssInfo->auc2G_NonHtChnlList[i] == ucPriChannel) + break; + } + if ((i > prBssInfo->auc2G_NonHtChnlList[0]) && + (i <= CHNL_LIST_SZ_2G)) { + prBssInfo->auc2G_NonHtChnlList[i] = ucPriChannel; + prBssInfo->auc2G_NonHtChnlList[0]++; + } + } + + return FALSE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief AIS or P2P GC. + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +static u_int8_t rlmRecBcnInfoForClient(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, + struct SW_RFB *prSwRfb, uint8_t *pucIE, + uint16_t u2IELength) +{ + /* For checking if syncing params are different from + * last syncing and need to sync again + */ + struct CMD_SET_BSS_RLM_PARAM rBssRlmParam; + u_int8_t fgNewParameter = FALSE; + + ASSERT(prAdapter); + ASSERT(prBssInfo && prSwRfb); + ASSERT(pucIE); + +#if 0 /* SW migration 2010/8/20 */ + /* Note: we shall not update parameters when scanning, otherwise + * channel and bandwidth will not be correct or asserted failure + * during scanning. + * Note: remove channel checking. All received Beacons should be + * processed if measurement or other actions are executed in adjacent + * channels and Beacon content checking mechanism is not disabled. + */ + if (IS_SCAN_ACTIVE() + /* || prBssInfo->ucPrimaryChannel != CHNL_NUM_BY_SWRFB(prSwRfb) */ + ) { + return FALSE; + } +#endif + + /* Handle change of slot time */ + prBssInfo->u2CapInfo = + ((struct WLAN_BEACON_FRAME *)(prSwRfb->pvHeader))->u2CapInfo; + prBssInfo->fgUseShortSlotTime = + ((prBssInfo->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME) || + (prBssInfo->eBand != BAND_2G4)) + ? TRUE + : FALSE; + + /* Check if syncing params are different from last syncing and need to + * sync again + * If yes, return TRUE and sync with FW; Otherwise, return FALSE. + */ + rBssRlmParam.ucRfBand = (u_int8_t)prBssInfo->eBand; + rBssRlmParam.ucPrimaryChannel = prBssInfo->ucPrimaryChannel; + rBssRlmParam.ucRfSco = (u_int8_t)prBssInfo->eBssSCO; + rBssRlmParam.ucErpProtectMode = (u_int8_t)prBssInfo->fgErpProtectMode; + rBssRlmParam.ucHtProtectMode = (u_int8_t)prBssInfo->eHtProtectMode; + rBssRlmParam.ucGfOperationMode = (u_int8_t)prBssInfo->eGfOperationMode; + rBssRlmParam.ucTxRifsMode = (u_int8_t)prBssInfo->eRifsOperationMode; + rBssRlmParam.u2HtOpInfo3 = prBssInfo->u2HtOpInfo3; + rBssRlmParam.u2HtOpInfo2 = prBssInfo->u2HtOpInfo2; + rBssRlmParam.ucHtOpInfo1 = prBssInfo->ucHtOpInfo1; + rBssRlmParam.ucUseShortPreamble = prBssInfo->fgUseShortPreamble; + rBssRlmParam.ucUseShortSlotTime = prBssInfo->fgUseShortSlotTime; + rBssRlmParam.ucVhtChannelWidth = prBssInfo->ucVhtChannelWidth; + rBssRlmParam.ucVhtChannelFrequencyS1 = + prBssInfo->ucVhtChannelFrequencyS1; + rBssRlmParam.ucVhtChannelFrequencyS2 = + prBssInfo->ucVhtChannelFrequencyS2; + rBssRlmParam.u2VhtBasicMcsSet = prBssInfo->u2VhtBasicMcsSet; + rBssRlmParam.ucRxNss = prBssInfo->ucOpRxNss; + rBssRlmParam.ucTxNss = prBssInfo->ucOpTxNss; + + rlmRecIeInfoForClient(prAdapter, prBssInfo, pucIE, u2IELength); + + if (rBssRlmParam.ucRfBand != prBssInfo->eBand || + rBssRlmParam.ucPrimaryChannel != prBssInfo->ucPrimaryChannel || + rBssRlmParam.ucRfSco != prBssInfo->eBssSCO || + rBssRlmParam.ucErpProtectMode != prBssInfo->fgErpProtectMode || + rBssRlmParam.ucHtProtectMode != prBssInfo->eHtProtectMode || + rBssRlmParam.ucGfOperationMode != prBssInfo->eGfOperationMode || + rBssRlmParam.ucTxRifsMode != prBssInfo->eRifsOperationMode || + rBssRlmParam.u2HtOpInfo3 != prBssInfo->u2HtOpInfo3 || + rBssRlmParam.u2HtOpInfo2 != prBssInfo->u2HtOpInfo2 || + rBssRlmParam.ucHtOpInfo1 != prBssInfo->ucHtOpInfo1 || + rBssRlmParam.ucUseShortPreamble != + prBssInfo->fgUseShortPreamble || + rBssRlmParam.ucUseShortSlotTime != + prBssInfo->fgUseShortSlotTime || + rBssRlmParam.ucVhtChannelWidth != + prBssInfo->ucVhtChannelWidth || + rBssRlmParam.ucVhtChannelFrequencyS1 != + prBssInfo->ucVhtChannelFrequencyS1 || + rBssRlmParam.ucVhtChannelFrequencyS2 != + prBssInfo->ucVhtChannelFrequencyS2 || + rBssRlmParam.u2VhtBasicMcsSet != prBssInfo->u2VhtBasicMcsSet || + rBssRlmParam.ucRxNss != prBssInfo->ucOpRxNss || + rBssRlmParam.ucTxNss != prBssInfo->ucOpTxNss) + fgNewParameter = TRUE; + else { + DBGLOG(RLM, TRACE, + "prBssInfo's params are all the same! not to sync!\n"); + fgNewParameter = FALSE; + } + + return fgNewParameter; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rlmProcessBcn(struct ADAPTER *prAdapter, struct SW_RFB *prSwRfb, + uint8_t *pucIE, uint16_t u2IELength) +{ + struct BSS_INFO *prBssInfo; + u_int8_t fgNewParameter; +#if (CFG_SUPPORT_802_11AX == 1) + u_int8_t fgNewSRParam = FALSE; +#endif + uint8_t i; + + ASSERT(prAdapter); + ASSERT(prSwRfb); + ASSERT(pucIE); + + fgNewParameter = FALSE; + + /* When concurrent networks exist, GO shall have the same handle as + * the other BSS, so the Beacon shall be processed for bandwidth and + * protection mechanism. + * Note1: we do not have 2 AP (GO) cases simultaneously now. + * Note2: If we are GO, concurrent AIS AP should detect it and reflect + * action in its Beacon, so AIS STA just follows Beacon from AP. + */ + for (i = 0; i < prAdapter->ucHwBssIdNum; i++) { + prBssInfo = prAdapter->aprBssInfo[i]; + + if (IS_BSS_BOW(prBssInfo)) + continue; + + if (IS_BSS_ACTIVE(prBssInfo)) { + if (prBssInfo->eCurrentOPMode == + OP_MODE_INFRASTRUCTURE && + prBssInfo->eConnectionState == + MEDIA_STATE_CONNECTED) { + /* P2P client or AIS infra STA */ + if (EQUAL_MAC_ADDR( + prBssInfo->aucBSSID, + ((struct WLAN_MAC_MGMT_HEADER + *)(prSwRfb->pvHeader)) + ->aucBSSID)) { + + fgNewParameter = rlmRecBcnInfoForClient( + prAdapter, prBssInfo, prSwRfb, + pucIE, u2IELength); +#if (CFG_SUPPORT_802_11AX == 1) + if (fgEfuseCtrlAxOn == 1) { + fgNewSRParam = heRlmRecHeSRParams( + prAdapter, prBssInfo, + prSwRfb, pucIE, u2IELength); + } +#endif + } else { + fgNewParameter = + rlmRecBcnFromNeighborForClient( + prAdapter, prBssInfo, + prSwRfb, pucIE, + u2IELength); + } + } +#if CFG_ENABLE_WIFI_DIRECT + else if (prAdapter->fgIsP2PRegistered && + (prBssInfo->eCurrentOPMode == + OP_MODE_ACCESS_POINT || + prBssInfo->eCurrentOPMode == + OP_MODE_P2P_DEVICE)) { + /* AP scan to check if 20/40M bandwidth is + * permitted + */ + rlmRecBcnFromNeighborForClient( + prAdapter, prBssInfo, prSwRfb, pucIE, + u2IELength); + } +#endif + else if (prBssInfo->eCurrentOPMode == OP_MODE_IBSS) { + /* To do: Nothing */ + /* To do: Ad-hoc */ + } + + /* Appy new parameters if necessary */ + if (fgNewParameter) { + rlmSyncOperationParams(prAdapter, prBssInfo); + fgNewParameter = FALSE; + } +#if (CFG_SUPPORT_802_11AX == 1) + if (fgEfuseCtrlAxOn == 1) { + if (fgNewSRParam) { + nicRlmUpdateSRParams(prAdapter, + prBssInfo->ucBssIndex); + fgNewSRParam = FALSE; + } + } +#endif + + } /* end of IS_BSS_ACTIVE() */ + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function should be invoked after judging successful association. + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rlmProcessAssocRsp(struct ADAPTER *prAdapter, struct SW_RFB *prSwRfb, + uint8_t *pucIE, uint16_t u2IELength) +{ + struct BSS_INFO *prBssInfo; + struct STA_RECORD *prStaRec; + uint8_t ucPriChannel; +#if (CFG_SUPPORT_802_11AX == 1) + uint8_t fgNewSRParam; +#endif + + ASSERT(prAdapter); + ASSERT(prSwRfb); + ASSERT(pucIE); + + prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); + if (!prStaRec) + return; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex); + if (!prBssInfo) + return; + + if (prStaRec != prBssInfo->prStaRecOfAP) + return; + + /* To do: the invoked function is used to clear all members. It may be + * done by center mechanism in invoker. + */ + rlmBssReset(prAdapter, prBssInfo); + + prBssInfo->fgUseShortSlotTime = + ((prBssInfo->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME) || + (prBssInfo->eBand != BAND_2G4)) + ? TRUE + : FALSE; + ucPriChannel = + rlmRecIeInfoForClient(prAdapter, prBssInfo, pucIE, u2IELength); + + /*Update the parameters from Association Response only, + *if the parameters need to be updated by both Beacon and Association + *Response, + *user should use another function, rlmRecIeInfoForClient() + */ + rlmRecAssocRespIeInfoForClient(prAdapter, prBssInfo, pucIE, u2IELength); + + if (prBssInfo->ucPrimaryChannel != ucPriChannel) { + DBGLOG(RLM, INFO, + "Use RF pri channel[%u].Pri channel in HT OP IE is :[%u]\n", + prBssInfo->ucPrimaryChannel, ucPriChannel); + } + /* Avoid wrong primary channel info in HT operation + * IE info when accept association response + */ +#if 0 + if (ucPriChannel > 0) + prBssInfo->ucPrimaryChannel = ucPriChannel; +#endif + + if (!RLM_NET_IS_11N(prBssInfo) || + !(prStaRec->u2HtCapInfo & HT_CAP_INFO_SUP_CHNL_WIDTH)) + prBssInfo->fg40mBwAllowed = FALSE; + +#if (CFG_SUPPORT_802_11AX == 1) + if (fgEfuseCtrlAxOn == 1) { + fgNewSRParam = heRlmRecHeSRParams(prAdapter, prBssInfo, + prSwRfb, pucIE, u2IELength); + /* ASSERT(fgNewSRParam); */ + nicRlmUpdateSRParams(prAdapter, prBssInfo->ucBssIndex); + } +#endif + + /* Note: Update its capabilities to WTBL by cnmStaRecChangeState(), + * which + * shall be invoked afterwards. + * Update channel, bandwidth and protection mode by nicUpdateBss() + */ +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rlmProcessHtAction(struct ADAPTER *prAdapter, struct SW_RFB *prSwRfb) +{ + struct ACTION_NOTIFY_CHNL_WIDTH_FRAME *prRxFrame; + struct ACTION_SM_POWER_SAVE_FRAME *prRxSmpsFrame; + struct STA_RECORD *prStaRec; + struct BSS_INFO *prBssInfo; + uint16_t u2HtCapInfoBitmask = 0; + + ASSERT(prAdapter); + ASSERT(prSwRfb); + + prRxFrame = (struct ACTION_NOTIFY_CHNL_WIDTH_FRAME *)prSwRfb->pvHeader; + prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); + + if (!prStaRec) + return; + + switch (prRxFrame->ucAction) { + case ACTION_HT_NOTIFY_CHANNEL_WIDTH: + if (prStaRec->ucStaState != STA_STATE_3 || + prSwRfb->u2PacketLen < + sizeof(struct ACTION_NOTIFY_CHNL_WIDTH_FRAME)) { + return; + } + + /* To do: depending regulation class 13 and 14 based on spec + * Note: (ucChannelWidth==1) shall restored back to original + * capability, not current setting to 40MHz BW here + */ + /* 1. Update StaRec for AP/STA mode */ + if (prRxFrame->ucChannelWidth == HT_NOTIFY_CHANNEL_WIDTH_20) + prStaRec->u2HtCapInfo &= ~HT_CAP_INFO_SUP_CHNL_WIDTH; + else if (prRxFrame->ucChannelWidth == + HT_NOTIFY_CHANNEL_WIDTH_ANY_SUPPORT_CAHNNAEL_WIDTH) + prStaRec->u2HtCapInfo |= HT_CAP_INFO_SUP_CHNL_WIDTH; + + cnmStaSendUpdateCmd(prAdapter, prStaRec, NULL, FALSE); + + /* 2. Update BssInfo for STA mode */ + prBssInfo = prAdapter->aprBssInfo[prStaRec->ucBssIndex]; + if (prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) { + if (prRxFrame->ucChannelWidth == + HT_NOTIFY_CHANNEL_WIDTH_20) { + prBssInfo->ucHtOpInfo1 &= + ~HT_OP_INFO1_STA_CHNL_WIDTH; + prBssInfo->eBssSCO = CHNL_EXT_SCN; + } else if ( + prRxFrame->ucChannelWidth == + HT_NOTIFY_CHANNEL_WIDTH_ANY_SUPPORT_CAHNNAEL_WIDTH) + prBssInfo->ucHtOpInfo1 |= + HT_OP_INFO1_STA_CHNL_WIDTH; + + /* Revise by own OP BW if needed */ + if (prBssInfo->fgIsOpChangeChannelWidth && + prBssInfo->ucOpChangeChannelWidth == MAX_BW_20MHZ) { + prBssInfo->ucHtOpInfo1 &= + ~(HT_OP_INFO1_SCO | + HT_OP_INFO1_STA_CHNL_WIDTH); + prBssInfo->eBssSCO = CHNL_EXT_SCN; + } + + /* 3. Update OP BW to FW */ + rlmSyncOperationParams(prAdapter, prBssInfo); + } + break; + /* Support SM power save */ /* TH3_Huang */ + case ACTION_HT_SM_POWER_SAVE: + prRxSmpsFrame = + (struct ACTION_SM_POWER_SAVE_FRAME *)prSwRfb->pvHeader; + if (prStaRec->ucStaState != STA_STATE_3 || + prSwRfb->u2PacketLen < + sizeof(struct ACTION_SM_POWER_SAVE_FRAME)) { + return; + } + + /* The SM power enable bit is different definition in HtCap and + * SMpower IE field + */ + if (!(prRxSmpsFrame->ucSmPowerCtrl & + (HT_SM_POWER_SAVE_CONTROL_ENABLED | + HT_SM_POWER_SAVE_CONTROL_SM_MODE))) + u2HtCapInfoBitmask |= HT_CAP_INFO_SM_POWER_SAVE; + + /* Support SMPS action frame, TH3_Huang */ + /* Update StaRec if SM power state changed */ + if ((prStaRec->u2HtCapInfo & HT_CAP_INFO_SM_POWER_SAVE) != + u2HtCapInfoBitmask) { + prStaRec->u2HtCapInfo &= ~HT_CAP_INFO_SM_POWER_SAVE; + prStaRec->u2HtCapInfo |= u2HtCapInfoBitmask; + DBGLOG(RLM, INFO, + "rlmProcessHtAction -- SMPS change u2HtCapInfo to (%x)\n", + prStaRec->u2HtCapInfo); + cnmStaSendUpdateCmd(prAdapter, prStaRec, NULL, FALSE); + } + break; + default: + break; + } +} + +#if CFG_SUPPORT_802_11AC +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rlmProcessVhtAction(struct ADAPTER *prAdapter, struct SW_RFB *prSwRfb) +{ + struct ACTION_OP_MODE_NOTIFICATION_FRAME *prRxFrame; + struct STA_RECORD *prStaRec; + struct BSS_INFO *prBssInfo; + uint8_t ucVhtOpModeChannelWidth = 0; + + ASSERT(prAdapter); + ASSERT(prSwRfb); + + prRxFrame = + (struct ACTION_OP_MODE_NOTIFICATION_FRAME *)prSwRfb->pvHeader; + prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); + + if (!prStaRec) + return; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex); + + if (!prBssInfo) + return; + + switch (prRxFrame->ucAction) { + /* Support Operating mode notification action frame, TH3_Huang */ + case ACTION_OPERATING_MODE_NOTIFICATION: + if (prStaRec->ucStaState != STA_STATE_3 || + prSwRfb->u2PacketLen < + sizeof(struct ACTION_OP_MODE_NOTIFICATION_FRAME)) { + return; + } + + if (((prRxFrame->ucOperatingMode & VHT_OP_MODE_RX_NSS_TYPE) != + VHT_OP_MODE_RX_NSS_TYPE) && + (prStaRec->ucVhtOpMode != prRxFrame->ucOperatingMode)) { + /* 1. Fill OP mode notification info */ + prStaRec->ucVhtOpMode = prRxFrame->ucOperatingMode; + DBGLOG(RLM, INFO, + "rlmProcessVhtAction -- Update ucVhtOpMode to 0x%x\n", + prStaRec->ucVhtOpMode); + + /* 2. Modify channel width parameters */ + ucVhtOpModeChannelWidth = prRxFrame->ucOperatingMode & + VHT_OP_MODE_CHANNEL_WIDTH; + if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) { + if (ucVhtOpModeChannelWidth == + VHT_OP_MODE_CHANNEL_WIDTH_20) + prStaRec->u2HtCapInfo &= + ~HT_CAP_INFO_SUP_CHNL_WIDTH; + else /* for other 3 VHT cases: 40/80/160 */ + prStaRec->u2HtCapInfo |= + HT_CAP_INFO_SUP_CHNL_WIDTH; + } else if (prBssInfo->eCurrentOPMode == + OP_MODE_INFRASTRUCTURE) + rlmRecOpModeBwForClient(ucVhtOpModeChannelWidth, + prBssInfo); + + /* 3. Update StaRec to FW */ + /* As defined in spec, 11 means not support this MCS */ + if (((prRxFrame->ucOperatingMode & VHT_OP_MODE_RX_NSS) + >> VHT_OP_MODE_RX_NSS_OFFSET) == + VHT_OP_MODE_NSS_2) { + prStaRec->u2VhtRxMcsMap = BITS(0, 15) & + (~(VHT_CAP_INFO_MCS_1SS_MASK | + VHT_CAP_INFO_MCS_2SS_MASK)); + + prStaRec->u2VhtRxMcsMap |= + (prStaRec->u2VhtRxMcsMapAssoc & + (VHT_CAP_INFO_MCS_1SS_MASK | + VHT_CAP_INFO_MCS_2SS_MASK)); + + DBGLOG(RLM, INFO, + "NSS=2 RxMcsMap:0x%x, McsMapAssoc:0x%x\n", + prStaRec->u2VhtRxMcsMap, + prStaRec->u2VhtRxMcsMapAssoc); + } else { + /* NSS = 1 or others */ + prStaRec->u2VhtRxMcsMap = BITS(0, 15) & + (~VHT_CAP_INFO_MCS_1SS_MASK); + + prStaRec->u2VhtRxMcsMap |= + (prStaRec->u2VhtRxMcsMapAssoc & + VHT_CAP_INFO_MCS_1SS_MASK); + + DBGLOG(RLM, INFO, + "NSS=1 RxMcsMap:0x%x, McsMapAssoc:0x%x\n", + prStaRec->u2VhtRxMcsMap, + prStaRec->u2VhtRxMcsMapAssoc); + } + cnmStaSendUpdateCmd(prAdapter, prStaRec, NULL, FALSE); + + /* 4. Update BW parameters in BssInfo for STA mode only + */ + if (prBssInfo->eCurrentOPMode == + OP_MODE_INFRASTRUCTURE) { + /* 4.1 Revise by own OP BW if needed for STA + * mode only + */ + if (prBssInfo->fgIsOpChangeChannelWidth) { + /* VHT */ + if (rlmGetVhtOpBwByBssOpBw( + prBssInfo + ->ucOpChangeChannelWidth) < + prBssInfo->ucVhtChannelWidth) + rlmFillVhtOpInfoByBssOpBw( + prBssInfo, + prBssInfo + ->ucOpChangeChannelWidth); + /* HT */ + if (prBssInfo + ->fgIsOpChangeChannelWidth && + prBssInfo->ucOpChangeChannelWidth == + MAX_BW_20MHZ) { + prBssInfo->ucHtOpInfo1 &= ~( + HT_OP_INFO1_SCO | + HT_OP_INFO1_STA_CHNL_WIDTH); + prBssInfo->eBssSCO = + CHNL_EXT_SCN; + } + } + + /* 4.2 Check if OP BW parameter valid */ + if (!rlmDomainIsValidRfSetting( + prAdapter, prBssInfo->eBand, + prBssInfo->ucPrimaryChannel, + prBssInfo->eBssSCO, + prBssInfo->ucVhtChannelWidth, + prBssInfo->ucVhtChannelFrequencyS1, + prBssInfo->ucVhtChannelFrequencyS2)) { + + DBGLOG(RLM, WARN, + "rlmProcessVhtAction invalid RF settings\n"); + + /* Error Handling for Non-predicted IE - + * Fixed to set 20MHz + */ + prBssInfo->ucVhtChannelWidth = + CW_20_40MHZ; + prBssInfo->ucVhtChannelFrequencyS1 = 0; + prBssInfo->ucVhtChannelFrequencyS2 = 0; + prBssInfo->eBssSCO = CHNL_EXT_SCN; + prBssInfo->ucHtOpInfo1 &= + ~(HT_OP_INFO1_SCO | + HT_OP_INFO1_STA_CHNL_WIDTH); + } + + /* 4.3 Update BSS OP BW to FW for STA mode only + */ + rlmSyncOperationParams(prAdapter, prBssInfo); + } + } + break; + default: + break; + } +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function should be invoked after judging successful association. + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rlmFillSyncCmdParam(struct CMD_SET_BSS_RLM_PARAM *prCmdBody, + struct BSS_INFO *prBssInfo) +{ + if (!prCmdBody || !prBssInfo) + return; + + prCmdBody->ucBssIndex = prBssInfo->ucBssIndex; + prCmdBody->ucRfBand = (uint8_t)prBssInfo->eBand; + prCmdBody->ucPrimaryChannel = prBssInfo->ucPrimaryChannel; + prCmdBody->ucRfSco = (uint8_t)prBssInfo->eBssSCO; + prCmdBody->ucErpProtectMode = (uint8_t)prBssInfo->fgErpProtectMode; + prCmdBody->ucHtProtectMode = (uint8_t)prBssInfo->eHtProtectMode; + prCmdBody->ucGfOperationMode = (uint8_t)prBssInfo->eGfOperationMode; + prCmdBody->ucTxRifsMode = (uint8_t)prBssInfo->eRifsOperationMode; + prCmdBody->u2HtOpInfo3 = prBssInfo->u2HtOpInfo3; + prCmdBody->u2HtOpInfo2 = prBssInfo->u2HtOpInfo2; + prCmdBody->ucHtOpInfo1 = prBssInfo->ucHtOpInfo1; + prCmdBody->ucUseShortPreamble = prBssInfo->fgUseShortPreamble; + prCmdBody->ucUseShortSlotTime = prBssInfo->fgUseShortSlotTime; + prCmdBody->ucVhtChannelWidth = prBssInfo->ucVhtChannelWidth; + prCmdBody->ucVhtChannelFrequencyS1 = prBssInfo->ucVhtChannelFrequencyS1; + prCmdBody->ucVhtChannelFrequencyS2 = prBssInfo->ucVhtChannelFrequencyS2; + prCmdBody->u2VhtBasicMcsSet = prBssInfo->u2BSSBasicRateSet; + prCmdBody->ucTxNss = prBssInfo->ucOpTxNss; + prCmdBody->ucRxNss = prBssInfo->ucOpRxNss; + + if (RLM_NET_PARAM_VALID(prBssInfo)) { + DBGLOG(RLM, INFO, + "N=%d b=%d c=%d s=%d e=%d h=%d I=0x%02x l=%d p=%d w=%d s1=%d s2=%d RxN=%d, TxN=%d\n", + prCmdBody->ucBssIndex, prCmdBody->ucRfBand, + prCmdBody->ucPrimaryChannel, prCmdBody->ucRfSco, + prCmdBody->ucErpProtectMode, prCmdBody->ucHtProtectMode, + prCmdBody->ucHtOpInfo1, prCmdBody->ucUseShortSlotTime, + prCmdBody->ucUseShortPreamble, + prCmdBody->ucVhtChannelWidth, + prCmdBody->ucVhtChannelFrequencyS1, + prCmdBody->ucVhtChannelFrequencyS2, + prCmdBody->ucRxNss, + prCmdBody->ucTxNss); + } else { + DBGLOG(RLM, INFO, "N=%d closed\n", prCmdBody->ucBssIndex); + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function will operation parameters based on situations of + * concurrent networks. Channel, bandwidth, protection mode, supported + * rate will be modified. + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rlmSyncOperationParams(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo) +{ + struct CMD_SET_BSS_RLM_PARAM *prCmdBody; + uint32_t rStatus; + + ASSERT(prAdapter); + ASSERT(prBssInfo); + + prCmdBody = (struct CMD_SET_BSS_RLM_PARAM *)cnmMemAlloc( + prAdapter, RAM_TYPE_BUF, sizeof(struct CMD_SET_BSS_RLM_PARAM)); + + /* ASSERT(prCmdBody); */ + /* To do: exception handle */ + if (!prCmdBody) { + DBGLOG(RLM, WARN, "No buf for sync RLM params (Net=%d)\n", + prBssInfo->ucBssIndex); + return; + } + + rlmFillSyncCmdParam(prCmdBody, prBssInfo); + + rStatus = wlanSendSetQueryCmd( + prAdapter, /* prAdapter */ + CMD_ID_SET_BSS_RLM_PARAM, /* ucCID */ + TRUE, /* fgSetQuery */ + FALSE, /* fgNeedResp */ + FALSE, /* fgIsOid */ + NULL, /* pfCmdDoneHandler */ + NULL, /* pfCmdTimeoutHandler */ + sizeof(struct CMD_SET_BSS_RLM_PARAM), /* u4SetQueryInfoLen */ + (uint8_t *)prCmdBody, /* pucInfoBuffer */ + NULL, /* pvSetQueryBuffer */ + 0 /* u4SetQueryBufferLen */ + ); + + /* ASSERT(rStatus == WLAN_STATUS_PENDING); */ + if (rStatus != WLAN_STATUS_PENDING) + DBGLOG(RLM, WARN, "rlmSyncOperationParams set cmd fail\n"); + + cnmMemFree(prAdapter, prCmdBody); +} + +#if CFG_SUPPORT_AAA +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function should be invoked after judging successful association. + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rlmProcessAssocReq(struct ADAPTER *prAdapter, struct SW_RFB *prSwRfb, + uint8_t *pucIE, uint16_t u2IELength) +{ + struct BSS_INFO *prBssInfo; + struct STA_RECORD *prStaRec; + uint16_t u2Offset; + struct IE_HT_CAP *prHtCap; +#if CFG_SUPPORT_802_11AC + struct IE_VHT_CAP *prVhtCap = NULL; + struct IE_OP_MODE_NOTIFICATION + *prOPModeNotification; /* Operation Mode Notification */ + u_int8_t fgHasOPModeIE = FALSE; +#endif + + ASSERT(prAdapter); + ASSERT(prSwRfb); + ASSERT(pucIE); + + prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); + if (!prStaRec) + return; + ASSERT(prStaRec->ucBssIndex <= prAdapter->ucHwBssIdNum); + + prBssInfo = prAdapter->aprBssInfo[prStaRec->ucBssIndex]; + + IE_FOR_EACH(pucIE, u2IELength, u2Offset) + { + switch (IE_ID(pucIE)) { + case ELEM_ID_HT_CAP: + if (!RLM_NET_IS_11N(prBssInfo) || + IE_LEN(pucIE) != (sizeof(struct IE_HT_CAP) - 2)) + break; + prHtCap = (struct IE_HT_CAP *)pucIE; + prStaRec->ucMcsSet = + prHtCap->rSupMcsSet.aucRxMcsBitmask[0]; + prStaRec->fgSupMcs32 = + (prHtCap->rSupMcsSet.aucRxMcsBitmask[32 / 8] & + BIT(0)) + ? TRUE + : FALSE; + + kalMemCopy( + prStaRec->aucRxMcsBitmask, + prHtCap->rSupMcsSet.aucRxMcsBitmask, + /*SUP_MCS_RX_BITMASK_OCTET_NUM */ + sizeof(prStaRec->aucRxMcsBitmask)); + + prStaRec->u2HtCapInfo = prHtCap->u2HtCapInfo; + + /* Set Short LDPC Tx capability */ + if (IS_FEATURE_FORCE_ENABLED( + prAdapter->rWifiVar.ucTxLdpc)) + prStaRec->u2HtCapInfo |= HT_CAP_INFO_LDPC_CAP; + else if (IS_FEATURE_DISABLED( + prAdapter->rWifiVar.ucTxLdpc)) + prStaRec->u2HtCapInfo &= ~HT_CAP_INFO_LDPC_CAP; + + /* Set STBC Tx capability */ + if (IS_FEATURE_FORCE_ENABLED( + prAdapter->rWifiVar.ucTxStbc)) + prStaRec->u2HtCapInfo |= HT_CAP_INFO_TX_STBC; + else if (IS_FEATURE_DISABLED( + prAdapter->rWifiVar.ucTxStbc)) + prStaRec->u2HtCapInfo &= ~HT_CAP_INFO_TX_STBC; + /* Set Short GI Tx capability */ + if (IS_FEATURE_FORCE_ENABLED( + prAdapter->rWifiVar.ucTxShortGI)) { + prStaRec->u2HtCapInfo |= + HT_CAP_INFO_SHORT_GI_20M; + prStaRec->u2HtCapInfo |= + HT_CAP_INFO_SHORT_GI_40M; + } else if (IS_FEATURE_DISABLED( + prAdapter->rWifiVar.ucTxShortGI)) { + prStaRec->u2HtCapInfo &= + ~HT_CAP_INFO_SHORT_GI_20M; + prStaRec->u2HtCapInfo &= + ~HT_CAP_INFO_SHORT_GI_40M; + } + + /* Set HT Greenfield Tx capability */ + if (IS_FEATURE_FORCE_ENABLED( + prAdapter->rWifiVar.ucTxGf)) + prStaRec->u2HtCapInfo |= HT_CAP_INFO_HT_GF; + else if (IS_FEATURE_DISABLED( + prAdapter->rWifiVar.ucTxGf)) + prStaRec->u2HtCapInfo &= ~HT_CAP_INFO_HT_GF; + + prStaRec->ucAmpduParam = prHtCap->ucAmpduParam; + prStaRec->u2HtExtendedCap = prHtCap->u2HtExtendedCap; + prStaRec->u4TxBeamformingCap = + prHtCap->u4TxBeamformingCap; + prStaRec->ucAselCap = prHtCap->ucAselCap; + break; + +#if (CFG_SUPPORT_802_11AX == 1) + case ELEM_ID_RESERVED: + if (IE_ID_EXT(pucIE) == ELEM_EXT_ID_HE_CAP) + heRlmRecHeCapInfo(prAdapter, prStaRec, pucIE); + break; +#endif + +#if CFG_SUPPORT_802_11AC + case ELEM_ID_VHT_CAP: + if (!RLM_NET_IS_11AC(prBssInfo) || + IE_LEN(pucIE) != (sizeof(struct IE_VHT_CAP) - 2)) + break; + + prVhtCap = (struct IE_VHT_CAP *)pucIE; + + prStaRec->u4VhtCapInfo = prVhtCap->u4VhtCapInfo; + + /* Set Tx LDPC capability */ + if (IS_FEATURE_FORCE_ENABLED( + prAdapter->rWifiVar.ucTxLdpc)) + prStaRec->u4VhtCapInfo |= VHT_CAP_INFO_RX_LDPC; + else if (IS_FEATURE_DISABLED( + prAdapter->rWifiVar.ucTxLdpc)) + prStaRec->u4VhtCapInfo &= ~VHT_CAP_INFO_RX_LDPC; + + /* Set Tx STBC capability */ + if (IS_FEATURE_FORCE_ENABLED( + prAdapter->rWifiVar.ucTxStbc)) + prStaRec->u4VhtCapInfo |= VHT_CAP_INFO_TX_STBC; + else if (IS_FEATURE_DISABLED( + prAdapter->rWifiVar.ucTxStbc)) + prStaRec->u4VhtCapInfo &= ~VHT_CAP_INFO_TX_STBC; + + /* Set Tx TXOP PS capability */ + if (IS_FEATURE_FORCE_ENABLED( + prAdapter->rWifiVar.ucTxopPsTx)) + prStaRec->u4VhtCapInfo |= + VHT_CAP_INFO_VHT_TXOP_PS; + else if (IS_FEATURE_DISABLED( + prAdapter->rWifiVar.ucTxopPsTx)) + prStaRec->u4VhtCapInfo &= + ~VHT_CAP_INFO_VHT_TXOP_PS; + + /* Set Tx Short GI capability */ + if (IS_FEATURE_FORCE_ENABLED( + prAdapter->rWifiVar.ucTxShortGI)) { + prStaRec->u4VhtCapInfo |= + VHT_CAP_INFO_SHORT_GI_80; + prStaRec->u4VhtCapInfo |= + VHT_CAP_INFO_SHORT_GI_160_80P80; + } else if (IS_FEATURE_DISABLED( + prAdapter->rWifiVar.ucTxShortGI)) { + prStaRec->u4VhtCapInfo &= + ~VHT_CAP_INFO_SHORT_GI_80; + prStaRec->u4VhtCapInfo &= + ~VHT_CAP_INFO_SHORT_GI_160_80P80; + } + + prStaRec->u2VhtRxMcsMap = + prVhtCap->rVhtSupportedMcsSet.u2RxMcsMap; + + prStaRec->u2VhtRxMcsMapAssoc = + prStaRec->u2VhtRxMcsMap; + + prStaRec->u2VhtRxHighestSupportedDataRate = + prVhtCap->rVhtSupportedMcsSet + .u2RxHighestSupportedDataRate; + prStaRec->u2VhtTxMcsMap = + prVhtCap->rVhtSupportedMcsSet.u2TxMcsMap; + prStaRec->u2VhtTxHighestSupportedDataRate = + prVhtCap->rVhtSupportedMcsSet + .u2TxHighestSupportedDataRate; + + /* Set initial value of VHT OP mode */ + prStaRec->ucVhtOpMode = 0; + prStaRec->ucVhtOpMode |= + rlmGetOpModeBwByVhtAndHtOpInfo(prBssInfo); + prStaRec->ucVhtOpMode |= + ((rlmGetSupportRxNssInVhtCap(prVhtCap) - 1) + << VHT_OP_MODE_RX_NSS_OFFSET) & + VHT_OP_MODE_RX_NSS; + + break; + case ELEM_ID_OP_MODE: + if (!RLM_NET_IS_11AC(prBssInfo) || + IE_LEN(pucIE) != + (sizeof(struct IE_OP_MODE_NOTIFICATION) - + 2)) + break; + prOPModeNotification = + (struct IE_OP_MODE_NOTIFICATION *)pucIE; + + if ((prOPModeNotification->ucOpMode & + VHT_OP_MODE_RX_NSS_TYPE) != + VHT_OP_MODE_RX_NSS_TYPE) { + fgHasOPModeIE = TRUE; + } + + break; + +#endif + + default: + break; + } /* end of switch */ + } /* end of IE_FOR_EACH */ +#if CFG_SUPPORT_802_11AC + /*Fill by OP Mode IE after completing parsing all IE to make sure it + * won't be overwrite + */ + if (fgHasOPModeIE == TRUE) + prStaRec->ucVhtOpMode = prOPModeNotification->ucOpMode; +#endif +} +#endif /* CFG_SUPPORT_AAA */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief It is for both STA and AP modes + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rlmBssInitForAPandIbss(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo) +{ + ASSERT(prAdapter); + ASSERT(prBssInfo); + +#if CFG_ENABLE_WIFI_DIRECT + if (prAdapter->fgIsP2PRegistered && + prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) + rlmBssInitForAP(prAdapter, prBssInfo); +#endif +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief It is for both STA and AP modes + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rlmBssAborted(struct ADAPTER *prAdapter, struct BSS_INFO *prBssInfo) +{ + ASSERT(prAdapter); + ASSERT(prBssInfo); + + rlmBssReset(prAdapter, prBssInfo); + + prBssInfo->fg40mBwAllowed = FALSE; + prBssInfo->fgAssoc40mBwAllowed = FALSE; + + /* Assume FW state is updated by CMD_ID_SET_BSS_INFO, so + * the sync CMD is not needed here. + */ +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief All RLM timers will also be stopped. + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +static void rlmBssReset(struct ADAPTER *prAdapter, struct BSS_INFO *prBssInfo) +{ + ASSERT(prAdapter); + ASSERT(prBssInfo); + + /* HT related parameters */ + prBssInfo->ucHtOpInfo1 = 0; /* RIFS disabled. 20MHz */ + prBssInfo->u2HtOpInfo2 = 0; + prBssInfo->u2HtOpInfo3 = 0; + +#if CFG_SUPPORT_802_11AC + prBssInfo->ucVhtChannelWidth = 0; /* VHT_OP_CHANNEL_WIDTH_80; */ + prBssInfo->ucVhtChannelFrequencyS1 = 0; /* 42; */ + prBssInfo->ucVhtChannelFrequencyS2 = 0; + prBssInfo->u2VhtBasicMcsSet = 0; /* 0xFFFF; */ +#endif + + prBssInfo->eBssSCO = 0; + prBssInfo->fgErpProtectMode = 0; + prBssInfo->eHtProtectMode = 0; + prBssInfo->eGfOperationMode = 0; + prBssInfo->eRifsOperationMode = 0; + + /* OBSS related parameters */ + prBssInfo->auc2G_20mReqChnlList[0] = 0; + prBssInfo->auc2G_NonHtChnlList[0] = 0; + prBssInfo->auc2G_PriChnlList[0] = 0; + prBssInfo->auc2G_SecChnlList[0] = 0; + prBssInfo->auc5G_20mReqChnlList[0] = 0; + prBssInfo->auc5G_NonHtChnlList[0] = 0; + prBssInfo->auc5G_PriChnlList[0] = 0; + prBssInfo->auc5G_SecChnlList[0] = 0; + + /* All RLM timers will also be stopped */ + cnmTimerStopTimer(prAdapter, &prBssInfo->rObssScanTimer); + prBssInfo->u2ObssScanInterval = 0; + + prBssInfo->fgObssErpProtectMode = 0; /* GO only */ + prBssInfo->eObssHtProtectMode = 0; /* GO only */ + prBssInfo->eObssGfOperationMode = 0; /* GO only */ + prBssInfo->fgObssRifsOperationMode = 0; /* GO only */ + prBssInfo->fgObssActionForcedTo20M = 0; /* GO only */ + prBssInfo->fgObssBeaconForcedTo20M = 0; /* GO only */ + + /* OP mode change control parameters */ + prBssInfo->fgIsOpChangeChannelWidth = FALSE; + prBssInfo->fgIsOpChangeRxNss = FALSE; + prBssInfo->fgIsOpChangeTxNss = FALSE; + +#if (CFG_SUPPORT_802_11AX == 1) + if (fgEfuseCtrlAxOn == 1) { + /* MU EDCA params */ + prBssInfo->ucMUEdcaUpdateCnt = 0; + kalMemSet(&prBssInfo->arMUEdcaParams[0], 0, + sizeof(struct _CMD_MU_EDCA_PARAMS_T) * WMM_AC_INDEX_NUM); + + /* Spatial Reuse params */ + prBssInfo->ucSRControl = 0; + prBssInfo->ucNonSRGObssPdMaxOffset = 0; + prBssInfo->ucSRGObssPdMinOffset = 0; + prBssInfo->ucSRGObssPdMaxOffset = 0; + prBssInfo->u8SRGBSSColorBitmap = 0; + prBssInfo->u8SRGPartialBSSIDBitmap = 0; + + /* HE Operation */ + memset(prBssInfo->ucHeOpParams, 0, HE_OP_BYTE_NUM); + /* set TXOP to 0x3FF (Spec. define default value) */ + prBssInfo->ucHeOpParams[0] + |= HE_OP_PARAM0_TXOP_DUR_RTS_THRESHOLD_MASK; + prBssInfo->ucHeOpParams[1] + |= HE_OP_PARAM1_TXOP_DUR_RTS_THRESHOLD_MASK; + prBssInfo->ucBssColorInfo = 0; + prBssInfo->u2HeBasicMcsSet = 0; + } +#endif + +#ifdef CFG_DFS_CHSW_FORCE_BW20 + g_fgHasChannelSwitchIE = FALSE; +#endif +} + +#if CFG_SUPPORT_TDLS +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +uint32_t rlmFillVhtCapIEByAdapter(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, uint8_t *pOutBuf) +{ + struct IE_VHT_CAP *prVhtCap; + struct VHT_SUPPORTED_MCS_FIELD *prVhtSupportedMcsSet; + uint8_t i; + + ASSERT(prAdapter); + ASSERT(prBssInfo); + /* ASSERT(prMsduInfo); */ + + prVhtCap = (struct IE_VHT_CAP *)pOutBuf; + + prVhtCap->ucId = ELEM_ID_VHT_CAP; + prVhtCap->ucLength = sizeof(struct IE_VHT_CAP) - ELEM_HDR_LEN; + prVhtCap->u4VhtCapInfo = VHT_CAP_INFO_DEFAULT_VAL; + + if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucRxShortGI)) + prVhtCap->u4VhtCapInfo |= VHT_CAP_INFO_SHORT_GI_80; + + if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucRxLdpc)) + prVhtCap->u4VhtCapInfo |= VHT_CAP_INFO_RX_LDPC; + + if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucRxStbc)) + prVhtCap->u4VhtCapInfo |= VHT_CAP_INFO_RX_STBC_ONE_STREAM; + + /*set MCS map */ + prVhtSupportedMcsSet = &prVhtCap->rVhtSupportedMcsSet; + kalMemZero((void *)prVhtSupportedMcsSet, + sizeof(struct VHT_SUPPORTED_MCS_FIELD)); + + for (i = 0; i < 8; i++) { + prVhtSupportedMcsSet->u2RxMcsMap |= BITS(2 * i, (2 * i + 1)); + prVhtSupportedMcsSet->u2TxMcsMap |= BITS(2 * i, (2 * i + 1)); + } + + prVhtSupportedMcsSet->u2RxMcsMap &= + (VHT_CAP_INFO_MCS_MAP_MCS9 << VHT_CAP_INFO_MCS_1SS_OFFSET); + prVhtSupportedMcsSet->u2TxMcsMap &= + (VHT_CAP_INFO_MCS_MAP_MCS9 << VHT_CAP_INFO_MCS_1SS_OFFSET); + prVhtSupportedMcsSet->u2RxHighestSupportedDataRate = + VHT_CAP_INFO_DEFAULT_HIGHEST_DATA_RATE; + prVhtSupportedMcsSet->u2TxHighestSupportedDataRate = + VHT_CAP_INFO_DEFAULT_HIGHEST_DATA_RATE; + + ASSERT(IE_SIZE(prVhtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_VHT_CAP)); + + return IE_SIZE(prVhtCap); +} +#endif + +#if CFG_SUPPORT_TDLS +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +uint32_t rlmFillHtCapIEByParams(u_int8_t fg40mAllowed, + u_int8_t fgShortGIDisabled, + uint8_t u8SupportRxSgi20, + uint8_t u8SupportRxSgi40, uint8_t u8SupportRxGf, + enum ENUM_OP_MODE eCurrentOPMode, + uint8_t *pOutBuf) +{ + struct IE_HT_CAP *prHtCap; + struct SUP_MCS_SET_FIELD *prSupMcsSet; + + ASSERT(pOutBuf); + + prHtCap = (struct IE_HT_CAP *)pOutBuf; + + /* Add HT capabilities IE */ + prHtCap->ucId = ELEM_ID_HT_CAP; + prHtCap->ucLength = sizeof(struct IE_HT_CAP) - ELEM_HDR_LEN; + + prHtCap->u2HtCapInfo = HT_CAP_INFO_DEFAULT_VAL; + if (!fg40mAllowed) { + prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | + HT_CAP_INFO_SHORT_GI_40M | + HT_CAP_INFO_DSSS_CCK_IN_40M); + } + if (fgShortGIDisabled) + prHtCap->u2HtCapInfo &= + ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M); + + if (u8SupportRxSgi20 == 2) + prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_20M); + if (u8SupportRxSgi40 == 2) + prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_40M); + if (u8SupportRxGf == 2) + prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_HT_GF); + + prHtCap->ucAmpduParam = AMPDU_PARAM_DEFAULT_VAL; + + prSupMcsSet = &prHtCap->rSupMcsSet; + kalMemZero((void *)&prSupMcsSet->aucRxMcsBitmask[0], + SUP_MCS_RX_BITMASK_OCTET_NUM); + + prSupMcsSet->aucRxMcsBitmask[0] = BITS(0, 7); + + if (fg40mAllowed) + prSupMcsSet->aucRxMcsBitmask[32 / 8] = BIT(0); /* MCS32 */ + prSupMcsSet->u2RxHighestSupportedRate = SUP_MCS_RX_DEFAULT_HIGHEST_RATE; + prSupMcsSet->u4TxRateInfo = SUP_MCS_TX_DEFAULT_VAL; + + prHtCap->u2HtExtendedCap = HT_EXT_CAP_DEFAULT_VAL; + if (!fg40mAllowed || eCurrentOPMode != OP_MODE_INFRASTRUCTURE) + prHtCap->u2HtExtendedCap &= + ~(HT_EXT_CAP_PCO | HT_EXT_CAP_PCO_TRANS_TIME_NONE); + + prHtCap->u4TxBeamformingCap = TX_BEAMFORMING_CAP_DEFAULT_VAL; + + prHtCap->ucAselCap = ASEL_CAP_DEFAULT_VAL; + + ASSERT(IE_SIZE(prHtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP)); + + return IE_SIZE(prHtCap); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +uint32_t rlmFillHtCapIEByAdapter(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, uint8_t *pOutBuf) +{ + struct IE_HT_CAP *prHtCap; + struct SUP_MCS_SET_FIELD *prSupMcsSet; + u_int8_t fg40mAllowed; + + ASSERT(prAdapter); + ASSERT(prBssInfo); + ASSERT(pOutBuf); + + fg40mAllowed = prBssInfo->fgAssoc40mBwAllowed; + + prHtCap = (struct IE_HT_CAP *)pOutBuf; + + /* Add HT capabilities IE */ + prHtCap->ucId = ELEM_ID_HT_CAP; + prHtCap->ucLength = sizeof(struct IE_HT_CAP) - ELEM_HDR_LEN; + + prHtCap->u2HtCapInfo = HT_CAP_INFO_DEFAULT_VAL; + if (!fg40mAllowed) { + prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | + HT_CAP_INFO_SHORT_GI_40M | + HT_CAP_INFO_DSSS_CCK_IN_40M); + } + if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucRxShortGI)) + prHtCap->u2HtCapInfo |= + (HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M); + + if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucRxLdpc)) + prHtCap->u2HtCapInfo |= HT_CAP_INFO_LDPC_CAP; + + if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucRxStbc)) + prHtCap->u2HtCapInfo |= HT_CAP_INFO_RX_STBC_1_SS; + + prHtCap->ucAmpduParam = AMPDU_PARAM_DEFAULT_VAL; + + prSupMcsSet = &prHtCap->rSupMcsSet; + kalMemZero((void *)&prSupMcsSet->aucRxMcsBitmask[0], + SUP_MCS_RX_BITMASK_OCTET_NUM); + + prSupMcsSet->aucRxMcsBitmask[0] = BITS(0, 7); + + if (fg40mAllowed && IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucMCS32)) + prSupMcsSet->aucRxMcsBitmask[32 / 8] = BIT(0); /* MCS32 */ + prSupMcsSet->u2RxHighestSupportedRate = SUP_MCS_RX_DEFAULT_HIGHEST_RATE; + prSupMcsSet->u4TxRateInfo = SUP_MCS_TX_DEFAULT_VAL; + + prHtCap->u2HtExtendedCap = HT_EXT_CAP_DEFAULT_VAL; + if (!fg40mAllowed || + prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) + prHtCap->u2HtExtendedCap &= + ~(HT_EXT_CAP_PCO | HT_EXT_CAP_PCO_TRANS_TIME_NONE); + + prHtCap->u4TxBeamformingCap = TX_BEAMFORMING_CAP_DEFAULT_VAL; + + prHtCap->ucAselCap = ASEL_CAP_DEFAULT_VAL; + + ASSERT(IE_SIZE(prHtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP)); + + return IE_SIZE(prHtCap); +} + +#endif + +#if CFG_SUPPORT_DFS +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will compose the TPC Report frame. + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] prStaRec Pointer to the STA_RECORD_T. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +static void tpcComposeReportFrame(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, + IN PFN_TX_DONE_HANDLER pfTxDoneHandler) +{ + struct MSDU_INFO *prMsduInfo; + struct BSS_INFO *prBssInfo; + struct ACTION_TPC_REPORT_FRAME *prTxFrame; + uint16_t u2PayloadLen; + + ASSERT(prAdapter); + ASSERT(prStaRec); + + prBssInfo = &prAdapter->rWifiVar.arBssInfoPool[prStaRec->ucBssIndex]; + ASSERT(prBssInfo); + + prMsduInfo = (struct MSDU_INFO *)cnmMgtPktAlloc( + prAdapter, MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN); + + if (!prMsduInfo) + return; + + prTxFrame = (struct ACTION_TPC_REPORT_FRAME + *)((unsigned long)(prMsduInfo->prPacket) + + MAC_TX_RESERVED_FIELD); + + prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; + + COPY_MAC_ADDR(prTxFrame->aucDestAddr, prStaRec->aucMacAddr); + COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); + COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); + + prTxFrame->ucCategory = CATEGORY_SPEC_MGT; + prTxFrame->ucAction = ACTION_TPC_REPORT; + + /* 3 Compose the frame body's frame. */ + prTxFrame->ucDialogToken = prStaRec->ucSmDialogToken; + prTxFrame->ucElemId = ELEM_ID_TPC_REPORT; + prTxFrame->ucLength = + sizeof(prTxFrame->ucLinkMargin) + sizeof(prTxFrame->ucTransPwr); + prTxFrame->ucTransPwr = prAdapter->u4GetTxPower; + prTxFrame->ucLinkMargin = + prAdapter->rLinkQuality.rLq[prStaRec->ucBssIndex]. + cRssi - (0 - MIN_RCV_PWR); + + u2PayloadLen = ACTION_SM_TPC_REPORT_LEN; + + /* 4 Update information of MSDU_INFO_T */ + TX_SET_MMPDU(prAdapter, prMsduInfo, prStaRec->ucBssIndex, + prStaRec->ucIndex, WLAN_MAC_MGMT_HEADER_LEN, + WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen, pfTxDoneHandler, + MSDU_RATE_MODE_AUTO); + + DBGLOG(RLM, TRACE, "ucDialogToken %d ucTransPwr %d ucLinkMargin %d\n", + prTxFrame->ucDialogToken, prTxFrame->ucTransPwr, + prTxFrame->ucLinkMargin); + + /* 4 Enqueue the frame to send this action frame. */ + nicTxEnqueueMsdu(prAdapter, prMsduInfo); + + return; + +} /* end of tpcComposeReportFrame() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will compose the Measurement Report frame. + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] prStaRec Pointer to the STA_RECORD_T. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +static void msmtComposeReportFrame(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, + IN PFN_TX_DONE_HANDLER pfTxDoneHandler) +{ + struct MSDU_INFO *prMsduInfo; + struct BSS_INFO *prBssInfo; + struct ACTION_SM_REQ_FRAME *prTxFrame; + struct IE_MEASUREMENT_REPORT *prMeasurementRepIE; + uint8_t *pucIE; + uint16_t u2PayloadLen; + + ASSERT(prAdapter); + ASSERT(prStaRec); + + prBssInfo = &prAdapter->rWifiVar.arBssInfoPool[prStaRec->ucBssIndex]; + ASSERT(prBssInfo); + + prMsduInfo = (struct MSDU_INFO *)cnmMgtPktAlloc( + prAdapter, MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN); + + if (!prMsduInfo) + return; + + prTxFrame = (struct ACTION_SM_REQ_FRAME + *)((unsigned long)(prMsduInfo->prPacket) + + MAC_TX_RESERVED_FIELD); + pucIE = prTxFrame->aucInfoElem; + prMeasurementRepIE = SM_MEASUREMENT_REP_IE(pucIE); + + prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; + + COPY_MAC_ADDR(prTxFrame->aucDestAddr, prStaRec->aucMacAddr); + COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); + COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); + + prTxFrame->ucCategory = CATEGORY_SPEC_MGT; + prTxFrame->ucAction = ACTION_MEASUREMENT_REPORT; + + /* 3 Compose the frame body's frame. */ + prTxFrame->ucDialogToken = prStaRec->ucSmDialogToken; + prMeasurementRepIE->ucId = ELEM_ID_MEASUREMENT_REPORT; + +#if 0 + if (prStaRec->ucSmMsmtRequestMode == ELEM_RM_TYPE_BASIC_REQ) { + prMeasurementRepIE->ucLength = + sizeof(struct SM_BASIC_REPORT) + 3; + u2PayloadLen = ACTION_SM_MEASURE_REPORT_LEN+ + ACTION_SM_BASIC_REPORT_LEN; + } else if (prStaRec->ucSmMsmtRequestMode == ELEM_RM_TYPE_CCA_REQ) { + prMeasurementRepIE->ucLength = sizeof(struct SM_CCA_REPORT) + 3; + u2PayloadLen = ACTION_SM_MEASURE_REPORT_LEN+ + ACTION_SM_CCA_REPORT_LEN; + } else if (prStaRec->ucSmMsmtRequestMode == + ELEM_RM_TYPE_RPI_HISTOGRAM_REQ) { + prMeasurementRepIE->ucLength = sizeof(struct SM_RPI_REPORT) + 3; + u2PayloadLen = ACTION_SM_MEASURE_REPORT_LEN+ + ACTION_SM_PRI_REPORT_LEN; + } else { + prMeasurementRepIE->ucLength = 3; + u2PayloadLen = ACTION_SM_MEASURE_REPORT_LEN; + } +#else + prMeasurementRepIE->ucLength = 3; + u2PayloadLen = ACTION_SM_MEASURE_REPORT_LEN; + prMeasurementRepIE->ucToken = prStaRec->ucSmMsmtToken; + prMeasurementRepIE->ucReportMode = BIT(1); + prMeasurementRepIE->ucMeasurementType = prStaRec->ucSmMsmtRequestMode; +#endif + + /* 4 Update information of MSDU_INFO_T */ + TX_SET_MMPDU(prAdapter, prMsduInfo, prStaRec->ucBssIndex, + prStaRec->ucIndex, WLAN_MAC_MGMT_HEADER_LEN, + WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen, pfTxDoneHandler, + MSDU_RATE_MODE_AUTO); + + DBGLOG(RLM, TRACE, + "ucDialogToken %d ucToken %d ucReportMode %d ucMeasurementType %d\n", + prTxFrame->ucDialogToken, prMeasurementRepIE->ucToken, + prMeasurementRepIE->ucReportMode, + prMeasurementRepIE->ucMeasurementType); + + /* 4 Enqueue the frame to send this action frame. */ + nicTxEnqueueMsdu(prAdapter, prMsduInfo); + + return; + +} /* end of msmtComposeReportFrame() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function handle spectrum management action frame + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rlmProcessSpecMgtAction(struct ADAPTER *prAdapter, struct SW_RFB *prSwRfb) +{ + uint8_t *pucIE; + struct STA_RECORD *prStaRec; + struct BSS_INFO *prBssInfo; + uint16_t u2IELength; + uint16_t u2Offset = 0; + struct IE_CHANNEL_SWITCH *prChannelSwitchAnnounceIE; + struct IE_SECONDARY_OFFSET *prSecondaryOffsetIE; + struct IE_WIDE_BAND_CHANNEL *prWideBandChannelIE; + struct IE_TPC_REQ *prTpcReqIE; + struct IE_TPC_REPORT *prTpcRepIE; + struct IE_MEASUREMENT_REQ *prMeasurementReqIE; + struct IE_MEASUREMENT_REPORT *prMeasurementRepIE; + struct ACTION_SM_REQ_FRAME *prRxFrame; + u_int8_t fgHasWideBandIE = FALSE; + u_int8_t fgHasSCOIE = FALSE; + u_int8_t fgHasChannelSwitchIE = FALSE; + + DBGLOG(RLM, INFO, "[Mgt Action]rlmProcessSpecMgtAction\n"); + ASSERT(prAdapter); + ASSERT(prSwRfb); + + u2IELength = + prSwRfb->u2PacketLen - + (uint16_t)OFFSET_OF(struct ACTION_SM_REQ_FRAME, aucInfoElem[0]); + + prRxFrame = (struct ACTION_SM_REQ_FRAME *)prSwRfb->pvHeader; + pucIE = prRxFrame->aucInfoElem; + + prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); + if (!prStaRec) + return; + + if (prStaRec->ucBssIndex > prAdapter->ucHwBssIdNum) + return; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex); + + prStaRec->ucSmDialogToken = prRxFrame->ucDialogToken; + + DBGLOG_MEM8(RLM, INFO, pucIE, u2IELength); + switch (prRxFrame->ucAction) { + case ACTION_MEASUREMENT_REQ: + DBGLOG(RLM, INFO, "[Mgt Action] Measure Request\n"); + prMeasurementReqIE = SM_MEASUREMENT_REQ_IE(pucIE); + if (prMeasurementReqIE->ucId == ELEM_ID_MEASUREMENT_REQ) { + /* Check IE length is valid */ + if (prMeasurementReqIE->ucLength != 0 && + (prMeasurementReqIE->ucLength >= + sizeof(struct IE_MEASUREMENT_REQ) - 2)) { + prStaRec->ucSmMsmtRequestMode = + prMeasurementReqIE->ucRequestMode; + prStaRec->ucSmMsmtToken = + prMeasurementReqIE->ucToken; + msmtComposeReportFrame(prAdapter, prStaRec, + NULL); + } + } + + break; + case ACTION_MEASUREMENT_REPORT: + DBGLOG(RLM, INFO, "[Mgt Action] Measure Report\n"); + prMeasurementRepIE = SM_MEASUREMENT_REP_IE(pucIE); + if (prMeasurementRepIE->ucId == ELEM_ID_MEASUREMENT_REPORT) + DBGLOG(RLM, TRACE, + "[Mgt Action] Correct Measurement report IE !!\n"); + break; + case ACTION_TPC_REQ: + DBGLOG(RLM, INFO, "[Mgt Action] TPC Request\n"); + prTpcReqIE = SM_TPC_REQ_IE(pucIE); + + if (prTpcReqIE->ucId == ELEM_ID_TPC_REQ) + tpcComposeReportFrame(prAdapter, prStaRec, NULL); + + break; + case ACTION_TPC_REPORT: + DBGLOG(RLM, INFO, "[Mgt Action] TPC Report\n"); + prTpcRepIE = SM_TPC_REP_IE(pucIE); + + if (prTpcRepIE->ucId == ELEM_ID_TPC_REPORT) + DBGLOG(RLM, TRACE, + "[Mgt Action] Correct TPC report IE !!\n"); + + break; + case ACTION_CHNL_SWITCH: + IE_FOR_EACH(pucIE, u2IELength, u2Offset) + { + switch (IE_ID(pucIE)) { + + case ELEM_ID_WIDE_BAND_CHANNEL_SWITCH: + if (!RLM_NET_IS_11AC(prBssInfo) || + IE_LEN(pucIE) != + (sizeof(struct + IE_WIDE_BAND_CHANNEL) - + 2)) { + DBGLOG(RLM, INFO, + "[Mgt Action] ELEM_ID_WIDE_BAND_CHANNEL_SWITCH, Length\n"); + break; + } + DBGLOG(RLM, INFO, + "[Mgt Action] ELEM_ID_WIDE_BAND_CHANNEL_SWITCH, 11AC\n"); + prWideBandChannelIE = + (struct IE_WIDE_BAND_CHANNEL *)pucIE; + prBssInfo->ucVhtChannelWidth = + prWideBandChannelIE->ucNewChannelWidth; + prBssInfo->ucVhtChannelFrequencyS1 = + prWideBandChannelIE->ucChannelS1; + prBssInfo->ucVhtChannelFrequencyS2 = + prWideBandChannelIE->ucChannelS2; + + /* Revise by own OP BW if needed */ + if ((prBssInfo->fgIsOpChangeChannelWidth) && + (rlmGetVhtOpBwByBssOpBw( + prBssInfo + ->ucOpChangeChannelWidth) < + prBssInfo->ucVhtChannelWidth)) { + + DBGLOG(RLM, LOUD, + "Change to w:%d s1:%d s2:%d since own changed BW < peer's WideBand BW", + prBssInfo->ucVhtChannelWidth, + prBssInfo->ucVhtChannelFrequencyS1, + prBssInfo->ucVhtChannelFrequencyS2); + rlmFillVhtOpInfoByBssOpBw( + prBssInfo, + prBssInfo + ->ucOpChangeChannelWidth); + } + + fgHasWideBandIE = TRUE; + break; + + case ELEM_ID_CH_SW_ANNOUNCEMENT: + if (IE_LEN(pucIE) != + (sizeof(struct IE_CHANNEL_SWITCH) - 2)) { + DBGLOG(RLM, INFO, + "[Mgt Action] ELEM_ID_CH_SW_ANNOUNCEMENT, Length\n"); + break; + } + + prChannelSwitchAnnounceIE = + (struct IE_CHANNEL_SWITCH *)pucIE; + + if (prChannelSwitchAnnounceIE + ->ucChannelSwitchMode == 1) { + + /* Need to stop data + * transmission immediately + */ + if (!g_fgHasStopTx) { + g_fgHasStopTx = TRUE; + /* AP */ + qmSetStaRecTxAllowed(prAdapter, + prStaRec, + FALSE); + DBGLOG(RLM, EVENT, + "[Ch] TxAllowed = FALSE\n"); + } + + if (prChannelSwitchAnnounceIE + ->ucChannelSwitchCount <= 5) { + DBGLOG(RLM, INFO, + "[Mgt Action] switch channel [%d]->[%d]\n", + prBssInfo->ucPrimaryChannel, + prChannelSwitchAnnounceIE + ->ucNewChannelNum); + prBssInfo->ucPrimaryChannel = + prChannelSwitchAnnounceIE + ->ucNewChannelNum; + prBssInfo->eBand = + (prBssInfo + ->ucPrimaryChannel + <= 14) ? BAND_2G4 : + BAND_5G; + } + } else { + DBGLOG(RLM, INFO, + "[Mgt Action] ucChannelSwitchMode = 0\n"); + } + + fgHasChannelSwitchIE = TRUE; + break; + case ELEM_ID_SCO: + if (IE_LEN(pucIE) != + (sizeof(struct IE_SECONDARY_OFFSET) - 2)) { + DBGLOG(RLM, INFO, + "[Mgt Action] ELEM_ID_SCO, Length\n"); + break; + } + prSecondaryOffsetIE = + (struct IE_SECONDARY_OFFSET *)pucIE; + DBGLOG(RLM, INFO, + "[Mgt Action] SCO [%d]->[%d]\n", + prBssInfo->eBssSCO, + prSecondaryOffsetIE->ucSecondaryOffset); + prBssInfo->eBssSCO = + prSecondaryOffsetIE->ucSecondaryOffset; + fgHasSCOIE = TRUE; + break; + default: + break; + } /*end of switch IE_ID */ + } /*end of IE_FOR_EACH */ + if (fgHasChannelSwitchIE != FALSE) { + struct BSS_DESC *prBssDesc; + struct PARAM_SSID rSsid; + + COPY_SSID(rSsid.aucSsid, rSsid.u4SsidLen, + prBssInfo->aucSSID, prBssInfo->ucSSIDLen); + prBssDesc = scanSearchBssDescByBssidAndSsid( + prAdapter, prBssInfo->aucBSSID, TRUE, &rSsid); + + if (fgHasWideBandIE == FALSE) { + prBssInfo->ucVhtChannelWidth = 0; + prBssInfo->ucVhtChannelFrequencyS1 = + prBssInfo->ucPrimaryChannel; + prBssInfo->ucVhtChannelFrequencyS2 = 0; + } + if (fgHasSCOIE == FALSE) + prBssInfo->eBssSCO = CHNL_EXT_SCN; + + /* Check SAP channel */ + p2pFuncSwitchSapChannel(prAdapter); + if (prBssDesc) { + prBssDesc->ucChannelNum = + prBssInfo->ucPrimaryChannel; + prBssDesc->eChannelWidth = + prBssInfo->ucVhtChannelWidth; + prBssDesc->ucCenterFreqS1 = prBssInfo-> + ucVhtChannelFrequencyS1; + prBssDesc->ucCenterFreqS2 = prBssInfo-> + ucVhtChannelFrequencyS2; + } else { + DBGLOG(RLM, WARN, + "[Mgt Action] BssDesc is not found!\n"); + } + } + nicUpdateBss(prAdapter, prBssInfo->ucBssIndex); + break; + default: + break; + } +} + +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Send OpMode Norification frame (VHT action frame) + * + * \param[in] ucChannelWidth 0:20MHz, 1:40MHz, 2:80MHz, 3:160MHz or 80+80MHz + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +uint32_t rlmSendOpModeNotificationFrame(struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + uint8_t ucChannelWidth, uint8_t ucOpRxNss) +{ + + struct MSDU_INFO *prMsduInfo; + struct ACTION_OP_MODE_NOTIFICATION_FRAME *prTxFrame; + struct BSS_INFO *prBssInfo; + uint16_t u2EstimatedFrameLen; + PFN_TX_DONE_HANDLER pfTxDoneHandler = (PFN_TX_DONE_HANDLER)NULL; + + /* Sanity Check */ + if (!prStaRec) + return WLAN_STATUS_FAILURE; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex); + if (!prBssInfo) + return WLAN_STATUS_FAILURE; + + /* Calculate MSDU buffer length */ + u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + + sizeof(struct ACTION_OP_MODE_NOTIFICATION_FRAME); + + /* Alloc MSDU_INFO */ + prMsduInfo = (struct MSDU_INFO *)cnmMgtPktAlloc(prAdapter, + u2EstimatedFrameLen); + + if (!prMsduInfo) + return WLAN_STATUS_FAILURE; + + kalMemZero(prMsduInfo->prPacket, u2EstimatedFrameLen); + + prTxFrame = prMsduInfo->prPacket; + + /* Fill frame ctrl */ + prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; + + COPY_MAC_ADDR(prTxFrame->aucDestAddr, prStaRec->aucMacAddr); + COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); + COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); + + /* 3 Compose the frame body's frame */ + prTxFrame->ucCategory = CATEGORY_VHT_ACTION; + prTxFrame->ucAction = ACTION_OPERATING_MODE_NOTIFICATION; + + prTxFrame->ucOperatingMode |= + (ucChannelWidth & VHT_OP_MODE_CHANNEL_WIDTH); + + if (ucOpRxNss == 0) + ucOpRxNss = 1; + prTxFrame->ucOperatingMode |= + (((ucOpRxNss - 1) << 4) & VHT_OP_MODE_RX_NSS); + prTxFrame->ucOperatingMode &= ~VHT_OP_MODE_RX_NSS_TYPE; + + if (prBssInfo->pfOpChangeHandler) + pfTxDoneHandler = rlmNotifyVhtOpModeTxDone; + + /* 4 Update information of MSDU_INFO_T */ + TX_SET_MMPDU(prAdapter, prMsduInfo, prBssInfo->ucBssIndex, + prStaRec->ucIndex, WLAN_MAC_MGMT_HEADER_LEN, + sizeof(struct ACTION_OP_MODE_NOTIFICATION_FRAME), + pfTxDoneHandler, MSDU_RATE_MODE_AUTO); + + /* 4 Enqueue the frame to send this action frame. */ + nicTxEnqueueMsdu(prAdapter, prMsduInfo); + + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Send SM Power Save frame (HT action frame) + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +uint32_t rlmSendSmPowerSaveFrame(struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, uint8_t ucOpRxNss) +{ + struct MSDU_INFO *prMsduInfo; + struct ACTION_SM_POWER_SAVE_FRAME *prTxFrame; + struct BSS_INFO *prBssInfo; + uint16_t u2EstimatedFrameLen; + PFN_TX_DONE_HANDLER pfTxDoneHandler = (PFN_TX_DONE_HANDLER)NULL; + + /* Sanity Check */ + if (!prStaRec) + return WLAN_STATUS_FAILURE; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex); + if (!prBssInfo) + return WLAN_STATUS_FAILURE; + + /* Calculate MSDU buffer length */ + u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + + sizeof(struct ACTION_SM_POWER_SAVE_FRAME); + + /* Alloc MSDU_INFO */ + prMsduInfo = (struct MSDU_INFO *)cnmMgtPktAlloc(prAdapter, + u2EstimatedFrameLen); + + if (!prMsduInfo) + return WLAN_STATUS_FAILURE; + + kalMemZero(prMsduInfo->prPacket, u2EstimatedFrameLen); + + prTxFrame = prMsduInfo->prPacket; + + /* Fill frame ctrl */ + prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; + + COPY_MAC_ADDR(prTxFrame->aucDestAddr, prStaRec->aucMacAddr); + COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); + COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); + + /* 3 Compose the frame body's frame */ + prTxFrame->ucCategory = CATEGORY_HT_ACTION; + prTxFrame->ucAction = ACTION_HT_SM_POWER_SAVE; + + if (ucOpRxNss == 1) + prTxFrame->ucSmPowerCtrl |= HT_SM_POWER_SAVE_CONTROL_ENABLED; + else if (ucOpRxNss == 2) + prTxFrame->ucSmPowerCtrl &= ~HT_SM_POWER_SAVE_CONTROL_ENABLED; + else { + DBGLOG(RLM, WARN, + "Can't switch to RxNss = %d since we don't support.\n", + ucOpRxNss); + return WLAN_STATUS_FAILURE; + } + + /* Static SM power save mode */ + prTxFrame->ucSmPowerCtrl &= + (~HT_SM_POWER_SAVE_CONTROL_SM_MODE); + + if (prBssInfo->pfOpChangeHandler) + pfTxDoneHandler = rlmSmPowerSaveTxDone; + + /* 4 Update information of MSDU_INFO_T */ + TX_SET_MMPDU(prAdapter, prMsduInfo, prBssInfo->ucBssIndex, + prStaRec->ucIndex, WLAN_MAC_MGMT_HEADER_LEN, + sizeof(struct ACTION_SM_POWER_SAVE_FRAME), pfTxDoneHandler, + MSDU_RATE_MODE_AUTO); + + /* 4 Enqueue the frame to send this action frame. */ + nicTxEnqueueMsdu(prAdapter, prMsduInfo); + + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Send Notify Channel Width frame (HT action frame) + * + * \param[in] ucChannelWidth 0:20MHz, 1:Any channel width + * in the STAs Supported Channel Width Set subfield + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +uint32_t rlmSendNotifyChannelWidthFrame(struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + uint8_t ucChannelWidth) +{ + struct MSDU_INFO *prMsduInfo; + struct ACTION_NOTIFY_CHANNEL_WIDTH_FRAME *prTxFrame; + struct BSS_INFO *prBssInfo; + uint16_t u2EstimatedFrameLen; + PFN_TX_DONE_HANDLER pfTxDoneHandler = (PFN_TX_DONE_HANDLER)NULL; + + /* Sanity Check */ + if (!prStaRec) + return WLAN_STATUS_FAILURE; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex); + if (!prBssInfo) + return WLAN_STATUS_FAILURE; + + /* Calculate MSDU buffer length */ + u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + + sizeof(struct ACTION_NOTIFY_CHANNEL_WIDTH_FRAME); + + /* Alloc MSDU_INFO */ + prMsduInfo = (struct MSDU_INFO *)cnmMgtPktAlloc(prAdapter, + u2EstimatedFrameLen); + + if (!prMsduInfo) + return WLAN_STATUS_FAILURE; + + kalMemZero(prMsduInfo->prPacket, u2EstimatedFrameLen); + + prTxFrame = prMsduInfo->prPacket; + + /* Fill frame ctrl */ + prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; + + COPY_MAC_ADDR(prTxFrame->aucDestAddr, prStaRec->aucMacAddr); + COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); + COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); + + /* 3 Compose the frame body's frame */ + prTxFrame->ucCategory = CATEGORY_HT_ACTION; + prTxFrame->ucAction = ACTION_HT_NOTIFY_CHANNEL_WIDTH; + + prTxFrame->ucChannelWidth = ucChannelWidth; + + if (prBssInfo->pfOpChangeHandler) + pfTxDoneHandler = rlmNotifyChannelWidthtTxDone; + + /* 4 Update information of MSDU_INFO_T */ + TX_SET_MMPDU(prAdapter, prMsduInfo, prBssInfo->ucBssIndex, + prStaRec->ucIndex, WLAN_MAC_MGMT_HEADER_LEN, + sizeof(struct ACTION_NOTIFY_CHANNEL_WIDTH_FRAME), + pfTxDoneHandler, MSDU_RATE_MODE_AUTO); + + /* 4 Enqueue the frame to send this action frame. */ + nicTxEnqueueMsdu(prAdapter, prMsduInfo); + + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + * + */ +/*----------------------------------------------------------------------------*/ +uint32_t rlmNotifyVhtOpModeTxDone(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN enum ENUM_TX_RESULT_CODE rTxDoneStatus) +{ + u_int8_t fgIsSuccess = FALSE; + + do { + ASSERT((prAdapter != NULL) && (prMsduInfo != NULL)); + + if (rTxDoneStatus == TX_RESULT_SUCCESS) + fgIsSuccess = TRUE; + + } while (FALSE); + + rlmOpModeTxDoneHandler(prAdapter, prMsduInfo, OP_NOTIFY_TYPE_VHT_NSS_BW, + fgIsSuccess); + + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +uint32_t rlmSmPowerSaveTxDone(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN enum ENUM_TX_RESULT_CODE rTxDoneStatus) +{ + u_int8_t fgIsSuccess = FALSE; + + do { + ASSERT((prAdapter != NULL) && (prMsduInfo != NULL)); + + if (rTxDoneStatus == TX_RESULT_SUCCESS) + fgIsSuccess = TRUE; + + } while (FALSE); + + rlmOpModeTxDoneHandler(prAdapter, prMsduInfo, OP_NOTIFY_TYPE_HT_NSS, + fgIsSuccess); + + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +uint32_t rlmNotifyChannelWidthtTxDone(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN enum ENUM_TX_RESULT_CODE rTxDoneStatus) +{ + u_int8_t fgIsSuccess = FALSE; + + do { + ASSERT((prAdapter != NULL) && (prMsduInfo != NULL)); + + if (rTxDoneStatus == TX_RESULT_SUCCESS) + fgIsSuccess = TRUE; + + } while (FALSE); + + rlmOpModeTxDoneHandler(prAdapter, prMsduInfo, OP_NOTIFY_TYPE_HT_BW, + fgIsSuccess); + + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Handle TX done for OP mode noritfication frame + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +static void rlmOpModeTxDoneHandler(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN uint8_t ucOpChangeType, + IN u_int8_t fgIsSuccess) +{ + uint32_t u4Status = WLAN_STATUS_SUCCESS; + struct BSS_INFO *prBssInfo = NULL; + struct STA_RECORD *prStaRec = NULL; + u_int8_t fgIsOpModeChangeSuccess = FALSE; /* OP change result */ + uint8_t ucRelatedFrameType = + OP_NOTIFY_TYPE_NUM; /* Used for HT notification frame */ + /* Used for HT notification frame */ + uint8_t *pucCurrOpState = NULL; + uint8_t *pucRelatedOpState = NULL; + + /* Sanity check */ + ASSERT((prAdapter != NULL) && (prMsduInfo != NULL)); + + prBssInfo = prAdapter->aprBssInfo[prMsduInfo->ucBssIndex]; + + ASSERT(prBssInfo); + + prStaRec = prBssInfo->prStaRecOfAP; + + DBGLOG(RLM, INFO, + "OP notification Tx done: BSS[%d] Type[%d] Status[%d] IsSuccess[%d]\n", + prBssInfo->ucBssIndex, ucOpChangeType, + prBssInfo->aucOpModeChangeState[ucOpChangeType], fgIsSuccess); + + do { + /* <1>handle abnormal case */ + if ((prBssInfo->aucOpModeChangeState[ucOpChangeType] != + OP_NOTIFY_STATE_KEEP) && + (prBssInfo->aucOpModeChangeState[ucOpChangeType] != + OP_NOTIFY_STATE_SENDING)) { + DBGLOG(RLM, WARN, + "Unexpected BSS[%d] OpModeChangeState[%d]\n", + prBssInfo->ucBssIndex, + prBssInfo->aucOpModeChangeState[ucOpChangeType]); + rlmRollbackOpChangeParam(prBssInfo, TRUE, TRUE); + fgIsOpModeChangeSuccess = FALSE; + break; + } + + if (ucOpChangeType >= OP_NOTIFY_TYPE_NUM) { + DBGLOG(RLM, WARN, + "Uxexpected Bss[%d] OpChangeType[%d]\n", + prMsduInfo->ucBssIndex, ucOpChangeType); + rlmRollbackOpChangeParam(prBssInfo, TRUE, TRUE); + fgIsOpModeChangeSuccess = FALSE; + break; + } + + pucCurrOpState = &prBssInfo + ->aucOpModeChangeState[ucOpChangeType]; + + /* <2>Assign Op notification Type/State for HT notification + * frame + */ + if ((ucOpChangeType == OP_NOTIFY_TYPE_HT_BW) || + (ucOpChangeType == OP_NOTIFY_TYPE_HT_NSS)) { + + ucRelatedFrameType = + (ucOpChangeType == OP_NOTIFY_TYPE_HT_BW) + ? OP_NOTIFY_TYPE_HT_NSS + : OP_NOTIFY_TYPE_HT_BW; + + pucRelatedOpState = &prBssInfo + ->aucOpModeChangeState[ucRelatedFrameType]; + } + + /* <3.1>handle TX done - SUCCESS */ + if (fgIsSuccess == TRUE) { + + /* Clear retry count */ + prBssInfo->aucOpModeChangeRetryCnt[ucOpChangeType] = 0; + + if (ucOpChangeType == OP_NOTIFY_TYPE_VHT_NSS_BW) { + *pucCurrOpState = OP_NOTIFY_STATE_SUCCESS; + + if (prBssInfo->aucOpModeChangeState + [OP_NOTIFY_TYPE_HT_BW] == + OP_NOTIFY_STATE_SENDING || + prBssInfo->aucOpModeChangeState + [OP_NOTIFY_TYPE_HT_NSS] == + OP_NOTIFY_STATE_SENDING) { + /* Wait for HT BW/Nss notification + * frames Tx done + */ + return; + } + + /* VHT notification frame sent */ + fgIsOpModeChangeSuccess = TRUE; + break; + } + + /* HT notification frame sent */ + if (*pucCurrOpState == + OP_NOTIFY_STATE_SENDING) { /* Change OpMode */ + *pucCurrOpState = OP_NOTIFY_STATE_SUCCESS; + + /* Case1: Wait for VHT notification frame & + * HT BW/Nss notification frame TX done + */ + if (*pucRelatedOpState == + OP_NOTIFY_STATE_SENDING || + prBssInfo->aucOpModeChangeState + [OP_NOTIFY_TYPE_VHT_NSS_BW] == + OP_NOTIFY_STATE_SENDING) + return; + + /* Case2: Both BW and Nss notification TX done + * or only change either BW or Nss + */ + if ((*pucRelatedOpState == + OP_NOTIFY_STATE_KEEP) || + (*pucRelatedOpState == + OP_NOTIFY_STATE_SUCCESS)) { + fgIsOpModeChangeSuccess = TRUE; + + /* Case3: One of the notification TX + * failed, + * re-send a notification frame to + * rollback the successful one + */ + } else if (*pucRelatedOpState == + OP_NOTIFY_STATE_FAIL) { + /*Rollback to keep the original BW/Nss + */ + *pucCurrOpState = OP_NOTIFY_STATE_KEEP; + if (ucOpChangeType == + OP_NOTIFY_TYPE_HT_BW) + u4Status = + rlmSendNotifyChannelWidthFrame( + prAdapter, prStaRec, + rlmGetBssOpBwByVhtAndHtOpInfo( + prBssInfo)); + else if (ucOpChangeType == + OP_NOTIFY_TYPE_HT_NSS) + u4Status = + rlmSendSmPowerSaveFrame( + prAdapter, prStaRec, + prBssInfo->ucOpRxNss); + + DBGLOG(RLM, INFO, + "Bss[%d] OpType[%d] Tx Failed, send OpType", + prMsduInfo->ucBssIndex, + ucRelatedFrameType); + DBGLOG(RLM, INFO, + "[%d] for roll back to BW[%d] RxNss[%d]\n", + ucOpChangeType, + rlmGetBssOpBwByVhtAndHtOpInfo + (prBssInfo), + prBssInfo->ucOpRxNss); + + if (u4Status == WLAN_STATUS_SUCCESS) + return; + } + } else if (*pucCurrOpState == + OP_NOTIFY_STATE_KEEP) { /* Rollback OpMode */ + + /* Case4: Rollback success, keep original OP + * BW/Nss + */ + if (ucOpChangeType == OP_NOTIFY_TYPE_HT_BW) + rlmRollbackOpChangeParam(prBssInfo, + TRUE, FALSE); + else if (ucOpChangeType == + OP_NOTIFY_TYPE_HT_NSS) + rlmRollbackOpChangeParam(prBssInfo, + FALSE, TRUE); + + fgIsOpModeChangeSuccess = FALSE; + } + } /* End of processing TX success */ + /* <3.2>handle TX done - FAIL */ + else { + prBssInfo->aucOpModeChangeRetryCnt[ucOpChangeType]++; + + /* Re-send notification frame */ + if (prBssInfo + ->aucOpModeChangeRetryCnt[ucOpChangeType] <= + OPERATION_NOTICATION_TX_LIMIT) { + if (ucOpChangeType == OP_NOTIFY_TYPE_VHT_NSS_BW) + u4Status = + rlmSendOpModeNotificationFrame( + prAdapter, prStaRec, + prBssInfo->ucOpChangeChannelWidth, + prBssInfo->ucOpChangeRxNss); + else if (ucOpChangeType == + OP_NOTIFY_TYPE_HT_NSS) + u4Status = rlmSendSmPowerSaveFrame( + prAdapter, prStaRec, + prBssInfo->ucOpChangeRxNss); + else if (ucOpChangeType == OP_NOTIFY_TYPE_HT_BW) + u4Status = + rlmSendNotifyChannelWidthFrame( + prAdapter, prStaRec, + prBssInfo + ->ucOpChangeChannelWidth); + + if (u4Status == WLAN_STATUS_SUCCESS) + return; + } + + /* Clear retry count when retry count > TX limit */ + prBssInfo->aucOpModeChangeRetryCnt[ucOpChangeType] = 0; + + /* VHT notification frame sent */ + if (ucOpChangeType == + OP_NOTIFY_TYPE_VHT_NSS_BW) { + *pucCurrOpState = OP_NOTIFY_STATE_FAIL; + + /* Change failed, keep original OP BW/Nss */ + rlmRollbackOpChangeParam(prBssInfo, TRUE, TRUE); + fgIsOpModeChangeSuccess = FALSE; + break; + } + + /* HT notification frame sent */ + if (*pucCurrOpState == + OP_NOTIFY_STATE_SENDING) { /* Change OpMode */ + *pucCurrOpState = OP_NOTIFY_STATE_FAIL; + + /* Change failed, keep original OP BW/Nss */ + if (ucOpChangeType == OP_NOTIFY_TYPE_HT_BW) + rlmRollbackOpChangeParam(prBssInfo, + TRUE, FALSE); + else if (ucOpChangeType == + OP_NOTIFY_TYPE_HT_NSS) + rlmRollbackOpChangeParam(prBssInfo, + FALSE, TRUE); + + /* Case1: Wait for both HT BW/Nss notification + * frame TX done + */ + if (*pucRelatedOpState == + OP_NOTIFY_STATE_SENDING) { + return; + + /* Case2: Both BW and Nss notification + * TX done + * or only change either BW or Nss + */ + } else if ((*pucRelatedOpState == + OP_NOTIFY_STATE_KEEP) || + (*pucRelatedOpState == + OP_NOTIFY_STATE_FAIL)) { + fgIsOpModeChangeSuccess = FALSE; + + /* Case3: One of the notification TX + * failed, + * re-send a notification frame to + * rollback the successful one + */ + } else if (*pucRelatedOpState == + OP_NOTIFY_STATE_SUCCESS) { + /*Rollback to keep the original BW/Nss + */ + *pucRelatedOpState = + OP_NOTIFY_STATE_KEEP; + + if (ucRelatedFrameType == + OP_NOTIFY_TYPE_HT_BW) { + u4Status = + rlmSendNotifyChannelWidthFrame( + prAdapter, prStaRec, + rlmGetBssOpBwByVhtAndHtOpInfo( + prBssInfo)); + } else if (ucRelatedFrameType == + OP_NOTIFY_TYPE_HT_NSS) + u4Status = + rlmSendSmPowerSaveFrame( + prAdapter, prStaRec, + prBssInfo->ucOpRxNss); + + DBGLOG(RLM, INFO, + "Bss[%d] OpType[%d] Tx Failed, send a OpType[%d] for roll back to BW[%d] RxNss[%d]\n", + prMsduInfo->ucBssIndex, + ucOpChangeType, + ucRelatedFrameType, + rlmGetBssOpBwByVhtAndHtOpInfo( + prBssInfo), + prBssInfo->ucOpRxNss); + + if (u4Status == WLAN_STATUS_SUCCESS) + return; + } + } else if (*pucCurrOpState == + OP_NOTIFY_STATE_KEEP) /* Rollback OpMode */ + /* Case4: Rollback failed, keep changing OP + * BW/Nss + */ + fgIsOpModeChangeSuccess = FALSE; + } /* End of processing TX failed */ + + } while (FALSE); + + /* <4>Change own OP info */ + rlmCompleteOpModeChange(prAdapter, prBssInfo, fgIsOpModeChangeSuccess); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +static void rlmRollbackOpChangeParam(struct BSS_INFO *prBssInfo, + u_int8_t fgIsRollbackBw, + u_int8_t fgIsRollbackNss) +{ + + ASSERT(prBssInfo); + + if (fgIsRollbackBw == TRUE) { + prBssInfo->fgIsOpChangeChannelWidth = FALSE; + prBssInfo->ucOpChangeChannelWidth = + rlmGetBssOpBwByVhtAndHtOpInfo(prBssInfo); + } + + if (fgIsRollbackNss == TRUE) { + prBssInfo->fgIsOpChangeRxNss = FALSE; + prBssInfo->fgIsOpChangeTxNss = FALSE; + prBssInfo->ucOpChangeRxNss = prBssInfo->ucOpRxNss; + prBssInfo->ucOpChangeTxNss = prBssInfo->ucOpTxNss; + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Get BSS operating channel width by VHT and HT OP Info + * + * \param[in] + * + * \return ucBssOpBw 0:20MHz, 1:40MHz, 2:80MHz, 3:160MHz 4:80+80MHz + * + */ +/*----------------------------------------------------------------------------*/ +uint8_t rlmGetBssOpBwByVhtAndHtOpInfo(struct BSS_INFO *prBssInfo) +{ + + uint8_t ucBssOpBw = MAX_BW_20MHZ; + + ASSERT(prBssInfo); + + switch (prBssInfo->ucVhtChannelWidth) { + case VHT_OP_CHANNEL_WIDTH_80P80: + ucBssOpBw = MAX_BW_80_80_MHZ; + break; + + case VHT_OP_CHANNEL_WIDTH_160: + ucBssOpBw = MAX_BW_160MHZ; + break; + + case VHT_OP_CHANNEL_WIDTH_80: + ucBssOpBw = MAX_BW_80MHZ; + break; + + case VHT_OP_CHANNEL_WIDTH_20_40: + if (prBssInfo->eBssSCO != CHNL_EXT_SCN) + ucBssOpBw = MAX_BW_40MHZ; + break; + default: + DBGLOG(RLM, WARN, "%s: unexpected VHT channel width: %d\n", + __func__, prBssInfo->ucVhtChannelWidth); +#if CFG_SUPPORT_802_11AC + if (RLM_NET_IS_11AC(prBssInfo)) + /*VHT default should support BW 80*/ + ucBssOpBw = MAX_BW_80MHZ; +#endif + break; + } + + return ucBssOpBw; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return ucVhtOpBw 0:20M/40Hz, 1:80MHz, 2:160MHz, 3:80+80MHz + * + */ +/*----------------------------------------------------------------------------*/ +uint8_t rlmGetVhtOpBwByBssOpBw(uint8_t ucBssOpBw) +{ + uint8_t ucVhtOpBw = + VHT_OP_CHANNEL_WIDTH_80; /*VHT default should support BW 80*/ + + switch (ucBssOpBw) { + case MAX_BW_20MHZ: + case MAX_BW_40MHZ: + ucVhtOpBw = VHT_OP_CHANNEL_WIDTH_20_40; + break; + + case MAX_BW_80MHZ: + ucVhtOpBw = VHT_OP_CHANNEL_WIDTH_80; + break; + + case MAX_BW_160MHZ: + ucVhtOpBw = VHT_OP_CHANNEL_WIDTH_160; + break; + + case MAX_BW_80_80_MHZ: + ucVhtOpBw = VHT_OP_CHANNEL_WIDTH_80P80; + break; + default: + DBGLOG(RLM, WARN, "%s: unexpected Bss OP BW: %d\n", __func__, + ucBssOpBw); + break; + } + + return ucVhtOpBw; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Get operating notification channel width by VHT and HT operating Info + * + * \param[in] + * + * \return ucOpModeBw 0:20MHz, 1:40MHz, 2:80MHz, 3:160MHz/80+80MHz + * + */ +/*----------------------------------------------------------------------------*/ +static uint8_t rlmGetOpModeBwByVhtAndHtOpInfo(struct BSS_INFO *prBssInfo) +{ + uint8_t ucOpModeBw = VHT_OP_MODE_CHANNEL_WIDTH_20; + + ASSERT(prBssInfo); + + switch (prBssInfo->ucVhtChannelWidth) { + case VHT_OP_CHANNEL_WIDTH_20_40: + if (prBssInfo->eBssSCO != CHNL_EXT_SCN) + ucOpModeBw = VHT_OP_MODE_CHANNEL_WIDTH_40; + break; + case VHT_OP_CHANNEL_WIDTH_80: + ucOpModeBw = VHT_OP_MODE_CHANNEL_WIDTH_80; + break; + case VHT_OP_CHANNEL_WIDTH_160: + case VHT_OP_CHANNEL_WIDTH_80P80: + ucOpModeBw = VHT_OP_MODE_CHANNEL_WIDTH_160_80P80; + break; + default: + DBGLOG(RLM, WARN, "%s: unexpected VHT channel width: %d\n", + __func__, prBssInfo->ucVhtChannelWidth); + /*VHT default IE should support BW 80*/ + ucOpModeBw = VHT_OP_MODE_CHANNEL_WIDTH_80; + break; + } + + return ucOpModeBw; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +static void rlmChangeOwnOpInfo(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo) +{ + struct STA_RECORD *prStaRec; + + ASSERT((prAdapter != NULL) && (prBssInfo != NULL)); + + /* Update own operating channel Width */ + if (prBssInfo->fgIsOpChangeChannelWidth) { + if (prBssInfo->ucPhyTypeSet & PHY_TYPE_BIT_HT) { +#if CFG_SUPPORT_802_11AC + /* Update VHT OP Info*/ + if (prBssInfo->ucPhyTypeSet & PHY_TYPE_BIT_VHT) { + rlmFillVhtOpInfoByBssOpBw( + prBssInfo, + prBssInfo->ucOpChangeChannelWidth); + + DBGLOG(RLM, INFO, + "Update BSS[%d] VHT Channel Width Info to w=%d s1=%d s2=%d\n", + prBssInfo->ucBssIndex, + prBssInfo->ucVhtChannelWidth, + prBssInfo->ucVhtChannelFrequencyS1, + prBssInfo->ucVhtChannelFrequencyS2); + } +#endif + + /* Update HT OP Info*/ + if (prBssInfo->ucOpChangeChannelWidth == MAX_BW_20MHZ) { + prBssInfo->ucHtOpInfo1 &= + ~HT_OP_INFO1_STA_CHNL_WIDTH; + prBssInfo->eBssSCO = CHNL_EXT_SCN; + } else { + prBssInfo->ucHtOpInfo1 |= + HT_OP_INFO1_STA_CHNL_WIDTH; + + if (prBssInfo->eCurrentOPMode == + OP_MODE_INFRASTRUCTURE) { + prStaRec = prBssInfo->prStaRecOfAP; + if (!prStaRec) + return; + + if ((prStaRec->ucHtPeerOpInfo1 & + HT_OP_INFO1_SCO) != CHNL_EXT_RES) + prBssInfo->eBssSCO = + (enum ENUM_CHNL_EXT)( + prStaRec->ucHtPeerOpInfo1 & + HT_OP_INFO1_SCO); + } else if (prBssInfo->eCurrentOPMode == + OP_MODE_ACCESS_POINT) { + prBssInfo->eBssSCO = rlmDecideScoForAP( + prAdapter, prBssInfo); + } + } + + DBGLOG(RLM, INFO, + "Update BSS[%d] HT Channel Width Info to bw=%d sco=%d\n", + prBssInfo->ucBssIndex, + (uint8_t)((prBssInfo->ucHtOpInfo1 & + HT_OP_INFO1_STA_CHNL_WIDTH) >> + HT_OP_INFO1_STA_CHNL_WIDTH_OFFSET), + prBssInfo->eBssSCO); + } + } + + /* Update own operating RxNss */ + if (prBssInfo->fgIsOpChangeRxNss) { + prBssInfo->ucOpRxNss = prBssInfo->ucOpChangeRxNss; + DBGLOG(RLM, INFO, "Update OP RxNss[%d]\n", + prBssInfo->ucOpRxNss); + } + + /* Update own operating TxNss */ + if (prBssInfo->fgIsOpChangeTxNss) { + prBssInfo->ucOpTxNss = prBssInfo->ucOpChangeTxNss; + DBGLOG(RLM, INFO, "Update OP TxNss[%d]\n", + prBssInfo->ucOpTxNss); + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +static void rlmCompleteOpModeChange(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, + u_int8_t fgIsSuccess) +{ + PFN_OPMODE_NOTIFY_DONE_FUNC pfnCallback; + + ASSERT((prAdapter != NULL) && (prBssInfo != NULL)); + + if ((prBssInfo->fgIsOpChangeChannelWidth) || + (prBssInfo->fgIsOpChangeRxNss) || + (prBssInfo->fgIsOpChangeTxNss)) { + + /* <1> Update own OP BW/Nss */ + rlmChangeOwnOpInfo(prAdapter, prBssInfo); + + /* <2> Update OP BW/Nss to FW */ + rlmSyncOperationParams(prAdapter, prBssInfo); + + /* <3> Update BCN/Probe Resp IE to notify peers our OP info is + * changed (AP mode) + */ + if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) + bssUpdateBeaconContent(prAdapter, + prBssInfo->ucBssIndex); + } + + DBGLOG(RLM, INFO, + "Complete BSS[%d] OP Mode change to BW[%d] RxNss[%d] TxNss[%d]", + prBssInfo->ucBssIndex, + rlmGetBssOpBwByVhtAndHtOpInfo(prBssInfo), + prBssInfo->ucOpRxNss, + prBssInfo->ucOpTxNss); + + /* <4> Tell OpMode change caller the change result + * Allow callback function re-trigger OpModeChange immediately. + */ + pfnCallback = prBssInfo->pfOpChangeHandler; + prBssInfo->pfOpChangeHandler = NULL; + if (pfnCallback) + pfnCallback(prAdapter, prBssInfo->ucBssIndex, + fgIsSuccess); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Change OpMode Nss/Channel Width + * + * \param[in] ucChannelWidth 0:20MHz, 1:40MHz, 2:80MHz, 3:160MHz 4:80+80MHz + * + * \return fgIsChangeOpMode + * TRUE: Can change/Don't need to change operation mode + * FALSE: Can't change operation mode + */ +/*----------------------------------------------------------------------------*/ +enum ENUM_OP_CHANGE_STATUS_T +rlmChangeOperationMode( + struct ADAPTER *prAdapter, uint8_t ucBssIndex, + uint8_t ucChannelWidth, uint8_t ucOpRxNss, uint8_t ucOpTxNss, + #if CFG_SUPPORT_SMART_GEAR + uint8_t eNewReq, + #endif + PFN_OPMODE_NOTIFY_DONE_FUNC pfOpChangeHandler + ) +{ + struct BSS_INFO *prBssInfo; + struct STA_RECORD *prStaRec = (struct STA_RECORD *)NULL; + u_int8_t fgIsChangeBw = TRUE, + fgIsChangeRxNss = TRUE, /* Indicate if need to change */ + fgIsChangeTxNss = TRUE; + uint8_t i; + uint32_t u4Status = WLAN_STATUS_SUCCESS; + + /* Sanity check */ + if (ucBssIndex >= prAdapter->ucHwBssIdNum) + return OP_CHANGE_STATUS_INVALID; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + + if (!prBssInfo) + return OP_CHANGE_STATUS_INVALID; + + /* <1>Check if OP change parameter is valid */ + if (rlmCheckOpChangeParamValid(prAdapter, prBssInfo, ucChannelWidth, + ucOpRxNss, ucOpTxNss) == FALSE) + return OP_CHANGE_STATUS_INVALID; + + /* <2>Check if OpMode notification is ongoing, if not, register the call + * back function + */ + if (prBssInfo->pfOpChangeHandler) { + DBGLOG(RLM, INFO, + "BSS[%d] OpMode change notification is ongoing\n", + ucBssIndex); + return OP_CHANGE_STATUS_INVALID; + } + + prBssInfo->pfOpChangeHandler = pfOpChangeHandler; + + /* <3>Check if the current operating BW/Nss is the same as the target + * one + */ + if (ucChannelWidth == rlmGetBssOpBwByVhtAndHtOpInfo(prBssInfo)) { + fgIsChangeBw = FALSE; + prBssInfo->fgIsOpChangeChannelWidth = FALSE; + } + if (ucOpRxNss == prBssInfo->ucOpRxNss) { + fgIsChangeRxNss = FALSE; + prBssInfo->fgIsOpChangeRxNss = FALSE; + } + if (ucOpTxNss == prBssInfo->ucOpTxNss) { + fgIsChangeTxNss = FALSE; + prBssInfo->fgIsOpChangeTxNss = FALSE; + } + if ((!fgIsChangeBw) && (!fgIsChangeRxNss) && (!fgIsChangeTxNss)) { + DBGLOG(RLM, INFO, + "BSS[%d] target OpMode BW[%d] RxNss[%d] TxNss[%d] No change, return\n", + ucBssIndex, ucChannelWidth, ucOpRxNss, ucOpTxNss); + rlmCompleteOpModeChange(prAdapter, prBssInfo, TRUE); + return OP_CHANGE_STATUS_VALID_NO_CHANGE; + } + + DBGLOG(RLM, INFO, + "Intend to change BSS[%d] OP Mode to BW[%d] RxNss[%d] TxNss[%d]\n", + ucBssIndex, ucChannelWidth, ucOpRxNss, ucOpTxNss); + + /* <4> Fill OP Change Info into BssInfo*/ + if (fgIsChangeBw) { + prBssInfo->ucOpChangeChannelWidth = ucChannelWidth; + prBssInfo->fgIsOpChangeChannelWidth = TRUE; + DBGLOG(RLM, INFO, "Intend to change BSS[%d] to BW[%d]\n", + ucBssIndex, ucChannelWidth); + } + if (fgIsChangeRxNss) { + prBssInfo->ucOpChangeRxNss = ucOpRxNss; + prBssInfo->fgIsOpChangeRxNss = TRUE; + DBGLOG(RLM, INFO, "Intend to change BSS[%d] to RxNss[%d]\n", + ucBssIndex, ucOpRxNss); + } + if (fgIsChangeTxNss) { + prBssInfo->ucOpChangeTxNss = ucOpTxNss; + prBssInfo->fgIsOpChangeTxNss = TRUE; + DBGLOG(RLM, INFO, "Intend to change BSS[%d] to TxNss[%d]\n", + ucBssIndex, ucOpTxNss); + } + + /* <5>Handling OP Info change for STA/GC */ + if ((prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) && + (prBssInfo->prStaRecOfAP)) { + prStaRec = prBssInfo->prStaRecOfAP; + /* <5.1>Initialize OP mode change parameters related to + * notification Tx done handler (STA mode) + */ + if (prBssInfo->pfOpChangeHandler) { + for (i = 0; i < OP_NOTIFY_TYPE_NUM; i++) { + prBssInfo->aucOpModeChangeState[i] = + OP_NOTIFY_STATE_KEEP; + prBssInfo->aucOpModeChangeRetryCnt[i] = 0; + } + } + +#if CFG_SUPPORT_SMART_GEAR + if (eNewReq != 0x04 /* CNM_OPMODE_REQ_SMARTGEAR_1T2R */) { +#endif /* <5.2> Send operating mode notification frame (STA mode) + * No action frame is needed if we only changed OpTxNss. + */ +#if CFG_SUPPORT_802_11AC + if (RLM_NET_IS_11AC(prBssInfo) && + (fgIsChangeBw || fgIsChangeRxNss)) { + if (prBssInfo->pfOpChangeHandler) + prBssInfo->aucOpModeChangeState + [OP_NOTIFY_TYPE_VHT_NSS_BW] = + OP_NOTIFY_STATE_SENDING; + DBGLOG(RLM, INFO, + "Send VHT OP notification frame: BSS[%d] BW[%d] RxNss[%d]\n", + ucBssIndex, ucChannelWidth, ucOpRxNss); + u4Status = rlmSendOpModeNotificationFrame( + prAdapter, prStaRec, + ucChannelWidth, ucOpRxNss); + } +#endif + if (RLM_NET_IS_11N(prBssInfo) && + (fgIsChangeBw || fgIsChangeRxNss)) { + if (prBssInfo->pfOpChangeHandler) { + if (fgIsChangeRxNss) + prBssInfo->aucOpModeChangeState + [OP_NOTIFY_TYPE_HT_NSS] = + OP_NOTIFY_STATE_SENDING; + if (fgIsChangeBw) + prBssInfo->aucOpModeChangeState + [OP_NOTIFY_TYPE_HT_BW] = + OP_NOTIFY_STATE_SENDING; + } + if (fgIsChangeRxNss) { + u4Status = rlmSendSmPowerSaveFrame( + prAdapter, prStaRec, ucOpRxNss); + DBGLOG(RLM, INFO, + "Send HT SM Power Save frame: "); + DBGLOG(RLM, INFO, "BSS[%d] RxNss[%d]\n", + ucBssIndex, ucOpRxNss); + } + if (fgIsChangeBw) { + u4Status = rlmSendNotifyChannelWidthFrame( + prAdapter, prStaRec, ucChannelWidth); + DBGLOG(RLM, INFO, + "Send HT Notify Channel Width frame: "); + DBGLOG(RLM, INFO, "BSS[%d] BW[%d]\n", + ucBssIndex, ucChannelWidth); + } + } +#if CFG_SUPPORT_SMART_GEAR + } +#endif + /* Error handling */ + if (u4Status != WLAN_STATUS_SUCCESS) { + rlmCompleteOpModeChange(prAdapter, prBssInfo, FALSE); + return OP_CHANGE_STATUS_INVALID; + } + + /* <5.3> Change OP Info w/o waiting for notification Tx done */ + if (prBssInfo->pfOpChangeHandler == NULL || +#if CFG_SUPPORT_SMART_GEAR + eNewReq == 0x04 /* CNM_OPMODE_REQ_SMARTGEAR_1T2R */ || +#endif + (!fgIsChangeBw && !fgIsChangeRxNss)) { + rlmCompleteOpModeChange(prAdapter, prBssInfo, TRUE); + /* No callback */ + return OP_CHANGE_STATUS_VALID_CHANGE_CALLBACK_DONE; + } + + return OP_CHANGE_STATUS_VALID_CHANGE_CALLBACK_WAIT; + } + /* <6>Handling OP Info change for AP/GO */ + else if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) { + /* Complete OP Info change after notifying client by beacon */ + rlmCompleteOpModeChange(prAdapter, prBssInfo, TRUE); + return OP_CHANGE_STATUS_VALID_CHANGE_CALLBACK_DONE; + } + + /* Complete OP mode change if no sending action frames */ + rlmCompleteOpModeChange(prAdapter, prBssInfo, TRUE); + return OP_CHANGE_STATUS_VALID_CHANGE_CALLBACK_DONE; +} + + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Check our desired BW/RxNss is less or equal than peer's capability to + * prevent IOT issue. + * + * \param[in] prBssInfo + * \param[in] ucChannelWidth + * \param[in] ucOpTxNss + * + * \return + * TRUE : Can change to desired BW/RxNss + * FALSE: Should not change operation mode + */ +/*----------------------------------------------------------------------------*/ +static u_int8_t rlmCheckOpChangeParamForClient(struct BSS_INFO *prBssInfo, + uint8_t ucChannelWidth, + uint8_t ucOpRxNss) +{ + struct STA_RECORD *prStaRec; + + prStaRec = prBssInfo->prStaRecOfAP; + + if (!prStaRec) + return FALSE; + +#if CFG_SUPPORT_802_11AC + if (RLM_NET_IS_11AC(prBssInfo)) { /* VHT */ + /* Check peer OP Channel Width */ + switch (ucChannelWidth) { + case MAX_BW_80_80_MHZ: + if (prStaRec->ucVhtOpChannelWidth != + VHT_OP_CHANNEL_WIDTH_80P80) { + DBGLOG(RLM, INFO, + "Can't change BSS[%d] OP BW to:%d for peer VHT OP BW is:%d\n", + prBssInfo->ucBssIndex, ucChannelWidth, + prStaRec->ucVhtOpChannelWidth); + return FALSE; + } + break; + case MAX_BW_160MHZ: + if (prStaRec->ucVhtOpChannelWidth != + VHT_OP_CHANNEL_WIDTH_160) { + DBGLOG(RLM, INFO, + "Can't change BSS[%d] OP BW to:%d for peer VHT OP BW is:%d\n", + prBssInfo->ucBssIndex, ucChannelWidth, + prStaRec->ucVhtOpChannelWidth); + return FALSE; + } + break; + case MAX_BW_80MHZ: + if (prStaRec->ucVhtOpChannelWidth < + VHT_OP_CHANNEL_WIDTH_80) { + DBGLOG(RLM, INFO, + "Can't change BSS[%d] OP BW to:%d for peer VHT OP BW is:%d\n", + prBssInfo->ucBssIndex, ucChannelWidth, + prStaRec->ucVhtOpChannelWidth); + return FALSE; + } + break; + case MAX_BW_40MHZ: + if (!(prStaRec->ucHtPeerOpInfo1 & + HT_OP_INFO1_STA_CHNL_WIDTH) || + (!prBssInfo->fg40mBwAllowed)) { + DBGLOG(RLM, INFO, + "Can't change BSS[%d] OP BW to:%d for PeerOpBw:%d fg40mBwAllowed:%d\n", + prBssInfo->ucBssIndex, ucChannelWidth, + (uint8_t)(prStaRec->ucHtPeerOpInfo1 & + HT_OP_INFO1_STA_CHNL_WIDTH), + prBssInfo->fg40mBwAllowed); + return FALSE; + } + break; + case MAX_BW_20MHZ: + break; + default: + DBGLOG(RLM, WARN, + "BSS[%d] target OP BW:%d is invalid for VHT OpMode change\n", + prBssInfo->ucBssIndex, ucChannelWidth); + return FALSE; + } + + /* Check peer Rx Nss Cap */ + if (ucOpRxNss == 2 && + ((prStaRec->u2VhtRxMcsMap & VHT_CAP_INFO_MCS_2SS_MASK) >> + VHT_CAP_INFO_MCS_2SS_OFFSET) == + VHT_CAP_INFO_MCS_NOT_SUPPORTED) { + DBGLOG(RLM, INFO, + "Don't change Nss since VHT peer doesn't support 2ss\n"); + return FALSE; + } + + } else +#endif + { + if (RLM_NET_IS_11N(prBssInfo)) { /* HT */ + /* Check peer Channel Width */ + if (ucChannelWidth >= MAX_BW_80MHZ) { + DBGLOG(RLM, WARN, + "BSS[%d] target OP BW:%d is invalid for HT OpMode change\n", + prBssInfo->ucBssIndex, ucChannelWidth); + return FALSE; + } else if (ucChannelWidth == + MAX_BW_40MHZ) { + if (!(prStaRec->ucHtPeerOpInfo1 & + HT_OP_INFO1_STA_CHNL_WIDTH) || + (!prBssInfo->fg40mBwAllowed)) { + DBGLOG(RLM, INFO, + "Can't change BSS[%d] OP BW to:%d for PeerOpBw:%d fg40mBwAllowed:%d\n", + prBssInfo->ucBssIndex, + ucChannelWidth, + (uint8_t)( + prStaRec->ucHtPeerOpInfo1 & + HT_OP_INFO1_STA_CHNL_WIDTH), + prBssInfo->fg40mBwAllowed); + return FALSE; + } + } + + /* Check peer Rx Nss Cap */ + if (ucOpRxNss == 2 && + (prStaRec->aucRxMcsBitmask[1] == 0)) { + DBGLOG(RLM, INFO, + "Don't change Nss since HT peer doesn't support 2ss\n"); + return FALSE; + } + } + } + return TRUE; +} + +static u_int8_t rlmCheckOpChangeParamValid(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, + uint8_t ucChannelWidth, + uint8_t ucOpRxNss, + uint8_t ucOpTxNss) +{ + uint8_t ucCapNss; + + ASSERT(prBssInfo); + + /* <1>Check if BSS PHY type is legacy mode */ + if (!RLM_NET_IS_11N(prBssInfo)) { + DBGLOG(RLM, WARN, + "Can't change BSS[%d] OP info for legacy BSS\n", + prBssInfo->ucBssIndex); + return FALSE; + } + + /* <2>Check network type */ + if ((prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) && + (prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT)) { + DBGLOG(RLM, WARN, + "Can't change BSS[%d] OP info for OpMode:%d\n", + prBssInfo->ucBssIndex, prBssInfo->eCurrentOPMode); + return FALSE; + } + + /* <3>Check if target OP BW/Nss <= Own Cap BW/Nss */ + ucCapNss = wlanGetSupportNss(prAdapter, prBssInfo->ucBssIndex); + if (ucOpRxNss > ucCapNss || ucOpRxNss == 0 || + ucOpTxNss > ucCapNss || ucOpTxNss == 0) { + DBGLOG(RLM, WARN, + "Can't change BSS[%d] OP RxNss[%d]TxNss[%d] due to CapNss[%d]\n", + prBssInfo->ucBssIndex, ucOpRxNss, ucOpTxNss, ucCapNss); + return FALSE; + } + + if (ucChannelWidth > cnmGetBssMaxBw(prAdapter, prBssInfo->ucBssIndex)) { + DBGLOG(RLM, WARN, + "Can't change BSS[%d] OP BW[%d] due to CapBW[%d]\n", + prBssInfo->ucBssIndex, ucChannelWidth, + cnmGetBssMaxBw(prAdapter, prBssInfo->ucBssIndex)); + return FALSE; + } + + /* <4>Check if target OP BW is valid for band and primary channel of + * current BSS + */ + if (prBssInfo->eBand == BAND_2G4) { + if ((ucChannelWidth != MAX_BW_20MHZ) && + (ucChannelWidth != MAX_BW_40MHZ)) { + DBGLOG(RLM, WARN, + "Can't change BSS[%d] OP BW to:%d for 2.4G\n", + prBssInfo->ucBssIndex, ucChannelWidth); + return FALSE; + } + } else { + /* It can only use BW20 for CH165 */ + if ((ucChannelWidth != MAX_BW_20MHZ) && + (prBssInfo->ucPrimaryChannel == 165)) { + DBGLOG(RLM, WARN, + "Can't change BSS[%d] OP BW to:%d for CH165\n", + prBssInfo->ucBssIndex, ucChannelWidth); + return FALSE; + } + + if ((ucChannelWidth == MAX_BW_160MHZ) && + ((prBssInfo->ucPrimaryChannel < 36) || + ((prBssInfo->ucPrimaryChannel > 64) && + (prBssInfo->ucPrimaryChannel < 100)) || + (prBssInfo->ucPrimaryChannel > 128))) { + DBGLOG(RLM, WARN, + "Can't change BSS[%d] to OP BW160 for primary CH%d\n", + prBssInfo->ucBssIndex, + prBssInfo->ucPrimaryChannel); + return FALSE; + } + } + + /* <5>Check if target OP BW/Nss <= peer's BW/Nss (STA mode) */ + if (prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) { + if (rlmCheckOpChangeParamForClient(prBssInfo, ucChannelWidth, + ucOpRxNss) == FALSE) + return FALSE; + } + + return TRUE; +} + +void rlmDummyChangeOpHandler(struct ADAPTER *prAdapter, uint8_t ucBssIndex, + bool fgIsChangeSuccess) +{ + DBGLOG(RLM, INFO, "OP change done for BSS[%d] IsSuccess[%d]\n", + ucBssIndex, fgIsChangeSuccess); +} + +void rlmSetMaxTxPwrLimit(IN struct ADAPTER *prAdapter, int8_t cLimit, + uint8_t ucEnable) +{ + struct CMD_SET_AP_CONSTRAINT_PWR_LIMIT rTxPwrLimit; + + kalMemZero(&rTxPwrLimit, sizeof(rTxPwrLimit)); + rTxPwrLimit.ucCmdVer = 0x1; + rTxPwrLimit.ucPwrSetEnable = ucEnable; + if (ucEnable) { + if (cLimit > RLM_MAX_TX_PWR) { + DBGLOG(RLM, INFO, + "LM: Target MaxPwr %d Higher than Capability, reset to capability\n", + cLimit); + cLimit = RLM_MAX_TX_PWR; + } + if (cLimit < RLM_MIN_TX_PWR) { + DBGLOG(RLM, INFO, + "LM: Target MinPwr %d Lower than Capability, reset to capability\n", + cLimit); + cLimit = RLM_MIN_TX_PWR; + } + DBGLOG(RLM, INFO, + "LM: Set Max Tx Power Limit %d, Min Limit %d\n", cLimit, + RLM_MIN_TX_PWR); + rTxPwrLimit.cMaxTxPwr = + cLimit * 2; /* unit of cMaxTxPwr is 0.5 dBm */ + rTxPwrLimit.cMinTxPwr = RLM_MIN_TX_PWR * 2; + } else + DBGLOG(RLM, TRACE, "LM: Disable Tx Power Limit\n"); + wlanSendSetQueryCmd(prAdapter, CMD_ID_SET_AP_CONSTRAINT_PWR_LIMIT, TRUE, + FALSE, FALSE, nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_SET_AP_CONSTRAINT_PWR_LIMIT), + (uint8_t *)&rTxPwrLimit, NULL, 0); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Send channel switch frame + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +uint32_t rlmSendChannelSwitchTxDone(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN enum ENUM_TX_RESULT_CODE rTxDoneStatus) +{ + do { + ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); + + DBGLOG(P2P, INFO, + "CSA TX Done Status: %d, seqNo: %d\n", + rTxDoneStatus, + prMsduInfo->ucTxSeqNum); + + } while (FALSE); + + return WLAN_STATUS_SUCCESS; +} + +void rlmSendChannelSwitchFrame(struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) +{ + struct MSDU_INFO *prMsduInfo; + struct ACTION_CHANNEL_SWITCH_FRAME *prTxFrame; + struct BSS_INFO *prBssInfo; + uint16_t u2EstimatedFrameLen; + PFN_TX_DONE_HANDLER pfTxDoneHandler = (PFN_TX_DONE_HANDLER)NULL; + uint8_t aucBMC[] = BC_MAC_ADDR; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + if (!prBssInfo) + return; + + /* Calculate MSDU buffer length */ + u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + + sizeof(struct ACTION_CHANNEL_SWITCH_FRAME); + + /* Alloc MSDU_INFO */ + prMsduInfo = (struct MSDU_INFO *)cnmMgtPktAlloc(prAdapter, + u2EstimatedFrameLen); + if (!prMsduInfo) + return; + + kalMemZero(prMsduInfo->prPacket, u2EstimatedFrameLen); + + prTxFrame = prMsduInfo->prPacket; + + /* Fill frame ctrl */ + prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; + + COPY_MAC_ADDR(prTxFrame->aucDestAddr, aucBMC); + COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); + COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); + + /* 3 Compose the frame body's frame */ + prTxFrame->ucCategory = CATEGORY_SPEC_MGT; + prTxFrame->ucAction = ACTION_CHNL_SWITCH; + + prTxFrame->aucInfoElem[0] = ELEM_ID_CH_SW_ANNOUNCEMENT; + prTxFrame->aucInfoElem[1] = 3; + prTxFrame->aucInfoElem[2] + = prAdapter->rWifiVar.ucChannelSwitchMode; + prTxFrame->aucInfoElem[3] + = prAdapter->rWifiVar.ucNewChannelNumber; + prTxFrame->aucInfoElem[4] + = prAdapter->rWifiVar.ucChannelSwitchCount; + + pfTxDoneHandler = rlmSendChannelSwitchTxDone; + + /* 4 Update information of MSDU_INFO_T */ + TX_SET_MMPDU(prAdapter, prMsduInfo, prBssInfo->ucBssIndex, + STA_REC_INDEX_BMCAST, WLAN_MAC_MGMT_HEADER_LEN, + sizeof(struct ACTION_CHANNEL_SWITCH_FRAME), + pfTxDoneHandler, + MSDU_RATE_MODE_AUTO); + + /* 4 Enqueue the frame to send this action frame. */ + nicTxEnqueueMsdu(prAdapter, prMsduInfo); +} + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/rlm_domain.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/rlm_domain.c new file mode 100644 index 0000000000000000000000000000000000000000..47d007ba34e570190dfbfa6036329fe4a0447770 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/rlm_domain.c @@ -0,0 +1,5548 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rlm_domain.c#2 + */ + +/*! \file "rlm_domain.c" + * \brief + * + */ + + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" +#include "rlm_txpwr_init.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#if CFG_SUPPORT_DYNAMIC_PWR_LIMIT +/* dynamic tx power control */ +char *g_au1TxPwrChlTypeLabel[] = { + "NORMAL", + "ALL", + "RANGE", + "2G4", + "5G", + "BANDEDGE_2G4", + "BANDEDGE_5G", + "5GBAND1", + "5GBAND2", + "5GBAND3", + "5GBAND4", +}; + +char *g_au1TxPwrAppliedWayLabel[] = { + "wifi on", + "ioctl" +}; + +char *g_au1TxPwrOperationLabel[] = { + "power level", + "power offset" +}; +#endif + +#define PWR_BUF_LEN 200 + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ +#if CFG_SUPPORT_DYNAMIC_PWR_LIMIT +/* dynamic tx power control */ +char *g_au1TxPwrDefaultSetting[] = { +#if (CFG_SUPPORT_DYNA_TX_PWR_CTRL_OFDM_SETTING == 1) + "_SAR_PwrLevel;1;2;1;[2G4,,,,,,,,,,,][5G,,,,,,,,,,,]", + "_G_Scenario;1;2;1;[ALL,,,,,,,,,,,]", + "_G_Scenario;2;2;1;[ALL,,,,,,,,,,,]", + "_G_Scenario;3;2;1;[ALL,,,,,,,,,,,]", + "_G_Scenario;4;2;1;[ALL,,,,,,,,,,,]", + "_G_Scenario;5;2;1;[ALL,,,,,,,,,,,]", +#else + "_SAR_PwrLevel;1;2;1;[2G4,,,,,,,,,][5G,,,,,,,,,]", + "_G_Scenario;1;2;1;[ALL,,,,,,,,,]", + "_G_Scenario;2;2;1;[ALL,,,,,,,,,]", + "_G_Scenario;3;2;1;[ALL,,,,,,,,,]", + "_G_Scenario;4;2;1;[ALL,,,,,,,,,]", + "_G_Scenario;5;2;1;[ALL,,,,,,,,,]", +#endif /* CFG_SUPPORT_DYNA_TX_PWR_CTRL_OFDM_SETTING */ +}; +#endif +/* The following country or domain shall be set from host driver. + * And host driver should pass specified DOMAIN_INFO_ENTRY to MT6620 as + * the channel list of being a STA to do scanning/searching AP or being an + * AP to choose an adequate channel if auto-channel is set. + */ + +/* Define mapping tables between country code and its channel set + */ +static const uint16_t g_u2CountryGroup0[] = { COUNTRY_CODE_JP }; + +static const uint16_t g_u2CountryGroup1[] = { + COUNTRY_CODE_AS, COUNTRY_CODE_AI, COUNTRY_CODE_BM, COUNTRY_CODE_KY, + COUNTRY_CODE_GU, COUNTRY_CODE_FM, COUNTRY_CODE_PR, COUNTRY_CODE_VI, + COUNTRY_CODE_AZ, COUNTRY_CODE_BW, COUNTRY_CODE_KH, COUNTRY_CODE_CX, + COUNTRY_CODE_CO, COUNTRY_CODE_CR, COUNTRY_CODE_GD, COUNTRY_CODE_GT, + COUNTRY_CODE_KI, COUNTRY_CODE_LB, COUNTRY_CODE_LR, COUNTRY_CODE_MN, + COUNTRY_CODE_AN, COUNTRY_CODE_NI, COUNTRY_CODE_PW, COUNTRY_CODE_WS, + COUNTRY_CODE_LK, COUNTRY_CODE_TT, COUNTRY_CODE_MM +}; + +static const uint16_t g_u2CountryGroup2[] = { + COUNTRY_CODE_AW, COUNTRY_CODE_LA, COUNTRY_CODE_AE, COUNTRY_CODE_UG +}; + +static const uint16_t g_u2CountryGroup3[] = { + COUNTRY_CODE_AR, COUNTRY_CODE_BR, COUNTRY_CODE_HK, COUNTRY_CODE_OM, + COUNTRY_CODE_PH, COUNTRY_CODE_SA, COUNTRY_CODE_SG, COUNTRY_CODE_ZA, + COUNTRY_CODE_VN, COUNTRY_CODE_KR, COUNTRY_CODE_DO, COUNTRY_CODE_FK, + COUNTRY_CODE_KZ, COUNTRY_CODE_MZ, COUNTRY_CODE_NA, COUNTRY_CODE_LC, + COUNTRY_CODE_VC, COUNTRY_CODE_UA, COUNTRY_CODE_UZ, COUNTRY_CODE_ZW, + COUNTRY_CODE_MP +}; + +static const uint16_t g_u2CountryGroup4[] = { + COUNTRY_CODE_AT, COUNTRY_CODE_BE, COUNTRY_CODE_BG, COUNTRY_CODE_HR, + COUNTRY_CODE_CZ, COUNTRY_CODE_DK, COUNTRY_CODE_FI, COUNTRY_CODE_FR, + COUNTRY_CODE_GR, COUNTRY_CODE_HU, COUNTRY_CODE_IS, COUNTRY_CODE_IE, + COUNTRY_CODE_IT, COUNTRY_CODE_LU, COUNTRY_CODE_NL, COUNTRY_CODE_NO, + COUNTRY_CODE_PL, COUNTRY_CODE_PT, COUNTRY_CODE_RO, COUNTRY_CODE_SK, + COUNTRY_CODE_SI, COUNTRY_CODE_ES, COUNTRY_CODE_SE, COUNTRY_CODE_CH, + COUNTRY_CODE_GB, COUNTRY_CODE_AL, COUNTRY_CODE_AD, COUNTRY_CODE_BY, + COUNTRY_CODE_BA, COUNTRY_CODE_VG, COUNTRY_CODE_CV, COUNTRY_CODE_CY, + COUNTRY_CODE_EE, COUNTRY_CODE_ET, COUNTRY_CODE_GF, COUNTRY_CODE_PF, + COUNTRY_CODE_TF, COUNTRY_CODE_GE, COUNTRY_CODE_DE, COUNTRY_CODE_GH, + COUNTRY_CODE_GP, COUNTRY_CODE_IQ, COUNTRY_CODE_KE, COUNTRY_CODE_LV, + COUNTRY_CODE_LS, COUNTRY_CODE_LI, COUNTRY_CODE_LT, COUNTRY_CODE_MK, + COUNTRY_CODE_MT, COUNTRY_CODE_MQ, COUNTRY_CODE_MR, COUNTRY_CODE_MU, + COUNTRY_CODE_YT, COUNTRY_CODE_MD, COUNTRY_CODE_MC, COUNTRY_CODE_ME, + COUNTRY_CODE_MS, COUNTRY_CODE_RE, COUNTRY_CODE_MF, COUNTRY_CODE_SM, + COUNTRY_CODE_SN, COUNTRY_CODE_RS, COUNTRY_CODE_TR, COUNTRY_CODE_TC, + COUNTRY_CODE_VA, COUNTRY_CODE_EU, COUNTRY_CODE_DZ +}; + +static const uint16_t g_u2CountryGroup5[] = { + COUNTRY_CODE_AU, COUNTRY_CODE_NZ, COUNTRY_CODE_EC, COUNTRY_CODE_PY, + COUNTRY_CODE_PE, COUNTRY_CODE_TH, COUNTRY_CODE_UY +}; + +static const uint16_t g_u2CountryGroup6[] = { COUNTRY_CODE_RU }; + +static const uint16_t g_u2CountryGroup7[] = { + COUNTRY_CODE_CL, COUNTRY_CODE_EG, COUNTRY_CODE_IN, COUNTRY_CODE_AG, + COUNTRY_CODE_BS, COUNTRY_CODE_BH, COUNTRY_CODE_BB, COUNTRY_CODE_BN, + COUNTRY_CODE_MV, COUNTRY_CODE_PA, COUNTRY_CODE_ZM, COUNTRY_CODE_CN +}; + +static const uint16_t g_u2CountryGroup8[] = { COUNTRY_CODE_MY }; + +static const uint16_t g_u2CountryGroup9[] = { COUNTRY_CODE_NP }; + +static const uint16_t g_u2CountryGroup10[] = { + COUNTRY_CODE_IL, COUNTRY_CODE_AM, COUNTRY_CODE_KW, COUNTRY_CODE_MA, + COUNTRY_CODE_NE, COUNTRY_CODE_TN +}; + +static const uint16_t g_u2CountryGroup11[] = { + COUNTRY_CODE_JO, COUNTRY_CODE_PG +}; + +static const uint16_t g_u2CountryGroup12[] = { COUNTRY_CODE_AF }; + +static const uint16_t g_u2CountryGroup13[] = { COUNTRY_CODE_NG }; + +static const uint16_t g_u2CountryGroup14[] = { + COUNTRY_CODE_PK, COUNTRY_CODE_QA, COUNTRY_CODE_BF, COUNTRY_CODE_GY, + COUNTRY_CODE_HT, COUNTRY_CODE_JM, COUNTRY_CODE_MO, COUNTRY_CODE_MW, + COUNTRY_CODE_RW, COUNTRY_CODE_KN, COUNTRY_CODE_TZ, COUNTRY_CODE_BD +}; + +static const uint16_t g_u2CountryGroup15[] = { COUNTRY_CODE_ID }; + +static const uint16_t g_u2CountryGroup16[] = { + COUNTRY_CODE_AO, COUNTRY_CODE_BZ, COUNTRY_CODE_BJ, COUNTRY_CODE_BT, + COUNTRY_CODE_BO, COUNTRY_CODE_BI, COUNTRY_CODE_CM, COUNTRY_CODE_CF, + COUNTRY_CODE_TD, COUNTRY_CODE_KM, COUNTRY_CODE_CD, COUNTRY_CODE_CG, + COUNTRY_CODE_CI, COUNTRY_CODE_DJ, COUNTRY_CODE_GQ, COUNTRY_CODE_ER, + COUNTRY_CODE_FJ, COUNTRY_CODE_GA, COUNTRY_CODE_GM, COUNTRY_CODE_GN, + COUNTRY_CODE_GW, COUNTRY_CODE_RKS, COUNTRY_CODE_KG, COUNTRY_CODE_LY, + COUNTRY_CODE_MG, COUNTRY_CODE_ML, COUNTRY_CODE_NR, COUNTRY_CODE_NC, + COUNTRY_CODE_ST, COUNTRY_CODE_SC, COUNTRY_CODE_SL, COUNTRY_CODE_SB, + COUNTRY_CODE_SO, COUNTRY_CODE_SR, COUNTRY_CODE_SZ, COUNTRY_CODE_TJ, + COUNTRY_CODE_TG, COUNTRY_CODE_TO, COUNTRY_CODE_TM, COUNTRY_CODE_TV, + COUNTRY_CODE_VU, COUNTRY_CODE_YE +}; + +static const uint16_t g_u2CountryGroup17[] = { + COUNTRY_CODE_US, COUNTRY_CODE_CA, COUNTRY_CODE_TW +}; + +static const uint16_t g_u2CountryGroup18[] = { + COUNTRY_CODE_DM, COUNTRY_CODE_SV, COUNTRY_CODE_HN +}; + +static const uint16_t g_u2CountryGroup19[] = { + COUNTRY_CODE_MX, COUNTRY_CODE_VE +}; + +static const uint16_t g_u2CountryGroup20[] = { + COUNTRY_CODE_CK, COUNTRY_CODE_CU, COUNTRY_CODE_TL, COUNTRY_CODE_FO, + COUNTRY_CODE_GI, COUNTRY_CODE_GG, COUNTRY_CODE_IR, COUNTRY_CODE_IM, + COUNTRY_CODE_JE, COUNTRY_CODE_KP, COUNTRY_CODE_MH, COUNTRY_CODE_NU, + COUNTRY_CODE_NF, COUNTRY_CODE_PS, COUNTRY_CODE_PN, COUNTRY_CODE_PM, + COUNTRY_CODE_SS, COUNTRY_CODE_SD, COUNTRY_CODE_SY +}; + +#if (CFG_SUPPORT_SINGLE_SKU == 1) +struct mtk_regd_control g_mtk_regd_control = { + .en = FALSE, + .state = REGD_STATE_UNDEFINED +}; + +#if (CFG_SUPPORT_SINGLE_SKU_LOCAL_DB == 1) +const struct ieee80211_regdomain default_regdom_ww = { + .n_reg_rules = 4, + .alpha2 = "99", + .reg_rules = { + /* channels 1..13 */ + REG_RULE_LIGHT(2412-10, 2472+10, 40, 0), + /* channels 14 */ + REG_RULE_LIGHT(2484-10, 2484+10, 20, 0), + /* channel 36..64 */ + REG_RULE_LIGHT(5150-10, 5350+10, 80, 0), + /* channel 100..165 */ + REG_RULE_LIGHT(5470-10, 5850+10, 80, 0), + } +}; +#endif + +struct TX_PWR_LIMIT_SECTION { + uint8_t ucSectionNum; + const char *arSectionNames[TX_PWR_LIMIT_SECTION_NUM]; +} gTx_Pwr_Limit_Section[] = { + {5, + {"legacy", "ht20", "ht40", "vht20", "offset"} + }, + {9, + {"cck", "ofdm", "ht20", "ht40", "vht20", "vht40", + "vht80", "vht160", "txbf_backoff"} + }, +}; + + +const u8 gTx_Pwr_Limit_Element_Num[][TX_PWR_LIMIT_SECTION_NUM] = { + {7, 6, 7, 7, 5}, + {POWER_LIMIT_SKU_CCK_NUM, POWER_LIMIT_SKU_OFDM_NUM, + POWER_LIMIT_SKU_HT20_NUM, POWER_LIMIT_SKU_HT40_NUM, + POWER_LIMIT_SKU_VHT20_NUM, POWER_LIMIT_SKU_VHT40_NUM, + POWER_LIMIT_SKU_VHT80_NUM, POWER_LIMIT_SKU_VHT160_NUM, + POWER_LIMIT_TXBF_BACKOFF_PARAM_NUM}, +}; + +const char *gTx_Pwr_Limit_Element[] + [TX_PWR_LIMIT_SECTION_NUM] + [TX_PWR_LIMIT_ELEMENT_NUM] = { + { + {"cck1_2", "cck_5_11", "ofdm6_9", "ofdm12_18", "ofdm24_36", + "ofdm48", "ofdm54"}, + {"mcs0_8", "mcs1_2_9_10", "mcs3_4_11_12", "mcs5_13", "mcs6_14", + "mcs7_15"}, + {"mcs0_8", "mcs1_2_9_10", "mcs3_4_11_12", "mcs5_13", "mcs6_14", + "mcs7_15", "mcs32"}, + {"mcs0", "mcs1_2", "mcs3_4", "mcs5_6", "mcs7", "mcs8", "mcs9"}, + {"lg40", "lg80", "vht40", "vht80", "vht160nc"}, + }, + { + {"c1", "c2", "c5", "c11"}, + {"o6", "o9", "o12", "o18", + "o24", "o36", "o48", "o54"}, + {"m0", "m1", "m2", "m3", "m4", "m5", "m6", "m7"}, + {"m0", "m1", "m2", "m3", "m4", "m5", "m6", "m7", "m32"}, + {"m0", "m1", "m2", "m3", "m4", "m5", "m6", "m7", "m8", "m9"}, + {"m0", "m1", "m2", "m3", "m4", "m5", "m6", "m7", "m8", "m9"}, + {"m0", "m1", "m2", "m3", "m4", "m5", "m6", "m7", "m8", "m9"}, + {"m0", "m1", "m2", "m3", "m4", "m5", "m6", "m7", "m8", "m9"}, + {"2to1"}, + }, +}; + +static const int8_t gTx_Pwr_Limit_2g_Ch[] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; +static const int8_t gTx_Pwr_Limit_5g_Ch[] = { + 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 100, 102, + 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 132, + 134, 136, 138, 140, 142, 144, 149, 151, 153, 155, 157, 159, 161, 165}; + +#define TX_PWR_LIMIT_2G_CH_NUM (ARRAY_SIZE(gTx_Pwr_Limit_2g_Ch)) +#define TX_PWR_LIMIT_5G_CH_NUM (ARRAY_SIZE(gTx_Pwr_Limit_5g_Ch)) + +u_int8_t g_bTxBfBackoffExists = FALSE; + +#endif + +struct DOMAIN_INFO_ENTRY arSupportedRegDomains[] = { + { + (uint16_t *) g_u2CountryGroup0, sizeof(g_u2CountryGroup0) / 2, + { + {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} + , /* CH_SET_2G4_1_13 */ + + {82, BAND_2G4, CHNL_SPAN_5, 14, 1, FALSE} + , /* CH_SET_2G4_14_14 */ + {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} + , /* CH_SET_UNII_LOW_36_48 */ + {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} + , /* CH_SET_UNII_MID_52_64 */ + {121, BAND_5G, CHNL_SPAN_20, 100, 11, TRUE} + , /* CH_SET_UNII_WW_100_140 */ + {125, BAND_NULL, 0, 0, 0, FALSE} + /* CH_SET_UNII_UPPER_NA */ + } + } + , + { + (uint16_t *) g_u2CountryGroup1, sizeof(g_u2CountryGroup1) / 2, + { + {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} + , /* CH_SET_2G4_1_13 */ + + {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} + , /* CH_SET_UNII_LOW_36_48 */ + {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} + , /* CH_SET_UNII_MID_52_64 */ + {121, BAND_5G, CHNL_SPAN_20, 100, 12, TRUE} + , /* CH_SET_UNII_WW_100_144 */ + {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} + , /* CH_SET_UNII_UPPER_149_165 */ + {0, BAND_NULL, 0, 0, 0, FALSE} + } + } + , + { + (uint16_t *) g_u2CountryGroup2, sizeof(g_u2CountryGroup2) / 2, + { + {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} + , /* CH_SET_2G4_1_13 */ + + {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} + , /* CH_SET_UNII_LOW_36_48 */ + {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} + , /* CH_SET_UNII_MID_52_64 */ + {121, BAND_5G, CHNL_SPAN_20, 100, 12, TRUE} + , /* CH_SET_UNII_WW_100_144 */ + {125, BAND_5G, CHNL_SPAN_20, 149, 4, FALSE} + , /* CH_SET_UNII_UPPER_149_161 */ + {0, BAND_NULL, 0, 0, 0, FALSE} + } + } + , + { + (uint16_t *) g_u2CountryGroup3, sizeof(g_u2CountryGroup3) / 2, + { + {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} + , /* CH_SET_2G4_1_13 */ + + {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} + , /* CH_SET_UNII_LOW_36_48 */ + {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} + , /* CH_SET_UNII_MID_52_64 */ + {121, BAND_5G, CHNL_SPAN_20, 100, 11, TRUE} + , /* CH_SET_UNII_WW_100_140 */ + {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} + , /* CH_SET_UNII_UPPER_149_165 */ + {0, BAND_NULL, 0, 0, 0, FALSE} + } + } + , + { + (uint16_t *) g_u2CountryGroup4, sizeof(g_u2CountryGroup4) / 2, + { + {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} + , /* CH_SET_2G4_1_13 */ + + {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} + , /* CH_SET_UNII_LOW_36_48 */ + {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} + , /* CH_SET_UNII_MID_52_64 */ + {121, BAND_5G, CHNL_SPAN_20, 100, 11, TRUE} + , /* CH_SET_UNII_WW_100_140 */ + {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} + , /* CH_SET_UNII_UPPER_149_165 */ + {0, BAND_NULL, 0, 0, 0, FALSE} + } + } + , + { + (uint16_t *) g_u2CountryGroup5, sizeof(g_u2CountryGroup5) / 2, + { + {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} + , /* CH_SET_2G4_1_13 */ + + {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} + , /* CH_SET_UNII_LOW_36_48 */ + {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} + , /* CH_SET_UNII_MID_52_64 */ + {121, BAND_5G, CHNL_SPAN_20, 100, 5, TRUE} + , /* CH_SET_UNII_WW_100_116 */ + {121, BAND_5G, CHNL_SPAN_20, 132, 3, TRUE} + , /* CH_SET_UNII_WW_132_140 */ + {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} + /* CH_SET_UNII_UPPER_149_165 */ + } + } + , + { + (uint16_t *) g_u2CountryGroup6, sizeof(g_u2CountryGroup6) / 2, + { + {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} + , /* CH_SET_2G4_1_13 */ + + {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} + , /* CH_SET_UNII_LOW_36_48 */ + {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} + , /* CH_SET_UNII_MID_52_64 */ + {121, BAND_5G, CHNL_SPAN_20, 132, 3, TRUE} + , /* CH_SET_UNII_WW_132_140 */ + {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} + , /* CH_SET_UNII_UPPER_149_165 */ + {0, BAND_NULL, 0, 0, 0, FALSE} + } + } + , + { + (uint16_t *) g_u2CountryGroup7, sizeof(g_u2CountryGroup7) / 2, + { + {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} + , /* CH_SET_2G4_1_13 */ + + {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} + , /* CH_SET_UNII_LOW_36_48 */ + {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} + , /* CH_SET_UNII_MID_52_64 */ + {121, BAND_NULL, 0, 0, 0, FALSE} + , /* CH_SET_UNII_WW_NA */ + {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} + , /* CH_SET_UNII_UPPER_149_165 */ + {0, BAND_NULL, 0, 0, 0, FALSE} + } + } + , + { + (uint16_t *) g_u2CountryGroup8, sizeof(g_u2CountryGroup8) / 2, + { + {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} + , /* CH_SET_2G4_1_13 */ + + {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} + , /* CH_SET_UNII_LOW_36_48 */ + {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} + , /* CH_SET_UNII_MID_52_64 */ + {121, BAND_5G, CHNL_SPAN_20, 100, 8, TRUE} + , /* CH_SET_UNII_WW_100_128 */ + {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} + , /* CH_SET_UNII_UPPER_149_165 */ + {0, BAND_NULL, 0, 0, 0, FALSE} + } + } + , + { + (uint16_t *) g_u2CountryGroup9, sizeof(g_u2CountryGroup9) / 2, + { + {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} + , /* CH_SET_2G4_1_13 */ + + {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} + , /* CH_SET_UNII_LOW_36_48 */ + {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} + , /* CH_SET_UNII_MID_52_64 */ + {121, BAND_NULL, 0, 0, 0, FALSE} + , /* CH_SET_UNII_WW_NA */ + {125, BAND_5G, CHNL_SPAN_20, 149, 4, FALSE} + , /* CH_SET_UNII_UPPER_149_161 */ + {0, BAND_NULL, 0, 0, 0, FALSE} + } + } + , + { + (uint16_t *) g_u2CountryGroup10, sizeof(g_u2CountryGroup10) / 2, + { + {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} + , /* CH_SET_2G4_1_13 */ + + {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} + , /* CH_SET_UNII_LOW_36_48 */ + {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} + , /* CH_SET_UNII_MID_52_64 */ + {121, BAND_NULL, 0, 0, 0, FALSE} + , /* CH_SET_UNII_WW_NA */ + {125, BAND_NULL, 0, 0, 0, FALSE} + , /* CH_SET_UNII_UPPER_NA */ + {0, BAND_NULL, 0, 0, 0, FALSE} + } + } + , + { + (uint16_t *) g_u2CountryGroup11, sizeof(g_u2CountryGroup11) / 2, + { + {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} + , /* CH_SET_2G4_1_13 */ + + {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} + , /* CH_SET_UNII_LOW_36_48 */ + {118, BAND_NULL, 0, 0, 0, FALSE} + , /* CH_SET_UNII_MID_NA */ + {121, BAND_NULL, 0, 0, 0, FALSE} + , /* CH_SET_UNII_WW_NA */ + {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} + , /* CH_SET_UNII_UPPER_149_165 */ + {0, BAND_NULL, 0, 0, 0, FALSE} + } + } + , + { + (uint16_t *) g_u2CountryGroup12, sizeof(g_u2CountryGroup12) / 2, + { + {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} + , /* CH_SET_2G4_1_13 */ + + {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} + , /* CH_SET_UNII_LOW_36_48 */ + {118, BAND_NULL, 0, 0, 0, FALSE} + , /* CH_SET_UNII_MID_NA */ + {121, BAND_NULL, 0, 0, 0, FALSE} + , /* CH_SET_UNII_WW_NA */ + {125, BAND_NULL, 0, 0, 0, FALSE} + , /* CH_SET_UNII_UPPER_NA */ + {0, BAND_NULL, 0, 0, 0, FALSE} + } + } + , + { + (uint16_t *) g_u2CountryGroup13, sizeof(g_u2CountryGroup13) / 2, + { + {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} + , /* CH_SET_2G4_1_13 */ + + {115, BAND_NULL, 0, 0, 0, FALSE} + , /* CH_SET_UNII_LOW_NA */ + {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} + , /* CH_SET_UNII_MID_52_64 */ + {121, BAND_5G, CHNL_SPAN_20, 100, 11, TRUE} + , /* CH_SET_UNII_WW_100_140 */ + {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} + , /* CH_SET_UNII_UPPER_149_165 */ + {0, BAND_NULL, 0, 0, 0, FALSE} + } + } + , + { + (uint16_t *) g_u2CountryGroup14, sizeof(g_u2CountryGroup14) / 2, + { + {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} + , /* CH_SET_2G4_1_13 */ + + {115, BAND_NULL, 0, 0, 0, FALSE} + , /* CH_SET_UNII_LOW_NA */ + {118, BAND_NULL, 0, 0, 0, FALSE} + , /* CH_SET_UNII_MID_NA */ + {121, BAND_NULL, 0, 0, 0, FALSE} + , /* CH_SET_UNII_WW_NA */ + {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} + , /* CH_SET_UNII_UPPER_149_165 */ + {0, BAND_NULL, 0, 0, 0, FALSE} + } + } + , + { + (uint16_t *) g_u2CountryGroup15, sizeof(g_u2CountryGroup15) / 2, + { + {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} + , /* CH_SET_2G4_1_13 */ + {115, BAND_NULL, 0, 0, 0, FALSE} + , /* CH_SET_UNII_LOW_NA */ + {118, BAND_NULL, 0, 0, 0, FALSE} + , /* CH_SET_UNII_MID_NA */ + {121, BAND_NULL, 0, 0, 0, FALSE} + , /* CH_SET_UNII_WW_NA */ + {125, BAND_5G, CHNL_SPAN_20, 149, 4, FALSE} + , /* CH_SET_UNII_UPPER_149_161 */ + {0, BAND_NULL, 0, 0, 0, FALSE} + } + } + , + { + (uint16_t *) g_u2CountryGroup16, sizeof(g_u2CountryGroup16) / 2, + { + {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} + , /* CH_SET_2G4_1_13 */ + {115, BAND_NULL, 0, 0, 0, FALSE} + , /* CH_SET_UNII_LOW_NA */ + {118, BAND_NULL, 0, 0, 0, FALSE} + , /* CH_SET_UNII_MID_NA */ + {121, BAND_NULL, 0, 0, 0, FALSE} + , /* CH_SET_UNII_WW_NA */ + {125, BAND_NULL, 0, 0, 0, FALSE} + , /* CH_SET_UNII_UPPER_NA */ + {0, BAND_NULL, 0, 0, 0, FALSE} + } + } + , + { + (uint16_t *) g_u2CountryGroup17, sizeof(g_u2CountryGroup17) / 2, + { + {81, BAND_2G4, CHNL_SPAN_5, 1, 11, FALSE} + , /* CH_SET_2G4_1_11 */ + {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} + , /* CH_SET_UNII_LOW_36_48 */ + {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} + , /* CH_SET_UNII_MID_52_64 */ + {121, BAND_5G, CHNL_SPAN_20, 100, 12, TRUE} + , /* CH_SET_UNII_WW_100_144 */ + {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} + /* CH_SET_UNII_UPPER_149_165 */ + } + } + , + { + (uint16_t *) g_u2CountryGroup18, sizeof(g_u2CountryGroup18) / 2, + { + {81, BAND_2G4, CHNL_SPAN_5, 1, 11, FALSE} + , /* CH_SET_2G4_1_11 */ + {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} + , /* CH_SET_UNII_LOW_36_48 */ + {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} + , /* CH_SET_UNII_MID_52_64 */ + {121, BAND_5G, CHNL_SPAN_20, 100, 5, TRUE} + , /* CH_SET_UNII_WW_100_116 */ + {121, BAND_5G, CHNL_SPAN_20, 132, 3, TRUE} + , /* CH_SET_UNII_WW_132_140 */ + {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} + /* CH_SET_UNII_UPPER_149_165 */ + } + } + , + { + (uint16_t *) g_u2CountryGroup19, sizeof(g_u2CountryGroup19) / 2, + { + {81, BAND_2G4, CHNL_SPAN_5, 1, 11, FALSE} + , /* CH_SET_2G4_1_11 */ + {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} + , /* CH_SET_UNII_LOW_36_48 */ + {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} + , /* CH_SET_UNII_MID_52_64 */ + {121, BAND_NULL, 0, 0, 0, FALSE} + , /* CH_SET_UNII_WW_NA */ + {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} + , /* CH_SET_UNII_UPPER_149_165 */ + {0, BAND_NULL, 0, 0, 0, FALSE} + } + } + , + { + (uint16_t *) g_u2CountryGroup20, sizeof(g_u2CountryGroup20) / 2, + { + {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} + , /* CH_SET_2G4_1_13 */ + {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} + , /* CH_SET_UNII_LOW_36_48 */ + {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} + , /* CH_SET_UNII_MID_52_64 */ + {121, BAND_5G, CHNL_SPAN_20, 100, 12, TRUE} + , /* CH_SET_UNII_WW_100_144 */ + {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} + , /* CH_SET_UNII_UPPER_149_165 */ + {0, BAND_NULL, 0, 0, 0, FALSE} + } + } + , + { + /* Note: Default group if no matched country code */ + NULL, 0, + { + {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} + , /* CH_SET_2G4_1_13 */ + {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} + , /* CH_SET_UNII_LOW_36_48 */ + {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} + , /* CH_SET_UNII_MID_52_64 */ + {121, BAND_5G, CHNL_SPAN_20, 100, 12, TRUE} + , /* CH_SET_UNII_WW_100_144 */ + {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} + , /* CH_SET_UNII_UPPER_149_165 */ + {0, BAND_NULL, 0, 0, 0, FALSE} + } + } +}; + +static const uint16_t g_u2CountryGroup0_Passive[] = { + COUNTRY_CODE_TW +}; + +struct DOMAIN_INFO_ENTRY arSupportedRegDomains_Passive[] = { + { + (uint16_t *) g_u2CountryGroup0_Passive, + sizeof(g_u2CountryGroup0_Passive) / 2, + { + {81, BAND_2G4, CHNL_SPAN_5, 1, 0, FALSE} + , /* CH_SET_2G4_1_14_NA */ + {82, BAND_2G4, CHNL_SPAN_5, 14, 0, FALSE} + , + + {115, BAND_5G, CHNL_SPAN_20, 36, 0, FALSE} + , /* CH_SET_UNII_LOW_NA */ + {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} + , /* CH_SET_UNII_MID_52_64 */ + {121, BAND_5G, CHNL_SPAN_20, 100, 11, TRUE} + , /* CH_SET_UNII_WW_100_140 */ + {125, BAND_5G, CHNL_SPAN_20, 149, 0, FALSE} + , /* CH_SET_UNII_UPPER_NA */ + } + } + , + { + /* Default passive scan channel table: ch52~64, ch100~144 */ + NULL, + 0, + { + {81, BAND_2G4, CHNL_SPAN_5, 1, 0, FALSE} + , /* CH_SET_2G4_1_14_NA */ + {82, BAND_2G4, CHNL_SPAN_5, 14, 0, FALSE} + , + + {115, BAND_5G, CHNL_SPAN_20, 36, 0, FALSE} + , /* CH_SET_UNII_LOW_NA */ + {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} + , /* CH_SET_UNII_MID_52_64 */ + {121, BAND_5G, CHNL_SPAN_20, 100, 12, TRUE} + , /* CH_SET_UNII_WW_100_144 */ + {125, BAND_5G, CHNL_SPAN_20, 149, 0, FALSE} + , /* CH_SET_UNII_UPPER_NA */ + } + } +}; + +#if (CFG_SUPPORT_PWR_LIMIT_COUNTRY == 1) +struct SUBBAND_CHANNEL g_rRlmSubBand[] = { + + {BAND_2G4_LOWER_BOUND, BAND_2G4_UPPER_BOUND, 1, 0} + , /* 2.4G */ + {UNII1_LOWER_BOUND, UNII1_UPPER_BOUND, 2, 0} + , /* ch36,38,40,..,48 */ + {UNII2A_LOWER_BOUND, UNII2A_UPPER_BOUND, 2, 0} + , /* ch52,54,56,..,64 */ + {UNII2C_LOWER_BOUND, UNII2C_UPPER_BOUND, 2, 0} + , /* ch100,102,104,...,144 */ + {UNII3_LOWER_BOUND, UNII3_UPPER_BOUND, 2, 0} + /* ch149,151,153,....,165 */ +}; +#endif +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in/out] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +struct DOMAIN_INFO_ENTRY *rlmDomainGetDomainInfo(struct ADAPTER *prAdapter) +{ +#define REG_DOMAIN_GROUP_NUM \ + (sizeof(arSupportedRegDomains) / sizeof(struct DOMAIN_INFO_ENTRY)) +#define REG_DOMAIN_DEF_IDX (REG_DOMAIN_GROUP_NUM - 1) + + struct DOMAIN_INFO_ENTRY *prDomainInfo; + struct REG_INFO *prRegInfo; + uint16_t u2TargetCountryCode; + uint16_t i, j; + + ASSERT(prAdapter); + + if (prAdapter->prDomainInfo) + return prAdapter->prDomainInfo; + + prRegInfo = &prAdapter->prGlueInfo->rRegInfo; + + DBGLOG(RLM, TRACE, "eRegChannelListMap=%d, u2CountryCode=0x%04x\n", + prRegInfo->eRegChannelListMap, + prAdapter->rWifiVar.u2CountryCode); + + /* + * Domain info can be specified by given idx of arSupportedRegDomains + * table, customized, or searched by country code, + * only one is set among these three methods in NVRAM. + */ + if (prRegInfo->eRegChannelListMap == REG_CH_MAP_TBL_IDX && + prRegInfo->ucRegChannelListIndex < REG_DOMAIN_GROUP_NUM) { + /* by given table idx */ + DBGLOG(RLM, TRACE, "ucRegChannelListIndex=%d\n", + prRegInfo->ucRegChannelListIndex); + prDomainInfo = &arSupportedRegDomains + [prRegInfo->ucRegChannelListIndex]; + } else if (prRegInfo->eRegChannelListMap == REG_CH_MAP_CUSTOMIZED) { + /* by customized */ + prDomainInfo = &prRegInfo->rDomainInfo; + } else { + /* by country code */ + u2TargetCountryCode = + prAdapter->rWifiVar.u2CountryCode; + + for (i = 0; i < REG_DOMAIN_GROUP_NUM; i++) { + prDomainInfo = &arSupportedRegDomains[i]; + + if ((prDomainInfo->u4CountryNum && + prDomainInfo->pu2CountryGroup) || + prDomainInfo->u4CountryNum == 0) { + for (j = 0; + j < prDomainInfo->u4CountryNum; + j++) { + if (prDomainInfo->pu2CountryGroup[j] == + u2TargetCountryCode) + break; + } + if (j < prDomainInfo->u4CountryNum) + break; /* Found */ + } + } + + /* If no matched country code, + * use the default regulatory domain + */ + if (i >= REG_DOMAIN_GROUP_NUM) { + DBGLOG(RLM, INFO, + "No matched country code, use the default regulatory domain\n"); + prDomainInfo = &arSupportedRegDomains + [REG_DOMAIN_DEF_IDX]; + } + } + + prAdapter->prDomainInfo = prDomainInfo; + return prDomainInfo; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Retrieve the supported channel list of specified band + * + * \param[in/out] eSpecificBand: BAND_2G4, BAND_5G or BAND_NULL + * (both 2.4G and 5G) + * fgNoDfs: whether to exculde DFS channels + * ucMaxChannelNum: max array size + * pucNumOfChannel: pointer to returned channel number + * paucChannelList: pointer to returned channel list array + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void +rlmDomainGetChnlList_V2(struct ADAPTER *prAdapter, + enum ENUM_BAND eSpecificBand, u_int8_t fgNoDfs, + uint8_t ucMaxChannelNum, uint8_t *pucNumOfChannel, + struct RF_CHANNEL_INFO *paucChannelList) +{ +#if (CFG_SUPPORT_SINGLE_SKU == 1) + enum ENUM_BAND band; + uint8_t max_count, i, ucNum; + struct CMD_DOMAIN_CHANNEL *prCh; + + if (eSpecificBand == BAND_2G4) { + i = 0; + max_count = rlmDomainGetActiveChannelCount(KAL_BAND_2GHZ); + } else if (eSpecificBand == BAND_5G) { + i = rlmDomainGetActiveChannelCount(KAL_BAND_2GHZ); + max_count = rlmDomainGetActiveChannelCount(KAL_BAND_5GHZ) + + rlmDomainGetActiveChannelCount(KAL_BAND_2GHZ); + } else { + i = 0; + max_count = rlmDomainGetActiveChannelCount(KAL_BAND_5GHZ) + + rlmDomainGetActiveChannelCount(KAL_BAND_2GHZ); + } + + ucNum = 0; + for (; i < max_count; i++) { + prCh = rlmDomainGetActiveChannels() + i; + if (fgNoDfs && (prCh->eFlags & IEEE80211_CHAN_RADAR)) + continue; /*not match*/ + + if (i < rlmDomainGetActiveChannelCount(KAL_BAND_2GHZ)) + band = BAND_2G4; + else + band = BAND_5G; + + paucChannelList[ucNum].eBand = band; + paucChannelList[ucNum].ucChannelNum = prCh->u2ChNum; + + ucNum++; + if (ucMaxChannelNum == ucNum) + break; + } + + *pucNumOfChannel = ucNum; +#else + *pucNumOfChannel = 0; +#endif +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Check if Channel supported by HW + * + * \param[in/out] eBand: BAND_2G4, BAND_5G or BAND_NULL + * (both 2.4G and 5G) + * ucNumOfChannel: channel number + * + * \return TRUE/FALSE + */ +/*----------------------------------------------------------------------------*/ +u_int8_t rlmIsValidChnl(struct ADAPTER *prAdapter, uint8_t ucNumOfChannel, + enum ENUM_BAND eBand) +{ + struct ieee80211_supported_band *channelList; + int i, chSize; + struct GLUE_INFO *prGlueInfo; + struct wiphy *prWiphy; + + prGlueInfo = prAdapter->prGlueInfo; + prWiphy = priv_to_wiphy(prGlueInfo); + + if (eBand == BAND_5G) { + channelList = prWiphy->bands[KAL_BAND_5GHZ]; + chSize = channelList->n_channels; + } else if (eBand == BAND_2G4) { + channelList = prWiphy->bands[KAL_BAND_2GHZ]; + chSize = channelList->n_channels; + } else + return FALSE; + + for (i = 0; i < chSize; i++) { + if ((channelList->channels[i]).hw_value == ucNumOfChannel) + return TRUE; + } + return FALSE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Retrieve the supported channel list of specified band + * + * \param[in/out] eSpecificBand: BAND_2G4, BAND_5G or BAND_NULL + * (both 2.4G and 5G) + * fgNoDfs: whether to exculde DFS channels + * ucMaxChannelNum: max array size + * pucNumOfChannel: pointer to returned channel number + * paucChannelList: pointer to returned channel list array + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void +rlmDomainGetChnlList(struct ADAPTER *prAdapter, + enum ENUM_BAND eSpecificBand, u_int8_t fgNoDfs, + uint8_t ucMaxChannelNum, uint8_t *pucNumOfChannel, + struct RF_CHANNEL_INFO *paucChannelList) +{ + uint8_t i, j, ucNum, ch; + struct DOMAIN_SUBBAND_INFO *prSubband; + struct DOMAIN_INFO_ENTRY *prDomainInfo; + + ASSERT(prAdapter); + ASSERT(paucChannelList); + ASSERT(pucNumOfChannel); + + if (regd_is_single_sku_en()) + return rlmDomainGetChnlList_V2(prAdapter, eSpecificBand, + fgNoDfs, ucMaxChannelNum, + pucNumOfChannel, + paucChannelList); + + /* If no matched country code, the final one will be used */ + prDomainInfo = rlmDomainGetDomainInfo(prAdapter); + ASSERT(prDomainInfo); + + ucNum = 0; + for (i = 0; i < MAX_SUBBAND_NUM; i++) { + prSubband = &prDomainInfo->rSubBand[i]; + + if (prSubband->ucBand == BAND_NULL || + prSubband->ucBand >= BAND_NUM || + (prSubband->ucBand == BAND_5G && + !prAdapter->fgEnable5GBand)) + continue; + + /* repoert to upper layer only non-DFS channel + * for ap mode usage + */ + if (fgNoDfs == TRUE && prSubband->fgDfs == TRUE) + continue; + + if (eSpecificBand == BAND_NULL || + prSubband->ucBand == eSpecificBand) { + for (j = 0; j < prSubband->ucNumChannels; j++) { + if (ucNum >= ucMaxChannelNum) + break; + + ch = prSubband->ucFirstChannelNum + + j * prSubband->ucChannelSpan; + if (!rlmIsValidChnl(prAdapter, ch, + prSubband->ucBand)) { + DBGLOG(RLM, INFO, + "Not support ch%d!\n", ch); + continue; + } + paucChannelList[ucNum].eBand = + prSubband->ucBand; + paucChannelList[ucNum].ucChannelNum = ch; + paucChannelList[ucNum].eDFS = prSubband->fgDfs; + ucNum++; + } + } + } + + *pucNumOfChannel = ucNum; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Retrieve DFS channels from 5G band + * + * \param[in/out] ucMaxChannelNum: max array size + * pucNumOfChannel: pointer to returned channel number + * paucChannelList: pointer to returned channel list array + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rlmDomainGetDfsChnls(struct ADAPTER *prAdapter, + uint8_t ucMaxChannelNum, uint8_t *pucNumOfChannel, + struct RF_CHANNEL_INFO *paucChannelList) +{ + uint8_t i, j, ucNum, ch; + struct DOMAIN_SUBBAND_INFO *prSubband; + struct DOMAIN_INFO_ENTRY *prDomainInfo; + + ASSERT(prAdapter); + ASSERT(paucChannelList); + ASSERT(pucNumOfChannel); + + prDomainInfo = rlmDomainGetDomainInfo(prAdapter); + ASSERT(prDomainInfo); + + ucNum = 0; + for (i = 0; i < MAX_SUBBAND_NUM; i++) { + prSubband = &prDomainInfo->rSubBand[i]; + + if (prSubband->ucBand == BAND_5G) { + if (!prAdapter->fgEnable5GBand) + continue; + + if (prSubband->fgDfs == TRUE) { + for (j = 0; j < prSubband->ucNumChannels; j++) { + if (ucNum >= ucMaxChannelNum) + break; + + ch = prSubband->ucFirstChannelNum + + j * prSubband->ucChannelSpan; + if (!rlmIsValidChnl(prAdapter, ch, + prSubband->ucBand)) { + DBGLOG(RLM, INFO, + "Not support ch%d!\n", ch); + continue; + } + + paucChannelList[ucNum].eBand = + prSubband->ucBand; + paucChannelList[ucNum].ucChannelNum = + ch; + ucNum++; + } + } + } + } + + *pucNumOfChannel = ucNum; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief + * + * @param[in] + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void rlmDomainSendCmd(struct ADAPTER *prAdapter) +{ + if (!regd_is_single_sku_en()) + rlmDomainSendPassiveScanInfoCmd(prAdapter); + rlmDomainSendDomainInfoCmd(prAdapter); +#if CFG_SUPPORT_PWR_LIMIT_COUNTRY + rlmDomainSendPwrLimitCmd(prAdapter); +#endif +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief + * + * @param[in] + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void rlmDomainSendDomainInfoCmd_V2(struct ADAPTER *prAdapter) +{ +#if (CFG_SUPPORT_SINGLE_SKU == 1) + u8 max_channel_count = 0; + u32 buff_max_size, buff_valid_size; + struct CMD_SET_DOMAIN_INFO_V2 *prCmd; + struct CMD_DOMAIN_ACTIVE_CHANNEL_LIST *prChs; + struct wiphy *pWiphy; + + + pWiphy = priv_to_wiphy(prAdapter->prGlueInfo); + if (pWiphy->bands[KAL_BAND_2GHZ] != NULL) + max_channel_count += pWiphy->bands[KAL_BAND_2GHZ]->n_channels; + if (pWiphy->bands[KAL_BAND_5GHZ] != NULL) + max_channel_count += pWiphy->bands[KAL_BAND_5GHZ]->n_channels; + + if (max_channel_count == 0) { + DBGLOG(RLM, ERROR, "%s, invalid channel count.\n", __func__); + ASSERT(0); + } + + + buff_max_size = sizeof(struct CMD_SET_DOMAIN_INFO_V2) + + max_channel_count * sizeof(struct CMD_DOMAIN_CHANNEL); + + prCmd = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, buff_max_size); + if (!prCmd) { + DBGLOG(RLM, ERROR, "Alloc cmd buffer failed\n"); + return; + } + prChs = &(prCmd->arActiveChannels); + + + /* + * Fill in the active channels + */ + rlmExtractChannelInfo(max_channel_count, prChs); + + prCmd->u4CountryCode = rlmDomainGetCountryCode(); + prCmd->uc2G4Bandwidth = prAdapter->rWifiVar.uc2G4BandwidthMode; + prCmd->uc5GBandwidth = prAdapter->rWifiVar.uc5GBandwidthMode; + prCmd->aucPadding[0] = 0; + prCmd->aucPadding[1] = 0; + + buff_valid_size = sizeof(struct CMD_SET_DOMAIN_INFO_V2) + + (prChs->u1ActiveChNum2g + prChs->u1ActiveChNum5g) * + sizeof(struct CMD_DOMAIN_CHANNEL); + + DBGLOG(RLM, INFO, + "rlmDomainSendDomainInfoCmd_V2(), buff_valid_size = 0x%x\n", + buff_valid_size); + + + /* Set domain info to chip */ + wlanSendSetQueryCmd(prAdapter, /* prAdapter */ + CMD_ID_SET_DOMAIN_INFO, /* ucCID */ + TRUE, /* fgSetQuery */ + FALSE, /* fgNeedResp */ + FALSE, /* fgIsOid */ + NULL, /* pfCmdDoneHandler */ + NULL, /* pfCmdTimeoutHandler */ + buff_valid_size, + (uint8_t *) prCmd, /* pucInfoBuffer */ + NULL, /* pvSetQueryBuffer */ + 0 /* u4SetQueryBufferLen */ + ); + + cnmMemFree(prAdapter, prCmd); +#endif +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief + * + * @param[in] + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void rlmDomainSendDomainInfoCmd(struct ADAPTER *prAdapter) +{ + struct DOMAIN_INFO_ENTRY *prDomainInfo; + struct CMD_SET_DOMAIN_INFO *prCmd; + struct DOMAIN_SUBBAND_INFO *prSubBand; + uint8_t i; + + if (regd_is_single_sku_en()) + return rlmDomainSendDomainInfoCmd_V2(prAdapter); + + + prDomainInfo = rlmDomainGetDomainInfo(prAdapter); + ASSERT(prDomainInfo); + + prCmd = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, + sizeof(struct CMD_SET_DOMAIN_INFO)); + if (!prCmd) { + DBGLOG(RLM, ERROR, "Alloc cmd buffer failed\n"); + return; + } + kalMemZero(prCmd, sizeof(struct CMD_SET_DOMAIN_INFO)); + + prCmd->u2CountryCode = + prAdapter->rWifiVar.u2CountryCode; + prCmd->u2IsSetPassiveScan = 0; + prCmd->uc2G4Bandwidth = + prAdapter->rWifiVar.uc2G4BandwidthMode; + prCmd->uc5GBandwidth = + prAdapter->rWifiVar.uc5GBandwidthMode; + prCmd->aucReserved[0] = 0; + prCmd->aucReserved[1] = 0; + + for (i = 0; i < MAX_SUBBAND_NUM; i++) { + prSubBand = &prDomainInfo->rSubBand[i]; + + prCmd->rSubBand[i].ucRegClass = prSubBand->ucRegClass; + prCmd->rSubBand[i].ucBand = prSubBand->ucBand; + + if (prSubBand->ucBand != BAND_NULL && prSubBand->ucBand + < BAND_NUM) { + prCmd->rSubBand[i].ucChannelSpan + = prSubBand->ucChannelSpan; + prCmd->rSubBand[i].ucFirstChannelNum + = prSubBand->ucFirstChannelNum; + prCmd->rSubBand[i].ucNumChannels + = prSubBand->ucNumChannels; + } + } + + /* Set domain info to chip */ + wlanSendSetQueryCmd(prAdapter, /* prAdapter */ + CMD_ID_SET_DOMAIN_INFO, /* ucCID */ + TRUE, /* fgSetQuery */ + FALSE, /* fgNeedResp */ + FALSE, /* fgIsOid */ + NULL, /* pfCmdDoneHandler */ + NULL, /* pfCmdTimeoutHandler */ + sizeof(struct CMD_SET_DOMAIN_INFO), /* u4SetQueryInfoLen */ + (uint8_t *) prCmd, /* pucInfoBuffer */ + NULL, /* pvSetQueryBuffer */ + 0 /* u4SetQueryBufferLen */ + ); + + cnmMemFree(prAdapter, prCmd); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief + * + * @param[in] + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void rlmDomainSendPassiveScanInfoCmd(struct ADAPTER *prAdapter) +{ +#define REG_DOMAIN_PASSIVE_DEF_IDX 1 +#define REG_DOMAIN_PASSIVE_GROUP_NUM \ + (sizeof(arSupportedRegDomains_Passive) \ + / sizeof(struct DOMAIN_INFO_ENTRY)) + + struct DOMAIN_INFO_ENTRY *prDomainInfo; + struct CMD_SET_DOMAIN_INFO *prCmd; + struct DOMAIN_SUBBAND_INFO *prSubBand; + uint16_t u2TargetCountryCode; + uint8_t i, j; + + prCmd = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, + sizeof(struct CMD_SET_DOMAIN_INFO)); + if (!prCmd) { + DBGLOG(RLM, ERROR, "Alloc cmd buffer failed\n"); + return; + } + kalMemZero(prCmd, sizeof(struct CMD_SET_DOMAIN_INFO)); + + prCmd->u2CountryCode = prAdapter->rWifiVar.u2CountryCode; + prCmd->u2IsSetPassiveScan = 1; + prCmd->uc2G4Bandwidth = + prAdapter->rWifiVar.uc2G4BandwidthMode; + prCmd->uc5GBandwidth = + prAdapter->rWifiVar.uc5GBandwidthMode; + prCmd->aucReserved[0] = 0; + prCmd->aucReserved[1] = 0; + + DBGLOG(RLM, TRACE, "u2CountryCode=0x%04x\n", + prAdapter->rWifiVar.u2CountryCode); + + u2TargetCountryCode = prAdapter->rWifiVar.u2CountryCode; + + for (i = 0; i < REG_DOMAIN_PASSIVE_GROUP_NUM; i++) { + prDomainInfo = &arSupportedRegDomains_Passive[i]; + + for (j = 0; j < prDomainInfo->u4CountryNum; j++) { + if (prDomainInfo->pu2CountryGroup[j] == + u2TargetCountryCode) + break; + } + if (j < prDomainInfo->u4CountryNum) + break; /* Found */ + } + + if (i >= REG_DOMAIN_PASSIVE_GROUP_NUM) + prDomainInfo = &arSupportedRegDomains_Passive + [REG_DOMAIN_PASSIVE_DEF_IDX]; + + for (i = 0; i < MAX_SUBBAND_NUM; i++) { + prSubBand = &prDomainInfo->rSubBand[i]; + + prCmd->rSubBand[i].ucRegClass = prSubBand->ucRegClass; + prCmd->rSubBand[i].ucBand = prSubBand->ucBand; + + if (prSubBand->ucBand != BAND_NULL && prSubBand->ucBand + < BAND_NUM) { + prCmd->rSubBand[i].ucChannelSpan = + prSubBand->ucChannelSpan; + prCmd->rSubBand[i].ucFirstChannelNum = + prSubBand->ucFirstChannelNum; + prCmd->rSubBand[i].ucNumChannels = + prSubBand->ucNumChannels; + } + } + + /* Set passive scan channel info to chip */ + wlanSendSetQueryCmd(prAdapter, /* prAdapter */ + CMD_ID_SET_DOMAIN_INFO, /* ucCID */ + TRUE, /* fgSetQuery */ + FALSE, /* fgNeedResp */ + FALSE, /* fgIsOid */ + NULL, /* pfCmdDoneHandler */ + NULL, /* pfCmdTimeoutHandler */ + sizeof(struct CMD_SET_DOMAIN_INFO), /* u4SetQueryInfoLen */ + (uint8_t *) prCmd, /* pucInfoBuffer */ + NULL, /* pvSetQueryBuffer */ + 0 /* u4SetQueryBufferLen */ + ); + + cnmMemFree(prAdapter, prCmd); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in/out] + * + * \return TRUE Legal channel + * FALSE Illegal channel for current regulatory domain + */ +/*----------------------------------------------------------------------------*/ +u_int8_t rlmDomainIsLegalChannel_V2(struct ADAPTER *prAdapter, + enum ENUM_BAND eBand, + uint8_t ucChannel) +{ +#if (CFG_SUPPORT_SINGLE_SKU == 1) + uint8_t idx, start_idx, end_idx; + struct CMD_DOMAIN_CHANNEL *prCh; + + if (eBand == BAND_2G4) { + start_idx = 0; + end_idx = rlmDomainGetActiveChannelCount(KAL_BAND_2GHZ); + } else { + start_idx = rlmDomainGetActiveChannelCount(KAL_BAND_2GHZ); + end_idx = rlmDomainGetActiveChannelCount(KAL_BAND_2GHZ) + + rlmDomainGetActiveChannelCount(KAL_BAND_5GHZ); + } + + for (idx = start_idx; idx < end_idx; idx++) { + prCh = rlmDomainGetActiveChannels() + idx; + + if (prCh->u2ChNum == ucChannel) + return TRUE; + } + + return FALSE; +#else + return FALSE; +#endif +} + +u_int8_t rlmDomainIsLegalChannel(struct ADAPTER *prAdapter, + enum ENUM_BAND eBand, uint8_t ucChannel) +{ + uint8_t i, j; + struct DOMAIN_SUBBAND_INFO *prSubband; + struct DOMAIN_INFO_ENTRY *prDomainInfo; + + if (regd_is_single_sku_en()) + return rlmDomainIsLegalChannel_V2(prAdapter, eBand, ucChannel); + + + prDomainInfo = rlmDomainGetDomainInfo(prAdapter); + ASSERT(prDomainInfo); + + for (i = 0; i < MAX_SUBBAND_NUM; i++) { + prSubband = &prDomainInfo->rSubBand[i]; + + if (prSubband->ucBand == BAND_5G && !prAdapter->fgEnable5GBand) + continue; + + if (prSubband->ucBand == eBand) { + for (j = 0; j < prSubband->ucNumChannels; j++) { + if ((prSubband->ucFirstChannelNum + j * + prSubband->ucChannelSpan) == ucChannel) { + if (!rlmIsValidChnl(prAdapter, + ucChannel, + prSubband->ucBand)) { + DBGLOG(RLM, INFO, + "Not support ch%d!\n", + ucChannel); + return FALSE; + } else + return TRUE; + + } + } + } + } + + return FALSE; +} + +u_int8_t rlmDomainIsLegalDfsChannel(struct ADAPTER *prAdapter, + enum ENUM_BAND eBand, uint8_t ucChannel) +{ + uint8_t i, j; + struct DOMAIN_SUBBAND_INFO *prSubband; + struct DOMAIN_INFO_ENTRY *prDomainInfo; + + prDomainInfo = rlmDomainGetDomainInfo(prAdapter); + ASSERT(prDomainInfo); + + for (i = 0; i < MAX_SUBBAND_NUM; i++) { + prSubband = &prDomainInfo->rSubBand[i]; + + if (prSubband->ucBand == BAND_5G + && !prAdapter->fgEnable5GBand) + continue; + + if (prSubband->ucBand == eBand + && prSubband->fgDfs == TRUE) { + for (j = 0; j < prSubband->ucNumChannels; j++) { + if ((prSubband->ucFirstChannelNum + j * + prSubband->ucChannelSpan) + == ucChannel) { + return TRUE; + } + } + } + } + + return FALSE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in/out] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ + +uint32_t rlmDomainSupOperatingClassIeFill(uint8_t *pBuf) +{ + /* + * The Country element should only be included for + * Status Code 0 (Successful). + */ + uint32_t u4IeLen; + uint8_t aucClass[12] = { 0x01, 0x02, 0x03, 0x05, 0x16, 0x17, 0x19, 0x1b, + 0x1c, 0x1e, 0x20, 0x21 + }; + + /* + * The Supported Operating Classes element is used by a STA to + * advertise the operating classes that it is capable of operating + * with in this country. + * The Country element (see 8.4.2.10) allows a STA to configure its + * PHY and MAC for operation when the operating triplet of Operating + * Extension Identifier, Operating Class, and Coverage Class fields + * is present. + */ + SUP_OPERATING_CLASS_IE(pBuf)->ucId = ELEM_ID_SUP_OPERATING_CLASS; + SUP_OPERATING_CLASS_IE(pBuf)->ucLength = 1 + sizeof(aucClass); + SUP_OPERATING_CLASS_IE(pBuf)->ucCur = 0x0c; /* 0x51 */ + kalMemCopy(SUP_OPERATING_CLASS_IE(pBuf)->ucSup, aucClass, + sizeof(aucClass)); + u4IeLen = (SUP_OPERATING_CLASS_IE(pBuf)->ucLength + 2); + pBuf += u4IeLen; + + COUNTRY_IE(pBuf)->ucId = ELEM_ID_COUNTRY_INFO; + COUNTRY_IE(pBuf)->ucLength = 6; + COUNTRY_IE(pBuf)->aucCountryStr[0] = 0x55; + COUNTRY_IE(pBuf)->aucCountryStr[1] = 0x53; + COUNTRY_IE(pBuf)->aucCountryStr[2] = 0x20; + COUNTRY_IE(pBuf)->arCountryStr[0].ucFirstChnlNum = 1; + COUNTRY_IE(pBuf)->arCountryStr[0].ucNumOfChnl = 11; + COUNTRY_IE(pBuf)->arCountryStr[0].cMaxTxPwrLv = 0x1e; + u4IeLen += (COUNTRY_IE(pBuf)->ucLength + 2); + + return u4IeLen; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief + * + * @param[in] + * + * @return (fgValid) : 0 -> inValid, 1 -> Valid + */ +/*----------------------------------------------------------------------------*/ +u_int8_t rlmDomainCheckChannelEntryValid(struct ADAPTER *prAdapter, + uint8_t ucCentralCh) +{ + u_int8_t fgValid = FALSE; + uint8_t ucTemp = 0xff; + uint8_t i; + /*Check Power limit table channel efficient or not */ + + /* CH50 is not located in any FCC subbands + * but it's a valid central channel for 160C + */ + if (ucCentralCh == 50) { + fgValid = TRUE; + return fgValid; + } + + for (i = POWER_LIMIT_2G4; i < POWER_LIMIT_SUBAND_NUM; i++) { + if ((ucCentralCh >= g_rRlmSubBand[i].ucStartCh) && + (ucCentralCh <= g_rRlmSubBand[i].ucEndCh)) + ucTemp = (ucCentralCh - g_rRlmSubBand[i].ucStartCh) % + g_rRlmSubBand[i].ucInterval; + } + + if (ucTemp == 0) + fgValid = TRUE; + return fgValid; + +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return + */ +/*----------------------------------------------------------------------------*/ +uint8_t rlmDomainGetCenterChannel(enum ENUM_BAND eBand, uint8_t ucPriChannel, + enum ENUM_CHNL_EXT eExtend) +{ + uint8_t ucCenterChannel; + + if (eExtend == CHNL_EXT_SCA) + ucCenterChannel = ucPriChannel + 2; + else if (eExtend == CHNL_EXT_SCB) + ucCenterChannel = ucPriChannel - 2; + else + ucCenterChannel = ucPriChannel; + + return ucCenterChannel; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return + */ +/*----------------------------------------------------------------------------*/ +u_int8_t +rlmDomainIsValidRfSetting(struct ADAPTER *prAdapter, + enum ENUM_BAND eBand, + uint8_t ucPriChannel, + enum ENUM_CHNL_EXT eExtend, + enum ENUM_CHANNEL_WIDTH eChannelWidth, + uint8_t ucChannelS1, uint8_t ucChannelS2) +{ + uint8_t ucCenterCh = 0; + uint8_t ucUpperChannel; + uint8_t ucLowerChannel; + u_int8_t fgValidChannel = TRUE; + u_int8_t fgUpperChannel = TRUE; + u_int8_t fgLowerChannel = TRUE; + u_int8_t fgValidBW = TRUE; + u_int8_t fgValidRfSetting = TRUE; + uint32_t u4PrimaryOffset; + + /*DBG msg for Channel InValid */ + if (eChannelWidth == CW_20_40MHZ) { + ucCenterCh = rlmDomainGetCenterChannel(eBand, ucPriChannel, + eExtend); + + /* Check Central Channel Valid or Not */ + fgValidChannel = rlmDomainCheckChannelEntryValid(prAdapter, + ucCenterCh); + if (fgValidChannel == FALSE) + DBGLOG(RLM, WARN, "Rf20: CentralCh=%d\n", ucCenterCh); + + /* Check Upper Channel and Lower Channel */ + switch (eExtend) { + case CHNL_EXT_SCA: + ucUpperChannel = ucPriChannel + 4; + ucLowerChannel = ucPriChannel; + break; + case CHNL_EXT_SCB: + ucUpperChannel = ucPriChannel; + ucLowerChannel = ucPriChannel - 4; + break; + default: + ucUpperChannel = ucPriChannel; + ucLowerChannel = ucPriChannel; + break; + } + + fgUpperChannel = rlmDomainCheckChannelEntryValid(prAdapter, + ucUpperChannel); + if (fgUpperChannel == FALSE) + DBGLOG(RLM, WARN, "Rf20: UpperCh=%d\n", ucUpperChannel); + + fgLowerChannel = rlmDomainCheckChannelEntryValid(prAdapter, + ucLowerChannel); + if (fgLowerChannel == FALSE) + DBGLOG(RLM, WARN, "Rf20: LowerCh=%d\n", ucLowerChannel); + + } else if ((eChannelWidth == CW_80MHZ) || + (eChannelWidth == CW_160MHZ)) { + ucCenterCh = ucChannelS1; + + /* Check Central Channel Valid or Not */ + if (eChannelWidth != CW_160MHZ) { + /* BW not check , ex: primary 36 and + * central channel 50 will fail the check + */ + fgValidChannel = + rlmDomainCheckChannelEntryValid(prAdapter, + ucCenterCh); + } + + if (fgValidChannel == FALSE) + DBGLOG(RLM, WARN, "Rf80/160C: CentralCh=%d\n", + ucCenterCh); + } else if (eChannelWidth == CW_80P80MHZ) { + ucCenterCh = ucChannelS1; + + fgValidChannel = rlmDomainCheckChannelEntryValid(prAdapter, + ucCenterCh); + + if (fgValidChannel == FALSE) + DBGLOG(RLM, WARN, "Rf160NC: CentralCh1=%d\n", + ucCenterCh); + + ucCenterCh = ucChannelS2; + + fgValidChannel = rlmDomainCheckChannelEntryValid(prAdapter, + ucCenterCh); + + if (fgValidChannel == FALSE) + DBGLOG(RLM, WARN, "Rf160NC: CentralCh2=%d\n", + ucCenterCh); + + /* Check Central Channel Valid or Not */ + } else { + DBGLOG(RLM, ERROR, "Wrong BW =%d\n", eChannelWidth); + fgValidChannel = FALSE; + } + + /* Check BW Setting Correct or Not */ + if (eBand == BAND_2G4) { + if (eChannelWidth != CW_20_40MHZ) { + fgValidBW = FALSE; + DBGLOG(RLM, WARN, "Rf: B=%d, W=%d\n", + eBand, eChannelWidth); + } + } else { + if ((eChannelWidth == CW_80MHZ) || + (eChannelWidth == CW_80P80MHZ)) { + u4PrimaryOffset = CAL_CH_OFFSET_80M(ucPriChannel, + ucChannelS1); + if (u4PrimaryOffset > 4) { + fgValidBW = FALSE; + DBGLOG(RLM, WARN, "Rf: PriOffSet=%d, W=%d\n", + u4PrimaryOffset, eChannelWidth); + } + if (ucPriChannel == 165) { + fgValidBW = FALSE; + DBGLOG(RLM, WARN, + "Rf: PriOffSet=%d, W=%d C=%d\n", + u4PrimaryOffset, eChannelWidth, + ucPriChannel); + } + } else if (eChannelWidth == CW_160MHZ) { + u4PrimaryOffset = CAL_CH_OFFSET_160M(ucPriChannel, + ucCenterCh); + if (u4PrimaryOffset > 8) { + fgValidBW = FALSE; + DBGLOG(RLM, WARN, + "Rf: PriOffSet=%d, W=%d\n", + u4PrimaryOffset, eChannelWidth); + } + } + } + + if ((fgValidBW == FALSE) || (fgValidChannel == FALSE) || + (fgUpperChannel == FALSE) || (fgLowerChannel == FALSE)) + fgValidRfSetting = FALSE; + + return fgValidRfSetting; + +} + +#if (CFG_SUPPORT_SINGLE_SKU == 1) +/* + * This function coverts country code from alphabet chars to u32, + * the caller need to pass country code chars and do size check + */ +uint32_t rlmDomainAlpha2ToU32(uint8_t *pcAlpha2, uint8_t ucAlpha2Size) +{ + uint8_t ucIdx; + uint32_t u4CountryCode = 0; + + if (ucAlpha2Size > TX_PWR_LIMIT_COUNTRY_STR_MAX_LEN) { + DBGLOG(RLM, ERROR, "alpha2 size %d is invalid!(max: %d)\n", + ucAlpha2Size, TX_PWR_LIMIT_COUNTRY_STR_MAX_LEN); + ucAlpha2Size = TX_PWR_LIMIT_COUNTRY_STR_MAX_LEN; + } + + for (ucIdx = 0; ucIdx < ucAlpha2Size; ucIdx++) + u4CountryCode |= (pcAlpha2[ucIdx] << (ucIdx * 8)); + + return u4CountryCode; +} + +uint8_t rlmDomainTxPwrLimitGetTableVersion( + uint8_t *pucBuf, uint32_t u4BufLen) +{ +#define TX_PWR_LIMIT_VERSION_STR_LEN 7 +#define TX_PWR_LIMIT_MAX_VERSION 1 + uint32_t u4TmpPos = 0; + uint8_t ucVersion = 0; + + while (u4TmpPos < u4BufLen && pucBuf[u4TmpPos] != '<') + u4TmpPos++; + + if (u4TmpPos >= (u4BufLen - TX_PWR_LIMIT_VERSION_STR_LEN)) + return ucVersion; + + if (kalStrnCmp(&pucBuf[u4TmpPos + 1], "Ver:", 4) == 0) { + ucVersion = (pucBuf[u4TmpPos + 5] - '0') * 10 + + (pucBuf[u4TmpPos + 6] - '0'); + } + + if (ucVersion > TX_PWR_LIMIT_MAX_VERSION) + ucVersion = 0; + + return ucVersion; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Search the tx power limit setting range of the specified in the text + * file + * + * \param[IN] u4CountryCode The u32 type of the specified country. + * \param[IN] pucBuf The content of the text file. + * \param[IN] u4cBufLen End boundary of the text file. + * \param[OUT] pu4CountryStart Store the start position of the desired country + * settings. + * \param[OUT] pu4CountryEnd Store the end position of the desired country + * settings. + * + * \retval TRUE Success. + * \retval FALSE Failure. + */ +/*----------------------------------------------------------------------------*/ +u_int8_t rlmDomainTxPwrLimitGetCountryRange( + uint32_t u4CountryCode, uint8_t *pucBuf, uint32_t u4BufLen, + uint32_t *pu4CountryStart, uint32_t *pu4CountryEnd) +{ + uint32_t u4TmpPos = 0; + char pcrCountryStr[TX_PWR_LIMIT_COUNTRY_STR_MAX_LEN + 1] = {0}; + uint8_t cIdx = 0; + + while (1) { + while (u4TmpPos < u4BufLen && pucBuf[u4TmpPos] != '[') + u4TmpPos++; + + u4TmpPos++; /* skip the '[' char */ + + cIdx = 0; + while ((u4TmpPos < u4BufLen) && + (cIdx < TX_PWR_LIMIT_COUNTRY_STR_MAX_LEN) && + (pucBuf[u4TmpPos] != ']')) { + pcrCountryStr[cIdx++] = pucBuf[u4TmpPos]; + u4TmpPos++; + } + + u4TmpPos++; /* skip the ']' char */ + + if ((u4TmpPos >= u4BufLen) || + (cIdx > TX_PWR_LIMIT_COUNTRY_STR_MAX_LEN)) + return FALSE; + + if (u4CountryCode == + rlmDomainAlpha2ToU32(pcrCountryStr, cIdx)) { + DBGLOG(RLM, INFO, + "Found TxPwrLimit table for CountryCode \"%s\"\n", + pcrCountryStr); + *pu4CountryStart = u4TmpPos; + /* the location after char ']' */ + break; + } + } + + while (u4TmpPos < u4BufLen && pucBuf[u4TmpPos] != '[') + u4TmpPos++; + + *pu4CountryEnd = u4TmpPos; + + return TRUE; +} + +u_int8_t rlmDomainTxPwrLimitSearchSection(const char *pSectionName, + uint8_t *pucBuf, uint32_t *pu4Pos, uint32_t u4BufEnd) +{ + uint32_t u4TmpPos = *pu4Pos; + uint8_t uSectionNameLen = kalStrLen(pSectionName); + + while (1) { + while (u4TmpPos < u4BufEnd && pucBuf[u4TmpPos] != '<') + u4TmpPos++; + + u4TmpPos++; /* skip char '<' */ + + if (u4TmpPos + uSectionNameLen >= u4BufEnd) + return FALSE; + + if (kalStrnCmp(&pucBuf[u4TmpPos], + pSectionName, uSectionNameLen) == 0) { + + /* Go to the end of section header line */ + while ((u4TmpPos < u4BufEnd) && + (pucBuf[u4TmpPos] != '\n')) + u4TmpPos++; + + *pu4Pos = u4TmpPos; + + break; + } + } + + return TRUE; +} + +u_int8_t rlmDomainTxPwrLimitSectionEnd(uint8_t *pucBuf, + const char *pSectionName, uint32_t *pu4Pos, uint32_t u4BufEnd) +{ + uint32_t u4TmpPos = *pu4Pos; + char cTmpChar = 0; + uint8_t uSectionNameLen = kalStrLen(pSectionName); + + while (u4TmpPos < u4BufEnd) { + cTmpChar = pucBuf[u4TmpPos]; + + /* skip blank lines */ + if (cTmpChar == ' ' || cTmpChar == '\t' || + cTmpChar == '\n' || cTmpChar == '\r') { + u4TmpPos++; + continue; + } + + break; + } + + /* 2 means '/' and '>' */ + if (u4TmpPos + uSectionNameLen + 2 >= u4BufEnd) { + *pu4Pos = u4BufEnd; + return FALSE; + } + + if (pucBuf[u4TmpPos] != '<') + return FALSE; + + if (pucBuf[u4TmpPos + 1] != '/' || + pucBuf[u4TmpPos + 2 + uSectionNameLen] != '>' || + kalStrnCmp(&pucBuf[u4TmpPos + 2], + pSectionName, uSectionNameLen)) { + + *pu4Pos = u4TmpPos + uSectionNameLen + 2; + return FALSE; + } + + /* 3 means go to the location after '>' */ + *pu4Pos = u4TmpPos + uSectionNameLen + 3; + return TRUE; +} + +int8_t rlmDomainTxPwrLimitGetChIdx( + struct TX_PWR_LIMIT_DATA *pTxPwrLimit, uint8_t ucChannel) +{ + int8_t cIdx = 0; + + for (cIdx = 0; cIdx < pTxPwrLimit->ucChNum; cIdx++) + if (ucChannel == + pTxPwrLimit->rChannelTxPwrLimit[cIdx].ucChannel) + return cIdx; + + DBGLOG(RLM, ERROR, + "Can't find idx of channel %d in TxPwrLimit data\n", + ucChannel); + + return -1; +} + +u_int8_t rlmDomainTxPwrLimitIsTxBfBackoffSection( + uint8_t ucVersion, uint8_t ucSectionIdx) +{ + if (ucVersion == 1 && ucSectionIdx == 8) + return TRUE; + + return FALSE; +} +u_int8_t rlmDomainTxPwrLimitLoadChannelSetting( + uint8_t ucVersion, uint8_t *pucBuf, uint32_t *pu4Pos, uint32_t u4BufEnd, + struct TX_PWR_LIMIT_DATA *pTxPwrLimit, uint8_t ucSectionIdx) +{ + uint32_t u4TmpPos = *pu4Pos; + char cTmpChar = 0; + struct CHANNEL_TX_PWR_LIMIT *prChTxPwrLimit = NULL; + u_int8_t bNeg = FALSE; + int8_t cLimitValue = 0, cChIdx = 0; + uint8_t ucIdx = 0, ucChannel = 0; + uint8_t ucElementNum = + gTx_Pwr_Limit_Element_Num[ucVersion][ucSectionIdx]; + + /* skip blank lines */ + while (u4TmpPos < u4BufEnd) { + cTmpChar = pucBuf[u4TmpPos]; + + if (cTmpChar == ' ' || cTmpChar == '\t' || + cTmpChar == '\n' || cTmpChar == '\r') { + u4TmpPos++; + continue; + } + + break; + } + + /* current is at the location of 'c', + * check remaining buf length for 'chxxx' + */ + if (u4TmpPos + 5 >= u4BufEnd) { + DBGLOG(RLM, ERROR, + "Invalid location of ch setting: %u/%u\n", + u4TmpPos, u4BufEnd); + return FALSE; + } + + if (pucBuf[u4TmpPos] == 'c' && pucBuf[u4TmpPos + 1] == 'h') { + ucChannel = (pucBuf[u4TmpPos + 2] - '0') * 100 + + (pucBuf[u4TmpPos + 3] - '0') * 10 + + (pucBuf[u4TmpPos + 4] - '0'); + } else { /* invalid format */ + *pu4Pos = u4TmpPos; + DBGLOG(RLM, ERROR, + "Invalid ch setting starting chars: %c%c\n", + pucBuf[u4TmpPos], pucBuf[u4TmpPos + 1]); + + /* goto next line */ + while (*pu4Pos < u4BufEnd && pucBuf[*pu4Pos] != '\n') + (*pu4Pos)++; + + return TRUE; + } + + cChIdx = rlmDomainTxPwrLimitGetChIdx(pTxPwrLimit, ucChannel); + + if (cChIdx == -1) { + *pu4Pos = u4TmpPos; + DBGLOG(RLM, ERROR, "Invalid ch %u %c%c%c\n", ucChannel, + pucBuf[u4TmpPos + 2], + pucBuf[u4TmpPos + 3], pucBuf[u4TmpPos + 4]); + + /* goto next line */ + while (*pu4Pos < u4BufEnd && pucBuf[*pu4Pos] != '\n') + (*pu4Pos)++; + + return TRUE; + } + + u4TmpPos += 5; + + prChTxPwrLimit = &pTxPwrLimit->rChannelTxPwrLimit[cChIdx]; + + /* read the channel TxPwrLimit settings */ + for (ucIdx = 0; ucIdx < ucElementNum; ucIdx++) { + + /* skip blank and comma */ + while (u4TmpPos < u4BufEnd) { + cTmpChar = pucBuf[u4TmpPos]; + + if ((cTmpChar == ' ') || + (cTmpChar == '\t') || + (cTmpChar == ',')) { + u4TmpPos++; + continue; + } + break; + } + + if (u4TmpPos >= u4BufEnd) { + *pu4Pos = u4BufEnd; + DBGLOG(RLM, ERROR, + "Invalid location of ch tx pwr limit val: %u/%u\n", + u4TmpPos, u4BufEnd); + return FALSE; + } + + bNeg = FALSE; + + cTmpChar = pucBuf[u4TmpPos]; + + if (cTmpChar == '-') { + bNeg = TRUE; + u4TmpPos++; + } else { + if (cTmpChar == 'x') { + if (!rlmDomainTxPwrLimitIsTxBfBackoffSection( + ucVersion, ucSectionIdx)) { + prChTxPwrLimit-> + rTxPwrLimitValue + [ucSectionIdx][ucIdx] = + TX_PWR_LIMIT_MAX_VAL; + } else { + prChTxPwrLimit->rTxBfBackoff[ucIdx] = + TX_PWR_LIMIT_MAX_VAL; + } + u4TmpPos++; + continue; + } + } + + cLimitValue = 0; + while (u4TmpPos < u4BufEnd) { + cTmpChar = pucBuf[u4TmpPos]; + + if (cTmpChar < '0' || cTmpChar > '9') + break; + + cLimitValue = (cLimitValue * 10) + (cTmpChar - '0'); + u4TmpPos++; + } + + if (bNeg) + cLimitValue = -cLimitValue; + if (!rlmDomainTxPwrLimitIsTxBfBackoffSection( + ucVersion, ucSectionIdx)) { + prChTxPwrLimit->rTxPwrLimitValue[ucSectionIdx][ucIdx] = + cLimitValue; + } else { + prChTxPwrLimit->rTxBfBackoff[ucIdx] = + cLimitValue; + } + } + + *pu4Pos = u4TmpPos; + return TRUE; +} + +void rlmDomainTxPwrLimitRemoveComments( + uint8_t *pucBuf, uint32_t u4BufLen) +{ + uint32_t u4TmpPos = 0; + char cTmpChar = 0; + + while (u4TmpPos < u4BufLen) { + cTmpChar = pucBuf[u4TmpPos]; + + if (cTmpChar == '#') { + while (cTmpChar != '\n') { + pucBuf[u4TmpPos] = ' '; + + u4TmpPos++; + if (u4TmpPos >= u4BufLen) + break; + + cTmpChar = pucBuf[u4TmpPos]; + } + } + u4TmpPos++; + } +} + +u_int8_t rlmDomainTxPwrLimitLoad( + struct ADAPTER *prAdapter, uint8_t *pucBuf, uint32_t u4BufLen, + uint8_t ucVersion, uint32_t u4CountryCode, + struct TX_PWR_LIMIT_DATA *pTxPwrLimitData) +{ + uint8_t uSecIdx = 0; + uint8_t ucSecNum = gTx_Pwr_Limit_Section[ucVersion].ucSectionNum; + uint32_t u4CountryStart = 0, u4CountryEnd = 0, u4Pos = 0; + struct TX_PWR_LIMIT_SECTION *prSection = + &gTx_Pwr_Limit_Section[ucVersion]; + uint8_t *prFileName = prAdapter->chip_info->prTxPwrLimitFile; + + + if (!rlmDomainTxPwrLimitGetCountryRange(u4CountryCode, pucBuf, + u4BufLen, &u4CountryStart, &u4CountryEnd)) { + DBGLOG(RLM, ERROR, "Can't find specified table in %s\n", + prFileName); + return FALSE; + } + u4Pos = u4CountryStart; + + for (uSecIdx = 0; uSecIdx < ucSecNum; uSecIdx++) { + const uint8_t *pSecName = + prSection->arSectionNames[uSecIdx]; + if (!rlmDomainTxPwrLimitSearchSection( + pSecName, pucBuf, &u4Pos, + u4CountryEnd)) { + DBGLOG(RLM, ERROR, + "Can't find specified section %s in %s\n", + pSecName, + prFileName); + continue; + } + + DBGLOG(RLM, INFO, "Find specified section %s in %s\n", + pSecName, + prFileName); + + while (!rlmDomainTxPwrLimitSectionEnd(pucBuf, + pSecName, + &u4Pos, u4CountryEnd) && + u4Pos < u4CountryEnd) { + if (!rlmDomainTxPwrLimitLoadChannelSetting( + ucVersion, pucBuf, &u4Pos, u4CountryEnd, + pTxPwrLimitData, uSecIdx)) + return FALSE; + if (rlmDomainTxPwrLimitIsTxBfBackoffSection( + ucVersion, uSecIdx)) + g_bTxBfBackoffExists = TRUE; + } + } + + DBGLOG(RLM, INFO, "Load %s finished\n", prFileName); + return TRUE; +} + +void rlmDomainTxPwrLimitSetChValues( + uint8_t ucVersion, + struct CMD_CHANNEL_POWER_LIMIT_V2 *pCmd, + struct CHANNEL_TX_PWR_LIMIT *pChTxPwrLimit) +{ + uint8_t section = 0, e = 0; + uint8_t ucElementNum = 0; + + pCmd->tx_pwr_dsss_cck = pChTxPwrLimit->rTxPwrLimitValue[0][0]; + pCmd->tx_pwr_dsss_bpsk = pChTxPwrLimit->rTxPwrLimitValue[0][1]; + + /* 6M, 9M */ + pCmd->tx_pwr_ofdm_bpsk = pChTxPwrLimit->rTxPwrLimitValue[0][2]; + /* 12M, 18M */ + pCmd->tx_pwr_ofdm_qpsk = pChTxPwrLimit->rTxPwrLimitValue[0][3]; + /* 24M, 36M */ + pCmd->tx_pwr_ofdm_16qam = pChTxPwrLimit->rTxPwrLimitValue[0][4]; + pCmd->tx_pwr_ofdm_48m = pChTxPwrLimit->rTxPwrLimitValue[0][5]; + pCmd->tx_pwr_ofdm_54m = pChTxPwrLimit->rTxPwrLimitValue[0][6]; + + /* MCS0*/ + pCmd->tx_pwr_ht20_bpsk = pChTxPwrLimit->rTxPwrLimitValue[1][0]; + /* MCS1, MCS2*/ + pCmd->tx_pwr_ht20_qpsk = pChTxPwrLimit->rTxPwrLimitValue[1][1]; + /* MCS3, MCS4*/ + pCmd->tx_pwr_ht20_16qam = pChTxPwrLimit->rTxPwrLimitValue[1][2]; + /* MCS5*/ + pCmd->tx_pwr_ht20_mcs5 = pChTxPwrLimit->rTxPwrLimitValue[1][3]; + /* MCS6*/ + pCmd->tx_pwr_ht20_mcs6 = pChTxPwrLimit->rTxPwrLimitValue[1][4]; + /* MCS7*/ + pCmd->tx_pwr_ht20_mcs7 = pChTxPwrLimit->rTxPwrLimitValue[1][5]; + + /* MCS0*/ + pCmd->tx_pwr_ht40_bpsk = pChTxPwrLimit->rTxPwrLimitValue[2][0]; + /* MCS1, MCS2*/ + pCmd->tx_pwr_ht40_qpsk = pChTxPwrLimit->rTxPwrLimitValue[2][1]; + /* MCS3, MCS4*/ + pCmd->tx_pwr_ht40_16qam = pChTxPwrLimit->rTxPwrLimitValue[2][2]; + /* MCS5*/ + pCmd->tx_pwr_ht40_mcs5 = pChTxPwrLimit->rTxPwrLimitValue[2][3]; + /* MCS6*/ + pCmd->tx_pwr_ht40_mcs6 = pChTxPwrLimit->rTxPwrLimitValue[2][4]; + /* MCS7*/ + pCmd->tx_pwr_ht40_mcs7 = pChTxPwrLimit->rTxPwrLimitValue[2][5]; + /* MCS32*/ + pCmd->tx_pwr_ht40_mcs32 = pChTxPwrLimit->rTxPwrLimitValue[2][6]; + + /* MCS0*/ + pCmd->tx_pwr_vht20_bpsk = pChTxPwrLimit->rTxPwrLimitValue[3][0]; + /* MCS1, MCS2*/ + pCmd->tx_pwr_vht20_qpsk = pChTxPwrLimit->rTxPwrLimitValue[3][1]; + /* MCS3, MCS4*/ + pCmd->tx_pwr_vht20_16qam = pChTxPwrLimit->rTxPwrLimitValue[3][2]; + /* MCS5, MCS6*/ + pCmd->tx_pwr_vht20_64qam = pChTxPwrLimit->rTxPwrLimitValue[3][3]; + pCmd->tx_pwr_vht20_mcs7 = pChTxPwrLimit->rTxPwrLimitValue[3][4]; + pCmd->tx_pwr_vht20_mcs8 = pChTxPwrLimit->rTxPwrLimitValue[3][5]; + pCmd->tx_pwr_vht20_mcs9 = pChTxPwrLimit->rTxPwrLimitValue[3][6]; + + pCmd->tx_pwr_vht_40 = pChTxPwrLimit->rTxPwrLimitValue[4][2]; + pCmd->tx_pwr_vht_80 = pChTxPwrLimit->rTxPwrLimitValue[4][3]; + pCmd->tx_pwr_vht_160c = pChTxPwrLimit->rTxPwrLimitValue[4][5]; + pCmd->tx_pwr_vht_160nc = pChTxPwrLimit->rTxPwrLimitValue[4][4]; + pCmd->tx_pwr_lg_40 = pChTxPwrLimit->rTxPwrLimitValue[4][0]; + pCmd->tx_pwr_lg_80 = pChTxPwrLimit->rTxPwrLimitValue[4][1]; + + + DBGLOG(RLM, TRACE, "ch %d\n", pCmd->ucCentralCh); + for (section = 0; section < TX_PWR_LIMIT_SECTION_NUM; section++) { + struct TX_PWR_LIMIT_SECTION *pSection = + &gTx_Pwr_Limit_Section[ucVersion]; + ucElementNum = gTx_Pwr_Limit_Element_Num[ucVersion][section]; + for (e = 0; e < ucElementNum; e++) + DBGLOG(RLM, TRACE, "TxPwrLimit[%s][%s]= %d\n", + pSection->arSectionNames[section], + gTx_Pwr_Limit_Element[ucVersion][section][e], + pChTxPwrLimit->rTxPwrLimitValue[section][e]); + } +} + +void rlmDomainTxPwrLimitPerRateSetChValues( + uint8_t ucVersion, + struct CMD_TXPOWER_CHANNEL_POWER_LIMIT_PER_RATE *pCmd, + struct CHANNEL_TX_PWR_LIMIT *pChTxPwrLimit) +{ + uint8_t section = 0, e = 0, count = 0; + uint8_t ucElementNum = 0; + + for (section = 0; section < TX_PWR_LIMIT_SECTION_NUM; section++) { + if (rlmDomainTxPwrLimitIsTxBfBackoffSection(ucVersion, section)) + continue; + ucElementNum = gTx_Pwr_Limit_Element_Num[ucVersion][section]; + for (e = 0; e < ucElementNum; e++) { + pCmd->aucTxPwrLimit.i1PwrLimit[count] = + pChTxPwrLimit->rTxPwrLimitValue[section][e]; + count++; + } + } + + DBGLOG(RLM, TRACE, "ch %d\n", pCmd->u1CentralCh); + count = 0; + for (section = 0; section < TX_PWR_LIMIT_SECTION_NUM; section++) { + struct TX_PWR_LIMIT_SECTION *pSection = + &gTx_Pwr_Limit_Section[ucVersion]; + if (rlmDomainTxPwrLimitIsTxBfBackoffSection(ucVersion, section)) + continue; + ucElementNum = gTx_Pwr_Limit_Element_Num[ucVersion][section]; + for (e = 0; e < ucElementNum; e++) { + DBGLOG(RLM, TRACE, "TxPwrLimit[%s][%s]= %d\n", + pSection->arSectionNames[section], + gTx_Pwr_Limit_Element[ucVersion][section][e], + pCmd->aucTxPwrLimit.i1PwrLimit[count]); + count++; + } + } +} + +void rlmDomainTxPwrLimitSetValues( + uint8_t ucVersion, + struct CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_V2 *pSetCmd, + struct TX_PWR_LIMIT_DATA *pTxPwrLimit) +{ + uint8_t ucIdx = 0; + int8_t cChIdx = 0; + struct CMD_CHANNEL_POWER_LIMIT_V2 *pCmd = NULL; + struct CHANNEL_TX_PWR_LIMIT *pChTxPwrLimit = NULL; + + if (!pSetCmd || !pTxPwrLimit) { + DBGLOG(RLM, ERROR, "Invalid TxPwrLimit request\n"); + return; + } + + for (ucIdx = 0; ucIdx < pSetCmd->ucNum; ucIdx++) { + pCmd = &(pSetCmd->rChannelPowerLimit[ucIdx]); + cChIdx = rlmDomainTxPwrLimitGetChIdx(pTxPwrLimit, + pCmd->ucCentralCh); + if (cChIdx == -1) { + DBGLOG(RLM, ERROR, + "Invalid ch idx found while assigning values\n"); + continue; + } + pChTxPwrLimit = &pTxPwrLimit->rChannelTxPwrLimit[cChIdx]; + rlmDomainTxPwrLimitSetChValues(ucVersion, pCmd, pChTxPwrLimit); + } +} + +void rlmDomainTxPwrLimitPerRateSetValues( + uint8_t ucVersion, + struct CMD_SET_TXPOWER_COUNTRY_TX_POWER_LIMIT_PER_RATE *pSetCmd, + struct TX_PWR_LIMIT_DATA *pTxPwrLimit) +{ + uint8_t ucIdx = 0; + int8_t cChIdx = 0; + struct CMD_TXPOWER_CHANNEL_POWER_LIMIT_PER_RATE *pChPwrLimit = NULL; + struct CHANNEL_TX_PWR_LIMIT *pChTxPwrLimit = NULL; + + if (pSetCmd == NULL) + return; + + for (ucIdx = 0; ucIdx < pSetCmd->ucNum; ucIdx++) { + pChPwrLimit = &(pSetCmd->rChannelPowerLimit[ucIdx]); + cChIdx = rlmDomainTxPwrLimitGetChIdx(pTxPwrLimit, + pChPwrLimit->u1CentralCh); + + if (cChIdx == -1) { + DBGLOG(RLM, ERROR, + "Invalid ch idx found while assigning values\n"); + continue; + } + pChTxPwrLimit = &pTxPwrLimit->rChannelTxPwrLimit[cChIdx]; + rlmDomainTxPwrLimitPerRateSetChValues(ucVersion, + pChPwrLimit, pChTxPwrLimit); + } +} + +u_int8_t rlmDomainTxPwrLimitLoadFromFile( + struct ADAPTER *prAdapter, + uint8_t *pucConfigBuf, uint32_t *pu4ConfigReadLen) +{ +#define TXPWRLIMIT_FILE_LEN 64 + u_int8_t bRet = TRUE; + uint8_t *prFileName = prAdapter->chip_info->prTxPwrLimitFile; + uint8_t aucPath[4][TXPWRLIMIT_FILE_LEN]; + + kalMemZero(aucPath, sizeof(aucPath)); + kalSnprintf(aucPath[0], TXPWRLIMIT_FILE_LEN, "%s", prFileName); + kalSnprintf(aucPath[1], TXPWRLIMIT_FILE_LEN, + "/data/misc/%s", prFileName); + kalSnprintf(aucPath[2], TXPWRLIMIT_FILE_LEN, + "/data/misc/wifi/%s", prFileName); + kalSnprintf(aucPath[3], TXPWRLIMIT_FILE_LEN, + "/storage/sdcard0/%s", prFileName); + + kalMemZero(pucConfigBuf, WLAN_TX_PWR_LIMIT_FILE_BUF_SIZE); + *pu4ConfigReadLen = 0; + + if (wlanGetFileContent( + prAdapter, + aucPath[0], + pucConfigBuf, + WLAN_TX_PWR_LIMIT_FILE_BUF_SIZE, + pu4ConfigReadLen, TRUE) == 0) { + /* ToDo:: Nothing */ + } else if (wlanGetFileContent( + prAdapter, + aucPath[1], + pucConfigBuf, + WLAN_TX_PWR_LIMIT_FILE_BUF_SIZE, + pu4ConfigReadLen, FALSE) == 0) { + /* ToDo:: Nothing */ + } else if (wlanGetFileContent( + prAdapter, + aucPath[2], + pucConfigBuf, + WLAN_TX_PWR_LIMIT_FILE_BUF_SIZE, + pu4ConfigReadLen, FALSE) == 0) { + /* ToDo:: Nothing */ + } else if (wlanGetFileContent( + prAdapter, + aucPath[3], + pucConfigBuf, + WLAN_TX_PWR_LIMIT_FILE_BUF_SIZE, + pu4ConfigReadLen, FALSE) == 0) { + /* ToDo:: Nothing */ + } else { + bRet = FALSE; + goto error; + } + + if (pucConfigBuf[0] == '\0' || *pu4ConfigReadLen == 0) { + bRet = FALSE; + goto error; + } + +error: + + return bRet; +} + +u_int8_t rlmDomainGetTxPwrLimit( + uint32_t country_code, + uint8_t *pucVersion, + struct GLUE_INFO *prGlueInfo, + struct TX_PWR_LIMIT_DATA *pTxPwrLimitData) +{ + u_int8_t bRet = TRUE; + uint8_t *pucConfigBuf = NULL; + uint32_t u4ConfigReadLen = 0; + + pucConfigBuf = (uint8_t *) kalMemAlloc( + WLAN_TX_PWR_LIMIT_FILE_BUF_SIZE, VIR_MEM_TYPE); + + if (!pucConfigBuf) + return FALSE; + + bRet = rlmDomainTxPwrLimitLoadFromFile(prGlueInfo->prAdapter, + pucConfigBuf, &u4ConfigReadLen); + + rlmDomainTxPwrLimitRemoveComments(pucConfigBuf, u4ConfigReadLen); + *pucVersion = rlmDomainTxPwrLimitGetTableVersion(pucConfigBuf, + u4ConfigReadLen); + + if (!rlmDomainTxPwrLimitLoad(prGlueInfo->prAdapter, + pucConfigBuf, u4ConfigReadLen, *pucVersion, + country_code, pTxPwrLimitData)) { + bRet = FALSE; + goto error; + } + +error: + + kalMemFree(pucConfigBuf, + VIR_MEM_TYPE, WLAN_TX_PWR_LIMIT_FILE_BUF_SIZE); + + return bRet; +} + +#endif + +#if CFG_SUPPORT_PWR_LIMIT_COUNTRY + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Check if power limit setting is in the range [MIN_TX_POWER, + * MAX_TX_POWER] + * + * @param[in] + * + * @return (fgValid) : 0 -> inValid, 1 -> Valid + */ +/*----------------------------------------------------------------------------*/ +u_int8_t +rlmDomainCheckPowerLimitValid(struct ADAPTER *prAdapter, + struct COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION + rPowerLimitTableConfiguration, + uint8_t ucPwrLimitNum) +{ + uint16_t i; + u_int8_t fgValid = TRUE; + int8_t *prPwrLimit; + + prPwrLimit = &rPowerLimitTableConfiguration.aucPwrLimit[0]; + + for (i = 0; i < ucPwrLimitNum; i++, prPwrLimit++) { + if (*prPwrLimit > MAX_TX_POWER || *prPwrLimit < MIN_TX_POWER) { + fgValid = FALSE; + break; /*Find out Wrong Power limit */ + } + } + return fgValid; + +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief 1.Check if power limit configuration table valid(channel intervel) + * 2.Check if power limit configuration/default table entry repeat + * + * @param[in] + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void rlmDomainCheckCountryPowerLimitTable(struct ADAPTER *prAdapter) +{ +#define PwrLmtConf g_rRlmPowerLimitConfiguration + uint16_t i, j; + uint16_t u2CountryCodeTable, u2CountryCodeCheck; + u_int8_t fgChannelValid = FALSE; + u_int8_t fgPowerLimitValid = FALSE; + u_int8_t fgEntryRepetetion = FALSE; + u_int8_t fgTableValid = TRUE; + + /*1.Configuration Table Check */ + for (i = 0; i < sizeof(PwrLmtConf) / + sizeof(struct COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION); i++) { + /*Table Country Code */ + WLAN_GET_FIELD_BE16(&PwrLmtConf[i].aucCountryCode[0], + &u2CountryCodeTable); + + /*<1>Repetition Entry Check */ + for (j = i + 1; j < sizeof(PwrLmtConf) / + sizeof(struct COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION); + j++) { + + WLAN_GET_FIELD_BE16(&PwrLmtConf[j].aucCountryCode[0], + &u2CountryCodeCheck); + if (((PwrLmtConf[i].ucCentralCh) == + PwrLmtConf[j].ucCentralCh) + && (u2CountryCodeTable == u2CountryCodeCheck)) { + fgEntryRepetetion = TRUE; + DBGLOG(RLM, LOUD, + "Domain: Configuration Repetition CC=%c%c, Ch=%d\n", + PwrLmtConf[i].aucCountryCode[0], + PwrLmtConf[i].aucCountryCode[1], + PwrLmtConf[i].ucCentralCh); + } + } + + /*<2>Channel Number Interval Check */ + fgChannelValid = + rlmDomainCheckChannelEntryValid(prAdapter, + PwrLmtConf[i].ucCentralCh); + + /*<3>Power Limit Range Check */ + fgPowerLimitValid = + rlmDomainCheckPowerLimitValid(prAdapter, + PwrLmtConf[i], + PWR_LIMIT_NUM); + + if (fgChannelValid == FALSE || fgPowerLimitValid == FALSE) { + fgTableValid = FALSE; + DBGLOG(RLM, LOUD, + "Domain: CC=%c%c, Ch=%d, Limit: %d,%d,%d,%d,%d,%d,%d,%d,%d, Valid:%d,%d\n", + PwrLmtConf[i].aucCountryCode[0], + PwrLmtConf[i].aucCountryCode[1], + PwrLmtConf[i].ucCentralCh, + PwrLmtConf[i].aucPwrLimit[PWR_LIMIT_CCK], + PwrLmtConf[i].aucPwrLimit[PWR_LIMIT_20M_L], + PwrLmtConf[i].aucPwrLimit[PWR_LIMIT_20M_H], + PwrLmtConf[i].aucPwrLimit[PWR_LIMIT_40M_L], + PwrLmtConf[i].aucPwrLimit[PWR_LIMIT_40M_H], + PwrLmtConf[i].aucPwrLimit[PWR_LIMIT_80M_L], + PwrLmtConf[i].aucPwrLimit[PWR_LIMIT_80M_H], + PwrLmtConf[i].aucPwrLimit[PWR_LIMIT_160M_L], + PwrLmtConf[i].aucPwrLimit[PWR_LIMIT_160M_H], + fgChannelValid, + fgPowerLimitValid); + } + + if (u2CountryCodeTable == COUNTRY_CODE_NULL) { + DBGLOG(RLM, LOUD, "Domain: Full search down\n"); + break; /*End of country table entry */ + } + + } + + if (fgEntryRepetetion == FALSE) + DBGLOG(RLM, TRACE, + "Domain: Configuration Table no Repetiton.\n"); + + /*Configuration Table no error */ + if (fgTableValid == TRUE) + prAdapter->fgIsPowerLimitTableValid = TRUE; + else + prAdapter->fgIsPowerLimitTableValid = FALSE; + + /*2.Default Table Repetition Entry Check */ + fgEntryRepetetion = FALSE; + for (i = 0; i < sizeof(g_rRlmPowerLimitDefault) / + sizeof(struct COUNTRY_POWER_LIMIT_TABLE_DEFAULT); i++) { + + WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitDefault[i]. + aucCountryCode[0], + &u2CountryCodeTable); + + for (j = i + 1; j < sizeof(g_rRlmPowerLimitDefault) / + sizeof(struct COUNTRY_POWER_LIMIT_TABLE_DEFAULT); j++) { + WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitDefault[j]. + aucCountryCode[0], + &u2CountryCodeCheck); + if (u2CountryCodeTable == u2CountryCodeCheck) { + fgEntryRepetetion = TRUE; + DBGLOG(RLM, LOUD, + "Domain: Default Repetition CC=%c%c\n", + g_rRlmPowerLimitDefault[j]. + aucCountryCode[0], + g_rRlmPowerLimitDefault[j]. + aucCountryCode[1]); + } + } + } + if (fgEntryRepetetion == FALSE) + DBGLOG(RLM, TRACE, "Domain: Default Table no Repetiton.\n"); +#undef PwrLmtConf +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief + * + * @param[in] + * + * @return (u2TableIndex) : if 0xFFFF -> No Table Match + */ +/*----------------------------------------------------------------------------*/ +uint16_t rlmDomainPwrLimitDefaultTableDecision(struct ADAPTER *prAdapter, + uint16_t u2CountryCode) +{ + + uint16_t i; + uint16_t u2CountryCodeTable = COUNTRY_CODE_NULL; + uint16_t u2TableIndex = POWER_LIMIT_TABLE_NULL; /* No Table Match */ + + /*Default Table Index */ + for (i = 0; i < sizeof(g_rRlmPowerLimitDefault) / + sizeof(struct COUNTRY_POWER_LIMIT_TABLE_DEFAULT); i++) { + + WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitDefault[i]. + aucCountryCode[0], + &u2CountryCodeTable); + + if (u2CountryCodeTable == u2CountryCode) { + u2TableIndex = i; + break; /*match country code */ + } else if (u2CountryCodeTable == COUNTRY_CODE_NULL) { + u2TableIndex = i; + break; /*find last one country- Default */ + } + } + + return u2TableIndex; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Fill power limit CMD by Power Limit Default Table(regulation) + * + * @param[in] + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void +rlmDomainBuildCmdByDefaultTable(struct CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT + *prCmd, + uint16_t u2DefaultTableIndex) +{ + uint16_t i, k; + struct COUNTRY_POWER_LIMIT_TABLE_DEFAULT *prPwrLimitSubBand = NULL; + struct CMD_CHANNEL_POWER_LIMIT *prPwrLimit = NULL; + struct CMD_CHANNEL_POWER_LIMIT_HE *prPwrLmtHE = NULL; + enum ENUM_PWR_LIMIT_TYPE eType; + + int8_t cLmtBand = 0; + + ASSERT(prCmd); + + prPwrLimitSubBand = &g_rRlmPowerLimitDefault[u2DefaultTableIndex]; + eType = prCmd->ucLimitType; + + if (eType == PWR_LIMIT_TYPE_COMP_11AX) + prPwrLmtHE = &prCmd->u.rChPwrLimtHE[0]; + else + prPwrLimit = &prCmd->u.rChannelPowerLimit[0]; + + + /*Build power limit cmd by default table information */ + + for (i = POWER_LIMIT_2G4; i < POWER_LIMIT_SUBAND_NUM; i++) { + + cLmtBand = prPwrLimitSubBand->aucPwrLimitSubBand[i]; + + if (prPwrLimitSubBand->aucPwrLimitSubBand[i] > MAX_TX_POWER) { + DBGLOG(RLM, WARN, "SubBand[%d] Pwr(%d) > Max (%d)", + prPwrLimitSubBand->aucPwrLimitSubBand[i], + MAX_TX_POWER); + cLmtBand = MAX_TX_POWER; + } + + for (k = g_rRlmSubBand[i].ucStartCh; + k <= g_rRlmSubBand[i].ucEndCh; + k += g_rRlmSubBand[i].ucInterval) { + + if (eType == PWR_LIMIT_TYPE_COMP_11AX) + prPwrLmtHE->ucCentralCh = k; + else + prPwrLimit->ucCentralCh = k; + + if ((prPwrLimitSubBand->ucPwrUnit + & BIT(i)) == 0) { + + if (eType == PWR_LIMIT_TYPE_COMP_11AX) + kalMemSet(&prPwrLmtHE->cPwrLimitRU26L, + cLmtBand, + PWR_LIMIT_HE_NUM); + else + kalMemSet(&prPwrLimit->cPwrLimitCCK, + cLmtBand, + PWR_LIMIT_NUM); + } else { + /* ex: 40MHz power limit(mW\MHz) + * = 20MHz power limit(mW\MHz) * 2 + * ---> 40MHz power limit(dBm) + * = 20MHz power limit(dBm) + 6; + */ + + if (eType == PWR_LIMIT_TYPE_COMP_11AX) { + /* BW20 */ + prPwrLmtHE->cPwrLimitRU26L = cLmtBand; + prPwrLmtHE->cPwrLimitRU26H = cLmtBand; + prPwrLmtHE->cPwrLimitRU26U = cLmtBand; + + prPwrLmtHE->cPwrLimitRU52L = cLmtBand; + prPwrLmtHE->cPwrLimitRU52H = cLmtBand; + prPwrLmtHE->cPwrLimitRU52U = cLmtBand; + + prPwrLmtHE->cPwrLimitRU106L = cLmtBand; + prPwrLmtHE->cPwrLimitRU106H = cLmtBand; + prPwrLmtHE->cPwrLimitRU106U = cLmtBand; + + prPwrLmtHE->cPwrLimitRU242L = cLmtBand; + prPwrLmtHE->cPwrLimitRU242H = cLmtBand; + prPwrLmtHE->cPwrLimitRU242U = cLmtBand; + + } else { + /* BW20 */ + prPwrLimit->cPwrLimitCCK = cLmtBand; +#if (CFG_SUPPORT_DYNA_TX_PWR_CTRL_OFDM_SETTING == 1) + prPwrLimit->cPwrLimitOFDM_L = cLmtBand; + prPwrLimit->cPwrLimitOFDM_H = cLmtBand; +#endif /* CFG_SUPPORT_DYNA_TX_PWR_CTRL_OFDM_SETTING */ + prPwrLimit->cPwrLimit20L = cLmtBand; + prPwrLimit->cPwrLimit20H = cLmtBand; + } + + /* BW40 */ + cLmtBand += 6; + + if (cLmtBand > MAX_TX_POWER) + cLmtBand = MAX_TX_POWER; + + if (eType == PWR_LIMIT_TYPE_COMP_11AX) { + prPwrLmtHE->cPwrLimitRU484L = cLmtBand; + prPwrLmtHE->cPwrLimitRU484H = cLmtBand; + prPwrLmtHE->cPwrLimitRU484U = cLmtBand; + } else { + prPwrLimit->cPwrLimit40L = cLmtBand; + prPwrLimit->cPwrLimit40H = cLmtBand; + } + + /* BW80 */ + cLmtBand += 6; + if (cLmtBand > MAX_TX_POWER) + cLmtBand = MAX_TX_POWER; + + if (eType == PWR_LIMIT_TYPE_COMP_11AX) { + prPwrLmtHE->cPwrLimitRU996L = cLmtBand; + prPwrLmtHE->cPwrLimitRU996H = cLmtBand; + prPwrLmtHE->cPwrLimitRU996U = cLmtBand; + + } else { + prPwrLimit->cPwrLimit80L = cLmtBand; + prPwrLimit->cPwrLimit80H = cLmtBand; + } + + /* BW160 */ + cLmtBand += 6; + if (cLmtBand > MAX_TX_POWER) + cLmtBand = MAX_TX_POWER; + if (eType == PWR_LIMIT_TYPE_COMP_11AX) { + /* prPwrLmtHE do nothing */ + } else { + prPwrLimit->cPwrLimit160L = cLmtBand; + prPwrLimit->cPwrLimit160H = cLmtBand; + } + + } + /* save to power limit array per + * subband channel + */ + if (eType == PWR_LIMIT_TYPE_COMP_11AX) + prPwrLmtHE++; + else + prPwrLimit++; + + prCmd->ucNum++; + + if (prCmd->ucNum >= MAX_CMD_SUPPORT_CHANNEL_NUM) + DBGLOG(RLM, WARN, "out of MAX CH Num\n"); + + } + } + + DBGLOG(RLM, STATE, "Build Default Limit(%c%c)ChNum=%d,typde=%d\n", + ((prCmd->u2CountryCode & + 0xff00) >> 8), + (prCmd->u2CountryCode & + 0x00ff), + prCmd->ucNum, + eType); + +} + +void rlmDomainCopyFromConfigTable(struct CMD_CHANNEL_POWER_LIMIT *prCmdPwrLimit, + struct COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION *prPwrLimitConfig) +{ + + +#if (CFG_SUPPORT_DYNA_TX_PWR_CTRL_OFDM_SETTING == 1) + /*remapping from old setting to new setting*/ + prCmdPwrLimit->cPwrLimitCCK = + prPwrLimitConfig->aucPwrLimit[PWR_LIMIT_CCK]; + prCmdPwrLimit->cPwrLimitOFDM_L = + prPwrLimitConfig->aucPwrLimit[PWR_LIMIT_OFDM_L]; + prCmdPwrLimit->cPwrLimitOFDM_H = + prPwrLimitConfig->aucPwrLimit[PWR_LIMIT_OFDM_H]; + kalMemCopy(&prCmdPwrLimit->cPwrLimit20L, + &prPwrLimitConfig->aucPwrLimit[PWR_LIMIT_OFDM_L], + PWR_LIMIT_NUM - 5); +#else + kalMemCopy(&prCmdPwrLimit->cPwrLimitCCK, + &prPwrLimitConfig->aucPwrLimit[0], + PWR_LIMIT_NUM); +#endif /* CFG_SUPPORT_DYNA_TX_PWR_CTRL_OFDM_SETTING */ +} + + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Fill power limit CMD by Power Limit Configurartion Table + * (Bandedge and Customization) + * + * @param[in] + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void rlmDomainBuildCmdByConfigTable(struct ADAPTER *prAdapter, + struct CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT *prCmd) +{ +#define PwrLmtConf g_rRlmPowerLimitConfiguration +#define PwrLmtConfHE g_rRlmPowerLimitConfigurationHE + uint16_t i, k; + uint16_t u2CountryCodeTable = COUNTRY_CODE_NULL; + enum ENUM_PWR_LIMIT_TYPE eType; + struct CMD_CHANNEL_POWER_LIMIT *prCmdPwrLimit; + struct CMD_CHANNEL_POWER_LIMIT_HE *prCmdPwrLimtHE; + u_int8_t fgChannelValid; + uint8_t ucCentCh; + uint8_t ucPwrLmitConfSize = sizeof(PwrLmtConf) / + sizeof(struct COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION); + + uint8_t ucPwrLmitConfSizeHE = sizeof(PwrLmtConfHE) / + sizeof(struct COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION_HE); + + eType = prCmd->ucLimitType; + /*Build power limit cmd by configuration table information */ + + for (k = 0; k < prCmd->ucNum; k++) { + + if (k >= MAX_CMD_SUPPORT_CHANNEL_NUM) { + DBGLOG(RLM, ERROR, "out of MAX CH Num\n"); + return; + } + + if (eType == PWR_LIMIT_TYPE_COMP_11AX) { + prCmdPwrLimtHE = &prCmd->u.rChPwrLimtHE[k]; + ucCentCh = prCmdPwrLimtHE->ucCentralCh; + + for (i = 0; i < ucPwrLmitConfSizeHE ; i++) { + + WLAN_GET_FIELD_BE16( + &PwrLmtConfHE[i].aucCountryCode[0], + &u2CountryCodeTable); + + fgChannelValid = + rlmDomainCheckChannelEntryValid(prAdapter, + PwrLmtConfHE[i].ucCentralCh); + + if (u2CountryCodeTable == COUNTRY_CODE_NULL) + break; /*end of configuration table */ + else if (u2CountryCodeTable + != prCmd->u2CountryCode) + continue; + else if (fgChannelValid == FALSE) + continue; + else if (ucCentCh + != PwrLmtConfHE[i].ucCentralCh) + continue; + + /* Cmd setting (Default table + * information) and Conf table + * has repetition channel entry, + * ex : Default table (ex: 2.4G, + * limit = 20dBm) --> + * ch1~14 limit =20dBm, + * Conf table (ex: ch1, limit = + * 22dBm) --> ch 1 = 22 dBm + * Cmd final setting --> ch1 = + * 22dBm, ch2~14 = 20dBm + */ + kalMemCopy(&prCmdPwrLimtHE->cPwrLimitRU26L, + &PwrLmtConfHE[i].aucPwrLimit, + PWR_LIMIT_HE_NUM); + } + + + } else { + prCmdPwrLimit = &prCmd->u.rChannelPowerLimit[k]; + ucCentCh = prCmdPwrLimit->ucCentralCh; + + for (i = 0; i < ucPwrLmitConfSize ; i++) { + + WLAN_GET_FIELD_BE16( + &PwrLmtConf[i].aucCountryCode[0], + &u2CountryCodeTable); + + fgChannelValid = + rlmDomainCheckChannelEntryValid( + prAdapter, + PwrLmtConf[i].ucCentralCh); + + if (u2CountryCodeTable == COUNTRY_CODE_NULL) + break; /*end of configuration table */ + else if (u2CountryCodeTable + != prCmd->u2CountryCode) + continue; + else if (fgChannelValid == FALSE) + continue; + else if (ucCentCh != PwrLmtConf[i].ucCentralCh) + continue; + + /* Cmd setting (Default table + * information) and Conf table + * has repetition channel entry, + * ex : Default table (ex: 2.4G, + * limit = 20dBm) --> + * ch1~14 limit =20dBm, + * Conf table (ex: ch1, limit = + * 22dBm) --> ch 1 = 22 dBm + * Cmd final setting --> ch1 = + * 22dBm, ch2~14 = 20dBm + */ + rlmDomainCopyFromConfigTable( + prCmdPwrLimit, + &PwrLmtConf[i] + ); + } + } + } +#undef PwrLmtConf +#undef PwrLmtConfHE + +} + +struct TX_PWR_LIMIT_DATA * +rlmDomainInitTxPwrLimitData(struct ADAPTER *prAdapter) +{ + uint8_t ch_cnt = 0; + uint8_t ch_idx = 0; + uint8_t band_idx = 0; + uint8_t ch_num = 0; + const int8_t *prChannelList = NULL; + struct TX_PWR_LIMIT_DATA *pTxPwrLimitData = NULL; + struct CHANNEL_TX_PWR_LIMIT *prChTxPwrLimit = NULL; + + pTxPwrLimitData = + (struct TX_PWR_LIMIT_DATA *) + kalMemAlloc(sizeof(struct TX_PWR_LIMIT_DATA), + VIR_MEM_TYPE); + + if (!pTxPwrLimitData) { + DBGLOG(RLM, ERROR, + "Alloc buffer for TxPwrLimit main struct failed\n"); + return NULL; + } + + pTxPwrLimitData->ucChNum = + TX_PWR_LIMIT_2G_CH_NUM + TX_PWR_LIMIT_5G_CH_NUM; + + pTxPwrLimitData->rChannelTxPwrLimit = + (struct CHANNEL_TX_PWR_LIMIT *) + kalMemAlloc(sizeof(struct CHANNEL_TX_PWR_LIMIT) * + (pTxPwrLimitData->ucChNum), VIR_MEM_TYPE); + + if (!pTxPwrLimitData->rChannelTxPwrLimit) { + DBGLOG(RLM, ERROR, + "Alloc buffer for TxPwrLimit ch values failed\n"); + + kalMemFree(pTxPwrLimitData, VIR_MEM_TYPE, + sizeof(struct TX_PWR_LIMIT_DATA)); + return NULL; + } + + for (ch_idx = 0; ch_idx < pTxPwrLimitData->ucChNum; ch_idx++) { + prChTxPwrLimit = + &(pTxPwrLimitData->rChannelTxPwrLimit[ch_idx]); + kalMemSet(prChTxPwrLimit->rTxPwrLimitValue, + MAX_TX_POWER, + sizeof(prChTxPwrLimit->rTxPwrLimitValue)); + kalMemSet(prChTxPwrLimit->rTxBfBackoff, + MAX_TX_POWER, + sizeof(prChTxPwrLimit->rTxBfBackoff)); + } + + ch_cnt = 0; + for (band_idx = 0; band_idx < KAL_NUM_BANDS; band_idx++) { + if (band_idx != KAL_BAND_2GHZ && band_idx != KAL_BAND_5GHZ) + continue; + + prChannelList = (band_idx == KAL_BAND_2GHZ) ? + gTx_Pwr_Limit_2g_Ch : gTx_Pwr_Limit_5g_Ch; + + ch_num = + (band_idx == KAL_BAND_2GHZ) ? + TX_PWR_LIMIT_2G_CH_NUM : + TX_PWR_LIMIT_5G_CH_NUM; + + for (ch_idx = 0; ch_idx < ch_num; ch_idx++) { + pTxPwrLimitData->rChannelTxPwrLimit[ch_cnt].ucChannel = + prChannelList[ch_idx]; + ++ch_cnt; + } + } + + return pTxPwrLimitData; +} + +void +rlmDomainSendTxPwrLimitCmd(struct ADAPTER *prAdapter, + uint8_t ucVersion, + struct TX_PWR_LIMIT_DATA *pTxPwrLimitData) +{ + uint8_t ch_cnt = 0; + uint8_t ch_idx = 0; + uint8_t band_idx = 0; + const int8_t *prChannelList = NULL; + uint32_t rStatus; + uint32_t u4SetQueryInfoLen; + uint32_t u4SetCmdTableMaxSize[KAL_NUM_BANDS] = {0}; + struct CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_V2 + *prCmd[KAL_NUM_BANDS] = {0}; + struct CMD_CHANNEL_POWER_LIMIT_V2 *prCmdChPwrLimitV2 = NULL; + uint32_t u4SetCountryCmdSize = + sizeof(struct CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_V2); + uint32_t u4ChPwrLimitV2Size = sizeof(struct CMD_CHANNEL_POWER_LIMIT_V2); + const uint8_t ucCmdBatchSize = + prAdapter->chip_info->ucTxPwrLimitBatchSize; + + for (band_idx = 0; band_idx < KAL_NUM_BANDS; band_idx++) { + if (band_idx != KAL_BAND_2GHZ && band_idx != KAL_BAND_5GHZ) + continue; + + prChannelList = (band_idx == KAL_BAND_2GHZ) ? + gTx_Pwr_Limit_2g_Ch : gTx_Pwr_Limit_5g_Ch; + + ch_cnt = (band_idx == KAL_BAND_2GHZ) ? TX_PWR_LIMIT_2G_CH_NUM : + TX_PWR_LIMIT_5G_CH_NUM; + + if (!ch_cnt) + continue; + + u4SetCmdTableMaxSize[band_idx] = u4SetCountryCmdSize + + ch_cnt * u4ChPwrLimitV2Size; + + prCmd[band_idx] = cnmMemAlloc(prAdapter, + RAM_TYPE_BUF, u4SetCmdTableMaxSize[band_idx]); + + if (!prCmd[band_idx]) { + DBGLOG(RLM, ERROR, "Domain: no buf to send cmd\n"); + goto error; + } + + /*initialize tw pwr table*/ + kalMemSet(prCmd[band_idx], MAX_TX_POWER, + u4SetCmdTableMaxSize[band_idx]); + + prCmd[band_idx]->ucNum = ch_cnt; + prCmd[band_idx]->eband = + (band_idx == KAL_BAND_2GHZ) ? + BAND_2G4 : BAND_5G; + prCmd[band_idx]->countryCode = rlmDomainGetCountryCode(); + + DBGLOG(RLM, INFO, + "%s, active n_channels=%d, band=%d\n", + __func__, ch_cnt, prCmd[band_idx]->eband); + + for (ch_idx = 0; ch_idx < ch_cnt; ch_idx++) { + prCmdChPwrLimitV2 = + &(prCmd[band_idx]->rChannelPowerLimit[ch_idx]); + prCmdChPwrLimitV2->ucCentralCh = + prChannelList[ch_idx]; + } + } + + rlmDomainTxPwrLimitSetValues(ucVersion, + prCmd[KAL_BAND_2GHZ], pTxPwrLimitData); + rlmDomainTxPwrLimitSetValues(ucVersion, + prCmd[KAL_BAND_5GHZ], pTxPwrLimitData); + + for (band_idx = 0; band_idx < KAL_NUM_BANDS; band_idx++) { + uint8_t ucRemainChNum, i, ucTempChNum, prCmdBatchNum; + uint32_t u4BufSize = 0; + struct CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_V2 *prTempCmd = NULL; + enum ENUM_BAND eBand = (band_idx == KAL_BAND_2GHZ) ? + BAND_2G4 : BAND_5G; + uint16_t u2ChIdx = 0; + + if (!prCmd[band_idx]) + continue; + + ucRemainChNum = prCmd[band_idx]->ucNum; + prCmdBatchNum = (ucRemainChNum + + ucCmdBatchSize - 1) / + ucCmdBatchSize; + + for (i = 0; i < prCmdBatchNum; i++) { + if (i == prCmdBatchNum - 1) + ucTempChNum = ucRemainChNum; + else + ucTempChNum = ucCmdBatchSize; + + u4BufSize = u4SetCountryCmdSize + + ucTempChNum * u4ChPwrLimitV2Size; + + prTempCmd = + cnmMemAlloc(prAdapter, + RAM_TYPE_BUF, u4BufSize); + + if (!prTempCmd) { + DBGLOG(RLM, ERROR, + "Domain: no buf to send cmd\n"); + goto error; + } + + /*copy partial tx pwr limit*/ + prTempCmd->ucNum = ucTempChNum; + prTempCmd->eband = eBand; + prTempCmd->countryCode = rlmDomainGetCountryCode(); + u2ChIdx = i * ucCmdBatchSize; + kalMemCopy(&prTempCmd->rChannelPowerLimit[0], + &prCmd[band_idx]->rChannelPowerLimit[u2ChIdx], + ucTempChNum * u4ChPwrLimitV2Size); + + u4SetQueryInfoLen = u4BufSize; + /* Update tx max. power info to chip */ + rStatus = wlanSendSetQueryCmd(prAdapter, + CMD_ID_SET_COUNTRY_POWER_LIMIT, + TRUE, + FALSE, + FALSE, + NULL, + NULL, + u4SetQueryInfoLen, + (uint8_t *) prTempCmd, + NULL, + 0); + + cnmMemFree(prAdapter, prTempCmd); + + ucRemainChNum -= ucTempChNum; + } + } + +error: + for (band_idx = 0; band_idx < KAL_NUM_BANDS; band_idx++) { + if (prCmd[band_idx]) + cnmMemFree(prAdapter, prCmd[band_idx]); + } +} + +u_int32_t rlmDomainInitTxPwrLimitPerRateCmd( + struct ADAPTER *prAdapter, + struct wiphy *prWiphy, + struct CMD_SET_TXPOWER_COUNTRY_TX_POWER_LIMIT_PER_RATE *prCmd[]) +{ + uint8_t ch_cnt = 0; + uint8_t ch_idx = 0; + uint8_t band_idx = 0; + const int8_t *prChannelList = NULL; + uint32_t u4SetCmdTableMaxSize[KAL_NUM_BANDS] = {0}; + uint32_t u4SetCountryTxPwrLimitCmdSize = + sizeof(struct CMD_SET_TXPOWER_COUNTRY_TX_POWER_LIMIT_PER_RATE); + uint32_t u4ChPwrLimitSize = + sizeof(struct CMD_TXPOWER_CHANNEL_POWER_LIMIT_PER_RATE); + struct CMD_TXPOWER_CHANNEL_POWER_LIMIT_PER_RATE *prChPwrLimit = NULL; + + for (band_idx = 0; band_idx < KAL_NUM_BANDS; band_idx++) { + if (band_idx != KAL_BAND_2GHZ && band_idx != KAL_BAND_5GHZ) + continue; + + prChannelList = (band_idx == KAL_BAND_2GHZ) ? + gTx_Pwr_Limit_2g_Ch : gTx_Pwr_Limit_5g_Ch; + + ch_cnt = (band_idx == KAL_BAND_2GHZ) ? TX_PWR_LIMIT_2G_CH_NUM : + TX_PWR_LIMIT_5G_CH_NUM; + + if (!ch_cnt) + continue; + + u4SetCmdTableMaxSize[band_idx] = u4SetCountryTxPwrLimitCmdSize + + ch_cnt * u4ChPwrLimitSize; + + prCmd[band_idx] = cnmMemAlloc(prAdapter, + RAM_TYPE_BUF, u4SetCmdTableMaxSize[band_idx]); + + if (!prCmd[band_idx]) { + DBGLOG(RLM, ERROR, "Domain: no buf to send cmd\n"); + return WLAN_STATUS_RESOURCES; + } + + /*initialize tx pwr table*/ + kalMemSet(prCmd[band_idx]->rChannelPowerLimit, MAX_TX_POWER, + ch_cnt * u4ChPwrLimitSize); + + prCmd[band_idx]->ucNum = ch_cnt; + prCmd[band_idx]->eBand = + (band_idx == KAL_BAND_2GHZ) ? + BAND_2G4 : BAND_5G; + prCmd[band_idx]->u4CountryCode = rlmDomainGetCountryCode(); + + DBGLOG(RLM, INFO, + "%s, active n_channels=%d, band=%d\n", + __func__, ch_cnt, prCmd[band_idx]->eBand); + + for (ch_idx = 0; ch_idx < ch_cnt; ch_idx++) { + prChPwrLimit = + &(prCmd[band_idx]-> + rChannelPowerLimit[ch_idx]); + prChPwrLimit->u1CentralCh = prChannelList[ch_idx]; + } + + } + + return WLAN_STATUS_SUCCESS; +} + +void rlmDomainTxPwrLimitSendPerRateCmd( + struct ADAPTER *prAdapter, + struct CMD_SET_TXPOWER_COUNTRY_TX_POWER_LIMIT_PER_RATE *prCmd[] +) +{ + uint32_t rStatus; + uint32_t u4SetQueryInfoLen; + uint8_t band_idx = 0; + uint32_t u4SetCountryTxPwrLimitCmdSize = + sizeof(struct CMD_SET_TXPOWER_COUNTRY_TX_POWER_LIMIT_PER_RATE); + uint32_t u4ChPwrLimitSize = + sizeof(struct CMD_TXPOWER_CHANNEL_POWER_LIMIT_PER_RATE); + const uint8_t ucCmdBatchSize = + prAdapter->chip_info->ucTxPwrLimitBatchSize; + + for (band_idx = 0; band_idx < KAL_NUM_BANDS; band_idx++) { + uint8_t ucRemainChNum, i, ucTempChNum, prCmdBatchNum; + uint32_t u4BufSize = 0; + struct CMD_SET_TXPOWER_COUNTRY_TX_POWER_LIMIT_PER_RATE + *prTempCmd = NULL; + enum ENUM_BAND eBand = (band_idx == KAL_BAND_2GHZ) ? + BAND_2G4 : BAND_5G; + uint16_t u2ChIdx = 0; + u_int8_t bCmdFinished = FALSE; + + if (!prCmd[band_idx]) + continue; + + ucRemainChNum = prCmd[band_idx]->ucNum; + prCmdBatchNum = (ucRemainChNum + + ucCmdBatchSize - 1) / + ucCmdBatchSize; + + for (i = 0; i < prCmdBatchNum; i++) { + if (i == prCmdBatchNum - 1) { + ucTempChNum = ucRemainChNum; + bCmdFinished = TRUE; + } else { + ucTempChNum = ucCmdBatchSize; + } + + u4BufSize = u4SetCountryTxPwrLimitCmdSize + + ucTempChNum * u4ChPwrLimitSize; + + prTempCmd = + cnmMemAlloc(prAdapter, + RAM_TYPE_BUF, u4BufSize); + + if (!prTempCmd) { + DBGLOG(RLM, ERROR, + "Domain: no buf to send cmd\n"); + return; + } + + /*copy partial tx pwr limit*/ + prTempCmd->ucNum = ucTempChNum; + prTempCmd->eBand = eBand; + prTempCmd->u4CountryCode = + rlmDomainGetCountryCode(); + prTempCmd->bCmdFinished = bCmdFinished; + u2ChIdx = i * ucCmdBatchSize; + kalMemCopy( + &prTempCmd->rChannelPowerLimit[0], + &prCmd[band_idx]-> + rChannelPowerLimit[u2ChIdx], + ucTempChNum * u4ChPwrLimitSize); + + u4SetQueryInfoLen = u4BufSize; + /* Update tx max. power info to chip */ + rStatus = wlanSendSetQueryCmd(prAdapter, + CMD_ID_SET_COUNTRY_POWER_LIMIT_PER_RATE, + TRUE, + FALSE, + FALSE, + NULL, + NULL, + u4SetQueryInfoLen, + (uint8_t *) prTempCmd, + NULL, + 0); + + cnmMemFree(prAdapter, prTempCmd); + + ucRemainChNum -= ucTempChNum; + } + } +} + +u_int32_t rlmDomainInitTxBfBackoffCmd( + struct ADAPTER *prAdapter, + struct wiphy *prWiphy, + struct CMD_TXPWR_TXBF_SET_BACKOFF **prCmd +) +{ + uint8_t ucChNum = TX_PWR_LIMIT_2G_CH_NUM + TX_PWR_LIMIT_5G_CH_NUM; + uint8_t ucChIdx = 0; + uint8_t ucChCnt = 0; + uint8_t ucBandIdx = 0; + uint8_t ucAisIdx = 0; + uint8_t ucCnt = 0; + const int8_t *prChannelList = NULL; + uint32_t u4SetCmdSize = sizeof(struct CMD_TXPWR_TXBF_SET_BACKOFF); + struct CMD_TXPWR_TXBF_CHANNEL_BACKOFF *prChTxBfBackoff = NULL; + + if (ucChNum >= CMD_POWER_LIMIT_TABLE_SUPPORT_CHANNEL_NUM) { + DBGLOG(RLM, ERROR, "ChNum %d should <= %d\n", + ucChNum, CMD_POWER_LIMIT_TABLE_SUPPORT_CHANNEL_NUM); + return WLAN_STATUS_FAILURE; + } + + *prCmd = cnmMemAlloc(prAdapter, + RAM_TYPE_BUF, u4SetCmdSize); + + if (!*prCmd) { + DBGLOG(RLM, ERROR, "Domain: no buf to send cmd\n"); + return WLAN_STATUS_RESOURCES; + } + + /*initialize backoff table*/ + kalMemSet((*prCmd)->rChannelTxBfBackoff, MAX_TX_POWER, + sizeof((*prCmd)->rChannelTxBfBackoff)); + + (*prCmd)->ucNum = ucChNum; + (*prCmd)->ucBssIdx = prAdapter->prAisBssInfo[ucAisIdx]->ucBssIndex; + + for (ucBandIdx = 0; ucBandIdx < KAL_NUM_BANDS; ucBandIdx++) { + if (ucBandIdx != KAL_BAND_2GHZ && ucBandIdx != KAL_BAND_5GHZ) + continue; + + prChannelList = (ucBandIdx == KAL_BAND_2GHZ) ? + gTx_Pwr_Limit_2g_Ch : gTx_Pwr_Limit_5g_Ch; + ucChCnt = (ucBandIdx == KAL_BAND_2GHZ) ? + TX_PWR_LIMIT_2G_CH_NUM : TX_PWR_LIMIT_5G_CH_NUM; + + for (ucChIdx = 0; ucChIdx < ucChCnt; ucChIdx++) { + prChTxBfBackoff = + &((*prCmd)->rChannelTxBfBackoff[ucCnt++]); + prChTxBfBackoff->ucCentralCh = prChannelList[ucChIdx]; + } + } + + return WLAN_STATUS_SUCCESS; +} + +void rlmDomainTxPwrTxBfBackoffSetValues( + uint8_t ucVersion, + struct CMD_TXPWR_TXBF_SET_BACKOFF *prTxBfBackoffCmd, + struct TX_PWR_LIMIT_DATA *pTxPwrLimitData) +{ + uint8_t ucIdx = 0; + int8_t cChIdx = 0; + struct CMD_TXPWR_TXBF_CHANNEL_BACKOFF *pChTxBfBackoff = NULL; + struct CHANNEL_TX_PWR_LIMIT *pChTxPwrLimit = NULL; + + if (prTxBfBackoffCmd == NULL || + pTxPwrLimitData == NULL) + return; + + for (ucIdx = 0; ucIdx < prTxBfBackoffCmd->ucNum; ucIdx++) { + pChTxBfBackoff = + &(prTxBfBackoffCmd->rChannelTxBfBackoff[ucIdx]); + cChIdx = rlmDomainTxPwrLimitGetChIdx(pTxPwrLimitData, + pChTxBfBackoff->ucCentralCh); + + if (cChIdx == -1) { + DBGLOG(RLM, ERROR, + "Invalid ch idx found while assigning values\n"); + return; + } + pChTxPwrLimit = &pTxPwrLimitData->rChannelTxPwrLimit[cChIdx]; + + kalMemCopy(&pChTxBfBackoff->acTxBfBackoff, + pChTxPwrLimit->rTxBfBackoff, + sizeof(pChTxBfBackoff->acTxBfBackoff)); + } + + for (ucIdx = 0; ucIdx < prTxBfBackoffCmd->ucNum; ucIdx++) { + pChTxBfBackoff = + &(prTxBfBackoffCmd->rChannelTxBfBackoff[ucIdx]); + + DBGLOG(RLM, ERROR, + "ch %d TxBf backoff 2to1 %d\n", + pChTxBfBackoff->ucCentralCh, + pChTxBfBackoff->acTxBfBackoff[0]); + + } + +} + +void rlmDomainTxPwrSendTxBfBackoffCmd( + struct ADAPTER *prAdapter, + struct CMD_TXPWR_TXBF_SET_BACKOFF *prCmd) +{ + uint32_t rStatus; + uint32_t u4SetQueryInfoLen; + uint32_t u4SetCmdSize = sizeof(struct CMD_TXPWR_TXBF_SET_BACKOFF); + + u4SetQueryInfoLen = u4SetCmdSize; + /* Update tx max. power info to chip */ + rStatus = wlanSendSetQueryCmd(prAdapter, + CMD_ID_SET_TXBF_BACKOFF, + TRUE, + FALSE, + FALSE, + NULL, + NULL, + u4SetQueryInfoLen, + (uint8_t *) prCmd, + NULL, + 0); + +} + +void +rlmDomainSendTxPwrLimitPerRateCmd(struct ADAPTER *prAdapter, + uint8_t ucVersion, + struct TX_PWR_LIMIT_DATA *pTxPwrLimitData) +{ + struct wiphy *wiphy; + uint8_t band_idx = 0; + struct CMD_SET_TXPOWER_COUNTRY_TX_POWER_LIMIT_PER_RATE + *prTxPwrLimitPerRateCmd[KAL_NUM_BANDS] = {0}; + + wiphy = priv_to_wiphy(prAdapter->prGlueInfo); + if (rlmDomainInitTxPwrLimitPerRateCmd( + prAdapter, wiphy, prTxPwrLimitPerRateCmd) != + WLAN_STATUS_SUCCESS) + goto error; + + rlmDomainTxPwrLimitPerRateSetValues(ucVersion, + prTxPwrLimitPerRateCmd[KAL_BAND_2GHZ], pTxPwrLimitData); + rlmDomainTxPwrLimitPerRateSetValues(ucVersion, + prTxPwrLimitPerRateCmd[KAL_BAND_5GHZ], pTxPwrLimitData); + rlmDomainTxPwrLimitSendPerRateCmd(prAdapter, prTxPwrLimitPerRateCmd); + +error: + for (band_idx = 0; band_idx < KAL_NUM_BANDS; band_idx++) + if (prTxPwrLimitPerRateCmd[band_idx]) + cnmMemFree(prAdapter, prTxPwrLimitPerRateCmd[band_idx]); +} + +void +rlmDomainSendTxBfBackoffCmd(struct ADAPTER *prAdapter, + uint8_t ucVersion, + struct TX_PWR_LIMIT_DATA *pTxPwrLimitData) +{ + struct wiphy *wiphy; + struct CMD_TXPWR_TXBF_SET_BACKOFF + *prTxBfBackoffCmd = NULL; + + wiphy = priv_to_wiphy(prAdapter->prGlueInfo); + + if (rlmDomainInitTxBfBackoffCmd( + prAdapter, wiphy, &prTxBfBackoffCmd) != + WLAN_STATUS_SUCCESS) + goto error; + + rlmDomainTxPwrTxBfBackoffSetValues( + ucVersion, prTxBfBackoffCmd, pTxPwrLimitData); + rlmDomainTxPwrSendTxBfBackoffCmd(prAdapter, prTxBfBackoffCmd); + +error: + + if (prTxBfBackoffCmd) + cnmMemFree(prAdapter, prTxBfBackoffCmd); +} + +void rlmDomainSendPwrLimitCmd_V2(struct ADAPTER *prAdapter) +{ +#if (CFG_SUPPORT_SINGLE_SKU == 1) + uint8_t ucVersion = 0; + struct TX_PWR_LIMIT_DATA *pTxPwrLimitData = NULL; + + DBGLOG(RLM, INFO, "rlmDomainSendPwrLimitCmd()\n"); + pTxPwrLimitData = rlmDomainInitTxPwrLimitData(prAdapter); + + if (!pTxPwrLimitData) { + DBGLOG(RLM, ERROR, + "Init TxPwrLimitData failed\n"); + goto error; + } + + /* + * Get Max Tx Power from MT_TxPwrLimit.dat + */ + rlmDomainGetTxPwrLimit(rlmDomainGetCountryCode(), + &ucVersion, + prAdapter->prGlueInfo, + pTxPwrLimitData); + + /* Prepare to send CMD to FW */ + if (ucVersion == 0) { + rlmDomainSendTxPwrLimitCmd(prAdapter, + ucVersion, pTxPwrLimitData); + } else if (ucVersion == 1) { + rlmDomainSendTxPwrLimitPerRateCmd(prAdapter, + ucVersion, pTxPwrLimitData); + + if (g_bTxBfBackoffExists) + rlmDomainSendTxBfBackoffCmd(prAdapter, + ucVersion, pTxPwrLimitData); + + } else { + DBGLOG(RLM, WARN, "Unsupported TxPwrLimit dat version %u\n", + ucVersion); + } + +error: + if (pTxPwrLimitData && pTxPwrLimitData->rChannelTxPwrLimit) + kalMemFree(pTxPwrLimitData->rChannelTxPwrLimit, VIR_MEM_TYPE, + sizeof(struct CHANNEL_TX_PWR_LIMIT) * + pTxPwrLimitData->ucChNum); + + if (pTxPwrLimitData) + kalMemFree(pTxPwrLimitData, VIR_MEM_TYPE, + sizeof(struct TX_PWR_LIMIT_DATA)); +#endif +} + +#if CFG_SUPPORT_DYNAMIC_PWR_LIMIT +/* dynamic tx power control: begin ********************************************/ +uint32_t txPwrParseNumber(char **pcContent, char *delim, uint8_t *op, + int8_t *value) { + u_int8_t fgIsNegtive = FALSE; + char *pcTmp = NULL; + char *result = NULL; + + if ((!pcContent) || (*pcContent == NULL)) + return -1; + + if (**pcContent == '-') { + fgIsNegtive = TRUE; + *pcContent = *pcContent + 1; + } + pcTmp = *pcContent; + + result = kalStrSep(pcContent, delim); + if (result == NULL) { + return -1; + } else if ((result != NULL) && (kalStrLen(result) == 0)) { + if (fgIsNegtive) + return -1; + *value = 0; + *op = 0; + } else { + if (kalkStrtou8(pcTmp, 0, value) != 0) { + DBGLOG(RLM, ERROR, + "parse number error: invalid number [%s]\n", + pcTmp); + return -1; + } + if (fgIsNegtive) + *op = 2; + else + *op = 1; + } + + return 0; +} + +void txPwrOperate(enum ENUM_TX_POWER_CTRL_TYPE eCtrlType, + int8_t *operand1, int8_t *operand2) +{ + switch (eCtrlType) { + case PWR_CTRL_TYPE_WIFION_POWER_LEVEL: + case PWR_CTRL_TYPE_IOCTL_POWER_LEVEL: + if (*operand1 > *operand2) + *operand1 = *operand2; + break; + case PWR_CTRL_TYPE_WIFION_POWER_OFFSET: + case PWR_CTRL_TYPE_IOCTL_POWER_OFFSET: + *operand1 += *operand2; + break; + default: + break; + } + + if (*operand1 > MAX_TX_POWER) + *operand1 = MAX_TX_POWER; + else if (*operand1 < MIN_TX_POWER) + *operand1 = MIN_TX_POWER; +} + +uint32_t txPwrArbitrator(enum ENUM_TX_POWER_CTRL_TYPE eCtrlType, + void *pvBuf, + struct TX_PWR_CTRL_CHANNEL_SETTING *prChlSetting, + enum ENUM_PWR_LIMIT_TYPE eType) +{ + struct CMD_CHANNEL_POWER_LIMIT *prPwrLimit; + struct CMD_CHANNEL_POWER_LIMIT_HE *prPwrLimitHE; + uint8_t rateIdx; + int8_t *prRateOfs; + + + + if (eType == PWR_LIMIT_TYPE_COMP_11AX) { + prPwrLimitHE = (struct CMD_CHANNEL_POWER_LIMIT_HE *) pvBuf; + prRateOfs = &prPwrLimitHE->cPwrLimitRU26L; + + for (rateIdx = PWR_LIMIT_RU26_L; + rateIdx < PWR_LIMIT_HE_NUM ; rateIdx++) { + if (prChlSetting->opHE[rateIdx] + != PWR_CTRL_TYPE_NO_ACTION) { + txPwrOperate(eCtrlType, prRateOfs + rateIdx, + &prChlSetting->i8PwrLimitHE[rateIdx]); + } + } + + } else { + prPwrLimit = (struct CMD_CHANNEL_POWER_LIMIT *) pvBuf; + prRateOfs = &prPwrLimit->cPwrLimitCCK; + + for (rateIdx = PWR_LIMIT_CCK; + rateIdx < PWR_LIMIT_NUM ; rateIdx++) { + if (prChlSetting->op[rateIdx] + != PWR_CTRL_TYPE_NO_ACTION) { + txPwrOperate(eCtrlType, prRateOfs + rateIdx, + &prChlSetting->i8PwrLimit[rateIdx]); + } + } + + } + + return 0; +} + +uint32_t txPwrApplyOneSetting(struct CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT *prCmd, + struct TX_PWR_CTRL_ELEMENT *prCurElement, + uint8_t *bandedgeParam) +{ + struct CMD_CHANNEL_POWER_LIMIT *prCmdPwrLimit = NULL; + struct CMD_CHANNEL_POWER_LIMIT_HE *prCmdPwrLimitHE = NULL; + struct TX_PWR_CTRL_CHANNEL_SETTING *prChlSetting = NULL; + uint8_t i, j, channel, channel2, channel3; + u_int8_t fgDoArbitrator; + enum ENUM_PWR_LIMIT_TYPE eType; + + ASSERT(prCmd); + eType = prCmd->ucLimitType; + + for (i = 0; i < prCmd->ucNum; i++) { + + if (eType == PWR_LIMIT_TYPE_COMP_11AX) { + prCmdPwrLimitHE = &prCmd->u.rChPwrLimtHE[i]; + channel = prCmdPwrLimitHE->ucCentralCh; + + } else { + prCmdPwrLimit = &prCmd->u.rChannelPowerLimit[i]; + channel = prCmdPwrLimit->ucCentralCh; + } + + + + for (j = 0; j < prCurElement->settingCount; j++) { + prChlSetting = &prCurElement->rChlSettingList[j]; + channel2 = prChlSetting->channelParam[0]; + channel3 = prChlSetting->channelParam[1]; + fgDoArbitrator = FALSE; + switch (prChlSetting->eChnlType) { + case PWR_CTRL_CHNL_TYPE_NORMAL: { + if (channel == channel2) + fgDoArbitrator = TRUE; + break; + } + case PWR_CTRL_CHNL_TYPE_ALL: { + fgDoArbitrator = TRUE; + break; + } + case PWR_CTRL_CHNL_TYPE_RANGE: { + if ((channel >= channel2) && + (channel <= channel3)) + fgDoArbitrator = TRUE; + break; + } + case PWR_CTRL_CHNL_TYPE_2G4: { + if (channel <= 14) + fgDoArbitrator = TRUE; + break; + } + case PWR_CTRL_CHNL_TYPE_5G: { + if (channel > 14) + fgDoArbitrator = TRUE; + break; + } + case PWR_CTRL_CHNL_TYPE_BANDEDGE_2G4: { + if ((channel == *bandedgeParam) || + (channel == *(bandedgeParam + 1))) + fgDoArbitrator = TRUE; + break; + } + case PWR_CTRL_CHNL_TYPE_BANDEDGE_5G: { + if ((channel == *(bandedgeParam + 2)) || + (channel == *(bandedgeParam + 3))) + fgDoArbitrator = TRUE; + break; + } + case PWR_CTRL_CHNL_TYPE_5G_BAND1: { + if ((channel >= 30) && (channel <= 50)) + fgDoArbitrator = TRUE; + break; + } + case PWR_CTRL_CHNL_TYPE_5G_BAND2: { + if ((channel >= 51) && (channel <= 70)) + fgDoArbitrator = TRUE; + break; + } + case PWR_CTRL_CHNL_TYPE_5G_BAND3: { + if ((channel >= 71) && (channel <= 145)) + fgDoArbitrator = TRUE; + break; + } + case PWR_CTRL_CHNL_TYPE_5G_BAND4: { + if ((channel >= 146) && + (channel <= 170)) + fgDoArbitrator = TRUE; + break; + } + } + + if (fgDoArbitrator) { + if (eType == PWR_LIMIT_TYPE_COMP_11AX) + txPwrArbitrator(prCurElement->eCtrlType, + prCmdPwrLimitHE, + prChlSetting, + eType); + else + txPwrArbitrator(prCurElement->eCtrlType, + prCmdPwrLimit, + prChlSetting, + eType); + } + } + + } + + return 0; +} + +uint32_t txPwrCtrlApplySettings(struct ADAPTER *prAdapter, + struct CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT *prCmd, + uint8_t *bandedgeParam) +{ + struct LINK_ENTRY *prCur, *prNext; + struct TX_PWR_CTRL_ELEMENT *element = NULL; + struct LINK *aryprlist[2] = { + &prAdapter->rTxPwr_DefaultList, + &prAdapter->rTxPwr_DynamicList + }; + int32_t i; + + /* show the tx power ctrl applied list */ + txPwrCtrlShowList(prAdapter, 1, "applied list"); + + for (i = 0; i < ARRAY_SIZE(aryprlist); i++) { + LINK_FOR_EACH_SAFE(prCur, prNext, aryprlist[i]) { + element = LINK_ENTRY(prCur, + struct TX_PWR_CTRL_ELEMENT, node); + if (element->fgApplied == TRUE) + txPwrApplyOneSetting( + prCmd, element, bandedgeParam); + } + } + + return 0; +} + +char *txPwrGetString(char **pcContent, char *delim) +{ + char *result = NULL; + + if (pcContent == NULL) + return NULL; + + result = kalStrSep(pcContent, delim); + if ((pcContent == NULL) || (result == NULL) || + ((result != NULL) && (kalStrLen(result) == 0))) + return NULL; + + return result; +} + +struct TX_PWR_CTRL_ELEMENT *txPwrCtrlStringToStruct(char *pcContent, + u_int8_t fgSkipHeader) +{ + struct TX_PWR_CTRL_ELEMENT *prCurElement = NULL; + struct TX_PWR_CTRL_CHANNEL_SETTING *prTmpSetting; + char acTmpName[MAX_TX_PWR_CTRL_ELEMENT_NAME_SIZE]; + char *pcContCur = NULL, *pcContCur2 = NULL, *pcContEnd = NULL; + char *pcContTmp = NULL, *pcContNext = NULL, *pcContOld = NULL; + uint32_t u4MemSize = sizeof(struct TX_PWR_CTRL_ELEMENT); + uint32_t copySize = 0; + uint8_t i, j, op, ucSettingCount = 0; + uint8_t value, value2, count = 0; + uint8_t ucAppliedWay, ucOperation = 0; + char carySeperator[2] = { 0, 0 }; + + char *pacParsePwrAC[PWR_CFG_PRAM_NUM_AC] = { + "CCK", +#if (CFG_SUPPORT_DYNA_TX_PWR_CTRL_OFDM_SETTING == 1) + "OFDML", + "OFDMH", +#endif + "HT20L", + "HT20H", + "HT40L", + "HT40H", + "HT80L", + "HT80H", + "HT160L", + "HT160H" + }; + char *pacParsePwrAX[PWR_CFG_PRAM_NUM_AX] = { + "RU26L", + "RU26H", + "RU26U", + "RU52L", + "RU52H", + "RU52U", + "RU106L", + "RU106H", + "RU106U", + "RU242L", + "RU242H", + "RU242U", + "RU484L", + "RU484H", + "RU484U", + "RU996L", + "RU996H", + "RU996U" + }; + + if (!pcContent) { + DBGLOG(RLM, ERROR, "pcContent is null\n"); + return NULL; + } + + pcContCur = pcContent; + pcContEnd = pcContent + kalStrLen(pcContent); + + if (fgSkipHeader == TRUE) + goto skipLabel; + + /* insert elenemt into prTxPwrCtrlList */ + /* parse scenario name */ + kalMemZero(acTmpName, MAX_TX_PWR_CTRL_ELEMENT_NAME_SIZE); + pcContOld = pcContCur; + pcContTmp = txPwrGetString(&pcContCur, ";"); + if (!pcContTmp) { + DBGLOG(RLM, ERROR, "parse scenario name error: %s\n", + pcContOld); + return NULL; + } + copySize = kalStrLen(pcContTmp); + if (copySize >= MAX_TX_PWR_CTRL_ELEMENT_NAME_SIZE) + copySize = MAX_TX_PWR_CTRL_ELEMENT_NAME_SIZE - 1; + kalMemCopy(acTmpName, pcContTmp, copySize); + acTmpName[copySize] = 0; + + /* parese scenario sub index */ + pcContOld = pcContCur; + if (txPwrParseNumber(&pcContCur, ";", &op, &value)) { + DBGLOG(RLM, ERROR, "parse scenario sub index error: %s\n", + pcContOld); + return NULL; + } + if ((op != 1) || (value < 0)) { + DBGLOG(RLM, ERROR, + "parse scenario sub index error: op=%u, val=%d\n", + op, value); + return NULL; + } + + /* parese scenario applied way */ + pcContOld = pcContCur; + if (txPwrParseNumber(&pcContCur, ";", &op, &ucAppliedWay)) { + DBGLOG(RLM, ERROR, "parse applied way error: %s\n", + pcContOld); + return NULL; + } + if ((ucAppliedWay < PWR_CTRL_TYPE_APPLIED_WAY_WIFION) || + (ucAppliedWay > PWR_CTRL_TYPE_APPLIED_WAY_IOCTL)) { + DBGLOG(RLM, ERROR, + "parse applied way error: value=%u\n", + ucAppliedWay); + return NULL; + } + + /* parese scenario applied type */ + pcContOld = pcContCur; + if (txPwrParseNumber(&pcContCur, ";", &op, &ucOperation)) { + DBGLOG(RLM, ERROR, "parse operation error: %s\n", + pcContOld); + return NULL; + } + if ((ucOperation < PWR_CTRL_TYPE_OPERATION_POWER_LEVEL) || + (ucOperation > PWR_CTRL_TYPE_OPERATION_POWER_OFFSET)) { + DBGLOG(RLM, ERROR, + "parse operation error: value=%u\n", + ucOperation); + return NULL; + } + + switch (ucAppliedWay) { + case PWR_CTRL_TYPE_APPLIED_WAY_WIFION: + if (ucOperation == PWR_CTRL_TYPE_OPERATION_POWER_LEVEL) + value2 = PWR_CTRL_TYPE_WIFION_POWER_LEVEL; + else + value2 = PWR_CTRL_TYPE_WIFION_POWER_OFFSET; + break; + case PWR_CTRL_TYPE_APPLIED_WAY_IOCTL: + if (ucOperation == PWR_CTRL_TYPE_OPERATION_POWER_LEVEL) + value2 = PWR_CTRL_TYPE_IOCTL_POWER_LEVEL; + else + value2 = PWR_CTRL_TYPE_IOCTL_POWER_OFFSET; + break; + } + +skipLabel: + /* decide how many channel setting */ + pcContOld = pcContCur; + while (pcContCur <= pcContEnd) { + if ((*pcContCur) == '[') + ucSettingCount++; + pcContCur++; + } + + if (ucSettingCount == 0) { + DBGLOG(RLM, ERROR, + "power ctrl channel setting is empty\n"); + return NULL; + } + + /* allocate memory for control element */ + u4MemSize += (ucSettingCount == 1) ? 0 : (ucSettingCount - 1) * + sizeof(struct TX_PWR_CTRL_CHANNEL_SETTING); + prCurElement = (struct TX_PWR_CTRL_ELEMENT *)kalMemAlloc( + u4MemSize, VIR_MEM_TYPE); + if (!prCurElement) { + DBGLOG(RLM, ERROR, + "alloc power ctrl element failed\n"); + return NULL; + } + + /* assign values into control element */ + kalMemZero(prCurElement, u4MemSize); + if (fgSkipHeader == FALSE) { + kalMemCopy(prCurElement->name, acTmpName, copySize); + prCurElement->index = (uint8_t)value; + prCurElement->eCtrlType = (enum ENUM_TX_POWER_CTRL_TYPE)value2; + if (prCurElement->eCtrlType <= + PWR_CTRL_TYPE_WIFION_POWER_OFFSET) + prCurElement->fgApplied = TRUE; + } + prCurElement->settingCount = ucSettingCount; + + /* parse channel setting list */ + pcContCur = pcContOld + 1; /* skip '[' */ + + for (i = 0; i < ucSettingCount; i++) { + if (pcContCur >= pcContEnd) { + DBGLOG(RLM, ERROR, + "parse error: out of bound\n"); + goto clearLabel; + } + + prTmpSetting = &prCurElement->rChlSettingList[i]; + + /* verify there is ] symbol */ + pcContNext = kalStrChr(pcContCur, ']'); + if (!pcContNext) { + DBGLOG(RLM, ERROR, + "parse error: miss symbol ']', %s\n", + pcContCur); + goto clearLabel; + } + + /* verify this setting has 9 segment */ + pcContTmp = pcContCur; + count = 0; + while (pcContTmp < pcContNext) { + if (*pcContTmp == ',') + count++; + pcContTmp++; + } + + if ((count != PWR_CFG_PRAM_NUM_AC) && + (count != PWR_CFG_PRAM_NUM_AX) && + (count != PWR_CFG_PRAM_NUM_ALL_RATE)) { + DBGLOG(RLM, ERROR, + "parse error: not segments, %s\n", + pcContCur); + goto clearLabel; + } + + /* parse channel setting type */ + pcContOld = pcContCur; + pcContTmp = txPwrGetString(&pcContCur, ","); + if (!pcContTmp) { + DBGLOG(RLM, ERROR, + "parse channel setting type error, %s\n", + pcContOld); + goto clearLabel; + /* "ALL" */ + } else if (kalStrCmp(pcContTmp, + PWR_CTRL_CHNL_TYPE_KEY_ALL) == 0) + prTmpSetting->eChnlType = + PWR_CTRL_CHNL_TYPE_ALL; + /* "2G4" */ + else if (kalStrCmp(pcContTmp, + PWR_CTRL_CHNL_TYPE_KEY_2G4) == 0) + prTmpSetting->eChnlType = + PWR_CTRL_CHNL_TYPE_2G4; + /* "5G" */ + else if (kalStrCmp(pcContTmp, + PWR_CTRL_CHNL_TYPE_KEY_5G) == 0) + prTmpSetting->eChnlType = + PWR_CTRL_CHNL_TYPE_5G; + /* "BANDEDGE2G4" */ + else if (kalStrCmp(pcContTmp, + PWR_CTRL_CHNL_TYPE_KEY_BANDEDGE_2G4) == 0) + prTmpSetting->eChnlType = + PWR_CTRL_CHNL_TYPE_BANDEDGE_2G4; + /* "BANDEDGE5G" */ + else if (kalStrCmp(pcContTmp, + PWR_CTRL_CHNL_TYPE_KEY_BANDEDGE_5G) == 0) + prTmpSetting->eChnlType = + PWR_CTRL_CHNL_TYPE_BANDEDGE_5G; + /* "5GBAND1" */ + else if (kalStrCmp(pcContTmp, + PWR_CTRL_CHNL_TYPE_KEY_5G_BAND1) == 0) + prTmpSetting->eChnlType = + PWR_CTRL_CHNL_TYPE_5G_BAND1; + /* "5GBAND2" */ + else if (kalStrCmp(pcContTmp, + PWR_CTRL_CHNL_TYPE_KEY_5G_BAND2) == 0) + prTmpSetting->eChnlType = + PWR_CTRL_CHNL_TYPE_5G_BAND2; + /* "5GBAND3" */ + else if (kalStrCmp(pcContTmp, + PWR_CTRL_CHNL_TYPE_KEY_5G_BAND3) == 0) + prTmpSetting->eChnlType = + PWR_CTRL_CHNL_TYPE_5G_BAND3; + /* "5GBAND4" */ + else if (kalStrCmp(pcContTmp, + PWR_CTRL_CHNL_TYPE_KEY_5G_BAND4) == 0) + prTmpSetting->eChnlType = + PWR_CTRL_CHNL_TYPE_5G_BAND4; + else { + pcContCur2 = pcContOld; + pcContTmp = txPwrGetString(&pcContCur2, "-"); + if (!pcContTmp) { + DBGLOG(RLM, ERROR, + "parse channel range error: %s\n"); + goto clearLabel; + } + if (pcContCur2 == NULL) { /* case: normal channel */ + if (kalkStrtou8(pcContOld, 0, &value) != 0) { + DBGLOG(RLM, ERROR, + "parse channel error: %s\n", + pcContOld); + goto clearLabel; + } + prTmpSetting->channelParam[0] = value; + prTmpSetting->eChnlType = + PWR_CTRL_CHNL_TYPE_NORMAL; + } else { /* case: channel range */ + if (kalkStrtou8(pcContTmp, 0, &value) != 0) { + DBGLOG(RLM, ERROR, + "parse first channel error, %s\n", + pcContTmp); + goto clearLabel; + } + if (kalkStrtou8(pcContCur2, 0, &value2) != 0) { + DBGLOG(RLM, ERROR, + "parse second channel error, %s\n", + pcContCur2); + goto clearLabel; + } + prTmpSetting->channelParam[0] = value; + prTmpSetting->channelParam[1] = value2; + prTmpSetting->eChnlType = + PWR_CTRL_CHNL_TYPE_RANGE; + } + } + + if (count == PWR_CFG_PRAM_NUM_ALL_RATE) { + /* parse all rate setting */ + pcContOld = pcContCur; + if (txPwrParseNumber(&pcContCur, "]", &op, &value)) { + DBGLOG(RLM, ERROR, "parse CCK error, %s\n", + pcContOld); + goto clearLabel; + } + + for (j = 0; j < PWR_CFG_PRAM_NUM_AC; j++) { + prTmpSetting->op[j] = op; + prTmpSetting->i8PwrLimit[j] = (op != 2) ? + value : (0 - value); + } + + for (j = 0; j < PWR_CFG_PRAM_NUM_AX; j++) { + prTmpSetting->opHE[j] = op; + prTmpSetting->i8PwrLimitHE[j] = (op != 2) ? + value : (0 - value); + } + goto skipLabel2; + } else if (count == PWR_CFG_PRAM_NUM_AC) { + for (j = 0; j < PWR_CFG_PRAM_NUM_AC; j++) { + /* parse cck/20L/20H .. 160L/160H setting */ + if (j == PWR_CFG_PRAM_NUM_AC - 1) + carySeperator[0] = ']'; + else + carySeperator[0] = ','; + + pcContOld = pcContCur; + if (txPwrParseNumber(&pcContCur, carySeperator, + &op, &value)) { + DBGLOG(RLM, ERROR, + "parse %s error, %s\n", + pacParsePwrAC[j], pcContOld); + goto clearLabel; + } + prTmpSetting->op[j] = + (enum ENUM_TX_POWER_CTRL_VALUE_SIGN)op; + prTmpSetting->i8PwrLimit[j] = + (op != 2) ? value : (0 - value); + if ((prTmpSetting->op[j] + == PWR_CTRL_TYPE_POSITIVE) && + (ucOperation + == PWR_CTRL_TYPE_OPERATION_POWER_OFFSET) + ) { + DBGLOG(RLM, ERROR, + "parse %s error, Power_Offset value cannot be positive: %u\n", + pacParsePwrAC[j], + value); + goto clearLabel; + } + } + + } else if (count == PWR_CFG_PRAM_NUM_AX) { + for (j = 0; j < PWR_CFG_PRAM_NUM_AX; j++) { + /* parse RU26L ... RU996U setting */ + if (j == PWR_CFG_PRAM_NUM_AX - 1) + carySeperator[0] = ']'; + else + carySeperator[0] = ','; + + pcContOld = pcContCur; + if (txPwrParseNumber(&pcContCur, carySeperator, + &op, &value)) { + DBGLOG(RLM, ERROR, + "parse %s error, %s\n", + pacParsePwrAX[j], + pcContOld); + goto clearLabel; + } + prTmpSetting->opHE[j] = + (enum ENUM_TX_POWER_CTRL_VALUE_SIGN)op; + prTmpSetting->i8PwrLimitHE[j] = + (op != 2) ? value : (0 - value); + if ((prTmpSetting->opHE[j] + == PWR_CTRL_TYPE_POSITIVE) && + (ucOperation + == PWR_CTRL_TYPE_OPERATION_POWER_OFFSET) + ) { + DBGLOG(RLM, ERROR, + "parse %s error, Power_Offset value cannot be positive: %u\n", + pacParsePwrAX[j], + value); + goto clearLabel; + } + } + + } + +skipLabel2: + pcContCur = pcContNext + 2; + } + + return prCurElement; + +clearLabel: + if (prCurElement != NULL) + kalMemFree(prCurElement, VIR_MEM_TYPE, u4MemSize); + + return NULL; +} + +/* filterType: 0:no filter, 1:fgEnable is TRUE */ +int txPwrCtrlListSize(struct ADAPTER *prAdapter, uint8_t filterType) +{ + struct LINK_ENTRY *prCur, *prNext; + struct TX_PWR_CTRL_ELEMENT *prCurElement = NULL; + struct LINK *aryprlist[2] = { + &prAdapter->rTxPwr_DefaultList, + &prAdapter->rTxPwr_DynamicList + }; + int i, count = 0; + + for (i = 0; i < ARRAY_SIZE(aryprlist); i++) { + LINK_FOR_EACH_SAFE(prCur, prNext, aryprlist[i]) { + prCurElement = LINK_ENTRY(prCur, + struct TX_PWR_CTRL_ELEMENT, node); + if ((filterType == 1) && + (prCurElement->fgApplied != TRUE)) + continue; + count++; + } + } + + return count; +} + +/* filterType: 0:no filter, 1:fgApplied is TRUE */ +void txPwrCtrlShowList(struct ADAPTER *prAdapter, uint8_t filterType, + char *message) +{ + struct LINK_ENTRY *prCur, *prNext; + struct TX_PWR_CTRL_ELEMENT *prCurElement = NULL; + struct TX_PWR_CTRL_CHANNEL_SETTING *prChlSettingList; + struct LINK *aryprlist[2] = { + &prAdapter->rTxPwr_DefaultList, + &prAdapter->rTxPwr_DynamicList + }; + uint8_t ucAppliedWay, ucOperation; + int i, j, k, count = 0; + char msgLimit[PWR_BUF_LEN]; + int msgOfs = 0; + + if (filterType == 1) + DBGLOG(RLM, TRACE, "Tx Power Ctrl List=[%s], Size=[%d]", + message, txPwrCtrlListSize(prAdapter, filterType)); + else + DBGLOG(RLM, TRACE, "Tx Power Ctrl List=[%s], Size=[%d]", + message, txPwrCtrlListSize(prAdapter, filterType)); + + for (i = 0; i < ARRAY_SIZE(aryprlist); i++) { + LINK_FOR_EACH_SAFE(prCur, prNext, aryprlist[i]) { + prCurElement = LINK_ENTRY(prCur, + struct TX_PWR_CTRL_ELEMENT, node); + if ((filterType == 1) && + (prCurElement->fgApplied != TRUE)) + continue; + + switch (prCurElement->eCtrlType) { + case PWR_CTRL_TYPE_WIFION_POWER_LEVEL: + ucAppliedWay = + PWR_CTRL_TYPE_APPLIED_WAY_WIFION; + ucOperation = + PWR_CTRL_TYPE_OPERATION_POWER_LEVEL; + break; + case PWR_CTRL_TYPE_WIFION_POWER_OFFSET: + ucAppliedWay = + PWR_CTRL_TYPE_APPLIED_WAY_WIFION; + ucOperation = + PWR_CTRL_TYPE_OPERATION_POWER_OFFSET; + break; + case PWR_CTRL_TYPE_IOCTL_POWER_LEVEL: + ucAppliedWay = + PWR_CTRL_TYPE_APPLIED_WAY_IOCTL; + ucOperation = + PWR_CTRL_TYPE_OPERATION_POWER_LEVEL; + break; + case PWR_CTRL_TYPE_IOCTL_POWER_OFFSET: + ucAppliedWay = + PWR_CTRL_TYPE_APPLIED_WAY_IOCTL; + ucOperation = + PWR_CTRL_TYPE_OPERATION_POWER_OFFSET; + break; + default: + ucAppliedWay = 0; + ucOperation = 0; + break; + } + + DBGLOG(RLM, TRACE, + "Tx Power Ctrl Element-%u: name=[%s], index=[%u], appliedWay=[%u:%s], operation=[%u:%s], ChlSettingCount=[%u]\n", + ++count, prCurElement->name, prCurElement->index, + ucAppliedWay, + g_au1TxPwrAppliedWayLabel[ucAppliedWay - 1], + ucOperation, + g_au1TxPwrOperationLabel[ucOperation - 1], + prCurElement->settingCount); + + for (j = 0; j < prCurElement->settingCount; j++) { + prChlSettingList = + &(prCurElement->rChlSettingList[j]); + msgOfs = 0; + + /*Coverity check*/ + if (prChlSettingList->eChnlType < 0) + prChlSettingList->eChnlType = 0; + + /*message head*/ + msgOfs += snprintf(msgLimit + msgOfs, + PWR_BUF_LEN - msgOfs, + "Setting-%u:[%s:%u,%u],Legcy:", + (j + 1), + g_au1TxPwrChlTypeLabel[ + prChlSettingList->eChnlType], + prChlSettingList->channelParam[0], + prChlSettingList->channelParam[1]); + + /*print legacy cfg*/ + for (k = 0; k < PWR_LIMIT_NUM ; k++) + msgOfs += snprintf(msgLimit + msgOfs, + PWR_BUF_LEN - msgOfs, + "[%u,%d]", + prChlSettingList->op[k], + prChlSettingList->i8PwrLimit[k]); + + /*print HE cfg*/ + msgOfs += snprintf(msgLimit + msgOfs, + PWR_BUF_LEN - msgOfs, + "HE:"); + for (k = 0; k < PWR_LIMIT_HE_NUM ; k++) + msgOfs += snprintf(msgLimit + msgOfs, + PWR_BUF_LEN - msgOfs, + "[%u,%d]", + prChlSettingList->opHE[k], + prChlSettingList->i8PwrLimitHE[k]); + + /*message tail*/ + if (msgOfs > 0) + msgLimit[msgOfs-1] = '\0'; + else + msgLimit[0] = '\0'; + + DBGLOG(RLM, TRACE, "%s\n", msgLimit); + } + } + } +} + +/* This function used to delete element by specifying name or index + * if index is 0, deletion only according name + * if index >= 1, deletion according name and index + */ +void _txPwrCtrlDeleteElement(struct ADAPTER *prAdapter, + uint8_t *name, + uint32_t index, + struct LINK *prTxPwrCtrlList) +{ + struct LINK_ENTRY *prCur, *prNext; + struct TX_PWR_CTRL_ELEMENT *prCurElement = NULL; + uint32_t u4MemSize = sizeof(struct TX_PWR_CTRL_ELEMENT); + uint32_t u4MemSize2; + uint32_t u4SettingSize = sizeof(struct TX_PWR_CTRL_CHANNEL_SETTING); + uint8_t ucSettingCount; + u_int8_t fgFind; + + LINK_FOR_EACH_SAFE(prCur, prNext, prTxPwrCtrlList) { + fgFind = FALSE; + prCurElement = LINK_ENTRY(prCur, struct TX_PWR_CTRL_ELEMENT, + node); + if (kalStrCmp(prCurElement->name, name) == 0) { + if (index == 0) + fgFind = TRUE; + else if (prCurElement->index == index) + fgFind = TRUE; + if (fgFind) { + linkDel(prCur); + if (prCurElement != NULL) { + ucSettingCount = + prCurElement->settingCount; + u4MemSize2 = u4MemSize + + ((ucSettingCount == 1) ? 0 : + (ucSettingCount - 1) * + u4SettingSize); + kalMemFree(prCurElement, VIR_MEM_TYPE, + u4MemSize2); + } + } + } + } +} + +void txPwrCtrlDeleteElement(struct ADAPTER *prAdapter, + uint8_t *name, + uint32_t index, + enum ENUM_TX_POWER_CTRL_LIST_TYPE eListType) +{ + if ((eListType == PWR_CTRL_TYPE_ALL_LIST) || + (eListType == PWR_CTRL_TYPE_DEFAULT_LIST)) + _txPwrCtrlDeleteElement(prAdapter, name, index, + &prAdapter->rTxPwr_DefaultList); + + if ((eListType == PWR_CTRL_TYPE_ALL_LIST) || + (eListType == PWR_CTRL_TYPE_DYNAMIC_LIST)) + _txPwrCtrlDeleteElement(prAdapter, name, index, + &prAdapter->rTxPwr_DynamicList); +} + +struct TX_PWR_CTRL_ELEMENT *_txPwrCtrlFindElement(struct ADAPTER *prAdapter, + uint8_t *name, uint32_t index, + u_int8_t fgCheckIsApplied, + struct LINK *prTxPwrCtrlList) +{ + struct LINK_ENTRY *prCur, *prNext; + struct TX_PWR_CTRL_ELEMENT *prCurElement = NULL; + + + LINK_FOR_EACH_SAFE(prCur, prNext, prTxPwrCtrlList) { + u_int8_t fgFind = FALSE; + + prCurElement = LINK_ENTRY( + prCur, struct TX_PWR_CTRL_ELEMENT, node); + if (kalStrCmp(prCurElement->name, name) == 0) { + if ((!fgCheckIsApplied) || + (fgCheckIsApplied && + (prCurElement->fgApplied == TRUE))) { + if (index == 0) + fgFind = TRUE; + else if (prCurElement->index == index) + fgFind = TRUE; + } + if (fgFind) + return prCurElement; + } + } + return NULL; +} + +struct TX_PWR_CTRL_ELEMENT *txPwrCtrlFindElement(struct ADAPTER *prAdapter, + uint8_t *name, uint32_t index, + u_int8_t fgCheckIsApplied, + enum ENUM_TX_POWER_CTRL_LIST_TYPE eListType) +{ + struct LINK *prTxPwrCtrlList = NULL; + + if (eListType == PWR_CTRL_TYPE_DEFAULT_LIST) + prTxPwrCtrlList = &prAdapter->rTxPwr_DefaultList; + if (eListType == PWR_CTRL_TYPE_DYNAMIC_LIST) + prTxPwrCtrlList = &prAdapter->rTxPwr_DynamicList; + if (prTxPwrCtrlList == NULL) + return NULL; + + return _txPwrCtrlFindElement(prAdapter, name, index, fgCheckIsApplied, + prTxPwrCtrlList); +} + +void txPwrCtrlAddElement(struct ADAPTER *prAdapter, + struct TX_PWR_CTRL_ELEMENT *prElement) +{ + struct LINK_ENTRY *prNode = &prElement->node; + + switch (prElement->eCtrlType) { + case PWR_CTRL_TYPE_WIFION_POWER_LEVEL: + linkAdd(prNode, &prAdapter->rTxPwr_DefaultList); + break; + case PWR_CTRL_TYPE_WIFION_POWER_OFFSET: + linkAddTail(prNode, &prAdapter->rTxPwr_DefaultList); + break; + case PWR_CTRL_TYPE_IOCTL_POWER_LEVEL: + linkAdd(prNode, &prAdapter->rTxPwr_DynamicList); + break; + case PWR_CTRL_TYPE_IOCTL_POWER_OFFSET: + linkAddTail(prNode, &prAdapter->rTxPwr_DynamicList); + break; + } +} + +void txPwrCtrlFileBufToList(struct ADAPTER *prAdapter, uint8_t *pucFileBuf) +{ + struct TX_PWR_CTRL_ELEMENT *prNewElement; + char *oneLine; + + if (pucFileBuf == NULL) + return; + + while ((oneLine = kalStrSep((char **)(&pucFileBuf), "\r\n")) + != NULL) { + /* skip comment line and empty line */ + if ((oneLine[0] == '#') || (oneLine[0] == 0)) + continue; + + prNewElement = txPwrCtrlStringToStruct(oneLine, FALSE); + if (prNewElement != NULL) { + /* delete duplicated element + * by checking name and index + */ + txPwrCtrlDeleteElement(prAdapter, + prNewElement->name, prNewElement->index, + PWR_CTRL_TYPE_ALL_LIST); + + /* append to rTxPwr_List */ + txPwrCtrlAddElement(prAdapter, prNewElement); + } + } + + /* show the tx power ctrl list */ + txPwrCtrlShowList(prAdapter, 0, "config list, after loading cfg file"); +} + +void txPwrCtrlGlobalVariableToList(struct ADAPTER *prAdapter) +{ + struct TX_PWR_CTRL_ELEMENT *pcElement; + char *ptr; + int32_t i, u4MemSize; + + for (i = 0; i < ARRAY_SIZE(g_au1TxPwrDefaultSetting); i++) { + /* skip empty line */ + if (g_au1TxPwrDefaultSetting[i][0] == 0) + continue; + u4MemSize = kalStrLen(g_au1TxPwrDefaultSetting[i]) + 1; + ptr = (char *)kalMemAlloc(u4MemSize, VIR_MEM_TYPE); + if (ptr == NULL) { + DBGLOG(RLM, ERROR, "kalMemAlloc fail: %d\n", u4MemSize); + continue; + } + kalMemCopy(ptr, g_au1TxPwrDefaultSetting[i], u4MemSize); + *(ptr + u4MemSize - 1) = 0; + pcElement = txPwrCtrlStringToStruct(ptr, FALSE); + kalMemFree(ptr, VIR_MEM_TYPE, u4MemSize); + if (pcElement != NULL) { + /* delete duplicated element + * by checking name and index + */ + txPwrCtrlDeleteElement(prAdapter, + pcElement->name, pcElement->index, + PWR_CTRL_TYPE_ALL_LIST); + + /* append to rTxPwr_List */ + txPwrCtrlAddElement(prAdapter, pcElement); + } + } + + /* show the tx power ctrl cfg list */ + txPwrCtrlShowList(prAdapter, 0, + "config list, after loadding global variables"); +} + +void txPwrCtrlCfgFileToList(struct ADAPTER *prAdapter) +{ + uint8_t *pucConfigBuf; + uint32_t u4ConfigReadLen = 0; + + pucConfigBuf = (uint8_t *)kalMemAlloc(WLAN_CFG_FILE_BUF_SIZE, + VIR_MEM_TYPE); + kalMemZero(pucConfigBuf, WLAN_CFG_FILE_BUF_SIZE); + if (pucConfigBuf) { + if (kalRequestFirmware("txpowerctrl.cfg", pucConfigBuf, + WLAN_CFG_FILE_BUF_SIZE, &u4ConfigReadLen, + prAdapter->prGlueInfo->prDev) == 0) { + /* ToDo:: Nothing */ + } else if (kalReadToFile("/data/misc/wifi/txpowerctrl.cfg", + pucConfigBuf, WLAN_CFG_FILE_BUF_SIZE, + &u4ConfigReadLen) == 0) { + /* ToDo:: Nothing */ + } else if (kalReadToFile("/storage/sdcard0/txpowerctrl.cfg", + pucConfigBuf, WLAN_CFG_FILE_BUF_SIZE, + &u4ConfigReadLen) == 0) { + /* ToDo:: Nothing */ + } + + if (pucConfigBuf[0] != '\0' && u4ConfigReadLen > 0) { + pucConfigBuf[u4ConfigReadLen] = 0; + txPwrCtrlFileBufToList(prAdapter, pucConfigBuf); + } else + DBGLOG(RLM, INFO, + "no txpowerctrl.cfg or file is empty\n"); + + kalMemFree(pucConfigBuf, VIR_MEM_TYPE, WLAN_CFG_FILE_BUF_SIZE); + } +} + +void txPwrCtrlLoadConfig(struct ADAPTER *prAdapter) +{ + /* 1. add records from global tx power ctrl setting into cfg list */ + txPwrCtrlGlobalVariableToList(prAdapter); + + /* 2. update cfg list by txpowerctrl.cfg */ + txPwrCtrlCfgFileToList(prAdapter); + +#if CFG_SUPPORT_PWR_LIMIT_COUNTRY + /* 3. send setting to firmware */ + rlmDomainSendPwrLimitCmd(prAdapter); +#endif +} + +void txPwrCtrlInit(struct ADAPTER *prAdapter) +{ + LINK_INITIALIZE(&prAdapter->rTxPwr_DefaultList); + LINK_INITIALIZE(&prAdapter->rTxPwr_DynamicList); +} + +void txPwrCtrlUninit(struct ADAPTER *prAdapter) +{ + struct LINK_ENTRY *prCur, *prNext; + struct TX_PWR_CTRL_ELEMENT *prCurElement = NULL; + struct LINK *aryprlist[2] = { + &prAdapter->rTxPwr_DefaultList, + &prAdapter->rTxPwr_DynamicList + }; + uint32_t u4MemSize = sizeof(struct TX_PWR_CTRL_ELEMENT); + uint32_t u4MemSize2; + uint32_t u4SettingSize = sizeof(struct TX_PWR_CTRL_CHANNEL_SETTING); + uint8_t ucSettingCount; + int32_t i; + + for (i = 0; i < ARRAY_SIZE(aryprlist); i++) { + LINK_FOR_EACH_SAFE(prCur, prNext, aryprlist[i]) { + prCurElement = LINK_ENTRY(prCur, + struct TX_PWR_CTRL_ELEMENT, node); + linkDel(prCur); + if (prCurElement) { + ucSettingCount = prCurElement->settingCount; + u4MemSize2 = u4MemSize + + ((ucSettingCount <= 1) ? 0 : + (ucSettingCount - 1) * u4SettingSize); + kalMemFree(prCurElement, + VIR_MEM_TYPE, u4MemSize2); + } + } + } +} +/* dynamic tx power control: end **********************************************/ +#endif /* CFG_SUPPORT_DYNAMIC_PWR_LIMIT */ + +void rlmDomainShowPwrLimitPerCh(char *message, + struct CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT *prCmd) +{ + /* for print usage */ + struct CMD_CHANNEL_POWER_LIMIT *prPwrLmt = NULL; + /* for print usage */ + struct CMD_CHANNEL_POWER_LIMIT_HE *prPwrLmtHE = NULL; + enum ENUM_PWR_LIMIT_TYPE eType; + uint8_t i, j; + char msgLimit[PWR_BUF_LEN]; + int msgOfs = 0; + int8_t *prcRatePwr; + + + ASSERT(prCmd); + + eType = prCmd->ucLimitType; + + for (i = 0; i < prCmd->ucNum; i++) { + + if (i >= MAX_CMD_SUPPORT_CHANNEL_NUM) { + DBGLOG(RLM, ERROR, "out of MAX CH Num\n"); + return; + } + + kalMemZero(msgLimit, sizeof(char)*PWR_BUF_LEN); + msgOfs = 0; + if (eType == PWR_LIMIT_TYPE_COMP_11AX) { + prPwrLmtHE = &prCmd->u.rChPwrLimtHE[i]; + prcRatePwr = &prPwrLmtHE->cPwrLimitRU26L; + + /*message head*/ + msgOfs += snprintf(msgLimit + msgOfs, + PWR_BUF_LEN - msgOfs, + "HE ch=%d,Limit=", + prPwrLmtHE->ucCentralCh); + + /*message body*/ + for (j = PWR_LIMIT_RU26_L; j < PWR_LIMIT_HE_NUM ; j++) + msgOfs += snprintf(msgLimit + msgOfs, + PWR_BUF_LEN - msgOfs, + "%d,", + *(prcRatePwr + j)); + /*message tail*/ + if (msgOfs >= 1) + msgLimit[msgOfs-1] = '\0'; + else + msgLimit[0] = '\0'; + + DBGLOG(RLM, TRACE, "%s:%s\n", message, msgLimit); + + } else { + prPwrLmt = &prCmd->u.rChannelPowerLimit[i]; + prcRatePwr = &prPwrLmt->cPwrLimitCCK; + + /*message head*/ + msgOfs += snprintf(msgLimit + msgOfs, + PWR_BUF_LEN - msgOfs, + "legacy ch=%d,Limit=", + prPwrLmt->ucCentralCh); + + /*message body*/ + for (j = PWR_LIMIT_CCK; j < PWR_LIMIT_NUM ; j++) + msgOfs += snprintf(msgLimit + msgOfs, + PWR_BUF_LEN - msgOfs, + "%d,", + *(prcRatePwr + j)); + + /*message tail*/ + if (msgOfs > 0) + msgLimit[msgOfs-1] = '\0'; + else + msgLimit[0] = '\0'; + + DBGLOG(RLM, TRACE, "%s:%s\n", message, msgLimit); + } + } + +} + +void rlmDomainSendPwrLimitCmd(struct ADAPTER *prAdapter) +{ + struct CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT *prCmd = NULL; + struct CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT *prCmdHE = NULL; + uint32_t rStatus; + uint16_t u2DefaultTableIndex; + uint32_t u4SetCmdTableMaxSize; + uint32_t u4SetCmdTableMaxSizeHE; + uint32_t u4SetQueryInfoLen; + uint32_t u4SetQueryInfoLenHE; + uint8_t bandedgeParam[4] = { 0, 0, 0, 0 }; + struct DOMAIN_INFO_ENTRY *prDomainInfo; + /* TODO : 5G band edge */ + prDomainInfo = rlmDomainGetDomainInfo(prAdapter); + if (prDomainInfo) { + bandedgeParam[0] = prDomainInfo->rSubBand[0].ucFirstChannelNum; + bandedgeParam[1] = bandedgeParam[0] + + prDomainInfo->rSubBand[0].ucNumChannels - 1; + } + + if (regd_is_single_sku_en()) + return rlmDomainSendPwrLimitCmd_V2(prAdapter); + + + u4SetCmdTableMaxSize = + sizeof(struct CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT); + + u4SetCmdTableMaxSizeHE = + sizeof(struct CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT); + + + prCmd = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, u4SetCmdTableMaxSize); + + if (!prCmd) { + DBGLOG(RLM, ERROR, "Domain: Alloc cmd buffer failed\n"); + goto err; + } + + prCmdHE = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, u4SetCmdTableMaxSizeHE); + + if (!prCmdHE) { + DBGLOG(RLM, ERROR, "Domain: Alloc cmd buffer failed\n"); + goto err; + } + + kalMemZero(prCmd, u4SetCmdTableMaxSize); + kalMemZero(prCmdHE, u4SetCmdTableMaxSize); + + u2DefaultTableIndex = + rlmDomainPwrLimitDefaultTableDecision(prAdapter, + prAdapter->rWifiVar.u2CountryCode); + + if (u2DefaultTableIndex == POWER_LIMIT_TABLE_NULL) { + DBGLOG(RLM, ERROR, + "Can't find any table index!\n"); + goto err; + } + + WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitDefault + [u2DefaultTableIndex] + .aucCountryCode[0], + &prCmd->u2CountryCode); + WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitDefault + [u2DefaultTableIndex] + .aucCountryCode[0], + &prCmdHE->u2CountryCode); + + if (prCmd->u2CountryCode == COUNTRY_CODE_NULL) + DBGLOG(RLM, WARN, + "CC={0x00,0x00},Power Limit use Default setting!"); + + + /* Initialize channel number */ + prCmd->ucNum = 0; + prCmd->ucLimitType = PWR_LIMIT_TYPE_COMP_11AC; + + prCmdHE->ucNum = 0; + prCmdHE->fgPwrTblKeep = TRUE; + prCmdHE->ucLimitType = PWR_LIMIT_TYPE_COMP_11AX; + + + /*<1>Command - default table information, + *fill all subband + */ + rlmDomainBuildCmdByDefaultTable(prCmd, + u2DefaultTableIndex); + + /*<2>Command - configuration table information, + * replace specified channel + */ + rlmDomainBuildCmdByConfigTable(prAdapter, + prCmd); + +#if (CFG_SUPPORT_PWR_LIMIT_HE == 1) + /*<1>Command - default table information, + *fill all subband + */ + rlmDomainBuildCmdByDefaultTable(prCmdHE, + u2DefaultTableIndex); + + /*<2>Command - configuration table information, + * replace specified channel + */ + rlmDomainBuildCmdByConfigTable(prAdapter, + prCmdHE); +#endif + + DBGLOG(RLM, INFO, + "Domain: ValidCC=%c%c, PwrLimitCC=%c%c, PwrLimitChNum=%d\n", + (prAdapter->rWifiVar.u2CountryCode & 0xff00) >> 8, + (prAdapter->rWifiVar.u2CountryCode & 0x00ff), + ((prCmd->u2CountryCode & 0xff00) >> 8), + (prCmd->u2CountryCode & 0x00ff), + prCmd->ucNum); + +#if CFG_SUPPORT_DYNAMIC_PWR_LIMIT + rlmDomainShowPwrLimitPerCh("Old", prCmd); + /* apply each setting into country channel power table */ + txPwrCtrlApplySettings(prAdapter, prCmd, bandedgeParam); + /* show tx power table after applying setting */ + rlmDomainShowPwrLimitPerCh("Final", prCmd); + +#if (CFG_SUPPORT_PWR_LIMIT_HE == 1) + rlmDomainShowPwrLimitPerCh("Old", prCmdHE); + txPwrCtrlApplySettings(prAdapter, prCmdHE, bandedgeParam); + rlmDomainShowPwrLimitPerCh("Final", prCmdHE); +#endif /*#if (CFG_SUPPORT_PWR_LIMIT_HE == 1)*/ +#endif + + + u4SetQueryInfoLen = + sizeof(struct CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT); + + u4SetQueryInfoLenHE = + sizeof(struct CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT); + + + /* Update domain info to chip */ + if (prCmd->ucNum <= MAX_CMD_SUPPORT_CHANNEL_NUM) { + rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ + CMD_ID_SET_COUNTRY_POWER_LIMIT, /* ucCID */ + TRUE, /* fgSetQuery */ + FALSE, /* fgNeedResp */ + FALSE, /* fgIsOid */ + NULL, /* pfCmdDoneHandler */ + NULL, /* pfCmdTimeoutHandler */ + u4SetQueryInfoLen, /* u4SetQueryInfoLen */ + (uint8_t *) prCmd, /* pucInfoBuffer */ + NULL, /* pvSetQueryBuffer */ + 0 /* u4SetQueryBufferLen */ + ); +#if (CFG_SUPPORT_PWR_LIMIT_HE == 1) + rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ + CMD_ID_SET_COUNTRY_POWER_LIMIT, /* ucCID */ + TRUE, /* fgSetQuery */ + FALSE, /* fgNeedResp */ + FALSE, /* fgIsOid */ + NULL, /* pfCmdDoneHandler */ + NULL, /* pfCmdTimeoutHandler */ + u4SetQueryInfoLenHE, /* u4SetQueryInfoLen */ + (uint8_t *) prCmdHE, /* pucInfoBuffer */ + NULL, /* pvSetQueryBuffer */ + 0 /* u4SetQueryBufferLen */ + ); +#endif + } else { + DBGLOG(RLM, ERROR, "Domain: illegal power limit table\n"); + } + + /* ASSERT(rStatus == WLAN_STATUS_PENDING); */ +err: + cnmMemFree(prAdapter, prCmd); + cnmMemFree(prAdapter, prCmdHE); + +} +#endif +u_int8_t regd_is_single_sku_en(void) +{ +#if (CFG_SUPPORT_SINGLE_SKU == 1) + return g_mtk_regd_control.en; +#else + return FALSE; +#endif +} + +#if (CFG_SUPPORT_SINGLE_SKU == 1) +u_int8_t rlmDomainIsCtrlStateEqualTo(enum regd_state state) +{ + return (g_mtk_regd_control.state == state) ? TRUE : FALSE; +} + +enum regd_state rlmDomainGetCtrlState(void) +{ + return g_mtk_regd_control.state; +} + + +void rlmDomainResetActiveChannel(void) +{ + g_mtk_regd_control.n_channel_active_2g = 0; + g_mtk_regd_control.n_channel_active_5g = 0; +} + +void rlmDomainAddActiveChannel(u8 band) + +{ + if (band == KAL_BAND_2GHZ) + g_mtk_regd_control.n_channel_active_2g += 1; + else if (band == KAL_BAND_5GHZ) + g_mtk_regd_control.n_channel_active_5g += 1; +} + +u8 rlmDomainGetActiveChannelCount(u8 band) +{ + if (band == KAL_BAND_2GHZ) + return g_mtk_regd_control.n_channel_active_2g; + else if (band == KAL_BAND_5GHZ) + return g_mtk_regd_control.n_channel_active_5g; + else + return 0; +} + +struct CMD_DOMAIN_CHANNEL *rlmDomainGetActiveChannels(void) +{ + return g_mtk_regd_control.channels; +} + +void rlmDomainSetDefaultCountryCode(void) +{ + g_mtk_regd_control.alpha2 = COUNTRY_CODE_WW; +} + +void rlmDomainResetCtrlInfo(u_int8_t force) +{ + if ((g_mtk_regd_control.state == REGD_STATE_UNDEFINED) || + (force == TRUE)) { + memset(&g_mtk_regd_control, 0, sizeof(struct mtk_regd_control)); + + g_mtk_regd_control.state = REGD_STATE_INIT; + + rlmDomainSetDefaultCountryCode(); + +#if (CFG_SUPPORT_SINGLE_SKU_LOCAL_DB == 1) + g_mtk_regd_control.flag |= REGD_CTRL_FLAG_SUPPORT_LOCAL_REGD_DB; +#endif + } +} + +u_int8_t rlmDomainIsUsingLocalRegDomainDataBase(void) +{ +#if (CFG_SUPPORT_SINGLE_SKU_LOCAL_DB == 1) + return (g_mtk_regd_control.flag & REGD_CTRL_FLAG_SUPPORT_LOCAL_REGD_DB) + ? TRUE : FALSE; +#else + return FALSE; +#endif +} + +bool rlmDomainIsSameCountryCode(char *alpha2, u8 size_of_alpha2) +{ + u8 idx; + u32 alpha2_hex = 0; + + for (idx = 0; idx < size_of_alpha2; idx++) + alpha2_hex |= (alpha2[idx] << (idx * 8)); + + return (rlmDomainGetCountryCode() == alpha2_hex) ? TRUE : FALSE; +} + +void rlmDomainSetCountryCode(char *alpha2, u8 size_of_alpha2) +{ + u8 max; + u8 buf_size; + + buf_size = sizeof(g_mtk_regd_control.alpha2); + max = (buf_size < size_of_alpha2) ? buf_size : size_of_alpha2; + + g_mtk_regd_control.alpha2 = rlmDomainAlpha2ToU32(alpha2, max); +} +void rlmDomainSetDfsRegion(enum nl80211_dfs_regions dfs_region) +{ + g_mtk_regd_control.dfs_region = dfs_region; +} + +enum nl80211_dfs_regions rlmDomainGetDfsRegion(void) +{ + return g_mtk_regd_control.dfs_region; +} + +void rlmDomainSetTempCountryCode(char *alpha2, u8 size_of_alpha2) +{ + u8 idx, max; + u8 buf_size; + + buf_size = sizeof(g_mtk_regd_control.tmp_alpha2); + max = (buf_size < size_of_alpha2) ? buf_size : size_of_alpha2; + + g_mtk_regd_control.tmp_alpha2 = 0; + + for (idx = 0; idx < max; idx++) + g_mtk_regd_control.tmp_alpha2 |= (alpha2[idx] << (idx * 8)); + +} + +enum regd_state rlmDomainStateTransition(enum regd_state request_state, + struct regulatory_request *pRequest) +{ + enum regd_state next_state, old_state; + bool the_same = 0; + + old_state = g_mtk_regd_control.state; + next_state = REGD_STATE_INVALID; + + if (old_state == REGD_STATE_INVALID) + DBGLOG(RLM, ERROR, + "%s(): invalid state. trasntion is not allowed.\n", + __func__); + + switch (request_state) { + case REGD_STATE_SET_WW_CORE: + if ((old_state == REGD_STATE_SET_WW_CORE) || + (old_state == REGD_STATE_INIT) || + (old_state == REGD_STATE_SET_COUNTRY_USER) || + (old_state == REGD_STATE_SET_COUNTRY_IE)) + next_state = request_state; + break; + case REGD_STATE_SET_COUNTRY_USER: + /* Allow user to set multiple times */ + if ((old_state == REGD_STATE_SET_WW_CORE) || + (old_state == REGD_STATE_INIT) || + (old_state == REGD_STATE_SET_COUNTRY_USER) || + (old_state == REGD_STATE_SET_COUNTRY_IE)) + next_state = request_state; + else + DBGLOG(RLM, ERROR, "Invalid old state = %d\n", + old_state); + break; + case REGD_STATE_SET_COUNTRY_DRIVER: + if (old_state == REGD_STATE_SET_COUNTRY_USER) { + /* + * Error. + * Mixing using set_country_by_user and + * set_country_by_driver is not allowed. + */ + break; + } + + next_state = request_state; + break; + case REGD_STATE_SET_COUNTRY_IE: + next_state = request_state; + break; + default: + break; + } + + if (next_state == REGD_STATE_INVALID) { + DBGLOG(RLM, ERROR, + "%s(): ERROR. trasntion to invalid state. o=%x, r=%x, s=%x\n", + __func__, old_state, request_state, the_same); + } else + DBGLOG(RLM, INFO, "%s(): trasntion to state = %x (old = %x)\n", + __func__, next_state, g_mtk_regd_control.state); + + g_mtk_regd_control.state = next_state; + + return g_mtk_regd_control.state; +} + +/** + * rlmDomainChannelFlagString - Transform channel flags to readable string + * + * @ flags: the ieee80211_channel->flags for a channel + * @ buf: string buffer to put the transformed string + * @ buf_size: size of the buf + **/ +void rlmDomainChannelFlagString(u32 flags, char *buf, size_t buf_size) +{ + int32_t buf_written = 0; + + if (!flags || !buf || !buf_size) + return; + + if (flags & IEEE80211_CHAN_DISABLED) { + LOGBUF(buf, ((int32_t)buf_size), buf_written, "DISABLED "); + /* If DISABLED, don't need to check other flags */ + return; + } + if (flags & IEEE80211_CHAN_PASSIVE_FLAG) + LOGBUF(buf, ((int32_t)buf_size), buf_written, + IEEE80211_CHAN_PASSIVE_STR " "); + if (flags & IEEE80211_CHAN_RADAR) + LOGBUF(buf, ((int32_t)buf_size), buf_written, "RADAR "); + if (flags & IEEE80211_CHAN_NO_HT40PLUS) + LOGBUF(buf, ((int32_t)buf_size), buf_written, "NO_HT40PLUS "); + if (flags & IEEE80211_CHAN_NO_HT40MINUS) + LOGBUF(buf, ((int32_t)buf_size), buf_written, "NO_HT40MINUS "); + if (flags & IEEE80211_CHAN_NO_80MHZ) + LOGBUF(buf, ((int32_t)buf_size), buf_written, "NO_80MHZ "); + if (flags & IEEE80211_CHAN_NO_160MHZ) + LOGBUF(buf, ((int32_t)buf_size), buf_written, "NO_160MHZ "); +} + +void rlmDomainParsingChannel(IN struct wiphy *pWiphy) +{ + u32 band_idx, ch_idx; + u32 ch_count; + struct ieee80211_supported_band *sband; + struct ieee80211_channel *chan; + struct CMD_DOMAIN_CHANNEL *pCh; + char chan_flag_string[64] = {0}; +#if (CFG_SUPPORT_REGD_UPDATE_DISCONNECT_ALLOWED == 1) + struct GLUE_INFO *prGlueInfo; + bool fgDisconnection = FALSE; + uint8_t ucChannelNum = 0; + uint32_t rStatus, u4BufLen; +#endif + + if (!pWiphy) { + DBGLOG(RLM, ERROR, "%s(): ERROR. pWiphy = NULL.\n", __func__); + ASSERT(0); + return; + } + +#if (CFG_SUPPORT_REGD_UPDATE_DISCONNECT_ALLOWED == 1) + /* Retrieve connected channel */ + prGlueInfo = rlmDomainGetGlueInfo(); + if (prGlueInfo && kalGetMediaStateIndicated(prGlueInfo) == + MEDIA_STATE_CONNECTED) { + ucChannelNum = + wlanGetChannelNumberByNetwork(prGlueInfo->prAdapter, + prGlueInfo->prAdapter->prAisBssInfo->ucBssIndex); + } +#endif + /* + * Ready to parse the channel for bands + */ + + rlmDomainResetActiveChannel(); + + ch_count = 0; + for (band_idx = 0; band_idx < KAL_NUM_BANDS; band_idx++) { + sband = pWiphy->bands[band_idx]; + if (!sband) + continue; + + for (ch_idx = 0; ch_idx < sband->n_channels; ch_idx++) { + chan = &sband->channels[ch_idx]; + pCh = (rlmDomainGetActiveChannels() + ch_count); + /* Parse flags and get readable string */ + rlmDomainChannelFlagString(chan->flags, + chan_flag_string, + sizeof(chan_flag_string)); + + if (chan->flags & IEEE80211_CHAN_DISABLED) { + DBGLOG(RLM, INFO, + "channels[%d][%d]: ch%d (freq = %d) flags=0x%x [ %s]\n", + band_idx, ch_idx, chan->hw_value, + chan->center_freq, chan->flags, + chan_flag_string); +#if (CFG_SUPPORT_REGD_UPDATE_DISCONNECT_ALLOWED == 1) + /* Disconnect AP in the end of this function*/ + if (chan->hw_value == ucChannelNum) + fgDisconnection = TRUE; +#endif + continue; + } + + /* Allowable channel */ + if (ch_count == MAX_SUPPORTED_CH_COUNT) { + DBGLOG(RLM, ERROR, + "%s(): no buffer to store channel information.\n", + __func__); + break; + } + + rlmDomainAddActiveChannel(band_idx); + + DBGLOG(RLM, INFO, + "channels[%d][%d]: ch%d (freq = %d) flgs=0x%x [%s]\n", + band_idx, ch_idx, chan->hw_value, + chan->center_freq, chan->flags, + chan_flag_string); + + pCh->u2ChNum = chan->hw_value; + pCh->eFlags = chan->flags; + + ch_count += 1; + } + + } +#if (CFG_SUPPORT_REGD_UPDATE_DISCONNECT_ALLOWED == 1) + /* Disconnect with AP if connected channel is disabled in new country */ + if (fgDisconnection) { + DBGLOG(RLM, STATE, "%s(): Disconnect! CH%d is DISABLED\n", + __func__, ucChannelNum); + rStatus = kalIoctl(prGlueInfo, wlanoidSetDisassociate, + NULL, 0, FALSE, FALSE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(RLM, WARN, "disassociate error:%lx\n", rStatus); + } +#endif +} +void rlmExtractChannelInfo(u32 max_ch_count, + struct CMD_DOMAIN_ACTIVE_CHANNEL_LIST *prBuff) +{ + u32 ch_count, idx; + struct CMD_DOMAIN_CHANNEL *pCh; + + prBuff->u1ActiveChNum2g = rlmDomainGetActiveChannelCount(KAL_BAND_2GHZ); + prBuff->u1ActiveChNum5g = rlmDomainGetActiveChannelCount(KAL_BAND_5GHZ); + ch_count = prBuff->u1ActiveChNum2g + prBuff->u1ActiveChNum5g; + + if (ch_count > max_ch_count) { + ch_count = max_ch_count; + DBGLOG(RLM, WARN, + "%s(); active channel list is not a complete one.\n", + __func__); + } + + for (idx = 0; idx < ch_count; idx++) { + pCh = &(prBuff->arChannels[idx]); + + pCh->u2ChNum = (rlmDomainGetActiveChannels() + idx)->u2ChNum; + pCh->eFlags = (rlmDomainGetActiveChannels() + idx)->eFlags; + } + +} + +const struct ieee80211_regdomain +*rlmDomainSearchRegdomainFromLocalDataBase(char *alpha2) +{ +#if (CFG_SUPPORT_SINGLE_SKU_LOCAL_DB == 1) + u8 idx; + const struct mtk_regdomain *prRegd; + + idx = 0; + while (g_prRegRuleTable[idx]) { + prRegd = g_prRegRuleTable[idx]; + + if ((prRegd->country_code[0] == alpha2[0]) && + (prRegd->country_code[1] == alpha2[1]) && + (prRegd->country_code[2] == alpha2[2]) && + (prRegd->country_code[3] == alpha2[3])) + return prRegd->prRegdRules; + + idx++; + } + + DBGLOG(RLM, ERROR, + "%s(): Error, Cannot find the correct RegDomain. country = %s\n", + __func__, alpha2); + DBGLOG(RLM, INFO, " Set as default WW.\n"); + + return &default_regdom_ww; /*default world wide*/ +#else + return NULL; +#endif +} + + +const struct ieee80211_regdomain *rlmDomainGetLocalDefaultRegd(void) +{ +#if (CFG_SUPPORT_SINGLE_SKU_LOCAL_DB == 1) + return &default_regdom_ww; +#else + return NULL; +#endif +} +struct GLUE_INFO *rlmDomainGetGlueInfo(void) +{ + return g_mtk_regd_control.pGlueInfo; +} + +bool rlmDomainIsEfuseUsed(void) +{ + return g_mtk_regd_control.isEfuseCountryCodeUsed; +} + +uint8_t rlmDomainGetChannelBw(uint8_t channelNum) +{ + uint32_t ch_idx = 0, start_idx = 0, end_idx = 0; + uint8_t channelBw = MAX_BW_80_80_MHZ; + struct CMD_DOMAIN_CHANNEL *pCh; + + end_idx = rlmDomainGetActiveChannelCount(KAL_BAND_2GHZ) + + rlmDomainGetActiveChannelCount(KAL_BAND_5GHZ); + + for (ch_idx = start_idx; ch_idx < end_idx; ch_idx++) { + pCh = (rlmDomainGetActiveChannels() + ch_idx); + + if (pCh->u2ChNum != channelNum) + continue; + + /* Max BW */ + if ((pCh->eFlags & IEEE80211_CHAN_NO_160MHZ) + == IEEE80211_CHAN_NO_160MHZ) + channelBw = MAX_BW_80MHZ; + if ((pCh->eFlags & IEEE80211_CHAN_NO_80MHZ) + == IEEE80211_CHAN_NO_80MHZ) + channelBw = MAX_BW_40MHZ; + if ((pCh->eFlags & IEEE80211_CHAN_NO_HT40) + == IEEE80211_CHAN_NO_HT40) + channelBw = MAX_BW_20MHZ; + } + + DBGLOG(RLM, TRACE, "ch=%d, BW=%d\n", channelNum, channelBw); + return channelBw; +} +#endif + +uint32_t rlmDomainExtractSingleSkuInfoFromFirmware(IN struct ADAPTER *prAdapter, + IN uint8_t *pucEventBuf) +{ +#if (CFG_SUPPORT_SINGLE_SKU == 1) + struct SINGLE_SKU_INFO *prSkuInfo = + (struct SINGLE_SKU_INFO *) pucEventBuf; + + g_mtk_regd_control.en = TRUE; + + if (prSkuInfo->isEfuseValid) { + if (!rlmDomainIsUsingLocalRegDomainDataBase()) { + + DBGLOG(RLM, ERROR, + "%s(): Error. In efuse mode, must use local data base.\n", + __func__); + + ASSERT(0); + /* force using local db if getting + * country code from efuse + */ + return WLAN_STATUS_NOT_SUPPORTED; + } + + rlmDomainSetCountryCode((char *) &prSkuInfo->u4EfuseCountryCode, + sizeof(prSkuInfo->u4EfuseCountryCode)); + g_mtk_regd_control.isEfuseCountryCodeUsed = TRUE; + + } +#endif + + return WLAN_STATUS_SUCCESS; +} + +void rlmDomainSendInfoToFirmware(IN struct ADAPTER *prAdapter) +{ +#if (CFG_SUPPORT_SINGLE_SKU == 1) + struct regulatory_request request; + struct regulatory_request *prReq = NULL; + + if (!regd_is_single_sku_en()) + return; /*not support single sku*/ + + if (g_mtk_regd_control.isEfuseCountryCodeUsed) { + request.initiator = NL80211_REGDOM_SET_BY_DRIVER; + prReq = &request; + } + + g_mtk_regd_control.pGlueInfo = prAdapter->prGlueInfo; + mtk_reg_notify(priv_to_wiphy(prAdapter->prGlueInfo), prReq); +#endif +} + +enum ENUM_CHNL_EXT rlmSelectSecondaryChannelType(struct ADAPTER *prAdapter, + enum ENUM_BAND band, + u8 primary_ch) +{ +#if (CFG_SUPPORT_SINGLE_SKU == 1) + u8 below_ch, above_ch; + + below_ch = primary_ch - CHNL_SPAN_20; + above_ch = primary_ch + CHNL_SPAN_20; + + if (rlmDomainIsLegalChannel(prAdapter, band, above_ch)) + return CHNL_EXT_SCA; + + if (rlmDomainIsLegalChannel(prAdapter, band, below_ch)) + return CHNL_EXT_SCB; + +#endif + + return CHNL_EXT_SCN; +} + +void rlmDomainOidSetCountry(IN struct ADAPTER *prAdapter, char *country, + u8 size_of_country) +{ +#if (CFG_SUPPORT_SINGLE_SKU == 1) + struct regulatory_request request; + kalMemZero(&request, sizeof(request)); + + if (rlmDomainIsUsingLocalRegDomainDataBase()) { + rlmDomainSetTempCountryCode(country, size_of_country); + request.initiator = NL80211_REGDOM_SET_BY_DRIVER; + mtk_reg_notify(priv_to_wiphy(prAdapter->prGlueInfo), &request); + } else { + DBGLOG(RLM, INFO, + "%s(): Using driver hint to query CRDA getting regd.\n", + __func__); + regulatory_hint(priv_to_wiphy(prAdapter->prGlueInfo), country); + } +#endif +} + +u32 rlmDomainGetCountryCode(void) +{ +#if (CFG_SUPPORT_SINGLE_SKU == 1) + return g_mtk_regd_control.alpha2; +#else + return 0; +#endif +} + +u32 rlmDomainGetTempCountryCode(void) +{ +#if (CFG_SUPPORT_SINGLE_SKU == 1) + return g_mtk_regd_control.tmp_alpha2; +#else + return 0; +#endif +} + +void rlmDomainAssert(u_int8_t cond) +{ + /* bypass this check because single sku is not enable */ + if (!regd_is_single_sku_en()) + return; + + if (!cond) { + WARN_ON(1); + DBGLOG(RLM, ERROR, "[WARNING!!] RLM unexpected case.\n"); + } + +} + + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/rlm_obss.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/rlm_obss.c new file mode 100644 index 0000000000000000000000000000000000000000..783917236729d8777043005c2a50519b36ea938b --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/rlm_obss.c @@ -0,0 +1,402 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rlm_obss.c#2 + */ + +/*! \file "rlm_obss.c" + * \brief + * + */ + + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +static void rlmObssScanTimeout(struct ADAPTER *prAdapter, + unsigned long ulParamPtr); + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rlmObssInit(struct ADAPTER *prAdapter) +{ + struct BSS_INFO *prBssInfo; + uint8_t i; + + ASSERT(prAdapter); + + for (i = 0; i < prAdapter->ucHwBssIdNum; i++) { + prBssInfo = prAdapter->aprBssInfo[i]; + + cnmTimerInitTimer(prAdapter, &prBssInfo->rObssScanTimer, + (PFN_MGMT_TIMEOUT_FUNC) rlmObssScanTimeout, + (unsigned long) prBssInfo); + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +u_int8_t rlmObssUpdateChnlLists(struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb) +{ + return TRUE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rlmObssScanDone(struct ADAPTER *prAdapter, struct MSG_HDR *prMsgHdr) +{ + struct MSG_SCN_SCAN_DONE *prScanDoneMsg; + struct BSS_INFO *prBssInfo; + struct MSDU_INFO *prMsduInfo; + struct ACTION_20_40_COEXIST_FRAME *prTxFrame; + uint16_t i, u2PayloadLen; + + ASSERT(prMsgHdr); + + prScanDoneMsg = (struct MSG_SCN_SCAN_DONE *) prMsgHdr; + prBssInfo = prAdapter->aprBssInfo[prScanDoneMsg->ucBssIndex]; + ASSERT(prBssInfo); + + DBGLOG(RLM, INFO, "OBSS Scan Done (NetIdx=%d, Mode=%d)\n", + prScanDoneMsg->ucBssIndex, prBssInfo->eCurrentOPMode); + + cnmMemFree(prAdapter, prMsgHdr); + +#if CFG_ENABLE_WIFI_DIRECT + /* AP mode */ + if ((prAdapter->fgIsP2PRegistered) && + (IS_NET_ACTIVE(prAdapter, prBssInfo->ucBssIndex)) && + (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT)) { + return; + } +#endif + + /* STA mode */ + if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE || + !RLM_NET_PARAM_VALID(prBssInfo) || + prBssInfo->u2ObssScanInterval == 0) { + DBGLOG(RLM, WARN, "OBSS Scan Done (NetIdx=%d) -- Aborted!!\n", + prBssInfo->ucBssIndex); + return; + } + + /* To do: check 2.4G channel list to decide if obss mgmt should be + * sent to associated AP. Note: how to handle concurrent network? + * To do: invoke rlmObssChnlLevel() to decide if 20/40 BSS coexistence + * management frame is needed. + */ + if (prBssInfo->auc2G_20mReqChnlList[0] > 0 || + prBssInfo->auc2G_NonHtChnlList[0] > 0) { + + DBGLOG(RLM, INFO, + "Send 20/40 coexistence mgmt(20mReq=%d, NonHt=%d)\n", + prBssInfo->auc2G_20mReqChnlList[0], + prBssInfo->auc2G_NonHtChnlList[0]); + + prMsduInfo = (struct MSDU_INFO *) cnmMgtPktAlloc(prAdapter, + MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN); + + if (prMsduInfo) { + prTxFrame = (struct ACTION_20_40_COEXIST_FRAME *) + ((unsigned long) (prMsduInfo->prPacket) + + MAC_TX_RESERVED_FIELD); + + prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; + COPY_MAC_ADDR(prTxFrame->aucDestAddr, + prBssInfo->aucBSSID); + COPY_MAC_ADDR(prTxFrame->aucSrcAddr, + prBssInfo->aucOwnMacAddr); + COPY_MAC_ADDR(prTxFrame->aucBSSID, + prBssInfo->aucBSSID); + + prTxFrame->ucCategory = CATEGORY_PUBLIC_ACTION; + prTxFrame->ucAction = ACTION_PUBLIC_20_40_COEXIST; + + /* To do: find correct algorithm */ + prTxFrame->rBssCoexist.ucId = + ELEM_ID_20_40_BSS_COEXISTENCE; + prTxFrame->rBssCoexist.ucLength = 1; + prTxFrame->rBssCoexist.ucData = + (prBssInfo->auc2G_20mReqChnlList[0] > 0) ? + BSS_COEXIST_20M_REQ : 0; + + u2PayloadLen = 2 + 3; + + if (prBssInfo->auc2G_NonHtChnlList[0] > 0) { + ASSERT(prBssInfo->auc2G_NonHtChnlList[0] <= + CHNL_LIST_SZ_2G); + + prTxFrame->rChnlReport.ucId = + ELEM_ID_20_40_INTOLERANT_CHNL_REPORT; + prTxFrame->rChnlReport.ucLength = + prBssInfo->auc2G_NonHtChnlList[0] + 1; + /* 2.4GHz, ch1~13 */ + prTxFrame->rChnlReport.ucRegulatoryClass = 81; + for (i = 0; + i < prBssInfo->auc2G_NonHtChnlList[0] && + i < CHNL_LIST_SZ_2G; i++) + prTxFrame->rChnlReport.aucChannelList[i] + = prBssInfo-> + auc2G_NonHtChnlList[i + 1]; + + u2PayloadLen += IE_SIZE(&prTxFrame-> + rChnlReport); + } + ASSERT((WLAN_MAC_HEADER_LEN + u2PayloadLen) <= + PUBLIC_ACTION_MAX_LEN); + + /* Clear up channel lists in 2.4G band */ + prBssInfo->auc2G_20mReqChnlList[0] = 0; + prBssInfo->auc2G_NonHtChnlList[0] = 0; + + /* 4 Update information of MSDU_INFO_T */ + + TX_SET_MMPDU(prAdapter, + prMsduInfo, + prBssInfo->ucBssIndex, + prBssInfo->prStaRecOfAP->ucIndex, + WLAN_MAC_MGMT_HEADER_LEN, + WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen, + NULL, MSDU_RATE_MODE_AUTO); + + /* 4 Enqueue the frame to send this action frame. */ + nicTxEnqueueMsdu(prAdapter, prMsduInfo); + } + } + /* end of prMsduInfo != NULL */ + if (prBssInfo->u2ObssScanInterval > 0) { + DBGLOG(RLM, INFO, "Set OBSS timer (NetIdx=%d, %d sec)\n", + prBssInfo->ucBssIndex, prBssInfo->u2ObssScanInterval); + + cnmTimerStartTimer(prAdapter, &prBssInfo->rObssScanTimer, + prBssInfo-> + u2ObssScanInterval * MSEC_PER_SEC); + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +static void rlmObssScanTimeout(struct ADAPTER *prAdapter, + unsigned long ulParamPtr) +{ + struct BSS_INFO *prBssInfo; + + prBssInfo = (struct BSS_INFO *) ulParamPtr; + ASSERT(prBssInfo); + +#if CFG_ENABLE_WIFI_DIRECT + /* AP mode */ + if (prAdapter->fgIsP2PRegistered && + (IS_NET_ACTIVE(prAdapter, prBssInfo->ucBssIndex)) && + (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT)) { + + prBssInfo->fgObssActionForcedTo20M = FALSE; + + /* Check if Beacon content need to be updated */ + rlmUpdateParamsForAP(prAdapter, prBssInfo, FALSE); + + return; + } +#if CFG_SUPPORT_WFD + /* WFD streaming */ + else { + struct WFD_CFG_SETTINGS *prWfdCfgSettings = + &prAdapter->rWifiVar.rWfdConfigureSettings; + + /* If WFD is enabled & connected */ + if (prWfdCfgSettings->ucWfdEnable) { + + /* Skip OBSS scan */ + prBssInfo->u2ObssScanInterval = 0; + DBGLOG(RLM, INFO, "WFD is running. Stop OBSS scan.\n"); + return; + } /* WFD is enabled */ + } +#endif +#endif /* end of CFG_ENABLE_WIFI_DIRECT */ + + /* STA mode */ + if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE || + !RLM_NET_PARAM_VALID(prBssInfo) || + prBssInfo->u2ObssScanInterval == 0) { + DBGLOG(RLM, WARN, + "OBSS Scan timeout (NetIdx=%d) -- Aborted!!\n", + prBssInfo->ucBssIndex); + return; + } + + rlmObssTriggerScan(prAdapter, prBssInfo); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rlmObssTriggerScan(struct ADAPTER *prAdapter, struct BSS_INFO *prBssInfo) +{ + struct MSG_SCN_SCAN_REQ_V2 *prScanReqMsg; + + if (prBssInfo == NULL) { + DBGLOG(RLM, WARN, "BssInfo = NULL!"); + return; + } + + prScanReqMsg = (struct MSG_SCN_SCAN_REQ_V2 *) + cnmMemAlloc(prAdapter, RAM_TYPE_MSG, + sizeof(struct MSG_SCN_SCAN_REQ_V2)); + + if (!prScanReqMsg) { + DBGLOG(RLM, WARN, "No buf for OBSS scan (NetIdx=%d)!!\n", + prBssInfo->ucBssIndex); + + cnmTimerStartTimer(prAdapter, &prBssInfo->rObssScanTimer, + prBssInfo-> + u2ObssScanInterval * MSEC_PER_SEC); + return; + } + + /* It is ok that ucSeqNum is set to fixed value because the same network + * OBSS scan interval is limited to OBSS_SCAN_MIN_INTERVAL (min 10 sec) + * and scan module don't care seqNum of OBSS scanning + */ + kalMemZero(prScanReqMsg, sizeof(struct MSG_SCN_SCAN_REQ_V2)); + prScanReqMsg->rMsgHdr.eMsgId = MID_RLM_SCN_SCAN_REQ_V2; + prScanReqMsg->ucSeqNum = 0x33; + prScanReqMsg->ucBssIndex = prBssInfo->ucBssIndex; + prScanReqMsg->eScanType = SCAN_TYPE_ACTIVE_SCAN; + prScanReqMsg->ucSSIDType = SCAN_REQ_SSID_WILDCARD; + prScanReqMsg->ucSSIDNum = 0; + prScanReqMsg->eScanChannel = SCAN_CHANNEL_2G4; + prScanReqMsg->u2IELen = 0; + + mboxSendMsg(prAdapter, MBOX_ID_0, (struct MSG_HDR *) prScanReqMsg, + MSG_SEND_METHOD_BUF); + + DBGLOG(RLM, INFO, "Timeout to trigger OBSS scan (NetIdx=%d)!!\n", + prBssInfo->ucBssIndex); +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/rlm_protection.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/rlm_protection.c new file mode 100644 index 0000000000000000000000000000000000000000..b6375a44c5abc9223f688dd8fa411931c4decd91 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/rlm_protection.c @@ -0,0 +1,105 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/ + * rlm_protection.c#1 + */ + +/*! \file "rlm_protection.c" + * \brief + * + */ + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/roaming_fsm.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/roaming_fsm.c new file mode 100644 index 0000000000000000000000000000000000000000..37a87a3819afd8d5e4ac1ac72e8e9a617491c9ab --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/roaming_fsm.c @@ -0,0 +1,816 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: + */ + +/*! \file "roaming_fsm.c" + * \brief This file defines the FSM for Roaming MODULE. + * + * This file defines the FSM for Roaming MODULE. + */ + + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" + +#if CFG_SUPPORT_ROAMING +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ +static uint8_t *apucDebugRoamingState[ROAMING_STATE_NUM] = { + (uint8_t *) DISP_STRING("IDLE"), + (uint8_t *) DISP_STRING("DECISION"), + (uint8_t *) DISP_STRING("DISCOVERY"), + (uint8_t *) DISP_STRING("REQ_CAND_LIST"), + (uint8_t *) DISP_STRING("ROAM") +}; + + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +static void roamingWaitCandidateTimeout(IN struct ADAPTER *prAdapter, + unsigned long ulParamPtr) +{ + uint8_t ucBssIndex = (uint8_t) ulParamPtr; + struct ROAMING_INFO *prRoamingFsmInfo; + + prRoamingFsmInfo = aisGetRoamingInfo(prAdapter, ucBssIndex); + if (prRoamingFsmInfo->eCurrentState == ROAMING_STATE_DECISION) { + aisResetNeighborApList(prAdapter, ucBssIndex); + aisSendNeighborRequest(prAdapter, ucBssIndex); + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Initialize the value in ROAMING_FSM_INFO_T for ROAMING FSM operation + * + * @param [IN P_ADAPTER_T] prAdapter + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void roamingFsmInit(IN struct ADAPTER *prAdapter, IN uint8_t ucBssIndex) +{ + struct ROAMING_INFO *prRoamingFsmInfo; + struct CONNECTION_SETTINGS *prConnSettings; + + DBGLOG(ROAMING, LOUD, + "[%d]->roamingFsmInit(): Current Time = %d\n", + ucBssIndex, + kalGetTimeTick()); + + prRoamingFsmInfo = + aisGetRoamingInfo(prAdapter, ucBssIndex); + prConnSettings = + aisGetConnSettings(prAdapter, ucBssIndex); + + /* 4 <1> Initiate FSM */ + prRoamingFsmInfo->fgIsEnableRoaming = + prConnSettings->fgIsEnableRoaming; + prRoamingFsmInfo->eCurrentState = ROAMING_STATE_IDLE; + prRoamingFsmInfo->rRoamingDiscoveryUpdateTime = 0; + prRoamingFsmInfo->fgDrvRoamingAllow = TRUE; + cnmTimerInitTimer(prAdapter, &prRoamingFsmInfo->rWaitCandidateTimer, + (PFN_MGMT_TIMEOUT_FUNC) roamingWaitCandidateTimeout, + (unsigned long) ucBssIndex); +} /* end of roamingFsmInit() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Uninitialize the value in AIS_FSM_INFO_T for AIS FSM operation + * + * @param [IN P_ADAPTER_T] prAdapter + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void roamingFsmUninit(IN struct ADAPTER *prAdapter, IN uint8_t ucBssIndex) +{ + struct ROAMING_INFO *prRoamingFsmInfo; + + DBGLOG(ROAMING, LOUD, + "[%d]->roamingFsmUninit(): Current Time = %d\n", + ucBssIndex, + kalGetTimeTick()); + + prRoamingFsmInfo = + aisGetRoamingInfo(prAdapter, ucBssIndex); + + prRoamingFsmInfo->eCurrentState = ROAMING_STATE_IDLE; + cnmTimerStopTimer(prAdapter, &prRoamingFsmInfo->rWaitCandidateTimer); +} /* end of roamingFsmUninit() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Send commands to firmware + * + * @param [IN P_ADAPTER_T] prAdapter + * [IN P_ROAMING_PARAM_T] prParam + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void roamingFsmSendCmd(IN struct ADAPTER *prAdapter, + IN struct CMD_ROAMING_TRANSIT *prTransit) +{ + struct ROAMING_INFO *prRoamingFsmInfo; + uint32_t rStatus; + uint8_t ucBssIndex = prTransit->ucBssidx; + + DBGLOG(ROAMING, LOUD, + "[%d]->roamingFsmSendCmd(): Current Time = %d\n", + ucBssIndex, + kalGetTimeTick()); + + prRoamingFsmInfo = + aisGetRoamingInfo(prAdapter, ucBssIndex); + + rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ + CMD_ID_ROAMING_TRANSIT, /* ucCID */ + TRUE, /* fgSetQuery */ + FALSE, /* fgNeedResp */ + FALSE, /* fgIsOid */ + NULL, /* pfCmdDoneHandler */ + NULL, /* pfCmdTimeoutHandler */ + sizeof(struct CMD_ROAMING_TRANSIT), + /* u4SetQueryInfoLen */ + (uint8_t *)prTransit, /* pucInfoBuffer */ + NULL, /* pvSetQueryBuffer */ + 0 /* u4SetQueryBufferLen */ + ); + + /* ASSERT(rStatus == WLAN_STATUS_PENDING); */ +} /* end of roamingFsmSendCmd() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Update the recent time when ScanDone occurred + * + * @param [IN P_ADAPTER_T] prAdapter + * + * @return none + */ +/*----------------------------------------------------------------------------*/ +void roamingFsmScanResultsUpdate( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) +{ + DBGLOG(ROAMING, LOUD, + "[%d]->roamingFsmScanResultsUpdate(): Current Time = %d\n", + ucBssIndex, kalGetTimeTick()); + + /* try driver roaming */ + if (scanCheckNeedDriverRoaming(prAdapter, ucBssIndex)) { + struct ROAMING_INFO *roam; + + DBGLOG(ROAMING, INFO, "Request driver roaming"); + roam = aisGetRoamingInfo(prAdapter, ucBssIndex); + roam->eReason = ROAMING_REASON_INACTIVE; + aisFsmRemoveRoamingRequest(prAdapter, ucBssIndex); + aisFsmInsertRequest(prAdapter, + AIS_REQUEST_ROAMING_CONNECT, ucBssIndex); + } +} /* end of roamingFsmScanResultsUpdate() */ + +/*----------------------------------------------------------------------------*/ +/* + * @brief Check if need to do scan for roaming + * + * @param[out] fgIsNeedScan Set to TRUE if need to scan since + * there is roaming candidate in current scan result + * or skip roaming times > limit times + * @return + */ +/*----------------------------------------------------------------------------*/ +static u_int8_t roamingFsmIsNeedScan( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) +{ + struct AIS_SPECIFIC_BSS_INFO *asbi = NULL; + struct LINK *prEssLink = NULL; + u_int8_t fgIsNeedScan = TRUE; + + asbi = aisGetAisSpecBssInfo(prAdapter, ucBssIndex); + if (asbi == NULL) { + DBGLOG(ROAMING, WARN, "ais specific bss info is NULL\n"); + return TRUE; + } + + prEssLink = &asbi->rCurEssLink; + +#if CFG_SUPPORT_ROAMING_SKIP_ONE_AP + /* + * Start skip roaming scan mechanism if only one ESSID AP + */ + if (prEssLink->u4NumElem == 1) { + struct BSS_DESC *prBssDesc; + + /* Get current BssDesc */ + prBssDesc = aisGetTargetBssDesc(prAdapter, ucBssIndex); + if (prBssDesc) { + DBGLOG(ROAMING, INFO, + "roamingFsmSteps: RCPI:%d RoamSkipTimes:%d\n", + prBssDesc->ucRCPI, asbi->ucRoamSkipTimes); + if (prBssDesc->ucRCPI > 90) { + /* Set parameters related to Good Area */ + asbi->ucRoamSkipTimes = 3; + asbi->fgGoodRcpiArea = TRUE; + asbi->fgPoorRcpiArea = FALSE; + } else { + if (asbi->fgGoodRcpiArea) { + asbi->ucRoamSkipTimes--; + } else if (prBssDesc->ucRCPI > 67) { + /*Set parameters related to Poor Area*/ + if (!asbi->fgPoorRcpiArea) { + asbi->ucRoamSkipTimes = 2; + asbi->fgPoorRcpiArea = TRUE; + asbi->fgGoodRcpiArea = FALSE; + } else { + asbi->ucRoamSkipTimes--; + } + } else { + asbi->fgPoorRcpiArea = FALSE; + asbi->fgGoodRcpiArea = FALSE; + asbi->ucRoamSkipTimes--; + } + } + + if (asbi->ucRoamSkipTimes == 0) { + asbi->ucRoamSkipTimes = 3; + asbi->fgPoorRcpiArea = FALSE; + asbi->fgGoodRcpiArea = FALSE; + DBGLOG(ROAMING, INFO, "Need Scan\n"); + } else { + struct CMD_ROAMING_SKIP_ONE_AP cmd = {0}; + + cmd.fgIsRoamingSkipOneAP = 1; + + wlanSendSetQueryCmd(prAdapter, + CMD_ID_SET_ROAMING_SKIP, + TRUE, + FALSE, + FALSE, NULL, NULL, + sizeof(struct CMD_ROAMING_SKIP_ONE_AP), + (uint8_t *)&cmd, NULL, 0); + + fgIsNeedScan = FALSE; + } + } else { + DBGLOG(ROAMING, WARN, "Target BssDesc is NULL\n"); + } + } +#endif + + if (cnmP2pIsActive(prAdapter)) + fgIsNeedScan = FALSE; + + return fgIsNeedScan; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief The Core FSM engine of ROAMING for AIS Infra. + * + * @param [IN P_ADAPTER_T] prAdapter + * [IN ENUM_ROAMING_STATE_T] eNextState Enum value of next AIS STATE + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void roamingFsmSteps(IN struct ADAPTER *prAdapter, + IN enum ENUM_ROAMING_STATE eNextState, + IN uint8_t ucBssIndex) +{ + struct ROAMING_INFO *prRoamingFsmInfo; + enum ENUM_ROAMING_STATE ePreviousState; + u_int8_t fgIsTransition = (u_int8_t) FALSE; + u_int32_t u4ScnResultsTimeout = prAdapter->rWifiVar.u4DiscoverTimeout; + + prRoamingFsmInfo = aisGetRoamingInfo(prAdapter, ucBssIndex); + do { + + /* Do entering Next State */ + DBGLOG(ROAMING, STATE, + "[ROAMING%d] TRANSITION: [%s] -> [%s]\n", + ucBssIndex, + apucDebugRoamingState[prRoamingFsmInfo->eCurrentState], + apucDebugRoamingState[eNextState]); + + /* NOTE(Kevin): This is the only place to + * change the eCurrentState(except initial) + */ + ePreviousState = prRoamingFsmInfo->eCurrentState; + prRoamingFsmInfo->eCurrentState = eNextState; + + fgIsTransition = (u_int8_t) FALSE; + + /* Do tasks of the State that we just entered */ + switch (prRoamingFsmInfo->eCurrentState) { + /* NOTE(Kevin): we don't have to rearrange the sequence of + * following switch case. Instead I would like to use a common + * lookup table of array of function pointer + * to speed up state search. + */ + case ROAMING_STATE_IDLE: + cnmTimerStopTimer( + prAdapter, + &prRoamingFsmInfo->rWaitCandidateTimer); + break; + case ROAMING_STATE_DECISION: +#if CFG_SUPPORT_DRIVER_ROAMING + GET_CURRENT_SYSTIME( + &prRoamingFsmInfo->rRoamingLastDecisionTime); +#endif + prRoamingFsmInfo->eReason = ROAMING_REASON_POOR_RCPI; + break; + + case ROAMING_STATE_DISCOVERY: { + OS_SYSTIME rCurrentTime; + u_int8_t fgIsNeedScan = FALSE; + +#if CFG_SUPPORT_NCHO + if (prAdapter->rNchoInfo.fgNCHOEnabled == TRUE) + u4ScnResultsTimeout = 0; +#endif + + GET_CURRENT_SYSTIME(&rCurrentTime); + if (CHECK_FOR_TIMEOUT(rCurrentTime, + prRoamingFsmInfo->rRoamingDiscoveryUpdateTime, + SEC_TO_SYSTIME(u4ScnResultsTimeout))) { + DBGLOG(ROAMING, LOUD, + "roamingFsmSteps: DiscoveryUpdateTime Timeout\n"); + + fgIsNeedScan = roamingFsmIsNeedScan(prAdapter, + ucBssIndex); + } + aisFsmRunEventRoamingDiscovery( + prAdapter, fgIsNeedScan, ucBssIndex); + } + break; + case ROAMING_STATE_REQ_CAND_LIST: + { +#if CFG_SUPPORT_802_11K + struct BSS_INFO *prBssInfo = + aisGetAisBssInfo(prAdapter, ucBssIndex); + struct BSS_DESC *prBssDesc = + aisGetTargetBssDesc(prAdapter, ucBssIndex); + /* if AP supports Neighbor AP report, then it can used + * to assist roaming candicate selection + */ + if (prBssInfo && prBssInfo->prStaRecOfAP) { + if (prBssDesc && + (prBssDesc->aucRrmCap[0] & + BIT(RRM_CAP_INFO_NEIGHBOR_REPORT_BIT))) { + cnmTimerStartTimer(prAdapter, + &prRoamingFsmInfo->rWaitCandidateTimer, + AIS_JOIN_CH_REQUEST_INTERVAL); + } + } +#endif + fgIsTransition = TRUE; + eNextState = ROAMING_STATE_DECISION; + break; + } + case ROAMING_STATE_ROAM: + break; + + default: + ASSERT(0); /* Make sure we have handle all STATEs */ + } + } while (fgIsTransition); + + return; + +} /* end of roamingFsmSteps() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Transit to Decision state after join completion + * + * @param [IN P_ADAPTER_T] prAdapter + * + * @return none + */ +/*----------------------------------------------------------------------------*/ +void roamingFsmRunEventStart(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) +{ + struct ROAMING_INFO *prRoamingFsmInfo; + enum ENUM_ROAMING_STATE eNextState; + struct BSS_INFO *prAisBssInfo; + struct CMD_ROAMING_TRANSIT rTransit; + + prRoamingFsmInfo = + aisGetRoamingInfo(prAdapter, ucBssIndex); + + /* Check Roaming Conditions */ + if (!(prRoamingFsmInfo->fgIsEnableRoaming)) + return; + + + prAisBssInfo = aisGetAisBssInfo(prAdapter, + ucBssIndex); + if (prAisBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) + return; + + DBGLOG(ROAMING, EVENT, + "[%d] EVENT-ROAMING START: Current Time = %d\n", + ucBssIndex, + kalGetTimeTick()); + + /* IDLE, ROAM -> DECISION */ + /* Errors as DECISION, DISCOVERY -> DECISION */ + if (!(prRoamingFsmInfo->eCurrentState == ROAMING_STATE_IDLE + || prRoamingFsmInfo->eCurrentState == ROAMING_STATE_ROAM)) + return; + + eNextState = ROAMING_STATE_REQ_CAND_LIST; + if (eNextState != prRoamingFsmInfo->eCurrentState) { + rTransit.u2Event = ROAMING_EVENT_START; + rTransit.u2Data = prAisBssInfo->ucBssIndex; + rTransit.ucBssidx = ucBssIndex; + roamingFsmSendCmd(prAdapter, + (struct CMD_ROAMING_TRANSIT *) &rTransit); + + /* Step to next state */ + roamingFsmSteps(prAdapter, eNextState, ucBssIndex); + } +} /* end of roamingFsmRunEventStart() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Transit to Discovery state when deciding to find a candidate + * + * @param [IN P_ADAPTER_T] prAdapter + * + * @return none + */ +/*----------------------------------------------------------------------------*/ +void roamingFsmRunEventDiscovery(IN struct ADAPTER *prAdapter, + IN struct CMD_ROAMING_TRANSIT *prTransit) +{ + struct ROAMING_INFO *prRoamingFsmInfo; + enum ENUM_ROAMING_STATE eNextState; + uint8_t ucBssIndex = prTransit->ucBssidx; + + prRoamingFsmInfo = + aisGetRoamingInfo(prAdapter, ucBssIndex); + + /* Check Roaming Conditions */ + if (!(prRoamingFsmInfo->fgIsEnableRoaming)) + return; + + DBGLOG(ROAMING, EVENT, + "[%d] EVENT-ROAMING DISCOVERY: Current Time = %d\n", + ucBssIndex, + kalGetTimeTick()); + + /* DECISION -> DISCOVERY */ + /* Errors as IDLE, DISCOVERY, ROAM -> DISCOVERY */ + if (prRoamingFsmInfo->eCurrentState != + ROAMING_STATE_DECISION) + return; + + eNextState = ROAMING_STATE_DISCOVERY; + /* DECISION -> DISCOVERY */ + if (eNextState != prRoamingFsmInfo->eCurrentState) { + struct BSS_INFO *prAisBssInfo; + struct BSS_DESC *prBssDesc; + struct BSS_DESC *prBssDescTarget; + uint8_t arBssid[PARAM_MAC_ADDR_LEN]; + struct PARAM_SSID rSsid; + struct AIS_FSM_INFO *prAisFsmInfo; + struct CONNECTION_SETTINGS *prConnSettings; + + kalMemZero(&rSsid, sizeof(struct PARAM_SSID)); + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + prConnSettings = + aisGetConnSettings(prAdapter, ucBssIndex); + + /* sync. rcpi with firmware */ + prAisBssInfo = + &(prAdapter->rWifiVar.arBssInfoPool[NETWORK_TYPE_AIS]); + prBssDesc = prAisFsmInfo->prTargetBssDesc; + if (prBssDesc) { + COPY_SSID(rSsid.aucSsid, rSsid.u4SsidLen, + prBssDesc->aucSSID, prBssDesc->ucSSIDLen); + COPY_MAC_ADDR(arBssid, prBssDesc->aucBSSID); + } else { + COPY_SSID(rSsid.aucSsid, rSsid.u4SsidLen, + prConnSettings->aucSSID, + prConnSettings->ucSSIDLen); + COPY_MAC_ADDR(arBssid, prConnSettings->aucBSSID); + } + + prRoamingFsmInfo->ucRcpi = (uint8_t)(prTransit->u2Data & 0xff); + prRoamingFsmInfo->ucThreshold = prTransit->u2RcpiLowThreshold; + + prBssDesc = scanSearchBssDescByBssidAndSsid(prAdapter, + arBssid, TRUE, &rSsid); + if (prBssDesc) { + prBssDesc->ucRCPI = prRoamingFsmInfo->ucRcpi; + DBGLOG(ROAMING, INFO, "RCPI %u(%d)\n", + prBssDesc->ucRCPI, RCPI_TO_dBm(prBssDesc->ucRCPI)); + } + + prBssDescTarget = aisGetTargetBssDesc(prAdapter, ucBssIndex); + if (prBssDescTarget && prBssDescTarget != prBssDesc) { + prBssDescTarget->ucRCPI = prRoamingFsmInfo->ucRcpi; + DBGLOG(ROAMING, WARN, "update target bss\n"); + } + + /* Save roaming reason code and PER value for AP selection */ + prRoamingFsmInfo->eReason = prTransit->eReason; + if (prTransit->eReason == ROAMING_REASON_TX_ERR) { + prRoamingFsmInfo->ucPER = + (prTransit->u2Data >> 8) & 0xff; + DBGLOG(ROAMING, INFO, "ucPER %u\n", + prRoamingFsmInfo->ucPER); + } else { + prRoamingFsmInfo->ucPER = 0; + } + +#if CFG_SUPPORT_NCHO + if (prRoamingFsmInfo->eReason == ROAMING_REASON_RETRY) + DBGLOG(ROAMING, INFO, + "NCHO enable=%d,trigger=%d,delta=%d,period=%d\n", + prAdapter->rNchoInfo.fgNCHOEnabled, + prAdapter->rNchoInfo.i4RoamTrigger, + prAdapter->rNchoInfo.i4RoamDelta, + prAdapter->rNchoInfo.u4RoamScanPeriod); +#endif + + roamingFsmSteps(prAdapter, eNextState, ucBssIndex); + } +} /* end of roamingFsmRunEventDiscovery() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Transit to Roam state after Scan Done + * + * @param [IN P_ADAPTER_T] prAdapter + * + * @return none + */ +/*----------------------------------------------------------------------------*/ +void roamingFsmRunEventRoam(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) +{ + struct ROAMING_INFO *prRoamingFsmInfo; + enum ENUM_ROAMING_STATE eNextState; + struct CMD_ROAMING_TRANSIT rTransit; + + prRoamingFsmInfo = + aisGetRoamingInfo(prAdapter, ucBssIndex); + + /* Check Roaming Conditions */ + if (!(prRoamingFsmInfo->fgIsEnableRoaming)) + return; + + + DBGLOG(ROAMING, EVENT, + "[%d] EVENT-ROAMING ROAM: Current Time = %d\n", + ucBssIndex, + kalGetTimeTick()); + + /* IDLE, ROAM -> DECISION */ + /* Errors as IDLE, DECISION, ROAM -> ROAM */ + if (prRoamingFsmInfo->eCurrentState != + ROAMING_STATE_DISCOVERY) + return; + + eNextState = ROAMING_STATE_ROAM; + /* DISCOVERY -> ROAM */ + if (eNextState != prRoamingFsmInfo->eCurrentState) { + rTransit.u2Event = ROAMING_EVENT_ROAM; + rTransit.ucBssidx = ucBssIndex; + roamingFsmSendCmd(prAdapter, + (struct CMD_ROAMING_TRANSIT *) &rTransit); + + /* Step to next state */ + roamingFsmSteps(prAdapter, eNextState, ucBssIndex); + } +} /* end of roamingFsmRunEventRoam() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Transit to Decision state as being failed to find out any candidate + * + * @param [IN P_ADAPTER_T] prAdapter + * + * @return none + */ +/*----------------------------------------------------------------------------*/ +void roamingFsmRunEventFail(IN struct ADAPTER *prAdapter, + IN uint32_t u4Param, IN uint8_t ucBssIndex) +{ + struct ROAMING_INFO *prRoamingFsmInfo; + enum ENUM_ROAMING_STATE eNextState; + struct CMD_ROAMING_TRANSIT rTransit; + + prRoamingFsmInfo = + aisGetRoamingInfo(prAdapter, ucBssIndex); + + /* Check Roaming Conditions */ + if (!(prRoamingFsmInfo->fgIsEnableRoaming)) + return; + + + DBGLOG(ROAMING, STATE, + "[%d] EVENT-ROAMING FAIL: reason %x Current Time = %d\n", + ucBssIndex, + u4Param, kalGetTimeTick()); + + /* IDLE, ROAM -> DECISION */ + /* Errors as IDLE, DECISION, DISCOVERY -> DECISION */ + if (prRoamingFsmInfo->eCurrentState != ROAMING_STATE_ROAM) + return; + + eNextState = ROAMING_STATE_DECISION; + /* ROAM -> DECISION */ + if (eNextState != prRoamingFsmInfo->eCurrentState) { + rTransit.u2Event = ROAMING_EVENT_FAIL; + rTransit.u2Data = (uint16_t) (u4Param & 0xffff); + rTransit.ucBssidx = ucBssIndex; + roamingFsmSendCmd(prAdapter, + (struct CMD_ROAMING_TRANSIT *) &rTransit); + + /* Step to next state */ + roamingFsmSteps(prAdapter, eNextState, ucBssIndex); + } +} /* end of roamingFsmRunEventFail() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Transit to Idle state as beging aborted by other moduels, AIS + * + * @param [IN P_ADAPTER_T] prAdapter + * + * @return none + */ +/*----------------------------------------------------------------------------*/ +void roamingFsmRunEventAbort(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) +{ + struct ROAMING_INFO *prRoamingFsmInfo; + enum ENUM_ROAMING_STATE eNextState; + struct CMD_ROAMING_TRANSIT rTransit; + + prRoamingFsmInfo = + aisGetRoamingInfo(prAdapter, ucBssIndex); + + /* Check Roaming Conditions */ + if (!(prRoamingFsmInfo->fgIsEnableRoaming)) + return; + + + DBGLOG(ROAMING, EVENT, + "[%d] EVENT-ROAMING ABORT: Current Time = %d\n", + ucBssIndex, + kalGetTimeTick()); + + eNextState = ROAMING_STATE_IDLE; + /* IDLE, DECISION, DISCOVERY, ROAM -> IDLE */ + if (eNextState != prRoamingFsmInfo->eCurrentState) { + rTransit.u2Event = ROAMING_EVENT_ABORT; + rTransit.ucBssidx = ucBssIndex; + roamingFsmSendCmd(prAdapter, + (struct CMD_ROAMING_TRANSIT *) &rTransit); + + /* Step to next state */ + roamingFsmSteps(prAdapter, eNextState, ucBssIndex); + } +} /* end of roamingFsmRunEventAbort() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Process events from firmware + * + * @param [IN P_ADAPTER_T] prAdapter + * [IN P_ROAMING_PARAM_T] prParam + * + * @return none + */ +/*----------------------------------------------------------------------------*/ +uint32_t roamingFsmProcessEvent(IN struct ADAPTER *prAdapter, + IN struct CMD_ROAMING_TRANSIT *prTransit) +{ + uint8_t ucBssIndex = prTransit->ucBssidx; + + DBGLOG(ROAMING, LOUD, + "[%d] ROAMING Process Events: Current Time = %d\n", + ucBssIndex, + kalGetTimeTick()); + + if (prTransit->u2Event == ROAMING_EVENT_DISCOVERY) { + DBGLOG(ROAMING, INFO, + "ROAMING_EVENT_DISCOVERY Data[%d] RCPI[%d(%d)] PER[%d] Thr[%d(%d)] Reason[%d] Time[%ld]\n", + prTransit->u2Data, + (prTransit->u2Data) & 0xff, /* L[8], RCPI */ + RCPI_TO_dBm((prTransit->u2Data) & 0xff), + (prTransit->u2Data >> 8) & 0xff, /* H[8], PER */ + prTransit->u2RcpiLowThreshold, + RCPI_TO_dBm(prTransit->u2RcpiLowThreshold), + prTransit->eReason, + prTransit->u4RoamingTriggerTime); + roamingFsmRunEventDiscovery(prAdapter, prTransit); + } else if (prTransit->u2Event == ROAMING_EVENT_THRESHOLD_UPDATE) { + DBGLOG(ROAMING, INFO, + "ROAMING_EVENT_THRESHOLD_UPDATE RCPI H[%d(%d)] L[%d(%d)]\n", + prTransit->u2RcpiHighThreshold, + RCPI_TO_dBm(prTransit->u2RcpiHighThreshold), + prTransit->u2RcpiLowThreshold, + RCPI_TO_dBm(prTransit->u2RcpiLowThreshold)); + } + + return WLAN_STATUS_SUCCESS; +} + +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/rrm.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/rrm.c new file mode 100644 index 0000000000000000000000000000000000000000..0ebbcfbcec1add33705cee1d3d95f77a4b8bcfae --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/rrm.c @@ -0,0 +1,1667 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +struct TIMER rBeaconReqTimer; + +struct REF_TSF { + uint32_t au4Tsf[2]; + OS_SYSTIME rTime; +}; +static struct REF_TSF rTsf; + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +static u_int8_t rrmAllMeasurementIssued( + struct RADIO_MEASUREMENT_REQ_PARAMS *prReq); + +static void rrmCalibrateRepetions( + struct RADIO_MEASUREMENT_REQ_PARAMS *prRmReq); + +static void rrmHandleBeaconReqSubelem( + IN struct ADAPTER *prAdapter, IN uint8_t ucBssIndex); + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rrmParamInit(struct ADAPTER *prAdapter, uint8_t ucBssIndex) +{ + struct RADIO_MEASUREMENT_REQ_PARAMS *prRmReqParam = + aisGetRmReqParam(prAdapter, ucBssIndex); + struct RADIO_MEASUREMENT_REPORT_PARAMS *prRmRepParam = + aisGetRmReportParam(prAdapter, ucBssIndex); + + kalMemZero(prRmRepParam, sizeof(*prRmRepParam)); + kalMemZero(prRmReqParam, sizeof(*prRmReqParam)); + prRmReqParam->rBcnRmParam.eState = RM_NO_REQUEST; + prRmReqParam->fgRmIsOngoing = FALSE; + LINK_INITIALIZE(&prRmRepParam->rReportLink); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rrmParamUninit(struct ADAPTER *prAdapter, uint8_t ucBssIndex) +{ + rrmFreeMeasurementResources(prAdapter, ucBssIndex); +} + +void rrmProcessNeighborReportResonse(struct ADAPTER *prAdapter, + struct WLAN_ACTION_FRAME *prAction, + struct SW_RFB *prSwRfb) +{ + struct ACTION_NEIGHBOR_REPORT_FRAME *prNeighborResponse = + (struct ACTION_NEIGHBOR_REPORT_FRAME *)prAction; + uint8_t ucBssIndex = secGetBssIdxByRfb(prAdapter, + prSwRfb); + + ASSERT(prAdapter); + ASSERT(prSwRfb); + ASSERT(prNeighborResponse); + + DBGLOG(RRM, INFO, + "[%d] Neighbor Resp From " MACSTR ", DialogToken %d\n", + ucBssIndex, + MAC2STR(prNeighborResponse->aucSrcAddr), + prNeighborResponse->ucDialogToken); +#if CFG_SUPPORT_802_11K + aisCollectNeighborAP( + prAdapter, &prNeighborResponse->aucInfoElem[0], + prSwRfb->u2PacketLen + - OFFSET_OF(struct ACTION_NEIGHBOR_REPORT_FRAME, + aucInfoElem), + 0, + ucBssIndex); +#endif +} + +void rrmTxNeighborReportRequest(struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + struct SUB_ELEMENT_LIST *prSubIEs) +{ + static uint8_t ucDialogToken = 1; + struct MSDU_INFO *prMsduInfo = NULL; + struct BSS_INFO *prBssInfo = NULL; + uint8_t *pucPayload = NULL; + struct ACTION_NEIGHBOR_REPORT_FRAME *prTxFrame = NULL; + uint16_t u2TxFrameLen = 500; + uint16_t u2FrameLen = 0; + + if (!prStaRec) + return; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex); + ASSERT(prBssInfo); + /* 1 Allocate MSDU Info */ + prMsduInfo = (struct MSDU_INFO *)cnmMgtPktAlloc( + prAdapter, MAC_TX_RESERVED_FIELD + u2TxFrameLen); + if (!prMsduInfo) + return; + prTxFrame = (struct ACTION_NEIGHBOR_REPORT_FRAME + *)((unsigned long)(prMsduInfo->prPacket) + + MAC_TX_RESERVED_FIELD); + + /* 2 Compose The Mac Header. */ + prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; + COPY_MAC_ADDR(prTxFrame->aucDestAddr, prStaRec->aucMacAddr); + COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); + COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); + prTxFrame->ucCategory = CATEGORY_RM_ACTION; + prTxFrame->ucAction = RM_ACTION_NEIGHBOR_REQUEST; + u2FrameLen = + OFFSET_OF(struct ACTION_NEIGHBOR_REPORT_FRAME, aucInfoElem); + /* 3 Compose the frame body's frame. */ + prTxFrame->ucDialogToken = ucDialogToken++; + u2TxFrameLen -= sizeof(*prTxFrame) - 1; + pucPayload = &prTxFrame->aucInfoElem[0]; + while (prSubIEs && u2TxFrameLen >= (prSubIEs->rSubIE.ucLength + 2)) { + kalMemCopy(pucPayload, &prSubIEs->rSubIE, + prSubIEs->rSubIE.ucLength + 2); + pucPayload += prSubIEs->rSubIE.ucLength + 2; + u2FrameLen += prSubIEs->rSubIE.ucLength + 2; + prSubIEs = prSubIEs->prNext; + } + nicTxSetMngPacket(prAdapter, prMsduInfo, prStaRec->ucBssIndex, + prStaRec->ucIndex, WLAN_MAC_MGMT_HEADER_LEN, + u2FrameLen, NULL, MSDU_RATE_MODE_AUTO); + + /* 5 Enqueue the frame to send this action frame. */ + nicTxEnqueueMsdu(prAdapter, prMsduInfo); +} + +void rrmFreeMeasurementResources(struct ADAPTER *prAdapter, + uint8_t ucBssIndex) +{ + struct RADIO_MEASUREMENT_REQ_PARAMS *prRmReq = + aisGetRmReqParam(prAdapter, ucBssIndex); + struct RADIO_MEASUREMENT_REPORT_PARAMS *prRmRep = + aisGetRmReportParam(prAdapter, ucBssIndex); + struct RM_MEASURE_REPORT_ENTRY *prReportEntry = NULL; + struct LINK *prReportLink = &prRmRep->rReportLink; + u_int8_t fgHasBcnReqTimer = timerPendingTimer(&rBeaconReqTimer); + + DBGLOG(RRM, TRACE, "Free measurement, Beacon Req timer is %d\n", + fgHasBcnReqTimer); + if (fgHasBcnReqTimer) + cnmTimerStopTimer(prAdapter, &rBeaconReqTimer); + + kalMemFree(prRmReq->pucReqIeBuf, VIR_MEM_TYPE, prRmReq->u2ReqIeBufLen); + kalMemFree(prRmRep->pucReportFrameBuff, VIR_MEM_TYPE, + RM_REPORT_FRAME_MAX_LENGTH); + while (!LINK_IS_EMPTY(prReportLink)) { + LINK_REMOVE_HEAD(prReportLink, prReportEntry, + struct RM_MEASURE_REPORT_ENTRY *); + kalMemFree(prReportEntry->pucMeasReport, + VIR_MEM_TYPE, prReportEntry->u2MeasReportLen); + kalMemFree(prReportEntry, VIR_MEM_TYPE, sizeof(*prReportEntry)); + } + kalMemZero(prRmReq, sizeof(*prRmReq)); + kalMemZero(prRmRep, sizeof(*prRmRep)); + prRmReq->rBcnRmParam.eState = RM_NO_REQUEST; + prRmReq->fgRmIsOngoing = FALSE; + LINK_INITIALIZE(&prRmRep->rReportLink); +} + +/* purpose: check if Radio Measurement is done */ +static u_int8_t rrmAllMeasurementIssued( + struct RADIO_MEASUREMENT_REQ_PARAMS *prReq) +{ + return prReq->u2RemainReqLen > IE_SIZE(prReq->prCurrMeasElem) ? FALSE + : TRUE; +} + +void rrmComposeIncapableRmRep(struct RADIO_MEASUREMENT_REPORT_PARAMS *prRep, + uint8_t ucToken, uint8_t ucMeasType) +{ + struct IE_MEASUREMENT_REPORT *prRepIE = + (struct IE_MEASUREMENT_REPORT *)(prRep->pucReportFrameBuff + + prRep->u2ReportFrameLen); + + prRepIE->ucId = ELEM_ID_MEASUREMENT_REPORT; + prRepIE->ucToken = ucToken; + prRepIE->ucMeasurementType = ucMeasType; + prRepIE->ucLength = 3; + prRepIE->ucReportMode = RM_REP_MODE_INCAPABLE; + prRep->u2ReportFrameLen += 5; +} + +int rrmBeaconRepUpdateLastFrame(struct ADAPTER *prAdapter, + uint8_t ucBssIndex) +{ + struct RADIO_MEASUREMENT_REQ_PARAMS *rmReqParam = + aisGetRmReqParam(prAdapter, ucBssIndex); + struct RADIO_MEASUREMENT_REPORT_PARAMS *prRmRepParam = + aisGetRmReportParam(prAdapter, ucBssIndex); + struct IE_MEASUREMENT_REQ *request = rmReqParam->prCurrMeasElem; + uint8_t *pos = prRmRepParam->pucReportFrameBuff + + OFFSET_OF(struct ACTION_RM_REPORT_FRAME, aucInfoElem); + size_t len = prRmRepParam->u2ReportFrameLen - + OFFSET_OF(struct ACTION_RM_REPORT_FRAME, aucInfoElem); + struct IE_MEASUREMENT_REPORT *msr_rep; + uint8_t *end = pos + len; + uint8_t *msr_rep_end; + struct RM_BCN_REPORT *rep = NULL; + uint8_t *subelem; + + if (request->ucMeasurementType != ELEM_RM_TYPE_BEACON_REQ) + return -EINVAL; + + /* Find the last beacon report element */ + while (end - pos >= (int) sizeof(*msr_rep)) { + msr_rep = (struct IE_MEASUREMENT_REPORT *) pos; + msr_rep_end = pos + msr_rep->ucLength + 2; + + if (msr_rep->ucId != ELEM_ID_MEASUREMENT_REPORT || + msr_rep_end > end) { +#define TEMP_LOG_TEMPLATE \ + "non-measurement report element in measurement report frame\n" + /* Should not happen. This indicates a bug. */ + DBGLOG(RRM, ERROR, TEMP_LOG_TEMPLATE); +#undef TEMP_LOG_TEMPLATE + return -EINVAL; + } + + if (msr_rep->ucMeasurementType == ELEM_RM_TYPE_BEACON_REPORT) + rep = (struct RM_BCN_REPORT *) + msr_rep->aucReportFields; + + pos += pos[1] + 2; + } + + if (!rep) + return 0; + + subelem = rep->aucOptElem; + while (subelem + 2 < msr_rep_end && + subelem[0] != BEACON_REPORT_SUBELEM_LAST_INDICATION) + subelem += 2 + subelem[1]; + + if (subelem + 2 < msr_rep_end && + subelem[0] == BEACON_REPORT_SUBELEM_LAST_INDICATION && + subelem[1] == 1 && + subelem + BEACON_REPORT_LAST_INDICATION_SUBELEM_LEN <= end) { + subelem[2] = 1; + DBGLOG(RRM, INFO, "update last indication subelem\n"); + } + + return 0; +} + +/* Purpose: Interative processing Measurement Request Element. If it is not the + ** first element, + ** will copy all collected report element to the report frame buffer. and + ** may tx the radio report frame. + ** prAdapter: pointer to the Adapter + ** fgNewStarted: if it is the first element in measurement request frame + */ +void rrmStartNextMeasurement(struct ADAPTER *prAdapter, u_int8_t fgNewStarted, + uint8_t ucBssIndex) +{ + struct RADIO_MEASUREMENT_REQ_PARAMS *prRmReq = + aisGetRmReqParam(prAdapter, ucBssIndex); + struct RADIO_MEASUREMENT_REPORT_PARAMS *prRmRep = + aisGetRmReportParam(prAdapter, ucBssIndex); + struct IE_MEASUREMENT_REQ *prCurrReq = prRmReq->prCurrMeasElem; + uint16_t u2RandomTime = 0; + +schedule_next: + if (!prRmReq->fgRmIsOngoing) { + DBGLOG(RRM, INFO, "Rm has been stopped\n"); + return; + } + /* we don't support parallel measurement now */ + if (prCurrReq->ucRequestMode & RM_REQ_MODE_PARALLEL_BIT) { + DBGLOG(RRM, WARN, + "Parallel request, compose incapable report\n"); + if (prRmRep->u2ReportFrameLen + 5 > RM_REPORT_FRAME_MAX_LENGTH) + rrmTxRadioMeasurementReport(prAdapter, ucBssIndex); + rrmComposeIncapableRmRep(prRmRep, prCurrReq->ucToken, + prCurrReq->ucMeasurementType); + if (rrmAllMeasurementIssued(prRmReq)) { + rrmTxRadioMeasurementReport(prAdapter, ucBssIndex); + + /* repeat measurement if repetitions is required and not + * only parallel measurements. + * otherwise, no need to repeat, it is not make sense to + * do that. + */ + if (prRmReq->u2Repetitions > 0) { + prRmReq->fgInitialLoop = FALSE; + prRmReq->u2Repetitions--; + prCurrReq = prRmReq->prCurrMeasElem = + (struct IE_MEASUREMENT_REQ *) + prRmReq->pucReqIeBuf; + prRmReq->u2RemainReqLen = + prRmReq->u2ReqIeBufLen; + rrmHandleBeaconReqSubelem( + prAdapter, ucBssIndex); + } else { + rrmFreeMeasurementResources(prAdapter, + ucBssIndex); + DBGLOG(RRM, INFO, + "Radio Measurement done\n"); + return; + } + } else { + uint16_t u2IeSize = IE_SIZE(prRmReq->prCurrMeasElem); + + prCurrReq = prRmReq->prCurrMeasElem = + (struct IE_MEASUREMENT_REQ + *)((uint8_t *)prRmReq->prCurrMeasElem + + u2IeSize); + prRmReq->u2RemainReqLen -= u2IeSize; + rrmHandleBeaconReqSubelem( + prAdapter, ucBssIndex); + } + fgNewStarted = FALSE; + goto schedule_next; + } + /* copy collected measurement report for specific measurement type */ + if (!fgNewStarted) { + struct RM_MEASURE_REPORT_ENTRY *prReportEntry = NULL; + struct LINK *prReportLink = &prRmRep->rReportLink; + uint8_t *pucReportFrame = + prRmRep->pucReportFrameBuff + prRmRep->u2ReportFrameLen; + uint16_t u2IeSize = 0; + u_int8_t fgNewLoop = FALSE; + + DBGLOG(RRM, INFO, + "total %u report element for current request\n", + prReportLink->u4NumElem); + /* copy collected report into the Measurement Report Frame + ** Buffer. + */ + while (1) { + LINK_REMOVE_HEAD(prReportLink, prReportEntry, + struct RM_MEASURE_REPORT_ENTRY *); + if (!prReportEntry) + break; + u2IeSize = prReportEntry->u2MeasReportLen; + /* if reach the max length of a MMPDU size, send a Rm + ** report first + */ + if (u2IeSize + prRmRep->u2ReportFrameLen > + RM_REPORT_FRAME_MAX_LENGTH) { + rrmTxRadioMeasurementReport(prAdapter, + ucBssIndex); + pucReportFrame = prRmRep->pucReportFrameBuff + + prRmRep->u2ReportFrameLen; + } + kalMemCopy(pucReportFrame, prReportEntry->pucMeasReport, + u2IeSize); + pucReportFrame += u2IeSize; + prRmRep->u2ReportFrameLen += u2IeSize; + + kalMemFree(prReportEntry->pucMeasReport, + VIR_MEM_TYPE, u2IeSize); + kalMemFree(prReportEntry, + VIR_MEM_TYPE, sizeof(*prReportEntry)); + } + rrmBeaconRepUpdateLastFrame(prAdapter, ucBssIndex); + /* if Measurement is done, free report element memory */ + if (rrmAllMeasurementIssued(prRmReq)) { + rrmTxRadioMeasurementReport(prAdapter, ucBssIndex); + /* repeat measurement if repetitions is required */ + if (prRmReq->u2Repetitions > 0) { + fgNewLoop = TRUE; + prRmReq->fgInitialLoop = FALSE; + prRmReq->u2Repetitions--; + prRmReq->prCurrMeasElem = + (struct IE_MEASUREMENT_REQ *) + prRmReq->pucReqIeBuf; + prRmReq->u2RemainReqLen = + prRmReq->u2ReqIeBufLen; + rrmHandleBeaconReqSubelem( + prAdapter, ucBssIndex); + } else { + /* don't free radio measurement resource due to + ** TSM is running + */ + if (!wmmTsmIsOngoing(prAdapter, ucBssIndex)) { + rrmFreeMeasurementResources(prAdapter, + ucBssIndex); + DBGLOG(RRM, INFO, + "Radio Measurement done\n"); + } + return; + } + } + if (!fgNewLoop) { + u2IeSize = IE_SIZE(prRmReq->prCurrMeasElem); + prCurrReq = prRmReq->prCurrMeasElem = + (struct IE_MEASUREMENT_REQ + *)((uint8_t *)prRmReq->prCurrMeasElem + + u2IeSize); + prRmReq->u2RemainReqLen -= u2IeSize; + rrmHandleBeaconReqSubelem(prAdapter, ucBssIndex); + } + } + + /* do specific measurement */ + switch (prCurrReq->ucMeasurementType) { + case ELEM_RM_TYPE_BEACON_REQ: { + struct RM_BCN_REQ *prBeaconReq = + (struct RM_BCN_REQ *)&prCurrReq->aucRequestFields[0]; + + if (!prRmReq->fgInitialLoop) { + /* If this is the repeating measurement, then wait next + ** scan done + */ + prRmReq->rBcnRmParam.eState = RM_WAITING; + break; + } + if (prBeaconReq->u2RandomInterval == 0) + rrmDoBeaconMeasurement(prAdapter, ucBssIndex); + else { + get_random_bytes(&u2RandomTime, 2); + u2RandomTime = + (u2RandomTime * prBeaconReq->u2RandomInterval) / + 65535; + u2RandomTime = TU_TO_MSEC(u2RandomTime); + if (u2RandomTime > 0) { + cnmTimerStopTimer(prAdapter, &rBeaconReqTimer); + cnmTimerInitTimer(prAdapter, &rBeaconReqTimer, + rrmDoBeaconMeasurement, ucBssIndex); + cnmTimerStartTimer(prAdapter, &rBeaconReqTimer, + u2RandomTime); + } else + rrmDoBeaconMeasurement(prAdapter, ucBssIndex); + } + break; + } +#if 0 + case ELEM_RM_TYPE_TSM_REQ: + { + struct RM_TS_MEASURE_REQ *prTsmReqIE = + (struct RM_TS_MEASURE_REQ *) + &prCurrReq->aucRequestFields[0]; + struct RM_TSM_REQ *prTsmReq = NULL; + uint16_t u2OffSet = 0; + uint8_t *pucIE = prTsmReqIE->aucSubElements; + struct ACTION_RM_REPORT_FRAME *prReportFrame = NULL; + + /* In case of repeating measurement, no need to start + ** triggered measurement again. According to current + ** specification of Radio Measurement, only TSM has the + ** triggered type of measurement. + */ + if ((prCurrReq->ucRequestMode & RM_REQ_MODE_ENABLE_BIT) && + !prRmReq->fgInitialLoop) + goto schedule_next; + + /* if enable bit is 1 and report bit is 0, need to stop all + ** triggered TSM measurement + */ + if ((prCurrReq->ucRequestMode & + (RM_REQ_MODE_ENABLE_BIT|RM_REQ_MODE_REPORT_BIT)) == + RM_REQ_MODE_ENABLE_BIT) { + wmmRemoveAllTsmMeasurement(prAdapter, TRUE); + break; + } + prTsmReq = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, + sizeof(struct RM_TSM_REQ)); + if (!prTsmReq) { + DBGLOG(RLM, ERROR, "No memory\n"); + break; + } + prTsmReq->ucToken = prCurrReq->ucToken; + prTsmReq->u2Duration = prTsmReqIE->u2Duration; + prTsmReq->ucTID = (prTsmReqIE->ucTrafficID & 0xf0) >> 4; + prTsmReq->ucB0Range = prTsmReqIE->ucBin0Range; + prReportFrame = (struct ACTION_RM_REPORT_FRAME *) + prRmRep->pucReportFrameBuff; + COPY_MAC_ADDR(prTsmReq->aucPeerAddr, + prReportFrame->aucDestAddr); + IE_FOR_EACH(pucIE, prCurrReq->ucLength - 3, u2OffSet) { + switch (IE_ID(pucIE)) { + case 1: /* Triggered Reporting */ + kalMemCopy(&prTsmReq->rTriggerCond, + pucIE+2, IE_LEN(pucIE)); + break; + case 221: /* Vendor Specified */ + break; /* No vendor IE now */ + default: + break; + } + } + if (!prTsmReqIE->u2RandomInterval) { + wmmStartTsmMeasurement(prAdapter, + (unsigned long)prTsmReq); + break; + } + get_random_bytes(&u2RandomTime, 2); + u2RandomTime = + (u2RandomTime * prTsmReqIE->u2RandomInterval) / 65535; + u2RandomTime = TU_TO_MSEC(u2RandomTime); + cnmTimerStopTimer(prAdapter, &rTSMReqTimer); + cnmTimerInitTimer(prAdapter, &rTSMReqTimer, + wmmStartTsmMeasurement, (unsigned long)prTsmReq); + cnmTimerStartTimer(prAdapter, &rTSMReqTimer, u2RandomTime); + break; + } +#endif + default: { + if (prRmRep->u2ReportFrameLen + 5 > RM_REPORT_FRAME_MAX_LENGTH) + rrmTxRadioMeasurementReport(prAdapter, + ucBssIndex); + rrmComposeIncapableRmRep(prRmRep, prCurrReq->ucToken, + prCurrReq->ucMeasurementType); + fgNewStarted = FALSE; + DBGLOG(RRM, INFO, + "RM type %d is not supported on this chip\n", + prCurrReq->ucMeasurementType); + goto schedule_next; + } + } +} + +u_int8_t rrmFillScanMsg(struct ADAPTER *prAdapter, + struct MSG_SCN_SCAN_REQ_V2 *prMsg) +{ + struct RADIO_MEASUREMENT_REQ_PARAMS *prRmReq = NULL; + struct IE_MEASUREMENT_REQ *prCurrReq = NULL; + struct RM_BCN_REQ *prBeaconReq = NULL; + uint16_t u2RemainLen = 0; + uint8_t *pucSubIE = NULL; + + static struct PARAM_SSID rBcnReqSsid; + + if (!prMsg) + return FALSE; + + prRmReq = aisGetRmReqParam(prAdapter, + prMsg->ucBssIndex); + + if (prRmReq->rBcnRmParam.eState != RM_ON_GOING) + return FALSE; + + prCurrReq = prRmReq->prCurrMeasElem; + prBeaconReq = (struct RM_BCN_REQ *)&prCurrReq->aucRequestFields[0]; + prMsg->ucSSIDType = SCAN_REQ_SSID_WILDCARD; + switch (prBeaconReq->ucMeasurementMode) { + case RM_BCN_REQ_PASSIVE_MODE: + prMsg->eScanType = SCAN_TYPE_PASSIVE_SCAN; + break; + case RM_BCN_REQ_ACTIVE_MODE: + prMsg->eScanType = SCAN_TYPE_ACTIVE_SCAN; + break; + default: + DBGLOG(RRM, WARN, + "Unexpect measure mode %d, use active mode as default\n", + prBeaconReq->ucMeasurementMode); + prMsg->eScanType = SCAN_TYPE_ACTIVE_SCAN; + break; + } + + WLAN_GET_FIELD_16(&prBeaconReq->u2Duration, &prMsg->u2ChannelDwellTime); + + COPY_MAC_ADDR(prMsg->aucBSSID, prBeaconReq->aucBssid); + + prMsg->u2ProbeDelay = 0; + prMsg->u2TimeoutValue = 0; + prMsg->ucSSIDNum = 0; + prMsg->u2IELen = 0; + /* if mandatory bit is set, we should do */ + if (prCurrReq->ucRequestMode & RM_REQ_MODE_DURATION_MANDATORY_BIT) + prMsg->u2ChannelMinDwellTime = prMsg->u2ChannelDwellTime; + else + prMsg->u2ChannelMinDwellTime = + (prMsg->u2ChannelDwellTime * 2) / 3; + if (prBeaconReq->ucChannel == 0) + prMsg->eScanChannel = SCAN_CHANNEL_FULL; + else if (prBeaconReq->ucChannel == 255) { /* latest Ap Channel Report */ + struct BSS_DESC *prBssDesc = + aisGetTargetBssDesc(prAdapter, + prMsg->ucBssIndex); + uint8_t *pucChnl = NULL; + uint8_t ucChnlNum = 0; + uint8_t ucIndex = 0; + struct RF_CHANNEL_INFO *prChnlInfo = prMsg->arChnlInfoList; + + prMsg->eScanChannel = SCAN_CHANNEL_SPECIFIED; + prMsg->ucChannelListNum = 0; + if (prBssDesc) { + uint8_t *pucIE = NULL; + uint16_t u2IELength = 0; + uint16_t u2Offset = 0; + + pucIE = prBssDesc->aucIEBuf; + u2IELength = prBssDesc->u2IELength; + IE_FOR_EACH(pucIE, u2IELength, u2Offset) + { + if (IE_ID(pucIE) != ELEM_ID_AP_CHANNEL_REPORT) + continue; + pucChnl = ((struct IE_AP_CHNL_REPORT *)pucIE) + ->aucChnlList; + ucChnlNum = pucIE[1] - 1; + DBGLOG(RRM, INFO, + "Channel number in latest AP channel report %d\n", + ucChnlNum); + while (ucIndex < ucChnlNum && + prMsg->ucChannelListNum < + MAXIMUM_OPERATION_CHANNEL_LIST) { + if (pucChnl[ucIndex] <= 14) + prChnlInfo + [prMsg->ucChannelListNum] + .eBand = + BAND_2G4; + else + prChnlInfo + [prMsg->ucChannelListNum] + .eBand = + BAND_5G; + prChnlInfo[prMsg->ucChannelListNum] + .ucChannelNum = + pucChnl[ucIndex]; + prMsg->ucChannelListNum++; + ucIndex++; + } + } + } + } else { + prMsg->eScanChannel = SCAN_CHANNEL_SPECIFIED; + prMsg->ucChannelListNum = 1; + prMsg->arChnlInfoList[0].ucChannelNum = prBeaconReq->ucChannel; + if (prBeaconReq->ucChannel <= 14) + prMsg->arChnlInfoList[0].eBand = BAND_2G4; + else + prMsg->arChnlInfoList[0].eBand = BAND_5G; + } + u2RemainLen = prCurrReq->ucLength - 3 - + OFFSET_OF(struct RM_BCN_REQ, aucSubElements); + pucSubIE = &prBeaconReq->aucSubElements[0]; + while (u2RemainLen > 0) { + if (IE_SIZE(pucSubIE) > u2RemainLen) + break; + switch (pucSubIE[0]) { + case BEACON_REQUEST_SUBELEM_SSID: /* SSID */ + /* length of sub-element ssid is 0 or first byte is 0, + ** means wildcard ssid matching + */ + if (!IE_LEN(pucSubIE) || !pucSubIE[2]) + break; + prMsg->ucSSIDNum = 1; + prMsg->prSsid = &rBcnReqSsid; + COPY_SSID(&rBcnReqSsid.aucSsid[0], + rBcnReqSsid.u4SsidLen, &pucSubIE[2], + pucSubIE[1]); + prMsg->ucSSIDType = SCAN_REQ_SSID_SPECIFIED_ONLY; + break; + case BEACON_REQUEST_SUBELEM_AP_CHANNEL: /* AP channel report */ + { + struct IE_AP_CHNL_REPORT *prApChnl = + (struct IE_AP_CHNL_REPORT *)pucSubIE; + uint8_t ucChannelCnt = prApChnl->ucLength - 1; + uint8_t ucIndex = 0; + + if (prBeaconReq->ucChannel == 0) + break; + prMsg->eScanChannel = SCAN_CHANNEL_SPECIFIED; + DBGLOG(RRM, INFO, + "Channel number in measurement AP channel report %d\n", + ucChannelCnt); + while (ucIndex < ucChannelCnt && + prMsg->ucChannelListNum < + MAXIMUM_OPERATION_CHANNEL_LIST) { + if (prApChnl->aucChnlList[ucIndex] <= 14) + prMsg->arChnlInfoList + [prMsg->ucChannelListNum] + .eBand = BAND_2G4; + else + prMsg->arChnlInfoList + [prMsg->ucChannelListNum] + .eBand = BAND_5G; + prMsg->arChnlInfoList[prMsg->ucChannelListNum] + .ucChannelNum = + prApChnl->aucChnlList[ucIndex]; + prMsg->ucChannelListNum++; + ucIndex++; + } + break; + } + } + u2RemainLen -= IE_SIZE(pucSubIE); + pucSubIE += IE_SIZE(pucSubIE); + } + + GET_CURRENT_SYSTIME(&prRmReq->rScanStartTime); + DBGLOG(RRM, INFO, + "SSIDtype %d, ScanType %d, Dwell %d, MinDwell %d, ChnlType %d, ChnlNum %d\n", + prMsg->ucSSIDType, prMsg->eScanType, prMsg->u2ChannelDwellTime, + prMsg->u2ChannelMinDwellTime, prMsg->eScanChannel, + prMsg->ucChannelListNum); + + return TRUE; +} + +void rrmDoBeaconMeasurement(struct ADAPTER *prAdapter, unsigned long ulParam) +{ + uint8_t ucBssIndex = (uint8_t) ulParam; + struct CONNECTION_SETTINGS *prConnSettings = + aisGetConnSettings(prAdapter, ucBssIndex); + struct RADIO_MEASUREMENT_REQ_PARAMS *prRmReq = + aisGetRmReqParam(prAdapter, ucBssIndex); + struct RM_BCN_REQ *prBcnReq = + (struct RM_BCN_REQ *)&prRmReq->prCurrMeasElem + ->aucRequestFields[0]; + + if (prBcnReq->ucMeasurementMode == RM_BCN_REQ_TABLE_MODE) { + struct LINK *prBSSDescList = + &prAdapter->rWifiVar.rScanInfo.rBSSDescList; + struct BSS_DESC *prBssDesc = NULL; + + prRmReq->rBcnRmParam.eState = RM_ON_GOING; + prBcnReq->ucChannel = 0; + DBGLOG(RRM, INFO, + "Beacon Table Mode, Beacon Table Num %u\n", + prBSSDescList->u4NumElem); + LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, + struct BSS_DESC) + { + rrmCollectBeaconReport(prAdapter, + prBssDesc, ucBssIndex); + } + rrmStartNextMeasurement(prAdapter, FALSE, ucBssIndex); + return; + } + if (prConnSettings->fgIsScanReqIssued) { + prRmReq->rBcnRmParam.eState = RM_WAITING; + } else { + prRmReq->rBcnRmParam.eState = RM_ON_GOING; + GET_CURRENT_SYSTIME(&prRmReq->rStartTime); + aisFsmScanRequest(prAdapter, NULL, NULL, 0, + ucBssIndex); + } +} + +static u_int8_t rrmRmFrameIsValid(struct SW_RFB *prSwRfb) +{ + uint16_t u2ElemLen = 0; + uint16_t u2Offset = + (uint16_t)OFFSET_OF(struct ACTION_RM_REQ_FRAME, aucInfoElem); + uint8_t *pucIE = (uint8_t *)prSwRfb->pvHeader; + struct IE_MEASUREMENT_REQ *prCurrMeasElem = NULL; + uint16_t u2CalcIELen = 0; + uint16_t u2IELen = 0; + + if (prSwRfb->u2PacketLen <= u2Offset) { + DBGLOG(RRM, ERROR, "Rm Packet length %d is too short\n", + prSwRfb->u2PacketLen); + return FALSE; + } + pucIE += u2Offset; + u2ElemLen = prSwRfb->u2PacketLen - u2Offset; + IE_FOR_EACH(pucIE, u2ElemLen, u2Offset) + { + u2IELen = IE_LEN(pucIE); + + /* The minimum value of the Length field is 3 (based on a + ** minimum length for the Measurement Request field + ** of 0 octets + */ + if (u2IELen < 3) { + DBGLOG(RRM, ERROR, "Abnormal RM IE length is %d\n", + u2IELen); + return FALSE; + } + + /* Check whether the length of each measurment request element + ** is reasonable + */ + prCurrMeasElem = (struct IE_MEASUREMENT_REQ *)pucIE; + switch (prCurrMeasElem->ucMeasurementType) { + case ELEM_RM_TYPE_BEACON_REQ: + if (u2IELen < (3 + OFFSET_OF(struct RM_BCN_REQ, + aucSubElements))) { + DBGLOG(RRM, ERROR, + "Abnormal Becaon Req IE length is %d\n", + u2IELen); + return FALSE; + } + break; + case ELEM_RM_TYPE_TSM_REQ: + if (u2IELen < (3 + OFFSET_OF(struct RM_TS_MEASURE_REQ, + aucSubElements))) { + DBGLOG(RRM, ERROR, + "Abnormal TSM Req IE length is %d\n", + u2IELen); + return FALSE; + } + break; + default: + DBGLOG(RRM, ERROR, + "Not support: MeasurementType is %d, IE length is %d\n", + prCurrMeasElem->ucMeasurementType, u2IELen); + return FALSE; + } + + u2CalcIELen += IE_SIZE(pucIE); + } + if (u2CalcIELen != u2ElemLen) { + DBGLOG(RRM, ERROR, + "Calculated Total IE len is not equal to received length\n"); + return FALSE; + } + return TRUE; +} + +void rrmProcessRadioMeasurementRequest(struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb) +{ + struct ACTION_RM_REQ_FRAME *prRmReqFrame = NULL; + struct ACTION_RM_REPORT_FRAME *prReportFrame = NULL; + struct RADIO_MEASUREMENT_REQ_PARAMS *prRmReqParam = NULL; + struct RADIO_MEASUREMENT_REPORT_PARAMS *prRmRepParam = NULL; + enum RM_REQ_PRIORITY eNewPriority; + struct BSS_INFO *prAisBssInfo = NULL; + struct STA_RECORD *prStaRec = NULL; + + ASSERT(prAdapter); + ASSERT(prSwRfb); + + prAisBssInfo = aisGetAisBssInfo(prAdapter, + secGetBssIdxByRfb(prAdapter, prSwRfb)); + if (prAisBssInfo == NULL) { + DBGLOG(RRM, INFO, "Ignored due to AIS isn't created\n"); + return; + } + + prRmReqFrame = (struct ACTION_RM_REQ_FRAME *)prSwRfb->pvHeader; + prRmReqParam = aisGetRmReqParam(prAdapter, + prAisBssInfo->ucBssIndex); + prRmRepParam = aisGetRmReportParam(prAdapter, + prAisBssInfo->ucBssIndex); + + if (!rrmRmFrameIsValid(prSwRfb)) + return; + prStaRec = prAisBssInfo->prStaRecOfAP; + if (!prStaRec) { + DBGLOG(RRM, INFO, "StaRec is NULL, ignore request\n"); + return; + } + DBGLOG(RRM, INFO, "RM Request From "MACSTR", DialogToken %d\n", + MAC2STR(prRmReqFrame->aucSrcAddr), + prRmReqFrame->ucDialogToken); + eNewPriority = rrmGetRmRequestPriority(prRmReqFrame->aucDestAddr); + if (prRmReqParam->ePriority > eNewPriority) { + DBGLOG(RRM, INFO, "ignore lower precedence rm request\n"); + return; + } + prRmReqParam->ePriority = eNewPriority; + /* */ + if (prRmReqParam->fgRmIsOngoing) { + DBGLOG(RRM, INFO, "Old RM is on-going, cancel it first\n"); + rrmTxRadioMeasurementReport(prAdapter, + prAisBssInfo->ucBssIndex); + wmmRemoveAllTsmMeasurement(prAdapter, FALSE, + prAisBssInfo->ucBssIndex); + rrmFreeMeasurementResources(prAdapter, + prAisBssInfo->ucBssIndex); + } + prRmReqParam->fgRmIsOngoing = TRUE; + /* Step1: Save Measurement Request Params */ + prRmReqParam->u2ReqIeBufLen = prRmReqParam->u2RemainReqLen = + prSwRfb->u2PacketLen - + OFFSET_OF(struct ACTION_RM_REQ_FRAME, aucInfoElem); + if (prRmReqParam->u2RemainReqLen < sizeof(struct IE_MEASUREMENT_REQ)) { + DBGLOG(RRM, ERROR, + "empty Radio Measurement Request Frame, Elem Len %d\n", + prRmReqParam->u2RemainReqLen); + return; + } + WLAN_GET_FIELD_BE16(&prRmReqFrame->u2Repetitions, + &prRmReqParam->u2Repetitions); + prRmReqParam->pucReqIeBuf = + kalMemAlloc(prRmReqParam->u2RemainReqLen, VIR_MEM_TYPE); + if (!prRmReqParam->pucReqIeBuf) { + DBGLOG(RRM, ERROR, + "Alloc %d bytes Req IE Buffer failed, No Memory\n", + prRmReqParam->u2RemainReqLen); + return; + } + kalMemCopy(prRmReqParam->pucReqIeBuf, &prRmReqFrame->aucInfoElem[0], + prRmReqParam->u2RemainReqLen); + prRmReqParam->prCurrMeasElem = + (struct IE_MEASUREMENT_REQ *)prRmReqParam->pucReqIeBuf; + prRmReqParam->fgInitialLoop = TRUE; + rrmHandleBeaconReqSubelem(prAdapter, prAisBssInfo->ucBssIndex); + + /* Step2: Prepare Report Frame and fill in Frame Header */ + prRmRepParam->pucReportFrameBuff = + kalMemAlloc(RM_REPORT_FRAME_MAX_LENGTH, VIR_MEM_TYPE); + if (!prRmRepParam->pucReportFrameBuff) { + DBGLOG(RRM, ERROR, + "Alloc Memory for Measurement Report Frame buffer failed\n"); + return; + } + kalMemZero(prRmRepParam->pucReportFrameBuff, + RM_REPORT_FRAME_MAX_LENGTH); + prReportFrame = (struct ACTION_RM_REPORT_FRAME *) + prRmRepParam->pucReportFrameBuff; + prReportFrame->u2FrameCtrl = MAC_FRAME_ACTION; + COPY_MAC_ADDR(prReportFrame->aucDestAddr, prRmReqFrame->aucSrcAddr); + COPY_MAC_ADDR(prReportFrame->aucSrcAddr, + prAisBssInfo->aucOwnMacAddr); + COPY_MAC_ADDR(prReportFrame->aucBSSID, prRmReqFrame->aucBSSID); + prReportFrame->ucCategory = CATEGORY_RM_ACTION; + prReportFrame->ucAction = RM_ACTION_RM_REPORT; + prReportFrame->ucDialogToken = prRmReqFrame->ucDialogToken; + prRmRepParam->u2ReportFrameLen = + OFFSET_OF(struct ACTION_RM_REPORT_FRAME, aucInfoElem); + rrmCalibrateRepetions(prRmReqParam); + /* Step3: Start to process Measurement Request Element */ + rrmStartNextMeasurement(prAdapter, TRUE, prAisBssInfo->ucBssIndex); +} + +void rrmTxRadioMeasurementReport(struct ADAPTER *prAdapter, + uint8_t ucBssIndex) +{ + struct MSDU_INFO *prMsduInfo = NULL; + struct RADIO_MEASUREMENT_REPORT_PARAMS *prRmRepParam = + aisGetRmReportParam(prAdapter, ucBssIndex); + struct STA_RECORD *prStaRec = NULL; + struct BSS_INFO *prAisBssInfo = NULL; + + if (prRmRepParam->u2ReportFrameLen <= + OFFSET_OF(struct ACTION_RM_REPORT_FRAME, aucInfoElem)) { + DBGLOG(RRM, INFO, "report frame length is too short, %d\n", + prRmRepParam->u2ReportFrameLen); + goto out; + } + prAisBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + if (!prAisBssInfo) { + DBGLOG(RRM, INFO, "ais bss info is NULL\n"); + goto out; + } + prStaRec = prAisBssInfo->prStaRecOfAP; + if (!prStaRec) { + DBGLOG(RRM, INFO, "StaRec of Ais is NULL\n"); + goto out; + } + prMsduInfo = (struct MSDU_INFO *)cnmMgtPktAlloc( + prAdapter, prRmRepParam->u2ReportFrameLen); + if (!prMsduInfo) { + DBGLOG(RRM, INFO, + "Alloc MSDU Info failed, frame length %d\n", + prRmRepParam->u2ReportFrameLen); + goto out; + } + DBGLOG(RRM, INFO, "frame length %d\n", + prRmRepParam->u2ReportFrameLen); + kalMemCopy(prMsduInfo->prPacket, prRmRepParam->pucReportFrameBuff, + prRmRepParam->u2ReportFrameLen); + + /* 2 Update information of MSDU_INFO_T */ + TX_SET_MMPDU(prAdapter, prMsduInfo, prStaRec->ucBssIndex, + prStaRec->ucIndex, WLAN_MAC_MGMT_HEADER_LEN, + prRmRepParam->u2ReportFrameLen, NULL, MSDU_RATE_MODE_AUTO); + nicTxEnqueueMsdu(prAdapter, prMsduInfo); + +out: + /* reset u2ReportFrameLen after tx frame */ + prRmRepParam->u2ReportFrameLen = + OFFSET_OF(struct ACTION_RM_REPORT_FRAME, aucInfoElem); +} + +void rrmGenerateRRMEnabledCapIE(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo) +{ + struct IE_RRM_ENABLED_CAP *prRrmEnabledCap = NULL; + + ASSERT(prAdapter); + ASSERT(prMsduInfo); + + prRrmEnabledCap = (struct IE_RRM_ENABLED_CAP *) + (((uint8_t *) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength); + prRrmEnabledCap->ucId = ELEM_ID_RRM_ENABLED_CAP; + prRrmEnabledCap->ucLength = ELEM_MAX_LEN_RRM_CAP; + kalMemZero(&prRrmEnabledCap->aucCap[0], ELEM_MAX_LEN_RRM_CAP); + rrmFillRrmCapa(&prRrmEnabledCap->aucCap[0]); + prMsduInfo->u2FrameLength += IE_SIZE(prRrmEnabledCap); +} + +void rrmFillRrmCapa(uint8_t *pucCapa) +{ + uint8_t ucIndex = 0; + uint8_t aucEnabledBits[] = {RRM_CAP_INFO_LINK_MEASURE_BIT, + RRM_CAP_INFO_NEIGHBOR_REPORT_BIT, + RRM_CAP_INFO_REPEATED_MEASUREMENT, + RRM_CAP_INFO_BEACON_PASSIVE_MEASURE_BIT, + RRM_CAP_INFO_BEACON_ACTIVE_MEASURE_BIT, + RRM_CAP_INFO_BEACON_TABLE_BIT, + RRM_CAP_INFO_RRM_BIT}; + + for (; ucIndex < sizeof(aucEnabledBits); ucIndex++) + SET_EXT_CAP(pucCapa, ELEM_MAX_LEN_RRM_CAP, + aucEnabledBits[ucIndex]); +} + +enum RM_REQ_PRIORITY rrmGetRmRequestPriority(uint8_t *pucDestAddr) +{ + if (IS_UCAST_MAC_ADDR(pucDestAddr)) + return RM_PRI_UNICAST; + else if (EQUAL_MAC_ADDR(pucDestAddr, "\xff\xff\xff\xff\xff\xff")) + return RM_PRI_BROADCAST; + return RM_PRI_MULTICAST; +} + +static void rrmCalibrateRepetions(struct RADIO_MEASUREMENT_REQ_PARAMS *prRmReq) +{ + uint16_t u2IeSize = 0; + uint16_t u2RemainReqLen = prRmReq->u2ReqIeBufLen; + struct IE_MEASUREMENT_REQ *prCurrReq = + (struct IE_MEASUREMENT_REQ *)prRmReq->prCurrMeasElem; + + if (prRmReq->u2Repetitions == 0) + return; + + u2IeSize = IE_SIZE(prCurrReq); + while (u2RemainReqLen >= u2IeSize) { + /* 1. If all measurement request has enable bit, no need to + ** repeat + ** see 11.10.6 Measurement request elements with the enable bit + ** set to 1 shall be processed once + ** regardless of the value in the number of repetitions in the + ** measurement request. + ** 2. Due to we don't support parallel measurement, if all + ** request has parallel bit, no need to repeat + ** measurement, to avoid frequent composing incapable response + ** IE and exhauste CPU resource + ** and then cause watch dog timeout. + ** 3. if all measurements are not supported, no need to repeat. + ** currently we only support Beacon request + ** on this chip. + */ + if (!(prCurrReq->ucRequestMode & + (RM_REQ_MODE_ENABLE_BIT | RM_REQ_MODE_PARALLEL_BIT))) { + if (prCurrReq->ucMeasurementType == + ELEM_RM_TYPE_BEACON_REQ) + return; + } + u2RemainReqLen -= u2IeSize; + prCurrReq = (struct IE_MEASUREMENT_REQ *)((uint8_t *)prCurrReq + + u2IeSize); + u2IeSize = IE_SIZE(prCurrReq); + } + DBGLOG(RRM, INFO, + "All Measurement has set enable bit, or all are parallel or not supported, don't repeat\n"); + prRmReq->u2Repetitions = 0; +} + +void rrmRunEventProcessNextRm(struct ADAPTER *prAdapter, + struct MSG_HDR *prMsgHdr) +{ + struct MSG_SCN_SCAN_DONE *prMsg; + uint8_t ucBssIndex = 0; + + ASSERT(prMsgHdr); + + prMsg = (struct MSG_SCN_SCAN_DONE *)prMsgHdr; + ucBssIndex = prMsg->ucBssIndex; + cnmMemFree(prAdapter, prMsgHdr); + rrmStartNextMeasurement(prAdapter, FALSE, ucBssIndex); +} + +void rrmScheduleNextRm(struct ADAPTER *prAdapter, + uint8_t ucBssIndex) +{ + struct MSG_SCN_SCAN_DONE *prMsg = NULL; + + prMsg = (struct MSG_SCN_SCAN_DONE *) cnmMemAlloc(prAdapter, + RAM_TYPE_MSG, sizeof(struct MSG_SCN_SCAN_DONE)); + if (!prMsg) { + DBGLOG(RRM, ERROR, "[RRM] No memory\n"); + return; + } + prMsg->rMsgHdr.eMsgId = MID_RRM_REQ_SCHEDULE; + prMsg->ucBssIndex = ucBssIndex; + mboxSendMsg(prAdapter, MBOX_ID_0, + (struct MSG_HDR *)prMsg, MSG_SEND_METHOD_BUF); +} + +static void rrmHandleBeaconReqSubelem( + IN struct ADAPTER *prAdapter, IN uint8_t ucBssIndex) +{ + struct RADIO_MEASUREMENT_REQ_PARAMS *rmReqParam = NULL; + struct IE_MEASUREMENT_REQ *request = NULL; + struct RM_BCN_REQ *prBcnReq = NULL; + struct BCN_RM_PARAMS *data = NULL; + uint16_t elemsLen = 0; + uint8_t *subelems = NULL; + uint8_t slen = 0; + uint8_t reportInfo = 0; + + rmReqParam = aisGetRmReqParam(prAdapter, ucBssIndex); + request = rmReqParam->prCurrMeasElem; + prBcnReq = (struct RM_BCN_REQ *)&request->aucRequestFields[0]; + data = &rmReqParam->rBcnRmParam; + + if (request->ucMeasurementType != ELEM_RM_TYPE_BEACON_REQ) + return; + + /* reset data */ + data->token = request->ucToken; + data->lastIndication = 0; + data->ssidLen = 0; + data->reportDetail = BEACON_REPORT_DETAIL_ALL_FIELDS_AND_ELEMENTS; + data->reportIeIdsLen = 0; + data->apChannelsLen = 0; + + elemsLen = request->ucLength - 3 - + OFFSET_OF(struct RM_BCN_REQ, aucSubElements); + subelems = &prBcnReq->aucSubElements[0]; + while (elemsLen >= 2) { + slen = subelems[1]; + if (slen > elemsLen - 2) { + DBGLOG(RRM, WARN, + "Beacon Request: Truncated subelement"); + return; + } + + switch (subelems[0]) { + case BEACON_REQUEST_SUBELEM_SSID: + { + if (!slen) { + DBGLOG(RRM, WARN, "Wildcard SSID"); + break; + } + + if (slen > ELEM_MAX_LEN_SSID) { + DBGLOG(RRM, WARN, + "Invalid SSID length: %u", slen); + break; + } + + COPY_SSID(data->ssid, data->ssidLen, + &subelems[2], slen); + break; + } + case BEACON_REQUEST_SUBELEM_INFO: + { + if (slen != 2) { + DBGLOG(RRM, WARN, + "%u Invalid reporting len: %u", + subelems[0], slen); + break; + } + /* Beacon reporting data field format + * Reporting condition 1, Threshold/Offset Reference 1 + */ + reportInfo = subelems[2]; + if (reportInfo != 0) { + DBGLOG(RRM, WARN, + "reporting info=%u not supported", + reportInfo); + break; + } + break; + } + case BEACON_REQUEST_SUBELEM_DETAIL: + { + if (slen != 1) { + DBGLOG(RRM, WARN, "%u Wrong len %u", + subelems[0], slen); + break; + } + + if (subelems[2] > + BEACON_REPORT_DETAIL_ALL_FIELDS_AND_ELEMENTS) { + DBGLOG(RRM, WARN, + "Invalid detail: %u", subelems[2]); + break; + } + + data->reportDetail = subelems[2]; + + break; + } + case BEACON_REQUEST_SUBELEM_REQUEST: + { + if (data->reportDetail != + BEACON_REPORT_DETAIL_REQUESTED_ONLY) { + DBGLOG(RRM, WARN, + "unexpected report detail is %u", + data->reportDetail); + break; + } + + if (!slen) { + DBGLOG(RRM, WARN, "subelem %u Wrong len %u", + subelems[0], slen); + break; + } + + data->reportIeIds = &subelems[2]; + data->reportIeIdsLen = slen; + break; + } + case BEACON_REQUEST_SUBELEM_AP_CHANNEL: + { + uint8_t *strbuf, *pos, *end; + uint8_t i; + + if (slen < 2) { + DBGLOG(RRM, WARN, "subelem %u Wrong len %u", + subelems[0], slen); + break; + } + + /* AP Channel Report element + * EleID 1, Length 1, Op class 1, channel List N + */ + data->apChannels = &subelems[3]; + data->apChannelsLen = slen - 1; + + strbuf = kalMemAlloc(slen * 4, VIR_MEM_TYPE); + if (strbuf) { + pos = strbuf; + end = pos + slen * 4; + for (i = 0; i < data->apChannelsLen; i++) { + pos += kalSnprintf(pos, end - pos, + " %d", data->apChannels[i]); + } + *pos = '\0'; + DBGLOG(RRM, INFO, "AP chnls %s", strbuf); + kalMemFree(strbuf, VIR_MEM_TYPE, slen * 4); + } + break; + } + case BEACON_REQUEST_SUBELEM_LAST_INDICATION: + { + if (slen != 1) { + DBGLOG(RRM, WARN, "Wrong len %u", slen); + break; + } + + data->lastIndication = subelems[2]; + break; + } + default: + DBGLOG(RRM, WARN, "Unknown subelem id %u", subelems[0]); + break; + } + elemsLen -= 2 + slen; + subelems += 2 + slen; + } +} + +uint8_t rrmCheckReportId(uint8_t id, uint8_t *ie, uint8_t len) +{ + uint8_t i; + + if (ie && len > 0) { + for (i = 0; i < len; i++) { + if (id == ie[i]) + return TRUE; + } + } + return FALSE; +} + +int rrmBeaconRepAddFrameBody(struct BCN_RM_PARAMS *data, + struct BSS_DESC *bss, uint8_t *buf, + uint32_t buf_len, uint8_t **ies_buf, + uint32_t *ie_len, int add_fixed) +{ + uint8_t *ies = *ies_buf; + uint32_t ies_len = *ie_len; + uint32_t old_ies_len = ies_len; + uint8_t *pos = buf; + int rem_len; + enum BEACON_REPORT_DETAIL detail = data->reportDetail; + + rem_len = 255 - sizeof(struct RM_BCN_REPORT) - + sizeof(struct IE_MEASUREMENT_REPORT) - 2 - + REPORTED_FRAME_BODY_SUBELEM_LEN; + + if (detail > BEACON_REPORT_DETAIL_ALL_FIELDS_AND_ELEMENTS) { + DBGLOG(RRM, WARN, "Invalid reporting detail: %d", detail); + return -EINVAL; + } + + if (detail == BEACON_REPORT_DETAIL_NONE) + return 0; + + /* + * Minimal frame body subelement size: EID(1) + length(1) + TSF(8) + + * beacon interval(2) + capabilities(2) = 14 bytes + */ + if (add_fixed && buf_len < 14) + return -EINVAL; + + *pos++ = BEACON_REPORT_SUBELEM_FRAME_BODY; + /* The length will be filled later */ + pos++; + + if (add_fixed) { + WLAN_SET_FIELD_64(pos, bss->u8TimeStamp.QuadPart); + pos += 8; + WLAN_SET_FIELD_16(pos, bss->u2BeaconInterval); + pos += 2; + WLAN_SET_FIELD_16(pos, bss->u2CapInfo); + pos += 2; + } + + rem_len -= pos - buf; + + /* + * According to IEEE Std 802.11-2016, 9.4.2.22.7, if the reported frame + * body subelement causes the element to exceed the maximum element + * size, the subelement is truncated so that the last IE is a complete + * IE. So even when required to report all IEs, add elements one after + * the other and stop once there is no more room in the measurement + * element. + */ + while (ies_len > 2 && 2U + ies[1] <= ies_len && rem_len > 0) { + if (detail == BEACON_REPORT_DETAIL_ALL_FIELDS_AND_ELEMENTS || + rrmCheckReportId(ies[0], data->reportIeIds, + data->reportIeIdsLen)) { + uint8_t elen = ies[1]; + + if (2 + elen > buf + buf_len - pos || + 2 + elen > rem_len) + break; + + *pos++ = ies[0]; + *pos++ = elen; + kalMemCopy(pos, ies + 2, elen); + pos += elen; + rem_len -= 2 + elen; + } + + ies_len -= 2 + ies[1]; + ies += 2 + ies[1]; + } + + *ie_len = ies_len; + *ies_buf = ies; + + /* Now the length is known */ + buf[1] = pos - buf - 2; + return old_ies_len != ies_len ? pos - buf : -EINVAL; +} + +int rrmReportElem(struct RM_MEASURE_REPORT_ENTRY *reportEntry, + uint8_t token, uint8_t mode, uint8_t type, + const uint8_t *data, uint32_t data_len) +{ + uint8_t *report = reportEntry->pucMeasReport; + uint8_t len = reportEntry->u2MeasReportLen; + uint32_t size = len + 5 + data_len; + uint8_t *buf; + + buf = kalMemAlloc(size, VIR_MEM_TYPE); + if (!buf) { + DBGLOG(RRM, ERROR, "alloc report elem fail\n"); + return -ENOMEM; + } + reportEntry->u2MeasReportLen = size; + reportEntry->pucMeasReport = buf; + + if (len) { + kalMemCopy(buf, report, len); + kalMemFree(report, VIR_MEM_TYPE, len); + buf += len; + } + + *buf++ = ELEM_ID_MEASUREMENT_REPORT; + *buf++ = 3 + data_len; + *buf++ = token; + *buf++ = mode; + *buf++ = type; + + if (data_len) { + kalMemCopy(buf, data, data_len); + buf += data_len; + } + + return 0; +} + +int rrmAddBeaconRepElem(IN struct ADAPTER *prAdapter, + struct BCN_RM_PARAMS *data, + struct BSS_DESC *bss, + struct RM_MEASURE_REPORT_ENTRY *reportEntry, + struct RM_BCN_REPORT *rep, + uint8_t **ie, uint32_t *ie_len, uint8_t idx) +{ + int ret; + uint8_t *buf, *pos; + uint8_t ve = prAdapter->rWifiVar.u4SwTestMode == + ENUM_SW_TEST_MODE_SIGMA_VOICE_ENT; + uint32_t subelems_len = + (!ve ? REPORTED_FRAME_BODY_SUBELEM_LEN : 0) + + (data->lastIndication ? + BEACON_REPORT_LAST_INDICATION_SUBELEM_LEN : 0); + uint32_t size = sizeof(*rep) + 14 + *ie_len + subelems_len; + + /* Maximum element length: Beacon Report element + Reported Frame Body + * subelement + all IEs of the reported Beacon frame + Reported Frame + * Body Fragment ID subelement + */ + buf = kalMemAlloc(size, VIR_MEM_TYPE); + if (!buf) { + DBGLOG(RRM, ERROR, "alloc beacon report elem fail\n"); + return -ENOMEM; + } + + kalMemCopy(buf, rep, sizeof(*rep)); + + ret = rrmBeaconRepAddFrameBody(data, + bss, buf + sizeof(*rep), + 14 + *ie_len, ie, ie_len, + idx == 0); + if (ret < 0) + goto out; + + pos = buf + ret + sizeof(*rep); + + + if (!ve) { + pos[0] = BEACON_REPORT_SUBELEM_FRAME_BODY_FRAGMENT_ID; + pos[1] = 2; + + /* + * Only one Beacon Report Measurement is supported at a time, + * so the Beacon Report ID can always be set to 1. + */ + pos[2] = 1; + + /* Fragment ID Number (bits 0..6) and + * More Frame Body Fragments (bit 7) + */ + pos[3] = idx; + if (data->reportDetail != BEACON_REPORT_DETAIL_NONE && *ie_len) + pos[3] |= REPORTED_FRAME_BODY_MORE_FRAGMENTS; + else + pos[3] &= ~REPORTED_FRAME_BODY_MORE_FRAGMENTS; + + pos += REPORTED_FRAME_BODY_SUBELEM_LEN; + } + + if (data->lastIndication) { + pos[0] = BEACON_REPORT_SUBELEM_LAST_INDICATION; + pos[1] = 1; + + /* This field will be updated later if this is the last frame */ + pos[2] = 0; + } + + ret = rrmReportElem(reportEntry, data->token, + MEASUREMENT_REPORT_MODE_ACCEPT, + ELEM_RM_TYPE_BEACON_REPORT, buf, + ret + sizeof(*rep) + subelems_len); +out: + kalMemFree(buf, VIR_MEM_TYPE, size); + return ret; +} + +void rrmCollectBeaconReport(IN struct ADAPTER *prAdapter, + IN struct BSS_DESC *prBssDesc, IN uint8_t ucBssIndex) +{ + struct RADIO_MEASUREMENT_REQ_PARAMS *rmReq = + aisGetRmReqParam(prAdapter, ucBssIndex); + struct RADIO_MEASUREMENT_REPORT_PARAMS *rmRep = + aisGetRmReportParam(prAdapter, ucBssIndex); + struct RM_BCN_REQ *bcnReq = + (struct RM_BCN_REQ *)&rmReq->prCurrMeasElem->aucRequestFields[0]; + struct BCN_RM_PARAMS *data = &rmReq->rBcnRmParam; + uint8_t *bssid = prBssDesc->aucBSSID; + uint8_t *pos = prBssDesc->aucIEBuf; + uint32_t ies_len = prBssDesc->u2IELength; + struct RM_BCN_REPORT rep; + struct RM_MEASURE_REPORT_ENTRY *reportEntry = NULL; + struct RM_MEASURE_REPORT_ENTRY *tmp = NULL; + u_int8_t idx = 0; + u_int8_t validChannel = FALSE; + OS_SYSTIME rCurrent; + uint64_t u8Tsf = 0; + + /* sanity check 1: bssid */ + if (!EQUAL_MAC_ADDR(bcnReq->aucBssid, "\xff\xff\xff\xff\xff\xff") && + !EQUAL_MAC_ADDR(bcnReq->aucBssid, bssid)) { + DBGLOG(RRM, INFO, + "bssid mismatch, req "MACSTR", actual "MACSTR"\n", + MAC2STR(bcnReq->aucBssid), MAC2STR(bssid)); + return; + } + + /* sanity check 2: channel */ + if (prBssDesc->ucChannelNum == bcnReq->ucChannel) + validChannel = TRUE; + if (!validChannel) { + uint8_t i = 0; + + for (i = 0; i < data->apChannelsLen; i++) { + if (prBssDesc->ucChannelNum == data->apChannels[i]) { + validChannel = TRUE; + break; + } + } + } + if (!validChannel && + bcnReq->ucChannel > 0 && bcnReq->ucChannel < 255) { + DBGLOG(RRM, INFO, ""MACSTR" chnl %d invalid, req %d\n", + MAC2STR(bssid), prBssDesc->ucChannelNum, + bcnReq->ucChannel); + return; + } + + /* sanity check 3: ssid */ + if (data->ssidLen && + UNEQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen, + data->ssid, data->ssidLen)) { + uint8_t reqSsid[ELEM_MAX_LEN_SSID + 1] = {0}; + uint8_t bcnSsid[ELEM_MAX_LEN_SSID + 1] = {0}; + + kalMemCopy(reqSsid, data->ssid, + min_t(uint8_t, data->ssidLen, ELEM_MAX_LEN_SSID)); + kalMemCopy(bcnSsid, prBssDesc->aucSSID, + min_t(uint8_t, prBssDesc->ucSSIDLen, ELEM_MAX_LEN_SSID)); + DBGLOG(RRM, TRACE, + ""MACSTR" SSID mismatch, req(%d, %s), bcn(%d, %s)\n", + MAC2STR(bssid), data->ssidLen, HIDE(reqSsid), + prBssDesc->ucSSIDLen, HIDE(bcnSsid)); + return; + } + + /* Compose Beacon Report in a temp buffer, search in saved + * reported link, check if we have saved a report for this AP + */ + LINK_FOR_EACH_ENTRY(tmp, &rmRep->rReportLink, rLinkEntry, + struct RM_MEASURE_REPORT_ENTRY) + { + if (EQUAL_MAC_ADDR(tmp->aucBSSID, bssid)) { + reportEntry = tmp; + break; + } + } + /* not found a entry in collected report link */ + if (!reportEntry) { + reportEntry = kalMemAlloc(sizeof(*reportEntry), + VIR_MEM_TYPE); + if (!reportEntry)/* no memory to allocate in OS */ { + DBGLOG(RRM, ERROR, + "Alloc entry failed, No Memory\n"); + return; + } + COPY_MAC_ADDR(reportEntry->aucBSSID, bssid); + reportEntry->u2MeasReportLen = 0; + reportEntry->pucMeasReport = NULL; + DBGLOG(RRM, TRACE, + "allocate entry for Bss "MACSTR", total entry %u\n", + MAC2STR(bssid), rmRep->rReportLink.u4NumElem); + LINK_INSERT_TAIL(&rmRep->rReportLink, + &reportEntry->rLinkEntry); + } else { + if (reportEntry->u2MeasReportLen) { + kalMemFree(reportEntry->pucMeasReport, + VIR_MEM_TYPE, reportEntry->u2MeasReportLen); + reportEntry->u2MeasReportLen = 0; + reportEntry->pucMeasReport = NULL; + } + } + + /* Fixed length field */ + rep.ucRegulatoryClass = bcnReq->ucRegulatoryClass; + rep.ucChannel = prBssDesc->ucChannelNum; + rep.u2Duration = bcnReq->u2Duration; + /* ucReportInfo: Bit 0 is the type of frame, 0 means beacon/probe + ** response, bit 1~7 means phy type + */ + rep.ucReportInfo = 0; + rep.ucRCPI = prBssDesc->ucRCPI; + rep.ucRSNI = 255; /* 255 = RSNI not available. see 7.3.2.41 */ + COPY_MAC_ADDR(rep.aucBSSID, bssid); + rep.ucAntennaID = 1; + u8Tsf = *(uint64_t *)&rTsf.au4Tsf[0]; + GET_CURRENT_SYSTIME(&rCurrent); + if (rmReq->rStartTime >= rTsf.rTime) + u8Tsf += rmReq->rStartTime - rTsf.rTime; + else + u8Tsf += rTsf.rTime - rmReq->rStartTime; + kalMemCopy(rep.aucStartTime, &u8Tsf, 8); + u8Tsf = *(uint64_t *)&rTsf.au4Tsf[0] + rCurrent - rTsf.rTime; + kalMemCopy(rep.aucParentTSF, &u8Tsf, 4); /* low part of TSF */ + + do { + int ret; + + ret = rrmAddBeaconRepElem(prAdapter, data, prBssDesc, + reportEntry, &rep, &pos, &ies_len, idx++); + if (ret) + break; + } while (data->reportDetail != BEACON_REPORT_DETAIL_NONE && + ies_len >= 2); + + DBGLOG(RRM, TRACE, + "Bss "MACSTR", ReportDeail %d, IncludeIE Num %d, chnl %d\n", + MAC2STR(bssid), data->reportDetail, data->reportIeIdsLen, + prBssDesc->ucChannelNum); +} + +void rrmUpdateBssTimeTsf(struct ADAPTER *prAdapter, struct BSS_DESC *prBssDesc) +{ + ASSERT(prAdapter); + ASSERT(prBssDesc); + + rTsf.rTime = prBssDesc->rUpdateTime; + kalMemCopy(&rTsf.au4Tsf[0], &prBssDesc->u8TimeStamp, 8); +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/rsn.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/rsn.c new file mode 100644 index 0000000000000000000000000000000000000000..dfeca2637b44b7dda9cbcd4325c7e1cb8e49a182 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/rsn.c @@ -0,0 +1,3679 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: mgmt/rsn.c#3 + */ + +/*! \file "rsn.c" + * \brief This file including the 802.11i, wpa and wpa2(rsn) related function. + * + * This file provided the macros and functions library to support + * the wpa/rsn ie parsing, cipher and AKM check to help the AP seleced + * deciding, tkip mic error handler and rsn PMKID support. + */ + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to parse RSN IE. + * + * \param[in] prInfoElem Pointer to the RSN IE + * \param[out] prRsnInfo Pointer to the BSSDescription structure to store the + * RSN information from the given RSN IE + * + * \retval TRUE - Succeeded + * \retval FALSE - Failed + */ +/*----------------------------------------------------------------------------*/ +u_int8_t rsnParseRsnIE(IN struct ADAPTER *prAdapter, + IN struct RSN_INFO_ELEM *prInfoElem, + OUT struct RSN_INFO *prRsnInfo) +{ + uint32_t i; + int32_t u4RemainRsnIeLen; + uint16_t u2Version; + uint16_t u2Cap = 0; + uint32_t u4GroupSuite = RSN_CIPHER_SUITE_CCMP; + uint16_t u2PairSuiteCount = 0; + uint16_t u2AuthSuiteCount = 0; + uint8_t *pucPairSuite = NULL; + uint8_t *pucAuthSuite = NULL; + uint16_t u2PmkidCount = 0; + uint8_t *cp; + + DEBUGFUNC("rsnParseRsnIE"); + + /* Verify the length of the RSN IE. */ + if (prInfoElem->ucLength < 2) { + DBGLOG(RSN, TRACE, "RSN IE length too short (length=%d)\n", + prInfoElem->ucLength); + return FALSE; + } + + /* Check RSN version: currently, we only support version 1. */ + WLAN_GET_FIELD_16(&prInfoElem->u2Version, &u2Version); + if (u2Version != 1) { + DBGLOG(RSN, TRACE, "Unsupported RSN IE version: %d\n", + u2Version); + return FALSE; + } + + cp = (uint8_t *) &prInfoElem->u4GroupKeyCipherSuite; + u4RemainRsnIeLen = (int32_t) prInfoElem->ucLength - 2; + + do { + if (u4RemainRsnIeLen == 0) + break; + + /* Parse the Group Key Cipher Suite field. */ + if (u4RemainRsnIeLen < 4) { + DBGLOG(RSN, TRACE, + "Fail to parse RSN IE in group cipher suite (IE len: %d)\n", + prInfoElem->ucLength); + return FALSE; + } + + WLAN_GET_FIELD_32(cp, &u4GroupSuite); + cp += 4; + u4RemainRsnIeLen -= 4; + + if (u4RemainRsnIeLen == 0) + break; + + /* Parse the Pairwise Key Cipher Suite Count field. */ + if (u4RemainRsnIeLen < 2) { + DBGLOG(RSN, TRACE, + "Fail to parse RSN IE in pairwise cipher suite count (IE len: %d)\n", + prInfoElem->ucLength); + return FALSE; + } + + WLAN_GET_FIELD_16(cp, &u2PairSuiteCount); + cp += 2; + u4RemainRsnIeLen -= 2; + + /* Parse the Pairwise Key Cipher Suite List field. */ + i = (uint32_t) u2PairSuiteCount * 4; + if (u4RemainRsnIeLen < (int32_t) i) { + DBGLOG(RSN, TRACE, + "Fail to parse RSN IE in pairwise cipher suite list (IE len: %d)\n", + prInfoElem->ucLength); + return FALSE; + } + + pucPairSuite = cp; + + cp += i; + u4RemainRsnIeLen -= (int32_t) i; + + if (u4RemainRsnIeLen == 0) + break; + + /* Parse the Authentication and Key Management Cipher + * Suite Count field. + */ + if (u4RemainRsnIeLen < 2) { + DBGLOG(RSN, TRACE, + "Fail to parse RSN IE in auth & key mgt suite count (IE len: %d)\n", + prInfoElem->ucLength); + return FALSE; + } + + WLAN_GET_FIELD_16(cp, &u2AuthSuiteCount); + cp += 2; + u4RemainRsnIeLen -= 2; + + /* Parse the Authentication and Key Management Cipher + * Suite List field. + */ + i = (uint32_t) u2AuthSuiteCount * 4; + if (u4RemainRsnIeLen < (int32_t) i) { + DBGLOG(RSN, TRACE, + "Fail to parse RSN IE in auth & key mgt suite list (IE len: %d)\n", + prInfoElem->ucLength); + return FALSE; + } + + pucAuthSuite = cp; + + cp += i; + u4RemainRsnIeLen -= (int32_t) i; + + if (u4RemainRsnIeLen == 0) + break; + + /* Parse the RSN u2Capabilities field. */ + if (u4RemainRsnIeLen < 2) { + DBGLOG(RSN, TRACE, + "Fail to parse RSN IE in RSN capabilities (IE len: %d)\n", + prInfoElem->ucLength); + return FALSE; + } + + WLAN_GET_FIELD_16(cp, &u2Cap); + cp += 2; + u4RemainRsnIeLen -= 2; + + if (u4RemainRsnIeLen == 0) + break; + + if (u4RemainRsnIeLen < 2) { + DBGLOG(RSN, TRACE, + "Fail to parse PMKID count in RSN iE\n"); + return FALSE; + } + + WLAN_GET_FIELD_16(cp, &u2PmkidCount); + cp += 2; + u4RemainRsnIeLen -= 2; + + if (u2PmkidCount > 4) { + DBGLOG(RSN, TRACE, + "Bad RSN IE due to PMKID count(%d)\n", + u2PmkidCount); + return FALSE; + } + + if (u2PmkidCount > 0 && u4RemainRsnIeLen < 16 * u2PmkidCount) { + DBGLOG(RSN, TRACE, + "Fail to parse PMKID in RSN iE, count: %d\n", + u2PmkidCount); + return FALSE; + } + } while (FALSE); + + /* Save the RSN information for the BSS. */ + prRsnInfo->ucElemId = ELEM_ID_RSN; + + prRsnInfo->u2Version = u2Version; + + prRsnInfo->u4GroupKeyCipherSuite = u4GroupSuite; + + DBGLOG(RSN, LOUD, + "RSN: version %d, group key cipher suite 0x%x\n", + u2Version, SWAP32(u4GroupSuite)); + + if (pucPairSuite) { + /* The information about the pairwise key cipher suites + * is present. + */ + if (u2PairSuiteCount > MAX_NUM_SUPPORTED_CIPHER_SUITES) + u2PairSuiteCount = MAX_NUM_SUPPORTED_CIPHER_SUITES; + + prRsnInfo->u4PairwiseKeyCipherSuiteCount = + (uint32_t) u2PairSuiteCount; + + for (i = 0; i < (uint32_t) u2PairSuiteCount; i++) { + WLAN_GET_FIELD_32(pucPairSuite, + &prRsnInfo->au4PairwiseKeyCipherSuite + [i]); + pucPairSuite += 4; + + DBGLOG(RSN, LOUD, + "RSN: pairwise key cipher suite [%d]: 0x%x\n", i, + SWAP32(prRsnInfo->au4PairwiseKeyCipherSuite[i])); + } + } else { + /* The information about the pairwise key cipher suites + * is not present. Use the default chipher suite for RSN: CCMP. + */ + prRsnInfo->u4PairwiseKeyCipherSuiteCount = 1; + prRsnInfo->au4PairwiseKeyCipherSuite[0] = RSN_CIPHER_SUITE_CCMP; + + DBGLOG(RSN, LOUD, + "RSN: pairwise key cipher suite: 0x%x (default)\n", + SWAP32(prRsnInfo->au4PairwiseKeyCipherSuite[0])); + } + + if (pucAuthSuite) { + /* The information about the authentication and + * key management suites is present. + */ + if (u2AuthSuiteCount > MAX_NUM_SUPPORTED_AKM_SUITES) + u2AuthSuiteCount = MAX_NUM_SUPPORTED_AKM_SUITES; + + prRsnInfo->u4AuthKeyMgtSuiteCount = (uint32_t) + u2AuthSuiteCount; + + for (i = 0; i < (uint32_t) u2AuthSuiteCount; i++) { + WLAN_GET_FIELD_32(pucAuthSuite, + &prRsnInfo->au4AuthKeyMgtSuite[i]); + pucAuthSuite += 4; + + DBGLOG(RSN, LOUD, "RSN: AKM suite [%d]: 0x%x\n", i, + SWAP32(prRsnInfo->au4AuthKeyMgtSuite[i])); + } + } else { + /* The information about the authentication and + * key management suites is not present. + * Use the default AKM suite for RSN. + */ + prRsnInfo->u4AuthKeyMgtSuiteCount = 1; + prRsnInfo->au4AuthKeyMgtSuite[0] = RSN_AKM_SUITE_802_1X; + + DBGLOG(RSN, LOUD, "RSN: AKM suite: 0x%x (default)\n", + SWAP32(prRsnInfo->au4AuthKeyMgtSuite[0])); + } + + prRsnInfo->u2RsnCap = u2Cap; + prRsnInfo->fgRsnCapPresent = TRUE; + DBGLOG(RSN, LOUD, "RSN cap: 0x%04x\n", prRsnInfo->u2RsnCap); + + return TRUE; +} /* rsnParseRsnIE */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to parse WPA IE. + * + * \param[in] prInfoElem Pointer to the WPA IE. + * \param[out] prWpaInfo Pointer to the BSSDescription structure to store the + * WPA information from the given WPA IE. + * + * \retval TRUE Succeeded. + * \retval FALSE Failed. + */ +/*----------------------------------------------------------------------------*/ +u_int8_t rsnParseWpaIE(IN struct ADAPTER *prAdapter, + IN struct WPA_INFO_ELEM *prInfoElem, + OUT struct RSN_INFO *prWpaInfo) +{ + uint32_t i; + int32_t u4RemainWpaIeLen; + uint16_t u2Version; + uint16_t u2Cap = 0; + uint32_t u4GroupSuite = WPA_CIPHER_SUITE_TKIP; + uint16_t u2PairSuiteCount = 0; + uint16_t u2AuthSuiteCount = 0; + uint8_t *pucPairSuite = NULL; + uint8_t *pucAuthSuite = NULL; + uint8_t *cp; + u_int8_t fgCapPresent = FALSE; + + DEBUGFUNC("rsnParseWpaIE"); + + /* Verify the length of the WPA IE. */ + if (prInfoElem->ucLength < 6) { + DBGLOG(RSN, TRACE, "WPA IE length too short (length=%d)\n", + prInfoElem->ucLength); + return FALSE; + } + + /* Check WPA version: currently, we only support version 1. */ + WLAN_GET_FIELD_16(&prInfoElem->u2Version, &u2Version); + if (u2Version != 1) { + DBGLOG(RSN, TRACE, "Unsupported WPA IE version: %d\n", + u2Version); + return FALSE; + } + + cp = (uint8_t *) &prInfoElem->u4GroupKeyCipherSuite; + u4RemainWpaIeLen = (int32_t) prInfoElem->ucLength - 6; + + do { + if (u4RemainWpaIeLen == 0) + break; + + /* WPA_OUI : 4 + * Version : 2 + * GroupSuite : 4 + * PairwiseCount: 2 + * PairwiseSuite: 4 * pairSuiteCount + * AuthCount : 2 + * AuthSuite : 4 * authSuiteCount + * Cap : 2 + */ + + /* Parse the Group Key Cipher Suite field. */ + if (u4RemainWpaIeLen < 4) { + DBGLOG(RSN, TRACE, + "Fail to parse WPA IE in group cipher suite (IE len: %d)\n", + prInfoElem->ucLength); + return FALSE; + } + + WLAN_GET_FIELD_32(cp, &u4GroupSuite); + cp += 4; + u4RemainWpaIeLen -= 4; + + if (u4RemainWpaIeLen == 0) + break; + + /* Parse the Pairwise Key Cipher Suite Count field. */ + if (u4RemainWpaIeLen < 2) { + DBGLOG(RSN, TRACE, + "Fail to parse WPA IE in pairwise cipher suite count (IE len: %d)\n", + prInfoElem->ucLength); + return FALSE; + } + + WLAN_GET_FIELD_16(cp, &u2PairSuiteCount); + cp += 2; + u4RemainWpaIeLen -= 2; + + /* Parse the Pairwise Key Cipher Suite List field. */ + i = (uint32_t) u2PairSuiteCount * 4; + if (u4RemainWpaIeLen < (int32_t) i) { + DBGLOG(RSN, TRACE, + "Fail to parse WPA IE in pairwise cipher suite list (IE len: %d)\n", + prInfoElem->ucLength); + return FALSE; + } + + pucPairSuite = cp; + + cp += i; + u4RemainWpaIeLen -= (int32_t) i; + + if (u4RemainWpaIeLen == 0) + break; + + /* Parse the Authentication and Key Management Cipher Suite + * Count field. + */ + if (u4RemainWpaIeLen < 2) { + DBGLOG(RSN, TRACE, + "Fail to parse WPA IE in auth & key mgt suite count (IE len: %d)\n", + prInfoElem->ucLength); + return FALSE; + } + + WLAN_GET_FIELD_16(cp, &u2AuthSuiteCount); + cp += 2; + u4RemainWpaIeLen -= 2; + + /* Parse the Authentication and Key Management Cipher Suite + * List field. + */ + i = (uint32_t) u2AuthSuiteCount * 4; + if (u4RemainWpaIeLen < (int32_t) i) { + DBGLOG(RSN, TRACE, + "Fail to parse WPA IE in auth & key mgt suite list (IE len: %d)\n", + prInfoElem->ucLength); + return FALSE; + } + + pucAuthSuite = cp; + + cp += i; + u4RemainWpaIeLen -= (int32_t) i; + + if (u4RemainWpaIeLen == 0) + break; + + /* Parse the WPA u2Capabilities field. */ + if (u4RemainWpaIeLen < 2) { + DBGLOG(RSN, TRACE, + "Fail to parse WPA IE in WPA capabilities (IE len: %d)\n", + prInfoElem->ucLength); + return FALSE; + } + + fgCapPresent = TRUE; + WLAN_GET_FIELD_16(cp, &u2Cap); + u4RemainWpaIeLen -= 2; + } while (FALSE); + + /* Save the WPA information for the BSS. */ + + prWpaInfo->ucElemId = ELEM_ID_WPA; + + prWpaInfo->u2Version = u2Version; + + prWpaInfo->u4GroupKeyCipherSuite = u4GroupSuite; + + DBGLOG(RSN, LOUD, "WPA: version %d, group key cipher suite 0x%x\n", + u2Version, SWAP32(u4GroupSuite)); + + if (pucPairSuite) { + /* The information about the pairwise key cipher suites + * is present. + */ + if (u2PairSuiteCount > MAX_NUM_SUPPORTED_CIPHER_SUITES) + u2PairSuiteCount = MAX_NUM_SUPPORTED_CIPHER_SUITES; + + prWpaInfo->u4PairwiseKeyCipherSuiteCount = + (uint32_t) u2PairSuiteCount; + + for (i = 0; i < (uint32_t) u2PairSuiteCount; i++) { + WLAN_GET_FIELD_32(pucPairSuite, + &prWpaInfo->au4PairwiseKeyCipherSuite + [i]); + pucPairSuite += 4; + + DBGLOG(RSN, LOUD, + "WPA: pairwise key cipher suite [%d]: 0x%x\n", i, + SWAP32(prWpaInfo->au4PairwiseKeyCipherSuite[i])); + } + } else { + /* The information about the pairwise key cipher suites + * is not present. + * Use the default chipher suite for WPA: TKIP. + */ + prWpaInfo->u4PairwiseKeyCipherSuiteCount = 1; + prWpaInfo->au4PairwiseKeyCipherSuite[0] = WPA_CIPHER_SUITE_TKIP; + + DBGLOG(RSN, LOUD, + "WPA: pairwise key cipher suite: 0x%x (default)\n", + SWAP32(prWpaInfo->au4PairwiseKeyCipherSuite[0])); + } + + if (pucAuthSuite) { + /* The information about the authentication and + * key management suites is present. + */ + if (u2AuthSuiteCount > MAX_NUM_SUPPORTED_AKM_SUITES) + u2AuthSuiteCount = MAX_NUM_SUPPORTED_AKM_SUITES; + + prWpaInfo->u4AuthKeyMgtSuiteCount = (uint32_t) + u2AuthSuiteCount; + + for (i = 0; i < (uint32_t) u2AuthSuiteCount; i++) { + WLAN_GET_FIELD_32(pucAuthSuite, + &prWpaInfo->au4AuthKeyMgtSuite[i]); + pucAuthSuite += 4; + + DBGLOG(RSN, LOUD, + "WPA: AKM suite [%d]: 0x%x\n", i, + SWAP32(prWpaInfo->au4AuthKeyMgtSuite[i])); + } + } else { + /* The information about the authentication + * and key management suites is not present. + * Use the default AKM suite for WPA. + */ + prWpaInfo->u4AuthKeyMgtSuiteCount = 1; + prWpaInfo->au4AuthKeyMgtSuite[0] = WPA_AKM_SUITE_802_1X; + + DBGLOG(RSN, LOUD, + "WPA: AKM suite: 0x%x (default)\n", + SWAP32(prWpaInfo->au4AuthKeyMgtSuite[0])); + } + + if (fgCapPresent) { + prWpaInfo->fgRsnCapPresent = TRUE; + prWpaInfo->u2RsnCap = u2Cap; + DBGLOG(RSN, LOUD, "WPA: RSN cap: 0x%04x\n", + prWpaInfo->u2RsnCap); + } else { + prWpaInfo->fgRsnCapPresent = FALSE; + prWpaInfo->u2RsnCap = 0; + } + + return TRUE; +} /* rsnParseWpaIE */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to search the desired pairwise + * cipher suite from the MIB Pairwise Cipher Suite + * configuration table. + * + * \param[in] u4Cipher The desired pairwise cipher suite to be searched + * \param[out] pu4Index Pointer to the index of the desired pairwise cipher in + * the table + * + * \retval TRUE - The desired pairwise cipher suite is found in the table. + * \retval FALSE - The desired pairwise cipher suite is not found in the + * table. + */ +/*----------------------------------------------------------------------------*/ +u_int8_t rsnSearchSupportedCipher(IN struct ADAPTER *prAdapter, + IN uint32_t u4Cipher, OUT uint32_t *pu4Index, + IN uint8_t ucBssIndex) +{ + uint8_t i; + struct DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY *prEntry; + struct IEEE_802_11_MIB *prMib; + + DEBUGFUNC("rsnSearchSupportedCipher"); + + prMib = aisGetMib(prAdapter, ucBssIndex); + + for (i = 0; i < MAX_NUM_SUPPORTED_CIPHER_SUITES; i++) { + prEntry = + &prMib->dot11RSNAConfigPairwiseCiphersTable[i]; + if (prEntry->dot11RSNAConfigPairwiseCipher == u4Cipher && + prEntry->dot11RSNAConfigPairwiseCipherEnabled) { + *pu4Index = i; + return TRUE; + } + } + return FALSE; +} /* rsnSearchSupportedCipher */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Whether BSS RSN is matched from upper layer set. + * + * \param[in] prAdapter Pointer to the Adapter structure, BSS RSN Information + * + * \retval BOOLEAN + */ +/*----------------------------------------------------------------------------*/ +u_int8_t rsnIsSuitableBSS(IN struct ADAPTER *prAdapter, + IN struct BSS_DESC *prBss, + IN struct RSN_INFO *prBssRsnInfo, + IN uint8_t ucBssIndex) +{ + uint32_t i, c, s, k; + struct CONNECTION_SETTINGS *prConnSettings; + + DEBUGFUNC("rsnIsSuitableBSS"); + + prConnSettings = + aisGetConnSettings(prAdapter, ucBssIndex); + + s = prConnSettings->rRsnInfo.u4GroupKeyCipherSuite; + k = prBssRsnInfo->u4GroupKeyCipherSuite; + + if ((s & 0x000000FF) != GET_SELECTOR_TYPE(k)) { + DBGLOG(RSN, WARN, "Break by GroupKey s=0x%x k=0x%x\n", + s, SWAP32(k)); + return FALSE; + } + + c = prBssRsnInfo->u4PairwiseKeyCipherSuiteCount; + for (i = 0; i < c; i++) { + s = prConnSettings-> + rRsnInfo.au4PairwiseKeyCipherSuite[0]; + k = prBssRsnInfo->au4PairwiseKeyCipherSuite[i]; + if ((s & 0x000000FF) == GET_SELECTOR_TYPE(k)) { + break; + } else if (i == c - 1) { + DBGLOG(RSN, WARN, "Break by PairwisKey s=0x%x k=0x%x\n", + s, SWAP32(k)); + return FALSE; + } + } + + if (aisGetAuthMode(prAdapter, ucBssIndex) == AUTH_MODE_WPA3_SAE) { + DBGLOG(RSN, WARN, "Don't check AuthKeyMgtSuite with SAE\n"); + return TRUE; + } + + /* check akm */ + s = prConnSettings->rRsnInfo.au4AuthKeyMgtSuite[0]; + if (prBss->ucIsAdaptive11r && + (s == WLAN_AKM_SUITE_FT_8021X || s == WLAN_AKM_SUITE_FT_PSK)) + return TRUE; + + c = prBssRsnInfo->u4AuthKeyMgtSuiteCount; + for (i = 0; i < c; i++) { + k = prBssRsnInfo->au4AuthKeyMgtSuite[i]; + if ((s & 0x000000FF) == GET_SELECTOR_TYPE(k)) { + break; + } else if (i == c - 1) { + DBGLOG(RSN, WARN, "Break by AuthKey s=0x%x k=0x%x\n", + s, SWAP32(k)); + return FALSE; + } + } + + return TRUE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * + * \brief This routine is called to search the desired + * authentication and key management (AKM) suite from the + * MIB Authentication and Key Management Suites table. + * + * \param[in] u4AkmSuite The desired AKM suite to be searched + * \param[out] pu4Index Pointer to the index of the desired AKM suite in the + * table + * + * \retval TRUE The desired AKM suite is found in the table. + * \retval FALSE The desired AKM suite is not found in the table. + * + * \note + */ +/*----------------------------------------------------------------------------*/ +u_int8_t rsnSearchAKMSuite(IN struct ADAPTER *prAdapter, + IN uint32_t u4AkmSuite, OUT uint32_t *pu4Index, + IN uint8_t ucBssIndex) +{ + uint8_t i; + struct DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY + *prEntry; + struct IEEE_802_11_MIB *prMib; + + DEBUGFUNC("rsnSearchAKMSuite"); + + prMib = aisGetMib(prAdapter, ucBssIndex); + + for (i = 0; i < MAX_NUM_SUPPORTED_AKM_SUITES; i++) { + prEntry = &prMib-> + dot11RSNAConfigAuthenticationSuitesTable[i]; + if (prEntry->dot11RSNAConfigAuthenticationSuite == + u4AkmSuite && + prEntry->dot11RSNAConfigAuthenticationSuiteEnabled) { + *pu4Index = i; + return TRUE; + } + } + return FALSE; +} /* rsnSearchAKMSuite */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief refer to wpa_supplicant wpa_key_mgmt_wpa + */ + +uint8_t rsnKeyMgmtWpa(IN struct ADAPTER *prAdapter, + IN enum ENUM_PARAM_AUTH_MODE eAuthMode, + IN uint8_t bssidx) +{ + uint32_t i; + + return eAuthMode == AUTH_MODE_WPA2 || + eAuthMode == AUTH_MODE_WPA2_PSK || + eAuthMode == AUTH_MODE_WPA2_FT_PSK || + eAuthMode == AUTH_MODE_WPA2_FT || + eAuthMode == AUTH_MODE_WPA3_SAE || + eAuthMode == AUTH_MODE_WPA3_OWE || + rsnSearchAKMSuite(prAdapter, RSN_AKM_SUITE_OWE, &i, bssidx) || + rsnSearchAKMSuite(prAdapter, RSN_AKM_SUITE_SAE, &i, bssidx); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to perform RSNA or TSN policy + * selection for a given BSS. + * + * \param[in] prBss Pointer to the BSS description + * + * \retval TRUE - The RSNA/TSN policy selection for the given BSS is + * successful. The selected pairwise and group cipher suites + * are returned in the BSS description. + * \retval FALSE - The RSNA/TSN policy selection for the given BSS is failed. + * The driver shall not attempt to join the given BSS. + * + * \note The Encrypt status matched score will save to bss for final ap select. + */ +/*----------------------------------------------------------------------------*/ +u_int8_t rsnPerformPolicySelection( + IN struct ADAPTER *prAdapter, IN struct BSS_DESC *prBss, + IN uint8_t ucBssIndex) +{ +#if CFG_SUPPORT_802_11W + int32_t i; + uint32_t j; +#else + uint32_t i, j; +#endif + u_int8_t fgSuiteSupported; + uint32_t u4PairwiseCipher = 0; + uint32_t u4GroupCipher = 0; + uint32_t u4AkmSuite = 0; + struct RSN_INFO *prBssRsnInfo; + u_int8_t fgIsWpsActive = (u_int8_t) FALSE; + enum ENUM_PARAM_AUTH_MODE eAuthMode; + enum ENUM_PARAM_OP_MODE eOPMode; + enum ENUM_WEP_STATUS eEncStatus; + + DEBUGFUNC("rsnPerformPolicySelection"); + + prBss->u4RsnSelectedPairwiseCipher = 0; + prBss->u4RsnSelectedGroupCipher = 0; + prBss->u4RsnSelectedAKMSuite = 0; + prBss->ucEncLevel = 0; + + aisGetAisSpecBssInfo(prAdapter, + ucBssIndex)->fgMgmtProtection = FALSE; + eAuthMode = + aisGetAuthMode(prAdapter, ucBssIndex); + eOPMode = + aisGetOPMode(prAdapter, ucBssIndex); + eEncStatus = + aisGetEncStatus(prAdapter, ucBssIndex); + +#if CFG_SUPPORT_WPS + fgIsWpsActive = aisGetConnSettings(prAdapter, + ucBssIndex)->fgWpsActive; + + /* CR1640, disable the AP select privacy check */ + if (fgIsWpsActive && + (eAuthMode < + AUTH_MODE_WPA) && + (eOPMode == NET_TYPE_INFRA)) { + DBGLOG(RSN, INFO, "-- Skip the Protected BSS check\n"); + return TRUE; + } +#endif + + /* Protection is not required in this BSS. */ + if ((prBss->u2CapInfo & CAP_INFO_PRIVACY) == 0) { + + if (secEnabledInAis(prAdapter, + ucBssIndex) == FALSE) { + DBGLOG(RSN, INFO, "-- No Protected BSS\n"); + return TRUE; + } + DBGLOG(RSN, INFO, "-- Protected BSS but No need\n"); + return FALSE; + } + + /* Protection is required in this BSS. */ + if ((prBss->u2CapInfo & CAP_INFO_PRIVACY) != 0) { + if (secEnabledInAis(prAdapter, + ucBssIndex) == FALSE) { + DBGLOG(RSN, INFO, "-- Protected BSS\n"); + return FALSE; + } + } + + if (eAuthMode == AUTH_MODE_WPA || + eAuthMode == AUTH_MODE_WPA_PSK || + eAuthMode == AUTH_MODE_WPA_NONE) { + + if (prBss->fgIEWPA) { + prBssRsnInfo = &prBss->rWPAInfo; + } else { + DBGLOG(RSN, INFO, + "WPA Information Element does not exist.\n"); + return FALSE; + } + } else if (rsnKeyMgmtWpa(prAdapter, eAuthMode, ucBssIndex)) { + + if (prBss->fgIERSN) { + prBssRsnInfo = &prBss->rRSNInfo; + } else { + DBGLOG(RSN, INFO, + "RSN Information Element does not exist.\n"); + return FALSE; + } +#if CFG_SUPPORT_PASSPOINT + } else if (eAuthMode == + AUTH_MODE_WPA_OSEN) { + /* OSEN is mutual exclusion with RSN, + * so we can reuse RSN's flag and variables + */ + if (prBss->fgIEOsen) { + prBssRsnInfo = &prBss->rRSNInfo; + } else { + DBGLOG(RSN, WARN, + "OSEN Information Element does not exist.\n"); + return FALSE; + } +#endif + } else if (eEncStatus != ENUM_ENCRYPTION1_ENABLED) { + /* If the driver is configured to use WEP only, + * ignore this BSS. + */ + return FALSE; + } else if (eEncStatus == + ENUM_ENCRYPTION1_ENABLED) { + /* If the driver is configured to use WEP only, use this BSS. */ + DBGLOG(RSN, INFO, "-- WEP-only legacy BSS\n"); + return TRUE; + } else { + DBGLOG(RSN, INFO, "unknown\n"); + return FALSE; + } + + if (!rsnIsSuitableBSS(prAdapter, prBss, prBssRsnInfo, ucBssIndex)) { +#if CFG_SUPPORT_RSN_SCORE + prBss->fgIsRSNSuitableBss = FALSE; + } else + prBss->fgIsRSNSuitableBss = TRUE; +#else + + return FALSE; + } +#endif + /* end Support AP Selection */ + + if (prBssRsnInfo->u4PairwiseKeyCipherSuiteCount == 1 && + GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[0]) == + CIPHER_SUITE_NONE) { + /* Since the pairwise cipher use the same cipher suite + * as the group cipher in the BSS, we check the group cipher + * suite against the current encryption status. + */ + fgSuiteSupported = FALSE; + + switch (prBssRsnInfo->u4GroupKeyCipherSuite) { + case RSN_CIPHER_SUITE_GCMP_256: + if (eEncStatus == + ENUM_ENCRYPTION4_ENABLED) + fgSuiteSupported = TRUE; + break; + case WPA_CIPHER_SUITE_CCMP: + case RSN_CIPHER_SUITE_CCMP: + if (eEncStatus == + ENUM_ENCRYPTION3_ENABLED) + fgSuiteSupported = TRUE; + break; + + case WPA_CIPHER_SUITE_TKIP: + case RSN_CIPHER_SUITE_TKIP: + if (eEncStatus == + ENUM_ENCRYPTION2_ENABLED) + fgSuiteSupported = TRUE; + break; + + case WPA_CIPHER_SUITE_WEP40: + case WPA_CIPHER_SUITE_WEP104: + if (eEncStatus == + ENUM_ENCRYPTION1_ENABLED) + fgSuiteSupported = TRUE; + break; + } + + if (fgSuiteSupported) { + u4PairwiseCipher = WPA_CIPHER_SUITE_NONE; + u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite; + } +#if DBG + else { + DBGLOG(RSN, TRACE, + "Inproper encryption status %d for group-key-only BSS\n", + eEncStatus); + } +#endif + } else { + fgSuiteSupported = FALSE; + + DBGLOG(RSN, TRACE, + "eEncStatus %d %d 0x%08x\n", + eEncStatus, + prBssRsnInfo->u4PairwiseKeyCipherSuiteCount, + prBssRsnInfo->au4PairwiseKeyCipherSuite[0]); + /* Select pairwise/group ciphers */ + switch (eEncStatus) { + case ENUM_ENCRYPTION4_ENABLED: + for (i = 0; i < prBssRsnInfo->u4PairwiseKeyCipherSuiteCount; + i++) { + /* TODO: WTBL cipher filed cannot + * 1-1 mapping to spec cipher suite number + */ + if (prBssRsnInfo->au4PairwiseKeyCipherSuite[i] == + RSN_CIPHER_SUITE_GCMP_256) { + u4PairwiseCipher = + prBssRsnInfo-> + au4PairwiseKeyCipherSuite[i]; + } + } + u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite; + break; + + case ENUM_ENCRYPTION3_ENABLED: + for (i = 0; i < prBssRsnInfo-> + u4PairwiseKeyCipherSuiteCount; i++) { + if (GET_SELECTOR_TYPE( + prBssRsnInfo-> + au4PairwiseKeyCipherSuite[i]) + == CIPHER_SUITE_CCMP) { + u4PairwiseCipher = + prBssRsnInfo-> + au4PairwiseKeyCipherSuite[i]; + } + } + u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite; + break; + + case ENUM_ENCRYPTION2_ENABLED: + for (i = 0; + i < prBssRsnInfo->u4PairwiseKeyCipherSuiteCount; + i++) { + if (GET_SELECTOR_TYPE + (prBssRsnInfo->au4PairwiseKeyCipherSuite[i]) + == CIPHER_SUITE_TKIP) { + u4PairwiseCipher = + prBssRsnInfo-> + au4PairwiseKeyCipherSuite[i]; + } + } + if (GET_SELECTOR_TYPE + (prBssRsnInfo->u4GroupKeyCipherSuite) + == CIPHER_SUITE_CCMP) + DBGLOG(RSN, TRACE, "Cannot join CCMP BSS\n"); + else + u4GroupCipher = + prBssRsnInfo->u4GroupKeyCipherSuite; + break; + + case ENUM_ENCRYPTION1_ENABLED: + for (i = 0; + i < prBssRsnInfo-> + u4PairwiseKeyCipherSuiteCount; + i++) { + if (GET_SELECTOR_TYPE( + prBssRsnInfo-> + au4PairwiseKeyCipherSuite[i]) + == CIPHER_SUITE_WEP40 || + GET_SELECTOR_TYPE( + prBssRsnInfo-> + au4PairwiseKeyCipherSuite[i]) + == CIPHER_SUITE_WEP104) { + u4PairwiseCipher = prBssRsnInfo-> + au4PairwiseKeyCipherSuite[i]; + } + } + if (GET_SELECTOR_TYPE(prBssRsnInfo-> + u4GroupKeyCipherSuite) + == CIPHER_SUITE_CCMP || + GET_SELECTOR_TYPE(prBssRsnInfo-> + u4GroupKeyCipherSuite) == CIPHER_SUITE_TKIP) { + DBGLOG(RSN, TRACE, + "Cannot join CCMP/TKIP BSS\n"); + } else { + u4GroupCipher = + prBssRsnInfo->u4GroupKeyCipherSuite; + } + break; + + default: + break; + } + } + + /* Exception handler */ + /* If we cannot find proper pairwise and group cipher suites + * to join the BSS, do not check the supported AKM suites. + */ + if (u4PairwiseCipher == 0 || u4GroupCipher == 0) { + DBGLOG(RSN, INFO, + "Failed to select pairwise/group cipher (0x%08x/0x%08x)\n", + u4PairwiseCipher, u4GroupCipher); + return FALSE; + } +#if CFG_ENABLE_WIFI_DIRECT + if ((prAdapter->fgIsP2PRegistered) && + (GET_BSS_INFO_BY_INDEX(prAdapter, + ucBssIndex)->eNetworkType == NETWORK_TYPE_P2P)) { + if (u4PairwiseCipher != RSN_CIPHER_SUITE_CCMP || + u4GroupCipher != RSN_CIPHER_SUITE_CCMP + || u4AkmSuite != RSN_AKM_SUITE_PSK) { + DBGLOG(RSN, INFO, + "Failed to select pairwise/group cipher for P2P network (0x%08x/0x%08x)\n", + u4PairwiseCipher, u4GroupCipher); + return FALSE; + } + } +#endif + +#if CFG_ENABLE_BT_OVER_WIFI + if (GET_BSS_INFO_BY_INDEX(prAdapter, + ucBssIndex)->eNetworkType == NETWORK_TYPE_BOW) { + if (u4PairwiseCipher != RSN_CIPHER_SUITE_CCMP || + u4GroupCipher != RSN_CIPHER_SUITE_CCMP + || u4AkmSuite != RSN_AKM_SUITE_PSK) { + DBGLOG(RSN, INFO, + "Failed to select pairwise/group cipher for BT over Wi-Fi network (0x%08x/0x%08x)\n", + u4PairwiseCipher, u4GroupCipher); + return FALSE; + } + } +#endif + + /* Verify if selected pairwisse cipher is supported */ + fgSuiteSupported = rsnSearchSupportedCipher(prAdapter, + u4PairwiseCipher, &i, ucBssIndex); + + /* Verify if selected group cipher is supported */ + if (fgSuiteSupported) + fgSuiteSupported = rsnSearchSupportedCipher(prAdapter, + u4GroupCipher, &i, ucBssIndex); + + if (!fgSuiteSupported) { + DBGLOG(RSN, INFO, + "Failed to support selected pairwise/group cipher (0x%08x/0x%08x)\n", + u4PairwiseCipher, u4GroupCipher); + return FALSE; + } + + /* Select AKM */ + /* If the driver cannot support any authentication suites advertised in + * the given BSS, we fail to perform RSNA policy selection. + */ + /* Attempt to find any overlapping supported AKM suite. */ + if (eAuthMode == + AUTH_MODE_WPA2_FT_PSK && + rsnSearchAKMSuite(prAdapter, + RSN_AKM_SUITE_FT_PSK, &j, ucBssIndex)) + u4AkmSuite = RSN_AKM_SUITE_FT_PSK; + else if (eAuthMode == + AUTH_MODE_WPA2_FT && + rsnSearchAKMSuite(prAdapter, + RSN_AKM_SUITE_FT_802_1X, &j, ucBssIndex)) + u4AkmSuite = RSN_AKM_SUITE_FT_802_1X; + else +#if CFG_SUPPORT_802_11W + if (i != 0) + for (i = (prBssRsnInfo->u4AuthKeyMgtSuiteCount - 1); i >= 0; + i--) { +#else + for (i = 0; i < prBssRsnInfo->u4AuthKeyMgtSuiteCount; i++) { +#endif + if (rsnSearchAKMSuite(prAdapter, + prBssRsnInfo->au4AuthKeyMgtSuite[i], &j, + ucBssIndex)) { + u4AkmSuite = + prBssRsnInfo->au4AuthKeyMgtSuite[i]; + break; + } + } + + if (u4AkmSuite == 0) { + DBGLOG(RSN, TRACE, "Cannot support any AKM suites\n"); + return FALSE; + } + + DBGLOG(RSN, TRACE, + "Selected pairwise/group cipher: 0x%x/0x%x\n", + SWAP32(u4PairwiseCipher), SWAP32(u4GroupCipher)); + + DBGLOG(RSN, TRACE, + "Selected AKM suite: 0x%x\n", SWAP32(u4AkmSuite)); + +#if CFG_SUPPORT_802_11W + DBGLOG(RSN, TRACE, "[MFP] MFP setting = %d\n ", + kalGetMfpSetting(prAdapter->prGlueInfo, ucBssIndex)); + + if (kalGetMfpSetting(prAdapter->prGlueInfo, + ucBssIndex) == RSN_AUTH_MFP_REQUIRED) { + if (!prBssRsnInfo->fgRsnCapPresent) { + DBGLOG(RSN, TRACE, + "[MFP] Skip RSN IE, No MFP Required Capability.\n"); + return FALSE; + } else if (!(prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPC)) { + DBGLOG(RSN, WARN, + "[MFP] Skip RSN IE, No MFP Required\n"); + return FALSE; + } + aisGetAisSpecBssInfo(prAdapter, ucBssIndex) + ->fgMgmtProtection = TRUE; + } else if (kalGetMfpSetting(prAdapter->prGlueInfo, + ucBssIndex) == + RSN_AUTH_MFP_OPTIONAL) { + if (prBssRsnInfo->u2RsnCap & (ELEM_WPA_CAP_MFPR | + ELEM_WPA_CAP_MFPC)) + aisGetAisSpecBssInfo(prAdapter, ucBssIndex) + ->fgMgmtProtection = TRUE; + } else { + if ((prBssRsnInfo->fgRsnCapPresent) && + (prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPR)) { + DBGLOG(RSN, INFO, + "[MFP] Skip RSN IE, No MFP Required Capability\n"); + return FALSE; + } + } + + if (GET_SELECTOR_TYPE(prBssRsnInfo->u4GroupKeyCipherSuite) + == CIPHER_SUITE_TKIP) { + DBGLOG(RSN, INFO, + "[MFP] Unset PMF flag due to unsupported TKIP\n"); + aisGetAisSpecBssInfo(prAdapter, ucBssIndex) + ->fgMgmtProtection = FALSE; + } + + DBGLOG(RSN, TRACE, + "setting=%d, Cap=%d, CapPresent=%d, MgmtProtection = %d\n", + kalGetMfpSetting(prAdapter->prGlueInfo, ucBssIndex), + prBssRsnInfo->u2RsnCap, + prBssRsnInfo->fgRsnCapPresent, + aisGetAisSpecBssInfo(prAdapter, ucBssIndex) + ->fgMgmtProtection); +#endif + + /* TODO: WTBL cipher filed cannot + * 1-1 mapping to spec cipher suite number + */ + if (u4GroupCipher == RSN_CIPHER_SUITE_GCMP_256) { + prBss->ucEncLevel = 4; + } else if (GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_CCMP) { + prBss->ucEncLevel = 3; + } else if (GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_TKIP) { + prBss->ucEncLevel = 2; + } else if (GET_SELECTOR_TYPE(u4GroupCipher) == + CIPHER_SUITE_WEP40 || + GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_WEP104) { + prBss->ucEncLevel = 1; + } else { + DBGLOG(RSN, WARN, + "GroupCipher not in CCMP/TKIP/WEP40/WEP104\n"); + } + prBss->u4RsnSelectedPairwiseCipher = u4PairwiseCipher; + prBss->u4RsnSelectedGroupCipher = u4GroupCipher; + prBss->u4RsnSelectedAKMSuite = u4AkmSuite; + + return TRUE; + +} /* rsnPerformPolicySelection */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to generate WPA IE for beacon frame. + * + * \param[in] pucIeStartAddr Pointer to put the generated WPA IE. + * + * \return The append WPA-None IE length + * \note + * Called by: JOIN module, compose beacon IE + */ +/*----------------------------------------------------------------------------*/ +void rsnGenerateWpaNoneIE(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo) +{ + uint32_t i; + struct WPA_INFO_ELEM *prWpaIE; + uint32_t u4Suite; + uint16_t u2SuiteCount; + uint8_t *cp, *cp2; + uint8_t ucExpendedLen = 0; + uint8_t *pucBuffer; + uint8_t ucBssIndex; + + DEBUGFUNC("rsnGenerateWpaNoneIE"); + + ucBssIndex = prMsduInfo->ucBssIndex; + + if (GET_BSS_INFO_BY_INDEX(prAdapter, + ucBssIndex)->eNetworkType != NETWORK_TYPE_AIS) + return; + + if (aisGetAuthMode(prAdapter, ucBssIndex) != AUTH_MODE_WPA_NONE) + return; + + pucBuffer = (uint8_t *) ((unsigned long) + prMsduInfo->prPacket + (unsigned long) + prMsduInfo->u2FrameLength); + prWpaIE = (struct WPA_INFO_ELEM *)(pucBuffer); + + /* Start to construct a WPA IE. */ + /* Fill the Element ID field. */ + prWpaIE->ucElemId = ELEM_ID_WPA; + + /* Fill the OUI and OUI Type fields. */ + prWpaIE->aucOui[0] = 0x00; + prWpaIE->aucOui[1] = 0x50; + prWpaIE->aucOui[2] = 0xF2; + prWpaIE->ucOuiType = VENDOR_OUI_TYPE_WPA; + + /* Fill the Version field. */ + WLAN_SET_FIELD_16(&prWpaIE->u2Version, 1); /* version 1 */ + ucExpendedLen = 6; + + /* Fill the Pairwise Key Cipher Suite List field. */ + u2SuiteCount = 0; + cp = (uint8_t *) &prWpaIE->aucPairwiseKeyCipherSuite1[0]; + + if (rsnSearchSupportedCipher(prAdapter, + WPA_CIPHER_SUITE_CCMP, &i, ucBssIndex)) + u4Suite = WPA_CIPHER_SUITE_CCMP; + else if (rsnSearchSupportedCipher(prAdapter, + WPA_CIPHER_SUITE_TKIP, &i, ucBssIndex)) + u4Suite = WPA_CIPHER_SUITE_TKIP; + else if (rsnSearchSupportedCipher(prAdapter, + WPA_CIPHER_SUITE_WEP104, &i, ucBssIndex)) + u4Suite = WPA_CIPHER_SUITE_WEP104; + else if (rsnSearchSupportedCipher(prAdapter, + WPA_CIPHER_SUITE_WEP40, &i, ucBssIndex)) + u4Suite = WPA_CIPHER_SUITE_WEP40; + else + u4Suite = WPA_CIPHER_SUITE_TKIP; + + WLAN_SET_FIELD_32(cp, u4Suite); + u2SuiteCount++; + ucExpendedLen += 4; + + cp = pucBuffer + sizeof(struct WPA_INFO_ELEM); + + /* Fill the Group Key Cipher Suite field as + * the same in pair-wise key. + */ + WLAN_SET_FIELD_32(&prWpaIE->u4GroupKeyCipherSuite, u4Suite); + ucExpendedLen += 4; + + /* Fill the Pairwise Key Cipher Suite Count field. */ + WLAN_SET_FIELD_16(&prWpaIE->u2PairwiseKeyCipherSuiteCount, + u2SuiteCount); + ucExpendedLen += 2; + + cp2 = cp; + + /* Fill the Authentication and Key Management Suite + * List field. + */ + u2SuiteCount = 0; + cp += 2; + + if (rsnSearchAKMSuite(prAdapter, + WPA_AKM_SUITE_802_1X, &i, ucBssIndex)) + u4Suite = WPA_AKM_SUITE_802_1X; + else if (rsnSearchAKMSuite(prAdapter, + WPA_AKM_SUITE_PSK, &i, ucBssIndex)) + u4Suite = WPA_AKM_SUITE_PSK; + else + u4Suite = WPA_AKM_SUITE_NONE; + + /* This shall be the only available value for current implementation */ + ASSERT(u4Suite == WPA_AKM_SUITE_NONE); + + WLAN_SET_FIELD_32(cp, u4Suite); + u2SuiteCount++; + ucExpendedLen += 4; + cp += 4; + + /* Fill the Authentication and Key Management Suite Count field. */ + WLAN_SET_FIELD_16(cp2, u2SuiteCount); + ucExpendedLen += 2; + + /* Fill the Length field. */ + prWpaIE->ucLength = (uint8_t) ucExpendedLen; + + /* Increment the total IE length for the Element ID + * and Length fields. + */ + prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); + +} /* rsnGenerateWpaNoneIE */ + +uint32_t _addWPAIE_impl(IN struct ADAPTER *prAdapter, + IN OUT struct MSDU_INFO *prMsduInfo) +{ + struct P2P_SPECIFIC_BSS_INFO *prP2pSpecBssInfo; + struct BSS_INFO *prBssInfo; + uint8_t ucBssIndex; + + ucBssIndex = prMsduInfo->ucBssIndex; + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + + if (!prAdapter->rWifiVar.fgReuseRSNIE) + return FALSE; + + if (!prBssInfo) + return FALSE; + + /* AP + GO */ + if (!IS_BSS_APGO(prBssInfo)) + return FALSE; + + /* AP only */ + if (!p2pFuncIsAPMode( + prAdapter->rWifiVar. + prP2PConnSettings[prBssInfo->u4PrivateData])) + return FALSE; + + /* PMF only */ + if (!prBssInfo->rApPmfCfg.fgMfpc) + return FALSE; + + prP2pSpecBssInfo = + prAdapter->rWifiVar. + prP2pSpecificBssInfo[prBssInfo->u4PrivateData]; + + if (prP2pSpecBssInfo && + (prP2pSpecBssInfo->u2WpaIeLen != 0)) { + uint8_t *pucBuffer = + (uint8_t *) ((unsigned long) + prMsduInfo->prPacket + (unsigned long) + prMsduInfo->u2FrameLength); + + kalMemCopy(pucBuffer, + prP2pSpecBssInfo->aucWpaIeBuffer, + prP2pSpecBssInfo->u2WpaIeLen); + prMsduInfo->u2FrameLength += prP2pSpecBssInfo->u2WpaIeLen; + + DBGLOG(RSN, INFO, + "Keep supplicant WPA IE content w/o update\n"); + + return TRUE; + } + + return FALSE; +} + + +uint32_t _addRSNIE_impl(IN struct ADAPTER *prAdapter, + IN OUT struct MSDU_INFO *prMsduInfo) +{ + struct P2P_SPECIFIC_BSS_INFO *prP2pSpecBssInfo; + struct BSS_INFO *prBssInfo; + uint8_t ucBssIndex; + + ucBssIndex = prMsduInfo->ucBssIndex; + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + + if (!prAdapter->rWifiVar.fgReuseRSNIE) + return FALSE; + + if (!prBssInfo) + return FALSE; + + /* AP + GO */ + if (!IS_BSS_APGO(prBssInfo)) + return FALSE; + + /* AP only */ + if (!p2pFuncIsAPMode( + prAdapter->rWifiVar. + prP2PConnSettings[prBssInfo->u4PrivateData])) + return FALSE; + + /* PMF only */ + if (!prBssInfo->rApPmfCfg.fgMfpc) + return FALSE; + + prP2pSpecBssInfo = + prAdapter->rWifiVar. + prP2pSpecificBssInfo[prBssInfo->u4PrivateData]; + + if (prP2pSpecBssInfo && + (prP2pSpecBssInfo->u2RsnIeLen != 0)) { + uint8_t *pucBuffer = + (uint8_t *) ((unsigned long) + prMsduInfo->prPacket + (unsigned long) + prMsduInfo->u2FrameLength); + + kalMemCopy(pucBuffer, + prP2pSpecBssInfo->aucRsnIeBuffer, + prP2pSpecBssInfo->u2RsnIeLen); + prMsduInfo->u2FrameLength += prP2pSpecBssInfo->u2RsnIeLen; + + DBGLOG(RSN, INFO, + "Keep supplicant RSN IE content w/o update\n"); + + return TRUE; + } + + return FALSE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * + * \brief This routine is called to generate WPA IE for + * associate request frame. + * + * \param[in] prCurrentBss The Selected BSS description + * + * \retval The append WPA IE length + * + * \note + * Called by: AIS module, Associate request + */ +/*----------------------------------------------------------------------------*/ +void rsnGenerateWPAIE(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo) +{ + uint8_t *cp; + uint8_t *pucBuffer; + uint8_t ucBssIndex; + struct BSS_INFO *prBssInfo; + struct P2P_SPECIFIC_BSS_INFO *prP2pSpecificBssInfo; + enum ENUM_PARAM_AUTH_MODE eAuthMode; + + DEBUGFUNC("rsnGenerateWPAIE"); + + pucBuffer = (uint8_t *) ((unsigned long) + prMsduInfo->prPacket + (unsigned long) + prMsduInfo->u2FrameLength); + ucBssIndex = prMsduInfo->ucBssIndex; + eAuthMode = + aisGetAuthMode(prAdapter, ucBssIndex); + prBssInfo = prAdapter->aprBssInfo[ucBssIndex]; + prP2pSpecificBssInfo = + prAdapter->rWifiVar. + prP2pSpecificBssInfo[prBssInfo->u4PrivateData]; + + /* if (eNetworkId != NETWORK_TYPE_AIS_INDEX) */ + /* return; */ + if (_addWPAIE_impl(prAdapter, prMsduInfo)) + return; + +#if CFG_ENABLE_WIFI_DIRECT + if ((prAdapter->fgIsP2PRegistered && + GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex)-> + eNetworkType == NETWORK_TYPE_P2P && + kalP2PGetTkipCipher(prAdapter->prGlueInfo, + (uint8_t) prBssInfo->u4PrivateData)) || + (GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex)-> + eNetworkType == NETWORK_TYPE_AIS && + (eAuthMode == + AUTH_MODE_WPA || + eAuthMode == + AUTH_MODE_WPA_PSK))) { +#else + if (GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex)-> + eNetworkType == NETWORK_TYPE_AIS && + (eAuthMode == + AUTH_MODE_WPA || + eAuthMode == + AUTH_MODE_WPA_PSK)) { +#endif + if (prAdapter->fgIsP2PRegistered && prP2pSpecificBssInfo + && (prP2pSpecificBssInfo->u2WpaIeLen != 0)) { + kalMemCopy(pucBuffer, + prP2pSpecificBssInfo->aucWpaIeBuffer, + prP2pSpecificBssInfo->u2WpaIeLen); + prMsduInfo->u2FrameLength += + prP2pSpecificBssInfo->u2WpaIeLen; + return; + } + /* Construct a WPA IE for association request frame. */ + WPA_IE(pucBuffer)->ucElemId = ELEM_ID_WPA; + WPA_IE(pucBuffer)->ucLength = ELEM_ID_WPA_LEN_FIXED; + WPA_IE(pucBuffer)->aucOui[0] = 0x00; + WPA_IE(pucBuffer)->aucOui[1] = 0x50; + WPA_IE(pucBuffer)->aucOui[2] = 0xF2; + WPA_IE(pucBuffer)->ucOuiType = VENDOR_OUI_TYPE_WPA; + WLAN_SET_FIELD_16(&WPA_IE(pucBuffer)->u2Version, 1); + +#if CFG_ENABLE_WIFI_DIRECT + if (prAdapter->fgIsP2PRegistered + && GET_BSS_INFO_BY_INDEX(prAdapter, + ucBssIndex)->eNetworkType == NETWORK_TYPE_P2P) { + WLAN_SET_FIELD_32( + &WPA_IE(pucBuffer)->u4GroupKeyCipherSuite, + WPA_CIPHER_SUITE_TKIP); + } else +#endif + WLAN_SET_FIELD_32( + &WPA_IE(pucBuffer)->u4GroupKeyCipherSuite, + prBssInfo-> + u4RsnSelectedGroupCipher); + + cp = (uint8_t *) & + WPA_IE(pucBuffer)->aucPairwiseKeyCipherSuite1[0]; + + WLAN_SET_FIELD_16(&WPA_IE(pucBuffer)-> + u2PairwiseKeyCipherSuiteCount, 1); +#if CFG_ENABLE_WIFI_DIRECT + if (prAdapter->fgIsP2PRegistered + && GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex)-> + eNetworkType == NETWORK_TYPE_P2P) { + WLAN_SET_FIELD_32(cp, WPA_CIPHER_SUITE_TKIP); + } else +#endif + WLAN_SET_FIELD_32(cp, prBssInfo + ->u4RsnSelectedPairwiseCipher); + + cp = pucBuffer + sizeof(struct WPA_INFO_ELEM); + + WLAN_SET_FIELD_16(cp, 1); + cp += 2; +#if CFG_ENABLE_WIFI_DIRECT + if (prAdapter->fgIsP2PRegistered + && GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex)-> + eNetworkType == NETWORK_TYPE_P2P) { + WLAN_SET_FIELD_32(cp, WPA_AKM_SUITE_PSK); + } else +#endif + WLAN_SET_FIELD_32(cp, prBssInfo + ->u4RsnSelectedAKMSuite); + cp += 4; + + WPA_IE(pucBuffer)->ucLength = ELEM_ID_WPA_LEN_FIXED; + + prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); + } + +} /* rsnGenerateWPAIE */ + +/*----------------------------------------------------------------------------*/ +/*! + * + * \brief This routine is called to generate RSN IE for + * associate request frame. + * + * \param[in] prMsduInfo The Selected BSS description + * + * \retval The append RSN IE length + * + * \note + * Called by: AIS module, P2P module, BOW module Associate request + */ +/*----------------------------------------------------------------------------*/ +void rsnGenerateRSNIE(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo) +{ + struct PMKID_ENTRY *entry = NULL; + uint8_t *cp; + /* UINT_8 ucExpendedLen = 0; */ + uint8_t *pucBuffer; + uint8_t ucBssIndex; + struct BSS_INFO *prBssInfo; + struct STA_RECORD *prStaRec; + enum ENUM_PARAM_AUTH_MODE eAuthMode; + struct AIS_SPECIFIC_BSS_INFO *prAisSpecBssInfo; + + DEBUGFUNC("rsnGenerateRSNIE"); + + pucBuffer = (uint8_t *) ((unsigned long) + prMsduInfo->prPacket + (unsigned long) + prMsduInfo->u2FrameLength); + /* Todo:: network id */ + ucBssIndex = prMsduInfo->ucBssIndex; + prAisSpecBssInfo = aisGetAisSpecBssInfo(prAdapter, ucBssIndex); + eAuthMode = aisGetAuthMode(prAdapter, ucBssIndex); + + /* For FT, we reuse the RSN Element composed in userspace */ + if (authAddRSNIE_impl(prAdapter, prMsduInfo)) { + DBGLOG(RSN, TRACE, "RSN IE: authAddRSNIE return\n"); + return; + } + + if (_addRSNIE_impl(prAdapter, prMsduInfo)) { + DBGLOG(RSN, TRACE, "RSN IE: _addRSNIE return\n"); + return; + } + + prBssInfo = prAdapter->aprBssInfo[ucBssIndex]; + + if ( +#if CFG_ENABLE_WIFI_DIRECT + ((prAdapter->fgIsP2PRegistered) && + (GET_BSS_INFO_BY_INDEX(prAdapter, + ucBssIndex)->eNetworkType == NETWORK_TYPE_P2P) + && (kalP2PGetCcmpCipher(prAdapter->prGlueInfo, + (uint8_t) prBssInfo->u4PrivateData))) || +#endif +#if CFG_ENABLE_BT_OVER_WIFI + (GET_BSS_INFO_BY_INDEX(prAdapter, + ucBssIndex)->eNetworkType == NETWORK_TYPE_BOW) + || +#endif + (GET_BSS_INFO_BY_INDEX(prAdapter, + ucBssIndex)->eNetworkType == + NETWORK_TYPE_AIS /* prCurrentBss->fgIERSN */ && + rsnKeyMgmtWpa(prAdapter, eAuthMode, ucBssIndex))) { + /* Construct a RSN IE for association request frame. */ + RSN_IE(pucBuffer)->ucElemId = ELEM_ID_RSN; + RSN_IE(pucBuffer)->ucLength = ELEM_ID_RSN_LEN_FIXED; + /* Version */ + WLAN_SET_FIELD_16(&RSN_IE(pucBuffer)->u2Version, 1); + WLAN_SET_FIELD_32(&RSN_IE(pucBuffer)->u4GroupKeyCipherSuite, + GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex)-> + u4RsnSelectedGroupCipher); + /* Group key suite */ + cp = (uint8_t *) &RSN_IE( + pucBuffer)->aucPairwiseKeyCipherSuite1[0]; + WLAN_SET_FIELD_16(&RSN_IE( + pucBuffer)->u2PairwiseKeyCipherSuiteCount, 1); + WLAN_SET_FIELD_32(cp, GET_BSS_INFO_BY_INDEX(prAdapter, + ucBssIndex)->u4RsnSelectedPairwiseCipher); + + cp = pucBuffer + sizeof(struct RSN_INFO_ELEM); + + if ((prBssInfo->eNetworkType == NETWORK_TYPE_P2P) && + (prBssInfo->u4RsnSelectedAKMSuite == + RSN_AKM_SUITE_SAE)) { + struct P2P_SPECIFIC_BSS_INFO *prP2pSpecBssInfo = + prAdapter->rWifiVar.prP2pSpecificBssInfo + [prBssInfo->u4PrivateData]; + uint8_t i = 0; + + /* AKM suite count */ + WLAN_SET_FIELD_16(cp, + prP2pSpecBssInfo->u4KeyMgtSuiteCount); + cp += 2; + + /* AKM suite */ + for (i = 0; + i < prP2pSpecBssInfo->u4KeyMgtSuiteCount; + i++) { + DBGLOG(RSN, TRACE, "KeyMgtSuite 0x%04x\n", + prP2pSpecBssInfo->au4KeyMgtSuite[i]); + WLAN_SET_FIELD_32(cp, + prP2pSpecBssInfo->au4KeyMgtSuite[i]); + cp += 4; + } + + RSN_IE(pucBuffer)->ucLength += + (prP2pSpecBssInfo->u4KeyMgtSuiteCount - 1) * 4; + } else { + WLAN_SET_FIELD_16(cp, 1); /* AKM suite count */ + cp += 2; + /* AKM suite */ + WLAN_SET_FIELD_32(cp, GET_BSS_INFO_BY_INDEX(prAdapter, + ucBssIndex)->u4RsnSelectedAKMSuite); + cp += 4; + } + + /* Capabilities */ + WLAN_SET_FIELD_16(cp, GET_BSS_INFO_BY_INDEX(prAdapter, + ucBssIndex)->u2RsnSelectedCapInfo); + DBGLOG(RSN, TRACE, + "Gen RSN IE = %x\n", GET_BSS_INFO_BY_INDEX(prAdapter, + ucBssIndex)->u2RsnSelectedCapInfo); + #if CFG_SUPPORT_802_11W + if (GET_BSS_INFO_BY_INDEX(prAdapter, + ucBssIndex)->eNetworkType == NETWORK_TYPE_AIS) { + if (GET_SELECTOR_TYPE(RSN_IE(pucBuffer)-> + u4GroupKeyCipherSuite) == CIPHER_SUITE_TKIP) { + DBGLOG(RSN, TRACE, + "!RSN_AUTH_MFP - TKIP, no MFP\n"); + } else if (kalGetRsnIeMfpCap(prAdapter->prGlueInfo, + ucBssIndex) == + RSN_AUTH_MFP_REQUIRED) { + WLAN_SET_FIELD_16(cp, + ELEM_WPA_CAP_MFPC | ELEM_WPA_CAP_MFPR); + /* Capabilities */ + DBGLOG(RSN, TRACE, + "RSN_AUTH_MFP - MFPC & MFPR\n"); + } else if (kalGetRsnIeMfpCap(prAdapter->prGlueInfo, + ucBssIndex) == + RSN_AUTH_MFP_OPTIONAL) { + WLAN_SET_FIELD_16(cp, ELEM_WPA_CAP_MFPC); + /* Capabilities */ + DBGLOG(RSN, TRACE, "RSN_AUTH_MFP - MFPC\n"); + } else { + DBGLOG(RSN, TRACE, + "!RSN_AUTH_MFP - No MFPC!\n"); + } + } else if ((GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex)-> + eNetworkType == NETWORK_TYPE_P2P) && + (GET_BSS_INFO_BY_INDEX(prAdapter, + ucBssIndex)->eCurrentOPMode == + (uint8_t) OP_MODE_ACCESS_POINT)) { + /* AP PMF */ + /* for AP mode, keep origin RSN IE content w/o update */ + } +#endif + cp += 2; + + /* Fill PMKID and Group Management Cipher for AIS */ + if (GET_BSS_INFO_BY_INDEX(prAdapter, + ucBssIndex)->eNetworkType == NETWORK_TYPE_AIS) { + prStaRec = cnmGetStaRecByIndex(prAdapter, + prMsduInfo->ucStaRecIndex); + + if (!prStaRec) { + DBGLOG(RSN, ERROR, "prStaRec is NULL!"); + } else { + entry = rsnSearchPmkidEntry(prAdapter, + prStaRec->aucMacAddr, ucBssIndex); + } + /* Fill PMKID Count and List field */ + if (entry) { + uint8_t *pmk = entry->rBssidInfo.arPMKID; + + RSN_IE(pucBuffer)->ucLength = 38; + /* Fill PMKID Count field */ + WLAN_SET_FIELD_16(cp, 1); + cp += 2; + DBGLOG(RSN, INFO, "BSSID " MACSTR + "use PMKID " PMKSTR "\n", + MAC2STR(entry->rBssidInfo.arBSSID), + pmk[0], pmk[1], pmk[2], pmk[3], pmk[4], + pmk[5], pmk[6], pmk[7], pmk[8], pmk[9], + pmk[10], pmk[11], pmk[12] + pmk[13], + pmk[14], pmk[15]); + /* Fill PMKID List field */ + kalMemCopy(cp, entry->rBssidInfo.arPMKID, + IW_PMKID_LEN); + cp += IW_PMKID_LEN; + } +#if CFG_SUPPORT_802_11W + else { + /* Follow supplicant flow to + * fill PMKID Count field = 0 only when + * Group Management Cipher field + * need to be filled + */ + if (prAisSpecBssInfo + ->fgMgmtProtection) { + WLAN_SET_FIELD_16(cp, 0) + + cp += 2; + RSN_IE(pucBuffer)->ucLength += 2; + } + } + + /* Fill Group Management Cipher field */ + if (prAisSpecBssInfo->fgMgmtProtection) { + WLAN_SET_FIELD_32(cp, + RSN_CIPHER_SUITE_AES_128_CMAC); + cp += 4; + RSN_IE(pucBuffer)->ucLength += 4; + } +#endif + } + prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); + } + + +} /* rsnGenerateRSNIE */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Parse the given IE buffer and check if it is WFA IE and return Type + * and SubType for further process. + * + * \param[in] pucBuf Pointer to buffer of WFA Information Element. + * \param[out] pucOuiType Pointer to the storage of OUI Type. + * \param[out] pu2SubTypeVersion Pointer to the storage of OUI SubType + * and Version. + * \retval TRUE Parse IE ok + * \retval FALSE Parse IE fail + */ +/*----------------------------------------------------------------------------*/ +u_int8_t +rsnParseCheckForWFAInfoElem(IN struct ADAPTER *prAdapter, + IN uint8_t *pucBuf, OUT uint8_t *pucOuiType, + OUT uint16_t *pu2SubTypeVersion) +{ + uint8_t aucWfaOui[] = VENDOR_OUI_WFA; + struct IE_WFA *prWfaIE; + + prWfaIE = (struct IE_WFA *)pucBuf; + do { + if (IE_LEN(pucBuf) <= ELEM_MIN_LEN_WFA_OUI_TYPE_SUBTYPE) { + break; + } else if (prWfaIE->aucOui[0] != aucWfaOui[0] || + prWfaIE->aucOui[1] != aucWfaOui[1] + || prWfaIE->aucOui[2] != aucWfaOui[2]) { + break; + } + + *pucOuiType = prWfaIE->ucOuiType; + WLAN_GET_FIELD_16(&prWfaIE->aucOuiSubTypeVersion[0], + pu2SubTypeVersion); + + return TRUE; + } while (FALSE); + + return FALSE; + +} /* end of rsnParseCheckForWFAInfoElem() */ + +#if CFG_SUPPORT_AAA +/*----------------------------------------------------------------------------*/ +/*! + * \brief Parse the given IE buffer and check if it is RSN IE with CCMP PSK + * + * \param[in] prAdapter Pointer to Adapter + * \param[in] prSwRfb Pointer to the rx buffer + * \param[in] pIE Pointer rthe buffer of Information Element. + * \param[out] prStatusCode Pointer to the return status code. + + * \retval none + */ +/*----------------------------------------------------------------------------*/ +void rsnParserCheckForRSNCCMPPSK(struct ADAPTER *prAdapter, + struct RSN_INFO_ELEM *prIe, + struct STA_RECORD *prStaRec, + uint16_t *pu2StatusCode) +{ + + struct RSN_INFO rRsnIe; + struct BSS_INFO *prBssInfo; + uint8_t i; + uint16_t statusCode; + + *pu2StatusCode = STATUS_CODE_INVALID_INFO_ELEMENT; + + if (rsnParseRsnIE(prAdapter, prIe, &rRsnIe)) { + if ((rRsnIe.u4PairwiseKeyCipherSuiteCount != 1) + || (rRsnIe.au4PairwiseKeyCipherSuite[0] != + RSN_CIPHER_SUITE_CCMP)) { + *pu2StatusCode = STATUS_CODE_INVALID_PAIRWISE_CIPHER; + return; + } + /* When softap's conf support both TKIP&CCMP, + * the Group Cipher Suite would be TKIP + * If we check the Group Cipher Suite == CCMP + * about peer's Asso Req + * The connection would be fail + * due to STATUS_CODE_INVALID_GROUP_CIPHER + */ + if (rRsnIe.u4GroupKeyCipherSuite != RSN_CIPHER_SUITE_CCMP && + !prAdapter->rWifiVar.fgReuseRSNIE) { + *pu2StatusCode = STATUS_CODE_INVALID_GROUP_CIPHER; + return; + } + + if ((rRsnIe.u4AuthKeyMgtSuiteCount != 1) + || ((rRsnIe.au4AuthKeyMgtSuite[0] != RSN_AKM_SUITE_PSK) +#if CFG_SUPPORT_SOFTAP_WPA3 + && (rRsnIe.au4AuthKeyMgtSuite[0] != RSN_AKM_SUITE_SAE) +#endif + )) { + DBGLOG(RSN, WARN, "RSN with invalid AKMP\n"); + *pu2StatusCode = STATUS_CODE_INVALID_AKMP; + return; + } + + DBGLOG(RSN, TRACE, "RSN with CCMP-PSK\n"); + *pu2StatusCode = WLAN_STATUS_SUCCESS; + +#if CFG_SUPPORT_802_11W + /* AP PMF */ + /* 1st check: if already PMF connection, reject assoc req: + * error 30 ASSOC_REJECTED_TEMPORARILY + */ + if (rsnCheckBipKeyInstalled(prAdapter, prStaRec)) { + *pu2StatusCode = STATUS_CODE_ASSOC_REJECTED_TEMPORARILY; + return; + } + + /* if RSN capability not exist, just return */ + if (!rRsnIe.fgRsnCapPresent) { + *pu2StatusCode = WLAN_STATUS_SUCCESS; + return; + } + + prStaRec->rPmfCfg.fgMfpc = (rRsnIe.u2RsnCap & + ELEM_WPA_CAP_MFPC) ? 1 : 0; + prStaRec->rPmfCfg.fgMfpr = (rRsnIe.u2RsnCap & + ELEM_WPA_CAP_MFPR) ? 1 : 0; + + prStaRec->rPmfCfg.fgSaeRequireMfp = FALSE; + + for (i = 0; i < rRsnIe.u4AuthKeyMgtSuiteCount; i++) { + if ((rRsnIe.au4AuthKeyMgtSuite[i] == + RSN_AKM_SUITE_802_1X_SHA256) || + (rRsnIe.au4AuthKeyMgtSuite[i] == + RSN_AKM_SUITE_PSK_SHA256)) { + DBGLOG(RSN, INFO, "STA SHA256 support\n"); + prStaRec->rPmfCfg.fgSha256 = TRUE; + break; + } else if (rRsnIe.au4AuthKeyMgtSuite[i] == + RSN_AKM_SUITE_SAE) { + DBGLOG(RSN, INFO, "STA SAE support\n"); + prStaRec->rPmfCfg.fgSaeRequireMfp = TRUE; + break; + } + } + + DBGLOG(RSN, INFO, + "STA Assoc req mfpc:%d, mfpr:%d, sha256:%d, bssIndex:%d, applyPmf:%d\n", + prStaRec->rPmfCfg.fgMfpc, prStaRec->rPmfCfg.fgMfpr, + prStaRec->rPmfCfg.fgSha256, prStaRec->ucBssIndex, + prStaRec->rPmfCfg.fgApplyPmf); + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prStaRec->ucBssIndex); + + /* if PMF validation fail, return success as legacy association + */ + statusCode = rsnPmfCapableValidation(prAdapter, prBssInfo, + prStaRec); + *pu2StatusCode = statusCode; +#endif + } + +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to generate an authentication event to NDIS. + * + * \param[in] u4Flags Authentication event: \n + * PARAM_AUTH_REQUEST_REAUTH 0x01 \n + * PARAM_AUTH_REQUEST_KEYUPDATE 0x02 \n + * PARAM_AUTH_REQUEST_PAIRWISE_ERROR 0x06 \n + * PARAM_AUTH_REQUEST_GROUP_ERROR 0x0E \n + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void rsnGenMicErrorEvent(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prSta, IN u_int8_t fgFlags) +{ + struct PARAM_INDICATION_EVENT authEvent; + struct BSS_INFO *prAisBssInfo; + uint8_t ucBssIndex = 0; + + DEBUGFUNC("rsnGenMicErrorEvent"); + + ucBssIndex = prSta->ucBssIndex; + + prAisBssInfo = + aisGetAisBssInfo(prAdapter, + ucBssIndex); + + /* Status type: Authentication Event */ + authEvent.rStatus.eStatusType = ENUM_STATUS_TYPE_AUTHENTICATION; + + /* Authentication request */ + authEvent.rAuthReq.u4Length = sizeof(struct PARAM_AUTH_REQUEST); + COPY_MAC_ADDR(authEvent.rAuthReq.arBssid, + prAisBssInfo->aucBSSID); + if (fgFlags == TRUE) + authEvent.rAuthReq.u4Flags = PARAM_AUTH_REQUEST_GROUP_ERROR; + else + authEvent.rAuthReq.u4Flags = PARAM_AUTH_REQUEST_PAIRWISE_ERROR; + + kalIndicateStatusAndComplete(prAdapter->prGlueInfo, + WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, + (void *)&authEvent, + sizeof(struct PARAM_INDICATION_EVENT), + ucBssIndex); +} /* rsnGenMicErrorEvent */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to handle TKIP MIC failures. + * + * \param[in] adapter_p Pointer to the adapter object data area. + * \param[in] prSta Pointer to the STA which occur MIC Error + * \param[in] fgErrorKeyType type of error key + * + * \retval none + */ +/*----------------------------------------------------------------------------*/ +void rsnTkipHandleMICFailure(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prSta, + IN u_int8_t fgErrorKeyType) +{ + /* UINT_32 u4RsnaCurrentMICFailTime; */ + /* P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; */ + + DEBUGFUNC("rsnTkipHandleMICFailure"); + +#if 1 + rsnGenMicErrorEvent(prAdapter, prSta, fgErrorKeyType); + + /* Generate authentication request event. */ + DBGLOG(RSN, INFO, + "Generate TKIP MIC error event (type: 0%d)\n", fgErrorKeyType); +#else + ASSERT(prSta); + + prAisSpecBssInfo = aisGetAisSpecBssInfo(prAdapter, prSta->ucBssIndex); + + /* Record the MIC error occur time. */ + GET_CURRENT_SYSTIME(&u4RsnaCurrentMICFailTime); + + /* Generate authentication request event. */ + DBGLOG(RSN, INFO, + "Generate TKIP MIC error event (type: 0%d)\n", fgErrorKeyType); + + /* If less than 60 seconds have passed since a previous TKIP MIC + * failure, disassociate from the AP and wait for 60 seconds + * before (re)associating with the same AP. + */ + if (prAisSpecBssInfo->u4RsnaLastMICFailTime != 0 && + !CHECK_FOR_TIMEOUT(u4RsnaCurrentMICFailTime, + prAisSpecBssInfo->u4RsnaLastMICFailTime, + SEC_TO_SYSTIME(TKIP_COUNTERMEASURE_SEC))) { + /* If less than 60 seconds expired since last MIC error, + * we have to block traffic. + */ + + DBGLOG(RSN, INFO, "Start blocking traffic!\n"); + rsnGenMicErrorEvent(prAdapter, /* prSta, */ fgErrorKeyType); + + secFsmEventStartCounterMeasure(prAdapter, prSta); + } else { + rsnGenMicErrorEvent(prAdapter, /* prSta, */ fgErrorKeyType); + DBGLOG(RSN, INFO, "First TKIP MIC error!\n"); + } + + COPY_SYSTIME(prAisSpecBssInfo->u4RsnaLastMICFailTime, + u4RsnaCurrentMICFailTime); +#endif +} /* rsnTkipHandleMICFailure */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to search the desired entry in + * PMKID cache according to the BSSID + * + * \param[in] pucBssid Pointer to the BSSID + * \param[out] pu4EntryIndex Pointer to place the found entry index + * + * \retval TRUE, if found one entry for specified BSSID + * \retval FALSE, if not found + */ +/*----------------------------------------------------------------------------*/ +struct PMKID_ENTRY *rsnSearchPmkidEntry(IN struct ADAPTER *prAdapter, + IN uint8_t *pucBssid, + IN uint8_t ucBssIndex) +{ + struct AIS_SPECIFIC_BSS_INFO *prAisSpecBssInfo; + struct PMKID_ENTRY *entry; + struct LINK *cache; + + prAisSpecBssInfo = aisGetAisSpecBssInfo(prAdapter, + ucBssIndex); + cache = &prAisSpecBssInfo->rPmkidCache; + + LINK_FOR_EACH_ENTRY(entry, cache, rLinkEntry, struct PMKID_ENTRY) { + if (EQUAL_MAC_ADDR(entry->rBssidInfo.arBSSID, pucBssid)) + return entry; + } + + return NULL; +} /* rsnSearchPmkidEntry */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to check the BSS Desc at scan result + * with pre-auth cap at wpa2 mode. If there is no cache entry, + * notify the PMKID indication. + * + * \param[in] prBss The BSS Desc at scan result + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void rsnCheckPmkidCache(IN struct ADAPTER *prAdapter, IN struct BSS_DESC *prBss, + IN uint8_t ucBssIndex) +{ + struct BSS_INFO *prAisBssInfo; + struct AIS_SPECIFIC_BSS_INFO *prAisSpecBssInfo; + struct CONNECTION_SETTINGS *prConnSettings; + + if (!prBss) + return; + + prConnSettings = aisGetConnSettings(prAdapter, ucBssIndex); + prAisBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + prAisSpecBssInfo = + aisGetAisSpecBssInfo(prAdapter, ucBssIndex); + + /* Generate pmkid candidate indications for other APs which are + * also belong to the same SSID with the current connected AP or + * beacon timeout AP but have no available pmkid. + */ + if ((prAisBssInfo->eConnectionState == MEDIA_STATE_CONNECTED || + (prAisBssInfo->eConnectionState == MEDIA_STATE_DISCONNECTED && + aisFsmIsInProcessPostpone(prAdapter, ucBssIndex))) && + prConnSettings->eAuthMode == AUTH_MODE_WPA2 && + EQUAL_SSID(prBss->aucSSID, prBss->ucSSIDLen, + prConnSettings->aucSSID, prConnSettings->ucSSIDLen) && + UNEQUAL_MAC_ADDR(prBss->aucBSSID, prAisBssInfo->aucBSSID) && + !rsnSearchPmkidEntry(prAdapter, prBss->aucBSSID, + ucBssIndex)) { + struct PARAM_PMKID_CANDIDATE candidate; + + COPY_MAC_ADDR(candidate.arBSSID, prBss->aucBSSID); + candidate.u4Flags = prBss->u2RsnCap & MASK_RSNIE_CAP_PREAUTH; + rsnGeneratePmkidIndication(prAdapter, &candidate, + ucBssIndex); + + DBGLOG(RSN, TRACE, "[%d] Generate " MACSTR + " with preauth %d to pmkid candidate list\n", + ucBssIndex, + MAC2STR(prBss->aucBSSID), candidate.u4Flags); + } +} /* rsnCheckPmkidCache */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to add/update pmkid. + * + * \param[in] prPmkid The new pmkid + * + * \return status + */ +/*----------------------------------------------------------------------------*/ +uint32_t rsnSetPmkid(IN struct ADAPTER *prAdapter, + IN struct PARAM_PMKID *prPmkid) +{ + struct AIS_SPECIFIC_BSS_INFO *prAisSpecBssInfo; + struct PMKID_ENTRY *entry; + struct LINK *cache; + + prAisSpecBssInfo = aisGetAisSpecBssInfo(prAdapter, + prPmkid->ucBssIdx); + cache = &prAisSpecBssInfo->rPmkidCache; + + entry = rsnSearchPmkidEntry(prAdapter, prPmkid->arBSSID, + prPmkid->ucBssIdx); + if (!entry) { + entry = kalMemAlloc(sizeof(struct PMKID_ENTRY), VIR_MEM_TYPE); + if (!entry) + return -ENOMEM; + LINK_INSERT_TAIL(cache, &entry->rLinkEntry); + } + + DBGLOG(RSN, INFO, + "[%d] Set " MACSTR ", total %d, PMKID " PMKSTR "\n", + prPmkid->ucBssIdx, + MAC2STR(prPmkid->arBSSID), cache->u4NumElem, + prPmkid->arPMKID[0], prPmkid->arPMKID[1], prPmkid->arPMKID[2], + prPmkid->arPMKID[3], prPmkid->arPMKID[4], prPmkid->arPMKID[5], + prPmkid->arPMKID[6], prPmkid->arPMKID[7], prPmkid->arPMKID[8], + prPmkid->arPMKID[9], prPmkid->arPMKID[10], prPmkid->arPMKID[11], + prPmkid->arPMKID[12] + prPmkid->arPMKID[13], + prPmkid->arPMKID[14], prPmkid->arPMKID[15]); + + kalMemCopy(&entry->rBssidInfo, prPmkid, sizeof(struct PARAM_PMKID)); + return WLAN_STATUS_SUCCESS; +} /* rsnSetPmkid */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to del pmkid. + * + * \param[in] prPmkid pmkid should be deleted + * + * \return status + */ +/*----------------------------------------------------------------------------*/ +uint32_t rsnDelPmkid(IN struct ADAPTER *prAdapter, + IN struct PARAM_PMKID *prPmkid) +{ + struct AIS_SPECIFIC_BSS_INFO *prAisSpecBssInfo; + struct PMKID_ENTRY *entry; + struct LINK *cache; + + if (!prPmkid) + return WLAN_STATUS_INVALID_DATA; + + DBGLOG(RSN, TRACE, "[%d] Del " MACSTR " pmkid\n", + prPmkid->ucBssIdx, + MAC2STR(prPmkid->arBSSID)); + + prAisSpecBssInfo = aisGetAisSpecBssInfo(prAdapter, + prPmkid->ucBssIdx); + cache = &prAisSpecBssInfo->rPmkidCache; + entry = rsnSearchPmkidEntry(prAdapter, prPmkid->arBSSID, + prPmkid->ucBssIdx); + if (entry) { + if (kalMemCmp(prPmkid->arPMKID, + entry->rBssidInfo.arPMKID, IW_PMKID_LEN)) { + DBGLOG(RSN, WARN, "Del " MACSTR " pmkid but mismatch\n", + MAC2STR(prPmkid->arBSSID)); + } + LINK_REMOVE_KNOWN_ENTRY(cache, entry); + kalMemFree(entry, VIR_MEM_TYPE, sizeof(struct PMKID_ENTRY)); + } + + return WLAN_STATUS_SUCCESS; +} /* rsnDelPmkid */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to delete all pmkid. + * + * \return status + */ +/*----------------------------------------------------------------------------*/ +uint32_t rsnFlushPmkid(IN struct ADAPTER *prAdapter, IN uint8_t ucBssIndex) +{ + struct AIS_SPECIFIC_BSS_INFO *prAisSpecBssInfo; + struct PMKID_ENTRY *entry; + struct LINK *cache; + + prAisSpecBssInfo = + aisGetAisSpecBssInfo(prAdapter, ucBssIndex); + cache = &prAisSpecBssInfo->rPmkidCache; + + DBGLOG(RSN, TRACE, "[%d] Flush Pmkid total:%d\n", + ucBssIndex, + cache->u4NumElem); + + while (!LINK_IS_EMPTY(cache)) { + LINK_REMOVE_HEAD(cache, entry, struct PMKID_ENTRY *); + kalMemFree(entry, VIR_MEM_TYPE, sizeof(struct PMKID_ENTRY)); + } + return WLAN_STATUS_SUCCESS; +} /* rsnDelPmkid */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to generate an PMKID candidate list + * indication to NDIS. + * + * \param[in] prAdapter Pointer to the adapter object data area. + * \param[in] u4Flags PMKID candidate list event: + * PARAM_PMKID_CANDIDATE_PREAUTH_ENABLED 0x01 + * + * \retval none + */ +/*----------------------------------------------------------------------------*/ +void rsnGeneratePmkidIndication(IN struct ADAPTER *prAdapter, + IN struct PARAM_PMKID_CANDIDATE *prCandi, + IN uint8_t ucBssIndex) +{ + struct PARAM_INDICATION_EVENT pmkidEvent; + + DEBUGFUNC("rsnGeneratePmkidIndication"); + + /* Status type: PMKID Candidatelist Event */ + pmkidEvent.rStatus.eStatusType = ENUM_STATUS_TYPE_CANDIDATE_LIST; + kalMemCopy(&pmkidEvent.rCandi, prCandi, + sizeof(struct PARAM_PMKID_CANDIDATE)); + + kalIndicateStatusAndComplete(prAdapter->prGlueInfo, + WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, + (void *) &pmkidEvent, + sizeof(struct PARAM_INDICATION_EVENT), + ucBssIndex); +} /* rsnGeneratePmkidIndication */ + +#if CFG_SUPPORT_802_11W + +/*----------------------------------------------------------------------------*/ +/*! + * \brief to check if the Bip Key installed or not + * + * \param[in] + * prAdapter + * + * \return + * TRUE + * FALSE + */ +/*----------------------------------------------------------------------------*/ +uint32_t rsnCheckBipKeyInstalled(IN struct ADAPTER + *prAdapter, IN struct STA_RECORD *prStaRec) +{ + /* caution: prStaRec might be null ! */ + if (prStaRec) { + if (GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex) + ->eNetworkType == (uint8_t) NETWORK_TYPE_AIS) { + return aisGetAisSpecBssInfo(prAdapter, + prStaRec->ucBssIndex) + ->fgBipKeyInstalled; + } else if ((GET_BSS_INFO_BY_INDEX(prAdapter, + prStaRec->ucBssIndex) + ->eNetworkType == NETWORK_TYPE_P2P) + && + (GET_BSS_INFO_BY_INDEX(prAdapter, + prStaRec->ucBssIndex) + ->eCurrentOPMode == OP_MODE_ACCESS_POINT)) { + if (prStaRec->rPmfCfg.fgApplyPmf) + DBGLOG(RSN, INFO, "AP-STA PMF capable\n"); + return prStaRec->rPmfCfg.fgApplyPmf; + } else { + return FALSE; + } + } else + return FALSE; + +} + +/*----------------------------------------------------------------------------*/ +/*! + * + * \brief This routine is called to check the Sa query timeout. + * + * + * \note + * Called by: AIS module, Handle by Sa Quert timeout + */ +/*----------------------------------------------------------------------------*/ +uint8_t rsnCheckSaQueryTimeout( + IN struct ADAPTER *prAdapter, IN uint8_t ucBssIdx) +{ + struct AIS_SPECIFIC_BSS_INFO *prBssSpecInfo; + struct BSS_INFO *prAisBssInfo; + uint32_t now; + + prBssSpecInfo = + aisGetAisSpecBssInfo(prAdapter, ucBssIdx); + prAisBssInfo = + aisGetAisBssInfo(prAdapter, ucBssIdx); + + GET_CURRENT_SYSTIME(&now); + + if (CHECK_FOR_TIMEOUT(now, prBssSpecInfo->u4SaQueryStart, + TU_TO_MSEC(1000))) { + DBGLOG(RSN, INFO, "association SA Query timed out\n"); + + prBssSpecInfo->ucSaQueryTimedOut = 1; + kalMemFree(prBssSpecInfo->pucSaQueryTransId, VIR_MEM_TYPE, + prBssSpecInfo->u4SaQueryCount + * ACTION_SA_QUERY_TR_ID_LEN); + prBssSpecInfo->pucSaQueryTransId = NULL; + prBssSpecInfo->u4SaQueryCount = 0; + cnmTimerStopTimer(prAdapter, &prBssSpecInfo->rSaQueryTimer); +#if 1 + if (prAisBssInfo == NULL) { + DBGLOG(RSN, ERROR, "prAisBssInfo is NULL"); + } else if (prAisBssInfo->eConnectionState == + MEDIA_STATE_CONNECTED) { + struct MSG_AIS_ABORT *prAisAbortMsg; + + prAisAbortMsg = + (struct MSG_AIS_ABORT *) cnmMemAlloc(prAdapter, + RAM_TYPE_MSG, + sizeof(struct MSG_AIS_ABORT)); + if (!prAisAbortMsg) + return 0; + prAisAbortMsg->rMsgHdr.eMsgId = MID_SAA_AIS_FSM_ABORT; + prAisAbortMsg->ucReasonOfDisconnect = + DISCONNECT_REASON_CODE_DISASSOCIATED; + prAisAbortMsg->fgDelayIndication = FALSE; + prAisAbortMsg->ucBssIndex = ucBssIdx; + mboxSendMsg(prAdapter, MBOX_ID_0, + (struct MSG_HDR *) prAisAbortMsg, + MSG_SEND_METHOD_BUF); + } +#else + /* Re-connect */ + kalIndicateStatusAndComplete(prAdapter->prGlueInfo, + WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); +#endif + return 1; + } + + return 0; +} + +/*----------------------------------------------------------------------------*/ +/*! + * + * \brief This routine is called to start the 802.11w sa query timer. + * + * + * \note + * Called by: AIS module, Handle Rx mgmt request + */ +/*----------------------------------------------------------------------------*/ +void rsnStartSaQueryTimer(IN struct ADAPTER *prAdapter, + IN unsigned long ulParamPtr) +{ + struct BSS_INFO *prBssInfo; + struct AIS_SPECIFIC_BSS_INFO *prBssSpecInfo; + struct MSDU_INFO *prMsduInfo; + struct ACTION_SA_QUERY_FRAME *prTxFrame; + uint16_t u2PayloadLen; + uint8_t *pucTmp = NULL; + uint8_t ucTransId[ACTION_SA_QUERY_TR_ID_LEN]; + uint8_t ucBssIndex = (uint8_t) ulParamPtr; + + prBssInfo = aisGetAisBssInfo(prAdapter, + ucBssIndex); + prBssSpecInfo = aisGetAisSpecBssInfo(prAdapter, ucBssIndex); + + DBGLOG(RSN, INFO, "MFP: Start Sa Query\n"); + + if (prBssInfo->prStaRecOfAP == NULL) { + DBGLOG(RSN, INFO, "MFP: unassociated AP!\n"); + return; + } + + if (prBssSpecInfo->u4SaQueryCount > 0 + && rsnCheckSaQueryTimeout(prAdapter, + ucBssIndex)) { + DBGLOG(RSN, INFO, "MFP: u4SaQueryCount count =%d\n", + prBssSpecInfo->u4SaQueryCount); + return; + } + + prMsduInfo = (struct MSDU_INFO *)cnmMgtPktAlloc(prAdapter, + MAC_TX_RESERVED_FIELD + + PUBLIC_ACTION_MAX_LEN); + + if (!prMsduInfo) + return; + + prTxFrame = (struct ACTION_SA_QUERY_FRAME *) + ((unsigned long)(prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); + + prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; + if (rsnCheckBipKeyInstalled(prAdapter, prBssInfo->prStaRecOfAP)) + prTxFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME; + COPY_MAC_ADDR(prTxFrame->aucDestAddr, prBssInfo->aucBSSID); + COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); + COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); + + prTxFrame->ucCategory = CATEGORY_SA_QUERY_ACTION; + prTxFrame->ucAction = ACTION_SA_QUERY_REQUEST; + + if (prBssSpecInfo->u4SaQueryCount == 0) + GET_CURRENT_SYSTIME(&prBssSpecInfo->u4SaQueryStart); + + if (prBssSpecInfo->u4SaQueryCount) { + pucTmp = kalMemAlloc(prBssSpecInfo->u4SaQueryCount * + ACTION_SA_QUERY_TR_ID_LEN, VIR_MEM_TYPE); + if (!pucTmp) { + DBGLOG(RSN, INFO, + "MFP: Fail to alloc tmp buffer for backup sa query id\n"); + cnmMgtPktFree(prAdapter, prMsduInfo); + return; + } + kalMemCopy(pucTmp, prBssSpecInfo->pucSaQueryTransId, + prBssSpecInfo->u4SaQueryCount + * ACTION_SA_QUERY_TR_ID_LEN); + } + + kalMemFree(prBssSpecInfo->pucSaQueryTransId, VIR_MEM_TYPE, + prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN); + + ucTransId[0] = (uint8_t) (kalRandomNumber() & 0xFF); + ucTransId[1] = (uint8_t) (kalRandomNumber() & 0xFF); + + kalMemCopy(prTxFrame->ucTransId, ucTransId, ACTION_SA_QUERY_TR_ID_LEN); + + prBssSpecInfo->u4SaQueryCount++; + + prBssSpecInfo->pucSaQueryTransId = + kalMemAlloc(prBssSpecInfo->u4SaQueryCount * + ACTION_SA_QUERY_TR_ID_LEN, VIR_MEM_TYPE); + if (!prBssSpecInfo->pucSaQueryTransId) { + kalMemFree(pucTmp, VIR_MEM_TYPE, + (prBssSpecInfo->u4SaQueryCount - 1) * + ACTION_SA_QUERY_TR_ID_LEN); + DBGLOG(RSN, INFO, + "MFP: Fail to alloc buffer for sa query id list\n"); + cnmMgtPktFree(prAdapter, prMsduInfo); + return; + } + + if (pucTmp) { + kalMemCopy(prBssSpecInfo->pucSaQueryTransId, pucTmp, + (prBssSpecInfo->u4SaQueryCount - 1) * + ACTION_SA_QUERY_TR_ID_LEN); + kalMemCopy( + &prBssSpecInfo->pucSaQueryTransId[ + (prBssSpecInfo->u4SaQueryCount - 1) + * ACTION_SA_QUERY_TR_ID_LEN], + ucTransId, ACTION_SA_QUERY_TR_ID_LEN); + kalMemFree(pucTmp, VIR_MEM_TYPE, + (prBssSpecInfo->u4SaQueryCount - + 1) * ACTION_SA_QUERY_TR_ID_LEN); + } else { + kalMemCopy(prBssSpecInfo->pucSaQueryTransId, ucTransId, + ACTION_SA_QUERY_TR_ID_LEN); + } + + u2PayloadLen = 2 + ACTION_SA_QUERY_TR_ID_LEN; + + /* 4 <3> Update information of MSDU_INFO_T */ + TX_SET_MMPDU(prAdapter, + prMsduInfo, + prBssInfo->prStaRecOfAP->ucBssIndex, + prBssInfo->prStaRecOfAP->ucIndex, + WLAN_MAC_MGMT_HEADER_LEN, + WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen, NULL, + MSDU_RATE_MODE_AUTO); + + /* 4 Enqueue the frame to send this action frame. */ + nicTxEnqueueMsdu(prAdapter, prMsduInfo); + + DBGLOG(RSN, INFO, "Set SA Query timer %d (%d Tu)", + prBssSpecInfo->u4SaQueryCount, 201); + + cnmTimerStartTimer(prAdapter, &prBssSpecInfo->rSaQueryTimer, + TU_TO_MSEC(201)); + +} + +/*----------------------------------------------------------------------------*/ +/*! + * + * \brief This routine is called to start the 802.11w sa query. + * + * + * \note + * Called by: AIS module, Handle Rx mgmt request + */ +/*----------------------------------------------------------------------------*/ +void rsnStartSaQuery(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIdx) +{ + struct AIS_SPECIFIC_BSS_INFO *prBssSpecInfo; + + prBssSpecInfo = aisGetAisSpecBssInfo(prAdapter, ucBssIdx); + + if (prBssSpecInfo->u4SaQueryCount == 0) + rsnStartSaQueryTimer(prAdapter, (unsigned long) ucBssIdx); +} + +/*----------------------------------------------------------------------------*/ +/*! + * + * \brief This routine is called to stop the 802.11w sa query. + * + * + * \note + * Called by: AIS module, Handle Rx mgmt request + */ +/*----------------------------------------------------------------------------*/ +void rsnStopSaQuery(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIdx) +{ + struct AIS_SPECIFIC_BSS_INFO *prBssSpecInfo; + + prBssSpecInfo = aisGetAisSpecBssInfo(prAdapter, ucBssIdx); + + cnmTimerStopTimer(prAdapter, &prBssSpecInfo->rSaQueryTimer); + + if (prBssSpecInfo->pucSaQueryTransId) { + kalMemFree(prBssSpecInfo->pucSaQueryTransId, VIR_MEM_TYPE, + prBssSpecInfo->u4SaQueryCount + * ACTION_SA_QUERY_TR_ID_LEN); + prBssSpecInfo->pucSaQueryTransId = NULL; + } + + prBssSpecInfo->u4SaQueryCount = 0; +} + +/*----------------------------------------------------------------------------*/ +/*! + * + * \brief This routine is called to process the 802.11w sa query action frame. + * + * + * \note + * Called by: AIS module, Handle Rx mgmt request + */ +/*----------------------------------------------------------------------------*/ +void rsnSaQueryRequest(IN struct ADAPTER *prAdapter, IN struct SW_RFB *prSwRfb) +{ + struct BSS_INFO *prBssInfo; + struct MSDU_INFO *prMsduInfo; + struct ACTION_SA_QUERY_FRAME *prRxFrame = NULL; + uint16_t u2PayloadLen; + struct STA_RECORD *prStaRec; + struct ACTION_SA_QUERY_FRAME *prTxFrame; + uint8_t ucBssIndex = secGetBssIdxByRfb(prAdapter, + prSwRfb); + + prBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + if (!prSwRfb) + return; + + prRxFrame = (struct ACTION_SA_QUERY_FRAME *) + prSwRfb->pvHeader; + if (!prRxFrame) + return; + + prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); + if (!prStaRec) /* Todo:: for not AIS check */ + return; + + DBGLOG(RSN, INFO, + "IEEE 802.11: Received SA Query Request from " MACSTR "\n", + MAC2STR(prStaRec->aucMacAddr)); + + DBGLOG_MEM8(RSN, INFO, prRxFrame->ucTransId, ACTION_SA_QUERY_TR_ID_LEN); + + if (kalGetMediaStateIndicated(prAdapter->prGlueInfo, + ucBssIndex) == + MEDIA_STATE_DISCONNECTED) { + DBGLOG(RSN, INFO, + "IEEE 802.11: Ignore SA Query Request from unassociated STA " + MACSTR "\n", MAC2STR(prStaRec->aucMacAddr)); + return; + } + + DBGLOG(RSN, INFO, + "IEEE 802.11: Sending SA Query Response to " MACSTR "\n", + MAC2STR(prStaRec->aucMacAddr)); + + prMsduInfo = (struct MSDU_INFO *)cnmMgtPktAlloc(prAdapter, + MAC_TX_RESERVED_FIELD + + PUBLIC_ACTION_MAX_LEN); + + if (!prMsduInfo) + return; + + prTxFrame = (struct ACTION_SA_QUERY_FRAME *) + ((unsigned long)(prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); + + prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; + if (rsnCheckBipKeyInstalled(prAdapter, prBssInfo->prStaRecOfAP)) + prTxFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME; + COPY_MAC_ADDR(prTxFrame->aucDestAddr, prBssInfo->aucBSSID); + COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); + COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); + + prTxFrame->ucCategory = CATEGORY_SA_QUERY_ACTION; + prTxFrame->ucAction = ACTION_SA_QUERY_RESPONSE; + + kalMemCopy(prTxFrame->ucTransId, prRxFrame->ucTransId, + ACTION_SA_QUERY_TR_ID_LEN); + + u2PayloadLen = 2 + ACTION_SA_QUERY_TR_ID_LEN; + + /* 4 <3> Update information of MSDU_INFO_T */ + TX_SET_MMPDU(prAdapter, + prMsduInfo, + prBssInfo->prStaRecOfAP->ucBssIndex, + prBssInfo->prStaRecOfAP->ucIndex, + WLAN_MAC_MGMT_HEADER_LEN, + WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen, NULL, + MSDU_RATE_MODE_AUTO); + +#if 0 + /* 4 Update information of MSDU_INFO_T */ + /* Management frame */ + prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; + prMsduInfo->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex; + prMsduInfo->ucNetworkType = prBssInfo->ucNetTypeIndex; + prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; + prMsduInfo->fgIs802_1x = FALSE; + prMsduInfo->fgIs802_11 = TRUE; + prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; + prMsduInfo->ucPID = nicAssignPID(prAdapter); + prMsduInfo->pfTxDoneHandler = NULL; + prMsduInfo->fgIsBasicRate = FALSE; +#endif + /* 4 Enqueue the frame to send this action frame. */ + nicTxEnqueueMsdu(prAdapter, prMsduInfo); + +} + +/*----------------------------------------------------------------------------*/ +/*! + * + * \brief This routine is called to process the 802.11w sa query action frame. + * + * + * \note + * Called by: AIS module, Handle Rx mgmt request + */ +/*----------------------------------------------------------------------------*/ +void rsnSaQueryAction(IN struct ADAPTER *prAdapter, IN struct SW_RFB *prSwRfb) +{ + struct AIS_SPECIFIC_BSS_INFO *prBssSpecInfo; + struct ACTION_SA_QUERY_FRAME *prRxFrame; + struct STA_RECORD *prStaRec; + uint32_t i; + uint8_t ucBssIndex = secGetBssIdxByRfb(prAdapter, + prSwRfb); + + prBssSpecInfo = + aisGetAisSpecBssInfo(prAdapter, ucBssIndex); + + prRxFrame = (struct ACTION_SA_QUERY_FRAME *) + prSwRfb->pvHeader; + prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); + + if (!prStaRec) + return; + + if (prSwRfb->u2PacketLen < ACTION_SA_QUERY_TR_ID_LEN) { + DBGLOG(RSN, INFO, + "IEEE 802.11: Too short SA Query Action frame (len=%lu)\n", + (unsigned long)prSwRfb->u2PacketLen); + return; + } + + if (prRxFrame->ucAction == ACTION_SA_QUERY_REQUEST) { + rsnSaQueryRequest(prAdapter, prSwRfb); + return; + } + + if (prRxFrame->ucAction != ACTION_SA_QUERY_RESPONSE) { + DBGLOG(RSN, INFO, + "IEEE 802.11: Unexpected SA Query Action %d\n", + prRxFrame->ucAction); + return; + } + + DBGLOG(RSN, INFO, + "IEEE 802.11: Received SA Query Response from " MACSTR "\n", + MAC2STR(prStaRec->aucMacAddr)); + + DBGLOG_MEM8(RSN, INFO, prRxFrame->ucTransId, ACTION_SA_QUERY_TR_ID_LEN); + + /* MLME-SAQuery.confirm */ + + for (i = 0; i < prBssSpecInfo->u4SaQueryCount; i++) { + if (kalMemCmp(prBssSpecInfo->pucSaQueryTransId + + i * ACTION_SA_QUERY_TR_ID_LEN, + prRxFrame->ucTransId, + ACTION_SA_QUERY_TR_ID_LEN) == 0) + break; + } + + if (i >= prBssSpecInfo->u4SaQueryCount) { + DBGLOG(RSN, INFO, + "IEEE 802.11: No matching SA Query transaction identifier found\n"); + return; + } + + DBGLOG(RSN, INFO, "Reply to pending SA Query received\n"); + + rsnStopSaQuery(prAdapter, ucBssIndex); +} +#endif + +static u_int8_t rsnCheckWpaRsnInfo(struct BSS_INFO *prBss, + struct BSS_DESC *prBssDesc, + struct RSN_INFO *prWpaRsnInfo) +{ + uint32_t i = 0, s; + + if (prWpaRsnInfo->u4GroupKeyCipherSuite != + prBss->u4RsnSelectedGroupCipher) { + DBGLOG(RSN, INFO, + "GroupCipherSuite change, old=0x%04x, new=0x%04x\n", + prBss->u4RsnSelectedGroupCipher, + prWpaRsnInfo->u4GroupKeyCipherSuite); + return TRUE; + } + + /* check akm */ + s = SWAP32(prBss->u4RsnSelectedAKMSuite); + if (prBssDesc->ucIsAdaptive11r && + (s == WLAN_AKM_SUITE_FT_8021X || s == WLAN_AKM_SUITE_FT_PSK)) + return FALSE; + + for (; i < prWpaRsnInfo->u4AuthKeyMgtSuiteCount; i++) + if (prBss->u4RsnSelectedAKMSuite == + prWpaRsnInfo->au4AuthKeyMgtSuite[i]) + break; + + if (i == prWpaRsnInfo->u4AuthKeyMgtSuiteCount) { + DBGLOG(RSN, INFO, + "KeyMgmt change, not find 0x%04x in new beacon\n", + prBss->u4RsnSelectedAKMSuite); + return TRUE; + } + + for (i = 0; i < prWpaRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) + if (prBss->u4RsnSelectedPairwiseCipher == + prWpaRsnInfo->au4PairwiseKeyCipherSuite[i]) + break; + if (i == prWpaRsnInfo->u4PairwiseKeyCipherSuiteCount) { + DBGLOG(RSN, INFO, + "Pairwise Cipher change, not find 0x%04x in new beacon\n", + prBss->u4RsnSelectedPairwiseCipher); + return TRUE; + } + + return FALSE; +} + +u_int8_t rsnCheckSecurityModeChanged( + struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, + struct BSS_DESC *prBssDesc) +{ + uint8_t ucBssIdx = 0; + enum ENUM_PARAM_AUTH_MODE eAuthMode; + struct GL_WPA_INFO *prWpaInfo; + + if (!prBssInfo) { + DBGLOG(RSN, ERROR, "Empty prBssInfo\n"); + return FALSE; + } + ucBssIdx = prBssInfo->ucBssIndex; + eAuthMode = aisGetAuthMode(prAdapter, ucBssIdx); + prWpaInfo = aisGetWpaInfo(prAdapter, ucBssIdx); + + switch (eAuthMode) { + case AUTH_MODE_OPEN: /* original is open system */ + if ((prBssDesc->u2CapInfo & CAP_INFO_PRIVACY) && + !prWpaInfo->fgPrivacyInvoke) { + DBGLOG(RSN, INFO, "security change, open->privacy\n"); + return TRUE; + } + break; + case AUTH_MODE_SHARED: /* original is WEP */ + case AUTH_MODE_AUTO_SWITCH: + if ((prBssDesc->u2CapInfo & CAP_INFO_PRIVACY) == 0) { + DBGLOG(RSN, INFO, "security change, WEP->open\n"); + return TRUE; + } else if (prBssDesc->fgIERSN || prBssDesc->fgIEWPA) { + DBGLOG(RSN, INFO, "security change, WEP->WPA/WPA2\n"); + return TRUE; + } + break; + case AUTH_MODE_WPA: /*original is WPA */ + case AUTH_MODE_WPA_PSK: + case AUTH_MODE_WPA_NONE: + if (prBssDesc->fgIEWPA) + return rsnCheckWpaRsnInfo(prBssInfo, prBssDesc, + &prBssDesc->rWPAInfo); + DBGLOG(RSN, INFO, "security change, WPA->%s\n", + prBssDesc->fgIERSN ? "WPA2" : + (prBssDesc->u2CapInfo & CAP_INFO_PRIVACY ? + "WEP" : "OPEN")); + return TRUE; + case AUTH_MODE_WPA2: /*original is WPA2 */ + case AUTH_MODE_WPA2_PSK: + case AUTH_MODE_WPA2_FT: + case AUTH_MODE_WPA2_FT_PSK: + case AUTH_MODE_WPA3_SAE: + if (prBssDesc->fgIERSN) + return rsnCheckWpaRsnInfo(prBssInfo, prBssDesc, + &prBssDesc->rRSNInfo); + DBGLOG(RSN, INFO, "security change, WPA2->%s\n", + prBssDesc->fgIEWPA ? "WPA" : + (prBssDesc->u2CapInfo & CAP_INFO_PRIVACY ? + "WEP" : "OPEN")); + return TRUE; + default: + DBGLOG(RSN, WARN, "unknowned eAuthMode=%d\n", eAuthMode); + break; + } + return FALSE; +} + +#if CFG_SUPPORT_AAA +#define WPS_DEV_OUI_WFA 0x0050f204 +#define ATTR_RESPONSE_TYPE 0x103b + +#define ATTR_VERSION 0x104a +#define ATTR_VENDOR_EXT 0x1049 +#define WPS_VENDOR_ID_WFA 14122 + +void rsnGenerateWSCIEForAssocRsp(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo) +{ + struct WIFI_VAR *prWifiVar = NULL; + struct BSS_INFO *prP2pBssInfo = (struct BSS_INFO *)NULL; + uint16_t u2IELen = 0; + + prWifiVar = &(prAdapter->rWifiVar); + + DBGLOG(RSN, TRACE, "WPS: Building WPS IE for (Re)Association Response"); + prP2pBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prMsduInfo->ucBssIndex); + + if (prP2pBssInfo->eNetworkType != NETWORK_TYPE_P2P) + return; + + u2IELen = kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 3, + (uint8_t) prP2pBssInfo->u4PrivateData); + + kalP2PGenWSC_IE(prAdapter->prGlueInfo, + 3, + (uint8_t *) ((unsigned long) prMsduInfo->prPacket + + (unsigned long) prMsduInfo->u2FrameLength), + (uint8_t) prP2pBssInfo->u4PrivateData); + prMsduInfo->u2FrameLength += (uint16_t) kalP2PCalWSC_IELen( + prAdapter->prGlueInfo, 3, + (uint8_t) prP2pBssInfo->u4PrivateData); +} + +#endif + +#if CFG_SUPPORT_802_11W +/* AP PMF */ +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to validate setting if PMF connection capable + * or not. If AP MFPC=1, and STA MFPC=1, we let this as PMF connection + * + * + * \return status code + */ +/*----------------------------------------------------------------------------*/ +uint16_t rsnPmfCapableValidation(IN struct ADAPTER + *prAdapter, IN struct BSS_INFO *prBssInfo, + IN struct STA_RECORD *prStaRec) +{ + u_int8_t selfMfpc, selfMfpr, peerMfpc, peerMfpr; + + selfMfpc = prBssInfo->rApPmfCfg.fgMfpc; + selfMfpr = prBssInfo->rApPmfCfg.fgMfpr; + peerMfpc = prStaRec->rPmfCfg.fgMfpc; + peerMfpr = prStaRec->rPmfCfg.fgMfpr; + + DBGLOG(RSN, INFO, + "AP mfpc:%d, mfpr:%d / STA mfpc:%d, mfpr:%d\n", + selfMfpc, selfMfpr, peerMfpc, peerMfpr); + + if ((selfMfpc == TRUE) && (peerMfpc == FALSE)) { + if ((selfMfpr == TRUE) && (peerMfpr == FALSE)) { + DBGLOG(RSN, ERROR, + "PMF policy violation for case 4\n"); + return STATUS_CODE_ROBUST_MGMT_FRAME_POLICY_VIOLATION; + } + + if (peerMfpr == TRUE) { + DBGLOG(RSN, ERROR, + "PMF policy violation for case 7\n"); + return STATUS_CODE_ROBUST_MGMT_FRAME_POLICY_VIOLATION; + } + + if ((prBssInfo->u4RsnSelectedAKMSuite == + RSN_AKM_SUITE_SAE) && + prStaRec->rPmfCfg.fgSaeRequireMfp) { + DBGLOG(RSN, ERROR, + "PMF policy violation for case sae_require_mfp\n"); + return STATUS_CODE_ROBUST_MGMT_FRAME_POLICY_VIOLATION; + } + } + + if ((selfMfpc == TRUE) && (peerMfpc == TRUE)) { + DBGLOG(RSN, ERROR, "PMF Connection\n"); + prStaRec->rPmfCfg.fgApplyPmf = TRUE; + } + + return STATUS_CODE_SUCCESSFUL; + +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to generate TIMEOUT INTERVAL IE + * for association resp. + * Add Timeout interval IE (56) when PMF invalid association. + * + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void rsnPmfGenerateTimeoutIE(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo) +{ + struct IE_TIMEOUT_INTERVAL *prTimeout; + struct STA_RECORD *prStaRec = NULL; + + prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); + + if (!prStaRec) + return; + + prTimeout = (struct IE_TIMEOUT_INTERVAL *) + (((uint8_t *) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength); + + /* only when PMF connection, and association error code is 30 */ + if ((rsnCheckBipKeyInstalled(prAdapter, prStaRec) == TRUE) + && + (prStaRec->u2StatusCode == + STATUS_CODE_ASSOC_REJECTED_TEMPORARILY)) { + + DBGLOG(RSN, INFO, "rsnPmfGenerateTimeoutIE TRUE\n"); + prTimeout->ucId = ELEM_ID_TIMEOUT_INTERVAL; + prTimeout->ucLength = ELEM_MAX_LEN_TIMEOUT_IE; + prTimeout->ucType = IE_TIMEOUT_INTERVAL_TYPE_ASSOC_COMEBACK; + prTimeout->u4Value = 1 << 10; + prMsduInfo->u2FrameLength += IE_SIZE(prTimeout); + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * + * \brief This routine is called to check the Sa query timeout. + * check if total retry time is greater than 1000ms + * + * \retval 1: retry max timeout. 0: not timeout + * \note + * Called by: AAA module, Handle by Sa Query timeout + */ +/*----------------------------------------------------------------------------*/ +uint8_t rsnApCheckSaQueryTimeout(IN struct ADAPTER + *prAdapter, IN struct STA_RECORD *prStaRec) +{ + struct BSS_INFO *prBssInfo; + uint32_t now; + + GET_CURRENT_SYSTIME(&now); + + if (CHECK_FOR_TIMEOUT(now, prStaRec->rPmfCfg.u4SAQueryStart, + TU_TO_MSEC(1000))) { + DBGLOG(RSN, INFO, "association SA Query timed out\n"); + + /* XXX PMF TODO how to report STA REC disconnect?? */ + /* when SAQ retry count timeout, clear this STA */ + prStaRec->rPmfCfg.ucSAQueryTimedOut = 1; + prStaRec->rPmfCfg.u2TransactionID = 0; + prStaRec->rPmfCfg.u4SAQueryCount = 0; + cnmTimerStopTimer(prAdapter, &prStaRec->rPmfCfg.rSAQueryTimer); + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prStaRec->ucBssIndex); + + /* refer to p2pRoleFsmRunEventRxDeauthentication */ + if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) { + if (bssRemoveClient(prAdapter, prBssInfo, prStaRec)) { + /* Indicate disconnect to Host. */ + p2pFuncDisconnect(prAdapter, prBssInfo, + prStaRec, FALSE, 0); + /* Deactive BSS if PWR is IDLE and no peer */ + if (IS_NET_PWR_STATE_IDLE(prAdapter, + prBssInfo->ucBssIndex) + && + (bssGetClientCount(prAdapter, prBssInfo) + == 0)) { + /* All Peer disconnected !! + * Stop BSS now!! + */ + p2pFuncStopComplete(prAdapter, + prBssInfo); + } + } + } + + return 1; + } + + return 0; +} + +/*----------------------------------------------------------------------------*/ +/*! + * + * \brief This routine is called to start the 802.11w sa query timer. + * This routine is triggered every 201ms, and every time enter function, + * check max timeout + * + * \note + * Called by: AAA module, Handle TX SAQ request + */ +/*----------------------------------------------------------------------------*/ +void rsnApStartSaQueryTimer(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, + IN unsigned long ulParamPtr) +{ + struct BSS_INFO *prBssInfo; + struct MSDU_INFO *prMsduInfo; + struct ACTION_SA_QUERY_FRAME *prTxFrame; + uint16_t u2PayloadLen; + + DBGLOG(RSN, INFO, "MFP: AP Start Sa Query timer\n"); + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex); + + if (prStaRec->rPmfCfg.u4SAQueryCount > 0 + && rsnApCheckSaQueryTimeout(prAdapter, prStaRec)) { + DBGLOG(RSN, INFO, + "MFP: retry max timeout, u4SaQueryCount count =%d\n", + prStaRec->rPmfCfg.u4SAQueryCount); + return; + } + + prMsduInfo = (struct MSDU_INFO *)cnmMgtPktAlloc(prAdapter, + MAC_TX_RESERVED_FIELD + + PUBLIC_ACTION_MAX_LEN); + + if (!prMsduInfo) + return; + + prTxFrame = (struct ACTION_SA_QUERY_FRAME *) + ((unsigned long)(prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); + + prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; + if (rsnCheckBipKeyInstalled(prAdapter, prStaRec)) + prTxFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME; + COPY_MAC_ADDR(prTxFrame->aucDestAddr, prStaRec->aucMacAddr); + COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucBSSID); + COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); + + prTxFrame->ucCategory = CATEGORY_SA_QUERY_ACTION; + prTxFrame->ucAction = ACTION_SA_QUERY_REQUEST; + + if (prStaRec->rPmfCfg.u4SAQueryCount == 0) + GET_CURRENT_SYSTIME(&prStaRec->rPmfCfg.u4SAQueryStart); + + /* if retry, transcation id ++ */ + if (prStaRec->rPmfCfg.u4SAQueryCount) { + prStaRec->rPmfCfg.u2TransactionID++; + } else { + /* if first SAQ request, random pick transaction id */ + prStaRec->rPmfCfg.u2TransactionID = + (uint16_t) (kalRandomNumber() & 0xFFFF); + } + + DBGLOG(RSN, INFO, "SAQ transaction id:%d\n", + prStaRec->rPmfCfg.u2TransactionID); + + /* trnsform U16 to U8 array */ + prTxFrame->ucTransId[0] = ((prStaRec->rPmfCfg.u2TransactionID + & 0xff00) >> 8); + prTxFrame->ucTransId[1] = ((prStaRec->rPmfCfg.u2TransactionID + & 0x00ff) >> 0); + + prStaRec->rPmfCfg.u4SAQueryCount++; + + u2PayloadLen = 2 + ACTION_SA_QUERY_TR_ID_LEN; + + /* 4 <3> Update information of MSDU_INFO_T */ + TX_SET_MMPDU(prAdapter, + prMsduInfo, + prStaRec->ucBssIndex, + prStaRec->ucIndex, + WLAN_MAC_MGMT_HEADER_LEN, + WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen, NULL, + MSDU_RATE_MODE_AUTO); + + /* 4 Enqueue the frame to send this action frame. */ + nicTxEnqueueMsdu(prAdapter, prMsduInfo); + + DBGLOG(RSN, INFO, "AP Set SA Query timer %d (%d Tu)\n", + prStaRec->rPmfCfg.u4SAQueryCount, 201); + + cnmTimerStartTimer(prAdapter, + &prStaRec->rPmfCfg.rSAQueryTimer, TU_TO_MSEC(201)); + +} + +/*----------------------------------------------------------------------------*/ +/*! + * + * \brief This routine is called to start the 802.11w TX SA query. + * + * + * \note + * Called by: AAA module, Handle Tx action frame request + */ +/*----------------------------------------------------------------------------*/ +void rsnApStartSaQuery(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec) +{ + DBGLOG(RSN, INFO, "rsnApStartSaQuery\n"); + + if (prStaRec) { + cnmTimerStopTimer(prAdapter, + &prStaRec->rPmfCfg.rSAQueryTimer); + cnmTimerInitTimer(prAdapter, + &prStaRec->rPmfCfg.rSAQueryTimer, + (PFN_MGMT_TIMEOUT_FUNC)rsnApStartSaQueryTimer, + (unsigned long) prStaRec); + + if (prStaRec->rPmfCfg.u4SAQueryCount == 0) + rsnApStartSaQueryTimer(prAdapter, prStaRec, + (unsigned long)NULL); + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * + * \brief This routine is called to stop the 802.11w SA query. + * + * + * \note + * Called by: AAA module, stop TX SAQ if receive correct SAQ response + */ +/*----------------------------------------------------------------------------*/ +void rsnApStopSaQuery(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec) +{ + cnmTimerStopTimer(prAdapter, &prStaRec->rPmfCfg.rSAQueryTimer); + prStaRec->rPmfCfg.u2TransactionID = 0; + prStaRec->rPmfCfg.u4SAQueryCount = 0; + prStaRec->rPmfCfg.ucSAQueryTimedOut = 0; +} + +/*----------------------------------------------------------------------------*/ +/*! + * + * \brief This routine is called to process the 802.11w sa query action frame. + * + * + * \note + * Called by: AAA module, Handle Rx action request + */ +/*----------------------------------------------------------------------------*/ +void rsnApSaQueryRequest(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb) +{ + struct BSS_INFO *prBssInfo; + struct MSDU_INFO *prMsduInfo; + struct ACTION_SA_QUERY_FRAME *prRxFrame = NULL; + uint16_t u2PayloadLen; + struct STA_RECORD *prStaRec; + struct ACTION_SA_QUERY_FRAME *prTxFrame; + + if (!prSwRfb) + return; + + prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); + if (!prStaRec) /* Todo:: for not AIS check */ + return; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex); + prRxFrame = (struct ACTION_SA_QUERY_FRAME *) + prSwRfb->pvHeader; + if (!prRxFrame) + return; + + DBGLOG(RSN, INFO, + "IEEE 802.11: AP Received SA Query Request from " MACSTR + "\n", MAC2STR(prStaRec->aucMacAddr)); + + DBGLOG_MEM8(RSN, INFO, prRxFrame->ucTransId, ACTION_SA_QUERY_TR_ID_LEN); + + if (!rsnCheckBipKeyInstalled(prAdapter, prStaRec)) { + DBGLOG(RSN, INFO, + "IEEE 802.11: AP Ignore SA Query Request non-PMF STA " + MACSTR "\n", MAC2STR(prStaRec->aucMacAddr)); + return; + } + + DBGLOG(RSN, INFO, + "IEEE 802.11: Sending SA Query Response to " MACSTR "\n", + MAC2STR(prStaRec->aucMacAddr)); + + prMsduInfo = (struct MSDU_INFO *)cnmMgtPktAlloc(prAdapter, + MAC_TX_RESERVED_FIELD + + PUBLIC_ACTION_MAX_LEN); + + if (!prMsduInfo) + return; + + /* drop cipher mismatch */ + if (rsnCheckBipKeyInstalled(prAdapter, prStaRec)) { + if (prSwRfb->fgIsCipherMS || + prSwRfb->fgIsCipherLenMS) { + /* if cipher mismatch, or incorrect encrypt, + * just drop + */ + DBGLOG(RSN, ERROR, "drop SAQ req CM/CLM=1\n"); + return; + } + } + + prTxFrame = (struct ACTION_SA_QUERY_FRAME *) + ((unsigned long)(prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); + + prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; + if (rsnCheckBipKeyInstalled(prAdapter, prStaRec)) { + prTxFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME; + DBGLOG(RSN, INFO, "AP SAQ resp set FC PF bit\n"); + } + COPY_MAC_ADDR(prTxFrame->aucDestAddr, prStaRec->aucMacAddr); + COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucBSSID); + COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); + + prTxFrame->ucCategory = CATEGORY_SA_QUERY_ACTION; + prTxFrame->ucAction = ACTION_SA_QUERY_RESPONSE; + + kalMemCopy(prTxFrame->ucTransId, prRxFrame->ucTransId, + ACTION_SA_QUERY_TR_ID_LEN); + + u2PayloadLen = 2 + ACTION_SA_QUERY_TR_ID_LEN; + + /* 4 <3> Update information of MSDU_INFO_T */ + TX_SET_MMPDU(prAdapter, + prMsduInfo, + prStaRec->ucBssIndex, + prStaRec->ucIndex, + WLAN_MAC_MGMT_HEADER_LEN, + WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen, NULL, + MSDU_RATE_MODE_AUTO); + + /* 4 Enqueue the frame to send this action frame. */ + nicTxEnqueueMsdu(prAdapter, prMsduInfo); + +} + +/*----------------------------------------------------------------------------*/ +/*! + * + * \brief This routine is called to process the 802.11w sa query action frame. + * + * + * \note + * Called by: AAA module, Handle Rx action request + */ +/*----------------------------------------------------------------------------*/ +void rsnApSaQueryAction(IN struct ADAPTER *prAdapter, IN struct SW_RFB *prSwRfb) +{ + struct ACTION_SA_QUERY_FRAME *prRxFrame; + struct STA_RECORD *prStaRec; + uint16_t u2SwapTrID; + + prRxFrame = (struct ACTION_SA_QUERY_FRAME *) + prSwRfb->pvHeader; + prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); + + if (prStaRec == NULL) { + DBGLOG(RSN, INFO, "rsnApSaQueryAction: prStaRec is NULL"); + return; + } + + DBGLOG(RSN, TRACE, + "AP PMF SAQ action enter from " MACSTR "\n", + MAC2STR(prStaRec->aucMacAddr)); + if (prSwRfb->u2PacketLen < ACTION_SA_QUERY_TR_ID_LEN) { + DBGLOG(RSN, INFO, + "IEEE 802.11: Too short SA Query Action frame (len=%lu)\n", + (unsigned long)prSwRfb->u2PacketLen); + return; + } + + if (prRxFrame->ucAction == ACTION_SA_QUERY_REQUEST) { + rsnApSaQueryRequest(prAdapter, prSwRfb); + return; + } + + if (prRxFrame->ucAction != ACTION_SA_QUERY_RESPONSE) { + DBGLOG(RSN, INFO, + "IEEE 802.11: Unexpected SA Query Action %d\n", + prRxFrame->ucAction); + return; + } + + DBGLOG(RSN, INFO, + "IEEE 802.11: Received SA Query Response from " MACSTR "\n", + MAC2STR(prStaRec->aucMacAddr)); + + DBGLOG_MEM8(RSN, INFO, prRxFrame->ucTransId, ACTION_SA_QUERY_TR_ID_LEN); + + /* MLME-SAQuery.confirm */ + /* transform to network byte order */ + u2SwapTrID = htons(prStaRec->rPmfCfg.u2TransactionID); + if (kalMemCmp((uint8_t *) &u2SwapTrID, prRxFrame->ucTransId, + ACTION_SA_QUERY_TR_ID_LEN) == 0) { + DBGLOG(RSN, INFO, "AP Reply to SA Query received\n"); + rsnApStopSaQuery(prAdapter, prStaRec); + } else { + DBGLOG(RSN, INFO, + "IEEE 802.11: AP No matching SA Query transaction identifier found\n"); + } + +} + +#endif /* CFG_SUPPORT_802_11W */ + +#if CFG_SUPPORT_PASSPOINT +u_int8_t rsnParseOsenIE(struct ADAPTER *prAdapter, + struct IE_WFA_OSEN *prInfoElem, + struct RSN_INFO *prOsenInfo) +{ + uint32_t i; + int32_t u4RemainRsnIeLen; + uint16_t u2Version = 0; + uint16_t u2Cap = 0; + uint32_t u4GroupSuite = RSN_CIPHER_SUITE_CCMP; + uint16_t u2PairSuiteCount = 0; + uint16_t u2AuthSuiteCount = 0; + uint8_t *pucPairSuite = NULL; + uint8_t *pucAuthSuite = NULL; + uint8_t *cp; + + cp = ((uint8_t *) prInfoElem) + 6; + u4RemainRsnIeLen = (int32_t) prInfoElem->ucLength - 4; + do { + if (u4RemainRsnIeLen == 0) + break; + + /* Parse the Group Key Cipher Suite field. */ + if (u4RemainRsnIeLen < 4) { + DBGLOG(RSN, WARN, + "Fail to parse RSN IE in group cipher suite (IE len: %d)\n", + prInfoElem->ucLength); + return FALSE; + } + + WLAN_GET_FIELD_32(cp, &u4GroupSuite); + cp += 4; + u4RemainRsnIeLen -= 4; + + if (u4RemainRsnIeLen == 0) + break; + + /* Parse the Pairwise Key Cipher Suite Count field. */ + if (u4RemainRsnIeLen < 2) { + DBGLOG(RSN, WARN, + "Fail to parse RSN IE in pairwise cipher suite count (IE len: %d)\n", + prInfoElem->ucLength); + return FALSE; + } + + WLAN_GET_FIELD_16(cp, &u2PairSuiteCount); + cp += 2; + u4RemainRsnIeLen -= 2; + + /* Parse the Pairwise Key Cipher Suite List field. */ + i = (uint32_t) u2PairSuiteCount * 4; + if (u4RemainRsnIeLen < (int32_t) i) { + DBGLOG(RSN, WARN, + "Fail to parse RSN IE in pairwise cipher suite list (IE len: %d, Remain %u, Cnt %d GS %x)\n", + prInfoElem->ucLength, u4RemainRsnIeLen, + u2PairSuiteCount, u4GroupSuite); + return FALSE; + } + + pucPairSuite = cp; + + cp += i; + u4RemainRsnIeLen -= (int32_t) i; + + if (u4RemainRsnIeLen == 0) + break; + + /* Parse the Authentication and Key Management Cipher Suite + * Count field. + */ + if (u4RemainRsnIeLen < 2) { + DBGLOG(RSN, WARN, + "Fail to parse RSN IE in auth & key mgt suite count (IE len: %d)\n", + prInfoElem->ucLength); + return FALSE; + } + + WLAN_GET_FIELD_16(cp, &u2AuthSuiteCount); + cp += 2; + u4RemainRsnIeLen -= 2; + + /* Parse the Authentication and Key Management Cipher Suite + * List field. + */ + i = (uint32_t) u2AuthSuiteCount * 4; + if (u4RemainRsnIeLen < (int32_t) i) { + DBGLOG(RSN, WARN, + "Fail to parse RSN IE in auth & key mgt suite list (IE len: %d)\n", + prInfoElem->ucLength); + return FALSE; + } + + pucAuthSuite = cp; + + cp += i; + u4RemainRsnIeLen -= (int32_t) i; + + if (u4RemainRsnIeLen == 0) + break; + + /* Parse the RSN u2Capabilities field. */ + if (u4RemainRsnIeLen < 2) { + DBGLOG(RSN, WARN, + "Fail to parse RSN IE in RSN capabilities (IE len: %d)\n", + prInfoElem->ucLength); + return FALSE; + } + + WLAN_GET_FIELD_16(cp, &u2Cap); + } while (FALSE); + + /* Save the RSN information for the BSS. */ + prOsenInfo->ucElemId = ELEM_ID_VENDOR; + + prOsenInfo->u2Version = 0; + + prOsenInfo->u4GroupKeyCipherSuite = u4GroupSuite; + + DBGLOG(RSN, TRACE, + "RSN: version %d, group key cipher suite 0x%x\n", + u2Version, SWAP32(u4GroupSuite)); + + if (pucPairSuite) { + /* The information about the pairwise key cipher suites + * is present. + */ + if (u2PairSuiteCount > MAX_NUM_SUPPORTED_CIPHER_SUITES) + u2PairSuiteCount = MAX_NUM_SUPPORTED_CIPHER_SUITES; + + prOsenInfo->u4PairwiseKeyCipherSuiteCount = + (uint32_t) u2PairSuiteCount; + + for (i = 0; i < (uint32_t) u2PairSuiteCount; i++) { + WLAN_GET_FIELD_32(pucPairSuite, + &prOsenInfo->au4PairwiseKeyCipherSuite[i]); + pucPairSuite += 4; + + DBGLOG(RSN, TRACE, + "RSN: pairwise key cipher suite [%d]: 0x%x\n", i, + SWAP32(prOsenInfo->au4PairwiseKeyCipherSuite[i])); + } + } else { + /* The information about the pairwise key cipher suites + * is not present. Use the default chipher suite for RSN: CCMP + */ + + prOsenInfo->u4PairwiseKeyCipherSuiteCount = 1; + prOsenInfo->au4PairwiseKeyCipherSuite[0] = + RSN_CIPHER_SUITE_CCMP; + + DBGLOG(RSN, WARN, + "No Pairwise Cipher Suite found, using default (CCMP)\n"); + } + + if (pucAuthSuite) { + /* The information about the authentication + * and key management suites is present. + */ + + if (u2AuthSuiteCount > MAX_NUM_SUPPORTED_AKM_SUITES) + u2AuthSuiteCount = MAX_NUM_SUPPORTED_AKM_SUITES; + + prOsenInfo->u4AuthKeyMgtSuiteCount = (uint32_t) + u2AuthSuiteCount; + + for (i = 0; i < (uint32_t) u2AuthSuiteCount; i++) { + WLAN_GET_FIELD_32(pucAuthSuite, + &prOsenInfo->au4AuthKeyMgtSuite[i]); + pucAuthSuite += 4; + + DBGLOG(RSN, TRACE, "RSN: AKM suite [%d]: 0x%x\n", i + SWAP32(prOsenInfo->au4AuthKeyMgtSuite[i])); + } + } else { + /* The information about the authentication and + * key management suites is not present. + * Use the default AKM suite for RSN. + */ + prOsenInfo->u4AuthKeyMgtSuiteCount = 1; + prOsenInfo->au4AuthKeyMgtSuite[0] = RSN_AKM_SUITE_802_1X; + + DBGLOG(RSN, WARN, "No AKM found, using default (802.1X)\n"); + } + + prOsenInfo->u2RsnCap = u2Cap; +#if CFG_SUPPORT_802_11W + prOsenInfo->fgRsnCapPresent = TRUE; +#endif + DBGLOG(RSN, TRACE, "RSN cap: 0x%04x\n", prOsenInfo->u2RsnCap); + + return TRUE; +} +#endif /* CFG_SUPPORT_PASSPOINT */ + +uint32_t rsnCalculateFTIELen(struct ADAPTER *prAdapter, uint8_t ucBssIdx, + struct STA_RECORD *prStaRec) +{ + struct FT_IES *prFtIEs = aisGetFtIe(prAdapter, ucBssIdx); + + if (!prFtIEs->prFTIE || + !rsnIsFtOverTheAir(prAdapter, ucBssIdx, prStaRec->ucIndex)) + return 0; + return IE_SIZE(prFtIEs->prFTIE); +} + +void rsnGenerateFTIE(IN struct ADAPTER *prAdapter, + IN OUT struct MSDU_INFO *prMsduInfo) +{ + uint8_t *pucBuffer = + (uint8_t *)prMsduInfo->prPacket + prMsduInfo->u2FrameLength; + uint32_t ucFtIeSize = 0; + uint8_t ucBssIdx = prMsduInfo->ucBssIndex; + struct FT_IES *prFtIEs = aisGetFtIe(prAdapter, ucBssIdx); + + if (!prFtIEs->prFTIE || + !rsnIsFtOverTheAir(prAdapter, ucBssIdx, prMsduInfo->ucStaRecIndex)) + return; + ucFtIeSize = IE_SIZE(prFtIEs->prFTIE); + prMsduInfo->u2FrameLength += ucFtIeSize; + kalMemCopy(pucBuffer, prFtIEs->prFTIE, ucFtIeSize); +} + +u_int8_t rsnIsFtOverTheAir(IN struct ADAPTER *prAdapter, IN uint8_t ucBssIdx, + IN uint8_t ucStaRecIdx) +{ + struct STA_RECORD *prStaRec; + + prStaRec = cnmGetStaRecByIndex(prAdapter, ucStaRecIdx); + if (IS_BSS_INDEX_VALID(ucBssIdx) && + IS_BSS_AIS(GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIdx)) && + prStaRec && prStaRec->ucAuthAlgNum == + (uint8_t) AUTH_ALGORITHM_NUM_FAST_BSS_TRANSITION) + return TRUE; + + return FALSE; +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/saa_fsm.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/saa_fsm.c new file mode 100644 index 0000000000000000000000000000000000000000..e92aedd55dc1f4dc4719cc6490210362e97a685b --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/saa_fsm.c @@ -0,0 +1,2197 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/saa_fsm.c#2 + */ + +/*! \file "saa_fsm.c" + * \brief This file defines the FSM for SAA MODULE. + * + * This file defines the FSM for SAA MODULE. + */ + + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ +static uint8_t *apucDebugAAState[AA_STATE_NUM] = { + (uint8_t *) DISP_STRING("AA_IDLE"), + (uint8_t *) DISP_STRING("SAA_SEND_AUTH1"), + (uint8_t *) DISP_STRING("SAA_WAIT_AUTH2"), + (uint8_t *) DISP_STRING("SAA_SEND_AUTH3"), + (uint8_t *) DISP_STRING("SAA_WAIT_AUTH4"), + (uint8_t *) DISP_STRING("SAA_EXTERNAL_AUTH"), + (uint8_t *) DISP_STRING("SAA_SEND_ASSOC1"), + (uint8_t *) DISP_STRING("SAA_WAIT_ASSOC2"), + (uint8_t *) DISP_STRING("AAA_SEND_AUTH2"), + (uint8_t *) DISP_STRING("AAA_SEND_AUTH4"), + (uint8_t *) DISP_STRING("AAA_SEND_ASSOC2"), + (uint8_t *) DISP_STRING("AA_RESOURCE") +}; + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief The Core FSM engine of SAA Module. + * + * @param[in] prStaRec Pointer to the STA_RECORD_T + * @param[in] eNextState The value of Next State + * @param[in] prRetainedSwRfb Pointer to the retained SW_RFB_T for JOIN + * Success + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void +saaFsmSteps(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, IN enum ENUM_AA_STATE eNextState, + IN struct SW_RFB *prRetainedSwRfb) +{ + uint32_t rStatus = WLAN_STATUS_FAILURE; + enum ENUM_AA_STATE ePreviousState; + u_int8_t fgIsTransition; + + if (!prStaRec) + return; + + do { + + if (prStaRec->eAuthAssocState >= 0 + && prStaRec->eAuthAssocState < AA_STATE_NUM + && eNextState >= 0 + && eNextState < AA_STATE_NUM) { + DBGLOG(SAA, STATE, "[SAA]TRANSITION: [%s] -> [%s]\n", + apucDebugAAState[prStaRec->eAuthAssocState], + apucDebugAAState[eNextState]); + } + + ePreviousState = prStaRec->eAuthAssocState; + + /* NOTE(Kevin): This is the only place to change the + * eAuthAssocState(except initial) + */ + prStaRec->eAuthAssocState = eNextState; + + fgIsTransition = (u_int8_t) FALSE; + switch (prStaRec->eAuthAssocState) { + case AA_STATE_IDLE: + DBGLOG(SAA, TRACE, + "FT: authAlgNum %d, AuthTranNum %d\n", + prStaRec->ucAuthAlgNum, + prStaRec->ucAuthTranNum); + if (prStaRec->ucAuthAlgNum == + AUTH_ALGORITHM_NUM_FAST_BSS_TRANSITION && + prStaRec->ucAuthTranNum == + AUTH_TRANSACTION_SEQ_2 && + prStaRec->ucStaState == STA_STATE_1) { + struct PARAM_STATUS_INDICATION rStatus = { + .eStatusType = + ENUM_STATUS_TYPE_FT_AUTH_STATUS}; + struct cfg80211_ft_event_params *prFtEvent = + aisGetFtEventParam(prAdapter, + prStaRec->ucBssIndex); + + prFtEvent->target_ap = prStaRec->aucMacAddr; + /* now, we don't support RIC first */ + prFtEvent->ric_ies = NULL; + prFtEvent->ric_ies_len = 0; + DBGLOG(SAA, INFO, + "[%d] FT: notify supplicant to update FT IEs\n", + prStaRec->ucBssIndex); + kalIndicateStatusAndComplete( + prAdapter->prGlueInfo, + WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, + &rStatus, sizeof(rStatus), + prStaRec->ucBssIndex); + break; + /* wait supplicant update ft ies and then + * continue to send assoc 1 + */ + } + + /* Only trigger this event once */ + if (ePreviousState != prStaRec->eAuthAssocState) { + + if (prRetainedSwRfb) { + if (saaFsmSendEventJoinComplete( + prAdapter, + WLAN_STATUS_SUCCESS, + prStaRec, + prRetainedSwRfb) == + WLAN_STATUS_SUCCESS) { + /* ToDo:: Nothing */ + } else { + eNextState = AA_STATE_RESOURCE; + fgIsTransition = TRUE; + } + } else { + if (saaFsmSendEventJoinComplete( + prAdapter, + WLAN_STATUS_FAILURE, + prStaRec, NULL) == + WLAN_STATUS_RESOURCES) { + eNextState = AA_STATE_RESOURCE; + fgIsTransition = TRUE; + } + } + + } + + /* Free allocated TCM memory */ + if (prStaRec->prChallengeText) { + cnmMemFree(prAdapter, + prStaRec->prChallengeText); + prStaRec->prChallengeText = + (struct IE_CHALLENGE_TEXT *) NULL; + } + + break; + + case SAA_STATE_SEND_AUTH1: + + /* Do tasks in INIT STATE */ + if (prStaRec->ucTxAuthAssocRetryCount >= + prStaRec->ucTxAuthAssocRetryLimit) { + + /* Record the Status Code of Auth Request */ + prStaRec->u2StatusCode = + STATUS_CODE_AUTH_TIMEOUT; + + eNextState = AA_STATE_IDLE; + fgIsTransition = TRUE; + } else { + prStaRec->ucTxAuthAssocRetryCount++; + prStaRec->ucAuthTranNum = + AUTH_TRANSACTION_SEQ_1; + /* Update Station Record - Class 1 Flag */ + cnmStaRecChangeState(prAdapter, prStaRec, + STA_STATE_1); + +#if !CFG_SUPPORT_AAA + rStatus = authSendAuthFrame(prAdapter, prStaRec, + AUTH_TRANSACTION_SEQ_1); +#else + rStatus = authSendAuthFrame(prAdapter, + prStaRec, + prStaRec->ucBssIndex, + NULL, + AUTH_TRANSACTION_SEQ_1, + STATUS_CODE_RESERVED); +#endif /* CFG_SUPPORT_AAA */ + if (rStatus != WLAN_STATUS_SUCCESS) { + cnmTimerInitTimer(prAdapter, + &prStaRec->rTxReqDoneOrRxRespTimer, + (PFN_MGMT_TIMEOUT_FUNC) + saaFsmRunEventTxReqTimeOut, + (unsigned long) prStaRec); + + cnmTimerStartTimer(prAdapter, + &prStaRec->rTxReqDoneOrRxRespTimer, + TU_TO_MSEC( + TX_AUTHENTICATION_RETRY_TIMEOUT_TU)); + } + } + + break; + + case SAA_STATE_WAIT_AUTH2: + break; + + case SAA_STATE_SEND_AUTH3: + + /* Do tasks in INIT STATE */ + if (prStaRec->ucTxAuthAssocRetryCount >= + prStaRec->ucTxAuthAssocRetryLimit) { + + /* Record the Status Code of Auth Request */ + prStaRec->u2StatusCode = + STATUS_CODE_AUTH_TIMEOUT; + + eNextState = AA_STATE_IDLE; + fgIsTransition = TRUE; + } else { + prStaRec->ucTxAuthAssocRetryCount++; + prStaRec->ucAuthTranNum = + AUTH_TRANSACTION_SEQ_3; + +#if !CFG_SUPPORT_AAA + rStatus = authSendAuthFrame(prAdapter, + prStaRec, + AUTH_TRANSACTION_SEQ_3); +#else + rStatus = authSendAuthFrame(prAdapter, + prStaRec, + prStaRec->ucBssIndex, + NULL, + AUTH_TRANSACTION_SEQ_3, + STATUS_CODE_RESERVED); +#endif /* CFG_SUPPORT_AAA */ + if (rStatus != WLAN_STATUS_SUCCESS) { + cnmTimerInitTimer(prAdapter, + &prStaRec->rTxReqDoneOrRxRespTimer, + (PFN_MGMT_TIMEOUT_FUNC) + saaFsmRunEventTxReqTimeOut, + (unsigned long) prStaRec); + + cnmTimerStartTimer(prAdapter, + &prStaRec->rTxReqDoneOrRxRespTimer, + TU_TO_MSEC( + TX_AUTHENTICATION_RETRY_TIMEOUT_TU)); + } + } + + break; + + case SAA_STATE_WAIT_AUTH4: + break; + +#if CFG_SUPPORT_WPA3 + case SAA_STATE_EXTERNAL_AUTH: + kalExternalAuthRequest(prAdapter, prStaRec->ucBssIndex); + break; +#endif + + case SAA_STATE_SEND_ASSOC1: + /* Do tasks in INIT STATE */ + if (prStaRec->ucTxAuthAssocRetryCount >= + prStaRec->ucTxAuthAssocRetryLimit) { + + /* Record the Status Code of Auth Request */ + prStaRec->u2StatusCode = + STATUS_CODE_ASSOC_TIMEOUT; + + eNextState = AA_STATE_IDLE; + fgIsTransition = TRUE; + } else { + prStaRec->ucTxAuthAssocRetryCount++; + + rStatus = assocSendReAssocReqFrame(prAdapter, + prStaRec); + if (rStatus != WLAN_STATUS_SUCCESS) { + cnmTimerInitTimer(prAdapter, + &prStaRec->rTxReqDoneOrRxRespTimer, + (PFN_MGMT_TIMEOUT_FUNC) + saaFsmRunEventTxReqTimeOut, + (unsigned long) prStaRec); + + cnmTimerStartTimer(prAdapter, + &prStaRec->rTxReqDoneOrRxRespTimer, + TU_TO_MSEC( + TX_ASSOCIATION_RETRY_TIMEOUT_TU)); + } + } + + break; + + case SAA_STATE_WAIT_ASSOC2: + break; + + case AA_STATE_RESOURCE: + /* TODO(Kevin) Can setup a timer and send + * message later + */ + break; + + default: + DBGLOG(SAA, ERROR, "Unknown AA STATE\n"); + ASSERT(0); + break; + } + + } while (fgIsTransition); + + return; + +} /* end of saaFsmSteps() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will send Event to AIS/BOW/P2P + * + * @param[in] rJoinStatus To indicate JOIN success or failure. + * @param[in] prStaRec Pointer to the STA_RECORD_T + * @param[in] prSwRfb Pointer to the SW_RFB_T + + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +uint32_t +saaFsmSendEventJoinComplete(IN struct ADAPTER *prAdapter, + IN uint32_t rJoinStatus, + IN struct STA_RECORD *prStaRec, + IN struct SW_RFB *prSwRfb) +{ + struct BSS_INFO *prBssInfo; + + if (!prStaRec) { + DBGLOG(SAA, ERROR, "[%s]prStaRec is NULL\n", __func__); + return WLAN_STATUS_INVALID_PACKET; + } + if (!prAdapter) { + DBGLOG(SAA, ERROR, "[%s]prAdapter is NULL\n", __func__); + return WLAN_STATUS_INVALID_PACKET; + } + + /* Store limitation about 40Mhz bandwidth capability during + * association. + */ + if (prStaRec->ucBssIndex < prAdapter->ucHwBssIdNum) { + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prStaRec->ucBssIndex); + + if (prBssInfo != NULL) { + if (rJoinStatus == WLAN_STATUS_SUCCESS) + prBssInfo->fg40mBwAllowed = + prBssInfo->fgAssoc40mBwAllowed; + prBssInfo->fgAssoc40mBwAllowed = FALSE; + } + } + + /* For wlan0 (AP) + p2p0, don't check the prAisBssInfo for the P2P. */ +#if CFG_ENABLE_WIFI_DIRECT + if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) { + struct MSG_SAA_FSM_COMP *prSaaFsmCompMsg; + + prSaaFsmCompMsg = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, + sizeof(struct MSG_SAA_FSM_COMP)); + if (!prSaaFsmCompMsg) + return WLAN_STATUS_RESOURCES; + + if (rJoinStatus == WLAN_STATUS_SUCCESS) + prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL; + + prSaaFsmCompMsg->rMsgHdr.eMsgId = MID_SAA_P2P_JOIN_COMPLETE; + prSaaFsmCompMsg->ucSeqNum = prStaRec->ucAuthAssocReqSeqNum; + prSaaFsmCompMsg->rJoinStatus = rJoinStatus; + prSaaFsmCompMsg->prStaRec = prStaRec; + prSaaFsmCompMsg->prSwRfb = prSwRfb; + + /* NOTE(Kevin): Set to UNBUF for immediately JOIN complete */ + mboxSendMsg(prAdapter, MBOX_ID_0, + (struct MSG_HDR *) prSaaFsmCompMsg, + MSG_SEND_METHOD_UNBUF); + + return WLAN_STATUS_SUCCESS; + } +#endif /* CFG_ENABLE_WIFI_DIRECT */ + + if (IS_STA_IN_AIS(prStaRec)) { + struct MSG_SAA_FSM_COMP *prSaaFsmCompMsg; + + prSaaFsmCompMsg = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, + sizeof(struct MSG_SAA_FSM_COMP)); + if (!prSaaFsmCompMsg) + return WLAN_STATUS_RESOURCES; + + if (rJoinStatus == WLAN_STATUS_SUCCESS) + prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL; + + prSaaFsmCompMsg->rMsgHdr.eMsgId = MID_SAA_AIS_JOIN_COMPLETE; + prSaaFsmCompMsg->ucSeqNum = prStaRec->ucAuthAssocReqSeqNum; + prSaaFsmCompMsg->rJoinStatus = rJoinStatus; + prSaaFsmCompMsg->prStaRec = prStaRec; + prSaaFsmCompMsg->prSwRfb = prSwRfb; + + /* NOTE(Kevin): Set to UNBUF for immediately JOIN complete */ + mboxSendMsg(prAdapter, MBOX_ID_0, + (struct MSG_HDR *) prSaaFsmCompMsg, + MSG_SEND_METHOD_UNBUF); + + return WLAN_STATUS_SUCCESS; + } +#if CFG_ENABLE_BT_OVER_WIFI + else if (IS_STA_BOW_TYPE(prStaRec)) { + /* @TODO: BOW handler */ + + struct MSG_SAA_FSM_COMP *prSaaFsmCompMsg; + + prSaaFsmCompMsg = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, + sizeof(struct MSG_SAA_FSM_COMP)); + if (!prSaaFsmCompMsg) + return WLAN_STATUS_RESOURCES; + + prSaaFsmCompMsg->rMsgHdr.eMsgId = MID_SAA_BOW_JOIN_COMPLETE; + prSaaFsmCompMsg->ucSeqNum = prStaRec->ucAuthAssocReqSeqNum; + prSaaFsmCompMsg->rJoinStatus = rJoinStatus; + prSaaFsmCompMsg->prStaRec = prStaRec; + prSaaFsmCompMsg->prSwRfb = prSwRfb; + + /* NOTE(Kevin): Set to UNBUF for immediately JOIN complete */ + mboxSendMsg(prAdapter, MBOX_ID_0, + (struct MSG_HDR *) prSaaFsmCompMsg, + MSG_SEND_METHOD_UNBUF); + + return WLAN_STATUS_SUCCESS; + } +#endif + else { + DBGLOG(SAA, ERROR, "Invalid case in %s.\n", __func__); + return WLAN_STATUS_FAILURE; + } + +} /* end of saaFsmSendEventJoinComplete() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will handle the Start Event to SAA FSM. + * + * @param[in] prMsgHdr Message of Join Request for a particular STA. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void saaFsmRunEventStart(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct MSG_SAA_FSM_START *prSaaFsmStartMsg; + struct STA_RECORD *prStaRec; + struct BSS_INFO *prBssInfo; + + prSaaFsmStartMsg = (struct MSG_SAA_FSM_START *) prMsgHdr; + prStaRec = prSaaFsmStartMsg->prStaRec; + + if ((!prStaRec) || (prStaRec->fgIsInUse == FALSE)) { + cnmMemFree(prAdapter, prMsgHdr); + return; + } + + DBGLOG(SAA, LOUD, "EVENT-START: Trigger SAA FSM.\n"); + + /* record sequence number of request message */ + prStaRec->ucAuthAssocReqSeqNum = prSaaFsmStartMsg->ucSeqNum; + + cnmMemFree(prAdapter, prMsgHdr); + if (prStaRec->ucAuthAlgNum == AUTH_ALGORITHM_NUM_FAST_BSS_TRANSITION && + prStaRec->ucAuthTranNum == AUTH_TRANSACTION_SEQ_2) { + DBGLOG(SAA, ERROR, + "FT: current is waiting FT auth, don't reentry\n"); + return; + } + + /* 4 <1> Validation of SAA Start Event */ + if (!IS_AP_STA(prStaRec)) { + + DBGLOG(SAA, ERROR, + "EVENT-START: STA Type - %d was not supported.\n", + prStaRec->eStaType); + + /* Ignore the return value because don't care the prSwRfb */ + saaFsmSendEventJoinComplete(prAdapter, WLAN_STATUS_FAILURE, + prStaRec, NULL); + + return; + } + /* 4 <2> The previous JOIN process is not completed ? */ + if (prStaRec->eAuthAssocState != AA_STATE_IDLE) { + DBGLOG(SAA, ERROR, "EVENT-START: Reentry of SAA Module.\n"); + prStaRec->eAuthAssocState = AA_STATE_IDLE; + } + /* 4 <3> Reset Status Code and Time */ + /* Update Station Record - Status/Reason Code */ + prStaRec->u2StatusCode = STATUS_CODE_UNSPECIFIED_FAILURE; + + /* Update the record join time. */ + GET_CURRENT_SYSTIME(&prStaRec->rLastJoinTime); + + prStaRec->ucTxAuthAssocRetryCount = 0; + + if (prStaRec->prChallengeText) { + cnmMemFree(prAdapter, prStaRec->prChallengeText); + prStaRec->prChallengeText = (struct IE_CHALLENGE_TEXT *) NULL; + } + + cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); + + /* 4 <4> Init the sec fsm */ + /* secFsmInit(prAdapter, prStaRec); */ + + /* 4 <5> Reset the STA STATE */ + /* Update Station Record - Class 1 Flag */ + /* NOTE(Kevin): Moved to AIS FSM for Reconnect issue - + * We won't deactivate the same struct STA_RECORD and then activate it + * again for the case of reconnection. + */ + /* cnmStaRecChangeState(prStaRec, STA_STATE_1); */ + + /* 4 <6> Decide if this BSS 20/40M bandwidth is allowed */ + if (prStaRec->ucBssIndex < prAdapter->ucHwBssIdNum) { + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prStaRec->ucBssIndex); + + if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & + PHY_TYPE_SET_802_11N) && + (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)) { + prBssInfo->fgAssoc40mBwAllowed = + cnmBss40mBwPermitted(prAdapter, + prBssInfo->ucBssIndex); + } else { + prBssInfo->fgAssoc40mBwAllowed = FALSE; + } + DBGLOG(RLM, TRACE, "STA 40mAllowed=%d\n", + prBssInfo->fgAssoc40mBwAllowed); + } + /* 4 <7> Trigger SAA FSM */ + if (prStaRec->ucStaState == STA_STATE_1) { + if (prStaRec->ucAuthAlgNum == AUTH_ALGORITHM_NUM_SAE) + saaFsmSteps(prAdapter, prStaRec, + SAA_STATE_EXTERNAL_AUTH, + (struct SW_RFB *) NULL); + else + saaFsmSteps(prAdapter, prStaRec, SAA_STATE_SEND_AUTH1, + (struct SW_RFB *) NULL); + } else if (prStaRec->ucStaState == STA_STATE_2 || + prStaRec->ucStaState == STA_STATE_3) + saaFsmSteps(prAdapter, prStaRec, + SAA_STATE_SEND_ASSOC1, (struct SW_RFB *) NULL); +} /* end of saaFsmRunEventStart() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will handle the Continue Event to SAA FSM. + * + * @param[in] prMsgHdr Message of Join Request for a particular STA. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void saaFsmRunEventFTContinue(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct MSG_SAA_FT_CONTINUE *prSaaFsmMsg = NULL; + struct STA_RECORD *prStaRec; + u_int8_t fgFtRicRequest = FALSE; + + prSaaFsmMsg = (struct MSG_SAA_FT_CONTINUE *)prMsgHdr; + prStaRec = prSaaFsmMsg->prStaRec; + fgFtRicRequest = prSaaFsmMsg->fgFTRicRequest; + cnmMemFree(prAdapter, prMsgHdr); + if ((!prStaRec) || (prStaRec->fgIsInUse == FALSE)) { + DBGLOG(SAA, ERROR, "No Sta Record or it is not in use\n"); + return; + } + if (prStaRec->eAuthAssocState != AA_STATE_IDLE) { + DBGLOG(SAA, ERROR, + "FT: Wrong SAA FSM state %d to continue auth/assoc\n", + prStaRec->eAuthAssocState); + return; + } + DBGLOG(SAA, TRACE, "Continue to do auth/assoc\n"); + if (fgFtRicRequest) + saaFsmSteps(prAdapter, prStaRec, SAA_STATE_SEND_AUTH3, + (struct SW_RFB *)NULL); + else { + cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); + saaFsmSteps(prAdapter, prStaRec, SAA_STATE_SEND_ASSOC1, + (struct SW_RFB *)NULL); + } +} /* end of saaFsmRunEventFTContinue() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will handle TxDone(Auth1/Auth3/AssocReq) Event of SAA + * FSM. + * + * @param[in] prMsduInfo Pointer to the MSDU_INFO_T. + * @param[in] rTxDoneStatus Return TX status of the Auth1/Auth3/AssocReq frame. + * + * @retval WLAN_STATUS_SUCCESS + */ +/*----------------------------------------------------------------------------*/ +uint32_t +saaFsmRunEventTxDone(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN enum ENUM_TX_RESULT_CODE rTxDoneStatus) +{ + + struct STA_RECORD *prStaRec; + enum ENUM_AA_STATE eNextState; + + prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); + + if (!prStaRec) + return WLAN_STATUS_INVALID_PACKET; + + if (rTxDoneStatus) + DBGLOG(SAA, INFO, + "EVENT-TX DONE [status: %d][seq: %d]: Current Time = %d\n", + rTxDoneStatus, prMsduInfo->ucTxSeqNum, kalGetTimeTick()); + + /* Trigger statistics log if Auth/Assoc Tx failed */ + if (rTxDoneStatus != TX_RESULT_SUCCESS) + wlanTriggerStatsLog(prAdapter, + prAdapter->rWifiVar.u4StatsLogDuration); + + eNextState = prStaRec->eAuthAssocState; + + switch (prStaRec->eAuthAssocState) { + case SAA_STATE_SEND_AUTH1: + { + /* Strictly check the outgoing frame is matched with + * current AA STATE + */ + if (authCheckTxAuthFrame(prAdapter, prMsduInfo, + AUTH_TRANSACTION_SEQ_1) != + WLAN_STATUS_SUCCESS) + break; + + if (rTxDoneStatus == TX_RESULT_SUCCESS) { + eNextState = SAA_STATE_WAIT_AUTH2; + + cnmTimerStopTimer(prAdapter, + &prStaRec->rTxReqDoneOrRxRespTimer); + + cnmTimerInitTimer(prAdapter, + &prStaRec->rTxReqDoneOrRxRespTimer, + (PFN_MGMT_TIMEOUT_FUNC) + saaFsmRunEventRxRespTimeOut, + (unsigned long) prStaRec); + + cnmTimerStartTimer(prAdapter, + &prStaRec->rTxReqDoneOrRxRespTimer, + TU_TO_MSEC( + DOT11_AUTHENTICATION_RESPONSE_TIMEOUT_TU)); + } + + /* if TX was successful, change to next state. + * if TX was failed, do retry if possible. + */ + saaFsmSteps(prAdapter, prStaRec, eNextState, + (struct SW_RFB *) NULL); + } + break; + + case SAA_STATE_SEND_AUTH3: + { + /* Strictly check the outgoing frame is matched with + * current JOIN STATE + */ + if (authCheckTxAuthFrame(prAdapter, prMsduInfo, + AUTH_TRANSACTION_SEQ_3) != + WLAN_STATUS_SUCCESS) + break; + + if (rTxDoneStatus == TX_RESULT_SUCCESS) { + eNextState = SAA_STATE_WAIT_AUTH4; + + cnmTimerStopTimer(prAdapter, + &prStaRec->rTxReqDoneOrRxRespTimer); + + cnmTimerInitTimer(prAdapter, + &prStaRec->rTxReqDoneOrRxRespTimer, + (PFN_MGMT_TIMEOUT_FUNC) + saaFsmRunEventRxRespTimeOut, + (unsigned long) prStaRec); + + cnmTimerStartTimer(prAdapter, + &prStaRec->rTxReqDoneOrRxRespTimer, + TU_TO_MSEC( + DOT11_AUTHENTICATION_RESPONSE_TIMEOUT_TU)); + } + + /* if TX was successful, change to next state. + * if TX was failed, do retry if possible. + */ + saaFsmSteps(prAdapter, prStaRec, eNextState, + (struct SW_RFB *) NULL); + } + break; + + case SAA_STATE_SEND_ASSOC1: + { + /* Strictly check the outgoing frame is matched with + * current SAA STATE + */ + if (assocCheckTxReAssocReqFrame(prAdapter, prMsduInfo) + != WLAN_STATUS_SUCCESS) + break; + + if (rTxDoneStatus == TX_RESULT_SUCCESS) { + eNextState = SAA_STATE_WAIT_ASSOC2; + + cnmTimerStopTimer(prAdapter, + &prStaRec-> + rTxReqDoneOrRxRespTimer); + + cnmTimerInitTimer(prAdapter, + &prStaRec->rTxReqDoneOrRxRespTimer, + (PFN_MGMT_TIMEOUT_FUNC) + saaFsmRunEventRxRespTimeOut, + (unsigned long) prStaRec); + + cnmTimerStartTimer(prAdapter, + &(prStaRec->rTxReqDoneOrRxRespTimer), + TU_TO_MSEC( + DOT11_ASSOCIATION_RESPONSE_TIMEOUT_TU)); + } + + /* if TX was successful, change to next state. + * if TX was failed, do retry if possible. + */ + saaFsmSteps(prAdapter, prStaRec, eNextState, + (struct SW_RFB *) NULL); + } + break; + + default: + break; /* Ignore other cases */ + } + + return WLAN_STATUS_SUCCESS; + +} /* end of saaFsmRunEventTxDone() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will send Tx Request Timeout Event to SAA FSM. + * + * @param[in] prStaRec Pointer to the STA_RECORD_T + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void saaFsmRunEventTxReqTimeOut(IN struct ADAPTER *prAdapter, + IN unsigned long plParamPtr) +{ + struct STA_RECORD *prStaRec = (struct STA_RECORD *) plParamPtr; + + if (!prStaRec) + return; + + DBGLOG(SAA, LOUD, "EVENT-TIMER: TX REQ TIMEOUT, Current Time = %d\n", + kalGetTimeTick()); + + /* Trigger statistics log if Auth/Assoc Tx timeout */ + wlanTriggerStatsLog(prAdapter, prAdapter->rWifiVar.u4StatsLogDuration); + + switch (prStaRec->eAuthAssocState) { + case SAA_STATE_SEND_AUTH1: + case SAA_STATE_SEND_AUTH3: + case SAA_STATE_SEND_ASSOC1: + saaFsmSteps(prAdapter, prStaRec, + prStaRec->eAuthAssocState, (struct SW_RFB *) NULL); + break; + + default: + return; + } +} /* end of saaFsmRunEventTxReqTimeOut() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will send Rx Response Timeout Event to SAA FSM. + * + * @param[in] prStaRec Pointer to the STA_RECORD_T + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void saaFsmRunEventRxRespTimeOut(IN struct ADAPTER *prAdapter, + IN unsigned long ulParamPtr) +{ + struct STA_RECORD *prStaRec = (struct STA_RECORD *) ulParamPtr; + enum ENUM_AA_STATE eNextState; + + DBGLOG(SAA, LOUD, "EVENT-TIMER: RX RESP TIMEOUT, Current Time = %d\n", + kalGetTimeTick()); + + if (!prStaRec) + return; + + eNextState = prStaRec->eAuthAssocState; + + switch (prStaRec->eAuthAssocState) { + case SAA_STATE_WAIT_AUTH2: + /* Record the Status Code of Authentication Request */ + prStaRec->u2StatusCode = STATUS_CODE_AUTH_TIMEOUT; + + /* Pull back to earlier state to do retry */ + eNextState = SAA_STATE_SEND_AUTH1; + break; + + case SAA_STATE_WAIT_AUTH4: + /* Record the Status Code of Authentication Request */ + prStaRec->u2StatusCode = STATUS_CODE_AUTH_TIMEOUT; + + /* Pull back to earlier state to do retry */ + eNextState = SAA_STATE_SEND_AUTH3; + break; + + case SAA_STATE_WAIT_ASSOC2: + /* Record the Status Code of Authentication Request */ + prStaRec->u2StatusCode = STATUS_CODE_ASSOC_TIMEOUT; + + /* Pull back to earlier state to do retry */ + eNextState = SAA_STATE_SEND_ASSOC1; + break; + + default: + break; /* Ignore other cases */ + } + + if (eNextState != prStaRec->eAuthAssocState) + saaFsmSteps(prAdapter, prStaRec, eNextState, + (struct SW_RFB *) NULL); +} /* end of saaFsmRunEventRxRespTimeOut() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will process the Rx Auth Response Frame and then + * trigger SAA FSM. + * + * @param[in] prSwRfb Pointer to the SW_RFB_T structure. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void saaFsmRunEventRxAuth(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb) +{ + struct STA_RECORD *prStaRec; + uint16_t u2StatusCode; + enum ENUM_AA_STATE eNextState; + uint8_t ucWlanIdx; + + prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); + ucWlanIdx = prSwRfb->ucWlanIdx; + + /* We should have the corresponding Sta Record. */ + if (!prStaRec) { + DBGLOG(SAA, WARN, + "Received a AuthResp: wlanIdx[%d] w/o corresponding staRec\n", + ucWlanIdx); + return; + } + + if (!IS_AP_STA(prStaRec)) + return; + + switch (prStaRec->eAuthAssocState) { + case SAA_STATE_SEND_AUTH1: + case SAA_STATE_WAIT_AUTH2: + /* Check if the incoming frame is what we are waiting for */ + if (authCheckRxAuthFrameStatus(prAdapter, + prSwRfb, + AUTH_TRANSACTION_SEQ_2, + &u2StatusCode) == + WLAN_STATUS_SUCCESS) { + + cnmTimerStopTimer(prAdapter, + &prStaRec->rTxReqDoneOrRxRespTimer); + + /* Record the Status Code of Authentication Request */ + prStaRec->u2StatusCode = u2StatusCode; + + if (u2StatusCode == STATUS_CODE_SUCCESSFUL) { + + authProcessRxAuth2_Auth4Frame(prAdapter, + prSwRfb); + + prStaRec->ucAuthTranNum = + AUTH_TRANSACTION_SEQ_2; + /* after received Auth2 for FT, should indicate + * to supplicant + * and wait response from supplicant + */ + if (prStaRec->ucAuthAlgNum == + AUTH_ALGORITHM_NUM_FAST_BSS_TRANSITION) + eNextState = AA_STATE_IDLE; + else if ( + prStaRec->ucAuthAlgNum == + (uint8_t) + AUTH_ALGORITHM_NUM_SHARED_KEY) { + + eNextState = SAA_STATE_SEND_AUTH3; + } else { + /* Update Station Record - Class 2 */ + cnmStaRecChangeState(prAdapter, + prStaRec, + STA_STATE_2); + + eNextState = SAA_STATE_SEND_ASSOC1; + } + } else { + DBGLOG(SAA, INFO, + "Auth Req was rejected by [" MACSTR + "], Status Code = %d\n", + MAC2STR(prStaRec->aucMacAddr), + u2StatusCode); + + eNextState = AA_STATE_IDLE; + } + + /* Reset Send Auth/(Re)Assoc Frame Count */ + prStaRec->ucTxAuthAssocRetryCount = 0; + + saaFsmSteps(prAdapter, prStaRec, eNextState, + (struct SW_RFB *) NULL); + } + break; + + case SAA_STATE_SEND_AUTH3: + case SAA_STATE_WAIT_AUTH4: + /* Check if the incoming frame is what we are waiting for */ + if (authCheckRxAuthFrameStatus(prAdapter, + prSwRfb, + AUTH_TRANSACTION_SEQ_4, + &u2StatusCode) == + WLAN_STATUS_SUCCESS) { + + cnmTimerStopTimer(prAdapter, + &prStaRec->rTxReqDoneOrRxRespTimer); + + /* Record the Status Code of Authentication Request */ + prStaRec->u2StatusCode = u2StatusCode; + + if (u2StatusCode == STATUS_CODE_SUCCESSFUL) { + + /* Add for 802.11r handling */ + uint32_t rStatus = + authProcessRxAuth2_Auth4Frame(prAdapter, + prSwRfb); + + prStaRec->ucAuthTranNum = + AUTH_TRANSACTION_SEQ_4; + /* if Auth4 check is failed(check mic in Auth + * ack frame), should disconnect + */ + if (prStaRec->ucAuthAlgNum == + AUTH_ALGORITHM_NUM_FAST_BSS_TRANSITION && + rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(SAA, INFO, + "Rx Auth4 fail [" MACSTR + "], status %d, maybe MIC error\n", + MAC2STR(prStaRec->aucMacAddr), + u2StatusCode); + /* Reset Send Auth/(Re)Assoc Frame Count + */ + prStaRec->ucTxAuthAssocRetryCount = 0; + saaFsmSteps(prAdapter, prStaRec, + AA_STATE_IDLE, + (struct SW_RFB *)NULL); + break; + } + + /* Update Station Record - Class 2 Flag */ + cnmStaRecChangeState(prAdapter, + prStaRec, STA_STATE_2); + + eNextState = SAA_STATE_SEND_ASSOC1; + } else { + DBGLOG(SAA, INFO, + "Auth Req was rejected by [" MACSTR + "], Status Code = %d\n", + MAC2STR(prStaRec->aucMacAddr), + u2StatusCode); + + eNextState = AA_STATE_IDLE; + } + + /* Reset Send Auth/(Re)Assoc Frame Count */ + prStaRec->ucTxAuthAssocRetryCount = 0; + + saaFsmSteps(prAdapter, prStaRec, + eNextState, (struct SW_RFB *) NULL); + } + break; + + case SAA_STATE_EXTERNAL_AUTH: + if (authCheckRxAuthFrameStatus(prAdapter, + prSwRfb, + AUTH_TRANSACTION_SEQ_2, + &u2StatusCode) == + WLAN_STATUS_SUCCESS) { + /* Record join fail status code only*/ + if (u2StatusCode != STATUS_CODE_SUCCESSFUL) { + DBGLOG(SAA, INFO, + "Auth Req was rejected by [" MACSTR + "], Status Code = %d\n", + MAC2STR(prStaRec->aucMacAddr), + u2StatusCode); + prStaRec->u2StatusCode = u2StatusCode; + } + } + kalIndicateRxMgmtFrame(prAdapter->prGlueInfo, prSwRfb, + prStaRec->ucBssIndex); + break; + + default: + break; /* Ignore other cases */ + } +} /* end of saaFsmRunEventRxAuth() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will process the Rx (Re)Association Response Frame and + * then trigger SAA FSM. + * + * @param[in] prSwRfb Pointer to the SW_RFB_T structure. + * + * @retval WLAN_STATUS_SUCCESS if the status code was not success + * @retval WLAN_STATUS_BUFFER_RETAINED if the status code was success + */ +/*----------------------------------------------------------------------------*/ +uint32_t saaFsmRunEventRxAssoc(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb) +{ + struct STA_RECORD *prStaRec; + uint16_t u2StatusCode; + enum ENUM_AA_STATE eNextState; + struct SW_RFB *prRetainedSwRfb = (struct SW_RFB *) NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint8_t ucWlanIdx; + struct WLAN_MAC_MGMT_HEADER *prWlanMgmtHdr; + + prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); + ucWlanIdx = prSwRfb->ucWlanIdx; + + /* We should have the corresponding Sta Record. */ + if (!prStaRec) { + /* ASSERT(0); */ + DBGLOG(SAA, WARN, + "Received a AssocResp: wlanIdx[%d] w/o corresponding staRec\n", + ucWlanIdx); + return rStatus; + } + + if (!IS_AP_STA(prStaRec)) + return rStatus; + + switch (prStaRec->eAuthAssocState) { + case SAA_STATE_SEND_ASSOC1: + case SAA_STATE_WAIT_ASSOC2: + /* TRUE if the incoming frame is what we are waiting for */ + if (assocCheckRxReAssocRspFrameStatus(prAdapter, + prSwRfb, &u2StatusCode) == WLAN_STATUS_SUCCESS) { + + cnmTimerStopTimer(prAdapter, + &prStaRec->rTxReqDoneOrRxRespTimer); + + /* Record the Status Code of Authentication Request */ + prStaRec->u2StatusCode = u2StatusCode; + + if (u2StatusCode == STATUS_CODE_SUCCESSFUL) { + + /* Update Station Record - Class 3 Flag */ + /* NOTE(Kevin): Moved to AIS FSM for roaming + * issue - We should deactivate the struct + * STA_RECORD of previous AP before activate + * new one in Driver. + */ + /* cnmStaRecChangeState(prStaRec, + * STA_STATE_3); + */ + + /* Clear history. */ + prStaRec->ucJoinFailureCount = 0; + + prRetainedSwRfb = prSwRfb; + rStatus = WLAN_STATUS_PENDING; + } else { + cnmStaRecChangeState(prAdapter, prStaRec, + STA_STATE_1); + DBGLOG(SAA, INFO, + "Assoc Req was rejected by [" MACSTR + "], Status Code = %d\n", + MAC2STR(prStaRec->aucMacAddr), + u2StatusCode); + } + /* Assoc Resp's BSSID doesn't match target, ignore */ + prWlanMgmtHdr = (struct WLAN_MAC_MGMT_HEADER *) + (prSwRfb->pvHeader); + if (!EQUAL_MAC_ADDR(prWlanMgmtHdr->aucBSSID, + prStaRec->aucMacAddr)) { + DBGLOG(SAA, ERROR, "Unknown BSSID\n"); + rStatus = WLAN_STATUS_FAILURE; + prRetainedSwRfb = NULL; + } + + /* Reset Send Auth/(Re)Assoc Frame Count */ + prStaRec->ucTxAuthAssocRetryCount = 0; + + /* update RCPI */ + ASSERT(prSwRfb->prRxStatusGroup3); + prStaRec->ucRCPI = + nicRxGetRcpiValueFromRxv( + prAdapter, RCPI_MODE_MAX, prSwRfb); + + eNextState = AA_STATE_IDLE; + + saaFsmSteps(prAdapter, prStaRec, + eNextState, prRetainedSwRfb); + } + break; + + default: + break; /* Ignore other cases */ + } + + return rStatus; + +} /* end of saaFsmRunEventRxAssoc() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will check the incoming Deauth Frame. + * + * @param[in] prSwRfb Pointer to the SW_RFB_T structure. + * + * @retval WLAN_STATUS_SUCCESS Always not retain deauthentication frames + */ +/*----------------------------------------------------------------------------*/ +uint32_t saaFsmRunEventRxDeauth(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb) +{ + struct STA_RECORD *prStaRec; + struct WLAN_DEAUTH_FRAME *prDeauthFrame; + uint8_t ucWlanIdx; + + prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); + prDeauthFrame = (struct WLAN_DEAUTH_FRAME *) prSwRfb->pvHeader; + ucWlanIdx = prSwRfb->ucWlanIdx; + + DBGLOG(SAA, INFO, "Rx Deauth frame ,DA[" MACSTR "] SA[" MACSTR + "] BSSID[" MACSTR "] ReasonCode[0x%x]\n", + MAC2STR(prDeauthFrame->aucDestAddr), + MAC2STR(prDeauthFrame->aucSrcAddr), + MAC2STR(prDeauthFrame->aucBSSID), prDeauthFrame->u2ReasonCode); + + do { + + /* We should have the corresponding Sta Record. */ + if (!prStaRec) { + DBGLOG(SAA, WARN, + "Received a Deauth: wlanIdx[%d] w/o corresponding staRec\n", + ucWlanIdx); + break; + } + + if (IS_STA_IN_AIS(prStaRec)) { + struct BSS_INFO *prAisBssInfo; + uint8_t ucBssIndex = 0; + + if (!IS_AP_STA(prStaRec)) + break; + + ucBssIndex = prStaRec->ucBssIndex; + + prAisBssInfo = aisGetAisBssInfo(prAdapter, + ucBssIndex); + + /* if state != CONNECTED, don't do disconnect again */ + if (kalGetMediaStateIndicated(prAdapter->prGlueInfo, + ucBssIndex) != + MEDIA_STATE_CONNECTED) + break; + + if (prStaRec->ucStaState > STA_STATE_1) { + + /* Check if this is the AP we are associated + * or associating with + */ + if (authProcessRxDeauthFrame(prSwRfb, + prStaRec->aucMacAddr, + &prStaRec->u2ReasonCode) + == WLAN_STATUS_SUCCESS) { + +#if CFG_SUPPORT_802_11W + struct AIS_SPECIFIC_BSS_INFO + *prAisSpecBssInfo; + + prAisSpecBssInfo = + aisGetAisSpecBssInfo(prAdapter, + ucBssIndex); + + DBGLOG(RSN, INFO, + "QM RX MGT: Deauth frame, P=%d Sec=%d CM=%d BC=%d fc=%02x\n", + prAisSpecBssInfo-> + fgMgmtProtection, (uint8_t) + prSwRfb->ucSecMode, + prSwRfb->fgIsCipherMS, + IS_BMCAST_MAC_ADDR + (prDeauthFrame->aucDestAddr), + prDeauthFrame->u2FrameCtrl); + if (prAisSpecBssInfo->fgMgmtProtection + && prSwRfb->fgIsCipherMS + /* HAL_RX_STATUS_GET_SEC_MODE + * (prSwRfb->prRxStatus) != + * CIPHER_SUITE_BIP + */ + ) { + saaChkDeauthfrmParamHandler( + prAdapter, prSwRfb, + prStaRec); + return WLAN_STATUS_SUCCESS; + } +#endif + saaSendDisconnectMsgHandler(prAdapter, + prStaRec, + prAisBssInfo, + FRM_DEAUTH); + } + } + } +#if CFG_ENABLE_WIFI_DIRECT + else if (prAdapter->fgIsP2PRegistered && + IS_STA_IN_P2P(prStaRec)) { + /* TODO(Kevin) */ + p2pRoleFsmRunEventRxDeauthentication(prAdapter, + prStaRec, + prSwRfb); + } +#endif +#if CFG_ENABLE_BT_OVER_WIFI + else if (IS_STA_BOW_TYPE(prStaRec)) + bowRunEventRxDeAuth(prAdapter, prStaRec, prSwRfb); +#endif + else + ASSERT(0); + + } while (FALSE); + + return WLAN_STATUS_SUCCESS; + +} /* end of saaFsmRunEventRxDeauth() */ + +/* for AOSP */ +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will check param of deauth frame and reson code for + * deauth. + * + * @param[in] + * + * @retval + */ +/*----------------------------------------------------------------------------*/ + +void saaChkDeauthfrmParamHandler(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, + IN struct STA_RECORD *prStaRec) +{ + struct WLAN_DEAUTH_FRAME *prDeauthFrame; + + do { + prDeauthFrame = (struct WLAN_DEAUTH_FRAME *) prSwRfb->pvHeader; + if (!IS_BMCAST_MAC_ADDR(prDeauthFrame->aucDestAddr)) { + DBGLOG(RSN, INFO, + "[%d] QM RX MGT: rsnStartSaQuery\n", + prStaRec->ucBssIndex); + /* MFP test plan 5.3.3.5 */ + rsnStartSaQuery(prAdapter, prStaRec->ucBssIndex); + } else { + DBGLOG(RSN, INFO, "RXM: Drop unprotected Mgmt frame\n"); + DBGLOG(RSN, INFO, + "RXM:(MACRX Done)RX(ucSecMode=0x%x)(ucWlanIdx=0x%x)\n", + prSwRfb->ucSecMode, prSwRfb->ucWlanIdx); + } + } while (0); +} + +/* for AOSP */ +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will check and send disconnect message to AIS module + * + * @param[in] + * + * @retval + */ +/*----------------------------------------------------------------------------*/ +void +saaSendDisconnectMsgHandler(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, + IN struct BSS_INFO *prAisBssInfo, + IN enum ENUM_AA_FRM_TYPE eFrmType) +{ + if (prStaRec->ucStaState == STA_STATE_3) { + struct MSG_AIS_ABORT *prAisAbortMsg; + u_int8_t fgIsTxAllowed; + + /* Backup txallowed status here because + * cnmStaRecChangeState will change it + */ + fgIsTxAllowed = prStaRec->fgIsTxAllowed; + + /* NOTE(Kevin): Change state immediately to + * avoid starvation of MSG buffer because of too + * many deauth frames before changing the STA + * state. + */ + cnmStaRecChangeState(prAdapter, prStaRec, + eFrmType == FRM_DEAUTH ? STA_STATE_1 : STA_STATE_2); + + prAisAbortMsg = + (struct MSG_AIS_ABORT *) + cnmMemAlloc(prAdapter, + RAM_TYPE_MSG, + sizeof(struct MSG_AIS_ABORT)); + if (!prAisAbortMsg) + return; + + prAisAbortMsg->rMsgHdr.eMsgId = + MID_SAA_AIS_FSM_ABORT; + prAisAbortMsg->ucReasonOfDisconnect = + eFrmType == FRM_DEAUTH ? + DISCONNECT_REASON_CODE_DEAUTHENTICATED : + DISCONNECT_REASON_CODE_DISASSOCIATED; + prAisAbortMsg->fgDelayIndication = fgIsTxAllowed; + prAisAbortMsg->ucBssIndex = + prStaRec->ucBssIndex; + mboxSendMsg(prAdapter, MBOX_ID_0, + (struct MSG_HDR *) prAisAbortMsg, + MSG_SEND_METHOD_BUF); + } + if (prAisBssInfo) + prAisBssInfo->u2DeauthReason = prStaRec->u2ReasonCode; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will check the incoming Disassociation Frame. + * + * @param[in] prSwRfb Pointer to the SW_RFB_T structure. + * + * @retval WLAN_STATUS_SUCCESS Always not retain disassociation frames + */ +/*----------------------------------------------------------------------------*/ +uint32_t saaFsmRunEventRxDisassoc(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb) +{ + struct STA_RECORD *prStaRec; + struct WLAN_DISASSOC_FRAME *prDisassocFrame; + uint8_t ucWlanIdx; + + prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); + prDisassocFrame = (struct WLAN_DISASSOC_FRAME *) prSwRfb->pvHeader; + ucWlanIdx = prSwRfb->ucWlanIdx; + + DBGLOG(SAA, INFO, + "Rx Disassoc frame from SA[" MACSTR "] BSSID[" MACSTR + "] DA[" MACSTR "] ReasonCode[0x%x]\n", + MAC2STR(prDisassocFrame->aucSrcAddr), + MAC2STR(prDisassocFrame->aucBSSID), + MAC2STR(prDisassocFrame->aucDestAddr), + prDisassocFrame->u2ReasonCode); + + do { + + /* We should have the corresponding Sta Record. */ + if (!prStaRec) { + DBGLOG(SAA, WARN, + "Received a DisAssoc: wlanIdx[%d] w/o corresponding staRec\n", + ucWlanIdx); + break; + } + + if (IS_STA_IN_AIS(prStaRec)) { + struct BSS_INFO *prAisBssInfo; + uint8_t ucBssIndex = 0; + + if (!IS_AP_STA(prStaRec)) + break; + + ucBssIndex = prStaRec->ucBssIndex; + + prAisBssInfo = aisGetAisBssInfo(prAdapter, + ucBssIndex); + + if (prStaRec->ucStaState > STA_STATE_1) { + + /* Check if this is the AP we are associated + * or associating with + */ + if (assocProcessRxDisassocFrame(prAdapter, + prSwRfb, prStaRec->aucMacAddr, &prStaRec-> + u2ReasonCode) == WLAN_STATUS_SUCCESS) { + +#if CFG_SUPPORT_802_11W + struct AIS_SPECIFIC_BSS_INFO + *prAisSpecBssInfo; + + prAisSpecBssInfo = + aisGetAisSpecBssInfo(prAdapter, + ucBssIndex); + + DBGLOG(RSN, INFO, + "QM RX MGT: Disassoc frame, P=%d Sec=%d CM=%d BC=%d fc=%02x\n", + prAisSpecBssInfo-> + fgMgmtProtection, (uint8_t) + prSwRfb->ucSecMode, + prSwRfb->fgIsCipherMS, + IS_BMCAST_MAC_ADDR + (prDisassocFrame->aucDestAddr), + prDisassocFrame->u2FrameCtrl); + if (IS_STA_IN_AIS(prStaRec) && + prAisSpecBssInfo->fgMgmtProtection + && prSwRfb->fgIsCipherMS + /* HAL_RX_STATUS_GET_SEC_MODE( + * prSwRfb->prRxStatus) != + * CIPHER_SUITE_CCMP + */ + ) { + /* prDisassocFrame = + * (P_WLAN_DISASSOC_FRAME_T) + * prSwRfb->pvHeader; + */ + saaChkDisassocfrmParamHandler( + prAdapter, + prDisassocFrame, prStaRec, + prSwRfb); + return WLAN_STATUS_SUCCESS; + } +#endif + saaSendDisconnectMsgHandler(prAdapter, + prStaRec, + prAisBssInfo, + FRM_DISASSOC); + } + } + } +#if CFG_ENABLE_WIFI_DIRECT + else if (prAdapter->fgIsP2PRegistered && + (IS_STA_IN_P2P(prStaRec))) { + /* TODO(Kevin) */ + p2pRoleFsmRunEventRxDisassociation(prAdapter, + prStaRec, prSwRfb); + } +#endif +#if CFG_ENABLE_BT_OVER_WIFI + else if (IS_STA_BOW_TYPE(prStaRec)) { + /* ToDo:: nothing */ + /* TODO(Kevin) */ + } +#endif + else + ASSERT(0); + + } while (FALSE); + + return WLAN_STATUS_SUCCESS; + +} /* end of saaFsmRunEventRxDisassoc() */ + +/* for AOSP */ +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will check param of Disassoc frame and reson code for + * Disassoc. + * + * @param[in] + * + * @retval + */ +/*----------------------------------------------------------------------------*/ + +void +saaChkDisassocfrmParamHandler(IN struct ADAPTER *prAdapter, + IN struct WLAN_DISASSOC_FRAME *prDisassocFrame, + IN struct STA_RECORD *prStaRec, + IN struct SW_RFB *prSwRfb) +{ + if (!IS_BMCAST_MAC_ADDR(prDisassocFrame->aucDestAddr)) { + /* MFP test plan 5.3.3.5 */ + DBGLOG(RSN, INFO, + "[%d] QM RX MGT: rsnStartSaQuery\n", + prStaRec->ucBssIndex); + rsnStartSaQuery(prAdapter, prStaRec->ucBssIndex); + } else { + DBGLOG(RSN, INFO, "RXM: Drop unprotected Mgmt frame\n"); + DBGLOG(RSN, INFO, + "RXM:(MACRX Done)RX(ucSecMode=0x%x)(ucWlanIdx=0x%x)\n", + prSwRfb->ucSecMode, prSwRfb->ucWlanIdx); + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will handle the Abort Event to SAA FSM. + * + * @param[in] prMsgHdr Message of Abort Request for a particular STA. + * + * @return none + */ +/*----------------------------------------------------------------------------*/ +void saaFsmRunEventAbort(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct MSG_SAA_FSM_ABORT *prSaaFsmAbortMsg; + struct STA_RECORD *prStaRec; + + prSaaFsmAbortMsg = (struct MSG_SAA_FSM_ABORT *) prMsgHdr; + prStaRec = prSaaFsmAbortMsg->prStaRec; + + if (!prStaRec) { + cnmMemFree(prAdapter, prMsgHdr); + return; + } + + DBGLOG(SAA, LOUD, "EVENT-ABORT: Stop SAA FSM.\n"); + + cnmMemFree(prAdapter, prMsgHdr); + + /* Reset Send Auth/(Re)Assoc Frame Count */ + prStaRec->ucTxAuthAssocRetryCount = 0; + + /* Cancel JOIN relative Timer */ + cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); + + if (prStaRec->eAuthAssocState != AA_STATE_IDLE) { + if (prStaRec->eAuthAssocState >= 0 + && prStaRec->eAuthAssocState < AA_STATE_NUM) { + DBGLOG(SAA, LOUD, + "EVENT-ABORT: Previous Auth/Assoc State == %s.\n", + apucDebugAAState[prStaRec->eAuthAssocState]); + } + } +#if 0 + /* For the Auth/Assoc State to IDLE */ + prStaRec->eAuthAssocState = AA_STATE_IDLE; +#else + /* Free this StaRec */ + cnmStaRecFree(prAdapter, prStaRec); +#endif +} /* end of saaFsmRunEventAbort() */ + +void saaFsmRunEventExternalAuthDone(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct MSG_SAA_EXTERNAL_AUTH_DONE *prSaaFsmMsg = NULL; + struct STA_RECORD *prStaRec; + uint16_t status; + + ASSERT(prAdapter); + ASSERT(prMsgHdr); + + prSaaFsmMsg = (struct MSG_SAA_EXTERNAL_AUTH_DONE *)prMsgHdr; + prStaRec = prSaaFsmMsg->prStaRec; + status = prSaaFsmMsg->status; + + cnmMemFree(prAdapter, prMsgHdr); + + if (status != WLAN_STATUS_SUCCESS) + saaFsmSteps(prAdapter, prStaRec, AA_STATE_IDLE, + (struct SW_RFB *)NULL); + else if (prStaRec->eAuthAssocState != SAA_STATE_EXTERNAL_AUTH) + DBGLOG(SAA, WARN, + "Receive External Auth DONE at wrong state\n"); + else + saaFsmSteps(prAdapter, prStaRec, SAA_STATE_SEND_ASSOC1, + (struct SW_RFB *)NULL); +} /* end of saaFsmRunEventExternalAuthDone() */ + +/* TODO(Kevin): following code will be modified and move to AIS FSM */ +#if 0 +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function will send Join Timeout Event to JOIN FSM. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * + * \retval WLAN_STATUS_FAILURE Fail because of Join Timeout + */ +/*----------------------------------------------------------------------------*/ +uint32_t joinFsmRunEventJoinTimeOut(IN struct ADAPTER *prAdapter) +{ + P_JOIN_INFO_T prJoinInfo; + struct STA_RECORD *prStaRec; + + DEBUGFUNC("joinFsmRunEventJoinTimeOut"); + + ASSERT(prAdapter); + prJoinInfo = &prAdapter->rJoinInfo; + + DBGLOG(JOIN, EVENT, "JOIN EVENT: JOIN TIMEOUT\n"); + + /* Get a Station Record if possible, TA == BSSID for AP */ + prStaRec = staRecGetStaRecordByAddr(prAdapter, + prJoinInfo->prBssDesc->aucBSSID); + + /* We have renew this Sta Record when in JOIN_STATE_INIT */ + ASSERT(prStaRec); + + /* Record the Status Code of Authentication Request */ + prStaRec->u2StatusCode = STATUS_CODE_JOIN_TIMEOUT; + + /* Increase Failure Count */ + prStaRec->ucJoinFailureCount++; + + /* Reset Send Auth/(Re)Assoc Frame Count */ + prJoinInfo->ucTxAuthAssocRetryCount = 0; + + /* Cancel other JOIN relative Timer */ + ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rTxRequestTimer); + + ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rRxResponseTimer); + + /* Restore original setting from current BSS_INFO_T */ + if (prAdapter->eConnectionState == MEDIA_STATE_CONNECTED) + joinAdoptParametersFromCurrentBss(prAdapter); + + /* Pull back to IDLE */ + joinFsmSteps(prAdapter, JOIN_STATE_IDLE); + + return WLAN_STATUS_FAILURE; + +} /* end of joinFsmRunEventJoinTimeOut() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function will adopt the parameters from Peer BSS. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void joinAdoptParametersFromPeerBss(IN struct ADAPTER *prAdapter) +{ + P_JOIN_INFO_T prJoinInfo; + struct BSS_DESC *prBssDesc; + + DEBUGFUNC("joinAdoptParametersFromPeerBss"); + + ASSERT(prAdapter); + prJoinInfo = &prAdapter->rJoinInfo; + prBssDesc = prJoinInfo->prBssDesc; + + /* 4 <1> Adopt Peer BSS' PHY TYPE */ + prAdapter->eCurrentPhyType = prBssDesc->ePhyType; + + DBGLOG(JOIN, INFO, "Target BSS[%s]'s PhyType = %s\n", + prBssDesc->aucSSID, (prBssDesc->ePhyType == PHY_TYPE_ERP_INDEX) ? + "ERP" : "HR_DSSS"); + + /* 4 <2> Adopt Peer BSS' Frequency(Band/Channel) */ + DBGLOG(JOIN, INFO, "Target BSS's Channel = %d, Band = %d\n", + prBssDesc->ucChannelNum, prBssDesc->eBand); + + nicSwitchChannel(prAdapter, prBssDesc->eBand, + prBssDesc->ucChannelNum, 10); + + prJoinInfo->fgIsParameterAdopted = TRUE; +} /* end of joinAdoptParametersFromPeerBss() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function will adopt the parameters from current associated BSS. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void joinAdoptParametersFromCurrentBss(IN struct ADAPTER *prAdapter) +{ + /* P_JOIN_INFO_T prJoinInfo = &prAdapter->rJoinInfo; */ + struct BSS_INFO *prBssInfo; + + ASSERT(prAdapter); + prBssInfo = &prAdapter->rBssInfo; + + /* 4 <1> Adopt current BSS' PHY TYPE */ + prAdapter->eCurrentPhyType = prBssInfo->ePhyType; + + /* 4 <2> Adopt current BSS' Frequency(Band/Channel) */ + DBGLOG(JOIN, INFO, "Current BSS's Channel = %d, Band = %d\n", + prBssInfo->ucChnl, prBssInfo->eBand); + + nicSwitchChannel(prAdapter, prBssInfo->eBand, prBssInfo->ucChnl, 10); +} /* end of joinAdoptParametersFromCurrentBss() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function will update all the SW variables and HW MCR registers + * after the association with target BSS. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void joinComplete(IN struct ADAPTER *prAdapter) +{ + P_JOIN_INFO_T prJoinInfo; + struct BSS_DESC *prBssDesc; + P_PEER_BSS_INFO_T prPeerBssInfo; + struct BSS_INFO *prBssInfo; + struct CONNECTION_SETTINGS *prConnSettings; + struct STA_RECORD *prStaRec; + struct TX_CTRL *prTxCtrl; +#if CFG_SUPPORT_802_11D + struct IE_COUNTRY *prIECountry; +#endif + + DEBUGFUNC("joinComplete"); + + ASSERT(prAdapter); + prJoinInfo = &prAdapter->rJoinInfo; + prBssDesc = prJoinInfo->prBssDesc; + prPeerBssInfo = &prAdapter->rPeerBssInfo; + prBssInfo = &prAdapter->rBssInfo; + prConnSettings = &prAdapter->rConnSettings; + prTxCtrl = &prAdapter->rTxCtrl; + +/* 4 <1> Update Connecting & Connected Flag of BSS_DESC_T. */ + /* Remove previous AP's Connection Flags if have */ + scanRemoveConnectionFlagOfBssDescByBssid(prAdapter, + prBssInfo->aucBSSID); + + prBssDesc->fgIsConnected = TRUE; /* Mask as Connected */ + + if (prBssDesc->fgIsHiddenSSID) { + /* NOTE(Kevin): This is for the case of Passive Scan and the + * target BSS didn't broadcast SSID on its Beacon Frame. + */ + COPY_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen, + prAdapter->rConnSettings.aucSSID, + prAdapter->rConnSettings.ucSSIDLen); + + if (prBssDesc->ucSSIDLen) + prBssDesc->fgIsHiddenSSID = FALSE; +#if DBG + else + ASSERT(0); +#endif /* DBG */ + + DBGLOG(JOIN, INFO, "Hidden SSID! - Update SSID : %s\n", + prBssDesc->aucSSID); + } + +/* 4 <2> Update BSS_INFO_T from BSS_DESC_T */ + /* 4 <2.A> PHY Type */ + prBssInfo->ePhyType = prBssDesc->ePhyType; + + /* 4 <2.B> BSS Type */ + prBssInfo->eBSSType = BSS_TYPE_INFRASTRUCTURE; + + /* 4 <2.C> BSSID */ + COPY_MAC_ADDR(prBssInfo->aucBSSID, prBssDesc->aucBSSID); + + DBGLOG(JOIN, INFO, + "JOIN to BSSID: [" MACSTR "]\n", MAC2STR(prBssDesc->aucBSSID)); + + /* 4 <2.D> SSID */ + COPY_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, + prBssDesc->aucSSID, prBssDesc->ucSSIDLen); + + /* 4 <2.E> Channel / Band information. */ + prBssInfo->eBand = prBssDesc->eBand; + prBssInfo->ucChnl = prBssDesc->ucChannelNum; + + /* 4 <2.F> RSN/WPA information. */ + secFsmRunEventStart(prAdapter); + prBssInfo->u4RsnSelectedPairwiseCipher = + prBssDesc->u4RsnSelectedPairwiseCipher; + prBssInfo->u4RsnSelectedGroupCipher = + prBssDesc->u4RsnSelectedGroupCipher; + prBssInfo->u4RsnSelectedAKMSuite = prBssDesc->u4RsnSelectedAKMSuite; + + if (secRsnKeyHandshakeEnabled()) + prBssInfo->fgIsWPAorWPA2Enabled = TRUE; + else + prBssInfo->fgIsWPAorWPA2Enabled = FALSE; + + /* 4 <2.G> Beacon interval. */ + prBssInfo->u2BeaconInterval = prBssDesc->u2BeaconInterval; + + /* 4 <2.H> DTIM period. */ + prBssInfo->ucDtimPeriod = prBssDesc->ucDTIMPeriod; + + /* 4 <2.I> ERP Information */ + /* Our BSS's PHY_TYPE is ERP now. */ + if ((prBssInfo->ePhyType == PHY_TYPE_ERP_INDEX) && + (prBssDesc->fgIsERPPresent)) { + + prBssInfo->fgIsERPPresent = TRUE; + /* Save the ERP for later check */ + prBssInfo->ucERP = prBssDesc->ucERP; + } else { + /* Some AP, may send ProbeResp without ERP IE. + * Thus prBssDesc->fgIsERPPresent is FALSE. + */ + prBssInfo->fgIsERPPresent = FALSE; + prBssInfo->ucERP = 0; + } + +#if CFG_SUPPORT_802_11D + /* 4 <2.J> Country inforamtion of the associated AP */ + if (prConnSettings->fgMultiDomainCapabilityEnabled) { + struct DOMAIN_INFO_ENTRY rDomainInfo; + + if (domainGetDomainInfoByScanResult(prAdapter, &rDomainInfo)) { + if (prBssDesc->prIECountry) { + prIECountry = prBssDesc->prIECountry; + + domainParseCountryInfoElem(prIECountry, + &prBssInfo->rDomainInfo); + + /* use the domain get from the BSS info */ + prBssInfo->fgIsCountryInfoPresent = TRUE; + nicSetupOpChnlList(prAdapter, + prBssInfo->rDomainInfo.u2CountryCode, FALSE); + } else { + /* use the domain get from the scan result */ + prBssInfo->fgIsCountryInfoPresent = TRUE; + nicSetupOpChnlList(prAdapter, + rDomainInfo.u2CountryCode, + FALSE); + } + } + } +#endif + + /* 4 <2.K> Signal Power of the associated AP */ + prBssInfo->rRcpi = prBssDesc->rRcpi; + prBssInfo->rRssi = RCPI_TO_dBm(prBssInfo->rRcpi); + GET_CURRENT_SYSTIME(&prBssInfo->rRssiLastUpdateTime); + + /* 4 <2.L> Capability Field of the associated AP */ + prBssInfo->u2CapInfo = prBssDesc->u2CapInfo; + + DBGLOG(JOIN, INFO, + "prBssInfo-> fgIsERPPresent = %d, ucERP = %02x, rRcpi = %d, rRssi = %ld\n", + prBssInfo->fgIsERPPresent, prBssInfo->ucERP, + prBssInfo->rRcpi, prBssInfo->rRssi); + +/* 4 <3> Update BSS_INFO_T from PEER_BSS_INFO_T & NIC RATE FUNC */ + /* 4 <3.A> Association ID */ + prBssInfo->u2AssocId = prPeerBssInfo->u2AssocId; + + /* 4 <3.B> WMM Information */ + if (prAdapter->fgIsEnableWMM && + (prPeerBssInfo->rWmmInfo.ucWmmFlag & WMM_FLAG_SUPPORT_WMM)) { + + prBssInfo->fgIsWmmAssoc = TRUE; + prTxCtrl->rTxQForVoipAccess = TXQ_AC3; + + qosWmmInfoInit(&prBssInfo->rWmmInfo, + (prBssInfo->ePhyType == PHY_TYPE_HR_DSSS_INDEX) + ? TRUE : FALSE); + + if (prPeerBssInfo->rWmmInfo.ucWmmFlag & + WMM_FLAG_AC_PARAM_PRESENT) { + kalMemCopy(&prBssInfo->rWmmInfo, + &prPeerBssInfo->rWmmInfo, + sizeof(WMM_INFO_T)); + } else { + kalMemCopy(&prBssInfo->rWmmInfo, + &prPeerBssInfo->rWmmInfo, + sizeof(WMM_INFO_T) - + sizeof(prPeerBssInfo-> + rWmmInfo.arWmmAcParams)); + } + } else { + prBssInfo->fgIsWmmAssoc = FALSE; + prTxCtrl->rTxQForVoipAccess = TXQ_AC1; + + kalMemZero(&prBssInfo->rWmmInfo, sizeof(WMM_INFO_T)); + } + + /* 4 <3.C> Operational Rate Set & BSS Basic Rate Set */ + prBssInfo->u2OperationalRateSet = prPeerBssInfo->u2OperationalRateSet; + prBssInfo->u2BSSBasicRateSet = prPeerBssInfo->u2BSSBasicRateSet; + + /* 4 <3.D> Short Preamble */ + if (prBssInfo->fgIsERPPresent) { + + /* NOTE(Kevin 2007/12/24): Truth Table. + * Short Preamble Bit in + * Final Drv Set + * TRUE FALSE FALSE FALSE(#1) + * TRUE FALSE TRUE FALSE + * FALSE FALSE FALSE FALSE(#1) + * FALSE FALSE TRUE FALSE + * TRUE TRUE FALSE TRUE(#2) + * TRUE TRUE TRUE FALSE(#2) + * FALSE TRUE FALSE FALSE(#3) + * FALSE TRUE TRUE FALSE(#4) + * #1: shouldn't have such case, use the AssocResp + * #2: follow ERP + * #3: shouldn't have such case, and we should set to FALSE + * #4: we should set to FALSE + */ + if ((prPeerBssInfo->fgIsShortPreambleAllowed) && + ((prConnSettings->ePreambleType == PREAMBLE_TYPE_SHORT) || + /* Short Preamble Option Enable is TRUE */ + ((prConnSettings->ePreambleType == PREAMBLE_TYPE_AUTO) && + (prBssDesc->u2CapInfo & CAP_INFO_SHORT_PREAMBLE)))) { + + prBssInfo->fgIsShortPreambleAllowed = TRUE; + + if (prBssInfo->ucERP & ERP_INFO_BARKER_PREAMBLE_MODE) + prBssInfo->fgUseShortPreamble = FALSE; + else + prBssInfo->fgUseShortPreamble = TRUE; + } else { + prBssInfo->fgIsShortPreambleAllowed = FALSE; + prBssInfo->fgUseShortPreamble = FALSE; + } + } else { + /* NOTE(Kevin 2007/12/24): Truth Table. + * Short Preamble Bit in + * Final Driver Setting(Short) + * TRUE FALSE FALSE + * FALSE FALSE FALSE + * TRUE TRUE TRUE + * FALSE TRUE(status success) TRUE + * --> Honor the result of prPeerBssInfo. + */ + + prBssInfo->fgIsShortPreambleAllowed = + prBssInfo->fgUseShortPreamble = + prPeerBssInfo->fgIsShortPreambleAllowed; + } + + DBGLOG(JOIN, INFO, + "prBssInfo->fgIsShortPreambleAllowed = %d, prBssInfo->fgUseShortPreamble = %d\n", + prBssInfo->fgIsShortPreambleAllowed, + prBssInfo->fgUseShortPreamble); + + /* 4 <3.E> Short Slot Time */ + /* AP support Short Slot Time */ + prBssInfo->fgUseShortSlotTime = prPeerBssInfo->fgUseShortSlotTime; + + DBGLOG(JOIN, INFO, "prBssInfo->fgUseShortSlotTime = %d\n", + prBssInfo->fgUseShortSlotTime); + + nicSetSlotTime(prAdapter, + prBssInfo->ePhyType, + ((prConnSettings->fgIsShortSlotTimeOptionEnable && + prBssInfo->fgUseShortSlotTime) ? TRUE : FALSE)); + + /* 4 <3.F> Update Tx Rate for Control Frame */ + bssUpdateTxRateForControlFrame(prAdapter); + + /* 4 <3.G> Save the available Auth Types during Roaming (Design for + * Fast BSS Transition). + */ + /* if (prAdapter->fgIsEnableRoaming) */ + /* NOTE(Kevin): Always prepare info for roaming */ + { + + if (prJoinInfo->ucCurrAuthAlgNum == + AUTH_ALGORITHM_NUM_OPEN_SYSTEM) + prJoinInfo->ucRoamingAuthTypes |= AUTH_TYPE_OPEN_SYSTEM; + else if (prJoinInfo->ucCurrAuthAlgNum == + AUTH_ALGORITHM_NUM_SHARED_KEY) + prJoinInfo->ucRoamingAuthTypes |= AUTH_TYPE_SHARED_KEY; + + prBssInfo->ucRoamingAuthTypes = prJoinInfo->ucRoamingAuthTypes; + + /* Set the stable time of the associated BSS. We won't do + * roaming decision during the stable time. + */ + SET_EXPIRATION_TIME(prBssInfo->rRoamingStableExpirationTime, + SEC_TO_SYSTIME(ROAMING_STABLE_TIMEOUT_SEC)); + } + + /* 4 <3.H> Update Parameter for TX Fragmentation Threshold */ +#if CFG_TX_FRAGMENT + txFragInfoUpdate(prAdapter); +#endif /* CFG_TX_FRAGMENT */ + +/* 4 <4> Update STA_RECORD_T */ + /* Get a Station Record if possible */ + prStaRec = staRecGetStaRecordByAddr(prAdapter, prBssDesc->aucBSSID); + + if (prStaRec) { + uint16_t u2OperationalRateSet, u2DesiredRateSet; + + /* 4 <4.A> Desired Rate Set */ + u2OperationalRateSet = (rPhyAttributes[prBssInfo->ePhyType]. + u2SupportedRateSet & prBssInfo-> + u2OperationalRateSet); + + u2DesiredRateSet = (u2OperationalRateSet & + prConnSettings->u2DesiredRateSet); + if (u2DesiredRateSet) { + prStaRec->u2DesiredRateSet = u2DesiredRateSet; + } else { + /* For Error Handling - The Desired Rate Set is not + * covered in Operational Rate Set. + */ + prStaRec->u2DesiredRateSet = u2OperationalRateSet; + } + + /* Try to set the best initial rate for this entry */ + if (!rateGetBestInitialRateIndex(prStaRec->u2DesiredRateSet, + prStaRec->rRcpi, &prStaRec-> + ucCurrRate1Index)) { + + if (!rateGetLowestRateIndexFromRateSet(prStaRec-> + u2DesiredRateSet, &prStaRec->ucCurrRate1Index)) + ASSERT(0); + } + + DBGLOG(JOIN, INFO, "prStaRec->ucCurrRate1Index = %d\n", + prStaRec->ucCurrRate1Index); + + /* 4 <4.B> Preamble Mode */ + prStaRec->fgIsShortPreambleOptionEnable = + prBssInfo->fgUseShortPreamble; + + /* 4 <4.C> QoS Flag */ + prStaRec->fgIsQoS = prBssInfo->fgIsWmmAssoc; + } +#if DBG + else + ASSERT(0); +#endif /* DBG */ + +/* 4 <5> Update NIC */ + /* 4 <5.A> Update BSSID & Operation Mode */ + nicSetupBSS(prAdapter, prBssInfo); + + /* 4 <5.B> Update WLAN Table. */ + if (nicSetHwBySta(prAdapter, prStaRec) == FALSE) + ASSERT(FALSE); + /* 4 <5.C> Update Desired Rate Set for BT. */ +#if CFG_TX_FRAGMENT + if (prConnSettings->fgIsEnableTxAutoFragmentForBT) + txRateSetInitForBT(prAdapter, prStaRec); +#endif /* CFG_TX_FRAGMENT */ + + /* 4 <5.D> TX AC Parameter and TX/RX Queue Control */ + if (prBssInfo->fgIsWmmAssoc) { + +#if CFG_TX_AGGREGATE_HW_FIFO + nicTxAggregateTXQ(prAdapter, FALSE); +#endif /* CFG_TX_AGGREGATE_HW_FIFO */ + + qosUpdateWMMParametersAndAssignAllowedACI(prAdapter, + &prBssInfo->rWmmInfo); + } else { + +#if CFG_TX_AGGREGATE_HW_FIFO + nicTxAggregateTXQ(prAdapter, TRUE); +#endif /* CFG_TX_AGGREGATE_HW_FIFO */ + + nicTxNonQoSAssignDefaultAdmittedTXQ(prAdapter); + + nicTxNonQoSUpdateTXQParameters(prAdapter, prBssInfo->ePhyType); + } + +#if CFG_TX_STOP_WRITE_TX_FIFO_UNTIL_JOIN + { + prTxCtrl->fgBlockTxDuringJoin = FALSE; + +#if !CFG_TX_AGGREGATE_HW_FIFO /* TX FIFO AGGREGATE already do flush once */ + nicTxFlushStopQueues(prAdapter, (uint8_t) TXQ_DATA_MASK, + (uint8_t) NULL); +#endif /* CFG_TX_AGGREGATE_HW_FIFO */ + + nicTxRetransmitOfSendWaitQue(prAdapter); + + if (prTxCtrl->fgIsPacketInOsSendQueue) + nicTxRetransmitOfOsSendQue(prAdapter); +#if CFG_SDIO_TX_ENHANCE + halTxLeftClusteredMpdu(prAdapter); +#endif /* CFG_SDIO_TX_ENHANCE */ + + } +#endif /* CFG_TX_STOP_WRITE_TX_FIFO_UNTIL_JOIN */ + +/* 4 <6> Setup CONNECTION flag. */ + prAdapter->eConnectionState = MEDIA_STATE_CONNECTED; + prAdapter->eConnectionStateIndicated = MEDIA_STATE_CONNECTED; + + if (prJoinInfo->fgIsReAssoc) + prAdapter->fgBypassPortCtrlForRoaming = TRUE; + else + prAdapter->fgBypassPortCtrlForRoaming = FALSE; + + kalIndicateStatusAndComplete(prAdapter->prGlueInfo, + WLAN_STATUS_MEDIA_CONNECT, + (void *) NULL, 0); +} /* end of joinComplete() */ +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/scan.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/scan.c new file mode 100644 index 0000000000000000000000000000000000000000..5a3ec8c202ceb16268f975d564ba763d73df59f6 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/scan.c @@ -0,0 +1,4292 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#define REPLICATED_BEACON_STRENGTH_THRESHOLD (32) +#define ROAMING_NO_SWING_RCPI_STEP (10) +#define REPLICATED_BEACON_FRESH_PERIOD (10000) +#define REPLICATED_BEACON_TIME_THRESHOLD (3000) + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ +/* The order of aucScanLogPrefix should be aligned the order + * of enum ENUM_SCAN_LOG_PREFIX + */ +const char aucScanLogPrefix[][SCAN_LOG_PREFIX_MAX_LEN] = { + /* Scan */ + "[SCN:100:K2D]", /* LOG_SCAN_REQ_K2D */ + "[SCN:200:D2F]", /* LOG_SCAN_REQ_D2F */ + "[SCN:300:F2D]", /* LOG_SCAN_RESULT_F2D */ + "[SCN:400:D2K]", /* LOG_SCAN_RESULT_D2K */ + "[SCN:500:F2D]", /* LOG_SCAN_DONE_F2D */ + "[SCN:600:D2K]", /* LOG_SCAN_DONE_D2K */ + + /* Sched scan */ + "[SCN:700:K2D]", /* LOG_SCHED_SCAN_REQ_START_K2D */ + "[SCN:800:D2F]", /* LOG_SCHED_SCAN_REQ_START_D2F */ + "[SCN:750:K2D]", /* LOG_SCHED_SCAN_REQ_STOP_K2D */ + "[SCN:850:D2F]", /* LOG_SCHED_SCAN_REQ_STOP_D2F */ + "[SCN:900:F2D]", /* LOG_SCHED_SCAN_DONE_F2D */ + "[SCN:1000:D2K]", /* LOG_SCHED_SCAN_DONE_D2K */ + + /* Scan abort */ + "[SCN:1100:K2D]", /* LOG_SCAN_ABORT_REQ_K2D */ + "[SCN:1200:D2F]", /* LOG_SCAN_ABORT_REQ_D2F */ + "[SCN:1300:D2K]", /* LOG_SCAN_ABORT_DONE_D2K */ + + /* Driver only */ + "[SCN:0:D2D]", /* LOG_SCAN_D2D */ + + /* Last one */ + "" /* LOG_SCAN_MAX */ +}; + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is used by SCN to initialize its variables + * + * @param (none) + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void scnInit(IN struct ADAPTER *prAdapter) +{ + struct SCAN_INFO *prScanInfo; + struct BSS_DESC *prBSSDesc; + uint8_t *pucBSSBuff; + uint32_t i; + + ASSERT(prAdapter); + + prScanInfo = &(prAdapter->rWifiVar.rScanInfo); + pucBSSBuff = &prScanInfo->aucScanBuffer[0]; + + log_dbg(SCN, TRACE, "->scnInit()\n"); + + /* 4 <1> Reset STATE and Message List */ + prScanInfo->eCurrentState = SCAN_STATE_IDLE; + + prScanInfo->rLastScanCompletedTime = (OS_SYSTIME) 0; + + LINK_INITIALIZE(&prScanInfo->rPendingMsgList); + + /* 4 <2> Reset link list of BSS_DESC_T */ + kalMemZero((void *) pucBSSBuff, SCN_MAX_BUFFER_SIZE); + + LINK_INITIALIZE(&prScanInfo->rFreeBSSDescList); + LINK_INITIALIZE(&prScanInfo->rBSSDescList); + + for (i = 0; i < CFG_MAX_NUM_BSS_LIST; i++) { + + prBSSDesc = (struct BSS_DESC *) pucBSSBuff; + + scanInsertBssDescToList(&prScanInfo->rFreeBSSDescList, + prBSSDesc, + FALSE); + + pucBSSBuff += ALIGN_4(sizeof(struct BSS_DESC)); + } + /* Check if the memory allocation consist with + * this initialization function + */ + ASSERT(((unsigned long) pucBSSBuff + - (unsigned long)&prScanInfo->aucScanBuffer[0]) + == SCN_MAX_BUFFER_SIZE); + + /* reset freest channel information */ + prScanInfo->fgIsSparseChannelValid = FALSE; + + prScanInfo->fgIsScanForFull2Partial = FALSE; + + /* reset Sched scan state */ + prScanInfo->fgSchedScanning = FALSE; + /*Support AP Selection */ + prScanInfo->u4ScanUpdateIdx = 0; +} /* end of scnInit() */ + +void scnFreeAllPendingScanRquests(IN struct ADAPTER *prAdapter) +{ + struct SCAN_INFO *prScanInfo; + struct MSG_HDR *prMsgHdr; + struct MSG_SCN_SCAN_REQ *prScanReqMsg; + + prScanInfo = &(prAdapter->rWifiVar.rScanInfo); + + /* check for pending scanning requests */ + while (!LINK_IS_EMPTY(&(prScanInfo->rPendingMsgList))) { + + /* load next message from pending list as scan parameters */ + LINK_REMOVE_HEAD(&(prScanInfo->rPendingMsgList), + prMsgHdr, struct MSG_HDR *); + if (prMsgHdr) { + prScanReqMsg = (struct MSG_SCN_SCAN_REQ *) prMsgHdr; + + log_dbg(SCN, INFO, "Free scan request eMsgId[%d] ucSeqNum [%d] BSSID[%d]!!\n", + prMsgHdr->eMsgId, + prScanReqMsg->ucSeqNum, + prScanReqMsg->ucBssIndex); + + cnmMemFree(prAdapter, prMsgHdr); + } else { + /* should not deliver to this function */ + ASSERT(0); + } + /* switch to next state */ + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is used by SCN to uninitialize its variables + * + * @param (none) + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void scnUninit(IN struct ADAPTER *prAdapter) +{ + struct SCAN_INFO *prScanInfo; + + ASSERT(prAdapter); + prScanInfo = &(prAdapter->rWifiVar.rScanInfo); + + log_dbg(SCN, INFO, "%s()\n", __func__); + + scnFreeAllPendingScanRquests(prAdapter); + + /* 4 <1> Reset STATE and Message List */ + prScanInfo->eCurrentState = SCAN_STATE_IDLE; + + prScanInfo->rLastScanCompletedTime = (OS_SYSTIME) 0; + + /* NOTE(Kevin): Check rPendingMsgList ? */ + + /* 4 <2> Reset link list of BSS_DESC_T */ + LINK_INITIALIZE(&prScanInfo->rFreeBSSDescList); + LINK_INITIALIZE(&prScanInfo->rBSSDescList); +} /* end of scnUninit() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Find the corresponding BSS Descriptor according to given BSSID + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] aucBSSID Given BSSID. + * + * @return Pointer to BSS Descriptor, if found. NULL, if not found + */ +/*----------------------------------------------------------------------------*/ +struct BSS_DESC *scanSearchBssDescByBssid(IN struct ADAPTER *prAdapter, + IN uint8_t aucBSSID[]) +{ + return scanSearchBssDescByBssidAndSsid(prAdapter, aucBSSID, + FALSE, NULL); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Check if the bit of the given bitmap is set + * The bitmap should be unsigned int based, which means that this function + * doesn't support other format bitmap, e.g. char array or short array + * + * @param[in] bit which bit to check. + * @param[in] bitMap bitmap array + * @param[in] bitMapSize bytes of bitmap + * + * @return TRUE if the bit of the given bitmap is set, FALSE otherwise + */ +/*----------------------------------------------------------------------------*/ +u_int8_t scanIsBitSet(IN uint32_t bit, IN uint32_t bitMap[], + IN uint32_t bitMapSize) +{ + if (bit >= bitMapSize * BITS_OF_BYTE) { + log_dbg(SCN, WARN, "bit %u is out of array range(%u bits)\n", + bit, bitMapSize * BITS_OF_BYTE); + return FALSE; + } else { + return (bitMap[bit/BITS_OF_UINT] & + (1 << (bit % BITS_OF_UINT))) ? TRUE : FALSE; + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Set the bit of the given bitmap. + * The bitmap should be unsigned int based, which means that this function + * doesn't support other format bitmap, e.g. char array or short array + * + * @param[in] bit which bit to set. + * @param[out] bitMap bitmap array + * @param[in] bitMapSize bytes of bitmap + * + * @return void + */ +/*----------------------------------------------------------------------------*/ +void scanSetBit(IN uint32_t bit, OUT uint32_t bitMap[], IN uint32_t bitMapSize) +{ + if (bit >= bitMapSize * BITS_OF_BYTE) { + log_dbg(SCN, WARN, "set bit %u to array(%u bits) failed\n", + bit, bitMapSize * BITS_OF_BYTE); + } else + bitMap[bit/BITS_OF_UINT] |= 1 << (bit % BITS_OF_UINT); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Return number of bit which is set to 1 in the given bitmap. + * The bitmap should be unsigned int based, which means that this function + * doesn't support other format bitmap, e.g. char array or short array + * + * @param[in] bitMap bitmap array + * @param[in] bitMapSize bytes of bitmap + * + * @return number of bit which is set to 1 + */ +/*----------------------------------------------------------------------------*/ + +uint32_t scanCountBits(IN uint32_t bitMap[], IN uint32_t bitMapSize) +{ + uint32_t count = 0; + uint32_t value; + int32_t arrayLen = bitMapSize/sizeof(uint32_t); + int32_t i; + + for (i = arrayLen - 1; i >= 0; i--) { + value = bitMap[i]; + log_dbg(SCN, TRACE, "array[%d]:%08X\n", i, value); + while (value) { + count += (value & 1); + value >>= 1; + } + } + return count; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Set scan channel to scanReqMsg. + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] u4ScanChannelNum number of input channels + * @param[in] arChannel channel list + * @param[in] fgIsOnlineScan online scan or not + * @param[out] prScanReqMsg scan request msg. Set channel number and + * channel list for output + * + * @return + */ +/*----------------------------------------------------------------------------*/ +void scanSetRequestChannel(IN struct ADAPTER *prAdapter, + IN uint32_t u4ScanChannelNum, + IN struct RF_CHANNEL_INFO arChannel[], + IN uint32_t u4ScanFlags, + IN uint8_t fgIsOnlineScan, + OUT struct MSG_SCN_SCAN_REQ_V2 *prScanReqMsg) +{ + uint32_t i, u4Channel, eBand, u4Index; + /*print channel info for debugging */ + uint32_t au4ChannelBitMap[SCAN_CHANNEL_BITMAP_ARRAY_LEN]; + struct SCAN_INFO *prScanInfo; + bool fgIsLowSpanScan = FALSE; +#if CFG_SUPPORT_FULL2PARTIAL_SCAN + uint8_t fgIsFull2Partial = FALSE; + OS_SYSTIME rCurrentTime; + + GET_CURRENT_SYSTIME(&rCurrentTime); +#endif /* CFG_SUPPORT_FULL2PARTIAL_SCAN */ + + ASSERT(u4ScanChannelNum <= MAXIMUM_OPERATION_CHANNEL_LIST); + + prScanInfo = &(prAdapter->rWifiVar.rScanInfo); + i = u4Index = 0; + kalMemZero(au4ChannelBitMap, sizeof(au4ChannelBitMap)); + fgIsLowSpanScan = (u4ScanFlags & NL80211_SCAN_FLAG_LOW_SPAN) >> 8; + +#if CFG_SUPPORT_FULL2PARTIAL_SCAN + /* fgIsCheckingFull2Partial should be true if it's an online scan. + * Next, enable full2partial if channel number to scan is + * larger than SCAN_FULL2PARTIAL_CHANNEL_NUM + */ + if (fgIsOnlineScan && (u4ScanChannelNum == 0 || + u4ScanChannelNum > SCAN_FULL2PARTIAL_CHANNEL_NUM)) { + + /* Do full scan when + * 1. did not do full scan yet OR + * 2. not APP scan and it's been 60s after last full scan + */ + if (prScanInfo->u4LastFullScanTime == 0 || + (!fgIsLowSpanScan && + (CHECK_FOR_TIMEOUT(rCurrentTime, + prScanInfo->u4LastFullScanTime, + SEC_TO_SYSTIME(CFG_SCAN_FULL2PARTIAL_PERIOD))))) { + prScanInfo->fgIsScanForFull2Partial = TRUE; + prScanInfo->ucFull2PartialSeq = prScanReqMsg->ucSeqNum; + prScanInfo->u4LastFullScanTime = rCurrentTime; + kalMemZero(prScanInfo->au4ChannelBitMap, + sizeof(prScanInfo->au4ChannelBitMap)); + log_dbg(SCN, INFO, + "Full2partial: 1st full scan start, low span=%d\n", + fgIsLowSpanScan); + } else { + log_dbg(SCN, INFO, + "Full2partial: enable full2partial, low span=%d\n", + fgIsLowSpanScan); + fgIsFull2Partial = TRUE; + } + } + + if (u4ScanChannelNum == 0) { + /* We don't have channel info when u4ScanChannelNum is 0. + * check full2partial bitmap and set scan channels + */ + uint32_t start = 1; + uint32_t end = HW_CHNL_NUM_MAX_4G_5G; + + if (prScanReqMsg->eScanChannel == SCAN_CHANNEL_2G4) + end = HW_CHNL_NUM_MAX_2G4; + else if (prScanReqMsg->eScanChannel == SCAN_CHANNEL_5G) + start = HW_CHNL_NUM_MAX_2G4 + 1; + + u4Index = 0; + /* If partial scan list are too old, do full scan */ + if (!CHECK_FOR_TIMEOUT(rCurrentTime, + prScanInfo->u4LastFullScanTime, + SEC_TO_SYSTIME(CFG_SCAN_FULL2PARTIAL_PERIOD))) { + for (u4Channel = start; u4Channel <= end; u4Channel++) { + if (scanIsBitSet(u4Channel, + prScanInfo->au4ChannelBitMap, + sizeof(prScanInfo->au4ChannelBitMap))) { + eBand = (u4Channel <= + HW_CHNL_NUM_MAX_2G4) ? + BAND_2G4 : BAND_5G; + prScanReqMsg->arChnlInfoList[u4Index]. + ucChannelNum = u4Channel; + prScanReqMsg->arChnlInfoList[u4Index]. + eBand = eBand; + scanSetBit(u4Channel, au4ChannelBitMap, + sizeof(au4ChannelBitMap)); + u4Index++; + } + } + } + + prScanReqMsg->ucChannelListNum = u4Index; + if (u4Index == 0) { + log_dbg(SCN, WARN, "No channel to scan, set to full scan\n"); + prScanReqMsg->eScanChannel = SCAN_CHANNEL_FULL; + } else + prScanReqMsg->eScanChannel = SCAN_CHANNEL_SPECIFIED; + } else +#endif /* CFG_SUPPORT_FULL2PARTIAL_SCAN */ + { + u4Index = 0; + for (i = 0; i < u4ScanChannelNum; i++) { + u4Channel = arChannel[i].ucChannelNum; + eBand = arChannel[i].eBand; + if (prScanReqMsg->eScanChannel == SCAN_CHANNEL_2G4 && + eBand != BAND_2G4) + continue; + else if (prScanReqMsg->eScanChannel == + SCAN_CHANNEL_5G && eBand != BAND_5G) + continue; +#if CFG_SUPPORT_FULL2PARTIAL_SCAN + if (fgIsFull2Partial && !scanIsBitSet(u4Channel, + prScanInfo->au4ChannelBitMap, + sizeof(prScanInfo->au4ChannelBitMap))) + continue; +#endif /* CFG_SUPPORT_FULL2PARTIAL_SCAN */ + kalMemCopy(&prScanReqMsg->arChnlInfoList[u4Index], + &arChannel[i], + sizeof(struct RF_CHANNEL_INFO)); + scanSetBit(u4Channel, au4ChannelBitMap, + sizeof(au4ChannelBitMap)); + + u4Index++; + } + if (u4Index == 0) { + log_dbg(SCN, WARN, "No channel to scan, set to full scan\n"); + prScanReqMsg->ucChannelListNum = 0; + prScanReqMsg->eScanChannel = SCAN_CHANNEL_FULL; + } else { + prScanReqMsg->ucChannelListNum = u4Index; + prScanReqMsg->eScanChannel = SCAN_CHANNEL_SPECIFIED; + } + } + + log_dbg(SCN, INFO, + "channel num(%u=>%u) %08X %08X %08X %08X %08X %08X %08X %08X\n", + u4ScanChannelNum, prScanReqMsg->ucChannelListNum, + au4ChannelBitMap[7], au4ChannelBitMap[6], + au4ChannelBitMap[5], au4ChannelBitMap[4], + au4ChannelBitMap[3], au4ChannelBitMap[2], + au4ChannelBitMap[1], au4ChannelBitMap[0]); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Find the corresponding BSS Descriptor according to given BSSID + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] aucBSSID Given BSSID. + * @param[in] fgCheckSsid Need to check SSID or not. (for multiple SSID + * with single BSSID cases) + * @param[in] prSsid Specified SSID + * + * @return Pointer to BSS Descriptor, if found. NULL, if not found + */ +/*----------------------------------------------------------------------------*/ +struct BSS_DESC * +scanSearchBssDescByBssidAndSsid(IN struct ADAPTER *prAdapter, + IN uint8_t aucBSSID[], + IN u_int8_t fgCheckSsid, + IN struct PARAM_SSID *prSsid) +{ + struct SCAN_INFO *prScanInfo; + struct LINK *prBSSDescList; + struct BSS_DESC *prBssDesc; + struct BSS_DESC *prDstBssDesc = (struct BSS_DESC *) NULL; + + ASSERT(prAdapter); + ASSERT(aucBSSID); + + prScanInfo = &(prAdapter->rWifiVar.rScanInfo); + + prBSSDescList = &prScanInfo->rBSSDescList; + + /* Search BSS Desc from current SCAN result list. */ + LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, + rLinkEntry, struct BSS_DESC) { + + if (!(EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID))) + continue; + if (fgCheckSsid == FALSE || prSsid == NULL) + return prBssDesc; + if (EQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen, + prSsid->aucSsid, prSsid->u4SsidLen)) { + return prBssDesc; + } + if (prDstBssDesc == NULL && prBssDesc->fgIsHiddenSSID == TRUE) { + prDstBssDesc = prBssDesc; + continue; + } + if (prBssDesc->eBSSType == BSS_TYPE_P2P_DEVICE) { + /* 20120206 frog: Equal BSSID but not SSID, + * SSID not hidden, SSID must be updated. + */ + COPY_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen, + prSsid->aucSsid, (uint8_t) (prSsid->u4SsidLen)); + return prBssDesc; + } + } + + return prDstBssDesc; + +} /* end of scanSearchBssDescByBssid() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Find the corresponding BSS Descriptor according to + * given Transmitter Address. + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] aucSrcAddr Given Source Address(TA). + * + * @return Pointer to BSS Descriptor, if found. NULL, if not found + */ +/*----------------------------------------------------------------------------*/ +struct BSS_DESC *scanSearchBssDescByTA(IN struct ADAPTER *prAdapter, + IN uint8_t aucSrcAddr[]) +{ + return scanSearchBssDescByTAAndSsid(prAdapter, aucSrcAddr, FALSE, NULL); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Find the corresponding BSS Descriptor according to + * given Transmitter Address. + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] aucSrcAddr Given Source Address(TA). + * @param[in] fgCheckSsid Need to check SSID or not. (for multiple SSID + * with single BSSID cases) + * @param[in] prSsid Specified SSID + * + * @return Pointer to BSS Descriptor, if found. NULL, if not found + */ +/*----------------------------------------------------------------------------*/ +struct BSS_DESC * +scanSearchBssDescByTAAndSsid(IN struct ADAPTER *prAdapter, + IN uint8_t aucSrcAddr[], + IN u_int8_t fgCheckSsid, + IN struct PARAM_SSID *prSsid) +{ + struct SCAN_INFO *prScanInfo; + struct LINK *prBSSDescList; + struct BSS_DESC *prBssDesc; + struct BSS_DESC *prDstBssDesc = (struct BSS_DESC *) NULL; + + ASSERT(prAdapter); + ASSERT(aucSrcAddr); + + prScanInfo = &(prAdapter->rWifiVar.rScanInfo); + + prBSSDescList = &prScanInfo->rBSSDescList; + + /* Search BSS Desc from current SCAN result list. */ + LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, + rLinkEntry, struct BSS_DESC) { + + if (EQUAL_MAC_ADDR(prBssDesc->aucSrcAddr, aucSrcAddr)) { + if (fgCheckSsid == FALSE || prSsid == NULL) + return prBssDesc; + if (EQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen, + prSsid->aucSsid, prSsid->u4SsidLen)) { + return prBssDesc; + } else if (prDstBssDesc == NULL + && prBssDesc->fgIsHiddenSSID == TRUE) { + prDstBssDesc = prBssDesc; + } + } + } + + return prDstBssDesc; + +} /* end of scanSearchBssDescByTA() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Find the corresponding BSS Descriptor according to + * given eBSSType, BSSID and Transmitter Address + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] eBSSType BSS Type of incoming Beacon/ProbeResp frame. + * @param[in] aucBSSID Given BSSID of Beacon/ProbeResp frame. + * @param[in] aucSrcAddr Given source address (TA) of Beacon/ProbeResp frame. + * + * @return Pointer to BSS Descriptor, if found. NULL, if not found + */ +/*----------------------------------------------------------------------------*/ +struct BSS_DESC * +scanSearchExistingBssDesc(IN struct ADAPTER *prAdapter, + IN enum ENUM_BSS_TYPE eBSSType, + IN uint8_t aucBSSID[], + IN uint8_t aucSrcAddr[]) +{ + return scanSearchExistingBssDescWithSsid(prAdapter, eBSSType, aucBSSID, + aucSrcAddr, FALSE, NULL); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Find the corresponding BSS Descriptor according to + * given eBSSType, BSSID and Transmitter Address + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] eBSSType BSS Type of incoming Beacon/ProbeResp frame. + * @param[in] aucBSSID Given BSSID of Beacon/ProbeResp frame. + * @param[in] aucSrcAddr Given source address (TA) of Beacon/ProbeResp frame. + * @param[in] fgCheckSsid Need to check SSID or not. (for multiple SSID with + * single BSSID cases) + * @param[in] prSsid Specified SSID + * + * @return Pointer to BSS Descriptor, if found. NULL, if not found + */ +/*----------------------------------------------------------------------------*/ +struct BSS_DESC * +scanSearchExistingBssDescWithSsid(IN struct ADAPTER *prAdapter, + IN enum ENUM_BSS_TYPE eBSSType, + IN uint8_t aucBSSID[], + IN uint8_t aucSrcAddr[], + IN u_int8_t fgCheckSsid, + IN struct PARAM_SSID *prSsid) +{ + struct SCAN_INFO *prScanInfo; + struct BSS_DESC *prBssDesc, *prIBSSBssDesc; + /* CASE III */ + struct LINK *prBSSDescList; + struct LINK *prFreeBSSDescList; + + ASSERT(prAdapter); + ASSERT(aucSrcAddr); + + prScanInfo = &(prAdapter->rWifiVar.rScanInfo); + + switch (eBSSType) { + case BSS_TYPE_P2P_DEVICE: + fgCheckSsid = FALSE; + /* fall through */ + case BSS_TYPE_INFRASTRUCTURE: + /* fall through */ + case BSS_TYPE_BOW_DEVICE: + prBssDesc = scanSearchBssDescByBssidAndSsid(prAdapter, + aucBSSID, fgCheckSsid, prSsid); + + /* if (eBSSType == prBssDesc->eBSSType) */ + + return prBssDesc; + case BSS_TYPE_IBSS: + prIBSSBssDesc = scanSearchBssDescByBssidAndSsid(prAdapter, + aucBSSID, fgCheckSsid, prSsid); + prBssDesc = scanSearchBssDescByTAAndSsid(prAdapter, + aucSrcAddr, fgCheckSsid, prSsid); + + /* NOTE(Kevin): + * Rules to maintain the SCAN Result: + * For AdHoc - + * CASE I We have TA1(BSSID1), but it change its + * BSSID to BSSID2 + * -> Update TA1 entry's BSSID. + * CASE II We have TA1(BSSID1), and get TA1(BSSID1) again + * -> Update TA1 entry's contain. + * CASE III We have a SCAN result TA1(BSSID1), and + * TA2(BSSID2). Sooner or later, TA2 merge into + * TA1, we get TA2(BSSID1) + * -> Remove TA2 first and then replace TA1 entry's + * TA with TA2, Still have only one entry + * of BSSID. + * CASE IV We have a SCAN result TA1(BSSID1), and another + * TA2 also merge into BSSID1. + * -> Replace TA1 entry's TA with TA2, Still have + * only one entry. + * CASE V New IBSS + * -> Add this one to SCAN result. + */ + if (prBssDesc) { + if ((!prIBSSBssDesc) || /* CASE I */ + (prBssDesc == prIBSSBssDesc)) { /* CASE II */ + + return prBssDesc; + } + + + prBSSDescList = &prScanInfo->rBSSDescList; + prFreeBSSDescList = &prScanInfo->rFreeBSSDescList; + + /* Remove this BSS Desc from the BSS Desc list */ + scanRemoveBssDescFromList(prBSSDescList, + prBssDesc, + prAdapter); + + /* Return this BSS Desc to the free BSS Desc list. */ + scanInsertBssDescToList(prFreeBSSDescList, + prBssDesc, + FALSE); + + return prIBSSBssDesc; + } + + if (prIBSSBssDesc) { /* CASE IV */ + + return prIBSSBssDesc; + } + /* CASE V */ + break; /* Return NULL; */ + default: + break; + } + + return (struct BSS_DESC *) NULL; + +} /* end of scanSearchExistingBssDesc() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Delete BSS Descriptors from current list according + * to given Remove Policy. + * + * @param[in] u4RemovePolicy Remove Policy. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void scanRemoveBssDescsByPolicy(IN struct ADAPTER *prAdapter, + IN uint32_t u4RemovePolicy) +{ + struct SCAN_INFO *prScanInfo; + struct LINK *prBSSDescList; + struct LINK *prFreeBSSDescList; + struct BSS_DESC *prBssDesc; + + ASSERT(prAdapter); + + prScanInfo = &(prAdapter->rWifiVar.rScanInfo); + prBSSDescList = &prScanInfo->rBSSDescList; + prFreeBSSDescList = &prScanInfo->rFreeBSSDescList; + +#if 0 /* TODO: Remove this */ + log_dbg(SCN, TRACE, ("Before Remove - Number Of SCAN Result = %ld\n", + prBSSDescList->u4NumElem)); +#endif + + if (u4RemovePolicy & SCN_RM_POLICY_TIMEOUT) { + struct BSS_DESC *prBSSDescNext; + OS_SYSTIME rCurrentTime; + + GET_CURRENT_SYSTIME(&rCurrentTime); + + /* Search BSS Desc from current SCAN result list. */ + LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, + prBSSDescList, rLinkEntry, struct BSS_DESC) { + + if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) + && (prBssDesc->fgIsConnected + || prBssDesc->fgIsConnecting)) { + /* Don't remove the one currently we + * are connected. + */ + continue; + } + + if (CHECK_FOR_TIMEOUT(rCurrentTime, + prBssDesc->rUpdateTime, + SEC_TO_SYSTIME(wlanWfdEnabled(prAdapter) ? + SCN_BSS_DESC_STALE_SEC_WFD : + SCN_BSS_DESC_STALE_SEC))) { + +#if 0 /* TODO: Remove this */ + log_dbg(SCN, TRACE, "Remove TIMEOUT BSS DESC(%#x):MAC: " + MACSTR + ", Current Time = %08lx, Update Time = %08lx\n", + prBssDesc, + MAC2STR(prBssDesc->aucBSSID), + rCurrentTime, prBssDesc->rUpdateTime)); +#endif + scanRemoveBssDescFromList(prBSSDescList, + prBssDesc, + prAdapter); + + /* Return this BSS Desc to the + * free BSS Desc list. + */ + scanInsertBssDescToList(prFreeBSSDescList, + prBssDesc, + FALSE); + } + } + } + if (u4RemovePolicy & SCN_RM_POLICY_OLDEST_HIDDEN) { + struct BSS_DESC *prBssDescOldest = (struct BSS_DESC *) NULL; + + /* Search BSS Desc from current SCAN result list. */ + LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, + rLinkEntry, struct BSS_DESC) { + + if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) + && (prBssDesc->fgIsConnected + || prBssDesc->fgIsConnecting)) { + /* Don't remove the one currently + * we are connected. + */ + continue; + } + + if (!prBssDesc->fgIsHiddenSSID) + continue; + + if (!prBssDescOldest) { /* 1st element */ + prBssDescOldest = prBssDesc; + continue; + } + + if (TIME_BEFORE(prBssDesc->rUpdateTime, + prBssDescOldest->rUpdateTime)) + prBssDescOldest = prBssDesc; + } + + if (prBssDescOldest) { +#if 0 /* TODO: Remove this */ + log_dbg(SCN, TRACE, "Remove OLDEST HIDDEN BSS DESC(%#x): MAC: " + MACSTR + ", Update Time = %08lx\n", + prBssDescOldest, + MAC2STR(prBssDescOldest->aucBSSID), + prBssDescOldest->rUpdateTime); +#endif + scanRemoveBssDescFromList(prBSSDescList, + prBssDescOldest, + prAdapter); + + /* Return this BSS Desc to the free BSS Desc list. */ + scanInsertBssDescToList(prFreeBSSDescList, + prBssDescOldest, + FALSE); + } + } + if (u4RemovePolicy & SCN_RM_POLICY_SMART_WEAKEST) { + struct BSS_DESC *prBssDescWeakest = (struct BSS_DESC *) NULL; + struct BSS_DESC *prBssDescWeakestSameSSID + = (struct BSS_DESC *) NULL; + uint32_t u4SameSSIDCount = 0; + uint8_t j; + uint8_t fgIsSameSSID; + + /* Search BSS Desc from current SCAN result list. */ + LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, + rLinkEntry, struct BSS_DESC) { + + if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) + && (prBssDesc->fgIsConnected + || prBssDesc->fgIsConnecting)) { + /* Don't remove the one currently + * we are connected. + */ + continue; + } + + fgIsSameSSID = FALSE; + for (j = 0; j < KAL_AIS_NUM; j++) { + + struct CONNECTION_SETTINGS *prConnSettings = + aisGetConnSettings(prAdapter, j); + + if (!prConnSettings) + continue; + + if ((!prBssDesc->fgIsHiddenSSID) && + (EQUAL_SSID(prBssDesc->aucSSID, + prBssDesc->ucSSIDLen, + prConnSettings->aucSSID, + prConnSettings->ucSSIDLen))) { + + u4SameSSIDCount++; + + if (!prBssDescWeakestSameSSID) + prBssDescWeakestSameSSID = + prBssDesc; + else if (prBssDesc->ucRCPI + < prBssDescWeakestSameSSID->ucRCPI) + prBssDescWeakestSameSSID = + prBssDesc; + + fgIsSameSSID = TRUE; + } + } + + if (fgIsSameSSID && + u4SameSSIDCount + < SCN_BSS_DESC_SAME_SSID_THRESHOLD) + continue; + + if (!prBssDescWeakest) { /* 1st element */ + prBssDescWeakest = prBssDesc; + continue; + } + + if (prBssDesc->ucRCPI < prBssDescWeakest->ucRCPI) + prBssDescWeakest = prBssDesc; + + } + + if ((u4SameSSIDCount >= SCN_BSS_DESC_SAME_SSID_THRESHOLD) + && (prBssDescWeakestSameSSID)) + prBssDescWeakest = prBssDescWeakestSameSSID; + + if (prBssDescWeakest) { +#if 0 /* TODO: Remove this */ + log_dbg(SCN, TRACE, "Remove WEAKEST BSS DESC(%#x): MAC: " + MACSTR + ", Update Time = %08lx\n", + prBssDescOldest, + MAC2STR(prBssDescOldest->aucBSSID), + prBssDescOldest->rUpdateTime); +#endif + + scanRemoveBssDescFromList(prBSSDescList, + prBssDescWeakest, + prAdapter); + + /* Return this BSS Desc to the free BSS Desc list. */ + scanInsertBssDescToList(prFreeBSSDescList, + prBssDescWeakest, + FALSE); + } + } + if (u4RemovePolicy & SCN_RM_POLICY_ENTIRE) { + struct BSS_DESC *prBSSDescNext; + + LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, + prBSSDescList, rLinkEntry, struct BSS_DESC) { + + if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) + && (prBssDesc->fgIsConnected + || prBssDesc->fgIsConnecting)) { + /* Don't remove the one currently + * we are connected. + */ + continue; + } + + scanRemoveBssDescFromList(prBSSDescList, + prBssDesc, + prAdapter); + + /* Return this BSS Desc to the free BSS Desc list. */ + scanInsertBssDescToList(prFreeBSSDescList, + prBssDesc, + FALSE); + } + + } +} /* end of scanRemoveBssDescsByPolicy() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Delete BSS Descriptors from current list according to given BSSID. + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] aucBSSID Given BSSID. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void scanRemoveBssDescByBssid(IN struct ADAPTER *prAdapter, + IN uint8_t aucBSSID[]) +{ + struct SCAN_INFO *prScanInfo; + struct LINK *prBSSDescList; + struct LINK *prFreeBSSDescList; + struct BSS_DESC *prBssDesc = (struct BSS_DESC *) NULL; + struct BSS_DESC *prBSSDescNext; + uint8_t ucTargetChNum = 0; + enum ENUM_BAND eTargetBand = BAND_NULL; + + ASSERT(prAdapter); + ASSERT(aucBSSID); + + prScanInfo = &(prAdapter->rWifiVar.rScanInfo); + prBSSDescList = &prScanInfo->rBSSDescList; + prFreeBSSDescList = &prScanInfo->rFreeBSSDescList; + + /* Check if such BSS Descriptor exists in a valid list */ + LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, + rLinkEntry, struct BSS_DESC) { + + if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) { + /* Because BSS descriptor will be cleared in next step, + * so we need to keep them temporarily. + */ + ucTargetChNum = prBssDesc->ucChannelNum; + eTargetBand = prBssDesc->eBand; + + /* Clear BSS descriptor */ + scanRemoveBssDescFromList(prBSSDescList, + prBssDesc, + prAdapter); + + /* Return this BSS Desc to the free BSS Desc list. */ + scanInsertBssDescToList(prFreeBSSDescList, + prBssDesc, + FALSE); + + /* We should notify kernel to unlink BSS */ + kalRemoveBss( + prAdapter->prGlueInfo, + aucBSSID, + ucTargetChNum, + eTargetBand); + + /* BSSID is not unique, so need to traverse + * whols link-list + */ + } + } +} /* end of scanRemoveBssDescByBssid() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Delete BSS Descriptors from current list according to given + * band configuration + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] eBand Given band + * @param[in] ucBssIndex AIS - Remove IBSS/Infrastructure BSS + * BOW - Remove BOW BSS + * P2P - Remove P2P BSS + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void scanRemoveBssDescByBandAndNetwork(IN struct ADAPTER *prAdapter, + IN enum ENUM_BAND eBand, + IN uint8_t ucBssIndex) +{ + struct SCAN_INFO *prScanInfo; + struct LINK *prBSSDescList; + struct LINK *prFreeBSSDescList; + struct BSS_DESC *prBssDesc = (struct BSS_DESC *) NULL; + struct BSS_DESC *prBSSDescNext; + u_int8_t fgToRemove; + + ASSERT(prAdapter); + ASSERT(eBand <= BAND_NUM); + ASSERT(ucBssIndex <= prAdapter->ucHwBssIdNum); + + prScanInfo = &(prAdapter->rWifiVar.rScanInfo); + prBSSDescList = &prScanInfo->rBSSDescList; + prFreeBSSDescList = &prScanInfo->rFreeBSSDescList; + + if (eBand == BAND_NULL) { + /* no need to do anything, keep all scan result */ + return; + } + + /* Check if such BSS Descriptor exists in a valid list */ + LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, + rLinkEntry, struct BSS_DESC) { + fgToRemove = FALSE; + + if (prBssDesc->eBand == eBand) { + switch (GET_BSS_INFO_BY_INDEX( + prAdapter, ucBssIndex)->eNetworkType) { + case NETWORK_TYPE_AIS: + if ((prBssDesc->eBSSType + == BSS_TYPE_INFRASTRUCTURE) + || (prBssDesc->eBSSType == BSS_TYPE_IBSS)) { + fgToRemove = TRUE; + } + break; + + case NETWORK_TYPE_P2P: + if (prBssDesc->eBSSType == BSS_TYPE_P2P_DEVICE) + fgToRemove = TRUE; + break; + + case NETWORK_TYPE_BOW: + if (prBssDesc->eBSSType == BSS_TYPE_BOW_DEVICE) + fgToRemove = TRUE; + break; + + default: + ASSERT(0); + break; + } + } + + if (fgToRemove == TRUE) { + scanRemoveBssDescFromList(prBSSDescList, + prBssDesc, + prAdapter); + + /* Return this BSS Desc to the free BSS Desc list. */ + scanInsertBssDescToList(prFreeBSSDescList, + prBssDesc, + FALSE); + } + } +} /* end of scanRemoveBssDescByBand() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Clear the CONNECTION FLAG of a specified BSS Descriptor. + * + * @param[in] aucBSSID Given BSSID. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void scanRemoveConnFlagOfBssDescByBssid(IN struct ADAPTER *prAdapter, + IN uint8_t aucBSSID[], + IN uint8_t ucBssIndex) +{ + struct SCAN_INFO *prScanInfo; + struct LINK *prBSSDescList; + struct BSS_DESC *prBssDesc = (struct BSS_DESC *) NULL; + + ASSERT(prAdapter); + ASSERT(aucBSSID); + + prScanInfo = &(prAdapter->rWifiVar.rScanInfo); + prBSSDescList = &prScanInfo->rBSSDescList; + + /* Search BSS Desc from current SCAN result list. */ + LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, + rLinkEntry, struct BSS_DESC) { + + if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) { + prBssDesc->fgIsConnected &= ~BIT(ucBssIndex); + prBssDesc->fgIsConnecting &= ~BIT(ucBssIndex); + + /* BSSID is not unique, so need to + * traverse whols link-list + */ + } + } +} /* end of scanRemoveConnectionFlagOfBssDescByBssid() */ + + +#if (CFG_SUPPORT_802_11V_MBSSID == 1) +/*----------------------------------------------------------------------------*/ +/*! + * @brief Allocate new BSS_DESC structure + * + * @param[in] prAdapter Pointer to the Adapter structure. + * + * @return Pointer to BSS Descriptor, if has + * free space. NULL, if has no space. + */ +/*----------------------------------------------------------------------------*/ +void scanParsingMBSSIDSubelement(IN struct ADAPTER *prAdapter, + IN struct BSS_DESC *prTransBSS, IN struct IE_MBSSID *prMbssidIe) +{ + uint8_t *pucIE; + uint16_t u2IELength, u2Offset; + uint8_t *pucProfileIE; + uint16_t u2ProfileLen, u2ProfileOffset; + struct BSS_DESC *prBssDesc; + struct IE_MBSSID_INDEX *prMbssidIdxIe; + uint8_t aucBSSID[MAC_ADDR_LEN]; + int8_t ucBssidLsb; + + if (prMbssidIe->ucMaxBSSIDIndicator == 0) /* invalid mbssid ie*/ + return; + + prTransBSS->ucMaxBSSIDIndicator = prMbssidIe->ucMaxBSSIDIndicator; + u2Offset = 0; + pucIE = &prMbssidIe->ucSubelements[0]; + u2IELength = IE_SIZE(prMbssidIe) - + OFFSET_OF(struct IE_MBSSID, ucSubelements); + IE_FOR_EACH(pucIE, u2IELength, u2Offset) + { + pucProfileIE = NULL; + /*search for each nontransmitted bssid profile*/ + if (IE_ID(pucIE) == NON_TX_BSSID_PROFILE) { + pucProfileIE = &((struct IE_HDR *)pucIE)->aucInfo[0]; + u2ProfileLen = IE_LEN(pucIE); + u2ProfileOffset = 0; + } + if (pucProfileIE == NULL) + continue; + + /*search for mbssid index ie in each profile*/ + prMbssidIdxIe = NULL; + IE_FOR_EACH(pucProfileIE, u2ProfileLen, u2ProfileOffset) { + if (IE_ID(pucProfileIE) == ELEM_ID_MBSSID_INDEX) { + prMbssidIdxIe = MBSSID_INDEX_IE(pucProfileIE); + break; + } + } + if (prMbssidIdxIe == NULL) + continue; + + /*calculate BSSID of this profile*/ + kalMemCopy(aucBSSID, &prTransBSS->aucBSSID[0], MAC_ADDR_LEN); + ucBssidLsb = aucBSSID[5] & + ((1 << prMbssidIe->ucMaxBSSIDIndicator) - 1); + aucBSSID[5] &= ~((1 << prMbssidIe->ucMaxBSSIDIndicator) - 1); + aucBSSID[5] |= (ucBssidLsb + prMbssidIdxIe->ucBSSIDIndex) % + (1 << prMbssidIe->ucMaxBSSIDIndicator); + + prBssDesc = scanSearchBssDescByBssidAndSsid(prAdapter, + aucBSSID, FALSE, NULL); + if (prBssDesc) { + prBssDesc->ucMaxBSSIDIndicator = + prMbssidIe->ucMaxBSSIDIndicator; + prBssDesc->ucMBSSIDIndex = + prMbssidIdxIe->ucBSSIDIndex; + } + } +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Allocate new BSS_DESC structure + * + * @param[in] prAdapter Pointer to the Adapter structure. + * + * @return Pointer to BSS Descriptor, if has + * free space. NULL, if has no space. + */ +/*----------------------------------------------------------------------------*/ +struct BSS_DESC *scanAllocateBssDesc(IN struct ADAPTER *prAdapter) +{ + struct SCAN_INFO *prScanInfo; + struct LINK *prFreeBSSDescList; + struct BSS_DESC *prBssDesc; + + ASSERT(prAdapter); + prScanInfo = &(prAdapter->rWifiVar.rScanInfo); + + prFreeBSSDescList = &prScanInfo->rFreeBSSDescList; + + LINK_REMOVE_HEAD(prFreeBSSDescList, prBssDesc, struct BSS_DESC *); + + if (prBssDesc) { + struct LINK *prBSSDescList; + + prBSSDescList = &prScanInfo->rBSSDescList; + + /* NOTE(Kevin): In current design, this new empty + * struct BSS_DESC will be inserted to BSSDescList immediately. + */ + scanInsertBssDescToList(prBSSDescList, + prBssDesc, + TRUE); + } + + return prBssDesc; + +} /* end of scanAllocateBssDesc() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This API parses Beacon/ProbeResp frame and insert extracted + * BSS_DESC structure with IEs into + * prAdapter->rWifiVar.rScanInfo.aucScanBuffer + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] prSwRfb Pointer to the receiving frame buffer. + * + * @return Pointer to BSS Descriptor + * NULL if the Beacon/ProbeResp frame is invalid + */ +/*----------------------------------------------------------------------------*/ +struct BSS_DESC *scanAddToBssDesc(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb) +{ + struct BSS_DESC *prBssDesc = NULL; + uint16_t u2CapInfo; + enum ENUM_BSS_TYPE eBSSType = BSS_TYPE_INFRASTRUCTURE; + + uint8_t *pucIE; + uint16_t u2IELength; + uint16_t u2Offset = 0; + + struct WLAN_BEACON_FRAME *prWlanBeaconFrame + = (struct WLAN_BEACON_FRAME *) NULL; + struct IE_SSID *prIeSsid = (struct IE_SSID *) NULL; + struct IE_SUPPORTED_RATE_IOT *prIeSupportedRate + = (struct IE_SUPPORTED_RATE_IOT *) NULL; + struct IE_EXT_SUPPORTED_RATE *prIeExtSupportedRate + = (struct IE_EXT_SUPPORTED_RATE *) NULL; + uint8_t ucHwChannelNum = 0; + uint8_t ucIeDsChannelNum = 0; + uint8_t ucIeHtChannelNum = 0; + u_int8_t fgIsValidSsid = FALSE; + struct PARAM_SSID rSsid; + uint64_t u8Timestamp; + u_int8_t fgIsNewBssDesc = FALSE; + + uint32_t i; + uint8_t ucSSIDChar; + /* PUINT_8 pucDumpIE; */ + enum ENUM_BAND eHwBand = BAND_NULL; + u_int8_t fgBandMismatch = FALSE; + uint8_t ucSubtype; + u_int8_t fgIsProbeResp = FALSE; + u_int8_t ucPowerConstraint = 0; + struct IE_COUNTRY *prCountryIE = NULL; + struct RX_DESC_OPS_T *prRxDescOps; +#if ((CFG_SUPPORT_802_11AX == 1) && (CFG_SUPPORT_HE_ER == 1)) + struct _IE_HE_OP_T *prHeOp; + struct _IE_HE_CAP_T *prHeCap; +#endif + + ASSERT(prAdapter); + ASSERT(prSwRfb); + prRxDescOps = prAdapter->chip_info->prRxDescOps; + + RX_STATUS_GET(prRxDescOps, eHwBand, get_rf_band, prSwRfb->prRxStatus); + prWlanBeaconFrame = (struct WLAN_BEACON_FRAME *) prSwRfb->pvHeader; + ucSubtype = (*(uint8_t *) (prSwRfb->pvHeader) & + MASK_FC_SUBTYPE) >> OFFSET_OF_FC_SUBTYPE; + + WLAN_GET_FIELD_16(&prWlanBeaconFrame->u2CapInfo, &u2CapInfo); + WLAN_GET_FIELD_64(&prWlanBeaconFrame->au4Timestamp[0], &u8Timestamp); + + /* decide BSS type */ + switch (u2CapInfo & CAP_INFO_BSS_TYPE) { + case CAP_INFO_ESS: + /* It can also be Group Owner of P2P Group. */ + eBSSType = BSS_TYPE_INFRASTRUCTURE; + break; + + case CAP_INFO_IBSS: + eBSSType = BSS_TYPE_IBSS; + break; + case 0: + /* The P2P Device shall set the ESS bit of + * the Capabilities field in the Probe Response fame to 0 + * and IBSS bit to 0. (3.1.2.1.1) + */ + eBSSType = BSS_TYPE_P2P_DEVICE; + break; + +#if CFG_ENABLE_BT_OVER_WIFI + /* @TODO: add rule to identify BOW beacons */ +#endif + + default: + log_dbg(SCN, WARN, "Skip unknown bss type(%u)\n", u2CapInfo); + return NULL; + } + + /* 4 <1.1> Pre-parse SSID IE and channel info */ + pucIE = prWlanBeaconFrame->aucInfoElem; + u2IELength = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) - + (uint16_t) OFFSET_OF(struct WLAN_BEACON_FRAME_BODY, aucInfoElem[0]); + + if (u2IELength > CFG_IE_BUFFER_SIZE) { + /* Give an warning msg when IE is going to be + * truncated. + */ + DBGLOG(SCN, ERROR, + "IE len(%u) > Max IE buffer size(%u), truncate IE!\n", + u2IELength, CFG_IE_BUFFER_SIZE); + u2IELength = CFG_IE_BUFFER_SIZE; + } + kalMemZero(&rSsid, sizeof(rSsid)); + IE_FOR_EACH(pucIE, u2IELength, u2Offset) { + switch (IE_ID(pucIE)) { + case ELEM_ID_SSID: + if (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID) { + ucSSIDChar = '\0'; + + /* D-Link DWL-900AP+ */ + if (IE_LEN(pucIE) == 0) + fgIsValidSsid = FALSE; + /* Cisco AP1230A - + * (IE_LEN(pucIE) == 1) + * && (SSID_IE(pucIE)->aucSSID[0] == '\0') + */ + /* Linksys WRK54G/WL520g - + * (IE_LEN(pucIE) == n) + * && (SSID_IE(pucIE)->aucSSID[0~(n-1)] == '\0') + */ + else { + for (i = 0; i < IE_LEN(pucIE); i++) { + ucSSIDChar + |= SSID_IE(pucIE) + ->aucSSID[i]; + } + + if (ucSSIDChar) + fgIsValidSsid = TRUE; + } + + /* Update SSID to BSS Descriptor only if + * SSID is not hidden. + */ + if (fgIsValidSsid == TRUE) { + COPY_SSID(rSsid.aucSsid, + rSsid.u4SsidLen, + SSID_IE(pucIE)->aucSSID, + SSID_IE(pucIE)->ucLength); + } + } + break; + case ELEM_ID_DS_PARAM_SET: + if (IE_LEN(pucIE) + == ELEM_MAX_LEN_DS_PARAMETER_SET) { + ucIeDsChannelNum + = DS_PARAM_IE(pucIE)->ucCurrChnl; + } + break; + + case ELEM_ID_HT_OP: + if (IE_LEN(pucIE) == (sizeof(struct IE_HT_OP) - 2)) + ucIeHtChannelNum = ((struct IE_HT_OP *) pucIE) + ->ucPrimaryChannel; + break; + default: + break; + } + } + + /** + * Set band mismatch flag if we receive Beacon/ProbeResp in 2.4G band, + * but the channel num in IE info is 5G, and vice versa + * We can get channel num from different IE info, we select + * ELEM_ID_DS_PARAM_SET first, and then ELEM_ID_HT_OP + * If we don't have any channel info, we set it as HW channel, which is + * the channel we get this Beacon/ProbeResp from. + */ + if (ucIeDsChannelNum > 0) { + if (ucIeDsChannelNum <= HW_CHNL_NUM_MAX_2G4) + fgBandMismatch = (eHwBand != BAND_2G4); + else if (ucIeDsChannelNum < HW_CHNL_NUM_MAX_4G_5G) + fgBandMismatch = (eHwBand != BAND_5G); + } else if (ucIeHtChannelNum > 0) { + if (ucIeHtChannelNum <= HW_CHNL_NUM_MAX_2G4) + fgBandMismatch = (eHwBand != BAND_2G4); + else if (ucIeHtChannelNum < HW_CHNL_NUM_MAX_4G_5G) + fgBandMismatch = (eHwBand != BAND_5G); + } + + if (fgBandMismatch) { + log_dbg(SCN, INFO, MACSTR "Band mismatch, HW band %d, DS chnl %d, HT chnl %d\n", + MAC2STR(prWlanBeaconFrame->aucBSSID), eHwBand, + ucIeDsChannelNum, ucIeHtChannelNum); + return NULL; + } + + /* 4 <1.2> Replace existing BSS_DESC structure or allocate a new one */ + prBssDesc = scanSearchExistingBssDescWithSsid( + prAdapter, + eBSSType, + (uint8_t *) prWlanBeaconFrame->aucBSSID, + (uint8_t *) prWlanBeaconFrame->aucSrcAddr, + fgIsValidSsid, fgIsValidSsid == TRUE ? &rSsid : NULL); + + log_dbg(SCN, TRACE, "Receive type %u in chnl %u %u %u (" MACSTR + ") valid(%u) found(%u)\n", + ucSubtype, ucIeDsChannelNum, ucIeHtChannelNum, + prSwRfb->ucChnlNum, + MAC2STR((uint8_t *)prWlanBeaconFrame->aucBSSID), fgIsValidSsid, + (prBssDesc != NULL) ? 1 : 0); + + if ((prWlanBeaconFrame->u2FrameCtrl & MASK_FRAME_TYPE) + == MAC_FRAME_PROBE_RSP) + fgIsProbeResp = TRUE; + + if (prBssDesc == (struct BSS_DESC *) NULL) { + fgIsNewBssDesc = TRUE; + + do { + /* 4 <1.2.1> First trial of allocation */ + prBssDesc = scanAllocateBssDesc(prAdapter); + if (prBssDesc) + break; + /* 4 <1.2.2> Hidden is useless, remove the oldest + * hidden ssid. (for passive scan) + */ + scanRemoveBssDescsByPolicy(prAdapter, + (SCN_RM_POLICY_EXCLUDE_CONNECTED + | SCN_RM_POLICY_OLDEST_HIDDEN + | SCN_RM_POLICY_TIMEOUT)); + + /* 4 <1.2.3> Second tail of allocation */ + prBssDesc = scanAllocateBssDesc(prAdapter); + if (prBssDesc) + break; + /* 4 <1.2.4> Remove the weakest one */ + /* If there are more than half of BSS which has the + * same ssid as connection setting, remove the weakest + * one from them. Else remove the weakest one. + */ + scanRemoveBssDescsByPolicy(prAdapter, + (SCN_RM_POLICY_EXCLUDE_CONNECTED + | SCN_RM_POLICY_SMART_WEAKEST)); + + /* 4 <1.2.5> reallocation */ + prBssDesc = scanAllocateBssDesc(prAdapter); + if (prBssDesc) + break; + /* 4 <1.2.6> no space, should not happen */ + log_dbg(SCN, WARN, "alloc new BssDesc for " + MACSTR " failed\n", + MAC2STR((uint8_t *) + prWlanBeaconFrame->aucBSSID)); + return NULL; + + } while (FALSE); + + } else { + OS_SYSTIME rCurrentTime; + + /* WCXRP00000091 */ + /* if the received strength is much weaker than + * the original one, ignore it due to it might be received + * on the folding frequency + */ + + GET_CURRENT_SYSTIME(&rCurrentTime); + + ASSERT(prSwRfb->prRxStatusGroup3); + + if (prBssDesc->eBSSType != eBSSType) { + prBssDesc->eBSSType = eBSSType; + } else if (prSwRfb->ucChnlNum != + prBssDesc->ucChannelNum + && prBssDesc->ucRCPI + > nicRxGetRcpiValueFromRxv( + prAdapter, RCPI_MODE_MAX, prSwRfb)) { + uint8_t ucRcpi = 0; + + /* for signal strength is too much weaker and + * previous beacon is not stale + */ + ASSERT(prSwRfb->prRxStatusGroup3); + ucRcpi = nicRxGetRcpiValueFromRxv(prAdapter, + RCPI_MODE_MAX, + prSwRfb); + if ((prBssDesc->ucRCPI - ucRcpi) + >= REPLICATED_BEACON_STRENGTH_THRESHOLD + && rCurrentTime - prBssDesc->rUpdateTime + <= REPLICATED_BEACON_FRESH_PERIOD) { + log_dbg(SCN, TRACE, "rssi(%u) is too much weaker and previous one(%u) is fresh\n", + ucRcpi, prBssDesc->ucRCPI); + return prBssDesc; + } + /* for received beacons too close in time domain */ + else if (rCurrentTime - prBssDesc->rUpdateTime + <= REPLICATED_BEACON_TIME_THRESHOLD) { + log_dbg(SCN, TRACE, "receive beacon/probe responses too soon(%u:%u)\n", + prBssDesc->rUpdateTime, rCurrentTime); + return prBssDesc; + } + } + + /* if Timestamp has been reset, re-generate BSS + * DESC 'cause AP should have reset itself + */ + if (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE + && u8Timestamp < prBssDesc->u8TimeStamp.QuadPart + && prBssDesc->fgIsConnecting == FALSE) { + u_int8_t fgIsConnected, fgIsConnecting; + + if (aisGetTargetBssDesc(prAdapter, AIS_DEFAULT_INDEX) + == prBssDesc) { + log_dbg(SCN, TRACE, "Timestamap reset. Reset prTargetBssDesc BSS:" + MACSTR " connected:%x connecting:%x", + MAC2STR(prBssDesc->aucBSSID), + prBssDesc->fgIsConnected, + prBssDesc->fgIsConnecting); + } + + /* set flag for indicating this is a new BSS-DESC */ + fgIsNewBssDesc = TRUE; + + /* backup 2 flags for APs which reset + * timestamp unexpectedly + */ + fgIsConnected = prBssDesc->fgIsConnected; + fgIsConnecting = prBssDesc->fgIsConnecting; + + /* Connected BSS descriptor still be used by other + * functions. Thus, we should re-initialize the BSS_DESC + * structure instead of re-allocating the BSS_DESC + * structure. + */ + scanResetBssDesc(prAdapter, prBssDesc); + + /* restore */ + prBssDesc->fgIsConnected = fgIsConnected; + prBssDesc->fgIsConnecting = fgIsConnecting; + } + } + + prBssDesc->u2RawLength = prSwRfb->u2PacketLen; + if (prBssDesc->u2RawLength > CFG_RAW_BUFFER_SIZE) { + prBssDesc->u2RawLength = CFG_RAW_BUFFER_SIZE; + /* Give an warning msg when content is going to be + * truncated. + */ + DBGLOG(SCN, WARN, + "Pkt len(%u) > Max RAW buffer size(%u), truncate it!\n", + prSwRfb->u2PacketLen, CFG_RAW_BUFFER_SIZE); + } + kalMemCopy(prBssDesc->aucRawBuf, + prWlanBeaconFrame, prBssDesc->u2RawLength); + + /* NOTE: Keep consistency of Scan Record during JOIN process */ + if (fgIsNewBssDesc == FALSE && prBssDesc->fgIsConnecting) { + log_dbg(SCN, TRACE, "we're connecting this BSS(" + MACSTR ") now, don't update it\n", + MAC2STR(prBssDesc->aucBSSID)); + return prBssDesc; + } + /* 4 <2> Get information from Fixed Fields */ + /* Update the latest BSS type information. */ + prBssDesc->eBSSType = eBSSType; + + COPY_MAC_ADDR(prBssDesc->aucSrcAddr, prWlanBeaconFrame->aucSrcAddr); + + COPY_MAC_ADDR(prBssDesc->aucBSSID, prWlanBeaconFrame->aucBSSID); + + prBssDesc->u8TimeStamp.QuadPart = u8Timestamp; + + WLAN_GET_FIELD_16(&prWlanBeaconFrame->u2BeaconInterval, + &prBssDesc->u2BeaconInterval); + + prBssDesc->u2CapInfo = u2CapInfo; + + /* 4 <2.1> Retrieve IEs for later parsing */ + u2IELength = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) - + (uint16_t) OFFSET_OF(struct WLAN_BEACON_FRAME_BODY, aucInfoElem[0]); + + if (u2IELength > CFG_IE_BUFFER_SIZE) { + u2IELength = CFG_IE_BUFFER_SIZE; + prBssDesc->fgIsIEOverflow = TRUE; + DBGLOG(SCN, WARN, "IE is truncated!\n"); + } else { + prBssDesc->fgIsIEOverflow = FALSE; + } + prBssDesc->u2IELength = u2IELength; + + if (fgIsProbeResp || fgIsValidSsid) { + kalMemCopy(prBssDesc->aucIEBuf, prWlanBeaconFrame->aucInfoElem, + u2IELength); + } + /* 4 <2.2> reset prBssDesc variables in case that AP + * has been reconfigured + */ +#if (CFG_SUPPORT_HE_ER == 1) + prBssDesc->fgIsERSUDisable = TRUE; + prBssDesc->ucDCMMaxConRx = 0; +#endif + prBssDesc->fgIsERPPresent = FALSE; + prBssDesc->fgIsHTPresent = FALSE; + prBssDesc->fgIsVHTPresent = FALSE; +#if (CFG_SUPPORT_802_11AX == 1) + if (fgEfuseCtrlAxOn == 1) + prBssDesc->fgIsHEPresent = FALSE; +#endif + prBssDesc->eSco = CHNL_EXT_SCN; + prBssDesc->fgIEWAPI = FALSE; + prBssDesc->fgIERSN = FALSE; + prBssDesc->fgIEWPA = FALSE; + + /*Reset VHT OP IE relative settings */ + prBssDesc->eChannelWidth = CW_20_40MHZ; + + prBssDesc->ucCenterFreqS1 = 0; + prBssDesc->ucCenterFreqS2 = 0; + + /* Support AP Selection */ + prBssDesc->fgExsitBssLoadIE = FALSE; + prBssDesc->fgMultiAnttenaAndSTBC = FALSE; +#if CFG_SUPPORT_MBO + prBssDesc->fgIsDisallowed = FALSE; +#endif + + if (fgIsProbeResp == FALSE) { + /* Probe response doesn't have TIM IE. Thus, we should + * reset TIM when handling beacon frame only. + */ + prBssDesc->fgTIMPresent = FALSE; + prBssDesc->ucDTIMPeriod = 0; + } + + /* The cPowerLimit should be set as invalid value while BSS description + * is reallocated + */ + if (fgIsNewBssDesc) { + prBssDesc->cPowerLimit = RLM_INVALID_POWER_LIMIT; + DBGLOG(SCN, LOUD, + "LM: New reallocated BSSDesc [" MACSTR "]\n", + MAC2STR(prBssDesc->aucBSSID)); + } + + /* 4 <3.1> Full IE parsing on SW_RFB_T */ + pucIE = prWlanBeaconFrame->aucInfoElem; + /* pucDumpIE = pucIE; */ + + IE_FOR_EACH(pucIE, u2IELength, u2Offset) { + + switch (IE_ID(pucIE)) { + case ELEM_ID_SSID: + if ((!prIeSsid) && /* NOTE(Kevin): for Atheros IOT #1 */ + (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) { + u_int8_t fgIsHiddenSSID = FALSE; + + ucSSIDChar = '\0'; + + prIeSsid = (struct IE_SSID *) pucIE; + + /* D-Link DWL-900AP+ */ + if (IE_LEN(pucIE) == 0) + fgIsHiddenSSID = TRUE; + /* Cisco AP1230A - + * (IE_LEN(pucIE) == 1) + * && (SSID_IE(pucIE)->aucSSID[0] == '\0') + */ + /* Linksys WRK54G/WL520g - + * (IE_LEN(pucIE) == n) + * && (SSID_IE(pucIE)->aucSSID[0~(n-1)] == '\0') + */ + else { + for (i = 0; i < IE_LEN(pucIE); i++) { + ucSSIDChar + |= SSID_IE(pucIE) + ->aucSSID[i]; + } + + if (!ucSSIDChar) + fgIsHiddenSSID = TRUE; + } + + /* Update SSID to BSS Descriptor only if + * SSID is not hidden. + */ + if (!fgIsHiddenSSID) { + COPY_SSID(prBssDesc->aucSSID, + prBssDesc->ucSSIDLen, + SSID_IE(pucIE)->aucSSID, + SSID_IE(pucIE)->ucLength); + } else if (fgIsProbeResp) { + /* SSID should be updated + * if it is ProbeResp + */ + kalMemZero(prBssDesc->aucSSID, + sizeof(prBssDesc->aucSSID)); + prBssDesc->ucSSIDLen = 0; + } + + } + break; + + case ELEM_ID_SUP_RATES: + /* NOTE(Kevin): Buffalo WHR-G54S's supported rate set + * IE exceed 8. + * IE_LEN(pucIE) == 12, "1(B), 2(B), 5.5(B), 6(B), 9(B), + * 11(B), 12(B), 18(B), 24(B), 36(B), 48(B), 54(B)" + */ + /* TP-LINK will set extra and incorrect ie + * with ELEM_ID_SUP_RATES + */ + if ((!prIeSupportedRate) + && (IE_LEN(pucIE) <= RATE_NUM_SW)) + prIeSupportedRate = SUP_RATES_IOT_IE(pucIE); + break; + + case ELEM_ID_TIM: + if (IE_LEN(pucIE) <= ELEM_MAX_LEN_TIM) { + prBssDesc->fgTIMPresent = TRUE; + prBssDesc->ucDTIMPeriod + = TIM_IE(pucIE)->ucDTIMPeriod; + } + break; + + case ELEM_ID_IBSS_PARAM_SET: + if (IE_LEN(pucIE) == ELEM_MAX_LEN_IBSS_PARAMETER_SET) { + prBssDesc->u2ATIMWindow + = IBSS_PARAM_IE(pucIE)->u2ATIMWindow; + } + break; + + case ELEM_ID_COUNTRY_INFO: + prCountryIE = (struct IE_COUNTRY *) pucIE; + break; + + case ELEM_ID_ERP_INFO: + if (IE_LEN(pucIE) == ELEM_MAX_LEN_ERP) + prBssDesc->fgIsERPPresent = TRUE; + break; + + case ELEM_ID_EXTENDED_SUP_RATES: + if (!prIeExtSupportedRate) + prIeExtSupportedRate = EXT_SUP_RATES_IE(pucIE); + break; + + case ELEM_ID_RSN: + if (rsnParseRsnIE(prAdapter, RSN_IE(pucIE), + &prBssDesc->rRSNInfo)) { + uint8_t i; + + prBssDesc->fgIERSN = TRUE; + prBssDesc->u2RsnCap + = prBssDesc->rRSNInfo.u2RsnCap; + + for (i = 0; i < KAL_AIS_NUM; i++) { + rsnCheckPmkidCache(prAdapter, + prBssDesc, + i); + } + } + break; + + case ELEM_ID_HT_CAP: + { + /* Support AP Selection */ + struct IE_HT_CAP *prHtCap = (struct IE_HT_CAP *)pucIE; + uint8_t ucSpatial = 0; + uint8_t i = 0; + /* end Support AP Selection */ + if (IE_LEN(pucIE) != (sizeof(struct IE_HT_CAP) - 2)) { + DBGLOG(SCN, WARN, + "HT_CAP wrong length(%d)->(%d)\n", + (sizeof(struct IE_HT_CAP) - 2), + IE_LEN(prHtCap)); + break; + } + prBssDesc->fgIsHTPresent = TRUE; + + /* Support AP Selection */ + if (prBssDesc->fgMultiAnttenaAndSTBC) + break; + + for (; i < 4; i++) { + if (prHtCap->rSupMcsSet.aucRxMcsBitmask[i] > 0) + ucSpatial++; + } + + prBssDesc->fgMultiAnttenaAndSTBC = + ((ucSpatial > 1) && + (prHtCap->u2HtCapInfo & HT_CAP_INFO_TX_STBC)); + /* end Support AP Selection */ + + break; + } + case ELEM_ID_HT_OP: + if (IE_LEN(pucIE) != (sizeof(struct IE_HT_OP) - 2)) + break; + + if ((((struct IE_HT_OP *) pucIE)->ucInfo1 + & HT_OP_INFO1_SCO) != CHNL_EXT_RES) { + prBssDesc->eSco = (enum ENUM_CHNL_EXT) + (((struct IE_HT_OP *) pucIE)->ucInfo1 + & HT_OP_INFO1_SCO); + } + break; + case ELEM_ID_VHT_CAP: + scanParseVHTCapIE(pucIE, prBssDesc); + break; + + case ELEM_ID_VHT_OP: + scanParseVHTOpIE(pucIE, prBssDesc); + break; + +#if CFG_SUPPORT_WAPI + case ELEM_ID_WAPI: + if (wapiParseWapiIE(WAPI_IE(pucIE), + &prBssDesc->rIEWAPI)) + prBssDesc->fgIEWAPI = TRUE; + break; +#endif + /* Support AP Selection */ + case ELEM_ID_BSS_LOAD: + { + struct IE_BSS_LOAD *prBssLoad = + (struct IE_BSS_LOAD *)pucIE; + if (IE_LEN(prBssLoad) != + (sizeof(struct IE_BSS_LOAD) - 2)) { + DBGLOG(SCN, WARN, + "BSS LOAD IE_LEN err(%d)->(%d)!\n", + (sizeof(struct IE_BSS_LOAD) - 2), + IE_LEN(prBssLoad)); + break; + } + + prBssDesc->u2StaCnt = prBssLoad->u2StaCnt; + prBssDesc->ucChnlUtilization = + prBssLoad->ucChnlUtilizaion; + prBssDesc->u2AvaliableAC = prBssLoad->u2AvailabeAC; + prBssDesc->fgExsitBssLoadIE = TRUE; + break; + } + /* end Support AP Selection */ + + case ELEM_ID_VENDOR: /* ELEM_ID_P2P, ELEM_ID_WMM */ + { + uint8_t ucOuiType; + uint16_t u2SubTypeVersion; + + if (rsnParseCheckForWFAInfoElem(prAdapter, + pucIE, &ucOuiType, &u2SubTypeVersion)) { + if ((ucOuiType == VENDOR_OUI_TYPE_WPA) + && (u2SubTypeVersion + == VERSION_WPA) + && (rsnParseWpaIE(prAdapter, + WPA_IE(pucIE), + &prBssDesc + ->rWPAInfo))) { + prBssDesc->fgIEWPA = TRUE; + } + } + + if (prBssDesc->fgIsVHTPresent == FALSE) + scanCheckEpigramVhtIE(pucIE, prBssDesc); +#if CFG_SUPPORT_PASSPOINT + /* since OSEN is mutual exclusion with RSN, so + * we reuse RSN here + */ + if ((pucIE[1] >= 10) + && (kalMemCmp(pucIE+2, + "\x50\x6f\x9a\x12", 4) == 0) + && (rsnParseOsenIE(prAdapter, + (struct IE_WFA_OSEN *)pucIE, + &prBssDesc->rRSNInfo))) + prBssDesc->fgIEOsen = TRUE; +#endif +#if CFG_ENABLE_WIFI_DIRECT + if (prAdapter->fgIsP2PRegistered) { + if ((p2pFuncParseCheckForP2PInfoElem( + prAdapter, pucIE, &ucOuiType)) + && (ucOuiType + == VENDOR_OUI_TYPE_P2P)) { + prBssDesc->fgIsP2PPresent + = TRUE; + } + } +#endif /* CFG_ENABLE_WIFI_DIRECT */ +#if CFG_SUPPORT_MBO + if (pucIE[1] >= 4 && + kalMemCmp(pucIE + 2, "\x50\x6f\x9a\x16", 4) == 0) { + struct IE_MBO_OCE *mbo = + (struct IE_MBO_OCE *)pucIE; + const uint8_t *disallow = NULL; + + disallow = kalFindIeMatchMask( + MBO_ATTR_ID_ASSOC_DISALLOW, + mbo->aucSubElements, + mbo->ucLength - 4, + NULL, 0, 0, NULL); + if (disallow && disallow[1] >= 1) { + prBssDesc->fgIsDisallowed = TRUE; + DBGLOG(SCN, INFO, + MACSTR " disallow reason %d\n", + MAC2STR(prBssDesc->aucBSSID), + disallow[2]); + } + } +#endif + scanCheckAdaptive11rIE(pucIE, prBssDesc); + break; + } +#if (CFG_SUPPORT_802_11AX == 1) + case ELEM_ID_RESERVED: + if (fgEfuseCtrlAxOn == 1) { +#if (CFG_SUPPORT_HE_ER == 1) + if (IE_ID_EXT(pucIE) == ELEM_EXT_ID_HE_CAP) { + prHeCap = (struct _IE_HE_CAP_T *) pucIE; + if (IE_LEN(prHeCap) == 0) { + DBGLOG(SCN, WARN, + "HE_CAP IE_LEN = 0!\n"); + break; + } + prBssDesc->fgIsHEPresent = TRUE; + prBssDesc->ucDCMMaxConRx = + HE_GET_PHY_CAP_DCM_MAX_CONSTELLATION_RX( + prHeCap->ucHePhyCap); + DBGLOG(SCN, INFO, + "ER: BSSID:" MACSTR + " SSID:%s,rx:%x\n", + MAC2STR(prBssDesc->aucBSSID), + prBssDesc->aucSSID, + prBssDesc->ucDCMMaxConRx); + } + if (IE_ID_EXT(pucIE) == ELEM_EXT_ID_HE_OP) { + prHeOp = (struct _IE_HE_OP_T *) pucIE; + if (IE_LEN(prHeOp) == 0) { + DBGLOG(SCN, WARN, + "HE_OP IE_LEN = 0!\n"); + break; + } + prBssDesc->fgIsERSUDisable = + HE_IS_ER_SU_DISABLE( + prHeOp->ucHeOpParams); + DBGLOG(SCN, INFO, + "ER: BSSID:" MACSTR + " SSID:%s,er:%x\n", + MAC2STR(prBssDesc->aucBSSID), + prBssDesc->aucSSID, + prBssDesc->fgIsERSUDisable); + } +#else + if (IE_ID_EXT(pucIE) == ELEM_EXT_ID_HE_CAP) + prBssDesc->fgIsHEPresent = TRUE; +#endif + } + break; +#endif + case ELEM_ID_PWR_CONSTRAINT: + { + struct IE_POWER_CONSTRAINT *prPwrConstraint = + (struct IE_POWER_CONSTRAINT *)pucIE; + + if (IE_LEN(pucIE) != 1) + break; + ucPowerConstraint = + prPwrConstraint->ucLocalPowerConstraint; + break; + } + case ELEM_ID_RRM_ENABLED_CAP: + if (IE_LEN(pucIE) == 5) { + /* RRM Capability IE is always 5 bytes */ + kalMemZero(prBssDesc->aucRrmCap, + sizeof(prBssDesc->aucRrmCap)); + kalMemCopy(prBssDesc->aucRrmCap, pucIE + 2, + sizeof(prBssDesc->aucRrmCap)); + } + break; +#if (CFG_SUPPORT_802_11V_MBSSID == 1) + case ELEM_ID_MBSSID: + if (MBSSID_IE(pucIE)->ucMaxBSSIDIndicator <= 0 || + MBSSID_IE(pucIE)->ucMaxBSSIDIndicator > 8) { + /* invalid Multiple BSSID ie + * (must in range 1~8) + */ + break; + } + + scanParsingMBSSIDSubelement(prAdapter, + prBssDesc, MBSSID_IE(pucIE)); + break; +#endif + + /* no default */ + } + } + + /* 4 <3.2> Save information from IEs - SSID */ + /* Update Flag of Hidden SSID for used in SEARCH STATE. */ + + /* NOTE(Kevin): in current driver, the ucSSIDLen == 0 represent + * all cases of hidden SSID. + * If the fgIsHiddenSSID == TRUE, it means we didn't get the + * ProbeResp with valid SSID. + */ + if (prBssDesc->ucSSIDLen == 0) + prBssDesc->fgIsHiddenSSID = TRUE; + else + prBssDesc->fgIsHiddenSSID = FALSE; + + /* 4 <3.3> Check rate information in related IEs. */ + if (prIeSupportedRate || prIeExtSupportedRate) { + rateGetRateSetFromIEs(prIeSupportedRate, + prIeExtSupportedRate, + &prBssDesc->u2OperationalRateSet, + &prBssDesc->u2BSSBasicRateSet, + &prBssDesc->fgIsUnknownBssBasicRate); + } + + /* 4 <4> Update information from HIF RX Header */ + { + void *prRxStatus; + uint8_t ucRxRCPI; + + prRxStatus = prSwRfb->prRxStatus; + ASSERT(prRxStatus); + + /* 4 <4.1> Get TSF comparison result */ + RX_STATUS_GET( + prRxDescOps, + prBssDesc->fgIsLargerTSF, + get_tcl, + prRxStatus); + + /* 4 <4.2> Get Band information */ + prBssDesc->eBand = eHwBand; + + /* 4 <4.2> Get channel and RCPI information */ + RX_STATUS_GET( + prRxDescOps, + ucHwChannelNum, + get_ch_num, + prRxStatus); + + ASSERT(prSwRfb->prRxStatusGroup3); + ucRxRCPI = nicRxGetRcpiValueFromRxv(prAdapter, + RCPI_MODE_MAX, prSwRfb); + if (prBssDesc->eBand == BAND_2G4) { + + /* Update RCPI if in right channel */ + + if (ucIeDsChannelNum >= 1 && ucIeDsChannelNum <= 14) { + + /* Receive Beacon/ProbeResp frame + * from adjacent channel. + */ + if ((ucIeDsChannelNum == ucHwChannelNum) + || (ucRxRCPI > prBssDesc->ucRCPI)) + prBssDesc->ucRCPI = ucRxRCPI; + /* trust channel information brought by IE */ + prBssDesc->ucChannelNum = ucIeDsChannelNum; + } else if (ucIeHtChannelNum >= 1 + && ucIeHtChannelNum <= 14) { + /* Receive Beacon/ProbeResp frame + * from adjacent channel. + */ + if ((ucIeHtChannelNum == ucHwChannelNum) + || (ucRxRCPI > prBssDesc->ucRCPI)) + prBssDesc->ucRCPI = ucRxRCPI; + /* trust channel information brought by IE */ + prBssDesc->ucChannelNum = ucIeHtChannelNum; + } else { + prBssDesc->ucRCPI = ucRxRCPI; + + prBssDesc->ucChannelNum = ucHwChannelNum; + } + } + /* 5G Band */ + else { + if (ucIeHtChannelNum >= 1 && ucIeHtChannelNum < 200) { + /* Receive Beacon/ProbeResp frame + * from adjacent channel. + */ + if ((ucIeHtChannelNum == ucHwChannelNum) + || (ucRxRCPI > prBssDesc->ucRCPI)) + prBssDesc->ucRCPI = ucRxRCPI; + /* trust channel information brought by IE */ + prBssDesc->ucChannelNum = ucIeHtChannelNum; + } else { + /* Always update RCPI */ + prBssDesc->ucRCPI = ucRxRCPI; + + prBssDesc->ucChannelNum = ucHwChannelNum; + } + } + } + + /* 4 <5> Check IE information corret or not */ + if (!rlmDomainIsValidRfSetting(prAdapter, prBssDesc->eBand, + prBssDesc->ucChannelNum, prBssDesc->eSco, + prBssDesc->eChannelWidth, + prBssDesc->ucCenterFreqS1, + prBssDesc->ucCenterFreqS2)) { +#if 0 /* TODO: Remove this */ + /* Dump IE Inforamtion */ + log_dbg(RLM, WARN, "ScanAddToBssDesc IE Information\n"); + log_dbg(RLM, WARN, "IE Length = %d\n", u2IELength); + log_mem8_dbg(RLM, WARN, pucDumpIE, u2IELength); +#endif + + /* Error Handling for Non-predicted IE - Fixed to set 20MHz */ + prBssDesc->eChannelWidth = CW_20_40MHZ; + prBssDesc->ucCenterFreqS1 = 0; + prBssDesc->ucCenterFreqS2 = 0; + prBssDesc->eSco = CHNL_EXT_SCN; + } +#if CFG_SUPPORT_802_11K + if (prCountryIE && prCountryIE->ucLength == + (sizeof(struct IE_COUNTRY) - 2)) { + uint8_t ucRemainLen = prCountryIE->ucLength - 3; + struct COUNTRY_INFO_SUBBAND_TRIPLET *prSubBand = + &prCountryIE->arCountryStr[0]; + const uint8_t ucSubBandSize = + (uint8_t)sizeof(struct COUNTRY_INFO_SUBBAND_TRIPLET); + int8_t cNewPwrLimit = RLM_INVALID_POWER_LIMIT; + + DBGLOG(SCN, LOUD, + "LM: Country IE of BSSID[" MACSTR "] is present\n", + MAC2STR(prBssDesc->aucBSSID)); + + /* Try to find a country subband base on our channel */ + while (ucRemainLen >= ucSubBandSize) { + if (prSubBand->ucFirstChnlNum < 201 && + prBssDesc->ucChannelNum >= + prSubBand->ucFirstChnlNum && + prBssDesc->ucChannelNum <= + (prSubBand->ucFirstChnlNum + + prSubBand->ucNumOfChnl - 1)) + break; + ucRemainLen -= ucSubBandSize; + prSubBand++; + } + /* Found a right country band */ + if (ucRemainLen >= ucSubBandSize) { + cNewPwrLimit = + prSubBand->cMaxTxPwrLv - ucPowerConstraint; + /* Limit Tx power changed */ + if (prBssDesc->cPowerLimit != cNewPwrLimit) { + prBssDesc->cPowerLimit = cNewPwrLimit; + DBGLOG(SCN, TRACE, + "LM: Old TxPwrLimit %d,New: CountryMax %d, Constraint %d\n", + prBssDesc->cPowerLimit, + prSubBand->cMaxTxPwrLv, + ucPowerConstraint); + /* should tell firmware to restrict tx power if + ** connected a BSS + */ + if (prBssDesc->fgIsConnected) { + if (prBssDesc->cPowerLimit != + RLM_INVALID_POWER_LIMIT) + rlmSetMaxTxPwrLimit( + prAdapter, + prBssDesc->cPowerLimit, + 1); + else + rlmSetMaxTxPwrLimit(prAdapter, + 0, 0); + } + } + } else if (prBssDesc->cPowerLimit != RLM_INVALID_POWER_LIMIT) { + DBGLOG(SCN, LOUD, + "LM: The channel of BSSID[" MACSTR + "] doesn't match with country IE, prBssDesc->cPowerLimit=%d\n", + MAC2STR(prBssDesc->aucBSSID), + prBssDesc->cPowerLimit); + prBssDesc->cPowerLimit = RLM_INVALID_POWER_LIMIT; + rlmSetMaxTxPwrLimit(prAdapter, 0, 0); + } + } else if (prBssDesc->cPowerLimit != RLM_INVALID_POWER_LIMIT) { + DBGLOG(SCN, LOUD, + "LM: Country IE of BSSID[" MACSTR + "] isn't present, prBssDesc->cPowerLimit=%d\n", + MAC2STR(prBssDesc->aucBSSID), + prBssDesc->cPowerLimit); + prBssDesc->cPowerLimit = RLM_INVALID_POWER_LIMIT; + rlmSetMaxTxPwrLimit(prAdapter, 0, 0); + } +#endif + + /* 4 <6> PHY type setting */ + prBssDesc->ucPhyTypeSet = 0; + + /* check if support 11n */ + if (prBssDesc->fgIsVHTPresent) + prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_VHT; + + if (prBssDesc->fgIsHTPresent) + prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_HT; + +#if (CFG_SUPPORT_802_11AX == 1) + if (fgEfuseCtrlAxOn == 1) { + if (prBssDesc->fgIsHEPresent) + prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_HE; + } +#endif + + /* if not 11n only */ + if (!(prBssDesc->u2BSSBasicRateSet & RATE_SET_BIT_HT_PHY)) { + if (prBssDesc->eBand == BAND_2G4) { + /* check if support 11g */ + if ((prBssDesc->u2OperationalRateSet & RATE_SET_OFDM) + || prBssDesc->fgIsERPPresent) + prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_ERP; + + /* if not 11g only */ + if (!(prBssDesc->u2BSSBasicRateSet & RATE_SET_OFDM)) { + /* check if support 11b */ + if (prBssDesc->u2OperationalRateSet + & RATE_SET_HR_DSSS) + prBssDesc->ucPhyTypeSet + |= PHY_TYPE_BIT_HR_DSSS; + } + } else { + prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_OFDM; + } + } + + /* Support AP Selection */ + /* update update-index and reset seen-probe-response */ + if (prBssDesc->u4UpdateIdx != + prAdapter->rWifiVar.rScanInfo.u4ScanUpdateIdx) { + prBssDesc->fgSeenProbeResp = FALSE; + prBssDesc->u4UpdateIdx = + prAdapter->rWifiVar.rScanInfo.u4ScanUpdateIdx; + } + + /* check if it is a probe response frame */ + if (fgIsProbeResp) + prBssDesc->fgSeenProbeResp = TRUE; + /* end Support AP Selection */ + /* 4 <7> Update BSS_DESC_T's Last Update TimeStamp. */ + if (fgIsProbeResp || fgIsValidSsid) + GET_CURRENT_SYSTIME(&prBssDesc->rUpdateTime); + +#if CFG_SUPPORT_802_11K + if (prBssDesc->fgIsConnected) + rrmUpdateBssTimeTsf(prAdapter, prBssDesc); +#endif + + return prBssDesc; +} + +/* clear all ESS scan result */ +void scanInitEssResult(struct ADAPTER *prAdapter) +{ + prAdapter->rWlanInfo.u4ScanResultEssNum = 0; + prAdapter->rWlanInfo.u4ScanDbgTimes1 = 0; + prAdapter->rWlanInfo.u4ScanDbgTimes2 = 0; + prAdapter->rWlanInfo.u4ScanDbgTimes3 = 0; + prAdapter->rWlanInfo.u4ScanDbgTimes4 = 0; + kalMemZero(prAdapter->rWlanInfo.arScanResultEss, + sizeof(prAdapter->rWlanInfo.arScanResultEss)); +} +/* print all ESS into log system once scan done + * it is useful to log that, otherwise, we have no information to + * identify if hardware has seen a specific AP, + * if user complained some AP were not found in scan result list + */ +void scanLogEssResult(struct ADAPTER *prAdapter) +{ + struct ESS_SCAN_RESULT_T *prEssResult + = &prAdapter->rWlanInfo.arScanResultEss[0]; + uint32_t u4ResultNum = prAdapter->rWlanInfo.u4ScanResultEssNum; + uint32_t u4Index = 0; + char *strbuf = NULL, *pos = NULL, *end = NULL; + int slen = 0; + u_int8_t first = TRUE; + + if (u4ResultNum == 0) { + scanlog_dbg(LOG_SCAN_DONE_D2K, INFO, "0 Bss is found, %d, %d, %d, %d\n", + prAdapter->rWlanInfo.u4ScanDbgTimes1, + prAdapter->rWlanInfo.u4ScanDbgTimes2, + prAdapter->rWlanInfo.u4ScanDbgTimes3, + prAdapter->rWlanInfo.u4ScanDbgTimes4); + return; + } + + for (u4Index = 0; u4Index < u4ResultNum; u4Index++) { + if (prEssResult[u4Index].u2SSIDLen > 0) + slen += prEssResult[u4Index].u2SSIDLen + 2; /* _ssid;*/ + } + + slen = min(slen + 1, SCAN_LOG_MSG_MAX_LEN); /* 1 for null end*/ + pos = strbuf = kalMemAlloc(slen, VIR_MEM_TYPE); + if (strbuf == NULL) { + scanlog_dbg(LOG_SCAN_DONE_D2K, INFO, "Can't allocate memory\n"); + return; + } + end = strbuf + slen; + for (u4Index = 0; u4Index < u4ResultNum; u4Index++) { + uint8_t len = prEssResult[u4Index].u2SSIDLen; + char ssid[PARAM_MAX_LEN_SSID + 1] = {0}; + + if (len == 0) + continue; + if (pos + len + 3 > end) { /* _ssid;nul */ + pos = strbuf; + if (first) { + scanlog_dbg(LOG_SCAN_DONE_D2K, INFO, + "Total:%u/%u %s", u4ResultNum, + prAdapter->rWlanInfo.u4ScanResultNum, + strbuf); + first = FALSE; + } else { + scanlog_dbg(LOG_SCAN_DONE_D2K, INFO, + "%s", strbuf); + } + } + kalStrnCpy(ssid, prEssResult[u4Index].aucSSID, sizeof(ssid)); + ssid[sizeof(ssid) - 1] = '\0'; + pos += kalSnprintf(pos, end - pos, " %s;", ssid); + } + if (pos != strbuf) { + if (first) + scanlog_dbg(LOG_SCAN_DONE_D2K, INFO, + "Total:%u/%u %s", u4ResultNum, + prAdapter->rWlanInfo.u4ScanResultNum, strbuf); + else + scanlog_dbg(LOG_SCAN_DONE_D2K, INFO, "%s", strbuf); + } + kalMemFree(strbuf, VIR_MEM_TYPE, slen); +} + +/* record all Scanned ESS, only one BSS was saved for each ESS, and AP who + * is hidden ssid was excluded. + */ +/* maximum we only support record 64 ESSes */ +static void scanAddEssResult(struct ADAPTER *prAdapter, + IN struct BSS_DESC *prBssDesc) +{ + struct ESS_SCAN_RESULT_T *prEssResult + = &prAdapter->rWlanInfo.arScanResultEss[0]; + uint32_t u4Index = 0; + + if (prBssDesc->fgIsHiddenSSID) + return; + if (prAdapter->rWlanInfo.u4ScanResultEssNum >= CFG_MAX_NUM_BSS_LIST) + return; + for (; u4Index < prAdapter->rWlanInfo.u4ScanResultEssNum; u4Index++) { + if (EQUAL_SSID(prEssResult[u4Index].aucSSID, + (uint8_t)prEssResult[u4Index].u2SSIDLen, + prBssDesc->aucSSID, prBssDesc->ucSSIDLen)) + return; + } + + COPY_SSID(prEssResult[u4Index].aucSSID, prEssResult[u4Index].u2SSIDLen, + prBssDesc->aucSSID, prBssDesc->ucSSIDLen); + COPY_MAC_ADDR(prEssResult[u4Index].aucBSSID, prBssDesc->aucBSSID); + prAdapter->rWlanInfo.u4ScanResultEssNum++; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Convert the Beacon or ProbeResp Frame in SW_RFB_T to scan + * result for query + * + * @param[in] prSwRfb Pointer to the receiving SW_RFB_T structure. + * + * @retval WLAN_STATUS_SUCCESS It is a valid Scan Result and been sent + * to the host. + * @retval WLAN_STATUS_FAILURE It is not a valid Scan Result. + */ +/*----------------------------------------------------------------------------*/ +uint32_t scanAddScanResult(IN struct ADAPTER *prAdapter, + IN struct BSS_DESC *prBssDesc, + IN struct SW_RFB *prSwRfb) +{ + struct SCAN_INFO *prScanInfo; + uint8_t aucRatesEx[PARAM_MAX_LEN_RATES_EX]; + struct WLAN_BEACON_FRAME *prWlanBeaconFrame; + uint8_t rMacAddr[PARAM_MAC_ADDR_LEN]; + struct PARAM_SSID rSsid; + enum ENUM_PARAM_NETWORK_TYPE eNetworkType; + struct PARAM_802_11_CONFIG rConfiguration; + enum ENUM_PARAM_OP_MODE eOpMode; + uint8_t ucRateLen = 0; + uint32_t i; + + ASSERT(prAdapter); + ASSERT(prSwRfb); + + prScanInfo = &(prAdapter->rWifiVar.rScanInfo); + + if (prBssDesc->eBand == BAND_2G4) { + if ((prBssDesc->u2OperationalRateSet & RATE_SET_OFDM) + || prBssDesc->fgIsERPPresent) { + eNetworkType = PARAM_NETWORK_TYPE_OFDM24; + } else { + eNetworkType = PARAM_NETWORK_TYPE_DS; + } + } else { + ASSERT(prBssDesc->eBand == BAND_5G); + eNetworkType = PARAM_NETWORK_TYPE_OFDM5; + } + + if (prBssDesc->eBSSType == BSS_TYPE_P2P_DEVICE) { + /* NOTE(Kevin): Not supported by WZC(TBD) */ + log_dbg(SCN, INFO, "Bss Desc type is P2P\n"); + return WLAN_STATUS_FAILURE; + } + + prWlanBeaconFrame = (struct WLAN_BEACON_FRAME *) prSwRfb->pvHeader; + COPY_MAC_ADDR(rMacAddr, prWlanBeaconFrame->aucBSSID); + COPY_SSID(rSsid.aucSsid, rSsid.u4SsidLen, + prBssDesc->aucSSID, prBssDesc->ucSSIDLen); + + rConfiguration.u4Length = sizeof(struct PARAM_802_11_CONFIG); + rConfiguration.u4BeaconPeriod + = (uint32_t) prWlanBeaconFrame->u2BeaconInterval; + rConfiguration.u4ATIMWindow = prBssDesc->u2ATIMWindow; + rConfiguration.u4DSConfig = nicChannelNum2Freq(prBssDesc->ucChannelNum); + rConfiguration.rFHConfig.u4Length + = sizeof(struct PARAM_802_11_CONFIG_FH); + + rateGetDataRatesFromRateSet(prBssDesc->u2OperationalRateSet, 0, + aucRatesEx, &ucRateLen); + + /* NOTE(Kevin): Set unused entries, if any, at the end of the + * array to 0 from OID_802_11_BSSID_LIST + */ + for (i = ucRateLen; i < ARRAY_SIZE(aucRatesEx); i++) + aucRatesEx[i] = 0; + + switch (prBssDesc->eBSSType) { + case BSS_TYPE_IBSS: + eOpMode = NET_TYPE_IBSS; + break; + + case BSS_TYPE_INFRASTRUCTURE: + case BSS_TYPE_P2P_DEVICE: + case BSS_TYPE_BOW_DEVICE: + default: + eOpMode = NET_TYPE_INFRA; + break; + } + + log_dbg(SCN, LOUD, "ind %s %d %d\n", prBssDesc->aucSSID, + prBssDesc->ucChannelNum, prBssDesc->ucRCPI); + + scanAddEssResult(prAdapter, prBssDesc); + if (prAdapter->rWifiVar.rScanInfo.fgSchedScanning && + test_bit(SUSPEND_FLAG_CLEAR_WHEN_RESUME, + &prAdapter->ulSuspendFlag)) { + uint8_t i = 0; + struct BSS_DESC **pprPendBssDesc + = &prScanInfo->rSchedScanParam. + aprPendingBssDescToInd[0]; + + for (; i < SCN_SSID_MATCH_MAX_NUM; i++) { + if (pprPendBssDesc[i]) + continue; + log_dbg(SCN, INFO, "indicate bss[" + MACSTR + "] before wiphy resume, need to indicate again after wiphy resume\n", + MAC2STR(prBssDesc->aucBSSID)); + pprPendBssDesc[i] = prBssDesc; + break; + } + } + + if (prBssDesc->u2RawLength != 0) { + kalIndicateBssInfo(prAdapter->prGlueInfo, + prBssDesc->aucRawBuf, + prBssDesc->u2RawLength, + prBssDesc->ucChannelNum, + RCPI_TO_dBm(prBssDesc->ucRCPI)); + } + + nicAddScanResult(prAdapter, + rMacAddr, + &rSsid, + prWlanBeaconFrame->u2CapInfo, + RCPI_TO_dBm(prBssDesc->ucRCPI), + eNetworkType, + &rConfiguration, + eOpMode, + aucRatesEx, + prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen, + (uint8_t *) ((unsigned long) (prSwRfb->pvHeader) + + WLAN_MAC_MGMT_HEADER_LEN)); + + return WLAN_STATUS_SUCCESS; + +} /* end of scanAddScanResult() */ + +u_int8_t scanCheckBssIsLegal(IN struct ADAPTER *prAdapter, + struct BSS_DESC *prBssDesc) +{ + u_int8_t fgAddToScanResult = FALSE; + enum ENUM_BAND eBand; + uint8_t ucChannel; + + ASSERT(prAdapter); + /* check the channel is in the legal doamin */ + if (rlmDomainIsLegalChannel(prAdapter, prBssDesc->eBand, + prBssDesc->ucChannelNum) == TRUE) { + /* check ucChannelNum/eBand for adjacement channel filtering */ + if (cnmAisInfraChannelFixed(prAdapter, + &eBand, &ucChannel) == TRUE && + (eBand != prBssDesc->eBand + || ucChannel != prBssDesc->ucChannelNum)) { + fgAddToScanResult = FALSE; + } else { + fgAddToScanResult = TRUE; + } + } + + return fgAddToScanResult; + +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Parse the content of given Beacon or ProbeResp Frame. + * + * @param[in] prSwRfb Pointer to the receiving SW_RFB_T structure. + * + * @retval WLAN_STATUS_SUCCESS if not report this SW_RFB_T to host + * @retval WLAN_STATUS_PENDING if report this SW_RFB_T to host as scan result + */ +/*----------------------------------------------------------------------------*/ +uint32_t scanProcessBeaconAndProbeResp(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb) +{ + struct SCAN_INFO *prScanInfo; + struct BSS_DESC *prBssDesc = (struct BSS_DESC *) NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + struct WLAN_BEACON_FRAME *prWlanBeaconFrame + = (struct WLAN_BEACON_FRAME *) NULL; +#if CFG_SLT_SUPPORT + struct SLT_INFO *prSltInfo = (struct SLT_INFO *) NULL; +#endif + uint32_t u4Idx = 0; + + ASSERT(prAdapter); + ASSERT(prSwRfb); + + prScanInfo = &(prAdapter->rWifiVar.rScanInfo); + + /* 4 <0> Ignore invalid Beacon Frame */ + if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < + (TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + + CAP_INFO_FIELD_LEN)) { + log_dbg(SCN, ERROR, "Ignore invalid Beacon Frame\n"); + return rStatus; + } + + scanResultLog(prAdapter, prSwRfb); + +#if CFG_SLT_SUPPORT + prSltInfo = &prAdapter->rWifiVar.rSltInfo; + + if (prSltInfo->fgIsDUT) { + log_dbg(P2P, INFO, "\n\rBCN: RX\n"); + prSltInfo->u4BeaconReceiveCnt++; + return WLAN_STATUS_SUCCESS; + } else { + return WLAN_STATUS_SUCCESS; + } +#endif + + prWlanBeaconFrame = (struct WLAN_BEACON_FRAME *) prSwRfb->pvHeader; + + /* 4 <1> Parse and add into BSS_DESC_T */ + prBssDesc = scanAddToBssDesc(prAdapter, prSwRfb); + prAdapter->rWlanInfo.u4ScanDbgTimes1++; + + if (prBssDesc) { + /* Full2Partial: save channel info for later scan */ + if (prScanInfo->fgIsScanForFull2Partial) { + log_dbg(SCN, TRACE, "Full2Partial: set channel=%d\n", + prBssDesc->ucChannelNum); + scanSetBit(prBssDesc->ucChannelNum, + prScanInfo->au4ChannelBitMap, + sizeof(prScanInfo->au4ChannelBitMap)); + } + + for (u4Idx = 0; u4Idx < KAL_AIS_NUM; u4Idx++) { + struct CONNECTION_SETTINGS *prConnSettings = + aisGetConnSettings(prAdapter, u4Idx); + struct BSS_INFO *prAisBssInfo = + aisGetAisBssInfo(prAdapter, u4Idx); + + /* 4 <1.1> Beacon Change Detection for Connected BSS */ + if ((prAisBssInfo != NULL) && + (prAisBssInfo->eConnectionState == + MEDIA_STATE_CONNECTED) && + ((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE + && prConnSettings->eOPMode != NET_TYPE_IBSS) + || (prBssDesc->eBSSType == BSS_TYPE_IBSS + && prConnSettings->eOPMode != NET_TYPE_INFRA)) + && EQUAL_MAC_ADDR(prBssDesc->aucBSSID, + prAisBssInfo->aucBSSID) + && EQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen, + prAisBssInfo->aucSSID, prAisBssInfo->ucSSIDLen)) { + +#if CFG_SUPPORT_DETECT_SECURITY_MODE_CHANGE + if (rsnCheckSecurityModeChanged(prAdapter, + prAisBssInfo, prBssDesc) +#if CFG_SUPPORT_WAPI + || (aisGetWapiMode(prAdapter, + u4Idx) && + !wapiPerformPolicySelection(prAdapter, + prBssDesc, u4Idx)) +#endif + ) { + + log_dbg(SCN, INFO, "Beacon security mode change detected\n"); + log_mem8_dbg(SCN, INFO, + prSwRfb->pvHeader, + prSwRfb->u2PacketLen); + if (!prConnSettings + ->fgSecModeChangeStartTimer) { + cnmTimerStartTimer(prAdapter, + aisGetSecModeChangeTimer( + prAdapter, + u4Idx), + SEC_TO_MSEC(3)); + prConnSettings + ->fgSecModeChangeStartTimer + = TRUE; + } + } else { + if (prConnSettings->fgSecModeChangeStartTimer) { + cnmTimerStopTimer(prAdapter, + aisGetSecModeChangeTimer( + prAdapter, + u4Idx)); + prConnSettings + ->fgSecModeChangeStartTimer + = FALSE; + } + } +#endif + } + /* 4 <1.1> Update AIS_BSS_INFO */ + if ((prAisBssInfo != NULL) && + ((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE && + prConnSettings->eOPMode != NET_TYPE_IBSS) + || (prBssDesc->eBSSType == BSS_TYPE_IBSS + && prConnSettings->eOPMode != NET_TYPE_INFRA))) { + if (prAisBssInfo->eConnectionState + == MEDIA_STATE_CONNECTED) { + + /* *not* checking prBssDesc->fgIsConnected + * anymore, due to Linksys AP uses " " as + * hidden SSID, and would have different + * BSS descriptor + */ + log_dbg(SCN, TRACE, "DTIMPeriod[%u] Present[%u] BSSID[" + MACSTR "]\n", + prAisBssInfo->ucDTIMPeriod, + prAisBssInfo->fgTIMPresent, + MAC2STR(prBssDesc->aucBSSID)); + if ((!prAisBssInfo->ucDTIMPeriod) && + prAisBssInfo->fgTIMPresent && + EQUAL_MAC_ADDR(prBssDesc->aucBSSID, + prAisBssInfo->aucBSSID) && + (prAisBssInfo->eCurrentOPMode + == OP_MODE_INFRASTRUCTURE) && + ((prWlanBeaconFrame->u2FrameCtrl + & MASK_FRAME_TYPE) + == MAC_FRAME_BEACON)) { + prAisBssInfo->ucDTIMPeriod + = prBssDesc->ucDTIMPeriod; + prAisBssInfo->fgTIMPresent + = prBssDesc->fgTIMPresent; + + /* Handle No TIM IE information case */ + if (!prAisBssInfo->fgTIMPresent) { + enum PARAM_POWER_MODE ePwrMode + = Param_PowerModeCAM; + + log_dbg(SCN, WARN, "IE TIM absence, set to CAM mode!\n"); + nicConfigPowerSaveProfile( + prAdapter, + prAisBssInfo-> + ucBssIndex, ePwrMode, + FALSE, + PS_CALLER_NO_TIM); + } + /* sync with firmware for + * beacon information + */ + nicPmIndicateBssConnected(prAdapter, + prAisBssInfo->ucBssIndex); + } + } +#if CFG_SUPPORT_ADHOC + if (EQUAL_SSID(prBssDesc->aucSSID, + prBssDesc->ucSSIDLen, + prConnSettings->aucSSID, + prConnSettings->ucSSIDLen) && + (prBssDesc->eBSSType == BSS_TYPE_IBSS) + && (prAisBssInfo->eCurrentOPMode + == OP_MODE_IBSS)) { + + ASSERT(prSwRfb->prRxStatusGroup3); + + ibssProcessMatchedBeacon(prAdapter, + prAisBssInfo, + prBssDesc, + nicRxGetRcpiValueFromRxv( + prAdapter, + RCPI_MODE_MAX, + prSwRfb)); + } +#endif /* CFG_SUPPORT_ADHOC */ + } + } + + rlmProcessBcn(prAdapter, + prSwRfb, + ((struct WLAN_BEACON_FRAME *) (prSwRfb->pvHeader)) + ->aucInfoElem, + (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) - + (uint16_t) (OFFSET_OF(struct WLAN_BEACON_FRAME_BODY, + aucInfoElem[0]))); + + mqmProcessBcn(prAdapter, + prSwRfb, + ((struct WLAN_BEACON_FRAME *) (prSwRfb->pvHeader)) + ->aucInfoElem, + (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) - + (uint16_t) (OFFSET_OF(struct WLAN_BEACON_FRAME_BODY, + aucInfoElem[0]))); + + prAdapter->rWlanInfo.u4ScanDbgTimes2++; + + /* 4 <3> Send SW_RFB_T to HIF when we perform SCAN for HOST */ + if (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE + || prBssDesc->eBSSType == BSS_TYPE_IBSS) { + /* for AIS, send to host */ + prAdapter->rWlanInfo.u4ScanDbgTimes3++; + if (prScanInfo->eCurrentState == SCAN_STATE_SCANNING + || prScanInfo->fgSchedScanning) { + u_int8_t fgAddToScanResult = FALSE; + + fgAddToScanResult + = scanCheckBssIsLegal(prAdapter, + prBssDesc); + prAdapter->rWlanInfo.u4ScanDbgTimes4++; + + if (fgAddToScanResult == TRUE) { + rStatus = scanAddScanResult(prAdapter, + prBssDesc, prSwRfb); + } + } + } +#if CFG_ENABLE_WIFI_DIRECT + if (prAdapter->fgIsP2PRegistered) { + scanP2pProcessBeaconAndProbeResp(prAdapter, prSwRfb, + &rStatus, prBssDesc, prWlanBeaconFrame); + } +#endif + } + + return rStatus; +} /* end of scanProcessBeaconAndProbeResp() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Search the Candidate of BSS Descriptor for JOIN(Infrastructure) or + * MERGE(AdHoc) according to current Connection Policy. + * + * \return Pointer to BSS Descriptor, if found. NULL, if not found + */ +/*----------------------------------------------------------------------------*/ +struct BSS_DESC *scanSearchBssDescByPolicy( + IN struct ADAPTER *prAdapter, IN uint8_t ucBssIndex) +{ + struct CONNECTION_SETTINGS *prConnSettings; + struct BSS_INFO *prBssInfo; + struct AIS_SPECIFIC_BSS_INFO *prAisSpecBssInfo; + struct SCAN_INFO *prScanInfo; + + struct LINK *prBSSDescList; + + struct BSS_DESC *prBssDesc = (struct BSS_DESC *) NULL; + struct BSS_DESC *prPrimaryBssDesc = (struct BSS_DESC *) NULL; + struct BSS_DESC *prCandidateBssDesc = (struct BSS_DESC *) NULL; + + struct STA_RECORD *prStaRec = (struct STA_RECORD *) NULL; + struct STA_RECORD *prPrimaryStaRec; + struct STA_RECORD *prCandidateStaRec = (struct STA_RECORD *) NULL; + + OS_SYSTIME rCurrentTime; + + /* The first one reach the check point will be our candidate */ + u_int8_t fgIsFindFirst = (u_int8_t) FALSE; + + u_int8_t fgIsFindBestRSSI = (u_int8_t) FALSE; + u_int8_t fgIsFindBestEncryptionLevel = (u_int8_t) FALSE; + /* u_int8_t fgIsFindMinChannelLoad = (u_int8_t) FALSE; */ + + /* TODO(Kevin): Support Min Channel Load */ + /* uint8_t aucChannelLoad[CHANNEL_NUM] = {0}; */ + + u_int8_t fgIsFixedChannel = (u_int8_t) FALSE; + enum ENUM_BAND eBand = BAND_2G4; + uint8_t ucChannel = 0; + uint32_t u4ScnAdhocBssDescTimeout = 0; +#if CFG_SUPPORT_NCHO + uint8_t ucRCPIStep = ROAMING_NO_SWING_RCPI_STEP; +#endif + + ASSERT(prAdapter); + + prConnSettings = + aisGetConnSettings(prAdapter, ucBssIndex); + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + + prAisSpecBssInfo = + aisGetAisSpecBssInfo(prAdapter, ucBssIndex); + + prScanInfo = &(prAdapter->rWifiVar.rScanInfo); + prBSSDescList = &prScanInfo->rBSSDescList; + + GET_CURRENT_SYSTIME(&rCurrentTime); + + /* check for fixed channel operation */ + if (prBssInfo->eNetworkType == NETWORK_TYPE_AIS) { +#if CFG_SUPPORT_CHNL_CONFLICT_REVISE + fgIsFixedChannel = + cnmAisDetectP2PChannel(prAdapter, &eBand, &ucChannel); +#else + fgIsFixedChannel = + cnmAisInfraChannelFixed(prAdapter, &eBand, &ucChannel); +#endif + } else + fgIsFixedChannel = FALSE; + +#if DBG + if (prConnSettings->ucSSIDLen < ELEM_MAX_LEN_SSID) + prConnSettings->aucSSID[prConnSettings->ucSSIDLen] = '\0'; +#endif + + log_dbg(SCN, INFO, "SEARCH: Bss Num: %d, Look for SSID: %s, " + MACSTR " Band=%d, channel=%d\n", + (uint32_t) prBSSDescList->u4NumElem, + HIDE(prConnSettings->aucSSID), + MAC2STR(prConnSettings->aucBSSID), eBand, ucChannel); + + /* 4 <1> The outer loop to search for a candidate. */ + LINK_FOR_EACH_ENTRY( + prBssDesc, prBSSDescList, rLinkEntry, struct BSS_DESC) { + + /* TODO(Kevin): Update Minimum Channel Load Information here */ + +#if 0 + log_dbg(SCN, INFO, "SEARCH: [" MACSTR "], SSID:%s\n", + MAC2STR(prBssDesc->aucBSSID), prBssDesc->aucSSID); +#endif + + /* 4 <2> Check PHY Type and attributes */ + /* 4 <2.1> Check Unsupported BSS PHY Type */ + if (!(prBssDesc->ucPhyTypeSet + & (prAdapter->rWifiVar.ucAvailablePhyTypeSet))) { + log_dbg(SCN, INFO, "SEARCH: Ignore unsupported ucPhyTypeSet = %x\n", + prBssDesc->ucPhyTypeSet); + continue; + } + /* 4 <2.2> Check if has unknown NonHT BSS Basic Rate Set. */ + if (prBssDesc->fgIsUnknownBssBasicRate) { + log_dbg(SCN, LOUD, "SEARCH: Ignore Unknown Bss Basic Rate\n"); + continue; + } + /* 4 <2.3> Check if fixed operation cases should be aware */ + if (fgIsFixedChannel == TRUE + && (prBssDesc->eBand != eBand + || prBssDesc->ucChannelNum != ucChannel)) { + log_dbg(SCN, LOUD, "SEARCH: Ignore BssBand[%d] != FixBand[%d] or BssCH[%d] != FixCH[%d]\n", + prBssDesc->eBand, eBand, + prBssDesc->ucChannelNum, ucChannel); + continue; + } + /* 4 <2.4> Check if the channel is legal under regulatory + * domain + */ + if (rlmDomainIsLegalChannel(prAdapter, prBssDesc->eBand, + prBssDesc->ucChannelNum) == FALSE) { + log_dbg(SCN, LOUD, "SEARCH: Ignore illegal CH Band[%d] CH[%d]\n", + prBssDesc->eBand, prBssDesc->ucChannelNum); + continue; + } + /* 4 <2.5> Check if this BSS_DESC_T is stale */ + u4ScnAdhocBssDescTimeout = SCN_BSS_DESC_STALE_SEC; +#if CFG_ENABLE_WIFI_DIRECT +#if CFG_SUPPORT_WFD + if (prAdapter->rWifiVar.rWfdConfigureSettings.ucWfdEnable) + u4ScnAdhocBssDescTimeout = SCN_BSS_DESC_STALE_SEC_WFD; +#endif +#endif + if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime, + SEC_TO_SYSTIME(u4ScnAdhocBssDescTimeout))) { + log_dbg(SCN, LOUD, "SEARCH: Ignore stale Bss, CurrTime[%u] BssUpdateTime[%u]\n", + rCurrentTime, prBssDesc->rUpdateTime); + continue; + } + /* 4 <3> Check if reach the excessive join retry limit */ + /* NOTE(Kevin): STA_RECORD_T is recorded by TA. */ + prStaRec = cnmGetStaRecByAddress( + prAdapter, ucBssIndex, prBssDesc->aucSrcAddr); + + /* NOTE(Kevin): + * The Status Code is the result of a Previous Connection + * Request,we use this as SCORE for choosing a proper candidate + * (Also used for compare see <6>) The Reason Code is an + * indication of the reason why AP reject us, we use this Code + * for "Reject" a SCAN result to become our candidate(Like a + * blacklist). + */ +#if 0 /* TODO(Kevin): */ + if (prStaRec + && prStaRec->u2ReasonCode != REASON_CODE_RESERVED) { + log_dbg(SCN, INFO, "SEARCH: Ignore BSS with previous Reason Code = %d\n", + prStaRec->u2ReasonCode); + continue; + } else +#endif + if (prStaRec + && prStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL) { + /* NOTE(Kevin): greedy association - after timeout, + * we'll still try to associate to the AP whose STATUS + * of conection attempt was not success. We may also use + * (ucJoinFailureCount x JOIN_RETRY_INTERVAL_SEC) for + * time bound. + */ + if ((prStaRec->ucJoinFailureCount + < JOIN_MAX_RETRY_FAILURE_COUNT) + || (CHECK_FOR_TIMEOUT(rCurrentTime, + prStaRec->rLastJoinTime, + SEC_TO_SYSTIME(JOIN_RETRY_INTERVAL_SEC) + ))) { + + /* NOTE(Kevin): Every JOIN_RETRY_INTERVAL_SEC + * interval, we can retry + * JOIN_MAX_RETRY_FAILURE_COUNT times. + */ + if (prStaRec->ucJoinFailureCount + >= JOIN_MAX_RETRY_FAILURE_COUNT) { + prStaRec->ucJoinFailureCount = 0; + } + + log_dbg(SCN, INFO, "SEARCH:Try to join BSS again,Status Code=%u(Curr=%u/Last Join=%u)\n", + prStaRec->u2StatusCode, rCurrentTime, + prStaRec->rLastJoinTime); + } else { + log_dbg(SCN, INFO, "SEARCH: Ignore BSS which reach maximum Join Retry Count = %d\n", + JOIN_MAX_RETRY_FAILURE_COUNT); + continue; + } + } + + /* 4 <4> Check for various NETWORK conditions */ + if (prBssInfo->eNetworkType == NETWORK_TYPE_AIS) { + enum ENUM_BSS_TYPE eBSSType = + prBssDesc->eBSSType; + enum ENUM_PARAM_OP_MODE eOPMode = + prConnSettings->eOPMode; + /* 4 <4.1> Check BSS Type for the corresponding + * Operation Mode in Connection Setting + */ + /* NOTE(Kevin): For NET_TYPE_AUTO_SWITCH, we will always + * pass following check. + */ + if (eOPMode == NET_TYPE_INFRA + && eBSSType != BSS_TYPE_INFRASTRUCTURE) { + log_dbg(SCN, INFO, "SEARCH: Ignore eBSSType = IBSS\n"); + continue; + } + if ((eOPMode == NET_TYPE_IBSS + || eOPMode == NET_TYPE_DEDICATED_IBSS) + && eBSSType != BSS_TYPE_IBSS) { + log_dbg(SCN, INFO, "SEARCH: Ignore eBSSType = INFRASTRUCTURE\n"); + continue; + } + /* 4 <4.2> Check AP's BSSID if OID_802_11_BSSID has been + * set. + */ + if (prConnSettings->fgIsConnByBssidIssued && + eBSSType == BSS_TYPE_INFRASTRUCTURE) { + if (UNEQUAL_MAC_ADDR(prConnSettings->aucBSSID, + prBssDesc->aucBSSID)) { + log_dbg(SCN, TRACE, "SEARCH: Ignore due to BSSID was not matched!\n"); + continue; + } + } +#if CFG_SUPPORT_ADHOC + /* 4 <4.3> Check for AdHoc Mode */ + if (eBSSType == BSS_TYPE_IBSS) { + OS_SYSTIME rCurrentTime; + + u4ScnAdhocBssDescTimeout = + SCN_ADHOC_BSS_DESC_TIMEOUT_SEC; + + /* 4 <4.3.1> Check if this SCAN record has been + * updated recently for IBSS. + */ + /* NOTE(Kevin): Because some STA may change its + * BSSID frequently after it create the IBSS - + * e.g. IPN2220, so we need to make sure we get + * the new one. For BSS, if the old record was + * matched, however it won't be able to pass the + * Join Process later. + */ + GET_CURRENT_SYSTIME(&rCurrentTime); +#if CFG_ENABLE_WIFI_DIRECT +#if CFG_SUPPORT_WFD + if (prAdapter->rWifiVar + .rWfdConfigureSettings.ucWfdEnable) { +#define __LOCAL_VAR__ SCN_ADHOC_BSS_DESC_TIMEOUT_SEC_WFD + u4ScnAdhocBssDescTimeout + = __LOCAL_VAR__; +#undef __LOCAL_VAR__ + } +#endif +#endif + if (CHECK_FOR_TIMEOUT(rCurrentTime, + prBssDesc->rUpdateTime, + SEC_TO_SYSTIME( + u4ScnAdhocBssDescTimeout))) { + log_dbg(SCN, LOUD, "SEARCH: Now(%u) Skip old record of BSS Descriptor(%u) - BSSID:[" + MACSTR "]\n", + rCurrentTime, + prBssDesc->rUpdateTime, + MAC2STR(prBssDesc->aucBSSID)); + continue; + } + + /* 4 <4.3.2> Check Peer's capability */ + if (ibssCheckCapabilityForAdHocMode(prAdapter, + prBssDesc, ucBssIndex) + == WLAN_STATUS_FAILURE) { + + log_dbg(SCN, INFO, "SEARCH: Ignore BSS DESC MAC: " + MACSTR + ", Capability is not supported for current AdHoc Mode.\n", + MAC2STR(prPrimaryBssDesc + ->aucBSSID)); + + continue; + } + + /* 4 <4.3.3> Compare TSF */ + if (prBssInfo->fgIsBeaconActivated && + UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, + prBssDesc->aucBSSID)) { + + log_dbg(SCN, LOUD, "SEARCH: prBssDesc->fgIsLargerTSF = %d\n", + prBssDesc->fgIsLargerTSF); + + if (!prBssDesc->fgIsLargerTSF) { + log_dbg(SCN, INFO, "SEARCH: Ignore BSS DESC MAC: [" + MACSTR + "], Smaller TSF\n", + MAC2STR(prBssDesc + ->aucBSSID)); + continue; + } + } + } +#endif /* CFG_SUPPORT_ADHOC */ + + } +#if 0 /* TODO(Kevin): For IBSS */ + /* 4 <2.c> Check if this SCAN record has been updated recently + * for IBSS. + */ + /* NOTE(Kevin): Because some STA may change its BSSID frequently + * after it create the IBSS, so we need to make sure we get the + * new one. For BSS, if the old record was matched, however it + * won't be able to pass the Join Process later. + */ + if (prBssDesc->eBSSType == BSS_TYPE_IBSS) { + OS_SYSTIME rCurrentTime; + + GET_CURRENT_SYSTIME(&rCurrentTime); + if (CHECK_FOR_TIMEOUT(rCurrentTime, + prBssDesc->rUpdateTime, + SEC_TO_SYSTIME( + BSS_DESC_TIMEOUT_SEC) + )){ + log_dbg(SCAN, TRACE, "Skip old record of BSS Descriptor - BSSID:[" + MACSTR "]\n\n", + MAC2STR(prBssDesc->aucBSSID)); + continue; + } + } + + if ((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) && + (prAdapter->eConnectionState + == MEDIA_STATE_CONNECTED)) { + OS_SYSTIME rCurrentTime; + + GET_CURRENT_SYSTIME(&rCurrentTime); + if (CHECK_FOR_TIMEOUT(rCurrentTime, + prBssDesc->rUpdateTime, + SEC_TO_SYSTIME(BSS_DESC_TIMEOUT_SEC))) { + log_dbg(SCAN, TRACE, "Skip old record of BSS Descriptor - BSSID:[" + MACSTR "]\n\n", + MAC2STR(prBssDesc->aucBSSID)); + continue; + } + } + + /* 4 <4B> Check for IBSS AdHoc Mode. */ + /* Skip if one or more BSS Basic Rate are not supported by + * current AdHocMode + */ + if (prPrimaryBssDesc->eBSSType == BSS_TYPE_IBSS) { + /* 4 <4B.1> Check if match the Capability of current + * IBSS AdHoc Mode. + */ + if (ibssCheckCapabilityForAdHocMode(prAdapter, + prPrimaryBssDesc) == WLAN_STATUS_FAILURE) { + + log_dbg(SCAN, TRACE, "Ignore BSS DESC MAC: " + MACSTR + ", Capability is not supported for current AdHoc Mode.\n", + MAC2STR(prPrimaryBssDesc->aucBSSID)); + + continue; + } + + /* 4 <4B.2> IBSS Merge Decision Flow for SEARCH STATE. + */ + if (prAdapter->fgIsIBSSActive && + UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, + prPrimaryBssDesc->aucBSSID)) { + + if (!fgIsLocalTSFRead) { + NIC_GET_CURRENT_TSF(prAdapter, + &rCurrentTsf); + + log_dbg(SCAN, TRACE, "\n\nCurrent TSF : %08lx-%08lx\n\n", + rCurrentTsf.u.HighPart, + rCurrentTsf.u.LowPart); + } + + if (rCurrentTsf.QuadPart + > prPrimaryBssDesc + ->u8TimeStamp.QuadPart) { + log_dbg(SCAN, TRACE, "Ignore BSS DESC MAC: [" + MACSTR"], Current BSSID: [" + MACSTR "].\n", + MAC2STR(prPrimaryBssDesc + ->aucBSSID), + MAC2STR(prBssInfo->aucBSSID)); + + log_dbg(SCAN, TRACE, "\n\nBSS's TSF : %08lx-%08lx\n\n", + prPrimaryBssDesc + ->u8TimeStamp + .u.HighPart, + prPrimaryBssDesc + ->u8TimeStamp + .u.LowPart); + + prPrimaryBssDesc->fgIsLargerTSF = FALSE; + continue; + } else { + prPrimaryBssDesc->fgIsLargerTSF = TRUE; + } + + } + } + /* 4 <5> Check the Encryption Status. */ + if (rsnPerformPolicySelection(prPrimaryBssDesc)) { + + if (prPrimaryBssDesc->ucEncLevel > 0) { + fgIsFindBestEncryptionLevel = TRUE; + + fgIsFindFirst = FALSE; + } + } else { + /* Can't pass the Encryption Status + * Check, get next one + */ + continue; + } + + /* For RSN Pre-authentication, update the PMKID canidate + * list for same SSID and encrypt status + */ + /* Update PMKID candicate list. */ + if (prAdapter->rWifiVar.rConnSettings.eAuthMode + == AUTH_MODE_WPA2) { + rsnUpdatePmkidCandidateList(prPrimaryBssDesc); + if (prAdapter->rWifiVar.rAisBssInfo + .u4PmkidCandicateCount) { + prAdapter->rWifiVar + .rAisBssInfo + .fgIndicatePMKID + = rsnCheckPmkidCandicate(); + } + } +#endif + + prPrimaryBssDesc = (struct BSS_DESC *) NULL; + + /* 4 <6> Check current Connection Policy. */ + switch (prConnSettings->eConnectionPolicy) { + case CONNECT_BY_SSID_BEST_RSSI: + /* Choose Hidden SSID to join only if + * the `fgIsEnableJoin...` is TRUE + */ + if (prAdapter->rWifiVar.fgEnableJoinToHiddenSSID + && prBssDesc->fgIsHiddenSSID) { + /* NOTE(Kevin): following if () statement + * means that If Target is hidden, then we + * won't connect when user specify + * SSID_ANY policy. + */ + if (prConnSettings->ucSSIDLen) { + prPrimaryBssDesc = prBssDesc; + + fgIsFindBestRSSI = TRUE; + } + + } else if (EQUAL_SSID(prBssDesc->aucSSID, + prBssDesc->ucSSIDLen, + prConnSettings->aucSSID, + prConnSettings->ucSSIDLen)) { + prPrimaryBssDesc = prBssDesc; + + fgIsFindBestRSSI = TRUE; + + log_dbg(SCN, LOUD, "SEARCH: Found BSS by SSID, [" + MACSTR "], SSID:%s\n", + MAC2STR(prBssDesc->aucBSSID), + HIDE(prBssDesc->aucSSID)); + } + break; + + case CONNECT_BY_SSID_ANY: + /* NOTE(Kevin): In this policy, we don't know the + * desired SSID from user, so we should exclude the + * Hidden SSID from scan list. And because we refuse + * to connect to Hidden SSID node at the beginning, so + * when the JOIN Module deal with a struct BSS_DESC + * which has fgIsHiddenSSID == TRUE, then the + * Connection Settings must be valid without doubt. + */ + if (!prBssDesc->fgIsHiddenSSID) { + prPrimaryBssDesc = prBssDesc; + + fgIsFindFirst = TRUE; + } + break; + + case CONNECT_BY_BSSID: + if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, + prConnSettings->aucBSSID)) { + + /* Make sure to match with SSID if supplied. + * Some old dualband APs share a single BSSID + * among different BSSes. + */ + if ((prBssDesc->ucSSIDLen > 0 && + prConnSettings->ucSSIDLen > 0 && + EQUAL_SSID(prBssDesc->aucSSID, + prBssDesc->ucSSIDLen, + prConnSettings->aucSSID, + prConnSettings->ucSSIDLen)) || + prConnSettings->ucSSIDLen == 0) { + log_dbg(SCN, LOUD, "%s: BSSID/SSID pair matched\n", + __func__); + prPrimaryBssDesc = prBssDesc; + } else + log_dbg(SCN, ERROR, "%s: BSSID/SSID pair unmatched (" + MACSTR + ")\n", __func__, + MAC2STR(prBssDesc->aucBSSID)); + } + break; + + default: + break; + } + + /* Primary Candidate was not found */ + if (prPrimaryBssDesc == NULL) + continue; + /* 4 <7> Check the Encryption Status. */ + if (prPrimaryBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) { +#if CFG_SUPPORT_WAPI + if (aisGetWapiMode(prAdapter, ucBssIndex)) { + if (wapiPerformPolicySelection(prAdapter, + prPrimaryBssDesc, ucBssIndex)) { + fgIsFindFirst = TRUE; + } else { + /* Can't pass the Encryption Status + * Check, get next one + */ + log_dbg(RSN, INFO, "Ignore BSS can't pass WAPI policy selection\n"); + continue; + } + } else +#endif + if (rsnPerformPolicySelection(prAdapter, + prPrimaryBssDesc, ucBssIndex)) { + if (prAisSpecBssInfo->fgCounterMeasure) { + log_dbg(RSN, INFO, "Skip while at counter measure period!!!\n"); + continue; + } + + if (prPrimaryBssDesc->ucEncLevel > 0) { + fgIsFindBestEncryptionLevel = TRUE; + + fgIsFindFirst = FALSE; + } + } else { + /* Can't pass the Encryption Status Check, + * get next one + */ + log_dbg(RSN, INFO, "Ignore BSS can't pass Encryption Status Check\n"); + continue; + } + } else { + /* Todo:: P2P and BOW Policy Selection */ + } + + prPrimaryStaRec = prStaRec; + + /* 4 <8> Compare the Candidate and the Primary Scan Record. */ + if (!prCandidateBssDesc) { + prCandidateBssDesc = prPrimaryBssDesc; + prCandidateStaRec = prPrimaryStaRec; + + /* 4 <8.1> Condition - Get the first matched one. */ + if (fgIsFindFirst) + break; + } else { + /* 4 <6D> Condition - Visible SSID win Hidden SSID. */ + if (prCandidateBssDesc->fgIsHiddenSSID) { + if (!prPrimaryBssDesc->fgIsHiddenSSID) { + /* The non Hidden SSID win. */ + prCandidateBssDesc = prPrimaryBssDesc; + + prCandidateStaRec = prPrimaryStaRec; + continue; + } + } else { + if (prPrimaryBssDesc->fgIsHiddenSSID) + continue; + } + + /* 4 <6E> Condition - Choose the one with + * better RCPI(RSSI). + */ + if (fgIsFindBestRSSI) { + /* TODO(Kevin): We shouldn't compare the actual + * value, we should allow some acceptable + * tolerance of some RSSI percentage here. + */ + log_dbg(SCN, TRACE, "Candidate [" + MACSTR + "]: uint8_t = %d, joinFailCnt=%d, Primary [" + MACSTR "]: uint8_t = %d, joinFailCnt=%d\n", + MAC2STR(prCandidateBssDesc->aucBSSID), + prCandidateBssDesc->ucRCPI, + prCandidateBssDesc->ucJoinFailureCount, + MAC2STR(prPrimaryBssDesc->aucBSSID), + prPrimaryBssDesc->ucRCPI, + prPrimaryBssDesc->ucJoinFailureCount); + + ASSERT(!(prCandidateBssDesc->fgIsConnected + && prPrimaryBssDesc->fgIsConnected)); + if (prPrimaryBssDesc->ucJoinFailureCount + > SCN_BSS_JOIN_FAIL_THRESOLD) { + /* give a chance to do join if join + * fail before + * SCN_BSS_DECRASE_JOIN_FAIL_CNT_SEC + * seconds + */ +#define __LOCAL_VAR__ \ +SCN_BSS_JOIN_FAIL_CNT_RESET_SEC + if (CHECK_FOR_TIMEOUT(rCurrentTime, + prBssDesc->rJoinFailTime, + SEC_TO_SYSTIME( + __LOCAL_VAR__))) { +#define __LOCAL_VAR2__ \ +SCN_BSS_JOIN_FAIL_RESET_STEP + + prBssDesc->ucJoinFailureCount + -= __LOCAL_VAR2__; +#undef __LOCAL_VAR2__ + + log_dbg(AIS, INFO, "decrease join fail count for Bss " + MACSTR + " to %u, timeout second %d\n", + MAC2STR( + prBssDesc->aucBSSID), + prBssDesc + ->ucJoinFailureCount, + __LOCAL_VAR__); + } +#undef __LOCAL_VAR__ + } + /* NOTE: To prevent SWING, we do roaming only + * if target AP has at least 5dBm larger + * than us. + */ +#if CFG_SUPPORT_NCHO + if (prAdapter->rNchoInfo.fgNCHOEnabled + == TRUE) { + ucRCPIStep = 2 * prAdapter + ->rNchoInfo.i4RoamDelta; + } +#endif + if (prCandidateBssDesc->fgIsConnected) { + if ((prCandidateBssDesc->ucRCPI + + ROAMING_NO_SWING_RCPI_STEP <= + prPrimaryBssDesc->ucRCPI) + && prPrimaryBssDesc + ->ucJoinFailureCount + <= SCN_BSS_JOIN_FAIL_THRESOLD) { + + prCandidateBssDesc + = prPrimaryBssDesc; + prCandidateStaRec + = prPrimaryStaRec; + continue; + } + } else if (prPrimaryBssDesc->fgIsConnected) { + if ((prCandidateBssDesc->ucRCPI < + prPrimaryBssDesc->ucRCPI + + ROAMING_NO_SWING_RCPI_STEP) + || (prCandidateBssDesc + ->ucJoinFailureCount + > SCN_BSS_JOIN_FAIL_THRESOLD)) { + + prCandidateBssDesc + = prPrimaryBssDesc; + prCandidateStaRec + = prPrimaryStaRec; + continue; + } + } else if (prPrimaryBssDesc + ->ucJoinFailureCount + > SCN_BSS_JOIN_FAIL_THRESOLD) + continue; + else if (prCandidateBssDesc + ->ucJoinFailureCount + > SCN_BSS_JOIN_FAIL_THRESOLD || + prCandidateBssDesc->ucRCPI + < prPrimaryBssDesc->ucRCPI) { + + prCandidateBssDesc = prPrimaryBssDesc; + prCandidateStaRec = prPrimaryStaRec; + continue; + } + } +#if 0 + /* If reach here, that means they have the same + * Encryption Score, and both RSSI value are close too. + */ + /* 4 <6F> Seek the minimum Channel Load for less + * interference. + */ + if (fgIsFindMinChannelLoad) { + /* ToDo:: Nothing */ + /* TODO(Kevin): Check which one has minimum + * channel load in its channel + */ + } +#endif + } + } + + return prCandidateBssDesc; + +} /* end of scanSearchBssDescByPolicy() */ + +void scanReportBss2Cfg80211(IN struct ADAPTER *prAdapter, + IN enum ENUM_BSS_TYPE eBSSType, + IN struct BSS_DESC *SpecificprBssDesc) +{ + struct SCAN_INFO *prScanInfo = NULL; + struct LINK *prBSSDescList = NULL; + struct BSS_DESC *prBssDesc = NULL; + struct RF_CHANNEL_INFO rChannelInfo; + + ASSERT(prAdapter); + + prScanInfo = &(prAdapter->rWifiVar.rScanInfo); + + prBSSDescList = &prScanInfo->rBSSDescList; + + log_dbg(SCN, TRACE, "eBSSType: %d\n", eBSSType); + + if (SpecificprBssDesc) { + { + /* check BSSID is legal channel */ + if (!scanCheckBssIsLegal(prAdapter, + SpecificprBssDesc)) { + log_dbg(SCN, TRACE, + "Remove specific SSID[%s %d]\n", + HIDE(SpecificprBssDesc->aucSSID), + SpecificprBssDesc->ucChannelNum); + return; + } + + log_dbg(SCN, TRACE, "Report specific SSID[%s]\n", + SpecificprBssDesc->aucSSID); + + if (eBSSType == BSS_TYPE_INFRASTRUCTURE) { + kalIndicateBssInfo( + prAdapter->prGlueInfo, + (uint8_t *) + SpecificprBssDesc->aucRawBuf, + SpecificprBssDesc->u2RawLength, + SpecificprBssDesc->ucChannelNum, + RCPI_TO_dBm( + SpecificprBssDesc->ucRCPI)); + } else { + + rChannelInfo.ucChannelNum + = SpecificprBssDesc->ucChannelNum; + rChannelInfo.eBand = SpecificprBssDesc->eBand; + kalP2PIndicateBssInfo(prAdapter->prGlueInfo, + (uint8_t *) + SpecificprBssDesc->aucRawBuf, + SpecificprBssDesc->u2RawLength, + &rChannelInfo, + RCPI_TO_dBm(SpecificprBssDesc->ucRCPI)); + + } + +#if CFG_ENABLE_WIFI_DIRECT + SpecificprBssDesc->fgIsP2PReport = FALSE; +#endif + } + } else { + /* Search BSS Desc from current SCAN result list. */ + LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, + rLinkEntry, struct BSS_DESC) { + /* check BSSID is legal channel */ + if (!scanCheckBssIsLegal(prAdapter, prBssDesc)) { + log_dbg(SCN, TRACE, "Remove SSID[%s %d]\n", + HIDE(prBssDesc->aucSSID), + prBssDesc->ucChannelNum); + continue; + } + + if ((prBssDesc->eBSSType == eBSSType) +#if CFG_ENABLE_WIFI_DIRECT + || ((eBSSType == BSS_TYPE_P2P_DEVICE) + && (prBssDesc->fgIsP2PReport == TRUE)) +#endif + ) { +#define TEMP_LOG_TEMPLATE "Report " MACSTR " SSID[%s %u] eBSSType[%d] " \ + "u2RawLength[%d] fgIsP2PReport[%d]\n" + log_dbg(SCN, TRACE, TEMP_LOG_TEMPLATE, + MAC2STR(prBssDesc->aucBSSID), + HIDE(prBssDesc->aucSSID), + prBssDesc->ucChannelNum, + prBssDesc->eBSSType, + prBssDesc->u2RawLength, + prBssDesc->fgIsP2PReport); +#undef TEMP_LOG_TEMPLATE + + if (eBSSType == BSS_TYPE_INFRASTRUCTURE) { + if (prBssDesc->u2RawLength != 0) { + kalIndicateBssInfo( + prAdapter->prGlueInfo, + (uint8_t *) + prBssDesc->aucRawBuf, + prBssDesc->u2RawLength, + prBssDesc->ucChannelNum, + RCPI_TO_dBm( + prBssDesc->ucRCPI)); + } + kalMemZero(prBssDesc->aucRawBuf, + CFG_RAW_BUFFER_SIZE); + prBssDesc->u2RawLength = 0; +#if CFG_ENABLE_WIFI_DIRECT + prBssDesc->fgIsP2PReport = FALSE; +#endif + } else { +#if CFG_ENABLE_WIFI_DIRECT + if ((prBssDesc->fgIsP2PReport == TRUE) + && prBssDesc->u2RawLength != 0) { +#endif + rChannelInfo.ucChannelNum + = prBssDesc + ->ucChannelNum; + rChannelInfo.eBand + = prBssDesc->eBand; + + kalP2PIndicateBssInfo( + prAdapter->prGlueInfo, + (uint8_t *) + prBssDesc->aucRawBuf, + prBssDesc->u2RawLength, + &rChannelInfo, + RCPI_TO_dBm( + prBssDesc->ucRCPI)); + + /* do not clear it then we can + * pass the bss in + * Specific report + */ +#if 0 /* TODO: Remove this */ + kalMemZero(prBssDesc->aucRawBuf, + CFG_RAW_BUFFER_SIZE); +#endif + + /* the BSS entry will not be + * cleared after scan done. + * So if we dont receive the BSS + * in next scan, we cannot pass + * it. We use u2RawLength for + * the purpose. + */ +#if 0 + prBssDesc->u2RawLength = 0; +#endif + +#if CFG_ENABLE_WIFI_DIRECT + prBssDesc->fgIsP2PReport + = FALSE; + } +#endif + } + } + + } + p2pFunCalAcsChnScores(prAdapter); + } + +} + +#if CFG_SUPPORT_PASSPOINT +/*----------------------------------------------------------------------------*/ +/*! + * @brief Find the corresponding BSS Descriptor according to given BSSID + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] aucBSSID Given BSSID. + * @param[in] fgCheckSsid Need to check SSID or not. (for multiple SSID + * with single BSSID cases) + * @param[in] prSsid Specified SSID + * + * @return Pointer to BSS Descriptor, if found. NULL, if not found + */ +/*----------------------------------------------------------------------------*/ +struct BSS_DESC *scanSearchBssDescByBssidAndLatestUpdateTime( + IN struct ADAPTER *prAdapter, IN uint8_t aucBSSID[]) +{ + struct SCAN_INFO *prScanInfo; + struct LINK *prBSSDescList; + struct BSS_DESC *prBssDesc; + struct BSS_DESC *prDstBssDesc = (struct BSS_DESC *) NULL; + OS_SYSTIME rLatestUpdateTime = 0; + + ASSERT(prAdapter); + ASSERT(aucBSSID); + + prScanInfo = &(prAdapter->rWifiVar.rScanInfo); + + prBSSDescList = &prScanInfo->rBSSDescList; + + /* Search BSS Desc from current SCAN result list. */ + LINK_FOR_EACH_ENTRY( + prBssDesc, prBSSDescList, rLinkEntry, struct BSS_DESC) { + + if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) { + if (!rLatestUpdateTime + || CHECK_FOR_EXPIRATION(prBssDesc->rUpdateTime, + rLatestUpdateTime)) { + prDstBssDesc = prBssDesc; + COPY_SYSTIME(rLatestUpdateTime, + prBssDesc->rUpdateTime); + } + } + } + + return prDstBssDesc; + +} /* end of scanSearchBssDescByBssid() */ + +#endif /* CFG_SUPPORT_PASSPOINT */ + +#if CFG_SUPPORT_AGPS_ASSIST +void scanReportScanResultToAgps(struct ADAPTER *prAdapter) +{ + struct LINK *prBSSDescList = + &prAdapter->rWifiVar.rScanInfo.rBSSDescList; + struct BSS_DESC *prBssDesc = NULL; + struct AGPS_AP_LIST *prAgpsApList = + kalMemAlloc(sizeof(struct AGPS_AP_LIST), VIR_MEM_TYPE); + struct AGPS_AP_INFO *prAgpsInfo = &prAgpsApList->arApInfo[0]; + struct SCAN_INFO *prScanInfo = &prAdapter->rWifiVar.rScanInfo; + uint8_t ucIndex = 0; + + LINK_FOR_EACH_ENTRY( + prBssDesc, prBSSDescList, rLinkEntry, struct BSS_DESC) { + + if (prBssDesc->rUpdateTime < prScanInfo->rLastScanCompletedTime) + continue; + COPY_MAC_ADDR(prAgpsInfo->aucBSSID, prBssDesc->aucBSSID); + prAgpsInfo->ePhyType = AGPS_PHY_G; + prAgpsInfo->u2Channel = prBssDesc->ucChannelNum; + prAgpsInfo->i2ApRssi = RCPI_TO_dBm(prBssDesc->ucRCPI); + prAgpsInfo++; + ucIndex++; + if (ucIndex == SCN_AGPS_AP_LIST_MAX_NUM) + break; + } + prAgpsApList->ucNum = ucIndex; + GET_CURRENT_SYSTIME(&prScanInfo->rLastScanCompletedTime); + /* log_dbg(SCN, INFO, ("num of scan list:%d\n", ucIndex)); */ + kalIndicateAgpsNotify(prAdapter, AGPS_EVENT_WLAN_AP_LIST, + (uint8_t *) prAgpsApList, sizeof(struct AGPS_AP_LIST)); + kalMemFree(prAgpsApList, VIR_MEM_TYPE, sizeof(struct AGPS_AP_LIST)); +} +#endif /* CFG_SUPPORT_AGPS_ASSIST */ + +void scanReqLog(struct CMD_SCAN_REQ_V2 *prCmdScanReq) +{ + struct CMD_SCAN_REQ_V2 *req = prCmdScanReq; + char *strbuf = NULL, *pos = NULL, *end = NULL; + uint32_t slen = 0; + int i, j; + int snum[2] = {req->ucSSIDNum, req->ucSSIDExtNum}; + struct PARAM_SSID *slist[2] = {req->arSSID, req->arSSIDExtend}; + int cnum[2] = {req->ucChannelListNum, req->ucChannelListExtNum}; + struct CHANNEL_INFO *clist[2] = { + req->arChannelList, req->arChannelListExtend}; + + /* ssid and space */ + for (i = 0; i < 2; ++i) + for (j = 0; j < snum[i]; ++j) + slen += slist[i][j].u4SsidLen + 1; + + /* The length should be added 6 + 10 + 4 + 8 + 1 for the format + * ",Ssid:", * ",Ext ssid:", ",Ch:", ",Ext Ch:" and null byte. + */ + slen += 29 + 4 * (req->ucChannelListNum + req->ucChannelListExtNum); + pos = strbuf = kalMemAlloc(slen, VIR_MEM_TYPE); + if (strbuf == NULL) { + scanlog_dbg(LOG_SCAN_REQ_K2D, INFO, "Can't allocate memory\n"); + return; + } + end = strbuf + slen; + + for (i = 0; i < 2; ++i) { + if (snum[i] > 0) { + pos += kalSnprintf(pos, end - pos, "%s", + i == 0 ? ",Ssid:" : ",Ext Ssid:"); + for (j = 0; j < snum[i]; ++j) { + char ssid[PARAM_MAX_LEN_SSID + 1] = {0}; + + kalStrnCpy(ssid, + slist[i][j].aucSsid, sizeof(ssid)); + ssid[sizeof(ssid) - 1] = '\0'; + pos += kalSnprintf(pos, end - pos, " %s", ssid); + } + } + } + + for (i = 0; i < 2; ++i) { + if (cnum[i] > 0) { + pos += kalSnprintf(pos, end - pos, "%s", + i == 0 ? ",Ch:" : ",Ext Ch:"); + for (j = 0; j < cnum[i]; ++j) + pos += kalSnprintf(pos, end - pos, " %u", + clist[i][j].ucChannelNum % 1000); + } + } +#define TEMP_LOG_TEMPLATE \ + "ScanReqV2: ScanType=%d,BSS=%u,SSIDType=%d,Num=%u,Ext=%u," \ + "ChannelType=%d,Num=%d,Ext=%u,Seq=%u,Ver=%u,Dw=%u,Min=%u," \ + "Func=0x%X,Mac="MACSTR"%s\n" + scanlog_dbg(LOG_SCAN_REQ_D2F, INFO, TEMP_LOG_TEMPLATE, + prCmdScanReq->ucScanType, + prCmdScanReq->ucBssIndex, + prCmdScanReq->ucSSIDType, + prCmdScanReq->ucSSIDNum, + prCmdScanReq->ucSSIDExtNum, + prCmdScanReq->ucChannelType, + prCmdScanReq->ucChannelListNum, + prCmdScanReq->ucChannelListExtNum, + prCmdScanReq->ucSeqNum, prCmdScanReq->auVersion[0], + prCmdScanReq->u2ChannelDwellTime, + prCmdScanReq->u2ChannelMinDwellTime, + prCmdScanReq->ucScnFuncMask, + MAC2STR(prCmdScanReq->aucRandomMac), + strbuf != pos ? strbuf : ""); +#undef TEMP_LOG_TEMPLATE + kalMemFree(strbuf, VIR_MEM_TYPE, slen); +} + +void scanResultLog(struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb) +{ + struct WLAN_BEACON_FRAME *pFrame = + (struct WLAN_BEACON_FRAME *) prSwRfb->pvHeader; + KAL_SPIN_LOCK_DECLARATION(); + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BSSLIST_FW); + scanLogCacheAddBSS( + &(prAdapter->rWifiVar.rScanInfo.rScanLogCache.rBSSListFW), + prAdapter->rWifiVar.rScanInfo.rScanLogCache.arBSSListBufFW, + LOG_SCAN_RESULT_F2D, + pFrame->aucBSSID, + pFrame->u2SeqCtrl); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BSSLIST_FW); +} + +void scanLogCacheAddBSS(struct LINK *prList, + struct SCAN_LOG_ELEM_BSS *prListBuf, + enum ENUM_SCAN_LOG_PREFIX prefix, + uint8_t bssId[], uint16_t seq) +{ + struct SCAN_LOG_ELEM_BSS *pSavedBss = NULL; + struct SCAN_LOG_ELEM_BSS *pBss = NULL; + + if (LINK_IS_INVALID(prList)) { + LINK_INITIALIZE(prList); + } + + LINK_FOR_EACH_ENTRY(pSavedBss, prList, + rLinkEntry, struct SCAN_LOG_ELEM_BSS) { + if (pSavedBss && bssId) { + if (EQUAL_MAC_ADDR(pSavedBss->aucBSSID, bssId)) + return; + } else { + scanlog_dbg(prefix, ERROR, + "pSavedBss(0x%x) or bssid(0x%x) is NULL\n", + pSavedBss, bssId); + return; + } + } + + if (prList->u4NumElem < SCAN_LOG_BUFF_SIZE) { + if (prListBuf != NULL) { + pBss = &(prListBuf[prList->u4NumElem]); + } else { + scanlog_dbg(prefix, INFO, "Buffer is NULL\n"); + return; + } + } else { + scanlog_dbg(prefix, INFO, "Need more buffer\n"); + return; + } + kalMemZero(pBss, sizeof(struct SCAN_LOG_ELEM_BSS)); + + COPY_MAC_ADDR(pBss->aucBSSID, bssId); + pBss->u2SeqCtrl = seq; + + LINK_INSERT_TAIL(prList, &(pBss->rLinkEntry)); +} + +void scanLogCacheFlushBSS(struct LINK *prList, enum ENUM_SCAN_LOG_PREFIX prefix) +{ + char arlogBuf[SCAN_LOG_MSG_MAX_LEN]; + uint32_t idx = 0; + struct SCAN_LOG_ELEM_BSS *pBss = NULL; +#if CFG_SHOW_FULL_MACADDR + /* XXXXXXXXXXXX */ + const uint8_t dataLen = 12; +#else + /* XXXXsumXX */ + const uint8_t dataLen = 9; +#endif + + if (LINK_IS_INVALID(prList)) { + LINK_INITIALIZE(prList); + } + + if (LINK_IS_EMPTY(prList)) + return; + + kalMemZero(arlogBuf, SCAN_LOG_MSG_MAX_LEN); + /* The maximum characters of uint32_t could be 10. Thus, the + * mininum size should be 10+3 for the format "%u: ". + */ + if (dataLen + 1 > SCAN_LOG_MSG_MAX_LEN) { + scanlog_dbg(prefix, INFO, "Scan log buffer is too small.\n"); + while (!LINK_IS_EMPTY(prList)) { + LINK_REMOVE_HEAD(prList, + pBss, struct SCAN_LOG_ELEM_BSS *); + } + return; + } + idx += kalSnprintf(arlogBuf, SCAN_LOG_MSG_MAX_LEN, "%u: ", + prList->u4NumElem); + + while (!LINK_IS_EMPTY(prList)) { + if (idx+dataLen+1 > SCAN_LOG_MSG_MAX_LEN) { + arlogBuf[idx] = 0; /* terminating null byte */ + if (prefix != LOG_SCAN_D2D) + scanlog_dbg(prefix, INFO, "%s\n", arlogBuf); + idx = 0; + } + + LINK_REMOVE_HEAD(prList, + pBss, struct SCAN_LOG_ELEM_BSS *); + +#if CFG_SHOW_FULL_MACADDR + idx += kalSnprintf(arlogBuf+idx, dataLen+1, + "%02x%02x%02x%02x%02x%02x", + ((uint8_t *)pBss->aucBSSID)[0], + ((uint8_t *)pBss->aucBSSID)[1], + ((uint8_t *)pBss->aucBSSID)[2], + ((uint8_t *)pBss->aucBSSID)[3], + ((uint8_t *)pBss->aucBSSID)[4], + ((uint8_t *)pBss->aucBSSID)[5]); +#else + idx += kalSnprintf(arlogBuf+idx, dataLen+1, + "%02x%02x%03x%02x", + ((uint8_t *)pBss->aucBSSID)[0], + ((uint8_t *)pBss->aucBSSID)[1], + ((uint8_t *)pBss->aucBSSID)[2] + + ((uint8_t *)pBss->aucBSSID)[3] + + ((uint8_t *)pBss->aucBSSID)[4], + ((uint8_t *)pBss->aucBSSID)[5]); +#endif + + } + if (idx != 0) { + arlogBuf[idx] = 0; /* terminating null byte */ + if (prefix != LOG_SCAN_D2D) + scanlog_dbg(prefix, INFO, "%s\n", arlogBuf); + idx = 0; + } +} + +void scanLogCacheFlushAll(struct ADAPTER *prAdapter, + struct SCAN_LOG_CACHE *prScanLogCache, + enum ENUM_SCAN_LOG_PREFIX prefix) +{ + KAL_SPIN_LOCK_DECLARATION(); + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BSSLIST_FW); + scanLogCacheFlushBSS(&(prScanLogCache->rBSSListFW), + prefix); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BSSLIST_FW); + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BSSLIST_CFG); + scanLogCacheFlushBSS(&(prScanLogCache->rBSSListCFG), + prefix); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BSSLIST_CFG); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Remove and clean BSS Descriptors from the list. + * + * @param[in] prBSSDescList Pointer to the LINK structure. + * @param[in] prBssDesc Pointer to the BSS_DESC structure. + * @param[in] prAdapter Pointer to the Adapter structure. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void scanRemoveBssDescFromList(IN struct LINK *prBSSDescList, + IN struct BSS_DESC *prBssDesc, + IN struct ADAPTER *prAdapter) +{ + if (prAdapter != NULL && prBssDesc != NULL) { + uint8_t j; + + /* Support AP Selection */ + if (!prBssDesc->prBlack) + aisQueryBlackList(prAdapter, prBssDesc); + + /* Remove this BSS Desc from the Ess Desc List */ + for (j = 0; j < KAL_AIS_NUM; j++) { + struct AIS_SPECIFIC_BSS_INFO *prSpecBssInfo = + aisGetAisSpecBssInfo( + prAdapter, j); + struct LINK *prEssList; + + if (!prSpecBssInfo) + continue; + prEssList = + &prSpecBssInfo->rCurEssLink; + if (!prEssList) + continue; + + if (!LINK_ENTRY_IS_VALID(&prBssDesc->rLinkEntryEss[j])) + continue; + + LINK_REMOVE_KNOWN_ENTRY(prEssList, + &prBssDesc->rLinkEntryEss[j]); + } + /* end Support AP Selection */ + + /* Remove this BSS Desc from the BSS Desc list */ + if (prBSSDescList != NULL) + LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc); + } +} /* end of scanRemoveBssDescFromList() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Insert and initialize the BSS Descriptors to the list. + * + * @param[in] prBSSDescList Pointer to the LINK structure. + * @param[in] prBssDesc Pointer to the BSS_DESC structure. + * @param[in] init TRUE for initializing the BSS_DESC. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void scanInsertBssDescToList(IN struct LINK *prBSSDescList, + IN struct BSS_DESC *prBssDesc, + IN u_int8_t init) +{ + if (prBssDesc != NULL) { + if (init == TRUE) { + /* This will reset the link relationship */ + kalMemZero(prBssDesc, sizeof(struct BSS_DESC)); + +#if CFG_ENABLE_WIFI_DIRECT + LINK_INITIALIZE(&(prBssDesc->rP2pDeviceList)); + prBssDesc->fgIsP2PPresent = FALSE; +#endif /* CFG_ENABLE_WIFI_DIRECT */ + } + + /* Insert this BSS Desc to the BSS Desc list */ + if (prBSSDescList != NULL) + LINK_INSERT_TAIL(prBSSDescList, &prBssDesc->rLinkEntry); + } +} /* end of scanInsertBssDescToList() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Reset the BSS Descriptors. + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] prBssDesc Pointer to the BSS_DESC structure. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void scanResetBssDesc(IN struct ADAPTER *prAdapter, + IN struct BSS_DESC *prBssDesc) +{ + struct LINK *prBSSDescList = + &prAdapter->rWifiVar.rScanInfo.rBSSDescList; + + scanRemoveBssDescFromList(prBSSDescList, + prBssDesc, + prAdapter); + scanInsertBssDescToList(prBSSDescList, + prBssDesc, + TRUE); +} /* end of scanResetBssDesc() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Check if VHT IE exists in Vendor Epigram IE. + * + * @param[in] pucBuf Pointer to the Vendor IE. + * @param[in] prBssDesc Pointer to the BSS_DESC structure. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void scanCheckEpigramVhtIE(IN uint8_t *pucBuf, IN struct BSS_DESC *prBssDesc) +{ + uint32_t u4EpigramOui; + uint16_t u2EpigramVendorType; + struct IE_VENDOR_EPIGRAM_IE *prEpiIE; + uint8_t *pucIE; + uint16_t u2IELength; + uint16_t u2Offset = 0; + + if (pucBuf == NULL) { + DBGLOG(RLM, WARN, "[Epigram] pucBuf is NULL, skip!\n"); + return; + } + if (prBssDesc == NULL) { + DBGLOG(RLM, WARN, "[Epigram] prBssDesc is NULL, skip!\n"); + return; + } + + prEpiIE = (struct IE_VENDOR_EPIGRAM_IE *) pucBuf; + u2IELength = prEpiIE->ucLength; + WLAN_GET_FIELD_BE24(prEpiIE->aucOui, &u4EpigramOui); + WLAN_GET_FIELD_BE16(prEpiIE->aucVendorType, &u2EpigramVendorType); + if (u4EpigramOui != VENDOR_IE_EPIGRAM_OUI) + return; + if (u2EpigramVendorType != VENDOR_IE_EPIGRAM_VHTTYPE1 && + u2EpigramVendorType != VENDOR_IE_EPIGRAM_VHTTYPE2 && + u2EpigramVendorType != VENDOR_IE_EPIGRAM_VHTTYPE3) + return; + + pucIE = prEpiIE->pucData; + IE_FOR_EACH(pucIE, u2IELength, u2Offset) { + switch (IE_ID(pucIE)) { + case ELEM_ID_VHT_CAP: + scanParseVHTCapIE(pucIE, prBssDesc); + break; + case ELEM_ID_VHT_OP: + scanParseVHTOpIE(pucIE, prBssDesc); + break; + default: + break; + } + } +} + +void scanParseVHTCapIE(IN uint8_t *pucIE, IN struct BSS_DESC *prBssDesc) +{ + struct IE_VHT_CAP *prVhtCap = NULL; + uint16_t u2TxMcsSet = 0; + uint8_t ucSpatial = 0; + uint8_t j = 0; + + prVhtCap = (struct IE_VHT_CAP *) pucIE; + /* Error handling */ + if (IE_LEN(prVhtCap) != (sizeof(struct IE_VHT_CAP) - 2)) { + DBGLOG(SCN, WARN, + "VhtCap wrong length!(%d)->(%d)\n", + (sizeof(struct IE_VHT_CAP) - 2), + IE_LEN(prVhtCap)); + return; + } + + u2TxMcsSet = prVhtCap->rVhtSupportedMcsSet.u2TxMcsMap; + prBssDesc->fgIsVHTPresent = TRUE; +#if CFG_SUPPORT_BFEE +#define __LOCAL_VAR__ \ +VHT_CAP_INFO_NUMBER_OF_SOUNDING_DIMENSIONS_OFFSET + + prBssDesc->ucVhtCapNumSoundingDimensions = + (prVhtCap->u4VhtCapInfo + & VHT_CAP_INFO_NUMBER_OF_SOUNDING_DIMENSIONS) + >> __LOCAL_VAR__; +#undef __LOCAL_VAR__ +#endif + /* Support AP Selection*/ + if (prBssDesc->fgMultiAnttenaAndSTBC) + return; + + for (; j < 8; j++) { + if ((u2TxMcsSet & BITS(2 * j, 2 * j + 1)) != 3) + ucSpatial++; + } + prBssDesc->fgMultiAnttenaAndSTBC = + ((ucSpatial > 1) && (prVhtCap->u4VhtCapInfo & + VHT_CAP_INFO_TX_STBC)); +} + +void scanParseVHTOpIE(IN uint8_t *pucIE, IN struct BSS_DESC *prBssDesc) +{ + struct IE_VHT_OP *prVhtOp = NULL; + + prVhtOp = (struct IE_VHT_OP *) pucIE; + if (IE_LEN(prVhtOp) != (sizeof(struct IE_VHT_OP) - 2)) + return; + prBssDesc->eChannelWidth = (enum ENUM_CHANNEL_WIDTH) + (prVhtOp->ucVhtOperation[0]); + prBssDesc->ucCenterFreqS1 = (enum ENUM_CHANNEL_WIDTH) + (prVhtOp->ucVhtOperation[1]); + prBssDesc->ucCenterFreqS2 = (enum ENUM_CHANNEL_WIDTH) + (prVhtOp->ucVhtOperation[2]); + + /*add IEEE BW160 patch*/ + rlmModifyVhtBwPara(&prBssDesc->ucCenterFreqS1, + &prBssDesc->ucCenterFreqS2, + (uint8_t *)&prBssDesc->eChannelWidth); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Check if Adaptive 11r IE exists in Vendor Cisco IE. + * + * @param[in] pucBuf Pointer to the Vendor IE. + * @param[in] prBssDesc Pointer to the BSS_DESC structure. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void scanCheckAdaptive11rIE(IN uint8_t *pucBuf, IN struct BSS_DESC *prBssDesc) +{ + uint32_t oui; + struct IE_VENDOR_ADAPTIVE_11R_IE *ie; + uint8_t data; + uint16_t len; + + if (pucBuf == NULL || prBssDesc == NULL) { + DBGLOG(SCN, WARN, "adp11r pucBuf %p, prBssDesc %p, skip!\n", + pucBuf, prBssDesc); + return; + } + + ie = (struct IE_VENDOR_ADAPTIVE_11R_IE *) pucBuf; + len = ie->ucLength; + if (len < 5 || len > 8) + return; + + WLAN_GET_FIELD_BE24(ie->aucOui, &oui); + if (oui != VENDOR_IE_CISCO_OUI || + *(ie->aucVendorType) != VENDOR_IE_CISCO_TYPE) + return; + + data = *(ie->pucData); + prBssDesc->ucIsAdaptive11r = data & BIT(0); + DBGLOG(SCN, TRACE, "BSSDesc [" MACSTR "] adaptive11r = %d\n", + MAC2STR(prBssDesc->aucBSSID), prBssDesc->ucIsAdaptive11r); +} + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/scan_cache.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/scan_cache.c new file mode 100644 index 0000000000000000000000000000000000000000..037636f4c0ff301056b3ba14ee607a4c8504c777 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/scan_cache.c @@ -0,0 +1,289 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" + +#if CFG_SUPPORT_SCAN_CACHE_RESULT +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +static OS_SYSTIME getCurrentScanTime(void); + +static OS_SYSTIME getLastScanTime(struct GL_SCAN_CACHE_INFO *prScanCache); + +static void setLastScanTime(struct GL_SCAN_CACHE_INFO *prScanCache, + OS_SYSTIME rCurrentTime); + +static uint32_t getNumberOfScanChannels(struct GL_SCAN_CACHE_INFO *prScanCache); + +static u_int8_t isMediaConnected(struct GL_SCAN_CACHE_INFO *prScanCache); + +static u_int8_t isScanCacheChannels(struct GL_SCAN_CACHE_INFO *prScanCache); + +static u_int8_t isScanCacheTimeReady(struct GL_SCAN_CACHE_INFO *prScanCache); +static u_int8_t isScanCacheLowSpanScan(struct GL_SCAN_CACHE_INFO *prScanCache); +static u_int8_t isFull2PartialTimeout(struct GL_SCAN_CACHE_INFO *prScanCache); +static u_int8_t isScanCacheTimeOverflow(struct GL_SCAN_CACHE_INFO *prScanCache, + OS_SYSTIME rCurrentTime); + +static u_int8_t doScanCache(struct GL_SCAN_CACHE_INFO *prScanCache); + +static void updateScanCacheLastScanTime(struct GL_SCAN_CACHE_INFO *prScanCache, + OS_SYSTIME rCurrentTime); + +static void resetScanCacheLastScanTime(struct GL_SCAN_CACHE_INFO *prScanCache); + +static u_int8_t inScanCachePeriod(struct GL_SCAN_CACHE_INFO *prScanCache, + OS_SYSTIME rCurrentTime); + +static u_int8_t matchScanCache(struct GL_SCAN_CACHE_INFO *prScanCache, + OS_SYSTIME rCurrentTime); + +static u_int8_t matchLastScanTimeUpdate(struct GL_SCAN_CACHE_INFO *prScanCache, + OS_SYSTIME rCurrentTime); + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +static OS_SYSTIME getCurrentScanTime(void) +{ + OS_SYSTIME rCurrentTime = 0; + + GET_CURRENT_SYSTIME(&rCurrentTime); + return rCurrentTime; +} + +static OS_SYSTIME getLastScanTime(struct GL_SCAN_CACHE_INFO *prScanCache) +{ + return prScanCache->u4LastScanTime; +} + +static void setLastScanTime(struct GL_SCAN_CACHE_INFO *prScanCache, + OS_SYSTIME rCurrentTime) +{ + prScanCache->u4LastScanTime = rCurrentTime; +} + +static uint32_t getNumberOfScanChannels(struct GL_SCAN_CACHE_INFO *prScanCache) +{ + return (uint32_t) prScanCache->n_channels; +} + +static u_int8_t isMediaConnected(struct GL_SCAN_CACHE_INFO *prScanCache) +{ + return MEDIA_STATE_CONNECTED == + kalGetMediaStateIndicated(prScanCache->prGlueInfo, + prScanCache->ucBssIndex); +} + +static u_int8_t isScanCacheChannels(struct GL_SCAN_CACHE_INFO *prScanCache) +{ + return getNumberOfScanChannels(prScanCache) >= + CFG_SCAN_CACHE_MIN_CHANNEL_NUM; +} + +static u_int8_t isScanCacheTimeReady(struct GL_SCAN_CACHE_INFO *prScanCache) +{ + return prScanCache->u4LastScanTime != 0; +} + +static u_int8_t isScanCacheLowSpanScan(struct GL_SCAN_CACHE_INFO *prScanCache) +{ + return (prScanCache->u4Flags & NL80211_SCAN_FLAG_LOW_SPAN) >> 8; +} + +/* + * @brief This routine is to check the interval of full scan + * + * @param prScanCache - pointer of struct GL_SCAN_CACHE_INFO + * + * @retval TRUE: time diff between now and last full scan >= + * CFG_SCAN_FULL2PARTIAL_PERIOD + * FALSE: time diff between now and last full scan < + * CFG_SCAN_FULL2PARTIAL_PERIOD + */ +static u_int8_t isFull2PartialTimeout(struct GL_SCAN_CACHE_INFO *prScanCache) +{ + struct ADAPTER *prAdapter = NULL; + struct SCAN_INFO *prScanInfo; + u_int8_t fgLastFullScanTimeout = FALSE; + OS_SYSTIME rCurrentTime; + + GET_CURRENT_SYSTIME(&rCurrentTime); + + prAdapter = prScanCache->prGlueInfo->prAdapter; + if (prAdapter == NULL) { + DBGLOG(REQ, ERROR, "prScanCache->prGlueInfo->prAdapter NULL"); + return FALSE; + } + + prScanInfo = &(prAdapter->rWifiVar.rScanInfo); + if (prScanInfo == NULL) { + DBGLOG(REQ, ERROR, "prAdapter->rWifiVar.rScanInfo NULL"); + return FALSE; + } + +#if CFG_SUPPORT_FULL2PARTIAL_SCAN + if (CHECK_FOR_TIMEOUT(rCurrentTime, prScanInfo->u4LastFullScanTime, + SEC_TO_SYSTIME(CFG_SCAN_FULL2PARTIAL_PERIOD))) + fgLastFullScanTimeout = TRUE; +#endif + + return fgLastFullScanTimeout; +} + +static u_int8_t isScanCacheTimeOverflow(struct GL_SCAN_CACHE_INFO *prScanCache, + OS_SYSTIME rCurrentTime) +{ + return getLastScanTime(prScanCache) > rCurrentTime; +} + +static u_int8_t doScanCache(struct GL_SCAN_CACHE_INFO *prScanCache) +{ + GLUE_SPIN_LOCK_DECLARATION(); + + kalUpdateBssTimestamp(prScanCache->prGlueInfo); + GLUE_ACQUIRE_SPIN_LOCK(prScanCache->prGlueInfo, SPIN_LOCK_NET_DEV); + kalCfg80211ScanDone(prScanCache->prRequest, FALSE); + GLUE_RELEASE_SPIN_LOCK(prScanCache->prGlueInfo, SPIN_LOCK_NET_DEV); + return TRUE; +} + +static void updateScanCacheLastScanTime(struct GL_SCAN_CACHE_INFO *prScanCache, + OS_SYSTIME rCurrentTime) +{ + setLastScanTime(prScanCache, rCurrentTime); +} + +static void resetScanCacheLastScanTime(struct GL_SCAN_CACHE_INFO *prScanCache) +{ + setLastScanTime(prScanCache, 0); +} + +static u_int8_t inScanCachePeriod(struct GL_SCAN_CACHE_INFO *prScanCache, + OS_SYSTIME rCurrentTime) +{ + if (isScanCacheTimeReady(prScanCache) == FALSE) + return FALSE; + + if (isScanCacheTimeOverflow(prScanCache, rCurrentTime) == TRUE) + return FALSE; + + if (CHECK_FOR_TIMEOUT(rCurrentTime, getLastScanTime(prScanCache), + CFG_SCAN_CACHE_RESULT_PERIOD) == FALSE) + return TRUE; + + return FALSE; +} + +static u_int8_t matchScanCache(struct GL_SCAN_CACHE_INFO *prScanCache, + OS_SYSTIME rCurrentTime) +{ + + if (isMediaConnected(prScanCache) == TRUE) { + /* If scan not triggered by APP and it has been > + * CFG_SCAN_FULL2PARTIAL_PERIOD for last full scan, + * not to do scan cache + */ + if (!isScanCacheLowSpanScan(prScanCache) && + isFull2PartialTimeout(prScanCache)) + return FALSE; + else if (inScanCachePeriod(prScanCache, rCurrentTime) == TRUE && + isScanCacheChannels(prScanCache) == TRUE) + return TRUE; + } + return FALSE; +} + +static u_int8_t matchLastScanTimeUpdate(struct GL_SCAN_CACHE_INFO *prScanCache, + OS_SYSTIME rCurrentTime) +{ + if (isMediaConnected(prScanCache) == TRUE && + inScanCachePeriod(prScanCache, rCurrentTime) == FALSE && + isScanCacheChannels(prScanCache) == TRUE) + return TRUE; + + return FALSE; +} + +/* + * @brief This routine is responsible for checking scan cache + * + * @param prScanCache - pointer of struct GL_SCAN_CACHE_INFO + * + * @retval TRUE: do scan cache successful + * FALSE: didn't report scan cache + */ +u_int8_t isScanCacheDone(struct GL_SCAN_CACHE_INFO *prScanCache) +{ + OS_SYSTIME rCurrentTime = getCurrentScanTime(); + + if (matchScanCache(prScanCache, rCurrentTime) == TRUE) { + log_limited_dbg(REQ, INFO, "SCAN_CACHE: Skip scan too frequently(%u, %u). Call cfg80211_scan_done directly\n", + rCurrentTime, + getLastScanTime(prScanCache)); + + return doScanCache(prScanCache); + } + + if (matchLastScanTimeUpdate(prScanCache, rCurrentTime) == TRUE) { + log_dbg(REQ, INFO, "SCAN_CACHE: set scan cache time (%u)->(%u)\n", + getLastScanTime(prScanCache), + rCurrentTime); + + updateScanCacheLastScanTime(prScanCache, rCurrentTime); + } + + if (isMediaConnected(prScanCache) == FALSE) { + log_dbg(REQ, TRACE, "SCAN_CACHE: reset scan cache time (%u)->(0)\n", + getLastScanTime(prScanCache)); + + resetScanCacheLastScanTime(prScanCache); + } + return FALSE; +} +#endif /* CFG_SUPPORT_SCAN_CACHE_RESULT */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/scan_fsm.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/scan_fsm.c new file mode 100644 index 0000000000000000000000000000000000000000..7bfcd13a2b4b7567b806626e2aec6bf6b61af758 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/scan_fsm.c @@ -0,0 +1,1352 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/scan_fsm.c#2 + */ + +/*! \file "scan_fsm.c" + * \brief This file defines the state transition function for SCAN FSM. + * + * The SCAN FSM is part of SCAN MODULE and responsible for performing basic + * SCAN behavior as metioned in IEEE 802.11 2007 11.1.3.1 & 11.1.3.2. + */ + + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ +static uint8_t *apucDebugScanState[SCAN_STATE_NUM] = { + (uint8_t *) DISP_STRING("IDLE"), + (uint8_t *) DISP_STRING("SCANNING"), +}; + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void scnFsmSteps(IN struct ADAPTER *prAdapter, + IN enum ENUM_SCAN_STATE eNextState) +{ + struct SCAN_INFO *prScanInfo; + struct SCAN_PARAM *prScanParam; + struct MSG_HDR *prMsgHdr; + + u_int8_t fgIsTransition = (u_int8_t) FALSE; + + prScanInfo = &(prAdapter->rWifiVar.rScanInfo); + prScanParam = &prScanInfo->rScanParam; + + do { + /* Coverity */ + if (prScanInfo->eCurrentState >= 0 && eNextState >= 0) { + log_dbg(SCN, STATE, "[SCAN]TRANSITION: [%s] -> [%s]\n", + apucDebugScanState[prScanInfo->eCurrentState], + apucDebugScanState[eNextState]); + } + /* NOTE(Kevin): This is the only place to change the + * eCurrentState(except initial) + */ + prScanInfo->eCurrentState = eNextState; + + fgIsTransition = (u_int8_t) FALSE; + + switch (prScanInfo->eCurrentState) { + case SCAN_STATE_IDLE: + /* check for pending scanning requests */ + if (!LINK_IS_EMPTY(&(prScanInfo->rPendingMsgList))) { + /* load next message from pending list as + * scan parameters + */ + LINK_REMOVE_HEAD(&(prScanInfo->rPendingMsgList), + prMsgHdr, struct MSG_HDR *); + +#define __MSG_ID__ prMsgHdr->eMsgId + if (__MSG_ID__ == MID_AIS_SCN_SCAN_REQ + || __MSG_ID__ == MID_BOW_SCN_SCAN_REQ + || __MSG_ID__ == MID_P2P_SCN_SCAN_REQ + || __MSG_ID__ == MID_RLM_SCN_SCAN_REQ) { + scnFsmHandleScanMsg(prAdapter, + (struct MSG_SCN_SCAN_REQ *) + prMsgHdr); + + eNextState = SCAN_STATE_SCANNING; + fgIsTransition = TRUE; + } else if (__MSG_ID__ == MID_AIS_SCN_SCAN_REQ_V2 + || __MSG_ID__ == MID_BOW_SCN_SCAN_REQ_V2 + || __MSG_ID__ == MID_P2P_SCN_SCAN_REQ_V2 + || __MSG_ID__ == MID_RLM_SCN_SCAN_REQ_V2 + ) { + scnFsmHandleScanMsgV2(prAdapter, + (struct MSG_SCN_SCAN_REQ_V2 *) + prMsgHdr); + + eNextState = SCAN_STATE_SCANNING; + fgIsTransition = TRUE; + } else { + /* should not happen */ + ASSERT(0); + } +#undef __MSG_ID__ + + /* switch to next state */ + cnmMemFree(prAdapter, prMsgHdr); + } + break; + + case SCAN_STATE_SCANNING: + /* Support AP Selection */ + prScanInfo->u4ScanUpdateIdx++; + if (prScanParam->fgIsScanV2 == FALSE) + scnSendScanReq(prAdapter); + else + scnSendScanReqV2(prAdapter); + break; + + default: + ASSERT(0); + break; + + } + } while (fgIsTransition); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Generate CMD_ID_SCAN_REQ command + * + * Because CMD_ID_SCAN_REQ is deprecated, + * wrap this command to CMD_ID_SCAN_REQ_V2 + * + * \param[in] prAdapter adapter + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void scnSendScanReq(IN struct ADAPTER *prAdapter) +{ + log_dbg(SCN, WARN, + "CMD_ID_SCAN_REQ is deprecated, use CMD_ID_SCAN_REQ_V2\n"); + scnSendScanReqV2(prAdapter); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Generate CMD_ID_SCAN_REQ_V2 command + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void scnSendScanReqV2(IN struct ADAPTER *prAdapter) +{ + struct SCAN_INFO *prScanInfo; + struct SCAN_PARAM *prScanParam; + /* CMD_SCAN_REQ_V2 rCmdScanReq; */ + struct CMD_SCAN_REQ_V2 *prCmdScanReq; + uint32_t i; + + ASSERT(prAdapter); + + prScanInfo = &(prAdapter->rWifiVar.rScanInfo); + prScanParam = &(prScanInfo->rScanParam); + + prCmdScanReq = kalMemAlloc( + sizeof(struct CMD_SCAN_REQ_V2), VIR_MEM_TYPE); + if (!prCmdScanReq) { + log_dbg(SCN, ERROR, "alloc CmdScanReq V2 fail\n"); + return; + } + /* send command packet for scan */ + kalMemZero(prCmdScanReq, sizeof(struct CMD_SCAN_REQ_V2)); + /* Modify channelList number from 32 to 54 */ + COPY_MAC_ADDR(prCmdScanReq->aucBSSID, prScanParam->aucBSSID); + if (!EQUAL_MAC_ADDR(prCmdScanReq->aucBSSID, "\xff\xff\xff\xff\xff\xff")) + DBGLOG(SCN, INFO, "Include BSSID "MACSTR" in probe request\n", + MAC2STR(prCmdScanReq->aucBSSID)); + + prCmdScanReq->ucSeqNum = prScanParam->ucSeqNum; + prCmdScanReq->ucBssIndex = prScanParam->ucBssIndex; + prCmdScanReq->ucScanType = (uint8_t) prScanParam->eScanType; + prCmdScanReq->ucSSIDType = prScanParam->ucSSIDType; + prCmdScanReq->auVersion[0] = 1; + prCmdScanReq->ucScnFuncMask |= prScanParam->ucScnFuncMask; + if (kalIsValidMacAddr(prScanParam->aucRandomMac)) { + prCmdScanReq->ucScnFuncMask |= (ENUM_SCN_RANDOM_MAC_EN | + ENUM_SCN_RANDOM_SN_EN); + kalMemCopy(prCmdScanReq->aucRandomMac, + prScanParam->aucRandomMac, MAC_ADDR_LEN); + } + if (prAdapter->rWifiVar.eDbdcMode == ENUM_DBDC_MODE_DISABLED) + prCmdScanReq->ucScnFuncMask |= ENUM_SCN_DBDC_SCAN_DIS; + + /* Set SSID to scan request */ + if (prScanParam->ucSSIDNum <= SCAN_CMD_SSID_NUM) { + prCmdScanReq->ucSSIDNum = prScanParam->ucSSIDNum; + prCmdScanReq->ucSSIDExtNum = 0; + } else if (prScanParam->ucSSIDNum <= CFG_SCAN_SSID_MAX_NUM) { + prCmdScanReq->ucSSIDNum = SCAN_CMD_SSID_NUM; + prCmdScanReq->ucSSIDExtNum = prScanParam->ucSSIDNum + - SCAN_CMD_SSID_NUM; + } else { + log_dbg(SCN, WARN, "Too many SSID %u\n", + prScanParam->ucSSIDNum); + prCmdScanReq->ucSSIDNum = SCAN_CMD_SSID_NUM; + prCmdScanReq->ucSSIDExtNum = SCAN_CMD_EXT_SSID_NUM; + } + + for (i = 0; i < prCmdScanReq->ucSSIDNum; i++) { + COPY_SSID(prCmdScanReq->arSSID[i].aucSsid, + prCmdScanReq->arSSID[i].u4SsidLen, + prScanParam->aucSpecifiedSSID[i], + prScanParam->ucSpecifiedSSIDLen[i]); + log_dbg(SCN, TRACE, + "Ssid=%s, SsidLen=%d\n", + HIDE(prCmdScanReq->arSSID[i].aucSsid), + prCmdScanReq->arSSID[i].u4SsidLen); + } + for (i = 0; i < prCmdScanReq->ucSSIDExtNum; i++) { + COPY_SSID(prCmdScanReq->arSSIDExtend[i].aucSsid, + prCmdScanReq->arSSIDExtend[i].u4SsidLen, + prScanParam->aucSpecifiedSSID + [prCmdScanReq->ucSSIDNum+i], + prScanParam->ucSpecifiedSSIDLen + [prCmdScanReq->ucSSIDNum+i]); + log_dbg(SCN, TRACE, + "Ssid=%s, SsidLen=%d\n", + prCmdScanReq->arSSIDExtend[i].aucSsid, + prCmdScanReq->arSSIDExtend[i].u4SsidLen); + } + + prCmdScanReq->u2ProbeDelayTime + = (uint8_t) prScanParam->u2ProbeDelayTime; + prCmdScanReq->ucChannelType + = (uint8_t) prScanParam->eScanChannel; + + /* Set channel info to scan request */ + if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) { + if (prScanParam->ucChannelListNum <= SCAN_CMD_CHNL_NUM) { + prCmdScanReq->ucChannelListNum = + prScanParam->ucChannelListNum; + prCmdScanReq->ucChannelListExtNum = 0; + } else if (prScanParam->ucChannelListNum <= + MAXIMUM_OPERATION_CHANNEL_LIST) { + prCmdScanReq->ucChannelListNum = + SCAN_CMD_CHNL_NUM; + prCmdScanReq->ucChannelListExtNum = + prScanParam->ucChannelListNum - + SCAN_CMD_CHNL_NUM; + } else { + log_dbg(SCN, WARN, "Too many Channel %u\n", + prScanParam->ucChannelListNum); + prCmdScanReq->ucChannelListNum = 0; + prCmdScanReq->ucChannelListExtNum = 0; + prCmdScanReq->ucChannelType = SCAN_CHANNEL_FULL; + } + + for (i = 0; i < prCmdScanReq->ucChannelListNum; i++) { + prCmdScanReq->arChannelList[i].ucBand + = (uint8_t) prScanParam->arChnlInfoList[i] + .eBand; + + prCmdScanReq->arChannelList[i].ucChannelNum + = (uint8_t) prScanParam->arChnlInfoList[i] + .ucChannelNum; + } + for (i = 0; i < prCmdScanReq->ucChannelListExtNum; i++) { + prCmdScanReq->arChannelListExtend[i].ucBand + = (uint8_t)prScanParam + ->arChnlInfoList + [prCmdScanReq->ucChannelListNum+i] + .eBand; + + prCmdScanReq->arChannelListExtend[i].ucChannelNum + = (uint8_t) prScanParam + ->arChnlInfoList + [prCmdScanReq->ucChannelListNum+i] + .ucChannelNum; + } + } + + prCmdScanReq->u2ChannelDwellTime = prScanParam->u2ChannelDwellTime; + prCmdScanReq->u2ChannelMinDwellTime = + prScanParam->u2ChannelMinDwellTime; + prCmdScanReq->u2TimeoutValue = prScanParam->u2TimeoutValue; + + if (prScanParam->u2IELen <= MAX_IE_LENGTH) + prCmdScanReq->u2IELen = prScanParam->u2IELen; + else + prCmdScanReq->u2IELen = MAX_IE_LENGTH; + + if (prScanParam->u2IELen) + kalMemCopy(prCmdScanReq->aucIE, prScanParam->aucIE, + sizeof(uint8_t) * prCmdScanReq->u2IELen); + + log_dbg(SCN, INFO, "ScanReqV2: ScanType=%d,BSS=%u,SSIDType=%d,Num=%u,Ext=%u,ChannelType=%d,Num=%d,Ext=%u,Seq=%u,Ver=%u,Dw=%u,Min=%u,Func=0x%X,Mac=" + MACSTR "\n", + prCmdScanReq->ucScanType, + prCmdScanReq->ucBssIndex, + prCmdScanReq->ucSSIDType, + prCmdScanReq->ucSSIDNum, + prCmdScanReq->ucSSIDExtNum, + prCmdScanReq->ucChannelType, + prCmdScanReq->ucChannelListNum, + prCmdScanReq->ucChannelListExtNum, + prCmdScanReq->ucSeqNum, prCmdScanReq->auVersion[0], + prCmdScanReq->u2ChannelDwellTime, + prCmdScanReq->u2ChannelMinDwellTime, + prCmdScanReq->ucScnFuncMask, + MAC2STR(prCmdScanReq->aucRandomMac)); + + scanLogCacheFlushAll(prAdapter, &(prScanInfo->rScanLogCache), + LOG_SCAN_REQ_D2F); + scanReqLog(prCmdScanReq); + if (prCmdScanReq->ucBssIndex == KAL_NETWORK_TYPE_AIS_INDEX) + scanInitEssResult(prAdapter); + + wlanSendSetQueryCmd(prAdapter, + CMD_ID_SCAN_REQ_V2, + TRUE, + FALSE, + FALSE, + NULL, + NULL, + sizeof(struct CMD_SCAN_REQ_V2), + (uint8_t *)prCmdScanReq, NULL, 0); + log_dbg(SCN, TRACE, "Send %zu bytes\n", sizeof(struct CMD_SCAN_REQ_V2)); + + + kalMemFree(prCmdScanReq, VIR_MEM_TYPE, sizeof(struct CMD_SCAN_REQ_V2)); + +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void scnFsmMsgStart(IN struct ADAPTER *prAdapter, IN struct MSG_HDR *prMsgHdr) +{ + struct SCAN_INFO *prScanInfo; + struct SCAN_PARAM *prScanParam; + + ASSERT(prMsgHdr); + + prScanInfo = &(prAdapter->rWifiVar.rScanInfo); + prScanParam = &prScanInfo->rScanParam; + + if (prScanInfo->eCurrentState == SCAN_STATE_IDLE) { + if (prMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ + || prMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ + || prMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ + || prMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ) { + scnFsmHandleScanMsg(prAdapter, + (struct MSG_SCN_SCAN_REQ *) prMsgHdr); + } else if (prMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ_V2 + || prMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ_V2 + || prMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ_V2 + || prMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ_V2) { + scnFsmHandleScanMsgV2(prAdapter, + (struct MSG_SCN_SCAN_REQ_V2 *) prMsgHdr); + } else { + /* should not deliver to this function */ + ASSERT(0); + } + + cnmMemFree(prAdapter, prMsgHdr); + scnFsmSteps(prAdapter, SCAN_STATE_SCANNING); + } else { + LINK_INSERT_TAIL(&prScanInfo->rPendingMsgList, + &prMsgHdr->rLinkEntry); + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void scnFsmMsgAbort(IN struct ADAPTER *prAdapter, IN struct MSG_HDR *prMsgHdr) +{ + struct MSG_SCN_SCAN_CANCEL *prScanCancel; + struct SCAN_INFO *prScanInfo; + struct SCAN_PARAM *prScanParam; + struct CMD_SCAN_CANCEL rCmdScanCancel; + + ASSERT(prMsgHdr); + + prScanCancel = (struct MSG_SCN_SCAN_CANCEL *) prMsgHdr; + prScanInfo = &(prAdapter->rWifiVar.rScanInfo); + prScanParam = &prScanInfo->rScanParam; + + if (prScanInfo->eCurrentState != SCAN_STATE_IDLE) { + if (prScanCancel->ucSeqNum == prScanParam->ucSeqNum && + prScanCancel->ucBssIndex == prScanParam->ucBssIndex) { + enum ENUM_SCAN_STATUS eStatus = SCAN_STATUS_DONE; + + /* send cancel message to firmware domain */ + rCmdScanCancel.ucSeqNum = prScanParam->ucSeqNum; + rCmdScanCancel.ucIsExtChannel + = (uint8_t) prScanCancel->fgIsChannelExt; + + scanlog_dbg(LOG_SCAN_ABORT_REQ_D2F, INFO, "Scan Abort#%u to Q: isExtCh=%u", + rCmdScanCancel.ucSeqNum, + rCmdScanCancel.ucIsExtChannel); + + wlanSendSetQueryCmd(prAdapter, + CMD_ID_SCAN_CANCEL, + TRUE, + FALSE, + FALSE, + NULL, + NULL, + sizeof(struct CMD_SCAN_CANCEL), + (uint8_t *) &rCmdScanCancel, + NULL, + 0); + + /* Full2Partial: ignore this statistics */ + if (prScanInfo->fgIsScanForFull2Partial) { + prScanInfo->fgIsScanForFull2Partial = FALSE; + prScanInfo->u4LastFullScanTime = 0; + log_dbg(SCN, INFO, + "Full2Partial: scan canceled(%u)\n", + prScanParam->ucSeqNum); + } + + /* generate scan-done event for caller */ + if (prScanCancel->fgIsOidRequest) + eStatus = SCAN_STATUS_CANCELLED; + else + eStatus = SCAN_STATUS_DONE; + scnFsmGenerateScanDoneMsg(prAdapter, + prScanParam->eMsgId, + prScanParam->ucSeqNum, + prScanParam->ucBssIndex, + eStatus); + + /* switch to next pending scan */ + scnFsmSteps(prAdapter, SCAN_STATE_IDLE); + } else { + scnFsmRemovePendingMsg(prAdapter, + prScanCancel->ucSeqNum, + prScanCancel->ucBssIndex); + } + } + + cnmMemFree(prAdapter, prMsgHdr); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Scan Message Parsing (Legacy) + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void scnFsmHandleScanMsg(IN struct ADAPTER *prAdapter, + IN struct MSG_SCN_SCAN_REQ *prScanReqMsg) +{ + struct SCAN_INFO *prScanInfo; + struct SCAN_PARAM *prScanParam; + uint32_t i; + + ASSERT(prAdapter); + ASSERT(prScanReqMsg); + + prScanInfo = &(prAdapter->rWifiVar.rScanInfo); + prScanParam = &prScanInfo->rScanParam; + + kalMemZero(prScanParam, sizeof(*prScanParam)); + prScanParam->eScanType = prScanReqMsg->eScanType; + prScanParam->ucBssIndex = prScanReqMsg->ucBssIndex; + prScanParam->ucSSIDType = prScanReqMsg->ucSSIDType; + if (prScanParam->ucSSIDType + & (SCAN_REQ_SSID_SPECIFIED | SCAN_REQ_SSID_P2P_WILDCARD)) { + prScanParam->ucSSIDNum = 1; + + COPY_SSID(prScanParam->aucSpecifiedSSID[0], + prScanParam->ucSpecifiedSSIDLen[0], + prScanReqMsg->aucSSID, prScanReqMsg->ucSSIDLength); + + /* reset SSID length to zero for rest array entries */ + for (i = 1; i < SCN_SSID_MAX_NUM; i++) + prScanParam->ucSpecifiedSSIDLen[i] = 0; + } else { + prScanParam->ucSSIDNum = 0; + + for (i = 0; i < SCN_SSID_MAX_NUM; i++) + prScanParam->ucSpecifiedSSIDLen[i] = 0; + } + + prScanParam->u2ProbeDelayTime = 0; + prScanParam->eScanChannel = prScanReqMsg->eScanChannel; + if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) { + if (prScanReqMsg->ucChannelListNum + <= MAXIMUM_OPERATION_CHANNEL_LIST) { + prScanParam->ucChannelListNum + = prScanReqMsg->ucChannelListNum; + } else { + prScanParam->ucChannelListNum + = MAXIMUM_OPERATION_CHANNEL_LIST; + } + + kalMemCopy(prScanParam->arChnlInfoList, + prScanReqMsg->arChnlInfoList, + sizeof(struct RF_CHANNEL_INFO) + * prScanParam->ucChannelListNum); + } + + if (prScanReqMsg->u2IELen <= MAX_IE_LENGTH) + prScanParam->u2IELen = prScanReqMsg->u2IELen; + else + prScanParam->u2IELen = MAX_IE_LENGTH; + + if (prScanParam->u2IELen) { + kalMemCopy(prScanParam->aucIE, + prScanReqMsg->aucIE, prScanParam->u2IELen); + } + + prScanParam->u2ChannelDwellTime = prScanReqMsg->u2ChannelDwellTime; + prScanParam->u2TimeoutValue = prScanReqMsg->u2TimeoutValue; + prScanParam->ucSeqNum = prScanReqMsg->ucSeqNum; + prScanParam->eMsgId = prScanReqMsg->rMsgHdr.eMsgId; + prScanParam->fgIsScanV2 = FALSE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Scan Message Parsing - V2 with multiple SSID support + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void scnFsmHandleScanMsgV2(IN struct ADAPTER *prAdapter, + IN struct MSG_SCN_SCAN_REQ_V2 *prScanReqMsg) +{ + struct SCAN_INFO *prScanInfo; + struct SCAN_PARAM *prScanParam; + uint32_t i; + + ASSERT(prAdapter); + ASSERT(prScanReqMsg); + ASSERT(prScanReqMsg->ucSSIDNum <= SCN_SSID_MAX_NUM); + + prScanInfo = &(prAdapter->rWifiVar.rScanInfo); + prScanParam = &prScanInfo->rScanParam; + + kalMemZero(prScanParam, sizeof(*prScanParam)); + prScanParam->eScanType = prScanReqMsg->eScanType; + prScanParam->ucBssIndex = prScanReqMsg->ucBssIndex; + prScanParam->ucSSIDType = prScanReqMsg->ucSSIDType; + prScanParam->ucSSIDNum = prScanReqMsg->ucSSIDNum; + prScanParam->ucScnFuncMask |= prScanReqMsg->ucScnFuncMask; + kalMemCopy(prScanParam->aucRandomMac, prScanReqMsg->aucRandomMac, + MAC_ADDR_LEN); + + if (prScanParam->ucSSIDType & SCAN_REQ_SSID_SPECIFIED_ONLY) { + prScanParam->ucSSIDNum = 1; + kalMemZero(prScanParam->ucSpecifiedSSIDLen, + sizeof(prScanParam->ucSpecifiedSSIDLen)); + COPY_SSID(prScanParam->aucSpecifiedSSID[0], + prScanParam->ucSpecifiedSSIDLen[0], + &prScanReqMsg->prSsid[0].aucSsid[0], + prScanReqMsg->prSsid[0].u4SsidLen); + } else { + for (i = 0; i < prScanReqMsg->ucSSIDNum; i++) { + COPY_SSID(prScanParam->aucSpecifiedSSID[i], + prScanParam->ucSpecifiedSSIDLen[i], + prScanReqMsg->prSsid[i].aucSsid, + (uint8_t) prScanReqMsg->prSsid[i].u4SsidLen); + } + } + + prScanParam->u2ProbeDelayTime = prScanReqMsg->u2ProbeDelay; + prScanParam->eScanChannel = prScanReqMsg->eScanChannel; + if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) { + if (prScanReqMsg->ucChannelListNum + <= MAXIMUM_OPERATION_CHANNEL_LIST) { + prScanParam->ucChannelListNum + = prScanReqMsg->ucChannelListNum; + } else { + prScanParam->ucChannelListNum + = MAXIMUM_OPERATION_CHANNEL_LIST; + } + + kalMemCopy(prScanParam->arChnlInfoList, + prScanReqMsg->arChnlInfoList, + sizeof(struct RF_CHANNEL_INFO) + * prScanParam->ucChannelListNum); + } + + if (prScanReqMsg->u2IELen <= MAX_IE_LENGTH) + prScanParam->u2IELen = prScanReqMsg->u2IELen; + else + prScanParam->u2IELen = MAX_IE_LENGTH; + + if (prScanParam->u2IELen) { + kalMemCopy(prScanParam->aucIE, + prScanReqMsg->aucIE, prScanParam->u2IELen); + } + + prScanParam->u2ChannelDwellTime = prScanReqMsg->u2ChannelDwellTime; + prScanParam->u2ChannelMinDwellTime = + prScanReqMsg->u2ChannelMinDwellTime; + prScanParam->u2TimeoutValue = prScanReqMsg->u2TimeoutValue; + prScanParam->ucSeqNum = prScanReqMsg->ucSeqNum; + prScanParam->eMsgId = prScanReqMsg->rMsgHdr.eMsgId; + prScanParam->fgIsScanV2 = TRUE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Remove pending scan request + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void scnFsmRemovePendingMsg(IN struct ADAPTER *prAdapter, IN uint8_t ucSeqNum, + IN uint8_t ucBssIndex) +{ + struct SCAN_INFO *prScanInfo; + struct SCAN_PARAM *prScanParam; + struct MSG_HDR *prPendingMsgHdr = NULL; + struct MSG_HDR *prPendingMsgHdrNext = NULL; + struct MSG_HDR *prRemoveMsgHdr = NULL; + struct LINK_ENTRY *prRemoveLinkEntry = NULL; + u_int8_t fgIsRemovingScan = FALSE; + + ASSERT(prAdapter); + + prScanInfo = &(prAdapter->rWifiVar.rScanInfo); + prScanParam = &prScanInfo->rScanParam; + + /* traverse through rPendingMsgList for removal */ + LINK_FOR_EACH_ENTRY_SAFE(prPendingMsgHdr, + prPendingMsgHdrNext, &(prScanInfo->rPendingMsgList), + rLinkEntry, struct MSG_HDR) { + +#define __MSG_ID__ prPendingMsgHdr->eMsgId + if (__MSG_ID__ == MID_AIS_SCN_SCAN_REQ + || __MSG_ID__ == MID_BOW_SCN_SCAN_REQ + || __MSG_ID__ == MID_P2P_SCN_SCAN_REQ + || __MSG_ID__ == MID_RLM_SCN_SCAN_REQ) { + struct MSG_SCN_SCAN_REQ *prScanReqMsg + = (struct MSG_SCN_SCAN_REQ *) + prPendingMsgHdr; + + if (ucSeqNum == prScanReqMsg->ucSeqNum + && ucBssIndex == prScanReqMsg->ucBssIndex) { + prRemoveLinkEntry + = &(prScanReqMsg->rMsgHdr.rLinkEntry); + prRemoveMsgHdr = prPendingMsgHdr; + fgIsRemovingScan = TRUE; + } + } else if (__MSG_ID__ == MID_AIS_SCN_SCAN_REQ_V2 + || __MSG_ID__ == MID_BOW_SCN_SCAN_REQ_V2 + || __MSG_ID__ == MID_P2P_SCN_SCAN_REQ_V2 + || __MSG_ID__ == MID_RLM_SCN_SCAN_REQ_V2) { + struct MSG_SCN_SCAN_REQ_V2 *prScanReqMsgV2 + = (struct MSG_SCN_SCAN_REQ_V2 *) + prPendingMsgHdr; + + if (ucSeqNum == prScanReqMsgV2->ucSeqNum + && ucBssIndex == prScanReqMsgV2->ucBssIndex) { + prRemoveLinkEntry + = &(prScanReqMsgV2->rMsgHdr.rLinkEntry); + prRemoveMsgHdr = prPendingMsgHdr; + fgIsRemovingScan = TRUE; + } + } +#undef __MSG_ID__ + + if (prRemoveLinkEntry) { + if (fgIsRemovingScan == TRUE) { + /* generate scan-done event for caller */ + scnFsmGenerateScanDoneMsg(prAdapter, + prPendingMsgHdr->eMsgId, ucSeqNum, + ucBssIndex, SCAN_STATUS_CANCELLED); + } + + /* remove from pending list */ + LINK_REMOVE_KNOWN_ENTRY(&(prScanInfo->rPendingMsgList), + prRemoveLinkEntry); + cnmMemFree(prAdapter, prRemoveMsgHdr); + + break; + } + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void scnEventScanDone(IN struct ADAPTER *prAdapter, + IN struct EVENT_SCAN_DONE *prScanDone, u_int8_t fgIsNewVersion) +{ + struct SCAN_INFO *prScanInfo; + struct SCAN_PARAM *prScanParam; + uint32_t u4ChCnt = 0; + KAL_SPIN_LOCK_DECLARATION(); + + prScanInfo = &(prAdapter->rWifiVar.rScanInfo); + prScanParam = &prScanInfo->rScanParam; + + if (fgIsNewVersion) { + scanlog_dbg(LOG_SCAN_DONE_F2D, INFO, "scnEventScanDone Version%u!size of ScanDone%zu,ucCompleteChanCount[%u],ucCurrentState%u, u4ScanDurBcnCnt[%u],Seq[%u]\n", + prScanDone->ucScanDoneVersion, + sizeof(struct EVENT_SCAN_DONE), + prScanDone->ucCompleteChanCount, + prScanDone->ucCurrentState, + prScanDone->u4ScanDurBcnCnt, + prScanDone->ucSeqNum); + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BSSLIST_FW); + scanLogCacheFlushBSS(&(prScanInfo->rScanLogCache.rBSSListFW), + LOG_SCAN_DONE_F2D); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BSSLIST_FW); + + if (prScanDone->ucCurrentState != FW_SCAN_STATE_SCAN_DONE) { + log_dbg(SCN, INFO, "FW Scan timeout!generate ScanDone event at State%d complete chan count%d ucChannelListNum%d\n", + prScanDone->ucCurrentState, + prScanDone->ucCompleteChanCount, + prScanParam->ucChannelListNum); + + } else { + log_dbg(SCN, TRACE, " scnEventScanDone at FW_SCAN_STATE_SCAN_DONE state\n"); + } + } else { + scanlog_dbg(LOG_SCAN_DONE_F2D, INFO, "Old scnEventScanDone Version\n"); + } + + /* buffer empty channel information */ + if (prScanDone->ucSparseChannelValid) { + int num = 0; + char strbuf[SCN_SCAN_DONE_PRINT_BUFFER_LENGTH]; + + prScanInfo->fgIsSparseChannelValid = TRUE; + prScanInfo->rSparseChannel.eBand + = (enum ENUM_BAND) prScanDone->rSparseChannel.ucBand; + prScanInfo->rSparseChannel.ucChannelNum + = prScanDone->rSparseChannel.ucChannelNum; + num = prScanInfo->ucSparseChannelArrayValidNum + = prScanDone->ucSparseChannelArrayValidNum; + log_dbg(SCN, INFO, "Country Code = %c%c, Detected_Channel_Num = %d\n", + ((prAdapter->rWifiVar.u2CountryCode + & 0xff00) >> 8), + (prAdapter->rWifiVar.u2CountryCode + & 0x00ff), num); + +#define print_info(_Mod, _Clz, _Fmt, var) \ + do { \ + int written = 0; \ + int totalLen = SCN_SCAN_DONE_PRINT_BUFFER_LENGTH; \ + for (u4ChCnt = 0; u4ChCnt < num; u4ChCnt++) { \ + prScanInfo->var[u4ChCnt] \ + = prScanDone->var[u4ChCnt]; \ + written += kalSnprintf(strbuf + written, \ + totalLen - written, "%7d", \ + prScanInfo->var[u4ChCnt]); \ + } \ + log_dbg(_Mod, _Clz, _Fmt, strbuf); \ + } while (0) + + print_info(SCN, INFO, "Channel : %s\n", aucChannelNum); + print_info(SCN, INFO, "IdleTime : %s\n", au2ChannelIdleTime); + print_info(SCN, INFO, "MdrdyCnt : %s\n", aucChannelMDRDYCnt); + print_info(SCN, INFO, "BAndPCnt : %s\n", aucChannelBAndPCnt); + if (prScanDone->ucScanDoneVersion >= 4) + print_info(SCN, LOUD, + "ScanTime : %s\n", au2ChannelScanTime); +#undef print_scan_info + } else { + prScanInfo->fgIsSparseChannelValid = FALSE; + } + + /* Full2Partial */ + if (prScanInfo->fgIsScanForFull2Partial && + prScanInfo->ucFull2PartialSeq == prScanDone->ucSeqNum) { + uint32_t *pu4BitMap = &(prScanInfo->au4ChannelBitMap[0]); + + log_dbg(SCN, INFO, + "Full2Partial(%u):%08X %08X %08X %08X %08X %08X %08X %08X\n", + scanCountBits(prScanInfo->au4ChannelBitMap, + sizeof(prScanInfo->au4ChannelBitMap)), + pu4BitMap[7], pu4BitMap[6], pu4BitMap[5], pu4BitMap[4], + pu4BitMap[3], pu4BitMap[2], pu4BitMap[1], pu4BitMap[0]); + + prScanInfo->fgIsScanForFull2Partial = FALSE; + } + + if (prScanInfo->eCurrentState == SCAN_STATE_SCANNING + && prScanDone->ucSeqNum == prScanParam->ucSeqNum) { + scanRemoveBssDescsByPolicy(prAdapter, + SCN_RM_POLICY_EXCLUDE_CONNECTED | SCN_RM_POLICY_TIMEOUT); + + /* generate scan-done event for caller */ + scnFsmGenerateScanDoneMsg(prAdapter, + prScanParam->eMsgId, prScanParam->ucSeqNum, + prScanParam->ucBssIndex, SCAN_STATUS_DONE); + + /* switch to next pending scan */ + scnFsmSteps(prAdapter, SCAN_STATE_IDLE); + } else { + log_dbg(SCN, INFO, "Unexpected SCAN-DONE event: SeqNum = %d, Current State = %d\n", + prScanDone->ucSeqNum, + prScanInfo->eCurrentState); + } +} /* end of scnEventScanDone */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void +scnFsmGenerateScanDoneMsg(IN struct ADAPTER *prAdapter, + IN enum ENUM_MSG_ID eMsgId, IN uint8_t ucSeqNum, IN uint8_t ucBssIndex, + IN enum ENUM_SCAN_STATUS eScanStatus) +{ + struct SCAN_INFO *prScanInfo; + struct SCAN_PARAM *prScanParam; + struct MSG_SCN_SCAN_DONE *prScanDoneMsg; + + ASSERT(prAdapter); + + prScanInfo = &(prAdapter->rWifiVar.rScanInfo); + prScanParam = &prScanInfo->rScanParam; + + prScanDoneMsg = (struct MSG_SCN_SCAN_DONE *) cnmMemAlloc(prAdapter, + RAM_TYPE_MSG, sizeof(struct MSG_SCN_SCAN_DONE)); + if (!prScanDoneMsg) { + ASSERT(0); /* Can't indicate SCAN FSM Complete */ + return; + } + + switch (eMsgId) { + case MID_AIS_SCN_SCAN_REQ: + case MID_AIS_SCN_SCAN_REQ_V2: + prScanDoneMsg->rMsgHdr.eMsgId = MID_SCN_AIS_SCAN_DONE; + break; + case MID_P2P_SCN_SCAN_REQ: + case MID_P2P_SCN_SCAN_REQ_V2: + prScanDoneMsg->rMsgHdr.eMsgId = MID_SCN_P2P_SCAN_DONE; + break; + case MID_BOW_SCN_SCAN_REQ: + case MID_BOW_SCN_SCAN_REQ_V2: + prScanDoneMsg->rMsgHdr.eMsgId = MID_SCN_BOW_SCAN_DONE; + break; + case MID_RLM_SCN_SCAN_REQ: + case MID_RLM_SCN_SCAN_REQ_V2: + prScanDoneMsg->rMsgHdr.eMsgId = MID_SCN_RLM_SCAN_DONE; + break; + default: + log_dbg(SCN, ERROR, "Unexpected Network Type: %d\n"); + cnmMemFree(prAdapter, prScanDoneMsg); + return; + } + + prScanDoneMsg->ucSeqNum = ucSeqNum; + prScanDoneMsg->ucBssIndex = ucBssIndex; + prScanDoneMsg->eScanStatus = eScanStatus; + + mboxSendMsg(prAdapter, MBOX_ID_0, + (struct MSG_HDR *) prScanDoneMsg, MSG_SEND_METHOD_BUF); + +} /* end of scnFsmGenerateScanDoneMsg() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Query for most sparse channel + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +u_int8_t scnQuerySparseChannel(IN struct ADAPTER *prAdapter, + enum ENUM_BAND *prSparseBand, uint8_t *pucSparseChannel) +{ + struct SCAN_INFO *prScanInfo; + + ASSERT(prAdapter); + + prScanInfo = &(prAdapter->rWifiVar.rScanInfo); + + if (prScanInfo->fgIsSparseChannelValid == TRUE) { + if (prSparseBand) + *prSparseBand = prScanInfo->rSparseChannel.eBand; + + if (pucSparseChannel) { + *pucSparseChannel + = prScanInfo->rSparseChannel.ucChannelNum; + } + + return TRUE; + } else { + return FALSE; + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Event handler for schedule scan done event + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void scnEventSchedScanDone(IN struct ADAPTER *prAdapter, + IN struct EVENT_SCHED_SCAN_DONE *prSchedScanDone) +{ + struct SCAN_INFO *prScanInfo; + struct SCHED_SCAN_PARAM *prSchedScanParam; + + prScanInfo = &(prAdapter->rWifiVar.rScanInfo); + prSchedScanParam = &prScanInfo->rSchedScanParam; + + if (prScanInfo->fgSchedScanning == TRUE) { + scanlog_dbg(LOG_SCHED_SCAN_DONE_F2D, INFO, "scnEventSchedScanDone seq %u\n", + prSchedScanDone->ucSeqNum); + + kalSchedScanResults(prAdapter->prGlueInfo); + } else { + scanlog_dbg(LOG_SCHED_SCAN_DONE_F2D, INFO, "Unexpected SCHEDSCANDONE event: Seq = %u, Current State = %d\n", + prSchedScanDone->ucSeqNum, prScanInfo->eCurrentState); + } +} + +#if CFG_SUPPORT_SCHED_SCAN +/*----------------------------------------------------------------------------*/ +/*! + * \brief handler for starting schedule scan + * + * \param[in] + * + * \return TRUE if send sched scan successfully. FALSE otherwise + */ +/*----------------------------------------------------------------------------*/ +u_int8_t +scnFsmSchedScanRequest(IN struct ADAPTER *prAdapter, + IN struct PARAM_SCHED_SCAN_REQUEST *prRequest) +{ + struct SCAN_INFO *prScanInfo; + struct SCHED_SCAN_PARAM *prSchedScanParam; + struct CMD_SCHED_SCAN_REQ *prSchedScanCmd = NULL; + struct SSID_MATCH_SETS *prMatchSets = NULL; + struct PARAM_SSID *prSsid = NULL; + uint32_t i; + uint16_t u2IeLen; + enum ENUM_BAND ePreferedChnl = BAND_NULL; + struct BSS_INFO *prAisBssInfo; + + ASSERT(prAdapter); + ASSERT(prRequest); + ASSERT(prRequest->u4SsidNum <= CFG_SCAN_HIDDEN_SSID_MAX_NUM); + ASSERT(prRequest->u4MatchSsidNum <= CFG_SCAN_SSID_MATCH_MAX_NUM); + log_dbg(SCN, TRACE, "scnFsmSchedScanRequest\n"); + + prAisBssInfo = aisGetAisBssInfo(prAdapter, + prRequest->ucBssIndex); + if (prAisBssInfo == NULL) { + log_dbg(SCN, WARN, "prAisBssInfo is NULL\n"); + return FALSE; + } + + prScanInfo = &(prAdapter->rWifiVar.rScanInfo); + prSchedScanParam = &prScanInfo->rSchedScanParam; + + if (prScanInfo->fgSchedScanning) { + log_dbg(SCN, WARN, "prScanInfo->fgSchedScanning = TRUE already scanning\n"); + + return FALSE; + } + + /* 0. allocate memory for schedule scan command */ + if (prRequest->u4IELength <= MAX_IE_LENGTH) + u2IeLen = (uint16_t)prRequest->u4IELength; + else + u2IeLen = MAX_IE_LENGTH; + + prSchedScanCmd = (struct CMD_SCHED_SCAN_REQ *) cnmMemAlloc(prAdapter, + RAM_TYPE_BUF, sizeof(struct CMD_SCHED_SCAN_REQ) + u2IeLen); + if (!prSchedScanCmd) { + log_dbg(SCN, ERROR, "alloc CMD_SCHED_SCAN_REQ (%zu+%u) fail\n", + sizeof(struct CMD_SCHED_SCAN_REQ), u2IeLen); + return FALSE; + } + kalMemZero(prSchedScanCmd, sizeof(struct CMD_SCHED_SCAN_REQ) + u2IeLen); + prMatchSets = &(prSchedScanCmd->auMatchSsid[0]); + prSsid = &(prSchedScanCmd->auSsid[0]); + + /* 1 Set Sched scan param parameters */ + prSchedScanParam->ucSeqNum++; + prSchedScanParam->ucBssIndex = prAisBssInfo->ucBssIndex; + prSchedScanParam->fgStopAfterIndication = FALSE; + + prSchedScanCmd->ucBssIndex = prSchedScanParam->ucBssIndex; + if (!IS_NET_ACTIVE(prAdapter, prAisBssInfo->ucBssIndex)) { + SET_NET_ACTIVE(prAdapter, prAisBssInfo->ucBssIndex); + /* sync with firmware */ + nicActivateNetwork(prAdapter, + prAisBssInfo->ucBssIndex); + } + + /* 2.1 Prepare command. Set FW struct SSID_MATCH_SETS */ + /* ssid in ssid list will be send in probe request in advance */ + prSchedScanCmd->ucSsidNum = prRequest->u4SsidNum; + for (i = 0; i < prSchedScanCmd->ucSsidNum; i++) { + kalMemCopy(&(prSsid[i]), &(prRequest->arSsid[i]), + sizeof(struct PARAM_SSID)); + log_dbg(SCN, TRACE, "ssid set(%d) %s\n", i, + HIDE(prSsid[i].aucSsid)); + } + + prSchedScanCmd->ucMatchSsidNum = prRequest->u4MatchSsidNum; + for (i = 0; i < prSchedScanCmd->ucMatchSsidNum; i++) { + COPY_SSID(prMatchSets[i].aucSsid, prMatchSets[i].ucSsidLen, + prRequest->arMatchSsid[i].aucSsid, + prRequest->arMatchSsid[i].u4SsidLen); + prMatchSets[i].i4RssiThresold = prRequest->ai4RssiThold[i]; + log_dbg(SCN, TRACE, "Match set(%d) %s, rssi>%d\n", + i, prMatchSets[i].aucSsid, + prMatchSets[i].i4RssiThresold); + } + + /* 2.2 Prepare command. Set channel */ + + ePreferedChnl + = prAdapter->aePreferBand[NETWORK_TYPE_AIS]; + if (ePreferedChnl == BAND_2G4) { + prSchedScanCmd->ucChannelType = + SCHED_SCAN_CHANNEL_TYPE_2G4_ONLY; + prSchedScanCmd->ucChnlNum = 0; + } else if (ePreferedChnl == BAND_5G) { + prSchedScanCmd->ucChannelType = + SCHED_SCAN_CHANNEL_TYPE_5G_ONLY; + prSchedScanCmd->ucChnlNum = 0; + } else if (prRequest->ucChnlNum > 0 && + prRequest->ucChnlNum <= MAXIMUM_OPERATION_CHANNEL_LIST) { + prSchedScanCmd->ucChannelType = + SCHED_SCAN_CHANNEL_TYPE_SPECIFIED; + prSchedScanCmd->ucChnlNum = prRequest->ucChnlNum; + for (i = 0; i < prRequest->ucChnlNum; i++) { + prSchedScanCmd->aucChannel[i].ucChannelNum = + prRequest->pucChannels[i]; + prSchedScanCmd->aucChannel[i].ucBand = + (prSchedScanCmd->aucChannel[i].ucChannelNum <= + HW_CHNL_NUM_MAX_2G4) ? BAND_2G4 : BAND_5G; + } + } else { + prSchedScanCmd->ucChnlNum = 0; + prSchedScanCmd->ucChannelType = + SCHED_SCAN_CHANNEL_TYPE_DUAL_BAND; + } + + prSchedScanCmd->ucSeqNum = prSchedScanParam->ucSeqNum; + prSchedScanCmd->fgStopAfterIndication = + prSchedScanParam->fgStopAfterIndication; + prSchedScanCmd->u2IELen = u2IeLen; + prSchedScanCmd->ucVersion = SCHED_SCAN_CMD_VERSION; + if (prSchedScanCmd->u2IELen) { + kalMemCopy(prSchedScanCmd->aucIE, prRequest->pucIE, + prSchedScanCmd->u2IELen); + } + + prSchedScanCmd->ucScnFuncMask |= prRequest->ucScnFuncMask; + + scnSetSchedScanPlan(prAdapter, prSchedScanCmd); + + log_dbg(SCN, INFO, "V(%u)seq(%u)sz(%zu)chT(%u)chN(%u)ssid(%u)match(%u)IE(%u=>%u)MSP(%u)Func(0x%X)\n", + prSchedScanCmd->ucVersion, + prSchedScanCmd->ucSeqNum, sizeof(struct CMD_SCHED_SCAN_REQ), + prSchedScanCmd->ucChannelType, prSchedScanCmd->ucChnlNum, + prSchedScanCmd->ucSsidNum, prSchedScanCmd->ucMatchSsidNum, + prRequest->u4IELength, prSchedScanCmd->u2IELen, + prSchedScanCmd->ucMspEntryNum, + prSchedScanCmd->ucScnFuncMask); + + /* 3. send command packet to FW */ + do { + if (!scnFsmSchedScanSetCmd(prAdapter, prSchedScanCmd)) { + log_dbg(SCN, TRACE, "scnFsmSchedScanSetCmd failed\n"); + break; + } + if (!scnFsmSchedScanSetAction(prAdapter, + SCHED_SCAN_ACT_ENABLE)) { + log_dbg(SCN, TRACE, "scnFsmSchedScanSetAction failed\n"); + break; + } + prScanInfo->fgSchedScanning = TRUE; + } while (0); + + if (!prScanInfo->fgSchedScanning) + nicDeactivateNetwork(prAdapter, + prAisBssInfo->ucBssIndex); + + cnmMemFree(prAdapter, (void *) prSchedScanCmd); + + return prScanInfo->fgSchedScanning; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief handler for stopping scheduled scan + * + * \param[in] + * + * \return TRUE if send stop command successfully. FALSE otherwise + */ +/*----------------------------------------------------------------------------*/ +u_int8_t scnFsmSchedScanStopRequest(IN struct ADAPTER *prAdapter) +{ + uint8_t ucBssIndex = 0; + + ASSERT(prAdapter); + + ucBssIndex = + prAdapter->rWifiVar.rScanInfo.rSchedScanParam.ucBssIndex; + + if (aisGetAisBssInfo(prAdapter, + ucBssIndex) == NULL) { + log_dbg(SCN, WARN, + "prAisBssInfo%d is NULL\n", + ucBssIndex); + return FALSE; + } + + if (!scnFsmSchedScanSetAction(prAdapter, SCHED_SCAN_ACT_DISABLE)) { + log_dbg(SCN, TRACE, "scnFsmSchedScanSetAction failed\n"); + return FALSE; + } + + prAdapter->rWifiVar.rScanInfo.fgSchedScanning = FALSE; + + return TRUE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief handler for setting schedule scan action + * \param prAdapter adapter + * \param ucSchedScanAct schedule scan action. set enable/disable to FW + * + * \return TRUE if send query command successfully. FALSE otherwise + */ +/*----------------------------------------------------------------------------*/ +u_int8_t +scnFsmSchedScanSetAction(IN struct ADAPTER *prAdapter, + IN enum ENUM_SCHED_SCAN_ACT ucSchedScanAct) +{ + struct CMD_SET_SCHED_SCAN_ENABLE rCmdSchedScanAction; + uint32_t rStatus; + + ASSERT(prAdapter); + + kalMemZero(&rCmdSchedScanAction, + sizeof(struct CMD_SET_SCHED_SCAN_ENABLE)); + + /* 0:enable, 1:disable */ + rCmdSchedScanAction.ucSchedScanAct = ucSchedScanAct; + + if (ucSchedScanAct == SCHED_SCAN_ACT_ENABLE) { + scanlog_dbg(LOG_SCHED_SCAN_REQ_START_D2F, INFO, "sched scan action = %d\n", + rCmdSchedScanAction.ucSchedScanAct); + } else { + scanlog_dbg(LOG_SCHED_SCAN_REQ_STOP_D2F, INFO, "sched scan action = %d\n", + rCmdSchedScanAction.ucSchedScanAct); + } + + rStatus = wlanSendSetQueryCmd(prAdapter, + CMD_ID_SET_SCAN_SCHED_ENABLE, + TRUE, + FALSE, + FALSE, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_SET_SCHED_SCAN_ENABLE), + (uint8_t *)&rCmdSchedScanAction, NULL, 0); + + return (rStatus != WLAN_STATUS_FAILURE) ? TRUE : FALSE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief handler for setting schedule scan command + * \param prAdapter adapter + * \param prSchedScanCmd schedule scan command + * + * \return TRUE if send query command successfully. + * FAIL otherwise + */ +/*----------------------------------------------------------------------------*/ +u_int8_t +scnFsmSchedScanSetCmd(IN struct ADAPTER *prAdapter, + IN struct CMD_SCHED_SCAN_REQ *prSchedScanCmd) +{ + uint16_t u2IeSize = 0; + uint32_t rStatus; + + ASSERT(prAdapter); + + log_dbg(SCN, TRACE, "--> %s()\n", __func__); + + if (prSchedScanCmd) + u2IeSize = prSchedScanCmd->u2IELen; + rStatus = wlanSendSetQueryCmd(prAdapter, + CMD_ID_SET_SCAN_SCHED_REQ, + TRUE, + FALSE, + FALSE, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_SCHED_SCAN_REQ) + u2IeSize, + (uint8_t *) prSchedScanCmd, NULL, 0); + + return (rStatus != WLAN_STATUS_FAILURE) ? TRUE : FALSE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Set schedule scan multiple scan plan (scan interval) + * \param prAdapter adapter + * \param prSchedScanCmd schedule scan command request + * + * \return void + */ +/*----------------------------------------------------------------------------*/ +void +scnSetSchedScanPlan(IN struct ADAPTER *prAdapter, + IN struct CMD_SCHED_SCAN_REQ *prSchedScanCmd) +{ + /* Set Multiple Scan Plan here */ + log_dbg(SCN, TRACE, "--> %s()\n", __func__); + + ASSERT(prAdapter); + + prSchedScanCmd->ucMspEntryNum = 0; + kalMemZero(prSchedScanCmd->au2MspList, + sizeof(prSchedScanCmd->au2MspList)); +} + +#endif /* CFG_SUPPORT_SCHED_SCAN */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/stats.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/stats.c new file mode 100644 index 0000000000000000000000000000000000000000..8b12512e35c8885b87df7392b72c98a09d7e899e --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/stats.c @@ -0,0 +1,814 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 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. + * + * You should have received a copy of the GNU General Public License along with + * this program. + * If not, see . + */ + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" + +#if (CFG_SUPPORT_STATISTICS == 1) + +enum EVENT_TYPE { + EVENT_RX, + EVENT_TX, +}; +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E F U N C T I O N S + ******************************************************************************* + */ + +uint32_t u4TotalTx; +uint32_t u4NoDelayTx; +uint32_t u4TotalRx; +uint32_t u4NoDelayRx; + +static uint8_t g_ucTxRxFlag; +static uint8_t g_ucTxIpProto; +static uint16_t g_u2TxUdpPort; +static uint32_t g_u4TxDelayThreshold; +static uint8_t g_ucRxIpProto; +static uint16_t g_u2RxUdpPort; +static uint32_t g_u4RxDelayThreshold; + +void StatsResetTxRx(void) +{ + u4TotalRx = 0; + u4TotalTx = 0; + u4NoDelayRx = 0; + u4NoDelayTx = 0; +} + +uint64_t StatsEnvTimeGet(void) +{ + uint64_t u8Clk; + + u8Clk = sched_clock(); /* unit: naro seconds */ + + return (uint64_t) u8Clk; /* sched_clock *//* jiffies size = 4B */ +} + +void StatsEnvGetPktDelay(OUT uint8_t *pucTxRxFlag, + OUT uint8_t *pucTxIpProto, OUT uint16_t *pu2TxUdpPort, + OUT uint32_t *pu4TxDelayThreshold, OUT uint8_t *pucRxIpProto, + OUT uint16_t *pu2RxUdpPort, OUT uint32_t *pu4RxDelayThreshold) +{ + *pucTxRxFlag = g_ucTxRxFlag; + *pucTxIpProto = g_ucTxIpProto; + *pu2TxUdpPort = g_u2TxUdpPort; + *pu4TxDelayThreshold = g_u4TxDelayThreshold; + *pucRxIpProto = g_ucRxIpProto; + *pu2RxUdpPort = g_u2RxUdpPort; + *pu4RxDelayThreshold = g_u4RxDelayThreshold; +} + +void StatsEnvSetPktDelay(IN uint8_t ucTxOrRx, IN uint8_t ucIpProto, + IN uint16_t u2UdpPort, uint32_t u4DelayThreshold) +{ +#define MODULE_RESET 0 +#define MODULE_TX 1 +#define MODULE_RX 2 + + if (ucTxOrRx == MODULE_TX) { + g_ucTxRxFlag |= BIT(0); + g_ucTxIpProto = ucIpProto; + g_u2TxUdpPort = u2UdpPort; + g_u4TxDelayThreshold = u4DelayThreshold; + } else if (ucTxOrRx == MODULE_RX) { + g_ucTxRxFlag |= BIT(1); + g_ucRxIpProto = ucIpProto; + g_u2RxUdpPort = u2UdpPort; + g_u4RxDelayThreshold = u4DelayThreshold; + } else if (ucTxOrRx == MODULE_RESET) { + g_ucTxRxFlag = 0; + g_ucTxIpProto = 0; + g_u2TxUdpPort = 0; + g_u4TxDelayThreshold = 0; + g_ucRxIpProto = 0; + g_u2RxUdpPort = 0; + g_u4RxDelayThreshold = 0; + } +} + +void StatsEnvRxTime2Host(IN struct ADAPTER *prAdapter, + struct sk_buff *prSkb, struct net_device *prNetDev) +{ + uint8_t *pucEth = prSkb->data; + uint16_t u2EthType = 0; + uint8_t ucIpVersion = 0; + uint8_t ucIpProto = 0; + uint16_t u2IPID = 0; + uint16_t u2UdpDstPort = 0; + uint16_t u2UdpSrcPort = 0; + uint64_t u8IntTime = 0; + uint64_t u8RxTime = 0; + uint32_t u4Delay = 0; + struct timeval tval; + struct rtc_time tm; + + u2EthType = (pucEth[ETH_TYPE_LEN_OFFSET] << 8) + | (pucEth[ETH_TYPE_LEN_OFFSET + 1]); + pucEth += ETH_HLEN; + u2IPID = pucEth[4] << 8 | pucEth[5]; + + DBGLOG(RX, TEMP, "u2IpId=%d rx_packets=%lu\n", + u2IPID, prNetDev->stats.rx_packets); + + if ((g_ucTxRxFlag & BIT(1)) == 0) + return; + if (prSkb->len <= 24 + ETH_HLEN) + return; + if (u2EthType != ETH_P_IPV4) + return; + ucIpProto = pucEth[9]; + if (g_ucRxIpProto && (ucIpProto != g_ucRxIpProto)) + return; + ucIpVersion = (pucEth[0] & IPVH_VERSION_MASK) >> IPVH_VERSION_OFFSET; + if (ucIpVersion != IPVERSION) + return; + u2IPID = pucEth[4] << 8 | pucEth[5]; + u8IntTime = GLUE_RX_GET_PKT_INT_TIME(prSkb); + u4Delay = ((uint32_t)(sched_clock() - u8IntTime))/NSEC_PER_USEC; + u8RxTime = GLUE_RX_GET_PKT_RX_TIME(prSkb); + do_gettimeofday(&tval); + rtc_time_to_tm(tval.tv_sec, &tm); + + switch (ucIpProto) { + case IP_PRO_TCP: + case IP_PRO_UDP: + u2UdpSrcPort = (pucEth[20] << 8) | pucEth[21]; + u2UdpDstPort = (pucEth[22] << 8) | pucEth[23]; + if (g_u2RxUdpPort && (u2UdpSrcPort != g_u2RxUdpPort)) + break; + case IP_PRO_ICMP: + u4TotalRx++; + if (g_u4RxDelayThreshold && (u4Delay <= g_u4RxDelayThreshold)) { + u4NoDelayRx++; + break; + } + DBGLOG(RX, INFO, + "IPID 0x%04x src %d dst %d UP %d,delay %u us,int2rx %lu us,IntTime %llu,%u/%u,leave at %02d:%02d:%02d.%06ld\n", + u2IPID, u2UdpSrcPort, u2UdpDstPort, + ((pucEth[1] & IPTOS_PREC_MASK) >> IPTOS_PREC_OFFSET), + u4Delay, + ((uint32_t)(u8RxTime - u8IntTime))/NSEC_PER_USEC, + u8IntTime, u4NoDelayRx, u4TotalRx, + tm.tm_hour, tm.tm_min, tm.tm_sec, tval.tv_usec); + break; + default: + break; + } +} + +void StatsEnvTxTime2Hif(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo) +{ + uint64_t u8SysTime, u8SysTimeIn; + uint32_t u4TimeDiff; + uint8_t *pucEth; + uint32_t u4PacketLen; + uint8_t ucIpVersion = 0; + uint8_t ucIpProto = 0; + uint8_t *pucEthBody = NULL; + uint16_t u2EthType = 0; + uint8_t *pucAheadBuf = NULL; + uint16_t u2IPID = 0; + uint16_t u2UdpDstPort = 0; + uint16_t u2UdpSrcPort = 0; + + if (prMsduInfo == NULL) { + DBGLOG(TX, ERROR, "prMsduInfo=NULL"); + return; + } + + if (prMsduInfo->prPacket == NULL) { + DBGLOG(TX, ERROR, "prMsduInfo->prPacket=NULL"); + return; + } + + kalTraceEvent("Move ipid=0x%04x sn=%d", + GLUE_GET_PKT_IP_ID(prMsduInfo->prPacket), + GLUE_GET_PKT_SEQ_NO(prMsduInfo->prPacket)); + + pucEth = ((struct sk_buff *)prMsduInfo->prPacket)->data; + + if (pucEth == NULL) { + DBGLOG(TX, ERROR, "pucEth=NULL"); + return; + } + + u4PacketLen = ((struct sk_buff *)prMsduInfo->prPacket)->len; + + u8SysTime = StatsEnvTimeGet(); + u8SysTimeIn = GLUE_GET_PKT_XTIME(prMsduInfo->prPacket); + + if ((g_ucTxRxFlag & BIT(0)) == 0) + return; + + if ((u8SysTimeIn == 0) || (u8SysTime <= u8SysTimeIn)) + return; + + /* units of u4TimeDiff is micro seconds (us) */ + if (u4PacketLen < 24 + ETH_HLEN) + return; + pucAheadBuf = &pucEth[76]; + u2EthType = (pucAheadBuf[ETH_TYPE_LEN_OFFSET] << 8) + | (pucAheadBuf[ETH_TYPE_LEN_OFFSET + 1]); + pucEthBody = &pucAheadBuf[ETH_HLEN]; + if (u2EthType != ETH_P_IPV4) + return; + ucIpProto = pucEthBody[9]; + if (g_ucTxIpProto && (ucIpProto != g_ucTxIpProto)) + return; + ucIpVersion = (pucEthBody[0] & IPVH_VERSION_MASK) + >> IPVH_VERSION_OFFSET; + if (ucIpVersion != IPVERSION) + return; + u2IPID = pucEthBody[4]<<8 | pucEthBody[5]; + u8SysTime = u8SysTime - u8SysTimeIn; + u4TimeDiff = (uint32_t) u8SysTime; + u4TimeDiff = u4TimeDiff / 1000; /* ns to us */ + + switch (ucIpProto) { + case IP_PRO_TCP: + case IP_PRO_UDP: + u2UdpDstPort = (pucEthBody[22] << 8) | pucEthBody[23]; + u2UdpSrcPort = (pucEthBody[20] << 8) | pucEthBody[21]; + if (g_u2TxUdpPort && (u2UdpDstPort != g_u2TxUdpPort)) + break; + case IP_PRO_ICMP: + u4TotalTx++; + if (g_u4TxDelayThreshold + && (u4TimeDiff <= g_u4TxDelayThreshold)) { + u4NoDelayTx++; + break; + } + DBGLOG(TX, INFO, + "IPID 0x%04x src %d dst %d UP %d,delay %u us,u8SysTimeIn %llu, %u/%u\n", + u2IPID, u2UdpSrcPort, u2UdpDstPort, + ((pucEthBody[1] & IPTOS_PREC_MASK) + >> IPTOS_PREC_OFFSET), + u4TimeDiff, u8SysTimeIn, u4NoDelayTx, u4TotalTx); + break; + default: + break; + } +} + +void statsParseARPInfo(struct sk_buff *skb, + uint8_t *pucEthBody, uint8_t eventType) +{ + uint16_t u2OpCode = (pucEthBody[6] << 8) | pucEthBody[7]; + + switch (eventType) { + case EVENT_RX: + GLUE_SET_INDEPENDENT_PKT(skb, TRUE); + if (u2OpCode == ARP_PRO_REQ) + DBGLOG_LIMITED(RX, INFO, + " Arp Req From IP: %d.%d.%d.%d\n", + pucEthBody[14], pucEthBody[15], + pucEthBody[16], pucEthBody[17]); + else if (u2OpCode == ARP_PRO_RSP) + DBGLOG(RX, INFO, + " Arp Rsp from IP: %d.%d.%d.%d\n", + pucEthBody[14], pucEthBody[15], + pucEthBody[16], pucEthBody[17]); + break; + case EVENT_TX: + DBGLOG(TX, INFO, + "ARP %s SRC MAC/IP[" + MACSTR "]/[" IPV4STR "], TAR MAC/IP[" + MACSTR "]/[" IPV4STR "], SeqNo: %d\n", + u2OpCode == ARP_OPERATION_REQUEST ? "REQ" : "RSP", + MAC2STR(&pucEthBody[ARP_SENDER_MAC_OFFSET]), + IPV4TOSTR(&pucEthBody[ARP_SENDER_IP_OFFSET]), + MAC2STR(&pucEthBody[ARP_TARGET_MAC_OFFSET]), + IPV4TOSTR(&pucEthBody[ARP_TARGET_IP_OFFSET]), + GLUE_GET_PKT_SEQ_NO(skb)); + break; + } +} + +void statsParseUDPInfo(struct sk_buff *skb, uint8_t *pucEthBody, + uint8_t eventType, uint16_t u2IpId) +{ + /* the number of DHCP packets is seldom so we print log here */ + uint8_t *pucUdp = &pucEthBody[20]; + uint8_t *pucBootp = &pucUdp[UDP_HDR_LEN]; + struct BOOTP_PROTOCOL *prBootp = NULL; + uint16_t u2UdpDstPort; + uint16_t u2UdpSrcPort; + uint32_t u4TransID; + uint32_t u4DhcpMagicCode; + char buf[50] = {0}; + + prBootp = (struct BOOTP_PROTOCOL *) &pucUdp[UDP_HDR_LEN]; + u2UdpDstPort = (pucUdp[2] << 8) | pucUdp[3]; + u2UdpSrcPort = (pucUdp[0] << 8) | pucUdp[1]; + if (u2UdpDstPort == UDP_PORT_DHCPS || u2UdpDstPort == UDP_PORT_DHCPC) { + WLAN_GET_FIELD_BE32(&prBootp->u4TransId, &u4TransID); + switch (eventType) { + case EVENT_RX: + GLUE_SET_INDEPENDENT_PKT(skb, TRUE); + + WLAN_GET_FIELD_BE32(&prBootp->aucOptions[0], + &u4DhcpMagicCode); + if (u4DhcpMagicCode == DHCP_MAGIC_NUMBER) { + uint32_t u4Opt; + + WLAN_GET_FIELD_BE32(&prBootp->aucOptions[4], + &u4Opt); + switch (u4Opt & 0xffffff00) { + case 0x35010100: + kalSnprintf(buf, 49, "DISCOVERY"); + break; + case 0x35010200: + kalSnprintf(buf, 49, "OFFER"); + break; + case 0x35010300: + kalSnprintf(buf, 49, "REQUEST"); + break; + case 0x35010500: + kalSnprintf(buf, 49, "ACK"); + break; + case 0x35010600: + kalSnprintf(buf, 49, "NAK"); + break; + } + } + DBGLOG_LIMITED(RX, INFO, + " DHCP: Recv %s IPID 0x%02x, MsgType 0x%x, TransID 0x%04x\n", + buf, u2IpId, prBootp->aucOptions[6], + u4TransID); + break; + case EVENT_TX: + { + uint32_t u4Xid = 0; + uint32_t u4Opt = 0; + + WLAN_GET_FIELD_BE32(&prBootp->aucOptions[0], + &u4DhcpMagicCode); + if (u4DhcpMagicCode == DHCP_MAGIC_NUMBER) { + WLAN_GET_FIELD_BE32(&prBootp->u4TransId, + &u4Xid); + WLAN_GET_FIELD_BE32(&prBootp->aucOptions[4], + &u4Opt); + + switch (u4Opt & 0xffffff00) { + case 0x35010100: + kalSnprintf(buf, 49, + "client DISCOVERY"); + break; + case 0x35010200: + kalSnprintf(buf, 49, "server OFFER"); + break; + case 0x35010300: + kalSnprintf(buf, 49, "client REQUEST"); + break; + case 0x35010500: + kalSnprintf(buf, 49, "server ACK"); + break; + case 0x35010600: + kalSnprintf(buf, 49, "server NAK"); + break; + } + } + + DBGLOG_LIMITED(TX, INFO, + " DHCP %s, XID[0x%08x] OPT[0x%08x] TYPE[%u], SeqNo: %d\n", + buf, u4Xid, u4Opt, prBootp->aucOptions[6], + GLUE_GET_PKT_SEQ_NO(skb)); + } + break; + } + } else if (u2UdpSrcPort == UDP_PORT_DNS) { /* tx dns */ + uint16_t u2TransId = + (pucBootp[0] << 8) | pucBootp[1]; + if (eventType == EVENT_RX) { + GLUE_SET_INDEPENDENT_PKT(skb, TRUE); + DBGLOG_LIMITED(RX, INFO, + " DNS: IPID 0x%02x, TransID 0x%04x\n", + u2IpId, u2TransId); + } else if (eventType == EVENT_TX) { + DBGLOG_LIMITED(TX, INFO, + " DNS: IPID[0x%02x] TransID[0x%04x] SeqNo[%d]\n", + u2IpId, u2TransId, GLUE_GET_PKT_SEQ_NO(skb)); + } + } +} + +void statsParseIPV4Info(struct sk_buff *skb, + uint8_t *pucEthBody, uint8_t eventType) +{ + /* IP header without options */ + uint8_t ucIpProto = pucEthBody[9]; + uint8_t ucIpVersion = + (pucEthBody[0] & IPVH_VERSION_MASK) + >> IPVH_VERSION_OFFSET; + uint16_t u2IpId = pucEthBody[4] << 8 | pucEthBody[5]; + + if (ucIpVersion != IPVERSION) + return; + + GLUE_SET_PKT_IP_ID(skb, u2IpId); + switch (ucIpProto) { + case IP_PRO_ICMP: + { + /* the number of ICMP packets is seldom so we print log here */ + uint8_t ucIcmpType; + uint16_t u2IcmpId, u2IcmpSeq; + uint8_t *pucIcmp = &pucEthBody[20]; + + ucIcmpType = pucIcmp[0]; + /* don't log network unreachable packet */ + if (ucIcmpType == 3) + break; + u2IcmpId = *(uint16_t *) &pucIcmp[4]; + u2IcmpSeq = *(uint16_t *) &pucIcmp[6]; + switch (eventType) { + case EVENT_RX: + GLUE_SET_INDEPENDENT_PKT(skb, TRUE); + DBGLOG_LIMITED(RX, INFO, + " ICMP: Type %d, Id BE 0x%04x, Seq BE 0x%04x\n", + ucIcmpType, u2IcmpId, u2IcmpSeq); + break; + case EVENT_TX: + DBGLOG_LIMITED(TX, INFO, + " ICMP: IPID[0x%04x] Type %d, Id 0x%04x, Seq BE 0x%04x, SeqNo: %d\n", + u2IpId, ucIcmpType, u2IcmpId, u2IcmpSeq, + GLUE_GET_PKT_SEQ_NO(skb)); + break; + } + break; + } + case IP_PRO_UDP: + statsParseUDPInfo(skb, pucEthBody, eventType, u2IpId); + } +} + +void statsLogData(uint8_t eventType, enum WAKE_DATA_TYPE wakeType) +{ + if (eventType == EVENT_TX) + wlanLogTxData(wakeType); + else if (eventType == EVENT_RX) + wlanLogRxData(wakeType); +} + +static void statsParsePktInfo(uint8_t *pucPkt, struct sk_buff *skb, + uint8_t status, uint8_t eventType) +{ + /* get ethernet protocol */ + uint16_t u2EtherType = + (pucPkt[ETH_TYPE_LEN_OFFSET] << 8) + | (pucPkt[ETH_TYPE_LEN_OFFSET + 1]); + uint8_t *pucEthBody = &pucPkt[ETH_HLEN]; + + switch (u2EtherType) { + case ETH_P_ARP: + { + statsLogData(eventType, WLAN_WAKE_ARP); + statsParseARPInfo(skb, pucEthBody, eventType); + break; + } + case ETH_P_IPV4: + { + statsLogData(eventType, WLAN_WAKE_IPV4); + statsParseIPV4Info(skb, pucEthBody, eventType); + break; + } + case ETH_P_IPV6: + { + /* IPv6 header without options */ + uint8_t ucIpv6Proto = + pucEthBody[IPV6_HDR_PROTOCOL_OFFSET]; + uint8_t ucIpVersion = + (pucEthBody[0] & IPVH_VERSION_MASK) + >> IPVH_VERSION_OFFSET; + + if (ucIpVersion != IP_VERSION_6) + break; + + statsLogData(eventType, WLAN_WAKE_IPV6); + switch (ucIpv6Proto) { + case 0x06:/*tcp*/ + switch (eventType) { + case EVENT_RX: + DBGLOG(RX, TRACE, " tcp packet\n"); + break; + case EVENT_TX: + DBGLOG(TX, TRACE, " tcp packet\n"); + break; + } + break; + + case 0x11:/*UDP*/ + switch (eventType) { + case EVENT_RX: + { + uint16_t ucIpv6UDPSrcPort = 0; + + /* IPv6 header without options */ + ucIpv6UDPSrcPort = pucEthBody[IPV6_HDR_LEN]; + ucIpv6UDPSrcPort = ucIpv6UDPSrcPort << 8; + ucIpv6UDPSrcPort += + pucEthBody[IPV6_HDR_LEN + 1]; + + switch (ucIpv6UDPSrcPort) { + case 53:/*dns port*/ + DBGLOG(RX, TRACE, + " dns packet\n"); + GLUE_SET_INDEPENDENT_PKT(skb, TRUE); + break; + case 547:/*dhcp*/ + case 546: + DBGLOG(RX, INFO, + " dhcp packet\n"); + GLUE_SET_INDEPENDENT_PKT(skb, TRUE); + break; + case 123:/*ntp port*/ + DBGLOG(RX, INFO, + " ntp packet\n"); + GLUE_SET_INDEPENDENT_PKT(skb, TRUE); + break; + default: + DBGLOG(RX, TRACE, + " other packet srtport=%u\n", + ucIpv6UDPSrcPort); + break; + } + } + break; + case EVENT_TX: + DBGLOG(TX, INFO, " UDP packet\n"); + break; + } + break; + + case 0x00:/*IPv6 hop-by-hop*/ + switch (eventType) { + case EVENT_RX: + /*need chech detai pakcet type*/ + /*130 mlti listener query*/ + /*143 multi listener report v2*/ + GLUE_SET_INDEPENDENT_PKT(skb, TRUE); + + DBGLOG(RX, INFO, + " hop-by-hop packet\n"); + break; + case EVENT_TX: + DBGLOG(TX, INFO, + " hop-by-hop packet\n"); + break; + } + break; + + case 0x3a:/*ipv6 ICMPV6*/ + switch (eventType) { + case EVENT_RX: + { + uint8_t ucICMPv6Type = 0; + + /* IPv6 header without options */ + ucICMPv6Type = pucEthBody[IPV6_HDR_LEN]; + GLUE_SET_INDEPENDENT_PKT(skb, TRUE); + + switch (ucICMPv6Type) { + case 0x85: /*ICMPV6_TYPE_ROUTER_SOLICITATION*/ + DBGLOG_LIMITED(RX, INFO, + " ICMPV6 Router Solicitation\n"); + break; + + case 0x86: /*ICMPV6_TYPE_ROUTER_ADVERTISEMENT*/ + DBGLOG_LIMITED(RX, INFO, + " ICMPV6 Router Advertisement\n"); + break; + + case ICMPV6_TYPE_NEIGHBOR_SOLICITATION: + DBGLOG_LIMITED(RX, INFO, + " ICMPV6 Neighbor Solicitation\n"); + break; + + case ICMPV6_TYPE_NEIGHBOR_ADVERTISEMENT: + DBGLOG_LIMITED(RX, INFO, + " ICMPV6 Neighbor Advertisement\n"); + break; + default: + DBGLOG_LIMITED(RX, INFO, + " ICMPV6 type=%u\n", + ucICMPv6Type); + break; + } + } + break; + case EVENT_TX: + DBGLOG_LIMITED(TX, INFO, + " ICMPV6 packet\n"); + break; + } + break; + default: + if (eventType == EVENT_RX) + DBGLOG(RX, INFO, + " default protocol=%u\n", + ucIpv6Proto); + break; + } + break; + } + case ETH_P_1X: + { + uint8_t *pucEapol = pucEthBody; + uint8_t ucEapolType = pucEapol[1]; + uint16_t u2KeyInfo = 0; + uint8_t m = 0; + + statsLogData(eventType, WLAN_WAKE_1X); + switch (ucEapolType) { + case 0: /* eap packet */ + switch (eventType) { + case EVENT_RX: + DBGLOG(RX, INFO, + " EAP Packet: code %d, id %d, type %d\n", + pucEapol[4], pucEapol[5], pucEapol[7]); + break; + case EVENT_TX: + DBGLOG(TX, INFO, + " EAP Packet: code %d, id %d, type %d, SeqNo: %d\n", + pucEapol[4], pucEapol[5], pucEapol[7], + GLUE_GET_PKT_SEQ_NO(skb)); + break; + } + break; + case 1: /* eapol start */ + switch (eventType) { + case EVENT_RX: + DBGLOG(RX, INFO, + " EAPOL: start\n"); + break; + case EVENT_TX: + DBGLOG(TX, INFO, + " EAPOL: start, SeqNo: %d\n", + GLUE_GET_PKT_SEQ_NO(skb)); + break; + } + break; + case ETH_EAPOL_KEY: /* key */ + WLAN_GET_FIELD_BE16(&pucEapol[5], &u2KeyInfo); + switch (eventType) { + case EVENT_RX: + if ((u2KeyInfo & 0xfff0) == 0x0080) + m = 1; + else if ((u2KeyInfo & 0xfff0) == 0x13c0) + m = 3; + DBGLOG(RX, INFO, + " EAPOL: key, M%d, KeyInfo 0x%04x\n", + m, u2KeyInfo); + break; + case EVENT_TX: + if ((u2KeyInfo & 0xfff0) == 0x0100) + m = 2; + else if ((u2KeyInfo & 0xfff0) == 0x0300) + m = 4; + DBGLOG(TX, INFO, + " EAPOL: key, M%d, KeyInfo 0x%04x SeqNo: %d\n", + m, u2KeyInfo, GLUE_GET_PKT_SEQ_NO(skb)); + break; + } + break; + } + break; + } +#if CFG_SUPPORT_WAPI + case ETH_WPI_1X: + { + uint8_t ucSubType = pucEthBody[3]; /* sub type filed*/ + uint16_t u2Length = *(uint16_t *)&pucEthBody[6]; + uint16_t u2Seq = *(uint16_t *)&pucEthBody[8]; + + statsLogData(eventType, WLAN_WAKE_1X); + switch (eventType) { + case EVENT_RX: + DBGLOG(RX, INFO, + " WAPI: subType %d, Len %d, Seq %d\n", + ucSubType, u2Length, u2Seq); + break; + case EVENT_TX: + DBGLOG(TX, INFO, + " WAPI: subType %d, Len %d, Seq %d, SeqNo: %d\n", + ucSubType, u2Length, u2Seq, + GLUE_GET_PKT_SEQ_NO(skb)); + break; + } + break; + } +#endif + case ETH_PRO_TDLS: + statsLogData(eventType, WLAN_WAKE_TDLS); + switch (eventType) { + case EVENT_RX: + DBGLOG(RX, INFO, + " TDLS type %d, category %d, Action %d, Token %d\n", + pucEthBody[0], pucEthBody[1], + pucEthBody[2], pucEthBody[3]); + break; + case EVENT_TX: + DBGLOG(TX, INFO, + " TDLS type %d, category %d, Action %d, Token %d\n", + pucEthBody[0], pucEthBody[1], + pucEthBody[2], pucEthBody[3]); + break; + } + break; + default: + statsLogData(eventType, WLAN_WAKE_OTHER); + break; + } +} +/*----------------------------------------------------------------------------*/ +/*! \brief This routine is called to display rx packet information. + * + * \param[in] pPkt Pointer to the packet + * \param[out] None + * + * \retval None + */ +/*----------------------------------------------------------------------------*/ +void StatsRxPktInfoDisplay(struct SW_RFB *prSwRfb) +{ + uint8_t *pPkt = NULL; + struct sk_buff *skb = NULL; + + if (prSwRfb->u2PacketLen <= ETHER_HEADER_LEN) + return; + + pPkt = prSwRfb->pvHeader; + if (!pPkt) + return; + + skb = (struct sk_buff *)(prSwRfb->pvPacket); + if (!skb) + return; + + statsParsePktInfo(pPkt, skb, 0, EVENT_RX); + + DBGLOG(RX, TEMP, "RxPkt p=%p ipid=%d\n", + prSwRfb, GLUE_GET_PKT_IP_ID(skb)); + kalTraceEvent("RxPkt p=%p ipid=0x%04x", + prSwRfb, GLUE_GET_PKT_IP_ID(skb)); +} + +/*----------------------------------------------------------------------------*/ +/*! \brief This routine is called to display tx packet information. + * + * \param[in] pPkt Pointer to the packet + * \param[out] None + * + * \retval None + */ +/*----------------------------------------------------------------------------*/ +void StatsTxPktInfoDisplay(struct sk_buff *prSkb) +{ + uint8_t *pPkt; + + pPkt = prSkb->data; + statsParsePktInfo(pPkt, prSkb, 0, EVENT_TX); +} + +#endif /* CFG_SUPPORT_STATISTICS */ + +/* End of stats.c */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/swcr.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/swcr.c new file mode 100644 index 0000000000000000000000000000000000000000..e7b3121958235fe721daed340dd18c8d34911006 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/swcr.c @@ -0,0 +1,1470 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/swcr.c#1 + */ + +/*! \file "swcr.c" + * \brief + * + */ + + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" +#include "swcr.h" + +#if CFG_SUPPORT_SWCR + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ +uint32_t g_au4SwCr[SWCR_CR_NUM]; /*: 0: command other: data */ + +/* JB mDNS Filter*/ +uint32_t g_u4RXFilter; /* [31] 0: stop 1: start, [3] IPv6 [2] IPv4 */ + +static struct TIMER g_rSwcrDebugTimer; +static u_int8_t g_fgSwcrDebugTimer = FALSE; +static uint32_t g_u4SwcrDebugCheckTimeout; +static enum ENUM_SWCR_DBG_TYPE g_ucSwcrDebugCheckType; +static uint32_t g_u4SwcrDebugFrameDumpType; + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ +static const PFN_CMD_RW_T g_arSwCtrlCmd[] = { + swCtrlCmdCategory0, + swCtrlCmdCategory1 +#if TEST_PS + , testPsCmdCategory0, testPsCmdCategory1 +#endif +#if CFG_SUPPORT_802_11V +#if (CFG_SUPPORT_802_11V_TIMING_MEASUREMENT == 1) && (WNM_UNIT_TEST == 1) + , testWNMCmdCategory0 +#endif +#endif +}; + +const PFN_SWCR_RW_T g_arSwCrModHandle[] = { + swCtrlSwCr, + NULL +}; + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +enum { + SWCTRL_MAGIC, + SWCTRL_DEBUG, + SWCTRL_WIFI_VAR, + SWCTRL_ENABLE_INT, + SWCTRL_DISABLE_INT, + SWCTRL_TXM_INFO, + SWCTRL_RXM_INFO, + SWCTRL_DUMP_BSS, + SWCTRL_QM_INFO, + SWCTRL_DUMP_ALL_QUEUE_LEN, + SWCTRL_DUMP_MEM, + SWCTRL_TX_CTRL_INFO, + SWCTRL_DUMP_QUEUE, + SWCTRL_DUMP_QM_DBG_CNT, + SWCTRL_QM_DBG_CNT, + SWCTRL_RX_PKTS_DUMP, + SWCTRL_RX_FILTER, +#if CFG_INIT_ENABLE_PATTERN_FILTER_ARP + SWCTRL_RX_ARP_OFFLOAD, +#endif + SWCTRL_PS_DTIM_SKIP, + SWCTRL_ROAMING, + SWCTRL_CATA0_INDEX_NUM +}; + +enum { + SWCTRL_STA_INFO, + SWCTRL_DUMP_STA, + SWCTRL_STA_QUE_INFO, + SWCTRL_CATA1_INDEX_NUM +}; + +/* JB mDNS Filter*/ +#define RX_FILTER_START (1<<31) +#define RX_FILTER_IPV4 (1<<2) +#define RX_FILTER_IPV6 (1<<3) +enum ENUM_SWCR_RX_FILTER_CMD { + SWCR_RX_FILTER_CMD_STOP = 0, + SWCR_RX_FILTER_CMD_START, + SWCR_RX_FILTER_CMD_ADD, + SWCR_RX_FILTER_CMD_REMOVE, + SWCR_RX_FILTER_NUM +}; + +#if TEST_PS +enum { + TEST_PS_MAGIC, + TEST_PS_SETUP_BSS, + TEST_PS_ENABLE_BEACON, + TEST_PS_TRIGGER_BMC, + TEST_PS_SEND_NULL, + TEST_PS_BUFFER_BMC, + TEST_PS_UPDATE_BEACON, + TEST_PS_CATA0_INDEX_NUM +}; + +enum { + TEST_PS_STA_PS, + TEST_PS_STA_ENTER_PS, + TEST_PS_STA_EXIT_PS, + TEST_PS_STA_TRIGGER_PSPOLL, + TEST_PS_STA_TRIGGER_FRAME, + TEST_PS_CATA1_INDEX_NUM +}; +#endif + +#if CFG_SUPPORT_802_11V +#if WNM_UNIT_TEST +enum { + TEST_WNM_TIMING_MEAS, + TEST_WNM_CATA0_INDEX_NUM +}; +#endif +#endif + +#define _SWCTRL_MAGIC 0x66201642 + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +void dumpQueue(struct ADAPTER *prAdapter) +{ + + struct TX_CTRL *prTxCtrl; + struct QUE_MGT *prQM; + struct GLUE_INFO *prGlueInfo; + uint32_t i; + uint32_t j; + + DEBUGFUNC("dumpQueue"); + + prTxCtrl = &prAdapter->rTxCtrl; + prQM = &prAdapter->rQM; + prGlueInfo = prAdapter->prGlueInfo; +#if QM_ADAPTIVE_TC_RESOURCE_CTRL + for (i = TC0_INDEX; i < TC_NUM; i++) { + DBGLOG(SW4, INFO, "TC %u\n", i); + DBGLOG(SW4, INFO, "Max %u Free %u\n", + prTxCtrl->rTc.au4MaxNumOfBuffer[i], + prTxCtrl->rTc.au4FreeBufferCount[i]); + + DBGLOG(SW4, INFO, + "Average %u minReserved %u CurrentTcResource %u GuaranteedTcResource %u\n", + QM_GET_TX_QUEUE_LEN(prAdapter, i), + prQM->au4MinReservedTcResource[i], + prQM->au4CurrentTcResource[i], + prQM->au4GuaranteedTcResource[i]); + + } +#endif + +#if QM_FORWARDING_FAIRNESS + for (i = 0; i < NUM_OF_PER_STA_TX_QUEUES; i++) { + DBGLOG(SW4, INFO, + "TC %u HeadStaIdx %u ForwardCount %u\n", i, + prQM->au4HeadStaRecIndex[i], + prQM->au4ResourceUsedCount[i]); + } +#endif + + DBGLOG(SW4, INFO, "BMC or unknown TxQueue Len %u\n", + prQM->arTxQueue[0].u4NumElem); + DBGLOG(SW4, INFO, "Pending %d\n", + prGlueInfo->i4TxPendingFrameNum); + DBGLOG(SW4, INFO, "Pending Security %d\n", + prGlueInfo->i4TxPendingSecurityFrameNum); +#if defined(LINUX) + for (i = 0; i < 4; i++) { + for (j = 0; j < CFG_MAX_TXQ_NUM; j++) { + DBGLOG(SW4, INFO, + "Pending Q[%u][%u] %d\n", i, j, + prGlueInfo->ai4TxPendingFrameNumPerQueue[i][j]); + } + } +#endif + + DBGLOG(SW4, INFO, " rFreeSwRfbList %u\n", + prAdapter->rRxCtrl.rFreeSwRfbList.u4NumElem); + DBGLOG(SW4, INFO, " rReceivedRfbList %u\n", + prAdapter->rRxCtrl.rReceivedRfbList.u4NumElem); + DBGLOG(SW4, INFO, " rIndicatedRfbList %u\n", + prAdapter->rRxCtrl.rIndicatedRfbList.u4NumElem); + DBGLOG(SW4, INFO, " ucNumIndPacket %u\n", + prAdapter->rRxCtrl.ucNumIndPacket); + DBGLOG(SW4, INFO, " ucNumRetainedPacket %u\n", + prAdapter->rRxCtrl.ucNumRetainedPacket); + +} + +void dumpSTA(struct ADAPTER *prAdapter, struct STA_RECORD *prStaRec) +{ + uint8_t ucWTEntry; + uint32_t i; + struct BSS_INFO *prBssInfo; + + DEBUGFUNC("dumpSTA"); + + ASSERT(prStaRec); + ucWTEntry = prStaRec->ucWlanIndex; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex); + ASSERT(prBssInfo); + + DBGLOG(SW4, INFO, "Mac address: " MACSTR " Rcpi %u\n", + MAC2STR(prStaRec->aucMacAddr), prStaRec->ucRCPI); + + DBGLOG(SW4, INFO, + "Idx %u Wtbl %u Used %u State %u Bss Phy 0x%x Sta DesiredPhy 0x%x\n", + prStaRec->ucIndex, ucWTEntry, + prStaRec->fgIsInUse, prStaRec->ucStaState, + prBssInfo->ucPhyTypeSet, prStaRec->ucDesiredPhyTypeSet); + + DBGLOG(SW4, INFO, + "Sta Operation 0x%x DesiredNontHtRateSet 0x%x Mcs 0x%x u2HtCapInfo 0x%x\n", + prStaRec->u2OperationalRateSet, + prStaRec->u2DesiredNonHTRateSet, prStaRec->ucMcsSet, + prStaRec->u2HtCapInfo); + + for (i = 0; i < NUM_OF_PER_STA_TX_QUEUES; i++) + DBGLOG(SW4, INFO, "TC %u Queue Len %u\n", i, + prStaRec->aprTargetQueue[i]->u4NumElem); + + DBGLOG(SW4, INFO, "BmpDeliveryAC %x\n", + prStaRec->ucBmpDeliveryAC); + DBGLOG(SW4, INFO, "BmpTriggerAC %x\n", + prStaRec->ucBmpTriggerAC); + DBGLOG(SW4, INFO, "UapsdSpSupproted %u\n", + prStaRec->fgIsUapsdSupported); + DBGLOG(SW4, INFO, "IsQoS %u\n", prStaRec->fgIsQoS); + DBGLOG(SW4, INFO, "AssocId %u\n", prStaRec->u2AssocId); + + DBGLOG(SW4, INFO, "fgIsInPS %u\n", prStaRec->fgIsInPS); + DBGLOG(SW4, INFO, "ucFreeQuota %u\n", + prStaRec->ucFreeQuota); + DBGLOG(SW4, INFO, "ucFreeQuotaForDelivery %u\n", + prStaRec->ucFreeQuotaForDelivery); + DBGLOG(SW4, INFO, "ucFreeQuotaForNonDelivery %u\n", + prStaRec->ucFreeQuotaForNonDelivery); + +#if 0 + DBGLOG(SW4, INFO, "IsQmmSup %u\n", + prStaRec->fgIsWmmSupported); + DBGLOG(SW4, INFO, "IsUapsdSup %u\n", + prStaRec->fgIsUapsdSupported); + DBGLOG(SW4, INFO, "AvailabaleDeliverPkts %u\n", + prStaRec->ucAvailableDeliverPkts); + DBGLOG(SW4, INFO, "BmpDeliverPktsAC %u\n", + prStaRec->u4BmpDeliverPktsAC); + DBGLOG(SW4, INFO, "BmpBufferAC %u\n", + prStaRec->u4BmpBufferAC); + DBGLOG(SW4, INFO, "BmpNonDeliverPktsAC %u\n", + prStaRec->u4BmpNonDeliverPktsAC); +#endif + + for (i = 0; i < CFG_RX_MAX_BA_TID_NUM; i++) { + if (prStaRec->aprRxReorderParamRefTbl[i]) { + DBGLOG(SW4, INFO, "RxReorder fgIsValid: %u\n", + prStaRec->aprRxReorderParamRefTbl[i]-> + fgIsValid); + DBGLOG(SW4, INFO, "RxReorder Tid: %u\n", + prStaRec->aprRxReorderParamRefTbl[i]->ucTid); + DBGLOG(SW4, INFO, + "RxReorder rReOrderQue Len: %u\n", + prStaRec->aprRxReorderParamRefTbl[i]-> + rReOrderQue.u4NumElem); + DBGLOG(SW4, INFO, "RxReorder WinStart: %u\n", + prStaRec->aprRxReorderParamRefTbl[i]-> + u2WinStart); + DBGLOG(SW4, INFO, "RxReorder WinEnd: %u\n", + prStaRec->aprRxReorderParamRefTbl[i]-> + u2WinEnd); + DBGLOG(SW4, INFO, "RxReorder WinSize: %u\n", + prStaRec->aprRxReorderParamRefTbl[i]-> + u2WinSize); + } + } + +} + +void dumpBss(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo) +{ + + DBGLOG(SW4, INFO, "SSID %s\n", HIDE(prBssInfo->aucSSID)); + DBGLOG(SW4, INFO, "OWN " MACSTR "\n", + MAC2STR(prBssInfo->aucOwnMacAddr)); + DBGLOG(SW4, INFO, "BSSID " MACSTR "\n", + MAC2STR(prBssInfo->aucBSSID)); + DBGLOG(SW4, INFO, "eNetworkType %u\n", + prBssInfo->eNetworkType); + DBGLOG(SW4, INFO, "ucBssIndex %u\n", prBssInfo->ucBssIndex); + DBGLOG(SW4, INFO, "eConnectionState %u\n", + prBssInfo->eConnectionState); + DBGLOG(SW4, INFO, "eCurrentOPMode %u\n", + prBssInfo->eCurrentOPMode); + DBGLOG(SW4, INFO, "fgIsQBSS %u\n", prBssInfo->fgIsQBSS); + DBGLOG(SW4, INFO, "fgIsShortPreambleAllowed %u\n", + prBssInfo->fgIsShortPreambleAllowed); + DBGLOG(SW4, INFO, "fgUseShortPreamble %u\n", + prBssInfo->fgUseShortPreamble); + DBGLOG(SW4, INFO, "fgUseShortSlotTime %u\n", + prBssInfo->fgUseShortSlotTime); + DBGLOG(SW4, INFO, "ucNonHTBasicPhyType %x\n", + prBssInfo->ucNonHTBasicPhyType); + DBGLOG(SW4, INFO, "u2OperationalRateSet %x\n", + prBssInfo->u2OperationalRateSet); + DBGLOG(SW4, INFO, "u2BSSBasicRateSet %x\n", + prBssInfo->u2BSSBasicRateSet); + DBGLOG(SW4, INFO, "ucPhyTypeSet %x\n", + prBssInfo->ucPhyTypeSet); + DBGLOG(SW4, INFO, "rStaRecOfClientList %d\n", + prBssInfo->rStaRecOfClientList.u4NumElem); + DBGLOG(SW4, INFO, "u2CapInfo %x\n", prBssInfo->u2CapInfo); + DBGLOG(SW4, INFO, "u2ATIMWindow %x\n", + prBssInfo->u2ATIMWindow); + DBGLOG(SW4, INFO, "u2AssocId %x\n", prBssInfo->u2AssocId); + DBGLOG(SW4, INFO, "ucDTIMPeriod %x\n", + prBssInfo->ucDTIMPeriod); + DBGLOG(SW4, INFO, "ucDTIMCount %x\n", + prBssInfo->ucDTIMCount); + DBGLOG(SW4, INFO, "fgIsNetAbsent %x\n", + prBssInfo->fgIsNetAbsent); + DBGLOG(SW4, INFO, "eBand %d\n", prBssInfo->eBand); + DBGLOG(SW4, INFO, "ucPrimaryChannel %d\n", + prBssInfo->ucPrimaryChannel); + DBGLOG(SW4, INFO, "ucHtOpInfo1 %d\n", + prBssInfo->ucHtOpInfo1); + DBGLOG(SW4, INFO, "ucHtOpInfo2 %d\n", + prBssInfo->u2HtOpInfo2); + DBGLOG(SW4, INFO, "ucHtOpInfo3 %d\n", + prBssInfo->u2HtOpInfo3); + DBGLOG(SW4, INFO, "fgErpProtectMode %d\n", + prBssInfo->fgErpProtectMode); + DBGLOG(SW4, INFO, "eHtProtectMode %d\n", + prBssInfo->eHtProtectMode); + DBGLOG(SW4, INFO, "eGfOperationMode %d\n", + prBssInfo->eGfOperationMode); + DBGLOG(SW4, INFO, "eRifsOperationMode %d\n", + prBssInfo->eRifsOperationMode); + DBGLOG(SW4, INFO, "fgObssErpProtectMode %d\n", + prBssInfo->fgObssErpProtectMode); + DBGLOG(SW4, INFO, "eObssHtProtectMode %d\n", + prBssInfo->eObssHtProtectMode); + DBGLOG(SW4, INFO, "eObssGfProtectMode %d\n", + prBssInfo->eObssGfOperationMode); + DBGLOG(SW4, INFO, "fgObssRifsOperationMode %d\n", + prBssInfo->fgObssRifsOperationMode); + DBGLOG(SW4, INFO, "fgAssoc40mBwAllowed %d\n", + prBssInfo->fgAssoc40mBwAllowed); + DBGLOG(SW4, INFO, "fg40mBwAllowed %d\n", + prBssInfo->fg40mBwAllowed); + DBGLOG(SW4, INFO, "eBssSCO %d\n", prBssInfo->eBssSCO); + +} + +void swCtrlCmdCategory0(struct ADAPTER *prAdapter, + uint8_t ucCate, uint8_t ucAction, uint8_t ucOpt0, + uint8_t ucOpt1) +{ + uint8_t ucIndex, ucRead; + uint32_t i; + struct CMD_RX_PACKET_FILTER rSetRxPacketFilter; + + DEBUGFUNC("swCtrlCmdCategory0"); + + SWCR_GET_RW_INDEX(ucAction, ucRead, ucIndex); + + i = 0; + + if (ucIndex >= SWCTRL_CATA0_INDEX_NUM) + return; + + if (ucRead == SWCR_WRITE) { + switch (ucIndex) { + case SWCTRL_DEBUG: + break; + case SWCTRL_WIFI_VAR: + break; + +#if QM_DEBUG_COUNTER + case SWCTRL_DUMP_QM_DBG_CNT: + for (i = 0; i < QM_DBG_CNT_NUM; i++) + prAdapter->rQM.au4QmDebugCounters[i] = 0; + break; + case SWCTRL_QM_DBG_CNT: + prAdapter->rQM.au4QmDebugCounters[ucOpt0] = + g_au4SwCr[1]; + + break; +#endif +#if CFG_RX_PKTS_DUMP + case SWCTRL_RX_PKTS_DUMP: + prAdapter->rRxCtrl.u4RxPktsDumpTypeMask = g_au4SwCr[1]; + break; +#endif + case SWCTRL_RX_FILTER: { + uint32_t u4rxfilter; + u_int8_t fgUpdate = FALSE; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + + if (ucOpt0 == SWCR_RX_FILTER_CMD_STOP) { + g_u4RXFilter &= ~(RX_FILTER_START); + /* changed by jeffrey to align + * Android behavior + */ +#if 0 + if (prAdapter->fgAllMulicastFilter == FALSE) + prAdapter->u4OsPacketFilter &= + ~PARAM_PACKET_FILTER_ALL_MULTICAST; +#endif + prAdapter->u4OsPacketFilter &= + ~PARAM_PACKET_FILTER_MULTICAST; + u4rxfilter = prAdapter->u4OsPacketFilter; + fgUpdate = TRUE; + } else if (ucOpt0 == SWCR_RX_FILTER_CMD_START) { + g_u4RXFilter |= (RX_FILTER_START); + + if ((g_u4RXFilter & RX_FILTER_IPV4) + || (g_u4RXFilter & RX_FILTER_IPV6)) { +#if 0 + prAdapter->u4OsPacketFilter |= + PARAM_PACKET_FILTER_ALL_MULTICAST; +#endif + prAdapter->u4OsPacketFilter |= + PARAM_PACKET_FILTER_MULTICAST; + } + u4rxfilter = prAdapter->u4OsPacketFilter; + fgUpdate = TRUE; + } else if (ucOpt0 == SWCR_RX_FILTER_CMD_ADD) { + if (ucOpt1 < 31) + g_u4RXFilter |= (1 << ucOpt1); + } else if (ucOpt0 == SWCR_RX_FILTER_CMD_REMOVE) { + if (ucOpt1 < 31) + g_u4RXFilter &= ~(1 << ucOpt1); + } + + if (fgUpdate == TRUE) { + rSetRxPacketFilter. + u4RxPacketFilter = u4rxfilter; + rStatus = + wlanoidSetPacketFilter( + prAdapter, &rSetRxPacketFilter, + FALSE, NULL, 0); + } + /* DBGLOG(SW4, INFO,("SWCTRL_RX_FILTER: + * g_u4RXFilter %x ucOpt0 %x ucOpt1 %x fgUpdate %x + * u4rxfilter %x, rStatus %x\n", + * g_u4RXFilter, ucOpt0, ucOpt1, + * fgUpdate, u4rxfilter, rStatus)); + */ + } + break; + +#if CFG_INIT_ENABLE_PATTERN_FILTER_ARP + case SWCTRL_RX_ARP_OFFLOAD: { + uint32_t rStatus = WLAN_STATUS_FAILURE; + uint32_t u4SetInfoLen = 0; + uint32_t u4Len = OFFSET_OF(struct + PARAM_NETWORK_ADDRESS_LIST, arAddress); + uint32_t u4NumIPv4 = 0, u4NumIPv6 = 0; + uint32_t i = 0; + uint8_t *pucBufIpAddr = NULL; + struct PARAM_NETWORK_ADDRESS_LIST *prParamNetAddrList = + NULL; + struct PARAM_NETWORK_ADDRESS_IP *prParamIpAddr = NULL; + uint8_t *pucIp = NULL; + /* PUINT_8 pucIpv6 = NULL; */ + uint32_t bufSize = + u4Len + (OFFSET_OF(struct PARAM_NETWORK_ADDRESS, + aucAddress) + + sizeof( + struct PARAM_NETWORK_ADDRESS_IP)) * 3; + struct PARAM_NETWORK_ADDRESS *prParamNetAddr = NULL; + + /* <1> allocate IP address buffer */ + pucBufIpAddr = kalMemAlloc(bufSize, VIR_MEM_TYPE); + /* TODO: replace 3 to macro */ + pucIp = kalMemAlloc(3 * 4, VIR_MEM_TYPE); + + prParamNetAddrList = + (struct PARAM_NETWORK_ADDRESS_LIST *) + pucBufIpAddr; + prParamNetAddr = prParamNetAddrList->arAddress; + /* <2> clear IP address buffer */ + kalMemZero(pucBufIpAddr, bufSize); + kalMemZero(pucIp, 3 * 4); + + /* <3> setup the number of IP address */ + if (ucOpt1 == 1) { + /* TODO: repleace 3 to macro */ + if (wlanGetIPV4Address( + prAdapter->prGlueInfo, pucIp, + &u4NumIPv4) && u4NumIPv4 > 3) + u4NumIPv4 = 3; + } else if (ucOpt1 == 0) { + u4NumIPv4 = u4NumIPv6 = 0; + } + DBGLOG(INIT, INFO, "u4Len:%d bufSize:%d u4NumIPv4:%d\n", + u4Len, bufSize, u4NumIPv4); + + prParamNetAddrList->u4AddressCount = + u4NumIPv6 + u4NumIPv4; + prParamNetAddrList->u2AddressType = + PARAM_PROTOCOL_ID_TCP_IP; + + for (i = 0; i < u4NumIPv4; i++) { + prParamNetAddr->u2AddressLength = sizeof(struct + PARAM_NETWORK_ADDRESS_IP); + prParamNetAddr->u2AddressType = + PARAM_PROTOCOL_ID_TCP_IP; + prParamIpAddr = + (struct PARAM_NETWORK_ADDRESS_IP *) + prParamNetAddr->aucAddress; + kalMemCopy(&prParamIpAddr->in_addr, + pucIp + (i * 4), 4); + prParamNetAddr = + (struct PARAM_NETWORK_ADDRESS *) + ((uint32_t) prParamNetAddr + + OFFSET_OF + (struct + PARAM_NETWORK_ADDRESS, + aucAddress) + + sizeof( + struct + PARAM_NETWORK_ADDRESS_IP + )); + u4Len += + OFFSET_OF(struct PARAM_NETWORK_ADDRESS, + aucAddress) + + sizeof( + struct + PARAM_NETWORK_ADDRESS_IP); + } + +#if 0 +#ifdef CONFIG_IPV6 + if (!wlanGetIPV6Address(prAdapter->prGlueInfo, pucIp, + &u4NumIPv6) + || (u4NumIPv6 + u4NumIPv4) > 3) { + goto bailout; + } + + pucIpv6 = kalMemAlloc(u4NumIPv6 * 16, VIR_MEM_TYPE); + + for (i = 0; i < u4NumIPv6; i++) { + prParamNetAddr->u2AddressLength = 6; + prParamNetAddr->u2AddressType = + PARAM_PROTOCOL_ID_TCP_IP; + kalMemCopy(prParamNetAddr->aucAddress, + pucIpv6 + (i * 16), + 16); + prParamNetAddr = + (struct PARAM_NETWORK_ADDRESS *) + ((uint32_t) prParamNetAddr + + sizeof(ip6)); + u4Len += OFFSET_OF(struct PARAM_NETWORK_ADDRESS, + aucAddress) + sizeof(ip6); + } +#endif +#endif + + ASSERT(u4Len <= bufSize); + + rStatus = wlanoidSetNetworkAddress(prAdapter, + (void *) prParamNetAddrList, + u4Len, &u4SetInfoLen); + + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(INIT, INFO, + "set HW packet filter fail 0x%1x\n", + rStatus); + + /* TODO: replace 3 to marco */ + if (pucIp) + kalMemFree(pucIp, VIR_MEM_TYPE, 3 * 4); + if (pucBufIpAddr) + kalMemFree(pucBufIpAddr, VIR_MEM_TYPE, bufSize); + + } + break; +#endif + case SWCTRL_PS_DTIM_SKIP: + break; + case SWCTRL_ROAMING: + break; + default: + break; + } + } else { + switch (ucIndex) { + case SWCTRL_DEBUG: + break; + case SWCTRL_MAGIC: + g_au4SwCr[1] = _SWCTRL_MAGIC; + break; + case SWCTRL_QM_INFO: { + struct QUE_MGT *prQM = &prAdapter->rQM; + + switch (ucOpt0) { + case 0: +#if QM_ADAPTIVE_TC_RESOURCE_CTRL + g_au4SwCr[1] = + (QM_GET_TX_QUEUE_LEN(prAdapter, + ucOpt1)); + g_au4SwCr[2] = + prQM->au4MinReservedTcResource[ucOpt1]; + g_au4SwCr[3] = + prQM->au4CurrentTcResource[ucOpt1]; + g_au4SwCr[4] = + prQM->au4GuaranteedTcResource[ucOpt1]; +#endif + break; + + case 1: +#if QM_FORWARDING_FAIRNESS + g_au4SwCr[1] = + prQM->au4ResourceUsedCount[ucOpt1]; + g_au4SwCr[2] = prQM->au4HeadStaRecIndex[ucOpt1]; +#endif + break; + + case 2: + /* only one */ + g_au4SwCr[1] = + prQM->arTxQueue[ucOpt1].u4NumElem; + + break; + } + } + break; + case SWCTRL_TX_CTRL_INFO: { + struct TX_CTRL *prTxCtrl; + + prTxCtrl = &prAdapter->rTxCtrl; + switch (ucOpt0) { + case 0: + g_au4SwCr[1] = + prAdapter->rTxCtrl.rTc. + au4FreeBufferCount[ucOpt1]; + g_au4SwCr[2] = + prAdapter->rTxCtrl.rTc. + au4MaxNumOfBuffer[ucOpt1]; + break; + } + + } + break; + case SWCTRL_DUMP_QUEUE: + dumpQueue(prAdapter); + + break; +#if QM_DEBUG_COUNTER + case SWCTRL_DUMP_QM_DBG_CNT: + for (i = 0; i < QM_DBG_CNT_NUM; i++) + DBGLOG(SW4, INFO, "QM:DBG %u %u\n", i, + prAdapter->rQM.au4QmDebugCounters[i]); + break; + + case SWCTRL_QM_DBG_CNT: + g_au4SwCr[1] = + prAdapter->rQM.au4QmDebugCounters[ucOpt0]; + break; +#endif + case SWCTRL_DUMP_BSS: { + dumpBss(prAdapter, GET_BSS_INFO_BY_INDEX(prAdapter, + ucOpt0)); + } + break; + + default: + break; + } + + } +} + +void swCtrlCmdCategory1(struct ADAPTER *prAdapter, + uint8_t ucCate, uint8_t ucAction, uint8_t ucOpt0, + uint8_t ucOpt1) +{ + uint8_t ucIndex, ucRead; + uint8_t ucWTEntry; + struct STA_RECORD *prStaRec; + + DEBUGFUNC("swCtrlCmdCategory1"); + + SWCR_GET_RW_INDEX(ucAction, ucRead, ucIndex); + + if (ucOpt0 >= CFG_STA_REC_NUM) + return; + + /* prStaRec = cnmGetStaRecByIndex (prAdapter, ucOpt0); */ + prStaRec = &prAdapter->arStaRec[ucOpt0]; + ucWTEntry = prStaRec->ucWlanIndex; + if (ucRead == SWCR_WRITE) { + /* ToDo:: Nothing */ + } else { + /* Read */ + switch (ucIndex) { + case SWCTRL_STA_QUE_INFO: { + g_au4SwCr[1] = prStaRec->arTxQueue[ucOpt1].u4NumElem; + } + break; + case SWCTRL_STA_INFO: + switch (ucOpt1) { + case 0: + g_au4SwCr[1] = prStaRec->fgIsInPS; + break; + } + + break; + + case SWCTRL_DUMP_STA: { + dumpSTA(prAdapter, prStaRec); + } + break; + + default: + + break; + } + } + +} + +#if TEST_PS + +void +testPsSendQoSNullFrame(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, + IN uint8_t ucUP, + IN uint8_t ucBssIndex, + IN u_int8_t fgBMC, + IN u_int8_t fgIsBurstEnd, IN u_int8_t ucPacketType, + IN u_int8_t ucPsSessionID, IN u_int8_t fgSetEOSP) +{ + struct MSDU_INFO *prMsduInfo; + uint16_t u2EstimatedFrameLen; + struct WLAN_MAC_HEADER_QOS *prQoSNullFrame; + + DEBUGFUNC("testPsSendQoSNullFrame"); + DBGLOG(SW4, LOUD, "\n"); + + /* 4 <1> Allocate a PKT_INFO_T for Null Frame */ + /* Init with MGMT Header Length */ + u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + + WLAN_MAC_HEADER_QOS_LEN; + + /* Allocate a MSDU_INFO_T */ + + prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); + + if (prMsduInfo == NULL) { + DBGLOG(SW4, WARN, + "No PKT_INFO_T for sending Null Frame.\n"); + return; + } + /* 4 <2> Compose Null frame in MSDU_INfO_T. */ + bssComposeQoSNullFrame(prAdapter, + (uint8_t *) ((unsigned long) (prMsduInfo->prPacket) + + MAC_TX_RESERVED_FIELD), + prStaRec, ucUP, fgSetEOSP); + + TX_SET_MMPDU(prAdapter, + prMsduInfo, + ucBssIndex, + prStaRec->ucIndex, WLAN_MAC_HEADER_QOS_LEN, + WLAN_MAC_HEADER_QOS_LEN, NULL, MSDU_RATE_MODE_AUTO); + + prMsduInfo->ucUserPriority = ucUP; + prMsduInfo->ucPacketType = ucPacketType; + + prQoSNullFrame = (struct WLAN_MAC_HEADER_QOS *) ((uint8_t *) + ((unsigned long) (prMsduInfo->prPacket) + + MAC_TX_RESERVED_FIELD)); + + if (fgBMC) + prQoSNullFrame->aucAddr1[0] = 0xfd; + else + prQoSNullFrame->aucAddr1[5] = 0xdd; + + /* 4 <4> Inform TXM to send this Null frame. */ + nicTxEnqueueMsdu(prAdapter, prMsduInfo); + +} + +void testPsSetupBss(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) +{ + struct BSS_INFO *prBssInfo; + uint8_t _aucZeroMacAddr[] = NULL_MAC_ADDR; + + DEBUGFUNC("testPsSetupBss()"); + DBGLOG(SW4, INFO, "index %d\n", ucBssIndex); + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + + /* 4 <1.2> Initiate PWR STATE */ + /* SET_NET_PWR_STATE_IDLE(prAdapter, ucNetworkTypeIndex); */ + + /* 4 <2> Initiate BSS_INFO_T - common part */ + BSS_INFO_INIT(prAdapter, prBssInfo); + + prBssInfo->eConnectionState = + MEDIA_STATE_DISCONNECTED; + prBssInfo->eConnectionStateIndicated = + MEDIA_STATE_DISCONNECTED; + prBssInfo->eCurrentOPMode = OP_MODE_ACCESS_POINT; + prBssInfo->fgIsNetActive = TRUE; + prBssInfo->ucBssIndex = ucBssIndex; + prBssInfo->ucReasonOfDisconnect = + DISCONNECT_REASON_CODE_RESERVED; + + /* Depend on eBand */ + prBssInfo->ucPhyTypeSet = + PHY_TYPE_SET_802_11BG; + /* Depend on eCurrentOPMode and ucPhyTypeSet */ + prBssInfo->ucConfigAdHocAPMode = + AP_MODE_MIXED_11BG; + prBssInfo->u2BSSBasicRateSet = RATE_SET_ERP; + prBssInfo->u2OperationalRateSet = RATE_SET_OFDM; + prBssInfo->fgErpProtectMode = FALSE; + prBssInfo->fgIsQBSS = TRUE; + + /* 4 <1.5> Setup MIB for current BSS */ + prBssInfo->u2BeaconInterval = 100; + prBssInfo->ucDTIMPeriod = DOT11_DTIM_PERIOD_DEFAULT; + prBssInfo->u2ATIMWindow = 0; + + prBssInfo->ucBeaconTimeoutCount = 0; + + bssInitForAP(prAdapter, prBssInfo, TRUE); + + COPY_MAC_ADDR(prBssInfo->aucBSSID, _aucZeroMacAddr); + LINK_INITIALIZE(&prBssInfo->rStaRecOfClientList); + prBssInfo->fgIsBeaconActivated = TRUE; + prBssInfo->u2HwDefaultFixedRateCode = RATE_CCK_1M_LONG; + + COPY_MAC_ADDR(prBssInfo->aucOwnMacAddr, + prAdapter->rWifiVar.aucMacAddress); + + /* 4 <3> Initiate BSS_INFO_T - private part */ + /* TODO */ + prBssInfo->eBand = BAND_2G4; + prBssInfo->ucPrimaryChannel = 1; + prBssInfo->prStaRecOfAP = (struct STA_RECORD *) NULL; + + /* prBssInfo->fgErpProtectMode = eErpProectMode; */ + /* prBssInfo->eHtProtectMode = eHtProtectMode; */ + /* prBssInfo->eGfOperationMode = eGfOperationMode; */ + + /* 4 <4> Allocate MSDU_INFO_T for Beacon */ + prBssInfo->prBeacon = cnmMgtPktAlloc(prAdapter, + OFFSET_OF(struct WLAN_BEACON_FRAME, + aucInfoElem[0]) + MAX_IE_LENGTH); + + if (prBssInfo->prBeacon) { + prBssInfo->prBeacon->eSrc = TX_PACKET_MGMT; + prBssInfo->prBeacon->ucBssIndex = ucBssIndex; + } else { + DBGLOG(SW4, INFO, "prBeacon allocation fail\n"); + } + +#if 0 + prBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC = PM_UAPSD_ALL; + prBssInfo->rPmProfSetupInfo.ucBmpTriggerAC = PM_UAPSD_ALL; + prBssInfo->rPmProfSetupInfo.ucUapsdSp = WMM_MAX_SP_LENGTH_2; +#else + prBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC = + (uint8_t) prAdapter->u4UapsdAcBmp; + prBssInfo->rPmProfSetupInfo.ucBmpTriggerAC = + (uint8_t) prAdapter->u4UapsdAcBmp; + prBssInfo->rPmProfSetupInfo.ucUapsdSp = (uint8_t) + prAdapter->u4MaxSpLen; +#endif + +#if 0 + for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { + + prBssInfo->arACQueParms[eAci].ucIsACMSet = FALSE; + prBssInfo->arACQueParms[eAci].u2Aifsn = (uint16_t) eAci; + prBssInfo->arACQueParms[eAci].u2CWmin = 7; + prBssInfo->arACQueParms[eAci].u2CWmax = 31; + prBssInfo->arACQueParms[eAci].u2TxopLimit = eAci + 1; + DBGLOG(SW4, INFO, + "MQM: eAci = %d, ACM = %d, Aifsn = %d, CWmin = %d, CWmax = %d, TxopLimit = %d\n", + eAci, prBssInfo->arACQueParms[eAci].ucIsACMSet, + prBssInfo->arACQueParms[eAci].u2Aifsn, + prBssInfo->arACQueParms[eAci].u2CWmin, + prBssInfo->arACQueParms[eAci].u2CWmax, + prBssInfo->arACQueParms[eAci].u2TxopLimit); + + } +#endif + + DBGLOG(SW4, INFO, + "[2] ucBmpDeliveryAC:0x%x, ucBmpTriggerAC:0x%x, ucUapsdSp:0x%x", + prBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC, + prBssInfo->rPmProfSetupInfo.ucBmpTriggerAC, + prBssInfo->rPmProfSetupInfo.ucUapsdSp); +} + +void testPsCmdCategory0(struct ADAPTER *prAdapter, + uint8_t ucCate, uint8_t ucAction, uint8_t ucOpt0, + uint8_t ucOpt1) +{ + uint8_t ucIndex, ucRead; + struct STA_RECORD *prStaRec; + + DEBUGFUNC("testPsCmdCategory0"); + SWCR_GET_RW_INDEX(ucAction, ucRead, ucIndex); + + DBGLOG(SW4, LOUD, "Read %u Index %u\n", ucRead, ucIndex); + + prStaRec = cnmGetStaRecByIndex(prAdapter, 0); + + if (ucIndex >= TEST_PS_CATA0_INDEX_NUM) + return; + + if (ucRead == SWCR_WRITE) { + switch (ucIndex) { + case TEST_PS_SETUP_BSS: + testPsSetupBss(prAdapter, ucOpt0); + break; + + case TEST_PS_ENABLE_BEACON: + break; + + case TEST_PS_TRIGGER_BMC: + /* txmForwardQueuedBmcPkts (ucOpt0); */ + break; + case TEST_PS_SEND_NULL: { + if (prStaRec == NULL) + break; + testPsSendQoSNullFrame(prAdapter, prStaRec, + /* UP */ + (uint8_t) (g_au4SwCr[1] & 0xFF), + /* BMC */ + ucOpt0, (u_int8_t) ((g_au4SwCr[1] >> 8) & 0xFF), + /* BurstEnd */ + (u_int8_t) ((g_au4SwCr[1] >> 16) & 0xFF), + /* Packet type */ + (u_int8_t) ((g_au4SwCr[1] >> 24) & 0xFF), + /* PS sesson ID 7: NOACK */ + (uint8_t) ((g_au4SwCr[2]) & 0xFF), + /* EOSP */ + FALSE + ); + } + break; + case TEST_PS_BUFFER_BMC: + break; + case TEST_PS_UPDATE_BEACON: + bssUpdateBeaconContent(prAdapter, + ucOpt0 /*networktype */); + break; + + default: + break; + } + } else { + switch (ucIndex) { + + case TEST_PS_MAGIC: + g_au4SwCr[1] = 0x88660011; + break; + + } + } +} + +#endif /* TEST_PS */ + +#if TEST_PS + +void testPsCmdCategory1(struct ADAPTER *prAdapter, + uint8_t ucCate, uint8_t ucAction, uint8_t ucOpt0, + uint8_t ucOpt1) +{ + uint8_t ucIndex, ucRead; + uint8_t ucWTEntry; + struct STA_RECORD *prStaRec; + + DEBUGFUNC("testPsCmdCategory1"); + + SWCR_GET_RW_INDEX(ucAction, ucRead, ucIndex); + + if (ucOpt0 >= CFG_STA_REC_NUM) + return; + + prStaRec = cnmGetStaRecByIndex(prAdapter, ucOpt0); + + if (!prStaRec) { + DBGLOG(SW4, INFO, "prStaRec is NULL, ucOpt0:%d\n", ucOpt0); + return; + } + + ucWTEntry = prStaRec->ucWlanIndex; + if (ucRead == SWCR_WRITE) { + + switch (ucIndex) { + case TEST_PS_STA_PS: + prStaRec->fgIsInPS = (u_int8_t) (g_au4SwCr[1] & 0x1); + prStaRec->fgIsQoS = + (u_int8_t) (g_au4SwCr[1] >> 8 & 0xFF); + prStaRec->fgIsUapsdSupported = + (u_int8_t) (g_au4SwCr[1] >> 16 & 0xFF); + prStaRec->ucBmpDeliveryAC = + (u_int8_t) (g_au4SwCr[1] >> 24 & 0xFF); + break; + + } + + } else { + /* Read */ + switch (ucIndex) { + default: + break; + } + } + +} + +#endif /* TEST_PS */ + +#if CFG_SUPPORT_802_11V +#if (CFG_SUPPORT_802_11V_TIMING_MEASUREMENT == 1) && (WNM_UNIT_TEST == 1) +void testWNMCmdCategory0(struct ADAPTER *prAdapter, + uint8_t ucCate, uint8_t ucAction, uint8_t ucOpt0, + uint8_t ucOpt1) +{ + uint8_t ucIndex, ucRead; + struct STA_RECORD *prStaRec; + + DEBUGFUNC("testWNMCmdCategory0"); + SWCR_GET_RW_INDEX(ucAction, ucRead, ucIndex); + + DBGLOG(SW4, INFO, "Read %u Index %u\n", ucRead, ucIndex); + + if (ucIndex >= TEST_WNM_CATA0_INDEX_NUM) + return; + + if (ucRead == SWCR_WRITE) { + switch (ucIndex) { + case TEST_WNM_TIMING_MEAS: + wnmTimingMeasUnitTest1(prAdapter, ucOpt0); + break; + + default: + break; + } + } +} +#endif /* TEST_WNM */ +#endif /* CFG_SUPPORT_802_11V */ + +void swCtrlSwCr(struct ADAPTER *prAdapter, uint8_t ucRead, + uint16_t u2Addr, uint32_t *pu4Data) +{ + /* According other register STAIDX */ + uint8_t ucOffset; + + ucOffset = (u2Addr >> 2) & 0x3F; + + if (ucOffset >= SWCR_CR_NUM) + return; + + if (ucRead == SWCR_WRITE) { + g_au4SwCr[ucOffset] = *pu4Data; + if (ucOffset == 0x0) { + /* Commmand [31:24]: Category */ + /* Commmand [23:23]: 1(W) 0(R) */ + /* Commmand [22:16]: Index */ + /* Commmand [15:08]: Option0 */ + /* Commmand [07:00]: Option1 */ + uint8_t ucCate; + uint32_t u4Cmd; + + u4Cmd = g_au4SwCr[0]; + ucCate = (uint8_t) (u4Cmd >> 24); + if (ucCate < ARRAY_SIZE(g_arSwCtrlCmd)) { + if (g_arSwCtrlCmd[ucCate] != NULL) { + g_arSwCtrlCmd[ucCate] ( + prAdapter, ucCate, + (uint8_t) (u4Cmd >> 16 & 0xFF), + (uint8_t) ((u4Cmd >> 8) & 0xFF), + (uint8_t) (u4Cmd & 0xFF)); + } + } + } + } else { + *pu4Data = g_au4SwCr[ucOffset]; + } +} + +void swCrReadWriteCmd(struct ADAPTER *prAdapter, + uint8_t ucRead, uint16_t u2Addr, uint32_t *pu4Data) +{ + uint8_t ucMod; + + ucMod = u2Addr >> 8; + /* Address [15:8] MOD ID */ + /* Address [7:0] OFFSET */ + + DEBUGFUNC("swCrReadWriteCmd"); + DBGLOG(SW4, INFO, "%u addr 0x%x data 0x%x\n", ucRead, + u2Addr, *pu4Data); + + if (ucMod < (ARRAY_SIZE(g_arSwCrModHandle))) { + + if (g_arSwCrModHandle[ucMod] != NULL) + g_arSwCrModHandle[ucMod] (prAdapter, ucRead, u2Addr, + pu4Data); + } /* ucMod */ +} + +/* Debug Support */ +void swCrFrameCheckEnable(struct ADAPTER *prAdapter, + uint32_t u4DumpType) +{ + g_u4SwcrDebugFrameDumpType = u4DumpType; +#if CFG_RX_PKTS_DUMP + prAdapter->rRxCtrl.u4RxPktsDumpTypeMask = u4DumpType; +#endif +} + +void swCrDebugInit(struct ADAPTER *prAdapter) +{ + /* frame dump */ + if (g_u4SwcrDebugFrameDumpType) + swCrFrameCheckEnable(prAdapter, g_u4SwcrDebugFrameDumpType); + /* debug counter */ + g_fgSwcrDebugTimer = FALSE; + + cnmTimerInitTimer(prAdapter, &g_rSwcrDebugTimer, + (PFN_MGMT_TIMEOUT_FUNC) swCrDebugCheckTimeout, + (unsigned long) NULL); + + if (g_u4SwcrDebugCheckTimeout) + swCrDebugCheckEnable(prAdapter, TRUE, + g_ucSwcrDebugCheckType, g_u4SwcrDebugCheckTimeout); +} + +void swCrDebugUninit(struct ADAPTER *prAdapter) +{ + cnmTimerStopTimer(prAdapter, &g_rSwcrDebugTimer); + + g_fgSwcrDebugTimer = FALSE; +} + +void swCrDebugCheckEnable(struct ADAPTER *prAdapter, + u_int8_t fgIsEnable, uint8_t ucType, uint32_t u4Timeout) +{ + if (fgIsEnable) { + g_ucSwcrDebugCheckType = ucType; + g_u4SwcrDebugCheckTimeout = u4Timeout; + if (g_fgSwcrDebugTimer == FALSE) + swCrDebugCheckTimeout(prAdapter, 0); + } else { + cnmTimerStopTimer(prAdapter, &g_rSwcrDebugTimer); + g_u4SwcrDebugCheckTimeout = 0; + } + + g_fgSwcrDebugTimer = fgIsEnable; +} + +void swCrDebugCheck(struct ADAPTER *prAdapter, + struct CMD_SW_DBG_CTRL *prCmdSwCtrl) +{ + struct RX_CTRL *prRxCtrl; + struct TX_CTRL *prTxCtrl; + + ASSERT(prAdapter); + + prTxCtrl = &prAdapter->rTxCtrl; + prRxCtrl = &prAdapter->rRxCtrl; + + /* dump counters */ + if (prCmdSwCtrl) { + if (prCmdSwCtrl->u4Data == SWCR_DBG_TYPE_ALL) { + + /* TX Counter from fw */ + DBGLOG(SW4, INFO, "TX0\n" + "%08x %08x %08x %08x\n" + "%08x %08x %08x %08x\n", + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_TX_CNT], + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_TX_BCN_CNT], + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_TX_FAILED_CNT], + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_TX_RETRY_CNT], + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_TX_AGING_TIMEOUT_CNT], + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_TX_PS_OVERFLOW_CNT], + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_TX_MGNT_DROP_CNT], + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_TX_ERROR_CNT]); +#if 1 + /* TX Counter from drv */ + DBGLOG(SW4, INFO, "TX1\n" + "%08x %08x %08x %08x\n", + (uint32_t) TX_GET_CNT(prTxCtrl, + TX_INACTIVE_BSS_DROP), + (uint32_t) TX_GET_CNT(prTxCtrl, + TX_INACTIVE_STA_DROP), + (uint32_t) TX_GET_CNT(prTxCtrl, + TX_FORWARD_OVERFLOW_DROP), + (uint32_t) TX_GET_CNT(prTxCtrl, + TX_AP_BORADCAST_DROP)); +#endif + + /* RX Counter */ + DBGLOG(SW4, INFO, "RX0\n" + "%08x %08x %08x %08x\n" + "%08x %08x %08x %08x\n" + "%08x %08x %08x %08x\n" + "%08x %08x %08x %08x\n", + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_RX_CNT], + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_RX_DROP_CNT], + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_RX_DUP_DROP_CNT], + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_RX_TYPE_ERROR_DROP_CNT], + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_RX_CLASS_ERROR_DROP_CNT], + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_RX_AMPDU_ERROR_DROP_CNT], + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_RX_STATUS_ERROR_DROP_CNT], + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_RX_FORMAT_ERROR_DROP_CNT], + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_RX_ICV_ERROR_DROP_CNT], + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_RX_KEY_ERROR_DROP_CNT], + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_RX_TKIP_ERROR_DROP_CNT], + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_RX_MIC_ERROR_DROP_CNT], + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_RX_BIP_ERROR_DROP_CNT], + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_RX_FCSERR_CNT], + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_RX_FIFOFULL_CNT], + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_RX_PFDROP_CNT]); + + DBGLOG(SW4, INFO, "RX1\n" + "%08x %08x %08x %08x\n" + "%08x %08x %08x %08x\n", + (uint32_t) RX_GET_CNT(prRxCtrl, + RX_MPDU_TOTAL_COUNT), + (uint32_t) RX_GET_CNT(prRxCtrl, + RX_DATA_INDICATION_COUNT), + (uint32_t) RX_GET_CNT(prRxCtrl, + RX_DATA_RETURNED_COUNT), + (uint32_t) RX_GET_CNT(prRxCtrl, + RX_DATA_RETAINED_COUNT), + (uint32_t) RX_GET_CNT(prRxCtrl, + RX_DROP_TOTAL_COUNT), + (uint32_t) RX_GET_CNT(prRxCtrl, + RX_TYPE_ERR_DROP_COUNT), + (uint32_t) RX_GET_CNT(prRxCtrl, + RX_CLASS_ERR_DROP_COUNT), + (uint32_t) RX_GET_CNT(prRxCtrl, + RX_DST_NULL_DROP_COUNT)); + + DBGLOG(SW4, INFO, "PWR\n" + "%08x %08x %08x %08x\n" + "%08x %08x %08x %08x\n", + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_PWR_PS_POLL_CNT], + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_PWR_TRIGGER_NULL_CNT], + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_PWR_BCN_IND_CNT], + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_PWR_BCN_TIMEOUT_CNT], + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_PWR_PM_STATE0], + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_PWR_PM_STATE1], + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_PWR_CUR_PS_PROF0], + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_PWR_CUR_PS_PROF1]); + + DBGLOG(SW4, INFO, "ARM\n" + "%08x %08x %08x %08x\n" + "%08x %08x\n", + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_AR_STA0_RATE], + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_AR_STA0_BWGI], + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_AR_STA0_RX_RATE_RCPI], + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_ROAMING_ENABLE], + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_ROAMING_ROAM_CNT], + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_ROAMING_INT_CNT]); + + DBGLOG(SW4, INFO, "BB\n" + "%08x %08x %08x %08x\n" + "%08x %08x %08x %08x\n", + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_BB_RX_MDRDY_CNT], + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_BB_RX_FCSERR_CNT], + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_BB_CCK_PD_CNT], + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_BB_OFDM_PD_CNT], + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_BB_CCK_SFDERR_CNT], + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_BB_CCK_SIGERR_CNT], + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_BB_OFDM_TAGERR_CNT], + prCmdSwCtrl->u4DebugCnt[ + SWCR_DBG_ALL_BB_OFDM_SIGERR_CNT]); + + } + } + /* start the next check */ + if (g_u4SwcrDebugCheckTimeout) + cnmTimerStartTimer(prAdapter, &g_rSwcrDebugTimer, + g_u4SwcrDebugCheckTimeout * MSEC_PER_SEC); +} + +void swCrDebugCheckTimeout(IN struct ADAPTER *prAdapter, + unsigned long ulParamPtr) +{ + struct CMD_SW_DBG_CTRL rCmdSwCtrl; + uint32_t rStatus; + + rCmdSwCtrl.u4Id = (0xb000 << 16) + g_ucSwcrDebugCheckType; + rCmdSwCtrl.u4Data = 0; + rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ + CMD_ID_SW_DBG_CTRL, /* ucCID */ + FALSE, /* fgSetQuery */ + TRUE, /* fgNeedResp */ + FALSE, /* fgIsOid */ + swCrDebugQuery, /* pfCmdDoneHandler */ + swCrDebugQueryTimeout, /* pfCmdTimeoutHandler */ + sizeof(struct CMD_SW_DBG_CTRL), /* u4SetQueryInfoLen */ + (uint8_t *) &rCmdSwCtrl, /* pucInfoBuffer */ + NULL, /* pvSetQueryBuffer */ + 0 /* u4SetQueryBufferLen */ + ); + + ASSERT(rStatus == WLAN_STATUS_PENDING); +} + +void swCrDebugQuery(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf) +{ + ASSERT(prAdapter); + + swCrDebugCheck(prAdapter, + (struct CMD_SW_DBG_CTRL *) (pucEventBuf)); +} + +void swCrDebugQueryTimeout(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo) +{ + ASSERT(prAdapter); + + swCrDebugCheck(prAdapter, NULL); +} + +#endif /* CFG_SUPPORT_SWCR */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/tdls.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/tdls.c new file mode 100644 index 0000000000000000000000000000000000000000..b5358ec116f2b9217d8cc7fd8be5cc85051f6aa5 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/tdls.c @@ -0,0 +1,1636 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: tdls.c#1 + */ + +/*! \file tdls.c + * \brief This file includes IEEE802.11z TDLS support. + */ + + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" + +#if CFG_SUPPORT_TDLS +#include "tdls.h" +#include "queue.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ +uint8_t g_arTdlsLink[MAXNUM_TDLS_PEER] = { + 0, + 0, + 0, + 0 + }; + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ +static u_int8_t fgIsPtiTimeoutSkip = FALSE; +static u_int8_t fgIsWaitForTxDone = FALSE; + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ +#define ELEM_ID_LINK_IDENTIFIER_LENGTH 16 + +#define TDLS_KEY_TIMEOUT_INTERVAL 43200 + +#define TDLS_REASON_CODE_UNREACHABLE 25 +#define TDLS_REASON_CODE_UNSPECIFIED 26 + +#define WLAN_REASON_TDLS_TEARDOWN_UNREACHABLE 25 +#define WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED 26 + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to hadel TDLS link oper from nl80211. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * \param[in] + * \param[in] + * \param[in] buf includes RSN IE + FT IE + Lifetimeout IE + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t TdlsexLinkMgt(struct ADAPTER *prAdapter, + void *pvSetBuffer, uint32_t u4SetBufferLen, + uint32_t *pu4SetInfoLen) +{ + uint32_t rResult = TDLS_STATUS_SUCCESS; + struct STA_RECORD *prStaRec; + struct BSS_INFO *prBssInfo; + struct TDLS_CMD_LINK_MGT *prCmd; + + prCmd = (struct TDLS_CMD_LINK_MGT *) pvSetBuffer; + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prCmd->ucBssIdx); + if (prBssInfo == NULL) { + DBGLOG(TDLS, ERROR, "prBssInfo %d is NULL!\n" + , prCmd->ucBssIdx); + return -EINVAL; + } + + DBGLOG(TDLS, INFO, "u4SetBufferLen=%d", u4SetBufferLen); + +#if 1 + /* AIS only */ + if (prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) { + prStaRec = prBssInfo->prStaRecOfAP; + if (prStaRec == NULL) + return 0; + } else { + return -EINVAL; + } +#endif + + DBGLOG(TDLS, INFO, "prCmd->ucActionCode=%d, prCmd->ucDialogToken=%d", + prCmd->ucActionCode, prCmd->ucDialogToken); + + prStaRec = prBssInfo->prStaRecOfAP; + + switch (prCmd->ucActionCode) { + + case TDLS_FRM_ACTION_DISCOVERY_REQ: + if (prStaRec == NULL) + return 0; + rResult = TdlsDataFrameSend_DISCOVERY_REQ(prAdapter, + prStaRec, + prCmd->aucPeer, + prCmd->ucActionCode, + prCmd->ucDialogToken, + prCmd->u2StatusCode, + (uint8_t *) (prCmd->aucSecBuf), + prCmd->u4SecBufLen); + break; + + case TDLS_FRM_ACTION_SETUP_REQ: + if (prStaRec == NULL) + return 0; + prStaRec = cnmGetTdlsPeerByAddress(prAdapter, + prBssInfo->ucBssIndex, + prCmd->aucPeer); + g_arTdlsLink[prStaRec->ucTdlsIndex] = 0; + rResult = TdlsDataFrameSend_SETUP_REQ(prAdapter, + prStaRec, + prCmd->aucPeer, + prCmd->ucActionCode, + prCmd->ucDialogToken, + prCmd->u2StatusCode, + (uint8_t *) (prCmd->aucSecBuf), + prCmd->u4SecBufLen); + break; + + case TDLS_FRM_ACTION_SETUP_RSP: + /* fix sigma bug 5.2.4.2, 5.2.4.7, we sent Status code decline, + * but the sigma recogniezis it as scucess, and it will fail + */ + /* if(prCmd->u2StatusCode != 0) */ + if (prBssInfo->fgTdlsIsProhibited) + return 0; + + rResult = TdlsDataFrameSend_SETUP_RSP(prAdapter, + prStaRec, + prCmd->aucPeer, + prCmd->ucActionCode, + prCmd->ucDialogToken, + prCmd->u2StatusCode, + (uint8_t *) (prCmd->aucSecBuf), + prCmd->u4SecBufLen); + break; + + case TDLS_FRM_ACTION_DISCOVERY_RSP: + rResult = TdlsDataFrameSend_DISCOVERY_RSP(prAdapter, + prStaRec, + prCmd->aucPeer, + prCmd->ucActionCode, + prCmd->ucDialogToken, + prCmd->u2StatusCode, + (uint8_t *) (prCmd->aucSecBuf), + prCmd->u4SecBufLen); + break; + + case TDLS_FRM_ACTION_CONFIRM: + rResult = TdlsDataFrameSend_CONFIRM(prAdapter, + prStaRec, + prCmd->aucPeer, + prCmd->ucActionCode, + prCmd->ucDialogToken, + prCmd->u2StatusCode, + (uint8_t *) (prCmd->aucSecBuf), + prCmd->u4SecBufLen); + break; + + case TDLS_FRM_ACTION_TEARDOWN: + prStaRec = cnmGetTdlsPeerByAddress(prAdapter, + prBssInfo->ucBssIndex, + prCmd->aucPeer); + if (prCmd->u2StatusCode == TDLS_REASON_CODE_UNREACHABLE) + g_arTdlsLink[prStaRec->ucTdlsIndex] = 0; + + rResult = TdlsDataFrameSend_TearDown(prAdapter, + prStaRec, + prCmd->aucPeer, + prCmd->ucActionCode, + prCmd->ucDialogToken, + prCmd->u2StatusCode, + (uint8_t *) (prCmd->aucSecBuf), + prCmd->u4SecBufLen); + break; + + default: + DBGLOG(TDLS, INFO, "default=%d", prCmd->ucActionCode); + return -EINVAL; + } + + if (rResult == TDLS_STATUS_PENDING) + fgIsWaitForTxDone = TRUE; + + DBGLOG(TDLS, INFO, "rResult=%d", rResult); + + return rResult; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to hadel TDLS link mgt from nl80211. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * \param[in] + * \param[in] + * \param[in] buf includes RSN IE + FT IE + Lifetimeout IE + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t TdlsexLinkOper(struct ADAPTER *prAdapter, + void *pvSetBuffer, uint32_t u4SetBufferLen, + uint32_t *pu4SetInfoLen) +{ + /* from supplicant -- wpa_supplicant_tdls_peer_addset() */ + uint16_t i; + struct STA_RECORD *prStaRec; + + struct TDLS_CMD_LINK_OPER *prCmd; + + struct BSS_INFO *prBssInfo; + + prCmd = (struct TDLS_CMD_LINK_OPER *) pvSetBuffer; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prCmd->ucBssIdx); + if (prBssInfo == NULL) { + DBGLOG(TDLS, ERROR, "prBssInfo %d is NULL!\n" + , prCmd->ucBssIdx); + return 0; + } + + DBGLOG(TDLS, INFO, "prCmd->oper=%d, u4SetBufferLen=%d", + prCmd->oper, u4SetBufferLen); + + switch (prCmd->oper) { + + case TDLS_ENABLE_LINK: + + for (i = 0; i < MAXNUM_TDLS_PEER; i++) { + if (!g_arTdlsLink[i]) { + g_arTdlsLink[i] = 1; + prStaRec = + cnmGetTdlsPeerByAddress(prAdapter, + prBssInfo->ucBssIndex, + prCmd->aucPeerMac); + prStaRec->ucTdlsIndex = i; + break; + } + } + + /* printk("TDLS_ENABLE_LINK %d\n", i); */ + break; + case TDLS_DISABLE_LINK: + + prStaRec = cnmGetTdlsPeerByAddress(prAdapter, + prBssInfo->ucBssIndex, + prCmd->aucPeerMac); + + /* printk("TDLS_ENABLE_LINK %d\n", prStaRec->ucTdlsIndex); */ + g_arTdlsLink[prStaRec->ucTdlsIndex] = 0; + if (IS_DLS_STA(prStaRec)) + cnmStaRecFree(prAdapter, prStaRec); + + break; + default: + return 0; + } + + return 0; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to append general IEs. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * \param[in] + * + * \retval append length + */ +/*----------------------------------------------------------------------------*/ +uint32_t TdlsFrameGeneralIeAppend(struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, uint8_t *pPkt) +{ + struct GLUE_INFO *prGlueInfo; + struct BSS_INFO *prBssInfo; + struct PM_PROFILE_SETUP_INFO *prPmProfSetupInfo; + uint16_t u2SupportedRateSet; + uint8_t aucAllSupportedRates[RATE_NUM_SW] = { 0 }; + uint8_t ucAllSupportedRatesLen; + uint8_t ucSupRatesLen; + uint8_t ucExtSupRatesLen; + uint32_t u4PktLen, u4IeLen; + + /* init */ + prGlueInfo = (struct GLUE_INFO *) prAdapter->prGlueInfo; + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prStaRec->ucBssIndex); + if (prBssInfo == NULL) { + DBGLOG(TDLS, ERROR, "prBssInfo %d is NULL!\n" + , prStaRec->ucBssIndex); + return 0; + } + + prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; + u4PktLen = 0; + + /* 3. Frame Formation - (5) Supported Rates element */ + /* use all sup rate we can support */ + u2SupportedRateSet = prStaRec->u2OperationalRateSet; + rateGetDataRatesFromRateSet(u2SupportedRateSet, 0, + aucAllSupportedRates, + &ucAllSupportedRatesLen); + + ucSupRatesLen = ((ucAllSupportedRatesLen > + ELEM_MAX_LEN_SUP_RATES) ? + ELEM_MAX_LEN_SUP_RATES : ucAllSupportedRatesLen); + + ucExtSupRatesLen = ucAllSupportedRatesLen - ucSupRatesLen; + + if (ucSupRatesLen) { + SUP_RATES_IE(pPkt)->ucId = ELEM_ID_SUP_RATES; + SUP_RATES_IE(pPkt)->ucLength = ucSupRatesLen; + kalMemCopy(SUP_RATES_IE(pPkt)->aucSupportedRates, + aucAllSupportedRates, ucSupRatesLen); + + u4IeLen = IE_SIZE(pPkt); + pPkt += u4IeLen; + u4PktLen += u4IeLen; + } + + /* 3. Frame Formation - (7) Extended sup rates element */ + if (ucExtSupRatesLen) { + + EXT_SUP_RATES_IE(pPkt)->ucId = ELEM_ID_EXTENDED_SUP_RATES; + EXT_SUP_RATES_IE(pPkt)->ucLength = ucExtSupRatesLen; + + kalMemCopy(EXT_SUP_RATES_IE(pPkt)->aucExtSupportedRates, + &aucAllSupportedRates[ucSupRatesLen], + ucExtSupRatesLen); + + u4IeLen = IE_SIZE(pPkt); + pPkt += u4IeLen; + u4PktLen += u4IeLen; + } + + /* 3. Frame Formation - (8) Supported channels element */ + SUPPORTED_CHANNELS_IE(pPkt)->ucId = ELEM_ID_SUP_CHS; + SUPPORTED_CHANNELS_IE(pPkt)->ucLength = 2; + SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[0] = 1; + SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[1] = 13; + + if (prAdapter->fgEnable5GBand == TRUE) { + SUPPORTED_CHANNELS_IE(pPkt)->ucLength = 10; + SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[2] = 36; + SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[3] = 4; + SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[4] = 52; + SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[5] = 4; + SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[6] = 149; + SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[7] = 4; + SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[8] = 165; + SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[9] = 1; + } + + u4IeLen = IE_SIZE(pPkt); + pPkt += u4IeLen; + u4PktLen += u4IeLen; + + return u4PktLen; +} + +/*! + * \brief This routine is called to transmit a TDLS data frame. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * \param[in] + * \param[in] + * \param[in] buf includes RSN IE + FT IE + Lifetimeout IE + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t +TdlsDataFrameSend_TearDown(struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + uint8_t *pPeerMac, + uint8_t ucActionCode, + uint8_t ucDialogToken, uint16_t u2StatusCode, + uint8_t *pAppendIe, uint32_t AppendIeLen) +{ + + struct GLUE_INFO *prGlueInfo; + struct BSS_INFO *prBssInfo; + struct PM_PROFILE_SETUP_INFO *prPmProfSetupInfo; + struct sk_buff *prMsduInfo; + uint8_t *pPkt; + uint32_t u4PktLen, u4IeLen; + uint16_t ReasonCode; + + /* allocate/init packet */ + prGlueInfo = (struct GLUE_INFO *) prAdapter->prGlueInfo; + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prStaRec->ucBssIndex); + if (prBssInfo == NULL) { + DBGLOG(TDLS, ERROR, "prBssInfo %d is NULL!\n" + , prStaRec->ucBssIndex); + return 0; + } + + prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; + u4PktLen = 0; + + prMsduInfo = kalPacketAllocWithHeadroom(prGlueInfo, 1600, + &pPkt); + if (prMsduInfo == NULL) + return TDLS_STATUS_RESOURCES; + + prMsduInfo->dev = wlanGetNetDev(prGlueInfo, + prStaRec->ucBssIndex); + if (prMsduInfo->dev == NULL) { + kalPacketFree(prGlueInfo, prMsduInfo); + return TDLS_STATUS_FAIL; + } + + /* make up frame content */ + /* 1. 802.3 header */ + kalMemCopy(pPkt, pPeerMac, TDLS_FME_MAC_ADDR_LEN); + pPkt += TDLS_FME_MAC_ADDR_LEN; + kalMemCopy(pPkt, prBssInfo->aucOwnMacAddr, + TDLS_FME_MAC_ADDR_LEN); + pPkt += TDLS_FME_MAC_ADDR_LEN; + *(uint16_t *) pPkt = htons(TDLS_FRM_PROT_TYPE); + pPkt += 2; + u4PktLen += TDLS_FME_MAC_ADDR_LEN * 2 + 2; + + /* 2. payload type */ + *pPkt = TDLS_FRM_PAYLOAD_TYPE; + pPkt++; + u4PktLen++; + + /* 3. Frame Formation - (1) Category */ + *pPkt = TDLS_FRM_CATEGORY; + pPkt++; + u4PktLen++; + + /* 3. Frame Formation - (2) Action */ + *pPkt = ucActionCode; + pPkt++; + u4PktLen++; + + /* 3. Frame Formation - status code */ + + ReasonCode = u2StatusCode; + + /* printk("\n\n ReasonCode = %u\n\n",ReasonCode ); */ + + kalMemCopy(pPkt, &ReasonCode, 2); + pPkt = pPkt + 2; + u4PktLen = u4PktLen + 2; + + if (pAppendIe != NULL) { + kalMemCopy(pPkt, pAppendIe, AppendIeLen); + LR_TDLS_FME_FIELD_FILL(AppendIeLen); + } + + /* 7. Append Supported Operating Classes IE */ + if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) { + /* Note: if we do not put the IE, Marvell STA will + * decline our TDLS setup request + */ + u4IeLen = rlmDomainSupOperatingClassIeFill(pPkt); + LR_TDLS_FME_FIELD_FILL(u4IeLen); + } + + /* 3. Frame Formation - (16) Link identifier element */ + TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = + ELEM_ID_LINK_IDENTIFIER; + TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = 18; + + kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, + prBssInfo->aucBSSID, 6); + kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, + prBssInfo->aucOwnMacAddr, 6); + kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, + pPeerMac, 6); + + u4IeLen = IE_SIZE(pPkt); + pPkt += u4IeLen; + u4PktLen += u4IeLen; + + /* 5. Update packet length */ + prMsduInfo->len = u4PktLen; + + /* printk(" TdlsDataFrameSend_TearDown !!\n"); */ + + /* 5. send the data frame */ + wlanHardStartXmit(prMsduInfo, prMsduInfo->dev); + + return TDLS_STATUS_PENDING; +} + +/*! + * \brief This routine is called to transmit a TDLS data frame. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * \param[in] + * \param[in] + * \param[in] buf includes RSN IE + FT IE + Lifetimeout IE + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t /* TDLS_STATUS */ +TdlsDataFrameSend_SETUP_REQ(struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + uint8_t *pPeerMac, + uint8_t ucActionCode, + uint8_t ucDialogToken, uint16_t u2StatusCode, + uint8_t *pAppendIe, uint32_t AppendIeLen) +{ + + struct GLUE_INFO *prGlueInfo; + struct BSS_INFO *prBssInfo; + struct PM_PROFILE_SETUP_INFO *prPmProfSetupInfo; + struct sk_buff *prMsduInfo; + uint8_t *pPkt; + uint32_t u4PktLen, u4IeLen; + uint16_t u2CapInfo; + + /* allocate/init packet */ + prGlueInfo = (struct GLUE_INFO *) prAdapter->prGlueInfo; + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prStaRec->ucBssIndex); + if (prBssInfo == NULL) { + DBGLOG(TDLS, ERROR, "prBssInfo %d is NULL!\n" + , prStaRec->ucBssIndex); + return 0; + } + + prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; + u4PktLen = 0; + + prMsduInfo = kalPacketAllocWithHeadroom(prGlueInfo, 512, &pPkt); + if (prMsduInfo == NULL) + return TDLS_STATUS_RESOURCES; + + prMsduInfo->dev = wlanGetNetDev(prGlueInfo, + prStaRec->ucBssIndex); + if (prMsduInfo->dev == NULL) { + kalPacketFree(prGlueInfo, prMsduInfo); + return TDLS_STATUS_FAIL; + } + + /* make up frame content */ + /* 1. 802.3 header */ + kalMemCopy(pPkt, pPeerMac, TDLS_FME_MAC_ADDR_LEN); + LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); + kalMemCopy(pPkt, prBssInfo->aucOwnMacAddr, TDLS_FME_MAC_ADDR_LEN); + LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); + *(uint16_t *) pPkt = htons(TDLS_FRM_PROT_TYPE); + LR_TDLS_FME_FIELD_FILL(2); + + /* 2. payload type */ + *pPkt = TDLS_FRM_PAYLOAD_TYPE; + LR_TDLS_FME_FIELD_FILL(1); + + /* + * 3.1 Category + * 3.2 Action + * 3.3 Dialog Token + * 3.4 Capability + * 3.5 Supported rates + * 3.6 Country + * 3.7 Extended supported rates + * 3.8 Supported Channels (optional) + * 3.9 RSNIE (optional) + * 3.10 Extended Capabilities + * 3.11 QoS Capability + * 3.12 FTIE (optional) + * 3.13 Timeout Interval (optional) + * 3.14 Supported Regulatory Classes (optional) + * 3.15 HT Capabilities + * 3.16 20/40 BSS Coexistence + * 3.17 Link Identifier + */ + + /* 3.1 Category */ + *pPkt = TDLS_FRM_CATEGORY; + LR_TDLS_FME_FIELD_FILL(1); + + /* 3.2 Action */ + *pPkt = ucActionCode; + LR_TDLS_FME_FIELD_FILL(1); + + /* 3.3 Dialog Token */ + *pPkt = ucDialogToken; + LR_TDLS_FME_FIELD_FILL(1); + + /* 3.4 Capability */ + u2CapInfo = assocBuildCapabilityInfo(prAdapter, prStaRec); + WLAN_SET_FIELD_16(pPkt, u2CapInfo); + LR_TDLS_FME_FIELD_FILL(2); + + /* + * 3.5 Supported rates + * 3.7 Extended supported rates + * 3.8 Supported Channels (optional) + */ + u4IeLen = TdlsFrameGeneralIeAppend(prAdapter, prStaRec, pPkt); + LR_TDLS_FME_FIELD_FILL(u4IeLen); + + /* 3.6 Country */ + /* 3.14 Supported Regulatory Classes (optional) */ + /* Note: if we do not put the IE, Marvell STA will decline + * our TDLS setup request + */ + u4IeLen = rlmDomainSupOperatingClassIeFill(pPkt); + LR_TDLS_FME_FIELD_FILL(u4IeLen); + + /* 3.10 Extended Capabilities */ + EXT_CAP_IE(pPkt)->ucId = ELEM_ID_EXTENDED_CAP; + EXT_CAP_IE(pPkt)->ucLength = 5; + + EXT_CAP_IE(pPkt)->aucCapabilities[0] = 0x00; /* bit0 ~ bit7 */ + EXT_CAP_IE(pPkt)->aucCapabilities[1] = 0x00; /* bit8 ~ bit15 */ + EXT_CAP_IE(pPkt)->aucCapabilities[2] = 0x00; /* bit16 ~ bit23 */ + EXT_CAP_IE(pPkt)->aucCapabilities[3] = 0x00; /* bit24 ~ bit31 */ + EXT_CAP_IE(pPkt)->aucCapabilities[4] = 0x00; /* bit32 ~ bit39 */ + + EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((28 - 24)); + EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((30 - 24)); + EXT_CAP_IE(pPkt)->aucCapabilities[4] |= BIT((37 - 32)); + + u4IeLen = IE_SIZE(pPkt); + LR_TDLS_FME_FIELD_FILL(u4IeLen); + + /* Append extra IEs */ + /* + * 3.9 RSNIE (optional) + * 3.12 FTIE (optional) + * 3.13 Timeout Interval (optional) + */ + if (pAppendIe != NULL) { + kalMemCopy(pPkt, pAppendIe, AppendIeLen); + LR_TDLS_FME_FIELD_FILL(AppendIeLen); + } + + /* 3.11 QoS Capability */ + /* HT WMM IE append */ + if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucQoS)) { + u4IeLen = mqmGenerateWmmInfoIEByStaRec(prAdapter, prBssInfo, + prStaRec, pPkt); + LR_TDLS_FME_FIELD_FILL(u4IeLen); + u4IeLen = mqmGenerateWmmParamIEByParam(prAdapter, prBssInfo, + pPkt); + LR_TDLS_FME_FIELD_FILL(u4IeLen); + } + + /* 3.15 HT Capabilities */ + if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & + PHY_TYPE_SET_802_11N)) { + u4IeLen = rlmFillHtCapIEByAdapter(prAdapter, prBssInfo, pPkt); + LR_TDLS_FME_FIELD_FILL(u4IeLen); + } +#if 0 /* TODO: VHT support */ +#if CFG_SUPPORT_802_11AC + if (prAdapter->rWifiVar.ucAvailablePhyTypeSet & + PHY_TYPE_SET_802_11AC) { + u4IeLen = rlmFillVhtCapIEByAdapter(prAdapter, prBssInfo, pPkt); + LR_TDLS_FME_FIELD_FILL(u4IeLen); + } +#endif +#endif + + /* 3.16 20/40 BSS Coexistence */ + BSS_20_40_COEXIST_IE(pPkt)->ucId = ELEM_ID_20_40_BSS_COEXISTENCE; + BSS_20_40_COEXIST_IE(pPkt)->ucLength = 1; + BSS_20_40_COEXIST_IE(pPkt)->ucData = 0x01; + LR_TDLS_FME_FIELD_FILL(3); + + /* 3.17 Link Identifier */ + TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER; + TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = 18; + kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, + prBssInfo->aucBSSID, 6); + kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, + prBssInfo->aucOwnMacAddr, 6); + kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, + pPeerMac, 6); + + u4IeLen = IE_SIZE(pPkt); + LR_TDLS_FME_FIELD_FILL(u4IeLen); + + /* 4. Update packet length */ + prMsduInfo->len = u4PktLen; + + DBGLOG(TDLS, INFO, "wlanHardStartXmit, u4PktLen=%d", u4PktLen); + + /* 5. send the data frame */ + wlanHardStartXmit(prMsduInfo, prMsduInfo->dev); + + return TDLS_STATUS_PENDING; +} + +uint32_t +TdlsDataFrameSend_SETUP_RSP(struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + uint8_t *pPeerMac, + uint8_t ucActionCode, + uint8_t ucDialogToken, uint16_t u2StatusCode, + uint8_t *pAppendIe, uint32_t AppendIeLen) +{ + struct GLUE_INFO *prGlueInfo; + struct BSS_INFO *prBssInfo; + struct PM_PROFILE_SETUP_INFO *prPmProfSetupInfo; + struct sk_buff *prMsduInfo; + uint8_t *pPkt; + uint32_t u4PktLen, u4IeLen; + uint16_t u2CapInfo; + + /* allocate/init packet */ + prGlueInfo = (struct GLUE_INFO *) prAdapter->prGlueInfo; + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prStaRec->ucBssIndex); + if (prBssInfo == NULL) { + DBGLOG(TDLS, ERROR, "prBssInfo %d is NULL!\n" + , prStaRec->ucBssIndex); + return 0; + } + prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; + u4PktLen = 0; + + prMsduInfo = kalPacketAllocWithHeadroom(prGlueInfo, 512, &pPkt); + if (prMsduInfo == NULL) + return TDLS_STATUS_RESOURCES; + + prMsduInfo->dev = wlanGetNetDev(prGlueInfo, + prStaRec->ucBssIndex); + if (prMsduInfo->dev == NULL) { + kalPacketFree(prGlueInfo, prMsduInfo); + return TDLS_STATUS_FAIL; + } + + /* make up frame content */ + /* 1. 802.3 header */ + kalMemCopy(pPkt, pPeerMac, TDLS_FME_MAC_ADDR_LEN); + LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); + kalMemCopy(pPkt, prBssInfo->aucOwnMacAddr, TDLS_FME_MAC_ADDR_LEN); + LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); + *(uint16_t *) pPkt = htons(TDLS_FRM_PROT_TYPE); + LR_TDLS_FME_FIELD_FILL(2); + + /* 2. payload type */ + *pPkt = TDLS_FRM_PAYLOAD_TYPE; + LR_TDLS_FME_FIELD_FILL(1); + + /* + * 3.1 Category + * 3.2 Action + * 3.3 Status Code + * 3.4 Dialog Token + *** Below IE should be only included for Status Code=0 (Successful) + * 3.5 Capability + * 3.6 Supported rates + * 3.7 Country + * 3.8 Extended supported rates + * 3.9 Supported Channels (optional) + * 3.10 RSNIE (optional) + * 3.11 Extended Capabilities + * 3.12 QoS Capability + * 3.13 FTIE (optional) + * 3.14 Timeout Interval (optional) + * 3.15 Supported Regulatory Classes (optional) + * 3.16 HT Capabilities + * 3.17 20/40 BSS Coexistence + * 3.18 Link Identifier + */ + + /* 3.1 Category */ + *pPkt = TDLS_FRM_CATEGORY; + LR_TDLS_FME_FIELD_FILL(1); + + /* 3.2 Action */ + *pPkt = ucActionCode; + LR_TDLS_FME_FIELD_FILL(1); + + /* 3.3 Status Code */ + kalMemCopy(pPkt, &u2StatusCode, 2); + LR_TDLS_FME_FIELD_FILL(2); + + /* 3.4 Dialog Token */ + *pPkt = ucDialogToken; + LR_TDLS_FME_FIELD_FILL(1); + + if (u2StatusCode == 0) { + /* 3.5 Capability */ + u2CapInfo = assocBuildCapabilityInfo(prAdapter, prStaRec); + WLAN_SET_FIELD_16(pPkt, u2CapInfo); + LR_TDLS_FME_FIELD_FILL(2); + + /* + * 3.6 Supported rates + * 3.8 Extended supported rates + * 3.9 Supported Channels (optional) + */ + u4IeLen = TdlsFrameGeneralIeAppend(prAdapter, prStaRec, pPkt); + LR_TDLS_FME_FIELD_FILL(u4IeLen); + + /* 3.7 Country */ + /* 3.15 Supported Regulatory Classes (optional) */ + /* Note: if we do not put the IE, Marvell STA will decline + * our TDLS setup request + */ + u4IeLen = rlmDomainSupOperatingClassIeFill(pPkt); + LR_TDLS_FME_FIELD_FILL(u4IeLen); + + /* 3.11 Extended Capabilities */ + EXT_CAP_IE(pPkt)->ucId = ELEM_ID_EXTENDED_CAP; + EXT_CAP_IE(pPkt)->ucLength = 5; + + EXT_CAP_IE(pPkt)->aucCapabilities[0] = 0x00; /* bit0 ~ bit7 */ + EXT_CAP_IE(pPkt)->aucCapabilities[1] = 0x00; /* bit8 ~ bit15 */ + EXT_CAP_IE(pPkt)->aucCapabilities[2] = 0x00; /* bit16 ~ bit23 */ + EXT_CAP_IE(pPkt)->aucCapabilities[3] = 0x00; /* bit24 ~ bit31 */ + EXT_CAP_IE(pPkt)->aucCapabilities[4] = 0x00; /* bit32 ~ bit39 */ + + EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((28 - 24)); + EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((30 - 24)); + EXT_CAP_IE(pPkt)->aucCapabilities[4] |= BIT((37 - 32)); + + u4IeLen = IE_SIZE(pPkt); + LR_TDLS_FME_FIELD_FILL(u4IeLen); + + /* 3.12 QoS Capability */ + if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucQoS)) { + /* Add WMM IE *//* try to reuse p2p path */ + u4IeLen = mqmGenerateWmmInfoIEByStaRec(prAdapter, + prBssInfo, prStaRec, pPkt); + LR_TDLS_FME_FIELD_FILL(u4IeLen); + + u4IeLen = mqmGenerateWmmParamIEByParam(prAdapter, + prBssInfo, pPkt); + LR_TDLS_FME_FIELD_FILL(u4IeLen); + } + + /* 3.16 HT Capabilities */ + if (prAdapter->rWifiVar.ucAvailablePhyTypeSet & + PHY_TYPE_SET_802_11N) { + u4IeLen = rlmFillHtCapIEByAdapter(prAdapter, prBssInfo, + pPkt); + LR_TDLS_FME_FIELD_FILL(u4IeLen); + } +#if 0 /* TODO: VHT support */ +#if CFG_SUPPORT_802_11AC + if (prAdapter->rWifiVar.ucAvailablePhyTypeSet & + PHY_TYPE_SET_802_11AC) { + u4IeLen = rlmFillVhtCapIEByAdapter(prAdapter, prBssInfo, + pPkt); + LR_TDLS_FME_FIELD_FILL(u4IeLen); + } +#endif +#endif + + /* 3.17 20/40 BSS Coexistence */ + BSS_20_40_COEXIST_IE(pPkt)->ucId = + ELEM_ID_20_40_BSS_COEXISTENCE; + BSS_20_40_COEXIST_IE(pPkt)->ucLength = 1; + BSS_20_40_COEXIST_IE(pPkt)->ucData = 0x01; + LR_TDLS_FME_FIELD_FILL(3); + + /* 3.18 Link Identifier */ + TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER; + TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = 18; + + kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, + prBssInfo->aucBSSID, 6); + kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, + pPeerMac, 6); + kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, + prBssInfo->aucOwnMacAddr, 6); + + u4IeLen = IE_SIZE(pPkt); + LR_TDLS_FME_FIELD_FILL(u4IeLen); + + /* Append extra IEs */ + /* + * 3.10 RSNIE (optional) + * 3.13 FTIE (optional) + * 3.14 Timeout Interval (optional) + */ + if (pAppendIe != NULL) { + kalMemCopy(pPkt, pAppendIe, AppendIeLen); + LR_TDLS_FME_FIELD_FILL(AppendIeLen); + } + } + + /* 4. Update packet length */ + prMsduInfo->len = u4PktLen; + + /* 5. send the data frame */ + wlanHardStartXmit(prMsduInfo, prMsduInfo->dev); + + return TDLS_STATUS_PENDING; +} + +uint32_t +TdlsDataFrameSend_CONFIRM(struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + uint8_t *pPeerMac, + uint8_t ucActionCode, + uint8_t ucDialogToken, uint16_t u2StatusCode, + uint8_t *pAppendIe, uint32_t AppendIeLen) +{ + + struct GLUE_INFO *prGlueInfo; + struct BSS_INFO *prBssInfo; + struct PM_PROFILE_SETUP_INFO *prPmProfSetupInfo; + struct sk_buff *prMsduInfo; + uint8_t *pPkt; + uint32_t u4PktLen, u4IeLen; + + /* allocate/init packet */ + prGlueInfo = (struct GLUE_INFO *) prAdapter->prGlueInfo; + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prStaRec->ucBssIndex); + if (prBssInfo == NULL) { + DBGLOG(TDLS, ERROR, "prBssInfo %d is NULL!\n" + , prStaRec->ucBssIndex); + return 0; + } + + prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; + u4PktLen = 0; + + prMsduInfo = kalPacketAllocWithHeadroom(prGlueInfo, 512, &pPkt); + if (prMsduInfo == NULL) + return TDLS_STATUS_RESOURCES; + + prMsduInfo->dev = wlanGetNetDev(prGlueInfo, + prStaRec->ucBssIndex); + if (prMsduInfo->dev == NULL) { + kalPacketFree(prGlueInfo, prMsduInfo); + return TDLS_STATUS_FAIL; + } + + /* make up frame content */ + /* 1. 802.3 header */ + kalMemCopy(pPkt, pPeerMac, TDLS_FME_MAC_ADDR_LEN); + LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); + kalMemCopy(pPkt, prBssInfo->aucOwnMacAddr, TDLS_FME_MAC_ADDR_LEN); + LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); + *(uint16_t *) pPkt = htons(TDLS_FRM_PROT_TYPE); + LR_TDLS_FME_FIELD_FILL(2); + + /* 2. payload type */ + *pPkt = TDLS_FRM_PAYLOAD_TYPE; + LR_TDLS_FME_FIELD_FILL(1); + + /* + * 3.1 Category + * 3.2 Action + * 3.3 Status Code + * 3.4 Dialog Token + *** 3.5 - 3.9 should be only included for Status Code=0 (Successful) + * 3.5 RSNIE (optional) + * 3.6 EDCA Parameter Set + * 3.7 FTIE (optional) + * 3.8 Timeout Interval (optional) + * 3.9 HT Operation (optional) + * 3.10 Link Identifier + */ + + /* 3.1 Category */ + *pPkt = TDLS_FRM_CATEGORY; + LR_TDLS_FME_FIELD_FILL(1); + + /* 3.2 Action */ + *pPkt = ucActionCode; + LR_TDLS_FME_FIELD_FILL(1); + + /* 3.3 Status Code */ + kalMemCopy(pPkt, &u2StatusCode, 2); + LR_TDLS_FME_FIELD_FILL(2); + + /* 3.4 Dialog Token */ + *pPkt = ucDialogToken; + LR_TDLS_FME_FIELD_FILL(1); + + if (u2StatusCode == 0) { + /* + * 3.5 RSNIE (optional) + * 3.7 FTIE (optional) + * 3.8 Timeout Interval (optional) + */ + if (pAppendIe) { + kalMemCopy(pPkt, pAppendIe, AppendIeLen); + LR_TDLS_FME_FIELD_FILL(AppendIeLen); + } + + /* 3.6 EDCA Parameter Set */ + /* HT WMM IE append */ + if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucQoS)) { + u4IeLen = mqmGenerateWmmInfoIEByStaRec(prAdapter, + prBssInfo, prStaRec, pPkt); + LR_TDLS_FME_FIELD_FILL(u4IeLen); + u4IeLen = mqmGenerateWmmParamIEByParam(prAdapter, + prBssInfo, pPkt); + LR_TDLS_FME_FIELD_FILL(u4IeLen); + } + } + + /* 3.10 Link Identifier */ + TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER; + TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = 18; + kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, + prBssInfo->aucBSSID, 6); + kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, + prBssInfo->aucOwnMacAddr, 6); + kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, + pPeerMac, 6); + + u4IeLen = IE_SIZE(pPkt); + LR_TDLS_FME_FIELD_FILL(u4IeLen); + + /* 4. Update packet length */ + prMsduInfo->len = u4PktLen; + + /* 5. send the data frame */ + wlanHardStartXmit(prMsduInfo, prMsduInfo->dev); + + return TDLS_STATUS_PENDING; +} + +/* + * \brief This routine is called to transmit a TDLS data frame. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * \param[in] + * \param[in] + * \param[in] buf includes RSN IE + FT IE + Lifetimeout IE + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +uint32_t /* TDLS_STATUS */ +TdlsDataFrameSend_DISCOVERY_REQ(struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + uint8_t *pPeerMac, + uint8_t ucActionCode, + uint8_t ucDialogToken, uint16_t u2StatusCode, + uint8_t *pAppendIe, uint32_t AppendIeLen) +{ + struct GLUE_INFO *prGlueInfo; + struct BSS_INFO *prBssInfo; + struct PM_PROFILE_SETUP_INFO *prPmProfSetupInfo; + struct sk_buff *prMsduInfo; + struct MSDU_INFO *prMsduInfoMgmt; + uint8_t *pPkt, *pucInitiator, *pucResponder; + uint32_t u4PktLen, u4IeLen; + + prGlueInfo = (struct GLUE_INFO *) prAdapter->prGlueInfo; + + if (prStaRec != NULL) { + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prStaRec->ucBssIndex); + if (prBssInfo == NULL) { + DBGLOG(TDLS, ERROR, "prBssInfo %d is NULL!\n" + , prStaRec->ucBssIndex); + return TDLS_STATUS_FAIL; + } + } else + return TDLS_STATUS_FAIL; + + /* allocate/init packet */ + prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; + u4PktLen = 0; + prMsduInfo = NULL; + prMsduInfoMgmt = NULL; + + /* make up frame content */ + prMsduInfo = kalPacketAllocWithHeadroom(prGlueInfo, 512, &pPkt); + if (prMsduInfo == NULL) + return TDLS_STATUS_RESOURCES; + + prMsduInfo->dev = wlanGetNetDev(prGlueInfo, + prStaRec->ucBssIndex); + if (prMsduInfo->dev == NULL) { + kalPacketFree(prGlueInfo, prMsduInfo); + return TDLS_STATUS_FAIL; + } + + /* 1. 802.3 header */ + kalMemCopy(pPkt, pPeerMac, TDLS_FME_MAC_ADDR_LEN); + LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); + kalMemCopy(pPkt, prBssInfo->aucOwnMacAddr, TDLS_FME_MAC_ADDR_LEN); + LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); + *(uint16_t *) pPkt = htons(TDLS_FRM_PROT_TYPE); + LR_TDLS_FME_FIELD_FILL(2); + + /* 2. payload type */ + *pPkt = TDLS_FRM_PAYLOAD_TYPE; + LR_TDLS_FME_FIELD_FILL(1); + + /* + * 3.1 Category + * 3.2 Action + * 3.3 Dialog Token + * 3.4 Link Identifier + */ + + /* 3.1 Category */ + *pPkt = TDLS_FRM_CATEGORY; + LR_TDLS_FME_FIELD_FILL(1); + + /* 3.2 Action */ + *pPkt = ucActionCode; + LR_TDLS_FME_FIELD_FILL(1); + + /* 3.3 Dialog Token */ + *pPkt = ucDialogToken; + LR_TDLS_FME_FIELD_FILL(1); + + /* 3.4 Link Identifier */ + TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER; + TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = 18; + kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, + prBssInfo->aucBSSID, 6); + pucInitiator = prBssInfo->aucOwnMacAddr; + pucResponder = pPeerMac; + prStaRec->flgTdlsIsInitiator = TRUE; + kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, pucInitiator, 6); + kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, pucResponder, 6); + u4IeLen = IE_SIZE(pPkt); + LR_TDLS_FME_FIELD_FILL(u4IeLen); + + /* 4. Update packet length */ + prMsduInfo->len = u4PktLen; + + /* 5. send the data frame */ + wlanHardStartXmit(prMsduInfo, prMsduInfo->dev); + + return TDLS_STATUS_PENDING; +} + +uint32_t +TdlsDataFrameSend_DISCOVERY_RSP(struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + uint8_t *pPeerMac, + uint8_t ucActionCode, + uint8_t ucDialogToken, uint16_t u2StatusCode, + uint8_t *pAppendIe, uint32_t AppendIeLen) +{ + struct GLUE_INFO *prGlueInfo; + struct BSS_INFO *prBssInfo; + struct PM_PROFILE_SETUP_INFO *prPmProfSetupInfo; + struct MSDU_INFO *prMsduInfoMgmt; + uint8_t *pPkt, *pucInitiator, *pucResponder; + uint32_t u4PktLen, u4IeLen; + uint16_t u2CapInfo; + struct WLAN_MAC_HEADER *prHdr; + + prGlueInfo = (struct GLUE_INFO *) prAdapter->prGlueInfo; + + /* sanity check */ + if (prStaRec != NULL) { + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prStaRec->ucBssIndex); + if (prBssInfo == NULL) { + DBGLOG(TDLS, ERROR, "prBssInfo %d is NULL!\n" + , prStaRec->ucBssIndex); + return TDLS_STATUS_FAIL; + } + } else + return TDLS_STATUS_FAIL; + + /* allocate/init packet */ + prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; + u4PktLen = 0; + prMsduInfoMgmt = NULL; + + /* make up frame content */ + prMsduInfoMgmt = (struct MSDU_INFO *) cnmMgtPktAlloc(prAdapter, + PUBLIC_ACTION_MAX_LEN); + if (prMsduInfoMgmt == NULL) + return TDLS_STATUS_RESOURCES; + + pPkt = (uint8_t *) prMsduInfoMgmt->prPacket; + prHdr = (struct WLAN_MAC_HEADER *) pPkt; + + /* 1. 802.11 header */ + prHdr->u2FrameCtrl = MAC_FRAME_ACTION; + prHdr->u2DurationID = 0; + kalMemCopy(prHdr->aucAddr1, pPeerMac, TDLS_FME_MAC_ADDR_LEN); + kalMemCopy(prHdr->aucAddr2, prBssInfo->aucOwnMacAddr, + TDLS_FME_MAC_ADDR_LEN); + kalMemCopy(prHdr->aucAddr3, prBssInfo->aucBSSID, TDLS_FME_MAC_ADDR_LEN); + prHdr->u2SeqCtrl = 0; + LR_TDLS_FME_FIELD_FILL(sizeof(struct WLAN_MAC_HEADER)); + + + /* + * 3.1 Category + * 3.2 Action + * 3.3 Dialog Token + * 3.4 Capability + * 3.5 Supported rates + * 3.6 Extended supported rates + * 3.7 Supported Channels (optional) + * 3.8 RSNIE + * 3.9 Extended Capabilities + * 3.10 FTIE + * 3.11 Timeout Interval (optional) + * 3.12 Supported Regulatory Classes (optional) + * 3.13 HT Capabilities + * 3.14 20/40 BSS Coexistence + * 3.15 Link Identifier + */ + + /* 3.1 Category */ + *pPkt = CATEGORY_PUBLIC_ACTION; + LR_TDLS_FME_FIELD_FILL(1); + + /* 3.2 Action */ + *pPkt = ucActionCode; + LR_TDLS_FME_FIELD_FILL(1); + + /* 3.3 Dialog Token */ + *pPkt = ucDialogToken; + LR_TDLS_FME_FIELD_FILL(1); + + + /* 3.4 Capability */ + u2CapInfo = assocBuildCapabilityInfo(prAdapter, prStaRec); + WLAN_SET_FIELD_16(pPkt, u2CapInfo); + LR_TDLS_FME_FIELD_FILL(2); + + /* + * 3.5 Supported rates + * 3.6 Extended supported rates + * 3.7 Supported Channels (optional) + */ + u4IeLen = TdlsFrameGeneralIeAppend(prAdapter, prStaRec, pPkt); + LR_TDLS_FME_FIELD_FILL(u4IeLen); + + /* 3.9 Extended Capabilities */ + EXT_CAP_IE(pPkt)->ucId = ELEM_ID_EXTENDED_CAP; + EXT_CAP_IE(pPkt)->ucLength = 5; + + EXT_CAP_IE(pPkt)->aucCapabilities[0] = 0x00; /* bit0 ~ bit7 */ + EXT_CAP_IE(pPkt)->aucCapabilities[1] = 0x00; /* bit8 ~ bit15 */ + EXT_CAP_IE(pPkt)->aucCapabilities[2] = 0x00; /* bit16 ~ bit23 */ + EXT_CAP_IE(pPkt)->aucCapabilities[3] = 0x00; /* bit24 ~ bit31 */ + EXT_CAP_IE(pPkt)->aucCapabilities[4] = 0x00; /* bit32 ~ bit39 */ + + /* bit 28 TDLS_EX_CAP_PEER_UAPSD */ + EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((28 - 24)); + /* bit 30 TDLS_EX_CAP_CHAN_SWITCH */ + EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((30 - 24)); + /* bit 37 TDLS_EX_CAP_TDLS */ + EXT_CAP_IE(pPkt)->aucCapabilities[4] |= BIT((37 - 32)); + + u4IeLen = IE_SIZE(pPkt); + LR_TDLS_FME_FIELD_FILL(u4IeLen); + + /* + * 3.8 RSNIE + * 3.10 FTIE + * 3.11 Timeout Interval (optional) + */ + if (pAppendIe != NULL) { + kalMemCopy(pPkt, pAppendIe, AppendIeLen); + LR_TDLS_FME_FIELD_FILL(AppendIeLen); + } + + /* 3.12 Supported Regulatory Classes (optional) */ + /* Note: if we do not put the IE, Marvell STA will + * decline our TDLS setup request + */ + u4IeLen = rlmDomainSupOperatingClassIeFill(pPkt); + LR_TDLS_FME_FIELD_FILL(u4IeLen); + + /* 3.13 HT Capabilities */ + if (prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11N) { + u4IeLen = rlmFillHtCapIEByAdapter(prAdapter, prBssInfo, pPkt); + LR_TDLS_FME_FIELD_FILL(u4IeLen); + } + +#if 0 /* TODO: VHT support */ +#if CFG_SUPPORT_802_11AC + if (prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11AC) { + u4IeLen = rlmFillVhtCapIEByAdapter(prAdapter, prBssInfo, pPkt); + LR_TDLS_FME_FIELD_FILL(u4IeLen); + } +#endif +#endif + + /* 3.14 20/40 BSS Coexistence */ + BSS_20_40_COEXIST_IE(pPkt)->ucId = ELEM_ID_20_40_BSS_COEXISTENCE; + BSS_20_40_COEXIST_IE(pPkt)->ucLength = 1; + BSS_20_40_COEXIST_IE(pPkt)->ucData = 0x01; + LR_TDLS_FME_FIELD_FILL(3); + + /* 3.15 Link Identifier */ + TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER; + TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = 18; + kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, + prBssInfo->aucBSSID, 6); + kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, + pPeerMac, 6); + kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, + prBssInfo->aucOwnMacAddr, 6); + + u4IeLen = IE_SIZE(pPkt); + LR_TDLS_FME_FIELD_FILL(u4IeLen); + pucInitiator = pPeerMac; + pucResponder = prBssInfo->aucOwnMacAddr; + if (prStaRec != NULL) + prStaRec->flgTdlsIsInitiator = FALSE; + + if (prMsduInfoMgmt != NULL) { + prMsduInfoMgmt->ucPacketType = TX_PACKET_TYPE_MGMT; + prMsduInfoMgmt->ucStaRecIndex = + prBssInfo->prStaRecOfAP->ucIndex; + prMsduInfoMgmt->ucBssIndex = prBssInfo->ucBssIndex; + prMsduInfoMgmt->ucMacHeaderLength = + WLAN_MAC_MGMT_HEADER_LEN; + prMsduInfoMgmt->fgIs802_1x = FALSE; + prMsduInfoMgmt->fgIs802_11 = TRUE; + prMsduInfoMgmt->u2FrameLength = u4PktLen; + prMsduInfoMgmt->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); + prMsduInfoMgmt->pfTxDoneHandler = NULL; + + /* Send them to HW queue */ + nicTxEnqueueMsdu(prAdapter, prMsduInfoMgmt); + } + + return TDLS_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! \brief This routine is called to send a command to TDLS module. + * + * \param[in] prGlueInfo Pointer to the Adapter structure + * \param[in] prInBuf A pointer to the command string buffer + * \param[in] u4InBufLen The length of the buffer + * \param[out] None + * + * \retval None + */ +/*----------------------------------------------------------------------------*/ +void TdlsexEventHandle(struct GLUE_INFO *prGlueInfo, + uint8_t *prInBuf, uint32_t u4InBufLen) +{ + uint32_t u4EventId; + + DBGLOG(TDLS, INFO, "TdlsexEventHandle\n"); + + /* sanity check */ + if ((prGlueInfo == NULL) || (prInBuf == NULL)) + return; /* shall not be here */ + + /* handle */ + u4EventId = *(uint32_t *) prInBuf; + u4InBufLen -= 4; + + switch (u4EventId) { + case TDLS_HOST_EVENT_TEAR_DOWN: + DBGLOG(TDLS, INFO, "TDLS_HOST_EVENT_TEAR_DOWN\n"); + TdlsEventTearDown(prGlueInfo, prInBuf + 4, u4InBufLen); + break; + + case TDLS_HOST_EVENT_TX_DONE: + + break; + } +} + +/*----------------------------------------------------------------------------*/ +/*! \brief This routine is called to do tear down. + * + * \param[in] prGlueInfo Pointer to the Adapter structure + * \param[in] prInBuf A pointer to the command string buffer, + * from u4EventSubId + * \param[in] u4InBufLen The length of the buffer + * \param[out] None + * + * \retval None + * + */ +/*----------------------------------------------------------------------------*/ +void TdlsEventTearDown(struct GLUE_INFO *prGlueInfo, + uint8_t *prInBuf, uint32_t u4InBufLen) +{ + struct STA_RECORD *prStaRec; + uint16_t u2ReasonCode = TDLS_REASON_CODE_NONE; + uint32_t u4TearDownSubId; + uint8_t *pMac, aucZeroMac[6]; + struct net_device *prDev = NULL; + + /* init */ + u4TearDownSubId = *(uint32_t *) prInBuf; + kalMemZero(aucZeroMac, sizeof(aucZeroMac)); + pMac = aucZeroMac; + + prStaRec = cnmGetStaRecByIndex(prGlueInfo->prAdapter, + *(prInBuf + 4)); + + /* sanity check */ + if (prStaRec == NULL) + return; + + pMac = prStaRec->aucMacAddr; + + if (fgIsPtiTimeoutSkip == TRUE) { + /* skip PTI timeout event */ + if (u4TearDownSubId == TDLS_HOST_EVENT_TD_PTI_TIMEOUT) + return; + } + + prDev = wlanGetNetDev(prGlueInfo, prStaRec->ucBssIndex); + if (prDev == NULL) + return; + + if (u4TearDownSubId == TDLS_HOST_EVENT_TD_PTI_TIMEOUT) { + DBGLOG(TDLS, INFO, + "TDLS_HOST_EVENT_TD_PTI_TIMEOUT TDLS_REASON_CODE_UNSPECIFIED\n"); + u2ReasonCode = TDLS_REASON_CODE_UNSPECIFIED; + + cfg80211_tdls_oper_request(prDev, + prStaRec->aucMacAddr, + NL80211_TDLS_TEARDOWN, + WLAN_REASON_TDLS_TEARDOWN_UNREACHABLE, + GFP_ATOMIC); + } + + if (u4TearDownSubId == TDLS_HOST_EVENT_TD_AGE_TIMEOUT) { + DBGLOG(TDLS, INFO, + "TDLS_HOST_EVENT_TD_AGE_TIMEOUT TDLS_REASON_CODE_UNREACHABLE\n"); + u2ReasonCode = TDLS_REASON_CODE_UNREACHABLE; + + cfg80211_tdls_oper_request(prDev, + prStaRec->aucMacAddr, NL80211_TDLS_TEARDOWN, + WLAN_REASON_TDLS_TEARDOWN_UNREACHABLE, + GFP_ATOMIC); + + } + + DBGLOG(TDLS, INFO, "\n\n u2ReasonCode = %u\n\n", + u2ReasonCode); +} + +void TdlsBssExtCapParse(struct STA_RECORD *prStaRec, + uint8_t *pucIE) +{ + uint8_t *pucIeExtCap; + + /* sanity check */ + if ((prStaRec == NULL) || (pucIE == NULL)) + return; + + if (IE_ID(pucIE) != ELEM_ID_EXTENDED_CAP) + return; + + /* + * from bit0 ~ + * bit 38: TDLS Prohibited + * The TDLS Prohibited subfield indicates whether the use of TDLS is + * prohibited. + * The field is set to 1 to indicate that TDLS is prohibited + * and to 0 to indicate that TDLS is allowed. + */ + if (IE_LEN(pucIE) < 5) + return; /* we need 39/8 = 5 bytes */ + + /* init */ + prStaRec->fgTdlsIsProhibited = FALSE; + prStaRec->fgTdlsIsChSwProhibited = FALSE; + + /* parse */ + pucIeExtCap = pucIE + 2; + pucIeExtCap += 4; /* shift to the byte we care about */ + + if ((*pucIeExtCap) & BIT(38 - 32)) + prStaRec->fgTdlsIsProhibited = TRUE; + if ((*pucIeExtCap) & BIT(39 - 32)) + prStaRec->fgTdlsIsChSwProhibited = TRUE; + +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Generate CMD_ID_SET_TDLS_CH_SW command + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +uint32_t +TdlsSendChSwControlCmd(struct ADAPTER *prAdapter, + void *pvSetBuffer, uint32_t u4SetBufferLen, + uint32_t *pu4SetInfoLen) +{ + + struct CMD_TDLS_CH_SW rCmdTdlsChSwCtrl; + struct BSS_INFO *prBssInfo; + + prBssInfo = + GET_BSS_INFO_BY_INDEX(prAdapter, AIS_DEFAULT_INDEX); + + /* send command packet for scan */ + kalMemZero(&rCmdTdlsChSwCtrl, + sizeof(struct CMD_TDLS_CH_SW)); + + rCmdTdlsChSwCtrl.fgIsTDLSChSwProhibit = + prBssInfo->fgTdlsIsChSwProhibited; + + wlanSendSetQueryCmd(prAdapter, + CMD_ID_SET_TDLS_CH_SW, + TRUE, + FALSE, FALSE, NULL, NULL, + sizeof(struct CMD_TDLS_CH_SW), + (uint8_t *)&rCmdTdlsChSwCtrl, NULL, 0); + return TDLS_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to handle TX done for TDLS data packet. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * \param[in] rTxDoneStatus TX Done status + * + * \retval none + */ +/*----------------------------------------------------------------------------*/ +void TdlsHandleTxDoneStatus(struct ADAPTER *prAdapter, + enum ENUM_TX_RESULT_CODE rTxDoneStatus) +{ + DBGLOG(TDLS, INFO, "TdlsHandleTxDoneStatus=%d, fgIsWaitForTxDone=%d", + rTxDoneStatus, fgIsWaitForTxDone); + if (fgIsWaitForTxDone == TRUE) { + kalOidComplete(prAdapter->prGlueInfo, 0, 0, + WLAN_STATUS_SUCCESS); + fgIsWaitForTxDone = FALSE; + } +} + +#endif /* CFG_SUPPORT_TDLS */ + +/* End of tdls.c */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/tkip_mic.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/tkip_mic.c new file mode 100644 index 0000000000000000000000000000000000000000..70af23b16c4c79244d662b8c4737a2523d3f7182 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/tkip_mic.c @@ -0,0 +1,571 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: //Department/DaVinci/TRUNK/MT6620_WiFi_Firmware/ + * mcu/wifi/mgmt/tkip_mic.c#7 + */ + +/*! \file tkip_sw.c + * \brief This file include the tkip encrypted / decrypted mic function. + */ +/******************************************************************************* + * Copyright (c) 2003-2004 Inprocomm, Inc. + * + * All rights reserved. Copying, compilation, modification, distribution + * or any other use whatsoever of this material is strictly prohibited + * except in accordance with a Software License Agreement with + * Inprocomm, Inc. + ******************************************************************************* + */ + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/* length of TKIP and CCMP MIC field */ +#define WLAN_MAC_MIC_LEN 8 + +#define MK16_TKIP(x, y) (((uint16_t) (x) << 8) | (uint16_t) (y)) + +/* obtain low 8-bit from 16-bit value */ +#define LO_8BITS(x) ((x) & 0x00ff) + +/* obtain high 8-bit from 16-bit value */ +#define HI_8BITS(x) ((x) >> 8) + +#define ROTR32(x, y) (((x) >> (y)) | ((x) << (32 - (y)))) +#define ROTL32(x, y) (((x) << (y)) | ((x) >> (32 - (y)))) +#define ROTR16(x, y) (((x) >> (y)) | ((x) << (16 - (y)))) +#define ROTL16(x, y) (((x) << (y)) | ((x) >> (16 - (y)))) + +#define XSWAP32(x) ((((x) & 0xFF00FF00) >> 8) | (((x) & 0x00FF00FF) << 8)) + +/* obtain 16-bit entries SBOX form two 8-bit entries SBOX1 and SBOX2 */ +#define SBOX(x) (tkipSBOX1[LO_8BITS(x)] ^ tkipSBOX2[HI_8BITS(x)]) + + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ +const uint16_t tkipSBOX1[256] = { + 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154, + 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A, + 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B, + 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B, + 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F, + 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F, + 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5, + 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F, + 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB, + 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397, + 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED, + 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A, + 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194, + 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3, + 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104, + 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D, + 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39, + 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695, + 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83, + 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76, + 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4, + 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B, + 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0, + 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018, + 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751, + 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85, + 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12, + 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9, + 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7, + 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A, + 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8, + 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A +}; + +const uint16_t tkipSBOX2[256] = { + 0xA5C6, 0x84F8, 0x99EE, 0x8DF6, 0x0DFF, 0xBDD6, 0xB1DE, 0x5491, + 0x5060, 0x0302, 0xA9CE, 0x7D56, 0x19E7, 0x62B5, 0xE64D, 0x9AEC, + 0x458F, 0x9D1F, 0x4089, 0x87FA, 0x15EF, 0xEBB2, 0xC98E, 0x0BFB, + 0xEC41, 0x67B3, 0xFD5F, 0xEA45, 0xBF23, 0xF753, 0x96E4, 0x5B9B, + 0xC275, 0x1CE1, 0xAE3D, 0x6A4C, 0x5A6C, 0x417E, 0x02F5, 0x4F83, + 0x5C68, 0xF451, 0x34D1, 0x08F9, 0x93E2, 0x73AB, 0x5362, 0x3F2A, + 0x0C08, 0x5295, 0x6546, 0x5E9D, 0x2830, 0xA137, 0x0F0A, 0xB52F, + 0x090E, 0x3624, 0x9B1B, 0x3DDF, 0x26CD, 0x694E, 0xCD7F, 0x9FEA, + 0x1B12, 0x9E1D, 0x7458, 0x2E34, 0x2D36, 0xB2DC, 0xEEB4, 0xFB5B, + 0xF6A4, 0x4D76, 0x61B7, 0xCE7D, 0x7B52, 0x3EDD, 0x715E, 0x9713, + 0xF5A6, 0x68B9, 0x0000, 0x2CC1, 0x6040, 0x1FE3, 0xC879, 0xEDB6, + 0xBED4, 0x468D, 0xD967, 0x4B72, 0xDE94, 0xD498, 0xE8B0, 0x4A85, + 0x6BBB, 0x2AC5, 0xE54F, 0x16ED, 0xC586, 0xD79A, 0x5566, 0x9411, + 0xCF8A, 0x10E9, 0x0604, 0x81FE, 0xF0A0, 0x4478, 0xBA25, 0xE34B, + 0xF3A2, 0xFE5D, 0xC080, 0x8A05, 0xAD3F, 0xBC21, 0x4870, 0x04F1, + 0xDF63, 0xC177, 0x75AF, 0x6342, 0x3020, 0x1AE5, 0x0EFD, 0x6DBF, + 0x4C81, 0x1418, 0x3526, 0x2FC3, 0xE1BE, 0xA235, 0xCC88, 0x392E, + 0x5793, 0xF255, 0x82FC, 0x477A, 0xACC8, 0xE7BA, 0x2B32, 0x95E6, + 0xA0C0, 0x9819, 0xD19E, 0x7FA3, 0x6644, 0x7E54, 0xAB3B, 0x830B, + 0xCA8C, 0x29C7, 0xD36B, 0x3C28, 0x79A7, 0xE2BC, 0x1D16, 0x76AD, + 0x3BDB, 0x5664, 0x4E74, 0x1E14, 0xDB92, 0x0A0C, 0x6C48, 0xE4B8, + 0x5D9F, 0x6EBD, 0xEF43, 0xA6C4, 0xA839, 0xA431, 0x37D3, 0x8BF2, + 0x32D5, 0x438B, 0x596E, 0xB7DA, 0x8C01, 0x64B1, 0xD29C, 0xE049, + 0xB4D8, 0xFAAC, 0x07F3, 0x25CF, 0xAFCA, 0x8EF4, 0xE947, 0x1810, + 0xD56F, 0x88F0, 0x6F4A, 0x725C, 0x2438, 0xF157, 0xC773, 0x5197, + 0x23CB, 0x7CA1, 0x9CE8, 0x213E, 0xDD96, 0xDC61, 0x860D, 0x850F, + 0x90E0, 0x427C, 0xC471, 0xAACC, 0xD890, 0x0506, 0x01F7, 0x121C, + 0xA3C2, 0x5F6A, 0xF9AE, 0xD069, 0x9117, 0x5899, 0x273A, 0xB927, + 0x38D9, 0x13EB, 0xB32B, 0x3322, 0xBBD2, 0x70A9, 0x8907, 0xA733, + 0xB62D, 0x223C, 0x9215, 0x20C9, 0x4987, 0xFFAA, 0x7850, 0x7AA5, + 0x8F03, 0xF859, 0x8009, 0x171A, 0xDA65, 0x31D7, 0xC684, 0xB8D0, + 0xC382, 0xB029, 0x775A, 0x111E, 0xCB7B, 0xFCA8, 0xD66D, 0x3A2C +}; + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief TKIP Michael block function + * + * \param[in][out] pu4L - pointer to left value + * \param[in][out] pu4PR - pointer to right value + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void tkipMicB(IN OUT uint32_t *pu4L, IN OUT uint32_t *pu4R) +{ + *pu4R = *pu4R ^ ROTL32(*pu4L, 17); /* r <- r ^ (l<<<17) */ + *pu4L = (*pu4L + *pu4R); /* l <- (l+r) mod 2^32 */ + *pu4R = *pu4R ^ XSWAP32(*pu4L); /* r <- r ^ XSWAP(l) */ + *pu4L = (*pu4L + *pu4R); /* l <- (l+r) mod 2^32 */ + *pu4R = *pu4R ^ ROTL32(*pu4L, 3); /* r <- r ^ (l<<<3) */ + *pu4L = (*pu4L + *pu4R); /* l <- (l+r) mod 2^32 */ + *pu4R = *pu4R ^ ROTR32(*pu4L, 2); /* r <- r ^ (l>>>2) */ + *pu4L = (*pu4L + *pu4R); /* l <- (l+r) mod 2^32 */ +} /* tkipMicB */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief TKIP Michael generation function + * + * \param[in] pucMickey Pointer to MIC key + * \param[in] pucData Pointer to message + * \param[in] u4DataLen Message length, in byte(s) + * \param[in] pucSa Pointer to source address SA + * \param[in] pucDa Pointer to destination address DA + * \param[in] ucPriority Priority of IEEE 802.11 traffic class + * \param[out] pucMic Pointer to 64-bit MIC + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void +tkipMicGen(IN uint8_t *pucMickey, + IN uint8_t *pucData, + IN uint32_t u4DataLen, IN uint8_t *pucSa, IN uint8_t *pucDa, + IN uint8_t ucPriority, OUT uint8_t *pucMic) +{ + + uint32_t i; + uint32_t l, r; + uint32_t au4Msg[3]; + + WLAN_GET_FIELD_32(pucMickey, &l); + WLAN_GET_FIELD_32(pucMickey + 4, &r); + + /* Michael message processing for DA and SA. */ + WLAN_GET_FIELD_32(pucDa, &au4Msg[0]); + au4Msg[1] = ((uint32_t) pucDa[4]) | ((uint32_t) pucDa[5] << + 8) | + ((uint32_t) pucSa[0] << 16) | ((uint32_t) pucSa[1] << 24); + WLAN_GET_FIELD_32(pucSa + 2, &au4Msg[2]); + + for (i = 0; i < 3; i++) { + l = l ^ au4Msg[i]; + tkipMicB(&l, &r); + } + + /* Michael message processing for priority. */ + au4Msg[0] = (uint32_t) ucPriority; + + l = l ^ au4Msg[0]; + tkipMicB(&l, &r); + + /* Michael message processing for MSDU data playload except + * the last octets which cannot be partitioned into a 32-bit word. + */ + for (i = 0; i < (uint32_t) u4DataLen / 4; i++) { + WLAN_GET_FIELD_32(pucData + i * 4, &au4Msg[0]); + l = l ^ au4Msg[0]; + tkipMicB(&l, &r); + } + + /* Michael message processing for the last uncomplete octets, + * if present, and the padding. + */ + switch (u4DataLen & 3) { + case 1: + au4Msg[0] = ((uint32_t) pucData[u4DataLen - 1]) | + 0x00005A00; + break; + + case 2: + au4Msg[0] = ((uint32_t) pucData[u4DataLen - 2]) | (( + uint32_t) pucData[u4DataLen - 1] << 8) | 0x005A0000; + break; + + case 3: + au4Msg[0] = ((uint32_t) pucData[u4DataLen - 3]) | + ((uint32_t) pucData[u4DataLen - 2] << 8) | (( + uint32_t) pucData[u4DataLen - 1] << 16) | 0x5A000000; + break; + + default: + au4Msg[0] = 0x0000005A; + } + au4Msg[1] = 0; + for (i = 0; i < 2; i++) { + l = l ^ au4Msg[i]; + tkipMicB(&l, &r); + } + + /* return ( l, r ), i.e. MIC */ + WLAN_SET_FIELD_32(pucMic, l); + WLAN_SET_FIELD_32(pucMic + 4, r); + +} /* tkipMicGen */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief this function decapsulate MSDU frame body( with MIC ) according + * to IEEE 802.11i TKIP sepcification. + * + * \param[in] prAdapter Pointer to the adapter object data area. + * \param[in] pucDa Pointer to destination address DA + * \param[in] pucSa Pointer to source address SA + * \param[in] ucPriority Priority of IEEE 802.11 traffic class + * \param[in] pucPayload Pointer to message + * \param[in] u2PayloadLen Message length, in byte(s) + * \param[out] pucMic Pointer to 64-bit MIC + * + * \retval NONE + */ +/*----------------------------------------------------------------------------*/ +void +tkipMicEncapsulate(IN uint8_t *pucDa, + IN uint8_t *pucSa, + IN uint8_t ucPriority, + IN uint16_t u2PayloadLen, IN uint8_t *pucPayload, + IN uint8_t *pucMic, IN uint8_t *pucMicKey) +{ + uint8_t aucMic[8]; /* MIC' */ + + DEBUGFUNC("tkipSwMsduEncapsulate"); + DBGLOG(RSN, LOUD, + "MIC key %02x-%02x-%02x-%02x %02x-%02x-%02x-%02x\n", + pucMicKey[0], pucMicKey[1], pucMicKey[2], pucMicKey[3], + pucMicKey[4], pucMicKey[5], pucMicKey[6], pucMicKey[7]); + + tkipMicGen(pucMicKey, (uint8_t *) pucPayload, u2PayloadLen, + pucSa, pucDa, ucPriority, aucMic); + + kalMemCopy((uint8_t *) pucMic, &aucMic[0], + WLAN_MAC_MIC_LEN); + + DBGLOG(RSN, LOUD, + "Mic %02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x\n", + pucMic[0], pucMic[1], pucMic[2], pucMic[3], pucMic[4], + pucMic[5], pucMic[6], pucMic[7]); + +} /* tkipSwMsduEncapsulate */ + +/*----------------------------------------------------------------------------*/ +u_int8_t tkipMicDecapsulate(IN struct SW_RFB *prSwRfb, + IN uint8_t *pucMicKey) +{ + uint8_t *pucMic1; /* MIC */ + uint8_t aucMic2[8]; /* MIC' */ + uint8_t ucPriority; + u_int8_t fgStatus; + uint8_t *pucSa, *pucDa; + /* PUCHAR pucMickey; */ + uint8_t *pucFrameBody; + uint16_t u2FrameBodyLen; + struct WLAN_MAC_HEADER *prMacHeader; + + DEBUGFUNC("tkipMicDecapsulate"); + + /* prRxStatus = prSwRfb->prRxStatus; */ + pucFrameBody = prSwRfb->pucPayload; + u2FrameBodyLen = prSwRfb->u2PayloadLength; + + if (!pucFrameBody) { + DBGLOG(RSN, INFO, "pucPayload is NULL, drop this packet"); + return FALSE; + } + + DBGLOG(RSN, LOUD, "Before TKIP MSDU Decapsulate:\n"); + DBGLOG(RSN, LOUD, "MIC key:\n"); + /* DBGLOG_MEM8(RSN, LOUD, pucMicKey, 8); */ + + prMacHeader = (struct WLAN_MAC_HEADER *) prSwRfb->pvHeader; + pucDa = prMacHeader->aucAddr1; + pucSa = prMacHeader->aucAddr3; + + switch (prMacHeader->u2FrameCtrl & MASK_TO_DS_FROM_DS) { + case 0: + pucDa = prMacHeader->aucAddr1; + pucSa = prMacHeader->aucAddr2; + break; + case MASK_FC_FROM_DS: + pucDa = prMacHeader->aucAddr1; + pucSa = prMacHeader->aucAddr3; + break; + default: + ASSERT((prMacHeader->u2FrameCtrl & MASK_FC_TO_DS) == 0); + return TRUE; + } + + if (RXM_IS_QOS_DATA_FRAME(prSwRfb->u2FrameCtrl)) + ucPriority = (uint8_t) ((((struct WLAN_MAC_HEADER_QOS *) + prSwRfb->pvHeader)->u2QosCtrl) & MASK_QC_TID); + else + ucPriority = 0; + + /* generate MIC' */ + tkipMicGen(pucMicKey, pucFrameBody, + u2FrameBodyLen - WLAN_MAC_MIC_LEN, pucSa, pucDa, ucPriority, + aucMic2); + + /* verify MIC and MIC' */ + pucMic1 = &pucFrameBody[u2FrameBodyLen - WLAN_MAC_MIC_LEN]; + if (pucMic1[0] == aucMic2[0] && pucMic1[1] == aucMic2[1] && + pucMic1[2] == aucMic2[2] && pucMic1[3] == aucMic2[3] && + pucMic1[4] == aucMic2[4] && pucMic1[5] == aucMic2[5] && + pucMic1[6] == aucMic2[6] && pucMic1[7] == aucMic2[7]) { + u2FrameBodyLen -= WLAN_MAC_MIC_LEN; + fgStatus = TRUE; + } else { + fgStatus = FALSE; + } + + /* DBGLOG(RSN, LOUD, ("TKIP MIC:\n")); */ + /* DBGLOG_MEM8(RSN, LOUD, pucMic1, 8); */ + /* DBGLOG(RSN, LOUD, ("TKIP MIC':\n")); */ + /* DBGLOG_MEM8(RSN, LOUD, aucMic2, 8); */ + + prSwRfb->u2PayloadLength = u2FrameBodyLen; + + DBGLOG(RSN, LOUD, "After TKIP MSDU Decapsulate:\n"); + DBGLOG(RSN, LOUD, "Frame body: (length = %u)\n", + u2FrameBodyLen); + /* DBGLOG_MEM8(RSN, LOUD, pucFrameBody, u2FrameBodyLen); */ + + return fgStatus; + +} /* tkipMicDecapsulate */ + + +/*----------------------------------------------------------------------------*/ +u_int8_t tkipMicDecapsulateInRxHdrTransMode( + IN struct SW_RFB *prSwRfb, IN uint8_t *pucMicKey) +{ + uint8_t *pucMic1; /* MIC */ + uint8_t aucMic2[8]; /* MIC' */ + u_int8_t fgStatus = FALSE; + /* PUCHAR pucMickey; */ + uint8_t *pucFrameBody; + uint16_t u2FrameBodyLen; + struct sk_buff *prSkb = NULL; +#if 0 + struct WLAN_MAC_HEADER *prMacHeader; + uint8_t *pucSa, *pucDa; + uint8_t ucPriority; + uint8_t aucDA[6]; + uint8_t aucSA[6]; + uint8_t aucType[2]; +#endif + + DEBUGFUNC("tkipMicDecapsulateInRxHdrTransMode"); + + /* prRxStatus = prSwRfb->prRxStatus; */ + pucFrameBody = prSwRfb->pucPayload; + u2FrameBodyLen = prSwRfb->u2PayloadLength; + + if (!pucFrameBody) { + DBGLOG(RSN, INFO, "pucPayload is NULL, drop this packet"); + return FALSE; + } + + DBGLOG(RSN, LOUD, "Before TKIP MSDU Decapsulate:\n"); + DBGLOG(RSN, LOUD, "MIC key:\n"); + /* DBGLOG_MEM8(RSN, LOUD, pucMicKey, 8); */ + + prSkb = dev_alloc_skb(u2FrameBodyLen + ETHERNET_HEADER_SZ * + 4); + if (prSkb) { + /* copy to etherhdr + payload to skb data */ + kalMemCopy(prSkb->data, prSwRfb->pvHeader, + u2FrameBodyLen + ETHERNET_HEADER_SZ); + *(prSkb->data + 6) = ETH_LLC_DSAP_SNAP; + *(prSkb->data + 7) = ETH_LLC_SSAP_SNAP; + *(prSkb->data + 8) = ETH_LLC_CONTROL_UNNUMBERED_INFORMATION; + *(prSkb->data + 9) = 0x00; + *(prSkb->data + 10) = 0x00; + *(prSkb->data + 11) = 0x00; + *(prSkb->data + 12) = *(uint8_t *)(prSwRfb->pvHeader + 12); + *(prSkb->data + 13) = *(uint8_t *)(prSwRfb->pvHeader + 13); + + tkipMicGen(pucMicKey, + prSkb->data + 6, + u2FrameBodyLen - WLAN_MAC_MIC_LEN + 8, + prSwRfb->pvHeader + 6, + prSwRfb->pvHeader, + prSwRfb->ucTid, aucMic2); + + if (prSkb) + kfree_skb((struct sk_buff *)prSkb); + } else { + DBGLOG(RX, ERROR, "MIC SW DEC1\n"); + return fgStatus; + } + + + /* verify MIC and MIC' */ + pucMic1 = &pucFrameBody[u2FrameBodyLen - WLAN_MAC_MIC_LEN]; + if (pucMic1[0] == aucMic2[0] && pucMic1[1] == aucMic2[1] && + pucMic1[2] == aucMic2[2] && pucMic1[3] == aucMic2[3] && + pucMic1[4] == aucMic2[4] && pucMic1[5] == aucMic2[5] && + pucMic1[6] == aucMic2[6] && pucMic1[7] == aucMic2[7]) { + u2FrameBodyLen -= WLAN_MAC_MIC_LEN; + fgStatus = TRUE; + } else { + fgStatus = FALSE; + DBGLOG(RX, ERROR, "MIC SW DEC2\n"); + } + +#if 0 + /* perform header transfer for tkip defragment frame, + * if receiving 802.11 pkt + */ + if (fgStatus == TRUE) { + /* reassign payload address */ + prSwRfb->pucPayload += (ETH_LLC_LEN + ETH_SNAP_LEN); + + /* reassign payload length */ + u2FrameBodyLen -= (ETH_LLC_LEN + ETH_SNAP_LEN); + + prSwRfb->pvHeader = prSwRfb->pucPayload - + (ETHERNET_HEADER_SZ); + + kalMemCopy(&aucDA[0], pucDa, MAC_ADDR_LEN); + kalMemCopy(&aucSA[0], pucSa, MAC_ADDR_LEN); + kalMemCopy(&aucType[0], prSwRfb->pucPayload - 2, 2); + + kalMemCopy(prSwRfb->pvHeader, &aucDA[0], MAC_ADDR_LEN); + kalMemCopy(prSwRfb->pvHeader + MAC_ADDR_LEN, &aucSA[0], + MAC_ADDR_LEN); + kalMemCopy(prSwRfb->pvHeader + MAC_ADDR_LEN + 2, + &aucType[0], 2); + + prSwRfb->u2HeaderLen = ETHERNET_HEADER_SZ; + } +#endif + + /* DBGLOG(RSN, LOUD, ("TKIP MIC:\n")); */ + /* DBGLOG_MEM8(RSN, LOUD, pucMic1, 8); */ + /* DBGLOG(RSN, LOUD, ("TKIP MIC':\n")); */ + /* DBGLOG_MEM8(RSN, LOUD, aucMic2, 8); */ + + prSwRfb->u2PayloadLength = u2FrameBodyLen; + + DBGLOG(RSN, LOUD, "After TKIP MSDU Decapsulate:\n"); + DBGLOG(RSN, LOUD, "Frame body: (length = %u)\n", + u2FrameBodyLen); + /* DBGLOG_MEM8(RSN, LOUD, pucFrameBody, u2FrameBodyLen); */ + + return fgStatus; + +} /* tkipMicDecapsulate */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/twt.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/twt.c new file mode 100644 index 0000000000000000000000000000000000000000..776a70070b05814b1db7974042e9e09fe4a01581 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/twt.c @@ -0,0 +1,597 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2017 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2017 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/*! \file "twt.c" +* \brief Functions for processing TWT related elements and frames. +*/ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include "precomp.h" + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +static void twtFillTWTElement( + struct _IE_TWT_T *prTWTBuf, + uint8_t ucTWTFlowId, + struct _TWT_PARAMS_T *prTWTParams); + +static void twtParseTWTElement( + struct _IE_TWT_T *prTWTIE, + struct _TWT_PARAMS_T *prTWTParams); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +/*----------------------------------------------------------------------------*/ +/*! +* \brief Send TWT Setup frame (S1G action frame) +* +* \param[in] prAdapter ADAPTER structure +* prStaRec station record structure +* +* \return none +*/ +/*----------------------------------------------------------------------------*/ +uint32_t twtSendSetupFrame( + struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + uint8_t ucTWTFlowId, + struct _TWT_PARAMS_T *prTWTParams, + PFN_TX_DONE_HANDLER pfTxDoneHandler) +{ + struct MSDU_INFO *prMsduInfo; + struct _ACTION_TWT_SETUP_FRAME *prTxFrame; + struct BSS_INFO *prBssInfo; + uint16_t u2EstimatedFrameLen; + struct _IE_TWT_T *prTWTBuf; + + ASSERT(prAdapter); + ASSERT(prStaRec); + ASSERT(prTWTParams); + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex); + + ASSERT(prBssInfo); + + /* Calculate MSDU buffer length */ + u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + + sizeof(struct _ACTION_TWT_SETUP_FRAME); + + /* Alloc MSDU_INFO */ + prMsduInfo = (struct MSDU_INFO *) + cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); + + if (!prMsduInfo) { + DBGLOG(TWT_REQUESTER, WARN, + "No MSDU_INFO_T for sending TWT Setup Frame.\n"); + return WLAN_STATUS_RESOURCES; + } + + kalMemZero(prMsduInfo->prPacket, u2EstimatedFrameLen); + + prTxFrame = prMsduInfo->prPacket; + + /* Fill frame ctrl */ + prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; + + COPY_MAC_ADDR(prTxFrame->aucDestAddr, prStaRec->aucMacAddr); + COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); + COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); + + /* Compose the frame body's frame */ + prTxFrame->ucCategory = CATEGORY_S1G_ACTION; + prTxFrame->ucAction = ACTION_S1G_TWT_SETUP; + + prTWTBuf = &(prTxFrame->rTWT); + twtFillTWTElement(prTWTBuf, ucTWTFlowId, prTWTParams); + + /* Update information of MSDU_INFO_T */ + TX_SET_MMPDU(prAdapter, + prMsduInfo, + prBssInfo->ucBssIndex, + prStaRec->ucIndex, + WLAN_MAC_MGMT_HEADER_LEN, + sizeof(struct _ACTION_TWT_SETUP_FRAME), + pfTxDoneHandler, MSDU_RATE_MODE_AUTO); + + /* Enqueue the frame to send this action frame */ + nicTxEnqueueMsdu(prAdapter, prMsduInfo); + + return WLAN_STATUS_SUCCESS; +} + +uint32_t twtSendTeardownFrame( + struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + uint8_t ucTWTFlowId, + PFN_TX_DONE_HANDLER pfTxDoneHandler) +{ + struct MSDU_INFO *prMsduInfo; + struct _ACTION_TWT_TEARDOWN_FRAME *prTxFrame; + struct BSS_INFO *prBssInfo; + uint16_t u2EstimatedFrameLen; + + ASSERT(prAdapter); + ASSERT(prStaRec); + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex); + + ASSERT(prBssInfo); + + /* Calculate MSDU buffer length */ + u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + + sizeof(struct _ACTION_TWT_TEARDOWN_FRAME); + + /* Alloc MSDU_INFO */ + prMsduInfo = (struct MSDU_INFO *) cnmMgtPktAlloc( + prAdapter, u2EstimatedFrameLen); + + if (!prMsduInfo) { + DBGLOG(TWT_REQUESTER, WARN, + "No MSDU_INFO_T for sending TWT Teardown Frame.\n"); + return WLAN_STATUS_RESOURCES; + } + + kalMemZero(prMsduInfo->prPacket, u2EstimatedFrameLen); + + prTxFrame = prMsduInfo->prPacket; + + /* Fill frame ctrl */ + prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; + + COPY_MAC_ADDR(prTxFrame->aucDestAddr, prStaRec->aucMacAddr); + COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); + COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); + + /* Compose the frame body's frame */ + prTxFrame->ucCategory = CATEGORY_S1G_ACTION; + prTxFrame->ucAction = ACTION_S1G_TWT_TEARDOWN; + prTxFrame->ucTWTFlow = ucTWTFlowId; + + /* Update information of MSDU_INFO_T */ + TX_SET_MMPDU(prAdapter, + prMsduInfo, + prBssInfo->ucBssIndex, + prStaRec->ucIndex, + WLAN_MAC_MGMT_HEADER_LEN, + sizeof(struct _ACTION_TWT_TEARDOWN_FRAME), + pfTxDoneHandler, MSDU_RATE_MODE_AUTO); + + /* Enqueue the frame to send this action frame */ + nicTxEnqueueMsdu(prAdapter, prMsduInfo); + + return WLAN_STATUS_SUCCESS; +} + +uint32_t twtSendInfoFrame( + struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + uint8_t ucTWTFlowId, + struct _NEXT_TWT_INFO_T *prNextTWTInfo, + PFN_TX_DONE_HANDLER pfTxDoneHandler) +{ + struct MSDU_INFO *prMsduInfo; + struct _ACTION_TWT_INFO_FRAME *prTxFrame; + uint32_t u4Pos = + OFFSET_OF(struct _ACTION_TWT_INFO_FRAME, aucNextTWT[0]); + struct BSS_INFO *prBssInfo; + uint16_t u2EstimatedFrameLen; + + ASSERT(prAdapter); + ASSERT(prStaRec); + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex); + + ASSERT(prBssInfo); + + /* Calculate MSDU buffer length */ + u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + + sizeof(struct _ACTION_TWT_INFO_FRAME) + + twtGetNextTWTByteCnt(prNextTWTInfo->ucNextTWTSize); + + /* Alloc MSDU_INFO */ + prMsduInfo = (struct MSDU_INFO *) cnmMgtPktAlloc( + prAdapter, u2EstimatedFrameLen); + + if (!prMsduInfo) { + DBGLOG(TWT_REQUESTER, WARN, + "No MSDU_INFO_T for sending TWT Info Frame.\n"); + return WLAN_STATUS_RESOURCES; + } + + kalMemZero(prMsduInfo->prPacket, u2EstimatedFrameLen); + + prTxFrame = prMsduInfo->prPacket; + + /* Fill frame ctrl */ + prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; + + COPY_MAC_ADDR(prTxFrame->aucDestAddr, prStaRec->aucMacAddr); + COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); + COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); + + /* Compose the frame body's frame */ + prTxFrame->ucCategory = CATEGORY_S1G_ACTION; + prTxFrame->ucAction = ACTION_S1G_TWT_INFORMATION; + prTxFrame->ucNextTWTCtrl = (ucTWTFlowId & TWT_INFO_FLOW_ID) | + ((prNextTWTInfo->ucNextTWTSize & TWT_INFO_NEXT_TWT_SIZE) << + TWT_INFO_NEXT_TWT_SIZE_OFFSET); + + switch (prNextTWTInfo->ucNextTWTSize) { + case NEXT_TWT_SUBFIELD_64_BITS: + { + uint64_t *pu8NextTWT = + (uint64_t *)(((uint8_t *)prTxFrame) + u4Pos); + *pu8NextTWT = CPU_TO_LE64(prNextTWTInfo->u8NextTWT); + break; + } + + case NEXT_TWT_SUBFIELD_32_BITS: + { + uint32_t *pu4NextTWT = + (uint32_t *)(((uint8_t *)prTxFrame) + u4Pos); + *pu4NextTWT = CPU_TO_LE32( + (uint32_t)(prNextTWTInfo->u8NextTWT & 0xFFFFFFFF)); + break; + } + + case NEXT_TWT_SUBFIELD_48_BITS: + { + uint8_t *pucMem = ((uint8_t *)prTxFrame) + u4Pos; + /* little endian placement */ + *pucMem = prNextTWTInfo->u8NextTWT & 0xFF; + *(pucMem + 1) = (prNextTWTInfo->u8NextTWT >> 8) & 0xFF; + *(pucMem + 2) = (prNextTWTInfo->u8NextTWT >> 16) & 0xFF; + *(pucMem + 3) = (prNextTWTInfo->u8NextTWT >> 24) & 0xFF; + *(pucMem + 4) = (prNextTWTInfo->u8NextTWT >> 32) & 0xFF; + *(pucMem + 5) = (prNextTWTInfo->u8NextTWT >> 40) & 0xFF; + break; + } + + default: + break; + } + + /* Update information of MSDU_INFO_T */ + TX_SET_MMPDU(prAdapter, + prMsduInfo, + prBssInfo->ucBssIndex, + prStaRec->ucIndex, + WLAN_MAC_MGMT_HEADER_LEN, + (sizeof(struct _ACTION_TWT_INFO_FRAME) + + prNextTWTInfo->ucNextTWTSize), + pfTxDoneHandler, MSDU_RATE_MODE_AUTO); + + /* Enqueue the frame to send this action frame */ + nicTxEnqueueMsdu(prAdapter, prMsduInfo); + + return WLAN_STATUS_SUCCESS; +} + +static void twtFillTWTElement( + struct _IE_TWT_T *prTWTBuf, + uint8_t ucTWTFlowId, + struct _TWT_PARAMS_T *prTWTParams) +{ + ASSERT(prTWTBuf); + ASSERT(prTWTParams); + + /* Add TWT element */ + prTWTBuf->ucId = ELEM_ID_TWT; + prTWTBuf->ucLength = sizeof(struct _IE_TWT_T) - ELEM_HDR_LEN; + + /* Request Type */ + prTWTBuf->u2ReqType |= SET_TWT_RT_REQUEST(prTWTParams->fgReq) | + SET_TWT_RT_SETUP_CMD(prTWTParams->ucSetupCmd) | + SET_TWT_RT_TRIGGER(prTWTParams->fgTrigger) | + TWT_REQ_TYPE_IMPLICIT_LAST_BCAST_PARAM | + SET_TWT_RT_FLOW_TYPE(prTWTParams->fgUnannounced) | + SET_TWT_RT_FLOW_ID(ucTWTFlowId) | + SET_TWT_RT_WAKE_INTVAL_EXP(prTWTParams->ucWakeIntvalExponent) | + SET_TWT_RT_PROTECTION(prTWTParams->fgProtect); + + prTWTBuf->u8TWT = CPU_TO_LE64(prTWTParams->u8TWT); + prTWTBuf->ucMinWakeDur = prTWTParams->ucMinWakeDur; + prTWTBuf->u2WakeIntvalMantiss = + CPU_TO_LE16(prTWTParams->u2WakeIntvalMantiss); +} + +static void twtParseTWTElement( + struct _IE_TWT_T *prTWTIE, + struct _TWT_PARAMS_T *prTWTParams) +{ + uint16_t u2ReqType; + + u2ReqType = LE16_TO_CPU(prTWTIE->u2ReqType); + + prTWTParams->fgReq = GET_TWT_RT_REQUEST(u2ReqType); + prTWTParams->ucSetupCmd = GET_TWT_RT_SETUP_CMD(u2ReqType); + prTWTParams->fgTrigger = GET_TWT_RT_TRIGGER(u2ReqType); + prTWTParams->fgUnannounced = GET_TWT_RT_FLOW_TYPE(u2ReqType); + + prTWTParams->ucWakeIntvalExponent = + GET_TWT_RT_WAKE_INTVAL_EXP(u2ReqType); + + prTWTParams->fgProtect = GET_TWT_RT_PROTECTION(u2ReqType); + prTWTParams->u8TWT = LE64_TO_CPU(prTWTIE->u8TWT); + prTWTParams->ucMinWakeDur = prTWTIE->ucMinWakeDur; + + prTWTParams->u2WakeIntvalMantiss = + LE16_TO_CPU(prTWTIE->u2WakeIntvalMantiss); +} + +uint8_t twtGetTxSetupFlowId( + struct MSDU_INFO *prMsduInfo) +{ + uint8_t ucFlowId; + struct _ACTION_TWT_SETUP_FRAME *prTxFrame; + + ASSERT(prMsduInfo); + + prTxFrame = (struct _ACTION_TWT_SETUP_FRAME *)(prMsduInfo->prPacket); + ucFlowId = GET_TWT_RT_FLOW_ID(prTxFrame->rTWT.u2ReqType); + + return ucFlowId; +} + +uint8_t twtGetTxTeardownFlowId( + struct MSDU_INFO *prMsduInfo) +{ + uint8_t ucFlowId; + struct _ACTION_TWT_TEARDOWN_FRAME *prTxFrame; + + ASSERT(prMsduInfo); + + prTxFrame = (struct _ACTION_TWT_TEARDOWN_FRAME *)(prMsduInfo->prPacket); + ucFlowId = (prTxFrame->ucTWTFlow & TWT_TEARDOWN_FLOW_ID); + + return ucFlowId; +} + +uint8_t twtGetTxInfoFlowId( + struct MSDU_INFO *prMsduInfo) +{ + uint8_t ucFlowId; + struct _ACTION_TWT_INFO_FRAME *prTxFrame; + + ASSERT(prMsduInfo); + + prTxFrame = (struct _ACTION_TWT_INFO_FRAME *)(prMsduInfo->prPacket); + ucFlowId = GET_TWT_INFO_FLOW_ID(prTxFrame->ucNextTWTCtrl); + + return ucFlowId; +} + +uint8_t twtGetRxSetupFlowId( + struct _IE_TWT_T *prTWTIE) +{ + uint16_t u2ReqType; + + ASSERT(prTWTIE); + + u2ReqType = LE16_TO_CPU(prTWTIE->u2ReqType); + + return GET_TWT_RT_FLOW_ID(u2ReqType); +} + +void twtProcessS1GAction( + struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb) +{ + struct WLAN_ACTION_FRAME *prRxFrame; + struct _ACTION_TWT_SETUP_FRAME *prRxSetupFrame = NULL; + struct _ACTION_TWT_TEARDOWN_FRAME *prRxTeardownFrame = NULL; + struct _ACTION_TWT_INFO_FRAME *prRxInfoFrame = NULL; + struct STA_RECORD *prStaRec; + struct RX_DESC_OPS_T *prRxDescOps; + + uint8_t ucTWTFlowId; + uint32_t u4Offset; + uint16_t u2ReqType; + + ASSERT(prAdapter); + ASSERT(prSwRfb); + + prRxDescOps = prAdapter->chip_info->prRxDescOps; + ASSERT(prRxDescOps->nic_rxd_get_rx_byte_count); + ASSERT(prRxDescOps->nic_rxd_get_pkt_type); + ASSERT(prRxDescOps->nic_rxd_get_wlan_idx); + + prRxFrame = (struct WLAN_ACTION_FRAME *) prSwRfb->pvHeader; + prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); + if (!prStaRec) { + DBGLOG(TWT_REQUESTER, WARN, + "Received an S1G Action: wlanIdx[%d] w/o corresponding staRec\n" + , prRxDescOps->nic_rxd_get_wlan_idx(prSwRfb->prRxStatus)); + return; + } + + switch (prRxFrame->ucAction) { + case ACTION_S1G_TWT_SETUP: + prRxSetupFrame = + (struct _ACTION_TWT_SETUP_FRAME *) prSwRfb->pvHeader; + if (prStaRec->ucStaState != STA_STATE_3 || + prSwRfb->u2PacketLen < + sizeof(struct _ACTION_TWT_SETUP_FRAME)) { + DBGLOG(TWT_REQUESTER, WARN, + "Received improper TWT Setup frame\n"); + return; + } + + /* Parse TWT element */ + ucTWTFlowId = twtGetRxSetupFlowId(&(prRxSetupFrame->rTWT)); + twtParseTWTElement(&(prRxSetupFrame->rTWT), + &(prStaRec->arTWTFlow[ucTWTFlowId].rTWTPeerParams)); + + /* Notify TWT Requester FSM upon reception of a TWT response */ + u2ReqType = prRxSetupFrame->rTWT.u2ReqType; + if (!(u2ReqType & TWT_REQ_TYPE_TWT_REQUEST)) { + twtReqFsmRunEventRxSetup(prAdapter, + prSwRfb, prStaRec, ucTWTFlowId); + } + + break; + + case ACTION_S1G_TWT_TEARDOWN: + prRxTeardownFrame = (struct _ACTION_TWT_TEARDOWN_FRAME *) + prSwRfb->pvHeader; + if (prStaRec->ucStaState != STA_STATE_3 || + prSwRfb->u2PacketLen < + sizeof(struct _ACTION_TWT_TEARDOWN_FRAME)) { + DBGLOG(TWT_REQUESTER, WARN, + "Received improper TWT Teardown frame\n"); + return; + } + + ucTWTFlowId = prRxTeardownFrame->ucTWTFlow; + + /* Notify TWT Requester FSM */ + twtReqFsmRunEventRxTeardown( + prAdapter, prSwRfb, prStaRec, ucTWTFlowId); + + break; + + case ACTION_S1G_TWT_INFORMATION: + { + uint8_t ucNextTWTSize = 0; + uint8_t *pucMem; + struct _NEXT_TWT_INFO_T rNextTWTInfo; + + prRxInfoFrame = (struct _ACTION_TWT_INFO_FRAME *) + prSwRfb->pvHeader; + if (prStaRec->ucStaState != STA_STATE_3 || + prSwRfb->u2PacketLen < + sizeof(struct _ACTION_TWT_INFO_FRAME)) { + DBGLOG(TWT_REQUESTER, WARN, + "Received improper TWT Info frame\n"); + return; + } + + ucTWTFlowId = GET_TWT_INFO_FLOW_ID( + prRxInfoFrame->ucNextTWTCtrl); + ucNextTWTSize = GET_TWT_INFO_NEXT_TWT_SIZE( + prRxInfoFrame->ucNextTWTCtrl); + + u4Offset = OFFSET_OF(struct _ACTION_TWT_INFO_FRAME, + aucNextTWT[0]); + pucMem = ((uint8_t *)prRxInfoFrame) + u4Offset; + + if (ucNextTWTSize == NEXT_TWT_SUBFIELD_64_BITS && + prSwRfb->u2PacketLen >= + (sizeof(struct _ACTION_TWT_INFO_FRAME) + 8)) { + rNextTWTInfo.u8NextTWT = + LE64_TO_CPU(*((uint64_t *)pucMem)); + } else if (ucNextTWTSize == NEXT_TWT_SUBFIELD_32_BITS && + prSwRfb->u2PacketLen >= + (sizeof(struct _ACTION_TWT_INFO_FRAME) + 4)) { + rNextTWTInfo.u8NextTWT = + LE32_TO_CPU(*((uint32_t *)pucMem)); + } else if (ucNextTWTSize == NEXT_TWT_SUBFIELD_48_BITS && + prSwRfb->u2PacketLen >= + (sizeof(struct _ACTION_TWT_INFO_FRAME) + 6)) { + rNextTWTInfo.u8NextTWT = + GET_48_BITS_NEXT_TWT_FROM_PKT(pucMem); + } else { + DBGLOG(TWT_REQUESTER, WARN, + "TWT Info frame with imcorrect size\n"); + return; + } + + rNextTWTInfo.ucNextTWTSize = ucNextTWTSize; + + /* Notify TWT Requester FSM */ + twtReqFsmRunEventRxInfoFrm( + prAdapter, prSwRfb, prStaRec, ucTWTFlowId, + &rNextTWTInfo); + + break; + } + default: + break; + } +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/twt_planner.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/twt_planner.c new file mode 100644 index 0000000000000000000000000000000000000000..7d94519a897ecf59f50323dc2c97ad6c21f4623e --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/twt_planner.c @@ -0,0 +1,1419 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2017 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2017 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/*! \file "twt_planner.c" +* \brief TWT Planner to determine TWT negotiation policy +*/ + + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include "precomp.h" + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +static uint32_t +_twtPlannerDrvAgrtAdd(struct _TWT_PLANNER_T *prTWTPlanner, + uint8_t ucBssIdx, uint8_t ucFlowId, + struct _TWT_PARAMS_T *prTWTParams, uint8_t ucIdx) +{ + struct _TWT_AGRT_T *prTWTAgrt = &(prTWTPlanner->arTWTAgrtTbl[ucIdx]); + + prTWTAgrt->fgValid = TRUE; + prTWTAgrt->ucBssIdx = ucBssIdx; + prTWTAgrt->ucFlowId = ucFlowId; + prTWTAgrt->ucAgrtTblIdx = ucIdx; + kalMemCopy(&(prTWTAgrt->rTWTAgrt), prTWTParams, + sizeof(struct _TWT_PARAMS_T)); + + return WLAN_STATUS_SUCCESS; +} + +static uint32_t +_twtPlannerDrvAgrtDel( + struct _TWT_PLANNER_T *prTWTPlanner, uint8_t ucIdx) +{ + struct _TWT_AGRT_T *prTWTAgrt = &(prTWTPlanner->arTWTAgrtTbl[ucIdx]); + + kalMemSet(prTWTAgrt, 0, sizeof(struct _TWT_AGRT_T)); + + return WLAN_STATUS_SUCCESS; +} + +static uint32_t +_twtPlannerDrvAgrtModify( + struct _TWT_PLANNER_T *prTWTPlanner, + struct _NEXT_TWT_INFO_T *prNextTWTInfo, + uint64_t u8CurTsf, uint8_t ucIdx, + struct _TWT_PARAMS_T *prTWTParams) +{ + struct _TWT_AGRT_T *prTWTAgrt = &(prTWTPlanner->arTWTAgrtTbl[ucIdx]); + + if (!prNextTWTInfo || !prTWTParams) + return WLAN_STATUS_FAILURE; + + if (prNextTWTInfo->ucNextTWTSize == NEXT_TWT_SUBFIELD_64_BITS) { + prTWTAgrt->rTWTAgrt.u8TWT = prNextTWTInfo->u8NextTWT; + } else if (prNextTWTInfo->ucNextTWTSize == NEXT_TWT_SUBFIELD_32_BITS) { + prTWTAgrt->rTWTAgrt.u8TWT = + ((u8CurTsf & ((uint64_t)0xFFFFFFFF << 32)) | + prNextTWTInfo->u8NextTWT); + } else if (prNextTWTInfo->ucNextTWTSize == NEXT_TWT_SUBFIELD_48_BITS) { + prTWTAgrt->rTWTAgrt.u8TWT = + ((u8CurTsf & ((uint64_t)0xFFFF << 48)) | + prNextTWTInfo->u8NextTWT); + } else { + /* Zero bit Next TWT is not acceptable */ + return WLAN_STATUS_FAILURE; + } + + kalMemCopy(prTWTParams, &(prTWTAgrt->rTWTAgrt), + sizeof(struct _TWT_PARAMS_T)); + + return WLAN_STATUS_SUCCESS; +} + +static uint32_t +_twtPlannerDrvAgrtGet( + struct _TWT_PLANNER_T *prTWTPlanner, + uint8_t ucIdx, struct _TWT_PARAMS_T *prTWTParams) +{ + struct _TWT_AGRT_T *prTWTAgrt = &(prTWTPlanner->arTWTAgrtTbl[ucIdx]); + + if (!prTWTParams) + return WLAN_STATUS_FAILURE; + + kalMemCopy(prTWTParams, &(prTWTAgrt->rTWTAgrt), + sizeof(struct _TWT_PARAMS_T)); + + return WLAN_STATUS_SUCCESS; +} + +static uint8_t +twtPlannerDrvAgrtFind(struct ADAPTER *prAdapter, uint8_t ucBssIdx, + uint8_t ucFlowId) +{ + uint8_t i; + struct _TWT_PLANNER_T *prTWTPlanner = &(prAdapter->rTWTPlanner); + struct _TWT_AGRT_T *prTWTAgrt = &(prTWTPlanner->arTWTAgrtTbl[0]); + + for (i = 0; i < TWT_AGRT_MAX_NUM; i++, prTWTAgrt++) { + if (prTWTAgrt->fgValid == TRUE && + prTWTAgrt->ucFlowId == ucFlowId && + prTWTAgrt->ucBssIdx == ucBssIdx) + break; + } + + return i; +} + +uint32_t +twtPlannerDrvAgrtAdd(struct ADAPTER *prAdapter, + uint8_t ucBssIdx, uint8_t ucFlowId, + struct _TWT_PARAMS_T *prTWTParams, uint8_t *pucIdx) +{ + uint8_t ucIdx; + uint32_t rStatus = WLAN_STATUS_FAILURE; + struct _TWT_PLANNER_T *prTWTPlanner = &(prAdapter->rTWTPlanner); + struct _TWT_AGRT_T *prTWTAgrt = &(prTWTPlanner->arTWTAgrtTbl[0]); + + for (ucIdx = 0; ucIdx < TWT_AGRT_MAX_NUM; ucIdx++, prTWTAgrt++) { + if (prTWTAgrt->fgValid == FALSE) + break; + } + + if (ucIdx < TWT_AGRT_MAX_NUM) { + _twtPlannerDrvAgrtAdd(prTWTPlanner, ucBssIdx, + ucFlowId, prTWTParams, ucIdx); + *pucIdx = ucIdx; + rStatus = WLAN_STATUS_SUCCESS; + } + + return rStatus; +} + +uint32_t +twtPlannerDrvAgrtModify( + struct ADAPTER *prAdapter, + uint8_t ucBssIdx, uint8_t ucFlowId, + struct _NEXT_TWT_INFO_T *prNextTWTInfo, + uint8_t *pucIdx, struct _TWT_PARAMS_T *prTWTParams) +{ + uint8_t ucIdx; + uint64_t u8CurTsf; + struct _TWT_PLANNER_T *prTWTPlanner = &(prAdapter->rTWTPlanner); + uint32_t rStatus; + + ucIdx = twtPlannerDrvAgrtFind(prAdapter, ucBssIdx, ucFlowId); + if (ucIdx >= TWT_AGRT_MAX_NUM) { + DBGLOG(TWT_PLANNER, ERROR, "Can't find agrt bss %u flow %u\n", + ucBssIdx, ucFlowId); + return WLAN_STATUS_FAILURE; + } + + /* TODO: get current TSF from FW */ + u8CurTsf = 0; + + rStatus = _twtPlannerDrvAgrtModify(prTWTPlanner, prNextTWTInfo, + u8CurTsf, ucIdx, prTWTParams); + if (rStatus == WLAN_STATUS_SUCCESS) + *pucIdx = ucIdx; + + return rStatus; +} + +uint32_t +twtPlannerDrvAgrtGet(struct ADAPTER *prAdapter, + uint8_t ucBssIdx, uint8_t ucFlowId, + uint8_t *pucIdx, struct _TWT_PARAMS_T *prTWTParams) +{ + uint8_t ucIdx; + struct _TWT_PLANNER_T *prTWTPlanner = &(prAdapter->rTWTPlanner); + uint32_t rStatus; + + ucIdx = twtPlannerDrvAgrtFind(prAdapter, ucBssIdx, ucFlowId); + if (ucIdx >= TWT_AGRT_MAX_NUM) { + DBGLOG(TWT_PLANNER, ERROR, "Can't find agrt bss %u flow %u\n", + ucBssIdx, ucFlowId); + return WLAN_STATUS_FAILURE; + } + + rStatus = _twtPlannerDrvAgrtGet(prTWTPlanner, ucIdx, prTWTParams); + if (rStatus == WLAN_STATUS_SUCCESS) + *pucIdx = ucIdx; + + return rStatus; +} + +bool +twtPlannerIsDrvAgrtExisting(struct ADAPTER *prAdapter) +{ + bool ret = FALSE; + uint8_t i; + struct _TWT_PLANNER_T *prTWTPlanner = &(prAdapter->rTWTPlanner); + struct _TWT_AGRT_T *prTWTAgrt = &(prTWTPlanner->arTWTAgrtTbl[0]); + + for (i = 0; i < TWT_AGRT_MAX_NUM; i++, prTWTAgrt++) { + if (prTWTAgrt->fgValid == TRUE) { + ret = TRUE; + break; + } + } + + return ret; +} + +void twtPlannerInit(IN struct _TWT_PLANNER_T *pTWTPlanner) +{ + ASSERT(pTWTPlanner); + + kalMemSet(&(pTWTPlanner->arTWTAgrtTbl[0]), 0, + TWT_AGRT_MAX_NUM * sizeof(struct _TWT_AGRT_T)); +} + +static struct _TWT_FLOW_T *twtPlannerFlowFindById( + struct STA_RECORD *prStaRec, uint8_t ucFlowId) +{ + struct _TWT_FLOW_T *prTWTFlow = NULL; + + ASSERT(prStaRec); + + if (ucFlowId >= TWT_MAX_FLOW_NUM) { + DBGLOG(TWT_PLANNER, ERROR, "Invalid TWT flow id %u\n", + ucFlowId); + return NULL; + } + + prTWTFlow = &(prStaRec->arTWTFlow[ucFlowId]); + + return prTWTFlow; +} + +static uint32_t +twtPlannerSendReqStart( + struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + uint8_t ucTWTFlowId) +{ + struct _MSG_TWT_REQFSM_START_T *prTWTReqFsmStartMsg; + + prTWTReqFsmStartMsg = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, + sizeof(struct _MSG_TWT_REQFSM_START_T)); + if (prTWTReqFsmStartMsg) { + prTWTReqFsmStartMsg->rMsgHdr.eMsgId = MID_TWT_REQ_FSM_START; + prTWTReqFsmStartMsg->prStaRec = prStaRec; + prTWTReqFsmStartMsg->ucTWTFlowId = ucTWTFlowId; + + mboxSendMsg(prAdapter, + MBOX_ID_0, + (struct MSG_HDR *) prTWTReqFsmStartMsg, + MSG_SEND_METHOD_BUF); + } else + return WLAN_STATUS_RESOURCES; + + return WLAN_STATUS_SUCCESS; +} + +static uint32_t +twtPlannerSendReqTeardown(struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + uint8_t ucTWTFlowId) +{ + struct _MSG_TWT_REQFSM_TEARDOWN_T *prTWTReqFsmTeardownMsg; + + prTWTReqFsmTeardownMsg = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, + sizeof(struct _MSG_TWT_REQFSM_TEARDOWN_T)); + if (prTWTReqFsmTeardownMsg) { + prTWTReqFsmTeardownMsg->rMsgHdr.eMsgId = + MID_TWT_REQ_FSM_TEARDOWN; + prTWTReqFsmTeardownMsg->prStaRec = prStaRec; + prTWTReqFsmTeardownMsg->ucTWTFlowId = ucTWTFlowId; + + mboxSendMsg(prAdapter, MBOX_ID_0, + (struct MSG_HDR *) prTWTReqFsmTeardownMsg, + MSG_SEND_METHOD_BUF); + } else + return WLAN_STATUS_RESOURCES; + + return WLAN_STATUS_SUCCESS; +} + +static uint32_t +twtPlannerSendReqSuspend(struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + uint8_t ucTWTFlowId) +{ + struct _MSG_TWT_REQFSM_SUSPEND_T *prTWTReqFsmSuspendMsg; + + prTWTReqFsmSuspendMsg = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, + sizeof(struct _MSG_TWT_REQFSM_SUSPEND_T)); + if (prTWTReqFsmSuspendMsg) { + prTWTReqFsmSuspendMsg->rMsgHdr.eMsgId = + MID_TWT_REQ_FSM_SUSPEND; + prTWTReqFsmSuspendMsg->prStaRec = prStaRec; + prTWTReqFsmSuspendMsg->ucTWTFlowId = ucTWTFlowId; + + mboxSendMsg(prAdapter, MBOX_ID_0, + (struct MSG_HDR *) prTWTReqFsmSuspendMsg, + MSG_SEND_METHOD_BUF); + } else + return WLAN_STATUS_RESOURCES; + + return WLAN_STATUS_SUCCESS; +} + +static uint32_t +twtPlannerSendReqResume(struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + uint8_t ucTWTFlowId, + uint64_t u8NextTWT, + uint8_t ucNextTWTSize) +{ + struct _MSG_TWT_REQFSM_RESUME_T *prTWTReqFsmResumeMsg; + + prTWTReqFsmResumeMsg = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, + sizeof(struct _MSG_TWT_REQFSM_RESUME_T)); + if (prTWTReqFsmResumeMsg) { + prTWTReqFsmResumeMsg->rMsgHdr.eMsgId = + MID_TWT_REQ_FSM_RESUME; + prTWTReqFsmResumeMsg->prStaRec = prStaRec; + prTWTReqFsmResumeMsg->ucTWTFlowId = ucTWTFlowId; + prTWTReqFsmResumeMsg->u8NextTWT = u8NextTWT; + prTWTReqFsmResumeMsg->ucNextTWTSize = ucNextTWTSize; + + mboxSendMsg(prAdapter, MBOX_ID_0, + (struct MSG_HDR *) prTWTReqFsmResumeMsg, + MSG_SEND_METHOD_BUF); + } else + return WLAN_STATUS_RESOURCES; + + return WLAN_STATUS_SUCCESS; +} + +static uint32_t +twtPlannerAddAgrtTbl( + struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, + struct STA_RECORD *prStaRec, + struct _TWT_PARAMS_T *prTWTParams, + uint8_t ucFlowId, + uint8_t fgIsOid, + PFN_CMD_DONE_HANDLER pfCmdDoneHandler, + PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler) +{ + uint8_t ucAgrtTblIdx; + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + struct _EXT_CMD_TWT_ARGT_UPDATE_T *prTWTAgrtUpdate; + + if (prBssInfo == NULL) { + DBGLOG(TWT_PLANNER, ERROR, "No bssinfo to add agrt\n"); + return WLAN_STATUS_INVALID_DATA; + } + + rWlanStatus = twtPlannerDrvAgrtAdd(prAdapter, prBssInfo->ucBssIndex, + ucFlowId, prTWTParams, &ucAgrtTblIdx); + if (rWlanStatus) { + DBGLOG(TWT_PLANNER, ERROR, + "Agreement table is full\n"); + return WLAN_STATUS_FAILURE; + } + + prTWTAgrtUpdate = cnmMemAlloc( + prAdapter, + RAM_TYPE_MSG, + sizeof(struct _EXT_CMD_TWT_ARGT_UPDATE_T)); + if (!prTWTAgrtUpdate) { + DBGLOG( + TWT_PLANNER, + ERROR, + "Allocate _EXT_CMD_TWT_ARGT_UPDATE_T ==> FAILED.\n"); + return WLAN_STATUS_FAILURE; + } + + prTWTAgrtUpdate->ucAgrtTblIdx = ucAgrtTblIdx; + prTWTAgrtUpdate->ucAgrtCtrlFlag = TWT_AGRT_CTRL_ADD; + prTWTAgrtUpdate->ucOwnMacId = + (prBssInfo) ? prBssInfo->ucOwnMacIndex : 0; + prTWTAgrtUpdate->ucFlowId = ucFlowId; + prTWTAgrtUpdate->u2PeerIdGrpId = + (prStaRec) ? CPU_TO_LE16(prStaRec->ucWlanIndex) : 1; + prTWTAgrtUpdate->ucAgrtSpDuration = prTWTParams->ucMinWakeDur; + prTWTAgrtUpdate->ucBssIndex = prBssInfo ? prBssInfo->ucBssIndex : 0; + prTWTAgrtUpdate->u4AgrtSpStartTsfLow = + CPU_TO_LE32(prTWTParams->u8TWT & 0xFFFFFFFF); + prTWTAgrtUpdate->u4AgrtSpStartTsfHigh = + CPU_TO_LE32((uint32_t)(prTWTParams->u8TWT >> 32)); + prTWTAgrtUpdate->u2AgrtSpWakeIntvlMantissa = + CPU_TO_LE16(prTWTParams->u2WakeIntvalMantiss); + prTWTAgrtUpdate->ucAgrtSpWakeIntvlExponent = + prTWTParams->ucWakeIntvalExponent; + prTWTAgrtUpdate->ucIsRoleAp = 0; /* STA role */ + + prTWTAgrtUpdate->ucAgrtParaBitmap = + ((prTWTParams->fgProtect << TWT_AGRT_PARA_BITMAP_PROTECT_OFFSET) | + ((!prTWTParams->fgUnannounced) << TWT_AGRT_PARA_BITMAP_ANNCE_OFFSET) | + (prTWTParams->fgTrigger << TWT_AGRT_PARA_BITMAP_TRIGGER_OFFSET)); + + prTWTAgrtUpdate->ucGrpMemberCnt = 0; + + rWlanStatus = wlanSendSetQueryExtCmd(prAdapter, + CMD_ID_LAYER_0_EXT_MAGIC_NUM, + EXT_CMD_ID_TWT_AGRT_UPDATE, + TRUE, + TRUE, + fgIsOid, + pfCmdDoneHandler, + pfCmdTimeoutHandler, + sizeof(struct _EXT_CMD_TWT_ARGT_UPDATE_T), + (uint8_t *) (prTWTAgrtUpdate), + NULL, 0); + +#if (CFG_TWT_SMART_STA == 1) + if (g_TwtSmartStaCtrl.fgTwtSmartStaReq == TRUE) { + g_TwtSmartStaCtrl.fgTwtSmartStaActivated = TRUE; + g_TwtSmartStaCtrl.ucFlowId = ucFlowId; + g_TwtSmartStaCtrl.ucBssIndex + = prBssInfo ? prBssInfo->ucBssIndex : 0; + g_TwtSmartStaCtrl.eState + = TWT_SMART_STA_STATE_SUCCESS; + } +#endif + + + return rWlanStatus; +} + +static uint32_t +twtPlannerResumeAgrtTbl(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, struct STA_RECORD *prStaRec, + uint8_t ucFlowId, uint8_t fgIsOid, + PFN_CMD_DONE_HANDLER pfCmdDoneHandler, + PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler) +{ + uint8_t ucAgrtTblIdx; + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + struct _EXT_CMD_TWT_ARGT_UPDATE_T *prTWTAgrtUpdate; + struct _TWT_PARAMS_T rTWTParams; + + if (prBssInfo == NULL) { + DBGLOG(TWT_PLANNER, ERROR, "No bssinfo to resume agrt\n"); + return WLAN_STATUS_INVALID_DATA; + } + + rWlanStatus = twtPlannerDrvAgrtGet(prAdapter, prBssInfo->ucBssIndex, + ucFlowId, &ucAgrtTblIdx, &rTWTParams); + if (rWlanStatus) { + DBGLOG(TWT_PLANNER, ERROR, "No agrt to resume Bss %u flow %u\n", + prBssInfo->ucBssIndex, ucFlowId); + return WLAN_STATUS_FAILURE; + } + + prTWTAgrtUpdate = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, + sizeof(struct _EXT_CMD_TWT_ARGT_UPDATE_T)); + if (!prTWTAgrtUpdate) { + DBGLOG(TWT_PLANNER, ERROR, + "Allocate _EXT_CMD_TWT_ARGT_UPDATE_T ==> FAILED.\n"); + return WLAN_STATUS_FAILURE; + } + + prTWTAgrtUpdate->ucAgrtTblIdx = ucAgrtTblIdx; + prTWTAgrtUpdate->ucAgrtCtrlFlag = TWT_AGRT_CTRL_ADD; + prTWTAgrtUpdate->ucOwnMacId = (prBssInfo) ? + prBssInfo->ucOwnMacIndex : 0; + prTWTAgrtUpdate->ucFlowId = ucFlowId; + prTWTAgrtUpdate->u2PeerIdGrpId = (prStaRec) ? + CPU_TO_LE16(prStaRec->ucWlanIndex) : 1; + prTWTAgrtUpdate->ucAgrtSpDuration = rTWTParams.ucMinWakeDur; + prTWTAgrtUpdate->ucBssIndex = prBssInfo->ucBssIndex; + prTWTAgrtUpdate->u4AgrtSpStartTsfLow = + CPU_TO_LE32(rTWTParams.u8TWT & 0xFFFFFFFF); + prTWTAgrtUpdate->u4AgrtSpStartTsfHigh = + CPU_TO_LE32((uint32_t)(rTWTParams.u8TWT >> 32)); + prTWTAgrtUpdate->u2AgrtSpWakeIntvlMantissa = + CPU_TO_LE16(rTWTParams.u2WakeIntvalMantiss); + prTWTAgrtUpdate->ucAgrtSpWakeIntvlExponent = + rTWTParams.ucWakeIntvalExponent; + prTWTAgrtUpdate->ucIsRoleAp = 0; /* STA role */ + prTWTAgrtUpdate->ucAgrtParaBitmap = + ((rTWTParams.fgProtect << TWT_AGRT_PARA_BITMAP_PROTECT_OFFSET) | + ((!rTWTParams.fgUnannounced) << TWT_AGRT_PARA_BITMAP_ANNCE_OFFSET) | + (rTWTParams.fgTrigger << TWT_AGRT_PARA_BITMAP_TRIGGER_OFFSET)); + prTWTAgrtUpdate->ucGrpMemberCnt = 0; + + rWlanStatus = wlanSendSetQueryExtCmd(prAdapter, + CMD_ID_LAYER_0_EXT_MAGIC_NUM, + EXT_CMD_ID_TWT_AGRT_UPDATE, + TRUE, + TRUE, + fgIsOid, + pfCmdDoneHandler, + pfCmdTimeoutHandler, + sizeof(struct _EXT_CMD_TWT_ARGT_UPDATE_T), + (uint8_t *) (prTWTAgrtUpdate), + NULL, 0); + + return rWlanStatus; +} + +static uint32_t +twtPlannerModifyAgrtTbl(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, struct STA_RECORD *prStaRec, + struct _NEXT_TWT_INFO_T *prNextTWTInfo, + uint8_t ucFlowId, uint8_t fgIsOid, + PFN_CMD_DONE_HANDLER pfCmdDoneHandler, + PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler) +{ + uint8_t ucAgrtTblIdx; + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + struct _EXT_CMD_TWT_ARGT_UPDATE_T *prTWTAgrtUpdate; + struct _TWT_PARAMS_T rTWTParams; + + if (prBssInfo == NULL) { + DBGLOG(TWT_PLANNER, ERROR, "No bssinfo to modify agrt\n"); + return WLAN_STATUS_INVALID_DATA; + } + + /* Handle driver agreement table */ + rWlanStatus = twtPlannerDrvAgrtModify(prAdapter, prBssInfo->ucBssIndex, + ucFlowId, prNextTWTInfo, &ucAgrtTblIdx, &rTWTParams); + + if (rWlanStatus) { + DBGLOG(TWT_PLANNER, ERROR, "No agrt to modify Bss %u flow %u\n", + prBssInfo->ucBssIndex, ucFlowId); + return WLAN_STATUS_FAILURE; + } + + /* Handle FW agreement table */ + prTWTAgrtUpdate = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, + sizeof(struct _EXT_CMD_TWT_ARGT_UPDATE_T)); + if (!prTWTAgrtUpdate) { + DBGLOG(TWT_PLANNER, ERROR, + "Allocate _EXT_CMD_TWT_ARGT_UPDATE_T ==> FAILED.\n"); + return WLAN_STATUS_FAILURE; + } + + prTWTAgrtUpdate->ucAgrtTblIdx = ucAgrtTblIdx; + prTWTAgrtUpdate->ucAgrtCtrlFlag = TWT_AGRT_CTRL_MODIFY; + prTWTAgrtUpdate->ucOwnMacId = (prBssInfo) ? + prBssInfo->ucOwnMacIndex : 0; + prTWTAgrtUpdate->ucFlowId = ucFlowId; + prTWTAgrtUpdate->u2PeerIdGrpId = (prStaRec) ? + CPU_TO_LE16(prStaRec->ucWlanIndex) : 1; + prTWTAgrtUpdate->ucAgrtSpDuration = rTWTParams.ucMinWakeDur; + prTWTAgrtUpdate->u4AgrtSpStartTsfLow = + CPU_TO_LE32(rTWTParams.u8TWT & 0xFFFFFFFF); + prTWTAgrtUpdate->u4AgrtSpStartTsfHigh = + CPU_TO_LE32((uint32_t)(rTWTParams.u8TWT >> 32)); + prTWTAgrtUpdate->ucGrpMemberCnt = 0; + prTWTAgrtUpdate->ucBssIndex = prBssInfo->ucBssIndex; + + rWlanStatus = wlanSendSetQueryExtCmd(prAdapter, + CMD_ID_LAYER_0_EXT_MAGIC_NUM, + EXT_CMD_ID_TWT_AGRT_UPDATE, + TRUE, + TRUE, + fgIsOid, + pfCmdDoneHandler, + pfCmdTimeoutHandler, + sizeof(struct _EXT_CMD_TWT_ARGT_UPDATE_T), + (uint8_t *) (prTWTAgrtUpdate), + NULL, 0); + + return rWlanStatus; +} + +static uint32_t +twtPlannerDelAgrtTbl(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, struct STA_RECORD *prStaRec, + uint8_t ucFlowId, uint8_t fgIsOid, + PFN_CMD_DONE_HANDLER pfCmdDoneHandler, + PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler, + uint8_t fgDelDrvEntry) +{ + uint8_t ucAgrtTblIdx; + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + struct _TWT_PLANNER_T *prTWTPlanner = &(prAdapter->rTWTPlanner); + struct _EXT_CMD_TWT_ARGT_UPDATE_T *prTWTAgrtUpdate; + + if (prBssInfo == NULL) { + DBGLOG(TWT_PLANNER, ERROR, "No bssinfo to delete agrt\n"); + return WLAN_STATUS_INVALID_DATA; + } + + /* Find and delete the agreement entry in the driver */ + ucAgrtTblIdx = twtPlannerDrvAgrtFind(prAdapter, + prBssInfo->ucBssIndex, ucFlowId); + + if (ucAgrtTblIdx >= TWT_AGRT_MAX_NUM) { + DBGLOG(TWT_PLANNER, ERROR, + "Cannot find the flow %u to be deleted\n", ucFlowId); + return WLAN_STATUS_FAILURE; + + } + + if (fgDelDrvEntry) + _twtPlannerDrvAgrtDel(prTWTPlanner, ucAgrtTblIdx); + + /* Send cmd to delete agreement entry in FW */ + prTWTAgrtUpdate = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, + sizeof(struct _EXT_CMD_TWT_ARGT_UPDATE_T)); + if (!prTWTAgrtUpdate) { + DBGLOG(TWT_PLANNER, ERROR, + "Alloc _EXT_CMD_TWT_ARGT_UPDATE_T for del FAILED.\n"); + return WLAN_STATUS_FAILURE; + } + + prTWTAgrtUpdate->ucAgrtTblIdx = ucAgrtTblIdx; + prTWTAgrtUpdate->ucAgrtCtrlFlag = TWT_AGRT_CTRL_DELETE; + prTWTAgrtUpdate->ucOwnMacId = (prBssInfo) ? + prBssInfo->ucOwnMacIndex : 0; + prTWTAgrtUpdate->ucFlowId = ucFlowId; + prTWTAgrtUpdate->u2PeerIdGrpId = (prStaRec) ? + CPU_TO_LE16(prStaRec->ucWlanIndex) : 1; + prTWTAgrtUpdate->ucIsRoleAp = 0; /* STA role */ + prTWTAgrtUpdate->ucBssIndex = prBssInfo ? prBssInfo->ucBssIndex : 0; + + rWlanStatus = wlanSendSetQueryExtCmd(prAdapter, + CMD_ID_LAYER_0_EXT_MAGIC_NUM, + EXT_CMD_ID_TWT_AGRT_UPDATE, + TRUE, + TRUE, + fgIsOid, + pfCmdDoneHandler, + pfCmdTimeoutHandler, + sizeof(struct _EXT_CMD_TWT_ARGT_UPDATE_T), + (uint8_t *) (prTWTAgrtUpdate), + NULL, 0); + + return rWlanStatus; +} + +static uint32_t +twtPlannerTeardownAgrtTbl(struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + uint8_t fgIsOid, + PFN_CMD_DONE_HANDLER pfCmdDoneHandler, + PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler) +{ + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + struct _EXT_CMD_TWT_ARGT_UPDATE_T *prTWTAgrtUpdate; + + /* Send cmd to teardown this STA in FW */ + prTWTAgrtUpdate = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, + sizeof(struct _EXT_CMD_TWT_ARGT_UPDATE_T)); + if (!prTWTAgrtUpdate) { + DBGLOG(TWT_PLANNER, ERROR, + "Alloc _EXT_CMD_TWT_ARGT_UPDATE_T for del FAILED.\n"); + return WLAN_STATUS_FAILURE; + } + + /* Don't care about other fields of the cmd */ + prTWTAgrtUpdate->ucAgrtCtrlFlag = TWT_AGRT_CTRL_TEARDOWN; + prTWTAgrtUpdate->u2PeerIdGrpId = (prStaRec) ? + CPU_TO_LE16(prStaRec->ucWlanIndex) : 1; + prTWTAgrtUpdate->ucIsRoleAp = 0; /* STA role */ + prTWTAgrtUpdate->ucBssIndex = prStaRec ? prStaRec->ucBssIndex : 0; + + rWlanStatus = wlanSendSetQueryExtCmd(prAdapter, + CMD_ID_LAYER_0_EXT_MAGIC_NUM, + EXT_CMD_ID_TWT_AGRT_UPDATE, + TRUE, + TRUE, + fgIsOid, + pfCmdDoneHandler, + pfCmdTimeoutHandler, + sizeof(struct _EXT_CMD_TWT_ARGT_UPDATE_T), + (uint8_t *) (prTWTAgrtUpdate), + NULL, 0); + + return rWlanStatus; +} + +uint32_t twtPlannerReset( + struct ADAPTER *prAdapter, struct BSS_INFO *prBssInfo) +{ + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + struct STA_RECORD *prStaRec; + struct _EXT_CMD_TWT_ARGT_UPDATE_T *prTWTAgrtUpdate; + + /* If no agrt exits, don't bother resetting */ + if (twtPlannerIsDrvAgrtExisting(prAdapter) == FALSE) + return rWlanStatus; + + prTWTAgrtUpdate = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, + sizeof(struct _EXT_CMD_TWT_ARGT_UPDATE_T)); + if (!prTWTAgrtUpdate) { + DBGLOG(TWT_PLANNER, ERROR, + "Alloc _EXT_CMD_TWT_ARGT_UPDATE_T for reset FAILED.\n"); + return WLAN_STATUS_FAILURE; + } + + /* send cmd to reset FW agreement table */ + ASSERT(prBssInfo); + prStaRec = prBssInfo->prStaRecOfAP; + + prTWTAgrtUpdate->ucAgrtCtrlFlag = TWT_AGRT_CTRL_RESET; + prTWTAgrtUpdate->u2PeerIdGrpId = (prStaRec) ? + CPU_TO_LE16(prStaRec->ucWlanIndex) : 1; + prTWTAgrtUpdate->ucIsRoleAp = 0; /* STA role */ + prTWTAgrtUpdate->ucBssIndex = prBssInfo ? prBssInfo->ucBssIndex : 0; + + rWlanStatus = wlanSendSetQueryExtCmd(prAdapter, + CMD_ID_LAYER_0_EXT_MAGIC_NUM, + EXT_CMD_ID_TWT_AGRT_UPDATE, + TRUE, + TRUE, + FALSE, + NULL, + NULL, + sizeof(struct _EXT_CMD_TWT_ARGT_UPDATE_T), + (uint8_t *) (prTWTAgrtUpdate), + NULL, 0); + + + /* reset driver agreement table */ + memset(&(prAdapter->rTWTPlanner), 0, sizeof(prAdapter->rTWTPlanner)); + + /* Enable scan after TWT agrt reset */ + prAdapter->fgEnOnlineScan = TRUE; + +#if (CFG_TWT_SMART_STA == 1) + g_TwtSmartStaCtrl.fgTwtSmartStaActivated = FALSE; + g_TwtSmartStaCtrl.fgTwtSmartStaReq = FALSE; + g_TwtSmartStaCtrl.fgTwtSmartStaTeardownReq = FALSE; + g_TwtSmartStaCtrl.ucBssIndex = 0; + g_TwtSmartStaCtrl.ucFlowId = 0; + g_TwtSmartStaCtrl.u4CurTp = 0; + g_TwtSmartStaCtrl.u4LastTp = 0; + g_TwtSmartStaCtrl.u4TwtSwitch == 0; + g_TwtSmartStaCtrl.eState = TWT_SMART_STA_STATE_IDLE; +#endif + + return rWlanStatus; +} + +uint64_t twtPlannerAdjustNextTWT(struct ADAPTER *prAdapter, + uint8_t ucBssIdx, uint8_t ucFlowId, + uint64_t u8NextTWTOrig) +{ + uint8_t ucAgrtTblIdx; + struct _TWT_PARAMS_T rTWTParams = {0x0}; + uint64_t u8Diff; + uint32_t u4WakeIntvl; + + twtPlannerDrvAgrtGet(prAdapter, ucBssIdx, ucFlowId, + &ucAgrtTblIdx, &rTWTParams); + + u4WakeIntvl = rTWTParams.u2WakeIntvalMantiss << + rTWTParams.ucWakeIntvalExponent; + u8Diff = u8NextTWTOrig - rTWTParams.u8TWT; + /* TODO: move div_u64 to os-dependent file */ + return (rTWTParams.u8TWT + + (div_u64(u8Diff, u4WakeIntvl) + 1) * u4WakeIntvl); +} + +void twtPlannerGetTsfDone( + struct ADAPTER *prAdapter, + struct CMD_INFO *prCmdInfo, + uint8_t *pucEventBuf) +{ + struct EXT_EVENT_MAC_INFO_T *prEventMacInfo; + struct _TWT_GET_TSF_CONTEXT_T *prGetTsfCtxt; + struct BSS_INFO *prBssInfo; + struct STA_RECORD *prStaRec; + struct TSF_RESULT_T *prTsfResult; + uint64_t u8CurTsf; + + ASSERT(prAdapter); + ASSERT(prCmdInfo); + ASSERT(pucEventBuf); + + if (!pucEventBuf) { + DBGLOG(TWT_PLANNER, ERROR, "pucEventBuf is NULL.\n"); + return; + } + if (!prCmdInfo->pvInformationBuffer) { + DBGLOG(TWT_PLANNER, ERROR, + "prCmdInfo->pvInformationBuffer is NULL.\n"); + return; + } + + prEventMacInfo = (struct EXT_EVENT_MAC_INFO_T *) (pucEventBuf); + prGetTsfCtxt = (struct _TWT_GET_TSF_CONTEXT_T *) + prCmdInfo->pvInformationBuffer; + + ASSERT(prGetTsfCtxt); + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prGetTsfCtxt->ucBssIdx); + ASSERT(prBssInfo); + prStaRec = prBssInfo->prStaRecOfAP; + ASSERT(prStaRec); + + prTsfResult = &(prEventMacInfo->rMacInfoResult.rTsfResult); + u8CurTsf = LE32_TO_CPU(prTsfResult->u4TsfBitsLow) | + (((uint64_t)(LE32_TO_CPU(prTsfResult->u4TsfBitsHigh))) << 32); + + switch (prGetTsfCtxt->ucReason) { + case TWT_GET_TSF_FOR_ADD_AGRT_BYPASS: + prGetTsfCtxt->rTWTParams.u8TWT = u8CurTsf + TSF_OFFSET_FOR_EMU; + twtPlannerAddAgrtTbl(prAdapter, prBssInfo, + prStaRec, &(prGetTsfCtxt->rTWTParams), + prGetTsfCtxt->ucTWTFlowId, + prGetTsfCtxt->fgIsOid, + NULL, NULL); + break; + + case TWT_GET_TSF_FOR_ADD_AGRT: + { + struct _TWT_PARAMS_T *prTWTParams; + struct _TWT_FLOW_T *prTWTFlow = twtPlannerFlowFindById(prStaRec, + prGetTsfCtxt->ucTWTFlowId); + + if (prTWTFlow == NULL) { + DBGLOG(TWT_PLANNER, ERROR, "prTWTFlow is NULL.\n"); + + kalMemFree(prGetTsfCtxt, + VIR_MEM_TYPE, sizeof(*prGetTsfCtxt)); + + return; + } + + prGetTsfCtxt->rTWTParams.u8TWT = + u8CurTsf + TSF_OFFSET_FOR_AGRT_ADD; + + prTWTParams = &(prTWTFlow->rTWTParams); + + kalMemCopy(prTWTParams, &(prGetTsfCtxt->rTWTParams), + sizeof(struct _TWT_PARAMS_T)); + + /* Start the process to nego for a new agreement */ + twtPlannerSendReqStart(prAdapter, + prStaRec, prGetTsfCtxt->ucTWTFlowId); + + break; + } + case TWT_GET_TSF_FOR_RESUME_AGRT: + { + uint8_t ucNextTWTSize = NEXT_TWT_SUBFIELD_64_BITS; + uint64_t u8NextTWT = u8CurTsf + TSF_OFFSET_FOR_AGRT_RESUME; + + /* Adjust next TWT if 'Flexible TWT Sched' is not supported */ + if (!HE_IS_MAC_CAP_FLEXIBLE_TWT_SHDL( + prStaRec->ucHeMacCapInfo)) { + u8NextTWT = twtPlannerAdjustNextTWT(prAdapter, + prBssInfo->ucBssIndex, + prGetTsfCtxt->ucTWTFlowId, + u8NextTWT); + } + + /* Start the process to resume this TWT agreement */ + twtPlannerSendReqResume(prAdapter, + prStaRec, prGetTsfCtxt->ucTWTFlowId, + u8NextTWT, ucNextTWTSize); + + break; + } + + default: + DBGLOG(TWT_PLANNER, ERROR, + "Unknown reason to get TSF %u\n", + prGetTsfCtxt->ucReason); + break; + } + + /* free memory */ + kalMemFree(prGetTsfCtxt, VIR_MEM_TYPE, sizeof(*prGetTsfCtxt)); +} + +static uint32_t +twtPlannerGetCurrentTSF( + struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, + void *pvSetBuffer, + uint32_t u4SetBufferLen) +{ + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + struct _EXT_CMD_GET_MAC_INFO_T *prMacInfoCmd; + struct _EXTRA_ARG_TSF_T *prTsfArg; + + prMacInfoCmd = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, + sizeof(struct _EXT_CMD_GET_MAC_INFO_T)); + if (!prMacInfoCmd) { + DBGLOG(TWT_PLANNER, ERROR, + "Alloc _EXT_CMD_GET_MAC_INFO_T FAILED.\n"); + return WLAN_STATUS_FAILURE; + } + + prTsfArg = &(prMacInfoCmd->rExtraArgument.rTsfArg); + prMacInfoCmd->u2MacInfoId = CPU_TO_LE16(MAC_INFO_TYPE_TSF); + prTsfArg->ucHwBssidIndex = prBssInfo->ucOwnMacIndex; + + rWlanStatus = wlanSendSetQueryExtCmd(prAdapter, + CMD_ID_LAYER_0_EXT_MAGIC_NUM, + EXT_CMD_ID_GET_MAC_INFO, + FALSE, + TRUE, + FALSE, + twtPlannerGetTsfDone, + NULL, + sizeof(struct _EXT_CMD_GET_MAC_INFO_T), + (uint8_t *) (prMacInfoCmd), + pvSetBuffer, u4SetBufferLen); + + return rWlanStatus; +} + +void twtPlannerSetParams( + struct ADAPTER *prAdapter, struct MSG_HDR *prMsgHdr) +{ + struct _MSG_TWT_PARAMS_SET_T *prTWTParamSetMsg; + struct _TWT_CTRL_T rTWTCtrl, *prTWTCtrl = &rTWTCtrl; + struct BSS_INFO *prBssInfo; + struct STA_RECORD *prStaRec; + uint8_t ucBssIdx, ucFlowId; + + ASSERT(prAdapter); + ASSERT(prMsgHdr); + + prTWTParamSetMsg = (struct _MSG_TWT_PARAMS_SET_T *) prMsgHdr; + kalMemCopy(prTWTCtrl, &prTWTParamSetMsg->rTWTCtrl, sizeof(*prTWTCtrl)); + + cnmMemFree(prAdapter, prMsgHdr); + + /* Find the BSS info */ + ucBssIdx = prTWTCtrl->ucBssIdx; + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIdx); + + if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE || + prBssInfo->eConnectionState != MEDIA_STATE_CONNECTED) { + DBGLOG(TWT_PLANNER, ERROR, + "Current op mode %d connection state %d\n", + prBssInfo->eCurrentOPMode, prBssInfo->eConnectionState); + return; + } + + /* Get the STA Record */ + prStaRec = prBssInfo->prStaRecOfAP; + if (!prStaRec) { + DBGLOG(TWT_PLANNER, ERROR, "No AP STA Record\n"); + return; + } + + /* If bypassing TWT nego, this ctrl param is treated as a TWT agrt*/ + if (IS_TWT_PARAM_ACTION_ADD_BYPASS(prTWTCtrl->ucCtrlAction)) { + struct _TWT_GET_TSF_CONTEXT_T *prGetTsfCtxt = + kalMemAlloc(sizeof(struct _TWT_GET_TSF_CONTEXT_T), + VIR_MEM_TYPE); + if (prGetTsfCtxt == NULL) { + DBGLOG(TWT_PLANNER, ERROR, "mem alloc failed\n"); + return; + } + + prGetTsfCtxt->ucReason = TWT_GET_TSF_FOR_ADD_AGRT_BYPASS; + prGetTsfCtxt->ucBssIdx = ucBssIdx; + prGetTsfCtxt->ucTWTFlowId = prTWTCtrl->ucTWTFlowId; + prGetTsfCtxt->fgIsOid = FALSE; + kalMemCopy(&(prGetTsfCtxt->rTWTParams), + &(prTWTCtrl->rTWTParams), + sizeof(struct _TWT_PARAMS_T)); + twtPlannerGetCurrentTSF(prAdapter, + prBssInfo, prGetTsfCtxt, sizeof(*prGetTsfCtxt)); + + return; + } + + /* Check if peer has TWT responder capability and local config */ + if (!HE_IS_MAC_CAP_TWT_RSP(prStaRec->ucHeMacCapInfo) || + !IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucTWTRequester)) { + DBGLOG(TWT_PLANNER, ERROR, + "Peer cap 0x%x user config of TWT req %u\n", + prStaRec->ucHeMacCapInfo[0], + prAdapter->rWifiVar.ucTWTRequester); + return; + } + + /* For COEX concern, suppose only 5G is allowed */ + if ((prAdapter->rWifiVar.ucTWTStaBandBitmap & prBssInfo->eBand) + != prBssInfo->eBand) { + DBGLOG(TWT_PLANNER, ERROR, + "TWT BAND support bitmaps(%u)!=%u\n", + prAdapter->rWifiVar.ucTWTStaBandBitmap, + prBssInfo->eBand); + return; + } + + ucFlowId = prTWTCtrl->ucTWTFlowId; + + switch (prTWTCtrl->ucCtrlAction) { + case TWT_PARAM_ACTION_ADD: + if (twtPlannerDrvAgrtFind( + prAdapter, ucBssIdx, ucFlowId) >= TWT_AGRT_MAX_NUM) { + + struct _TWT_GET_TSF_CONTEXT_T *prGetTsfCtxt = + kalMemAlloc( + sizeof(struct _TWT_GET_TSF_CONTEXT_T), + VIR_MEM_TYPE); + if (prGetTsfCtxt == NULL) { + DBGLOG(TWT_PLANNER, ERROR, + "mem alloc failed\n"); + return; + } + + prGetTsfCtxt->ucReason = TWT_GET_TSF_FOR_ADD_AGRT; + prGetTsfCtxt->ucBssIdx = ucBssIdx; + prGetTsfCtxt->ucTWTFlowId = prTWTCtrl->ucTWTFlowId; + prGetTsfCtxt->fgIsOid = FALSE; + kalMemCopy(&(prGetTsfCtxt->rTWTParams), + &(prTWTCtrl->rTWTParams), + sizeof(struct _TWT_PARAMS_T)); + twtPlannerGetCurrentTSF(prAdapter, prBssInfo, + prGetTsfCtxt, sizeof(*prGetTsfCtxt)); + + return; + } + + DBGLOG(TWT_PLANNER, ERROR, + "BSS %u TWT flow %u already exists\n", + ucBssIdx, ucFlowId); + break; + + case TWT_PARAM_ACTION_DEL: + if (twtPlannerDrvAgrtFind( + prAdapter, ucBssIdx, ucFlowId) < TWT_AGRT_MAX_NUM) { + /* Start the process to tear down this TWT agreement */ + twtPlannerSendReqTeardown(prAdapter, + prStaRec, ucFlowId); + } else { + DBGLOG(TWT_PLANNER, ERROR, + "BSS %u TWT flow %u doesn't exist\n", + ucBssIdx, ucFlowId); + } + break; + + case TWT_PARAM_ACTION_SUSPEND: + if (twtPlannerDrvAgrtFind( + prAdapter, ucBssIdx, ucFlowId) < TWT_AGRT_MAX_NUM) { + /* Start the process to suspend this TWT agreement */ + twtPlannerSendReqSuspend(prAdapter, + prStaRec, ucFlowId); + } else { + DBGLOG(TWT_PLANNER, ERROR, + "BSS %u TWT flow %u doesn't exist\n", + ucBssIdx, ucFlowId); + } + break; + + case TWT_PARAM_ACTION_RESUME: + if (twtPlannerDrvAgrtFind( + prAdapter, ucBssIdx, ucFlowId) < TWT_AGRT_MAX_NUM) { + struct _TWT_GET_TSF_CONTEXT_T *prGetTsfCtxt = + kalMemAlloc( + sizeof(struct _TWT_GET_TSF_CONTEXT_T), + VIR_MEM_TYPE); + if (prGetTsfCtxt == NULL) { + DBGLOG(TWT_PLANNER, ERROR, + "mem alloc failed\n"); + return; + } + + prGetTsfCtxt->ucReason = TWT_GET_TSF_FOR_RESUME_AGRT; + prGetTsfCtxt->ucBssIdx = ucBssIdx; + prGetTsfCtxt->ucTWTFlowId = prTWTCtrl->ucTWTFlowId; + prGetTsfCtxt->fgIsOid = FALSE; + twtPlannerGetCurrentTSF(prAdapter, prBssInfo, + prGetTsfCtxt, sizeof(*prGetTsfCtxt)); + } else { + DBGLOG(TWT_PLANNER, ERROR, + "BSS %u TWT flow %u doesn't exist\n", + ucBssIdx, ucFlowId); + } + + break; + + default: + DBGLOG(TWT_PLANNER, ERROR, + "Action %u not supported\n", prTWTCtrl->ucCtrlAction); + break; + } +} + +void twtPlannerRxNegoResult( + struct ADAPTER *prAdapter, + struct MSG_HDR *prMsgHdr) +{ + struct _MSG_TWT_REQFSM_IND_RESULT_T *prTWTFsmResultMsg; + struct STA_RECORD *prStaRec; + struct BSS_INFO *prBssInfo; + uint8_t ucTWTFlowId; + struct _TWT_PARAMS_T *prTWTResult, *prTWTParams; + struct _TWT_FLOW_T *prTWTFlow; + + ASSERT(prAdapter); + ASSERT(prMsgHdr); + + prTWTFsmResultMsg = (struct _MSG_TWT_REQFSM_IND_RESULT_T *) prMsgHdr; + prStaRec = prTWTFsmResultMsg->prStaRec; + ucTWTFlowId = prTWTFsmResultMsg->ucTWTFlowId; + + if ((!prStaRec) || (prStaRec->fgIsInUse == FALSE)) { + cnmMemFree(prAdapter, prMsgHdr); + return; + } + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex); + + cnmMemFree(prAdapter, prMsgHdr); + + if (!IS_AP_STA(prStaRec)) { + DBGLOG(TWT_PLANNER, ERROR, + "Rx nego result: invalid STA Type %d\n", + prStaRec->eStaType); + return; + } + + prTWTFlow = &(prStaRec->arTWTFlow[ucTWTFlowId]); + prTWTResult = &(prTWTFlow->rTWTPeerParams); + + switch (prTWTResult->ucSetupCmd) { + case TWT_SETUP_CMD_ACCEPT: + /* Update agreement table */ + twtPlannerAddAgrtTbl(prAdapter, prBssInfo, prStaRec, + prTWTResult, ucTWTFlowId, FALSE, + NULL, NULL /* handle TWT cmd timeout? */); + + /* Disable SCAN during TWT activity */ + prAdapter->fgEnOnlineScan = FALSE; + + break; + + case TWT_SETUP_CMD_ALTERNATE: + case TWT_SETUP_CMD_DICTATE: + /* Use AP's suggestions */ + prTWTParams = &(prTWTFlow->rTWTParams); + kalMemCopy(prTWTParams, + prTWTResult, sizeof(struct _TWT_PARAMS_T)); + prTWTParams->ucSetupCmd = TWT_SETUP_CMD_SUGGEST; + prTWTParams->fgReq = 1; + twtPlannerSendReqStart(prAdapter, prStaRec, ucTWTFlowId); + break; + + case TWT_SETUP_CMD_REJECT: + /* Clear TWT flow in StaRec */ + break; + + default: + DBGLOG(TWT_PLANNER, ERROR, + "Unknown setup command %u\n", prTWTResult->ucSetupCmd); + ASSERT(0); + break; + + } +} + +void twtPlannerSuspendDone( + struct ADAPTER *prAdapter, struct MSG_HDR *prMsgHdr) +{ + struct _MSG_TWT_REQFSM_IND_RESULT_T *prTWTFsmResultMsg; + struct STA_RECORD *prStaRec; + struct BSS_INFO *prBssInfo; + uint8_t ucTWTFlowId; + + ASSERT(prAdapter); + ASSERT(prMsgHdr); + + prTWTFsmResultMsg = (struct _MSG_TWT_REQFSM_IND_RESULT_T *) prMsgHdr; + prStaRec = prTWTFsmResultMsg->prStaRec; + ucTWTFlowId = prTWTFsmResultMsg->ucTWTFlowId; + + if ((!prStaRec) || (prStaRec->fgIsInUse == FALSE)) { + cnmMemFree(prAdapter, prMsgHdr); + return; + } + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex); + + cnmMemFree(prAdapter, prMsgHdr); + + if (!IS_AP_STA(prStaRec)) { + DBGLOG(TWT_PLANNER, ERROR, + "Rx suspend result: invalid STA Type %d\n", + prStaRec->eStaType); + return; + } + + /* Delete only FW TWT agreement entry */ + twtPlannerDelAgrtTbl(prAdapter, prBssInfo, prStaRec, + ucTWTFlowId, FALSE, + NULL, NULL /* handle TWT cmd timeout? */, FALSE); + + /* Teardown FW TWT agreement entry */ + twtPlannerTeardownAgrtTbl(prAdapter, prStaRec, + FALSE, NULL, NULL /* handle TWT cmd timeout? */); + +} + +void twtPlannerResumeDone( + struct ADAPTER *prAdapter, struct MSG_HDR *prMsgHdr) +{ + struct _MSG_TWT_REQFSM_IND_RESULT_T *prTWTFsmResultMsg; + struct STA_RECORD *prStaRec; + struct BSS_INFO *prBssInfo; + uint8_t ucTWTFlowId; + + ASSERT(prAdapter); + ASSERT(prMsgHdr); + + prTWTFsmResultMsg = (struct _MSG_TWT_REQFSM_IND_RESULT_T *) prMsgHdr; + prStaRec = prTWTFsmResultMsg->prStaRec; + ucTWTFlowId = prTWTFsmResultMsg->ucTWTFlowId; + + if ((!prStaRec) || (prStaRec->fgIsInUse == FALSE)) { + cnmMemFree(prAdapter, prMsgHdr); + return; + } + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex); + + cnmMemFree(prAdapter, prMsgHdr); + + if (!IS_AP_STA(prStaRec)) { + DBGLOG(TWT_PLANNER, ERROR, + "Rx suspend result: invalid STA Type %d\n", + prStaRec->eStaType); + return; + } + + /* Add back the FW TWT agreement entry */ + twtPlannerResumeAgrtTbl(prAdapter, prBssInfo, prStaRec, + ucTWTFlowId, FALSE, + NULL, NULL /* handle TWT cmd timeout? */); + +} + +void twtPlannerTeardownDone( + struct ADAPTER *prAdapter, struct MSG_HDR *prMsgHdr) +{ + struct _MSG_TWT_REQFSM_IND_RESULT_T *prTWTFsmResultMsg; + struct STA_RECORD *prStaRec; + struct BSS_INFO *prBssInfo; + uint8_t ucTWTFlowId; + + ASSERT(prAdapter); + ASSERT(prMsgHdr); + + prTWTFsmResultMsg = (struct _MSG_TWT_REQFSM_IND_RESULT_T *) prMsgHdr; + prStaRec = prTWTFsmResultMsg->prStaRec; + ucTWTFlowId = prTWTFsmResultMsg->ucTWTFlowId; + + if ((!prStaRec) || (prStaRec->fgIsInUse == FALSE)) { + cnmMemFree(prAdapter, prMsgHdr); + return; + } + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex); + + cnmMemFree(prAdapter, prMsgHdr); + + if (!IS_AP_STA(prStaRec)) { + DBGLOG(TWT_PLANNER, ERROR, + "Rx teardown result: invalid STA Type %d\n", + prStaRec->eStaType); + return; + } + + /* Delete driver & FW TWT agreement entry */ + twtPlannerDelAgrtTbl(prAdapter, prBssInfo, prStaRec, + ucTWTFlowId, FALSE, + NULL, NULL /* handle TWT cmd timeout? */, TRUE); + + /* Teardown FW TWT agreement entry */ + twtPlannerTeardownAgrtTbl(prAdapter, prStaRec, + FALSE, NULL, NULL /* handle TWT cmd timeout? */); + + /* Enable SCAN after TWT agrt has been tear down */ + prAdapter->fgEnOnlineScan = TRUE; + +#if (CFG_TWT_SMART_STA == 1) + g_TwtSmartStaCtrl.fgTwtSmartStaActivated = FALSE; + g_TwtSmartStaCtrl.fgTwtSmartStaReq = FALSE; + g_TwtSmartStaCtrl.fgTwtSmartStaTeardownReq = FALSE; + g_TwtSmartStaCtrl.ucBssIndex = 0; + g_TwtSmartStaCtrl.ucFlowId = 0; + g_TwtSmartStaCtrl.u4CurTp = 0; + g_TwtSmartStaCtrl.u4LastTp = 0; + g_TwtSmartStaCtrl.u4TwtSwitch == 0; + g_TwtSmartStaCtrl.eState = TWT_SMART_STA_STATE_IDLE; +#endif + +} + +void twtPlannerRxInfoFrm( + struct ADAPTER *prAdapter, struct MSG_HDR *prMsgHdr) +{ + struct _MSG_TWT_REQFSM_IND_INFOFRM_T *prTWTFsmInfoFrmMsg; + struct STA_RECORD *prStaRec; + struct BSS_INFO *prBssInfo; + uint8_t ucTWTFlowId; + struct _NEXT_TWT_INFO_T rNextTWTInfo; + + ASSERT(prAdapter); + ASSERT(prMsgHdr); + + prTWTFsmInfoFrmMsg = (struct _MSG_TWT_REQFSM_IND_INFOFRM_T *) prMsgHdr; + prStaRec = prTWTFsmInfoFrmMsg->prStaRec; + ucTWTFlowId = prTWTFsmInfoFrmMsg->ucTWTFlowId; + + if ((!prStaRec) || (prStaRec->fgIsInUse == FALSE)) { + cnmMemFree(prAdapter, prMsgHdr); + return; + } + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex); + + if (!IS_AP_STA(prStaRec)) { + DBGLOG(TWT_PLANNER, ERROR, + "Rx info frame: invalid STA Type %d\n", + prStaRec->eStaType); + cnmMemFree(prAdapter, prMsgHdr); + return; + } + + kalMemCopy(&(rNextTWTInfo), &(prTWTFsmInfoFrmMsg->rNextTWTInfo), + sizeof(struct _NEXT_TWT_INFO_T)); + + cnmMemFree(prAdapter, prMsgHdr); + + /* Modify the TWT agreement entry */ + twtPlannerModifyAgrtTbl(prAdapter, prBssInfo, prStaRec, + &rNextTWTInfo, ucTWTFlowId, FALSE, + NULL, NULL /* handle TWT cmd timeout? */); + +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/twt_req_fsm.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/twt_req_fsm.c new file mode 100644 index 0000000000000000000000000000000000000000..1056155f865a3d5a96d894aedceb4a7ba4df4af4 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/twt_req_fsm.c @@ -0,0 +1,669 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2017 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2017 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/*! \file "twt_req_fsm.c" +* \brief FSM for TWT Requesting STA negotiation +*/ + + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include "precomp.h" + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +static uint8_t *apucDebugTWTReqState[TWT_REQ_STATE_NUM] = { + (uint8_t *) DISP_STRING("TWT_REQ_STATE_IDLE"), + (uint8_t *) DISP_STRING("TWT_REQ_STATE_REQTX"), + (uint8_t *) DISP_STRING("TWT_REQ_STATE_WAIT_RSP"), + (uint8_t *) DISP_STRING("TWT_REQ_STATE_SUSPENDING"), + (uint8_t *) DISP_STRING("TWT_REQ_STATE_SUSPENDED"), + (uint8_t *) DISP_STRING("TWT_REQ_STATE_RESUMING"), + (uint8_t *) DISP_STRING("TWT_REQ_STATE_TEARING_DOWN"), +}; + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +static uint32_t +twtReqFsmSendEvent( + struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + uint8_t ucTWTFlowId, + enum ENUM_MSG_ID eMsgId); + +static uint32_t +twtReqFsmSendEventRxInfoFrm( + struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + uint8_t ucTWTFlowId, + struct _NEXT_TWT_INFO_T *prNextTWTInfo); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +/*----------------------------------------------------------------------------*/ +/*! +* @brief The Core FSM engine of TWT Requester Module. +* +* @param[in] prStaRec Pointer to the STA_RECORD_T +* @param[in] eNextState The value of Next State +* @param[in] prRetainedSwRfb SW_RFB_T for JOIN Success +* +* @return (none) +*/ +/*----------------------------------------------------------------------------*/ +void +twtReqFsmSteps( + struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + enum _ENUM_TWT_REQUESTER_STATE_T eNextState, + uint8_t ucTWTFlowId, + void *pParam) +{ + uint32_t rStatus = WLAN_STATUS_FAILURE; + enum _ENUM_TWT_REQUESTER_STATE_T ePreState; + uint8_t fgIsTransition; + + ASSERT(prAdapter); + ASSERT(prStaRec); + + do { + + DBGLOG(TWT_REQUESTER, STATE, + "[TWT_REQ] Flow %d TRANSITION: [%s] -> [%s]\n", + ucTWTFlowId, + apucDebugTWTReqState[prStaRec->aeTWTReqState], + apucDebugTWTReqState[eNextState]); + + ePreState = prStaRec->aeTWTReqState; + + prStaRec->aeTWTReqState = eNextState; + fgIsTransition = (uint8_t) FALSE; + + switch (prStaRec->aeTWTReqState) { + case TWT_REQ_STATE_IDLE: + /* Notify TWT Planner of the negotiation result */ + if (ePreState == TWT_REQ_STATE_WAIT_RSP) { + twtReqFsmSendEvent(prAdapter, prStaRec, + ucTWTFlowId, MID_TWT_REQ_IND_RESULT); + /* TODO: how to handle failures */ + } else if (ePreState == TWT_REQ_STATE_TEARING_DOWN) { + twtReqFsmSendEvent(prAdapter, prStaRec, + ucTWTFlowId, + MID_TWT_REQ_IND_TEARDOWN_DONE); + } else if (ePreState == TWT_REQ_STATE_RESUMING) { + twtReqFsmSendEvent(prAdapter, prStaRec, + ucTWTFlowId, + MID_TWT_REQ_IND_RESUME_DONE); + } + break; + + case TWT_REQ_STATE_REQTX: + { + struct _TWT_PARAMS_T *prTWTParams = + (struct _TWT_PARAMS_T *)pParam; + ASSERT(prTWTParams); + rStatus = twtSendSetupFrame( + prAdapter, prStaRec, ucTWTFlowId, + prTWTParams, twtReqFsmRunEventTxDone); + if (rStatus != WLAN_STATUS_SUCCESS) { + eNextState = TWT_REQ_STATE_IDLE; + fgIsTransition = TRUE; + } + break; + } + + case TWT_REQ_STATE_WAIT_RSP: + break; + + case TWT_REQ_STATE_TEARING_DOWN: + rStatus = twtSendTeardownFrame( + prAdapter, prStaRec, ucTWTFlowId, + twtReqFsmRunEventTxDone); + if (rStatus != WLAN_STATUS_SUCCESS) { + eNextState = TWT_REQ_STATE_IDLE; + fgIsTransition = TRUE; + } + break; + + case TWT_REQ_STATE_SUSPENDING: + { + struct _NEXT_TWT_INFO_T rNextTWTInfo = {0}; + + rStatus = twtSendInfoFrame( + prAdapter, prStaRec, ucTWTFlowId, &rNextTWTInfo, + twtReqFsmRunEventTxDone); + if (rStatus != WLAN_STATUS_SUCCESS) { + eNextState = TWT_REQ_STATE_IDLE; + fgIsTransition = TRUE; + } + break; + } + + case TWT_REQ_STATE_RESUMING: + { + struct _NEXT_TWT_INFO_T *prNextTWTInfo = + (struct _NEXT_TWT_INFO_T *)pParam; + rStatus = twtSendInfoFrame( + prAdapter, prStaRec, ucTWTFlowId, prNextTWTInfo, + twtReqFsmRunEventTxDone); + if (rStatus != WLAN_STATUS_SUCCESS) { + eNextState = TWT_REQ_STATE_IDLE; + fgIsTransition = TRUE; + } + + break; + } + + case TWT_REQ_STATE_SUSPENDED: + twtReqFsmSendEvent(prAdapter, prStaRec, + ucTWTFlowId, MID_TWT_REQ_IND_SUSPEND_DONE); + break; + + case TWT_REQ_STATE_RX_TEARDOWN: + twtReqFsmSendEvent(prAdapter, prStaRec, + ucTWTFlowId, MID_TWT_REQ_IND_TEARDOWN_DONE); + break; + + case TWT_REQ_STATE_RX_INFOFRM: + { + struct _NEXT_TWT_INFO_T *prNextTWTInfo = + (struct _NEXT_TWT_INFO_T *)pParam; + twtReqFsmSendEventRxInfoFrm(prAdapter, prStaRec, + ucTWTFlowId, prNextTWTInfo); + break; + } + + default: + DBGLOG(TWT_REQUESTER, ERROR, + "Unknown TWT_REQUESTER STATE\n"); + ASSERT(0); + break; + } + + } while (fgIsTransition); +} + +static uint32_t +twtReqFsmSendEvent( + struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + uint8_t ucTWTFlowId, + enum ENUM_MSG_ID eMsgId) +{ + struct _MSG_TWT_REQFSM_IND_RESULT_T *prTWTFsmResultMsg; + + prTWTFsmResultMsg = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, + sizeof(struct _MSG_TWT_REQFSM_IND_RESULT_T)); + if (prTWTFsmResultMsg) { + prTWTFsmResultMsg->rMsgHdr.eMsgId = eMsgId; + prTWTFsmResultMsg->prStaRec = prStaRec; + prTWTFsmResultMsg->ucTWTFlowId = ucTWTFlowId; + + mboxSendMsg(prAdapter, + MBOX_ID_0, + (struct MSG_HDR *) prTWTFsmResultMsg, + MSG_SEND_METHOD_BUF); + } else + return WLAN_STATUS_RESOURCES; + + return WLAN_STATUS_SUCCESS; +} + +static uint32_t +twtReqFsmSendEventRxInfoFrm( + struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + uint8_t ucTWTFlowId, + struct _NEXT_TWT_INFO_T *prNextTWTInfo) +{ + struct _MSG_TWT_REQFSM_IND_INFOFRM_T *prTWTFsmInfoFrmMsg; + + prTWTFsmInfoFrmMsg = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, + sizeof(struct _MSG_TWT_REQFSM_IND_INFOFRM_T)); + if (prTWTFsmInfoFrmMsg) { + prTWTFsmInfoFrmMsg->rMsgHdr.eMsgId = MID_TWT_REQ_IND_INFOFRM; + prTWTFsmInfoFrmMsg->prStaRec = prStaRec; + prTWTFsmInfoFrmMsg->ucTWTFlowId = ucTWTFlowId; + kalMemCopy(&(prTWTFsmInfoFrmMsg->rNextTWTInfo), prNextTWTInfo, + sizeof(struct _NEXT_TWT_INFO_T)); + + mboxSendMsg(prAdapter, MBOX_ID_0, + (struct MSG_HDR *) prTWTFsmInfoFrmMsg, + MSG_SEND_METHOD_BUF); + } else + return WLAN_STATUS_RESOURCES; + + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! +* @brief This function will handle the Start Event to TWT FSM. +* +* @param[in] prMsgHdr Message of Request for a particular STA. +* +* @return (none) +*/ +/*----------------------------------------------------------------------------*/ +void twtReqFsmRunEventStart( + struct ADAPTER *prAdapter, + struct MSG_HDR *prMsgHdr) +{ + struct _MSG_TWT_REQFSM_START_T *prTWTReqFsmStartMsg; + struct STA_RECORD *prStaRec; + struct _TWT_PARAMS_T *prTWTParams; + uint8_t ucTWTFlowId; + + ASSERT(prAdapter); + ASSERT(prMsgHdr); + + prTWTReqFsmStartMsg = (struct _MSG_TWT_REQFSM_START_T *) prMsgHdr; + prStaRec = prTWTReqFsmStartMsg->prStaRec; + ucTWTFlowId = prTWTReqFsmStartMsg->ucTWTFlowId; + prTWTParams = &(prStaRec->arTWTFlow[ucTWTFlowId].rTWTParams); + + if ((!prStaRec) || (prStaRec->fgIsInUse == FALSE)) { + cnmMemFree(prAdapter, prMsgHdr); + return; + } + + ASSERT(prStaRec); + ASSERT(prTWTParams); + + DBGLOG(TWT_REQUESTER, LOUD, + "EVENT-START: TWT Requester FSM %d\n", ucTWTFlowId); + + cnmMemFree(prAdapter, prMsgHdr); + + /* Validation of TWT Requester Start Event */ + if (!IS_AP_STA(prStaRec)) { + DBGLOG(TWT_REQUESTER, ERROR, + "EVENT-START: Invalid Type %d\n", + prStaRec->eStaType); + + /* TODO: Notify TWT Planner */ + + return; + } + + twtReqFsmSteps(prAdapter, prStaRec, + TWT_REQ_STATE_REQTX, ucTWTFlowId, prTWTParams); +} + +/*----------------------------------------------------------------------------*/ +/*! +* @brief This function will handle the Teardown Event to TWT FSM. +* +* @param[in] prMsgHdr Message of Request for a particular STA. +* +* @return (none) +*/ +/*----------------------------------------------------------------------------*/ +void twtReqFsmRunEventTeardown( + struct ADAPTER *prAdapter, struct MSG_HDR *prMsgHdr) +{ + struct _MSG_TWT_REQFSM_TEARDOWN_T *prTWTReqFsmTeardownMsg; + struct STA_RECORD *prStaRec; + uint8_t ucTWTFlowId; + + ASSERT(prAdapter); + ASSERT(prMsgHdr); + + prTWTReqFsmTeardownMsg = (struct _MSG_TWT_REQFSM_TEARDOWN_T *) prMsgHdr; + prStaRec = prTWTReqFsmTeardownMsg->prStaRec; + ucTWTFlowId = prTWTReqFsmTeardownMsg->ucTWTFlowId; + + if ((!prStaRec) || (prStaRec->fgIsInUse == FALSE)) { + cnmMemFree(prAdapter, prMsgHdr); + return; + } + + ASSERT(prStaRec); + + DBGLOG(TWT_REQUESTER, LOUD, "EVENT-TEARDOWN: TWT Requester FSM %d\n", + ucTWTFlowId); + + cnmMemFree(prAdapter, prMsgHdr); + + /* Validation of TWT Requester Teardown Event */ + if (!IS_AP_STA(prStaRec)) { + DBGLOG(TWT_REQUESTER, ERROR, "Invalid STA Type %d\n", + prStaRec->eStaType); + + /* TODO: Notify TWT Planner */ + + return; + } + + twtReqFsmSteps(prAdapter, prStaRec, TWT_REQ_STATE_TEARING_DOWN, + ucTWTFlowId, NULL); +} + +/*----------------------------------------------------------------------------*/ +/*! +* @brief This function will handle the Suspend Event to TWT FSM. +* +* @param[in] prMsgHdr Message of Request for a particular STA. +* +* @return (none) +*/ +/*----------------------------------------------------------------------------*/ +void twtReqFsmRunEventSuspend( + struct ADAPTER *prAdapter, struct MSG_HDR *prMsgHdr) +{ + struct _MSG_TWT_REQFSM_SUSPEND_T *prTWTReqFsmSuspendMsg; + struct STA_RECORD *prStaRec; + uint8_t ucTWTFlowId; + + ASSERT(prAdapter); + ASSERT(prMsgHdr); + + prTWTReqFsmSuspendMsg = (struct _MSG_TWT_REQFSM_SUSPEND_T *) prMsgHdr; + prStaRec = prTWTReqFsmSuspendMsg->prStaRec; + ucTWTFlowId = prTWTReqFsmSuspendMsg->ucTWTFlowId; + + if ((!prStaRec) || (prStaRec->fgIsInUse == FALSE)) { + cnmMemFree(prAdapter, prMsgHdr); + return; + } + + ASSERT(prStaRec); + + DBGLOG(TWT_REQUESTER, LOUD, "EVENT-SUSPEND: TWT Requester FSM %d\n", + ucTWTFlowId); + + cnmMemFree(prAdapter, prMsgHdr); + + /* Validation of TWT Requester Suspend Event */ + if (!IS_AP_STA(prStaRec)) { + DBGLOG(TWT_REQUESTER, ERROR, "Invalid STA Type %d\n", + prStaRec->eStaType); + + /* TODO: Notify TWT Planner */ + + return; + } + + twtReqFsmSteps(prAdapter, prStaRec, TWT_REQ_STATE_SUSPENDING, + ucTWTFlowId, NULL); +} + +/*----------------------------------------------------------------------------*/ +/*! +* @brief This function will handle the Suspend Event to TWT FSM. +* +* @param[in] prMsgHdr Message of Request for a particular STA. +* +* @return (none) +*/ +/*----------------------------------------------------------------------------*/ +void twtReqFsmRunEventResume( + struct ADAPTER *prAdapter, struct MSG_HDR *prMsgHdr) +{ + struct _MSG_TWT_REQFSM_RESUME_T *prTWTReqFsmResumeMsg; + struct STA_RECORD *prStaRec; + uint8_t ucTWTFlowId; + struct _NEXT_TWT_INFO_T rNextTWTInfo; + + ASSERT(prAdapter); + ASSERT(prMsgHdr); + + prTWTReqFsmResumeMsg = (struct _MSG_TWT_REQFSM_RESUME_T *) prMsgHdr; + prStaRec = prTWTReqFsmResumeMsg->prStaRec; + ucTWTFlowId = prTWTReqFsmResumeMsg->ucTWTFlowId; + rNextTWTInfo.u8NextTWT = prTWTReqFsmResumeMsg->u8NextTWT; + rNextTWTInfo.ucNextTWTSize = prTWTReqFsmResumeMsg->ucNextTWTSize; + + if ((!prStaRec) || (prStaRec->fgIsInUse == FALSE)) { + cnmMemFree(prAdapter, prMsgHdr); + return; + } + + ASSERT(prStaRec); + + DBGLOG(TWT_REQUESTER, LOUD, "EVENT-RESUME: TWT Requester FSM %d\n", + ucTWTFlowId); + + cnmMemFree(prAdapter, prMsgHdr); + + /* Validation of TWT Requester Teardown Event */ + if (!IS_AP_STA(prStaRec)) { + DBGLOG(TWT_REQUESTER, ERROR, "Invalid STA Type %d\n", + prStaRec->eStaType); + + /* TODO: Notify TWT Planner */ + + return; + } + + twtReqFsmSteps(prAdapter, prStaRec, TWT_REQ_STATE_RESUMING, + ucTWTFlowId, (void *)&rNextTWTInfo); +} + +uint32_t +twtReqFsmRunEventTxDone( + struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo, + enum ENUM_TX_RESULT_CODE rTxDoneStatus) +{ + struct STA_RECORD *prStaRec; + enum _ENUM_TWT_REQUESTER_STATE_T eNextState; + uint8_t ucTWTFlowId; + + ASSERT(prMsduInfo); + + prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); + if (!prStaRec) { + DBGLOG(TWT_REQUESTER, ERROR, + "EVENT-TXDONE: No valid STA Record\n"); + return WLAN_STATUS_INVALID_PACKET; + } + + if (rTxDoneStatus) + DBGLOG(TWT_REQUESTER, INFO, + "EVENT-TX DONE [status: %d][seq: %d]: Current Time = %d\n", + rTxDoneStatus, prMsduInfo->ucTxSeqNum, kalGetTimeTick()); + + /* Next state is set to current state + *by default and check Tx done status to transition if possible + */ + eNextState = prStaRec->aeTWTReqState; + + switch (prStaRec->aeTWTReqState) { + case TWT_REQ_STATE_REQTX: + + if (rTxDoneStatus == TX_RESULT_SUCCESS) + eNextState = TWT_REQ_STATE_WAIT_RSP; + else + eNextState = TWT_REQ_STATE_IDLE; + + ucTWTFlowId = twtGetTxSetupFlowId(prMsduInfo); + twtReqFsmSteps(prAdapter, + prStaRec, eNextState, ucTWTFlowId, NULL); + + break; + + case TWT_REQ_STATE_TEARING_DOWN: + + if (rTxDoneStatus == TX_RESULT_SUCCESS) + eNextState = TWT_REQ_STATE_IDLE; + + ucTWTFlowId = twtGetTxTeardownFlowId(prMsduInfo); + twtReqFsmSteps(prAdapter, prStaRec, eNextState, + ucTWTFlowId, NULL); + + break; + + case TWT_REQ_STATE_SUSPENDING: + if (rTxDoneStatus == TX_RESULT_SUCCESS) + eNextState = TWT_REQ_STATE_SUSPENDED; + + ucTWTFlowId = twtGetTxInfoFlowId(prMsduInfo); + twtReqFsmSteps(prAdapter, prStaRec, eNextState, + ucTWTFlowId, NULL); + + break; + + case TWT_REQ_STATE_RESUMING: + if (rTxDoneStatus == TX_RESULT_SUCCESS) + eNextState = TWT_REQ_STATE_IDLE; + + ucTWTFlowId = twtGetTxInfoFlowId(prMsduInfo); + twtReqFsmSteps(prAdapter, prStaRec, eNextState, + ucTWTFlowId, NULL); + + break; + + default: + break; /* Ignore other cases */ + } + + return WLAN_STATUS_SUCCESS; +} + +void twtReqFsmRunEventRxSetup( + struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb, + struct STA_RECORD *prStaRec, + uint8_t ucTWTFlowId) +{ + if (!IS_AP_STA(prStaRec)) + return; + + switch (prStaRec->aeTWTReqState) { + case TWT_REQ_STATE_WAIT_RSP: + /* transition to the IDLE state */ + twtReqFsmSteps(prAdapter, + prStaRec, TWT_REQ_STATE_IDLE, ucTWTFlowId, NULL); + break; + + default: + break; /* Ignore other cases */ + } +} + +void twtReqFsmRunEventRxTeardown( + struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb, + struct STA_RECORD *prStaRec, + uint8_t ucTWTFlowId) +{ + if (!IS_AP_STA(prStaRec)) + return; + + switch (prStaRec->aeTWTReqState) { + case TWT_REQ_STATE_IDLE: + /* transition to the RX TEARDOWN state */ + twtReqFsmSteps(prAdapter, prStaRec, TWT_REQ_STATE_RX_TEARDOWN, + ucTWTFlowId, NULL); + break; + + default: + break; /* Ignore other cases */ + } +} + +void twtReqFsmRunEventRxInfoFrm( + struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb, + struct STA_RECORD *prStaRec, + uint8_t ucTWTFlowId, + struct _NEXT_TWT_INFO_T *prNextTWTInfo) +{ + if (!IS_AP_STA(prStaRec)) + return; + + switch (prStaRec->aeTWTReqState) { + case TWT_REQ_STATE_IDLE: + /* transition to the RX Info frame state */ + twtReqFsmSteps(prAdapter, prStaRec, TWT_REQ_STATE_RX_INFOFRM, + ucTWTFlowId, prNextTWTInfo); + break; + + default: + break; /* Ignore other cases */ + } +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/wapi.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/wapi.c new file mode 100644 index 0000000000000000000000000000000000000000..0d434b2c9c12addf8723397ba4a1fbbce1d1dd32 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/wapi.c @@ -0,0 +1,484 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/wapi.c#1 + */ + +/*! \file "wapi.c" + * \brief This file including the WAPI related function. + * + * This file provided the macros and functions library support + * the wapi ie parsing, cipher and AKM check to help the AP seleced deciding + */ + +/****************************************************************************** + * C O M P I L E R F L A G S + ****************************************************************************** + */ + +/****************************************************************************** + * E X T E R N A L R E F E R E N C E S + ****************************************************************************** + */ + +#include "precomp.h" +#if CFG_SUPPORT_WAPI + +/****************************************************************************** + * C O N S T A N T S + ****************************************************************************** + */ + +/****************************************************************************** + * D A T A T Y P E S + ****************************************************************************** + */ + +/****************************************************************************** + * P U B L I C D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * P R I V A T E D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * M A C R O S + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N D E C L A R A T I O N S + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N S + ****************************************************************************** + */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to parse WAPI IE. + * + * \param[in] prInfoElem Pointer to the RSN IE + * \param[out] prRsnInfo Pointer to the BSSDescription structure to store the + * WAPI information from the given WAPI IE + * + * \retval TRUE - Succeeded + * \retval FALSE - Failed + */ +/*----------------------------------------------------------------------------*/ +u_int8_t wapiParseWapiIE(IN struct WAPI_INFO_ELEM *prInfoElem, + OUT struct WAPI_INFO *prWapiInfo) +{ + uint32_t i; + int32_t u4RemainWapiIeLen; + uint16_t u2Version; + uint16_t u2Cap = 0; + uint32_t u4GroupSuite = WAPI_CIPHER_SUITE_WPI; + uint16_t u2PairSuiteCount = 0; + uint16_t u2AuthSuiteCount = 0; + uint8_t *pucPairSuite = NULL; + uint8_t *pucAuthSuite = NULL; + uint8_t *cp; + + DEBUGFUNC("wapiParseWapiIE"); + + /* Verify the length of the WAPI IE. */ + if (prInfoElem->ucLength < 6) { + DBGLOG(SEC, TRACE, "WAPI IE length too short (length=%d)\n", + prInfoElem->ucLength); + return FALSE; + } + + /* Check WAPI version: currently, we only support version 1. */ + WLAN_GET_FIELD_16(&prInfoElem->u2Version, &u2Version); + if (u2Version != 1) { + DBGLOG(SEC, TRACE, "Unsupported WAPI IE version: %d\n", + u2Version); + return FALSE; + } + + cp = (uint8_t *) &prInfoElem->u2AKMSuiteCount; + u4RemainWapiIeLen = (int32_t) prInfoElem->ucLength - 2; + + do { + if (u4RemainWapiIeLen == 0) + break; + + /* + * AuthCount : 2 + * AuthSuite : 4 * authSuiteCount + * PairwiseCount: 2 + * PairwiseSuite: 4 * pairSuiteCount + * GroupSuite : 4 + * Cap : 2 + */ + + /* Parse the Authentication + * and Key Management Cipher Suite Count field. + */ + if (u4RemainWapiIeLen < 2) { + DBGLOG(SEC, TRACE, + "Fail to parse WAPI IE in auth & key mgt suite count (IE len: %d)\n", + prInfoElem->ucLength); + return FALSE; + } + + WLAN_GET_FIELD_16(cp, &u2AuthSuiteCount); + cp += 2; + u4RemainWapiIeLen -= 2; + + /* Parse the Authentication + * and Key Management Cipher Suite List field. + */ + i = (uint32_t) u2AuthSuiteCount * 4; + if (u4RemainWapiIeLen < (int32_t) i) { + DBGLOG(SEC, TRACE, + "Fail to parse WAPI IE in auth & key mgt suite list (IE len: %d)\n", + prInfoElem->ucLength); + return FALSE; + } + + pucAuthSuite = cp; + + cp += i; + u4RemainWapiIeLen -= (int32_t) i; + + if (u4RemainWapiIeLen == 0) + break; + + /* Parse the Pairwise Key Cipher Suite Count field. */ + if (u4RemainWapiIeLen < 2) { + DBGLOG(SEC, TRACE, + "Fail to parse WAPI IE in pairwise cipher suite count (IE len: %d)\n", + prInfoElem->ucLength); + return FALSE; + } + + WLAN_GET_FIELD_16(cp, &u2PairSuiteCount); + cp += 2; + u4RemainWapiIeLen -= 2; + + /* Parse the Pairwise Key Cipher Suite List field. */ + i = (uint32_t) u2PairSuiteCount * 4; + if (u4RemainWapiIeLen < (int32_t) i) { + DBGLOG(SEC, TRACE, + "Fail to parse WAPI IE in pairwise cipher suite list (IE len: %d)\n", + prInfoElem->ucLength); + return FALSE; + } + + pucPairSuite = cp; + + cp += i; + u4RemainWapiIeLen -= (int32_t) i; + + /* Parse the Group Key Cipher Suite field. */ + if (u4RemainWapiIeLen < 4) { + DBGLOG(SEC, TRACE, + "Fail to parse WAPI IE in group cipher suite (IE len: %d)\n", + prInfoElem->ucLength); + return FALSE; + } + + WLAN_GET_FIELD_32(cp, &u4GroupSuite); + cp += 4; + u4RemainWapiIeLen -= 4; + + /* Parse the WAPI u2Capabilities field. */ + if (u4RemainWapiIeLen < 2) { + DBGLOG(SEC, TRACE, + "Fail to parse WAPI IE in WAPI capabilities (IE len: %d)\n", + prInfoElem->ucLength); + return FALSE; + } + + WLAN_GET_FIELD_16(cp, &u2Cap); + u4RemainWapiIeLen -= 2; + + /* Todo:: BKID support */ + } while (FALSE); + + /* Save the WAPI information for the BSS. */ + + prWapiInfo->ucElemId = ELEM_ID_WAPI; + + prWapiInfo->u2Version = u2Version; + + prWapiInfo->u4GroupKeyCipherSuite = u4GroupSuite; + + DBGLOG(SEC, LOUD, + "WAPI: version %d, group key cipher suite %02x-%02x-%02x-%02x\n", + u2Version, (uint8_t) (u4GroupSuite & 0x000000FF), + (uint8_t) ((u4GroupSuite >> 8) & 0x000000FF), + (uint8_t) ((u4GroupSuite >> 16) & 0x000000FF), + (uint8_t) ((u4GroupSuite >> 24) & 0x000000FF)); + + if (pucPairSuite) { + /* The information about the pairwise key cipher suites + * is present. + */ + if (u2PairSuiteCount > MAX_NUM_SUPPORTED_WAPI_CIPHER_SUITES) + u2PairSuiteCount = MAX_NUM_SUPPORTED_WAPI_CIPHER_SUITES; + + prWapiInfo->u4PairwiseKeyCipherSuiteCount = + (uint32_t) u2PairSuiteCount; + + for (i = 0; i < (uint32_t) u2PairSuiteCount; i++) { + WLAN_GET_FIELD_32(pucPairSuite, + &prWapiInfo->au4PairwiseKeyCipherSuite + [i]); + pucPairSuite += 4; + + DBGLOG(SEC, LOUD, + "WAPI: pairwise key cipher suite [%d]: %02x-%02x-%02x-%02x\n", + (uint8_t) i, + (uint8_t) (prWapiInfo->au4PairwiseKeyCipherSuite + [i] & 0x000000FF), + (uint8_t) ((prWapiInfo->au4PairwiseKeyCipherSuite + [i] >> 8) & 0x000000FF), + (uint8_t) ((prWapiInfo->au4PairwiseKeyCipherSuite + [i] >> 16) & 0x000000FF), + (uint8_t) ((prWapiInfo->au4PairwiseKeyCipherSuite + [i] >> 24) & 0x000000FF)); + } + } else { + /* The information about the pairwise key cipher suites + * is not present. + * Use the default chipher suite for WAPI: WPI. + */ + prWapiInfo->u4PairwiseKeyCipherSuiteCount = 1; + prWapiInfo->au4PairwiseKeyCipherSuite[0] = + WAPI_CIPHER_SUITE_WPI; + + DBGLOG(SEC, LOUD, + "WAPI: pairwise key cipher suite: %02x-%02x-%02x-%02x (default)\n", + (uint8_t) (prWapiInfo->au4PairwiseKeyCipherSuite[0] & + 0x000000FF), + (uint8_t) ((prWapiInfo->au4PairwiseKeyCipherSuite[0] >> + 8) & 0x000000FF), + (uint8_t) ((prWapiInfo->au4PairwiseKeyCipherSuite[0] >> + 16) & 0x000000FF), + (uint8_t) ((prWapiInfo->au4PairwiseKeyCipherSuite[0] >> + 24) & 0x000000FF)); + } + + if (pucAuthSuite) { + /* The information about the authentication and + * key management suites is present. + */ + if (u2AuthSuiteCount > MAX_NUM_SUPPORTED_WAPI_AKM_SUITES) + u2AuthSuiteCount = MAX_NUM_SUPPORTED_WAPI_AKM_SUITES; + + prWapiInfo->u4AuthKeyMgtSuiteCount = + (uint32_t) u2AuthSuiteCount; + + for (i = 0; i < (uint32_t) u2AuthSuiteCount; i++) { + WLAN_GET_FIELD_32(pucAuthSuite, + &prWapiInfo->au4AuthKeyMgtSuite[i]); + pucAuthSuite += 4; + + DBGLOG(SEC, LOUD, + "WAPI: AKM suite [%d]: %02x-%02x-%02x-%02x\n", + (uint8_t) i, + (uint8_t) (prWapiInfo->au4AuthKeyMgtSuite[i] & + 0x000000FF), + (uint8_t) ((prWapiInfo->au4AuthKeyMgtSuite[i] >> + 8) & 0x000000FF), + (uint8_t) ((prWapiInfo->au4AuthKeyMgtSuite[i] >> + 16) & 0x000000FF), + (uint8_t) ((prWapiInfo->au4AuthKeyMgtSuite[i] >> + 24) & 0x000000FF)); + } + } else { + /* The information about the authentication and + * key management suites is not present. + * Use the default AKM suite for WAPI. + */ + prWapiInfo->u4AuthKeyMgtSuiteCount = 1; + prWapiInfo->au4AuthKeyMgtSuite[0] = WAPI_AKM_SUITE_802_1X; + + DBGLOG(SEC, LOUD, + "WAPI: AKM suite: %02x-%02x-%02x-%02x (default)\n", + (uint8_t) (prWapiInfo->au4AuthKeyMgtSuite[0] & + 0x000000FF), + (uint8_t) ((prWapiInfo->au4AuthKeyMgtSuite[0] >> 8) & + 0x000000FF), + (uint8_t) ((prWapiInfo->au4AuthKeyMgtSuite[0] >> 16) & + 0x000000FF), + (uint8_t) ((prWapiInfo->au4AuthKeyMgtSuite[0] >> 24) & + 0x000000FF)); + } + + prWapiInfo->u2WapiCap = u2Cap; + DBGLOG(SEC, LOUD, "WAPI: cap: 0x%04x\n", prWapiInfo->u2WapiCap); + + return TRUE; +} /* wapiParseWapiIE */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to perform WAPI policy selection for + * a given BSS. + * + * \param[in] prAdapter Pointer to the adapter object data area. + * \param[in] prBss Pointer to the BSS description + * + * \retval TRUE - The WAPI policy selection for the given BSS is + * successful. The selected pairwise and group cipher suites + * are returned in the BSS description. + * \retval FALSE - The WAPI policy selection for the given BSS is failed. + * The driver shall not attempt to join the given BSS. + * + * \note The Encrypt status matched score will save to bss for final ap select. + */ +/*----------------------------------------------------------------------------*/ +u_int8_t wapiPerformPolicySelection(IN struct ADAPTER *prAdapter, + IN struct BSS_DESC *prBss, IN uint8_t ucBssIndex) +{ + uint32_t i; + uint32_t u4PairwiseCipher = 0; + uint32_t u4GroupCipher = 0; + uint32_t u4AkmSuite = 0; + struct WAPI_INFO *prBssWapiInfo; + struct WLAN_INFO *prWlanInfo; + struct CONNECTION_SETTINGS *prConnSettings; + + DEBUGFUNC("wapiPerformPolicySelection"); + + /* Notice!!!! WAPI AP not set the privacy bit for WAI + * and WAI-PSK at WZC configuration mode + */ + prWlanInfo = &prAdapter->rWlanInfo; + + prConnSettings = + aisGetConnSettings(prAdapter, ucBssIndex); + + if (prBss->fgIEWAPI) { + prBssWapiInfo = &prBss->rIEWAPI; + } else { + if (prConnSettings->fgWapiMode == FALSE) { + DBGLOG(SEC, TRACE, "-- No Protected BSS\n"); + return TRUE; + } + DBGLOG(SEC, TRACE, + "WAPI Information Element does not exist.\n"); + return FALSE; + } + + /* Select pairwise/group ciphers */ + for (i = 0; i < prBssWapiInfo->u4PairwiseKeyCipherSuiteCount; i++) { + if (prBssWapiInfo->au4PairwiseKeyCipherSuite[i] == + prConnSettings->u4WapiSelectedPairwiseCipher) { + u4PairwiseCipher = + prBssWapiInfo->au4PairwiseKeyCipherSuite[i]; + } + } + if (prBssWapiInfo->u4GroupKeyCipherSuite == + prConnSettings->u4WapiSelectedGroupCipher) + u4GroupCipher = prBssWapiInfo->u4GroupKeyCipherSuite; + + /* Exception handler */ + /* If we cannot find proper pairwise and group cipher suites to join the + * BSS, do not check the supported AKM suites. + */ + if (u4PairwiseCipher == 0 || u4GroupCipher == 0) { + DBGLOG(SEC, TRACE, + "Failed to select pairwise/group cipher (0x%08x/0x%08x)\n", + u4PairwiseCipher, u4GroupCipher); + return FALSE; + } + + /* Select AKM */ + /* If the driver cannot support any authentication suites advertised in + * the given BSS, we fail to perform RSNA policy selection. + */ + /* Attempt to find any overlapping supported AKM suite. */ + for (i = 0; i < prBssWapiInfo->u4AuthKeyMgtSuiteCount; i++) { + if (prBssWapiInfo->au4AuthKeyMgtSuite[i] == + prConnSettings->u4WapiSelectedAKMSuite) { + u4AkmSuite = prBssWapiInfo->au4AuthKeyMgtSuite[i]; + break; + } + } + + if (u4AkmSuite == 0) { + DBGLOG(SEC, TRACE, "Cannot support any AKM suites\n"); + return FALSE; + } + + DBGLOG(SEC, TRACE, + "Selected pairwise/group cipher: %02x-%02x-%02x-%02x/%02x-%02x-%02x-%02x\n", + (uint8_t) (u4PairwiseCipher & 0x000000FF), + (uint8_t) ((u4PairwiseCipher >> 8) & 0x000000FF), + (uint8_t) ((u4PairwiseCipher >> 16) & 0x000000FF), + (uint8_t) ((u4PairwiseCipher >> 24) & 0x000000FF), + (uint8_t) (u4GroupCipher & 0x000000FF), + (uint8_t) ((u4GroupCipher >> 8) & 0x000000FF), + (uint8_t) ((u4GroupCipher >> 16) & 0x000000FF), + (uint8_t) ((u4GroupCipher >> 24) & 0x000000FF)); + + DBGLOG(SEC, TRACE, "Selected AKM suite: %02x-%02x-%02x-%02x\n", + (uint8_t) (u4AkmSuite & 0x000000FF), + (uint8_t) ((u4AkmSuite >> 8) & 0x000000FF), + (uint8_t) ((u4AkmSuite >> 16) & 0x000000FF), + (uint8_t) ((u4AkmSuite >> 24) & 0x000000FF)); + + return TRUE; +} /* wapiPerformPolicySelection */ + + +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/wmm.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/wmm.c new file mode 100644 index 0000000000000000000000000000000000000000..6b6b0e6d4d9149dce030c96c8c83579b6e764014 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/wmm.c @@ -0,0 +1,1886 @@ +/* + * Copyright (C) 2016 MediaTek Inc. + * + * This program is free software: you can redistribute it and/or modify it under + * the terms of the + * GNU General Public License version 2 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. + * + * You should have received a copy of the GNU General Public License along with + * this program. + * If not, see . + */ + +#include "precomp.h" + +static void wmmTxTspecFrame(struct ADAPTER *prAdapter, uint8_t ucTid, + enum TSPEC_OP_CODE eOpCode, + struct PARAM_QOS_TSPEC *prTsParam, + uint8_t ucBssIndex); +static void wmmSyncAcParamWithFw(struct ADAPTER *prAdapter, uint8_t ucAc, + uint16_t u2MediumTime, uint32_t u4PhyRate, uint8_t ucBssIndex); + +static void wmmGetTsmRptTimeout(struct ADAPTER *prAdapter, + unsigned long ulParam); + +static void wmmQueryTsmResult(struct ADAPTER *prAdapter, unsigned long ulParam); +static void wmmRemoveTSM(struct ADAPTER *prAdapter, + struct ACTIVE_RM_TSM_REQ *prActiveTsm, + u_int8_t fgNeedStop, + uint8_t ucBssIndex); +static struct ACTIVE_RM_TSM_REQ *wmmGetActiveTsmReq(struct ADAPTER *prAdapter, + uint8_t ucTid, + u_int8_t fgTriggered, + u_int8_t fgAllocIfNotExist, + uint8_t ucBssIndex); +static uint32_t wmmRunEventActionTxDone(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo, + enum ENUM_TX_RESULT_CODE rTxDoneStatus); +static void wmmMayDoTsReplacement(struct ADAPTER *prAdapter, + uint8_t ucNewTid, uint8_t ucBssIndex); + +#if 0 +static void DumpData(PUINT8 prAddr, UINT8 uLen, char *tag); +#endif + +#if CFG_SUPPORT_SOFT_ACM +static uint16_t wmmAcmTxTimeCal(uint16_t u2SecExtra, uint16_t u2EthBodyLen, + uint16_t u2DataRate, uint16_t u2BasicRate, + uint8_t ucFlags); + +static uint16_t wmmAcmTxTimeHtCal(uint16_t u2SecExtra, uint16_t u2EthBodyLen, + uint8_t ucMcsId, uint8_t ucFlags); + +static void wmmAcmDequeueTimeOut(IN struct ADAPTER *prAdapter, + unsigned long ulParamPtr); + +#define FLAG_S_PREAMBLE BIT(0) +#define FLAG_CTS_SELF BIT(1) +#define FLAG_RTS_CTS BIT(2) +#define FLAG_G_MODE BIT(3) +#define FLAG_SHORT_GI BIT(4) +#define FLAG_40M_BW BIT(5) +#define FLAG_GF_HT BIT(6) +#define FLAG_ONLY_DATA BIT(7) + +#define TIME_LONG_PREAMBLE 192 +#define TIME_SHORT_PREAMBLE 96 +#define TIME_SIFSG 0x10 +#define TIME_SIFS 0x0A +#define FRM_LENGTH_BLOCK_ACK 30 +#define TIME_SIFSGx2 0x20 /* support Clause 18 STA exists */ +#define TIME_SIFSx2 0x14 +#define FRM_LENGTH_RTS 0x14 +#define FRM_LENGTH_ACK 0x0E +/* aggregation related */ +#define FRM_LENGTH_AGG_AMSDU_HDR 17 +#define FRM_LENGTH_AGG_RAILNK_HDR 14 + +#define LMR_PREAMBL_TIME(__fgIsGmode, __fgIsSpreamble) \ + ({ \ + uint8_t ucTime; \ + if (__fgIsGmode) \ + ucTime = 20; \ + else \ + ucTime = __fgIsSpreamble ? TIME_SHORT_PREAMBLE \ + : TIME_LONG_PREAMBLE; \ + ucTime; \ + }) +#endif + +uint8_t const aucUp2ACIMap[8] = {ACI_BE, ACI_BK, ACI_BK, ACI_BE, + ACI_VI, ACI_VI, ACI_VO, ACI_VO}; + +void wmmInit(IN struct ADAPTER *prAdapter) +{ + uint8_t i; + + for (i = 0; i < KAL_AIS_NUM; i++) { + struct WMM_INFO *prWmmInfo = + aisGetWMMInfo(prAdapter, i); + struct TSPEC_INFO *prTspecInfo = &prWmmInfo->arTsInfo[0]; + uint8_t ucTid = 0; + + for (ucTid = 0; ucTid < WMM_TSPEC_ID_NUM; + ucTid++, prTspecInfo++) { + prTspecInfo->ucTid = ucTid; + cnmTimerInitTimer(prAdapter, + &prTspecInfo->rAddTsTimer, + (PFN_MGMT_TIMEOUT_FUNC) + wmmSetupTspecTimeOut, + (unsigned long)prTspecInfo); + } +#if CFG_SUPPORT_SOFT_ACM + cnmTimerInitTimer(prAdapter, &prWmmInfo->rAcmDeqTimer, + wmmAcmDequeueTimeOut, i); + kalMemZero(&prWmmInfo->arAcmCtrl[0], + sizeof(prWmmInfo->arAcmCtrl)); +#endif + LINK_INITIALIZE(&prWmmInfo->rActiveTsmReq); + prWmmInfo->rTriggeredTsmRptTime = 0; + } + DBGLOG(WMM, TRACE, "wmm init done\n"); +} + +void wmmUnInit(IN struct ADAPTER *prAdapter) +{ + uint8_t i; + + for (i = 0; i < KAL_AIS_NUM; i++) { + struct WMM_INFO *prWmmInfo = + aisGetWMMInfo(prAdapter, i); + struct TSPEC_INFO *prTspecInfo = &prWmmInfo->arTsInfo[0]; + uint8_t ucTid = 0; + + for (ucTid = 0; ucTid < WMM_TSPEC_ID_NUM; + ucTid++, prTspecInfo++) + cnmTimerStopTimer(prAdapter, + &prTspecInfo->rAddTsTimer); +#if CFG_SUPPORT_SOFT_ACM + cnmTimerStopTimer(prAdapter, &prWmmInfo->rAcmDeqTimer); +#endif + wmmRemoveAllTsmMeasurement(prAdapter, FALSE, i); + } + DBGLOG(WMM, TRACE, "wmm uninit done\n"); +} + +void wmmFillTsinfo(struct PARAM_QOS_TSINFO *prTsInfo, uint8_t *pucTsInfo) +{ + uint32_t u4TsInfoValue = 0; + /* | 0 |1-4 | 5-6 | 7-8 | 9 | + *10 | 11-13 | 14-23 | + ** Traffic Type|TSID| Dir |Access Policy|Reserved | PSB| UP + *|reserved| + */ + + u4TsInfoValue = prTsInfo->ucTrafficType & 0x1; + u4TsInfoValue |= (prTsInfo->ucTid & 0xf) << 1; + u4TsInfoValue |= (prTsInfo->ucDirection & 0x3) << 5; + u4TsInfoValue |= (prTsInfo->ucAccessPolicy & 0x3) << 7; + u4TsInfoValue |= (prTsInfo->ucApsd & 0x1) << 10; + u4TsInfoValue |= (prTsInfo->ucuserPriority) << 11; + u4TsInfoValue |= BIT(7); /* Fixed bit in spec */ + + pucTsInfo[0] = u4TsInfoValue & 0xFF; + pucTsInfo[1] = (u4TsInfoValue >> 8) & 0xff; + pucTsInfo[2] = (u4TsInfoValue >> 16) & 0xff; +} + +void wmmComposeTspecIE(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + struct PARAM_QOS_TSPEC *prParamQosTspec) +{ + struct IE_WMM_TSPEC *prIeWmmTspec = NULL; + uint8_t *pucTemp = NULL; + uint8_t aucWfaOui[] = VENDOR_OUI_WFA; + + prIeWmmTspec = (struct IE_WMM_TSPEC *)((uint8_t *)prMsduInfo->prPacket + + prMsduInfo->u2FrameLength); + pucTemp = prIeWmmTspec->aucTspecBodyPart; + + /*fill WMM head*/ + prIeWmmTspec->ucId = ELEM_ID_VENDOR; + prIeWmmTspec->ucLength = ELEM_MAX_LEN_WMM_TSPEC; + kalMemCopy(prIeWmmTspec->aucOui, aucWfaOui, sizeof(aucWfaOui)); + prIeWmmTspec->ucOuiType = VENDOR_OUI_TYPE_WMM; + prIeWmmTspec->ucOuiSubtype = VENDOR_OUI_SUBTYPE_WMM_TSPEC; + prIeWmmTspec->ucVersion = VERSION_WMM; + + /*fill tsinfo*/ + wmmFillTsinfo(&prParamQosTspec->rTsInfo, prIeWmmTspec->aucTsInfo); + /*1.2 BODY*/ + /*nominal size*/ + /* DumpData(prParamQosTspec, sizeof(struct PARAM_QOS_TSPEC), + ** "QosTspc"); + */ + WLAN_SET_FIELD_16(pucTemp, prParamQosTspec->u2NominalMSDUSize); + pucTemp += 2; + WLAN_SET_FIELD_16(pucTemp, prParamQosTspec->u2MaxMSDUsize); + pucTemp += 2; + WLAN_SET_FIELD_32(pucTemp, prParamQosTspec->u4MinSvcIntv); + pucTemp += 4; + WLAN_SET_FIELD_32(pucTemp, prParamQosTspec->u4MaxSvcIntv); + pucTemp += 4; + WLAN_SET_FIELD_32(pucTemp, prParamQosTspec->u4InactIntv); + pucTemp += 4; + WLAN_SET_FIELD_32(pucTemp, prParamQosTspec->u4SpsIntv); + pucTemp += 4; + WLAN_SET_FIELD_32(pucTemp, prParamQosTspec->u4SvcStartTime); + pucTemp += 4; + WLAN_SET_FIELD_32(pucTemp, prParamQosTspec->u4MinDataRate); + pucTemp += 4; + WLAN_SET_FIELD_32(pucTemp, prParamQosTspec->u4MeanDataRate); + pucTemp += 4; + WLAN_SET_FIELD_32(pucTemp, prParamQosTspec->u4PeakDataRate); + pucTemp += 4; + WLAN_SET_FIELD_32(pucTemp, prParamQosTspec->u4MaxBurstSize); + pucTemp += 4; + WLAN_SET_FIELD_32(pucTemp, prParamQosTspec->u4DelayBound); + pucTemp += 4; + WLAN_SET_FIELD_32(pucTemp, prParamQosTspec->u4MinPHYRate); + pucTemp += 4; + WLAN_SET_FIELD_16(pucTemp, prParamQosTspec->u2Sba); + pucTemp += 2; + WLAN_SET_FIELD_16(pucTemp, prParamQosTspec->u2MediumTime); + /*DumpData(prIeWmmTspec->aucTsInfo, 55, "tspec ie");*/ + + prMsduInfo->u2FrameLength += IE_SIZE(prIeWmmTspec); +} + +static uint8_t wmmNewDlgToken(void) +{ + static uint8_t sWmmDlgToken; + + return sWmmDlgToken++; +} + +/* follow WMM spec, send add/del tspec request frame */ +static void wmmTxTspecFrame(struct ADAPTER *prAdapter, uint8_t ucTid, + enum TSPEC_OP_CODE eOpCode, + struct PARAM_QOS_TSPEC *prTsParam, + uint8_t ucBssIndex) +{ + struct BSS_INFO *prBssInfo = + aisGetAisBssInfo(prAdapter, ucBssIndex); + uint16_t u2PayLoadLen = WLAN_MAC_HEADER_LEN + 4; /*exclude TSPEC IE*/ + struct STA_RECORD *prStaRec = + aisGetTargetStaRec(prAdapter, ucBssIndex); + struct MSDU_INFO *prMsduInfo = NULL; + struct WMM_ACTION_TSPEC_FRAME *prActionFrame = NULL; + uint16_t u2FrameCtrl = MAC_FRAME_ACTION; + + if (!prStaRec || !prTsParam || !prBssInfo) { + DBGLOG(WMM, ERROR, "prStaRec NULL %d, prTsParam NULL %d\n", + !prStaRec, !prTsParam); + return; + } + /*build ADDTS for TID*/ + /*1 compose Action frame Fix field*/ + DBGLOG(WMM, INFO, "Tspec Action to AP=" MACSTR "\n", + MAC2STR(prStaRec->aucMacAddr)); + + prMsduInfo = cnmMgtPktAlloc(prAdapter, ACTION_ADDTS_REQ_FRAME_LEN); + if (!prMsduInfo) { + DBGLOG(WMM, ERROR, "Failed to allocate msdu info\n"); + return; + } + TX_SET_MMPDU(prAdapter, prMsduInfo, prStaRec->ucBssIndex, + prStaRec->ucIndex, WLAN_MAC_MGMT_HEADER_LEN, u2PayLoadLen, + wmmRunEventActionTxDone, MSDU_RATE_MODE_AUTO); + + kalMemZero(prMsduInfo->prPacket, ACTION_ADDTS_REQ_FRAME_LEN); + + prActionFrame = (struct WMM_ACTION_TSPEC_FRAME *)prMsduInfo->prPacket; + + /*********frame header**********************/ + WLAN_SET_FIELD_16(&prActionFrame->u2FrameCtrl, u2FrameCtrl); + COPY_MAC_ADDR(prActionFrame->aucDestAddr, prStaRec->aucMacAddr); + COPY_MAC_ADDR(prActionFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); + COPY_MAC_ADDR(prActionFrame->aucBSSID, prStaRec->aucMacAddr); + prActionFrame->u2SeqCtrl = 0; + + /********Frame body*************/ + prActionFrame->ucCategory = + CATEGORY_WME_MGT_NOTIFICATION; /*CATEGORY_QOS_ACTION;*/ + if (eOpCode == TX_ADDTS_REQ) { + prActionFrame->ucAction = ACTION_ADDTS_REQ; + prActionFrame->ucDlgToken = (prTsParam->ucDialogToken == 0) + ? wmmNewDlgToken() + : prTsParam->ucDialogToken; + } else if (eOpCode == TX_DELTS_REQ) { + prActionFrame->ucAction = ACTION_DELTS; + prActionFrame->ucDlgToken = + 0; /* dialog token should be always 0 in delts frame */ + } + + /* this field only meanful in ADD TS response, otherwise set to 0 */ + prActionFrame->ucStatusCode = 0; + + /*DumpData((PUINT_8)prMsduInfo->prPacket,u2PayLoadLen, "ADDTS-FF");*/ + + /********Information Element *************/ + wmmComposeTspecIE(prAdapter, prMsduInfo, prTsParam); + + /******** Insert into Msdu Queue *************/ + nicTxEnqueueMsdu(prAdapter, prMsduInfo); +#if 0 + DumpData(((uint8_t *)prMsduInfo->prPacket) + u2PayLoadLen, + prMsduInfo->u2FrameLength - u2PayLoadLen, "TSPEC-IE"); +#endif +} + +void wmmSetupTspecTimeOut(struct ADAPTER *prAdapter, unsigned long ulParam) +{ + struct TSPEC_INFO *prTsInfo = (struct TSPEC_INFO *)ulParam; + + if (!prTsInfo) { + DBGLOG(WMM, INFO, "Wrong TS info\n"); + return; + } + + switch (prTsInfo->eState) { + case QOS_TS_ACTIVE: + DBGLOG(WMM, INFO, "Update TS TIMEOUT for TID %d\n", + prTsInfo->ucTid); + break; + case QOS_TS_SETUPING: + DBGLOG(WMM, INFO, "ADD TS TIMEOUT for TID %d\n", + prTsInfo->ucTid); + prTsInfo->eState = QOS_TS_INACTIVE; + break; + default: + DBGLOG(WMM, INFO, + "Shouldn't start this timer when Ts %d in state %d\n", + prTsInfo->ucTid, prTsInfo->eState); + break; + } +} + +uint8_t wmmCalculateUapsdSetting(struct ADAPTER *prAdapter, + uint8_t ucBssIndex) +{ + struct PM_PROFILE_SETUP_INFO *prPmProf = NULL; + struct WMM_INFO *prWmmInfo = + aisGetWMMInfo(prAdapter, ucBssIndex); + struct TSPEC_INFO *prCurTs; + uint8_t ucTid = 0; + uint8_t ucFinalSetting = 0; + struct BSS_INFO *prAisBssInfo; + + prAisBssInfo = + aisGetAisBssInfo(prAdapter, + ucBssIndex); + + if (!prAisBssInfo || !prWmmInfo) { + DBGLOG(WMM, INFO, "prWmmInfo is null %d\n", ucBssIndex); + return 0; + } + + prCurTs = &prWmmInfo->arTsInfo[0]; + prPmProf = &prAisBssInfo->rPmProfSetupInfo; + ucFinalSetting = + (prPmProf->ucBmpDeliveryAC << 4) | prPmProf->ucBmpTriggerAC; + for (ucTid = 0; ucTid < WMM_TSPEC_ID_NUM; ucTid++, prCurTs++) { + uint8_t ucPsd = 0; + + if (prCurTs->eState != QOS_TS_ACTIVE) + continue; + switch (prCurTs->eDir) { + case UPLINK_TS: + ucPsd = BIT(prCurTs->eAC); + break; + case DOWNLINK_TS: + ucPsd = BIT(prCurTs->eAC + 4); + break; + case BI_DIR_TS: + ucPsd = BIT(prCurTs->eAC) | BIT(prCurTs->eAC + 4); + break; + } + if (prCurTs->fgUapsd) + ucFinalSetting |= ucPsd; + else + ucFinalSetting &= ~ucPsd; + } + return ucFinalSetting; +} + +void wmmSyncAcParamWithFw(struct ADAPTER *prAdapter, uint8_t ucAc, + uint16_t u2MediumTime, uint32_t u4PhyRate, + uint8_t ucBssIndex) +{ + struct CMD_SET_WMM_PS_TEST_STRUCT rSetWmmPsTestParam; +#if CFG_SUPPORT_SOFT_ACM + struct SOFT_ACM_CTRL *prAcmCtrl = NULL; +#endif + struct CMD_UPDATE_AC_PARAMS rCmdUpdateAcParam; + struct BSS_INFO *prAisBssInfo; + struct WMM_INFO *prWmmInfo = + aisGetWMMInfo(prAdapter, ucBssIndex); + + prAisBssInfo = + aisGetAisBssInfo(prAdapter, + ucBssIndex); + ASSERT(prAisBssInfo); +#if CFG_SUPPORT_SOFT_ACM + prAcmCtrl = &prWmmInfo->arAcmCtrl[ucAc]; +/* admitted time is in unit 32-us */ +#if 0 /* UT/IT code */ + if (u2MediumTime) + u2MediumTime = 153; +#endif + prAcmCtrl->u4AdmittedTime = u2MediumTime * 32; + prAcmCtrl->u4IntervalEndSec = 0; +#endif + kalMemZero(&rCmdUpdateAcParam, sizeof(rCmdUpdateAcParam)); + rCmdUpdateAcParam.ucAcIndex = ucAc; + rCmdUpdateAcParam.ucBssIdx = prAisBssInfo->ucBssIndex; + rCmdUpdateAcParam.u2MediumTime = u2MediumTime; + rCmdUpdateAcParam.u4PhyRate = u4PhyRate; + wlanSendSetQueryCmd(prAdapter, CMD_ID_UPDATE_AC_PARMS, TRUE, FALSE, + FALSE, NULL, NULL, sizeof(struct CMD_UPDATE_AC_PARAMS), + (uint8_t *)&rCmdUpdateAcParam, NULL, 0); + kalMemZero(&rSetWmmPsTestParam, sizeof(rSetWmmPsTestParam)); + rSetWmmPsTestParam.ucBssIndex = prAisBssInfo->ucBssIndex; + rSetWmmPsTestParam.bmfgApsdEnAc = + wmmCalculateUapsdSetting(prAdapter, + prAisBssInfo->ucBssIndex); + wlanSendSetQueryCmd(prAdapter, CMD_ID_SET_WMM_PS_TEST_PARMS, TRUE, + FALSE, FALSE, NULL, NULL, + sizeof(struct CMD_SET_WMM_PS_TEST_STRUCT), + (uint8_t *)&rSetWmmPsTestParam, NULL, 0); + + DBGLOG(WMM, INFO, "Ac=%d, MediumTime=%d PhyRate=%u Uapsd 0x%02x\n", + ucAc, u2MediumTime, u4PhyRate, rSetWmmPsTestParam.bmfgApsdEnAc); +} + +/* Return: AC List in bit map if this ac has active tspec */ +uint8_t wmmHasActiveTspec(struct WMM_INFO *prWmmInfo) +{ + uint8_t ucTid = 0; + uint8_t ucACList = 0; + + if (!prWmmInfo) { + DBGLOG(WMM, INFO, "prWmmInfo is null\n"); + return 0; + } + + /* if any tspec is active, it means */ + for (; ucTid < WMM_TSPEC_ID_NUM; ucTid++) + if (prWmmInfo->arTsInfo[ucTid].eState == QOS_TS_ACTIVE) + ucACList |= 1 << prWmmInfo->arTsInfo[ucTid].eAC; + return ucACList; +} + +void wmmRunEventTSOperate(IN struct ADAPTER *prAdapter, + IN struct MSG_HDR *prMsgHdr) +{ + struct MSG_TS_OPERATE *prMsgTsOperate = + (struct MSG_TS_OPERATE *)prMsgHdr; + uint8_t ucBssIndex = prMsgTsOperate->ucBssIdx; + + wmmTspecSteps(prAdapter, prMsgTsOperate->ucTid, prMsgTsOperate->eOpCode, + (void *)&prMsgTsOperate->rTspecParam, + ucBssIndex); + cnmMemFree(prAdapter, prMsgHdr); +} + +void wmmTspecSteps(struct ADAPTER *prAdapter, uint8_t ucTid, + enum TSPEC_OP_CODE eOpCode, void *prStepParams, + uint8_t ucBssIndex) +{ + struct AIS_FSM_INFO *prAisFsmInfo = + aisGetAisFsmInfo(prAdapter, ucBssIndex); + struct WMM_INFO *prWmmInfo = + aisGetWMMInfo(prAdapter, ucBssIndex); + struct TSPEC_INFO *prCurTs = NULL; + struct BSS_INFO *prAisBssInfo = + aisGetAisBssInfo(prAdapter, ucBssIndex); + + ASSERT(prAisBssInfo); + if (prAisBssInfo->eConnectionState != + MEDIA_STATE_CONNECTED || + prAisFsmInfo->eCurrentState == AIS_STATE_DISCONNECTING) { + DBGLOG(WMM, INFO, + "ignore OP code %d when medium disconnected\n", eOpCode); + return; + } + + if (ucTid >= WMM_TSPEC_ID_NUM) { + DBGLOG(WMM, INFO, "Invalid TID %d\n", ucTid); + return; + } + + prCurTs = &prWmmInfo->arTsInfo[ucTid]; + DBGLOG(WMM, TRACE, "TID %d, State %d, Oper %d\n", ucTid, + prCurTs->eState, eOpCode); + + switch (prCurTs->eState) { + case QOS_TS_INACTIVE: { + struct PARAM_QOS_TSPEC *prQosTspec = + (struct PARAM_QOS_TSPEC *)prStepParams; + + if (eOpCode != TX_ADDTS_REQ) + break; + if (!prQosTspec) { + DBGLOG(WMM, INFO, "Lack of Tspec Param\n"); + break; + } + /*Send ADDTS req Frame*/ + wmmTxTspecFrame(prAdapter, ucTid, TX_ADDTS_REQ, prQosTspec, + ucBssIndex); + + /*start ADDTS timer*/ + cnmTimerStartTimer(prAdapter, &prCurTs->rAddTsTimer, 1000); + prCurTs->eState = QOS_TS_SETUPING; + prCurTs->eAC = aucUp2ACIMap[prQosTspec->rTsInfo.ucuserPriority]; + prCurTs->ucToken = prQosTspec->ucDialogToken; + break; + } + case QOS_TS_SETUPING: { + struct WMM_ADDTS_RSP_STEP_PARAM *prParam = + (struct WMM_ADDTS_RSP_STEP_PARAM *)prStepParams; + + if (eOpCode == TX_DELTS_REQ || eOpCode == RX_DELTS_REQ || + eOpCode == DISC_DELTS_REQ) { + cnmTimerStopTimer(prAdapter, &prCurTs->rAddTsTimer); + prCurTs->eState = QOS_TS_INACTIVE; + DBGLOG(WMM, INFO, "Del Ts %d in setuping state\n", + ucTid); + break; + } else if (eOpCode != RX_ADDTS_RSP || + prParam->ucDlgToken != + prWmmInfo->arTsInfo[ucTid].ucToken) + break; + + cnmTimerStopTimer(prAdapter, &prCurTs->rAddTsTimer); + if (prParam->ucStatusCode == WMM_TS_STATUS_ADMISSION_ACCEPTED) { + struct ACTIVE_RM_TSM_REQ *prActiveTsmReq = NULL; + + prCurTs->eState = QOS_TS_ACTIVE; + prCurTs->eDir = prParam->eDir; + prCurTs->fgUapsd = !!prParam->ucApsd; + prCurTs->u2MediumTime = prParam->u2MediumTime; + prCurTs->u4PhyRate = prParam->u4PhyRate; + wmmSyncAcParamWithFw(prAdapter, prCurTs->eAC, + prParam->u2MediumTime, + prParam->u4PhyRate, + ucBssIndex); + wmmMayDoTsReplacement(prAdapter, ucTid, ucBssIndex); + /* start pending TSM if it was requested before admitted + */ + prActiveTsmReq = wmmGetActiveTsmReq(prAdapter, ucTid, + TRUE, FALSE, ucBssIndex); + if (prActiveTsmReq) + wmmStartTsmMeasurement( + prAdapter, (unsigned long)prActiveTsmReq + ->prTsmReq, + ucBssIndex); + prActiveTsmReq = wmmGetActiveTsmReq(prAdapter, ucTid, + FALSE, FALSE, ucBssIndex); + if (prActiveTsmReq) + wmmStartTsmMeasurement( + prAdapter, (unsigned long)prActiveTsmReq + ->prTsmReq, + ucBssIndex); + + /* nicTxChangeDataPortByAc( + ** prAisBssInfo->prStaRecOfAP, + ** prCurTs->eAC, TRUE); + */ + } else { + prCurTs->eState = QOS_TS_INACTIVE; + DBGLOG(WMM, ERROR, "ADD TS is rejected, status=%d\n", + prParam->ucStatusCode); + } + break; + } + case QOS_TS_ACTIVE: { + struct ACTIVE_RM_TSM_REQ *prActiveTsm = NULL; + + switch (eOpCode) { + case TX_DELTS_REQ: + case RX_DELTS_REQ: + case DISC_DELTS_REQ: + prActiveTsm = wmmGetActiveTsmReq(prAdapter, ucTid, TRUE, + FALSE, ucBssIndex); + if (prActiveTsm) + wmmRemoveTSM(prAdapter, prActiveTsm, TRUE, + ucBssIndex); + prActiveTsm = wmmGetActiveTsmReq(prAdapter, ucTid, + FALSE, FALSE, ucBssIndex); + if (prActiveTsm) + wmmRemoveTSM(prAdapter, prActiveTsm, TRUE, + ucBssIndex); + prCurTs->eState = QOS_TS_INACTIVE; +#if CFG_SUPPORT_SOFT_ACM + /* Need to change tx queue, due to we do soft ACM */ + qmHandleDelTspec(prAdapter, + prAisFsmInfo->prTargetStaRec, + prCurTs->eAC); +#endif + wmmSyncAcParamWithFw(prAdapter, prCurTs->eAC, 0, 0, + ucBssIndex); + wmmDumpActiveTspecs(prAdapter, NULL, 0, + ucBssIndex); + if (eOpCode == TX_DELTS_REQ) + wmmTxTspecFrame( + prAdapter, ucTid, TX_DELTS_REQ, + (struct PARAM_QOS_TSPEC *)prStepParams, + ucBssIndex); + break; + case TX_ADDTS_REQ: + /*Send ADDTS req Frame*/ + wmmTxTspecFrame(prAdapter, ucTid, TX_ADDTS_REQ, + (struct PARAM_QOS_TSPEC *)prStepParams, + ucBssIndex); + prCurTs->eAC = + aucUp2ACIMap[((struct PARAM_QOS_TSPEC *) + prStepParams) + ->rTsInfo.ucuserPriority]; + prCurTs->ucToken = + ((struct PARAM_QOS_TSPEC *)prStepParams) + ->ucDialogToken; + /*start ADDTS timer*/ + cnmTimerStartTimer(prAdapter, &prCurTs->rAddTsTimer, + 1000); + break; + /* for case: TS of tid N has existed, then setup TS with this + ** tid again. + */ + case RX_ADDTS_RSP: { + struct WMM_ADDTS_RSP_STEP_PARAM *prParam = + (struct WMM_ADDTS_RSP_STEP_PARAM *)prStepParams; + + if (prParam->ucStatusCode != + WMM_TS_STATUS_ADMISSION_ACCEPTED) { + DBGLOG(WMM, INFO, + "Update TS %d request was rejected by BSS\n", + ucTid); + break; + } + prCurTs->eDir = prParam->eDir; + prCurTs->fgUapsd = !!prParam->ucApsd; + prCurTs->u2MediumTime = prParam->u2MediumTime; + prCurTs->u4PhyRate = prParam->u4PhyRate; + wmmSyncAcParamWithFw(prAdapter, prCurTs->eAC, + prParam->u2MediumTime, + prParam->u4PhyRate, + ucBssIndex); + wmmMayDoTsReplacement(prAdapter, ucTid, ucBssIndex); + break; + } + default: + break; + } + break; + } + default: + break; + } +} + +static uint32_t wmmRunEventActionTxDone(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo, + enum ENUM_TX_RESULT_CODE rTxDoneStatus) +{ + DBGLOG(WMM, INFO, "Status %d\n", rTxDoneStatus); + return WLAN_STATUS_SUCCESS; +} + +void DumpData(uint8_t *prAddr, uint8_t uLen, char *tag) +{ + uint16_t k = 0; + char buf[16 * 3 + 1]; + uint16_t loop = 0; + uint8_t *p = prAddr; + static char const charmap[16] = {'0', '1', '2', '3', '4', '5', + '6', '7', '8', '9', 'A', 'B', + 'C', 'D', 'E', 'F'}; + + uLen = (uLen > 128) ? 128 : uLen; + loop = uLen / 16; + if (tag) + DBGLOG(WMM, INFO, "++++++++ dump data \"%s\" p=%p len=%d\n", + tag, prAddr, uLen); + else + DBGLOG(WMM, INFO, "++++++ dump data p=%p, len=%d\n", prAddr, + uLen); + + while (loop) { + for (k = 0; k < 16; k++) { + buf[k * 3] = charmap[((*(p + k) & 0xF0) >> 4)]; + buf[k * 3 + 1] = charmap[(*(p + k) & 0x0F)]; + buf[k * 3 + 2] = ' '; + } + buf[16 * 3] = 0; + DBGLOG(WMM, INFO, "%s\n", buf); + loop--; + p += 16; + } + uLen = uLen % 16; + k = 0; + while (uLen) { + buf[k * 3] = charmap[((*(p + k) & 0xF0) >> 4)]; + buf[k * 3 + 1] = charmap[(*(p + k) & 0x0F)]; + buf[k * 3 + 2] = ' '; + k++; + uLen--; + } + buf[k * 3] = 0; + DBGLOG(WMM, INFO, "%s\n", buf); + DBGLOG(WMM, INFO, "====== end dump data\n"); +} + +/* TSM related */ +static void wmmQueryTsmResult(struct ADAPTER *prAdapter, + unsigned long ulParam) +{ + uint8_t ucBssIndex = + ((struct ACTIVE_RM_TSM_REQ *)ulParam)->ucBssIdx; + struct RM_TSM_REQ *prTsmReq = + ((struct ACTIVE_RM_TSM_REQ *)ulParam)->prTsmReq; + struct WMM_INFO *prWmmInfo = + aisGetWMMInfo(prAdapter, ucBssIndex); + struct CMD_GET_TSM_STATISTICS rGetTsmStatistics; + + DBGLOG(WMM, INFO, "[%d] Query TSM statistics, tid = %d\n", + ucBssIndex, + prTsmReq->ucTID); + DBGLOG(WMM, INFO, "%p , aci %d, duration %d\n", prTsmReq, + prTsmReq->ucACI, prTsmReq->u2Duration); + + rGetTsmStatistics.ucBssIdx = ucBssIndex; + rGetTsmStatistics.ucAcIndex = prTsmReq->ucACI; + rGetTsmStatistics.ucTid = prTsmReq->ucTID; + COPY_MAC_ADDR(rGetTsmStatistics.aucPeerAddr, prTsmReq->aucPeerAddr); + + wlanSendSetQueryCmd(prAdapter, CMD_ID_GET_TSM_STATISTICS, FALSE, TRUE, + FALSE, wmmComposeTsmRpt, NULL, + sizeof(struct CMD_GET_TSM_STATISTICS), + (uint8_t *)&rGetTsmStatistics, NULL, 0); + cnmTimerInitTimer(prAdapter, &prWmmInfo->rTsmTimer, + wmmGetTsmRptTimeout, + ulParam); + cnmTimerStartTimer(prAdapter, &prWmmInfo->rTsmTimer, 2000); + +} + +static struct ACTIVE_RM_TSM_REQ *wmmGetActiveTsmReq(struct ADAPTER *prAdapter, + uint8_t ucTid, + u_int8_t fgTriggered, + u_int8_t fgAllocIfNotExist, + uint8_t ucBssIndex) +{ + struct WMM_INFO *prWMMInfo = + aisGetWMMInfo(prAdapter, ucBssIndex); + struct ACTIVE_RM_TSM_REQ *prActiveReq = NULL; + u_int8_t fgFound = FALSE; + + LINK_FOR_EACH_ENTRY(prActiveReq, &prWMMInfo->rActiveTsmReq, rLinkEntry, + struct ACTIVE_RM_TSM_REQ) + { + if ((!!prActiveReq->prTsmReq->u2Duration) == fgTriggered && + ucTid == prActiveReq->prTsmReq->ucTID) { + fgFound = TRUE; + break; + } + } + if (!fgFound && fgAllocIfNotExist) { + fgFound = TRUE; + prActiveReq = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, + sizeof(struct ACTIVE_RM_TSM_REQ)); + if (!prActiveReq) + return NULL; + LINK_INSERT_TAIL(&prWMMInfo->rActiveTsmReq, + &prActiveReq->rLinkEntry); + } + return fgFound ? prActiveReq : NULL; +} + +static void wmmRemoveTSM(struct ADAPTER *prAdapter, + struct ACTIVE_RM_TSM_REQ *prActiveTsm, + u_int8_t fgNeedStop, + uint8_t ucBssIndex) +{ + struct WMM_INFO *prWMMInfo = + aisGetWMMInfo(prAdapter, ucBssIndex); + struct LINK *prActiveTsmLink = &prWMMInfo->rActiveTsmReq; + + LINK_REMOVE_KNOWN_ENTRY(prActiveTsmLink, prActiveTsm); + if (fgNeedStop) { + struct CMD_SET_TSM_STATISTICS_REQUEST rTsmStatistics; + struct STA_RECORD *prStaRec = NULL; + struct BSS_INFO *prAisBssInfo; + + prAisBssInfo = + aisGetAisBssInfo(prAdapter, + ucBssIndex); + if (!prAisBssInfo) { + DBGLOG(WMM, ERROR, "prAisBssInfo is NULL\n"); + return; + } + prStaRec = prAisBssInfo->prStaRecOfAP; + nicTxChangeDataPortByAc(prAdapter, + prStaRec, + prActiveTsm->prTsmReq->ucACI, + FALSE); + rTsmStatistics.ucBssIdx = prAisBssInfo->ucBssIndex; + rTsmStatistics.ucEnabled = FALSE; + rTsmStatistics.ucAcIndex = prActiveTsm->prTsmReq->ucACI; + rTsmStatistics.ucTid = prActiveTsm->prTsmReq->ucTID; + COPY_MAC_ADDR(rTsmStatistics.aucPeerAddr, + prActiveTsm->prTsmReq->aucPeerAddr); + wlanSendSetQueryCmd(prAdapter, + CMD_ID_SET_TSM_STATISTICS_REQUEST, TRUE, + FALSE, FALSE, NULL, NULL, + sizeof(struct CMD_SET_TSM_STATISTICS_REQUEST), + (uint8_t *)&rTsmStatistics, NULL, 0); + } + cnmMemFree(prAdapter, prActiveTsm->prTsmReq); + cnmMemFree(prAdapter, prActiveTsm); +} + +void wmmStartTsmMeasurement(struct ADAPTER *prAdapter, unsigned long ulParam, + uint8_t ucBssIndex) +{ + struct WMM_INFO *prWMMInfo = + aisGetWMMInfo(prAdapter, ucBssIndex); + struct CMD_SET_TSM_STATISTICS_REQUEST rTsmStatistics; + struct RM_TSM_REQ *prTsmReq = (struct RM_TSM_REQ *)ulParam; + uint8_t ucTid = prTsmReq->ucTID; + struct ACTIVE_RM_TSM_REQ *prActiveTsmReq = NULL; + struct STA_RECORD *prStaRec = NULL; + struct TSPEC_INFO *prCurTs = NULL; + struct BSS_INFO *prAisBssInfo; + + prAisBssInfo = + aisGetAisBssInfo(prAdapter, ucBssIndex); + + ASSERT(prAisBssInfo); + if (!prTsmReq->u2Duration && + !(prTsmReq->rTriggerCond.ucCondition & TSM_TRIGGER_CONDITION_ALL)) { + DBGLOG(WMM, WARN, "Duration is %d, Trigger Condition %d\n", + prTsmReq->u2Duration, + prTsmReq->rTriggerCond.ucCondition); + cnmMemFree(prAdapter, prTsmReq); + rrmScheduleNextRm(prAdapter, + ucBssIndex); + return; + } + prStaRec = prAisBssInfo->prStaRecOfAP; + if (!prStaRec) { + DBGLOG(WMM, INFO, "No station record found for "MACSTR"\n", + MAC2STR(prTsmReq->aucPeerAddr)); + cnmMemFree(prAdapter, prTsmReq); + rrmScheduleNextRm(prAdapter, + ucBssIndex); + return; + } + /* if there's a active tspec, then TID means TS ID */ + prCurTs = &prWMMInfo->arTsInfo[ucTid]; + if (prCurTs->eState == QOS_TS_ACTIVE) + prTsmReq->ucACI = prCurTs->eAC; + else { /* otherwise TID means TC ID */ + uint8_t ucTsAcs = wmmHasActiveTspec(prWMMInfo); + + prTsmReq->ucACI = aucUp2ACIMap[ucTid]; + /* if current TID is not admitted, don't start measurement, only + ** save this requirement + */ + if (prStaRec->afgAcmRequired[prTsmReq->ucACI] && + !(ucTsAcs & BIT(prTsmReq->ucACI))) { + DBGLOG(WMM, INFO, + "ACM is set for UP %d, but No tspec is setup\n", + ucTid); + rrmScheduleNextRm(prAdapter, + ucBssIndex); + return; + } + } + + kalMemZero(&rTsmStatistics, sizeof(rTsmStatistics)); + if (prTsmReq->u2Duration) { + /* If a non-AP QoS STa receives a Transmit Stream/Category + *Measurement Request for a TC, or + ** TS that is already being measured using a triggered transmit + *stream/category measurement, + ** the triggered traffic stream measurement shall be suspended + *for the duration of the requested + ** traffic stream measurement. When triggered measurement + *resumes, the traffic stream metrics + ** shall be reset. See end part of 802.11k 11.10.8.8 + **/ + LINK_FOR_EACH_ENTRY(prActiveTsmReq, &prWMMInfo->rActiveTsmReq, + rLinkEntry, struct ACTIVE_RM_TSM_REQ) + { + if (prActiveTsmReq->prTsmReq->u2Duration || + prActiveTsmReq->prTsmReq->ucACI != prTsmReq->ucACI) + continue; + nicTxChangeDataPortByAc( + prAdapter, + prStaRec, + prTsmReq->ucACI, + FALSE); + rTsmStatistics.ucBssIdx = + ucBssIndex; + rTsmStatistics.ucEnabled = FALSE; + rTsmStatistics.ucAcIndex = prTsmReq->ucACI; + rTsmStatistics.ucTid = prActiveTsmReq->prTsmReq->ucTID; + COPY_MAC_ADDR(rTsmStatistics.aucPeerAddr, + prActiveTsmReq->prTsmReq->aucPeerAddr); + wlanSendSetQueryCmd( + prAdapter, CMD_ID_SET_TSM_STATISTICS_REQUEST, + TRUE, FALSE, FALSE, NULL, NULL, + sizeof(struct CMD_SET_TSM_STATISTICS_REQUEST), + (uint8_t *)&rTsmStatistics, NULL, 0); + } + prActiveTsmReq = wmmGetActiveTsmReq( + prAdapter, ucTid, !!prTsmReq->u2Duration, TRUE, + ucBssIndex); + /* if exist normal tsm on the same ts, replace it */ + if (prActiveTsmReq->prTsmReq) + cnmMemFree(prAdapter, prActiveTsmReq->prTsmReq); + DBGLOG(WMM, INFO, "%p tid %d, aci %d, duration %d\n", prTsmReq, + prTsmReq->ucTID, prTsmReq->ucACI, prTsmReq->u2Duration); + prActiveTsmReq->ucBssIdx = ucBssIndex; + cnmTimerInitTimer(prAdapter, &prWMMInfo->rTsmTimer, + wmmQueryTsmResult, + (unsigned long)prActiveTsmReq); + cnmTimerStartTimer(prAdapter, &prWMMInfo->rTsmTimer, + TU_TO_MSEC(prTsmReq->u2Duration)); + } else { + prActiveTsmReq = wmmGetActiveTsmReq( + prAdapter, ucTid, !prTsmReq->u2Duration, TRUE, + ucBssIndex); + /* if exist triggered tsm on the same ts, replace it */ + if (prActiveTsmReq->prTsmReq) { + cnmTimerStopTimer(prAdapter, + &prActiveTsmReq->rTsmTimer); + cnmMemFree(prAdapter, prActiveTsmReq->prTsmReq); + } + rTsmStatistics.ucTriggerCondition = + prTsmReq->rTriggerCond.ucCondition; + rTsmStatistics.ucMeasureCount = + prTsmReq->rTriggerCond.ucMeasureCount; + rTsmStatistics.ucTriggerTimeout = + prTsmReq->rTriggerCond.ucTriggerTimeout; + rTsmStatistics.ucAvgErrThreshold = + prTsmReq->rTriggerCond.ucAvgErrThreshold; + rTsmStatistics.ucConsecutiveErrThreshold = + prTsmReq->rTriggerCond.ucConsecutiveErr; + rTsmStatistics.ucDelayThreshold = + prTsmReq->rTriggerCond.ucDelayThreshold; + rTsmStatistics.ucBin0Range = prTsmReq->ucB0Range; + } + nicTxChangeDataPortByAc(prAdapter, prStaRec, prTsmReq->ucACI, TRUE); + prActiveTsmReq->prTsmReq = prTsmReq; + rTsmStatistics.ucBssIdx = ucBssIndex; + rTsmStatistics.ucAcIndex = prTsmReq->ucACI; + rTsmStatistics.ucTid = prTsmReq->ucTID; + rTsmStatistics.ucEnabled = TRUE; + COPY_MAC_ADDR(rTsmStatistics.aucPeerAddr, prTsmReq->aucPeerAddr); + DBGLOG(WMM, INFO, "enabled=%d, tid=%d\n", rTsmStatistics.ucEnabled, + ucTid); + wlanSendSetQueryCmd(prAdapter, CMD_ID_SET_TSM_STATISTICS_REQUEST, TRUE, + FALSE, FALSE, NULL, NULL, + sizeof(struct CMD_SET_TSM_STATISTICS_REQUEST), + (uint8_t *)&rTsmStatistics, NULL, 0); +} + +void wmmRemoveAllTsmMeasurement(struct ADAPTER *prAdapter, + u_int8_t fgOnlyTriggered, uint8_t ucBssIndex) +{ + struct WMM_INFO *prWmmInfo = + aisGetWMMInfo(prAdapter, ucBssIndex); + struct LINK *prActiveTsmLink = + &prWmmInfo->rActiveTsmReq; + struct ACTIVE_RM_TSM_REQ *prActiveTsm = NULL; + struct ACTIVE_RM_TSM_REQ *prHead = LINK_PEEK_HEAD( + prActiveTsmLink, struct ACTIVE_RM_TSM_REQ, rLinkEntry); + u_int8_t fgFinished = FALSE; + + if (!fgOnlyTriggered) + cnmTimerStopTimer(prAdapter, + &prWmmInfo->rTsmTimer); + do { + prActiveTsm = LINK_PEEK_TAIL( + prActiveTsmLink, struct ACTIVE_RM_TSM_REQ, rLinkEntry); + if (!prActiveTsm) + break; + if (prActiveTsm == prHead) + fgFinished = TRUE; + if (fgOnlyTriggered && prActiveTsm->prTsmReq->u2Duration) + continue; + wmmRemoveTSM(prAdapter, prActiveTsm, TRUE, ucBssIndex); + } while (!fgFinished); + prWmmInfo->rTriggeredTsmRptTime = 0; +} + +u_int8_t wmmParseQosAction(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb) +{ + struct WLAN_ACTION_FRAME *prWlanActionFrame = NULL; + uint8_t *pucIE = NULL; + struct PARAM_QOS_TSPEC rTspec; + uint16_t u2Offset = 0; + uint16_t u2IEsBufLen = 0; + uint8_t ucTid = WMM_TSPEC_ID_NUM; + struct WMM_ADDTS_RSP_STEP_PARAM rStepParam; + u_int8_t ret = FALSE; + uint8_t ucBssIndex = secGetBssIdxByRfb(prAdapter, + prSwRfb); + + prWlanActionFrame = (struct WLAN_ACTION_FRAME *)prSwRfb->pvHeader; + DBGLOG(WMM, INFO, "[%d] Action=%d\n", + ucBssIndex, + prWlanActionFrame->ucAction); + switch (prWlanActionFrame->ucAction) { + case ACTION_ADDTS_RSP: { + kalMemZero(&rStepParam, sizeof(rStepParam)); + if (prWlanActionFrame->ucCategory == + CATEGORY_WME_MGT_NOTIFICATION) { + struct WMM_ACTION_TSPEC_FRAME *prAddTsRsp = + (struct WMM_ACTION_TSPEC_FRAME *) + prWlanActionFrame; + + rStepParam.ucDlgToken = prAddTsRsp->ucDlgToken; + rStepParam.ucStatusCode = prAddTsRsp->ucStatusCode; + pucIE = (uint8_t *)prAddTsRsp->aucInfoElem; + } else if (prWlanActionFrame->ucCategory == + CATEGORY_QOS_ACTION) { + struct ACTION_ADDTS_RSP_FRAME *prAddTsRsp = + (struct ACTION_ADDTS_RSP_FRAME *) + prWlanActionFrame; + + rStepParam.ucDlgToken = prAddTsRsp->ucDialogToken; + rStepParam.ucStatusCode = prAddTsRsp->ucStatusCode; + pucIE = (uint8_t *)prAddTsRsp->aucInfoElem; + } else { + DBGLOG(WMM, INFO, + "Not supported category %d for action %d\n", + prWlanActionFrame->ucCategory, + prWlanActionFrame->ucAction); + break; + } + + /*for each IE*/ + u2IEsBufLen = + prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen - + (uint16_t)(OFFSET_OF(struct ACTION_ADDTS_RSP_FRAME, + aucInfoElem) - + WLAN_MAC_HEADER_LEN); + + IE_FOR_EACH(pucIE, u2IEsBufLen, u2Offset) + { + switch (IE_ID(pucIE)) { + case ELEM_ID_TSPEC: + case ELEM_ID_VENDOR: + if (wmmParseTspecIE(prAdapter, pucIE, + &rTspec)) { + rStepParam.u2MediumTime = + rTspec.u2MediumTime; + ucTid = rTspec.rTsInfo.ucTid; + rStepParam.eDir = + rTspec.rTsInfo.ucDirection; + rStepParam.u4PhyRate = + rTspec.u4MinPHYRate; + rStepParam.ucApsd = + rTspec.rTsInfo.ucApsd; + } else { + DBGLOG(WMM, INFO, + "can't parse Tspec IE?!\n"); + } + break; + default: + break; + } + } + wmmTspecSteps(prAdapter, ucTid, RX_ADDTS_RSP, &rStepParam, + ucBssIndex); + ret = TRUE; + break; + } + case ACTION_DELTS: { + if (prWlanActionFrame->ucCategory == + CATEGORY_WME_MGT_NOTIFICATION) { + /* wmm Tspec */ + struct WMM_ACTION_TSPEC_FRAME *prDelTs = + (struct WMM_ACTION_TSPEC_FRAME *) + prWlanActionFrame; + + u2IEsBufLen = prSwRfb->u2PacketLen - + (uint16_t)OFFSET_OF( + struct WMM_ACTION_TSPEC_FRAME, + aucInfoElem); + u2Offset = 0; + pucIE = prDelTs->aucInfoElem; + IE_FOR_EACH(pucIE, u2IEsBufLen, u2Offset) + { + if (!wmmParseTspecIE(prAdapter, pucIE, &rTspec)) + continue; + ucTid = rTspec.rTsInfo.ucTid; + break; + } + } else if (prWlanActionFrame->ucCategory == + CATEGORY_QOS_ACTION) { + /* IEEE 802.11 Tspec */ + struct ACTION_DELTS_FRAME *prDelTs = + (struct ACTION_DELTS_FRAME *)prWlanActionFrame; + + ucTid = WMM_TSINFO_TSID(prDelTs->aucTsInfo[0]); + } + + wmmTspecSteps(prAdapter, ucTid, RX_DELTS_REQ, NULL, + ucBssIndex); + ret = TRUE; + break; + } + default: + break; + } + return ret; +} + +u_int8_t wmmParseTspecIE(struct ADAPTER *prAdapter, uint8_t *pucIE, + struct PARAM_QOS_TSPEC *prTspec) +{ + uint32_t u4TsInfoValue = 0; + uint8_t *pucTemp = NULL; + + if (IE_ID(pucIE) == ELEM_ID_TSPEC) { + DBGLOG(WMM, INFO, "found 802.11 Tspec Information Element\n"); + /* todo: implement 802.11 Tspec here, assign value to + ** u4TsInfoValue and pucTemp + */ + u4TsInfoValue = 0; + pucTemp = NULL; + return FALSE; /* we didn't support IEEE 802.11 Tspec now */ + } + { + struct IE_WMM_TSPEC *prIeWmmTspec = + (struct IE_WMM_TSPEC *)pucIE; + uint8_t aucWfaOui[] = VENDOR_OUI_WFA; + + /* WMM TSPEC length */ + if (prIeWmmTspec->ucLength < ELEM_MAX_LEN_WMM_TSPEC) { + DBGLOG(WMM, INFO, "Abnormal IE length\n"); + return FALSE; + } + + if (prIeWmmTspec->ucId != ELEM_ID_VENDOR || + kalMemCmp(prIeWmmTspec->aucOui, aucWfaOui, + sizeof(aucWfaOui)) || + prIeWmmTspec->ucOuiType != VENDOR_OUI_TYPE_WMM || + prIeWmmTspec->ucOuiSubtype != + VENDOR_OUI_SUBTYPE_WMM_TSPEC) { + return FALSE; + } + u4TsInfoValue |= prIeWmmTspec->aucTsInfo[0]; + u4TsInfoValue |= (prIeWmmTspec->aucTsInfo[1] << 8); + u4TsInfoValue |= (prIeWmmTspec->aucTsInfo[2] << 16); + pucTemp = prIeWmmTspec->aucTspecBodyPart; + } + + prTspec->rTsInfo.ucTrafficType = WMM_TSINFO_TRAFFIC_TYPE(u4TsInfoValue); + prTspec->rTsInfo.ucTid = WMM_TSINFO_TSID(u4TsInfoValue); + prTspec->rTsInfo.ucDirection = WMM_TSINFO_DIR(u4TsInfoValue); + prTspec->rTsInfo.ucAccessPolicy = WMM_TSINFO_AC(u4TsInfoValue); + prTspec->rTsInfo.ucApsd = WMM_TSINFO_PSB(u4TsInfoValue); + prTspec->rTsInfo.ucuserPriority = WMM_TSINFO_UP(u4TsInfoValue); + + /* nominal size*/ + WLAN_GET_FIELD_16(pucTemp, &prTspec->u2NominalMSDUSize); + pucTemp += 2; + WLAN_GET_FIELD_16(pucTemp, &prTspec->u2MaxMSDUsize); + pucTemp += 2; + WLAN_GET_FIELD_32(pucTemp, &prTspec->u4MinSvcIntv); + pucTemp += 4; + WLAN_GET_FIELD_32(pucTemp, &prTspec->u4MaxSvcIntv); + pucTemp += 4; + WLAN_GET_FIELD_32(pucTemp, &prTspec->u4InactIntv); + pucTemp += 4; + WLAN_GET_FIELD_32(pucTemp, &prTspec->u4SpsIntv); + pucTemp += 4; + WLAN_GET_FIELD_32(pucTemp, &prTspec->u4SvcStartTime); + pucTemp += 4; + WLAN_GET_FIELD_32(pucTemp, &prTspec->u4MinDataRate); + pucTemp += 4; + WLAN_GET_FIELD_32(pucTemp, &prTspec->u4MeanDataRate); + pucTemp += 4; + WLAN_GET_FIELD_32(pucTemp, &prTspec->u4PeakDataRate); + pucTemp += 4; + WLAN_GET_FIELD_32(pucTemp, &prTspec->u4MaxBurstSize); + pucTemp += 4; + WLAN_GET_FIELD_32(pucTemp, &prTspec->u4DelayBound); + pucTemp += 4; + WLAN_GET_FIELD_32(pucTemp, &prTspec->u4MinPHYRate); + pucTemp += 4; + WLAN_GET_FIELD_16(pucTemp, &prTspec->u2Sba); + pucTemp += 2; + WLAN_GET_FIELD_16(pucTemp, &prTspec->u2MediumTime); + pucTemp += 2; + ASSERT((pucTemp == (IE_SIZE(pucIE) + pucIE))); + DBGLOG(WMM, INFO, "TsId=%d, TrafficType=%d, PSB=%d, MediumTime=%d\n", + prTspec->rTsInfo.ucTid, prTspec->rTsInfo.ucTrafficType, + prTspec->rTsInfo.ucApsd, prTspec->u2MediumTime); + return TRUE; +} + +static void wmmGetTsmRptTimeout(struct ADAPTER *prAdapter, + unsigned long ulParam) +{ + uint8_t ucBssIndex = + ((struct ACTIVE_RM_TSM_REQ *)ulParam)->ucBssIdx; + DBGLOG(WMM, ERROR, + "[%d] timeout to get Tsm Rpt from firmware\n", ucBssIndex); + wlanReleasePendingCmdById(prAdapter, CMD_ID_GET_TSM_STATISTICS); + wmmRemoveTSM(prAdapter, (struct ACTIVE_RM_TSM_REQ *)ulParam, TRUE, + ucBssIndex); + /* schedule next measurement after a duration based TSM done */ + rrmStartNextMeasurement(prAdapter, FALSE, ucBssIndex); +} + +void wmmComposeTsmRpt(struct ADAPTER *prAdapter, struct CMD_INFO *prCmdInfo, + uint8_t *pucEventBuf) +{ + struct CMD_GET_TSM_STATISTICS *prTsmStatistic = + (struct CMD_GET_TSM_STATISTICS *)pucEventBuf; + uint8_t ucBssIndex = prTsmStatistic->ucBssIdx; + struct RADIO_MEASUREMENT_REPORT_PARAMS *prRmRep = + aisGetRmReportParam(prAdapter, ucBssIndex); + struct IE_MEASUREMENT_REPORT *prTsmRpt = NULL; + struct RM_TSM_REPORT *prTsmRptField = NULL; + uint16_t u2IeSize = + OFFSET_OF(struct IE_MEASUREMENT_REPORT, aucReportFields) + + sizeof(*prTsmRptField); + struct ACTIVE_RM_TSM_REQ *prCurrentTsmReq = NULL; + struct WMM_INFO *prWMMInfo = + aisGetWMMInfo(prAdapter, ucBssIndex); + struct BSS_INFO *prAisBssInfo = + aisGetAisBssInfo(prAdapter, ucBssIndex); + + if (!prAisBssInfo) { + DBGLOG(WMM, ERROR, "prAisBssInfo is NULL\n"); + return; + } + prCurrentTsmReq = + wmmGetActiveTsmReq(prAdapter, prTsmStatistic->ucTid, + !prTsmStatistic->ucReportReason, FALSE, + ucBssIndex); + /* prCmdInfo is not NULL or report reason is 0 means it is a command + ** reply, so we need to stop the timer + */ + if (prCmdInfo || !prTsmStatistic->ucReportReason) + cnmTimerStopTimer(prAdapter, &prWMMInfo->rTsmTimer); + if (!prCurrentTsmReq) { + DBGLOG(WMM, ERROR, "unexpected Tsm statistic event, tid %d\n", + prTsmStatistic->ucTid); + /* schedule next measurement after a duration based TSM done */ + rrmScheduleNextRm(prAdapter, + ucBssIndex); + return; + } + + /* Put the report IE into report frame */ + if (u2IeSize + prRmRep->u2ReportFrameLen > RM_REPORT_FRAME_MAX_LENGTH) + rrmTxRadioMeasurementReport(prAdapter, ucBssIndex); + + DBGLOG(WMM, INFO, "tid %d, aci %d\n", prCurrentTsmReq->prTsmReq->ucTID, + prCurrentTsmReq->prTsmReq->ucACI); + prTsmRpt = + (struct IE_MEASUREMENT_REPORT *)(prRmRep->pucReportFrameBuff + + prRmRep->u2ReportFrameLen); + prTsmRpt->ucId = ELEM_ID_MEASUREMENT_REPORT; + prTsmRpt->ucToken = prCurrentTsmReq->prTsmReq->ucToken; + prTsmRpt->ucMeasurementType = ELEM_RM_TYPE_TSM_REPORT; + prTsmRpt->ucReportMode = 0; + prTsmRpt->ucLength = u2IeSize - 2; + prTsmRptField = (struct RM_TSM_REPORT *)&prTsmRpt->aucReportFields[0]; + prTsmRptField->u8ActualStartTime = prTsmStatistic->u8StartTime; + prTsmRptField->u2Duration = prCurrentTsmReq->prTsmReq->u2Duration; + COPY_MAC_ADDR(prTsmRptField->aucPeerAddress, + prTsmStatistic->aucPeerAddr); + /* TID filed: bit0~bit3 reserved, bit4~bit7: real tid */ + prTsmRptField->ucTID = (prCurrentTsmReq->prTsmReq->ucTID & 0xf) << 4; + prTsmRptField->ucReason = prTsmStatistic->ucReportReason; + prTsmRptField->u4TransmittedMsduCnt = prTsmStatistic->u4PktTxDoneOK; + prTsmRptField->u4DiscardedMsduCnt = prTsmStatistic->u4PktDiscard; + prTsmRptField->u4FailedMsduCnt = prTsmStatistic->u4PktFail; + prTsmRptField->u4MultiRetryCnt = prTsmStatistic->u4PktRetryTxDoneOK; + prTsmRptField->u4CfPollLostCnt = prTsmStatistic->u4PktQosCfPollLost; + prTsmRptField->u4AvgQueDelay = prTsmStatistic->u4AvgPktQueueDelay; + prTsmRptField->u4AvgDelay = prTsmStatistic->u4AvgPktTxDelay; + prTsmRptField->ucBin0Range = prCurrentTsmReq->prTsmReq->ucB0Range; + kalMemCopy(&prTsmRptField->u4Bin[0], &prTsmStatistic->au4PktCntBin[0], + sizeof(prTsmStatistic->au4PktCntBin)); + prRmRep->u2ReportFrameLen += u2IeSize; + /* For normal TSM, only once measurement */ + if (prCurrentTsmReq->prTsmReq->u2Duration) { + struct RM_TSM_REQ *prTsmReq = NULL; + struct CMD_SET_TSM_STATISTICS_REQUEST rTsmStatistics; + + wmmRemoveTSM(prAdapter, prCurrentTsmReq, FALSE, ucBssIndex); + /* Resume all triggered tsm whose TC is same with this normal + ** tsm + */ + LINK_FOR_EACH_ENTRY(prCurrentTsmReq, &prWMMInfo->rActiveTsmReq, + rLinkEntry, struct ACTIVE_RM_TSM_REQ) + { + prTsmReq = prCurrentTsmReq->prTsmReq; + if (prTsmReq->u2Duration || + prTsmReq->ucACI != prTsmStatistic->ucAcIndex) + continue; + + nicTxChangeDataPortByAc( + prAdapter, + prAisBssInfo->prStaRecOfAP, + prTsmReq->ucACI, TRUE); + kalMemZero(&rTsmStatistics, sizeof(rTsmStatistics)); + rTsmStatistics.ucBssIdx = + ucBssIndex; + rTsmStatistics.ucEnabled = TRUE; + rTsmStatistics.ucAcIndex = prTsmReq->ucACI; + rTsmStatistics.ucTid = prTsmReq->ucTID; + COPY_MAC_ADDR(rTsmStatistics.aucPeerAddr, + prTsmReq->aucPeerAddr); + rTsmStatistics.ucTriggerCondition = + prTsmReq->rTriggerCond.ucCondition; + rTsmStatistics.ucMeasureCount = + prTsmReq->rTriggerCond.ucMeasureCount; + rTsmStatistics.ucTriggerTimeout = + prTsmReq->rTriggerCond.ucTriggerTimeout; + rTsmStatistics.ucAvgErrThreshold = + prTsmReq->rTriggerCond.ucAvgErrThreshold; + rTsmStatistics.ucConsecutiveErrThreshold = + prTsmReq->rTriggerCond.ucConsecutiveErr; + rTsmStatistics.ucDelayThreshold = + prTsmReq->rTriggerCond.ucDelayThreshold; + rTsmStatistics.ucBin0Range = prTsmReq->ucB0Range; + wlanSendSetQueryCmd( + prAdapter, CMD_ID_SET_TSM_STATISTICS_REQUEST, + TRUE, FALSE, FALSE, NULL, NULL, + sizeof(rTsmStatistics), + (uint8_t *)&rTsmStatistics, NULL, 0); + } + /* schedule next measurement after a duration based TSM done */ + rrmScheduleNextRm(prAdapter, ucBssIndex); + } else { + /* Triggered TSM, we should send TSM report to peer if the first + ** report time to now more than 10 second + */ + OS_SYSTIME rCurrent = kalGetTimeTick(); + + if (prWMMInfo->rTriggeredTsmRptTime == 0) + prWMMInfo->rTriggeredTsmRptTime = rCurrent; + else if (CHECK_FOR_TIMEOUT(rCurrent, + prWMMInfo->rTriggeredTsmRptTime, + 10000)) { + rrmTxRadioMeasurementReport(prAdapter, ucBssIndex); + prWMMInfo->rTriggeredTsmRptTime = 0; + } + } +} + +void wmmNotifyDisconnected(struct ADAPTER *prAdapter, + uint8_t ucBssIndex) +{ + struct WMM_INFO *prWmmInfo = + aisGetWMMInfo(prAdapter, ucBssIndex); + uint8_t ucTid = 0; + + for (; ucTid < WMM_TSPEC_ID_NUM; ucTid++) + wmmTspecSteps(prAdapter, ucTid, DISC_DELTS_REQ, NULL, + ucBssIndex); + wmmRemoveAllTsmMeasurement(prAdapter, FALSE, + ucBssIndex); +#if CFG_SUPPORT_SOFT_ACM + kalMemZero(&prWmmInfo->arAcmCtrl[0], + sizeof(prWmmInfo->arAcmCtrl)); +#endif +} + +u_int8_t wmmTsmIsOngoing(struct ADAPTER *prAdapter, + uint8_t ucBssIndex) +{ + struct WMM_INFO *prWmmInfo = + aisGetWMMInfo(prAdapter, ucBssIndex); + + return !LINK_IS_EMPTY(&prWmmInfo->rActiveTsmReq); +} + +/* This function implements TS replacement rule + ** Replace case base on same AC: + ** 1. old: Uni-dir; New: Bi-dir or same dir with old + ** 2. old: Bi-dir; New: Bi-dir or Uni-dir + ** 3. old: two diff Uni-dir; New: Bi-dir + ** for detail, see WMM spec V1.2.0, section 3.5 + */ +static void wmmMayDoTsReplacement(struct ADAPTER *prAdapter, + uint8_t ucNewTid, uint8_t ucBssIndex) +{ + struct WMM_INFO *prWmmInfo = + aisGetWMMInfo(prAdapter, ucBssIndex); + struct TSPEC_INFO *prTspec = &prWmmInfo->arTsInfo[0]; + uint8_t ucTid = 0; + + for (; ucTid < WMM_TSPEC_ID_NUM; ucTid++) { + if (ucTid == ucNewTid) + continue; + if (prTspec[ucTid].eState != QOS_TS_ACTIVE || + prTspec[ucTid].eAC != prTspec[ucNewTid].eAC) + continue; + if (prTspec[ucNewTid].eDir != prTspec[ucTid].eDir && + prTspec[ucNewTid].eDir < BI_DIR_TS && + prTspec[ucTid].eDir < BI_DIR_TS) + continue; + prTspec[ucTid].eAC = ACI_NUM; + prTspec[ucTid].eState = QOS_TS_INACTIVE; + } + wmmDumpActiveTspecs(prAdapter, NULL, 0, ucBssIndex); +} + +uint32_t wmmDumpActiveTspecs(struct ADAPTER *prAdapter, uint8_t *pucBuffer, + uint16_t u2BufferLen, uint8_t ucBssIndex) +{ + uint8_t ucTid = 0; + int32_t i4BytesWritten = 0; + struct WMM_INFO *prWmmInfo = + aisGetWMMInfo(prAdapter, ucBssIndex); + struct TSPEC_INFO *prTspec = &prWmmInfo->arTsInfo[0]; + + for (; ucTid < WMM_TSPEC_ID_NUM; ucTid++, prTspec++) { + if (prTspec->eState != QOS_TS_ACTIVE) + continue; + if (u2BufferLen > 0 && pucBuffer) { + i4BytesWritten += kalSnprintf( + pucBuffer + i4BytesWritten, u2BufferLen, + "Tid %d, AC %d, Dir %d, Uapsd %d, MediumTime %d, PhyRate %u\n", + ucTid, prTspec->eAC, prTspec->eDir, + prTspec->fgUapsd, prTspec->u2MediumTime, + prTspec->u4PhyRate); + if (i4BytesWritten <= 0) + break; + u2BufferLen -= (uint16_t)i4BytesWritten; + } else + DBGLOG(WMM, INFO, + "Tid %d, AC %d, Dir %d, Uapsd %d, MediumTime %d, PhyRate %u\n", + ucTid, prTspec->eAC, prTspec->eDir, + prTspec->fgUapsd, prTspec->u2MediumTime, + prTspec->u4PhyRate); + } + if (u2BufferLen > 0 && pucBuffer) { + struct STA_RECORD *prStaRec = + aisGetStaRecOfAP(prAdapter, ucBssIndex); + + if (prStaRec) { + i4BytesWritten += kalSnprintf( + pucBuffer + i4BytesWritten, u2BufferLen, + "\nACM status for AP "MACSTR + ":\nBE %d; BK %d; VI %d; VO %d\n", + MAC2STR(prStaRec->aucMacAddr), + prStaRec->afgAcmRequired[ACI_BE], + prStaRec->afgAcmRequired[ACI_BK], + prStaRec->afgAcmRequired[ACI_VI], + prStaRec->afgAcmRequired[ACI_VO]); + } else + i4BytesWritten += kalSnprintf( + pucBuffer + i4BytesWritten, u2BufferLen, "%s\n", + "Didn't connect to a AP"); + } + return (uint32_t)i4BytesWritten; +} + +#if CFG_SUPPORT_SOFT_ACM +/* u2PktLen: Ethernet payload length, exclude eth header. + ** Return value: estimated tx time in unit us. + */ +uint32_t wmmCalculatePktUsedTime(struct BSS_INFO *prBssInfo, + struct STA_RECORD *prStaRec, uint16_t u2PktLen) +{ + uint8_t ucSecurityPadding = 0; + int8_t i = 0; + uint32_t u4TxTime = 0; + uint8_t ucFlags = 0; + + ASSERT(prBssInfo); + ASSERT(prStaRec); + switch (prBssInfo->u4RsnSelectedPairwiseCipher) { + case RSN_CIPHER_SUITE_CCMP: + ucSecurityPadding = 16; + break; + case RSN_CIPHER_SUITE_TKIP: + ucSecurityPadding = 20; + break; + case RSN_CIPHER_SUITE_WEP104: + case RSN_CIPHER_SUITE_WEP40: + ucSecurityPadding = 8; + break; + default: + ucSecurityPadding = 0; + break; + } + /* ToDo: 802.11AC? WMM-AC didn't support 802.11AC now */ + if (prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_SET_802_11N) { + if (prBssInfo->fg40mBwAllowed) { + if (prStaRec->u2HtCapInfo & HT_CAP_INFO_SHORT_GI_40M) + ucFlags |= FLAG_SHORT_GI; + ucFlags |= FLAG_40M_BW; + } else if (prStaRec->u2HtCapInfo & HT_CAP_INFO_SHORT_GI_20M) + ucFlags |= FLAG_SHORT_GI; + + u4TxTime = wmmAcmTxTimeHtCal(ucSecurityPadding, u2PktLen, 7, + ucFlags); + DBGLOG(WMM, INFO, + "MCS 7, Tx %d bytes, SecExtra %d bytes, Flags %02x, Time %u us\n", + u2PktLen, ucSecurityPadding, ucFlags, u4TxTime); + } else { + uint16_t u2DataRate = RATE_54M; + + if (prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_802_11G) { + u2DataRate = RATE_54M; + for (i = 13; i >= 4; i--) { + if ((prStaRec->u2BSSBasicRateSet & BIT(i)) && + aucDataRate[i] <= u2DataRate) + break; + } + ucFlags |= FLAG_G_MODE; + } else if (prStaRec->ucDesiredPhyTypeSet & + (PHY_TYPE_802_11B | PHY_CONFIG_802_11A)) { + u2DataRate = RATE_11M; + for (i = 3; i >= 0; i--) { + if ((prStaRec->u2BSSBasicRateSet & BIT(i)) && + aucDataRate[i] <= u2DataRate) + break; + } + } + + if (i >= 0) { + if (prBssInfo->fgUseShortPreamble) + ucFlags |= FLAG_S_PREAMBLE; + u4TxTime = wmmAcmTxTimeCal(ucSecurityPadding, u2PktLen, + u2DataRate, aucDataRate[i], ucFlags); + DBGLOG(WMM, INFO, + "DataRate %d, BasicRate %d, Tx %d bytes, SecExtra %d bytes, Flags %02x, Time %u us\n", + u2DataRate, aucDataRate[i], u2PktLen, + ucSecurityPadding, ucFlags, u4TxTime); + } else { + u4TxTime = 0; + DBGLOG(WMM, ERROR, "i is %d !!", i); + } + } + return u4TxTime; +} + +/* 1. u4PktTxTime is 0, this function give a fast check if remain medium time is + *enough to Deq + ** 2. u4PktTxTime is not 0, if remain medium time is greater than u4PktTxTime, + *statistic deq number + ** and remain time. Otherwise, start a timer to schedule next dequeue + *interval + ** return value: + ** TRUE: Can dequeue + ** FALSE: No time to dequeue + */ +u_int8_t wmmAcmCanDequeue(struct ADAPTER *prAdapter, uint8_t ucAc, + uint32_t u4PktTxTime, uint8_t ucBssIndex) +{ + struct SOFT_ACM_CTRL *prAcmCtrl = NULL; + struct WMM_INFO *prWmmInfo = + aisGetWMMInfo(prAdapter, ucBssIndex); + uint32_t u4CurTime = 0; +#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE + struct timespec64 ts; +#else + struct timespec ts; +#endif + if (!prWmmInfo) { + DBGLOG(WMM, INFO, "prWmmInfo is null %d\n", ucBssIndex); + return FALSE; + } + + prAcmCtrl = &prWmmInfo->arAcmCtrl[ucAc]; + if (!prAcmCtrl->u4AdmittedTime) + return FALSE; +#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE + ktime_get_boottime_ts64(&ts); +#else + get_monotonic_boottime(&ts); +#endif + u4CurTime = ts.tv_sec; + if (!TIME_BEFORE(u4CurTime, prAcmCtrl->u4IntervalEndSec)) { + u4CurTime++; + DBGLOG(WMM, INFO, + "AC %d, Admitted %u, LastEnd %u, NextEnd %u, LastUsed %u, LastDeq %d\n", + ucAc, prAcmCtrl->u4AdmittedTime, + prAcmCtrl->u4IntervalEndSec, u4CurTime, + prAcmCtrl->u4AdmittedTime - prAcmCtrl->u4RemainTime, + prAcmCtrl->u2DeqNum); + prAcmCtrl->u4IntervalEndSec = u4CurTime; + prAcmCtrl->u4RemainTime = prAcmCtrl->u4AdmittedTime; + prAcmCtrl->u2DeqNum = 0; + /* Stop the next dequeue timer due to we will dequeue right now. + */ + if (timerPendingTimer(&prWmmInfo->rAcmDeqTimer)) + cnmTimerStopTimer(prAdapter, &prWmmInfo->rAcmDeqTimer); + } + if (!u4PktTxTime) { + DBGLOG(WMM, TRACE, "AC %d, can dq %d\n", ucAc, + (prAcmCtrl->u4RemainTime > 0)); + return (prAcmCtrl->u4RemainTime > 0); + } + /* If QM request to dequeue, and have enough medium time, then dequeue + */ + if (prAcmCtrl->u4RemainTime >= u4PktTxTime) { + prAcmCtrl->u2DeqNum++; + prAcmCtrl->u4RemainTime -= u4PktTxTime; + DBGLOG(WMM, INFO, "AC %d, Remain %u, DeqNum %d\n", ucAc, + prAcmCtrl->u4RemainTime, prAcmCtrl->u2DeqNum); + if (prAcmCtrl->u4RemainTime > 0) + return TRUE; + } + /* If not enough medium time to dequeue next packet, should start a + * timer to schedue next dequeue + * We didn't consider the case u4RemainTime is enough to dequeue + * packets except the head of the + * station tx queue, because it is too complex to implement dequeue + * routine. + * We should reset u4RemainTime to 0, used to skip next dequeue request + * if still in this deq interval. + * the dequeue interval is 1 second according to WMM-AC specification. + */ + prAcmCtrl->u4RemainTime = 0; + /* Start a timer to schedule next dequeue interval, since application + * may stop sending data to driver, + * but driver still pending some data to dequeue + */ + if (!timerPendingTimer(&prWmmInfo->rAcmDeqTimer)) { + uint32_t u4EndMsec = prAcmCtrl->u4IntervalEndSec * 1000; +#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE + ktime_get_boottime_ts64(&ts); +#else + get_monotonic_boottime(&ts); +#endif + u4CurTime = ts.tv_sec * MSEC_PER_SEC; + u4CurTime += ts.tv_nsec / NSEC_PER_MSEC; + /* It is impossible that u4EndMsec is less than u4CurTime */ + u4EndMsec = u4EndMsec - u4CurTime + + 20; /* the timeout duration at least 2 jiffies */ + cnmTimerStartTimer(prAdapter, &prWmmInfo->rAcmDeqTimer, + u4EndMsec); + DBGLOG(WMM, INFO, + "AC %d, will start next deq interval after %u ms\n", + ucAc, u4EndMsec); + } + return FALSE; +} + +static uint16_t wmmAcmTxTimePLCPCal(uint16_t u2Length, uint16_t u2Rate, + uint8_t FlgIsGmode) +{ + uint16_t u2PLCP; + + if (FlgIsGmode) { + u2Rate <<= 1; + /* EX1: BodyLen = 30B and rate = 54Mbps, + * 1. additional 22 bit in PSDU + * PLCP = 30*8 + 22 = 262 bits + * 2. round_up{X / 4} * 4 means OFDM symbol is in unit of 4 + * usec + * PLCP = (262/54) = 4.8xxx us + * 4.8xxx / 4 = 1.2xxx + * 3. PLCP = round up(1.2xxx) * 4 = 2 * 4 = 8 us + * EX2: BodyLen = 14B and rate = 6Mbps, + * 1. additional 22 bit in PSDU + * PLCP = 14*8 + 22 = 134 bits + * 2. round_up{X / 4} * 4 means OFDM symbol is in unit of 4 + * usec + * PLCP = (134/6) = 22.3xxx us + * 22.3xxx / 4 = 5.583xxx + * 3. PLCP = round up(5.583xxx) * 4 = 6 * 4 = 24 us + */ + u2PLCP = (u2Length << 3) + 22; /* need to add 22 bits in 11g */ + u2PLCP = (u2PLCP % u2Rate) ? (u2PLCP / u2Rate) + 1 + : (u2PLCP / u2Rate); + return u2PLCP << 2; + } + + /* ex: BodyLen = 30B and rate = 11Mbps, PLCP = 30 * 8 / 11 = 22us */ + return (u2Length << 4) / u2Rate; +} + +/* For G mode, no long or short preamble time, only long (20us) or short slot + ** time (9us). + */ +static uint16_t wmmAcmTxTimeCal(uint16_t u2SecExtra, uint16_t u2EthBodyLen, + uint16_t u2DataRate, uint16_t u2BasicRate, + uint8_t ucFlags) +{ + uint16_t u2TxTime = 0; + uint16_t u2PreambleTime = 0; + u_int8_t fgIsGMode = !!(ucFlags & FLAG_G_MODE); + + u2PreambleTime = + LMR_PREAMBL_TIME(fgIsGMode, !!(ucFlags & FLAG_S_PREAMBLE)); + + /* CTS-self */ + if (ucFlags & FLAG_CTS_SELF) { + u2TxTime = u2PreambleTime + TIME_SIFSG; + u2TxTime += wmmAcmTxTimePLCPCal(FRM_LENGTH_ACK, u2BasicRate, + fgIsGMode); + } else if (ucFlags & FLAG_RTS_CTS) { /* CTS + RTS */ + u2TxTime = 2 * u2PreambleTime + + (fgIsGMode ? TIME_SIFSGx2 : TIME_SIFSx2); + u2TxTime += wmmAcmTxTimePLCPCal(FRM_LENGTH_RTS + FRM_LENGTH_ACK, + u2BasicRate, fgIsGMode); + } + /* Data Pkt Preamble Time + RTS/CTS time + 802.11 QoS hdr + LLC header + + ** Ethernet Payload + sec extra + FCS + */ + u2TxTime += u2PreambleTime + + wmmAcmTxTimePLCPCal(WLAN_MAC_HEADER_QOS_LEN + 8 + + u2EthBodyLen + u2SecExtra + 4, + u2DataRate, fgIsGMode); + /* Ack frame for data packet. Preamble + Ack + SIFS */ + u2TxTime += + wmmAcmTxTimePLCPCal(FRM_LENGTH_ACK, u2BasicRate, fgIsGMode) + + (fgIsGMode ? TIME_SIFSG : TIME_SIFS) + u2PreambleTime; + return u2TxTime; +} + +/* Reference to Draft802.11n_D3.07, Transmission Time = + ** 1. Mix mode, short GI + ** TXTIME = T_LEG_PREAMBLE + T_L_SIG + T_HT_PREAMBLE + T_HT_SIG + + ** T_SYM * Ceiling{T_SYMS * N_SYM / T_SYM} + ** 2. Mix mode, regular GI + ** TXTIME = T_LEG_PREAMBLE + T_L_SIG + T_HT_PREAMBLE + T_HT_SIG + + ** T_SYM * N_SYM + ** 3. GreenField mode, short GI + ** TXTIME = T_GF_HT_PREAMBLE + T_HT_SIG + T_SYMS * N_SYM + ** 4. GreenField mode, regular GI + ** TXTIME = T_GF_HT_PREAMBLE + T_HT_SIG + T_SYM * N_SYM + ** Where + ** (1) T_LEG_PREAMBLE = T_L_STF + T_L_LTF = 8 + 8 = 16 us + ** (2) T_L_SIG = 4 us + ** (3) T_HT_PREAMBLE = T_HT_STF + T_HT_LTF1 + (N_LTF - 1) * T_HT_LTFS + ** = 4 + 4 + ((N_DLTF + N_ELTF) - 1) * 4 + ** EX: Nss = 2, N_DLTF = 2, Ness = 0, N_ELTF = 0, T_HT_PREAMBLE = 12 us + ** (4) T_HT_SIG = 8 us + ** (5) T_SYM = 4 us + ** (6) T_SYMS = 3.6 us + ** (7) N_SYM = mSTBC * Ceil((8*len+16+6*N_ES)/(mSTBC * + *N_DBPS)) + ** (8) T_GF_HT_PREAMBLE= T_HT_GF_STF + T_HT_LTF1 + (N_LTF - 1) * T_HT_LTFS + ** = 8 + 4 + ((N_DLTF + N_ELTF) - 1) * 4 + */ +static uint16_t wmmAcmTxTimeHtPLCPCal(uint16_t u2Length, uint8_t ucMcsId, + uint8_t ucNess, uint8_t ucFlags) +{ + uint32_t T_LEG_PREAMBLE, T_L_SIG, T_HT_PREAMBLE, T_HT_SIG; + uint32_t T_SYM, T_SYMS, N_SYM; + uint32_t T_GF_HT_PREAMBLE; + uint32_t TxTime; + uint32_t N_DLTF[5] = {1, 1, 2, 4, 4}; + uint32_t N_ELTF[4] = {0, 1, 2, 4}; + uint32_t N_SYM_1_NUM; /* numerator of N_SYM */ + uint8_t ucBwId = (ucFlags & FLAG_40M_BW) ? 1 : 0; + uint8_t ucNss = 0; + static const uint16_t gAcmRateNdbps[2][32] = { + /* MCS0 ~ MCS31 */ + /* 20MHz */ + {26, 52, 78, 104, 156, 208, 234, 260, 52, 104, 156, + 208, 312, 416, 468, 520, 78, 156, 234, 312, 468, 624, + 702, 780, 104, 208, 312, 416, 624, 832, 936, 1040}, + + /* MCS0 ~ MCS31 */ + /* 40MHz */ + {54, 108, 162, 216, 324, 432, 486, 540, 108, 216, 324, + 432, 648, 864, 972, 1080, 162, 324, 486, 648, 972, 1296, + 1458, 1620, 216, 432, 648, 864, 1296, 1728, 1944, 2160}, + }; + + /* init */ + T_LEG_PREAMBLE = 16; + T_L_SIG = 4; + T_HT_SIG = 8; + T_SYM = 4; + T_SYMS = 36; /* unit: 0.1us */ + TxTime = 0; + + if (ucMcsId < 8) + ucNss = 1; + else if (ucMcsId < 16) + ucNss = 2; + else if (ucMcsId < 24) + ucNss = 3; + else if (ucMcsId < 32) + ucNss = 4; + else { + ucMcsId = 31; + ucNss = 1; + } + /* calculate N_SYM */ + /* ex: 1538B, 1st MPDU of AMPDU, (1538 * 8 + 22)/1080 + 1 = 12 */ + /* STBC is not used, BCC is used */ + N_SYM = ((u2Length << 3) + 16 + 6) / gAcmRateNdbps[ucBwId][ucMcsId] + 1; + + /* calculate transmission time */ + if (!(ucFlags & FLAG_GF_HT)) { + /* ex: 1538B, 1st MPDU of AMPDU, 4 + 4 + 2*4 = 16us */ + T_HT_PREAMBLE = + 4 + 4 + ((N_DLTF[ucNss] + N_ELTF[ucNess] - 1) << 2); + + /* ex: 1538B, 1st MPDU of AMPDU, 16 + 4 + 16 + 8 = 44us */ + if (!(ucFlags & FLAG_ONLY_DATA)) + TxTime = T_LEG_PREAMBLE + T_L_SIG + T_HT_PREAMBLE + + T_HT_SIG; + + /* End of if */ + + /* ex: 1538B, 1st MPDU of AMPDU, 4 * 12 = 48us */ + if (!(ucFlags & FLAG_SHORT_GI)) + TxTime += T_SYM * N_SYM; + else { + N_SYM_1_NUM = (T_SYMS * N_SYM) / (T_SYM * 10); + + if ((T_SYMS * N_SYM) % (T_SYM * 10)) + N_SYM_1_NUM++; + + TxTime += T_SYM * N_SYM_1_NUM; + } /* End of if */ + } else { + T_GF_HT_PREAMBLE = + 8 + 4 + ((N_DLTF[ucNss] + N_ELTF[ucNess] - 1) << 2); + + if (!(ucFlags & FLAG_ONLY_DATA)) + TxTime = T_GF_HT_PREAMBLE + T_HT_SIG; + + TxTime += (ucFlags & FLAG_SHORT_GI) ? ((T_SYMS * N_SYM) / 10) + : (T_SYM * N_SYM); + } /* End of if */ + + return TxTime; +} /* End of ACM_TX_TimePlcpCalHT */ + +static uint16_t wmmAcmTxTimeHtCal(uint16_t u2SecExtra, uint16_t u2EthBodyLen, + uint8_t ucMcsId, uint8_t ucFlags) +{ + uint16_t u2PreambleTime = 0; + uint16_t u2TxTime = 0; + + u2PreambleTime = LMR_PREAMBL_TIME(TRUE, !!(ucFlags & FLAG_S_PREAMBLE)); + if (ucFlags & FLAG_RTS_CTS) { + /* add RTS/CTS 24Mbps time */ + u2TxTime += 2 * u2PreambleTime + TIME_SIFSGx2; + u2TxTime += wmmAcmTxTimePLCPCal(FRM_LENGTH_RTS + FRM_LENGTH_ACK, + RATE_24M, TRUE); + } + /* SIFS + ACK, always use G mode to calculate preamble */ + + u2TxTime += TIME_SIFSG + u2PreambleTime; + /* always use block ack to calculate ack time */ + u2TxTime += wmmAcmTxTimePLCPCal(FRM_LENGTH_BLOCK_ACK, RATE_24M, TRUE); + + /* Data Pkt Preamble Time + RTS/CTS time + 802.11 QoS hdr + LLC header + + ** Ethernet Payload + sec extra + FCS + ** Nss always set to 1 due to only + */ + u2TxTime += wmmAcmTxTimeHtPLCPCal(WLAN_MAC_HEADER_QOS_LEN + 8 + + u2EthBodyLen + u2SecExtra + 4, + ucMcsId, 0, ucFlags); + + return u2TxTime; +} /* End of ACM_TX_TimeCalHT */ + +static void wmmAcmDequeueTimeOut(IN struct ADAPTER *prAdapter, + unsigned long ulParamPtr) +{ + DBGLOG(WMM, INFO, "Timeout, trigger to do ACM dequeue\n"); + kalSetEvent(prAdapter->prGlueInfo); +} +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/wnm.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/wnm.c new file mode 100644 index 0000000000000000000000000000000000000000..597a3fe1c2ce1fac0f313be6147939fd3080311c --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/mgmt/wnm.c @@ -0,0 +1,651 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/TRUNK/MT6620_5931_WiFi_Driver/mgmt/wnm.c#1 + */ + +/*! \file "wnm.c" + * \brief This file includes the 802.11v default vale and functions. + */ + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +#define WNM_MAX_TOD_ERROR 0 +#define WNM_MAX_TOA_ERROR 0 +#define MICRO_TO_10NANO(x) ((x)*100) +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ +#if CFG_SUPPORT_802_11V_TIMING_MEASUREMENT +static uint8_t ucTimingMeasToken; +#endif +static uint8_t ucBtmMgtToken = 1; + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +#if CFG_SUPPORT_802_11V_TIMING_MEASUREMENT +static uint32_t +wnmRunEventTimgingMeasTxDone(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN enum ENUM_TX_RESULT_CODE rTxDoneStatus); + +static void wnmComposeTimingMeasFrame(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, + IN PFN_TX_DONE_HANDLER pfTxDoneHandler); + +static void wnmTimingMeasRequest(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb); +#endif +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +/*----------------------------------------------------------------------------*/ +/*! + * + * \brief This routine is called to process the 802.11v wnm category action + * frame. + * + * + * \note + * Called by: Handle Rx mgmt request + */ +/*----------------------------------------------------------------------------*/ +void wnmWNMAction(IN struct ADAPTER *prAdapter, IN struct SW_RFB *prSwRfb) +{ + struct WLAN_ACTION_FRAME *prRxFrame; + + prRxFrame = (struct WLAN_ACTION_FRAME *)prSwRfb->pvHeader; + + DBGLOG(WNM, TRACE, "WNM action frame: %d from " MACSTR "\n", + prRxFrame->ucAction, MAC2STR(prRxFrame->aucSrcAddr)); + + switch (prRxFrame->ucAction) { +#if CFG_SUPPORT_802_11V_TIMING_MEASUREMENT + case ACTION_WNM_TIMING_MEASUREMENT_REQUEST: + wnmTimingMeasRequest(prAdapter, prSwRfb); + break; +#endif +#if CFG_SUPPORT_802_11V_BSS_TRANSITION_MGT + case ACTION_WNM_BSS_TRANSITION_MANAGEMENT_REQ: +#if CFG_TC3_FEATURE + /* Ignore BTM REQ for TC3 */ + DBGLOG(RX, TRACE, "WNM: BTM request is ignored"); + break; +#endif +#endif + case ACTION_WNM_NOTIFICATION_REQUEST: + default: + DBGLOG(RX, INFO, + "WNM: action frame %d, try to send to supplicant\n", + prRxFrame->ucAction); + aisFuncValidateRxActionFrame(prAdapter, prSwRfb); + break; + } +} + +#if CFG_SUPPORT_802_11V_TIMING_MEASUREMENT +/*----------------------------------------------------------------------------*/ +/*! + * + * \brief This routine is called to report timing measurement data. + * + */ +/*----------------------------------------------------------------------------*/ +void wnmReportTimingMeas(IN struct ADAPTER *prAdapter, IN uint8_t ucStaRecIndex, + IN uint32_t u4ToD, IN uint32_t u4ToA) +{ + struct STA_RECORD *prStaRec; + + prStaRec = cnmGetStaRecByIndex(prAdapter, ucStaRecIndex); + + if ((!prStaRec) || (!prStaRec->fgIsInUse)) + return; + + DBGLOG(WNM, TRACE, "WNM: wnmReportTimingMeas: u4ToD %x u4ToA %x", u4ToD, + u4ToA); + + if (!prStaRec->rWNMTimingMsmt.ucTrigger) + return; + + prStaRec->rWNMTimingMsmt.u4ToD = MICRO_TO_10NANO(u4ToD); + prStaRec->rWNMTimingMsmt.u4ToA = MICRO_TO_10NANO(u4ToA); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will handle TxDone(TimingMeasurement) Event. + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] prMsduInfo Pointer to the MSDU_INFO_T. + * @param[in] rTxDoneStatus Return TX status of the Timing Measurement frame. + * + * @retval WLAN_STATUS_SUCCESS + */ +/*----------------------------------------------------------------------------*/ +static uint32_t +wnmRunEventTimgingMeasTxDone(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN enum ENUM_TX_RESULT_CODE rTxDoneStatus) +{ + struct STA_RECORD *prStaRec; + + DBGLOG(WNM, LOUD, "WNM: EVENT-TX DONE: Current Time = %ld\n", + kalGetTimeTick()); + + prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); + + if ((!prStaRec) || (!prStaRec->fgIsInUse)) + return WLAN_STATUS_SUCCESS; /* For the case of replying ERROR + * STATUS CODE + */ + + DBGLOG(WNM, TRACE, + "WNM: wnmRunEventTimgingMeasTxDone: ucDialog %d ucFollowUp %d u4ToD %x u4ToA %x", + prStaRec->rWNMTimingMsmt.ucDialogToken, + prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken, + prStaRec->rWNMTimingMsmt.u4ToD, prStaRec->rWNMTimingMsmt.u4ToA); + + prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken = + prStaRec->rWNMTimingMsmt.ucDialogToken; + prStaRec->rWNMTimingMsmt.ucDialogToken = ++ucTimingMeasToken; + + wnmComposeTimingMeasFrame(prAdapter, prStaRec, NULL); + + return WLAN_STATUS_SUCCESS; + +} /* end of wnmRunEventTimgingMeasTxDone() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will compose the Timing Measurement frame. + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] prStaRec Pointer to the STA_RECORD_T. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +static void wnmComposeTimingMeasFrame(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, + IN PFN_TX_DONE_HANDLER pfTxDoneHandler) +{ + struct MSDU_INFO *prMsduInfo; + struct BSS_INFO *prBssInfo; + struct ACTION_UNPROTECTED_WNM_TIMING_MEAS_FRAME *prTxFrame; + uint16_t u2PayloadLen; + + prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]; + prMsduInfo = (struct MSDU_INFO *)cnmMgtPktAlloc( + prAdapter, MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN); + + if (!prMsduInfo) + return; + + prTxFrame = (struct ACTION_UNPROTECTED_WNM_TIMING_MEAS_FRAME + *)((uint32_t)(prMsduInfo->prPacket) + + MAC_TX_RESERVED_FIELD); + + prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; + + COPY_MAC_ADDR(prTxFrame->aucDestAddr, prStaRec->aucMacAddr); + COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); + COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); + + prTxFrame->ucCategory = CATEGORY_UNPROTECTED_WNM_ACTION; + prTxFrame->ucAction = ACTION_UNPROTECTED_WNM_TIMING_MEASUREMENT; + + /* 3 Compose the frame body's frame. */ + prTxFrame->ucDialogToken = prStaRec->rWNMTimingMsmt.ucDialogToken; + prTxFrame->ucFollowUpDialogToken = + prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken; + prTxFrame->u4ToD = prStaRec->rWNMTimingMsmt.u4ToD; + prTxFrame->u4ToA = prStaRec->rWNMTimingMsmt.u4ToA; + prTxFrame->ucMaxToDErr = WNM_MAX_TOD_ERROR; + prTxFrame->ucMaxToAErr = WNM_MAX_TOA_ERROR; + + u2PayloadLen = 2 + ACTION_UNPROTECTED_WNM_TIMING_MEAS_LEN; + + /* 4 Update information of MSDU_INFO_T */ + TX_SET_MMPDU(prAdapter, prMsduInfo, prStaRec->ucBssIndex, + prStaRec->ucIndex, WLAN_MAC_MGMT_HEADER_LEN, + WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen, pfTxDoneHandler, + MSDU_RATE_MODE_AUTO); + + DBGLOG(WNM, TRACE, + "WNM: wnmComposeTimingMeasFrame: ucDialogToken %d ucFollowUpDialogToken %d u4ToD %x u4ToA %x\n", + prTxFrame->ucDialogToken, prTxFrame->ucFollowUpDialogToken, + prTxFrame->u4ToD, prTxFrame->u4ToA); + + /* 4 Enqueue the frame to send this action frame. */ + nicTxEnqueueMsdu(prAdapter, prMsduInfo); + + return; + +} /* end of wnmComposeTimingMeasFrame() */ + +/*----------------------------------------------------------------------------*/ +/*! + * + * \brief This routine is called to process the 802.11v timing measurement + * request. + * + * + * \note + * Handle Rx mgmt request + */ +/*----------------------------------------------------------------------------*/ +static void wnmTimingMeasRequest(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb) +{ + struct ACTION_WNM_TIMING_MEAS_REQ_FRAME *prRxFrame = NULL; + struct STA_RECORD *prStaRec; + + prRxFrame = + (struct ACTION_WNM_TIMING_MEAS_REQ_FRAME *)prSwRfb->pvHeader; + if (!prRxFrame) + return; + + prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); + if ((!prStaRec) || (!prStaRec->fgIsInUse)) + return; + + DBGLOG(WNM, TRACE, + "WNM: Received Timing Measuremen Request from " MACSTR "\n", + MAC2STR(prStaRec->aucMacAddr)); + + /* reset timing msmt */ + prStaRec->rWNMTimingMsmt.fgInitiator = TRUE; + prStaRec->rWNMTimingMsmt.ucTrigger = prRxFrame->ucTrigger; + if (!prRxFrame->ucTrigger) + return; + prStaRec->rWNMTimingMsmt.ucDialogToken = ++ucTimingMeasToken; + prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken = 0; + wnmComposeTimingMeasFrame(prAdapter, prStaRec, + wnmRunEventTimgingMeasTxDone); +} + +#if WNM_UNIT_TEST +void wnmTimingMeasUnitTest1(struct ADAPTER *prAdapter, uint8_t ucStaRecIndex) +{ + struct STA_RECORD *prStaRec; + + prStaRec = cnmGetStaRecByIndex(prAdapter, ucStaRecIndex); + if ((!prStaRec) || (!prStaRec->fgIsInUse)) + return; + DBGLOG(WNM, INFO, + "WNM: Test Timing Measuremen Request from " MACSTR "\n", + MAC2STR(prStaRec->aucMacAddr)); + prStaRec->rWNMTimingMsmt.fgInitiator = TRUE; + prStaRec->rWNMTimingMsmt.ucTrigger = 1; + prStaRec->rWNMTimingMsmt.ucDialogToken = ++ucTimingMeasToken; + prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken = 0; + wnmComposeTimingMeasFrame(prAdapter, prStaRec, + wnmRunEventTimgingMeasTxDone); +} +#endif + +#endif /* CFG_SUPPORT_802_11V_TIMING_MEASUREMENT */ + +uint8_t wnmGetBtmToken(void) +{ + return ucBtmMgtToken++; +} + +static uint32_t wnmBTMQueryTxDone(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN enum ENUM_TX_RESULT_CODE rTxDoneStatus) +{ + DBGLOG(WNM, INFO, "BTM: Query Frame Tx Done, Status %d\n", + rTxDoneStatus); + return WLAN_STATUS_SUCCESS; +} + +static uint32_t wnmBTMResponseTxDone(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN enum ENUM_TX_RESULT_CODE rTxDoneStatus) +{ + uint8_t ucBssIndex = 0; + struct BSS_TRANSITION_MGT_PARAM_T *prBtm; + struct AIS_FSM_INFO *prAisFsmInfo; + + ucBssIndex = + prMsduInfo->ucBssIndex; + prBtm = + aisGetBTMParam(prAdapter, ucBssIndex); + prAisFsmInfo = + aisGetAisFsmInfo(prAdapter, ucBssIndex); + + DBGLOG(WNM, INFO, "BTM: Response Frame Tx Done Status %d\n", + rTxDoneStatus); + if (prBtm->fgPendingResponse && + prAisFsmInfo->eCurrentState == AIS_STATE_SEARCH) { + prBtm->fgPendingResponse = FALSE; + aisFsmSteps(prAdapter, AIS_STATE_REQ_CHANNEL_JOIN, + ucBssIndex); + } + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will compose the BTM Response frame. + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] prStaRec Pointer to the STA_RECORD_T. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void wnmSendBTMResponseFrame(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec) +{ + struct MSDU_INFO *prMsduInfo = NULL; + struct BSS_INFO *prBssInfo = NULL; + struct ACTION_BTM_RSP_FRAME *prTxFrame = NULL; + uint16_t u2PayloadLen = 0; + struct BSS_TRANSITION_MGT_PARAM_T *prBtmParam; + uint8_t *pucOptInfo = NULL; + + if (!prStaRec) { + DBGLOG(WNM, INFO, "BTM: No station record found\n"); + return; + } + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex); + prBtmParam = + aisGetBTMParam(prAdapter, prStaRec->ucBssIndex); + + /* 1 Allocate MSDU Info */ + prMsduInfo = (struct MSDU_INFO *)cnmMgtPktAlloc( + prAdapter, MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN); + if (!prMsduInfo) + return; + prTxFrame = (struct ACTION_BTM_RSP_FRAME + *)((unsigned long)(prMsduInfo->prPacket) + + MAC_TX_RESERVED_FIELD); + + /* 2 Compose The Mac Header. */ + prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; + + COPY_MAC_ADDR(prTxFrame->aucDestAddr, prStaRec->aucMacAddr); + COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); + COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); + + prTxFrame->ucCategory = CATEGORY_WNM_ACTION; + prTxFrame->ucAction = ACTION_WNM_BSS_TRANSITION_MANAGEMENT_RSP; + + /* 3 Compose the frame body's frame. */ + prTxFrame->ucDialogToken = prBtmParam->ucDialogToken; + prBtmParam->ucDialogToken = 0; /* reset dialog token */ + prTxFrame->ucStatusCode = prBtmParam->ucStatusCode; + prTxFrame->ucBssTermDelay = prBtmParam->ucTermDelay; + pucOptInfo = &prTxFrame->aucOptInfo[0]; + if (prBtmParam->ucStatusCode == BSS_TRANSITION_MGT_STATUS_ACCEPT) { + COPY_MAC_ADDR(pucOptInfo, prBtmParam->aucTargetBssid); + pucOptInfo += MAC_ADDR_LEN; + u2PayloadLen += MAC_ADDR_LEN; + } + if (prBtmParam->u2OurNeighborBssLen > 0) { + kalMemCopy(pucOptInfo, prBtmParam->pucOurNeighborBss, + prBtmParam->u2OurNeighborBssLen); + kalMemFree(prBtmParam->pucOurNeighborBss, VIR_MEM_TYPE, + prBtmParam->u2OurNeighborBssLen); + prBtmParam->u2OurNeighborBssLen = 0; + u2PayloadLen += prBtmParam->u2OurNeighborBssLen; + } + + /* 4 Update information of MSDU_INFO_T */ + TX_SET_MMPDU(prAdapter, prMsduInfo, prStaRec->ucBssIndex, + prStaRec->ucIndex, WLAN_MAC_MGMT_HEADER_LEN, + OFFSET_OF(struct ACTION_BTM_RSP_FRAME, aucOptInfo) + + u2PayloadLen, + wnmBTMResponseTxDone, MSDU_RATE_MODE_AUTO); + + /* 5 Enqueue the frame to send this action frame. */ + nicTxEnqueueMsdu(prAdapter, prMsduInfo); +} /* end of wnmComposeBTMResponseFrame() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will compose the BTM Query frame. + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] prStaRec Pointer to the STA_RECORD_T. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void wnmSendBTMQueryFrame(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec) +{ + struct MSDU_INFO *prMsduInfo = NULL; + struct BSS_INFO *prBssInfo = NULL; + struct ACTION_BTM_QUERY_FRAME *prTxFrame = NULL; + struct BSS_TRANSITION_MGT_PARAM_T *prBtmParam; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex); + prBtmParam = + aisGetBTMParam(prAdapter, prStaRec->ucBssIndex); + + /* 1 Allocate MSDU Info */ + prMsduInfo = (struct MSDU_INFO *)cnmMgtPktAlloc( + prAdapter, MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN); + if (!prMsduInfo) + return; + prTxFrame = (struct ACTION_BTM_QUERY_FRAME + *)((unsigned long)(prMsduInfo->prPacket) + + MAC_TX_RESERVED_FIELD); + + /* 2 Compose The Mac Header. */ + prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; + COPY_MAC_ADDR(prTxFrame->aucDestAddr, prStaRec->aucMacAddr); + COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); + COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); + prTxFrame->ucCategory = CATEGORY_WNM_ACTION; + prTxFrame->ucAction = ACTION_WNM_BSS_TRANSITION_MANAGEMENT_QUERY; + + /* 3 Compose the frame body's frame. */ + prTxFrame->ucDialogToken = prBtmParam->ucDialogToken; + prTxFrame->ucQueryReason = prBtmParam->ucQueryReason; + if (prBtmParam->u2OurNeighborBssLen > 0) { + kalMemCopy(prTxFrame->pucNeighborBss, + prBtmParam->pucOurNeighborBss, + prBtmParam->u2OurNeighborBssLen); + kalMemFree(prBtmParam->pucOurNeighborBss, VIR_MEM_TYPE, + prBtmParam->u2OurNeighborBssLen); + prBtmParam->u2OurNeighborBssLen = 0; + } + + /* 4 Update information of MSDU_INFO_T */ + TX_SET_MMPDU(prAdapter, prMsduInfo, prStaRec->ucBssIndex, + prStaRec->ucIndex, WLAN_MAC_MGMT_HEADER_LEN, + WLAN_MAC_MGMT_HEADER_LEN + 4 + + prBtmParam->u2OurNeighborBssLen, + wnmBTMQueryTxDone, MSDU_RATE_MODE_AUTO); + + /* 5 Enqueue the frame to send this action frame. */ + nicTxEnqueueMsdu(prAdapter, prMsduInfo); +} /* end of wnmComposeBTMQueryFrame() */ + +/*----------------------------------------------------------------------------*/ +/*! + * + * \brief This routine is called to process the 802.11v BTM request. + * + * + * \note + * Handle Rx mgmt request + */ +/*----------------------------------------------------------------------------*/ +void wnmRecvBTMRequest(IN struct ADAPTER *prAdapter, IN struct SW_RFB *prSwRfb) +{ + struct ACTION_BTM_REQ_FRAME *prRxFrame = NULL; + struct BSS_TRANSITION_MGT_PARAM_T *prBtmParam; + uint8_t *pucOptInfo = NULL; + uint8_t ucRequestMode = 0; + uint16_t u2TmpLen = 0; + struct MSG_AIS_BSS_TRANSITION_T *prMsg = NULL; + enum WNM_AIS_BSS_TRANSITION eTransType = BSS_TRANSITION_NO_MORE_ACTION; + uint8_t ucBssIndex = secGetBssIdxByRfb(prAdapter, prSwRfb); + + prRxFrame = (struct ACTION_BTM_REQ_FRAME *) prSwRfb->pvHeader; + if (!prRxFrame) + return; + if (prSwRfb->u2PacketLen < + OFFSET_OF(struct ACTION_BTM_REQ_FRAME, aucOptInfo)) { + DBGLOG(WNM, WARN, + "BTM: Request frame length is less than a standard BTM frame\n"); + return; + } + prMsg = (struct MSG_AIS_BSS_TRANSITION_T *)cnmMemAlloc( + prAdapter, RAM_TYPE_MSG, + sizeof(struct MSG_AIS_BSS_TRANSITION_T)); + if (!prMsg) { + DBGLOG(WNM, WARN, "BTM: Msg Hdr is NULL\n"); + return; + } + + prBtmParam = + aisGetBTMParam(prAdapter, ucBssIndex); + kalMemZero(prMsg, sizeof(*prMsg)); + prBtmParam->ucRequestMode = prRxFrame->ucRequestMode; + prMsg->ucToken = prRxFrame->ucDialogToken; + prBtmParam->u2DisassocTimer = prRxFrame->u2DisassocTimer; + prBtmParam->ucDialogToken = prRxFrame->ucDialogToken; + pucOptInfo = &prRxFrame->aucOptInfo[0]; + ucRequestMode = prBtmParam->ucRequestMode; + u2TmpLen = OFFSET_OF(struct ACTION_BTM_REQ_FRAME, aucOptInfo); + if (ucRequestMode & BTM_REQ_MODE_DISC_IMM) + eTransType = BSS_TRANSITION_REQ_ROAMING; + if (ucRequestMode & BTM_REQ_MODE_BSS_TERM_INCLUDE) { + struct SUB_IE_BSS_TERM_DURATION *prBssTermDuration = + (struct SUB_IE_BSS_TERM_DURATION *)pucOptInfo; + + prBtmParam->u2TermDuration = prBssTermDuration->u2Duration; + kalMemCopy(prBtmParam->aucTermTsf, + prBssTermDuration->aucTermTsf, 8); + pucOptInfo += sizeof(*prBssTermDuration); + u2TmpLen += sizeof(*prBssTermDuration); + eTransType = BSS_TRANSITION_REQ_ROAMING; + } + if (ucRequestMode & BTM_REQ_MODE_ESS_DISC_IMM) { + kalMemCopy(prBtmParam->aucSessionURL, &pucOptInfo[1], + pucOptInfo[0]); + prBtmParam->ucSessionURLLen = pucOptInfo[0]; + u2TmpLen += pucOptInfo[0]; + pucOptInfo += pucOptInfo[0] + 1; + eTransType = BSS_TRANSITION_DISASSOC; + } + if (ucRequestMode & BTM_REQ_MODE_CAND_INCLUDED_BIT) { + if (!(ucRequestMode & BTM_REQ_MODE_ESS_DISC_IMM)) + eTransType = BSS_TRANSITION_REQ_ROAMING; + if (prSwRfb->u2PacketLen > u2TmpLen) { + prMsg->u2CandListLen = prSwRfb->u2PacketLen - u2TmpLen; + prMsg->pucCandList = pucOptInfo; + prMsg->ucValidityInterval = + prRxFrame->ucValidityInterval; + } else + DBGLOG(WNM, WARN, + "BTM: Candidate Include bit is set, but no candidate list\n"); + } + + DBGLOG(WNM, INFO, + "BTM: Req %d, VInt %d, DiscTimer %d, Token %d, TransType %d\n", + prBtmParam->ucRequestMode, prRxFrame->ucValidityInterval, + prBtmParam->u2DisassocTimer, prMsg->ucToken, eTransType); + + prMsg->eTransitionType = eTransType; + prMsg->rMsgHdr.eMsgId = MID_WNM_AIS_BSS_TRANSITION; + prMsg->ucBssIndex = ucBssIndex; + /* if BTM Request is dest for broadcast, don't send BTM Response */ + if (kalMemCmp(prRxFrame->aucDestAddr, "\xff\xff\xff\xff\xff\xff", + MAC_ADDR_LEN)) + prMsg->fgNeedResponse = TRUE; + else + prMsg->fgNeedResponse = FALSE; + mboxSendMsg(prAdapter, MBOX_ID_0, (struct MSG_HDR *)prMsg, + MSG_SEND_METHOD_BUF); +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/cmd_buf.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/cmd_buf.c new file mode 100644 index 0000000000000000000000000000000000000000..c10d05529274c54178c7ff76a262d4bff753296e --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/cmd_buf.c @@ -0,0 +1,321 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/cmd_buf.c#1 + */ + +/*! \file "cmd_buf.c" + * \brief This file contain the management function of internal Command + * Buffer for CMD_INFO_T. + * + * We'll convert the OID into Command Packet and then send to FW. + * Thus we need to copy the OID information to Command Buffer + * for following reasons. + * 1. The data structure of OID information may not equal to the data + * structure of Command, we cannot use the OID buffer directly. + * 2. If the Command was not generated by driver we also need a place + * to store the information. + * 3. Because the CMD is NOT FIFO when doing memory allocation (CMD will be + * generated from OID or interrupt handler), thus we'll use the Block + * style of Memory Allocation here. + */ + + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ +u_int8_t fgCmdDumpIsDone = FALSE; +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is used to initial the MGMT memory pool for CMD Packet. + * + * @param prAdapter Pointer to the Adapter structure. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void cmdBufInitialize(IN struct ADAPTER *prAdapter) +{ + struct CMD_INFO *prCmdInfo; + uint32_t i; + + ASSERT(prAdapter); + + QUEUE_INITIALIZE(&prAdapter->rFreeCmdList); + + for (i = 0; i < CFG_TX_MAX_CMD_PKT_NUM; i++) { + prCmdInfo = &prAdapter->arHifCmdDesc[i]; + QUEUE_INSERT_TAIL(&prAdapter->rFreeCmdList, + &prCmdInfo->rQueEntry); + } + +} /* end of cmdBufInitialize() */ + +#define CMD_DUMP_NUM_PER_LINE 5 +/*----------------------------------------------------------------------------*/ +/*! + * @brief dump CMD queue and print to trace, for debug use only + * @param[in] prQueue Pointer to the command Queue to be dumped + * @param[in] quename Name of the queue + */ +/*----------------------------------------------------------------------------*/ +void cmdBufDumpCmdQueue(struct QUE *prQueue, + int8_t *queName) +{ + struct CMD_INFO *prCmdInfo = (struct CMD_INFO *) + QUEUE_GET_HEAD(prQueue); + uint8_t i = 1, pos = 0; + char buf[500] = {0}; + + DBGLOG(NIC, INFO, "Dump CMD info for %s, Elem number:%u\n", + queName, prQueue->u4NumElem); + kalMemZero(buf, sizeof(buf)); + while (prCmdInfo) { + u_int8_t fgEndLine = i == prQueue->u4NumElem || + i % CMD_DUMP_NUM_PER_LINE == 0; + + pos += kalSnprintf(buf + pos, 30, + "CID:0x%02x,SEQ:%d,Type:%d%s", + prCmdInfo->ucCID, + prCmdInfo->ucCmdSeqNum, + prCmdInfo->eCmdType, + fgEndLine ? "\n" : "; "); + if (fgEndLine) { + DBGLOG(NIC, INFO, "%s", buf); + kalMemZero(buf, sizeof(buf)); + pos = 0; + } + prCmdInfo = (struct CMD_INFO *) QUEUE_GET_NEXT_ENTRY(( + struct QUE_ENTRY *) prCmdInfo); + i++; + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Allocate CMD_INFO_T from a free list and MGMT memory pool. + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @param[in] u4Length Length of the frame buffer to allocate. + * + * @retval NULL Pointer to the valid CMD Packet handler + * @retval !NULL Fail to allocat CMD Packet + */ +/*----------------------------------------------------------------------------*/ +#if CFG_DBG_MGT_BUF +struct CMD_INFO *cmdBufAllocateCmdInfoX(IN struct ADAPTER + *prAdapter, IN uint32_t u4Length, + uint8_t *fileAndLine) +#else +struct CMD_INFO *cmdBufAllocateCmdInfo(IN struct ADAPTER + *prAdapter, IN uint32_t u4Length) +#endif +{ + struct CMD_INFO *prCmdInfo; + + KAL_SPIN_LOCK_DECLARATION(); + + DEBUGFUNC("cmdBufAllocateCmdInfo"); + + ASSERT(prAdapter); + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); + QUEUE_REMOVE_HEAD(&prAdapter->rFreeCmdList, prCmdInfo, + struct CMD_INFO *); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); + + if (prCmdInfo) { + kalMemZero(prCmdInfo, sizeof(struct CMD_INFO)); + /* Setup initial value in CMD_INFO_T */ + prCmdInfo->u2InfoBufLen = 0; + prCmdInfo->fgIsOid = FALSE; + + if (u4Length) { + /* Start address of allocated memory */ + u4Length = TFCB_FRAME_PAD_TO_DW(u4Length); + +#if CFG_DBG_MGT_BUF + prCmdInfo->pucInfoBuffer = cnmMemAllocX(prAdapter, + RAM_TYPE_BUF, u4Length, fileAndLine); +#else + prCmdInfo->pucInfoBuffer = cnmMemAlloc(prAdapter, + RAM_TYPE_BUF, u4Length); +#endif + + if (prCmdInfo->pucInfoBuffer == NULL) { + KAL_ACQUIRE_SPIN_LOCK(prAdapter, + SPIN_LOCK_CMD_RESOURCE); + QUEUE_INSERT_TAIL(&prAdapter->rFreeCmdList, + &prCmdInfo->rQueEntry); + KAL_RELEASE_SPIN_LOCK(prAdapter, + SPIN_LOCK_CMD_RESOURCE); + + prCmdInfo = NULL; + } else { + kalMemZero(prCmdInfo->pucInfoBuffer, u4Length); + } + } else { + prCmdInfo->pucInfoBuffer = NULL; + } + fgCmdDumpIsDone = FALSE; + } else if (!fgCmdDumpIsDone) { + struct GLUE_INFO *prGlueInfo = prAdapter->prGlueInfo; + struct QUE *prCmdQue = &prGlueInfo->rCmdQueue; + struct QUE *prPendingCmdQue = &prAdapter->rPendingCmdQueue; + struct TX_TCQ_STATUS *prTc = &prAdapter->rTxCtrl.rTc; + + fgCmdDumpIsDone = TRUE; + cmdBufDumpCmdQueue(prCmdQue, "waiting Tx CMD queue"); + cmdBufDumpCmdQueue(prPendingCmdQue, + "waiting response CMD queue"); + DBGLOG(NIC, INFO, "Tc4 number:%d\n", + prTc->au4FreeBufferCount[TC4_INDEX]); + } + + if (prCmdInfo) { + DBGLOG(MEM, TRACE, + "CMD[0x%p] allocated! LEN[%04u], Rest[%u]\n", + prCmdInfo, u4Length, prAdapter->rFreeCmdList.u4NumElem); + + } else { + /* dump debug log */ + prAdapter->u4HifDbgFlag |= DEG_HIF_DEFAULT_DUMP; + kalSetHifDbgEvent(prAdapter->prGlueInfo); + + DBGLOG(MEM, ERROR, + "CMD allocation failed! LEN[%04u], Rest[%u]\n", + u4Length, prAdapter->rFreeCmdList.u4NumElem); + } + + return prCmdInfo; + +} /* end of cmdBufAllocateCmdInfo() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is used to free the CMD Packet to the MGMT memory pool. + * + * @param prAdapter Pointer to the Adapter structure. + * @param prCmdInfo CMD Packet handler + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void cmdBufFreeCmdInfo(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo) +{ + KAL_SPIN_LOCK_DECLARATION(); + + DEBUGFUNC("cmdBufFreeCmdInfo"); + + ASSERT(prAdapter); + + if (prCmdInfo) { + if (prCmdInfo->pucInfoBuffer) { + cnmMemFree(prAdapter, prCmdInfo->pucInfoBuffer); + prCmdInfo->pucInfoBuffer = NULL; + } + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); + QUEUE_INSERT_TAIL(&prAdapter->rFreeCmdList, + &prCmdInfo->rQueEntry); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); + } + + if (prCmdInfo) + DBGLOG(MEM, LOUD, "CMD[0x%p] freed! Rest[%u]\n", prCmdInfo, + prAdapter->rFreeCmdList.u4NumElem); + + return; + +} /* end of cmdBufFreeCmdPacket() */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/nic.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/nic.c new file mode 100644 index 0000000000000000000000000000000000000000..84204aed6aa4f84bbbcf35e765255dee8c292a34 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/nic.c @@ -0,0 +1,4974 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic.c#4 + */ + +/*! \file nic.c + * \brief Functions that provide operation in NIC's (Network Interface Card) + * point of view. + * This file includes functions which unite multiple hal(Hardware) operations + * and also take the responsibility of Software Resource Management in order + * to keep the synchronization with Hardware Manipulation. + */ + + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" + +#if (CFG_TWT_SMART_STA == 1) +#include "twt.h" +#endif + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +const uint8_t aucPhyCfg2PhyTypeSet[PHY_CONFIG_NUM] = { + PHY_TYPE_SET_802_11ABG, /* PHY_CONFIG_802_11ABG */ + PHY_TYPE_SET_802_11BG, /* PHY_CONFIG_802_11BG */ + PHY_TYPE_SET_802_11G, /* PHY_CONFIG_802_11G */ + PHY_TYPE_SET_802_11A, /* PHY_CONFIG_802_11A */ + PHY_TYPE_SET_802_11B, /* PHY_CONFIG_802_11B */ + PHY_TYPE_SET_802_11ABGN, /* PHY_CONFIG_802_11ABGN */ + PHY_TYPE_SET_802_11BGN, /* PHY_CONFIG_802_11BGN */ + PHY_TYPE_SET_802_11AN, /* PHY_CONFIG_802_11AN */ + PHY_TYPE_SET_802_11GN, /* PHY_CONFIG_802_11GN */ + PHY_TYPE_SET_802_11AC, + PHY_TYPE_SET_802_11ANAC, + PHY_TYPE_SET_802_11ABGNAC, +#if (CFG_SUPPORT_802_11AX == 1) + PHY_TYPE_SET_802_11ABGNACAX, +#endif +}; + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +static struct INT_EVENT_MAP arIntEventMapTable[] = { + {WHISR_ABNORMAL_INT, INT_EVENT_ABNORMAL}, + {WHISR_D2H_SW_INT, INT_EVENT_SW_INT}, + {WHISR_TX_DONE_INT, INT_EVENT_TX}, + {(WHISR_RX0_DONE_INT | WHISR_RX1_DONE_INT), INT_EVENT_RX} +}; + +static const uint8_t ucIntEventMapSize = (sizeof( + arIntEventMapTable) / sizeof(struct INT_EVENT_MAP)); + +static IST_EVENT_FUNCTION apfnEventFuncTable[] = { + nicProcessAbnormalInterrupt, /*!< INT_EVENT_ABNORMAL */ + nicProcessSoftwareInterrupt, /*!< INT_EVENT_SW_INT */ + nicProcessTxInterrupt, /*!< INT_EVENT_TX */ + nicProcessRxInterrupt, /*!< INT_EVENT_RX */ +}; + +struct ECO_INFO g_eco_info = {0xFF}; +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ +#if defined(_HIF_USB) +struct TIMER rSerSyncTimer = { + .rLinkEntry = {0} +}; +#endif + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ +/*! This macro is used to reduce coding errors inside nicAllocateAdapterMemory() + * and also enhance the readability. + */ +#define LOCAL_NIC_ALLOCATE_MEMORY(pucMem, u4Size, eMemType, pucComment) \ +{ \ + pucMem = (uint8_t *)kalMemAlloc(u4Size, eMemType); \ + if (pucMem == (uint8_t *)NULL) { \ + DBGLOG(INIT, ERROR, \ + "Could not allocate %u bytes for %s.\n", \ + u4Size, (char *) pucComment); \ + break; \ + } \ + ASSERT(((unsigned long)pucMem % 4) == 0); \ + DBGLOG(INIT, TRACE, "Alloc %u bytes, addr = 0x%p for %s.\n", \ + u4Size, (void *) pucMem, (char *) pucComment); \ +} + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is responsible for the allocation of the data structures + * inside the Adapter structure, include: + * 1. SW_RFB_Ts + * 2. Common coalescing buffer for TX PATH. + * + * @param prAdapter Pointer of Adapter Data Structure + * + * @retval WLAN_STATUS_SUCCESS - Has enough memory. + * @retval WLAN_STATUS_RESOURCES - Memory is not enough. + */ +/*----------------------------------------------------------------------------*/ +uint32_t nicAllocateAdapterMemory(IN struct ADAPTER + *prAdapter) +{ + uint32_t status = WLAN_STATUS_RESOURCES; + struct RX_CTRL *prRxCtrl; + struct TX_CTRL *prTxCtrl; + + DEBUGFUNC("nicAllocateAdapterMemory"); + + ASSERT(prAdapter); + prRxCtrl = &prAdapter->rRxCtrl; + prTxCtrl = &prAdapter->rTxCtrl; + + do { + /* 4 <0> Reset all Memory Handler */ +#if CFG_DBG_MGT_BUF + prAdapter->u4MemFreeDynamicCount = 0; + prAdapter->u4MemAllocDynamicCount = 0; +#endif + prAdapter->pucMgtBufCached = (uint8_t *) NULL; + prRxCtrl->pucRxCached = (uint8_t *) NULL; + + /* 4 <1> Memory for Management Memory Pool and CMD_INFO_T */ + /* Allocate memory for the struct CMD_INFO + * and its MGMT memory pool. + */ + prAdapter->u4MgtBufCachedSize = MGT_BUFFER_SIZE; + + LOCAL_NIC_ALLOCATE_MEMORY(prAdapter->pucMgtBufCached, + prAdapter->u4MgtBufCachedSize, PHY_MEM_TYPE, + "COMMON MGMT MEMORY POOL"); + + /* 4 <2> Memory for RX Descriptor */ + /* Initialize the number of rx buffers + * we will have in our queue. + */ + /* We may setup ucRxPacketDescriptors by GLUE Layer, + * and using this variable directly. + */ + /* Allocate memory for the SW receive structures. */ + prRxCtrl->u4RxCachedSize = CFG_RX_MAX_PKT_NUM * ALIGN_4( + sizeof(struct SW_RFB)); + + LOCAL_NIC_ALLOCATE_MEMORY(prRxCtrl->pucRxCached, + prRxCtrl->u4RxCachedSize, + VIR_MEM_TYPE, "struct SW_RFB"); + + /* 4 <3> Memory for TX DEscriptor */ + prTxCtrl->u4TxCachedSize = CFG_TX_MAX_PKT_NUM * ALIGN_4( + sizeof(struct MSDU_INFO)); + + LOCAL_NIC_ALLOCATE_MEMORY(prTxCtrl->pucTxCached, + prTxCtrl->u4TxCachedSize, + VIR_MEM_TYPE, "struct MSDU_INFO"); + + /* 4 <4> Memory for Common Coalescing Buffer */ + + /* Get valid buffer size based on config & host capability */ + prAdapter->u4CoalescingBufCachedSize = + halGetValidCoalescingBufSize(prAdapter); + + /* Allocate memory for the common coalescing buffer. */ + prAdapter->pucCoalescingBufCached = kalAllocateIOBuffer( + prAdapter->u4CoalescingBufCachedSize); + + if (prAdapter->pucCoalescingBufCached == NULL) { + DBGLOG(INIT, ERROR, + "Could not allocate %u bytes for coalescing buffer.\n", + prAdapter->u4CoalescingBufCachedSize); + break; + } + + /* <5> Memory for HIF */ + if (halAllocateIOBuffer(prAdapter) != WLAN_STATUS_SUCCESS) + break; + +#if CFG_DBG_MGT_BUF + LINK_INITIALIZE(&prAdapter->rMemTrackLink); +#endif + status = WLAN_STATUS_SUCCESS; + + } while (FALSE); + + if (status != WLAN_STATUS_SUCCESS) + nicReleaseAdapterMemory(prAdapter); + + return status; + +} /* end of nicAllocateAdapterMemory() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is responsible for releasing the allocated memory by + * nicAllocatedAdapterMemory(). + * + * @param prAdapter Pointer of Adapter Data Structure + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void nicReleaseAdapterMemory(IN struct ADAPTER *prAdapter) +{ + struct TX_CTRL *prTxCtrl; + struct RX_CTRL *prRxCtrl; + uint32_t u4Idx; + + ASSERT(prAdapter); + prTxCtrl = &prAdapter->rTxCtrl; + prRxCtrl = &prAdapter->rRxCtrl; + + /* 4 <5> Memory for HIF */ + halReleaseIOBuffer(prAdapter); + + /* 4 <4> Memory for Common Coalescing Buffer */ + if (prAdapter->pucCoalescingBufCached) { + kalReleaseIOBuffer((void *) + prAdapter->pucCoalescingBufCached, + prAdapter->u4CoalescingBufCachedSize); + prAdapter->pucCoalescingBufCached = (uint8_t *) NULL; + } + + /* 4 <3> Memory for TX Descriptor */ + if (prTxCtrl->pucTxCached) { + kalMemFree((void *) prTxCtrl->pucTxCached, VIR_MEM_TYPE, + prTxCtrl->u4TxCachedSize); + prTxCtrl->pucTxCached = (uint8_t *) NULL; + } + /* 4 <2> Memory for RX Descriptor */ + if (prRxCtrl->pucRxCached) { + kalMemFree((void *) prRxCtrl->pucRxCached, VIR_MEM_TYPE, + prRxCtrl->u4RxCachedSize); + prRxCtrl->pucRxCached = (uint8_t *) NULL; + } + /* 4 <1> Memory for Management Memory Pool */ + if (prAdapter->pucMgtBufCached) { + kalMemFree((void *) prAdapter->pucMgtBufCached, + PHY_MEM_TYPE, prAdapter->u4MgtBufCachedSize); + prAdapter->pucMgtBufCached = (uint8_t *) NULL; + } + + /* Memory for TX Desc Template */ + for (u4Idx = 0; u4Idx < CFG_STA_REC_NUM; u4Idx++) + nicTxFreeDescTemplate(prAdapter, + &prAdapter->arStaRec[u4Idx]); + +#if CFG_DBG_MGT_BUF + do { + u_int8_t fgUnfreedMem = FALSE; + struct BUF_INFO *prBufInfo; + + /* Dynamic allocated memory from OS */ + if (prAdapter->u4MemFreeDynamicCount != + prAdapter->u4MemAllocDynamicCount) + fgUnfreedMem = TRUE; + + /* MSG buffer */ + prBufInfo = &prAdapter->rMsgBufInfo; + if (prBufInfo->u4AllocCount != (prBufInfo->u4FreeCount + + prBufInfo->u4AllocNullCount)) + fgUnfreedMem = TRUE; + + /* MGT buffer */ + prBufInfo = &prAdapter->rMgtBufInfo; + if (prBufInfo->u4AllocCount != (prBufInfo->u4FreeCount + + prBufInfo->u4AllocNullCount)) + fgUnfreedMem = TRUE; + + /* Check if all allocated memories are free */ + if (fgUnfreedMem) { + DBGLOG(MEM, ERROR, + "Unequal memory alloc/free count!\n"); + + qmDumpQueueStatus(prAdapter, NULL, 0); + cnmDumpMemoryStatus(prAdapter, NULL, 0); + } + + if (!wlanIsChipNoAck(prAdapter)) { + /* Skip this ASSERT if chip is no ACK */ + if (prAdapter->u4MemFreeDynamicCount != + prAdapter->u4MemAllocDynamicCount) { + struct MEM_TRACK *prMemTrack = NULL; + + DBGLOG(MEM, ERROR, "----- Memory Leak -----\n"); + LINK_FOR_EACH_ENTRY(prMemTrack, + &prAdapter->rMemTrackLink, + rLinkEntry, + struct MEM_TRACK) { + DBGLOG(MEM, ERROR, + "file:line %s, cmd id: %u, where: %u\n", + prMemTrack->pucFileAndLine, + prMemTrack->u2CmdIdAndWhere & + 0x00FF, + (prMemTrack->u2CmdIdAndWhere & + 0xFF00) >> 8); + } + } + ASSERT(prAdapter->u4MemFreeDynamicCount == + prAdapter->u4MemAllocDynamicCount); + } + } while (FALSE); +#endif + +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief disable global interrupt + * + * @param prAdapter pointer to the Adapter handler + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void nicDisableInterrupt(IN struct ADAPTER *prAdapter) +{ + halDisableInterrupt(prAdapter); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief enable global interrupt + * + * @param prAdapter pointer to the Adapter handler + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void nicEnableInterrupt(IN struct ADAPTER *prAdapter) +{ + halEnableInterrupt(prAdapter); + +} /* end of nicEnableInterrupt() */ + +#if 0 /* CFG_SDIO_INTR_ENHANCE */ +/*----------------------------------------------------------------------------*/ +/*! + * @brief Read interrupt status from hardware + * + * @param prAdapter pointer to the Adapter handler + * @param the interrupts + * + * @return N/A + * + */ +/*----------------------------------------------------------------------------*/ +void nicSDIOReadIntStatus(IN struct ADAPTER *prAdapter, + OUT uint32_t *pu4IntStatus) +{ + struct ENHANCE_MODE_DATA_STRUCT *prSDIOCtrl; + + DEBUGFUNC("nicSDIOReadIntStatus"); + + ASSERT(prAdapter); + ASSERT(pu4IntStatus); + + prSDIOCtrl = prAdapter->prSDIOCtrl; + ASSERT(prSDIOCtrl); + + HAL_PORT_RD(prAdapter, + MCR_WHISR, + sizeof(struct ENHANCE_MODE_DATA_STRUCT), + (uint8_t *) prSDIOCtrl, + sizeof(struct ENHANCE_MODE_DATA_STRUCT)); + + if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE + || fgIsBusAccessFailed == TRUE) { + *pu4IntStatus = 0; + return; + } + + /* workaround */ + if ((prSDIOCtrl->u4WHISR & WHISR_TX_DONE_INT) == 0 + && (prSDIOCtrl->rTxInfo.au4WTSR[0] + | prSDIOCtrl->rTxInfo.au4WTSR[1] + | prSDIOCtrl->rTxInfo.au4WTSR[2] + | prSDIOCtrl->rTxInfo.au4WTSR[3] + | prSDIOCtrl->rTxInfo.au4WTSR[4] + | prSDIOCtrl->rTxInfo.au4WTSR[5] + | prSDIOCtrl->rTxInfo.au4WTSR[6] + | prSDIOCtrl->rTxInfo.au4WTSR[7])) { + prSDIOCtrl->u4WHISR |= WHISR_TX_DONE_INT; + } + + if ((prSDIOCtrl->u4WHISR & BIT(31)) == 0 && + HAL_GET_MAILBOX_READ_CLEAR(prAdapter) == TRUE && + (prSDIOCtrl->u4RcvMailbox0 != 0 + || prSDIOCtrl->u4RcvMailbox1 != 0)) { + prSDIOCtrl->u4WHISR |= BIT(31); + } + + *pu4IntStatus = prSDIOCtrl->u4WHISR; + +} /* end of nicSDIOReadIntStatus() */ +#endif + +#if 0 /*defined(_HIF_PCIE) */ +void nicPCIEReadIntStatus(IN struct ADAPTER *prAdapter, + OUT uint32_t *pu4IntStatus) +{ + uint32_t u4RegValue; + + *pu4IntStatus = 0; + + HAL_MCR_RD(prAdapter, WPDMA_INT_STA, &u4RegValue); + + if (HAL_IS_RX_DONE_INTR(u4RegValue)) + *pu4IntStatus |= WHISR_RX0_DONE_INT; + + if (HAL_IS_TX_DONE_INTR(u4RegValue)) + *pu4IntStatus |= WHISR_TX_DONE_INT; + + /* clear interrupt */ + HAL_MCR_WR(prAdapter, WPDMA_INT_STA, u4RegValue); + +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * @brief The function used to read interrupt status and then invoking + * dispatching procedure for the appropriate functions + * corresponding to specific interrupt bits + * + * @param prAdapter pointer to the Adapter handler + * + * @retval WLAN_STATUS_SUCCESS + * @retval WLAN_STATUS_ADAPTER_NOT_READY + */ +/*----------------------------------------------------------------------------*/ +uint32_t nicProcessIST(IN struct ADAPTER *prAdapter) +{ + if (prAdapter == NULL) { + DBGLOG(REQ, ERROR, "prAdapter is NULL!!"); + return WLAN_STATUS_FAILURE; + } + return nicProcessISTWithSpecifiedCount(prAdapter, + prAdapter->rWifiVar.u4HifIstLoopCount); +} + +uint32_t nicProcessISTWithSpecifiedCount(IN struct ADAPTER *prAdapter, + IN uint32_t u4HifIstLoopCount) +{ + uint32_t u4Status = WLAN_STATUS_SUCCESS; + uint32_t u4IntStatus = 0; + uint32_t i; + + ASSERT(prAdapter); + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, WARN, + "Fail in set nicProcessIST! (Adapter not ready). ACPI=D%d, Radio=%d\n", + prAdapter->rAcpiState, prAdapter->fgIsRadioOff); + return WLAN_STATUS_ADAPTER_NOT_READY; + } + + for (i = 0; i < u4HifIstLoopCount; i++) { + + HAL_READ_INT_STATUS(prAdapter, &u4IntStatus); + /* DBGLOG(INIT, TRACE, "u4IntStatus: 0x%x\n", u4IntStatus); */ + + if (u4IntStatus == 0) { + if (i == 0) + u4Status = WLAN_STATUS_NOT_INDICATING; + break; + } + + nicProcessIST_impl(prAdapter, u4IntStatus); + } + + return u4Status; +} /* end of nicProcessIST() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief The function used to dispatch the appropriate functions for specific + * interrupt bits + * + * @param prAdapter pointer to the Adapter handler + * u4IntStatus interrupt status bits + * + * @retval WLAN_STATUS_SUCCESS + * @retval WLAN_STATUS_ADAPTER_NOT_READY + */ +/*----------------------------------------------------------------------------*/ +uint32_t nicProcessIST_impl(IN struct ADAPTER *prAdapter, + IN uint32_t u4IntStatus) +{ + uint32_t u4IntCount = 0; + struct INT_EVENT_MAP *prIntEventMap = NULL; + + ASSERT(prAdapter); + + prAdapter->u4IntStatus = u4IntStatus; + + /* Process each of the interrupt status consequently */ + prIntEventMap = &arIntEventMapTable[0]; + for (u4IntCount = 0; u4IntCount < ucIntEventMapSize; + prIntEventMap++, u4IntCount++) { + if (prIntEventMap->u4Int & prAdapter->u4IntStatus) { + if (0) { + /* ignore */ + } else if (apfnEventFuncTable[prIntEventMap->u4Event] != + NULL) { + apfnEventFuncTable[ + prIntEventMap->u4Event] (prAdapter); + } else { + DBGLOG(INTR, WARN, + "Empty INTR handler! ISAR bit#: %u, event:%u, func: 0x%p\n", + prIntEventMap->u4Int, + prIntEventMap->u4Event, + apfnEventFuncTable[prIntEventMap->u4Event]); + + /* to trap any NULL interrupt handler */ + ASSERT(0); + } + prAdapter->u4IntStatus &= ~prIntEventMap->u4Int; + } + } + + return WLAN_STATUS_SUCCESS; +} /* end of nicProcessIST_impl() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Verify the CHIP ID + * + * @param prAdapter a pointer to adapter private data structure. + * + * + * @retval TRUE CHIP ID is the same as the setting compiled + * @retval FALSE CHIP ID is different from the setting compiled + */ +/*----------------------------------------------------------------------------*/ +u_int8_t nicVerifyChipID(IN struct ADAPTER *prAdapter) +{ + return halVerifyChipID(prAdapter); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Initialize the MCR to the appropriate init value, and verify the init + * value + * + * @param prAdapter a pointer to adapter private data structure. + * + * @return - + */ +/*----------------------------------------------------------------------------*/ +void nicMCRInit(IN struct ADAPTER *prAdapter) +{ + + ASSERT(prAdapter); + + /* 4 <0> Initial value */ +} + +void nicHifInit(IN struct ADAPTER *prAdapter) +{ + + ASSERT(prAdapter); +#if 0 + /* reset event */ + nicPutMailbox(prAdapter, 0, 0x52455345); /* RESE */ + nicPutMailbox(prAdapter, 1, 0x545F5746); /* T_WF */ + nicSetSwIntr(prAdapter, BIT(16)); +#endif +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Initialize the Adapter soft variable + * + * @param prAdapter pointer to the Adapter handler + * + * @return (none) + * + */ +/*----------------------------------------------------------------------------*/ +uint32_t nicInitializeAdapter(IN struct ADAPTER *prAdapter) +{ + uint32_t u4Status = WLAN_STATUS_SUCCESS; + + ASSERT(prAdapter); + + prAdapter->fgIsIntEnableWithLPOwnSet = FALSE; + prAdapter->fgIsReadRevID = FALSE; + + do { + if (!nicVerifyChipID(prAdapter)) { + u4Status = WLAN_STATUS_FAILURE; + break; + } + /* 4 <1> MCR init */ + nicMCRInit(prAdapter); + + HAL_HIF_INIT(prAdapter); + + /* 4 <2> init FW HIF */ + nicHifInit(prAdapter); + } while (FALSE); + + return u4Status; +} + +#if defined(_HIF_SPI) +/*----------------------------------------------------------------------------*/ +/*! + * \brief Restore the SPI Mode Select to default mode, + * this is important while driver is unload, and this must be last mcr + * since the operation will let the hif use 8bit mode access + * + * \param[in] prAdapter a pointer to adapter private data structure. + * \param[in] eGPIO2_Mode GPIO2 operation mode + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void nicRestoreSpiDefMode(IN struct ADAPTER *prAdapter) +{ + ASSERT(prAdapter); + + HAL_MCR_WR(prAdapter, MCR_WCSR, SPICSR_8BIT_MODE_DATA); + +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Process rx interrupt. When the rx + * Interrupt is asserted, it means there are frames in queue. + * + * @param prAdapter Pointer to the Adapter structure. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void nicProcessAbnormalInterrupt(IN struct ADAPTER + *prAdapter) +{ + if (halIsHifStateSuspend(prAdapter)) + DBGLOG(RX, WARN, "suspend Abnormal\n"); + + prAdapter->prGlueInfo->IsrAbnormalCnt++; + + halProcessAbnormalInterrupt(prAdapter); + glSetRstReason(RST_PROCESS_ABNORMAL_INT); + GL_RESET_TRIGGER(prAdapter, RST_FLAG_DO_CORE_DUMP); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief . + * + * @param prAdapter Pointer to the Adapter structure. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void nicProcessFwOwnBackInterrupt(IN struct ADAPTER + *prAdapter) +{ + +} /* end of nicProcessFwOwnBackInterrupt() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief . + * + * @param prAdapter Pointer to the Adapter structure. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void nicProcessSoftwareInterrupt(IN struct ADAPTER + *prAdapter) +{ + prAdapter->prGlueInfo->IsrSoftWareCnt++; + if (halIsHifStateSuspend(prAdapter)) + DBGLOG(RX, WARN, "suspend SW INT\n"); + halProcessSoftwareInterrupt(prAdapter); +} /* end of nicProcessSoftwareInterrupt() */ + +void nicSetSwIntr(IN struct ADAPTER *prAdapter, + IN uint32_t u4SwIntrBitmap) +{ + /* NOTE: + * SW interrupt in HW bit 16 is mapping to SW bit 0 + * (shift 16bit in HW transparancy) + * SW interrupt valid from b0~b15 + */ + ASSERT((u4SwIntrBitmap & BITS(0, 15)) == 0); + /* DBGLOG(INIT, TRACE, ("u4SwIntrBitmap: 0x%08x\n", u4SwIntrBitmap)); */ + + HAL_MCR_WR(prAdapter, MCR_WSICR, u4SwIntrBitmap); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This procedure is used to dequeue from prAdapter->rPendingCmdQueue + * with specified sequential number + * + * @param prAdapter Pointer of ADAPTER_T + * ucSeqNum Sequential Number + * + * @retval - P_CMD_INFO_T + */ +/*----------------------------------------------------------------------------*/ +struct CMD_INFO *nicGetPendingCmdInfo(IN struct ADAPTER + *prAdapter, IN uint8_t ucSeqNum) +{ + struct QUE *prCmdQue; + struct QUE rTempCmdQue; + struct QUE *prTempCmdQue = &rTempCmdQue; + struct QUE_ENTRY *prQueueEntry = (struct QUE_ENTRY *) NULL; + struct CMD_INFO *prCmdInfo = (struct CMD_INFO *) NULL; + + KAL_SPIN_LOCK_DECLARATION(); + + ASSERT(prAdapter); + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); + + prCmdQue = &prAdapter->rPendingCmdQueue; + QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); + + QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, + struct QUE_ENTRY *); + while (prQueueEntry) { + prCmdInfo = (struct CMD_INFO *) prQueueEntry; + + if (prCmdInfo->ucCmdSeqNum == ucSeqNum) + break; + + QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); + + prCmdInfo = NULL; + + QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, + struct QUE_ENTRY *); + } + QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue); + + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); + + return prCmdInfo; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This procedure is used to dequeue from + * prAdapter->rTxCtrl.rTxMgmtTxingQueue + * with specified sequential number + * + * @param prAdapter Pointer of ADAPTER_T + * ucSeqNum Sequential Number + * + * @retval - P_MSDU_INFO_T + */ +/*----------------------------------------------------------------------------*/ +struct MSDU_INFO *nicGetPendingTxMsduInfo( + IN struct ADAPTER *prAdapter, IN uint8_t ucWlanIndex, + IN uint8_t ucPID) +{ + struct QUE *prTxingQue; + struct QUE rTempQue; + struct QUE *prTempQue = &rTempQue; + struct QUE_ENTRY *prQueueEntry = (struct QUE_ENTRY *) NULL; + struct MSDU_INFO *prMsduInfo = (struct MSDU_INFO *) NULL; + + KAL_SPIN_LOCK_DECLARATION(); + + ASSERT(prAdapter); + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); + + prTxingQue = &(prAdapter->rTxCtrl.rTxMgmtTxingQueue); + QUEUE_MOVE_ALL(prTempQue, prTxingQue); + + QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, + struct QUE_ENTRY *); + while (prQueueEntry) { + prMsduInfo = (struct MSDU_INFO *) prQueueEntry; + + if ((prMsduInfo->ucPID == ucPID) + && (prMsduInfo->ucWlanIndex == ucWlanIndex)) + break; + + QUEUE_INSERT_TAIL(prTxingQue, prQueueEntry); + + prMsduInfo = NULL; + + QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, + struct QUE_ENTRY *); + } + QUEUE_CONCATENATE_QUEUES(prTxingQue, prTempQue); + + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); + + if (prMsduInfo) { + DBGLOG(TX, TRACE, + "Get Msdu WIDX:PID[%u:%u] SEQ[%u] from Pending Q\n", + prMsduInfo->ucWlanIndex, prMsduInfo->ucPID, + prMsduInfo->ucTxSeqNum); + } else { + DBGLOG(TX, WARN, + "Cannot get Target Msdu WIDX:PID[%u:%u] from Pending Q\n", + ucWlanIndex, ucPID); + } + + return prMsduInfo; +} + +void nicFreePendingTxMsduInfo(IN struct ADAPTER *prAdapter, + IN uint8_t ucIndex, IN enum ENUM_REMOVE_BY_MSDU_TPYE ucFreeType) +{ + struct QUE *prTxingQue; + struct QUE rTempQue; + struct QUE *prTempQue = &rTempQue; + struct QUE_ENTRY *prQueueEntry = (struct QUE_ENTRY *) NULL; + struct MSDU_INFO *prMsduInfoListHead = (struct MSDU_INFO *) + NULL; + struct MSDU_INFO *prMsduInfoListTail = (struct MSDU_INFO *) + NULL; + struct MSDU_INFO *prMsduInfo = (struct MSDU_INFO *) NULL; + uint8_t ucRemoveByIndex = 255; + + KAL_SPIN_LOCK_DECLARATION(); + + ASSERT(prAdapter); + + if (ucFreeType >= ENUM_REMOVE_BY_MSDU_TPYE_NUM) { + DBGLOG(TX, WARN, "Wrong remove type: %d\n", ucFreeType); + return; + } + + DBGLOG(NIC, TRACE, "ucIndex: %d, ucFreeType: %d\n", + ucIndex, ucFreeType); + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); + + prTxingQue = &(prAdapter->rTxCtrl.rTxMgmtTxingQueue); + QUEUE_MOVE_ALL(prTempQue, prTxingQue); + + QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, + struct QUE_ENTRY *); + + while (prQueueEntry) { + prMsduInfo = (struct MSDU_INFO *) prQueueEntry; + + switch (ucFreeType) { + case MSDU_REMOVE_BY_WLAN_INDEX: + ucRemoveByIndex = prMsduInfo->ucWlanIndex; + break; + case MSDU_REMOVE_BY_BSS_INDEX: + ucRemoveByIndex = prMsduInfo->ucBssIndex; + break; + case MSDU_REMOVE_BY_ALL: + ucRemoveByIndex = 0xFF; + break; + default: + break; + } + + if (ucRemoveByIndex == ucIndex) { + DBGLOG(TX, TRACE, + "%s: Get Msdu WIDX:PID[%u:%u] SEQ[%u] from Pending Q\n", + __func__, prMsduInfo->ucWlanIndex, + prMsduInfo->ucPID, + prMsduInfo->ucTxSeqNum); + + if (prMsduInfoListHead == NULL) { + prMsduInfoListHead = + prMsduInfoListTail = prMsduInfo; + } else { + QM_TX_SET_NEXT_MSDU_INFO( + prMsduInfoListTail, prMsduInfo); + prMsduInfoListTail = prMsduInfo; + } + } else { + QUEUE_INSERT_TAIL(prTxingQue, prQueueEntry); + + prMsduInfo = NULL; + } + + QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, + struct QUE_ENTRY *); + } + QUEUE_CONCATENATE_QUEUES(prTxingQue, prTempQue); + + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); + + /* free */ + if (prMsduInfoListHead) { + nicTxFreeMsduInfoPacket(prAdapter, prMsduInfoListHead); + nicTxReturnMsduInfo(prAdapter, prMsduInfoListHead); + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This procedure is used to retrieve a CMD sequence number atomically + * + * @param prAdapter Pointer of ADAPTER_T + * + * @retval - UINT_8 + */ +/*----------------------------------------------------------------------------*/ +uint8_t nicIncreaseCmdSeqNum(IN struct ADAPTER *prAdapter) +{ + uint8_t ucRetval; + + KAL_SPIN_LOCK_DECLARATION(); + + ASSERT(prAdapter); + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_SEQ_NUM); + + prAdapter->ucCmdSeqNum++; + ucRetval = prAdapter->ucCmdSeqNum; + + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_SEQ_NUM); + + return ucRetval; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This procedure is used to retrieve a TX sequence number atomically + * + * @param prAdapter Pointer of ADAPTER_T + * + * @retval - UINT_8 + */ +/*----------------------------------------------------------------------------*/ +uint8_t nicIncreaseTxSeqNum(IN struct ADAPTER *prAdapter) +{ + uint8_t ucRetval; + + KAL_SPIN_LOCK_DECLARATION(); + + ASSERT(prAdapter); + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_SEQ_NUM); + + ucRetval = prAdapter->ucTxSeqNum; + + prAdapter->ucTxSeqNum++; + + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_SEQ_NUM); + + return ucRetval; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This utility function is used to handle + * media state change event + * + * @param + * + * @retval + */ +/*----------------------------------------------------------------------------*/ +uint32_t +nicMediaStateChange(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN struct EVENT_CONNECTION_STATUS *prConnectionStatus) +{ + struct GLUE_INFO *prGlueInfo; + struct AIS_FSM_INFO *prAisFsmInfo; + + ASSERT(prAdapter); + prGlueInfo = prAdapter->prGlueInfo; + + switch (GET_BSS_INFO_BY_INDEX(prAdapter, + ucBssIndex)->eNetworkType) { + case NETWORK_TYPE_AIS: + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + if (prConnectionStatus->ucMediaStatus == + MEDIA_STATE_DISCONNECTED) { /* disconnected */ + if (kalGetMediaStateIndicated(prGlueInfo, + ucBssIndex) != + MEDIA_STATE_DISCONNECTED || + prAisFsmInfo->eCurrentState == AIS_STATE_JOIN) { + + kalIndicateStatusAndComplete(prGlueInfo, + WLAN_STATUS_MEDIA_DISCONNECT, NULL, + 0, ucBssIndex); + + prAdapter->rWlanInfo.u4SysTime = + kalGetTimeTick(); + } + + /* reset buffered link quality information */ + prAdapter->rLinkQuality.rLq[ucBssIndex]. + fgIsLinkQualityValid = FALSE; + prAdapter->rLinkQuality.rLq[ucBssIndex]. + fgIsLinkRateValid = FALSE; + } else if (prConnectionStatus->ucMediaStatus == + MEDIA_STATE_CONNECTED) { /* connected */ + struct PARAM_BSSID_EX *prCurrBssid = + aisGetCurrBssId(prAdapter, ucBssIndex); + + prAdapter->rWlanInfo.u4SysTime = kalGetTimeTick(); + + /* fill information for association result */ + prCurrBssid->rSsid.u4SsidLen = + prConnectionStatus->ucSsidLen; + kalMemCopy( + prCurrBssid->rSsid.aucSsid, + prConnectionStatus->aucSsid, + prConnectionStatus->ucSsidLen); + kalMemCopy(prCurrBssid->arMacAddress, + prConnectionStatus->aucBssid, MAC_ADDR_LEN); + prCurrBssid->u4Privacy = + prConnectionStatus->ucEncryptStatus;/* @FIXME */ + prCurrBssid->rRssi = 0; /* @FIXME */ + prCurrBssid->eNetworkTypeInUse = + PARAM_NETWORK_TYPE_AUTOMODE;/* @FIXME */ + prCurrBssid-> + rConfiguration.u4BeaconPeriod + = prConnectionStatus->u2BeaconPeriod; + prCurrBssid-> + rConfiguration.u4ATIMWindow + = prConnectionStatus->u2ATIMWindow; + prCurrBssid-> + rConfiguration.u4DSConfig = + prConnectionStatus->u4FreqInKHz; + prAdapter->rWlanInfo.ucNetworkType[ucBssIndex] = + prConnectionStatus->ucNetworkType; + prCurrBssid->eOpMode + = (enum ENUM_PARAM_OP_MODE) + prConnectionStatus->ucInfraMode; + + /* always indicate to OS according to + * MSDN (re-association/roaming) + */ + if (kalGetMediaStateIndicated(prGlueInfo, + ucBssIndex) != + MEDIA_STATE_CONNECTED) { + kalIndicateStatusAndComplete(prGlueInfo, + WLAN_STATUS_MEDIA_CONNECT, NULL, + 0, ucBssIndex); + } else { + /* connected -> connected : roaming ? */ + kalIndicateStatusAndComplete(prGlueInfo, + WLAN_STATUS_ROAM_OUT_FIND_BEST, + NULL, + 0, ucBssIndex); + } + } + break; + +#if CFG_ENABLE_BT_OVER_WIFI + case NETWORK_TYPE_BOW: + break; +#endif + +#if CFG_ENABLE_WIFI_DIRECT + case NETWORK_TYPE_P2P: + break; +#endif + default: + ASSERT(0); + } + + return WLAN_STATUS_SUCCESS; +} /* nicMediaStateChange */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This utility function is used to generate a join failure event to OS + * + * @param + * + * @retval + */ +/*----------------------------------------------------------------------------*/ +uint32_t nicMediaJoinFailure(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, IN uint32_t rStatus) +{ + struct GLUE_INFO *prGlueInfo; + + ASSERT(prAdapter); + prGlueInfo = prAdapter->prGlueInfo; + + switch (GET_BSS_INFO_BY_INDEX(prAdapter, + ucBssIndex)->eNetworkType) { + case NETWORK_TYPE_AIS: + kalIndicateStatusAndComplete(prGlueInfo, rStatus, NULL, 0, + ucBssIndex); + + break; + + case NETWORK_TYPE_BOW: + case NETWORK_TYPE_P2P: + default: + break; + } + + return WLAN_STATUS_SUCCESS; +} /* end of nicMediaJoinFailure() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This utility function is used to convert between + * frequency and channel number + * + * @param u4ChannelNum + * + * @retval - Frequency in unit of KHz, 0 for invalid channel number + */ +/*----------------------------------------------------------------------------*/ +uint32_t nicChannelNum2Freq(uint32_t u4ChannelNum) +{ + uint32_t u4ChannelInMHz; + + if (u4ChannelNum >= 1 && u4ChannelNum <= 13) + u4ChannelInMHz = 2412 + (u4ChannelNum - 1) * 5; + else if (u4ChannelNum == 14) + u4ChannelInMHz = 2484; + else if (u4ChannelNum == 133) + u4ChannelInMHz = 3665; /* 802.11y */ + else if (u4ChannelNum == 137) + u4ChannelInMHz = 3685; /* 802.11y */ + else if ((u4ChannelNum >= 34 && u4ChannelNum <= 181) + || (u4ChannelNum == 16)) + u4ChannelInMHz = 5000 + u4ChannelNum * 5; + else if (u4ChannelNum >= 182 && u4ChannelNum <= 196) + u4ChannelInMHz = 4000 + u4ChannelNum * 5; + else if (u4ChannelNum == 201) + u4ChannelInMHz = 2730; + else if (u4ChannelNum == 202) + u4ChannelInMHz = 2498; + else + u4ChannelInMHz = 0; + + return 1000 * u4ChannelInMHz; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This utility function is used to convert between + * frequency and channel number + * + * @param u4FreqInKHz + * + * @retval - Frequency Number, 0 for invalid freqency + */ +/*----------------------------------------------------------------------------*/ +uint32_t nicFreq2ChannelNum(uint32_t u4FreqInKHz) +{ + switch (u4FreqInKHz) { + case 2412000: + return 1; + case 2417000: + return 2; + case 2422000: + return 3; + case 2427000: + return 4; + case 2432000: + return 5; + case 2437000: + return 6; + case 2442000: + return 7; + case 2447000: + return 8; + case 2452000: + return 9; + case 2457000: + return 10; + case 2462000: + return 11; + case 2467000: + return 12; + case 2472000: + return 13; + case 2484000: + return 14; + case 3665000: + return 133; /* 802.11y */ + case 3685000: + return 137; /* 802.11y */ + case 4915000: + return 183; + case 4920000: + return 184; + case 4925000: + return 185; + case 4930000: + return 186; + case 4935000: + return 187; + case 4940000: + return 188; + case 4945000: + return 189; + case 4960000: + return 192; + case 4980000: + return 196; + case 5170000: + return 34; + case 5180000: + return 36; + case 5190000: + return 38; + case 5200000: + return 40; + case 5210000: + return 42; + case 5220000: + return 44; + case 5230000: + return 46; + case 5240000: + return 48; + case 5250000: + return 50; + case 5260000: + return 52; + case 5270000: + return 54; + case 5280000: + return 56; + case 5290000: + return 58; + case 5300000: + return 60; + case 5310000: + return 62; + case 5320000: + return 64; + case 5500000: + return 100; + case 5510000: + return 102; + case 5520000: + return 104; + case 5530000: + return 106; + case 5540000: + return 108; + case 5550000: + return 110; + case 5560000: + return 112; + case 5570000: + return 114; + case 5580000: + return 116; + case 5590000: + return 118; + case 5600000: + return 120; + case 5610000: + return 122; + case 5620000: + return 124; + case 5630000: + return 126; + case 5640000: + return 128; + case 5660000: + return 132; + case 5670000: + return 134; + case 5680000: + return 136; + case 5690000: + return 138; + case 5700000: + return 140; + case 5710000: + return 142; + case 5720000: + return 144; + case 5745000: + return 149; + case 5755000: + return 151; + case 5765000: + return 153; + case 5775000: + return 155; + case 5785000: + return 157; + case 5795000: + return 159; + case 5805000: + return 161; + case 5825000: + return 165; + case 5845000: + return 169; + case 5865000: + return 173; + default: + DBGLOG(BSS, INFO, "Return Invalid Channelnum = 0.\n"); + return 0; + } +} + +uint8_t nicGetVhtS1(uint8_t ucPrimaryChannel, + uint8_t ucBandwidth) +{ + /* find S1 (central channel 42, 58, 106, 122, and 155) */ + + if ((ucBandwidth == VHT_OP_CHANNEL_WIDTH_80) + || (ucBandwidth == VHT_OP_CHANNEL_WIDTH_80P80)) { + + if (ucPrimaryChannel >= 36 && ucPrimaryChannel <= 48) + return 42; + else if (ucPrimaryChannel >= 52 && ucPrimaryChannel <= 64) + return 58; + else if (ucPrimaryChannel >= 100 && ucPrimaryChannel <= 112) + return 106; + else if (ucPrimaryChannel >= 116 && ucPrimaryChannel <= 128) + return 122; + else if (ucPrimaryChannel >= 132 && ucPrimaryChannel <= 144) + return 138; + else if (ucPrimaryChannel >= 149 && ucPrimaryChannel <= 161) + return 155; + + } else if (ucBandwidth == VHT_OP_CHANNEL_WIDTH_160) { + + if (ucPrimaryChannel >= 36 && ucPrimaryChannel <= 64) + return 50; + else if (ucPrimaryChannel >= 100 && ucPrimaryChannel <= 128) + return 114; + + } else { + + return 0; + } + + return 0; + +} + +/* firmware command wrapper */ +/* NETWORK (WIFISYS) */ +/*----------------------------------------------------------------------------*/ +/*! + * @brief This utility function is used to activate WIFISYS for specified + * network + * + * @param prAdapter Pointer of ADAPTER_T + * eNetworkTypeIdx Index of network type + * + * @retval - + */ +/*----------------------------------------------------------------------------*/ +uint32_t nicActivateNetwork(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) +{ + struct CMD_BSS_ACTIVATE_CTRL rCmdActivateCtrl; + struct BSS_INFO *prBssInfo; + /* const UINT_8 aucZeroMacAddr[] = NULL_MAC_ADDR; */ + + ASSERT(prAdapter); + ASSERT(ucBssIndex <= prAdapter->ucHwBssIdNum); + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + + prBssInfo->fg40mBwAllowed = FALSE; + prBssInfo->fgAssoc40mBwAllowed = FALSE; + + rCmdActivateCtrl.ucBssIndex = ucBssIndex; + rCmdActivateCtrl.ucActive = 1; + rCmdActivateCtrl.ucNetworkType = (uint8_t) + prBssInfo->eNetworkType; + rCmdActivateCtrl.ucOwnMacAddrIndex = + prBssInfo->ucOwnMacIndex; + COPY_MAC_ADDR(rCmdActivateCtrl.aucBssMacAddr, + prBssInfo->aucOwnMacAddr); + + prBssInfo->ucBMCWlanIndex = + secPrivacySeekForBcEntry(prAdapter, prBssInfo->ucBssIndex, + prBssInfo->aucOwnMacAddr, + STA_REC_INDEX_NOT_FOUND, + CIPHER_SUITE_NONE, 0xFF); + rCmdActivateCtrl.ucBMCWlanIndex = prBssInfo->ucBMCWlanIndex; + + kalMemZero(&rCmdActivateCtrl.ucReserved, + sizeof(rCmdActivateCtrl.ucReserved)); + +#if 1 /* DBG */ + DBGLOG_LIMITED(RSN, INFO, + "[BSS index]=%d OwnMac%d=" MACSTR " BSSID=" MACSTR + " BMCIndex = %d NetType=%d\n", + ucBssIndex, + prBssInfo->ucOwnMacIndex, + MAC2STR(prBssInfo->aucOwnMacAddr), + MAC2STR(prBssInfo->aucBSSID), + prBssInfo->ucBMCWlanIndex, prBssInfo->eNetworkType); +#endif + + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_BSS_ACTIVATE_CTRL, + TRUE, + FALSE, + FALSE, + NULL, NULL, + sizeof(struct CMD_BSS_ACTIVATE_CTRL), + (uint8_t *)&rCmdActivateCtrl, NULL, 0); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This utility function is used to deactivate WIFISYS for specified + * network + * + * @param prAdapter Pointer of ADAPTER_T + * eNetworkTypeIdx Index of network type + * + * @retval - + */ +/*----------------------------------------------------------------------------*/ +uint32_t nicDeactivateNetwork(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) +{ + uint32_t u4Status; + struct CMD_BSS_ACTIVATE_CTRL rCmdActivateCtrl; + struct BSS_INFO *prBssInfo; + + ASSERT(prAdapter); + ASSERT(ucBssIndex <= prAdapter->ucHwBssIdNum); + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + + /* FW only supports BMCWlan index 0 ~ 31. + * it always checks BMCWlan index validity and triggers + * assertion if BMCWlan index is invalid. + */ + if (prBssInfo->ucBMCWlanIndex == WTBL_RESERVED_ENTRY) { + DBGLOG(RSN, WARN, + "Network may be deactivated already, ignore\n"); + return WLAN_STATUS_NOT_ACCEPTED; + } + + kalMemZero(&rCmdActivateCtrl, + sizeof(struct CMD_BSS_ACTIVATE_CTRL)); + + rCmdActivateCtrl.ucBssIndex = ucBssIndex; + rCmdActivateCtrl.ucActive = 0; + rCmdActivateCtrl.ucNetworkType = + (uint8_t)prBssInfo->eNetworkType; + rCmdActivateCtrl.ucOwnMacAddrIndex = + prBssInfo->ucOwnMacIndex; + rCmdActivateCtrl.ucBMCWlanIndex = + prBssInfo->ucBMCWlanIndex; + + DBGLOG_LIMITED(RSN, INFO, + "[BSS index]=%d OwnMac=" MACSTR " BSSID=" MACSTR + " BMCIndex = %d NetType=%d\n", + ucBssIndex, + MAC2STR(prBssInfo->aucOwnMacAddr), + MAC2STR(prBssInfo->aucBSSID), + prBssInfo->ucBMCWlanIndex, prBssInfo->eNetworkType); + + u4Status = wlanSendSetQueryCmd(prAdapter, + CMD_ID_BSS_ACTIVATE_CTRL, + TRUE, + FALSE, + FALSE, + NULL, + NULL, + sizeof(struct CMD_BSS_ACTIVATE_CTRL), + (uint8_t *)&rCmdActivateCtrl, NULL, 0); + + secRemoveBssBcEntry(prAdapter, prBssInfo, FALSE); + + /* free all correlated station records */ + cnmStaFreeAllStaByNetwork(prAdapter, ucBssIndex, + STA_REC_EXCLUDE_NONE); + if (HAL_IS_TX_DIRECT(prAdapter)) + nicTxDirectClearBssAbsentQ(prAdapter, ucBssIndex); + else + qmFreeAllByBssIdx(prAdapter, ucBssIndex); + + nicFreePendingTxMsduInfo(prAdapter, ucBssIndex, + MSDU_REMOVE_BY_BSS_INDEX); + kalClearSecurityFramesByBssIdx(prAdapter->prGlueInfo, ucBssIndex); + + cnmFreeWmmIndex(prAdapter, prBssInfo); + return u4Status; +} + +/* BSS-INFO */ +/*----------------------------------------------------------------------------*/ +/*! + * @brief This utility function is used to sync bss info with firmware + * when a new BSS has been connected or disconnected + * + * @param prAdapter Pointer of ADAPTER_T + * ucBssIndex Index of BSS-INFO + * + * @retval - + */ +/*----------------------------------------------------------------------------*/ +uint32_t nicUpdateBss(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) +{ + uint32_t u4Status = WLAN_STATUS_NOT_ACCEPTED; + struct BSS_INFO *prBssInfo; + struct CMD_SET_BSS_INFO rCmdSetBssInfo; + + ASSERT(prAdapter); + ASSERT(ucBssIndex <= prAdapter->ucHwBssIdNum); + + prBssInfo = prAdapter->aprBssInfo[ucBssIndex]; + + kalMemZero(&rCmdSetBssInfo, + sizeof(struct CMD_SET_BSS_INFO)); + + rCmdSetBssInfo.ucBssIndex = ucBssIndex; + rCmdSetBssInfo.ucConnectionState = (uint8_t) + prBssInfo->eConnectionState; + rCmdSetBssInfo.ucCurrentOPMode = (uint8_t) + prBssInfo->eCurrentOPMode; + rCmdSetBssInfo.ucSSIDLen = (uint8_t) prBssInfo->ucSSIDLen; + kalMemCopy(rCmdSetBssInfo.aucSSID, prBssInfo->aucSSID, + prBssInfo->ucSSIDLen); + COPY_MAC_ADDR(rCmdSetBssInfo.aucBSSID, prBssInfo->aucBSSID); + rCmdSetBssInfo.ucIsQBSS = (uint8_t) prBssInfo->fgIsQBSS; + rCmdSetBssInfo.ucNonHTBasicPhyType = + prBssInfo->ucNonHTBasicPhyType; + rCmdSetBssInfo.u2OperationalRateSet = + prBssInfo->u2OperationalRateSet; + rCmdSetBssInfo.u2BSSBasicRateSet = + prBssInfo->u2BSSBasicRateSet; + rCmdSetBssInfo.u2HwDefaultFixedRateCode = + prBssInfo->u2HwDefaultFixedRateCode; + rCmdSetBssInfo.ucPhyTypeSet = prBssInfo->ucPhyTypeSet; + rCmdSetBssInfo.u4PrivateData = prBssInfo->u4PrivateData; +#if CFG_SUPPORT_DBDC + /* + *To do: In fact, this is not used anymore and could be removed now. + *But command structure change has driver and firmware dependency. + *So currently using ENUM_BAND_AUTO is a temporary solution. + */ + rCmdSetBssInfo.ucDBDCBand = ENUM_BAND_AUTO; +#endif + rCmdSetBssInfo.ucWmmSet = prBssInfo->ucWmmQueSet; + rCmdSetBssInfo.ucNss = prBssInfo->ucOpTxNss; /* Backward compatible */ + + if (prBssInfo->fgBcDefaultKeyExist) { + if (prBssInfo->wepkeyWlanIdx < + prAdapter->ucTxDefaultWlanIndex) + rCmdSetBssInfo.ucBMCWlanIndex = + prBssInfo->wepkeyWlanIdx; + else if (prBssInfo->ucBMCWlanIndexSUsed[ + prBssInfo->ucBcDefaultKeyIdx]) + rCmdSetBssInfo.ucBMCWlanIndex = + prBssInfo->ucBMCWlanIndexS[ + prBssInfo->ucBcDefaultKeyIdx]; + } else + rCmdSetBssInfo.ucBMCWlanIndex = prBssInfo->ucBMCWlanIndex; + + DBGLOG(RSN, TRACE, "Update BSS BMC WlanIdx %u\n", + rCmdSetBssInfo.ucBMCWlanIndex); + +#if CFG_ENABLE_WIFI_DIRECT + rCmdSetBssInfo.ucHiddenSsidMode = + prBssInfo->eHiddenSsidType; +#endif + rlmFillSyncCmdParam(&rCmdSetBssInfo.rBssRlmParam, + prBssInfo); + + rCmdSetBssInfo.ucWapiMode = (uint8_t) FALSE; + + if (IS_BSS_AIS(prBssInfo)) { + struct CONNECTION_SETTINGS *prConnSettings = + aisGetConnSettings(prAdapter, ucBssIndex); +#if CFG_SUPPORT_PASSPOINT + /* mapping OSEN to WPA2, + * due to firmware no need to know current is OSEN + */ + if (prConnSettings->eAuthMode == AUTH_MODE_WPA_OSEN) + rCmdSetBssInfo.ucAuthMode = AUTH_MODE_WPA2; + else +#endif + rCmdSetBssInfo.ucAuthMode = (uint8_t) prConnSettings->eAuthMode; + rCmdSetBssInfo.ucEncStatus = (uint8_t) + prConnSettings->eEncStatus; + rCmdSetBssInfo.ucWapiMode = (uint8_t) + prConnSettings->fgWapiMode; + } +#if CFG_ENABLE_BT_OVER_WIFI + else if (IS_BSS_BOW(prBssInfo)) { + rCmdSetBssInfo.ucAuthMode = (uint8_t) AUTH_MODE_WPA2_PSK; + rCmdSetBssInfo.ucEncStatus = (uint8_t) + ENUM_ENCRYPTION3_KEY_ABSENT; + } +#endif + else { +#if CFG_ENABLE_WIFI_DIRECT + if (prAdapter->fgIsP2PRegistered) { + if (kalP2PGetCcmpCipher(prAdapter->prGlueInfo, + (uint8_t) prBssInfo->u4PrivateData)) { + rCmdSetBssInfo.ucAuthMode = + (uint8_t) AUTH_MODE_WPA2_PSK; + rCmdSetBssInfo.ucEncStatus = + (uint8_t) + ENUM_ENCRYPTION3_ENABLED; + } else if (kalP2PGetTkipCipher(prAdapter->prGlueInfo, + (uint8_t) prBssInfo->u4PrivateData)) { + rCmdSetBssInfo.ucAuthMode = + (uint8_t) AUTH_MODE_WPA_PSK; + rCmdSetBssInfo.ucEncStatus = + (uint8_t) ENUM_ENCRYPTION2_ENABLED; + } else if (kalP2PGetWepCipher(prAdapter->prGlueInfo, + (uint8_t) prBssInfo->u4PrivateData)) { + rCmdSetBssInfo.ucAuthMode = + (uint8_t) AUTH_MODE_OPEN; + rCmdSetBssInfo.ucEncStatus = + (uint8_t) ENUM_ENCRYPTION1_ENABLED; + } else { + rCmdSetBssInfo.ucAuthMode = + (uint8_t) AUTH_MODE_OPEN; + rCmdSetBssInfo.ucEncStatus = + (uint8_t) ENUM_ENCRYPTION_DISABLED; + } + /* Need the probe response to detect the PBC overlap */ + rCmdSetBssInfo.ucIsApMode = + p2pFuncIsAPMode( + prAdapter->rWifiVar.prP2PConnSettings[ + prBssInfo->u4PrivateData]); + + } +#else + rCmdSetBssInfo.ucAuthMode = (uint8_t) AUTH_MODE_WPA2_PSK; + rCmdSetBssInfo.ucEncStatus = (uint8_t) + ENUM_ENCRYPTION3_KEY_ABSENT; +#endif + } + rCmdSetBssInfo.ucDisconnectDetectThreshold = 0; + + if (IS_BSS_AIS(prBssInfo) && + (prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) && + (prBssInfo->prStaRecOfAP != NULL)) { + struct BSS_DESC *prBssDesc; + struct AIS_FSM_INFO *prAisFsmInfo; + + rCmdSetBssInfo.ucStaRecIdxOfAP = + prBssInfo->prStaRecOfAP->ucIndex; + cnmAisInfraConnectNotify(prAdapter); + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + prBssDesc = prAisFsmInfo->prTargetBssDesc; + if (prBssDesc != NULL) + rCmdSetBssInfo.ucIotApAct = prBssDesc->ucIotApAct; +#if CFG_SUPPORT_SMART_GEAR + DBGLOG(SW4, INFO, "[SG]cnmAisInfraConnectNotify,%d\n", + prBssInfo->eConnectionState); + if (prBssInfo->eConnectionState == MEDIA_STATE_CONNECTED) { + uint8_t ucSGEnable = TRUE, ucRetValNss = 0; + ucRetValNss = wlanGetSupportNss(prAdapter, ucBssIndex); + DBGLOG(SW4, INFO, "[SG]SG Get NSS,%d\n", ucRetValNss); + if (rCmdSetBssInfo.ucIotApAct == WLAN_IOT_AP_DIS_SG) { + DBGLOG(SW4, INFO, + "[SG]Hit SG blacklist, disable SG\n"); + ucSGEnable = FALSE; + } + /*Send Event to Enable/Disable SG*/ + wlandioSetSGStatus(prAdapter, + ucSGEnable, 0xFF, ucRetValNss); + } +#endif + } +#if CFG_ENABLE_WIFI_DIRECT + else if ((prAdapter->fgIsP2PRegistered) && + (prBssInfo->eNetworkType == NETWORK_TYPE_P2P) && + (prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) + && (prBssInfo->prStaRecOfAP != NULL)) { + rCmdSetBssInfo.ucStaRecIdxOfAP = + prBssInfo->prStaRecOfAP->ucIndex; + } +#endif + +#if CFG_ENABLE_BT_OVER_WIFI +/* disabled for BOW to finish ucBssIndex migration */ + else if (prBssInfo->eNetworkType == NETWORK_TYPE_BOW && + prBssInfo->eCurrentOPMode == OP_MODE_BOW + && prBssInfo->prStaRecOfAP != NULL) { + rCmdSetBssInfo.ucStaRecIdxOfAP = + prBssInfo->prStaRecOfAP->ucIndex; + } +#endif + else + rCmdSetBssInfo.ucStaRecIdxOfAP = STA_REC_INDEX_NOT_FOUND; + +#if (CFG_SUPPORT_802_11AX == 1) + if (fgEfuseCtrlAxOn == 1) { + memcpy(rCmdSetBssInfo.ucHeOpParams, prBssInfo->ucHeOpParams, + HE_OP_BYTE_NUM); + rCmdSetBssInfo.ucBssColorInfo = prBssInfo->ucBssColorInfo; + rCmdSetBssInfo.u2HeBasicMcsSet = + CPU_TO_LE16(prBssInfo->u2HeBasicMcsSet); + } +#endif + +#if (CFG_SUPPORT_802_11V_MBSSID == 1) + rCmdSetBssInfo.ucMaxBSSIDIndicator = prBssInfo->ucMaxBSSIDIndicator; + rCmdSetBssInfo.ucMBSSIDIndex = prBssInfo->ucMBSSIDIndex; +#endif + + DBGLOG(BSS, INFO, + "Update Bss[%u] ConnState[%u] OPmode[%u] BSSID[" MACSTR + "] AuthMode[%u] EncStatus[%u] IotAct[%u]\n", ucBssIndex, + prBssInfo->eConnectionState, + prBssInfo->eCurrentOPMode, MAC2STR(prBssInfo->aucBSSID), + rCmdSetBssInfo.ucAuthMode, + rCmdSetBssInfo.ucEncStatus, + rCmdSetBssInfo.ucIotApAct); + + u4Status = wlanSendSetQueryCmd(prAdapter, + CMD_ID_SET_BSS_INFO, + TRUE, + FALSE, + FALSE, + NULL, NULL, + sizeof(struct CMD_SET_BSS_INFO), + (uint8_t *)&rCmdSetBssInfo, NULL, 0); + + /* if BSS-INFO is going to be disconnected state, + * free all correlated station records + */ + if (prBssInfo->eConnectionState == + MEDIA_STATE_DISCONNECTED) { + /* clear client list */ + bssInitializeClientList(prAdapter, prBssInfo); + +#if DBG + DBGLOG(BSS, TRACE, "nicUpdateBss for disconnect state\n"); +#endif + /* free all correlated station records */ + cnmStaFreeAllStaByNetwork(prAdapter, ucBssIndex, + STA_REC_EXCLUDE_NONE); + if (HAL_IS_TX_DIRECT(prAdapter)) + nicTxDirectClearBssAbsentQ(prAdapter, ucBssIndex); + else + qmFreeAllByBssIdx(prAdapter, ucBssIndex); + kalClearSecurityFramesByBssIdx(prAdapter->prGlueInfo, + ucBssIndex); +#if CFG_ENABLE_GTK_FRAME_FILTER + if (prBssInfo->prIpV4NetAddrList) + FREE_IPV4_NETWORK_ADDR_LIST( + prBssInfo->prIpV4NetAddrList); +#endif +#if CFG_SUPPORT_DBDC + cnmDbdcRuntimeCheckDecision(prAdapter, ucBssIndex); +#endif + } + + return u4Status; +} + +/* BSS-INFO Indication (PM) */ +/*----------------------------------------------------------------------------*/ +/*! + * @brief This utility function is used to indicate PM that + * a BSS has been created. (for AdHoc / P2P-GO) + * + * @param prAdapter Pointer of ADAPTER_T + * ucBssIndex Index of BSS-INFO + * + * @retval - + */ +/*----------------------------------------------------------------------------*/ +uint32_t nicPmIndicateBssCreated(IN struct ADAPTER + *prAdapter, IN uint8_t ucBssIndex) +{ + struct BSS_INFO *prBssInfo; + struct CMD_INDICATE_PM_BSS_CREATED rCmdIndicatePmBssCreated; + + ASSERT(prAdapter); + ASSERT(ucBssIndex <= prAdapter->ucHwBssIdNum); + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + + rCmdIndicatePmBssCreated.ucBssIndex = ucBssIndex; + rCmdIndicatePmBssCreated.ucDtimPeriod = + prBssInfo->ucDTIMPeriod; + rCmdIndicatePmBssCreated.u2BeaconInterval = + prBssInfo->u2BeaconInterval; + rCmdIndicatePmBssCreated.u2AtimWindow = + prBssInfo->u2ATIMWindow; + + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_INDICATE_PM_BSS_CREATED, + TRUE, + FALSE, + FALSE, + NULL, + NULL, + sizeof(struct CMD_INDICATE_PM_BSS_CREATED), + (uint8_t *)&rCmdIndicatePmBssCreated, NULL, 0); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This utility function is used to indicate PM that + * a BSS has been connected + * + * @param prAdapter Pointer of ADAPTER_T + * eNetworkTypeIdx Index of BSS-INFO + * + * @retval - + */ +/*----------------------------------------------------------------------------*/ +uint32_t nicPmIndicateBssConnected(IN struct ADAPTER + *prAdapter, IN uint8_t ucBssIndex) +{ + struct BSS_INFO *prBssInfo; + struct CMD_INDICATE_PM_BSS_CONNECTED + rCmdIndicatePmBssConnected; + + ASSERT(prAdapter); + ASSERT(ucBssIndex <= prAdapter->ucHwBssIdNum); + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + + rCmdIndicatePmBssConnected.ucBssIndex = ucBssIndex; + rCmdIndicatePmBssConnected.ucDtimPeriod = + prBssInfo->ucDTIMPeriod; + rCmdIndicatePmBssConnected.u2AssocId = prBssInfo->u2AssocId; + rCmdIndicatePmBssConnected.u2BeaconInterval = + prBssInfo->u2BeaconInterval; + rCmdIndicatePmBssConnected.u2AtimWindow = + prBssInfo->u2ATIMWindow; + + rCmdIndicatePmBssConnected.ucBmpDeliveryAC = + prBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC; + rCmdIndicatePmBssConnected.ucBmpTriggerAC = + prBssInfo->rPmProfSetupInfo.ucBmpTriggerAC; + + /* rCmdIndicatePmBssConnected.ucBmpDeliveryAC, */ + /* rCmdIndicatePmBssConnected.ucBmpTriggerAC); */ + + if ((GET_BSS_INFO_BY_INDEX(prAdapter, + ucBssIndex)->eNetworkType == NETWORK_TYPE_AIS) +#if CFG_ENABLE_WIFI_DIRECT + || ((GET_BSS_INFO_BY_INDEX(prAdapter, + ucBssIndex)->eNetworkType == NETWORK_TYPE_P2P) + && (prAdapter->fgIsP2PRegistered)) +#endif + ) { + if (prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE && + prBssInfo->prStaRecOfAP) { + uint8_t ucUapsd = wmmCalculateUapsdSetting(prAdapter, + ucBssIndex); + + /* should sync Tspec uapsd settings */ + rCmdIndicatePmBssConnected.ucBmpDeliveryAC = + (ucUapsd >> 4) & 0xf; + rCmdIndicatePmBssConnected.ucBmpTriggerAC = + ucUapsd & 0xf; + rCmdIndicatePmBssConnected.fgIsUapsdConnection = + (uint8_t) prBssInfo->prStaRecOfAP-> + fgIsUapsdSupported; + } else { + rCmdIndicatePmBssConnected.fgIsUapsdConnection = + 0; /* @FIXME */ + } + } else { + rCmdIndicatePmBssConnected.fgIsUapsdConnection = 0; + } + + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_INDICATE_PM_BSS_CONNECTED, + TRUE, + FALSE, + FALSE, + NULL, + NULL, + sizeof(struct CMD_INDICATE_PM_BSS_CONNECTED), + (uint8_t *)&rCmdIndicatePmBssConnected, NULL, 0); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This utility function is used to indicate PM that + * a BSS has been disconnected + * + * @param prAdapter Pointer of ADAPTER_T + * ucBssIndex Index of BSS-INFO + * + * @retval - + */ +/*----------------------------------------------------------------------------*/ +uint32_t nicPmIndicateBssAbort(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) +{ + struct CMD_INDICATE_PM_BSS_ABORT rCmdIndicatePmBssAbort; + + ASSERT(prAdapter); + ASSERT(ucBssIndex <= prAdapter->ucHwBssIdNum); + + rCmdIndicatePmBssAbort.ucBssIndex = ucBssIndex; + + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_INDICATE_PM_BSS_ABORT, + TRUE, + FALSE, + FALSE, + NULL, + NULL, + sizeof(struct CMD_INDICATE_PM_BSS_ABORT), + (uint8_t *)&rCmdIndicatePmBssAbort, NULL, 0); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This utility function is used to set power save bit map + * + * + * @param prAdapter Pointer of ADAPTER_T + * ucBssIndex Index of BSS-INFO + * ucSet enter power save or not(1 PS, 0 not PS) + * ucCaller index of bit map for caller + * @retval - + */ +/*----------------------------------------------------------------------------*/ +void +nicPowerSaveInfoMap(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN enum PARAM_POWER_MODE ePowerMode, + IN enum POWER_SAVE_CALLER ucCaller) +{ + uint32_t u4Flag; + + /* max caller is 24 */ + if (ucCaller >= PS_CALLER_MAX_NUM) + ASSERT(0); + + u4Flag = prAdapter->rWlanInfo.u4PowerSaveFlag[ucBssIndex]; + + /* set send command flag */ + if (ePowerMode != Param_PowerModeCAM) { + if ((u4Flag & 0x00FFFFFF) == BIT(ucCaller)) + u4Flag |= PS_SYNC_WITH_FW; + u4Flag &= ~BIT(ucCaller); + } else { + if (u4Flag == 0) + u4Flag |= PS_SYNC_WITH_FW; + u4Flag |= BIT(ucCaller); + } + + DBGLOG(NIC, INFO, + "Flag=0x%04x, Caller=%d, PM=%d, PSFlag[%d]=0x%04x\n", + u4Flag, ucCaller, ePowerMode, ucBssIndex, + prAdapter->rWlanInfo.u4PowerSaveFlag[ucBssIndex]); + + prAdapter->rWlanInfo.u4PowerSaveFlag[ucBssIndex] = u4Flag; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This utility function is used to set power save profile + * + * + * @param prAdapter Pointer of ADAPTER_T + * ucBssIndex Index of BSS-INFO + * ucSet enter power save or not(1 PS, 0 not PS) + * fgEnCmdEvent Enable the functions when command done and timeout + * ucCaller index of bit map for caller + * + * @retval WLAN_STATUS_SUCCESS + * @retval WLAN_STATUS_PENDING + * @retval WLAN_STATUS_FAILURE + * @retval WLAN_STATUS_NOT_SUPPORTED + */ +/*----------------------------------------------------------------------------*/ +uint32_t +nicConfigPowerSaveProfile(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN enum PARAM_POWER_MODE ePwrMode, + IN u_int8_t fgEnCmdEvent, + IN enum POWER_SAVE_CALLER ucCaller) +{ + DEBUGFUNC("nicConfigPowerSaveProfile"); + DBGLOG(INIT, TRACE, + "ucBssIndex:%d, ePwrMode:%d, fgEnCmdEvent:%d\n", + ucBssIndex, ePwrMode, fgEnCmdEvent); + + ASSERT(prAdapter); + + if (ucBssIndex >= prAdapter->ucHwBssIdNum) { + ASSERT(0); + return WLAN_STATUS_NOT_SUPPORTED; + } + + nicPowerSaveInfoMap(prAdapter, ucBssIndex, ePwrMode, ucCaller); + + prAdapter->rWlanInfo.arPowerSaveMode[ucBssIndex].ucBssIndex + = ucBssIndex; + prAdapter->rWlanInfo.arPowerSaveMode[ucBssIndex].ucPsProfile + = (uint8_t) ePwrMode; + + if (PS_SYNC_WITH_FW + & prAdapter->rWlanInfo.u4PowerSaveFlag[ucBssIndex]) { + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + + prAdapter->rWlanInfo.u4PowerSaveFlag[ucBssIndex] + &= ~PS_SYNC_WITH_FW; + + DBGLOG(NIC, TRACE, + "SYNC_WITH_FW u4PowerSaveFlag[%d]=0x%04x\n", + ucBssIndex, + prAdapter->rWlanInfo.u4PowerSaveFlag[ucBssIndex]); + + rWlanStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ + CMD_ID_POWER_SAVE_MODE, /* ucCID */ + TRUE, /* fgSetQuery */ + FALSE, /* fgNeedResp */ + fgEnCmdEvent, /* fgIsOid */ + + /* pfCmdDoneHandler */ + (fgEnCmdEvent ? nicCmdEventSetCommon : NULL), + + /* pfCmdTimeoutHandler */ + (fgEnCmdEvent ? nicOidCmdTimeoutCommon : NULL), + + /* u4SetQueryInfoLen */ + sizeof(struct CMD_PS_PROFILE), + + /* pucInfoBuffer */ + (uint8_t *) &(prAdapter->rWlanInfo + .arPowerSaveMode[ucBssIndex]), + + /* pvSetQueryBuffer */ + NULL, + + /* u4SetQueryBufferLen */ + 0 + ); + + if (fgEnCmdEvent) + return rWlanStatus; + } + return WLAN_STATUS_SUCCESS; +} /* end of nicConfigPowerSaveProfile */ + +uint32_t +nicConfigProcSetCamCfgWrite(IN struct ADAPTER *prAdapter, + IN u_int8_t enabled, IN uint8_t ucBssIndex) +{ + enum PARAM_POWER_MODE ePowerMode; + struct CMD_PS_PROFILE rPowerSaveMode; + + if ((!prAdapter)) + return WLAN_STATUS_FAILURE; + + if (ucBssIndex >= BSS_DEFAULT_NUM) + return WLAN_STATUS_FAILURE; + rPowerSaveMode.ucBssIndex = ucBssIndex; + + if (enabled) { + prAdapter->rWlanInfo.fgEnSpecPwrMgt = TRUE; + ePowerMode = Param_PowerModeCAM; + rPowerSaveMode.ucPsProfile = (uint8_t) ePowerMode; + DBGLOG(INIT, INFO, "Enable CAM BssIndex:%d, PowerMode:%d\n", + ucBssIndex, rPowerSaveMode.ucPsProfile); + } else { + prAdapter->rWlanInfo.fgEnSpecPwrMgt = FALSE; + rPowerSaveMode.ucPsProfile = + prAdapter->rWlanInfo.arPowerSaveMode[ucBssIndex]. + ucPsProfile; + DBGLOG(INIT, INFO, + "Disable CAM BssIndex:%d, PowerMode:%d\n", + ucBssIndex, rPowerSaveMode.ucPsProfile); + } + + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_POWER_SAVE_MODE, + TRUE, + FALSE, + FALSE, + NULL, + NULL, + sizeof(struct CMD_PS_PROFILE), + (uint8_t *) &rPowerSaveMode, + NULL, 0); +} + +uint32_t nicEnterCtiaMode(IN struct ADAPTER *prAdapter, + u_int8_t fgEnterCtia, u_int8_t fgEnCmdEvent) +{ + struct CMD_SW_DBG_CTRL rCmdSwCtrl; + /* CMD_ACCESS_REG rCmdAccessReg; */ + uint32_t rWlanStatus; + uint8_t ucBssIdx; + + DEBUGFUNC("nicEnterCtiaMode"); + DBGLOG(INIT, TRACE, "nicEnterCtiaMode: %d\n", fgEnterCtia); + + ASSERT(prAdapter); + + rWlanStatus = WLAN_STATUS_SUCCESS; + + if (fgEnterCtia) { + /* 1. Disable On-Lin Scan */ + prAdapter->fgEnOnlineScan = FALSE; + + /* 2. Disable FIFO FULL no ack */ + /* 3. Disable Roaming */ + /* 4. Disalbe auto tx power */ + rCmdSwCtrl.u4Id = 0xa0100003; + rCmdSwCtrl.u4Data = 0x0; + wlanSendSetQueryCmd(prAdapter, + CMD_ID_SW_DBG_CTRL, + TRUE, + FALSE, + FALSE, NULL, NULL, + sizeof(struct CMD_SW_DBG_CTRL), + (uint8_t *)&rCmdSwCtrl, NULL, 0); + + /* 2. Keep at CAM mode */ + for (ucBssIdx = 0; ucBssIdx < KAL_AIS_NUM; ucBssIdx++) { + enum PARAM_POWER_MODE ePowerMode; + + prAdapter->u4CtiaPowerMode = 0; + prAdapter->fgEnCtiaPowerMode = TRUE; + + ePowerMode = Param_PowerModeCAM; + rWlanStatus = nicConfigPowerSaveProfile(prAdapter, + ucBssIdx, + ePowerMode, fgEnCmdEvent, PS_CALLER_CTIA); + } + + /* 5. Disable Beacon Timeout Detection */ + prAdapter->fgDisBcnLostDetection = TRUE; + } else { + /* 1. Enaable On-Lin Scan */ + prAdapter->fgEnOnlineScan = TRUE; + + /* 2. Enable FIFO FULL no ack */ + /* 3. Enable Roaming */ + /* 4. Enable auto tx power */ + /* */ + + rCmdSwCtrl.u4Id = 0xa0100003; + rCmdSwCtrl.u4Data = 0x1; + wlanSendSetQueryCmd(prAdapter, + CMD_ID_SW_DBG_CTRL, + TRUE, + FALSE, + FALSE, NULL, NULL, + sizeof(struct CMD_SW_DBG_CTRL), + (uint8_t *)&rCmdSwCtrl, NULL, 0); + + /* 2. Keep at Fast PS */ + for (ucBssIdx = 0; ucBssIdx < KAL_AIS_NUM; ucBssIdx++) { + enum PARAM_POWER_MODE ePowerMode; + + prAdapter->u4CtiaPowerMode = 2; + prAdapter->fgEnCtiaPowerMode = TRUE; + + ePowerMode = Param_PowerModeFast_PSP; + rWlanStatus = nicConfigPowerSaveProfile(prAdapter, + ucBssIdx, + ePowerMode, fgEnCmdEvent, PS_CALLER_CTIA); + } + + /* 5. Enable Beacon Timeout Detection */ + prAdapter->fgDisBcnLostDetection = FALSE; + + } + + return rWlanStatus; +} /* end of nicEnterCtiaMode() */ + +uint32_t nicEnterCtiaModeOfScan(IN struct ADAPTER + *prAdapter, u_int8_t fgEnterCtia, u_int8_t fgEnCmdEvent) +{ + uint32_t rWlanStatus; + + ASSERT(prAdapter); + DBGLOG(INIT, INFO, "nicEnterCtiaModeOfScan: %d\n", + fgEnterCtia); + + rWlanStatus = WLAN_STATUS_SUCCESS; + + if (fgEnterCtia) { + /* Disable On-Line Scan */ + prAdapter->fgEnOnlineScan = FALSE; + } else { + /* Enable On-Line Scan */ + prAdapter->fgEnOnlineScan = TRUE; + } + + return rWlanStatus; +} + +uint32_t nicEnterCtiaModeOfRoaming(IN struct ADAPTER + *prAdapter, u_int8_t fgEnterCtia, u_int8_t fgEnCmdEvent) +{ + struct CMD_SW_DBG_CTRL rCmdSwCtrl; + uint32_t rWlanStatus; + + ASSERT(prAdapter); + DBGLOG(INIT, INFO, "nicEnterCtiaModeOfRoaming: %d\n", + fgEnterCtia); + + rWlanStatus = WLAN_STATUS_SUCCESS; + + if (fgEnterCtia) { + /* Disable Roaming */ + rCmdSwCtrl.u4Id = 0x55660000; + rCmdSwCtrl.u4Data = 0x0; + wlanSendSetQueryCmd(prAdapter, + CMD_ID_SW_DBG_CTRL, + TRUE, + FALSE, + FALSE, NULL, NULL, + sizeof(struct CMD_SW_DBG_CTRL), + (uint8_t *) &rCmdSwCtrl, NULL, 0); + } else { + /* Enable Roaming */ + rCmdSwCtrl.u4Id = 0x55660000; + rCmdSwCtrl.u4Data = 0x1; + wlanSendSetQueryCmd(prAdapter, + CMD_ID_SW_DBG_CTRL, + TRUE, + FALSE, + FALSE, NULL, NULL, + sizeof(struct CMD_SW_DBG_CTRL), + (uint8_t *) &rCmdSwCtrl, NULL, 0); + } + + return rWlanStatus; +} + +uint32_t nicEnterCtiaModeOfCAM(IN struct ADAPTER *prAdapter, + u_int8_t fgEnterCtia, u_int8_t fgEnCmdEvent) +{ + uint32_t rWlanStatus; + uint8_t ucBssIdx; + + ASSERT(prAdapter); + DBGLOG(INIT, INFO, "nicEnterCtiaModeOfCAM: %d\n", + fgEnterCtia); + + rWlanStatus = WLAN_STATUS_SUCCESS; + + if (fgEnterCtia) { + /* Keep at CAM mode */ + for (ucBssIdx = 0; ucBssIdx < KAL_AIS_NUM; ucBssIdx++) { + enum PARAM_POWER_MODE ePowerMode; + + prAdapter->u4CtiaPowerMode = 0; + prAdapter->fgEnCtiaPowerMode = TRUE; + + ePowerMode = Param_PowerModeCAM; + rWlanStatus = nicConfigPowerSaveProfile(prAdapter, + ucBssIdx, + ePowerMode, fgEnCmdEvent, PS_CALLER_CTIA_CAM); + } + } else { + /* Keep at Fast PS */ + for (ucBssIdx = 0; ucBssIdx < KAL_AIS_NUM; ucBssIdx++) { + enum PARAM_POWER_MODE ePowerMode; + + prAdapter->u4CtiaPowerMode = 2; + prAdapter->fgEnCtiaPowerMode = TRUE; + + ePowerMode = Param_PowerModeFast_PSP; + rWlanStatus = nicConfigPowerSaveProfile(prAdapter, + ucBssIdx, + ePowerMode, fgEnCmdEvent, PS_CALLER_CTIA_CAM); + } + } + + return rWlanStatus; +} + +uint32_t nicEnterCtiaModeOfBCNTimeout(IN struct ADAPTER + *prAdapter, u_int8_t fgEnterCtia, u_int8_t fgEnCmdEvent) +{ + uint32_t rWlanStatus; + + ASSERT(prAdapter); + DBGLOG(INIT, INFO, "nicEnterCtiaModeOfBCNTimeout: %d\n", + fgEnterCtia); + + rWlanStatus = WLAN_STATUS_SUCCESS; + + if (fgEnterCtia) { + /* Disable Beacon Timeout Detection */ + prAdapter->fgDisBcnLostDetection = TRUE; + } else { + /* Enable Beacon Timeout Detection */ + prAdapter->fgDisBcnLostDetection = FALSE; + } + + return rWlanStatus; +} + +uint32_t nicEnterCtiaModeOfAutoTxPower(IN struct ADAPTER + *prAdapter, u_int8_t fgEnterCtia, u_int8_t fgEnCmdEvent) +{ + struct CMD_SW_DBG_CTRL rCmdSwCtrl; + uint32_t rWlanStatus; + + ASSERT(prAdapter); + DBGLOG(INIT, INFO, "nicEnterCtiaModeOfAutoTxPower: %d\n", + fgEnterCtia); + + rWlanStatus = WLAN_STATUS_SUCCESS; + + if (fgEnterCtia) { + /* Disalbe auto tx power */ + rCmdSwCtrl.u4Id = 0x55670003; + rCmdSwCtrl.u4Data = 0x0; + wlanSendSetQueryCmd(prAdapter, + CMD_ID_SW_DBG_CTRL, + TRUE, + FALSE, + FALSE, + NULL, + NULL, + sizeof(struct CMD_SW_DBG_CTRL), + (uint8_t *) &rCmdSwCtrl, + NULL, 0); + } else { + /* Enable auto tx power */ + rCmdSwCtrl.u4Id = 0x55670003; + rCmdSwCtrl.u4Data = 0x1; + wlanSendSetQueryCmd(prAdapter, + CMD_ID_SW_DBG_CTRL, + TRUE, + FALSE, + FALSE, + NULL, + NULL, + sizeof(struct CMD_SW_DBG_CTRL), + (uint8_t *) &rCmdSwCtrl, + NULL, 0); + } + + return rWlanStatus; +} + +uint32_t nicEnterCtiaModeOfFIFOFullNoAck(IN struct ADAPTER + *prAdapter, u_int8_t fgEnterCtia, u_int8_t fgEnCmdEvent) +{ + struct CMD_SW_DBG_CTRL rCmdSwCtrl; + uint32_t rWlanStatus; + + ASSERT(prAdapter); + DBGLOG(INIT, INFO, "nicEnterCtiaModeOfFIFOFullNoAck: %d\n", + fgEnterCtia); + + rWlanStatus = WLAN_STATUS_SUCCESS; + + if (fgEnterCtia) { + /* Disable FIFO FULL no ack */ + rCmdSwCtrl.u4Id = 0x55680000; + rCmdSwCtrl.u4Data = 0x0; + wlanSendSetQueryCmd(prAdapter, + CMD_ID_SW_DBG_CTRL, + TRUE, + FALSE, + FALSE, + NULL, + NULL, + sizeof(struct CMD_SW_DBG_CTRL), + (uint8_t *) &rCmdSwCtrl, + NULL, 0); + } else { + /* Enable FIFO FULL no ack */ + rCmdSwCtrl.u4Id = 0x55680000; + rCmdSwCtrl.u4Data = 0x1; + wlanSendSetQueryCmd(prAdapter, + CMD_ID_SW_DBG_CTRL, + TRUE, + FALSE, + FALSE, + NULL, + NULL, + sizeof(struct CMD_SW_DBG_CTRL), + (uint8_t *) &rCmdSwCtrl, + NULL, 0); + } + + return rWlanStatus; +} + +uint32_t nicEnterTPTestMode(IN struct ADAPTER *prAdapter, + IN uint8_t ucFuncMask) +{ + struct CMD_SW_DBG_CTRL rCmdSwCtrl; + uint32_t rWlanStatus; + uint8_t ucBssIdx; + struct BSS_INFO *prBssInfo; + + ASSERT(prAdapter); + + rWlanStatus = WLAN_STATUS_SUCCESS; + + if (ucFuncMask) { + /* 1. Disable On-Lin Scan */ + if (ucFuncMask & TEST_MODE_DISABLE_ONLINE_SCAN) + prAdapter->fgEnOnlineScan = FALSE; + + /* 2. Disable Roaming */ + if (ucFuncMask & TEST_MODE_DISABLE_ROAMING) { + rCmdSwCtrl.u4Id = 0xa0210000; + rCmdSwCtrl.u4Data = 0x0; + wlanSendSetQueryCmd(prAdapter, CMD_ID_SW_DBG_CTRL, TRUE, + FALSE, FALSE, + NULL, NULL, sizeof(struct CMD_SW_DBG_CTRL), + (uint8_t *)&rCmdSwCtrl, NULL, 0); + } + /* 3. Keep at CAM mode */ + if (ucFuncMask & TEST_MODE_FIXED_CAM_MODE) + for (ucBssIdx = 0; ucBssIdx < prAdapter->ucHwBssIdNum; + ucBssIdx++) { + prBssInfo = + GET_BSS_INFO_BY_INDEX(prAdapter, + ucBssIdx); + if (prBssInfo->fgIsInUse + && (prBssInfo->eCurrentOPMode + == OP_MODE_INFRASTRUCTURE)) + nicConfigPowerSaveProfile(prAdapter, + ucBssIdx, Param_PowerModeCAM, + FALSE, PS_CALLER_TP); + } + + /* 4. Disable Beacon Timeout Detection */ + if (ucFuncMask & TEST_MODE_DISABLE_BCN_LOST_DET) + prAdapter->fgDisBcnLostDetection = TRUE; + } else { + /* 1. Enaable On-Lin Scan */ + prAdapter->fgEnOnlineScan = TRUE; + + /* 2. Enable Roaming */ + rCmdSwCtrl.u4Id = 0xa0210000; + rCmdSwCtrl.u4Data = 0x1; + wlanSendSetQueryCmd(prAdapter, CMD_ID_SW_DBG_CTRL, TRUE, + FALSE, FALSE, + NULL, NULL, sizeof(struct CMD_SW_DBG_CTRL), + (uint8_t *)&rCmdSwCtrl, NULL, 0); + + /* 3. Keep at Fast PS */ + for (ucBssIdx = 0; ucBssIdx < prAdapter->ucHwBssIdNum; + ucBssIdx++) { + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIdx); + if (prBssInfo->fgIsInUse + && (prBssInfo->eCurrentOPMode + == OP_MODE_INFRASTRUCTURE)) + nicConfigPowerSaveProfile(prAdapter, ucBssIdx, + Param_PowerModeFast_PSP, + FALSE, PS_CALLER_TP); + } + + /* 4. Enable Beacon Timeout Detection */ + prAdapter->fgDisBcnLostDetection = FALSE; + } + + return rWlanStatus; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This utility function is used to indicate firmware domain + * for beacon generation parameters + * + * @param prAdapter Pointer of ADAPTER_T + * eIeUpdMethod, Update Method + * ucBssIndex Index of BSS-INFO + * u2Capability Capability + * aucIe Pointer to buffer of IEs + * u2IELen Length of IEs + * + * @retval - WLAN_STATUS_SUCCESS + * WLAN_STATUS_FAILURE + * WLAN_STATUS_PENDING + * WLAN_STATUS_INVALID_DATA + */ +/*----------------------------------------------------------------------------*/ +uint32_t +nicUpdateBeaconIETemplate(IN struct ADAPTER *prAdapter, + IN enum ENUM_IE_UPD_METHOD eIeUpdMethod, + IN uint8_t ucBssIndex, IN uint16_t u2Capability, + IN uint8_t *aucIe, IN uint16_t u2IELen) +{ + struct CMD_BEACON_TEMPLATE_UPDATE *prCmdBcnUpdate; + uint16_t u2CmdBufLen = 0, cmd_size; + struct GLUE_INFO *prGlueInfo; + struct CMD_INFO *prCmdInfo; + struct mt66xx_chip_info *prChipInfo; + + DEBUGFUNC("wlanUpdateBeaconIETemplate"); + DBGLOG(INIT, LOUD, "\n"); + + ASSERT(prAdapter); + prGlueInfo = prAdapter->prGlueInfo; + prChipInfo = prAdapter->chip_info; + + if (u2IELen > MAX_IE_LENGTH) + return WLAN_STATUS_INVALID_DATA; + + if (eIeUpdMethod == IE_UPD_METHOD_UPDATE_RANDOM + || eIeUpdMethod == IE_UPD_METHOD_UPDATE_ALL) { + u2CmdBufLen = OFFSET_OF(struct CMD_BEACON_TEMPLATE_UPDATE, + aucIE) + u2IELen; + } else if (eIeUpdMethod == IE_UPD_METHOD_DELETE_ALL) { + u2CmdBufLen = OFFSET_OF(struct CMD_BEACON_TEMPLATE_UPDATE, + u2IELen); +#if CFG_SUPPORT_P2P_GO_OFFLOAD_PROBE_RSP + } else if (eIeUpdMethod == IE_UPD_METHOD_UPDATE_PROBE_RSP) { + u2CmdBufLen = OFFSET_OF(struct CMD_BEACON_TEMPLATE_UPDATE, + aucIE) + u2IELen; + DBGLOG(NIC, INFO, + "update for probe response offload to firmware\n"); +#endif + } else { + DBGLOG(INIT, ERROR, "Unknown IeUpdMethod.\n"); + return WLAN_STATUS_FAILURE; + } + + /* prepare command info */ + cmd_size = prChipInfo->u2CmdTxHdrSize + u2CmdBufLen; + prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, cmd_size); + if (!prCmdInfo) { + DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); + return WLAN_STATUS_FAILURE; + } + + /* Setup common CMD Info Packet */ + prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; + prCmdInfo->u2InfoBufLen = cmd_size; + prCmdInfo->pfCmdDoneHandler = NULL; /* @FIXME */ + prCmdInfo->pfCmdTimeoutHandler = NULL; /* @FIXME */ + prCmdInfo->fgIsOid = FALSE; + prCmdInfo->ucCID = CMD_ID_UPDATE_BEACON_CONTENT; + prCmdInfo->fgSetQuery = TRUE; + prCmdInfo->fgNeedResp = FALSE; + prCmdInfo->u4SetInfoLen = u2CmdBufLen; + prCmdInfo->pvInformationBuffer = NULL; + prCmdInfo->u4InformationBufferLength = 0; + + /* Setup WIFI_CMD_T (no payload) */ + NIC_FILL_CMD_TX_HDR(prAdapter, + prCmdInfo->pucInfoBuffer, + prCmdInfo->u2InfoBufLen, + prCmdInfo->ucCID, + CMD_PACKET_TYPE_ID, + &prCmdInfo->ucCmdSeqNum, + prCmdInfo->fgSetQuery, + &prCmdBcnUpdate, FALSE, 0, S2D_INDEX_CMD_H2N); + + /* fill beacon updating command */ + prCmdBcnUpdate->ucUpdateMethod = (uint8_t) eIeUpdMethod; + prCmdBcnUpdate->ucBssIndex = ucBssIndex; + prCmdBcnUpdate->u2Capability = u2Capability; + prCmdBcnUpdate->u2IELen = u2IELen; + if (u2IELen > 0) + kalMemCopy(prCmdBcnUpdate->aucIE, aucIe, u2IELen); + /* insert into prCmdQueue */ + kalEnqueueCommand(prGlueInfo, + (struct QUE_ENTRY *) prCmdInfo); + + /* wakeup txServiceThread later */ + GLUE_SET_EVENT(prGlueInfo); + return WLAN_STATUS_PENDING; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This utility function is used to initialization PHY related + * varaibles + * + * @param prAdapter Pointer of ADAPTER_T + * + * @retval none + */ +/*----------------------------------------------------------------------------*/ +void nicSetAvailablePhyTypeSet(IN struct ADAPTER *prAdapter) +{ + ASSERT(prAdapter); + + if (prAdapter->rWifiVar.eDesiredPhyConfig >= PHY_CONFIG_NUM) { + ASSERT(0); + return; + } + + prAdapter->rWifiVar.ucAvailablePhyTypeSet = + aucPhyCfg2PhyTypeSet[ + prAdapter->rWifiVar.eDesiredPhyConfig]; + + if (prAdapter->rWifiVar.ucAvailablePhyTypeSet & + PHY_TYPE_BIT_ERP) + prAdapter->rWifiVar.eNonHTBasicPhyType2G4 = + PHY_TYPE_ERP_INDEX; + /* NOTE(Kevin): Because we don't have N only mode, TBD */ + else + prAdapter->rWifiVar.eNonHTBasicPhyType2G4 = + PHY_TYPE_HR_DSSS_INDEX; + +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This utility function is used to update WMM Parms + * + * @param prAdapter Pointer of ADAPTER_T + * ucBssIndex Index of BSS-INFO + * + * @retval - + */ +/*----------------------------------------------------------------------------*/ +uint32_t nicQmUpdateWmmParms(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) +{ + struct BSS_INFO *prBssInfo; + struct CMD_UPDATE_WMM_PARMS rCmdUpdateWmmParms; + struct mt66xx_chip_info *prChipInfo; + uint32_t u4TxHifRes = 0, u4Idx = 0; + + ASSERT(prAdapter); + prChipInfo = prAdapter->chip_info; + + DBGLOG(QM, TRACE, "Update WMM parameters for BSS[%u]\n", + ucBssIndex); + + DBGLOG(QM, TRACE, "sizeof(struct AC_QUE_PARMS): %zu\n", + sizeof(struct AC_QUE_PARMS)); + DBGLOG(QM, TRACE, "sizeof(CMD_UPDATE_WMM_PARMS): %zu\n", + sizeof(struct CMD_UPDATE_WMM_PARMS)); + DBGLOG(QM, TRACE, "u2CmdTxHdrSize: %u\n", + prChipInfo->u2CmdTxHdrSize); + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + rCmdUpdateWmmParms.ucBssIndex = (uint8_t) ucBssIndex; + kalMemCopy(&rCmdUpdateWmmParms.arACQueParms[0], + &prBssInfo->arACQueParms[0], + (sizeof(struct AC_QUE_PARMS) * AC_NUM)); + + rCmdUpdateWmmParms.fgIsQBSS = prBssInfo->fgIsQBSS; + rCmdUpdateWmmParms.ucWmmSet = (uint8_t) + prBssInfo->ucWmmQueSet; + + /* If VI use worse parameter than BE, need to use round-robbin queue + * to enqueue data from HIF to HW. + * (Should revise if HIF can have separate queue for each AC) + */ + if (rCmdUpdateWmmParms.arACQueParms[AC1].u2Aifsn + < rCmdUpdateWmmParms.arACQueParms[AC2].u2Aifsn) { + + /* Use round-robbin queuing in HIF */ + prAdapter->rWifiVar.ucTxMsduQueue = 1; + + /* The ratio of each AC is 1:1:1:1 in this case */ + u4TxHifRes = 0x00111111; + } else { + /* Use default setting when wifi init */ + prAdapter->rWifiVar.ucTxMsduQueue = + prAdapter->rWifiVar.ucTxMsduQueueInit; + u4TxHifRes = prAdapter->rWifiVar.u4TxHifRes; + } + + DBGLOG_LIMITED(QM, INFO, "ucTxMsduQueue:[%u], u4TxHifRes[%d]", + prAdapter->rWifiVar.ucTxMsduQueue, u4TxHifRes); + + for (u4Idx = 0; u4Idx < TX_PORT_NUM && u4TxHifRes; u4Idx++) { + prAdapter->au4TxHifResCtl[u4Idx] = u4TxHifRes & BITS(0, 3); + u4TxHifRes = u4TxHifRes >> 4; + } + + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_UPDATE_WMM_PARMS, + TRUE, + FALSE, + FALSE, + NULL, NULL, + sizeof(struct CMD_UPDATE_WMM_PARMS), + (uint8_t *)&rCmdUpdateWmmParms, NULL, 0); +} + +#if (CFG_SUPPORT_802_11AX == 1) +uint32_t nicQmUpdateMUEdcaParams(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) +{ + struct BSS_INFO *prBssInfo; + struct _CMD_MQM_UPDATE_MU_EDCA_PARMS_T rCmdUpdateMUEdcaParms; + + ASSERT(prAdapter); + + DBGLOG(QM, INFO, "Update MU EDCA parameters for BSS[%u]\n", ucBssIndex); + + DBGLOG(QM, EVENT, "sizeof(CMD_MU_EDCA_PARAMS_T): %d\n", + sizeof(struct _CMD_MU_EDCA_PARAMS_T)); + DBGLOG(QM, EVENT, "sizeof(CMD_MQM_UPDATE_MU_EDCA_PARMS_T): %d\n", + sizeof(struct _CMD_MQM_UPDATE_MU_EDCA_PARMS_T)); + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + rCmdUpdateMUEdcaParms.ucBssIndex = (uint8_t) ucBssIndex; + + if (prAdapter->fgMuEdcaOverride) { + + enum ENUM_WMM_ACI eAci; + struct _CMD_MU_EDCA_PARAMS_T *prMUEdca; + + for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { + + prMUEdca = + &(rCmdUpdateMUEdcaParms.arMUEdcaParams[eAci]); + + prMUEdca->ucECWmin = 15; + prMUEdca->ucECWmax = 15; + prMUEdca->ucAifsn = 0; + prMUEdca->ucIsACMSet = 0; + prMUEdca->ucMUEdcaTimer = 0xff; + } + } else { + kalMemCopy(&rCmdUpdateMUEdcaParms.arMUEdcaParams[0], + &prBssInfo->arMUEdcaParams[0], + (sizeof(struct _CMD_MU_EDCA_PARAMS_T) * AC_NUM)); + } + + rCmdUpdateMUEdcaParms.fgIsQBSS = prBssInfo->fgIsQBSS; + rCmdUpdateMUEdcaParms.ucWmmSet = (uint8_t) prBssInfo->ucWmmQueSet; + + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_MQM_UPDATE_MU_EDCA_PARMS, + TRUE, + FALSE, + FALSE, + NULL, NULL, + sizeof(struct _CMD_MQM_UPDATE_MU_EDCA_PARMS_T), + (uint8_t *)&rCmdUpdateMUEdcaParms, NULL, 0); +} + +uint32_t nicRlmUpdateSRParams(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) +{ + struct BSS_INFO *prBssInfo; + struct _CMD_RLM_UPDATE_SR_PARMS_T rCmdUpdateSRParms; + + ASSERT(prAdapter); + + DBGLOG(RLM, INFO, + "Update Spatial Reuse parameters for BSS[%u] size: %d\n", + ucBssIndex, + sizeof(struct _CMD_RLM_UPDATE_SR_PARMS_T)); + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + rCmdUpdateSRParms.ucBssIndex = ucBssIndex; + rCmdUpdateSRParms.ucSRControl = prBssInfo->ucSRControl; + rCmdUpdateSRParms.ucNonSRGObssPdMaxOffset = + prBssInfo->ucNonSRGObssPdMaxOffset; + rCmdUpdateSRParms.ucSRGObssPdMinOffset = + prBssInfo->ucSRGObssPdMinOffset; + rCmdUpdateSRParms.ucSRGObssPdMaxOffset = + prBssInfo->ucSRGObssPdMaxOffset; + rCmdUpdateSRParms.u4SRGBSSColorBitmapLow = CPU_TO_LE32( + (uint32_t)(prBssInfo->u8SRGBSSColorBitmap & 0xFFFFFFFF)); + rCmdUpdateSRParms.u4SRGBSSColorBitmapHigh = CPU_TO_LE32( + (uint32_t)(prBssInfo->u8SRGBSSColorBitmap >> 32)); + rCmdUpdateSRParms.u4SRGPartialBSSIDBitmapLow = CPU_TO_LE32( + (uint32_t)(prBssInfo->u8SRGPartialBSSIDBitmap & 0xFFFFFFFF)); + rCmdUpdateSRParms.u4SRGPartialBSSIDBitmapHigh = CPU_TO_LE32( + (uint32_t)(prBssInfo->u8SRGPartialBSSIDBitmap >> 32)); + + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_RLM_UPDATE_SR_PARAMS, + TRUE, + FALSE, + FALSE, + NULL, NULL, + sizeof(struct _CMD_RLM_UPDATE_SR_PARMS_T), + (uint8_t *)&rCmdUpdateSRParms, NULL, 0); +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This utility function is used to update TX power gain corresponding to + * each band/modulation combination + * + * @param prAdapter Pointer of ADAPTER_T + * prTxPwrParam Pointer of TX power parameters + * + * @retval WLAN_STATUS_PENDING + * WLAN_STATUS_FAILURE + */ +/*----------------------------------------------------------------------------*/ +uint32_t nicUpdateTxPower(IN struct ADAPTER *prAdapter, + IN struct CMD_TX_PWR *prTxPwrParam) +{ + DEBUGFUNC("nicUpdateTxPower"); + + ASSERT(prAdapter); + + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_SET_TX_PWR, + TRUE, + FALSE, FALSE, NULL, NULL, + sizeof(struct CMD_TX_PWR), + (uint8_t *) prTxPwrParam, NULL, 0); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This utility function is used to set auto tx power parameter + * + * @param prAdapter Pointer of ADAPTER_T + * prTxPwrParam Pointer of Auto TX power parameters + * + * @retval WLAN_STATUS_PENDING + * WLAN_STATUS_FAILURE + */ +/*----------------------------------------------------------------------------*/ +uint32_t nicSetAutoTxPower(IN struct ADAPTER *prAdapter, + IN struct CMD_AUTO_POWER_PARAM *prAutoPwrParam) +{ + DEBUGFUNC("nicSetAutoTxPower"); + + ASSERT(prAdapter); + + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_SET_AUTOPWR_CTRL, + TRUE, + FALSE, + FALSE, + NULL, NULL, + sizeof(struct CMD_AUTO_POWER_PARAM), + (uint8_t *) prAutoPwrParam, NULL, 0); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This utility function is used to update TX power gain corresponding to + * each band/modulation combination + * + * @param prAdapter Pointer of ADAPTER_T + * prTxPwrParam Pointer of TX power parameters + * + * @retval WLAN_STATUS_PENDING + * WLAN_STATUS_FAILURE + */ +/*----------------------------------------------------------------------------*/ +uint32_t nicSetAutoTxPowerControl(IN struct ADAPTER + *prAdapter, IN struct CMD_TX_PWR *prTxPwrParam) +{ + DEBUGFUNC("nicUpdateTxPower"); + + ASSERT(prAdapter); + + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_SET_TX_PWR, + TRUE, + FALSE, FALSE, NULL, NULL, + sizeof(struct CMD_TX_PWR), + (uint8_t *) prTxPwrParam, NULL, 0); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This utility function is used to update power offset around 5GHz band + * + * @param prAdapter Pointer of ADAPTER_T + * pr5GPwrOffset Pointer of 5GHz power offset parameter + * + * @retval WLAN_STATUS_PENDING + * WLAN_STATUS_FAILURE + */ +/*----------------------------------------------------------------------------*/ +uint32_t nicUpdate5GOffset(IN struct ADAPTER *prAdapter, + IN struct CMD_5G_PWR_OFFSET *pr5GPwrOffset) +{ +#if 0 /* It is not needed anymore */ + DEBUGFUNC("nicUpdate5GOffset"); + + ASSERT(prAdapter); + + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_SET_5G_PWR_OFFSET, + TRUE, + FALSE, + FALSE, NULL, NULL, + sizeof(struct CMD_5G_PWR_OFFSET), + (uint8_t *) pr5GPwrOffset, NULL, 0); +#else + return 0; +#endif +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This utility function is used to update DPD calibration result + * + * @param prAdapter Pointer of ADAPTER_T + * pr5GPwrOffset Pointer of parameter for DPD calibration result + * + * @retval WLAN_STATUS_PENDING + * WLAN_STATUS_FAILURE + */ +/*----------------------------------------------------------------------------*/ +uint32_t nicUpdateDPD(IN struct ADAPTER *prAdapter, + IN struct CMD_PWR_PARAM *prDpdCalResult) +{ + DEBUGFUNC("nicUpdateDPD"); + + ASSERT(prAdapter); + + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_SET_PWR_PARAM, + TRUE, + FALSE, + FALSE, NULL, NULL, + sizeof(struct CMD_PWR_PARAM), + (uint8_t *) prDpdCalResult, NULL, 0); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This utility function starts system service such as timer and + * memory pools + * + * @param prAdapter Pointer of ADAPTER_T + * + * @retval none + */ +/*----------------------------------------------------------------------------*/ +void nicInitSystemService(IN struct ADAPTER *prAdapter, + IN const u_int8_t bAtResetFlow) +{ + ASSERT(prAdapter); + + /* <1> Initialize MGMT Memory pool and STA_REC */ + if (!bAtResetFlow) { + cnmMemInit(prAdapter); + cnmStaRecInit(prAdapter); + } + + cmdBufInitialize(prAdapter); + + if (!bAtResetFlow) { + /* <2> Mailbox Initialization */ + mboxInitialize(prAdapter); + + /* <3> Timer Initialization */ + cnmTimerInitialize(prAdapter); + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This utility function reset some specific system service, + * such as STA-REC + * + * @param prAdapter Pointer of ADAPTER_T + * + * @retval none + */ +/*----------------------------------------------------------------------------*/ +void nicResetSystemService(IN struct ADAPTER *prAdapter) +{ + ASSERT(prAdapter); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This utility function is used to update WMM Parms + * + * @param prAdapter Pointer of ADAPTER_T + * + * @retval none + */ +/*----------------------------------------------------------------------------*/ +void nicUninitSystemService(IN struct ADAPTER *prAdapter) +{ + ASSERT(prAdapter); + + /* Timer Destruction */ + cnmTimerDestroy(prAdapter); + + /* Mailbox Destruction */ + mboxDestroy(prAdapter); + +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This utility function is used to update WMM Parms + * + * @param prAdapter Pointer of ADAPTER_T + * + * @retval none + */ +/*----------------------------------------------------------------------------*/ +void nicInitMGMT(IN struct ADAPTER *prAdapter, + IN struct REG_INFO *prRegInfo) +{ + uint8_t i; + + ASSERT(prAdapter); + + /* CNM Module - initialization */ + cnmInit(prAdapter); + + wmmInit(prAdapter); + + /* RLM Module - initialization */ + rlmFsmEventInit(prAdapter); + + /* SCN Module - initialization */ + scnInit(prAdapter); + + for (i = 0; i < KAL_AIS_NUM; i++) { + /* AIS Module - intiailization */ + aisFsmInit(prAdapter, i); + aisInitializeConnectionSettings(prAdapter, + prRegInfo, + i); +#if CFG_SUPPORT_ROAMING + /* Roaming Module - intiailization */ + roamingFsmInit(prAdapter, i); +#endif /* CFG_SUPPORT_ROAMING */ + } + +#if CFG_SUPPORT_SWCR + swCrDebugInit(prAdapter); +#endif /* CFG_SUPPORT_SWCR */ + +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This utility function is used to update WMM Parms + * + * @param prAdapter Pointer of ADAPTER_T + * + * @retval none + */ +/*----------------------------------------------------------------------------*/ +void nicUninitMGMT(IN struct ADAPTER *prAdapter) +{ + uint8_t i; + + ASSERT(prAdapter); + +#if CFG_SUPPORT_SWCR + swCrDebugUninit(prAdapter); +#endif /* CFG_SUPPORT_SWCR */ + + for (i = 0; i < KAL_AIS_NUM; i++) { +#if CFG_SUPPORT_ROAMING + /* Roaming Module - unintiailization */ + roamingFsmUninit(prAdapter, i); +#endif /* CFG_SUPPORT_ROAMING */ + + /* AIS Module - unintiailization */ + aisFsmUninit(prAdapter, i); + } + + /* SCN Module - unintiailization */ + scnUninit(prAdapter); + + wmmUnInit(prAdapter); + + /* RLM Module - uninitialization */ + rlmFsmEventUninit(prAdapter); + + /* CNM Module - uninitialization */ + cnmUninit(prAdapter); + +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is invoked to buffer scan result + * + * @param prAdapter Pointer to the Adapter structure. + * @param rMacAddr BSSID + * @param prSsid Pointer to SSID + * @param u2CapInfo Capability settings + * @param rRssi Received Strength (-10 ~ -200 dBm) + * @param eNetworkType Network Type (a/b/g) + * @param prConfiguration Network Parameter + * @param eOpMode Infra/Ad-Hoc + * @param rSupportedRates Supported basic rates + * @param u2IELength IE Length + * @param pucIEBuf Pointer to Information Elements(IEs) + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void +nicAddScanResult(IN struct ADAPTER *prAdapter, + IN uint8_t rMacAddr[PARAM_MAC_ADDR_LEN], + IN struct PARAM_SSID *prSsid, + IN uint16_t u2CapInfo, + IN int32_t rRssi, + IN enum ENUM_PARAM_NETWORK_TYPE eNetworkType, + IN struct PARAM_802_11_CONFIG *prConfiguration, + IN enum ENUM_PARAM_OP_MODE eOpMode, + IN uint8_t rSupportedRates[PARAM_MAX_LEN_RATES_EX], + IN uint16_t u2IELength, IN uint8_t *pucIEBuf) +{ + u_int8_t bReplace; + uint32_t i; + uint32_t u4IdxWeakest = 0; + int32_t rWeakestRssi; + uint32_t u4BufferSize; + /* Privicy setting 0: Open / 1: WEP/WPA/WPA2 enabled */ + uint32_t u4Privacy = u2CapInfo & CAP_INFO_PRIVACY ? 1 : 0; + + ASSERT(prAdapter); + + rWeakestRssi = (int32_t) INT_MAX; + u4BufferSize = ARRAY_SIZE( + prAdapter->rWlanInfo.aucScanIEBuf); + + bReplace = FALSE; + + /* decide to replace or add */ + for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { + uint8_t j; + u_int8_t bUnMatch = TRUE; + + for (j = 0; j < KAL_AIS_NUM; j++) { + struct PARAM_BSSID_EX *prCurrBssid; + + prCurrBssid = aisGetCurrBssId(prAdapter, + j); + if (EQUAL_MAC_ADDR + (prAdapter->rWlanInfo. + arScanResult[i].arMacAddress, + prCurrBssid->arMacAddress)) { + bUnMatch = FALSE; + break; + } + } + + /* find weakest entry && not connected one */ + if (bUnMatch + && prAdapter->rWlanInfo.arScanResult[i].rRssi < + rWeakestRssi) { + u4IdxWeakest = i; + rWeakestRssi + = prAdapter->rWlanInfo.arScanResult[i].rRssi; + } + + if (prAdapter->rWlanInfo.arScanResult[i].eOpMode == eOpMode + && + EQUAL_MAC_ADDR(&(prAdapter->rWlanInfo. + arScanResult[i].arMacAddress), rMacAddr) + && + (EQUAL_SSID + (prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid, + prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen, + prSsid->aucSsid, prSsid->u4SsidLen) + || prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen == + 0)) { + /* replace entry */ + bReplace = TRUE; + + /* free IE buffer then zero */ + nicFreeScanResultIE(prAdapter, i); + kalMemZero(&(prAdapter->rWlanInfo.arScanResult[i]), + OFFSET_OF(struct PARAM_BSSID_EX, aucIEs)); + + /* then fill buffer */ + prAdapter->rWlanInfo.arScanResult[i].u4Length = + OFFSET_OF(struct PARAM_BSSID_EX, aucIEs) + + u2IELength; + COPY_MAC_ADDR( + prAdapter->rWlanInfo.arScanResult[i]. + arMacAddress, + rMacAddr); + COPY_SSID( + prAdapter->rWlanInfo.arScanResult[i].rSsid. + aucSsid, + prAdapter->rWlanInfo.arScanResult[i].rSsid. + u4SsidLen, + prSsid->aucSsid, prSsid->u4SsidLen); + prAdapter->rWlanInfo.arScanResult[i].u4Privacy + = u4Privacy; + prAdapter->rWlanInfo.arScanResult[i].rRssi = rRssi; + prAdapter->rWlanInfo.arScanResult[i].eNetworkTypeInUse = + eNetworkType; + kalMemCopy(& + (prAdapter->rWlanInfo.arScanResult[i]. + rConfiguration), + prConfiguration, + sizeof(struct PARAM_802_11_CONFIG)); + prAdapter->rWlanInfo.arScanResult[i].eOpMode = eOpMode; + kalMemCopy(( + prAdapter->rWlanInfo. + arScanResult[i].rSupportedRates), + rSupportedRates, (sizeof(uint8_t) * + PARAM_MAX_LEN_RATES_EX)); + prAdapter->rWlanInfo.arScanResult[i].u4IELength = + (uint32_t) u2IELength; + + /* IE - allocate buffer and update pointer */ + if (u2IELength > 0) { + if (ALIGN_4(u2IELength) + + prAdapter->rWlanInfo.u4ScanIEBufferUsage + <= u4BufferSize) { + kalMemCopy(& + (prAdapter->rWlanInfo. + aucScanIEBuf[prAdapter-> + rWlanInfo. + u4ScanIEBufferUsage]), + pucIEBuf, + u2IELength); + + prAdapter->rWlanInfo. + apucScanResultIEs[i] + = &(prAdapter->rWlanInfo. + aucScanIEBuf[prAdapter-> + rWlanInfo. + u4ScanIEBufferUsage]); + + prAdapter->rWlanInfo.u4ScanIEBufferUsage + += ALIGN_4(u2IELength); + } else { + /* buffer is not enough */ + prAdapter->rWlanInfo. + arScanResult[i].u4Length -= u2IELength; + prAdapter->rWlanInfo. + arScanResult[i].u4IELength = 0; + prAdapter->rWlanInfo. + apucScanResultIEs[i] = NULL; + } + } else { + prAdapter->rWlanInfo. + apucScanResultIEs[i] = NULL; + } + + break; + } + } + + if (bReplace == FALSE) { + if (prAdapter->rWlanInfo.u4ScanResultNum < + (CFG_MAX_NUM_BSS_LIST - 1)) { + i = prAdapter->rWlanInfo.u4ScanResultNum; + + /* zero */ + kalMemZero(&(prAdapter->rWlanInfo.arScanResult[i]), + OFFSET_OF(struct PARAM_BSSID_EX, aucIEs)); + + /* then fill buffer */ + prAdapter->rWlanInfo.arScanResult[i].u4Length = + OFFSET_OF(struct PARAM_BSSID_EX, aucIEs) + + u2IELength; + COPY_MAC_ADDR( + prAdapter->rWlanInfo.arScanResult[i]. + arMacAddress, + rMacAddr); + COPY_SSID( + prAdapter->rWlanInfo.arScanResult[i]. + rSsid.aucSsid, + prAdapter->rWlanInfo.arScanResult[i]. + rSsid.u4SsidLen, + prSsid->aucSsid, prSsid->u4SsidLen); + prAdapter->rWlanInfo.arScanResult[i]. + u4Privacy = u4Privacy; + prAdapter->rWlanInfo.arScanResult[i].rRssi = rRssi; + prAdapter->rWlanInfo.arScanResult[i].eNetworkTypeInUse = + eNetworkType; + kalMemCopy(& + (prAdapter->rWlanInfo.arScanResult[i]. + rConfiguration), + prConfiguration, + sizeof(struct PARAM_802_11_CONFIG)); + prAdapter->rWlanInfo.arScanResult[i].eOpMode = eOpMode; + kalMemCopy(( + prAdapter->rWlanInfo.arScanResult[i]. + rSupportedRates), + rSupportedRates, (sizeof(uint8_t) * + PARAM_MAX_LEN_RATES_EX)); + prAdapter->rWlanInfo.arScanResult[i].u4IELength = + (uint32_t) u2IELength; + + /* IE - allocate buffer and update pointer */ + if (u2IELength > 0) { + if (ALIGN_4(u2IELength) + + prAdapter->rWlanInfo.u4ScanIEBufferUsage + <= u4BufferSize) { + kalMemCopy(& + (prAdapter->rWlanInfo. + aucScanIEBuf[prAdapter-> + rWlanInfo. + u4ScanIEBufferUsage]), + pucIEBuf, + u2IELength); + + prAdapter->rWlanInfo. + apucScanResultIEs[i] + = &(prAdapter->rWlanInfo. + aucScanIEBuf[prAdapter-> + rWlanInfo. + u4ScanIEBufferUsage]); + + prAdapter->rWlanInfo.u4ScanIEBufferUsage + += ALIGN_4(u2IELength); + } else { + /* buffer is not enough */ + prAdapter->rWlanInfo.arScanResult[i]. + u4Length -= u2IELength; + prAdapter->rWlanInfo.arScanResult[i]. + u4IELength = 0; + prAdapter->rWlanInfo. + apucScanResultIEs[i] = NULL; + } + } else { + prAdapter->rWlanInfo.apucScanResultIEs[i] + = NULL; + } + + prAdapter->rWlanInfo.u4ScanResultNum++; + } else if (rWeakestRssi != (int32_t) INT_MAX) { + /* replace weakest one */ + i = u4IdxWeakest; + + /* free IE buffer then zero */ + nicFreeScanResultIE(prAdapter, i); + kalMemZero(&(prAdapter->rWlanInfo.arScanResult[i]), + OFFSET_OF(struct PARAM_BSSID_EX, aucIEs)); + + /* then fill buffer */ + prAdapter->rWlanInfo.arScanResult[i].u4Length = + OFFSET_OF(struct PARAM_BSSID_EX, aucIEs) + + u2IELength; + COPY_MAC_ADDR( + prAdapter->rWlanInfo.arScanResult[i]. + arMacAddress, + rMacAddr); + COPY_SSID( + prAdapter->rWlanInfo.arScanResult[i]. + rSsid.aucSsid, + prAdapter->rWlanInfo.arScanResult[i]. + rSsid.u4SsidLen, + prSsid->aucSsid, prSsid->u4SsidLen); + prAdapter->rWlanInfo.arScanResult[i].u4Privacy + = u4Privacy; + prAdapter->rWlanInfo.arScanResult[i].rRssi = rRssi; + prAdapter->rWlanInfo.arScanResult[i].eNetworkTypeInUse = + eNetworkType; + kalMemCopy(&(prAdapter->rWlanInfo. + arScanResult[i].rConfiguration), + prConfiguration, + sizeof(struct PARAM_802_11_CONFIG)); + prAdapter->rWlanInfo.arScanResult[i].eOpMode = eOpMode; + kalMemCopy(( + prAdapter->rWlanInfo.arScanResult[i]. + rSupportedRates), + rSupportedRates, (sizeof(uint8_t) * + PARAM_MAX_LEN_RATES_EX)); + prAdapter->rWlanInfo.arScanResult[i].u4IELength = + (uint32_t) u2IELength; + + if (u2IELength > 0) { + /* IE - allocate buffer and update pointer */ + if (ALIGN_4(u2IELength) + + prAdapter->rWlanInfo.u4ScanIEBufferUsage + <= u4BufferSize) { + kalMemCopy(& + (prAdapter->rWlanInfo. + aucScanIEBuf[ + prAdapter->rWlanInfo. + u4ScanIEBufferUsage]), + pucIEBuf, + u2IELength); + + prAdapter->rWlanInfo. + apucScanResultIEs[i] + = &(prAdapter->rWlanInfo. + aucScanIEBuf[prAdapter-> + rWlanInfo. + u4ScanIEBufferUsage]); + + prAdapter->rWlanInfo.u4ScanIEBufferUsage + += ALIGN_4(u2IELength); + } else { + /* buffer is not enough */ + prAdapter->rWlanInfo.arScanResult[i]. + u4Length -= u2IELength; + prAdapter->rWlanInfo.arScanResult[i]. + u4IELength = 0; + prAdapter->rWlanInfo. + apucScanResultIEs[i] = NULL; + } + } else { + prAdapter->rWlanInfo.apucScanResultIEs[i] + = NULL; + } + } + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is invoked to free IE buffer for dedicated scan result + * + * @param prAdapter Pointer to the Adapter structure. + * @param u4Idx Index of Scan Result + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void nicFreeScanResultIE(IN struct ADAPTER *prAdapter, + IN uint32_t u4Idx) +{ + uint32_t i; + uint8_t *pucPivot, *pucMovePivot; + uint32_t u4MoveSize, u4FreeSize, u4ReserveSize; + + ASSERT(prAdapter); + ASSERT(u4Idx < CFG_MAX_NUM_BSS_LIST); + + if (prAdapter->rWlanInfo.arScanResult[u4Idx].u4IELength == 0 + || prAdapter->rWlanInfo.apucScanResultIEs[u4Idx] == NULL) { + return; + } + + u4FreeSize = ALIGN_4( + prAdapter->rWlanInfo.arScanResult[u4Idx].u4IELength); + + pucPivot = prAdapter->rWlanInfo.apucScanResultIEs[u4Idx]; + pucMovePivot = (uint8_t *) ((unsigned long) ( + prAdapter->rWlanInfo.apucScanResultIEs[u4Idx]) + + u4FreeSize); + + u4ReserveSize = ((unsigned long) pucPivot) - + (unsigned long) (&(prAdapter->rWlanInfo.aucScanIEBuf[0])); + u4MoveSize = prAdapter->rWlanInfo.u4ScanIEBufferUsage - + u4ReserveSize - u4FreeSize; + + /* 1. rest of buffer to move forward */ + kalMemCopy(pucPivot, pucMovePivot, u4MoveSize); + + /* 1.1 modify pointers */ + for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { + if (i != u4Idx) { + if (prAdapter->rWlanInfo.apucScanResultIEs[i] >= + pucMovePivot) { + prAdapter->rWlanInfo.apucScanResultIEs[i] = + (uint8_t *) ((unsigned long) ( + prAdapter->rWlanInfo. + apucScanResultIEs[i]) + - u4FreeSize); + } + } + } + + /* 1.2 reset the freed one */ + prAdapter->rWlanInfo.arScanResult[u4Idx].u4IELength = 0; + prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL; + + /* 2. reduce IE buffer usage */ + prAdapter->rWlanInfo.u4ScanIEBufferUsage -= u4FreeSize; + +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is to hack parameters for WLAN TABLE for + * fixed rate settings + * + * @param prAdapter Pointer to the Adapter structure. + * @param eRateSetting + * @param pu2DesiredNonHTRateSet, + * @param pu2BSSBasicRateSet, + * @param pucMcsSet + * @param pucSupMcs32 + * @param pu2HtCapInfo + * + * @return WLAN_STATUS_SUCCESS + */ +/*----------------------------------------------------------------------------*/ +uint32_t +nicUpdateRateParams(IN struct ADAPTER *prAdapter, + IN enum ENUM_REGISTRY_FIXED_RATE eRateSetting, + IN uint8_t *pucDesiredPhyTypeSet, + IN uint16_t *pu2DesiredNonHTRateSet, + IN uint16_t *pu2BSSBasicRateSet, + IN uint8_t *pucMcsSet, IN uint8_t *pucSupMcs32, + IN uint16_t *pu2HtCapInfo) +{ + ASSERT(prAdapter); + ASSERT(eRateSetting > FIXED_RATE_NONE + && eRateSetting < FIXED_RATE_NUM); + + switch (prAdapter->rWifiVar.eRateSetting) { + case FIXED_RATE_1M: + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HR_DSSS; + *pu2DesiredNonHTRateSet = RATE_SET_BIT_1M; + *pu2BSSBasicRateSet = RATE_SET_BIT_1M; + *pucMcsSet = 0; + *pucSupMcs32 = 0; + *pu2HtCapInfo = 0; + break; + + case FIXED_RATE_2M: + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HR_DSSS; + *pu2DesiredNonHTRateSet = RATE_SET_BIT_2M; + *pu2BSSBasicRateSet = RATE_SET_BIT_2M; + *pucMcsSet = 0; + *pucSupMcs32 = 0; + *pu2HtCapInfo = 0; + break; + + case FIXED_RATE_5_5M: + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HR_DSSS; + *pu2DesiredNonHTRateSet = RATE_SET_BIT_5_5M; + *pu2BSSBasicRateSet = RATE_SET_BIT_5_5M; + *pucMcsSet = 0; + *pucSupMcs32 = 0; + *pu2HtCapInfo = 0; + break; + + case FIXED_RATE_11M: + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HR_DSSS; + *pu2DesiredNonHTRateSet = RATE_SET_BIT_11M; + *pu2BSSBasicRateSet = RATE_SET_BIT_11M; + *pucMcsSet = 0; + *pucSupMcs32 = 0; + *pu2HtCapInfo = 0; + break; + + case FIXED_RATE_6M: + if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; + else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; + + *pu2DesiredNonHTRateSet = RATE_SET_BIT_6M; + *pu2BSSBasicRateSet = RATE_SET_BIT_6M; + *pucMcsSet = 0; + *pucSupMcs32 = 0; + *pu2HtCapInfo = 0; + break; + + case FIXED_RATE_9M: + if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; + else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; + + *pu2DesiredNonHTRateSet = RATE_SET_BIT_9M; + *pu2BSSBasicRateSet = RATE_SET_BIT_9M; + *pucMcsSet = 0; + *pucSupMcs32 = 0; + *pu2HtCapInfo = 0; + break; + + case FIXED_RATE_12M: + if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; + else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; + + *pu2DesiredNonHTRateSet = RATE_SET_BIT_12M; + *pu2BSSBasicRateSet = RATE_SET_BIT_12M; + *pucMcsSet = 0; + *pucSupMcs32 = 0; + *pu2HtCapInfo = 0; + break; + + case FIXED_RATE_18M: + if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; + else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; + + *pu2DesiredNonHTRateSet = RATE_SET_BIT_18M; + *pu2BSSBasicRateSet = RATE_SET_BIT_18M; + *pucMcsSet = 0; + *pucSupMcs32 = 0; + *pu2HtCapInfo = 0; + break; + + case FIXED_RATE_24M: + if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; + else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; + + *pu2DesiredNonHTRateSet = RATE_SET_BIT_24M; + *pu2BSSBasicRateSet = RATE_SET_BIT_24M; + *pucMcsSet = 0; + *pucSupMcs32 = 0; + *pu2HtCapInfo = 0; + break; + + case FIXED_RATE_36M: + if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; + else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; + + *pu2DesiredNonHTRateSet = RATE_SET_BIT_36M; + *pu2BSSBasicRateSet = RATE_SET_BIT_36M; + *pucMcsSet = 0; + *pucSupMcs32 = 0; + *pu2HtCapInfo = 0; + break; + + case FIXED_RATE_48M: + if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; + else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; + + *pu2DesiredNonHTRateSet = RATE_SET_BIT_48M; + *pu2BSSBasicRateSet = RATE_SET_BIT_48M; + *pucMcsSet = 0; + *pucSupMcs32 = 0; + *pu2HtCapInfo = 0; + break; + + case FIXED_RATE_54M: + if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; + else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; + + *pu2DesiredNonHTRateSet = RATE_SET_BIT_54M; + *pu2BSSBasicRateSet = RATE_SET_BIT_54M; + *pucMcsSet = 0; + *pucSupMcs32 = 0; + *pu2HtCapInfo = 0; + break; + + case FIXED_RATE_MCS0_20M_800NS: + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; + *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; + *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; + *pucMcsSet = BIT(HT_RATE_MCS0_INDEX - 1); + *pucSupMcs32 = 0; + (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH + | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | + HT_CAP_INFO_HT_GF); + break; + + case FIXED_RATE_MCS1_20M_800NS: + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; + *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; + *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; + *pucMcsSet = BIT(HT_RATE_MCS1_INDEX - 1); + *pucSupMcs32 = 0; + (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH + | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | + HT_CAP_INFO_HT_GF); + break; + + case FIXED_RATE_MCS2_20M_800NS: + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; + *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; + *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; + *pucMcsSet = BIT(HT_RATE_MCS2_INDEX - 1); + *pucSupMcs32 = 0; + (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH + | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | + HT_CAP_INFO_HT_GF); + break; + + case FIXED_RATE_MCS3_20M_800NS: + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; + *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; + *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; + *pucMcsSet = BIT(HT_RATE_MCS3_INDEX - 1); + *pucSupMcs32 = 0; + (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH + | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | + HT_CAP_INFO_HT_GF); + break; + + case FIXED_RATE_MCS4_20M_800NS: + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; + *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; + *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; + *pucMcsSet = BIT(HT_RATE_MCS4_INDEX - 1); + *pucSupMcs32 = 0; + (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH + | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | + HT_CAP_INFO_HT_GF); + break; + + case FIXED_RATE_MCS5_20M_800NS: + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; + *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; + *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; + *pucMcsSet = BIT(HT_RATE_MCS5_INDEX - 1); + *pucSupMcs32 = 0; + (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH + | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | + HT_CAP_INFO_HT_GF); + break; + + case FIXED_RATE_MCS6_20M_800NS: + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; + *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; + *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; + *pucMcsSet = BIT(HT_RATE_MCS6_INDEX - 1); + *pucSupMcs32 = 0; + (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH + | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | + HT_CAP_INFO_HT_GF); + break; + + case FIXED_RATE_MCS7_20M_800NS: + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; + *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; + *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; + *pucMcsSet = BIT(HT_RATE_MCS7_INDEX - 1); + *pucSupMcs32 = 0; + (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH + | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | + HT_CAP_INFO_HT_GF); + break; + + case FIXED_RATE_MCS0_20M_400NS: + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; + *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; + *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; + *pucMcsSet = BIT(HT_RATE_MCS0_INDEX - 1); + *pucSupMcs32 = 0; + (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | + HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); + (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; + break; + + case FIXED_RATE_MCS1_20M_400NS: + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; + *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; + *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; + *pucMcsSet = BIT(HT_RATE_MCS1_INDEX - 1); + *pucSupMcs32 = 0; + (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | + HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); + (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; + break; + + case FIXED_RATE_MCS2_20M_400NS: + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; + *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; + *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; + *pucMcsSet = BIT(HT_RATE_MCS2_INDEX - 1); + *pucSupMcs32 = 0; + (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | + HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); + (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; + break; + + case FIXED_RATE_MCS3_20M_400NS: + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; + *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; + *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; + *pucMcsSet = BIT(HT_RATE_MCS3_INDEX - 1); + *pucSupMcs32 = 0; + (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | + HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); + (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; + break; + + case FIXED_RATE_MCS4_20M_400NS: + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; + *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; + *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; + *pucMcsSet = BIT(HT_RATE_MCS4_INDEX - 1); + *pucSupMcs32 = 0; + (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | + HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); + (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; + break; + + case FIXED_RATE_MCS5_20M_400NS: + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; + *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; + *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; + *pucMcsSet = BIT(HT_RATE_MCS5_INDEX - 1); + *pucSupMcs32 = 0; + (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | + HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); + (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; + break; + + case FIXED_RATE_MCS6_20M_400NS: + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; + *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; + *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; + *pucMcsSet = BIT(HT_RATE_MCS6_INDEX - 1); + *pucSupMcs32 = 0; + (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | + HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); + (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; + break; + + case FIXED_RATE_MCS7_20M_400NS: + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; + *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; + *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; + *pucMcsSet = BIT(HT_RATE_MCS7_INDEX - 1); + *pucSupMcs32 = 0; + (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | + HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); + (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; + break; + + case FIXED_RATE_MCS0_40M_800NS: + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; + *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; + *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; + *pucMcsSet = BIT(HT_RATE_MCS0_INDEX - 1); + *pucSupMcs32 = 0; + (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | + HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); + (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; + break; + + case FIXED_RATE_MCS1_40M_800NS: + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; + *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; + *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; + *pucMcsSet = BIT(HT_RATE_MCS1_INDEX - 1); + *pucSupMcs32 = 0; + (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | + HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); + (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; + break; + + case FIXED_RATE_MCS2_40M_800NS: + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; + *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; + *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; + *pucMcsSet = BIT(HT_RATE_MCS2_INDEX - 1); + *pucSupMcs32 = 0; + (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | + HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); + (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; + break; + + case FIXED_RATE_MCS3_40M_800NS: + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; + *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; + *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; + *pucMcsSet = BIT(HT_RATE_MCS3_INDEX - 1); + *pucSupMcs32 = 0; + (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | + HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); + (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; + break; + + case FIXED_RATE_MCS4_40M_800NS: + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; + *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; + *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; + *pucMcsSet = BIT(HT_RATE_MCS4_INDEX - 1); + *pucSupMcs32 = 0; + (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | + HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); + (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; + break; + + case FIXED_RATE_MCS5_40M_800NS: + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; + *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; + *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; + *pucMcsSet = BIT(HT_RATE_MCS5_INDEX - 1); + *pucSupMcs32 = 0; + (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | + HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); + (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; + break; + + case FIXED_RATE_MCS6_40M_800NS: + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; + *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; + *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; + *pucMcsSet = BIT(HT_RATE_MCS6_INDEX - 1); + *pucSupMcs32 = 0; + (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | + HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); + (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; + break; + + case FIXED_RATE_MCS7_40M_800NS: + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; + *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; + *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; + *pucMcsSet = BIT(HT_RATE_MCS7_INDEX - 1); + *pucSupMcs32 = 0; + (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | + HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); + (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; + break; + + case FIXED_RATE_MCS32_800NS: + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; + *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; + *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; + *pucMcsSet = 0; + *pucSupMcs32 = 1; + (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | + HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); + (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; + break; + + case FIXED_RATE_MCS0_40M_400NS: + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; + *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; + *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; + *pucMcsSet = BIT(HT_RATE_MCS0_INDEX - 1); + *pucSupMcs32 = 0; + (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | + HT_CAP_INFO_HT_GF); + (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | + HT_CAP_INFO_SHORT_GI_40M); + break; + + case FIXED_RATE_MCS1_40M_400NS: + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; + *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; + *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; + *pucMcsSet = BIT(HT_RATE_MCS1_INDEX - 1); + *pucSupMcs32 = 0; + (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | + HT_CAP_INFO_HT_GF); + (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | + HT_CAP_INFO_SHORT_GI_40M); + break; + + case FIXED_RATE_MCS2_40M_400NS: + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; + *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; + *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; + *pucMcsSet = BIT(HT_RATE_MCS2_INDEX - 1); + *pucSupMcs32 = 0; + (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | + HT_CAP_INFO_HT_GF); + (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | + HT_CAP_INFO_SHORT_GI_40M); + break; + + case FIXED_RATE_MCS3_40M_400NS: + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; + *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; + *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; + *pucMcsSet = BIT(HT_RATE_MCS3_INDEX - 1); + *pucSupMcs32 = 0; + (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | + HT_CAP_INFO_HT_GF); + (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | + HT_CAP_INFO_SHORT_GI_40M); + break; + + case FIXED_RATE_MCS4_40M_400NS: + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; + *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; + *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; + *pucMcsSet = BIT(HT_RATE_MCS4_INDEX - 1); + *pucSupMcs32 = 0; + (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | + HT_CAP_INFO_HT_GF); + (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | + HT_CAP_INFO_SHORT_GI_40M); + break; + + case FIXED_RATE_MCS5_40M_400NS: + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; + *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; + *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; + *pucMcsSet = BIT(HT_RATE_MCS5_INDEX - 1); + *pucSupMcs32 = 0; + (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | + HT_CAP_INFO_HT_GF); + (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | + HT_CAP_INFO_SHORT_GI_40M); + break; + + case FIXED_RATE_MCS6_40M_400NS: + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; + *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; + *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; + *pucMcsSet = BIT(HT_RATE_MCS6_INDEX - 1); + *pucSupMcs32 = 0; + (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | + HT_CAP_INFO_HT_GF); + (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | + HT_CAP_INFO_SHORT_GI_40M); + break; + + case FIXED_RATE_MCS7_40M_400NS: + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; + *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; + *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; + *pucMcsSet = BIT(HT_RATE_MCS7_INDEX - 1); + *pucSupMcs32 = 0; + (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | + HT_CAP_INFO_HT_GF); + (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | + HT_CAP_INFO_SHORT_GI_40M); + break; + + case FIXED_RATE_MCS32_400NS: + *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; + *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; + *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; + *pucMcsSet = 0; + *pucSupMcs32 = 1; + (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | + HT_CAP_INFO_HT_GF); + (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | + HT_CAP_INFO_SHORT_GI_40M); + break; + + default: + ASSERT(0); + } + + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This utility function is used to write the register + * + * @param u4Address Register address + * u4Value the value to be written + * + * @retval WLAN_STATUS_SUCCESS + * WLAN_STATUS_FAILURE + */ +/*----------------------------------------------------------------------------*/ + +uint32_t nicWriteMcr(IN struct ADAPTER *prAdapter, + IN uint32_t u4Address, IN uint32_t u4Value) +{ + struct CMD_ACCESS_REG rCmdAccessReg; + + rCmdAccessReg.u4Address = u4Address; + rCmdAccessReg.u4Data = u4Value; + + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_ACCESS_REG, + TRUE, + FALSE, + FALSE, NULL, NULL, + sizeof(struct CMD_ACCESS_REG), + (uint8_t *) &rCmdAccessReg, NULL, 0); + +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This utility function is used to modify the auto rate parameters + * + * @param u4ArSysParam0 see description below + * u4ArSysParam1 + * u4ArSysParam2 + * u4ArSysParam3 + * + * + * @retval WLAN_STATUS_SUCCESS + * WLAN_STATUS_FAILURE + * + * @note + * ArSysParam0[0:3] -> auto rate version (0:disable 1:version1 2:version2) + * ArSysParam0[4:5]-> auto bw version (0:disable 1:version1 2:version2) + * ArSysParam0[6:7]-> auto gi version (0:disable 1:version1 2:version2) + * ArSysParam0[8:15]-> HT rate clear mask + * ArSysParam0[16:31]-> Legacy rate clear mask + * ArSysParam1[0:7]-> Auto Rate check weighting window + * ArSysParam1[8:15]-> Auto Rate v1 Force Rate down + * ArSysParam1[16:23]-> Auto Rate v1 PerH + * ArSysParam1[24:31]-> Auto Rate v1 PerL + * + * Examples + * ArSysParam0 = 1, + * Enable auto rate version 1 + * + * ArSysParam0 = 983041, + * Enable auto rate version 1 + * Remove CCK 1M, 2M, 5.5M, 11M + * + * ArSysParam0 = 786433 + * Enable auto rate version 1 + * Remove CCK 5.5M 11M + */ +/*----------------------------------------------------------------------------*/ + +uint32_t +nicRlmArUpdateParms(IN struct ADAPTER *prAdapter, + IN uint32_t u4ArSysParam0, + IN uint32_t u4ArSysParam1, IN uint32_t u4ArSysParam2, + IN uint32_t u4ArSysParam3) +{ + uint8_t ucArVer, ucAbwVer, ucAgiVer; + uint16_t u2HtClrMask; + uint16_t u2LegacyClrMask; + uint8_t ucArCheckWindow; + uint8_t ucArPerL; + uint8_t ucArPerH; + uint8_t ucArPerForceRateDownPer; + + ucArVer = (uint8_t) (u4ArSysParam0 & BITS(0, 3)); + ucAbwVer = (uint8_t) ((u4ArSysParam0 & BITS(4, 5)) >> 4); + ucAgiVer = (uint8_t) ((u4ArSysParam0 & BITS(6, 7)) >> 6); + u2HtClrMask = (uint16_t) ((u4ArSysParam0 & BITS(8, + 15)) >> 8); + u2LegacyClrMask = (uint16_t) ((u4ArSysParam0 & BITS(16, + 31)) >> 16); + +#if 0 + ucArCheckWindow = (uint8_t) (u4ArSysParam1 & BITS(0, 7)); + ucArPerH = (uint8_t) ((u4ArSysParam1 & BITS(16, 23)) >> 16); + ucArPerL = (uint8_t) ((u4ArSysParam1 & BITS(24, 31)) >> 24); +#endif + + ucArCheckWindow = (uint8_t) (u4ArSysParam1 & BITS(0, 7)); + ucArPerForceRateDownPer = (uint8_t) (((u4ArSysParam1 >> 8) & + BITS(0, 7))); + ucArPerH = (uint8_t) (((u4ArSysParam1 >> 16) & BITS(0, 7))); + ucArPerL = (uint8_t) (((u4ArSysParam1 >> 24) & BITS(0, 7))); + + DBGLOG(INIT, INFO, "ArParam %u %u %u %u\n", u4ArSysParam0, + u4ArSysParam1, u4ArSysParam2, u4ArSysParam3); + DBGLOG(INIT, INFO, "ArVer %u AbwVer %u AgiVer %u\n", + ucArVer, ucAbwVer, ucAgiVer); + DBGLOG(INIT, INFO, "HtMask %x LegacyMask %x\n", u2HtClrMask, + u2LegacyClrMask); + DBGLOG(INIT, INFO, + "CheckWin %u RateDownPer %u PerH %u PerL %u\n", + ucArCheckWindow, + ucArPerForceRateDownPer, ucArPerH, ucArPerL); + +#define SWCR_DATA_ADDR(MOD, ADDR) (0x90000000+(MOD<<8)+(ADDR)) +#define SWCR_DATA_CMD(CATE, WRITE, INDEX, OPT0, OPT1) \ + ((CATE<<24) | (WRITE<<23) | (INDEX<<16) | (OPT0 << 8) | OPT1) +#define SWCR_DATA0 0x0 +#define SWCR_DATA1 0x4 +#define SWCR_DATA2 0x8 +#define SWCR_DATA3 0xC +#define SWCR_DATA4 0x10 +#define SWCR_WRITE 1 +#define SWCR_READ 0 + + if (ucArVer > 0) { + /* dummy = WiFi.WriteMCR(&h90000104, &h00000001) */ + /* dummy = WiFi.WriteMCR(&h90000100, &h00850000) */ + + nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, + SWCR_DATA1), 1); + nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, + SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 5, 0, 0)); + } else { + nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, + SWCR_DATA1), 0); + nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, + SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 5, 0, 0)); + } + + /* ucArVer 0: none 1:PER 2:Rcpi */ + nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, + SWCR_DATA1), ucArVer); + nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, + SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 7, 0, 0)); + + /* Candidate rate Ht mask */ + nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, + SWCR_DATA1), u2HtClrMask); + nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, + SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0x1c, 0, 0)); + + /* Candidate rate legacy mask */ + nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, + SWCR_DATA1), u2LegacyClrMask); + nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, + SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0x1d, 0, 0)); + +#if 0 + if (ucArCheckWindow != 0) { + /* TX DONE MCS INDEX CHECK STA RATE DOWN TH */ + nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, + SWCR_DATA1), ucArCheckWindow); + nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, + SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0x14, 0, 0)); + nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, + SWCR_DATA1), ucArCheckWindow); + nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, + SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0xc, 0, 0)); + } + + if (ucArPerForceRateDownPer != 0) { + nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, + SWCR_DATA1), ucArPerForceRateDownPer); + nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, + SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0x18, 0, 0)); + } + if (ucArPerH != 0) { + nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, + SWCR_DATA1), ucArPerH); + nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, + SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0x1, 0, 0)); + } + if (ucArPerL != 0) { + nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, + SWCR_DATA1), ucArPerL); + nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, + SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0x2, 0, 0)); + } +#endif + + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called to update Link Quality information + * + * @param prAdapter Pointer of Adapter Data Structure + * ucBssIndex + * prEventLinkQuality + * cRssi + * cLinkQuality + * + * @return none + */ +/*----------------------------------------------------------------------------*/ +void nicUpdateLinkQuality(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN struct EVENT_LINK_QUALITY *prEventLinkQuality) +{ + int8_t cRssi; + uint16_t u2AdjustRssi = 10; + struct LINK_SPEED_EX_ *prLq; + +#if (CFG_TWT_SMART_STA == 1) + struct _MSG_TWT_PARAMS_SET_T *prTWTParamSetMsg; + struct _TWT_CTRL_T rTWTCtrl; +#endif + + ASSERT(prAdapter); + ASSERT(ucBssIndex <= prAdapter->ucHwBssIdNum); + ASSERT(prEventLinkQuality); + + prLq = &prAdapter->rLinkQuality.rLq[ucBssIndex]; + switch (GET_BSS_INFO_BY_INDEX(prAdapter, + ucBssIndex)->eNetworkType) { + case NETWORK_TYPE_AIS: + if (GET_BSS_INFO_BY_INDEX(prAdapter, + ucBssIndex)->eConnectionState == + MEDIA_STATE_CONNECTED) { + /* check is to prevent RSSI to be updated by + * incorrect initial RSSI from hardware + */ + /* buffer statistics for further query */ + if (prLq->fgIsLinkQualityValid == FALSE || + (kalGetTimeTick() - prLq->rLinkQualityUpdateTime) > + CFG_LINK_QUALITY_VALID_PERIOD) { + /* ranged from (-128 ~ 30) in unit of dBm */ + cRssi = + prEventLinkQuality->rLq[ucBssIndex]. + cRssi; + cRssi = + (int8_t) (((int16_t) + (cRssi) * u2AdjustRssi) / 10); + DBGLOG(RLM, INFO, + "Rssi=%d, NewRssi=%d\n", + prEventLinkQuality->rLq[ucBssIndex]. + cRssi, + cRssi); + nicUpdateRSSI(prAdapter, ucBssIndex, cRssi, + prEventLinkQuality->rLq[ucBssIndex]. + cLinkQuality); + +#if (CFG_TWT_SMART_STA == 1) + + DBGLOG(RLM, INFO, + "smarttwtreq=%d, smarttwtact=%d(%d)\n", + g_TwtSmartStaCtrl. + fgTwtSmartStaReq, + g_TwtSmartStaCtrl. + fgTwtSmartStaActivated, + g_TwtSmartStaCtrl.eState); + + if ((cRssi >= (-35)) && + (g_TwtSmartStaCtrl.u4TwtSwitch == 0) && + ((g_TwtSmartStaCtrl. + fgTwtSmartStaReq == TRUE) && + (g_TwtSmartStaCtrl. + fgTwtSmartStaActivated == FALSE) + && (g_TwtSmartStaCtrl. + eState == + TWT_SMART_STA_STATE_IDLE)) + ) { + rTWTCtrl.ucBssIdx + = ucBssIndex; + rTWTCtrl.ucCtrlAction + = 4; + rTWTCtrl.ucTWTFlowId + = 0; + rTWTCtrl.rTWTParams. + fgReq = TRUE; + rTWTCtrl.rTWTParams. + ucSetupCmd = 1; + rTWTCtrl.rTWTParams. + fgTrigger = 0; + rTWTCtrl.rTWTParams. + fgUnannounced + = 1; + rTWTCtrl.rTWTParams. + ucWakeIntvalExponent + = 10; + rTWTCtrl.rTWTParams. + fgProtect = 0; + rTWTCtrl.rTWTParams. + ucMinWakeDur + = 255; + rTWTCtrl.rTWTParams. + u2WakeIntvalMantiss + = 512; + + g_TwtSmartStaCtrl.eState = + TWT_SMART_STA_STATE_REQUESTING; + + prTWTParamSetMsg = + cnmMemAlloc(prAdapter, + RAM_TYPE_MSG, + sizeof(struct + _MSG_TWT_REQFSM_RESUME_T)); + } + + if (((cRssi <= (-40)) || + (g_TwtSmartStaCtrl. + fgTwtSmartStaTeardownReq + == TRUE)) && + (g_TwtSmartStaCtrl. + fgTwtSmartStaActivated + == true)) { + rTWTCtrl.ucBssIdx + = ucBssIndex; + rTWTCtrl.ucCtrlAction + = 5; + rTWTCtrl.ucTWTFlowId + = g_TwtSmartStaCtrl. + ucFlowId; + + DBGLOG(RLM, INFO, + "twtswitch=%d, rxrate=%d\n", + g_TwtSmartStaCtrl.u4TwtSwitch, + g_TwtSmartStaCtrl.u4LastTp); + + prTWTParamSetMsg + = cnmMemAlloc(prAdapter, + RAM_TYPE_MSG, + sizeof(struct + _MSG_TWT_REQFSM_RESUME_T)); + } + + if (prTWTParamSetMsg) { + prTWTParamSetMsg-> + rMsgHdr.eMsgId = + MID_TWT_PARAMS_SET; + kalMemCopy( + &prTWTParamSetMsg-> + rTWTCtrl, + &rTWTCtrl, + sizeof(rTWTCtrl)); + + mboxSendMsg(prAdapter, + MBOX_ID_0, + (struct MSG_HDR *) + prTWTParamSetMsg, + MSG_SEND_METHOD_BUF); + } + + +#endif + } + + if (prLq->fgIsLinkRateValid == FALSE || + (kalGetTimeTick() - prLq->rLinkRateUpdateTime) + > CFG_LINK_QUALITY_VALID_PERIOD) { + nicUpdateLinkSpeed(prAdapter, ucBssIndex, + prEventLinkQuality->rLq[ucBssIndex]. + u2LinkSpeed); + } + + } + break; + +#if 0 +/* #if CFG_ENABLE_WIFI_DIRECT && CFG_SUPPORT_P2P_RSSI_QUERY */ + case NETWORK_TYPE_P2P: + if (prAdapter->fgIsP2pLinkQualityValid == FALSE + || (kalGetTimeTick() - prAdapter->rP2pLinkQualityUpdateTime) + > CFG_LINK_QUALITY_VALID_PERIOD) { + struct EVENT_LINK_QUALITY_EX *prEventLQEx = + (struct EVENT_LINK_QUALITY_EX *) + prEventLinkQuality; + + nicUpdateRSSI(prAdapter, ucBssIndex, + prEventLQEx->cRssiP2P, + prEventLQEx->cLinkQualityP2P); + } + break; +#endif + default: + break; + + } + +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called to update RSSI and Link Quality information + * + * @param prAdapter Pointer of Adapter Data Structure + * ucBssIndex + * cRssi + * cLinkQuality + * + * @return none + */ +/*----------------------------------------------------------------------------*/ +void nicUpdateRSSI(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, IN int8_t cRssi, + IN int8_t cLinkQuality) +{ + ASSERT(prAdapter); + ASSERT(ucBssIndex <= prAdapter->ucHwBssIdNum); + + switch (GET_BSS_INFO_BY_INDEX(prAdapter, + ucBssIndex)->eNetworkType) { + case NETWORK_TYPE_AIS: + if (GET_BSS_INFO_BY_INDEX(prAdapter, + ucBssIndex)->eConnectionState == + MEDIA_STATE_CONNECTED) { + prAdapter->rLinkQuality.rLq[ucBssIndex]. + fgIsLinkQualityValid = TRUE; + prAdapter->rLinkQuality.rLq[ucBssIndex]. + rLinkQualityUpdateTime = kalGetTimeTick(); + + prAdapter->rLinkQuality.rLq[ucBssIndex]. + cRssi = cRssi; + prAdapter->rLinkQuality.rLq[ucBssIndex]. + cLinkQuality = cLinkQuality; + /* indicate to glue layer */ + kalUpdateRSSI(prAdapter->prGlueInfo, + ucBssIndex, cRssi, cLinkQuality); + } + + break; +#if CFG_ENABLE_WIFI_DIRECT && CFG_SUPPORT_P2P_RSSI_QUERY + case NETWORK_TYPE_P2P: + prAdapter->fgIsP2pLinkQualityValid = TRUE; + prAdapter->rP2pLinkQualityUpdateTime = kalGetTimeTick(); + + prAdapter->rP2pLinkQuality.cRssi = cRssi; + prAdapter->rP2pLinkQuality.cLinkQuality = cLinkQuality; + + kalUpdateRSSI(prAdapter->prGlueInfo, + ucBssIndex, cRssi, cLinkQuality); + break; +#endif + default: + break; + + } + +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called to update Link Quality information + * + * @param prAdapter Pointer of Adapter Data Structure + * ucBssIndex + * prEventLinkQuality + * cRssi + * cLinkQuality + * + * @return none + */ +/*----------------------------------------------------------------------------*/ +void nicUpdateLinkSpeed(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, IN uint16_t u2LinkSpeed) +{ + ASSERT(prAdapter); + ASSERT(ucBssIndex <= prAdapter->ucHwBssIdNum); + + switch (GET_BSS_INFO_BY_INDEX(prAdapter, + ucBssIndex)->eNetworkType) { + case NETWORK_TYPE_AIS: + if (GET_BSS_INFO_BY_INDEX(prAdapter, + ucBssIndex)->eConnectionState == + MEDIA_STATE_CONNECTED) { + /* buffer statistics for further query */ + prAdapter->rLinkQuality.rLq[ucBssIndex]. + fgIsLinkRateValid = TRUE; + prAdapter->rLinkQuality.rLq[ucBssIndex]. + rLinkRateUpdateTime = kalGetTimeTick(); + + prAdapter->rLinkQuality.rLq[ucBssIndex]. + u2LinkSpeed = u2LinkSpeed; + } + break; + + default: + break; + + } + +} + +#if CFG_SUPPORT_RDD_TEST_MODE +uint32_t nicUpdateRddTestMode(IN struct ADAPTER *prAdapter, + IN struct CMD_RDD_CH *prRddChParam) +{ + DEBUGFUNC("nicUpdateRddTestMode.\n"); + + ASSERT(prAdapter); + + /* aisFsmScanRequest(prAdapter, NULL); */ + + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_SET_RDD_CH, + TRUE, + FALSE, FALSE, NULL, NULL, + sizeof(struct CMD_RDD_CH), + (uint8_t *) prRddChParam, NULL, 0); +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called to apply network address setting to + * both OS side and firmware domain + * + * @param prAdapter Pointer of Adapter Data Structure + * + * @return none + */ +/*----------------------------------------------------------------------------*/ + +uint32_t nicApplyNetworkAddress(IN struct ADAPTER + *prAdapter) +{ + uint32_t i; + + ASSERT(prAdapter); + + /* copy to adapter */ + COPY_MAC_ADDR(prAdapter->rMyMacAddr, + prAdapter->rWifiVar.aucMacAddress); + + /* 4 <3> Update new MAC address to all 3 networks */ + COPY_MAC_ADDR(prAdapter->rWifiVar.aucDeviceAddress, + prAdapter->rMyMacAddr); + prAdapter->rWifiVar.aucDeviceAddress[0] ^= + MAC_ADDR_LOCAL_ADMIN; + + for (i = 0; i < KAL_P2P_NUM; i++) { + COPY_MAC_ADDR(prAdapter->rWifiVar.aucInterfaceAddress[i], + prAdapter->rMyMacAddr); + prAdapter->rWifiVar.aucInterfaceAddress[i][0] |= 0x2; + prAdapter->rWifiVar.aucInterfaceAddress[i][0] ^= + i << MAC_ADDR_LOCAL_ADMIN; + } + +#if CFG_ENABLE_WIFI_DIRECT + if (prAdapter->fgIsP2PRegistered) { + for (i = 0; i < prAdapter->ucHwBssIdNum; i++) { + if (prAdapter->rWifiVar.arBssInfoPool[i].eNetworkType == + NETWORK_TYPE_P2P) { + COPY_MAC_ADDR( + prAdapter->rWifiVar.arBssInfoPool[i]. + aucOwnMacAddr, + prAdapter->rWifiVar.aucDeviceAddress); + } + } + } +#endif + +#if CFG_ENABLE_BT_OVER_WIFI + for (i = 0; i < prAdapter->ucHwBssIdNum; i++) { + if (prAdapter->rWifiVar.arBssInfoPool[i].eNetworkType == + NETWORK_TYPE_BOW) { + COPY_MAC_ADDR( + prAdapter->rWifiVar.arBssInfoPool[i]. + aucOwnMacAddr, + prAdapter->rWifiVar.aucDeviceAddress); + } + } +#endif + +#if CFG_TEST_WIFI_DIRECT_GO + if (prAdapter->rWifiVar.prP2pFsmInfo->eCurrentState == + P2P_STATE_IDLE) { + wlanEnableP2pFunction(prAdapter); + + wlanEnableATGO(prAdapter); + } +#endif + + kalUpdateMACAddress(prAdapter->prGlueInfo, + prAdapter->rWifiVar.aucMacAddress); + + if (KAL_AIS_NUM > 1) { + /* Generate from wlan0 MAC */ + COPY_MAC_ADDR(prAdapter->rWifiVar.aucMacAddress1, + prAdapter->rWifiVar.aucMacAddress); + /* Update wlan1 address */ + prAdapter->rWifiVar.aucMacAddress1[3] ^= BIT(1); + } + + return WLAN_STATUS_SUCCESS; +} + +#if 1 +uint8_t nicGetChipHwVer(void) +{ + return g_eco_info.ucHwVer; +} + +uint8_t nicGetChipSwVer(void) +{ + return g_eco_info.ucRomVer; +} + +uint8_t nicGetChipFactoryVer(void) +{ + return g_eco_info.ucFactoryVer; +} + +uint8_t nicSetChipHwVer(uint8_t value) +{ + g_eco_info.ucHwVer = value; + return 0; +} + +uint8_t nicSetChipSwVer(uint8_t value) +{ + g_eco_info.ucRomVer = value; + return 0; +} + +uint8_t nicSetChipFactoryVer(uint8_t value) +{ + g_eco_info.ucFactoryVer = value; + return 0; +} + +#else +uint8_t nicGetChipHwVer(void) +{ + return mtk_wcn_wmt_ic_info_get(WMTCHIN_HWVER) & BITS(0, 7); +} + +uint8_t nicGetChipSwVer(void) +{ + return mtk_wcn_wmt_ic_info_get(WMTCHIN_FWVER) & BITS(0, 7); +} + +uint8_t nicGetChipFactoryVer(void) +{ + return (mtk_wcn_wmt_ic_info_get(WMTCHIN_FWVER) & BITS(8, + 11)) >> 8; +} +#endif + +uint8_t nicGetChipEcoVer(IN struct ADAPTER *prAdapter) +{ + struct ECO_INFO *prEcoInfo; + uint8_t ucEcoVer; + uint8_t ucCurSwVer, ucCurHwVer, ucCurFactoryVer; + + ucCurSwVer = nicGetChipSwVer(); + ucCurHwVer = nicGetChipHwVer(); + ucCurFactoryVer = nicGetChipFactoryVer(); + + ucEcoVer = 0; + + while (TRUE) { + /* Get ECO info from table */ + prEcoInfo = (struct ECO_INFO *) & + (prAdapter->chip_info->eco_info[ucEcoVer]); + + if ((prEcoInfo->ucRomVer == 0) && + (prEcoInfo->ucHwVer == 0) && + (prEcoInfo->ucFactoryVer == 0)) { + + /* last ECO info */ + if (ucEcoVer > 0) + ucEcoVer--; + + /* End of table */ + break; + } + + if ((prEcoInfo->ucRomVer == ucCurSwVer) && + (prEcoInfo->ucHwVer == ucCurHwVer) && + (prEcoInfo->ucFactoryVer == ucCurFactoryVer)) { + break; + } + + ucEcoVer++; + } + +#if 0 + DBGLOG(INIT, INFO, + "Cannot get ECO version for SwVer[0x%02x]HwVer[0x%02x]FactoryVer[0x%1x],recognize as latest version[E%u]\n", + ucCurSwVer, ucCurHwVer, ucCurFactoryVer, + prAdapter->chip_info->eco_info[ucEcoVer].ucEcoVer); +#endif + return prAdapter->chip_info->eco_info[ucEcoVer].ucEcoVer; +} + +u_int8_t nicIsEcoVerEqualTo(IN struct ADAPTER *prAdapter, + uint8_t ucEcoVer) +{ + if (ucEcoVer == prAdapter->chip_info->eco_ver) + return TRUE; + else + return FALSE; +} + +u_int8_t nicIsEcoVerEqualOrLaterTo(IN struct ADAPTER + *prAdapter, uint8_t ucEcoVer) +{ + if (ucEcoVer <= prAdapter->chip_info->eco_ver) + return TRUE; + else + return FALSE; +} + +void nicSerStopTxRx(IN struct ADAPTER *prAdapter) +{ +#if defined(_HIF_USB) + unsigned long ulFlags; + + /*TODO: multiple spinlocks seems risky. + * http://www.linuxgrill.com/anonymous/fire/netfilter/ + * kernel-hacking-HOWTO-5.html + */ + /* 1. Make sure ucSerState is accessed sequentially. + * 2. Two scenario for race condition: + * - When hif_thread is doing usb_submit_urb, SER occurs. + * hif_thread acquires the lock first, + * so nicSerSyncTimerHandler must wait hif_thread + * until it completes current usb_submit_urb. + * Then, nicSerSyncTimerHandler acquires the lock, + * change ucSerState to prevent subsequent usb_submit_urb and + * cancel ALL TX BULK OUT URB. + * - When SER is triggered and executed, + * hif_thread is prepared to do usb_submit_urb. + * nicSerSyncTimerHandler acquires the lock first, + * which guarantees ucSerState is accessed sequentially. + * Then, hif_thread acquires the lock, knows that SER is ongoing, + * and bypass usb_submit_urb. + */ + spin_lock_irqsave(&prAdapter->prGlueInfo->rHifInfo.rStateLock, + ulFlags); +#endif + + DBGLOG(NIC, WARN, "SER: Stop HIF Tx/Rx!\n"); + + prAdapter->ucSerState = SER_STOP_HOST_TX_RX; + + /* Force own to FW as ACK and stop HIF */ + prAdapter->fgWiFiInSleepyState = TRUE; + +#if defined(_HIF_USB) + spin_unlock_irqrestore(&prAdapter->prGlueInfo->rHifInfo.rStateLock, + ulFlags); +#endif + +} + +void nicSerStopTx(IN struct ADAPTER *prAdapter) +{ + DBGLOG(NIC, WARN, "SER: Stop HIF Tx!\n"); + + prAdapter->ucSerState = SER_STOP_HOST_TX; +} + +void nicSerStartTxRx(IN struct ADAPTER *prAdapter) +{ + DBGLOG(NIC, WARN, "SER: Start HIF T/R!\n"); + + prAdapter->ucSerState = SER_IDLE_DONE; +} + +u_int8_t nicSerIsWaitingReset(IN struct ADAPTER *prAdapter) +{ + if (prAdapter->ucSerState == SER_STOP_HOST_TX_RX) + return TRUE; + else + return FALSE; +} + +u_int8_t nicSerIsTxStop(IN struct ADAPTER *prAdapter) +{ + switch (prAdapter->ucSerState) { + case SER_STOP_HOST_TX: + case SER_STOP_HOST_TX_RX: + case SER_REINIT_HIF: + return TRUE; + + case SER_IDLE_DONE: + default: + return FALSE; + } +} + +u_int8_t nicSerIsRxStop(IN struct ADAPTER *prAdapter) +{ + switch (prAdapter->ucSerState) { + case SER_STOP_HOST_TX_RX: + case SER_REINIT_HIF: + return TRUE; + + case SER_STOP_HOST_TX: + case SER_IDLE_DONE: + default: + return FALSE; + } +} + +void nicSerReInitBeaconFrame(IN struct ADAPTER *prAdapter) +{ + struct P2P_ROLE_FSM_INFO *prRoleP2pFsmInfo; + + prRoleP2pFsmInfo = P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, + 0); + if (prRoleP2pFsmInfo != NULL) { + bssUpdateBeaconContent(prAdapter, + prRoleP2pFsmInfo->ucBssIndex); + DBGLOG(NIC, INFO, "SER beacon frame is updated\n"); + } +} + +#if defined(_HIF_USB) +void nicSerTimerHandler(IN struct ADAPTER *prAdapter, + IN unsigned long plParamPtr) +{ + halSerSyncTimerHandler(prAdapter); + cnmTimerStartTimer(prAdapter, + &rSerSyncTimer, + WIFI_SER_SYNC_TIMER_TIMEOUT_IN_MS); +} +#endif + +void nicSerInit(IN struct ADAPTER *prAdapter) +{ +#if defined(_HIF_USB) + /* check SER is supported or not */ + if (prAdapter->rWifiVar.fgEnableSer == TRUE && + prAdapter->chip_info->u4SerUsbMcuEventAddr != 0) { + cnmTimerInitTimer(prAdapter, + &rSerSyncTimer, + (PFN_MGMT_TIMEOUT_FUNC) nicSerTimerHandler, + (unsigned long) NULL); + cnmTimerStartTimer(prAdapter, + &rSerSyncTimer, + WIFI_SER_SYNC_TIMER_TIMEOUT_IN_MS); + } +#endif + /* if ser is not enabled, disable this feature in FW */ + if (prAdapter->rWifiVar.fgEnableSer == FALSE +#if defined(_HIF_USB) + || prAdapter->chip_info->u4SerUsbMcuEventAddr == 0 +#endif + ) { + wlanoidSerExtCmd(prAdapter, SER_ACTION_SET, + SER_SET_DISABLE, 0); + } + +} + +void nicSerDeInit(IN struct ADAPTER *prAdapter) +{ +#if defined(_HIF_USB) + cnmTimerStopTimer(prAdapter, &rSerSyncTimer); +#endif +} + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/nic_cmd_event.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/nic_cmd_event.c new file mode 100644 index 0000000000000000000000000000000000000000..491be8c70b0065baa194411cf7ab86e4bfe0519a --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/nic_cmd_event.c @@ -0,0 +1,5459 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: //Department/DaVinci/BRANCHES/ + * MT6620_WIFI_DRIVER_V2_3/nic/nic_cmd_event.c#3 + */ + +/*! \file nic_cmd_event.c + * \brief Callback functions for Command packets. + * + * Various Event packet handlers which will be setup in the callback + * function of a command packet. + */ + + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" +#include "gl_ate_agent.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +const struct NIC_CAPABILITY_V2_REF_TABLE + gNicCapabilityV2InfoTable[] = { +#if defined(_HIF_SDIO) + {TAG_CAP_TX_RESOURCE, nicEventQueryTxResourceEntry}, +#endif + {TAG_CAP_TX_EFUSEADDRESS, nicCmdEventQueryNicEfuseAddr}, + {TAG_CAP_COEX_FEATURE, nicCmdEventQueryNicCoexFeature}, + {TAG_CAP_SINGLE_SKU, rlmDomainExtractSingleSkuInfoFromFirmware}, +#if CFG_TCP_IP_CHKSUM_OFFLOAD + {TAG_CAP_CSUM_OFFLOAD, nicCmdEventQueryNicCsumOffload}, +#endif + {TAG_CAP_HW_VERSION, nicCfgChipCapHwVersion}, + {TAG_CAP_SW_VERSION, nicCfgChipCapSwVersion}, + {TAG_CAP_MAC_ADDR, nicCfgChipCapMacAddr}, + {TAG_CAP_PHY_CAP, nicCfgChipCapPhyCap}, + {TAG_CAP_MAC_CAP, nicCfgChipCapMacCap}, + {TAG_CAP_FRAME_BUF_CAP, nicCfgChipCapFrameBufCap}, + {TAG_CAP_BEAMFORM_CAP, nicCfgChipCapBeamformCap}, + {TAG_CAP_LOCATION_CAP, nicCfgChipCapLocationCap}, + {TAG_CAP_MUMIMO_CAP, nicCfgChipCapMuMimoCap}, + {TAG_CAP_HW_ADIE_VERSION, nicCfgChipAdieHwVersion}, +#if CFG_SUPPORT_ANT_SWAP + {TAG_CAP_ANTSWP, nicCfgChipCapAntSwpCap}, +#endif +#if (CFG_SUPPORT_P2PGO_ACS == 1) + {TAG_CAP_P2P, nicCfgChipP2PCap}, +#endif + {TAG_CAP_HOST_STATUS_EMI_OFFSET, nicCmdEventHostStatusEmiOffset}, + +}; + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ +struct MIB_INFO_STAT g_arMibInfo[ENUM_BAND_NUM]; +uint8_t fgEfuseCtrlAxOn = 1; /* run time control if support AX by efuse */ + + +/******************************************************************************* + * F U N C T I O N D A T A + ******************************************************************************* + */ +void nicCmdEventQueryMcrRead(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf) +{ + uint32_t u4QueryInfoLen; + struct PARAM_CUSTOM_MCR_RW_STRUCT *prMcrRdInfo; + struct GLUE_INFO *prGlueInfo; + struct CMD_ACCESS_REG *prCmdAccessReg; + + ASSERT(prAdapter); + ASSERT(prCmdInfo); + ASSERT(pucEventBuf); + + /* 4 <2> Update information of OID */ + if (prCmdInfo->fgIsOid) { + prGlueInfo = prAdapter->prGlueInfo; + prCmdAccessReg = (struct CMD_ACCESS_REG *) (pucEventBuf); + + u4QueryInfoLen = sizeof(struct PARAM_CUSTOM_MCR_RW_STRUCT); + + prMcrRdInfo = (struct PARAM_CUSTOM_MCR_RW_STRUCT *) + prCmdInfo->pvInformationBuffer; + prMcrRdInfo->u4McrOffset = prCmdAccessReg->u4Address; + prMcrRdInfo->u4McrData = prCmdAccessReg->u4Data; + + kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, + u4QueryInfoLen, WLAN_STATUS_SUCCESS); + } + + return; + +} + +void nicCmdEventQueryCfgRead(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf) +{ + uint32_t u4QueryInfoLen; + struct CMD_HEADER *prInCfgHeader; + struct GLUE_INFO *prGlueInfo; + struct CMD_HEADER *prOutCfgHeader; + + ASSERT(prAdapter); + ASSERT(prCmdInfo); + ASSERT(pucEventBuf); + + /* 4 <2> Update information of OID */ + if (prCmdInfo->fgIsOid) { + prGlueInfo = prAdapter->prGlueInfo; + prInCfgHeader = (struct CMD_HEADER *) (pucEventBuf); + u4QueryInfoLen = sizeof(struct CMD_HEADER); + prOutCfgHeader = (struct CMD_HEADER *) + (prCmdInfo->pvInformationBuffer); + + kalMemCopy(prOutCfgHeader, prInCfgHeader, + sizeof(struct CMD_HEADER)); + + kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, + u4QueryInfoLen, WLAN_STATUS_SUCCESS); + } +} + +#if CFG_SUPPORT_QA_TOOL +void nicCmdEventQueryRxStatistics(IN struct ADAPTER + *prAdapter, IN struct CMD_INFO *prCmdInfo, + IN uint8_t *pucEventBuf) +{ + struct PARAM_CUSTOM_ACCESS_RX_STAT *prRxStatistics; + struct EVENT_ACCESS_RX_STAT *prEventAccessRxStat; + uint32_t u4QueryInfoLen, i; + struct GLUE_INFO *prGlueInfo; + uint32_t *prElement; + uint32_t u4Temp; + /* P_CMD_ACCESS_RX_STAT prCmdRxStat, prRxStat; */ + + ASSERT(prAdapter); + ASSERT(prCmdInfo); + ASSERT(pucEventBuf); + + /* 4 <2> Update information of OID */ + if (prCmdInfo->fgIsOid) { + prGlueInfo = prAdapter->prGlueInfo; + prEventAccessRxStat = (struct EVENT_ACCESS_RX_STAT *) ( + pucEventBuf); + + prRxStatistics = (struct PARAM_CUSTOM_ACCESS_RX_STAT *) + prCmdInfo->pvInformationBuffer; + prRxStatistics->u4SeqNum = prEventAccessRxStat->u4SeqNum; + prRxStatistics->u4TotalNum = + prEventAccessRxStat->u4TotalNum; + + u4QueryInfoLen = sizeof(struct CMD_ACCESS_RX_STAT); + + if (prRxStatistics->u4SeqNum == u4RxStatSeqNum) { + prElement = &g_HqaRxStat.MAC_FCS_Err; + for (i = 0; i < HQA_RX_STATISTIC_NUM; i++) { + u4Temp = ntohl( + prEventAccessRxStat->au4Buffer[i]); + kalMemCopy(prElement, &u4Temp, 4); + + if (i < (HQA_RX_STATISTIC_NUM - 1)) + prElement++; + } + + g_HqaRxStat.AllMacMdrdy0 = ntohl( + prEventAccessRxStat->au4Buffer[i]); + i++; + g_HqaRxStat.AllMacMdrdy1 = ntohl( + prEventAccessRxStat->au4Buffer[i]); + /* i++; */ + /* g_HqaRxStat.AllFCSErr0 = + * ntohl(prEventAccessRxStat->au4Buffer[i]); + */ + /* i++; */ + /* g_HqaRxStat.AllFCSErr1 = + * ntohl(prEventAccessRxStat->au4Buffer[i]); + */ + } + + DBGLOG(INIT, ERROR, + "MT6632 : RX Statistics Test SeqNum = %d, TotalNum = %d\n", + (unsigned int)prEventAccessRxStat->u4SeqNum, + (unsigned int)prEventAccessRxStat->u4TotalNum); + + DBGLOG(INIT, ERROR, + "MAC_FCS_ERR = %d, MAC_MDRDY = %d, MU_RX_CNT = %d, RX_FIFO_FULL = %d\n", + (unsigned int)prEventAccessRxStat->au4Buffer[0], + (unsigned int)prEventAccessRxStat->au4Buffer[1], + (unsigned int)prEventAccessRxStat->au4Buffer[65], + (unsigned int)prEventAccessRxStat->au4Buffer[22]); + + kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, + u4QueryInfoLen, WLAN_STATUS_SUCCESS); + } + +} + +#if CFG_SUPPORT_TX_BF +void nicCmdEventPfmuDataRead(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf) +{ + uint32_t u4QueryInfoLen; + struct GLUE_INFO *prGlueInfo; + union PFMU_DATA *prEventPfmuDataRead = NULL; + + ASSERT(prAdapter); + ASSERT(prCmdInfo); + ASSERT(pucEventBuf); + + /* 4 <2> Update information of OID */ + if (prCmdInfo->fgIsOid) { + prGlueInfo = prAdapter->prGlueInfo; + prEventPfmuDataRead = (union PFMU_DATA *) (pucEventBuf); + + u4QueryInfoLen = sizeof(union PFMU_DATA); + + g_rPfmuData = *prEventPfmuDataRead; + } + + DBGLOG(INIT, INFO, "=========== Before ===========\n"); + if (prEventPfmuDataRead != NULL) { + DBGLOG(INIT, INFO, "u2Phi11 = 0x%x\n", + prEventPfmuDataRead->rField.u2Phi11); + DBGLOG(INIT, INFO, "ucPsi21 = 0x%x\n", + prEventPfmuDataRead->rField.ucPsi21); + DBGLOG(INIT, INFO, "u2Phi21 = 0x%x\n", + prEventPfmuDataRead->rField.u2Phi21); + DBGLOG(INIT, INFO, "ucPsi31 = 0x%x\n", + prEventPfmuDataRead->rField.ucPsi31); + DBGLOG(INIT, INFO, "u2Phi31 = 0x%x\n", + prEventPfmuDataRead->rField.u2Phi31); + DBGLOG(INIT, INFO, "ucPsi41 = 0x%x\n", + prEventPfmuDataRead->rField.ucPsi41); + DBGLOG(INIT, INFO, "u2Phi22 = 0x%x\n", + prEventPfmuDataRead->rField.u2Phi22); + DBGLOG(INIT, INFO, "ucPsi32 = 0x%x\n", + prEventPfmuDataRead->rField.ucPsi32); + DBGLOG(INIT, INFO, "u2Phi32 = 0x%x\n", + prEventPfmuDataRead->rField.u2Phi32); + DBGLOG(INIT, INFO, "ucPsi42 = 0x%x\n", + prEventPfmuDataRead->rField.ucPsi42); + DBGLOG(INIT, INFO, "u2Phi33 = 0x%x\n", + prEventPfmuDataRead->rField.u2Phi33); + DBGLOG(INIT, INFO, "ucPsi43 = 0x%x\n", + prEventPfmuDataRead->rField.ucPsi43); + DBGLOG(INIT, INFO, "u2dSNR00 = 0x%x\n", + prEventPfmuDataRead->rField.u2dSNR00); + DBGLOG(INIT, INFO, "u2dSNR01 = 0x%x\n", + prEventPfmuDataRead->rField.u2dSNR01); + DBGLOG(INIT, INFO, "u2dSNR02 = 0x%x\n", + prEventPfmuDataRead->rField.u2dSNR02); + DBGLOG(INIT, INFO, "u2dSNR03 = 0x%x\n", + prEventPfmuDataRead->rField.u2dSNR03); + } +} + +void nicCmdEventPfmuTagRead(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf) +{ + uint32_t u4QueryInfoLen; + struct GLUE_INFO *prGlueInfo; + struct EVENT_PFMU_TAG_READ *prEventPfmuTagRead = NULL; + struct PARAM_CUSTOM_PFMU_TAG_READ_STRUCT *prPfumTagRead = + NULL; + + ASSERT(prAdapter); + ASSERT(prCmdInfo); + ASSERT(pucEventBuf); + + if (!pucEventBuf) { + DBGLOG(INIT, ERROR, "pucEventBuf is NULL.\n"); + return; + } + if (!prCmdInfo->pvInformationBuffer) { + DBGLOG(INIT, ERROR, + "prCmdInfo->pvInformationBuffer is NULL.\n"); + return; + } + /* 4 <2> Update information of OID */ + if (!prCmdInfo->fgIsOid) { + DBGLOG(INIT, ERROR, "cmd %u seq #%u not oid!", + prCmdInfo->ucCID, prCmdInfo->ucCmdSeqNum); + return; + } + prGlueInfo = prAdapter->prGlueInfo; + prEventPfmuTagRead = (struct EVENT_PFMU_TAG_READ *) ( + pucEventBuf); + + prPfumTagRead = (struct PARAM_CUSTOM_PFMU_TAG_READ_STRUCT *) + prCmdInfo->pvInformationBuffer; + + kalMemCopy(prPfumTagRead, prEventPfmuTagRead, + sizeof(struct EVENT_PFMU_TAG_READ)); + + u4QueryInfoLen = sizeof(union CMD_TXBF_ACTION); + + g_rPfmuTag1 = prPfumTagRead->ru4TxBfPFMUTag1; + g_rPfmuTag2 = prPfumTagRead->ru4TxBfPFMUTag2; + + kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, + u4QueryInfoLen, WLAN_STATUS_SUCCESS); + + DBGLOG(INIT, INFO, + "========================== (R)Tag1 info ==========================\n"); + + DBGLOG(INIT, INFO, + " Row data0 : %x, Row data1 : %x, Row data2 : %x, Row data3 : %x\n", + prEventPfmuTagRead->ru4TxBfPFMUTag1.au4RawData[0], + prEventPfmuTagRead->ru4TxBfPFMUTag1.au4RawData[1], + prEventPfmuTagRead->ru4TxBfPFMUTag1.au4RawData[2], + prEventPfmuTagRead->ru4TxBfPFMUTag1.au4RawData[3]); + DBGLOG(INIT, INFO, "ProfileID = %d Invalid status = %d\n", + prEventPfmuTagRead->ru4TxBfPFMUTag1.rField.ucProfileID, + prEventPfmuTagRead->ru4TxBfPFMUTag1.rField.ucInvalidProf); + DBGLOG(INIT, INFO, "0:iBF / 1:eBF = %d\n", + prEventPfmuTagRead->ru4TxBfPFMUTag1.rField.ucTxBf); + DBGLOG(INIT, INFO, "0:SU / 1:MU = %d\n", + prEventPfmuTagRead->ru4TxBfPFMUTag1.rField.ucSU_MU); + DBGLOG(INIT, INFO, "DBW(0/1/2/3 BW20/40/80/160NC) = %d\n", + prEventPfmuTagRead->ru4TxBfPFMUTag1.rField.ucDBW); + DBGLOG(INIT, INFO, "RMSD = %d\n", + prEventPfmuTagRead->ru4TxBfPFMUTag1.rField.ucRMSD); + DBGLOG(INIT, INFO, + "Nrow = %d, Ncol = %d, Ng = %d, LM = %d\n", + prEventPfmuTagRead->ru4TxBfPFMUTag1.rField.ucNrow, + prEventPfmuTagRead->ru4TxBfPFMUTag1.rField.ucNcol, + prEventPfmuTagRead->ru4TxBfPFMUTag1.rField.ucNgroup, + prEventPfmuTagRead->ru4TxBfPFMUTag1.rField.ucLM); + DBGLOG(INIT, INFO, + "Mem1(%d, %d), Mem2(%d, %d), Mem3(%d, %d), Mem4(%d, %d)\n", + prEventPfmuTagRead->ru4TxBfPFMUTag1.rField.ucMemAddr1ColIdx, + prEventPfmuTagRead->ru4TxBfPFMUTag1.rField.ucMemAddr1RowIdx, + prEventPfmuTagRead->ru4TxBfPFMUTag1.rField.ucMemAddr2ColIdx, + (prEventPfmuTagRead->ru4TxBfPFMUTag1. + rField.ucMemAddr2RowIdx | + (prEventPfmuTagRead->ru4TxBfPFMUTag1.rField.ucMemAddr2RowIdxMsb + << 5)), + prEventPfmuTagRead->ru4TxBfPFMUTag1.rField.ucMemAddr3ColIdx, + prEventPfmuTagRead->ru4TxBfPFMUTag1.rField.ucMemAddr3RowIdx, + prEventPfmuTagRead->ru4TxBfPFMUTag1.rField.ucMemAddr4ColIdx, + prEventPfmuTagRead->ru4TxBfPFMUTag1.rField.ucMemAddr4RowIdx); + DBGLOG(INIT, INFO, + "SNR STS0=0x%x, SNR STS1=0x%x, SNR STS2=0x%x, SNR STS3=0x%x\n", + prEventPfmuTagRead->ru4TxBfPFMUTag1.rField.ucSNR_STS0, + prEventPfmuTagRead->ru4TxBfPFMUTag1.rField.ucSNR_STS1, + prEventPfmuTagRead->ru4TxBfPFMUTag1.rField.ucSNR_STS2, + prEventPfmuTagRead->ru4TxBfPFMUTag1.rField.ucSNR_STS3); + DBGLOG(INIT, INFO, + "===============================================================\n"); + + DBGLOG(INIT, INFO, + "========================== (R)Tag2 info ==========================\n"); + DBGLOG(INIT, INFO, + " Row data0 : %x, Row data1 : %x, Row data2 : %x\n", + prEventPfmuTagRead->ru4TxBfPFMUTag2.au4RawData[0], + prEventPfmuTagRead->ru4TxBfPFMUTag2.au4RawData[1], + prEventPfmuTagRead->ru4TxBfPFMUTag2.au4RawData[2]); + DBGLOG(INIT, INFO, "Smart Ant Cfg = %d\n", + prEventPfmuTagRead->ru4TxBfPFMUTag2.rField.u2SmartAnt); + DBGLOG(INIT, INFO, "SE index = %d\n", + prEventPfmuTagRead->ru4TxBfPFMUTag2.rField.ucSEIdx); + DBGLOG(INIT, INFO, "RMSD Threshold = %d\n", + prEventPfmuTagRead->ru4TxBfPFMUTag2.rField.ucRMSDThd); + DBGLOG(INIT, INFO, + "MCS TH L1SS = %d, S1SS = %d, L2SS = %d, S2SS = %d\n" + "L3SS = %d, S3SS = %d\n", + prEventPfmuTagRead->ru4TxBfPFMUTag2.rField.ucMCSThL1SS, + prEventPfmuTagRead->ru4TxBfPFMUTag2.rField.ucMCSThS1SS, + prEventPfmuTagRead->ru4TxBfPFMUTag2.rField.ucMCSThL2SS, + prEventPfmuTagRead->ru4TxBfPFMUTag2.rField.ucMCSThS2SS, + prEventPfmuTagRead->ru4TxBfPFMUTag2.rField.ucMCSThL3SS, + prEventPfmuTagRead->ru4TxBfPFMUTag2.rField.ucMCSThS3SS); + DBGLOG(INIT, INFO, "iBF lifetime limit(unit:4ms) = 0x%x\n", + prEventPfmuTagRead->ru4TxBfPFMUTag2.rField.uciBfTimeOut); + DBGLOG(INIT, INFO, + "iBF desired DBW = %d\n 0/1/2/3 : BW20/40/80/160NC\n", + prEventPfmuTagRead->ru4TxBfPFMUTag2.rField.uciBfDBW); + DBGLOG(INIT, INFO, + "iBF desired Ncol = %d\n 0/1/2 : Ncol = 1 ~ 3\n", + prEventPfmuTagRead->ru4TxBfPFMUTag2.rField.uciBfNcol); + DBGLOG(INIT, INFO, + "iBF desired Nrow = %d\n 0/1/2/3 : Nrow = 1 ~ 4\n", + prEventPfmuTagRead->ru4TxBfPFMUTag2.rField.uciBfNrow); + DBGLOG(INIT, INFO, + "===============================================================\n"); + +} + +#endif /* CFG_SUPPORT_TX_BF */ +#if CFG_SUPPORT_MU_MIMO +void nicCmdEventGetQd(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf) +{ + uint32_t u4QueryInfoLen; + struct GLUE_INFO *prGlueInfo; + struct EVENT_HQA_GET_QD *prEventHqaGetQd; + uint32_t i; + + struct PARAM_CUSTOM_GET_QD_STRUCT *prGetQd = NULL; + + ASSERT(prAdapter); + ASSERT(prCmdInfo); + ASSERT(pucEventBuf); + if (!pucEventBuf) { + DBGLOG(INIT, ERROR, "pucEventBuf is NULL.\n"); + return; + } + if (!prCmdInfo->pvInformationBuffer) { + DBGLOG(INIT, ERROR, + "prCmdInfo->pvInformationBuffer is NULL.\n"); + return; + } + /* 4 <2> Update information of OID */ + if (!prCmdInfo->fgIsOid) { + DBGLOG(INIT, ERROR, "cmd %u seq #%u not oid!\n", + prCmdInfo->ucCID, prCmdInfo->ucCmdSeqNum); + return; + } + prGlueInfo = prAdapter->prGlueInfo; + prEventHqaGetQd = (struct EVENT_HQA_GET_QD *) (pucEventBuf); + + prGetQd = (struct PARAM_CUSTOM_GET_QD_STRUCT *) + prCmdInfo->pvInformationBuffer; + + kalMemCopy(prGetQd, prEventHqaGetQd, + sizeof(struct EVENT_HQA_GET_QD)); + + u4QueryInfoLen = sizeof(union CMD_MUMIMO_ACTION); + + /* g_rPfmuTag1 = prPfumTagRead->ru4TxBfPFMUTag1; */ + /* g_rPfmuTag2 = prPfumTagRead->ru4TxBfPFMUTag2; */ + + kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, + u4QueryInfoLen, WLAN_STATUS_SUCCESS); + + DBGLOG(INIT, INFO, " event id : %x\n", prGetQd->u4EventId); + for (i = 0; i < 14; i++) + DBGLOG(INIT, INFO, "au4RawData[%d]: %x\n", i, + prGetQd->au4RawData[i]); + +} + +void nicCmdEventGetCalcLq(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf) +{ + uint32_t u4QueryInfoLen; + struct GLUE_INFO *prGlueInfo; + struct EVENT_HQA_GET_MU_CALC_LQ *prEventHqaGetMuCalcLq; + uint32_t i, j; + + struct PARAM_CUSTOM_GET_MU_CALC_LQ_STRUCT *prGetMuCalcLq = + NULL; + + ASSERT(prAdapter); + ASSERT(prCmdInfo); + ASSERT(pucEventBuf); + if (!pucEventBuf) { + DBGLOG(INIT, ERROR, "pucEventBuf is NULL.\n"); + return; + } + if (!prCmdInfo->pvInformationBuffer) { + DBGLOG(INIT, ERROR, + "prCmdInfo->pvInformationBuffer is NULL.\n"); + return; + } + /* 4 <2> Update information of OID */ + if (!prCmdInfo->fgIsOid) { + DBGLOG(INIT, ERROR, "cmd %u seq #%u not oid!\n", + prCmdInfo->ucCID, prCmdInfo->ucCmdSeqNum); + return; + } + prGlueInfo = prAdapter->prGlueInfo; + prEventHqaGetMuCalcLq = (struct EVENT_HQA_GET_MU_CALC_LQ *) + (pucEventBuf); + + prGetMuCalcLq = (struct PARAM_CUSTOM_GET_MU_CALC_LQ_STRUCT + *) prCmdInfo->pvInformationBuffer; + + kalMemCopy(prGetMuCalcLq, prEventHqaGetMuCalcLq, + sizeof(struct EVENT_HQA_GET_MU_CALC_LQ)); + + u4QueryInfoLen = sizeof(union CMD_MUMIMO_ACTION); + + /* g_rPfmuTag1 = prPfumTagRead->ru4TxBfPFMUTag1; */ + /* g_rPfmuTag2 = prPfumTagRead->ru4TxBfPFMUTag2; */ + + kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, + u4QueryInfoLen, WLAN_STATUS_SUCCESS); + + + DBGLOG(INIT, INFO, " event id : %x\n", + prGetMuCalcLq->u4EventId); + for (i = 0; i < NUM_OF_USER; i++) + for (j = 0; j < NUM_OF_MODUL; j++) + DBGLOG(INIT, INFO, " lq_report[%d][%d]: %x\n", i, j, + prGetMuCalcLq->rEntry.lq_report[i][j]); + +} + +void nicCmdEventGetCalcInitMcs(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf) +{ + uint32_t u4QueryInfoLen; + struct GLUE_INFO *prGlueInfo; + struct EVENT_SHOW_GROUP_TBL_ENTRY *prEventShowGroupTblEntry + = NULL; + + struct PARAM_CUSTOM_SHOW_GROUP_TBL_ENTRY_STRUCT + *prShowGroupTbl; + + ASSERT(prAdapter); + ASSERT(prCmdInfo); + ASSERT(pucEventBuf); + if (!pucEventBuf) { + DBGLOG(INIT, ERROR, "pucEventBuf is NULL.\n"); + return; + } + if (!prCmdInfo->pvInformationBuffer) { + DBGLOG(INIT, ERROR, + "prCmdInfo->pvInformationBuffer is NULL.\n"); + return; + } + /* 4 <2> Update information of OID */ + if (!prCmdInfo->fgIsOid) { + DBGLOG(INIT, ERROR, "cmd %u seq #%u not oid!\n", + prCmdInfo->ucCID, prCmdInfo->ucCmdSeqNum); + return; + } + prGlueInfo = prAdapter->prGlueInfo; + prEventShowGroupTblEntry = (struct + EVENT_SHOW_GROUP_TBL_ENTRY *) (pucEventBuf); + + prShowGroupTbl = (struct + PARAM_CUSTOM_SHOW_GROUP_TBL_ENTRY_STRUCT *) + prCmdInfo->pvInformationBuffer; + + kalMemCopy(prShowGroupTbl, prEventShowGroupTblEntry, + sizeof(struct EVENT_SHOW_GROUP_TBL_ENTRY)); + + u4QueryInfoLen = sizeof(union CMD_MUMIMO_ACTION); + + /* g_rPfmuTag1 = prPfumTagRead->ru4TxBfPFMUTag1; */ + /* g_rPfmuTag2 = prPfumTagRead->ru4TxBfPFMUTag2; */ + + kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, + u4QueryInfoLen, WLAN_STATUS_SUCCESS); + + + DBGLOG(INIT, INFO, + "========================== (R)Group table info ==========================\n"); + DBGLOG(INIT, INFO, " event id : %x\n", + prEventShowGroupTblEntry->u4EventId); + DBGLOG(INIT, INFO, "index = %x numUser = %x\n", + prEventShowGroupTblEntry->index, + prEventShowGroupTblEntry->numUser); + DBGLOG(INIT, INFO, "BW = %x NS0/1/ = %x/%x\n", + prEventShowGroupTblEntry->BW, prEventShowGroupTblEntry->NS0, + prEventShowGroupTblEntry->NS1); + DBGLOG(INIT, INFO, "PFIDUser0/1 = %x/%x\n", + prEventShowGroupTblEntry->PFIDUser0, + prEventShowGroupTblEntry->PFIDUser1); + DBGLOG(INIT, INFO, + "fgIsShortGI = %x, fgIsUsed = %x, fgIsDisable = %x\n", + prEventShowGroupTblEntry->fgIsShortGI, + prEventShowGroupTblEntry->fgIsUsed, + prEventShowGroupTblEntry->fgIsDisable); + DBGLOG(INIT, INFO, "initMcsUser0/1 = %x/%x\n", + prEventShowGroupTblEntry->initMcsUser0, + prEventShowGroupTblEntry->initMcsUser1); + DBGLOG(INIT, INFO, "dMcsUser0: 0/1/ = %x/%x\n", + prEventShowGroupTblEntry->dMcsUser0, + prEventShowGroupTblEntry->dMcsUser1); + +} +#endif /* CFG_SUPPORT_MU_MIMO */ +#endif /* CFG_SUPPORT_QA_TOOL */ + +void nicCmdEventQuerySwCtrlRead(IN struct ADAPTER + *prAdapter, IN struct CMD_INFO *prCmdInfo, + IN uint8_t *pucEventBuf) +{ + uint32_t u4QueryInfoLen; + struct PARAM_CUSTOM_SW_CTRL_STRUCT *prSwCtrlInfo; + struct GLUE_INFO *prGlueInfo; + struct CMD_SW_DBG_CTRL *prCmdSwCtrl; + + ASSERT(prAdapter); + ASSERT(prCmdInfo); + ASSERT(pucEventBuf); + + /* 4 <2> Update information of OID */ + if (prCmdInfo->fgIsOid) { + prGlueInfo = prAdapter->prGlueInfo; + prCmdSwCtrl = (struct CMD_SW_DBG_CTRL *) (pucEventBuf); + + u4QueryInfoLen = sizeof(struct PARAM_CUSTOM_SW_CTRL_STRUCT); + + prSwCtrlInfo = (struct PARAM_CUSTOM_SW_CTRL_STRUCT *) + prCmdInfo->pvInformationBuffer; + prSwCtrlInfo->u4Id = prCmdSwCtrl->u4Id; + prSwCtrlInfo->u4Data = prCmdSwCtrl->u4Data; + + kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, + u4QueryInfoLen, WLAN_STATUS_SUCCESS); + } + +} + +void nicCmdEventQueryChipConfig(IN struct ADAPTER + *prAdapter, IN struct CMD_INFO *prCmdInfo, + IN uint8_t *pucEventBuf) +{ + uint32_t u4QueryInfoLen; + struct PARAM_CUSTOM_CHIP_CONFIG_STRUCT *prChipConfigInfo; + struct GLUE_INFO *prGlueInfo; + struct CMD_CHIP_CONFIG *prCmdChipConfig; + + ASSERT(prAdapter); + ASSERT(prCmdInfo); + ASSERT(pucEventBuf); + + /* 4 <2> Update information of OID */ + if (prCmdInfo->fgIsOid) { + prGlueInfo = prAdapter->prGlueInfo; + prCmdChipConfig = (struct CMD_CHIP_CONFIG *) (pucEventBuf); + + u4QueryInfoLen = sizeof(struct + PARAM_CUSTOM_CHIP_CONFIG_STRUCT); + + if (prCmdInfo->u4InformationBufferLength < sizeof( + struct PARAM_CUSTOM_CHIP_CONFIG_STRUCT)) { + DBGLOG(REQ, INFO, + "Chip config u4InformationBufferLength %u is not valid (event)\n", + prCmdInfo->u4InformationBufferLength); + } + prChipConfigInfo = (struct PARAM_CUSTOM_CHIP_CONFIG_STRUCT + *) prCmdInfo->pvInformationBuffer; + prChipConfigInfo->ucRespType = prCmdChipConfig->ucRespType; + prChipConfigInfo->u2MsgSize = prCmdChipConfig->u2MsgSize; + DBGLOG(REQ, INFO, "%s: RespTyep %u\n", __func__, + prChipConfigInfo->ucRespType); + DBGLOG(REQ, INFO, "%s: u2MsgSize %u\n", __func__, + prChipConfigInfo->u2MsgSize); + +#if 0 + if (prChipConfigInfo->u2MsgSize > CHIP_CONFIG_RESP_SIZE) { + DBGLOG(REQ, INFO, + "Chip config Msg Size %u is not valid (event)\n", + prChipConfigInfo->u2MsgSize); + prChipConfigInfo->u2MsgSize = CHIP_CONFIG_RESP_SIZE; + } +#endif + kalMemCopy(prChipConfigInfo->aucCmd, + prCmdChipConfig->aucCmd, prChipConfigInfo->u2MsgSize); + kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, + u4QueryInfoLen, WLAN_STATUS_SUCCESS); + } + +} + +void nicCmdEventSetCommon(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf) +{ + ASSERT(prAdapter); + ASSERT(prCmdInfo); + + if (prCmdInfo->fgIsOid) { + /* Update Set Information Length */ + kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, + prCmdInfo->u4InformationBufferLength, WLAN_STATUS_SUCCESS); + } + +} + +void nicCmdEventSetIpAddress(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf) +{ + uint32_t u4Count; + + ASSERT(prAdapter); + ASSERT(prCmdInfo); + + u4Count = (prCmdInfo->u4SetInfoLen - OFFSET_OF( + struct CMD_SET_NETWORK_ADDRESS_LIST, arNetAddress)) + / sizeof(struct CMD_IPV4_NETWORK_ADDRESS); + + if (prCmdInfo->fgIsOid) { + /* Update Set Information Length */ + kalOidComplete(prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, + OFFSET_OF(struct PARAM_NETWORK_ADDRESS_LIST, + arAddress) + u4Count * + (OFFSET_OF(struct PARAM_NETWORK_ADDRESS, aucAddress) + + sizeof(struct PARAM_NETWORK_ADDRESS_IP)), + WLAN_STATUS_SUCCESS); + } + +} + +void nicCmdEventQueryRfTestATInfo(IN struct ADAPTER + *prAdapter, IN struct CMD_INFO *prCmdInfo, + IN uint8_t *pucEventBuf) +{ + union EVENT_TEST_STATUS *prTestStatus, *prQueryBuffer; + struct GLUE_INFO *prGlueInfo; + uint32_t u4QueryInfoLen; + + ASSERT(prAdapter); + ASSERT(prCmdInfo); + + prTestStatus = (union EVENT_TEST_STATUS *) pucEventBuf; + + if (prCmdInfo->fgIsOid) { + prGlueInfo = prAdapter->prGlueInfo; + prQueryBuffer = (union EVENT_TEST_STATUS *) + prCmdInfo->pvInformationBuffer; + + /* Memory copy length is depended on upper-layer */ + kalMemCopy(prQueryBuffer, prTestStatus, + prCmdInfo->u4InformationBufferLength); + + u4QueryInfoLen = sizeof(union EVENT_TEST_STATUS); + + /* Update Query Information Length */ + kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, + u4QueryInfoLen, WLAN_STATUS_SUCCESS); + } + +} + +void nicCmdEventQueryLinkQuality(IN struct ADAPTER + *prAdapter, IN struct CMD_INFO *prCmdInfo, + IN uint8_t *pucEventBuf) +{ + struct EVENT_LINK_QUALITY *prLinkQuality; + struct PARAM_LINK_SPEED_EX *prLinkSpeed; + struct GLUE_INFO *prGlueInfo; + uint32_t u4QueryInfoLen; + uint32_t i; + + ASSERT(prAdapter); + ASSERT(prCmdInfo); + + prLinkQuality = (struct EVENT_LINK_QUALITY *) pucEventBuf; + prLinkSpeed = (struct PARAM_LINK_SPEED_EX *) + prCmdInfo->pvInformationBuffer; + + for (i = 0; i < BSSID_NUM; i++) { + prLinkSpeed->rLq[i].u2LinkSpeed + = prLinkQuality->rLq[i].u2LinkSpeed * 5000; + + /* ranged from (-128 ~ 30) in unit of dBm */ + prLinkSpeed->rLq[i].cRssi + = prLinkQuality->rLq[i].cRssi; + + DBGLOG(REQ, TRACE, + "ucBssIdx = %d, rate = %u, signal = %d\n", + i, prLinkSpeed->rLq[i].u2LinkSpeed, + prLinkSpeed->rLq[i].cRssi); + } + u4QueryInfoLen = sizeof(struct PARAM_LINK_SPEED_EX); + + + if (prCmdInfo->fgIsOid) { + prGlueInfo = prAdapter->prGlueInfo; + kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, + u4QueryInfoLen, WLAN_STATUS_SUCCESS); + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is in response of OID_GEN_LINK_SPEED query request + * + * @param prAdapter Pointer to the Adapter structure. + * @param prCmdInfo Pointer to the pending command info + * @param pucEventBuf + * + * @retval none + */ +/*----------------------------------------------------------------------------*/ +void nicCmdEventQueryLinkSpeed(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf) +{ + struct LINK_QUALITY *prLinkQuality; + struct GLUE_INFO *prGlueInfo; + uint32_t u4QueryInfoLen; + uint32_t *pu4LinkSpeed; + + ASSERT(prAdapter); + ASSERT(prCmdInfo); + + prLinkQuality = (struct LINK_QUALITY *) pucEventBuf; + + prGlueInfo = prAdapter->prGlueInfo; + pu4LinkSpeed = (uint32_t *) (prCmdInfo->pvInformationBuffer); + *pu4LinkSpeed = prLinkQuality->u2LinkSpeed * 5000; + + u4QueryInfoLen = sizeof(uint32_t); + + if (prCmdInfo->fgIsOid) + kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, + u4QueryInfoLen, WLAN_STATUS_SUCCESS); +} + +void nicCmdEventQueryLinkSpeedEx(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf) +{ + struct EVENT_LINK_QUALITY *prLinkQuality; + struct PARAM_LINK_SPEED_EX *pu4LinkSpeed; + struct GLUE_INFO *prGlueInfo; + uint32_t u4QueryInfoLen; + uint32_t i; + + ASSERT(prAdapter); + ASSERT(prCmdInfo); + + prLinkQuality = (struct EVENT_LINK_QUALITY *) pucEventBuf; + + if (prCmdInfo->fgIsOid) { + prGlueInfo = prAdapter->prGlueInfo; + pu4LinkSpeed = (struct PARAM_LINK_SPEED_EX *) ( + prCmdInfo->pvInformationBuffer); + + for (i = 0; i < BSSID_NUM; i++) { + pu4LinkSpeed->rLq[i].u2LinkSpeed + = prLinkQuality->rLq[i].u2LinkSpeed * 5000; + + /* ranged from (-128 ~ 30) in unit of dBm */ + pu4LinkSpeed->rLq[i].cRssi + = prLinkQuality->rLq[i].cRssi; + + DBGLOG(NIC, TRACE, + "ucBssIdx = %d, rate = %u, signal = %d\n", + i, + pu4LinkSpeed->rLq[i].u2LinkSpeed, + pu4LinkSpeed->rLq[i].cRssi); + } + + u4QueryInfoLen = sizeof(struct PARAM_LINK_SPEED_EX); + + kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, + u4QueryInfoLen, WLAN_STATUS_SUCCESS); + } +} + +void nicCmdEventQueryStatistics(IN struct ADAPTER + *prAdapter, IN struct CMD_INFO *prCmdInfo, + IN uint8_t *pucEventBuf) +{ + struct PARAM_802_11_STATISTICS_STRUCT *prStatistics; + struct EVENT_STATISTICS *prEventStatistics; + struct GLUE_INFO *prGlueInfo; + uint32_t u4QueryInfoLen; +#ifdef CFG_SUPPORT_LINK_QUALITY_MONITOR + struct WIFI_LINK_QUALITY_INFO *prLinkQualityInfo; + struct SCAN_INFO *prScanInfo; +#endif + + ASSERT(prAdapter); + ASSERT(prCmdInfo); + + prEventStatistics = (struct EVENT_STATISTICS *) pucEventBuf; + + prGlueInfo = prAdapter->prGlueInfo; + + u4QueryInfoLen = sizeof(struct + PARAM_802_11_STATISTICS_STRUCT); + prStatistics = (struct PARAM_802_11_STATISTICS_STRUCT *) + prCmdInfo->pvInformationBuffer; + + prStatistics->rTransmittedFragmentCount = + prEventStatistics->rTransmittedFragmentCount; + prStatistics->rMulticastTransmittedFrameCount = + prEventStatistics->rMulticastTransmittedFrameCount; + prStatistics->rFailedCount = + prEventStatistics->rFailedCount; + prStatistics->rRetryCount = prEventStatistics->rRetryCount; + prStatistics->rMultipleRetryCount = + prEventStatistics->rMultipleRetryCount; + prStatistics->rRTSSuccessCount = + prEventStatistics->rRTSSuccessCount; + prStatistics->rRTSFailureCount = + prEventStatistics->rRTSFailureCount; + prStatistics->rACKFailureCount = + prEventStatistics->rACKFailureCount; + prStatistics->rFrameDuplicateCount = + prEventStatistics->rFrameDuplicateCount; + prStatistics->rReceivedFragmentCount = + prEventStatistics->rReceivedFragmentCount; + prStatistics->rMulticastReceivedFrameCount = + prEventStatistics->rMulticastReceivedFrameCount; + prStatistics->rFCSErrorCount = + prEventStatistics->rFCSErrorCount; +#ifdef CFG_SUPPORT_LINK_QUALITY_MONITOR + prScanInfo = &(prAdapter->rWifiVar.rScanInfo); + prStatistics->rMdrdyCnt = prEventStatistics->rMdrdyCnt; + prStatistics->rChnlIdleCnt = prEventStatistics->rChnlIdleCnt; + prStatistics->u4HwAwakeDuration = + prEventStatistics->u4HwMacAwakeDuration; + + prLinkQualityInfo = + &(prAdapter->rLinkQualityInfo); + + prLinkQualityInfo->u8TxRetryCount = + prStatistics->rRetryCount.QuadPart; + + prLinkQualityInfo->u8TxRtsFailCount = + prStatistics->rRTSFailureCount.QuadPart; + prLinkQualityInfo->u8TxAckFailCount = + prStatistics->rACKFailureCount.QuadPart; + prLinkQualityInfo->u8TxFailCount = + prLinkQualityInfo->u8TxRtsFailCount + + prLinkQualityInfo->u8TxAckFailCount; + prLinkQualityInfo->u8TxTotalCount = + prStatistics->rTransmittedFragmentCount.QuadPart; + + prLinkQualityInfo->u8RxTotalCount = + prStatistics->rReceivedFragmentCount.QuadPart; + /* FW report is diff, driver count total */ + prLinkQualityInfo->u8RxErrCount += + prStatistics->rFCSErrorCount.QuadPart; + prLinkQualityInfo->u8MdrdyCount = + prStatistics->rMdrdyCnt.QuadPart; + prLinkQualityInfo->u8IdleSlotCount = + prStatistics->rChnlIdleCnt.QuadPart; + prLinkQualityInfo->u4HwMacAwakeDuration = + prStatistics->u4HwAwakeDuration; + if (prScanInfo->eCurrentState == SCAN_STATE_SCANNING) + prLinkQualityInfo->u2FlagScanning = 1; + else + prLinkQualityInfo->u2FlagScanning = 0; + + wlanFinishCollectingLinkQuality(prGlueInfo); + + DBGLOG(SW4, TRACE, + "EVENT_STATISTICS: rTransmittedFragmentCount.QuadPart:%lld, rRetryCount.QuadPart:%lld, rRTSFailureCount.QuadPart:%lld, rACKFailureCount.QuadPart:%lld, rReceivedFragmentCount.QuadPart:%lld, rFCSErrorCount.QuadPart:%lld, rChnlIdleCnt.QuadPart:%lld\n", + prEventStatistics->rTransmittedFragmentCount.QuadPart, + prEventStatistics->rRetryCount.QuadPart, + prEventStatistics->rRTSFailureCount.QuadPart, + prEventStatistics->rACKFailureCount.QuadPart, + prEventStatistics->rReceivedFragmentCount.QuadPart, + prEventStatistics->rFCSErrorCount.QuadPart, + prEventStatistics->rChnlIdleCnt.QuadPart + ); +#endif + + if (prCmdInfo->fgIsOid) + kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, + u4QueryInfoLen, WLAN_STATUS_SUCCESS); +} + +void nicCmdEventQueryBugReport(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf) +{ +#define BUG_REPORT_VERSION 1 + + struct EVENT_BUG_REPORT *prStatistics; + struct EVENT_BUG_REPORT *prEventStatistics; + struct GLUE_INFO *prGlueInfo; + uint32_t u4QueryInfoLen; + + ASSERT(prAdapter); + ASSERT(prCmdInfo); + + prEventStatistics = (struct EVENT_BUG_REPORT *) + pucEventBuf; + + if (prCmdInfo->fgIsOid) { + prGlueInfo = prAdapter->prGlueInfo; + u4QueryInfoLen = sizeof(struct EVENT_BUG_REPORT); + if (prEventStatistics->u4BugReportVersion == + BUG_REPORT_VERSION) { + prStatistics = (struct EVENT_BUG_REPORT *) + prCmdInfo->pvInformationBuffer; + kalMemCopy(prStatistics, + prEventStatistics, u4QueryInfoLen); + } + + kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, + u4QueryInfoLen, WLAN_STATUS_SUCCESS); + } +} + +void nicCmdEventEnterRfTest(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf) +{ + uint32_t u4Idx = 0; + + ASSERT(prAdapter); + ASSERT(prCmdInfo); + + /* [driver-land] */ + prAdapter->fgTestMode = TRUE; + + /* 0. always indicate disconnection */ + for (u4Idx = 0; u4Idx < KAL_AIS_NUM; u4Idx++) { + if (kalGetMediaStateIndicated( + prAdapter->prGlueInfo, + u4Idx) != + MEDIA_STATE_DISCONNECTED) + kalIndicateStatusAndComplete( + prAdapter->prGlueInfo, + WLAN_STATUS_MEDIA_DISCONNECT, + NULL, 0, u4Idx); + } + /* 1. Remove pending TX */ + nicTxRelease(prAdapter, TRUE); + + /* 1.1 clear pending Security / Management Frames */ + kalClearSecurityFrames(prAdapter->prGlueInfo); + kalClearMgmtFrames(prAdapter->prGlueInfo); + + /* 1.2 clear pending TX packet queued in glue layer */ + kalFlushPendingTxPackets(prAdapter->prGlueInfo); + + /* 2. Reset driver-domain FSMs */ + nicUninitMGMT(prAdapter); + + nicResetSystemService(prAdapter); + nicInitMGMT(prAdapter, NULL); + + /* Block til firmware completed entering into RF test mode */ + kalMsleep(500); + +#if defined(_HIF_SDIO) && 0 + /* 3. Disable Interrupt */ + HAL_INTR_DISABLE(prAdapter); + + /* 4. Block til firmware completed entering into RF test mode */ + kalMsleep(500); + while (1) { + uint32_t u4Value; + + HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value); + + if (u4Value & WCIR_WLAN_READY) { + break; + } else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE + || fgIsBusAccessFailed == TRUE) { + if (prCmdInfo->fgIsOid) { + /* Update Set Information Length */ + kalOidComplete(prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, + prCmdInfo->u4SetInfoLen, + WLAN_STATUS_NOT_SUPPORTED); + + } + return; + } + kalMsleep(10); + } + + /* 5. Clear Interrupt Status */ + { + uint32_t u4WHISR = 0; + uint16_t au2TxCount[16]; + + HAL_READ_INTR_STATUS(prAdapter, 4, (uint8_t *)&u4WHISR); + if (HAL_IS_TX_DONE_INTR(u4WHISR)) + HAL_READ_TX_RELEASED_COUNT(prAdapter, au2TxCount); + } + /* 6. Reset TX Counter */ + nicTxResetResource(prAdapter); + + /* 7. Re-enable Interrupt */ + HAL_INTR_ENABLE(prAdapter); +#endif + + /* 8. completion indication */ + if (prCmdInfo->fgIsOid) { + /* Update Set Information Length */ + kalOidComplete(prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, prCmdInfo->u4SetInfoLen, + WLAN_STATUS_SUCCESS); + } +#if CFG_SUPPORT_NVRAM + /* 9. load manufacture data */ + if (kalIsConfigurationExist(prAdapter->prGlueInfo) == TRUE) + wlanLoadManufactureData(prAdapter, + kalGetConfiguration(prAdapter->prGlueInfo)); + else + DBGLOG(REQ, WARN, "%s: load manufacture data fail\n", + __func__); +#endif + +} + +void nicCmdEventLeaveRfTest(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf) +{ + uint32_t u4Idx = 0; + + /* Block until firmware completed leaving from RF test mode */ + kalMsleep(500); + +#if defined(_HIF_SDIO) && 0 + uint32_t u4WHISR = 0; + uint16_t au2TxCount[16]; + uint32_t u4Value; + + /* 1. Disable Interrupt */ + HAL_INTR_DISABLE(prAdapter); + + /* 2. Block until firmware completed leaving from RF test mode */ + kalMsleep(500); + while (1) { + HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value); + + if (u4Value & WCIR_WLAN_READY) { + break; + } else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE + || fgIsBusAccessFailed == TRUE) { + if (prCmdInfo->fgIsOid) { + /* Update Set Information Length */ + kalOidComplete(prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, + prCmdInfo->u4SetInfoLen, + WLAN_STATUS_NOT_SUPPORTED); + + } + return; + } + kalMsleep(10); + } + /* 3. Clear Interrupt Status */ + HAL_READ_INTR_STATUS(prAdapter, 4, (uint8_t *)&u4WHISR); + if (HAL_IS_TX_DONE_INTR(u4WHISR)) + HAL_READ_TX_RELEASED_COUNT(prAdapter, au2TxCount); + /* 4. Reset TX Counter */ + nicTxResetResource(prAdapter); + + /* 5. Re-enable Interrupt */ + HAL_INTR_ENABLE(prAdapter); +#endif + + /* 6. set driver-land variable */ + prAdapter->fgTestMode = FALSE; + + /* 7. completion indication */ + if (prCmdInfo->fgIsOid) { + /* Update Set Information Length */ + kalOidComplete(prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, prCmdInfo->u4SetInfoLen, + WLAN_STATUS_SUCCESS); + } + + /* 8. Indicate as disconnected */ + for (u4Idx = 0; u4Idx < KAL_AIS_NUM; u4Idx++) { + if (kalGetMediaStateIndicated( + prAdapter->prGlueInfo, + u4Idx) != + MEDIA_STATE_DISCONNECTED) { + + kalIndicateStatusAndComplete( + prAdapter->prGlueInfo, + WLAN_STATUS_MEDIA_DISCONNECT, + NULL, 0, u4Idx); + + prAdapter->rWlanInfo.u4SysTime = + kalGetTimeTick(); + } + } +#if CFG_SUPPORT_NVRAM + /* 9. load manufacture data */ + if (kalIsConfigurationExist(prAdapter->prGlueInfo) == TRUE) + wlanLoadManufactureData(prAdapter, + kalGetConfiguration(prAdapter->prGlueInfo)); + else + DBGLOG(REQ, WARN, "%s: load manufacture data fail\n", + __func__); +#endif + + /* 10. Override network address */ + wlanUpdateNetworkAddress(prAdapter); + +} + +void nicCmdEventQueryMcastAddr(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf) +{ + uint32_t u4QueryInfoLen; + struct GLUE_INFO *prGlueInfo; + struct CMD_MAC_MCAST_ADDR *prEventMacMcastAddr; + + ASSERT(prAdapter); + ASSERT(prCmdInfo); + ASSERT(pucEventBuf); + + /* 4 <2> Update information of OID */ + if (prCmdInfo->fgIsOid) { + prGlueInfo = prAdapter->prGlueInfo; + prEventMacMcastAddr = (struct CMD_MAC_MCAST_ADDR *) ( + pucEventBuf); + + u4QueryInfoLen = prEventMacMcastAddr->u4NumOfGroupAddr * + MAC_ADDR_LEN; + + /* buffer length check */ + if (prCmdInfo->u4InformationBufferLength < u4QueryInfoLen) { + kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, + u4QueryInfoLen, WLAN_STATUS_BUFFER_TOO_SHORT); + } else { + kalMemCopy(prCmdInfo->pvInformationBuffer, + prEventMacMcastAddr->arAddress, + prEventMacMcastAddr->u4NumOfGroupAddr * + MAC_ADDR_LEN); + + kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, + u4QueryInfoLen, WLAN_STATUS_SUCCESS); + } + } +} + +void nicCmdEventQueryEepromRead(IN struct ADAPTER + *prAdapter, IN struct CMD_INFO *prCmdInfo, + IN uint8_t *pucEventBuf) +{ + uint32_t u4QueryInfoLen; + struct PARAM_CUSTOM_EEPROM_RW_STRUCT *prEepromRdInfo; + struct GLUE_INFO *prGlueInfo; + struct CMD_ACCESS_EEPROM *prEventAccessEeprom; + + ASSERT(prAdapter); + ASSERT(prCmdInfo); + ASSERT(pucEventBuf); + + /* 4 <2> Update information of OID */ + if (prCmdInfo->fgIsOid) { + prGlueInfo = prAdapter->prGlueInfo; + prEventAccessEeprom = (struct CMD_ACCESS_EEPROM *) ( + pucEventBuf); + + u4QueryInfoLen = sizeof(struct + PARAM_CUSTOM_EEPROM_RW_STRUCT); + + prEepromRdInfo = (struct PARAM_CUSTOM_EEPROM_RW_STRUCT *) + prCmdInfo->pvInformationBuffer; + prEepromRdInfo->info.rEeprom.ucEepromIndex = (uint8_t) ( + prEventAccessEeprom->u2Offset); + prEepromRdInfo->info.rEeprom.u2EepromData = + prEventAccessEeprom->u2Data; + + kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, + u4QueryInfoLen, WLAN_STATUS_SUCCESS); + } + +} + +void nicCmdEventSetMediaStreamMode(IN struct ADAPTER + *prAdapter, IN struct CMD_INFO *prCmdInfo, + IN uint8_t *pucEventBuf) +{ + struct PARAM_MEDIA_STREAMING_INDICATION + rParamMediaStreamIndication; + + ASSERT(prAdapter); + ASSERT(prCmdInfo); + + if (prCmdInfo->fgIsOid) { + /* Update Set Information Length */ + kalOidComplete(prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, prCmdInfo->u4SetInfoLen, + WLAN_STATUS_SUCCESS); + } + + rParamMediaStreamIndication.rStatus.eStatusType = + ENUM_STATUS_TYPE_MEDIA_STREAM_MODE; + rParamMediaStreamIndication.eMediaStreamMode = + prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode == 0 ? + ENUM_MEDIA_STREAM_OFF : ENUM_MEDIA_STREAM_ON; + + kalIndicateStatusAndComplete(prAdapter->prGlueInfo, + WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, + (void *)&rParamMediaStreamIndication, + sizeof(struct PARAM_MEDIA_STREAMING_INDICATION), + AIS_DEFAULT_INDEX); +} + +void nicCmdEventSetStopSchedScan(IN struct ADAPTER + *prAdapter, IN struct CMD_INFO *prCmdInfo, + IN uint8_t *pucEventBuf) +{ + /* + * DBGLOG(SCN, INFO, "--->nicCmdEventSetStopSchedScan\n" )); + */ + ASSERT(prAdapter); + ASSERT(prCmdInfo); + /* + * DBGLOG(SCN, INFO, "<--kalSchedScanStopped\n" ); + */ + if (prCmdInfo->fgIsOid) { + /* Update Set Information Length */ + kalOidComplete(prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, + prCmdInfo->u4InformationBufferLength, + WLAN_STATUS_SUCCESS); + } + + DBGLOG(SCN, INFO, + "nicCmdEventSetStopSchedScan OID done, release lock and send event to uplayer\n"); + /* Due to dead lock issue, need to release the IO + * control before calling kernel APIs + */ + kalSchedScanStopped(prAdapter->prGlueInfo, + !prCmdInfo->fgIsOid); + +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called when command by OID/ioctl has been timeout + * + * @param prAdapter Pointer to the Adapter structure. + * @param prCmdInfo Pointer to the command information + * + * @return TRUE + * FALSE + */ +/*----------------------------------------------------------------------------*/ +void nicOidCmdTimeoutCommon(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo) +{ + ASSERT(prAdapter); + + if (prCmdInfo->fgIsOid) + kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, + 0, WLAN_STATUS_FAILURE); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is a generic command timeout handler + * + * @param pfnOidHandler Pointer to the OID handler + * + * @return none + */ +/*----------------------------------------------------------------------------*/ +void nicCmdTimeoutCommon(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo) +{ + ASSERT(prAdapter); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called when command for entering RF test has + * failed sending due to timeout (highly possibly by firmware crash) + * + * @param prAdapter Pointer to the Adapter structure. + * @param prCmdInfo Pointer to the command information + * + * @return none + * + */ +/*----------------------------------------------------------------------------*/ +void nicOidCmdEnterRFTestTimeout(IN struct ADAPTER + *prAdapter, IN struct CMD_INFO *prCmdInfo) +{ + ASSERT(prAdapter); + + /* 1. Remove pending TX frames */ + nicTxRelease(prAdapter, TRUE); + + /* 1.1 clear pending Security / Management Frames */ + kalClearSecurityFrames(prAdapter->prGlueInfo); + kalClearMgmtFrames(prAdapter->prGlueInfo); + + /* 1.2 clear pending TX packet queued in glue layer */ + kalFlushPendingTxPackets(prAdapter->prGlueInfo); + + /* 2. indicate for OID failure */ + kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, + 0, WLAN_STATUS_FAILURE); +} + +#if CFG_SUPPORT_QA_TOOL +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called when received dump memory event packet. + * transfer the memory data to the IQ format data and write into file + * + * @param prIQAry Pointer to the array store I or Q data. + * prDataLen The return data length - bytes + * u4IQ 0: get I data + * 1 : get Q data + * + * @return -1: open file error + * + */ +/*----------------------------------------------------------------------------*/ +int32_t GetIQData(struct ADAPTER *prAdapter, + int32_t **prIQAry, uint32_t *prDataLen, uint32_t u4IQ, + uint32_t u4GetWf1) +{ + uint8_t aucPath[50]; /* the path for iq data dump out */ + uint8_t aucData[50]; /* iq data in string format */ + uint32_t i = 0, j = 0, count = 0; + int32_t ret = -1; + int32_t rv; + struct file *file = NULL; + + *prIQAry = prAdapter->rIcapInfo.au4IQData; + + /* sprintf(aucPath, "/pattern.txt"); // CSD's Pattern */ + kalSprintf(aucPath, "/tmp/dump_out_%05hu_WF%u.txt", + prAdapter->rIcapInfo.u2DumpIndex - 1, u4GetWf1); + if (kalCheckPath(aucPath) == -1) { + kalSnprintf(aucPath, sizeof(aucPath), + "/data/dump_out_%05hu_WF%u.txt", + prAdapter->rIcapInfo.u2DumpIndex - 1, u4GetWf1); + } + + DBGLOG(INIT, INFO, + "iCap Read Dump File dump_out_%05hu_WF%u.txt\n", + prAdapter->rIcapInfo.u2DumpIndex - 1, u4GetWf1); + + file = kalFileOpen(aucPath, O_RDONLY, 0); + + if ((file != NULL) && !IS_ERR(file)) { + /* read 1K data per time */ + for (i = 0; i < RTN_IQ_DATA_LEN / sizeof(uint32_t); + i++, prAdapter->rIcapInfo.au4Offset[u4GetWf1][u4IQ] += + IQ_FILE_LINE_OFFSET) { + if (kalFileRead(file, + prAdapter->rIcapInfo.au4Offset[u4GetWf1][u4IQ], + aucData, IQ_FILE_IQ_STR_LEN) == 0) + break; + + count = 0; + + for (j = 0; j < 8; j++) { + if (aucData[j] != ' ') + aucData[count++] = aucData[j]; + } + + aucData[count] = '\0'; + + /* transfer data format (string to int) */ + rv = kalStrtoint(aucData, 0, + &prAdapter->rIcapInfo.au4IQData[i]); + } + *prDataLen = i * sizeof(uint32_t); + kalFileClose(file); + ret = 0; + } + + DBGLOG(INIT, INFO, + "MT6632 : QA_AGENT GetIQData prDataLen = %d\n", *prDataLen); + DBGLOG(INIT, INFO, "MT6632 : QA_AGENT GetIQData i = %d\n", + i); + + return ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called when received dump memory event packet. + * transfer the memory data to the IQ format data and write into file + * + * @param prEventDumpMem Pointer to the event dump memory structure. + * + * @return 0: SUCCESS, -1: FAIL + * + */ +/*----------------------------------------------------------------------------*/ + +uint32_t nicTsfRawData2IqFmt(struct EVENT_DUMP_MEM + *prEventDumpMem, struct ICAP_INFO_T *prIcap) +{ + static uint8_t + aucPathWF0[40]; /* the path for iq data dump out */ + static uint8_t + aucPathWF1[40]; /* the path for iq data dump out */ + static uint8_t + aucPathRAWWF0[40]; /* the path for iq data dump out */ + static uint8_t + aucPathRAWWF1[40]; /* the path for iq data dump out */ + uint8_t *pucDataWF0 = NULL; /* the data write into file */ + uint8_t *pucDataWF1 = NULL; /* the data write into file */ + uint8_t *pucDataRAWWF0 = + NULL; /* the data write into file */ + uint8_t *pucDataRAWWF1 = + NULL; /* the data write into file */ + uint32_t u4SrcOffset; /* record the buffer offset */ + uint32_t u4FmtLen = 0; /* bus format length */ + uint32_t u4CpyLen = 0; + uint32_t u4RemainByte; + uint32_t u4DataWBufSize = 150; + uint32_t u4DataRAWWBufSize = 150; + uint32_t u4DataWLenF0 = 0; + uint32_t u4DataWLenF1 = 0; + uint32_t u4DataRAWWLenF0 = 0; + uint32_t u4DataRAWWLenF1 = 0; + + u_int8_t fgAppend; + int32_t u4Iqc160WF0Q0, u4Iqc160WF1I1; + + static uint8_t + ucDstOffset; /* for alignment. bcs we send 2KB data per packet,*/ + /*the data will not align in 12 bytes case. */ + static uint32_t u4CurTimeTick; + + static union ICAP_BUS_FMT icapBusData; + uint32_t *ptr; + + pucDataWF0 = kmalloc(u4DataWBufSize, GFP_KERNEL); + pucDataWF1 = kmalloc(u4DataWBufSize, GFP_KERNEL); + pucDataRAWWF0 = kmalloc(u4DataRAWWBufSize, GFP_KERNEL); + pucDataRAWWF1 = kmalloc(u4DataRAWWBufSize, GFP_KERNEL); + + + if ((!pucDataWF0) || (!pucDataWF1) || (!pucDataRAWWF0) + || (!pucDataRAWWF1)) { + DBGLOG(INIT, ERROR, "kmalloc failed.\n"); + kfree(pucDataWF0); + kfree(pucDataWF1); + kfree(pucDataRAWWF0); + kfree(pucDataRAWWF1); + ASSERT(-1); + return -1; + } + + fgAppend = TRUE; + if (prEventDumpMem->ucFragNum == 1) { + + u4CurTimeTick = kalGetTimeTick(); + /* Store memory dump into sdcard, + * path /sdcard/dump__ + * _.hex + */ +#if defined(LINUX) + + /* if blbist mkdir undre /data/blbist, + * the dump files wouls put on it + */ + kalScnprintf(aucPathWF0, sizeof(aucPathWF0), + "/tmp/dump_out_%05hu_WF0.txt", prIcap->u2DumpIndex); + kalScnprintf(aucPathWF1, sizeof(aucPathWF1), + "/tmp/dump_out_%05hu_WF1.txt", prIcap->u2DumpIndex); + if (kalCheckPath(aucPathWF0) == -1) { + kalMemSet(aucPathWF0, 0x00, sizeof(aucPathWF0)); + kalScnprintf(aucPathWF0, sizeof(aucPathWF0), + "/data/dump_out_%05hu_WF0.txt", + prIcap->u2DumpIndex); + } else + kalTrunkPath(aucPathWF0); + + if (kalCheckPath(aucPathWF1) == -1) { + kalMemSet(aucPathWF1, 0x00, sizeof(aucPathWF1)); + kalScnprintf(aucPathWF1, sizeof(aucPathWF1), + "/data/dump_out_%05hu_WF1.txt", + prIcap->u2DumpIndex); + } else + kalTrunkPath(aucPathWF1); + + kalScnprintf(aucPathRAWWF0, sizeof(aucPathRAWWF0), + "/dump_RAW_%hu_WF0.txt", prIcap->u2DumpIndex); + kalScnprintf(aucPathRAWWF1, sizeof(aucPathRAWWF1), + "/dump_RAW_%hu_WF1.txt", prIcap->u2DumpIndex); + if (kalCheckPath(aucPathRAWWF0) == -1) { + kalMemSet(aucPathRAWWF0, 0x00, sizeof(aucPathRAWWF0)); + kalScnprintf(aucPathRAWWF0, sizeof(aucPathRAWWF0), + "/data/dump_RAW_%05hu_WF0.txt", + prIcap->u2DumpIndex); + } else + kalTrunkPath(aucPathRAWWF0); + + if (kalCheckPath(aucPathRAWWF1) == -1) { + kalMemSet(aucPathRAWWF1, 0x00, sizeof(aucPathRAWWF1)); + kalScnprintf(aucPathRAWWF1, sizeof(aucPathRAWWF1), + "/data/dump_RAW_%05hu_WF1.txt", + prIcap->u2DumpIndex); + } else + kalTrunkPath(aucPathRAWWF1); + +#else + kal_sprintf_ddk(aucPathWF0, sizeof(aucPathWF0), + u4CurTimeTick, prEventDumpMem->u4Address, + prEventDumpMem->u4Length + + prEventDumpMem->u4RemainLength); + kal_sprintf_ddk(aucPathWF1, sizeof(aucPathWF1), + u4CurTimeTick, prEventDumpMem->u4Address, + prEventDumpMem->u4Length + + prEventDumpMem->u4RemainLength); +#endif + /* fgAppend = FALSE; */ + } + + ptr = (uint32_t *)(&prEventDumpMem->aucBuffer[0]); + + for (u4SrcOffset = 0, + u4RemainByte = prEventDumpMem->u4Length; u4RemainByte > 0; + ) { + u4FmtLen = + (prEventDumpMem->eIcapContent + == ICAP_CONTENT_SPECTRUM) ? + sizeof(struct SPECTRUM_BUS_FMT) : sizeof(union + ICAP_BUS_FMT); + /* 4 bytes : 12 bytes */ + u4CpyLen = (u4RemainByte - u4FmtLen >= 0) ? u4FmtLen : + u4RemainByte; + + if ((ucDstOffset + u4CpyLen) > sizeof(icapBusData)) { + DBGLOG(INIT, ERROR, + "ucDstOffset(%u) + u4CpyLen(%u) exceed bound of icapBusData\n", + ucDstOffset, u4CpyLen); + kfree(pucDataWF0); + kfree(pucDataWF1); + kfree(pucDataRAWWF0); + kfree(pucDataRAWWF1); + ASSERT(-1); + return -1; + } + memcpy((uint8_t *)&icapBusData + ucDstOffset, + &prEventDumpMem->aucBuffer[0] + u4SrcOffset, u4CpyLen); +#if 0 + if (prEventDumpMem->eIcapContent == ICAP_CONTENT_ADC) { + sprintf(aucDataWF0, "%8d,%8d\n", + icapBusData.rAdcBusData.u4Dcoc0I, + icapBusData.rAdcBusData.u4Dcoc0Q); + sprintf(aucDataWF1, "%8d,%8d\n", + icapBusData.rAdcBusData.u4Dcoc1I, + icapBusData.rAdcBusData.u4Dcoc1Q); + } +#endif + if (prEventDumpMem->eIcapContent == ICAP_CONTENT_FIIQ || + prEventDumpMem->eIcapContent == ICAP_CONTENT_FDIQ) { + u4DataWLenF0 = kalScnprintf(pucDataWF0, u4DataWBufSize, + "%8d,%8d\n", + icapBusData.rIqcBusData.u4Iqc0I, + icapBusData.rIqcBusData.u4Iqc0Q); + u4DataWLenF1 = kalScnprintf(pucDataWF1, u4DataWBufSize, + "%8d,%8d\n", + icapBusData.rIqcBusData.u4Iqc1I, + icapBusData.rIqcBusData.u4Iqc1Q); + } else if (prEventDumpMem->eIcapContent - 1000 == + ICAP_CONTENT_FIIQ + || prEventDumpMem->eIcapContent - 1000 == + ICAP_CONTENT_FDIQ) { + u4Iqc160WF0Q0 = + icapBusData.rIqc160BusData.u4Iqc0Q0P1 | + (icapBusData.rIqc160BusData.u4Iqc0Q0P2 << 8); + u4Iqc160WF1I1 = + icapBusData.rIqc160BusData.u4Iqc1I1P1 | + (icapBusData.rIqc160BusData.u4Iqc1I1P2 << 4); + + u4DataWLenF0 = kalScnprintf(pucDataWF0, u4DataWBufSize, + "%8d,%8d\n%8d,%8d\n", + icapBusData.rIqc160BusData.u4Iqc0I0, + u4Iqc160WF0Q0, + icapBusData.rIqc160BusData.u4Iqc0I1, + icapBusData.rIqc160BusData.u4Iqc0Q1); + + u4DataWLenF1 = kalScnprintf(pucDataWF1, u4DataWBufSize, + "%8d,%8d\n%8d,%8d\n", + icapBusData.rIqc160BusData.u4Iqc1I0, + icapBusData.rIqc160BusData.u4Iqc1Q0, + u4Iqc160WF1I1, + icapBusData.rIqc160BusData.u4Iqc1Q1); + + } else if (prEventDumpMem->eIcapContent == + ICAP_CONTENT_SPECTRUM) { + u4DataWLenF0 = kalScnprintf(pucDataWF0, u4DataWBufSize, + "%8d,%8d\n", + icapBusData.rSpectrumBusData.u4DcocI, + icapBusData.rSpectrumBusData.u4DcocQ); + } else if (prEventDumpMem->eIcapContent == + ICAP_CONTENT_ADC) { + u4DataWLenF0 = kalScnprintf(pucDataWF0, u4DataWBufSize, + "%8d,%8d\n%8d,%8d\n%8d,%8d\n%8d,%8d\n%8d,%8d\n%8d,%8d\n", + icapBusData.rPackedAdcBusData.u4AdcI0T0, + icapBusData.rPackedAdcBusData.u4AdcQ0T0, + icapBusData.rPackedAdcBusData.u4AdcI0T1, + icapBusData.rPackedAdcBusData.u4AdcQ0T1, + icapBusData.rPackedAdcBusData.u4AdcI0T2, + icapBusData.rPackedAdcBusData.u4AdcQ0T2, + icapBusData.rPackedAdcBusData.u4AdcI0T3, + icapBusData.rPackedAdcBusData.u4AdcQ0T3, + icapBusData.rPackedAdcBusData.u4AdcI0T4, + icapBusData.rPackedAdcBusData.u4AdcQ0T4, + icapBusData.rPackedAdcBusData.u4AdcI0T5, + icapBusData.rPackedAdcBusData.u4AdcQ0T5); + + u4DataWLenF1 = kalScnprintf(pucDataWF1, u4DataWBufSize, + "%8d,%8d\n%8d,%8d\n%8d,%8d\n%8d,%8d\n%8d,%8d\n%8d,%8d\n", + icapBusData.rPackedAdcBusData.u4AdcI1T0, + icapBusData.rPackedAdcBusData.u4AdcQ1T0, + icapBusData.rPackedAdcBusData.u4AdcI1T1, + icapBusData.rPackedAdcBusData.u4AdcQ1T1, + icapBusData.rPackedAdcBusData.u4AdcI1T2, + icapBusData.rPackedAdcBusData.u4AdcQ1T2, + icapBusData.rPackedAdcBusData.u4AdcI1T3, + icapBusData.rPackedAdcBusData.u4AdcQ1T3, + icapBusData.rPackedAdcBusData.u4AdcI1T4, + icapBusData.rPackedAdcBusData.u4AdcQ1T4, + icapBusData.rPackedAdcBusData.u4AdcI1T5, + icapBusData.rPackedAdcBusData.u4AdcQ1T5); + } else if (prEventDumpMem->eIcapContent - 2000 == + ICAP_CONTENT_ADC) { + u4DataWLenF0 = kalScnprintf(pucDataWF0, u4DataWBufSize, + "%8d,%8d\n%8d,%8d\n%8d,%8d\n", + icapBusData.rPackedAdcBusData.u4AdcI0T0, + icapBusData.rPackedAdcBusData.u4AdcQ0T0, + icapBusData.rPackedAdcBusData.u4AdcI0T1, + icapBusData.rPackedAdcBusData.u4AdcQ0T1, + icapBusData.rPackedAdcBusData.u4AdcI0T2, + icapBusData.rPackedAdcBusData.u4AdcQ0T2); + + u4DataWLenF1 = kalScnprintf(pucDataWF1, u4DataWBufSize, + "%8d,%8d\n%8d,%8d\n%8d,%8d\n", + icapBusData.rPackedAdcBusData.u4AdcI1T0, + icapBusData.rPackedAdcBusData.u4AdcQ1T0, + icapBusData.rPackedAdcBusData.u4AdcI1T1, + icapBusData.rPackedAdcBusData.u4AdcQ1T1, + icapBusData.rPackedAdcBusData.u4AdcI1T2, + icapBusData.rPackedAdcBusData.u4AdcQ1T2); + } else if (prEventDumpMem->eIcapContent == + ICAP_CONTENT_TOAE) { + /* actually, this is DCOC. we take TOAE as DCOC */ + u4DataWLenF0 = kalScnprintf(pucDataWF0, u4DataWBufSize, + "%8d,%8d\n", + icapBusData.rAdcBusData.u4Dcoc0I, + icapBusData.rAdcBusData.u4Dcoc0Q); + u4DataWLenF1 = kalScnprintf(pucDataWF1, u4DataWBufSize, + "%8d,%8d\n", + icapBusData.rAdcBusData.u4Dcoc1I, + icapBusData.rAdcBusData.u4Dcoc1Q); + } + if (u4CpyLen == + u4FmtLen) { /* the data format is complete */ + kalWriteToFile(aucPathWF0, fgAppend, pucDataWF0, + u4DataWLenF0); + kalWriteToFile(aucPathWF1, fgAppend, pucDataWF1, + u4DataWLenF1); + } + ptr = (uint32_t *)(&prEventDumpMem->aucBuffer[0] + + u4SrcOffset); + u4DataRAWWLenF0 = kalScnprintf(pucDataRAWWF0, u4DataWBufSize, + "%08x%08x%08x\n", + *(ptr + 2), *(ptr + 1), *ptr); + kalWriteToFile(aucPathRAWWF0, fgAppend, pucDataRAWWF0, + u4DataRAWWLenF0); + kalWriteToFile(aucPathRAWWF1, fgAppend, pucDataRAWWF1, + u4DataRAWWLenF1); + + u4RemainByte -= u4CpyLen; + u4SrcOffset += u4CpyLen; /* shift offset */ + /* only use ucDstOffset at first packet for align 2KB */ + ucDstOffset = 0; + } + /* if this is a last packet, we can't transfer the remain data. + * bcs we can't guarantee the data is complete align data format + */ + /* the data format is complete */ + if (u4CpyLen != u4FmtLen) { + /* not align 2KB, keep the data + * and next packet data will append it + */ + ucDstOffset = u4CpyLen; + } + + kfree(pucDataWF0); + kfree(pucDataWF1); + kfree(pucDataRAWWF0); + kfree(pucDataRAWWF1); + + if (u4RemainByte < 0) { + ASSERT(-1); + return -1; + } + + return 0; +} +#endif /* CFG_SUPPORT_QA_TOOL */ + +#if CFG_SUPPORT_CAL_RESULT_BACKUP_TO_HOST +void nicCmdEventQueryCalBackupV2(IN struct ADAPTER + *prAdapter, IN struct CMD_INFO *prCmdInfo, + IN uint8_t *pucEventBuf) +{ + struct PARAM_CAL_BACKUP_STRUCT_V2 *prCalBackupDataV2Info; + struct CMD_CAL_BACKUP_STRUCT_V2 *prEventCalBackupDataV2; + uint32_t u4QueryInfoLen, u4QueryInfo, u4TempAddress; + struct GLUE_INFO *prGlueInfo; + + DBGLOG(RFTEST, INFO, "%s\n", __func__); + + ASSERT(prAdapter); + ASSERT(prCmdInfo); + ASSERT(pucEventBuf); + + + prGlueInfo = prAdapter->prGlueInfo; + prEventCalBackupDataV2 = (struct CMD_CAL_BACKUP_STRUCT_V2 *) + (pucEventBuf); + + u4QueryInfoLen = sizeof(struct CMD_CAL_BACKUP_STRUCT_V2); + + prCalBackupDataV2Info = (struct PARAM_CAL_BACKUP_STRUCT_V2 + *) prCmdInfo->pvInformationBuffer; +#if 0 + DBGLOG(RFTEST, INFO, + "============ Receive a Cal Data EVENT (Info) ============\n"); + DBGLOG(RFTEST, INFO, "Reason = %d\n", + prEventCalBackupDataV2->ucReason); + DBGLOG(RFTEST, INFO, "Action = %d\n", + prEventCalBackupDataV2->ucAction); + DBGLOG(RFTEST, INFO, "NeedResp = %d\n", + prEventCalBackupDataV2->ucNeedResp); + DBGLOG(RFTEST, INFO, "FragNum = %d\n", + prEventCalBackupDataV2->ucFragNum); + DBGLOG(RFTEST, INFO, "RomRam = %d\n", + prEventCalBackupDataV2->ucRomRam); + DBGLOG(RFTEST, INFO, "ThermalValue = %d\n", + prEventCalBackupDataV2->u4ThermalValue); + DBGLOG(RFTEST, INFO, "Address = 0x%08x\n", + prEventCalBackupDataV2->u4Address); + DBGLOG(RFTEST, INFO, "Length = %d\n", + prEventCalBackupDataV2->u4Length); + DBGLOG(RFTEST, INFO, "RemainLength = %d\n", + prEventCalBackupDataV2->u4RemainLength); + DBGLOG(RFTEST, INFO, + "=========================================================\n"); +#endif + + if (prEventCalBackupDataV2->ucReason == 0 + && prEventCalBackupDataV2->ucAction == 0) { + DBGLOG(RFTEST, INFO, + "Received an EVENT for Query Thermal Temp.\n"); + prCalBackupDataV2Info->u4ThermalValue = + prEventCalBackupDataV2->u4ThermalValue; + g_rBackupCalDataAllV2.u4ThermalInfo = + prEventCalBackupDataV2->u4ThermalValue; + kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, + u4QueryInfoLen, WLAN_STATUS_SUCCESS); + } else if (prEventCalBackupDataV2->ucReason == 0 + && prEventCalBackupDataV2->ucAction == 1) { + DBGLOG(RFTEST, INFO, + "Received an EVENT for Query Total Cal Data Length.\n"); + prCalBackupDataV2Info->u4Length = + prEventCalBackupDataV2->u4Length; + + if (prEventCalBackupDataV2->ucRomRam == 0) + g_rBackupCalDataAllV2.u4ValidRomCalDataLength = + prEventCalBackupDataV2->u4Length; + else if (prEventCalBackupDataV2->ucRomRam == 1) + g_rBackupCalDataAllV2.u4ValidRamCalDataLength = + prEventCalBackupDataV2->u4Length; + + kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, + u4QueryInfoLen, WLAN_STATUS_SUCCESS); + } else if (prEventCalBackupDataV2->ucReason == 2 + && prEventCalBackupDataV2->ucAction == 4) { + DBGLOG(RFTEST, INFO, + "Received an EVENT for Query All Cal (%s) Data. FragNum = %d\n", + prCalBackupDataV2Info->ucRomRam == 0 ? "ROM" : "RAM", + prEventCalBackupDataV2->ucFragNum); + prCalBackupDataV2Info->u4Address = + prEventCalBackupDataV2->u4Address; + prCalBackupDataV2Info->u4Length = + prEventCalBackupDataV2->u4Length; + prCalBackupDataV2Info->u4RemainLength = + prEventCalBackupDataV2->u4RemainLength; + prCalBackupDataV2Info->ucFragNum = + prEventCalBackupDataV2->ucFragNum; + + /* Copy Cal Data From FW to Driver Array */ + if (prEventCalBackupDataV2->ucRomRam == 0) { + u4TempAddress = prEventCalBackupDataV2->u4Address; + kalMemCopy( + (uint8_t *)(g_rBackupCalDataAllV2.au4RomCalData) + + u4TempAddress, + (uint8_t *)(prEventCalBackupDataV2->au4Buffer), + prEventCalBackupDataV2->u4Length); + } else if (prEventCalBackupDataV2->ucRomRam == 1) { + u4TempAddress = prEventCalBackupDataV2->u4Address; + kalMemCopy( + (uint8_t *)(g_rBackupCalDataAllV2.au4RamCalData) + + u4TempAddress, + (uint8_t *)(prEventCalBackupDataV2->au4Buffer), + prEventCalBackupDataV2->u4Length); + } + + if (prEventCalBackupDataV2->u4Address == 0xFFFFFFFF) { + DBGLOG(RFTEST, INFO, + "RLM CMD : Address Error!!!!!!!!!!!\n"); + } else if (prEventCalBackupDataV2->u4RemainLength == 0 + && prEventCalBackupDataV2->ucRomRam == 1) { + DBGLOG(RFTEST, INFO, + "RLM CMD : Get Cal Data from FW (%s). Finish!!!!!!!!!!!\n", + prCalBackupDataV2Info->ucRomRam == 0 ? "ROM" : "RAM"); + } else if (prEventCalBackupDataV2->u4RemainLength == 0 + && prEventCalBackupDataV2->ucRomRam == 0) { + DBGLOG(RFTEST, INFO, + "RLM CMD : Get Cal Data from FW (%s). Finish!!!!!!!!!!!\n", + prCalBackupDataV2Info->ucRomRam == 0 ? "ROM" : "RAM"); + prCalBackupDataV2Info->ucFragNum = 0; + prCalBackupDataV2Info->ucRomRam = 1; + prCalBackupDataV2Info->u4ThermalValue = 0; + prCalBackupDataV2Info->u4Address = 0; + prCalBackupDataV2Info->u4Length = 0; + prCalBackupDataV2Info->u4RemainLength = 0; + DBGLOG(RFTEST, INFO, + "RLM CMD : Get Cal Data from FW (%s). Start!!!!!!!!!!!!!!!!\n", + prCalBackupDataV2Info->ucRomRam == 0 ? "ROM" : "RAM"); + DBGLOG(RFTEST, INFO, "Thermal Temp = %d\n", + g_rBackupCalDataAllV2.u4ThermalInfo); + wlanoidQueryCalBackupV2(prAdapter, + prCalBackupDataV2Info, + sizeof(struct PARAM_CAL_BACKUP_STRUCT_V2), + &u4QueryInfo); + } else { + wlanoidSendCalBackupV2Cmd(prAdapter, + prCmdInfo->pvInformationBuffer, + prCmdInfo->u4InformationBufferLength); + } + } else if (prEventCalBackupDataV2->ucReason == 3 + && prEventCalBackupDataV2->ucAction == 5) { + DBGLOG(RFTEST, INFO, + "Received an EVENT for Send All Cal Data. FragNum = %d\n", + prEventCalBackupDataV2->ucFragNum); + prCalBackupDataV2Info->u4Address = + prEventCalBackupDataV2->u4Address; + prCalBackupDataV2Info->u4Length = + prEventCalBackupDataV2->u4Length; + prCalBackupDataV2Info->u4RemainLength = + prEventCalBackupDataV2->u4RemainLength; + prCalBackupDataV2Info->ucFragNum = + prEventCalBackupDataV2->ucFragNum; + + if (prEventCalBackupDataV2->u4RemainLength == 0 + || prEventCalBackupDataV2->u4Address == 0xFFFFFFFF) { + kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, + u4QueryInfoLen, WLAN_STATUS_SUCCESS); + } else { + wlanoidSendCalBackupV2Cmd(prAdapter, + prCmdInfo->pvInformationBuffer, + prCmdInfo->u4InformationBufferLength); + } + } else { + kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, + u4QueryInfoLen, WLAN_STATUS_SUCCESS); + } + +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called to handle dump burst event + * + * @param prAdapter Pointer to the Adapter structure. + * @param prCmdInfo Pointer to the command information + * @param pucEventBuf Pointer to event buffer + * + * @return none + * + */ +/*----------------------------------------------------------------------------*/ +void nicEventQueryMemDump(IN struct ADAPTER *prAdapter, + IN uint8_t *pucEventBuf) +{ + struct EVENT_DUMP_MEM *prEventDumpMem; + static uint8_t aucPath[256]; + static uint8_t aucPath_done[300]; + static uint32_t u4CurTimeTick; + + ASSERT(prAdapter); + ASSERT(pucEventBuf); + + kalSprintf(aucPath, "/dump_%05hu.hex", + prAdapter->rIcapInfo.u2DumpIndex); + + prEventDumpMem = (struct EVENT_DUMP_MEM *) (pucEventBuf); + + if (kalCheckPath(aucPath) == -1) { + kalMemSet(aucPath, 0x00, 256); + kalSprintf(aucPath, "/data/dump_%05hu.hex", + prAdapter->rIcapInfo.u2DumpIndex); + } + + if (prEventDumpMem->ucFragNum == 1) { + /* Store memory dump into sdcard, + * path /sdcard/dump__ + * _.hex + */ + u4CurTimeTick = kalGetTimeTick(); +#if defined(LINUX) + + /* if blbist mkdir undre /data/blbist, + * the dump files wouls put on it + */ + kalSprintf(aucPath, "/dump_%05hu.hex", + prAdapter->rIcapInfo.u2DumpIndex); + if (kalCheckPath(aucPath) == -1) { + kalMemSet(aucPath, 0x00, 256); + kalSprintf(aucPath, "/data/dump_%05hu.hex", + prAdapter->rIcapInfo.u2DumpIndex); + } +#else + kal_sprintf_ddk(aucPath, sizeof(aucPath), + u4CurTimeTick, + prEventDumpMem->u4Address, + prEventDumpMem->u4Length + + prEventDumpMem->u4RemainLength); +#endif + kalWriteToFile(aucPath, FALSE, + &prEventDumpMem->aucBuffer[0], + prEventDumpMem->u4Length); + } else { + /* Append current memory dump to the hex file */ + kalWriteToFile(aucPath, TRUE, &prEventDumpMem->aucBuffer[0], + prEventDumpMem->u4Length); + } +#if CFG_SUPPORT_QA_TOOL + nicTsfRawData2IqFmt(prEventDumpMem, &prAdapter->rIcapInfo); +#endif /* CFG_SUPPORT_QA_TOOL */ + DBGLOG(INIT, INFO, + "iCap : ==> (u4RemainLength = %x, u4Address=%x )\n", + prEventDumpMem->u4RemainLength, + prEventDumpMem->u4Address); + + if (prEventDumpMem->u4RemainLength == 0 + || prEventDumpMem->u4Address == 0xFFFFFFFF) { + + /* The request is finished or firmware response a error */ + /* Reply time tick to iwpriv */ + + prAdapter->rIcapInfo.eIcapState = ICAP_STATE_FW_DUMP_DONE; + + kalSprintf(aucPath_done, "/file_dump_done.txt"); + if (kalCheckPath(aucPath_done) == -1) { + kalMemSet(aucPath_done, 0x00, 256); + kalSprintf(aucPath_done, "/data/file_dump_done.txt"); + } + DBGLOG(INIT, INFO, ": ==> gen done_file\n"); + kalWriteToFile(aucPath_done, FALSE, aucPath_done, + sizeof(aucPath_done)); +#if CFG_SUPPORT_QA_TOOL + prAdapter->rIcapInfo.au4Offset[0][0] = 0; + prAdapter->rIcapInfo.au4Offset[0][1] = 9; + prAdapter->rIcapInfo.au4Offset[1][0] = 0; + prAdapter->rIcapInfo.au4Offset[1][1] = 9; +#endif /* CFG_SUPPORT_QA_TOOL */ + + prAdapter->rIcapInfo.u2DumpIndex++; + + } + +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called when command for memory dump has + * replied a event. + * + * @param prAdapter Pointer to the Adapter structure. + * @param prCmdInfo Pointer to the command information + * @param pucEventBuf Pointer to event buffer + * + * @return none + * + */ +/*----------------------------------------------------------------------------*/ +void nicCmdEventQueryMemDump(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf) +{ + uint32_t u4QueryInfoLen; + struct GLUE_INFO *prGlueInfo; + struct EVENT_DUMP_MEM *prEventDumpMem; + static uint8_t aucPath[256]; + /* static UINT_8 aucPath_done[300]; */ + static uint32_t u4CurTimeTick; + + ASSERT(prAdapter); + ASSERT(prCmdInfo); + ASSERT(pucEventBuf); + + /* 4 <2> Update information of OID */ + if (1) { + prGlueInfo = prAdapter->prGlueInfo; + prEventDumpMem = (struct EVENT_DUMP_MEM *) (pucEventBuf); + + u4QueryInfoLen = sizeof(struct PARAM_CUSTOM_MEM_DUMP_STRUCT + *); + + if (prEventDumpMem->ucFragNum == 1) { + /* Store memory dump into sdcard, + * path /sdcard/dump__ + * _.hex + */ + u4CurTimeTick = kalGetTimeTick(); +#if defined(LINUX) + + /* PeiHsuan add for avoiding out of memory 20160801 */ + if (prAdapter->rIcapInfo.u2DumpIndex >= 20) + prAdapter->rIcapInfo.u2DumpIndex = 0; + + /* if blbist mkdir undre /data/blbist, + * the dump files wouls put on it + */ + sprintf(aucPath, "/dump_%05hu.hex", + prAdapter->rIcapInfo.u2DumpIndex); + if (kalCheckPath(aucPath) == -1) { + kalMemSet(aucPath, 0x00, 256); + sprintf(aucPath, "/data/dump_%05hu.hex", + prAdapter->rIcapInfo.u2DumpIndex); + } else + kalTrunkPath(aucPath); + + DBGLOG(INIT, INFO, + "iCap Create New Dump File dump_%05hu.hex\n", + prAdapter->rIcapInfo.u2DumpIndex); +#else + kal_sprintf_ddk(aucPath, sizeof(aucPath), + u4CurTimeTick, + prEventDumpMem->u4Address, + prEventDumpMem->u4Length + + prEventDumpMem->u4RemainLength); + /* strcpy(aucPath, "dump.hex"); */ +#endif + kalWriteToFile(aucPath, FALSE, + &prEventDumpMem->aucBuffer[0], + prEventDumpMem->u4Length); + } else { + /* Append current memory dump to the hex file */ + kalWriteToFile(aucPath, TRUE, + &prEventDumpMem->aucBuffer[0], + prEventDumpMem->u4Length); + } +#if CFG_SUPPORT_QA_TOOL + nicTsfRawData2IqFmt(prEventDumpMem, &prAdapter->rIcapInfo); +#endif /* CFG_SUPPORT_QA_TOOL */ + if (prEventDumpMem->u4RemainLength == 0 + || prEventDumpMem->u4Address == 0xFFFFFFFF) { + /* The request is finished or firmware response + * a error + */ + /* Reply time tick to iwpriv */ + if (prCmdInfo->fgIsOid) { + + /* the oid would be complete only in oid-trigger + * mode, that is no need to if the event-trigger + */ + if (prAdapter->rIcapInfo.eIcapState + == ICAP_STATE_FW_DUMPING) { + *((uint32_t *) + prCmdInfo->pvInformationBuffer) + = u4CurTimeTick; + kalOidComplete(prGlueInfo, + prCmdInfo->fgSetQuery, + u4QueryInfoLen, + WLAN_STATUS_SUCCESS); + } + } + + prAdapter->rIcapInfo.eIcapState + = ICAP_STATE_FW_DUMP_DONE; + +#if defined(LINUX) + + prAdapter->rIcapInfo.u2DumpIndex++; + +#else + kal_sprintf_done_ddk(aucPath_done, + sizeof(aucPath_done)); + kalWriteToFile(aucPath_done, FALSE, aucPath_done, + sizeof(aucPath_done)); +#endif + } else { +#if defined(LINUX) + +#else /* 2013/05/26 fw would try to send the buffer successfully */ + /* The memory dump request is not finished, + * Send next command + */ + wlanSendMemDumpCmd(prAdapter, + prCmdInfo->pvInformationBuffer, + prCmdInfo->u4InformationBufferLength); +#endif + } + } + + return; + +} + +#if CFG_SUPPORT_BATCH_SCAN +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called when event for SUPPORT_BATCH_SCAN + * + * @param prAdapter Pointer to the Adapter structure. + * @param prCmdInfo Pointer to the command information + * @param pucEventBuf Pointer to the event buffer + * + * @return none + * + */ +/*----------------------------------------------------------------------------*/ +void nicCmdEventBatchScanResult(IN struct ADAPTER + *prAdapter, IN struct CMD_INFO *prCmdInfo, + IN uint8_t *pucEventBuf) +{ + uint32_t u4QueryInfoLen; + struct EVENT_BATCH_RESULT *prEventBatchResult; + struct GLUE_INFO *prGlueInfo; + + DBGLOG(SCN, TRACE, "nicCmdEventBatchScanResult"); + + ASSERT(prAdapter); + ASSERT(prCmdInfo); + ASSERT(pucEventBuf); + + /* 4 <2> Update information of OID */ + if (prCmdInfo->fgIsOid) { + prGlueInfo = prAdapter->prGlueInfo; + prEventBatchResult = (struct EVENT_BATCH_RESULT *) + pucEventBuf; + + u4QueryInfoLen = sizeof(struct EVENT_BATCH_RESULT); + kalMemCopy(prCmdInfo->pvInformationBuffer, + prEventBatchResult, sizeof(struct EVENT_BATCH_RESULT)); + + kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, + u4QueryInfoLen, WLAN_STATUS_SUCCESS); + } + +} +#endif + +void nicEventHifCtrlv2(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ +#if defined(_HIF_USB) + struct EVENT_HIF_CTRL *prEventHifCtrl; + struct GL_HIF_INFO *prHifInfo; + + prEventHifCtrl = (struct EVENT_HIF_CTRL *) ( + prEvent->aucBuffer); + + if (prEventHifCtrl->ucHifSuspend) { + /* suspend event, change state to PRE_SUSPEND_DONE */ + if (prEventHifCtrl->ucHifTxTrafficStatus == + ENUM_HIF_TRAFFIC_IDLE && + prEventHifCtrl->ucHifRxTrafficStatus == + ENUM_HIF_TRAFFIC_IDLE) { /* success */ + halUSBPreSuspendDone(prAdapter, + NULL, prEvent->aucBuffer); + } else { + /* busy */ + /* invalid */ + halUSBPreSuspendTimeout(prAdapter, NULL); + } + } else { + /* if USB get resume event, change to LINK_UP */ + prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + glUsbSetState(prHifInfo, USB_STATE_LINK_UP); + } +#endif +} + +void nicEventHifCtrl(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ +#if defined(_HIF_USB) + struct EVENT_HIF_CTRL *prEventHifCtrl; + struct BUS_INFO *prBusInfo; + + prBusInfo = prAdapter->chip_info->bus_info; + prEventHifCtrl = (struct EVENT_HIF_CTRL *) ( + prEvent->aucBuffer); + + DBGLOG(HAL, INFO, "%s: EVENT_ID_HIF_CTRL\n", __func__); + DBGLOG(HAL, INFO, "prEventHifCtrl->ucHifType = %hhu suspend %d\n", + prEventHifCtrl->ucHifType, prEventHifCtrl->ucHifSuspend); + DBGLOG(HAL, INFO, + "prEventHifCtrl->ucHifTxTrafficStatus, prEventHifCtrl->ucHifRxTrafficStatus = %hhu, %hhu\n", + prEventHifCtrl->ucHifTxTrafficStatus, + prEventHifCtrl->ucHifRxTrafficStatus); + + if (prBusInfo->u4SuspendVer == SUSPEND_V2) { + /* Suspend V2, control state of HIF here */ + nicEventHifCtrlv2(prAdapter, prEvent); + } else { + if (prEventHifCtrl->ucHifTxTrafficStatus == + ENUM_HIF_TRAFFIC_IDLE && + prEventHifCtrl->ucHifRxTrafficStatus == + ENUM_HIF_TRAFFIC_IDLE) { /* success */ + halUSBPreSuspendDone(prAdapter, + NULL, prEvent->aucBuffer); + } else { + /* busy */ + /* invalid */ + halUSBPreSuspendTimeout(prAdapter, NULL); + } + } +#endif +} + +#if CFG_SUPPORT_BUILD_DATE_CODE +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called when event for build date code information + * has been retrieved + * + * @param prAdapter Pointer to the Adapter structure. + * @param prCmdInfo Pointer to the command information + * @param pucEventBuf Pointer to the event buffer + * + * @return none + * + */ +/*----------------------------------------------------------------------------*/ +void nicCmdEventBuildDateCode(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf) +{ + uint32_t u4QueryInfoLen; + struct EVENT_BUILD_DATE_CODE *prEvent; + struct GLUE_INFO *prGlueInfo; + + ASSERT(prAdapter); + ASSERT(prCmdInfo); + ASSERT(pucEventBuf); + + /* 4 <2> Update information of OID */ + if (prCmdInfo->fgIsOid) { + prGlueInfo = prAdapter->prGlueInfo; + prEvent = (struct EVENT_BUILD_DATE_CODE *) pucEventBuf; + + u4QueryInfoLen = sizeof(uint8_t) * 16; + kalMemCopy(prCmdInfo->pvInformationBuffer, + prEvent->aucDateCode, sizeof(uint8_t) * 16); + + kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, + u4QueryInfoLen, WLAN_STATUS_SUCCESS); + } + +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called when event for query STA link status + * has been retrieved + * + * @param prAdapter Pointer to the Adapter structure. + * @param prCmdInfo Pointer to the command information + * @param pucEventBuf Pointer to the event buffer + * + * @return none + * + */ +/*----------------------------------------------------------------------------*/ +void nicCmdEventQueryStaStatistics(IN struct ADAPTER + *prAdapter, IN struct CMD_INFO *prCmdInfo, + IN uint8_t *pucEventBuf) +{ + uint32_t u4QueryInfoLen; + struct EVENT_STA_STATISTICS *prEvent; + struct GLUE_INFO *prGlueInfo; + struct PARAM_GET_STA_STATISTICS *prStaStatistics; + enum ENUM_WMM_ACI eAci; + struct STA_RECORD *prStaRec; + uint8_t ucDbdcIdx, ucIdx; +#ifdef CFG_SUPPORT_LINK_QUALITY_MONITOR + struct WIFI_LINK_QUALITY_INFO *prLinkQualityInfo; +#endif + + ASSERT(prAdapter); + ASSERT(prCmdInfo); + ASSERT(pucEventBuf); + ASSERT(prCmdInfo->pvInformationBuffer); + + prGlueInfo = prAdapter->prGlueInfo; + prEvent = (struct EVENT_STA_STATISTICS *) pucEventBuf; + prStaStatistics = (struct PARAM_GET_STA_STATISTICS *) + prCmdInfo->pvInformationBuffer; + + u4QueryInfoLen = sizeof(struct PARAM_GET_STA_STATISTICS); + + /* Statistics from FW is valid */ + if (prEvent->u4Flags & BIT(0)) { + prStaStatistics->ucPer = prEvent->ucPer; + prStaStatistics->ucRcpi = prEvent->ucRcpi; + prStaStatistics->u4PhyMode = prEvent->u4PhyMode; + prStaStatistics->u2LinkSpeed = prEvent->u2LinkSpeed; + + prStaStatistics->u4TxFailCount = prEvent->u4TxFailCount; + prStaStatistics->u4TxLifeTimeoutCount = + prEvent->u4TxLifeTimeoutCount; + prStaStatistics->u4TransmitCount = + prEvent->u4TransmitCount; + prStaStatistics->u4TransmitFailCount = + prEvent->u4TransmitFailCount; + prStaStatistics->u4Rate1TxCnt = prEvent->u4Rate1TxCnt; + prStaStatistics->u4Rate1FailCnt = + prEvent->u4Rate1FailCnt; + + prStaStatistics->ucTemperature = prEvent->ucTemperature; + prStaStatistics->ucSkipAr = prEvent->ucSkipAr; + prStaStatistics->ucArTableIdx = prEvent->ucArTableIdx; + prStaStatistics->ucRateEntryIdx = + prEvent->ucRateEntryIdx; + prStaStatistics->ucRateEntryIdxPrev = + prEvent->ucRateEntryIdxPrev; + prStaStatistics->ucTxSgiDetectPassCnt = + prEvent->ucTxSgiDetectPassCnt; + prStaStatistics->ucAvePer = prEvent->ucAvePer; +#if (CFG_SUPPORT_RA_GEN == 0) + kalMemCopy(prStaStatistics->aucArRatePer, + prEvent->aucArRatePer, + sizeof(prEvent->aucArRatePer)); + kalMemCopy(prStaStatistics->aucRateEntryIndex, + prEvent->aucRateEntryIndex, + sizeof(prEvent->aucRateEntryIndex)); +#else + prStaStatistics->u4AggRangeCtrl_0 = + prEvent->u4AggRangeCtrl_0; + prStaStatistics->u4AggRangeCtrl_1 = + prEvent->u4AggRangeCtrl_1; + prStaStatistics->ucRangeType = prEvent->ucRangeType; +#if (CFG_SUPPORT_CONNAC2X == 1) + prStaStatistics->u4AggRangeCtrl_2 = + prEvent->u4AggRangeCtrl_2; + prStaStatistics->u4AggRangeCtrl_3 = + prEvent->u4AggRangeCtrl_3; +#endif + kalMemCopy(prStaStatistics->aucReserved5, + prEvent->aucReserved5, + sizeof(prEvent->aucReserved5)); +#endif + prStaStatistics->ucArStateCurr = prEvent->ucArStateCurr; + prStaStatistics->ucArStatePrev = prEvent->ucArStatePrev; + prStaStatistics->ucArActionType = + prEvent->ucArActionType; + prStaStatistics->ucHighestRateCnt = + prEvent->ucHighestRateCnt; + prStaStatistics->ucLowestRateCnt = + prEvent->ucLowestRateCnt; + prStaStatistics->u2TrainUp = prEvent->u2TrainUp; + prStaStatistics->u2TrainDown = prEvent->u2TrainDown; + kalMemCopy(&prStaStatistics->rTxVector, + &prEvent->rTxVector, + sizeof(prEvent->rTxVector)); + kalMemCopy(&prStaStatistics->rMibInfo, + &prEvent->rMibInfo, + sizeof(prEvent->rMibInfo)); + for (ucDbdcIdx = 0; ucDbdcIdx < ENUM_BAND_NUM; ucDbdcIdx++) { + g_arMibInfo[ucDbdcIdx].u4RxMpduCnt += + prStaStatistics->rMibInfo[ucDbdcIdx]. + u4RxMpduCnt; + g_arMibInfo[ucDbdcIdx].u4FcsError += + prStaStatistics->rMibInfo[ucDbdcIdx]. + u4FcsError; + g_arMibInfo[ucDbdcIdx].u4RxFifoFull += + prStaStatistics->rMibInfo[ucDbdcIdx]. + u4RxFifoFull; + g_arMibInfo[ucDbdcIdx].u4AmpduTxSfCnt += + prStaStatistics->rMibInfo[ucDbdcIdx]. + u4AmpduTxSfCnt; + g_arMibInfo[ucDbdcIdx].u4AmpduTxAckSfCnt += + prStaStatistics->rMibInfo[ucDbdcIdx]. + u4AmpduTxAckSfCnt; + + for (ucIdx = 0; ucIdx <= AGG_RANGE_SEL_NUM; ucIdx++) + g_arMibInfo[ucDbdcIdx].au2TxRangeAmpduCnt[ucIdx] + += prStaStatistics->rMibInfo[ucDbdcIdx]. + au2TxRangeAmpduCnt[ucIdx]; + } + + prStaStatistics->fgIsForceTxStream = + prEvent->fgIsForceTxStream; + prStaStatistics->fgIsForceSeOff = + prEvent->fgIsForceSeOff; +#if (CFG_SUPPORT_RA_GEN == 0) + kalMemCopy(prStaStatistics->aucReserved6, + prEvent->aucReserved6, + sizeof(prEvent->aucReserved6)); +#else + prStaStatistics->u2RaRunningCnt = + prEvent->u2RaRunningCnt; + prStaStatistics->ucRaStatus = prEvent->ucRaStatus; + prStaStatistics->ucFlag = prEvent->ucFlag; + kalMemCopy(&prStaStatistics->aucTxQuality, + &prEvent->aucTxQuality, + sizeof(prEvent->aucTxQuality)); + prStaStatistics->ucTxRateUpPenalty = + prEvent->ucTxRateUpPenalty; + prStaStatistics->ucLowTrafficMode = + prEvent->ucLowTrafficMode; + prStaStatistics->ucLowTrafficCount = + prEvent->ucLowTrafficCount; + prStaStatistics->ucLowTrafficDashBoard = + prEvent->ucLowTrafficDashBoard; + prStaStatistics->ucDynamicSGIState = + prEvent->ucDynamicSGIState; + prStaStatistics->ucDynamicSGIScore = + prEvent->ucDynamicSGIScore; + prStaStatistics->ucDynamicBWState = + prEvent->ucDynamicBWState; + prStaStatistics->ucDynamicGband256QAMState = + prEvent->ucDynamicGband256QAMState; + prStaStatistics->ucVhtNonSpRateState = + prEvent->ucVhtNonSpRateState; +#endif + prStaRec = cnmGetStaRecByIndex(prAdapter, + prEvent->ucStaRecIdx); + + if (prStaRec) { + /*link layer statistics */ + for (eAci = 0; eAci < WMM_AC_INDEX_NUM; + eAci++) { + prStaStatistics->arLinkStatistics[eAci]. + u4TxFailMsdu = + prEvent->arLinkStatistics[eAci]. + u4TxFailMsdu; + prStaStatistics->arLinkStatistics[eAci]. + u4TxRetryMsdu = + prEvent->arLinkStatistics[eAci]. + u4TxRetryMsdu; + + /*for dump bss statistics */ + prStaRec->arLinkStatistics[eAci]. + u4TxFailMsdu = + prEvent->arLinkStatistics[eAci]. + u4TxFailMsdu; + prStaRec->arLinkStatistics[eAci]. + u4TxRetryMsdu = + prEvent->arLinkStatistics[eAci]. + u4TxRetryMsdu; + } + } + if (prEvent->u4TxCount) { + uint32_t u4TxDoneAirTimeMs = + USEC_TO_MSEC(prEvent->u4TxDoneAirTime * + 32); + + prStaStatistics->u4TxAverageAirTime = + (u4TxDoneAirTimeMs / + prEvent->u4TxCount); + } else { + prStaStatistics->u4TxAverageAirTime = 0; + } + +#if CFG_ENABLE_PER_STA_STATISTICS_LOG +#if CFG_SUPPORT_WFD + /* dump statistics for WFD */ + if (prAdapter->rWifiVar + .rWfdConfigureSettings.ucWfdEnable == 1) { + uint32_t u4LinkScore = 0; + uint32_t u4TotalError = + prStaStatistics->u4TxFailCount + + prStaStatistics->u4TxLifeTimeoutCount; + uint32_t u4TxExceedThresholdCount = + prStaStatistics->u4TxExceedThresholdCount; + uint32_t u4TxTotalCount = + prStaStatistics->u4TxTotalCount; + + /* Calcute Link Score + * u4LinkScore 10~100 , + * ExceedThreshold ratio 0~90 only + * u4LinkScore 0~9 + * Drop packet ratio 0~9 and + * all packets exceed threshold + */ + if (u4TxTotalCount) { + if (u4TxExceedThresholdCount <= u4TxTotalCount) + u4LinkScore = (90 - + ((u4TxExceedThresholdCount * 90) + / u4TxTotalCount)); + else + u4LinkScore = 0; + } else + u4LinkScore = 90; + + u4LinkScore += 10; + if (u4LinkScore == 10) { + if (u4TotalError <= u4TxTotalCount) + u4LinkScore = (10 - + ((u4TotalError * 10) / + u4TxTotalCount)); + else + u4LinkScore = 0; + } + + if (u4LinkScore > 100) + u4LinkScore = 100; + + prAdapter->rWifiVar.rWfdConfigureSettings.u4LinkScore + = u4LinkScore; + + log_dbg(P2P, INFO, + "[%u][%u] link_score=%u, rssi=%u, rate=%u, threshold_cnt=%u, fail_cnt=%u\n", + prEvent->ucNetworkTypeIndex, + prEvent->ucStaRecIdx, + u4LinkScore, + prStaStatistics->ucRcpi, + prStaStatistics->u2LinkSpeed, + prStaStatistics->u4TxExceedThresholdCount, + prStaStatistics->u4TxFailCount); + log_dbg(P2P, INFO, "timeout_cnt=%u, apt=%u, aat=%u, total_cnt=%u\n", + prStaStatistics->u4TxLifeTimeoutCount, + prStaStatistics->u4TxAverageProcessTime, + prStaStatistics->u4TxAverageAirTime, + prStaStatistics->u4TxTotalCount); + } +#endif +#endif +#ifdef CFG_SUPPORT_LINK_QUALITY_MONITOR + prLinkQualityInfo = &(prAdapter->rLinkQualityInfo); + prLinkQualityInfo->u4CurTxRate = prEvent->u2LinkSpeed * 5; +#endif + } + + if (prCmdInfo->fgIsOid) + kalOidComplete(prGlueInfo, + prCmdInfo->fgSetQuery, + u4QueryInfoLen, + WLAN_STATUS_SUCCESS); + +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is called when event for query LTE safe channels + * has been retrieved + * + * @param prAdapter Pointer to the Adapter structure. + * @param prCmdInfo Pointer to the command information + * @param pucEventBuf Pointer to the event buffer + * + * @return none + */ +/*----------------------------------------------------------------------------*/ +void nicCmdEventQueryLteSafeChn(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, + IN uint8_t *pucEventBuf) +{ + struct EVENT_LTE_SAFE_CHN *prEvent; + struct PARAM_GET_CHN_INFO *prLteSafeChnInfo; + uint8_t ucIdx = 0; + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo; + + if ((prAdapter == NULL) || (prCmdInfo == NULL) || (pucEventBuf == NULL) + || (prCmdInfo->pvInformationBuffer == NULL)) { + ASSERT(FALSE); + return; + } + + prEvent = (struct EVENT_LTE_SAFE_CHN *) pucEventBuf; + + prLteSafeChnInfo = (struct PARAM_GET_CHN_INFO *) + prCmdInfo->pvInformationBuffer; + + if (prLteSafeChnInfo->ucRoleIndex >= BSS_P2P_NUM) { + ASSERT(FALSE); + kalMemFree(prLteSafeChnInfo, VIR_MEM_TYPE, + sizeof(struct PARAM_GET_CHN_INFO)); + return; + } + prP2pRoleFsmInfo = P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, + prLteSafeChnInfo->ucRoleIndex); + if (prP2pRoleFsmInfo == NULL) { + DBGLOG(P2P, ERROR, + "Corresponding P2P Role FSM empty: %d.\n", + prLteSafeChnInfo->ucRoleIndex); + kalMemFree(prLteSafeChnInfo, VIR_MEM_TYPE, + sizeof(struct PARAM_GET_CHN_INFO)); + return; + } + + /* Statistics from FW is valid */ + if (prEvent->u4Flags & BIT(0)) { + struct LTE_SAFE_CHN_INFO *prLteSafeChnList; + + prLteSafeChnList = &prLteSafeChnInfo->rLteSafeChnList; + for (ucIdx = 0; ucIdx < + ENUM_SAFE_CH_MASK_MAX_NUM; + ucIdx++) { + prLteSafeChnList->au4SafeChannelBitmask[ucIdx] + = prEvent->rLteSafeChn. + au4SafeChannelBitmask[ucIdx]; + + DBGLOG(NIC, INFO, + "[ACS]LTE safe channels[%d]=0x%08x\n", + ucIdx, + prLteSafeChnList->au4SafeChannelBitmask[ucIdx]); + } + } else { + DBGLOG(NIC, ERROR, "FW's event is NOT valid.\n"); + } + p2pFunProcessAcsReport(prAdapter, + prLteSafeChnInfo->ucRoleIndex, + prLteSafeChnInfo, + &(prP2pRoleFsmInfo->rAcsReqInfo)); + kalMemFree(prLteSafeChnInfo, VIR_MEM_TYPE, + sizeof(struct PARAM_GET_CHN_INFO)); +} + +void nicEventRddPulseDump(IN struct ADAPTER *prAdapter, + IN uint8_t *pucEventBuf) +{ + uint16_t u2Idx, u2PulseCnt; + struct EVENT_WIFI_RDD_TEST *prRddPulseEvent; + + ASSERT(prAdapter); + ASSERT(pucEventBuf); + + prRddPulseEvent = (struct EVENT_WIFI_RDD_TEST *) ( + pucEventBuf); + + u2PulseCnt = (prRddPulseEvent->u4FuncLength - + RDD_EVENT_HDR_SIZE) / RDD_ONEPLUSE_SIZE; + + DBGLOG(INIT, INFO, "[RDD]0x%08x %08d[RDD%d]\n", + prRddPulseEvent->u4Prefix + , prRddPulseEvent->u4Count, prRddPulseEvent->ucRddIdx); + + for (u2Idx = 0; u2Idx < u2PulseCnt; u2Idx++) { + DBGLOG(INIT, INFO, + "[RDD]0x%02x%02x%02x%02x %02x%02x%02x%02x[RDD%d]\n" + , prRddPulseEvent->aucBuffer[RDD_ONEPLUSE_SIZE * u2Idx + + RDD_PULSE_OFFSET3] + , prRddPulseEvent->aucBuffer[RDD_ONEPLUSE_SIZE * u2Idx + + RDD_PULSE_OFFSET2] + , prRddPulseEvent->aucBuffer[RDD_ONEPLUSE_SIZE * u2Idx + + RDD_PULSE_OFFSET1] + , prRddPulseEvent->aucBuffer[RDD_ONEPLUSE_SIZE * u2Idx + + RDD_PULSE_OFFSET0] + , prRddPulseEvent->aucBuffer[RDD_ONEPLUSE_SIZE * u2Idx + + RDD_PULSE_OFFSET7] + , prRddPulseEvent->aucBuffer[RDD_ONEPLUSE_SIZE * u2Idx + + RDD_PULSE_OFFSET6] + , prRddPulseEvent->aucBuffer[RDD_ONEPLUSE_SIZE * u2Idx + + RDD_PULSE_OFFSET5] + , prRddPulseEvent->aucBuffer[RDD_ONEPLUSE_SIZE * u2Idx + + RDD_PULSE_OFFSET4] + , prRddPulseEvent->ucRddIdx + ); + } + +} + +#if CFG_SUPPORT_MSP +void nicCmdEventQueryWlanInfo(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf) +{ + struct PARAM_HW_WLAN_INFO *prWlanInfo; + struct EVENT_WLAN_INFO *prEventWlanInfo; + struct GLUE_INFO *prGlueInfo; + uint32_t u4QueryInfoLen; + + ASSERT(prAdapter); + ASSERT(prCmdInfo); + + prEventWlanInfo = (struct EVENT_WLAN_INFO *) pucEventBuf; + + DBGLOG(RSN, INFO, "MT6632 : nicCmdEventQueryWlanInfo\n"); + + prGlueInfo = prAdapter->prGlueInfo; + + u4QueryInfoLen = sizeof(struct PARAM_HW_WLAN_INFO); + prWlanInfo = (struct PARAM_HW_WLAN_INFO *) + prCmdInfo->pvInformationBuffer; + + /* prWlanInfo->u4Length = sizeof(PARAM_HW_WLAN_INFO_T); */ + if (prEventWlanInfo && prWlanInfo) { + kalMemCopy(&prWlanInfo->rWtblTxConfig, + &prEventWlanInfo->rWtblTxConfig, + sizeof(struct PARAM_TX_CONFIG)); + kalMemCopy(&prWlanInfo->rWtblSecConfig, + &prEventWlanInfo->rWtblSecConfig, + sizeof(struct PARAM_SEC_CONFIG)); + kalMemCopy(&prWlanInfo->rWtblKeyConfig, + &prEventWlanInfo->rWtblKeyConfig, + sizeof(struct PARAM_KEY_CONFIG)); + kalMemCopy(&prWlanInfo->rWtblRateInfo, + &prEventWlanInfo->rWtblRateInfo, + sizeof(struct PARAM_PEER_RATE_INFO)); + kalMemCopy(&prWlanInfo->rWtblBaConfig, + &prEventWlanInfo->rWtblBaConfig, + sizeof(struct PARAM_PEER_BA_CONFIG)); + kalMemCopy(&prWlanInfo->rWtblPeerCap, + &prEventWlanInfo->rWtblPeerCap, + sizeof(struct PARAM_PEER_CAP)); + kalMemCopy(&prWlanInfo->rWtblRxCounter, + &prEventWlanInfo->rWtblRxCounter, + sizeof(struct PARAM_PEER_RX_COUNTER_ALL)); + kalMemCopy(&prWlanInfo->rWtblTxCounter, + &prEventWlanInfo->rWtblTxCounter, + sizeof(struct PARAM_PEER_TX_COUNTER_ALL)); + } + + if (prCmdInfo->fgIsOid) + kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, + u4QueryInfoLen, WLAN_STATUS_SUCCESS); +} + + +void nicCmdEventQueryMibInfo(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf) +{ + struct PARAM_HW_MIB_INFO *prMibInfo; + struct EVENT_MIB_INFO *prEventMibInfo; + struct GLUE_INFO *prGlueInfo; + uint32_t u4QueryInfoLen; + + ASSERT(prAdapter); + ASSERT(prCmdInfo); + + prEventMibInfo = (struct EVENT_MIB_INFO *) pucEventBuf; + + DBGLOG(RSN, INFO, "MT6632 : nicCmdEventQueryMibInfo\n"); + + prGlueInfo = prAdapter->prGlueInfo; + + u4QueryInfoLen = sizeof(struct PARAM_HW_MIB_INFO); + prMibInfo = (struct PARAM_HW_MIB_INFO *) + prCmdInfo->pvInformationBuffer; + if (prEventMibInfo && prMibInfo) { + kalMemCopy(&prMibInfo->rHwMibCnt, + &prEventMibInfo->rHwMibCnt, + sizeof(struct HW_MIB_COUNTER)); + kalMemCopy(&prMibInfo->rHwMib2Cnt, + &prEventMibInfo->rHwMib2Cnt, + sizeof(struct HW_MIB2_COUNTER)); + kalMemCopy(&prMibInfo->rHwTxAmpduMts, + &prEventMibInfo->rHwTxAmpduMts, + sizeof(struct HW_TX_AMPDU_METRICS)); + } + + if (prCmdInfo->fgIsOid) + kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, + u4QueryInfoLen, WLAN_STATUS_SUCCESS); +} +#endif + +uint32_t nicEventQueryTxResourceEntry(IN struct ADAPTER *prAdapter, + IN uint8_t *pucEventBuf) +{ + struct NIC_TX_RESOURCE *prTxResource; + uint32_t version = *((uint32_t *)pucEventBuf); + + + prAdapter->fgIsNicTxReousrceValid = TRUE; + + if (version & NIC_TX_RESOURCE_REPORT_VERSION_PREFIX) + return nicEventQueryTxResource(prAdapter, pucEventBuf); + + /* 6632, 7668 ways */ + prAdapter->nicTxReousrce.txResourceInit = NULL; + + prTxResource = (struct NIC_TX_RESOURCE *)pucEventBuf; + prAdapter->nicTxReousrce.u4CmdTotalResource = + prTxResource->u4CmdTotalResource; + prAdapter->nicTxReousrce.u4CmdResourceUnit = + prTxResource->u4CmdResourceUnit; + prAdapter->nicTxReousrce.u4DataTotalResource = + prTxResource->u4DataTotalResource; + prAdapter->nicTxReousrce.u4DataResourceUnit = + prTxResource->u4DataResourceUnit; + + DBGLOG(INIT, INFO, + "nicCmdEventQueryNicTxResource: u4CmdTotalResource = %x\n", + prAdapter->nicTxReousrce.u4CmdTotalResource); + DBGLOG(INIT, INFO, + "nicCmdEventQueryNicTxResource: u4CmdResourceUnit = %x\n", + prAdapter->nicTxReousrce.u4CmdResourceUnit); + DBGLOG(INIT, INFO, + "nicCmdEventQueryNicTxResource: u4DataTotalResource = %x\n", + prAdapter->nicTxReousrce.u4DataTotalResource); + DBGLOG(INIT, INFO, + "nicCmdEventQueryNicTxResource: u4DataResourceUnit = %x\n", + prAdapter->nicTxReousrce.u4DataResourceUnit); + + return WLAN_STATUS_SUCCESS; +} + +uint32_t nicCmdEventQueryNicEfuseAddr(IN struct ADAPTER *prAdapter, + IN uint8_t *pucEventBuf) +{ + struct NIC_EFUSE_ADDRESS *prTxResource = + (struct NIC_EFUSE_ADDRESS *)pucEventBuf; + + prAdapter->u4EfuseStartAddress = + prTxResource->u4EfuseStartAddress; + prAdapter->u4EfuseEndAddress = + prTxResource->u4EfuseEndAddress; + + DBGLOG(INIT, INFO, + "nicCmdEventQueryNicEfuseAddr: u4EfuseStartAddress = %x\n", + prAdapter->u4EfuseStartAddress); + DBGLOG(INIT, INFO, + "nicCmdEventQueryNicEfuseAddr: u4EfuseEndAddress = %x\n", + prAdapter->u4EfuseEndAddress); + + return WLAN_STATUS_SUCCESS; +} + +uint32_t nicCmdEventQueryNicCoexFeature(IN struct ADAPTER *prAdapter, + IN uint8_t *pucEventBuf) +{ + struct NIC_COEX_FEATURE *prCoexFeature = + (struct NIC_COEX_FEATURE *)pucEventBuf; + + prAdapter->u4FddMode = prCoexFeature->u4FddMode; + + DBGLOG(INIT, INFO, + "nicCmdEventQueryNicCoexFeature: u4FddMode = %x\n", + prAdapter->u4FddMode); + + return WLAN_STATUS_SUCCESS; +} + +#if CFG_TCP_IP_CHKSUM_OFFLOAD +uint32_t nicCmdEventQueryNicCsumOffload(IN struct ADAPTER *prAdapter, + IN uint8_t *pucEventBuf) +{ + struct NIC_CSUM_OFFLOAD *prChecksumOffload = + (struct NIC_CSUM_OFFLOAD *)pucEventBuf; + + prAdapter->fgIsSupportCsumOffload = + prChecksumOffload->ucIsSupportCsumOffload; + + DBGLOG(INIT, INFO, + "nicCmdEventQueryNicCsumOffload: ucIsSupportCsumOffload = %x\n", + prAdapter->fgIsSupportCsumOffload); + + return WLAN_STATUS_SUCCESS; +} +#endif + +uint32_t nicCfgChipCapHwVersion(IN struct ADAPTER *prAdapter, + IN uint8_t *pucEventBuf) +{ + struct mt66xx_chip_info *prChipInfo = NULL; + struct CAP_HW_VERSION *prHwVer = + (struct CAP_HW_VERSION *)pucEventBuf; + + ASSERT(prAdapter); + prChipInfo = prAdapter->chip_info; + ASSERT(prChipInfo); + + prAdapter->rVerInfo.u2FwProductID = prHwVer->u2ProductID; + prChipInfo->u4ChipIpConfig = prHwVer->u4ConfigId; + prChipInfo->u4ChipIpVersion = prHwVer->u4TopIpID; + + return WLAN_STATUS_SUCCESS; +} + +uint32_t nicCfgChipAdieHwVersion(IN struct ADAPTER *prAdapter, + IN uint8_t *pucEventBuf) +{ + struct mt66xx_chip_info *prChipInfo = NULL; + struct CAP_HW_ADIE_VERSION *prAdieHwVer = + (struct CAP_HW_ADIE_VERSION *)pucEventBuf; + + ASSERT(prAdapter); + prChipInfo = prAdapter->chip_info; + ASSERT(prChipInfo); + + prChipInfo->u2ADieChipVersion = prAdieHwVer->u2ProductID; + DBGLOG(INIT, INFO, "A DieID = 0x%x\n", prAdieHwVer->u2ProductID); + return WLAN_STATUS_SUCCESS; +} + + +uint32_t nicCfgChipCapSwVersion(IN struct ADAPTER *prAdapter, + IN uint8_t *pucEventBuf) +{ + struct CAP_SW_VERSION *prSwVer = + (struct CAP_SW_VERSION *)pucEventBuf; + + prAdapter->rVerInfo.u2FwOwnVersion = prSwVer->u2FwVersion; + prAdapter->rVerInfo.ucFwBuildNumber = + prSwVer->u2FwBuildNumber; + kalMemCopy(prAdapter->rVerInfo.aucFwBranchInfo, + prSwVer->aucBranchInfo, 4); + kalMemCopy(prAdapter->rVerInfo.aucFwDateCode, + prSwVer->aucDateCode, 16); + + return WLAN_STATUS_SUCCESS; +} + +uint32_t nicCfgChipCapMacAddr(IN struct ADAPTER *prAdapter, + IN uint8_t *pucEventBuf) +{ + struct CAP_MAC_ADDR *prMacAddr = (struct CAP_MAC_ADDR *)pucEventBuf; + uint8_t aucZeroMacAddr[] = NULL_MAC_ADDR; + + COPY_MAC_ADDR(prAdapter->rWifiVar.aucPermanentAddress, + prMacAddr->aucMacAddr); + COPY_MAC_ADDR(prAdapter->rWifiVar.aucMacAddress, + prMacAddr->aucMacAddr); + prAdapter->fgIsEmbbededMacAddrValid = (u_int8_t) ( + !IS_BMCAST_MAC_ADDR(prMacAddr->aucMacAddr) && + !EQUAL_MAC_ADDR(aucZeroMacAddr, prMacAddr->aucMacAddr)); + + return WLAN_STATUS_SUCCESS; +} + +uint32_t nicCfgChipCapPhyCap(IN struct ADAPTER *prAdapter, + IN uint8_t *pucEventBuf) +{ + struct CAP_PHY_CAP *prPhyCap = (struct CAP_PHY_CAP *)pucEventBuf; + + prAdapter->rWifiVar.ucStaVht &= prPhyCap->ucVht; + wlanCfgSetUint32(prAdapter, "StaVHT", prAdapter->rWifiVar.ucStaVht); + if (prAdapter->rWifiVar.ucApVht != FEATURE_FORCE_ENABLED) { + prAdapter->rWifiVar.ucApVht &= prPhyCap->ucVht; + wlanCfgSetUint32(prAdapter, "ApVHT", + prAdapter->rWifiVar.ucApVht); + } + prAdapter->rWifiVar.ucP2pGoVht &= prPhyCap->ucVht; + wlanCfgSetUint32(prAdapter, "P2pGoVHT", prAdapter->rWifiVar.ucP2pGoVht); + prAdapter->rWifiVar.ucP2pGcVht &= prPhyCap->ucVht; + wlanCfgSetUint32(prAdapter, "P2pGcVHT", prAdapter->rWifiVar.ucP2pGcVht); + prAdapter->fgIsHw5GBandDisabled = !prPhyCap->uc5gBand; + prAdapter->rWifiVar.ucNSS = (prPhyCap->ucNss > + prAdapter->rWifiVar.ucNSS) ? + (prAdapter->rWifiVar.ucNSS):(prPhyCap->ucNss); + wlanCfgSetUint32(prAdapter, "Nss", prAdapter->rWifiVar.ucNSS); +#if CFG_SUPPORT_DBDC + if (!prPhyCap->ucDbdc) { + prAdapter->rWifiVar.eDbdcMode = ENUM_DBDC_MODE_DISABLED; + wlanCfgSetUint32(prAdapter, "DbdcMode", + prAdapter->rWifiVar.eDbdcMode); + } else if (prPhyCap->ucWifiPath + == (WLAN_FLAG_2G4_WF0 | WLAN_FLAG_5G_WF1)) { + prAdapter->rWifiVar.eDbdcMode = ENUM_DBDC_MODE_STATIC; + wlanCfgSetUint32(prAdapter, "DbdcMode", + prAdapter->rWifiVar.eDbdcMode); + } +#endif + prAdapter->rWifiVar.ucTxLdpc &= prPhyCap->ucTxLdpc; + wlanCfgSetUint32(prAdapter, "LdpcTx", prAdapter->rWifiVar.ucTxLdpc); + prAdapter->rWifiVar.ucRxLdpc &= prPhyCap->ucRxLdpc; + wlanCfgSetUint32(prAdapter, "LdpcRx", prAdapter->rWifiVar.ucRxLdpc); + prAdapter->rWifiVar.ucTxStbc &= prPhyCap->ucTxStbc; + wlanCfgSetUint32(prAdapter, "StbcTx", prAdapter->rWifiVar.ucTxStbc); + prAdapter->rWifiVar.ucRxStbc &= prPhyCap->ucRxStbc; + wlanCfgSetUint32(prAdapter, "StbcRx", prAdapter->rWifiVar.ucRxStbc); + + + if ((prPhyCap->ucWifiPath != 0xF) && (prPhyCap->ucWifiPath != 0x3)) { + /* May be legal settings in the future */ + DBGLOG(INIT, ERROR, "illegle ucWifiPath %x\n", + prPhyCap->ucWifiPath); + } else { /* 0xF = 2*2, 0x3 = 1*1 */ + DBGLOG(INIT, TRACE, "ucWifiPath %x\n", + prPhyCap->ucWifiPath); + } + /* Overwirte driver default setting here */ + prAdapter->rWifiFemCfg.u2WifiPath = prPhyCap->ucWifiPath; + + +#if (CFG_SUPPORT_802_11AX == 1) + prAdapter->rWifiVar.ucStaHe &= prPhyCap->ucHe; + wlanCfgSetUint32(prAdapter, "StaHE", prAdapter->rWifiVar.ucStaHe); + prAdapter->rWifiVar.ucApHe &= prPhyCap->ucHe; + wlanCfgSetUint32(prAdapter, "ApHE", prAdapter->rWifiVar.ucApHe); + prAdapter->rWifiVar.ucP2pGoHe &= prPhyCap->ucHe; + wlanCfgSetUint32(prAdapter, "P2pGoHE", prAdapter->rWifiVar.ucP2pGoHe); + prAdapter->rWifiVar.ucP2pGcHe &= prPhyCap->ucHe; + wlanCfgSetUint32(prAdapter, "P2pGcHE", prAdapter->rWifiVar.ucP2pGcHe); + if (prAdapter->rWifiVar.ucStaHe & BIT(0)) { /* (wifi.cfg & chip cap) */ + fgEfuseCtrlAxOn = 1; /* default is 0 */ + } +#endif + + DBGLOG(INIT, TRACE, + "Vht [%u] He[%u] 5gBand [%d], Nss [%d], Dbdc [%d]\n", + prPhyCap->ucVht, + prPhyCap->ucHe, + prPhyCap->uc5gBand, + prPhyCap->ucNss, + prPhyCap->ucDbdc); + + DBGLOG(INIT, TRACE, + "TxLdpc [%u], RxLdpc [%u], StbcTx [%u], StbcRx [%u], WifiPath [%x]\n", + prPhyCap->ucTxLdpc, + prPhyCap->ucRxLdpc, + prPhyCap->ucTxStbc, + prPhyCap->ucRxStbc, + prPhyCap->ucWifiPath); + + + return WLAN_STATUS_SUCCESS; +} + +#if (CFG_SUPPORT_P2PGO_ACS == 1) +uint32_t nicCfgChipP2PCap(IN struct ADAPTER *prAdapter, + IN uint8_t *pucEventBuf) +{ +#if 0 + struct CAP_PHY_CAP *prPhyCap = + (struct CAP_PHY_CAP *)pucEventBuf; + prAdapter->rWifiVar.ucStaVht &= prPhyCap->ucVht; +#endif + wlanCfgSetUint32(prAdapter, "P2pGoACSEnable", + prAdapter->rWifiVar.ucP2pGoACS); + DBGLOG(INIT, INFO, "P2pGoACSEnable:ACS Enable[%d]\n", + prAdapter->rWifiVar.ucP2pGoACS); + return WLAN_STATUS_SUCCESS; + } +#endif + +uint32_t nicCmdEventHostStatusEmiOffset(IN struct ADAPTER *prAdapter, + IN uint8_t *pucEventBuf) +{ + struct NIC_HOST_STATUS_EMI_OFFSET *prOffset = + (struct NIC_HOST_STATUS_EMI_OFFSET *)pucEventBuf; + + prAdapter->u4HostStatusEmiOffset = prOffset->u4EmiOffset; + + DBGLOG(INIT, INFO, + "EMI offset= %x\n", + prAdapter->u4HostStatusEmiOffset); + + return WLAN_STATUS_SUCCESS; +} + +uint32_t nicCfgChipCapMacCap(IN struct ADAPTER *prAdapter, + IN uint8_t *pucEventBuf) +{ + struct CAP_MAC_CAP *prMacCap = (struct CAP_MAC_CAP *)pucEventBuf; + + if (prMacCap->ucHwBssIdNum > 0 + && prMacCap->ucHwBssIdNum <= MAX_BSSID_NUM) { + prAdapter->ucHwBssIdNum = prMacCap->ucHwBssIdNum; + prAdapter->ucP2PDevBssIdx = prAdapter->ucHwBssIdNum; + prAdapter->aprBssInfo[prAdapter->ucP2PDevBssIdx] = + &prAdapter->rWifiVar.rP2pDevInfo; + } + + if (prMacCap->ucWtblEntryNum > 0 + && prMacCap->ucWtblEntryNum <= WTBL_SIZE) { + prAdapter->ucWtblEntryNum = prMacCap->ucWtblEntryNum; + prAdapter->ucTxDefaultWlanIndex = prAdapter->ucWtblEntryNum + - 1; + } + + prAdapter->ucWmmSetNum = prMacCap->ucWmmSet > 0 ? + prMacCap->ucWmmSet : 1; + DBGLOG(INIT, INFO, + "ucHwBssIdNum: %d, ucWtblEntryNum: %d, ucWmmSetNum: %d.\n", + prMacCap->ucHwBssIdNum, + prMacCap->ucWtblEntryNum, + prMacCap->ucWmmSet); + + return WLAN_STATUS_SUCCESS; +} + +uint32_t nicCfgChipCapFrameBufCap(IN struct ADAPTER *prAdapter, + IN uint8_t *pucEventBuf) +{ + return WLAN_STATUS_SUCCESS; +} + +uint32_t nicCfgChipCapBeamformCap(IN struct ADAPTER *prAdapter, + IN uint8_t *pucEventBuf) +{ + return WLAN_STATUS_SUCCESS; +} + +uint32_t nicCfgChipCapLocationCap(IN struct ADAPTER *prAdapter, + IN uint8_t *pucEventBuf) +{ + return WLAN_STATUS_SUCCESS; +} + +uint32_t nicCfgChipCapMuMimoCap(IN struct ADAPTER *prAdapter, + IN uint8_t *pucEventBuf) +{ + return WLAN_STATUS_SUCCESS; +} + +#if CFG_SUPPORT_ANT_SWAP +uint32_t nicCfgChipCapAntSwpCap(IN struct ADAPTER *prAdapter, + IN uint8_t *pucEventBuf) +{ + struct CAP_ANTSWP *prAntSwpCap = (struct CAP_ANTSWP *)pucEventBuf; + + /* FW's value combines both platform and FW capablity */ + prAdapter->fgIsSupportAntSwp = prAntSwpCap->ucIsSupported; + DBGLOG(INIT, INFO, + "fgIsSupportAntSwp = %d\n", + prAdapter->fgIsSupportAntSwp); + + return WLAN_STATUS_SUCCESS; +} +#endif /* CFG_SUPPORT_ANT_SWAP */ + +struct nicTxRsrcEvtHdlr nicTxRsrcEvtHdlrTbl[] = { + {NIC_TX_RESOURCE_REPORT_VERSION_1, + nicEventQueryTxResource_v1, + nicTxResourceUpdate_v1}, +}; + +uint32_t nicEventQueryTxResource(IN struct ADAPTER + *prAdapter, IN uint8_t *pucEventBuf) +{ + uint32_t i, i_max; + uint32_t version = *((uint32_t *)(pucEventBuf)); + + i_max = sizeof(nicTxRsrcEvtHdlrTbl) / sizeof( + struct nicTxRsrcEvtHdlr); + for (i = 0; i < i_max; i += 2) { + if (version == nicTxRsrcEvtHdlrTbl[i].u4Version) { + /* assign callback to do the resource init. */ + prAdapter->nicTxReousrce.txResourceInit = + nicTxRsrcEvtHdlrTbl[i].nicTxResourceInit; + + return nicTxRsrcEvtHdlrTbl[i].nicEventTxResource( + prAdapter, pucEventBuf); + } + } + + /* invalid version, cannot find the handler */ + DBGLOG(INIT, ERROR, + "nicEventQueryTxResource(): Invaalid version.\n"); + prAdapter->nicTxReousrce.txResourceInit = NULL; + + return WLAN_STATUS_NOT_SUPPORTED; +} + +uint32_t nicEventQueryTxResource_v1(IN struct ADAPTER + *prAdapter, IN uint8_t *pucEventBuf) +{ + struct tx_resource_report_v1 *pV1 = + (struct tx_resource_report_v1 *)pucEventBuf; + uint16_t page_size; + + /* PSE */ + page_size = pV1->u4PlePsePageSize & 0xFFFF; + prAdapter->nicTxReousrce.u4CmdTotalResource = + pV1->u4HifCmdPsePageQuota; + prAdapter->nicTxReousrce.u4CmdResourceUnit = page_size; + prAdapter->nicTxReousrce.u4DataTotalResource = + pV1->u4HifDataPsePageQuota; + prAdapter->nicTxReousrce.u4DataResourceUnit = page_size; + + /* PLE */ + page_size = (pV1->u4PlePsePageSize >> 16) & 0xFFFF; + prAdapter->nicTxReousrce.u4CmdTotalResourcePle = + pV1->u4HifCmdPlePageQuota; + prAdapter->nicTxReousrce.u4CmdResourceUnitPle = page_size; + prAdapter->nicTxReousrce.u4DataTotalResourcePle = + pV1->u4HifDataPlePageQuota; + prAdapter->nicTxReousrce.u4DataResourceUnitPle = page_size; + + /* PpTxAddCnt */ + prAdapter->nicTxReousrce.ucPpTxAddCnt = pV1->ucPpTxAddCnt; + + /* enable PLE resource control flag */ + if (!prAdapter->nicTxReousrce.u4DataTotalResourcePle) + prAdapter->rTxCtrl.rTc.fgNeedPleCtrl = FALSE; + else + prAdapter->rTxCtrl.rTc.fgNeedPleCtrl = + NIC_TX_RESOURCE_CTRL_PLE; + return WLAN_STATUS_SUCCESS; +} + +void nicCmdEventQueryNicCapabilityV2(IN struct ADAPTER *prAdapter, + IN uint8_t *pucEventBuf) +{ + struct EVENT_NIC_CAPABILITY_V2 *prEventNicV2 = + (struct EVENT_NIC_CAPABILITY_V2 *)pucEventBuf; + struct NIC_CAPABILITY_V2_ELEMENT *prElement; + uint32_t tag_idx, table_idx, offset; + + offset = 0; + + /* process each element */ + for (tag_idx = 0; tag_idx < prEventNicV2->u2TotalElementNum; + tag_idx++) { + + prElement = (struct NIC_CAPABILITY_V2_ELEMENT *)( + prEventNicV2->aucBuffer + offset); + + for (table_idx = 0; + table_idx < (sizeof(gNicCapabilityV2InfoTable) / sizeof( + struct NIC_CAPABILITY_V2_REF_TABLE)); + table_idx++) { + + /* find the corresponding tag's handler */ + if (gNicCapabilityV2InfoTable[table_idx].tag_type == + prElement->tag_type) { + gNicCapabilityV2InfoTable[table_idx].hdlr( + prAdapter, prElement->aucbody); + break; + } + } + + /* move to the next tag */ + offset += prElement->body_len + (uint16_t) OFFSET_OF( + struct NIC_CAPABILITY_V2_ELEMENT, aucbody); + } + +} + +#if (CFG_SUPPORT_TXPOWER_INFO == 1) +void nicCmdEventQueryTxPowerInfo(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, + IN uint8_t *pucEventBuf) +{ + struct EXT_EVENT_TXPOWER_ALL_RATE_POWER_INFO_T *prEvent = + NULL; + struct PARAM_TXPOWER_ALL_RATE_POWER_INFO_T *prTxPowerInfo = + NULL; + uint32_t u4QueryInfoLen = 0; + struct GLUE_INFO *prGlueInfo = NULL; + + if (!prAdapter) + return; + + prGlueInfo = prAdapter->prGlueInfo; + if (!prCmdInfo) + return; + if (!pucEventBuf) + return; + if (!(prCmdInfo->pvInformationBuffer)) + return; + + if (prCmdInfo->fgIsOid) { + prEvent = (struct EXT_EVENT_TXPOWER_ALL_RATE_POWER_INFO_T *) + pucEventBuf; + + if (prEvent->ucTxPowerCategory == + TXPOWER_EVENT_SHOW_ALL_RATE_TXPOWER_INFO) { + prEvent = + (struct + EXT_EVENT_TXPOWER_ALL_RATE_POWER_INFO_T *) + pucEventBuf; + prTxPowerInfo = + (struct PARAM_TXPOWER_ALL_RATE_POWER_INFO_T *) + prCmdInfo->pvInformationBuffer; + u4QueryInfoLen = + sizeof( + struct PARAM_TXPOWER_ALL_RATE_POWER_INFO_T); + + kalMemCopy(prTxPowerInfo, prEvent, + sizeof( + struct EXT_EVENT_TXPOWER_ALL_RATE_POWER_INFO_T)); + } + + kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, + u4QueryInfoLen, WLAN_STATUS_SUCCESS); + } +} +#endif + +void nicEventLinkQuality(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ + struct mt66xx_chip_info *prChipInfo = NULL; + struct CMD_INFO *prCmdInfo; + uint8_t ucBssIndex = AIS_DEFAULT_INDEX; + + ASSERT(prAdapter); + prChipInfo = prAdapter->chip_info; + +#if CFG_ENABLE_WIFI_DIRECT && CFG_SUPPORT_P2P_RSSI_QUERY + if (prEvent->u2PacketLen == prChipInfo->event_hdr_size + + sizeof(struct EVENT_LINK_QUALITY_EX)) { + struct EVENT_LINK_QUALITY_EX *prLqEx = + (struct EVENT_LINK_QUALITY_EX *) (prEvent->aucBuffer); + + if (prLqEx->ucIsLQ0Rdy) + nicUpdateLinkQuality(prAdapter, 0, + (struct LINK_QUALITY *) prLqEx); + if (prLqEx->ucIsLQ1Rdy) + nicUpdateLinkQuality(prAdapter, 1, + (struct LINK_QUALITY *) prLqEx); + } else { + /* For old FW, P2P may invoke link quality query, + * and make driver flag becone TRUE. + */ + DBGLOG(P2P, WARN, + "Old FW version, not support P2P RSSI query.\n"); + + /* Must not use NETWORK_TYPE_P2P_INDEX, + * cause the structure is mismatch. + */ + nicUpdateLinkQuality(prAdapter, 0, + (struct LINK_QUALITY *) (prEvent->aucBuffer)); + } +#else + /*only support ais query */ + { + struct BSS_INFO *prBssInfo; + + for (ucBssIndex = 0; ucBssIndex < prAdapter->ucHwBssIdNum; + ucBssIndex++) { + prBssInfo = prAdapter->aprBssInfo[ucBssIndex]; + if (IS_BSS_AIS(prBssInfo) && + prBssInfo->fgIsInUse) { + nicUpdateLinkQuality(prAdapter, ucBssIndex, + (struct EVENT_LINK_QUALITY *) + (prEvent->aucBuffer)); + } + } + } + +#endif + + /* command response handling */ + prCmdInfo = nicGetPendingCmdInfo(prAdapter, + prEvent->ucSeqNum); + + if (prCmdInfo != NULL) { + if (prCmdInfo->pfCmdDoneHandler) + prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, + prEvent->aucBuffer); + else if (prCmdInfo->fgIsOid) + kalOidComplete(prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, + 0, WLAN_STATUS_SUCCESS); + /* return prCmdInfo */ + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + } +#ifndef LINUX + if (prAdapter->rWlanInfo.eRssiTriggerType == + ENUM_RSSI_TRIGGER_GREATER && + prAdapter->rWlanInfo.rRssiTriggerValue >= (int32_t) ( + prAdapter->rLinkQuality.rLq[ucBssIndex].cRssi)) { + + prAdapter->rWlanInfo.eRssiTriggerType = + ENUM_RSSI_TRIGGER_TRIGGERED; + + kalIndicateStatusAndComplete(prAdapter->prGlueInfo, + WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, + (void *) &(prAdapter->rWlanInfo.rRssiTriggerValue), + sizeof(int32_t), + ucBssIndex); + } else if (prAdapter->rWlanInfo.eRssiTriggerType == + ENUM_RSSI_TRIGGER_LESS && + prAdapter->rWlanInfo.rRssiTriggerValue <= (int32_t) ( + prAdapter->rLinkQuality.rLq[ucBssIndex].cRssi)) { + + prAdapter->rWlanInfo.eRssiTriggerType = + ENUM_RSSI_TRIGGER_TRIGGERED; + + kalIndicateStatusAndComplete(prAdapter->prGlueInfo, + WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, + (void *) &(prAdapter->rWlanInfo.rRssiTriggerValue), + sizeof(int32_t), + ucBssIndex); + } +#endif +} + +uint32_t nicExtTsfRawData2IqFmt( + struct EXT_EVENT_RBIST_DUMP_DATA_T *prEventDumpMem, + struct ICAP_INFO_T *prIcap) +{ + static uint8_t + aucPathWF0[40]; /* the path for iq data dump out */ + static uint8_t + aucPathWF1[40]; /* the path for iq data dump out */ + static uint8_t + aucPathRAWWF0[40]; /* the path for iq data dump out */ + static uint8_t + aucPathRAWWF1[40]; /* the path for iq data dump out */ + uint8_t *pucDataWF0 = NULL; /* the data write into file */ + uint8_t *pucDataWF1 = NULL; /* the data write into file */ + uint8_t *pucDataRAWWF0 = + NULL; /* the data write into file */ + uint8_t *pucDataRAWWF1 = + NULL; /* the data write into file */ + uint32_t u4SrcOffset; /* record the buffer offset */ + uint32_t u4FmtLen = 0; /* bus format length */ + uint32_t u4CpyLen = 0; + uint32_t u4RemainByte; + uint32_t u4DataWBufSize = 150; + uint32_t u4DataRAWWBufSize = 150; + uint32_t u4DataWLenF0 = 0; + uint32_t u4DataWLenF1 = 0; + uint32_t u4DataRAWWLenF0 = 0; + uint32_t u4DataRAWWLenF1 = 0; + u_int8_t fgAppend; + int32_t u4Iqc160WF0Q0, u4Iqc160WF1I1; + /* for alignment. bcs we send 2KB data per packet,*/ + static uint8_t ucDstOffset; + /* the data will not align in 12 bytes case. */ + static uint32_t u4CurTimeTick; + + static union ICAP_BUS_FMT icapBusData; + uint32_t *ptr; + + pucDataWF0 = kmalloc(u4DataWBufSize, GFP_KERNEL); + pucDataWF1 = kmalloc(u4DataWBufSize, GFP_KERNEL); + pucDataRAWWF0 = kmalloc(u4DataRAWWBufSize, GFP_KERNEL); + pucDataRAWWF1 = kmalloc(u4DataRAWWBufSize, GFP_KERNEL); + + + if ((!pucDataWF0) || (!pucDataWF1) || (!pucDataRAWWF0) + || (!pucDataRAWWF1)) { + DBGLOG(INIT, ERROR, "kmalloc failed.\n"); + kfree(pucDataWF0); + kfree(pucDataWF1); + kfree(pucDataRAWWF0); + kfree(pucDataRAWWF1); + ASSERT(-1); + return -1; + } + + fgAppend = TRUE; + if (prEventDumpMem->u4PktNum == 0) { + u4CurTimeTick = kalGetTimeTick(); + /* Store memory dump into sdcard, + * path /sdcard/dump__ + * _.hex + */ +#if defined(LINUX) + + /* if blbist mkdir undre /data/blbist, + * the dump files wouls put on it + */ + kalScnprintf(aucPathWF0, sizeof(aucPathWF0), + "/dump_out_%05hu_WF0.txt", prIcap->u2DumpIndex); + kalScnprintf(aucPathWF1, sizeof(aucPathWF1), + "/dump_out_%05hu_WF1.txt", prIcap->u2DumpIndex); + if (kalCheckPath(aucPathWF0) == -1) { + kalMemSet(aucPathWF0, 0x00, sizeof(aucPathWF0)); + kalScnprintf(aucPathWF0, sizeof(aucPathWF0), + "/data/dump_out_%05hu_WF0.txt", + prIcap->u2DumpIndex); + } else + kalTrunkPath(aucPathWF0); + + if (kalCheckPath(aucPathWF1) == -1) { + kalMemSet(aucPathWF1, 0x00, sizeof(aucPathWF1)); + kalScnprintf(aucPathWF1, sizeof(aucPathWF1), + "/data/dump_out_%05hu_WF1.txt", + prIcap->u2DumpIndex); + } else + kalTrunkPath(aucPathWF1); + + kalScnprintf(aucPathRAWWF0, sizeof(aucPathRAWWF0), + "/dump_RAW_%05hu_WF0.txt", prIcap->u2DumpIndex); + kalScnprintf(aucPathRAWWF1, sizeof(aucPathRAWWF1), + "/dump_RAW_%05hu_WF1.txt", prIcap->u2DumpIndex); + if (kalCheckPath(aucPathRAWWF0) == -1) { + kalMemSet(aucPathRAWWF0, 0x00, sizeof(aucPathRAWWF0)); + kalScnprintf(aucPathRAWWF0, sizeof(aucPathRAWWF0), + "/data/dump_RAW_%05hu_WF0.txt", + prIcap->u2DumpIndex); + } else + kalTrunkPath(aucPathRAWWF0); + + if (kalCheckPath(aucPathRAWWF1) == -1) { + kalMemSet(aucPathRAWWF1, 0x00, sizeof(aucPathRAWWF1)); + kalScnprintf(aucPathRAWWF1, sizeof(aucPathRAWWF1), + "/data/dump_RAW_%hu_WF1.txt", + prIcap->u2DumpIndex); + } else + kalTrunkPath(aucPathRAWWF1); + +#else + /* TODO: check Address */ + kal_sprintf_ddk(aucPathWF0, sizeof(aucPathWF0), + u4CurTimeTick, prEventDumpMem->u4Address, + prEventDumpMem->u4Length + + prEventDumpMem->u4RemainLength); + kal_sprintf_ddk(aucPathWF1, sizeof(aucPathWF1), + u4CurTimeTick, prEventDumpMem->u4Address, + prEventDumpMem->u4Length + + prEventDumpMem->u4RemainLength); +#endif + /* fgAppend = FALSE; */ + } + + ptr = (uint32_t *)(&prEventDumpMem->u4Data); + + for (u4SrcOffset = 0, + u4RemainByte = prEventDumpMem->u4DataLength; + u4RemainByte > 0;) { + u4FmtLen = (prIcap->u4CapNode == ICAP_CONTENT_SPECTRUM) ? + sizeof(struct SPECTRUM_BUS_FMT) : sizeof(union + ICAP_BUS_FMT); + /* 4 bytes : 12 bytes */ + u4CpyLen = (u4RemainByte - u4FmtLen >= 0) ? u4FmtLen : + u4RemainByte; + if ((ucDstOffset + u4CpyLen) > sizeof(icapBusData)) { + DBGLOG(INIT, ERROR, + "ucDstOffset(%u) + u4CpyLen(%u) exceed bound of icapBusData\n", + ucDstOffset, u4CpyLen); + kfree(pucDataWF0); + kfree(pucDataWF1); + kfree(pucDataRAWWF0); + kfree(pucDataRAWWF1); + ASSERT(-1); + return -1; + } + + memcpy((uint8_t *)&icapBusData + ucDstOffset, + &prEventDumpMem->u4Data + u4SrcOffset, u4CpyLen); + if (prIcap->u4CapNode == ICAP_CONTENT_FIIQ + || prIcap->u4CapNode == ICAP_CONTENT_FDIQ) { + u4DataWLenF0 = kalScnprintf(pucDataWF0, u4DataWBufSize, + "%8d,%8d\n", + icapBusData.rIqcBusData.u4Iqc0I, + icapBusData.rIqcBusData.u4Iqc0Q); + u4DataWLenF1 = kalScnprintf(pucDataWF1, u4DataWBufSize, + "%8d,%8d\n", + icapBusData.rIqcBusData.u4Iqc1I, + icapBusData.rIqcBusData.u4Iqc1Q); + } else if (prIcap->u4CapNode - 1000 == ICAP_CONTENT_FIIQ || + prIcap->u4CapNode - 1000 == ICAP_CONTENT_FDIQ) { + u4Iqc160WF0Q0 = icapBusData.rIqc160BusData.u4Iqc0Q0P1 | + (icapBusData.rIqc160BusData.u4Iqc0Q0P2 << 8); + u4Iqc160WF1I1 = icapBusData.rIqc160BusData.u4Iqc1I1P1 | + (icapBusData.rIqc160BusData.u4Iqc1I1P2 << 4); + + u4DataWLenF0 = kalScnprintf(pucDataWF0, u4DataWBufSize, + "%8d,%8d\n%8d,%8d\n", + icapBusData.rIqc160BusData.u4Iqc0I0, + u4Iqc160WF0Q0, + icapBusData.rIqc160BusData.u4Iqc0I1, + icapBusData.rIqc160BusData.u4Iqc0Q1); + + u4DataWLenF1 = kalScnprintf(pucDataWF1, u4DataWBufSize, + "%8d,%8d\n%8d,%8d\n", + icapBusData.rIqc160BusData.u4Iqc1I0, + icapBusData.rIqc160BusData.u4Iqc1Q0, + u4Iqc160WF1I1, + icapBusData.rIqc160BusData.u4Iqc1Q1); + + } else if (prIcap->u4CapNode == ICAP_CONTENT_SPECTRUM) { + u4DataWLenF0 = kalScnprintf(pucDataWF0, u4DataWBufSize, + "%8d,%8d\n", + icapBusData.rSpectrumBusData.u4DcocI, + icapBusData.rSpectrumBusData.u4DcocQ); + } else if (prIcap->u4CapNode == ICAP_CONTENT_ADC) { + u4DataWLenF0 = kalScnprintf(pucDataWF0, u4DataWBufSize, + "%8d,%8d\n%8d,%8d\n%8d,%8d\n%8d,%8d\n%8d,%8d\n%8d,%8d\n", + icapBusData.rPackedAdcBusData.u4AdcI0T0, + icapBusData.rPackedAdcBusData.u4AdcQ0T0, + icapBusData.rPackedAdcBusData.u4AdcI0T1, + icapBusData.rPackedAdcBusData.u4AdcQ0T1, + icapBusData.rPackedAdcBusData.u4AdcI0T2, + icapBusData.rPackedAdcBusData.u4AdcQ0T2, + icapBusData.rPackedAdcBusData.u4AdcI0T3, + icapBusData.rPackedAdcBusData.u4AdcQ0T3, + icapBusData.rPackedAdcBusData.u4AdcI0T4, + icapBusData.rPackedAdcBusData.u4AdcQ0T4, + icapBusData.rPackedAdcBusData.u4AdcI0T5, + icapBusData.rPackedAdcBusData.u4AdcQ0T5); + + u4DataWLenF1 = kalScnprintf(pucDataWF1, u4DataWBufSize, + "%8d,%8d\n%8d,%8d\n%8d,%8d\n%8d,%8d\n%8d,%8d\n%8d,%8d\n", + icapBusData.rPackedAdcBusData.u4AdcI1T0, + icapBusData.rPackedAdcBusData.u4AdcQ1T0, + icapBusData.rPackedAdcBusData.u4AdcI1T1, + icapBusData.rPackedAdcBusData.u4AdcQ1T1, + icapBusData.rPackedAdcBusData.u4AdcI1T2, + icapBusData.rPackedAdcBusData.u4AdcQ1T2, + icapBusData.rPackedAdcBusData.u4AdcI1T3, + icapBusData.rPackedAdcBusData.u4AdcQ1T3, + icapBusData.rPackedAdcBusData.u4AdcI1T4, + icapBusData.rPackedAdcBusData.u4AdcQ1T4, + icapBusData.rPackedAdcBusData.u4AdcI1T5, + icapBusData.rPackedAdcBusData.u4AdcQ1T5); + } else if (prIcap->u4CapNode - 2000 == ICAP_CONTENT_ADC) { + u4DataWLenF0 = kalScnprintf(pucDataWF0, u4DataWBufSize, + "%8d,%8d\n%8d,%8d\n%8d,%8d\n", + icapBusData.rPackedAdcBusData.u4AdcI0T0, + icapBusData.rPackedAdcBusData.u4AdcQ0T0, + icapBusData.rPackedAdcBusData.u4AdcI0T1, + icapBusData.rPackedAdcBusData.u4AdcQ0T1, + icapBusData.rPackedAdcBusData.u4AdcI0T2, + icapBusData.rPackedAdcBusData.u4AdcQ0T2); + + u4DataWLenF1 = kalScnprintf(pucDataWF1, u4DataWBufSize, + "%8d,%8d\n%8d,%8d\n%8d,%8d\n", + icapBusData.rPackedAdcBusData.u4AdcI1T0, + icapBusData.rPackedAdcBusData.u4AdcQ1T0, + icapBusData.rPackedAdcBusData.u4AdcI1T1, + icapBusData.rPackedAdcBusData.u4AdcQ1T1, + icapBusData.rPackedAdcBusData.u4AdcI1T2, + icapBusData.rPackedAdcBusData.u4AdcQ1T2); + } else if (prIcap->u4CapNode == ICAP_CONTENT_TOAE) { + /* actually, this is DCOC. we take TOAE as DCOC */ + u4DataWLenF0 = kalScnprintf(pucDataWF0, u4DataWBufSize, + "%8d,%8d\n", + icapBusData.rAdcBusData.u4Dcoc0I, + icapBusData.rAdcBusData.u4Dcoc0Q); + u4DataWLenF1 = kalScnprintf(pucDataWF1, u4DataWBufSize, + "%8d,%8d\n", + icapBusData.rAdcBusData.u4Dcoc1I, + icapBusData.rAdcBusData.u4Dcoc1Q); + } + if (u4CpyLen == + u4FmtLen) { /* the data format is complete */ + kalWriteToFile(aucPathWF0, fgAppend, pucDataWF0, + u4DataWLenF0); + kalWriteToFile(aucPathWF1, fgAppend, pucDataWF1, + u4DataWLenF1); + } + ptr = (uint32_t *)(&prEventDumpMem->u4Data + u4SrcOffset); + u4DataRAWWLenF0 = kalScnprintf(pucDataRAWWF0, u4DataWBufSize, + "%08x%08x%08x\n", + *(ptr + 2), *(ptr + 1), *ptr); + kalWriteToFile(aucPathRAWWF0, fgAppend, pucDataRAWWF0, + u4DataRAWWLenF0); + kalWriteToFile(aucPathRAWWF1, fgAppend, pucDataRAWWF1, + u4DataRAWWLenF1); + + u4RemainByte -= u4CpyLen; + u4SrcOffset += u4CpyLen; /* shift offset */ + /* only use ucDstOffset at first packet for align 2KB */ + ucDstOffset = 0; + } + /* if this is a last packet, we can't transfer the remain data. + * bcs we can't guarantee the data is complete align data format + */ + if (u4CpyLen != + u4FmtLen) { /* the data format is complete */ + /* not align 2KB, keep the data and next packet data + * will append it + */ + ucDstOffset = u4CpyLen; + } + + kfree(pucDataWF0); + kfree(pucDataWF1); + kfree(pucDataRAWWF0); + kfree(pucDataRAWWF1); + + if (u4RemainByte < 0) { + ASSERT(-1); + return -1; + } + + return 0; +} + +void nicExtEventReCalData(IN struct ADAPTER *prAdapter, IN uint8_t *pucEventBuf) +{ + struct EXT_EVENT_RECAL_DATA_T *prReCalData = NULL; + struct RECAL_INFO_T *prReCalInfo = NULL; + struct RECAL_DATA_T *prCalArray = NULL; + uint32_t u4Idx = 0; + + ASSERT(pucEventBuf); + ASSERT(prAdapter); + prReCalInfo = &prAdapter->rReCalInfo; + if (prReCalInfo->prCalArray == NULL) { + prCalArray = (struct RECAL_DATA_T *)kalMemAlloc( + 2048 * sizeof(struct RECAL_DATA_T), VIR_MEM_TYPE); + + if (prCalArray == NULL) { + DBGLOG(RFTEST, ERROR, + "Unable to alloc memory for recal data\n"); + return; + } + prReCalInfo->prCalArray = prCalArray; + } + + if (prReCalInfo->u4Count >= 2048) { + DBGLOG(RFTEST, ERROR, + "Too many Recal packet, maximum packets will be 2048, ignore\n"); + return; + } + + prCalArray = prReCalInfo->prCalArray; + DBGLOG(RFTEST, INFO, "prCalArray[%d] address [%p]\n", + prReCalInfo->u4Count, + &prCalArray[prReCalInfo->u4Count]); + + prReCalData = (struct EXT_EVENT_RECAL_DATA_T *)pucEventBuf; + switch (prReCalData->u4Type) { + case 0: { + unsigned long ulTmpData; + + prReCalData->u.ucData[9] = '\0'; + prReCalData->u.ucData[19] = '\0'; + u4Idx = prReCalInfo->u4Count; + + if (kalStrtoul(&prReCalData->u.ucData[1], 16, &ulTmpData)) + DBGLOG(RFTEST, ERROR, "convert fail: ucData[1]\n"); + else + prCalArray[u4Idx].u4CalId = (unsigned int)ulTmpData; + if (kalStrtoul(&prReCalData->u.ucData[11], 16, &ulTmpData)) + DBGLOG(RFTEST, ERROR, "convert fail: ucData[11]\n"); + else + prCalArray[u4Idx].u4CalAddr = (unsigned int)ulTmpData; + if (kalStrtoul(&prReCalData->u.ucData[20], 16, &ulTmpData)) + DBGLOG(RFTEST, ERROR, "convert fail: ucData[20] %s\n", + &prReCalData->u.ucData[20]); + else + prCalArray[u4Idx].u4CalValue = (unsigned int)ulTmpData; + + DBGLOG(RFTEST, TRACE, "[0x%08x][0x%08x][0x%08x]\n", + prCalArray[u4Idx].u4CalId, + prCalArray[u4Idx].u4CalAddr, + prCalArray[u4Idx].u4CalValue); + prReCalInfo->u4Count++; + break; + } + case 1: + /* Todo: for extension to handle int */ + /* data directly come from FW */ + break; + } +} + + +void nicExtEventICapIQData(IN struct ADAPTER *prAdapter, + IN uint8_t *pucEventBuf) +{ + struct EXT_EVENT_RBIST_DUMP_DATA_T *prICapEvent; + uint32_t Idxi = 0, Idxj = 0, Idxk = 0; + struct _RBIST_IQ_DATA_T *prIQArray = NULL; + struct ICAP_INFO_T *prIcapInfo = NULL; + + ASSERT(prAdapter); + ASSERT(pucEventBuf); + + prICapEvent = (struct EXT_EVENT_RBIST_DUMP_DATA_T *) + pucEventBuf; + prIcapInfo = &prAdapter->rIcapInfo; + prIQArray = prIcapInfo->prIQArray; + ASSERT(prIQArray); + + /* If we receive the packet which is delivered from + * last time data-capure, we need to drop it. + */ + DBGLOG(RFTEST, INFO, "prICapEvent->u4PktNum = %d\n", + prICapEvent->u4PktNum); + if (prICapEvent->u4PktNum > prIcapInfo->u4ICapEventCnt) { + if (prICapEvent->u4DataLength == 0) + prIcapInfo->eIcapState = ICAP_STATE_FW_DUMP_DONE; + + DBGLOG(RFTEST, ERROR, + "Packet out of order: Pkt num %d, EventCnt %d\n", + prICapEvent->u4PktNum, prIcapInfo->u4ICapEventCnt); + return; + } + + DBGLOG(RFTEST, INFO, + "u4SmplCnt = [%d], u4WFCnt = [%d], IQArrayIndex = [%d]\n", + prICapEvent->u4SmplCnt, + prICapEvent->u4WFCnt, + prIcapInfo->u4IQArrayIndex); + + if (prICapEvent->u4DataLength != 0 && + prICapEvent->u4SmplCnt * prICapEvent->u4WFCnt * + NUM_OF_CAP_TYPE > ICAP_EVENT_DATA_SAMPLE) { + /* Max count = Total ICAP_EVENT_DATA_SAMPLE count + * and cut into half (I/Q) + */ + prICapEvent->u4SmplCnt = ICAP_EVENT_DATA_SAMPLE / + NUM_OF_CAP_TYPE; + DBGLOG(RFTEST, WARN, + "u4SmplCnt is larger than buffer size\n"); + } + + if (prIcapInfo->u4IQArrayIndex + prICapEvent->u4SmplCnt >= + MAX_ICAP_IQ_DATA_CNT) { + DBGLOG(RFTEST, ERROR, + "Too many packets from FW, skip rest of them\n"); + return; + } + + for (Idxi = 0; Idxi < prICapEvent->u4SmplCnt; Idxi++) { + for (Idxj = 0; Idxj < prICapEvent->u4WFCnt; Idxj++) { + prIQArray[prIcapInfo->u4IQArrayIndex]. + u4IQArray[Idxj][CAP_I_TYPE] = + prICapEvent->u4Data[Idxk++]; + prIQArray[prIcapInfo->u4IQArrayIndex]. + u4IQArray[Idxj][CAP_Q_TYPE] = + prICapEvent->u4Data[Idxk++]; + } + prIcapInfo->u4IQArrayIndex++; + } + + /* Print ICap data to console for debugging purpose */ + for (Idxi = 0; Idxi < prICapEvent->u4SmplCnt; Idxi++) + if (prICapEvent->u4Data[Idxi] == 0) + DBGLOG(RFTEST, WARN, "Data[%d] : %x\n", Idxi, + prICapEvent->u4Data[Idxi]); + + + /* Update ICapEventCnt */ + if (prICapEvent->u4DataLength != 0) + prIcapInfo->u4ICapEventCnt++; + + /* Check whether is the last FW event or not */ + if ((prICapEvent->u4DataLength == 0) + && (prICapEvent->u4PktNum == prIcapInfo->u4ICapEventCnt)) { + /* Reset ICapEventCnt */ + prAdapter->rIcapInfo.eIcapState = ICAP_STATE_FW_DUMP_DONE; + prIcapInfo->u4ICapEventCnt = 0; + DBGLOG(INIT, INFO, ": ==> gen done_file\n"); + } else + prAdapter->rIcapInfo.eIcapState = ICAP_STATE_FW_DUMPING; + +} + +void nicExtEventQueryMemDump(IN struct ADAPTER *prAdapter, + IN uint8_t *pucEventBuf) +{ + struct EXT_EVENT_RBIST_DUMP_DATA_T *prEventDumpMem; + static uint8_t aucPath[256]; + static uint8_t aucPath_done[300]; + static uint32_t u4CurTimeTick; + + ASSERT(prAdapter); + ASSERT(pucEventBuf); + + kalSprintf(aucPath, "/dump_%05hu.hex", + prAdapter->rIcapInfo.u2DumpIndex); + + prEventDumpMem = (struct EXT_EVENT_RBIST_DUMP_DATA_T *) + pucEventBuf; + + if (kalCheckPath(aucPath) == -1) { + kalMemSet(aucPath, 0x00, 256); + kalSprintf(aucPath, "/data/dump_%05hu.hex", + prAdapter->rIcapInfo.u2DumpIndex); + } + + if (prEventDumpMem->u4PktNum == 0) { + /* Store memory dump into sdcard, + * path /sdcard/dump__ + * _.hex + */ + u4CurTimeTick = kalGetTimeTick(); +#if defined(LINUX) + + /* if blbist mkdir undre /data/blbist, + * the dump files wouls put on it + */ + kalSprintf(aucPath, "/dump_%05hu.hex", + prAdapter->rIcapInfo.u2DumpIndex); + if (kalCheckPath(aucPath) == -1) { + kalMemSet(aucPath, 0x00, 256); + kalSprintf(aucPath, "/data/dump_%05hu.hex", + prAdapter->rIcapInfo.u2DumpIndex); + } +#else + /* TODO: check Address */ + kal_sprintf_ddk(aucPath, sizeof(aucPath), + u4CurTimeTick, prEventDumpMem->u4Address, + prEventDumpMem->u4Length + + prEventDumpMem->u4RemainLength); +#endif + kalWriteToFile(aucPath, FALSE, + (uint8_t *)prEventDumpMem->u4Data, + prEventDumpMem->u4DataLength); + } else { + /* Append current memory dump to the hex file */ + kalWriteToFile(aucPath, TRUE, + (uint8_t *)prEventDumpMem->u4Data, + prEventDumpMem->u4DataLength); + } +#if CFG_SUPPORT_QA_TOOL + nicExtTsfRawData2IqFmt(prEventDumpMem, + &prAdapter->rIcapInfo); +#endif /* CFG_SUPPORT_QA_TOOL */ + + /* TODO: check Address */ + + if (prEventDumpMem->u4DataLength == 0) { + /* The request is finished or firmware response a error */ + /* Reply time tick to iwpriv */ + + prAdapter->rIcapInfo.eIcapState = ICAP_STATE_FW_DUMP_DONE; + + kalSprintf(aucPath_done, "/file_dump_done.txt"); + if (kalCheckPath(aucPath_done) == -1) { + kalMemSet(aucPath_done, 0x00, 256); + kalSprintf(aucPath_done, "/data/file_dump_done.txt"); + } + DBGLOG(INIT, INFO, ": ==> gen done_file\n"); + kalWriteToFile(aucPath_done, FALSE, aucPath_done, + sizeof(aucPath_done)); +#if CFG_SUPPORT_QA_TOOL + prAdapter->rIcapInfo.au4Offset[0][0] = 0; + prAdapter->rIcapInfo.au4Offset[0][1] = 9; + prAdapter->rIcapInfo.au4Offset[1][0] = 0; + prAdapter->rIcapInfo.au4Offset[1][1] = 9; +#endif /* CFG_SUPPORT_QA_TOOL */ + prAdapter->rIcapInfo.u2DumpIndex++; + + } +} + + +uint32_t nicRfTestEventHandler(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ + uint32_t u4QueryInfoLen = 0; + struct EXT_EVENT_RF_TEST_RESULT_T *prResult; + struct EXT_EVENT_RBIST_CAP_STATUS_T *prCapStatus; + struct mt66xx_chip_info *prChipInfo = NULL; + struct ATE_OPS_T *prAteOps = NULL; + struct ICAP_INFO_T *prIcapInfo; + + ASSERT(prAdapter); + prChipInfo = prAdapter->chip_info; + ASSERT(prChipInfo); + prAteOps = prChipInfo->prAteOps; + ASSERT(prAteOps); + prIcapInfo = &prAdapter->rIcapInfo; + + prResult = (struct EXT_EVENT_RF_TEST_RESULT_T *) + prEvent->aucBuffer; + DBGLOG(RFTEST, INFO, "%s funcID = %d\n", + __func__, + prResult->u4FuncIndex); + switch (prResult->u4FuncIndex) { + case GET_ICAP_CAPTURE_STATUS: + u4QueryInfoLen = sizeof(struct + EXT_EVENT_RBIST_CAP_STATUS_T); + prCapStatus = (struct EXT_EVENT_RBIST_CAP_STATUS_T *) + prEvent->aucBuffer; + + DBGLOG(RFTEST, INFO, "%s iCapDone = %d , icap state=%d\n", + __func__, + prCapStatus->u4CapDone, + prAdapter->rIcapInfo.eIcapState); + if (prCapStatus->u4CapDone && + prIcapInfo->eIcapState != ICAP_STATE_FW_DUMP_DONE) { + wlanoidRfTestICapRawDataProc(prAdapter, + 0 /*prCapStatus->u4CapStartAddr*/, + 0 /*prCapStatus->u4TotalBufferSize*/); + prIcapInfo->eIcapState = ICAP_STATE_FW_DUMPING; + } + break; + + case GET_ICAP_RAW_DATA: + if (prAteOps->getRbistDataDumpEvent) { + prAteOps->getRbistDataDumpEvent(prAdapter, + prEvent->aucBuffer); + if (prIcapInfo->eIcapState != ICAP_STATE_FW_DUMP_DONE) + wlanoidRfTestICapRawDataProc(prAdapter, + 0 /*prCapStatus->u4CapStartAddr*/, + 0 /*prCapStatus->u4TotalBufferSize*/); + } + break; + + case RE_CALIBRATION: + nicExtEventReCalData(prAdapter, prEvent->aucBuffer); + break; + + default: + DBGLOG(RFTEST, WARN, "Unknown rf test event, ignore\n"); + break; + } + + return u4QueryInfoLen; +} + +void nicEventLayer0ExtMagic(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ + uint32_t u4QueryInfoLen = 0; + struct CMD_INFO *prCmdInfo = NULL; + + log_dbg(NIC, TRACE, "prEvent->ucExtenEID = %x\n", prEvent->ucExtenEID); + + switch (prEvent->ucExtenEID) { + case EXT_EVENT_ID_CMD_RESULT: + u4QueryInfoLen = sizeof(struct + PARAM_CUSTOM_EFUSE_BUFFER_MODE); + prCmdInfo = nicGetPendingCmdInfo(prAdapter, + prEvent->ucSeqNum); + break; + + case EXT_EVENT_ID_EFUSE_ACCESS: + { + struct EVENT_ACCESS_EFUSE *prEventEfuseAccess; + + u4QueryInfoLen = sizeof(struct PARAM_CUSTOM_ACCESS_EFUSE); + prCmdInfo = nicGetPendingCmdInfo(prAdapter, + prEvent->ucSeqNum); + prEventEfuseAccess = (struct EVENT_ACCESS_EFUSE *) ( + prEvent->aucBuffer); + + /* Efuse block size 16 */ + kalMemCopy(prAdapter->aucEepromVaule, + prEventEfuseAccess->aucData, 16); + break; + } + + case EXT_EVENT_ID_RF_TEST: + u4QueryInfoLen = nicRfTestEventHandler(prAdapter, prEvent); + prCmdInfo = nicGetPendingCmdInfo(prAdapter, + prEvent->ucSeqNum); + break; + + case EXT_EVENT_ID_GET_TX_POWER: + { + struct EXT_EVENT_GET_TX_POWER *prEventGetTXPower; + + u4QueryInfoLen = sizeof(struct PARAM_CUSTOM_GET_TX_POWER); + prCmdInfo = nicGetPendingCmdInfo(prAdapter, + prEvent->ucSeqNum); + prEventGetTXPower = (struct EXT_EVENT_GET_TX_POWER *) ( + prEvent->aucBuffer); + + prAdapter->u4GetTxPower = + prEventGetTXPower->ucTx0TargetPower; + break; + } + + case EXT_EVENT_ID_EFUSE_FREE_BLOCK: + { + struct EXT_EVENT_EFUSE_FREE_BLOCK *prEventGetFreeBlock; + + u4QueryInfoLen = sizeof(struct + PARAM_CUSTOM_EFUSE_FREE_BLOCK); + prCmdInfo = nicGetPendingCmdInfo(prAdapter, + prEvent->ucSeqNum); + prEventGetFreeBlock = (struct EXT_EVENT_EFUSE_FREE_BLOCK *) + (prEvent->aucBuffer); + prAdapter->u4FreeBlockNum = + prEventGetFreeBlock->u2FreeBlockNum; + break; + } + + case EXT_EVENT_ID_BF_STATUS_READ: + prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum); + if (prCmdInfo != NULL && prCmdInfo->pfCmdDoneHandler) { + struct EXT_EVENT_BF_STATUS_T *prExtBfStatus = + (struct EXT_EVENT_BF_STATUS_T *)prEvent->aucBuffer; + + prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, + prExtBfStatus->aucBuf); + } + break; + + case EXT_EVENT_ID_MAX_AMSDU_LENGTH_UPDATE: + { + struct EXT_EVENT_MAX_AMSDU_LENGTH_UPDATE *prEventAmsdu; + struct STA_RECORD *prStaRec; + uint8_t ucStaRecIndex; + + prEventAmsdu = (struct EXT_EVENT_MAX_AMSDU_LENGTH_UPDATE *) + (prEvent->aucBuffer); + + ucStaRecIndex = secGetStaIdxByWlanIdx( + prAdapter, prEventAmsdu->ucWlanIdx); + if (ucStaRecIndex == STA_REC_INDEX_NOT_FOUND) + break; + + prStaRec = cnmGetStaRecByIndex(prAdapter, ucStaRecIndex); + if (!prStaRec) + break; + + if (prStaRec->ucMaxMpduCount == 0 || + prStaRec->ucMaxMpduCount > prEventAmsdu->ucAmsduLen) + prStaRec->ucMaxMpduCount = prEventAmsdu->ucAmsduLen; + + DBGLOG(NIC, INFO, + "Amsdu update event ucWlanIdx[%u] ucLen[%u] ucMaxMpduCount[%u]\n", + prEventAmsdu->ucWlanIdx, prEventAmsdu->ucAmsduLen, + prStaRec->ucMaxMpduCount); + break; + } +#if CFG_SUPPORT_WIFI_SYSDVT + case EXT_EVENT_ID_SYSDVT_TEST: + { + u4QueryInfoLen = sizeof(struct SYSDVT_CTRL_EXT_T); + prCmdInfo = nicGetPendingCmdInfo(prAdapter, + prEvent->ucSeqNum); + break; + } +#endif /* CFG_SUPPORT_WIFI_SYSDVT */ + default: + break; + } + + if (prCmdInfo != NULL) { + if ((prCmdInfo->fgIsOid) != 0) + kalOidComplete(prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, + u4QueryInfoLen, WLAN_STATUS_SUCCESS); + /* return prCmdInfo */ + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + } +#if (CFG_SUPPORT_TXPOWER_INFO == 1) + else if ((prEvent->ucExtenEID) == + EXT_EVENT_ID_TX_POWER_FEATURE_CTRL) { + u4QueryInfoLen = sizeof(struct + PARAM_TXPOWER_ALL_RATE_POWER_INFO_T); + /* command response handling */ + prCmdInfo = nicGetPendingCmdInfo(prAdapter, + prEvent->ucSeqNum); + + if (prCmdInfo != NULL) { + if (prCmdInfo->pfCmdDoneHandler) + prCmdInfo->pfCmdDoneHandler(prAdapter, + prCmdInfo, prEvent->aucBuffer); + else if (prCmdInfo->fgIsOid) + kalOidComplete(prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, + u4QueryInfoLen, WLAN_STATUS_SUCCESS); + + /* return prCmdInfo */ + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + } + } +#endif + else if ((prEvent->ucExtenEID) == EXT_EVENT_ID_MAC_INFO) { + u4QueryInfoLen = sizeof(struct EXT_EVENT_MAC_INFO_T); + prCmdInfo = + nicGetPendingCmdInfo(prAdapter, + prEvent->ucSeqNum); + + if (prCmdInfo != NULL) { + if (prCmdInfo->pfCmdDoneHandler) { + prCmdInfo->pfCmdDoneHandler( + prAdapter, + prCmdInfo, + prEvent->aucBuffer + ); + } else if ((prCmdInfo->fgIsOid) != 0) + kalOidComplete( + prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, + u4QueryInfoLen, + WLAN_STATUS_SUCCESS); + /* return prCmdInfo */ + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + } + } else if (prEvent->ucExtenEID == EXT_EVENT_ID_DUMP_MEM) { + u4QueryInfoLen = sizeof(struct EXT_CMD_EVENT_DUMP_MEM_T); + prCmdInfo = nicGetPendingCmdInfo( + prAdapter, + prEvent->ucSeqNum); + + if (prCmdInfo != NULL) { + if (prCmdInfo->pfCmdDoneHandler) { + prCmdInfo->pfCmdDoneHandler( + prAdapter, + prCmdInfo, + prEvent->aucBuffer + ); + } else if ((prCmdInfo->fgIsOid) != 0) + kalOidComplete( + prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, + u4QueryInfoLen, + WLAN_STATUS_SUCCESS); + /* return prCmdInfo */ + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + } + } +} + +void nicEventMicErrorInfo(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ + uint8_t ucBssIndex = AIS_DEFAULT_INDEX; + struct EVENT_MIC_ERR_INFO *prMicError; + /* P_PARAM_AUTH_EVENT_T prAuthEvent; */ + struct STA_RECORD *prStaRec; + struct PARAM_BSSID_EX *prCurrBssid = + aisGetCurrBssId(prAdapter, + ucBssIndex); + + DBGLOG(RSN, EVENT, "EVENT_ID_MIC_ERR_INFO\n"); + + prMicError = (struct EVENT_MIC_ERR_INFO *) ( + prEvent->aucBuffer); + prStaRec = cnmGetStaRecByAddress(prAdapter, + ucBssIndex, + prCurrBssid->arMacAddress); + ASSERT(prStaRec); + + if (prStaRec) + rsnTkipHandleMICFailure(prAdapter, prStaRec, + (u_int8_t) prMicError->u4Flags); + else + DBGLOG(RSN, INFO, "No STA rec!!\n"); +#if 0 + prAuthEvent = (struct PARAM_AUTH_EVENT *) + prAdapter->aucIndicationEventBuffer; + + /* Status type: Authentication Event */ + prAuthEvent->rStatus.eStatusType = + ENUM_STATUS_TYPE_AUTHENTICATION; + + /* Authentication request */ + prAuthEvent->arRequest[0].u4Length = sizeof( + struct PARAM_AUTH_REQUEST); + kalMemCopy((void *) prAuthEvent->arRequest[0].arBssid, + (void *) prAdapter->rWlanInfo.rCurrBssId.arMacAddress, + PARAM_MAC_ADDR_LEN); + + if (prMicError->u4Flags != 0) + prAuthEvent->arRequest[0].u4Flags = + PARAM_AUTH_REQUEST_GROUP_ERROR; + else + prAuthEvent->arRequest[0].u4Flags = + PARAM_AUTH_REQUEST_PAIRWISE_ERROR; + + kalIndicateStatusAndComplete( + prAdapter->prGlueInfo, + WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, + (void *) prAuthEvent, + sizeof(struct PARAM_STATUS_INDICATION) + sizeof( + struct PARAM_AUTH_REQUEST)); +#endif +} + +void nicEventScanDone(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ + scnEventScanDone(prAdapter, + (struct EVENT_SCAN_DONE *) (prEvent->aucBuffer), TRUE); +} + +void nicEventSchedScanDone(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ + DBGLOG(INIT, INFO, "EVENT_ID_SCHED_SCAN_DONE\n"); + scnEventSchedScanDone(prAdapter, + (struct EVENT_SCHED_SCAN_DONE *) (prEvent->aucBuffer)); +} + +void nicEventSleepyNotify(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ +#if !defined(_HIF_USB) + struct EVENT_SLEEPY_INFO *prEventSleepyNotify; + + prEventSleepyNotify = (struct EVENT_SLEEPY_INFO *) ( + prEvent->aucBuffer); + + prAdapter->fgWiFiInSleepyState = (u_int8_t) ( + prEventSleepyNotify->ucSleepyState); + +#if CFG_SUPPORT_MULTITHREAD + if (prEventSleepyNotify->ucSleepyState) + kalSetFwOwnEvent2Hif(prAdapter->prGlueInfo); +#endif +#endif +} + +void nicEventBtOverWifi(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ +#if CFG_ENABLE_BT_OVER_WIFI + uint8_t aucTmp[sizeof(struct BT_OVER_WIFI_EVENT) + sizeof( + struct BOW_LINK_DISCONNECTED)]; + struct EVENT_BT_OVER_WIFI *prEventBtOverWifi; + struct BT_OVER_WIFI_EVENT *prBowEvent; + struct BOW_LINK_CONNECTED *prBowLinkConnected; + struct BOW_LINK_DISCONNECTED *prBowLinkDisconnected; + + prEventBtOverWifi = (struct EVENT_BT_OVER_WIFI *) ( + prEvent->aucBuffer); + + /* construct event header */ + prBowEvent = (struct BT_OVER_WIFI_EVENT *) aucTmp; + + if (prEventBtOverWifi->ucLinkStatus == 0) { + /* Connection */ + prBowEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_CONNECTED; + prBowEvent->rHeader.ucSeqNumber = 0; + prBowEvent->rHeader.u2PayloadLength = sizeof( + struct BOW_LINK_CONNECTED); + + /* fill event body */ + prBowLinkConnected = (struct BOW_LINK_CONNECTED *) ( + prBowEvent->aucPayload); + prBowLinkConnected->rChannel.ucChannelNum = + prEventBtOverWifi->ucSelectedChannel; + kalMemZero(prBowLinkConnected->aucPeerAddress, + MAC_ADDR_LEN); /* @FIXME */ + + kalIndicateBOWEvent(prAdapter->prGlueInfo, prBowEvent); + } else { + /* Disconnection */ + prBowEvent->rHeader.ucEventId = + BOW_EVENT_ID_LINK_DISCONNECTED; + prBowEvent->rHeader.ucSeqNumber = 0; + prBowEvent->rHeader.u2PayloadLength = sizeof( + struct BOW_LINK_DISCONNECTED); + + /* fill event body */ + prBowLinkDisconnected = (struct BOW_LINK_DISCONNECTED *) ( + prBowEvent->aucPayload); + prBowLinkDisconnected->ucReason = 0; /* @FIXME */ + kalMemZero(prBowLinkDisconnected->aucPeerAddress, + MAC_ADDR_LEN); /* @FIXME */ + + kalIndicateBOWEvent(prAdapter->prGlueInfo, prBowEvent); + } +#endif +} + +void nicEventStatistics(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ + struct CMD_INFO *prCmdInfo; + + /* buffer statistics for further query */ + prAdapter->fgIsStatValid = TRUE; + prAdapter->rStatUpdateTime = kalGetTimeTick(); + kalMemCopy(&prAdapter->rStatStruct, prEvent->aucBuffer, + sizeof(struct EVENT_STATISTICS)); + + /* command response handling */ + prCmdInfo = nicGetPendingCmdInfo(prAdapter, + prEvent->ucSeqNum); + + if (prCmdInfo != NULL) { + if (prCmdInfo->pfCmdDoneHandler) + prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, + prEvent->aucBuffer); + else if (prCmdInfo->fgIsOid) + kalOidComplete(prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, + 0, WLAN_STATUS_SUCCESS); + /* return prCmdInfo */ + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + } +} +void nicEventWlanInfo(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ + struct CMD_INFO *prCmdInfo; + + /* buffer statistics for further query */ + prAdapter->fgIsStatValid = TRUE; + prAdapter->rStatUpdateTime = kalGetTimeTick(); + kalMemCopy(&prAdapter->rEventWlanInfo, prEvent->aucBuffer, + sizeof(struct EVENT_WLAN_INFO)); + + DBGLOG(RSN, INFO, "EVENT_ID_WTBL_INFO"); + /* command response handling */ + prCmdInfo = nicGetPendingCmdInfo(prAdapter, + prEvent->ucSeqNum); + + if (prCmdInfo != NULL) { + if (prCmdInfo->pfCmdDoneHandler) + prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, + prEvent->aucBuffer); + else if (prCmdInfo->fgIsOid) + kalOidComplete(prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, + 0, WLAN_STATUS_SUCCESS); + /* return prCmdInfo */ + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + } +} + +void nicEventMibInfo(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ + struct CMD_INFO *prCmdInfo; + + + /* buffer statistics for further query */ + prAdapter->fgIsStatValid = TRUE; + prAdapter->rStatUpdateTime = kalGetTimeTick(); + + DBGLOG(RSN, INFO, "EVENT_ID_MIB_INFO"); + /* command response handling */ + prCmdInfo = nicGetPendingCmdInfo(prAdapter, + prEvent->ucSeqNum); + + if (prCmdInfo != NULL) { + if (prCmdInfo->pfCmdDoneHandler) + prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, + prEvent->aucBuffer); + else if (prCmdInfo->fgIsOid) + kalOidComplete(prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, + 0, WLAN_STATUS_SUCCESS); + /* return prCmdInfo */ + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + } + +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function is to decide if the beacon time out is reasonable +* by the TRX and some known factors +* +* \param[in] prAdapter Pointer of ADAPTER_T +* +* \return true if the beacon timeout event is valid after policy checking +* false if the beacon timeout event needs to be ignored +*/ +/*----------------------------------------------------------------------------*/ +bool nicBeaconTimeoutFilterPolicy(IN struct ADAPTER *prAdapter, + uint8_t ucBcnTimeoutReason, uint8_t *ucDisconnectReason, + uint8_t ucBssIdx) +{ + struct RX_CTRL *prRxCtrl; + struct TX_CTRL *prTxCtrl; + OS_SYSTIME u4CurrentTime; + bool bValid = true; + uint32_t u4MonitorWindow; + struct BSS_INFO *prBssInfo = (struct BSS_INFO *) NULL; +#if CFG_SUPPORT_WFD + struct WFD_CFG_SETTINGS *prWfdCfgSettings = + &prAdapter->rWifiVar.rWfdConfigureSettings; +#endif + + ASSERT(prAdapter); + u4MonitorWindow = CFG_BEACON_TIMEOUT_FILTER_DURATION_DEFAULT_VALUE; + + prRxCtrl = &prAdapter->rRxCtrl; + ASSERT(prRxCtrl); + + prTxCtrl = &prAdapter->rTxCtrl; + ASSERT(prTxCtrl); + + GET_BOOT_SYSTIME(&u4CurrentTime); + + DBGLOG(NIC, INFO, + "u4MonitorWindow: %d, u4CurrentTime: %d, u4LastRxTime: %d, u4LastTxTime: %d", + u4MonitorWindow, u4CurrentTime, + prRxCtrl->u4LastRxTime[ucBssIdx], + prTxCtrl->u4LastTxTime[ucBssIdx]); + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIdx); + + if (IS_BSS_AIS(prBssInfo)) { + if (ucBcnTimeoutReason == BEACON_TIMEOUT_REASON_HIGH_PER) { + bValid = true; + } else if (!CHECK_FOR_TIMEOUT(u4CurrentTime, + prRxCtrl->u4LastRxTime[ucBssIdx], + SEC_TO_SYSTIME(MSEC_TO_SEC(u4MonitorWindow)))) { + /* Policy 1, if RX in the past duration (in ms) */ + if (scanBeaconTimeoutFilterPolicyForAis( + prAdapter, ucBssIdx)) { + DBGLOG(NIC, INFO, "Driver find better TX AP"); + *ucDisconnectReason = + DISCONNECT_REASON_CODE_RADIO_LOST_TX_ERR; + } else { + DBGLOG(NIC, INFO, "RX in the past duration"); + bValid = false; + } + } + } +#if CFG_ENABLE_WIFI_DIRECT + else if (IS_BSS_P2P(prBssInfo)) { + if (!CHECK_FOR_TIMEOUT(u4CurrentTime, + prRxCtrl->u4LastRxTime[ucBssIdx], + SEC_TO_SYSTIME(MSEC_TO_SEC(u4MonitorWindow)))) { + DBGLOG(NIC, INFO, + "Policy 1 hit, RX in the past duration"); + bValid = false; + } +#if CFG_SUPPORT_WFD + else if (prWfdCfgSettings->ucWfdEnable && + prWfdCfgSettings->u4LinkScore > 0) { + DBGLOG(NIC, INFO, + "Policy 2 hit, link score > 0 in WFD"); + bValid = false; + } +#endif /* CFG_SUPPORT_WFD */ + } +#endif /* CFG_ENABLE_WIFI_DIRECT */ + + DBGLOG(NIC, INFO, "valid beacon time out event?: %d", bValid); + + return bValid; +} + +void nicEventBeaconTimeout(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ + DBGLOG(NIC, INFO, "EVENT_ID_BSS_BEACON_TIMEOUT\n"); + + if (prAdapter->fgDisBcnLostDetection == FALSE) { + struct BSS_INFO *prBssInfo = (struct BSS_INFO *) NULL; + struct EVENT_BSS_BEACON_TIMEOUT *prEventBssBeaconTimeout; + + prEventBssBeaconTimeout = (struct EVENT_BSS_BEACON_TIMEOUT + *) (prEvent->aucBuffer); + + if (prEventBssBeaconTimeout->ucBssIndex >= + prAdapter->ucHwBssIdNum) + return; + + DBGLOG(NIC, INFO, "Reason code: %d\n", + prEventBssBeaconTimeout->ucReasonCode); + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prEventBssBeaconTimeout->ucBssIndex); + + if (IS_BSS_AIS(prBssInfo)) { + uint8_t ucDisconnectReason = + DISCONNECT_REASON_CODE_RADIO_LOST; + + if (nicBeaconTimeoutFilterPolicy(prAdapter, + prEventBssBeaconTimeout->ucReasonCode, + &ucDisconnectReason, + prBssInfo->ucBssIndex)) + aisBssBeaconTimeout_impl(prAdapter, + prEventBssBeaconTimeout->ucReasonCode, + ucDisconnectReason, + prBssInfo->ucBssIndex); + } +#if CFG_ENABLE_WIFI_DIRECT + else if (prBssInfo->eNetworkType == NETWORK_TYPE_P2P) { + uint8_t ucDisconnectReason = + DISCONNECT_REASON_CODE_RADIO_LOST; + + if (nicBeaconTimeoutFilterPolicy(prAdapter, + prEventBssBeaconTimeout->ucReasonCode, + &ucDisconnectReason, + prEventBssBeaconTimeout->ucBssIndex)) + p2pRoleFsmRunEventBeaconTimeout(prAdapter, + prBssInfo); + } +#endif +#if CFG_ENABLE_BT_OVER_WIFI + else if (GET_BSS_INFO_BY_INDEX(prAdapter, + prEventBssBeaconTimeout->ucBssIndex)->eNetworkType == + NETWORK_TYPE_BOW) { + /* ToDo:: Nothing */ + } +#endif + else { + DBGLOG(RX, ERROR, + "EVENT_ID_BSS_BEACON_TIMEOUT: (ucBssIndex = %d)\n", + prEventBssBeaconTimeout->ucBssIndex); + } + } + +} + +void nicEventUpdateNoaParams(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ +#if CFG_ENABLE_WIFI_DIRECT + if (prAdapter->fgIsP2PRegistered) { + struct EVENT_UPDATE_NOA_PARAMS *prEventUpdateNoaParam; + + prEventUpdateNoaParam = (struct EVENT_UPDATE_NOA_PARAMS *) ( + prEvent->aucBuffer); + + if (GET_BSS_INFO_BY_INDEX(prAdapter, + prEventUpdateNoaParam->ucBssIndex)->eNetworkType + == NETWORK_TYPE_P2P) { + + p2pProcessEvent_UpdateNOAParam(prAdapter, + prEventUpdateNoaParam->ucBssIndex, + prEventUpdateNoaParam); + } else { + ASSERT(0); + } + } +#else + ASSERT(0); +#endif +} + +void nicEventStaAgingTimeout(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ + if (prAdapter->fgDisStaAgingTimeoutDetection == FALSE) { + struct EVENT_STA_AGING_TIMEOUT *prEventStaAgingTimeout; + struct STA_RECORD *prStaRec; + struct BSS_INFO *prBssInfo = (struct BSS_INFO *) NULL; + + prEventStaAgingTimeout = (struct EVENT_STA_AGING_TIMEOUT *) + (prEvent->aucBuffer); + prStaRec = cnmGetStaRecByIndex(prAdapter, + prEventStaAgingTimeout->ucStaRecIdx); + if (prStaRec == NULL) + return; + + DBGLOG(NIC, INFO, "EVENT_ID_STA_AGING_TIMEOUT: STA[%u] " + MACSTR "\n", + prEventStaAgingTimeout->ucStaRecIdx, + MAC2STR(prStaRec->aucMacAddr)); + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prStaRec->ucBssIndex); + + bssRemoveClient(prAdapter, prBssInfo, prStaRec); + + if (prAdapter->fgIsP2PRegistered) { + p2pFuncDisconnect(prAdapter, prBssInfo, prStaRec, FALSE, + REASON_CODE_DISASSOC_INACTIVITY); + } + + } + /* gDisStaAgingTimeoutDetection */ +} + +void nicEventApObssStatus(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ +#if CFG_ENABLE_WIFI_DIRECT + if (prAdapter->fgIsP2PRegistered) + rlmHandleObssStatusEventPkt(prAdapter, + (struct EVENT_AP_OBSS_STATUS *) prEvent->aucBuffer); +#endif +} + +void nicEventRoamingStatus(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ +#if CFG_SUPPORT_ROAMING + struct CMD_ROAMING_TRANSIT *prTransit; + + prTransit = (struct CMD_ROAMING_TRANSIT *) ( + prEvent->aucBuffer); + + /* Default path */ + if (!IS_BSS_INDEX_AIS(prAdapter, prTransit->ucBssidx)) { + DBGLOG(NIC, LOUD, + "Use default, invalid index = %d\n", + prTransit->ucBssidx); + prTransit->ucBssidx = AIS_DEFAULT_INDEX; + } + + roamingFsmProcessEvent(prAdapter, prTransit); +#endif /* CFG_SUPPORT_ROAMING */ +} + +void nicEventSendDeauth(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ + struct SW_RFB rSwRfb; + + DBGLOG(NIC, INFO, "%s\n", __func__); +#if DBG + struct WLAN_MAC_HEADER *prWlanMacHeader; + + prWlanMacHeader = (struct WLAN_MAC_HEADER *)prEvent->aucBuffer; + DBGLOG(RX, TRACE, "nicRx: aucAddr1: " MACSTR "\n", + MAC2STR(prWlanMacHeader->aucAddr1)); + DBGLOG(RX, TRACE, "nicRx: aucAddr2: " MACSTR "\n", + MAC2STR(prWlanMacHeader->aucAddr2)); +#endif + + /* receive packets without StaRec */ + rSwRfb.pvHeader = (struct WLAN_MAC_HEADER *)prEvent->aucBuffer; + if (authSendDeauthFrame(prAdapter, NULL, NULL, &rSwRfb, + REASON_CODE_CLASS_3_ERR, + (PFN_TX_DONE_HANDLER) NULL) == WLAN_STATUS_SUCCESS) { + + DBGLOG(RX, ERROR, "Send Deauth Error\n"); + } +} + +void nicEventUpdateRddStatus(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ +#if CFG_SUPPORT_RDD_TEST_MODE + struct EVENT_RDD_STATUS *prEventRddStatus; + + prEventRddStatus = (struct EVENT_RDD_STATUS *) ( + prEvent->aucBuffer); + + prAdapter->ucRddStatus = prEventRddStatus->ucRddStatus; +#endif +} + +void nicEventUpdateBwcsStatus(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ + struct PTA_IPC *prEventBwcsStatus; + + prEventBwcsStatus = (struct PTA_IPC *) (prEvent->aucBuffer); + +#if CFG_SUPPORT_BCM_BWCS_DEBUG + DBGLOG(RSN, EVENT, "BCM BWCS Event: %02x%02x%02x%02x\n", + prEventBwcsStatus->u.aucBTPParams[0], + prEventBwcsStatus->u.aucBTPParams[1], + prEventBwcsStatus->u.aucBTPParams[2], + prEventBwcsStatus->u.aucBTPParams[3]); +#endif + + kalIndicateStatusAndComplete(prAdapter->prGlueInfo, + WLAN_STATUS_BWCS_UPDATE, + (void *) prEventBwcsStatus, sizeof(struct PTA_IPC), + AIS_DEFAULT_INDEX); +} + +void nicEventUpdateBcmDebug(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ + struct PTA_IPC *prEventBwcsStatus; + + prEventBwcsStatus = (struct PTA_IPC *) (prEvent->aucBuffer); + +#if CFG_SUPPORT_BCM_BWCS_DEBUG + DBGLOG(RSN, EVENT, "BCM FW status: %02x%02x%02x%02x\n", + prEventBwcsStatus->u.aucBTPParams[0], + prEventBwcsStatus->u.aucBTPParams[1], + prEventBwcsStatus->u.aucBTPParams[2], + prEventBwcsStatus->u.aucBTPParams[3]); +#endif +} + +void nicEventAddPkeyDone(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ + struct EVENT_ADD_KEY_DONE_INFO *prKeyDone; + struct STA_RECORD *prStaRec = NULL; + uint8_t ucKeyId; + + prKeyDone = (struct EVENT_ADD_KEY_DONE_INFO *) ( + prEvent->aucBuffer); + + DBGLOG(RSN, INFO, "EVENT_ID_ADD_PKEY_DONE BSSIDX=%d " MACSTR + "\n", + prKeyDone->ucBSSIndex, MAC2STR(prKeyDone->aucStaAddr)); + + prStaRec = cnmGetStaRecByAddress(prAdapter, + prKeyDone->ucBSSIndex, + prKeyDone->aucStaAddr); + + if (!prStaRec) { + ucKeyId = + aisGetAisSpecBssInfo(prAdapter, + prKeyDone->ucBSSIndex)->ucKeyAlgorithmId; + if ((ucKeyId == CIPHER_SUITE_WEP40) + || (ucKeyId == CIPHER_SUITE_WEP104)) { + DBGLOG(RX, INFO, "WEP, ucKeyAlgorithmId= %d\n", + ucKeyId); + prStaRec = cnmGetStaRecByAddress(prAdapter, + prKeyDone->ucBSSIndex, + prAdapter->rWifiVar.arBssInfoPool[ + prKeyDone->ucBSSIndex].aucBSSID); + if (!prStaRec) { + DBGLOG(RX, INFO, + "WEP, AddPKeyDone, ucBSSIndex %d, Addr " + MACSTR ", StaRec is NULL\n", + prKeyDone->ucBSSIndex, + MAC2STR(prAdapter->rWifiVar + .arBssInfoPool[prKeyDone-> + ucBSSIndex].aucBSSID)); + } + } else { + DBGLOG(RX, INFO, + "AddPKeyDone, ucBSSIndex %d, Addr " + MACSTR ", StaRec is NULL\n", + prKeyDone->ucBSSIndex, + MAC2STR(prKeyDone->aucStaAddr)); + } + } + if (prStaRec) { + DBGLOG(RSN, INFO, "STA " MACSTR " Add Key Done!!\n", + MAC2STR(prStaRec->aucMacAddr)); + prStaRec->fgIsTxKeyReady = TRUE; + qmUpdateStaRec(prAdapter, prStaRec); + } +} + +void nicEventIcapDone(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ + struct EVENT_ICAP_STATUS *prEventIcapStatus; + struct PARAM_CUSTOM_MEM_DUMP_STRUCT rMemDumpInfo; + uint32_t u4QueryInfo; + + prEventIcapStatus = (struct EVENT_ICAP_STATUS *) ( + prEvent->aucBuffer); + + rMemDumpInfo.u4Address = prEventIcapStatus->u4StartAddress; + rMemDumpInfo.u4Length = prEventIcapStatus->u4IcapSieze; +#if CFG_SUPPORT_QA_TOOL + rMemDumpInfo.u4IcapContent = + prEventIcapStatus->u4IcapContent; +#endif + + wlanoidQueryMemDump(prAdapter, &rMemDumpInfo, + sizeof(rMemDumpInfo), &u4QueryInfo); +} + +#if CFG_SUPPORT_CAL_RESULT_BACKUP_TO_HOST +struct PARAM_CAL_BACKUP_STRUCT_V2 g_rCalBackupDataV2; + +void nicEventCalAllDone(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ + struct CMD_CAL_BACKUP_STRUCT_V2 *prEventCalBackupDataV2; + uint32_t u4QueryInfo; + + DBGLOG(RFTEST, INFO, "%s\n", __func__); + + memset(&g_rCalBackupDataV2, 0, + sizeof(struct PARAM_CAL_BACKUP_STRUCT_V2)); + + prEventCalBackupDataV2 = (struct CMD_CAL_BACKUP_STRUCT_V2 *) + (prEvent->aucBuffer); + + if (prEventCalBackupDataV2->ucReason == 1 + && prEventCalBackupDataV2->ucAction == 2) { + DBGLOG(RFTEST, INFO, + "Received an EVENT for Trigger Do All Cal Function.\n"); + + g_rCalBackupDataV2.ucReason = 2; + g_rCalBackupDataV2.ucAction = 4; + g_rCalBackupDataV2.ucNeedResp = 1; + g_rCalBackupDataV2.ucFragNum = 0; + g_rCalBackupDataV2.ucRomRam = 0; + g_rCalBackupDataV2.u4ThermalValue = 0; + g_rCalBackupDataV2.u4Address = 0; + g_rCalBackupDataV2.u4Length = 0; + g_rCalBackupDataV2.u4RemainLength = 0; + + DBGLOG(RFTEST, INFO, + "RLM CMD : Get Cal Data from FW (%s). Start!!!!!!!!!!!!!!!!\n", + g_rCalBackupDataV2.ucRomRam == 0 ? "ROM" : "RAM"); + DBGLOG(RFTEST, INFO, "Thermal Temp = %d\n", + g_rBackupCalDataAllV2.u4ThermalInfo); + wlanoidQueryCalBackupV2(prAdapter, + &g_rCalBackupDataV2, + sizeof(struct PARAM_CAL_BACKUP_STRUCT_V2), + &u4QueryInfo); + } + +} +#endif + +void nicEventDebugMsg(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ + struct EVENT_DEBUG_MSG *prEventDebugMsg; + uint8_t ucMsgType; + uint16_t u2MsgSize; + uint8_t *pucMsg; + + prEventDebugMsg = (struct EVENT_DEBUG_MSG *)( + prEvent->aucBuffer); + if (!prEventDebugMsg) { + DBGLOG(RSN, WARN, "prEventDebugMsg is NULL\n"); + return; + } + + ucMsgType = prEventDebugMsg->ucMsgType; + u2MsgSize = prEventDebugMsg->u2MsgSize; + pucMsg = prEventDebugMsg->aucMsg; + +#if CFG_SUPPORT_QA_TOOL + if (ucMsgType == DEBUG_MSG_TYPE_ASCII) { + if (kalStrnCmp("[RECAL DUMP START]", pucMsg, 18) == 0) { + prAdapter->rReCalInfo.fgDumped = TRUE; + return; + } else if (kalStrnCmp("[RECAL DUMP END]", pucMsg, 16) == 0) { + prAdapter->rReCalInfo.fgDumped = TRUE; + return; + } else if (prAdapter->rReCalInfo.fgDumped && + kalStrnCmp("[Recal]", pucMsg, 7) == 0) { + struct WIFI_EVENT *prTmpEvent; + struct EXT_EVENT_RECAL_DATA_T *prCalData; + uint32_t u4Size = sizeof(struct WIFI_EVENT) + + sizeof(struct EXT_EVENT_RECAL_DATA_T); + + prTmpEvent = (struct WIFI_EVENT *) + kalMemAlloc(u4Size, VIR_MEM_TYPE); + + if (prTmpEvent == NULL) { + DBGLOG(RFTEST, ERROR, + "Unable to alloc memory for prTmpEvent\n"); + return; + } + kalMemZero(prTmpEvent, u4Size); + + prCalData = (struct EXT_EVENT_RECAL_DATA_T *) + prTmpEvent->aucBuffer; + if (prCalData) { + prCalData->u4FuncIndex = RE_CALIBRATION; + prCalData->u4Type = 0; + /* format: [XXXXXXXX][YYYYYYYY]ZZZZZZZZ */ + kalMemCopy(prCalData->u.ucData, pucMsg + 7, 28); + nicRfTestEventHandler(prAdapter, prTmpEvent); + } + kalMemFree(prTmpEvent, VIR_MEM_TYPE, u4Size); + } + } +#endif + + wlanPrintFwLog(pucMsg, u2MsgSize, ucMsgType, NULL); +} + +void nicEventTdls(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ + TdlsexEventHandle(prAdapter->prGlueInfo, + (uint8_t *)prEvent->aucBuffer, + (uint32_t)(prEvent->u2PacketLength - 8)); +} + +void nicEventRssiMonitor(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ + int32_t rssi = 0; + struct GLUE_INFO *prGlueInfo; + struct wiphy *wiphy; + struct net_device *dev; + + prGlueInfo = prAdapter->prGlueInfo; + wiphy = priv_to_wiphy(prGlueInfo); + + kalMemCopy(&rssi, prEvent->aucBuffer, sizeof(int32_t)); + DBGLOG(RX, TRACE, "EVENT_ID_RSSI_MONITOR value=%d\n", rssi); +#if KERNEL_VERSION(3, 16, 0) <= LINUX_VERSION_CODE + dev = wlanGetNetDev(prAdapter->prGlueInfo, + AIS_DEFAULT_INDEX); + if (dev != NULL) { + mtk_cfg80211_vendor_event_rssi_beyond_range(wiphy, + dev->ieee80211_ptr, rssi); + } +#endif +} + +void nicEventDumpMem(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ + struct CMD_INFO *prCmdInfo; + + DBGLOG(SW4, INFO, "%s: EVENT_ID_DUMP_MEM\n", __func__); + + prCmdInfo = nicGetPendingCmdInfo(prAdapter, + prEvent->ucSeqNum); + + if (prCmdInfo != NULL) { + DBGLOG(NIC, INFO, ": ==> 1\n"); + if (prCmdInfo->pfCmdDoneHandler) + prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, + prEvent->aucBuffer); + else if (prCmdInfo->fgIsOid) + kalOidComplete(prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS); + /* return prCmdInfo */ + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + } else { + /* Burst mode */ + DBGLOG(NIC, INFO, ": ==> 2\n"); +#if 0 + nicEventQueryMemDump(prAdapter, prEvent->aucBuffer); +#endif + } +} + +void nicEventAssertDump(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ + struct mt66xx_chip_info *prChipInfo = NULL; + + ASSERT(prAdapter); + prChipInfo = prAdapter->chip_info; + + if (wlanIsChipRstRecEnabled(prAdapter)) + wlanChipRstPreAct(prAdapter); + + if (prEvent->ucS2DIndex == S2D_INDEX_EVENT_N2H) { + if (!prAdapter->fgN9AssertDumpOngoing) { + DBGLOG(NIC, ERROR, + "%s: EVENT_ID_ASSERT_DUMP\n", __func__); + DBGLOG(NIC, ERROR, + "\n[DUMP_N9]====N9 ASSERT_DUMPSTART====\n"); + prAdapter->fgKeepPrintCoreDump = TRUE; + if (kalOpenCorDumpFile(TRUE) != WLAN_STATUS_SUCCESS) + DBGLOG(NIC, ERROR, "kalOpenCorDumpFile fail\n"); + else + prAdapter->fgN9CorDumpFileOpend = TRUE; + + prAdapter->fgN9AssertDumpOngoing = TRUE; + wlanCorDumpTimerInit(prAdapter, TRUE); + } + if (prAdapter->fgN9AssertDumpOngoing) { + + if (prAdapter->fgKeepPrintCoreDump) + DBGLOG(NIC, ERROR, "[DUMP_N9]%s:\n", + prEvent->aucBuffer); + if (!kalStrnCmp(prEvent->aucBuffer, + ";more log added here", 5) + || !kalStrnCmp(prEvent->aucBuffer, + ";[core dump start]", 5)) + prAdapter->fgKeepPrintCoreDump = FALSE; + + if (prAdapter->fgN9CorDumpFileOpend) { + if (kalWriteCorDumpFile( + prEvent->aucBuffer, + prEvent->u2PacketLength - + prChipInfo->event_hdr_size, + TRUE) != WLAN_STATUS_SUCCESS) { + DBGLOG(NIC, INFO, + "kalWriteN9CorDumpFile fail\n"); + } + } + wlanCorDumpTimerReset(prAdapter, TRUE); + } + } else { + /* prEvent->ucS2DIndex == S2D_INDEX_EVENT_C2H */ + if (!prAdapter->fgCr4AssertDumpOngoing) { + DBGLOG(NIC, ERROR, + "%s: EVENT_ID_ASSERT_DUMP\n", __func__); + DBGLOG(NIC, ERROR, + "\n[DUMP_Cr4]====CR4 ASSERT_DUMPSTART====\n"); + prAdapter->fgKeepPrintCoreDump = TRUE; + if (kalOpenCorDumpFile(FALSE) != WLAN_STATUS_SUCCESS) + DBGLOG(NIC, ERROR, "kalOpenCorDumpFile fail\n"); + else + prAdapter->fgCr4CorDumpFileOpend = TRUE; + + prAdapter->fgCr4AssertDumpOngoing = TRUE; + wlanCorDumpTimerInit(prAdapter, FALSE); + } + if (prAdapter->fgCr4AssertDumpOngoing) { + if (prAdapter->fgKeepPrintCoreDump) + DBGLOG(NIC, ERROR, "[DUMP_CR4]%s:\n", + prEvent->aucBuffer); + if (!kalStrnCmp(prEvent->aucBuffer, + ";more log added here", 5)) + prAdapter->fgKeepPrintCoreDump = FALSE; + + if (prAdapter->fgCr4CorDumpFileOpend) { + if (kalWriteCorDumpFile( + prEvent->aucBuffer, + prEvent->u2PacketLength - + prChipInfo->event_hdr_size, + FALSE) != WLAN_STATUS_SUCCESS) { + DBGLOG(NIC, ERROR, + "kalWriteN9CorDumpFile fail\n"); + } + } + wlanCorDumpTimerReset(prAdapter, FALSE); + } + } +} + +void nicEventRddSendPulse(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ + DBGLOG(RLM, INFO, "%s: EVENT_ID_RDD_SEND_PULSE\n", + __func__); + + nicEventRddPulseDump(prAdapter, prEvent->aucBuffer); +} + +void nicEventUpdateCoexPhyrate(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ + uint8_t i; + struct EVENT_UPDATE_COEX_PHYRATE *prEventUpdateCoexPhyrate; + + ASSERT(prAdapter); + + DBGLOG(NIC, LOUD, "%s\n", __func__); + + prEventUpdateCoexPhyrate = (struct EVENT_UPDATE_COEX_PHYRATE + *)(prEvent->aucBuffer); + + for (i = 0; i < (prAdapter->ucHwBssIdNum + 1); i++) { + prAdapter->aprBssInfo[i]->u4CoexPhyRateLimit = + prEventUpdateCoexPhyrate->au4PhyRateLimit[i]; + DBGLOG_LIMITED(NIC, TRACE, "Coex:BSS[%d]R:%d\n", i, + prAdapter->aprBssInfo[i]->u4CoexPhyRateLimit); + } + + prAdapter->ucSmarGearSupportSisoOnly = + prEventUpdateCoexPhyrate->ucSupportSisoOnly; + prAdapter->ucSmartGearWfPathSupport = + prEventUpdateCoexPhyrate->ucWfPathSupport; + + DBGLOG_LIMITED(NIC, INFO, "Smart Gear SISO:%d, WF:%d\n", + prAdapter->ucSmarGearSupportSisoOnly, + prAdapter->ucSmartGearWfPathSupport); +} + +void nicCmdEventQueryCnmInfo(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf) +{ + struct PARAM_GET_CNM_T *prCnmInfoQuery = NULL; + struct PARAM_GET_CNM_T *prCnmInfoEvent = NULL; + struct GLUE_INFO *prGlueInfo; + uint32_t u4QueryInfoLen; + + ASSERT(prAdapter); + ASSERT(prCmdInfo); + ASSERT(pucEventBuf); + + if (prCmdInfo->fgIsOid) { + prCnmInfoQuery = (struct PARAM_GET_CNM_T *) + prCmdInfo->pvInformationBuffer; + prCnmInfoEvent = (struct PARAM_GET_CNM_T *)pucEventBuf; + kalMemCopy(prCnmInfoQuery, prCnmInfoEvent, + sizeof(struct PARAM_GET_CNM_T)); + + prGlueInfo = prAdapter->prGlueInfo; + u4QueryInfoLen = sizeof(struct PARAM_GET_CNM_T); + kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, + u4QueryInfoLen, WLAN_STATUS_SUCCESS); + } +} + +void nicEventCnmInfo(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ + struct CMD_INFO *prCmdInfo; + + /* command response handling */ + prCmdInfo = nicGetPendingCmdInfo(prAdapter, + prEvent->ucSeqNum); + + if (prCmdInfo != NULL) { + if (prCmdInfo->pfCmdDoneHandler) + prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, + prEvent->aucBuffer); + else if (prCmdInfo->fgIsOid) + kalOidComplete(prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, + 0, WLAN_STATUS_SUCCESS); + /* return prCmdInfo */ + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + } +} + +#if CFG_SUPPORT_REPLAY_DETECTION +void nicCmdEventSetAddKey(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf) +{ + struct WIFI_CMD *prWifiCmd = NULL; + struct CMD_802_11_KEY *prCmdKey = NULL; + struct GLUE_INFO *prGlueInfo = NULL; + struct GL_DETECT_REPLAY_INFO *prDetRplyInfo = NULL; + + ASSERT(prAdapter); + ASSERT(prCmdInfo); + + if (prCmdInfo->fgIsOid) { + /* Update Set Information Length */ + kalOidComplete(prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, + prCmdInfo->u4InformationBufferLength, + WLAN_STATUS_SUCCESS); + } + + prGlueInfo = prAdapter->prGlueInfo; + + if (pucEventBuf) { + prWifiCmd = (struct WIFI_CMD *) (pucEventBuf); + prCmdKey = (struct CMD_802_11_KEY *) (prWifiCmd->aucBuffer); + + if (!IS_BSS_INDEX_AIS(prAdapter, + prCmdKey->ucBssIdx)) + return; + + /* AIS only */ + if (!prCmdKey->ucKeyType && + prCmdKey->ucKeyId >= 0 && prCmdKey->ucKeyId < 4) { + /* Only save data broadcast key info. + * ucKeyType == 1 means unicast key + * ucKeyId == 4 or ucKeyId == 5 means it is a PMF key + */ + prDetRplyInfo = aisGetDetRplyInfo(prAdapter, + prCmdKey->ucBssIdx); + + prDetRplyInfo->ucCurKeyId = prCmdKey->ucKeyId; + prDetRplyInfo->ucKeyType = prCmdKey->ucKeyType; + prDetRplyInfo->arReplayPNInfo[ + prCmdKey->ucKeyId].fgRekey = TRUE; + prDetRplyInfo->arReplayPNInfo[ + prCmdKey->ucKeyId].fgFirstPkt = TRUE; + DBGLOG(NIC, TRACE, + "[%d] Keyid is %d, ucKeyType is %d\n", + prCmdKey->ucBssIdx, + prCmdKey->ucKeyId, prCmdKey->ucKeyType); + } + } +} +void nicOidCmdTimeoutSetAddKey(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo) +{ + ASSERT(prAdapter); + + DBGLOG(NIC, WARN, "Wlan setaddkey timeout.\n"); + if (prCmdInfo->fgIsOid) + kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, + 0, WLAN_STATUS_FAILURE); +} +#endif + +#if CFG_SUPPORT_LOWLATENCY_MODE +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is in response of EVENT_ID_LOW_LATENCY_INFO form FW + * + * @param prAdapter Pointer to the Adapter structure. + * @param prEvent Pointer to the event structure. + * @retval none + */ +/*----------------------------------------------------------------------------*/ +void nicEventUpdateLowLatencyInfoStatus(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ + struct EVENT_LOW_LATENCY_INFO *prEvtLowLatencyInfo; + struct rtc_time tm; + struct timeval tv = { 0 }; +#if CFG_SUPPORT_DATA_STALL + uint8_t event[12]; + uint32_t iEventTime; + int8_t i, ret = 0; +#endif + + ASSERT(prAdapter); + + prEvtLowLatencyInfo = + (struct EVENT_LOW_LATENCY_INFO *)(prEvent->aucBuffer); + + do_gettimeofday(&tv); + rtc_time_to_tm(tv.tv_sec, &tm); + + DBGLOG_LIMITED(NIC, INFO, + "Low Latency DPP Info: drv cert=[%d], evt cert=[%d], evt dup=[%d] drv det=[%d] %02d-%02d %02d:%02d:%02d.%06u\n", + prAdapter->fgTxDupCertificate, + prEvtLowLatencyInfo->fgTxDupCert, + prEvtLowLatencyInfo->fgTxDupEnable, + prAdapter->fgEnTxDupDetect, + tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, + tm.tm_min, tm.tm_sec, (unsigned int)tv.tv_usec); + + if (prAdapter->fgTxDupCertificate != prEvtLowLatencyInfo->fgTxDupCert) { + + prAdapter->fgTxDupCertificate = + prEvtLowLatencyInfo->fgTxDupCert; + +#if CFG_SUPPORT_DATA_STALL + ret = sprintf(event, "%03d%02d%06u", + EVENT_TX_DUP_CERT_CHANGE, + tm.tm_sec, + (unsigned int)tv.tv_usec); + if (ret < 0 || ret > sizeof(event)) { + DBGLOG_LIMITED(NIC, INFO, "sprintf failed:%d\n", ret); + return; + } + + iEventTime = 0; + for (i = 0 ; i < 8 ; i++) + iEventTime = iEventTime*10 + atoi(event[i]); + + KAL_REPORT_ERROR_EVENT(prAdapter, + iEventTime, + (uint16_t)sizeof(uint32_t), + 0, + TRUE); +#endif + } + +#if CFG_SUPPORT_DATA_STALL + if (prAdapter->fgTxDupCertificate) { + + /* Indicate detect result to driver if detect on */ + if (prAdapter->fgEnTxDupDetect) { + if (prEvtLowLatencyInfo->fgTxDupEnable) { + ret = sprintf(event, "%03d%02d%06u", + EVENT_TX_DUP_ON, + tm.tm_sec, + (unsigned int)tv.tv_usec); + } else { + ret = sprintf(event, "%03d%02d%06u", + EVENT_TX_DUP_OFF, + tm.tm_sec, + (unsigned int)tv.tv_usec); + } + if (ret < 0 || ret > sizeof(event)) { + DBGLOG_LIMITED(NIC, INFO, + "sprintf failed:%d\n", ret); + return; + } + + /* Convert 11 byte string like '10121316927' to + * 8 digits uint32 integer 10121316 + */ + iEventTime = 0; + for (i = 0 ; i < 8 ; i++) + iEventTime = iEventTime*10 + atoi(event[i]); + + KAL_REPORT_ERROR_EVENT(prAdapter, + iEventTime, + (uint16_t)sizeof(uint32_t), + 0, + TRUE); + } + } +#endif +} +#endif + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/nic_ext_cmd_event.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/nic_ext_cmd_event.c new file mode 100644 index 0000000000000000000000000000000000000000..c83028bd56ba6b332b8381db13794aa479ad52a1 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/nic_ext_cmd_event.c @@ -0,0 +1,482 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ + +/*! \file nic_ext_cmd_event.c + * \brief Callback functions for Command packets. + * + * Various Event packet handlers which will be setup in the callback + * function of a command packet. + */ + + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ +#if (CFG_SUPPORT_CONNAC2X == 1) + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" +#include "gl_ate_agent.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D A T A + ******************************************************************************* + */ +static uint32_t +wlanSendSetQueryExtCmd2WA( + struct ADAPTER *prAdapter, + uint8_t ucCID, + uint8_t ucExtCID, + u_int8_t fgSetQuery, + u_int8_t fgNeedResp, + u_int8_t fgIsOid, + PFN_CMD_DONE_HANDLER pfCmdDoneHandler, + PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler, + uint32_t u4SetQueryInfoLen, + uint8_t *pucInfoBuffer, + void *pvSetQueryBuffer, + uint32_t u4SetQueryBufferLen) +{ + struct GLUE_INFO *prGlueInfo; + struct CMD_INFO *prCmdInfo; + uint8_t *pucCmdBuf; + struct mt66xx_chip_info *prChipInfo; + + prGlueInfo = prAdapter->prGlueInfo; + prChipInfo = prAdapter->chip_info; + prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, + (prChipInfo->u2CmdTxHdrSize + u4SetQueryInfoLen)); + + DEBUGFUNC("wlanSendSetQueryCmd"); + + if (!prCmdInfo) { + DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); + return WLAN_STATUS_FAILURE; + } + + /* Setup common CMD Info Packet */ + prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; + prCmdInfo->u2InfoBufLen = + (uint16_t)(prChipInfo->u2CmdTxHdrSize + u4SetQueryInfoLen); + prCmdInfo->pfCmdDoneHandler = pfCmdDoneHandler; + prCmdInfo->pfCmdTimeoutHandler = pfCmdTimeoutHandler; + prCmdInfo->fgIsOid = fgIsOid; + prCmdInfo->ucCID = ucCID; + prCmdInfo->fgSetQuery = fgSetQuery; + prCmdInfo->fgNeedResp = fgNeedResp; + prCmdInfo->u4SetInfoLen = u4SetQueryInfoLen; + prCmdInfo->pvInformationBuffer = pvSetQueryBuffer; + prCmdInfo->u4InformationBufferLength = u4SetQueryBufferLen; + + /* Setup WIFI_CMD_T (no payload) */ + NIC_FILL_CMD_TX_HDR(prAdapter, + prCmdInfo->pucInfoBuffer, + prCmdInfo->u2InfoBufLen, + prCmdInfo->ucCID, + CMD_PACKET_TYPE_ID, + &prCmdInfo->ucCmdSeqNum, + prCmdInfo->fgSetQuery, + &pucCmdBuf, FALSE, ucExtCID, S2D_INDEX_CMD_H2C); + if (u4SetQueryInfoLen > 0 && pucInfoBuffer != NULL) + kalMemCopy(pucCmdBuf, pucInfoBuffer, u4SetQueryInfoLen); + + /* insert into prCmdQueue */ + kalEnqueueCommand(prGlueInfo, (struct QUE_ENTRY *) prCmdInfo); + + /* wakeup txServiceThread later */ + GLUE_SET_EVENT(prGlueInfo); + return WLAN_STATUS_PENDING; +} + +static uint32_t StaRecUpdateBasic( + struct ADAPTER *pAd, + uint8_t *pMsgBuf, + void *args) +{ + struct STA_RECORD *pStaRecCfg = (struct STA_RECORD *)args; + struct STAREC_COMMON_T StaRecCommon = {0}; + + /* Fill TLV format */ + StaRecCommon.u2Tag = STA_REC_BASIC; + StaRecCommon.u2Length = sizeof(struct STAREC_COMMON_T); + StaRecCommon.u4ConnectionType = CPU_TO_LE32(CONNECTION_INFRA_STA); + StaRecCommon.ucConnectionState = pStaRecCfg->ucStaState; + /* New info to indicate this is new way to update STAREC */ + StaRecCommon.u2ExtraInfo = STAREC_COMMON_EXTRAINFO_V2; + + if (pStaRecCfg->ucStaState == STA_STATE_1) + StaRecCommon.u2ExtraInfo |= STAREC_COMMON_EXTRAINFO_NEWSTAREC; + +#if 0 /* TODO: soft ap mode */ +#ifdef CONFIG_AP_SUPPORT + if (pEntry) { + StaRecCommon.ucIsQBSS = + CLIENT_STATUS_TEST_FLAG(pEntry, + fCLIENT_STATUS_WMM_CAPABLE) ? + TRUE : FALSE; + StaRecCommon.u2AID = cpu2le16(pEntry->Aid); + } + +#endif /* CONFIG_AP_SUPPORT */ +#endif + + StaRecCommon.ucIsQBSS = pStaRecCfg->fgIsQoS; + + StaRecCommon.u2AID = CPU_TO_LE16(pStaRecCfg->u2AssocId); + kalMemCopy(&StaRecCommon.aucPeerMacAddr[0], &pStaRecCfg->aucMacAddr[0], + MAC_ADDR_LEN); + + /* Append this feature */ +#if 0 /* TODO: big endian platform */ +#ifdef RT_BIG_ENDIAN + StaRecCommon.u2Tag = cpu2le16(StaRecCommon.u2Tag); + StaRecCommon.u2Length = cpu2le16(StaRecCommon.u2Length); + StaRecCommon.u2ExtraInfo = cpu2le16(StaRecCommon.u2ExtraInfo); +#endif +#endif + kalMemCopy(pMsgBuf, + (char *)&StaRecCommon, + sizeof(struct STAREC_COMMON_T)); + return 0; +} + +static uint32_t BssInfoUpdateBasic( + struct ADAPTER *pAd, + uint8_t *pMsgBuf, + uint8_t ucBssIdx) +{ + struct BSSINFO_BASIC_T rBssInfo = {0}; + struct BSS_INFO *prBssInfo; + struct AIS_SPECIFIC_BSS_INFO *prAisSpecBssInfo = + aisGetAisSpecBssInfo(pAd, ucBssIdx); + + prBssInfo = pAd->aprBssInfo[ucBssIdx]; + /* Tag assignment */ + rBssInfo.u2Tag = BSS_INFO_BASIC; + rBssInfo.u2Length = sizeof(struct BSSINFO_BASIC_T); + /* content */ + kalMemCopy(rBssInfo.aucBSSID, prBssInfo->aucBSSID, MAC_ADDR_LEN); + rBssInfo.ucBcMcWlanidx = ucBssIdx; + rBssInfo.ucActive = TRUE; + rBssInfo.ucWmmIdx = prBssInfo->ucWmmQueSet; + rBssInfo.ucCipherSuit = + prAisSpecBssInfo->ucKeyAlgorithmId; + +/* WA didn't use */ +/* +* rBssInfo.u4NetworkType = NETWORK_TYPE_AIS; +* rBssInfo.u2BcnInterval = 100; +* rBssInfo.ucDtimPeriod = 1; +*/ + + /* Append this feature */ + kalMemCopy(pMsgBuf, + (char *)&rBssInfo, + sizeof(struct BSSINFO_BASIC_T)); + return 0; +} + +static uint32_t BssInfoUpdateConnectOwnDev( + struct ADAPTER *pAd, + uint8_t *pMsgBuf, + uint8_t ucBssIdx) +{ + struct BSSINFO_CONNECT_OWN_DEV_T rBssInfo = {0}; + struct BSS_INFO *prBssInfo; + + prBssInfo = pAd->aprBssInfo[ucBssIdx]; + /* Tag assignment */ + rBssInfo.u2Tag = BSS_INFO_OWN_MAC; + rBssInfo.u2Length = sizeof(struct BSSINFO_CONNECT_OWN_DEV_T); + /* content */ + rBssInfo.ucHwBSSIndex = ucBssIdx; + rBssInfo.ucOwnMacIdx = prBssInfo->ucOwnMacIndex; + rBssInfo.ucConnectionType = CPU_TO_LE32(CONNECTION_INFRA_STA); + + /* Append this feature */ + kalMemCopy(pMsgBuf, + (char *)&rBssInfo, + sizeof(struct BSSINFO_CONNECT_OWN_DEV_T)); + return 0; +} + +static uint32_t DevInfoUpdateBasic( + struct ADAPTER *pAd, + uint8_t *pMsgBuf, + uint8_t ucBssIdx) +{ + struct CMD_DEVINFO_ACTIVE_T rDevInfo = {0}; + struct BSS_INFO *prBssInfo; + + prBssInfo = pAd->aprBssInfo[ucBssIdx]; + + /* Tag assignment */ + rDevInfo.u2Tag = DEV_INFO_ACTIVE; + rDevInfo.u2Length = sizeof(struct CMD_DEVINFO_ACTIVE_T); + /* content */ + kalMemCopy(rDevInfo.aucOwnMacAddr, + prBssInfo->aucOwnMacAddr, MAC_ADDR_LEN); + rDevInfo.ucActive = TRUE; + rDevInfo.ucDbdcIdx = 0; + + /* Append this feature */ + kalMemCopy(pMsgBuf, + (char *)&rDevInfo, + sizeof(struct CMD_DEVINFO_ACTIVE_T)); + return 0; +} + +uint32_t CmdExtStaRecUpdate2WA( + struct ADAPTER *pAd, + struct STA_RECORD *pStaRecCfg) +{ + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + uint32_t size; + struct CMD_STAREC_UPDATE_T *prCmdContent; + + size = sizeof(struct CMD_STAREC_UPDATE_T); + size += sizeof(struct STAREC_COMMON_T); + + prCmdContent = cnmMemAlloc(pAd, RAM_TYPE_BUF, size); + if (!prCmdContent) { + log_dbg(MEM, WARN, + "%s: command allocation failed\n", + __func__); + + return WLAN_STATUS_RESOURCES; + } + + prCmdContent->ucBssIndex = pStaRecCfg->ucBssIndex; + prCmdContent->ucWlanIdx = pStaRecCfg->ucWlanIndex; + prCmdContent->ucMuarIdx = 0; + + StaRecUpdateBasic(pAd, + (uint8_t *)prCmdContent+sizeof(struct CMD_STAREC_UPDATE_T), + (void *)pStaRecCfg); + + rWlanStatus = wlanSendSetQueryExtCmd2WA(pAd, + CMD_ID_LAYER_0_EXT_MAGIC_NUM, + EXT_CMD_ID_STAREC_UPDATE, + TRUE, + FALSE, + TRUE, + NULL, + nicOidCmdTimeoutCommon, + size, + (uint8_t *) (prCmdContent), + NULL, 0); + cnmMemFree(pAd, prCmdContent); + return rWlanStatus; +} + +#if (CFG_SUPPORT_DMASHDL_SYSDVT) +/* Inform DVT item to WA */ +uint32_t CmdExtDmaShdlDvt2WA( + struct ADAPTER *pAd, + uint8_t ucItemNo, + uint8_t ucSubItemNo) +{ + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + uint32_t size; + struct EXT_CMD_CR4_DMASHDL_DVT_T *prCmdContent; + + size = sizeof(struct EXT_CMD_CR4_DMASHDL_DVT_T); + + prCmdContent = cnmMemAlloc(pAd, RAM_TYPE_BUF, size); + if (!prCmdContent) { + log_dbg(MEM, WARN, + "%s: command allocation failed\n", + __func__); + + return WLAN_STATUS_RESOURCES; + } + + prCmdContent->ucItemNo = ucItemNo; + prCmdContent->ucSubItemNo = ucSubItemNo; + + rWlanStatus = wlanSendSetQueryExtCmd2WA(pAd, + CMD_ID_LAYER_0_EXT_MAGIC_NUM, + EXT_CMD_ID_CR4_DMASHDL_DVT, + TRUE, + FALSE, + TRUE, + NULL, + nicOidCmdTimeoutCommon, + size, + (uint8_t *) (prCmdContent), + NULL, 0); + cnmMemFree(pAd, prCmdContent); + return rWlanStatus; +} +#endif /* CFG_SUPPORT_DMASHDL_SYSDVT */ + +uint32_t CmdExtBssInfoUpdate2WA( + struct ADAPTER *pAd, + uint8_t ucBssIndex) +{ + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + uint32_t size; + struct BSS_INFO *prBssInfo; + struct CMD_BSSINFO_UPDATE_T *prCmdContent; + + ASSERT(pAd); + ASSERT(ucBssIndex <= pAd->ucHwBssIdNum); + + prBssInfo = pAd->aprBssInfo[ucBssIndex]; + + size = sizeof(struct CMD_BSSINFO_UPDATE_T); + size += sizeof(struct BSSINFO_BASIC_T); + size += sizeof(struct BSSINFO_CONNECT_OWN_DEV_T); + + prCmdContent = cnmMemAlloc(pAd, RAM_TYPE_BUF, size); + if (!prCmdContent) { + log_dbg(MEM, WARN, + "%s: command allocation failed\n", + __func__); + return WLAN_STATUS_RESOURCES; + } + + prCmdContent->ucBssIndex = ucBssIndex; + prCmdContent->u2TotalElementNum = 1; + + BssInfoUpdateBasic(pAd, + (uint8_t *)prCmdContent+sizeof(struct CMD_BSSINFO_UPDATE_T), + ucBssIndex); + + BssInfoUpdateConnectOwnDev(pAd, + (uint8_t *)prCmdContent + + sizeof(struct CMD_BSSINFO_UPDATE_T) + + sizeof(struct BSSINFO_BASIC_T), + ucBssIndex); + + rWlanStatus = wlanSendSetQueryExtCmd2WA(pAd, + CMD_ID_LAYER_0_EXT_MAGIC_NUM, + EXT_CMD_ID_BSSINFO_UPDATE, + TRUE, + FALSE, + TRUE, + NULL, + nicOidCmdTimeoutCommon, + size, + (uint8_t *) (prCmdContent), + NULL, 0); + cnmMemFree(pAd, prCmdContent); + return rWlanStatus; +} + +uint32_t CmdExtDevInfoUpdate2WA( + struct ADAPTER *pAd, + uint8_t ucBssIndex) +{ + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + uint32_t size; + struct CMD_DEVINFO_UPDATE_T *prCmdContent; + struct BSS_INFO *prBssInfo; + + prBssInfo = pAd->aprBssInfo[ucBssIndex]; + + ASSERT(pAd); + + size = sizeof(struct CMD_DEVINFO_UPDATE_T); + size += sizeof(struct CMD_DEVINFO_ACTIVE_T); + + prCmdContent = cnmMemAlloc(pAd, RAM_TYPE_BUF, size); + if (!prCmdContent) { + log_dbg(MEM, WARN, + "%s: command allocation failed\n", + __func__); + + return WLAN_STATUS_RESOURCES; + } + + prCmdContent->ucOwnMacIdx = prBssInfo->ucOwnMacIndex; + prCmdContent->u2TotalElementNum = 1; + + DevInfoUpdateBasic(pAd, + (uint8_t *)prCmdContent+sizeof(struct CMD_DEVINFO_UPDATE_T), + ucBssIndex); + + rWlanStatus = wlanSendSetQueryExtCmd2WA(pAd, + CMD_ID_LAYER_0_EXT_MAGIC_NUM, + EXT_CMD_ID_DEVINFO_UPDATE, + TRUE, + FALSE, + TRUE, + NULL, + nicOidCmdTimeoutCommon, + size, + (uint8_t *) (prCmdContent), + NULL, 0); + cnmMemFree(pAd, prCmdContent); + return rWlanStatus; +} + +#endif /* CFG_SUPPORT_CONNAC2X == 1 */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/nic_pwr_mgt.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/nic_pwr_mgt.c new file mode 100644 index 0000000000000000000000000000000000000000..48da5e3f0f2967becf239778aedacded6672296c --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/nic_pwr_mgt.c @@ -0,0 +1,424 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/ + * MT6620_WIFI_DRIVER_V2_3/nic/nic_pwr_mgt.c#1 + */ + +/*! \file "nic_pwr_mgt.c" + * \brief In this file we define the STATE and EVENT for Power Management + * FSM. + * The SCAN FSM is responsible for performing SCAN behavior when the Arbiter + * enter ARB_STATE_SCAN. The STATE and EVENT for SCAN FSM are defined here + * with detail description. + */ + + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +void nicpmWakeUpWiFi(IN struct ADAPTER *prAdapter) +{ + if (!nicVerifyChipID(prAdapter)) { + DBGLOG(INIT, ERROR, "Chip id verify error!\n"); + return; + } + HAL_WAKE_UP_WIFI(prAdapter); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used to process the POWER ON procedure. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void nicpmSetFWOwn(IN struct ADAPTER *prAdapter, + IN u_int8_t fgEnableGlobalInt) +{ + halSetFWOwn(prAdapter, fgEnableGlobalInt); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used to process the POWER OFF procedure. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +u_int8_t nicpmSetDriverOwn(IN struct ADAPTER *prAdapter) +{ + return halSetDriverOwn(prAdapter); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used to set ACPI power mode to D0. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +u_int8_t nicpmSetAcpiPowerD0(IN struct ADAPTER *prAdapter) +{ + +#if 0 + uint32_t u4Status = WLAN_STATUS_SUCCESS; + uint32_t u4Value = 0, u4WHISR = 0; + uint16_t au2TxCount[16]; + uint32_t i; +#if CFG_ENABLE_FW_DOWNLOAD + uint32_t u4FwImgLength, u4FwLoadAddr, u4Cr4FwImgLength; + void *prFwMappingHandle; + void *pvFwImageMapFile = NULL; + void *pvCr4FwImageMapFile = NULL; +#if CFG_ENABLE_FW_DIVIDED_DOWNLOAD + struct FIRMWARE_DIVIDED_DOWNLOAD *prFwHead; + u_int8_t fgValidHead = TRUE; + +#endif +#endif + + DEBUGFUNC("nicpmSetAcpiPowerD0"); + + ASSERT(prAdapter); + + do { + /* 0. Reset variables in ADAPTER_T */ + prAdapter->fgIsFwOwn = TRUE; + prAdapter->fgWiFiInSleepyState = FALSE; + prAdapter->rAcpiState = ACPI_STATE_D0; + prAdapter->fgIsEnterD3ReqIssued = FALSE; + +#if defined(MT6630) + /* 1. Request Ownership to enter F/W download state */ + ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); +#if !CFG_ENABLE_FULL_PM + nicpmSetDriverOwn(prAdapter); +#endif + + /* 2. Initialize the Adapter */ + u4Status = nicInitializeAdapter(prAdapter); + if (u4Status != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, ERROR, "nicInitializeAdapter failed!\n"); + u4Status = WLAN_STATUS_FAILURE; + break; + } +#endif + +#if CFG_ENABLE_FW_DOWNLOAD + prFwMappingHandle = + kalFirmwareImageMapping(prAdapter->prGlueInfo, + &pvFwImageMapFile, &u4FwImgLength, + &pvCr4FwImageMapFile, &u4Cr4FwImgLength); + if (!prFwMappingHandle) { + DBGLOG(INIT, ERROR, + "Fail to load FW image from file!\n"); + pvFwImageMapFile = NULL; + } +#if defined(MT6630) + if (pvFwImageMapFile) { + /* 3.1 disable interrupt, + * download is done by polling mode only + */ + nicDisableInterrupt(prAdapter); + + /* 3.2 Initialize Tx Resource to fw download state */ + nicTxInitResetResource(prAdapter); + + /* 3.3 FW download here */ + u4FwLoadAddr = + kalGetFwLoadAddress(prAdapter->prGlueInfo); + +#if CFG_ENABLE_FW_DIVIDED_DOWNLOAD + /* 3a. parse file header for decision of + * divided firmware download or not + */ + prFwHead = + (struct FIRMWARE_DIVIDED_DOWNLOAD *) + ((uint8_t *) + pvFwImageMapFile + u4FwImgLength - + (2 * sizeof(struct FWDL_SECTION_INFO))); +#if 0 + if (prFwHead->u4Signature == MTK_WIFI_SIGNATURE && + prFwHead->u4CRC == wlanCRC32( + (uint8_t *) pvFwImageMapFile + + u4CRCOffset, + u4FwImgLength - u4CRCOffset)) { + fgValidHead = TRUE; + } else { + fgValidHead = FALSE; + } +#endif + /* 3b. engage divided firmware downloading */ + if (fgValidHead == TRUE) { + wlanFwDvdDwnloadHandler(prAdapter, prFwHead, + pvFwImageMapFile, &u4Status); + } else +#endif + { + if (wlanImageSectionConfig(prAdapter, + u4FwLoadAddr, + u4FwImgLength, TRUE) + != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, ERROR, + "Firmware download configuration failed!\n"); + + u4Status = WLAN_STATUS_FAILURE; + break; + } + wlanFwDwnloadHandler(prAdapter, u4FwImgLength, + pvFwImageMapFile, &u4Status); + } + /* escape to top */ + if (u4Status != WLAN_STATUS_SUCCESS) { + kalFirmwareImageUnmapping(prAdapter->prGlueInfo, + prFwMappingHandle, pvFwImageMapFile, + pvCr4FwImageMapFile); + break; + } +#if !CFG_ENABLE_FW_DOWNLOAD_ACK + /* Send INIT_CMD_ID_QUERY_PENDING_ERROR command + * and wait for response + */ + if (wlanImageQueryStatus(prAdapter) != + WLAN_STATUS_SUCCESS) { + kalFirmwareImageUnmapping(prAdapter->prGlueInfo, + prFwMappingHandle, pvFwImageMapFile, + pvCr4FwImageMapFile); + u4Status = WLAN_STATUS_FAILURE; + break; + } +#endif + + kalFirmwareImageUnmapping(prAdapter->prGlueInfo, + prFwMappingHandle, pvFwImageMapFile, + pvCr4FwImageMapFile); + } else { + u4Status = WLAN_STATUS_FAILURE; + break; + } + + /* 4. send Wi-Fi Start command */ +#if CFG_OVERRIDE_FW_START_ADDRESS + wlanConfigWifiFunc(prAdapter, TRUE, + kalGetFwStartAddress(prAdapter->prGlueInfo)); +#else + wlanConfigWifiFunc(prAdapter, FALSE, 0); +#endif +#endif +#endif + + /* 5. check Wi-Fi FW asserts ready bit */ + DBGLOG(INIT, TRACE, + "wlanAdapterStart(): Waiting for Ready bit..\n"); + i = 0; + while (1) { + HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value); + + if (u4Value & WCIR_WLAN_READY) { + DBGLOG(INIT, TRACE, "Ready bit asserted\n"); + break; + } else if ( + kalIsCardRemoved( + prAdapter->prGlueInfo) == TRUE + || fgIsBusAccessFailed == TRUE) { + u4Status = WLAN_STATUS_FAILURE; + break; + } else if (i >= CFG_RESPONSE_POLLING_TIMEOUT) { + DBGLOG(INIT, ERROR, + "Waiting for Ready bit: Timeout\n"); + u4Status = WLAN_STATUS_FAILURE; + break; + } + i++; + kalMsleep(10); + } + + if (u4Status == WLAN_STATUS_SUCCESS) { + /* 6.1 reset interrupt status */ + HAL_READ_INTR_STATUS(prAdapter, 4, (uint8_t *)&u4WHISR); + if (HAL_IS_TX_DONE_INTR(u4WHISR)) + HAL_READ_TX_RELEASED_COUNT(prAdapter, + au2TxCount); + + /* 6.2 reset TX Resource for normal operation */ + nicTxResetResource(prAdapter); + + /* 6.3 Enable interrupt */ + nicEnableInterrupt(prAdapter); + + /* 6.4 Update basic configuration */ + wlanUpdateBasicConfig(prAdapter); + + /* 6.5 Apply Network Address */ + nicApplyNetworkAddress(prAdapter); + + /* 6.6 indicate disconnection as default status */ + kalIndicateStatusAndComplete(prAdapter->prGlueInfo, + WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); + } + + RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); + + /* MGMT Initialization */ + nicInitMGMT(prAdapter, NULL); + + } while (FALSE); + + if (u4Status != WLAN_STATUS_SUCCESS) + return FALSE; + else + return TRUE; +#else + return TRUE; +#endif +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is used to set ACPI power mode to D3. + * + * @param prAdapter pointer to the Adapter handler + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +u_int8_t nicpmSetAcpiPowerD3(IN struct ADAPTER *prAdapter) +{ + /* UINT_32 i; */ + + ASSERT(prAdapter); + +#if 0 + /* 1. MGMT - unitialization */ + nicUninitMGMT(prAdapter); + + /* 2. Disable Interrupt */ + nicDisableInterrupt(prAdapter); + + /* 3. emit CMD_NIC_POWER_CTRL command packet */ + wlanSendNicPowerCtrlCmd(prAdapter, 1); + + /* 4. Clear Interrupt Status */ + i = 0; + while (i < CFG_IST_LOOP_COUNT + && nicProcessIST(prAdapter) != WLAN_STATUS_NOT_INDICATING) { + i++; + }; + + /* 5. Remove pending TX */ + nicTxRelease(prAdapter, TRUE); + + /* 5.1 clear pending Security / Management Frames */ + kalClearSecurityFrames(prAdapter->prGlueInfo); + kalClearMgmtFrames(prAdapter->prGlueInfo); + + /* 5.2 clear pending TX packet queued in glue layer */ + kalFlushPendingTxPackets(prAdapter->prGlueInfo); + + /* 6. Set Onwership to F/W */ + nicpmSetFWOwn(prAdapter, FALSE); + + /* 7. Set variables */ + prAdapter->rAcpiState = ACPI_STATE_D3; +#endif + return TRUE; +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/nic_rate.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/nic_rate.c new file mode 100644 index 0000000000000000000000000000000000000000..c64deedf2c0dd6c5349d08663f013543d6284dd5 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/nic_rate.c @@ -0,0 +1,1181 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ + +/*! \file "nic_rate.c" + * \brief This file contains the transmission rate handling routines. + * + * This file contains the transmission rate handling routines for setting up + * ACK/CTS Rate, Highest Tx Rate, Lowest Tx Rate, Initial Tx Rate and do + * conversion between Rate Set and Data Rates. + */ + + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#define RA_FIXEDRATE_FIELD_CCK_MCS_S 0 +#define RA_FIXEDRATE_FIELD_CCK_MCS_E 1 +#define RA_FIXEDRATE_FIELD_S_PREAMBLE 2 +#define RA_FIXEDRATE_FIELD_MCS_S 0 +#define RA_FIXEDRATE_FIELD_MCS_E 5 + +#define RA_FIXEDRATE_V1_FIELD_MODE_S 6 +#define RA_FIXEDRATE_V1_FIELD_MODE_E 8 +#define RA_FIXEDRATE_V1_FIELD_VHTNSS_S 9 +#define RA_FIXEDRATE_V1_FIELD_VHTNSS_E 10 + +#define RA_FIXEDRATE_V2_FIELD_MODE_S 6 +#define RA_FIXEDRATE_V2_FIELD_MODE_E 10 +#define RA_FIXEDRATE_V2_FIELD_VHTNSS_S 12 +#define RA_FIXEDRATE_V2_FIELD_VHTNSS_E 14 + +#define RA_FIXEDRATE_FIELD_STBC 11 + +#define RA_FIXEDRATE_FIELD_HE_LTF_MASK BITS(15, 16) +#define RA_FIXEDRATE_FIELD_HE_LTF_OFFSET 15 +#define RA_FIXEDRATE_FIELD_HE_GI_MASK BITS(17, 18) +#define RA_FIXEDRATE_FIELD_HE_GI_OFFSET 17 +#define RA_FIXEDRATE_FIELD_HE_ER_DCM 19 +#define RA_FIXEDRATE_FIELD_HE_ER_106 20 + +#define RA_FIXEDRATE_FIELD_FORMAT_VER_MASK BITS(23, 24) +#define RA_FIXEDRATE_FIELD_FORMAT_VER_OFFSET 23 + +#define RA_FIXEDRATE_FIELD_BAND 25 +#define RA_FIXEDRATE_FIELD_BW_S 26 +#define RA_FIXEDRATE_FIELD_BW_E 27 +#define RA_FIXEDRATE_FIELD_SPEEN 28 +#define RA_FIXEDRATE_FIELD_LDPC 29 +#define RA_FIXEDRATE_FIELD_SGI 30 +#define RA_FIXEDRATE BIT(31) + + +const uint16_t au2RateCCKLong[CCK_RATE_NUM] = { + RATE_CCK_1M_LONG, /* RATE_1M_INDEX = 0 */ + RATE_CCK_2M_LONG, /* RATE_2M_INDEX */ + RATE_CCK_5_5M_LONG, /* RATE_5_5M_INDEX */ + RATE_CCK_11M_LONG /* RATE_11M_INDEX */ +}; + +const uint16_t au2RateCCKShort[CCK_RATE_NUM] = { + RATE_CCK_1M_LONG, /* RATE_1M_INDEX = 0 */ + RATE_CCK_2M_SHORT, /* RATE_2M_INDEX */ + RATE_CCK_5_5M_SHORT, /* RATE_5_5M_INDEX */ + RATE_CCK_11M_SHORT /* RATE_11M_INDEX */ +}; + +const uint16_t au2RateOFDM[OFDM_RATE_NUM] = { + RATE_OFDM_6M, /* RATE_6M_INDEX */ + RATE_OFDM_9M, /* RATE_9M_INDEX */ + RATE_OFDM_12M, /* RATE_12M_INDEX */ + RATE_OFDM_18M, /* RATE_18M_INDEX */ + RATE_OFDM_24M, /* RATE_24M_INDEX */ + RATE_OFDM_36M, /* RATE_36M_INDEX */ + RATE_OFDM_48M, /* RATE_48M_INDEX */ + RATE_OFDM_54M /* RATE_54M_INDEX */ +}; + +const uint16_t au2RateHTMixed[HT_RATE_NUM] = { + RATE_MM_MCS_32, /* RATE_MCS32_INDEX, */ + RATE_MM_MCS_0, /* RATE_MCS0_INDEX, */ + RATE_MM_MCS_1, /* RATE_MCS1_INDEX, */ + RATE_MM_MCS_2, /* RATE_MCS2_INDEX, */ + RATE_MM_MCS_3, /* RATE_MCS3_INDEX, */ + RATE_MM_MCS_4, /* RATE_MCS4_INDEX, */ + RATE_MM_MCS_5, /* RATE_MCS5_INDEX, */ + RATE_MM_MCS_6, /* RATE_MCS6_INDEX, */ + RATE_MM_MCS_7 /* RATE_MCS7_INDEX, */ +}; + +const uint16_t au2RateHTGreenField[HT_RATE_NUM] = { + RATE_GF_MCS_32, /* RATE_MCS32_INDEX, */ + RATE_GF_MCS_0, /* RATE_MCS0_INDEX, */ + RATE_GF_MCS_1, /* RATE_MCS1_INDEX, */ + RATE_GF_MCS_2, /* RATE_MCS2_INDEX, */ + RATE_GF_MCS_3, /* RATE_MCS3_INDEX, */ + RATE_GF_MCS_4, /* RATE_MCS4_INDEX, */ + RATE_GF_MCS_5, /* RATE_MCS5_INDEX, */ + RATE_GF_MCS_6, /* RATE_MCS6_INDEX, */ + RATE_GF_MCS_7, /* RATE_MCS7_INDEX, */ +}; + +const uint16_t au2RateVHT[VHT_RATE_NUM] = { + RATE_VHT_MCS_0, /* RATE_MCS0_INDEX, */ + RATE_VHT_MCS_1, /* RATE_MCS1_INDEX, */ + RATE_VHT_MCS_2, /* RATE_MCS2_INDEX, */ + RATE_VHT_MCS_3, /* RATE_MCS3_INDEX, */ + RATE_VHT_MCS_4, /* RATE_MCS4_INDEX, */ + RATE_VHT_MCS_5, /* RATE_MCS5_INDEX, */ + RATE_VHT_MCS_6, /* RATE_MCS6_INDEX, */ + RATE_VHT_MCS_7, /* RATE_MCS7_INDEX, */ + RATE_VHT_MCS_8, /* RATE_MCS8_INDEX, */ + RATE_VHT_MCS_9 /* RATE_MCS9_INDEX, */ +}; + +/* in unit of 100kb/s */ +const struct EMU_MAC_RATE_INFO arMcsRate2PhyRate[] = { + /* Phy Rate Code, + * BW20, BW20 SGI, BW40, BW40 SGI, BW80, BW80 SGI, BW160, BW160 SGI + */ + RATE_INFO(PHY_RATE_MCS0, 65, 72, 135, 150, 293, 325, 585, 650), + RATE_INFO(PHY_RATE_MCS1, 130, 144, 270, 300, 585, 650, 1170, 1300), + RATE_INFO(PHY_RATE_MCS2, 195, 217, 405, 450, 878, 975, 1755, 1950), + RATE_INFO(PHY_RATE_MCS3, 260, 289, 540, 600, 1170, 1300, 2340, 2600), + RATE_INFO(PHY_RATE_MCS4, 390, 433, 810, 900, 1755, 1950, 3510, 3900), + RATE_INFO(PHY_RATE_MCS5, 520, 578, 1080, 1200, 2340, 2600, 4680, 5200), + RATE_INFO(PHY_RATE_MCS6, 585, 650, 1215, 1350, 2633, 2925, 5265, 5850), + RATE_INFO(PHY_RATE_MCS7, 650, 722, 1350, 1500, 2925, 3250, 5850, 6500), + RATE_INFO(PHY_RATE_MCS8, 780, 867, 1620, 1800, 3510, 3900, 7020, 7800), + RATE_INFO(PHY_RATE_MCS9, 867, 963, 1800, 2000, 3900, 4333, 7800, 8667), + RATE_INFO(PHY_RATE_MCS32, 0, 0, 60, 67, 0, 0, 0, 0) +}; + +/* in uint of 500kb/s */ +const uint8_t aucHwRate2PhyRate[] = { + RATE_1M, /*1M long */ + RATE_2M, /*2M long */ + RATE_5_5M, /*5.5M long */ + RATE_11M, /*11M long */ + RATE_1M, /*1M short invalid */ + RATE_2M, /*2M short */ + RATE_5_5M, /*5.5M short */ + RATE_11M, /*11M short */ + RATE_48M, /*48M */ + RATE_24M, /*24M */ + RATE_12M, /*12M */ + RATE_6M, /*6M */ + RATE_54M, /*54M */ + RATE_36M, /*36M */ + RATE_18M, /*18M */ + RATE_9M /*9M */ +}; +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +char *HW_TX_MODE_STR[] = { + "CCK", "OFDM", "MM", "GF", "VHT", "PLR", + "N/A", "N/A", "HE_SU", "HE_ER", "HE_TRIG", "HE_MU"}; +char *HW_TX_RATE_CCK_STR[] = {"1M", "2M", "5.5M", "11M", "N/A"}; +char *HW_TX_RATE_OFDM_STR[] = {"6M", "9M", "12M", "18M", "24M", "36M", + "48M", "54M", "N/A"}; +char *HW_TX_RATE_BW[] = {"BW20", "BW40", "BW80", "BW160/BW8080", "N/A"}; + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ +#define TX_GET_GI(_gi, _mode) \ + ((_mode) >= TX_RATE_MODE_HE_SU ? (((_gi) & 0xf0) >> 4) : ((_gi) & 0xf)) + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +uint32_t +nicGetPhyRateByMcsRate( + IN uint8_t ucIdx, + IN uint8_t ucBw, + IN uint8_t ucGI) +{ + return arMcsRate2PhyRate[ucIdx].u4PhyRate[ucBw][ucGI]; +} + +uint32_t +nicGetHwRateByPhyRate( + IN uint8_t ucIdx) +{ + return aucHwRate2PhyRate[ucIdx]; /* uint : 500 kbps */ +} + +uint32_t +nicSwIndex2RateIndex( + IN uint8_t ucRateSwIndex, + OUT uint8_t *pucRateIndex, + OUT uint8_t *pucPreambleOption +) +{ + ASSERT(pucRateIndex); + ASSERT(pucPreambleOption); + + if (ucRateSwIndex >= RATE_6M_SW_INDEX) { + *pucRateIndex = ucRateSwIndex - RATE_6M_SW_INDEX; + *pucPreambleOption = PREAMBLE_OFDM_MODE; + } else { + *pucRateIndex = ucRateSwIndex; + *pucPreambleOption = PREAMBLE_DEFAULT_LONG_NONE; + } + return WLAN_STATUS_SUCCESS; +} + +uint32_t nicRateIndex2RateCode(IN uint8_t ucPreambleOption, + IN uint8_t ucRateIndex, OUT uint16_t *pu2RateCode) +{ + switch (ucPreambleOption) { + case PREAMBLE_DEFAULT_LONG_NONE: + if (ucRateIndex >= CCK_RATE_NUM) + return WLAN_STATUS_INVALID_DATA; + *pu2RateCode = au2RateCCKLong[ucRateIndex]; + break; + + case PREAMBLE_OPTION_SHORT: + if (ucRateIndex >= CCK_RATE_NUM) + return WLAN_STATUS_INVALID_DATA; + *pu2RateCode = au2RateCCKShort[ucRateIndex]; + break; + + case PREAMBLE_OFDM_MODE: + if (ucRateIndex >= OFDM_RATE_NUM) + return WLAN_STATUS_INVALID_DATA; + *pu2RateCode = au2RateOFDM[ucRateIndex]; + break; + + case PREAMBLE_HT_MIXED_MODE: + if (ucRateIndex >= HT_RATE_NUM) + return WLAN_STATUS_INVALID_DATA; + *pu2RateCode = au2RateHTMixed[ucRateIndex]; + break; + + case PREAMBLE_HT_GREEN_FIELD: + if (ucRateIndex >= HT_RATE_NUM) + return WLAN_STATUS_INVALID_DATA; + *pu2RateCode = au2RateHTGreenField[ucRateIndex]; + break; + + case PREAMBLE_VHT_FIELD: + if (ucRateIndex >= VHT_RATE_NUM) + return WLAN_STATUS_INVALID_DATA; + *pu2RateCode = au2RateVHT[ucRateIndex]; + break; + + default: + return WLAN_STATUS_INVALID_DATA; + } + + return WLAN_STATUS_SUCCESS; +} + +uint32_t +nicRateCode2PhyRate( + IN uint16_t u2RateCode, + IN uint8_t ucBandwidth, + IN uint8_t ucGI, + IN uint8_t ucRateNss) +{ + uint8_t ucPhyRate; + uint16_t u2TxMode; + uint32_t u4PhyRateBy1SS, u4PhyRateIn100Kbps = 0; + + ucPhyRate = RATE_CODE_GET_PHY_RATE(u2RateCode); + u2TxMode = u2RateCode & RATE_TX_MODE_MASK; + ucRateNss = ucRateNss + AR_SS_1; /* change to be base=1 */ + + if ((u2TxMode == TX_MODE_HT_GF) + || (u2TxMode == TX_MODE_HT_MM)) { + + if (ucPhyRate > PHY_RATE_MCS7) + u2RateCode = u2RateCode - HT_RATE_MCS7_INDEX; + else + ucRateNss = AR_SS_1; + + } else if ((u2TxMode == TX_MODE_OFDM) + || (u2TxMode == TX_MODE_CCK)) { + ucRateNss = AR_SS_1; + } + DBGLOG(NIC, LOUD, + "Coex:nicRateCode2PhyRate,RC:%x,B:%d,I:%d\n", + u2RateCode, ucBandwidth, ucGI); + + u4PhyRateBy1SS = nicRateCode2DataRate(u2RateCode, + ucBandwidth, ucGI); + u4PhyRateIn100Kbps = u4PhyRateBy1SS * ucRateNss; + + DBGLOG(NIC, LOUD, + "Coex:nicRateCode2PhyRate,1ss R:%d,PHY R:%d\n", + u4PhyRateBy1SS, u4PhyRateIn100Kbps); + + return u4PhyRateIn100Kbps; +} + +uint32_t +nicRateCode2DataRate( + IN uint16_t u2RateCode, + IN uint8_t ucBandwidth, + IN uint8_t ucGI) +{ + uint8_t ucPhyRate, ucIdx, ucBw = 0; + uint32_t u4PhyRateIn100Kbps = 0; + uint16_t u2TxMode; + + if ((ucBandwidth == FIX_BW_NO_FIXED) + || (ucBandwidth == FIX_BW_20)) + ucBw = MAC_BW_20; + else if (ucBandwidth == FIX_BW_40) + ucBw = MAC_BW_40; + else if (ucBandwidth == FIX_BW_80) + ucBw = MAC_BW_80; + else if (ucBandwidth == FIX_BW_160) + ucBw = MAC_BW_160; + + ucPhyRate = RATE_CODE_GET_PHY_RATE(u2RateCode); + u2TxMode = u2RateCode & RATE_TX_MODE_MASK; + /* Set MMSS parameter if HT/VHT rate */ + if ((u2TxMode == TX_MODE_HT_GF) || + (u2TxMode == TX_MODE_HT_MM) || + (u2TxMode == TX_MODE_VHT)) { + /* No SGI Greenfield for 1T */ + /* Refer to section 20.3.11.11.6 of IEEE802.11-2012 */ + if (u2TxMode == TX_MODE_HT_GF) + ucGI = MAC_GI_NORMAL; + + ucIdx = ucPhyRate; + + if (ucIdx == PHY_RATE_MCS32) + ucIdx = 10; + + u4PhyRateIn100Kbps = nicGetPhyRateByMcsRate(ucIdx, ucBw, + ucGI); + } else if ((u2TxMode == TX_MODE_OFDM) || + (u2TxMode == TX_MODE_CCK)) { + u4PhyRateIn100Kbps = (nicGetHwRateByPhyRate( + ucPhyRate & BITS(0, 3))) * 5; + } else { + ASSERT(FALSE); + } + return u4PhyRateIn100Kbps; +} + +u_int8_t +nicGetRateIndexFromRateSetWithLimit( + IN uint16_t u2RateSet, + IN uint32_t u4PhyRateLimit, + IN u_int8_t fgGetLowest, + OUT uint8_t *pucRateSwIndex) +{ + uint32_t i; + uint32_t u4CurPhyRate, u4TarPhyRate, u4HighestPhyRate, + u4LowestPhyRate; + uint8_t ucRateIndex, ucRatePreamble, ucTarRateSwIndex, + ucHighestPhyRateSwIdx, ucLowestPhyRateSwIdx; + uint16_t u2CurRateCode; + uint32_t u4Status; + + /* Set init value */ + if (fgGetLowest) { + u4TarPhyRate = 0xFFFFFFFF; + u4HighestPhyRate = 0; + ucHighestPhyRateSwIdx = RATE_NUM_SW; + } else { + u4TarPhyRate = 0; + u4LowestPhyRate = 0xFFFFFFFF; + ucLowestPhyRateSwIdx = RATE_NUM_SW; + } + + ucTarRateSwIndex = RATE_NUM_SW; + + /* Find SW rate index by limitation */ + for (i = RATE_1M_SW_INDEX; i <= RATE_54M_SW_INDEX; i++) { + if (u2RateSet & BIT(i)) { + + /* Convert SW rate index to phy rate in 100kbps */ + nicSwIndex2RateIndex(i, &ucRateIndex, &ucRatePreamble); + u4Status = nicRateIndex2RateCode(ucRatePreamble, + ucRateIndex, &u2CurRateCode); + + if (u4Status != WLAN_STATUS_SUCCESS) + continue; + + u4CurPhyRate = + nicRateCode2DataRate(u2CurRateCode, MAC_BW_20, + MAC_GI_NORMAL); + + /* Compare */ + if (fgGetLowest) { + if (u4HighestPhyRate < u4CurPhyRate) { + u4HighestPhyRate = u4CurPhyRate; + ucHighestPhyRateSwIdx = i; + } + if ((u4CurPhyRate >= u4PhyRateLimit) + && (u4CurPhyRate <= u4TarPhyRate)) { + u4TarPhyRate = u4CurPhyRate; + ucTarRateSwIndex = i; + } + } else { + if (u4LowestPhyRate > u4CurPhyRate) { + u4LowestPhyRate = u4CurPhyRate; + ucLowestPhyRateSwIdx = i; + } + if ((u4CurPhyRate <= u4PhyRateLimit) + && (u4CurPhyRate >= u4TarPhyRate)) { + u4TarPhyRate = u4CurPhyRate; + ucTarRateSwIndex = i; + } + } + } + } + + /* Return target SW rate index */ + if (ucTarRateSwIndex < RATE_NUM_SW) { + *pucRateSwIndex = ucTarRateSwIndex; + } else { + if (fgGetLowest) + *pucRateSwIndex = ucHighestPhyRateSwIdx; + else + *pucRateSwIndex = ucLowestPhyRateSwIdx; + } + return TRUE; +} + +char *nicHwRateOfdmStr( + uint16_t ofdm_idx) +{ + switch (ofdm_idx) { + case 11: /* 6M */ + return HW_TX_RATE_OFDM_STR[0]; + case 15: /* 9M */ + return HW_TX_RATE_OFDM_STR[1]; + case 10: /* 12M */ + return HW_TX_RATE_OFDM_STR[2]; + case 14: /* 18M */ + return HW_TX_RATE_OFDM_STR[3]; + case 9: /* 24M */ + return HW_TX_RATE_OFDM_STR[4]; + case 13: /* 36M */ + return HW_TX_RATE_OFDM_STR[5]; + case 8: /* 48M */ + return HW_TX_RATE_OFDM_STR[6]; + case 12: /* 54M */ + return HW_TX_RATE_OFDM_STR[7]; + default: + return HW_TX_RATE_OFDM_STR[8]; + } +} + +uint32_t nicSetFixedRateData( + struct FIXED_RATE_INFO *pFixedRate, + uint32_t *pu4Data) +{ + uint32_t u4Data = 0; + uint8_t u4Nsts = 1; + uint8_t u1FormatVer; + uint8_t u1TxModeMcsNumMax[ENUM_TX_MODE_NUM]; + + kalMemZero(u1TxModeMcsNumMax, ENUM_TX_MODE_NUM); + /* u1TxModeMcsNumMax[ENUM_TX_MODE_NUM] = {4, 8, 33, 33, 10}; */ + u1TxModeMcsNumMax[ENUM_TX_MODE_CCK] = 4; + u1TxModeMcsNumMax[ENUM_TX_MODE_OFDM] = 8; + u1TxModeMcsNumMax[ENUM_TX_MODE_MM] = 33; + u1TxModeMcsNumMax[ENUM_TX_MODE_GF] = 33; + u1TxModeMcsNumMax[ENUM_TX_MODE_VHT] = 10; + +#if (CFG_SUPPORT_802_11AX == 1) + if (fgEfuseCtrlAxOn == 1) { + /* u1TxModeMcsNumMax[ENUM_TX_MODE_NUM] */ + /* = {4, 8, 33, 33, 10, 2, 0, 0, 12, 12, 12, 12}; */ + u1TxModeMcsNumMax[ENUM_TX_MODE_PLR] = 2; + u1TxModeMcsNumMax[ENUM_TX_MODE_HE_SU] = 12; + u1TxModeMcsNumMax[ENUM_TX_MODE_HE_ER] = 12; + u1TxModeMcsNumMax[ENUM_TX_MODE_HE_TRIG] = 12; + u1TxModeMcsNumMax[ENUM_TX_MODE_HE_MU] = 12; + } +#endif + + u4Data |= RA_FIXEDRATE; + + u1FormatVer = (pFixedRate->u4Mode < TX_RATE_MODE_HE_SU) ? + RATE_VER_1 : RATE_VER_2; + + u4Data |= ((u1FormatVer << RA_FIXEDRATE_FIELD_FORMAT_VER_OFFSET) + & RA_FIXEDRATE_FIELD_FORMAT_VER_MASK); + + if (u1FormatVer == RATE_VER_1) { + if (pFixedRate->u4SGI) + u4Data |= BIT(RA_FIXEDRATE_FIELD_SGI); + } else { + if (pFixedRate->u4SGI < GI_HE_NUM) + u4Data |= ((pFixedRate->u4SGI << + RA_FIXEDRATE_FIELD_HE_GI_OFFSET) & + RA_FIXEDRATE_FIELD_HE_GI_MASK); + else + DBGLOG(INIT, ERROR, + "Wrong HE GI! SGI=0, MGI=1, LGI=2\n"); + } + + if (pFixedRate->u4LDPC) + u4Data |= BIT(RA_FIXEDRATE_FIELD_LDPC); + if (pFixedRate->u4SpeEn) + u4Data |= BIT(RA_FIXEDRATE_FIELD_SPEEN); + if (pFixedRate->u4STBC) + u4Data |= BIT(RA_FIXEDRATE_FIELD_STBC); + + if (pFixedRate->u4Bw <= MAC_BW_160) + u4Data |= ((pFixedRate->u4Bw << RA_FIXEDRATE_FIELD_BW_S) + & BITS(RA_FIXEDRATE_FIELD_BW_S, RA_FIXEDRATE_FIELD_BW_E)); + else { + DBGLOG(INIT, ERROR, + "Wrong BW! BW20=0, BW40=1, BW80=2,BW160=3\n"); + return WLAN_STATUS_INVALID_DATA; + } + + if (pFixedRate->u4Mode < ENUM_TX_MODE_NUM) { + if (u1FormatVer == RATE_VER_1) + u4Data |= + ((pFixedRate->u4Mode << RA_FIXEDRATE_V1_FIELD_MODE_S) + & BITS(RA_FIXEDRATE_V1_FIELD_MODE_S, + RA_FIXEDRATE_V1_FIELD_MODE_E)); + else + u4Data |= + ((pFixedRate->u4Mode << RA_FIXEDRATE_V2_FIELD_MODE_S) + & BITS(RA_FIXEDRATE_V2_FIELD_MODE_S, + RA_FIXEDRATE_V2_FIELD_MODE_E)); + + if (pFixedRate->u4Mcs < u1TxModeMcsNumMax[pFixedRate->u4Mode]) { + if (pFixedRate->u4Mode != TX_RATE_MODE_OFDM) + u4Data |= pFixedRate->u4Mcs; + } else { + DBGLOG(INIT, ERROR, "%s mode but wrong MCS(=%d)!\n", + HW_TX_MODE_STR[pFixedRate->u4Mode], + pFixedRate->u4Mcs); + return WLAN_STATUS_INVALID_DATA; + } + + switch (pFixedRate->u4Mode) { + case TX_RATE_MODE_CCK: + if (pFixedRate->u4Preamble) + if (pFixedRate->u4Mcs > 0) + u4Data |= + BIT(RA_FIXEDRATE_FIELD_S_PREAMBLE); + else { + DBGLOG(INIT, ERROR, "SP but MCS=0!\n"); + return WLAN_STATUS_INVALID_DATA; + } + else + u4Data &= ~BIT(RA_FIXEDRATE_FIELD_S_PREAMBLE); + break; + case TX_RATE_MODE_OFDM: + switch (pFixedRate->u4Mcs) { + case 0: + /* 6'b001011 */ + u4Data |= 11; + break; + case 1: + /* 6'b001111 */ + u4Data |= 15; + break; + case 2: + /* 6'b001010 */ + u4Data |= 10; + break; + case 3: + /* 6'b001110 */ + u4Data |= 14; + break; + case 4: + /* 6'b001001 */ + u4Data |= 9; + break; + case 5: + /* 6'b001101 */ + u4Data |= 13; + break; + case 6: + /* 6'b001000 */ + u4Data |= 8; + break; + case 7: + /* 6'b001100 */ + u4Data |= 12; + break; + default: + DBGLOG(INIT, ERROR, + "OFDM mode but wrong MCS!\n"); + return WLAN_STATUS_INVALID_DATA; + } + break; + case TX_RATE_MODE_HTMIX: + case TX_RATE_MODE_HTGF: + if (pFixedRate->u4Mcs != 32) { + u4Nsts += (pFixedRate->u4Mcs >> 3); + if (pFixedRate->u4STBC && (u4Nsts == 1)) + u4Nsts++; + } + break; + case TX_RATE_MODE_PLR: + break; + case TX_RATE_MODE_VHT: + case TX_RATE_MODE_HE_SU: + case TX_RATE_MODE_HE_ER: + case TX_RATE_MODE_HE_TRIG: + case TX_RATE_MODE_HE_MU: + if (pFixedRate->u4STBC && (pFixedRate->u4VhtNss == 1)) + u4Nsts++; + else + u4Nsts = pFixedRate->u4VhtNss; + break; + default: + break; + } + } else { + DBGLOG(INIT, ERROR, + "Wrong TxMode! CCK=0, OFDM=1, HT=2, GF=3, VHT=4"); + DBGLOG(INIT, ERROR, + "HE_SU=8, HE_ER_SU=9, HE_TRIG=10, HE_MU=11\n"); + return WLAN_STATUS_INVALID_DATA; + } + + if (u1FormatVer == RATE_VER_1) + u4Data |= (((u4Nsts - 1) << RA_FIXEDRATE_V1_FIELD_VHTNSS_S) + & BITS(RA_FIXEDRATE_V1_FIELD_VHTNSS_S, + RA_FIXEDRATE_V1_FIELD_VHTNSS_E)); + else { + u4Data |= (((u4Nsts - 1) << RA_FIXEDRATE_V2_FIELD_VHTNSS_S) + & BITS(RA_FIXEDRATE_V2_FIELD_VHTNSS_S, + RA_FIXEDRATE_V2_FIELD_VHTNSS_E)); + u4Data |= ((pFixedRate->u4HeLTF << + RA_FIXEDRATE_FIELD_HE_LTF_OFFSET) + & RA_FIXEDRATE_FIELD_HE_LTF_MASK); + + if (pFixedRate->u4Mode == TX_RATE_MODE_HE_ER) { + if (pFixedRate->u4HeErDCM) + u4Data |= RA_FIXEDRATE_FIELD_HE_ER_DCM; + if (pFixedRate->u4HeEr106t) + u4Data |= RA_FIXEDRATE_FIELD_HE_ER_106; + } + } + + *pu4Data = u4Data; + return WLAN_STATUS_SUCCESS; +} + +uint32_t nicRateHeLtfCheckGi( + struct FIXED_RATE_INFO *pFixedRate) +{ + uint32_t u4Mode, u4GI; + + u4Mode = pFixedRate->u4Mode; + u4GI = pFixedRate->u4SGI; + + if (u4Mode < TX_RATE_MODE_HE_SU) + return WLAN_STATUS_SUCCESS; + + switch (pFixedRate->u4HeLTF) { + case HE_LTF_1X: + if (u4GI == GI_HE_SGI) { + if ((u4Mode == TX_RATE_MODE_HE_SU) || + (u4Mode == TX_RATE_MODE_HE_ER)) + return WLAN_STATUS_SUCCESS; + } else if (u4GI == GI_HE_MGI) { + /* also need non-OFDMA */ + if (u4Mode == TX_RATE_MODE_HE_TRIG) + return WLAN_STATUS_SUCCESS; + } + break; + case HE_LTF_2X: + if (u4GI == GI_HE_SGI) { + if ((u4Mode == TX_RATE_MODE_HE_SU) || + (u4Mode == TX_RATE_MODE_HE_ER) || + (u4Mode == TX_RATE_MODE_HE_MU)) + return WLAN_STATUS_SUCCESS; + } else if (u4GI == GI_HE_MGI) { + if ((u4Mode >= TX_RATE_MODE_HE_SU) && + (u4Mode <= TX_RATE_MODE_HE_MU)) + return WLAN_STATUS_SUCCESS; + } + break; + case HE_LTF_4X: + if (u4GI == GI_HE_SGI) { + if ((u4Mode == TX_RATE_MODE_HE_SU) || + (u4Mode == TX_RATE_MODE_HE_ER) || + (u4Mode == TX_RATE_MODE_HE_MU)) + return WLAN_STATUS_SUCCESS; + } else if (u4GI == GI_HE_LGI) { + if ((u4Mode >= TX_RATE_MODE_HE_SU) && + (u4Mode <= TX_RATE_MODE_HE_MU)) + return WLAN_STATUS_SUCCESS; + } + break; + + default: + break; + } + + return WLAN_STATUS_FAILURE; +} + +uint8_t nicGetTxSgiInfo( + IN struct PARAM_PEER_CAP *prWtblPeerCap, + IN uint8_t u1TxMode) +{ + if (!prWtblPeerCap) + return FALSE; + + switch (prWtblPeerCap->ucFrequencyCapability) { + case BW_20: + return TX_GET_GI(prWtblPeerCap->fgG2, u1TxMode); + case BW_40: + return TX_GET_GI(prWtblPeerCap->fgG4, u1TxMode); + case BW_80: + return TX_GET_GI(prWtblPeerCap->fgG8, u1TxMode); + case BW_160: + return TX_GET_GI(prWtblPeerCap->fgG16, u1TxMode); + default: + return FALSE; + } +} + +uint8_t nicGetTxLdpcInfo( + IN struct PARAM_TX_CONFIG *prWtblTxConfig) +{ + if (!prWtblTxConfig) + return FALSE; + + if (prWtblTxConfig->fgIsHE) + return prWtblTxConfig->fgHeLDPC; + else if (prWtblTxConfig->fgIsVHT) + return prWtblTxConfig->fgVhtLDPC; + else + return prWtblTxConfig->fgLDPC; +} + +uint16_t nicGetStatIdxInfo(IN struct ADAPTER *prAdapter, + IN uint8_t ucWlanIdx) +{ + static uint8_t aucWlanIdxArray[CFG_STAT_DBG_PEER_NUM] = {0}; + static uint16_t u2ValidBitMask; /* support max 16 peers */ + uint8_t ucIdx, ucStaIdx, ucCnt = 0; + uint8_t ucWlanIdxExist; + + /* check every wlanIdx and unmask no longer used wlanIdx */ + for (ucIdx = 0; ucIdx < CFG_STAT_DBG_PEER_NUM; ucIdx++) { + if (u2ValidBitMask & BIT(ucIdx)) { + ucWlanIdxExist = aucWlanIdxArray[ucIdx]; + + if (wlanGetStaIdxByWlanIdx(prAdapter, ucWlanIdxExist, + &ucStaIdx) != WLAN_STATUS_SUCCESS) + u2ValidBitMask &= ~BIT(ucIdx); + } + } + + /* Search matched WlanIdx */ + for (ucIdx = 0; ucIdx < CFG_STAT_DBG_PEER_NUM; ucIdx++) { + if (u2ValidBitMask & BIT(ucIdx)) { + ucCnt++; + ucWlanIdxExist = aucWlanIdxArray[ucIdx]; + + if (ucWlanIdxExist == ucWlanIdx) { + DBGLOG(REQ, INFO, + "=== Matched, Mask=0x%x, ucIdx=%d ===\n", + u2ValidBitMask, ucIdx); + return ucIdx; + } + } + } + + /* No matched WlanIdx, add new one */ + if (ucCnt < CFG_STAT_DBG_PEER_NUM) { + for (ucIdx = 0; ucIdx < CFG_STAT_DBG_PEER_NUM; ucIdx++) { + if (~u2ValidBitMask & BIT(ucIdx)) { + u2ValidBitMask |= BIT(ucIdx); + aucWlanIdxArray[ucIdx] = ucWlanIdx; + DBGLOG(REQ, INFO, + "=== New Add, Mask=0x%x, ucIdx=%d ===\n", + u2ValidBitMask, ucIdx); + return ucIdx; + } + } + } + + return 0xFFFF; +} + +int32_t nicGetTxRateInfo(IN char *pcCommand, IN int i4TotalLen, + u_int8_t fgDumpAll, + struct PARAM_HW_WLAN_INFO *prHwWlanInfo, + struct PARAM_GET_STA_STATISTICS *prQueryStaStatistics) +{ + uint8_t i, txmode, rate, stbc, sgi; + uint8_t nsts; + int32_t i4BytesWritten = 0; + + for (i = 0; i < AUTO_RATE_NUM; i++) { + txmode = HW_TX_RATE_TO_MODE( + prHwWlanInfo->rWtblRateInfo.au2RateCode[i]); + if (txmode >= ENUM_TX_MODE_NUM) + txmode = ENUM_TX_MODE_NUM - 1; + rate = HW_TX_RATE_TO_MCS( + prHwWlanInfo->rWtblRateInfo.au2RateCode[i]); + nsts = HW_TX_RATE_TO_NSS( + prHwWlanInfo->rWtblRateInfo.au2RateCode[i]) + 1; + stbc = HW_TX_RATE_TO_STBC( + prHwWlanInfo->rWtblRateInfo.au2RateCode[i]); + sgi = nicGetTxSgiInfo(&prHwWlanInfo->rWtblPeerCap, txmode); + + if (fgDumpAll) { + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "Rate index[%d] ", i); + + if (prHwWlanInfo->rWtblRateInfo.ucRateIdx == i) { + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", "--> "); + } else { + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", " "); + } + } + + if (!fgDumpAll) { + if (prHwWlanInfo->rWtblRateInfo.ucRateIdx != i) + continue; + else + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s", "Auto TX Rate", " = "); + } + + if (txmode == TX_RATE_MODE_CCK) + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s, ", HW_TX_RATE_CCK_STR[rate & 0x3]); + else if (txmode == TX_RATE_MODE_OFDM) + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s, ", nicHwRateOfdmStr(rate)); + else if ((txmode == TX_RATE_MODE_HTMIX) || + (txmode == TX_RATE_MODE_HTGF)) + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "MCS%d, ", rate); + else + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s%d_MCS%d, ", stbc ? "NSTS" : "NSS", + nsts, rate); + + if (prQueryStaStatistics->ucSkipAr) { + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s, ", + prHwWlanInfo->rWtblPeerCap.ucFrequencyCapability + < 4 ? HW_TX_RATE_BW[ + prHwWlanInfo->rWtblPeerCap.ucFrequencyCapability] + : HW_TX_RATE_BW[4]); + } else { + if ((txmode == TX_RATE_MODE_CCK) || + (txmode == TX_RATE_MODE_OFDM)) + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s, ", HW_TX_RATE_BW[0]); + else + if (i > prHwWlanInfo->rWtblPeerCap + .ucChangeBWAfterRateN) + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s, ", + prHwWlanInfo->rWtblPeerCap. + ucFrequencyCapability < 4 ? + (prHwWlanInfo->rWtblPeerCap. + ucFrequencyCapability > BW_20 ? + HW_TX_RATE_BW[prHwWlanInfo-> + rWtblPeerCap + .ucFrequencyCapability - 1] : + HW_TX_RATE_BW[prHwWlanInfo->rWtblPeerCap + .ucFrequencyCapability]) : + HW_TX_RATE_BW[4]); + else + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s, ", + prHwWlanInfo->rWtblPeerCap. + ucFrequencyCapability < 4 ? + HW_TX_RATE_BW[ + prHwWlanInfo->rWtblPeerCap + .ucFrequencyCapability] : + HW_TX_RATE_BW[4]); + } + + if (txmode == TX_RATE_MODE_CCK) + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s, ", rate < 4 ? "LP" : "SP"); + else if (txmode == TX_RATE_MODE_OFDM) + ; + else if ((txmode == TX_RATE_MODE_HTMIX) || + (txmode == TX_RATE_MODE_HTGF) || + (txmode == TX_RATE_MODE_VHT) || + (txmode == TX_RATE_MODE_PLR)) + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s, ", sgi == 0 ? "LGI" : "SGI"); + else + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s, ", sgi == 0 ? "SGI" : + (sgi == 1 ? "MGI" : "LGI")); + + if (prQueryStaStatistics->ucSkipAr) { + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s%s%s\n", + txmode <= ENUM_TX_MODE_NUM ? + HW_TX_MODE_STR[txmode] : "N/A", + stbc ? ", STBC, " : ", ", + nicGetTxLdpcInfo( + &prHwWlanInfo->rWtblTxConfig) == 0 ? + "BCC" : "LDPC"); + } else { +#if (CFG_SUPPORT_RA_GEN == 0) + if (prQueryStaStatistics->aucArRatePer[ + prQueryStaStatistics->aucRateEntryIndex[i]] == 0xFF) + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s%s%s (--)\n", + txmode < ENUM_TX_MODE_NUM ? + HW_TX_MODE_STR[txmode] : "N/A", + stbc ? ", STBC, " : ", ", + ((nicGetTxLdpcInfo( + &prHwWlanInfo->rWtblTxConfig) == 0) + || (txmode == TX_RATE_MODE_CCK) + || (txmode == TX_RATE_MODE_OFDM)) ? + "BCC" : "LDPC"); + else + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s%s%s (%d)\n", + txmode < ENUM_TX_MODE_NUM ? + HW_TX_MODE_STR[txmode] : "N/A", + stbc ? ", STBC, " : ", ", + ((nicGetTxLdpcInfo( + &prHwWlanInfo->rWtblTxConfig) == 0) + || (txmode == TX_RATE_MODE_CCK) + || (txmode == TX_RATE_MODE_OFDM)) + ? "BCC" : "LDPC", + prQueryStaStatistics->aucArRatePer[ + prQueryStaStatistics + ->aucRateEntryIndex[i]]); +#else + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s%s%s\n", + txmode < ENUM_TX_MODE_NUM ? + HW_TX_MODE_STR[txmode] : "N/A", + stbc ? ", STBC, " : ", ", + ((nicGetTxLdpcInfo( + &prHwWlanInfo->rWtblTxConfig) == 0) || + (txmode == TX_RATE_MODE_CCK) || + (txmode == TX_RATE_MODE_OFDM)) ? + "BCC" : "LDPC"); +#endif + } + + if (!fgDumpAll) + break; + } + + return i4BytesWritten; +} + +int32_t nicGetRxRateInfo(struct ADAPTER *prAdapter, IN char *pcCommand, + IN int i4TotalLen, IN uint8_t ucWlanIdx) +{ + uint32_t txmode, rate, frmode, sgi, nsts, ldpc, stbc, groupid, mu; + int32_t i4BytesWritten = 0; + uint32_t u4RxVector0 = 0, u4RxVector1 = 0; + uint8_t ucStaIdx; + struct CHIP_DBG_OPS *prChipDbg; + + if (wlanGetStaIdxByWlanIdx(prAdapter, ucWlanIdx, &ucStaIdx) == + WLAN_STATUS_SUCCESS) { + u4RxVector0 = prAdapter->arStaRec[ucStaIdx].u4RxVector0; + u4RxVector1 = prAdapter->arStaRec[ucStaIdx].u4RxVector1; + DBGLOG(REQ, LOUD, "****** RX Vector0 = 0x%08x ******\n", + u4RxVector0); + DBGLOG(REQ, LOUD, "****** RX Vector1 = 0x%08x ******\n", + u4RxVector1); + } else { + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s", "Last RX Rate", " = NOT SUPPORT"); + return i4BytesWritten; + } + + prChipDbg = prAdapter->chip_info->prDebugOps; + + if (prChipDbg && prChipDbg->show_rx_rate_info) { + i4BytesWritten = prChipDbg->show_rx_rate_info( + prAdapter, + pcCommand, + i4TotalLen, + ucStaIdx); + return i4BytesWritten; + } + + txmode = (u4RxVector0 & RX_VT_RX_MODE_MASK) >> RX_VT_RX_MODE_OFFSET; + rate = (u4RxVector0 & RX_VT_RX_RATE_MASK) >> RX_VT_RX_RATE_OFFSET; + frmode = (u4RxVector0 & RX_VT_FR_MODE_MASK) >> RX_VT_FR_MODE_OFFSET; + nsts = ((u4RxVector1 & RX_VT_NSTS_MASK) >> RX_VT_NSTS_OFFSET); + stbc = (u4RxVector0 & RX_VT_STBC_MASK) >> RX_VT_STBC_OFFSET; + sgi = u4RxVector0 & RX_VT_SHORT_GI; + ldpc = u4RxVector0 & RX_VT_LDPC; + groupid = (u4RxVector1 & RX_VT_GROUP_ID_MASK) >> RX_VT_GROUP_ID_OFFSET; + + if (groupid && groupid != 63) { + mu = 1; + } else { + mu = 0; + nsts += 1; + } + + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%-20s%s", "Last RX Rate", " = "); + + if (txmode == TX_RATE_MODE_CCK) + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s, ", + rate < 4 ? HW_TX_RATE_CCK_STR[rate] : + HW_TX_RATE_CCK_STR[4]); + else if (txmode == TX_RATE_MODE_OFDM) + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s, ", + nicHwRateOfdmStr(rate)); + else if ((txmode == TX_RATE_MODE_HTMIX) || + (txmode == TX_RATE_MODE_HTGF)) + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "MCS%d, ", rate); + else + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "NSS%d_MCS%d, ", + nsts, rate); + + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s, ", + frmode < 4 ? HW_TX_RATE_BW[frmode] : HW_TX_RATE_BW[4]); + + if (txmode == TX_RATE_MODE_CCK) + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s, ", + rate < 4 ? "LP" : "SP"); + else if (txmode == TX_RATE_MODE_OFDM) + ; + else + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s, ", + sgi == 0 ? "LGI" : "SGI"); + + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s", stbc == 0 ? "" : "STBC, "); + + if (mu) { + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s, %s, %s (%d)\n", + (txmode < ENUM_TX_MODE_NUM ? + HW_TX_MODE_STR[txmode] : "N/A"), + ldpc == 0 ? "BCC" : "LDPC", "MU", groupid); + } else { + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s, %s\n", + (txmode < ENUM_TX_MODE_NUM ? + HW_TX_MODE_STR[txmode] : "N/A"), + ldpc == 0 ? "BCC" : "LDPC"); + } + + return i4BytesWritten; +} + + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/nic_rx.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/nic_rx.c new file mode 100644 index 0000000000000000000000000000000000000000..cfc9ff7c6621138d72df32412797370570945082 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/nic_rx.c @@ -0,0 +1,4768 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic_rx.c#5 + */ + +/*! \file nic_rx.c + * \brief Functions that provide many rx-related functions + * + * This file includes the functions used to process RFB and dispatch RFBs to + * the appropriate related rx functions for protocols. + */ + + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" +#include "que_mgt.h" +#include "wnm.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +#if CFG_MGMT_FRAME_HANDLING +static PROCESS_RX_MGT_FUNCTION +apfnProcessRxMgtFrame[MAX_NUM_OF_FC_SUBTYPES] = { +#if CFG_SUPPORT_AAA + aaaFsmRunEventRxAssoc, /* subtype 0000: Association request */ +#else + NULL, /* subtype 0000: Association request */ +#endif /* CFG_SUPPORT_AAA */ + saaFsmRunEventRxAssoc, /* subtype 0001: Association response */ +#if CFG_SUPPORT_AAA + aaaFsmRunEventRxAssoc, /* subtype 0010: Reassociation request */ +#else + NULL, /* subtype 0010: Reassociation request */ +#endif /* CFG_SUPPORT_AAA */ + saaFsmRunEventRxAssoc, /* subtype 0011: Reassociation response */ +#if CFG_SUPPORT_ADHOC || CFG_ENABLE_WIFI_DIRECT + bssProcessProbeRequest, /* subtype 0100: Probe request */ +#else + NULL, /* subtype 0100: Probe request */ +#endif /* CFG_SUPPORT_ADHOC */ + scanProcessBeaconAndProbeResp, /* subtype 0101: Probe response */ + NULL, /* subtype 0110: reserved */ + NULL, /* subtype 0111: reserved */ + scanProcessBeaconAndProbeResp, /* subtype 1000: Beacon */ + NULL, /* subtype 1001: ATIM */ + saaFsmRunEventRxDisassoc, /* subtype 1010: Disassociation */ + authCheckRxAuthFrameTransSeq, /* subtype 1011: Authentication */ + saaFsmRunEventRxDeauth, /* subtype 1100: Deauthentication */ + nicRxProcessActionFrame, /* subtype 1101: Action */ + NULL, /* subtype 1110: reserved */ + NULL /* subtype 1111: reserved */ +}; +#endif + +static struct RX_EVENT_HANDLER arEventTable[] = { + {EVENT_ID_RX_ADDBA, qmHandleEventRxAddBa}, + {EVENT_ID_DBDC_SWITCH_DONE, cnmDbdcEventHwSwitchDone}, + {EVENT_ID_RX_DELBA, qmHandleEventRxDelBa}, + {EVENT_ID_LINK_QUALITY, nicEventLinkQuality}, + {EVENT_ID_LAYER_0_EXT_MAGIC_NUM, nicEventLayer0ExtMagic}, + {EVENT_ID_MIC_ERR_INFO, nicEventMicErrorInfo}, + {EVENT_ID_SCAN_DONE, nicEventScanDone}, + {EVENT_ID_SCHED_SCAN_DONE, nicEventSchedScanDone}, + {EVENT_ID_TX_DONE, nicTxProcessTxDoneEvent}, + {EVENT_ID_SLEEPY_INFO, nicEventSleepyNotify}, +#if CFG_ENABLE_BT_OVER_WIFI + {EVENT_ID_BT_OVER_WIFI, nicEventBtOverWifi}, +#endif + {EVENT_ID_STATISTICS, nicEventStatistics}, + {EVENT_ID_WTBL_INFO, nicEventWlanInfo}, + {EVENT_ID_MIB_INFO, nicEventMibInfo}, + {EVENT_ID_CH_PRIVILEGE, cnmChMngrHandleChEvent}, + {EVENT_ID_BSS_ABSENCE_PRESENCE, qmHandleEventBssAbsencePresence}, + {EVENT_ID_STA_CHANGE_PS_MODE, qmHandleEventStaChangePsMode}, + {EVENT_ID_STA_UPDATE_FREE_QUOTA, qmHandleEventStaUpdateFreeQuota}, + {EVENT_ID_BSS_BEACON_TIMEOUT, nicEventBeaconTimeout}, + {EVENT_ID_UPDATE_NOA_PARAMS, nicEventUpdateNoaParams}, + {EVENT_ID_STA_AGING_TIMEOUT, nicEventStaAgingTimeout}, + {EVENT_ID_AP_OBSS_STATUS, nicEventApObssStatus}, + {EVENT_ID_ROAMING_STATUS, nicEventRoamingStatus}, + {EVENT_ID_SEND_DEAUTH, nicEventSendDeauth}, + {EVENT_ID_UPDATE_RDD_STATUS, nicEventUpdateRddStatus}, + {EVENT_ID_UPDATE_BWCS_STATUS, nicEventUpdateBwcsStatus}, + {EVENT_ID_UPDATE_BCM_DEBUG, nicEventUpdateBcmDebug}, + {EVENT_ID_ADD_PKEY_DONE, nicEventAddPkeyDone}, + {EVENT_ID_ICAP_DONE, nicEventIcapDone}, + {EVENT_ID_DEBUG_MSG, nicEventDebugMsg}, + {EVENT_ID_TDLS, nicEventTdls}, +#if (CFG_SUPPORT_HE_ER == 1) + {EVENT_ID_BSS_ER_TX_MODE, bssProcessErTxModeEvent}, +#endif + {EVENT_ID_RSSI_MONITOR, nicEventRssiMonitor}, + {EVENT_ID_DUMP_MEM, nicEventDumpMem}, +#if CFG_ASSERT_DUMP + {EVENT_ID_ASSERT_DUMP, nicEventAssertDump}, +#endif +#if CFG_SUPPORT_CAL_RESULT_BACKUP_TO_HOST + {EVENT_ID_CAL_ALL_DONE, nicEventCalAllDone}, +#endif + {EVENT_ID_HIF_CTRL, nicEventHifCtrl}, + {EVENT_ID_RDD_SEND_PULSE, nicEventRddSendPulse}, +#if (CFG_SUPPORT_DFS_MASTER == 1) + {EVENT_ID_UPDATE_COEX_PHYRATE, nicEventUpdateCoexPhyrate}, + {EVENT_ID_RDD_REPORT, cnmRadarDetectEvent}, + {EVENT_ID_CSA_DONE, cnmCsaDoneEvent}, +#if CFG_SUPPORT_IDC_CH_SWITCH + {EVENT_ID_LTE_IDC_REPORT, cnmIdcDetectHandler}, +#endif +#else + {EVENT_ID_UPDATE_COEX_PHYRATE, nicEventUpdateCoexPhyrate}, +#endif + {EVENT_ID_TX_ADDBA, qmHandleEventTxAddBa}, + {EVENT_ID_GET_CNM, nicEventCnmInfo}, +#if CFG_SUPPORT_SMART_GEAR + {EVENT_ID_SG_STATUS, cnmEventSGStatus}, +#endif + {EVENT_ID_OPMODE_CHANGE, cnmOpmodeEventHandler}, +#if CFG_SUPPORT_LOWLATENCY_MODE + {EVENT_ID_LOW_LATENCY_INFO, nicEventUpdateLowLatencyInfoStatus}, +#endif +}; + +static const struct ACTION_FRAME_SIZE_MAP arActionFrameReservedLen[] = { + {(uint16_t)(CATEGORY_QOS_ACTION | ACTION_QOS_MAP_CONFIGURE << 8), + sizeof(struct _ACTION_QOS_MAP_CONFIGURE_FRAME)}, + {(uint16_t)(CATEGORY_PUBLIC_ACTION | ACTION_PUBLIC_20_40_COEXIST << 8), + OFFSET_OF(struct ACTION_20_40_COEXIST_FRAME, rChnlReport)}, + {(uint16_t) + (CATEGORY_PUBLIC_ACTION | ACTION_PUBLIC_VENDOR_SPECIFIC << 8), + sizeof(struct WLAN_PUBLIC_VENDOR_ACTION_FRAME)}, + {(uint16_t)(CATEGORY_HT_ACTION | ACTION_HT_NOTIFY_CHANNEL_WIDTH << 8), + sizeof(struct ACTION_NOTIFY_CHNL_WIDTH_FRAME)}, + {(uint16_t)(CATEGORY_HT_ACTION | ACTION_HT_SM_POWER_SAVE << 8), + sizeof(struct ACTION_SM_POWER_SAVE_FRAME)}, + {(uint16_t)(CATEGORY_SA_QUERY_ACTION | ACTION_SA_QUERY_REQUEST << 8), + sizeof(struct ACTION_SA_QUERY_FRAME)}, + {(uint16_t) + (CATEGORY_WNM_ACTION | ACTION_WNM_TIMING_MEASUREMENT_REQUEST << 8), + sizeof(struct ACTION_WNM_TIMING_MEAS_REQ_FRAME)}, + {(uint16_t)(CATEGORY_SPEC_MGT | ACTION_MEASUREMENT_REQ << 8), + sizeof(struct ACTION_SM_REQ_FRAME)}, + {(uint16_t)(CATEGORY_SPEC_MGT | ACTION_MEASUREMENT_REPORT << 8), + sizeof(struct ACTION_SM_REQ_FRAME)}, + {(uint16_t)(CATEGORY_SPEC_MGT | ACTION_TPC_REQ << 8), + sizeof(struct ACTION_SM_REQ_FRAME)}, + {(uint16_t)(CATEGORY_SPEC_MGT | ACTION_TPC_REPORT << 8), + sizeof(struct ACTION_SM_REQ_FRAME)}, + {(uint16_t)(CATEGORY_SPEC_MGT | ACTION_CHNL_SWITCH << 8), + sizeof(struct ACTION_SM_REQ_FRAME)}, + {(uint16_t) + (CATEGORY_VHT_ACTION | ACTION_OPERATING_MODE_NOTIFICATION << 8), + sizeof(struct ACTION_OP_MODE_NOTIFICATION_FRAME)}, +#if (CFG_SUPPORT_TWT == 1) + {(uint16_t)(CATEGORY_S1G_ACTION | ACTION_S1G_TWT_SETUP << 8), + sizeof(struct _ACTION_TWT_SETUP_FRAME)}, + {(uint16_t)(CATEGORY_S1G_ACTION | ACTION_S1G_TWT_TEARDOWN << 8), + sizeof(struct _ACTION_TWT_TEARDOWN_FRAME)}, + {(uint16_t)(CATEGORY_S1G_ACTION | ACTION_S1G_TWT_INFORMATION << 8), + sizeof(struct _ACTION_TWT_INFO_FRAME)}, +#endif + {(uint16_t)(CATEGORY_RM_ACTION | RM_ACTION_RM_REQUEST << 8), + sizeof(struct ACTION_RM_REQ_FRAME)}, + {(uint16_t)(CATEGORY_RM_ACTION | RM_ACTION_REIGHBOR_RESPONSE << 8), + sizeof(struct ACTION_NEIGHBOR_REPORT_FRAME)}, + {(uint16_t)(CATEGORY_WME_MGT_NOTIFICATION | ACTION_ADDTS_RSP << 8), + sizeof(struct WMM_ACTION_TSPEC_FRAME)}, + {(uint16_t)(CATEGORY_WME_MGT_NOTIFICATION | ACTION_DELTS << 8), + sizeof(struct WMM_ACTION_TSPEC_FRAME)}, +}; + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +/*----------------------------------------------------------------------------*/ +/*! + * @brief Initialize the RFBs + * + * @param prAdapter Pointer to the Adapter structure. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void nicRxInitialize(IN struct ADAPTER *prAdapter) +{ + struct RX_CTRL *prRxCtrl; + uint8_t *pucMemHandle; + struct SW_RFB *prSwRfb = (struct SW_RFB *) NULL; + uint32_t i; + + DEBUGFUNC("nicRxInitialize"); + + ASSERT(prAdapter); + prRxCtrl = &prAdapter->rRxCtrl; + + /* 4 <0> Clear allocated memory. */ + kalMemZero((void *) prRxCtrl->pucRxCached, + prRxCtrl->u4RxCachedSize); + + /* 4 <1> Initialize the RFB lists */ + QUEUE_INITIALIZE(&prRxCtrl->rFreeSwRfbList); + QUEUE_INITIALIZE(&prRxCtrl->rReceivedRfbList); + QUEUE_INITIALIZE(&prRxCtrl->rIndicatedRfbList); + + pucMemHandle = prRxCtrl->pucRxCached; + for (i = CFG_RX_MAX_PKT_NUM; i != 0; i--) { + prSwRfb = (struct SW_RFB *) pucMemHandle; + + if (nicRxSetupRFB(prAdapter, prSwRfb)) { + DBGLOG(RX, ERROR, + "nicRxInitialize failed: Cannot allocate packet buffer for SwRfb!\n"); + return; + } + nicRxReturnRFB(prAdapter, prSwRfb); + + pucMemHandle += ALIGN_4(sizeof(struct SW_RFB)); + } + + if (prRxCtrl->rFreeSwRfbList.u4NumElem != + CFG_RX_MAX_PKT_NUM) + ASSERT_NOMEM(); + /* Check if the memory allocation consist with this + * initialization function + */ + ASSERT((uint32_t) (pucMemHandle - prRxCtrl->pucRxCached) == + prRxCtrl->u4RxCachedSize); + + /* 4 <2> Clear all RX counters */ + RX_RESET_ALL_CNTS(prRxCtrl); + + prRxCtrl->pucRxCoalescingBufPtr = + prAdapter->pucCoalescingBufCached; + +#if CFG_HIF_STATISTICS + prRxCtrl->u4TotalRxAccessNum = 0; + prRxCtrl->u4TotalRxPacketNum = 0; +#endif + +#if CFG_HIF_RX_STARVATION_WARNING + prRxCtrl->u4QueuedCnt = 0; + prRxCtrl->u4DequeuedCnt = 0; +#endif + +} /* end of nicRxInitialize() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Uninitialize the RFBs + * + * @param prAdapter Pointer to the Adapter structure. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void nicRxUninitialize(IN struct ADAPTER *prAdapter) +{ + struct RX_CTRL *prRxCtrl; + struct SW_RFB *prSwRfb = (struct SW_RFB *) NULL; + + KAL_SPIN_LOCK_DECLARATION(); + + ASSERT(prAdapter); + prRxCtrl = &prAdapter->rRxCtrl; + ASSERT(prRxCtrl); + + nicRxFlush(prAdapter); + + do { + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); + QUEUE_REMOVE_HEAD(&prRxCtrl->rReceivedRfbList, prSwRfb, + struct SW_RFB *); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); + if (prSwRfb) { + if (prSwRfb->pvPacket) + kalPacketFree(prAdapter->prGlueInfo, + prSwRfb->pvPacket); + prSwRfb->pvPacket = NULL; + } else { + break; + } + } while (TRUE); + + do { + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_FREE_QUE); + QUEUE_REMOVE_HEAD(&prRxCtrl->rFreeSwRfbList, prSwRfb, + struct SW_RFB *); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_FREE_QUE); + if (prSwRfb) { + if (prSwRfb->pvPacket) + kalPacketFree(prAdapter->prGlueInfo, + prSwRfb->pvPacket); + prSwRfb->pvPacket = NULL; + } else { + break; + } + } while (TRUE); + +} /* end of nicRxUninitialize() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Fill RFB + * + * @param prAdapter pointer to the Adapter handler + * @param prSWRfb specify the RFB to receive rx data + * + * @return (none) + * + */ +/*----------------------------------------------------------------------------*/ +void nicRxFillRFB(IN struct ADAPTER *prAdapter, + IN OUT struct SW_RFB *prSwRfb) +{ + struct RX_DESC_OPS_T *prRxDescOps = prAdapter->chip_info->prRxDescOps; + + if (prRxDescOps->nic_rxd_fill_rfb) + prRxDescOps->nic_rxd_fill_rfb(prAdapter, prSwRfb); + else + DBGLOG(RX, ERROR, + "%s:: no nic_rxd_fill_rfb??\n", + __func__); +} + +#if CFG_TCP_IP_CHKSUM_OFFLOAD || CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60 +/*----------------------------------------------------------------------------*/ +/*! + * @brief Fill checksum status in RFB + * + * @param prAdapter pointer to the Adapter handler + * @param prSWRfb the RFB to receive rx data + * @param u4TcpUdpIpCksStatus specify the Checksum status + * + * @return (none) + * + */ +/*----------------------------------------------------------------------------*/ +void nicRxFillChksumStatus(IN struct ADAPTER *prAdapter, + IN OUT struct SW_RFB *prSwRfb) +{ + struct RX_CSO_REPORT_T *rReport; + uint32_t u4TcpUdpIpCksStatus; + + ASSERT(prAdapter); + ASSERT(prSwRfb); + + u4TcpUdpIpCksStatus = prSwRfb->u4TcpUdpIpCksStatus; + rReport = (struct RX_CSO_REPORT_T *) &u4TcpUdpIpCksStatus; + DBGLOG_LIMITED(RX, LOUD, + "RX_IPV4_STATUS=%d, RX_TCP_STATUS=%d, RX_UDP_STATUS=%d\n", + rReport->u4IpV4CksStatus, rReport->u4TcpCksStatus, + rReport->u4UdpCksStatus); + DBGLOG_LIMITED(RX, LOUD, + "RX_IPV4_TYPE=%d, RX_IPV6_TYPE=%d, RX_TCP_TYPE=%d, RX_UDP_TYPE=%d\n", + rReport->u4IpV4CksType, rReport->u4IpV6CksType, + rReport->u4TcpCksType, rReport->u4UdpCksType); + + if (prAdapter->u4CSUMFlags != CSUM_NOT_SUPPORTED) { + if (u4TcpUdpIpCksStatus & + RX_CS_TYPE_IPv4) { /* IPv4 packet */ + prSwRfb->aeCSUM[CSUM_TYPE_IPV6] = CSUM_RES_NONE; + if (u4TcpUdpIpCksStatus & + RX_CS_STATUS_IP) { /* IP packet csum failed */ + prSwRfb->aeCSUM[CSUM_TYPE_IPV4] = + CSUM_RES_FAILED; + } else { + prSwRfb->aeCSUM[CSUM_TYPE_IPV4] = + CSUM_RES_SUCCESS; + } + + if (u4TcpUdpIpCksStatus & RX_CS_TYPE_TCP) { + /* TCP packet */ + prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_NONE; + if (u4TcpUdpIpCksStatus & + RX_CS_STATUS_TCP) { + /* TCP packet csum failed */ + prSwRfb->aeCSUM[CSUM_TYPE_TCP] = + CSUM_RES_FAILED; + } else { + prSwRfb->aeCSUM[CSUM_TYPE_TCP] = + CSUM_RES_SUCCESS; + } + } else if (u4TcpUdpIpCksStatus & + RX_CS_TYPE_UDP) { /* UDP packet */ + prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_NONE; + if (u4TcpUdpIpCksStatus & + RX_CS_STATUS_UDP) { + /* UDP packet csum failed */ + prSwRfb->aeCSUM[CSUM_TYPE_UDP] = + CSUM_RES_FAILED; + } else { + prSwRfb->aeCSUM[CSUM_TYPE_UDP] = + CSUM_RES_SUCCESS; + } + } else { + prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_NONE; + prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_NONE; + } + } else if (u4TcpUdpIpCksStatus & + RX_CS_TYPE_IPv6) { /* IPv6 packet */ + prSwRfb->aeCSUM[CSUM_TYPE_IPV4] = CSUM_RES_NONE; + prSwRfb->aeCSUM[CSUM_TYPE_IPV6] = CSUM_RES_SUCCESS; + + if (u4TcpUdpIpCksStatus & RX_CS_TYPE_TCP) { + /* TCP packet */ + prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_NONE; + if (u4TcpUdpIpCksStatus & + RX_CS_STATUS_TCP) { + /* TCP packet csum failed */ + prSwRfb->aeCSUM[CSUM_TYPE_TCP] = + CSUM_RES_FAILED; + } else { + prSwRfb->aeCSUM[CSUM_TYPE_TCP] = + CSUM_RES_SUCCESS; + } + } else if (u4TcpUdpIpCksStatus & + RX_CS_TYPE_UDP) { /* UDP packet */ + prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_NONE; + if (u4TcpUdpIpCksStatus & + RX_CS_STATUS_UDP) { + /* UDP packet csum failed */ + prSwRfb->aeCSUM[CSUM_TYPE_UDP] = + CSUM_RES_FAILED; + } else { + prSwRfb->aeCSUM[CSUM_TYPE_UDP] = + CSUM_RES_SUCCESS; + } + } else { + prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_NONE; + prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_NONE; + } + } else { + prSwRfb->aeCSUM[CSUM_TYPE_IPV4] = CSUM_RES_NONE; + prSwRfb->aeCSUM[CSUM_TYPE_IPV6] = CSUM_RES_NONE; + } + } + +} +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief nicRxClearFrag() is used to clean all fragments in the fragment cache. + * + * \param[in] prAdapter pointer to the Adapter handler + * \param[in] prStaRec The fragment cache is stored under station record. + * + * @return (none) + * + */ +/*----------------------------------------------------------------------------*/ +void nicRxClearFrag(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec) +{ + int j; + struct FRAG_INFO *prFragInfo; + + for (j = 0; j < MAX_NUM_CONCURRENT_FRAGMENTED_MSDUS; j++) { + prFragInfo = &prStaRec->rFragInfo[j]; + + if (prFragInfo->pr1stFrag) { + nicRxReturnRFB(prAdapter, prFragInfo->pr1stFrag); + prFragInfo->pr1stFrag = (struct SW_RFB *)NULL; + } + } + + DBGLOG(RX, INFO, "%s\n", __func__); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief rxDefragMPDU() is used to defragment the incoming packets. + * + * \param[in] prSWRfb The RFB which is being processed. + * \param[in] UINT_16 u2FrameCtrl + * + * \retval NOT NULL Receive the last fragment data + * \retval NULL Receive the fragment packet which is not the last + */ +/*----------------------------------------------------------------------------*/ +struct SW_RFB *nicRxDefragMPDU(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSWRfb, OUT struct QUE *prReturnedQue) +{ + + struct SW_RFB *prOutputSwRfb = (struct SW_RFB *) NULL; + struct RX_CTRL *prRxCtrl; + struct FRAG_INFO *prFragInfo; + uint32_t i = 0, j; + uint16_t u2SeqCtrl, u2FrameCtrl; + uint16_t u2SeqNo; + uint8_t ucFragNo; + u_int8_t fgFirst = FALSE; + u_int8_t fgLast = FALSE; + OS_SYSTIME rCurrentTime; + struct WLAN_MAC_HEADER *prWlanHeader = NULL; + void *prRxStatus = NULL; + struct HW_MAC_RX_STS_GROUP_4 *prRxStatusGroup4 = NULL; +#if CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION + uint8_t ucSecMode = CIPHER_SUITE_NONE; + uint64_t u8PN; +#endif /* CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION */ + + DEBUGFUNC("nicRx: rxmDefragMPDU\n"); + + ASSERT(prSWRfb); + + prRxCtrl = &prAdapter->rRxCtrl; + + prRxStatus = prSWRfb->prRxStatus; + ASSERT(prRxStatus); + + if (prSWRfb->fgHdrTran == FALSE) { + prWlanHeader = (struct WLAN_MAC_HEADER *) prSWRfb->pvHeader; + u2FrameCtrl = prWlanHeader->u2FrameCtrl; + } else { + prRxStatusGroup4 = prSWRfb->prRxStatusGroup4; + prSWRfb->u2SequenceControl = HAL_RX_STATUS_GET_SEQFrag_NUM( + prRxStatusGroup4); + u2FrameCtrl = HAL_RX_STATUS_GET_FRAME_CTL_FIELD( + prRxStatusGroup4); + } + u2SeqCtrl = prSWRfb->u2SequenceControl; + u2SeqNo = u2SeqCtrl >> MASK_SC_SEQ_NUM_OFFSET; + ucFragNo = (uint8_t) (u2SeqCtrl & MASK_SC_FRAG_NUM); + prSWRfb->u2FrameCtrl = u2FrameCtrl; + + if (!(u2FrameCtrl & MASK_FC_MORE_FRAG)) { + /* The last fragment frame */ + if (ucFragNo) { + DBGLOG(RX, LOUD, + "FC %04x M %04x SQ %04x\n", u2FrameCtrl, + (uint16_t) (u2FrameCtrl & MASK_FC_MORE_FRAG), + u2SeqCtrl); + fgLast = TRUE; + } + /* Non-fragment frame */ + else + return prSWRfb; + } + /* The fragment frame except the last one */ + else { + if (ucFragNo == 0) { + DBGLOG(RX, LOUD, + "FC %04x M %04x SQ %04x\n", u2FrameCtrl, + (uint16_t) (u2FrameCtrl & MASK_FC_MORE_FRAG), + u2SeqCtrl); + fgFirst = TRUE; + } else { + DBGLOG(RX, LOUD, + "FC %04x M %04x SQ %04x\n", u2FrameCtrl, + (uint16_t) (u2FrameCtrl & MASK_FC_MORE_FRAG), + u2SeqCtrl); + } + } + + GET_CURRENT_SYSTIME(&rCurrentTime); + + /* check cipher suite to set if we need to get PN */ +#if CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION + if (prSWRfb->ucSecMode == CIPHER_SUITE_TKIP + || prSWRfb->ucSecMode == CIPHER_SUITE_TKIP_WO_MIC + || prSWRfb->ucSecMode == CIPHER_SUITE_CCMP + || prSWRfb->ucSecMode == CIPHER_SUITE_CCMP_W_CCX + || prSWRfb->ucSecMode == CIPHER_SUITE_CCMP_256 + || prSWRfb->ucSecMode == CIPHER_SUITE_GCMP_128 + || prSWRfb->ucSecMode == CIPHER_SUITE_GCMP_256) { + ucSecMode = prSWRfb->ucSecMode; + if (!qmRxPNtoU64(prSWRfb->prRxStatusGroup1->aucPN, + CCMPTSCPNNUM, &u8PN)) { + DBGLOG(QM, ERROR, "PN2U64 failed\n"); + /* should not enter here, just fallback */ + ucSecMode = CIPHER_SUITE_NONE; + } + } +#endif /* CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION */ + + + for (j = 0; j < MAX_NUM_CONCURRENT_FRAGMENTED_MSDUS; j++) { + prFragInfo = &prSWRfb->prStaRec->rFragInfo[j]; + if (prFragInfo->pr1stFrag) { + /* I. If the receive timer for the MSDU or MMPDU that + * is stored in the fragments queue exceeds + * dot11MaxReceiveLifetime, we discard the uncompleted + * fragments. + * II. If we didn't receive the last MPDU for a period, + * we use this function for remove frames. + */ + if (CHECK_FOR_EXPIRATION(rCurrentTime, + prFragInfo->rReceiveLifetimeLimit)) { + prFragInfo->pr1stFrag->eDst = + RX_PKT_DESTINATION_NULL; + QUEUE_INSERT_TAIL(prReturnedQue, + (struct QUE_ENTRY *) + prFragInfo->pr1stFrag); + + prFragInfo->pr1stFrag = (struct SW_RFB *) NULL; + } + } + } + + for (i = 0; i < MAX_NUM_CONCURRENT_FRAGMENTED_MSDUS; i++) { + + prFragInfo = &prSWRfb->prStaRec->rFragInfo[i]; + + if (fgFirst) { /* looking for timed-out frag buffer */ + + if (prFragInfo->pr1stFrag == (struct SW_RFB *) + NULL) /* find a free frag buffer */ + break; + } else { + /* looking for a buffer with desired next seqctrl */ + + if (prFragInfo->pr1stFrag == (struct SW_RFB *) NULL) + continue; + + if (RXM_IS_QOS_DATA_FRAME(u2FrameCtrl)) { + if (RXM_IS_QOS_DATA_FRAME( + prFragInfo->pr1stFrag->u2FrameCtrl)) { + if (u2SeqNo == prFragInfo->u2SeqNo +#if CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION + && ucSecMode + == prFragInfo->ucSecMode +#else + && ucFragNo + == prFragInfo->ucNextFragNo +#endif /* CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION */ + ) + break; + } + } else { + if (!RXM_IS_QOS_DATA_FRAME( + prFragInfo->pr1stFrag->u2FrameCtrl)) { + if (u2SeqNo == prFragInfo->u2SeqNo +#if CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION + && ucSecMode + == prFragInfo->ucSecMode +#else + && ucFragNo + == prFragInfo->ucNextFragNo +#endif /* CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION */ + ) + break; + } + } + } + } + + if (i >= MAX_NUM_CONCURRENT_FRAGMENTED_MSDUS) { + + /* Can't find a proper struct FRAG_INFO. + * I. 1st Fragment MPDU, all of the FragInfo are exhausted + * II. 2nd ~ (n-1)th Fragment MPDU, can't find the right + * FragInfo for defragment. + * Because we won't process fragment frame outside this + * function, so we should free it right away. + */ + nicRxReturnRFB(prAdapter, prSWRfb); + + return (struct SW_RFB *) NULL; + } + +#if CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION + if (prFragInfo->pr1stFrag != (struct SW_RFB *) NULL) { + /* check if the FragNo is cont. */ + if (ucFragNo != prFragInfo->ucNextFragNo + || ((ucSecMode != CIPHER_SUITE_NONE) + && (u8PN != prFragInfo->u8NextPN)) + ) { + DBGLOG(RX, INFO, "non-cont FragNo or PN, drop it."); + + DBGLOG(RX, INFO, + "SN:%04x NxFragN:%02x FragN:%02x\n", + prFragInfo->u2SeqNo, + prFragInfo->ucNextFragNo, + ucFragNo); + + if (ucSecMode != CIPHER_SUITE_NONE) + DBGLOG(RX, INFO, + "SN:%04x NxPN:%016x PN:%016x\n", + prFragInfo->u2SeqNo, + prFragInfo->u8NextPN, + u8PN); + + /* discard fragments if FragNo is non-cont. */ + nicRxReturnRFB(prAdapter, prFragInfo->pr1stFrag); + prFragInfo->pr1stFrag = (struct SW_RFB *) NULL; + + nicRxReturnRFB(prAdapter, prSWRfb); + return (struct SW_RFB *) NULL; + } + } +#endif /* CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION */ + + ASSERT(prFragInfo); + + /* retrieve Rx payload */ + prSWRfb->pucPayload = (uint8_t *) (( + (unsigned long) prSWRfb->pvHeader) + + prSWRfb->u2HeaderLen); + prSWRfb->u2PayloadLength = + (uint16_t) (prSWRfb->u2RxByteCount - (( + unsigned long) prSWRfb->pucPayload - + (unsigned long) prRxStatus)); + + if (fgFirst) { + DBGLOG(RX, LOUD, "rxDefragMPDU first\n"); + + SET_EXPIRATION_TIME(prFragInfo->rReceiveLifetimeLimit, + TU_TO_SYSTIME( + DOT11_RECEIVE_LIFETIME_TU_DEFAULT)); + + prFragInfo->pr1stFrag = prSWRfb; + + prFragInfo->pucNextFragStart = + (uint8_t *) prSWRfb->pucRecvBuff + + prSWRfb->u2RxByteCount; + + prFragInfo->u2SeqNo = u2SeqNo; + prFragInfo->ucNextFragNo = ucFragNo + 1; /* should be 1 */ + +#if CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION + prFragInfo->ucSecMode = ucSecMode; + if (prFragInfo->ucSecMode != CIPHER_SUITE_NONE) + prFragInfo->u8NextPN = u8PN + 1; + else + prFragInfo->u8NextPN = 0; +#endif /* CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION */ + + DBGLOG(RX, LOUD, + "First: SeqCtrl:%04x, SN:%04x, NxFragN = %02x\n", + u2SeqCtrl, prFragInfo->u2SeqNo, + prFragInfo->ucNextFragNo); + + /* prSWRfb->fgFragmented = TRUE; */ + /* whsu: todo for checksum */ + } else { + prFragInfo->pr1stFrag->u2RxByteCount += + prSWRfb->u2PayloadLength; + + if (prFragInfo->pr1stFrag->u2RxByteCount > + CFG_RX_MAX_PKT_SIZE) { + + prFragInfo->pr1stFrag->eDst = RX_PKT_DESTINATION_NULL; + QUEUE_INSERT_TAIL(prReturnedQue, + (struct QUE_ENTRY *) + prFragInfo->pr1stFrag); + + prFragInfo->pr1stFrag = (struct SW_RFB *) NULL; + + nicRxReturnRFB(prAdapter, prSWRfb); + DBGLOG(RX, LOUD, + "Defrag: dropped due length > CFG_RX_MAX_PKT_SIZE\n"); + } else { + kalMemCopy(prFragInfo->pucNextFragStart, + prSWRfb->pucPayload, + prSWRfb->u2PayloadLength); + /* [6630] update rx byte count and packet length */ + prFragInfo->pr1stFrag->u2PacketLen += + prSWRfb->u2PayloadLength; + prFragInfo->pr1stFrag->u2PayloadLength += + prSWRfb->u2PayloadLength; + + if (fgLast) { /* The last one, free the buffer */ + DBGLOG(RX, LOUD, "Defrag: finished\n"); + + prOutputSwRfb = prFragInfo->pr1stFrag; + + prFragInfo->pr1stFrag = (struct SW_RFB *) NULL; + } else { + DBGLOG(RX, LOUD, "Defrag: mid fraged\n"); + + prFragInfo->pucNextFragStart += + prSWRfb->u2PayloadLength; + + prFragInfo->ucNextFragNo++; + +#if CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION + if (prFragInfo->ucSecMode + != CIPHER_SUITE_NONE) + prFragInfo->u8NextPN++; +#endif /* CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION */ + + } + + nicRxReturnRFB(prAdapter, prSWRfb); + } + } + + /* DBGLOG_MEM8(RXM, INFO, */ + /* prFragInfo->pr1stFrag->pucPayload, */ + /* prFragInfo->pr1stFrag->u2PayloadLength); */ + + return prOutputSwRfb; +} /* end of rxmDefragMPDU() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Do duplicate detection + * + * @param prSwRfb Pointer to the RX packet + * + * @return TRUE: a duplicate, FALSE: not a duplicate + */ +/*----------------------------------------------------------------------------*/ +u_int8_t nicRxIsDuplicateFrame(IN OUT struct SW_RFB + *prSwRfb) +{ + + /* Non-QoS Unicast Data or Unicast MMPDU: SC Cache #4; + * QoS Unicast Data: SC Cache #0~3; + * Broadcast/Multicast: RetryBit == 0 + */ + uint32_t u4SeqCtrlCacheIdx; + uint16_t u2SequenceControl, u2FrameCtrl; + u_int8_t fgIsDuplicate = FALSE, fgIsAmsduSubframe = FALSE; + struct WLAN_MAC_HEADER *prWlanHeader = NULL; + void *prRxStatus = NULL; + struct HW_MAC_RX_STS_GROUP_4 *prRxStatusGroup4 = NULL; + + DEBUGFUNC("nicRx: Enter rxmIsDuplicateFrame()\n"); + + ASSERT(prSwRfb); + + /* Situations in which the STC_REC is missing include: + * (1) Probe Request (2) (Re)Association Request + * (3) IBSS data frames (4) Probe Response + */ + if (!prSwRfb->prStaRec) + return FALSE; + + prRxStatus = prSwRfb->prRxStatus; + ASSERT(prRxStatus); + + fgIsAmsduSubframe = prSwRfb->ucPayloadFormat; + if (prSwRfb->fgHdrTran == FALSE) { + prWlanHeader = (struct WLAN_MAC_HEADER *) prSwRfb->pvHeader; + u2SequenceControl = prSwRfb->u2SequenceControl; + u2FrameCtrl = prWlanHeader->u2FrameCtrl; + } else { + prRxStatusGroup4 = prSwRfb->prRxStatusGroup4; + u2SequenceControl = HAL_RX_STATUS_GET_SEQFrag_NUM( + prRxStatusGroup4); + u2FrameCtrl = HAL_RX_STATUS_GET_FRAME_CTL_FIELD( + prRxStatusGroup4); + } + prSwRfb->u2SequenceControl = u2SequenceControl; + + /* Case 1: Unicast QoS data */ + if (RXM_IS_QOS_DATA_FRAME( + u2FrameCtrl)) { + /* WLAN header shall exist when doing duplicate detection */ + if (prSwRfb->prStaRec-> + aprRxReorderParamRefTbl[prSwRfb->ucTid]) { + + /* QoS data with an RX BA agreement + * Case 1: The packet is not an AMPDU subframe, + * so the RetryBit may be set to 1 (TBC). + * Case 2: The RX BA agreement was just established. + * Some enqueued packets may not be sent with + * aggregation. + */ + + DBGLOG(RX, LOUD, "RX: SC=0x%X (BA Entry present)\n", + u2SequenceControl); + + /* Update the SN cache in order to ensure the + * correctness of duplicate removal in case the + * BA agreement is deleted + */ + prSwRfb->prStaRec->au2CachedSeqCtrl[prSwRfb->ucTid] = + u2SequenceControl; + + /* debug */ +#if 0 + DBGLOG(RXM, LOUD, + "RXM: SC= 0x%X (Cache[%d] updated) with BA\n", + u2SequenceControl, prSwRfb->ucTID); + + if (g_prMqm->arRxBaTable[ + prSwRfb->prStaRec->aucRxBaTable[prSwRfb->ucTID]] + .ucStatus == BA_ENTRY_STATUS_DELETING) { + DBGLOG(RXM, LOUD, + "RXM: SC= 0x%X (Cache[%d] updated) with DELETING BA\n", + u2SequenceControl, prSwRfb->ucTID); + } +#endif + + /* HW scoreboard shall take care Case 1. + * Let the layer layer handle Case 2. + */ + return FALSE; /* Not a duplicate */ + } + + if (prSwRfb->prStaRec->ucDesiredPhyTypeSet & + (PHY_TYPE_BIT_HT | PHY_TYPE_BIT_VHT)) { + u4SeqCtrlCacheIdx = prSwRfb->ucTid; +#if (CFG_SUPPORT_802_11AX == 1) + } else if (prSwRfb->prStaRec->ucDesiredPhyTypeSet & + PHY_TYPE_BIT_HE) { + u4SeqCtrlCacheIdx = prSwRfb->ucTid; +#endif + } else { + if (prSwRfb->ucTid < 8) { /* UP = 0~7 */ + u4SeqCtrlCacheIdx = aucTid2ACI[prSwRfb->ucTid]; + } else { + DBGLOG(RX, WARN, + "RXM: (Warning) Unknown QoS Data with TID=%d\n", + prSwRfb->ucTid); + /* Ignore duplicate frame check */ + return FALSE; + } + } + } + /* Case 2: Unicast non-QoS data or MMPDUs */ + else + u4SeqCtrlCacheIdx = TID_NUM; + + /* If this is a retransmission */ + if (u2FrameCtrl & MASK_FC_RETRY) { + if (u2SequenceControl != + prSwRfb->prStaRec->au2CachedSeqCtrl[u4SeqCtrlCacheIdx]) { + prSwRfb->prStaRec->au2CachedSeqCtrl[u4SeqCtrlCacheIdx] = + u2SequenceControl; + if (fgIsAmsduSubframe == + RX_PAYLOAD_FORMAT_FIRST_SUB_AMSDU) + prSwRfb->prStaRec-> + afgIsIgnoreAmsduDuplicate[ + u4SeqCtrlCacheIdx] = TRUE; + DBGLOG(RX, LOUD, "RXM: SC= 0x%x (Cache[%u] updated)\n", + u2SequenceControl, u4SeqCtrlCacheIdx); + } else { + /* A duplicate. */ + if (prSwRfb->prStaRec-> + afgIsIgnoreAmsduDuplicate[u4SeqCtrlCacheIdx]) { + if (fgIsAmsduSubframe == + RX_PAYLOAD_FORMAT_LAST_SUB_AMSDU) + prSwRfb->prStaRec-> + afgIsIgnoreAmsduDuplicate[ + u4SeqCtrlCacheIdx] = FALSE; + } else { + fgIsDuplicate = TRUE; + DBGLOG(RX, LOUD, + "RXM: SC= 0x%x (Cache[%u] duplicate)\n", + u2SequenceControl, u4SeqCtrlCacheIdx); + } + } + } + + /* Not a retransmission */ + else { + + prSwRfb->prStaRec->au2CachedSeqCtrl[u4SeqCtrlCacheIdx] = + u2SequenceControl; + prSwRfb->prStaRec->afgIsIgnoreAmsduDuplicate[u4SeqCtrlCacheIdx] + = FALSE; + + DBGLOG(RX, LOUD, "RXM: SC= 0x%x (Cache[%u] updated)\n", + u2SequenceControl, u4SeqCtrlCacheIdx); + } + + return fgIsDuplicate; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Process packet doesn't need to do buffer reordering + * + * @param prAdapter pointer to the Adapter handler + * @param prSWRfb the RFB to receive rx data + * + * @return (none) + * + */ +/*----------------------------------------------------------------------------*/ +void nicRxProcessPktWithoutReorder(IN struct ADAPTER + *prAdapter, IN struct SW_RFB *prSwRfb) +{ + struct RX_CTRL *prRxCtrl; + struct TX_CTRL *prTxCtrl; + u_int8_t fgIsRetained = FALSE; + uint32_t u4CurrentRxBufferCount; + /* P_STA_RECORD_T prStaRec = (P_STA_RECORD_T)NULL; */ + + DEBUGFUNC("nicRxProcessPktWithoutReorder"); + /* DBGLOG(RX, TRACE, ("\n")); */ + + ASSERT(prAdapter); + ASSERT(prSwRfb); + + prRxCtrl = &prAdapter->rRxCtrl; + ASSERT(prRxCtrl); + + prTxCtrl = &prAdapter->rTxCtrl; + ASSERT(prTxCtrl); + + u4CurrentRxBufferCount = prRxCtrl->rFreeSwRfbList.u4NumElem; + /* QM USED = $A, AVAILABLE COUNT = $B, INDICATED TO OS = $C + * TOTAL = $A + $B + $C + * + * Case #1 (Retain) + * ------------------------------------------------------- + * $A + $B < THRESHOLD := $A + $B + $C < THRESHOLD + $C + * := $TOTAL - THRESHOLD < $C + * => $C used too much, retain + * + * Case #2 (Non-Retain) + * ------------------------------------------------------- + * $A + $B > THRESHOLD := $A + $B + $C > THRESHOLD + $C + * := $TOTAL - THRESHOLD > $C + * => still available for $C to use + * + */ + +#if defined(LINUX) + fgIsRetained = FALSE; +#else + fgIsRetained = (((u4CurrentRxBufferCount + + qmGetRxReorderQueuedBufferCount(prAdapter) + + prTxCtrl->i4PendingFwdFrameCount) < + CFG_RX_RETAINED_PKT_THRESHOLD) ? TRUE : FALSE); +#endif + + /* DBGLOG(RX, INFO, ("fgIsRetained = %d\n", fgIsRetained)); */ +#if CFG_ENABLE_PER_STA_STATISTICS + if (prSwRfb->prStaRec + && (prAdapter->rWifiVar.rWfdConfigureSettings.ucWfdEnable > + 0)) + prSwRfb->prStaRec->u4TotalRxPktsNumber++; +#endif + if (kalProcessRxPacket(prAdapter->prGlueInfo, + prSwRfb->pvPacket, + prSwRfb->pvHeader, + (uint32_t) prSwRfb->u2PacketLen, fgIsRetained, + prSwRfb->aeCSUM) != WLAN_STATUS_SUCCESS) { + DBGLOG(RX, ERROR, + "kalProcessRxPacket return value != WLAN_STATUS_SUCCESS\n"); + + nicRxReturnRFB(prAdapter, prSwRfb); + return; + } + +#if CFG_SUPPORT_MULTITHREAD + if (HAL_IS_RX_DIRECT(prAdapter)) { + kalRxIndicateOnePkt(prAdapter->prGlueInfo, + (void *) GLUE_GET_PKT_DESCRIPTOR( + GLUE_GET_PKT_QUEUE_ENTRY(prSwRfb->pvPacket))); + if (fgIsRetained) + RX_ADD_CNT(prRxCtrl, RX_DATA_RETAINED_COUNT, 1); + } else { + KAL_SPIN_LOCK_DECLARATION(); + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_TO_OS_QUE); + QUEUE_INSERT_TAIL(&(prAdapter->rRxQueue), + (struct QUE_ENTRY *) GLUE_GET_PKT_QUEUE_ENTRY( + prSwRfb->pvPacket)); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_TO_OS_QUE); + + prRxCtrl->ucNumIndPacket++; + kalSetTxEvent2Rx(prAdapter->prGlueInfo); + } +#else + prRxCtrl->apvIndPacket[prRxCtrl->ucNumIndPacket] = + prSwRfb->pvPacket; + prRxCtrl->ucNumIndPacket++; +#endif + +#ifndef LINUX + if (fgIsRetained) { + prRxCtrl->apvRetainedPacket[prRxCtrl->ucNumRetainedPacket] = + prSwRfb->pvPacket; + prRxCtrl->ucNumRetainedPacket++; + } else +#endif + prSwRfb->pvPacket = NULL; + + + /* Return RFB */ + if (nicRxSetupRFB(prAdapter, prSwRfb)) { + DBGLOG(RX, WARN, + "Cannot allocate packet buffer for SwRfb!\n"); + if (!timerPendingTimer( + &prAdapter->rPacketDelaySetupTimer)) { + DBGLOG(RX, WARN, + "Start ReturnIndicatedRfb Timer (%u)\n", + RX_RETURN_INDICATED_RFB_TIMEOUT_SEC); + cnmTimerStartTimer(prAdapter, + &prAdapter->rPacketDelaySetupTimer, + SEC_TO_MSEC( + RX_RETURN_INDICATED_RFB_TIMEOUT_SEC)); + } + } + nicRxReturnRFB(prAdapter, prSwRfb); +} + +u_int8_t nicRxCheckForwardPktResource( + IN struct ADAPTER *prAdapter, uint32_t ucTid) +{ + struct TX_CTRL *prTxCtrl; + uint8_t i, uTxQidx; + + prTxCtrl = &prAdapter->rTxCtrl; + uTxQidx = aucACI2TxQIdx[aucTid2ACI[ucTid]]; + + /* If the resource used more than half, we could control WMM resource + * by limit every AC queue. + */ + for (i = uTxQidx+1; i < WMM_AC_INDEX_NUM; i++) { + if (GLUE_GET_REF_CNT(prTxCtrl + ->i4PendingFwdFrameWMMCount[uTxQidx]) >= + GLUE_GET_REF_CNT(prTxCtrl + ->i4PendingFwdFrameWMMCount[i]) && + GLUE_GET_REF_CNT(prTxCtrl + ->i4PendingFwdFrameWMMCount[i]) > 0 && + GLUE_GET_REF_CNT(prTxCtrl + ->i4PendingFwdFrameCount) > prAdapter + ->rQM.u4MaxForwardBufferCount) + return FALSE; + } + return TRUE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Process forwarding data packet + * + * @param prAdapter pointer to the Adapter handler + * @param prSWRfb the RFB to receive rx data + * + * @return (none) + * + */ +/*----------------------------------------------------------------------------*/ +void nicRxProcessForwardPkt(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb) +{ + struct MSDU_INFO *prMsduInfo, *prRetMsduInfoList; + struct TX_CTRL *prTxCtrl; + struct RX_CTRL *prRxCtrl; + + KAL_SPIN_LOCK_DECLARATION(); + + DEBUGFUNC("nicRxProcessForwardPkt"); + + ASSERT(prAdapter); + ASSERT(prSwRfb); + + prTxCtrl = &prAdapter->rTxCtrl; + prRxCtrl = &prAdapter->rRxCtrl; + + if (prSwRfb->ucTid >= TX_DESC_TID_NUM) { + DBGLOG_LIMITED(RX, WARN, + "Wrong forward packet: tid:%d\n", prSwRfb->ucTid); + prSwRfb->ucTid = 0; + } + + if (!nicRxCheckForwardPktResource(prAdapter, prSwRfb->ucTid)) { + nicRxReturnRFB(prAdapter, prSwRfb); + return; + } + + DBGLOG_LIMITED(RX, TRACE, "to forward packet: %d,%d,%d,%d,%d\n", + GLUE_GET_REF_CNT(prTxCtrl->i4PendingFwdFrameWMMCount[0]), + GLUE_GET_REF_CNT(prTxCtrl->i4PendingFwdFrameWMMCount[1]), + GLUE_GET_REF_CNT(prTxCtrl->i4PendingFwdFrameWMMCount[2]), + GLUE_GET_REF_CNT(prTxCtrl->i4PendingFwdFrameWMMCount[3]), + GLUE_GET_REF_CNT(prTxCtrl->i4PendingFwdFrameCount)); + + prMsduInfo = cnmPktAlloc(prAdapter, 0); + + if (prMsduInfo && + kalProcessRxPacket(prAdapter->prGlueInfo, + prSwRfb->pvPacket, + prSwRfb->pvHeader, + (uint32_t) prSwRfb->u2PacketLen, + prRxCtrl->rFreeSwRfbList.u4NumElem < + CFG_RX_RETAINED_PKT_THRESHOLD ? TRUE : FALSE, + prSwRfb->aeCSUM) == WLAN_STATUS_SUCCESS) { + + /* parsing forward frame */ + wlanProcessTxFrame(prAdapter, (void *) (prSwRfb->pvPacket)); + /* pack into MSDU_INFO_T */ + nicTxFillMsduInfo(prAdapter, prMsduInfo, + (void *) (prSwRfb->pvPacket)); + + prMsduInfo->eSrc = TX_PACKET_FORWARDING; + prMsduInfo->ucBssIndex = secGetBssIdxByWlanIdx(prAdapter, + prSwRfb->ucWlanIdx); + prMsduInfo->ucUserPriority = prSwRfb->ucTid; + + /* release RX buffer (to rIndicatedRfbList) */ + prSwRfb->pvPacket = NULL; + nicRxReturnRFB(prAdapter, prSwRfb); + + /* Handle if prMsduInfo out of bss index range*/ + if (prMsduInfo->ucBssIndex > MAX_BSSID_NUM) { + DBGLOG(QM, INFO, + "Invalid bssidx:%u\n", prMsduInfo->ucBssIndex); + if (prMsduInfo->pfTxDoneHandler != NULL) + prMsduInfo->pfTxDoneHandler(prAdapter, + prMsduInfo, + TX_RESULT_DROPPED_IN_DRIVER); + nicTxReturnMsduInfo(prAdapter, prMsduInfo); + return; + } + + /* increase forward frame counter */ + GLUE_INC_REF_CNT(prTxCtrl->i4PendingFwdFrameCount); + + /* add resource control for WMM forward packet */ + GLUE_INC_REF_CNT(prTxCtrl + ->i4PendingFwdFrameWMMCount[ + aucACI2TxQIdx[aucTid2ACI[prSwRfb->ucTid]]]); + + /* send into TX queue */ + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); + prRetMsduInfoList = qmEnqueueTxPackets(prAdapter, + prMsduInfo); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); + + if (prRetMsduInfoList != + NULL) { /* TX queue refuses queuing the packet */ + nicTxFreeMsduInfoPacket(prAdapter, prRetMsduInfoList); + nicTxReturnMsduInfo(prAdapter, prRetMsduInfoList); + } + /* indicate service thread for sending */ + if (prTxCtrl->i4PendingFwdFrameCount > 0) + kalSetEvent(prAdapter->prGlueInfo); + } else { /* no TX resource */ + DBGLOG(QM, INFO, "No Tx MSDU_INFO for forwarding frames\n"); + nicRxReturnRFB(prAdapter, prSwRfb); + if (prMsduInfo) + nicTxReturnMsduInfo(prAdapter, prMsduInfo); + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Process broadcast data packet for both host and forwarding + * + * @param prAdapter pointer to the Adapter handler + * @param prSWRfb the RFB to receive rx data + * + * @return (none) + * + */ +/*----------------------------------------------------------------------------*/ +void nicRxProcessGOBroadcastPkt(IN struct ADAPTER + *prAdapter, IN struct SW_RFB *prSwRfb) +{ + struct SW_RFB *prSwRfbDuplicated; + struct TX_CTRL *prTxCtrl; + struct RX_CTRL *prRxCtrl; + + KAL_SPIN_LOCK_DECLARATION(); + + DEBUGFUNC("nicRxProcessGOBroadcastPkt"); + + ASSERT(prAdapter); + ASSERT(prSwRfb); + + prTxCtrl = &prAdapter->rTxCtrl; + prRxCtrl = &prAdapter->rRxCtrl; + + ASSERT(CFG_NUM_OF_QM_RX_PKT_NUM >= 16); + + if (prRxCtrl->rFreeSwRfbList.u4NumElem + >= (CFG_RX_MAX_PKT_NUM - (CFG_NUM_OF_QM_RX_PKT_NUM - + 16 /* Reserved for others */))) { + + /* 1. Duplicate SW_RFB_T */ + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_FREE_QUE); + QUEUE_REMOVE_HEAD(&prRxCtrl->rFreeSwRfbList, + prSwRfbDuplicated, struct SW_RFB *); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_FREE_QUE); + + if (prSwRfbDuplicated) { + kalMemCopy(prSwRfbDuplicated->pucRecvBuff, + prSwRfb->pucRecvBuff, + ALIGN_4(prSwRfb->u2RxByteCount + + HIF_RX_HW_APPENDED_LEN)); + + prSwRfbDuplicated->ucPacketType = RX_PKT_TYPE_RX_DATA; + prSwRfbDuplicated->ucStaRecIdx = prSwRfb->ucStaRecIdx; + nicRxFillRFB(prAdapter, prSwRfbDuplicated); + GLUE_COPY_PRIV_DATA( + prSwRfbDuplicated->pvPacket, + prSwRfb->pvPacket); + + /* 2. Modify eDst */ + prSwRfbDuplicated->eDst = RX_PKT_DESTINATION_FORWARD; + + /* 4. Forward */ + nicRxProcessForwardPkt(prAdapter, prSwRfbDuplicated); + } + } else { + DBGLOG(RX, WARN, + "Stop to forward BMC packet due to less free Sw Rfb %u\n", + prRxCtrl->rFreeSwRfbList.u4NumElem); + } + + /* 3. Indicate to host */ + prSwRfb->eDst = RX_PKT_DESTINATION_HOST; + nicRxProcessPktWithoutReorder(prAdapter, prSwRfb); + +} + +#if CFG_SUPPORT_SNIFFER +void nicRxFillRadiotapMCS(IN OUT struct MONITOR_RADIOTAP + *prMonitorRadiotap, + IN struct HW_MAC_RX_STS_GROUP_3 *prRxStatusGroup3) +{ + uint8_t ucFrMode; + uint8_t ucShortGI; + uint8_t ucRxMode; + uint8_t ucLDPC; + uint8_t ucSTBC; + uint8_t ucNess; + + ucFrMode = (((prRxStatusGroup3)->u4RxVector[0] & + RX_VT_FR_MODE_MASK) >> RX_VT_FR_MODE_OFFSET); + /* VHTA1 B0-B1 */ + ucShortGI = ((prRxStatusGroup3)->u4RxVector[0] & + RX_VT_SHORT_GI) ? 1 : 0; /* HT_shortgi */ + ucRxMode = (((prRxStatusGroup3)->u4RxVector[0] & + RX_VT_RX_MODE_MASK) >> RX_VT_RX_MODE_OFFSET); + ucLDPC = ((prRxStatusGroup3)->u4RxVector[0] & RX_VT_LDPC) ? + 1 : 0; /* HT_adcode */ + ucSTBC = (((prRxStatusGroup3)->u4RxVector[0] & + RX_VT_STBC_MASK) >> RX_VT_STBC_OFFSET); /* HT_stbc */ + ucNess = (((prRxStatusGroup3)->u4RxVector[0] & + RX_VT_NESS_MASK) >> RX_VT_NESS_OFFSET); /* HT_extltf */ + + prMonitorRadiotap->ucMcsKnown = + (BITS(0, 6) | (((ucNess & BIT(1)) >> 1) << 7)); + + prMonitorRadiotap->ucMcsFlags = ((ucFrMode) | + (ucShortGI << 2) | + ((ucRxMode & BIT(0)) << 3) | + (ucLDPC << 4) | (ucSTBC << 5) | + ((ucNess & BIT(0)) << 7)); + /* Bit[6:0] for 802.11n, mcs0 ~ mcs7 */ + prMonitorRadiotap->ucMcsMcs = (( + prRxStatusGroup3)->u4RxVector[0] & RX_VT_RX_RATE_MASK); +} + +void nicRxFillRadiotapVHT(IN OUT struct MONITOR_RADIOTAP + *prMonitorRadiotap, + IN struct HW_MAC_RX_STS_GROUP_3 *prRxStatusGroup3) +{ + uint8_t ucSTBC; + uint8_t ucTxopPsNotAllow; + uint8_t ucShortGI; + uint8_t ucNsym; + uint8_t ucLdpcExtraOfdmSym; + uint8_t ucBeamFormed; + uint8_t ucFrMode; + uint8_t ucNsts; + uint8_t ucMcs; + + prMonitorRadiotap->u2VhtKnown = RADIOTAP_VHT_ALL_KNOWN; + prMonitorRadiotap->u2VhtKnown &= + ~RADIOTAP_VHT_SHORT_GI_NSYM_KNOWN; + + ucSTBC = (((prRxStatusGroup3)->u4RxVector[0] & + RX_VT_STBC_MASK) >> + RX_VT_STBC_OFFSET); /* BIT[7]: VHTA1 B3 */ + ucTxopPsNotAllow = ((prRxStatusGroup3)->u4RxVector[0] & + RX_VT_TXOP_PS_NOT_ALLOWED) ? 1 : 0; /* VHTA1 B22 */ + /* + * ucNsym = ((prRxStatusGroup3)->u4RxVector[0] + * & RX_VT_SHORT_GI_NSYM) ? 1 : 0; //VHTA2 B1 + */ + ucNsym = 0; /* Invalid in MT6632*/ + ucShortGI = ((prRxStatusGroup3)->u4RxVector[0] & + RX_VT_SHORT_GI) ? 1 : 0; /* VHTA2 B0 */ + ucLdpcExtraOfdmSym = ((prRxStatusGroup3)->u4RxVector[0] & + RX_VT_LDPC_EXTRA_OFDM_SYM) ? 1 : 0; /* VHTA2 B3 */ + ucBeamFormed = ((prRxStatusGroup3)->u4RxVector[0] & + RX_VT_BEAMFORMED) ? 1 : 0; /* VHTA2 B8 */ + prMonitorRadiotap->ucVhtFlags = ((ucSTBC) | + (ucTxopPsNotAllow << 1) | + (ucShortGI << 2) | (ucNsym << 3) + | (ucLdpcExtraOfdmSym << 4) + | (ucBeamFormed << 5)); + + ucFrMode = (((prRxStatusGroup3)->u4RxVector[0] & + RX_VT_FR_MODE_MASK) >> RX_VT_FR_MODE_OFFSET); + /* VHTA1 B0-B1 */ + switch (ucFrMode) { + case RX_VT_FR_MODE_20: + prMonitorRadiotap->ucVhtBandwidth = 0; + break; + case RX_VT_FR_MODE_40: + prMonitorRadiotap->ucVhtBandwidth = 1; + break; + case RX_VT_FR_MODE_80: + prMonitorRadiotap->ucVhtBandwidth = 4; + break; + case RX_VT_FR_MODE_160: + prMonitorRadiotap->ucVhtBandwidth = 11; + break; + default: + prMonitorRadiotap->ucVhtBandwidth = 0; + } + + /* Set to 0~7 for 1~8 space time streams */ + ucNsts = (((prRxStatusGroup3)->u4RxVector[1] & + RX_VT_NSTS_MASK) >> RX_VT_NSTS_OFFSET) + 1; + /* VHTA1 B10-B12 */ + + /* Bit[3:0] for 802.11ac, mcs0 ~ mcs9 */ + ucMcs = ((prRxStatusGroup3)->u4RxVector[0] & + RX_VT_RX_RATE_AC_MASK); + + prMonitorRadiotap->aucVhtMcsNss[0] = ((ucMcs << 4) | + (ucNsts - ucSTBC)); /* STBC = Nsts - Nss */ + + /* + * prMonitorRadiotap->ucVhtCoding = + * (((prRxStatusGroup3)->u4RxVector[0] + * & RX_VT_CODING_MASK) >> RX_VT_CODING_OFFSET); + */ + prMonitorRadiotap->ucVhtCoding = 0; /* Invalid in MT6632*/ + + /* VHTA2 B2-B3 */ + + prMonitorRadiotap->ucVhtGroupId = + (((((prRxStatusGroup3)->u4RxVector[1] & + RX_VT_GROUPID_1_MASK) >> RX_VT_GROUPID_1_OFFSET) << 2) | + (((prRxStatusGroup3)->u4RxVector[0] & RX_VT_GROUPID_0_MASK) + >> RX_VT_GROUPID_0_OFFSET)); + /* VHTA1 B4-B9 */ + /* VHTA1 B13-B21 */ + prMonitorRadiotap->u2VhtPartialAid = (((( + prRxStatusGroup3)->u4RxVector[2] + & RX_VT_AID_1_MASK) << 4) | + (((prRxStatusGroup3)->u4RxVector[1] + & RX_VT_AID_0_MASK) >> + RX_VT_AID_0_OFFSET)); + +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Process HIF monitor packet + * + * @param prAdapter pointer to the Adapter handler + * @param prSWRfb the RFB to receive rx data + * + * @return (none) + * + */ +/*----------------------------------------------------------------------------*/ +void nicRxProcessMonitorPacket(IN struct ADAPTER *prAdapter, + IN OUT struct SW_RFB *prSwRfb) +{ + struct sk_buff *prSkb = NULL; + struct RX_CTRL *prRxCtrl; + void *prRxStatus; + struct HW_MAC_RX_STS_GROUP_2 *prRxStatusGroup2; + struct HW_MAC_RX_STS_GROUP_3 *prRxStatusGroup3; + struct MONITOR_RADIOTAP rMonitorRadiotap; + struct RADIOTAP_FIELD_VENDOR_ rRadiotapFieldVendor; + uint8_t *prVendorNsOffset; + uint32_t u4VendorNsLen; + uint32_t u4RadiotapLen; + uint32_t u4ItPresent; + uint8_t aucMtkOui[] = VENDOR_OUI_MTK; + uint8_t ucRxRate; + uint8_t ucRxMode; + uint8_t ucChanNum = 0; + uint8_t ucMcs; + uint8_t ucFrMode; + uint8_t ucShortGI; + uint32_t u4PhyRate; + struct RX_DESC_OPS_T *prRxDescOps; + enum ENUM_BAND eBand = 0; + +#if CFG_SUPPORT_MULTITHREAD + KAL_SPIN_LOCK_DECLARATION(); +#endif + + DEBUGFUNC("nicRxProcessMonitorPacket"); + + ASSERT(prAdapter); + ASSERT(prSwRfb); + prRxDescOps = prAdapter->chip_info->prRxDescOps; + + prRxCtrl = &prAdapter->rRxCtrl; + + nicRxFillRFB(prAdapter, prSwRfb); + + /* can't parse radiotap info if no rx vector */ + if (((prSwRfb->ucGroupVLD & BIT(RX_GROUP_VLD_2)) == 0) + || ((prSwRfb->ucGroupVLD & BIT(RX_GROUP_VLD_3)) == 0)) { + nicRxReturnRFB(prAdapter, prSwRfb); + return; + } + + prRxStatus = prSwRfb->prRxStatus; + prRxStatusGroup2 = prSwRfb->prRxStatusGroup2; + prRxStatusGroup3 = prSwRfb->prRxStatusGroup3; + + /* Bit Number 30 Vendor Namespace */ + u4VendorNsLen = sizeof(struct RADIOTAP_FIELD_VENDOR_); + rRadiotapFieldVendor.aucOUI[0] = aucMtkOui[0]; + rRadiotapFieldVendor.aucOUI[1] = aucMtkOui[1]; + rRadiotapFieldVendor.aucOUI[2] = aucMtkOui[2]; + rRadiotapFieldVendor.ucSubNamespace = 0; + rRadiotapFieldVendor.u2DataLen = u4VendorNsLen - 6; + /* VHTA1 B0-B1 */ + rRadiotapFieldVendor.ucData = ((( + prRxStatusGroup3)->u4RxVector[0] + & RX_VT_FR_MODE_MASK) >> + RX_VT_FR_MODE_OFFSET); + + ucRxMode = (((prRxStatusGroup3)->u4RxVector[0] & + RX_VT_RX_MODE_MASK) >> RX_VT_RX_MODE_OFFSET); + + if (ucRxMode == RX_VT_VHT_MODE) { + u4RadiotapLen = RADIOTAP_LEN_VHT; + u4ItPresent = RADIOTAP_FIELDS_VHT; + } else if ((ucRxMode == RX_VT_MIXED_MODE) + || (ucRxMode == RX_VT_GREEN_MODE)) { + u4RadiotapLen = RADIOTAP_LEN_HT; + u4ItPresent = RADIOTAP_FIELDS_HT; + } else { + u4RadiotapLen = RADIOTAP_LEN_LEGACY; + u4ItPresent = RADIOTAP_FIELDS_LEGACY; + } + + /* Radiotap Header & Bit Number 30 Vendor Namespace */ + prVendorNsOffset = (uint8_t *) &rMonitorRadiotap + + u4RadiotapLen; + u4RadiotapLen += u4VendorNsLen; + kalMemSet(&rMonitorRadiotap, 0, + sizeof(struct MONITOR_RADIOTAP)); + kalMemCopy(prVendorNsOffset, + (uint8_t *) &rRadiotapFieldVendor, u4VendorNsLen); + rMonitorRadiotap.u2ItLen = cpu_to_le16(u4RadiotapLen); + rMonitorRadiotap.u4ItPresent = u4ItPresent; + + /* Bit Number 0 TSFT */ + rMonitorRadiotap.u8MacTime = + (prRxStatusGroup2->u4Timestamp); + + /* Bit Number 1 FLAGS */ + if (prSwRfb->fgIsFrag) + rMonitorRadiotap.ucFlags |= BIT(3); + + if (prSwRfb->fgIsFCS) + rMonitorRadiotap.ucFlags |= BIT(6); + + /* Bit Number 2 RATE */ + if ((ucRxMode == RX_VT_LEGACY_CCK) + || (ucRxMode == RX_VT_LEGACY_OFDM)) { + /* Bit[2:0] for Legacy CCK, Bit[3:0] for Legacy OFDM */ + ucRxRate = ((prRxStatusGroup3)->u4RxVector[0] & BITS(0, 3)); + rMonitorRadiotap.ucRate = nicGetHwRateByPhyRate(ucRxRate); + } else { + ucMcs = ((prRxStatusGroup3)->u4RxVector[0] & + RX_VT_RX_RATE_AC_MASK); + /* VHTA1 B0-B1 */ + ucFrMode = (((prRxStatusGroup3)->u4RxVector[0] & + RX_VT_FR_MODE_MASK) >> RX_VT_FR_MODE_OFFSET); + ucShortGI = ((prRxStatusGroup3)->u4RxVector[0] & + RX_VT_SHORT_GI) ? 1 : 0; /* VHTA2 B0 */ + + /* ucRate(500kbs) = u4PhyRate(100kbps) / 5, max ucRate = 0xFF */ + u4PhyRate = nicGetPhyRateByMcsRate(ucMcs, ucFrMode, + ucShortGI); + if (u4PhyRate > 1275) + rMonitorRadiotap.ucRate = 0xFF; + else + rMonitorRadiotap.ucRate = u4PhyRate / 5; + } + + /* Bit Number 3 CHANNEL */ + if (ucRxMode == RX_VT_LEGACY_CCK) + rMonitorRadiotap.u2ChFlags |= BIT(5); + else /* OFDM */ + rMonitorRadiotap.u2ChFlags |= BIT(6); + + RX_STATUS_GET(prRxDescOps, ucChanNum, get_ch_num, prRxStatus); + RX_STATUS_GET(prRxDescOps, eBand, get_rf_band, prRxStatus); + if (eBand == BAND_2G4) { + rMonitorRadiotap.u2ChFlags |= BIT(7); + rMonitorRadiotap.u2ChFrequency = (ucChanNum * 5 + 2407); + } else { /* BAND_5G */ + rMonitorRadiotap.u2ChFlags |= BIT(8); + rMonitorRadiotap.u2ChFrequency = (ucChanNum * 5 + 5000); + } + + /* Bit Number 5 ANT SIGNAL */ + rMonitorRadiotap.ucAntennaSignal = + RCPI_TO_dBm(HAL_RX_STATUS_GET_RCPI0(prRxStatusGroup3)); + + /* Bit Number 6 ANT NOISE */ + rMonitorRadiotap.ucAntennaNoise = (((( + prRxStatusGroup3)->u4RxVector[5] + & RX_VT_NF0_MASK) >> 1) + + 128); + + /* Bit Number 11 ANT, Invalid for MT6632 and MT7615 */ + rMonitorRadiotap.ucAntenna = (( + prRxStatusGroup3)->u4RxVector[2] & RX_VT_SEL_ANT) ? 1 : 0; + + /* Bit Number 19 MCS */ + if ((u4ItPresent & RADIOTAP_FIELD_MCS)) + nicRxFillRadiotapMCS(&rMonitorRadiotap, prRxStatusGroup3); + + /* Bit Number 20 AMPDU */ + if (prSwRfb->fgIsAmpdu) { + if (prSwRfb->ucRxvSeqNo) + ++prRxCtrl->u4AmpduRefNum; + rMonitorRadiotap.u4AmpduRefNum = prRxCtrl->u4AmpduRefNum; + } + + /* Bit Number 21 VHT */ + if ((u4ItPresent & RADIOTAP_FIELD_VHT)) + nicRxFillRadiotapVHT(&rMonitorRadiotap, prRxStatusGroup3); + + prSwRfb->pvHeader -= u4RadiotapLen; + kalMemCopy(prSwRfb->pvHeader, &rMonitorRadiotap, + u4RadiotapLen); + + prSkb = (struct sk_buff *)(prSwRfb->pvPacket); + prSkb->data = (unsigned char *)(prSwRfb->pvHeader); + + skb_reset_tail_pointer(prSkb); + skb_trim(prSkb, 0); + skb_put(prSkb, (u4RadiotapLen + prSwRfb->u2PacketLen)); + +#if CFG_SUPPORT_MULTITHREAD + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_TO_OS_QUE); + QUEUE_INSERT_TAIL(&(prAdapter->rRxQueue), + (struct QUE_ENTRY *) GLUE_GET_PKT_QUEUE_ENTRY( + prSwRfb->pvPacket)); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_TO_OS_QUE); + + prRxCtrl->ucNumIndPacket++; + kalSetTxEvent2Rx(prAdapter->prGlueInfo); +#else + prRxCtrl->apvIndPacket[prRxCtrl->ucNumIndPacket] = + prSwRfb->pvPacket; + prRxCtrl->ucNumIndPacket++; +#endif + + prSwRfb->pvPacket = NULL; + /* Return RFB */ + if (nicRxSetupRFB(prAdapter, prSwRfb)) { + DBGLOG(RX, WARN, + "Cannot allocate packet buffer for SwRfb!\n"); + if (!timerPendingTimer( + &prAdapter->rPacketDelaySetupTimer)) { + DBGLOG(RX, WARN, + "Start ReturnIndicatedRfb Timer (%u)\n", + RX_RETURN_INDICATED_RFB_TIMEOUT_SEC); + cnmTimerStartTimer(prAdapter, + &prAdapter->rPacketDelaySetupTimer, + SEC_TO_MSEC( + RX_RETURN_INDICATED_RFB_TIMEOUT_SEC)); + } + } + nicRxReturnRFB(prAdapter, prSwRfb); +} +#else +/*----------------------------------------------------------------------------*/ +/*! + * @brief Process HIF monitor packet + * + * @param prAdapter pointer to the Adapter handler + * @param prSWRfb the RFB to receive rx data + * + * @return (none) + * + */ +/*----------------------------------------------------------------------------*/ +void nicRxProcessMonitorPacket(IN struct ADAPTER *prAdapter, + IN OUT struct SW_RFB *prSwRfb) +{ +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Process & Parsing RXV for traffic indicator + * + * @param prAdapter pointer to the Adapter handler + * @param prSWRfb the RFB to receive rx data + * + * @return (none) + * + */ +/*----------------------------------------------------------------------------*/ +#if CFG_SUPPORT_PERF_IND +void nicRxPerfIndProcessRXV(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, + IN uint8_t ucBssIndex) +{ + struct mt66xx_chip_info *prChipInfo; + + prChipInfo = prAdapter->chip_info; + if (prChipInfo->asicRxPerfIndProcessRXV) + prChipInfo->asicRxPerfIndProcessRXV( + prAdapter, prSwRfb, ucBssIndex); + /* else { */ + /* print too much, remove for system perfomance */ + /* DBGLOG(RX, ERROR, "%s: no asicRxPerfIndProcessRXV ??\n", */ + /* __func__); */ + /* } */ +} +#endif + +static void nicRxSendDeauthPacket(IN struct ADAPTER *prAdapter, + IN uint16_t u2FrameCtrl, + IN uint8_t *pucSrcAddr, + IN uint8_t *pucDestAddr, + IN uint8_t *pucBssid) +{ + struct SW_RFB rSwRfb; + struct WLAN_MAC_HEADER rWlanHeader; + uint32_t u4Status; + + if (!prAdapter || !pucSrcAddr || !pucDestAddr || !pucBssid) + return; + + kalMemZero(&rSwRfb, sizeof(rSwRfb)); + kalMemZero(&rWlanHeader, sizeof(rWlanHeader)); + + rWlanHeader.u2FrameCtrl = u2FrameCtrl; + COPY_MAC_ADDR(rWlanHeader.aucAddr1, pucSrcAddr); + COPY_MAC_ADDR(rWlanHeader.aucAddr2, pucDestAddr); + COPY_MAC_ADDR(rWlanHeader.aucAddr3, pucBssid); + rSwRfb.pvHeader = &rWlanHeader; + + u4Status = authSendDeauthFrame(prAdapter, + NULL, + NULL, + &rSwRfb, + REASON_CODE_CLASS_3_ERR, + NULL); + if (u4Status != WLAN_STATUS_SUCCESS) + DBGLOG(NIC, WARN, "u4Status: %d\n", u4Status); +} + +static void nicRxProcessDropPacket(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb) +{ + struct WLAN_MAC_HEADER *prWlanHeader = NULL; + uint8_t ucBssIndex = 0; + uint16_t u2FrameCtrl; + + if (!prAdapter || !prSwRfb) + return; + + prWlanHeader = (struct WLAN_MAC_HEADER *) prSwRfb->pvHeader; + + if (!prWlanHeader) + return; + + u2FrameCtrl = prWlanHeader->u2FrameCtrl; + DBGLOG(RX, TEMP, + "TA: " MACSTR " RA: " MACSTR " bssid: " MACSTR " fc: 0x%x\n", + MAC2STR(prWlanHeader->aucAddr2), + MAC2STR(prWlanHeader->aucAddr1), + MAC2STR(prWlanHeader->aucAddr3), + u2FrameCtrl); + + if ((u2FrameCtrl & (MASK_FC_FROM_DS | MASK_FC_TO_DS)) == 0) + return; + + for (ucBssIndex = 0; ucBssIndex < prAdapter->ucHwBssIdNum; + ucBssIndex++) { + struct BSS_INFO *prBssInfo; + u_int8_t fgSendDeauth = FALSE; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + if (!prBssInfo) + continue; + if (IS_BSS_NOT_ALIVE(prAdapter, prBssInfo)) + continue; + switch (prBssInfo->eNetworkType) { + case NETWORK_TYPE_P2P: + if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT && + EQUAL_MAC_ADDR(prWlanHeader->aucAddr3, + prBssInfo->aucOwnMacAddr)) + fgSendDeauth = TRUE; + break; + default: + break; + } + + if (fgSendDeauth) + nicRxSendDeauthPacket(prAdapter, + u2FrameCtrl, + prWlanHeader->aucAddr1, + prWlanHeader->aucAddr2, + prWlanHeader->aucAddr3); + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Process HIF data packet + * + * @param prAdapter pointer to the Adapter handler + * @param prSWRfb the RFB to receive rx data + * + * @return (none) + * + */ +/*----------------------------------------------------------------------------*/ +void nicRxProcessDataPacket(IN struct ADAPTER *prAdapter, + IN OUT struct SW_RFB *prSwRfb) +{ + struct RX_CTRL *prRxCtrl; + struct SW_RFB *prRetSwRfb, *prNextSwRfb; + struct HW_MAC_RX_DESC *prRxStatus; + + u_int8_t fgDrop; + uint8_t ucBssIndex = 0; + struct mt66xx_chip_info *prChipInfo; + struct STA_RECORD *prStaRec; + struct RX_DESC_OPS_T *prRxDescOps; + + DEBUGFUNC("nicRxProcessDataPacket"); + /* DBGLOG(INIT, TRACE, ("\n")); */ + + ASSERT(prAdapter); + ASSERT(prSwRfb); + + nicRxFillRFB(prAdapter, prSwRfb); + + fgDrop = FALSE; + + prRxCtrl = &prAdapter->rRxCtrl; + prChipInfo = prAdapter->chip_info; + prRxDescOps = prChipInfo->prRxDescOps; + prRxStatus = prSwRfb->prRxStatus; + + /* Check AMPDU_nERR_Bitmap */ + prSwRfb->fgDataFrame = TRUE; + prSwRfb->fgFragFrame = FALSE; + prSwRfb->fgReorderBuffer = FALSE; + +#if CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION + prSwRfb->fgIsFirstSubAMSDULLCMS = FALSE; +#endif /* CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION */ + +#if CFG_WIFI_SW_CIPHER_MISMATCH + if (prSwRfb->prStaRec && + prSwRfb->prStaRec->fgTransmitKeyExist && + prSwRfb->prStaRec->ucStaState == STA_STATE_3 && + prSwRfb->fgIsBC == FALSE && + prSwRfb->fgIsMC == FALSE && + !prSwRfb->fgIsCipherMS) { + uint16_t u2FrameCtrl = 0; + + if (prSwRfb->fgHdrTran == FALSE) { + u2FrameCtrl = ((struct WLAN_MAC_HEADER *) + prSwRfb->pvHeader)->u2FrameCtrl; + prSwRfb->fgIsCipherMS = + !RXM_IS_PROTECTED_FRAME(u2FrameCtrl); + } else if (prSwRfb->prRxStatusGroup4) { + u2FrameCtrl = HAL_RX_STATUS_GET_FRAME_CTL_FIELD( + prSwRfb->prRxStatusGroup4); + prSwRfb->fgIsCipherMS = + !RXM_IS_PROTECTED_FRAME(u2FrameCtrl); + } + } +#endif + + if (prRxDescOps->nic_rxd_sanity_check) + fgDrop = prRxDescOps->nic_rxd_sanity_check( + prAdapter, prSwRfb); + else { + DBGLOG(RX, ERROR, + "%s:: no nic_rxd_sanity_check??\n", __func__); + fgDrop = TRUE; + } + + if (fgDrop && prRxStatus->ucWlanIdx >= WTBL_SIZE && + HAL_RX_STATUS_IS_LLC_MIS(prRxStatus)) + nicRxProcessDropPacket(prAdapter, prSwRfb); + +#if CFG_TCP_IP_CHKSUM_OFFLOAD || CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60 + if (prAdapter->fgIsSupportCsumOffload && fgDrop == FALSE) + nicRxFillChksumStatus(prAdapter, prSwRfb); +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ + + /* if(secCheckClassError(prAdapter, prSwRfb, prStaRec) == TRUE && */ + if (prAdapter->fgTestMode == FALSE && fgDrop == FALSE) { +#if CFG_HIF_RX_STARVATION_WARNING + prRxCtrl->u4QueuedCnt++; +#endif + ucBssIndex = secGetBssIdxByWlanIdx(prAdapter, + prSwRfb->ucWlanIdx); + GLUE_SET_PKT_BSS_IDX(prSwRfb->pvPacket, ucBssIndex); + STATS_RX_PKT_INFO_DISPLAY(prSwRfb); + +#if ((CFG_SUPPORT_802_11AX == 1) && (CFG_SUPPORT_WIFI_SYSDVT == 1)) + if (fgEfuseCtrlAxOn == 1) { + if (prAdapter->fgEnShowHETrigger) { + uint16_t u2TxFrameCtrl; + + u2TxFrameCtrl = (*(uint8_t *) (prSwRfb->pvHeader) & + MASK_FRAME_TYPE); + if (RXM_IS_TRIGGER_FRAME(u2TxFrameCtrl)) { + DBGLOG(NIC, STATE, + "\n%s: HE Trigger --------------\n", + __func__); + dumpMemory8((uint8_t *)prSwRfb->prRxStatus, + prSwRfb->u2RxByteCount); + DBGLOG(NIC, STATE, + "%s: HE Trigger end --------------\n", + __func__); + nicRxReturnRFB(prAdapter, prSwRfb); + return; + } + } + } +#endif /* CFG_SUPPORT_802_11AX == 1 */ + + prRetSwRfb = qmHandleRxPackets(prAdapter, prSwRfb); + if (prRetSwRfb != NULL) { + do { +#if (CFG_SUPPORT_MSP == 1) + /* collect RXV information */ + if (prChipInfo->asicRxProcessRxvforMSP) + prChipInfo->asicRxProcessRxvforMSP( + prAdapter, prRetSwRfb); +#endif /* CFG_SUPPORT_MSP == 1 */ +#if CFG_SUPPORT_PERF_IND + nicRxPerfIndProcessRXV( + prAdapter, + prRetSwRfb, + ucBssIndex); +#endif + + /* save next first */ + prNextSwRfb = (struct SW_RFB *) + QUEUE_GET_NEXT_ENTRY( + (struct QUE_ENTRY *) + prRetSwRfb); + + switch (prRetSwRfb->eDst) { + case RX_PKT_DESTINATION_HOST: + prStaRec = cnmGetStaRecByIndex( + prAdapter, + prRetSwRfb->ucStaRecIdx); + if (prStaRec && + IS_STA_IN_AIS(prStaRec)) { +#if ARP_MONITER_ENABLE + qmHandleRxArpPackets( + prAdapter, + prRetSwRfb); +#endif + } + + if (prStaRec) { /* STA or GC */ + qmHandleRxDhcpPackets( + prAdapter, + prRetSwRfb); + } +#if CFG_SUPPORT_WIFI_SYSDVT +#if (CFG_SUPPORT_CONNAC2X == 1) + /* Not handle non-CONNAC2X case */ + if (RXV_AUTODVT_DNABLED(prAdapter) && + (prRetSwRfb->ucGroupVLD & + BIT(RX_GROUP_VLD_3)) && + (prRetSwRfb->ucGroupVLD & + BIT(RX_GROUP_VLD_5))) { + connac2x_rxv_correct_test( + prAdapter, prRetSwRfb); + } +#endif +#endif /* CFG_SUPPORT_WIFI_SYSDVT */ + if (prStaRec && + prStaRec->ucBssIndex < MAX_BSSID_NUM) { + GET_BOOT_SYSTIME( + &prRxCtrl->u4LastRxTime + [prStaRec->ucBssIndex]); + } + nicRxProcessPktWithoutReorder( + prAdapter, prRetSwRfb); + break; + + case RX_PKT_DESTINATION_FORWARD: + nicRxProcessForwardPkt( + prAdapter, prRetSwRfb); + break; + + case RX_PKT_DESTINATION_HOST_WITH_FORWARD: + nicRxProcessGOBroadcastPkt(prAdapter, + prRetSwRfb); + break; + + case RX_PKT_DESTINATION_NULL: + nicRxReturnRFB(prAdapter, prRetSwRfb); + RX_INC_CNT(prRxCtrl, + RX_DST_NULL_DROP_COUNT); + RX_INC_CNT(prRxCtrl, + RX_DROP_TOTAL_COUNT); + break; + + default: + break; + } +#if CFG_HIF_RX_STARVATION_WARNING + prRxCtrl->u4DequeuedCnt++; +#endif + prRetSwRfb = prNextSwRfb; + } while (prRetSwRfb); + } + } else { + nicRxReturnRFB(prAdapter, prSwRfb); + RX_INC_CNT(prRxCtrl, RX_CLASS_ERR_DROP_COUNT); + RX_INC_CNT(prRxCtrl, RX_DROP_TOTAL_COUNT); + } +} + +#if 1 +void nicRxProcessEventPacket(IN struct ADAPTER *prAdapter, + IN OUT struct SW_RFB *prSwRfb) +{ + struct mt66xx_chip_info *prChipInfo; + struct CMD_INFO *prCmdInfo; + struct WIFI_EVENT *prEvent; + uint32_t u4Idx, u4Size; + + ASSERT(prAdapter); + ASSERT(prSwRfb); + prChipInfo = prAdapter->chip_info; + prEvent = (struct WIFI_EVENT *) + (prSwRfb->pucRecvBuff + prChipInfo->rxd_size); + if (prEvent->ucEID != EVENT_ID_DEBUG_MSG + && prEvent->ucEID != EVENT_ID_ASSERT_DUMP) { + DBGLOG_LIMITED(NIC, TRACE, + "RX EVENT: ID[0x%02X] SEQ[%u] LEN[%u]\n", + prEvent->ucEID, prEvent->ucSeqNum, + prEvent->u2PacketLength); + } +#if (CFG_SUPPORT_STATISTICS == 1) + wlanWakeLogEvent(prEvent->ucEID); +#endif + /* Event handler table */ + u4Size = sizeof(arEventTable) / sizeof(struct + RX_EVENT_HANDLER); + + for (u4Idx = 0; u4Idx < u4Size; u4Idx++) { + if (prEvent->ucEID == arEventTable[u4Idx].eEID) { + arEventTable[u4Idx].pfnHandler(prAdapter, prEvent); + + break; + } + } + + /* Event cannot be found in event handler table, use default action */ + if (u4Idx >= u4Size) { + prCmdInfo = nicGetPendingCmdInfo(prAdapter, + prEvent->ucSeqNum); + + if (prCmdInfo != NULL) { + if (prCmdInfo->pfCmdDoneHandler) + prCmdInfo->pfCmdDoneHandler( + prAdapter, prCmdInfo, + prEvent->aucBuffer); + else if (prCmdInfo->fgIsOid) + kalOidComplete( + prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, + 0, + WLAN_STATUS_SUCCESS); + + /* return prCmdInfo */ + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + } else { + DBGLOG_LIMITED(RX, INFO, + "UNHANDLED RX EVENT: ID[0x%02X] SEQ[%u] LEN[%u]\n", + prEvent->ucEID, prEvent->ucSeqNum, + prEvent->u2PacketLength); + } + } + + /* Reset Chip NoAck flag */ + if (prAdapter->fgIsChipNoAck) { + DBGLOG_LIMITED(RX, WARN, + "Got response from chip, clear NoAck flag!\n"); + WARN_ON(TRUE); + } + prAdapter->ucOidTimeoutCount = 0; + prAdapter->fgIsChipNoAck = FALSE; + + nicRxReturnRFB(prAdapter, prSwRfb); +} +#else +u_int8_t fgKeepPrintCoreDump = FALSE; +/*----------------------------------------------------------------------------*/ +/*! + * @brief Process HIF event packet + * + * @param prAdapter pointer to the Adapter handler + * @param prSWRfb the RFB to receive rx data + * + * @return (none) + * + */ +/*----------------------------------------------------------------------------*/ +void nicRxProcessEventPacket(IN struct ADAPTER *prAdapter, + IN OUT struct SW_RFB *prSwRfb) +{ + struct CMD_INFO *prCmdInfo; + /* P_MSDU_INFO_T prMsduInfo; */ + struct WIFI_EVENT *prEvent; + struct GLUE_INFO *prGlueInfo; + u_int8_t fgIsNewVersion; + /*#if (CFG_EFUSE_BUFFER_MODE_DELAY_CAL == 1)*/ + uint32_t u4QueryInfoLen; + /*#endif*/ + /*#if (CFG_EEPROM_PAGE_ACCESS == 1)*/ + struct EVENT_ACCESS_EFUSE *prEventEfuseAccess; + struct EXT_EVENT_EFUSE_FREE_BLOCK *prEventGetFreeBlock; + /*#endif*/ + DEBUGFUNC("nicRxProcessEventPacket"); + /* DBGLOG(INIT, TRACE, ("\n")); */ + + ASSERT(prAdapter); + ASSERT(prSwRfb); + + nicRxFillRFB(prAdapter, prSwRfb); + if (prSwRfb->prRxStatusGroup3 == NULL) { + DBGLOG(RX, WARN, + "rxStatusGroup3 for MGMT frame is NULL, drop this packet, dump RXD and Packet\n"); + DBGLOG_MEM8(RX, WARN, (uint8_t *) prSwRfb->prRxStatus, + sizeof(*prSwRfb->prRxStatus)); + if (prSwRfb->pvHeader) + DBGLOG_MEM8(RX, WARN, (uint8_t *) prSwRfb->pvHeader, + prSwRfb->u2PacketLen > 32 ? + 32 : prSwRfb->u2PacketLen); + nicRxReturnRFB(prAdapter, prSwRfb); + RX_INC_CNT(&prAdapter->rRxCtrl, RX_DROP_TOTAL_COUNT); +#if 0 +#if CFG_CHIP_RESET_SUPPORT + glSetRstReason(RST_GROUP3_NULL); + glResetTrigger(prAdapter); +#endif +#endif + ) { + DBGLOG(INIT, INFO, + "RX EVENT: ID[0x%02X] SEQ[%u] LEN[%u]\n", + prEvent->ucEID, prEvent->ucSeqNum, + prEvent->u2PacketLength); + } + + /* Event Handling */ + switch (prEvent->ucEID) { +#if 0 /* It is removed now */ + case EVENT_ID_CMD_RESULT: + prCmdInfo = nicGetPendingCmdInfo(prAdapter, + prEvent->ucSeqNum); + + if (prCmdInfo != NULL) { + struct EVENT_CMD_RESULT *prCmdResult; + + prCmdResult = (struct EVENT_CMD_RESULT *) + ((uint8_t *) prEvent + EVENT_HDR_SIZE); + + /* CMD_RESULT should be only in response to + * Set commands + */ + ASSERT(prCmdInfo->fgSetQuery == FALSE + || prCmdInfo->fgNeedResp == TRUE); + + if (prCmdResult->ucStatus == 0) { + /* success */ + if (prCmdInfo->pfCmdDoneHandler) { + prCmdInfo->pfCmdDoneHandler( + prAdapter, prCmdInfo, + prEvent->aucBuffer); + } else if (prCmdInfo->fgIsOid == TRUE) { + kalOidComplete( + prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, + 0, + WLAN_STATUS_SUCCESS); + } + } else if (prCmdResult->ucStatus == 1) { + /* reject */ + if (prCmdInfo->fgIsOid == TRUE) + kalOidComplete( + prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, + 0, + WLAN_STATUS_FAILURE); + } else if (prCmdResult->ucStatus == 2) { + /* unknown CMD */ + if (prCmdInfo->fgIsOid == TRUE) + kalOidComplete( + prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, + 0, + WLAN_STATUS_NOT_SUPPORTED + ); + } + /* return prCmdInfo */ + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + } + + break; +#endif + +#if 0 + case EVENT_ID_CONNECTION_STATUS: + /* OBSELETE */ + { + struct EVENT_CONNECTION_STATUS *prConnectionStatus; + + prConnectionStatus = + (struct EVENT_CONNECTION_STATUS *) + (prEvent->aucBuffer); + + DbgPrint("RX EVENT: EVENT_ID_CONNECTION_STATUS = %d\n", + prConnectionStatus->ucMediaStatus); + if (prConnectionStatus->ucMediaStatus == + MEDIA_STATE_DISCONNECTED) { + /* disconnected */ + if (kalGetMediaStateIndicated(prGlueInfo) != + MEDIA_STATE_DISCONNECTED) { + + kalIndicateStatusAndComplete(prGlueInfo, + WLAN_STATUS_MEDIA_DISCONNECT, + NULL, 0); + + prAdapter->rWlanInfo.u4SysTime = + kalGetTimeTick(); + } + } else if (prConnectionStatus->ucMediaStatus == + MEDIA_STATE_CONNECTED) { + /* connected */ + prAdapter->rWlanInfo.u4SysTime = + kalGetTimeTick(); + + /* fill information for association result */ + prAdapter->rWlanInfo.rCurrBssId.rSsid. + u4SsidLen = prConnectionStatus->ucSsidLen; + kalMemCopy( + prAdapter->rWlanInfo.rCurrBssId. + rSsid.aucSsid, + prConnectionStatus->aucSsid, + prConnectionStatus->ucSsidLen); + + kalMemCopy( + prAdapter->rWlanInfo.rCurrBssId. + arMacAddress, + prConnectionStatus->aucBssid, + MAC_ADDR_LEN); + /* @FIXME */ + prAdapter->rWlanInfo.rCurrBssId.u4Privacy = + prConnectionStatus->ucEncryptStatus; + /* @FIXME */ + prAdapter->rWlanInfo.rCurrBssId.rRssi = 0; + /* @FIXME */ + prAdapter->rWlanInfo.rCurrBssId. + eNetworkTypeInUse = PARAM_NETWORK_TYPE_AUTOMODE; + prAdapter->rWlanInfo.rCurrBssId.rConfiguration. + u4BeaconPeriod + = prConnectionStatus->u2BeaconPeriod; + prAdapter->rWlanInfo.rCurrBssId.rConfiguration. + u4ATIMWindow + = prConnectionStatus->u2ATIMWindow; + prAdapter->rWlanInfo.rCurrBssId.rConfiguration. + u4DSConfig + = prConnectionStatus->u4FreqInKHz; + prAdapter->rWlanInfo.ucNetworkType = + prConnectionStatus->ucNetworkType; + + switch (prConnectionStatus->ucInfraMode) { + case 0: + prAdapter->rWlanInfo.rCurrBssId.eOpMode + = NET_TYPE_IBSS; + break; + case 1: + prAdapter->rWlanInfo.rCurrBssId.eOpMode + = NET_TYPE_INFRA; + break; + case 2: + default: + prAdapter->rWlanInfo.rCurrBssId.eOpMode + = NET_TYPE_AUTO_SWITCH; + break; + } + /* always indicate to OS according to MSDN + * (re-association/roaming) + */ + kalIndicateStatusAndComplete(prGlueInfo, + WLAN_STATUS_MEDIA_CONNECT, NULL, 0); + } + } + break; + + case EVENT_ID_SCAN_RESULT: + /* OBSELETE */ + break; +#endif + + case EVENT_ID_RX_ADDBA: + /* The FW indicates that an RX BA agreement + * will be established + */ + qmHandleEventRxAddBa(prAdapter, prEvent); + break; + + case EVENT_ID_RX_DELBA: + /* The FW indicates that an RX BA agreement + * has been deleted + */ + qmHandleEventRxDelBa(prAdapter, prEvent); + break; + + case EVENT_ID_CHECK_REORDER_BUBBLE: + qmHandleEventCheckReorderBubble(prAdapter, prEvent); + break; + + case EVENT_ID_LINK_QUALITY: +#if CFG_ENABLE_WIFI_DIRECT && CFG_SUPPORT_P2P_RSSI_QUERY + if (prEvent->u2PacketLen == EVENT_HDR_SIZE + sizeof( + struct EVENT_LINK_QUALITY_EX)) { + struct EVENT_LINK_QUALITY_EX *prLqEx = + (struct EVENT_LINK_QUALITY_EX *) + (prEvent->aucBuffer); + + if (prLqEx->ucIsLQ0Rdy) + nicUpdateLinkQuality(prAdapter, 0, + (struct EVENT_LINK_QUALITY *) + prLqEx); + if (prLqEx->ucIsLQ1Rdy) + nicUpdateLinkQuality(prAdapter, 1, + (struct EVENT_LINK_QUALITY *) + prLqEx); + } else { + /* For old FW, P2P may invoke link quality + * query, and make driver flag becone TRUE. + */ + DBGLOG(P2P, WARN, + "Old FW version, not support P2P RSSI query.\n"); + + /* Must not use NETWORK_TYPE_P2P_INDEX, + * cause the structure is mismatch. + */ + nicUpdateLinkQuality(prAdapter, 0, + (struct EVENT_LINK_QUALITY *) + (prEvent->aucBuffer)); + } +#else + /*only support ais query */ + { + uint8_t ucBssIndex; + struct BSS_INFO *prBssInfo; + + for (ucBssIndex = 0; + ucBssIndex < prAdapter->ucHwBssIdNum; + ucBssIndex++) { + prBssInfo = + prAdapter->aprBssInfo[ + ucBssIndex]; + + if ((prBssInfo->eNetworkType == + NETWORK_TYPE_AIS) + && (prBssInfo->fgIsInUse)) + break; + } + + /* No hit(bss1 for default ais network) */ + if (ucBssIndex >= prAdapter->ucHwBssIdNum) + ucBssIndex = 1; + + nicUpdateLinkQuality(prAdapter, ucBssIndex, + (struct EVENT_LINK_QUALITY *) + (prEvent->aucBuffer)); + } + +#endif + + /* command response handling */ + prCmdInfo = nicGetPendingCmdInfo(prAdapter, + prEvent->ucSeqNum); + + if (prCmdInfo != NULL) { + if (prCmdInfo->pfCmdDoneHandler) + prCmdInfo->pfCmdDoneHandler( + prAdapter, prCmdInfo, + prEvent->aucBuffer); + else if (prCmdInfo->fgIsOid) + kalOidComplete( + prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, + 0, WLAN_STATUS_SUCCESS); + /* return prCmdInfo */ + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + } +#ifndef LINUX + if (prAdapter->rWlanInfo.eRssiTriggerType == + ENUM_RSSI_TRIGGER_GREATER && + prAdapter->rWlanInfo.rRssiTriggerValue + >= (int32_t) ( + prAdapter->rLinkQuality.cRssi)) { + prAdapter->rWlanInfo.eRssiTriggerType = + ENUM_RSSI_TRIGGER_TRIGGERED; + + kalIndicateStatusAndComplete(prGlueInfo, + WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, + (void *) + &(prAdapter->rWlanInfo. + rRssiTriggerValue), + sizeof(int32_t)); + } else if (prAdapter->rWlanInfo.eRssiTriggerType == + ENUM_RSSI_TRIGGER_LESS + && prAdapter->rWlanInfo.rRssiTriggerValue + <= (int32_t) ( + prAdapter->rLinkQuality.cRssi)) { + prAdapter->rWlanInfo.eRssiTriggerType = + ENUM_RSSI_TRIGGER_TRIGGERED; + + kalIndicateStatusAndComplete(prGlueInfo, + WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, + (void *) + &(prAdapter->rWlanInfo. + rRssiTriggerValue), + sizeof(int32_t)); + } +#endif + + break; + + /*#if (CFG_EFUSE_BUFFER_MODE_DELAY_CAL == 1)*/ + case EVENT_ID_LAYER_0_EXT_MAGIC_NUM: + if ((prEvent->ucExtenEID) == EXT_EVENT_ID_CMD_RESULT) { + + u4QueryInfoLen = + sizeof( + struct PARAM_CUSTOM_EFUSE_BUFFER_MODE); + + prCmdInfo = nicGetPendingCmdInfo(prAdapter, + prEvent->ucSeqNum); + + if (prCmdInfo != NULL) { + if ((prCmdInfo->fgIsOid) != 0) { + kalOidComplete( + prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, + u4QueryInfoLen, + WLAN_STATUS_SUCCESS); + /* return prCmdInfo */ + cmdBufFreeCmdInfo( + prAdapter, prCmdInfo); + } + } + } + /*#if (CFG_EEPROM_PAGE_ACCESS == 1)*/ + + else if ((prEvent->ucExtenEID) == + EXT_EVENT_ID_CMD_EFUSE_ACCESS) { + u4QueryInfoLen = + sizeof( + struct PARAM_CUSTOM_ACCESS_EFUSE); + prCmdInfo = nicGetPendingCmdInfo(prAdapter, + prEvent->ucSeqNum); + prEventEfuseAccess = + (struct EVENT_ACCESS_EFUSE *) + (prEvent->aucBuffer); + + /* Efuse block size 16 */ + kalMemCopy(prAdapter->aucEepromVaule, + prEventEfuseAccess->aucData, 16); + + if (prCmdInfo != NULL) { + if ((prCmdInfo->fgIsOid) != 0) { + kalOidComplete( + prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, + u4QueryInfoLen, + WLAN_STATUS_SUCCESS); + /* return prCmdInfo */ + cmdBufFreeCmdInfo( + prAdapter, prCmdInfo); + + } + } + } + + else if ((prEvent->ucExtenEID) == + EXT_EVENT_ID_EFUSE_FREE_BLOCK) { + u4QueryInfoLen = sizeof(struct + PARAM_CUSTOM_EFUSE_FREE_BLOCK); + prCmdInfo = nicGetPendingCmdInfo(prAdapter, + prEvent->ucSeqNum); + prEventGetFreeBlock = + (struct EXT_EVENT_EFUSE_FREE_BLOCK *) + (prEvent->aucBuffer); + prAdapter->u4FreeBlockNum = + prEventGetFreeBlock->u2FreeBlockNum; + + if (prCmdInfo != NULL) { + if ((prCmdInfo->fgIsOid) != 0) { + kalOidComplete( + prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, + u4QueryInfoLen, + WLAN_STATUS_SUCCESS); + /* return prCmdInfo */ + cmdBufFreeCmdInfo(prAdapter, + prCmdInfo); + } + } + } + /*#endif*/ + break; + /*#endif*/ + + case EVENT_ID_MIC_ERR_INFO: { + struct EVENT_MIC_ERR_INFO *prMicError; + /* P_PARAM_AUTH_EVENT_T prAuthEvent; */ + struct STA_RECORD *prStaRec; + + DBGLOG(RSN, EVENT, "EVENT_ID_MIC_ERR_INFO\n"); + + prMicError = (struct EVENT_MIC_ERR_INFO *) ( + prEvent->aucBuffer); + prStaRec = cnmGetStaRecByAddress(prAdapter, + prAdapter->prAisBssInfo->ucBssIndex, + prAdapter->rWlanInfo.rCurrBssId.arMacAddress); + ASSERT(prStaRec); + + if (prStaRec) + rsnTkipHandleMICFailure(prAdapter, prStaRec, + (u_int8_t) prMicError->u4Flags); + else + DBGLOG(RSN, INFO, "No STA rec!!\n"); +#if 0 + prAuthEvent = (struct PARAM_AUTH_EVENT *) + prAdapter->aucIndicationEventBuffer; + + /* Status type: Authentication Event */ + prAuthEvent->rStatus.eStatusType = + ENUM_STATUS_TYPE_AUTHENTICATION; + + /* Authentication request */ + prAuthEvent->arRequest[0].u4Length = sizeof( + struct PARAM_AUTH_REQUEST); + kalMemCopy((void *) prAuthEvent->arRequest[0].arBssid, + (void *) + prAdapter->rWlanInfo.rCurrBssId.arMacAddress, + PARAM_MAC_ADDR_LEN); + + if (prMicError->u4Flags != 0) + prAuthEvent->arRequest[0].u4Flags = + PARAM_AUTH_REQUEST_GROUP_ERROR; + else + prAuthEvent->arRequest[0].u4Flags = + PARAM_AUTH_REQUEST_PAIRWISE_ERROR; + + kalIndicateStatusAndComplete(prAdapter->prGlueInfo, + WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, + (void *) prAuthEvent, + sizeof(struct PARAM_STATUS_INDICATION) + sizeof( + struct PARAM_AUTH_REQUEST)); +#endif + } + break; + +#if 0 /* Marked for MT6630 */ + case EVENT_ID_ASSOC_INFO: { + struct EVENT_ASSOC_INFO *prAssocInfo; + + prAssocInfo = (struct EVENT_ASSOC_INFO *) ( + prEvent->aucBuffer); + + kalHandleAssocInfo(prAdapter->prGlueInfo, prAssocInfo); + } + break; + + case EVENT_ID_802_11_PMKID: { + struct PARAM_AUTH_EVENT *prAuthEvent; + uint8_t *cp; + uint32_t u4LenOfUsedBuffer; + + prAuthEvent = (struct PARAM_AUTH_EVENT *) + prAdapter->aucIndicationEventBuffer; + + prAuthEvent->rStatus.eStatusType = + ENUM_STATUS_TYPE_CANDIDATE_LIST; + + u4LenOfUsedBuffer = + (uint32_t) (prEvent->u2PacketLength - 8); + + prAuthEvent->arRequest[0].u4Length = u4LenOfUsedBuffer; + + cp = (uint8_t *) &prAuthEvent->arRequest[0]; + + /* Status type: PMKID Candidatelist Event */ + kalMemCopy(cp, (struct EVENT_PMKID_CANDIDATE_LIST *) ( + prEvent->aucBuffer), + prEvent->u2PacketLength - 8); + + kalIndicateStatusAndComplete(prAdapter->prGlueInfo, + WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, + (void *) prAuthEvent, + sizeof(struct PARAM_STATUS_INDICATION) + + u4LenOfUsedBuffer); + } + break; +#endif + case EVENT_ID_SCAN_DONE: + fgIsNewVersion = TRUE; + scnEventScanDone(prAdapter, + (struct EVENT_SCAN_DONE *) (prEvent->aucBuffer), + fgIsNewVersion); + break; + + case EVENT_ID_NLO_DONE: + DBGLOG(INIT, INFO, "EVENT_ID_NLO_DONE\n"); + scnEventNloDone(prAdapter, + (struct EVENT_NLO_DONE *) (prEvent->aucBuffer)); +#if CFG_SUPPORT_PNO + prAdapter->prAisBssInfo->fgIsPNOEnable = FALSE; + if (prAdapter->prAisBssInfo->fgIsNetRequestInActive + && prAdapter->prAisBssInfo->fgIsPNOEnable) { + UNSET_NET_ACTIVE(prAdapter, + prAdapter->prAisBssInfo->ucBssIndex); + DBGLOG(INIT, INFO, + "INACTIVE AIS from ACTIVEto disable PNO\n"); + /* sync with firmware */ + nicDeactivateNetwork(prAdapter, + prAdapter->prAisBssInfo->ucBssIndex); + } +#endif + break; + + case EVENT_ID_TX_DONE: +#if 1 + nicTxProcessTxDoneEvent(prAdapter, prEvent); +#else + { + struct EVENT_TX_DONE *prTxDone; + + prTxDone = + (struct EVENT_TX_DONE *) + (prEvent->aucBuffer); + + DBGLOG(INIT, INFO, + "EVENT_ID_TX_DONE WIDX:PID[%u:%u] Status[%u] SN[%u]\n", + prTxDone->ucWlanIndex, + prTxDone->ucPacketSeq, + prTxDone->ucStatus, + prTxDone->u2SequenceNumber); + + /* call related TX Done Handler */ + prMsduInfo = nicGetPendingTxMsduInfo(prAdapter, + prTxDone->ucWlanIndex, + prTxDone->ucPacketSeq); + +#if CFG_SUPPORT_802_11V_TIMING_MEASUREMENT + DBGLOG(INIT, TRACE, + "EVENT_ID_TX_DONE u4TimeStamp = %x u2AirDelay = %x\n", + prTxDone->au4Reserved1, + prTxDone->au4Reserved2); + + wnmReportTimingMeas(prAdapter, + prMsduInfo->ucStaRecIndex, + prTxDone->au4Reserved1, + prTxDone->au4Reserved1 + + prTxDone->au4Reserved2); +#endif + + if (prMsduInfo) { + prMsduInfo->pfTxDoneHandler( + prAdapter, prMsduInfo, + (enum ENUM_TX_RESULT_CODE) + (prTxDone->ucStatus)); + + if (prMsduInfo->eSrc == TX_PACKET_MGMT) + cnmMgtPktFree( + prAdapter, prMsduInfo); + else + nicTxReturnMsduInfo( + prAdapter, prMsduInfo); + } + } +#endif + break; + + case EVENT_ID_SLEEPY_INFO: +#if defined(_HIF_USB) +#else + { + struct EVENT_SLEEPY_INFO *prEventSleepyNotify; + + prEventSleepyNotify = (struct EVENT_SLEEPY_INFO *) ( + prEvent->aucBuffer); + + prAdapter->fgWiFiInSleepyState = (u_int8_t) ( + prEventSleepyNotify->ucSleepyState); + +#if CFG_SUPPORT_MULTITHREAD + if (prEventSleepyNotify->ucSleepyState) + kalSetFwOwnEvent2Hif(prGlueInfo); +#endif + } +#endif + break; + case EVENT_ID_BT_OVER_WIFI: +#if CFG_ENABLE_BT_OVER_WIFI + { + uint8_t aucTmp[sizeof(struct BT_OVER_WIFI_EVENT) + + sizeof(struct BOW_LINK_DISCONNECTED)]; + struct EVENT_BT_OVER_WIFI *prEventBtOverWifi; + struct BT_OVER_WIFI_EVENT *prBowEvent; + struct BOW_LINK_CONNECTED *prBowLinkConnected; + struct BOW_LINK_DISCONNECTED *prBowLinkDisconnected; + + prEventBtOverWifi = (struct EVENT_BT_OVER_WIFI *) ( + prEvent->aucBuffer); + + /* construct event header */ + prBowEvent = (struct BT_OVER_WIFI_EVENT *) aucTmp; + + if (prEventBtOverWifi->ucLinkStatus == 0) { + /* Connection */ + prBowEvent->rHeader.ucEventId = + BOW_EVENT_ID_LINK_CONNECTED; + prBowEvent->rHeader.ucSeqNumber = 0; + prBowEvent->rHeader.u2PayloadLength = sizeof( + struct BOW_LINK_CONNECTED); + + /* fill event body */ + prBowLinkConnected = + (struct BOW_LINK_CONNECTED *) + (prBowEvent->aucPayload); + prBowLinkConnected->rChannel.ucChannelNum = + prEventBtOverWifi->ucSelectedChannel; + kalMemZero(prBowLinkConnected->aucPeerAddress, + MAC_ADDR_LEN); /* @FIXME */ + + kalIndicateBOWEvent( + prAdapter->prGlueInfo, prBowEvent); + } else { + /* Disconnection */ + prBowEvent->rHeader.ucEventId = + BOW_EVENT_ID_LINK_DISCONNECTED; + prBowEvent->rHeader.ucSeqNumber = 0; + prBowEvent->rHeader.u2PayloadLength = sizeof( + struct BOW_LINK_DISCONNECTED); + + /* fill event body */ + prBowLinkDisconnected = + (struct BOW_LINK_DISCONNECTED *) + (prBowEvent->aucPayload); + /* @FIXME */ + prBowLinkDisconnected->ucReason = 0; + kalMemZero( + prBowLinkDisconnected->aucPeerAddress, + MAC_ADDR_LEN); /* @FIXME */ + + kalIndicateBOWEvent( + prAdapter->prGlueInfo, prBowEvent); + } + } + break; +#endif + case EVENT_ID_STATISTICS: + /* buffer statistics for further query */ + prAdapter->fgIsStatValid = TRUE; + prAdapter->rStatUpdateTime = kalGetTimeTick(); + kalMemCopy(&prAdapter->rStatStruct, prEvent->aucBuffer, + sizeof(struct EVENT_STATISTICS)); + + /* command response handling */ + prCmdInfo = nicGetPendingCmdInfo(prAdapter, + prEvent->ucSeqNum); + + if (prCmdInfo != NULL) { + if (prCmdInfo->pfCmdDoneHandler) + prCmdInfo->pfCmdDoneHandler( + prAdapter, prCmdInfo, + prEvent->aucBuffer); + else if (prCmdInfo->fgIsOid) + kalOidComplete(prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, + 0, WLAN_STATUS_SUCCESS); + /* return prCmdInfo */ + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + } + + break; + +#if CFG_SUPPORT_MSP + case EVENT_ID_WTBL_INFO: + /* buffer statistics for further query */ + prAdapter->fgIsStatValid = TRUE; + prAdapter->rStatUpdateTime = kalGetTimeTick(); + kalMemCopy(&prAdapter->rEventWlanInfo, + prEvent->aucBuffer, + sizeof(struct EVENT_WLAN_INFO)); + + DBGLOG(RSN, INFO, "EVENT_ID_WTBL_INFO"); + /* command response handling */ + prCmdInfo = nicGetPendingCmdInfo(prAdapter, + prEvent->ucSeqNum); + + if (prCmdInfo != NULL) { + if (prCmdInfo->pfCmdDoneHandler) + prCmdInfo->pfCmdDoneHandler( + prAdapter, prCmdInfo, + prEvent->aucBuffer); + else if (prCmdInfo->fgIsOid) + kalOidComplete(prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, + 0, WLAN_STATUS_SUCCESS); + /* return prCmdInfo */ + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + } + + break; + + case EVENT_ID_MIB_INFO: + /* buffer statistics for further query */ + prAdapter->fgIsStatValid = TRUE; + prAdapter->rStatUpdateTime = kalGetTimeTick(); + + DBGLOG(RSN, INFO, "EVENT_ID_MIB_INFO"); + /* command response handling */ + prCmdInfo = nicGetPendingCmdInfo(prAdapter, + prEvent->ucSeqNum); + + if (prCmdInfo != NULL) { + if (prCmdInfo->pfCmdDoneHandler) + prCmdInfo->pfCmdDoneHandler(prAdapter, + prCmdInfo, + prEvent->aucBuffer); + else if (prCmdInfo->fgIsOid) + kalOidComplete(prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, + 0, WLAN_STATUS_SUCCESS); + /* return prCmdInfo */ + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + } + + break; +#endif + case EVENT_ID_CH_PRIVILEGE: + cnmChMngrHandleChEvent(prAdapter, prEvent); + break; + + case EVENT_ID_BSS_ABSENCE_PRESENCE: + qmHandleEventBssAbsencePresence(prAdapter, prEvent); + break; + + case EVENT_ID_STA_CHANGE_PS_MODE: + qmHandleEventStaChangePsMode(prAdapter, prEvent); + break; +#if CFG_ENABLE_WIFI_DIRECT + case EVENT_ID_STA_UPDATE_FREE_QUOTA: + qmHandleEventStaUpdateFreeQuota(prAdapter, prEvent); + break; +#endif + case EVENT_ID_BSS_BEACON_TIMEOUT: + DBGLOG(INIT, INFO, "EVENT_ID_BSS_BEACON_TIMEOUT\n"); + + if (prAdapter->fgDisBcnLostDetection == FALSE) { + struct BSS_INFO *prBssInfo = + (struct BSS_INFO *) NULL; + struct EVENT_BSS_BEACON_TIMEOUT + *prEventBssBeaconTimeout; + + prEventBssBeaconTimeout = + (struct EVENT_BSS_BEACON_TIMEOUT *) + (prEvent->aucBuffer); + + if (prEventBssBeaconTimeout->ucBssIndex >= + prAdapter->ucHwBssIdNum) + break; + + DBGLOG(INIT, INFO, "Reason code: %d\n", + prEventBssBeaconTimeout->ucReasonCode); + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prEventBssBeaconTimeout->ucBssIndex); + + if (prEventBssBeaconTimeout->ucBssIndex == + prAdapter->prAisBssInfo->ucBssIndex) + aisBssBeaconTimeout(prAdapter); +#if CFG_ENABLE_WIFI_DIRECT + else if (prBssInfo->eNetworkType == + NETWORK_TYPE_P2P) + p2pRoleFsmRunEventBeaconTimeout( + prAdapter, prBssInfo); +#endif +#if CFG_ENABLE_BT_OVER_WIFI + else if (GET_BSS_INFO_BY_INDEX(prAdapter, + prEventBssBeaconTimeout->ucBssIndex)-> + eNetworkType == NETWORK_TYPE_BOW) { + /* ToDo:: Nothing */ + } +#endif + else { + DBGLOG(RX, ERROR, + "EVENT_ID_BSS_BEACON_TIMEOUT: (ucBssIndex = %d)\n", + prEventBssBeaconTimeout->ucBssIndex); + } + } + + break; + case EVENT_ID_UPDATE_NOA_PARAMS: +#if CFG_ENABLE_WIFI_DIRECT + if (prAdapter->fgIsP2PRegistered) { + struct EVENT_UPDATE_NOA_PARAMS + *prEventUpdateNoaParam; + + prEventUpdateNoaParam = + (struct EVENT_UPDATE_NOA_PARAMS *) + (prEvent->aucBuffer); + + if (GET_BSS_INFO_BY_INDEX(prAdapter, + prEventUpdateNoaParam-> + ucBssIndex)-> + eNetworkType == + NETWORK_TYPE_P2P) { + p2pProcessEvent_UpdateNOAParam( + prAdapter, + prEventUpdateNoaParam-> + ucBssIndex, + prEventUpdateNoaParam); + } else { + ASSERT(0); + } + } +#else + ASSERT(0); +#endif + break; + + case EVENT_ID_STA_AGING_TIMEOUT: +#if CFG_ENABLE_WIFI_DIRECT + { + if (prAdapter->fgDisStaAgingTimeoutDetection == FALSE) { + struct EVENT_STA_AGING_TIMEOUT + *prEventStaAgingTimeout; + struct STA_RECORD *prStaRec; + struct BSS_INFO *prBssInfo = + (struct BSS_INFO *) NULL; + + prEventStaAgingTimeout = + (struct EVENT_STA_AGING_TIMEOUT *) + (prEvent->aucBuffer); + prStaRec = cnmGetStaRecByIndex(prAdapter, + prEventStaAgingTimeout->ucStaRecIdx); + if (prStaRec == NULL) + break; + + DBGLOG(INIT, INFO, + "EVENT_ID_STA_AGING_TIMEOUT %u " MACSTR "\n", + prEventStaAgingTimeout->ucStaRecIdx, + MAC2STR(prStaRec->aucMacAddr)); + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prStaRec->ucBssIndex); + + bssRemoveClient(prAdapter, prBssInfo, prStaRec); + + /* Call False Auth */ + if (prAdapter->fgIsP2PRegistered) { + p2pFuncDisconnect(prAdapter, + prBssInfo, prStaRec, TRUE, + REASON_CODE_DISASSOC_INACTIVITY); + } + + } + /* gDisStaAgingTimeoutDetection */ + } +#endif + break; + + case EVENT_ID_AP_OBSS_STATUS: +#if CFG_ENABLE_WIFI_DIRECT + if (prAdapter->fgIsP2PRegistered) + rlmHandleObssStatusEventPkt(prAdapter, + (struct EVENT_AP_OBSS_STATUS *) + prEvent->aucBuffer); +#endif + break; + + case EVENT_ID_ROAMING_STATUS: +#if CFG_SUPPORT_ROAMING + { + struct CMD_ROAMING_TRANSIT *prTransit; + + prTransit = (struct CMD_ROAMING_TRANSIT *) ( + prEvent->aucBuffer); + roamingFsmProcessEvent(prAdapter, prTransit); + } +#endif /* CFG_SUPPORT_ROAMING */ + break; + case EVENT_ID_SEND_DEAUTH: +#if DBG + { + struct WLAN_MAC_HEADER *prWlanMacHeader; + + prWlanMacHeader = (struct WLAN_MAC_HEADER *) + prEvent->aucBuffer; + DBGLOG(RX, INFO, "nicRx: aucAddr1: " MACSTR "\n", + MAC2STR(prWlanMacHeader->aucAddr1)); + DBGLOG(RX, INFO, "nicRx: aucAddr2: " MACSTR "\n", + MAC2STR(prWlanMacHeader->aucAddr2)); + } +#endif + /* receive packets without StaRec */ + prSwRfb->pvHeader = (struct WLAN_MAC_HEADER *) + prEvent->aucBuffer; + if (authSendDeauthFrame(prAdapter, + NULL, + NULL, + prSwRfb, + REASON_CODE_CLASS_3_ERR, + (PFN_TX_DONE_HANDLER) NULL) == + WLAN_STATUS_SUCCESS) { + DBGLOG(RX, INFO, "Send Deauth Error\n"); + } + break; + +#if CFG_SUPPORT_RDD_TEST_MODE + case EVENT_ID_UPDATE_RDD_STATUS: { + struct EVENT_RDD_STATUS *prEventRddStatus; + + prEventRddStatus = (struct EVENT_RDD_STATUS *) ( + prEvent->aucBuffer); + + prAdapter->ucRddStatus = prEventRddStatus->ucRddStatus; + } + + break; +#endif + +#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS + case EVENT_ID_UPDATE_BWCS_STATUS: + { + struct PTA_IPC *prEventBwcsStatus; + + prEventBwcsStatus = + (struct PTA_IPC *) (prEvent->aucBuffer); + +#if CFG_SUPPORT_BCM_BWCS_DEBUG + DBGLOG(RSN, EVENT, "BCM BWCS Event: %02x%02x%02x%02x\n", + prEventBwcsStatus->u.aucBTPParams[0], + prEventBwcsStatus->u.aucBTPParams[1], + prEventBwcsStatus->u.aucBTPParams[2], + prEventBwcsStatus->u.aucBTPParams[3]); +#endif + + kalIndicateStatusAndComplete(prAdapter->prGlueInfo, + WLAN_STATUS_BWCS_UPDATE, + (void *) prEventBwcsStatus, + sizeof(struct PTA_IPC)); + } + + break; + + case EVENT_ID_UPDATE_BCM_DEBUG: { + struct PTA_IPC *prEventBwcsStatus; + + prEventBwcsStatus = + (struct PTA_IPC *) (prEvent->aucBuffer); + +#if CFG_SUPPORT_BCM_BWCS_DEBUG + DBGLOG(RSN, EVENT, "BCM FW status: %02x%02x%02x%02x\n", + prEventBwcsStatus->u.aucBTPParams[0], + prEventBwcsStatus->u.aucBTPParams[1], + prEventBwcsStatus->u.aucBTPParams[2], + prEventBwcsStatus->u.aucBTPParams[3]); +#endif + } + + break; +#endif + case EVENT_ID_ADD_PKEY_DONE: { + struct EVENT_ADD_KEY_DONE_INFO *prAddKeyDone; + struct STA_RECORD *prStaRec; + + prAddKeyDone = (struct EVENT_ADD_KEY_DONE_INFO *) ( + prEvent->aucBuffer); + + DBGLOG(RSN, EVENT, + "EVENT_ID_ADD_PKEY_DONE BSSIDX=%d " MACSTR "\n", + prAddKeyDone->ucBSSIndex, + MAC2STR(prAddKeyDone->aucStaAddr)); + + prStaRec = cnmGetStaRecByAddress(prAdapter, + prAddKeyDone->ucBSSIndex, + prAddKeyDone->aucStaAddr); + + if (prStaRec) { + DBGLOG(RSN, EVENT, + "STA " MACSTR " Add Key Done!!\n", + MAC2STR(prStaRec->aucMacAddr)); + prStaRec->fgIsTxKeyReady = TRUE; + qmUpdateStaRec(prAdapter, prStaRec); + } + } + break; + case EVENT_ID_ICAP_DONE: { + struct EVENT_ICAP_STATUS *prEventIcapStatus; + struct PARAM_CUSTOM_MEM_DUMP_STRUCT rMemDumpInfo; + uint32_t u4QueryInfo; + + prEventIcapStatus = (struct EVENT_ICAP_STATUS *) ( + prEvent->aucBuffer); + + rMemDumpInfo.u4Address = + prEventIcapStatus->u4StartAddress; + rMemDumpInfo.u4Length = + prEventIcapStatus->u4IcapSieze; +#if CFG_SUPPORT_QA_TOOL + rMemDumpInfo.u4IcapContent = + prEventIcapStatus->u4IcapContent; +#endif + + wlanoidQueryMemDump(prAdapter, &rMemDumpInfo, + sizeof(rMemDumpInfo), &u4QueryInfo); + + } + + break; + case EVENT_ID_DEBUG_MSG: { + struct EVENT_DEBUG_MSG *prEventDebugMsg; + uint16_t u2DebugMsgId; + uint8_t ucMsgType; + uint8_t ucFlags; + uint32_t u4Value; + uint16_t u2MsgSize; + uint8_t *pucMsg; + + prEventDebugMsg = (struct EVENT_DEBUG_MSG *) ( + prEvent->aucBuffer); + + u2DebugMsgId = prEventDebugMsg->u2DebugMsgId; + ucMsgType = prEventDebugMsg->ucMsgType; + ucFlags = prEventDebugMsg->ucFlags; + u4Value = prEventDebugMsg->u4Value; + u2MsgSize = prEventDebugMsg->u2MsgSize; + pucMsg = prEventDebugMsg->aucMsg; + + DBGLOG(SW4, TRACE, + "DEBUG_MSG Id %u Type %u Fg 0x%x Val 0x%x Size %u\n", + u2DebugMsgId, ucMsgType, + ucFlags, u4Value, u2MsgSize); + + if (u2MsgSize <= DEBUG_MSG_SIZE_MAX) { + if (ucMsgType >= DEBUG_MSG_TYPE_END) + ucMsgType = DEBUG_MSG_TYPE_MEM32; + + if (ucMsgType == DEBUG_MSG_TYPE_ASCII) { + uint8_t *pucChr; + + pucMsg[u2MsgSize] = '\0'; + + /* skip newline */ + pucChr = kalStrChr(pucMsg, '\0'); + if (*(pucChr - 1) == '\n') + *(pucChr - 1) = '\0'; + + DBGLOG(SW4, INFO, "%s\n", pucMsg); + } else if (ucMsgType == DEBUG_MSG_TYPE_MEM8) { + DBGLOG(SW4, INFO, "Dump MEM8\n"); + DBGLOG_MEM8(SW4, INFO, + pucMsg, u2MsgSize); + } else { + DBGLOG(SW4, INFO, "Dump MEM32\n"); + DBGLOG_MEM32(SW4, INFO, pucMsg, + u2MsgSize); + } + } /* DEBUG_MSG_SIZE_MAX */ + else + DBGLOG(SW4, INFO, + "Debug msg size %u is too large.\n", + u2MsgSize); + } + break; + +#if CFG_SUPPORT_BATCH_SCAN + case EVENT_ID_BATCH_RESULT: + DBGLOG(SCN, TRACE, "Got EVENT_ID_BATCH_RESULT"); + + /* command response handling */ + prCmdInfo = nicGetPendingCmdInfo(prAdapter, + prEvent->ucSeqNum); + + if (prCmdInfo != NULL) { + if (prCmdInfo->pfCmdDoneHandler) + prCmdInfo->pfCmdDoneHandler(prAdapter, + prCmdInfo, + prEvent->aucBuffer); + else if (prCmdInfo->fgIsOid) + kalOidComplete(prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, + 0, WLAN_STATUS_SUCCESS); + /* return prCmdInfo */ + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + } + + break; +#endif /* CFG_SUPPORT_BATCH_SCAN */ + +#if CFG_SUPPORT_TDLS + case EVENT_ID_TDLS: + + TdlsexEventHandle(prAdapter->prGlueInfo, + (uint8_t *) prEvent->aucBuffer, + (uint32_t) (prEvent->u2PacketLength - 8)); + break; +#endif /* CFG_SUPPORT_TDLS */ + + case EVENT_ID_DUMP_MEM: + DBGLOG(INIT, INFO, "%s: EVENT_ID_DUMP_MEM\n", __func__); + + prCmdInfo = nicGetPendingCmdInfo(prAdapter, + prEvent->ucSeqNum); + + if (prCmdInfo != NULL) { + DBGLOG(INIT, INFO, ": ==> 1\n"); + if (prCmdInfo->pfCmdDoneHandler) + prCmdInfo->pfCmdDoneHandler(prAdapter, + prCmdInfo, + prEvent->aucBuffer); + else if (prCmdInfo->fgIsOid) + kalOidComplete(prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, + 0, WLAN_STATUS_SUCCESS); + /* return prCmdInfo */ + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + } else { + /* Burst mode */ + DBGLOG(INIT, INFO, ": ==> 2\n"); + nicEventQueryMemDump(prAdapter, + prEvent->aucBuffer); + } + break; +#if CFG_ASSERT_DUMP + case EVENT_ID_ASSERT_DUMP: + + if (prEvent->ucS2DIndex == S2D_INDEX_EVENT_N2H) { + if (!prAdapter->fgN9AssertDumpOngoing) { + DBGLOG(INIT, INFO, + "%s: EVENT_ID_ASSERT_DUMP\n", + __func__); + DBGLOG(INIT, INFO, + "\n[DUMP_N9]====N9 ASSERT_DUMPSTART====\n"); + fgKeepPrintCoreDump = TRUE; + if (kalOpenCorDumpFile(TRUE) != + WLAN_STATUS_SUCCESS) + DBGLOG(INIT, INFO, + "kalOpenCorDumpFile fail\n"); + else + prAdapter->fgN9CorDumpFileOpend + = TRUE; + + prAdapter->fgN9AssertDumpOngoing = TRUE; + } else if (prAdapter->fgN9AssertDumpOngoing) { + + if (fgKeepPrintCoreDump) + DBGLOG(INIT, INFO, + "[DUMP_N9]%s:\n", + prEvent->aucBuffer); + if (!kalStrnCmp(prEvent->aucBuffer, + ";more log added here", + 5) || !kalStrnCmp( + prEvent->aucBuffer, + ";[core dump start]", + 5)) + fgKeepPrintCoreDump = FALSE; + + if (prAdapter->fgN9CorDumpFileOpend && + (kalWriteCorDumpFile( + prEvent->aucBuffer, + prEvent->u2PacketLength, + TRUE) != + WLAN_STATUS_SUCCESS)) { + DBGLOG(INIT, INFO, + "kalWriteN9CorDumpFile fail\n"); + } + wlanCorDumpTimerReset(prAdapter, TRUE); + } + } else { + /* prEvent->ucS2DIndex == S2D_INDEX_EVENT_C2H */ + if (!prAdapter->fgCr4AssertDumpOngoing) { + DBGLOG(INIT, INFO, + "%s: EVENT_ID_ASSERT_DUMP\n", + __func__); + DBGLOG(INIT, INFO, + "\n[DUMP_Cr4]====CR4 ASSERT_DUMPSTART====\n"); + fgKeepPrintCoreDump = TRUE; + if (kalOpenCorDumpFile(FALSE) != + WLAN_STATUS_SUCCESS) + DBGLOG(INIT, INFO, + "kalOpenCorDumpFile fail\n"); + else + prAdapter-> + fgCr4CorDumpFileOpend = TRUE; + + prAdapter->fgCr4AssertDumpOngoing = + TRUE; + } else if (prAdapter->fgCr4AssertDumpOngoing) { + if (fgKeepPrintCoreDump) + DBGLOG(INIT, INFO, + "[DUMP_CR4]%s:\n", + prEvent->aucBuffer); + if (!kalStrnCmp(prEvent->aucBuffer, + ";more log added here", + 5)) + fgKeepPrintCoreDump = FALSE; + + if (prAdapter->fgCr4CorDumpFileOpend && + (kalWriteCorDumpFile( + prEvent->aucBuffer, + prEvent->u2PacketLength, + FALSE) != + WLAN_STATUS_SUCCESS)) { + DBGLOG(INIT, INFO, + "kalWriteN9CorDumpFile fail\n"); + } + wlanCorDumpTimerReset(prAdapter, FALSE); + } + } + break; + +#endif + + case EVENT_ID_RDD_SEND_PULSE: + DBGLOG(INIT, INFO, "%s: EVENT_ID_RDD_SEND_PULSE\n", + __func__); + + nicEventRddPulseDump(prAdapter, prEvent->aucBuffer); + break; + + case EVENT_ID_ACCESS_RX_STAT: + case EVENT_ID_ACCESS_REG: + case EVENT_ID_NIC_CAPABILITY: + case EVENT_ID_ACCESS_EEPROM: + case EVENT_ID_TEST_STATUS: + default: + prCmdInfo = nicGetPendingCmdInfo(prAdapter, + prEvent->ucSeqNum); + + if (prCmdInfo != NULL) { + if (prCmdInfo->pfCmdDoneHandler) + prCmdInfo->pfCmdDoneHandler(prAdapter, + prCmdInfo, + prEvent->aucBuffer); + else if (prCmdInfo->fgIsOid) + kalOidComplete(prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, + 0, WLAN_STATUS_SUCCESS); + /* return prCmdInfo */ + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + } + + break; + } + + /* Reset Chip NoAck flag */ + if (prGlueInfo->prAdapter->fgIsChipNoAck) { + DBGLOG(INIT, WARN, + "Got response from chip, clear NoAck flag!\n"); + WARN_ON(TRUE); + } + prGlueInfo->prAdapter->ucOidTimeoutCount = 0; + prGlueInfo->prAdapter->fgIsChipNoAck = FALSE; + + nicRxReturnRFB(prAdapter, prSwRfb); + } +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * @brief nicRxProcessMgmtPacket is used to dispatch management frames + * to corresponding modules + * + * @param prAdapter Pointer to the Adapter structure. + * @param prSWRfb the RFB to receive rx data + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void nicRxProcessMgmtPacket(IN struct ADAPTER *prAdapter, + IN OUT struct SW_RFB *prSwRfb) +{ + struct GLUE_INFO *prGlueInfo; + uint8_t ucSubtype; +#if CFG_SUPPORT_802_11W + /* BOOL fgMfgDrop = FALSE; */ +#endif +#if CFG_WIFI_SW_CIPHER_MISMATCH + struct WLAN_MAC_HEADER *prWlanHeader = NULL; +#endif + ASSERT(prAdapter); + ASSERT(prSwRfb); + + nicRxFillRFB(prAdapter, prSwRfb); + +#if CFG_WIFI_SW_CIPHER_MISMATCH + prWlanHeader = (struct WLAN_MAC_HEADER *) prSwRfb->pvHeader; +#endif + ucSubtype = (*(uint8_t *) (prSwRfb->pvHeader) & + MASK_FC_SUBTYPE) >> OFFSET_OF_FC_SUBTYPE; + +#if CFG_RX_PKTS_DUMP + { + struct WLAN_MAC_MGMT_HEADER *prWlanMgmtHeader; + uint16_t u2TxFrameCtrl; + + u2TxFrameCtrl = (*(uint8_t *) (prSwRfb->pvHeader) & + MASK_FRAME_TYPE); + +#if ((CFG_SUPPORT_802_11AX == 1) && (CFG_SUPPORT_WIFI_SYSDVT == 1)) + if (fgEfuseCtrlAxOn == 1) { + if (RXM_IS_TRIGGER_FRAME(u2TxFrameCtrl)) { + if (prAdapter->fgEnShowHETrigger) { + DBGLOG(NIC, STATE, + "HE Trigger --------------\n"); + dumpMemory8((uint8_t *)prSwRfb->prRxStatus, + prSwRfb->u2RxByteCount); + DBGLOG(NIC, STATE, + "HE Trigger end --------------\n"); + } + nicRxReturnRFB(prAdapter, prSwRfb); + return; + } + } +#endif /* CFG_SUPPORT_802_11AX == 1 */ + + if (prAdapter->rRxCtrl.u4RxPktsDumpTypeMask & BIT( + HIF_RX_PKT_TYPE_MANAGEMENT)) { + if (u2TxFrameCtrl == MAC_FRAME_BEACON + || u2TxFrameCtrl == MAC_FRAME_PROBE_RSP) { + + prWlanMgmtHeader = + (struct WLAN_MAC_MGMT_HEADER *) ( + prSwRfb->pvHeader); + + DBGLOG(SW4, INFO, + "QM RX MGT: net %u sta idx %u wlan idx %u ssn %u ptype %u subtype %u 11 %u\n", + prSwRfb->prStaRec->ucBssIndex, + prSwRfb->ucStaRecIdx, + prSwRfb->ucWlanIdx, + prWlanMgmtHeader->u2SeqCtrl, + /* The new SN of the frame */ + prSwRfb->ucPacketType, ucSubtype); + /* HIF_RX_HDR_GET_80211_FLAG(prHifRxHdr))); */ + + DBGLOG_MEM8(SW4, TRACE, + (uint8_t *) prSwRfb->pvHeader, + prSwRfb->u2PacketLen); + } + } + } +#endif +#if CFG_SUPPORT_802_11W + if (prSwRfb->fgIcvErr) { + if (prSwRfb->ucSecMode == CIPHER_SUITE_BIP) + DBGLOG(RSN, INFO, "[MFP] RX with BIP ICV ERROR\n"); + else + DBGLOG(RSN, INFO, "[MFP] RX with ICV ERROR\n"); + + nicRxReturnRFB(prAdapter, prSwRfb); + RX_INC_CNT(&prAdapter->rRxCtrl, RX_DROP_TOTAL_COUNT); + return; + } +#endif + +#if CFG_WIFI_SW_CIPHER_MISMATCH + if ((rsnCheckBipKeyInstalled(prAdapter, prSwRfb->prStaRec)) + && (prSwRfb->prStaRec->ucStaState == STA_STATE_3) + && (!(prWlanHeader->u2FrameCtrl & MASK_FC_PROTECTED_FRAME)) + && (prSwRfb->fgIsBC == FALSE) + && (prSwRfb->fgIsMC == FALSE)) { + prSwRfb->fgIsCipherMS = TRUE; + } +#endif + + if (prAdapter->fgTestMode == FALSE) { +#if CFG_MGMT_FRAME_HANDLING + prGlueInfo = prAdapter->prGlueInfo; + if ((prGlueInfo == NULL) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(RX, WARN, + "Bypass this mgmt frame without wlanProbe done\n"); + } else if (apfnProcessRxMgtFrame[ucSubtype]) { + switch (apfnProcessRxMgtFrame[ucSubtype] (prAdapter, + prSwRfb)) { + case WLAN_STATUS_PENDING: + return; + case WLAN_STATUS_SUCCESS: + case WLAN_STATUS_FAILURE: + break; + + default: + DBGLOG(RX, WARN, + "Unexpected MMPDU(0x%02X) returned with abnormal status\n", + ucSubtype); + break; + } + } +#endif + } + + nicRxReturnRFB(prAdapter, prSwRfb); +} + +void nicRxProcessMsduReport(IN struct ADAPTER *prAdapter, + IN OUT struct SW_RFB *prSwRfb) +{ + halRxProcessMsduReport(prAdapter, prSwRfb); + + nicRxReturnRFB(prAdapter, prSwRfb); +} + +void nicRxProcessRxReport(IN struct ADAPTER *prAdapter, + IN OUT struct SW_RFB *prSwRfb) +{ + struct HW_MAC_RX_REPORT *prRxRpt; + uint32_t *prRxv = NULL; + uint32_t u4RxvOfst, u4Idx; + uint16_t u2RxByteCntHw, u2RxByteCntSw, u2PRXVCnt; + uint8_t ucDataType; + struct SW_RX_RPT_BLK_RXV *prRxRptBlkRxv = NULL; +#if (CFG_TWT_SMART_STA == 1) + uint32_t u4C1, u4MaxRxRate; + struct GLUE_INFO *prGlueInfo; +#endif + + ASSERT(prAdapter); + ASSERT(prAdapter->prGlueInfo); + + prRxRpt = (struct HW_MAC_RX_REPORT *)prSwRfb->pucRecvBuff; + u2RxByteCntHw = RX_RPT_GET_RX_BYTE_COUNT(prRxRpt); + u2RxByteCntSw = RX_RPT_HDR_LEN + RX_RPT_USER_INFO_LEN; + u2PRXVCnt = RX_RPT_GET_RXV_PRXV_BYTE_COUNT(prRxRpt); + u4RxvOfst = (RX_RPT_HDR_LEN + RX_RPT_USER_INFO_LEN + + RX_RPT_BLK_HDR_LEN) << 2; + + /* Sanity check */ + if (RX_RPT_GET_RXV_BLK_EXIST(prRxRpt)) + u2RxByteCntSw += RX_RPT_BLK_HDR_LEN; + if (RX_RPT_GET_RXV_TYPE_CRXV1_VLD(prRxRpt)) + u2RxByteCntSw += RX_RPT_BLK_CRXV1_LEN; + if (RX_RPT_GET_RXV_TYPE_PRXV1_VLD(prRxRpt)) + u2RxByteCntSw += RX_RPT_BLK_PRXV1_LEN; + if (RX_RPT_GET_RXV_TYPE_PRXV2_VLD(prRxRpt)) + u2RxByteCntSw += RX_RPT_BLK_PRXV2_LEN; + if (RX_RPT_GET_RXV_TYPE_CRXV2_VLD(prRxRpt)) + u2RxByteCntSw += RX_RPT_BLK_CRXV2_LEN; + + if (u2RxByteCntHw != (u2RxByteCntSw << 2)) { + DBGLOG(RX, ERROR, "Expect %d bytes but real %d bytes !!\n", + (u2RxByteCntSw << 2), u2RxByteCntHw); + return; + } + + prSwRfb->ucStaRecIdx = secGetStaIdxByWlanIdx(prAdapter, + (uint8_t) RX_RPT_GET_WLAN_ID(prRxRpt)); + + if (prSwRfb->ucStaRecIdx >= CFG_STA_REC_NUM) + return; + + /* Only check data frame */ + ucDataType = (uint8_t) RX_RPT_GET_FRAME_TYPE(prRxRpt); + if (!RX_RPT_IS_DATA_FRAME(ucDataType)) + return; + + prRxRptBlkRxv = (struct SW_RX_RPT_BLK_RXV *)kalMemAlloc( + sizeof(struct SW_RX_RPT_BLK_RXV), VIR_MEM_TYPE); + if (!prRxRptBlkRxv) { + DBGLOG(RX, ERROR, "Allocate prRxRptBlkRxv failed!\n"); + return; + } + + if (RX_RPT_GET_RXV_BLK_EXIST(prRxRpt)) { + if (RX_RPT_GET_RXV_TYPE_CRXV1_VLD(prRxRpt)) { + prRxv = (uint32_t *)((uint8_t *)prRxRpt + u4RxvOfst); + for (u4Idx = 0; u4Idx < RX_RPT_BLK_CRXV1_LEN; u4Idx++) { + prRxRptBlkRxv->u4CRxv1[u4Idx] = + *(prRxv + u4Idx); + } + + u4RxvOfst += (RX_RPT_BLK_CRXV1_LEN << 2); + } + if (RX_RPT_GET_RXV_TYPE_PRXV1_VLD(prRxRpt)) { + prRxv = (uint32_t *)((uint8_t *)prRxRpt + u4RxvOfst); + for (u4Idx = 0; u4Idx < RX_RPT_BLK_PRXV1_LEN; u4Idx++) + prRxRptBlkRxv->u4PRxv1[u4Idx] = + *(prRxv + u4Idx); + + u4RxvOfst += (RX_RPT_BLK_PRXV1_LEN << 2); + } + if (RX_RPT_GET_RXV_TYPE_PRXV2_VLD(prRxRpt)) { + prRxv = (uint32_t *)((uint8_t *)prRxRpt + u4RxvOfst); + for (u4Idx = 0; u4Idx < RX_RPT_BLK_PRXV2_LEN; u4Idx++) + prRxRptBlkRxv->u4PRxv2[u4Idx] = + *(prRxv + u4Idx); + + u4RxvOfst += (RX_RPT_BLK_PRXV2_LEN << 2); + } + if (RX_RPT_GET_RXV_TYPE_CRXV2_VLD(prRxRpt)) { + prRxv = (uint32_t *)((uint8_t *)prRxRpt + u4RxvOfst); + for (u4Idx = 0; u4Idx < RX_RPT_BLK_CRXV2_LEN; u4Idx++) + prRxRptBlkRxv->u4CRxv2[u4Idx] = + *(prRxv + u4Idx); + + u4RxvOfst += (RX_RPT_BLK_CRXV2_LEN << 2); + } + } + + /* P-B-0[0:31] */ + if (RX_RPT_GET_RXV_TYPE_PRXV1_VLD(prRxRpt)) + prAdapter->arStaRec[prSwRfb->ucStaRecIdx].u4RxVector0 = + prRxRptBlkRxv->u4PRxv1[0]; + else + prAdapter->arStaRec[prSwRfb->ucStaRecIdx].u4RxVector0 = 0; + +#if (CFG_SUPPORT_CONNAC2X == 1) + if (RX_RPT_GET_RXV_TYPE_CRXV1_VLD(prRxRpt)) { + /* C-B-0[0:31] */ + prAdapter->arStaRec[prSwRfb->ucStaRecIdx].u4RxVector1 = + prRxRptBlkRxv->u4CRxv1[0]; + /* C-B-1[0:31] */ + prAdapter->arStaRec[prSwRfb->ucStaRecIdx].u4RxVector2 = + prRxRptBlkRxv->u4CRxv1[2]; + /* C-B-3[0:31] */ + prAdapter->arStaRec[prSwRfb->ucStaRecIdx].u4RxVector3 = + prRxRptBlkRxv->u4CRxv1[4]; + /* C-B-3[0:31] */ + prAdapter->arStaRec[prSwRfb->ucStaRecIdx].u4RxVector4 = + prRxRptBlkRxv->u4CRxv1[6]; + } else { + prAdapter->arStaRec[prSwRfb->ucStaRecIdx].u4RxVector1 = + 0; + prAdapter->arStaRec[prSwRfb->ucStaRecIdx].u4RxVector2 = + 0; + prAdapter->arStaRec[prSwRfb->ucStaRecIdx].u4RxVector3 = + 0; + prAdapter->arStaRec[prSwRfb->ucStaRecIdx].u4RxVector4 = + 0; + DBGLOG(RX, WARN, "RX_RPT C-RXV1 not valid!\n"); + } +#endif + +#if (CFG_TWT_SMART_STA == 1) + prGlueInfo = prAdapter->prGlueInfo; + wlanGetRxRate(prGlueInfo, &u4C1, &u4MaxRxRate); + g_TwtSmartStaCtrl.u4LastTp = g_TwtSmartStaCtrl.u4CurTp; + g_TwtSmartStaCtrl.u4CurTp = u4C1; + + if (g_TwtSmartStaCtrl.u4LastTp < 8000) + g_TwtSmartStaCtrl.u4Count++; + + else + g_TwtSmartStaCtrl.u4Count = 0; + + if (g_TwtSmartStaCtrl.u4Count > 10) + g_TwtSmartStaCtrl.u4TwtSwitch = 1; + +#endif + + + if (prRxRptBlkRxv) + kalMemFree(prRxRptBlkRxv, VIR_MEM_TYPE, + sizeof(struct SW_RX_RPT_BLK_RXV)); +} + +#if CFG_SUPPORT_WAKEUP_REASON_DEBUG +static void nicRxCheckWakeupReason(struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb) +{ + struct RX_DESC_OPS_T *prRxDescOps; + + prRxDescOps = prAdapter->chip_info->prRxDescOps; + if (prRxDescOps->nic_rxd_check_wakeup_reason) + prRxDescOps->nic_rxd_check_wakeup_reason(prAdapter, prSwRfb); + else + DBGLOG(RX, ERROR, + "%s:: no nic_rxd_check_wakeup_reason??\n", + __func__); +} +#endif /* CFG_SUPPORT_WAKEUP_REASON_DEBUG */ + +static void nicRxProcessPacketType( + struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb) +{ + struct RX_CTRL *prRxCtrl; + struct mt66xx_chip_info *prChipInfo; + struct GLUE_INFO *prGlueInfo = prAdapter->prGlueInfo; + + prRxCtrl = &prAdapter->rRxCtrl; + prChipInfo = prAdapter->chip_info; + + switch (prSwRfb->ucPacketType) { + case RX_PKT_TYPE_RX_DATA: + if (HAL_IS_RX_DIRECT(prAdapter) + && HAL_MON_EN(prAdapter)) { + spin_lock_bh(&prGlueInfo->rSpinLock[ + SPIN_LOCK_RX_DIRECT]); + nicRxProcessMonitorPacket( + prAdapter, prSwRfb); + spin_unlock_bh(&prGlueInfo->rSpinLock[ + SPIN_LOCK_RX_DIRECT]); + break; + } else if (HAL_MON_EN(prAdapter)) { + nicRxProcessMonitorPacket( + prAdapter, prSwRfb); + break; + } + if (HAL_IS_RX_DIRECT(prAdapter)) { + spin_lock_bh(&prGlueInfo->rSpinLock[ + SPIN_LOCK_RX_DIRECT]); + nicRxProcessDataPacket( + prAdapter, + prSwRfb); + spin_unlock_bh(&prGlueInfo->rSpinLock[ + SPIN_LOCK_RX_DIRECT]); + } else { + nicRxProcessDataPacket( + prAdapter, + prSwRfb); + } + break; + + case RX_PKT_TYPE_SW_DEFINED: + /* HIF_RX_PKT_TYPE_EVENT */ + if ((NIC_RX_GET_U2_SW_PKT_TYPE( + prSwRfb->prRxStatus) & + prChipInfo->u2RxSwPktBitMap) == + prChipInfo->u2RxSwPktEvent) { + nicRxProcessEventPacket( + prAdapter, + prSwRfb); + } + /* case HIF_RX_PKT_TYPE_MANAGEMENT: */ + else if ((NIC_RX_GET_U2_SW_PKT_TYPE( + prSwRfb->prRxStatus) + & prChipInfo->u2RxSwPktBitMap) + == prChipInfo->u2RxSwPktFrame){ + /* OFLD pkts should go data flow + * 1: EAPOL + * 2: ARP / NS + * 3: TDLS + */ + RX_STATUS_GET( + prChipInfo->prRxDescOps, + prSwRfb->ucOFLD, + get_ofld, + prSwRfb->prRxStatus); + if (prSwRfb->ucOFLD) { + if (HAL_IS_RX_DIRECT(prAdapter)) { + spin_lock_bh(&prGlueInfo->rSpinLock[ + SPIN_LOCK_RX_DIRECT]); + if (HAL_MON_EN(prAdapter)) + nicRxProcessMonitorPacket( + prAdapter, prSwRfb); + else + nicRxProcessDataPacket( + prAdapter, prSwRfb); + spin_unlock_bh(&prGlueInfo->rSpinLock[ + SPIN_LOCK_RX_DIRECT]); + } else { + if (HAL_MON_EN(prAdapter)) + nicRxProcessMonitorPacket( + prAdapter, prSwRfb); + else + nicRxProcessDataPacket( + prAdapter, prSwRfb); + } + } + else + nicRxProcessMgmtPacket( + prAdapter, prSwRfb); + } else { + DBGLOG(RX, ERROR, + "u2PktTYpe(0x%04X) is OUT OF DEF.!!!\n", + NIC_RX_GET_U2_SW_PKT_TYPE( + prSwRfb->prRxStatus)); + DBGLOG_MEM8(RX, ERROR, + prSwRfb->pucRecvBuff, + prSwRfb->u2RxByteCount); + + /*ASSERT(0);*/ + nicRxReturnRFB(prAdapter, + prSwRfb); + RX_INC_CNT(prRxCtrl, + RX_TYPE_ERR_DROP_COUNT); + RX_INC_CNT(prRxCtrl, + RX_DROP_TOTAL_COUNT); + + } + break; + + case RX_PKT_TYPE_MSDU_REPORT: + nicRxProcessMsduReport(prAdapter, + prSwRfb); + break; + + case RX_PKT_TYPE_RX_REPORT: + nicRxProcessRxReport(prAdapter, prSwRfb); + nicRxReturnRFB(prAdapter, prSwRfb); + break; + + /* case HIF_RX_PKT_TYPE_TX_LOOPBACK: */ + /* case HIF_RX_PKT_TYPE_MANAGEMENT: */ + case RX_PKT_TYPE_TX_STATUS: + case RX_PKT_TYPE_RX_VECTOR: + case RX_PKT_TYPE_TM_REPORT: + default: + nicRxReturnRFB(prAdapter, prSwRfb); + RX_INC_CNT(prRxCtrl, + RX_TYPE_ERR_DROP_COUNT); + RX_INC_CNT(prRxCtrl, + RX_DROP_TOTAL_COUNT); + DBGLOG(RX, ERROR, "ucPacketType = %d\n", + prSwRfb->ucPacketType); + break; + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief nicProcessRFBs is used to process RFBs in the rReceivedRFBList queue. + * + * @param prAdapter Pointer to the Adapter structure. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void nicRxProcessRFBs(IN struct ADAPTER *prAdapter) +{ + struct RX_CTRL *prRxCtrl; + struct SW_RFB *prSwRfb = (struct SW_RFB *) NULL; + struct QUE rTempRfbList; + struct QUE *prTempRfbList = &rTempRfbList; + uint32_t u4RxLoopCount, u4Tick; + + KAL_SPIN_LOCK_DECLARATION(); + + DEBUGFUNC("nicRxProcessRFBs"); + + ASSERT(prAdapter); + + prRxCtrl = &prAdapter->rRxCtrl; + ASSERT(prRxCtrl); + + prRxCtrl->ucNumIndPacket = 0; + prRxCtrl->ucNumRetainedPacket = 0; + u4RxLoopCount = prAdapter->rWifiVar.u4TxRxLoopCount; + u4Tick = kalGetTimeTick(); + + QUEUE_INITIALIZE(prTempRfbList); + + while (u4RxLoopCount--) { + while (QUEUE_IS_NOT_EMPTY(&prRxCtrl->rReceivedRfbList)) { + + /* check process RFB timeout */ + if ((kalGetTimeTick() - u4Tick) > RX_PROCESS_TIMEOUT) { + DBGLOG(RX, WARN, "Rx process RFBs timeout\n"); + break; + } + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); + QUEUE_MOVE_ALL(prTempRfbList, + &prRxCtrl->rReceivedRfbList); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); + + while (QUEUE_IS_NOT_EMPTY(prTempRfbList)) { + QUEUE_REMOVE_HEAD(prTempRfbList, + prSwRfb, struct SW_RFB *); + + if (!prSwRfb) + break; +#if CFG_SUPPORT_WAKEUP_REASON_DEBUG + if (kalIsWakeupByWlan(prAdapter)) + nicRxCheckWakeupReason(prAdapter, + prSwRfb); +#endif + + /* Too many leading tabs - + * consider code refactoring + */ + nicRxProcessPacketType(prAdapter, prSwRfb); + } + + if (prRxCtrl->ucNumIndPacket > 0) { + RX_ADD_CNT(prRxCtrl, RX_DATA_RETAINED_COUNT, + prRxCtrl->ucNumRetainedPacket); +#if !CFG_SUPPORT_MULTITHREAD +#if CFG_NATIVE_802_11 + kalRxIndicatePkts(prAdapter->prGlueInfo, + (uint32_t) prRxCtrl->ucNumIndPacket, + (uint32_t) + prRxCtrl->ucNumRetainedPacket); +#else + kalRxIndicatePkts(prAdapter->prGlueInfo, + prRxCtrl->apvIndPacket, + (uint32_t) prRxCtrl->ucNumIndPacket); +#endif +#endif + kalPerMonStart(prAdapter->prGlueInfo); + } + } + } +} /* end of nicRxProcessRFBs() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Setup a RFB and allocate the os packet to the RFB + * + * @param prAdapter Pointer to the Adapter structure. + * @param prSwRfb Pointer to the RFB + * + * @retval WLAN_STATUS_SUCCESS + * @retval WLAN_STATUS_RESOURCES + */ +/*----------------------------------------------------------------------------*/ +uint32_t nicRxSetupRFB(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb) +{ + void *pvPacket; + uint8_t *pucRecvBuff; + + ASSERT(prAdapter); + ASSERT(prSwRfb); + + if (!prSwRfb->pvPacket) { + kalMemZero(prSwRfb, sizeof(struct SW_RFB)); + pvPacket = kalPacketAlloc(prAdapter->prGlueInfo, + CFG_RX_MAX_PKT_SIZE, &pucRecvBuff); + if (pvPacket == NULL) + return WLAN_STATUS_RESOURCES; + + prSwRfb->pvPacket = pvPacket; + prSwRfb->pucRecvBuff = (void *) pucRecvBuff; + } else { + kalMemZero(((uint8_t *) prSwRfb + OFFSET_OF(struct SW_RFB, + prRxStatus)), + (sizeof(struct SW_RFB) - OFFSET_OF(struct SW_RFB, + prRxStatus))); + } + + prSwRfb->prRxStatus = prSwRfb->pucRecvBuff; + + return WLAN_STATUS_SUCCESS; + +} /* end of nicRxSetupRFB() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is called to put a RFB back onto the "RFB with Buffer" + * list or "RFB without buffer" list according to pvPacket. + * + * @param prAdapter Pointer to the Adapter structure. + * @param prSwRfb Pointer to the RFB + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void nicRxReturnRFB(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb) +{ + struct RX_CTRL *prRxCtrl; + struct QUE_ENTRY *prQueEntry; + + KAL_SPIN_LOCK_DECLARATION(); + + ASSERT(prAdapter); + ASSERT(prSwRfb); + prRxCtrl = &prAdapter->rRxCtrl; + prQueEntry = &prSwRfb->rQueEntry; + + ASSERT(prQueEntry); + + /* The processing on this RFB is done, + * so put it back on the tail of our list + */ + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_FREE_QUE); + + if (prSwRfb->pvPacket) { + /* QUEUE_INSERT_TAIL */ + QUEUE_INSERT_TAIL(&prRxCtrl->rFreeSwRfbList, prQueEntry); + if (prAdapter->u4NoMoreRfb != 0) { + DBGLOG_LIMITED(RX, INFO, + "Free rfb and set IntEvent!!!!!\n"); + kalSetDrvIntEvent(prAdapter->prGlueInfo); + } + } else { + /* QUEUE_INSERT_TAIL */ + QUEUE_INSERT_TAIL(&prRxCtrl->rIndicatedRfbList, prQueEntry); + } + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_FREE_QUE); + + /* Trigger Rx if there are free SwRfb */ + if (halIsPendingRx(prAdapter) + && (prRxCtrl->rFreeSwRfbList.u4NumElem > 0)) + kalSetIntEvent(prAdapter->prGlueInfo); +} /* end of nicRxReturnRFB() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Process rx interrupt. When the rx + * Interrupt is asserted, it means there are frames in queue. + * + * @param prAdapter Pointer to the Adapter structure. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void nicProcessRxInterrupt(IN struct ADAPTER *prAdapter) +{ + ASSERT(prAdapter); + prAdapter->prGlueInfo->IsrRxCnt++; + + if (halIsHifStateSuspend(prAdapter)) { + DBGLOG(RX, WARN, "suspend RX INT\n"); + } + + /* SER break point */ + if (nicSerIsRxStop(prAdapter)) { + /* Skip following Rx handling */ + return; + } + + halProcessRxInterrupt(prAdapter); + +#if CFG_SUPPORT_MULTITHREAD + kalSetRxProcessEvent(prAdapter->prGlueInfo); +#else + nicRxProcessRFBs(prAdapter); +#endif + + return; + +} /* end of nicProcessRxInterrupt() */ + +#if CFG_TCP_IP_CHKSUM_OFFLOAD +/*----------------------------------------------------------------------------*/ +/*! + * @brief Used to update IP/TCP/UDP checksum statistics of RX Module. + * + * @param prAdapter Pointer to the Adapter structure. + * @param aeCSUM The array of checksum result. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void nicRxUpdateCSUMStatistics(IN struct ADAPTER * + prAdapter, IN const enum ENUM_CSUM_RESULT aeCSUM[]) { + struct RX_CTRL *prRxCtrl; + + ASSERT(prAdapter); + ASSERT(aeCSUM); + + prRxCtrl = &prAdapter->rRxCtrl; + ASSERT(prRxCtrl); + + if ((aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_SUCCESS) + || (aeCSUM[CSUM_TYPE_IPV6] == CSUM_RES_SUCCESS)) { + /* count success num */ + RX_INC_CNT(prRxCtrl, RX_CSUM_IP_SUCCESS_COUNT); + } else if ((aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_FAILED) + || (aeCSUM[CSUM_TYPE_IPV6] == CSUM_RES_FAILED)) { + RX_INC_CNT(prRxCtrl, RX_CSUM_IP_FAILED_COUNT); + } else if ((aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_NONE) + && (aeCSUM[CSUM_TYPE_IPV6] == CSUM_RES_NONE)) { + RX_INC_CNT(prRxCtrl, RX_CSUM_UNKNOWN_L3_PKT_COUNT); + } else { + ASSERT(0); + } + + if (aeCSUM[CSUM_TYPE_TCP] == CSUM_RES_SUCCESS) { + /* count success num */ + RX_INC_CNT(prRxCtrl, RX_CSUM_TCP_SUCCESS_COUNT); + } else if (aeCSUM[CSUM_TYPE_TCP] == CSUM_RES_FAILED) { + RX_INC_CNT(prRxCtrl, RX_CSUM_TCP_FAILED_COUNT); + } else if (aeCSUM[CSUM_TYPE_UDP] == CSUM_RES_SUCCESS) { + RX_INC_CNT(prRxCtrl, RX_CSUM_UDP_SUCCESS_COUNT); + } else if (aeCSUM[CSUM_TYPE_UDP] == CSUM_RES_FAILED) { + RX_INC_CNT(prRxCtrl, RX_CSUM_UDP_FAILED_COUNT); + } else if ((aeCSUM[CSUM_TYPE_UDP] == CSUM_RES_NONE) + && (aeCSUM[CSUM_TYPE_TCP] == CSUM_RES_NONE)) { + RX_INC_CNT(prRxCtrl, RX_CSUM_UNKNOWN_L4_PKT_COUNT); + } else { + ASSERT(0); + } + +} /* end of nicRxUpdateCSUMStatistics() */ +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is used to query current status of RX Module. + * + * @param prAdapter Pointer to the Adapter structure. + * @param pucBuffer Pointer to the message buffer. + * @param pu4Count Pointer to the buffer of message length count. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void nicRxQueryStatus(IN struct ADAPTER *prAdapter, + IN uint8_t *pucBuffer, OUT uint32_t *pu4Count) +{ + struct RX_CTRL *prRxCtrl; + uint8_t *pucCurrBuf = pucBuffer; + uint32_t u4CurrCount; + + ASSERT(prAdapter); + prRxCtrl = &prAdapter->rRxCtrl; + ASSERT(prRxCtrl); + ASSERT(pu4Count); + +#define SPRINTF_RX_QSTATUS(arg) \ + { \ + u4CurrCount = \ + kalScnprintf(pucCurrBuf, *pu4Count, PRINTF_ARG arg); \ + pucCurrBuf += (uint8_t)u4CurrCount; \ + *pu4Count -= u4CurrCount; \ + } + + + SPRINTF_RX_QSTATUS(("\n\nRX CTRL STATUS:")); + SPRINTF_RX_QSTATUS(("\n===============")); + SPRINTF_RX_QSTATUS(("\nFREE RFB w/i BUF LIST :%9u", + prRxCtrl->rFreeSwRfbList.u4NumElem)); + SPRINTF_RX_QSTATUS(("\nFREE RFB w/o BUF LIST :%9u", + prRxCtrl->rIndicatedRfbList.u4NumElem)); + SPRINTF_RX_QSTATUS(("\nRECEIVED RFB LIST :%9u", + prRxCtrl->rReceivedRfbList.u4NumElem)); + + SPRINTF_RX_QSTATUS(("\n\n")); + + /* *pu4Count = (UINT_32)((UINT_32)pucCurrBuf - (UINT_32)pucBuffer); */ + +} /* end of nicRxQueryStatus() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Clear RX related counters + * + * @param prAdapter Pointer of Adapter Data Structure + * + * @return - (none) + */ +/*----------------------------------------------------------------------------*/ +void nicRxClearStatistics(IN struct ADAPTER *prAdapter) +{ + struct RX_CTRL *prRxCtrl; + + ASSERT(prAdapter); + prRxCtrl = &prAdapter->rRxCtrl; + ASSERT(prRxCtrl); + + RX_RESET_ALL_CNTS(prRxCtrl); + +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is used to query current statistics of RX Module. + * + * @param prAdapter Pointer to the Adapter structure. + * @param pucBuffer Pointer to the message buffer. + * @param pu4Count Pointer to the buffer of message length count. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void nicRxQueryStatistics(IN struct ADAPTER *prAdapter, + IN uint8_t *pucBuffer, OUT uint32_t *pu4Count) +{ + struct RX_CTRL *prRxCtrl; + uint8_t *pucCurrBuf = pucBuffer; + uint32_t u4CurrCount; + + ASSERT(prAdapter); + prRxCtrl = &prAdapter->rRxCtrl; + ASSERT(prRxCtrl); + ASSERT(pu4Count); + +#define SPRINTF_RX_COUNTER(eCounter) \ + { \ + u4CurrCount = kalScnprintf(pucCurrBuf, *pu4Count, \ + "%-30s : %u\n", #eCounter, \ + (uint32_t)prRxCtrl->au8Statistics[eCounter]); \ + pucCurrBuf += (uint8_t)u4CurrCount; \ + *pu4Count -= u4CurrCount; \ + } + + SPRINTF_RX_COUNTER(RX_MPDU_TOTAL_COUNT); + SPRINTF_RX_COUNTER(RX_SIZE_ERR_DROP_COUNT); + SPRINTF_RX_COUNTER(RX_DATA_INDICATION_COUNT); + SPRINTF_RX_COUNTER(RX_DATA_RETURNED_COUNT); + SPRINTF_RX_COUNTER(RX_DATA_RETAINED_COUNT); + +#if CFG_TCP_IP_CHKSUM_OFFLOAD || CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60 + SPRINTF_RX_COUNTER(RX_CSUM_TCP_FAILED_COUNT); + SPRINTF_RX_COUNTER(RX_CSUM_UDP_FAILED_COUNT); + SPRINTF_RX_COUNTER(RX_CSUM_IP_FAILED_COUNT); + SPRINTF_RX_COUNTER(RX_CSUM_TCP_SUCCESS_COUNT); + SPRINTF_RX_COUNTER(RX_CSUM_UDP_SUCCESS_COUNT); + SPRINTF_RX_COUNTER(RX_CSUM_IP_SUCCESS_COUNT); + SPRINTF_RX_COUNTER(RX_CSUM_UNKNOWN_L4_PKT_COUNT); + SPRINTF_RX_COUNTER(RX_CSUM_UNKNOWN_L3_PKT_COUNT); + SPRINTF_RX_COUNTER(RX_IP_V6_PKT_CCOUNT); +#endif + + /* *pu4Count = (UINT_32)(pucCurrBuf - pucBuffer); */ + + nicRxClearStatistics(prAdapter); + +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Read the Response data from data port + * + * @param prAdapter pointer to the Adapter handler + * @param pucRspBuffer pointer to the Response buffer + * + * @retval WLAN_STATUS_SUCCESS: Response packet has been read + * @retval WLAN_STATUS_FAILURE: Read Response packet timeout or error occurred + * + */ +/*----------------------------------------------------------------------------*/ +uint32_t +nicRxWaitResponse(IN struct ADAPTER *prAdapter, + IN uint8_t ucPortIdx, OUT uint8_t *pucRspBuffer, + IN uint32_t u4MaxRespBufferLen, OUT uint32_t *pu4Length) { + struct mt66xx_chip_info *prChipInfo; + struct WIFI_EVENT *prEvent; + uint32_t u4Status = WLAN_STATUS_SUCCESS; + + ASSERT(prAdapter); + prChipInfo = prAdapter->chip_info; + + u4Status = halRxWaitResponse(prAdapter, ucPortIdx, + pucRspBuffer, + u4MaxRespBufferLen, pu4Length); + if (u4Status == WLAN_STATUS_SUCCESS) { + DBGLOG(RX, TRACE, + "Dump Response buffer, length = %u\n", *pu4Length); + DBGLOG_MEM8(RX, TRACE, pucRspBuffer, *pu4Length); + + prEvent = (struct WIFI_EVENT *) + (pucRspBuffer + prChipInfo->rxd_size); + + DBGLOG(INIT, TRACE, + "RX EVENT: ID[0x%02X] SEQ[%u] LEN[%u]\n", + prEvent->ucEID, prEvent->ucSeqNum, + prEvent->u2PacketLength); + } else { + prAdapter->u4HifDbgFlag |= DEG_HIF_DEFAULT_DUMP; + halPrintHifDbgInfo(prAdapter); + DBGLOG(RX, ERROR, "halRxWaitResponse fail!status %X\n", + u4Status); + } + + return u4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Set filter to enable Promiscuous Mode + * + * @param prAdapter Pointer to the Adapter structure. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void nicRxEnablePromiscuousMode(IN struct ADAPTER * + prAdapter) { + ASSERT(prAdapter); + +} /* end of nicRxEnablePromiscuousMode() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Set filter to disable Promiscuous Mode + * + * @param prAdapter Pointer to the Adapter structure. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void nicRxDisablePromiscuousMode(IN struct ADAPTER * + prAdapter) { + ASSERT(prAdapter); + +} /* end of nicRxDisablePromiscuousMode() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief this function flushes all packets queued in reordering module + * + * @param prAdapter Pointer to the Adapter structure. + * + * @retval WLAN_STATUS_SUCCESS Flushed successfully + */ +/*----------------------------------------------------------------------------*/ +uint32_t nicRxFlush(IN struct ADAPTER *prAdapter) +{ + struct SW_RFB *prSwRfb; + + ASSERT(prAdapter); + prSwRfb = qmFlushRxQueues(prAdapter); + if (prSwRfb != NULL) { + do { + struct SW_RFB *prNextSwRfb; + + /* save next first */ + prNextSwRfb = (struct SW_RFB *) QUEUE_GET_NEXT_ENTRY(( + struct QUE_ENTRY *) prSwRfb); + + /* free */ + nicRxReturnRFB(prAdapter, prSwRfb); + + prSwRfb = prNextSwRfb; + } while (prSwRfb); + } + + return WLAN_STATUS_SUCCESS; +} + +uint8_t nicIsActionFrameValid(IN struct SW_RFB *prSwRfb) +{ + struct WLAN_ACTION_FRAME *prActFrame; + uint16_t u2ActionIndex = 0, u2ExpectedLen = 0; + uint32_t u4Idx, u4Size; + + if (prSwRfb->u2PacketLen < sizeof(struct WLAN_ACTION_FRAME) - 1) + return FALSE; + prActFrame = (struct WLAN_ACTION_FRAME *) prSwRfb->pvHeader; + + DBGLOG(RSN, TRACE, "Action frame category=%d action=%d\n", + prActFrame->ucCategory, prActFrame->ucAction); + + u2ActionIndex = prActFrame->ucCategory | prActFrame->ucAction << 8; + u4Size = sizeof(arActionFrameReservedLen) / + sizeof(struct ACTION_FRAME_SIZE_MAP); + for (u4Idx = 0; u4Idx < u4Size; u4Idx++) { + if (u2ActionIndex == arActionFrameReservedLen[u4Idx].u2Index) { + u2ExpectedLen = (uint16_t) + arActionFrameReservedLen[u4Idx].len; + DBGLOG(RSN, LOUD, + "Found expected len of incoming action frame:%d\n", + u2ExpectedLen); + break; + } + } + if (u2ExpectedLen != 0 && prSwRfb->u2PacketLen < u2ExpectedLen) { + DBGLOG(RSN, INFO, + "Received an abnormal action frame: packet len/expected len:%d/%d\n", + prSwRfb->u2PacketLen, u2ExpectedLen); + return FALSE; + } + return TRUE; +} +/*----------------------------------------------------------------------------*/ +/*! + * @brief + * + * @param + * + * @retval + */ +/*----------------------------------------------------------------------------*/ +uint32_t nicRxProcessActionFrame(IN struct ADAPTER * + prAdapter, IN struct SW_RFB *prSwRfb) { + struct WLAN_ACTION_FRAME *prActFrame; + struct BSS_INFO *prBssInfo = NULL; +#if CFG_SUPPORT_802_11W + u_int8_t fgRobustAction = FALSE; + struct AIS_SPECIFIC_BSS_INFO *prAisSpecBssInfo; +#endif + + ASSERT(prAdapter); + ASSERT(prSwRfb); + + DBGLOG(RSN, TRACE, "[Rx] nicRxProcessActionFrame\n"); + + if (!nicIsActionFrameValid(prSwRfb)) + return WLAN_STATUS_INVALID_PACKET; + prActFrame = (struct WLAN_ACTION_FRAME *) prSwRfb->pvHeader; + +#if CFG_SUPPORT_802_11W + /* DBGLOG(RSN, TRACE, ("[Rx] fgRobustAction=%d\n", fgRobustAction)); */ + fgRobustAction = secIsRobustActionFrame(prAdapter, prSwRfb->pvHeader); + if (fgRobustAction && prSwRfb->prStaRec && + GET_BSS_INFO_BY_INDEX(prAdapter, + prSwRfb->prStaRec->ucBssIndex)->eNetworkType == + NETWORK_TYPE_AIS) { + prAisSpecBssInfo = + aisGetAisSpecBssInfo(prAdapter, + prSwRfb->prStaRec->ucBssIndex); + + DBGLOG(RSN, INFO, + "[Rx]RobustAction %x %x\n", + prSwRfb->ucWlanIdx, + prSwRfb->ucSecMode); + + if (prAisSpecBssInfo->fgMgmtProtection + && (!(prActFrame->u2FrameCtrl & MASK_FC_PROTECTED_FRAME) +#if CFG_WIFI_SW_CIPHER_MISMATCH + && (prSwRfb->fgIsCipherMS))) { +#else + && (prSwRfb->ucSecMode == CIPHER_SUITE_CCMP))) { +#endif + DBGLOG(RSN, INFO, + "[MFP] Not handle and drop un-protected robust action frame!!\n"); + return WLAN_STATUS_INVALID_PACKET; + } + } +#endif + + if (prSwRfb->prStaRec) + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prSwRfb->prStaRec->ucBssIndex); + + switch (prActFrame->ucCategory) { +#if CFG_M0VE_BA_TO_DRIVER + case CATEGORY_BLOCK_ACK_ACTION: + DBGLOG(RX, WARN, + "[Puff][%s] Rx CATEGORY_BLOCK_ACK_ACTION\n", __func__); + + if (prSwRfb->prStaRec) + mqmHandleBaActionFrame(prAdapter, prSwRfb); + + break; +#endif +#if DSCP_SUPPORT + case CATEGORY_QOS_ACTION: + DBGLOG(RX, INFO, "received dscp action frame: %d\n", + __LINE__); + handleQosMapConf(prAdapter, prSwRfb); + break; +#endif + case CATEGORY_PUBLIC_ACTION: + aisFuncValidateRxActionFrame(prAdapter, prSwRfb); +#if CFG_ENABLE_WIFI_DIRECT + if (prAdapter->fgIsP2PRegistered) { + rlmProcessPublicAction(prAdapter, prSwRfb); + if (prBssInfo) + p2pFuncValidateRxActionFrame(prAdapter, prSwRfb, + (prBssInfo->ucBssIndex == + prAdapter->ucP2PDevBssIdx), + (uint8_t) prBssInfo->u4PrivateData); + else + p2pFuncValidateRxActionFrame(prAdapter, + prSwRfb, TRUE, 0); + } +#endif + break; + + case CATEGORY_HT_ACTION: + rlmProcessHtAction(prAdapter, prSwRfb); + break; + case CATEGORY_VENDOR_SPECIFIC_ACTION: +#if CFG_ENABLE_WIFI_DIRECT + if (prAdapter->fgIsP2PRegistered) { + if (prBssInfo) + p2pFuncValidateRxActionFrame(prAdapter, prSwRfb, + (prBssInfo->ucBssIndex == + prAdapter->ucP2PDevBssIdx), + (uint8_t) prBssInfo->u4PrivateData); + else + p2pFuncValidateRxActionFrame(prAdapter, + prSwRfb, TRUE, 0); + } +#endif +#if CFG_SUPPORT_NCHO + if (prBssInfo && prBssInfo->eNetworkType == NETWORK_TYPE_AIS) { + if (prAdapter->rNchoInfo.fgNCHOEnabled == TRUE + && prAdapter->rNchoInfo.u4WesMode == TRUE) { + aisFuncValidateRxActionFrame(prAdapter, + prSwRfb); + DBGLOG(INIT, INFO, + "NCHO CATEGORY_VENDOR_SPECIFIC_ACTION\n"); + } + } +#endif + break; +#if CFG_SUPPORT_802_11W + case CATEGORY_SA_QUERY_ACTION: { + struct BSS_INFO *prBssInfo; + + if (prSwRfb->prStaRec) { + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prSwRfb->prStaRec->ucBssIndex); + ASSERT(prBssInfo); + if ((prBssInfo->eNetworkType == NETWORK_TYPE_AIS) && + aisGetAisSpecBssInfo(prAdapter, + prSwRfb->prStaRec->ucBssIndex)-> + fgMgmtProtection /* Use MFP */) { + /* MFP test plan 5.3.3.4 */ + rsnSaQueryAction(prAdapter, prSwRfb); + } else if ((prBssInfo->eNetworkType == + NETWORK_TYPE_P2P) && + (prBssInfo->eCurrentOPMode == + OP_MODE_ACCESS_POINT)) { + /* AP PMF */ + DBGLOG(RSN, INFO, + "[Rx] nicRx AP PMF SAQ action\n"); + if (rsnCheckBipKeyInstalled(prAdapter, + prSwRfb->prStaRec)) { + /* MFP test plan 4.3.3.4 */ + rsnApSaQueryAction(prAdapter, prSwRfb); + } + } + } + } + break; +#endif + case CATEGORY_WNM_ACTION: { + if (prSwRfb->prStaRec && + GET_BSS_INFO_BY_INDEX(prAdapter, + prSwRfb->prStaRec->ucBssIndex) + ->eNetworkType == NETWORK_TYPE_AIS) { + DBGLOG(RX, INFO, "WNM action frame: %d\n", __LINE__); + wnmWNMAction(prAdapter, prSwRfb); + } else + DBGLOG(RX, INFO, "WNM action frame: %d\n", __LINE__); + } + break; + +#if CFG_SUPPORT_DFS + case CATEGORY_SPEC_MGT: { + if (prAdapter->fgEnable5GBand) { + DBGLOG(RLM, INFO, + "[Channel Switch]nicRxProcessActionFrame\n"); + rlmProcessSpecMgtAction(prAdapter, prSwRfb); + } + } + break; +#endif + +#if CFG_SUPPORT_802_11AC + case CATEGORY_VHT_ACTION: + rlmProcessVhtAction(prAdapter, prSwRfb); + break; +#endif + +#if (CFG_SUPPORT_TWT == 1) + case CATEGORY_S1G_ACTION: + twtProcessS1GAction(prAdapter, prSwRfb); + break; +#endif + +#if CFG_SUPPORT_802_11K + case CATEGORY_RM_ACTION: + switch (prActFrame->ucAction) { + case RM_ACTION_RM_REQUEST: +#if CFG_SUPPORT_RM_BEACON_REPORT_BY_SUPPLICANT + /* handle RM beacon request by supplicant */ + if (prAdapter->prAisBssInfo && + prSwRfb->prStaRec + && prSwRfb->prStaRec->ucBssIndex == + prAdapter->prAisBssInfo->ucBssIndex) + aisFuncValidateRxActionFrame(prAdapter, + prSwRfb); +#else + rrmProcessRadioMeasurementRequest(prAdapter, prSwRfb); +#endif + break; + case RM_ACTION_REIGHBOR_RESPONSE: + rrmProcessNeighborReportResonse(prAdapter, prActFrame, + prSwRfb); + break; + } + break; +#endif + case CATEGORY_WME_MGT_NOTIFICATION: + wmmParseQosAction(prAdapter, prSwRfb); + break; + default: + break; + } /* end of switch case */ + + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief + * + * @param + * + * @retval + */ +/*----------------------------------------------------------------------------*/ +uint8_t nicRxGetRcpiValueFromRxv( + IN struct ADAPTER *prAdapter, + IN uint8_t ucRcpiMode, + IN struct SW_RFB *prSwRfb) +{ + struct mt66xx_chip_info *prChipInfo; + + prChipInfo = prAdapter->chip_info; + if (prChipInfo->asicRxGetRcpiValueFromRxv) + return prChipInfo->asicRxGetRcpiValueFromRxv( + ucRcpiMode, prSwRfb); + else { + DBGLOG(RX, ERROR, "%s: no asicRxGetRcpiValueFromRxv ??\n", + __func__); + return 0; + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief + * + * @param + * + * @retval + */ +/*----------------------------------------------------------------------------*/ +int32_t nicRxGetLastRxRssi(struct ADAPTER *prAdapter, IN char *pcCommand, + IN int i4TotalLen, IN uint8_t ucWlanIdx) +{ + int32_t i4RSSI0 = 0, i4RSSI1 = 0, i4RSSI2 = 0, i4RSSI3 = 0; + int32_t i4BytesWritten = 0; + uint32_t u4RxVector3 = 0; + uint8_t ucStaIdx; + struct CHIP_DBG_OPS *prChipDbg; + + if (wlanGetStaIdxByWlanIdx(prAdapter, ucWlanIdx, &ucStaIdx) == + WLAN_STATUS_SUCCESS) { + u4RxVector3 = prAdapter->arStaRec[ucStaIdx].u4RxVector3; + DBGLOG(REQ, LOUD, "****** RX Vector3 = 0x%08x ******\n", + u4RxVector3); + } else { + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s", "Last RX RSSI", " = NOT SUPPORT"); + return i4BytesWritten; + } + + prChipDbg = prAdapter->chip_info->prDebugOps; + + if (prChipDbg && prChipDbg->show_rx_rssi_info) { + i4BytesWritten = prChipDbg->show_rx_rssi_info( + prAdapter, + pcCommand, + i4TotalLen, + ucStaIdx); + return i4BytesWritten; + } + + i4RSSI0 = RCPI_TO_dBm((u4RxVector3 & RX_VT_RCPI0_MASK) >> + RX_VT_RCPI0_OFFSET); + i4RSSI1 = RCPI_TO_dBm((u4RxVector3 & RX_VT_RCPI1_MASK) >> + RX_VT_RCPI1_OFFSET); + + if (prAdapter->rWifiVar.ucNSS > 2) { + i4RSSI2 = RCPI_TO_dBm((u4RxVector3 & RX_VT_RCPI2_MASK) >> + RX_VT_RCPI2_OFFSET); + i4RSSI3 = RCPI_TO_dBm((u4RxVector3 & RX_VT_RCPI3_MASK) >> + RX_VT_RCPI3_OFFSET); + + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%-20s%s%d %d %d %d\n", + "Last RX Data RSSI", " = ", + i4RSSI0, i4RSSI1, i4RSSI2, i4RSSI3); + } else + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%-20s%s%d %d\n", + "Last RX Data RSSI", " = ", i4RSSI0, i4RSSI1); + + return i4BytesWritten; +} + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/nic_rxd_v1.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/nic_rxd_v1.c new file mode 100644 index 0000000000000000000000000000000000000000..0a7ce29638721d7a43ea0b5c4aef191717b4e19b --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/nic_rxd_v1.c @@ -0,0 +1,596 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic_tx.c#2 + */ + +/*! \file nic_tx.c + * \brief Functions that provide TX operation in NIC Layer. + * + * This file provides TX functions which are responsible for both Hardware + * and Software Resource Management and keep their Synchronization. + */ + + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +uint16_t nic_rxd_v1_get_rx_byte_count( + void *prRxStatus) +{ + return HAL_RX_STATUS_GET_RX_BYTE_CNT( + (struct HW_MAC_RX_DESC *)prRxStatus); +} + +uint8_t nic_rxd_v1_get_packet_type( + void *prRxStatus) +{ + return HAL_RX_STATUS_GET_PKT_TYPE( + (struct HW_MAC_RX_DESC *)prRxStatus); +} + +uint8_t nic_rxd_v1_get_wlan_idx( + void *prRxStatus) +{ + return HAL_RX_STATUS_GET_WLAN_IDX( + (struct HW_MAC_RX_DESC *)prRxStatus); +} + +uint8_t nic_rxd_v1_get_sec_mode( + void *prRxStatus) +{ + return HAL_RX_STATUS_GET_SEC_MODE( + (struct HW_MAC_RX_DESC *)prRxStatus); +} + +uint8_t nic_rxd_v1_get_sw_class_error_bit( + void *prRxStatus) +{ + struct HW_MAC_RX_DESC *prRxD; + + prRxD = (struct HW_MAC_RX_DESC *)prRxStatus; + + if ((prRxD->u2StatusFlag & RXS_DW2_RX_CLASSERR_BITMAP) + == RXS_DW2_RX_CLASSERR_VALUE) { + DBGLOG(RSN, ERROR, + "RX_CLASSERR: StatusFlag=0x%x\n", + prRxD->u2StatusFlag); + return TRUE; + } else + return FALSE; +} + +uint8_t nic_rxd_v1_get_ch_num( + void *prRxStatus) +{ + return HAL_RX_STATUS_GET_CHNL_NUM( + (struct HW_MAC_RX_DESC *)prRxStatus); +} + +uint8_t nic_rxd_v1_get_rf_band( + void *prRxStatus) +{ + return HAL_RX_STATUS_GET_RF_BAND( + (struct HW_MAC_RX_DESC *)prRxStatus); +} + +uint8_t nic_rxd_v1_get_tcl( + void *prRxStatus) +{ + return HAL_RX_STATUS_GET_TCL( + (struct HW_MAC_RX_DESC *)prRxStatus); +} + +uint8_t nic_rxd_v1_get_ofld( + void *prRxStatus) +{ + return HAL_RX_STATUS_GET_OFLD( + (struct HW_MAC_RX_DESC *)prRxStatus); +} +/*----------------------------------------------------------------------------*/ +/*! + * @brief Fill RFB + * + * @param prAdapter pointer to the Adapter handler + * @param prSWRfb specify the RFB to receive rx data + * + * @return (none) + * + */ +/*----------------------------------------------------------------------------*/ +void nic_rxd_v1_fill_rfb( + struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb) +{ + struct mt66xx_chip_info *prChipInfo; + struct HW_MAC_RX_DESC *prRxStatus; + + uint32_t u4PktLen = 0; + /* UINT_32 u4MacHeaderLen; */ + uint32_t u4HeaderOffset; + uint16_t u2RxStatusOffset; + + DEBUGFUNC("nicRxFillRFB"); + + prChipInfo = prAdapter->chip_info; + prRxStatus = prSwRfb->prRxStatus; + + u4PktLen = (uint32_t) HAL_RX_STATUS_GET_RX_BYTE_CNT( + prRxStatus); + u4HeaderOffset = (uint32_t) ( + HAL_RX_STATUS_GET_HEADER_OFFSET(prRxStatus)); + + u2RxStatusOffset = prChipInfo->rxd_size; + prSwRfb->ucGroupVLD = (uint8_t) HAL_RX_STATUS_GET_GROUP_VLD( + prRxStatus); + if (prSwRfb->ucGroupVLD & BIT(RX_GROUP_VLD_4)) { + prSwRfb->prRxStatusGroup4 = (struct HW_MAC_RX_STS_GROUP_4 *) + ((uint8_t *) prRxStatus + u2RxStatusOffset); + u2RxStatusOffset += sizeof(struct HW_MAC_RX_STS_GROUP_4); + + } + if (prSwRfb->ucGroupVLD & BIT(RX_GROUP_VLD_1)) { + prSwRfb->prRxStatusGroup1 = (struct HW_MAC_RX_STS_GROUP_1 *) + ((uint8_t *) prRxStatus + u2RxStatusOffset); + u2RxStatusOffset += sizeof(struct HW_MAC_RX_STS_GROUP_1); + + } + if (prSwRfb->ucGroupVLD & BIT(RX_GROUP_VLD_2)) { + prSwRfb->prRxStatusGroup2 = (struct HW_MAC_RX_STS_GROUP_2 *) + ((uint8_t *) prRxStatus + u2RxStatusOffset); + u2RxStatusOffset += sizeof(struct HW_MAC_RX_STS_GROUP_2); + + } + if (prSwRfb->ucGroupVLD & BIT(RX_GROUP_VLD_3)) { + prSwRfb->prRxStatusGroup3 = (struct HW_MAC_RX_STS_GROUP_3 *) + ((uint8_t *) prRxStatus + u2RxStatusOffset); + u2RxStatusOffset += sizeof(struct HW_MAC_RX_STS_GROUP_3); + } + + prSwRfb->u2RxStatusOffst = u2RxStatusOffset; + prSwRfb->pvHeader = (uint8_t *) prRxStatus + + u2RxStatusOffset + u4HeaderOffset; + prSwRfb->u2RxByteCount = u4PktLen; + prSwRfb->u2PacketLen = (uint16_t) (u4PktLen - + (u2RxStatusOffset + u4HeaderOffset)); + prSwRfb->u2HeaderLen = (uint16_t) + HAL_RX_STATUS_GET_HEADER_LEN(prRxStatus); + prSwRfb->ucWlanIdx = (uint8_t) HAL_RX_STATUS_GET_WLAN_IDX( + prRxStatus); + prSwRfb->ucStaRecIdx = secGetStaIdxByWlanIdx(prAdapter, + (uint8_t) HAL_RX_STATUS_GET_WLAN_IDX(prRxStatus)); + prSwRfb->prStaRec = cnmGetStaRecByIndex(prAdapter, + prSwRfb->ucStaRecIdx); + prSwRfb->ucTid = (uint8_t) HAL_RX_STATUS_GET_TID( + prRxStatus); + prSwRfb->fgHdrTran = HAL_RX_STATUS_IS_HEADER_TRAN(prRxStatus); + prSwRfb->ucPayloadFormat = HAL_RX_STATUS_GET_PAYLOAD_FORMAT(prRxStatus); + prSwRfb->fgIcvErr = HAL_RX_STATUS_IS_ICV_ERROR(prRxStatus); + prSwRfb->ucSecMode = HAL_RX_STATUS_GET_SEC_MODE(prRxStatus); + prSwRfb->ucOFLD = HAL_RX_STATUS_GET_OFLD(prRxStatus); + prSwRfb->fgIsBC = HAL_RX_STATUS_IS_BC(prRxStatus); + prSwRfb->fgIsMC = HAL_RX_STATUS_IS_MC(prRxStatus); + prSwRfb->fgIsCipherMS = HAL_RX_STATUS_IS_CIPHER_MISMATCH(prRxStatus); + prSwRfb->fgIsCipherLenMS = HAL_RX_STATUS_IS_CLM_ERROR(prRxStatus); + prSwRfb->ucKeyID = HAL_RX_STATUS_GET_KEY_ID(prRxStatus); + prSwRfb->fgIsFrag = HAL_RX_STATUS_IS_FRAG(prRxStatus); + prSwRfb->fgIsFCS = HAL_RX_STATUS_IS_FCS_ERROR(prRxStatus); + prSwRfb->fgIsAmpdu = HAL_RX_STATUS_IS_AMPDU_FORMAT(prRxStatus); + prSwRfb->ucRxvSeqNo = HAL_RX_STATUS_GET_RXV_SEQ_NO(prRxStatus); + prSwRfb->ucChnlNum = HAL_RX_STATUS_GET_CHNL_NUM(prRxStatus); + +#if 0 + if (prHifRxHdr->ucReorder & + HIF_RX_HDR_80211_HEADER_FORMAT) { + prSwRfb->u4HifRxHdrFlag |= HIF_RX_HDR_FLAG_802_11_FORMAT; + DBGLOG(RX, TRACE, "HIF_RX_HDR_FLAG_802_11_FORMAT\n"); + } + + if (prHifRxHdr->ucReorder & HIF_RX_HDR_DO_REORDER) { + prSwRfb->u4HifRxHdrFlag |= HIF_RX_HDR_FLAG_DO_REORDERING; + DBGLOG(RX, TRACE, "HIF_RX_HDR_FLAG_DO_REORDERING\n"); + + /* Get Seq. No and TID, Wlan Index info */ + if (prHifRxHdr->u2SeqNoTid & HIF_RX_HDR_BAR_FRAME) { + prSwRfb->u4HifRxHdrFlag |= HIF_RX_HDR_FLAG_BAR_FRAME; + DBGLOG(RX, TRACE, "HIF_RX_HDR_FLAG_BAR_FRAME\n"); + } + + prSwRfb->u2SSN = prHifRxHdr->u2SeqNoTid & + HIF_RX_HDR_SEQ_NO_MASK; + prSwRfb->ucTid = (uint8_t) ((prHifRxHdr->u2SeqNoTid & + HIF_RX_HDR_TID_MASK) + >> HIF_RX_HDR_TID_OFFSET); + DBGLOG(RX, TRACE, "u2SSN = %d, ucTid = %d\n", + prSwRfb->u2SSN, prSwRfb->ucTid); + } + + if (prHifRxHdr->ucReorder & HIF_RX_HDR_WDS) { + prSwRfb->u4HifRxHdrFlag |= HIF_RX_HDR_FLAG_AMP_WDS; + DBGLOG(RX, TRACE, "HIF_RX_HDR_FLAG_AMP_WDS\n"); + } +#endif +} + +u_int8_t nic_rxd_v1_sanity_check( + struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb) +{ + struct mt66xx_chip_info *prChipInfo; + struct HW_MAC_RX_DESC *prRxStatus; + u_int8_t fgDrop = FALSE; + + prChipInfo = prAdapter->chip_info; + prRxStatus = (struct HW_MAC_RX_DESC *)prSwRfb->prRxStatus; + /* BA session */ + if ((prRxStatus->u2StatusFlag & RXS_DW2_AMPDU_nERR_BITMAP) + == RXS_DW2_AMPDU_nERR_VALUE) + prSwRfb->fgReorderBuffer = TRUE; + /* non BA session */ + else if ((prRxStatus->u2StatusFlag & RXS_DW2_RX_nERR_BITMAP) + == RXS_DW2_RX_nERR_VALUE) { + if ((prRxStatus->u2StatusFlag & RXS_DW2_RX_nDATA_BITMAP) == + RXS_DW2_RX_nDATA_VALUE) + prSwRfb->fgDataFrame = FALSE; + + if ((prRxStatus->u2StatusFlag & RXS_DW2_RX_FRAG_BITMAP) == + RXS_DW2_RX_FRAG_VALUE) + prSwRfb->fgFragFrame = TRUE; + + } else { + DBGLOG(RX, TEMP, "Sanity check to drop\n"); + fgDrop = TRUE; + if (!HAL_RX_STATUS_IS_ICV_ERROR(prRxStatus) + && HAL_RX_STATUS_IS_TKIP_MIC_ERROR(prRxStatus)) { + uint8_t ucBssIndex = + secGetBssIdxByWlanIdx(prAdapter, + HAL_RX_STATUS_GET_WLAN_IDX(prRxStatus)); + struct STA_RECORD *prStaRec = NULL; + struct PARAM_BSSID_EX *prCurrBssid = + aisGetCurrBssId(prAdapter, + ucBssIndex); + + if (prCurrBssid) + prStaRec = cnmGetStaRecByAddress(prAdapter, + ucBssIndex, + prCurrBssid->arMacAddress); + if (prStaRec) { + DBGLOG(RSN, EVENT, "MIC_ERR_PKT\n"); + rsnTkipHandleMICFailure(prAdapter, prStaRec, 0); + } + } +#if UNIFIED_MAC_RX_FORMAT + else if (HAL_RX_STATUS_IS_LLC_MIS(prRxStatus) + && !HAL_RX_STATUS_IS_ERROR(prRxStatus) + && !FEAT_SUP_LLC_VLAN_RX(prChipInfo)) { + uint16_t *pu2EtherType; + + nicRxFillRFB(prAdapter, prSwRfb); + + pu2EtherType = (uint16_t *) + ((uint8_t *)prSwRfb->pvHeader + + 2 * MAC_ADDR_LEN); + + /* If ethernet type is VLAN, do not drop it. + * Pass up to driver process + */ + if (prSwRfb->u2HeaderLen >= ETH_HLEN + && *pu2EtherType == NTOHS(ETH_P_VLAN)) + fgDrop = FALSE; + +#if CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION + /* + * let qmAmsduAttackDetection check this subframe + * before drop it + */ + if (prSwRfb->ucPayloadFormat + == RX_PAYLOAD_FORMAT_FIRST_SUB_AMSDU) { + fgDrop = FALSE; + prSwRfb->fgIsFirstSubAMSDULLCMS = TRUE; + } +#endif /* CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION */ + } +#else + else if (HAL_RX_STATUS_IS_LLC_MIS(prRxStatus)) { + DBGLOG(RSN, EVENT, ("LLC_MIS_ERR\n")); + fgDrop = TRUE; /* Drop after send de-auth */ + } +#endif + + DBGLOG(RSN, TRACE, "Sanity check to drop:%d\n", fgDrop); + } + + /* Drop plain text during security connection */ + if (prSwRfb->fgIsCipherMS && prSwRfb->fgDataFrame == TRUE) { + uint16_t *pu2EtherType; + + pu2EtherType = (uint16_t *) + ((uint8_t *)prSwRfb->pvHeader + + 2 * MAC_ADDR_LEN); + if (prSwRfb->u2HeaderLen >= ETH_HLEN + && (*pu2EtherType == NTOHS(ETH_P_1X) +#if CFG_SUPPORT_WAPI + || (*pu2EtherType == NTOHS(ETH_WPI_1X)) +#endif + )) { + fgDrop = FALSE; + DBGLOG(RSN, INFO, + "Don't drop eapol or wpi packet\n"); + } else { + fgDrop = TRUE; + DBGLOG(RSN, INFO, + "Drop plain text during security connection\n"); + } + } + +#if CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION + /* Drop fragmented broadcast and multicast frame */ + if ((prSwRfb->fgIsBC | prSwRfb->fgIsMC) + && (prSwRfb->fgFragFrame == TRUE)) { + fgDrop = TRUE; + DBGLOG(RSN, INFO, + "Drop fragmented broadcast and multicast\n"); + } + + if (HAL_RX_STATUS_IS_DE_AMSDU_FAIL(prRxStatus)) + DBGLOG(RSN, INFO, "De-amsdu fail, drop:%d\n", fgDrop); +#endif /* CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION */ + + return fgDrop; +} + +#if CFG_SUPPORT_WAKEUP_REASON_DEBUG +void nic_rxd_v1_check_wakeup_reason( + struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb) +{ + struct mt66xx_chip_info *prChipInfo; + struct WIFI_EVENT *prEvent; + uint8_t *pvHeader = NULL; + struct HW_MAC_RX_DESC *prRxStatus; + uint16_t u2PktLen = 0; + uint32_t u4HeaderOffset; + + prChipInfo = prAdapter->chip_info; + + prRxStatus = (struct HW_MAC_RX_DESC *)prSwRfb->prRxStatus; + if (!prRxStatus) + return; + + prSwRfb->ucGroupVLD = (uint8_t) HAL_RX_STATUS_GET_GROUP_VLD(prRxStatus); + + switch (prSwRfb->ucPacketType) { + case RX_PKT_TYPE_RX_DATA: + { + uint16_t u2Temp = 0; + + u2PktLen = HAL_RX_STATUS_GET_RX_BYTE_CNT(prRxStatus); + u4HeaderOffset = (uint32_t) + (HAL_RX_STATUS_GET_HEADER_OFFSET(prRxStatus)); + u2Temp = prChipInfo->rxd_size; + if (prSwRfb->ucGroupVLD & BIT(RX_GROUP_VLD_4)) + u2Temp += sizeof(struct HW_MAC_RX_STS_GROUP_4); + if (prSwRfb->ucGroupVLD & BIT(RX_GROUP_VLD_1)) + u2Temp += sizeof(struct HW_MAC_RX_STS_GROUP_1); + if (prSwRfb->ucGroupVLD & BIT(RX_GROUP_VLD_2)) + u2Temp += sizeof(struct HW_MAC_RX_STS_GROUP_2); + if (prSwRfb->ucGroupVLD & BIT(RX_GROUP_VLD_3)) + u2Temp += sizeof(struct HW_MAC_RX_STS_GROUP_3); + pvHeader = (uint8_t *)prRxStatus + u2Temp + u4HeaderOffset; + u2PktLen -= u2Temp + u4HeaderOffset; + if (!pvHeader) { + DBGLOG(RX, ERROR, + "data packet but pvHeader is NULL!\n"); + break; + } + if ((prRxStatus->u2StatusFlag & (RXS_DW2_RX_nERR_BITMAP | + RXS_DW2_RX_nDATA_BITMAP)) == RXS_DW2_RX_nDATA_VALUE) { + struct WLAN_MAC_HEADER *prWlanMacHeader = + (struct WLAN_MAC_HEADER *)pvHeader; + + if ((prWlanMacHeader->u2FrameCtrl & MASK_FRAME_TYPE) == + MAC_FRAME_BLOCK_ACK_REQ) { + DBGLOG(RX, INFO, + "BAR frame[SSN:%d,TID:%d] wakeup host\n" + , prSwRfb->u2SSN, prSwRfb->ucTid); + break; + } + } + u2Temp = (pvHeader[ETH_TYPE_LEN_OFFSET] << 8) | + (pvHeader[ETH_TYPE_LEN_OFFSET + 1]); + + switch (u2Temp) { + case ETH_P_IPV4: + u2Temp = *(uint16_t *) &pvHeader[ETH_HLEN + 4]; + DBGLOG(RX, INFO, + "IP Packet from:%d.%d.%d.%d,", + pvHeader[ETH_HLEN + 12], + pvHeader[ETH_HLEN + 13], + pvHeader[ETH_HLEN + 14], + pvHeader[ETH_HLEN + 15]); + DBGLOG(RX, INFO, + " IP ID 0x%04x wakeup host\n", + u2Temp); + break; + case ETH_P_ARP: + break; + case ETH_P_1X: + case ETH_P_PRE_1X: +#if CFG_SUPPORT_WAPI + case ETH_WPI_1X: +#endif + case ETH_P_AARP: + case ETH_P_IPV6: + case ETH_P_IPX: + case 0x8100: /* VLAN */ + case 0x890d: /* TDLS */ + DBGLOG(RX, INFO, + "Data Packet, EthType 0x%04x wakeup host\n", + u2Temp); + break; + default: + DBGLOG(RX, WARN, + "abnormal packet, EthType 0x%04x wakeup host\n", + u2Temp); + DBGLOG_MEM8(RX, INFO, + pvHeader, u2PktLen > 50 ? 50:u2PktLen); + break; + } + break; + } + case RX_PKT_TYPE_SW_DEFINED: + /* HIF_RX_PKT_TYPE_EVENT */ + if ((NIC_RX_GET_U2_SW_PKT_TYPE(prSwRfb->prRxStatus) & + RXM_RXD_PKT_TYPE_SW_BITMAP) == + RXM_RXD_PKT_TYPE_SW_EVENT) { + + prEvent = (struct WIFI_EVENT *) + (prSwRfb->pucRecvBuff + prChipInfo->rxd_size); + + DBGLOG(RX, INFO, "Event 0x%02x wakeup host\n", + prEvent->ucEID); + break; + + } + /* case HIF_RX_PKT_TYPE_MANAGEMENT: */ + else if ((NIC_RX_GET_U2_SW_PKT_TYPE(prSwRfb->prRxStatus) & + RXM_RXD_PKT_TYPE_SW_BITMAP) == + RXM_RXD_PKT_TYPE_SW_FRAME) { + uint8_t ucSubtype; + struct WLAN_MAC_MGMT_HEADER *prWlanMgmtHeader; + uint16_t u2Temp = prChipInfo->rxd_size; + + u4HeaderOffset = (uint32_t) + (HAL_RX_STATUS_GET_HEADER_OFFSET(prRxStatus)); + if (prSwRfb->ucGroupVLD & BIT(RX_GROUP_VLD_4)) + u2Temp += sizeof(struct HW_MAC_RX_STS_GROUP_4); + if (prSwRfb->ucGroupVLD & BIT(RX_GROUP_VLD_1)) + u2Temp += sizeof(struct HW_MAC_RX_STS_GROUP_1); + if (prSwRfb->ucGroupVLD & BIT(RX_GROUP_VLD_2)) + u2Temp += sizeof(struct HW_MAC_RX_STS_GROUP_2); + if (prSwRfb->ucGroupVLD & BIT(RX_GROUP_VLD_3)) + u2Temp += sizeof(struct HW_MAC_RX_STS_GROUP_3); + pvHeader = (uint8_t *) + prRxStatus + u2Temp + u4HeaderOffset; + if (!pvHeader) { + DBGLOG(RX, ERROR, + "Mgmt Frame but pvHeader is NULL!\n"); + break; + } + prWlanMgmtHeader = + (struct WLAN_MAC_MGMT_HEADER *)pvHeader; + ucSubtype = (prWlanMgmtHeader->u2FrameCtrl & + MASK_FC_SUBTYPE) >> OFFSET_OF_FC_SUBTYPE; + DBGLOG(RX, INFO, + "MGMT frame subtype: %d\n", + ucSubtype); + DBGLOG(RX, INFO, + " SeqCtrl %d wakeup host\n", + prWlanMgmtHeader->u2SeqCtrl); + } else { + DBGLOG(RX, ERROR, + "[%s]: u2PktTYpe(0x%04X) is OUT OF DEF.!!!\n", + __func__, prSwRfb->ucPacketType); + ASSERT(0); + } + break; + default: + DBGLOG(RX, WARN, "Unknown Packet %d wakeup host\n", + prSwRfb->ucPacketType); + break; + } +} +#endif /* CFG_SUPPORT_WAKEUP_REASON_DEBUG */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/nic_rxd_v2.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/nic_rxd_v2.c new file mode 100644 index 0000000000000000000000000000000000000000..09218fccf1bb778fc6c51ad6a31ae9e7549321d0 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/nic_rxd_v2.c @@ -0,0 +1,627 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic_tx.c#2 + */ + +/*! \file nic_tx.c + * \brief Functions that provide TX operation in NIC Layer. + * + * This file provides TX functions which are responsible for both Hardware + * and Software Resource Management and keep their Synchronization. + */ + + +#if (CFG_SUPPORT_CONNAC2X == 1) +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +uint16_t nic_rxd_v2_get_rx_byte_count( + void *prRxStatus) +{ + return HAL_MAC_CONNAC2X_RX_STATUS_GET_RX_BYTE_CNT( + (struct HW_MAC_CONNAC2X_RX_DESC *)prRxStatus); +} + +uint8_t nic_rxd_v2_get_packet_type( + void *prRxStatus) +{ + return HAL_MAC_CONNAC2X_RX_STATUS_GET_PKT_TYPE( + (struct HW_MAC_CONNAC2X_RX_DESC *)prRxStatus); +} + +uint8_t nic_rxd_v2_get_wlan_idx( + void *prRxStatus) +{ + return HAL_MAC_CONNAC2X_RX_STATUS_GET_WLAN_IDX( + (struct HW_MAC_CONNAC2X_RX_DESC *)prRxStatus); +} + +uint8_t nic_rxd_v2_get_sec_mode( + void *prRxStatus) +{ + return HAL_MAC_CONNAC2X_RX_STATUS_GET_SEC_MODE( + (struct HW_MAC_CONNAC2X_RX_DESC *)prRxStatus); +} + +uint8_t nic_rxd_v2_get_sw_class_error_bit( + void *prRxStatus) +{ + struct HW_MAC_CONNAC2X_RX_DESC *prRxD; + + prRxD = (struct HW_MAC_CONNAC2X_RX_DESC *)prRxStatus; + if (HAL_MAC_CONNAC2X_RX_STATUS_IS_SW_DEFINE_RX_CLASSERR(prRxD)) { + DBGLOG(RSN, ERROR, + "RX_CLASSERR: RXD.DW2=0x%x\n", + prRxD->u4DW2); + return TRUE; + } else + return FALSE; +} + +uint8_t nic_rxd_v2_get_ch_num( + void *prRxStatus) +{ + return HAL_MAC_CONNAC2X_RX_STATUS_GET_CHNL_NUM( + (struct HW_MAC_CONNAC2X_RX_DESC *)prRxStatus); +} + +uint8_t nic_rxd_v2_get_rf_band( + void *prRxStatus) +{ + return HAL_MAC_CONNAC2X_RX_STATUS_GET_RF_BAND( + (struct HW_MAC_CONNAC2X_RX_DESC *)prRxStatus); +} + +uint8_t nic_rxd_v2_get_tcl( + void *prRxStatus) +{ + return HAL_MAC_CONNAC2X_RX_STATUS_GET_TCL( + (struct HW_MAC_CONNAC2X_RX_DESC *)prRxStatus); +} + +uint8_t nic_rxd_v2_get_ofld( + void *prRxStatus) +{ + return HAL_MAC_CONNAC2X_RX_STATUS_GET_OFLD( + (struct HW_MAC_CONNAC2X_RX_DESC *)prRxStatus); +} +/*----------------------------------------------------------------------------*/ +/*! + * @brief Fill RFB + * + * @param prAdapter pointer to the Adapter handler + * @param prSWRfb specify the RFB to receive rx data + * + * @return (none) + * + */ +/*----------------------------------------------------------------------------*/ +void nic_rxd_v2_fill_rfb( + struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb) +{ + struct mt66xx_chip_info *prChipInfo; + struct HW_MAC_CONNAC2X_RX_DESC *prRxStatus; + + uint32_t u4PktLen = 0; + /* UINT_32 u4MacHeaderLen; */ + uint32_t u4HeaderOffset; + uint16_t u2RxStatusOffset; + + DEBUGFUNC("nicRxFillRFB"); + + prChipInfo = prAdapter->chip_info; + prRxStatus = prSwRfb->prRxStatus; + + u4PktLen = (uint32_t) HAL_MAC_CONNAC2X_RX_STATUS_GET_RX_BYTE_CNT( + prRxStatus); + u4HeaderOffset = (uint32_t) ( + HAL_MAC_CONNAC2X_RX_STATUS_GET_HEADER_OFFSET(prRxStatus)); + + u2RxStatusOffset = prChipInfo->rxd_size; + prSwRfb->ucGroupVLD = + (uint8_t) HAL_MAC_CONNAC2X_RX_STATUS_GET_GROUP_VLD(prRxStatus); + if (prSwRfb->ucGroupVLD & BIT(RX_GROUP_VLD_4)) { + prSwRfb->prRxStatusGroup4 = (struct HW_MAC_RX_STS_GROUP_4 *) + ((uint8_t *) prRxStatus + u2RxStatusOffset); + u2RxStatusOffset += sizeof(struct HW_MAC_RX_STS_GROUP_4); + + } + if (prSwRfb->ucGroupVLD & BIT(RX_GROUP_VLD_1)) { + prSwRfb->prRxStatusGroup1 = (struct HW_MAC_RX_STS_GROUP_1 *) + ((uint8_t *) prRxStatus + u2RxStatusOffset); + u2RxStatusOffset += sizeof(struct HW_MAC_RX_STS_GROUP_1); + + } + if (prSwRfb->ucGroupVLD & BIT(RX_GROUP_VLD_2)) { + prSwRfb->prRxStatusGroup2 = (struct HW_MAC_RX_STS_GROUP_2 *) + ((uint8_t *) prRxStatus + u2RxStatusOffset); + u2RxStatusOffset += sizeof(struct HW_MAC_RX_STS_GROUP_2); + + } + if (prSwRfb->ucGroupVLD & BIT(RX_GROUP_VLD_3)) { + prSwRfb->prRxStatusGroup3 = (void *) + ((uint8_t *) prRxStatus + u2RxStatusOffset); + u2RxStatusOffset += sizeof(struct HW_MAC_RX_STS_GROUP_3_V2); + } + + if (prSwRfb->ucGroupVLD & BIT(RX_GROUP_VLD_5)) { + prSwRfb->prRxStatusGroup5 = (struct HW_MAC_RX_STS_GROUP_5 *) + ((uint8_t *) prRxStatus + u2RxStatusOffset); + u2RxStatusOffset += prChipInfo->group5_size; + } + + + prSwRfb->u2RxStatusOffst = u2RxStatusOffset; + prSwRfb->pvHeader = (uint8_t *) prRxStatus + + u2RxStatusOffset + u4HeaderOffset; + prSwRfb->u2RxByteCount = u4PktLen; + prSwRfb->u2PacketLen = (uint16_t) (u4PktLen - + (u2RxStatusOffset + u4HeaderOffset)); + prSwRfb->u2HeaderLen = (uint16_t) + HAL_MAC_CONNAC2X_RX_STATUS_GET_HEADER_LEN(prRxStatus); + prSwRfb->ucWlanIdx = + (uint8_t) HAL_MAC_CONNAC2X_RX_STATUS_GET_WLAN_IDX(prRxStatus); + prSwRfb->ucStaRecIdx = secGetStaIdxByWlanIdx(prAdapter, + (uint8_t) HAL_MAC_CONNAC2X_RX_STATUS_GET_WLAN_IDX(prRxStatus)); + prSwRfb->prStaRec = cnmGetStaRecByIndex(prAdapter, + prSwRfb->ucStaRecIdx); + prSwRfb->ucTid = + (uint8_t) HAL_MAC_CONNAC2X_RX_STATUS_GET_TID(prRxStatus); + prSwRfb->fgHdrTran = + HAL_MAC_CONNAC2X_RX_STATUS_IS_HEADER_TRAN(prRxStatus); + prSwRfb->ucPayloadFormat = + HAL_MAC_CONNAC2X_RX_STATUS_GET_PAYLOAD_FORMAT(prRxStatus); + prSwRfb->fgIcvErr = + HAL_MAC_CONNAC2X_RX_STATUS_IS_ICV_ERROR(prRxStatus); + prSwRfb->ucSecMode = + HAL_MAC_CONNAC2X_RX_STATUS_GET_SEC_MODE(prRxStatus); + prSwRfb->ucOFLD = HAL_MAC_CONNAC2X_RX_STATUS_GET_OFLD(prRxStatus); + prSwRfb->fgIsBC = HAL_MAC_CONNAC2X_RX_STATUS_IS_BC(prRxStatus); + prSwRfb->fgIsMC = HAL_MAC_CONNAC2X_RX_STATUS_IS_MC(prRxStatus); + prSwRfb->fgIsCipherMS = + HAL_MAC_CONNAC2X_RX_STATUS_IS_CIPHER_MISMATCH(prRxStatus); + prSwRfb->fgIsCipherLenMS = + HAL_MAC_CONNAC2X_RX_STATUS_IS_CLM_ERROR(prRxStatus); + prSwRfb->fgIsFrag = HAL_MAC_CONNAC2X_RX_STATUS_IS_FRAG(prRxStatus); + prSwRfb->fgIsFCS = HAL_MAC_CONNAC2X_RX_STATUS_IS_FCS_ERROR(prRxStatus); + prSwRfb->fgIsAmpdu = HAL_MAC_CONNAC2X_RX_STATUS_IS_NAMP(prRxStatus); + prSwRfb->ucRxvSeqNo = + HAL_MAC_CONNAC2X_RX_STATUS_GET_RXV_SEQ_NO(prRxStatus); + prSwRfb->ucChnlNum = + HAL_MAC_CONNAC2X_RX_STATUS_GET_CHNL_NUM(prRxStatus); +#if 0 + if (prHifRxHdr->ucReorder & + HIF_RX_HDR_80211_HEADER_FORMAT) { + prSwRfb->u4HifRxHdrFlag |= HIF_RX_HDR_FLAG_802_11_FORMAT; + DBGLOG(RX, TRACE, "HIF_RX_HDR_FLAG_802_11_FORMAT\n"); + } + + if (prHifRxHdr->ucReorder & HIF_RX_HDR_DO_REORDER) { + prSwRfb->u4HifRxHdrFlag |= HIF_RX_HDR_FLAG_DO_REORDERING; + DBGLOG(RX, TRACE, "HIF_RX_HDR_FLAG_DO_REORDERING\n"); + + /* Get Seq. No and TID, Wlan Index info */ + if (prHifRxHdr->u2SeqNoTid & HIF_RX_HDR_BAR_FRAME) { + prSwRfb->u4HifRxHdrFlag |= HIF_RX_HDR_FLAG_BAR_FRAME; + DBGLOG(RX, TRACE, "HIF_RX_HDR_FLAG_BAR_FRAME\n"); + } + + prSwRfb->u2SSN = prHifRxHdr->u2SeqNoTid & + HIF_RX_HDR_SEQ_NO_MASK; + prSwRfb->ucTid = (uint8_t) ((prHifRxHdr->u2SeqNoTid & + HIF_RX_HDR_TID_MASK) + >> HIF_RX_HDR_TID_OFFSET); + DBGLOG(RX, TRACE, "u2SSN = %d, ucTid = %d\n", + prSwRfb->u2SSN, prSwRfb->ucTid); + } + + if (prHifRxHdr->ucReorder & HIF_RX_HDR_WDS) { + prSwRfb->u4HifRxHdrFlag |= HIF_RX_HDR_FLAG_AMP_WDS; + DBGLOG(RX, TRACE, "HIF_RX_HDR_FLAG_AMP_WDS\n"); + } +#endif +} + +u_int8_t nic_rxd_v2_sanity_check( + struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb) +{ + struct mt66xx_chip_info *prChipInfo; + struct HW_MAC_CONNAC2X_RX_DESC *prRxStatus; + u_int8_t fgDrop = FALSE; + + prChipInfo = prAdapter->chip_info; + prRxStatus = (struct HW_MAC_CONNAC2X_RX_DESC *)prSwRfb->prRxStatus; + + if (!HAL_MAC_CONNAC2X_RX_STATUS_IS_FCS_ERROR(prRxStatus) + && !HAL_MAC_CONNAC2X_RX_STATUS_IS_DAF(prRxStatus) + && !HAL_MAC_CONNAC2X_RX_STATUS_IS_ICV_ERROR(prRxStatus) +#if CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION + && !HAL_MAC_CONNAC2X_RX_STATUS_IS_TKIP_MIC_ERROR(prRxStatus) +#endif /* CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION */ + ) { + if (!HAL_MAC_CONNAC2X_RX_STATUS_IS_NAMP(prRxStatus)) + prSwRfb->fgReorderBuffer = TRUE; + else if (HAL_MAC_CONNAC2X_RX_STATUS_IS_NDATA(prRxStatus)) + prSwRfb->fgDataFrame = FALSE; + else if (HAL_MAC_CONNAC2X_RX_STATUS_IS_FRAG(prRxStatus)) + prSwRfb->fgFragFrame = TRUE; + } else { + uint8_t ucBssIndex = + secGetBssIdxByWlanIdx(prAdapter, + HAL_MAC_CONNAC2X_RX_STATUS_GET_WLAN_IDX(prRxStatus)); + + DBGLOG(RX, TEMP, "Sanity check to drop\n"); + fgDrop = TRUE; + if (!HAL_MAC_CONNAC2X_RX_STATUS_IS_ICV_ERROR(prRxStatus) + && HAL_MAC_CONNAC2X_RX_STATUS_IS_TKIP_MIC_ERROR( + prRxStatus)) { + struct STA_RECORD *prStaRec = NULL; + struct PARAM_BSSID_EX *prCurrBssid = + aisGetCurrBssId(prAdapter, + ucBssIndex); + + if (prCurrBssid) + prStaRec = cnmGetStaRecByAddress(prAdapter, + ucBssIndex, + prCurrBssid->arMacAddress); + if (prStaRec) { + DBGLOG(RSN, EVENT, "MIC_ERR_PKT\n"); + rsnTkipHandleMICFailure(prAdapter, prStaRec, 0); + } + } else if (HAL_MAC_CONNAC2X_RX_STATUS_IS_LLC_MIS(prRxStatus) + && !HAL_MAC_CONNAC2X_RX_STATUS_IS_ERROR(prRxStatus) + && !FEAT_SUP_LLC_VLAN_RX(prChipInfo)) { + uint16_t *pu2EtherType; + + nicRxFillRFB(prAdapter, prSwRfb); + + pu2EtherType = (uint16_t *) + ((uint8_t *)prSwRfb->pvHeader + + 2 * MAC_ADDR_LEN); + + /* If ethernet type is VLAN, do not drop it. + * Pass up to driver process + */ + if (prSwRfb->u2HeaderLen >= ETH_HLEN + && *pu2EtherType == NTOHS(ETH_P_VLAN)) + fgDrop = FALSE; + +#if CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION + /* + * let qmAmsduAttackDetection check this subframe + * before drop it + */ + if (prSwRfb->ucPayloadFormat + == RX_PAYLOAD_FORMAT_FIRST_SUB_AMSDU) { + fgDrop = FALSE; + prSwRfb->fgIsFirstSubAMSDULLCMS = TRUE; + } +#endif /* CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION */ + } + + DBGLOG(RSN, TRACE, "Sanity check to drop:%d\n", fgDrop); + } + + /* Drop plain text during security connection */ + if (prSwRfb->fgIsCipherMS && prSwRfb->fgDataFrame == TRUE) { + uint16_t *pu2EtherType; + + pu2EtherType = (uint16_t *) + ((uint8_t *)prSwRfb->pvHeader + + 2 * MAC_ADDR_LEN); + if (prSwRfb->u2HeaderLen >= ETH_HLEN + && (*pu2EtherType == NTOHS(ETH_P_1X) +#if CFG_SUPPORT_WAPI + || (*pu2EtherType == NTOHS(ETH_WPI_1X)) +#endif + )) { + fgDrop = FALSE; + DBGLOG(RSN, INFO, + "Don't drop eapol or wpi packet\n"); + } else { + fgDrop = TRUE; + DBGLOG(RSN, INFO, + "Drop plain text during security connection\n"); + } + } + +#if CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION + /* Drop fragmented broadcast and multicast frame */ + if ((prSwRfb->fgIsBC | prSwRfb->fgIsMC) + && (prSwRfb->fgFragFrame == TRUE)) { + fgDrop = TRUE; + DBGLOG(RSN, INFO, + "Drop fragmented broadcast and multicast\n"); + } + + if (HAL_MAC_CONNAC2X_RX_STATUS_IS_DAF(prRxStatus)) + DBGLOG(RSN, INFO, "De-amsdu fail, drop:%d\n", fgDrop); +#endif /* CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION */ + + return fgDrop; +} + +#if CFG_SUPPORT_WAKEUP_REASON_DEBUG +void nic_rxd_v2_check_wakeup_reason( + struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb) +{ + struct mt66xx_chip_info *prChipInfo; + struct WIFI_EVENT *prEvent; + uint8_t *pvHeader = NULL; + struct HW_MAC_CONNAC2X_RX_DESC *prRxStatus; + uint16_t u2PktLen = 0; + uint32_t u4HeaderOffset; + u_int8_t fgDrop = FALSE; + + prChipInfo = prAdapter->chip_info; + + prRxStatus = (struct HW_MAC_CONNAC2X_RX_DESC *) prSwRfb->prRxStatus; + if (!prRxStatus) + return; + + fgDrop = nic_rxd_v2_sanity_check(prAdapter, prSwRfb); + if (fgDrop) { + DBGLOG(RX, WARN, + "%s: sanity check failed. drop!\n", __func__); + return; + } + + prSwRfb->ucGroupVLD = + (uint8_t) HAL_MAC_CONNAC2X_RX_STATUS_GET_GROUP_VLD(prRxStatus); + + switch (prSwRfb->ucPacketType) { + case RX_PKT_TYPE_SW_DEFINED: + if (prSwRfb->ucOFLD) { + DBGLOG(RX, INFO, "Need to treat as data frame.\n"); + /* + * In order to jump to case RX_PKT_TYPE_RX_DATA, + * DO NOT ADD break here!!! + */ + } else { + /* HIF_RX_PKT_TYPE_EVENT */ + if ((NIC_RX_GET_U2_SW_PKT_TYPE(prSwRfb->prRxStatus) & + CONNAC2X_RX_STATUS_PKT_TYPE_SW_BITMAP) == + CONNAC2X_RX_STATUS_PKT_TYPE_SW_EVENT) { + prEvent = (struct WIFI_EVENT *) + (prSwRfb->pucRecvBuff + prChipInfo->rxd_size); + DBGLOG(RX, INFO, "Event 0x%02x wakeup host\n", + prEvent->ucEID); + break; + } else if ((NIC_RX_GET_U2_SW_PKT_TYPE(prSwRfb->prRxStatus) & + CONNAC2X_RX_STATUS_PKT_TYPE_SW_BITMAP) == + CONNAC2X_RX_STATUS_PKT_TYPE_SW_FRAME) { + /* case HIF_RX_PKT_TYPE_MANAGEMENT: */ + uint8_t ucSubtype; + struct WLAN_MAC_MGMT_HEADER *prWlanMgmtHeader; + uint16_t u2Temp = prChipInfo->rxd_size; + + u2PktLen = + HAL_MAC_CONNAC2X_RX_STATUS_GET_RX_BYTE_CNT( + prRxStatus); + + u4HeaderOffset = (uint32_t) + HAL_MAC_CONNAC2X_RX_STATUS_GET_HEADER_OFFSET( + prRxStatus); + if (prSwRfb->ucGroupVLD & BIT(RX_GROUP_VLD_4)) + u2Temp += sizeof(struct HW_MAC_RX_STS_GROUP_4); + if (prSwRfb->ucGroupVLD & BIT(RX_GROUP_VLD_1)) + u2Temp += sizeof(struct HW_MAC_RX_STS_GROUP_1); + if (prSwRfb->ucGroupVLD & BIT(RX_GROUP_VLD_2)) + u2Temp += sizeof(struct HW_MAC_RX_STS_GROUP_2); + if (prSwRfb->ucGroupVLD & BIT(RX_GROUP_VLD_3)) + u2Temp += + sizeof(struct HW_MAC_RX_STS_GROUP_3_V2); + pvHeader = (uint8_t *) + prRxStatus + u2Temp + u4HeaderOffset; + u2PktLen -= u2Temp + u4HeaderOffset; + if (!pvHeader) { + DBGLOG(RX, ERROR, + "Frame but pvHeader is NULL!\n"); + break; + } + prWlanMgmtHeader = + (struct WLAN_MAC_MGMT_HEADER *)pvHeader; + ucSubtype = (prWlanMgmtHeader->u2FrameCtrl & + MASK_FC_SUBTYPE) >> OFFSET_OF_FC_SUBTYPE; + DBGLOG(RX, INFO, + "frame subtype: %d", + ucSubtype); + DBGLOG(RX, INFO, + " SeqCtrl %d wakeup host\n", + prWlanMgmtHeader->u2SeqCtrl); + DBGLOG_MEM8(RX, INFO, + pvHeader, u2PktLen > 50 ? 50:u2PktLen); + } else { + DBGLOG(RX, ERROR, + "[%s]: u2PktTYpe(0x%04X) is OUT OF DEF.!!!\n", + __func__, + NIC_RX_GET_U2_SW_PKT_TYPE(prSwRfb->prRxStatus)); + ASSERT(0); + } + break; + } + case RX_PKT_TYPE_RX_DATA: + { + uint16_t u2Temp = 0; + + u2PktLen = + HAL_MAC_CONNAC2X_RX_STATUS_GET_RX_BYTE_CNT(prRxStatus); + u4HeaderOffset = (uint32_t) + HAL_MAC_CONNAC2X_RX_STATUS_GET_HEADER_OFFSET( + prRxStatus); + u2Temp = prChipInfo->rxd_size; + if (prSwRfb->ucGroupVLD & BIT(RX_GROUP_VLD_4)) + u2Temp += sizeof(struct HW_MAC_RX_STS_GROUP_4); + if (prSwRfb->ucGroupVLD & BIT(RX_GROUP_VLD_1)) + u2Temp += sizeof(struct HW_MAC_RX_STS_GROUP_1); + if (prSwRfb->ucGroupVLD & BIT(RX_GROUP_VLD_2)) + u2Temp += sizeof(struct HW_MAC_RX_STS_GROUP_2); + if (prSwRfb->ucGroupVLD & BIT(RX_GROUP_VLD_3)) + u2Temp += sizeof(struct HW_MAC_RX_STS_GROUP_3_V2); + pvHeader = (uint8_t *)prRxStatus + u2Temp + u4HeaderOffset; + u2PktLen -= u2Temp + u4HeaderOffset; + if (!pvHeader) { + DBGLOG(RX, ERROR, + "data packet but pvHeader is NULL!\n"); + break; + } + if (HAL_MAC_CONNAC2X_RX_STATUS_IS_NDATA(prRxStatus)) { + struct WLAN_MAC_HEADER *prWlanMacHeader = + (struct WLAN_MAC_HEADER *)pvHeader; + + if ((prWlanMacHeader->u2FrameCtrl & MASK_FRAME_TYPE) == + MAC_FRAME_BLOCK_ACK_REQ) { + DBGLOG(RX, INFO, + "BAR frame[SSN:%d,TID:%d] wakeup host\n" + , prSwRfb->u2SSN, prSwRfb->ucTid); + break; + } + } + u2Temp = (pvHeader[ETH_TYPE_LEN_OFFSET] << 8) | + (pvHeader[ETH_TYPE_LEN_OFFSET + 1]); + + switch (u2Temp) { + case ETH_P_IPV4: + u2Temp = *(uint16_t *) &pvHeader[ETH_HLEN + 4]; + DBGLOG(RX, INFO, + "IP Packet from:%d.%d.%d.%d,\n", + pvHeader[ETH_HLEN + 12], + pvHeader[ETH_HLEN + 13], + pvHeader[ETH_HLEN + 14], + pvHeader[ETH_HLEN + 15]); + DBGLOG(RX, INFO, + " IP ID 0x%04x wakeup host\n", + u2Temp); + break; + case ETH_P_ARP: + break; + case ETH_P_1X: + case ETH_P_PRE_1X: +#if CFG_SUPPORT_WAPI + case ETH_WPI_1X: +#endif + case ETH_P_AARP: + case ETH_P_IPV6: + case ETH_P_IPX: + case 0x8100: /* VLAN */ + case 0x890d: /* TDLS */ + DBGLOG(RX, INFO, + "Data Packet, EthType 0x%04x wakeup host\n", + u2Temp); + break; + default: + DBGLOG(RX, WARN, + "abnormal packet, EthType 0x%04x wakeup host\n", + u2Temp); + DBGLOG_MEM8(RX, INFO, + pvHeader, u2PktLen > 50 ? 50:u2PktLen); + break; + } + break; + } + + default: + DBGLOG(RX, WARN, "Unknown Packet %d wakeup host\n", + prSwRfb->ucPacketType); + break; + } +} +#endif /* CFG_SUPPORT_WAKEUP_REASON_DEBUG */ +#endif /* CFG_SUPPORT_CONNAC2X == 1 */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/nic_tx.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/nic_tx.c new file mode 100644 index 0000000000000000000000000000000000000000..c763f2d98472aa814598077b810831422b554aaf --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/nic_tx.c @@ -0,0 +1,5426 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic_tx.c#2 + */ + +/*! \file nic_tx.c + * \brief Functions that provide TX operation in NIC Layer. + * + * This file provides TX functions which are responsible for both Hardware + * and Software Resource Management and keep their Synchronization. + */ + + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" +#include "que_mgt.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +PFN_TX_DATA_DONE_CB g_pfTxDataDoneCb = nicTxMsduDoneCb; + +static const struct TX_RESOURCE_CONTROL + arTcResourceControl[TC_NUM] = { + /* dest port index, dest queue index, HIF TX queue index */ + /* First HW queue */ + {PORT_INDEX_LMAC, MAC_TXQ_AC0_INDEX, HIF_TX_AC0_INDEX}, + {PORT_INDEX_LMAC, MAC_TXQ_AC1_INDEX, HIF_TX_AC1_INDEX}, + {PORT_INDEX_LMAC, MAC_TXQ_AC2_INDEX, HIF_TX_AC2_INDEX}, + {PORT_INDEX_LMAC, MAC_TXQ_AC3_INDEX, HIF_TX_AC3_INDEX}, + {PORT_INDEX_MCU, MCU_Q1_INDEX, HIF_TX_CPU_INDEX}, + + /* Second HW queue */ +#if NIC_TX_ENABLE_SECOND_HW_QUEUE + {PORT_INDEX_LMAC, MAC_TXQ_AC10_INDEX, HIF_TX_AC10_INDEX}, + {PORT_INDEX_LMAC, MAC_TXQ_AC11_INDEX, HIF_TX_AC11_INDEX}, + {PORT_INDEX_LMAC, MAC_TXQ_AC12_INDEX, HIF_TX_AC12_INDEX}, + {PORT_INDEX_LMAC, MAC_TXQ_AC13_INDEX, HIF_TX_AC13_INDEX}, + {PORT_INDEX_LMAC, MAC_TXQ_AC11_INDEX, HIF_TX_AC11_INDEX}, +#endif +}; + +/* Traffic settings per TC */ +static const struct TX_TC_TRAFFIC_SETTING + arTcTrafficSettings[NET_TC_NUM] = { + /* Tx desc template format, Remaining Tx time, + * Retry count + */ + /* For Data frame with StaRec, + * set Long Format to enable the following settings + */ + { + NIC_TX_DESC_LONG_FORMAT_LENGTH, NIC_TX_AC_BE_REMAINING_TX_TIME, + NIC_TX_DATA_DEFAULT_RETRY_COUNT_LIMIT + }, + { + NIC_TX_DESC_LONG_FORMAT_LENGTH, NIC_TX_AC_BK_REMAINING_TX_TIME, + NIC_TX_DATA_DEFAULT_RETRY_COUNT_LIMIT + }, + { + NIC_TX_DESC_LONG_FORMAT_LENGTH, NIC_TX_AC_VI_REMAINING_TX_TIME, + NIC_TX_DATA_DEFAULT_RETRY_COUNT_LIMIT + }, + { + NIC_TX_DESC_LONG_FORMAT_LENGTH, NIC_TX_AC_VO_REMAINING_TX_TIME, + NIC_TX_DATA_DEFAULT_RETRY_COUNT_LIMIT + }, + + /* MGMT frame */ + { + NIC_TX_DESC_LONG_FORMAT_LENGTH, NIC_TX_MGMT_REMAINING_TX_TIME, + NIC_TX_MGMT_DEFAULT_RETRY_COUNT_LIMIT + }, + + /* non-StaRec frame (BMC, etc...) */ + { + NIC_TX_DESC_LONG_FORMAT_LENGTH, TX_DESC_TX_TIME_NO_LIMIT, + NIC_TX_DATA_DEFAULT_RETRY_COUNT_LIMIT + }, +}; + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +static uint8_t *apucTxResultStr[TX_RESULT_NUM] = { + (uint8_t *) DISP_STRING("SUCCESS"), /* success */ + (uint8_t *) DISP_STRING("LIFE_TO"), /* life timeout */ + (uint8_t *) DISP_STRING("RTS_ER"), /* RTS error */ + (uint8_t *) DISP_STRING("MPDU_ER"), /* MPDU error */ + (uint8_t *) DISP_STRING("AGE_TO"), /* aging timeout */ + (uint8_t *) DISP_STRING("FLUSHED"), /* flushed */ + (uint8_t *) DISP_STRING("BIP_ER"), /* BIP error */ + (uint8_t *) DISP_STRING("UNSPEC_ER"), /* unspecified error */ + (uint8_t *) NULL, + (uint8_t *) NULL, + (uint8_t *) NULL, + (uint8_t *) NULL, + (uint8_t *) NULL, + (uint8_t *) NULL, + (uint8_t *) NULL, + (uint8_t *) NULL, + (uint8_t *) NULL, + (uint8_t *) NULL, + (uint8_t *) NULL, + (uint8_t *) NULL, + (uint8_t *) NULL, + (uint8_t *) NULL, + (uint8_t *) NULL, + (uint8_t *) NULL, + (uint8_t *) NULL, + (uint8_t *) NULL, + (uint8_t *) NULL, + (uint8_t *) NULL, + (uint8_t *) NULL, + (uint8_t *) NULL, + (uint8_t *) NULL, + (uint8_t *) NULL, + (uint8_t *) DISP_STRING("DP_IN_DRV"), /* drop in driver */ + (uint8_t *) DISP_STRING("DP_IN_FW"), /* drop in FW */ + (uint8_t *) DISP_STRING("QUE_CLR"), /* queue clearance */ + (uint8_t *) DISP_STRING("INACT_BSS") /* inactive BSS */ +}; + +static uint8_t *apucBandwidt[4] = { + (uint8_t *)"20", (uint8_t *)"40", + (uint8_t *)"80", (uint8_t *)"160/80+80" +}; + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will initial all variables in regard to SW TX Queues and + * all free lists of MSDU_INFO_T and SW_TFCB_T. + * + * @param prAdapter Pointer to the Adapter structure. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void nicTxInitialize(IN struct ADAPTER *prAdapter) +{ + struct TX_CTRL *prTxCtrl; + uint8_t *pucMemHandle; + struct MSDU_INFO *prMsduInfo; + uint32_t i; + + KAL_SPIN_LOCK_DECLARATION(); + + DEBUGFUNC("nicTxInitialize"); + + ASSERT(prAdapter); + prTxCtrl = &prAdapter->rTxCtrl; + + /* 4 <1> Initialization of Traffic Class Queue Parameters */ + nicTxResetResource(prAdapter); + + prTxCtrl->pucTxCoalescingBufPtr = + prAdapter->pucCoalescingBufCached; + + prTxCtrl->u4WrIdx = 0; + + /* allocate MSDU_INFO_T and link it into rFreeMsduInfoList */ + QUEUE_INITIALIZE(&prTxCtrl->rFreeMsduInfoList); + + pucMemHandle = prTxCtrl->pucTxCached; + for (i = 0; i < CFG_TX_MAX_PKT_NUM; i++) { + prMsduInfo = (struct MSDU_INFO *) pucMemHandle; + kalMemZero(prMsduInfo, sizeof(struct MSDU_INFO)); + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, + SPIN_LOCK_TX_MSDU_INFO_LIST); + QUEUE_INSERT_TAIL(&prTxCtrl->rFreeMsduInfoList, + (struct QUE_ENTRY *) prMsduInfo); + KAL_RELEASE_SPIN_LOCK(prAdapter, + SPIN_LOCK_TX_MSDU_INFO_LIST); + + pucMemHandle += ALIGN_4(sizeof(struct MSDU_INFO)); + } + + ASSERT(prTxCtrl->rFreeMsduInfoList.u4NumElem == + CFG_TX_MAX_PKT_NUM); + /* Check if the memory allocation consist + * with this initialization function + */ + ASSERT((uint32_t) (pucMemHandle - prTxCtrl->pucTxCached) == + prTxCtrl->u4TxCachedSize); + + QUEUE_INITIALIZE(&prTxCtrl->rTxMgmtTxingQueue); + prTxCtrl->i4TxMgmtPendingNum = 0; + +#if CFG_HIF_STATISTICS + prTxCtrl->u4TotalTxAccessNum = 0; + prTxCtrl->u4TotalTxPacketNum = 0; +#endif + + prTxCtrl->i4PendingFwdFrameCount = 0; + prTxCtrl->i4PendingFwdFrameWMMCount[WMM_AC_BE_INDEX] = 0; + prTxCtrl->i4PendingFwdFrameWMMCount[WMM_AC_BK_INDEX] = 0; + prTxCtrl->i4PendingFwdFrameWMMCount[WMM_AC_VI_INDEX] = 0; + prTxCtrl->i4PendingFwdFrameWMMCount[WMM_AC_VO_INDEX] = 0; + + /* Assign init value */ + /* Tx sequence number */ + prAdapter->ucTxSeqNum = 0; + /* PID pool */ + for (i = 0; i < WTBL_SIZE; i++) + prAdapter->aucPidPool[i] = NIC_TX_DESC_DRIVER_PID_MIN; + + /* enable/disable TX resource control */ + prTxCtrl->fgIsTxResourceCtrl = NIC_TX_RESOURCE_CTRL; + + prAdapter->cArpNoResponseIdx = -1; + + qmInit(prAdapter, halIsTxResourceControlEn(prAdapter)); + + TX_RESET_ALL_CNTS(prTxCtrl); + +} /* end of nicTxInitialize() */ + +u_int8_t nicTxSanityCheckResource(IN struct ADAPTER + *prAdapter) +{ + struct TX_CTRL *prTxCtrl; + uint8_t ucTC; + uint32_t ucTotalMaxResource = 0; + uint32_t ucTotalFreeResource = 0; + u_int8_t fgError = FALSE; + + if (prAdapter->rWifiVar.ucTxDbg & BIT(0)) { + prTxCtrl = &prAdapter->rTxCtrl; + + for (ucTC = TC0_INDEX; ucTC < TC_NUM; ucTC++) { + ucTotalMaxResource += + prTxCtrl->rTc.au4MaxNumOfPage[ucTC]; + ucTotalFreeResource += + prTxCtrl->rTc.au4FreePageCount[ucTC]; + + if (prTxCtrl->rTc.au4FreePageCount[ucTC] > + prTxCtrl->u4TotalPageNum) { + DBGLOG(TX, ERROR, + "%s:%u\n error\n", __func__, __LINE__); + fgError = TRUE; + } + + if (prTxCtrl->rTc.au4MaxNumOfPage[ucTC] > + prTxCtrl->u4TotalPageNum) { + DBGLOG(TX, ERROR, + "%s:%u\n error\n", __func__, __LINE__); + fgError = TRUE; + } + + if (prTxCtrl->rTc.au4FreePageCount[ucTC] > + prTxCtrl->rTc.au4MaxNumOfPage[ucTC]) { + DBGLOG(TX, ERROR, + "%s:%u\n error\n", __func__, __LINE__); + fgError = TRUE; + } + } + + if (ucTotalMaxResource != prTxCtrl->u4TotalPageNum) { + DBGLOG(TX, ERROR, + "%s:%u\n error\n", __func__, __LINE__); + fgError = TRUE; + } + + if (ucTotalMaxResource < ucTotalFreeResource) { + DBGLOG(TX, ERROR, + "%s:%u\n error\n", __func__, __LINE__); + fgError = TRUE; + } + + if (ucTotalFreeResource > prTxCtrl->u4TotalPageNum) { + DBGLOG(TX, ERROR, + "%s:%u\n error\n", __func__, __LINE__); + fgError = TRUE; + } + + if (fgError) { + DBGLOG(TX, ERROR, "Total resource[%u]\n", + prTxCtrl->u4TotalPageNum); + qmDumpQueueStatus(prAdapter, NULL, 0); + } + } + + return !fgError; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Condition check if the PLE resource control is needed or not + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] ucTC Specify the resource of TC + * + * \retval FALSE Resource control is not needed. + * \retval TRUE Resource is not needed. + */ +/*----------------------------------------------------------------------------*/ + +u_int8_t nicTxResourceIsPleCtrlNeeded(IN struct ADAPTER + *prAdapter, IN uint8_t ucTC) +{ + struct TX_CTRL *prTxCtrl; + struct TX_TCQ_STATUS *prTc; + + ASSERT(prAdapter); + + prTxCtrl = &prAdapter->rTxCtrl; + prTc = &prTxCtrl->rTc; + + /* no PLE resource control */ + if (!prTc->fgNeedPleCtrl) + return FALSE; + + /* CMD doesn't have PLE */ + if (ucTC == 4) + return FALSE; + + /* rom stage inbabd command use TC0. need refine a good method */ + if ((ucTC == 0) && (prAdapter->fgIsFwDownloaded == FALSE)) + return FALSE; + + return TRUE; +} + + +uint32_t nicTxResourceGetPleFreeCount(IN struct ADAPTER + *prAdapter, IN uint8_t ucTC) +{ + struct TX_CTRL *prTxCtrl; + struct TX_TCQ_STATUS *prTc; + + ASSERT(prAdapter); + + prTxCtrl = &prAdapter->rTxCtrl; + prTc = &prTxCtrl->rTc; + + if (!nicTxResourceIsPleCtrlNeeded(prAdapter, ucTC)) { + /* unlimited value*/ + return 0xFFFFFFFF; + } + + return prTc->au4FreePageCount_PLE[ucTC]; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Driver maintain a variable that is synchronous with the usage of + * individual TC Buffer Count. This function will check if has enough + * TC Buffer for incoming packet and then update the value after + * promise to provide the resources. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] ucTC Specify the resource of TC + * + * \retval WLAN_STATUS_SUCCESS Resource is available and been assigned. + * \retval WLAN_STATUS_RESOURCES Resource is not available. + */ +/*----------------------------------------------------------------------------*/ + +uint32_t nicTxAcquireResourcePLE(IN struct ADAPTER + *prAdapter, IN uint8_t ucTC) +{ + struct TX_CTRL *prTxCtrl; + struct TX_TCQ_STATUS *prTc; + + ASSERT(prAdapter); + + prTxCtrl = &prAdapter->rTxCtrl; + prTc = &prTxCtrl->rTc; + + if (ucTC >= TC_NUM) + return WLAN_STATUS_FAILURE; + + if (!nicTxResourceIsPleCtrlNeeded(prAdapter, ucTC)) + return WLAN_STATUS_SUCCESS; + + DBGLOG(INIT, INFO, + "Acquire PLE: TC%d AcquirePageCnt[%u] FreeBufferCnt[%u] FreePageCnt[%u]\n", + ucTC, NIX_TX_PLE_PAGE_CNT_PER_FRAME, + prTc->au4FreeBufferCount_PLE[ucTC], + prTc->au4FreePageCount_PLE[ucTC]); + + + /* PLE Acquire */ + if (prTc->au4FreePageCount_PLE[ucTC] >= + NIX_TX_PLE_PAGE_CNT_PER_FRAME) { + prTc->au4FreePageCount_PLE[ucTC] -= + NIX_TX_PLE_PAGE_CNT_PER_FRAME; + + return WLAN_STATUS_SUCCESS; + } + + DBGLOG(INIT, ERROR, + "Acquire PLE FAILURE. TC%d AcquirePageCnt[%u] FreeBufferCnt[%u] FreePageCnt[%u]\n", + ucTC, NIX_TX_PLE_PAGE_CNT_PER_FRAME, + prTc->au4FreeBufferCount_PLE[ucTC], + prTc->au4FreePageCount_PLE[ucTC]); + + + return WLAN_STATUS_RESOURCES; +} + + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Driver maintain a variable that is synchronous with the usage of + * individual TC Buffer Count. This function will check if has enough + * TC Buffer for incoming packet and then update the value after + * promise to provide the resources. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * \param[in] ucTC Specify the resource of TC + * + * \retval WLAN_STATUS_SUCCESS Resource is available and been assigned. + * \retval WLAN_STATUS_RESOURCES Resource is not available. + */ +/*----------------------------------------------------------------------------*/ +uint32_t u4CurrTick; +uint32_t nicTxAcquireResource(IN struct ADAPTER *prAdapter, + IN uint8_t ucTC, IN uint32_t u4PageCount, + IN u_int8_t fgReqLock) +{ +#define TC4_NO_RESOURCE_DELAY_MS 5 /* exponential of 5s */ + + struct TX_CTRL *prTxCtrl; + struct TX_TCQ_STATUS *prTc; + uint32_t u4Status = WLAN_STATUS_RESOURCES; + uint32_t u4MaxPageCntPerFrame = + prAdapter->rTxCtrl.u4MaxPageCntPerFrame; + struct QUE_MGT *prQM; + + KAL_SPIN_LOCK_DECLARATION(); + + /* enable/disable TX resource control */ + if (!prAdapter->rTxCtrl.fgIsTxResourceCtrl || ucTC >= TC_NUM) + return WLAN_STATUS_SUCCESS; + + ASSERT(prAdapter); + prTxCtrl = &prAdapter->rTxCtrl; + prTc = &prTxCtrl->rTc; + + if (fgReqLock) + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); +#if 1 + prQM = &prAdapter->rQM; + if (prTc->au4FreePageCount[ucTC] >= u4PageCount) { + + if (nicTxAcquireResourcePLE(prAdapter, + ucTC) != WLAN_STATUS_SUCCESS) { + if (fgReqLock) + KAL_RELEASE_SPIN_LOCK(prAdapter, + SPIN_LOCK_TX_RESOURCE); + + return WLAN_STATUS_RESOURCES; + } + + /* This update must be AFTER the PLE-resource-check */ + if (ucTC == TC4_INDEX) + u4CurrTick = 0; + prTc->au4FreePageCount[ucTC] -= u4PageCount; + prTc->au4FreeBufferCount[ucTC] = + (prTc->au4FreePageCount[ucTC] / u4MaxPageCntPerFrame); + prQM->au4QmTcUsedPageCounter[ucTC] += u4PageCount; + + DBGLOG(TX, LOUD, + "Acquire: TC%d AcquirePageCnt[%u] FreeBufferCnt[%u] FreePageCnt[%u]\n", + ucTC, u4PageCount, prTc->au4FreeBufferCount[ucTC], + prTc->au4FreePageCount[ucTC]); + + u4Status = WLAN_STATUS_SUCCESS; + } +#else + if (prTxCtrl->rTc.au4FreePageCount[ucTC] > 0) { + + prTxCtrl->rTc.au4FreePageCount[ucTC] -= 1; + + u4Status = WLAN_STATUS_SUCCESS; + } +#endif + if (fgReqLock) + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); + + if (ucTC == TC4_INDEX) { + if (u4CurrTick == 0) + u4CurrTick = kalGetTimeTick(); + if (CHECK_FOR_TIMEOUT(kalGetTimeTick(), u4CurrTick, + SEC_TO_SYSTIME(TC4_NO_RESOURCE_DELAY_MS))) { +#if (CFG_SUPPORT_TRACE_TC4 == 1) + wlanDumpTcResAndTxedCmd(NULL, 0); +#endif + cmdBufDumpCmdQueue(&prAdapter->rPendingCmdQueue, + "waiting response CMD queue"); + } + } + + return u4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Driver maintain a variable that is synchronous with the usage of + * individual TC Buffer Count. This function will do polling if FW has + * return the resource. + * Used when driver start up before enable interrupt. + * + * @param prAdapter Pointer to the Adapter structure. + * @param ucTC Specify the resource of TC + * + * @retval WLAN_STATUS_SUCCESS Resource is available. + * @retval WLAN_STATUS_FAILURE Resource is not available. + */ +/*----------------------------------------------------------------------------*/ +uint32_t nicTxPollingResource(IN struct ADAPTER *prAdapter, + IN uint8_t ucTC) +{ + struct TX_CTRL *prTxCtrl; + uint32_t u4Status = WLAN_STATUS_FAILURE; + int32_t i = NIC_TX_RESOURCE_POLLING_TIMEOUT; + /*UINT_32 au4WTSR[8];*/ + + ASSERT(prAdapter); + prTxCtrl = &prAdapter->rTxCtrl; + + if (ucTC >= TC_NUM) + return WLAN_STATUS_FAILURE; + + if (prTxCtrl->rTc.au4FreeBufferCount[ucTC] > 0) + return WLAN_STATUS_SUCCESS; + + while (i-- > 0) { +#if 1 + u4Status = halTxPollingResource(prAdapter, ucTC); + if (u4Status == WLAN_STATUS_RESOURCES) + kalMsleep(NIC_TX_RESOURCE_POLLING_DELAY_MSEC); + else + break; +#else + HAL_READ_TX_RELEASED_COUNT(prAdapter, au4WTSR); + + if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE + || fgIsBusAccessFailed == TRUE) { + u4Status = WLAN_STATUS_FAILURE; + break; + } else if (halTxReleaseResource(prAdapter, + (uint16_t *) au4WTSR)) { + if (prTxCtrl->rTc.au4FreeBufferCount[ucTC] > 0) { + u4Status = WLAN_STATUS_SUCCESS; + break; + } + kalMsleep(NIC_TX_RESOURCE_POLLING_DELAY_MSEC); + } else { + kalMsleep(NIC_TX_RESOURCE_POLLING_DELAY_MSEC); + } +#endif + } + +#if DBG + { + int32_t i4Times = NIC_TX_RESOURCE_POLLING_TIMEOUT - (i + 1); + + if (i4Times) { + DBGLOG(TX, TRACE, + "Polling MCR_WTSR delay %ld times, %ld msec\n", + i4Times, + (i4Times * NIC_TX_RESOURCE_POLLING_DELAY_MSEC)); + } + } +#endif /* DBG */ + + return u4Status; + +} /* end of nicTxPollingResource() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Driver maintain a variable that is synchronous with the usage of + * individual TC Buffer Count. This function will release TC Buffer + * count according to the given TX_STATUS COUNTER after TX Done. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +u_int8_t nicTxReleaseResource(IN struct ADAPTER *prAdapter, + IN uint8_t ucTc, IN uint32_t u4PageCount, + IN u_int8_t fgReqLock, IN u_int8_t fgPLE) +{ + struct TX_TCQ_STATUS *prTcqStatus; + u_int8_t bStatus = FALSE; + uint32_t u4MaxPageCntPerFrame = + prAdapter->rTxCtrl.u4MaxPageCntPerFrame; + struct QUE_MGT *prQM = NULL; + + KAL_SPIN_LOCK_DECLARATION(); + + ASSERT(prAdapter); + /* enable/disable TX resource control */ + if (!prAdapter->rTxCtrl.fgIsTxResourceCtrl || ucTc >= TC_NUM) + return TRUE; + + /* No need to do PLE resource control */ + if (fgPLE && !nicTxResourceIsPleCtrlNeeded(prAdapter, ucTc)) + return TRUE; + + prTcqStatus = &prAdapter->rTxCtrl.rTc; + prQM = &prAdapter->rQM; + + /* Return free Tc page count */ + if (fgReqLock) + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); + + if (fgPLE) { + prTcqStatus->au4FreePageCount_PLE[ucTc] += u4PageCount; + prTcqStatus->au4FreeBufferCount_PLE[ucTc] = + (prTcqStatus->au4FreePageCount_PLE[ucTc] / + NIX_TX_PLE_PAGE_CNT_PER_FRAME); + } else { + prTcqStatus->au4FreePageCount[ucTc] += u4PageCount; + prTcqStatus->au4FreeBufferCount[ucTc] = + (prTcqStatus->au4FreePageCount[ucTc] / + u4MaxPageCntPerFrame); + } + prQM->au4QmTcResourceBackCounter[ucTc] += u4PageCount; + + if (fgReqLock) + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); + +#if (CFG_SUPPORT_TRACE_TC4 == 1) + if (ucTc == TC4_INDEX) + wlanTraceReleaseTcRes(prAdapter, u4PageCount, + prTcqStatus->au4FreePageCount[ucTc]); +#endif + bStatus = TRUE; + + return bStatus; +} /* end of nicTxReleaseResource() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Driver maintain a variable that is synchronous with the usage of + * individual TC Buffer Count. This function will release TC Buffer + * count for resource allocated but un-Tx MSDU_INFO + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void nicTxReleaseMsduResource(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfoListHead) +{ + struct MSDU_INFO *prMsduInfo = prMsduInfoListHead, + *prNextMsduInfo; + + KAL_SPIN_LOCK_DECLARATION(); + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); + + while (prMsduInfo) { + prNextMsduInfo = (struct MSDU_INFO *) QUEUE_GET_NEXT_ENTRY(( + struct QUE_ENTRY *) prMsduInfo); + + nicTxReleaseResource_PSE(prAdapter, prMsduInfo->ucTC, + nicTxGetPageCount( + prAdapter, prMsduInfo->u2FrameLength, + FALSE), FALSE); + + nicTxReleaseResource_PLE(prAdapter, prMsduInfo->ucTC, + NIX_TX_PLE_PAGE_CNT_PER_FRAME, FALSE); + + prMsduInfo = prNextMsduInfo; + }; + + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Reset TC Buffer Count to initialized value + * + * \param[in] prAdapter Pointer to the Adapter structure. + * + * @return WLAN_STATUS_SUCCESS + */ +/*----------------------------------------------------------------------------*/ +uint32_t nicTxResetResource(IN struct ADAPTER *prAdapter) +{ + struct TX_CTRL *prTxCtrl; + uint8_t ucIdx; + + KAL_SPIN_LOCK_DECLARATION(); + + DEBUGFUNC("nicTxResetResource"); + + ASSERT(prAdapter); + prTxCtrl = &prAdapter->rTxCtrl; + + /* Following two lines MUST be in order. */ + prTxCtrl->u4PageSize = halGetHifTxPageSize(prAdapter); + prTxCtrl->u4MaxPageCntPerFrame = nicTxGetMaxPageCntPerFrame( + prAdapter); + + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); + + /* Delta page count */ + kalMemZero(prTxCtrl->rTc.au4TxDonePageCount, + sizeof(prTxCtrl->rTc.au4TxDonePageCount)); + kalMemZero(prTxCtrl->rTc.au4PreUsedPageCount, + sizeof(prTxCtrl->rTc.au4PreUsedPageCount)); + + prTxCtrl->rTc.ucNextTcIdx = TC0_INDEX; + prTxCtrl->rTc.u4AvaliablePageCount = 0; + + DBGLOG(TX, TRACE, + "Default TCQ free resource [%u %u %u %u %u]\n", + prAdapter->rWifiVar.au4TcPageCount[TC0_INDEX], + prAdapter->rWifiVar.au4TcPageCount[TC1_INDEX], + prAdapter->rWifiVar.au4TcPageCount[TC2_INDEX], + prAdapter->rWifiVar.au4TcPageCount[TC3_INDEX], + prAdapter->rWifiVar.au4TcPageCount[TC4_INDEX]); + + /* Reset counter: PSE */ + prAdapter->rTxCtrl.u4TotalPageNum = 0; + prAdapter->rTxCtrl.u4TotalTxRsvPageNum = 0; + /* Reset counter: PLE */ + prAdapter->rTxCtrl.u4TotalPageNumPle = 0; + + /* Assign resource for each TC according to prAdapter->rWifiVar */ + for (ucIdx = TC0_INDEX; ucIdx < TC_NUM; ucIdx++) { + + /* + * PSE + */ + + /* Page Count */ + prTxCtrl->rTc.au4MaxNumOfPage[ucIdx] = + prAdapter->rWifiVar.au4TcPageCount[ucIdx]; + prTxCtrl->rTc.au4FreePageCount[ucIdx] = + prAdapter->rWifiVar.au4TcPageCount[ucIdx]; + + DBGLOG(TX, TRACE, "Set TC%u Default[%u] Max[%u] Free[%u]\n", + ucIdx, + prAdapter->rWifiVar.au4TcPageCount[ucIdx], + prTxCtrl->rTc.au4MaxNumOfPage[ucIdx], + prTxCtrl->rTc.au4FreePageCount[ucIdx]); + + /* Buffer count */ + prTxCtrl->rTc.au4MaxNumOfBuffer[ucIdx] = + (prTxCtrl->rTc.au4MaxNumOfPage[ucIdx] / + (prTxCtrl->u4MaxPageCntPerFrame)); + + prTxCtrl->rTc.au4FreeBufferCount[ucIdx] = + (prTxCtrl->rTc.au4FreePageCount[ucIdx] / + (prTxCtrl->u4MaxPageCntPerFrame)); + + + DBGLOG(TX, TRACE, + "Set TC%u Default[%u] Buffer Max[%u] Free[%u]\n", + ucIdx, + prAdapter->rWifiVar.au4TcPageCount[ucIdx], + prTxCtrl->rTc.au4MaxNumOfBuffer[ucIdx], + prTxCtrl->rTc.au4FreeBufferCount[ucIdx]); + + prAdapter->rTxCtrl.u4TotalPageNum += + prTxCtrl->rTc.au4MaxNumOfPage[ucIdx]; + + + /* + * PLE + */ + if (prAdapter->rTxCtrl.rTc.fgNeedPleCtrl) { + /* Page Count */ + prTxCtrl->rTc.au4MaxNumOfPage_PLE[ucIdx] = + prAdapter->rWifiVar.au4TcPageCountPle[ucIdx]; + prTxCtrl->rTc.au4FreePageCount_PLE[ucIdx] = + prAdapter->rWifiVar.au4TcPageCountPle[ucIdx]; + + DBGLOG(TX, TRACE, + "[PLE]Set TC%u Default[%u] Max[%u] Free[%u]\n", + ucIdx, + prAdapter->rWifiVar.au4TcPageCountPle[ucIdx], + prTxCtrl->rTc.au4MaxNumOfPage_PLE[ucIdx], + prTxCtrl->rTc.au4FreePageCount_PLE[ucIdx]); + + /* Buffer count */ + prTxCtrl->rTc.au4MaxNumOfBuffer_PLE[ucIdx] = + (prTxCtrl->rTc.au4MaxNumOfPage_PLE[ucIdx] / + NIX_TX_PLE_PAGE_CNT_PER_FRAME); + + prTxCtrl->rTc.au4FreeBufferCount_PLE[ucIdx] = + (prTxCtrl->rTc.au4FreePageCount_PLE[ucIdx] / + NIX_TX_PLE_PAGE_CNT_PER_FRAME); + + + DBGLOG(TX, TRACE, + "[PLE]Set TC%u Default[%u] Buffer Max[%u] Free[%u]\n", + ucIdx, + prAdapter->rWifiVar.au4TcPageCountPle[ucIdx], + prTxCtrl->rTc.au4MaxNumOfBuffer_PLE[ucIdx], + prTxCtrl->rTc.au4FreeBufferCount_PLE[ucIdx]); + + prAdapter->rTxCtrl.u4TotalPageNumPle += + prTxCtrl->rTc.au4MaxNumOfPage_PLE[ucIdx]; + } + } + + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); + + if (!prAdapter->fgIsNicTxReousrceValid)/* use default value */ + prAdapter->nicTxReousrce.ucPpTxAddCnt = + NIC_TX_LEN_ADDING_LENGTH; + DBGLOG(TX, TRACE, + "Reset TCQ free resource to Page <>:Buf [%u:%u %u:%u %u:%u %u:%u %u:%u]\n", + prTxCtrl->rTc.au4FreePageCount[TC0_INDEX], + prTxCtrl->rTc.au4FreeBufferCount[TC0_INDEX], + prTxCtrl->rTc.au4FreePageCount[TC1_INDEX], + prTxCtrl->rTc.au4FreeBufferCount[TC1_INDEX], + prTxCtrl->rTc.au4FreePageCount[TC2_INDEX], + prTxCtrl->rTc.au4FreeBufferCount[TC2_INDEX], + prTxCtrl->rTc.au4FreePageCount[TC3_INDEX], + prTxCtrl->rTc.au4FreeBufferCount[TC3_INDEX], + prTxCtrl->rTc.au4FreePageCount[TC4_INDEX], + prTxCtrl->rTc.au4FreeBufferCount[TC4_INDEX]); + + if (prAdapter->rTxCtrl.rTc.fgNeedPleCtrl) + DBGLOG(TX, TRACE, + "Reset TCQ free resource to Page <>:Buf [%u:%u %u:%u %u:%u %u:%u %u:%u]\n", + prTxCtrl->rTc.au4FreePageCount_PLE[TC0_INDEX], + prTxCtrl->rTc.au4FreeBufferCount_PLE[TC0_INDEX], + prTxCtrl->rTc.au4FreePageCount_PLE[TC1_INDEX], + prTxCtrl->rTc.au4FreeBufferCount_PLE[TC1_INDEX], + prTxCtrl->rTc.au4FreePageCount_PLE[TC2_INDEX], + prTxCtrl->rTc.au4FreeBufferCount_PLE[TC2_INDEX], + prTxCtrl->rTc.au4FreePageCount_PLE[TC3_INDEX], + prTxCtrl->rTc.au4FreeBufferCount_PLE[TC3_INDEX], + prTxCtrl->rTc.au4FreePageCount_PLE[TC4_INDEX], + prTxCtrl->rTc.au4FreeBufferCount_PLE[TC4_INDEX]); + + + DBGLOG(TX, TRACE, + "Reset TCQ MAX resource to Page <>:Buf [%u:%u %u:%u %u:%u %u:%u %u:%u]\n", + prTxCtrl->rTc.au4MaxNumOfPage[TC0_INDEX], + prTxCtrl->rTc.au4MaxNumOfBuffer[TC0_INDEX], + prTxCtrl->rTc.au4MaxNumOfPage[TC1_INDEX], + prTxCtrl->rTc.au4MaxNumOfBuffer[TC1_INDEX], + prTxCtrl->rTc.au4MaxNumOfPage[TC2_INDEX], + prTxCtrl->rTc.au4MaxNumOfBuffer[TC2_INDEX], + prTxCtrl->rTc.au4MaxNumOfPage[TC3_INDEX], + prTxCtrl->rTc.au4MaxNumOfBuffer[TC3_INDEX], + prTxCtrl->rTc.au4MaxNumOfPage[TC4_INDEX], + prTxCtrl->rTc.au4MaxNumOfBuffer[TC4_INDEX]); + + if (prAdapter->rTxCtrl.rTc.fgNeedPleCtrl) + DBGLOG(TX, TRACE, + "Reset TCQ MAX resource to Page <>:Buf [%u:%u %u:%u %u:%u %u:%u %u:%u]\n", + prTxCtrl->rTc.au4MaxNumOfPage_PLE[TC0_INDEX], + prTxCtrl->rTc.au4MaxNumOfBuffer_PLE[TC0_INDEX], + prTxCtrl->rTc.au4MaxNumOfPage_PLE[TC1_INDEX], + prTxCtrl->rTc.au4MaxNumOfBuffer_PLE[TC1_INDEX], + prTxCtrl->rTc.au4MaxNumOfPage_PLE[TC2_INDEX], + prTxCtrl->rTc.au4MaxNumOfBuffer_PLE[TC2_INDEX], + prTxCtrl->rTc.au4MaxNumOfPage_PLE[TC3_INDEX], + prTxCtrl->rTc.au4MaxNumOfBuffer_PLE[TC3_INDEX], + prTxCtrl->rTc.au4MaxNumOfPage_PLE[TC4_INDEX], + prTxCtrl->rTc.au4MaxNumOfBuffer_PLE[TC4_INDEX]); + + return WLAN_STATUS_SUCCESS; +} + +#if QM_FAST_TC_RESOURCE_CTRL +uint32_t +nicTxGetAdjustableResourceCnt(IN struct ADAPTER *prAdapter) +{ + struct TX_CTRL *prTxCtrl; + uint8_t ucIdx; + uint32_t u4TotAdjCnt = 0; + uint32_t u4AdjCnt; + struct QUE_MGT *prQM = NULL; + + prQM = &prAdapter->rQM; + prTxCtrl = &prAdapter->rTxCtrl; + + for (ucIdx = TC0_INDEX; ucIdx < TC_NUM; ucIdx++) { + if (ucIdx == TC4_INDEX) + continue; + + if (prTxCtrl->rTc.au4FreeBufferCount[ucIdx] > + prQM->au4MinReservedTcResource[ucIdx]) + u4AdjCnt = prTxCtrl->rTc.au4FreeBufferCount[ucIdx] - + prQM->au4MinReservedTcResource[ucIdx]; + else + u4AdjCnt = 0; + + u4TotAdjCnt += u4AdjCnt; + } + + /* no PLE resource control */ + if (!prAdapter->rTxCtrl.rTc.fgNeedPleCtrl) + return u4TotAdjCnt; + + /* PLE part */ + for (ucIdx = TC0_INDEX; ucIdx < TC_NUM; ucIdx++) { + if (ucIdx == TC4_INDEX) + continue; + + if (prTxCtrl->rTc.au4FreeBufferCount_PLE[ucIdx] > + prQM->au4MinReservedTcResource[ucIdx]) + u4AdjCnt = prTxCtrl->rTc.au4FreeBufferCount_PLE[ucIdx] - + prQM->au4MinReservedTcResource[ucIdx]; + else + u4AdjCnt = 0; + + u4TotAdjCnt += u4AdjCnt; + } + + return u4TotAdjCnt; +} +#endif +/*----------------------------------------------------------------------------*/ +/*! + * @brief Driver maintain a variable that is synchronous with the usage of + * individual TC Buffer Count. This function will return the value for + * other component which needs this information for making decisions + * + * @param prAdapter Pointer to the Adapter structure. + * @param ucTC Specify the resource of TC + * + * @retval UINT_8 The number of corresponding TC number + */ +/*----------------------------------------------------------------------------*/ +uint16_t nicTxGetResource(IN struct ADAPTER *prAdapter, + IN uint8_t ucTC) +{ + struct TX_CTRL *prTxCtrl; + + ASSERT(prAdapter); + prTxCtrl = &prAdapter->rTxCtrl; + + ASSERT(prTxCtrl); + + if (ucTC >= TC_NUM) + return 0; + else + return prTxCtrl->rTc.au4FreePageCount[ucTC]; +} + +uint8_t nicTxGetFrameResourceType(IN uint8_t eFrameType, + IN struct MSDU_INFO *prMsduInfo) +{ + uint8_t ucTC; + + switch (eFrameType) { + case FRAME_TYPE_802_1X: + ucTC = TC4_INDEX; + break; + + case FRAME_TYPE_MMPDU: + if (prMsduInfo) + ucTC = prMsduInfo->ucTC; + else + ucTC = TC4_INDEX; + break; + + default: + DBGLOG(INIT, WARN, "Undefined Frame Type(%u)\n", + eFrameType); + ucTC = TC4_INDEX; + break; + } + + return ucTC; +} + +uint8_t nicTxGetCmdResourceType(IN struct CMD_INFO + *prCmdInfo) +{ + uint8_t ucTC; + + switch (prCmdInfo->eCmdType) { + case COMMAND_TYPE_NETWORK_IOCTL: + case COMMAND_TYPE_GENERAL_IOCTL: + ucTC = TC4_INDEX; + break; + + case COMMAND_TYPE_SECURITY_FRAME: + case COMMAND_TYPE_DATA_FRAME: + ucTC = nicTxGetFrameResourceType(FRAME_TYPE_802_1X, NULL); + break; + + case COMMAND_TYPE_MANAGEMENT_FRAME: + ucTC = nicTxGetFrameResourceType(FRAME_TYPE_MMPDU, + prCmdInfo->prMsduInfo); + break; + + default: + DBGLOG(INIT, WARN, "Undefined CMD Type(%u)\n", + prCmdInfo->eCmdType); + ucTC = TC4_INDEX; + break; + } + + return ucTC; +} + +uint8_t nicTxGetTxQByTc(IN struct ADAPTER *prAdapter, + IN uint8_t ucTc) +{ + return arTcResourceControl[ucTc].ucHifTxQIndex; +} + +uint8_t nicTxGetTxDestPortIdxByTc(IN uint8_t ucTc) +{ + return arTcResourceControl[ucTc].ucDestPortIndex; +} + +uint8_t nicTxGetTxDestQIdxByTc(IN uint8_t ucTc) +{ + return arTcResourceControl[ucTc].ucDestQueueIndex; +} + +uint32_t nicTxGetRemainingTxTimeByTc(IN uint8_t ucTc) +{ + return arTcTrafficSettings[ucTc].u4RemainingTxTime; +} + +uint8_t nicTxGetTxCountLimitByTc(IN uint8_t ucTc) +{ + return arTcTrafficSettings[ucTc].ucTxCountLimit; +} +/*----------------------------------------------------------------------------*/ +/*! + * @brief In this function, we'll aggregate frame(PACKET_INFO_T) + * corresponding to HIF TX port + * + * @param prAdapter Pointer to the Adapter structure. + * @param prMsduInfoListHead a link list of P_MSDU_INFO_T + * + * @retval WLAN_STATUS_SUCCESS Bus access ok. + * @retval WLAN_STATUS_FAILURE Bus access fail. + */ +/*----------------------------------------------------------------------------*/ +uint32_t nicTxMsduInfoList(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfoListHead) +{ + struct MSDU_INFO *prMsduInfo, *prNextMsduInfo; + struct QUE qDataPort0, qDataPort1; + struct QUE *prDataPort0, *prDataPort1; + uint32_t status; + + ASSERT(prAdapter); + ASSERT(prMsduInfoListHead); + + prMsduInfo = prMsduInfoListHead; + + prDataPort0 = &qDataPort0; + prDataPort1 = &qDataPort1; + + QUEUE_INITIALIZE(prDataPort0); + QUEUE_INITIALIZE(prDataPort1); + + /* Separate MSDU_INFO_T lists into 2 categories: for Port#0 & Port#1 */ + while (prMsduInfo) { + prNextMsduInfo = (struct MSDU_INFO *) QUEUE_GET_NEXT_ENTRY(( + struct QUE_ENTRY *) prMsduInfo); + + switch (prMsduInfo->ucTC) { + case TC0_INDEX: + case TC1_INDEX: + case TC2_INDEX: + case TC3_INDEX: + QUEUE_GET_NEXT_ENTRY((struct QUE_ENTRY *) prMsduInfo) = + NULL; + QUEUE_INSERT_TAIL(prDataPort0, + (struct QUE_ENTRY *) prMsduInfo); + status = nicTxAcquireResource( + prAdapter, prMsduInfo->ucTC, + nicTxGetPageCount( + prAdapter, prMsduInfo->u2FrameLength, + FALSE), TRUE); + ASSERT(status == WLAN_STATUS_SUCCESS); + + break; + + case TC4_INDEX: /* Management packets */ + QUEUE_GET_NEXT_ENTRY((struct QUE_ENTRY *) prMsduInfo) = + NULL; + QUEUE_INSERT_TAIL(prDataPort1, + (struct QUE_ENTRY *) prMsduInfo); + + status = nicTxAcquireResource( + prAdapter, prMsduInfo->ucTC, + nicTxGetPageCount(prAdapter, + prMsduInfo->u2FrameLength, + FALSE), TRUE); + ASSERT(status == WLAN_STATUS_SUCCESS); + + break; + + default: + ASSERT(0); + break; + } + + prMsduInfo = prNextMsduInfo; + } + + if (prDataPort0->u4NumElem > 0) + nicTxMsduQueue(prAdapter, 0, prDataPort0); + + if (prDataPort1->u4NumElem > 0) + nicTxMsduQueue(prAdapter, 1, prDataPort1); + + return WLAN_STATUS_SUCCESS; +} + +#if CFG_SUPPORT_MULTITHREAD +/*----------------------------------------------------------------------------*/ +/*! + * @brief In this function, we'll aggregate frame(PACKET_INFO_T) + * corresponding to HIF TX port + * + * @param prAdapter Pointer to the Adapter structure. + * @param prMsduInfoListHead a link list of P_MSDU_INFO_T + * + * @retval WLAN_STATUS_SUCCESS Bus access ok. + * @retval WLAN_STATUS_FAILURE Bus access fail. + */ +/*----------------------------------------------------------------------------*/ +uint32_t nicTxMsduInfoListMthread(IN struct ADAPTER + *prAdapter, IN struct MSDU_INFO *prMsduInfoListHead) +{ +#if CFG_FIX_2_TX_PORT + struct MSDU_INFO *prMsduInfo, *prNextMsduInfo; + struct QUE qDataPort0, qDataPort1; + struct QUE *prDataPort0, *prDataPort1; + + KAL_SPIN_LOCK_DECLARATION(); + + ASSERT(prAdapter); + ASSERT(prMsduInfoListHead); + + prMsduInfo = prMsduInfoListHead; + + prDataPort0 = &qDataPort0; + prDataPort1 = &qDataPort1; + + QUEUE_INITIALIZE(prDataPort0); + QUEUE_INITIALIZE(prDataPort1); + + /* Separate MSDU_INFO_T lists into 2 categories: for Port#0 & Port#1 */ + while (prMsduInfo) { + prNextMsduInfo = (struct MSDU_INFO *) QUEUE_GET_NEXT_ENTRY(( + struct QUE_ENTRY *) prMsduInfo); + + switch (prMsduInfo->ucTC) { + case TC0_INDEX: + case TC1_INDEX: + case TC2_INDEX: + case TC3_INDEX: + QUEUE_GET_NEXT_ENTRY((struct QUE_ENTRY *) prMsduInfo) = + NULL; + QUEUE_INSERT_TAIL(prDataPort0, + (struct QUE_ENTRY *) prMsduInfo); + break; + + case TC4_INDEX: /* Management packets */ + QUEUE_GET_NEXT_ENTRY((struct QUE_ENTRY *) prMsduInfo) = + NULL; + QUEUE_INSERT_TAIL(prDataPort1, + (struct QUE_ENTRY *) prMsduInfo); + break; + + default: + ASSERT(0); + break; + } + + nicTxFillDataDesc(prAdapter, prMsduInfo); + + prMsduInfo = prNextMsduInfo; + } + + if (prDataPort0->u4NumElem > 0 + || prDataPort1->u4NumElem > 0) { + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_PORT_QUE); + QUEUE_CONCATENATE_QUEUES((&(prAdapter->rTxP0Queue)), + (prDataPort0)); + QUEUE_CONCATENATE_QUEUES((&(prAdapter->rTxP1Queue)), + (prDataPort1)); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_PORT_QUE); + + kalSetTxEvent2Hif(prAdapter->prGlueInfo); + } +#else + + struct MSDU_INFO *prMsduInfo, *prNextMsduInfo; + struct QUE qDataPort[TX_PORT_NUM]; + struct QUE *prDataPort[TX_PORT_NUM]; + int32_t i; + u_int8_t fgSetTx2Hif = FALSE; + + KAL_SPIN_LOCK_DECLARATION(); + + ASSERT(prAdapter); + ASSERT(prMsduInfoListHead); + + prMsduInfo = prMsduInfoListHead; + + for (i = 0; i < TX_PORT_NUM; i++) { + prDataPort[i] = &qDataPort[i]; + QUEUE_INITIALIZE(prDataPort[i]); + } + + /* Separate MSDU_INFO_T lists into 2 categories: for Port#0 & Port#1 */ + while (prMsduInfo) { + + fgSetTx2Hif = TRUE; + prNextMsduInfo = (struct MSDU_INFO *) QUEUE_GET_NEXT_ENTRY(( + struct QUE_ENTRY *) prMsduInfo); + + if (prMsduInfo->ucWmmQueSet == DBDC_2G_WMM_INDEX) { + QUEUE_GET_NEXT_ENTRY((struct QUE_ENTRY *) prMsduInfo) = + NULL; + QUEUE_INSERT_TAIL(prDataPort[TX_2G_WMM_PORT_NUM], + (struct QUE_ENTRY *) prMsduInfo); + } else { + if (prMsduInfo->ucTC >= 0 && + prMsduInfo->ucTC < TC_NUM) { + QUEUE_GET_NEXT_ENTRY( + (struct QUE_ENTRY *) prMsduInfo) = + NULL; + QUEUE_INSERT_TAIL(prDataPort[prMsduInfo->ucTC], + (struct QUE_ENTRY *) prMsduInfo); + } else + ASSERT(0); + } + nicTxFillDataDesc(prAdapter, prMsduInfo); + GLUE_INC_REF_CNT(prAdapter->rHifStats.u4DataInCount); + + prMsduInfo = prNextMsduInfo; + } + + if (fgSetTx2Hif) { + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_PORT_QUE); + for (i = 0; i < TX_PORT_NUM; i++) + QUEUE_CONCATENATE_QUEUES((&(prAdapter->rTxPQueue[i])), + (prDataPort[i])); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_PORT_QUE); + kalSetTxEvent2Hif(prAdapter->prGlueInfo); + } + +#endif + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief In this function, we'll write frame(PACKET_INFO_T) into HIF + * when apply multithread. + * + * @param prAdapter Pointer to the Adapter structure. + * + * @retval WLAN_STATUS_SUCCESS Bus access ok. + * @retval WLAN_STATUS_FAILURE Bus access fail. + */ +/*----------------------------------------------------------------------------*/ +uint32_t nicTxMsduQueueMthread(IN struct ADAPTER *prAdapter) +{ +#if CFG_FIX_2_TX_PORT + struct QUE qDataPort0, qDataPort1; + struct QUE *prDataPort0, *prDataPort1; + uint32_t u4TxLoopCount; + + KAL_SPIN_LOCK_DECLARATION(); + + prDataPort0 = &qDataPort0; + prDataPort1 = &qDataPort1; + + QUEUE_INITIALIZE(prDataPort0); + QUEUE_INITIALIZE(prDataPort1); + + u4TxLoopCount = prAdapter->rWifiVar.u4HifTxloopCount; + + while (u4TxLoopCount--) { + while (QUEUE_IS_NOT_EMPTY(&(prAdapter->rTxP0Queue))) { + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_PORT_QUE); + QUEUE_MOVE_ALL(prDataPort0, &(prAdapter->rTxP0Queue)); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_PORT_QUE); + + nicTxMsduQueue(prAdapter, 0, prDataPort0); + + if (QUEUE_IS_NOT_EMPTY(prDataPort0)) { + KAL_ACQUIRE_SPIN_LOCK(prAdapter, + SPIN_LOCK_TX_PORT_QUE); + QUEUE_CONCATENATE_QUEUES_HEAD( + &(prAdapter->rTxP0Queue), + prDataPort0); + KAL_RELEASE_SPIN_LOCK(prAdapter, + SPIN_LOCK_TX_PORT_QUE); + + break; + } + } + + while (QUEUE_IS_NOT_EMPTY(&(prAdapter->rTxP1Queue))) { + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_PORT_QUE); + QUEUE_MOVE_ALL(prDataPort1, &(prAdapter->rTxP1Queue)); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_PORT_QUE); + + nicTxMsduQueue(prAdapter, 1, prDataPort1); + + if (QUEUE_IS_NOT_EMPTY(prDataPort1)) { + KAL_ACQUIRE_SPIN_LOCK(prAdapter, + SPIN_LOCK_TX_PORT_QUE); + QUEUE_CONCATENATE_QUEUES_HEAD( + &(prAdapter->rTxP1Queue), + prDataPort1); + KAL_RELEASE_SPIN_LOCK(prAdapter, + SPIN_LOCK_TX_PORT_QUE); + + break; + } + } + } +#else + + uint32_t u4TxLoopCount = prAdapter->rWifiVar.u4HifTxloopCount; + + if (halIsHifStateSuspend(prAdapter)) { + DBGLOG(TX, WARN, "Suspend TxMsduQueueMthread\n"); + return WLAN_STATUS_SUCCESS; + } + + while (u4TxLoopCount--) { + if (prAdapter->rWifiVar.ucTxMsduQueue == 1) + nicTxMsduQueueByRR(prAdapter); + else + nicTxMsduQueueByPrio(prAdapter); + } +#endif + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief In this function, we'll write MSDU into HIF by TC priority + * + * + * @param prAdapter Pointer to the Adapter structure. + * + */ +/*----------------------------------------------------------------------------*/ +void nicTxMsduQueueByPrio(struct ADAPTER *prAdapter) +{ + struct QUE qDataPort[TX_PORT_NUM]; + struct QUE *prDataPort[TX_PORT_NUM]; + int32_t i; + + KAL_SPIN_LOCK_DECLARATION(); + + for (i = 0; i < TX_PORT_NUM; i++) { + prDataPort[i] = &qDataPort[i]; + QUEUE_INITIALIZE(prDataPort[i]); + } + + for (i = TC_NUM; i >= 0; i--) { + while (QUEUE_IS_NOT_EMPTY(&(prAdapter->rTxPQueue[i]))) { + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_PORT_QUE); + QUEUE_MOVE_ALL(prDataPort[i], + &(prAdapter->rTxPQueue[i])); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_PORT_QUE); + + TRACE(nicTxMsduQueue(prAdapter, 0, prDataPort[i]), + "Move TxPQueue%d %d", i, prDataPort[i]->u4NumElem); + + if (QUEUE_IS_NOT_EMPTY(prDataPort[i])) { + KAL_ACQUIRE_SPIN_LOCK( + prAdapter, + SPIN_LOCK_TX_PORT_QUE); + QUEUE_CONCATENATE_QUEUES_HEAD( + &(prAdapter->rTxPQueue[i]), + prDataPort[i]); + KAL_RELEASE_SPIN_LOCK(prAdapter, + SPIN_LOCK_TX_PORT_QUE); + + break; + } + } + } +} + +#if CFG_SUPPORT_LOWLATENCY_MODE +/*----------------------------------------------------------------------------*/ +/*! + * @brief In this function, we'll pick high priority packet to data queue + * + * + * @param prAdapter Pointer to the Adapter structure. + * @param prDataPort Pointer to data queue + * + */ +/*----------------------------------------------------------------------------*/ +static void nicTxMsduPickHighPrioPkt(struct ADAPTER *prAdapter, + struct QUE *prDataPort0, + struct QUE *prDataPort1) +{ + struct QUE *prDataPort, *prTxQue; + struct MSDU_INFO *prMsduInfo; + struct sk_buff *prSkb; + int32_t i4TcIdx; + uint32_t u4QSize, u4Idx; + uint8_t ucPortIdx; + + for (i4TcIdx = TC_NUM; i4TcIdx >= 0; i4TcIdx--) { + prTxQue = &(prAdapter->rTxPQueue[i4TcIdx]); + u4QSize = prTxQue->u4NumElem; + for (u4Idx = 0; u4Idx < u4QSize; u4Idx++) { + QUEUE_REMOVE_HEAD(prTxQue, prMsduInfo, + struct MSDU_INFO *); + if (!prMsduInfo || !prMsduInfo->prPacket) { + QUEUE_INSERT_TAIL( + prTxQue, + (struct QUE_ENTRY *)prMsduInfo); + continue; + } + + ucPortIdx = halTxRingDataSelect(prAdapter, prMsduInfo); + prDataPort = (ucPortIdx == TX_RING_DATA1_IDX_1) ? + prDataPort1 : prDataPort0; + + prSkb = prMsduInfo->prPacket; + if (prSkb->mark == NIC_TX_SKB_PRIORITY_MARK1 || + (prSkb->mark & BIT(NIC_TX_SKB_PRIORITY_MARK_BIT))) { + QUEUE_INSERT_TAIL( + prDataPort, + (struct QUE_ENTRY *)prMsduInfo); + } else { + QUEUE_INSERT_TAIL( + prTxQue, + (struct QUE_ENTRY *)prMsduInfo); + } + } + } +} +#endif /* CFG_SUPPORT_LOWLATENCY_MODE */ + + +/*----------------------------------------------------------------------------*/ +/*! + * @brief In this function, we'll write MSDU into HIF by Round-Robin + * + * + * @param prAdapter Pointer to the Adapter structure. + * + */ +/*----------------------------------------------------------------------------*/ +void nicTxMsduQueueByRR(struct ADAPTER *prAdapter) +{ + struct WIFI_VAR *prWifiVar; + struct QUE qDataPort0, qDataPort1, arTempQue[TX_PORT_NUM]; + struct QUE *prDataPort0, *prDataPort1, *prDataPort, *prTxQue; + struct MSDU_INFO *prMsduInfo; + uint32_t u4Idx, u4IsNotAllQueneEmpty; + uint8_t ucPortIdx; + uint32_t au4TxCnt[TX_PORT_NUM], u4Offset = 0; + char aucLogBuf[512]; + + KAL_SPIN_LOCK_DECLARATION(); + + prWifiVar = &prAdapter->rWifiVar; + prDataPort0 = &qDataPort0; + prDataPort1 = &qDataPort1; + QUEUE_INITIALIZE(prDataPort0); + QUEUE_INITIALIZE(prDataPort1); + kalMemZero(aucLogBuf, 512); + + for (u4Idx = 0; u4Idx < TX_PORT_NUM; u4Idx++) { + QUEUE_INITIALIZE(&arTempQue[u4Idx]); + au4TxCnt[u4Idx] = 0; + } + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_PORT_QUE); + +#if CFG_SUPPORT_LOWLATENCY_MODE + /* Dequeue each TCQ to dataQ, high priority packet first */ + if (prWifiVar->ucLowLatencyPacketPriority & BIT(1)) + nicTxMsduPickHighPrioPkt(prAdapter, prDataPort0, prDataPort1); +#endif /* CFG_SUPPORT_LOWLATENCY_MODE */ + + /* Dequeue each TCQ to dataQ by round-robin */ + /* Check each TCQ is empty or not */ + u4IsNotAllQueneEmpty = BITS(0, TC_NUM); + while (u4IsNotAllQueneEmpty) { + u4Idx = prAdapter->u4TxHifResCtlIdx; + prTxQue = &(prAdapter->rTxPQueue[u4Idx]); + if (QUEUE_IS_NOT_EMPTY(prTxQue)) { + QUEUE_REMOVE_HEAD(prTxQue, prMsduInfo, + struct MSDU_INFO *); + if (prMsduInfo != NULL) { + ucPortIdx = halTxRingDataSelect( + prAdapter, prMsduInfo); + prDataPort = + (ucPortIdx == TX_RING_DATA1_IDX_1) ? + prDataPort1 : prDataPort0; + QUEUE_INSERT_TAIL(prDataPort, + (struct QUE_ENTRY *) prMsduInfo); + au4TxCnt[u4Idx]++; + } else { + /* unset empty queue */ + u4IsNotAllQueneEmpty &= ~BIT(u4Idx); + DBGLOG(NIC, WARN, "prMsduInfo is NULL\n"); + } + } else { + /* unset empty queue */ + u4IsNotAllQueneEmpty &= ~BIT(u4Idx); + } + prAdapter->u4TxHifResCtlNum++; + if (prAdapter->u4TxHifResCtlNum >= + prAdapter->au4TxHifResCtl[u4Idx]) { + prAdapter->u4TxHifResCtlIdx++; + prAdapter->u4TxHifResCtlIdx %= TX_PORT_NUM; + prAdapter->u4TxHifResCtlNum = 0; + } + } + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_PORT_QUE); + + nicTxMsduQueue(prAdapter, 0, prDataPort0); + nicTxMsduQueue(prAdapter, 0, prDataPort1); + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_PORT_QUE); + /* Enque from dataQ to TCQ if TX don't finish */ + /* Need to reverse dataQ by TC first */ + while (QUEUE_IS_NOT_EMPTY(prDataPort0)) { + QUEUE_REMOVE_HEAD(prDataPort0, prMsduInfo, struct MSDU_INFO *); + QUEUE_INSERT_HEAD(&arTempQue[prMsduInfo->ucTC], + (struct QUE_ENTRY *) prMsduInfo); + } + while (QUEUE_IS_NOT_EMPTY(prDataPort1)) { + QUEUE_REMOVE_HEAD(prDataPort1, prMsduInfo, struct MSDU_INFO *); + QUEUE_INSERT_HEAD(&arTempQue[prMsduInfo->ucTC], + (struct QUE_ENTRY *) prMsduInfo); + } + + for (u4Idx = 0; u4Idx < TX_PORT_NUM; u4Idx++) { + while (QUEUE_IS_NOT_EMPTY(&arTempQue[u4Idx])) { + QUEUE_REMOVE_HEAD(&arTempQue[u4Idx], prMsduInfo, + struct MSDU_INFO *); + QUEUE_INSERT_HEAD(&prAdapter->rTxPQueue[u4Idx], + (struct QUE_ENTRY *) prMsduInfo); + } + } + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_PORT_QUE); + + for (u4Idx = 0; u4Idx < TX_PORT_NUM; u4Idx++) { + u4Offset += snprintf( + aucLogBuf + u4Offset, 512 - u4Offset, + "TC[%u]:%u ", u4Idx, au4TxCnt[u4Idx]); + } + DBGLOG_LIMITED(NIC, LOUD, "%s\n", aucLogBuf); +} + +uint32_t nicTxGetMsduPendingCnt(IN struct ADAPTER + *prAdapter) +{ +#if CFG_FIX_2_TX_PORT + return prAdapter->rTxP0Queue.u4NumElem + + prAdapter->rTxP1Queue.u4NumElem; +#else + int32_t i; + uint32_t retValue = 0; + + for (i = 0; i < TX_PORT_NUM; i++) + retValue += prAdapter->rTxPQueue[i].u4NumElem; + return retValue; +#endif +} + +#endif + +void nicTxComposeDescAppend(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + OUT uint8_t *prTxDescBuffer) +{ + struct mt66xx_chip_info *prChipInfo = prAdapter->chip_info; + + if (prChipInfo->prTxDescOps->fillNicAppend) + prChipInfo->prTxDescOps->fillNicAppend(prAdapter, + prMsduInfo, prTxDescBuffer); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief In this function, we'll compose the Tx descriptor of the MSDU. + * + * @param prAdapter Pointer to the Adapter structure. + * @param prMsduInfo Pointer to the Msdu info + * @param prTxDesc Pointer to the Tx descriptor buffer + * + * @retval VOID + */ +/*----------------------------------------------------------------------------*/ +void +nicTxComposeDesc( + IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN uint32_t u4TxDescLength, + IN u_int8_t fgIsTemplate, + OUT uint8_t *prTxDescBuffer) +{ + struct TX_DESC_OPS_T *prTxDescOps = prAdapter->chip_info->prTxDescOps; + + if (prTxDescOps->nic_txd_compose) + prTxDescOps->nic_txd_compose( + prAdapter, + prMsduInfo, + u4TxDescLength, + fgIsTemplate, + prTxDescBuffer); + else + DBGLOG(TX, ERROR, "%s:: no nic_txd_compose??\n", __func__); +} + +void +nicTxComposeSecurityFrameDesc( + IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, + OUT uint8_t *prTxDescBuffer, + OUT uint8_t *pucTxDescLength) +{ + struct TX_DESC_OPS_T *prTxDescOps = prAdapter->chip_info->prTxDescOps; + + if (prTxDescOps->nic_txd_compose_security_frame) + prTxDescOps->nic_txd_compose_security_frame( + prAdapter, + prCmdInfo, + prTxDescBuffer, + pucTxDescLength); + else + DBGLOG(TX, ERROR, "%s:: no nic_txd_compose_security_frame??\n", + __func__); +} + +void +nicTxForceAmsduForCert( + struct ADAPTER *prAdapter, + u_int8_t *prTxDescBuffer) +{ +#if (CFG_SUPPORT_802_11AX == 1) && (CFG_SUPPORT_CONNAC2X == 1) + struct HW_MAC_CONNAC2X_TX_DESC *prTxDesc = + (struct HW_MAC_CONNAC2X_TX_DESC *) prTxDescBuffer; + + if (fgEfuseCtrlAxOn == 1) { + if (prAdapter->rWifiVar.ucHeAmsduInAmpduTx && + prAdapter->rWifiVar.ucHeCertForceAmsdu) + HAL_MAC_CONNAC2X_TXD_SET_HW_AMSDU(prTxDesc); + } +#endif /* (CFG_SUPPORT_802_11AX == 1) && (CFG_SUPPORT_CONNAC2X == 1) */ +} + +u_int8_t nicTxIsTXDTemplateAllowed(IN struct ADAPTER + *prAdapter, IN struct MSDU_INFO *prMsduInfo, + IN struct STA_RECORD *prStaRec) +{ + if (prMsduInfo->fgIsTXDTemplateValid) { + if (prMsduInfo->fgIs802_1x) + return FALSE; + + if (prMsduInfo->ucRateMode != MSDU_RATE_MODE_AUTO) + return FALSE; + + if (!prStaRec) + return FALSE; + + if (prMsduInfo->ucControlFlag) + return FALSE; + + if (prMsduInfo->pfTxDoneHandler) + return FALSE; + + if (prAdapter->rWifiVar.ucDataTxRateMode) + return FALSE; + + return TRUE; + } + return FALSE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief In this function, we'll compose the Tx descriptor of the MSDU. + * + * @param prAdapter Pointer to the Adapter structure. + * @param prMsduInfo Pointer to the Msdu info + * @param prTxDesc Pointer to the Tx descriptor buffer + * + * @retval VOID + */ +/*----------------------------------------------------------------------------*/ +void +nicTxFillDesc(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + OUT uint8_t *prTxDescBuffer, OUT uint32_t *pu4TxDescLength) +{ + struct mt66xx_chip_info *prChipInfo = prAdapter->chip_info; + void *prTxDesc = prTxDescBuffer; + void *prTxDescTemplate = NULL; + struct STA_RECORD *prStaRec = cnmGetStaRecByIndex(prAdapter, + prMsduInfo->ucStaRecIndex); + uint32_t u4TxDescLength; +#if CFG_TCP_IP_CHKSUM_OFFLOAD + uint8_t ucChksumFlag = 0; +#endif + struct TX_DESC_OPS_T *prTxDescOps = prChipInfo->prTxDescOps; + + /* + * ------------------------------------------------------------------- + * Fill up common fileds + * ------------------------------------------------------------------- + */ + u4TxDescLength = NIC_TX_DESC_LONG_FORMAT_LENGTH; + + /* Get TXD from pre-allocated template */ + if (nicTxIsTXDTemplateAllowed(prAdapter, prMsduInfo, + prStaRec)) { + prTxDescTemplate = + prStaRec->aprTxDescTemplate[prMsduInfo->ucUserPriority]; + } + if (prTxDescTemplate) { + prMsduInfo->ucWlanIndex = nicTxGetWlanIdx(prAdapter, + prMsduInfo->ucBssIndex, prMsduInfo->ucStaRecIndex); + if (prMsduInfo->ucPacketType == TX_PACKET_TYPE_DATA) + kalMemCopy(prTxDesc, prTxDescTemplate, + u4TxDescLength + prChipInfo->txd_append_size); + else + kalMemCopy(prTxDesc, prTxDescTemplate, u4TxDescLength); + /* Overwrite fields for EOSP or More data */ + nicTxFillDescByPktOption(prAdapter, prMsduInfo, prTxDesc); + } else { /* Compose TXD by Msdu info */ + DBGLOG_LIMITED(NIC, TRACE, "Compose TXD by Msdu info\n"); +#if (UNIFIED_MAC_TX_FORMAT == 1) + if (prMsduInfo->eSrc == TX_PACKET_MGMT) + prMsduInfo->ucPacketFormat = TXD_PKT_FORMAT_COMMAND; + else + prMsduInfo->ucPacketFormat = prChipInfo->ucPacketFormat; +#endif /* UNIFIED_MAC_TX_FORMAT == 1 */ + nicTxComposeDesc(prAdapter, prMsduInfo, u4TxDescLength, + FALSE, prTxDescBuffer); + + /* Compose TxD append */ + if (prMsduInfo->ucPacketType == TX_PACKET_TYPE_DATA) + nicTxComposeDescAppend(prAdapter, prMsduInfo, + prTxDescBuffer + u4TxDescLength); + } + + nicTxForceAmsduForCert(prAdapter, (u_int8_t *)prTxDesc); + /* + * -------------------------------------------------------------------- + * Fill up remaining parts, per-packet variant fields + * -------------------------------------------------------------------- + */ + if (prTxDescOps->fillTxByteCount) + prTxDescOps->fillTxByteCount(prAdapter, + prMsduInfo, prTxDesc); + + /* Checksum offload */ +#if CFG_TCP_IP_CHKSUM_OFFLOAD + if (prAdapter->fgIsSupportCsumOffload + && prMsduInfo->eSrc == TX_PACKET_OS) { + if (prAdapter->u4CSUMFlags & + (CSUM_OFFLOAD_EN_TX_TCP | CSUM_OFFLOAD_EN_TX_UDP | + CSUM_OFFLOAD_EN_TX_IP)) { + ASSERT(prMsduInfo->prPacket); + kalQueryTxChksumOffloadParam(prMsduInfo->prPacket, + &ucChksumFlag); + if (prTxDescOps->nic_txd_chksum_op) + prTxDescOps->nic_txd_chksum_op( + prTxDesc, ucChksumFlag); + else + DBGLOG(TX, ERROR, + "%s:: no nic_txd_chksum_op??\n", + __func__); + } + } +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ + + /* Set EtherType & VLAN for non 802.11 frame */ + if (prTxDescOps->nic_txd_header_format_op) + prTxDescOps->nic_txd_header_format_op( + prTxDesc, prMsduInfo); + else + DBGLOG(TX, ERROR, + "%s:: no nic_txd_header_format_op??\n", + __func__); + + if (pu4TxDescLength) + *pu4TxDescLength = u4TxDescLength; +} + +void +nicTxFillDataDesc(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo) +{ + uint8_t *pucOutputBuf; + struct mt66xx_chip_info *prChipInfo = prAdapter->chip_info; + + pucOutputBuf = skb_push((struct sk_buff *) + prMsduInfo->prPacket, + NIC_TX_DESC_AND_PADDING_LENGTH + + prChipInfo->txd_append_size); + + nicTxFillDesc(prAdapter, prMsduInfo, pucOutputBuf, NULL); + /* dump TXD to debug TX issue */ + if (prAdapter->rWifiVar.ucDataTxDone == 1) + halDumpTxdInfo(prAdapter, (uint32_t *)pucOutputBuf); +} + +void +nicTxCopyDesc(IN struct ADAPTER *prAdapter, + IN uint8_t *pucTarTxDesc, IN uint8_t *pucSrcTxDesc, + OUT uint8_t *pucTxDescLength) +{ + struct TX_DESC_OPS_T *prTxDescOps; + uint8_t ucTxDescLength; + + prTxDescOps = prAdapter->chip_info->prTxDescOps; + if (prTxDescOps->nic_txd_long_format_op(pucSrcTxDesc, FALSE)) + ucTxDescLength = NIC_TX_DESC_LONG_FORMAT_LENGTH; + else + ucTxDescLength = NIC_TX_DESC_SHORT_FORMAT_LENGTH; + + kalMemCopy(pucTarTxDesc, pucSrcTxDesc, ucTxDescLength); + + if (pucTxDescLength) + *pucTxDescLength = ucTxDescLength; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief In this function, we'll generate Tx descriptor template for each TID. + * + * @param prAdapter Pointer to the Adapter structure. + * @param prStaRec Pointer to the StaRec structure. + * + * @retval VOID + */ +/*----------------------------------------------------------------------------*/ +uint32_t nicTxGenerateDescTemplate(IN struct ADAPTER + *prAdapter, IN struct STA_RECORD *prStaRec) +{ + uint8_t ucTid; + uint8_t ucTc; + uint32_t u4TxDescSize, u4TxDescAppendSize; + void *prTxDesc; + struct MSDU_INFO *prMsduInfo; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + struct mt66xx_chip_info *prChipInfo; + + ASSERT(prAdapter); + + /* Free previous template, first */ + /* nicTxFreeDescTemplate(prAdapter, prStaRec); */ + for (ucTid = 0; ucTid < TX_DESC_TID_NUM; ucTid++) + prStaRec->aprTxDescTemplate[ucTid] = NULL; + + prMsduInfo = cnmPktAlloc(prAdapter, 0); + + if (!prMsduInfo) + return WLAN_STATUS_RESOURCES; + + prChipInfo = prAdapter->chip_info; + + /* Fill up MsduInfo template */ + prMsduInfo->eSrc = TX_PACKET_OS; + prMsduInfo->fgIs802_11 = FALSE; + prMsduInfo->fgIs802_1x = FALSE; + prMsduInfo->fgIs802_1x_NonProtected = FALSE; + prMsduInfo->fgIs802_3 = FALSE; + prMsduInfo->fgIsVlanExists = FALSE; + prMsduInfo->pfTxDoneHandler = NULL; + prMsduInfo->prPacket = NULL; + prMsduInfo->u2FrameLength = 0; + prMsduInfo->u4Option = 0; + prMsduInfo->u4FixedRateOption = 0; + prMsduInfo->ucRateMode = MSDU_RATE_MODE_AUTO; + prMsduInfo->ucBssIndex = prStaRec->ucBssIndex; + prMsduInfo->ucPacketType = TX_PACKET_TYPE_DATA; + prMsduInfo->ucPacketFormat = prChipInfo->ucPacketFormat; + prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; + prMsduInfo->ucPID = NIC_TX_DESC_PID_RESERVED; + + u4TxDescSize = NIC_TX_DESC_LONG_FORMAT_LENGTH; + u4TxDescAppendSize = prChipInfo->txd_append_size; + + DBGLOG(QM, INFO, + "Generate TXD template for STA[%u] QoS[%u]\n", + prStaRec->ucIndex, prStaRec->fgIsQoS); + + /* Generate new template */ + if (prStaRec->fgIsQoS) { + /* For QoS STA, generate 8 TXD template (TID0~TID7) */ + for (ucTid = 0; ucTid < TX_DESC_TID_NUM; ucTid++) { + + if (prAdapter->rWifiVar.ucTcRestrict < TC_NUM) + ucTc = prAdapter->rWifiVar.ucTcRestrict; + else + ucTc = + arNetwork2TcResource[ + prStaRec->ucBssIndex][ + aucTid2ACI[ucTid]]; + u4TxDescSize = arTcTrafficSettings[ucTc].u4TxDescLength; + + /* Include TxD append */ + prTxDesc = kalMemAlloc( + u4TxDescSize + u4TxDescAppendSize, + VIR_MEM_TYPE); + DBGLOG(QM, TRACE, "STA[%u] TID[%u] TxDTemp[0x%p]\n", + prStaRec->ucIndex, ucTid, prTxDesc); + if (!prTxDesc) { + rStatus = WLAN_STATUS_RESOURCES; + break; + } + + /* Update MsduInfo TID & TC */ + prMsduInfo->ucUserPriority = ucTid; + prMsduInfo->ucTC = ucTc; + + /* Compose Tx desc template */ + nicTxComposeDesc( + prAdapter, prMsduInfo, u4TxDescSize, TRUE, + (uint8_t *) prTxDesc); + + /* Fill TxD append */ + nicTxComposeDescAppend(prAdapter, prMsduInfo, + ((uint8_t *)prTxDesc + u4TxDescSize)); + + prStaRec->aprTxDescTemplate[ucTid] = prTxDesc; + } + } else { + /* For non-QoS STA, generate 1 TXD template (TID0) */ + do { + if (prAdapter->rWifiVar.ucTcRestrict < TC_NUM) + ucTc = prAdapter->rWifiVar.ucTcRestrict; + else + ucTc = arNetwork2TcResource[ + prStaRec->ucBssIndex][ + NET_TC_WMM_AC_BE_INDEX]; + + /* ucTxDescSize = + * arTcTrafficSettings[ucTc].ucTxDescLength; + */ + u4TxDescSize = NIC_TX_DESC_LONG_FORMAT_LENGTH; + + prTxDesc = kalMemAlloc( + u4TxDescSize + u4TxDescAppendSize, + VIR_MEM_TYPE); + if (!prTxDesc) { + rStatus = WLAN_STATUS_RESOURCES; + break; + } + /* Update MsduInfo TID & TC */ + prMsduInfo->ucUserPriority = 0; + prMsduInfo->ucTC = ucTc; + + /* Compose Tx desc template */ + nicTxComposeDesc( + prAdapter, prMsduInfo, u4TxDescSize, TRUE, + (uint8_t *) prTxDesc); + + /* Fill TxD append */ + nicTxComposeDescAppend(prAdapter, prMsduInfo, + ((uint8_t *)prTxDesc + u4TxDescSize)); + + for (ucTid = 0; ucTid < TX_DESC_TID_NUM; ucTid++) { + prStaRec->aprTxDescTemplate[ucTid] = prTxDesc; + DBGLOG(QM, TRACE, + "TXD template: TID[%u] Ptr[0x%p]\n", + ucTid, prTxDesc); + } + } while (FALSE); + } + + nicTxReturnMsduInfo(prAdapter, prMsduInfo); + + return rStatus; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief In this function, we'll free Tx descriptor template for each TID. + * + * @param prAdapter Pointer to the Adapter structure. + * @param prStaRec Pointer to the StaRec structure. + * + * @retval VOID + */ +/*----------------------------------------------------------------------------*/ +void nicTxFreeDescTemplate(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec) +{ + struct TX_DESC_OPS_T *prTxDescOps; + uint8_t ucTid; + uint8_t ucTxDescSize; + void *prTxDesc; + + DBGLOG(QM, TRACE, "Free TXD template for STA[%u] QoS[%u]\n", + prStaRec->ucIndex, prStaRec->fgIsQoS); + + prTxDescOps = prAdapter->chip_info->prTxDescOps; + if (prStaRec->fgIsQoS) { + for (ucTid = 0; ucTid < TX_DESC_TID_NUM; ucTid++) { + prTxDesc = prStaRec->aprTxDescTemplate[ucTid]; + + if (prTxDesc) { + if (prTxDescOps->nic_txd_long_format_op( + prTxDesc, FALSE)) + ucTxDescSize = + NIC_TX_DESC_LONG_FORMAT_LENGTH; + else + ucTxDescSize = + NIC_TX_DESC_SHORT_FORMAT_LENGTH; + + kalMemFree(prTxDesc, VIR_MEM_TYPE, + ucTxDescSize); + + prTxDesc = + prStaRec->aprTxDescTemplate[ucTid] = + NULL; + } + } + } else { + prTxDesc = prStaRec->aprTxDescTemplate[0]; + if (prTxDesc) { + if (prTxDescOps->nic_txd_long_format_op( + prTxDesc, FALSE)) + ucTxDescSize = NIC_TX_DESC_LONG_FORMAT_LENGTH; + else + ucTxDescSize = NIC_TX_DESC_SHORT_FORMAT_LENGTH; + + kalMemFree(prTxDesc, VIR_MEM_TYPE, ucTxDescSize); + prTxDesc = NULL; + } + for (ucTid = 0; ucTid < TX_DESC_TID_NUM; ucTid++) + prStaRec->aprTxDescTemplate[ucTid] = NULL; + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief In this function, we'll Update H/W AMSDU filed of TxD template. + * + * @param prAdapter Pointer to the Adapter structure. + * @param prStaRec Pointer to the StaRec structure. + * @param ucTid Select target Tid template + * @param ucSet Set or clear + * + * @retval VOID + */ +/*----------------------------------------------------------------------------*/ +void nicTxSetHwAmsduDescTemplate( + IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, + IN uint8_t ucTid, + IN u_int8_t fgSet) +{ + struct TX_DESC_OPS_T *prTxDescOps = prAdapter->chip_info->prTxDescOps; + + if (prTxDescOps->nic_txd_set_hw_amsdu_template) + prTxDescOps->nic_txd_set_hw_amsdu_template( + prAdapter, + prStaRec, + ucTid, + fgSet); + else + DBGLOG(TX, ERROR, + "%s:: no nic_txd_set_hw_amsdu_template??\n", + __func__); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Write data to device done + * + * \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. + * \param[in] prQue msdu info que to be free + * + * \retval TRUE operation success + * \retval FALSE operation fail + */ +/*----------------------------------------------------------------------------*/ +void nicTxMsduDoneCb(IN struct GLUE_INFO *prGlueInfo, + IN struct QUE *prQue) +{ + struct MSDU_INFO *prMsduInfo, *prNextMsduInfo; + struct QUE rFreeQueue; + struct QUE *prFreeQueue; + /* P_NATIVE_PACKET prNativePacket;*/ + struct TX_CTRL *prTxCtrl; + struct ADAPTER *prAdapter = prGlueInfo->prAdapter; + + ASSERT(prAdapter); + prTxCtrl = &prAdapter->rTxCtrl; + ASSERT(prTxCtrl); + + prFreeQueue = &rFreeQueue; + QUEUE_INITIALIZE(prFreeQueue); + + if (prQue && prQue->u4NumElem > 0) { + prMsduInfo = (struct MSDU_INFO *) QUEUE_GET_HEAD(prQue); + + while (prMsduInfo) { + prNextMsduInfo = + (struct MSDU_INFO *) QUEUE_GET_NEXT_ENTRY( + &prMsduInfo->rQueEntry); + +#if 1 + nicTxFreePacket(prAdapter, prMsduInfo, FALSE); +#else + prNativePacket = prMsduInfo->prPacket; + + /* Free MSDU_INFO */ + if (prMsduInfo->eSrc == TX_PACKET_OS) { + wlanTxProfilingTagMsdu(prAdapter, prMsduInfo, + TX_PROF_TAG_DRV_DEQUE); + kalSendComplete( + prAdapter->prGlueInfo, prNativePacket, + WLAN_STATUS_SUCCESS); + prMsduInfo->prPacket = NULL; + } else if (prMsduInfo->eSrc == TX_PACKET_FORWARDING) { + GLUE_DEC_REF_CNT( + prTxCtrl->i4PendingFwdFrameCount); + } +#endif + + if (!prMsduInfo->pfTxDoneHandler) + QUEUE_INSERT_TAIL(prFreeQueue, + (struct QUE_ENTRY *) prMsduInfo); + + prMsduInfo = prNextMsduInfo; + } + + wlanTxProfilingTagMsdu(prAdapter, + (struct MSDU_INFO *) QUEUE_GET_HEAD(&rFreeQueue), + TX_PROF_TAG_DRV_FREE); + + nicTxReturnMsduInfo(prAdapter, + (struct MSDU_INFO *) + QUEUE_GET_HEAD(&rFreeQueue)); + } +} + +void nicHifTxMsduDoneCb(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo) +{ + struct TX_CTRL *prTxCtrl; + + if (!prAdapter || !prMsduInfo) + return; + + prTxCtrl = &prAdapter->rTxCtrl; + + if (prMsduInfo->pfTxDoneHandler) { + KAL_SPIN_LOCK_DECLARATION(); + + /* Record native packet pointer for Tx done log */ + WLAN_GET_FIELD_32(&prMsduInfo->prPacket, + &prMsduInfo->u4TxDoneTag); + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, + SPIN_LOCK_TXING_MGMT_LIST); + QUEUE_INSERT_TAIL(&(prTxCtrl->rTxMgmtTxingQueue), + (struct QUE_ENTRY *) prMsduInfo); + KAL_RELEASE_SPIN_LOCK(prAdapter, + SPIN_LOCK_TXING_MGMT_LIST); + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief In this function, we'll write frame(PACKET_INFO_T) into HIF. + * + * @param prAdapter Pointer to the Adapter structure. + * @param ucPortIdx Port Number + * @param prQue a link list of P_MSDU_INFO_T + * + * @retval WLAN_STATUS_SUCCESS Bus access ok. + * @retval WLAN_STATUS_FAILURE Bus access fail. + */ +/*----------------------------------------------------------------------------*/ +uint32_t nicTxMsduQueue(IN struct ADAPTER *prAdapter, + uint8_t ucPortIdx, struct QUE *prQue) +{ + struct MSDU_INFO *prMsduInfo; + struct TX_CTRL *prTxCtrl; + + ASSERT(prAdapter); + ASSERT(prQue); + + prTxCtrl = &prAdapter->rTxCtrl; + +#if CFG_HIF_STATISTICS + prTxCtrl->u4TotalTxAccessNum++; + prTxCtrl->u4TotalTxPacketNum += prQue->u4NumElem; +#endif + + while (QUEUE_IS_NOT_EMPTY(prQue)) { + u_int8_t fgTxDoneHandler; + + QUEUE_REMOVE_HEAD(prQue, prMsduInfo, struct MSDU_INFO *); + + if (prMsduInfo == NULL) { + DBGLOG(TX, WARN, "prMsduInfo is NULL\n"); + break; + } + + if (!halTxIsDataBufEnough(prAdapter, prMsduInfo)) { + QUEUE_INSERT_HEAD(prQue, + (struct QUE_ENTRY *) prMsduInfo); + break; + } + + fgTxDoneHandler = prMsduInfo->pfTxDoneHandler ? + TRUE : FALSE; + +#if !CFG_SUPPORT_MULTITHREAD + nicTxFillDataDesc(prAdapter, prMsduInfo); +#endif + + if (prMsduInfo->eSrc == TX_PACKET_OS) { + wlanTxProfilingTagMsdu(prAdapter, prMsduInfo, + TX_PROF_TAG_DRV_TX_DONE); + wlanFillTimestamp(prAdapter, prMsduInfo->prPacket, + PHASE_HIF_TX); + } + + if (!fgTxDoneHandler) + wlanTxProfilingTagMsdu(prAdapter, prMsduInfo, + TX_PROF_TAG_DRV_TX_DONE); + +#if (CFG_SUPPORT_STATISTICS == 1) + StatsEnvTxTime2Hif(prAdapter, prMsduInfo); +#endif + HAL_WRITE_TX_DATA(prAdapter, prMsduInfo); + } + + HAL_KICK_TX_DATA(prAdapter); + + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief In this function, we'll write Command(CMD_INFO_T) into HIF. + * + * @param prAdapter Pointer to the Adapter structure. + * @param prPacketInfo Pointer of CMD_INFO_T + * @param ucTC Specify the resource of TC + * + * @retval WLAN_STATUS_SUCCESS Bus access ok. + * @retval WLAN_STATUS_FAILURE Bus access fail. + */ +/*----------------------------------------------------------------------------*/ +uint32_t nicTxCmd(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t ucTC) +{ + struct MSDU_INFO *prMsduInfo; + struct TX_CTRL *prTxCtrl; + struct sk_buff *skb; + struct TX_DESC_OPS_T *prTxDescOps; + + KAL_SPIN_LOCK_DECLARATION(); + + ASSERT(prAdapter); + ASSERT(prCmdInfo); + prTxDescOps = prAdapter->chip_info->prTxDescOps; + prTxCtrl = &prAdapter->rTxCtrl; +#if (CFG_SUPPORT_TRACE_TC4 == 1) + wlanTraceTxCmd(prCmdInfo); +#endif + + if (prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME || + prCmdInfo->eCmdType == COMMAND_TYPE_DATA_FRAME) { + prMsduInfo = prCmdInfo->prMsduInfo; + + /* dump TXD to debug TX issue */ + if (prAdapter->rWifiVar.ucDataTxDone == 3) + halDumpTxdInfo(prAdapter, + (uint32_t *)prMsduInfo->aucTxDescBuffer); + + prCmdInfo->pucTxd = prMsduInfo->aucTxDescBuffer; + if (prTxDescOps->nic_txd_long_format_op( + prMsduInfo->aucTxDescBuffer, FALSE)) + prCmdInfo->u4TxdLen = NIC_TX_DESC_LONG_FORMAT_LENGTH; + else + prCmdInfo->u4TxdLen = NIC_TX_DESC_SHORT_FORMAT_LENGTH; + + skb = (struct sk_buff *)prMsduInfo->prPacket; + prCmdInfo->pucTxp = skb->data; + prCmdInfo->u4TxpLen = skb->len; + + HAL_WRITE_TX_CMD(prAdapter, prCmdInfo, ucTC); + + prMsduInfo->prPacket = NULL; + + DBGLOG_LIMITED(INIT, TRACE, + "TX Data Frame: BSS[%u] WIDX:PID[%u:%u] SEQ[%u] STA[%u] RSP[%u]\n", + prMsduInfo->ucBssIndex, prMsduInfo->ucWlanIndex, + prMsduInfo->ucPID, + prMsduInfo->ucTxSeqNum, prMsduInfo->ucStaRecIndex, + prMsduInfo->pfTxDoneHandler ? TRUE : FALSE); + + if (prMsduInfo->pfTxDoneHandler) { + KAL_ACQUIRE_SPIN_LOCK(prAdapter, + SPIN_LOCK_TXING_MGMT_LIST); + QUEUE_INSERT_TAIL(&(prTxCtrl->rTxMgmtTxingQueue), + (struct QUE_ENTRY *) prMsduInfo); + KAL_RELEASE_SPIN_LOCK(prAdapter, + SPIN_LOCK_TXING_MGMT_LIST); + } else { + /* Only return MSDU_INFO */ + /* NativePacket will be freed at + * SEC frame CMD callback + */ + nicTxReturnMsduInfo(prAdapter, prMsduInfo); + } + + } else if (prCmdInfo->eCmdType == + COMMAND_TYPE_MANAGEMENT_FRAME) { + prMsduInfo = prCmdInfo->prMsduInfo; + + ASSERT(prMsduInfo->fgIs802_11 == TRUE); + ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT); + + /* dump TXD to debug TX issue */ + if (prAdapter->rWifiVar.ucDataTxDone == 3) + halDumpTxdInfo(prAdapter, + (uint32_t *)prMsduInfo->aucTxDescBuffer); + + prCmdInfo->pucTxd = prMsduInfo->aucTxDescBuffer; + if (prTxDescOps->nic_txd_long_format_op( + prMsduInfo->aucTxDescBuffer, FALSE)) + prCmdInfo->u4TxdLen = NIC_TX_DESC_LONG_FORMAT_LENGTH; + else + prCmdInfo->u4TxdLen = NIC_TX_DESC_SHORT_FORMAT_LENGTH; + + prCmdInfo->pucTxp = prMsduInfo->prPacket; + prCmdInfo->u4TxpLen = prMsduInfo->u2FrameLength; + + HAL_WRITE_TX_CMD(prAdapter, prCmdInfo, ucTC); + /* <4> Management Frame Post-Processing */ + GLUE_DEC_REF_CNT(prTxCtrl->i4TxMgmtPendingNum); + + DBGLOG(INIT, TRACE, + "TX MGMT Frame: BSS[%u] WIDX:PID[%u:%u] SEQ[%u] STA[%u] RSP[%u]\n", + prMsduInfo->ucBssIndex, prMsduInfo->ucWlanIndex, + prMsduInfo->ucPID, + prMsduInfo->ucTxSeqNum, prMsduInfo->ucStaRecIndex, + prMsduInfo->pfTxDoneHandler ? TRUE : FALSE); + + if (prMsduInfo->pfTxDoneHandler) { + KAL_ACQUIRE_SPIN_LOCK(prAdapter, + SPIN_LOCK_TXING_MGMT_LIST); + QUEUE_INSERT_TAIL(&(prTxCtrl->rTxMgmtTxingQueue), + (struct QUE_ENTRY *) prMsduInfo); + KAL_RELEASE_SPIN_LOCK(prAdapter, + SPIN_LOCK_TXING_MGMT_LIST); + } else { + cnmMgtPktFree(prAdapter, prMsduInfo); + } + + } else { + prCmdInfo->pucTxd = prCmdInfo->pucInfoBuffer; + prCmdInfo->u4TxdLen = prCmdInfo->u2InfoBufLen; + prCmdInfo->pucTxp = NULL; + prCmdInfo->u4TxpLen = 0; + + HAL_WRITE_TX_CMD(prAdapter, prCmdInfo, ucTC); + } + + return WLAN_STATUS_SUCCESS; +} /* end of nicTxCmd() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function will clean up all the pending frames in internal + * SW Queues by return the pending TX packet to the system. + * + * @param prAdapter Pointer to the Adapter structure. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void nicTxRelease(IN struct ADAPTER *prAdapter, + IN u_int8_t fgProcTxDoneHandler) +{ + struct TX_CTRL *prTxCtrl; + struct MSDU_INFO *prMsduInfo; + + KAL_SPIN_LOCK_DECLARATION(); + + ASSERT(prAdapter); + + prTxCtrl = &prAdapter->rTxCtrl; + + nicTxFlush(prAdapter); + + /* free MSDU_INFO_T from rTxMgmtMsduInfoList */ + do { + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); + QUEUE_REMOVE_HEAD(&prTxCtrl->rTxMgmtTxingQueue, prMsduInfo, + struct MSDU_INFO *); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); + + if (prMsduInfo) { + DBGLOG(TX, TRACE, + "%s: Get Msdu WIDX:PID[%u:%u] SEQ[%u] from Pending Q\n", + __func__, prMsduInfo->ucWlanIndex, prMsduInfo->ucPID, + prMsduInfo->ucTxSeqNum); + + /* invoke done handler */ + if (prMsduInfo->pfTxDoneHandler && fgProcTxDoneHandler) + prMsduInfo->pfTxDoneHandler( + prAdapter, prMsduInfo, + TX_RESULT_DROPPED_IN_DRIVER); + + nicTxFreeMsduInfoPacket(prAdapter, prMsduInfo); + nicTxReturnMsduInfo(prAdapter, prMsduInfo); + } else { + break; + } + } while (TRUE); + +} /* end of nicTxRelease() */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Process the TX Done interrupt and pull in more pending frames in SW + * Queues for transmission. + * + * @param prAdapter Pointer to the Adapter structure. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void nicProcessTxInterrupt(IN struct ADAPTER *prAdapter) +{ + struct WIFI_VAR *prWifiVar = &prAdapter->rWifiVar; + + prAdapter->prGlueInfo->IsrTxCnt++; + halProcessTxInterrupt(prAdapter); + + if (halIsHifStateSuspend(prAdapter)) + DBGLOG(TX, WARN, "Suspend TX INT\n"); + + /* Indicate Service Thread */ + if (kalGetTxPendingCmdCount(prAdapter->prGlueInfo) > 0 + || wlanGetTxPendingFrameCount(prAdapter) > 0) + kalSetEvent(prAdapter->prGlueInfo); + + /* SER break point */ + if (nicSerIsTxStop(prAdapter)) { + /* Skip following Tx handling */ + return; + } + + /* TX Commands */ + if (kalGetTxPendingCmdCount(prAdapter->prGlueInfo)) + wlanTxCmdMthread(prAdapter); + + /* Process TX data packet to HIF */ + if (nicTxGetMsduPendingCnt(prAdapter) >= + prWifiVar->u4TxIntThCount) + nicTxMsduQueueMthread(prAdapter); +} /* end of nicProcessTxInterrupt() */ + +void nicTxFreePacket(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, IN u_int8_t fgDrop) +{ + void *prNativePacket; + struct TX_CTRL *prTxCtrl; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + + ASSERT(prAdapter); + + prTxCtrl = &prAdapter->rTxCtrl; + + prNativePacket = prMsduInfo->prPacket; + + wlanTxProfilingTagMsdu(prAdapter, prMsduInfo, TX_PROF_TAG_DRV_FREE); + + if (fgDrop) + rStatus = WLAN_STATUS_FAILURE; + + if (prMsduInfo->eSrc == TX_PACKET_OS) { + if (prNativePacket) + kalSendComplete(prAdapter->prGlueInfo, prNativePacket, + rStatus); + if (fgDrop) + wlanUpdateTxStatistics(prAdapter, prMsduInfo, + TRUE); /*get per-AC Tx drop packets */ + } else if (prMsduInfo->eSrc == TX_PACKET_MGMT) { + if (prMsduInfo->pfTxDoneHandler) + prMsduInfo->pfTxDoneHandler(prAdapter, prMsduInfo, + TX_RESULT_DROPPED_IN_DRIVER); + if (prNativePacket) + cnmMemFree(prAdapter, prNativePacket); + } else if (prMsduInfo->eSrc == TX_PACKET_FORWARDING) { + GLUE_DEC_REF_CNT(prTxCtrl->i4PendingFwdFrameCount); + GLUE_DEC_REF_CNT(prTxCtrl + ->i4PendingFwdFrameWMMCount[ + aucACI2TxQIdx[aucTid2ACI[prMsduInfo->ucUserPriority]]]); + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief this function frees packet of P_MSDU_INFO_T linked-list + * + * @param prAdapter Pointer to the Adapter structure. + * @param prMsduInfoList a link list of P_MSDU_INFO_T + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void nicTxFreeMsduInfoPacket(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfoListHead) +{ + void *prNativePacket; + struct MSDU_INFO *prMsduInfo = prMsduInfoListHead; + struct TX_CTRL *prTxCtrl; + + ASSERT(prAdapter); + ASSERT(prMsduInfoListHead); + + prTxCtrl = &prAdapter->rTxCtrl; + + while (prMsduInfo) { + prNativePacket = prMsduInfo->prPacket; + +#if 1 + nicTxFreePacket(prAdapter, prMsduInfo, TRUE); +#else + if (prMsduInfo->eSrc == TX_PACKET_OS) { + if (prNativePacket) + kalSendComplete( + prAdapter->prGlueInfo, prNativePacket, + WLAN_STATUS_FAILURE); + /*get per-AC Tx drop packets */ + wlanUpdateTxStatistics(prAdapter, prMsduInfo, TRUE); + } else if (prMsduInfo->eSrc == TX_PACKET_MGMT) { + if (prMsduInfo->pfTxDoneHandler) + prMsduInfo->pfTxDoneHandler( + prAdapter, prMsduInfo, + TX_RESULT_DROPPED_IN_DRIVER); + if (prNativePacket) + cnmMemFree(prAdapter, prNativePacket); + } else if (prMsduInfo->eSrc == TX_PACKET_FORWARDING) { + GLUE_DEC_REF_CNT(prTxCtrl->i4PendingFwdFrameCount); + } +#endif + prMsduInfo = (struct MSDU_INFO *) QUEUE_GET_NEXT_ENTRY(( + struct QUE_ENTRY *) prMsduInfo); + } + +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief this function returns P_MSDU_INFO_T of MsduInfoList to + * TxCtrl->rfreeMsduInfoList + * + * @param prAdapter Pointer to the Adapter structure. + * @param prMsduInfoList a link list of P_MSDU_INFO_T + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void nicTxReturnMsduInfo(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfoListHead) +{ + struct TX_CTRL *prTxCtrl; + struct MSDU_INFO *prMsduInfo = prMsduInfoListHead, + *prNextMsduInfo; + + KAL_SPIN_LOCK_DECLARATION(); + + ASSERT(prAdapter); + + prTxCtrl = &prAdapter->rTxCtrl; + ASSERT(prTxCtrl); + + while (prMsduInfo) { + prNextMsduInfo = (struct MSDU_INFO *) QUEUE_GET_NEXT_ENTRY(( + struct QUE_ENTRY *) prMsduInfo); + + switch (prMsduInfo->eSrc) { + case TX_PACKET_FORWARDING: + wlanReturnPacket(prAdapter, prMsduInfo->prPacket); + break; + case TX_PACKET_OS: + case TX_PACKET_OS_OID: + case TX_PACKET_MGMT: + default: + break; + } + + /* Reset MSDU_INFO fields */ + kalMemZero(prMsduInfo, sizeof(struct MSDU_INFO)); + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, + SPIN_LOCK_TX_MSDU_INFO_LIST); + QUEUE_INSERT_TAIL(&prTxCtrl->rFreeMsduInfoList, + (struct QUE_ENTRY *) prMsduInfo); + KAL_RELEASE_SPIN_LOCK(prAdapter, + SPIN_LOCK_TX_MSDU_INFO_LIST); + prMsduInfo = prNextMsduInfo; + }; + +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief this function fills packet information to P_MSDU_INFO_T + * + * @param prAdapter Pointer to the Adapter structure. + * @param prMsduInfo P_MSDU_INFO_T + * @param prPacket P_NATIVE_PACKET + * + * @retval TRUE Success to extract information + * @retval FALSE Fail to extract correct information + */ +/*----------------------------------------------------------------------------*/ +u_int8_t nicTxFillMsduInfo(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, IN void *prPacket) +{ + struct GLUE_INFO *prGlueInfo; + + ASSERT(prAdapter); + + kalMemZero(prMsduInfo, sizeof(struct MSDU_INFO)); + + prGlueInfo = prAdapter->prGlueInfo; + ASSERT(prGlueInfo); + + kalGetEthDestAddr(prAdapter->prGlueInfo, prPacket, + prMsduInfo->aucEthDestAddr); + + prMsduInfo->prPacket = prPacket; + prMsduInfo->ucBssIndex = GLUE_GET_PKT_BSS_IDX(prPacket); +#if CFG_SUPPORT_WIFI_SYSDVT + if (prAdapter->ucTxTestUP != TX_TEST_UP_UNDEF) + prMsduInfo->ucUserPriority = prAdapter->ucTxTestUP; + else +#endif /* CFG_SUPPORT_WIFI_SYSDVT */ + prMsduInfo->ucUserPriority = GLUE_GET_PKT_TID(prPacket); + prMsduInfo->ucMacHeaderLength = GLUE_GET_PKT_HEADER_LEN( + prPacket); + prMsduInfo->u2FrameLength = (uint16_t) + GLUE_GET_PKT_FRAME_LEN(prPacket); + prMsduInfo->u4PageCount = nicTxGetPageCount(prAdapter, + prMsduInfo->u2FrameLength, FALSE); + + if (GLUE_IS_PKT_FLAG_SET(prPacket)) { + prMsduInfo->fgIs802_1x = GLUE_TEST_PKT_FLAG(prPacket, + ENUM_PKT_1X) ? TRUE : FALSE; + prMsduInfo->fgIs802_1x_NonProtected = + GLUE_TEST_PKT_FLAG(prPacket, + ENUM_PKT_NON_PROTECTED_1X) ? TRUE : FALSE; + prMsduInfo->fgIs802_3 = GLUE_TEST_PKT_FLAG(prPacket, + ENUM_PKT_802_3) ? TRUE : FALSE; + prMsduInfo->fgIsVlanExists = GLUE_TEST_PKT_FLAG(prPacket, + ENUM_PKT_VLAN_EXIST) ? TRUE : FALSE; + + if (prMsduInfo->fgIs802_1x) + prMsduInfo->eEapolKeyType = secGetEapolKeyType((( + struct sk_buff *)prPacket)->data); + + if (GLUE_TEST_PKT_FLAG(prPacket, ENUM_PKT_DHCP) + && prAdapter->rWifiVar.ucDhcpTxDone) + prMsduInfo->ucPktType = ENUM_PKT_DHCP; + else if (GLUE_TEST_PKT_FLAG(prPacket, ENUM_PKT_ARP) + && prAdapter->rWifiVar.ucArpTxDone) + prMsduInfo->ucPktType = ENUM_PKT_ARP; + else if (GLUE_TEST_PKT_FLAG(prPacket, ENUM_PKT_1X)) + prMsduInfo->ucPktType = ENUM_PKT_1X; + else if (GLUE_TEST_PKT_FLAG(prPacket, ENUM_PKT_ICMP)) + prMsduInfo->ucPktType = ENUM_PKT_ICMP; + else if (GLUE_TEST_PKT_FLAG(prPacket, ENUM_PKT_TDLS)) + prMsduInfo->ucPktType = ENUM_PKT_TDLS; + else if (GLUE_TEST_PKT_FLAG(prPacket, ENUM_PKT_DNS)) + prMsduInfo->ucPktType = ENUM_PKT_DNS; + +#if (CFG_SUPPORT_DMASHDL_SYSDVT) + if (prMsduInfo->ucPktType != ENUM_PKT_ICMP) { + /* blocking non ICMP packets at DMASHDL DVT items */ + if (DMASHDL_DVT_ALLOW_PING_ONLY(prAdapter)) + return FALSE; + } +#endif + if (prMsduInfo->ucPktType != 0) { + prMsduInfo->pfTxDoneHandler = wlanPktTxDone; + prMsduInfo->ucTxSeqNum = GLUE_GET_PKT_SEQ_NO(prPacket); + } + +#if CFG_SUPPORT_WIFI_SYSDVT + if (prAdapter->ucTxTestUP != TX_TEST_UP_UNDEF) + ; + else +#endif /* CFG_SUPPORT_WIFI_SYSDVT */ + if (GLUE_TEST_PKT_FLAG(prPacket, ENUM_PKT_DHCP) || + GLUE_TEST_PKT_FLAG(prPacket, ENUM_PKT_ARP) || + GLUE_TEST_PKT_FLAG(prPacket, ENUM_PKT_1X)) { + /* Set BSS/STA lowest basic rate */ + prMsduInfo->ucRateMode = MSDU_RATE_MODE_LOWEST_RATE; + } + } + + /* Add dummy Tx done */ + if ((prAdapter->rWifiVar.ucDataTxDone == 1) + && (prMsduInfo->pfTxDoneHandler == NULL)) + prMsduInfo->pfTxDoneHandler = nicTxDummyTxDone; + + prMsduInfo->pfHifTxMsduDoneCb = nicHifTxMsduDoneCb; + + return TRUE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief this function update TCQ values by passing current status to + * txAdjustTcQuotas + * + * @param prAdapter Pointer to the Adapter structure. + * + * @retval WLAN_STATUS_SUCCESS Updated successfully + */ +/*----------------------------------------------------------------------------*/ +uint32_t nicTxAdjustTcq(IN struct ADAPTER *prAdapter) +{ +#if CFG_SUPPORT_MULTITHREAD + struct TX_TCQ_ADJUST rTcqAdjust; + struct TX_CTRL *prTxCtrl; + + ASSERT(prAdapter); + + prTxCtrl = &prAdapter->rTxCtrl; + ASSERT(prTxCtrl); + + qmAdjustTcQuotasMthread(prAdapter, &rTcqAdjust, + &prTxCtrl->rTc); + +#else + + uint32_t u4Num; + struct TX_TCQ_ADJUST rTcqAdjust; + struct TX_CTRL *prTxCtrl; + struct TX_TCQ_STATUS *prTcqStatus; + + KAL_SPIN_LOCK_DECLARATION(); + + ASSERT(prAdapter); + + prTxCtrl = &prAdapter->rTxCtrl; + prTcqStatus = &prAdapter->rTxCtrl.rTc; + ASSERT(prTxCtrl); + + if (qmAdjustTcQuotas(prAdapter, &rTcqAdjust, + &prTxCtrl->rTc)) { + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); + + for (u4Num = 0; u4Num < TC_NUM; u4Num++) { + /* Page count */ + prTxCtrl->rTc.au4FreePageCount[u4Num] += + (rTcqAdjust.ai4Variation[u4Num] * + NIC_TX_MAX_PAGE_PER_FRAME); + prTxCtrl->rTc.au4MaxNumOfPage[u4Num] += + (rTcqAdjust.ai4Variation[u4Num] * + NIC_TX_MAX_PAGE_PER_FRAME); + + /* Buffer count */ + prTxCtrl->rTc.au4FreeBufferCount[u4Num] += + rTcqAdjust.ai4Variation[u4Num]; + prTxCtrl->rTc.au4MaxNumOfBuffer[u4Num] += + rTcqAdjust.ai4Variation[u4Num]; + + ASSERT(prTxCtrl->rTc.au4FreeBufferCount[u4Num] >= 0); + ASSERT(prTxCtrl->rTc.au4MaxNumOfBuffer[u4Num] >= 0); + } + + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); +#if 0 + DBGLOG(TX, LOUD, + "TCQ Status Free Page:Buf[%03u:%02u, %03u:%02u, %03u:%02u, %03u:%02u, %03u:%02u, %03u:%02u]\n", + prTcqStatus->au4FreePageCount[TC0_INDEX], + prTcqStatus->au4FreeBufferCount[TC0_INDEX], + prTcqStatus->au4FreePageCount[TC1_INDEX], + prTcqStatus->au4FreeBufferCount[TC1_INDEX], + prTcqStatus->au4FreePageCount[TC2_INDEX], + prTcqStatus->au4FreeBufferCount[TC2_INDEX], + prTcqStatus->au4FreePageCount[TC3_INDEX], + prTcqStatus->au4FreeBufferCount[TC3_INDEX], + prTcqStatus->au4FreePageCount[TC4_INDEX], + prTcqStatus->au4FreeBufferCount[TC4_INDEX], + prTcqStatus->au4FreePageCount[TC5_INDEX], + prTcqStatus->au4FreeBufferCount[TC5_INDEX]); +#endif + DBGLOG(TX, LOUD, + "TCQ Status Max Page:Buf[%03u:%02u, %03u:%02u, %03u:%02u, %03u:%02u, %03u:%02u]\n", + prTcqStatus->au4MaxNumOfPage[TC0_INDEX], + prTcqStatus->au4MaxNumOfBuffer[TC0_INDEX], + prTcqStatus->au4MaxNumOfPage[TC1_INDEX], + prTcqStatus->au4MaxNumOfBuffer[TC1_INDEX], + prTcqStatus->au4MaxNumOfPage[TC2_INDEX], + prTcqStatus->au4MaxNumOfBuffer[TC2_INDEX], + prTcqStatus->au4MaxNumOfPage[TC3_INDEX], + prTcqStatus->au4MaxNumOfBuffer[TC3_INDEX], + prTcqStatus->au4MaxNumOfPage[TC4_INDEX], + prTcqStatus->au4MaxNumOfBuffer[TC4_INDEX]); + + } +#endif + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief this function flushes all packets queued in STA/AC queue + * + * @param prAdapter Pointer to the Adapter structure. + * + * @retval WLAN_STATUS_SUCCESS Flushed successfully + */ +/*----------------------------------------------------------------------------*/ + +uint32_t nicTxFlush(IN struct ADAPTER *prAdapter) +{ + struct MSDU_INFO *prMsduInfo; + + KAL_SPIN_LOCK_DECLARATION(); + + ASSERT(prAdapter); + + if (HAL_IS_TX_DIRECT(prAdapter)) { + nicTxDirectClearAllStaPsQ(prAdapter); + } else { + /* ask Per STA/AC queue to be fllushed + * and return all queued packets + */ + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); + prMsduInfo = qmFlushTxQueues(prAdapter); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); + + if (prMsduInfo != NULL) { + nicTxFreeMsduInfoPacket(prAdapter, prMsduInfo); + nicTxReturnMsduInfo(prAdapter, prMsduInfo); + } + } + + return WLAN_STATUS_SUCCESS; +} + +#if CFG_ENABLE_FW_DOWNLOAD +/*----------------------------------------------------------------------------*/ +/*! + * \brief In this function, we'll write Command(CMD_INFO_T) into HIF. + * However this function is used for INIT_CMD. + * + * In order to avoid further maintenance issues, these 2 functions + * are separated + * + * @param prAdapter Pointer to the Adapter structure. + * @param prPacketInfo Pointer of CMD_INFO_T + * @param ucTC Specify the resource of TC + * + * @retval WLAN_STATUS_SUCCESS Bus access ok. + * @retval WLAN_STATUS_FAILURE Bus access fail. + */ +/*----------------------------------------------------------------------------*/ +uint32_t nicTxInitCmd(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint16_t u2Port) +{ + uint16_t u2OverallBufferLength; + /* Pointer to Transmit Data Structure Frame */ + uint8_t *pucOutputBuf = (uint8_t *) NULL; + struct TX_CTRL *prTxCtrl; + struct mt66xx_chip_info *prChipInfo; + + ASSERT(prAdapter); + ASSERT(prCmdInfo); + + prChipInfo = prAdapter->chip_info; + prTxCtrl = &prAdapter->rTxCtrl; + pucOutputBuf = prTxCtrl->pucTxCoalescingBufPtr; + u2OverallBufferLength = TFCB_FRAME_PAD_TO_DW(( + prCmdInfo->u2InfoBufLen + prChipInfo->u2HifTxdSize) & + (uint16_t) + HIF_TX_HDR_TX_BYTE_COUNT_MASK); + + /* <0> Copy HIF TXD if need */ + HAL_WRITE_HIF_TXD(prChipInfo, pucOutputBuf, + prCmdInfo->u2InfoBufLen); + + /* <1> Copy CMD Header to command buffer + * (by using pucCoalescingBufCached) + */ + kalMemCopy((void *)&pucOutputBuf[prChipInfo->u2HifTxdSize], + (void *) prCmdInfo->pucInfoBuffer, prCmdInfo->u2InfoBufLen); + + ASSERT(u2OverallBufferLength <= + prAdapter->u4CoalescingBufCachedSize); + + GLUE_INC_REF_CNT(prAdapter->rHifStats.u4CmdInCount); + /* <2> Write frame to data port */ + HAL_WRITE_TX_PORT(prAdapter, u2Port/*NIC_TX_INIT_CMD_PORT*/, + (uint32_t) u2OverallBufferLength, + (uint8_t *) pucOutputBuf, + (uint32_t) prAdapter->u4CoalescingBufCachedSize); + + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief In this function, we'll reset TX resource counter to initial + * value used in F/W download state + * + * @param prAdapter Pointer to the Adapter structure. + * + * @retval WLAN_STATUS_SUCCESS Reset is done successfully. + */ +/*----------------------------------------------------------------------------*/ +uint32_t nicTxInitResetResource(IN struct ADAPTER + *prAdapter) +{ + struct TX_CTRL *prTxCtrl; + uint8_t ucIdx; + uint32_t u4MaxPageCntPerFrame = + prAdapter->rTxCtrl.u4MaxPageCntPerFrame; + + DEBUGFUNC("nicTxInitResetResource"); + + ASSERT(prAdapter); + prTxCtrl = &prAdapter->rTxCtrl; + + /* Delta page count */ + kalMemZero(prTxCtrl->rTc.au4TxDonePageCount, + sizeof(prTxCtrl->rTc.au4TxDonePageCount)); + kalMemZero(prTxCtrl->rTc.au4PreUsedPageCount, + sizeof(prTxCtrl->rTc.au4PreUsedPageCount)); + prTxCtrl->rTc.ucNextTcIdx = TC0_INDEX; + prTxCtrl->rTc.u4AvaliablePageCount = 0; + + /* Page count */ + prTxCtrl->rTc.au4MaxNumOfPage[TC0_INDEX] = + NIC_TX_INIT_PAGE_COUNT_TC0; + prTxCtrl->rTc.au4FreePageCount[TC0_INDEX] = + NIC_TX_INIT_PAGE_COUNT_TC0; + + prTxCtrl->rTc.au4MaxNumOfPage[TC1_INDEX] = + NIC_TX_INIT_PAGE_COUNT_TC1; + prTxCtrl->rTc.au4FreePageCount[TC1_INDEX] = + NIC_TX_INIT_PAGE_COUNT_TC1; + + prTxCtrl->rTc.au4MaxNumOfPage[TC2_INDEX] = + NIC_TX_INIT_PAGE_COUNT_TC2; + prTxCtrl->rTc.au4FreePageCount[TC2_INDEX] = + NIC_TX_INIT_PAGE_COUNT_TC2; + + prTxCtrl->rTc.au4MaxNumOfPage[TC3_INDEX] = + NIC_TX_INIT_PAGE_COUNT_TC3; + prTxCtrl->rTc.au4FreePageCount[TC3_INDEX] = + NIC_TX_INIT_PAGE_COUNT_TC3; + + prTxCtrl->rTc.au4MaxNumOfPage[TC4_INDEX] = + NIC_TX_INIT_PAGE_COUNT_TC4; + prTxCtrl->rTc.au4FreePageCount[TC4_INDEX] = + NIC_TX_INIT_PAGE_COUNT_TC4; + + /* Buffer count */ + for (ucIdx = TC0_INDEX; ucIdx < TC_NUM; ucIdx++) { + prTxCtrl->rTc.au4MaxNumOfBuffer[ucIdx] = + prTxCtrl->rTc.au4MaxNumOfPage[ucIdx] / + u4MaxPageCntPerFrame; + prTxCtrl->rTc.au4FreeBufferCount[ucIdx] = + prTxCtrl->rTc.au4FreePageCount[ucIdx] / + u4MaxPageCntPerFrame; + } + + return WLAN_STATUS_SUCCESS; + +} + +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Handle data packet that will send to firmware + * + * + * @param prAdapter Pointer to the Adapter structure. + * @param prMsduInfo Pointer of MSDU_INFO + * + * @retval TRUE Process success. + */ +/*----------------------------------------------------------------------------*/ +u_int8_t nicTxProcessCmdDataPacket(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo) +{ +#if (CFG_SUPPORT_CONNAC2X == 0) +#define _SET_PKT_FORMAT HAL_MAC_TX_DESC_SET_PKT_FORMAT +#define _SET_REMAINING_LIFE_TIME_IN_MS \ + HAL_MAC_TX_DESC_SET_REMAINING_LIFE_TIME_IN_MS +#define _SET_PID HAL_MAC_TX_DESC_SET_PID +#define _TX_DESC struct HW_MAC_TX_DESC* +#else +#define _SET_PKT_FORMAT HAL_MAC_CONNAC2X_TXD_SET_PKT_FORMAT +#define _SET_REMAINING_LIFE_TIME_IN_MS \ + HAL_MAC_CONNAC2X_TXD_SET_REMAINING_LIFE_TIME_IN_MS +#define _SET_PID HAL_MAC_CONNAC2X_TXD_SET_PID +#define _TX_DESC struct HW_MAC_CONNAC2X_TX_DESC* +#endif + struct BSS_INFO *prBssInfo; + _TX_DESC prTxDesc; + + /* Sanity check */ + if (!prMsduInfo->prPacket) { + DBGLOG_LIMITED(TX, WARN, "MSDU prPacket is null\n"); + return FALSE; + } + + if (!prMsduInfo->u2FrameLength) { + DBGLOG_LIMITED(TX, WARN, "MSDU u2FrameLength is 0\n"); + return FALSE; + } + + if (!prMsduInfo->ucMacHeaderLength) { + DBGLOG_LIMITED(TX, WARN, "MSDU ucMacHeaderLength is 0\n"); + return FALSE; + } + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prMsduInfo->ucBssIndex); + /* Set StaRecIndex here*/ + qmDetermineStaRecIndex(prAdapter, prMsduInfo); + prMsduInfo->eSrc = TX_PACKET_OS; + + /* MMPDU: force stick to TC4 */ + prMsduInfo->ucTC = TC4_INDEX; + + /* No Tx descriptor template for MMPDU */ + prMsduInfo->fgIsTXDTemplateValid = FALSE; + + /* Set packet type to data to fill correct TxD */ + prMsduInfo->ucPacketType = TX_PACKET_TYPE_DATA; + +#if CFG_SUPPORT_MULTITHREAD + nicTxFillDesc(prAdapter, prMsduInfo, + prMsduInfo->aucTxDescBuffer, NULL); + /* DBGLOG_MEM32(HAL, ERROR, prMsduInfo->aucTxDescBuffer, 64); */ +#endif + + /* + * Adjust TxD for command data after fill description + */ + prTxDesc = (_TX_DESC) prMsduInfo->aucTxDescBuffer; + + /* (1) Force set packet format to command for command data*/ +#if (UNIFIED_MAC_TX_FORMAT == 1) + _SET_PKT_FORMAT(prTxDesc, TXD_PKT_FORMAT_COMMAND); +#endif + + /* (2) Set remaining TX time to no limit as cut-through data. + * Not use arTcTrafficSettings[TC4_INDEX].u4RemainingTxTime; + */ + if (!(prMsduInfo->u4Option & MSDU_OPT_MANUAL_LIFE_TIME)) + prMsduInfo->u4RemainingLifetime = TX_DESC_TX_TIME_NO_LIMIT; + + _SET_REMAINING_LIFE_TIME_IN_MS(prTxDesc, + prMsduInfo->u4RemainingLifetime); + + /* (3) If prMsduInfo->pfTxDoneHandler is not set (ie. PID is not set) + * Still set PID for command data packet for firmware usage. Driver + * does not handle EVENT_ID_TX_DONE in this case + */ + if (prMsduInfo->ucPID < NIC_TX_DESC_DRIVER_PID_MIN) { + prMsduInfo->ucPID = nicTxAssignPID(prAdapter, + prMsduInfo->ucWlanIndex); + + _SET_PID(prTxDesc, prMsduInfo->ucPID); + } + +#undef _SET_PKT_FORMAT +#undef _SET_REMAINING_LIFE_TIME_IN_MS +#undef _SET_PID +#undef _TX_DESC + + return TRUE; +} + +u_int8_t nicTxProcessMngPacket(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo) +{ +#if 0 + uint16_t u2RateCode; +#endif + struct BSS_INFO *prBssInfo; + struct STA_RECORD *prStaRec; + + if (prMsduInfo->eSrc != TX_PACKET_MGMT) + return FALSE; + + /* Sanity check */ + if (!prMsduInfo->prPacket) + return FALSE; + + if (!prMsduInfo->u2FrameLength) + return FALSE; + + if (!prMsduInfo->ucMacHeaderLength) + return FALSE; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prMsduInfo->ucBssIndex); + prStaRec = cnmGetStaRecByIndex(prAdapter, + prMsduInfo->ucStaRecIndex); + + /* MMPDU: force stick to TC4 */ + if (prMsduInfo->fgMgmtUseDataQ) + prMsduInfo->ucTC = TC0_INDEX; + else + prMsduInfo->ucTC = TC4_INDEX; + + /* No Tx descriptor template for MMPDU */ + prMsduInfo->fgIsTXDTemplateValid = FALSE; + + /* Fixed Rate */ + if (prMsduInfo->ucRateMode == MSDU_RATE_MODE_AUTO && + prMsduInfo->fgMgmtUseDataQ != TRUE) { +#if 0 + prMsduInfo->ucRateMode = MSDU_RATE_MODE_MANUAL_DESC; + + if (prStaRec) + u2RateCode = prStaRec->u2HwDefaultFixedRateCode; + else + u2RateCode = prBssInfo->u2HwDefaultFixedRateCode; + + nicTxSetPktFixedRateOption(prMsduInfo, u2RateCode, + FIX_BW_NO_FIXED, FALSE, FALSE); +#else + nicTxSetPktLowestFixedRate(prAdapter, prMsduInfo); +#endif + } +#if CFG_SUPPORT_MULTITHREAD + nicTxFillDesc(prAdapter, prMsduInfo, + prMsduInfo->aucTxDescBuffer, NULL); +#endif + + return TRUE; +} + +void nicTxProcessTxDoneEvent(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ + struct EVENT_TX_DONE *prTxDone; + struct MSDU_INFO *prMsduInfo; + struct TX_CTRL *prTxCtrl = &prAdapter->rTxCtrl; + char *prBw = "INVALID"; + + prTxDone = (struct EVENT_TX_DONE *) (prEvent->aucBuffer); + + if (prTxDone->ucFlag & BIT(TXS_WITH_ADVANCED_INFO)) { + /* Tx Done with advanced info */ + if (prTxDone->ucStatus != 0) + DBGLOG_LIMITED(NIC, INFO, + "EVENT_ID_TX_DONE WIDX:PID[%u:%u] Status[%u:%s] SN[%u] TID[%u] CNT[%u] Flush[%u]\n", + prTxDone->ucWlanIndex, prTxDone->ucPacketSeq, + prTxDone->ucStatus, + apucTxResultStr[prTxDone->ucStatus], + prTxDone->u2SequenceNumber, prTxDone->ucTid, + prTxDone->ucTxCount, prTxDone->ucFlushReason); + else + DBGLOG(NIC, TRACE, + "EVENT_ID_TX_DONE WIDX:PID[%u:%u] Status[%u:%s] SN[%u] TID[%u] CNT[%u] Flush[%u]\n", + prTxDone->ucWlanIndex, prTxDone->ucPacketSeq, + prTxDone->ucStatus, + apucTxResultStr[prTxDone->ucStatus], + prTxDone->u2SequenceNumber, prTxDone->ucTid, + prTxDone->ucTxCount, prTxDone->ucFlushReason); + + if (prTxDone->ucFlag & BIT(TXS_IS_EXIST)) { + uint8_t ucNss, ucStbc; + int8_t icTxPwr; + uint32_t *pu4RawTxs = + (uint32_t *)&prTxDone->aucRawTxS[0]; + + ucNss = (prTxDone->u2TxRate & TX_DESC_NSTS_MASK) >> + TX_DESC_NSTS_OFFSET; + ucNss += 1; + ucStbc = (prTxDone->u2TxRate & TX_DESC_STBC) ? + TRUE : FALSE; + + if (ucStbc) + ucNss /= 2; + + if (prTxDone->ucBandwidth >= + sizeof(apucBandwidt) / sizeof(uint8_t *)) + DBGLOG(NIC, WARN, "Invalid bandwidth: %u", + prTxDone->ucBandwidth); + else + prBw = apucBandwidt[prTxDone->ucBandwidth]; + + if (prTxDone->ucStatus != 0) + DBGLOG_LIMITED(NIC, INFO, + "||RATE[0x%04x] BW[%s] NSS[%u] ArIdx[%u] RspRate[0x%02x]\n", + prTxDone->u2TxRate, + prBw, + ucNss, + prTxDone->ucRateTableIdx, + prTxDone->ucRspRate); + else + DBGLOG(NIC, TRACE, + "||RATE[0x%04x] BW[%s] NSS[%u] ArIdx[%u] RspRate[0x%02x]\n", + prTxDone->u2TxRate, + prBw, + ucNss, + prTxDone->ucRateTableIdx, + prTxDone->ucRspRate); + icTxPwr = (int8_t)prTxDone->ucTxPower; + if (icTxPwr & BIT(6)) + icTxPwr |= BIT(7); + + if (prTxDone->ucStatus != 0) + DBGLOG_LIMITED(NIC, INFO, + "||AMPDU[%u] PS[%u] IBF[%u] EBF[%u] TxPwr[%d%sdBm] TSF[%u] TxDelay[%uus]\n", + prTxDone->u4AppliedFlag & + BIT(TX_FRAME_IN_AMPDU_FORMAT) ? + TRUE : FALSE, + prTxDone->u4AppliedFlag & + BIT(TX_FRAME_PS_BIT) ? TRUE : FALSE, + prTxDone->u4AppliedFlag & + BIT(TX_FRAME_IMP_BF) ? TRUE : FALSE, + prTxDone->u4AppliedFlag & + BIT(TX_FRAME_EXP_BF) ? TRUE : FALSE, + icTxPwr / 2, icTxPwr & BIT(0) ? + ".5" : "", + prTxDone->u4Timestamp, + prTxDone->u4TxDelay); + else + DBGLOG_LIMITED(NIC, TRACE, + "||AMPDU[%u] PS[%u] IBF[%u] EBF[%u] TxPwr[%d%sdBm] TSF[%u] TxDelay[%uus]\n", + prTxDone->u4AppliedFlag & + BIT(TX_FRAME_IN_AMPDU_FORMAT) ? + TRUE : FALSE, + prTxDone->u4AppliedFlag & + BIT(TX_FRAME_PS_BIT) ? TRUE : FALSE, + prTxDone->u4AppliedFlag & + BIT(TX_FRAME_IMP_BF) ? TRUE : FALSE, + prTxDone->u4AppliedFlag & + BIT(TX_FRAME_EXP_BF) ? TRUE : FALSE, + icTxPwr / 2, icTxPwr & BIT(0) ? + ".5" : "", + prTxDone->u4Timestamp, + prTxDone->u4TxDelay); + if (prTxDone->ucStatus != 0) + DBGLOG_LIMITED(NIC, INFO, + "TxS[%08x %08x %08x %08x %08x %08x %08x]\n", + *pu4RawTxs, + *(pu4RawTxs + 1), *(pu4RawTxs + 2), + *(pu4RawTxs + 3), *(pu4RawTxs + 4), + *(pu4RawTxs + 5), *(pu4RawTxs + 6)); + else + DBGLOG_LIMITED(NIC, TRACE, + "TxS[%08x %08x %08x %08x %08x %08x %08x]\n", + *pu4RawTxs, + *(pu4RawTxs + 1), *(pu4RawTxs + 2), + *(pu4RawTxs + 3), *(pu4RawTxs + 4), + *(pu4RawTxs + 5), *(pu4RawTxs + 6)); + } + } else { + DBGLOG(NIC, TRACE, + "EVENT_ID_TX_DONE WIDX:PID[%u:%u] Status[%u:%s] SN[%u]\n", + prTxDone->ucWlanIndex, prTxDone->ucPacketSeq, + prTxDone->ucStatus, + apucTxResultStr[prTxDone->ucStatus], + prTxDone->u2SequenceNumber); + } + + /* call related TX Done Handler */ + prMsduInfo = nicGetPendingTxMsduInfo(prAdapter, + prTxDone->ucWlanIndex, + prTxDone->ucPacketSeq); + +#if CFG_SUPPORT_802_11V_TIMING_MEASUREMENT + DBGLOG(NIC, TRACE, + "EVENT_ID_TX_DONE u4TimeStamp = %x u2AirDelay = %x\n", + prTxDone->au4Reserved1, prTxDone->au4Reserved2); + + wnmReportTimingMeas(prAdapter, prMsduInfo->ucStaRecIndex, + prTxDone->au4Reserved1, + prTxDone->au4Reserved1 + prTxDone->au4Reserved2); +#endif + +#if CFG_SUPPORT_WIFI_SYSDVT + if (is_frame_test(prAdapter, 1) != 0) { + prAdapter->auto_dvt->txs.received_pid = prTxDone->ucPacketSeq; + receive_del_txs_queue(prTxDone->u2SequenceNumber, + prTxDone->ucPacketSeq, prTxDone->ucWlanIndex, + prTxDone->u4Timestamp); + DBGLOG(REQ, LOUD, + "Done receive_del_txs_queue pid=%d timestamp=%d\n", + prTxDone->ucPacketSeq, prTxDone->u4Timestamp); + } +#endif + + if (prMsduInfo) { + prMsduInfo->pfTxDoneHandler(prAdapter, prMsduInfo, + (enum ENUM_TX_RESULT_CODE) (prTxDone->ucStatus)); + + if (prMsduInfo->eSrc == TX_PACKET_MGMT) + cnmMgtPktFree(prAdapter, prMsduInfo); +#if defined(_HIF_PCIE) || defined(_HIF_AXI) + else if (prMsduInfo->prToken) + prMsduInfo->pfTxDoneHandler = NULL; +#endif + else { + nicTxFreePacket(prAdapter, prMsduInfo, FALSE); + nicTxReturnMsduInfo(prAdapter, prMsduInfo); + } + + if (prTxDone->ucStatus == 0 && + prMsduInfo->ucBssIndex < MAX_BSSID_NUM) + GET_BOOT_SYSTIME( + &prTxCtrl->u4LastTxTime + [prMsduInfo->ucBssIndex]); + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief this function enqueues MSDU_INFO_T into queue management, + * or command queue + * + * @param prAdapter Pointer to the Adapter structure. + * prMsduInfo Pointer to MSDU + * + * @retval WLAN_STATUS_SUCCESS Reset is done successfully. + */ +/*----------------------------------------------------------------------------*/ +uint32_t nicTxEnqueueMsdu(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo) +{ + struct TX_CTRL *prTxCtrl; + struct MSDU_INFO *prNextMsduInfo, *prRetMsduInfo, + *prMsduInfoHead; + struct QUE qDataPort0, qDataPort1; + struct QUE *prDataPort0, *prDataPort1; + struct CMD_INFO *prCmdInfo; + uint32_t u4Status = WLAN_STATUS_SUCCESS; + + KAL_SPIN_LOCK_DECLARATION(); + + ASSERT(prAdapter); + ASSERT(prMsduInfo); + + prTxCtrl = &prAdapter->rTxCtrl; + ASSERT(prTxCtrl); + + prDataPort0 = &qDataPort0; + prDataPort1 = &qDataPort1; + + QUEUE_INITIALIZE(prDataPort0); + QUEUE_INITIALIZE(prDataPort1); + + /* check how many management frame are being queued */ + while (prMsduInfo) { + prNextMsduInfo = (struct MSDU_INFO *) QUEUE_GET_NEXT_ENTRY(( + struct QUE_ENTRY *) prMsduInfo); + + QUEUE_GET_NEXT_ENTRY((struct QUE_ENTRY *) prMsduInfo) = + NULL; + + if (prMsduInfo->eSrc == TX_PACKET_MGMT) { + if (nicTxProcessMngPacket(prAdapter, prMsduInfo)) { + /* Valid MGMT */ + QUEUE_INSERT_TAIL(prDataPort1, + (struct QUE_ENTRY *) + prMsduInfo); + } else { + /* Invalid MGMT */ + DBGLOG(TX, WARN, + "Invalid MGMT[0x%p] BSS[%u] STA[%u],free it\n", + prMsduInfo, prMsduInfo->ucBssIndex, + prMsduInfo->ucStaRecIndex); + + cnmMgtPktFree(prAdapter, prMsduInfo); + } + } else { + QUEUE_INSERT_TAIL(prDataPort0, + (struct QUE_ENTRY *) prMsduInfo); + } + + prMsduInfo = prNextMsduInfo; + } + + if (prDataPort0->u4NumElem) { + /* send to QM */ + KAL_SPIN_LOCK_DECLARATION(); + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); + prRetMsduInfo = qmEnqueueTxPackets(prAdapter, + (struct MSDU_INFO *) QUEUE_GET_HEAD(prDataPort0)); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); +#if ARP_MONITER_ENABLE + if (prAdapter->cArpNoResponseIdx >= 0) { +#if CFG_SUPPORT_DATA_STALL + KAL_REPORT_ERROR_EVENT(prAdapter, + EVENT_ARP_NO_RESPONSE, + (uint16_t)sizeof(uint32_t), + prAdapter->cArpNoResponseIdx, + FALSE); +#endif /* CFG_SUPPORT_DATA_STALL */ + aisBssBeaconTimeout(prAdapter, + prAdapter->cArpNoResponseIdx); + prAdapter->cArpNoResponseIdx = -1; + } +#endif /* ARP_MONITER_ENABLE */ + /* post-process for dropped packets */ + if (prRetMsduInfo) { /* unable to enqueue */ + nicTxFreeMsduInfoPacket(prAdapter, prRetMsduInfo); + nicTxReturnMsduInfo(prAdapter, prRetMsduInfo); + } + } + + if (prDataPort1->u4NumElem) { + prMsduInfoHead = (struct MSDU_INFO *) QUEUE_GET_HEAD( + prDataPort1); + + if (nicTxGetFreeCmdCount(prAdapter) < + NIC_TX_CMD_INFO_RESERVED_COUNT) { + /* not enough descriptors for sending */ + u4Status = WLAN_STATUS_FAILURE; + + /* free all MSDUs */ + while (prMsduInfoHead) { + prNextMsduInfo = + (struct MSDU_INFO *) + QUEUE_GET_NEXT_ENTRY( + &prMsduInfoHead->rQueEntry); + + if (prMsduInfoHead->pfTxDoneHandler != NULL) { + prMsduInfoHead->pfTxDoneHandler( + prAdapter, prMsduInfoHead, + TX_RESULT_DROPPED_IN_DRIVER); + } + + cnmMgtPktFree(prAdapter, prMsduInfoHead); + + prMsduInfoHead = prNextMsduInfo; + } + } else { + /* send to command queue */ + while (prMsduInfoHead) { + prNextMsduInfo = + (struct MSDU_INFO *) + QUEUE_GET_NEXT_ENTRY( + &prMsduInfoHead->rQueEntry); + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, + SPIN_LOCK_CMD_RESOURCE); + QUEUE_REMOVE_HEAD( + &prAdapter->rFreeCmdList, + prCmdInfo, + struct CMD_INFO *); + KAL_RELEASE_SPIN_LOCK(prAdapter, + SPIN_LOCK_CMD_RESOURCE); + + if (prCmdInfo) { + GLUE_INC_REF_CNT( + prTxCtrl->i4TxMgmtPendingNum); + + kalMemZero(prCmdInfo, + sizeof(struct CMD_INFO)); + +#if CFG_ENABLE_PKT_LIFETIME_PROFILE + /* Tag MGMT enqueue time */ + GET_CURRENT_SYSTIME( + &prMsduInfoHead-> + rPktProfile.rEnqueueTimestamp); +#endif + prCmdInfo->eCmdType = + COMMAND_TYPE_MANAGEMENT_FRAME; + prCmdInfo->u2InfoBufLen = + prMsduInfoHead->u2FrameLength; + prCmdInfo->pucInfoBuffer = NULL; + prCmdInfo->prMsduInfo = prMsduInfoHead; + prCmdInfo->pfCmdDoneHandler = NULL; + prCmdInfo->pfCmdTimeoutHandler = NULL; + prCmdInfo->fgIsOid = FALSE; + prCmdInfo->fgSetQuery = TRUE; + prCmdInfo->fgNeedResp = FALSE; + prCmdInfo->ucCmdSeqNum = + prMsduInfoHead->ucTxSeqNum; + + DBGLOG(TX, TRACE, + "%s: EN-Q MSDU[0x%p] SEQ[%u] BSS[%u] STA[%u] to CMD Q\n", + __func__, prMsduInfoHead, + prMsduInfoHead->ucTxSeqNum, + prMsduInfoHead->ucBssIndex, + prMsduInfoHead->ucStaRecIndex); + + kalEnqueueCommand(prAdapter->prGlueInfo, + (struct QUE_ENTRY *) prCmdInfo); + } else { + /* Cmd free count is larger than + * expected, but allocation fail. + */ + u4Status = WLAN_STATUS_FAILURE; + + if (prMsduInfoHead->pfTxDoneHandler + != NULL) { + prMsduInfoHead->pfTxDoneHandler( + prAdapter, + prMsduInfoHead, + TX_RESULT_DROPPED_IN_DRIVER); + } + + cnmMgtPktFree(prAdapter, + prMsduInfoHead); + } + + prMsduInfoHead = prNextMsduInfo; + } + } + } + + /* indicate service thread for sending */ + if (prTxCtrl->i4TxMgmtPendingNum > 0 + || kalGetTxPendingFrameCount(prAdapter->prGlueInfo) > 0) + kalSetEvent(prAdapter->prGlueInfo); + + return u4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief this function returns WLAN index + * + * @param prAdapter Pointer to the Adapter structure. + * + * @retval + */ +/*----------------------------------------------------------------------------*/ +uint8_t nicTxGetWlanIdx(struct ADAPTER *prAdapter, + uint8_t ucBssIdx, uint8_t ucStaRecIdx) +{ + struct STA_RECORD *prStaRec; + struct BSS_INFO *prBssInfo; + uint8_t ucWlanIndex = prAdapter->ucTxDefaultWlanIndex; + + prStaRec = cnmGetStaRecByIndex(prAdapter, ucStaRecIdx); + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIdx); + + if (prStaRec) + ucWlanIndex = prStaRec->ucWlanIndex; + else if ((ucStaRecIdx == STA_REC_INDEX_BMCAST) + && prBssInfo->fgIsInUse) { + if (prBssInfo->fgBcDefaultKeyExist) { + if (prBssInfo->wepkeyUsed[prBssInfo->ucBcDefaultKeyIdx] + && prBssInfo->wepkeyWlanIdx + < prAdapter->ucTxDefaultWlanIndex) + ucWlanIndex = prBssInfo->wepkeyWlanIdx; + else if (prBssInfo->ucBMCWlanIndexSUsed[ + prBssInfo->ucBcDefaultKeyIdx]) + ucWlanIndex = + prBssInfo->ucBMCWlanIndexS[ + prBssInfo->ucBcDefaultKeyIdx]; + } else + ucWlanIndex = prBssInfo->ucBMCWlanIndex; + } + + if (ucWlanIndex >= WTBL_SIZE) { + DBGLOG(TX, WARN, + "Unexpected WIDX[%u] BSS[%u] STA[%u], set WIDX to default value[%u]\n", + ucWlanIndex, ucBssIdx, ucStaRecIdx, + prAdapter->ucTxDefaultWlanIndex); + + ucWlanIndex = prAdapter->ucTxDefaultWlanIndex; + } + + return ucWlanIndex; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * @param prAdapter Pointer to the Adapter structure. + * + * @retval + */ +/*----------------------------------------------------------------------------*/ +u_int8_t nicTxIsMgmtResourceEnough(IN struct ADAPTER + *prAdapter) +{ + if (nicTxGetFreeCmdCount(prAdapter) > + (CFG_TX_MAX_CMD_PKT_NUM / 2)) + return TRUE; + else + return FALSE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief this function returns available count in command queue + * + * @param prAdapter Pointer to the Adapter structure. + * + * @retval + */ +/*----------------------------------------------------------------------------*/ +uint32_t nicTxGetFreeCmdCount(IN struct ADAPTER *prAdapter) +{ + ASSERT(prAdapter); + + return prAdapter->rFreeCmdList.u4NumElem; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief this function returns page count of frame + * + * @param prAdapter Pointer to the Adapter structure. + * @param u4FrameLength frame length + * + * @retval page count of this frame + */ +/*----------------------------------------------------------------------------*/ +uint32_t nicTxGetPageCount(IN struct ADAPTER *prAdapter, + IN uint32_t u4FrameLength, IN u_int8_t fgIncludeDesc) +{ + return halTxGetPageCount(prAdapter, u4FrameLength, + fgIncludeDesc); +} + +uint32_t nicTxGetCmdPageCount(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo) +{ + uint32_t u4PageCount; + + switch (prCmdInfo->eCmdType) { + case COMMAND_TYPE_NETWORK_IOCTL: + case COMMAND_TYPE_GENERAL_IOCTL: + u4PageCount = nicTxGetPageCount(prAdapter, + prCmdInfo->u2InfoBufLen, TRUE); + break; + + case COMMAND_TYPE_SECURITY_FRAME: + case COMMAND_TYPE_MANAGEMENT_FRAME: + case COMMAND_TYPE_DATA_FRAME: + /* No TxD append field for management packet */ + u4PageCount = nicTxGetPageCount(prAdapter, + prCmdInfo->u2InfoBufLen + + NIC_TX_DESC_LONG_FORMAT_LENGTH, + TRUE); + break; + + default: + DBGLOG(INIT, WARN, "Undefined CMD Type(%u)\n", + prCmdInfo->eCmdType); + u4PageCount = nicTxGetPageCount(prAdapter, + prCmdInfo->u2InfoBufLen, FALSE); + break; + } + + return u4PageCount; +} + +void nicTxSetMngPacket(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo, + uint8_t ucBssIndex, uint8_t ucStaRecIndex, + uint8_t ucMacHeaderLength, + uint16_t u2FrameLength, + PFN_TX_DONE_HANDLER pfTxDoneHandler, + uint8_t ucRateMode) +{ + static uint16_t u2SwSn; + ASSERT(prMsduInfo); + + prMsduInfo->ucBssIndex = ucBssIndex; + prMsduInfo->ucStaRecIndex = ucStaRecIndex; + prMsduInfo->ucMacHeaderLength = ucMacHeaderLength; + prMsduInfo->u2FrameLength = u2FrameLength; + prMsduInfo->pfTxDoneHandler = pfTxDoneHandler; + prMsduInfo->ucRateMode = ucRateMode; + + /* Reset default value for MMPDU */ + prMsduInfo->fgIs802_11 = TRUE; + prMsduInfo->fgIs802_1x = FALSE; + prMsduInfo->fgIs802_1x_NonProtected = + TRUE; /*For data frame only, no sense for management frame*/ + prMsduInfo->u4FixedRateOption = 0; + prMsduInfo->cPowerOffset = 0; + prMsduInfo->u4Option = 0; + prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); + prMsduInfo->ucPID = NIC_TX_DESC_PID_RESERVED; + prMsduInfo->ucPacketType = TX_PACKET_TYPE_MGMT; + prMsduInfo->ucUserPriority = 0; + prMsduInfo->eSrc = TX_PACKET_MGMT; + u2SwSn++; + if (u2SwSn > 4095) + u2SwSn = 0; + nicTxSetPktSequenceNumber(prMsduInfo, u2SwSn); +} + +void nicTxSetDataPacket(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo, + uint8_t ucBssIndex, uint8_t ucStaRecIndex, + uint8_t ucMacHeaderLength, + uint16_t u2FrameLength, PFN_TX_DONE_HANDLER pfTxDoneHandler, + uint8_t ucRateMode, enum ENUM_TX_PACKET_SRC eSrc, + uint8_t ucTID, + u_int8_t fgIs802_11Frame, u_int8_t fgIs1xFrame) +{ + ASSERT(prMsduInfo); + + prMsduInfo->ucBssIndex = ucBssIndex; + prMsduInfo->ucStaRecIndex = ucStaRecIndex; + prMsduInfo->ucMacHeaderLength = ucMacHeaderLength; + prMsduInfo->u2FrameLength = u2FrameLength; + prMsduInfo->pfTxDoneHandler = pfTxDoneHandler; + prMsduInfo->ucRateMode = ucRateMode; + prMsduInfo->ucUserPriority = ucTID; + prMsduInfo->fgIs802_11 = fgIs802_11Frame; + prMsduInfo->eSrc = eSrc; + prMsduInfo->fgIs802_1x = fgIs1xFrame; + + /* Reset default value for data packet */ + prMsduInfo->u4FixedRateOption = 0; + prMsduInfo->cPowerOffset = 0; + prMsduInfo->u4Option = 0; + prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); + prMsduInfo->ucPID = NIC_TX_DESC_PID_RESERVED; + prMsduInfo->ucPacketType = TX_PACKET_TYPE_DATA; +} + +void nicTxFillDescByPktOption( + struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo, + void *prTxDesc) +{ + struct TX_DESC_OPS_T *prTxDescOps = prAdapter->chip_info->prTxDescOps; + + if (prTxDescOps->nic_txd_fill_by_pkt_option) + prTxDescOps->nic_txd_fill_by_pkt_option( + prMsduInfo, + prTxDesc); + else + DBGLOG(TX, ERROR, "%s:: no nic_txd_fill_by_pkt_option??\n", + __func__); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Extra configuration for Tx packet + * + * @retval + */ +/*----------------------------------------------------------------------------*/ +void nicTxConfigPktOption(struct MSDU_INFO *prMsduInfo, + uint32_t u4OptionMask, u_int8_t fgSetOption) +{ + if (fgSetOption) + prMsduInfo->u4Option |= u4OptionMask; + else + prMsduInfo->u4Option &= ~u4OptionMask; +} + +void nicTxConfigPktControlFlag(struct MSDU_INFO *prMsduInfo, + uint8_t ucControlFlagMask, u_int8_t fgSetFlag) +{ + /* Set control flag */ + if (fgSetFlag) + prMsduInfo->ucControlFlag |= ucControlFlagMask; + else + prMsduInfo->ucControlFlag &= + ~ucControlFlagMask; /* Clear control flag */ +} + +void nicTxSetPktLifeTime(struct MSDU_INFO *prMsduInfo, + uint32_t u4TxLifeTimeInMs) +{ + prMsduInfo->u4RemainingLifetime = u4TxLifeTimeInMs; + prMsduInfo->u4Option |= MSDU_OPT_MANUAL_LIFE_TIME; +} + +void nicTxSetPktRetryLimit(struct MSDU_INFO *prMsduInfo, + uint8_t ucRetryLimit) +{ + prMsduInfo->ucRetryLimit = ucRetryLimit; + prMsduInfo->u4Option |= MSDU_OPT_MANUAL_RETRY_LIMIT; +} + +void nicTxSetForceRts(IN struct MSDU_INFO *prMsduInfo, + int8_t fgForceRts) +{ + if (fgForceRts) + prMsduInfo->u4Option |= MSDU_OPT_FORCE_RTS; + else + prMsduInfo->u4Option &= ~MSDU_OPT_FORCE_RTS; +} + +void nicTxSetPktPowerOffset(struct MSDU_INFO *prMsduInfo, + int8_t cPowerOffset) +{ + prMsduInfo->cPowerOffset = cPowerOffset; + prMsduInfo->u4Option |= MSDU_OPT_MANUAL_POWER_OFFSET; +} + +void nicTxSetPktSequenceNumber(struct MSDU_INFO *prMsduInfo, + uint16_t u2SN) +{ + prMsduInfo->u2SwSN = u2SN; + prMsduInfo->u4Option |= MSDU_OPT_MANUAL_SN; +} + +void nicTxSetPktMacTxQue(struct MSDU_INFO *prMsduInfo, + uint8_t ucMacTxQue) +{ + uint8_t ucTcIdx; + + for (ucTcIdx = TC0_INDEX; ucTcIdx < TC_NUM; ucTcIdx++) { + if (arTcResourceControl[ucTcIdx].ucDestQueueIndex == + ucMacTxQue) + break; + } + + if (ucTcIdx < TC_NUM) { + prMsduInfo->ucTC = ucTcIdx; + prMsduInfo->u4Option |= MSDU_OPT_MANUAL_TX_QUE; + } +} + +void nicTxSetPktFixedRateOptionFull( + struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo, + uint16_t u2RateCode, + uint8_t ucBandwidth, + u_int8_t fgShortGI, + u_int8_t fgLDPC, + u_int8_t fgDynamicBwRts, + u_int8_t fgBeamforming, + uint8_t ucAntennaIndex) +{ + struct TX_DESC_OPS_T *prTxDescOps = prAdapter->chip_info->prTxDescOps; + + if (prTxDescOps->nic_txd_set_pkt_fixed_rate_option_full) + prTxDescOps->nic_txd_set_pkt_fixed_rate_option_full( + prMsduInfo, + u2RateCode, + ucBandwidth, + fgShortGI, + fgLDPC, + fgDynamicBwRts, + fgBeamforming, + ucAntennaIndex); + else + DBGLOG(TX, ERROR, + "%s:: no nic_txd_set_pkt_fixed_rate_option_full??\n", + __func__); +} + +void nicTxSetPktFixedRateOption( + struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo, + uint16_t u2RateCode, + uint8_t ucBandwidth, + u_int8_t fgShortGI, + u_int8_t fgDynamicBwRts) +{ + struct TX_DESC_OPS_T *prTxDescOps = prAdapter->chip_info->prTxDescOps; + + if (prTxDescOps->nic_txd_set_pkt_fixed_rate_option) + prTxDescOps->nic_txd_set_pkt_fixed_rate_option( + prMsduInfo, + u2RateCode, + ucBandwidth, + fgShortGI, + fgDynamicBwRts); + else + DBGLOG(TX, ERROR, + "%s:: no nicTxSetPktFixedRateOption??\n", + __func__); +} + +void nicTxSetPktLowestFixedRate(IN struct ADAPTER + *prAdapter, IN struct MSDU_INFO *prMsduInfo) +{ + struct BSS_INFO *prBssInfo = GET_BSS_INFO_BY_INDEX( + prAdapter, prMsduInfo->ucBssIndex); + struct STA_RECORD *prStaRec = cnmGetStaRecByIndex(prAdapter, + prMsduInfo->ucStaRecIndex); + uint8_t ucRateSwIndex, ucRateIndex, ucRatePreamble; + uint16_t u2RateCode, u2RateCodeLimit, u2OperationalRateSet; + uint32_t u4CurrentPhyRate, u4Status; + + /* Not to use TxD template for fixed rate */ + prMsduInfo->fgIsTXDTemplateValid = FALSE; + + /* Fixed Rate */ + prMsduInfo->ucRateMode = MSDU_RATE_MODE_MANUAL_DESC; + + if (prStaRec) { + u2RateCode = prStaRec->u2HwDefaultFixedRateCode; + u2OperationalRateSet = prStaRec->u2OperationalRateSet; + } else { + u2RateCode = prBssInfo->u2HwDefaultFixedRateCode; + u2OperationalRateSet = prBssInfo->u2OperationalRateSet; + } + + /* CoexPhyRateLimit is 0 means phy rate is unlimited */ + if (prBssInfo->u4CoexPhyRateLimit != 0) { + + u4CurrentPhyRate = nicRateCode2PhyRate(u2RateCode, + FIX_BW_NO_FIXED, MAC_GI_NORMAL, AR_SS_NULL); + + if (prBssInfo->u4CoexPhyRateLimit > u4CurrentPhyRate) { + nicGetRateIndexFromRateSetWithLimit( + u2OperationalRateSet, + prBssInfo->u4CoexPhyRateLimit, + TRUE, &ucRateSwIndex); + + /* Convert SW rate index to rate code */ + nicSwIndex2RateIndex(ucRateSwIndex, &ucRateIndex, + &ucRatePreamble); + u4Status = nicRateIndex2RateCode(ucRatePreamble, + ucRateIndex, &u2RateCodeLimit); + if (u4Status == WLAN_STATUS_SUCCESS) { + /* Replace by limitation rate */ + u2RateCode = u2RateCodeLimit; + DBGLOG(NIC, INFO, + "Coex RatePreamble=%d, R_SW_IDX:%d, R_CODE:0x%x\n", + ucRatePreamble, ucRateIndex, u2RateCode); + } + } + } + nicTxSetPktFixedRateOption(prAdapter, prMsduInfo, u2RateCode, + FIX_BW_NO_FIXED, FALSE, FALSE); +} + +void nicTxSetPktMoreData(struct MSDU_INFO + *prCurrentMsduInfo, u_int8_t fgSetMoreDataBit) +{ + struct WLAN_MAC_HEADER *prWlanMacHeader = NULL; + + if (prCurrentMsduInfo->fgIs802_11) { + prWlanMacHeader = + (struct WLAN_MAC_HEADER *) (((uint8_t *) ( + prCurrentMsduInfo->prPacket)) + MAC_TX_RESERVED_FIELD); + } + + if (fgSetMoreDataBit) { + if (!prCurrentMsduInfo->fgIs802_11) + prCurrentMsduInfo->u4Option |= MSDU_OPT_MORE_DATA; + else + prWlanMacHeader->u2FrameCtrl |= MASK_FC_MORE_DATA; + } else { + if (!prCurrentMsduInfo->fgIs802_11) + prCurrentMsduInfo->u4Option &= ~MSDU_OPT_MORE_DATA; + else + prWlanMacHeader->u2FrameCtrl &= ~MASK_FC_MORE_DATA; + } +} + +uint8_t nicTxAssignPID(IN struct ADAPTER *prAdapter, + IN uint8_t ucWlanIndex) +{ + uint8_t ucRetval; + uint8_t *pucPidPool; + + ASSERT(prAdapter); + + pucPidPool = &prAdapter->aucPidPool[ucWlanIndex]; + + ucRetval = *pucPidPool; + + /* Driver side Tx Sequence number: 1~127 */ + (*pucPidPool)++; + + if (*pucPidPool > NIC_TX_DESC_DRIVER_PID_MAX) + *pucPidPool = NIC_TX_DESC_DRIVER_PID_MIN; + + return ucRetval; +} + +void nicTxSetPktEOSP(struct MSDU_INFO *prCurrentMsduInfo, + u_int8_t fgSetEOSPBit) +{ + struct WLAN_MAC_HEADER_QOS *prWlanMacHeader = NULL; + u_int8_t fgWriteToDesc = TRUE; + + if (prCurrentMsduInfo->fgIs802_11) { + prWlanMacHeader = + (struct WLAN_MAC_HEADER_QOS *) (((uint8_t *) ( + prCurrentMsduInfo->prPacket)) + MAC_TX_RESERVED_FIELD); + fgWriteToDesc = FALSE; + } + + if (fgSetEOSPBit) { + if (fgWriteToDesc) + prCurrentMsduInfo->u4Option |= MSDU_OPT_EOSP; + else + prWlanMacHeader->u2QosCtrl |= MASK_QC_EOSP; + } else { + if (fgWriteToDesc) + prCurrentMsduInfo->u4Option &= ~MSDU_OPT_EOSP; + else + prWlanMacHeader->u2QosCtrl &= ~MASK_QC_EOSP; + } +} + +uint32_t +nicTxDummyTxDone(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN enum ENUM_TX_RESULT_CODE rTxDoneStatus) +{ + struct PERF_MONITOR *prPerMonitor = &prAdapter->rPerMonitor; + + if (rTxDoneStatus == 0) { + prPerMonitor->ulTotalTxSuccessCount++; + } else { + DBGLOG(TX, INFO, + "Msdu WIDX:PID[%u:%u] SEQ[%u] Tx Status[%u]\n", + prMsduInfo->ucWlanIndex, prMsduInfo->ucPID, + prMsduInfo->ucTxSeqNum, rTxDoneStatus); + prPerMonitor->ulTotalTxFailCount++; + } + + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Update BSS Tx Params + * + * @param prStaRec The peer + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void nicTxUpdateBssDefaultRate(struct BSS_INFO *prBssInfo) +{ + uint8_t ucLowestBasicRateIndex; + + prBssInfo->u2HwDefaultFixedRateCode = RATE_OFDM_6M; + + /* 4 <1> Find Lowest Basic Rate Index for default TX Rate of MMPDU */ + if (rateGetLowestRateIndexFromRateSet( + prBssInfo->u2BSSBasicRateSet, &ucLowestBasicRateIndex)) { + nicRateIndex2RateCode(PREAMBLE_DEFAULT_LONG_NONE, + ucLowestBasicRateIndex, + &prBssInfo->u2HwDefaultFixedRateCode); + } else { + switch (prBssInfo->ucNonHTBasicPhyType) { + case PHY_TYPE_ERP_INDEX: + case PHY_TYPE_OFDM_INDEX: + prBssInfo->u2HwDefaultFixedRateCode = RATE_OFDM_6M; + break; + + default: + prBssInfo->u2HwDefaultFixedRateCode = RATE_CCK_1M_LONG; + break; + } + } + +#if (CFG_SUPPORT_HE_ER == 1) + if (prBssInfo->ucErMode == RA_DCM) { + prBssInfo->u2HwDefaultFixedRateCode = RATE_HE_ER_DCM_MCS_0; + DBGLOG_LIMITED(TX, WARN, + "nicTxUpdateBssDefaultRate:HE_ER DCM\n"); + } else if (prBssInfo->ucErMode == RA_ER_106) { + prBssInfo->u2HwDefaultFixedRateCode = RATE_HE_ER_TONE_106_MCS_0; + DBGLOG_LIMITED(TX, WARN, + "nicTxUpdateBssDefaultRate:HE_ER 106 tone\n"); + } else { + DBGLOG_LIMITED(TX, WARN, + "nicTxUpdateBssDefaultRate:HE_ER Disable\n"); + } +#endif + +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Update StaRec Tx parameters + * + * @param prStaRec The peer + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void nicTxUpdateStaRecDefaultRate(struct ADAPTER *prAdapter, struct STA_RECORD + *prStaRec) +{ + uint8_t ucLowestBasicRateIndex; + + prStaRec->u2HwDefaultFixedRateCode = RATE_OFDM_6M; + + /* 4 <1> Find Lowest Basic Rate Index for default TX Rate of MMPDU */ + if (rateGetLowestRateIndexFromRateSet( + prStaRec->u2BSSBasicRateSet, &ucLowestBasicRateIndex)) { + nicRateIndex2RateCode(PREAMBLE_DEFAULT_LONG_NONE, + ucLowestBasicRateIndex, + &prStaRec->u2HwDefaultFixedRateCode); + } else { + if (prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_SET_802_11B) + prStaRec->u2HwDefaultFixedRateCode = RATE_CCK_1M_LONG; + else if (prStaRec->ucDesiredPhyTypeSet & + PHY_TYPE_SET_802_11G) + prStaRec->u2HwDefaultFixedRateCode = RATE_OFDM_6M; + else if (prStaRec->ucDesiredPhyTypeSet & + PHY_TYPE_SET_802_11A) + prStaRec->u2HwDefaultFixedRateCode = RATE_OFDM_6M; + else if (prStaRec->ucDesiredPhyTypeSet & + PHY_TYPE_SET_802_11N) + prStaRec->u2HwDefaultFixedRateCode = RATE_MM_MCS_0; + } + +#if (CFG_SUPPORT_HE_ER == 1) + { + struct BSS_INFO *prBssInfo; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prStaRec->ucBssIndex); + + if (prBssInfo->ucErMode == RA_DCM) { + prBssInfo->u2HwDefaultFixedRateCode = + RATE_HE_ER_DCM_MCS_0; + DBGLOG_LIMITED(TX, WARN, + "nicTxUpdateStaRecDefaultRate:HE_ER DCM\n"); + } else if (prBssInfo->ucErMode == RA_ER_106) { + prBssInfo->u2HwDefaultFixedRateCode = + RATE_HE_ER_TONE_106_MCS_0; + DBGLOG_LIMITED(TX, WARN, + "nicTxUpdateStaRecDefaultRate:HE_ER 106 tone\n"); + } else { + DBGLOG_LIMITED(TX, WARN, + "nicTxUpdateStaRecDefaultRate:HE_ER Disable\n"); + } + } +#endif + +} + +void nicTxCancelSendingCmd(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo) +{ + halTxCancelSendingCmd(prAdapter, prCmdInfo); +} + +uint32_t nicTxGetMaxPageCntPerFrame(IN struct ADAPTER + *prAdapter) +{ + uint32_t page_size = halGetHifTxPageSize(prAdapter); + + /* + * want to replace + * #define NIC_TX_MAX_PAGE_PER_FRAME \ + * ((NIC_TX_DESC_AND_PADDING_LENGTH + + * NIC_TX_DESC_HEADER_PADDING_LENGTH + \ + * NIC_TX_MAX_SIZE_PER_FRAME + NIC_TX_PAGE_SIZE - 1) + * / NIC_TX_PAGE_SIZE) + */ + + return ((NIC_TX_DESC_AND_PADDING_LENGTH + + NIC_TX_DESC_HEADER_PADDING_LENGTH + + NIC_TX_MAX_SIZE_PER_FRAME + page_size - 1) / page_size); +} + +/* TX Direct functions : BEGIN */ + +/*----------------------------------------------------------------------------*/ +/* + * \brief This function is to start rTxDirectHifTimer to try to + * send out packets in + * rStaPsQueue[], rBssAbsentQueue[], rTxDirectHifQueue[]. + * + * \param[in] prAdapter Pointer of Adapter + * + * \retval none + */ +/*----------------------------------------------------------------------------*/ +void nicTxDirectStartCheckQTimer(IN struct ADAPTER + *prAdapter) +{ + mod_timer(&prAdapter->rTxDirectHifTimer, jiffies + 1); +} + +void nicTxDirectClearSkbQ(IN struct ADAPTER *prAdapter) +{ + struct GLUE_INFO *prGlueInfo = prAdapter->prGlueInfo; + struct sk_buff *prSkb; + + while (TRUE) { + spin_lock_bh(&prGlueInfo->rSpinLock[SPIN_LOCK_TX_DIRECT]); + prSkb = skb_dequeue(&prAdapter->rTxDirectSkbQueue); + spin_unlock_bh(&prGlueInfo->rSpinLock[SPIN_LOCK_TX_DIRECT]); + if (prSkb == NULL) + break; + + kalSendComplete(prGlueInfo, prSkb, + WLAN_STATUS_NOT_ACCEPTED); + } +} + +void nicTxDirectClearHifQ(IN struct ADAPTER *prAdapter) +{ + struct GLUE_INFO *prGlueInfo = prAdapter->prGlueInfo; + uint8_t ucHifTc = 0; + struct QUE rNeedToFreeQue; + struct QUE *prNeedToFreeQue = &rNeedToFreeQue; + + QUEUE_INITIALIZE(prNeedToFreeQue); + + for (ucHifTc = 0; ucHifTc < TX_PORT_NUM; ucHifTc++) { + spin_lock_bh( + &prGlueInfo->rSpinLock[SPIN_LOCK_TX_DIRECT]); + if (QUEUE_IS_NOT_EMPTY( + &prAdapter->rTxDirectHifQueue[ucHifTc])) { + QUEUE_MOVE_ALL(prNeedToFreeQue, + &prAdapter->rTxDirectHifQueue[ucHifTc]); + spin_unlock_bh( + &prGlueInfo->rSpinLock[SPIN_LOCK_TX_DIRECT]); + + wlanProcessQueuedMsduInfo(prAdapter, + (struct MSDU_INFO *) + QUEUE_GET_HEAD(prNeedToFreeQue)); + } else { + spin_unlock_bh( + &prGlueInfo->rSpinLock[SPIN_LOCK_TX_DIRECT]); + } + } +} + +void nicTxDirectClearStaPsQ(IN struct ADAPTER *prAdapter, + uint8_t ucStaRecIndex) +{ + struct GLUE_INFO *prGlueInfo = prAdapter->prGlueInfo; + struct QUE rNeedToFreeQue; + struct QUE *prNeedToFreeQue = &rNeedToFreeQue; + + QUEUE_INITIALIZE(prNeedToFreeQue); + spin_lock_bh(&prGlueInfo->rSpinLock[SPIN_LOCK_TX_DIRECT]); + if (QUEUE_IS_NOT_EMPTY( + &prAdapter->rStaPsQueue[ucStaRecIndex])) { + QUEUE_MOVE_ALL(prNeedToFreeQue, + &prAdapter->rStaPsQueue[ucStaRecIndex]); + spin_unlock_bh(&prGlueInfo->rSpinLock[SPIN_LOCK_TX_DIRECT]); + + wlanProcessQueuedMsduInfo(prAdapter, + (struct MSDU_INFO *) QUEUE_GET_HEAD(prNeedToFreeQue)); + } else { + spin_unlock_bh(&prGlueInfo->rSpinLock[SPIN_LOCK_TX_DIRECT]); + } +} + +void nicTxDirectClearBssAbsentQ(IN struct ADAPTER + *prAdapter, uint8_t ucBssIndex) +{ + struct GLUE_INFO *prGlueInfo = prAdapter->prGlueInfo; + struct QUE rNeedToFreeQue; + struct QUE *prNeedToFreeQue = &rNeedToFreeQue; + + QUEUE_INITIALIZE(prNeedToFreeQue); + spin_lock_bh(&prGlueInfo->rSpinLock[SPIN_LOCK_TX_DIRECT]); + if (QUEUE_IS_NOT_EMPTY( + &prAdapter->rBssAbsentQueue[ucBssIndex])) { + QUEUE_MOVE_ALL(prNeedToFreeQue, + &prAdapter->rBssAbsentQueue[ucBssIndex]); + spin_unlock_bh(&prGlueInfo->rSpinLock[SPIN_LOCK_TX_DIRECT]); + + wlanProcessQueuedMsduInfo(prAdapter, + (struct MSDU_INFO *) QUEUE_GET_HEAD(prNeedToFreeQue)); + } else { + spin_unlock_bh(&prGlueInfo->rSpinLock[SPIN_LOCK_TX_DIRECT]); + } +} + +void nicTxDirectClearAllStaPsQ(IN struct ADAPTER *prAdapter) +{ + uint8_t ucStaRecIndex; + uint32_t u4StaPsBitmap; + + u4StaPsBitmap = prAdapter->u4StaPsBitmap; + + if (!u4StaPsBitmap) + return; + + for (ucStaRecIndex = 0; ucStaRecIndex < CFG_STA_REC_NUM; + ++ucStaRecIndex) { + if (QUEUE_IS_NOT_EMPTY( + &prAdapter->rStaPsQueue[ucStaRecIndex])) { + nicTxDirectClearStaPsQ(prAdapter, + ucStaRecIndex); + u4StaPsBitmap &= ~BIT(ucStaRecIndex); + } + if (u4StaPsBitmap == 0) + break; + } +} + +/*----------------------------------------------------------------------------*/ +/* + * \brief This function is to check the StaRec is in Ps or not, + * and store MsduInfo(s) or sent MsduInfo(s) to the next + * stage respectively. + * + * \param[in] prAdapter Pointer of Adapter + * \param[in] ucStaRecIndex Indictate which StaRec to be checked + * \param[in] prQue Pointer of MsduInfo queue which to be processed + * + * \retval none + */ +/*----------------------------------------------------------------------------*/ +static void nicTxDirectCheckStaPsQ(IN struct ADAPTER + *prAdapter, uint8_t ucStaRecIndex, struct QUE *prQue) +{ + struct STA_RECORD *prStaRec; /* The current focused STA */ + struct MSDU_INFO *prMsduInfo; + struct QUE_ENTRY *prQueueEntry = (struct QUE_ENTRY *) NULL; + u_int8_t fgReturnStaPsQ = FALSE; + + if (ucStaRecIndex >= CFG_STA_REC_NUM) + return; + + prStaRec = cnmGetStaRecByIndex(prAdapter, ucStaRecIndex); + + QUEUE_CONCATENATE_QUEUES( + &prAdapter->rStaPsQueue[ucStaRecIndex], prQue); + QUEUE_REMOVE_HEAD(&prAdapter->rStaPsQueue[ucStaRecIndex], + prQueueEntry, struct QUE_ENTRY *); + prMsduInfo = (struct MSDU_INFO *) prQueueEntry; + + if (prMsduInfo == NULL) { + DBGLOG(TX, INFO, "prMsduInfo empty\n"); + return; + } + + if (prStaRec == NULL) { + DBGLOG(TX, INFO, "prStaRec empty\n"); + return; + } + + if (prStaRec->fgIsInPS) { + KAL_SPIN_LOCK_DECLARATION(); + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); + DBGLOG(TX, INFO, "fgIsInPS!\n"); + while (1) { + if (prStaRec->fgIsQoS && prStaRec->fgIsUapsdSupported && + (prStaRec->ucBmpTriggerAC + & BIT(prMsduInfo->ucTC))) { + if (prStaRec->ucFreeQuotaForDelivery > 0) { + prStaRec->ucFreeQuotaForDelivery--; + QUEUE_INSERT_TAIL( + prQue, + (struct QUE_ENTRY *) + prMsduInfo); + } else { + fgReturnStaPsQ = TRUE; + break; + } + } else { + if (prStaRec->ucFreeQuotaForNonDelivery > 0) { + prStaRec->ucFreeQuotaForNonDelivery--; + QUEUE_INSERT_TAIL( + prQue, + (struct QUE_ENTRY *) + prMsduInfo); + } else { + fgReturnStaPsQ = TRUE; + break; + } + } + if (QUEUE_IS_NOT_EMPTY( + &prAdapter->rStaPsQueue[ucStaRecIndex])) { + QUEUE_REMOVE_HEAD( + &prAdapter->rStaPsQueue[ucStaRecIndex], + prQueueEntry, struct QUE_ENTRY *); + prMsduInfo = (struct MSDU_INFO *) prQueueEntry; + if (prMsduInfo == NULL) { + DBGLOG(TX, INFO, "prMsduInfo null\n"); + break; + } + } else { + break; + } + } + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); + if (fgReturnStaPsQ) { + QUEUE_INSERT_HEAD( + &prAdapter->rStaPsQueue[ucStaRecIndex], + (struct QUE_ENTRY *) prMsduInfo); + prAdapter->u4StaPsBitmap |= BIT(ucStaRecIndex); + return; + } + } else { + QUEUE_INSERT_TAIL(prQue, (struct QUE_ENTRY *) prMsduInfo); + if (QUEUE_IS_NOT_EMPTY( + &prAdapter->rStaPsQueue[ucStaRecIndex])) + QUEUE_CONCATENATE_QUEUES(prQue, + &prAdapter->rStaPsQueue[ucStaRecIndex]); + } + prAdapter->u4StaPsBitmap &= ~BIT(ucStaRecIndex); +} + +/*----------------------------------------------------------------------------*/ +/* + * \brief This function is to check the Bss is net absent or not, + * and store MsduInfo(s) or sent MsduInfo(s) to the next + * stage respectively. + * + * \param[in] prAdapter Pointer of Adapter + * \param[in] ucBssIndex Indictate which Bss to be checked + * \param[in] prQue Pointer of MsduInfo queue which to be processed + * + * \retval none + */ +/*----------------------------------------------------------------------------*/ +static void nicTxDirectCheckBssAbsentQ(IN struct ADAPTER + *prAdapter, uint8_t ucBssIndex, struct QUE *prQue) +{ + struct BSS_INFO *prBssInfo; + struct MSDU_INFO *prMsduInfo; + struct QUE_ENTRY *prQueueEntry = (struct QUE_ENTRY *) NULL; + u_int8_t fgReturnBssAbsentQ = FALSE; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + + QUEUE_CONCATENATE_QUEUES( + &prAdapter->rBssAbsentQueue[ucBssIndex], prQue); + QUEUE_REMOVE_HEAD(&prAdapter->rBssAbsentQueue[ucBssIndex], + prQueueEntry, struct QUE_ENTRY *); + prMsduInfo = (struct MSDU_INFO *) prQueueEntry; + + if (prMsduInfo == NULL) { + DBGLOG(TX, INFO, "prMsduInfo empty\n"); + return; + } + + if (prBssInfo->fgIsNetAbsent) { + KAL_SPIN_LOCK_DECLARATION(); + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); + DBGLOG(TX, INFO, "fgIsNetAbsent!\n"); + while (1) { + if (prBssInfo->ucBssFreeQuota > 0) { + prBssInfo->ucBssFreeQuota--; + QUEUE_INSERT_TAIL( + prQue, (struct QUE_ENTRY *) prMsduInfo); + DBGLOG(TX, INFO, + "fgIsNetAbsent Quota Availalbe\n"); + } else { + fgReturnBssAbsentQ = TRUE; + DBGLOG(TX, INFO, "fgIsNetAbsent NoQuota\n"); + break; + } + if (QUEUE_IS_NOT_EMPTY( + &prAdapter->rBssAbsentQueue[ucBssIndex])) { + QUEUE_REMOVE_HEAD( + &prAdapter->rBssAbsentQueue[ucBssIndex], + prQueueEntry, struct QUE_ENTRY *); + prMsduInfo = (struct MSDU_INFO *) prQueueEntry; + } else { + break; + } + } + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); + if (fgReturnBssAbsentQ) { + QUEUE_INSERT_HEAD( + &prAdapter->rBssAbsentQueue[ucBssIndex], + (struct QUE_ENTRY *) prMsduInfo); + prAdapter->u4BssAbsentBitmap |= BIT(ucBssIndex); + return; + } + } else { + if (prAdapter->u4BssAbsentBitmap) + DBGLOG(TX, INFO, "fgIsNetAbsent END!\n"); + QUEUE_INSERT_TAIL(prQue, (struct QUE_ENTRY *) prMsduInfo); + if (QUEUE_IS_NOT_EMPTY( + &prAdapter->rBssAbsentQueue[ucBssIndex])) + QUEUE_CONCATENATE_QUEUES(prQue, + &prAdapter->rBssAbsentQueue[ucBssIndex]); + } + prAdapter->u4BssAbsentBitmap &= ~BIT(ucBssIndex); +} + +/*----------------------------------------------------------------------------*/ +/* + * \brief Get Tc for hif port mapping. + * + * \param[in] prMsduInfo Pointer of the MsduInfo + * + * \retval Tc which maps to hif port. + */ +/*----------------------------------------------------------------------------*/ +static uint8_t nicTxDirectGetHifTc(struct MSDU_INFO + *prMsduInfo) +{ + uint8_t ucHifTc = 0; + + if (prMsduInfo->ucWmmQueSet == DBDC_2G_WMM_INDEX) { + ucHifTc = TX_2G_WMM_PORT_NUM; + } else { + if (prMsduInfo->ucTC >= 0 && prMsduInfo->ucTC < TC_NUM) + ucHifTc = prMsduInfo->ucTC; + else + ASSERT(0); + } + return ucHifTc; +} + +/*----------------------------------------------------------------------------*/ +/* + * \brief This function is called by nicTxDirectStartXmit() + * and nicTxDirectTimerCheckHifQ(). + * It is the main function to send skb out on HIF bus. + * + * \param[in] prSkb Pointer of the sk_buff to be sent + * \param[in] prMsduInfo Pointer of the MsduInfo + * \param[in] prAdapter Pointer of Adapter + * \param[in] ucCheckTc Indictate which Tc HifQ to be checked + * \param[in] ucStaRecIndex Indictate which StaPsQ to be checked + * \param[in] ucBssIndex Indictate which BssAbsentQ to be checked + * + * \retval WLAN_STATUS + */ +/*----------------------------------------------------------------------------*/ +static uint32_t nicTxDirectStartXmitMain(struct sk_buff + *prSkb, struct MSDU_INFO *prMsduInfo, + struct ADAPTER *prAdapter, + uint8_t ucCheckTc, uint8_t ucStaRecIndex, + uint8_t ucBssIndex) +{ + struct STA_RECORD *prStaRec; /* The current focused STA */ + struct BSS_INFO *prBssInfo; + uint8_t ucTC = 0, ucHifTc = 0; + struct QUE *prTxQue; + u_int8_t fgDropPacket = FALSE; + struct QUE_ENTRY *prQueueEntry = (struct QUE_ENTRY *) NULL; + struct QUE rProcessingQue; + struct QUE *prProcessingQue = &rProcessingQue; + uint8_t ucActivedTspec = 0; + + + QUEUE_INITIALIZE(prProcessingQue); + + ucActivedTspec = + wmmHasActiveTspec(aisGetWMMInfo(prAdapter, ucBssIndex)); + + if (prSkb) { + nicTxFillMsduInfo(prAdapter, prMsduInfo, prSkb); + + /* Tx profiling */ + wlanTxProfilingTagMsdu(prAdapter, prMsduInfo, + TX_PROF_TAG_DRV_ENQUE); + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prMsduInfo->ucBssIndex); + + if (!prBssInfo) { + /* No BSS_INFO */ + fgDropPacket = TRUE; + } else if (IS_BSS_ACTIVE(prBssInfo)) { + /* BSS active */ + fgDropPacket = FALSE; + } else { + /* BSS inactive */ + fgDropPacket = TRUE; + } + + if (fgDropPacket) { + DBGLOG(QM, TRACE, + "Drop the Packet for inactive Bss %u\n", + prMsduInfo->ucBssIndex); + QM_DBG_CNT_INC(prQM, QM_DBG_CNT_31); + TX_INC_CNT(&prAdapter->rTxCtrl, TX_INACTIVE_BSS_DROP); + + wlanProcessQueuedMsduInfo(prAdapter, prMsduInfo); + return WLAN_STATUS_FAILURE; + } + + qmDetermineStaRecIndex(prAdapter, prMsduInfo); + + wlanUpdateTxStatistics(prAdapter, prMsduInfo, + FALSE); /*get per-AC Tx packets */ + + switch (prMsduInfo->ucStaRecIndex) { + case STA_REC_INDEX_BMCAST: + ucTC = + arNetwork2TcResource[ + prMsduInfo->ucBssIndex][ + NET_TC_BMC_INDEX]; + + /* Always set BMC packet retry limit to unlimited */ + if (!(prMsduInfo->u4Option + & MSDU_OPT_MANUAL_RETRY_LIMIT)) + nicTxSetPktRetryLimit(prMsduInfo, + TX_DESC_TX_COUNT_NO_LIMIT); + + QM_DBG_CNT_INC(prQM, QM_DBG_CNT_23); + break; + case STA_REC_INDEX_NOT_FOUND: + /* Drop packet if no STA_REC is found */ + DBGLOG(QM, TRACE, "Drop the Packet for no STA_REC\n"); + + TX_INC_CNT(&prAdapter->rTxCtrl, TX_INACTIVE_STA_DROP); + QM_DBG_CNT_INC(prQM, QM_DBG_CNT_24); + wlanProcessQueuedMsduInfo(prAdapter, prMsduInfo); + return WLAN_STATUS_FAILURE; + default: + prTxQue = qmDetermineStaTxQueue(prAdapter, prMsduInfo, + ucActivedTspec, &ucTC); + break; /*default */ + } /* switch (prMsduInfo->ucStaRecIndex) */ + + prMsduInfo->ucTC = ucTC; + prMsduInfo->ucWmmQueSet = + prBssInfo->ucWmmQueSet; /* to record WMM Set */ + + /* Check the Tx descriptor template is valid */ + qmSetTxPacketDescTemplate(prAdapter, prMsduInfo); + + /* Set Tx rate */ + switch (prAdapter->rWifiVar.ucDataTxRateMode) { + case DATA_RATE_MODE_BSS_LOWEST: + nicTxSetPktLowestFixedRate(prAdapter, prMsduInfo); + break; + + case DATA_RATE_MODE_MANUAL: + prMsduInfo->u4FixedRateOption = + prAdapter->rWifiVar.u4DataTxRateCode; + + prMsduInfo->ucRateMode = MSDU_RATE_MODE_MANUAL_DESC; + break; + + case DATA_RATE_MODE_AUTO: + default: + if (prMsduInfo->ucRateMode + == MSDU_RATE_MODE_LOWEST_RATE) + nicTxSetPktLowestFixedRate( + prAdapter, prMsduInfo); + break; + } + + nicTxFillDataDesc(prAdapter, prMsduInfo); + + prStaRec = cnmGetStaRecByIndex(prAdapter, + prMsduInfo->ucStaRecIndex); + + QUEUE_INSERT_TAIL(prProcessingQue, + (struct QUE_ENTRY *) prMsduInfo); + + /* Power-save STA handling */ + nicTxDirectCheckStaPsQ(prAdapter, prMsduInfo->ucStaRecIndex, + prProcessingQue); + + /* Absent BSS handling */ + nicTxDirectCheckBssAbsentQ(prAdapter, + prMsduInfo->ucBssIndex, prProcessingQue); + + if (QUEUE_IS_EMPTY(prProcessingQue)) + return WLAN_STATUS_SUCCESS; + + if (prProcessingQue->u4NumElem != 1) { + while (1) { + QUEUE_REMOVE_HEAD(prProcessingQue, prQueueEntry, + struct QUE_ENTRY *); + if (prQueueEntry == NULL) + break; + prMsduInfo = (struct MSDU_INFO *) prQueueEntry; + ucHifTc = nicTxDirectGetHifTc(prMsduInfo); + QUEUE_INSERT_TAIL( + &prAdapter->rTxDirectHifQueue[ucHifTc], + (struct QUE_ENTRY *) prMsduInfo); + } + nicTxDirectStartCheckQTimer(prAdapter); + return WLAN_STATUS_SUCCESS; + } + + QUEUE_REMOVE_HEAD(prProcessingQue, prQueueEntry, + struct QUE_ENTRY *); + prMsduInfo = (struct MSDU_INFO *) prQueueEntry; + ucHifTc = nicTxDirectGetHifTc(prMsduInfo); + + if (QUEUE_IS_NOT_EMPTY( + &prAdapter->rTxDirectHifQueue[ucHifTc])) { + QUEUE_INSERT_TAIL( + &prAdapter->rTxDirectHifQueue[ucHifTc], + (struct QUE_ENTRY *) prMsduInfo); + QUEUE_REMOVE_HEAD( + &prAdapter->rTxDirectHifQueue[ucHifTc], + prQueueEntry, struct QUE_ENTRY *); + prMsduInfo = (struct MSDU_INFO *) prQueueEntry; + } + } else { + if (ucStaRecIndex != 0xff || ucBssIndex != 0xff) { + /* Power-save STA handling */ + if (ucStaRecIndex != 0xff) + nicTxDirectCheckStaPsQ(prAdapter, ucStaRecIndex, + prProcessingQue); + + /* Absent BSS handling */ + if (ucBssIndex != 0xff) + nicTxDirectCheckBssAbsentQ( + prAdapter, ucBssIndex, + prProcessingQue); + + if (QUEUE_IS_EMPTY(prProcessingQue)) + return WLAN_STATUS_SUCCESS; + + if (prProcessingQue->u4NumElem != 1) { + while (1) { + QUEUE_REMOVE_HEAD( + prProcessingQue, prQueueEntry, + struct QUE_ENTRY *); + if (prQueueEntry == NULL) + break; + prMsduInfo = + (struct MSDU_INFO *) + prQueueEntry; + ucHifTc = + nicTxDirectGetHifTc(prMsduInfo); + QUEUE_INSERT_TAIL( + &prAdapter-> + rTxDirectHifQueue[ucHifTc], + (struct QUE_ENTRY *) + prMsduInfo); + } + nicTxDirectStartCheckQTimer(prAdapter); + return WLAN_STATUS_SUCCESS; + } + + QUEUE_REMOVE_HEAD(prProcessingQue, prQueueEntry, + struct QUE_ENTRY *); + prMsduInfo = (struct MSDU_INFO *) prQueueEntry; + ucHifTc = nicTxDirectGetHifTc(prMsduInfo); + } else { + if (ucCheckTc != 0xff) + ucHifTc = ucCheckTc; + + if (QUEUE_IS_EMPTY( + &prAdapter->rTxDirectHifQueue[ucHifTc])) { + DBGLOG(TX, INFO, + "ERROR: no rTxDirectHifQueue (%u)\n", + ucHifTc); + return WLAN_STATUS_FAILURE; + } + QUEUE_REMOVE_HEAD( + &prAdapter->rTxDirectHifQueue[ucHifTc], + prQueueEntry, struct QUE_ENTRY *); + prMsduInfo = (struct MSDU_INFO *) prQueueEntry; + } + } + + while (1) { + if (!halTxIsDataBufEnough(prAdapter, prMsduInfo)) { + QUEUE_INSERT_HEAD( + &prAdapter->rTxDirectHifQueue[ucHifTc], + (struct QUE_ENTRY *) prMsduInfo); + mod_timer(&prAdapter->rTxDirectHifTimer, + jiffies + TX_DIRECT_CHECK_INTERVAL); + + return WLAN_STATUS_SUCCESS; + } + + if (prMsduInfo->pfTxDoneHandler) { + KAL_SPIN_LOCK_DECLARATION(); + + /* Record native packet pointer for Tx done log */ + WLAN_GET_FIELD_32(&prMsduInfo->prPacket, + &prMsduInfo->u4TxDoneTag); + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, + SPIN_LOCK_TXING_MGMT_LIST); + QUEUE_INSERT_TAIL( + &(prAdapter->rTxCtrl.rTxMgmtTxingQueue), + (struct QUE_ENTRY *) prMsduInfo); + KAL_RELEASE_SPIN_LOCK(prAdapter, + SPIN_LOCK_TXING_MGMT_LIST); + } + HAL_WRITE_TX_DATA(prAdapter, prMsduInfo); + + if (QUEUE_IS_NOT_EMPTY( + &prAdapter->rTxDirectHifQueue[ucHifTc])) { + QUEUE_REMOVE_HEAD( + &prAdapter->rTxDirectHifQueue[ucHifTc], + prQueueEntry, struct QUE_ENTRY *); + prMsduInfo = (struct MSDU_INFO *) prQueueEntry; + if (prMsduInfo == NULL) { + DBGLOG(TX, WARN, + "prMsduInfo is NULL\n"); + break; + } + } else { + break; + } + } + + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/* + * \brief This function is the timeout function of timer rTxDirectSkbTimer. + * The purpose is to check if rTxDirectSkbQueue has any skb to be sent. + * + * \param[in] data Pointer of GlueInfo + * + * \retval none + */ +/*----------------------------------------------------------------------------*/ +#if KERNEL_VERSION(4, 15, 0) <= LINUX_VERSION_CODE +void nicTxDirectTimerCheckSkbQ(struct timer_list *timer) +#else +void nicTxDirectTimerCheckSkbQ(unsigned long data) +#endif + +{ +#if KERNEL_VERSION(4, 15, 0) <= LINUX_VERSION_CODE + struct ADAPTER *prAdapter = + from_timer(prAdapter, timer, rTxDirectSkbTimer); + struct GLUE_INFO *prGlueInfo = prAdapter->prGlueInfo; +#else + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *)data; + struct ADAPTER *prAdapter = prGlueInfo->prAdapter; +#endif + if (skb_queue_len(&prAdapter->rTxDirectSkbQueue)) + nicTxDirectStartXmit(NULL, prGlueInfo); + else + DBGLOG(TX, INFO, "fgHasNoMsdu FALSE\n"); +} + +/*----------------------------------------------------------------------------*/ +/* + * \brief This function is the timeout function of timer rTxDirectHifTimer. + * The purpose is to check if rStaPsQueue, rBssAbsentQueue, + * and rTxDirectHifQueue has any MsduInfo to be sent. + * + * \param[in] data Pointer of GlueInfo + * + * \retval none + */ +/*----------------------------------------------------------------------------*/ +#if KERNEL_VERSION(4, 15, 0) <= LINUX_VERSION_CODE +void nicTxDirectTimerCheckHifQ(struct timer_list *timer) +#else +void nicTxDirectTimerCheckHifQ(unsigned long data) +#endif +{ +#if KERNEL_VERSION(4, 15, 0) <= LINUX_VERSION_CODE + struct ADAPTER *prAdapter = + from_timer(prAdapter, timer, rTxDirectHifTimer); + struct GLUE_INFO *prGlueInfo = prAdapter->prGlueInfo; +#else + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *)data; + struct ADAPTER *prAdapter = prGlueInfo->prAdapter; +#endif + uint8_t ucHifTc = 0; + uint32_t u4StaPsBitmap, u4BssAbsentBitmap; + uint8_t ucStaRecIndex, ucBssIndex; + + spin_lock_bh(&prGlueInfo->rSpinLock[SPIN_LOCK_TX_DIRECT]); + + u4StaPsBitmap = prAdapter->u4StaPsBitmap; + u4BssAbsentBitmap = prAdapter->u4BssAbsentBitmap; + + if (u4StaPsBitmap) + for (ucStaRecIndex = 0; ucStaRecIndex < CFG_STA_REC_NUM; + ++ucStaRecIndex) { + if (QUEUE_IS_NOT_EMPTY( + &prAdapter->rStaPsQueue[ucStaRecIndex])) { + nicTxDirectStartXmitMain(NULL, NULL, prAdapter, + 0xff, ucStaRecIndex, 0xff); + u4StaPsBitmap &= ~BIT(ucStaRecIndex); + DBGLOG(TX, INFO, + "ucStaRecIndex: %u\n", ucStaRecIndex); + } + if (u4StaPsBitmap == 0) + break; + } + + if (u4BssAbsentBitmap) + for (ucBssIndex = 0; ucBssIndex < MAX_BSSID_NUM + 1; + ++ucBssIndex) { + if (QUEUE_IS_NOT_EMPTY( + &prAdapter->rBssAbsentQueue[ucBssIndex])) { + nicTxDirectStartXmitMain(NULL, NULL, prAdapter, + 0xff, 0xff, ucBssIndex); + u4BssAbsentBitmap &= ~BIT(ucBssIndex); + DBGLOG(TX, INFO, + "ucBssIndex: %u\n", ucBssIndex); + } + if (u4BssAbsentBitmap == 0) + break; + } + + + for (ucHifTc = 0; ucHifTc < TX_PORT_NUM; ucHifTc++) + if (QUEUE_IS_NOT_EMPTY( + &prAdapter->rTxDirectHifQueue[ucHifTc])) + nicTxDirectStartXmitMain(NULL, NULL, prAdapter, ucHifTc, + 0xff, 0xff); + + spin_unlock_bh(&prGlueInfo->rSpinLock[SPIN_LOCK_TX_DIRECT]); +} + +/*----------------------------------------------------------------------------*/ +/* + * \brief This function is have to called by kalHardStartXmit(). + * The purpose is to let as many as possible TX processing in softirq + * instead of in kernel thread to reduce TX CPU usage. + * NOTE: Currently only USB interface can use this function. + * + * \param[in] prSkb Pointer of the sk_buff to be sent + * \param[in] prGlueInfo Pointer of prGlueInfo + * + * \retval WLAN_STATUS + */ +/*----------------------------------------------------------------------------*/ +uint32_t nicTxDirectStartXmit(struct sk_buff *prSkb, + struct GLUE_INFO *prGlueInfo) +{ + struct ADAPTER *prAdapter = prGlueInfo->prAdapter; + struct MSDU_INFO *prMsduInfo; + uint32_t ret = WLAN_STATUS_SUCCESS; + + spin_lock_bh(&prGlueInfo->rSpinLock[SPIN_LOCK_TX_DIRECT]); + + if (prSkb) { + prMsduInfo = cnmPktAlloc(prAdapter, 0); + + if (prMsduInfo == NULL) { + DBGLOG(TX, INFO, "cnmPktAlloc NULL\n"); + skb_queue_tail(&prAdapter->rTxDirectSkbQueue, prSkb); + + ret = WLAN_STATUS_SUCCESS; + goto end; + } + if (skb_queue_len(&prAdapter->rTxDirectSkbQueue)) { + skb_queue_tail(&prAdapter->rTxDirectSkbQueue, prSkb); + prSkb = skb_dequeue(&prAdapter->rTxDirectSkbQueue); + } + } else { + prMsduInfo = cnmPktAlloc(prAdapter, 0); + if (prMsduInfo != NULL) { + prSkb = skb_dequeue(&prAdapter->rTxDirectSkbQueue); + if (prSkb == NULL) { + DBGLOG(TX, INFO, + "ERROR: no rTxDirectSkbQueue\n"); + nicTxReturnMsduInfo(prAdapter, prMsduInfo); + ret = WLAN_STATUS_FAILURE; + goto end; + } + } else { + ret = WLAN_STATUS_FAILURE; + goto end; + } + } + + while (1) { + nicTxDirectStartXmitMain(prSkb, prMsduInfo, prAdapter, 0xff, + 0xff, 0xff); + prSkb = skb_dequeue(&prAdapter->rTxDirectSkbQueue); + if (prSkb != NULL) { + prMsduInfo = cnmPktAlloc(prAdapter, 0); + if (prMsduInfo == NULL) { + skb_queue_head(&prAdapter->rTxDirectSkbQueue, + prSkb); + break; + } + } else { + break; + } + } + +end: + if (skb_queue_len(&prAdapter->rTxDirectSkbQueue)) + mod_timer(&prAdapter->rTxDirectSkbTimer, + jiffies + TX_DIRECT_CHECK_INTERVAL); + spin_unlock_bh(&prGlueInfo->rSpinLock[SPIN_LOCK_TX_DIRECT]); + return ret; +} +/* TX Direct functions : END */ + + +/*----------------------------------------------------------------------------*/ +/* + * \brief Assign Tc resource to prWifiVar according to firmware's report + * + * \param[in] prSkb Pointer of the sk_buff to be sent + * \param[in] prGlueInfo Pointer of prGlueInfo + * + */ +/*----------------------------------------------------------------------------*/ + +void nicTxResourceUpdate_v1(IN struct ADAPTER *prAdapter) +{ + uint8_t string[128], idx, i, tc_num, ret = 0; + uint32_t u4share, u4remains; + struct WIFI_VAR *prWifiVar = &prAdapter->rWifiVar; + uint32_t *pau4TcPageCount; +#if QM_ADAPTIVE_TC_RESOURCE_CTRL + struct QUE_MGT *prQM = &prAdapter->rQM; +#endif + + + /* + * Use the settings in config file first, + * else, use the settings reported from firmware. + */ + + + /* + * 1. assign PSE/PLE free page count for each TC + */ + + tc_num = (TC_NUM - 1); /* except TC4_INDEX */ + for (i = 0; i < 2; i++) { + if (i == 0) { + /* PSE CMD*/ + prWifiVar->au4TcPageCount[TC4_INDEX] = + prAdapter->nicTxReousrce.u4CmdTotalResource; + + /* calculate PSE free page count for each TC, + * except TC_4 + */ + u4share = prAdapter->nicTxReousrce.u4DataTotalResource / + tc_num; + u4remains = prAdapter->nicTxReousrce. + u4DataTotalResource % tc_num; + pau4TcPageCount = prWifiVar->au4TcPageCount; + } else { + /* PLE CMD*/ + prWifiVar->au4TcPageCountPle[TC4_INDEX] = + prAdapter->nicTxReousrce.u4CmdTotalResourcePle; + + /* calculate PLE free page count for each TC, + * except TC_4 + */ + u4share = prAdapter->nicTxReousrce. + u4DataTotalResourcePle / tc_num; + u4remains = prAdapter->nicTxReousrce. + u4DataTotalResourcePle % tc_num; + pau4TcPageCount = prWifiVar->au4TcPageCountPle; + } + + /* assign free page count for each TC, except TC_4 */ + for (idx = TC0_INDEX; idx < TC_NUM; idx++) { + if (idx != TC4_INDEX) + pau4TcPageCount[idx] = u4share; + } + /* if there is remaings, give them to TC_3, which is VO */ + pau4TcPageCount[TC3_INDEX] += u4remains; + } + + +#if QM_ADAPTIVE_TC_RESOURCE_CTRL + /* + * 2. assign guaranteed page count for each TC + */ + + /* 2 1. update guaranteed page count in QM */ + for (idx = 0; idx < TC_NUM; idx++) + prQM->au4GuaranteedTcResource[idx] = + prWifiVar->au4TcPageCount[idx]; +#endif + + + +#if CFG_SUPPORT_CFG_FILE + /* + * 3. Use the settings in config file first, + * else, use the settings reported from firmware. + */ + + /* 3 1. update for free page count */ + for (idx = 0; idx < TC_NUM; idx++) { + + /* construct prefix: Tc0Page, Tc1Page... */ + memset(string, 0, sizeof(string) / sizeof(uint8_t)); + ret = snprintf(string, sizeof(string) / sizeof(uint8_t), + "Tc%xPage", idx); + if (ret > (sizeof(string) / sizeof(uint8_t))) { + DBGLOG(NIC, INFO, + "sprintf failed of page count:%d\n", ret); + } else { + /* update the final value */ + prWifiVar->au4TcPageCount[idx] = + (uint32_t) wlanCfgGetUint32(prAdapter, + string, prWifiVar->au4TcPageCount[idx]); + } + } + +#if QM_ADAPTIVE_TC_RESOURCE_CTRL + /* 3 2. update for guaranteed page count */ + for (idx = 0; idx < TC_NUM; idx++) { + + /* construct prefix: Tc0Grt, Tc1Grt... */ + memset(string, 0, sizeof(string) / sizeof(uint8_t)); + ret = snprintf(string, sizeof(string) / sizeof(uint8_t), + "Tc%xGrt", idx); + if (ret > (sizeof(string) / sizeof(uint8_t))) { + DBGLOG(NIC, INFO, + "sprintf failed of guaranteed page count:%d\n", ret); + } else { + /* update the final value */ + prQM->au4GuaranteedTcResource[idx] = + (uint32_t) wlanCfgGetUint32(prAdapter, + string, prQM->au4GuaranteedTcResource[idx]); + } + } +#endif /* end of #if QM_ADAPTIVE_TC_RESOURCE_CTRL */ +#endif /* end of #if CFG_SUPPORT_CFG_FILE */ + + + + + /* + * 4. Peak throughput settings. + * Give most of the resource to TC1_INDEX. + * Reference to arNetwork2TcResource[], AC_BE uses TC1_INDEX. + */ + if (prAdapter->rWifiVar.ucTpTestMode == + ENUM_TP_TEST_MODE_THROUGHPUT) { + uint32_t u4psePageCnt, u4plePageCnt, u4pseRemain, + u4pleRemain; +#define DEFAULT_PACKET_NUM 5 + + + /* pse */ + u4pseRemain = prAdapter->nicTxReousrce.u4DataTotalResource; + u4psePageCnt = DEFAULT_PACKET_NUM * + nicTxGetMaxPageCntPerFrame(prAdapter); + + /* ple */ + u4pleRemain = + prAdapter->nicTxReousrce.u4DataTotalResourcePle; + u4plePageCnt = DEFAULT_PACKET_NUM * + NIX_TX_PLE_PAGE_CNT_PER_FRAME; + + /* equally giving to each TC */ + for (idx = 0; idx < TC_NUM; idx++) { + if (idx == TC4_INDEX) + continue; + + /* pse */ + prWifiVar->au4TcPageCount[idx] = u4psePageCnt; + u4pseRemain -= u4psePageCnt; + + /* ple */ + prWifiVar->au4TcPageCountPle[idx] = u4plePageCnt; + u4pleRemain -= u4plePageCnt; + } + + /* remaings are to TC1_INDEX */ + prWifiVar->au4TcPageCount[TC1_INDEX] += u4pseRemain; + prWifiVar->au4TcPageCountPle[TC1_INDEX] += u4pleRemain; + } +} + +void nicTxChangeDataPortByAc( + struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + uint8_t ucAci, + u_int8_t fgToMcu) +{ + struct TX_DESC_OPS_T *prTxDescOps = prAdapter->chip_info->prTxDescOps; + + if (prTxDescOps->nic_txd_change_data_port_by_ac) + prTxDescOps->nic_txd_change_data_port_by_ac( + prStaRec, + ucAci, + fgToMcu); +} + +/* if some msdus are waiting tx done status, but now roaming done, then need to +** change wlan index of these msdus to match tx done status event +** In multi-thread solution, we also need to check if pending tx packets in +** hif_thread tx queue. +*/ +void nicTxHandleRoamingDone(struct ADAPTER *prAdapter, + struct STA_RECORD *prOldStaRec, + struct STA_RECORD *prNewStaRec) +{ + struct MSDU_INFO *prMsduInfo = NULL; + uint8_t ucOldWlanIndex = prOldStaRec->ucWlanIndex; + uint8_t ucNewWlanIndex = prNewStaRec->ucWlanIndex; + uint8_t ucIndex = 0; + + KAL_SPIN_LOCK_DECLARATION(); + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); + prMsduInfo = (struct MSDU_INFO *)QUEUE_GET_HEAD( + &prAdapter->rTxCtrl.rTxMgmtTxingQueue); + while (prMsduInfo) { + if (prMsduInfo->ucWlanIndex == ucOldWlanIndex) + prMsduInfo->ucWlanIndex = ucNewWlanIndex; + prMsduInfo = (struct MSDU_INFO *)QUEUE_GET_NEXT_ENTRY( + &prMsduInfo->rQueEntry); + } + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); + +/* I think any time we disconnect with previous AP, rTxP0Queue and rTxP1Queue +** should be empty. +** because we have stopped dequeue when initial to connect the new roaming AP. +** It is enough time for hif_thread to send out these packets. But anyway, let's +** prepare code for that case to avoid scheduler corner case. +*/ +#if CFG_SUPPORT_MULTITHREAD + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_PORT_QUE); +#if CFG_FIX_2_TX_PORT + prMsduInfo = (struct MSDU_INFO *)QUEUE_GET_HEAD(&prAdapter->rTxP0Queue); + while (prMsduInfo) { + if (prMsduInfo->ucWlanIndex == ucOldWlanIndex) + prMsduInfo->ucWlanIndex = ucNewWlanIndex; + prMsduInfo = (struct MSDU_INFO *)QUEUE_GET_NEXT_ENTRY( + &prMsduInfo->rQueEntry); + } + prMsduInfo = (struct MSDU_INFO *)QUEUE_GET_HEAD(&prAdapter->rTxP1Queue); + while (prMsduInfo) { + if (prMsduInfo->ucWlanIndex == ucOldWlanIndex) + prMsduInfo->ucWlanIndex = ucNewWlanIndex; + prMsduInfo = (struct MSDU_INFO *)QUEUE_GET_NEXT_ENTRY( + &prMsduInfo->rQueEntry); + } +#else + for (ucIndex = 0; ucIndex < TX_PORT_NUM; ucIndex++) { + prMsduInfo = (struct MSDU_INFO *)QUEUE_GET_HEAD( + &prAdapter->rTxPQueue[ucIndex]); + while (prMsduInfo) { + if (prMsduInfo->ucWlanIndex == ucOldWlanIndex) + prMsduInfo->ucWlanIndex = ucNewWlanIndex; + prMsduInfo = (struct MSDU_INFO *)QUEUE_GET_NEXT_ENTRY( + &prMsduInfo->rQueEntry); + } + } +#endif + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_PORT_QUE); +#endif +} + +int32_t nicTxGetVectorInfo(IN char *pcCommand, IN int i4TotalLen, + IN struct TX_VECTOR_BBP_LATCH *prTxV) +{ + uint8_t rate, txmode, frmode, sgi, ldpc, nsts, stbc, txpwr; + int32_t i4BytesWritten = 0; + + rate = TX_VECTOR_GET_TX_RATE(prTxV); + txmode = TX_VECTOR_GET_TX_MODE(prTxV); + frmode = TX_VECTOR_GET_TX_FRMODE(prTxV); + nsts = TX_VECTOR_GET_TX_NSTS(prTxV) + 1; + sgi = TX_VECTOR_GET_TX_SGI(prTxV); + ldpc = TX_VECTOR_GET_TX_LDPC(prTxV); + stbc = TX_VECTOR_GET_TX_STBC(prTxV); + txpwr = TX_VECTOR_GET_TX_PWR(prTxV); + + if (prTxV->u4TxV[0] == 0xFFFFFFFF) { + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%s\n", "Last TX Rate", " = ", "N/A"); + } else { + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s", "Last TX Rate", " = "); + + if (txmode == TX_RATE_MODE_CCK) + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s, ", rate < 4 ? HW_TX_RATE_CCK_STR[rate] : + HW_TX_RATE_CCK_STR[4]); + else if (txmode == TX_RATE_MODE_OFDM) + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s, ", nicHwRateOfdmStr(rate)); + else if ((txmode == TX_RATE_MODE_HTMIX) || + (txmode == TX_RATE_MODE_HTGF)) + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "MCS%d, ", rate); + else + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s%d_MCS%d, ", stbc ? "NSTS" : "NSS", + nsts, rate); + + if (txmode == TX_RATE_MODE_HE_ER) + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s, ", + frmode > 0 ? "106-RU" : "242-RU"); + else + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s, ", + frmode < 4 ? HW_TX_RATE_BW[frmode] : + HW_TX_RATE_BW[4]); + + if (txmode == TX_RATE_MODE_CCK) + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s, ", rate < 4 ? "LP" : "SP"); + else if (txmode == TX_RATE_MODE_OFDM) + ; + else if ((txmode == TX_RATE_MODE_HTMIX) || + (txmode == TX_RATE_MODE_HTGF) || + (txmode == TX_RATE_MODE_VHT) || + (txmode == TX_RATE_MODE_PLR)) + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s, ", sgi == 0 ? "LGI" : "SGI"); + else + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s, ", sgi == 0 ? "LGI" : + (sgi == 1 ? "SGI" : "MGI")); + + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s%s%s\n", + txmode < 5 ? HW_TX_MODE_STR[txmode] : HW_TX_MODE_STR[5], + stbc ? ", STBC, " : ", ", ldpc == 0 ? "BCC" : "LDPC"); + } + + return i4BytesWritten; +} + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/nic_txd_v1.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/nic_txd_v1.c new file mode 100644 index 0000000000000000000000000000000000000000..dcd14df4ba2fc7bddf119271e1681908e8971b49 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/nic_txd_v1.c @@ -0,0 +1,765 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic_tx.c#2 + */ + +/*! \file nic_tx.c + * \brief Functions that provide TX operation in NIC Layer. + * + * This file provides TX functions which are responsible for both Hardware + * and Software Resource Management and keep their Synchronization. + */ + + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +uint8_t nic_txd_v1_long_format_op( + void *prTxDesc, + uint8_t fgSet) +{ + if (fgSet) + HAL_MAC_TX_DESC_SET_LONG_FORMAT( + (struct HW_MAC_TX_DESC *)prTxDesc); + return HAL_MAC_TX_DESC_IS_LONG_FORMAT( + (struct HW_MAC_TX_DESC *)prTxDesc); +} + +uint8_t nic_txd_v1_tid_op( + void *prTxDesc, + uint8_t ucTid, + uint8_t fgSet) +{ + if (fgSet) + HAL_MAC_TX_DESC_SET_TID( + (struct HW_MAC_TX_DESC *)prTxDesc, ucTid); + return HAL_MAC_TX_DESC_GET_TID( + (struct HW_MAC_TX_DESC *)prTxDesc); +} + +uint8_t nic_txd_v1_queue_idx_op( + void *prTxDesc, + uint8_t ucQueIdx, + uint8_t fgSet) +{ + if (fgSet) + HAL_MAC_TX_DESC_SET_QUEUE_INDEX( + (struct HW_MAC_TX_DESC *)prTxDesc, ucQueIdx); + return HAL_MAC_TX_DESC_GET_QUEUE_INDEX( + (struct HW_MAC_TX_DESC *)prTxDesc); +} + +#if (CFG_TCP_IP_CHKSUM_OFFLOAD == 1) +void nic_txd_v1_chksum_op( + void *prTxDesc, + uint8_t ucChksumFlag) +{ + if ((ucChksumFlag & TX_CS_IP_GEN)) + HAL_MAC_TX_DESC_SET_IP_CHKSUM( + (struct HW_MAC_TX_DESC *)prTxDesc); + if ((ucChksumFlag & TX_CS_TCP_UDP_GEN)) + HAL_MAC_TX_DESC_SET_TCP_UDP_CHKSUM( + (struct HW_MAC_TX_DESC *)prTxDesc); +} +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD == 1 */ + +void nic_txd_v1_header_format_op( + void *prTxDesc, + struct MSDU_INFO *prMsduInfo) +{ + if (!prMsduInfo->fgIs802_11) { + if (prMsduInfo->fgIs802_3) + HAL_MAC_TX_DESC_UNSET_ETHERNET_II( + (struct HW_MAC_TX_DESC *)prTxDesc); + if (prMsduInfo->fgIsVlanExists) + HAL_MAC_TX_DESC_SET_VLAN( + (struct HW_MAC_TX_DESC *)prTxDesc); + } +} + +void nic_txd_v1_fill_by_pkt_option( + struct MSDU_INFO *prMsduInfo, + void *prTxD) +{ + struct HW_MAC_TX_DESC *prTxDesc = (struct HW_MAC_TX_DESC *)prTxD; + uint32_t u4PktOption = prMsduInfo->u4Option; + u_int8_t fgIsLongFormat; + u_int8_t fgProtected = FALSE; + + /* Skip this function if no options is set */ + if (!u4PktOption) + return; + + fgIsLongFormat = HAL_MAC_TX_DESC_IS_LONG_FORMAT(prTxDesc); + + /* Fields in DW0 and DW1 (Short Format) */ + if (u4PktOption & MSDU_OPT_NO_ACK) + HAL_MAC_TX_DESC_SET_NO_ACK(prTxDesc); + + if (u4PktOption & MSDU_OPT_PROTECTED_FRAME) { + /* DBGLOG(RSN, INFO, "MSDU_OPT_PROTECTED_FRAME\n"); */ + HAL_MAC_TX_DESC_SET_PROTECTION(prTxDesc); + fgProtected = TRUE; + } + + switch (HAL_MAC_TX_DESC_GET_HEADER_FORMAT(prTxDesc)) { + case HEADER_FORMAT_802_11_ENHANCE_MODE: + if (u4PktOption & MSDU_OPT_EOSP) + HAL_MAC_TX_DESC_SET_EOSP(prTxDesc); + + if (u4PktOption & MSDU_OPT_AMSDU) + HAL_MAC_TX_DESC_SET_AMSDU(prTxDesc); + break; + + case HEADER_FORMAT_NON_802_11: + if (u4PktOption & MSDU_OPT_EOSP) + HAL_MAC_TX_DESC_SET_EOSP(prTxDesc); + + if (u4PktOption & MSDU_OPT_MORE_DATA) + HAL_MAC_TX_DESC_SET_MORE_DATA(prTxDesc); + + if (u4PktOption & MSDU_OPT_REMOVE_VLAN) + HAL_MAC_TX_DESC_SET_REMOVE_VLAN(prTxDesc); + break; + + case HEADER_FORMAT_802_11_NORMAL_MODE: + if (fgProtected && prMsduInfo->prPacket) { + struct WLAN_MAC_HEADER *prWlanHeader = + (struct WLAN_MAC_HEADER *) ((unsigned long) ( + prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); + + prWlanHeader->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME; + } + break; + + default: + break; + } + + if (!fgIsLongFormat) + return; + + /* Fields in DW2~6 (Long Format) */ + if (u4PktOption & MSDU_OPT_NO_AGGREGATE) + HAL_MAC_TX_DESC_SET_BA_DISABLE(prTxDesc); + + if (u4PktOption & MSDU_OPT_TIMING_MEASURE) + HAL_MAC_TX_DESC_SET_TIMING_MEASUREMENT(prTxDesc); + + if (u4PktOption & MSDU_OPT_NDP) + HAL_MAC_TX_DESC_SET_NDP(prTxDesc); + + if (u4PktOption & MSDU_OPT_NDPA) + HAL_MAC_TX_DESC_SET_NDPA(prTxDesc); + + if (u4PktOption & MSDU_OPT_SOUNDING) + HAL_MAC_TX_DESC_SET_SOUNDING_FRAME(prTxDesc); + + if (u4PktOption & MSDU_OPT_FORCE_RTS) + HAL_MAC_TX_DESC_SET_FORCE_RTS_CTS(prTxDesc); + + if (u4PktOption & MSDU_OPT_BIP) + HAL_MAC_TX_DESC_SET_BIP(prTxDesc); + + /* SW field */ + if (u4PktOption & MSDU_OPT_SW_DURATION) + HAL_MAC_TX_DESC_SET_DURATION_CONTROL_BY_SW(prTxDesc); + + if (u4PktOption & MSDU_OPT_SW_PS_BIT) + HAL_MAC_TX_DESC_SET_SW_PM_CONTROL(prTxDesc); + + if (u4PktOption & MSDU_OPT_SW_HTC) + HAL_MAC_TX_DESC_SET_HTC_EXIST(prTxDesc); +#if 0 + if (u4PktOption & MSDU_OPT_SW_BAR_SN) + HAL_MAC_TX_DESC_SET_SW_BAR_SSN(prTxDesc); +#endif + if (u4PktOption & MSDU_OPT_MANUAL_SN) { + HAL_MAC_TX_DESC_SET_TXD_SN_VALID(prTxDesc); + HAL_MAC_TX_DESC_SET_SEQUENCE_NUMBER(prTxDesc, + prMsduInfo->u2SwSN); + } + +} + +void nic_txd_v1_fill_by_pkt_ctrl( + struct MSDU_INFO *prMsduInfo, + void *prTxD) +{ + struct HW_MAC_TX_DESC *prTxDesc = (struct HW_MAC_TX_DESC *)prTxD; + uint8_t ucPktControl = prMsduInfo->ucControlFlag; + uint8_t ucSwReserved; + + /* Skip this function if no options is set */ + if (!ucPktControl) + return; + + if (HAL_MAC_TX_DESC_IS_LONG_FORMAT(prTxDesc)) { + ucSwReserved = HAL_MAC_TX_DESC_GET_SW_RESERVED(prTxDesc); + + if (ucPktControl & MSDU_CONTROL_FLAG_FORCE_TX) + ucSwReserved |= MSDU_CONTROL_FLAG_FORCE_TX; + + HAL_MAC_TX_DESC_SET_SW_RESERVED(prTxDesc, ucSwReserved); + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief In this function, we'll compose the Tx descriptor of the MSDU. + * + * @param prAdapter Pointer to the Adapter structure. + * @param prMsduInfo Pointer to the Msdu info + * @param prTxDesc Pointer to the Tx descriptor buffer + * + * @retval VOID + */ +/*----------------------------------------------------------------------------*/ +void nic_txd_v1_compose( + struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo, + uint32_t u4TxDescLength, + u_int8_t fgIsTemplate, + uint8_t *prTxDescBuffer) +{ + struct HW_MAC_TX_DESC *prTxDesc; + struct STA_RECORD *prStaRec; + struct BSS_INFO *prBssInfo; + uint8_t ucEtherTypeOffsetInWord; + uint32_t u4TxDescAndPaddingLength; + uint8_t ucTarPort, ucTarQueue; +#if ((CFG_SISO_SW_DEVELOP == 1) || (CFG_SUPPORT_SPE_IDX_CONTROL == 1)) + enum ENUM_WF_PATH_FAVOR_T eWfPathFavor; +#endif + prTxDesc = (struct HW_MAC_TX_DESC *) prTxDescBuffer; + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prMsduInfo->ucBssIndex); + prStaRec = cnmGetStaRecByIndex(prAdapter, + prMsduInfo->ucStaRecIndex); + + u4TxDescAndPaddingLength = u4TxDescLength + + NIC_TX_DESC_PADDING_LENGTH; + + kalMemZero(prTxDesc, u4TxDescAndPaddingLength); + + /* Move to nicTxFillDesc */ + /* Tx byte count */ + /* HAL_MAC_TX_DESC_SET_TX_BYTE_COUNT(prTxDesc, + * ucTxDescAndPaddingLength + prMsduInfo->u2FrameLength); + */ + + /* Ether-type offset */ + if (prMsduInfo->fgIs802_11) { + ucEtherTypeOffsetInWord = + (NIC_TX_PSE_HEADER_LENGTH + + prMsduInfo->ucMacHeaderLength + + prMsduInfo->ucLlcLength) >> 1; + } else { + ucEtherTypeOffsetInWord = ((ETHER_HEADER_LEN - + ETHER_TYPE_LEN) + NIC_TX_PSE_HEADER_LENGTH) >> 1; + } + HAL_MAC_TX_DESC_SET_ETHER_TYPE_OFFSET(prTxDesc, + ucEtherTypeOffsetInWord); + + /* Port index / queue index */ + ucTarPort = nicTxGetTxDestPortIdxByTc(prMsduInfo->ucTC); + HAL_MAC_TX_DESC_SET_PORT_INDEX(prTxDesc, ucTarPort); + + ucTarQueue = nicTxGetTxDestQIdxByTc(prMsduInfo->ucTC); + if (ucTarPort == PORT_INDEX_LMAC) + ucTarQueue += (prBssInfo->ucWmmQueSet * WMM_AC_INDEX_NUM); + + HAL_MAC_TX_DESC_SET_QUEUE_INDEX(prTxDesc, ucTarQueue); + + /* BMC packet */ + if (prMsduInfo->ucStaRecIndex == STA_REC_INDEX_BMCAST) { + HAL_MAC_TX_DESC_SET_BMC(prTxDesc); + + /* Must set No ACK to mask retry bit in FC */ + HAL_MAC_TX_DESC_SET_NO_ACK(prTxDesc); + } + /* WLAN index */ + prMsduInfo->ucWlanIndex = nicTxGetWlanIdx(prAdapter, + prMsduInfo->ucBssIndex, prMsduInfo->ucStaRecIndex); + +#if 0 /* DBG */ + DBGLOG(RSN, INFO, + "Tx WlanIndex = %d eAuthMode = %d\n", + prMsduInfo->ucWlanIndex, + prAdapter->rWifiVar.rConnSettings.eAuthMode); +#endif + HAL_MAC_TX_DESC_SET_WLAN_INDEX(prTxDesc, + prMsduInfo->ucWlanIndex); + + /* Header format */ + if (prMsduInfo->fgIs802_11) { + HAL_MAC_TX_DESC_SET_HEADER_FORMAT(prTxDesc, + HEADER_FORMAT_802_11_NORMAL_MODE); + HAL_MAC_TX_DESC_SET_802_11_HEADER_LENGTH(prTxDesc, + (prMsduInfo->ucMacHeaderLength >> 1)); + } else { + HAL_MAC_TX_DESC_SET_HEADER_FORMAT(prTxDesc, + HEADER_FORMAT_NON_802_11); + HAL_MAC_TX_DESC_SET_ETHERNET_II(prTxDesc); + } + + /* Header Padding */ + HAL_MAC_TX_DESC_SET_HEADER_PADDING(prTxDesc, + NIC_TX_DESC_HEADER_PADDING_LENGTH); + + /* TID */ + HAL_MAC_TX_DESC_SET_TID(prTxDesc, + prMsduInfo->ucUserPriority); + + /* Protection */ + if (secIsProtectedFrame(prAdapter, prMsduInfo, prStaRec)) { + /* Update Packet option, + * PF bit will be set in nicTxFillDescByPktOption() + */ + if ((prStaRec && prStaRec->fgTransmitKeyExist) + || fgIsTemplate) { + nicTxConfigPktOption( + prMsduInfo, MSDU_OPT_PROTECTED_FRAME, + TRUE); + + if (prMsduInfo->fgIs802_1x && + prMsduInfo->fgIs802_1x_NonProtected) { + nicTxConfigPktOption( + prMsduInfo, MSDU_OPT_PROTECTED_FRAME, + FALSE); + DBGLOG(RSN, LOUD, + "Pairwise EAPoL not protect!\n"); + } + } else if (prMsduInfo->ucStaRecIndex == + STA_REC_INDEX_BMCAST) {/* BMC packet */ + nicTxConfigPktOption(prMsduInfo, + MSDU_OPT_PROTECTED_FRAME, + TRUE); + DBGLOG(RSN, LOUD, "Protect BMC frame!\n"); + } + } +#if (UNIFIED_MAC_TX_FORMAT == 1) + /* Packet Format */ + HAL_MAC_TX_DESC_SET_PKT_FORMAT(prTxDesc, + prMsduInfo->ucPacketFormat); +#endif + + /* Own MAC */ + HAL_MAC_TX_DESC_SET_OWN_MAC_INDEX(prTxDesc, + prBssInfo->ucOwnMacIndex); + + if (u4TxDescLength == NIC_TX_DESC_SHORT_FORMAT_LENGTH) { + HAL_MAC_TX_DESC_SET_SHORT_FORMAT(prTxDesc); + + /* Update Packet option */ + nic_txd_v1_fill_by_pkt_option(prMsduInfo, prTxDesc); + + /* Short format, Skip DW 2~6 */ + return; + } + HAL_MAC_TX_DESC_SET_LONG_FORMAT(prTxDesc); + + /* Update Packet option */ + nic_txd_v1_fill_by_pkt_option(prMsduInfo, prTxDesc); + + nic_txd_v1_fill_by_pkt_ctrl(prMsduInfo, prTxDesc); + + /* Type */ + if (prMsduInfo->fgIs802_11) { + struct WLAN_MAC_HEADER *prWlanHeader = + (struct WLAN_MAC_HEADER *) ((unsigned long) ( + prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); + + HAL_MAC_TX_DESC_SET_TYPE(prTxDesc, + (prWlanHeader->u2FrameCtrl & MASK_FC_TYPE) >> 2); + HAL_MAC_TX_DESC_SET_SUB_TYPE(prTxDesc, + (prWlanHeader->u2FrameCtrl & MASK_FC_SUBTYPE) >> + OFFSET_OF_FC_SUBTYPE); + } + /* PID */ + if (prMsduInfo->pfTxDoneHandler) { + prMsduInfo->ucPID = nicTxAssignPID(prAdapter, + prMsduInfo->ucWlanIndex); + HAL_MAC_TX_DESC_SET_PID(prTxDesc, prMsduInfo->ucPID); + HAL_MAC_TX_DESC_SET_TXS_TO_MCU(prTxDesc); + } else if (prAdapter->rWifiVar.ucDataTxDone == 2) { + /* Log mode: only TxS to FW, no event to driver */ + HAL_MAC_TX_DESC_SET_PID(prTxDesc, NIC_TX_DESC_PID_RESERVED); + HAL_MAC_TX_DESC_SET_TXS_TO_MCU(prTxDesc); + } + + /* Remaining TX time */ + if (!(prMsduInfo->u4Option & MSDU_OPT_MANUAL_LIFE_TIME)) + prMsduInfo->u4RemainingLifetime = + nicTxGetRemainingTxTimeByTc(prMsduInfo->ucTC); + HAL_MAC_TX_DESC_SET_REMAINING_LIFE_TIME_IN_MS(prTxDesc, + prMsduInfo->u4RemainingLifetime); + + /* Tx count limit */ + if (!(prMsduInfo->u4Option & MSDU_OPT_MANUAL_RETRY_LIMIT)) { + /* Note: BMC packet retry limit is set to unlimited */ + prMsduInfo->ucRetryLimit = + nicTxGetTxCountLimitByTc(prMsduInfo->ucTC); + } + HAL_MAC_TX_DESC_SET_REMAINING_TX_COUNT(prTxDesc, + prMsduInfo->ucRetryLimit); + + /* Power Offset */ + HAL_MAC_TX_DESC_SET_POWER_OFFSET(prTxDesc, + prMsduInfo->cPowerOffset); + + /* Fix rate */ + switch (prMsduInfo->ucRateMode) { + case MSDU_RATE_MODE_MANUAL_DESC: + HAL_MAC_TX_DESC_SET_DW(prTxDesc, 6, 1, + &prMsduInfo->u4FixedRateOption); +#if ((CFG_SISO_SW_DEVELOP == 1) || (CFG_SUPPORT_SPE_IDX_CONTROL == 1)) + /* Update spatial extension index setting */ + eWfPathFavor = wlanGetAntPathType(prAdapter, ENUM_WF_NON_FAVOR); + HAL_MAC_TX_DESC_SET_SPE_IDX(prTxDesc, + wlanGetSpeIdx(prAdapter, prBssInfo->ucBssIndex, + eWfPathFavor)); +#endif + /* Set SPE_IDX_SEL to: + * 0: reference SPE_IDX configuration in TXD + * 1: reference SPE_IDX configuration in WTBL + */ + HAL_MAC_TX_DESC_SET_SPE_IDX_SEL(prTxDesc, 0); + HAL_MAC_TX_DESC_SET_FIXED_RATE_MODE_TO_DESC(prTxDesc); + HAL_MAC_TX_DESC_SET_FIXED_RATE_ENABLE(prTxDesc); + break; + + case MSDU_RATE_MODE_MANUAL_CR: + HAL_MAC_TX_DESC_SET_FIXED_RATE_MODE_TO_CR(prTxDesc); + HAL_MAC_TX_DESC_SET_FIXED_RATE_ENABLE(prTxDesc); + break; + + case MSDU_RATE_MODE_AUTO: + default: + break; + } + +} + + +void nic_txd_v1_compose_security_frame( + struct ADAPTER *prAdapter, + struct CMD_INFO *prCmdInfo, + uint8_t *prTxDescBuffer, + uint8_t *pucTxDescLength) +{ + struct HW_MAC_TX_DESC *prTxDesc = (struct HW_MAC_TX_DESC *) + prTxDescBuffer; + uint8_t ucTxDescAndPaddingLength = + NIC_TX_DESC_LONG_FORMAT_LENGTH + NIC_TX_DESC_PADDING_LENGTH; + + struct BSS_INFO *prBssInfo; + uint8_t ucTid = 0; + uint8_t ucTempTC = TC4_INDEX; + void *prNativePacket; + uint8_t ucEtherTypeOffsetInWord; + struct MSDU_INFO *prMsduInfo; + + prMsduInfo = prCmdInfo->prMsduInfo; + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prMsduInfo->ucBssIndex); + prNativePacket = prMsduInfo->prPacket; + + ASSERT(prNativePacket); + + kalMemZero(prTxDesc, ucTxDescAndPaddingLength); + + /* WLAN index */ + prMsduInfo->ucWlanIndex = nicTxGetWlanIdx(prAdapter, + prMsduInfo->ucBssIndex, prMsduInfo->ucStaRecIndex); + + /* UC to a connected peer */ + HAL_MAC_TX_DESC_SET_WLAN_INDEX(prTxDesc, + prMsduInfo->ucWlanIndex); + /* Redirect Security frame to TID0 */ + /* ucTempTC = arNetwork2TcResource[prStaRec->ucBssIndex] + * [aucTid2ACI[ucTid]]; + */ + + /* Tx byte count */ + HAL_MAC_TX_DESC_SET_TX_BYTE_COUNT(prTxDesc, + ucTxDescAndPaddingLength + prCmdInfo->u2InfoBufLen); + + /* Ether-type offset */ + ucEtherTypeOffsetInWord = ((ETHER_HEADER_LEN - + ETHER_TYPE_LEN) + NIC_TX_PSE_HEADER_LENGTH) >> 1; + HAL_MAC_TX_DESC_SET_ETHER_TYPE_OFFSET(prTxDesc, + ucEtherTypeOffsetInWord); + + /* Port index / queue index */ + HAL_MAC_TX_DESC_SET_PORT_INDEX(prTxDesc, + nicTxGetTxDestPortIdxByTc(ucTempTC)); + HAL_MAC_TX_DESC_SET_QUEUE_INDEX(prTxDesc, + nicTxGetTxDestQIdxByTc(ucTempTC)); + + /* Header format */ + HAL_MAC_TX_DESC_SET_HEADER_FORMAT(prTxDesc, + HEADER_FORMAT_NON_802_11); + + /* Long Format */ + HAL_MAC_TX_DESC_SET_LONG_FORMAT(prTxDesc); + + /* Update Packet option */ + nicTxFillDescByPktOption(prAdapter, prMsduInfo, prTxDesc); + + if (!GLUE_TEST_PKT_FLAG(prNativePacket, ENUM_PKT_802_3)) { + /* Set EthernetII */ + HAL_MAC_TX_DESC_SET_ETHERNET_II(prTxDesc); + } + /* Header Padding */ + HAL_MAC_TX_DESC_SET_HEADER_PADDING(prTxDesc, + NIC_TX_DESC_HEADER_PADDING_LENGTH); + + /* TID */ + HAL_MAC_TX_DESC_SET_TID(prTxDesc, ucTid); + + /* Remaining TX time */ + HAL_MAC_TX_DESC_SET_REMAINING_LIFE_TIME_IN_MS(prTxDesc, + nicTxGetRemainingTxTimeByTc(ucTempTC)); + + /* Tx count limit */ + HAL_MAC_TX_DESC_SET_REMAINING_TX_COUNT(prTxDesc, + nicTxGetTxCountLimitByTc(ucTempTC)); + + /* Set lowest BSS basic rate */ + HAL_MAC_TX_DESC_SET_FR_RATE(prTxDesc, + prBssInfo->u2HwDefaultFixedRateCode); + HAL_MAC_TX_DESC_SET_FIXED_RATE_MODE_TO_DESC(prTxDesc); + HAL_MAC_TX_DESC_SET_FIXED_RATE_ENABLE(prTxDesc); + + /* Packet Format */ + HAL_MAC_TX_DESC_SET_PKT_FORMAT(prTxDesc, + TXD_PKT_FORMAT_COMMAND); + + /* Own MAC */ + HAL_MAC_TX_DESC_SET_OWN_MAC_INDEX(prTxDesc, + prBssInfo->ucOwnMacIndex); + + /* PID */ + if (prMsduInfo->pfTxDoneHandler) { + prMsduInfo->ucPID = nicTxAssignPID(prAdapter, + prMsduInfo->ucWlanIndex); + HAL_MAC_TX_DESC_SET_PID(prTxDesc, prMsduInfo->ucPID); + HAL_MAC_TX_DESC_SET_TXS_TO_MCU(prTxDesc); + } + + if (pucTxDescLength) + *pucTxDescLength = ucTxDescAndPaddingLength; +} + +void nic_txd_v1_set_pkt_fixed_rate_option_full( + struct MSDU_INFO *prMsduInfo, + uint16_t u2RateCode, + uint8_t ucBandwidth, + u_int8_t fgShortGI, + u_int8_t fgLDPC, + u_int8_t fgDynamicBwRts, + u_int8_t fgBeamforming, + uint8_t ucAntennaIndex) +{ + struct HW_MAC_TX_DESC rTxDesc; + struct HW_MAC_TX_DESC *prTxDesc = &rTxDesc; + + kalMemZero(prTxDesc, NIC_TX_DESC_LONG_FORMAT_LENGTH); + + /* Follow the format of Tx descriptor DW 6 */ + HAL_MAC_TX_DESC_SET_FR_RATE(prTxDesc, u2RateCode); + + if (ucBandwidth) + HAL_MAC_TX_DESC_SET_FR_BW(prTxDesc, ucBandwidth); + + if (fgBeamforming) + HAL_MAC_TX_DESC_SET_FR_BF(prTxDesc); + + if (fgShortGI) + HAL_MAC_TX_DESC_SET_FR_SHORT_GI(prTxDesc); + + if (fgLDPC) + HAL_MAC_TX_DESC_SET_FR_LDPC(prTxDesc); + + if (fgDynamicBwRts) + HAL_MAC_TX_DESC_SET_FR_DYNAMIC_BW_RTS(prTxDesc); + + HAL_MAC_TX_DESC_SET_FR_ANTENNA_ID(prTxDesc, ucAntennaIndex); + + /* Write back to RateOption of MSDU_INFO */ + HAL_MAC_TX_DESC_GET_DW(prTxDesc, 6, 1, + &prMsduInfo->u4FixedRateOption); + + prMsduInfo->ucRateMode = MSDU_RATE_MODE_MANUAL_DESC; + +} + +void nic_txd_v1_set_pkt_fixed_rate_option( + struct MSDU_INFO *prMsduInfo, + uint16_t u2RateCode, + uint8_t ucBandwidth, + u_int8_t fgShortGI, + u_int8_t fgDynamicBwRts) +{ + struct HW_MAC_TX_DESC rTxDesc; + struct HW_MAC_TX_DESC *prTxDesc = &rTxDesc; + + kalMemZero(prTxDesc, NIC_TX_DESC_LONG_FORMAT_LENGTH); + + /* Follow the format of Tx descriptor DW 6 */ + HAL_MAC_TX_DESC_SET_FR_RATE(prTxDesc, u2RateCode); + + if (ucBandwidth) + HAL_MAC_TX_DESC_SET_FR_BW(prTxDesc, ucBandwidth); + + if (fgShortGI) + HAL_MAC_TX_DESC_SET_FR_SHORT_GI(prTxDesc); + + if (fgDynamicBwRts) + HAL_MAC_TX_DESC_SET_FR_DYNAMIC_BW_RTS(prTxDesc); + + /* Write back to RateOption of MSDU_INFO */ + HAL_MAC_TX_DESC_GET_DW(prTxDesc, 6, 1, + &prMsduInfo->u4FixedRateOption); + + prMsduInfo->ucRateMode = MSDU_RATE_MODE_MANUAL_DESC; + +} + +void nic_txd_v1_set_hw_amsdu_template( + struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + uint8_t ucTid, + u_int8_t fgSet) +{ + struct HW_MAC_TX_DESC *prTxDesc; + + DBGLOG(QM, INFO, + "Update HW Amsdu field of TXD template for STA[%u] Tid[%u]\n", + prStaRec->ucIndex, ucTid); + + if (prStaRec->aprTxDescTemplate[ucTid]) { + prTxDesc = (struct HW_MAC_TX_DESC *) + prStaRec->aprTxDescTemplate[ucTid]; + if (fgSet) + HAL_MAC_TX_DESC_SET_HW_AMSDU(prTxDesc); + else + HAL_MAC_TX_DESC_UNSET_HW_AMSDU(prTxDesc); + } +} + +void nic_txd_v1_change_data_port_by_ac( + struct STA_RECORD *prStaRec, + uint8_t ucAci, + u_int8_t fgToMcu) +{ + uint8_t ucTid; + void **pprTxDTemplate = NULL; + + if (!prStaRec) + return; + DBGLOG(TX, INFO, "Data Packets in Aci %d will route to %s\n", ucAci, + fgToMcu ? "MCU" : "LMAC"); + pprTxDTemplate = &prStaRec->aprTxDescTemplate[0]; + for (ucTid = 0; ucTid < TX_DESC_TID_NUM; ucTid++) { + if (aucTid2ACI[ucTid] != ucAci) + continue; + HAL_MAC_TX_DESC_SET_PORT_INDEX( + (struct HW_MAC_TX_DESC *)pprTxDTemplate[ucTid], + fgToMcu ? PORT_INDEX_MCU:PORT_INDEX_LMAC); + } +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/nic_txd_v2.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/nic_txd_v2.c new file mode 100644 index 0000000000000000000000000000000000000000..58e81c60ce5a7df3529ff2f2f347612ebccb3844 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/nic_txd_v2.c @@ -0,0 +1,818 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic_tx.c#2 + */ + +/*! \file nic_tx.c + * \brief Functions that provide TX operation in NIC Layer. + * + * This file provides TX functions which are responsible for both Hardware + * and Software Resource Management and keep their Synchronization. + */ + + +#if (CFG_SUPPORT_CONNAC2X == 1) +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +uint8_t nic_txd_v2_long_format_op( + void *prTxDesc, + uint8_t fgSet) +{ + if (fgSet) + HAL_MAC_CONNAC2X_TXD_SET_LONG_FORMAT( + (struct HW_MAC_CONNAC2X_TX_DESC *)prTxDesc); + return HAL_MAC_CONNAC2X_TXD_IS_LONG_FORMAT( + (struct HW_MAC_CONNAC2X_TX_DESC *)prTxDesc); +} + +uint8_t nic_txd_v2_tid_op( + void *prTxDesc, + uint8_t ucTid, + uint8_t fgSet) +{ + if (fgSet) + HAL_MAC_CONNAC2X_TXD_SET_TID( + (struct HW_MAC_CONNAC2X_TX_DESC *)prTxDesc, ucTid); + return HAL_MAC_CONNAC2X_TXD_GET_TID( + (struct HW_MAC_CONNAC2X_TX_DESC *)prTxDesc); +} + +uint8_t nic_txd_v2_queue_idx_op( + void *prTxDesc, + uint8_t ucQueIdx, + uint8_t fgSet) +{ + if (fgSet) + HAL_MAC_CONNAC2X_TXD_SET_QUEUE_INDEX( + (struct HW_MAC_CONNAC2X_TX_DESC *)prTxDesc, ucQueIdx); + return HAL_MAC_CONNAC2X_TXD_GET_QUEUE_INDEX( + (struct HW_MAC_CONNAC2X_TX_DESC *)prTxDesc); +} + +#if (CFG_TCP_IP_CHKSUM_OFFLOAD == 1) +void nic_txd_v2_chksum_op( + void *prTxDesc, + uint8_t ucChksumFlag) +{ + if ((ucChksumFlag & TX_CS_IP_GEN)) + HAL_MAC_CONNAC2X_TXD_SET_IP_CHKSUM( + (struct HW_MAC_CONNAC2X_TX_DESC *)prTxDesc); + if ((ucChksumFlag & TX_CS_TCP_UDP_GEN)) + HAL_MAC_CONNAC2X_TXD_SET_TCP_UDP_CHKSUM( + (struct HW_MAC_CONNAC2X_TX_DESC *)prTxDesc); +} +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD == 1 */ + +void nic_txd_v2_header_format_op( + void *prTxDesc, + struct MSDU_INFO *prMsduInfo) +{ + if (!prMsduInfo->fgIs802_11) { + if (prMsduInfo->fgIs802_3) + HAL_MAC_CONNAC2X_TXD_UNSET_ETHERNET_II( + (struct HW_MAC_CONNAC2X_TX_DESC *)prTxDesc); + if (prMsduInfo->fgIsVlanExists) + HAL_MAC_CONNAC2X_TXD_SET_VLAN( + (struct HW_MAC_CONNAC2X_TX_DESC *)prTxDesc); + } +} + +void nic_txd_v2_fill_by_pkt_option( + struct MSDU_INFO *prMsduInfo, + void *prTxD) +{ + struct HW_MAC_CONNAC2X_TX_DESC *prTxDesc = + (struct HW_MAC_CONNAC2X_TX_DESC *)prTxD; + uint32_t u4PktOption = prMsduInfo->u4Option; + u_int8_t fgIsLongFormat; + u_int8_t fgProtected = FALSE; + + /* Skip this function if no options is set */ + if (!u4PktOption) + return; + + fgIsLongFormat = HAL_MAC_CONNAC2X_TXD_IS_LONG_FORMAT(prTxDesc); + + /* Fields in DW0 and DW1 (Short Format) */ + if (u4PktOption & MSDU_OPT_NO_ACK) + HAL_MAC_CONNAC2X_TXD_SET_NO_ACK(prTxDesc); + + if (u4PktOption & MSDU_OPT_PROTECTED_FRAME) { + /* DBGLOG(RSN, INFO, "MSDU_OPT_PROTECTED_FRAME\n"); */ + HAL_MAC_CONNAC2X_TXD_SET_PROTECTION(prTxDesc); + fgProtected = TRUE; + } + + switch (HAL_MAC_CONNAC2X_TXD_GET_HEADER_FORMAT(prTxDesc)) { + case HEADER_FORMAT_802_11_ENHANCE_MODE: + if (u4PktOption & MSDU_OPT_EOSP) + HAL_MAC_CONNAC2X_TXD_SET_EOSP(prTxDesc); + + if (u4PktOption & MSDU_OPT_AMSDU) + HAL_MAC_CONNAC2X_TXD_SET_AMSDU(prTxDesc); + break; + + case HEADER_FORMAT_NON_802_11: + if (u4PktOption & MSDU_OPT_EOSP) + HAL_MAC_CONNAC2X_TXD_SET_EOSP(prTxDesc); + + if (u4PktOption & MSDU_OPT_MORE_DATA) + HAL_MAC_CONNAC2X_TXD_SET_MORE_DATA(prTxDesc); + + if (u4PktOption & MSDU_OPT_REMOVE_VLAN) + HAL_MAC_CONNAC2X_TXD_SET_REMOVE_VLAN(prTxDesc); + break; + + case HEADER_FORMAT_802_11_NORMAL_MODE: + if (fgProtected && prMsduInfo->prPacket) { + struct WLAN_MAC_HEADER *prWlanHeader = + (struct WLAN_MAC_HEADER *) + ((unsigned long) (prMsduInfo->prPacket) + + MAC_TX_RESERVED_FIELD); + + prWlanHeader->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME; + } + break; + + default: + break; + } + + if (!fgIsLongFormat) + return; + + /* Fields in DW2~6 (Long Format) */ + if (u4PktOption & MSDU_OPT_NO_AGGREGATE) + HAL_MAC_CONNAC2X_TXD_SET_BA_DISABLE(prTxDesc); + + if (u4PktOption & MSDU_OPT_TIMING_MEASURE) + HAL_MAC_CONNAC2X_TXD_SET_TIMING_MEASUREMENT(prTxDesc); + + if (u4PktOption & MSDU_OPT_NDP) + HAL_MAC_CONNAC2X_TXD_SET_NDP(prTxDesc); + + if (u4PktOption & MSDU_OPT_NDPA) + HAL_MAC_CONNAC2X_TXD_SET_NDPA(prTxDesc); + + if (u4PktOption & MSDU_OPT_SOUNDING) + HAL_MAC_CONNAC2X_TXD_SET_SOUNDING_FRAME(prTxDesc); + + if (u4PktOption & MSDU_OPT_FORCE_RTS) + HAL_MAC_CONNAC2X_TXD_SET_FORCE_RTS_CTS(prTxDesc); + + if (u4PktOption & MSDU_OPT_BIP) + HAL_MAC_CONNAC2X_TXD_SET_BIP(prTxDesc); + + /* SW field */ + if (u4PktOption & MSDU_OPT_SW_DURATION) + HAL_MAC_CONNAC2X_TXD_SET_DURATION_CONTROL_BY_SW(prTxDesc); + + if (u4PktOption & MSDU_OPT_SW_PS_BIT) + HAL_MAC_CONNAC2X_TXD_SET_SW_PM_CONTROL(prTxDesc); + + if (u4PktOption & MSDU_OPT_SW_HTC) + HAL_MAC_CONNAC2X_TXD_SET_HTC_EXIST(prTxDesc); +#if 0 + if (u4PktOption & MSDU_OPT_SW_BAR_SN) + HAL_MAC_TX_DESC_SET_SW_BAR_SSN(prTxDesc); +#endif + if (u4PktOption & MSDU_OPT_MANUAL_SN) { + HAL_MAC_CONNAC2X_TXD_SET_TXD_SN_VALID(prTxDesc); + HAL_MAC_CONNAC2X_TXD_SET_SEQUENCE_NUMBER + (prTxDesc, prMsduInfo->u2SwSN); + } + +} + +/*----------------------------------------------------------------------------*/ +/*! +* @brief In this function, we'll compose the Tx descriptor of the MSDU. +* +* @param prAdapter Pointer to the Adapter structure. +* @param prMsduInfo Pointer to the Msdu info +* @param prTxDesc Pointer to the Tx descriptor buffer +* +* @retval VOID +*/ +/*----------------------------------------------------------------------------*/ +void nic_txd_v2_compose( + struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo, + u_int32_t u4TxDescLength, + u_int8_t fgIsTemplate, + u_int8_t *prTxDescBuffer) +{ + struct HW_MAC_CONNAC2X_TX_DESC *prTxDesc; + struct STA_RECORD *prStaRec; + struct BSS_INFO *prBssInfo; + u_int8_t ucEtherTypeOffsetInWord; + u_int32_t u4TxDescAndPaddingLength; + u_int8_t ucTarQueue, ucTarPort; +#if ((CFG_SISO_SW_DEVELOP == 1) || (CFG_SUPPORT_SPE_IDX_CONTROL == 1)) + enum ENUM_WF_PATH_FAVOR_T eWfPathFavor; +#endif + + prTxDesc = (struct HW_MAC_CONNAC2X_TX_DESC *) prTxDescBuffer; + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prMsduInfo->ucBssIndex); + prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); + + u4TxDescAndPaddingLength = u4TxDescLength + NIC_TX_DESC_PADDING_LENGTH; + + kalMemZero(prTxDesc, u4TxDescAndPaddingLength); + + /* Ether-type offset */ + if (prMsduInfo->fgIs802_11) { + ucEtherTypeOffsetInWord = + (prAdapter->chip_info->pse_header_length + + prMsduInfo->ucMacHeaderLength + + prMsduInfo->ucLlcLength) >> 1; + } else { + ucEtherTypeOffsetInWord = + ((ETHER_HEADER_LEN - ETHER_TYPE_LEN) + + prAdapter->chip_info->pse_header_length) >> 1; + } + HAL_MAC_CONNAC2X_TXD_SET_ETHER_TYPE_OFFSET( + prTxDesc, + ucEtherTypeOffsetInWord); + + ucTarPort = nicTxGetTxDestPortIdxByTc(prMsduInfo->ucTC); + if (ucTarPort == PORT_INDEX_MCU && + prMsduInfo->ucControlFlag & MSDU_CONTROL_FLAG_FORCE_TX) { + /* To MCU packet with always tx flag */ + ucTarQueue = MAC_TXQ_ALTX_0_INDEX; + } else { + ucTarQueue = nicTxGetTxDestQIdxByTc(prMsduInfo->ucTC); + ucTarQueue += (prBssInfo->ucWmmQueSet * WMM_AC_INDEX_NUM); + } + +#if (CFG_SUPPORT_DMASHDL_SYSDVT) + if (prMsduInfo->ucPktType == ENUM_PKT_ICMP) { + /* send packets to specific mapping queue for DMASHDL DVT */ + if (DMASHDL_DVT_QUEUE_MAPPING_TYPE1(prAdapter)) { + ucTarQueue = DMASHDL_DVT_GET_MAPPING_QID(prAdapter); + prMsduInfo->ucTarQueue = ucTarQueue; + DMASHDL_DVT_SET_MAPPING_QID(prAdapter, + (ucTarQueue + 1) % MAC_TXQ_AC33_INDEX); + } else if (DMASHDL_DVT_QUEUE_MAPPING_TYPE2(prAdapter)) { + ucTarQueue = DMASHDL_DVT_GET_MAPPING_QID(prAdapter); + prMsduInfo->ucTarQueue = ucTarQueue; + DMASHDL_DVT_SET_MAPPING_QID(prAdapter, + (ucTarQueue + 1) % MAC_TXQ_AC2_INDEX); + } + } +#endif + + HAL_MAC_CONNAC2X_TXD_SET_QUEUE_INDEX(prTxDesc, ucTarQueue); + + /* BMC packet */ + if (prMsduInfo->ucStaRecIndex == STA_REC_INDEX_BMCAST) { + HAL_MAC_CONNAC2X_TXD_SET_BMC(prTxDesc); + + /* Must set No ACK to mask retry bit in FC */ + HAL_MAC_CONNAC2X_TXD_SET_NO_ACK(prTxDesc); + } + /* WLAN index */ + prMsduInfo->ucWlanIndex = nicTxGetWlanIdx(prAdapter, + prMsduInfo->ucBssIndex, prMsduInfo->ucStaRecIndex); + +#if 0 /* DBG */ + DBGLOG(RSN, INFO, + "Tx WlanIndex = %d eAuthMode = %d\n", prMsduInfo->ucWlanIndex, + prAdapter->rWifiVar.rConnSettings.eAuthMode); +#endif + HAL_MAC_CONNAC2X_TXD_SET_WLAN_INDEX( + prTxDesc, prMsduInfo->ucWlanIndex); + + /* Header format */ + if (prMsduInfo->fgIs802_11) { + HAL_MAC_CONNAC2X_TXD_SET_HEADER_FORMAT( + prTxDesc, HEADER_FORMAT_802_11_NORMAL_MODE); + HAL_MAC_CONNAC2X_TXD_SET_802_11_HEADER_LENGTH( + prTxDesc, (prMsduInfo->ucMacHeaderLength >> 1)); + } else { + HAL_MAC_CONNAC2X_TXD_SET_HEADER_FORMAT( + prTxDesc, HEADER_FORMAT_NON_802_11); + HAL_MAC_CONNAC2X_TXD_SET_ETHERNET_II(prTxDesc); + } + + /* Header Padding */ + HAL_MAC_CONNAC2X_TXD_SET_HEADER_PADDING( + prTxDesc, NIC_TX_DESC_HEADER_PADDING_LENGTH); + + /* TID */ + HAL_MAC_CONNAC2X_TXD_SET_TID(prTxDesc, prMsduInfo->ucUserPriority); + + /* Protection */ + if (secIsProtectedFrame(prAdapter, prMsduInfo, prStaRec)) { + /* Update Packet option, */ + /* PF bit will be set in nicTxFillDescByPktOption() */ + if ((prStaRec + && prStaRec->fgTransmitKeyExist) || fgIsTemplate) { + DBGLOG_LIMITED(RSN, TRACE, + "Set MSDU_OPT_PROTECTED_FRAME\n"); + nicTxConfigPktOption( + prMsduInfo, MSDU_OPT_PROTECTED_FRAME, TRUE); + + if (prMsduInfo->fgIs802_1x && + prMsduInfo->fgIs802_1x_NonProtected) { + nicTxConfigPktOption( + prMsduInfo, + MSDU_OPT_PROTECTED_FRAME, FALSE); + DBGLOG(RSN, LOUD, + "Pairwise EAPoL not protect!\n"); + } + } else if (prMsduInfo->ucStaRecIndex + == STA_REC_INDEX_BMCAST) {/* BMC packet */ + nicTxConfigPktOption( + prMsduInfo, MSDU_OPT_PROTECTED_FRAME, TRUE); + DBGLOG(RSN, LOUD, "Protect BMC frame!\n"); + } + } +#if (UNIFIED_MAC_TX_FORMAT == 1) + /* Packet Format */ + HAL_MAC_CONNAC2X_TXD_SET_PKT_FORMAT( + prTxDesc, prMsduInfo->ucPacketFormat); +#endif + + /* Own MAC */ + HAL_MAC_CONNAC2X_TXD_SET_OWN_MAC_INDEX( + prTxDesc, prBssInfo->ucOwnMacIndex); + + if (u4TxDescLength == NIC_TX_DESC_SHORT_FORMAT_LENGTH) { + HAL_MAC_CONNAC2X_TXD_SET_SHORT_FORMAT(prTxDesc); + + /* Update Packet option */ + nic_txd_v2_fill_by_pkt_option(prMsduInfo, prTxDesc); + + /* Short format, Skip DW 2~6 */ + return; + } + HAL_MAC_CONNAC2X_TXD_SET_LONG_FORMAT(prTxDesc); + + /* Update Packet option */ + nic_txd_v2_fill_by_pkt_option(prMsduInfo, prTxDesc); + + /* Type */ + if (prMsduInfo->fgIs802_11) { + struct WLAN_MAC_HEADER *prWlanHeader = + (struct WLAN_MAC_HEADER *) + ((unsigned long) + (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); + + HAL_MAC_CONNAC2X_TXD_SET_TYPE( + prTxDesc, + (prWlanHeader->u2FrameCtrl & MASK_FC_TYPE) >> 2); + HAL_MAC_CONNAC2X_TXD_SET_SUB_TYPE( + prTxDesc, + (prWlanHeader->u2FrameCtrl & MASK_FC_SUBTYPE) + >> OFFSET_OF_FC_SUBTYPE); + + HAL_MAC_CONNAC2X_TXD7_SET_TYPE( + prTxDesc, + (prWlanHeader->u2FrameCtrl & MASK_FC_TYPE) >> 2); + HAL_MAC_CONNAC2X_TXD7_SET_SUB_TYPE( + prTxDesc, + (prWlanHeader->u2FrameCtrl & MASK_FC_SUBTYPE) + >> OFFSET_OF_FC_SUBTYPE); + } + /* PID */ + if (prMsduInfo->pfTxDoneHandler) { + prMsduInfo->ucPID = nicTxAssignPID( + prAdapter, prMsduInfo->ucWlanIndex); + HAL_MAC_CONNAC2X_TXD_SET_PID(prTxDesc, prMsduInfo->ucPID); + HAL_MAC_CONNAC2X_TXD_SET_TXS_TO_MCU(prTxDesc); + } else if (prAdapter->rWifiVar.ucDataTxDone == 2) { + /* Log mode: only TxS to FW, no event to driver */ + HAL_MAC_CONNAC2X_TXD_SET_PID( + prTxDesc, NIC_TX_DESC_PID_RESERVED); + HAL_MAC_CONNAC2X_TXD_SET_TXS_TO_MCU(prTxDesc); + } + +#if CFG_SUPPORT_WIFI_SYSDVT + if (prMsduInfo->pfTxDoneHandler) { + DBGLOG(REQ, LOUD, "PacketType=%d\n", + prMsduInfo->ucPacketType); + if (is_frame_test(prAdapter, 0) == 1 && + prMsduInfo->ucPacketType == 0) { /* Data */ + prMsduInfo->ucPID = prAdapter->auto_dvt->txs.pid; + HAL_MAC_CONNAC2X_TXD_SET_PID(prTxDesc, + prAdapter->auto_dvt->txs.pid); + HAL_MAC_CONNAC2X_TXD_SET_TXS_FORMAT(prTxDesc, + prAdapter->auto_dvt->txs.format); + send_add_txs_queue(prAdapter->auto_dvt->txs.pid, + prMsduInfo->ucWlanIndex); + DBGLOG(REQ, LOUD, + "Send_add_txs_queue pid=%d auto_txs_format=%d\n", + prMsduInfo->ucPID, + prAdapter->auto_dvt->txs.format); + } else if (is_frame_test(prAdapter, 0) == 2 && + prMsduInfo->ucPacketType == 1) { /* Mgmt */ + struct WLAN_MAC_HEADER *prWlanHeader = + (struct WLAN_MAC_HEADER *) + ((unsigned long)(prMsduInfo->prPacket) + + MAC_TX_RESERVED_FIELD); + + if (((prWlanHeader->u2FrameCtrl & + MASK_FC_TYPE) >> 2) == 0 && + ((prWlanHeader->u2FrameCtrl & MASK_FC_SUBTYPE) + >> OFFSET_OF_FC_SUBTYPE) == 8) + ;/* FC_TYPE_MGMT=0, SUBTYPE_BEACON=8 */ + else if (((prWlanHeader->u2FrameCtrl & + MASK_FC_TYPE) >> 2) == 0) { + prMsduInfo->ucPID = + prAdapter->auto_dvt->txs.pid; + HAL_MAC_CONNAC2X_TXD_SET_PID(prTxDesc, + prAdapter->auto_dvt->txs.pid); + HAL_MAC_CONNAC2X_TXD_SET_TXS_FORMAT(prTxDesc, + prAdapter->auto_dvt->txs.format); + send_add_txs_queue(prAdapter->auto_dvt->txs.pid, + prMsduInfo->ucWlanIndex); + DBGLOG(REQ, LOUD, + "Send_add_txs_queue pid=%d auto_txs_format=%d\n", + prMsduInfo->ucPID, + prAdapter->auto_dvt->txs.format); + } else { + prMsduInfo->ucPID = + prAdapter->auto_dvt->txs.pid; + HAL_MAC_CONNAC2X_TXD_SET_PID(prTxDesc, + prAdapter->auto_dvt->txs.pid); + HAL_MAC_CONNAC2X_TXD_SET_TXS_FORMAT(prTxDesc, + prAdapter->auto_dvt->txs.format); + HAL_MAC_CONNAC2X_TXD_SET_NO_ACK(prTxDesc); + send_add_txs_queue( + prAdapter->auto_dvt->txs.pid, + prMsduInfo->ucWlanIndex); + DBGLOG(REQ, LOUD, + "Send_add_txs_queue pid=%d auto_txs_format=%d\n", + prMsduInfo->ucPID, + prAdapter->auto_dvt->txs.format); + } + } + } +#endif /* AUTOMATION */ + + /* Remaining TX time */ + if (!(prMsduInfo->u4Option & MSDU_OPT_MANUAL_LIFE_TIME)) + prMsduInfo->u4RemainingLifetime = + nicTxGetRemainingTxTimeByTc(prMsduInfo->ucTC); + HAL_MAC_CONNAC2X_TXD_SET_REMAINING_LIFE_TIME_IN_MS( + prTxDesc, prMsduInfo->u4RemainingLifetime); + + /* Tx count limit */ + if (!(prMsduInfo->u4Option & MSDU_OPT_MANUAL_RETRY_LIMIT)) { + /* Note: BMC packet retry limit is set to unlimited */ + prMsduInfo->ucRetryLimit = + nicTxGetTxCountLimitByTc(prMsduInfo->ucTC); + } + HAL_MAC_CONNAC2X_TXD_SET_REMAINING_TX_COUNT( + prTxDesc, prMsduInfo->ucRetryLimit); + + /* Power Offset */ + HAL_MAC_CONNAC2X_TXD_SET_POWER_OFFSET( + prTxDesc, prMsduInfo->cPowerOffset); + + /* Fix rate */ + switch (prMsduInfo->ucRateMode) { + case MSDU_RATE_MODE_MANUAL_DESC: + HAL_MAC_TX_DESC_SET_DW( + prTxDesc, 6, 1, &prMsduInfo->u4FixedRateOption); +#if (CFG_SISO_SW_DEVELOP == 1 || CFG_SUPPORT_SPE_IDX_CONTROL == 1) + /* Update spatial extension index setting */ + eWfPathFavor = wlanGetAntPathType(prAdapter, ENUM_WF_NON_FAVOR); + HAL_MAC_CONNAC2X_TXD_SET_SPE_IDX( + prTxDesc, + wlanGetSpeIdx(prAdapter, prBssInfo->ucBssIndex, + eWfPathFavor)); +#endif + HAL_MAC_CONNAC2X_TXD_SET_SPE_IDX_SEL(prTxDesc, + ENUM_SPE_SEL_BY_TXD); + HAL_MAC_CONNAC2X_TXD_SET_FIXED_RATE_MODE_TO_DESC(prTxDesc); + HAL_MAC_CONNAC2X_TXD_SET_FIXED_RATE_ENABLE(prTxDesc); + +#if (CFG_SUPPORT_HE_ER == 1) + if (prBssInfo->ucErMode == RA_DCM || + prBssInfo->ucErMode == RA_ER_106) { + /* 2 HE LTF */ + HAL_MAC_CONNAC2X_TXD_SET_HE_LTF(prTxDesc, 1); + /* 1.6us GI */ + HAL_MAC_CONNAC2X_TXD_SET_GI_TYPE(prTxDesc, 1); + /* DBGLOG(TX, WARN, "nic_txd:LTF:2(%x,GI:1.6(%x", */ + /* HAL_MAC_CONNAC2X_TXD_GET_HE_LTF(prTxDesc), */ + /* HAL_MAC_CONNAC2X_TXD_GET_GI_TYPE(prTxDesc)); */ + } +#endif + break; + + case MSDU_RATE_MODE_MANUAL_CR: + HAL_MAC_CONNAC2X_TXD_SET_FIXED_RATE_MODE_TO_CR(prTxDesc); + HAL_MAC_CONNAC2X_TXD_SET_FIXED_RATE_ENABLE(prTxDesc); + break; + + case MSDU_RATE_MODE_AUTO: + default: + break; + } +} + +void nic_txd_v2_compose_security_frame( + struct ADAPTER *prAdapter, + struct CMD_INFO *prCmdInfo, + uint8_t *prTxDescBuffer, + uint8_t *pucTxDescLength) +{ + struct HW_MAC_CONNAC2X_TX_DESC *prTxDesc + = (struct HW_MAC_CONNAC2X_TX_DESC *) prTxDescBuffer; + uint8_t ucTxDescAndPaddingLength + = NIC_TX_DESC_LONG_FORMAT_LENGTH + NIC_TX_DESC_PADDING_LENGTH; + struct BSS_INFO *prBssInfo; + uint8_t ucTid = 0; + uint8_t ucTempTC = TC4_INDEX; + void *prNativePacket; + uint8_t ucEtherTypeOffsetInWord; + struct MSDU_INFO *prMsduInfo; + + prMsduInfo = prCmdInfo->prMsduInfo; + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prMsduInfo->ucBssIndex); + prNativePacket = prMsduInfo->prPacket; + + ASSERT(prNativePacket); + + kalMemZero(prTxDesc, ucTxDescAndPaddingLength); + + /* WLAN index */ + prMsduInfo->ucWlanIndex = + nicTxGetWlanIdx(prAdapter, + prMsduInfo->ucBssIndex, prMsduInfo->ucStaRecIndex); + + /* UC to a connected peer */ + HAL_MAC_CONNAC2X_TXD_SET_WLAN_INDEX(prTxDesc, + prMsduInfo->ucWlanIndex); + + /* Tx byte count */ + HAL_MAC_CONNAC2X_TXD_SET_TX_BYTE_COUNT(prTxDesc, + ucTxDescAndPaddingLength + prCmdInfo->u2InfoBufLen); + + /* Ether-type offset */ + ucEtherTypeOffsetInWord = + ((ETHER_HEADER_LEN - ETHER_TYPE_LEN) + + prAdapter->chip_info->pse_header_length) + >> 1; + + HAL_MAC_CONNAC2X_TXD_SET_ETHER_TYPE_OFFSET(prTxDesc, + ucEtherTypeOffsetInWord); + + /* queue index */ + HAL_MAC_CONNAC2X_TXD_SET_QUEUE_INDEX(prTxDesc, + nicTxGetTxDestQIdxByTc(ucTempTC)); + + /* Header format */ + HAL_MAC_CONNAC2X_TXD_SET_HEADER_FORMAT(prTxDesc, + HEADER_FORMAT_NON_802_11); + + /* Long Format */ + HAL_MAC_CONNAC2X_TXD_SET_LONG_FORMAT(prTxDesc); + + /* Update Packet option */ + nic_txd_v2_fill_by_pkt_option(prMsduInfo, prTxDesc); + + if (!GLUE_TEST_PKT_FLAG(prNativePacket, ENUM_PKT_802_3)) { + /* Set EthernetII */ + HAL_MAC_CONNAC2X_TXD_SET_ETHERNET_II(prTxDesc); + } + /* Header Padding */ + HAL_MAC_CONNAC2X_TXD_SET_HEADER_PADDING(prTxDesc, + NIC_TX_DESC_HEADER_PADDING_LENGTH); + + /* TID */ + HAL_MAC_CONNAC2X_TXD_SET_TID(prTxDesc, ucTid); + + /* Remaining TX time */ + HAL_MAC_CONNAC2X_TXD_SET_REMAINING_LIFE_TIME_IN_MS(prTxDesc, + nicTxGetRemainingTxTimeByTc(ucTempTC)); + + /* Tx count limit */ + HAL_MAC_CONNAC2X_TXD_SET_REMAINING_TX_COUNT(prTxDesc, + nicTxGetTxCountLimitByTc(ucTempTC)); + + /* Set lowest BSS basic rate */ + HAL_MAC_CONNAC2X_TXD_SET_FR_RATE(prTxDesc, + prBssInfo->u2HwDefaultFixedRateCode); +#if 0 /* FALCON_TODO */ + HAL_MAC_FALCON_TX_DESC_SET_FIXED_RATE_MODE_TO_DESC(prTxDesc); +#endif + HAL_MAC_CONNAC2X_TXD_SET_FIXED_RATE_ENABLE(prTxDesc); + + /* Packet Format */ + HAL_MAC_CONNAC2X_TXD_SET_PKT_FORMAT(prTxDesc, TXD_PKT_FORMAT_COMMAND); + + /* Own MAC */ + HAL_MAC_CONNAC2X_TXD_SET_OWN_MAC_INDEX(prTxDesc, + prBssInfo->ucOwnMacIndex); + + /* PID */ + if (prMsduInfo->pfTxDoneHandler) { + prMsduInfo->ucPID = + nicTxAssignPID(prAdapter, prMsduInfo->ucWlanIndex); + HAL_MAC_CONNAC2X_TXD_SET_PID(prTxDesc, prMsduInfo->ucPID); + HAL_MAC_CONNAC2X_TXD_SET_TXS_TO_MCU(prTxDesc); + } + + if (pucTxDescLength) + *pucTxDescLength = ucTxDescAndPaddingLength; +} + +void nic_txd_v2_set_pkt_fixed_rate_option_full(struct MSDU_INFO + *prMsduInfo, + uint16_t u2RateCode, + uint8_t ucBandwidth, + u_int8_t fgShortGI, + u_int8_t fgLDPC, + u_int8_t fgDynamicBwRts, u_int8_t fgBeamforming, + uint8_t ucAntennaIndex) +{ + struct HW_MAC_CONNAC2X_TX_DESC rTxDesc; + struct HW_MAC_CONNAC2X_TX_DESC *prTxDesc = &rTxDesc; + + kalMemZero(prTxDesc, NIC_TX_DESC_LONG_FORMAT_LENGTH); + + /* Follow the format of Tx descriptor DW 6 */ + HAL_MAC_CONNAC2X_TXD_SET_FR_RATE(prTxDesc, u2RateCode); + + if (ucBandwidth) + HAL_MAC_CONNAC2X_TXD_SET_FR_BW(prTxDesc, ucBandwidth); +#if 0 + if (fgBeamforming) + HAL_MAC_CONNAC2X_TXD_SET_FR_BF(prTxDesc); +#else + DBGLOG(TX, ERROR, "%s:: Need BF owner to check this setting!\n", + __func__); +#endif + if (fgShortGI) + HAL_MAC_CONNAC2X_TXD_SET_GI_TYPE(prTxDesc, SHORT_GI); + + if (fgLDPC) + HAL_MAC_CONNAC2X_TXD_SET_LDPC(prTxDesc); + + if (fgDynamicBwRts) + HAL_MAC_CONNAC2X_TXD_SET_FR_DYNAMIC_BW_RTS(prTxDesc); + + HAL_MAC_CONNAC2X_TXD_SET_FR_ANTENNA_ID(prTxDesc, ucAntennaIndex); + + /* Write back to RateOption of MSDU_INFO */ + HAL_MAC_TX_DESC_GET_DW(prTxDesc, 6, 1, + &prMsduInfo->u4FixedRateOption); + + prMsduInfo->ucRateMode = MSDU_RATE_MODE_MANUAL_DESC; + +} + +void nic_txd_v2_set_pkt_fixed_rate_option( + struct MSDU_INFO *prMsduInfo, + uint16_t u2RateCode, + uint8_t ucBandwidth, + u_int8_t fgShortGI, + u_int8_t fgDynamicBwRts) +{ + struct HW_MAC_CONNAC2X_TX_DESC rTxDesc; + struct HW_MAC_CONNAC2X_TX_DESC *prTxDesc = &rTxDesc; + + kalMemZero(prTxDesc, NIC_TX_DESC_LONG_FORMAT_LENGTH); + + /* Follow the format of Tx descriptor DW 6 */ + HAL_MAC_CONNAC2X_TXD_SET_FR_RATE(prTxDesc, u2RateCode); + + if (ucBandwidth) + HAL_MAC_CONNAC2X_TXD_SET_FR_BW(prTxDesc, ucBandwidth); + + if (fgShortGI) + HAL_MAC_CONNAC2X_TXD_SET_GI_TYPE(prTxDesc, SHORT_GI); + + if (fgDynamicBwRts) + HAL_MAC_CONNAC2X_TXD_SET_FR_DYNAMIC_BW_RTS(prTxDesc); + + /* Write back to RateOption of MSDU_INFO */ + HAL_MAC_TX_DESC_GET_DW(prTxDesc, 6, 1, + &prMsduInfo->u4FixedRateOption); + + prMsduInfo->ucRateMode = MSDU_RATE_MODE_MANUAL_DESC; + +} + +void nic_txd_v2_set_hw_amsdu_template( + struct ADAPTER *prAdapter, + struct STA_RECORD *prStaRec, + u_int8_t ucTid, + IN u_int8_t fgSet) +{ + struct HW_MAC_CONNAC2X_TX_DESC *prTxDesc; + + DBGLOG(QM, INFO, + "Update HW Amsdu field of TXD template for STA[%u] Tid[%u]\n", + prStaRec->ucIndex, ucTid); + + if (prStaRec->aprTxDescTemplate[ucTid]) { + prTxDesc = + (struct HW_MAC_CONNAC2X_TX_DESC *) + prStaRec->aprTxDescTemplate[ucTid]; + if (fgSet) + HAL_MAC_CONNAC2X_TXD_SET_HW_AMSDU(prTxDesc); + else + HAL_MAC_CONNAC2X_TXD_UNSET_HW_AMSDU(prTxDesc); + } +} +#endif /* CFG_SUPPORT_CONNAC2X == 1 */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/nic_umac.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/nic_umac.c new file mode 100644 index 0000000000000000000000000000000000000000..85fc186ccb4c692b45fb9892a71fc64eb8ffb401 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/nic_umac.c @@ -0,0 +1,458 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic_umac.c#5 + */ + +/*! \file nic_umac.c + * \brief Functions that used for debug UMAC + * + * This file includes the functions used do umac debug + * + */ + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" +#include "que_mgt.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + + + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +struct UMAC_PG_INFO_AND_RESERVE_CNT_CR_OFFSET_MAP { + uint8_t ucGroupID; + uint32_t u4PgReservePageCntRegOffset; + uint32_t u4PgInfoRegOffset; +}; + +struct UMAC_PG_MAX_MIN_QUOTA_SET { + uint8_t ucPageGroupID; + uint16_t u2MaxPageQuota; + uint16_t u2MinPageQuota; +}; + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +const struct UMAC_PG_INFO_AND_RESERVE_CNT_CR_OFFSET_MAP + g_arPlePgInfoAndReserveCrOffsetMap[] = { + { + UMAC_PG_HIF0_GROUP_0, + UMAC_PG_HIF0_GROUP(UMAC_PLE_CFG_POOL_INDEX), + UMAC_HIF0_PG_INFO(UMAC_PLE_CFG_POOL_INDEX) + }, + { + UMAC_PG_HIF0_GROUP_0, + UMAC_PG_HIF0_GROUP(UMAC_PLE_CFG_POOL_INDEX), + UMAC_HIF0_PG_INFO(UMAC_PLE_CFG_POOL_INDEX) + }, + { + UMAC_PG_CPU_GROUP_2, + UMAC_PG_CPU_GROUP(UMAC_PLE_CFG_POOL_INDEX), + UMAC_CPU_PG_INFO(UMAC_PLE_CFG_POOL_INDEX) + }, +}; + +const struct UMAC_PG_INFO_AND_RESERVE_CNT_CR_OFFSET_MAP + g_arPsePgInfoAndReserveCrOffsetMap[] = { + { + UMAC_PG_HIF0_GROUP_0, + UMAC_PG_HIF0_GROUP(UMAC_PSE_CFG_POOL_INDEX), + UMAC_HIF0_PG_INFO(UMAC_PSE_CFG_POOL_INDEX) + }, + { + UMAC_PG_HIF1_GROUP_1, + UMAC_PG_HIF1_GROUP(UMAC_PSE_CFG_POOL_INDEX), + UMAC_HIF1_PG_INFO(UMAC_PSE_CFG_POOL_INDEX) + }, + { + UMAC_PG_CPU_GROUP_2, + UMAC_PG_CPU_GROUP(UMAC_PSE_CFG_POOL_INDEX), + UMAC_CPU_PG_INFO(UMAC_PSE_CFG_POOL_INDEX) + }, + { + UMAC_PG_LMAC0_GROUP_3, + UMAC_PG_LMAC0_GROUP(UMAC_PSE_CFG_POOL_INDEX), + UMAC_LMAC0_PG_INFO(UMAC_PSE_CFG_POOL_INDEX) + }, + { + UMAC_PG_LMAC1_GROUP_4, + UMAC_PG_LMAC1_GROUP(UMAC_PSE_CFG_POOL_INDEX), + UMAC_LMAC1_PG_INFO(UMAC_PSE_CFG_POOL_INDEX) + }, + { + UMAC_PG_LMAC2_GROUP_5, + UMAC_PG_LMAC2_GROUP(UMAC_PSE_CFG_POOL_INDEX), + UMAC_LMAC2_PG_INFO(UMAC_PSE_CFG_POOL_INDEX) + }, + { + UMAC_PG_PLE_GROUP_6, + UMAC_PG_PLE_GROUP(UMAC_PSE_CFG_POOL_INDEX), + UMAC_PLE_PG_INFO(UMAC_PSE_CFG_POOL_INDEX) + }, +}; + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief halUmacWrapSourcePortSanityCheck: + * + * @param IN BOOLEAN fgPsePleFlag, + * IN UINT_8 ucPageGroupID + * @return TRUE/FALSE + */ +/*----------------------------------------------------------------------------*/ + +OUT u_int8_t halUmacWrapSourcePortSanityCheck( + IN u_int8_t fgPsePleFlag, IN uint8_t ucPageGroupID) +{ + + if (fgPsePleFlag == UMAC_PSE_CFG_POOL_INDEX) { + if (ucPageGroupID > UMAC_PG_PLE_GROUP_6) + return FALSE; + } else if (fgPsePleFlag == UMAC_PLE_CFG_POOL_INDEX) { + if ((ucPageGroupID != UMAC_PG_HIF0_GROUP_0) + && (ucPageGroupID != UMAC_PG_CPU_GROUP_2)) + return FALSE; + } else + return FALSE; + + return TRUE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief halUmacWrapRsvPgCnt: + * + * @param IN P_ADAPTER_T prAdapter + * IN BOOLEAN fgPsePleFlag, + * IN UINT_8 ucPageGroupID + * @return UINT_16 + */ +/*----------------------------------------------------------------------------*/ + +OUT uint16_t halUmacWrapRsvPgCnt(IN struct ADAPTER + *prAdapter, IN u_int8_t fgPsePleFlag, + IN uint8_t ucPageGroupID) +{ + uint32_t u4RegAddr = 0; + uint32_t u4Value = 0; + + if (halUmacWrapSourcePortSanityCheck(fgPsePleFlag, + ucPageGroupID) == FALSE) + return UMAC_FID_FAULT; + + if (fgPsePleFlag == UMAC_PSE_CFG_POOL_INDEX) + u4RegAddr = + g_arPsePgInfoAndReserveCrOffsetMap[ucPageGroupID]. + u4PgInfoRegOffset; + else if (fgPsePleFlag == UMAC_PLE_CFG_POOL_INDEX) + u4RegAddr = + g_arPlePgInfoAndReserveCrOffsetMap[ucPageGroupID]. + u4PgInfoRegOffset; + + HAL_MCR_RD(prAdapter, u4RegAddr, &u4Value); + + return (uint16_t) (u4Value & BITS(0, 11)); +} + + +/*----------------------------------------------------------------------------*/ +/*! + * @brief halUmacWrapSrcPgCnt: + * + * @param IN P_ADAPTER_T prAdapter + * IN BOOLEAN fgPsePleFlag, + * IN UINT_8 ucPageGroupID + * @return UINT_16 + */ +/*----------------------------------------------------------------------------*/ + +OUT uint16_t halUmacWrapSrcPgCnt(IN struct ADAPTER + *prAdapter, IN u_int8_t fgPsePleFlag, + IN uint8_t ucPageGroupID) +{ + uint32_t u4RegAddr = 0; + uint32_t u4Value = 0; + + if (halUmacWrapSourcePortSanityCheck(fgPsePleFlag, + ucPageGroupID) == FALSE) + return UMAC_FID_FAULT; + + if (fgPsePleFlag == UMAC_PSE_CFG_POOL_INDEX) + u4RegAddr = + g_arPsePgInfoAndReserveCrOffsetMap[ucPageGroupID]. + u4PgInfoRegOffset; + else if (fgPsePleFlag == UMAC_PLE_CFG_POOL_INDEX) + u4RegAddr = + g_arPlePgInfoAndReserveCrOffsetMap[ucPageGroupID]. + u4PgInfoRegOffset; + + HAL_MCR_RD(prAdapter, u4RegAddr, &u4Value); + + return (uint16_t) ((u4Value & BITS(16, 27)) >> 16); +} + + +/*----------------------------------------------------------------------------*/ +/*! + * @brief halUmacPbufCtrlTotalPageNum: + * + * @param IN P_ADAPTER_T prAdapter + * IN BOOLEAN fgPsePleFlag, + * @return UINT_16 + */ +/*----------------------------------------------------------------------------*/ + +OUT uint16_t halUmacPbufCtrlTotalPageNum(IN struct ADAPTER + *prAdapter, IN uint16_t fgPsePleFlag) +{ + uint32_t u4Value = 0; + + HAL_MCR_RD(prAdapter, UMAC_PBUF_CTRL(fgPsePleFlag), + &u4Value); + + return (uint16_t) (u4Value & + UMAC_PBUF_CTRL_TOTAL_PAGE_NUM_MASK); +} + + +/*----------------------------------------------------------------------------*/ +/*! + * @brief halUmacWrapFrePageCnt: + * + * @param IN P_ADAPTER_T prAdapter + * IN BOOLEAN fgPsePleFlag, + * @return UINT_16 + */ +/*----------------------------------------------------------------------------*/ + +OUT uint16_t halUmacWrapFrePageCnt(IN struct ADAPTER + *prAdapter, IN u_int8_t fgPsePleFlag) +{ + uint32_t u4Value = 0; + + HAL_MCR_RD(prAdapter, UMAC_FREEPG_CNT(fgPsePleFlag), + &u4Value); + return (u4Value & UMAC_FREEPG_CNT_FREEPAGE_CNT_MASK) >> + UMAC_FREEPG_CNT_FREEPAGE_CNT_OFFSET; +} + + +/*----------------------------------------------------------------------------*/ +/*! + * @brief halUmacWrapFfaCnt: + * + * @param IN P_ADAPTER_T prAdapter + * IN BOOLEAN fgPsePleFlag, + * @return UINT_16 + */ +/*----------------------------------------------------------------------------*/ + +OUT uint16_t halUmacWrapFfaCnt(IN struct ADAPTER *prAdapter, + IN u_int8_t fgPsePleFlag) +{ + uint32_t u4Value = 0; + + HAL_MCR_RD(prAdapter, UMAC_FREEPG_CNT(fgPsePleFlag), + &u4Value); + return (u4Value & UMAC_FREEPG_CNT_FFA_CNT_MASK) >> + UMAC_FREEPG_CNT_FFA_CNT_OFFSET; +} + + +/*----------------------------------------------------------------------------*/ +/*! + * @brief halUmacInfoGetMiscStatus: + * + * @param IN P_ADAPTER_T prAdapter + * IN P_UMAC_STAT2_GET_T pUmacStat2Get, + * @return UINT_16 + */ +/*----------------------------------------------------------------------------*/ + + +OUT u_int8_t halUmacInfoGetMiscStatus(IN struct ADAPTER + *prAdapter, IN struct UMAC_STAT2_GET *pUmacStat2Get) +{ + pUmacStat2Get->u2PleRevPgHif0Group0 = + halUmacWrapRsvPgCnt(prAdapter, UMAC_PLE_CFG_POOL_INDEX, + UMAC_PG_HIF0_GROUP_0); + + pUmacStat2Get->u2PleRevPgCpuGroup2 = + halUmacWrapRsvPgCnt(prAdapter, UMAC_PLE_CFG_POOL_INDEX, + UMAC_PG_CPU_GROUP_2); + + pUmacStat2Get->u2PseRevPgHif0Group0 = + halUmacWrapRsvPgCnt(prAdapter, UMAC_PSE_CFG_POOL_INDEX, + UMAC_PG_HIF0_GROUP_0); + + pUmacStat2Get->u2PseRevPgHif1Group1 = + halUmacWrapRsvPgCnt(prAdapter, UMAC_PSE_CFG_POOL_INDEX, + UMAC_PG_HIF1_GROUP_1); + + pUmacStat2Get->u2PseRevPgCpuGroup2 = + halUmacWrapRsvPgCnt(prAdapter, UMAC_PSE_CFG_POOL_INDEX, + UMAC_PG_CPU_GROUP_2); + + pUmacStat2Get->u2PseRevPgLmac0Group3 = + halUmacWrapRsvPgCnt(prAdapter, UMAC_PSE_CFG_POOL_INDEX, + UMAC_PG_LMAC0_GROUP_3); + + pUmacStat2Get->u2PseRevPgLmac1Group4 = + halUmacWrapRsvPgCnt(prAdapter, UMAC_PSE_CFG_POOL_INDEX, + UMAC_PG_LMAC1_GROUP_4); + + pUmacStat2Get->u2PseRevPgLmac2Group5 = + halUmacWrapRsvPgCnt(prAdapter, UMAC_PSE_CFG_POOL_INDEX, + UMAC_PG_LMAC2_GROUP_5); + + pUmacStat2Get->u2PseRevPgPleGroup6 = + halUmacWrapRsvPgCnt(prAdapter, UMAC_PSE_CFG_POOL_INDEX, + UMAC_PG_PLE_GROUP_6); + + pUmacStat2Get->u2PleSrvPgHif0Group0 = + halUmacWrapSrcPgCnt(prAdapter, UMAC_PLE_CFG_POOL_INDEX, + UMAC_PG_HIF0_GROUP_0); + + pUmacStat2Get->u2PleSrvPgCpuGroup2 = + halUmacWrapSrcPgCnt(prAdapter, UMAC_PLE_CFG_POOL_INDEX, + UMAC_PG_CPU_GROUP_2); + + pUmacStat2Get->u2PseSrvPgHif0Group0 = + halUmacWrapSrcPgCnt(prAdapter, UMAC_PSE_CFG_POOL_INDEX, + UMAC_PG_HIF0_GROUP_0); + + pUmacStat2Get->u2PseSrvPgHif1Group1 = + halUmacWrapSrcPgCnt(prAdapter, UMAC_PSE_CFG_POOL_INDEX, + UMAC_PG_HIF1_GROUP_1); + + pUmacStat2Get->u2PseSrvPgCpuGroup2 = + halUmacWrapSrcPgCnt(prAdapter, UMAC_PSE_CFG_POOL_INDEX, + UMAC_PG_CPU_GROUP_2); + + pUmacStat2Get->u2PseSrvPgLmac0Group3 = + halUmacWrapSrcPgCnt(prAdapter, UMAC_PSE_CFG_POOL_INDEX, + UMAC_PG_LMAC0_GROUP_3); + + pUmacStat2Get->u2PseSrvPgLmac1Group4 = + halUmacWrapSrcPgCnt(prAdapter, UMAC_PSE_CFG_POOL_INDEX, + UMAC_PG_LMAC1_GROUP_4); + + pUmacStat2Get->u2PseSrvPgLmac2Group5 = + halUmacWrapSrcPgCnt(prAdapter, UMAC_PSE_CFG_POOL_INDEX, + UMAC_PG_LMAC2_GROUP_5); + + pUmacStat2Get->u2PseSrvPgPleGroup6 = + halUmacWrapSrcPgCnt(prAdapter, UMAC_PSE_CFG_POOL_INDEX, + UMAC_PG_PLE_GROUP_6); + + + pUmacStat2Get->u2PleTotalPageNum = + halUmacPbufCtrlTotalPageNum(prAdapter, + UMAC_PLE_CFG_POOL_INDEX); + + pUmacStat2Get->u2PseTotalPageNum = + halUmacPbufCtrlTotalPageNum(prAdapter, + UMAC_PSE_CFG_POOL_INDEX); + + pUmacStat2Get->u2PleFreePageNum = halUmacWrapFrePageCnt( + prAdapter, UMAC_PLE_CFG_POOL_INDEX); + + pUmacStat2Get->u2PseFreePageNum = halUmacWrapFrePageCnt( + prAdapter, UMAC_PSE_CFG_POOL_INDEX); + + pUmacStat2Get->u2PleFfaNum = halUmacWrapFfaCnt(prAdapter, + UMAC_PLE_CFG_POOL_INDEX); + + pUmacStat2Get->u2PseFfaNum = halUmacWrapFfaCnt(prAdapter, + UMAC_PSE_CFG_POOL_INDEX); + + return TRUE; +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/p2p_nic.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/p2p_nic.c new file mode 100644 index 0000000000000000000000000000000000000000..b0379c459897412e2aaf780f8308a5f32136c2c0 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/p2p_nic.c @@ -0,0 +1,283 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: @(#) p2p_nic.c@@ + */ + +/*! \file p2p_nic.c + * \brief Wi-Fi Direct Functions that provide operation + * in NIC's (Network Interface Card) point of view. + * + * This file includes functions which unite multiple hal(Hardware) operations + * and also take the responsibility of Software Resource Management in order + * to keep the synchronization with Hardware Manipulation. + */ + +/****************************************************************************** + * C O M P I L E R F L A G S + ****************************************************************************** + */ + +/****************************************************************************** + * E X T E R N A L R E F E R E N C E S + ****************************************************************************** + */ + +#include "precomp.h" + +/****************************************************************************** + * C O N S T A N T S + ****************************************************************************** + */ + +/****************************************************************************** + * D A T A T Y P E S + ****************************************************************************** + */ + +/****************************************************************************** + * P U B L I C D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * P R I V A T E D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * M A C R O S + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N D E C L A R A T I O N S + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N S + ****************************************************************************** + */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief When Probe Rsp & Beacon frame is received and decide a P2P device, + * this function will be invoked to buffer scan result + * + * @param prAdapter Pointer to the Adapter structure. + * @param prEventScanResult Pointer of EVENT_SCAN_RESULT_T. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void +nicRxAddP2pDevice(IN struct ADAPTER *prAdapter, + IN struct EVENT_P2P_DEV_DISCOVER_RESULT *prP2pResult, + IN uint8_t *pucRxIEBuf, + IN uint16_t u2RxIELength) +{ + struct P2P_INFO *prP2pInfo = (struct P2P_INFO *) NULL; + struct EVENT_P2P_DEV_DISCOVER_RESULT *prTargetResult = + (struct EVENT_P2P_DEV_DISCOVER_RESULT *) NULL; + uint32_t u4Idx = 0; + u_int8_t bUpdate = FALSE; + + uint8_t *pucIeBuf = (uint8_t *) NULL; + uint16_t u2IELength = 0; + uint8_t zeroMac[] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }; + + ASSERT(prAdapter); + + prP2pInfo = prAdapter->prP2pInfo; + + for (u4Idx = 0; u4Idx < prP2pInfo->u4DeviceNum; u4Idx++) { + prTargetResult = &prP2pInfo->arP2pDiscoverResult[u4Idx]; + + if (EQUAL_MAC_ADDR(prTargetResult->aucDeviceAddr, + prP2pResult->aucDeviceAddr)) { + + bUpdate = TRUE; + + /* Backup OLD buffer result. */ + pucIeBuf = prTargetResult->pucIeBuf; + u2IELength = prTargetResult->u2IELength; + + /* Update Device Info. */ + /* zero */ + kalMemZero(prTargetResult, + sizeof(struct EVENT_P2P_DEV_DISCOVER_RESULT)); + + /* then buffer */ + kalMemCopy(prTargetResult, + (void *) prP2pResult, + sizeof(struct EVENT_P2P_DEV_DISCOVER_RESULT)); + + /* See if new IE length is longer or not. */ + if ((u2RxIELength > u2IELength) && (u2IELength != 0)) { + /* Buffer is not enough. */ + u2RxIELength = u2IELength; + } else if ((u2IELength == 0) && (u2RxIELength != 0)) { + /* RX new IE buf. */ + ASSERT(pucIeBuf == NULL); + pucIeBuf = prP2pInfo->pucCurrIePtr; + + if (((unsigned long) prP2pInfo->pucCurrIePtr + + (unsigned long) u2RxIELength) > + (unsigned long)& + prP2pInfo->aucCommIePool + [CFG_MAX_COMMON_IE_BUF_LEN]) { + + /* Common Buffer is no enough. */ + u2RxIELength = + (uint16_t) ((unsigned long) + &prP2pInfo->aucCommIePool + [CFG_MAX_COMMON_IE_BUF_LEN] - + (unsigned long) + prP2pInfo->pucCurrIePtr); + } + + /* Step to next buffer address. */ + prP2pInfo->pucCurrIePtr = + (uint8_t *) ((unsigned long) + prP2pInfo->pucCurrIePtr + + (unsigned long) u2RxIELength); + } + + /* Restore buffer pointer. */ + prTargetResult->pucIeBuf = pucIeBuf; + + if (pucRxIEBuf) { + /* If new received IE is available. + * Replace the old one & update new IE length. + */ + kalMemCopy(pucIeBuf, pucRxIEBuf, u2RxIELength); + prTargetResult->u2IELength = u2RxIELength; + } else { + /* There is no new IE information, + * keep the old one. + */ + prTargetResult->u2IELength = u2IELength; + } + } + } + + if (!bUpdate) { + /* We would flush the whole scan result + * after each scan request is issued. + * If P2P device is too many, it may over the scan list. + */ + if ((u4Idx < CFG_MAX_NUM_BSS_LIST) + && (UNEQUAL_MAC_ADDR(zeroMac, + prP2pResult->aucDeviceAddr))) { + + prTargetResult = &prP2pInfo->arP2pDiscoverResult[u4Idx]; + + /* zero */ + kalMemZero(prTargetResult, + sizeof(struct EVENT_P2P_DEV_DISCOVER_RESULT)); + + /* then buffer */ + kalMemCopy(prTargetResult, + (void *) prP2pResult, + sizeof(struct EVENT_P2P_DEV_DISCOVER_RESULT)); + + /* printk("DVC FND %d " MACSTR", " MACSTR "\n", + * prP2pInfo->u4DeviceNum, + * MAC2STR(prP2pResult->aucDeviceAddr), + * MAC2STR(prTargetResult->aucDeviceAddr)); + */ + + if (u2RxIELength) { + prTargetResult->pucIeBuf = + prP2pInfo->pucCurrIePtr; + + if (((unsigned long) prP2pInfo->pucCurrIePtr + + (unsigned long) u2RxIELength) > + (unsigned long) + &prP2pInfo->aucCommIePool + [CFG_MAX_COMMON_IE_BUF_LEN]) { + + /* Common Buffer is no enough. */ + u2IELength = + (uint16_t) ((unsigned long) + &prP2pInfo->aucCommIePool + [CFG_MAX_COMMON_IE_BUF_LEN] - + (unsigned long) + prP2pInfo->pucCurrIePtr); + } else { + u2IELength = u2RxIELength; + } + + prP2pInfo->pucCurrIePtr = + (uint8_t *) ((unsigned long) + prP2pInfo->pucCurrIePtr + + (unsigned long) u2IELength); + + kalMemCopy((void *) prTargetResult->pucIeBuf, + (void *) pucRxIEBuf, + (uint32_t) u2IELength); + + prTargetResult->u2IELength = u2IELength; + } else { + prTargetResult->pucIeBuf = NULL; + prTargetResult->u2IELength = 0; + } + + prP2pInfo->u4DeviceNum++; + + } else { + /* TODO: Fixme to replace an old one. (?) */ + ASSERT(FALSE); + } + } +} /* nicRxAddP2pDevice */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/que_mgt.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/que_mgt.c new file mode 100644 index 0000000000000000000000000000000000000000..782ec5135fd1cae6d546b849a24fa2bc34f4e63e --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/nic/que_mgt.c @@ -0,0 +1,8627 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/*! \file "que_mgt.c" + * \brief TX/RX queues management + * + * The main tasks of queue management include TC-based HIF TX flow control, + * adaptive TC quota adjustment, HIF TX grant scheduling, Power-Save + * forwarding control, RX packet reordering, and RX BA agreement management. + */ + + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" +#include "queue.h" +#if CFG_MTK_MCIF_WIFI_SUPPORT +#include "mddp.h" +#endif +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ +OS_SYSTIME g_arMissTimeout[CFG_STA_REC_NUM][CFG_RX_MAX_BA_TID_NUM]; + +const uint8_t aucTid2ACI[TX_DESC_TID_NUM] = { + WMM_AC_BE_INDEX, /* TID0 */ + WMM_AC_BK_INDEX, /* TID1 */ + WMM_AC_BK_INDEX, /* TID2 */ + WMM_AC_BE_INDEX, /* TID3 */ + WMM_AC_VI_INDEX, /* TID4 */ + WMM_AC_VI_INDEX, /* TID5 */ + WMM_AC_VO_INDEX, /* TID6 */ + WMM_AC_VO_INDEX /* TID7 */ +}; + +const uint8_t aucACI2TxQIdx[WMM_AC_INDEX_NUM] = { + TX_QUEUE_INDEX_AC1, /* WMM_AC_BE_INDEX */ + TX_QUEUE_INDEX_AC0, /* WMM_AC_BK_INDEX */ + TX_QUEUE_INDEX_AC2, /* WMM_AC_VI_INDEX */ + TX_QUEUE_INDEX_AC3 /* WMM_AC_VO_INDEX */ +}; + +const uint8_t *apucACI2Str[WMM_AC_INDEX_NUM] = { + "BE", "BK", "VI", "VO" +}; + +const uint8_t arNetwork2TcResource[MAX_BSSID_NUM + 1][NET_TC_NUM] = { + /* HW Queue Set 1 */ + /* AC_BE, AC_BK, AC_VI, AC_VO, MGMT, BMC */ + /* AIS */ + {TC1_INDEX, TC0_INDEX, TC2_INDEX, TC3_INDEX, TC4_INDEX, BMC_TC_INDEX}, + /* P2P/BoW */ + {TC1_INDEX, TC0_INDEX, TC2_INDEX, TC3_INDEX, TC4_INDEX, BMC_TC_INDEX}, + /* P2P/BoW */ + {TC1_INDEX, TC0_INDEX, TC2_INDEX, TC3_INDEX, TC4_INDEX, BMC_TC_INDEX}, + /* P2P/BoW */ + {TC1_INDEX, TC0_INDEX, TC2_INDEX, TC3_INDEX, TC4_INDEX, BMC_TC_INDEX}, + /* P2P_DEV */ + {TC1_INDEX, TC0_INDEX, TC2_INDEX, TC3_INDEX, TC4_INDEX, BMC_TC_INDEX}, +}; + +const uint8_t aucWmmAC2TcResourceSet1[WMM_AC_INDEX_NUM] = { + TC1_INDEX, + TC0_INDEX, + TC2_INDEX, + TC3_INDEX +}; + +#if NIC_TX_ENABLE_SECOND_HW_QUEUE +const uint8_t aucWmmAC2TcResourceSet2[WMM_AC_INDEX_NUM] = { + TC7_INDEX, + TC6_INDEX, + TC8_INDEX, + TC9_INDEX +}; +#endif +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ +#if ARP_MONITER_ENABLE +static uint16_t arpMoniter; +static uint8_t apIp[4]; +static uint8_t gatewayIp[4]; +static uint32_t last_rx_packets, latest_rx_packets; +#endif +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ +#ifdef CFG_SUPPORT_LINK_QUALITY_MONITOR +#define LINK_QUALITY_COUNT_DUP(prAdapter, prSwRfb) \ +do { \ + struct BSS_INFO *prBssInfo = NULL; \ + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, \ + AIS_DEFAULT_INDEX); \ + if (prBssInfo && prBssInfo->prStaRecOfAP) \ + if (prBssInfo->prStaRecOfAP->ucWlanIndex == \ + prSwRfb->ucWlanIdx) \ + prAdapter->rLinkQualityInfo.u4RxDupCount++; \ +} while (0) +#else +#define LINK_QUALITY_COUNT_DUP +#endif /* CFG_SUPPORT_LINK_QUALITY_MONITOR */ + +#if CFG_RX_REORDERING_ENABLED +#define qmHandleRxPackets_AOSP_1 \ +do { \ + DBGLOG(RX, TEMP, "qmHandleRxPackets_AOSP_1 %p\n", prCurrSwRfb); \ + /* ToDo[6630]: duplicate removal */ \ + if (!fgIsBMC && nicRxIsDuplicateFrame(prCurrSwRfb) == TRUE) { \ + DBGLOG(RX, TEMP, "Duplicated packet is detected\n"); \ + RX_INC_CNT(&prAdapter->rRxCtrl, RX_DUPICATE_DROP_COUNT); \ + LINK_QUALITY_COUNT_DUP(prAdapter, prCurrSwRfb); \ + prCurrSwRfb->eDst = RX_PKT_DESTINATION_NULL; \ + } \ + /* ToDo[6630]: defragmentation */ \ + if (prCurrSwRfb->fgFragFrame) { \ + prCurrSwRfb = nicRxDefragMPDU(prAdapter, \ + prCurrSwRfb, prReturnedQue); \ + if (prCurrSwRfb) { \ + prRxStatus = prCurrSwRfb->prRxStatus; \ + DBGLOG(RX, TEMP, \ + "defragmentation RxStatus=%p\n", prRxStatus); \ + } \ + } \ + if (prCurrSwRfb) { \ + fgMicErr = FALSE; \ + if (prCurrSwRfb->ucSecMode == \ + CIPHER_SUITE_TKIP_WO_MIC) { \ + if (prCurrSwRfb->prStaRec) { \ + uint8_t ucBssIndex; \ + struct BSS_INFO *prBssInfo = NULL; \ + uint8_t *pucMicKey = NULL; \ + ucBssIndex = \ + prCurrSwRfb->prStaRec->ucBssIndex; \ + ASSERT(ucBssIndex < prAdapter->ucHwBssIdNum); \ + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, \ + ucBssIndex); \ + ASSERT(prBssInfo); \ + if (prBssInfo->eCurrentOPMode == \ + OP_MODE_INFRASTRUCTURE) \ + pucMicKey = \ + &(aisGetAisSpecBssInfo(prAdapter, \ + ucBssIndex)->aucRxMicKey[0]); \ + else { \ + ASSERT(FALSE); \ + } \ + /* SW TKIP MIC verify */ \ + if (pucMicKey == NULL) { \ + DBGLOG(RX, ERROR, \ + "No TKIP Mic Key\n"); \ + fgMicErr = TRUE; \ + } \ + else if (tkipMicDecapsulateInRxHdrTransMode( \ + prCurrSwRfb, pucMicKey) == FALSE) { \ + fgMicErr = TRUE; \ + } \ + } \ + if (fgMicErr) { \ + /* bypass tkip frag */ \ + if (!prCurrSwRfb->fgFragFrame) { \ + log_dbg(RX, ERROR, \ + "Mark NULL for TKIP Mic Error\n"); \ + RX_INC_CNT(&prAdapter->rRxCtrl, \ + RX_MIC_ERROR_DROP_COUNT); \ + prCurrSwRfb->eDst = \ + RX_PKT_DESTINATION_NULL; \ + } \ + } \ + } \ + QUEUE_INSERT_TAIL(prReturnedQue, \ + (struct QUE_ENTRY *)prCurrSwRfb); \ + } \ +} while (0) +#endif + +#define RX_DIRECT_REORDER_LOCK(pad, dbg) \ +do { \ + struct GLUE_INFO *_glue = pad->prGlueInfo; \ + if (!HAL_IS_RX_DIRECT(pad) || !_glue) \ + break; \ + if (dbg) \ + DBGLOG(QM, EVENT, "RX_DIRECT_REORDER_LOCK %d\n", __LINE__); \ + spin_lock_bh(&_glue->rSpinLock[SPIN_LOCK_RX_DIRECT_REORDER]);\ +} while (0) + +#define RX_DIRECT_REORDER_UNLOCK(pad, dbg) \ +do { \ + struct GLUE_INFO *_glue = pad->prGlueInfo; \ + if (!HAL_IS_RX_DIRECT(pad) || !_glue) \ + break; \ + if (dbg) \ + DBGLOG(QM, EVENT, "RX_DIRECT_REORDER_UNLOCK %u\n", __LINE__); \ + spin_unlock_bh(&_glue->rSpinLock[SPIN_LOCK_RX_DIRECT_REORDER]); \ +} while (0) + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Init Queue Management for TX + * + * \param[in] (none) + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void qmInit(IN struct ADAPTER *prAdapter, + IN u_int8_t isTxResrouceControlEn) +{ + uint32_t u4Idx; +#if QM_ADAPTIVE_TC_RESOURCE_CTRL + uint32_t u4TotalMinReservedTcResource = 0; + uint32_t u4TotalTcResource = 0; + uint32_t u4TotalGurantedTcResource = 0; +#endif + + struct QUE_MGT *prQM = &prAdapter->rQM; + + /* DbgPrint("QM: Enter qmInit()\n"); */ + + /* 4 <2> Initialize other TX queues (queues not in STA_RECs) */ + for (u4Idx = 0; u4Idx < NUM_OF_PER_TYPE_TX_QUEUES; u4Idx++) + QUEUE_INITIALIZE(&(prQM->arTxQueue[u4Idx])); + + /* 4 <3> Initialize the RX BA table and RX queues */ + /* Initialize the RX Reordering Parameters and Queues */ + for (u4Idx = 0; u4Idx < CFG_NUM_OF_RX_BA_AGREEMENTS; u4Idx++) { + prQM->arRxBaTable[u4Idx].fgIsValid = FALSE; + QUEUE_INITIALIZE(&(prQM->arRxBaTable[u4Idx].rReOrderQue)); + prQM->arRxBaTable[u4Idx].u2WinStart = 0xFFFF; + prQM->arRxBaTable[u4Idx].u2WinEnd = 0xFFFF; + + prQM->arRxBaTable[u4Idx].fgIsWaitingForPktWithSsn = FALSE; + prQM->arRxBaTable[u4Idx].fgHasBubble = FALSE; +#if CFG_SUPPORT_RX_AMSDU + /* RX reorder for one MSDU in AMSDU issue */ + prQM->arRxBaTable[u4Idx].u8LastAmsduSubIdx = + RX_PAYLOAD_FORMAT_MSDU; + prQM->arRxBaTable[u4Idx].fgAmsduNeedLastFrame = FALSE; + prQM->arRxBaTable[u4Idx].fgIsAmsduDuplicated = FALSE; +#endif + cnmTimerInitTimer(prAdapter, + &(prQM->arRxBaTable[u4Idx].rReorderBubbleTimer), + (PFN_MGMT_TIMEOUT_FUNC) qmHandleReorderBubbleTimeout, + (unsigned long) (&prQM->arRxBaTable[u4Idx])); + + } + prQM->ucRxBaCount = 0; + + kalMemSet(&g_arMissTimeout, 0, sizeof(g_arMissTimeout)); + + prQM->fgIsTxResrouceControlEn = isTxResrouceControlEn; + +#if QM_ADAPTIVE_TC_RESOURCE_CTRL + /* 4 <4> Initialize TC resource control variables */ + for (u4Idx = 0; u4Idx < TC_NUM; u4Idx++) + prQM->au4AverageQueLen[u4Idx] = 0; + + ASSERT(prQM->u4TimeToAdjustTcResource + && prQM->u4TimeToUpdateQueLen); + + for (u4Idx = 0; u4Idx < TC_NUM; u4Idx++) { + prQM->au4CurrentTcResource[u4Idx] = + prAdapter->rTxCtrl.rTc.au4MaxNumOfBuffer[u4Idx]; + + if (u4Idx != TC4_INDEX) { + u4TotalTcResource += prQM->au4CurrentTcResource[u4Idx]; + u4TotalGurantedTcResource += + prQM->au4GuaranteedTcResource[u4Idx]; + u4TotalMinReservedTcResource += + prQM->au4MinReservedTcResource[u4Idx]; + } + } + + /* Sanity Check */ + if (u4TotalMinReservedTcResource > u4TotalTcResource) + kalMemZero(prQM->au4MinReservedTcResource, + sizeof(prQM->au4MinReservedTcResource)); + + if (u4TotalGurantedTcResource > u4TotalTcResource) + kalMemZero(prQM->au4GuaranteedTcResource, + sizeof(prQM->au4GuaranteedTcResource)); + + u4TotalGurantedTcResource = 0; + + /* Initialize Residual TC resource */ + for (u4Idx = 0; u4Idx < TC_NUM; u4Idx++) { + if (prQM->au4GuaranteedTcResource[u4Idx] < + prQM->au4MinReservedTcResource[u4Idx]) + prQM->au4GuaranteedTcResource[u4Idx] = + prQM->au4MinReservedTcResource[u4Idx]; + + if (u4Idx != TC4_INDEX) + u4TotalGurantedTcResource += + prQM->au4GuaranteedTcResource[u4Idx]; + } + + prQM->u4ResidualTcResource = u4TotalTcResource - + u4TotalGurantedTcResource; + + prQM->fgTcResourcePostAnnealing = FALSE; + prQM->fgForceReassign = FALSE; +#if QM_FAST_TC_RESOURCE_CTRL + prQM->fgTcResourceFastReaction = FALSE; +#endif +#endif + +#if QM_TEST_MODE + prQM->u4PktCount = 0; + +#if QM_TEST_FAIR_FORWARDING + + prQM->u4CurrentStaRecIndexToEnqueue = 0; + { + uint8_t aucMacAddr[MAC_ADDR_LEN]; + struct STA_RECORD *prStaRec; + + /* Irrelevant in case this STA is an AIS AP + * (see qmDetermineStaRecIndex()) + */ + aucMacAddr[0] = 0x11; + aucMacAddr[1] = 0x22; + aucMacAddr[2] = 0xAA; + aucMacAddr[3] = 0xBB; + aucMacAddr[4] = 0xCC; + aucMacAddr[5] = 0xDD; + + prStaRec = &prAdapter->arStaRec[1]; + ASSERT(prStaRec); + + prStaRec->fgIsValid = TRUE; + prStaRec->fgIsQoS = TRUE; + prStaRec->fgIsInPS = FALSE; + prStaRec->ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; + COPY_MAC_ADDR((prStaRec)->aucMacAddr, aucMacAddr); + + } + +#endif + +#endif + +#if QM_FORWARDING_FAIRNESS + for (u4Idx = 0; u4Idx < NUM_OF_PER_STA_TX_QUEUES; u4Idx++) { + prQM->au4ResourceUsedCount[u4Idx] = 0; + prQM->au4HeadStaRecIndex[u4Idx] = 0; + } + + prQM->u4GlobalResourceUsedCount = 0; +#endif + + prQM->u4TxAllowedStaCount = 0; + + prQM->rLastTxPktDumpTime = (OS_SYSTIME) kalGetTimeTick(); + +} + +#if QM_TEST_MODE +void qmTestCases(IN struct ADAPTER *prAdapter) +{ + struct QUE_MGT *prQM = &prAdapter->rQM; + + DbgPrint("QM: ** TEST MODE **\n"); + + if (QM_TEST_STA_REC_DETERMINATION) { + if (prAdapter->arStaRec[0].fgIsValid) { + prAdapter->arStaRec[0].fgIsValid = FALSE; + DbgPrint("QM: (Test) Deactivate STA_REC[0]\n"); + } else { + prAdapter->arStaRec[0].fgIsValid = TRUE; + DbgPrint("QM: (Test) Activate STA_REC[0]\n"); + } + } + + if (QM_TEST_STA_REC_DEACTIVATION) { + /* Note that QM_STA_REC_HARD_CODING + * shall be set to 1 for this test + */ + + if (prAdapter->arStaRec[0].fgIsValid) { + + DbgPrint("QM: (Test) Deactivate STA_REC[0]\n"); + qmDeactivateStaRec(prAdapter, &prAdapter->arStaRec[0]); + } else { + + uint8_t aucMacAddr[MAC_ADDR_LEN]; + + /* Irrelevant in case this STA is an AIS AP + * (see qmDetermineStaRecIndex()) + */ + aucMacAddr[0] = 0x11; + aucMacAddr[1] = 0x22; + aucMacAddr[2] = 0xAA; + aucMacAddr[3] = 0xBB; + aucMacAddr[4] = 0xCC; + aucMacAddr[5] = 0xDD; + + DbgPrint("QM: (Test) Activate STA_REC[0]\n"); + qmActivateStaRec(prAdapter, /* Adapter pointer */ + 0, /* STA_REC index from FW */ + TRUE, /* fgIsQoS */ + NETWORK_TYPE_AIS_INDEX, /* Network type */ + TRUE, /* fgIsAp */ + aucMacAddr /* MAC address */ + ); + } + } + + if (QM_TEST_FAIR_FORWARDING) { + if (prAdapter->arStaRec[1].fgIsValid) { + prQM->u4CurrentStaRecIndexToEnqueue++; + prQM->u4CurrentStaRecIndexToEnqueue %= 2; + DbgPrint("QM: (Test) Switch to STA_REC[%ld]\n", + prQM->u4CurrentStaRecIndexToEnqueue); + } + } + +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Update a STA_REC + * + * \param[in] prAdapter Pointer to the Adapter instance + * \param[in] prStaRec The pointer of the STA_REC + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void qmUpdateStaRec(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec) +{ + struct BSS_INFO *prBssInfo; + u_int8_t fgIsTxAllowed = FALSE; + + if (!prStaRec) + return; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex); + + ASSERT(prBssInfo); + + /* 4 <1> Ensure STA is valid */ + if (prStaRec->fgIsValid) { + /* 4 <2.1> STA/BSS is protected */ + if (secIsProtectedBss(prAdapter, prBssInfo)) { + if (prStaRec->fgIsTxKeyReady || + secIsWepBss(prAdapter, prBssInfo)) + fgIsTxAllowed = TRUE; + else + fgIsTxAllowed = FALSE; + } + /* 4 <2.2> OPEN security */ + else + fgIsTxAllowed = TRUE; + } + /* 4 Update StaRec */ + qmSetStaRecTxAllowed(prAdapter, prStaRec, fgIsTxAllowed); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Activate a STA_REC + * + * \param[in] prAdapter Pointer to the Adapter instance + * \param[in] prStaRec The pointer of the STA_REC + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void qmActivateStaRec(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec) +{ + /* 4 <1> Deactivate first */ + if (!prStaRec) + return; + + if (prStaRec->fgIsValid) { /* The STA_REC has been activated */ + DBGLOG(QM, WARN, + "QM: (WARNING) Activating a STA_REC which has been activated\n"); + DBGLOG(QM, WARN, + "QM: (WARNING) Deactivating a STA_REC before re-activating\n"); + /* To flush TX/RX queues and del RX BA agreements */ + qmDeactivateStaRec(prAdapter, prStaRec); + } + /* 4 <2> Activate the STA_REC */ + /* Reset buffer count */ + prStaRec->ucFreeQuota = 0; + prStaRec->ucFreeQuotaForDelivery = 0; + prStaRec->ucFreeQuotaForNonDelivery = 0; + + /* Init the STA_REC */ + prStaRec->fgIsValid = TRUE; + prStaRec->fgIsInPS = FALSE; + + /* Default setting of TX/RX AMPDU */ + prStaRec->fgTxAmpduEn = IS_FEATURE_ENABLED( + prAdapter->rWifiVar.ucAmpduTx); + prStaRec->fgRxAmpduEn = IS_FEATURE_ENABLED( + prAdapter->rWifiVar.ucAmpduRx); + + nicTxGenerateDescTemplate(prAdapter, prStaRec); + + qmUpdateStaRec(prAdapter, prStaRec); + + /* Done in qmInit() or qmDeactivateStaRec() */ +#if 0 + /* At the beginning, no RX BA agreements have been established */ + for (i = 0; i < CFG_RX_MAX_BA_TID_NUM; i++) + (prStaRec->aprRxReorderParamRefTbl)[i] = NULL; +#endif + +#if CFG_MTK_MCIF_WIFI_SUPPORT + mddpNotifyDrvTxd(prAdapter, prStaRec, TRUE); +#endif + + DBGLOG(QM, INFO, "QM: +STA[%d]\n", prStaRec->ucIndex); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Deactivate a STA_REC + * + * \param[in] prAdapter Pointer to the Adapter instance + * \param[in] u4StaRecIdx The index of the STA_REC + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void qmDeactivateStaRec(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec) +{ + uint32_t i; + + if (!prStaRec) + return; + +#if CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION + /* clear fragment cache when reconnect, reassoc, disconnect */ + nicRxClearFrag(prAdapter, prStaRec); +#endif /* CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION */ + + /* 4 <1> Flush TX queues */ + if (HAL_IS_TX_DIRECT(prAdapter)) { + nicTxDirectClearStaPsQ(prAdapter, prStaRec->ucIndex); + } else { + struct MSDU_INFO *prFlushedTxPacketList = NULL; + + prFlushedTxPacketList = qmFlushStaTxQueues(prAdapter, + prStaRec->ucIndex); + + if (prFlushedTxPacketList) + wlanProcessQueuedMsduInfo(prAdapter, + prFlushedTxPacketList); + } + + /* 4 <2> Flush RX queues and delete RX BA agreements */ + for (i = 0; i < CFG_RX_MAX_BA_TID_NUM; i++) { + /* Delete the RX BA entry with TID = i */ + qmDelRxBaEntry(prAdapter, prStaRec->ucIndex, (uint8_t) i, + FALSE); + } + + /* 4 <3> Deactivate the STA_REC */ + prStaRec->fgIsValid = FALSE; + prStaRec->fgIsInPS = FALSE; + prStaRec->fgIsTxKeyReady = FALSE; + + /* Reset buffer count */ + prStaRec->ucFreeQuota = 0; + prStaRec->ucFreeQuotaForDelivery = 0; + prStaRec->ucFreeQuotaForNonDelivery = 0; + + nicTxFreeDescTemplate(prAdapter, prStaRec); + + qmUpdateStaRec(prAdapter, prStaRec); + +#if CFG_MTK_MCIF_WIFI_SUPPORT + mddpNotifyDrvTxd(prAdapter, prStaRec, FALSE); +#endif + + DBGLOG(QM, INFO, "QM: -STA[%u]\n", prStaRec->ucIndex); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Deactivate a STA_REC + * + * \param[in] prAdapter Pointer to the Adapter instance + * \param[in] ucBssIndex The index of the BSS + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void qmFreeAllByBssIdx(IN struct ADAPTER *prAdapter, IN uint8_t ucBssIndex) +{ + + struct QUE_MGT *prQM; + struct QUE *prQue; + struct QUE rNeedToFreeQue; + struct QUE rTempQue; + struct QUE *prNeedToFreeQue; + struct QUE *prTempQue; + struct MSDU_INFO *prMsduInfo; + + prQM = &prAdapter->rQM; + prQue = &prQM->arTxQueue[TX_QUEUE_INDEX_BMCAST]; + + QUEUE_INITIALIZE(&rNeedToFreeQue); + QUEUE_INITIALIZE(&rTempQue); + + prNeedToFreeQue = &rNeedToFreeQue; + prTempQue = &rTempQue; + + QUEUE_MOVE_ALL(prTempQue, prQue); + + QUEUE_REMOVE_HEAD(prTempQue, prMsduInfo, + struct MSDU_INFO *); + while (prMsduInfo) { + + if (prMsduInfo->ucBssIndex == ucBssIndex) { + /* QUEUE_INSERT_TAIL */ + QUEUE_INSERT_TAIL(prNeedToFreeQue, + (struct QUE_ENTRY *) prMsduInfo); + } else { + /* QUEUE_INSERT_TAIL */ + QUEUE_INSERT_TAIL(prQue, + (struct QUE_ENTRY *) prMsduInfo); + } + + QUEUE_REMOVE_HEAD(prTempQue, prMsduInfo, + struct MSDU_INFO *); + } + if (QUEUE_IS_NOT_EMPTY(prNeedToFreeQue)) + wlanProcessQueuedMsduInfo(prAdapter, + (struct MSDU_INFO *) + QUEUE_GET_HEAD(prNeedToFreeQue)); + +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Flush all TX queues + * + * \param[in] (none) + * + * \return The flushed packets (in a list of MSDU_INFOs) + */ +/*----------------------------------------------------------------------------*/ +struct MSDU_INFO *qmFlushTxQueues(IN struct ADAPTER *prAdapter) +{ + uint8_t ucStaArrayIdx; + uint8_t ucQueArrayIdx; + + struct QUE_MGT *prQM = &prAdapter->rQM; + + struct QUE rTempQue; + struct QUE *prTempQue = &rTempQue; + struct QUE *prQue; + + DBGLOG(QM, TRACE, "QM: Enter qmFlushTxQueues()\n"); + + QUEUE_INITIALIZE(prTempQue); + + /* Concatenate all MSDU_INFOs in per-STA queues */ + for (ucStaArrayIdx = 0; ucStaArrayIdx < CFG_STA_REC_NUM; + ucStaArrayIdx++) { + for (ucQueArrayIdx = 0; + ucQueArrayIdx < NUM_OF_PER_STA_TX_QUEUES; + ucQueArrayIdx++) { + prQue = &(prAdapter->arStaRec[ucStaArrayIdx]. + arPendingTxQueue[ucQueArrayIdx]); + QUEUE_CONCATENATE_QUEUES(prTempQue, prQue); + prQue = &(prAdapter->arStaRec[ucStaArrayIdx]. + arTxQueue[ucQueArrayIdx]); + QUEUE_CONCATENATE_QUEUES(prTempQue, prQue); + } + } + + /* Flush per-Type queues */ + for (ucQueArrayIdx = 0; + ucQueArrayIdx < NUM_OF_PER_TYPE_TX_QUEUES; + ucQueArrayIdx++) { + prQue = &(prQM->arTxQueue[ucQueArrayIdx]); + QUEUE_CONCATENATE_QUEUES(prTempQue, prQue); + } + + return (struct MSDU_INFO *)QUEUE_GET_HEAD(prTempQue); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Flush TX packets for a particular STA + * + * \param[in] u4StaRecIdx STA_REC index + * + * \return The flushed packets (in a list of MSDU_INFOs) + */ +/*----------------------------------------------------------------------------*/ +struct MSDU_INFO *qmFlushStaTxQueues(IN struct ADAPTER *prAdapter, + IN uint32_t u4StaRecIdx) +{ + uint8_t ucQueArrayIdx; + struct STA_RECORD *prStaRec; + struct QUE *prQue; + struct QUE rTempQue; + struct QUE *prTempQue = &rTempQue; + + DBGLOG(QM, TRACE, "QM: Enter qmFlushStaTxQueues(%u)\n", u4StaRecIdx); + + ASSERT(u4StaRecIdx < CFG_STA_REC_NUM); + + prStaRec = &prAdapter->arStaRec[u4StaRecIdx]; + ASSERT(prStaRec); + + QUEUE_INITIALIZE(prTempQue); + + /* Concatenate all MSDU_INFOs in TX queues of this STA_REC */ + for (ucQueArrayIdx = 0; + ucQueArrayIdx < NUM_OF_PER_STA_TX_QUEUES; ucQueArrayIdx++) { + prQue = &(prStaRec->arPendingTxQueue[ucQueArrayIdx]); + QUEUE_CONCATENATE_QUEUES(prTempQue, prQue); + prQue = &(prStaRec->arTxQueue[ucQueArrayIdx]); + QUEUE_CONCATENATE_QUEUES(prTempQue, prQue); + } + + return (struct MSDU_INFO *)QUEUE_GET_HEAD(prTempQue); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Flush RX packets + * + * \param[in] (none) + * + * \return The flushed packets (in a list of SW_RFBs) + */ +/*----------------------------------------------------------------------------*/ +struct SW_RFB *qmFlushRxQueues(IN struct ADAPTER *prAdapter) +{ + uint32_t i; + struct SW_RFB *prSwRfbListHead; + struct SW_RFB *prSwRfbListTail; + struct QUE_MGT *prQM = &prAdapter->rQM; + + prSwRfbListHead = prSwRfbListTail = NULL; + + DBGLOG(QM, TRACE, "QM: Enter qmFlushRxQueues()\n"); + + RX_DIRECT_REORDER_LOCK(prAdapter, 0); + for (i = 0; i < CFG_NUM_OF_RX_BA_AGREEMENTS; i++) { + if (QUEUE_IS_NOT_EMPTY(& + (prQM->arRxBaTable[i].rReOrderQue))) { + if (!prSwRfbListHead) { + + /* The first MSDU_INFO is found */ + prSwRfbListHead = (struct SW_RFB *) + QUEUE_GET_HEAD( + &(prQM->arRxBaTable[i]. + rReOrderQue)); + prSwRfbListTail = (struct SW_RFB *) + QUEUE_GET_TAIL( + &(prQM->arRxBaTable[i]. + rReOrderQue)); + } else { + /* Concatenate the MSDU_INFO list with + * the existing list + */ + QM_TX_SET_NEXT_MSDU_INFO(prSwRfbListTail, + QUEUE_GET_HEAD( + &(prQM->arRxBaTable[i]. + rReOrderQue))); + + prSwRfbListTail = (struct SW_RFB *) + QUEUE_GET_TAIL( + &(prQM->arRxBaTable[i]. + rReOrderQue)); + } + + QUEUE_INITIALIZE(&(prQM->arRxBaTable[i].rReOrderQue)); + if (QM_RX_GET_NEXT_SW_RFB(prSwRfbListTail)) { + DBGLOG(QM, ERROR, + "QM: non-null tail->next at arRxBaTable[%u]\n", + i); + } + } else { + continue; + } + } + RX_DIRECT_REORDER_UNLOCK(prAdapter, 0); + + if (prSwRfbListTail) { + /* Terminate the MSDU_INFO list with a NULL pointer */ + QM_TX_SET_NEXT_SW_RFB(prSwRfbListTail, NULL); + } + return prSwRfbListHead; + +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Flush RX packets with respect to a particular STA + * + * \param[in] u4StaRecIdx STA_REC index + * \param[in] u4Tid TID + * + * \return The flushed packets (in a list of SW_RFBs) + */ +/*----------------------------------------------------------------------------*/ +struct SW_RFB *qmFlushStaRxQueue(IN struct ADAPTER *prAdapter, + IN uint32_t u4StaRecIdx, IN uint32_t u4Tid) +{ + /* UINT_32 i; */ + struct SW_RFB *prSwRfbListHead; + struct SW_RFB *prSwRfbListTail; + struct RX_BA_ENTRY *prReorderQueParm; + struct STA_RECORD *prStaRec; + + DBGLOG(QM, TRACE, "QM: Enter qmFlushStaRxQueues(%u)\n", u4StaRecIdx); + + prSwRfbListHead = prSwRfbListTail = NULL; + + prStaRec = &prAdapter->arStaRec[u4StaRecIdx]; + ASSERT(prStaRec); + + /* No matter whether this is an activated STA_REC, do flush */ +#if 0 + if (!prStaRec->fgIsValid) + return NULL; +#endif + + /* Obtain the RX BA Entry pointer */ + prReorderQueParm = ((prStaRec->aprRxReorderParamRefTbl)[u4Tid]); + + /* Note: For each queued packet, + * prCurrSwRfb->eDst equals RX_PKT_DESTINATION_HOST + */ + if (prReorderQueParm) { + RX_DIRECT_REORDER_LOCK(prAdapter, 0); + if (QUEUE_IS_NOT_EMPTY(&(prReorderQueParm->rReOrderQue))) { + + prSwRfbListHead = (struct SW_RFB *) + QUEUE_GET_HEAD( + &(prReorderQueParm->rReOrderQue)); + prSwRfbListTail = (struct SW_RFB *) + QUEUE_GET_TAIL( + &(prReorderQueParm->rReOrderQue)); + + QUEUE_INITIALIZE(&(prReorderQueParm->rReOrderQue)); + } + RX_DIRECT_REORDER_UNLOCK(prAdapter, 0); + } + + if (prSwRfbListTail) { + if (QM_RX_GET_NEXT_SW_RFB(prSwRfbListTail)) { + DBGLOG(QM, ERROR, + "QM: non-empty tail->next at STA %u TID %u\n", + u4StaRecIdx, u4Tid); + } + + /* Terminate the MSDU_INFO list with a NULL pointer */ + QM_TX_SET_NEXT_SW_RFB(prSwRfbListTail, NULL); + } + return prSwRfbListHead; +} + +struct QUE *qmDetermineStaTxQueue(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN uint8_t ucActiveTs, OUT uint8_t *pucTC) +{ + struct QUE *prTxQue = NULL; + struct STA_RECORD *prStaRec; + enum ENUM_WMM_ACI eAci = WMM_AC_BE_INDEX; + u_int8_t fgCheckACMAgain; + uint8_t ucTC, ucQueIdx = WMM_AC_BE_INDEX; + struct BSS_INFO *prBssInfo; + /* BEtoBK, na, VItoBE, VOtoVI */ + uint8_t aucNextUP[WMM_AC_INDEX_NUM] = {1, 1, 0, 4}; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prMsduInfo->ucBssIndex); + prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, + prMsduInfo->ucStaRecIndex); + if (prStaRec == NULL) + return prTxQue; + + if (!prStaRec) { + DBGLOG(QM, ERROR, "prStaRec is null.\n"); + return NULL; + } + if (prMsduInfo->ucUserPriority < 8) { + QM_DBG_CNT_INC(&prAdapter->rQM, + prMsduInfo->ucUserPriority + 15); + } + + eAci = WMM_AC_BE_INDEX; + do { + fgCheckACMAgain = FALSE; + if (prStaRec->fgIsQoS) { + if (prMsduInfo->ucUserPriority < TX_DESC_TID_NUM) { + eAci = aucTid2ACI[prMsduInfo->ucUserPriority]; + ucQueIdx = aucACI2TxQIdx[eAci]; + ucTC = + arNetwork2TcResource[ + prMsduInfo->ucBssIndex][eAci]; + } else { + ucQueIdx = TX_QUEUE_INDEX_AC1; + ucTC = TC1_INDEX; + eAci = WMM_AC_BE_INDEX; + DBGLOG(QM, WARN, + "Packet TID is not in [0~7]\n"); + ASSERT(0); + } + if ((prBssInfo->arACQueParms[eAci].ucIsACMSet) && + !(ucActiveTs & BIT(eAci)) && + (eAci != WMM_AC_BK_INDEX)) { + DBGLOG(WMM, TRACE, + "ucUserPriority: %d, aucNextUP[eAci]: %d", + prMsduInfo->ucUserPriority, + aucNextUP[eAci]); + prMsduInfo->ucUserPriority = aucNextUP[eAci]; + fgCheckACMAgain = TRUE; + } + } else { + ucQueIdx = TX_QUEUE_INDEX_NON_QOS; + ucTC = arNetwork2TcResource[prMsduInfo->ucBssIndex][ + NET_TC_WMM_AC_BE_INDEX]; + } + + if (prAdapter->rWifiVar.ucTcRestrict < TC_NUM) { + ucTC = prAdapter->rWifiVar.ucTcRestrict; + ucQueIdx = ucTC; + } + + } while (fgCheckACMAgain); + + if (ucQueIdx >= NUM_OF_PER_STA_TX_QUEUES) { + DBGLOG(QM, ERROR, + "ucQueIdx = %u, needs 0~3 to avoid out-of-bounds.\n", + ucQueIdx); + return NULL; + } + if (prStaRec->fgIsTxAllowed) { + /* non protected BSS or protected BSS with key set */ + prTxQue = prStaRec->aprTargetQueue[ucQueIdx]; + } else if (secIsProtectedBss(prAdapter, prBssInfo) && + prMsduInfo->fgIs802_1x && + prMsduInfo->fgIs802_1x_NonProtected) { + /* protected BSS without key set */ + /* Tx pairwise EAPOL 1x packet (non-protected frame) */ + prTxQue = &prStaRec->arTxQueue[ucQueIdx]; + } else { + /* protected BSS without key set */ + /* Enqueue protected frame into pending queue */ + prTxQue = prStaRec->aprTargetQueue[ucQueIdx]; + } + + *pucTC = ucTC; + /* + * Record how many packages enqueue this STA + * to TX during statistic intervals + */ + prStaRec->u4EnqueueCounter++; + + return prTxQue; +} + +void qmSetTxPacketDescTemplate(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo) +{ + struct STA_RECORD *prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX( + prAdapter, prMsduInfo->ucStaRecIndex); + + /* Check the Tx descriptor template is valid */ + if (prStaRec && + prStaRec->aprTxDescTemplate[prMsduInfo->ucUserPriority]) { + prMsduInfo->fgIsTXDTemplateValid = TRUE; + } else { + if (prStaRec) { + DBGLOG(QM, TRACE, + "Cannot get TXD template for STA[%u] QoS[%u] MSDU UP[%u]\n", + prStaRec->ucIndex, prStaRec->fgIsQoS, + prMsduInfo->ucUserPriority); + } + prMsduInfo->fgIsTXDTemplateValid = FALSE; + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief : To StaRec, function to stop TX + * + * \param[in] : + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void qmSetStaRecTxAllowed(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, IN u_int8_t fgIsTxAllowed) +{ + uint8_t ucIdx; + struct QUE *prSrcQ, *prDstQ; + + DBGLOG(QM, INFO, "Set Sta[%u] TxAllowed from [%u] to [%u] %s TxQ\n", + prStaRec->ucIndex, + prStaRec->fgIsTxAllowed, + fgIsTxAllowed, + fgIsTxAllowed ? "normal" : "pending"); + + /* Update Tx queue when allowed state change*/ + if (prStaRec->fgIsTxAllowed != fgIsTxAllowed) { + for (ucIdx = 0; ucIdx < NUM_OF_PER_STA_TX_QUEUES; ucIdx++) { + if (fgIsTxAllowed) { + prSrcQ = &prStaRec->arPendingTxQueue[ucIdx]; + prDstQ = &prStaRec->arTxQueue[ucIdx]; + } else { + prSrcQ = &prStaRec->arTxQueue[ucIdx]; + prDstQ = &prStaRec->arPendingTxQueue[ucIdx]; + } + + QUEUE_CONCATENATE_QUEUES_HEAD(prDstQ, prSrcQ); + prStaRec->aprTargetQueue[ucIdx] = prDstQ; + } + + if (fgIsTxAllowed) + prAdapter->rQM.u4TxAllowedStaCount++; + else + prAdapter->rQM.u4TxAllowedStaCount--; + } + prStaRec->fgIsTxAllowed = fgIsTxAllowed; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Enqueue TX packets + * + * \param[in] prMsduInfoListHead Pointer to the list of TX packets + * + * \return The freed packets, which are not enqueued + */ +/*----------------------------------------------------------------------------*/ +struct MSDU_INFO *qmEnqueueTxPackets(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfoListHead) +{ + struct MSDU_INFO *prMsduInfoReleaseList; + struct MSDU_INFO *prCurrentMsduInfo; + struct MSDU_INFO *prNextMsduInfo; + + struct QUE *prTxQue; + struct QUE rNotEnqueuedQue; + struct STA_RECORD *prStaRec; + uint8_t ucTC; + struct TX_CTRL *prTxCtrl = &prAdapter->rTxCtrl; + struct QUE_MGT *prQM = &prAdapter->rQM; + struct BSS_INFO *prBssInfo; + u_int8_t fgDropPacket; + uint8_t ucActivedTspec = 0; + + DBGLOG(QM, LOUD, "Enter qmEnqueueTxPackets\n"); + + ASSERT(prMsduInfoListHead); + + prMsduInfoReleaseList = NULL; + prCurrentMsduInfo = NULL; + QUEUE_INITIALIZE(&rNotEnqueuedQue); + prNextMsduInfo = prMsduInfoListHead; + + do { + prCurrentMsduInfo = prNextMsduInfo; + prNextMsduInfo = QM_TX_GET_NEXT_MSDU_INFO( + prCurrentMsduInfo); + ucTC = TC1_INDEX; + + /* 4 <0> Sanity check of BSS_INFO */ + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prCurrentMsduInfo->ucBssIndex); + + if (!prBssInfo) { + /* No BSS_INFO */ + fgDropPacket = TRUE; + } else if (IS_BSS_ACTIVE(prBssInfo)) { + /* BSS active */ + fgDropPacket = FALSE; + } else { + /* BSS inactive */ + fgDropPacket = TRUE; + } + + if (!fgDropPacket) { + /* 4 <1> Lookup the STA_REC index */ + /* The ucStaRecIndex will be set in this function */ + qmDetermineStaRecIndex(prAdapter, prCurrentMsduInfo); + + /*get per-AC Tx packets */ + wlanUpdateTxStatistics(prAdapter, prCurrentMsduInfo, + FALSE); + + DBGLOG(QM, LOUD, "Enqueue MSDU by StaRec[%u]!\n", + prCurrentMsduInfo->ucStaRecIndex); + + switch (prCurrentMsduInfo->ucStaRecIndex) { + case STA_REC_INDEX_BMCAST: + prTxQue = + &prQM->arTxQueue[TX_QUEUE_INDEX_BMCAST]; + ucTC = + arNetwork2TcResource[prCurrentMsduInfo-> + ucBssIndex][NET_TC_BMC_INDEX]; + + /* Always set BMC packet retry limit + * to unlimited + */ + if (!(prCurrentMsduInfo->u4Option & + MSDU_OPT_MANUAL_RETRY_LIMIT)) + nicTxSetPktRetryLimit(prCurrentMsduInfo, + TX_DESC_TX_COUNT_NO_LIMIT); + + QM_DBG_CNT_INC(prQM, QM_DBG_CNT_23); + break; + + case STA_REC_INDEX_NOT_FOUND: + /* Drop packet if no STA_REC is found */ + DBGLOG(QM, TRACE, + "Drop the Packet for no STA_REC\n"); + + prTxQue = &rNotEnqueuedQue; + + TX_INC_CNT(&prAdapter->rTxCtrl, + TX_INACTIVE_STA_DROP); + QM_DBG_CNT_INC(prQM, QM_DBG_CNT_24); + break; + + default: + ucActivedTspec = wmmHasActiveTspec( + aisGetWMMInfo(prAdapter, + prCurrentMsduInfo->ucBssIndex)); + + prTxQue = qmDetermineStaTxQueue( + prAdapter, prCurrentMsduInfo, + ucActivedTspec, &ucTC); + if (!prTxQue) { + DBGLOG(QM, INFO, + "Drop the Packet for TxQue is NULL\n"); + prTxQue = &rNotEnqueuedQue; + TX_INC_CNT(&prAdapter->rTxCtrl, + TX_INACTIVE_STA_DROP); + QM_DBG_CNT_INC(prQM, QM_DBG_CNT_24); + } +#if ARP_MONITER_ENABLE + prStaRec = + QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, + prCurrentMsduInfo-> + ucStaRecIndex); + if (prStaRec && IS_STA_IN_AIS(prStaRec) && + prCurrentMsduInfo->eSrc == TX_PACKET_OS) + qmDetectArpNoResponse(prAdapter, + prCurrentMsduInfo); +#endif + break; /*default */ + } /* switch (prCurrentMsduInfo->ucStaRecIndex) */ + + if (prCurrentMsduInfo->eSrc == TX_PACKET_FORWARDING) { + DBGLOG(QM, TRACE, + "Forward Pkt to STA[%u] BSS[%u]\n", + prCurrentMsduInfo->ucStaRecIndex, + prCurrentMsduInfo->ucBssIndex); + + if (prTxQue->u4NumElem >= + prQM->u4MaxForwardBufferCount) { + DBGLOG(QM, INFO, + "Drop the Packet for full Tx queue (forwarding) Bss %u\n", + prCurrentMsduInfo->ucBssIndex); + prTxQue = &rNotEnqueuedQue; + TX_INC_CNT(&prAdapter->rTxCtrl, + TX_FORWARD_OVERFLOW_DROP); + } + } + + } else { + DBGLOG(QM, TRACE, + "Drop the Packet for inactive Bss %u\n", + prCurrentMsduInfo->ucBssIndex); + QM_DBG_CNT_INC(prQM, QM_DBG_CNT_31); + prTxQue = &rNotEnqueuedQue; + TX_INC_CNT(&prAdapter->rTxCtrl, TX_INACTIVE_BSS_DROP); + } + + /* 4 <3> Fill the MSDU_INFO for constructing HIF TX header */ + /* Note that the BSS Index and STA_REC index are determined in + * qmDetermineStaRecIndex(prCurrentMsduInfo). + */ + prCurrentMsduInfo->ucTC = ucTC; + + /* Check the Tx descriptor template is valid */ + qmSetTxPacketDescTemplate(prAdapter, prCurrentMsduInfo); + + /* Set Tx rate */ + switch (prAdapter->rWifiVar.ucDataTxRateMode) { + case DATA_RATE_MODE_BSS_LOWEST: + nicTxSetPktLowestFixedRate(prAdapter, + prCurrentMsduInfo); + break; + + case DATA_RATE_MODE_MANUAL: + prCurrentMsduInfo->u4FixedRateOption = + prAdapter->rWifiVar.u4DataTxRateCode; + + prCurrentMsduInfo->ucRateMode = + MSDU_RATE_MODE_MANUAL_DESC; + break; + + case DATA_RATE_MODE_AUTO: + default: + if (prCurrentMsduInfo->ucRateMode == + MSDU_RATE_MODE_LOWEST_RATE) + nicTxSetPktLowestFixedRate(prAdapter, + prCurrentMsduInfo); + break; + } + + /* 4 <4> Enqueue the packet */ + QUEUE_INSERT_TAIL(prTxQue, + (struct QUE_ENTRY *) prCurrentMsduInfo); + wlanFillTimestamp(prAdapter, prCurrentMsduInfo->prPacket, + PHASE_ENQ_QM); + /* + * Record how many packages enqueue + * to TX during statistic intervals + */ + if (prTxQue != &rNotEnqueuedQue) { + prQM->u4EnqueueCounter++; + /* how many page count this frame wanted */ + prQM->au4QmTcWantedPageCounter[ucTC] += + prCurrentMsduInfo->u4PageCount; + } +#if QM_TC_RESOURCE_EMPTY_COUNTER + if (prCurrentMsduInfo->u4PageCount > + prTxCtrl->rTc.au4FreePageCount[ucTC]) + prQM->au4QmTcResourceEmptyCounter[ + prCurrentMsduInfo->ucBssIndex][ucTC]++; +#endif + +#if QM_FAST_TC_RESOURCE_CTRL && QM_ADAPTIVE_TC_RESOURCE_CTRL + if (prTxQue != &rNotEnqueuedQue) { + /* Check and trigger fast TC resource + * adjustment for queued packets + */ + qmCheckForFastTcResourceCtrl(prAdapter, ucTC); + } +#endif + +#if QM_TEST_MODE + if (++prQM->u4PktCount == QM_TEST_TRIGGER_TX_COUNT) { + prQM->u4PktCount = 0; + qmTestCases(prAdapter); + } +#endif + } while (prNextMsduInfo); + + if (QUEUE_IS_NOT_EMPTY(&rNotEnqueuedQue)) { + QM_TX_SET_NEXT_MSDU_INFO((struct MSDU_INFO *) + QUEUE_GET_TAIL(&rNotEnqueuedQue), NULL); + prMsduInfoReleaseList = (struct MSDU_INFO *) QUEUE_GET_HEAD( + &rNotEnqueuedQue); + } +#if QM_ADAPTIVE_TC_RESOURCE_CTRL + /* 4 Update TC resource control related variables */ + /* Keep track of the queue length */ + qmDoAdaptiveTcResourceCtrl(prAdapter); +#endif + + return prMsduInfoReleaseList; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Determine the STA_REC index for a packet + * + * \param[in] prMsduInfo Pointer to the packet + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void qmDetermineStaRecIndex(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo) +{ + uint32_t i; + + struct STA_RECORD *prTempStaRec; + struct BSS_INFO *prBssInfo; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prMsduInfo->ucBssIndex); + prTempStaRec = NULL; + + ASSERT(prMsduInfo); + + DBGLOG(QM, LOUD, + "Msdu BSS Idx[%u] OpMode[%u] StaRecOfApExist[%u]\n", + prMsduInfo->ucBssIndex, prBssInfo->eCurrentOPMode, + prBssInfo->prStaRecOfAP ? TRUE : FALSE); + + switch (prBssInfo->eCurrentOPMode) { + case OP_MODE_IBSS: + case OP_MODE_ACCESS_POINT: + /* 4 <1> DA = BMCAST */ + if (IS_BMCAST_MAC_ADDR(prMsduInfo->aucEthDestAddr)) { + prMsduInfo->ucStaRecIndex = STA_REC_INDEX_BMCAST; + DBGLOG(QM, LOUD, "TX with DA = BMCAST\n"); + return; + } + break; + + /* Infra Client/GC */ + case OP_MODE_INFRASTRUCTURE: + case OP_MODE_BOW: + if (prBssInfo->prStaRecOfAP) { +#if CFG_SUPPORT_TDLS + + prTempStaRec = + cnmGetTdlsPeerByAddress(prAdapter, + prBssInfo->ucBssIndex, + prMsduInfo->aucEthDestAddr); + if (IS_DLS_STA(prTempStaRec) + && prTempStaRec->ucStaState == STA_STATE_3) { + if (g_arTdlsLink[prTempStaRec->ucTdlsIndex]) { + prMsduInfo->ucStaRecIndex = + prTempStaRec->ucIndex; + return; + } + } +#endif + /* 4 <2> Check if an AP STA is present */ + prTempStaRec = prBssInfo->prStaRecOfAP; + + DBGLOG(QM, LOUD, + "StaOfAp Idx[%u] WIDX[%u] Valid[%u] TxAllowed[%u] InUse[%u] Type[%u]\n", + prTempStaRec->ucIndex, + prTempStaRec->ucWlanIndex, + prTempStaRec->fgIsValid, + prTempStaRec->fgIsTxAllowed, + prTempStaRec->fgIsInUse, + prTempStaRec->eStaType); + + if (prTempStaRec->fgIsInUse) { + prMsduInfo->ucStaRecIndex = + prTempStaRec->ucIndex; + DBGLOG(QM, LOUD, "TX with AP_STA[%u]\n", + prTempStaRec->ucIndex); + return; + } + } + break; + + case OP_MODE_P2P_DEVICE: + break; + + default: + break; + } + + /* 4 <3> Not BMCAST, No AP --> Compare DA + * (i.e., to see whether this is a unicast frame to a client) + */ + for (i = 0; i < CFG_STA_REC_NUM; i++) { + prTempStaRec = &(prAdapter->arStaRec[i]); + if (prTempStaRec->fgIsInUse) { + if (EQUAL_MAC_ADDR(prTempStaRec->aucMacAddr, + prMsduInfo->aucEthDestAddr)) { + prMsduInfo->ucStaRecIndex = + prTempStaRec->ucIndex; + DBGLOG(QM, LOUD, "TX with STA[%u]\n", + prTempStaRec->ucIndex); + return; + } + } + } + + /* 4 <4> No STA found, Not BMCAST --> Indicate NOT_FOUND to FW */ + prMsduInfo->ucStaRecIndex = STA_REC_INDEX_NOT_FOUND; + DBGLOG(QM, LOUD, "QM: TX with STA_REC_INDEX_NOT_FOUND\n"); + +#if (QM_TEST_MODE && QM_TEST_FAIR_FORWARDING) + prMsduInfo->ucStaRecIndex = + (uint8_t) prQM->u4CurrentStaRecIndexToEnqueue; +#endif +} + +struct STA_RECORD *qmDetermineStaToBeDequeued( + IN struct ADAPTER *prAdapter, + IN uint32_t u4StartStaRecIndex) +{ + + return NULL; +} + +struct QUE *qmDequeueStaTxPackets(IN struct ADAPTER *prAdapter) +{ + + return NULL; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Dequeue TX packets from a STA_REC for a particular TC + * + * \param[out] prQue The queue to put the dequeued packets + * \param[in] ucTC The TC index (TC0_INDEX to TC5_INDEX) + * \param[in] ucMaxNum The maximum amount of dequeued packets + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +uint32_t +qmDequeueTxPacketsFromPerStaQueues(IN struct ADAPTER *prAdapter, + OUT struct QUE *prQue, IN uint8_t ucTC, + IN uint32_t u4CurrentQuota, + IN uint32_t *prPleCurrentQuota, + IN uint32_t u4TotalQuota) +{ + uint32_t ucLoop; /* Loop for */ + + uint32_t u4CurStaIndex = 0; + uint32_t u4CurStaUsedResource = 0; + + /* The current focused STA */ + struct STA_RECORD *prStaRec; + /* The Bss for current focused STA */ + struct BSS_INFO *prBssInfo; + /* The current TX queue to dequeue */ + struct QUE *prCurrQueue; + /* The dequeued packet */ + struct MSDU_INFO *prDequeuedPkt; + + /* To remember the total forwarded packets for a STA */ + uint32_t u4CurStaForwardFrameCount; + /* The maximum number of packets a STA can forward */ + uint32_t u4MaxForwardFrameCountLimit; + uint32_t u4AvaliableResource; /* The TX resource amount */ + uint32_t u4MaxResourceLimit; + + u_int8_t fgEndThisRound; + struct QUE_MGT *prQM = &prAdapter->rQM; + + uint8_t *pucPsStaFreeQuota; +#if CFG_SUPPORT_SOFT_ACM + uint8_t ucAc; + u_int8_t fgAcmFlowCtrl = FALSE; + static const uint8_t aucTc2Ac[] = {ACI_BK, ACI_BE, ACI_VI, ACI_VO}; +#endif + + /* Sanity Check */ + if (!u4CurrentQuota) { + DBGLOG(TX, LOUD, + "(Fairness) Skip TC = %u u4CurrentQuota = %u\n", ucTC, + u4CurrentQuota); + prQM->au4DequeueNoTcResourceCounter[ucTC]++; + return u4CurrentQuota; + } + /* Check PLE resource */ + if (!(*prPleCurrentQuota)) + return u4CurrentQuota; + /* 4 <1> Assign init value */ + u4AvaliableResource = u4CurrentQuota; + u4MaxResourceLimit = u4TotalQuota; + +#if QM_FORWARDING_FAIRNESS + u4CurStaIndex = prQM->au4HeadStaRecIndex[ucTC]; + u4CurStaUsedResource = prQM->au4ResourceUsedCount[ucTC]; +#endif + + fgEndThisRound = FALSE; + ucLoop = 0; + u4CurStaForwardFrameCount = 0; + + DBGLOG(QM, TEMP, + "(Fairness) TC[%u] Init Head STA[%u] Resource[%u]\n", + ucTC, u4CurStaIndex, u4AvaliableResource); + + /* 4 <2> Traverse STA array from Head STA */ + /* From STA[x] to STA[x+1] to STA[x+2] to ... to STA[x] */ + while (ucLoop < CFG_STA_REC_NUM) { + prStaRec = &prAdapter->arStaRec[u4CurStaIndex]; + prCurrQueue = &prStaRec->arTxQueue[ucTC]; + + /* 4 <2.1> Find a Tx allowed STA */ + /* Only Data frame will be queued in */ + /* if (prStaRec->fgIsTxAllowed) { */ + if (QUEUE_IS_NOT_EMPTY(prCurrQueue)) { + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prStaRec->ucBssIndex); + + /* prCurrQueue = &prStaRec->aprTxQueue[ucTC]; */ + prDequeuedPkt = NULL; + pucPsStaFreeQuota = NULL; + /* Set default forward count limit to unlimited */ + u4MaxForwardFrameCountLimit = + QM_STA_FORWARD_COUNT_UNLIMITED; + + /* 4 <2.2> Update forward frame/page count + * limit for this STA + */ + /* AP mode: STA in PS buffer handling */ + if (prStaRec->fgIsInPS) { + if (prStaRec->fgIsQoS && + prStaRec->fgIsUapsdSupported && + (prStaRec->ucBmpTriggerAC & + BIT(ucTC))) { + u4MaxForwardFrameCountLimit = + prStaRec-> + ucFreeQuotaForDelivery; + pucPsStaFreeQuota = + &prStaRec-> + ucFreeQuotaForDelivery; + } else { + u4MaxForwardFrameCountLimit = + prStaRec-> + ucFreeQuotaForNonDelivery; + pucPsStaFreeQuota = + &prStaRec-> + ucFreeQuotaForNonDelivery; + } + } + + /* fgIsInPS */ + /* Absent BSS handling */ + if (prBssInfo->fgIsNetAbsent) { + if (u4MaxForwardFrameCountLimit > + prBssInfo->ucBssFreeQuota) + u4MaxForwardFrameCountLimit = + prBssInfo->ucBssFreeQuota; + } +#if CFG_SUPPORT_DBDC + if (prAdapter->rWifiVar.fgDbDcModeEn) + u4MaxResourceLimit = + gmGetDequeueQuota(prAdapter, + prStaRec, prBssInfo, + u4TotalQuota); +#endif +#if CFG_SUPPORT_SOFT_ACM + if (ucTC <= TC3_INDEX && + prStaRec->afgAcmRequired[aucTc2Ac[ucTC]]) { + ucAc = aucTc2Ac[ucTC]; + DBGLOG(QM, TRACE, "AC %d Pending Pkts %u\n", + ucAc, prCurrQueue->u4NumElem); + /* Quick check remain medium time and pending + ** packets + */ + if (QUEUE_IS_EMPTY(prCurrQueue) || + !wmmAcmCanDequeue(prAdapter, ucAc, 0, + prBssInfo->ucBssIndex)) + goto skip_dequeue; + fgAcmFlowCtrl = TRUE; + } else + fgAcmFlowCtrl = FALSE; +#endif + /* 4 <2.3> Dequeue packet */ + /* Three cases to break: (1) No resource + * (2) No packets (3) Fairness + */ + while (!QUEUE_IS_EMPTY(prCurrQueue)) { + prDequeuedPkt = (struct MSDU_INFO *) + QUEUE_GET_HEAD(prCurrQueue); + + if ((u4CurStaForwardFrameCount >= + u4MaxForwardFrameCountLimit) || + (u4CurStaUsedResource >= + u4MaxResourceLimit)) { + /* Exceeds Limit */ + prQM-> + au4DequeueNoTcResourceCounter[ucTC]++; + break; + } else if (prDequeuedPkt->u4PageCount > + u4AvaliableResource) { + /* Available Resource is not enough */ + prQM-> + au4DequeueNoTcResourceCounter[ucTC]++; + if (!(prAdapter->rWifiVar. + ucAlwaysResetUsedRes & BIT(0))) + fgEndThisRound = TRUE; + break; + } else if ((*prPleCurrentQuota) < + NIX_TX_PLE_PAGE_CNT_PER_FRAME) { + if (!(prAdapter->rWifiVar. + ucAlwaysResetUsedRes & BIT(0))) + fgEndThisRound = TRUE; + break; + } else if (!prStaRec->fgIsValid) { + /* In roaming, if the sta_rec doesn't + * active by event 0x0C, it can't + * dequeue data. + */ + DBGLOG_LIMITED(QM, WARN, + "sta_rec is not valid\n"); + break; + } +#if CFG_SUPPORT_SOFT_ACM + if (fgAcmFlowCtrl) { + uint32_t u4PktTxTime = 0; + + u4PktTxTime = wmmCalculatePktUsedTime( + prBssInfo, prStaRec, + prDequeuedPkt->u2FrameLength - + ETH_HLEN); + if (!wmmAcmCanDequeue(prAdapter, ucAc, + u4PktTxTime, + prBssInfo->ucBssIndex)) + break; + } +#endif + /* Available to be Tx */ + + QUEUE_REMOVE_HEAD(prCurrQueue, prDequeuedPkt, + struct MSDU_INFO *); + + if (!QUEUE_IS_EMPTY(prCurrQueue)) { + /* XXX: check all queues for STA */ + prDequeuedPkt->ucPsForwardingType = + PS_FORWARDING_MORE_DATA_ENABLED; + } + /* to record WMM Set */ + prDequeuedPkt->ucWmmQueSet = + prBssInfo->ucWmmQueSet; + QUEUE_INSERT_TAIL(prQue, + (struct QUE_ENTRY *) + prDequeuedPkt); + prStaRec->u4DeqeueuCounter++; + prQM->u4DequeueCounter++; + + u4AvaliableResource -= + prDequeuedPkt->u4PageCount; + u4CurStaUsedResource += + prDequeuedPkt->u4PageCount; + u4CurStaForwardFrameCount++; + (*prPleCurrentQuota) -= + NIX_TX_PLE_PAGE_CNT_PER_FRAME; + } +#if CFG_SUPPORT_SOFT_ACM +skip_dequeue: +#endif + /* AP mode: Update STA in PS Free quota */ + if (prStaRec->fgIsInPS && pucPsStaFreeQuota) { + if ((*pucPsStaFreeQuota) >= + u4CurStaForwardFrameCount) + (*pucPsStaFreeQuota) -= + u4CurStaForwardFrameCount; + else + (*pucPsStaFreeQuota) = 0; + } + + if (prBssInfo->fgIsNetAbsent) { + if (prBssInfo->ucBssFreeQuota >= + u4CurStaForwardFrameCount) + prBssInfo->ucBssFreeQuota -= + u4CurStaForwardFrameCount; + else + prBssInfo->ucBssFreeQuota = 0; + } + } + + if (fgEndThisRound) { + /* End this round */ + break; + } + + /* Prepare for next STA */ + ucLoop++; + u4CurStaIndex++; + u4CurStaIndex %= CFG_STA_REC_NUM; + u4CurStaUsedResource = 0; + u4CurStaForwardFrameCount = 0; + } + + /* 4 <3> Store Head Sta information to QM */ + /* No need to count used resource if thers is only one STA */ + if ((prQM->u4TxAllowedStaCount == 1) || + (prAdapter->rWifiVar.ucAlwaysResetUsedRes & BIT(1))) + u4CurStaUsedResource = 0; + +#if QM_FORWARDING_FAIRNESS + prQM->au4HeadStaRecIndex[ucTC] = u4CurStaIndex; + prQM->au4ResourceUsedCount[ucTC] = u4CurStaUsedResource; +#endif + + DBGLOG(QM, TEMP, + "(Fairness) TC[%u] Scheduled Head STA[%u] Left Resource[%u]\n", + ucTC, u4CurStaIndex, u4AvaliableResource); + + return u4AvaliableResource; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Dequeue TX packets from a per-Type-based Queue for a particular TC + * + * \param[out] prQue The queue to put the dequeued packets + * \param[in] ucTC The TC index(Shall always be BMC_TC_INDEX) + * \param[in] ucMaxNum The maximum amount of available resource + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void +qmDequeueTxPacketsFromPerTypeQueues(IN struct ADAPTER *prAdapter, + OUT struct QUE *prQue, IN uint8_t ucTC, + IN uint32_t u4CurrentQuota, + IN uint32_t *prPleCurrentQuota, + IN uint32_t u4TotalQuota) +{ + uint32_t u4AvaliableResource, u4LeftResource; + uint32_t u4MaxResourceLimit; + uint32_t u4TotalUsedResource = 0; + struct QUE_MGT *prQM; + PFN_DEQUEUE_FUNCTION pfnDeQFunc[2]; + u_int8_t fgChangeDeQFunc = TRUE; + u_int8_t fgGlobalQueFirst = TRUE; + + DBGLOG(QM, TEMP, "Enter %s (TC = %d, quota = %u)\n", + __func__, ucTC, u4CurrentQuota); + + /* Broadcast/Multicast data packets */ + if (u4CurrentQuota == 0) + return; + /* Check PLE resource */ + if (!(*prPleCurrentQuota)) + return; + + prQM = &prAdapter->rQM; + + u4AvaliableResource = u4CurrentQuota; + u4MaxResourceLimit = u4TotalQuota; +#if QM_FORWARDING_FAIRNESS + u4TotalUsedResource = prQM->u4GlobalResourceUsedCount; + fgGlobalQueFirst = prQM->fgGlobalQFirst; +#endif + + /* Dequeue function selection */ + if (fgGlobalQueFirst) { + pfnDeQFunc[0] = qmDequeueTxPacketsFromGlobalQueue; + pfnDeQFunc[1] = qmDequeueTxPacketsFromPerStaQueues; + } else { + pfnDeQFunc[0] = qmDequeueTxPacketsFromPerStaQueues; + pfnDeQFunc[1] = qmDequeueTxPacketsFromGlobalQueue; + } + + /* 1st dequeue function */ + u4LeftResource = pfnDeQFunc[0](prAdapter, prQue, ucTC, + u4AvaliableResource, + prPleCurrentQuota, + (u4MaxResourceLimit - u4TotalUsedResource)); + + /* dequeue function comsumes no resource, change */ + if ((u4LeftResource >= u4AvaliableResource) && + (u4AvaliableResource >= + prAdapter->rTxCtrl.u4MaxPageCntPerFrame)) { + fgChangeDeQFunc = TRUE; + } else { + u4TotalUsedResource += + (u4AvaliableResource - u4LeftResource); + /* Used resource exceeds limit, change */ + if (u4TotalUsedResource >= u4MaxResourceLimit) + fgChangeDeQFunc = TRUE; + } + + if (fgChangeDeQFunc) { + fgGlobalQueFirst = !fgGlobalQueFirst; + u4TotalUsedResource = 0; + } + + /* 2nd dequeue function */ + u4LeftResource = pfnDeQFunc[1](prAdapter, prQue, ucTC, + u4LeftResource, prPleCurrentQuota, u4MaxResourceLimit); + +#if QM_FORWARDING_FAIRNESS + prQM->fgGlobalQFirst = fgGlobalQueFirst; + prQM->u4GlobalResourceUsedCount = u4TotalUsedResource; +#endif + +} /* qmDequeueTxPacketsFromPerTypeQueues */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Dequeue TX packets from a QM global Queue for a particular TC + * + * \param[out] prQue The queue to put the dequeued packets + * \param[in] ucTC The TC index(Shall always be BMC_TC_INDEX) + * \param[in] ucMaxNum The maximum amount of available resource + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +uint32_t +qmDequeueTxPacketsFromGlobalQueue(IN struct ADAPTER *prAdapter, + OUT struct QUE *prQue, + IN uint8_t ucTC, IN uint32_t u4CurrentQuota, + IN uint32_t *prPleCurrentQuota, + IN uint32_t u4TotalQuota) +{ + struct BSS_INFO *prBssInfo; + struct QUE *prCurrQueue; + uint32_t u4AvaliableResource; + struct MSDU_INFO *prDequeuedPkt; + struct MSDU_INFO *prBurstEndPkt; + struct QUE rMergeQue; + struct QUE *prMergeQue; + struct QUE_MGT *prQM; + + DBGLOG(QM, TEMP, "Enter %s (TC = %d, quota = %u)\n", + __func__, ucTC, u4CurrentQuota); + + /* Broadcast/Multicast data packets */ + if (u4CurrentQuota == 0) + return u4CurrentQuota; + /* Check PLE resource */ + if (!(*prPleCurrentQuota)) + return u4CurrentQuota; + + prQM = &prAdapter->rQM; + + /* 4 <1> Determine the queue */ + prCurrQueue = &prQM->arTxQueue[TX_QUEUE_INDEX_BMCAST]; + u4AvaliableResource = u4CurrentQuota; + prDequeuedPkt = NULL; + prBurstEndPkt = NULL; + + QUEUE_INITIALIZE(&rMergeQue); + prMergeQue = &rMergeQue; + + /* 4 <2> Dequeue packets */ + while (!QUEUE_IS_EMPTY(prCurrQueue)) { + prDequeuedPkt = (struct MSDU_INFO *) QUEUE_GET_HEAD( + prCurrQueue); + if (prDequeuedPkt->u4PageCount > u4AvaliableResource) + break; + if ((*prPleCurrentQuota) < NIX_TX_PLE_PAGE_CNT_PER_FRAME) + break; + + QUEUE_REMOVE_HEAD(prCurrQueue, prDequeuedPkt, + struct MSDU_INFO *); + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prDequeuedPkt->ucBssIndex); + + if (IS_BSS_ACTIVE(prBssInfo)) { + if (!prBssInfo->fgIsNetAbsent) { + /* to record WMM Set */ + prDequeuedPkt->ucWmmQueSet = + prBssInfo->ucWmmQueSet; + QUEUE_INSERT_TAIL(prQue, + (struct QUE_ENTRY *) + prDequeuedPkt); + prBurstEndPkt = prDequeuedPkt; + prQM->u4DequeueCounter++; + u4AvaliableResource -= + prDequeuedPkt->u4PageCount; + (*prPleCurrentQuota) -= + NIX_TX_PLE_PAGE_CNT_PER_FRAME; + QM_DBG_CNT_INC(prQM, QM_DBG_CNT_26); + } else { + QUEUE_INSERT_TAIL(prMergeQue, + (struct QUE_ENTRY *) + prDequeuedPkt); + } + } else { + QM_TX_SET_NEXT_MSDU_INFO(prDequeuedPkt, NULL); + wlanProcessQueuedMsduInfo(prAdapter, prDequeuedPkt); + } + } + + if (QUEUE_IS_NOT_EMPTY(prMergeQue)) { + QUEUE_CONCATENATE_QUEUES(prMergeQue, prCurrQueue); + QUEUE_MOVE_ALL(prCurrQueue, prMergeQue); + QM_TX_SET_NEXT_MSDU_INFO((struct MSDU_INFO *) + QUEUE_GET_TAIL(prCurrQueue), NULL); + } + + return u4AvaliableResource; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Dequeue TX packets to send to HIF TX + * + * \param[in] prTcqStatus Info about the maximum amount of dequeued packets + * + * \return The list of dequeued TX packets + */ +/*----------------------------------------------------------------------------*/ +struct MSDU_INFO *qmDequeueTxPackets(IN struct ADAPTER *prAdapter, + IN struct TX_TCQ_STATUS *prTcqStatus) +{ + int32_t i; + struct MSDU_INFO *prReturnedPacketListHead; + struct QUE rReturnedQue; + uint32_t u4MaxQuotaLimit; + uint32_t u4AvailableResourcePLE; + + DBGLOG(QM, TEMP, "Enter qmDequeueTxPackets\n"); + + QUEUE_INITIALIZE(&rReturnedQue); + + prReturnedPacketListHead = NULL; + + /* TC0 to TC3: AC0~AC3 (commands packets are not handled by QM) */ + for (i = TC3_INDEX; i >= TC0_INDEX; i--) { + DBGLOG(QM, TEMP, "Dequeue packets from Per-STA queue[%u]\n", i); + + /* If only one STA is Tx allowed, + * no need to restrict Max quota + */ + if (prAdapter->rWifiVar.u4MaxTxDeQLimit) + u4MaxQuotaLimit = prAdapter->rWifiVar.u4MaxTxDeQLimit; + else if (prAdapter->rQM.u4TxAllowedStaCount == 1) + u4MaxQuotaLimit = QM_STA_FORWARD_COUNT_UNLIMITED; + else + u4MaxQuotaLimit = + (uint32_t) prTcqStatus->au4MaxNumOfPage[i]; + + u4AvailableResourcePLE = nicTxResourceGetPleFreeCount( + prAdapter, i); + + if (i == BMC_TC_INDEX) + qmDequeueTxPacketsFromPerTypeQueues(prAdapter, + &rReturnedQue, (uint8_t)i, + prTcqStatus->au4FreePageCount[i], + &u4AvailableResourcePLE, + u4MaxQuotaLimit); + else + qmDequeueTxPacketsFromPerStaQueues(prAdapter, + &rReturnedQue, + (uint8_t)i, + prTcqStatus->au4FreePageCount[i], + &u4AvailableResourcePLE, + u4MaxQuotaLimit); + + /* The aggregate number of dequeued packets */ + DBGLOG(QM, TEMP, "DQA)[%u](%u)\n", i, + rReturnedQue.u4NumElem); + } + + if (QUEUE_IS_NOT_EMPTY(&rReturnedQue)) { + prReturnedPacketListHead = (struct MSDU_INFO *) + QUEUE_GET_HEAD(&rReturnedQue); + QM_TX_SET_NEXT_MSDU_INFO((struct MSDU_INFO *) + QUEUE_GET_TAIL(&rReturnedQue), NULL); + } + + return prReturnedPacketListHead; +} + +#if CFG_SUPPORT_MULTITHREAD +/*----------------------------------------------------------------------------*/ +/*! + * \brief Dequeue TX packets to send to HIF TX + * + * \param[in] prTcqStatus Info about the maximum amount of dequeued packets + * + * \return The list of dequeued TX packets + */ +/*----------------------------------------------------------------------------*/ +struct MSDU_INFO *qmDequeueTxPacketsMthread( + IN struct ADAPTER *prAdapter, + IN struct TX_TCQ_STATUS *prTcqStatus) +{ + + /* INT_32 i; */ + struct MSDU_INFO *prReturnedPacketListHead; + /* QUE_T rReturnedQue; */ + /* UINT_32 u4MaxQuotaLimit; */ + struct MSDU_INFO *prMsduInfo, *prNextMsduInfo; + + KAL_SPIN_LOCK_DECLARATION(); + +#if QM_ADAPTIVE_TC_RESOURCE_CTRL + if (prAdapter->rQM.fgForceReassign) + qmDoAdaptiveTcResourceCtrl(prAdapter); +#endif + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); + + prReturnedPacketListHead = qmDequeueTxPackets(prAdapter, + prTcqStatus); + + /* require the resource first to prevent from unsync */ + prMsduInfo = prReturnedPacketListHead; + while (prMsduInfo) { + prNextMsduInfo = (struct MSDU_INFO *) QUEUE_GET_NEXT_ENTRY(( + struct QUE_ENTRY *) prMsduInfo); + nicTxAcquireResource(prAdapter, prMsduInfo->ucTC, + nicTxGetPageCount(prAdapter, prMsduInfo->u2FrameLength, + FALSE), FALSE); + prMsduInfo = prNextMsduInfo; + } + + if (prReturnedPacketListHead) + wlanTxProfilingTagMsdu(prAdapter, prReturnedPacketListHead, + TX_PROF_TAG_DRV_DEQUE); + + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); + + return prReturnedPacketListHead; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Adjust the TC quotas according to traffic demands + * + * \param[out] prTcqAdjust The resulting adjustment + * \param[in] prTcqStatus Info about the current TC quotas and counters + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +u_int8_t +qmAdjustTcQuotasMthread(IN struct ADAPTER *prAdapter, + OUT struct TX_TCQ_ADJUST *prTcqAdjust, + IN struct TX_TCQ_STATUS *prTcqStatus) +{ +#if QM_ADAPTIVE_TC_RESOURCE_CTRL + uint32_t i; + struct QUE_MGT *prQM = &prAdapter->rQM; + + KAL_SPIN_LOCK_DECLARATION(); + + /* Must initialize */ + for (i = 0; i < QM_ACTIVE_TC_NUM; i++) + prTcqAdjust->ai4Variation[i] = 0; + + /* 4 <1> If TC resource is not just adjusted, exit directly */ + if (!prQM->fgTcResourcePostAnnealing) + return FALSE; + + /* 4 <2> Adjust TcqStatus according to + * the updated prQM->au4CurrentTcResource + */ + else { + int32_t i4TotalExtraQuota = 0; + int32_t ai4ExtraQuota[QM_ACTIVE_TC_NUM]; + u_int8_t fgResourceRedistributed = TRUE; + + /* Must initialize */ + for (i = 0; i < TC_NUM; i++) + prTcqAdjust->ai4Variation[i] = 0; + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); + + /* Obtain the free-to-distribute resource */ + for (i = 0; i < QM_ACTIVE_TC_NUM; i++) { + ai4ExtraQuota[i] = + (int32_t) prTcqStatus->au4MaxNumOfBuffer[i] - + (int32_t) prQM->au4CurrentTcResource[i]; + + if (ai4ExtraQuota[i] > 0) { + /* The resource shall be reallocated + * to other TCs + */ + if (ai4ExtraQuota[i] > + prTcqStatus->au4FreeBufferCount[ + i]) { + ai4ExtraQuota[i] = + prTcqStatus-> + au4FreeBufferCount[i]; + fgResourceRedistributed = FALSE; + } + + i4TotalExtraQuota += ai4ExtraQuota[i]; + prTcqAdjust->ai4Variation[i] = + (-ai4ExtraQuota[i]); + } + } + + /* Distribute quotas to TCs which need extra resource + * according to prQM->au4CurrentTcResource + */ + for (i = 0; i < QM_ACTIVE_TC_NUM; i++) { + if (ai4ExtraQuota[i] < 0) { + if ((-ai4ExtraQuota[i]) > i4TotalExtraQuota) { + ai4ExtraQuota[i] = (-i4TotalExtraQuota); + fgResourceRedistributed = FALSE; + } + + i4TotalExtraQuota += ai4ExtraQuota[i]; + prTcqAdjust->ai4Variation[i] = + (-ai4ExtraQuota[i]); + } + } + + /* In case some TC is waiting for TX Done, + * continue to adjust TC quotas upon TX Done + */ + prQM->fgTcResourcePostAnnealing = (!fgResourceRedistributed); + + for (i = 0; i < TC_NUM; i++) { + prTcqStatus->au4FreePageCount[i] += + (prTcqAdjust->ai4Variation[i] * + prAdapter->rTxCtrl.u4MaxPageCntPerFrame); + prTcqStatus->au4MaxNumOfPage[i] += + (prTcqAdjust->ai4Variation[i] * + prAdapter->rTxCtrl.u4MaxPageCntPerFrame); + + prTcqStatus->au4FreeBufferCount[i] += + prTcqAdjust->ai4Variation[i]; + prTcqStatus->au4MaxNumOfBuffer[i] += + prTcqAdjust->ai4Variation[i]; + } + + + /* PLE */ + qmAdjustTcQuotaPle(prAdapter, prTcqAdjust, prTcqStatus); + + +#if QM_FAST_TC_RESOURCE_CTRL + prQM->fgTcResourceFastReaction = FALSE; +#endif + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); + } + + return TRUE; +#else + return FALSE; +#endif +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Adjust the TC PLE quotas according to traffic demands + * + * \param[out] prTcqAdjust The resulting adjustment + * \param[in] prTcqStatus Info about the current TC quotas and counters + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void qmAdjustTcQuotaPle(IN struct ADAPTER *prAdapter, + OUT struct TX_TCQ_ADJUST *prTcqAdjust, + IN struct TX_TCQ_STATUS *prTcqStatus) +{ + uint8_t i; + int32_t i4pages; + struct TX_CTRL *prTxCtrl; + struct TX_TCQ_STATUS *prTc; + int32_t i4TotalExtraQuota = 0; + + ASSERT(prAdapter); + + prTxCtrl = &prAdapter->rTxCtrl; + prTc = &prTxCtrl->rTc; + + /* no PLE resource control */ + if (!prTc->fgNeedPleCtrl) + return; + + /* collect free PLE resource */ + for (i = TC0_INDEX; i < TC_NUM; i++) { + + if (!nicTxResourceIsPleCtrlNeeded(prAdapter, i)) + continue; + + /* adjust ple resource */ + i4pages = prTcqAdjust->ai4Variation[i] * + NIX_TX_PLE_PAGE_CNT_PER_FRAME; + + if (i4pages < 0) { + /* donate resource to other TC */ + if (prTcqStatus->au4FreePageCount_PLE[i] < (-i4pages)) { + /* not enough to give */ + i4pages = + -(prTcqStatus->au4FreePageCount_PLE[i]); + } + i4TotalExtraQuota += -i4pages; + + prTcqStatus->au4FreePageCount_PLE[i] += i4pages; + prTcqStatus->au4MaxNumOfPage_PLE[i] += i4pages; + + prTcqStatus->au4FreeBufferCount_PLE[i] += + (i4pages / NIX_TX_PLE_PAGE_CNT_PER_FRAME); + prTcqStatus->au4MaxNumOfBuffer_PLE[i] += + (i4pages / NIX_TX_PLE_PAGE_CNT_PER_FRAME); + } + } + + /* distribute PLE resource */ + for (i = TC0_INDEX; i < TC_NUM; i++) { + if (!nicTxResourceIsPleCtrlNeeded(prAdapter, i)) + continue; + + /* adjust ple resource */ + i4pages = prTcqAdjust->ai4Variation[i] * + NIX_TX_PLE_PAGE_CNT_PER_FRAME; + + if (i4pages > 0) { + if (i4TotalExtraQuota >= i4pages) { + i4TotalExtraQuota -= i4pages; + } else { + i4pages = i4TotalExtraQuota; + i4TotalExtraQuota = 0; + } + prTcqStatus->au4FreePageCount_PLE[i] += i4pages; + prTcqStatus->au4MaxNumOfPage_PLE[i] += i4pages; + + prTcqStatus->au4FreeBufferCount_PLE[i] = + (prTcqStatus->au4FreePageCount_PLE[i] / + NIX_TX_PLE_PAGE_CNT_PER_FRAME); + prTcqStatus->au4MaxNumOfBuffer_PLE[i] = + (prTcqStatus->au4MaxNumOfBuffer_PLE[i] / + NIX_TX_PLE_PAGE_CNT_PER_FRAME); + } + } + + /* distribute remaining PLE resource */ + while (i4TotalExtraQuota != 0) { + DBGLOG(QM, INFO, + "distribute remaining PLE resource[%u]\n", + i4TotalExtraQuota); + for (i = TC0_INDEX; i < TC_NUM; i++) { + if (!nicTxResourceIsPleCtrlNeeded(prAdapter, i)) + continue; + + if (i4TotalExtraQuota >= + NIX_TX_PLE_PAGE_CNT_PER_FRAME) { + prTcqStatus->au4FreePageCount_PLE[i] += + NIX_TX_PLE_PAGE_CNT_PER_FRAME; + prTcqStatus->au4MaxNumOfPage_PLE[i] += + NIX_TX_PLE_PAGE_CNT_PER_FRAME; + + prTcqStatus->au4FreeBufferCount_PLE[i] += 1; + prTcqStatus->au4MaxNumOfBuffer_PLE[i] += 1; + + i4TotalExtraQuota -= + NIX_TX_PLE_PAGE_CNT_PER_FRAME; + } else { + /* remaining PLE pages are + * not enough for a package + */ + prTcqStatus->au4FreePageCount_PLE[i] += + i4TotalExtraQuota; + prTcqStatus->au4MaxNumOfPage_PLE[i] += + i4TotalExtraQuota; + + prTcqStatus->au4FreeBufferCount_PLE[i] = + (prTcqStatus->au4FreePageCount_PLE[i] / + NIX_TX_PLE_PAGE_CNT_PER_FRAME); + prTcqStatus->au4MaxNumOfBuffer_PLE[i] = + (prTcqStatus->au4MaxNumOfPage_PLE[i] / + NIX_TX_PLE_PAGE_CNT_PER_FRAME); + + i4TotalExtraQuota = 0; + } + } + } + +} + +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Adjust the TC quotas according to traffic demands + * + * \param[out] prTcqAdjust The resulting adjustment + * \param[in] prTcqStatus Info about the current TC quotas and counters + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +u_int8_t qmAdjustTcQuotas(IN struct ADAPTER *prAdapter, + OUT struct TX_TCQ_ADJUST *prTcqAdjust, + IN struct TX_TCQ_STATUS *prTcqStatus) +{ +#if QM_ADAPTIVE_TC_RESOURCE_CTRL + uint32_t i; + struct QUE_MGT *prQM = &prAdapter->rQM; + + /* Must initialize */ + for (i = 0; i < QM_ACTIVE_TC_NUM; i++) + prTcqAdjust->ai4Variation[i] = 0; + + /* 4 <1> If TC resource is not just adjusted, exit directly */ + if (!prQM->fgTcResourcePostAnnealing) + return FALSE; + /* 4 <2> Adjust TcqStatus according to + * the updated prQM->au4CurrentTcResource + */ + else { + int32_t i4TotalExtraQuota = 0; + int32_t ai4ExtraQuota[QM_ACTIVE_TC_NUM]; + u_int8_t fgResourceRedistributed = TRUE; + + /* Obtain the free-to-distribute resource */ + for (i = 0; i < QM_ACTIVE_TC_NUM; i++) { + ai4ExtraQuota[i] = + (int32_t) prTcqStatus->au4MaxNumOfBuffer[i] - + (int32_t) prQM->au4CurrentTcResource[i]; + + if (ai4ExtraQuota[i] > 0) { + /* The resource shall be + * reallocated to other TCs + */ + if (ai4ExtraQuota[i] > + prTcqStatus->au4FreeBufferCount[i]) { + ai4ExtraQuota[i] = + prTcqStatus-> + au4FreeBufferCount[i]; + fgResourceRedistributed = FALSE; + } + + i4TotalExtraQuota += ai4ExtraQuota[i]; + prTcqAdjust->ai4Variation[i] = + (-ai4ExtraQuota[i]); + } + } + + /* Distribute quotas to TCs which need extra resource + * according to prQM->au4CurrentTcResource + */ + for (i = 0; i < QM_ACTIVE_TC_NUM; i++) { + if (ai4ExtraQuota[i] < 0) { + if ((-ai4ExtraQuota[i]) > i4TotalExtraQuota) { + ai4ExtraQuota[i] = (-i4TotalExtraQuota); + fgResourceRedistributed = FALSE; + } + + i4TotalExtraQuota += ai4ExtraQuota[i]; + prTcqAdjust->ai4Variation[i] = + (-ai4ExtraQuota[i]); + } + } + + /* In case some TC is waiting for TX Done, + * continue to adjust TC quotas upon TX Done + */ + prQM->fgTcResourcePostAnnealing = (!fgResourceRedistributed); + +#if QM_FAST_TC_RESOURCE_CTRL + prQM->fgTcResourceFastReaction = FALSE; +#endif + +#if QM_PRINT_TC_RESOURCE_CTRL + DBGLOG(QM, LOUD, + "QM: Curr Quota [0]=%u [1]=%u [2]=%u [3]=%u [4]=%u [5]=%u\n", + prTcqStatus->au4FreeBufferCount[0], + prTcqStatus->au4FreeBufferCount[1], + prTcqStatus->au4FreeBufferCount[2], + prTcqStatus->au4FreeBufferCount[3], + prTcqStatus->au4FreeBufferCount[4], + prTcqStatus->au4FreeBufferCount[5]); +#endif + } + + return TRUE; +#else + return FALSE; +#endif +} + +#if QM_ADAPTIVE_TC_RESOURCE_CTRL +/*----------------------------------------------------------------------------*/ +/*! + * \brief Update the average TX queue length for the TC resource control + * mechanism + * + * \param (none) + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void qmUpdateAverageTxQueLen(IN struct ADAPTER *prAdapter) +{ + int32_t u4CurrQueLen, u4Tc, u4StaRecIdx; + struct STA_RECORD *prStaRec; + struct QUE_MGT *prQM = &prAdapter->rQM; + struct BSS_INFO *prBssInfo; + + /* 4 <1> Update the queue lengths for TC0 to TC3 (skip TC4) and TC5 */ + for (u4Tc = 0; u4Tc < QM_ACTIVE_TC_NUM; u4Tc++) { + u4CurrQueLen = 0; + + /* Calculate per-STA queue length */ + if (u4Tc < NUM_OF_PER_STA_TX_QUEUES) { + for (u4StaRecIdx = 0; u4StaRecIdx < CFG_STA_REC_NUM; + u4StaRecIdx++) { + prStaRec = cnmGetStaRecByIndex(prAdapter, + u4StaRecIdx); + if (prStaRec) { + prBssInfo = GET_BSS_INFO_BY_INDEX( + prAdapter, + prStaRec->ucBssIndex); + + /* If the STA is activated, + * get the queue length + */ + if ((prStaRec->fgIsValid) && + (!prBssInfo->fgIsNetAbsent)) + u4CurrQueLen += + (prStaRec-> + arTxQueue[u4Tc]. + u4NumElem); + } + } + } + + if (u4Tc == BMC_TC_INDEX) { + /* Update the queue length for (BMCAST) */ + u4CurrQueLen += prQM->arTxQueue[ + TX_QUEUE_INDEX_BMCAST].u4NumElem; + } + + if (prQM->au4AverageQueLen[u4Tc] == 0) { + prQM->au4AverageQueLen[u4Tc] = (u4CurrQueLen << + prQM->u4QueLenMovingAverage); + } else { + prQM->au4AverageQueLen[u4Tc] -= + (prQM->au4AverageQueLen[u4Tc] >> + prQM->u4QueLenMovingAverage); + prQM->au4AverageQueLen[u4Tc] += (u4CurrQueLen); + } + } +#if 0 + /* Update the queue length for TC5 (BMCAST) */ + u4CurrQueLen = + prQM->arTxQueue[TX_QUEUE_INDEX_BMCAST].u4NumElem; + + if (prQM->au4AverageQueLen[TC5_INDEX] == 0) { + prQM->au4AverageQueLen[TC5_INDEX] = (u4CurrQueLen << + QM_QUE_LEN_MOVING_AVE_FACTOR); + } else { + prQM->au4AverageQueLen[TC5_INDEX] -= + (prQM->au4AverageQueLen[TC5_INDEX] >> + QM_QUE_LEN_MOVING_AVE_FACTOR); + prQM->au4AverageQueLen[TC5_INDEX] += (u4CurrQueLen); + } +#endif +} + +void qmAllocateResidualTcResource(IN struct ADAPTER *prAdapter, + IN int32_t *ai4TcResDemand, + IN uint32_t *pu4ResidualResource, + IN uint32_t *pu4ShareCount) +{ + struct QUE_MGT *prQM = &prAdapter->rQM; + uint32_t u4Share = 0; + uint32_t u4TcIdx; + uint8_t ucIdx; + uint32_t au4AdjTc[] = { TC3_INDEX, TC2_INDEX, TC1_INDEX, TC0_INDEX }; + uint32_t u4AdjTcSize = (sizeof(au4AdjTc) / sizeof(uint32_t)); + uint32_t u4ResidualResource = *pu4ResidualResource; + uint32_t u4ShareCount = *pu4ShareCount; + + /* If there is no resource left, exit directly */ + if (u4ResidualResource == 0) + return; + + /* This shall not happen */ + if (u4ShareCount == 0) { + prQM->au4CurrentTcResource[TC1_INDEX] += u4ResidualResource; + DBGLOG(QM, ERROR, "QM: (Error) u4ShareCount = 0\n"); + return; + } + + /* Share the residual resource evenly */ + u4Share = (u4ResidualResource / u4ShareCount); + if (u4Share) { + for (u4TcIdx = 0; u4TcIdx < QM_ACTIVE_TC_NUM; u4TcIdx++) { + /* Skip TC4 (not adjustable) */ + if (u4TcIdx == TC4_INDEX) + continue; + + if (ai4TcResDemand[u4TcIdx] > 0) { + if (ai4TcResDemand[u4TcIdx] > u4Share) { + prQM->au4CurrentTcResource[u4TcIdx] += + u4Share; + u4ResidualResource -= u4Share; + ai4TcResDemand[u4TcIdx] -= u4Share; + } else { + prQM->au4CurrentTcResource[u4TcIdx] += + ai4TcResDemand[u4TcIdx]; + u4ResidualResource -= + ai4TcResDemand[u4TcIdx]; + ai4TcResDemand[u4TcIdx] = 0; + } + } + } + } + + /* By priority, allocate the left resource + * that is not divisible by u4Share + */ + ucIdx = 0; + while (u4ResidualResource) { + u4TcIdx = au4AdjTc[ucIdx]; + + if (ai4TcResDemand[u4TcIdx]) { + prQM->au4CurrentTcResource[u4TcIdx]++; + u4ResidualResource--; + ai4TcResDemand[u4TcIdx]--; + + if (ai4TcResDemand[u4TcIdx] == 0) + u4ShareCount--; + } + + if (u4ShareCount <= 0) + break; + + ucIdx++; + ucIdx %= u4AdjTcSize; + } + + /* Allocate the left resource */ + prQM->au4CurrentTcResource[TC3_INDEX] += u4ResidualResource; + + *pu4ResidualResource = u4ResidualResource; + *pu4ShareCount = u4ShareCount; + +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Assign TX resource for each TC according to TX queue length and + * current assignment + * + * \param (none) + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void qmReassignTcResource(IN struct ADAPTER *prAdapter) +{ + int32_t i4TotalResourceDemand = 0; + uint32_t u4ResidualResource = 0; + uint32_t u4TcIdx; + int32_t ai4TcResDemand[QM_ACTIVE_TC_NUM]; + uint32_t u4ShareCount = 0; + uint32_t u4Share = 0; + struct QUE_MGT *prQM = &prAdapter->rQM; + uint32_t u4ActiveTcCount = 0; + uint32_t u4LastActiveTcIdx = TC3_INDEX; + + /* Note: After the new assignment is obtained, + * set prQM->fgTcResourcePostAnnealing to TRUE to + * start the TC-quota adjusting procedure, + * which will be invoked upon every TX Done + */ + + /* 4 <1> Determine the demands */ + /* Determine the amount of extra resource + * to fulfill all of the demands + */ + for (u4TcIdx = 0; u4TcIdx < QM_ACTIVE_TC_NUM; u4TcIdx++) { + /* Skip TC4, which is not adjustable */ + if (u4TcIdx == TC4_INDEX) + continue; + + /* Define: extra_demand = que_length + + * min_reserved_quota - current_quota + */ + ai4TcResDemand[u4TcIdx] = ((int32_t)(QM_GET_TX_QUEUE_LEN( + prAdapter, u4TcIdx) + + prQM->au4MinReservedTcResource[u4TcIdx]) - + (int32_t)prQM->au4CurrentTcResource[u4TcIdx]); + + /* If there are queued packets, allocate extra resource + * for the TC (for TCP consideration) + */ + if (QM_GET_TX_QUEUE_LEN(prAdapter, u4TcIdx)) { + ai4TcResDemand[u4TcIdx] += + prQM->u4ExtraReservedTcResource; + u4ActiveTcCount++; + } + + i4TotalResourceDemand += ai4TcResDemand[u4TcIdx]; + } + + /* 4 <2> Case 1: Demand <= Total Resource */ + if (i4TotalResourceDemand <= 0) { + + /* 4 <2.1> Calculate the residual resource evenly */ + /* excluding TC4 */ + if (u4ActiveTcCount == 0) + u4ShareCount = (QM_ACTIVE_TC_NUM - 1); + else + u4ShareCount = u4ActiveTcCount; + + u4ResidualResource = (uint32_t) (-i4TotalResourceDemand); + u4Share = (u4ResidualResource / u4ShareCount); + + /* 4 <2.2> Satisfy every TC and share + * the residual resource evenly + */ + for (u4TcIdx = 0; u4TcIdx < QM_ACTIVE_TC_NUM; u4TcIdx++) { + /* Skip TC4 (not adjustable) */ + if (u4TcIdx == TC4_INDEX) + continue; + + prQM->au4CurrentTcResource[u4TcIdx] += + ai4TcResDemand[u4TcIdx]; + + /* Every TC is fully satisfied */ + ai4TcResDemand[u4TcIdx] = 0; + + /* The left resource will be allocated */ + if (QM_GET_TX_QUEUE_LEN(prAdapter, u4TcIdx) || + (u4ActiveTcCount == 0)) { + prQM->au4CurrentTcResource[u4TcIdx] += u4Share; + u4ResidualResource -= u4Share; + u4LastActiveTcIdx = u4TcIdx; + } + } + + /* 4 <2.3> Allocate the left resource to last active TC */ + prQM->au4CurrentTcResource[u4LastActiveTcIdx] += + (u4ResidualResource); + + } + /* 4 <3> Case 2: Demand > Total Resource --> Guarantee + * a minimum amount of resource for each TC + */ + else { + u4ShareCount = 0; + u4ResidualResource = prQM->u4ResidualTcResource; + + /* 4 <3.1> Allocated resouce amount = minimum + * of (guaranteed, total demand) + */ + for (u4TcIdx = 0; u4TcIdx < QM_ACTIVE_TC_NUM; u4TcIdx++) { + /* Skip TC4 (not adjustable) */ + if (u4TcIdx == TC4_INDEX) + continue; + + /* The demand can be fulfilled with + * the guaranteed resource amount + */ + if ((prQM->au4CurrentTcResource[u4TcIdx] + + ai4TcResDemand[u4TcIdx]) <= + prQM->au4GuaranteedTcResource[u4TcIdx]) { + + prQM->au4CurrentTcResource[u4TcIdx] += + ai4TcResDemand[u4TcIdx]; + u4ResidualResource += + (prQM->au4GuaranteedTcResource[u4TcIdx] + - prQM->au4CurrentTcResource[u4TcIdx]); + ai4TcResDemand[u4TcIdx] = 0; + } + + /* The demand can not be fulfilled with + * the guaranteed resource amount + */ + else { + ai4TcResDemand[u4TcIdx] -= + (prQM->au4GuaranteedTcResource[u4TcIdx] + - prQM->au4CurrentTcResource[u4TcIdx]); + + prQM->au4CurrentTcResource[u4TcIdx] = + prQM->au4GuaranteedTcResource[u4TcIdx]; + u4ShareCount++; + } + } + + /* 4 <3.2> Allocate the residual resource */ + qmAllocateResidualTcResource(prAdapter, ai4TcResDemand, + &u4ResidualResource, &u4ShareCount); + } + + prQM->fgTcResourcePostAnnealing = TRUE; + +#if QM_PRINT_TC_RESOURCE_CTRL + /* Debug print */ + DBGLOG(QM, INFO, + "QM: TC Rsc adjust to [%03u:%03u:%03u:%03u:%03u:%03u]\n", + prQM->au4CurrentTcResource[0], + prQM->au4CurrentTcResource[1], + prQM->au4CurrentTcResource[2], + prQM->au4CurrentTcResource[3], + prQM->au4CurrentTcResource[4], + prQM->au4CurrentTcResource[5]); +#endif + +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Adjust TX resource for each TC according to TX queue length and + * current assignment + * + * \param (none) + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void qmDoAdaptiveTcResourceCtrl(IN struct ADAPTER *prAdapter) +{ + struct QUE_MGT *prQM = &prAdapter->rQM; + + if (prQM->fgForceReassign) { + prQM->u4TimeToUpdateQueLen = 1; + prQM->u4TimeToAdjustTcResource = 1; + prQM->fgTcResourceFastReaction = TRUE; + + prQM->fgForceReassign = FALSE; + } + + /* 4 <0> Check to update queue length or not */ + if (--prQM->u4TimeToUpdateQueLen) + return; + /* 4 <1> Update TC queue length */ + prQM->u4TimeToUpdateQueLen = QM_INIT_TIME_TO_UPDATE_QUE_LEN; + qmUpdateAverageTxQueLen(prAdapter); + + /* 4 <2> Adjust TC resource assignment */ + /* Check whether it is time to adjust the TC resource assignment */ + if (--prQM->u4TimeToAdjustTcResource == 0) { + /* The last assignment has not been completely applied */ + if (prQM->fgTcResourcePostAnnealing) { + /* Upon the next qmUpdateAverageTxQueLen function call, + * do this check again + */ + prQM->u4TimeToAdjustTcResource = 1; + } + + /* The last assignment has been applied */ + else { + prQM->u4TimeToAdjustTcResource = + QM_INIT_TIME_TO_ADJUST_TC_RSC; + qmReassignTcResource(prAdapter); +#if QM_FAST_TC_RESOURCE_CTRL + if (prQM->fgTcResourceFastReaction) { + prQM->fgTcResourceFastReaction = FALSE; + nicTxAdjustTcq(prAdapter); + } +#endif + } + } + + /* Debug */ +#if QM_PRINT_TC_RESOURCE_CTRL + do { + uint32_t u4Tc; + + for (u4Tc = 0; u4Tc < QM_ACTIVE_TC_NUM; u4Tc++) { + if (QM_GET_TX_QUEUE_LEN(prAdapter, u4Tc) >= 100) { + log_dbg(QM, LOUD, "QM: QueLen [%ld %ld %ld %ld %ld %ld]\n", + QM_GET_TX_QUEUE_LEN(prAdapter, 0), + QM_GET_TX_QUEUE_LEN(prAdapter, 1), + QM_GET_TX_QUEUE_LEN(prAdapter, 2), + QM_GET_TX_QUEUE_LEN(prAdapter, 3), + QM_GET_TX_QUEUE_LEN(prAdapter, 4), + QM_GET_TX_QUEUE_LEN(prAdapter, 5)); + break; + } + } + } while (FALSE); +#endif + +} + +#if QM_FAST_TC_RESOURCE_CTRL +void qmCheckForFastTcResourceCtrl(IN struct ADAPTER *prAdapter, + IN uint8_t ucTc) +{ + struct QUE_MGT *prQM = &prAdapter->rQM; + u_int8_t fgTrigger = FALSE; + + if (!prAdapter->rTxCtrl.rTc.au4FreeBufferCount[ucTc] + || ((prAdapter->rTxCtrl.rTc.fgNeedPleCtrl) && + (!prAdapter->rTxCtrl.rTc.au4FreeBufferCount_PLE[ucTc]))) { + if (!prQM->au4CurrentTcResource[ucTc] || + nicTxGetAdjustableResourceCnt(prAdapter)) + fgTrigger = TRUE; + } + + /* Trigger TC resource adjustment + * if there is a requirement coming for a empty TC + */ + if (fgTrigger) { + prQM->fgForceReassign = TRUE; + + DBGLOG(QM, LOUD, + "Trigger TC Resource adjustment for TC[%u]\n", ucTc); + } +} +#endif + +#endif + +uint32_t gmGetDequeueQuota( + IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, + IN struct BSS_INFO *prBssInfo, + IN uint32_t u4TotalQuota +) +{ + uint32_t u4Weight = 100; + uint32_t u4Quota; + + struct QUE_MGT *prQM = &prAdapter->rQM; + + /* Only apply to SDIO, PCIE/AXI use HW DMA */ + if ((prAdapter->rWifiVar.uDeQuePercentEnable == FALSE) || + (prQM->fgIsTxResrouceControlEn == FALSE)) + return u4TotalQuota; + + if (prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_BIT_VHT) { + if (prBssInfo->ucVhtChannelWidth > + VHT_OP_CHANNEL_WIDTH_20_40) { + /* BW80 NSS1 rate: MCS9 433 Mbps */ + u4Weight = prAdapter->rWifiVar.u4DeQuePercentVHT80Nss1; + } else if (prBssInfo->eBssSCO != CHNL_EXT_SCN) { + /* BW40 NSS1 Max rate: 200 Mbps */ + u4Weight = prAdapter->rWifiVar.u4DeQuePercentVHT40Nss1; + } else { + /* BW20 NSS1 Max rate: 72.2Mbps (MCS8 86.7Mbps) */ + u4Weight = prAdapter->rWifiVar.u4DeQuePercentVHT20Nss1; + } + } else if (prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_BIT_HT) { + if (prBssInfo->ucHtOpInfo1 & HT_OP_INFO1_STA_CHNL_WIDTH) { + /* BW40 NSS1 Max rate: 150 Mbps (MCS9 200Mbps)*/ + u4Weight = prAdapter->rWifiVar.u4DeQuePercentHT40Nss1; + } else { + /* BW20 NSS1 Max rate: 72.2Mbps (MCS8 86.7Mbps)*/ + u4Weight = prAdapter->rWifiVar.u4DeQuePercentHT20Nss1; + } + } +#if (CFG_SUPPORT_802_11AX == 1) + else if (fgEfuseCtrlAxOn == 1) { + if (prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_BIT_HE) + ;/* TBD */ + } +#endif + + u4Quota = u4TotalQuota * u4Weight / 100; + + if (u4Quota > u4TotalQuota || u4Quota <= 0) + return u4TotalQuota; + + return u4Quota; +} + +/*----------------------------------------------------------------------------*/ +/* RX-Related Queue Management */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/*! + * \brief Init Queue Management for RX + * + * \param[in] (none) + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void qmInitRxQueues(IN struct ADAPTER *prAdapter) +{ + /* DbgPrint("QM: Enter qmInitRxQueues()\n"); */ + /* TODO */ +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Handle RX packets (buffer reordering) + * + * \param[in] prSwRfbListHead The list of RX packets + * + * \return The list of packets which are not buffered for reordering + */ +/*----------------------------------------------------------------------------*/ +struct SW_RFB *qmHandleRxPackets(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfbListHead) +{ + +#if CFG_RX_REORDERING_ENABLED + struct SW_RFB *prCurrSwRfb; + struct SW_RFB *prNextSwRfb; + void *prRxStatus; + struct QUE rReturnedQue; + struct QUE *prReturnedQue; + uint8_t *pucEthDestAddr; + u_int8_t fgIsBMC, fgIsHTran; + u_int8_t fgMicErr; +#if CFG_SUPPORT_REPLAY_DETECTION + u_int8_t ucBssIndexRly = 0; + struct BSS_INFO *prBssInfoRly = NULL; +#endif + + DEBUGFUNC("qmHandleRxPackets"); + + ASSERT(prSwRfbListHead); + + prReturnedQue = &rReturnedQue; + + QUEUE_INITIALIZE(prReturnedQue); + prNextSwRfb = prSwRfbListHead; + + do { + prCurrSwRfb = prNextSwRfb; + prNextSwRfb = QM_RX_GET_NEXT_SW_RFB(prCurrSwRfb); + + prRxStatus = prCurrSwRfb->prRxStatus; + if (prCurrSwRfb->u2RxByteCount > CFG_RX_MAX_PKT_SIZE) { + prCurrSwRfb->eDst = RX_PKT_DESTINATION_NULL; + QUEUE_INSERT_TAIL(prReturnedQue, + (struct QUE_ENTRY *) prCurrSwRfb); + DBGLOG(QM, ERROR, + "Drop packet when packet length is larger than CFG_RX_MAX_PKT_SIZE. Packet length=%d\n", + prCurrSwRfb->u2RxByteCount); + continue; + } + /* TODO: (Tehuang) Check if relaying */ + prCurrSwRfb->eDst = RX_PKT_DESTINATION_HOST; + + /* Decide the Destination */ +#if CFG_RX_PKTS_DUMP + if (prAdapter->rRxCtrl.u4RxPktsDumpTypeMask & BIT( + HIF_RX_PKT_TYPE_DATA)) { + log_dbg(SW4, INFO, + "QM RX DATA: net _u sta idx %u wlan idx %u", + prCurrSwRfb->ucStaRecIdx, + prCurrSwRfb->ucWlanIdx); + log_dbg(SW4, INFO, + " ssn _u tid %u ptype %u 11 %u\n", + prCurrSwRfb->ucTid, + prCurrSwRfb->ucPacketType, + prCurrSwRfb->fgReorderBuffer); + + DBGLOG_MEM8(SW4, TRACE, + (uint8_t *) prCurrSwRfb->pvHeader, + prCurrSwRfb->u2PacketLen); + } +#endif + + fgIsBMC = (prCurrSwRfb->fgIsBC | prCurrSwRfb->fgIsMC); + fgIsHTran = FALSE; + if (prCurrSwRfb->fgHdrTran) { + /* (!HIF_RX_HDR_GET_80211_FLAG(prHifRxHdr)){ */ + + uint8_t ucBssIndex; + struct BSS_INFO *prBssInfo; + uint8_t aucTaAddr[MAC_ADDR_LEN]; + + fgIsHTran = TRUE; + pucEthDestAddr = prCurrSwRfb->pvHeader; + if (prCurrSwRfb->prRxStatusGroup4 == NULL) { + DBGLOG(QM, ERROR, + "H/W did Header Trans but prRxStatusGroup4 is NULL !!!\n"); + DBGLOG_MEM8(QM, ERROR, prCurrSwRfb->pucRecvBuff, + prCurrSwRfb->u2RxByteCount); + prCurrSwRfb->eDst = RX_PKT_DESTINATION_NULL; + QUEUE_INSERT_TAIL(prReturnedQue, + (struct QUE_ENTRY *) + prCurrSwRfb); + DBGLOG(RX, WARN, + "rxStatusGroup4 for data packet is NULL, drop this packet, and dump RXD and Packet\n"); + DBGLOG_MEM8(RX, WARN, (uint8_t *) prRxStatus, + sizeof(*prRxStatus)); + if (prCurrSwRfb->pvHeader) + DBGLOG_MEM8(RX, WARN, + prCurrSwRfb->pvHeader, + prCurrSwRfb->u2PacketLen > + 32 ? 32 : + prCurrSwRfb->u2PacketLen); +#if 0 + glSetRstReason(RST_GROUP4_NULL); + GL_RESET_TRIGGER(prAdapter, + RST_FLAG_DO_CORE_DUMP); +#endif + continue; + } + + if (prCurrSwRfb->prStaRec == NULL) { + /* Workaround WTBL Issue */ + HAL_RX_STATUS_GET_TA( + prCurrSwRfb->prRxStatusGroup4, + aucTaAddr); + prCurrSwRfb->ucStaRecIdx = + secLookupStaRecIndexFromTA( + prAdapter, aucTaAddr); + if (prCurrSwRfb->ucStaRecIdx < + CFG_STA_REC_NUM) { + prCurrSwRfb->prStaRec = + cnmGetStaRecByIndex(prAdapter, + prCurrSwRfb-> + ucStaRecIdx); +#define __STR_FMT__ \ + "Re-search the staRec = %d, mac = " MACSTR ", byteCnt= %d\n" + log_dbg(QM, TRACE, + __STR_FMT__, + prCurrSwRfb->ucStaRecIdx, + MAC2STR(aucTaAddr), + prCurrSwRfb->u2RxByteCount); +#undef __STR_FMT__ + } + + if (prCurrSwRfb->prStaRec == NULL) { + DBGLOG(RX, TEMP, + "Mark NULL the Packet for no STA_REC, wlanIdx=%d\n", + prCurrSwRfb->ucWlanIdx); + RX_INC_CNT(&prAdapter->rRxCtrl, + RX_NO_STA_DROP_COUNT); + prCurrSwRfb->eDst = + RX_PKT_DESTINATION_NULL; + QUEUE_INSERT_TAIL(prReturnedQue, + (struct QUE_ENTRY *) + prCurrSwRfb); + continue; + } + + prCurrSwRfb->ucWlanIdx = + prCurrSwRfb->prStaRec->ucWlanIndex; + GLUE_SET_PKT_BSS_IDX(prCurrSwRfb->pvPacket, + secGetBssIdxByWlanIdx(prAdapter, + prCurrSwRfb->ucWlanIdx)); + } + + ucBssIndex = prCurrSwRfb->prStaRec->ucBssIndex; + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + ucBssIndex); + + if (!IS_BSS_ACTIVE(prBssInfo)) { + log_dbg(RX, TEMP, "Mark NULL the Packet for inactive Bss %u\n", + ucBssIndex); + RX_INC_CNT(&prAdapter->rRxCtrl, + RX_INACTIVE_BSS_DROP_COUNT); + prCurrSwRfb->eDst = + RX_PKT_DESTINATION_NULL; + QUEUE_INSERT_TAIL(prReturnedQue, + (struct QUE_ENTRY *) + prCurrSwRfb); + continue; + } + + if (prBssInfo->eCurrentOPMode == + OP_MODE_ACCESS_POINT) { + if (IS_BMCAST_MAC_ADDR( + pucEthDestAddr)) { + prCurrSwRfb->eDst = + RX_PKT_DESTINATION_HOST_WITH_FORWARD; + } else if ( + secLookupStaRecIndexFromTA( + prAdapter, + pucEthDestAddr) + != + STA_REC_INDEX_NOT_FOUND) { + + prCurrSwRfb->eDst = + RX_PKT_DESTINATION_FORWARD; + } + } +#if CFG_SUPPORT_PASSPOINT + else if (hs20IsFrameFilterEnabled(prAdapter, + prBssInfo) && + hs20IsUnsecuredFrame(prAdapter, + prBssInfo, + prCurrSwRfb)) { + DBGLOG(QM, WARN, + "Mark NULL the Packet for Dropped Packet %u\n", + ucBssIndex); + RX_INC_CNT(&prAdapter->rRxCtrl, + RX_HS20_DROP_COUNT); + prCurrSwRfb->eDst = + RX_PKT_DESTINATION_NULL; + QUEUE_INSERT_TAIL(prReturnedQue, + (struct QUE_ENTRY *) + prCurrSwRfb); + continue; + } +#endif /* CFG_SUPPORT_PASSPOINT */ + } else { + uint16_t u2FrameCtrl = 0; + struct WLAN_MAC_HEADER *prWlanHeader = NULL; + struct BSS_INFO *prAisBssInfo = NULL; + + prAisBssInfo = aisGetAisBssInfo(prAdapter, + secGetBssIdxByWlanIdx( + prAdapter, + prCurrSwRfb->ucWlanIdx)); + prWlanHeader = (struct WLAN_MAC_HEADER *) + prCurrSwRfb->pvHeader; + u2FrameCtrl = prWlanHeader->u2FrameCtrl; + prCurrSwRfb->u2SequenceControl = + prWlanHeader->u2SeqCtrl; + if (prCurrSwRfb->prStaRec == NULL && + RXM_IS_DATA_FRAME(u2FrameCtrl) && + (prAisBssInfo) && + (prAisBssInfo->eConnectionState == + MEDIA_STATE_CONNECTED)) { + /* rx header translation */ + log_dbg(QM, WARN, "RXD Trans: FrameCtrl=0x%02x GVLD=0x%x, StaRecIdx=%d, WlanIdx=%d PktLen=%d\n", + u2FrameCtrl, prCurrSwRfb->ucGroupVLD, + prCurrSwRfb->ucStaRecIdx, + prCurrSwRfb->ucWlanIdx, + prCurrSwRfb->u2PacketLen); + DBGLOG_MEM8(QM, LOUD, + (uint8_t *) + prCurrSwRfb->pvHeader, + (prCurrSwRfb-> + u2PacketLen > 32) ? 32 : + prCurrSwRfb-> + u2PacketLen); + if (prAisBssInfo + && prAisBssInfo->prStaRecOfAP) + if (EQUAL_MAC_ADDR( + prWlanHeader-> + aucAddr1, + prAisBssInfo-> + aucOwnMacAddr) + && EQUAL_MAC_ADDR( + prWlanHeader-> + aucAddr2, + prAisBssInfo-> + aucBSSID)) { + uint16_t u2MACLen = 0; + /* QoS data, VHT */ + if (RXM_IS_QOS_DATA_FRAME( + u2FrameCtrl)) + u2MACLen = sizeof( + struct WLAN_MAC_HEADER_QOS); + else + u2MACLen = sizeof( + struct + WLAN_MAC_HEADER); + u2MACLen += + ETH_LLC_LEN + + ETH_SNAP_OUI_LEN; + u2MACLen -= + ETHER_TYPE_LEN_OFFSET; + prCurrSwRfb->pvHeader += + u2MACLen; + kalMemCopy( + prCurrSwRfb->pvHeader, + prWlanHeader->aucAddr1, + MAC_ADDR_LEN); + kalMemCopy( + prCurrSwRfb->pvHeader + + MAC_ADDR_LEN, + prWlanHeader->aucAddr2, + MAC_ADDR_LEN); + prCurrSwRfb->u2PacketLen -= + u2MACLen; + + /* record StaRec related info */ + prCurrSwRfb->prStaRec = + prAisBssInfo-> + prStaRecOfAP; + prCurrSwRfb->ucStaRecIdx = + prCurrSwRfb->prStaRec-> + ucIndex; + prCurrSwRfb->ucWlanIdx = + prCurrSwRfb->prStaRec-> + ucWlanIndex; + GLUE_SET_PKT_BSS_IDX( + prCurrSwRfb->pvPacket, + secGetBssIdxByWlanIdx( + prAdapter, + prCurrSwRfb-> + ucWlanIdx)); + DBGLOG_MEM8(QM, WARN, + (uint8_t *) + prCurrSwRfb->pvHeader, + (prCurrSwRfb-> + u2PacketLen > 64) ? 64 : + prCurrSwRfb-> + u2PacketLen); + } + } + } + +#if CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION + if (prCurrSwRfb->fgDataFrame && prCurrSwRfb->prStaRec && + qmAmsduAttackDetection(prAdapter, prCurrSwRfb)) { + prCurrSwRfb->eDst = RX_PKT_DESTINATION_NULL; + QUEUE_INSERT_TAIL(prReturnedQue, + (struct QUE_ENTRY *) prCurrSwRfb); + DBGLOG(QM, INFO, "drop AMSDU attack packet\n"); + continue; + } + + if (prCurrSwRfb->fgDataFrame && prCurrSwRfb->prStaRec && + qmDetectRxInvalidEAPOL(prAdapter, prCurrSwRfb)) { + prCurrSwRfb->eDst = RX_PKT_DESTINATION_NULL; + QUEUE_INSERT_TAIL(prReturnedQue, + (struct QUE_ENTRY *) prCurrSwRfb); + DBGLOG(QM, INFO, + "drop EAPOL packet not in sec mode\n"); + continue; + } +#endif /* CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION */ + +#if CFG_SUPPORT_WAPI + if (prCurrSwRfb->u2PacketLen > ETHER_HEADER_LEN) { + uint8_t *pc = (uint8_t *) prCurrSwRfb->pvHeader; + uint16_t u2Etype = 0; + + u2Etype = (pc[ETHER_TYPE_LEN_OFFSET] << 8) | + (pc[ETHER_TYPE_LEN_OFFSET + 1]); + /* for wapi integrity test. WPI_1x packet should be + * always in non-encrypted mode. if we received any + * WPI(0x88b4) packet that is encrypted, drop here. + */ + if (u2Etype == ETH_WPI_1X && + prCurrSwRfb->ucSecMode != 0 && + prCurrSwRfb->fgIsCipherMS == 0) { + DBGLOG(QM, INFO, + "drop wpi packet with sec mode\n"); + prCurrSwRfb->eDst = RX_PKT_DESTINATION_NULL; + QUEUE_INSERT_TAIL(prReturnedQue, + (struct QUE_ENTRY *) prCurrSwRfb); + continue; + } + } +#endif + + /* Todo:: Move the data class error check here */ + +#if CFG_SUPPORT_REPLAY_DETECTION + if (prCurrSwRfb->prStaRec) { + ucBssIndexRly = prCurrSwRfb->prStaRec->ucBssIndex; + prBssInfoRly = GET_BSS_INFO_BY_INDEX(prAdapter, + ucBssIndexRly); + if (prBssInfoRly && !IS_BSS_ACTIVE(prBssInfoRly)) { + DBGLOG(QM, INFO, + "Mark NULL the Packet for inactive Bss %u\n", + ucBssIndexRly); + prCurrSwRfb->eDst = RX_PKT_DESTINATION_NULL; + QUEUE_INSERT_TAIL(prReturnedQue, + (struct QUE_ENTRY *) prCurrSwRfb); + continue; + } + } + if (fgIsBMC && prBssInfoRly && IS_BSS_AIS(prBssInfoRly) && + qmHandleRxReplay(prAdapter, prCurrSwRfb)) { + prCurrSwRfb->eDst = RX_PKT_DESTINATION_NULL; + QUEUE_INSERT_TAIL(prReturnedQue, + (struct QUE_ENTRY *) prCurrSwRfb); + DBGLOG(RX, TEMP, "BMC replay\n"); + continue; + } +#endif + + if (prCurrSwRfb->fgReorderBuffer && !fgIsBMC && fgIsHTran) { + /* If this packet should dropped or indicated to the + * host immediately, it should be enqueued into the + * rReturnedQue with specific flags. If this packet + * should be buffered for reordering, it should be + * enqueued into the reordering queue in the STA_REC + * rather than into the rReturnedQue. + */ + if (prCurrSwRfb->ucTid >= CFG_RX_MAX_BA_TID_NUM) { + log_dbg(QM, ERROR, + "TID from RXD = %d, out of range !!!\n", + prCurrSwRfb->ucTid); + DBGLOG_MEM8(QM, ERROR, + prCurrSwRfb->pucRecvBuff, + prCurrSwRfb->u2RxByteCount); + QUEUE_INSERT_TAIL(prReturnedQue, + (struct QUE_ENTRY *) prCurrSwRfb); + } else + qmProcessPktWithReordering(prAdapter, + prCurrSwRfb, prReturnedQue); + + } else if (prCurrSwRfb->fgDataFrame) { + /* Check Class Error */ + if (prCurrSwRfb->prStaRec && + (secCheckClassError(prAdapter, prCurrSwRfb, + prCurrSwRfb->prStaRec) == TRUE)) { + struct RX_BA_ENTRY *prReorderQueParm = NULL; + + if ((prCurrSwRfb->ucTid < CFG_RX_MAX_BA_TID_NUM) + && !fgIsBMC && fgIsHTran && + (HAL_RX_STATUS_GET_FRAME_CTL_FIELD( + prCurrSwRfb->prRxStatusGroup4) & + MASK_FRAME_TYPE) != MAC_FRAME_DATA) { + prReorderQueParm = + ((prCurrSwRfb->prStaRec-> + aprRxReorderParamRefTbl)[ + prCurrSwRfb->ucTid]); + } + + if (prReorderQueParm && + prReorderQueParm->fgIsValid) { + /* Only QoS Data frame with BA aggrement + * shall enter reordering buffer + */ + qmProcessPktWithReordering(prAdapter, + prCurrSwRfb, + prReturnedQue); + } else + qmHandleRxPackets_AOSP_1; + } else { + DBGLOG(RX, TEMP, + "Mark NULL the Packet for class error\n"); + RX_INC_CNT(&prAdapter->rRxCtrl, + RX_CLASS_ERR_DROP_COUNT); + prCurrSwRfb->eDst = RX_PKT_DESTINATION_NULL; + QUEUE_INSERT_TAIL(prReturnedQue, + (struct QUE_ENTRY *) prCurrSwRfb); + } + } else { + struct WLAN_MAC_HEADER *prWlanMacHeader; + + ASSERT(prCurrSwRfb->pvHeader); + + prWlanMacHeader = (struct WLAN_MAC_HEADER *) + prCurrSwRfb->pvHeader; + prCurrSwRfb->eDst = RX_PKT_DESTINATION_NULL; + + switch (prWlanMacHeader->u2FrameCtrl & + MASK_FRAME_TYPE) { + /* BAR frame */ + case MAC_FRAME_BLOCK_ACK_REQ: + qmProcessBarFrame(prAdapter, + prCurrSwRfb, prReturnedQue); + RX_INC_CNT(&prAdapter->rRxCtrl, + RX_BAR_DROP_COUNT); + break; + default: + DBGLOG(RX, TEMP, + "Mark NULL the Packet for non-interesting type\n"); + RX_INC_CNT(&prAdapter->rRxCtrl, + RX_NO_INTEREST_DROP_COUNT); + QUEUE_INSERT_TAIL(prReturnedQue, + (struct QUE_ENTRY *) prCurrSwRfb); + break; + } + } + + } while (prNextSwRfb); + + /* The returned list of SW_RFBs must end with a NULL pointer */ + if (QUEUE_IS_NOT_EMPTY(prReturnedQue)) + QM_TX_SET_NEXT_MSDU_INFO((struct SW_RFB *) QUEUE_GET_TAIL( + prReturnedQue), NULL); + + return (struct SW_RFB *) QUEUE_GET_HEAD(prReturnedQue); + +#else + + /* DbgPrint("QM: Enter qmHandleRxPackets()\n"); */ + return prSwRfbListHead; + +#endif + +} + +#if CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION +/*----------------------------------------------------------------------------*/ +/*! + * \brief qmDetectRxInvalidEAPOL() is used for fake EAPOL checking. + * + * \param[in] prSwRfb The RFB which is being processed. + * + * \return TRUE when we need to drop it + */ +/*----------------------------------------------------------------------------*/ +u_int8_t qmDetectRxInvalidEAPOL(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb) +{ + uint8_t *pucPkt = NULL; + uint8_t ucBssIndex; + struct BSS_INFO *prBssInfo; + uint16_t u2EtherType = 0; + u_int8_t fgDrop = FALSE; + uint16_t u2SeqCtrl, u2FrameCtrl; + uint8_t ucFragNo; + + DEBUGFUNC("qmDetectRxInvalidEAPOL"); + + ASSERT(prSwRfb); + ASSERT(prSwRfb->prStaRec); + + /* return FALSE if no Header Translation*/ + if (prSwRfb->fgHdrTran == FALSE) + return FALSE; + + if (prSwRfb->u2PacketLen <= ETHER_HEADER_LEN) + return FALSE; + + pucPkt = prSwRfb->pvHeader; + if (!pucPkt) + return FALSE; + + ucBssIndex = prSwRfb->prStaRec->ucBssIndex; + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + + /* return FALSE if OP_MODE is not SAP */ + if (!IS_BSS_ACTIVE(prBssInfo) + || prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) + return FALSE; + + /* return FALSE for this frame is a mid/last fragment*/ + u2FrameCtrl = HAL_RX_STATUS_GET_FRAME_CTL_FIELD( + prSwRfb->prRxStatusGroup4); + u2SeqCtrl = HAL_RX_STATUS_GET_SEQFrag_NUM(prSwRfb->prRxStatusGroup4); + ucFragNo = (uint8_t) (u2SeqCtrl & MASK_SC_FRAG_NUM); + if (prSwRfb->fgFragFrame && ucFragNo != 0) + return FALSE; + + u2EtherType = (pucPkt[ETH_TYPE_LEN_OFFSET] << 8) + | (pucPkt[ETH_TYPE_LEN_OFFSET + 1]); + + /* return FALSE if EtherType is not EAPOL */ + if (u2EtherType != ETH_P_1X) + return FALSE; + + if ((prSwRfb->eDst + == RX_PKT_DESTINATION_HOST_WITH_FORWARD + || prSwRfb->eDst == RX_PKT_DESTINATION_FORWARD)) { + /* fgIsTxKeyReady is set by nicEventAddPkeyDone */ + if (prSwRfb->prStaRec->fgIsTxKeyReady != TRUE) + fgDrop = TRUE; + } + + DBGLOG(QM, TRACE, + "QM: eDst:%d TxKeyReady:%d fgDrop:%d", + prSwRfb->eDst, prSwRfb->prStaRec->fgIsTxKeyReady, + fgDrop); + + return fgDrop; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief AMSDU Attack Detection + * + * \param[in] prSwRfb The RX packet to process + * + * \return TRUE when we find an amsdu attack + */ +/*----------------------------------------------------------------------------*/ +u_int8_t qmAmsduAttackDetection(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb) +{ + u_int8_t fgDrop = FALSE; + uint8_t aucTaAddr[MAC_ADDR_LEN]; + uint8_t *pucTaAddr = NULL, *pucRaAddr = NULL; + uint8_t *pucSaAddr = NULL, *pucDaAddr = NULL; + uint8_t *pucAmsduAddr = NULL, *pucCmpAddr = NULL; + uint8_t ucBssIndex = 0; + struct BSS_INFO *prBssInfo = NULL; + struct STA_RECORD *prStaRec = NULL; + uint16_t u2FrameCtrl, u2SSN; + struct WLAN_MAC_HEADER *prWlanHeader = NULL; + uint8_t ucTid; + uint8_t *pucPaylod = NULL; + + DEBUGFUNC("qmAmsduAttackDetection"); + + ASSERT(prSwRfb); + + prStaRec = prSwRfb->prStaRec; + ASSERT(prStaRec); + + /* 802.11 header TA */ + if (prSwRfb->fgHdrTran) { + u2SSN = HAL_RX_STATUS_GET_SEQFrag_NUM( + prSwRfb->prRxStatusGroup4) >> RX_STATUS_SEQ_NUM_OFFSET; + u2FrameCtrl = HAL_RX_STATUS_GET_FRAME_CTL_FIELD( + prSwRfb->prRxStatusGroup4); + HAL_RX_STATUS_GET_TA(prSwRfb->prRxStatusGroup4, aucTaAddr); + pucTaAddr = &aucTaAddr[0]; + pucPaylod = prSwRfb->pvHeader; + } else { + prWlanHeader = (struct WLAN_MAC_HEADER *) prSwRfb->pvHeader; + u2SSN = prWlanHeader->u2SeqCtrl >> MASK_SC_SEQ_NUM_OFFSET; + u2FrameCtrl = prWlanHeader->u2FrameCtrl; + pucTaAddr = prWlanHeader->aucAddr2; + pucPaylod = prSwRfb->pvHeader + prSwRfb->u2HeaderLen; + } + + /* 802.11 header RA */ + ucBssIndex = prSwRfb->prStaRec->ucBssIndex; + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + pucRaAddr = &prBssInfo->aucOwnMacAddr[0]; + + /* DA and SA */ + pucDaAddr = pucPaylod; + pucSaAddr = pucPaylod + MAC_ADDR_LEN; + + if (RXM_IS_QOS_DATA_FRAME(u2FrameCtrl)) { + ucTid = prSwRfb->ucTid; + } else { + /* for non-qos data, use TID_NUM as tid */ + ucTid = TID_NUM; + } + + if (prSwRfb->ucPayloadFormat == RX_PAYLOAD_FORMAT_MSDU) { + return FALSE; + } else if (prSwRfb->ucPayloadFormat + == RX_PAYLOAD_FORMAT_FIRST_SUB_AMSDU) { + if (RXM_IS_FROM_DS(u2FrameCtrl)) { + /* + * FromDS frames: + * A-MSDU DA must match 802.11 header RA + */ + pucCmpAddr = pucDaAddr; + pucAmsduAddr = pucRaAddr; + } else if (RXM_IS_TO_DS(u2FrameCtrl)) { + /* + * ToDS frames: + * A-MSDU SA must match 802.11 header TA + */ + pucCmpAddr = pucSaAddr; + pucAmsduAddr = pucTaAddr; + } + + /* mark to drop amsdu with same SeqNo */ + if (prSwRfb->fgIsFirstSubAMSDULLCMS) { + fgDrop = TRUE; + DBGLOG(QM, TRACE, + "QM: AMSDU Attack LLC Mismatch."); + } else { + if (prSwRfb->fgHdrTran) { + if (prSwRfb->u2PacketLen <= ETH_HLEN) + fgDrop = TRUE; + } else { + if (prSwRfb->u2PacketLen + <= prSwRfb->u2HeaderLen + ETH_HLEN) + fgDrop = TRUE; + } + + if (fgDrop == TRUE) + DBGLOG(QM, TRACE, + "QM: AMSDU Attack Unexpected HLen."); + } + + if (fgDrop == FALSE && + pucCmpAddr != NULL && pucAmsduAddr != NULL) { + if (UNEQUAL_MAC_ADDR(pucCmpAddr, pucAmsduAddr)) + fgDrop = TRUE; + +#define __STR_FMT__ \ + "QM: FromDS:%d ToDS:%d TID:%u SN:%u PF:%u" \ + " TA:" MACSTR " RA:" MACSTR " DA:" MACSTR " SA:" MACSTR " Drop:%d" + DBGLOG(QM, TRACE, + __STR_FMT__, + RXM_IS_FROM_DS(u2FrameCtrl), + RXM_IS_TO_DS(u2FrameCtrl), + ucTid, prSwRfb->u2SSN, + prSwRfb->ucPayloadFormat, + MAC2STR(pucTaAddr), MAC2STR(pucRaAddr), + MAC2STR(pucDaAddr), MAC2STR(pucSaAddr), + fgDrop + ); +#undef __STR_FMT__ + } + + prStaRec->afgIsAmsduInvalid[ucTid] = fgDrop; + prStaRec->au2AmsduInvalidSN[ucTid] = u2SSN; + } else { + /* drop it if find an asmdu attack in station record */ + if (prStaRec->afgIsAmsduInvalid[ucTid] == TRUE + && prStaRec->au2AmsduInvalidSN[ucTid] == u2SSN) { + fgDrop = TRUE; + DBGLOG(QM, TRACE, + "QM: AMSDU Attack TID:%u SN:%u PF:%u", + ucTid, prSwRfb->u2SSN, + prSwRfb->ucPayloadFormat); + } + + /* reset flag when find last subframe */ + if (prSwRfb->ucPayloadFormat + == RX_PAYLOAD_FORMAT_LAST_SUB_AMSDU) { + prStaRec->afgIsAmsduInvalid[ucTid] = FALSE; + prStaRec->au2AmsduInvalidSN[ucTid] = 0XFFFF; + } + } + + return fgDrop; +} +#endif /* CFG_SUPPORT_FRAG_AGG_ATTACK_DETECTION */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Reorder the received packet + * + * \param[in] prSwRfb The RX packet to process + * \param[out] prReturnedQue The queue for indicating packets + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void qmProcessPktWithReordering(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, + OUT struct QUE *prReturnedQue) +{ + + struct STA_RECORD *prStaRec; + struct RX_BA_ENTRY *prReorderQueParm; + +#if CFG_SUPPORT_RX_AMSDU + uint8_t u8AmsduSubframeIdx; + uint32_t u4SeqNo; +#endif + DEBUGFUNC("qmProcessPktWithReordering"); + + ASSERT(prSwRfb); + ASSERT(prReturnedQue); + + /* We should have STA_REC here */ + prStaRec = prSwRfb->prStaRec; + ASSERT(prStaRec); + ASSERT(prSwRfb->ucTid < CFG_RX_MAX_BA_TID_NUM); + + if (prSwRfb->ucTid >= CFG_RX_MAX_BA_TID_NUM) { + DBGLOG(QM, WARN, "TID from RXD = %d, out of range!!\n", + prSwRfb->ucTid); + DBGLOG_MEM8(QM, ERROR, prSwRfb->pucRecvBuff, + prSwRfb->u2RxByteCount); + prSwRfb->eDst = RX_PKT_DESTINATION_NULL; + QUEUE_INSERT_TAIL(prReturnedQue, + (struct QUE_ENTRY *) prSwRfb); + return; + } + + /* Check whether the BA agreement exists */ + prReorderQueParm = (( + prStaRec->aprRxReorderParamRefTbl)[prSwRfb->ucTid]); + if (!prReorderQueParm || !(prReorderQueParm->fgIsValid)) { + DBGLOG(RX, TEMP, + "Reordering but no BA agreement for STA[%d] TID[%d]\n", + prStaRec->ucIndex, prSwRfb->ucTid); + QUEUE_INSERT_TAIL(prReturnedQue, + (struct QUE_ENTRY *) prSwRfb); + return; + } + + RX_INC_CNT(&prAdapter->rRxCtrl, + RX_DATA_REORDER_TOTAL_COUNT); + + prSwRfb->u2SSN = HAL_RX_STATUS_GET_SEQFrag_NUM( + prSwRfb->prRxStatusGroup4) >> RX_STATUS_SEQ_NUM_OFFSET; + +#if CFG_SUPPORT_RX_AMSDU + /* RX reorder for one MSDU in AMSDU issue */ + /* QUEUE_INITIALIZE(&prSwRfb->rAmsduQue); */ + + u8AmsduSubframeIdx = prSwRfb->ucPayloadFormat; + + /* prMpduSwRfb = prReorderQueParm->prMpduSwRfb; */ + u4SeqNo = (uint32_t)prSwRfb->u2SSN; + + switch (u8AmsduSubframeIdx) { + case RX_PAYLOAD_FORMAT_FIRST_SUB_AMSDU: + if (prReorderQueParm->fgAmsduNeedLastFrame) { + RX_INC_CNT(&prAdapter->rRxCtrl, + RX_DATA_AMSDU_MISS_COUNT); + prReorderQueParm->fgAmsduNeedLastFrame = FALSE; + } + RX_INC_CNT(&prAdapter->rRxCtrl, + RX_DATA_MSDU_IN_AMSDU_COUNT); + RX_INC_CNT(&prAdapter->rRxCtrl, RX_DATA_AMSDU_COUNT); + break; + + case RX_PAYLOAD_FORMAT_MIDDLE_SUB_AMSDU: + prReorderQueParm->fgAmsduNeedLastFrame = TRUE; + RX_INC_CNT(&prAdapter->rRxCtrl, + RX_DATA_MSDU_IN_AMSDU_COUNT); + if (prReorderQueParm->u4SeqNo != u4SeqNo) { + RX_INC_CNT(&prAdapter->rRxCtrl, + RX_DATA_AMSDU_MISS_COUNT); + RX_INC_CNT(&prAdapter->rRxCtrl, + RX_DATA_AMSDU_COUNT); + } + break; + case RX_PAYLOAD_FORMAT_LAST_SUB_AMSDU: + prReorderQueParm->fgAmsduNeedLastFrame = FALSE; + RX_INC_CNT(&prAdapter->rRxCtrl, + RX_DATA_MSDU_IN_AMSDU_COUNT); + if (prReorderQueParm->u4SeqNo != u4SeqNo) { + RX_INC_CNT(&prAdapter->rRxCtrl, + RX_DATA_AMSDU_MISS_COUNT); + RX_INC_CNT(&prAdapter->rRxCtrl, + RX_DATA_AMSDU_COUNT); + } + break; + + case RX_PAYLOAD_FORMAT_MSDU: + if (prReorderQueParm->fgAmsduNeedLastFrame) { + RX_INC_CNT(&prAdapter->rRxCtrl, + RX_DATA_AMSDU_MISS_COUNT); + prReorderQueParm->fgAmsduNeedLastFrame = FALSE; + } + break; + default: + break; + } + + prReorderQueParm->u4SeqNo = u4SeqNo; +#endif + + RX_DIRECT_REORDER_LOCK(prAdapter, 0); + /* Insert reorder packet */ + qmInsertReorderPkt(prAdapter, prSwRfb, prReorderQueParm, + prReturnedQue); + RX_DIRECT_REORDER_UNLOCK(prAdapter, 0); +} + +void qmProcessBarFrame(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, OUT struct QUE *prReturnedQue) +{ + + struct STA_RECORD *prStaRec; + struct RX_BA_ENTRY *prReorderQueParm; + struct CTRL_BAR_FRAME *prBarCtrlFrame; + + uint32_t u4SSN; + uint32_t u4WinStart; + uint32_t u4WinEnd; + + ASSERT(prSwRfb); + ASSERT(prReturnedQue); + ASSERT(prSwRfb->pvHeader); + + prBarCtrlFrame = (struct CTRL_BAR_FRAME *) prSwRfb->pvHeader; + + prSwRfb->ucTid = + (*((uint16_t *) ((uint8_t *) prBarCtrlFrame + + CTRL_BAR_BAR_CONTROL_OFFSET))) >> + BAR_CONTROL_TID_INFO_OFFSET; + prSwRfb->u2SSN = + (*((uint16_t *) ((uint8_t *) prBarCtrlFrame + + CTRL_BAR_BAR_INFORMATION_OFFSET))) >> + OFFSET_BAR_SSC_SN; + + prSwRfb->eDst = RX_PKT_DESTINATION_NULL; + QUEUE_INSERT_TAIL(prReturnedQue, (struct QUE_ENTRY *) prSwRfb); + + /* Incorrect STA_REC index */ + prSwRfb->ucStaRecIdx = secLookupStaRecIndexFromTA(prAdapter, + prBarCtrlFrame->aucSrcAddr); + if (prSwRfb->ucStaRecIdx >= CFG_STA_REC_NUM) { + DBGLOG(QM, WARN, + "QM: (Warning) BAR for a NULL STA_REC, ucStaRecIdx = %d\n", + prSwRfb->ucStaRecIdx); + /* ASSERT(0); */ + return; + } + + /* Check whether the STA_REC is activated */ + prSwRfb->prStaRec = cnmGetStaRecByIndex(prAdapter, + prSwRfb->ucStaRecIdx); + prStaRec = prSwRfb->prStaRec; + if (prStaRec == NULL) { + /* ASSERT(prStaRec); */ + return; + } +#if 0 + if (!(prStaRec->fgIsValid)) { + /* TODO: (Tehuang) Handle the Host-FW sync issue. */ + DbgPrint("QM: (Warning) BAR for an invalid STA_REC\n"); + /* ASSERT(0); */ + return; + } +#endif + + /* Check whether the BA agreement exists */ + prReorderQueParm = prStaRec->aprRxReorderParamRefTbl[prSwRfb->ucTid]; + if (!prReorderQueParm) { + /* TODO: (Tehuang) Handle the Host-FW sync issue. */ + DBGLOG(QM, WARN, + "QM: (Warning) BAR for a NULL ReorderQueParm\n"); + /* ASSERT(0); */ + return; + } + + RX_DIRECT_REORDER_LOCK(prAdapter, 0); + + u4SSN = (uint32_t) (prSwRfb->u2SSN); + u4WinStart = (uint32_t) (prReorderQueParm->u2WinStart); + u4WinEnd = (uint32_t) (prReorderQueParm->u2WinEnd); + + if (qmCompareSnIsLessThan(u4WinStart, u4SSN)) { + prReorderQueParm->u2WinStart = (uint16_t) u4SSN; + prReorderQueParm->u2WinEnd = + ((prReorderQueParm->u2WinStart) + + (prReorderQueParm->u2WinSize) - 1) % MAX_SEQ_NO_COUNT; +#if CFG_SUPPORT_RX_AMSDU + /* RX reorder for one MSDU in AMSDU issue */ + prReorderQueParm->u8LastAmsduSubIdx = RX_PAYLOAD_FORMAT_MSDU; +#endif + DBGLOG(RX, TEMP, + "QM:(BAR)[%d](%u){%hu,%hu}\n", + prSwRfb->ucTid, u4SSN, + prReorderQueParm->u2WinStart, + prReorderQueParm->u2WinEnd); + qmPopOutDueToFallAhead(prAdapter, prReorderQueParm, + prReturnedQue); + } else { + DBGLOG(RX, TEMP, "QM:(BAR)(%d)(%u){%u,%u}\n", + prSwRfb->ucTid, u4SSN, u4WinStart, u4WinEnd); + } + RX_DIRECT_REORDER_UNLOCK(prAdapter, 0); +} + +void qmInsertReorderPkt(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, + IN struct RX_BA_ENTRY *prReorderQueParm, + OUT struct QUE *prReturnedQue) +{ + uint32_t u4SeqNo; + uint32_t u4WinStart; + uint32_t u4WinEnd; + + /* Start to reorder packets */ + u4SeqNo = (uint32_t) (prSwRfb->u2SSN); + u4WinStart = (uint32_t) (prReorderQueParm->u2WinStart); + u4WinEnd = (uint32_t) (prReorderQueParm->u2WinEnd); + + /* Debug */ + DBGLOG(RX, TEMP, "QM:ipid=%d(R)[%u](%u){%u,%u}\n", + GLUE_GET_PKT_IP_ID(prSwRfb->pvPacket), prSwRfb->ucTid, + u4SeqNo, u4WinStart, u4WinEnd); + + if (prReorderQueParm->fgNoDrop) { + if (!qmCompareSnIsLessThan(u4SeqNo, + prReorderQueParm->u2WinStart)) { + /* Fall behind SSN pkts started to Fall within + * StartWin + */ + prReorderQueParm->u4SNOverlapCount++; + if (prReorderQueParm->u4SNOverlapCount > 10) { + /* Set threshold as 10 to make sure + * the SSN is really falling within StartWin + */ + prReorderQueParm->u4SNOverlapCount = 0; + prReorderQueParm->fgNoDrop = FALSE; + DBGLOG(QM, INFO, "NO drop = FALSE, [%d][%d]\n", + u4SeqNo, prReorderQueParm->u2WinStart); + } + } + } + /* Case 1: Fall within */ + if /* 0 - start - sn - end - 4095 */ + (((u4WinStart <= u4SeqNo) && (u4SeqNo <= u4WinEnd)) + /* 0 - end - start - sn - 4095 */ + || ((u4WinEnd < u4WinStart) && (u4WinStart <= u4SeqNo)) + /* 0 - sn - end - start - 4095 */ + || ((u4SeqNo <= u4WinEnd) && (u4WinEnd < u4WinStart))) { + DBGLOG(RX, TEMP, "RxPkt=%p seq=%d fall within\n", + prSwRfb, u4SeqNo); + + qmInsertFallWithinReorderPkt(prAdapter, prSwRfb, + prReorderQueParm, prReturnedQue); + +#if QM_RX_WIN_SSN_AUTO_ADVANCING + if (prReorderQueParm->fgIsWaitingForPktWithSsn) { + /* Let the first received packet + * pass the reorder check + */ + DBGLOG(RX, TEMP, "QM:(A)[%d](%u){%u,%u}\n", + prSwRfb->ucTid, u4SeqNo, u4WinStart, u4WinEnd); + + prReorderQueParm->u2WinStart = (uint16_t) u4SeqNo; + prReorderQueParm->u2WinEnd = + ((prReorderQueParm->u2WinStart) + + (prReorderQueParm->u2WinSize) - 1) % + MAX_SEQ_NO_COUNT; + prReorderQueParm->fgIsWaitingForPktWithSsn = FALSE; +#if CFG_SUPPORT_RX_AMSDU + /* RX reorder for one MSDU in AMSDU issue */ + prReorderQueParm->u8LastAmsduSubIdx = + RX_PAYLOAD_FORMAT_MSDU; +#endif + } +#endif + + qmPopOutDueToFallWithin(prAdapter, prReorderQueParm, + prReturnedQue); + } + /* Case 2: Fall ahead */ + else if + /* 0 - start - end - sn - (start+2048) - 4095 */ + (((u4WinStart < u4WinEnd) && (u4WinEnd < u4SeqNo) && + (u4SeqNo < (u4WinStart + HALF_SEQ_NO_COUNT))) + /* 0 - sn - (start+2048) - start - end - 4095 */ + || ((u4SeqNo < u4WinStart) && (u4WinStart < u4WinEnd) && + ((u4SeqNo + MAX_SEQ_NO_COUNT) < + (u4WinStart + HALF_SEQ_NO_COUNT))) + /* 0 - end - sn - (start+2048) - start - 4095 */ + || ((u4WinEnd < u4SeqNo) && (u4SeqNo < u4WinStart) && + ((u4SeqNo + MAX_SEQ_NO_COUNT) < (u4WinStart + + HALF_SEQ_NO_COUNT)))) { + + uint16_t u2Delta, u2BeforeWinEnd; + uint32_t u4BeforeCount, u4MissingCount; + + DBGLOG(RX, TEMP, "RxPkt=%p seq=%d fall ahead\n", + prSwRfb, u4SeqNo); + +#if QM_RX_WIN_SSN_AUTO_ADVANCING + if (prReorderQueParm->fgIsWaitingForPktWithSsn) + prReorderQueParm->fgIsWaitingForPktWithSsn = FALSE; +#endif + + qmInsertFallAheadReorderPkt(prAdapter, prSwRfb, + prReorderQueParm, prReturnedQue); + + u2BeforeWinEnd = prReorderQueParm->u2WinEnd; + + /* Advance the window after inserting a new tail */ + prReorderQueParm->u2WinEnd = (uint16_t) u4SeqNo; + prReorderQueParm->u2WinStart = + (((prReorderQueParm->u2WinEnd) + MAX_SEQ_NO_COUNT - + prReorderQueParm->u2WinSize + 1) % + MAX_SEQ_NO_COUNT); +#if CFG_SUPPORT_RX_AMSDU + /* RX reorder for one MSDU in AMSDU issue */ + prReorderQueParm->u8LastAmsduSubIdx = + RX_PAYLOAD_FORMAT_MSDU; +#endif + u4BeforeCount = prReorderQueParm->rReOrderQue.u4NumElem; + qmPopOutDueToFallAhead(prAdapter, prReorderQueParm, + prReturnedQue); + + if (prReorderQueParm->u2WinEnd >= u2BeforeWinEnd) + u2Delta = prReorderQueParm->u2WinEnd - u2BeforeWinEnd; + else + u2Delta = MAX_SEQ_NO_COUNT - (u2BeforeWinEnd - + prReorderQueParm->u2WinEnd); + + u4MissingCount = u2Delta - (u4BeforeCount - + prReorderQueParm->rReOrderQue.u4NumElem); + + RX_ADD_CNT(&prAdapter->rRxCtrl, RX_DATA_REORDER_MISS_COUNT, + u4MissingCount); + /* If the SSN jump over 1024, + * we consider it as an abnormal jump and + * temporally reserve the fall behind packets until + * the pkt SSN is really falling within StartWin + */ + if (u2Delta > QUARTER_SEQ_NO_COUNT) { + prReorderQueParm->fgNoDrop = TRUE; + prReorderQueParm->u4SNOverlapCount = 0; + DBGLOG_LIMITED(QM, INFO, + "QM: SSN jump over 1024:[%d]\n", u2Delta); + } + DBGLOG(RX, TEMP, "QM: Miss Count:[%lu]\n", + RX_GET_CNT(&prAdapter->rRxCtrl, + RX_DATA_REORDER_MISS_COUNT)); + } + /* Case 3: Fall behind */ + else { +#if CFG_SUPPORT_LOWLATENCY_MODE || CFG_SUPPORT_OSHARE + if (qmIsNoDropPacket(prAdapter, prSwRfb) || + prReorderQueParm->fgNoDrop) { + qmPopOutReorderPkt(prAdapter, prSwRfb, + prReturnedQue, RX_DATA_REORDER_BEHIND_COUNT); + DBGLOG(RX, TEMP, + "QM: No drop packet:[%d](%d){%d,%d} total:%lu\n", + prSwRfb->ucTid, u4SeqNo, u4WinStart, u4WinEnd, + RX_GET_CNT(&prAdapter->rRxCtrl, + RX_DATA_REORDER_BEHIND_COUNT)); + return; + } +#endif /* CFG_SUPPORT_LOWLATENCY_MODE */ + +#if QM_RX_WIN_SSN_AUTO_ADVANCING && QM_RX_INIT_FALL_BEHIND_PASS + if (prReorderQueParm->fgIsWaitingForPktWithSsn) { + qmPopOutReorderPkt(prAdapter, prSwRfb, prReturnedQue, + RX_DATA_REORDER_BEHIND_COUNT); + DBGLOG(RX, TEMP, "QM:(P)[%u](%u){%u,%u} total:%lu\n", + prSwRfb->ucTid, u4SeqNo, u4WinStart, u4WinEnd, + RX_GET_CNT(&prAdapter->rRxCtrl, + RX_DATA_REORDER_BEHIND_COUNT)); + return; + } +#endif + + /* An erroneous packet */ + prSwRfb->eDst = RX_PKT_DESTINATION_NULL; + qmPopOutReorderPkt(prAdapter, prSwRfb, prReturnedQue, + RX_REORDER_BEHIND_DROP_COUNT); + DBGLOG(RX, TEMP, "QM:(D)[%u](%u){%u,%u} total:%lu\n", + prSwRfb->ucTid, u4SeqNo, u4WinStart, u4WinEnd, + RX_GET_CNT(&prAdapter->rRxCtrl, + RX_REORDER_BEHIND_DROP_COUNT)); + return; + } +} + +void qmInsertFallWithinReorderPkt(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, + IN struct RX_BA_ENTRY *prReorderQueParm, + OUT struct QUE *prReturnedQue) +{ + struct SW_RFB *prExaminedQueuedSwRfb; + struct QUE *prReorderQue; + uint8_t u8AmsduSubframeIdx; /* RX reorder for one MSDU in AMSDU issue */ + + ASSERT(prSwRfb); + ASSERT(prReorderQueParm); + ASSERT(prReturnedQue); + + prReorderQue = &(prReorderQueParm->rReOrderQue); + prExaminedQueuedSwRfb = (struct SW_RFB *) QUEUE_GET_HEAD( + prReorderQue); + + u8AmsduSubframeIdx = prSwRfb->ucPayloadFormat; + + /* There are no packets queued in the Reorder Queue */ + if (prExaminedQueuedSwRfb == NULL) { + ((struct QUE_ENTRY *) prSwRfb)->prPrev = NULL; + ((struct QUE_ENTRY *) prSwRfb)->prNext = NULL; + prReorderQue->prHead = (struct QUE_ENTRY *) prSwRfb; + prReorderQue->prTail = (struct QUE_ENTRY *) prSwRfb; + prReorderQue->u4NumElem++; + } + + /* Determine the insert position */ + else { + do { + /* Case 1: Terminate. A duplicate packet */ + if ((prExaminedQueuedSwRfb->u2SSN) == + (prSwRfb->u2SSN)) { +#if CFG_SUPPORT_RX_AMSDU + /* RX reorder for one MSDU in AMSDU issue */ + /* if middle or last and first is not + * duplicated, not a duplicat packet + */ + if (!prReorderQueParm->fgIsAmsduDuplicated && + (u8AmsduSubframeIdx == + RX_PAYLOAD_FORMAT_MIDDLE_SUB_AMSDU || + u8AmsduSubframeIdx == + RX_PAYLOAD_FORMAT_LAST_SUB_AMSDU)) { + + prExaminedQueuedSwRfb = + (struct SW_RFB *)(( + (struct QUE_ENTRY *) + prExaminedQueuedSwRfb)->prNext); + while (prExaminedQueuedSwRfb && + ((prExaminedQueuedSwRfb-> + u2SSN) == (prSwRfb->u2SSN))) + prExaminedQueuedSwRfb = + (struct SW_RFB *)(( + (struct QUE_ENTRY *) + prExaminedQueuedSwRfb)-> + prNext); + + break; + } + /* if first is duplicated, + * drop subsequent middle and last frames + */ + if (u8AmsduSubframeIdx == + RX_PAYLOAD_FORMAT_FIRST_SUB_AMSDU) + prReorderQueParm->fgIsAmsduDuplicated = + TRUE; +#endif + prSwRfb->eDst = RX_PKT_DESTINATION_NULL; + qmPopOutReorderPkt(prAdapter, + prSwRfb, prReturnedQue, + RX_DUPICATE_DROP_COUNT); + DBGLOG(RX, TEMP, + "seq=%d dup drop total:%lu\n", + prSwRfb->u2SSN, + RX_GET_CNT(&prAdapter->rRxCtrl, + RX_DUPICATE_DROP_COUNT)); + LINK_QUALITY_COUNT_DUP(prAdapter, prSwRfb); + return; + } + + /* Case 2: Terminate. The insert point is found */ + else if (qmCompareSnIsLessThan((prSwRfb->u2SSN), + (prExaminedQueuedSwRfb->u2SSN))) + break; + + /* Case 3: Insert point not found. + * Check the next SW_RFB in the Reorder Queue + */ + else + prExaminedQueuedSwRfb = + (struct SW_RFB *) (((struct QUE_ENTRY *) + prExaminedQueuedSwRfb)->prNext); + } while (prExaminedQueuedSwRfb); +#if CFG_SUPPORT_RX_AMSDU + prReorderQueParm->fgIsAmsduDuplicated = FALSE; +#endif + /* Update the Reorder Queue Parameters according to + * the found insert position + */ + if (prExaminedQueuedSwRfb == NULL) { + /* The received packet shall be placed at the tail */ + ((struct QUE_ENTRY *) prSwRfb)->prPrev = + prReorderQue->prTail; + ((struct QUE_ENTRY *) prSwRfb)->prNext = NULL; + (prReorderQue->prTail)->prNext = + (struct QUE_ENTRY *) (prSwRfb); + prReorderQue->prTail = (struct QUE_ENTRY *) (prSwRfb); + } else { + ((struct QUE_ENTRY *) prSwRfb)->prPrev = + ((struct QUE_ENTRY *) + prExaminedQueuedSwRfb)->prPrev; + ((struct QUE_ENTRY *) prSwRfb)->prNext = + (struct QUE_ENTRY *) prExaminedQueuedSwRfb; + if (((struct QUE_ENTRY *) prExaminedQueuedSwRfb) == + (prReorderQue->prHead)) { + /* The received packet will become the head */ + prReorderQue->prHead = + (struct QUE_ENTRY *) prSwRfb; + } else { + (((struct QUE_ENTRY *) + prExaminedQueuedSwRfb)->prPrev)->prNext = + (struct QUE_ENTRY *) prSwRfb; + } + ((struct QUE_ENTRY *) prExaminedQueuedSwRfb)->prPrev = + (struct QUE_ENTRY *) prSwRfb; + } + + prReorderQue->u4NumElem++; + } + +} + +void qmInsertFallAheadReorderPkt(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, + IN struct RX_BA_ENTRY *prReorderQueParm, + OUT struct QUE *prReturnedQue) +{ + struct QUE *prReorderQue; + + ASSERT(prSwRfb); + ASSERT(prReorderQueParm); + ASSERT(prReturnedQue); +#if CFG_SUPPORT_RX_AMSDU + /* RX reorder for one MSDU in AMSDU issue */ + prReorderQueParm->fgIsAmsduDuplicated = FALSE; +#endif + prReorderQue = &(prReorderQueParm->rReOrderQue); + /* There are no packets queued in the Reorder Queue */ + if (QUEUE_IS_EMPTY(prReorderQue)) { + ((struct QUE_ENTRY *) prSwRfb)->prPrev = NULL; + ((struct QUE_ENTRY *) prSwRfb)->prNext = NULL; + prReorderQue->prHead = (struct QUE_ENTRY *) prSwRfb; + } else { + ((struct QUE_ENTRY *) prSwRfb)->prPrev = + prReorderQue->prTail; + ((struct QUE_ENTRY *) prSwRfb)->prNext = NULL; + (prReorderQue->prTail)->prNext = (struct QUE_ENTRY *) ( + prSwRfb); + } + prReorderQue->prTail = (struct QUE_ENTRY *) prSwRfb; + prReorderQue->u4NumElem++; +} + +void qmPopOutReorderPkt(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, OUT struct QUE *prReturnedQue, + IN enum ENUM_RX_STATISTIC_COUNTER eRxCounter) +{ + uint32_t u4PktCnt = 0; + /* RX reorder for one MSDU in AMSDU issue */ +#if 0 + struct SW_RFB *prAmsduSwRfb; +#endif + + u4PktCnt++; + QUEUE_INSERT_TAIL(prReturnedQue, + (struct QUE_ENTRY *)prSwRfb); + +#if 0 + u4PktCnt += prSwRfb->rAmsduQue.u4NumElem; + QUEUE_REMOVE_HEAD(&prSwRfb->rAmsduQue, prAmsduSwRfb, + struct SW_RFB *); + while (prAmsduSwRfb) { + /* Update MSDU destination of AMSDU */ + prAmsduSwRfb->eDst = prSwRfb->eDst; + QUEUE_INSERT_TAIL(prReturnedQue, + (struct QUE_ENTRY *)prAmsduSwRfb); + QUEUE_REMOVE_HEAD(&prSwRfb->rAmsduQue, prAmsduSwRfb, + struct SW_RFB *); + } +#endif + RX_ADD_CNT(&prAdapter->rRxCtrl, eRxCounter, u4PktCnt); +} + +void qmPopOutDueToFallWithin(IN struct ADAPTER *prAdapter, + IN struct RX_BA_ENTRY *prReorderQueParm, + OUT struct QUE *prReturnedQue) +{ + struct SW_RFB *prReorderedSwRfb; + struct QUE *prReorderQue; + u_int8_t fgDequeuHead, fgMissing; + OS_SYSTIME rCurrentTime, *prMissTimeout; + /* RX reorder for one MSDU in AMSDU issue */ + uint8_t fgIsAmsduSubframe; + + prReorderQue = &(prReorderQueParm->rReOrderQue); + + fgMissing = FALSE; + rCurrentTime = 0; + prMissTimeout = + &g_arMissTimeout[prReorderQueParm->ucStaRecIdx][ + prReorderQueParm->ucTid]; + if (*prMissTimeout) { + fgMissing = TRUE; + GET_CURRENT_SYSTIME(&rCurrentTime); + } + + /* Check whether any packet can be indicated to the higher layer */ + while (TRUE) { + if (QUEUE_IS_EMPTY(prReorderQue)) + break; + + /* Always examine the head packet */ + prReorderedSwRfb = (struct SW_RFB *) QUEUE_GET_HEAD( + prReorderQue); + fgDequeuHead = FALSE; + + /* RX reorder for one MSDU in AMSDU issue */ + fgIsAmsduSubframe = prReorderedSwRfb->ucPayloadFormat; +#if CFG_SUPPORT_RX_AMSDU + /* If SN + 1 come and last frame is first or middle, + * update winstart + */ + if ((qmCompareSnIsLessThan((prReorderQueParm->u2WinStart), + (prReorderedSwRfb->u2SSN))) + && (prReorderQueParm->u4SeqNo != + prReorderQueParm->u2WinStart)) { + if (prReorderQueParm->u8LastAmsduSubIdx == + RX_PAYLOAD_FORMAT_FIRST_SUB_AMSDU + || prReorderQueParm->u8LastAmsduSubIdx == + RX_PAYLOAD_FORMAT_MIDDLE_SUB_AMSDU) { + + prReorderQueParm->u2WinStart = + (((prReorderQueParm->u2WinStart) + 1) % + MAX_SEQ_NO_COUNT); + prReorderQueParm->u8LastAmsduSubIdx = + RX_PAYLOAD_FORMAT_MSDU; + } + } +#endif + /* SN == WinStart, so the head packet + * shall be indicated (advance the window) + */ + if ((prReorderedSwRfb->u2SSN) == + (prReorderQueParm->u2WinStart)) { + + fgDequeuHead = TRUE; + /* RX reorder for one MSDU in AMSDU issue */ + /* if last frame, winstart++. + * Otherwise, keep winstart + */ + if (fgIsAmsduSubframe == + RX_PAYLOAD_FORMAT_LAST_SUB_AMSDU + || fgIsAmsduSubframe == RX_PAYLOAD_FORMAT_MSDU) + prReorderQueParm->u2WinStart = + (((prReorderedSwRfb->u2SSN) + 1) % + MAX_SEQ_NO_COUNT); +#if CFG_SUPPORT_RX_AMSDU + prReorderQueParm->u8LastAmsduSubIdx = fgIsAmsduSubframe; +#endif + } + /* SN > WinStart, break to update WinEnd */ + else { + /* Start bubble timer */ + if (!prReorderQueParm->fgHasBubble) { + cnmTimerStartTimer(prAdapter, + &(prReorderQueParm->rReorderBubbleTimer), + prAdapter->u4QmRxBaMissTimeout); + prReorderQueParm->fgHasBubble = TRUE; + prReorderQueParm->u2FirstBubbleSn = + prReorderQueParm->u2WinStart; + + DBGLOG(RX, TEMP, + "QM:(Bub Timer) STA[%u] TID[%u] BubSN[%u] Win{%d, %d}\n", + prReorderQueParm->ucStaRecIdx, + prReorderedSwRfb->ucTid, + prReorderQueParm->u2FirstBubbleSn, + prReorderQueParm->u2WinStart, + prReorderQueParm->u2WinEnd); + } + + if (fgMissing && + CHECK_FOR_TIMEOUT(rCurrentTime, *prMissTimeout, + MSEC_TO_SYSTIME( + prAdapter->u4QmRxBaMissTimeout + ))) { + + DBGLOG(RX, TEMP, + "QM:RX BA Timout Next Tid %d SSN %d\n", + prReorderQueParm->ucTid, + prReorderedSwRfb->u2SSN); + fgDequeuHead = TRUE; + prReorderQueParm->u2WinStart = + (((prReorderedSwRfb->u2SSN) + 1) % + MAX_SEQ_NO_COUNT); +#if CFG_SUPPORT_RX_AMSDU + /* RX reorder for one MSDU in AMSDU issue */ + prReorderQueParm->u8LastAmsduSubIdx = + RX_PAYLOAD_FORMAT_MSDU; +#endif + fgMissing = FALSE; + } else + break; + } + + /* Dequeue the head packet */ + if (fgDequeuHead) { + if (((struct QUE_ENTRY *) prReorderedSwRfb)->prNext == + NULL) { + prReorderQue->prHead = NULL; + prReorderQue->prTail = NULL; + } else { + prReorderQue->prHead = + ((struct QUE_ENTRY *) + prReorderedSwRfb)->prNext; + (((struct QUE_ENTRY *) + prReorderedSwRfb)->prNext)->prPrev = + NULL; + } + prReorderQue->u4NumElem--; + qmPopOutReorderPkt(prAdapter, prReorderedSwRfb, + prReturnedQue, RX_DATA_REORDER_WITHIN_COUNT); + DBGLOG(RX, TEMP, "QM: [%d] %d (%d) within total:%lu\n", + prReorderQueParm->ucTid, + prReorderedSwRfb->u2PacketLen, + prReorderedSwRfb->u2SSN, + RX_GET_CNT(&prAdapter->rRxCtrl, + RX_DATA_REORDER_WITHIN_COUNT)); + } + } + + if (QUEUE_IS_EMPTY(prReorderQue)) + *prMissTimeout = 0; + else { + if (fgMissing == FALSE) + GET_CURRENT_SYSTIME(prMissTimeout); + } + + /* After WinStart has been determined, update the WinEnd */ + prReorderQueParm->u2WinEnd = + (((prReorderQueParm->u2WinStart) + + (prReorderQueParm->u2WinSize) - 1) % MAX_SEQ_NO_COUNT); + +} + +void qmPopOutDueToFallAhead(IN struct ADAPTER *prAdapter, + IN struct RX_BA_ENTRY *prReorderQueParm, + OUT struct QUE *prReturnedQue) +{ + struct SW_RFB *prReorderedSwRfb; + struct QUE *prReorderQue; + u_int8_t fgDequeuHead; + uint8_t fgIsAmsduSubframe;/* RX reorder for one MSDU in AMSDU issue */ + + prReorderQue = &(prReorderQueParm->rReOrderQue); + + /* Check whether any packet can be indicated to the higher layer */ + while (TRUE) { + if (QUEUE_IS_EMPTY(prReorderQue)) + break; + + /* Always examine the head packet */ + prReorderedSwRfb = + (struct SW_RFB *) QUEUE_GET_HEAD(prReorderQue); + fgDequeuHead = FALSE; + + /* RX reorder for one MSDU in AMSDU issue */ + fgIsAmsduSubframe = prReorderedSwRfb->ucPayloadFormat; +#if CFG_SUPPORT_RX_AMSDU + /* If SN + 1 come and last frame is first or middle, + * update winstart + */ + if ((qmCompareSnIsLessThan((prReorderQueParm->u2WinStart), + (prReorderedSwRfb->u2SSN))) + && (prReorderQueParm->u4SeqNo != + prReorderQueParm->u2WinStart)) { + if (prReorderQueParm->u8LastAmsduSubIdx == + RX_PAYLOAD_FORMAT_FIRST_SUB_AMSDU + || prReorderQueParm->u8LastAmsduSubIdx == + RX_PAYLOAD_FORMAT_MIDDLE_SUB_AMSDU) { + + prReorderQueParm->u2WinStart = + (((prReorderQueParm->u2WinStart) + 1) % + MAX_SEQ_NO_COUNT); + prReorderQueParm->u8LastAmsduSubIdx = + RX_PAYLOAD_FORMAT_MSDU; + } + } +#endif + /* SN == WinStart, so the head packet shall be + * indicated (advance the window) + */ + if ((prReorderedSwRfb->u2SSN) == + (prReorderQueParm->u2WinStart)) { + + fgDequeuHead = TRUE; + /* RX reorder for one MSDU in AMSDU issue */ + /* if last frame, winstart++. + * Otherwise, keep winstart + */ + if (fgIsAmsduSubframe == + RX_PAYLOAD_FORMAT_LAST_SUB_AMSDU || + fgIsAmsduSubframe == RX_PAYLOAD_FORMAT_MSDU) + prReorderQueParm->u2WinStart = + (((prReorderedSwRfb->u2SSN) + 1) % + MAX_SEQ_NO_COUNT); +#if CFG_SUPPORT_RX_AMSDU + prReorderQueParm->u8LastAmsduSubIdx = fgIsAmsduSubframe; +#endif + } + + /* SN < WinStart, so the head packet shall be + * indicated (do not advance the window) + */ + else if (qmCompareSnIsLessThan((uint32_t)( + prReorderedSwRfb->u2SSN), + (uint32_t)(prReorderQueParm->u2WinStart))) + fgDequeuHead = TRUE; + + /* SN > WinStart, break to update WinEnd */ + else { + /* Start bubble timer */ + if (!prReorderQueParm->fgHasBubble) { + cnmTimerStartTimer(prAdapter, + &(prReorderQueParm-> + rReorderBubbleTimer), + prAdapter->u4QmRxBaMissTimeout); + prReorderQueParm->fgHasBubble = TRUE; + prReorderQueParm->u2FirstBubbleSn = + prReorderQueParm->u2WinStart; + + DBGLOG(RX, TEMP, + "QM:(Bub Timer) STA[%u] TID[%u] BubSN[%u] Win{%d, %d}\n", + prReorderQueParm->ucStaRecIdx, + prReorderedSwRfb->ucTid, + prReorderQueParm->u2FirstBubbleSn, + prReorderQueParm->u2WinStart, + prReorderQueParm->u2WinEnd); + } + break; + } + + /* Dequeue the head packet */ + if (fgDequeuHead) { + if (((struct QUE_ENTRY *) prReorderedSwRfb)->prNext == + NULL) { + prReorderQue->prHead = NULL; + prReorderQue->prTail = NULL; + } else { + prReorderQue->prHead = ((struct QUE_ENTRY *) + prReorderedSwRfb)->prNext; + (((struct QUE_ENTRY *) prReorderedSwRfb)-> + prNext)->prPrev = NULL; + } + prReorderQue->u4NumElem--; + qmPopOutReorderPkt(prAdapter, prReorderedSwRfb, + prReturnedQue, RX_DATA_REORDER_AHEAD_COUNT); + DBGLOG(RX, TEMP, "QM: [%u] %u (%u) ahead total:%lu\n", + prReorderQueParm->ucTid, + prReorderedSwRfb->u2PacketLen, + prReorderedSwRfb->u2SSN, + RX_GET_CNT(&prAdapter->rRxCtrl, + RX_DATA_REORDER_WITHIN_COUNT)); + } + } + + /* After WinStart has been determined, update the WinEnd */ + prReorderQueParm->u2WinEnd = + (((prReorderQueParm->u2WinStart) + + (prReorderQueParm->u2WinSize) - 1) % MAX_SEQ_NO_COUNT); + +} + +void qmHandleReorderBubbleTimeout(IN struct ADAPTER *prAdapter, + IN unsigned long ulParamPtr) +{ + struct RX_BA_ENTRY *prReorderQueParm = + (struct RX_BA_ENTRY *) ulParamPtr; + + ASSERT(prAdapter); + + if (!prReorderQueParm->fgIsValid) { + DBGLOG(QM, TRACE, + "QM:(Bub Check Cancel) STA[%u] TID[%u], No Rx BA entry\n", + prReorderQueParm->ucStaRecIdx, prReorderQueParm->ucTid); + return; + } + + if (!prReorderQueParm->fgHasBubble) { + DBGLOG(QM, TRACE, + "QM:(Bub Check Cancel) STA[%u] TID[%u], Bubble has been filled\n", + prReorderQueParm->ucStaRecIdx, prReorderQueParm->ucTid); + return; + } + + DBGLOG(QM, TRACE, + "QM:(Bub Timeout) STA[%u] TID[%u] BubSN[%u]\n", + prReorderQueParm->ucStaRecIdx, prReorderQueParm->ucTid, + prReorderQueParm->u2FirstBubbleSn); + + qmHandleEventCheckReorderBubble(prAdapter, prReorderQueParm); +} + +void qmHandleEventCheckReorderBubble(IN struct ADAPTER *prAdapter, + struct RX_BA_ENTRY *prReorderQueParm) +{ + struct QUE *prReorderQue; + struct QUE rReturnedQue; + struct QUE *prReturnedQue = &rReturnedQue; + struct SW_RFB *prReorderedSwRfb, *prSwRfb; + OS_SYSTIME *prMissTimeout; + + QUEUE_INITIALIZE(prReturnedQue); + + /* Sanity Check */ + if (!prReorderQueParm) { + DBGLOG(QM, TRACE, "QM:(Bub Check Cancel) No Rx BA entry\n"); + return; + } + + if (!prReorderQueParm->fgIsValid) { + DBGLOG(QM, TRACE, + "QM:(Bub Check Cancel) STA[%u] TID[%u], No Rx BA entry\n", + prReorderQueParm->ucStaRecIdx, prReorderQueParm->ucTid); + return; + } + + if (!prReorderQueParm->fgHasBubble) { + DBGLOG(QM, TRACE, + "QM:(Bub Check Cancel) STA[%u] TID[%u], Bubble has been filled\n", + prReorderQueParm->ucStaRecIdx, prReorderQueParm->ucTid); + return; + } + + prReorderQue = &(prReorderQueParm->rReOrderQue); + + RX_DIRECT_REORDER_LOCK(prAdapter, 0); + + if (QUEUE_IS_EMPTY(prReorderQue)) { + prReorderQueParm->fgHasBubble = FALSE; + + DBGLOG(QM, TRACE, + "QM:(Bub Check Cancel) STA[%u] TID[%u], Bubble has been filled\n", + prReorderQueParm->ucStaRecIdx, prReorderQueParm->ucTid); + + RX_DIRECT_REORDER_UNLOCK(prAdapter, 0); + return; + } + + DBGLOG(QM, TRACE, + "QM:(Bub Check Event Got) STA[%u] TID[%u]\n", + prReorderQueParm->ucStaRecIdx, prReorderQueParm->ucTid); + + /* Expected bubble timeout => pop out packets before win_end */ + if (prReorderQueParm->u2FirstBubbleSn == + prReorderQueParm->u2WinStart) { + + prReorderedSwRfb = (struct SW_RFB *) QUEUE_GET_TAIL( + prReorderQue); + + prReorderQueParm->u2WinStart = prReorderedSwRfb->u2SSN + 1; + if (prReorderQueParm->u2WinStart >= MAX_SEQ_NO_COUNT) + prReorderQueParm->u2WinStart %= MAX_SEQ_NO_COUNT; + prReorderQueParm->u2WinEnd = + ((prReorderQueParm->u2WinStart) + + (prReorderQueParm->u2WinSize) - 1) % MAX_SEQ_NO_COUNT; +#if CFG_SUPPORT_RX_AMSDU + prReorderQueParm->u8LastAmsduSubIdx = + RX_PAYLOAD_FORMAT_MSDU; +#endif + qmPopOutDueToFallAhead(prAdapter, prReorderQueParm, + prReturnedQue); + + DBGLOG(QM, TRACE, + "QM:(Bub Flush) STA[%u] TID[%u] BubSN[%u] Win{%u, %u}\n", + prReorderQueParm->ucStaRecIdx, + prReorderQueParm->ucTid, + prReorderQueParm->u2FirstBubbleSn, + prReorderQueParm->u2WinStart, + prReorderQueParm->u2WinEnd); + + prReorderQueParm->fgHasBubble = FALSE; + RX_DIRECT_REORDER_UNLOCK(prAdapter, 0); + + /* process prReturnedQue after unlock prReturnedQue */ + if (QUEUE_IS_NOT_EMPTY(prReturnedQue)) { + QM_TX_SET_NEXT_MSDU_INFO( + (struct SW_RFB *) QUEUE_GET_TAIL( + prReturnedQue), NULL); + + prSwRfb = (struct SW_RFB *) + QUEUE_GET_HEAD(prReturnedQue); + while (prSwRfb) { + DBGLOG(QM, TRACE, + "QM:(Bub Flush) STA[%u] TID[%u] Pop Out SN[%u]\n", + prReorderQueParm->ucStaRecIdx, + prReorderQueParm->ucTid, + prSwRfb->u2SSN); + + prSwRfb = (struct SW_RFB *) + QUEUE_GET_NEXT_ENTRY( + (struct QUE_ENTRY *) prSwRfb); + } + + wlanProcessQueuedSwRfb(prAdapter, + (struct SW_RFB *) + QUEUE_GET_HEAD(prReturnedQue)); + } else { + DBGLOG(QM, TRACE, + "QM:(Bub Flush) STA[%u] TID[%u] Pop Out 0 packet\n", + prReorderQueParm->ucStaRecIdx, + prReorderQueParm->ucTid); + } + } + /* First bubble has been filled but others exist */ + else { + prReorderQueParm->u2FirstBubbleSn = + prReorderQueParm->u2WinStart; + + DBGLOG(QM, TRACE, + "QM:(Bub Timer) STA[%u] TID[%u] BubSN[%u] Win{%u, %u}\n", + prReorderQueParm->ucStaRecIdx, + prReorderQueParm->ucTid, + prReorderQueParm->u2FirstBubbleSn, + prReorderQueParm->u2WinStart, + prReorderQueParm->u2WinEnd); + RX_DIRECT_REORDER_UNLOCK(prAdapter, 0); + + cnmTimerStartTimer(prAdapter, + &(prReorderQueParm->rReorderBubbleTimer), + prAdapter->u4QmRxBaMissTimeout); + } + + prMissTimeout = &g_arMissTimeout[ + prReorderQueParm->ucStaRecIdx][prReorderQueParm->ucTid]; + if (QUEUE_IS_EMPTY(prReorderQue)) { + DBGLOG(QM, TRACE, + "QM:(Bub Check) Reset prMissTimeout to zero\n"); + *prMissTimeout = 0; + } else { + DBGLOG(QM, TRACE, + "QM:(Bub Check) Reset prMissTimeout to current time\n"); + GET_CURRENT_SYSTIME(prMissTimeout); + } +} + +u_int8_t qmCompareSnIsLessThan(IN uint32_t u4SnLess, IN uint32_t u4SnGreater) +{ + /* 0 <---> SnLess <--(gap>2048)--> SnGreater : SnLess > SnGreater */ + if ((u4SnLess + HALF_SEQ_NO_COUNT) <= u4SnGreater) + return FALSE; + + /* 0 <---> SnGreater <--(gap>2048)--> SnLess : SnLess < SnGreater */ + else if ((u4SnGreater + HALF_SEQ_NO_COUNT) < u4SnLess) + return TRUE; + + /* 0 <---> SnGreater <--(gap<2048)--> SnLess : SnLess > SnGreater */ + /* 0 <---> SnLess <--(gap<2048)--> SnGreater : SnLess < SnGreater */ + else + return u4SnLess < u4SnGreater; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Handle Mailbox RX messages + * + * \param[in] prMailboxRxMsg The received Mailbox message from the FW + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void qmHandleMailboxRxMessage(IN struct MAILBOX_MSG prMailboxRxMsg) +{ + /* DbgPrint("QM: Enter qmHandleMailboxRxMessage()\n"); */ + /* TODO */ +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Handle ADD TX BA Event from the FW + * + * \param[in] prAdapter Adapter pointer + * \param[in] prEvent The event packet from the FW + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void qmHandleEventTxAddBa(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ + struct mt66xx_chip_info *prChipInfo; + struct EVENT_TX_ADDBA *prEventTxAddBa; + struct STA_RECORD *prStaRec; + uint8_t ucStaRecIdx; + uint8_t ucTid; + + ASSERT(prAdapter); + prChipInfo = prAdapter->chip_info; + + DBGLOG(QM, INFO, "QM:Event +TxBa\n"); + + if (!prChipInfo->is_support_hw_amsdu && + prChipInfo->ucMaxSwAmsduNum <= 1) { + DBGLOG(QM, INFO, "QM:Event +TxBa but chip is not support\n"); + return; + } + + prEventTxAddBa = (struct EVENT_TX_ADDBA *) (prEvent->aucBuffer); + ucStaRecIdx = prEventTxAddBa->ucStaRecIdx; + prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, ucStaRecIdx); + if (!prStaRec) { + /* Invalid STA_REC index, discard the event packet */ + /* ASSERT(0); */ + DBGLOG(QM, INFO, + "QM: (Warning) TX ADDBA Event for a NULL STA_REC\n"); + return; + } + + for (ucTid = 0; ucTid < TX_DESC_TID_NUM; ucTid++) { + uint8_t ucStaEn = prStaRec->ucAmsduEnBitmap & BIT(ucTid); + uint8_t ucEvtEn = prEventTxAddBa->ucAmsduEnBitmap & BIT(ucTid); + + if (prChipInfo->is_support_hw_amsdu && ucStaEn != ucEvtEn) + nicTxSetHwAmsduDescTemplate(prAdapter, prStaRec, ucTid, + ucEvtEn >> ucTid); + } + + prStaRec->ucAmsduEnBitmap = prEventTxAddBa->ucAmsduEnBitmap; + prStaRec->ucMaxMpduCount = prEventTxAddBa->ucMaxMpduCount; + prStaRec->u4MaxMpduLen = prEventTxAddBa->u4MaxMpduLen; + prStaRec->u4MinMpduLen = prEventTxAddBa->u4MinMpduLen; + + DBGLOG(QM, INFO, + "QM:Event +TxBa bitmap[0x%x] count[%u] MaxLen[%u] MinLen[%u]\n", + prStaRec->ucAmsduEnBitmap, prStaRec->ucMaxMpduCount, + prStaRec->u4MaxMpduLen, prStaRec->u4MinMpduLen); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Handle ADD RX BA Event from the FW + * + * \param[in] prAdapter Adapter pointer + * \param[in] prEvent The event packet from the FW + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void qmHandleEventRxAddBa(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ + struct EVENT_RX_ADDBA *prEventRxAddBa; + struct STA_RECORD *prStaRec; + uint32_t u4Tid; + uint32_t u4WinSize; + + DBGLOG(QM, INFO, "QM:Event +RxBa\n"); + + prEventRxAddBa = (struct EVENT_RX_ADDBA *) ( + prEvent->aucBuffer); + prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, + prEventRxAddBa->ucStaRecIdx); + + if (!prStaRec) { + /* Invalid STA_REC index, discard the event packet */ + /* ASSERT(0); */ + DBGLOG(QM, INFO, + "QM: (Warning) RX ADDBA Event for a NULL STA_REC\n"); + return; + } +#if 0 + if (!(prStaRec->fgIsValid)) { + /* TODO: (Tehuang) Handle the Host-FW synchronization issue */ + DBGLOG(QM, WARN, + "QM: (Warning) RX ADDBA Event for an invalid STA_REC\n"); + /* ASSERT(0); */ + /* return; */ + } +#endif + + u4Tid = (((prEventRxAddBa->u2BAParameterSet) & + BA_PARAM_SET_TID_MASK) >> + BA_PARAM_SET_TID_MASK_OFFSET); + + u4WinSize = (((prEventRxAddBa->u2BAParameterSet) & + BA_PARAM_SET_BUFFER_SIZE_MASK) >> + BA_PARAM_SET_BUFFER_SIZE_MASK_OFFSET); + + if (!qmAddRxBaEntry(prAdapter, + prStaRec->ucIndex, + (uint8_t) u4Tid, + (prEventRxAddBa->u2BAStartSeqCtrl >> + OFFSET_BAR_SSC_SN), + (uint16_t) u4WinSize)) { + + /* FW shall ensure the availabiilty of + * the free-to-use BA entry + */ + DBGLOG(QM, ERROR, "QM: (Error) qmAddRxBaEntry() failure\n"); + } + +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Handle DEL RX BA Event from the FW + * + * \param[in] prAdapter Adapter pointer + * \param[in] prEvent The event packet from the FW + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void qmHandleEventRxDelBa(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ + struct EVENT_RX_DELBA *prEventRxDelBa; + struct STA_RECORD *prStaRec; + + /* DbgPrint("QM:Event -RxBa\n"); */ + + prEventRxDelBa = (struct EVENT_RX_DELBA *) ( + prEvent->aucBuffer); + prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, + prEventRxDelBa->ucStaRecIdx); + + if (!prStaRec) + /* Invalid STA_REC index, discard the event packet */ + /* ASSERT(0); */ + return; +#if 0 + if (!(prStaRec->fgIsValid)) + /* TODO: (Tehuang) Handle the Host-FW synchronization issue */ + /* ASSERT(0); */ + return; +#endif + + qmDelRxBaEntry(prAdapter, prStaRec->ucIndex, + prEventRxDelBa->ucTid, TRUE); + +} + +struct RX_BA_ENTRY *qmLookupRxBaEntry(IN struct ADAPTER *prAdapter, + uint8_t ucStaRecIdx, uint8_t ucTid) +{ + int i; + struct QUE_MGT *prQM = &prAdapter->rQM; + + /* DbgPrint("QM: Enter qmLookupRxBaEntry()\n"); */ + + for (i = 0; i < CFG_NUM_OF_RX_BA_AGREEMENTS; i++) { + if (prQM->arRxBaTable[i].fgIsValid) { + if ((prQM->arRxBaTable[i].ucStaRecIdx == ucStaRecIdx) + && (prQM->arRxBaTable[i].ucTid == ucTid)) + return &prQM->arRxBaTable[i]; + } + } + return NULL; +} + +u_int8_t qmAddRxBaEntry(IN struct ADAPTER *prAdapter, + IN uint8_t ucStaRecIdx, IN uint8_t ucTid, + IN uint16_t u2WinStart, IN uint16_t u2WinSize) +{ + int i; + struct RX_BA_ENTRY *prRxBaEntry = NULL; + struct STA_RECORD *prStaRec; + struct QUE_MGT *prQM = &prAdapter->rQM; + + ASSERT(ucStaRecIdx < CFG_STA_REC_NUM); + + if (ucStaRecIdx >= CFG_STA_REC_NUM || ucTid >= CFG_RX_MAX_BA_TID_NUM) { + /* Invalid STA_REC index, discard the event packet */ + DBGLOG(QM, WARN, + "QM: (WARNING) RX ADDBA Event for a invalid ucStaRecIdx = %d, ucTID=%d\n", + ucStaRecIdx, ucTid); + return FALSE; + } + + prStaRec = &prAdapter->arStaRec[ucStaRecIdx]; + ASSERT(prStaRec); + + /* 4 <1> Delete before adding */ + /* Remove the BA entry for the same (STA, TID) tuple if it exists */ + /* prQM->ucRxBaCount-- */ + if (qmLookupRxBaEntry(prAdapter, ucStaRecIdx, ucTid)) + qmDelRxBaEntry(prAdapter, ucStaRecIdx, ucTid, TRUE); + /* 4 <2> Add a new BA entry */ + /* No available entry to store the BA agreement info. Retrun FALSE. */ + if (prQM->ucRxBaCount >= CFG_NUM_OF_RX_BA_AGREEMENTS) { + DBGLOG(QM, ERROR, + "QM: **failure** (limited resource, ucRxBaCount=%d)\n", + prQM->ucRxBaCount); + return FALSE; + } + /* Find the free-to-use BA entry */ + for (i = 0; i < CFG_NUM_OF_RX_BA_AGREEMENTS; i++) { + if (!prQM->arRxBaTable[i].fgIsValid) { + prRxBaEntry = &(prQM->arRxBaTable[i]); + prQM->ucRxBaCount++; + DBGLOG(QM, LOUD, + "QM: ucRxBaCount=%d\n", prQM->ucRxBaCount); + break; + } + } + + /* If a free-to-use entry is found, + * configure it and associate it with the STA_REC + */ + u2WinSize += CFG_RX_BA_INC_SIZE; + if (prRxBaEntry) { + prRxBaEntry->ucStaRecIdx = ucStaRecIdx; + prRxBaEntry->ucTid = ucTid; + prRxBaEntry->u2WinStart = u2WinStart; + prRxBaEntry->u2WinSize = u2WinSize; + prRxBaEntry->u2WinEnd = ((u2WinStart + u2WinSize - 1) % + MAX_SEQ_NO_COUNT); +#if CFG_SUPPORT_RX_AMSDU + /* RX reorder for one MSDU in AMSDU issue */ + prRxBaEntry->u8LastAmsduSubIdx = RX_PAYLOAD_FORMAT_MSDU; + prRxBaEntry->fgAmsduNeedLastFrame = FALSE; + prRxBaEntry->fgIsAmsduDuplicated = FALSE; +#endif + prRxBaEntry->fgIsValid = TRUE; + prRxBaEntry->fgIsWaitingForPktWithSsn = TRUE; + prRxBaEntry->fgHasBubble = FALSE; + + g_arMissTimeout[ucStaRecIdx][ucTid] = 0; + + DBGLOG(QM, INFO, + "QM: +RxBA(STA=%u TID=%u WinStart=%u WinEnd=%u WinSize=%u)\n", + ucStaRecIdx, ucTid, prRxBaEntry->u2WinStart, + prRxBaEntry->u2WinEnd, + prRxBaEntry->u2WinSize); + + /* Update the BA entry reference table for per-packet lookup */ + prStaRec->aprRxReorderParamRefTbl[ucTid] = prRxBaEntry; + } else { + /* This shall not happen because + * FW should keep track of the usage of RX BA entries + */ + DBGLOG(QM, ERROR, "QM: **AddBA Error** (ucRxBaCount=%d)\n", + prQM->ucRxBaCount); + return FALSE; + } + + + return TRUE; +} + +void qmDelRxBaEntry(IN struct ADAPTER *prAdapter, + IN uint8_t ucStaRecIdx, IN uint8_t ucTid, + IN u_int8_t fgFlushToHost) +{ + struct RX_BA_ENTRY *prRxBaEntry; + struct STA_RECORD *prStaRec; + struct SW_RFB *prFlushedPacketList = NULL; + struct QUE_MGT *prQM = &prAdapter->rQM; + + ASSERT(ucStaRecIdx < CFG_STA_REC_NUM); + + prStaRec = &prAdapter->arStaRec[ucStaRecIdx]; + ASSERT(prStaRec); + +#if 0 + if (!(prStaRec->fgIsValid)) { + DbgPrint("QM: (WARNING) Invalid STA when deleting an RX BA\n"); + return; + } +#endif + + /* Remove the BA entry for the same (STA, TID) tuple if it exists */ + prRxBaEntry = prStaRec->aprRxReorderParamRefTbl[ucTid]; + + if (prRxBaEntry) { + + prFlushedPacketList = qmFlushStaRxQueue(prAdapter, + ucStaRecIdx, ucTid); + + if (prFlushedPacketList) { + + if (fgFlushToHost) { + wlanProcessQueuedSwRfb(prAdapter, + prFlushedPacketList); + } else { + + struct SW_RFB *prSwRfb; + struct SW_RFB *prNextSwRfb; + + prSwRfb = prFlushedPacketList; + + do { + prNextSwRfb = (struct SW_RFB *) + QUEUE_GET_NEXT_ENTRY( + (struct QUE_ENTRY *) prSwRfb); + nicRxReturnRFB(prAdapter, prSwRfb); + prSwRfb = prNextSwRfb; + } while (prSwRfb); + + } + + } + + if (prRxBaEntry->fgHasBubble) { + DBGLOG(QM, TRACE, + "QM:(Bub Check Cancel) STA[%u] TID[%u], DELBA\n", + prRxBaEntry->ucStaRecIdx, prRxBaEntry->ucTid); + + cnmTimerStopTimer(prAdapter, + &prRxBaEntry->rReorderBubbleTimer); + prRxBaEntry->fgHasBubble = FALSE; + } +#if ((QM_TEST_MODE == 0) && (QM_TEST_STA_REC_DEACTIVATION == 0)) + /* Update RX BA entry state. + * Note that RX queue flush is not done here + */ + prRxBaEntry->fgIsValid = FALSE; + prQM->ucRxBaCount--; + + /* Debug */ +#if 0 + DbgPrint("QM: ucRxBaCount=%d\n", prQM->ucRxBaCount); +#endif + + /* Update STA RX BA table */ + prStaRec->aprRxReorderParamRefTbl[ucTid] = NULL; +#endif + + DBGLOG(QM, INFO, "QM: -RxBA(STA=%d,TID=%d)\n", + ucStaRecIdx, ucTid); + + } + + /* Debug */ +#if CFG_HIF_RX_STARVATION_WARNING + { + struct RX_CTRL *prRxCtrl; + + prRxCtrl = &prAdapter->rRxCtrl; + DBGLOG(QM, TRACE, + "QM: (RX DEBUG) Enqueued: %d / Dequeued: %d\n", + prRxCtrl->u4QueuedCnt, prRxCtrl->u4DequeuedCnt); + } +#endif +} + +u_int8_t qmIsIndependentPkt(IN struct SW_RFB *prSwRfb) +{ + struct sk_buff *skb = NULL; + + if (prSwRfb->u2PacketLen <= ETHER_HEADER_LEN) + return FALSE; + + skb = (struct sk_buff *)(prSwRfb->pvPacket); + if (!skb) + return FALSE; + + if (GLUE_GET_INDEPENDENT_PKT(skb)) + return TRUE; + + return FALSE; +} + +void mqmParseAssocReqWmmIe(IN struct ADAPTER *prAdapter, + IN uint8_t *pucIE, IN struct STA_RECORD *prStaRec) +{ + struct IE_WMM_INFO *prIeWmmInfo; + uint8_t ucQosInfo; + uint8_t ucQosInfoAC; + uint8_t ucBmpAC; + uint8_t aucWfaOui[] = VENDOR_OUI_WFA; + + if ((WMM_IE_OUI_TYPE(pucIE) == VENDOR_OUI_TYPE_WMM) + && (!kalMemCmp(WMM_IE_OUI(pucIE), aucWfaOui, 3))) { + + switch (WMM_IE_OUI_SUBTYPE(pucIE)) { + case VENDOR_OUI_SUBTYPE_WMM_INFO: + if (IE_LEN(pucIE) != 7) + break; /* WMM Info IE with a wrong length */ + + prStaRec->fgIsQoS = TRUE; + prStaRec->fgIsWmmSupported = TRUE; + + prIeWmmInfo = (struct IE_WMM_INFO *) pucIE; + ucQosInfo = prIeWmmInfo->ucQosInfo; + ucQosInfoAC = ucQosInfo & BITS(0, 3); + + if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucUapsd)) + prStaRec->fgIsUapsdSupported = + (ucQosInfoAC) ? TRUE : FALSE; + else + prStaRec->fgIsUapsdSupported = FALSE; + + ucBmpAC = 0; + + if (ucQosInfoAC & WMM_QOS_INFO_VO_UAPSD) + ucBmpAC |= BIT(ACI_VO); + + if (ucQosInfoAC & WMM_QOS_INFO_VI_UAPSD) + ucBmpAC |= BIT(ACI_VI); + + if (ucQosInfoAC & WMM_QOS_INFO_BE_UAPSD) + ucBmpAC |= BIT(ACI_BE); + + if (ucQosInfoAC & WMM_QOS_INFO_BK_UAPSD) + ucBmpAC |= BIT(ACI_BK); + prStaRec->ucBmpTriggerAC = prStaRec->ucBmpDeliveryAC = + ucBmpAC; + prStaRec->ucUapsdSp = (ucQosInfo & + WMM_QOS_INFO_MAX_SP_LEN_MASK) >> 5; + break; + + default: + /* Other WMM QoS IEs. Ignore any */ + break; + } + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief To process WMM related IEs in ASSOC_RSP + * + * \param[in] prAdapter Adapter pointer + * \param[in] prSwRfb The received frame + * \param[in] pucIE The pointer to the first IE in the frame + * \param[in] u2IELength The total length of IEs in the frame + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void mqmProcessAssocReq(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, IN uint8_t *pucIE, + IN uint16_t u2IELength) +{ + struct STA_RECORD *prStaRec; + uint16_t u2Offset; + uint8_t *pucIEStart; + uint32_t u4Flags; + + DEBUGFUNC("mqmProcessAssocReq"); + + ASSERT(prSwRfb); + ASSERT(pucIE); + + prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); + ASSERT(prStaRec); + + if (prStaRec == NULL) + return; + + prStaRec->fgIsQoS = FALSE; + prStaRec->fgIsWmmSupported = prStaRec->fgIsUapsdSupported = FALSE; + + pucIEStart = pucIE; + + /* If the device does not support QoS or if + * WMM is not supported by the peer, exit. + */ + if (IS_FEATURE_DISABLED(prAdapter->rWifiVar.ucQoS)) + return; + + /* Determine whether QoS is enabled with the association */ + else { + prStaRec->u4Flags = 0; + IE_FOR_EACH(pucIE, u2IELength, u2Offset) { + switch (IE_ID(pucIE)) { + case ELEM_ID_VENDOR: + mqmParseAssocReqWmmIe(prAdapter, + pucIE, prStaRec); + +#if CFG_SUPPORT_MTK_SYNERGY + if (rlmParseCheckMTKOuiIE(prAdapter, + pucIE, &u4Flags)) + prStaRec->u4Flags = u4Flags; +#endif + + break; + + case ELEM_ID_HT_CAP: + /* Some client won't put the WMM IE + * if client is 802.11n + */ + if (IE_LEN(pucIE) == + (sizeof(struct IE_HT_CAP) - 2)) + prStaRec->fgIsQoS = TRUE; + break; + default: + break; + } + } + + DBGLOG(QM, TRACE, + "MQM: Assoc_Req Parsing (QoS Enabled=%d)\n", + prStaRec->fgIsQoS); + + } +} + +void mqmParseAssocRspWmmIe(IN uint8_t *pucIE, + IN struct STA_RECORD *prStaRec) +{ + uint8_t aucWfaOui[] = VENDOR_OUI_WFA; + + if ((WMM_IE_OUI_TYPE(pucIE) == VENDOR_OUI_TYPE_WMM) + && (!kalMemCmp(WMM_IE_OUI(pucIE), aucWfaOui, 3))) { + struct IE_WMM_PARAM *prWmmParam = (struct IE_WMM_PARAM *) pucIE; + enum ENUM_ACI eAci; + + switch (WMM_IE_OUI_SUBTYPE(pucIE)) { + case VENDOR_OUI_SUBTYPE_WMM_PARAM: + if (IE_LEN(pucIE) != 24) + break; /* WMM Info IE with a wrong length */ + prStaRec->fgIsQoS = TRUE; + prStaRec->fgIsUapsdSupported = + !!(prWmmParam->ucQosInfo & WMM_QOS_INFO_UAPSD); + for (eAci = ACI_BE; eAci < ACI_NUM; eAci++) + prStaRec->afgAcmRequired[eAci] = !!( + prWmmParam->arAcParam[eAci].ucAciAifsn & + WMM_ACIAIFSN_ACM); + DBGLOG(WMM, INFO, + "WMM: " MACSTR "ACM BK=%d BE=%d VI=%d VO=%d\n", + MAC2STR(prStaRec->aucMacAddr), + prStaRec->afgAcmRequired[ACI_BK], + prStaRec->afgAcmRequired[ACI_BE], + prStaRec->afgAcmRequired[ACI_VI], + prStaRec->afgAcmRequired[ACI_VO]); + break; + + case VENDOR_OUI_SUBTYPE_WMM_INFO: + if (IE_LEN(pucIE) != 7) + break; /* WMM Info IE with a wrong length */ + prStaRec->fgIsQoS = TRUE; + break; + + default: + /* Other WMM QoS IEs. Ignore any */ + break; + } + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief To process WMM related IEs in ASSOC_RSP + * + * \param[in] prAdapter Adapter pointer + * \param[in] prSwRfb The received frame + * \param[in] pucIE The pointer to the first IE in the frame + * \param[in] u2IELength The total length of IEs in the frame + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void mqmProcessAssocRsp(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, IN uint8_t *pucIE, + IN uint16_t u2IELength) +{ + struct STA_RECORD *prStaRec; + uint16_t u2Offset; + uint8_t *pucIEStart; + uint32_t u4Flags; + + DEBUGFUNC("mqmProcessAssocRsp"); + + ASSERT(prSwRfb); + ASSERT(pucIE); + + prStaRec = cnmGetStaRecByIndex(prAdapter, + prSwRfb->ucStaRecIdx); + ASSERT(prStaRec); + + if (prStaRec == NULL) + return; + + prStaRec->fgIsQoS = FALSE; + + pucIEStart = pucIE; + + DBGLOG(QM, TRACE, + "QM: (fgIsWmmSupported=%d, fgSupportQoS=%d)\n", + prStaRec->fgIsWmmSupported, prAdapter->rWifiVar.ucQoS); + + /* If the device does not support QoS + * or if WMM is not supported by the peer, exit. + */ + if (IS_FEATURE_DISABLED(prAdapter->rWifiVar.ucQoS)) + return; + + /* Determine whether QoS is enabled with the association */ + else { + prStaRec->u4Flags = 0; + IE_FOR_EACH(pucIE, u2IELength, u2Offset) { + switch (IE_ID(pucIE)) { + case ELEM_ID_VENDOR: + /* Process WMM related IE */ + mqmParseAssocRspWmmIe(pucIE, prStaRec); + +#if CFG_SUPPORT_MTK_SYNERGY + if (rlmParseCheckMTKOuiIE(prAdapter, + pucIE, &u4Flags)) + prStaRec->u4Flags = u4Flags; +#endif + + break; + + case ELEM_ID_HT_CAP: + /* Some AP won't put the WMM IE + * if client is 802.11n + */ + if (IE_LEN(pucIE) == + (sizeof(struct IE_HT_CAP) - 2)) + prStaRec->fgIsQoS = TRUE; + break; +#if DSCP_SUPPORT + case ELEM_ID_QOS_MAP_SET: + DBGLOG(QM, WARN, + "QM: received assoc resp qosmapset ie\n"); + qosParseQosMapSet(prAdapter, prStaRec, pucIE); + break; +#endif + default: + break; + } + } + /* Parse AC parameters and write to HW CRs */ + if ((prStaRec->fgIsQoS) + && (prStaRec->eStaType == STA_TYPE_LEGACY_AP)) { + mqmParseEdcaParameters(prAdapter, prSwRfb, pucIEStart, + u2IELength, TRUE); +#if (CFG_SUPPORT_802_11AX == 1) + if (fgEfuseCtrlAxOn == 1) { + mqmParseMUEdcaParams(prAdapter, prSwRfb, + pucIEStart, u2IELength, TRUE); + } +#endif + +#if ARP_MONITER_ENABLE + qmResetArpDetect(); +#endif + } + DBGLOG(QM, TRACE, + "MQM: Assoc_Rsp Parsing (QoS Enabled=%d)\n", + prStaRec->fgIsQoS); + if (prStaRec->fgIsWmmSupported) + nicQmUpdateWmmParms(prAdapter, prStaRec->ucBssIndex); +#if (CFG_SUPPORT_802_11AX == 1) + if (fgEfuseCtrlAxOn == 1) { + if (prStaRec->fgIsMuEdcaSupported || + prAdapter->fgMuEdcaOverride) { + nicQmUpdateMUEdcaParams(prAdapter, + prStaRec->ucBssIndex); + } + } +#endif + + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void mqmProcessBcn(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, IN uint8_t *pucIE, + IN uint16_t u2IELength) +{ + struct BSS_INFO *prBssInfo; + u_int8_t fgNewParameter; +#if (CFG_SUPPORT_802_11AX == 1) + u_int8_t fgNewMUEdca = FALSE; +#endif + uint8_t i; + + ASSERT(prAdapter); + ASSERT(prSwRfb); + ASSERT(pucIE); + + DBGLOG(QM, TRACE, "Enter %s\n", __func__); + + fgNewParameter = FALSE; + + for (i = 0; i < prAdapter->ucHwBssIdNum; i++) { + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, i); + + if (IS_BSS_ACTIVE(prBssInfo)) { + if (prBssInfo->eCurrentOPMode == + OP_MODE_INFRASTRUCTURE && + prBssInfo->eConnectionState == + MEDIA_STATE_CONNECTED) { + /* P2P client or AIS infra STA */ + if (EQUAL_MAC_ADDR(prBssInfo->aucBSSID, + ((struct WLAN_MAC_MGMT_HEADER *) + (prSwRfb->pvHeader))->aucBSSID)) { + + fgNewParameter = + mqmParseEdcaParameters( + prAdapter, + prSwRfb, pucIE, + u2IELength, FALSE); +#if (CFG_SUPPORT_802_11AX == 1) + if (fgEfuseCtrlAxOn == 1) { + fgNewMUEdca = mqmParseMUEdcaParams( + prAdapter, prSwRfb, pucIE, + u2IELength, FALSE); + } +#endif + } + } + + /* Appy new parameters if necessary */ + if (fgNewParameter) { + nicQmUpdateWmmParms(prAdapter, + prBssInfo->ucBssIndex); + fgNewParameter = FALSE; + } +#if (CFG_SUPPORT_802_11AX == 1) + if (fgEfuseCtrlAxOn == 1) { + if (fgNewMUEdca) { + nicQmUpdateMUEdcaParams(prAdapter, + prBssInfo->ucBssIndex); + fgNewMUEdca = FALSE; + } + } +#endif + } + } /* end of IS_BSS_ACTIVE() */ +} + + +u_int8_t mqmUpdateEdcaParameters(IN struct BSS_INFO *prBssInfo, + IN uint8_t *pucIE, IN u_int8_t fgForceOverride) +{ + struct AC_QUE_PARMS *prAcQueParams; + struct IE_WMM_PARAM *prIeWmmParam; + enum ENUM_WMM_ACI eAci; + u_int8_t fgNewParameter = FALSE; + + do { + if (IE_LEN(pucIE) != 24) + break; /* WMM Param IE with a wrong length */ + + prIeWmmParam = (struct IE_WMM_PARAM *) pucIE; + + /* Check the Parameter Set Count to determine + * whether EDCA parameters have been changed + */ + if (!fgForceOverride) { + if (mqmCompareEdcaParameters(prIeWmmParam, prBssInfo)) { + fgNewParameter = FALSE; + break; + } + } + + fgNewParameter = TRUE; + /* Update Parameter Set Count */ + prBssInfo->ucWmmParamSetCount = (prIeWmmParam->ucQosInfo & + WMM_QOS_INFO_PARAM_SET_CNT); + /* Update EDCA parameters */ + for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { + prAcQueParams = &prBssInfo->arACQueParms[eAci]; + mqmFillAcQueParam(prIeWmmParam, eAci, prAcQueParams); + log_dbg(QM, INFO, "BSS[%u]: eAci[%d] ACM[%d] Aifsn[%d] CWmin/max[%d/%d] TxopLimit[%d] NewParameter[%d]\n", + prBssInfo->ucBssIndex, eAci, + prAcQueParams->ucIsACMSet, + prAcQueParams->u2Aifsn, prAcQueParams->u2CWmin, + prAcQueParams->u2CWmax, + prAcQueParams->u2TxopLimit, fgNewParameter); + } + } while (FALSE); + + return fgNewParameter; +} + +#if (CFG_SUPPORT_802_11AX == 1) +uint8_t mqmCompareMUEdcaParameters( + struct _IE_MU_EDCA_PARAM_T *prIeMUEdcaParam, + struct BSS_INFO *prBssInfo) +{ + struct _CMD_MU_EDCA_PARAMS_T *prBSSMUEdca; + struct _MU_AC_PARAM_RECORD_T *prMUAcParamInIE; + enum ENUM_WMM_ACI eAci; + + /* Check Set Count */ + if (prBssInfo->ucMUEdcaUpdateCnt != + (prIeMUEdcaParam->ucMUQosInfo & WMM_QOS_INFO_PARAM_SET_CNT)) + return FALSE; + + for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { + prBSSMUEdca = &prBssInfo->arMUEdcaParams[eAci]; + prMUAcParamInIE = &prIeMUEdcaParam->arMUAcParam[eAci]; + + /* ACM */ + if (prBSSMUEdca->ucIsACMSet != ((prMUAcParamInIE->ucAciAifsn & + WMM_ACIAIFSN_ACM) ? TRUE : FALSE)) + return FALSE; + + /* AIFSN */ + if (prBSSMUEdca->ucAifsn != (prMUAcParamInIE->ucAciAifsn & + WMM_ACIAIFSN_AIFSN)) + return FALSE; + + /* CW Max */ + if (prBSSMUEdca->ucECWmax != + ((prMUAcParamInIE->ucEcw & WMM_ECW_WMAX_MASK) + >> WMM_ECW_WMAX_OFFSET)) + return FALSE; + + /* CW Min */ + if (prBSSMUEdca->ucECWmin != + (prMUAcParamInIE->ucEcw & WMM_ECW_WMIN_MASK)) + return FALSE; + + /* MU EDCA timer */ + if (prBSSMUEdca->ucMUEdcaTimer != + prMUAcParamInIE->ucMUEdcaTimer) + return FALSE; + } + + return TRUE; +} + +uint8_t mqmUpdateMUEdcaParams(struct BSS_INFO *prBssInfo, + uint8_t *pucIE, uint8_t fgForceOverride) +{ + struct _CMD_MU_EDCA_PARAMS_T *prBSSMUEdca; + struct _IE_MU_EDCA_PARAM_T *prIeMUEdcaParam; + struct _MU_AC_PARAM_RECORD_T *prMUAcParamInIE; + enum ENUM_WMM_ACI eAci; + uint8_t fgNewParameter = FALSE; + + do { + if (IE_LEN(pucIE) != 14) + break; /* MU EDCA Param IE with a wrong length */ + + prIeMUEdcaParam = (struct _IE_MU_EDCA_PARAM_T *) pucIE; + + /* + * Check the Parameter Set Count to determine whether + * MU EDCA parameters have been changed + */ + if (!fgForceOverride) { + if (mqmCompareMUEdcaParameters(prIeMUEdcaParam, + prBssInfo)) { + fgNewParameter = FALSE; + break; + } + } + + fgNewParameter = TRUE; + /* Update Parameter Set Count */ + prBssInfo->ucMUEdcaUpdateCnt = (prIeMUEdcaParam->ucMUQosInfo & + WMM_QOS_INFO_PARAM_SET_CNT); + /* Update MU EDCA parameters to BSS structure */ + for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { + prMUAcParamInIE = &(prIeMUEdcaParam->arMUAcParam[eAci]); + prBSSMUEdca = &prBssInfo->arMUEdcaParams[eAci]; + + prBSSMUEdca->ucECWmin = prMUAcParamInIE->ucEcw & + WMM_ECW_WMIN_MASK; + prBSSMUEdca->ucECWmax = (prMUAcParamInIE->ucEcw & + WMM_ECW_WMAX_MASK) + >> WMM_ECW_WMAX_OFFSET; + prBSSMUEdca->ucAifsn = (prMUAcParamInIE->ucAciAifsn & + WMM_ACIAIFSN_AIFSN); + prBSSMUEdca->ucIsACMSet = (prMUAcParamInIE->ucAciAifsn & + WMM_ACIAIFSN_ACM) ? TRUE : FALSE; + prBSSMUEdca->ucMUEdcaTimer = + prMUAcParamInIE->ucMUEdcaTimer; + + DBGLOG(QM, INFO, + "BSS[%u]: eAci[%d] ACM[%d] Aifsn[%d],", + prBssInfo->ucBssIndex, eAci, + prBSSMUEdca->ucIsACMSet, prBSSMUEdca->ucAifsn); + DBGLOG(QM, INFO, + "ECWmin/max[%d/%d] NewParameter[%d]\n", + prBSSMUEdca->ucECWmin, prBSSMUEdca->ucECWmax, + fgNewParameter); + + } + } while (FALSE); + + return fgNewParameter; +} + +uint8_t +mqmParseMUEdcaParams( + struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb, + uint8_t *pucIE, + uint16_t u2IELength, + uint8_t fgForceOverride) +{ + struct STA_RECORD *prStaRec; + uint16_t u2Offset; + struct BSS_INFO *prBssInfo; + uint8_t fgNewParameter = FALSE; + + DEBUGFUNC("mqmParseMUEdcaParams"); + + if (!prSwRfb) + return FALSE; + + if (!pucIE) + return FALSE; + + prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); + if (prStaRec == NULL) + return FALSE; + + DBGLOG(QM, TRACE, "QM: (fgIsQoS=%d)\n", prStaRec->fgIsQoS); + + if (IS_FEATURE_DISABLED(prAdapter->rWifiVar.ucQoS) || + (!prStaRec->fgIsQoS)) + return FALSE; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex); + + /* Goal: Obtain the MU EDCA parameters */ + IE_FOR_EACH(pucIE, u2IELength, u2Offset) { + switch (IE_ID(pucIE)) { + case ELEM_ID_RESERVED: + if (IE_ID_EXT(pucIE) == ELEM_EXT_ID_MU_EDCA_PARAM) { + prStaRec->fgIsMuEdcaSupported = TRUE; + fgNewParameter = mqmUpdateMUEdcaParams( + prBssInfo, pucIE, fgForceOverride); + } + break; + default: + break; + } + } + + return fgNewParameter; +} +#endif + + +/*----------------------------------------------------------------------------*/ +/*! + * \brief To parse WMM Parameter IE (in BCN or Assoc_Rsp) + * + * \param[in] prAdapter Adapter pointer + * \param[in] prSwRfb The received frame + * \param[in] pucIE The pointer to the first IE in the frame + * \param[in] u2IELength The total length of IEs in the frame + * \param[in] fgForceOverride TRUE: If EDCA parameters are found, always set + * to HW CRs. + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +u_int8_t +mqmParseEdcaParameters(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb, IN uint8_t *pucIE, + IN uint16_t u2IELength, IN u_int8_t fgForceOverride) +{ + struct STA_RECORD *prStaRec; + uint16_t u2Offset; + uint8_t aucWfaOui[] = VENDOR_OUI_WFA; + struct BSS_INFO *prBssInfo; + u_int8_t fgNewParameter = FALSE; + + DEBUGFUNC("mqmParseEdcaParameters"); + + if (!prSwRfb) + return FALSE; + + if (!pucIE) + return FALSE; + + prStaRec = cnmGetStaRecByIndex(prAdapter, + prSwRfb->ucStaRecIdx); + /* ASSERT(prStaRec); */ + + if (prStaRec == NULL) + return FALSE; + + DBGLOG(QM, TRACE, "QM: (fgIsWmmSupported=%d, fgIsQoS=%d)\n", + prStaRec->fgIsWmmSupported, prStaRec->fgIsQoS); + + if (IS_FEATURE_DISABLED(prAdapter->rWifiVar.ucQoS) + || (!prStaRec->fgIsWmmSupported) + || (!prStaRec->fgIsQoS)) + return FALSE; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prStaRec->ucBssIndex); + + /* Goal: Obtain the EDCA parameters */ + IE_FOR_EACH(pucIE, u2IELength, u2Offset) { + switch (IE_ID(pucIE)) { + case ELEM_ID_WMM: + if (!((WMM_IE_OUI_TYPE(pucIE) == VENDOR_OUI_TYPE_WMM) && + (!kalMemCmp(WMM_IE_OUI(pucIE), aucWfaOui, 3)))) + break; + + switch (WMM_IE_OUI_SUBTYPE(pucIE)) { + case VENDOR_OUI_SUBTYPE_WMM_PARAM: + fgNewParameter = + mqmUpdateEdcaParameters(prBssInfo, + pucIE, fgForceOverride); + break; + + default: + /* Other WMM QoS IEs. Ignore */ + break; + } + + /* else: VENDOR_OUI_TYPE_WPA, VENDOR_OUI_TYPE_WPS, ... + * (not cared) + */ + break; + default: + break; + } + } + + return fgNewParameter; +} + +u_int8_t mqmCompareEdcaParameters(IN struct IE_WMM_PARAM *prIeWmmParam, + IN struct BSS_INFO *prBssInfo) +{ + struct AC_QUE_PARMS *prAcQueParams; + struct WMM_AC_PARAM *prWmmAcParams; + enum ENUM_WMM_ACI eAci; + + /* return FALSE; */ + + /* Check Set Count */ + if (prBssInfo->ucWmmParamSetCount != + (prIeWmmParam->ucQosInfo & WMM_QOS_INFO_PARAM_SET_CNT)) + return FALSE; + + for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { + prAcQueParams = &prBssInfo->arACQueParms[eAci]; + prWmmAcParams = &prIeWmmParam->arAcParam[eAci]; + + /* ACM */ + if (prAcQueParams->ucIsACMSet != ((prWmmAcParams->ucAciAifsn & + WMM_ACIAIFSN_ACM) ? TRUE : FALSE)) + return FALSE; + + /* AIFSN */ + if (prAcQueParams->u2Aifsn != (prWmmAcParams->ucAciAifsn & + WMM_ACIAIFSN_AIFSN)) + return FALSE; + + /* CW Max */ + if (prAcQueParams->u2CWmax != + (BIT((prWmmAcParams->ucEcw & WMM_ECW_WMAX_MASK) >> + WMM_ECW_WMAX_OFFSET) - 1)) + return FALSE; + + /* CW Min */ + if (prAcQueParams->u2CWmin != (BIT(prWmmAcParams->ucEcw & + WMM_ECW_WMIN_MASK) - 1)) + return FALSE; + + if (prAcQueParams->u2TxopLimit != + prWmmAcParams->u2TxopLimit) + return FALSE; + } + + return TRUE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is used for parsing EDCA parameters specified in the + * WMM Parameter IE + * + * \param[in] prAdapter Adapter pointer + * \param[in] prIeWmmParam The pointer to the WMM Parameter IE + * \param[in] u4AcOffset The offset specifying the AC queue for parsing + * \param[in] prHwAcParams The parameter structure used to configure the + * HW CRs + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void mqmFillAcQueParam(IN struct IE_WMM_PARAM *prIeWmmParam, + IN uint32_t u4AcOffset, + OUT struct AC_QUE_PARMS *prAcQueParams) +{ + struct WMM_AC_PARAM *prAcParam = + &prIeWmmParam->arAcParam[u4AcOffset]; + + prAcQueParams->ucIsACMSet = (prAcParam->ucAciAifsn & + WMM_ACIAIFSN_ACM) ? TRUE : FALSE; + + prAcQueParams->u2Aifsn = (prAcParam->ucAciAifsn & + WMM_ACIAIFSN_AIFSN); + + prAcQueParams->u2CWmax = BIT((prAcParam->ucEcw & + WMM_ECW_WMAX_MASK) >> WMM_ECW_WMAX_OFFSET) - 1; + + prAcQueParams->u2CWmin = BIT(prAcParam->ucEcw & + WMM_ECW_WMIN_MASK) - 1; + + WLAN_GET_FIELD_16(&prAcParam->u2TxopLimit, + &prAcQueParams->u2TxopLimit); + + prAcQueParams->ucGuradTime = + TXM_DEFAULT_FLUSH_QUEUE_GUARD_TIME; + +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief To parse WMM/11n related IEs in scan results (only for AP peers) + * + * \param[in] prAdapter Adapter pointer + * \param[in] prScanResult The scan result which shall be parsed to + * obtain needed info + * \param[out] prStaRec The obtained info is stored in the STA_REC + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void mqmProcessScanResult(IN struct ADAPTER *prAdapter, + IN struct BSS_DESC *prScanResult, + OUT struct STA_RECORD *prStaRec) +{ + uint8_t *pucIE; + uint16_t u2IELength; + uint16_t u2Offset; + uint8_t aucWfaOui[] = VENDOR_OUI_WFA; + u_int8_t fgIsHtVht; + + DEBUGFUNC("mqmProcessScanResult"); + + ASSERT(prScanResult); + ASSERT(prStaRec); + + /* Reset the flag before parsing */ + prStaRec->fgIsWmmSupported = FALSE; + prStaRec->fgIsUapsdSupported = FALSE; + prStaRec->fgIsQoS = FALSE; +#if (CFG_SUPPORT_802_11AX == 1) + prStaRec->fgIsMuEdcaSupported = FALSE; +#endif + + fgIsHtVht = FALSE; + + if (IS_FEATURE_DISABLED(prAdapter->rWifiVar.ucQoS)) + return; + + u2IELength = prScanResult->u2IELength; + pucIE = prScanResult->aucIEBuf; + + /* <1> Determine whether the peer supports WMM/QoS and UAPSDU */ + IE_FOR_EACH(pucIE, u2IELength, u2Offset) { + switch (IE_ID(pucIE)) { + + case ELEM_ID_EXTENDED_CAP: +#if CFG_SUPPORT_TDLS + TdlsBssExtCapParse(prStaRec, pucIE); +#endif /* CFG_SUPPORT_TDLS */ +#if CFG_SUPPORT_802_11V_BSS_TRANSITION_MGT + prStaRec->fgSupportBTM = + !!((*(uint32_t *)(pucIE + 2)) & + BIT(ELEM_EXT_CAP_BSS_TRANSITION_BIT)); +#endif + break; + + case ELEM_ID_WMM: + if ((WMM_IE_OUI_TYPE(pucIE) == VENDOR_OUI_TYPE_WMM) && + (!kalMemCmp(WMM_IE_OUI(pucIE), aucWfaOui, 3))) { + struct IE_WMM_PARAM *prWmmParam = + (struct IE_WMM_PARAM *)pucIE; + enum ENUM_ACI eAci; + + switch (WMM_IE_OUI_SUBTYPE(pucIE)) { + case VENDOR_OUI_SUBTYPE_WMM_PARAM: + /* WMM Param IE with a wrong length */ + if (IE_LEN(pucIE) != 24) + break; + prStaRec->fgIsWmmSupported = TRUE; + prStaRec->fgIsUapsdSupported = + !!(prWmmParam->ucQosInfo & + WMM_QOS_INFO_UAPSD); + for (eAci = ACI_BE; eAci < ACI_NUM; + eAci++) + prStaRec->afgAcmRequired + [eAci] = !!( + prWmmParam + ->arAcParam + [eAci] + .ucAciAifsn & + WMM_ACIAIFSN_ACM); + DBGLOG(WMM, INFO, + "WMM: " MACSTR + "ACM BK=%d BE=%d VI=%d VO=%d\n", + MAC2STR(prStaRec->aucMacAddr), + prStaRec->afgAcmRequired[ACI_BK], + prStaRec->afgAcmRequired[ACI_BE], + prStaRec->afgAcmRequired[ACI_VI], + prStaRec->afgAcmRequired + [ACI_VO]); + break; + + case VENDOR_OUI_SUBTYPE_WMM_INFO: + /* WMM Info IE with a wrong length */ + if (IE_LEN(pucIE) != 7) + break; + prStaRec->fgIsWmmSupported = TRUE; + prStaRec->fgIsUapsdSupported = + (((( + (struct IE_WMM_INFO *) + pucIE)->ucQosInfo) + & WMM_QOS_INFO_UAPSD) + ? TRUE : FALSE); + break; + + default: + /* A WMM QoS IE that doesn't matter. + * Ignore it. + */ + break; + } + } + break; + + default: + /* A WMM IE that doesn't matter. Ignore it. */ + break; + } + } + + /* <1> Determine QoS */ + if (prStaRec->ucDesiredPhyTypeSet & (PHY_TYPE_SET_802_11N | + PHY_TYPE_SET_802_11AC)) + fgIsHtVht = TRUE; + + if (fgIsHtVht || prStaRec->fgIsWmmSupported) + prStaRec->fgIsQoS = TRUE; + +#if (CFG_SUPPORT_802_11AX == 1) + if (fgEfuseCtrlAxOn == 1) { + if (prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_SET_802_11AX) + prStaRec->fgIsQoS = TRUE; + } +#endif + +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Generate the WMM Info IE by Param + * + * \param[in] prAdapter Adapter pointer + * @param prMsduInfo The TX MMPDU + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +uint32_t +mqmFillWmmInfoIE(uint8_t *pucOutBuf, + u_int8_t fgSupportUAPSD, uint8_t ucBmpDeliveryAC, + uint8_t ucBmpTriggerAC, uint8_t ucUapsdSp) +{ + struct IE_WMM_INFO *prIeWmmInfo; + uint32_t ucUapsd[] = { + WMM_QOS_INFO_BE_UAPSD, + WMM_QOS_INFO_BK_UAPSD, + WMM_QOS_INFO_VI_UAPSD, + WMM_QOS_INFO_VO_UAPSD + }; + uint8_t aucWfaOui[] = VENDOR_OUI_WFA; + + ASSERT(pucOutBuf); + + prIeWmmInfo = (struct IE_WMM_INFO *) pucOutBuf; + + prIeWmmInfo->ucId = ELEM_ID_WMM; + prIeWmmInfo->ucLength = ELEM_MAX_LEN_WMM_INFO; + + /* WMM-2.2.1 WMM Information Element Field Values */ + prIeWmmInfo->aucOui[0] = aucWfaOui[0]; + prIeWmmInfo->aucOui[1] = aucWfaOui[1]; + prIeWmmInfo->aucOui[2] = aucWfaOui[2]; + prIeWmmInfo->ucOuiType = VENDOR_OUI_TYPE_WMM; + prIeWmmInfo->ucOuiSubtype = VENDOR_OUI_SUBTYPE_WMM_INFO; + + prIeWmmInfo->ucVersion = VERSION_WMM; + prIeWmmInfo->ucQosInfo = 0; + + /* UAPSD initial queue configurations (delivery and trigger enabled) */ + if (fgSupportUAPSD) { + uint8_t ucQosInfo = 0; + uint8_t i; + + /* Static U-APSD setting */ + for (i = ACI_BE; i <= ACI_VO; i++) { + if (ucBmpDeliveryAC & ucBmpTriggerAC & BIT(i)) + ucQosInfo |= (uint8_t) ucUapsd[i]; + } + + if (ucBmpDeliveryAC & ucBmpTriggerAC) { + switch (ucUapsdSp) { + case WMM_MAX_SP_LENGTH_ALL: + ucQosInfo |= WMM_QOS_INFO_MAX_SP_ALL; + break; + + case WMM_MAX_SP_LENGTH_2: + ucQosInfo |= WMM_QOS_INFO_MAX_SP_2; + break; + + case WMM_MAX_SP_LENGTH_4: + ucQosInfo |= WMM_QOS_INFO_MAX_SP_4; + break; + + case WMM_MAX_SP_LENGTH_6: + ucQosInfo |= WMM_QOS_INFO_MAX_SP_6; + break; + + default: + DBGLOG(QM, INFO, "MQM: Incorrect SP length\n"); + ucQosInfo |= WMM_QOS_INFO_MAX_SP_2; + break; + } + } + prIeWmmInfo->ucQosInfo = ucQosInfo; + + } + + /* Increment the total IE length + * for the Element ID and Length fields. + */ + return IE_SIZE(prIeWmmInfo); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Generate the WMM Info IE + * + * \param[in] prAdapter Adapter pointer + * @param prMsduInfo The TX MMPDU + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +uint32_t +mqmGenerateWmmInfoIEByStaRec(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, struct STA_RECORD *prStaRec, + uint8_t *pucOutBuf) +{ + struct PM_PROFILE_SETUP_INFO *prPmProfSetupInfo; + u_int8_t fgSupportUapsd; + + ASSERT(pucOutBuf); + + /* In case QoS is not turned off, exit directly */ + if (IS_FEATURE_DISABLED(prAdapter->rWifiVar.ucQoS)) + return 0; + + if (prStaRec == NULL) + return 0; + + if (!prStaRec->fgIsQoS) + return 0; + + prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; + + fgSupportUapsd = (IS_FEATURE_ENABLED( + prAdapter->rWifiVar.ucUapsd) && + prStaRec->fgIsUapsdSupported); + + return mqmFillWmmInfoIE(pucOutBuf, + fgSupportUapsd, + prPmProfSetupInfo->ucBmpDeliveryAC, + prPmProfSetupInfo->ucBmpTriggerAC, + prPmProfSetupInfo->ucUapsdSp); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Generate the WMM Info IE + * + * \param[in] prAdapter Adapter pointer + * @param prMsduInfo The TX MMPDU + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void mqmGenerateWmmInfoIE(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo) +{ + struct BSS_INFO *prBssInfo; + struct STA_RECORD *prStaRec; + uint32_t u4Length; + + DEBUGFUNC("mqmGenerateWmmInfoIE"); + + ASSERT(prMsduInfo); + + prStaRec = cnmGetStaRecByIndex(prAdapter, + prMsduInfo->ucStaRecIndex); + ASSERT(prStaRec); + + if (prStaRec == NULL) + return; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prStaRec->ucBssIndex); + + u4Length = mqmGenerateWmmInfoIEByStaRec(prAdapter, + prBssInfo, prStaRec, + ((uint8_t *) prMsduInfo->prPacket + + prMsduInfo->u2FrameLength)); + + prMsduInfo->u2FrameLength += u4Length; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Generate the WMM Param IE + * + * \param[in] prAdapter Adapter pointer + * @param prMsduInfo The TX MMPDU + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void mqmGenerateWmmParamIE(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo) +{ + struct IE_WMM_PARAM *prIeWmmParam; + + uint8_t aucWfaOui[] = VENDOR_OUI_WFA; + + uint8_t aucACI[] = { + WMM_ACI_AC_BE, + WMM_ACI_AC_BK, + WMM_ACI_AC_VI, + WMM_ACI_AC_VO + }; + + struct BSS_INFO *prBssInfo; + struct STA_RECORD *prStaRec; + enum ENUM_WMM_ACI eAci; + struct WMM_AC_PARAM *prAcParam; + + DEBUGFUNC("mqmGenerateWmmParamIE"); + DBGLOG(QM, LOUD, "\n"); + + ASSERT(prMsduInfo); + + /* In case QoS is not turned off, exit directly */ + if (IS_FEATURE_DISABLED(prAdapter->rWifiVar.ucQoS)) + return; + + prStaRec = cnmGetStaRecByIndex(prAdapter, + prMsduInfo->ucStaRecIndex); + + if (prStaRec) { + if (!prStaRec->fgIsQoS) + return; + } + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prMsduInfo->ucBssIndex); + + if (!prBssInfo->fgIsQBSS) + return; + + prIeWmmParam = (struct IE_WMM_PARAM *) + ((uint8_t *) prMsduInfo->prPacket + + prMsduInfo->u2FrameLength); + + prIeWmmParam->ucId = ELEM_ID_WMM; + prIeWmmParam->ucLength = ELEM_MAX_LEN_WMM_PARAM; + + /* WMM-2.2.1 WMM Information Element Field Values */ + prIeWmmParam->aucOui[0] = aucWfaOui[0]; + prIeWmmParam->aucOui[1] = aucWfaOui[1]; + prIeWmmParam->aucOui[2] = aucWfaOui[2]; + prIeWmmParam->ucOuiType = VENDOR_OUI_TYPE_WMM; + prIeWmmParam->ucOuiSubtype = VENDOR_OUI_SUBTYPE_WMM_PARAM; + + prIeWmmParam->ucVersion = VERSION_WMM; + prIeWmmParam->ucQosInfo = (prBssInfo->ucWmmParamSetCount & + WMM_QOS_INFO_PARAM_SET_CNT); + + /* UAPSD initial queue configurations (delivery and trigger enabled) */ + if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucUapsd)) + prIeWmmParam->ucQosInfo |= WMM_QOS_INFO_UAPSD; + + /* EDCA parameter */ + + for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { + prAcParam = &prIeWmmParam->arAcParam[eAci]; + + /* ACI */ + prAcParam->ucAciAifsn = aucACI[eAci]; + /* ACM */ + if (prBssInfo->arACQueParmsForBcast[eAci].ucIsACMSet) + prAcParam->ucAciAifsn |= WMM_ACIAIFSN_ACM; + /* AIFSN */ + prAcParam->ucAciAifsn |= + (prBssInfo->arACQueParmsForBcast[eAci].u2Aifsn & + WMM_ACIAIFSN_AIFSN); + + /* ECW Min */ + prAcParam->ucEcw = (prBssInfo->aucCWminLog2ForBcast[eAci] & + WMM_ECW_WMIN_MASK); + /* ECW Max */ + prAcParam->ucEcw |= + ((prBssInfo->aucCWmaxLog2ForBcast[eAci] << + WMM_ECW_WMAX_OFFSET) & WMM_ECW_WMAX_MASK); + + /* Txop limit */ + WLAN_SET_FIELD_16(&prAcParam->u2TxopLimit, + prBssInfo->arACQueParmsForBcast[eAci].u2TxopLimit); + + } + + /* Increment the total IE length + * for the Element ID and Length fields. + */ + prMsduInfo->u2FrameLength += IE_SIZE(prIeWmmParam); + +} + +#if CFG_SUPPORT_TDLS +/*----------------------------------------------------------------------------*/ +/*! + * @brief Generate the WMM Param IE + * + * \param[in] prAdapter Adapter pointer + * @param prMsduInfo The TX MMPDU + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +uint32_t mqmGenerateWmmParamIEByParam(struct ADAPTER *prAdapter, + struct BSS_INFO *prBssInfo, uint8_t *pOutBuf) +{ + struct IE_WMM_PARAM *prIeWmmParam; + + uint8_t aucWfaOui[] = VENDOR_OUI_WFA; + + uint8_t aucACI[] = { + WMM_ACI_AC_BE, + WMM_ACI_AC_BK, + WMM_ACI_AC_VI, + WMM_ACI_AC_VO + }; + + struct AC_QUE_PARMS *prACQueParms; + /* BE, BK, VO, VI */ + uint8_t auCWminLog2ForBcast[WMM_AC_INDEX_NUM] = {4, 4, 3, 2}; + uint8_t auCWmaxLog2ForBcast[WMM_AC_INDEX_NUM] = {10, 10, 4, 3}; + uint8_t auAifsForBcast[WMM_AC_INDEX_NUM] = {3, 7, 2, 2}; + /* If the AP is OFDM */ + uint8_t auTxopForBcast[WMM_AC_INDEX_NUM] = {0, 0, 94, 47}; + + enum ENUM_WMM_ACI eAci; + struct WMM_AC_PARAM *prAcParam; + + DEBUGFUNC("mqmGenerateWmmParamIE"); + DBGLOG(QM, LOUD, "\n"); + + ASSERT(pOutBuf); + + /* In case QoS is not turned off, exit directly */ + if (IS_FEATURE_DISABLED(prAdapter->rWifiVar.ucQoS)) + return WLAN_STATUS_SUCCESS; + + if (!prBssInfo->fgIsQBSS) + return WLAN_STATUS_SUCCESS; + + if (IS_FEATURE_ENABLED( + prAdapter->rWifiVar.fgTdlsBufferSTASleep)) { + prACQueParms = prBssInfo->arACQueParmsForBcast; + + for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { + prACQueParms[eAci].ucIsACMSet = FALSE; + prACQueParms[eAci].u2Aifsn = auAifsForBcast[eAci]; + prACQueParms[eAci].u2CWmin = + BIT(auCWminLog2ForBcast[eAci]) - 1; + prACQueParms[eAci].u2CWmax = + BIT(auCWmaxLog2ForBcast[eAci]) - 1; + prACQueParms[eAci].u2TxopLimit = auTxopForBcast[eAci]; + + /* used to send WMM IE */ + prBssInfo->aucCWminLog2ForBcast[eAci] = + auCWminLog2ForBcast[eAci]; + prBssInfo->aucCWmaxLog2ForBcast[eAci] = + auCWmaxLog2ForBcast[eAci]; + } + } + + prIeWmmParam = (struct IE_WMM_PARAM *) pOutBuf; + + prIeWmmParam->ucId = ELEM_ID_WMM; + prIeWmmParam->ucLength = ELEM_MAX_LEN_WMM_PARAM; + + /* WMM-2.2.1 WMM Information Element Field Values */ + prIeWmmParam->aucOui[0] = aucWfaOui[0]; + prIeWmmParam->aucOui[1] = aucWfaOui[1]; + prIeWmmParam->aucOui[2] = aucWfaOui[2]; + prIeWmmParam->ucOuiType = VENDOR_OUI_TYPE_WMM; + prIeWmmParam->ucOuiSubtype = VENDOR_OUI_SUBTYPE_WMM_PARAM; + + prIeWmmParam->ucVersion = VERSION_WMM; + /* STAUT Buffer STA, also sleeps (optional) + * The STAUT sends a TDLS Setup/Response/Confirm Frame, + * with all four AC flags set to 1 in QoS Info Field + * to STA 2, via the AP, + */ + if (IS_FEATURE_ENABLED( + prAdapter->rWifiVar.fgTdlsBufferSTASleep)) + prIeWmmParam->ucQosInfo = (0x0F & + WMM_QOS_INFO_PARAM_SET_CNT); + else + prIeWmmParam->ucQosInfo = (prBssInfo->ucWmmParamSetCount & + WMM_QOS_INFO_PARAM_SET_CNT); + + /* UAPSD initial queue configurations (delivery and trigger enabled) */ + if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucUapsd)) + prIeWmmParam->ucQosInfo |= WMM_QOS_INFO_UAPSD; + + /* EDCA parameter */ + + for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { + prAcParam = &prIeWmmParam->arAcParam[eAci]; + /* ACI */ + prAcParam->ucAciAifsn = aucACI[eAci]; + /* ACM */ + if (prBssInfo->arACQueParmsForBcast[eAci].ucIsACMSet) + prAcParam->ucAciAifsn |= WMM_ACIAIFSN_ACM; + /* AIFSN */ + prAcParam->ucAciAifsn |= + (prBssInfo->arACQueParmsForBcast[eAci].u2Aifsn & + WMM_ACIAIFSN_AIFSN); + + /* ECW Min */ + prAcParam->ucEcw = (prBssInfo->aucCWminLog2ForBcast[eAci] & + WMM_ECW_WMIN_MASK); + /* ECW Max */ + prAcParam->ucEcw |= + ((prBssInfo->aucCWmaxLog2ForBcast[eAci] << + WMM_ECW_WMAX_OFFSET) & WMM_ECW_WMAX_MASK); + + /* Txop limit */ + WLAN_SET_FIELD_16(&prAcParam->u2TxopLimit, + prBssInfo->arACQueParmsForBcast[eAci].u2TxopLimit); + + } + + /* Increment the total IE length + * for the Element ID and Length fields. + */ + return IE_SIZE(prIeWmmParam); + +} + +#endif + +u_int8_t isProbeResponse(IN struct MSDU_INFO *prMgmtTxMsdu) +{ + struct WLAN_MAC_HEADER *prWlanHdr = + (struct WLAN_MAC_HEADER *) NULL; + + prWlanHdr = + (struct WLAN_MAC_HEADER *) ((unsigned long) + prMgmtTxMsdu->prPacket + MAC_TX_RESERVED_FIELD); + + return (prWlanHdr->u2FrameCtrl & MASK_FRAME_TYPE) == + MAC_FRAME_PROBE_RSP ? TRUE : FALSE; +} + + +enum ENUM_FRAME_ACTION qmGetFrameAction(IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex, + IN uint8_t ucStaRecIdx, IN struct MSDU_INFO *prMsduInfo, + IN enum ENUM_FRAME_TYPE_IN_CMD_Q eFrameType, + IN uint16_t u2FrameLength) +{ + enum ENUM_FRAME_ACTION eFrameAction = FRAME_ACTION_TX_PKT; + struct BSS_INFO *prBssInfo; + struct STA_RECORD *prStaRec; + uint8_t ucTC = nicTxGetFrameResourceType(eFrameType, prMsduInfo); + uint16_t u2FreeResource = nicTxGetResource(prAdapter, ucTC); + uint8_t ucReqResource; + struct WIFI_VAR *prWifiVar = &prAdapter->rWifiVar; + + DEBUGFUNC("qmGetFrameAction"); + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, ucStaRecIdx); + + do { + /* 4 <1> Tx, if FORCE_TX is set */ + if (prMsduInfo) { + if (prMsduInfo->ucControlFlag & + MSDU_CONTROL_FLAG_FORCE_TX) { + eFrameAction = FRAME_ACTION_TX_PKT; + break; + } + } + /* 4 <2> Drop, if BSS is inactive */ + if (!IS_BSS_ACTIVE(prBssInfo)) { + DBGLOG(QM, TRACE, + "Drop packets (BSS[%u] is INACTIVE)\n", + prBssInfo->ucBssIndex); + eFrameAction = FRAME_ACTION_DROP_PKT; + break; + } + + /* 4 <3> Queue, if BSS is absent, drop probe response */ + if (prBssInfo->fgIsNetAbsent) { + if (prMsduInfo && isProbeResponse(prMsduInfo)) { + DBGLOG(TX, TRACE, + "Drop probe response (BSS[%u] Absent)\n", + prBssInfo->ucBssIndex); + + eFrameAction = FRAME_ACTION_DROP_PKT; + } else { + DBGLOG(TX, TRACE, + "Queue packets (BSS[%u] Absent)\n", + prBssInfo->ucBssIndex); + eFrameAction = FRAME_ACTION_QUEUE_PKT; + } + break; + } + + /* 4 <4> Check based on StaRec */ + if (prStaRec) { + /* 4 <4.1> Drop, if StaRec is not in use */ + if (!prStaRec->fgIsInUse) { + DBGLOG(QM, TRACE, + "Drop packets (Sta[%u] not in USE)\n", + prStaRec->ucIndex); + eFrameAction = FRAME_ACTION_DROP_PKT; + break; + } + /* 4 <4.2> Sta in PS */ + if (prStaRec->fgIsInPS) { + ucReqResource = nicTxGetPageCount(prAdapter, + u2FrameLength, FALSE) + + prWifiVar->ucCmdRsvResource + + QM_MGMT_QUEUED_THRESHOLD; + + /* 4 <4.2.1> Tx, if resource is enough */ + if (u2FreeResource > ucReqResource) { + eFrameAction = FRAME_ACTION_TX_PKT; + break; + } + /* 4 <4.2.2> Queue, if resource is not enough */ + else { + DBGLOG(QM, INFO, + "Queue packets (Sta[%u] in PS)\n", + prStaRec->ucIndex); + eFrameAction = FRAME_ACTION_QUEUE_PKT; + break; + } + } + } + + } while (FALSE); + + /* <5> Resource CHECK! */ + /* <5.1> Reserve resource for CMD & 1X */ + if (eFrameType == FRAME_TYPE_MMPDU) { + ucReqResource = nicTxGetPageCount(prAdapter, u2FrameLength, + FALSE) + prWifiVar->ucCmdRsvResource; + + if (u2FreeResource < ucReqResource) { + eFrameAction = FRAME_ACTION_QUEUE_PKT; + DBGLOG(QM, INFO, + "Queue MGMT (MSDU[0x%p] Req/Rsv/Free[%u/%u/%u])\n", + prMsduInfo, + nicTxGetPageCount(prAdapter, + u2FrameLength, FALSE), + prWifiVar->ucCmdRsvResource, u2FreeResource); + } + + /* <6> Timeout check! */ +#if CFG_ENABLE_PKT_LIFETIME_PROFILE + if ((eFrameAction == FRAME_ACTION_QUEUE_PKT) && prMsduInfo) { + OS_SYSTIME rCurrentTime, rEnqTime; + + GET_CURRENT_SYSTIME(&rCurrentTime); + rEnqTime = prMsduInfo->rPktProfile.rEnqueueTimestamp; + + if (CHECK_FOR_TIMEOUT(rCurrentTime, rEnqTime, + MSEC_TO_SYSTIME( + prWifiVar->u4MgmtQueueDelayTimeout))) { + eFrameAction = FRAME_ACTION_DROP_PKT; + log_dbg(QM, INFO, "Drop MGMT (MSDU[0x%p] timeout[%ums])\n", + prMsduInfo, + prWifiVar->u4MgmtQueueDelayTimeout); + } + } +#endif + } + + return eFrameAction; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Handle BSS change operation Event from the FW + * + * \param[in] prAdapter Adapter pointer + * \param[in] prEvent The event packet from the FW + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void qmHandleEventBssAbsencePresence(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ + struct EVENT_BSS_ABSENCE_PRESENCE *prEventBssStatus; + struct BSS_INFO *prBssInfo; + u_int8_t fgIsNetAbsentOld; + + prEventBssStatus = (struct EVENT_BSS_ABSENCE_PRESENCE *) ( + prEvent->aucBuffer); + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prEventBssStatus->ucBssIndex); + fgIsNetAbsentOld = prBssInfo->fgIsNetAbsent; + prBssInfo->fgIsNetAbsent = prEventBssStatus->ucIsAbsent; + prBssInfo->ucBssFreeQuota = prEventBssStatus->ucBssFreeQuota; + + DBGLOG(QM, INFO, "NAF=%d,%d,%d\n", + prEventBssStatus->ucBssIndex, prBssInfo->fgIsNetAbsent, + prBssInfo->ucBssFreeQuota); + + if (!prBssInfo->fgIsNetAbsent) { + /* ToDo:: QM_DBG_CNT_INC */ + QM_DBG_CNT_INC(&(prAdapter->rQM), QM_DBG_CNT_27); + } else { + /* ToDo:: QM_DBG_CNT_INC */ + QM_DBG_CNT_INC(&(prAdapter->rQM), QM_DBG_CNT_28); + } + /* From Absent to Present */ + if ((fgIsNetAbsentOld) && (!prBssInfo->fgIsNetAbsent)) { + if (HAL_IS_TX_DIRECT(prAdapter)) + nicTxDirectStartCheckQTimer(prAdapter); + else { +#if QM_ADAPTIVE_TC_RESOURCE_CTRL + prAdapter->rQM.fgForceReassign = TRUE; +#endif + kalSetEvent(prAdapter->prGlueInfo); + } + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Handle STA change PS mode Event from the FW + * + * \param[in] prAdapter Adapter pointer + * \param[in] prEvent The event packet from the FW + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void qmHandleEventStaChangePsMode(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ + struct EVENT_STA_CHANGE_PS_MODE *prEventStaChangePsMode; + struct STA_RECORD *prStaRec; + u_int8_t fgIsInPSOld; + + /* DbgPrint("QM:Event -RxBa\n"); */ + + prEventStaChangePsMode = (struct EVENT_STA_CHANGE_PS_MODE *) + (prEvent->aucBuffer); + prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, + prEventStaChangePsMode->ucStaRecIdx); + /* ASSERT(prStaRec); */ + + if (prStaRec) { + + fgIsInPSOld = prStaRec->fgIsInPS; + prStaRec->fgIsInPS = prEventStaChangePsMode->ucIsInPs; + + qmUpdateFreeQuota(prAdapter, + prStaRec, + prEventStaChangePsMode->ucUpdateMode, + prEventStaChangePsMode->ucFreeQuota); + + DBGLOG(QM, INFO, "PS=%d,%d\n", + prEventStaChangePsMode->ucStaRecIdx, + prStaRec->fgIsInPS); + + /* From PS to Awake */ + if ((fgIsInPSOld) && (!prStaRec->fgIsInPS)) { + if (HAL_IS_TX_DIRECT(prAdapter)) + nicTxDirectStartCheckQTimer(prAdapter); + else { +#if QM_ADAPTIVE_TC_RESOURCE_CTRL + prAdapter->rQM.fgForceReassign = TRUE; +#endif + kalSetEvent(prAdapter->prGlueInfo); + } + } + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Update STA free quota Event from FW + * + * \param[in] prAdapter Adapter pointer + * \param[in] prEvent The event packet from the FW + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void qmHandleEventStaUpdateFreeQuota(IN struct ADAPTER *prAdapter, + IN struct WIFI_EVENT *prEvent) +{ + struct EVENT_STA_UPDATE_FREE_QUOTA + *prEventStaUpdateFreeQuota; + struct STA_RECORD *prStaRec; + + prEventStaUpdateFreeQuota = (struct + EVENT_STA_UPDATE_FREE_QUOTA *) (prEvent->aucBuffer); + prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, + prEventStaUpdateFreeQuota->ucStaRecIdx); + /* 2013/08/30 + * Station Record possible been freed. + */ + /* ASSERT(prStaRec); */ + + if (prStaRec) { + if (prStaRec->fgIsInPS) { + qmUpdateFreeQuota(prAdapter, + prStaRec, + prEventStaUpdateFreeQuota->ucUpdateMode, + prEventStaUpdateFreeQuota->ucFreeQuota); + + if (HAL_IS_TX_DIRECT(prAdapter)) + nicTxDirectStartCheckQTimer(prAdapter); + else + kalSetEvent(prAdapter->prGlueInfo); + } + DBGLOG(QM, TRACE, "UFQ=%d,%d,%d\n", + prEventStaUpdateFreeQuota->ucStaRecIdx, + prEventStaUpdateFreeQuota->ucUpdateMode, + prEventStaUpdateFreeQuota->ucFreeQuota); + + } + +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Update STA free quota + * + * \param[in] prStaRec the STA + * \param[in] ucUpdateMode the method to update free quota + * \param[in] ucFreeQuota the value for update + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void +qmUpdateFreeQuota(IN struct ADAPTER *prAdapter, + IN struct STA_RECORD *prStaRec, IN uint8_t ucUpdateMode, + IN uint8_t ucFreeQuota) +{ + + uint8_t ucFreeQuotaForNonDelivery; + uint8_t ucFreeQuotaForDelivery; + + ASSERT(prStaRec); + DBGLOG(QM, LOUD, + "qmUpdateFreeQuota orig ucFreeQuota=%d Mode %u New %u\n", + prStaRec->ucFreeQuota, ucUpdateMode, ucFreeQuota); + + if (!prStaRec->fgIsInPS) + return; + + switch (ucUpdateMode) { + case FREE_QUOTA_UPDATE_MODE_INIT: + case FREE_QUOTA_UPDATE_MODE_OVERWRITE: + prStaRec->ucFreeQuota = ucFreeQuota; + break; + case FREE_QUOTA_UPDATE_MODE_INCREASE: + prStaRec->ucFreeQuota += ucFreeQuota; + break; + case FREE_QUOTA_UPDATE_MODE_DECREASE: + prStaRec->ucFreeQuota -= ucFreeQuota; + break; + default: + ASSERT(0); + } + + DBGLOG(QM, LOUD, "qmUpdateFreeQuota new ucFreeQuota=%d)\n", + prStaRec->ucFreeQuota); + + ucFreeQuota = prStaRec->ucFreeQuota; + + ucFreeQuotaForNonDelivery = 0; + ucFreeQuotaForDelivery = 0; + + if (ucFreeQuota > 0) { + if (prStaRec->fgIsQoS && prStaRec->fgIsUapsdSupported + /* && prAdapter->rWifiVar.fgSupportQoS */ + /* && prAdapter->rWifiVar.fgSupportUAPSD */) { + /* XXX We should assign quota to + * aucFreeQuotaPerQueue[NUM_OF_PER_STA_TX_QUEUES] + */ + + if (prStaRec->ucFreeQuotaForNonDelivery > 0 + && prStaRec->ucFreeQuotaForDelivery > 0) { + ucFreeQuotaForNonDelivery = ucFreeQuota >> 1; + ucFreeQuotaForDelivery = ucFreeQuota - + ucFreeQuotaForNonDelivery; + } else if (prStaRec->ucFreeQuotaForNonDelivery == 0 + && prStaRec->ucFreeQuotaForDelivery == 0) { + ucFreeQuotaForNonDelivery = ucFreeQuota >> 1; + ucFreeQuotaForDelivery = ucFreeQuota - + ucFreeQuotaForNonDelivery; + } else if (prStaRec->ucFreeQuotaForNonDelivery > 0) { + /* NonDelivery is not busy */ + if (ucFreeQuota >= 3) { + ucFreeQuotaForNonDelivery = 2; + ucFreeQuotaForDelivery = ucFreeQuota - + ucFreeQuotaForNonDelivery; + } else { + ucFreeQuotaForDelivery = ucFreeQuota; + ucFreeQuotaForNonDelivery = 0; + } + } else if (prStaRec->ucFreeQuotaForDelivery > 0) { + /* Delivery is not busy */ + if (ucFreeQuota >= 3) { + ucFreeQuotaForDelivery = 2; + ucFreeQuotaForNonDelivery = + ucFreeQuota - + ucFreeQuotaForDelivery; + } else { + ucFreeQuotaForNonDelivery = ucFreeQuota; + ucFreeQuotaForDelivery = 0; + } + } + + } else { + /* !prStaRec->fgIsUapsdSupported */ + ucFreeQuotaForNonDelivery = ucFreeQuota; + ucFreeQuotaForDelivery = 0; + } + } + /* ucFreeQuota > 0 */ + prStaRec->ucFreeQuotaForDelivery = ucFreeQuotaForDelivery; + prStaRec->ucFreeQuotaForNonDelivery = + ucFreeQuotaForNonDelivery; + + DBGLOG(QM, LOUD, + "new QuotaForDelivery = %d QuotaForNonDelivery = %d\n", + prStaRec->ucFreeQuotaForDelivery, + prStaRec->ucFreeQuotaForNonDelivery); + +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Return the reorder queued RX packets + * + * \param[in] (none) + * + * \return The number of queued RX packets + */ +/*----------------------------------------------------------------------------*/ +uint32_t qmGetRxReorderQueuedBufferCount(IN struct ADAPTER *prAdapter) +{ + uint32_t i, u4Total; + struct QUE_MGT *prQM = &prAdapter->rQM; + + u4Total = 0; + /* XXX The summation may impact the performance */ + for (i = 0; i < CFG_NUM_OF_RX_BA_AGREEMENTS; i++) { + u4Total += prQM->arRxBaTable[i].rReOrderQue.u4NumElem; +#if DBG && 0 + if (QUEUE_IS_EMPTY(&(prQM->arRxBaTable[i].rReOrderQue))) + ASSERT(prQM->arRxBaTable[i].rReOrderQue == 0); +#endif + } + ASSERT(u4Total <= (CFG_NUM_OF_QM_RX_PKT_NUM * 2)); + return u4Total; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Dump current queue status + * + * \param[in] (none) + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +uint32_t qmDumpQueueStatus(IN struct ADAPTER *prAdapter, + IN uint8_t *pucBuf, IN uint32_t u4Max) +{ + struct TX_CTRL *prTxCtrl; + struct QUE_MGT *prQM; + struct GLUE_INFO *prGlueInfo; + uint32_t i, u4TotalBufferCount, u4TotalPageCount; + uint32_t u4CurBufferCount, u4CurPageCount; + uint32_t u4Len = 0; + + DEBUGFUNC(("%s", __func__)); + + ASSERT(prAdapter); + + prTxCtrl = &prAdapter->rTxCtrl; + prQM = &prAdapter->rQM; + prGlueInfo = prAdapter->prGlueInfo; + u4TotalBufferCount = 0; + u4TotalPageCount = 0; + u4CurBufferCount = 0; + u4CurPageCount = 0; + + LOGBUF(pucBuf, u4Max, u4Len, "\n"); + LOGBUF(pucBuf, u4Max, u4Len, + "------------\n"); + + for (i = TC0_INDEX; i < TC_NUM; i++) { + LOGBUF(pucBuf, u4Max, u4Len, + "TC%u ResCount: Max[%02u/%03u] Free[%02u/%03u] PreUsed[%03u]\n", + i, prTxCtrl->rTc.au4MaxNumOfBuffer[i], + prTxCtrl->rTc.au4MaxNumOfPage[i], + prTxCtrl->rTc.au4FreeBufferCount[i], + prTxCtrl->rTc.au4FreePageCount[i], + prTxCtrl->rTc.au4PreUsedPageCount[i]); + + u4TotalBufferCount += prTxCtrl->rTc.au4MaxNumOfBuffer[i]; + u4TotalPageCount += prTxCtrl->rTc.au4MaxNumOfPage[i]; + u4CurBufferCount += prTxCtrl->rTc.au4FreeBufferCount[i]; + u4CurPageCount += prTxCtrl->rTc.au4FreePageCount[i]; + } + + LOGBUF(pucBuf, u4Max, u4Len, + "ToT ResCount: Max[%02u/%03u] Free[%02u/%03u]\n", + u4TotalBufferCount, u4TotalPageCount, u4CurBufferCount, + u4CurPageCount); + + u4TotalBufferCount = 0; + u4TotalPageCount = 0; + u4CurBufferCount = 0; + u4CurPageCount = 0; + LOGBUF(pucBuf, u4Max, u4Len, + "------------\n"); + + for (i = TC0_INDEX; i < TC_NUM; i++) { + LOGBUF(pucBuf, u4Max, u4Len, + "TC%u ResCount: Max[%02u/%03u] Free[%02u/%03u] PreUsed[%03u]\n", + i, prTxCtrl->rTc.au4MaxNumOfBuffer_PLE[i], + prTxCtrl->rTc.au4MaxNumOfPage_PLE[i], + prTxCtrl->rTc.au4FreeBufferCount_PLE[i], + prTxCtrl->rTc.au4FreePageCount_PLE[i], + prTxCtrl->rTc.au4PreUsedPageCount[i]); + + u4TotalBufferCount += prTxCtrl->rTc.au4MaxNumOfBuffer_PLE[i]; + u4TotalPageCount += prTxCtrl->rTc.au4MaxNumOfPage_PLE[i]; + u4CurBufferCount += prTxCtrl->rTc.au4FreeBufferCount_PLE[i]; + u4CurPageCount += prTxCtrl->rTc.au4FreePageCount_PLE[i]; + } + + LOGBUF(pucBuf, u4Max, u4Len, + "ToT ResCount: Max[%02u/%03u] Free[%02u/%03u]\n", + u4TotalBufferCount, u4TotalPageCount, u4CurBufferCount, + u4CurPageCount); + + LOGBUF(pucBuf, u4Max, u4Len, + "---------------------------------\n"); + +#if QM_ADAPTIVE_TC_RESOURCE_CTRL + for (i = TC0_INDEX; i < TC_NUM; i++) { + LOGBUF(pucBuf, u4Max, u4Len, + "TC%u AvgQLen[%04u] minRsv[%02u] CurTcRes[%02u] GrtdTcRes[%02u]\n", + i, QM_GET_TX_QUEUE_LEN(prAdapter, i), + prQM->au4MinReservedTcResource[i], + prQM->au4CurrentTcResource[i], + prQM->au4GuaranteedTcResource[i]); + } + + LOGBUF(pucBuf, u4Max, u4Len, + "Resource Residual[%u] ExtraRsv[%u]\n", + prQM->u4ResidualTcResource, + prQM->u4ExtraReservedTcResource); + LOGBUF(pucBuf, u4Max, u4Len, + "QueLenMovingAvg[%u] Time2AdjResource[%u] Time2UpdateQLen[%u]\n", + prQM->u4QueLenMovingAverage, prQM->u4TimeToAdjustTcResource, + prQM->u4TimeToUpdateQueLen); +#endif + + DBGLOG(SW4, INFO, "---------------------------------\n"); + +#if QM_FORWARDING_FAIRNESS + for (i = 0; i < NUM_OF_PER_STA_TX_QUEUES; i++) { + LOGBUF(pucBuf, u4Max, u4Len, + "TC%u HeadSta[%u] ResourceUsedCount[%u]\n", + i, prQM->au4HeadStaRecIndex[i], + prQM->au4ResourceUsedCount[i]); + } +#endif + + LOGBUF(pucBuf, u4Max, u4Len, + "BMC or unknown TxQueue Len[%u]\n", + prQM->arTxQueue[0].u4NumElem); + LOGBUF(pucBuf, u4Max, u4Len, + "Pending QLen Normal[%u] Sec[%u] Cmd[%u]\n", + GLUE_GET_REF_CNT(prGlueInfo->i4TxPendingFrameNum), + GLUE_GET_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum), + GLUE_GET_REF_CNT(prGlueInfo->i4TxPendingCmdNum)); + +#if defined(LINUX) + for (i = 0; i < prAdapter->ucHwBssIdNum; i++) { + LOGBUF(pucBuf, u4Max, u4Len, + "Pending BSS[%u] QLen[%u:%u:%u:%u]\n", i, + prGlueInfo->ai4TxPendingFrameNumPerQueue[i][0], + prGlueInfo->ai4TxPendingFrameNumPerQueue[i][1], + prGlueInfo->ai4TxPendingFrameNumPerQueue[i][2], + prGlueInfo->ai4TxPendingFrameNumPerQueue[i][3]); + } +#endif + LOGBUF(pucBuf, u4Max, u4Len, "Pending FWD CNT[%d]\n", + prTxCtrl->i4PendingFwdFrameCount); + LOGBUF(pucBuf, u4Max, u4Len, "Pending MGMT CNT[%d]\n", + prTxCtrl->i4TxMgmtPendingNum); + + LOGBUF(pucBuf, u4Max, u4Len, + "---------------------------------\n"); + + LOGBUF(pucBuf, u4Max, u4Len, "Total RFB[%u]\n", + CFG_RX_MAX_PKT_NUM); + LOGBUF(pucBuf, u4Max, u4Len, "rFreeSwRfbList[%u]\n", + prAdapter->rRxCtrl.rFreeSwRfbList.u4NumElem); + LOGBUF(pucBuf, u4Max, u4Len, "rReceivedRfbList[%u]\n", + prAdapter->rRxCtrl.rReceivedRfbList.u4NumElem); + LOGBUF(pucBuf, u4Max, u4Len, "rIndicatedRfbList[%u]\n", + prAdapter->rRxCtrl.rIndicatedRfbList.u4NumElem); + LOGBUF(pucBuf, u4Max, u4Len, "ucNumIndPacket[%u]\n", + prAdapter->rRxCtrl.ucNumIndPacket); + LOGBUF(pucBuf, u4Max, u4Len, "ucNumRetainedPacket[%u]\n", + prAdapter->rRxCtrl.ucNumRetainedPacket); + + LOGBUF(pucBuf, u4Max, u4Len, + "---------------------------------\n"); + LOGBUF(pucBuf, u4Max, u4Len, + "CMD: Free[%u/%u] PQ[%u] CQ[%u] TCQ[%u] TCDQ[%u]\n", + prAdapter->rFreeCmdList.u4NumElem, + CFG_TX_MAX_CMD_PKT_NUM, + prAdapter->rPendingCmdQueue.u4NumElem, + prGlueInfo->rCmdQueue.u4NumElem, + prAdapter->rTxCmdQueue.u4NumElem, + prAdapter->rTxCmdDoneQueue.u4NumElem); + LOGBUF(pucBuf, u4Max, u4Len, + "MSDU: Free[%u/%u] Pending[%u] Done[%u]\n", + prAdapter->rTxCtrl.rFreeMsduInfoList.u4NumElem, + CFG_TX_MAX_PKT_NUM, + prAdapter->rTxCtrl.rTxMgmtTxingQueue.u4NumElem, + prAdapter->rTxDataDoneQueue.u4NumElem); + + LOGBUF(pucBuf, u4Max, u4Len, + "---------------------------------\n"); + if (prGlueInfo->rCmdQueue.u4NumElem > 0) + cmdBufDumpCmdQueue(&prGlueInfo->rCmdQueue, + "waiting Tx CMD queue"); + + return u4Len; +} + +#if CFG_M0VE_BA_TO_DRIVER +/*----------------------------------------------------------------------------*/ +/*! + * @brief Send DELBA Action frame + * + * @param fgIsInitiator DELBA_ROLE_INITIATOR or DELBA_ROLE_RECIPIENT + * @param prStaRec Pointer to the STA_REC of the receiving peer + * @param u4Tid TID of the BA entry + * @param u4ReasonCode The reason code carried in the Action frame + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void +mqmSendDelBaFrame(IN struct ADAPTER *prAdapter, + IN u_int8_t fgIsInitiator, IN struct STA_RECORD *prStaRec, + IN uint32_t u4Tid, IN uint32_t u4ReasonCode) +{ + + struct MSDU_INFO *prTxMsduInfo; + struct ACTION_DELBA_FRAME *prDelBaFrame; + struct BSS_INFO *prBssInfo; + + DBGLOG(QM, WARN, "[Puff]: Enter mqmSendDelBaFrame()\n"); + + ASSERT(prStaRec); + + /* 3 <1> Block the message in case of invalid STA */ + if (!prStaRec->fgIsInUse) { + DBGLOG(QM, WARN, + "[Puff][%s]: (Warning) sta_rec is not inuse\n", + __func__); + return; + } + /* Check HT-capabale STA */ + if (!(prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_BIT_HT)) { + DBGLOG(QM, WARN, + "[Puff][%s]: (Warning) sta is NOT HT-capable(0x%08X)\n", + __func__, + prStaRec->ucDesiredPhyTypeSet); + return; + } + /* 4 <2> Construct the DELBA frame */ + prTxMsduInfo = (struct MSDU_INFO *) cnmMgtPktAlloc( + prAdapter, ACTION_DELBA_FRAME_LEN); + + if (!prTxMsduInfo) { + log_dbg(QM, WARN, "[Puff][%s]: (Warning) DELBA for TID=%ld was not sent (MSDU_INFO alloc failure)\n", + __func__, u4Tid); + return; + } + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prStaRec->ucBssIndex); + + /* Fill the Action frame */ + prDelBaFrame = (struct ACTION_DELBA_FRAME *) + ((uint32_t) (prTxMsduInfo->prPacket) + + MAC_TX_RESERVED_FIELD); + prDelBaFrame->u2FrameCtrl = MAC_FRAME_ACTION; +#if CFG_SUPPORT_802_11W + if (rsnCheckBipKeyInstalled(prAdapter, prStaRec)) { + DBGLOG(QM, WARN, + "[Puff][%s]: (Warning) DELBA is 80211w enabled\n", + __func__); + prDelBaFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME; + } +#endif + + prDelBaFrame->u2DurationID = 0; + prDelBaFrame->ucCategory = CATEGORY_BLOCK_ACK_ACTION; + prDelBaFrame->ucAction = ACTION_DELBA; + + prDelBaFrame->u2DelBaParameterSet = 0; + prDelBaFrame->u2DelBaParameterSet |= ((fgIsInitiator ? + ACTION_DELBA_INITIATOR_MASK : 0)); + prDelBaFrame->u2DelBaParameterSet |= ((u4Tid << + ACTION_DELBA_TID_OFFSET) & ACTION_DELBA_TID_MASK); + prDelBaFrame->u2ReasonCode = u4ReasonCode; + + COPY_MAC_ADDR(prDelBaFrame->aucDestAddr, + prStaRec->aucMacAddr); + COPY_MAC_ADDR(prDelBaFrame->aucSrcAddr, + prBssInfo->aucOwnMacAddr); + COPY_MAC_ADDR(prDelBaFrame->aucBSSID, prBssInfo->aucBSSID); + + /* 4 <3> Configure the MSDU_INFO and forward it to TXM */ + TX_SET_MMPDU(prAdapter, + prTxMsduInfo, + prStaRec->ucBssIndex, + (prStaRec != NULL) ? (prStaRec->ucIndex) : + (STA_REC_INDEX_NOT_FOUND), + WLAN_MAC_HEADER_LEN, ACTION_DELBA_FRAME_LEN, NULL, + MSDU_RATE_MODE_AUTO); + + /* TID and fgIsInitiator are needed + * when processing TX Done of the DELBA frame + */ + prTxMsduInfo->ucTID = (uint8_t) u4Tid; + prTxMsduInfo->ucControlFlag = (fgIsInitiator ? 1 : 0); + + nicTxEnqueueMsdu(prAdapter, prTxMsduInfo); + + DBGLOG(QM, WARN, + "[Puff][%s]: Send DELBA for TID=%ld Initiator=%d\n", + __func__, u4Tid, fgIsInitiator); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Callback function for the TX Done event for an ADDBA_RSP + * + * @param prMsduInfo The TX packet + * @param rWlanStatus WLAN_STATUS_SUCCESS if TX is successful + * + * @return WLAN_STATUS_BUFFER_RETAINED is returned if the buffer shall not be + * freed by TXM + */ +/*----------------------------------------------------------------------------*/ +uint32_t +mqmCallbackAddBaRspSent(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo, + IN enum ENUM_TX_RESULT_CODE rTxDoneStatus) +{ + struct RX_BA_ENTRY *prRxBaEntry; + struct STA_RECORD *prStaRec; + struct QUE_MGT *prQM; + + uint32_t u4Tid = 0; + + /* ASSERT(prMsduInfo); */ + prStaRec = cnmGetStaRecByIndex(prAdapter, + prMsduInfo->ucStaRecIndex); + ASSERT(prStaRec); + + prQM = &prAdapter->rQM; + + DBGLOG(QM, WARN, + "[Puff]: Enter mqmCallbackAddBaRspSent()\n"); + + /* 4 <0> Check STA_REC status */ + /* Check STA_REC is inuse */ + if (!prStaRec->fgIsInUse) { + DBGLOG(QM, WARN, "[Puff][%s]: (Warning) sta_rec is not inuse\n", + __func__); + return WLAN_STATUS_SUCCESS; + } + /* Check HT-capabale STA */ + if (!(prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_BIT_HT)) { + DBGLOG(QM, WARN, + "[Puff][%s]: (Warning) sta is NOT HT-capable(0x%08X)\n", + __func__, + prStaRec->ucDesiredPhyTypeSet); + /* To free the received ADDBA_REQ directly */ + return WLAN_STATUS_SUCCESS; + } + /* 4 <1> Find the corresponding BA entry */ + /* TID is stored in MSDU_INFO when composing the ADDBA_RSP frame */ + u4Tid = prMsduInfo->ucTID; + prRxBaEntry = &prQM->arRxBaTable[u4Tid]; + + /* Note: Due to some reason, for example, receiving a DELBA, + * the BA entry may not be in state NEGO + */ + /* 4 <2> INVALID state */ + if (!prRxBaEntry) { + log_dbg(QM, WARN, "[Puff][%s]: (RX_BA) ADDBA_RSP ---> peer (STA=%d TID=%d)(TX successful)(invalid BA)\n", + __func__, prStaRec->ucIndex, u4Tid); + } + /* 4 <3> NEGO, ACTIVE, or DELETING state */ + else { + switch (rTxDoneStatus) { + /* 4 TX Success */ + case TX_RESULT_SUCCESS: + + DBGLOG(QM, WARN, + "[Puff][%s]: (RX_BA) ADDBA_RSP ---> peer (STA=%d TID=%d)(TX successful)\n", + __func__, prStaRec->ucIndex, u4Tid); + + /* 4 NEGO or ACTIVE state */ + if (prRxBaEntry->ucStatus != BA_ENTRY_STATUS_DELETING) + mqmRxModifyBaEntryStatus(prAdapter, prRxBaEntry, + BA_ENTRY_STATUS_ACTIVE); + break; + + /* 4 TX Failure */ + default: + + log_dbg(QM, WARN, "[Puff][%s]: (RX_BA) ADDBA_RSP ---> peer (STA=%d TID=%ld Entry_Status=%d)(TX failed)\n", + __func__, prStaRec->ucIndex, + u4Tid, prRxBaEntry->ucStatus); + + /* 4 NEGO or ACTIVE state */ + /* Notify the host to delete the agreement */ + if (prRxBaEntry->ucStatus != BA_ENTRY_STATUS_DELETING) { + mqmRxModifyBaEntryStatus(prAdapter, prRxBaEntry, + BA_ENTRY_STATUS_DELETING); + + /* Send DELBA to the peer to ensure + * the BA state is synchronized + */ + mqmSendDelBaFrame(prAdapter, + DELBA_ROLE_RECIPIENT, + prStaRec, u4Tid, + STATUS_CODE_UNSPECIFIED_FAILURE); + } + break; + } + + } + + return WLAN_STATUS_SUCCESS; /* TXM shall release the packet */ + +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Check if there is any idle RX BA + * + * @param u4Param (not used) + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void mqmTimeoutCheckIdleRxBa(IN struct ADAPTER *prAdapter, + IN unsigned long ulParamPtr) +{ + int8_t i; + struct RX_BA_ENTRY *prRxBa; + uint32_t u4IdleCountThreshold = 0; + struct STA_RECORD *prStaRec; + struct QUE_MGT *prQM; + + DBGLOG(QM, WARN, + "[Puff]: Enter mqmTimeoutIdleRxBaDetection()\n"); + + prQM = &prAdapter->rQM; + + /* 4 <1> Restart the timer */ + cnmTimerStopTimer(prAdapter, + &prAdapter->rMqmIdleRxBaDetectionTimer); + cnmTimerStartTimer(prAdapter, + &prAdapter->rMqmIdleRxBaDetectionTimer, + MQM_IDLE_RX_BA_CHECK_INTERVAL); + + /* 4 <2> Increment the idle count for each idle BA */ + for (i = 0; i < CFG_NUM_OF_RX_BA_AGREEMENTS; i++) { + + prRxBa = &prQM->arRxBaTable[i]; + + if (prRxBa->ucStatus == BA_ENTRY_STATUS_ACTIVE) { + + prStaRec = cnmGetStaRecByIndex(prAdapter, + prRxBa->ucStaRecIdx); + + if (!prStaRec->fgIsInUse) { + DBGLOG(QM, WARN, + "[Puff][%s]: (Warning) sta_rec is not inuse\n", + __func__); + ASSERT(0); + } + /* Check HT-capabale STA */ + if (!(prStaRec->ucDesiredPhyTypeSet & + PHY_TYPE_BIT_HT)) { + DBGLOG(QM, WARN, + "[Puff][%s]: (Warning) sta is NOT HT-capable(0x%08X)\n", + __func__, + prStaRec->ucDesiredPhyTypeSet); + ASSERT(0); + } + /* 4 <2.1> Idle detected, increment idle count + * and see if a DELBA should be sent + */ + if (prRxBa->u2SnapShotSN == + prStaRec->au2CachedSeqCtrl[prRxBa->ucTid]) { + + prRxBa->ucIdleCount++; + + ASSERT(prRxBa->ucTid < 8); + switch (aucTid2ACI[prRxBa->ucTid]) { + case 0: /* BK */ + u4IdleCountThreshold = + MQM_DEL_IDLE_RXBA_THRESHOLD_BK; + break; + case 1: /* BE */ + u4IdleCountThreshold = + MQM_DEL_IDLE_RXBA_THRESHOLD_BE; + break; + case 2: /* VI */ + u4IdleCountThreshold = + MQM_DEL_IDLE_RXBA_THRESHOLD_VI; + break; + case 3: /* VO */ + u4IdleCountThreshold = + MQM_DEL_IDLE_RXBA_THRESHOLD_VO; + break; + } + + if (prRxBa->ucIdleCount >= + u4IdleCountThreshold) { + mqmRxModifyBaEntryStatus(prAdapter, + prRxBa, + BA_ENTRY_STATUS_INVALID); + mqmSendDelBaFrame(prAdapter, + DELBA_ROLE_RECIPIENT, prStaRec, + (uint32_t) prRxBa->ucTid, + REASON_CODE_PEER_TIME_OUT); + qmDelRxBaEntry(prAdapter, + prStaRec->ucIndex, + prRxBa->ucTid, TRUE); + } + } + /* 4 <2.2> Activity detected */ + else { + prRxBa->u2SnapShotSN = + prStaRec->au2CachedSeqCtrl[ + prRxBa->ucTid]; + prRxBa->ucIdleCount = 0; + continue; /* check the next BA entry */ + } + } + } + +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Do RX BA entry state transition + * + * @param prRxBaEntry The BA entry pointer + * @param eStatus The state to transition to + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void +mqmRxModifyBaEntryStatus(IN struct ADAPTER *prAdapter, + IN struct RX_BA_ENTRY *prRxBaEntry, + IN enum ENUM_BA_ENTRY_STATUS eStatus) +{ + struct STA_RECORD *prStaRec; + struct QUE_MGT *prQM; + + u_int8_t fgResetScoreBoard = FALSE; + + ASSERT(prRxBaEntry); + + prStaRec = cnmGetStaRecByIndex(prAdapter, + prRxBaEntry->ucStaRecIdx); + ASSERT(prStaRec); + prQM = &prAdapter->rQM; + + if (prRxBaEntry->ucStatus == (uint8_t) eStatus) { + DBGLOG(QM, WARN, "[Puff][%s]: eStatus are identical...\n", + __func__, prRxBaEntry->ucStatus); + return; + } + /* 4 <1> State transition from state X */ + switch (prRxBaEntry->ucStatus) { + + /* 4 <1.1> From (X = INVALID) to (ACTIVE or NEGO or DELETING) */ + case BA_ENTRY_STATUS_INVALID: + + /* Associate the BA entry with the STA_REC + * when leaving INVALID state + */ + kalMemCopy(&prQM->arRxBaTable[prRxBaEntry->ucTid], + prRxBaEntry, sizeof(struct RX_BA_ENTRY)); + + /* Increment the RX BA counter */ + prQM->ucRxBaCount++; + ASSERT(prQM->ucRxBaCount <= CFG_NUM_OF_RX_BA_AGREEMENTS); + + /* Since AMPDU may be received during INVALID state */ + fgResetScoreBoard = TRUE; + + /* Reset Idle Count since this BA entry is being activated now. + * Note: If there is no ACTIVE entry, + * the idle detection timer will not be started. + */ + prRxBaEntry->ucIdleCount = 0; + break; + + /* 4 <1.2> Other cases */ + default: + break; + } + + /* 4 <2> State trasition to state Y */ + switch (eStatus) { + + /* 4 <2.1> From (NEGO, ACTIVE, DELETING) to (Y=INVALID) */ + case BA_ENTRY_STATUS_INVALID: + + /* Disassociate the BA entry with the STA_REC */ + kalMemZero(&prQM->arRxBaTable[prRxBaEntry->ucTid], + sizeof(struct RX_BA_ENTRY)); + + /* Decrement the RX BA counter */ + prQM->ucRxBaCount--; + ASSERT(prQM->ucRxBaCount < CFG_NUM_OF_RX_BA_AGREEMENTS); + + /* (TBC) */ + fgResetScoreBoard = TRUE; + + /* If there is not any BA agreement, + * stop doing idle detection + */ + if (prQM->ucRxBaCount == 0) { + if (MQM_CHECK_FLAG(prAdapter->u4FlagBitmap, + MQM_FLAG_IDLE_RX_BA_TIMER_STARTED)) { + cnmTimerStopTimer(prAdapter, + &prAdapter->rMqmIdleRxBaDetectionTimer); + MQM_CLEAR_FLAG(prAdapter->u4FlagBitmap, + MQM_FLAG_IDLE_RX_BA_TIMER_STARTED); + } + } + + break; + + /* 4 <2.2> From (any) to (Y=ACTIVE) */ + case BA_ENTRY_STATUS_ACTIVE: + + /* If there is at least one BA going into ACTIVE, + * start idle detection + */ + if (!MQM_CHECK_FLAG(prAdapter->u4FlagBitmap, + MQM_FLAG_IDLE_RX_BA_TIMER_STARTED)) { + cnmTimerInitTimer(prAdapter, + &prAdapter->rMqmIdleRxBaDetectionTimer, + (PFN_MGMT_TIMEOUT_FUNC) mqmTimeoutCheckIdleRxBa, + (unsigned long) NULL); + /* No parameter */ + + cnmTimerStopTimer(prAdapter, + &prAdapter->rMqmIdleRxBaDetectionTimer); + +#if MQM_IDLE_RX_BA_DETECTION + cnmTimerStartTimer(prAdapter, + &prAdapter->rMqmIdleRxBaDetectionTimer, + MQM_IDLE_RX_BA_CHECK_INTERVAL); + MQM_SET_FLAG(prAdapter->u4FlagBitmap, + MQM_FLAG_IDLE_RX_BA_TIMER_STARTED); +#endif + } + + break; + + case BA_ENTRY_STATUS_NEGO: + default: + break; + } + + if (fgResetScoreBoard) { + struct CMD_RESET_BA_SCOREBOARD *prCmdBody; + + prCmdBody = (struct CMD_RESET_BA_SCOREBOARD *) + cnmMemAlloc(prAdapter, RAM_TYPE_BUF, + sizeof(struct CMD_RESET_BA_SCOREBOARD)); + ASSERT(prCmdBody); + + prCmdBody->ucflag = MAC_ADDR_TID_MATCH; + prCmdBody->ucTID = prRxBaEntry->ucTid; + kalMemCopy(prCmdBody->aucMacAddr, prStaRec->aucMacAddr, + PARAM_MAC_ADDR_LEN); + + wlanoidResetBAScoreboard(prAdapter, prCmdBody, + sizeof(struct CMD_RESET_BA_SCOREBOARD)); + + cnmMemFree(prAdapter, prCmdBody); + } + + DBGLOG(QM, WARN, + "[Puff]QM: (RX_BA) [STA=%d TID=%d] status from %d to %d\n", + prRxBaEntry->ucStaRecIdx, prRxBaEntry->ucTid, + prRxBaEntry->ucStatus, eStatus); + + prRxBaEntry->ucStatus = (uint8_t) eStatus; + +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void mqmHandleAddBaReq(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb) +{ + struct STA_RECORD *prStaRec; + struct BSS_INFO *prBssInfo; + struct ACTION_ADDBA_REQ_FRAME *prAddBaReq; + struct ACTION_ADDBA_REQ_BODY rAddBaReqBody; + struct ACTION_ADDBA_RSP_FRAME *prAddBaRsp; + struct ACTION_ADDBA_RSP_BODY rAddBaRspBody; + struct RX_BA_ENTRY *prRxBaEntry; + struct MSDU_INFO *prTxMsduInfo; + struct QUE_MGT *prQM; + + /* Reject or accept the ADDBA_REQ */ + u_int8_t fgIsReqAccepted = TRUE; + /* Indicator: Whether a new RX BA entry will be added */ + u_int8_t fgIsNewEntryAdded = FALSE; + + uint32_t u4Tid; + uint32_t u4StaRecIdx; + uint16_t u2WinStart; + uint16_t u2WinSize; + uint32_t u4BuffSize; + +#if CFG_SUPPORT_BCM + uint32_t u4BuffSizeBT; +#endif + + ASSERT(prSwRfb); + + prStaRec = prSwRfb->prStaRec; + prQM = &prAdapter->rQM; + + do { + + /* 4 <0> Check if this is an active HT-capable STA */ + /* Check STA_REC is inuse */ + if (!prStaRec->fgIsInUse) { + log_dbg(QM, WARN, "[Puff][%s]: (Warning) sta_rec is not inuse\n", + __func__); + break; + } + /* Check HT-capabale STA */ + if (!(prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_BIT_HT)) { + DBGLOG(QM, WARN, + "[Puff][%s]: (Warning) sta is NOT HT-capable(0x%08X)\n", + __func__, + prStaRec->ucDesiredPhyTypeSet); + break; /* To free the received ADDBA_REQ directly */ + } + /* 4 <1> Check user configurations and HW capabilities */ + /* Check configurations (QoS support, AMPDU RX support) */ + if ((!prAdapter->rWifiVar.fgSupportQoS) || + (!prAdapter->rWifiVar.fgSupportAmpduRx) || + (!prStaRec->fgRxAmpduEn)) { + DBGLOG(QM, WARN, + "[Puff][%s]: (Warning) BA ACK Policy not supported fgSupportQoS(%d)", + __func__, prAdapter->rWifiVar.fgSupportQoS); + DBGLOG(QM, WARN, + "fgSupportAmpduRx(%d), fgRxAmpduEn(%d)\n", + prAdapter->rWifiVar.fgSupportAmpduRx, + prStaRec->fgRxAmpduEn); + /* Will send an ADDBA_RSP with DECLINED */ + fgIsReqAccepted = FALSE; + } + /* Check capability */ + prAddBaReq = ((struct ACTION_ADDBA_REQ_FRAME *) ( + prSwRfb->pvHeader)); + kalMemCopy((uint8_t *) (&rAddBaReqBody), + (uint8_t *) (&(prAddBaReq->aucBAParameterSet[0])), + 6); + if ((((rAddBaReqBody.u2BAParameterSet) & + BA_PARAM_SET_ACK_POLICY_MASK) >> + BA_PARAM_SET_ACK_POLICY_MASK_OFFSET) + != BA_PARAM_SET_ACK_POLICY_IMMEDIATE_BA) { + /* Only Immediate_BA is supported */ + DBGLOG(QM, WARN, + "[Puff][%s]: (Warning) BA ACK Policy not supported (0x%08X)\n", + __func__, rAddBaReqBody.u2BAParameterSet); + /* Will send an ADDBA_RSP with DECLINED */ + fgIsReqAccepted = FALSE; + } + + /* 4 <2> Determine the RX BA entry (existing or to be added) */ + /* Note: BA entry index = (TID, STA_REC index) */ + u4Tid = (((rAddBaReqBody.u2BAParameterSet) & + BA_PARAM_SET_TID_MASK) >> + BA_PARAM_SET_TID_MASK_OFFSET); + u4StaRecIdx = prStaRec->ucIndex; + DBGLOG(QM, WARN, + "[Puff][%s]: BA entry index = [TID(%d), STA_REC index(%d)]\n", + __func__, u4Tid, u4StaRecIdx); + + u2WinStart = ((rAddBaReqBody.u2BAStartSeqCtrl) >> + OFFSET_BAR_SSC_SN); + u2WinSize = (((rAddBaReqBody.u2BAParameterSet) & + BA_PARAM_SET_BUFFER_SIZE_MASK) >> + BA_PARAM_SET_BUFFER_SIZE_MASK_OFFSET); + DBGLOG(QM, WARN, + "[Puff][%s]: BA entry info = [WinStart(%d), WinSize(%d)]\n", + __func__, u2WinStart, u2WinSize); + + if (fgIsReqAccepted) { + + prRxBaEntry = &prQM->arRxBaTable[u4Tid]; + + if (!prRxBaEntry) { + + /* 4 INVALID state && BA entry + * available --> Add a new entry and accept + */ + if (prQM->ucRxBaCount < + CFG_NUM_OF_RX_BA_AGREEMENTS) { + + fgIsNewEntryAdded = + qmAddRxBaEntry(prAdapter, + (uint8_t) u4StaRecIdx, + (uint8_t) u4Tid, u2WinStart, + u2WinSize); + + if (!fgIsNewEntryAdded) { + DBGLOG(QM, ERROR, + "[Puff][%s]: (Error) Free RX BA entry alloc failure\n"); + fgIsReqAccepted = FALSE; + } else { + log_dbg(QM, WARN, "[Puff][%s]: Create a new BA Entry\n"); + } + } + /* 4 INVALID state && BA entry + * unavailable --> Reject the ADDBA_REQ + */ + else { + log_dbg(QM, WARN, "[Puff][%s]: (Warning) Free RX BA entry unavailable(req: %d)\n", + __func__, prQM->ucRxBaCount); + /* Will send ADDBA_RSP with DECLINED */ + fgIsReqAccepted = FALSE; + } + } else { + + /* 4 NEGO or DELETING state --> + * Ignore the ADDBA_REQ + * For NEGO: do nothing. Wait for TX Done of + * ADDBA_RSP + * For DELETING: do nothing. Wait for TX Done + * of DELBA + */ + if (prRxBaEntry->ucStatus != + BA_ENTRY_STATUS_ACTIVE) { + /* Ignore the ADDBA_REQ since + * the current state is NEGO + */ + log_dbg(QM, WARN, "[Puff][%s]:(Warning)ADDBA_REQ for TID=%ld is received, status:%d)\n", + __func__, u4Tid, + prRxBaEntry->ucStatus); + break; + } + } + } + /* 4 <3> Construct the ADDBA_RSP frame */ + prTxMsduInfo = (struct MSDU_INFO *) cnmMgtPktAlloc( + prAdapter, ACTION_ADDBA_RSP_FRAME_LEN); + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prStaRec->ucBssIndex); + + if (!prTxMsduInfo) { + + /* The peer may send an ADDBA_REQ message later. + * Do nothing to the BA entry. No DELBA will be + * sent (because cnmMgtPktAlloc() may fail again). + * No BA deletion event will be sent to the host + * (because cnmMgtPktAlloc() may fail again). + */ + DBGLOG(QM, WARN, + "[Puff][%s]: (Warning) ADDBA_RSP alloc failure\n", + __func__); + + if (fgIsNewEntryAdded) { + /* If a new entry has been created due + * to this ADDBA_REQ, delete it + */ + ASSERT(prRxBaEntry); + mqmRxModifyBaEntryStatus(prAdapter, + prRxBaEntry, BA_ENTRY_STATUS_INVALID); + } + + break; /* Exit directly to free the ADDBA_REQ */ + } + + /* Fill the ADDBA_RSP message */ + prAddBaRsp = (struct ACTION_ADDBA_RSP_FRAME *) + ((uint32_t) (prTxMsduInfo->prPacket) + + MAC_TX_RESERVED_FIELD); + prAddBaRsp->u2FrameCtrl = MAC_FRAME_ACTION; + +#if CFG_SUPPORT_802_11W + if (rsnCheckBipKeyInstalled(prAdapter, prStaRec)) { + DBGLOG(QM, WARN, + "[Puff][%s]: (Warning) ADDBA_RSP is 80211w enabled\n", + __func__); + prAddBaReq->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME; + } +#endif + prAddBaRsp->u2DurationID = 0; + prAddBaRsp->ucCategory = CATEGORY_BLOCK_ACK_ACTION; + prAddBaRsp->ucAction = ACTION_ADDBA_RSP; + prAddBaRsp->ucDialogToken = prAddBaReq->ucDialogToken; + + log_dbg(QM, WARN, "[Puff][%s]: (Warning) ADDBA_RSP DurationID(%d) Category(%d) Action(%d) DialogToken(%d)\n", + __func__, prAddBaRsp->u2DurationID, + prAddBaRsp->ucCategory, prAddBaRsp->ucAction, + prAddBaRsp->ucDialogToken); + + if (fgIsReqAccepted) + rAddBaRspBody.u2StatusCode = STATUS_CODE_SUCCESSFUL; + else + rAddBaRspBody.u2StatusCode = STATUS_CODE_REQ_DECLINED; + + /* WinSize = min(WinSize in ADDBA_REQ, CFG_RX_BA_MAX_WINSIZE) */ + u4BuffSize = (((rAddBaReqBody.u2BAParameterSet) & + BA_PARAM_SET_BUFFER_SIZE_MASK) >> + BA_PARAM_SET_BUFFER_SIZE_MASK_OFFSET); + + /*If ADDBA req WinSize<=0 => use default WinSize(16) */ + if ((u4BuffSize > CFG_RX_BA_MAX_WINSIZE) + || (u4BuffSize <= 0)) + u4BuffSize = CFG_RX_BA_MAX_WINSIZE; +#if CFG_SUPPORT_BCM + /* TODO: Call BT coexistence function to limit the winsize */ + u4BuffSizeBT = bcmRequestBaWinSize(); + DBGLOG(QM, WARN, + "[Puff][%s]: (Warning) bcmRequestBaWinSize(%d)\n", + __func__, u4BuffSizeBT); + + if (u4BuffSize > u4BuffSizeBT) + u4BuffSize = u4BuffSizeBT; +#endif /* CFG_SUPPORT_BCM */ + + rAddBaRspBody.u2BAParameterSet = (BA_POLICY_IMMEDIATE | + (u4Tid << BA_PARAM_SET_TID_MASK_OFFSET) | + (u4BuffSize << BA_PARAM_SET_BUFFER_SIZE_MASK_OFFSET)); + + /* TODO: Determine the BA timeout value + * according to the default preference + */ + rAddBaRspBody.u2BATimeoutValue = + rAddBaReqBody.u2BATimeoutValue; + + DBGLOG(QM, WARN, + "[Puff][%s]: (Warning) ADDBA_RSP u4BuffSize(%d) StatusCode(%d)", + __func__, u4BuffSize, rAddBaRspBody.u2StatusCode); + DBGLOG(QM, WARN, + "BAParameterSet(0x%08X) BATimeoutValue(%d)\n", + rAddBaRspBody.u2BAParameterSet, + rAddBaRspBody.u2BATimeoutValue); + kalMemCopy((uint8_t *) (&(prAddBaRsp->aucStatusCode[0])), + (uint8_t *) (&rAddBaRspBody), 6); + + COPY_MAC_ADDR(prAddBaRsp->aucDestAddr, + prStaRec->aucMacAddr); + COPY_MAC_ADDR(prAddBaRsp->aucSrcAddr, + prBssInfo->aucOwnMacAddr); + COPY_MAC_ADDR(prAddBaRsp->aucBSSID, prAddBaReq->aucBSSID); + + /* 4 <4> Forward the ADDBA_RSP to TXM */ + TX_SET_MMPDU(prAdapter, + prTxMsduInfo, + prStaRec->ucBssIndex, + (prStaRec != NULL) ? (prStaRec->ucIndex) : + (STA_REC_INDEX_NOT_FOUND), + WLAN_MAC_HEADER_LEN, + ACTION_ADDBA_RSP_FRAME_LEN, + mqmCallbackAddBaRspSent, + MSDU_RATE_MODE_AUTO); + + /* Note: prTxMsduInfo->ucTID is not used for transmitting the + * ADDBA_RSP. However, when processing TX Done of this + * ADDBA_RSP, the TID value is needed, so store the TID value + * in advance to prevent parsing the ADDBA_RSP frame + */ + prTxMsduInfo->ucTID = (uint8_t) u4Tid; + + nicTxEnqueueMsdu(prAdapter, prTxMsduInfo); + + DBGLOG(QM, WARN, + "[Puff][%s]: (RX_BA) ADDBA_RSP ---> peer (STA=%d TID=%ld)\n", + __func__, + prStaRec->ucIndex, u4Tid); + +#if 0 + /* 4 <5> Notify the host to start buffer reordering */ + /* Only when a new BA entry is indeed + * added will the host be notified + */ + if (fgIsNewEntryAdded) { + ASSERT(fgIsReqAccepted); + + prSwRfbEventToHost = (struct SW_RFB *) cnmMgtPktAlloc( + EVENT_RX_ADDBA_PACKET_LEN); + + if (!prSwRfbEventToHost) { + + /* Note: DELBA will not be sent since + * cnmMgtPktAlloc() may fail again. However, + * it does not matter because upon receipt of + * AMPDUs without a RX BA agreement, + * MQM will send DELBA frames + */ + + DBGLOG(MQM, WARN, + "MQM: (Warning) EVENT packet alloc failed\n"); + + /* Ensure that host and FW are synchronized */ + mqmRxModifyBaEntryStatus(prRxBaEntry, + BA_ENTRY_STATUS_INVALID); + + break; /* Free the received ADDBA_REQ */ + } + prEventRxAddBa = (struct EVENT_RX_ADDBA *) + prSwRfbEventToHost->pucBuffer; + prEventRxAddBa->ucStaRecIdx = (uint8_t) u4StaRecIdx; + prEventRxAddBa->u2Length = EVENT_RX_ADDBA_PACKET_LEN; + prEventRxAddBa->ucEID = EVENT_ID_RX_ADDBA; + /* Unsolicited event packet */ + prEventRxAddBa->ucSeqNum = 0; + prEventRxAddBa->u2BAParameterSet = + rAddBaRspBody.u2BAParameterSet; + prEventRxAddBa->u2BAStartSeqCtrl = + rAddBaReqBody.u2BAStartSeqCtrl; + prEventRxAddBa->u2BATimeoutValue = + rAddBaReqBody.u2BATimeoutValue; + prEventRxAddBa->ucDialogToken = + prAddBaReq->ucDialogToken; + + log_dbg(MQM, INFO, "MQM: (RX_BA) Event ADDBA ---> driver (STA=%ld TID=%ld WinStart=%d)\n", + u4StaRecIdx, u4Tid, + (prEventRxAddBa->u2BAStartSeqCtrl >> 4)); + + /* Configure the SW_RFB for the Event packet */ + RXM_SET_EVENT_PACKET( + /* struct SW_RFB **/ (struct SW_RFB *) + prSwRfbEventToHost, + /* HIF RX Packet pointer */ + (uint8_t *) prEventRxAddBa, + /* HIF RX port number */ HIF_RX0_INDEX + ); + + rxmSendEventToHost(prSwRfbEventToHost); + + + } +#endif + + } while (FALSE); + +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void mqmHandleAddBaRsp(IN struct SW_RFB *prSwRfb) +{ + +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void mqmHandleDelBa(IN struct SW_RFB *prSwRfb) +{ + +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void mqmHandleBaActionFrame(IN struct ADAPTER *prAdapter, + IN struct SW_RFB *prSwRfb) +{ + struct WLAN_ACTION_FRAME *prRxFrame; + + ASSERT(prAdapter); + ASSERT(prSwRfb); + + prRxFrame = (struct WLAN_ACTION_FRAME *) prSwRfb->pvHeader; + DBGLOG(RLM, WARN, "[Puff][%s] Action(%d)\n", __func__, + prRxFrame->ucAction); + + switch (prRxFrame->ucAction) { + + case ACTION_ADDBA_REQ: + DBGLOG(RLM, WARN, + "[Puff][%s] (RX_BA) ADDBA_REQ <--- peer\n", __func__); + mqmHandleAddBaReq(prAdapter, prSwRfb); + break; + + case ACTION_ADDBA_RSP: + DBGLOG(RLM, WARN, + "[Puff][%s] (RX_BA) ADDBA_RSP <--- peer\n", __func__); + mqmHandleAddBaRsp(prSwRfb); + break; + + case ACTION_DELBA: + DBGLOG(RLM, WARN, "[Puff][%s] (RX_BA) DELBA <--- peer\n", + __func__); + mqmHandleDelBa(prSwRfb); + break; + + default: + DBGLOG(RLM, WARN, "[Puff][%s] Unknown BA Action Frame\n", + __func__); + break; + } + +} + +#endif + +#if ARP_MONITER_ENABLE +void qmDetectArpNoResponse(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo) +{ + struct STA_RECORD *prStaRec; + struct sk_buff *prSkb = NULL; + uint8_t *pucData = NULL; + uint16_t u2EtherType = 0; + int arpOpCode = 0; + struct BSS_INFO *prAisBssInfo = NULL; + struct WIFI_VAR *prWifiVar = NULL; + uint32_t uArpMonitorNumber; + uint32_t uArpMonitorRxPktNum; + struct net_device *prNetDev = NULL; + struct GLUE_INFO *prGlueInfo = NULL; + + if (!prAdapter || + !prAdapter->prGlueInfo || + !prAdapter->prGlueInfo->prDevHandler) { + DBGLOG(QM, WARN, "Param is invalid\n"); + return; + } + prGlueInfo = prAdapter->prGlueInfo; + prNetDev = prGlueInfo->prDevHandler; + prWifiVar = &prAdapter->rWifiVar; + uArpMonitorNumber = prWifiVar->uArpMonitorNumber; + uArpMonitorRxPktNum = prWifiVar->uArpMonitorRxPktNum; + + if (uArpMonitorNumber == 0) + return; + + /* We need to disable arp monitor in CTIA mode */ + if (prAdapter->fgDisBcnLostDetection == TRUE) + return; + + prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX( + prAdapter, prMsduInfo->ucStaRecIndex); + if (!prStaRec || !IS_STA_IN_AIS(prStaRec)) + return; + + prAisBssInfo = aisGetAisBssInfo(prAdapter, + prStaRec->ucBssIndex); + + if (prMsduInfo->eSrc != TX_PACKET_OS) + return; + + prSkb = (struct sk_buff *)prMsduInfo->prPacket; + + if (!prSkb || (prSkb->len <= ETHER_HEADER_LEN)) + return; + + pucData = prSkb->data; + if (!pucData) + return; + u2EtherType = (pucData[ETH_TYPE_LEN_OFFSET] << 8) | + (pucData[ETH_TYPE_LEN_OFFSET + 1]); + + if (u2EtherType != ETH_P_ARP) + return; + + /* If ARP req is neither to apIp nor to gatewayIp, ignore detection */ + if (kalMemCmp(apIp, &pucData[ETH_TYPE_LEN_OFFSET + 26], + sizeof(apIp)) && + kalMemCmp(gatewayIp, &pucData[ETH_TYPE_LEN_OFFSET + 26], + sizeof(gatewayIp))) + return; + + arpOpCode = (pucData[ETH_TYPE_LEN_OFFSET + 8] << 8) | + (pucData[ETH_TYPE_LEN_OFFSET + 8 + 1]); + + if (arpOpCode == ARP_PRO_REQ) { + arpMoniter++; + /* Record counts of RX Packets when Tx 1st ARP Req */ + if (!last_rx_packets) { + last_rx_packets = prNetDev->stats.rx_packets; + latest_rx_packets = 0; + } + /* Record counts of RX Packets when TX ARP Req recently */ + latest_rx_packets = prNetDev->stats.rx_packets; + if (arpMoniter > uArpMonitorNumber) { + if ((latest_rx_packets - last_rx_packets) <= + uArpMonitorRxPktNum) { + DBGLOG(INIT, WARN, "IOT issue, arp no resp!\n"); + if (prAisBssInfo) + prAisBssInfo->u2DeauthReason = + BEACON_TIMEOUT_DUE_2_APR_NO_RESPONSE; + prAdapter->cArpNoResponseIdx = + prStaRec->ucBssIndex; + } else + DBGLOG(INIT, WARN, "ARP, still have %d pkts\n", + latest_rx_packets - last_rx_packets); + arpMoniter = 0; + last_rx_packets = 0; + latest_rx_packets = 0; + kalMemZero(apIp, sizeof(apIp)); + } + } +} + +void qmHandleRxArpPackets(struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb) +{ + uint8_t *pucData = NULL; + uint16_t u2EtherType = 0; + int arpOpCode = 0; + struct BSS_INFO *prAisBssInfo = NULL; + + prAisBssInfo = aisGetAisBssInfo(prAdapter, + secGetBssIdxByRfb(prAdapter, prSwRfb)); + + if (prSwRfb->u2PacketLen <= ETHER_HEADER_LEN) + return; + + pucData = (uint8_t *)prSwRfb->pvHeader; + if (!pucData) + return; + u2EtherType = (pucData[ETH_TYPE_LEN_OFFSET] << 8) | + (pucData[ETH_TYPE_LEN_OFFSET + 1]); + + if (u2EtherType != ETH_P_ARP) + return; + + arpOpCode = (pucData[ETH_TYPE_LEN_OFFSET + 8] << 8) | + (pucData[ETH_TYPE_LEN_OFFSET + 8 + 1]); + if (arpOpCode == ARP_PRO_RSP) { + arpMoniter = 0; + if (prAisBssInfo && + prAisBssInfo->prStaRecOfAP) { + if (EQUAL_MAC_ADDR( + &(pucData[ETH_TYPE_LEN_OFFSET + 10]), + /* source hardware address */ + prAisBssInfo-> + prStaRecOfAP->aucMacAddr)) { + kalMemCopy(apIp, + &(pucData[ETH_TYPE_LEN_OFFSET + 16]), + sizeof(apIp)); + DBGLOG(INIT, TRACE, + "get arp response from AP %d.%d.%d.%d\n", + apIp[0], apIp[1], apIp[2], apIp[3]); + } + } + } +} + +void qmHandleRxDhcpPackets(struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb) +{ + uint8_t *pucData = NULL; + uint8_t *pucEthBody = NULL; + uint8_t *pucUdpBody = NULL; + uint32_t udpLength = 0; + uint32_t i = 0; + struct BOOTP_PROTOCOL *prBootp = NULL; + uint32_t u4DhcpMagicCode = 0; + uint8_t dhcpTypeGot = 0; + uint8_t dhcpGatewayGot = 0; + + if (prSwRfb->u2PacketLen <= ETHER_HEADER_LEN) + return; + + pucData = (uint8_t *)prSwRfb->pvHeader; + if (!pucData) + return; + if (((pucData[ETH_TYPE_LEN_OFFSET] << 8) | + pucData[ETH_TYPE_LEN_OFFSET + 1]) != ETH_P_IPV4) + return; + + pucEthBody = &pucData[ETH_HLEN]; + if (((pucEthBody[0] & IPVH_VERSION_MASK) >> + IPVH_VERSION_OFFSET) != IPVERSION) + return; + if (pucEthBody[9] != IP_PRO_UDP) + return; + + pucUdpBody = &pucEthBody[(pucEthBody[0] & 0x0F) * 4]; + if ((pucUdpBody[0] << 8 | pucUdpBody[1]) != UDP_PORT_DHCPS || + (pucUdpBody[2] << 8 | pucUdpBody[3]) != UDP_PORT_DHCPC) + return; + + udpLength = pucUdpBody[4] << 8 | pucUdpBody[5]; + + prBootp = (struct BOOTP_PROTOCOL *) &pucUdpBody[8]; + + WLAN_GET_FIELD_BE32(&prBootp->aucOptions[0], + &u4DhcpMagicCode); + if (u4DhcpMagicCode != DHCP_MAGIC_NUMBER) { + DBGLOG(INIT, WARN, + "dhcp wrong magic number, magic code: %d\n", + u4DhcpMagicCode); + return; + } + + /* 1. 248 is from udp header to the beginning of dhcp option + * 2. not sure the dhcp option always usd 255 as a end mark? + * if so, while condition should be removed? + */ + while (i < udpLength - 248) { + /* bcz of the strange struct BOOTP_PROTOCOL *, + * the dhcp magic code was count in dhcp options + * so need to [i + 4] to skip it + */ + switch (prBootp->aucOptions[i + 4]) { + case 3: + /* both dhcp ack and offer will update it */ + if (prBootp->aucOptions[i + 6] || + prBootp->aucOptions[i + 7] || + prBootp->aucOptions[i + 8] || + prBootp->aucOptions[i + 9]) { + gatewayIp[0] = prBootp->aucOptions[i + 6]; + gatewayIp[1] = prBootp->aucOptions[i + 7]; + gatewayIp[2] = prBootp->aucOptions[i + 8]; + gatewayIp[3] = prBootp->aucOptions[i + 9]; + + DBGLOG(INIT, TRACE, "Gateway ip: %d.%d.%d.%d\n", + gatewayIp[0], + gatewayIp[1], + gatewayIp[2], + gatewayIp[3]); + }; + dhcpGatewayGot = 1; + break; + case 53: + if (prBootp->aucOptions[i + 6] != 0x02 + && prBootp->aucOptions[i + 6] != 0x05) { + DBGLOG(INIT, WARN, + "wrong dhcp message type, type: %d\n", + prBootp->aucOptions[i + 6]); + if (dhcpGatewayGot) + kalMemZero(gatewayIp, + sizeof(gatewayIp)); + return; + } else if (prBootp->aucOptions[i + 6] == 0x05) { + uint8_t ucBssIndex = + secGetBssIdxByRfb( + prAdapter, prSwRfb); + /* Check if join timer is ticking, then release + * channel privilege and stop join timer. + */ + qmReleaseCHAtFinishedDhcp(prAdapter, + ucBssIndex); + } + dhcpTypeGot = 1; + break; + case 255: + return; + + default: + break; + } + if (dhcpGatewayGot && dhcpTypeGot) + return; + + i += prBootp->aucOptions[i + 5] + 2; + } + DBGLOG(INIT, WARN, + "can't find the dhcp option 255?, need to check the net log\n"); +} + +void qmResetArpDetect(void) +{ + arpMoniter = 0; + last_rx_packets = 0; + latest_rx_packets = 0; + kalMemZero(apIp, sizeof(apIp)); + kalMemZero(gatewayIp, sizeof(gatewayIp)); +} +#endif + +#if QM_ADAPTIVE_TC_RESOURCE_CTRL +void qmResetTcControlResource(IN struct ADAPTER *prAdapter) +{ + uint32_t u4Idx; + uint32_t u4TotalMinReservedTcResource = 0; + uint32_t u4TotalTcResource = 0; + uint32_t u4TotalGurantedTcResource = 0; + struct QUE_MGT *prQM = &prAdapter->rQM; + + /* Initialize TC resource control variables */ + for (u4Idx = 0; u4Idx < TC_NUM; u4Idx++) + prQM->au4AverageQueLen[u4Idx] = 0; + + ASSERT(prQM->u4TimeToAdjustTcResource + && prQM->u4TimeToUpdateQueLen); + + for (u4Idx = 0; u4Idx < TC_NUM; u4Idx++) { + prQM->au4CurrentTcResource[u4Idx] = + prAdapter->rTxCtrl.rTc.au4MaxNumOfBuffer[u4Idx]; + + if (u4Idx != TC4_INDEX) { + u4TotalTcResource += prQM->au4CurrentTcResource[u4Idx]; + u4TotalGurantedTcResource += + prQM->au4GuaranteedTcResource[u4Idx]; + u4TotalMinReservedTcResource += + prQM->au4MinReservedTcResource[u4Idx]; + } + } + + /* Sanity Check */ + if (u4TotalMinReservedTcResource > u4TotalTcResource) + kalMemZero(prQM->au4MinReservedTcResource, + sizeof(prQM->au4MinReservedTcResource)); + + if (u4TotalGurantedTcResource > u4TotalTcResource) + kalMemZero(prQM->au4GuaranteedTcResource, + sizeof(prQM->au4GuaranteedTcResource)); + + u4TotalGurantedTcResource = 0; + + /* Initialize Residual TC resource */ + for (u4Idx = 0; u4Idx < TC_NUM; u4Idx++) { + if (prQM->au4GuaranteedTcResource[u4Idx] < + prQM->au4MinReservedTcResource[u4Idx]) + prQM->au4GuaranteedTcResource[u4Idx] = + prQM->au4MinReservedTcResource[u4Idx]; + + if (u4Idx != TC4_INDEX) + u4TotalGurantedTcResource += + prQM->au4GuaranteedTcResource[u4Idx]; + } + + prQM->u4ResidualTcResource = u4TotalTcResource - + u4TotalGurantedTcResource; + +} +#endif + +/* To change PN number to UINT64 */ +u_int8_t qmRxPNtoU64(uint8_t *pucPN, uint8_t uPNNum, + uint64_t *pu64Rets) +{ + uint8_t ucCount = 0; + uint64_t u64Data = 0; + + if (!pu64Rets) { + DBGLOG(QM, ERROR, "Please input valid pu8Rets\n"); + return FALSE; + } + + if (uPNNum > CCMPTSCPNNUM) { + DBGLOG(QM, ERROR, "Please input valid uPNNum:%d\n", uPNNum); + return FALSE; + } + + *pu64Rets = 0; + for (; ucCount < uPNNum; ucCount++) { + u64Data = ((uint64_t) pucPN[ucCount]) << (8 * ucCount); + *pu64Rets += u64Data; + } + return TRUE; +} + +#ifdef CFG_SUPPORT_REPLAY_DETECTION +/* To check PN/TSC between RxStatus and local record. + * return TRUE if PNS is not bigger than PNT + */ +u_int8_t qmRxDetectReplay(uint8_t *pucPNS, uint8_t *pucPNT) +{ + uint64_t u8RxNum = 0; + uint64_t u8LocalRec = 0; + + if (!pucPNS || !pucPNT) { + DBGLOG(QM, ERROR, "Please input valid PNS:%p and PNT:%p\n", + pucPNS, pucPNT); + return TRUE; + } + + if (!qmRxPNtoU64(pucPNS, CCMPTSCPNNUM, &u8RxNum) + || !qmRxPNtoU64(pucPNT, CCMPTSCPNNUM, &u8LocalRec)) { + DBGLOG(QM, ERROR, "PN2U64 failed\n"); + return TRUE; + } + /* PN overflow ? */ + return !(u8RxNum > u8LocalRec); +} + +/* TO filter broadcast and multicast data packet replay issue. */ +u_int8_t qmHandleRxReplay(struct ADAPTER *prAdapter, + struct SW_RFB *prSwRfb) +{ + uint8_t *pucPN = NULL; + uint8_t ucKeyID = 0; /* 0~4 */ + /* CIPHER_SUITE_NONE~CIPHER_SUITE_GCMP */ + uint8_t ucSecMode = CIPHER_SUITE_NONE; + struct GLUE_INFO *prGlueInfo = NULL; + struct GL_WPA_INFO *prWpaInfo = NULL; + struct GL_DETECT_REPLAY_INFO *prDetRplyInfo = NULL; + + if (!prAdapter) + return TRUE; + if (prSwRfb->u2PacketLen <= ETHER_HEADER_LEN) + return TRUE; + + if (!(prSwRfb->ucGroupVLD & BIT(RX_GROUP_VLD_1))) { + DBGLOG_LIMITED(QM, TRACE, "Group 1 invalid\n"); + return FALSE; + } + + /* BMC only need check CCMP and TKIP Cipher suite */ + ucSecMode = prSwRfb->ucSecMode; + + prGlueInfo = prAdapter->prGlueInfo; + + prWpaInfo = aisGetWpaInfo(prAdapter, + secGetBssIdxByRfb(prAdapter, prSwRfb)); + + DBGLOG_LIMITED(QM, TRACE, "ucSecMode = [%u], ChiperGroup = [%u]\n", + ucSecMode, prWpaInfo->u4CipherGroup); + + if (ucSecMode != CIPHER_SUITE_CCMP + && ucSecMode != CIPHER_SUITE_TKIP) { + DBGLOG_LIMITED(QM, TRACE, + "SecMode: %d and CipherGroup: %d, no need check replay\n", + ucSecMode, prWpaInfo->u4CipherGroup); + return FALSE; + } + + if (prWpaInfo->u4CipherGroup != IW_AUTH_CIPHER_TKIP && + prWpaInfo->u4CipherGroup != IW_AUTH_CIPHER_CCMP) { + DBGLOG(QM, ERROR, + "RX status Chipher mode doens't match AP's setting\n"); + return FALSE; + } + + ucKeyID = prSwRfb->ucKeyID; + if (ucKeyID >= MAX_KEY_NUM) { + DBGLOG(QM, ERROR, "KeyID: %d error\n", ucKeyID); + return TRUE; + } + + prDetRplyInfo = aisGetDetRplyInfo(prAdapter, + secGetBssIdxByRfb(prAdapter, prSwRfb)); + /* TODO : Need check fw rekey while fw rekey event. */ + if (ucKeyID != prDetRplyInfo->ucCurKeyId) { + DBGLOG(QM, TRACE, + "use last keyID while detect replay information.(0x%x->0x%x)\n", + prDetRplyInfo->ucCurKeyId, ucKeyID); + ucKeyID = prDetRplyInfo->ucCurKeyId; + } + + if (prDetRplyInfo->arReplayPNInfo[ucKeyID].fgFirstPkt) { + prDetRplyInfo->arReplayPNInfo[ucKeyID].fgFirstPkt = FALSE; + HAL_RX_STATUS_GET_PN(prSwRfb->prRxStatusGroup1, + prDetRplyInfo->arReplayPNInfo[ucKeyID].auPN); + DBGLOG(QM, INFO, + "First check packet. Key ID:0x%x\n", ucKeyID); + return FALSE; + } + + pucPN = prSwRfb->prRxStatusGroup1->aucPN; + DBGLOG_LIMITED(QM, TRACE, + "BC packet 0x%x:0x%x:0x%x:0x%x:0x%x:0x%x--0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n", + pucPN[0], pucPN[1], pucPN[2], pucPN[3], pucPN[4], pucPN[5], + prDetRplyInfo->arReplayPNInfo[ucKeyID].auPN[0], + prDetRplyInfo->arReplayPNInfo[ucKeyID].auPN[1], + prDetRplyInfo->arReplayPNInfo[ucKeyID].auPN[2], + prDetRplyInfo->arReplayPNInfo[ucKeyID].auPN[3], + prDetRplyInfo->arReplayPNInfo[ucKeyID].auPN[4], + prDetRplyInfo->arReplayPNInfo[ucKeyID].auPN[5]); + if (qmRxDetectReplay(pucPN, + prDetRplyInfo->arReplayPNInfo[ucKeyID].auPN)) { + DBGLOG_LIMITED(QM, WARN, "Drop BC replay packet!\n"); + return TRUE; + } + + HAL_RX_STATUS_GET_PN(prSwRfb->prRxStatusGroup1, + prDetRplyInfo->arReplayPNInfo[ucKeyID].auPN); + return FALSE; +} +#endif + +u_int8_t +qmIsIPLayerPacket(uint8_t *pucPkt) +{ + uint16_t u2EtherType = + (pucPkt[ETH_TYPE_LEN_OFFSET] << 8) + | (pucPkt[ETH_TYPE_LEN_OFFSET + 1]); + + if (u2EtherType == ETH_P_IPV4 || u2EtherType == ETH_P_IPV6) { + uint8_t *pucEthBody = &pucPkt[ETH_HLEN]; + uint8_t ucIpProto = + (u2EtherType == ETH_P_IPV4 ? + pucEthBody[IP_PROTO_HLEN] : + pucEthBody[IPV6_HDR_PROTOCOL_OFFSET]); + + if (ucIpProto == IP_PRO_UDP || ucIpProto == IP_PRO_TCP) + return TRUE; + } + + return FALSE; +} + +u_int8_t +qmIsNoDropPacket(IN struct ADAPTER *prAdapter, IN struct SW_RFB *prSwRfb) +{ + uint8_t *pucData = (uint8_t *) prSwRfb->pvHeader; + uint8_t ucBssIndex + = secGetBssIdxByWlanIdx(prAdapter, prSwRfb->ucWlanIdx); + u_int8_t fgCheckDrop = FALSE; + struct BSS_INFO *prBssInfo = NULL; + + if (ucBssIndex <= MAX_BSSID_NUM) + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + +#if CFG_SUPPORT_LOWLATENCY_MODE + if (prAdapter->fgEnLowLatencyMode) + fgCheckDrop = TRUE; +#endif + +#if CFG_SUPPORT_OSHARE + if (!fgCheckDrop && + (prAdapter->fgEnOshareMode) && + prBssInfo && + prBssInfo->eNetworkType == NETWORK_TYPE_P2P) + fgCheckDrop = TRUE; +#endif + +#if CFG_MTK_MDDP_WH_SUPPORT + if (!fgCheckDrop && prAdapter->fgMddpActivated && + prBssInfo && + prBssInfo->eNetworkType == NETWORK_TYPE_P2P) { + struct WIFI_VAR *prWifiVar = NULL; + struct P2P_CONNECTION_SETTINGS *prP2PConnSettings = NULL; + + prWifiVar = &prAdapter->rWifiVar; + if (prWifiVar && prBssInfo->u4PrivateData < BSS_P2P_NUM) { + prP2PConnSettings = prWifiVar->prP2PConnSettings[ + prBssInfo->u4PrivateData]; + fgCheckDrop = prP2PConnSettings && + p2pFuncIsAPMode(prP2PConnSettings); + } + } +#endif + + if (fgCheckDrop && qmIsIPLayerPacket(pucData)) + return TRUE; + + /* For some special packet, like DNS, DHCP, + * do not drop evan fall behind. + */ + if (qmIsIndependentPkt(prSwRfb)) + return TRUE; + + return FALSE; +} + +void qmMoveStaTxQueue(struct STA_RECORD *prSrcStaRec, + struct STA_RECORD *prDstStaRec) +{ + uint8_t ucQueArrayIdx; + struct QUE *prSrcQue = NULL; + struct QUE *prDstQue = NULL; + struct MSDU_INFO *prMsduInfo = NULL; + uint8_t ucDstStaIndex = 0; + + ASSERT(prSrcStaRec); + ASSERT(prDstStaRec); + + prSrcQue = &prSrcStaRec->arTxQueue[0]; + prDstQue = &prDstStaRec->arTxQueue[0]; + ucDstStaIndex = prDstStaRec->ucIndex; + + DBGLOG(QM, INFO, "Pending MSDUs for TC 0~3, %u %u %u %u\n", + prSrcQue[TC0_INDEX].u4NumElem, prSrcQue[TC1_INDEX].u4NumElem, + prSrcQue[TC2_INDEX].u4NumElem, prSrcQue[TC3_INDEX].u4NumElem); + /* Concatenate all MSDU_INFOs in TX queues of this STA_REC */ + for (ucQueArrayIdx = 0; ucQueArrayIdx < TC4_INDEX; ucQueArrayIdx++) { + prMsduInfo = (struct MSDU_INFO *)QUEUE_GET_HEAD( + &prSrcQue[ucQueArrayIdx]); + while (prMsduInfo) { + prMsduInfo->ucStaRecIndex = ucDstStaIndex; + prMsduInfo = (struct MSDU_INFO *)QUEUE_GET_NEXT_ENTRY( + &prMsduInfo->rQueEntry); + } + QUEUE_CONCATENATE_QUEUES((&prDstQue[ucQueArrayIdx]), + (&prSrcQue[ucQueArrayIdx])); + } +} + +void qmHandleDelTspec(struct ADAPTER *prAdapter, struct STA_RECORD *prStaRec, + enum ENUM_ACI eAci) +{ + uint8_t aucNextUP[ACI_NUM] = {1 /* BEtoBK */, 1 /*na */, 0 /*VItoBE */, + 4 /*VOtoVI */}; + enum ENUM_ACI aeNextAci[ACI_NUM] = {ACI_BK, ACI_BK, ACI_BE, ACI_VI}; + uint8_t ucActivedTspec = 0; + uint8_t ucNewUp = 0; + struct QUE *prSrcQue = NULL; + struct QUE *prDstQue = NULL; + struct MSDU_INFO *prMsduInfo = NULL; + struct AC_QUE_PARMS *prAcQueParam = NULL; + uint8_t ucTc = 0; + struct BSS_INFO *prAisBssInfo = NULL; + + if (!prStaRec || eAci == ACI_NUM || eAci == ACI_BK || !prAdapter) { + DBGLOG(QM, ERROR, "prSta NULL %d, eAci %d, prAdapter NULL %d\n", + !prStaRec, eAci, !prAdapter); + return; + } + prAisBssInfo = aisGetAisBssInfo(prAdapter, + prStaRec->ucBssIndex); + if (!prAisBssInfo) { + DBGLOG(QM, ERROR, "prAisBssInfo NULL\n"); + return; + } + + prSrcQue = &prStaRec->arTxQueue[aucWmmAC2TcResourceSet1[eAci]]; + prAcQueParam = &(prAisBssInfo->arACQueParms[0]); + ucActivedTspec = wmmHasActiveTspec( + aisGetWMMInfo(prAdapter, prAisBssInfo->ucBssIndex)); + + while (prAcQueParam[eAci].ucIsACMSet && + !(ucActivedTspec & BIT(eAci)) && eAci != ACI_BK) { + eAci = aeNextAci[eAci]; + ucNewUp = aucNextUP[eAci]; + } + DBGLOG(QM, INFO, "new ACI %d, ACM %d, HasTs %d\n", eAci, + prAcQueParam[eAci].ucIsACMSet, !!(ucActivedTspec & BIT(eAci))); + ucTc = aucWmmAC2TcResourceSet1[eAci]; + prDstQue = &prStaRec->arTxQueue[ucTc]; + prMsduInfo = (struct MSDU_INFO *)QUEUE_GET_HEAD(prSrcQue); + while (prMsduInfo) { + prMsduInfo->ucUserPriority = ucNewUp; + prMsduInfo->ucTC = ucTc; + prMsduInfo = (struct MSDU_INFO *)QUEUE_GET_NEXT_ENTRY( + &prMsduInfo->rQueEntry); + } + QUEUE_CONCATENATE_QUEUES(prDstQue, prSrcQue); +#if QM_ADAPTIVE_TC_RESOURCE_CTRL + qmUpdateAverageTxQueLen(prAdapter); + qmReassignTcResource(prAdapter); +#endif + nicTxAdjustTcq(prAdapter); + kalSetEvent(prAdapter->prGlueInfo); +} + +void qmReleaseCHAtFinishedDhcp(struct ADAPTER *prAdapter, + uint8_t ucBssIndex) +{ + struct BSS_INFO *prBssInfo; + struct AIS_FSM_INFO *prAisFsmInfo = (struct AIS_FSM_INFO *) NULL; + + if (prAdapter == NULL) + return; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + if (prBssInfo == NULL) + return; + + if (IS_BSS_AIS(prBssInfo)) { /* STA */ + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, ucBssIndex); + + if (!timerPendingTimer(&prAisFsmInfo->rJoinTimeoutTimer)) { + DBGLOG(QM, ERROR, "No channel occupation\n"); + } else { + DBGLOG(QM, INFO, "Dhcp done, stop join timer.\n"); + cnmTimerStopTimer(prAdapter, + &prAisFsmInfo->rJoinTimeoutTimer); + aisFsmRunEventJoinTimeout(prAdapter, ucBssIndex); + } + } else if (IS_BSS_P2P(prBssInfo)) { /* GC */ + DBGLOG(QM, INFO, "Dhcp done, stop GC join timer\n"); + p2pRoleFsmNotifyDhcpDone(prAdapter, ucBssIndex); + } +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_ate_agent.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_ate_agent.c new file mode 100644 index 0000000000000000000000000000000000000000..9f2a1578c786aa5a1109a2476d74c07a1139c6a9 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_ate_agent.c @@ -0,0 +1,2688 @@ +/******************************************************************************* + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ +/* + Module Name: + gl_ate_agent.c +*/ +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +#include "precomp.h" +#if CFG_SUPPORT_QA_TOOL +#include "gl_wext.h" +#include "gl_cfg80211.h" +#include "gl_ate_agent.h" +#include "gl_hook_api.h" +#include "gl_qa_agent.h" +#if KERNEL_VERSION(3, 8, 0) <= CFG80211_VERSION_CODE +#include +#endif + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +#if CFG_SUPPORT_TX_BF +union PFMU_PROFILE_TAG1 g_rPfmuTag1; +union PFMU_PROFILE_TAG2 g_rPfmuTag2; +union PFMU_DATA g_rPfmuData; +#endif + +struct ATE_PRIV_CMD { + uint8_t *name; + int (*set_proc)(struct net_device *prNetDev, + uint8_t *prInBuf); +}; + +struct ATE_PRIV_CMD rAtePrivCmdTable[] = { + {"ResetCounter", Set_ResetStatCounter_Proc}, + {"ATE", SetATE}, +#if 0 + {"ADCDump", SetADCDump}, + {"ATEBSSID", SetATEBssid}, +#endif + {"ATEDA", SetATEDa}, + {"ATESA", SetATESa}, + {"ATECHANNEL", SetATEChannel}, + {"ATETXPOW0", SetATETxPower0}, + {"ATETXGI", SetATETxGi}, + {"ATETXBW", SetATETxBw}, + {"ATETXLEN", SetATETxLength}, + {"ATETXCNT", SetATETxCount}, + {"ATETXMCS", SetATETxMcs}, + {"ATETXMODE", SetATETxMode}, + {"ATEIPG", SetATEIpg}, + {"ATEVHTNSS", SetATETxVhtNss}, + {"ATETXANT", SetATETxPath}, + {"ATERXANT", SetATERxPath}, +#if CFG_SUPPORT_ANT_SWAP + {"ATEANTSWP", SetATEAntSwp}, +#endif +#if CFG_SUPPORT_TX_BF + {"TxBfProfileTagHelp", Set_TxBfProfileTag_Help}, + {"TxBfProfileTagInValid", Set_TxBfProfileTag_InValid}, + {"TxBfProfileTagPfmuIdx", Set_TxBfProfileTag_PfmuIdx}, + {"TxBfProfileTagBfType", Set_TxBfProfileTag_BfType}, + {"TxBfProfileTagBw", Set_TxBfProfileTag_DBW}, + {"TxBfProfileTagSuMu", Set_TxBfProfileTag_SuMu}, + {"TxBfProfileTagMemAlloc", Set_TxBfProfileTag_Mem}, + {"TxBfProfileTagMatrix", Set_TxBfProfileTag_Matrix}, + {"TxBfProfileTagSnr", Set_TxBfProfileTag_SNR}, + {"TxBfProfileTagSmtAnt", Set_TxBfProfileTag_SmartAnt}, + {"TxBfProfileTagSeIdx", Set_TxBfProfileTag_SeIdx}, + {"TxBfProfileTagRmsdThrd", Set_TxBfProfileTag_RmsdThrd}, + {"TxBfProfileTagMcsThrd", Set_TxBfProfileTag_McsThrd}, + {"TxBfProfileTagTimeOut", Set_TxBfProfileTag_TimeOut}, + {"TxBfProfileTagDesiredBw", Set_TxBfProfileTag_DesiredBW}, + {"TxBfProfileTagDesiredNc", Set_TxBfProfileTag_DesiredNc}, + {"TxBfProfileTagDesiredNr", Set_TxBfProfileTag_DesiredNr}, + {"TxBfProfileTagRead", Set_TxBfProfileTagRead}, + {"TxBfProfileTagWrite", Set_TxBfProfileTagWrite}, + {"TxBfProfileDataRead", Set_TxBfProfileDataRead}, + {"TxBfProfileDataWrite", Set_TxBfProfileDataWrite}, + {"TxBfProfilePnRead", Set_TxBfProfilePnRead}, + {"TxBfProfilePnWrite", Set_TxBfProfilePnWrite}, + {"TxBfSounding", Set_Trigger_Sounding_Proc}, + {"TxBfSoundingStop", Set_Stop_Sounding_Proc}, + {"TxBfTxApply", Set_TxBfTxApply}, + {"TxBfManualAssoc", Set_TxBfManualAssoc}, + {"TxBfPfmuMemAlloc", Set_TxBfPfmuMemAlloc}, + {"TxBfPfmuMemRelease", Set_TxBfPfmuMemRelease}, + {"StaRecCmmUpdate", Set_StaRecCmmUpdate}, + {"StaRecBfUpdate", Set_StaRecBfUpdate}, + {"DevInfoUpdate", Set_DevInfoUpdate}, + {"BssInfoUpdate", Set_BssInfoUpdate}, +#if CFG_SUPPORT_MU_MIMO + {"MUGetInitMCS", Set_MUGetInitMCS}, + {"MUCalInitMCS", Set_MUCalInitMCS}, + {"MUCalLQ", Set_MUCalLQ}, + {"MUGetLQ", Set_MUGetLQ}, + {"MUSetSNROffset", Set_MUSetSNROffset}, + {"MUSetZeroNss", Set_MUSetZeroNss}, + {"MUSetSpeedUpLQ", Set_MUSetSpeedUpLQ}, + {"MUSetMUTable", Set_MUSetMUTable}, + {"MUSetGroup", Set_MUSetGroup}, + {"MUGetQD", Set_MUGetQD}, + {"MUSetEnable", Set_MUSetEnable}, + {"MUSetGID_UP", Set_MUSetGID_UP}, + {"MUTriggerTx", Set_MUTriggerTx}, +#endif + +#if CFG_SUPPORT_TX_BF_FPGA + {"TxBfProfileSwTagWrite", Set_TxBfProfileSwTagWrite}, +#endif + +#endif + + {"WriteEfuse", WriteEfuse}, + {"TxPower", SetTxTargetPower}, +#if (CFG_SUPPORT_DFS_MASTER == 1) + {"RDDReport", SetRddReport}, + {"ByPassCac", SetByPassCac}, + {"RadarDetectMode", SetRadarDetectMode}, +#endif + + {NULL,} +}; + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to Reset RX Statistic Counters. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prInBuf A pointer to the command string buffer + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +int Set_ResetStatCounter_Proc(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + int32_t i4Status; + + DBGLOG(REQ, INFO, + "ATE_AGENT iwpriv Set_ResetStatCounter_Proc\n"); + + i4Status = MT_ATEResetTXRXCounter(prNetDev); + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to Set Start Test Mode / Stop Test Mode + * / Start TX / Stop TX / Start RX / Stop RX. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prInBuf A pointer to the command string buffer + * \param[out] None + * + * \retval 0 On success. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int SetATE(struct net_device *prNetDev, uint8_t *prInBuf) +{ + int32_t i4Status; + + DBGLOG(REQ, INFO, "ATE_AGENT iwpriv SetATE\n"); + + if (!strcmp(prInBuf, "ATESTART")) { + DBGLOG(REQ, INFO, "ATE_AGENT iwpriv SetATE - ATESTART\n"); + i4Status = MT_ATEStart(prNetDev, prInBuf); + } else if (!strcmp(prInBuf, "ICAPSTART")) { + DBGLOG(REQ, INFO, "ATE_AGENT iwpriv SetATE - ICAPSTART\n"); + i4Status = MT_ICAPStart(prNetDev, prInBuf); + } else if (prInBuf[0] == '1' || prInBuf[0] == '2' + || prInBuf[0] == '3' || prInBuf[0] == '4' + || prInBuf[0] == '5' || prInBuf[0] == '6') { + DBGLOG(REQ, INFO, + "ATE_AGENT iwpriv SetATE - ICAP COMMAND\n"); + i4Status = MT_ICAPCommand(prNetDev, prInBuf); + } else if (!strcmp(prInBuf, "ATESTOP")) { + DBGLOG(REQ, INFO, "ATE_AGENT iwpriv SetATE - ATESTOP\n"); + i4Status = MT_ATEStop(prNetDev, prInBuf); + } else if (!strcmp(prInBuf, "TXFRAME")) { + DBGLOG(REQ, INFO, "ATE_AGENT iwpriv SetATE - TXFRAME\n"); + i4Status = MT_ATEStartTX(prNetDev, prInBuf); + } else if (!strcmp(prInBuf, "TXSTOP")) { + DBGLOG(REQ, INFO, "ATE_AGENT iwpriv SetATE - TXSTOP\n"); + i4Status = MT_ATEStopTX(prNetDev, prInBuf); + } else if (!strcmp(prInBuf, "RXFRAME")) { + DBGLOG(REQ, INFO, "ATE_AGENT iwpriv SetATE - RXFRAME\n"); + i4Status = MT_ATEStartRX(prNetDev, prInBuf); + } else if (!strcmp(prInBuf, "RXSTOP")) { + DBGLOG(REQ, INFO, "ATE_AGENT iwpriv SetATE - RXSTOP\n"); + i4Status = MT_ATEStopRX(prNetDev, prInBuf); + } else { + return -EINVAL; + } + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to Set TX Destination Address. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prInBuf A pointer to the command string buffer + * \param[out] None + * + * \retval 0 On success. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int SetATEDa(struct net_device *prNetDev, uint8_t *prInBuf) +{ + int32_t i4Status = 0; + uint32_t addr[MAC_ADDR_LEN]; + uint8_t addr2[MAC_ADDR_LEN]; + int32_t rv; + + DBGLOG(RFTEST, ERROR, "ATE_AGENT iwpriv SetDa\n"); + /* xx:xx:xx:xx:xx:xx */ + rv = sscanf(prInBuf, "%x:%x:%x:%x:%x:%x", &addr[0], + &addr[1], &addr[2], &addr[3], &addr[4], &addr[5]); + if (rv == 6) { + DBGLOG(RFTEST, ERROR, + "ATE_AGENT iwpriv SetATEDa Sa:%02x:%02x:%02x:%02x:%02x:%02x\n", + addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); + + addr2[0] = (uint8_t) addr[0]; + addr2[1] = (uint8_t) addr[1]; + addr2[2] = (uint8_t) addr[2]; + addr2[3] = (uint8_t) addr[3]; + addr2[4] = (uint8_t) addr[4]; + addr2[5] = (uint8_t) addr[5]; + + i4Status = MT_ATESetMACAddress(prNetDev, + RF_AT_FUNCID_SET_MAC_ADDRESS, addr2); + } else { + return -EINVAL; + } + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to Set TX Source Address. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prInBuf A pointer to the command string buffer + * \param[out] None + * + * \retval 0 On success. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int SetATESa(struct net_device *prNetDev, uint8_t *prInBuf) +{ + int32_t i4Status = 0; + uint32_t addr[MAC_ADDR_LEN]; + uint8_t addr2[MAC_ADDR_LEN]; + int32_t rv; + + DBGLOG(RFTEST, ERROR, "ATE_AGENT iwpriv SetSa\n"); + /* xx:xx:xx:xx:xx:xx */ + rv = sscanf(prInBuf, "%x:%x:%x:%x:%x:%x", &addr[0], + &addr[1], &addr[2], &addr[3], &addr[4], &addr[5]); + if (rv == 6) { + DBGLOG(RFTEST, ERROR, + "ATE_AGENT iwpriv SetATESa Sa:%02x:%02x:%02x:%02x:%02x:%02x\n", + addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); + + addr2[0] = (uint8_t) addr[0]; + addr2[1] = (uint8_t) addr[1]; + addr2[2] = (uint8_t) addr[2]; + addr2[3] = (uint8_t) addr[3]; + addr2[4] = (uint8_t) addr[4]; + addr2[5] = (uint8_t) addr[5]; + + i4Status = MT_ATESetMACAddress(prNetDev, + RF_AT_FUNCID_SET_TA, addr2); + } else { + return -EINVAL; + } + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to Set Channel Frequency. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prInBuf A pointer to the command string buffer + * \param[out] None + * + * \retval 0 On success. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int SetATEChannel(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + uint32_t i4SetFreq = 0; + int32_t i4Status, i4SetChan = 0; + int32_t rv; + + DBGLOG(REQ, INFO, "ATE_AGENT iwpriv SetChannel\n"); + + rv = kstrtoint(prInBuf, 0, &i4SetChan); + if (rv == 0) { + i4SetFreq = nicChannelNum2Freq(i4SetChan); + i4Status = MT_ATESetChannel(prNetDev, 0, i4SetFreq); + } else + return -EINVAL; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to Set TX WF0 Power. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prInBuf A pointer to the command string buffer + * \param[out] None + * + * \retval 0 On success. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int SetATETxPower0(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + uint32_t i4SetTxPower0 = 0; + int32_t i4Status; + int32_t rv; + + DBGLOG(REQ, INFO, "ATE_AGENT iwpriv SetTxPower0\n"); + + rv = kstrtoint(prInBuf, 0, &i4SetTxPower0); + if (rv == 0) + i4Status = MT_ATESetTxPower0(prNetDev, i4SetTxPower0); + else + return -EINVAL; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to Set TX Guard Interval. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prInBuf A pointer to the command string buffer + * \param[out] None + * + * \retval 0 On success. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int SetATETxGi(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + uint32_t i4SetTxGi = 0; + int32_t i4Status; + int32_t rv; + + DBGLOG(REQ, INFO, "ATE_AGENT iwpriv SetTxGi\n"); + + rv = kstrtoint(prInBuf, 0, &i4SetTxGi); + if (rv == 0) + i4Status = MT_ATESetTxGi(prNetDev, i4SetTxGi); + else + return -EINVAL; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to Set TX System Bandwidth. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prInBuf A pointer to the command string buffer + * \param[out] None + * + * \retval 0 On success. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int SetATETxBw(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + uint32_t i4SetSystemBW = 0; + int32_t i4Status; + int32_t rv; + + DBGLOG(REQ, INFO, "ATE_AGENT iwpriv SetSystemBW\n"); + + rv = kstrtoint(prInBuf, 0, &i4SetSystemBW); + if (rv == 0) + i4Status = MT_ATESetSystemBW(prNetDev, i4SetSystemBW); + else + return -EINVAL; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to Set TX Mode (Preamble). + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prInBuf A pointer to the command string buffer + * \param[out] None + * + * \retval 0 On success. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int SetATETxMode(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + uint32_t i4SetTxMode = 0; + int32_t i4Status; + int32_t rv; + + DBGLOG(REQ, INFO, "ATE_AGENT iwpriv SetTxMode\n"); + + rv = kstrtoint(prInBuf, 0, &i4SetTxMode); + if (rv == 0) + i4Status = MT_ATESetPreamble(prNetDev, i4SetTxMode); + else + return -EINVAL; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to Set TX Length. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prInBuf A pointer to the command string buffer + * \param[out] None + * + * \retval 0 On success. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int SetATETxLength(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + uint32_t i4SetTxLength = 0; + int32_t i4Status; + int32_t rv; + + DBGLOG(REQ, INFO, "ATE_AGENT iwpriv SetTxLength\n"); + + rv = kstrtoint(prInBuf, 0, &i4SetTxLength); + if (rv == 0) + i4Status = MT_ATESetTxLength(prNetDev, i4SetTxLength); + else + return -EINVAL; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to Set TX Count. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prInBuf A pointer to the command string buffer + * \param[out] None + * + * \retval 0 On success. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int SetATETxCount(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + uint32_t i4SetTxCount = 0; + int32_t i4Status; + int32_t rv; + uint8_t addr[MAC_ADDR_LEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; + + DBGLOG(REQ, INFO, "ATE_AGENT iwpriv SetTxCount\n"); + + rv = kstrtoint(prInBuf, 0, &i4SetTxCount); + if (rv == 0) + i4Status = MT_ATESetTxCount(prNetDev, i4SetTxCount); + else + return -EINVAL; + + i4Status = MT_ATESetMACAddress(prNetDev, + RF_AT_FUNCID_SET_MAC_ADDRESS, addr); + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to Set TX Rate. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prInBuf A pointer to the command string buffer + * \param[out] None + * + * \retval 0 On success. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int SetATETxMcs(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + uint32_t i4SetTxMcs = 0; + int32_t i4Status; + int32_t rv; + + DBGLOG(REQ, INFO, "ATE_AGENT iwpriv SetTxMcs\n"); + + rv = kstrtoint(prInBuf, 0, &i4SetTxMcs); + if (rv == 0) + i4Status = MT_ATESetRate(prNetDev, i4SetTxMcs); + else + return -EINVAL; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to Set Inter-Packet Guard Interval. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prInBuf A pointer to the command string buffer + * \param[out] None + * + * \retval 0 On success. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int SetATEIpg(struct net_device *prNetDev, uint8_t *prInBuf) +{ + uint32_t i4SetTxIPG = 0; + int32_t i4Status; + int32_t rv; + + DBGLOG(REQ, INFO, "ATE_AGENT iwpriv SetIpg\n"); + + rv = kstrtoint(prInBuf, 0, &i4SetTxIPG); + if (rv == 0) + i4Status = MT_ATESetTxIPG(prNetDev, i4SetTxIPG); + else + return -EINVAL; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to Set Inter-Packet Guard Interval. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prInBuf A pointer to the command string buffer + * \param[out] None + * + * \retval 0 On success. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int SetATETxVhtNss(struct net_device *prNetDev, uint8_t *prInBuf) +{ + uint32_t i4SetTVhtNSS = 0; + int32_t i4Status; + int32_t rv; + + DBGLOG(REQ, INFO, "ATE_AGENT iwpriv SetATETxVhtNss\n"); + + rv = kstrtoint(prInBuf, 0, &i4SetTVhtNSS); + if (rv == 0) + i4Status = MT_ATESetTxVhtNss(prNetDev, i4SetTVhtNSS); + else + return -EINVAL; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to Set Inter-Packet Guard Interval. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prInBuf A pointer to the command string buffer + * \param[out] None + * + * \retval 0 On success. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int SetATETxPath(struct net_device *prNetDev, uint8_t *prInBuf) +{ + uint32_t i4TxPath = 0; + int32_t i4Status; + int32_t rv; + + DBGLOG(REQ, INFO, "ATE_AGENT iwpriv SetATETxPath\n"); + + rv = kstrtoint(prInBuf, 0, &i4TxPath); + if (rv == 0) + i4Status = MT_ATESetTxPath(prNetDev, i4TxPath); + else + return -EINVAL; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to Set Inter-Packet Guard Interval. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prInBuf A pointer to the command string buffer + * \param[out] None + * + * \retval 0 On success. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int SetATERxPath(struct net_device *prNetDev, uint8_t *prInBuf) +{ + uint32_t i4RxPath = 0; + int32_t i4Status; + int32_t rv; + + DBGLOG(REQ, INFO, "ATE_AGENT iwpriv SetATERxPath\n"); + + rv = kstrtoint(prInBuf, 0, &i4RxPath); + if (rv == 0) + i4Status = MT_ATESetRxPath(prNetDev, i4RxPath); + else + return -EINVAL; + + return i4Status; +} + +#if CFG_SUPPORT_ANT_SWAP +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to Set Antenna Swap + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prInBuf A pointer to the command string buffer + * \param[out] None + * + * \retval 0 On success. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int SetATEAntSwp(struct net_device *prNetDev, uint8_t *prInBuf) +{ + uint32_t i4SetAntSwp = 0; + int32_t i4Status; + int32_t rv; + + DBGLOG(REQ, INFO, "ATE_AGENT iwpriv SetAntSwp\n"); + + rv = kstrtoint(prInBuf, 0, &i4SetAntSwp); + if (rv == 0) { + DBGLOG(REQ, INFO, "i4SetAntSwp = %d\n", i4SetAntSwp); + i4Status = MT_ATESetAntSwap(prNetDev, i4SetAntSwp); + } else + return -EINVAL; + + return i4Status; +} +#endif + +#if CFG_SUPPORT_TX_BF +int Set_TxBfProfileTag_Help(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + DBGLOG(RFTEST, ERROR, + "========================================================================================================================\n" + "TxBfProfile Tag1 setting example :\n" + "iwpriv ra0 set TxBfProfileTagPfmuIdx =xx\n" + "iwpriv ra0 set TxBfProfileTagBfType =xx (0: iBF; 1: eBF)\n" + "iwpriv ra0 set TxBfProfileTagBw =xx (0/1/2/3 : BW20/40/80/160NC)\n" + "iwpriv ra0 set TxBfProfileTagSuMu =xx (0:SU, 1:MU)\n" + "iwpriv ra0 set TxBfProfileTagInvalid =xx (0: valid, 1: invalid)\n" + "iwpriv ra0 set TxBfProfileTagMemAlloc =xx:xx:xx:xx:xx:xx:xx:xx (mem_row, mem_col), ..\n" + "iwpriv ra0 set TxBfProfileTagMatrix =nrow:nol:ng:LM\n" + "iwpriv ra0 set TxBfProfileTagSnr =SNR_STS0:SNR_STS1:SNR_STS2:SNR_STS3\n" + "\n\n" + "TxBfProfile Tag2 setting example :\n" + "iwpriv ra0 set TxBfProfileTagSmtAnt =xx (11:0)\n" + "iwpriv ra0 set TxBfProfileTagSeIdx =xx\n" + "iwpriv ra0 set TxBfProfileTagRmsdThrd =xx\n" + "iwpriv ra0 set TxBfProfileTagMcsThrd =xx:xx:xx:xx:xx:xx (MCS TH L1SS:S1SS:L2SS:....)\n" + "iwpriv ra0 set TxBfProfileTagTimeOut =xx\n" + "iwpriv ra0 set TxBfProfileTagDesiredBw=xx (0/1/2/3 : BW20/40/80/160NC)\n" + "iwpriv ra0 set TxBfProfileTagDesiredNc=xx\n" + "iwpriv ra0 set TxBfProfileTagDesiredNr=xx\n" + "\n\n" + "Read TxBf profile Tag :\n" + "iwpriv ra0 set TxBfProfileTagRead =xx (PFMU ID)\n" + "\n" + "Write TxBf profile Tag :\n" + "iwpriv ra0 set TxBfProfileTagWrite =xx (PFMU ID)\n" + "When you use one of relative CMD to update one of tag parameters, you should call TxBfProfileTagWrite to update Tag\n" + "\n\n" + "Read TxBf profile Data :\n" + "iwpriv ra0 set TxBfProfileDataRead =xx (PFMU ID)\n" + "\n" + "Write TxBf profile Data :\n" + "iwpriv ra0 set TxBfProfileDataWrite =BW :subcarrier:phi11:psi2l:Phi21:Psi31:Phi31:Psi41:Phi22:Psi32:Phi32:Psi42:Phi33:Psi43\n" + "iwpriv ra0 set TxBfProfileDataWriteAll=Profile ID : BW (BW : 0x00 (20M) , 0x01 (40M), 0x02 (80M), 0x3 (160M)\n" + "When you use CMD TxBfProfileDataWrite to update profile data per subcarrier, you should call TxBfProfileDataWriteAll to update all of\n" + "subcarrier's profile data.\n\n" + "Read TxBf profile PN :\n" + "iwpriv ra0 set TxBfProfilePnRead =xx (PFMU ID)\n" + "\n" + "Write TxBf profile PN :\n" + "iwpriv ra0 set TxBfProfilePnWrite =Profile ID:BW:1STS_Tx0:1STS_Tx1:1STS_Tx2:1STS_Tx3:2STS_Tx0:2STS_Tx1:2STS_Tx2:2STS_Tx3:3STS_Tx1:3STS_Tx2:3STS_Tx3\n" + "========================================================================================================================\n"); + return 0; +} + +int Set_TxBfProfileTag_InValid(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + uint32_t ucInValid; + int32_t i4Status = 0; + int32_t rv; + + DBGLOG(RFTEST, ERROR, "Set_TxBfProfileTag_InValid\n"); + + rv = kstrtoint(prInBuf, 0, &ucInValid); + if (rv == 0) { + DBGLOG(RFTEST, ERROR, + "Set_TxBfProfileTag_InValid prInBuf = %s, ucInValid = %d\n", + prInBuf, + ucInValid); + i4Status = TxBfProfileTag_InValid(prNetDev, &g_rPfmuTag1, + ucInValid); + } else + return -EINVAL; + + return i4Status; +} + +int Set_TxBfProfileTag_PfmuIdx(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + uint32_t ucProfileIdx; + int32_t i4Status = 0; + int32_t rv; + + DBGLOG(RFTEST, ERROR, "Set_TxBfProfileTag_PfmuIdx\n"); + + rv = kstrtoint(prInBuf, 0, &ucProfileIdx); + if (rv == 0) { + DBGLOG(RFTEST, ERROR, + "Set_TxBfProfileTag_PfmuIdx prInBuf = %s, ucProfileIdx = %d\n", + prInBuf, + ucProfileIdx); + i4Status = TxBfProfileTag_PfmuIdx(prNetDev, &g_rPfmuTag1, + ucProfileIdx); + } else + return -EINVAL; + + return i4Status; +} + +int Set_TxBfProfileTag_BfType(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + uint32_t ucBFType; + int32_t i4Status = 0; + int32_t rv; + + DBGLOG(RFTEST, ERROR, "Set_TxBfProfileTag_BfType\n"); + + rv = kstrtoint(prInBuf, 0, &ucBFType); + if (rv == 0) { + DBGLOG(RFTEST, ERROR, + "Set_TxBfProfileTag_BfType prInBuf = %s, ucBFType = %d\n", + prInBuf, ucBFType); + i4Status = TxBfProfileTag_TxBfType(prNetDev, &g_rPfmuTag1, + ucBFType); + } else + return -EINVAL; + + return i4Status; +} + +int Set_TxBfProfileTag_DBW(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + uint32_t ucBW; + int32_t i4Status = 0; + int32_t rv; + + DBGLOG(RFTEST, ERROR, "Set_TxBfProfileTag_DBW\n"); + + rv = kstrtoint(prInBuf, 0, &ucBW); + if (rv == 0) { + DBGLOG(RFTEST, ERROR, + "Set_TxBfProfileTag_DBW prInBuf = %s, ucBW = %d\n", + prInBuf, ucBW); + i4Status = TxBfProfileTag_DBW(prNetDev, &g_rPfmuTag1, ucBW); + } else + return -EINVAL; + + return i4Status; +} + +int Set_TxBfProfileTag_SuMu(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + uint32_t ucSuMu; + int32_t i4Status = 0; + int32_t rv; + + DBGLOG(RFTEST, ERROR, "Set_TxBfProfileTag_SuMu\n"); + + rv = kstrtoint(prInBuf, 0, &ucSuMu); + if (rv == 0) { + DBGLOG(RFTEST, ERROR, + "Set_TxBfProfileTag_SuMu prInBuf = %s, ucSuMu = %d\n", + prInBuf, ucSuMu); + i4Status = TxBfProfileTag_SuMu(prNetDev, &g_rPfmuTag1, + ucSuMu); + } else + return -EINVAL; + + return i4Status; +} + +int Set_TxBfProfileTag_Mem(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + uint32_t aucInput[8]; + int32_t i4Status = 0; + uint8_t aucMemAddrColIdx[4], aucMemAddrRowIdx[4]; + int32_t rv; + + DBGLOG(RFTEST, ERROR, "Set_TxBfProfileTag_Mem\n"); + + rv = sscanf(prInBuf, "%d:%d:%d:%d:%d:%d:%d:%d", + &aucInput[0], &aucInput[1], &aucInput[2], &aucInput[3], + &aucInput[4], &aucInput[5], &aucInput[6], + &aucInput[7]); + /* mem col0:row0:col1:row1:col2:row2:col3:row3 */ + if (rv == 8) { + DBGLOG(RFTEST, ERROR, + "ATE_AGENT iwpriv Set_TxBfProfileTag_Mem aucInput:%d:%d:%d:%d:%d:%d:%d:%d\n", + aucInput[0], aucInput[1], aucInput[2], aucInput[3], + aucInput[4], aucInput[5], aucInput[6], + aucInput[7]); + + aucMemAddrColIdx[0] = (uint8_t) aucInput[0]; + aucMemAddrRowIdx[0] = (uint8_t) aucInput[1]; + aucMemAddrColIdx[1] = (uint8_t) aucInput[2]; + aucMemAddrRowIdx[1] = (uint8_t) aucInput[3]; + aucMemAddrColIdx[2] = (uint8_t) aucInput[4]; + aucMemAddrRowIdx[2] = (uint8_t) aucInput[5]; + aucMemAddrColIdx[3] = (uint8_t) aucInput[6]; + aucMemAddrRowIdx[3] = (uint8_t) aucInput[7]; + + i4Status = TxBfProfileTag_Mem(prNetDev, &g_rPfmuTag1, + aucMemAddrColIdx, aucMemAddrRowIdx); + } else + return -EINVAL; + + return i4Status; +} + +int Set_TxBfProfileTag_Matrix(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + uint32_t aucInput[6]; + uint8_t ucNrow, ucNcol, ucNgroup, ucLM, ucCodeBook, + ucHtcExist; + int32_t i4Status = 0; + int32_t rv; + + DBGLOG(RFTEST, ERROR, "Set_TxBfProfileTag_Matrix\n"); + + rv = sscanf(prInBuf, "%d:%d:%d:%d:%d:%d", + &aucInput[0], &aucInput[1], &aucInput[2], &aucInput[3], + &aucInput[4], &aucInput[5]); + /* nrow:nol:ng:LM:CodeBook:HtcExist */ + if (rv == 6) { + DBGLOG(RFTEST, ERROR, + "ATE_AGENT iwpriv Set_TxBfProfileTag_Matrix aucInput:%d:%d:%d:%d:%d:%d\n", + aucInput[0], aucInput[1], aucInput[2], aucInput[3], + aucInput[4], aucInput[5]); + ucNrow = (uint8_t) aucInput[0]; + ucNcol = (uint8_t) aucInput[1]; + ucNgroup = (uint8_t) aucInput[2]; + ucLM = (uint8_t) aucInput[3]; + ucCodeBook = (uint8_t) aucInput[4]; + ucHtcExist = (uint8_t) aucInput[5]; + + i4Status = TxBfProfileTag_Matrix(prNetDev, &g_rPfmuTag1, ucNrow, + ucNcol, ucNgroup, ucLM, ucCodeBook, ucHtcExist); + } else + return -EINVAL; + + return i4Status; +} + +int Set_TxBfProfileTag_SNR(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + uint32_t aucInput[4]; + uint8_t ucSNR_STS0, ucSNR_STS1, ucSNR_STS2, ucSNR_STS3; + int32_t i4Status = 0; + int32_t rv; + + DBGLOG(RFTEST, ERROR, "Set_TxBfProfileTag_SNR\n"); + + rv = sscanf(prInBuf, "%d:%d:%d:%d", &aucInput[0], + &aucInput[1], &aucInput[2], &aucInput[3]); + if (rv == 4) { + DBGLOG(RFTEST, ERROR, + "ATE_AGENT iwpriv Set_TxBfProfileTag_SNR aucInput:%d:%d:%d:%d\n", + aucInput[0], aucInput[1], aucInput[2], aucInput[3]); + + ucSNR_STS0 = (uint8_t) aucInput[0]; + ucSNR_STS1 = (uint8_t) aucInput[1]; + ucSNR_STS2 = (uint8_t) aucInput[2]; + ucSNR_STS3 = (uint8_t) aucInput[3]; + + i4Status = TxBfProfileTag_SNR(prNetDev, &g_rPfmuTag1, + ucSNR_STS0, ucSNR_STS1, ucSNR_STS2, ucSNR_STS3); + } else + return -EINVAL; + + return i4Status; +} + +int Set_TxBfProfileTag_SmartAnt(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + int32_t i4Status = 0; + uint32_t ucSmartAnt; + int32_t rv; + + DBGLOG(RFTEST, ERROR, "Set_TxBfProfileTag_SmartAnt\n"); + + rv = kstrtoint(prInBuf, 0, &ucSmartAnt); + if (rv == 0) { + DBGLOG(RFTEST, ERROR, + "Set_TxBfProfileTag_SmartAnt prInBuf = %s, ucSmartAnt = %d\n", + prInBuf, + ucSmartAnt); + i4Status = TxBfProfileTag_SmtAnt(prNetDev, &g_rPfmuTag2, + ucSmartAnt); + } else + return -EINVAL; + + return i4Status; +} + +int Set_TxBfProfileTag_SeIdx(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + int32_t i4Status = 0; + uint32_t ucSeIdx; + int32_t rv; + + DBGLOG(RFTEST, ERROR, "Set_TxBfProfileTag_SeIdx\n"); + + rv = kstrtoint(prInBuf, 0, &ucSeIdx); + if (rv == 0) { + DBGLOG(RFTEST, ERROR, + "TxBfProfileTag_SeIdx prInBuf = %s, ucSeIdx = %d\n", + prInBuf, ucSeIdx); + i4Status = TxBfProfileTag_SeIdx(prNetDev, &g_rPfmuTag2, + ucSeIdx); + } else + return -EINVAL; + + return i4Status; +} + +int Set_TxBfProfileTag_RmsdThrd(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + int32_t i4Status = 0; + uint32_t ucRmsdThrd; + int32_t rv; + + DBGLOG(RFTEST, ERROR, "Set_TxBfProfileTag_RmsdThrd\n"); + + rv = kstrtoint(prInBuf, 0, &ucRmsdThrd); + if (rv == 0) { + DBGLOG(RFTEST, ERROR, + "Set_TxBfProfileTag_RmsdThrd prInBuf = %s, ucRmsdThrd = %d\n", + prInBuf, + ucRmsdThrd); + i4Status = TxBfProfileTag_RmsdThd(prNetDev, &g_rPfmuTag2, + ucRmsdThrd); + } else + return -EINVAL; + + return i4Status; +} + +int Set_TxBfProfileTag_McsThrd(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + uint32_t aucInput[6]; + uint8_t ucMcsLss[3], ucMcsSss[3]; + int32_t i4Status = 0; + int32_t rv; + + DBGLOG(RFTEST, ERROR, "Set_TxBfProfileTag_McsThrd\n"); + + rv = sscanf(prInBuf, "%d:%d:%d:%d:%d:%d", + &aucInput[0], &aucInput[1], &aucInput[2], &aucInput[3], + &aucInput[4], &aucInput[5]); + if (rv == 6) { + DBGLOG(RFTEST, ERROR, + "ATE_AGENT iwpriv Set_TxBfProfileTag_McsThrd aucInput:%d:%d:%d:%d:%d:%d\n", + aucInput[0], aucInput[1], aucInput[2], aucInput[3], + aucInput[4], aucInput[5]); + + ucMcsLss[0] = (uint8_t) aucInput[0]; + ucMcsSss[0] = (uint8_t) aucInput[1]; + ucMcsLss[1] = (uint8_t) aucInput[2]; + ucMcsSss[1] = (uint8_t) aucInput[3]; + ucMcsLss[2] = (uint8_t) aucInput[4]; + ucMcsSss[2] = (uint8_t) aucInput[5]; + + i4Status = TxBfProfileTag_McsThd(prNetDev, &g_rPfmuTag2, + ucMcsLss, ucMcsSss); + } else + return -EINVAL; + + return i4Status; +} + +int Set_TxBfProfileTag_TimeOut(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + uint32_t ucTimeOut; + int32_t i4Status = 0; + int32_t rv; + + DBGLOG(RFTEST, ERROR, "Set_TxBfProfileTag_TimeOut\n"); + + rv = kstrtouint(prInBuf, 0, &ucTimeOut); + if (rv == 0) { + DBGLOG(RFTEST, ERROR, + "Set_TxBfProfileTag_TimeOut prInBuf = %s, ucTimeOut = %d\n", + prInBuf, + ucTimeOut); + i4Status = TxBfProfileTag_TimeOut(prNetDev, &g_rPfmuTag2, + ucTimeOut); + } else + return -EINVAL; + + return i4Status; +} + +int Set_TxBfProfileTag_DesiredBW(struct net_device + *prNetDev, uint8_t *prInBuf) +{ + uint32_t ucDesiredBW; + int32_t i4Status = 0; + int32_t rv; + + DBGLOG(RFTEST, ERROR, "Set_TxBfProfileTag_DesiredBW\n"); + + rv = kstrtoint(prInBuf, 0, &ucDesiredBW); + if (rv == 0) { + DBGLOG(RFTEST, ERROR, + "Set_TxBfProfileTag_DesiredBW prInBuf = %s, ucDesiredBW = %d\n", + prInBuf, + ucDesiredBW); + i4Status = TxBfProfileTag_DesiredBW(prNetDev, &g_rPfmuTag2, + ucDesiredBW); + } else + return -EINVAL; + + return i4Status; +} + +int Set_TxBfProfileTag_DesiredNc(struct net_device + *prNetDev, uint8_t *prInBuf) +{ + uint32_t ucDesiredNc; + int32_t i4Status = 0; + int32_t rv; + + DBGLOG(RFTEST, ERROR, "Set_TxBfProfileTag_DesiredNc\n"); + + rv = kstrtoint(prInBuf, 0, &ucDesiredNc); + if (rv == 0) { + DBGLOG(RFTEST, ERROR, + "Set_TxBfProfileTag_DesiredNc prInBuf = %s, ucDesiredNc = %d\n", + prInBuf, + ucDesiredNc); + i4Status = TxBfProfileTag_DesiredNc(prNetDev, &g_rPfmuTag2, + ucDesiredNc); + } else + return -EINVAL; + + return i4Status; +} + +int Set_TxBfProfileTag_DesiredNr(struct net_device + *prNetDev, uint8_t *prInBuf) +{ + uint32_t ucDesiredNr; + int32_t i4Status = 0; + int32_t rv; + + DBGLOG(RFTEST, ERROR, "Set_TxBfProfileTag_DesiredNr\n"); + + rv = kstrtoint(prInBuf, 0, &ucDesiredNr); + if (rv == 0) { + DBGLOG(RFTEST, ERROR, + "Set_TxBfProfileTag_DesiredNr prInBuf = %s, ucDesiredNr = %d\n", + prInBuf, + ucDesiredNr); + i4Status = TxBfProfileTag_DesiredNr(prNetDev, &g_rPfmuTag2, + ucDesiredNr); + } else + return -EINVAL; + + return i4Status; +} + +int Set_TxBfProfileTagWrite(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + uint32_t profileIdx; + int32_t i4Status = 0; + int32_t rv; + + DBGLOG(RFTEST, ERROR, "Set_TxBfProfileTagWrite\n"); + + rv = kstrtoint(prInBuf, 0, &profileIdx); + if (rv == 0) { + DBGLOG(RFTEST, ERROR, + "Set_TxBfProfileTagWrite prInBuf = %s, profileIdx = %d\n", + prInBuf, + profileIdx); + i4Status = TxBfProfileTagWrite(prNetDev, &g_rPfmuTag1, + &g_rPfmuTag2, profileIdx); + } else + return -EINVAL; + + return i4Status; +} + +int Set_TxBfProfileTagRead(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + uint32_t profileIdx, fgBFer; + int32_t i4Status = 0; + int32_t rv; + + DBGLOG(RFTEST, ERROR, "Set_TxBfProfileTagRead\n"); + + rv = sscanf(prInBuf, "%d:%d", &profileIdx, &fgBFer); + if (rv == 2) { + DBGLOG(RFTEST, ERROR, + "Set_TxBfProfileTagRead prInBuf = %s, profileIdx = %d, fgBFer = %d\n", + prInBuf, profileIdx, fgBFer); + i4Status = TxBfProfileTagRead(prNetDev, profileIdx, fgBFer); + } else + return -EINVAL; + + return i4Status; +} + +int Set_TxBfProfileDataRead(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + uint32_t profileIdx, fgBFer, subcarrierIdxMsb, + subcarrierIdxLsb; + int32_t i4Status = 0; + int32_t rv; + + DBGLOG(RFTEST, ERROR, "Set_TxBfProfileDataRead\n"); + + rv = sscanf(prInBuf, "%d:%d:%x:%x", &profileIdx, &fgBFer, + &subcarrierIdxMsb, &subcarrierIdxLsb); + if (rv == 4) { + DBGLOG(RFTEST, ERROR, + "Set_TxBfProfileDataRead prInBuf = %s, profileIdx = %d, fgBFer = %d, subcarrierIdxMsb:%x, subcarrierIdxLsb:%x\n", + prInBuf, profileIdx, fgBFer, subcarrierIdxMsb, + subcarrierIdxLsb); + i4Status = TxBfProfileDataRead(prNetDev, profileIdx, fgBFer, + subcarrierIdxMsb, subcarrierIdxLsb); + } else + return -EINVAL; + + return i4Status; +} + +int Set_TxBfProfileDataWrite(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + + uint32_t u4ProfileIdx; + uint32_t u4SubcarrierIdx; + uint32_t au4Phi[6]; + uint32_t au4Psi[6]; + uint32_t au4DSnr[4]; + uint16_t au2Phi[6]; + uint8_t aucPsi[6]; + uint8_t aucDSnr[4]; + uint32_t i; + int32_t rv; + + int32_t i4Status = 0; + + DBGLOG(RFTEST, ERROR, "TxBfProfileDataWrite\n"); + + rv = sscanf(prInBuf, + "%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x", + &u4ProfileIdx, &u4SubcarrierIdx, &au4Phi[0], &au4Psi[0], + &au4Phi[1], &au4Psi[1], + &au4Phi[2], &au4Psi[2], &au4Phi[3], &au4Psi[3], &au4Phi[4], + &au4Psi[4], + &au4Phi[5], &au4Psi[5], + &au4DSnr[0], &au4DSnr[1], &au4DSnr[2], &au4DSnr[3]); + + if (rv == 18) { + DBGLOG(RFTEST, ERROR, + "TxBfProfileDataWrite prInBuf = %s, u4ProfileIdx = %x, u4SubcarrierIdx = %x, au4Phi[0]:%x, au4Phi[1]:%x, au4Phi[2]:%x, au4Phi[3]:%x, au4Phi[4]:%x, au4Phi[5]:%x, au4Psi[0]:%x, au4Psi[1]:%x, au4Psi[2]:%x, au4Psi[3]:%x, au4Psi[4]:%x, au4Psi[5]:%x,au4DSnr[0]:%x, au4DSnr[1]:%x, au4DSnr[2]:%x, au4DSnr[3]:%x\n", + prInBuf, u4ProfileIdx, u4SubcarrierIdx, + au4Phi[0], au4Phi[1], au4Phi[2], au4Phi[3], au4Phi[4], + au4Phi[5], + au4Psi[0], au4Psi[1], au4Psi[2], au4Psi[3], au4Psi[4], + au4Psi[5], + au4DSnr[0], au4DSnr[1], au4DSnr[2], au4DSnr[3]); + for (i = 0; i < 6; i++) { + au2Phi[i] = au4Phi[i]; + aucPsi[i] = au4Psi[i]; + } + for (i = 0; i < 4; i++) + aucDSnr[i] = au4DSnr[i]; + + i4Status = TxBfProfileDataWrite(prNetDev, u4ProfileIdx, + u4SubcarrierIdx, au2Phi, aucPsi, aucDSnr); + } else + return -EINVAL; + + return i4Status; +} + +int Set_TxBfProfilePnRead(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + uint32_t profileIdx; + int32_t i4Status = 0; + int32_t rv; + + DBGLOG(RFTEST, ERROR, "Set_TxBfProfilePnRead\n"); + + rv = kstrtoint(prInBuf, 0, &profileIdx); + if (rv == 0) { + DBGLOG(RFTEST, ERROR, + "Set_TxBfProfilePnRead prInBuf = %s, profileIdx = %d\n", + prInBuf, profileIdx); + i4Status = TxBfProfilePnRead(prNetDev, profileIdx); + } else + return -EINVAL; + + return i4Status; +} + +int Set_TxBfProfilePnWrite(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + uint32_t u4ProfileIdx; + uint16_t u2bw; + uint16_t au2XSTS[12]; + int32_t rv; + + int32_t i4Status = 0; + + DBGLOG(RFTEST, ERROR, "TxBfProfilePnWrite\n"); + + rv = sscanf(prInBuf, + "%d:%hd:%hd:%hd:%hd:%hd:%hd:%hd:%hd:%hd:%hd:%hd:%hd:%hd", + &u4ProfileIdx, &u2bw, &au2XSTS[0], &au2XSTS[1], &au2XSTS[2], + &au2XSTS[3], + &au2XSTS[4], &au2XSTS[5], &au2XSTS[6], &au2XSTS[7], + &au2XSTS[8], &au2XSTS[9], &au2XSTS[10], + &au2XSTS[11]); + if (rv == 14) { + DBGLOG(RFTEST, ERROR, + "TxBfProfilePnWrite prInBuf = %s, ucProfileIdx = %d, u2bw = %dau2XSTS[0]:%d, au2XSTS[1]:%d, au2XSTS[2]:%d, au2XSTS[3]:%d, au2XSTS[4]:%d, au2XSTS[5]:%d, au2XSTS[6]:%d, au2XSTS[7]:%d, au2XSTS[8]:%d, au2XSTS[9]:%d, au2XSTS[10]:%d, au2XSTS[11]:%d\n", + prInBuf, u4ProfileIdx, u2bw, au2XSTS[0], + au2XSTS[1], au2XSTS[2], au2XSTS[3], au2XSTS[4], + au2XSTS[5], au2XSTS[6], au2XSTS[7], au2XSTS[8], + au2XSTS[9], au2XSTS[10], au2XSTS[11]); + + i4Status = TxBfProfilePnWrite(prNetDev, u4ProfileIdx, u2bw, + au2XSTS); + } else + return -EINVAL; + + return i4Status; +} + +/* Su_Mu:NumSta:SndInterval:WLan0:WLan1:WLan2:WLan3 */ +int Set_Trigger_Sounding_Proc(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + uint32_t ucSuMu, ucNumSta, ucSndInterval, ucWLan0, ucWLan1, + ucWLan2, ucWLan3; + int32_t i4Status = 0; + int32_t rv; + + DBGLOG(RFTEST, ERROR, "Set_Trigger_Sounding_Proc\n"); + + rv = sscanf + (prInBuf, "%x:%x:%x:%x:%x:%x:%x", &ucSuMu, &ucNumSta, + &ucSndInterval, &ucWLan0, &ucWLan1, &ucWLan2, + &ucWLan3); + if (rv == 7) { + DBGLOG(RFTEST, ERROR, + "Set_Trigger_Sounding_Proc prInBuf = %s, ucSuMu = %d, ucNumSta = %d, ucSndInterval = %d, ucWLan0 = %d, ucWLan1 = %d, ucWLan2:%d, ucWLan3:%d\n", + prInBuf, ucSuMu, ucNumSta, ucSndInterval, ucWLan0, + ucWLan1, ucWLan2, ucWLan3); + i4Status = TxBfSounding(prNetDev, ucSuMu, ucNumSta, + ucSndInterval, ucWLan0, ucWLan1, ucWLan2, ucWLan3); + } else + return -EINVAL; + + return i4Status; +} + +int Set_Stop_Sounding_Proc(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + int32_t i4Status = 0; + + DBGLOG(RFTEST, ERROR, "Set_Stop_Sounding_Proc\n"); + + i4Status = TxBfSoundingStop(prNetDev); + + return i4Status; +} + +int Set_TxBfTxApply(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + uint32_t u4WlanId, u4ETxBf, u4ITxBf, u4MuTxBf; + int32_t i4Status = 0; + int32_t rv; + + DBGLOG(RFTEST, ERROR, "TxBfTxApply\n"); + + rv = sscanf(prInBuf, "%d:%d:%d:%d", &u4WlanId, &u4ETxBf, + &u4ITxBf, &u4MuTxBf); + if (rv == 4) { + DBGLOG(RFTEST, ERROR, + "TxBfTxApply prInBuf = %s, u4WlanId = %d, u4ETxBf = %d, u4ITxBf = %d, u4MuTxBf = %d\n", + prInBuf, u4WlanId, u4ETxBf, u4ITxBf, u4MuTxBf); + i4Status = TxBfTxApply(prNetDev, u4WlanId, u4ETxBf, u4ITxBf, + u4MuTxBf); + } else + return -EINVAL; + + return i4Status; +} + +int Set_TxBfManualAssoc(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + int32_t au4Mac[MAC_ADDR_LEN]; + int32_t u4Type, u4Wtbl, u4Ownmac, u4PhyMode, u4Bw, u4Nss, + u4PfmuId, u4Mode, u4Marate, u4SpeIdx, ucaid, u4Rv; + int8_t aucMac[MAC_ADDR_LEN]; + int32_t i4Status = 0; + int32_t i = 0; + int32_t rv; + + DBGLOG(RFTEST, ERROR, "TxBfManualAssoc\n"); + + rv = sscanf(prInBuf, + "%x:%x:%x:%x:%x:%x:%x:%d:%x:%x:%x:%x:%d:%x:%x:%x:%d:%x", + &au4Mac[0], &au4Mac[1], &au4Mac[2], &au4Mac[3], &au4Mac[4], + &au4Mac[5], + &u4Type, &u4Wtbl, &u4Ownmac, &u4PhyMode, &u4Bw, &u4Nss, + &u4PfmuId, &u4Mode, &u4Marate, &u4SpeIdx, + &ucaid, &u4Rv); + if (rv == 18) { + DBGLOG(RFTEST, ERROR, + "TxBfManualAssoc au4Mac[0] = %x, au4Mac[1] = %x, au4Mac[2] = %xau4Mac[3] = %x, au4Mac[4] = %x, au4Mac[5] = %x, u4Type = %x, u4Wtbl = %d, u4Ownmac = %x, u4PhyMode = %x u4Bw = %x, u4Nss = %x, u4PfmuId = %d, u4Mode = %x, u4Marate = %x, u4SpeIdx = %d, ucaid = %d, u4Rv = %x", + au4Mac[0], au4Mac[1], au4Mac[2], au4Mac[3], au4Mac[4], + au4Mac[5], u4Type, u4Wtbl, u4Ownmac, + u4PhyMode, u4Bw, u4Nss, u4PfmuId, u4Mode, u4Marate, + u4SpeIdx, ucaid, u4Rv); + for (i = 0; i < MAC_ADDR_LEN; i++) + aucMac[i] = au4Mac[i]; + + i4Status = + TxBfManualAssoc(prNetDev, aucMac, u4Type, u4Wtbl, + u4Ownmac, u4Mode, u4Bw, u4Nss, u4PfmuId, + u4Marate, u4SpeIdx, ucaid, u4Rv); + } else + return -EINVAL; + + return i4Status; +} + +int Set_TxBfPfmuMemAlloc(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + uint32_t ucSuMuMode, ucWlanIdx; + int32_t i4Status = 0; + int32_t rv; + + DBGLOG(RFTEST, ERROR, "TxBfPfmuMemAlloc\n"); + + rv = sscanf(prInBuf, "%d:%d", &ucSuMuMode, &ucWlanIdx); + if (rv == 2) { + DBGLOG(RFTEST, ERROR, + "TxBfPfmuMemAlloc ucSuMuMode = %d, ucWlanIdx = %d", + ucSuMuMode, ucWlanIdx); + i4Status = TxBfPfmuMemAlloc(prNetDev, ucSuMuMode, + ucWlanIdx); + } else + return -EINVAL; + + return i4Status; +} + +int Set_TxBfPfmuMemRelease(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + uint32_t ucWlanId; + int32_t i4Status = 0; + int32_t rv; + + DBGLOG(RFTEST, ERROR, "TxBfPfmuMemRelease\n"); + + rv = kstrtoint(prInBuf, 0, &ucWlanId); + if (rv == 0) { + DBGLOG(RFTEST, ERROR, "TxBfPfmuMemRelease ucWlanId = %d", + ucWlanId); + i4Status = TxBfPfmuMemRelease(prNetDev, ucWlanId); + } else + return -EINVAL; + + return i4Status; +} + +int Set_DevInfoUpdate(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + uint32_t u4OwnMacIdx, fgBand; + uint32_t OwnMacAddr[MAC_ADDR_LEN]; + uint8_t aucMacAddr[MAC_ADDR_LEN]; + int32_t i4Status = 0; + uint32_t i; + int32_t rv; + + DBGLOG(RFTEST, ERROR, "DevInfoUpdate\n"); + + rv = sscanf + (prInBuf, "%d:%x:%x:%x:%x:%x:%x:%d", &u4OwnMacIdx, + &OwnMacAddr[0], &OwnMacAddr[1], &OwnMacAddr[2], + &OwnMacAddr[3], &OwnMacAddr[4], &OwnMacAddr[5], &fgBand); + if (rv == 8) { + DBGLOG(RFTEST, ERROR, + "DevInfoUpdate prInBuf = %s, u4OwnMacIdx = %x, fgBand = %x,OwnMacAddr[0]:%x, OwnMacAddr[1]:%x, OwnMacAddr[2]:%x, OwnMacAddr[3]:%x, OwnMacAddr[4]:%x, OwnMacAddr[5]:%x,", + prInBuf, u4OwnMacIdx, fgBand, + OwnMacAddr[0], OwnMacAddr[1], + OwnMacAddr[2], OwnMacAddr[3], + OwnMacAddr[4], OwnMacAddr[5]); + for (i = 0; i < MAC_ADDR_LEN; i++) + aucMacAddr[i] = OwnMacAddr[i]; + + i4Status = DevInfoUpdate(prNetDev, u4OwnMacIdx, fgBand, + aucMacAddr); + } else + return -EINVAL; + + return i4Status; +} + +int Set_BssInfoUpdate(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + uint32_t u4OwnMacIdx, u4BssIdx; + uint32_t au4BssId[MAC_ADDR_LEN]; + uint8_t aucBssId[MAC_ADDR_LEN]; + int32_t i4Status = 0; + uint32_t i; + int32_t rv; + + DBGLOG(RFTEST, ERROR, "BssInfoUpdate\n"); + + rv = sscanf + (prInBuf, "%d:%d:%x:%x:%x:%x:%x:%x", &u4OwnMacIdx, + &u4BssIdx, &au4BssId[0], &au4BssId[1], &au4BssId[2], + &au4BssId[3], &au4BssId[4], &au4BssId[5]); + if (rv == 8) { + DBGLOG(RFTEST, ERROR, + "BssInfoUpdate prInBuf = %s, u4OwnMacIdx = %x, u4BssIdx = %x,au4BssId[0]:%x, au4BssId[1]:%x, au4BssId[2]:%x, au4BssId[3]:%x, au4BssId[4]:%x, au4BssId[5]:%x,", + prInBuf, u4OwnMacIdx, u4BssIdx, au4BssId[0], au4BssId[1], + au4BssId[2], au4BssId[3], au4BssId[4], + au4BssId[5]); + for (i = 0; i < MAC_ADDR_LEN; i++) + aucBssId[i] = au4BssId[i]; + + i4Status = BssInfoUpdate(prNetDev, u4OwnMacIdx, u4BssIdx, + aucBssId); + } else + return -EINVAL; + + return i4Status; +} + +int Set_StaRecCmmUpdate(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + uint32_t u4WlanId, u4BssId, u4Aid; + uint32_t au4MacAddr[MAC_ADDR_LEN]; + uint8_t aucMacAddr[MAC_ADDR_LEN]; + int32_t i4Status = 0; + uint32_t i; + int32_t rv; + + DBGLOG(RFTEST, ERROR, "Set_StaRecCmmUpdate\n"); + + rv = sscanf + (prInBuf, "%x:%x:%x:%x:%x:%x:%x:%x:%x", &u4WlanId, &u4BssId, + &u4Aid, &au4MacAddr[0], &au4MacAddr[1], + &au4MacAddr[2], &au4MacAddr[3], &au4MacAddr[4], + &au4MacAddr[5]); + if (rv == 9) { + DBGLOG(RFTEST, ERROR, + "Set_StaRecCmmUpdate prInBuf = %s, u4WlanId = %x, u4BssId = %x, u4Aid = %x,aucMacAddr[0]:%x, aucMacAddr[1]:%x, aucMacAddr[2]:%x, aucMacAddr[3]:%x, aucMacAddr[4]:%x, aucMacAddr[5]:%x,", + prInBuf, u4WlanId, u4BssId, u4Aid, au4MacAddr[0], + au4MacAddr[1], au4MacAddr[2], au4MacAddr[3], + au4MacAddr[4], au4MacAddr[5]); + for (i = 0; i < MAC_ADDR_LEN; i++) + aucMacAddr[i] = au4MacAddr[i]; + + i4Status = StaRecCmmUpdate(prNetDev, u4WlanId, u4BssId, + u4Aid, aucMacAddr); + } else + return -EINVAL; + + return i4Status; +} + +int Set_StaRecBfUpdate(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + struct STA_REC_BF_UPD_ARGUMENT rStaRecBfUpdArg; + uint8_t aucMemRow[4], aucMemCol[4]; + int32_t i4Status = 0; + uint32_t i; + int32_t rv; + + DBGLOG(RFTEST, ERROR, "Set_StaRecBfUpdate\n"); + + rv = sscanf(prInBuf, + "%x:%x:%x:%x:%x:%d:%d:%d:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x", + &rStaRecBfUpdArg.u4WlanId, &rStaRecBfUpdArg.u4BssId, + &rStaRecBfUpdArg.u4PfmuId, + &rStaRecBfUpdArg.u4SuMu, &rStaRecBfUpdArg.u4eTxBfCap, + &rStaRecBfUpdArg.u4NdpaRate, + &rStaRecBfUpdArg.u4NdpRate, &rStaRecBfUpdArg.u4ReptPollRate, + &rStaRecBfUpdArg.u4TxMode, + &rStaRecBfUpdArg.u4Nc, &rStaRecBfUpdArg.u4Nr, + &rStaRecBfUpdArg.u4Bw, &rStaRecBfUpdArg.u4SpeIdx, + &rStaRecBfUpdArg.u4TotalMemReq, + &rStaRecBfUpdArg.u4MemReq20M, &rStaRecBfUpdArg.au4MemRow[0], + &rStaRecBfUpdArg.au4MemCol[0], + &rStaRecBfUpdArg.au4MemRow[1], + &rStaRecBfUpdArg.au4MemCol[1], + &rStaRecBfUpdArg.au4MemRow[2], + &rStaRecBfUpdArg.au4MemCol[2], + &rStaRecBfUpdArg.au4MemRow[3], + &rStaRecBfUpdArg.au4MemCol[3]); + if (rv == 23) { + /* + *DBGLOG(RFTEST, ERROR, + *"Set_StaRecBfUpdate prInBuf = %s, u4WlanId = %x, u4BssId = %x, + * u4Aid = %x, + * aucMacAddr[0]:%x, aucMacAddr[1]:%x, aucMacAddr[2]:%x, + * aucMacAddr[3]:%x, aucMacAddr[4]:%x, aucMacAddr[5]:%x", + * prInBuf, u4OwnMacIdx, u4BssIdx, u4Aid, + * aucMacAddr[0], aucMacAddr[1], aucMacAddr[2], aucMacAddr[3], + * aucMacAddr[4], aucMacAddr[5]); + */ + for (i = 0; i < 4; i++) { + aucMemRow[i] = rStaRecBfUpdArg.au4MemRow[i]; + aucMemCol[i] = rStaRecBfUpdArg.au4MemCol[i]; + } + i4Status = StaRecBfUpdate(prNetDev, rStaRecBfUpdArg, + aucMemRow, aucMemCol); + } else + return -EINVAL; + + return i4Status; +} + +#if CFG_SUPPORT_MU_MIMO +int Set_MUGetInitMCS(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_CUSTOM_MUMIMO_ACTION_STRUCT rMuMimoActionInfo; + int32_t i4Status = 0; + uint32_t u4BufLen = 0; + + uint32_t u4groupIdx; + int32_t rv; + + DBGLOG(RFTEST, ERROR, "Set_MUGetInitMCS\n"); + + kalMemZero(&rMuMimoActionInfo, sizeof(rMuMimoActionInfo)); + + ASSERT(prNetDev); + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + rv = kstrtouint(prInBuf, 0, &u4groupIdx); + if (rv == 0) { + DBGLOG(RFTEST, ERROR, "Test\n"); + DBGLOG(RFTEST, ERROR, + "Set_MUGetInitMCS prInBuf = %s, u4groupIdx = %x", + prInBuf, u4groupIdx); + + rMuMimoActionInfo.ucMuMimoCategory = MU_GET_CALC_INIT_MCS; + rMuMimoActionInfo.unMuMimoParam.rMuGetCalcInitMcs.ucgroupIdx + = u4groupIdx; + + i4Status = kalIoctl(prGlueInfo, + wlanoidMuMimoAction, + &rMuMimoActionInfo, + sizeof(rMuMimoActionInfo), + TRUE, TRUE, TRUE, &u4BufLen); + } else + return -EINVAL; + + return i4Status; +} + +int Set_MUCalInitMCS(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_CUSTOM_MUMIMO_ACTION_STRUCT rMuMimoActionInfo; + int32_t i4Status = 0; + uint32_t u4BufLen = 0; + + uint32_t u4NumOfUser, u4Bandwidth, u4NssOfUser0, + u4NssOfUser1, u4PfMuIdOfUser0, u4PfMuIdOfUser1, u4NumOfTxer, + u4SpeIndex, u4GroupIndex; + int32_t rv; + + DBGLOG(RFTEST, ERROR, "Set_MUCalInitMCS\n"); + + kalMemZero(&rMuMimoActionInfo, sizeof(rMuMimoActionInfo)); + + ASSERT(prNetDev); + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + rv = sscanf + (prInBuf, "%x:%x:%x:%x:%x:%x:%x:%x:%x", &u4NumOfUser, + &u4Bandwidth, &u4NssOfUser0, &u4NssOfUser1, + &u4PfMuIdOfUser0, &u4PfMuIdOfUser1, &u4NumOfTxer, + &u4SpeIndex, &u4GroupIndex); + if (rv == 9) { + DBGLOG(RFTEST, ERROR, + "Set_MUCalInitMCS prInBuf = %s, u4NumOfUser = %x, u4Bandwidth = %x, u4NssOfUser0 = %x, u4NssOfUser1 = %x, u4PfMuIdOfUser0 = %x, u4PfMuIdOfUser1 = %x, u4NumOfTxer = %x, u4SpeIndex = %x, u4GroupIndex = %x", + prInBuf, u4NumOfUser, u4Bandwidth, u4NssOfUser0, + u4NssOfUser1, u4PfMuIdOfUser0, u4PfMuIdOfUser1, + u4NumOfTxer, u4SpeIndex, u4GroupIndex); + + rMuMimoActionInfo.ucMuMimoCategory = MU_SET_CALC_INIT_MCS; + rMuMimoActionInfo.unMuMimoParam.rMuSetInitMcs.ucNumOfUser = + u4NumOfUser; + rMuMimoActionInfo.unMuMimoParam.rMuSetInitMcs.ucBandwidth = + u4Bandwidth; + rMuMimoActionInfo.unMuMimoParam.rMuSetInitMcs.ucNssOfUser0 = + u4NssOfUser0; + rMuMimoActionInfo.unMuMimoParam.rMuSetInitMcs.ucNssOfUser1 = + u4NssOfUser1; + rMuMimoActionInfo.unMuMimoParam.rMuSetInitMcs.ucPfMuIdOfUser0 + = u4PfMuIdOfUser0; + rMuMimoActionInfo.unMuMimoParam.rMuSetInitMcs.ucPfMuIdOfUser1 + = u4PfMuIdOfUser1; + rMuMimoActionInfo.unMuMimoParam.rMuSetInitMcs.ucNumOfTxer = + u4NumOfTxer; + rMuMimoActionInfo.unMuMimoParam.rMuSetInitMcs.ucSpeIndex = + u4SpeIndex; + rMuMimoActionInfo.unMuMimoParam.rMuSetInitMcs.u4GroupIndex = + u4GroupIndex; + + i4Status = kalIoctl(prGlueInfo, + wlanoidMuMimoAction, + &rMuMimoActionInfo, + sizeof(rMuMimoActionInfo), + FALSE, FALSE, TRUE, &u4BufLen); + } else + return -EINVAL; + + return i4Status; +} + +int Set_MUCalLQ(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_CUSTOM_MUMIMO_ACTION_STRUCT rMuMimoActionInfo; + int32_t i4Status = 0; + uint32_t u4BufLen = 0; + + uint32_t u4NumOfUser, u4Bandwidth, u4NssOfUser0, + u4NssOfUser1, u4PfMuIdOfUser0, u4PfMuIdOfUser1, + u4NumOfTxer, u4SpeIndex, u4GroupIndex; + int32_t rv; + + DBGLOG(RFTEST, ERROR, "Set_MUCalLQ\n"); + + kalMemZero(&rMuMimoActionInfo, sizeof(rMuMimoActionInfo)); + + ASSERT(prNetDev); + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + rv = sscanf + (prInBuf, "%x:%x:%x:%x:%x:%x:%x:%x:%x", &u4NumOfUser, + &u4Bandwidth, &u4NssOfUser0, &u4NssOfUser1, + &u4PfMuIdOfUser0, &u4PfMuIdOfUser1, &u4NumOfTxer, + &u4SpeIndex, &u4GroupIndex); + if (rv == 9) { + DBGLOG(RFTEST, ERROR, + "Set_MUCalLQ prInBuf = %s, u4NumOfUser = %x, u4Bandwidth = %x, u4NssOfUser0 = %x, u4NssOfUser1 = %x, u4PfMuIdOfUser0 = %x, u4PfMuIdOfUser1 = %x, u4NumOfTxer = %x, u4SpeIndex = %x, u4GroupIndex = %x", + prInBuf, u4NumOfUser, u4Bandwidth, u4NssOfUser0, + u4NssOfUser1, u4PfMuIdOfUser0, u4PfMuIdOfUser1, + u4NumOfTxer, u4SpeIndex, u4GroupIndex); + + rMuMimoActionInfo.ucMuMimoCategory = MU_HQA_SET_CALC_LQ; + /* rMuMimoActionInfo.unMuMimoParam.rMuSetCalcLq.ucType = + * u4Type; + */ + rMuMimoActionInfo.unMuMimoParam.rMuSetCalcLq.ucNumOfUser = + u4NumOfUser; + rMuMimoActionInfo.unMuMimoParam.rMuSetCalcLq.ucBandwidth = + u4Bandwidth; + rMuMimoActionInfo.unMuMimoParam.rMuSetCalcLq.ucNssOfUser0 = + u4NssOfUser0; + rMuMimoActionInfo.unMuMimoParam.rMuSetCalcLq.ucNssOfUser1 = + u4NssOfUser1; + rMuMimoActionInfo.unMuMimoParam.rMuSetCalcLq.ucPfMuIdOfUser0 + = u4PfMuIdOfUser0; + rMuMimoActionInfo.unMuMimoParam.rMuSetCalcLq.ucPfMuIdOfUser1 + = u4PfMuIdOfUser1; + rMuMimoActionInfo.unMuMimoParam.rMuSetCalcLq.ucNumOfTxer = + u4NumOfTxer; + rMuMimoActionInfo.unMuMimoParam.rMuSetCalcLq.ucSpeIndex = + u4SpeIndex; + rMuMimoActionInfo.unMuMimoParam.rMuSetCalcLq.u4GroupIndex = + u4GroupIndex; + + i4Status = kalIoctl(prGlueInfo, + wlanoidMuMimoAction, + &rMuMimoActionInfo, + sizeof(rMuMimoActionInfo), + FALSE, FALSE, TRUE, &u4BufLen); + } else + return -EINVAL; + + return i4Status; +} + +int Set_MUGetLQ(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_CUSTOM_MUMIMO_ACTION_STRUCT rMuMimoActionInfo; + int32_t i4Status = 0; + /* UINT_32 u4Type; */ + uint32_t u4BufLen = 0; + + DBGLOG(RFTEST, ERROR, "Set_MUGetLQ\n"); + + kalMemZero(&rMuMimoActionInfo, sizeof(rMuMimoActionInfo)); + + ASSERT(prNetDev); + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + /* if (sscanf(prInBuf, "%x", &u4Type) == 1) + * { + * DBGLOG(RFTEST, ERROR, "Set_MUGetLQ prInBuf = %s, u4Type = %x", + * prInBuf, u4Type); + */ + + rMuMimoActionInfo.ucMuMimoCategory = MU_HQA_GET_CALC_LQ; + /* rMuMimoActionInfo.unMuMimoParam.rMuGetLq.ucType = u4Type; */ + + i4Status = kalIoctl(prGlueInfo, + wlanoidMuMimoAction, + &rMuMimoActionInfo, + sizeof(rMuMimoActionInfo), + TRUE, TRUE, TRUE, &u4BufLen); + /* } + * else + * { + * return -EINVAL; + * } + */ + + return i4Status; +} + +int Set_MUSetSNROffset(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_CUSTOM_MUMIMO_ACTION_STRUCT rMuMimoActionInfo; + int32_t i4Status = 0; + uint32_t u4BufLen = 0; + + uint32_t u4Val; + int32_t rv; + + DBGLOG(RFTEST, ERROR, "Set_MUSetSNROffset\n"); + + kalMemZero(&rMuMimoActionInfo, sizeof(rMuMimoActionInfo)); + + ASSERT(prNetDev); + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + rv = kstrtoint(prInBuf, 0, &u4Val); + if (rv == 0) { + DBGLOG(RFTEST, ERROR, + "Set_MUSetSNROffset prInBuf = %s, u4Val = %x", prInBuf, + u4Val); + + rMuMimoActionInfo.ucMuMimoCategory = MU_HQA_SET_SNR_OFFSET; + rMuMimoActionInfo.unMuMimoParam.rMuSetSnrOffset.ucVal = + u4Val; + + i4Status = kalIoctl(prGlueInfo, + wlanoidMuMimoAction, + &rMuMimoActionInfo, + sizeof(rMuMimoActionInfo), + FALSE, FALSE, TRUE, &u4BufLen); + } else + return -EINVAL; + + return i4Status; +} + +int Set_MUSetZeroNss(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_CUSTOM_MUMIMO_ACTION_STRUCT rMuMimoActionInfo; + int32_t i4Status = 0; + uint32_t u4BufLen = 0; + + uint32_t u4Val; + int32_t rv; + + DBGLOG(RFTEST, ERROR, "Set_MUSetZeroNss\n"); + + kalMemZero(&rMuMimoActionInfo, sizeof(rMuMimoActionInfo)); + + ASSERT(prNetDev); + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + rv = kstrtouint(prInBuf, 0, &u4Val); + if (rv == 0) { + DBGLOG(RFTEST, ERROR, + "Set_MUSetZeroNss prInBuf = %s, u4Val = %x", prInBuf, + u4Val); + + rMuMimoActionInfo.ucMuMimoCategory = MU_HQA_SET_ZERO_NSS; + rMuMimoActionInfo.unMuMimoParam.rMuSetZeroNss.ucVal = u4Val; + + i4Status = kalIoctl(prGlueInfo, + wlanoidMuMimoAction, + &rMuMimoActionInfo, + sizeof(rMuMimoActionInfo), + FALSE, FALSE, TRUE, &u4BufLen); + } else + return -EINVAL; + + return i4Status; +} + +int Set_MUSetSpeedUpLQ(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_CUSTOM_MUMIMO_ACTION_STRUCT rMuMimoActionInfo; + int32_t i4Status = 0; + uint32_t u4BufLen = 0; + + uint32_t u4Val; + int32_t rv; + + DBGLOG(RFTEST, ERROR, "Set_MUSetSpeedUpLQ\n"); + + kalMemZero(&rMuMimoActionInfo, sizeof(rMuMimoActionInfo)); + + ASSERT(prNetDev); + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + rv = kstrtouint(prInBuf, 0, &u4Val); + if (rv == 0) { + DBGLOG(RFTEST, ERROR, + "Set_MUSetSpeedUpLQ prInBuf = %s, u4Val = %x", prInBuf, + u4Val); + + rMuMimoActionInfo.ucMuMimoCategory = MU_HQA_SET_SPEED_UP_LQ; + rMuMimoActionInfo.unMuMimoParam.rMuSpeedUpLq.u4Val = u4Val; + + i4Status = kalIoctl(prGlueInfo, + wlanoidMuMimoAction, + &rMuMimoActionInfo, + sizeof(rMuMimoActionInfo), + FALSE, FALSE, TRUE, &u4BufLen); + } else + return -EINVAL; + + return i4Status; +} + +int Set_MUSetMUTable(struct net_device *prNetDev, + uint8_t *prTable) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_CUSTOM_MUMIMO_ACTION_STRUCT rMuMimoActionInfo; + int32_t i4Status = 0; + uint32_t u4BufLen = 0; + /*uint32_t i; + *uint32_t u4Type, u4Length; + */ + + DBGLOG(RFTEST, ERROR, "Set_MUSetMUTable\n"); + + kalMemZero(&rMuMimoActionInfo, sizeof(rMuMimoActionInfo)); + + ASSERT(prNetDev); + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + /* if (sscanf(prInBuf, "%x:%x", &u4Type, &u4Length) == 2) */ + /* { */ + /* DBGLOG(RFTEST, ERROR, "Set_MUSetMUTable prInBuf = %s, */ + /* u4Type = %x, u4Length = %x", prInBuf, u4Type, u4Length); */ + + rMuMimoActionInfo.ucMuMimoCategory = MU_HQA_SET_MU_TABLE; + /* rMuMimoActionInfo.unMuMimoParam.rMuSetMuTable.u2Type = u4Type; */ + /* rMuMimoActionInfo.unMuMimoParam.rMuSetMuTable.u4Length = u4Length; */ + + /* for ( i = 0 ; i < NUM_MUT_NR_NUM * NUM_MUT_FEC * NUM_MUT_MCS + * * NUM_MUT_INDEX ; i++) + * { + */ + memcpy(rMuMimoActionInfo.unMuMimoParam.rMuSetMuTable.aucMetricTable, + prTable, + NUM_MUT_NR_NUM * NUM_MUT_FEC * NUM_MUT_MCS * NUM_MUT_INDEX); + /* } */ + + i4Status = kalIoctl(prGlueInfo, + wlanoidMuMimoAction, + &rMuMimoActionInfo, + sizeof(rMuMimoActionInfo), + FALSE, FALSE, TRUE, &u4BufLen); + /* } */ + /* else */ + /* { */ + /* return -EINVAL; */ + /* } */ + + return i4Status; +} + +int Set_MUSetGroup(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_CUSTOM_MUMIMO_ACTION_STRUCT rMuMimoActionInfo; + int32_t i4Status = 0; + uint32_t u4BufLen = 0; + uint32_t i = 0; + + uint32_t aucUser0MacAddr[PARAM_MAC_ADDR_LEN], + aucUser1MacAddr[PARAM_MAC_ADDR_LEN]; + + DBGLOG(RFTEST, ERROR, "Set_MUSetGroup\n"); + + kalMemZero(&rMuMimoActionInfo, sizeof(rMuMimoActionInfo)); + + ASSERT(prNetDev); + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + if (sscanf(prInBuf, + "%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x", + &rMuMimoActionInfo.unMuMimoParam.rMuSetGroup.u4GroupIndex, + &rMuMimoActionInfo.unMuMimoParam.rMuSetGroup.u4NumOfUser, + &rMuMimoActionInfo.unMuMimoParam.rMuSetGroup.u4User0Ldpc, + &rMuMimoActionInfo.unMuMimoParam.rMuSetGroup.u4User1Ldpc, + &rMuMimoActionInfo.unMuMimoParam.rMuSetGroup.u4ShortGI, + &rMuMimoActionInfo.unMuMimoParam.rMuSetGroup.u4Bw, + &rMuMimoActionInfo.unMuMimoParam.rMuSetGroup.u4User0Nss, + &rMuMimoActionInfo.unMuMimoParam.rMuSetGroup.u4User1Nss, + &rMuMimoActionInfo.unMuMimoParam.rMuSetGroup.u4GroupId, + &rMuMimoActionInfo.unMuMimoParam.rMuSetGroup.u4User0UP, + &rMuMimoActionInfo.unMuMimoParam.rMuSetGroup.u4User1UP, + &rMuMimoActionInfo.unMuMimoParam.rMuSetGroup.u4User0MuPfId, + &rMuMimoActionInfo.unMuMimoParam.rMuSetGroup.u4User1MuPfId, + &rMuMimoActionInfo.unMuMimoParam.rMuSetGroup.u4User0InitMCS, + &rMuMimoActionInfo.unMuMimoParam.rMuSetGroup.u4User1InitMCS, + &aucUser0MacAddr[0], + &aucUser0MacAddr[1], &aucUser0MacAddr[2], + &aucUser0MacAddr[3], &aucUser0MacAddr[4], + &aucUser0MacAddr[5], &aucUser1MacAddr[0], + &aucUser1MacAddr[1], &aucUser1MacAddr[2], + &aucUser1MacAddr[3], &aucUser1MacAddr[4], + &aucUser1MacAddr[5]) != 27) { + return -EINVAL; + } + + DBGLOG(RFTEST, ERROR, + "Set_MUSetGroup prInBuf = %s,u4GroupIndex = %d, u4NumOfUser = %d, u4User0Ldpc = %d, u4User1Ldpc = %d, u4ShortGI = %d, u4Bw = %d, u4User0Nss = %d, u4User1Nss = %d, u4GroupId = %d, u4User0UP = %d, u4User1UP = %d, u4User0MuPfId = %d, u4User1MuPfId = %d, u4User0InitMCS = %d, u4User1InitMCS = %d,aucUser0MacAddr[0] = %x, aucUser0MacAddr[1] = %x, aucUser0MacAddr[2] = %x, aucUser0MacAddr[3] = %x, aucUser0MacAddr[4] = %x, aucUser0MacAddr[5] = %x,aucUser1MacAddr[0] = %x, aucUser1MacAddr[1] = %x, aucUser1MacAddr[2] = %x, aucUser1MacAddr[3] = %x, aucUser1MacAddr[4] = %x, aucUser1MacAddr[5] = %x,", + prInBuf, + rMuMimoActionInfo.unMuMimoParam.rMuSetGroup.u4GroupIndex, + rMuMimoActionInfo.unMuMimoParam.rMuSetGroup.u4NumOfUser, + rMuMimoActionInfo.unMuMimoParam.rMuSetGroup.u4User0Ldpc, + rMuMimoActionInfo.unMuMimoParam.rMuSetGroup.u4User1Ldpc, + rMuMimoActionInfo.unMuMimoParam.rMuSetGroup.u4ShortGI, + rMuMimoActionInfo.unMuMimoParam.rMuSetGroup.u4Bw, + rMuMimoActionInfo.unMuMimoParam.rMuSetGroup.u4User0Nss, + rMuMimoActionInfo.unMuMimoParam.rMuSetGroup.u4User1Nss, + rMuMimoActionInfo.unMuMimoParam.rMuSetGroup.u4GroupId, + rMuMimoActionInfo.unMuMimoParam.rMuSetGroup.u4User0UP, + rMuMimoActionInfo.unMuMimoParam.rMuSetGroup.u4User1UP, + rMuMimoActionInfo.unMuMimoParam.rMuSetGroup.u4User0MuPfId, + rMuMimoActionInfo.unMuMimoParam.rMuSetGroup.u4User1MuPfId, + rMuMimoActionInfo.unMuMimoParam.rMuSetGroup.u4User0InitMCS, + rMuMimoActionInfo.unMuMimoParam.rMuSetGroup.u4User1InitMCS, + aucUser0MacAddr[0], aucUser0MacAddr[1], + aucUser0MacAddr[2], aucUser0MacAddr[3], + aucUser0MacAddr[4], aucUser0MacAddr[5], + aucUser1MacAddr[0], aucUser1MacAddr[1], + aucUser1MacAddr[2], aucUser1MacAddr[3], + aucUser1MacAddr[4], aucUser1MacAddr[5]); + + rMuMimoActionInfo.ucMuMimoCategory = MU_HQA_SET_GROUP; + for (i = 0; i < PARAM_MAC_ADDR_LEN; i++) { + rMuMimoActionInfo.unMuMimoParam.rMuSetGroup.aucUser0MacAddr[i] + = aucUser0MacAddr[i]; + rMuMimoActionInfo.unMuMimoParam.rMuSetGroup.aucUser1MacAddr[i] + = aucUser1MacAddr[i]; + } + + i4Status = kalIoctl(prGlueInfo, wlanoidMuMimoAction, &rMuMimoActionInfo, + sizeof(rMuMimoActionInfo), + FALSE, FALSE, TRUE, &u4BufLen); + + return i4Status; +} + +int Set_MUGetQD(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_CUSTOM_MUMIMO_ACTION_STRUCT rMuMimoActionInfo; + int32_t i4Status = 0; + uint32_t u4BufLen = 0; + + uint32_t u4SubcarrierIndex, u4Length; + + DBGLOG(RFTEST, ERROR, "Set_MUGetQD\n"); + + kalMemZero(&rMuMimoActionInfo, sizeof(rMuMimoActionInfo)); + + ASSERT(prNetDev); + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + if (sscanf(prInBuf, "%x:%x", &u4SubcarrierIndex, + &u4Length) == 2) { + DBGLOG(RFTEST, ERROR, + "Set_MUGetQD prInBuf = %s, u4SubcarrierIndex = %x, u4Length = %x", + prInBuf, + u4SubcarrierIndex, u4Length); + + rMuMimoActionInfo.ucMuMimoCategory = MU_HQA_GET_QD; + rMuMimoActionInfo.unMuMimoParam.rMuGetQd.ucSubcarrierIndex = + u4SubcarrierIndex; + /* rMuMimoActionInfo.unMuMimoParam.rMuGetQd.u4Length = + * u4Length; + */ + /* rMuMimoActionInfo.unMuMimoParam.rMuGetQd.ucgroupIdx = + * ucgroupIdx; + */ + + i4Status = kalIoctl(prGlueInfo, + wlanoidMuMimoAction, + &rMuMimoActionInfo, + sizeof(rMuMimoActionInfo), + TRUE, TRUE, TRUE, &u4BufLen); + } else { + return -EINVAL; + } + + return i4Status; +} + +int Set_MUSetEnable(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_CUSTOM_MUMIMO_ACTION_STRUCT rMuMimoActionInfo; + int32_t i4Status = 0; + uint32_t u4BufLen = 0; + + uint32_t u4Val; + int32_t rv; + + DBGLOG(RFTEST, ERROR, "Set_MUSetEnable\n"); + + kalMemZero(&rMuMimoActionInfo, sizeof(rMuMimoActionInfo)); + + ASSERT(prNetDev); + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + rv = kstrtouint(prInBuf, 0, &u4Val); + if (rv == 0) { + DBGLOG(RFTEST, ERROR, + "Set_MUSetEnable prInBuf = %s, u4Val = %x", + prInBuf, u4Val); + + rMuMimoActionInfo.ucMuMimoCategory = MU_HQA_SET_ENABLE; + rMuMimoActionInfo.unMuMimoParam.rMuSetEnable.ucVal = u4Val; + + i4Status = kalIoctl(prGlueInfo, + wlanoidMuMimoAction, + &rMuMimoActionInfo, + sizeof(rMuMimoActionInfo), + FALSE, FALSE, TRUE, &u4BufLen); + } else + return -EINVAL; + + return i4Status; +} + +int Set_MUSetGID_UP(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_CUSTOM_MUMIMO_ACTION_STRUCT rMuMimoActionInfo; + int32_t i4Status = 0; + uint32_t u4BufLen = 0; + + DBGLOG(RFTEST, ERROR, "Set_MUSetGID_UP\n"); + + kalMemZero(&rMuMimoActionInfo, sizeof(rMuMimoActionInfo)); + + ASSERT(prNetDev); + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + if (sscanf(prInBuf, "%d:%d:%d:%d:%d:%d", + &rMuMimoActionInfo.unMuMimoParam.rMuSetGidUp.au4Gid[0], + &rMuMimoActionInfo.unMuMimoParam.rMuSetGidUp.au4Gid[1], + &rMuMimoActionInfo.unMuMimoParam.rMuSetGidUp.au4Up[0], + &rMuMimoActionInfo.unMuMimoParam.rMuSetGidUp.au4Up[1], + &rMuMimoActionInfo.unMuMimoParam.rMuSetGidUp.au4Up[2], + &rMuMimoActionInfo.unMuMimoParam.rMuSetGidUp.au4Up[3]) == 6 + ) { + DBGLOG(RFTEST, ERROR, + "Set_MUSetGID_UP prInBuf = %s, au4Gid[0] = %x, au4Gid[1] = %x, au4Up[0] = %x, au4Up[1] = %x, au4Up[2] = %x, au4Up[3] = %x", + prInBuf, + rMuMimoActionInfo.unMuMimoParam.rMuSetGidUp.au4Gid[0], + rMuMimoActionInfo.unMuMimoParam.rMuSetGidUp.au4Gid[1], + rMuMimoActionInfo.unMuMimoParam.rMuSetGidUp.au4Up[0], + rMuMimoActionInfo.unMuMimoParam.rMuSetGidUp.au4Up[1], + rMuMimoActionInfo.unMuMimoParam.rMuSetGidUp.au4Up[2], + rMuMimoActionInfo.unMuMimoParam.rMuSetGidUp.au4Up[3]); + + rMuMimoActionInfo.ucMuMimoCategory = MU_HQA_SET_STA_PARAM; + + i4Status = kalIoctl(prGlueInfo, + wlanoidMuMimoAction, + &rMuMimoActionInfo, + sizeof(rMuMimoActionInfo), + FALSE, FALSE, TRUE, &u4BufLen); + } else { + return -EINVAL; + } + + return i4Status; +} + +int Set_MUTriggerTx(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_CUSTOM_MUMIMO_ACTION_STRUCT rMuMimoActionInfo; + int32_t i4Status = 0; + uint32_t u4BufLen = 0; + uint32_t i, j; + + uint32_t u4IsRandomPattern, u4MsduPayloadLength0, + u4MsduPayloadLength1, u4MuPacketCount, u4NumOfSTAs; + uint32_t au4MacAddrs[2][6]; + + DBGLOG(RFTEST, ERROR, "Set_MUTriggerTx\n"); + + kalMemZero(&rMuMimoActionInfo, sizeof(rMuMimoActionInfo)); + + ASSERT(prNetDev); + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + if (sscanf(prInBuf, + "%d:%x:%x:%x:%d:%d:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x", + &u4IsRandomPattern, &u4MsduPayloadLength0, + &u4MsduPayloadLength1, &u4MuPacketCount, &u4NumOfSTAs, + &au4MacAddrs[0][0], &au4MacAddrs[0][1], &au4MacAddrs[0][2], + &au4MacAddrs[0][3], &au4MacAddrs[0][4], + &au4MacAddrs[0][5], &au4MacAddrs[1][0], &au4MacAddrs[1][1], + &au4MacAddrs[1][2], &au4MacAddrs[1][3], + &au4MacAddrs[1][4], &au4MacAddrs[1][5]) == 17) { + DBGLOG(RFTEST, ERROR, + "Set_MUTriggerTx prInBuf = %s, u4IsRandomPattern = %x, u4MsduPayloadLength0 = %x, u4MsduPayloadLength1 = %x, u4MuPacketCount = %x, u4NumOfSTAs = %x, au4MacAddrs[0][0] = %x, au4MacAddrs[0][1] = %x, au4MacAddrs[0][2] = %x, au4MacAddrs[0][3] = %x, au4MacAddrs[0][4] = %x, au4MacAddrs[0][5] = %x,au4MacAddrs[1][0] = %x, au4MacAddrs[1][1] = %x, au4MacAddrs[1][2] = %x, au4MacAddrs[1][3] = %x, au4MacAddrs[1][4] = %x, au4MacAddrs[1][5] = %x", + prInBuf, u4IsRandomPattern, u4MsduPayloadLength0, + u4MsduPayloadLength1, u4MuPacketCount, + u4NumOfSTAs, au4MacAddrs[0][0], au4MacAddrs[0][1], + au4MacAddrs[0][2], au4MacAddrs[0][3], + au4MacAddrs[0][4], au4MacAddrs[0][5], au4MacAddrs[1][0], + au4MacAddrs[1][1], au4MacAddrs[1][2], + au4MacAddrs[1][3], au4MacAddrs[1][4], au4MacAddrs[1][5]); + + rMuMimoActionInfo.ucMuMimoCategory = MU_SET_TRIGGER_MU_TX; + rMuMimoActionInfo.unMuMimoParam.rMuTriggerMuTx + .fgIsRandomPattern + = u4IsRandomPattern; + rMuMimoActionInfo.unMuMimoParam.rMuTriggerMuTx + .u4MsduPayloadLength0 + = u4MsduPayloadLength0; + rMuMimoActionInfo.unMuMimoParam.rMuTriggerMuTx + .u4MsduPayloadLength1 + = u4MsduPayloadLength1; + rMuMimoActionInfo.unMuMimoParam.rMuTriggerMuTx.u4MuPacketCount + = u4MuPacketCount; + rMuMimoActionInfo.unMuMimoParam.rMuTriggerMuTx.u4NumOfSTAs = + u4NumOfSTAs; + + for (i = 0 ; i < 2 ; i++) { + for (j = 0 ; j < PARAM_MAC_ADDR_LEN ; j++) + rMuMimoActionInfo.unMuMimoParam.rMuTriggerMuTx + .aucMacAddrs[i][j] + = au4MacAddrs[i][j]; + } + + i4Status = kalIoctl(prGlueInfo, + wlanoidMuMimoAction, + &rMuMimoActionInfo, + sizeof(rMuMimoActionInfo), + FALSE, FALSE, TRUE, &u4BufLen); + } else { + return -EINVAL; + } + + return i4Status; +} +#endif + +#if CFG_SUPPORT_TX_BF_FPGA +int Set_TxBfProfileSwTagWrite(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + int32_t i4Status = 0; + int32_t rv; + uint32_t u4Lm, u4Nc, u4Nr, u4Bw, u4Codebook, u4Group; + + DBGLOG(RFTEST, ERROR, "Set_TxBfProfileSwTagWrite\n"); + + rv = sscanf(prInBuf, "%d-%d-%d-%d-%d-%d", &u4Lm, &u4Nr, + &u4Nc, &u4Bw, &u4Codebook, &u4Group); + + if (rv == 6) { + if ((u4Lm > 0) && (u4Group < 3) && (u4Nr < 4) && (u4Nc < 4) + && (u4Codebook < 4)) { + DBGLOG(RFTEST, ERROR, + "Set_TxBfProfileSwTagWrite prInBuf = %s, u4Lm = %d, u4Nr = %d, u4Nc = %d, u4BW = %d, u4CodeBook = %d, u4Group=%d\n", + prInBuf, u4Lm, u4Nr, u4Nc, u4Bw, u4Codebook, + u4Group); + + i4Status = TxBfPseudoTagUpdate(prNetDev, u4Lm, u4Nr, + u4Nc, u4Bw, u4Codebook, u4Group); + } else + return -EINVAL; + } else + return -EINVAL; + + return i4Status; +} +#endif +#endif + + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to Write Efuse. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prInBuf A pointer to the command string buffer + * \param[out] None + * + * \retval 0 On success. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int WriteEfuse(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + int32_t i4Status; + int32_t rv; + uint32_t addr[2]; + uint16_t addr2[2]; + + DBGLOG(REQ, INFO, "ATE_AGENT iwpriv WriteEfuse, buf: %s\n", + prInBuf); + + rv = sscanf(prInBuf, "%x:%x", &addr[0], &addr[1]); + + DBGLOG(REQ, INFO, + "ATE_AGENT iwpriv WriteEfuse, prInBuf: %s\n", prInBuf); + DBGLOG(INIT, ERROR, + "ATE_AGENT iwpriv WriteEfuse :%02x:%02x\n", addr[0], + addr[1]); + + addr2[0] = (uint16_t) addr[0]; + addr2[1] = (uint16_t) addr[1]; + + if (rv == 2) + i4Status = MT_ATEWriteEfuse(prNetDev, addr2[0], addr2[1]); + else + return -EINVAL; + + return i4Status; +} + + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to Set Tx Power. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prInBuf A pointer to the command string buffer + * \param[out] None + * + * \retval 0 On success. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int SetTxTargetPower(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + int32_t i4Status; + int32_t rv; + int addr; + uint8_t addr2; + + DBGLOG(REQ, INFO, + "ATE_AGENT iwpriv Set Tx Target Power, buf: %s\n", prInBuf); + + /* rv = sscanf(prInBuf, "%u", &addr);*/ + rv = kstrtoint(prInBuf, 0, &addr); + + DBGLOG(REQ, INFO, + "ATE_AGENT iwpriv Set Tx Target Power, prInBuf: %s\n", + prInBuf); + DBGLOG(INIT, ERROR, + "ATE_AGENT iwpriv Set Tx Target Power :%02x\n", addr); + + addr2 = (uint8_t) addr; + + if (rv == 0) + i4Status = MT_ATESetTxTargetPower(prNetDev, addr2); + else + return -EINVAL; + + return i4Status; +} + +#if (CFG_SUPPORT_DFS_MASTER == 1) +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to Set RDD Report + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prInBuf A pointer to the command string buffer + * \param[out] None + * + * \retval 0 On success. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int SetRddReport(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + int32_t i4Status; + int32_t rv; + int dbdcIdx; + uint8_t ucDbdcIdx; + + DBGLOG(REQ, INFO, + "ATE_AGENT iwpriv Set RDD Report, buf: %s\n", prInBuf); + + /* rv = sscanf(prInBuf, "%u", &addr);*/ + rv = kstrtoint(prInBuf, 0, &dbdcIdx); + + DBGLOG(REQ, INFO, + "ATE_AGENT iwpriv Set RDD Report, prInBuf: %s\n", prInBuf); + DBGLOG(INIT, ERROR, + "ATE_AGENT iwpriv Set RDD Report : Band %d\n", dbdcIdx); + + if (p2pFuncGetDfsState() == DFS_STATE_INACTIVE + || p2pFuncGetDfsState() == DFS_STATE_DETECTED) { + DBGLOG(REQ, ERROR, + "RDD Report is not supported in this DFS state (inactive or deteted)\n"); + return WLAN_STATUS_NOT_SUPPORTED; + } + + if (dbdcIdx != 0 && dbdcIdx != 1) { + DBGLOG(REQ, ERROR, + "RDD index is not \"0\" or \"1\", Invalid data\n"); + return WLAN_STATUS_INVALID_DATA; + } + + ucDbdcIdx = (uint8_t) dbdcIdx; + + if (rv == 0) + i4Status = MT_ATESetRddReport(prNetDev, ucDbdcIdx); + else + return -EINVAL; + + return i4Status; +} + + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to Set By Pass CAC. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prInBuf A pointer to the command string buffer + * \param[out] None + * + * \retval 0 On success. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int SetByPassCac(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + int32_t i4Status; + int32_t rv; + int32_t i4ByPassCacTime; + uint32_t u4ByPassCacTime; + + DBGLOG(REQ, INFO, + "ATE_AGENT iwpriv Set By Pass Cac, buf: %s\n", prInBuf); + + rv = kstrtoint(prInBuf, 0, &i4ByPassCacTime); + + DBGLOG(REQ, INFO, + "ATE_AGENT iwpriv Set By Pass Cac, prInBuf: %s\n", prInBuf); + DBGLOG(INIT, ERROR, + "ATE_AGENT iwpriv Set By Pass Cac : %dsec\n", + i4ByPassCacTime); + + if (i4ByPassCacTime < 0) { + DBGLOG(REQ, ERROR, "Cac time < 0, Invalid data\n"); + return WLAN_STATUS_INVALID_DATA; + } + + u4ByPassCacTime = (uint32_t) i4ByPassCacTime; + + p2pFuncEnableManualCac(); + + if (rv == 0) + i4Status = p2pFuncSetDriverCacTime(u4ByPassCacTime); + else + return -EINVAL; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to Set Radar Detect Mode. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prInBuf A pointer to the command string buffer + * \param[out] None + * + * \retval 0 On success. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int SetRadarDetectMode(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + int32_t i4Status; + int32_t rv; + int radarDetectMode; + uint8_t ucRadarDetectMode; + + DBGLOG(REQ, INFO, + "ATE_AGENT iwpriv Set Radar Detect Mode, buf: %s\n", + prInBuf); + + rv = kstrtoint(prInBuf, 0, &radarDetectMode); + + DBGLOG(REQ, INFO, + "ATE_AGENT iwpriv Set Radar Detect Mode, prInBuf: %s\n", + prInBuf); + DBGLOG(INIT, ERROR, + "ATE_AGENT iwpriv Set Radar Detect Mode : %d\n", + radarDetectMode); + + if (p2pFuncGetDfsState() == DFS_STATE_INACTIVE + || p2pFuncGetDfsState() == DFS_STATE_DETECTED) { + DBGLOG(REQ, ERROR, + "RDD Report is not supported in this DFS state (inactive or deteted)\n"); + return WLAN_STATUS_NOT_SUPPORTED; + } + + if (radarDetectMode != 0 && radarDetectMode != 1) { + DBGLOG(REQ, ERROR, + "Radar Detect Mode is not \"0\" or \"1\", Invalid data\n"); + return WLAN_STATUS_INVALID_DATA; + } + + ucRadarDetectMode = (uint8_t) radarDetectMode; + + p2pFuncSetRadarDetectMode(ucRadarDetectMode); + + if (rv == 0) + i4Status = MT_ATESetRadarDetectMode(prNetDev, + ucRadarDetectMode); + else + return -EINVAL; + + return i4Status; +} + +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to search the corresponding ATE agent + * function. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prInBuf A pointer to the command string buffer + * \param[in] u4InBufLen The length of the buffer + * \param[out] None + * + * \retval 0 On success. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int AteCmdSetHandle(struct net_device *prNetDev, + uint8_t *prInBuf, uint32_t u4InBufLen) +{ + uint8_t *this_char, *value; + struct ATE_PRIV_CMD *prAtePrivCmd; + int32_t i4Status = 0; + + while ((this_char = strsep((char **)&prInBuf, + ",")) != NULL) { + if (!*this_char) + continue; + DBGLOG(RFTEST, ERROR, "ATE_AGENT iwpriv this_char = %s\n", + this_char); + DBGLOG(RFTEST, INFO, "ATE_AGENT iwpriv this_char = %s\n", + this_char); + + value = strchr(this_char, '='); + if (value != NULL) + *value++ = 0; + + DBGLOG(REQ, INFO, "ATE_AGENT iwpriv cmd = %s, value = %s\n", + this_char, value); + + for (prAtePrivCmd = rAtePrivCmdTable; prAtePrivCmd->name; + prAtePrivCmd++) { + if (!strcmp(this_char, prAtePrivCmd->name)) { + /* FALSE: Set private failed then return Invalid + * argument + */ + if (prAtePrivCmd->set_proc(prNetDev, value) + != 0) + i4Status = -EINVAL; + break; /*Exit for loop. */ + } + } + + if (prAtePrivCmd->name == NULL) { /*Not found argument */ + i4Status = -EINVAL; + break; + } + } + return i4Status; +} +#endif /*CFG_SUPPORT_QA_TOOL */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_bow.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_bow.c new file mode 100644 index 0000000000000000000000000000000000000000..2ad16735acc2cb431d22c60fe1a3d354166e1e86 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_bow.c @@ -0,0 +1,1175 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* +** Id: @(#) gl_bow.c@@ +*/ + +/*! \file gl_bow.c +* \brief Main routines of Linux driver interface for 802.11 PAL (BT 3.0 + HS) +* +* This file contains the main routines of Linux driver for MediaTek Inc. 802.11 +* Wireless LAN Adapters. +*/ + + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include "gl_os.h" +#include "debug.h" +#include "wlan_lib.h" +#include "gl_wext.h" +#include "precomp.h" +#include +#include "bss.h" + +#if CFG_ENABLE_BT_OVER_WIFI + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ +/* @FIXME if there is command/event with payload length > 28 */ +#define MAX_BUFFER_SIZE (64) + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +uint32_t g_u4PrevSysTime; +uint32_t g_u4CurrentSysTime; +uint32_t g_arBowRevPalPacketTime[32]; + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/* forward declarations */ +static ssize_t bow_ampc_read(IN struct file *filp, IN char __user *buf, IN size_t size, IN OUT loff_t *ppos); + +static ssize_t bow_ampc_write(IN struct file *filp, OUT const char __user *buf, IN size_t size, IN OUT loff_t *ppos); + +static long bow_ampc_ioctl(IN struct file *filp, IN unsigned int cmd, IN OUT unsigned long arg); + +static unsigned int bow_ampc_poll(IN struct file *filp, IN poll_table * wait); + +static int bow_ampc_open(IN struct inode *inodep, IN struct file *filp); + +static int bow_ampc_release(IN struct inode *inodep, IN struct file *filp); + +/* character file operations */ +static const struct file_operations bow_ampc_fops = { + /* .owner = THIS_MODULE, */ + .read = bow_ampc_read, + .write = bow_ampc_write, + .unlocked_ioctl = bow_ampc_ioctl, + .poll = bow_ampc_poll, + .open = bow_ampc_open, + .release = bow_ampc_release, +}; + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Register for character device to communicate with 802.11 PAL +* +* \param[in] prGlueInfo Pointer to glue info +* +* \return TRUE +* FALSE +*/ +/*----------------------------------------------------------------------------*/ +u_int8_t glRegisterAmpc(IN struct GLUE_INFO *prGlueInfo) +{ + ASSERT(prGlueInfo); + + DBGLOG(BOW, INFO, "Register for character device to communicate with 802.11 PAL.\n"); + + if (prGlueInfo->rBowInfo.fgIsRegistered == TRUE) + return FALSE; +#if 0 + /* 1. allocate major number dynamically */ + + if (alloc_chrdev_region(&(prGlueInfo->rBowInfo.u4DeviceNumber), 0, /* first minor number */ + 1, /* number */ + GLUE_BOW_DEVICE_NAME) != 0) + + return FALSE; +#endif + +#if 1 + +#if defined(CONFIG_AMPC_CDEV_NUM) + prGlueInfo->rBowInfo.u4DeviceNumber = MKDEV(CONFIG_AMPC_CDEV_NUM, 0); +#else + prGlueInfo->rBowInfo.u4DeviceNumber = MKDEV(226, 0); +#endif + + if (register_chrdev_region(prGlueInfo->rBowInfo.u4DeviceNumber, 1, /* number */ + GLUE_BOW_DEVICE_NAME) != 0) + + return FALSE; +#endif + + /* 2. spin-lock initialization */ + /* spin_lock_init(&(prGlueInfo->rBowInfo.rSpinLock)); */ + + /* 3. initialize kfifo */ +#if 0 + prGlueInfo->rBowInfo.prKfifo = kfifo_alloc(GLUE_BOW_KFIFO_DEPTH, + GFP_KERNEL, + &(prGlueInfo->rBowInfo.rSpinLock)); +#endif + if ((kfifo_alloc((struct kfifo *)&(prGlueInfo->rBowInfo.rKfifo), GLUE_BOW_KFIFO_DEPTH, GFP_KERNEL))) + goto fail_kfifo_alloc; + + /* if(prGlueInfo->rBowInfo.prKfifo == NULL) */ + if (&(prGlueInfo->rBowInfo.rKfifo) == NULL) + goto fail_kfifo_alloc; + + /* 4. initialize cdev */ + cdev_init(&(prGlueInfo->rBowInfo.cdev), &bow_ampc_fops); + /* prGlueInfo->rBowInfo.cdev.owner = THIS_MODULE; */ + prGlueInfo->rBowInfo.cdev.ops = &bow_ampc_fops; + + /* 5. add character device */ + if (cdev_add(&(prGlueInfo->rBowInfo.cdev), prGlueInfo->rBowInfo.u4DeviceNumber, 1)) + goto fail_cdev_add; + + /* 6. in queue initialization */ + init_waitqueue_head(&(prGlueInfo->rBowInfo.outq)); + + /* 7. finish */ + prGlueInfo->rBowInfo.fgIsRegistered = TRUE; + return TRUE; + +fail_cdev_add: + kfifo_free(&(prGlueInfo->rBowInfo.rKfifo)); +/* kfifo_free(prGlueInfo->rBowInfo.prKfifo); */ +fail_kfifo_alloc: + unregister_chrdev_region(prGlueInfo->rBowInfo.u4DeviceNumber, 1); + return FALSE; +} /* end of glRegisterAmpc */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Unregister character device for communicating with 802.11 PAL +* +* \param[in] prGlueInfo Pointer to glue info +* +* \return TRUE +* FALSE +*/ +/*----------------------------------------------------------------------------*/ +u_int8_t glUnregisterAmpc(IN struct GLUE_INFO *prGlueInfo) +{ + ASSERT(prGlueInfo); + + DBGLOG(BOW, INFO, "Unregister character device for communicating with 802.11 PAL.\n"); + + if (prGlueInfo->rBowInfo.fgIsRegistered == FALSE) + return FALSE; + + prGlueInfo->rBowInfo.fgIsRegistered = FALSE; + + /* 1. free netdev if necessary */ +#if CFG_BOW_SEPARATE_DATA_PATH + kalUninitBowDevice(prGlueInfo); +#endif + + /* 2. removal of character device */ + cdev_del(&(prGlueInfo->rBowInfo.cdev)); + + /* 3. free kfifo */ +/* kfifo_free(prGlueInfo->rBowInfo.prKfifo); */ + kfifo_free(&(prGlueInfo->rBowInfo.rKfifo)); +/* prGlueInfo->rBowInfo.prKfifo = NULL; */ +/* prGlueInfo->rBowInfo.rKfifo = NULL; */ + + /* 4. free device number */ + unregister_chrdev_region(prGlueInfo->rBowInfo.u4DeviceNumber, 1); + + return TRUE; + +} /* end of glUnregisterAmpc */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief read handler for character device to communicate with 802.11 PAL +* +* \param[in] +* \return +* Follows Linux Character Device Interface +* +*/ +/*----------------------------------------------------------------------------*/ +static ssize_t bow_ampc_read(IN struct file *filp, IN char __user *buf, IN size_t size, IN OUT loff_t *ppos) +{ + uint8_t aucBuffer[MAX_BUFFER_SIZE]; + ssize_t retval; + + struct GLUE_INFO *prGlueInfo; + + prGlueInfo = (struct GLUE_INFO *) (filp->private_data); + + ASSERT(prGlueInfo); + + DBGLOG(BOW, INFO, "BoW EVENT read.\n"); + + if ((prGlueInfo->rBowInfo.fgIsRegistered == FALSE) || (prGlueInfo->ulFlag & GLUE_FLAG_HALT)) + return -EFAULT; + /* size check */ +/* if(kfifo_len(prGlueInfo->rBowInfo.prKfifo) >= size) */ + if (kfifo_len(&(prGlueInfo->rBowInfo.rKfifo)) >= size) + retval = size; + else + retval = kfifo_len(&(prGlueInfo->rBowInfo.rKfifo)); +/* retval = kfifo_len(prGlueInfo->rBowInfo.prKfifo); */ + +/* kfifo_get(prGlueInfo->rBowInfo.prKfifo, aucBuffer, retval); */ +/* kfifo_out(prGlueInfo->rBowInfo.prKfifo, aucBuffer, retval); */ + if (!(kfifo_out(&(prGlueInfo->rBowInfo.rKfifo), aucBuffer, retval))) + retval = -EIO; + + if (copy_to_user(buf, aucBuffer, retval)) + retval = -EIO; + + return retval; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief write handler for character device to communicate with 802.11 PAL +* +* \param[in] +* \return +* Follows Linux Character Device Interface +* +*/ +/*----------------------------------------------------------------------------*/ +static ssize_t bow_ampc_write(IN struct file *filp, OUT const char __user *buf, IN size_t size, IN OUT loff_t *ppos) +{ + uint8_t i; + + uint8_t aucBuffer[MAX_BUFFER_SIZE]; + struct BT_OVER_WIFI_COMMAND *prCmd; + struct GLUE_INFO *prGlueInfo; + + prGlueInfo = (struct GLUE_INFO *) (filp->private_data); + ASSERT(prGlueInfo); + + if ((prGlueInfo->rBowInfo.fgIsRegistered == FALSE) || (prGlueInfo->ulFlag & GLUE_FLAG_HALT)) + return -EFAULT; + + if (size > MAX_BUFFER_SIZE) + return -EINVAL; + else if (copy_from_user(aucBuffer, buf, size)) + return -EIO; + + DBGLOG(BOW, EVENT, "AMP driver CMD buffer size : %d.\n", size); + + for (i = 0; i < MAX_BUFFER_SIZE; i++) + DBGLOG(BOW, EVENT, "AMP write content : 0x%x.\n", aucBuffer[i]); + + DBGLOG(BOW, EVENT, "BoW CMD write.\n"); + + prCmd = (struct BT_OVER_WIFI_COMMAND *) aucBuffer; + + DBGLOG(BOW, EVENT, "AMP write content payload length : %d.\n", prCmd->rHeader.u2PayloadLength); + + DBGLOG(BOW, EVENT, "AMP write content header length : %d.\n", sizeof(struct BT_OVER_WIFI_COMMAND_HEADER)); + + /* size check */ + if (prCmd->rHeader.u2PayloadLength + sizeof(struct BT_OVER_WIFI_COMMAND_HEADER) != size) { + DBGLOG(BOW, EVENT, "Wrong CMD total length.\n"); + + return -EINVAL; + } + + if (wlanbowHandleCommand(prGlueInfo->prAdapter, prCmd) == WLAN_STATUS_SUCCESS) + return size; + else + return -EINVAL; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief ioctl handler for character device to communicate with 802.11 PAL +* +* \param[in] +* \return +* Follows Linux Character Device Interface +* +*/ +/*----------------------------------------------------------------------------*/ +static long bow_ampc_ioctl(IN struct file *filp, IN unsigned int cmd, IN OUT unsigned long arg) +{ + int err = 0; + struct GLUE_INFO *prGlueInfo; + + prGlueInfo = (struct GLUE_INFO *) (filp->private_data); + + ASSERT(prGlueInfo); + + if ((prGlueInfo->rBowInfo.fgIsRegistered == FALSE) || (prGlueInfo->ulFlag & GLUE_FLAG_HALT)) + return -EFAULT; + /* permission check */ + if (_IOC_DIR(cmd) & _IOC_READ) + err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd)); + else if (_IOC_DIR(cmd) & _IOC_WRITE) + err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd)); + if (err) + return -EFAULT; + + /* no ioctl is implemented yet */ + return 0; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief ioctl handler for character device to communicate with 802.11 PAL +* +* \param[in] +* \return +* Follows Linux Character Device Interface +* +*/ +/*----------------------------------------------------------------------------*/ +static unsigned int bow_ampc_poll(IN struct file *filp, IN poll_table * wait) +{ + unsigned int retval; + struct GLUE_INFO *prGlueInfo; + + prGlueInfo = (struct GLUE_INFO *) (filp->private_data); + + ASSERT(prGlueInfo); + + if ((prGlueInfo->rBowInfo.fgIsRegistered == FALSE) || (prGlueInfo->ulFlag & GLUE_FLAG_HALT)) + return -EFAULT; + + poll_wait(filp, &prGlueInfo->rBowInfo.outq, wait); + + retval = (POLLOUT | POLLWRNORM); /* always accepts incoming command packets */ + +/* DBGLOG(BOW, EVENT, ("bow_ampc_pol, POLLOUT | POLLWRNORM, %x\n", retval)); */ + +/* if(kfifo_len(prGlueInfo->rBowInfo.prKfifo) > 0) */ + if (kfifo_len(&(prGlueInfo->rBowInfo.rKfifo)) > 0) { + retval |= (POLLIN | POLLRDNORM); + +/* DBGLOG(BOW, EVENT, ("bow_ampc_pol, POLLIN | POLLRDNORM, %x\n", retval)); */ + + } + + return retval; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief open handler for character device to communicate with 802.11 PAL +* +* \param[in] +* \return +* Follows Linux Character Device Interface +* +*/ +/*----------------------------------------------------------------------------*/ +static int bow_ampc_open(IN struct inode *inodep, IN struct file *filp) +{ + struct GLUE_INFO *prGlueInfo; + struct GL_BOW_INFO *prBowInfo; + + DBGLOG(BOW, INFO, "in %s\n", __func__); + + prBowInfo = container_of(inodep->i_cdev, struct GL_BOW_INFO, cdev); + ASSERT(prBowInfo); + + prGlueInfo = container_of(prBowInfo, struct GLUE_INFO, rBowInfo); + ASSERT(prGlueInfo); + + /* set-up private data */ + filp->private_data = prGlueInfo; + + return 0; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief close handler for character device to communicate with 802.11 PAL +* +* \param[in] +* \return +* Follows Linux Character Device Interface +* +*/ +/*----------------------------------------------------------------------------*/ +static int bow_ampc_release(IN struct inode *inodep, IN struct file *filp) +{ + struct GLUE_INFO *prGlueInfo; + + prGlueInfo = (struct GLUE_INFO *) (filp->private_data); + + DBGLOG(BOW, INFO, "in %s\n", __func__); + + ASSERT(prGlueInfo); + + return 0; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief to indicate event for Bluetooth over Wi-Fi +* +* \param[in] +* prGlueInfo +* prEvent +* \return +* none +*/ +/*----------------------------------------------------------------------------*/ +void kalIndicateBOWEvent(IN struct GLUE_INFO *prGlueInfo, IN struct BT_OVER_WIFI_EVENT *prEvent) +{ + size_t u4AvailSize, u4EventSize; + + ASSERT(prGlueInfo); + ASSERT(prEvent); + + /* check device */ + if ((prGlueInfo->rBowInfo.fgIsRegistered == FALSE) || (prGlueInfo->ulFlag & GLUE_FLAG_HALT)) + return; +#if 0 + u4AvailSize = GLUE_BOW_KFIFO_DEPTH - kfifo_len(prGlueInfo->rBowInfo.prKfifo); +#endif + u4AvailSize = GLUE_BOW_KFIFO_DEPTH - kfifo_len(&(prGlueInfo->rBowInfo.rKfifo)); + + u4EventSize = prEvent->rHeader.u2PayloadLength + sizeof(struct BT_OVER_WIFI_EVENT_HEADER); + + /* check kfifo availability */ + if (u4AvailSize < u4EventSize) { + DBGLOG(BOW, EVENT, "[bow] no space for event: %d/%d\n", u4EventSize, u4AvailSize); + return; + } + /* queue into kfifo */ +/* kfifo_put(prGlueInfo->rBowInfo.prKfifo, (PUINT_8)prEvent, u4EventSize); */ +/* kfifo_in(prGlueInfo->rBowInfo.prKfifo, (PUINT_8)prEvent, u4EventSize); */ + kfifo_in(&(prGlueInfo->rBowInfo.rKfifo), (uint8_t *) prEvent, u4EventSize); + wake_up_interruptible(&(prGlueInfo->rBowInfo.outq)); + +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief to retrieve Bluetooth-over-Wi-Fi state from glue layer +* +* \param[in] +* prGlueInfo +* rPeerAddr +* \return +* ENUM_BOW_DEVICE_STATE +*/ +/*----------------------------------------------------------------------------*/ +enum ENUM_BOW_DEVICE_STATE kalGetBowState(IN struct GLUE_INFO *prGlueInfo, IN uint8_t aucPeerAddress[6]) +{ + uint8_t i; + + ASSERT(prGlueInfo); + + DBGLOG(BOW, EVENT, "kalGetBowState.\n"); + + for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) { + if (EQUAL_MAC_ADDR(prGlueInfo->rBowInfo.arPeerAddr, aucPeerAddress) == 0) { + DBGLOG(BOW, EVENT, + "kalGetBowState, aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", i, + aucPeerAddress[0], aucPeerAddress[1], aucPeerAddress[2], + aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5]); + + DBGLOG(BOW, EVENT, + "kalGetBowState, prGlueInfo->rBowInfo.aeState %x, %x.\n", i, + prGlueInfo->rBowInfo.aeState[i]); + + return prGlueInfo->rBowInfo.aeState[i]; + } + } + + return BOW_DEVICE_STATE_DISCONNECTED; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief to set Bluetooth-over-Wi-Fi state in glue layer +* +* \param[in] +* prGlueInfo +* eBowState +* rPeerAddr +* \return +* none +*/ +/*----------------------------------------------------------------------------*/ +u_int8_t kalSetBowState(IN struct GLUE_INFO *prGlueInfo, IN enum ENUM_BOW_DEVICE_STATE eBowState, IN uint8_t aucPeerAddress[6]) +{ + uint8_t i; + + ASSERT(prGlueInfo); + DBGLOG(BOW, EVENT, "kalSetBowState, aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", + aucPeerAddress[0], + aucPeerAddress[1], aucPeerAddress[2], aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5]); + + for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) { + if (EQUAL_MAC_ADDR(prGlueInfo->rBowInfo.arPeerAddr, aucPeerAddress) == 0) { + prGlueInfo->rBowInfo.aeState[i] = eBowState; + + DBGLOG(BOW, EVENT, + "kalSetBowState, aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", i, + aucPeerAddress[0], aucPeerAddress[1], aucPeerAddress[2], + aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5]); + + DBGLOG(BOW, EVENT, + "kalSetBowState, prGlueInfo->rBowInfo.aeState %x, %x.\n", i, + prGlueInfo->rBowInfo.aeState[i]); + + return TRUE; + } + } + + return FALSE; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief to retrieve Bluetooth-over-Wi-Fi global state +* +* \param[in] +* prGlueInfo +* +* \return +* BOW_DEVICE_STATE_DISCONNECTED +* in case there is no BoW connection or +* BoW connection under initialization +* +* BOW_DEVICE_STATE_STARTING +* in case there is no BoW connection but +* some BoW connection under initialization +* +* BOW_DEVICE_STATE_CONNECTED +* in case there is any BoW connection available +*/ +/*----------------------------------------------------------------------------*/ +enum ENUM_BOW_DEVICE_STATE kalGetBowGlobalState(IN struct GLUE_INFO *prGlueInfo) +{ + uint32_t i; + + ASSERT(prGlueInfo); + +/* Henry, can reduce this logic to indentify state change */ + + for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) { + if (prGlueInfo->rBowInfo.aeState[i] == BOW_DEVICE_STATE_CONNECTED) + return BOW_DEVICE_STATE_CONNECTED; + } + + for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) { + if (prGlueInfo->rBowInfo.aeState[i] == BOW_DEVICE_STATE_STARTING) + return BOW_DEVICE_STATE_STARTING; + } + + return BOW_DEVICE_STATE_DISCONNECTED; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief to retrieve Bluetooth-over-Wi-Fi operating frequency +* +* \param[in] +* prGlueInfo +* +* \return +* in unit of KHz +*/ +/*----------------------------------------------------------------------------*/ +uint32_t kalGetBowFreqInKHz(IN struct GLUE_INFO *prGlueInfo) +{ + ASSERT(prGlueInfo); + + return prGlueInfo->rBowInfo.u4FreqInKHz; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief to retrieve Bluetooth-over-Wi-Fi role +* +* \param[in] +* prGlueInfo +* +* \return +* 0: Responder +* 1: Initiator +*/ +/*----------------------------------------------------------------------------*/ +uint8_t kalGetBowRole(IN struct GLUE_INFO *prGlueInfo, IN uint8_t rPeerAddr[PARAM_MAC_ADDR_LEN]) +{ + uint32_t i; + + ASSERT(prGlueInfo); + + for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) { + if (EQUAL_MAC_ADDR(prGlueInfo->rBowInfo.arPeerAddr[i], rPeerAddr) == 0) + return prGlueInfo->rBowInfo.aucRole[i]; + } + + return 0; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief to set Bluetooth-over-Wi-Fi role +* +* \param[in] +* prGlueInfo +* ucRole +* 0: Responder +* 1: Initiator +* \return +* none +*/ +/*----------------------------------------------------------------------------*/ +void kalSetBowRole(IN struct GLUE_INFO *prGlueInfo, IN uint8_t ucRole, IN uint8_t rPeerAddr[PARAM_MAC_ADDR_LEN]) +{ + uint32_t i; + + ASSERT(prGlueInfo); + ASSERT(ucRole <= 1); + + for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) { + if (EQUAL_MAC_ADDR(prGlueInfo->rBowInfo.arPeerAddr[i], rPeerAddr) == 0) { + /* Henry, 0 : Responder, 1 : Initiator */ + prGlueInfo->rBowInfo.aucRole[i] = ucRole; + } + } +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief to get available Bluetooth-over-Wi-Fi physical link number +* +* \param[in] +* prGlueInfo +* \return +* UINT_32 +* how many physical links are aviailable +*/ +/*----------------------------------------------------------------------------*/ +uint8_t kalGetBowAvailablePhysicalLinkCount(IN struct GLUE_INFO *prGlueInfo) +{ + uint8_t i; + uint8_t ucLinkCount = 0; + + ASSERT(prGlueInfo); + + for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) { + if (prGlueInfo->rBowInfo.aeState[i] == BOW_DEVICE_STATE_DISCONNECTED) + ucLinkCount++; + } + +#if 0 + DBGLOG(BOW, EVENT, "kalGetBowAvailablePhysicalLinkCount, ucLinkCount, %c.\n", ucLinkCount); +#endif + + return ucLinkCount; +} + +/*----------------------------------------------------------------------------*/ +/*! +* @brief This inline function is to extract some packet information for BoW +* +* @param prGlueInfo Pointer to the glue structure +* @param prNdisPacket Packet descriptor +* @param pfgIs1X 802.1x packet or not +* +* @retval TRUE Success to extract information +* @retval FALSE Fail to extract correct information +*/ +/*----------------------------------------------------------------------------*/ +u_int8_t kalBowFrameClassifier(IN struct GLUE_INFO *prGlueInfo, IN void *prPacket, OUT u_int8_t *pfgIs1X) +{ + uint32_t u4PacketLen; + uint16_t u2EtherTypeLen; + struct sk_buff *prSkb = (struct sk_buff *)prPacket; + uint8_t *aucLookAheadBuf = NULL; + uint8_t ucEthTypeLenOffset = ETHER_HEADER_LEN - ETHER_TYPE_LEN; + uint8_t *pucNextProtocol = NULL; + uint8_t aucLLC[] = ETH_LLC; + uint8_t aucSnapBtOui[] = ETH_SNAP_BT_SIG_OUI; + uint8_t ucMinLength = ucEthTypeLenOffset + ETHER_TYPE_LEN + ETH_LLC_LEN + ETH_SNAP_LEN; + + DEBUGFUNC("kalQoSFrameClassifierAndPacketInfo"); + + u4PacketLen = prSkb->len; + + if (u4PacketLen < ETHER_HEADER_LEN) { + DBGLOG(INIT, WARN, "Invalid Ether packet length: %lu\n", u4PacketLen); + return FALSE; + } + + aucLookAheadBuf = prSkb->data; + + *pfgIs1X = FALSE; + + /* 4 <0> Obtain Ether Type/Len */ + WLAN_GET_FIELD_BE16(&aucLookAheadBuf[ucEthTypeLenOffset], &u2EtherTypeLen); + + /* 4 <1> Skip 802.1Q header (VLAN Tagging) */ + if (u2EtherTypeLen == ETH_P_VLAN) { + ucEthTypeLenOffset += ETH_802_1Q_HEADER_LEN; + WLAN_GET_FIELD_BE16(&aucLookAheadBuf[ucEthTypeLenOffset], &u2EtherTypeLen); + } + /* 4 <2> Obtain next protocol pointer */ + pucNextProtocol = &aucLookAheadBuf[ucEthTypeLenOffset + ETHER_TYPE_LEN]; + + /* 4 <3> Handle ethernet format */ + if (u2EtherTypeLen > ETH_802_3_MAX_LEN) { + /* Not BoW frame */ + return FALSE; + } + /* 4 <4> Check for PAL (BT over Wi-Fi) */ + /* BoW LLC/SNAP header check */ + if (u4PacketLen >= ucMinLength && + !kalMemCmp(pucNextProtocol, aucLLC, ETH_LLC_LEN) && + !kalMemCmp(pucNextProtocol + ETH_LLC_LEN, aucSnapBtOui, ETH_SNAP_OUI_LEN)) { + uint16_t u2LocalCode; + + WLAN_GET_FIELD_BE16(pucNextProtocol + ETH_LLC_LEN + ETH_SNAP_OUI_LEN, &u2LocalCode); + + if (u2LocalCode == BOW_PROTOCOL_ID_SECURITY_FRAME) + *pfgIs1X = TRUE; + + return TRUE; + } + + return FALSE; +} /* end of kalBoWFrameClassifier() */ + +#if CFG_BOW_SEPARATE_DATA_PATH + +/* Net Device Hooks */ +/*----------------------------------------------------------------------------*/ +/*! + * \brief A function for net_device open (ifup) + * + * \param[in] prDev Pointer to struct net_device. + * + * \retval 0 The execution succeeds. + * \retval < 0 The execution failed. + */ +/*----------------------------------------------------------------------------*/ +static int bowOpen(IN struct net_device *prDev) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + + ASSERT(prDev); + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prDev)); + ASSERT(prGlueInfo); + + prAdapter = prGlueInfo->prAdapter; + ASSERT(prAdapter); + + /* 2. carrier on & start TX queue */ + netif_carrier_on(prDev); + netif_tx_start_all_queues(prDev); + + return 0; /* success */ +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief A function for net_device stop (ifdown) + * + * \param[in] prDev Pointer to struct net_device. + * + * \retval 0 The execution succeeds. + * \retval < 0 The execution failed. + */ +/*----------------------------------------------------------------------------*/ +static int bowStop(IN struct net_device *prDev) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + + ASSERT(prDev); + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prDev)); + ASSERT(prGlueInfo); + + prAdapter = prGlueInfo->prAdapter; + ASSERT(prAdapter); + + /* 1. stop TX queue */ + netif_tx_stop_all_queues(prDev); + + /* 2. turn of carrier */ + if (netif_carrier_ok(prDev)) + netif_carrier_off(prDev); + + return 0; +}; + +#if 0 +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is TX entry point of NET DEVICE. + * + * \param[in] prSkb Pointer of the sk_buff to be sent + * \param[in] prDev Pointer to struct net_device + * + * \retval NETDEV_TX_OK - on success. + * \retval NETDEV_TX_BUSY - on failure, packet will be discarded by upper layer. + */ +/*----------------------------------------------------------------------------*/ +static netdev_tx_t bowHardStartXmit(IN struct sk_buff *prSkb, + IN struct net_device *prDev) +{ + struct GLUE_INFO *prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prDev)); + + struct QUE_ENTRY *prQueueEntry = NULL; + struct QUE *prTxQueue = NULL; + uint16_t u2QueueIdx = 0; + uint8_t ucDSAP, ucSSAP, ucControl; + uint8_t aucOUI[3]; + uint8_t *aucLookAheadBuf = NULL; + uint8_t ucBssIndex; + + GLUE_SPIN_LOCK_DECLARATION(); + + ASSERT(prSkb); + ASSERT(prDev); + ASSERT(prGlueInfo); + + aucLookAheadBuf = prSkb->data; + + ucDSAP = *(uint8_t *) &aucLookAheadBuf[ETH_LLC_OFFSET]; + ucSSAP = *(uint8_t *) &aucLookAheadBuf[ETH_LLC_OFFSET + 1]; + ucControl = *(uint8_t *) &aucLookAheadBuf[ETH_LLC_OFFSET + 2]; + aucOUI[0] = *(uint8_t *) &aucLookAheadBuf[ETH_SNAP_OFFSET]; + aucOUI[1] = *(uint8_t *) &aucLookAheadBuf[ETH_SNAP_OFFSET + 1]; + aucOUI[2] = *(uint8_t *) &aucLookAheadBuf[ETH_SNAP_OFFSET + 2]; + + if (!(ucDSAP == ETH_LLC_DSAP_SNAP && + ucSSAP == ETH_LLC_SSAP_SNAP && + ucControl == ETH_LLC_CONTROL_UNNUMBERED_INFORMATION && + aucOUI[0] == ETH_SNAP_BT_SIG_OUI_0 && + aucOUI[1] == ETH_SNAP_BT_SIG_OUI_1 && aucOUI[2] == ETH_SNAP_BT_SIG_OUI_2) || (prSkb->len > 1514)) { + dev_kfree_skb(prSkb); + return NETDEV_TX_OK; + } + + if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { + DBGLOG(BOW, TRACE, "GLUE_FLAG_HALT skip tx\n"); + dev_kfree_skb(prSkb); + return NETDEV_TX_OK; + } + + GLUE_SET_PKT_FLAG_PAL(prSkb); + + ucBssIndex = wlanGetBssIdxByNetInterface(prGlueInfo, NET_DEV_BOW_IDX); + + GLUE_SET_PKT_BSS_IDX(prSkb, ucBssIndex); + + prQueueEntry = (struct QUE_ENTRY *) GLUE_GET_PKT_QUEUE_ENTRY(prSkb); + prTxQueue = &prGlueInfo->rTxQueue; + + if (wlanProcessSecurityFrame(prGlueInfo->prAdapter, (void *) prSkb) == FALSE) { + GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); + QUEUE_INSERT_TAIL(prTxQueue, prQueueEntry); + GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); + + GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingFrameNum); + GLUE_INC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[ucBssIndex][u2QueueIdx]); + + if (prGlueInfo->ai4TxPendingFrameNumPerQueue[ucBssIndex][u2QueueIdx] >= + CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD) { + netif_stop_subqueue(prDev, u2QueueIdx); + } + } else { + GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum); + } + + kalSetEvent(prGlueInfo); + + /* For Linux, we'll always return OK FLAG, because we'll free this skb by ourself */ + return NETDEV_TX_OK; +} +#else +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is TX entry point of NET DEVICE. + * + * \param[in] prSkb Pointer of the sk_buff to be sent + * \param[in] prDev Pointer to struct net_device + * + * \retval NETDEV_TX_OK - on success. + * \retval NETDEV_TX_BUSY - on failure, packet will be discarded by upper layer. + */ +/*----------------------------------------------------------------------------*/ +static netdev_tx_t bowHardStartXmit(IN struct sk_buff *prSkb, + IN struct net_device *prDev) +{ + struct NETDEV_PRIVATE_GLUE_INFO *prNetDevPrivate = (struct NETDEV_PRIVATE_GLUE_INFO *) NULL; + struct GLUE_INFO *prGlueInfo = NULL; + uint8_t ucBssIndex; + u_int8_t fgIs1x; + + ASSERT(prSkb); + ASSERT(prDev); + +#if 1 + prNetDevPrivate = (struct NETDEV_PRIVATE_GLUE_INFO *) netdev_priv(prDev); + prGlueInfo = prNetDevPrivate->prGlueInfo; + ucBssIndex = prNetDevPrivate->ucBssIdx; +#else + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prDev)); + + ucBssIndex = wlanGetBssIdxByNetInterface(prGlueInfo, NET_DEV_BOW_IDX); +#endif + + kalResetPacket(prGlueInfo, (void *) prSkb); + + /* Discard frames not generated by PAL */ + /* Parsing BOW frame info */ + if (!kalBowFrameClassifier(prGlueInfo, (void *) prSkb, &fgIs1x)) { + /* Cannot extract packet */ + DBGLOG(BOW, INFO, "Invalid BOW frame, skip Tx\n"); + dev_kfree_skb(prSkb); + return NETDEV_TX_OK; + } + + if (fgIs1x) + GLUE_SET_PKT_FLAG(prSkb, ENUM_PKT_1X); + + if (kalHardStartXmit(prSkb, prDev, prGlueInfo, ucBssIndex) == WLAN_STATUS_SUCCESS) { + /* Successfully enqueue to Tx queue */ + /* Successfully enqueue to Tx queue */ + } + + /* For Linux, we'll always return OK FLAG, because we'll free this skb by ourself */ + return NETDEV_TX_OK; +} +#endif + +/* callbacks for netdevice */ +static const struct net_device_ops bow_netdev_ops = { + .ndo_open = bowOpen, + .ndo_stop = bowStop, + .ndo_start_xmit = bowHardStartXmit, +}; + +/*----------------------------------------------------------------------------*/ +/*! +* \brief initialize net device for Bluetooth-over-Wi-Fi +* +* \param[in] +* prGlueInfo +* prDevName +* +* \return +* TRUE +* FALSE +*/ +/*----------------------------------------------------------------------------*/ +u_int8_t kalInitBowDevice(IN struct GLUE_INFO *prGlueInfo, IN const char *prDevName) +{ + struct ADAPTER *prAdapter; + struct GL_HIF_INFO *prHif; + uint8_t rMacAddr[PARAM_MAC_ADDR_LEN]; + struct NETDEV_PRIVATE_GLUE_INFO *prNetDevPriv = (struct NETDEV_PRIVATE_GLUE_INFO *) NULL; + struct mt66xx_chip_info *prChipInfo; + + ASSERT(prGlueInfo); + ASSERT(prGlueInfo->rBowInfo.fgIsRegistered == TRUE); + + prAdapter = prGlueInfo->prAdapter; + ASSERT(prAdapter); + + prHif = &prGlueInfo->rHifInfo; + ASSERT(prHif); + + prChipInfo = prGlueInfo->prAdapter->chip_info; + + if (prGlueInfo->rBowInfo.fgIsNetRegistered == FALSE) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0) + prGlueInfo->rBowInfo.prDevHandler = + alloc_netdev_mq(sizeof(struct GLUE_INFO *), prDevName, + NET_NAME_PREDICTABLE, ether_setup, CFG_MAX_TXQ_NUM); +#else + prGlueInfo->rBowInfo.prDevHandler = + alloc_netdev_mq(sizeof(struct GLUE_INFO *), prDevName, ether_setup, CFG_MAX_TXQ_NUM); +#endif + if (!prGlueInfo->rBowInfo.prDevHandler) + return FALSE; + + /* 1. setup netdev */ + /* 1.1 Point to shared glue structure */ + /* *((P_GLUE_INFO_T *) netdev_priv(prGlueInfo->rBowInfo.prDevHandler)) = prGlueInfo; */ + prNetDevPriv = (struct NETDEV_PRIVATE_GLUE_INFO *) netdev_priv(prGlueInfo->rBowInfo.prDevHandler); + prNetDevPriv->prGlueInfo = prGlueInfo; + + /* 1.2 fill hardware address */ + COPY_MAC_ADDR(rMacAddr, prAdapter->rMyMacAddr); + rMacAddr[0] |= 0x2; /* change to local administrated address */ + kalMemCopy(prGlueInfo->rBowInfo.prDevHandler->dev_addr, rMacAddr, ETH_ALEN); + kalMemCopy(prGlueInfo->rBowInfo.prDevHandler->perm_addr, + prGlueInfo->rBowInfo.prDevHandler->dev_addr, ETH_ALEN); + + /* 1.3 register callback functions */ + prGlueInfo->rBowInfo.prDevHandler->needed_headroom = + NIC_TX_DESC_AND_PADDING_LENGTH + prChipInfo->txd_append_size; + prGlueInfo->rBowInfo.prDevHandler->netdev_ops = &bow_netdev_ops; + +#if defined(_HIF_SDIO) && (MTK_WCN_HIF_SDIO == 0) + SET_NETDEV_DEV(prGlueInfo->rBowInfo.prDevHandler, &(prHif->func->dev)); +#endif + + register_netdev(prGlueInfo->rBowInfo.prDevHandler); + + /* 2. net device initialize */ + netif_carrier_off(prGlueInfo->rBowInfo.prDevHandler); + netif_tx_stop_all_queues(prGlueInfo->rBowInfo.prDevHandler); + + /* 2.1 bind NetDev pointer to NetDev index */ + wlanBindBssIdxToNetInterface(prGlueInfo, bowInit(prAdapter), + (void *) prGlueInfo->rBowInfo.prDevHandler); + prNetDevPriv->ucBssIdx = prAdapter->rWifiVar.rBowFsmInfo.ucBssIndex; + /* wlanBindNetInterface(prGlueInfo, NET_DEV_BOW_IDX, */ + /* (PVOID)prGlueInfo->rBowInfo.prDevHandler); */ + + /* 3. finish */ + prGlueInfo->rBowInfo.fgIsNetRegistered = TRUE; + } + + return TRUE; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief uninitialize net device for Bluetooth-over-Wi-Fi +* +* \param[in] +* prGlueInfo +* +* \return +* TRUE +* FALSE +*/ +/*----------------------------------------------------------------------------*/ +u_int8_t kalUninitBowDevice(IN struct GLUE_INFO *prGlueInfo) +{ + struct ADAPTER *prAdapter; + + ASSERT(prGlueInfo); + + prAdapter = prGlueInfo->prAdapter; + ASSERT(prAdapter); + /* ASSERT(prGlueInfo->rBowInfo.fgIsRegistered == TRUE); */ + + if (prGlueInfo->rBowInfo.fgIsNetRegistered == TRUE) { + + prGlueInfo->rBowInfo.fgIsNetRegistered = FALSE; + + bowUninit(prAdapter); + + if (netif_carrier_ok(prGlueInfo->rBowInfo.prDevHandler)) + netif_carrier_off(prGlueInfo->rBowInfo.prDevHandler); + + netif_tx_stop_all_queues(prGlueInfo->rBowInfo.prDevHandler); + + /* netdevice unregistration & free */ + unregister_netdev(prGlueInfo->rBowInfo.prDevHandler); + free_netdev(prGlueInfo->rBowInfo.prDevHandler); + prGlueInfo->rBowInfo.prDevHandler = NULL; + + return TRUE; + + } else { + return FALSE; + } +} + +#endif /* CFG_BOW_SEPARATE_DATA_PATH */ +#endif /* CFG_ENABLE_BT_OVER_WIFI */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_cfg80211.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_cfg80211.c new file mode 100644 index 0000000000000000000000000000000000000000..3f4a639201c828111c02de34477fd2f1fbd93b36 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_cfg80211.c @@ -0,0 +1,7625 @@ +/******************************************************************************* + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ +/* + ** Id: @(#) gl_cfg80211.c@@ + */ + +/*! \file gl_cfg80211.c + * \brief Main routines for supporintg MT6620 cfg80211 control interface + * + * This file contains the support routines of Linux driver for MediaTek Inc. + * 802.11 Wireless LAN Adapters. + */ + + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "gl_os.h" +#include "debug.h" +#include "wlan_lib.h" +#include "gl_wext.h" +#include "precomp.h" +#include +#include +#include +#include "gl_cfg80211.h" +#include "gl_vendor.h" +#include "gl_p2p_os.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is responsible for change STA type between + * 1. Infrastructure Client (Non-AP STA) + * 2. Ad-Hoc IBSS + * + * @param + * + * @retval 0: successful + * others: failure + */ +/*----------------------------------------------------------------------------*/ +int +mtk_cfg80211_change_iface(struct wiphy *wiphy, + struct net_device *ndev, enum nl80211_iftype type, + u32 *flags, struct vif_params *params) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + struct PARAM_OP_MODE rOpMode; + uint32_t u4BufLen; + struct GL_WPA_INFO *prWpaInfo; + uint8_t ucBssIndex = 0; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + ASSERT(prGlueInfo); + + ucBssIndex = wlanGetBssIdx(ndev); + if (!IS_BSS_INDEX_VALID(ucBssIndex)) + return -EINVAL; + + if (type == NL80211_IFTYPE_STATION) + rOpMode.eOpMode = NET_TYPE_INFRA; + else if (type == NL80211_IFTYPE_ADHOC) + rOpMode.eOpMode = NET_TYPE_IBSS; + else + return -EINVAL; + rOpMode.ucBssIdx = ucBssIndex; + rStatus = kalIoctl(prGlueInfo, wlanoidSetInfrastructureMode, + (void *)&rOpMode, sizeof(struct PARAM_OP_MODE), + FALSE, FALSE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(REQ, WARN, "set infrastructure mode error:%x\n", + rStatus); + + prWpaInfo = aisGetWpaInfo(prGlueInfo->prAdapter, + ucBssIndex); + + /* reset wpa info */ + prWpaInfo->u4WpaVersion = + IW_AUTH_WPA_VERSION_DISABLED; + prWpaInfo->u4KeyMgmt = 0; + prWpaInfo->u4CipherGroup = IW_AUTH_CIPHER_NONE; + prWpaInfo->u4CipherPairwise = IW_AUTH_CIPHER_NONE; + prWpaInfo->u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM; +#if CFG_SUPPORT_802_11W + prWpaInfo->u4Mfp = IW_AUTH_MFP_DISABLED; + prWpaInfo->ucRSNMfpCap = 0; +#endif + + ndev->ieee80211_ptr->iftype = type; + + return 0; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is responsible for adding key + * + * @param + * + * @retval 0: successful + * others: failure + */ +/*----------------------------------------------------------------------------*/ +int +mtk_cfg80211_add_key(struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index, bool pairwise, const u8 *mac_addr, + struct key_params *params) +{ + struct PARAM_KEY rKey; + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + int32_t i4Rslt = -EINVAL; + uint32_t u4BufLen = 0; + uint8_t tmp1[8], tmp2[8]; + uint8_t ucBssIndex = 0; + const uint8_t aucBCAddr[] = BC_MAC_ADDR; + /* const UINT_8 aucZeroMacAddr[] = NULL_MAC_ADDR; */ + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + ASSERT(prGlueInfo); + + ucBssIndex = wlanGetBssIdx(ndev); + if (!IS_BSS_INDEX_VALID(ucBssIndex)) + return -EINVAL; + + #if DBG + if (mac_addr) { + DBGLOG(RSN, INFO, + "keyIdx = %d pairwise = %d mac = " MACSTR "\n", + key_index, pairwise, MAC2STR(mac_addr)); + } else { + DBGLOG(RSN, INFO, "keyIdx = %d pairwise = %d null mac\n", + key_index, pairwise); + } + DBGLOG(RSN, INFO, "Cipher = %x\n", params->cipher); + DBGLOG_MEM8(RSN, INFO, params->key, params->key_len); +#endif + + kalMemZero(&rKey, sizeof(struct PARAM_KEY)); + + rKey.u4KeyIndex = key_index; + + if (params->cipher) { + switch (params->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + rKey.ucCipher = CIPHER_SUITE_WEP40; + break; + case WLAN_CIPHER_SUITE_WEP104: + rKey.ucCipher = CIPHER_SUITE_WEP104; + break; +#if 0 + case WLAN_CIPHER_SUITE_WEP128: + rKey.ucCipher = CIPHER_SUITE_WEP128; + break; +#endif + case WLAN_CIPHER_SUITE_TKIP: + rKey.ucCipher = CIPHER_SUITE_TKIP; + break; + case WLAN_CIPHER_SUITE_CCMP: + rKey.ucCipher = CIPHER_SUITE_CCMP; + break; +#if 0 + case WLAN_CIPHER_SUITE_GCMP: + rKey.ucCipher = CIPHER_SUITE_GCMP; + break; + case WLAN_CIPHER_SUITE_CCMP_256: + rKey.ucCipher = CIPHER_SUITE_CCMP256; + break; +#endif + case WLAN_CIPHER_SUITE_SMS4: + rKey.ucCipher = CIPHER_SUITE_WPI; + break; + case WLAN_CIPHER_SUITE_AES_CMAC: + rKey.ucCipher = CIPHER_SUITE_BIP; + break; + case WLAN_CIPHER_SUITE_GCMP_256: + rKey.ucCipher = CIPHER_SUITE_GCMP_256; + break; + case WLAN_CIPHER_SUITE_BIP_GMAC_256: + DBGLOG(RSN, INFO, + "[TODO] Set BIP-GMAC-256, SW should handle it ...\n"); + return 0; + default: + ASSERT(FALSE); + } + } + + if (pairwise) { + ASSERT(mac_addr); + rKey.u4KeyIndex |= BIT(31); + rKey.u4KeyIndex |= BIT(30); + COPY_MAC_ADDR(rKey.arBSSID, mac_addr); + } else { /* Group key */ + COPY_MAC_ADDR(rKey.arBSSID, aucBCAddr); + } + + if (params->key) { + if (params->key_len > sizeof(rKey.aucKeyMaterial)) + return -EINVAL; + + kalMemCopy(rKey.aucKeyMaterial, params->key, + params->key_len); + if (rKey.ucCipher == CIPHER_SUITE_TKIP) { + kalMemCopy(tmp1, ¶ms->key[16], 8); + kalMemCopy(tmp2, ¶ms->key[24], 8); + kalMemCopy(&rKey.aucKeyMaterial[16], tmp2, 8); + kalMemCopy(&rKey.aucKeyMaterial[24], tmp1, 8); + } + } + + rKey.ucBssIdx = ucBssIndex; + + rKey.u4KeyLength = params->key_len; + rKey.u4Length = OFFSET_OF(struct PARAM_KEY, aucKeyMaterial) + + rKey.u4KeyLength; + + rStatus = kalIoctl(prGlueInfo, wlanoidSetAddKey, &rKey, + rKey.u4Length, FALSE, FALSE, TRUE, &u4BufLen); + + if (rStatus == WLAN_STATUS_SUCCESS) + i4Rslt = 0; + + return i4Rslt; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is responsible for getting key for specified STA + * + * @param + * + * @retval 0: successful + * others: failure + */ +/*----------------------------------------------------------------------------*/ +int +mtk_cfg80211_get_key(struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index, + bool pairwise, + const u8 *mac_addr, void *cookie, + void (*callback)(void *cookie, struct key_params *) + ) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + ASSERT(prGlueInfo); + +#if 1 + DBGLOG(INIT, INFO, "--> %s()\n", __func__); +#endif + + /* not implemented */ + + return -EINVAL; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is responsible for removing key for specified STA + * + * @param + * + * @retval 0: successful + * others: failure + */ +/*----------------------------------------------------------------------------*/ +int mtk_cfg80211_del_key(struct wiphy *wiphy, + struct net_device *ndev, u8 key_index, bool pairwise, + const u8 *mac_addr) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct BSS_INFO *prBssInfo; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + struct PARAM_REMOVE_KEY rRemoveKey; + uint32_t u4BufLen = 0; + int32_t i4Rslt = -EINVAL; + uint8_t ucBssIndex = 0; + uint32_t waitRet = 0; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + ASSERT(prGlueInfo); + + if (g_u4HaltFlag) { + DBGLOG_LIMITED(RSN, WARN, "wlan is halt, skip key deletion\n"); + return WLAN_STATUS_FAILURE; + } + + ucBssIndex = wlanGetBssIdx(ndev); + if (!IS_BSS_INDEX_VALID(ucBssIndex)) + return -EINVAL; + + if (mac_addr) { + DBGLOG(RSN, TRACE, + "keyIdx = %d pairwise = %d mac = " MACSTR "\n", + key_index, pairwise, MAC2STR(mac_addr)); + } else { + DBGLOG(RSN, TRACE, + "keyIdx = %d pairwise = %d null mac\n", + key_index, pairwise); + } + + kalMemZero(&rRemoveKey, sizeof(struct PARAM_REMOVE_KEY)); + rRemoveKey.u4KeyIndex = key_index; + rRemoveKey.u4Length = sizeof(struct PARAM_REMOVE_KEY); + if (mac_addr) { + COPY_MAC_ADDR(rRemoveKey.arBSSID, mac_addr); + rRemoveKey.u4KeyIndex |= BIT(30); + } + + if (prGlueInfo->prAdapter == NULL) + return i4Rslt; + + rRemoveKey.ucBssIdx = ucBssIndex; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prGlueInfo->prAdapter, + ucBssIndex); +#if CFG_SUPPORT_802_11W + /* if encrypted deauth frame is in process, pending remove key */ + if (IS_BSS_INDEX_AIS(prGlueInfo->prAdapter, ucBssIndex) + && prBssInfo->encryptedDeauthIsInProcess == TRUE) { + waitRet = wait_for_completion_timeout( + &prBssInfo->rDeauthComp, + MSEC_TO_JIFFIES(1000)); + if (!waitRet) { + DBGLOG(RSN, WARN, "timeout\n"); + prBssInfo->encryptedDeauthIsInProcess = FALSE; + } else + DBGLOG(RSN, INFO, "complete\n"); + } +#endif + rStatus = kalIoctl(prGlueInfo, wlanoidSetRemoveKey, &rRemoveKey, + rRemoveKey.u4Length, FALSE, FALSE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG_LIMITED(RSN, WARN, "remove key error:%x\n", rStatus); + else + i4Rslt = 0; + + return i4Rslt; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is responsible for setting default key on an interface + * + * @param + * + * @retval 0: successful + * others: failure + */ +/*----------------------------------------------------------------------------*/ +int +mtk_cfg80211_set_default_key(struct wiphy *wiphy, + struct net_device *ndev, u8 key_index, bool unicast, + bool multicast) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_DEFAULT_KEY rDefaultKey; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + int32_t i4Rst = -EINVAL; + uint32_t u4BufLen = 0; + u_int8_t fgDef = FALSE, fgMgtDef = FALSE; + uint8_t ucBssIndex = 0; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + ASSERT(prGlueInfo); + + ucBssIndex = wlanGetBssIdx(ndev); + if (!IS_BSS_INDEX_VALID(ucBssIndex)) + return -EINVAL; + + /* For STA, should wep set the default key !! */ + #if DBG + DBGLOG(RSN, INFO, + "keyIdx = %d unicast = %d multicast = %d\n", key_index, + unicast, multicast); +#endif + + rDefaultKey.ucKeyID = key_index; + rDefaultKey.ucUnicast = unicast; + rDefaultKey.ucMulticast = multicast; + if (rDefaultKey.ucUnicast && !rDefaultKey.ucMulticast) + return WLAN_STATUS_SUCCESS; + + if (rDefaultKey.ucUnicast && rDefaultKey.ucMulticast) + fgDef = TRUE; + + if (!rDefaultKey.ucUnicast && rDefaultKey.ucMulticast) + fgMgtDef = TRUE; + + rDefaultKey.ucBssIdx = ucBssIndex; + + rStatus = kalIoctl(prGlueInfo, wlanoidSetDefaultKey, &rDefaultKey, + sizeof(struct PARAM_DEFAULT_KEY), + FALSE, FALSE, TRUE, &u4BufLen); + if (rStatus == WLAN_STATUS_SUCCESS) + i4Rst = 0; + + return i4Rst; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is responsible for getting station information such as + * RSSI + * + * @param + * + * @retval 0: successful + * others: failure + */ +/*----------------------------------------------------------------------------*/ +#if KERNEL_VERSION(3, 16, 0) <= CFG80211_VERSION_CODE +int mtk_cfg80211_get_station(struct wiphy *wiphy, + struct net_device *ndev, const u8 *mac, + struct station_info *sinfo) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus; + uint8_t arBssid[PARAM_MAC_ADDR_LEN]; + uint32_t u4BufLen, u4Rate; + int32_t i4Rssi = 0; + struct PARAM_GET_STA_STATISTICS rQueryStaStatistics; + struct PARAM_LINK_SPEED_EX rLinkSpeed; + uint32_t u4TotalError; + struct net_device_stats *prDevStats; + uint8_t ucBssIndex = 0; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + ASSERT(prGlueInfo); + + ucBssIndex = wlanGetBssIdx(ndev); + if (!IS_BSS_INDEX_AIS(prGlueInfo->prAdapter, ucBssIndex)) + return -EINVAL; + + kalMemZero(arBssid, MAC_ADDR_LEN); + SET_IOCTL_BSSIDX(prGlueInfo->prAdapter, ucBssIndex); + wlanQueryInformation(prGlueInfo->prAdapter, wlanoidQueryBssid, + &arBssid[0], sizeof(arBssid), &u4BufLen); + + /* 1. check input MAC address */ + /* On Android O, this might be wlan0 address */ + if (UNEQUAL_MAC_ADDR(arBssid, mac) + && UNEQUAL_MAC_ADDR( + prGlueInfo->prAdapter->rWifiVar.aucMacAddress, mac)) { + /* wrong MAC address */ + DBGLOG(REQ, WARN, + "incorrect BSSID: [" MACSTR + "] currently connected BSSID[" + MACSTR "]\n", + MAC2STR(mac), MAC2STR(arBssid)); + return -ENOENT; + } + + /* 2. fill TX rate */ + if (kalGetMediaStateIndicated(prGlueInfo, ucBssIndex) != + MEDIA_STATE_CONNECTED) { + /* not connected */ + DBGLOG(REQ, WARN, "not yet connected\n"); + return 0; + } + +#if defined(CFG_REPORT_MAX_TX_RATE) && (CFG_REPORT_MAX_TX_RATE == 1) + rStatus = kalIoctlByBssIdx(prGlueInfo, + wlanoidQueryMaxLinkSpeed, &rLinkSpeed, + sizeof(rLinkSpeed), TRUE, FALSE, FALSE, + &u4BufLen, ucBssIndex); +#else + rStatus = kalIoctlByBssIdx(prGlueInfo, + wlanoidQueryLinkSpeedEx, &rLinkSpeed, + sizeof(rLinkSpeed), TRUE, FALSE, FALSE, + &u4BufLen, ucBssIndex); +#endif /* CFG_REPORT_MAX_TX_RATE */ + if (ucBssIndex < BSSID_NUM) + u4Rate = rLinkSpeed.rLq[ucBssIndex].u2LinkSpeed; + +#if KERNEL_VERSION(4, 0, 0) <= CFG80211_VERSION_CODE + sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE); +#else + sinfo->filled |= STATION_INFO_TX_BITRATE; +#endif + if ((rStatus != WLAN_STATUS_SUCCESS) || (u4Rate == 0)) { + /* unable to retrieve link speed */ + DBGLOG(REQ, WARN, "last link speed\n"); + sinfo->txrate.legacy = prGlueInfo->u4LinkSpeedCache[ucBssIndex]; + } else { + /* convert from 100bps to 100kbps */ + sinfo->txrate.legacy = u4Rate / 1000; + prGlueInfo->u4LinkSpeedCache[ucBssIndex] = u4Rate / 1000; + } + + /* 3. fill RSSI */ + rStatus = kalIoctlByBssIdx(prGlueInfo, + wlanoidQueryRssi, + &rLinkSpeed, sizeof(rLinkSpeed), + TRUE, FALSE, FALSE, + &u4BufLen, ucBssIndex); + if (IS_BSS_INDEX_VALID(ucBssIndex)) + i4Rssi = rLinkSpeed.rLq[ucBssIndex].cRssi; +#if KERNEL_VERSION(4, 0, 0) <= CFG80211_VERSION_CODE + sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL); +#else + sinfo->filled |= STATION_INFO_SIGNAL; +#endif + + if (rStatus != WLAN_STATUS_SUCCESS || i4Rssi == 0) { + DBGLOG(REQ, WARN, + "Query RSSI failed, use last RSSI %d\n", + prGlueInfo->i4RssiCache[ucBssIndex]); + sinfo->signal = prGlueInfo->i4RssiCache[ucBssIndex] ? + prGlueInfo->i4RssiCache[ucBssIndex] : + PARAM_WHQL_RSSI_INITIAL_DBM; + } else if (i4Rssi == PARAM_WHQL_RSSI_MIN_DBM || + i4Rssi == PARAM_WHQL_RSSI_MAX_DBM) { + DBGLOG(REQ, WARN, + "RSSI abnormal, use last RSSI %d\n", + prGlueInfo->i4RssiCache[ucBssIndex]); + sinfo->signal = prGlueInfo->i4RssiCache[ucBssIndex] ? + prGlueInfo->i4RssiCache[ucBssIndex] : i4Rssi; + } else { + sinfo->signal = i4Rssi; /* dBm */ + prGlueInfo->i4RssiCache[ucBssIndex] = i4Rssi; + } + + /* Get statistics from net_dev */ + prDevStats = (struct net_device_stats *)kalGetStats(ndev); + + if (prDevStats) { + /* 4. fill RX_PACKETS */ +#if KERNEL_VERSION(4, 0, 0) <= CFG80211_VERSION_CODE + sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS); + sinfo->filled |= BIT(NL80211_STA_INFO_RX_BYTES64); +#else + sinfo->filled |= STATION_INFO_RX_PACKETS; + sinfo->filled |= NL80211_STA_INFO_RX_BYTES64; +#endif + sinfo->rx_packets = prDevStats->rx_packets; + sinfo->rx_bytes = prDevStats->rx_bytes; + + /* 5. fill TX_PACKETS */ +#if KERNEL_VERSION(4, 0, 0) <= CFG80211_VERSION_CODE + sinfo->filled |= BIT(NL80211_STA_INFO_TX_PACKETS); + sinfo->filled |= BIT(NL80211_STA_INFO_TX_BYTES64); +#else + sinfo->filled |= STATION_INFO_TX_PACKETS; + sinfo->filled |= NL80211_STA_INFO_TX_BYTES64; +#endif + sinfo->tx_packets = prDevStats->tx_packets; + sinfo->tx_bytes = prDevStats->tx_bytes; + + /* 6. fill TX_FAILED */ + kalMemZero(&rQueryStaStatistics, + sizeof(rQueryStaStatistics)); + COPY_MAC_ADDR(rQueryStaStatistics.aucMacAddr, arBssid); + rQueryStaStatistics.ucReadClear = TRUE; + + rStatus = kalIoctl(prGlueInfo, wlanoidQueryStaStatistics, + &rQueryStaStatistics, + sizeof(rQueryStaStatistics), + TRUE, FALSE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, WARN, + "link speed=%u, rssi=%d, unable to retrieve link speed,status=%u\n", + sinfo->txrate.legacy, sinfo->signal, rStatus); + } else { + DBGLOG(REQ, INFO, + "link speed=%u, rssi=%d, BSSID:[" MACSTR + "], TxFail=%u, TxTimeOut=%u, TxOK=%u, RxOK=%u\n", + sinfo->txrate.legacy, sinfo->signal, + MAC2STR(arBssid), + rQueryStaStatistics.u4TxFailCount, + rQueryStaStatistics.u4TxLifeTimeoutCount, + sinfo->tx_packets, sinfo->rx_packets); + + u4TotalError = rQueryStaStatistics.u4TxFailCount + + rQueryStaStatistics.u4TxLifeTimeoutCount; + prDevStats->tx_errors += u4TotalError; + } +#if KERNEL_VERSION(4, 0, 0) <= CFG80211_VERSION_CODE + sinfo->filled |= BIT(NL80211_STA_INFO_TX_FAILED); +#else + sinfo->filled |= STATION_INFO_TX_FAILED; +#endif + sinfo->tx_failed = prDevStats->tx_errors; + } + + return 0; +} +#else +int mtk_cfg80211_get_station(struct wiphy *wiphy, + struct net_device *ndev, u8 *mac, + struct station_info *sinfo) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus; + uint8_t arBssid[PARAM_MAC_ADDR_LEN]; + uint32_t u4BufLen, u4Rate; + int32_t i4Rssi; + struct PARAM_GET_STA_STATISTICS rQueryStaStatistics; + struct PARAM_LINK_SPEED_EX rLinkSpeed; + uint32_t u4TotalError; + struct net_device_stats *prDevStats; + uint8_t ucBssIndex = 0; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + ASSERT(prGlueInfo); + + ucBssIndex = wlanGetBssIdx(ndev); + if (!IS_BSS_INDEX_AIS(prGlueInfo->prAdapter, ucBssIndex)) + return -EINVAL; + + kalMemZero(arBssid, MAC_ADDR_LEN); + SET_IOCTL_BSSIDX(prGlueInfo->prAdapter, ucBssIndex); + wlanQueryInformation(prGlueInfo->prAdapter, wlanoidQueryBssid, + &arBssid[0], sizeof(arBssid), &u4BufLen); + + /* 1. check BSSID */ + if (UNEQUAL_MAC_ADDR(arBssid, mac)) { + /* wrong MAC address */ + DBGLOG(REQ, WARN, + "incorrect BSSID: [" MACSTR + "] currently connected BSSID[" + MACSTR "]\n", + MAC2STR(mac), MAC2STR(arBssid)); + return -ENOENT; + } + + /* 2. fill TX rate */ + if (kalGetMediaStateIndicated(prGlueInfo, ucBssIndex) != + MEDIA_STATE_CONNECTED) { + /* not connected */ + DBGLOG(REQ, WARN, "not yet connected\n"); + } else { +#if defined(CFG_REPORT_MAX_TX_RATE) && (CFG_REPORT_MAX_TX_RATE == 1) + rStatus = kalIoctlByBssIdx(prGlueInfo, wlanoidQueryMaxLinkSpeed, + &u4Rate, sizeof(u4Rate), TRUE, FALSE, FALSE, + &u4BufLen, + ucBssIndex); +#else + rStatus = kalIoctlByBssIdx(prGlueInfo, + wlanoidQueryLinkSpeedEx, + &rLinkSpeed, sizeof(rLinkSpeed), + TRUE, FALSE, FALSE, + &u4BufLen, ucBssIndex); + if (ucBssIndex < BSSID_NUM) + u4Rate = rLinkSpeed.rLq[ucBssIndex].u2LinkSpeed; +#endif /* CFG_REPORT_MAX_TX_RATE */ + + sinfo->filled |= STATION_INFO_TX_BITRATE; + + if ((rStatus != WLAN_STATUS_SUCCESS) || (u4Rate == 0)) { + /* unable to retrieve link speed */ + DBGLOG(REQ, WARN, "last link speed\n"); + sinfo->txrate.legacy = + prGlueInfo->u4LinkSpeedCache[ucBssIndex]; + } else { + /* convert from 100bps to 100kbps */ + sinfo->txrate.legacy = u4Rate / 1000; + prGlueInfo->u4LinkSpeedCache[ucBssIndex] = + u4Rate / 1000; + } + } + + /* 3. fill RSSI */ + if (kalGetMediaStateIndicated(prGlueInfo, ucBssIndex) != + MEDIA_STATE_CONNECTED) { + /* not connected */ + DBGLOG(REQ, WARN, "not yet connected\n"); + } else { + rStatus = kalIoctlByBssIdx(prGlueInfo, + wlanoidQueryRssi, + &rLinkSpeed, sizeof(rLinkSpeed), + TRUE, FALSE, FALSE, + &u4BufLen, ucBssIndex); + if (IS_BSS_INDEX_VALID(ucBssIndex)) + i4Rssi = rLinkSpeed.rLq[ucBssIndex].cRssi; + + sinfo->filled |= STATION_INFO_SIGNAL; + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, WARN, + "Query RSSI failed, use last RSSI %d\n", + prGlueInfo->i4RssiCache[ucBssIndex]); + sinfo->signal = prGlueInfo->i4RssiCache[ucBssIndex] ? + prGlueInfo->i4RssiCache[ucBssIndex] : + PARAM_WHQL_RSSI_INITIAL_DBM; + } else if (i4Rssi == PARAM_WHQL_RSSI_MIN_DBM || + i4Rssi == PARAM_WHQL_RSSI_MAX_DBM) { + DBGLOG(REQ, WARN, + "RSSI abnormal, use last RSSI %d\n", + prGlueInfo->i4RssiCache[ucBssIndex]); + sinfo->signal = prGlueInfo->i4RssiCache[ucBssIndex] ? + prGlueInfo->i4RssiCache[ucBssIndex] : i4Rssi; + } else { + sinfo->signal = i4Rssi; /* dBm */ + prGlueInfo->i4RssiCache[ucBssIndex] = i4Rssi; + } + } + + /* Get statistics from net_dev */ + prDevStats = (struct net_device_stats *)kalGetStats(ndev); + if (prDevStats) { + /* 4. fill RX_PACKETS */ + sinfo->filled |= STATION_INFO_RX_PACKETS; + sinfo->rx_packets = prDevStats->rx_packets; + + /* 5. fill TX_PACKETS */ + sinfo->filled |= STATION_INFO_TX_PACKETS; + sinfo->tx_packets = prDevStats->tx_packets; + + /* 6. fill TX_FAILED */ + kalMemZero(&rQueryStaStatistics, + sizeof(rQueryStaStatistics)); + COPY_MAC_ADDR(rQueryStaStatistics.aucMacAddr, arBssid); + rQueryStaStatistics.ucReadClear = TRUE; + + rStatus = kalIoctl(prGlueInfo, wlanoidQueryStaStatistics, + &rQueryStaStatistics, + sizeof(rQueryStaStatistics), + TRUE, FALSE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, WARN, + "link speed=%u, rssi=%d, unable to get sta statistics: status=%u\n", + sinfo->txrate.legacy, sinfo->signal, rStatus); + } else { + DBGLOG(REQ, INFO, + "link speed=%u, rssi=%d, BSSID=[" MACSTR + "], TxFailCount=%d, LifeTimeOut=%d\n", + sinfo->txrate.legacy, sinfo->signal, + MAC2STR(arBssid), + rQueryStaStatistics.u4TxFailCount, + rQueryStaStatistics.u4TxLifeTimeoutCount); + + u4TotalError = rQueryStaStatistics.u4TxFailCount + + rQueryStaStatistics.u4TxLifeTimeoutCount; + prDevStats->tx_errors += u4TotalError; + } + sinfo->filled |= STATION_INFO_TX_FAILED; + sinfo->tx_failed = prDevStats->tx_errors; + } + + return 0; +} +#endif +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is responsible for getting statistics for Link layer + * statistics + * + * @param + * + * @retval 0: successful + * others: failure + */ +/*----------------------------------------------------------------------------*/ +int mtk_cfg80211_get_link_statistics(struct wiphy *wiphy, + struct net_device *ndev, u8 *mac, + struct station_info *sinfo) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus; + uint8_t arBssid[PARAM_MAC_ADDR_LEN]; + uint32_t u4BufLen; + struct PARAM_LINK_SPEED_EX rLinkSpeed; + struct PARAM_GET_STA_STATISTICS rQueryStaStatistics; + struct PARAM_GET_BSS_STATISTICS rQueryBssStatistics; + struct net_device_stats *prDevStats; + uint8_t ucBssIndex = 0; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + ASSERT(prGlueInfo); + + ucBssIndex = wlanGetBssIdx(ndev); + if (!IS_BSS_INDEX_AIS(prGlueInfo->prAdapter, ucBssIndex)) + return -EINVAL; + + kalMemZero(arBssid, MAC_ADDR_LEN); + SET_IOCTL_BSSIDX(prGlueInfo->prAdapter, ucBssIndex); + wlanQueryInformation(prGlueInfo->prAdapter, wlanoidQueryBssid, + &arBssid[0], sizeof(arBssid), &u4BufLen); + + /* 1. check BSSID */ + if (UNEQUAL_MAC_ADDR(arBssid, mac)) { + /* wrong MAC address */ + DBGLOG(REQ, WARN, + "incorrect BSSID: [" MACSTR + "] currently connected BSSID[" + MACSTR "]\n", + MAC2STR(mac), MAC2STR(arBssid)); + return -ENOENT; + } + + /* 2. fill RSSI */ + if (kalGetMediaStateIndicated(prGlueInfo, ucBssIndex) != + MEDIA_STATE_CONNECTED) { + /* not connected */ + DBGLOG(REQ, WARN, "not yet connected\n"); + } else { + rStatus = kalIoctlByBssIdx + (prGlueInfo, + wlanoidQueryRssi, + &rLinkSpeed, sizeof(rLinkSpeed), + TRUE, FALSE, FALSE, + &u4BufLen, ucBssIndex); + + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(REQ, WARN, "unable to retrieve rssi\n"); + } + + /* Get statistics from net_dev */ + prDevStats = (struct net_device_stats *)kalGetStats(ndev); + + /*3. get link layer statistics from Driver and FW */ + if (prDevStats) { + /* 3.1 get per-STA link statistics */ + kalMemZero(&rQueryStaStatistics, + sizeof(rQueryStaStatistics)); + COPY_MAC_ADDR(rQueryStaStatistics.aucMacAddr, arBssid); + rQueryStaStatistics.ucLlsReadClear = + FALSE; /* dont clear for get BSS statistic */ + + rStatus = kalIoctl(prGlueInfo, wlanoidQueryStaStatistics, + &rQueryStaStatistics, + sizeof(rQueryStaStatistics), + TRUE, FALSE, TRUE, &u4BufLen); + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(REQ, WARN, + "unable to retrieve per-STA link statistics\n"); + + /*3.2 get per-BSS link statistics */ + if (rStatus == WLAN_STATUS_SUCCESS) { + kalMemZero(&rQueryBssStatistics, + sizeof(rQueryBssStatistics)); + rQueryBssStatistics.ucBssIndex = ucBssIndex; + + rStatus = kalIoctl(prGlueInfo, + wlanoidQueryBssStatistics, + &rQueryBssStatistics, + sizeof(rQueryBssStatistics), + TRUE, FALSE, TRUE, &u4BufLen); + } else { + DBGLOG(REQ, WARN, + "unable to retrieve per-BSS link statistics\n"); + } + + } + + return 0; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is responsible for requesting to do a scan + * + * @param + * + * @retval 0: successful + * others: failure + */ +/*----------------------------------------------------------------------------*/ +int mtk_cfg80211_scan(struct wiphy *wiphy, + struct cfg80211_scan_request *request) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus; + uint32_t i, j, u4BufLen; + struct PARAM_SCAN_REQUEST_ADV *prScanRequest; + uint32_t num_ssid = 0; + uint32_t old_num_ssid = 0; + uint32_t u4ValidIdx = 0; + uint32_t wildcard_flag = 0; +#if (CFG_SUPPORT_QA_TOOL == 1) || (CFG_SUPPORT_LOWLATENCY_MODE == 1) + struct ADAPTER *prAdapter = NULL; +#endif + uint8_t ucBssIndex = 0; + GLUE_SPIN_LOCK_DECLARATION(); + + if (kalIsResetting()) + return -EBUSY; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + if (!prGlueInfo) { + DBGLOG(REQ, ERROR, "prGlueInfo is NULL"); + return -EINVAL; + } + + ucBssIndex = wlanGetBssIdx(request->wdev->netdev); + if (!IS_BSS_INDEX_AIS(prGlueInfo->prAdapter, ucBssIndex)) + return -EINVAL; + +#if (CFG_SUPPORT_QA_TOOL == 1) || (CFG_SUPPORT_LOWLATENCY_MODE == 1) + prAdapter = prGlueInfo->prAdapter; + if (prGlueInfo->prAdapter == NULL) { + DBGLOG(REQ, ERROR, "prGlueInfo->prAdapter is NULL"); + return -EINVAL; + } +#endif + + if (wlanIsChipAssert(prGlueInfo->prAdapter)) + return -EBUSY; + +#if CFG_SUPPORT_QA_TOOL + if (prAdapter->fgTestMode) { + DBGLOG(REQ, ERROR, + "directly return scan done, TestMode running\n"); + + GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); + kalCfg80211ScanDone(request, FALSE); + GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); + return 0; + } + if (prAdapter->rIcapInfo.eIcapState != ICAP_STATE_INIT) { + DBGLOG(REQ, ERROR, "skip scan, ICAP In State(%d)\n", + prAdapter->rIcapInfo.eIcapState); + return -EBUSY; + } +#endif + + kalScanReqLog(request); + + /* check if there is any pending scan/sched_scan not yet finished */ + if (prGlueInfo->prScanRequest != NULL) { + DBGLOG(REQ, ERROR, "prGlueInfo->prScanRequest != NULL\n"); + return -EBUSY; + } + +#if CFG_SUPPORT_LOWLATENCY_MODE + if (!prGlueInfo->prAdapter->fgEnCfg80211Scan + && MEDIA_STATE_CONNECTED + == kalGetMediaStateIndicated(prGlueInfo, ucBssIndex)) { + DBGLOG(REQ, INFO, + "mtk_cfg80211_scan LowLatency reject scan\n"); + return -EBUSY; + } +#endif /* CFG_SUPPORT_LOWLATENCY_MODE */ + +#if CFG_SUPPORT_SCAN_CACHE_RESULT + prGlueInfo->scanCache.prGlueInfo = prGlueInfo; + prGlueInfo->scanCache.prRequest = request; + prGlueInfo->scanCache.n_channels = (uint32_t) request->n_channels; + prGlueInfo->scanCache.ucBssIndex = ucBssIndex; + prGlueInfo->scanCache.u4Flags = request->flags; + if (isScanCacheDone(&prGlueInfo->scanCache) == TRUE) + return 0; +#endif /* CFG_SUPPORT_SCAN_CACHE_RESULT */ + + prScanRequest = kalMemAlloc(sizeof(struct PARAM_SCAN_REQUEST_ADV), + VIR_MEM_TYPE); + if (prScanRequest == NULL) { + DBGLOG(REQ, ERROR, "alloc scan request fail\n"); + return -ENOMEM; + + } + kalMemZero(prScanRequest, + sizeof(struct PARAM_SCAN_REQUEST_ADV)); + + if (request->n_ssids == 0) { + prScanRequest->u4SsidNum = 0; + prScanRequest->ucScanType = SCAN_TYPE_PASSIVE_SCAN; + } else if ((request->ssids) && (request->n_ssids > 0) + && (request->n_ssids <= (SCN_SSID_MAX_NUM + 1))) { + num_ssid = (uint32_t)request->n_ssids; + old_num_ssid = (uint32_t)request->n_ssids; + u4ValidIdx = 0; + for (i = 0; i < request->n_ssids; i++) { + if ((request->ssids[i].ssid[0] == 0) + || (request->ssids[i].ssid_len == 0)) { + /* remove if this is a wildcard scan */ + num_ssid--; + wildcard_flag |= (1 << i); + DBGLOG(REQ, TRACE, "i=%d, wildcard scan\n", i); + continue; + } + COPY_SSID(prScanRequest->rSsid[u4ValidIdx].aucSsid, + prScanRequest->rSsid[u4ValidIdx].u4SsidLen, + request->ssids[i].ssid, + request->ssids[i].ssid_len); + if (prScanRequest->rSsid[u4ValidIdx].u4SsidLen > + ELEM_MAX_LEN_SSID) { + prScanRequest->rSsid[u4ValidIdx].u4SsidLen = + ELEM_MAX_LEN_SSID; + } + DBGLOG(REQ, TRACE, + "i=%d, u4ValidIdx=%d, Ssid=%s, SsidLen=%d\n", + i, u4ValidIdx, + HIDE(prScanRequest->rSsid[u4ValidIdx].aucSsid), + prScanRequest->rSsid[u4ValidIdx].u4SsidLen); + + u4ValidIdx++; + if (u4ValidIdx == SCN_SSID_MAX_NUM) { + DBGLOG(REQ, TRACE, "SCN_SSID_MAX_NUM\n"); + break; + } + } + /* real SSID number to firmware */ + prScanRequest->u4SsidNum = u4ValidIdx; + prScanRequest->ucScanType = SCAN_TYPE_ACTIVE_SCAN; + } else { + DBGLOG(REQ, ERROR, "request->n_ssids:%d\n", + request->n_ssids); + kalMemFree(prScanRequest, + sizeof(struct PARAM_SCAN_REQUEST_ADV), VIR_MEM_TYPE); + return -EINVAL; + } + + /* Set channel info */ + if (request->n_channels > MAXIMUM_OPERATION_CHANNEL_LIST) { + prScanRequest->u4ChannelNum = 0; + DBGLOG(REQ, INFO, + "Channel list %u exceed maximum support.\n", + request->n_channels); + } else { + j = 0; + for (i = 0; i < request->n_channels; i++) { + uint32_t u4channel = + nicFreq2ChannelNum(request->channels[i]->center_freq * + 1000); + if (u4channel == 0) { + DBGLOG(REQ, WARN, "Wrong Channel[%d] freq=%u\n", + i, request->channels[i]->center_freq); + continue; + } + prScanRequest->arChannel[j].ucChannelNum = u4channel; + switch ((request->channels[i])->band) { + case KAL_BAND_2GHZ: + prScanRequest->arChannel[j].eBand = BAND_2G4; + break; + case KAL_BAND_5GHZ: + prScanRequest->arChannel[j].eBand = BAND_5G; + break; + default: + DBGLOG(REQ, WARN, "UNKNOWN Band %d(chnl=%u)\n", + request->channels[i]->band, + u4channel); + prScanRequest->arChannel[j].eBand = BAND_NULL; + break; + } + j++; + } + prScanRequest->u4ChannelNum = j; + } + + if (kalScanParseRandomMac(request->wdev->netdev, + request, prScanRequest->aucRandomMac)) { + prScanRequest->ucScnFuncMask |= ENUM_SCN_RANDOM_MAC_EN; + } + + if (request->ie_len > 0) { + prScanRequest->u4IELength = request->ie_len; + prScanRequest->pucIE = (uint8_t *) (request->ie); + } + +#define TEMP_LOG_TEMPLATE "n_ssid=(%u->%u) n_channel(%u==>%u) " \ + "wildcard=0x%X flag=0x%x random_mac=" MACSTR "\n" + DBGLOG(REQ, INFO, TEMP_LOG_TEMPLATE, + request->n_ssids, num_ssid, request->n_channels, + prScanRequest->u4ChannelNum, wildcard_flag, + request->flags, + MAC2STR(prScanRequest->aucRandomMac)); +#undef TEMP_LOG_TEMPLATE + + prScanRequest->ucBssIndex = ucBssIndex; + prScanRequest->u4Flags = request->flags; + prGlueInfo->prScanRequest = request; + rStatus = kalIoctl(prGlueInfo, wlanoidSetBssidListScanAdv, + prScanRequest, sizeof(struct PARAM_SCAN_REQUEST_ADV), + FALSE, FALSE, FALSE, &u4BufLen); + + kalMemFree(prScanRequest, + sizeof(struct PARAM_SCAN_REQUEST_ADV), VIR_MEM_TYPE); + if (rStatus != WLAN_STATUS_SUCCESS) { + prGlueInfo->prScanRequest = NULL; + DBGLOG(REQ, WARN, "scan error:%x\n", rStatus); + return -EINVAL; + } + + return 0; +} +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is responsible for abort an ongoing scan. The driver + * shall indicate the status of the scan through cfg80211_scan_done() + * + * @param wiphy - pointer of wireless hardware description + * wdev - pointer of wireless device state + * + */ +/*----------------------------------------------------------------------------*/ +void mtk_cfg80211_abort_scan(struct wiphy *wiphy, + struct wireless_dev *wdev) +{ + uint32_t u4SetInfoLen = 0; + uint32_t rStatus; + struct GLUE_INFO *prGlueInfo = NULL; + uint8_t ucBssIndex = 0; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + ASSERT(prGlueInfo); + + ucBssIndex = wlanGetBssIdx(wdev->netdev); + if (!IS_BSS_INDEX_VALID(ucBssIndex)) + return; + + scanlog_dbg(LOG_SCAN_ABORT_REQ_K2D, INFO, "mtk_cfg80211_abort_scan\n"); + + rStatus = kalIoctlByBssIdx(prGlueInfo, + wlanoidAbortScan, + NULL, 1, FALSE, FALSE, TRUE, &u4SetInfoLen, + ucBssIndex); + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(REQ, ERROR, "wlanoidAbortScan fail 0x%x\n", rStatus); +} + +static uint8_t wepBuf[48]; + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is responsible for requesting to connect to + * the ESS with the specified parameters + * + * @param + * + * @retval 0: successful + * others: failure + */ +/*----------------------------------------------------------------------------*/ +int mtk_cfg80211_connect(struct wiphy *wiphy, + struct net_device *ndev, + struct cfg80211_connect_params *sme) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus; + uint32_t u4BufLen; + enum ENUM_WEP_STATUS eEncStatus; + enum ENUM_PARAM_AUTH_MODE eAuthMode; + uint32_t cipher; + struct PARAM_CONNECT rNewSsid; + struct PARAM_OP_MODE rOpMode; + uint32_t i, u4AkmSuite = 0; + struct DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY + *prEntry; + struct CONNECTION_SETTINGS *prConnSettings = NULL; +#if CFG_SUPPORT_REPLAY_DETECTION + struct GL_DETECT_REPLAY_INFO *prDetRplyInfo = NULL; +#endif + struct GL_WPA_INFO *prWpaInfo; + struct IEEE_802_11_MIB *prMib; +#if CFG_SUPPORT_PASSPOINT + struct HS20_INFO *prHS20Info; +#endif + uint8_t ucBssIndex = 0; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + ASSERT(prGlueInfo); + + ucBssIndex = wlanGetBssIdx(ndev); + if (!IS_BSS_INDEX_AIS(prGlueInfo->prAdapter, ucBssIndex)) + return -EINVAL; + + DBGLOG(REQ, INFO, "[wlan%d] mtk_cfg80211_connect %p %zu\n", + ucBssIndex, sme->ie, sme->ie_len); + + prConnSettings = + aisGetConnSettings(prGlueInfo->prAdapter, + ucBssIndex); + if (prConnSettings->eOPMode > + NET_TYPE_AUTO_SWITCH) + rOpMode.eOpMode = NET_TYPE_AUTO_SWITCH; + else + rOpMode.eOpMode = prConnSettings->eOPMode; + rOpMode.ucBssIdx = ucBssIndex; + rStatus = kalIoctl(prGlueInfo, wlanoidSetInfrastructureMode, + (void *)&rOpMode, sizeof(struct PARAM_OP_MODE), + FALSE, FALSE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, INFO, + "wlanoidSetInfrastructureMode fail 0x%x\n", rStatus); + return -EFAULT; + } + + /* after set operation mode, key table are cleared */ + +#if CFG_SUPPORT_REPLAY_DETECTION + /* reset Detect replay information */ + prDetRplyInfo = aisGetDetRplyInfo(prGlueInfo->prAdapter, + ucBssIndex); + kalMemZero(prDetRplyInfo, sizeof(struct GL_DETECT_REPLAY_INFO)); +#endif + + prWpaInfo = aisGetWpaInfo(prGlueInfo->prAdapter, + ucBssIndex); + /* <1> Reset WPA info */ + prWpaInfo->u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED; + prWpaInfo->u4KeyMgmt = 0; + prWpaInfo->u4CipherGroup = IW_AUTH_CIPHER_NONE; + prWpaInfo->u4CipherPairwise = IW_AUTH_CIPHER_NONE; + prWpaInfo->u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM; + prWpaInfo->fgPrivacyInvoke = FALSE; +#if CFG_SUPPORT_802_11W + prWpaInfo->u4Mfp = IW_AUTH_MFP_DISABLED; + prWpaInfo->ucRSNMfpCap = RSN_AUTH_MFP_DISABLED; +#endif + + if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) + prWpaInfo->u4WpaVersion = IW_AUTH_WPA_VERSION_WPA; + else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) + prWpaInfo->u4WpaVersion = + IW_AUTH_WPA_VERSION_WPA2; + else + prWpaInfo->u4WpaVersion = + IW_AUTH_WPA_VERSION_DISABLED; + + DBGLOG(REQ, INFO, + "sme->auth_type=%x, sme->crypto.wpa_versions=%x", + sme->auth_type, sme->crypto.wpa_versions); + + switch (sme->auth_type) { + case NL80211_AUTHTYPE_OPEN_SYSTEM: + prWpaInfo->u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM; + break; + case NL80211_AUTHTYPE_SHARED_KEY: + prWpaInfo->u4AuthAlg = IW_AUTH_ALG_SHARED_KEY; + break; + case NL80211_AUTHTYPE_FT: + prWpaInfo->u4AuthAlg = IW_AUTH_ALG_FT; + break; + case NL80211_AUTHTYPE_SAE: + prWpaInfo->u4AuthAlg = IW_AUTH_ALG_SAE; + /* To prevent FWKs asks connect without AKM Suite */ + eAuthMode = AUTH_MODE_WPA3_SAE; + u4AkmSuite = RSN_AKM_SUITE_SAE; + break; + default: + prWpaInfo->u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM | + IW_AUTH_ALG_SHARED_KEY; + break; + } + + if (sme->crypto.n_ciphers_pairwise) { + DBGLOG(RSN, INFO, "[wlan] cipher pairwise (%x)\n", + sme->crypto.ciphers_pairwise[0]); + + prConnSettings->rRsnInfo + .au4PairwiseKeyCipherSuite[0] = sme->crypto.ciphers_pairwise[0]; + switch (sme->crypto.ciphers_pairwise[0]) { + case WLAN_CIPHER_SUITE_WEP40: + prWpaInfo->u4CipherPairwise = + IW_AUTH_CIPHER_WEP40; + break; + case WLAN_CIPHER_SUITE_WEP104: + prWpaInfo->u4CipherPairwise = + IW_AUTH_CIPHER_WEP104; + break; + case WLAN_CIPHER_SUITE_TKIP: + prWpaInfo->u4CipherPairwise = + IW_AUTH_CIPHER_TKIP; + break; + case WLAN_CIPHER_SUITE_CCMP: + prWpaInfo->u4CipherPairwise = + IW_AUTH_CIPHER_CCMP; + break; + case WLAN_CIPHER_SUITE_AES_CMAC: + prWpaInfo->u4CipherPairwise = + IW_AUTH_CIPHER_CCMP; + break; + case WLAN_CIPHER_SUITE_BIP_GMAC_256: + prWpaInfo->u4CipherPairwise = + IW_AUTH_CIPHER_GCMP256; + break; + case WLAN_CIPHER_SUITE_GCMP_256: + prWpaInfo->u4CipherPairwise = + IW_AUTH_CIPHER_GCMP256; + break; + case WLAN_CIPHER_SUITE_NO_GROUP_ADDR: + DBGLOG(REQ, INFO, "WLAN_CIPHER_SUITE_NO_GROUP_ADDR\n"); + break; + default: + DBGLOG(REQ, WARN, "invalid cipher pairwise (%d)\n", + sme->crypto.ciphers_pairwise[0]); + return -EINVAL; + } + } + + if (sme->crypto.cipher_group) { + prConnSettings->rRsnInfo + .u4GroupKeyCipherSuite = sme->crypto.cipher_group; + switch (sme->crypto.cipher_group) { + case WLAN_CIPHER_SUITE_WEP40: + prWpaInfo->u4CipherGroup = + IW_AUTH_CIPHER_WEP40; + break; + case WLAN_CIPHER_SUITE_WEP104: + prWpaInfo->u4CipherGroup = + IW_AUTH_CIPHER_WEP104; + break; + case WLAN_CIPHER_SUITE_TKIP: + prWpaInfo->u4CipherGroup = + IW_AUTH_CIPHER_TKIP; + break; + case WLAN_CIPHER_SUITE_CCMP: + prWpaInfo->u4CipherGroup = + IW_AUTH_CIPHER_CCMP; + break; + case WLAN_CIPHER_SUITE_AES_CMAC: + prWpaInfo->u4CipherGroup = + IW_AUTH_CIPHER_CCMP; + break; + case WLAN_CIPHER_SUITE_BIP_GMAC_256: + prWpaInfo->u4CipherGroup = + IW_AUTH_CIPHER_GCMP256; + break; + case WLAN_CIPHER_SUITE_GCMP_256: + prWpaInfo->u4CipherGroup = + IW_AUTH_CIPHER_GCMP256; + break; + case WLAN_CIPHER_SUITE_NO_GROUP_ADDR: + break; + default: + DBGLOG(REQ, WARN, "invalid cipher group (%d)\n", + sme->crypto.cipher_group); + return -EINVAL; + } + } + + if (sme->crypto.n_akm_suites) { + DBGLOG(REQ, INFO, "n_akm_suites=%x, akm_suites=%x", + sme->crypto.n_akm_suites, + sme->crypto.akm_suites[0]); + prConnSettings->rRsnInfo + .au4AuthKeyMgtSuite[0] = sme->crypto.akm_suites[0]; + if (prWpaInfo->u4WpaVersion == + IW_AUTH_WPA_VERSION_WPA) { + switch (sme->crypto.akm_suites[0]) { + case WLAN_AKM_SUITE_8021X: + eAuthMode = AUTH_MODE_WPA; + u4AkmSuite = WPA_AKM_SUITE_802_1X; + break; + case WLAN_AKM_SUITE_PSK: + eAuthMode = AUTH_MODE_WPA_PSK; + u4AkmSuite = WPA_AKM_SUITE_PSK; + break; + default: + DBGLOG(REQ, WARN, "invalid Akm Suite (%08x)\n", + sme->crypto.akm_suites[0]); + return -EINVAL; + } + } else if (prWpaInfo->u4WpaVersion == + IW_AUTH_WPA_VERSION_WPA2) { + switch (sme->crypto.akm_suites[0]) { + case WLAN_AKM_SUITE_8021X: + eAuthMode = AUTH_MODE_WPA2; + u4AkmSuite = RSN_AKM_SUITE_802_1X; + break; + case WLAN_AKM_SUITE_PSK: + eAuthMode = AUTH_MODE_WPA2_PSK; + u4AkmSuite = RSN_AKM_SUITE_PSK; + break; +#if CFG_SUPPORT_802_11R + case WLAN_AKM_SUITE_FT_8021X: + eAuthMode = AUTH_MODE_WPA2_FT; + u4AkmSuite = RSN_AKM_SUITE_FT_802_1X; + break; + case WLAN_AKM_SUITE_FT_PSK: + eAuthMode = AUTH_MODE_WPA2_FT_PSK; + u4AkmSuite = RSN_AKM_SUITE_FT_PSK; + break; +#endif +#if CFG_SUPPORT_802_11W + /* Notice:: Need kernel patch!! */ + case WLAN_AKM_SUITE_8021X_SHA256: + eAuthMode = AUTH_MODE_WPA2; + u4AkmSuite = RSN_AKM_SUITE_802_1X_SHA256; + break; + case WLAN_AKM_SUITE_PSK_SHA256: + eAuthMode = AUTH_MODE_WPA2_PSK; + u4AkmSuite = RSN_AKM_SUITE_PSK_SHA256; + break; +#endif +#if CFG_SUPPORT_PASSPOINT + case WLAN_AKM_SUITE_OSEN: + eAuthMode = AUTH_MODE_WPA_OSEN; + u4AkmSuite = WFA_AKM_SUITE_OSEN; + break; +#endif + case WLAN_AKM_SUITE_SAE: + if (sme->auth_type == NL80211_AUTHTYPE_SAE) + eAuthMode = AUTH_MODE_WPA3_SAE; + else + eAuthMode = AUTH_MODE_OPEN; + u4AkmSuite = RSN_AKM_SUITE_SAE; + break; + + case WLAN_AKM_SUITE_OWE: + eAuthMode = AUTH_MODE_WPA3_OWE; + u4AkmSuite = RSN_AKM_SUITE_OWE; + break; + default: + DBGLOG(REQ, WARN, "invalid Akm Suite (%d)\n", + sme->crypto.akm_suites[0]); + return -EINVAL; + } + } + } + + DBGLOG(REQ, INFO, "u4WpaVersion=%d, u4AuthAlg=%d", + prWpaInfo->u4WpaVersion, + prWpaInfo->u4AuthAlg); + if (prWpaInfo->u4WpaVersion == + IW_AUTH_WPA_VERSION_DISABLED) { + switch (prWpaInfo->u4AuthAlg) { + case IW_AUTH_ALG_FT: + DBGLOG(REQ, INFO, "FT: Non-RSN FT connect\n"); + eAuthMode = AUTH_MODE_OPEN; + break; + case IW_AUTH_ALG_OPEN_SYSTEM: + eAuthMode = AUTH_MODE_OPEN; + break; + default: + eAuthMode = AUTH_MODE_AUTO_SWITCH; + break; + } + } + + prWpaInfo->fgPrivacyInvoke = sme->privacy; + prConnSettings->fgWpsActive = FALSE; + +#if CFG_SUPPORT_PASSPOINT + prHS20Info = aisGetHS20Info(prGlueInfo->prAdapter, + ucBssIndex); + prHS20Info->fgConnectHS20AP = FALSE; +#endif /* CFG_SUPPORT_PASSPOINT */ + + prConnSettings->non_wfa_vendor_ie_len = 0; + if (sme->ie && sme->ie_len > 0) { + uint32_t rStatus; + uint32_t u4BufLen; + uint8_t *prDesiredIE = NULL; + uint8_t *pucIEStart = (uint8_t *)sme->ie; +#if CFG_SUPPORT_WAPI + rStatus = kalIoctlByBssIdx(prGlueInfo, wlanoidSetWapiAssocInfo, + pucIEStart, sme->ie_len, FALSE, FALSE, FALSE, + &u4BufLen, + ucBssIndex); + + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(REQ, TRACE, + "[wapi] wapi not support due to set wapi assoc info error:%x\n", + rStatus); +#endif +#if CFG_SUPPORT_PASSPOINT + if (wextSrchDesiredHS20IE(pucIEStart, sme->ie_len, + (uint8_t **) &prDesiredIE)) { + rStatus = kalIoctlByBssIdx(prGlueInfo, + wlanoidSetHS20Info, + prDesiredIE, IE_SIZE(prDesiredIE), + FALSE, FALSE, TRUE, &u4BufLen, + ucBssIndex); +#if 0 + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(INIT, INFO, + "[HS20] set HS20 assoc info error:%x\n", + rStatus); +#endif + } else if (wextSrchDesiredOsenIE(pucIEStart, sme->ie_len, + (uint8_t **) &prDesiredIE)) { + /* we can reuse aucHS20AssocInfoIE because hs20 + * indication IE is not present when OSEN exist + */ + kalMemCopy(prGlueInfo->aucHS20AssocInfoIE, + prDesiredIE, IE_SIZE(prDesiredIE)); + prGlueInfo->u2HS20AssocInfoIELen = + (uint16_t)IE_SIZE(prDesiredIE); + } +#endif /* CFG_SUPPORT_PASSPOINT */ + if (wextSrchDesiredWPAIE(pucIEStart, sme->ie_len, 0x30, + (uint8_t **) &prDesiredIE)) { + struct RSN_INFO rRsnInfo; + + if (rsnParseRsnIE(prGlueInfo->prAdapter, + (struct RSN_INFO_ELEM *)prDesiredIE, &rRsnInfo)) { +#if CFG_SUPPORT_802_11W + if (rRsnInfo.u2RsnCap & ELEM_WPA_CAP_MFPC) { + prWpaInfo->ucRSNMfpCap = + RSN_AUTH_MFP_OPTIONAL; + if (rRsnInfo.u2RsnCap & + ELEM_WPA_CAP_MFPR) + prWpaInfo-> + ucRSNMfpCap = + RSN_AUTH_MFP_REQUIRED; + } else + prWpaInfo->ucRSNMfpCap = + RSN_AUTH_MFP_DISABLED; +#endif + } + } + /* Find non-wfa vendor specific ies set from upper layer */ + if (cfg80211_get_non_wfa_vendor_ie(prGlueInfo, pucIEStart, + sme->ie_len, ucBssIndex) > 0) { + DBGLOG(RSN, INFO, "Found non-wfa vendor ie (len=%u)\n", + prConnSettings->non_wfa_vendor_ie_len); + } + } + + /* Fill WPA info - mfp setting */ + /* Must put after paring RSNE from upper layer + * for prWpaInfo->ucRSNMfpCap assignment + */ +#if CFG_SUPPORT_802_11W + switch (sme->mfp) { + case NL80211_MFP_NO: + prWpaInfo->u4Mfp = IW_AUTH_MFP_DISABLED; + /* Change Mfp parameter from DISABLED to OPTIONAL + * if upper layer set MFPC = 1 in RSNE + * since upper layer can't bring MFP OPTIONAL information + * to driver by sme->mfp + */ + if (prWpaInfo->ucRSNMfpCap == RSN_AUTH_MFP_OPTIONAL) + prWpaInfo->u4Mfp = IW_AUTH_MFP_OPTIONAL; + else if (prWpaInfo->ucRSNMfpCap == + RSN_AUTH_MFP_REQUIRED) + DBGLOG(REQ, WARN, + "mfp parameter(DISABLED) conflict with mfp cap(REQUIRED)\n"); + break; + case NL80211_MFP_REQUIRED: + prWpaInfo->u4Mfp = IW_AUTH_MFP_REQUIRED; + break; + default: + prWpaInfo->u4Mfp = IW_AUTH_MFP_DISABLED; + break; + } + /* DBGLOG(REQ, INFO, ("MFP=%d\n", prWpaInfo->u4Mfp)); */ +#endif + + rStatus = kalIoctlByBssIdx(prGlueInfo, wlanoidSetAuthMode, &eAuthMode, + sizeof(eAuthMode), FALSE, FALSE, FALSE, &u4BufLen, + ucBssIndex); + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(REQ, WARN, "set auth mode error:%x\n", rStatus); + + prMib = aisGetMib(prGlueInfo->prAdapter, ucBssIndex); + + /* Enable the specific AKM suite only. */ + for (i = 0; i < MAX_NUM_SUPPORTED_AKM_SUITES; i++) { + prEntry = &prMib-> + dot11RSNAConfigAuthenticationSuitesTable[i]; + + if (prEntry->dot11RSNAConfigAuthenticationSuite == + u4AkmSuite) { + prEntry->dot11RSNAConfigAuthenticationSuiteEnabled = + TRUE; + /* printk("match AuthenticationSuite = 0x%x", + * u4AkmSuite); + */ + } else { + prEntry->dot11RSNAConfigAuthenticationSuiteEnabled = + FALSE; + } + } + + cipher = prWpaInfo->u4CipherGroup | + prWpaInfo->u4CipherPairwise; + + if (1 /* prWpaInfo->fgPrivacyInvoke */) { + if (cipher & IW_AUTH_CIPHER_GCMP256) { + eEncStatus = ENUM_ENCRYPTION4_ENABLED; + } else if (cipher & IW_AUTH_CIPHER_CCMP) { + eEncStatus = ENUM_ENCRYPTION3_ENABLED; + } else if (cipher & IW_AUTH_CIPHER_TKIP) { + eEncStatus = ENUM_ENCRYPTION2_ENABLED; + } else if (cipher & (IW_AUTH_CIPHER_WEP104 | + IW_AUTH_CIPHER_WEP40)) { + eEncStatus = ENUM_ENCRYPTION1_ENABLED; + } else if (cipher & IW_AUTH_CIPHER_NONE) { + if (prWpaInfo->fgPrivacyInvoke) + eEncStatus = ENUM_ENCRYPTION1_ENABLED; + else + eEncStatus = ENUM_ENCRYPTION_DISABLED; + } else { + eEncStatus = ENUM_ENCRYPTION_DISABLED; + } + } else { + eEncStatus = ENUM_ENCRYPTION_DISABLED; + } + + rStatus = kalIoctlByBssIdx(prGlueInfo, + wlanoidSetEncryptionStatus, &eEncStatus, + sizeof(eEncStatus), FALSE, FALSE, FALSE, &u4BufLen, + ucBssIndex); + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(REQ, WARN, "set encryption mode error:%x\n", + rStatus); + + if (sme->key_len != 0 + && prWpaInfo->u4WpaVersion == + IW_AUTH_WPA_VERSION_DISABLED) { + /* NL80211 only set the Tx wep key while connect, the max 4 wep + * key set prior via add key cmd + */ + struct PARAM_WEP *prWepKey = (struct PARAM_WEP *) wepBuf; + + kalMemZero(prWepKey, sizeof(struct PARAM_WEP)); + prWepKey->u4Length = OFFSET_OF(struct PARAM_WEP, + aucKeyMaterial) + sme->key_len; + prWepKey->u4KeyLength = (uint32_t) sme->key_len; + prWepKey->u4KeyIndex = (uint32_t) sme->key_idx; + prWepKey->u4KeyIndex |= IS_TRANSMIT_KEY; + if (prWepKey->u4KeyLength > MAX_KEY_LEN) { + DBGLOG(REQ, WARN, "Too long key length (%u)\n", + prWepKey->u4KeyLength); + return -EINVAL; + } + kalMemCopy(prWepKey->aucKeyMaterial, sme->key, + prWepKey->u4KeyLength); + + rStatus = kalIoctlByBssIdx(prGlueInfo, + wlanoidAbortScan, + NULL, 1, FALSE, FALSE, TRUE, &u4BufLen, + ucBssIndex); + + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(REQ, ERROR, "wlanoidAbortScan fail 0x%x\n", + rStatus); + + rStatus = kalIoctlByBssIdx(prGlueInfo, + wlanoidSetAddWep, prWepKey, + prWepKey->u4Length, + FALSE, FALSE, TRUE, &u4BufLen, + ucBssIndex); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, INFO, "wlanoidSetAddWep fail 0x%x\n", + rStatus); + return -EFAULT; + } + } + + /* Avoid dangling pointer, set defatul all zero */ + kalMemZero(&rNewSsid, sizeof(rNewSsid)); + rNewSsid.u4CenterFreq = sme->channel ? + sme->channel->center_freq : 0; + rNewSsid.pucBssid = (uint8_t *)sme->bssid; +#if KERNEL_VERSION(3, 15, 0) <= CFG80211_VERSION_CODE + rNewSsid.pucBssidHint = (uint8_t *)sme->bssid_hint; +#endif + rNewSsid.pucSsid = (uint8_t *)sme->ssid; + rNewSsid.u4SsidLen = sme->ssid_len; + rNewSsid.pucIEs = (uint8_t *)sme->ie; + rNewSsid.u4IesLen = sme->ie_len; + rNewSsid.ucBssIdx = ucBssIndex; + + rStatus = kalIoctl(prGlueInfo, wlanoidSetConnect, + (void *)&rNewSsid, sizeof(struct PARAM_CONNECT), + FALSE, FALSE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, WARN, "set SSID:%x\n", rStatus); + return -EINVAL; + } +#if 0 + if (sme->bssid != NULL + && 1 /* prGlueInfo->fgIsBSSIDSet */) { + /* connect by BSSID */ + if (sme->ssid_len > 0) { + struct CONNECTION_SETTINGS *prConnSettings = NULL; + + prConnSettings = & + (prGlueInfo->prAdapter->rWifiVar.rConnSettings); + /* prGlueInfo->fgIsSSIDandBSSIDSet = TRUE; */ + COPY_SSID(prConnSettings->aucSSID, + prConnSettings->ucSSIDLen, + sme->ssid, sme->ssid_len); + } + rStatus = kalIoctl(prGlueInfo, wlanoidSetBssid, + (void *) sme->bssid, MAC_ADDR_LEN, + FALSE, FALSE, TRUE, FALSE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, WARN, "set BSSID:%x\n", rStatus); + return -EINVAL; + } + } else if (sme->ssid_len > 0) { + /* connect by SSID */ + COPY_SSID(rNewSsid.aucSsid, rNewSsid.u4SsidLen, sme->ssid, + sme->ssid_len); + rNewSsid.ucBssIdx = ucBssIndex; + rStatus = kalIoctl(prGlueInfo, wlanoidSetSsid, + (void *)&rNewSsid, sizeof(struct PARAM_SSID), + FALSE, FALSE, TRUE, FALSE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, WARN, "set SSID:%x\n", rStatus); + return -EINVAL; + } + } +#endif + return 0; +} +#if CFG_SUPPORT_WPA3 +int mtk_cfg80211_external_auth(struct wiphy *wiphy, + struct net_device *ndev, + struct cfg80211_external_auth_params *params) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_FAILURE; + uint32_t u4BufLen; + struct PARAM_EXTERNAL_AUTH auth; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + if (!prGlueInfo) + DBGLOG(REQ, WARN, + "SAE-confirm failed with invalid prGlueInfo\n"); + + COPY_MAC_ADDR(auth.bssid, params->bssid); + auth.status = params->status; + auth.ucBssIdx = wlanGetBssIdx(ndev); + rStatus = kalIoctl(prGlueInfo, wlanoidExternalAuthDone, (void *)&auth, + sizeof(auth), FALSE, FALSE, FALSE, &u4BufLen); + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(OID, INFO, "SAE-confirm failed with: %d\n", rStatus); + + return 0; +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is responsible for requesting to disconnect from + * currently connected ESS + * + * @param + * + * @retval 0: successful + * others: failure + */ +/*----------------------------------------------------------------------------*/ +int mtk_cfg80211_disconnect(struct wiphy *wiphy, + struct net_device *ndev, u16 reason_code) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus; + uint32_t u4BufLen; + uint8_t ucBssIndex = 0; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + ASSERT(prGlueInfo); + + ucBssIndex = wlanGetBssIdx(ndev); + if (!IS_BSS_INDEX_VALID(ucBssIndex)) + return -EINVAL; + + DBGLOG(REQ, INFO, "ucBssIndex = %d\n", ucBssIndex); + rStatus = kalIoctlByBssIdx(prGlueInfo, wlanoidSetDisassociate, NULL, + 0, FALSE, FALSE, TRUE, &u4BufLen, + ucBssIndex); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, WARN, "disassociate error:%x\n", rStatus); + return -EFAULT; + } + + return 0; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is responsible for requesting to join an IBSS group + * + * @param + * + * @retval 0: successful + * others: failure + */ +/*----------------------------------------------------------------------------*/ +int mtk_cfg80211_join_ibss(struct wiphy *wiphy, + struct net_device *ndev, + struct cfg80211_ibss_params *params) +{ + struct PARAM_SSID rNewSsid; + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t u4ChnlFreq; /* Store channel or frequency information */ + uint32_t u4BufLen = 0, u4SsidLen = 0; + uint32_t rStatus; + uint8_t ucBssIndex = 0; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + ASSERT(prGlueInfo); + + ucBssIndex = wlanGetBssIdx(ndev); + if (!IS_BSS_INDEX_VALID(ucBssIndex)) + return -EINVAL; + + /* set channel */ + if (params->channel_fixed) { + u4ChnlFreq = params->chandef.center_freq1; + + rStatus = kalIoctlByBssIdx(prGlueInfo, wlanoidSetFrequency, + &u4ChnlFreq, sizeof(u4ChnlFreq), + FALSE, FALSE, FALSE, &u4BufLen, + ucBssIndex); + if (rStatus != WLAN_STATUS_SUCCESS) + return -EFAULT; + } + + /* set SSID */ + if (params->ssid_len > PARAM_MAX_LEN_SSID) + u4SsidLen = PARAM_MAX_LEN_SSID; + else + u4SsidLen = params->ssid_len; + + kalMemCopy(rNewSsid.aucSsid, params->ssid, + u4SsidLen); + rStatus = kalIoctlByBssIdx(prGlueInfo, + wlanoidSetSsid, (void *)&rNewSsid, + sizeof(struct PARAM_SSID), + FALSE, FALSE, TRUE, &u4BufLen, + ucBssIndex); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, WARN, "set SSID:%x\n", rStatus); + return -EFAULT; + } + + return 0; + + return -EINVAL; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is responsible for requesting to leave from IBSS group + * + * @param + * + * @retval 0: successful + * others: failure + */ +/*----------------------------------------------------------------------------*/ +int mtk_cfg80211_leave_ibss(struct wiphy *wiphy, + struct net_device *ndev) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus; + uint32_t u4BufLen; + uint8_t ucBssIndex = 0; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + ASSERT(prGlueInfo); + + ucBssIndex = wlanGetBssIdx(ndev); + if (!IS_BSS_INDEX_VALID(ucBssIndex)) + return -EINVAL; + + rStatus = kalIoctlByBssIdx(prGlueInfo, wlanoidSetDisassociate, NULL, + 0, FALSE, FALSE, TRUE, &u4BufLen, + ucBssIndex); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, WARN, "disassociate error:%x\n", rStatus); + return -EFAULT; + } + + return 0; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is responsible for requesting to configure + * WLAN power managemenet + * + * @param + * + * @retval 0: successful + * others: failure + */ +/*----------------------------------------------------------------------------*/ +int mtk_cfg80211_set_power_mgmt(struct wiphy *wiphy, + struct net_device *ndev, bool enabled, int timeout) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus; + uint32_t u4BufLen; + struct PARAM_POWER_MODE_ rPowerMode; + uint8_t ucBssIndex = 0; + struct BSS_INFO *prBssInfo; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + if (!prGlueInfo) + return -EFAULT; + + if (prGlueInfo->prAdapter->fgEnDbgPowerMode) { + DBGLOG(REQ, WARN, + "Force power mode enabled, ignore: %d\n", enabled); + return 0; + } + + ucBssIndex = wlanGetBssIdx(ndev); + if (!IS_BSS_INDEX_VALID(ucBssIndex)) + return -EINVAL; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prGlueInfo->prAdapter, + ucBssIndex); + if (!prBssInfo) + return -EINVAL; + + DBGLOG(REQ, INFO, "%d: enabled=%d, timeout=%d, fgTIMPresend=%d\n", + ucBssIndex, enabled, timeout, + prBssInfo->fgTIMPresent); + + if (enabled) { + if (prBssInfo->eConnectionState + == MEDIA_STATE_CONNECTED && + !prBssInfo->fgTIMPresent) + return -EFAULT; + + if (timeout == -1) + rPowerMode.ePowerMode = Param_PowerModeFast_PSP; + else + rPowerMode.ePowerMode = Param_PowerModeMAX_PSP; + } else { + rPowerMode.ePowerMode = Param_PowerModeCAM; + } + + rPowerMode.ucBssIdx = ucBssIndex; + + rStatus = kalIoctl(prGlueInfo, wlanoidSet802dot11PowerSaveProfile, + &rPowerMode, sizeof(struct PARAM_POWER_MODE_), + FALSE, FALSE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, WARN, "set_power_mgmt error:%x\n", rStatus); + return -EFAULT; + } + + return 0; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is responsible for requesting to cache + * a PMKID for a BSSID + * + * @param + * + * @retval 0: successful + * others: failure + */ +/*----------------------------------------------------------------------------*/ +int mtk_cfg80211_set_pmksa(struct wiphy *wiphy, + struct net_device *ndev, struct cfg80211_pmksa *pmksa) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus; + uint32_t u4BufLen; + struct PARAM_PMKID pmkid; + uint8_t ucBssIndex = 0; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + ASSERT(prGlueInfo); + + DBGLOG(REQ, TRACE, "mtk_cfg80211_set_pmksa " MACSTR " pmk\n", + MAC2STR(pmksa->bssid)); + + ucBssIndex = wlanGetBssIdx(ndev); + if (!IS_BSS_INDEX_VALID(ucBssIndex)) + return -EINVAL; + + COPY_MAC_ADDR(pmkid.arBSSID, pmksa->bssid); + kalMemCopy(pmkid.arPMKID, pmksa->pmkid, IW_PMKID_LEN); + pmkid.ucBssIdx = ucBssIndex; + rStatus = kalIoctl(prGlueInfo, wlanoidSetPmkid, &pmkid, + sizeof(struct PARAM_PMKID), + FALSE, FALSE, FALSE, &u4BufLen); + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(INIT, INFO, "add pmkid error:%x\n", rStatus); + + return 0; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is responsible for requesting to remove + * a cached PMKID for a BSSID + * + * @param + * + * @retval 0: successful + * others: failure + */ +/*----------------------------------------------------------------------------*/ +int mtk_cfg80211_del_pmksa(struct wiphy *wiphy, + struct net_device *ndev, struct cfg80211_pmksa *pmksa) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus; + uint32_t u4BufLen; + struct PARAM_PMKID pmkid; + uint8_t ucBssIndex = 0; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + ASSERT(prGlueInfo); + + DBGLOG(REQ, TRACE, "mtk_cfg80211_del_pmksa " MACSTR "\n", + MAC2STR(pmksa->bssid)); + + ucBssIndex = wlanGetBssIdx(ndev); + if (!IS_BSS_INDEX_VALID(ucBssIndex)) + return -EINVAL; + + COPY_MAC_ADDR(pmkid.arBSSID, pmksa->bssid); + kalMemCopy(pmkid.arPMKID, pmksa->pmkid, IW_PMKID_LEN); + pmkid.ucBssIdx = ucBssIndex; + rStatus = kalIoctl(prGlueInfo, wlanoidDelPmkid, &pmkid, + sizeof(struct PARAM_PMKID), + FALSE, FALSE, FALSE, &u4BufLen); + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(INIT, INFO, "add pmkid error:%x\n", rStatus); + + return 0; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is responsible for requesting to flush + * all cached PMKID + * + * @param + * + * @retval 0: successful + * others: failure + */ +/*----------------------------------------------------------------------------*/ +int mtk_cfg80211_flush_pmksa(struct wiphy *wiphy, + struct net_device *ndev) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus; + uint32_t u4BufLen; + uint8_t ucBssIndex = 0; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + ASSERT(prGlueInfo); + + ucBssIndex = wlanGetBssIdx(ndev); + if (!IS_BSS_INDEX_VALID(ucBssIndex)) + return -EINVAL; + + rStatus = kalIoctlByBssIdx(prGlueInfo, wlanoidFlushPmkid, NULL, 0, + FALSE, FALSE, FALSE, &u4BufLen, + ucBssIndex); + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(INIT, INFO, "flush pmkid error:%x\n", rStatus); + + return 0; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is responsible for setting the rekey data + * + * @param + * + * @retval 0: successful + * others: failure + */ +/*----------------------------------------------------------------------------*/ +int mtk_cfg80211_set_rekey_data(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_gtk_rekey_data *data) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t u4BufLen; + struct PARAM_GTK_REKEY_DATA *prGtkData; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + int32_t i4Rslt = -EINVAL; + struct GL_WPA_INFO *prWpaInfo; + uint8_t ucBssIndex = 0; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + ASSERT(prGlueInfo); + + ucBssIndex = wlanGetBssIdx(dev); + if (!IS_BSS_INDEX_VALID(ucBssIndex)) + return -EINVAL; + + prGtkData = + (struct PARAM_GTK_REKEY_DATA *) kalMemAlloc(sizeof( + struct PARAM_GTK_REKEY_DATA), VIR_MEM_TYPE); + + if (!prGtkData) + return WLAN_STATUS_SUCCESS; + + DBGLOG(RSN, INFO, "ucBssIndex = %d, size(%d)\n", + ucBssIndex, + (uint32_t) sizeof(struct cfg80211_gtk_rekey_data)); + + DBGLOG(RSN, TRACE, "kek\n"); + DBGLOG_MEM8(RSN, TRACE, (uint8_t *)data->kek, + NL80211_KEK_LEN); + DBGLOG(RSN, TRACE, "kck\n"); + DBGLOG_MEM8(RSN, TRACE, (uint8_t *)data->kck, + NL80211_KCK_LEN); + DBGLOG(RSN, TRACE, "replay count\n"); + DBGLOG_MEM8(RSN, TRACE, (uint8_t *)data->replay_ctr, + NL80211_REPLAY_CTR_LEN); + + +#if 0 + kalMemCopy(prGtkData, data, sizeof(*data)); +#else + kalMemCopy(prGtkData->aucKek, data->kek, NL80211_KEK_LEN); + kalMemCopy(prGtkData->aucKck, data->kck, NL80211_KCK_LEN); + kalMemCopy(prGtkData->aucReplayCtr, data->replay_ctr, + NL80211_REPLAY_CTR_LEN); +#endif + + prGtkData->ucBssIndex = ucBssIndex; + + prWpaInfo = aisGetWpaInfo(prGlueInfo->prAdapter, + ucBssIndex); + + prGtkData->u4Proto = NL80211_WPA_VERSION_2; + if (prWpaInfo->u4WpaVersion == + IW_AUTH_WPA_VERSION_WPA) + prGtkData->u4Proto = NL80211_WPA_VERSION_1; + + if (prWpaInfo->u4CipherPairwise == + IW_AUTH_CIPHER_TKIP) + prGtkData->u4PairwiseCipher = BIT(3); + else if (prWpaInfo->u4CipherPairwise == + IW_AUTH_CIPHER_CCMP) + prGtkData->u4PairwiseCipher = BIT(4); + else { + kalMemFree(prGtkData, VIR_MEM_TYPE, + sizeof(struct PARAM_GTK_REKEY_DATA)); + return WLAN_STATUS_SUCCESS; + } + + if (prWpaInfo->u4CipherGroup == + IW_AUTH_CIPHER_TKIP) + prGtkData->u4GroupCipher = BIT(3); + else if (prWpaInfo->u4CipherGroup == + IW_AUTH_CIPHER_CCMP) + prGtkData->u4GroupCipher = BIT(4); + else { + kalMemFree(prGtkData, VIR_MEM_TYPE, + sizeof(struct PARAM_GTK_REKEY_DATA)); + return WLAN_STATUS_SUCCESS; + } + + prGtkData->u4KeyMgmt = prWpaInfo->u4KeyMgmt; + prGtkData->u4MgmtGroupCipher = 0; + + rStatus = kalIoctl(prGlueInfo, wlanoidSetGtkRekeyData, prGtkData, + sizeof(struct PARAM_GTK_REKEY_DATA), + FALSE, FALSE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(INIT, INFO, "set GTK rekey data error:%x\n", + rStatus); + else + i4Rslt = 0; + + kalMemFree(prGtkData, VIR_MEM_TYPE, + sizeof(struct PARAM_GTK_REKEY_DATA)); + + return i4Rslt; +} + +void mtk_cfg80211_mgmt_frame_register(IN struct wiphy *wiphy, + IN struct wireless_dev *wdev, + IN u16 frame_type, + IN bool reg) +{ +#if 0 + struct MSG_P2P_MGMT_FRAME_REGISTER *prMgmtFrameRegister = + (struct MSG_P2P_MGMT_FRAME_REGISTER *) NULL; +#endif + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *) NULL; + + do { + + DBGLOG(INIT, TRACE, "mtk_cfg80211_mgmt_frame_register\n"); + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + switch (frame_type) { + case MAC_FRAME_PROBE_REQ: + if (reg) { + prGlueInfo->u4OsMgmtFrameFilter |= + PARAM_PACKET_FILTER_PROBE_REQ; + DBGLOG(INIT, TRACE, + "Open packet filer probe request\n"); + } else { + prGlueInfo->u4OsMgmtFrameFilter &= + ~PARAM_PACKET_FILTER_PROBE_REQ; + DBGLOG(INIT, TRACE, + "Close packet filer probe request\n"); + } + break; + case MAC_FRAME_ACTION: + if (reg) { + prGlueInfo->u4OsMgmtFrameFilter |= + PARAM_PACKET_FILTER_ACTION_FRAME; + DBGLOG(INIT, TRACE, + "Open packet filer action frame.\n"); + } else { + prGlueInfo->u4OsMgmtFrameFilter &= + ~PARAM_PACKET_FILTER_ACTION_FRAME; + DBGLOG(INIT, TRACE, + "Close packet filer action frame.\n"); + } + break; + default: + DBGLOG(INIT, TRACE, + "Ask frog to add code for mgmt:%x\n", + frame_type); + break; + } + + if (prGlueInfo->prAdapter != NULL) { + + set_bit(GLUE_FLAG_FRAME_FILTER_AIS_BIT, + &prGlueInfo->ulFlag); + + /* wake up main thread */ + wake_up_interruptible(&prGlueInfo->waitq); + + if (in_interrupt()) + DBGLOG(INIT, TRACE, + "It is in interrupt level\n"); + } +#if 0 + + prMgmtFrameRegister = + (struct MSG_P2P_MGMT_FRAME_REGISTER *) cnmMemAlloc( + prGlueInfo->prAdapter, RAM_TYPE_MSG, + sizeof(struct MSG_P2P_MGMT_FRAME_REGISTER)); + + if (prMgmtFrameRegister == NULL) { + ASSERT(FALSE); + break; + } + + prMgmtFrameRegister->rMsgHdr.eMsgId = + MID_MNY_P2P_MGMT_FRAME_REGISTER; + + prMgmtFrameRegister->u2FrameType = frame_type; + prMgmtFrameRegister->fgIsRegister = reg; + + mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, + (struct MSG_HDR *) prMgmtFrameRegister, + MSG_SEND_METHOD_BUF); + +#endif + + } while (FALSE); + +} /* mtk_cfg80211_mgmt_frame_register */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is responsible for requesting to stay on a + * specified channel + * + * @param + * + * @retval 0: successful + * others: failure + */ +/*----------------------------------------------------------------------------*/ +int mtk_cfg80211_remain_on_channel(struct wiphy *wiphy, + struct wireless_dev *wdev, + struct ieee80211_channel *chan, unsigned int duration, + u64 *cookie) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4Rslt = -EINVAL; + struct MSG_REMAIN_ON_CHANNEL *prMsgChnlReq = + (struct MSG_REMAIN_ON_CHANNEL *) NULL; + uint8_t ucBssIndex = 0; + + do { + if ((wiphy == NULL) + || (wdev == NULL) + || (chan == NULL) + || (cookie == NULL)) { + break; + } + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + ASSERT(prGlueInfo); + + ucBssIndex = wlanGetBssIdx(wdev->netdev); + if (!IS_BSS_INDEX_VALID(ucBssIndex)) + return -EINVAL; + + *cookie = prGlueInfo->u8Cookie++; + + prMsgChnlReq = cnmMemAlloc(prGlueInfo->prAdapter, + RAM_TYPE_MSG, sizeof(struct MSG_REMAIN_ON_CHANNEL)); + + if (prMsgChnlReq == NULL) { + ASSERT(FALSE); + i4Rslt = -ENOMEM; + break; + } + + prMsgChnlReq->rMsgHdr.eMsgId = + MID_MNY_AIS_REMAIN_ON_CHANNEL; + prMsgChnlReq->u8Cookie = *cookie; + prMsgChnlReq->u4DurationMs = duration; + prMsgChnlReq->eReqType = CH_REQ_TYPE_ROC; + prMsgChnlReq->ucChannelNum = nicFreq2ChannelNum( + chan->center_freq * 1000); + + switch (chan->band) { + case KAL_BAND_2GHZ: + prMsgChnlReq->eBand = BAND_2G4; + break; + case KAL_BAND_5GHZ: + prMsgChnlReq->eBand = BAND_5G; + break; + default: + prMsgChnlReq->eBand = BAND_2G4; + break; + } + + prMsgChnlReq->eSco = CHNL_EXT_SCN; + + prMsgChnlReq->ucBssIdx = ucBssIndex; + + mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, + (struct MSG_HDR *) prMsgChnlReq, MSG_SEND_METHOD_BUF); + + i4Rslt = 0; + } while (FALSE); + + return i4Rslt; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is responsible for requesting to cancel staying + * on a specified channel + * + * @param + * + * @retval 0: successful + * others: failure + */ +/*----------------------------------------------------------------------------*/ +int mtk_cfg80211_cancel_remain_on_channel( + struct wiphy *wiphy, struct wireless_dev *wdev, u64 cookie) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4Rslt = -EINVAL; + struct MSG_CANCEL_REMAIN_ON_CHANNEL *prMsgChnlAbort = + (struct MSG_CANCEL_REMAIN_ON_CHANNEL *) NULL; + uint8_t ucBssIndex = 0; + + do { + if ((wiphy == NULL) + || (wdev == NULL) + ) { + break; + } + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + ASSERT(prGlueInfo); + + ucBssIndex = wlanGetBssIdx(wdev->netdev); + if (!IS_BSS_INDEX_VALID(ucBssIndex)) + return -EINVAL; + + prMsgChnlAbort = + cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, + sizeof(struct MSG_CANCEL_REMAIN_ON_CHANNEL)); + + if (prMsgChnlAbort == NULL) { + ASSERT(FALSE); + i4Rslt = -ENOMEM; + break; + } + + prMsgChnlAbort->rMsgHdr.eMsgId = + MID_MNY_AIS_CANCEL_REMAIN_ON_CHANNEL; + prMsgChnlAbort->u8Cookie = cookie; + + prMsgChnlAbort->ucBssIdx = ucBssIndex; + + mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, + (struct MSG_HDR *) prMsgChnlAbort, MSG_SEND_METHOD_BUF); + + i4Rslt = 0; + } while (FALSE); + + return i4Rslt; +} + +int _mtk_cfg80211_mgmt_tx(struct wiphy *wiphy, + struct wireless_dev *wdev, struct ieee80211_channel *chan, + bool offchan, unsigned int wait, const u8 *buf, size_t len, + bool no_cck, bool dont_wait_for_ack, u64 *cookie) +{ + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *) NULL; + int32_t i4Rslt = -EINVAL; + struct MSG_MGMT_TX_REQUEST *prMsgTxReq = + (struct MSG_MGMT_TX_REQUEST *) NULL; + struct MSDU_INFO *prMgmtFrame = (struct MSDU_INFO *) NULL; + uint8_t *pucFrameBuf = (uint8_t *) NULL; + uint64_t *pu8GlCookie = (uint64_t *) NULL; + + do { + if ((wiphy == NULL) || (wdev == NULL) || (cookie == NULL)) + break; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + ASSERT(prGlueInfo); + + *cookie = prGlueInfo->u8Cookie++; + + prMsgTxReq = cnmMemAlloc(prGlueInfo->prAdapter, + RAM_TYPE_MSG, + sizeof(struct MSG_MGMT_TX_REQUEST)); + + if (prMsgTxReq == NULL) { + ASSERT(FALSE); + i4Rslt = -ENOMEM; + break; + } + + if (offchan) { + prMsgTxReq->fgIsOffChannel = TRUE; + + kalChannelFormatSwitch(NULL, chan, + &prMsgTxReq->rChannelInfo); + kalChannelScoSwitch(NL80211_CHAN_NO_HT, + &prMsgTxReq->eChnlExt); + } else { + prMsgTxReq->fgIsOffChannel = FALSE; + } + + if (wait) + prMsgTxReq->u4Duration = wait; + else + prMsgTxReq->u4Duration = 0; + + if (no_cck) + prMsgTxReq->fgNoneCckRate = TRUE; + else + prMsgTxReq->fgNoneCckRate = FALSE; + + if (dont_wait_for_ack) + prMsgTxReq->fgIsWaitRsp = FALSE; + else + prMsgTxReq->fgIsWaitRsp = TRUE; + + prMgmtFrame = cnmMgtPktAlloc(prGlueInfo->prAdapter, + (int32_t) (len + sizeof(uint64_t) + + MAC_TX_RESERVED_FIELD)); + prMsgTxReq->prMgmtMsduInfo = prMgmtFrame; + if (prMsgTxReq->prMgmtMsduInfo == NULL) { + /* ASSERT(FALSE); */ + i4Rslt = -ENOMEM; + break; + } + + prMsgTxReq->u8Cookie = *cookie; + prMsgTxReq->rMsgHdr.eMsgId = MID_MNY_AIS_MGMT_TX; + prMsgTxReq->ucBssIdx = wlanGetBssIdx(wdev->netdev); + + pucFrameBuf = + (uint8_t *) + ((unsigned long) prMgmtFrame->prPacket + + MAC_TX_RESERVED_FIELD); + pu8GlCookie = + (uint64_t *) + ((unsigned long) prMgmtFrame->prPacket + + (unsigned long) len + + MAC_TX_RESERVED_FIELD); + + kalMemCopy(pucFrameBuf, buf, len); + + *pu8GlCookie = *cookie; + + prMgmtFrame->u2FrameLength = len; + prMgmtFrame->ucBssIndex = wlanGetBssIdx(wdev->netdev); + +#define TEMP_LOG_TEMPLATE "bssIdx: %d, band: %d, chan: %d, offchan: %d, " \ + "wait: %d, len: %d, no_cck: %d, dont_wait_for_ack: %d, " \ + "cookie: 0x%llx\n" + DBGLOG(P2P, INFO, TEMP_LOG_TEMPLATE, + prMsgTxReq->ucBssIdx, + prMsgTxReq->rChannelInfo.eBand, + prMsgTxReq->rChannelInfo.ucChannelNum, + prMsgTxReq->fgIsOffChannel, + prMsgTxReq->u4Duration, + prMsgTxReq->prMgmtMsduInfo->u2FrameLength, + prMsgTxReq->fgNoneCckRate, + prMsgTxReq->fgIsWaitRsp, + prMsgTxReq->u8Cookie); +#undef TEMP_LOG_TEMPLATE + + mboxSendMsg(prGlueInfo->prAdapter, + MBOX_ID_0, + (struct MSG_HDR *) prMsgTxReq, + MSG_SEND_METHOD_BUF); + + i4Rslt = 0; + } while (FALSE); + + if ((i4Rslt != 0) && (prMsgTxReq != NULL)) { + if (prMsgTxReq->prMgmtMsduInfo != NULL) + cnmMgtPktFree(prGlueInfo->prAdapter, + prMsgTxReq->prMgmtMsduInfo); + + cnmMemFree(prGlueInfo->prAdapter, prMsgTxReq); + } + + return i4Rslt; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is responsible for requesting to send a management frame + * + * @param + * + * @retval 0: successful + * others: failure + */ +/*----------------------------------------------------------------------------*/ +#if KERNEL_VERSION(3, 14, 0) <= CFG80211_VERSION_CODE +int mtk_cfg80211_mgmt_tx(struct wiphy *wiphy, + struct wireless_dev *wdev, + struct cfg80211_mgmt_tx_params *params, + u64 *cookie) +{ + if (params == NULL) + return -EINVAL; + + return _mtk_cfg80211_mgmt_tx(wiphy, wdev, params->chan, + params->offchan, params->wait, params->buf, params->len, + params->no_cck, params->dont_wait_for_ack, cookie); +} +#else +int mtk_cfg80211_mgmt_tx(struct wiphy *wiphy, + struct wireless_dev *wdev, struct ieee80211_channel *channel, + bool offchan, unsigned int wait, const u8 *buf, size_t len, + bool no_cck, bool dont_wait_for_ack, u64 *cookie) +{ + return _mtk_cfg80211_mgmt_tx(wiphy, wdev, channel, offchan, wait, buf, + len, no_cck, dont_wait_for_ack, cookie); +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is responsible for requesting to cancel the wait time + * from transmitting a management frame on another channel + * + * @param + * + * @retval 0: successful + * others: failure + */ +/*----------------------------------------------------------------------------*/ +int mtk_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, + struct wireless_dev *wdev, u64 cookie) +{ + int32_t i4Rslt = -EINVAL; + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *) NULL; + struct MSG_CANCEL_TX_WAIT_REQUEST *prMsgCancelTxWait = + (struct MSG_CANCEL_TX_WAIT_REQUEST *) NULL; + uint8_t ucBssIndex = 0; + + do { + ASSERT(wiphy); + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + ASSERT(prGlueInfo); + + ucBssIndex = wlanGetBssIdx(wdev->netdev); + if (!IS_BSS_INDEX_VALID(ucBssIndex)) + return -EINVAL; + + DBGLOG(P2P, INFO, "cookie: 0x%llx, ucBssIndex = %d\n", + cookie, ucBssIndex); + + + prMsgCancelTxWait = cnmMemAlloc(prGlueInfo->prAdapter, + RAM_TYPE_MSG, + sizeof(struct MSG_CANCEL_TX_WAIT_REQUEST)); + + if (prMsgCancelTxWait == NULL) { + ASSERT(FALSE); + i4Rslt = -ENOMEM; + break; + } + + prMsgCancelTxWait->rMsgHdr.eMsgId = + MID_MNY_AIS_MGMT_TX_CANCEL_WAIT; + prMsgCancelTxWait->u8Cookie = cookie; + prMsgCancelTxWait->ucBssIdx = ucBssIndex; + + mboxSendMsg(prGlueInfo->prAdapter, + MBOX_ID_0, + (struct MSG_HDR *) prMsgCancelTxWait, + MSG_SEND_METHOD_BUF); + + i4Rslt = 0; + } while (FALSE); + + return i4Rslt; +} + +#ifdef CONFIG_NL80211_TESTMODE + +#if CFG_SUPPORT_PASSPOINT +int mtk_cfg80211_testmode_hs20_cmd(IN struct wiphy *wiphy, + IN struct wireless_dev *wdev, + IN void *data, IN int len) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct wpa_driver_hs20_data_s *prParams = NULL; + uint32_t rstatus = WLAN_STATUS_SUCCESS; + int fgIsValid = 0; + uint32_t u4SetInfoLen = 0; + uint8_t ucBssIndex = 0; + + ASSERT(wiphy); + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + ucBssIndex = wlanGetBssIdx(wdev->netdev); + if (!IS_BSS_INDEX_VALID(ucBssIndex)) + return -EINVAL; + + if (data && len) + prParams = (struct wpa_driver_hs20_data_s *)data; + + if (prParams) { + int i; + + DBGLOG(INIT, INFO, "Cmd Type (%d)\n", prParams->CmdType); + switch (prParams->CmdType) { + case HS20_CMD_ID_SET_BSSID_POOL: + DBGLOG(REQ, TRACE, + "fgBssidPoolIsEnable=%d, ucNumBssidPool=%d\n", + prParams->hs20_set_bssid_pool.fgBssidPoolIsEnable, + prParams->hs20_set_bssid_pool.ucNumBssidPool); + for (i = 0; + i < prParams->hs20_set_bssid_pool.ucNumBssidPool; + i++) { + DBGLOG(REQ, TRACE, + "[%d][ " MACSTR " ]\n", + i, + MAC2STR(prParams-> + hs20_set_bssid_pool. + arBssidPool[i])); + } + rstatus = kalIoctlByBssIdx(prGlueInfo, + (PFN_OID_HANDLER_FUNC) wlanoidSetHS20BssidPool, + &prParams->hs20_set_bssid_pool, + sizeof(struct param_hs20_set_bssid_pool), + FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen, + ucBssIndex); + break; + default: + DBGLOG(REQ, TRACE, + "Unknown Cmd Type (%d)\n", + prParams->CmdType); + rstatus = WLAN_STATUS_FAILURE; + + } + + } + + if (rstatus != WLAN_STATUS_SUCCESS) + fgIsValid = -EFAULT; + + return fgIsValid; +} +#endif /* CFG_SUPPORT_PASSPOINT */ + +#if CFG_SUPPORT_WAPI +int mtk_cfg80211_testmode_set_key_ext(IN struct wiphy + *wiphy, + IN struct wireless_dev *wdev, + IN void *data, IN int len) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct NL80211_DRIVER_SET_KEY_EXTS *prParams = + (struct NL80211_DRIVER_SET_KEY_EXTS *) NULL; + struct iw_encode_exts *prIWEncExt = (struct iw_encode_exts + *)NULL; + uint32_t rstatus = WLAN_STATUS_SUCCESS; + int fgIsValid = 0; + uint32_t u4BufLen = 0; + const uint8_t aucBCAddr[] = BC_MAC_ADDR; + uint8_t ucBssIndex = 0; + + struct PARAM_KEY *prWpiKey = (struct PARAM_KEY *) + keyStructBuf; + + memset(keyStructBuf, 0, sizeof(keyStructBuf)); + + ASSERT(wiphy); + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if (data == NULL || len == 0) { + DBGLOG(INIT, TRACE, "%s data or len is invalid\n", __func__); + return -EINVAL; + } + + ucBssIndex = wlanGetBssIdx(wdev->netdev); + if (!IS_BSS_INDEX_VALID(ucBssIndex)) + ucBssIndex = 0; + + prParams = (struct NL80211_DRIVER_SET_KEY_EXTS *) data; + prIWEncExt = (struct iw_encode_exts *)&prParams->ext; + + if (prIWEncExt->alg == IW_ENCODE_ALG_SMS4) { + /* KeyID */ + prWpiKey->u4KeyIndex = prParams->key_index; + prWpiKey->u4KeyIndex--; + if (prWpiKey->u4KeyIndex > 1) { + /* key id is out of range */ + /* printk(KERN_INFO "[wapi] add key error: + * key_id invalid %d\n", prWpiKey->ucKeyID); + */ + return -EINVAL; + } + + if (prIWEncExt->key_len != 32) { + /* key length not valid */ + /* printk(KERN_INFO "[wapi] add key error: + * key_len invalid %d\n", prIWEncExt->key_len); + */ + return -EINVAL; + } + prWpiKey->u4KeyLength = prIWEncExt->key_len; + + if (prIWEncExt->ext_flags & IW_ENCODE_EXT_SET_TX_KEY && + !(prIWEncExt->ext_flags & IW_ENCODE_EXT_GROUP_KEY)) { + /* WAI seems set the STA group key with + * IW_ENCODE_EXT_SET_TX_KEY !!!! + * Ignore the group case + */ + prWpiKey->u4KeyIndex |= BIT(30); + prWpiKey->u4KeyIndex |= BIT(31); + /* BSSID */ + memcpy(prWpiKey->arBSSID, prIWEncExt->addr, 6); + } else { + COPY_MAC_ADDR(prWpiKey->arBSSID, aucBCAddr); + } + + /* PN */ + /* memcpy(prWpiKey->rKeyRSC, prIWEncExt->tx_seq, + * IW_ENCODE_SEQ_MAX_SIZE * 2); + */ + + memcpy(prWpiKey->aucKeyMaterial, prIWEncExt->key, 32); + + prWpiKey->u4Length = sizeof(struct PARAM_KEY); + prWpiKey->ucBssIdx = ucBssIndex; + prWpiKey->ucCipher = CIPHER_SUITE_WPI; + + rstatus = kalIoctl(prGlueInfo, wlanoidSetAddKey, prWpiKey, + sizeof(struct PARAM_KEY), + FALSE, FALSE, TRUE, &u4BufLen); + + if (rstatus != WLAN_STATUS_SUCCESS) { + /* printk(KERN_INFO "[wapi] add key error:%x\n", + * rStatus); + */ + fgIsValid = -EFAULT; + } + + } + return fgIsValid; +} +#endif + +int +mtk_cfg80211_testmode_get_sta_statistics(IN struct wiphy + *wiphy, IN void *data, IN int len, + IN struct GLUE_INFO *prGlueInfo) +{ + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen; + uint32_t u4LinkScore; + uint32_t u4TotalError; + uint32_t u4TxExceedThresholdCount; + uint32_t u4TxTotalCount; + + struct NL80211_DRIVER_GET_STA_STATISTICS_PARAMS *prParams = + NULL; + struct PARAM_GET_STA_STATISTICS rQueryStaStatistics; + struct sk_buff *skb; + + ASSERT(wiphy); + ASSERT(prGlueInfo); + + if (data && len) + prParams = (struct NL80211_DRIVER_GET_STA_STATISTICS_PARAMS + *) data; + + if (prParams == NULL) { + DBGLOG(QM, ERROR, "prParams is NULL, data=%p, len=%d\n", + data, len); + return -EINVAL; + } else if (prParams->aucMacAddr == NULL) { + DBGLOG(QM, ERROR, + "prParams->aucMacAddr is NULL, data=%p, len=%d\n", + data, len); + return -EINVAL; + } + + skb = cfg80211_testmode_alloc_reply_skb(wiphy, + sizeof(struct PARAM_GET_STA_STATISTICS) + 1); + if (!skb) { + DBGLOG(QM, ERROR, "allocate skb failed:%x\n", rStatus); + return -ENOMEM; + } + + DBGLOG(QM, TRACE, "Get [" MACSTR "] STA statistics\n", + MAC2STR(prParams->aucMacAddr)); + + kalMemZero(&rQueryStaStatistics, + sizeof(rQueryStaStatistics)); + COPY_MAC_ADDR(rQueryStaStatistics.aucMacAddr, + prParams->aucMacAddr); + rQueryStaStatistics.ucReadClear = TRUE; + + rStatus = kalIoctl(prGlueInfo, + wlanoidQueryStaStatistics, + &rQueryStaStatistics, sizeof(rQueryStaStatistics), + TRUE, FALSE, TRUE, &u4BufLen); + + /* Calcute Link Score */ + u4TxExceedThresholdCount = + rQueryStaStatistics.u4TxExceedThresholdCount; + u4TxTotalCount = rQueryStaStatistics.u4TxTotalCount; + u4TotalError = rQueryStaStatistics.u4TxFailCount + + rQueryStaStatistics.u4TxLifeTimeoutCount; + + /* u4LinkScore 10~100 , ExceedThreshold ratio 0~90 only + * u4LinkScore 0~9 , Drop packet ratio 0~9 and all packets exceed + * threshold + */ + if (u4TxTotalCount) { + if (u4TxExceedThresholdCount <= u4TxTotalCount) + u4LinkScore = (90 - ((u4TxExceedThresholdCount * 90) + / u4TxTotalCount)); + else + u4LinkScore = 0; + } else { + u4LinkScore = 90; + } + + u4LinkScore += 10; + + if (u4LinkScore == 10) { + if (u4TotalError <= u4TxTotalCount) + u4LinkScore = (10 - ((u4TotalError * 10) + / u4TxTotalCount)); + else + u4LinkScore = 0; + + } + + if (u4LinkScore > 100) + u4LinkScore = 100; + { + u8 __tmp = 0; + + if (unlikely(nla_put(skb, + NL80211_TESTMODE_STA_STATISTICS_INVALID, sizeof(u8), + &__tmp) < 0)) + goto nla_put_failure; + } + { + u8 __tmp = NL80211_DRIVER_TESTMODE_VERSION; + + if (unlikely(nla_put(skb, + NL80211_TESTMODE_STA_STATISTICS_VERSION, sizeof(u8), + &__tmp) < 0)) + goto nla_put_failure; + } + if (unlikely(nla_put(skb, + NL80211_TESTMODE_STA_STATISTICS_MAC, MAC_ADDR_LEN, + prParams->aucMacAddr) < 0)) + goto nla_put_failure; + { + u32 __tmp = u4LinkScore; + + if (unlikely(nla_put(skb, + NL80211_TESTMODE_STA_STATISTICS_LINK_SCORE, sizeof(u32), + &__tmp) < 0)) + goto nla_put_failure; + } + + { + u32 __tmp = rQueryStaStatistics.u4Flag; + + if (unlikely(nla_put(skb, + NL80211_TESTMODE_STA_STATISTICS_FLAG, sizeof(u32), + &__tmp) < 0)) + goto nla_put_failure; + } + { + u32 __tmp = rQueryStaStatistics.u4EnqueueCounter; + + if (unlikely(nla_put(skb, + NL80211_TESTMODE_STA_STATISTICS_ENQUEUE, sizeof(u32), + &__tmp) < 0)) + goto nla_put_failure; + } + { + u32 __tmp = rQueryStaStatistics.u4DequeueCounter; + + if (unlikely(nla_put(skb, + NL80211_TESTMODE_STA_STATISTICS_DEQUEUE, sizeof(u32), + &__tmp) < 0)) + goto nla_put_failure; + } + { + u32 __tmp = rQueryStaStatistics.u4EnqueueStaCounter; + + if (unlikely(nla_put(skb, + NL80211_TESTMODE_STA_STATISTICS_STA_ENQUEUE, sizeof(u32), + &__tmp) < 0)) + goto nla_put_failure; + } + { + u32 __tmp = rQueryStaStatistics.u4DequeueStaCounter; + + if (unlikely(nla_put(skb, + NL80211_TESTMODE_STA_STATISTICS_STA_DEQUEUE, sizeof(u32), + &__tmp) < 0)) + goto nla_put_failure; + } + { + u32 __tmp = rQueryStaStatistics.IsrCnt; + + if (unlikely(nla_put(skb, + NL80211_TESTMODE_STA_STATISTICS_IRQ_ISR_CNT, sizeof(u32), + &__tmp) < 0)) + goto nla_put_failure; + } + + { + u32 __tmp = rQueryStaStatistics.IsrPassCnt; + + if (unlikely(nla_put(skb, + NL80211_TESTMODE_STA_STATISTICS_IRQ_ISR_PASS_CNT, + sizeof(u32), &__tmp) < 0)) + goto nla_put_failure; + } + + { + u32 __tmp = rQueryStaStatistics.TaskIsrCnt; + + if (unlikely(nla_put(skb, + NL80211_TESTMODE_STA_STATISTICS_IRQ_TASK_CNT, sizeof(u32), + &__tmp) < 0)) + goto nla_put_failure; + } + + { + u32 __tmp = rQueryStaStatistics.IsrAbnormalCnt; + + if (unlikely(nla_put(skb, + NL80211_TESTMODE_STA_STATISTICS_IRQ_AB_CNT, sizeof(u32), + &__tmp) < 0)) + goto nla_put_failure; + } + + { + u32 __tmp = rQueryStaStatistics.IsrSoftWareCnt; + + if (unlikely(nla_put(skb, + NL80211_TESTMODE_STA_STATISTICS_IRQ_SW_CNT, sizeof(u32), + &__tmp) < 0)) + goto nla_put_failure; + } + + { + u32 __tmp = rQueryStaStatistics.IsrTxCnt; + + if (unlikely(nla_put(skb, + NL80211_TESTMODE_STA_STATISTICS_IRQ_TX_CNT, sizeof(u32), + &__tmp) < 0)) + goto nla_put_failure; + } + + { + u32 __tmp = rQueryStaStatistics.IsrRxCnt; + + if (unlikely(nla_put(skb, + NL80211_TESTMODE_STA_STATISTICS_IRQ_RX_CNT, sizeof(u32), + &__tmp) < 0)) + goto nla_put_failure; + } + + /* FW part STA link status */ + { + u8 __tmp = rQueryStaStatistics.ucPer; + + if (unlikely(nla_put(skb, + NL80211_TESTMODE_STA_STATISTICS_PER, sizeof(u8), + &__tmp) < 0)) + goto nla_put_failure; + } + { + u8 __tmp = rQueryStaStatistics.ucRcpi; + + if (unlikely(nla_put(skb, + NL80211_TESTMODE_STA_STATISTICS_RSSI, sizeof(u8), + &__tmp) < 0)) + goto nla_put_failure; + } + { + u32 __tmp = rQueryStaStatistics.u4PhyMode; + + if (unlikely(nla_put(skb, + NL80211_TESTMODE_STA_STATISTICS_PHY_MODE, sizeof(u32), + &__tmp) < 0)) + goto nla_put_failure; + } + { + u16 __tmp = rQueryStaStatistics.u2LinkSpeed; + + if (unlikely(nla_put(skb, + NL80211_TESTMODE_STA_STATISTICS_TX_RATE, sizeof(u16), + &__tmp) < 0)) + goto nla_put_failure; + } + { + u32 __tmp = rQueryStaStatistics.u4TxFailCount; + + if (unlikely(nla_put(skb, + NL80211_TESTMODE_STA_STATISTICS_FAIL_CNT, sizeof(u32), + &__tmp) < 0)) + goto nla_put_failure; + } + { + u32 __tmp = rQueryStaStatistics.u4TxLifeTimeoutCount; + + if (unlikely(nla_put(skb, + NL80211_TESTMODE_STA_STATISTICS_TIMEOUT_CNT, sizeof(u32), + &__tmp) < 0)) + goto nla_put_failure; + } + { + u32 __tmp = rQueryStaStatistics.u4TxAverageAirTime; + + if (unlikely(nla_put(skb, + NL80211_TESTMODE_STA_STATISTICS_AVG_AIR_TIME, sizeof(u32), + &__tmp) < 0)) + goto nla_put_failure; + } + + /* Driver part link status */ + { + u32 __tmp = rQueryStaStatistics.u4TxTotalCount; + + if (unlikely(nla_put(skb, + NL80211_TESTMODE_STA_STATISTICS_TOTAL_CNT, sizeof(u32), + &__tmp) < 0)) + goto nla_put_failure; + } + { + u32 __tmp = rQueryStaStatistics.u4TxExceedThresholdCount; + + if (unlikely(nla_put(skb, + NL80211_TESTMODE_STA_STATISTICS_THRESHOLD_CNT, sizeof(u32), + &__tmp) < 0)) + goto nla_put_failure; + } + { + u32 __tmp = rQueryStaStatistics.u4TxAverageProcessTime; + + if (unlikely(nla_put(skb, + NL80211_TESTMODE_STA_STATISTICS_AVG_PROCESS_TIME, + sizeof(u32), &__tmp) < 0)) + goto nla_put_failure; + } + { + u32 __tmp = rQueryStaStatistics.u4TxMaxTime; + + if (unlikely(nla_put(skb, + NL80211_TESTMODE_STA_STATISTICS_MAX_PROCESS_TIME, + sizeof(u32), &__tmp) < 0)) + goto nla_put_failure; + } + { + u32 __tmp = rQueryStaStatistics.u4TxAverageHifTime; + + if (unlikely(nla_put(skb, + NL80211_TESTMODE_STA_STATISTICS_AVG_HIF_PROCESS_TIME, + sizeof(u32), &__tmp) < 0)) + goto nla_put_failure; + } + { + u32 __tmp = rQueryStaStatistics.u4TxMaxHifTime; + + if (unlikely(nla_put(skb, + NL80211_TESTMODE_STA_STATISTICS_MAX_HIF_PROCESS_TIME, + sizeof(u32), &__tmp) < 0)) + goto nla_put_failure; + } + + /* Network counter */ + if (unlikely(nla_put(skb, + NL80211_TESTMODE_STA_STATISTICS_TC_EMPTY_CNT_ARRAY, + sizeof(rQueryStaStatistics.au4TcResourceEmptyCount), + rQueryStaStatistics.au4TcResourceEmptyCount) < 0)) + goto nla_put_failure; + + if (unlikely(nla_put(skb, + NL80211_TESTMODE_STA_STATISTICS_NO_TC_ARRAY, + sizeof(rQueryStaStatistics.au4DequeueNoTcResource), + rQueryStaStatistics.au4DequeueNoTcResource) < 0)) + goto nla_put_failure; + + if (unlikely(nla_put(skb, + NL80211_TESTMODE_STA_STATISTICS_RB_ARRAY, + sizeof(rQueryStaStatistics.au4TcResourceBackCount), + rQueryStaStatistics.au4TcResourceBackCount) < 0)) + goto nla_put_failure; + + if (unlikely(nla_put(skb, + NL80211_TESTMODE_STA_STATISTICS_USED_TC_PGCT_ARRAY, + sizeof(rQueryStaStatistics.au4TcResourceUsedPageCount), + rQueryStaStatistics.au4TcResourceUsedPageCount) < 0)) + goto nla_put_failure; + + if (unlikely(nla_put(skb, + NL80211_TESTMODE_STA_STATISTICS_WANTED_TC_PGCT_ARRAY, + sizeof(rQueryStaStatistics.au4TcResourceWantedPageCount), + rQueryStaStatistics.au4TcResourceWantedPageCount) < 0)) + goto nla_put_failure; + + /* Sta queue length */ + if (unlikely(nla_put(skb, + NL80211_TESTMODE_STA_STATISTICS_TC_QUE_LEN_ARRAY, + sizeof(rQueryStaStatistics.au4TcQueLen), + rQueryStaStatistics.au4TcQueLen) < 0)) + goto nla_put_failure; + + /* Global QM counter */ + if (unlikely(nla_put(skb, + NL80211_TESTMODE_STA_STATISTICS_TC_AVG_QUE_LEN_ARRAY, + sizeof(rQueryStaStatistics.au4TcAverageQueLen), + rQueryStaStatistics.au4TcAverageQueLen) < 0)) + goto nla_put_failure; + + if (unlikely(nla_put(skb, + NL80211_TESTMODE_STA_STATISTICS_TC_CUR_QUE_LEN_ARRAY, + sizeof(rQueryStaStatistics.au4TcCurrentQueLen), + rQueryStaStatistics.au4TcCurrentQueLen) < 0)) + goto nla_put_failure; + + /* Reserved field */ + if (unlikely(nla_put(skb, + NL80211_TESTMODE_STA_STATISTICS_RESERVED_ARRAY, + sizeof(rQueryStaStatistics.au4Reserved), + rQueryStaStatistics.au4Reserved) < 0)) + goto nla_put_failure; + + return cfg80211_testmode_reply(skb); + +nla_put_failure: + /* nal_put_skb_fail */ + kfree_skb(skb); + return -EFAULT; +} + +int +mtk_cfg80211_testmode_get_link_detection(IN struct wiphy + *wiphy, + IN struct wireless_dev *wdev, + IN void *data, IN int len, + IN struct GLUE_INFO *prGlueInfo) +{ + + uint32_t rStatus = WLAN_STATUS_SUCCESS; + int32_t i4Status = -EINVAL; + uint32_t u4BufLen; + uint8_t u1buf = 0; + uint32_t i = 0; + uint32_t arBugReport[sizeof(struct EVENT_BUG_REPORT)]; + struct PARAM_802_11_STATISTICS_STRUCT rStatistics; + struct EVENT_BUG_REPORT *prBugReport; + struct sk_buff *skb; + + ASSERT(wiphy); + ASSERT(prGlueInfo); + + prBugReport = (struct EVENT_BUG_REPORT *) kalMemAlloc( + sizeof(struct EVENT_BUG_REPORT), VIR_MEM_TYPE); + if (!prBugReport) { + DBGLOG(QM, TRACE, "%s allocate prBugReport failed\n", + __func__); + return -ENOMEM; + } + skb = cfg80211_testmode_alloc_reply_skb(wiphy, + sizeof(struct PARAM_802_11_STATISTICS_STRUCT) + + sizeof(struct EVENT_BUG_REPORT) + 1); + + if (!skb) { + kalMemFree(prBugReport, VIR_MEM_TYPE, + sizeof(struct EVENT_BUG_REPORT)); + DBGLOG(QM, TRACE, "%s allocate skb failed\n", __func__); + return -ENOMEM; + } + + kalMemZero(&rStatistics, sizeof(rStatistics)); + kalMemZero(prBugReport, sizeof(struct EVENT_BUG_REPORT)); + kalMemZero(arBugReport, sizeof(struct EVENT_BUG_REPORT)); + + rStatus = kalIoctl(prGlueInfo, + wlanoidQueryStatistics, + &rStatistics, sizeof(rStatistics), + TRUE, TRUE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(INIT, INFO, "query statistics error:%x\n", rStatus); + + rStatus = kalIoctl(prGlueInfo, + wlanoidQueryBugReport, + prBugReport, sizeof(struct EVENT_BUG_REPORT), + TRUE, TRUE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(INIT, INFO, "query statistics error:%x\n", rStatus); + + kalMemCopy(arBugReport, prBugReport, + sizeof(struct EVENT_BUG_REPORT)); + + rStatistics.u4RstReason = glGetRstReason(); + rStatistics.u8RstTime = u8ResetTime; + rStatistics.u4RoamFailCnt = prGlueInfo->u4RoamFailCnt; + rStatistics.u8RoamFailTime = prGlueInfo->u8RoamFailTime; + rStatistics.u2TxDoneDelayIsARP = + prGlueInfo->fgTxDoneDelayIsARP; + rStatistics.u4ArriveDrvTick = prGlueInfo->u4ArriveDrvTick; + rStatistics.u4EnQueTick = prGlueInfo->u4EnQueTick; + rStatistics.u4DeQueTick = prGlueInfo->u4DeQueTick; + rStatistics.u4LeaveDrvTick = prGlueInfo->u4LeaveDrvTick; + rStatistics.u4CurrTick = prGlueInfo->u4CurrTick; + rStatistics.u8CurrTime = prGlueInfo->u8CurrTime; + + if (!NLA_PUT_U8(skb, NL80211_TESTMODE_LINK_INVALID, &u1buf)) + goto nla_put_failure; + + if (!NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_TX_FAIL_CNT, + &rStatistics.rFailedCount.QuadPart)) + goto nla_put_failure; + + if (!NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_TX_RETRY_CNT, + &rStatistics.rRetryCount.QuadPart)) + goto nla_put_failure; + + if (!NLA_PUT_U64(skb, + NL80211_TESTMODE_LINK_TX_MULTI_RETRY_CNT, + &rStatistics.rMultipleRetryCount.QuadPart)) + goto nla_put_failure; + + if (!NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_ACK_FAIL_CNT, + &rStatistics.rACKFailureCount.QuadPart)) + goto nla_put_failure; + + if (!NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_FCS_ERR_CNT, + &rStatistics.rFCSErrorCount.QuadPart)) + goto nla_put_failure; + + if (!NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_TX_CNT, + &rStatistics.rTransmittedFragmentCount.QuadPart)) + goto nla_put_failure; + + if (!NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_RX_CNT, + &rStatistics.rReceivedFragmentCount.QuadPart)) + goto nla_put_failure; + + if (!NLA_PUT_U32(skb, NL80211_TESTMODE_LINK_RST_REASON, + &rStatistics.u4RstReason)) + goto nla_put_failure; + + if (!NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_RST_TIME, + &rStatistics.u8RstTime)) + goto nla_put_failure; + + if (!NLA_PUT_U32(skb, NL80211_TESTMODE_LINK_ROAM_FAIL_TIMES, + &rStatistics.u4RoamFailCnt)) + goto nla_put_failure; + + if (!NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_ROAM_FAIL_TIME, + &rStatistics.u8RoamFailTime)) + goto nla_put_failure; + + if (!NLA_PUT_U8(skb, + NL80211_TESTMODE_LINK_TX_DONE_DELAY_IS_ARP, + &rStatistics.u2TxDoneDelayIsARP)) + goto nla_put_failure; + + if (!NLA_PUT_U32(skb, NL80211_TESTMODE_LINK_ARRIVE_DRV_TICK, + &rStatistics.u4ArriveDrvTick)) + goto nla_put_failure; + + if (!NLA_PUT_U32(skb, NL80211_TESTMODE_LINK_ENQUE_TICK, + &rStatistics.u4EnQueTick)) + goto nla_put_failure; + + if (!NLA_PUT_U32(skb, NL80211_TESTMODE_LINK_DEQUE_TICK, + &rStatistics.u4DeQueTick)) + goto nla_put_failure; + + if (!NLA_PUT_U32(skb, NL80211_TESTMODE_LINK_LEAVE_DRV_TICK, + &rStatistics.u4LeaveDrvTick)) + goto nla_put_failure; + + if (!NLA_PUT_U32(skb, NL80211_TESTMODE_LINK_CURR_TICK, + &rStatistics.u4CurrTick)) + goto nla_put_failure; + + if (!NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_CURR_TIME, + &rStatistics.u8CurrTime)) + goto nla_put_failure; + + for (i = 0; + i < sizeof(struct EVENT_BUG_REPORT) / sizeof(uint32_t); + i++) { + if (!NLA_PUT_U32(skb, i + NL80211_TESTMODE_LINK_DETECT_NUM, + &arBugReport[i])) + goto nla_put_failure; + } + + i4Status = cfg80211_testmode_reply(skb); + kalMemFree(prBugReport, VIR_MEM_TYPE, + sizeof(struct EVENT_BUG_REPORT)); + return i4Status; + +nla_put_failure: + /* nal_put_skb_fail */ + kfree_skb(skb); + kalMemFree(prBugReport, VIR_MEM_TYPE, + sizeof(struct EVENT_BUG_REPORT)); + return -EFAULT; +} + +int mtk_cfg80211_testmode_sw_cmd(IN struct wiphy *wiphy, + IN struct wireless_dev *wdev, + IN void *data, IN int len) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct NL80211_DRIVER_SW_CMD_PARAMS *prParams = + (struct NL80211_DRIVER_SW_CMD_PARAMS *) NULL; + uint32_t rstatus = WLAN_STATUS_SUCCESS; + int fgIsValid = 0; + uint32_t u4SetInfoLen = 0; + + ASSERT(wiphy); + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + +#if 0 + DBGLOG(INIT, INFO, "--> %s()\n", __func__); +#endif + + if (data && len) + prParams = (struct NL80211_DRIVER_SW_CMD_PARAMS *) data; + + if (prParams) { + if (prParams->set == 1) { + rstatus = kalIoctl(prGlueInfo, + (PFN_OID_HANDLER_FUNC) wlanoidSetSwCtrlWrite, + &prParams->adr, (uint32_t) 8, + FALSE, FALSE, TRUE, &u4SetInfoLen); + } + } + + if (rstatus != WLAN_STATUS_SUCCESS) + fgIsValid = -EFAULT; + + return fgIsValid; +} + +static int mtk_wlan_cfg_testmode_cmd(struct wiphy *wiphy, + struct wireless_dev *wdev, + void *data, int len) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct NL80211_DRIVER_TEST_MODE_PARAMS *prParams = NULL; + int32_t i4Status; + + ASSERT(wiphy); + + if (!data || !len) { + DBGLOG(REQ, ERROR, "mtk_cfg80211_testmode_cmd null data\n"); + return -EINVAL; + } + + if (!wiphy) { + DBGLOG(REQ, ERROR, + "mtk_cfg80211_testmode_cmd null wiphy\n"); + return -EINVAL; + } + + prGlueInfo = (struct GLUE_INFO *)wiphy_priv(wiphy); + prParams = (struct NL80211_DRIVER_TEST_MODE_PARAMS *)data; + + /* Clear the version byte */ + prParams->index = prParams->index & ~BITS(24, 31); + DBGLOG(INIT, TRACE, "params index=%x\n", prParams->index); + + switch (prParams->index) { + case TESTMODE_CMD_ID_SW_CMD: /* SW cmd */ + i4Status = mtk_cfg80211_testmode_sw_cmd(wiphy, + wdev, data, len); + break; + case TESTMODE_CMD_ID_WAPI: /* WAPI */ +#if CFG_SUPPORT_WAPI + i4Status = mtk_cfg80211_testmode_set_key_ext(wiphy, + wdev, data, len); +#endif + break; + case 0x10: + i4Status = mtk_cfg80211_testmode_get_sta_statistics(wiphy, + data, len, prGlueInfo); + break; + case 0x20: + i4Status = mtk_cfg80211_testmode_get_link_detection(wiphy, + wdev, data, len, prGlueInfo); + break; +#if CFG_SUPPORT_PASSPOINT + case TESTMODE_CMD_ID_HS20: + i4Status = mtk_cfg80211_testmode_hs20_cmd(wiphy, + wdev, data, len); + break; +#endif /* CFG_SUPPORT_PASSPOINT */ + case TESTMODE_CMD_ID_STR_CMD: + i4Status = mtk_cfg80211_process_str_cmd(wiphy, + wdev, data, len); + break; + + default: + i4Status = -EINVAL; + break; + } + + if (i4Status != 0) + DBGLOG(REQ, TRACE, "prParams->index=%d, status=%d\n", + prParams->index, i4Status); + + return i4Status; +} + +#if KERNEL_VERSION(3, 12, 0) <= CFG80211_VERSION_CODE +int mtk_cfg80211_testmode_cmd(struct wiphy *wiphy, + struct wireless_dev *wdev, + void *data, int len) +{ + ASSERT(wdev); + return mtk_wlan_cfg_testmode_cmd(wiphy, wdev, data, len); +} +#else +int mtk_cfg80211_testmode_cmd(struct wiphy *wiphy, + void *data, int len) +{ + return mtk_wlan_cfg_testmode_cmd(wiphy, NULL, data, len); +} +#endif +#endif + +#if CFG_SUPPORT_SCHED_SCAN +int mtk_cfg80211_sched_scan_start(IN struct wiphy *wiphy, + IN struct net_device *ndev, + IN struct cfg80211_sched_scan_request *request) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus; + uint32_t i, u4BufLen; + struct PARAM_SCHED_SCAN_REQUEST *prSchedScanRequest; + uint32_t num = 0; + uint8_t ucBssIndex = 0; + + ucBssIndex = wlanGetBssIdx(ndev); + if (!IS_BSS_INDEX_AIS(prGlueInfo->prAdapter, ucBssIndex)) + return -EINVAL; + + if (likely(request)) { + scanlog_dbg(LOG_SCHED_SCAN_REQ_START_K2D, INFO, "ssid(%d)match(%d)ch(%u)f(%u)rssi(%d)\n", + request->n_ssids, request->n_match_sets, + request->n_channels, request->flags, +#if KERNEL_VERSION(3, 15, 0) <= CFG80211_VERSION_CODE + request->min_rssi_thold); +#else + request->rssi_thold); +#endif + } else + scanlog_dbg(LOG_SCHED_SCAN_REQ_START_K2D, INFO, "--> %s()\n", + __func__); + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + ASSERT(prGlueInfo); + + if (prGlueInfo->prAdapter == NULL) { + DBGLOG(REQ, ERROR, "prGlueInfo->prAdapter is NULL"); + return -EINVAL; + } + +#if CFG_SUPPORT_LOWLATENCY_MODE + if (!prGlueInfo->prAdapter->fgEnCfg80211Scan + && MEDIA_STATE_CONNECTED + == kalGetMediaStateIndicated(prGlueInfo, ucBssIndex)) { + DBGLOG(REQ, INFO, + "sched_scan_start LowLatency reject scan\n"); + return -EBUSY; + } +#endif /* CFG_SUPPORT_LOWLATENCY_MODE */ + + if (prGlueInfo->prSchedScanRequest != NULL) { + DBGLOG(SCN, ERROR, + "GlueInfo->prSchedScanRequest != NULL\n"); + return -EBUSY; + } else if (request == NULL) { + DBGLOG(SCN, ERROR, "request == NULL\n"); + return -EINVAL; + } else if (!request->n_match_sets) { + /* invalid scheduled scan request */ + DBGLOG(SCN, ERROR, + "No match sets. No need to do sched scan\n"); + return -EINVAL; + } else if (request->n_match_sets > + CFG_SCAN_SSID_MATCH_MAX_NUM) { + DBGLOG(SCN, WARN, "request->n_match_sets(%d) > %d\n", + request->n_match_sets, + CFG_SCAN_SSID_MATCH_MAX_NUM); + return -EINVAL; + } else if (request->n_ssids > + CFG_SCAN_HIDDEN_SSID_MAX_NUM) { + DBGLOG(SCN, WARN, "request->n_ssids(%d) > %d\n", + request->n_ssids, CFG_SCAN_HIDDEN_SSID_MAX_NUM); + return -EINVAL; + } + + prSchedScanRequest = (struct PARAM_SCHED_SCAN_REQUEST *) + kalMemAlloc(sizeof(struct PARAM_SCHED_SCAN_REQUEST), + VIR_MEM_TYPE); + if (prSchedScanRequest == NULL) { + DBGLOG(SCN, ERROR, "prSchedScanRequest kalMemAlloc fail\n"); + return -ENOMEM; + } + kalMemZero(prSchedScanRequest, + sizeof(struct PARAM_SCHED_SCAN_REQUEST)); + + /* passed in the probe_reqs in active scans */ + if (request->ssids) { + for (i = 0; i < request->n_ssids; i++) { + DBGLOG(SCN, TRACE, "ssids : (%d)[%s]\n", + i, request->ssids[i].ssid); + /* driver ignored the null ssid */ + if (request->ssids[i].ssid_len == 0 + || request->ssids[i].ssid[0] == 0) + DBGLOG(SCN, TRACE, "ignore null ssid(%d)\n", i); + else { + struct PARAM_SSID *prSsid; + + prSsid = &(prSchedScanRequest->arSsid[num]); + COPY_SSID(prSsid->aucSsid, prSsid->u4SsidLen, + request->ssids[i].ssid, + request->ssids[i].ssid_len); + num++; + } + } + } + prSchedScanRequest->u4SsidNum = num; +#if KERNEL_VERSION(3, 15, 0) <= CFG80211_VERSION_CODE + prSchedScanRequest->i4MinRssiThold = + request->min_rssi_thold; +#else + prSchedScanRequest->i4MinRssiThold = request->rssi_thold; +#endif + + num = 0; + if (request->match_sets) { + for (i = 0; i < request->n_match_sets; i++) { + DBGLOG(SCN, TRACE, "match : (%d)[%s]\n", i, + request->match_sets[i].ssid.ssid); + /* driver ignored the null ssid */ + if (request->match_sets[i].ssid.ssid_len == 0 + || request->match_sets[i].ssid.ssid[0] == 0) + DBGLOG(SCN, TRACE, "ignore null ssid(%d)\n", i); + else { + struct PARAM_SSID *prSsid = + &(prSchedScanRequest->arMatchSsid[num]); + + COPY_SSID(prSsid->aucSsid, + prSsid->u4SsidLen, + request->match_sets[i].ssid.ssid, + request->match_sets[i].ssid.ssid_len); +#if KERNEL_VERSION(3, 15, 0) <= CFG80211_VERSION_CODE + prSchedScanRequest->ai4RssiThold[i] = + request->match_sets[i].rssi_thold; +#else + prSchedScanRequest->ai4RssiThold[i] = + request->rssi_thold; +#endif + num++; + } + } + } + prSchedScanRequest->u4MatchSsidNum = num; + + if (kalSchedScanParseRandomMac(ndev, request, + prSchedScanRequest->aucRandomMac, + prSchedScanRequest->aucRandomMacMask)) { + prSchedScanRequest->ucScnFuncMask |= ENUM_SCN_RANDOM_MAC_EN; + } + + prSchedScanRequest->u4IELength = request->ie_len; + if (request->ie_len > 0) { + prSchedScanRequest->pucIE = + kalMemAlloc(request->ie_len, VIR_MEM_TYPE); + if (prSchedScanRequest->pucIE == NULL) { + DBGLOG(SCN, ERROR, "pucIE kalMemAlloc fail\n"); + } else { + kalMemZero(prSchedScanRequest->pucIE, request->ie_len); + kalMemCopy(prSchedScanRequest->pucIE, + (uint8_t *)request->ie, request->ie_len); + } + } + +#if KERNEL_VERSION(4, 4, 0) <= CFG80211_VERSION_CODE + prSchedScanRequest->u2ScanInterval = + (uint16_t) (request->scan_plans->interval); +#else + prSchedScanRequest->u2ScanInterval = (uint16_t) ( + request->interval); +#endif + + prSchedScanRequest->ucChnlNum = (uint8_t) + request->n_channels; + prSchedScanRequest->pucChannels = + kalMemAlloc(request->n_channels, VIR_MEM_TYPE); + if (!prSchedScanRequest->pucChannels) { + DBGLOG(SCN, ERROR, "pucChannels kalMemAlloc fail\n"); + prSchedScanRequest->ucChnlNum = 0; + } else { + for (i = 0; i < request->n_channels; i++) { + uint32_t freq = + request->channels[i]->center_freq * 1000; + + prSchedScanRequest->pucChannels[i] = + nicFreq2ChannelNum(freq); + } + } + + prSchedScanRequest->ucBssIndex = ucBssIndex; + rStatus = kalIoctl(prGlueInfo, wlanoidSetStartSchedScan, + prSchedScanRequest, + sizeof(struct PARAM_SCHED_SCAN_REQUEST), + FALSE, FALSE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, WARN, "scheduled scan error:%x\n", rStatus); + kalMemFree(prSchedScanRequest->pucChannels, + VIR_MEM_TYPE, request->n_channels); + kalMemFree(prSchedScanRequest->pucIE, + VIR_MEM_TYPE, request->ie_len); + kalMemFree(prSchedScanRequest, + VIR_MEM_TYPE, sizeof(struct PARAM_SCHED_SCAN_REQUEST)); + return -EINVAL; + } + + /* prSchedScanRequest is owned by oid now, don't free it */ + + return 0; +} + +#if KERNEL_VERSION(4, 12, 0) <= CFG80211_VERSION_CODE +int mtk_cfg80211_sched_scan_stop(IN struct wiphy *wiphy, + IN struct net_device *ndev, + IN u64 reqid) +#else +int mtk_cfg80211_sched_scan_stop(IN struct wiphy *wiphy, + IN struct net_device *ndev) +#endif +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus; + uint32_t u4BufLen; + uint8_t ucBssIndex = 0; + + ucBssIndex = wlanGetBssIdx(ndev); + if (!IS_BSS_INDEX_VALID(ucBssIndex)) + return -EINVAL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + ASSERT(prGlueInfo); + + scanlog_dbg(LOG_SCHED_SCAN_REQ_STOP_K2D, INFO, "--> %s()\n", __func__); + + /* check if there is any pending scan/sched_scan not yet finished */ + if (prGlueInfo->prSchedScanRequest == NULL) + return -EPERM; /* Operation not permitted */ + + rStatus = kalIoctl(prGlueInfo, wlanoidSetStopSchedScan, + NULL, 0, + FALSE, FALSE, TRUE, &u4BufLen); + + if (rStatus == WLAN_STATUS_FAILURE) { + DBGLOG(REQ, WARN, "scheduled scan error in IoCtl:%x\n", + rStatus); + return 0; + } else if (rStatus == WLAN_STATUS_RESOURCES) { + DBGLOG(REQ, WARN, "scheduled scan error in Driver:%x\n", + rStatus); + return -EINVAL; + } + + return 0; +} +#endif /* CFG_SUPPORT_SCHED_SCAN */ + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is responsible for handling association request + * + * @param + * + * @retval 0: successful + * others: failure + */ +/*----------------------------------------------------------------------------*/ +int mtk_cfg80211_assoc(struct wiphy *wiphy, + struct net_device *ndev, struct cfg80211_assoc_request *req) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint8_t arBssid[PARAM_MAC_ADDR_LEN]; +#if CFG_SUPPORT_PASSPOINT + uint8_t *prDesiredIE = NULL; +#endif /* CFG_SUPPORT_PASSPOINT */ + uint32_t rStatus; + uint32_t u4BufLen; + uint8_t ucBssIndex = 0; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + ASSERT(prGlueInfo); + + ucBssIndex = wlanGetBssIdx(ndev); + if (!IS_BSS_INDEX_VALID(ucBssIndex)) + return -EINVAL; + + kalMemZero(arBssid, MAC_ADDR_LEN); + SET_IOCTL_BSSIDX(prGlueInfo->prAdapter, ucBssIndex); + wlanQueryInformation(prGlueInfo->prAdapter, wlanoidQueryBssid, + &arBssid[0], sizeof(arBssid), &u4BufLen); + + /* 1. check BSSID */ + if (UNEQUAL_MAC_ADDR(arBssid, req->bss->bssid)) { + /* wrong MAC address */ + DBGLOG(REQ, WARN, + "incorrect BSSID: [" MACSTR + "] currently connected BSSID[" + MACSTR "]\n", + MAC2STR(req->bss->bssid), MAC2STR(arBssid)); + return -ENOENT; + } + + if (req->ie && req->ie_len > 0) { +#if CFG_SUPPORT_PASSPOINT + if (wextSrchDesiredHS20IE((uint8_t *) req->ie, req->ie_len, + (uint8_t **) &prDesiredIE)) { + rStatus = kalIoctlByBssIdx(prGlueInfo, + wlanoidSetHS20Info, + prDesiredIE, IE_SIZE(prDesiredIE), + FALSE, FALSE, TRUE, &u4BufLen, + ucBssIndex); + if (rStatus != WLAN_STATUS_SUCCESS) { + /* DBGLOG(REQ, TRACE, + * ("[HS20] set HS20 assoc info error:%x\n", + * rStatus)); + */ + } + } +#endif /* CFG_SUPPORT_PASSPOINT */ + } + + rStatus = kalIoctlByBssIdx(prGlueInfo, wlanoidSetBssid, + (void *)req->bss->bssid, MAC_ADDR_LEN, + FALSE, FALSE, TRUE, &u4BufLen, + ucBssIndex); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, WARN, "set BSSID:%x\n", rStatus); + return -EINVAL; + } + + return 0; +} + +#if CFG_SUPPORT_NFC_BEAM_PLUS + +int mtk_cfg80211_testmode_get_scan_done(IN struct wiphy + *wiphy, IN void *data, IN int len, + IN struct GLUE_INFO *prGlueInfo) +{ + int32_t i4Status = -EINVAL; + +#ifdef CONFIG_NL80211_TESTMODE +#define NL80211_TESTMODE_P2P_SCANDONE_INVALID 0 +#define NL80211_TESTMODE_P2P_SCANDONE_STATUS 1 + + uint32_t rStatus = WLAN_STATUS_SUCCESS; + int32_t READY_TO_BEAM = 0; + + struct sk_buff *skb = NULL; + + ASSERT(wiphy); + ASSERT(prGlueInfo); + + skb = cfg80211_testmode_alloc_reply_skb(wiphy, + sizeof(uint32_t)); + + /* READY_TO_BEAM = + * (UINT_32)(prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo + * .fgIsGOInitialDone) + * &(!prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo + * .fgIsScanRequest); + */ + READY_TO_BEAM = 1; + /* DBGLOG(QM, TRACE, + * "NFC:GOInitialDone[%d] and P2PScanning[%d]\n", + * prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo + * .fgIsGOInitialDone, + * prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo + * .fgIsScanRequest)); + */ + + if (!skb) { + DBGLOG(QM, TRACE, "%s allocate skb failed:%x\n", __func__, + rStatus); + return -ENOMEM; + } + { + u8 __tmp = 0; + + if (unlikely(nla_put(skb, NL80211_TESTMODE_P2P_SCANDONE_INVALID, + sizeof(u8), &__tmp) < 0)) { + kfree_skb(skb); + return -EINVAL; + } + } + { + u32 __tmp = READY_TO_BEAM; + + if (unlikely(nla_put(skb, NL80211_TESTMODE_P2P_SCANDONE_STATUS, + sizeof(u32), &__tmp) < 0)) { + kfree_skb(skb); + return -EINVAL; + } + } + + i4Status = cfg80211_testmode_reply(skb); +#else + DBGLOG(QM, WARN, "CONFIG_NL80211_TESTMODE not enabled\n"); +#endif + return i4Status; +} + +#endif + +#if CFG_SUPPORT_TDLS + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is responsible for changing a station information + * + * @param + * + * @retval 0: successful + * others: failure + */ +/*----------------------------------------------------------------------------*/ +#if KERNEL_VERSION(3, 16, 0) <= CFG80211_VERSION_CODE +int +mtk_cfg80211_change_station(struct wiphy *wiphy, + struct net_device *ndev, const u8 *mac, + struct station_parameters *params) +{ + + /* return 0; */ + + /* from supplicant -- wpa_supplicant_tdls_peer_addset() */ + struct GLUE_INFO *prGlueInfo = NULL; + struct CMD_PEER_UPDATE rCmdUpdate; + uint32_t rStatus; + uint32_t u4BufLen, u4Temp; + struct ADAPTER *prAdapter; + struct BSS_INFO *prBssInfo; + uint8_t ucBssIndex = 0; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + ASSERT(prGlueInfo); + + ucBssIndex = wlanGetBssIdx(ndev); + if (!IS_BSS_INDEX_VALID(ucBssIndex)) + return -EINVAL; + + /* make up command */ + + prAdapter = prGlueInfo->prAdapter; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + ucBssIndex); + if (!prBssInfo || !params || !mac) + return -EINVAL; + + if ((params->sta_flags_set & BIT( + NL80211_STA_FLAG_AUTHORIZED))) { + rStatus = kalIoctl(prGlueInfo, wlanoidSetAuthorized, + (void *) mac, MAC_ADDR_LEN, FALSE, + FALSE, FALSE, &u4BufLen); + } + + if (params->supported_rates == NULL) + return 0; + + /* init */ + kalMemZero(&rCmdUpdate, sizeof(rCmdUpdate)); + kalMemCopy(rCmdUpdate.aucPeerMac, mac, 6); + + if (params->supported_rates != NULL) { + + u4Temp = params->supported_rates_len; + if (u4Temp > CMD_PEER_UPDATE_SUP_RATE_MAX) + u4Temp = CMD_PEER_UPDATE_SUP_RATE_MAX; + kalMemCopy(rCmdUpdate.aucSupRate, params->supported_rates, + u4Temp); + rCmdUpdate.u2SupRateLen = u4Temp; + } + + /* + * In supplicant, only recognize WLAN_EID_QOS 46, not 0xDD WMM + * So force to support UAPSD here. + */ + rCmdUpdate.UapsdBitmap = 0x0F; /*params->uapsd_queues; */ + rCmdUpdate.UapsdMaxSp = 0; /*params->max_sp; */ + + rCmdUpdate.u2Capability = params->capability; + + if (params->ext_capab != NULL) { + + u4Temp = params->ext_capab_len; + if (u4Temp > CMD_PEER_UPDATE_EXT_CAP_MAXLEN) + u4Temp = CMD_PEER_UPDATE_EXT_CAP_MAXLEN; + kalMemCopy(rCmdUpdate.aucExtCap, params->ext_capab, u4Temp); + rCmdUpdate.u2ExtCapLen = u4Temp; + } + + if (params->ht_capa != NULL) { + + rCmdUpdate.rHtCap.u2CapInfo = params->ht_capa->cap_info; + rCmdUpdate.rHtCap.ucAmpduParamsInfo = + params->ht_capa->ampdu_params_info; + rCmdUpdate.rHtCap.u2ExtHtCapInfo = + params->ht_capa->extended_ht_cap_info; + rCmdUpdate.rHtCap.u4TxBfCapInfo = + params->ht_capa->tx_BF_cap_info; + rCmdUpdate.rHtCap.ucAntennaSelInfo = + params->ht_capa->antenna_selection_info; + kalMemCopy(rCmdUpdate.rHtCap.rMCS.arRxMask, + params->ht_capa->mcs.rx_mask, + sizeof(rCmdUpdate.rHtCap.rMCS.arRxMask)); + + rCmdUpdate.rHtCap.rMCS.u2RxHighest = + params->ht_capa->mcs.rx_highest; + rCmdUpdate.rHtCap.rMCS.ucTxParams = + params->ht_capa->mcs.tx_params; + rCmdUpdate.fgIsSupHt = TRUE; + } + /* vht */ + + if (params->vht_capa != NULL) { + /* rCmdUpdate.rVHtCap */ + /* rCmdUpdate.rVHtCap */ + } + + /* update a TDLS peer record */ + /* sanity check */ + if ((params->sta_flags_set & BIT( + NL80211_STA_FLAG_TDLS_PEER))) + rCmdUpdate.eStaType = STA_TYPE_DLS_PEER; + rCmdUpdate.ucBssIdx = ucBssIndex; + rStatus = kalIoctl(prGlueInfo, cnmPeerUpdate, &rCmdUpdate, + sizeof(struct CMD_PEER_UPDATE), FALSE, FALSE, FALSE, + /* FALSE, //6628 -> 6630 fgIsP2pOid-> x */ + &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) + return -EINVAL; + /* for Ch Sw AP prohibit case */ + if (prBssInfo->fgTdlsIsChSwProhibited) { + /* disable TDLS ch sw function */ + + rStatus = kalIoctl(prGlueInfo, + TdlsSendChSwControlCmd, + &TdlsSendChSwControlCmd, + sizeof(struct CMD_TDLS_CH_SW), + FALSE, FALSE, FALSE, + /* FALSE, //6628 -> 6630 fgIsP2pOid-> x */ + &u4BufLen); + } + + return 0; +} +#else +int +mtk_cfg80211_change_station(struct wiphy *wiphy, + struct net_device *ndev, u8 *mac, + struct station_parameters *params) +{ + + /* return 0; */ + + /* from supplicant -- wpa_supplicant_tdls_peer_addset() */ + struct GLUE_INFO *prGlueInfo = NULL; + struct CMD_PEER_UPDATE rCmdUpdate; + uint32_t rStatus; + uint32_t u4BufLen, u4Temp; + struct ADAPTER *prAdapter; + struct BSS_INFO *prBssInfo; + uint8_t ucBssIndex = 0; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + ASSERT(prGlueInfo); + + ucBssIndex = wlanGetBssIdx(ndev); + if (!IS_BSS_INDEX_VALID(ucBssIndex)) + return -EINVAL; + + /* make up command */ + + prAdapter = prGlueInfo->prAdapter; + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + ucBssIndex); + if (!prBssInfo || !params || !mac) + return -EINVAL; + + if ((params->sta_flags_set & BIT( + NL80211_STA_FLAG_AUTHORIZED))) { + rStatus = kalIoctl(prGlueInfo, wlanoidSetAuthorized, + (void *) mac, MAC_ADDR_LEN, FALSE, + FALSE, FALSE, &u4BufLen); + } + + if (params->supported_rates == NULL) + return 0; + + /* init */ + kalMemZero(&rCmdUpdate, sizeof(rCmdUpdate)); + kalMemCopy(rCmdUpdate.aucPeerMac, mac, 6); + + if (params->supported_rates != NULL) { + + u4Temp = params->supported_rates_len; + if (u4Temp > CMD_PEER_UPDATE_SUP_RATE_MAX) + u4Temp = CMD_PEER_UPDATE_SUP_RATE_MAX; + kalMemCopy(rCmdUpdate.aucSupRate, params->supported_rates, + u4Temp); + rCmdUpdate.u2SupRateLen = u4Temp; + } + + /* + * In supplicant, only recognize WLAN_EID_QOS 46, not 0xDD WMM + * So force to support UAPSD here. + */ + rCmdUpdate.UapsdBitmap = 0x0F; /*params->uapsd_queues; */ + rCmdUpdate.UapsdMaxSp = 0; /*params->max_sp; */ + + rCmdUpdate.u2Capability = params->capability; + + if (params->ext_capab != NULL) { + + u4Temp = params->ext_capab_len; + if (u4Temp > CMD_PEER_UPDATE_EXT_CAP_MAXLEN) + u4Temp = CMD_PEER_UPDATE_EXT_CAP_MAXLEN; + kalMemCopy(rCmdUpdate.aucExtCap, params->ext_capab, u4Temp); + rCmdUpdate.u2ExtCapLen = u4Temp; + } + + if (params->ht_capa != NULL) { + + rCmdUpdate.rHtCap.u2CapInfo = params->ht_capa->cap_info; + rCmdUpdate.rHtCap.ucAmpduParamsInfo = + params->ht_capa->ampdu_params_info; + rCmdUpdate.rHtCap.u2ExtHtCapInfo = + params->ht_capa->extended_ht_cap_info; + rCmdUpdate.rHtCap.u4TxBfCapInfo = + params->ht_capa->tx_BF_cap_info; + rCmdUpdate.rHtCap.ucAntennaSelInfo = + params->ht_capa->antenna_selection_info; + kalMemCopy(rCmdUpdate.rHtCap.rMCS.arRxMask, + params->ht_capa->mcs.rx_mask, + sizeof(rCmdUpdate.rHtCap.rMCS.arRxMask)); + + rCmdUpdate.rHtCap.rMCS.u2RxHighest = + params->ht_capa->mcs.rx_highest; + rCmdUpdate.rHtCap.rMCS.ucTxParams = + params->ht_capa->mcs.tx_params; + rCmdUpdate.fgIsSupHt = TRUE; + } + /* vht */ + + if (params->vht_capa != NULL) { + /* rCmdUpdate.rVHtCap */ + /* rCmdUpdate.rVHtCap */ + } + + /* update a TDLS peer record */ + /* sanity check */ + if ((params->sta_flags_set & BIT( + NL80211_STA_FLAG_TDLS_PEER))) + rCmdUpdate.eStaType = STA_TYPE_DLS_PEER; + rCmdUpdate.ucBssIdx = ucBssIndex; + rStatus = kalIoctl(prGlueInfo, cnmPeerUpdate, &rCmdUpdate, + sizeof(struct CMD_PEER_UPDATE), FALSE, FALSE, FALSE, + /* FALSE, //6628 -> 6630 fgIsP2pOid-> x */ + &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) + return -EINVAL; + + /* for Ch Sw AP prohibit case */ + if (prBssInfo->fgTdlsIsChSwProhibited) { + /* disable TDLS ch sw function */ + + rStatus = kalIoctl(prGlueInfo, + TdlsSendChSwControlCmd, + &TdlsSendChSwControlCmd, + sizeof(struct CMD_TDLS_CH_SW), + FALSE, FALSE, FALSE, + /* FALSE, //6628 -> 6630 fgIsP2pOid-> x */ + &u4BufLen); + } + + return 0; +} +#endif +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is responsible for adding a station information + * + * @param + * + * @retval 0: successful + * others: failure + */ +/*----------------------------------------------------------------------------*/ +#if KERNEL_VERSION(3, 16, 0) <= CFG80211_VERSION_CODE +int mtk_cfg80211_add_station(struct wiphy *wiphy, + struct net_device *ndev, + const u8 *mac, struct station_parameters *params) +{ + /* return 0; */ + + /* from supplicant -- wpa_supplicant_tdls_peer_addset() */ + struct GLUE_INFO *prGlueInfo = NULL; + struct CMD_PEER_ADD rCmdCreate; + struct ADAPTER *prAdapter; + uint32_t rStatus; + uint32_t u4BufLen; + uint8_t ucBssIndex = 0; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + ASSERT(prGlueInfo); + + ucBssIndex = wlanGetBssIdx(ndev); + if (!IS_BSS_INDEX_VALID(ucBssIndex)) + return -EINVAL; + + /* make up command */ + + prAdapter = prGlueInfo->prAdapter; + + /* init */ + kalMemZero(&rCmdCreate, sizeof(rCmdCreate)); + kalMemCopy(rCmdCreate.aucPeerMac, mac, 6); + + /* create a TDLS peer record */ + if ((params->sta_flags_set & BIT( + NL80211_STA_FLAG_TDLS_PEER))) { + rCmdCreate.eStaType = STA_TYPE_DLS_PEER; + rCmdCreate.ucBssIdx = ucBssIndex; + rStatus = kalIoctl(prGlueInfo, cnmPeerAdd, &rCmdCreate, + sizeof(struct CMD_PEER_ADD), + FALSE, FALSE, FALSE, + /* FALSE, //6628 -> 6630 fgIsP2pOid-> x */ + &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) + return -EINVAL; + } + + return 0; +} +#else +int mtk_cfg80211_add_station(struct wiphy *wiphy, + struct net_device *ndev, u8 *mac, + struct station_parameters *params) +{ + /* return 0; */ + + /* from supplicant -- wpa_supplicant_tdls_peer_addset() */ + struct GLUE_INFO *prGlueInfo = NULL; + struct CMD_PEER_ADD rCmdCreate; + struct ADAPTER *prAdapter; + uint32_t rStatus; + uint32_t u4BufLen; + uint8_t ucBssIndex = 0; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + ASSERT(prGlueInfo); + + ucBssIndex = wlanGetBssIdx(ndev); + if (!IS_BSS_INDEX_VALID(ucBssIndex)) + return -EINVAL; + + /* make up command */ + + prAdapter = prGlueInfo->prAdapter; + + /* init */ + kalMemZero(&rCmdCreate, sizeof(rCmdCreate)); + kalMemCopy(rCmdCreate.aucPeerMac, mac, 6); + + /* create a TDLS peer record */ + if ((params->sta_flags_set & BIT( + NL80211_STA_FLAG_TDLS_PEER))) { + rCmdCreate.eStaType = STA_TYPE_DLS_PEER; + rCmdCreate.ucBssIdx = ucBssIndex; + rStatus = kalIoctl(prGlueInfo, cnmPeerAdd, &rCmdCreate, + sizeof(struct CMD_PEER_ADD), + FALSE, FALSE, FALSE, + /* FALSE, //6628 -> 6630 fgIsP2pOid-> x */ + &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) + return -EINVAL; + } + + return 0; +} +#endif +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is responsible for deleting a station information + * + * @param + * + * @retval 0: successful + * others: failure + * + * @other + * must implement if you have add_station(). + */ +/*----------------------------------------------------------------------------*/ +#if KERNEL_VERSION(3, 16, 0) <= CFG80211_VERSION_CODE +#if KERNEL_VERSION(3, 19, 0) <= CFG80211_VERSION_CODE +static const u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; +int mtk_cfg80211_del_station(struct wiphy *wiphy, + struct net_device *ndev, + struct station_del_parameters *params) +{ + /* fgIsTDLSlinkEnable = 0; */ + + /* return 0; */ + /* from supplicant -- wpa_supplicant_tdls_peer_addset() */ + + const u8 *mac = params->mac ? params->mac : bcast_addr; + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter; + struct STA_RECORD *prStaRec; + u8 deleteMac[MAC_ADDR_LEN]; + uint8_t ucBssIndex = 0; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + ASSERT(prGlueInfo); + + ucBssIndex = wlanGetBssIdx(ndev); + if (!IS_BSS_INDEX_VALID(ucBssIndex)) + return -EINVAL; + + prAdapter = prGlueInfo->prAdapter; + + /* For kernel 3.18 modification, we trasfer to local buff to query + * sta + */ + memset(deleteMac, 0, MAC_ADDR_LEN); + memcpy(deleteMac, mac, MAC_ADDR_LEN); + + prStaRec = cnmGetStaRecByAddress(prAdapter, + (uint8_t) ucBssIndex, deleteMac); + + if (prStaRec != NULL) + cnmStaRecFree(prAdapter, prStaRec); + + return 0; +} +#else +int mtk_cfg80211_del_station(struct wiphy *wiphy, + struct net_device *ndev, const u8 *mac) +{ + /* fgIsTDLSlinkEnable = 0; */ + + /* return 0; */ + /* from supplicant -- wpa_supplicant_tdls_peer_addset() */ + + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter; + struct STA_RECORD *prStaRec; + u8 deleteMac[MAC_ADDR_LEN]; + uint8_t ucBssIndex = 0; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + ASSERT(prGlueInfo); + + ucBssIndex = wlanGetBssIdx(ndev); + if (!IS_BSS_INDEX_VALID(ucBssIndex)) + return -EINVAL; + + prAdapter = prGlueInfo->prAdapter; + + /* For kernel 3.18 modification, we trasfer to local buff to query + * sta + */ + memset(deleteMac, 0, MAC_ADDR_LEN); + memcpy(deleteMac, mac, MAC_ADDR_LEN); + + prStaRec = cnmGetStaRecByAddress(prAdapter, + (uint8_t) ucBssIndex, deleteMac); + + if (prStaRec != NULL) + cnmStaRecFree(prAdapter, prStaRec); + + return 0; +} +#endif +#else +int mtk_cfg80211_del_station(struct wiphy *wiphy, + struct net_device *ndev, u8 *mac) +{ + /* fgIsTDLSlinkEnable = 0; */ + + /* return 0; */ + /* from supplicant -- wpa_supplicant_tdls_peer_addset() */ + + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter; + struct STA_RECORD *prStaRec; + uint8_t ucBssIndex = 0; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + ASSERT(prGlueInfo); + + ucBssIndex = wlanGetBssIdx(ndev); + if (!IS_BSS_INDEX_VALID(ucBssIndex)) + return -EINVAL; + + prAdapter = prGlueInfo->prAdapter; + + prStaRec = cnmGetStaRecByAddress(prAdapter, + (uint8_t) ucBssIndex, mac); + + if (prStaRec != NULL) + cnmStaRecFree(prAdapter, prStaRec); + + return 0; +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to transmit a TDLS data frame from nl80211. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * \param[in] + * \param[in] + * \param[in] buf includes RSN IE + FT IE + Lifetimeout IE + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +#if KERNEL_VERSION(3, 18, 0) <= CFG80211_VERSION_CODE +int +mtk_cfg80211_tdls_mgmt(struct wiphy *wiphy, + struct net_device *dev, + const u8 *peer, u8 action_code, u8 dialog_token, + u16 status_code, u32 peer_capability, + bool initiator, const u8 *buf, size_t len) +{ + struct GLUE_INFO *prGlueInfo; + struct TDLS_CMD_LINK_MGT rCmdMgt; + uint32_t u4BufLen; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint8_t ucBssIndex = 0; + + ucBssIndex = wlanGetBssIdx(dev); + if (!IS_BSS_INDEX_VALID(ucBssIndex)) + return -EINVAL; + + /* sanity check */ + if ((wiphy == NULL) || (peer == NULL) || (buf == NULL)) + return -EINVAL; + + /* init */ + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + if (prGlueInfo == NULL) + return -EINVAL; + + kalMemZero(&rCmdMgt, sizeof(rCmdMgt)); + rCmdMgt.u2StatusCode = status_code; + rCmdMgt.u4SecBufLen = len; + rCmdMgt.ucDialogToken = dialog_token; + rCmdMgt.ucActionCode = action_code; + kalMemCopy(&(rCmdMgt.aucPeer), peer, 6); + + if (len > TDLS_SEC_BUF_LENGTH) { + DBGLOG(REQ, WARN, "%s:len > TDLS_SEC_BUF_LENGTH\n", __func__); + return -EINVAL; + } + + kalMemCopy(&(rCmdMgt.aucSecBuf), buf, len); + rCmdMgt.ucBssIdx = ucBssIndex; + rStatus = kalIoctl(prGlueInfo, TdlsexLinkMgt, &rCmdMgt, + sizeof(struct TDLS_CMD_LINK_MGT), FALSE, TRUE, FALSE, + &u4BufLen); + + DBGLOG(REQ, INFO, "rStatus: %x", rStatus); + + if (rStatus == WLAN_STATUS_SUCCESS) + return 0; + else + return -EINVAL; +} +#elif KERNEL_VERSION(3, 16, 0) <= CFG80211_VERSION_CODE +int +mtk_cfg80211_tdls_mgmt(struct wiphy *wiphy, + struct net_device *dev, + const u8 *peer, u8 action_code, u8 dialog_token, + u16 status_code, u32 peer_capability, + const u8 *buf, size_t len) +{ + struct GLUE_INFO *prGlueInfo; + struct TDLS_CMD_LINK_MGT rCmdMgt; + uint32_t u4BufLen; + uint8_t ucBssIndex = 0; + + ucBssIndex = wlanGetBssIdx(dev); + if (!IS_BSS_INDEX_VALID(ucBssIndex)) + return -EINVAL; + + /* sanity check */ + if ((wiphy == NULL) || (peer == NULL) || (buf == NULL)) + return -EINVAL; + + /* init */ + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + if (prGlueInfo == NULL) + return -EINVAL; + + kalMemZero(&rCmdMgt, sizeof(rCmdMgt)); + rCmdMgt.u2StatusCode = status_code; + rCmdMgt.u4SecBufLen = len; + rCmdMgt.ucDialogToken = dialog_token; + rCmdMgt.ucActionCode = action_code; + kalMemCopy(&(rCmdMgt.aucPeer), peer, 6); + kalMemCopy(&(rCmdMgt.aucSecBuf), buf, len); + rCmdMgt.ucBssIdx = ucBssIndex; + kalIoctl(prGlueInfo, TdlsexLinkMgt, &rCmdMgt, + sizeof(struct TDLS_CMD_LINK_MGT), FALSE, TRUE, FALSE, + &u4BufLen); + return 0; + +} + +#else +int +mtk_cfg80211_tdls_mgmt(struct wiphy *wiphy, + struct net_device *dev, + u8 *peer, u8 action_code, u8 dialog_token, + u16 status_code, const u8 *buf, size_t len) +{ + struct GLUE_INFO *prGlueInfo; + struct TDLS_CMD_LINK_MGT rCmdMgt; + uint32_t u4BufLen; + uint8_t ucBssIndex = 0; + + ucBssIndex = wlanGetBssIdx(dev); + if (!IS_BSS_INDEX_VALID(ucBssIndex)) + return -EINVAL; + + /* sanity check */ + if ((wiphy == NULL) || (peer == NULL) || (buf == NULL)) + return -EINVAL; + + /* init */ + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + if (prGlueInfo == NULL) + return -EINVAL; + + kalMemZero(&rCmdMgt, sizeof(rCmdMgt)); + rCmdMgt.u2StatusCode = status_code; + rCmdMgt.u4SecBufLen = len; + rCmdMgt.ucDialogToken = dialog_token; + rCmdMgt.ucActionCode = action_code; + kalMemCopy(&(rCmdMgt.aucPeer), peer, 6); + if (len > TDLS_SEC_BUF_LENGTH) + DBGLOG(REQ, WARN, + "In mtk_cfg80211_tdls_mgmt , len > TDLS_SEC_BUF_LENGTH, please check\n"); + else + kalMemCopy(&(rCmdMgt.aucSecBuf), buf, len); + rCmdMgt.ucBssIdx = ucBssIndex; + kalIoctl(prGlueInfo, TdlsexLinkMgt, &rCmdMgt, + sizeof(struct TDLS_CMD_LINK_MGT), FALSE, TRUE, FALSE, + &u4BufLen); + return 0; + +} +#endif +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to hadel TDLS link from nl80211. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * \param[in] + * \param[in] + * \param[in] buf includes RSN IE + FT IE + Lifetimeout IE + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +#if KERNEL_VERSION(3, 16, 0) <= CFG80211_VERSION_CODE +int mtk_cfg80211_tdls_oper(struct wiphy *wiphy, + struct net_device *dev, + const u8 *peer, enum nl80211_tdls_operation oper) +{ + + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t u4BufLen; + struct ADAPTER *prAdapter; + struct TDLS_CMD_LINK_OPER rCmdOper; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint8_t ucBssIndex = 0; + + ucBssIndex = wlanGetBssIdx(dev); + if (!IS_BSS_INDEX_VALID(ucBssIndex)) + return -EINVAL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + DBGLOG(REQ, INFO, "ucBssIndex = %d, oper=%d", + ucBssIndex, oper); + + ASSERT(prGlueInfo); + prAdapter = prGlueInfo->prAdapter; + + kalMemZero(&rCmdOper, sizeof(rCmdOper)); + kalMemCopy(rCmdOper.aucPeerMac, peer, 6); + + rCmdOper.oper = (enum ENUM_TDLS_LINK_OPER)oper; + rCmdOper.ucBssIdx = ucBssIndex; + rStatus = kalIoctl(prGlueInfo, TdlsexLinkOper, &rCmdOper, + sizeof(struct TDLS_CMD_LINK_OPER), FALSE, FALSE, FALSE, + &u4BufLen); + + DBGLOG(REQ, INFO, "rStatus: %x", rStatus); + + if (rStatus == WLAN_STATUS_SUCCESS) + return 0; + else + return -EINVAL; +} +#else +int mtk_cfg80211_tdls_oper(struct wiphy *wiphy, + struct net_device *dev, u8 *peer, + enum nl80211_tdls_operation oper) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t u4BufLen; + struct ADAPTER *prAdapter; + struct TDLS_CMD_LINK_OPER rCmdOper; + uint8_t ucBssIndex = 0; + + ucBssIndex = wlanGetBssIdx(dev); + if (!IS_BSS_INDEX_VALID(ucBssIndex)) + return -EINVAL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + ASSERT(prGlueInfo); + + DBGLOG(REQ, INFO, "ucBssIndex = %d, oper=%d", + ucBssIndex, oper); + + prAdapter = prGlueInfo->prAdapter; + + kalMemZero(&rCmdOper, sizeof(rCmdOper)); + kalMemCopy(rCmdOper.aucPeerMac, peer, 6); + + rCmdOper.oper = oper; + rCmdOper.ucBssIdx = ucBssIndex; + + kalIoctl(prGlueInfo, TdlsexLinkOper, &rCmdOper, + sizeof(struct TDLS_CMD_LINK_OPER), FALSE, FALSE, FALSE, + &u4BufLen); + return 0; +} +#endif +#endif + +#ifdef CONFIG_NL80211_TESTMODE +#if CFG_SUPPORT_NCHO +/* NCHO related command definition. Setting by supplicant */ +#define CMD_NCHO_ROAM_TRIGGER_GET "GETROAMTRIGGER" +#define CMD_NCHO_ROAM_TRIGGER_SET "SETROAMTRIGGER" +#define CMD_NCHO_ROAM_DELTA_GET "GETROAMDELTA" +#define CMD_NCHO_ROAM_DELTA_SET "SETROAMDELTA" +#define CMD_NCHO_ROAM_SCAN_PERIOD_GET "GETROAMSCANPERIOD" +#define CMD_NCHO_ROAM_SCAN_PERIOD_SET "SETROAMSCANPERIOD" +#define CMD_NCHO_ROAM_SCAN_CHANNELS_GET "GETROAMSCANCHANNELS" +#define CMD_NCHO_ROAM_SCAN_CHANNELS_SET "SETROAMSCANCHANNELS" +#define CMD_NCHO_ROAM_SCAN_CHANNELS_ADD "ADDROAMSCANCHANNELS" +#define CMD_NCHO_ROAM_SCAN_CONTROL_GET "GETROAMSCANCONTROL" +#define CMD_NCHO_ROAM_SCAN_CONTROL_SET "SETROAMSCANCONTROL" +#define CMD_NCHO_MODE_SET "SETNCHOMODE" +#define CMD_NCHO_MODE_GET "GETNCHOMODE" + +int testmode_set_ncho_roam_trigger(IN struct wiphy *wiphy, + IN char *pcCommand, IN int i4TotalLen) +{ + int32_t i4Param = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + int32_t i4Ret = -1; + uint32_t u4SetInfoLen = 0; + uint32_t rStatus = WLAN_STATUS_FAILURE; + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *)wiphy_priv(wiphy); + + DBGLOG(INIT, TRACE, "NCHO command is %s\n", pcCommand); + rStatus = wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + + if (rStatus == WLAN_STATUS_SUCCESS && i4Argc >= 2) { + DBGLOG(REQ, TRACE, "NCHO argc is %i, %s\n", i4Argc, apcArgv[1]); + i4Ret = kalkStrtos32(apcArgv[1], 0, &i4Param); + if (i4Ret) { + DBGLOG(REQ, ERROR, "NCHO parse u4Param error %d\n", + i4Ret); + return WLAN_STATUS_INVALID_DATA; + } + + DBGLOG(INIT, TRACE, "NCHO set roam trigger cmd %d\n", i4Param); + rStatus = kalIoctl(prGlueInfo, wlanoidSetNchoRoamTrigger, + &i4Param, sizeof(int32_t), + FALSE, FALSE, TRUE, &u4SetInfoLen); + + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(INIT, ERROR, "NCHO set roam trigger fail 0x%x\n", + rStatus); + else + DBGLOG(INIT, TRACE, + "NCHO set roam trigger successed\n"); + } else { + DBGLOG(REQ, ERROR, "NCHO set failed\n"); + rStatus = WLAN_STATUS_INVALID_DATA; + } + return rStatus; +} + +int testmode_get_ncho_roam_trigger(IN struct wiphy *wiphy, + IN char *pcCommand, IN int i4TotalLen) +{ + int32_t i4BytesWritten = -1; + int32_t i4Param = 0; + uint32_t u4BufLen = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = { 0 }; + uint32_t rStatus = WLAN_STATUS_FAILURE; + struct CMD_HEADER cmdV1Header; + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *)wiphy_priv(wiphy); + char buf[512]; + + DBGLOG(INIT, TRACE, "NCHO command is %s\n", pcCommand); + + rStatus = wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + if (rStatus != WLAN_STATUS_SUCCESS || i4Argc >= 2) { + DBGLOG(REQ, ERROR, "NCHO error input parameter %d\n", i4Argc); + return rStatus; + } + + rStatus = kalIoctl(prGlueInfo, wlanoidQueryNchoRoamTrigger, + &cmdV1Header, sizeof(cmdV1Header), + TRUE, TRUE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, ERROR, + "NCHO wlanoidQueryNchoRoamTrigger fail 0x%x\n", rStatus); + return rStatus; + } + + i4BytesWritten = kalkStrtou32(cmdV1Header.buffer, 0, &i4Param); + if (i4BytesWritten) { + DBGLOG(REQ, ERROR, "NCHO parse u4Param error %d!\n", + i4BytesWritten); + return WLAN_STATUS_NOT_INDICATING; + } + + i4Param = RCPI_TO_dBm(i4Param); /* RCPI to DB */ + i4BytesWritten = snprintf(buf, 512, + CMD_NCHO_ROAM_TRIGGER_GET" %d", i4Param); + DBGLOG(INIT, INFO, "NCHO query RoamTrigger is [%s][%s]\n", + cmdV1Header.buffer, pcCommand); + + return mtk_cfg80211_process_str_cmd_reply(wiphy, + buf, i4BytesWritten + 1); +} + +int testmode_set_ncho_roam_delta(IN struct wiphy *wiphy, + IN char *pcCommand, IN int i4TotalLen) +{ + int32_t i4Param = 0; + uint32_t u4SetInfoLen = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + int32_t i4Ret = -1; + uint32_t rStatus = WLAN_STATUS_FAILURE; + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *)wiphy_priv(wiphy); + + DBGLOG(INIT, TRACE, "NCHO command is %s\n", pcCommand); + rStatus = wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + + if (rStatus == WLAN_STATUS_SUCCESS && i4Argc >= 2) { + DBGLOG(REQ, TRACE, "NCHO argc is %i, %s\n", i4Argc, apcArgv[1]); + i4Ret = kalkStrtos32(apcArgv[1], 0, &i4Param); + if (i4Ret) { + DBGLOG(REQ, ERROR, + "NCHO parse u4Param error %d\n", i4Ret); + return WLAN_STATUS_INVALID_DATA; + } + + DBGLOG(INIT, TRACE, "NCHO set roam delta cmd %d\n", i4Param); + rStatus = kalIoctl(prGlueInfo, wlanoidSetNchoRoamDelta, + &i4Param, sizeof(int32_t), + FALSE, FALSE, TRUE, &u4SetInfoLen); + + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(INIT, ERROR, + "NCHO set roam delta fail 0x%x\n", rStatus); + else + DBGLOG(INIT, TRACE, "NCHO set roam delta successed\n"); + } else { + DBGLOG(REQ, ERROR, "NCHO set failed\n"); + rStatus = WLAN_STATUS_INVALID_DATA; + } + return rStatus; +} + +int testmode_get_ncho_roam_delta(IN struct wiphy *wiphy, + IN char *pcCommand, IN int i4TotalLen) +{ + int32_t i4BytesWritten = -1; + int32_t i4Param = 0; + uint32_t u4BufLen = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = { 0 }; + uint32_t rStatus = WLAN_STATUS_FAILURE; + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *)wiphy_priv(wiphy); + char buf[512]; + + DBGLOG(INIT, TRACE, "NCHO command is %s\n", pcCommand); + + rStatus = wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + if (rStatus != WLAN_STATUS_SUCCESS || i4Argc >= 2) { + DBGLOG(REQ, ERROR, "NCHO error input parameter %d\n", i4Argc); + return rStatus; + } + + rStatus = kalIoctl(prGlueInfo, wlanoidQueryNchoRoamDelta, + &i4Param, sizeof(int32_t), + TRUE, TRUE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, ERROR, + "NCHO wlanoidQueryNchoRoamDelta fail 0x%x\n", rStatus); + return rStatus; + } + + i4BytesWritten = snprintf(buf, 512, + CMD_NCHO_ROAM_DELTA_GET" %d", i4Param); + DBGLOG(REQ, TRACE, "NCHO query ok and ret is [%d][%s]\n", + i4Param, buf); + + return mtk_cfg80211_process_str_cmd_reply(wiphy, + buf, i4BytesWritten + 1); +} + +int testmode_set_ncho_roam_scn_period(IN struct wiphy *wiphy, + IN char *pcCommand, IN int i4TotalLen) +{ + uint32_t u4Param = 0; + uint32_t u4SetInfoLen = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + int32_t i4Ret = -1; + uint32_t rStatus = WLAN_STATUS_FAILURE; + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *)wiphy_priv(wiphy); + + DBGLOG(INIT, TRACE, "NCHO command is %s\n", pcCommand); + rStatus = wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + + if (rStatus == WLAN_STATUS_SUCCESS && i4Argc >= 2) { + DBGLOG(REQ, TRACE, "NCHO argc is %i, %s\n", i4Argc, apcArgv[1]); + i4Ret = kalkStrtou32(apcArgv[1], 0, &u4Param); + if (i4Ret) { + DBGLOG(REQ, ERROR, "NCHO parse u4Param error %d\n", + i4Ret); + return -1; + } + + DBGLOG(INIT, TRACE, "NCHO set roam period cmd %d\n", u4Param); + rStatus = kalIoctl(prGlueInfo, wlanoidSetNchoRoamScnPeriod, + &u4Param, sizeof(uint32_t), + FALSE, FALSE, TRUE, &u4SetInfoLen); + + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(INIT, ERROR, "NCHO set roam period fail 0x%x\n", + rStatus); + else + DBGLOG(INIT, TRACE, "NCHO set roam period successed\n"); + } else { + DBGLOG(REQ, ERROR, "NCHO set failed\n"); + rStatus = WLAN_STATUS_INVALID_DATA; + } + return rStatus; +} + +int testmode_get_ncho_roam_scn_period(IN struct wiphy *wiphy, + IN char *pcCommand, IN int i4TotalLen) +{ + int32_t i4BytesWritten = -1; + int32_t i4Param = 0; + uint32_t u4BufLen = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = { 0 }; + uint32_t rStatus = WLAN_STATUS_FAILURE; + struct CMD_HEADER cmdV1Header; + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *)wiphy_priv(wiphy); + char buf[512]; + + DBGLOG(INIT, TRACE, "NCHO command is %s\n", pcCommand); + + rStatus = wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + if (rStatus != WLAN_STATUS_SUCCESS || i4Argc >= 2) { + DBGLOG(REQ, ERROR, "NCHO error input parameter %d\n", i4Argc); + return rStatus; + } + + rStatus = kalIoctl(prGlueInfo, wlanoidQueryNchoRoamScnPeriod, + &cmdV1Header, sizeof(cmdV1Header), + TRUE, TRUE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, ERROR, + "NCHO wlanoidQueryNchoRoamTrigger fail 0x%x\n", rStatus); + return rStatus; + } + + i4BytesWritten = kalkStrtou32(cmdV1Header.buffer, 0, &i4Param); + if (i4BytesWritten) { + DBGLOG(REQ, ERROR, "NCHO parse u4Param error %d!\n", + i4BytesWritten); + return WLAN_STATUS_NOT_INDICATING; + } + + i4BytesWritten = snprintf(buf, 512, + CMD_NCHO_ROAM_SCAN_PERIOD_GET" %d", i4Param); + DBGLOG(INIT, INFO, "NCHO query Roam Period is [%s][%s]\n", + cmdV1Header.buffer, buf); + + return mtk_cfg80211_process_str_cmd_reply(wiphy, + buf, i4BytesWritten + 1); +} + +int testmode_set_ncho_roam_scn_chnl(IN struct wiphy *wiphy, + IN char *pcCommand, IN int i4TotalLen, IN uint8_t changeMode) +{ + uint32_t u4ChnlInfo = 0; + uint8_t i = 1; + uint8_t t = 0; + uint32_t u4SetInfoLen = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + int32_t i4Ret = -1; + uint32_t rStatus = WLAN_STATUS_FAILURE; + struct CFG_NCHO_SCAN_CHNL rRoamScnChnl; + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *)wiphy_priv(wiphy); + + DBGLOG(INIT, TRACE, "NCHO command is %s\n", pcCommand); + rStatus = wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + + if (rStatus == WLAN_STATUS_SUCCESS && i4Argc >= 2) { + DBGLOG(REQ, TRACE, "NCHO argc is %i, cmd is %s\n", i4Argc, + apcArgv[1]); + i4Ret = kalkStrtou32(apcArgv[1], 0, &u4ChnlInfo); + if (i4Ret) { + DBGLOG(REQ, ERROR, "NCHO parse u4Param error %d\n", + i4Ret); + return WLAN_STATUS_INVALID_DATA; + } + + rRoamScnChnl.ucChannelListNum = u4ChnlInfo; + DBGLOG(REQ, INFO, "NCHO ChannelListNum is %d\n", u4ChnlInfo); + if (i4Argc != u4ChnlInfo + 2) { + DBGLOG(REQ, ERROR, "NCHO param mismatch %d\n", + u4ChnlInfo); + return WLAN_STATUS_INVALID_DATA; + } + for (i = 2; i < i4Argc; i++) { + i4Ret = kalkStrtou32(apcArgv[i], 0, &u4ChnlInfo); + if (i4Ret) { + while (i != 2) { + rRoamScnChnl.arChnlInfoList[i] + .ucChannelNum = 0; + i--; + } + DBGLOG(REQ, ERROR, + "NCHO parse chnl num error %d\n", i4Ret); + return -1; + } + if (u4ChnlInfo != 0) { + DBGLOG(INIT, TRACE, + "NCHO t = %d, channel value=%d\n", + t, u4ChnlInfo); + if ((u4ChnlInfo >= 1) && (u4ChnlInfo <= 14)) + rRoamScnChnl.arChnlInfoList[t].eBand = + BAND_2G4; + else + rRoamScnChnl.arChnlInfoList[t].eBand = + BAND_5G; + + rRoamScnChnl.arChnlInfoList[t].ucChannelNum = + u4ChnlInfo; + t++; + } + + } + + DBGLOG(INIT, TRACE, "NCHO %s roam scan channel cmd\n", + changeMode ? "set" : "add"); + if (changeMode) + rStatus = kalIoctl(prGlueInfo, + wlanoidSetNchoRoamScnChnl, &rRoamScnChnl, + sizeof(struct CFG_NCHO_SCAN_CHNL), + FALSE, FALSE, TRUE, &u4SetInfoLen); + else + rStatus = kalIoctl(prGlueInfo, + wlanoidAddNchoRoamScnChnl, &rRoamScnChnl, + sizeof(struct CFG_NCHO_SCAN_CHNL), + FALSE, FALSE, TRUE, &u4SetInfoLen); + + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(INIT, ERROR, + "NCHO set roam scan channel fail 0x%x\n", + rStatus); + else + DBGLOG(INIT, TRACE, + "NCHO set roam scan channel successed\n"); + } else { + DBGLOG(REQ, ERROR, "NCHO set failed\n"); + rStatus = WLAN_STATUS_INVALID_DATA; + } + return rStatus; +} + +int testmode_get_ncho_roam_scn_chnl(IN struct wiphy *wiphy, + IN char *pcCommand, IN int i4TotalLen) +{ + uint8_t i = 0; + uint32_t u4BufLen = 0; + int32_t i4BytesWritten = -1; + int32_t i4Argc = 0; + uint32_t u4ChnlInfo = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = { 0 }; + struct CFG_NCHO_SCAN_CHNL rRoamScnChnl; + uint32_t rStatus = WLAN_STATUS_FAILURE; + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *)wiphy_priv(wiphy); + char buf[512]; + + DBGLOG(INIT, TRACE, "NCHO command is %s\n", pcCommand); + + rStatus = wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + if (rStatus != WLAN_STATUS_SUCCESS || i4Argc >= 2) { + DBGLOG(REQ, ERROR, "NCHO error input parameter %d\n", i4Argc); + return rStatus; + } + + rStatus = kalIoctl(prGlueInfo, wlanoidQueryNchoRoamScnChnl, + &rRoamScnChnl, sizeof(struct CFG_NCHO_SCAN_CHNL), + TRUE, TRUE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, ERROR, + "NCHO wlanoidQueryNchoRoamScnChnl fail 0x%x\n", rStatus); + return rStatus; + } + + DBGLOG(REQ, TRACE, "NCHO query ok and ret is %d\n", + rRoamScnChnl.ucChannelListNum); + u4ChnlInfo = rRoamScnChnl.ucChannelListNum; + i4BytesWritten = 0; + i4BytesWritten += snprintf(buf + i4BytesWritten, + 512 - i4BytesWritten, + CMD_NCHO_ROAM_SCAN_CHANNELS_GET" %u", + u4ChnlInfo); + for (i = 0; i < rRoamScnChnl.ucChannelListNum; i++) { + u4ChnlInfo = + rRoamScnChnl.arChnlInfoList[i].ucChannelNum; + i4BytesWritten += snprintf(buf + i4BytesWritten, + 512 - i4BytesWritten, + " %u", u4ChnlInfo); + } + + DBGLOG(REQ, INFO, "NCHO get scn chl list num is [%d][%s]\n", + rRoamScnChnl.ucChannelListNum, buf); + + return mtk_cfg80211_process_str_cmd_reply(wiphy, + buf, i4BytesWritten + 1); +} + +int testmode_set_ncho_roam_scn_ctrl(IN struct wiphy *wiphy, + IN char *pcCommand, IN int i4TotalLen) +{ + uint32_t u4Param = 0; + uint32_t u4SetInfoLen = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + int32_t i4Ret = -1; + uint32_t rStatus = WLAN_STATUS_FAILURE; + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *)wiphy_priv(wiphy); + + DBGLOG(INIT, TRACE, "NCHO command is %s\n", pcCommand); + rStatus = wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + + if (rStatus == WLAN_STATUS_SUCCESS && i4Argc >= 2) { + DBGLOG(REQ, TRACE, "NCHO argc is %i, %s\n", i4Argc, apcArgv[1]); + i4Ret = kalkStrtou32(apcArgv[1], 0, &u4Param); + if (i4Ret) { + DBGLOG(REQ, ERROR, "NCHO parse u4Param error %d\n", + i4Ret); + return -1; + } + + DBGLOG(INIT, TRACE, "NCHO set roam scan control cmd %d\n", + u4Param); + rStatus = kalIoctl(prGlueInfo, wlanoidSetNchoRoamScnCtrl, + &u4Param, sizeof(uint32_t), + FALSE, FALSE, TRUE, &u4SetInfoLen); + + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(INIT, ERROR, + "NCHO set roam scan control fail 0x%x\n", + rStatus); + else + DBGLOG(INIT, TRACE, + "NCHO set roam scan control successed\n"); + } else { + DBGLOG(REQ, ERROR, "NCHO set failed\n"); + rStatus = WLAN_STATUS_INVALID_DATA; + } + return rStatus; +} + +int testmode_get_ncho_roam_scn_ctrl(IN struct wiphy *wiphy, + IN char *pcCommand, IN int i4TotalLen) +{ + int32_t i4BytesWritten = -1; + uint32_t u4Param = 0; + uint32_t u4BufLen = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = { 0 }; + uint32_t rStatus = WLAN_STATUS_FAILURE; + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *)wiphy_priv(wiphy); + char buf[512]; + + DBGLOG(INIT, TRACE, "NCHO command is %s\n", pcCommand); + + rStatus = wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + if (rStatus != WLAN_STATUS_SUCCESS || i4Argc >= 2) { + DBGLOG(REQ, ERROR, "NCHO error input parameter %d\n", i4Argc); + return WLAN_STATUS_INVALID_DATA; + } + + rStatus = kalIoctl(prGlueInfo, wlanoidQueryNchoRoamScnCtrl, + &u4Param, sizeof(uint32_t), + TRUE, TRUE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, ERROR, + "NCHO wlanoidQueryNchoRoamScnCtrl fail 0x%x\n", rStatus); + return rStatus; + } + + i4BytesWritten = snprintf(buf, 512, + CMD_NCHO_ROAM_SCAN_CONTROL_GET" %u", u4Param); + DBGLOG(REQ, INFO, "NCHO query ok and ret is [%u][%s]\n", + u4Param, buf); + return mtk_cfg80211_process_str_cmd_reply(wiphy, + buf, i4BytesWritten + 1); +} + +int testmode_set_ncho_mode(IN struct wiphy *wiphy, IN char *pcCommand, + IN int i4TotalLen) +{ + uint32_t u4Param = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + int32_t i4BytesWritten = -1; + uint32_t u4SetInfoLen = 0; + uint32_t rStatus = WLAN_STATUS_FAILURE; + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *)wiphy_priv(wiphy); + + DBGLOG(INIT, TRACE, "NCHO command is %s\n", pcCommand); + rStatus = wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + + if (rStatus == WLAN_STATUS_SUCCESS && i4Argc >= 2) { + DBGLOG(REQ, TRACE, "NCHO argc is %i, %s\n", i4Argc, + apcArgv[1]); + i4BytesWritten = kalkStrtou32(apcArgv[1], 0, &u4Param); + if (i4BytesWritten) { + DBGLOG(REQ, ERROR, "NCHO parse u4Param error %d\n", + i4BytesWritten); + i4BytesWritten = -1; + } else { + DBGLOG(INIT, TRACE, "NCHO set enable cmd %d\n", + u4Param); + rStatus = kalIoctl(prGlueInfo, wlanoidSetNchoEnable, + &u4Param, sizeof(uint32_t), + FALSE, FALSE, TRUE, &u4SetInfoLen); + + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(INIT, ERROR, + "NCHO set enable fail 0x%x\n", rStatus); + else + DBGLOG(INIT, TRACE, + "NCHO set enable successed\n"); + } + } else { + DBGLOG(REQ, ERROR, "NCHO set failed\n"); + rStatus = WLAN_STATUS_INVALID_DATA; + } + + return rStatus; +} + +int testmode_get_ncho_mode(IN struct wiphy *wiphy, IN char *pcCommand, + IN int i4TotalLen) +{ + int32_t i4BytesWritten = -1; + uint32_t u4Param = 0; + uint32_t u4BufLen = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = { 0 }; + uint32_t rStatus = WLAN_STATUS_FAILURE; + struct CMD_HEADER cmdV1Header; + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *)wiphy_priv(wiphy); + char buf[512]; + + rStatus = wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + if (rStatus != WLAN_STATUS_SUCCESS || i4Argc >= 2) { + DBGLOG(REQ, ERROR, "NCHO error input parameter %d\n", i4Argc); + return WLAN_STATUS_INVALID_DATA; + } + + /*<2> Query NCHOEnable Satus*/ + rStatus = kalIoctl(prGlueInfo, wlanoidQueryNchoEnable, + &cmdV1Header, sizeof(cmdV1Header), + TRUE, TRUE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, ERROR, "NCHO wlanoidQueryNchoEnable fail 0x%x\n", + rStatus); + return rStatus; + } + + i4BytesWritten = kalkStrtou32(cmdV1Header.buffer, 0, &u4Param); + if (i4BytesWritten) { + DBGLOG(REQ, ERROR, "NCHO parse u4Param error %d!\n", + i4BytesWritten); + return WLAN_STATUS_INVALID_DATA; + } + + i4BytesWritten = snprintf(buf, 512, CMD_NCHO_MODE_GET" %u", u4Param); + DBGLOG(REQ, INFO, "NCHO query ok and ret is [%u][%s]\n", + u4Param, buf); + + return mtk_cfg80211_process_str_cmd_reply(wiphy, + buf, i4BytesWritten + 1); +} + +#endif /* CFG_SUPPORT_NCHO */ + +int testmode_add_roam_scn_chnl( + IN struct wiphy *wiphy, IN char *pcCommand, IN int i4TotalLen) +{ + uint32_t u4ChnlInfo = 0; + uint8_t i = 1; + uint8_t t = 0; + uint32_t u4SetInfoLen = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + int32_t i4Ret = -1; + uint32_t rStatus = WLAN_STATUS_FAILURE; + struct CFG_SCAN_CHNL *prRoamScnChnl; + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *)wiphy_priv(wiphy); + + DBGLOG(INIT, TRACE, "command is %s\n", pcCommand); + rStatus = wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + + prRoamScnChnl = kalMemAlloc(sizeof(struct CFG_SCAN_CHNL), VIR_MEM_TYPE); + if (prRoamScnChnl == NULL) { + DBGLOG(REQ, ERROR, "alloc roaming scan channel fail\n"); + return WLAN_STATUS_RESOURCES; + } + kalMemZero(prRoamScnChnl, sizeof(struct CFG_SCAN_CHNL)); + + if (rStatus == WLAN_STATUS_SUCCESS && i4Argc >= 2) { + DBGLOG(REQ, TRACE, "argc is %i, cmd is %s\n", i4Argc, + apcArgv[1]); + i4Ret = kalkStrtou32(apcArgv[1], 0, &u4ChnlInfo); + if (i4Ret) { + DBGLOG(REQ, ERROR, "parse u4Param error %d\n", + i4Ret); + rStatus = WLAN_STATUS_INVALID_DATA; + goto label_exit; + } + + prRoamScnChnl->ucChannelListNum = u4ChnlInfo; + DBGLOG(REQ, INFO, "ChannelListNum is %d\n", u4ChnlInfo); + if (i4Argc != u4ChnlInfo + 2) { + DBGLOG(REQ, ERROR, "param mismatch %d\n", + u4ChnlInfo); + rStatus = WLAN_STATUS_INVALID_DATA; + goto label_exit; + + } + for (i = 2; i < i4Argc; i++) { + i4Ret = kalkStrtou32(apcArgv[i], 0, &u4ChnlInfo); + if (i4Ret) { + while (i != 2) { + prRoamScnChnl->arChnlInfoList[i] + .ucChannelNum = 0; + i--; + } + DBGLOG(REQ, ERROR, + "parse chnl num error %d\n", i4Ret); + rStatus = WLAN_STATUS_FAILURE; + goto label_exit; + } + if (u4ChnlInfo != 0) { + DBGLOG(INIT, TRACE, + "t = %d, channel value=%d\n", + t, u4ChnlInfo); + if ((u4ChnlInfo >= 1) && (u4ChnlInfo <= 14)) + prRoamScnChnl->arChnlInfoList[t].eBand = + BAND_2G4; + else + prRoamScnChnl->arChnlInfoList[t].eBand = + BAND_5G; + + prRoamScnChnl->arChnlInfoList[t].ucChannelNum = + u4ChnlInfo; + t++; + } + + } + + rStatus = kalIoctl(prGlueInfo, wlanoidAddRoamScnChnl, + prRoamScnChnl, sizeof(struct CFG_SCAN_CHNL), + FALSE, FALSE, TRUE, &u4SetInfoLen); + + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(INIT, ERROR, + "add roam scan channel fail 0x%x\n", + rStatus); + else + DBGLOG(INIT, TRACE, + "add roam scan channel successed\n"); + goto label_exit; + } else { + DBGLOG(REQ, ERROR, "add failed\n"); + rStatus = WLAN_STATUS_INVALID_DATA; + goto label_exit; + } + +label_exit: + kalMemFree(prRoamScnChnl, sizeof(struct CFG_SCAN_CHNL), VIR_MEM_TYPE); + return rStatus; +} + +int32_t mtk_cfg80211_process_str_cmd_reply( + IN struct wiphy *wiphy, IN char *data, IN int len) +{ + + struct sk_buff *skb; + + skb = cfg80211_testmode_alloc_reply_skb(wiphy, len); + + if (!skb) { + DBGLOG(REQ, INFO, "%s allocate skb failed\n", __func__); + return -ENOMEM; + } + + nla_put_nohdr(skb, len, data); + + return cfg80211_testmode_reply(skb); +} + +int32_t mtk_cfg80211_process_str_cmd(IN struct wiphy *wiphy, + struct wireless_dev *wdev, + uint8_t *data, int32_t len) +{ + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4SetInfoLen = 0; + uint8_t ucBssIndex = 0; + struct NL80211_DRIVER_STRING_CMD_PARAMS *param = + (struct NL80211_DRIVER_STRING_CMD_PARAMS *) data; + uint8_t *cmd = (uint8_t *) (param + 1); + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *)wiphy_priv(wiphy); + + len -= sizeof(struct NL80211_DRIVER_STRING_CMD_PARAMS); + ucBssIndex = wlanGetBssIdx(wdev->netdev); + if (!IS_BSS_INDEX_VALID(ucBssIndex)) + return -EINVAL; + + DBGLOG(REQ, INFO, "cmd: %s\n", cmd); + + if (strnicmp(cmd, "tdls-ps ", 8) == 0) { +#if CFG_SUPPORT_TDLS + rStatus = kalIoctl(prGlueInfo, + wlanoidDisableTdlsPs, + (void *)(cmd + 8), 1, + FALSE, FALSE, TRUE, &u4SetInfoLen); +#else + DBGLOG(REQ, WARN, "not support tdls\n"); + return -EOPNOTSUPP; +#endif + } else if (strncasecmp(cmd, "NEIGHBOR-REQUEST", 16) == 0) { + uint8_t *pucSSID = NULL; + uint32_t u4SSIDLen = 0; + + if (len > 16 && (strncasecmp(cmd+16, " SSID=", 6) == 0)) { + pucSSID = cmd + 22; + u4SSIDLen = len - 22; + DBGLOG(REQ, INFO, "cmd=%s, ssid len %u, ssid=%s\n", cmd, + u4SSIDLen, HIDE(pucSSID)); + } + rStatus = kalIoctlByBssIdx(prGlueInfo, + wlanoidSendNeighborRequest, + (void *)pucSSID, u4SSIDLen, FALSE, FALSE, + TRUE, &u4SetInfoLen, + ucBssIndex); + } else if (strncasecmp(cmd, "BSS-TRANSITION-QUERY", 20) == 0) { + uint8_t *pucReason = NULL; + + if (len > 20 && (strncasecmp(cmd+20, " reason=", 8) == 0)) + pucReason = cmd + 28; + rStatus = kalIoctlByBssIdx(prGlueInfo, wlanoidSendBTMQuery, + (void *)pucReason, 1, FALSE, FALSE, TRUE, + &u4SetInfoLen, + ucBssIndex); + } else if (strnicmp(cmd, "OSHAREMOD ", 10) == 0) { +#if CFG_SUPPORT_OSHARE + struct OSHARE_MODE_T cmdBuf; + struct OSHARE_MODE_T *pCmdHeader = NULL; + struct OSHARE_MODE_SETTING_V1_T *pCmdData = NULL; + + kalMemZero(&cmdBuf, sizeof(cmdBuf)); + + pCmdHeader = &cmdBuf; + pCmdHeader->cmdVersion = OSHARE_MODE_CMD_V1; + pCmdHeader->cmdType = 1; /*1-set 0-query*/ + pCmdHeader->magicCode = OSHARE_MODE_MAGIC_CODE; + pCmdHeader->cmdBufferLen = MAX_OSHARE_MODE_LENGTH; + + pCmdData = (struct OSHARE_MODE_SETTING_V1_T *) & + (pCmdHeader->buffer[0]); + pCmdData->osharemode = *(uint8_t *)(cmd + 10) - '0'; + + DBGLOG(REQ, INFO, "cmd=%s, osharemode=%u\n", cmd, + pCmdData->osharemode); + + rStatus = kalIoctl(prGlueInfo, + wlanoidSetOshareMode, + &cmdBuf, + sizeof(struct OSHARE_MODE_T), + FALSE, + FALSE, + TRUE, + &u4SetInfoLen); + + if (rStatus == WLAN_STATUS_SUCCESS) + prGlueInfo->prAdapter->fgEnOshareMode + = pCmdData->osharemode; +#else + DBGLOG(REQ, WARN, "not support OSHAREMOD\n"); + return -EOPNOTSUPP; +#endif + } else if (strnicmp(cmd, "CMD_EXAMPLE", 11) == 0) { + char tmp[] = "CMD_RESPONSE"; + + return mtk_cfg80211_process_str_cmd_reply( + wiphy, tmp, sizeof(tmp)); + } else if (strnicmp(cmd, "ADDROAMSCANCHANNELS_LEGACY", 26) == 0) { + rStatus = testmode_add_roam_scn_chnl(wiphy, cmd, len); +#if CFG_SUPPORT_NCHO + } else if (strnicmp(cmd, CMD_NCHO_ROAM_TRIGGER_SET, + strlen(CMD_NCHO_ROAM_TRIGGER_SET)) == 0) { + rStatus = testmode_set_ncho_roam_trigger(wiphy, cmd, len); + } else if (strnicmp(cmd, CMD_NCHO_ROAM_TRIGGER_GET, + strlen(CMD_NCHO_ROAM_TRIGGER_GET)) == 0) { + return testmode_get_ncho_roam_trigger(wiphy, cmd, len); + } else if (strnicmp(cmd, CMD_NCHO_ROAM_DELTA_SET, + strlen(CMD_NCHO_ROAM_DELTA_SET)) == 0) { + rStatus = testmode_set_ncho_roam_delta(wiphy, cmd, len); + } else if (strnicmp(cmd, CMD_NCHO_ROAM_DELTA_GET, + strlen(CMD_NCHO_ROAM_DELTA_GET)) == 0) { + return testmode_get_ncho_roam_delta(wiphy, cmd, len); + } else if (strnicmp(cmd, CMD_NCHO_ROAM_SCAN_PERIOD_SET, + strlen(CMD_NCHO_ROAM_SCAN_PERIOD_SET)) == 0) { + rStatus = testmode_set_ncho_roam_scn_period(wiphy, cmd, len); + } else if (strnicmp(cmd, CMD_NCHO_ROAM_SCAN_PERIOD_GET, + strlen(CMD_NCHO_ROAM_SCAN_PERIOD_GET)) == 0) { + return testmode_get_ncho_roam_scn_period(wiphy, cmd, len); + } else if (strnicmp(cmd, CMD_NCHO_ROAM_SCAN_CHANNELS_SET, + strlen(CMD_NCHO_ROAM_SCAN_CHANNELS_SET)) == 0) { + rStatus = testmode_set_ncho_roam_scn_chnl(wiphy, cmd, len, 1); + } else if (strnicmp(cmd, CMD_NCHO_ROAM_SCAN_CHANNELS_ADD, + strlen(CMD_NCHO_ROAM_SCAN_CHANNELS_ADD)) == 0) { + rStatus = testmode_set_ncho_roam_scn_chnl(wiphy, cmd, len, 0); + } else if (strnicmp(cmd, CMD_NCHO_ROAM_SCAN_CHANNELS_GET, + strlen(CMD_NCHO_ROAM_SCAN_CHANNELS_GET)) == 0) { + return testmode_get_ncho_roam_scn_chnl(wiphy, cmd, len); + } else if (strnicmp(cmd, CMD_NCHO_ROAM_SCAN_CONTROL_SET, + strlen(CMD_NCHO_ROAM_SCAN_CONTROL_SET)) == 0) { + rStatus = testmode_set_ncho_roam_scn_ctrl(wiphy, cmd, len); + } else if (strnicmp(cmd, CMD_NCHO_ROAM_SCAN_CONTROL_GET, + strlen(CMD_NCHO_ROAM_SCAN_CONTROL_GET)) == 0) { + return testmode_get_ncho_roam_scn_ctrl(wiphy, cmd, len); + } else if (strnicmp(cmd, CMD_NCHO_MODE_SET, + strlen(CMD_NCHO_MODE_SET)) == 0) { + rStatus = testmode_set_ncho_mode(wiphy, cmd, len); + } else if (strnicmp(cmd, CMD_NCHO_MODE_GET, + strlen(CMD_NCHO_MODE_GET)) == 0) { + return testmode_get_ncho_mode(wiphy, cmd, len); +#endif + } else + return -EOPNOTSUPP; + + return rStatus; +} + +#endif /* CONFIG_NL80211_TESTMODE */ + +#if (CFG_SUPPORT_SINGLE_SKU == 1) + +#if (CFG_BUILT_IN_DRIVER == 1) +/* in kernel-x.x/net/wireless/reg.c */ +#else +bool is_world_regdom(const char *alpha2) +{ + if (!alpha2) + return false; + + return (alpha2[0] == '0') && (alpha2[1] == '0'); +} +#endif + +enum regd_state regd_state_machine(IN struct regulatory_request *pRequest) +{ + switch (pRequest->initiator) { + case NL80211_REGDOM_SET_BY_USER: + DBGLOG(RLM, INFO, "regd_state_machine: SET_BY_USER\n"); + + return rlmDomainStateTransition(REGD_STATE_SET_COUNTRY_USER, + pRequest); + + case NL80211_REGDOM_SET_BY_DRIVER: + DBGLOG(RLM, INFO, "regd_state_machine: SET_BY_DRIVER\n"); + + return rlmDomainStateTransition( + REGD_STATE_SET_COUNTRY_DRIVER, pRequest); + + case NL80211_REGDOM_SET_BY_CORE: + DBGLOG(RLM, INFO, + "regd_state_machine: NL80211_REGDOM_SET_BY_CORE\n"); + + return rlmDomainStateTransition(REGD_STATE_SET_WW_CORE, + pRequest); + + case NL80211_REGDOM_SET_BY_COUNTRY_IE: + DBGLOG(RLM, WARN, + "============== WARNING ==============\n"); + DBGLOG(RLM, WARN, + "regd_state_machine: SET_BY_COUNTRY_IE\n"); + DBGLOG(RLM, WARN, "Regulatory rule is updated by IE.\n"); + DBGLOG(RLM, WARN, + "============== WARNING ==============\n"); + + return rlmDomainStateTransition(REGD_STATE_SET_COUNTRY_IE, + pRequest); + + default: + return rlmDomainStateTransition(REGD_STATE_INVALID, + pRequest); + } +} + + +void +mtk_apply_custom_regulatory(IN struct wiphy *pWiphy, + IN const struct ieee80211_regdomain *pRegdom) +{ + u32 band_idx, ch_idx; + struct ieee80211_supported_band *sband; + struct ieee80211_channel *chan; + + DBGLOG(RLM, INFO, "%s()\n", __func__); + + /* to reset cha->flags*/ + for (band_idx = 0; band_idx < KAL_NUM_BANDS; band_idx++) { + sband = pWiphy->bands[band_idx]; + if (!sband) + continue; + + for (ch_idx = 0; ch_idx < sband->n_channels; ch_idx++) { + chan = &sband->channels[ch_idx]; + + /*reset chan->flags*/ + chan->flags = 0; + } + + } + + /* update to kernel */ + wiphy_apply_custom_regulatory(pWiphy, pRegdom); +} + +void +mtk_reg_notify(IN struct wiphy *pWiphy, + IN struct regulatory_request *pRequest) +{ + struct GLUE_INFO *prGlueInfo; + struct ADAPTER *prAdapter; + enum regd_state old_state; + struct wiphy *pBaseWiphy = wlanGetWiphy(); + + if (g_u4HaltFlag) { + DBGLOG(RLM, WARN, "wlan is halt, skip reg callback\n"); + return; + } + + if (!pWiphy) { + DBGLOG(RLM, ERROR, "pWiphy = NULL!\n"); + return; + } + + /* + * Awlays use wlan0's base wiphy pointer to update reg notifier. + * Because only one reg state machine is handled. + */ + if (pBaseWiphy && (pWiphy != pBaseWiphy)) { + pWiphy = pBaseWiphy; + DBGLOG(RLM, ERROR, "Use base wiphy to update (p=%p)\n", + pBaseWiphy); + } + + old_state = rlmDomainGetCtrlState(); + + /* + * Magic flow for driver to send inband command after kernel's calling + * reg_notifier callback + */ + if (!pRequest) { + /*triggered by our driver in wlan initial process.*/ + + if (old_state == REGD_STATE_INIT) { + if (rlmDomainIsUsingLocalRegDomainDataBase()) { + DBGLOG(RLM, WARN, + "County Code is not assigned. Use default WW.\n"); + goto DOMAIN_SEND_CMD; + + } else { + DBGLOG(RLM, ERROR, + "Invalid REG state happened. state = 0x%x\n", + old_state); + return; + } + } else if ((old_state == REGD_STATE_SET_WW_CORE) || + (old_state == REGD_STATE_SET_COUNTRY_USER) || + (old_state == REGD_STATE_SET_COUNTRY_DRIVER)) { + goto DOMAIN_SEND_CMD; + } else { + DBGLOG(RLM, ERROR, + "Invalid REG state happened. state = 0x%x\n", + old_state); + return; + } + } + + /* + * Ignore the CORE's WW setting when using local data base of regulatory + * rules + */ + if ((pRequest->initiator == NL80211_REGDOM_SET_BY_CORE) && +#if KERNEL_VERSION(3, 14, 0) > CFG80211_VERSION_CODE + (pWiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY)) +#else + (pWiphy->regulatory_flags & REGULATORY_CUSTOM_REG)) +#endif + return;/*Ignore the CORE's WW setting*/ + + /* + * State machine transition + */ + DBGLOG(RLM, INFO, + "request->alpha2=%s, initiator=%x, intersect=%d\n", + pRequest->alpha2, pRequest->initiator, pRequest->intersect); + + regd_state_machine(pRequest); + + if (rlmDomainGetCtrlState() == old_state) { + if (((old_state == REGD_STATE_SET_COUNTRY_USER) + || (old_state == REGD_STATE_SET_COUNTRY_DRIVER)) + && (!(rlmDomainIsSameCountryCode(pRequest->alpha2, + sizeof(pRequest->alpha2))))) + DBGLOG(RLM, INFO, "Set by user to NEW country code\n"); + else + /* Change to same state or same country, ignore */ + return; + } else if (rlmDomainIsCtrlStateEqualTo(REGD_STATE_INVALID)) { + DBGLOG(RLM, ERROR, + "\n%s():\n---> WARNING. Transit to invalid state.\n", + __func__); + DBGLOG(RLM, ERROR, "---> WARNING.\n "); + rlmDomainAssert(0); + } + + /* + * Set country code + */ + if (pRequest->initiator != NL80211_REGDOM_SET_BY_DRIVER) { + rlmDomainSetCountryCode(pRequest->alpha2, + sizeof(pRequest->alpha2)); + } else { + /*SET_BY_DRIVER*/ + + if (rlmDomainIsEfuseUsed()) { + if (!rlmDomainIsUsingLocalRegDomainDataBase()) + DBGLOG(RLM, WARN, + "[WARNING!!!] Local DB must be used if country code from efuse.\n"); + } else { + /* iwpriv case */ + if (rlmDomainIsUsingLocalRegDomainDataBase() && + (!rlmDomainIsEfuseUsed())) { + /*iwpriv set country but local data base*/ + u32 country_code = + rlmDomainGetTempCountryCode(); + + rlmDomainSetCountryCode((char *)&country_code, + sizeof(country_code)); + } else { + /*iwpriv set country but query CRDA*/ + rlmDomainSetCountryCode(pRequest->alpha2, + sizeof(pRequest->alpha2)); + } + } + } + + rlmDomainSetDfsRegion(pRequest->dfs_region); + + +DOMAIN_SEND_CMD: + DBGLOG(RLM, INFO, "g_mtk_regd_control.alpha2 = 0x%x\n", + rlmDomainGetCountryCode()); + + /* + * Check if using customized regulatory rule + */ + if (rlmDomainIsUsingLocalRegDomainDataBase()) { + const struct ieee80211_regdomain *pRegdom; + u32 country_code = rlmDomainGetCountryCode(); + char alpha2[4]; + + /*fetch regulatory rules from local data base*/ + alpha2[0] = country_code & 0xFF; + alpha2[1] = (country_code >> 8) & 0xFF; + alpha2[2] = (country_code >> 16) & 0xFF; + alpha2[3] = (country_code >> 24) & 0xFF; + + pRegdom = rlmDomainSearchRegdomainFromLocalDataBase(alpha2); + if (!pRegdom) { + DBGLOG(RLM, ERROR, + "%s(): Error, Cannot find the correct RegDomain. country = %u\n", + __func__, rlmDomainGetCountryCode()); + + rlmDomainAssert(0); + return; + } + + mtk_apply_custom_regulatory(pWiphy, pRegdom); + } + + /* + * Parsing channels + */ + rlmDomainParsingChannel(pWiphy); /*real regd update*/ + + /* + * Check if firmawre support single sku. + * no need to send information to FW due to FW is not supported. + */ + if (!regd_is_single_sku_en()) + return; + + /* + * Always use the wlan GlueInfo as parameter. + */ + prGlueInfo = rlmDomainGetGlueInfo(); + if (!prGlueInfo) { + DBGLOG(RLM, ERROR, "prGlueInfo is NULL!\n"); + return; /*interface is not up yet.*/ + } + + prAdapter = prGlueInfo->prAdapter; + if (!prAdapter) { + DBGLOG(RLM, ERROR, "prAdapter is NULL!\n"); + return; /*interface is not up yet.*/ + } + + /* + * Send commands to firmware + */ + prAdapter->rWifiVar.u2CountryCode = + (uint16_t)rlmDomainGetCountryCode(); + rlmDomainSendCmd(prAdapter); +} + +void +cfg80211_regd_set_wiphy(IN struct wiphy *prWiphy) +{ + /* + * register callback + */ + prWiphy->reg_notifier = mtk_reg_notify; + + + /* + * clear REGULATORY_CUSTOM_REG flag + */ +#if KERNEL_VERSION(3, 14, 0) > CFG80211_VERSION_CODE + /*tells kernel that assign WW as default*/ + prWiphy->flags &= ~(WIPHY_FLAG_CUSTOM_REGULATORY); +#else + prWiphy->regulatory_flags &= ~(REGULATORY_CUSTOM_REG); + + /*ignore the hint from IE*/ + prWiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE; +#endif + + + /* + * set REGULATORY_CUSTOM_REG flag + */ +#if (CFG_SUPPORT_SINGLE_SKU_LOCAL_DB == 1) +#if KERNEL_VERSION(3, 14, 0) > CFG80211_VERSION_CODE + /*tells kernel that assign WW as default*/ + prWiphy->flags |= (WIPHY_FLAG_CUSTOM_REGULATORY); +#else + prWiphy->regulatory_flags |= (REGULATORY_CUSTOM_REG); +#endif + /* assigned a defautl one */ + if (rlmDomainGetLocalDefaultRegd()) + wiphy_apply_custom_regulatory(prWiphy, + rlmDomainGetLocalDefaultRegd()); +#endif + + + /* + * Initialize regd control information + */ + rlmDomainResetCtrlInfo(FALSE); +} + +#else +void +cfg80211_regd_set_wiphy(IN struct wiphy *prWiphy) +{ +} +#endif + +int mtk_cfg80211_suspend(struct wiphy *wiphy, + struct cfg80211_wowlan *wow) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + DBGLOG(REQ, INFO, "mtk_cfg80211_suspend\n"); + +#if (CFG_SUPPORT_STATISTICS == 1) + wlanWakeDumpRes(); +#endif + if (kalHaltTryLock()) + return 0; + + if (kalIsHalted() || !wiphy) + goto end; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + + if (prGlueInfo && prGlueInfo->prAdapter) { + set_bit(SUSPEND_FLAG_FOR_WAKEUP_REASON, + &prGlueInfo->prAdapter->ulSuspendFlag); + set_bit(SUSPEND_FLAG_CLEAR_WHEN_RESUME, + &prGlueInfo->prAdapter->ulSuspendFlag); + if (prGlueInfo->prAdapter->u4HostStatusEmiOffset) + kalSetSuspendFlagToEMI(prGlueInfo->prAdapter, TRUE); + } +end: + kalHaltUnlock(); + + return 0; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief cfg80211 resume callback, will be invoked in wiphy_resume. + * + * @param wiphy: pointer to wiphy + * + * @retval 0: successful + * others: failure + */ +/*----------------------------------------------------------------------------*/ +int mtk_cfg80211_resume(struct wiphy *wiphy) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + uint32_t rStatus, u4InfoLen; + + DBGLOG(REQ, INFO, "mtk_cfg80211_resume\n"); + + if (kalHaltTryLock()) + return 0; + + if (kalIsHalted() || !wiphy) + goto end; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + if (prGlueInfo) + prAdapter = prGlueInfo->prAdapter; + if (prAdapter == NULL) + goto end; + + clear_bit(SUSPEND_FLAG_CLEAR_WHEN_RESUME, + &prAdapter->ulSuspendFlag); + + rStatus = kalIoctl(prGlueInfo, + wlanoidIndicateBssInfo, + (void *) NULL, + 0, + FALSE, FALSE, FALSE, &u4InfoLen); + + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(REQ, WARN, "ScanResultLog error:%x\n", + rStatus); + if (prGlueInfo->prAdapter->u4HostStatusEmiOffset) + kalSetSuspendFlagToEMI(prGlueInfo->prAdapter, FALSE); +end: + kalHaltUnlock(); + + return 0; +} + +#if CFG_ENABLE_UNIFY_WIPHY +/*----------------------------------------------------------------------------*/ +/*! + * @brief Check the net device is P2P net device (P2P GO/GC, AP), or not. + * + * @param prGlueInfo : the driver private data + * ndev : the net device + * + * @retval 0: AIS device (STA/IBSS) + * 1: P2P GO/GC, AP + */ +/*----------------------------------------------------------------------------*/ +int mtk_IsP2PNetDevice(struct GLUE_INFO *prGlueInfo, + struct net_device *ndev) +{ + struct NETDEV_PRIVATE_GLUE_INFO *prNetDevPrivate = NULL; + int iftype = 0; + int ret = 1; + + if (ndev == NULL) { + DBGLOG(REQ, WARN, "ndev is NULL\n"); + return -1; + } + + prNetDevPrivate = (struct NETDEV_PRIVATE_GLUE_INFO *) + netdev_priv(ndev); + iftype = ndev->ieee80211_ptr->iftype; + + /* P2P device/GO/GC always return 1 */ + if (prNetDevPrivate->ucIsP2p == TRUE) + ret = 1; + else if (iftype == NL80211_IFTYPE_STATION) + ret = 0; + else if (iftype == NL80211_IFTYPE_ADHOC) + ret = 0; + + return ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Initialize the AIS related FSM and data. + * + * @param prGlueInfo : the driver private data + * ndev : the net device + * ucBssIdx : the AIS BSS index adssigned by the driver (wlanProbe) + * + * @retval 0 + * + */ +/*----------------------------------------------------------------------------*/ +int mtk_init_sta_role(struct ADAPTER *prAdapter, + struct net_device *ndev) +{ + struct NETDEV_PRIVATE_GLUE_INFO *prNdevPriv = NULL; + uint8_t ucBssIndex = 0; + + if ((prAdapter == NULL) || (ndev == NULL)) + return -1; + + ucBssIndex = wlanGetBssIdx(ndev); + if (!IS_BSS_INDEX_AIS(prAdapter, ucBssIndex)) + return -1; + + /* init AIS FSM */ + aisFsmInit(prAdapter, ucBssIndex); + +#if CFG_SUPPORT_ROAMING + /* Roaming Module - intiailization */ + roamingFsmInit(prAdapter, ucBssIndex); +#endif /* CFG_SUPPORT_ROAMING */ + + ndev->netdev_ops = wlanGetNdevOps(); + ndev->ieee80211_ptr->iftype = NL80211_IFTYPE_STATION; + + /* set the ndev's ucBssIdx to the AIS BSS index */ + prNdevPriv = (struct NETDEV_PRIVATE_GLUE_INFO *) + netdev_priv(ndev); + prNdevPriv->ucBssIdx = ucBssIndex; + + return 0; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Uninitialize the AIS related FSM and data. + * + * @param prAdapter : the driver private data + * + * @retval 0 + * + */ +/*----------------------------------------------------------------------------*/ +int mtk_uninit_sta_role(struct ADAPTER *prAdapter, + struct net_device *ndev) +{ + struct NETDEV_PRIVATE_GLUE_INFO *prNdevPriv = NULL; + uint8_t ucBssIndex = 0; + + if ((prAdapter == NULL) || (ndev == NULL)) + return -1; + + ucBssIndex = wlanGetBssIdx(ndev); + if (!IS_BSS_INDEX_AIS(prAdapter, ucBssIndex)) + return -1; + +#if CFG_SUPPORT_ROAMING + /* Roaming Module - unintiailization */ + roamingFsmUninit(prAdapter, ucBssIndex); +#endif /* CFG_SUPPORT_ROAMING */ + + /* uninit AIS FSM */ + aisFsmUninit(prAdapter, ucBssIndex); + + /* set the ucBssIdx to the illegal value */ + prNdevPriv = (struct NETDEV_PRIVATE_GLUE_INFO *) + netdev_priv(ndev); + prNdevPriv->ucBssIdx = 0xff; + + return 0; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Initialize the AP (P2P) related FSM and data. + * + * @param prGlueInfo : the driver private data + * ndev : net device + * + * @retval 0 : success + * others : can't alloc and setup the AP FSM & data + * + */ +/*----------------------------------------------------------------------------*/ +int mtk_init_ap_role(struct GLUE_INFO *prGlueInfo, + struct net_device *ndev) +{ + uint8_t u4Idx = 0; + struct ADAPTER *prAdapter = prGlueInfo->prAdapter; + + for (u4Idx = 0; u4Idx < KAL_P2P_NUM; u4Idx++) { + if (gprP2pRoleWdev[u4Idx] == NULL) + break; + } + + if (u4Idx >= KAL_P2P_NUM) { + DBGLOG(INIT, ERROR, "There is no free gprP2pRoleWdev.\n"); + return -ENOMEM; + } + + if ((u4Idx == 0) || + (prAdapter == NULL) || + (prAdapter->rP2PNetRegState != + ENUM_NET_REG_STATE_REGISTERED)) { + DBGLOG(INIT, ERROR, + "The wlan0 can't set to AP without p2p0\n"); + /* System will crash, if p2p0 isn't existing. */ + return -EFAULT; + } + + /* reference from the glRegisterP2P() */ + gprP2pRoleWdev[u4Idx] = ndev->ieee80211_ptr; + if (glSetupP2P(prGlueInfo, gprP2pRoleWdev[u4Idx], ndev, + u4Idx, TRUE)) { + gprP2pRoleWdev[u4Idx] = NULL; + return -EFAULT; + } + + prGlueInfo->prAdapter->prP2pInfo->u4DeviceNum++; + + /* reference from p2pNetRegister() */ + /* The ndev doesn't need register_netdev, only reassign the gPrP2pDev.*/ + gPrP2pDev[u4Idx] = ndev; + + return 0; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Unnitialize the AP (P2P) related FSM and data. + * + * @param prGlueInfo : the driver private data + * ndev : net device + * + * @retval 0 : success + * others : can't find the AP information by the ndev + * + */ +/*----------------------------------------------------------------------------*/ +uint32_t +mtk_oid_uninit_ap_role(struct ADAPTER *prAdapter, void *pvSetBuffer, + uint32_t u4SetBufferLen, uint32_t *pu4SetInfoLen) +{ + unsigned char u4Idx = 0; + + if ((prAdapter == NULL) || (pvSetBuffer == NULL) + || (pu4SetInfoLen == NULL)) + return WLAN_STATUS_FAILURE; + + /* init */ + *pu4SetInfoLen = sizeof(unsigned char); + if (u4SetBufferLen < sizeof(unsigned char)) + return WLAN_STATUS_INVALID_LENGTH; + + ASSERT(pvSetBuffer); + u4Idx = *(unsigned char *) pvSetBuffer; + + DBGLOG(INIT, INFO, "ucRoleIdx = %d\n", u4Idx); + + glUnregisterP2P(prAdapter->prGlueInfo, u4Idx); + + gPrP2pDev[u4Idx] = NULL; + gprP2pRoleWdev[u4Idx] = NULL; + + return 0; + +} + +int mtk_uninit_ap_role(struct GLUE_INFO *prGlueInfo, + struct net_device *ndev) +{ + unsigned char u4Idx; + uint32_t rStatus; + uint32_t u4BufLen; + + if (!prGlueInfo) { + DBGLOG(INIT, WARN, "prGlueInfo is NULL\n"); + return -EINVAL; + } + if (mtk_Netdev_To_RoleIdx(prGlueInfo, ndev, &u4Idx) != 0) { + DBGLOG(INIT, WARN, + "can't find the matched dev to uninit AP\n"); + return -EFAULT; + } + + rStatus = kalIoctl(prGlueInfo, + mtk_oid_uninit_ap_role, &u4Idx, + sizeof(unsigned char), + FALSE, FALSE, FALSE, + &u4BufLen); + if (rStatus != WLAN_STATUS_SUCCESS) + return -EINVAL; + + return 0; +} + +#if (CFG_SUPPORT_DFS_MASTER == 1) +#if KERNEL_VERSION(3, 15, 0) <= CFG80211_VERSION_CODE +int mtk_cfg_start_radar_detection(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_chan_def *chandef, + unsigned int cac_time_ms) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + + if (mtk_IsP2PNetDevice(prGlueInfo, dev) <= 0) { + DBGLOG(REQ, WARN, "STA doesn't support this function\n"); + return -EFAULT; + } + + return mtk_p2p_cfg80211_start_radar_detection(wiphy, + dev, + chandef, + cac_time_ms); + +} +#else +int mtk_cfg_start_radar_detection(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_chan_def *chandef) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + + if (mtk_IsP2PNetDevice(prGlueInfo, dev) <= 0) { + DBGLOG(REQ, WARN, "STA doesn't support this function\n"); + return -EFAULT; + } + + return mtk_p2p_cfg80211_start_radar_detection(wiphy, dev, chandef); + +} + +#endif + + +#if KERNEL_VERSION(3, 13, 0) <= CFG80211_VERSION_CODE +int mtk_cfg_channel_switch(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_csa_settings *params) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + + if (mtk_IsP2PNetDevice(prGlueInfo, dev) <= 0) { + DBGLOG(REQ, WARN, "STA doesn't support this function\n"); + return -EFAULT; + } + + return mtk_p2p_cfg80211_channel_switch(wiphy, dev, params); + +} +#endif +#endif + +#if KERNEL_VERSION(4, 12, 0) <= CFG80211_VERSION_CODE +struct wireless_dev *mtk_cfg_add_iface(struct wiphy *wiphy, + const char *name, + unsigned char name_assign_type, + enum nl80211_iftype type, + struct vif_params *params) +#elif KERNEL_VERSION(4, 1, 0) <= CFG80211_VERSION_CODE +struct wireless_dev *mtk_cfg_add_iface(struct wiphy *wiphy, + const char *name, + unsigned char name_assign_type, + enum nl80211_iftype type, + u32 *flags, + struct vif_params *params) +#else +struct wireless_dev *mtk_cfg_add_iface(struct wiphy *wiphy, + const char *name, + enum nl80211_iftype type, + u32 *flags, + struct vif_params *params) +#endif +{ + struct GLUE_INFO *prGlueInfo = NULL; +#if KERNEL_VERSION(4, 12, 0) <= CFG80211_VERSION_CODE + u32 *flags = NULL; +#endif + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return ERR_PTR(-EFAULT); + } + + /* TODO: error handele for the non-P2P interface */ + +#if (CFG_ENABLE_WIFI_DIRECT_CFG_80211 == 0) + DBGLOG(REQ, WARN, "P2P is not supported\n"); + return ERR_PTR(-EINVAL); +#else /* CFG_ENABLE_WIFI_DIRECT_CFG_80211 */ +#if KERNEL_VERSION(4, 1, 0) <= CFG80211_VERSION_CODE + return mtk_p2p_cfg80211_add_iface(wiphy, name, + name_assign_type, type, + flags, params); +#else /* KERNEL_VERSION > (4, 1, 0) */ + return mtk_p2p_cfg80211_add_iface(wiphy, name, type, flags, + params); +#endif /* KERNEL_VERSION */ +#endif /* CFG_ENABLE_WIFI_DIRECT_CFG_80211 */ +} + +int mtk_cfg_del_iface(struct wiphy *wiphy, + struct wireless_dev *wdev) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + + /* TODO: error handele for the non-P2P interface */ +#if (CFG_ENABLE_WIFI_DIRECT_CFG_80211 == 0) + DBGLOG(REQ, WARN, "P2P is not supported\n"); + return -EINVAL; +#else /* CFG_ENABLE_WIFI_DIRECT_CFG_80211 */ + return mtk_p2p_cfg80211_del_iface(wiphy, wdev); +#endif /* CFG_ENABLE_WIFI_DIRECT_CFG_80211 */ +} + +#if KERNEL_VERSION(4, 12, 0) <= CFG80211_VERSION_CODE +int mtk_cfg_change_iface(struct wiphy *wiphy, + struct net_device *ndev, + enum nl80211_iftype type, + struct vif_params *params) +#else +int mtk_cfg_change_iface(struct wiphy *wiphy, + struct net_device *ndev, + enum nl80211_iftype type, u32 *flags, + struct vif_params *params) +#endif +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + struct NETDEV_PRIVATE_GLUE_INFO *prNetdevPriv = NULL; + struct P2P_INFO *prP2pInfo = NULL; +#if KERNEL_VERSION(4, 12, 0) <= CFG80211_VERSION_CODE + u32 *flags = NULL; +#endif + + GLUE_SPIN_LOCK_DECLARATION(); + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + ASSERT(prGlueInfo); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + + if (!ndev) { + DBGLOG(REQ, WARN, "ndev is NULL\n"); + return -EINVAL; + } + + prNetdevPriv = (struct NETDEV_PRIVATE_GLUE_INFO *) + netdev_priv(ndev); + +#if (CFG_ENABLE_WIFI_DIRECT_CFG_80211) + /* for p2p0(GO/GC) & ap0(SAP): mtk_p2p_cfg80211_change_iface + * for wlan0 (STA/SAP): the following mtk_cfg_change_iface process + */ + if (!wlanIsAisDev(ndev)) { + return mtk_p2p_cfg80211_change_iface(wiphy, ndev, type, + flags, params); + } +#endif /* CFG_ENABLE_WIFI_DIRECT_CFG_80211 */ + + DBGLOG(P2P, INFO, "ndev=%p, new type=%d\n", ndev, type); + + prAdapter = prGlueInfo->prAdapter; + + if (ndev->ieee80211_ptr->iftype == type) { + DBGLOG(REQ, INFO, "ndev type is not changed (%d)\n", type); + return 0; + } + + netif_carrier_off(ndev); + /* stop ap will stop all queue, and kalIndicateStatusAndComplete only do + * netif_carrier_on. So that, the following STA can't send 4-way M2 to + * AP. + */ + netif_tx_start_all_queues(ndev); + + /* flush scan */ + GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); + if ((prGlueInfo->prScanRequest != NULL) && + (prGlueInfo->prScanRequest->wdev == ndev->ieee80211_ptr)) { + kalCfg80211ScanDone(prGlueInfo->prScanRequest, TRUE); + prGlueInfo->prScanRequest = NULL; + } + GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); + + /* expect that only AP & STA will be handled here (excluding IBSS) */ + + if (type == NL80211_IFTYPE_AP) { + /* STA mode change to AP mode */ + prP2pInfo = prAdapter->prP2pInfo; + + if (prP2pInfo == NULL) { + DBGLOG(INIT, ERROR, "prP2pInfo is NULL\n"); + return -EFAULT; + } + + if (prP2pInfo->u4DeviceNum >= KAL_P2P_NUM) { + DBGLOG(INIT, ERROR, "resource invalid, u4DeviceNum=%d\n" + , prP2pInfo->u4DeviceNum); + return -EFAULT; + } + + mtk_uninit_sta_role(prAdapter, ndev); + + if (mtk_init_ap_role(prGlueInfo, ndev) != 0) { + DBGLOG(INIT, ERROR, "mtk_init_ap_role FAILED\n"); + + /* Only AP/P2P resource has the failure case. */ + /* So, just re-init AIS. */ + mtk_init_sta_role(prAdapter, ndev); + return -EFAULT; + } + } else { + /* AP mode change to STA mode */ + if (mtk_uninit_ap_role(prGlueInfo, ndev) != 0) { + DBGLOG(INIT, ERROR, "mtk_uninit_ap_role FAILED\n"); + return -EFAULT; + } + + mtk_init_sta_role(prAdapter, ndev); + + /* continue the mtk_cfg80211_change_iface() process */ + mtk_cfg80211_change_iface(wiphy, ndev, type, flags, params); + } + + return 0; +} + +int mtk_cfg_add_key(struct wiphy *wiphy, + struct net_device *ndev, u8 key_index, + bool pairwise, const u8 *mac_addr, + struct key_params *params) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + + if (mtk_IsP2PNetDevice(prGlueInfo, ndev) > 0) { + return mtk_p2p_cfg80211_add_key(wiphy, ndev, key_index, + pairwise, mac_addr, params); + } + /* STA Mode */ + return mtk_cfg80211_add_key(wiphy, ndev, key_index, + pairwise, + mac_addr, params); +} + +int mtk_cfg_get_key(struct wiphy *wiphy, + struct net_device *ndev, u8 key_index, + bool pairwise, const u8 *mac_addr, void *cookie, + void (*callback)(void *cookie, struct key_params *)) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + + if (mtk_IsP2PNetDevice(prGlueInfo, ndev) > 0) { + return mtk_p2p_cfg80211_get_key(wiphy, ndev, key_index, + pairwise, mac_addr, cookie, callback); + } + /* STA Mode */ + return mtk_cfg80211_get_key(wiphy, ndev, key_index, + pairwise, mac_addr, cookie, callback); +} + +int mtk_cfg_del_key(struct wiphy *wiphy, + struct net_device *ndev, u8 key_index, + bool pairwise, const u8 *mac_addr) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + + if (mtk_IsP2PNetDevice(prGlueInfo, ndev) > 0) { + return mtk_p2p_cfg80211_del_key(wiphy, ndev, key_index, + pairwise, mac_addr); + } + /* STA Mode */ + return mtk_cfg80211_del_key(wiphy, ndev, key_index, + pairwise, mac_addr); +} + +int mtk_cfg_set_default_key(struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index, bool unicast, bool multicast) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + + if (mtk_IsP2PNetDevice(prGlueInfo, ndev) > 0) { + return mtk_p2p_cfg80211_set_default_key(wiphy, ndev, + key_index, unicast, multicast); + } + /* STA Mode */ + return mtk_cfg80211_set_default_key(wiphy, ndev, + key_index, unicast, multicast); +} + +int mtk_cfg_set_default_mgmt_key(struct wiphy *wiphy, + struct net_device *ndev, u8 key_index) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + + if (mtk_IsP2PNetDevice(prGlueInfo, ndev) > 0) + return mtk_p2p_cfg80211_set_mgmt_key(wiphy, ndev, key_index); + /* STA Mode */ + DBGLOG(REQ, WARN, "STA don't support this function\n"); + return -EFAULT; +} + +#if KERNEL_VERSION(3, 16, 0) <= CFG80211_VERSION_CODE +int mtk_cfg_get_station(struct wiphy *wiphy, + struct net_device *ndev, + const u8 *mac, struct station_info *sinfo) +#else +int mtk_cfg_get_station(struct wiphy *wiphy, + struct net_device *ndev, + u8 *mac, struct station_info *sinfo) +#endif +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + + if (mtk_IsP2PNetDevice(prGlueInfo, ndev) > 0) + return mtk_p2p_cfg80211_get_station(wiphy, ndev, mac, + sinfo); + /* STA Mode */ + return mtk_cfg80211_get_station(wiphy, ndev, mac, sinfo); +} + +#if CFG_SUPPORT_TDLS +#if KERNEL_VERSION(3, 16, 0) <= CFG80211_VERSION_CODE +int mtk_cfg_change_station(struct wiphy *wiphy, + struct net_device *ndev, + const u8 *mac, struct station_parameters *params) +#else +int mtk_cfg_change_station(struct wiphy *wiphy, + struct net_device *ndev, + u8 *mac, struct station_parameters *params) +#endif +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + + if (mtk_IsP2PNetDevice(prGlueInfo, ndev) > 0) { + DBGLOG(REQ, WARN, "P2P/AP don't support this function\n"); + return -EFAULT; + } + /* STA Mode */ + return mtk_cfg80211_change_station(wiphy, ndev, mac, + params); +} + +#if KERNEL_VERSION(3, 16, 0) <= CFG80211_VERSION_CODE +int mtk_cfg_add_station(struct wiphy *wiphy, + struct net_device *ndev, + const u8 *mac, struct station_parameters *params) +#else +int mtk_cfg_add_station(struct wiphy *wiphy, + struct net_device *ndev, + u8 *mac, struct station_parameters *params) +#endif +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + + if (mtk_IsP2PNetDevice(prGlueInfo, ndev) > 0) { + DBGLOG(REQ, WARN, "P2P/AP don't support this function\n"); + return -EFAULT; + } + /* STA Mode */ + return mtk_cfg80211_add_station(wiphy, ndev, mac, params); +} + +#if KERNEL_VERSION(3, 16, 0) <= CFG80211_VERSION_CODE +int mtk_cfg_tdls_oper(struct wiphy *wiphy, + struct net_device *ndev, + const u8 *peer, enum nl80211_tdls_operation oper) +#else +int mtk_cfg_tdls_oper(struct wiphy *wiphy, + struct net_device *ndev, + u8 *peer, enum nl80211_tdls_operation oper) +#endif +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + + if (mtk_IsP2PNetDevice(prGlueInfo, ndev) > 0) { + DBGLOG(REQ, WARN, "P2P/AP don't support this function\n"); + return -EFAULT; + } + /* STA Mode */ + return mtk_cfg80211_tdls_oper(wiphy, ndev, peer, oper); +} + +#if KERNEL_VERSION(3, 18, 0) <= CFG80211_VERSION_CODE +int mtk_cfg_tdls_mgmt(struct wiphy *wiphy, + struct net_device *dev, + const u8 *peer, u8 action_code, u8 dialog_token, + u16 status_code, u32 peer_capability, + bool initiator, const u8 *buf, size_t len) +#elif KERNEL_VERSION(3, 16, 0) <= CFG80211_VERSION_CODE +int mtk_cfg_tdls_mgmt(struct wiphy *wiphy, + struct net_device *dev, + const u8 *peer, u8 action_code, u8 dialog_token, + u16 status_code, u32 peer_capability, + const u8 *buf, size_t len) +#else +int mtk_cfg_tdls_mgmt(struct wiphy *wiphy, + struct net_device *dev, + u8 *peer, u8 action_code, u8 dialog_token, + u16 status_code, + const u8 *buf, size_t len) +#endif +{ + struct GLUE_INFO *prGlueInfo; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + + if (mtk_IsP2PNetDevice(prGlueInfo, dev) > 0) { + DBGLOG(REQ, WARN, "P2P/AP don't support this function\n"); + return -EFAULT; + } + +#if KERNEL_VERSION(3, 18, 0) <= CFG80211_VERSION_CODE + return mtk_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code, + dialog_token, status_code, peer_capability, initiator, + buf, len); +#elif KERNEL_VERSION(3, 16, 0) <= CFG80211_VERSION_CODE + return mtk_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code, + dialog_token, status_code, peer_capability, + buf, len); +#else + return mtk_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code, + dialog_token, status_code, + buf, len); +#endif +} +#endif /* CFG_SUPPORT_TDLS */ + +#if KERNEL_VERSION(3, 19, 0) <= CFG80211_VERSION_CODE +int mtk_cfg_del_station(struct wiphy *wiphy, + struct net_device *ndev, + struct station_del_parameters *params) +#elif KERNEL_VERSION(3, 16, 0) <= CFG80211_VERSION_CODE +int mtk_cfg_del_station(struct wiphy *wiphy, + struct net_device *ndev, + const u8 *mac) +#else +int mtk_cfg_del_station(struct wiphy *wiphy, + struct net_device *ndev, u8 *mac) +#endif +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + + if (mtk_IsP2PNetDevice(prGlueInfo, ndev) > 0) { +#if KERNEL_VERSION(3, 19, 0) <= CFG80211_VERSION_CODE + return mtk_p2p_cfg80211_del_station(wiphy, ndev, params); +#else + return mtk_p2p_cfg80211_del_station(wiphy, ndev, mac); +#endif + } + /* STA Mode */ +#if CFG_SUPPORT_TDLS +#if KERNEL_VERSION(3, 19, 0) <= CFG80211_VERSION_CODE + return mtk_cfg80211_del_station(wiphy, ndev, params); +#else /* CFG80211_VERSION_CODE > KERNEL_VERSION(3, 19, 0) */ + return mtk_cfg80211_del_station(wiphy, ndev, mac); +#endif /* CFG80211_VERSION_CODE */ +#else /* CFG_SUPPORT_TDLS == 0 */ + /* AIS only support this function when CFG_SUPPORT_TDLS */ + return -EFAULT; +#endif /* CFG_SUPPORT_TDLS */ +} + +int mtk_cfg_scan(struct wiphy *wiphy, + struct cfg80211_scan_request *request) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + + if (mtk_IsP2PNetDevice(prGlueInfo, + request->wdev->netdev) > 0) + return mtk_p2p_cfg80211_scan(wiphy, request); + /* STA Mode */ + return mtk_cfg80211_scan(wiphy, request); +} + +#if KERNEL_VERSION(4, 5, 0) <= CFG80211_VERSION_CODE +void mtk_cfg_abort_scan(struct wiphy *wiphy, + struct wireless_dev *wdev) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return; + } + + if (mtk_IsP2PNetDevice(prGlueInfo, wdev->netdev) > 0) + mtk_p2p_cfg80211_abort_scan(wiphy, wdev); + else /* STA Mode */ + mtk_cfg80211_abort_scan(wiphy, wdev); +} +#endif + +#if CFG_SUPPORT_SCHED_SCAN +int mtk_cfg_sched_scan_start(IN struct wiphy *wiphy, + IN struct net_device *ndev, + IN struct cfg80211_sched_scan_request *request) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + + if (mtk_IsP2PNetDevice(prGlueInfo, ndev) > 0) { + DBGLOG(REQ, WARN, "P2P/AP don't support this function\n"); + return -EFAULT; + } + + return mtk_cfg80211_sched_scan_start(wiphy, ndev, request); + +} + +#if KERNEL_VERSION(4, 12, 0) <= CFG80211_VERSION_CODE +int mtk_cfg_sched_scan_stop(IN struct wiphy *wiphy, + IN struct net_device *ndev, + IN u64 reqid) +#else +int mtk_cfg_sched_scan_stop(IN struct wiphy *wiphy, + IN struct net_device *ndev) +#endif +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return 0; + } +#if KERNEL_VERSION(4, 12, 0) <= CFG80211_VERSION_CODE + return mtk_cfg80211_sched_scan_stop(wiphy, ndev, reqid); +#else + return mtk_cfg80211_sched_scan_stop(wiphy, ndev); +#endif +} +#endif /* CFG_SUPPORT_SCHED_SCAN */ + +int mtk_cfg_connect(struct wiphy *wiphy, + struct net_device *ndev, + struct cfg80211_connect_params *sme) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + + if (mtk_IsP2PNetDevice(prGlueInfo, ndev) > 0) + return mtk_p2p_cfg80211_connect(wiphy, ndev, sme); + /* STA Mode */ + return mtk_cfg80211_connect(wiphy, ndev, sme); +} + +int mtk_cfg_disconnect(struct wiphy *wiphy, + struct net_device *ndev, + u16 reason_code) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + + if (mtk_IsP2PNetDevice(prGlueInfo, ndev) > 0) + return mtk_p2p_cfg80211_disconnect(wiphy, ndev, + reason_code); + /* STA Mode */ + return mtk_cfg80211_disconnect(wiphy, ndev, reason_code); +} + +int mtk_cfg_join_ibss(struct wiphy *wiphy, + struct net_device *ndev, + struct cfg80211_ibss_params *params) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + + if (mtk_IsP2PNetDevice(prGlueInfo, ndev) > 0) + return mtk_p2p_cfg80211_join_ibss(wiphy, ndev, params); + /* STA Mode */ + return mtk_cfg80211_join_ibss(wiphy, ndev, params); +} + +int mtk_cfg_leave_ibss(struct wiphy *wiphy, + struct net_device *ndev) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + + if (mtk_IsP2PNetDevice(prGlueInfo, ndev) > 0) + return mtk_p2p_cfg80211_leave_ibss(wiphy, ndev); + /* STA Mode */ + return mtk_cfg80211_leave_ibss(wiphy, ndev); +} + +int mtk_cfg_set_power_mgmt(struct wiphy *wiphy, + struct net_device *ndev, + bool enabled, int timeout) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + + if (mtk_IsP2PNetDevice(prGlueInfo, ndev) > 0) { + return mtk_p2p_cfg80211_set_power_mgmt(wiphy, ndev, + enabled, timeout); + } + /* STA Mode */ + return mtk_cfg80211_set_power_mgmt(wiphy, ndev, enabled, + timeout); +} + +int mtk_cfg_set_pmksa(struct wiphy *wiphy, + struct net_device *ndev, + struct cfg80211_pmksa *pmksa) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + + if (mtk_IsP2PNetDevice(prGlueInfo, ndev) > 0) { + DBGLOG(REQ, WARN, "P2P/AP don't support this function\n"); + return -EFAULT; + } + + return mtk_cfg80211_set_pmksa(wiphy, ndev, pmksa); +} + +int mtk_cfg_del_pmksa(struct wiphy *wiphy, + struct net_device *ndev, + struct cfg80211_pmksa *pmksa) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + + if (mtk_IsP2PNetDevice(prGlueInfo, ndev) > 0) { + DBGLOG(REQ, WARN, "P2P/AP don't support this function\n"); + return -EFAULT; + } + + return mtk_cfg80211_del_pmksa(wiphy, ndev, pmksa); +} + +int mtk_cfg_flush_pmksa(struct wiphy *wiphy, + struct net_device *ndev) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + + if (mtk_IsP2PNetDevice(prGlueInfo, ndev) > 0) { + DBGLOG(REQ, TRACE, "P2P/AP don't support this function\n"); + return -EFAULT; + } + + return mtk_cfg80211_flush_pmksa(wiphy, ndev); +} + +#if CONFIG_SUPPORT_GTK_REKEY +int mtk_cfg_set_rekey_data(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_gtk_rekey_data *data) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + + if (mtk_IsP2PNetDevice(prGlueInfo, dev) > 0) { + DBGLOG(REQ, WARN, "P2P/AP don't support this function\n"); + return -EFAULT; + } + + return mtk_cfg80211_set_rekey_data(wiphy, dev, data); +} +#endif /* CONFIG_SUPPORT_GTK_REKEY */ + +int mtk_cfg_suspend(struct wiphy *wiphy, + struct cfg80211_wowlan *wow) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if (!wlanIsDriverReady(prGlueInfo)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return 0; + } + + /* TODO: AP/P2P do not support this function, should take that case. */ + return mtk_cfg80211_suspend(wiphy, wow); +} + +int mtk_cfg_resume(struct wiphy *wiphy) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if (!wlanIsDriverReady(prGlueInfo)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return 0; + } + + /* TODO: AP/P2P do not support this function, should take that case. */ + return mtk_cfg80211_resume(wiphy); +} + +int mtk_cfg_assoc(struct wiphy *wiphy, + struct net_device *ndev, + struct cfg80211_assoc_request *req) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + + if (mtk_IsP2PNetDevice(prGlueInfo, ndev) > 0) { + DBGLOG(REQ, WARN, "P2P/AP don't support this function\n"); + return -EFAULT; + } + /* STA Mode */ + return mtk_cfg80211_assoc(wiphy, ndev, req); +} + +int mtk_cfg_remain_on_channel(struct wiphy *wiphy, + struct wireless_dev *wdev, + struct ieee80211_channel *chan, + unsigned int duration, u64 *cookie) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + + if (mtk_IsP2PNetDevice(prGlueInfo, wdev->netdev) > 0) { + return mtk_p2p_cfg80211_remain_on_channel(wiphy, wdev, chan, + duration, cookie); + } + /* STA Mode */ + return mtk_cfg80211_remain_on_channel(wiphy, wdev, chan, + duration, cookie); +} + +int mtk_cfg_cancel_remain_on_channel(struct wiphy *wiphy, + struct wireless_dev *wdev, u64 cookie) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + + if (mtk_IsP2PNetDevice(prGlueInfo, wdev->netdev) > 0) { + return mtk_p2p_cfg80211_cancel_remain_on_channel(wiphy, + wdev, + cookie); + } + /* STA Mode */ + return mtk_cfg80211_cancel_remain_on_channel(wiphy, wdev, + cookie); +} + +#if KERNEL_VERSION(3, 14, 0) <= CFG80211_VERSION_CODE +int mtk_cfg_mgmt_tx(struct wiphy *wiphy, + struct wireless_dev *wdev, + struct cfg80211_mgmt_tx_params *params, u64 *cookie) +#else +int mtk_cfg_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, + struct ieee80211_channel *channel, bool offchan, + unsigned int wait, const u8 *buf, size_t len, bool no_cck, + bool dont_wait_for_ack, u64 *cookie) +#endif +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + +#if KERNEL_VERSION(3, 14, 0) <= CFG80211_VERSION_CODE + if (mtk_IsP2PNetDevice(prGlueInfo, wdev->netdev) > 0) + return mtk_p2p_cfg80211_mgmt_tx(wiphy, wdev, params, + cookie); + /* STA Mode */ + return mtk_cfg80211_mgmt_tx(wiphy, wdev, params, cookie); +#else /* KERNEL_VERSION(3, 14, 0) > CFG80211_VERSION_CODE */ + if (mtk_IsP2PNetDevice(prGlueInfo, wdev->netdev) > 0) { + return mtk_p2p_cfg80211_mgmt_tx(wiphy, wdev, channel, offchan, + wait, buf, len, no_cck, dont_wait_for_ack, cookie); + } + /* STA Mode */ + return mtk_cfg80211_mgmt_tx(wiphy, wdev, channel, offchan, wait, buf, + len, no_cck, dont_wait_for_ack, cookie); +#endif +} + +void mtk_cfg_mgmt_frame_register(struct wiphy *wiphy, + struct wireless_dev *wdev, + u16 frame_type, bool reg) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return; + } + + if (mtk_IsP2PNetDevice(prGlueInfo, wdev->netdev) > 0) { + mtk_p2p_cfg80211_mgmt_frame_register(wiphy, wdev, + frame_type, + reg); + } else { + mtk_cfg80211_mgmt_frame_register(wiphy, wdev, frame_type, + reg); + } +} + +#ifdef CONFIG_NL80211_TESTMODE +#if KERNEL_VERSION(3, 12, 0) <= CFG80211_VERSION_CODE +int mtk_cfg_testmode_cmd(struct wiphy *wiphy, + struct wireless_dev *wdev, + void *data, int len) +#else +int mtk_cfg_testmode_cmd(struct wiphy *wiphy, void *data, + int len) +#endif +{ +#if KERNEL_VERSION(3, 12, 0) <= CFG80211_VERSION_CODE + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + + if (mtk_IsP2PNetDevice(prGlueInfo, wdev->netdev) > 0) { + return mtk_p2p_cfg80211_testmode_cmd(wiphy, wdev, data, + len); + } + + return mtk_cfg80211_testmode_cmd(wiphy, wdev, data, len); +#else + /* XXX: no information can to check the mtk_IsP2PNetDevice */ + /* return mtk_p2p_cfg80211_testmode_cmd(wiphy, data, len); */ + return mtk_cfg80211_testmode_cmd(wiphy, data, len); +#endif +} +#endif /* CONFIG_NL80211_TESTMODE */ + +#if (CFG_ENABLE_WIFI_DIRECT_CFG_80211 != 0) +int mtk_cfg_change_bss(struct wiphy *wiphy, + struct net_device *dev, + struct bss_parameters *params) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + + if (mtk_IsP2PNetDevice(prGlueInfo, dev) <= 0) { + DBGLOG(REQ, WARN, "STA doesn't support this function\n"); + return -EFAULT; + } + + return mtk_p2p_cfg80211_change_bss(wiphy, dev, params); +} + +int mtk_cfg_mgmt_tx_cancel_wait(struct wiphy *wiphy, + struct wireless_dev *wdev, + u64 cookie) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + + if (mtk_IsP2PNetDevice(prGlueInfo, wdev->netdev) <= 0) { + return mtk_cfg80211_mgmt_tx_cancel_wait(wiphy, wdev, cookie); + } + + return mtk_p2p_cfg80211_mgmt_tx_cancel_wait(wiphy, wdev, + cookie); +} + +int mtk_cfg_deauth(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_deauth_request *req) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + + if (mtk_IsP2PNetDevice(prGlueInfo, dev) <= 0) { + DBGLOG(REQ, WARN, "STA doesn't support this function\n"); + return -EFAULT; + } + + return mtk_p2p_cfg80211_deauth(wiphy, dev, req); +} + +int mtk_cfg_disassoc(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_disassoc_request *req) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + + if (mtk_IsP2PNetDevice(prGlueInfo, dev) <= 0) { + DBGLOG(REQ, WARN, "STA doesn't support this function\n"); + return -EFAULT; + } + + return mtk_p2p_cfg80211_disassoc(wiphy, dev, req); +} + +int mtk_cfg_start_ap(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_ap_settings *settings) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + + if (mtk_IsP2PNetDevice(prGlueInfo, dev) <= 0) { + DBGLOG(REQ, WARN, "STA doesn't support this function\n"); + return -EFAULT; + } + + return mtk_p2p_cfg80211_start_ap(wiphy, dev, settings); +} + +int mtk_cfg_change_beacon(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_beacon_data *info) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + + if (mtk_IsP2PNetDevice(prGlueInfo, dev) <= 0) { + DBGLOG(REQ, WARN, "STA doesn't support this function\n"); + return -EFAULT; + } + + return mtk_p2p_cfg80211_change_beacon(wiphy, dev, info); +} + +int mtk_cfg_stop_ap(struct wiphy *wiphy, + struct net_device *dev) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + + if (mtk_IsP2PNetDevice(prGlueInfo, dev) <= 0) { + DBGLOG(REQ, WARN, "STA doesn't support this function\n"); + return -EFAULT; + } + + return mtk_p2p_cfg80211_stop_ap(wiphy, dev); +} + +int mtk_cfg_set_wiphy_params(struct wiphy *wiphy, + u32 changed) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + + /* TODO: AIS not support this function */ + return mtk_p2p_cfg80211_set_wiphy_params(wiphy, changed); +} + +int mtk_cfg_set_bitrate_mask(struct wiphy *wiphy, + struct net_device *dev, + const u8 *peer, + const struct cfg80211_bitrate_mask *mask) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + + if (mtk_IsP2PNetDevice(prGlueInfo, dev) <= 0) { + DBGLOG(REQ, WARN, "STA doesn't support this function\n"); + return -EFAULT; + } + + return mtk_p2p_cfg80211_set_bitrate_mask(wiphy, dev, peer, + mask); +} + +int mtk_cfg_set_txpower(struct wiphy *wiphy, + struct wireless_dev *wdev, + enum nl80211_tx_power_setting type, int mbm) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + + if (mtk_IsP2PNetDevice(prGlueInfo, wdev->netdev) <= 0) { + DBGLOG(REQ, WARN, "STA doesn't support this function\n"); + return -EFAULT; + } + + return mtk_p2p_cfg80211_set_txpower(wiphy, wdev, type, mbm); +} + +int mtk_cfg_get_txpower(struct wiphy *wiphy, + struct wireless_dev *wdev, + int *dbm) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + if ((!prGlueInfo) || (prGlueInfo->u4ReadyFlag == 0)) { + DBGLOG_LIMITED(REQ, TRACE, "driver is not ready\n"); + return -EFAULT; + } + + if (mtk_IsP2PNetDevice(prGlueInfo, wdev->netdev) <= 0) { + DBGLOG_LIMITED(REQ, TRACE, + "STA doesn't support this function\n"); + return -EFAULT; + } + + return mtk_p2p_cfg80211_get_txpower(wiphy, wdev, dbm); +} +#endif /* (CFG_ENABLE_WIFI_DIRECT_CFG_80211 != 0) */ +#endif /* CFG_ENABLE_UNIFY_WIPHY */ + +/*-----------------------------------------------------------------------*/ +/*! + * @brief This function goes through the provided ies buffer, and + * collects those non-wfa vendor specific ies into driver's + * internal buffer (non_wfa_vendor_ie_buf), to be sent in + * AssocReq in AIS mode. + * The non-wfa vendor specific ies are those with ie_id = 0xdd + * and ouis are different from wfa's oui. (i.e., it could be + * customer's vendor ie ...etc. + * + * @param prGlueInfo driver's private glueinfo + * ies ie buffer + * len length of ie + * + * @retval length of the non_wfa vendor ie + */ +/*-----------------------------------------------------------------------*/ +uint16_t cfg80211_get_non_wfa_vendor_ie(struct GLUE_INFO *prGlueInfo, + uint8_t *ies, int32_t len, uint8_t ucBssIndex) +{ + const uint8_t *pos = ies, *end = ies+len; + struct ieee80211_vendor_ie *ie; + int32_t ie_oui = 0; + uint16_t *ret_len, max_len; + uint8_t *w_pos; + struct CONNECTION_SETTINGS *prConnSettings; + + if (!prGlueInfo || !ies || !len) + return 0; + + prConnSettings = + aisGetConnSettings(prGlueInfo->prAdapter, + ucBssIndex); + if (!prConnSettings) + return 0; + + w_pos = prConnSettings->non_wfa_vendor_ie_buf; + ret_len = &prConnSettings->non_wfa_vendor_ie_len; + max_len = (uint16_t)sizeof(prConnSettings->non_wfa_vendor_ie_buf); + + while (pos < end) { + pos = cfg80211_find_ie(WLAN_EID_VENDOR_SPECIFIC, pos, + end - pos); + if (!pos) + break; + + ie = (struct ieee80211_vendor_ie *)pos; + + /* Make sure we can access ie->len */ + BUILD_BUG_ON(offsetof(struct ieee80211_vendor_ie, len) != 1); + + if (ie->len < sizeof(*ie)) + goto cont; + + ie_oui = ie->oui[0] << 16 | ie->oui[1] << 8 | ie->oui[2]; + /* + * If oui is other than: 0x0050f2 & 0x506f9a, + * we consider it is non-wfa oui. + */ + if (ie_oui != WLAN_OUI_MICROSOFT && ie_oui != WLAN_OUI_WFA) { + /* + * If remaining buf len is capable, we copy + * this ie to the buf. + */ + if (max_len-(*ret_len) >= ie->len+2) { + DBGLOG(AIS, TRACE, + "vendor ie(len=%d, oui=0x%06x)\n", + ie->len, ie_oui); + memcpy(w_pos, pos, ie->len+2); + w_pos += (ie->len+2); + (*ret_len) += ie->len+2; + } else { + /* Otherwise we give an error msg + * and return. + */ + DBGLOG(AIS, ERROR, + "Insufficient buf for vendor ie, exit!\n"); + break; + } + } +cont: + pos += 2 + ie->len; + } + return *ret_len; +} + +int mtk_cfg80211_update_ft_ies(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_update_ft_ies_params *ftie) +{ +#if CFG_SUPPORT_802_11R + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t u4InfoBufLen = 0; + uint32_t rStatus = WLAN_STATUS_FAILURE; + uint8_t ucBssIndex = 0; + + if (!wiphy) + return -1; + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + ucBssIndex = wlanGetBssIdx(dev); + if (!IS_BSS_INDEX_VALID(ucBssIndex)) + return -EINVAL; + + rStatus = kalIoctlByBssIdx(prGlueInfo, wlanoidUpdateFtIes, (void *)ftie, + sizeof(*ftie), FALSE, FALSE, FALSE, &u4InfoBufLen, + ucBssIndex); + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(OID, INFO, "FT: update Ft IE failed\n"); +#else + DBGLOG(OID, INFO, "FT: 802.11R is not enabled\n"); +#endif + + return 0; +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_hook_api.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_hook_api.c new file mode 100644 index 0000000000000000000000000000000000000000..f6424c317730a132c95ff143cf841ac409f1af1c --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_hook_api.c @@ -0,0 +1,4696 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ +/* + Module Name: + gl_ate_agent.c +*/ +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" +#if CFG_SUPPORT_QA_TOOL +#include "gl_wext.h" +#include "gl_cfg80211.h" +#include "gl_ate_agent.h" +#include "gl_qa_agent.h" +#if KERNEL_VERSION(3, 8, 0) <= CFG80211_VERSION_CODE +#include +#endif + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +enum { + ATE_LOG_RXV = 1, + ATE_LOG_RDD, + ATE_LOG_RE_CAL, + ATE_LOG_TYPE_NUM, + ATE_LOG_RXINFO, + ATE_LOG_TXDUMP, + ATE_LOG_TEST, +}; + +enum { + ATE_LOG_OFF, + ATE_LOG_ON, + ATE_LOG_DUMP, + ATE_LOG_CTRL_NUM, +}; + +/* Maximum rxv vectors under 2048-2 bytes */ +#define MAX_RXV_DUMP_COUNT (56) +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Enter Test Mode. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prInBuf + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATEStart(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + uint32_t u4BufLen = 0; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK SetATE = %s\n", prInBuf); + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetTestMode, /* pfnOidHandler */ + NULL, /* pvInfoBuf */ + 0, /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Enter ICAP Mode. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prInBuf + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ICAPStart(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + uint32_t u4BufLen = 0; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK SetATE = %s\n", prInBuf); + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetTestIcapMode, /* pfnOidHandler */ + NULL, /* pvInfoBuf */ + 0, /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Enter ICAP Mode. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prInBuf + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ICAPCommand(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + int32_t i4Status = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct mt66xx_chip_info *prChipInfo = NULL; + struct ATE_OPS_T *prAteOps = NULL; + uint32_t *buf = NULL; + + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK SetATE = %s\n", prInBuf); + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prChipInfo = prGlueInfo->prAdapter->chip_info; + ASSERT(prChipInfo); + prAteOps = prChipInfo->prAteOps; + ASSERT(prAteOps); + + if (prInBuf[0] == '1') { + if (prAteOps->setICapStart) + i4Status = prAteOps->setICapStart(prGlueInfo, + 1, + 0, + 0, + 0x10000006, + 0, + 10, + 0, + 0x2000, + 0xefefefef, + 0x0001efef, + 0); + else + i4Status = 1; + } else if (prInBuf[0] == '2') { + if (prAteOps->getICapStatus) + i4Status = prAteOps->getICapStatus(prGlueInfo); + else + i4Status = 1; + } else if (prInBuf[0] == '3') { + if (prAteOps->getICapIQData) { + buf = kalMemAlloc(1024, VIR_MEM_TYPE); + if (buf) { + i4Status = prAteOps->getICapIQData(prGlueInfo, + (uint8_t *) buf, CAP_I_TYPE, 0); + dumpMemory32((uint32_t *)buf, i4Status); + kalMemFree(buf, VIR_MEM_TYPE, 1024); + } + } else + i4Status = 1; + } else if (prInBuf[0] == '4') { + if (prAteOps->getICapIQData) { + buf = (uint32_t *) kalMemAlloc(1024, VIR_MEM_TYPE); + if (buf) { + i4Status = prAteOps->getICapIQData(prGlueInfo, + (uint8_t *) buf, CAP_Q_TYPE, 0); + dumpMemory32((uint32_t *)buf, i4Status); + kalMemFree(buf, VIR_MEM_TYPE, 1024); + } + } else + i4Status = 1; + } else if (prInBuf[0] == '5') { + if (prAteOps->getICapIQData) { + buf = (uint32_t *) kalMemAlloc(1024, VIR_MEM_TYPE); + if (buf) { + i4Status = prAteOps->getICapIQData(prGlueInfo, + (uint8_t *) buf, CAP_I_TYPE, 1); + dumpMemory32((uint32_t *)buf, i4Status); + kalMemFree(buf, VIR_MEM_TYPE, 1024); + } + } else + i4Status = 1; + } else if (prInBuf[0] == '6') { + if (prAteOps->getICapIQData) { + buf = (uint32_t *) kalMemAlloc(1024, VIR_MEM_TYPE); + if (buf) { + i4Status = prAteOps->getICapIQData(prGlueInfo, + (uint8_t *) buf, CAP_Q_TYPE, 1); + dumpMemory32((uint32_t *)buf, i4Status); + kalMemFree(buf, VIR_MEM_TYPE, 1024); + } + } else + i4Status = 1; + } + + return i4Status; +} + + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Abort Test Mode. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prInBuf + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATEStop(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + uint32_t u4BufLen = 0; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK SetATE = %s\n", prInBuf); + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAbortTestMode, /* pfnOidHandler */ + NULL, /* pvInfoBuf */ + 0, /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Start auto Tx test in packet format and the driver will + * enter auto Tx test mode. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prInBuf + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATEStartTX(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + uint32_t u4BufLen = 0; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK SetATE = %s\n", prInBuf); + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_COMMAND; + rRfATInfo.u4FuncData = RF_AT_COMMAND_STARTTX; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Stop TX/RX test action if the driver is in any test + * mode. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prInBuf + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATEStopTX(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + uint32_t u4BufLen = 0; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK SetATE = %s\n", prInBuf); + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_COMMAND; + rRfATInfo.u4FuncData = RF_AT_COMMAND_STOPTEST; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Start auto Rx test and the driver will enter auto Rx + * test mode. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prInBuf + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATEStartRX(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + uint32_t u4BufLen = 0; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK SetATE = %s\n", prInBuf); + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_COMMAND; + rRfATInfo.u4FuncData = RF_AT_COMMAND_STARTRX; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Stop TX/RX test action if the driver is in any test + * mode. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prInBuf + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATEStopRX(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + uint32_t u4BufLen = 0; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK SetATE = %s\n", prInBuf); + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_COMMAND; + rRfATInfo.u4FuncData = RF_AT_COMMAND_STOPTEST; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Set Channel Frequency. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] u4SetFreq Center frequency in unit of KHz + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATESetChannel(struct net_device *prNetDev, + uint32_t u4SXIdx, uint32_t u4SetFreq) +{ + uint32_t u4BufLen = 0; + uint32_t i4SetChan; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + i4SetChan = nicFreq2ChannelNum(u4SetFreq); + + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK SetChannel=%d, Freq=%d\n", + i4SetChan, u4SetFreq); + + if (u4SetFreq == 0) + return -EINVAL; + + if (u4SXIdx == 0) { + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_CHNL_FREQ; + rRfATInfo.u4FuncData = u4SetFreq; + } else { + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_CHNL_FREQ | BIT(16); + rRfATInfo.u4FuncData = u4SetFreq; + } + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Set Preamble. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] u4Mode depends on Rate. 0--> normal, + * 1--> CCK short preamble, + * 2: 11n MM, + * 3: 11n GF + * 4: 11ac VHT + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATESetPreamble(struct net_device *prNetDev, + uint32_t u4Mode) +{ + uint32_t u4BufLen = 0; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK SetPreamble=%d\n", + u4Mode); + + if (u4Mode > 4) + return -EINVAL; + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_PREAMBLE; + rRfATInfo.u4FuncData = u4Mode; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Set Channel Bandwidth. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] u4BW Choose Channel Bandwidth + * 0: 20 / 1: 40 / 2: 80 / 3: 160 + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATESetSystemBW(struct net_device *prNetDev, + uint32_t u4BW) +{ + uint32_t u4BufLen = 0; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + uint32_t u4BWMapping = 0; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK SetSystemBW=%d\n", u4BW); + + if (u4BW > 6) + return -EINVAL; + + /* BW Mapping in QA Tool + * 0: BW20 + * 1: BW40 + * 2: BW80 + * 3: BW10 + * 4: BW5 + * 5: BW160C + * 6: BW160NC + */ + /* BW Mapping in FW + * 0: BW20 + * 1: BW40 + * 2: BW80 + * 3: BW160C + * 4: BW160NC + * 5: BW5 + * 6: BW10 + */ + if (u4BW == 0) + u4BWMapping = 0; + else if (u4BW == 1) + u4BWMapping = 1; + else if (u4BW == 2) + u4BWMapping = 2; + else if (u4BW == 3) + u4BWMapping = 6; + else if (u4BW == 4) + u4BWMapping = 5; + else if (u4BW == 5) + u4BWMapping = 3; + else if (u4BW == 6) + u4BWMapping = 4; + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_CBW; + rRfATInfo.u4FuncData = u4BWMapping; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Set TX Length. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] u4TxLength Packet length (MPDU) + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATESetTxLength(struct net_device *prNetDev, + uint32_t u4TxLength) +{ + uint32_t u4BufLen = 0; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK SetTxLength=%d\n", + u4TxLength); + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_PKTLEN; + rRfATInfo.u4FuncData = u4TxLength; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Set TX Count. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] u4TxCount Total packet count to send. 0 : unlimited, + * until stopped + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATESetTxCount(struct net_device *prNetDev, + uint32_t u4TxCount) +{ + uint32_t u4BufLen = 0; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK SetTxCount=%d\n", + u4TxCount); + + if (u4TxCount < 0) + return -EINVAL; + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_PKTCNT; + rRfATInfo.u4FuncData = u4TxCount; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Set TX Inter-Packet Guard. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] u4TxIPG In unit of us. The min value is 19us and max + * value is 2314us. + * \ It will be round-up to (19+9n) us. + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATESetTxIPG(struct net_device *prNetDev, + uint32_t u4TxIPG) +{ + uint32_t u4BufLen = 0; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK SetTxIPG=%d\n", u4TxIPG); + + if (u4TxIPG > 2314 || u4TxIPG < 19) + return -EINVAL; + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_PKTINTERVAL; + rRfATInfo.u4FuncData = u4TxIPG; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Set WF0 TX Power. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] u4TxPower0 Tx Gain of RF. The value is signed absolute + * power + * (2's complement representation) in unit of 0.5 dBm. + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATESetTxPower0(struct net_device *prNetDev, + uint32_t u4TxPower0) +{ + uint32_t u4BufLen = 0; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK SetTxPower0=0x%02x\n", + u4TxPower0); + + if (u4TxPower0 > 0x3F) { + u4TxPower0 += 128; + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK Negative Power =0x%02x\n", + u4TxPower0); + } + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_POWER; + rRfATInfo.u4FuncData = u4TxPower0; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Set Per Packet BW. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] u4BW 0: 20 / 1: 40 / 2: 80 / 3: 160 + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATESetPerPacketBW(struct net_device *prNetDev, + uint32_t u4BW) +{ + uint32_t u4BufLen = 0; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + uint32_t u4BWMapping = 0; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK SetPerPacketBW=%d\n", + u4BW); + + if (u4BW > 6) + return -EINVAL; + + /* BW Mapping in QA Tool + * 0: BW20 + * 1: BW40 + * 2: BW80 + * 3: BW10 + * 4: BW5 + * 5: BW160C + * 6: BW160NC + */ + /* BW Mapping in FW + * 0: BW20 + * 1: BW40 + * 2: BW80 + * 3: BW160C + * 4: BW160NC + * 5: BW5 + * 6: BW10 + */ + if (u4BW == 0) + u4BWMapping = 0; + else if (u4BW == 1) + u4BWMapping = 1; + else if (u4BW == 2) + u4BWMapping = 2; + else if (u4BW == 3) + u4BWMapping = 6; + else if (u4BW == 4) + u4BWMapping = 5; + else if (u4BW == 5) + u4BWMapping = 3; + else if (u4BW == 6) + u4BWMapping = 4; + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_DBW; + rRfATInfo.u4FuncData = u4BWMapping; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Primary Channel Setting. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] u4PrimaryCh The range is from 0~7 + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATEPrimarySetting(struct net_device *prNetDev, + uint32_t u4PrimaryCh) +{ + uint32_t u4BufLen = 0; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK PrimarySetting=%d\n", + u4PrimaryCh); + + if (u4PrimaryCh > 7) + return -EINVAL; + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_PRIMARY_CH; + rRfATInfo.u4FuncData = u4PrimaryCh; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Set TX Guard Interval. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] u4SetTxGi 0: Normal GI, 1: Short GI + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATESetTxGi(struct net_device *prNetDev, + uint32_t u4SetTxGi) +{ + uint32_t u4BufLen = 0; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK SetTxGi=%d\n", u4SetTxGi); + + if (u4SetTxGi != 0 && u4SetTxGi != 1) + return -EINVAL; + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_GI; + rRfATInfo.u4FuncData = u4SetTxGi; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Set TX Path. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] u4Tx_path 0: All Tx, 1: WF0, 2: WF1, 3: WF0+WF1 + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATESetTxPath(struct net_device *prNetDev, + uint32_t u4Tx_path) +{ + uint32_t u4BufLen = 0; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK u4Tx_path=%d\n", + u4Tx_path); + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_TX_PATH; + rRfATInfo.u4FuncData = u4Tx_path; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Set RX Path. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] u4Tx_path + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATESetRxPath(struct net_device *prNetDev, uint32_t u4Rx_path) +{ + uint32_t u4BufLen = 0; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK u4Rx_path=%d\n", u4Rx_path); + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_RX_PATH; + rRfATInfo.u4FuncData = u4Rx_path; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; +} + + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Set TX Payload Fix/Random. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] u4Stbc 0: Disable , 1 : Enable + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATESetTxPayLoad(struct net_device *prNetDev, + uint32_t u4Gen_payload_rule, uint8_t ucPayload) +{ + uint32_t u4BufLen = 0; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK rule=%d, len =0x%x\n", + u4Gen_payload_rule, ucPayload); + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_PAYLOAD; + rRfATInfo.u4FuncData = ((u4Gen_payload_rule << 16) | + ucPayload); + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Set TX STBC. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] u4Stbc 0: Disable , 1 : Enable + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATESetTxSTBC(struct net_device *prNetDev, + uint32_t u4Stbc) +{ + uint32_t u4BufLen = 0; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK u4Stbc=%d\n", u4Stbc); + + if (u4Stbc > 1) + return -EINVAL; + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_STBC; + rRfATInfo.u4FuncData = u4Stbc; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Set TX Nss. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] u4Nss 1/2 + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATESetTxVhtNss(struct net_device *prNetDev, + uint32_t u4VhtNss) +{ + uint32_t u4BufLen = 0; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK u4Nss=%d\n", u4VhtNss); + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_NSS; + rRfATInfo.u4FuncData = u4VhtNss; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Set Rate. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] u4Rate Rate + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATESetRate(struct net_device *prNetDev, + uint32_t u4Rate) +{ + uint32_t u4BufLen = 0; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK SetRate=0x%08x\n", + u4Rate); + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_RATE; + rRfATInfo.u4FuncData = u4Rate; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Set Encode Mode. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] u4Ldpc 0: BCC / 1: LDPC + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATESetEncodeMode(struct net_device *prNetDev, + uint32_t u4Ldpc) +{ + uint32_t u4BufLen = 0; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK SetEncodeMode=%d\n", + u4Ldpc); + + if (u4Ldpc != 0 && u4Ldpc != 1) + return -EINVAL; + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_ENCODE_MODE; + rRfATInfo.u4FuncData = u4Ldpc; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Set iBF Enable. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] u4iBF 0: disable / 1: enable + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATESetiBFEnable(struct net_device *prNetDev, + uint32_t u4iBF) +{ + uint32_t u4BufLen = 0; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK SetiBFEnable=%d\n", + u4iBF); + + if (u4iBF != 0 && u4iBF != 1) + return -EINVAL; + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_IBF_ENABLE; + rRfATInfo.u4FuncData = u4iBF; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Set eBF Enable. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] u4eBF 0: disable / 1: enable + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATESeteBFEnable(struct net_device *prNetDev, + uint32_t u4eBF) +{ + uint32_t u4BufLen = 0; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK SeteBFEnable=%d\n", + u4eBF); + + if (u4eBF != 0 && u4eBF != 1) + return -EINVAL; + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_EBF_ENABLE; + rRfATInfo.u4FuncData = u4eBF; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Set MAC Address. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] u4Type Address type + * \param[in] ucAddr Address ready to set + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATESetMACAddress(struct net_device *prNetDev, + uint32_t u4Type, uint8_t *ucAddr) +{ + uint32_t u4BufLen = 0; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(RFTEST, ERROR, + "QA_ATE_HOOK SetMACAddress Type = %d, Addr = %02x:%02x:%02x:%02x:%02x:%02x\n", + u4Type, ucAddr[0], ucAddr[1], ucAddr[2], ucAddr[3], + ucAddr[4], ucAddr[5]); + +#if 1 + rRfATInfo.u4FuncIndex = u4Type; + memcpy(&rRfATInfo.u4FuncData, ucAddr, 4); + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; +#endif + rRfATInfo.u4FuncIndex = u4Type | BIT(18); + memset(&rRfATInfo.u4FuncData, 0, + sizeof(rRfATInfo.u4FuncData)); + memcpy(&rRfATInfo.u4FuncData, ucAddr + 4, 2); + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for RX Vector Dump. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] u4Type + * \param[in] u4On_off + * \param[in] u4Size + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATELogOnOff(struct net_device *prNetDev, + uint32_t u4Type, uint32_t u4On_off, uint32_t u4Size) +{ + int32_t i4Status = 0, i, i4TargetLength = 0, + i4MaxDumpRXVCnt = 500; + uint32_t u4BufLen = 0, rxv; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK MT_ATELogOnOff\n"); + + switch (u4Type) { + case ATE_LOG_RXV: + DBGLOG(RFTEST, INFO, + "QA_ATE_HOOK MT_ATELogOnOff : ATE_LOG_RXV\n\n"); + break; + case ATE_LOG_RDD: + DBGLOG(RFTEST, INFO, + "QA_ATE_HOOK MT_ATELogOnOff : ATE_LOG_RDD\n\n"); + break; + case ATE_LOG_RE_CAL: + DBGLOG(RFTEST, INFO, + "QA_ATE_HOOK MT_ATELogOnOff : ATE_LOG_RE_CAL\n\n"); + break; + case ATE_LOG_RXINFO: + DBGLOG(RFTEST, INFO, + "QA_ATE_HOOK MT_ATELogOnOff : ATE_LOG_RXINFO\n\n"); + break; + case ATE_LOG_TXDUMP: + DBGLOG(RFTEST, INFO, + "QA_ATE_HOOK MT_ATELogOnOff : ATE_LOG_TXDUMP\n\n"); + break; + case ATE_LOG_TEST: + DBGLOG(RFTEST, INFO, + "QA_ATE_HOOK MT_ATELogOnOff : ATE_LOG_TEST\n\n"); + break; + default: + DBGLOG(RFTEST, INFO, + "QA_ATE_HOOK log type %d not supported\n\n", u4Type); + } + + if ((u4On_off == ATE_LOG_DUMP) && (u4Type == ATE_LOG_RXV)) { + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_RESULT_INFO; + rRfATInfo.u4FuncData = RF_AT_FUNCID_RXV_DUMP; + + i4Status = kalIoctl(prGlueInfo, wlanoidRftestQueryAutoTest, + &rRfATInfo, sizeof(rRfATInfo), + TRUE, TRUE, TRUE, &u4BufLen); + + if (i4Status == 0) { + i4TargetLength = rRfATInfo.u4FuncData * 36; + DBGLOG(RFTEST, ERROR, + "QA_ATE_HOOK Get RX Vector Total size = %d\n", + i4TargetLength); + + if (i4TargetLength >= (i4MaxDumpRXVCnt * 36)) + i4TargetLength = (i4MaxDumpRXVCnt * 36); + } else { + DBGLOG(RFTEST, ERROR, + "QA_ATE_HOOK Get RX Vector Total Size Error!!!!\n\n"); + } + + TOOL_PRINTLOG(RFTEST, ERROR, "[LOG DUMP START]\n"); + + for (i = 0; i < i4TargetLength; i += 4) { + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_RXV_DUMP; + rRfATInfo.u4FuncData = i; + + i4Status = kalIoctl(prGlueInfo, + wlanoidRftestQueryAutoTest, + &rRfATInfo, sizeof(rRfATInfo), + TRUE, TRUE, TRUE, &u4BufLen); + + if (i4Status == 0) { + rxv = rRfATInfo.u4FuncData; + + if (i % 36 == 0) + TOOL_PRINTLOG(RFTEST, ERROR, + "%%[RXV DUMP START][%d]\n", + (i / 36) + 1); + + TOOL_PRINTLOG(RFTEST, ERROR, "[RXVD%d]%08x\n", + ((i % 36) / 4) + 1, rxv); + + if (((i % 36) / 4) + 1 == 9) + TOOL_PRINTLOG(RFTEST, ERROR, + "[RXV DUMP END]\n"); + } + } + + TOOL_PRINTLOG(RFTEST, ERROR, "[LOG DUMP END]\n"); + } + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Hook API for Get RX Vector Dump. +* +* \param[in] prNetDev Pointer to the Net Device +* \param[out] pucData Pointer to the output data buffer +* \param[out] pCount Pointer to the length of data +* +* \retval 0 On success. +* \retval -EFAULT If kalIoctl return nonzero. +*/ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATEGetDumpRXV(struct net_device *prNetDev, + uint8_t *pucData, + int32_t *pCount) +{ + int32_t i4Status = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + uint32_t i = 0, u4BufLen = 0, u4Value = 0; + uint32_t u4RespLen = 2, i4TargetLength = 0; + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_RESULT_INFO; + rRfATInfo.u4FuncData = RF_AT_FUNCID_RXV_DUMP; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + ASSERT(prGlueInfo); + + i4Status = kalIoctl(prGlueInfo, + wlanoidRftestQueryAutoTest, + &rRfATInfo, + sizeof(rRfATInfo), + TRUE, + TRUE, + TRUE, + &u4BufLen); + + if (i4Status == 0) { + DBGLOG(RFTEST, INFO, "Get RX Vector Total count = %d\n", + rRfATInfo.u4FuncData); + if (rRfATInfo.u4FuncData > MAX_RXV_DUMP_COUNT) + rRfATInfo.u4FuncData = MAX_RXV_DUMP_COUNT; + + i4TargetLength = rRfATInfo.u4FuncData * 36; + u4Value = ntohl(rRfATInfo.u4FuncData); + kalMemCopy(pucData + u4RespLen, + (uint8_t *)&u4Value, + sizeof(u4Value)); + u4RespLen += sizeof(u4Value); + } else { + DBGLOG(RFTEST, ERROR, "Get RX Vector Total Size Error!!\n"); + return -EFAULT; + } + + for (i = 0; i < i4TargetLength; i += 4) { + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_RXV_DUMP; + rRfATInfo.u4FuncData = i; + + i4Status = kalIoctl(prGlueInfo, + wlanoidRftestQueryAutoTest, + &rRfATInfo, + sizeof(rRfATInfo), + TRUE, + TRUE, + TRUE, + &u4BufLen); + + if (i4Status == 0) { + u4Value = ntohl(rRfATInfo.u4FuncData); + kalMemCopy(pucData + u4RespLen, + (uint8_t *)&u4Value, + sizeof(u4Value)); + u4RespLen += sizeof(u4Value); + } else { + DBGLOG(RFTEST, ERROR, + "Error getting index[%d]'s RXV dump data!!\n", i); + return -EFAULT; + } + } + + *pCount = i4TargetLength; + /* dumpMemory32((PUINT_32)pucData, i4TargetLength + 8); */ + + return 0; +} + + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Reset Counter. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATEResetTXRXCounter(struct net_device *prNetDev) +{ + uint32_t u4BufLen = 0; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(RFTEST, INFO, + "QA_ATE_HOOK MT_ATEResetTXRXCounter\n"); + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_RESETTXRXCOUNTER; + rRfATInfo.u4FuncData = 0; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Set DBDC Band Index. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] u4BandIdx Band Index Number ready to set + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATESetDBDCBandIndex(struct net_device *prNetDev, + uint32_t u4BandIdx) +{ + uint32_t u4BufLen = 0; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(RFTEST, INFO, + "QA_ATE_HOOK MT_ATESetDBDCBandIndex\n"); + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_DBDC_BAND_IDX; + rRfATInfo.u4FuncData = u4BandIdx; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Set Band. (2G or 5G) + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] i4Band Band to set + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATESetBand(struct net_device *prNetDev, + int32_t i4Band) +{ + uint32_t u4BufLen = 0; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK MT_ATESetBand\n"); + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_BAND; + rRfATInfo.u4FuncData = i4Band; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Set Tx Tone Type. (2G or 5G) + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] i4ToneType Set Single or Two Tone. + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATESetTxToneType(struct net_device *prNetDev, + int32_t i4ToneType) +{ + uint32_t u4BufLen = 0; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK MT_ATESetTxToneType\n"); + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_TONE_TYPE; + rRfATInfo.u4FuncData = i4ToneType; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Set Tx Tone Frequency. (DC/5M/10M/20M/40M) + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] i4ToneFreq Set Tx Tone Frequency. + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATESetTxToneBW(struct net_device *prNetDev, + int32_t i4ToneFreq) +{ + uint32_t u4BufLen = 0; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK MT_ATESetTxToneBW\n"); + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_TONE_BW; + rRfATInfo.u4FuncData = i4ToneFreq; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Set Tx Tone DC Offset. (DC Offset I / DC Offset Q) + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] i4DcOffsetI Set Tx Tone DC Offset I. + * \param[in] i4DcOffsetQ Set Tx Tone DC Offset Q. + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATESetTxToneDCOffset(struct net_device *prNetDev, + int32_t i4DcOffsetI, int32_t i4DcOffsetQ) +{ + uint32_t u4BufLen = 0; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(RFTEST, INFO, + "QA_ATE_HOOK MT_ATESetTxToneDCOffset\n"); + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_TONE_DC_OFFSET; + rRfATInfo.u4FuncData = i4DcOffsetQ << 16 | i4DcOffsetI; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Set Tx Tone Power. (RF and Digital) + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] i4AntIndex + * \param[in] i4RF_Power + * \param[in] i4Digi_Power + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATESetDBDCTxTonePower(struct net_device *prNetDev, + int32_t i4AntIndex, int32_t i4RF_Power, int32_t i4Digi_Power) +{ + uint32_t u4BufLen = 0; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(RFTEST, INFO, + "QA_ATE_HOOK MT_ATESetDBDCTxTonePower\n"); + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_TONE_RF_GAIN; + rRfATInfo.u4FuncData = i4AntIndex << 16 | i4RF_Power; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_TONE_DIGITAL_GAIN; + rRfATInfo.u4FuncData = i4AntIndex << 16 | i4Digi_Power; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Start Tx Tone. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] i4Control Start or Stop TX Tone. + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATEDBDCTxTone(struct net_device *prNetDev, + int32_t i4Control) +{ + uint32_t u4BufLen = 0; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK MT_ATEDBDCTxTone\n"); + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + if (i4Control) { + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_COMMAND; + rRfATInfo.u4FuncData = RF_AT_COMMAND_SINGLE_TONE; + } else { + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_COMMAND; + rRfATInfo.u4FuncData = RF_AT_COMMAND_STOPTEST; + } + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Set TX Mac Header. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] u4BandIdx Band Index Number ready to set + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATESetMacHeader(struct net_device *prNetDev, + uint32_t u4FrameCtrl, uint32_t u4DurationID, + uint32_t u4SeqCtrl) +{ + uint32_t u4BufLen = 0; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK MT_ATESetMacHeader\n"); + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_MAC_HEADER; + rRfATInfo.u4FuncData = u4FrameCtrl || (u4DurationID << 16); + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_SEQ_CTRL; + rRfATInfo.u4FuncData = u4SeqCtrl; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for IRR Set ADC. (RF_AT_FUNCID_SET_ADC) + * + * \param[in] prNetDev Pointer to the Net Device + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATE_IRRSetADC(struct net_device *prNetDev, + uint32_t u4WFIdx, + uint32_t u4ChFreq, + uint32_t u4BW, uint32_t u4Sx, uint32_t u4Band, + uint32_t u4RunType, uint32_t u4FType) +{ + uint32_t u4BufLen = 0, i = 0; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + uint32_t au4Param[7]; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK MT_ATE_IRRSetADC\n"); + + if (u4BW == 3 || u4BW == 4 || u4BW > 5) + return -EINVAL; + + if (u4BW == 5) /* For BW160, UI will pass "5" */ + u4BW = 3; + + au4Param[0] = u4ChFreq; + au4Param[1] = u4WFIdx; + au4Param[2] = u4BW; + au4Param[3] = u4Sx; + au4Param[4] = u4Band; + au4Param[5] = u4RunType; + au4Param[6] = u4FType; + + for (i = 0; i < 8; i++) { + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_ADC | (i << 16); + if (i < 7) + rRfATInfo.u4FuncData = au4Param[i]; + else + rRfATInfo.u4FuncData = 0; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + } + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for IRR Set RX Gain. (RF_AT_FUNCID_SET_RX_GAIN) + * + * \param[in] prNetDev Pointer to the Net Device + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATE_IRRSetRxGain(struct net_device *prNetDev, + uint32_t u4PgaLpfg, uint32_t u4Lna, uint32_t u4Band, + uint32_t u4WF_inx, uint32_t u4Rfdgc) +{ + uint32_t u4BufLen = 0, i = 0; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + uint32_t au4Param[5]; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK MT_ATE_IRRSetRxGain\n"); + + au4Param[0] = u4PgaLpfg; + au4Param[1] = u4Lna; + au4Param[2] = u4Band; + au4Param[3] = u4WF_inx; + au4Param[4] = u4Rfdgc; + + for (i = 0; i < 6; i++) { + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_RX_GAIN | + (i << 16); + if (i < 5) + rRfATInfo.u4FuncData = au4Param[i]; + else + rRfATInfo.u4FuncData = 0; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + } + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for IRR Set TTG. (RF_AT_FUNCID_SET_TTG) + * + * \param[in] prNetDev Pointer to the Net Device + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATE_IRRSetTTG(struct net_device *prNetDev, + uint32_t u4TTGPwrIdx, uint32_t u4ChFreq, + uint32_t u4FIToneFreq, uint32_t u4Band) +{ + uint32_t u4BufLen = 0, i = 0; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + uint32_t au4Param[4]; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK MT_ATE_IRRSetTTG\n"); + + au4Param[0] = u4ChFreq; + au4Param[1] = u4FIToneFreq; + au4Param[2] = u4TTGPwrIdx; + au4Param[3] = u4Band; + + for (i = 0; i < 5; i++) { + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_TTG | (i << 16); + if (i < 4) + rRfATInfo.u4FuncData = au4Param[i]; + else + rRfATInfo.u4FuncData = 0; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + } + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for IRR Set TTG On/Off. (RF_AT_FUNCID_TTG_ON_OFF) + * + * \param[in] prNetDev Pointer to the Net Device + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATE_IRRSetTrunOnTTG(struct net_device *prNetDev, + uint32_t u4TTGOnOff, uint32_t u4Band, uint32_t u4WF_inx) +{ + uint32_t u4BufLen = 0, i = 0; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + uint32_t au4Param[3]; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(RFTEST, INFO, + "QA_ATE_HOOK MT_ATE_IRRSetTrunOnTTG\n"); + + au4Param[0] = u4TTGOnOff; + au4Param[1] = u4Band; + au4Param[2] = u4WF_inx; + + for (i = 0; i < 4; i++) { + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_TTG_ON_OFF | (i << 16); + if (i < 3) + rRfATInfo.u4FuncData = au4Param[i]; + else + rRfATInfo.u4FuncData = 0; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + } + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for IRR Set TTG On/Off. + * + * \param[in] prNetDev Pointer to the Net Device + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATE_TMRSetting(struct net_device *prNetDev, uint32_t u4Setting, + uint32_t u4Version, uint32_t u4MPThres, uint32_t u4MPIter) +{ + uint32_t u4BufLen = 0; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK MT_ATE_TMRSetting\n"); + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_TMR_ROLE; + rRfATInfo.u4FuncData = u4Setting; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_TMR_MODULE; + rRfATInfo.u4FuncData = u4Version; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_TMR_DBM; + rRfATInfo.u4FuncData = u4MPThres; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_TMR_ITER; + rRfATInfo.u4FuncData = u4MPIter; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for MPS Setting. (Set Seq Data) + * + * \param[in] prNetDev Pointer to the Net Device + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATEMPSSetSeqData(struct net_device *prNetDev, + uint32_t u4TestNum, uint32_t *pu4Phy, uint32_t u4Band) +{ + uint32_t u4BufLen = 0, i; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK MT_ATEMPSSetSeqData\n"); + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_MPS_SIZE; + rRfATInfo.u4FuncData = u4TestNum; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + for (i = 0 ; i < u4TestNum ; i++) { + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_MPS_SEQ_DATA | + (i << 16); + rRfATInfo.u4FuncData = pu4Phy[i]; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + } + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for MPS Setting. (Set Payload Length) + * + * \param[in] prNetDev Pointer to the Net Device + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATEMPSSetPayloadLength(struct net_device *prNetDev, + uint32_t u4TestNum, uint32_t *pu4Length, uint32_t u4Band) +{ + uint32_t u4BufLen = 0, i; + int32_t i4Status = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + DBGLOG(RFTEST, INFO, + "QA_ATE_HOOK MT_ATEMPSSetPayloadLength\n"); + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + for (i = 0 ; i < u4TestNum ; i++) { + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_MPS_PAYLOAD_LEN | + (i << 16); + rRfATInfo.u4FuncData = pu4Length[i]; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + } + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for MPS Setting. (Set Packet Count) + * + * \param[in] prNetDev Pointer to the Net Device + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATEMPSSetPacketCount(struct net_device *prNetDev, + uint32_t u4TestNum, uint32_t *pu4PktCnt, uint32_t u4Band) +{ + uint32_t u4BufLen = 0, i; + int32_t i4Status = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + DBGLOG(RFTEST, INFO, + "QA_ATE_HOOK MT_ATEMPSSetPacketCount\n"); + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + for (i = 0 ; i < u4TestNum ; i++) { + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_MPS_PKT_CNT | + (i << 16); + rRfATInfo.u4FuncData = pu4PktCnt[i]; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + } + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for MPS Setting. (Set Power Gain) + * + * \param[in] prNetDev Pointer to the Net Device + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATEMPSSetPowerGain(struct net_device *prNetDev, + uint32_t u4TestNum, uint32_t *pu4PwrGain, uint32_t u4Band) +{ + uint32_t u4BufLen = 0, i; + int32_t i4Status = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK MT_ATEMPSSetPowerGain\n"); + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + for (i = 0 ; i < u4TestNum ; i++) { + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_MPS_PWR_GAIN | + (i << 16); + rRfATInfo.u4FuncData = pu4PwrGain[i]; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + } + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for MPS Setting. (Set NSS) + * + * \param[in] prNetDev Pointer to the Net Device + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATEMPSSetNss(struct net_device *prNetDev, + uint32_t u4TestNum, uint32_t *pu4Nss, uint32_t u4Band) +{ + uint32_t u4BufLen = 0, i; + int32_t i4Status = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK MT_ATEMPSSetNss\n"); + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + for (i = 0 ; i < u4TestNum ; i++) { + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_MPS_NSS | + (i << 16); + rRfATInfo.u4FuncData = pu4Nss[i]; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + } + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for MPS Setting. (Set NSS) + * + * \param[in] prNetDev Pointer to the Net Device + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATEMPSSetPerpacketBW(struct net_device *prNetDev, + uint32_t u4TestNum, uint32_t *pu4PerPktBW, uint32_t u4Band) +{ + uint32_t u4BufLen = 0, i; + int32_t i4Status = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + DBGLOG(RFTEST, INFO, + "QA_ATE_HOOK MT_ATEMPSSetPerpacketBW\n"); + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + for (i = 0 ; i < u4TestNum ; i++) { + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_MPS_PACKAGE_BW | + (i << 16); + rRfATInfo.u4FuncData = pu4PerPktBW[i]; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + } + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Start RDD. + * + * \param[in] prNetDev Pointer to the Net Device + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATERDDStart(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + uint32_t u4BufLen = 0; + int32_t i4Status = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK SetATE = %s\n", prInBuf); + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_COMMAND; + rRfATInfo.u4FuncData = RF_AT_COMMAND_RDD; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Stop RDD. + * + * \param[in] prNetDev Pointer to the Net Device + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATERDDStop(struct net_device *prNetDev, + uint8_t *prInBuf) +{ + uint32_t u4BufLen = 0; + int32_t i4Status = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(RFTEST, INFO, "QA_ATE_HOOK SetATE = %s\n", prInBuf); + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_COMMAND; + rRfATInfo.u4FuncData = RF_AT_COMMAND_RDD_OFF; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; + +} + + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Write Efuse. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] u2Offset Efuse offset + * \param[in] u2Content Efuse content + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATEWriteEfuse(struct net_device *prNetDev, + uint16_t u2Offset, uint16_t u2Content) +{ + uint32_t u4BufLen = 0; + struct PARAM_CUSTOM_ACCESS_EFUSE rAccessEfuseInfoRead, + rAccessEfuseInfoWrite; + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t i4Status = WLAN_STATUS_SUCCESS; + uint8_t u4Index = 0, u4Loop = 0; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + if (!prGlueInfo) { + log_dbg(RFTEST, ERROR, "prGlueInfo is NULL\n"); + return -EFAULT; + } + kalMemSet(&rAccessEfuseInfoRead, 0, + sizeof(struct PARAM_CUSTOM_ACCESS_EFUSE)); + kalMemSet(&rAccessEfuseInfoWrite, 0, + sizeof(struct PARAM_CUSTOM_ACCESS_EFUSE)); + + if (prGlueInfo && + prGlueInfo->prAdapter && + prGlueInfo->prAdapter->chip_info && + !prGlueInfo->prAdapter->chip_info->is_support_efuse) { + log_dbg(RFTEST, WARN, "Efuse not support\n"); + return -EFAULT; + } + + /* Read */ + DBGLOG(INIT, INFO, "QA_AGENT HQA_WriteBulkEEPROM Read\n"); + kalMemSet(&rAccessEfuseInfoRead, 0, + sizeof(struct PARAM_CUSTOM_ACCESS_EFUSE)); + rAccessEfuseInfoRead.u4Address = (u2Offset / + EFUSE_BLOCK_SIZE) * EFUSE_BLOCK_SIZE; + i4Status = kalIoctl(prGlueInfo, + wlanoidQueryProcessAccessEfuseRead, + &rAccessEfuseInfoRead, + sizeof(struct PARAM_CUSTOM_ACCESS_EFUSE), + TRUE, TRUE, TRUE, &u4BufLen); + + + /* Write */ + kalMemSet(&rAccessEfuseInfoWrite, 0, + sizeof(struct PARAM_CUSTOM_ACCESS_EFUSE)); + u4Index = u2Offset % EFUSE_BLOCK_SIZE; + + if (u4Index >= EFUSE_BLOCK_SIZE - 1) { + DBGLOG(INIT, INFO, "u4Index [%d] overrun\n", u4Index); + return -EFAULT; + } + + prGlueInfo->prAdapter->aucEepromVaule[u4Index] = u2Content; + prGlueInfo->prAdapter->aucEepromVaule[u4Index + 1] = + u2Content >> 8 & 0xff; + + kalMemCopy(rAccessEfuseInfoWrite.aucData, + prGlueInfo->prAdapter->aucEepromVaule, 16); + + for (u4Loop = 0; u4Loop < (EFUSE_BLOCK_SIZE); u4Loop++) { + DBGLOG(INIT, INFO, + "QA_AGENT aucEepromVaule u4Loop=%d u4Value=%x\n", + u4Loop, prGlueInfo->prAdapter->aucEepromVaule[u4Loop]); + + DBGLOG(INIT, INFO, + "QA_AGENT rAccessEfuseInfoWrite.aucData u4Loop=%d u4Value=%x\n", + u4Loop, rAccessEfuseInfoWrite.aucData[u4Loop]); + } + + rAccessEfuseInfoWrite.u4Address = (u2Offset / + EFUSE_BLOCK_SIZE) * EFUSE_BLOCK_SIZE; + + i4Status = kalIoctl(prGlueInfo, + wlanoidQueryProcessAccessEfuseWrite, + &rAccessEfuseInfoWrite, + sizeof(struct PARAM_CUSTOM_ACCESS_EFUSE), + FALSE, TRUE, TRUE, &u4BufLen); + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; +} + + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Set Tx Target Power. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] u2TxTargetPower TxTarget Power + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATESetTxTargetPower(struct net_device *prNetDev, + uint8_t ucTxTargetPower) +{ + uint32_t u4BufLen = 0; + struct PARAM_CUSTOM_SET_TX_TARGET_POWER rSetTxTargetPwr; + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t i4Status = WLAN_STATUS_SUCCESS; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + kalMemSet(&rSetTxTargetPwr, 0, + sizeof(struct PARAM_CUSTOM_SET_TX_TARGET_POWER)); + + + /* Set Target Power Base */ + DBGLOG(INIT, INFO, "QA_AGENT Set Tx Target Power= %x dbm\n", + ucTxTargetPower); + rSetTxTargetPwr.ucTxTargetPwr = ucTxTargetPower; + + i4Status = kalIoctl(prGlueInfo, + wlanoidQuerySetTxTargetPower, + &rSetTxTargetPwr, + sizeof(struct PARAM_CUSTOM_SET_TX_TARGET_POWER), + FALSE, FALSE, TRUE, &u4BufLen); + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; +} + +#if CFG_SUPPORT_ANT_SWAP +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Set Antenna swap + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] u4Ant The antenna to choose (0 for main, 1 for aux) + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATESetAntSwap(struct net_device *prNetDev, + uint32_t u4Ant) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + uint32_t u4BufLen = 0; + int32_t i4Status = 0; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + if (!prGlueInfo) { + DBGLOG(RFTEST, ERROR, "prGlueInfo is NULL\n"); + return WLAN_STATUS_ADAPTER_NOT_READY; + } + + DBGLOG(RFTEST, INFO, + "QA_AGENT MT_ATESetAntSwap u4Ant : %d\n", u4Ant); + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_ANT_SWP; + rRfATInfo.u4FuncData = (uint32_t) u4Ant; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; + +} +#endif /* CFG_SUPPORT_ANT_SWAP */ + +#if (CFG_SUPPORT_DFS_MASTER == 1) +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Set Rdd Report. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] ucDbdcIdx Dbdc Index + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATESetRddReport(struct net_device *prNetDev, + uint8_t ucDbdcIdx) +{ + uint32_t u4BufLen = 0; + struct PARAM_CUSTOM_SET_RDD_REPORT rSetRddReport; + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t i4Status = WLAN_STATUS_SUCCESS; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + kalMemSet(&rSetRddReport, 0, + sizeof(struct PARAM_CUSTOM_SET_RDD_REPORT)); + + /* Set Rdd Report */ + DBGLOG(INIT, INFO, "QA_AGENT Set RDD Report - Band: %d\n", + ucDbdcIdx); + rSetRddReport.ucDbdcIdx = ucDbdcIdx; + + i4Status = kalIoctl(prGlueInfo, + wlanoidQuerySetRddReport, + &rSetRddReport, + sizeof(struct PARAM_CUSTOM_SET_RDD_REPORT), + FALSE, FALSE, TRUE, &u4BufLen); + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Hook API for Set Radar Detect Mode. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] ucRadarDetectMode Radar Detect Mode + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If kalIoctl return nonzero. + * \retval -EINVAL If invalid argument. + */ +/*----------------------------------------------------------------------------*/ +int32_t MT_ATESetRadarDetectMode(struct net_device + *prNetDev, uint8_t ucRadarDetectMode) +{ + uint32_t u4BufLen = 0; + struct PARAM_CUSTOM_SET_RADAR_DETECT_MODE + rSetRadarDetectMode; + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t i4Status = WLAN_STATUS_SUCCESS; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + kalMemSet(&rSetRadarDetectMode, 0, + sizeof(struct PARAM_CUSTOM_SET_RADAR_DETECT_MODE)); + + /* Set Rdd Report */ + DBGLOG(INIT, INFO, "QA_AGENT Set Radar Detect Mode: %d\n", + ucRadarDetectMode); + rSetRadarDetectMode.ucRadarDetectMode = ucRadarDetectMode; + + i4Status = kalIoctl(prGlueInfo, + wlanoidQuerySetRadarDetectMode, + &rSetRadarDetectMode, + sizeof(struct PARAM_CUSTOM_SET_RADAR_DETECT_MODE), + FALSE, FALSE, TRUE, &u4BufLen); + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return i4Status; +} + +#endif + +#if CFG_SUPPORT_TX_BF +int32_t TxBfProfileTag_InValid(struct net_device *prNetDev, + union PFMU_PROFILE_TAG1 *prPfmuTag1, + uint8_t ucInValid) +{ + int32_t i4Status = 0; + + prPfmuTag1->rField.ucInvalidProf = ucInValid; + + return i4Status; +} + +int32_t TxBfProfileTag_PfmuIdx(struct net_device *prNetDev, + union PFMU_PROFILE_TAG1 *prPfmuTag1, + uint8_t ucProfileIdx) +{ + int32_t i4Status = 0; + + prPfmuTag1->rField.ucProfileID = ucProfileIdx; + + return i4Status; +} + +int32_t TxBfProfileTag_TxBfType(struct net_device *prNetDev, + union PFMU_PROFILE_TAG1 *prPfmuTag1, + uint8_t ucBFType) +{ + int32_t i4Status = 0; + + prPfmuTag1->rField.ucTxBf = ucBFType; + + return i4Status; +} + +int32_t TxBfProfileTag_DBW(struct net_device *prNetDev, + union PFMU_PROFILE_TAG1 *prPfmuTag1, uint8_t ucBW) +{ + int32_t i4Status = 0; + + prPfmuTag1->rField.ucDBW = ucBW; + + return i4Status; +} + +int32_t TxBfProfileTag_SuMu(struct net_device *prNetDev, + union PFMU_PROFILE_TAG1 *prPfmuTag1, uint8_t ucSuMu) +{ + int32_t i4Status = 0; + + prPfmuTag1->rField.ucSU_MU = ucSuMu; + + return i4Status; +} + +int32_t TxBfProfileTag_Mem(struct net_device *prNetDev, + union PFMU_PROFILE_TAG1 *prPfmuTag1, + uint8_t *aucMemAddrColIdx, uint8_t *aucMemAddrRowIdx) +{ + int32_t i4Status = 0; + + prPfmuTag1->rField.ucMemAddr1ColIdx = aucMemAddrColIdx[0]; + prPfmuTag1->rField.ucMemAddr1RowIdx = aucMemAddrRowIdx[0]; + prPfmuTag1->rField.ucMemAddr2ColIdx = aucMemAddrColIdx[1]; + prPfmuTag1->rField.ucMemAddr2RowIdx = aucMemAddrRowIdx[1] & + 0x1F; + prPfmuTag1->rField.ucMemAddr2RowIdxMsb = aucMemAddrRowIdx[1] + >> 5; + prPfmuTag1->rField.ucMemAddr3ColIdx = aucMemAddrColIdx[2]; + prPfmuTag1->rField.ucMemAddr3RowIdx = aucMemAddrRowIdx[2]; + prPfmuTag1->rField.ucMemAddr4ColIdx = aucMemAddrColIdx[3]; + prPfmuTag1->rField.ucMemAddr4RowIdx = aucMemAddrRowIdx[3]; + + return i4Status; +} + +int32_t TxBfProfileTag_Matrix(struct net_device *prNetDev, + union PFMU_PROFILE_TAG1 *prPfmuTag1, + uint8_t ucNrow, + uint8_t ucNcol, uint8_t ucNgroup, uint8_t ucLM, + uint8_t ucCodeBook, uint8_t ucHtcExist) +{ + int32_t i4Status = 0; + + prPfmuTag1->rField.ucNrow = ucNrow; + prPfmuTag1->rField.ucNcol = ucNcol; + prPfmuTag1->rField.ucNgroup = ucNgroup; + prPfmuTag1->rField.ucLM = ucLM; + prPfmuTag1->rField.ucCodeBook = ucCodeBook; + prPfmuTag1->rField.ucHtcExist = ucHtcExist; + + return i4Status; +} + +int32_t TxBfProfileTag_SNR(struct net_device *prNetDev, + union PFMU_PROFILE_TAG1 *prPfmuTag1, + uint8_t ucSNR_STS0, uint8_t ucSNR_STS1, + uint8_t ucSNR_STS2, uint8_t ucSNR_STS3) +{ + int32_t i4Status = 0; + + prPfmuTag1->rField.ucSNR_STS0 = ucSNR_STS0; + prPfmuTag1->rField.ucSNR_STS1 = ucSNR_STS1; + prPfmuTag1->rField.ucSNR_STS2 = ucSNR_STS2; + prPfmuTag1->rField.ucSNR_STS3 = ucSNR_STS3; + + return i4Status; +} + +int32_t TxBfProfileTag_SmtAnt(struct net_device *prNetDev, + union PFMU_PROFILE_TAG2 *prPfmuTag2, + uint8_t ucSmartAnt) +{ + int32_t i4Status = 0; + + prPfmuTag2->rField.u2SmartAnt = ucSmartAnt; + + return i4Status; +} + +int32_t TxBfProfileTag_SeIdx(struct net_device *prNetDev, + union PFMU_PROFILE_TAG2 *prPfmuTag2, + uint8_t ucSeIdx) +{ + int32_t i4Status = 0; + + prPfmuTag2->rField.ucSEIdx = ucSeIdx; + + return i4Status; +} + +int32_t TxBfProfileTag_RmsdThd(struct net_device *prNetDev, + union PFMU_PROFILE_TAG2 *prPfmuTag2, + uint8_t ucRmsdThrd) +{ + int32_t i4Status = 0; + + prPfmuTag2->rField.ucRMSDThd = ucRmsdThrd; + + return i4Status; +} + +int32_t TxBfProfileTag_McsThd(struct net_device *prNetDev, + union PFMU_PROFILE_TAG2 *prPfmuTag2, + uint8_t *pMCSThLSS, uint8_t *pMCSThSSS) +{ + int32_t i4Status = 0; + + prPfmuTag2->rField.ucMCSThL1SS = pMCSThLSS[0]; + prPfmuTag2->rField.ucMCSThS1SS = pMCSThSSS[0]; + prPfmuTag2->rField.ucMCSThL2SS = pMCSThLSS[1]; + prPfmuTag2->rField.ucMCSThS2SS = pMCSThSSS[1]; + prPfmuTag2->rField.ucMCSThL3SS = pMCSThLSS[2]; + prPfmuTag2->rField.ucMCSThS3SS = pMCSThSSS[2]; + + return i4Status; +} + +int32_t TxBfProfileTag_TimeOut(struct net_device *prNetDev, + union PFMU_PROFILE_TAG2 *prPfmuTag2, uint8_t ucTimeOut) +{ + int32_t i4Status = 0; + + prPfmuTag2->rField.uciBfTimeOut = ucTimeOut; + + return i4Status; +} + +int32_t TxBfProfileTag_DesiredBW(struct net_device + *prNetDev, union PFMU_PROFILE_TAG2 *prPfmuTag2, + uint8_t ucDesiredBW) +{ + int32_t i4Status = 0; + + prPfmuTag2->rField.uciBfDBW = ucDesiredBW; + + return i4Status; +} + +int32_t TxBfProfileTag_DesiredNc(struct net_device + *prNetDev, union PFMU_PROFILE_TAG2 *prPfmuTag2, + uint8_t ucDesiredNc) +{ + int32_t i4Status = 0; + + prPfmuTag2->rField.uciBfNcol = ucDesiredNc; + + return i4Status; +} + +int32_t TxBfProfileTag_DesiredNr(struct net_device + *prNetDev, union PFMU_PROFILE_TAG2 *prPfmuTag2, + uint8_t ucDesiredNr) +{ + int32_t i4Status = 0; + + prPfmuTag2->rField.uciBfNrow = ucDesiredNr; + + return i4Status; +} + +int32_t TxBfProfileTagWrite(struct net_device *prNetDev, + union PFMU_PROFILE_TAG1 *prPfmuTag1, + union PFMU_PROFILE_TAG2 *prPfmuTag2, + uint8_t profileIdx) +{ + int32_t i4Status = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + uint32_t u4BufLen = 0; + union PARAM_CUSTOM_TXBF_ACTION_STRUCT rTxBfActionInfo; + + kalMemZero(&rTxBfActionInfo, sizeof(rTxBfActionInfo)); + + ASSERT(prNetDev); + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + DBGLOG(RFTEST, ERROR, + "prPfmuTag1 : au4RawData[0] = 0x%08x\n", + prPfmuTag1->au4RawData[0]); + DBGLOG(RFTEST, ERROR, + "prPfmuTag1 : au4RawData[1] = 0x%08x\n", + prPfmuTag1->au4RawData[1]); + DBGLOG(RFTEST, ERROR, + "prPfmuTag1 : au4RawData[2] = 0x%08x\n", + prPfmuTag1->au4RawData[2]); + DBGLOG(RFTEST, ERROR, + "prPfmuTag1 : au4RawData[3] = 0x%08x\n", + prPfmuTag1->au4RawData[3]); + + DBGLOG(RFTEST, ERROR, + "prPfmuTag2 : au4RawData[0] = 0x%08x\n", + prPfmuTag2->au4RawData[0]); + DBGLOG(RFTEST, ERROR, + "prPfmuTag2 : au4RawData[1] = 0x%08x\n", + prPfmuTag2->au4RawData[1]); + DBGLOG(RFTEST, ERROR, + "prPfmuTag2 : au4RawData[2] = 0x%08x\n", + prPfmuTag2->au4RawData[2]); + + DBGLOG(RFTEST, ERROR, + "prPfmuTag1 : prPfmuTag1->rField.ucProfileID= %d\n", + prPfmuTag1->rField.ucProfileID); + DBGLOG(RFTEST, ERROR, + "prPfmuTag1 : prPfmuTag1->rField.ucTxBf= %d\n", + prPfmuTag1->rField.ucTxBf); + DBGLOG(RFTEST, ERROR, + "prPfmuTag1 : prPfmuTag1->rField.ucDBW= %d\n", + prPfmuTag1->rField.ucDBW); + DBGLOG(RFTEST, ERROR, + "prPfmuTag1 : prPfmuTag1->rField.ucSU_MU= %d\n", + prPfmuTag1->rField.ucSU_MU); + DBGLOG(RFTEST, ERROR, + "prPfmuTag1 : prPfmuTag1->rField.ucInvalidProf= %d\n", + prPfmuTag1->rField.ucInvalidProf); + DBGLOG(RFTEST, ERROR, + "prPfmuTag1 : prPfmuTag1->rField.ucRMSD= %d\n", + prPfmuTag1->rField.ucRMSD); + DBGLOG(RFTEST, ERROR, + "prPfmuTag1 : prPfmuTag1->rField.ucMemAddr1ColIdx= %d\n", + prPfmuTag1->rField.ucMemAddr1ColIdx); + DBGLOG(RFTEST, ERROR, + "prPfmuTag1 : prPfmuTag1->rField.ucMemAddr1RowIdx= %d\n", + prPfmuTag1->rField.ucMemAddr1RowIdx); + DBGLOG(RFTEST, ERROR, + "prPfmuTag1 : prPfmuTag1->rField.ucMemAddr2ColIdx= %d\n", + prPfmuTag1->rField.ucMemAddr2ColIdx); + DBGLOG(RFTEST, ERROR, + "prPfmuTag1 : prPfmuTag1->rField.ucMemAddr2RowIdx= %d\n", + prPfmuTag1->rField.ucMemAddr2RowIdx); + DBGLOG(RFTEST, ERROR, + "prPfmuTag1 : prPfmuTag1->rField.ucMemAddr2RowIdxMsb= %d\n", + prPfmuTag1->rField.ucMemAddr2RowIdxMsb); + DBGLOG(RFTEST, ERROR, + "prPfmuTag1 : prPfmuTag1->rField.ucMemAddr3ColIdx= %d\n", + prPfmuTag1->rField.ucMemAddr3ColIdx); + DBGLOG(RFTEST, ERROR, + "prPfmuTag1 : prPfmuTag1->rField.ucMemAddr3RowIdx= %d\n", + prPfmuTag1->rField.ucMemAddr3RowIdx); + DBGLOG(RFTEST, ERROR, + "prPfmuTag1 : prPfmuTag1->rField.ucMemAddr4ColIdx= %d\n", + prPfmuTag1->rField.ucMemAddr4ColIdx); + DBGLOG(RFTEST, ERROR, + "prPfmuTag1 : prPfmuTag1->rField.ucMemAddr4RowIdx= %d\n", + prPfmuTag1->rField.ucMemAddr4RowIdx); + DBGLOG(RFTEST, ERROR, + "prPfmuTag1 : prPfmuTag1->rField.ucReserved= %d\n", + prPfmuTag1->rField.ucReserved); + DBGLOG(RFTEST, ERROR, + "prPfmuTag1 : prPfmuTag1->rField.ucNrow= %d\n", + prPfmuTag1->rField.ucNrow); + DBGLOG(RFTEST, ERROR, + "prPfmuTag1 : prPfmuTag1->rField.ucNcol= %d\n", + prPfmuTag1->rField.ucNcol); + DBGLOG(RFTEST, ERROR, + "prPfmuTag1 : prPfmuTag1->rField.ucNgroup= %d\n", + prPfmuTag1->rField.ucNgroup); + DBGLOG(RFTEST, ERROR, + "prPfmuTag1 : prPfmuTag1->rField.ucLM= %d\n", + prPfmuTag1->rField.ucLM); + DBGLOG(RFTEST, ERROR, + "prPfmuTag1 : prPfmuTag1->rField.ucCodeBook= %d\n", + prPfmuTag1->rField.ucCodeBook); + DBGLOG(RFTEST, ERROR, + "prPfmuTag1 : prPfmuTag1->rField.ucHtcExist= %d\n", + prPfmuTag1->rField.ucHtcExist); + DBGLOG(RFTEST, ERROR, + "prPfmuTag1 : prPfmuTag1->rField.ucReserved1= %d\n", + prPfmuTag1->rField.ucReserved1); + DBGLOG(RFTEST, ERROR, + "prPfmuTag1 : prPfmuTag1->rField.ucSNR_STS0= %d\n", + prPfmuTag1->rField.ucSNR_STS0); + DBGLOG(RFTEST, ERROR, + "prPfmuTag1 : prPfmuTag1->rField.ucSNR_STS1= %d\n", + prPfmuTag1->rField.ucSNR_STS1); + DBGLOG(RFTEST, ERROR, + "prPfmuTag1 : prPfmuTag1->rField.ucSNR_STS2= %d\n", + prPfmuTag1->rField.ucSNR_STS2); + DBGLOG(RFTEST, ERROR, + "prPfmuTag1 : prPfmuTag1->rField.ucSNR_STS3= %d\n", + prPfmuTag1->rField.ucSNR_STS3); + DBGLOG(RFTEST, ERROR, + "prPfmuTag1 : prPfmuTag1->rField.ucIBfLnaIdx= %d\n", + prPfmuTag1->rField.ucIBfLnaIdx); + + DBGLOG(RFTEST, ERROR, + "prPfmuTag2 : prPfmuTag2->rField.u2SmartAnt = %d\n", + prPfmuTag2->rField.u2SmartAnt); + DBGLOG(RFTEST, ERROR, + "prPfmuTag2 : prPfmuTag2->rField.ucReserved0 = %d\n", + prPfmuTag2->rField.ucReserved0); + DBGLOG(RFTEST, ERROR, + "prPfmuTag2 : prPfmuTag2->rField.ucSEIdx = %d\n", + prPfmuTag2->rField.ucSEIdx); + DBGLOG(RFTEST, ERROR, + "prPfmuTag2 : prPfmuTag2->rField.ucRMSDThd = %d\n", + prPfmuTag2->rField.ucRMSDThd); + DBGLOG(RFTEST, ERROR, + "prPfmuTag2 : prPfmuTag2->rField.ucReserved1 = %d\n", + prPfmuTag2->rField.ucReserved1); + DBGLOG(RFTEST, ERROR, + "prPfmuTag2 : prPfmuTag2->rField.ucMCSThL1SS = %d\n", + prPfmuTag2->rField.ucMCSThL1SS); + DBGLOG(RFTEST, ERROR, + "prPfmuTag2 : prPfmuTag2->rField.ucMCSThS1SS = %d\n", + prPfmuTag2->rField.ucMCSThS1SS); + DBGLOG(RFTEST, ERROR, + "prPfmuTag2 : prPfmuTag2->rField.ucMCSThL2SS = %d\n", + prPfmuTag2->rField.ucMCSThL2SS); + DBGLOG(RFTEST, ERROR, + "prPfmuTag2 : prPfmuTag2->rField.ucMCSThS2SS = %d\n", + prPfmuTag2->rField.ucMCSThS2SS); + DBGLOG(RFTEST, ERROR, + "prPfmuTag2 : prPfmuTag2->rField.ucMCSThL3SS = %d\n", + prPfmuTag2->rField.ucMCSThL3SS); + DBGLOG(RFTEST, ERROR, + "prPfmuTag2 : prPfmuTag2->rField.ucMCSThS3SS = %d\n", + prPfmuTag2->rField.ucMCSThS3SS); + DBGLOG(RFTEST, ERROR, + "prPfmuTag2 : prPfmuTag2->rField.uciBfTimeOut = %d\n", + prPfmuTag2->rField.uciBfTimeOut); + DBGLOG(RFTEST, ERROR, + "prPfmuTag2 : prPfmuTag2->rField.ucReserved2 = %d\n", + prPfmuTag2->rField.ucReserved2); + DBGLOG(RFTEST, ERROR, + "prPfmuTag2 : prPfmuTag2->rField.ucReserved3 = %d\n", + prPfmuTag2->rField.ucReserved3); + DBGLOG(RFTEST, ERROR, + "prPfmuTag2 : prPfmuTag2->rField.ucReserved4 = %d\n", + prPfmuTag2->rField.ucReserved4); + DBGLOG(RFTEST, ERROR, + "prPfmuTag2 : prPfmuTag2->rField.uciBfDBW = %d\n", + prPfmuTag2->rField.uciBfDBW); + DBGLOG(RFTEST, ERROR, + "prPfmuTag2 : prPfmuTag2->rField.uciBfNcol = %d\n", + prPfmuTag2->rField.uciBfNcol); + DBGLOG(RFTEST, ERROR, + "prPfmuTag2 : prPfmuTag2->rField.uciBfNrow = %d\n", + prPfmuTag2->rField.uciBfNrow); + DBGLOG(RFTEST, ERROR, + "prPfmuTag2 : prPfmuTag2->rField.u2Reserved5 = %d\n", + prPfmuTag2->rField.u2Reserved5); + + rTxBfActionInfo.rProfileTagWrite.ucTxBfCategory = + BF_PFMU_TAG_WRITE; + rTxBfActionInfo.rProfileTagWrite.ucPfmuId = profileIdx; + memcpy(&rTxBfActionInfo.rProfileTagWrite.ucBuffer, + prPfmuTag1, sizeof(union PFMU_PROFILE_TAG1)); + memcpy(&rTxBfActionInfo.rProfileTagWrite.ucBuffer[16], + prPfmuTag2, sizeof(union PFMU_PROFILE_TAG2)); + + i4Status = kalIoctl(prGlueInfo, wlanoidTxBfAction, &rTxBfActionInfo, + sizeof(rTxBfActionInfo), + FALSE, FALSE, TRUE, &u4BufLen); + + return i4Status; +} + +int32_t TxBfProfileTagRead(struct net_device *prNetDev, + uint8_t profileIdx, uint8_t fgBFer) +{ + int32_t i4Status = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + uint32_t u4BufLen = 0; + union PARAM_CUSTOM_TXBF_ACTION_STRUCT rTxBfActionInfo; + + kalMemZero(&rTxBfActionInfo, sizeof(rTxBfActionInfo)); + + ASSERT(prNetDev); + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + DBGLOG(RFTEST, ERROR, + "TxBfProfileTagRead : profileIdx = 0x%08x\n", profileIdx); + DBGLOG(RFTEST, ERROR, + "TxBfProfileTagRead : fgBFer = 0x%08x\n", fgBFer); + + rTxBfActionInfo.rProfileTagRead.ucTxBfCategory = + BF_PFMU_TAG_READ; + rTxBfActionInfo.rProfileTagRead.ucProfileIdx = profileIdx; + rTxBfActionInfo.rProfileTagRead.fgBfer = fgBFer; + + i4Status = kalIoctl(prGlueInfo, wlanoidTxBfAction, &rTxBfActionInfo, + sizeof(rTxBfActionInfo), + TRUE, TRUE, TRUE, &u4BufLen); + + return i4Status; +} + +int32_t StaRecCmmUpdate(struct net_device *prNetDev, + uint8_t ucWlanId, uint8_t ucBssId, uint8_t u4Aid, + uint8_t aucMacAddr[MAC_ADDR_LEN] + ) +{ + struct STAREC_COMMON rStaRecCmm; + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + uint32_t u4BufLen = 0; + int32_t i4Status = 0; + + ASSERT(prNetDev); + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + kalMemZero(&rStaRecCmm, sizeof(struct STAREC_COMMON)); + /* Tag assignment */ + rStaRecCmm.u2Tag = STA_REC_BASIC; + rStaRecCmm.u2Length = sizeof(struct STAREC_COMMON); + + /* content */ + kalMemCopy(rStaRecCmm.aucPeerMacAddr, aucMacAddr, + MAC_ADDR_LEN); + rStaRecCmm.ucConnectionState = TRUE; + rStaRecCmm.u2AID = u4Aid; + rStaRecCmm.u2Reserve1 = ucWlanId; + + DBGLOG(RFTEST, ERROR, "ucWlanId = 0x%08x\n", ucWlanId); + + i4Status = kalIoctl(prGlueInfo, wlanoidStaRecUpdate, &rStaRecCmm, + sizeof(struct STAREC_COMMON), + FALSE, FALSE, TRUE, &u4BufLen); + + return i4Status; +} + +int32_t StaRecBfUpdate(struct net_device *prNetDev, + struct STA_REC_BF_UPD_ARGUMENT rStaRecBfUpdArg, + uint8_t aucMemRow[4], uint8_t aucMemCol[4] + ) +{ + struct CMD_STAREC_BF rStaRecBF; + /* PARAM_CUSTOM_STA_REC_UPD_STRUCT_T rStaRecUpdateInfo = {0}; */ + /* P_STA_RECORD_T prStaRec; */ + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + uint32_t u4BufLen = 0; + int32_t i4Status = 0; + + ASSERT(prNetDev); + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + kalMemZero(&rStaRecBF, sizeof(struct CMD_STAREC_BF)); + /* Tag assignment */ + rStaRecBF.u2Tag = STA_REC_BF; + rStaRecBF.u2Length = sizeof(struct CMD_STAREC_BF); + rStaRecBF.ucReserved[0] = rStaRecBfUpdArg.u4BssId; + rStaRecBF.ucReserved[1] = rStaRecBfUpdArg.u4WlanId; + /* content */ + rStaRecBF.rTxBfPfmuInfo.u2PfmuId = rStaRecBfUpdArg.u4PfmuId; + rStaRecBF.rTxBfPfmuInfo.ucTotMemRequire = + rStaRecBfUpdArg.u4TotalMemReq; + rStaRecBF.rTxBfPfmuInfo.ucMemRequire20M = + rStaRecBfUpdArg.u4MemReq20M; + rStaRecBF.rTxBfPfmuInfo.ucMemRow0 = aucMemRow[0]; + rStaRecBF.rTxBfPfmuInfo.ucMemCol0 = aucMemCol[0]; + rStaRecBF.rTxBfPfmuInfo.ucMemRow1 = aucMemRow[1]; + rStaRecBF.rTxBfPfmuInfo.ucMemCol1 = aucMemCol[1]; + rStaRecBF.rTxBfPfmuInfo.ucMemRow2 = aucMemRow[2]; + rStaRecBF.rTxBfPfmuInfo.ucMemCol2 = aucMemCol[2]; + rStaRecBF.rTxBfPfmuInfo.ucMemRow3 = aucMemRow[3]; + rStaRecBF.rTxBfPfmuInfo.ucMemCol3 = aucMemCol[3]; + /* 0 : SU, 1 : MU */ + rStaRecBF.rTxBfPfmuInfo.fgSU_MU = rStaRecBfUpdArg.u4SuMu; + /* 0: iBF, 1: eBF */ + rStaRecBF.rTxBfPfmuInfo.fgETxBfCap = + rStaRecBfUpdArg.u4eTxBfCap; + /* 0: legacy, 1: OFDM, 2: HT, 4: VHT */ + rStaRecBF.rTxBfPfmuInfo.ucSoundingPhy = 1; + rStaRecBF.rTxBfPfmuInfo.ucNdpaRate = + rStaRecBfUpdArg.u4NdpaRate; + rStaRecBF.rTxBfPfmuInfo.ucNdpRate = + rStaRecBfUpdArg.u4NdpRate; + rStaRecBF.rTxBfPfmuInfo.ucReptPollRate = + rStaRecBfUpdArg.u4ReptPollRate; + /* 0: legacy, 1: OFDM, 2: HT, 4: VHT */ + rStaRecBF.rTxBfPfmuInfo.ucTxMode = rStaRecBfUpdArg.u4TxMode; + rStaRecBF.rTxBfPfmuInfo.ucNc = rStaRecBfUpdArg.u4Nc; + rStaRecBF.rTxBfPfmuInfo.ucNr = rStaRecBfUpdArg.u4Nr; + /* 0 : 20M, 1 : 40M, 2 : 80M, 3 : 80 + 80M */ + rStaRecBF.rTxBfPfmuInfo.ucCBW = rStaRecBfUpdArg.u4Bw; + rStaRecBF.rTxBfPfmuInfo.ucSEIdx = rStaRecBfUpdArg.u4SpeIdx; + /* Default setting */ + rStaRecBF.rTxBfPfmuInfo.u2SmartAnt = 0; + rStaRecBF.rTxBfPfmuInfo.uciBfTimeOut = 0; + rStaRecBF.rTxBfPfmuInfo.uciBfDBW = 0; + rStaRecBF.rTxBfPfmuInfo.uciBfNcol = 0; + rStaRecBF.rTxBfPfmuInfo.uciBfNrow = 0; + + i4Status = kalIoctl(prGlueInfo, + wlanoidStaRecBFUpdate, &rStaRecBF, + sizeof(struct CMD_STAREC_BF), FALSE, FALSE, TRUE, + &u4BufLen); + + return i4Status; +} + +int32_t DevInfoUpdate(struct net_device *prNetDev, + uint8_t ucOwnMacIdx, uint8_t fgBand, + uint8_t aucMacAddr[MAC_ADDR_LEN]) +{ + struct CMD_DEVINFO_ACTIVE rDevInfo; + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + uint32_t u4BufLen = 0; + int32_t i4Status = 0; + + ASSERT(prNetDev); + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + kalMemZero(&rDevInfo, sizeof(struct CMD_DEVINFO_ACTIVE)); + /* Tag assignment */ + rDevInfo.u2Tag = DEV_INFO_ACTIVE; + rDevInfo.u2Length = sizeof(struct CMD_DEVINFO_ACTIVE); + /* content */ + kalMemCopy(rDevInfo.aucOwnMacAddr, aucMacAddr, + MAC_ADDR_LEN); + rDevInfo.ucActive = TRUE; + rDevInfo.ucBandNum = 0; + rDevInfo.aucReserve[0] = ucOwnMacIdx; + + i4Status = kalIoctl(prGlueInfo, wlanoidDevInfoActive, &rDevInfo, + sizeof(struct CMD_DEVINFO_ACTIVE), + FALSE, FALSE, TRUE, &u4BufLen); + + return i4Status; +} + +int32_t BssInfoUpdate(struct net_device *prNetDev, + uint8_t ucOwnMacIdx, uint8_t ucBssIdx, + uint8_t ucBssId[MAC_ADDR_LEN]) +{ + struct BSSINFO_BASIC rBssInfo; + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + uint32_t u4BufLen = 0; + int32_t i4Status = 0; + + ASSERT(prNetDev); + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + kalMemZero(&rBssInfo, sizeof(struct BSSINFO_BASIC)); + /* Tag assignment */ + rBssInfo.u2Tag = BSS_INFO_BASIC; + rBssInfo.u2Length = sizeof(struct BSSINFO_BASIC); + /* content */ + kalMemCopy(rBssInfo.aucBSSID, ucBssId, MAC_ADDR_LEN); + rBssInfo.ucBcMcWlanidx = ucBssIdx; + rBssInfo.ucActive = TRUE; + rBssInfo.u4NetworkType = NETWORK_TYPE_AIS; + rBssInfo.u2BcnInterval = 100; + rBssInfo.ucDtimPeriod = 1; + + i4Status = kalIoctl(prGlueInfo, + wlanoidBssInfoBasic, &rBssInfo, + sizeof(struct BSSINFO_BASIC), FALSE, FALSE, TRUE, + &u4BufLen); + + return i4Status; +} + +int32_t TxBfProfileDataRead(struct net_device *prNetDev, + uint8_t profileIdx, uint8_t fgBFer, + uint8_t ucSubCarrIdxMsb, uint8_t ucSubCarrIdxLsb) +{ + int32_t i4Status = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + uint32_t u4BufLen = 0; + union PARAM_CUSTOM_TXBF_ACTION_STRUCT rTxBfActionInfo; + + kalMemZero(&rTxBfActionInfo, sizeof(rTxBfActionInfo)); + + ASSERT(prNetDev); + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + DBGLOG(RFTEST, ERROR, + "TxBfProfileDataRead : ucPfmuIdx = 0x%08x\n", profileIdx); + DBGLOG(RFTEST, ERROR, + "TxBfProfileDataRead : fgBFer = 0x%08x\n", fgBFer); + DBGLOG(RFTEST, ERROR, + "TxBfProfileDataRead : ucSubCarrIdxMsb = 0x%08x\n", + ucSubCarrIdxMsb); + DBGLOG(RFTEST, ERROR, + "TxBfProfileDataRead : ucSubCarrIdxLsb = 0x%08x\n", + ucSubCarrIdxLsb); + + rTxBfActionInfo.rProfileDataRead.ucTxBfCategory = + BF_PROFILE_READ; + rTxBfActionInfo.rProfileDataRead.ucPfmuIdx = profileIdx; + rTxBfActionInfo.rProfileDataRead.fgBFer = fgBFer; + rTxBfActionInfo.rProfileDataRead.ucSubCarrIdxMsb = + ucSubCarrIdxMsb; + rTxBfActionInfo.rProfileDataRead.ucSubCarrIdxLsb = + ucSubCarrIdxLsb; + + i4Status = kalIoctl(prGlueInfo, wlanoidTxBfAction, &rTxBfActionInfo, + sizeof(rTxBfActionInfo), + TRUE, TRUE, TRUE, &u4BufLen); + + return i4Status; +} + +int32_t TxBfProfileDataWrite(struct net_device *prNetDev, + uint8_t profileIdx, + uint16_t u2SubCarrIdx, uint16_t au2Phi[6], + uint8_t aucPsi[6], uint8_t aucDSnr[4] + ) +{ + int32_t i4Status = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + uint32_t u4BufLen = 0; + union PARAM_CUSTOM_TXBF_ACTION_STRUCT rTxBfActionInfo; + + kalMemZero(&rTxBfActionInfo, sizeof(rTxBfActionInfo)); + + ASSERT(prNetDev); + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + DBGLOG(RFTEST, ERROR, + "TxBfProfileDataWrite : ucPfmuIdx = 0x%08x\n", profileIdx); + DBGLOG(RFTEST, ERROR, + "TxBfProfileDataWrite : u2SubCarrIdx = 0x%08x\n", + u2SubCarrIdx); + + DBGLOG(RFTEST, ERROR, + "TxBfProfileDataWrite : au2Phi[0] = 0x%08x\n", au2Phi[0]); + DBGLOG(RFTEST, ERROR, + "TxBfProfileDataWrite : au2Phi[1] = 0x%08x\n", au2Phi[1]); + DBGLOG(RFTEST, ERROR, + "TxBfProfileDataWrite : au2Phi[2] = 0x%08x\n", au2Phi[2]); + DBGLOG(RFTEST, ERROR, + "TxBfProfileDataWrite : au2Phi[3] = 0x%08x\n", au2Phi[3]); + DBGLOG(RFTEST, ERROR, + "TxBfProfileDataWrite : au2Phi[4] = 0x%08x\n", au2Phi[4]); + DBGLOG(RFTEST, ERROR, + "TxBfProfileDataWrite : au2Phi[5] = 0x%08x\n", au2Phi[5]); + + DBGLOG(RFTEST, ERROR, + "TxBfProfileDataWrite : aucPsi[0] = 0x%08x\n", aucPsi[0]); + DBGLOG(RFTEST, ERROR, + "TxBfProfileDataWrite : aucPsi[1] = 0x%08x\n", aucPsi[1]); + DBGLOG(RFTEST, ERROR, + "TxBfProfileDataWrite : aucPsi[2] = 0x%08x\n", aucPsi[2]); + DBGLOG(RFTEST, ERROR, + "TxBfProfileDataWrite : aucPsi[3] = 0x%08x\n", aucPsi[3]); + DBGLOG(RFTEST, ERROR, + "TxBfProfileDataWrite : aucPsi[4] = 0x%08x\n", aucPsi[4]); + DBGLOG(RFTEST, ERROR, + "TxBfProfileDataWrite : aucPsi[5] = 0x%08x\n", aucPsi[5]); + + DBGLOG(RFTEST, ERROR, + "TxBfProfileDataWrite : aucDSnr[0] = 0x%x\n", aucDSnr[0]); + DBGLOG(RFTEST, ERROR, + "TxBfProfileDataWrite : aucDSnr[1] = 0x%x\n", aucDSnr[1]); + DBGLOG(RFTEST, ERROR, + "TxBfProfileDataWrite : aucDSnr[2] = 0x%x\n", aucDSnr[2]); + DBGLOG(RFTEST, ERROR, + "TxBfProfileDataWrite : aucDSnr[3] = 0x%x\n", aucDSnr[3]); + + rTxBfActionInfo.rProfileDataWrite.ucTxBfCategory = + BF_PROFILE_WRITE; + rTxBfActionInfo.rProfileDataWrite.ucPfmuIdx = profileIdx; + rTxBfActionInfo.rProfileDataWrite.u2SubCarrIdxLsb = + u2SubCarrIdx; + rTxBfActionInfo.rProfileDataWrite.u2SubCarrIdxMsb = + u2SubCarrIdx >> 8; + rTxBfActionInfo.rProfileDataWrite.rTxBfPfmuData.rField.u2Phi11 + = au2Phi[0]; + rTxBfActionInfo.rProfileDataWrite.rTxBfPfmuData.rField.u2Phi21 + = au2Phi[1]; + rTxBfActionInfo.rProfileDataWrite.rTxBfPfmuData.rField.u2Phi31 + = au2Phi[2]; + rTxBfActionInfo.rProfileDataWrite.rTxBfPfmuData.rField.u2Phi22 + = au2Phi[3]; + rTxBfActionInfo.rProfileDataWrite.rTxBfPfmuData.rField.u2Phi32 + = au2Phi[4]; + rTxBfActionInfo.rProfileDataWrite.rTxBfPfmuData.rField.u2Phi33 + = au2Phi[5]; + rTxBfActionInfo.rProfileDataWrite.rTxBfPfmuData.rField.ucPsi21 + = aucPsi[0]; + rTxBfActionInfo.rProfileDataWrite.rTxBfPfmuData.rField.ucPsi31 + = aucPsi[1]; + rTxBfActionInfo.rProfileDataWrite.rTxBfPfmuData.rField.ucPsi41 + = aucPsi[2]; + rTxBfActionInfo.rProfileDataWrite.rTxBfPfmuData.rField.ucPsi32 + = aucPsi[3]; + rTxBfActionInfo.rProfileDataWrite.rTxBfPfmuData.rField.ucPsi42 + = aucPsi[4]; + rTxBfActionInfo.rProfileDataWrite.rTxBfPfmuData.rField.ucPsi43 + = aucPsi[5]; + rTxBfActionInfo.rProfileDataWrite.rTxBfPfmuData.rField.u2dSNR00 + = aucDSnr[0]; + rTxBfActionInfo.rProfileDataWrite.rTxBfPfmuData.rField.u2dSNR01 + = aucDSnr[1]; + rTxBfActionInfo.rProfileDataWrite.rTxBfPfmuData.rField.u2dSNR02 + = aucDSnr[2]; + rTxBfActionInfo.rProfileDataWrite.rTxBfPfmuData.rField.u2dSNR03 + = aucDSnr[3]; + + i4Status = kalIoctl(prGlueInfo, wlanoidTxBfAction, &rTxBfActionInfo, + sizeof(rTxBfActionInfo), + FALSE, FALSE, TRUE, &u4BufLen); + + return i4Status; +} + +int32_t TxBfProfilePnRead(struct net_device *prNetDev, + uint8_t profileIdx) +{ + int32_t i4Status = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + uint32_t u4BufLen = 0; + union PARAM_CUSTOM_TXBF_ACTION_STRUCT rTxBfActionInfo; + + kalMemZero(&rTxBfActionInfo, sizeof(rTxBfActionInfo)); + + ASSERT(prNetDev); + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + DBGLOG(RFTEST, ERROR, + "TxBfProfilePnRead : ucPfmuIdx = 0x%08x\n", profileIdx); + + rTxBfActionInfo.rProfilePnRead.ucTxBfCategory = BF_PN_READ; + rTxBfActionInfo.rProfilePnRead.ucPfmuIdx = profileIdx; + + i4Status = kalIoctl(prGlueInfo, wlanoidTxBfAction, &rTxBfActionInfo, + sizeof(rTxBfActionInfo), + FALSE, FALSE, TRUE, &u4BufLen); + + return i4Status; +} + +int32_t TxBfProfilePnWrite(struct net_device *prNetDev, + uint8_t profileIdx, uint16_t u2bw, uint16_t au2XSTS[12]) +{ + int32_t i4Status = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + uint32_t u4BufLen = 0; + union PARAM_CUSTOM_TXBF_ACTION_STRUCT rTxBfActionInfo; + + kalMemZero(&rTxBfActionInfo, sizeof(rTxBfActionInfo)); + + ASSERT(prNetDev); + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + DBGLOG(RFTEST, ERROR, + "TxBfProfilePnWrite : ucPfmuIdx = 0x%08x\n", profileIdx); + DBGLOG(RFTEST, ERROR, + "TxBfProfilePnWrite : u2bw = 0x%08x\n", u2bw); + DBGLOG(RFTEST, ERROR, + "TxBfProfilePnWrite : au2XSTS[0] = 0x%08x\n", au2XSTS[0]); + DBGLOG(RFTEST, ERROR, + "TxBfProfilePnWrite : au2XSTS[1] = 0x%08x\n", au2XSTS[1]); + DBGLOG(RFTEST, ERROR, + "TxBfProfilePnWrite : au2XSTS[2] = 0x%08x\n", au2XSTS[2]); + DBGLOG(RFTEST, ERROR, + "TxBfProfilePnWrite : au2XSTS[3] = 0x%08x\n", au2XSTS[3]); + DBGLOG(RFTEST, ERROR, + "TxBfProfilePnWrite : au2XSTS[4] = 0x%08x\n", au2XSTS[4]); + DBGLOG(RFTEST, ERROR, + "TxBfProfilePnWrite : au2XSTS[5] = 0x%08x\n", au2XSTS[5]); + DBGLOG(RFTEST, ERROR, + "TxBfProfilePnWrite : au2XSTS[6] = 0x%08x\n", au2XSTS[6]); + DBGLOG(RFTEST, ERROR, + "TxBfProfilePnWrite : au2XSTS[7] = 0x%08x\n", au2XSTS[7]); + DBGLOG(RFTEST, ERROR, + "TxBfProfilePnWrite : au2XSTS[8] = 0x%08x\n", au2XSTS[8]); + DBGLOG(RFTEST, ERROR, + "TxBfProfilePnWrite : au2XSTS[9] = 0x%08x\n", au2XSTS[9]); + DBGLOG(RFTEST, ERROR, + "TxBfProfilePnWrite : au2XSTS[10] = 0x%08x\n", au2XSTS[10]); + DBGLOG(RFTEST, ERROR, + "TxBfProfilePnWrite : au2XSTS[11] = 0x%08x\n", au2XSTS[11]); + + rTxBfActionInfo.rProfilePnWrite.ucTxBfCategory = + BF_PN_WRITE; + rTxBfActionInfo.rProfilePnWrite.ucPfmuIdx = profileIdx; + rTxBfActionInfo.rProfilePnWrite.u2bw = u2bw; + memcpy(&rTxBfActionInfo.rProfilePnWrite.ucBuf[0], &au2XSTS[0], + sizeof(uint16_t) * 12); + + i4Status = kalIoctl(prGlueInfo, wlanoidTxBfAction, &rTxBfActionInfo, + sizeof(rTxBfActionInfo), + FALSE, FALSE, TRUE, &u4BufLen); + + return i4Status; +} + +int32_t TxBfSounding(struct net_device *prNetDev, + uint8_t ucSuMu, /* 0/1/2/3 */ + uint8_t ucNumSta, /* 00~04 */ + uint8_t ucSndInterval, /* 00~FF */ + uint8_t ucWLan0, /* 00~7F */ + uint8_t ucWLan1, /* 00~7F */ + uint8_t ucWLan2, /* 00~7F */ + + uint8_t ucWLan3 /* 00~7F */ + ) +{ + int32_t i4Status = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + uint32_t u4BufLen = 0; + union PARAM_CUSTOM_TXBF_ACTION_STRUCT rTxBfActionInfo; + + kalMemZero(&rTxBfActionInfo, sizeof(rTxBfActionInfo)); + + ASSERT(prNetDev); + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + DBGLOG(RFTEST, ERROR, "TxBfSounding : ucSuMu = 0x%08x\n", + ucSuMu); + DBGLOG(RFTEST, ERROR, "TxBfSounding : ucNumSta = 0x%08x\n", + ucNumSta); + DBGLOG(RFTEST, ERROR, + "TxBfSounding : ucSndInterval = 0x%08x\n", ucSndInterval); + DBGLOG(RFTEST, ERROR, "TxBfSounding : ucWLan0 = 0x%08x\n", + ucWLan0); + DBGLOG(RFTEST, ERROR, "TxBfSounding : ucWLan1 = 0x%08x\n", + ucWLan1); + DBGLOG(RFTEST, ERROR, "TxBfSounding : ucWLan2 = 0x%08x\n", + ucWLan2); + DBGLOG(RFTEST, ERROR, "TxBfSounding : ucWLan3 = 0x%08x\n", + ucWLan3); + + switch (ucSuMu) { + case MU_SOUNDING: + + case MU_PERIODIC_SOUNDING: + rTxBfActionInfo.rTxBfSoundingStart.rTxBfSounding + .rExtCmdExtBfMuSndPeriodicTriggerCtrl.ucCmdCategoryID = + BF_SOUNDING_ON; + rTxBfActionInfo.rTxBfSoundingStart.rTxBfSounding + .rExtCmdExtBfMuSndPeriodicTriggerCtrl.ucSuMuSndMode = ucSuMu; + rTxBfActionInfo.rTxBfSoundingStart.rTxBfSounding + .rExtCmdExtBfMuSndPeriodicTriggerCtrl.ucStaNum = ucNumSta; + rTxBfActionInfo.rTxBfSoundingStart.rTxBfSounding + .rExtCmdExtBfMuSndPeriodicTriggerCtrl.u4SoundingInterval = + ucSndInterval; + rTxBfActionInfo.rTxBfSoundingStart.rTxBfSounding + .rExtCmdExtBfMuSndPeriodicTriggerCtrl.ucWlanId[0] = ucWLan0; + rTxBfActionInfo.rTxBfSoundingStart.rTxBfSounding + .rExtCmdExtBfMuSndPeriodicTriggerCtrl.ucWlanId[1] = ucWLan1; + rTxBfActionInfo.rTxBfSoundingStart.rTxBfSounding + .rExtCmdExtBfMuSndPeriodicTriggerCtrl.ucWlanId[2] = ucWLan2; + rTxBfActionInfo.rTxBfSoundingStart.rTxBfSounding + .rExtCmdExtBfMuSndPeriodicTriggerCtrl.ucWlanId[3] = ucWLan3; + break; + + case SU_SOUNDING: + case SU_PERIODIC_SOUNDING: + rTxBfActionInfo.rTxBfSoundingStart.rTxBfSounding + .rExtCmdExtBfSndPeriodicTriggerCtrl.ucCmdCategoryID = + BF_SOUNDING_ON; + rTxBfActionInfo.rTxBfSoundingStart.rTxBfSounding + .rExtCmdExtBfSndPeriodicTriggerCtrl.ucSuMuSndMode = ucSuMu; + rTxBfActionInfo.rTxBfSoundingStart.rTxBfSounding + .rExtCmdExtBfSndPeriodicTriggerCtrl.u4SoundingInterval = + ucSndInterval; + rTxBfActionInfo.rTxBfSoundingStart.rTxBfSounding + .rExtCmdExtBfSndPeriodicTriggerCtrl.ucWlanIdx = ucWLan0; + break; + default: + break; + } + + i4Status = kalIoctl(prGlueInfo, wlanoidTxBfAction, &rTxBfActionInfo, + sizeof(rTxBfActionInfo), + FALSE, FALSE, TRUE, &u4BufLen); + + return i4Status; +} + +int32_t TxBfSoundingStop(struct net_device *prNetDev) +{ + int32_t i4Status = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + uint32_t u4BufLen = 0; + union PARAM_CUSTOM_TXBF_ACTION_STRUCT rTxBfActionInfo; + + kalMemZero(&rTxBfActionInfo, sizeof(rTxBfActionInfo)); + + ASSERT(prNetDev); + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + DBGLOG(RFTEST, ERROR, "TxBfSoundingStop\n"); + + rTxBfActionInfo.rTxBfSoundingStop.ucTxBfCategory = + BF_SOUNDING_OFF; + rTxBfActionInfo.rTxBfSoundingStop.ucSndgStop = 1; + + i4Status = kalIoctl(prGlueInfo, wlanoidTxBfAction, &rTxBfActionInfo, + sizeof(rTxBfActionInfo), + FALSE, FALSE, TRUE, &u4BufLen); + + return i4Status; +} + +int32_t TxBfTxApply(struct net_device *prNetDev, + uint8_t ucWlanId, uint8_t fgETxBf, uint8_t fgITxBf, + uint8_t fgMuTxBf) +{ + int32_t i4Status = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + uint32_t u4BufLen = 0; + union PARAM_CUSTOM_TXBF_ACTION_STRUCT rTxBfActionInfo; + + kalMemZero(&rTxBfActionInfo, sizeof(rTxBfActionInfo)); + + ASSERT(prNetDev); + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + DBGLOG(RFTEST, ERROR, + "TxBfTxApply : ucWlanId = 0x%08x, fgETxBf = 0x%08x,fgITxBf = 0x%08x,fgMuTxBf = 0x%08x\n", + ucWlanId, fgETxBf, fgITxBf, fgMuTxBf); + + rTxBfActionInfo.rTxBfTxApply.ucTxBfCategory = + BF_DATA_PACKET_APPLY; + rTxBfActionInfo.rTxBfTxApply.ucWlanId = ucWlanId; + rTxBfActionInfo.rTxBfTxApply.fgETxBf = fgETxBf; + rTxBfActionInfo.rTxBfTxApply.fgITxBf = fgITxBf; + rTxBfActionInfo.rTxBfTxApply.fgMuTxBf = fgMuTxBf; + + i4Status = kalIoctl(prGlueInfo, wlanoidTxBfAction, &rTxBfActionInfo, + sizeof(rTxBfActionInfo), + FALSE, FALSE, TRUE, &u4BufLen); + + return i4Status; +} + +int32_t TxBfPfmuMemAlloc(struct net_device *prNetDev, + uint8_t ucSuMuMode, uint8_t ucWlanIdx) +{ + int32_t i4Status = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + uint32_t u4BufLen = 0; + union PARAM_CUSTOM_TXBF_ACTION_STRUCT rTxBfActionInfo; + + kalMemZero(&rTxBfActionInfo, sizeof(rTxBfActionInfo)); + + ASSERT(prNetDev); + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + DBGLOG(RFTEST, ERROR, + "TxBfPfmuMemAlloc : ucSuMuMode = 0x%08x, ucWlanIdx = 0x%08x\n", + ucSuMuMode, ucWlanIdx); + + rTxBfActionInfo.rTxBfPfmuMemAlloc.ucTxBfCategory = + BF_PFMU_MEM_ALLOCATE; + rTxBfActionInfo.rTxBfPfmuMemAlloc.ucSuMuMode = ucSuMuMode; + rTxBfActionInfo.rTxBfPfmuMemAlloc.ucWlanIdx = ucWlanIdx; + + i4Status = kalIoctl(prGlueInfo, wlanoidTxBfAction, &rTxBfActionInfo, + sizeof(rTxBfActionInfo), + FALSE, FALSE, TRUE, &u4BufLen); + + return i4Status; +} + +int32_t TxBfPfmuMemRelease(struct net_device *prNetDev, + uint8_t ucWlanId) +{ + int32_t i4Status = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + uint32_t u4BufLen = 0; + union PARAM_CUSTOM_TXBF_ACTION_STRUCT rTxBfActionInfo; + + kalMemZero(&rTxBfActionInfo, sizeof(rTxBfActionInfo)); + + ASSERT(prNetDev); + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + DBGLOG(RFTEST, ERROR, + "TxBfPfmuMemRelease : ucWlanId = 0x%08x\n", ucWlanId); + + rTxBfActionInfo.rTxBfPfmuMemRls.ucTxBfCategory = + BF_PFMU_MEM_RELEASE; + rTxBfActionInfo.rTxBfPfmuMemRls.ucWlanId = ucWlanId; + + i4Status = kalIoctl(prGlueInfo, wlanoidTxBfAction, &rTxBfActionInfo, + sizeof(rTxBfActionInfo), + FALSE, FALSE, TRUE, &u4BufLen); + + return i4Status; +} + +int32_t TxBfBssInfoUpdate(struct net_device *prNetDev, + uint8_t ucOwnMacIdx, uint8_t ucBssIdx, + uint8_t ucBssId[MAC_ADDR_LEN]) +{ + int32_t i4Status = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + /* UINT_32 u4BufLen = 0; */ + union PARAM_CUSTOM_TXBF_ACTION_STRUCT rTxBfActionInfo; + struct BSS_INFO *prBssInfo; + + kalMemZero(&rTxBfActionInfo, sizeof(rTxBfActionInfo)); + + ASSERT(prNetDev); + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + DBGLOG(RFTEST, ERROR, + "TxBfBssInfoUpdate : ucOwnMacIdx = 0x%08x\n", ucOwnMacIdx); + DBGLOG(RFTEST, ERROR, + "TxBfBssInfoUpdate : ucBssIdx = 0x%08x\n", ucBssIdx); + DBGLOG(RFTEST, ERROR, + "TxBfBssInfoUpdate : ucBssId[0] = 0x%08x\n", ucBssId[0]); + DBGLOG(RFTEST, ERROR, + "TxBfBssInfoUpdate : ucBssId[1] = 0x%08x\n", ucBssId[1]); + DBGLOG(RFTEST, ERROR, + "TxBfBssInfoUpdate : ucBssId[2] = 0x%08x\n", ucBssId[2]); + DBGLOG(RFTEST, ERROR, + "TxBfBssInfoUpdate : ucBssId[3] = 0x%08x\n", ucBssId[3]); + DBGLOG(RFTEST, ERROR, + "TxBfBssInfoUpdate : ucBssId[4] = 0x%08x\n", ucBssId[4]); + DBGLOG(RFTEST, ERROR, + "TxBfBssInfoUpdate : ucBssId[5] = 0x%08x\n", ucBssId[5]); + + prBssInfo = prAdapter->aprBssInfo[ucBssIdx]; + + if (!prBssInfo) + return WLAN_STATUS_FAILURE; + prBssInfo->ucOwnMacIndex = ucOwnMacIdx; + memcpy(&prBssInfo->aucBSSID, &ucBssId[0], MAC_ADDR_LEN); + + nicUpdateBss(prAdapter, prBssInfo->ucBssIndex); + + return i4Status; +} + +/* iwpriv ra0 set assoc=[mac:hh:hh:hh:hh:hh:hh]-[wtbl:dd]- + * [ownmac:dd]-[type:xx]-[mode:mmm]-[bw:dd]-[nss:ss]-[maxrate:kkk_dd] + */ +int32_t TxBfManualAssoc(struct net_device *prNetDev, + uint8_t aucMac[MAC_ADDR_LEN], + uint8_t ucType, /* no use */ + uint8_t ucWtbl, + uint8_t ucOwnmac, + uint8_t ucMode, + uint8_t ucBw, + uint8_t ucNss, uint8_t ucPfmuId, uint8_t ucMarate, + uint8_t ucSpeIdx, uint8_t ucRca2, uint8_t ucRv) +{ + struct CMD_MANUAL_ASSOC_STRUCT rManualAssoc; + /* P_STA_RECORD_T prStaRec; */ + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + uint32_t u4BufLen = 0; + int32_t i4Status = 0; + /* uint8_t ucNsts; + * uint32_t i; + */ + + ASSERT(prNetDev); + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + kalMemZero(&rManualAssoc, + sizeof(struct CMD_MANUAL_ASSOC_STRUCT)); + /* Tag assignment */ + rManualAssoc.u2Tag = STA_REC_MAUNAL_ASSOC; + rManualAssoc.u2Length = sizeof(struct + CMD_MANUAL_ASSOC_STRUCT); + /* content */ + kalMemCopy(rManualAssoc.aucMac, aucMac, MAC_ADDR_LEN); + rManualAssoc.ucType = ucType; + rManualAssoc.ucWtbl = ucWtbl; + rManualAssoc.ucOwnmac = ucOwnmac; + rManualAssoc.ucMode = ucMode; + rManualAssoc.ucBw = ucBw; + rManualAssoc.ucNss = ucNss; + rManualAssoc.ucPfmuId = ucPfmuId; + rManualAssoc.ucMarate = ucMarate; + rManualAssoc.ucSpeIdx = ucSpeIdx; + rManualAssoc.ucaid = ucRca2; + +#if 0 + switch (ucMode) { + case 0: /* abggnanac */ + prStaRec->ucDesiredPhyTypeSet = + aucPhyCfg2PhyTypeSet[PHY_TYPE_SET_802_11ABGNAC]; + break; + case 1: /* bggnan */ + prStaRec->ucDesiredPhyTypeSet = + aucPhyCfg2PhyTypeSet[PHY_TYPE_SET_802_11ABGN]; + break; + case 2: /* aanac */ + prStaRec->ucDesiredPhyTypeSet = + aucPhyCfg2PhyTypeSet[PHY_TYPE_SET_802_11ANAC]; + break; + default: + prStaRec->ucDesiredPhyTypeSet = + aucPhyCfg2PhyTypeSet[PHY_TYPE_SET_802_11ABGNAC]; + break; + } + + prStaRec->rTxBfPfmuStaInfo.u2PfmuId = ucPfmuId; + + memcpy(prStaRec->aucMacAddr, aucMac, MAC_ADDR_LEN); + + i4Status = kalIoctl(prGlueInfo, wlanoidStaRecUpdate, &rStaRecUpdateInfo, + sizeof(struct PARAM_CUSTOM_STA_REC_UPD_STRUCT), + FALSE, FALSE, TRUE, &u4BufLen); +#endif + + i4Status = kalIoctl(prGlueInfo, wlanoidManualAssoc, &rManualAssoc, + sizeof(struct CMD_MANUAL_ASSOC_STRUCT), + FALSE, FALSE, TRUE, &u4BufLen); + + return i4Status; +} + +#if CFG_SUPPORT_TX_BF_FPGA +int32_t TxBfPseudoTagUpdate(struct net_device *prNetDev, + uint8_t ucLm, uint8_t ucNr, + uint8_t ucNc, uint8_t ucBw, uint8_t ucCodeBook, + uint8_t ucGroup) +{ + int32_t i4Status = 0; + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t u4BufLen = 0; + union PARAM_CUSTOM_TXBF_ACTION_STRUCT rTxBfActionInfo; + + kalMemZero(&rTxBfActionInfo, sizeof(rTxBfActionInfo)); + + ASSERT(prNetDev); + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(RFTEST, ERROR, + "TxBfPseudoTagUpdate : ucLm = 0x%08x, ucNr = 0x%08x, ucNc = 0x%08x, ucBw = 0x%08x, ucCodeBook = 0x%08x, ucGroup = 0x%08x\n", + ucLm, ucNr, ucNc, ucBw, ucCodeBook, ucGroup); + + rTxBfActionInfo.rTxBfProfileSwTagWrite.ucTxBfCategory = + BF_PFMU_SW_TAG_WRITE; + rTxBfActionInfo.rTxBfProfileSwTagWrite.ucLm = ucLm; + rTxBfActionInfo.rTxBfProfileSwTagWrite.ucNr = ucNr; + rTxBfActionInfo.rTxBfProfileSwTagWrite.ucNc = ucNc; + rTxBfActionInfo.rTxBfProfileSwTagWrite.ucBw = ucBw; + rTxBfActionInfo.rTxBfProfileSwTagWrite.ucCodebook = + ucCodeBook; + rTxBfActionInfo.rTxBfProfileSwTagWrite.ucgroup = ucGroup; + + i4Status = kalIoctl(prGlueInfo, wlanoidTxBfAction, &rTxBfActionInfo, + sizeof(rTxBfActionInfo), + FALSE, FALSE, TRUE, &u4BufLen); + + return i4Status; +} +#endif + +#endif +#endif /*CFG_SUPPORT_QA_TOOL */ +#if (CONFIG_WLAN_SERVICE == 1) +uint32_t ServiceRfTestInit(void *winfos) +{ + + uint32_t u4SetInfoLen = 0; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint8_t ucBssIndex = 0; + + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + struct test_wlan_info *prTestWinfo; + + + ASSERT(winfos); + prTestWinfo = (struct test_wlan_info *)winfos; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prTestWinfo->net_dev)); + ASSERT(prGlueInfo); + prAdapter = prGlueInfo->prAdapter; + ASSERT(prAdapter); + + /*1. do abort Scan, reset AIS FSM to IDLE*/ + + ucBssIndex = wlanGetBssIdx(prTestWinfo->net_dev); + + if (!IS_BSS_INDEX_VALID(ucBssIndex)) { + DBGLOG(REQ, WARN, "Test Abort SCAN invalid BssIndex\n"); + return WLAN_STATUS_FAILURE; + } + + DBGLOG(REQ, WARN, "Test Abort SCAN ucBssIndex = %d\n", ucBssIndex); + + rStatus = kalIoctlByBssIdx(prGlueInfo, + wlanoidAbortScan, + NULL, 1, FALSE, FALSE, TRUE, &u4SetInfoLen, + ucBssIndex); + + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(REQ, ERROR, "wlanoidAbortScan fail 0x%x\n", rStatus); + + return rStatus; + +} +uint32_t ServiceIcapInit(struct ADAPTER *prAdapter) +{ + struct mt66xx_chip_info *prChipInfo = NULL; + struct ATE_OPS_T *prAteOps = NULL; + struct ICAP_INFO_T *prIcapInfo = NULL; + uint32_t u4IQArrayLen = 0; + uint32_t u4Status = WLAN_STATUS_SUCCESS; + + + ASSERT(prAdapter); + prChipInfo = prAdapter->chip_info; + ASSERT(prChipInfo); + prAteOps = prChipInfo->prAteOps; + ASSERT(prAteOps); + prIcapInfo = &prAdapter->rIcapInfo; + ASSERT(prIcapInfo); + + u4IQArrayLen = + MAX_ICAP_IQ_DATA_CNT * sizeof(struct _RBIST_IQ_DATA_T); + + /*init IQ data array*/ + if (!prIcapInfo->prIQArray) { + prIcapInfo->prIQArray = + kalMemAlloc(u4IQArrayLen, VIR_MEM_TYPE); + if (!prIcapInfo->prIQArray) { + DBGLOG(RFTEST, ERROR, + "Not enough memory for IQ_Array\n"); + return WLAN_STATUS_NOT_ACCEPTED; + } + } + prIcapInfo->u4IQArrayIndex = 0; + prIcapInfo->u4ICapEventCnt = 0; + + kalMemZero(prIcapInfo->au4ICapDumpIndex, + sizeof(prIcapInfo->au4ICapDumpIndex)); + kalMemZero(prIcapInfo->prIQArray, u4IQArrayLen); + + + if (prIcapInfo->eIcapState == ICAP_STATE_INIT) { + + if (prAteOps->icapRiseVcoreClockRate) + prAteOps->icapRiseVcoreClockRate(); + + u4Status = WLAN_STATUS_SUCCESS; + } else { + DBGLOG(RFTEST, ERROR, "icap start ignore state in %d\n", + prIcapInfo->eIcapState); + u4Status = WLAN_STATUS_NOT_ACCEPTED; + } + + DBGLOG(RFTEST, STATE, "%s done\n", __func__); + + return u4Status; +} +uint32_t ServiceIcapDeInit(struct ADAPTER *prAdapter) +{ + struct mt66xx_chip_info *prChipInfo = NULL; + struct ATE_OPS_T *prAteOps = NULL; + struct ICAP_INFO_T *prIcapInfo = NULL; + uint32_t u4Status = WLAN_STATUS_SUCCESS; + + ASSERT(prAdapter); + prChipInfo = prAdapter->chip_info; + ASSERT(prChipInfo); + prAteOps = prChipInfo->prAteOps; + ASSERT(prAteOps); + prIcapInfo = &prAdapter->rIcapInfo; + ASSERT(prIcapInfo); + + if (prAteOps->icapDownVcoreClockRate) + prAteOps->icapDownVcoreClockRate(); + + if (prIcapInfo->prIQArray != NULL) + kalMemFree(prIcapInfo->prIQArray, + VIR_MEM_TYPE, + 0); + + prIcapInfo->u4IQArrayIndex = 0; + prIcapInfo->u4ICapEventCnt = 0; + prIcapInfo->prIQArray = NULL; + + return u4Status; +} +uint32_t ServiceWlanOid(void *winfos, + uint32_t oidType, + void *param, + uint32_t paramLen, + uint32_t *u4BufLen, + void *rsp_data) +{ + int32_t i4Status = 0; + uint32_t u4BufLen2; + uint32_t *resp; + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + struct RECAL_INFO_T *prReCalInfo = NULL; + boolean fgRead, fgWaitResp, fgCmd; + PFN_OID_HANDLER_FUNC pfnOidHandler = NULL; + struct test_wlan_info *prTestWinfo; + struct hqa_m_rx_stat *prStatsData = NULL; +#if CFG_SUPPORT_ANT_SWAP + struct mt66xx_chip_info *prChipInfo = NULL; +#endif + struct ICAP_INFO_T *prIcapInfo = NULL; + struct test_capability *capability = NULL; + + ASSERT(winfos); + + /* Avoid assert caused by u4BufLen = NULL. */ + if (u4BufLen == NULL) + u4BufLen = &u4BufLen2; + + prTestWinfo = (struct test_wlan_info *)winfos; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prTestWinfo->net_dev)); + ASSERT(prGlueInfo); + prAdapter = prGlueInfo->prAdapter; + ASSERT(prAdapter); + prReCalInfo = &prAdapter->rReCalInfo; +#if CFG_SUPPORT_ANT_SWAP + prChipInfo = prAdapter->chip_info; + ASSERT(prChipInfo); +#endif + prIcapInfo = &prAdapter->rIcapInfo; + ASSERT(prIcapInfo); + + /* Normal set */ + fgRead = FALSE; + fgWaitResp = FALSE; + fgCmd = TRUE; + + if (prAdapter->fgTestMode == FALSE) { + /* workaround for meta tool */ + DBGLOG(RFTEST, INFO, + "Test Mode Start Workaround for META!\n"); + + ServiceRfTestInit(winfos); + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetTestMode, /* pfnOidHandler */ + NULL, /* pvInfoBuf */ + 0, /* u4InfoBufLen */ + fgRead, /* fgRead */ + fgWaitResp, /* fgWaitResp */ + fgCmd, /* fgCmd */ + u4BufLen); /* pu4QryInfoLen */ + + DBGLOG(RFTEST, INFO, + "Test Mode Start Workaround for META2!\n"); + + } + + switch (oidType) { + case OP_WLAN_OID_SET_TEST_MODE_START: + DBGLOG(RFTEST, INFO, "Test Mode Start!\n"); + ServiceRfTestInit(winfos); + pfnOidHandler = wlanoidRftestSetTestMode; + break; + case OP_WLAN_OID_SET_TEST_MODE_ABORT: + DBGLOG(RFTEST, INFO, "Test Mode Abort!\n"); + pfnOidHandler = wlanoidRftestSetAbortTestMode; + break; + case OP_WLAN_OID_RFTEST_SET_AUTO_TEST: + pfnOidHandler = wlanoidRftestSetAutoTest; + break; + case OP_WLAN_OID_RFTEST_QUERY_AUTO_TEST: + pfnOidHandler = wlanoidRftestQueryAutoTest; + fgRead = TRUE; + fgWaitResp = TRUE; + fgCmd = TRUE; + break; + case OP_WLAN_OID_QUERY_RX_STATISTICS: + prStatsData = (struct hqa_m_rx_stat *)rsp_data; + pfnOidHandler = wlanoidQueryRxStatistics; + fgRead = TRUE; + fgWaitResp = TRUE; + fgCmd = TRUE; + break; + case OP_WLAN_OID_GET_CAPABILITY: + capability = (struct test_capability *)rsp_data; + kalMemSet(capability, 0, sizeof(struct test_capability)); + + /* ph_cap.protocol */ + capability->ph_cap.protocol = BIT(0); + if (prAdapter->rWifiVar.ucStaHt) + capability->ph_cap.protocol |= BIT(1); + if (prAdapter->rWifiVar.ucStaVht) + capability->ph_cap.protocol |= BIT(2); +#if (CFG_SUPPORT_802_11AX == 1) + if (prAdapter->rWifiVar.ucStaHe) + capability->ph_cap.protocol |= BIT(3); +#endif /* (CFG_SUPPORT_802_11AX == 1) */ + + /* ph_cap.ant_num */ + capability->ph_cap.ant_num = prAdapter->rWifiVar.ucNSS; + + /* ph_cap.dbdc */ + if (prAdapter->rWifiVar.eDbdcMode != ENUM_DBDC_MODE_DISABLED) + capability->ph_cap.dbdc |= BIT(0); + + /* ph_cap.coding */ + if (prAdapter->rWifiVar.ucTxLdpc) + capability->ph_cap.coding |= BIT(0); + if (prAdapter->rWifiVar.ucRxLdpc) + capability->ph_cap.coding |= BIT(1); + if (prAdapter->rWifiVar.ucTxStbc) + capability->ph_cap.coding |= BIT(2); + if (prAdapter->rWifiVar.ucRxStbc) + capability->ph_cap.coding |= BIT(3); + + /* ph_cap.channel_band */ + capability->ph_cap.channel_band = BIT(0); + if (!prAdapter->fgIsHw5GBandDisabled) + capability->ph_cap.channel_band |= BIT(1); + + /* ph_cap.bandwidth */ + capability->ph_cap.bandwidth = BITS(0, 1); + if (prAdapter->rWifiVar.ucStaVht) + capability->ph_cap.bandwidth |= BIT(2); + + /* ph_cap.channel_band_dbdc */ + if (prAdapter->rWifiVar.eDbdcMode == ENUM_DBDC_MODE_DISABLED) + /* band0 (2.4G + 5G) */ + capability->ph_cap.channel_band_dbdc = 0x00000003; + else + /* 6635: band0 (2.4G); band1 (5G) */ + capability->ph_cap.channel_band_dbdc = 0x00020001; + + /* ext_cap.feature1: BIT0: AntSwap */ +#if CFG_SUPPORT_ANT_SWAP + if (prAdapter->fgIsSupportAntSwp) + capability->ext_cap.feature1 |= BIT(0); +#endif /* CFG_SUPPORT_ANT_SWAP */ + + /* ext_cap.feature1: BIT1: HW TX support */ + /* currently, only AX support */ + if (capability->ph_cap.protocol & BIT(3)) + capability->ext_cap.feature1 |= BIT(1); + + return WLAN_STATUS_SUCCESS; + /* ICAP Operation Function -- Start*/ + case OP_WLAN_OID_SET_TEST_ICAP_MODE: + pfnOidHandler = wlanoidRftestSetTestIcapMode; + break; + case OP_WLAN_OID_SET_TEST_ICAP_START: + ServiceIcapInit(prAdapter); + pfnOidHandler = wlanoidExtRfTestICapStart; + break; + case OP_WLAN_OID_SET_TEST_ICAP_ABORT: + i4Status = ServiceIcapDeInit(prAdapter); + pfnOidHandler = wlanoidExtRfTestICapStart; + break; + case OP_WLAN_OID_SET_TEST_ICAP_STATUS: + + if (!rsp_data) + return WLAN_STATUS_INVALID_DATA; + + resp = (uint32_t *)rsp_data; + + if (prIcapInfo->eIcapState == ICAP_STATE_FW_DUMP_DONE) { + DBGLOG(RFTEST, INFO, "icap capture done!\n"); + *resp = 0; /*response QA TOOL CAPTURE success*/ + return WLAN_STATUS_SUCCESS; + } else if (prIcapInfo->eIcapState == ICAP_STATE_FW_DUMPING) { + DBGLOG(RFTEST, INFO, "icap fw dumping !!!\n"); + *resp = 1; /*response QA TOOL CAPTURE wait*/ + return WLAN_STATUS_SUCCESS; + } + + pfnOidHandler = wlanoidExtRfTestICapStatus; + *resp = 1; /*response QA TOOL CAPTURE wait*/ + + break; + case OP_WLAN_OID_GET_TEST_ICAP_MAX_DATA_LEN: + /* Maximum 1KB = ICAP_EVENT_DATA_SAMPLE (256) slots */ + if (!rsp_data) + return WLAN_STATUS_INVALID_DATA; + + resp = (uint32_t *)rsp_data; + *resp = ICAP_EVENT_DATA_SAMPLE * sizeof(uint32_t); + return WLAN_STATUS_SUCCESS; + case OP_WLAN_OID_GET_TEST_ICAP_DATA: + if ((prIcapInfo->eIcapState != ICAP_STATE_QA_TOOL_CAPTURE) && + (prIcapInfo->eIcapState != ICAP_STATE_FW_DUMP_DONE)) { + DBGLOG(RFTEST, ERROR, "ICAP State = %d don't support\n", + prIcapInfo->eIcapState); + return WLAN_STATUS_NOT_SUPPORTED; + } + pfnOidHandler = wlanoidRfTestICapGetIQData; + fgRead = TRUE; + fgWaitResp = FALSE; + fgCmd = FALSE; + break; + /* ICAP Operation Function -- END*/ + + case OP_WLAN_OID_SET_MCR_WRITE: + pfnOidHandler = wlanoidSetMcrWrite; + fgRead = TRUE; + fgWaitResp = TRUE; + fgCmd = TRUE; + break; + case OP_WLAN_OID_QUERY_MCR_READ: + pfnOidHandler = wlanoidQueryMcrRead; + break; + case OP_WLAN_OID_GET_RECAL_COUNT: + *u4BufLen = prReCalInfo->u4Count; + + return WLAN_STATUS_SUCCESS; + case OP_WLAN_OID_GET_RECAL_CONTENT: + if (!rsp_data) + return WLAN_STATUS_INVALID_DATA; + + if (prReCalInfo->u4Count > 0) { + kalMemCopy(rsp_data, &prReCalInfo->prCalArray[0], + (prReCalInfo->u4Count * sizeof(struct RECAL_DATA_T))); + } + + return WLAN_STATUS_SUCCESS; + case OP_WLAN_OID_GET_ANTSWAP_CAPBILITY: +#if CFG_SUPPORT_ANT_SWAP + if (!prChipInfo) { + DBGLOG(RFTEST, ERROR, "prChipInfo is NULL\n"); + return -EFAULT; + } + + DBGLOG(RFTEST, INFO, "HQA_GetAntSwapCapability [%d]\n", + prGlueInfo->prAdapter->fgIsSupportAntSwp); + + DBGLOG(RFTEST, INFO, "ucMaxSwapAntenna = [%d]\n", + prChipInfo->ucMaxSwapAntenna); + + if (prGlueInfo->prAdapter->fgIsSupportAntSwp) + *u4BufLen = prChipInfo->ucMaxSwapAntenna; + else + *u4BufLen = 0; + + return WLAN_STATUS_SUCCESS; +#endif + case OP_WLAN_OID_RESET_RECAL_COUNT: + kalMemSet(&prReCalInfo->prCalArray[0], 0, + (prReCalInfo->u4Count * sizeof(struct RECAL_DATA_T))); + + prReCalInfo->u4Count = 0; + + return WLAN_STATUS_SUCCESS; + + case OP_WLAN_OID_NUM: + default: + return WLAN_STATUS_FAILURE; + } + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + pfnOidHandler, /* pfnOidHandler */ + param, /* pvInfoBuf */ + paramLen, /* u4InfoBufLen */ + fgRead, /* fgRead */ + fgWaitResp, /* fgWaitResp */ + fgCmd, /* fgCmd */ + u4BufLen); /* pu4QryInfoLen */ + + if ((prStatsData) && + (oidType == OP_WLAN_OID_QUERY_RX_STATISTICS)) { + + /* 264 = 66 items * 4 bytes */ + kalMemCopy(&prStatsData->mac_rx_fcs_err_cnt, + &(g_HqaRxStat.MAC_FCS_Err), 264); + } + + return i4Status; +} +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_init.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_init.c new file mode 100644 index 0000000000000000000000000000000000000000..777fc166dd8859d0aa534860575c9c0b49aa6fce --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_init.c @@ -0,0 +1,5521 @@ +/******************************************************************************* + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux + * /gl_init.c#11 + */ + +/*! \file gl_init.c + * \brief Main routines of Linux driver + * + * This file contains the main routines of Linux driver for MediaTek Inc. + * 802.11 Wireless LAN Adapters. + */ + + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "gl_os.h" +#include "debug.h" +#include "wlan_lib.h" +#include "gl_wext.h" +#include "gl_cfg80211.h" +#include "precomp.h" +#if CFG_SUPPORT_AGPS_ASSIST +#include "gl_kal.h" +#endif +#if CFG_TC1_FEATURE +#include +#endif +#if CFG_CHIP_RESET_SUPPORT +#include "gl_rst.h" +#endif +#include "gl_vendor.h" +#include "gl_hook_api.h" +#if CFG_MTK_MCIF_WIFI_SUPPORT +#include "mddp.h" +#endif +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +/* #define MAX_IOREQ_NUM 10 */ +struct semaphore g_halt_sem; +int g_u4HaltFlag; +int g_u4WlanInitFlag; +enum ENUM_NVRAM_STATE g_NvramFsm = NVRAM_STATE_INIT; + +uint8_t g_aucNvram[MAX_CFG_FILE_WIFI_REC_SIZE]; +struct wireless_dev *gprWdev[KAL_AIS_NUM]; + +#if CFG_SUPPORT_PERSIST_NETDEV +struct net_device *gprNetdev[KAL_AIS_NUM] = {}; +#endif +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +/* Tasklet mechanism is like buttom-half in Linux. We just want to + * send a signal to OS for interrupt defer processing. All resources + * are NOT allowed reentry, so txPacket, ISR-DPC and ioctl must avoid preempty. + */ +struct WLANDEV_INFO { + struct net_device *prDev; +}; + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +MODULE_AUTHOR(NIC_AUTHOR); +MODULE_DESCRIPTION(NIC_DESC); +MODULE_SUPPORTED_DEVICE(NIC_NAME); + +/* MODULE_LICENSE("MTK Propietary"); */ +MODULE_LICENSE("Dual BSD/GPL"); + +#ifdef CFG_DRIVER_INF_NAME_CHANGE +char *gprifnamesta = ""; +char *gprifnamep2p = ""; +char *gprifnameap = ""; +module_param_named(sta, gprifnamesta, charp, 0000); +module_param_named(p2p, gprifnamep2p, charp, 0000); +module_param_named(ap, gprifnameap, charp, 0000); +#endif /* CFG_DRIVER_INF_NAME_CHANGE */ + +/* NIC interface name */ +#define NIC_INF_NAME "wlan%d" + +#ifdef CFG_DRIVER_INF_NAME_CHANGE +/* Kernel IFNAMESIZ is 16, we use 5 in case some protocol might auto gen + * interface name, + */ +/* in that case, the interface name might have risk of over kernel's IFNAMESIZ + */ +#define CUSTOM_IFNAMESIZ 5 +#endif /* CFG_DRIVER_INF_NAME_CHANGE */ + +#if CFG_SUPPORT_SNIFFER +#define NIC_MONITOR_INF_NAME "radiotap%d" +#endif + +uint8_t aucDebugModule[DBG_MODULE_NUM]; +uint32_t au4LogLevel[ENUM_WIFI_LOG_MODULE_NUM] = {ENUM_WIFI_LOG_LEVEL_DEFAULT}; + +/* 4 2007/06/26, mikewu, now we don't use this, we just fix the number of wlan + * device to 1 + */ +static struct WLANDEV_INFO + arWlanDevInfo[CFG_MAX_WLAN_DEVICES] = { {0} }; + +static uint32_t +u4WlanDevNum; /* How many NICs coexist now */ + +#if CFG_SUPPORT_CAL_RESULT_BACKUP_TO_HOST +u_int8_t g_fgIsCalDataBackuped = FALSE; +#endif + +/* 20150205 added work queue for sched_scan to avoid cfg80211 stop schedule scan + * dead loack + */ +struct delayed_work sched_workq; + +#define CFG_EEPRM_FILENAME "EEPROM" +#define FILE_NAME_MAX 64 + +#if (CFG_EFUSE_BUFFER_MODE_DELAY_CAL == 1) +static uint8_t *apucEepromName[] = { + (uint8_t *) CFG_EEPRM_FILENAME "_MT", + NULL +}; +#endif + +/* For running on X86 UT environment */ +#if defined(UT_TEST_MODE) && defined(CFG_BUILD_X86_PLATFORM) +phys_addr_t gConEmiPhyBase; +EXPORT_SYMBOL(gConEmiPhyBase); + +unsigned long long gConEmiSize; +EXPORT_SYMBOL(gConEmiSize); +#endif + +#if CFG_MTK_ANDROID_EMI +phys_addr_t gConEmiPhyBaseFinal; +unsigned long long gConEmiSizeFinal; +#endif + +int CFG80211_Suspend(struct wiphy *wiphy, + struct cfg80211_wowlan *wow) +{ + DBGLOG(INIT, INFO, "CFG80211 suspend CB\n"); + + return 0; +} + +int CFG80211_Resume(struct wiphy *wiphy) +{ + DBGLOG(INIT, INFO, "CFG80211 resume CB\n"); + + return 0; +} + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +#define CHAN2G(_channel, _freq, _flags) \ +{ \ + .band = KAL_BAND_2GHZ, \ + .center_freq = (_freq), \ + .hw_value = (_channel), \ + .flags = (_flags), \ + .max_antenna_gain = 0, \ + .max_power = 30, \ +} +static struct ieee80211_channel mtk_2ghz_channels[] = { + CHAN2G(1, 2412, 0), + CHAN2G(2, 2417, 0), + CHAN2G(3, 2422, 0), + CHAN2G(4, 2427, 0), + CHAN2G(5, 2432, 0), + CHAN2G(6, 2437, 0), + CHAN2G(7, 2442, 0), + CHAN2G(8, 2447, 0), + CHAN2G(9, 2452, 0), + CHAN2G(10, 2457, 0), + CHAN2G(11, 2462, 0), + CHAN2G(12, 2467, 0), + CHAN2G(13, 2472, 0), + CHAN2G(14, 2484, 0), +}; + +#define CHAN5G(_channel, _flags) \ +{ \ + .band = KAL_BAND_5GHZ, \ + .center_freq = \ + (((_channel >= 182) && (_channel <= 196)) ? \ + (4000 + (5 * (_channel))) : (5000 + (5 * (_channel)))), \ + .hw_value = (_channel), \ + .flags = (_flags), \ + .max_antenna_gain = 0, \ + .max_power = 30, \ +} +static struct ieee80211_channel mtk_5ghz_channels[] = { + /* UNII-1 */ + CHAN5G(36, 0), + CHAN5G(40, 0), + CHAN5G(44, 0), + CHAN5G(48, 0), + /* UNII-2 */ + CHAN5G(52, IEEE80211_CHAN_RADAR), + CHAN5G(56, IEEE80211_CHAN_RADAR), + CHAN5G(60, IEEE80211_CHAN_RADAR), + CHAN5G(64, IEEE80211_CHAN_RADAR), + /* UNII-2e */ + CHAN5G(100, IEEE80211_CHAN_RADAR), + CHAN5G(104, IEEE80211_CHAN_RADAR), + CHAN5G(108, IEEE80211_CHAN_RADAR), + CHAN5G(112, IEEE80211_CHAN_RADAR), + CHAN5G(116, IEEE80211_CHAN_RADAR), + CHAN5G(120, IEEE80211_CHAN_RADAR), + CHAN5G(124, IEEE80211_CHAN_RADAR), + CHAN5G(128, IEEE80211_CHAN_RADAR), + CHAN5G(132, IEEE80211_CHAN_RADAR), + CHAN5G(136, IEEE80211_CHAN_RADAR), + CHAN5G(140, IEEE80211_CHAN_RADAR), + CHAN5G(144, IEEE80211_CHAN_RADAR), + /* UNII-3 */ + CHAN5G(149, 0), + CHAN5G(153, 0), + CHAN5G(157, 0), + CHAN5G(161, 0), + CHAN5G(165, 0) +}; + +#define RATETAB_ENT(_rate, _rateid, _flags) \ +{ \ + .bitrate = (_rate), \ + .hw_value = (_rateid), \ + .flags = (_flags), \ +} + +/* for cfg80211 - rate table */ +static struct ieee80211_rate mtk_rates[] = { + RATETAB_ENT(10, 0x1000, 0), + RATETAB_ENT(20, 0x1001, 0), + RATETAB_ENT(55, 0x1002, 0), + RATETAB_ENT(110, 0x1003, 0), /* 802.11b */ + RATETAB_ENT(60, 0x2000, 0), + RATETAB_ENT(90, 0x2001, 0), + RATETAB_ENT(120, 0x2002, 0), + RATETAB_ENT(180, 0x2003, 0), + RATETAB_ENT(240, 0x2004, 0), + RATETAB_ENT(360, 0x2005, 0), + RATETAB_ENT(480, 0x2006, 0), + RATETAB_ENT(540, 0x2007, 0), /* 802.11a/g */ +}; + +#define mtk_a_rates (mtk_rates + 4) +#define mtk_a_rates_size (ARRAY_SIZE(mtk_rates) - 4) +#define mtk_g_rates (mtk_rates + 0) +#define mtk_g_rates_size (ARRAY_SIZE(mtk_rates) - 0) + +#define WLAN_MCS_INFO \ +{ \ + .rx_mask = {0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \ + .rx_highest = 0, \ + .tx_params = IEEE80211_HT_MCS_TX_DEFINED, \ +} + +#define WLAN_VHT_MCS_INFO \ +{ \ + .rx_mcs_map = 0xFFFA, \ + .rx_highest = cpu_to_le16(867), \ + .tx_mcs_map = 0xFFFA, \ + .tx_highest = cpu_to_le16(867), \ +} + + +#define WLAN_HT_CAP \ +{ \ + .ht_supported = true, \ + .cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 \ + | IEEE80211_HT_CAP_SM_PS \ + | IEEE80211_HT_CAP_GRN_FLD \ + | IEEE80211_HT_CAP_SGI_20 \ + | IEEE80211_HT_CAP_SGI_40, \ + .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, \ + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE, \ + .mcs = WLAN_MCS_INFO, \ +} + +#define WLAN_VHT_CAP \ +{ \ + .vht_supported = true, \ + .cap = IEEE80211_VHT_CAP_RXLDPC \ + | IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK \ + | IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 \ + | IEEE80211_VHT_CAP_RXLDPC \ + | IEEE80211_VHT_CAP_SHORT_GI_80 \ + | IEEE80211_VHT_CAP_TXSTBC \ + | IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE \ + | IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE, \ + .vht_mcs = WLAN_VHT_MCS_INFO, \ +} + +/* public for both Legacy Wi-Fi / P2P access */ +struct ieee80211_supported_band mtk_band_2ghz = { + .band = KAL_BAND_2GHZ, + .channels = mtk_2ghz_channels, + .n_channels = ARRAY_SIZE(mtk_2ghz_channels), + .bitrates = mtk_g_rates, + .n_bitrates = mtk_g_rates_size, + .ht_cap = WLAN_HT_CAP, +}; + +/* public for both Legacy Wi-Fi / P2P access */ +struct ieee80211_supported_band mtk_band_5ghz = { + .band = KAL_BAND_5GHZ, + .channels = mtk_5ghz_channels, + .n_channels = ARRAY_SIZE(mtk_5ghz_channels), + .bitrates = mtk_a_rates, + .n_bitrates = mtk_a_rates_size, + .ht_cap = WLAN_HT_CAP, + .vht_cap = WLAN_VHT_CAP, +}; + +const uint32_t mtk_cipher_suites[] = { + /* keep WEP first, it may be removed below */ + WLAN_CIPHER_SUITE_WEP40, + WLAN_CIPHER_SUITE_WEP104, + WLAN_CIPHER_SUITE_TKIP, + WLAN_CIPHER_SUITE_CCMP, + + /* keep last -- depends on hw flags! */ + WLAN_CIPHER_SUITE_AES_CMAC, + WLAN_CIPHER_SUITE_GCMP_256, + WLAN_CIPHER_SUITE_BIP_GMAC_256, /* TODO, HW not support, + * SW should handle integrity check + */ + WLAN_CIPHER_SUITE_NO_GROUP_ADDR +}; + +#if (CFG_ENABLE_UNIFY_WIPHY == 0) +static struct cfg80211_ops mtk_wlan_ops = { + .suspend = mtk_cfg80211_suspend, + .resume = mtk_cfg80211_resume, + .change_virtual_intf = mtk_cfg80211_change_iface, + .add_key = mtk_cfg80211_add_key, + .get_key = mtk_cfg80211_get_key, + .del_key = mtk_cfg80211_del_key, + .set_default_key = mtk_cfg80211_set_default_key, + .get_station = mtk_cfg80211_get_station, +#if CFG_SUPPORT_TDLS + .change_station = mtk_cfg80211_change_station, + .add_station = mtk_cfg80211_add_station, + .del_station = mtk_cfg80211_del_station, +#endif + .scan = mtk_cfg80211_scan, +#if KERNEL_VERSION(4, 5, 0) <= CFG80211_VERSION_CODE + .abort_scan = mtk_cfg80211_abort_scan, +#endif + .connect = mtk_cfg80211_connect, + .disconnect = mtk_cfg80211_disconnect, + .join_ibss = mtk_cfg80211_join_ibss, + .leave_ibss = mtk_cfg80211_leave_ibss, + .set_power_mgmt = mtk_cfg80211_set_power_mgmt, + .set_pmksa = mtk_cfg80211_set_pmksa, + .del_pmksa = mtk_cfg80211_del_pmksa, + .flush_pmksa = mtk_cfg80211_flush_pmksa, +#if CONFIG_SUPPORT_GTK_REKEY + .set_rekey_data = mtk_cfg80211_set_rekey_data, +#endif + .assoc = mtk_cfg80211_assoc, + + /* Action Frame TX/RX */ + .remain_on_channel = mtk_cfg80211_remain_on_channel, + .cancel_remain_on_channel = mtk_cfg80211_cancel_remain_on_channel, + .mgmt_tx = mtk_cfg80211_mgmt_tx, + /* .mgmt_tx_cancel_wait = mtk_cfg80211_mgmt_tx_cancel_wait, */ + .mgmt_frame_register = mtk_cfg80211_mgmt_frame_register, + +#ifdef CONFIG_NL80211_TESTMODE + .testmode_cmd = mtk_cfg80211_testmode_cmd, +#endif +#if CFG_SUPPORT_SCHED_SCAN + .sched_scan_start = mtk_cfg80211_sched_scan_start, + .sched_scan_stop = mtk_cfg80211_sched_scan_stop, +#endif /* CFG_SUPPORT_SCHED_SCAN */ +#if CFG_SUPPORT_TDLS + .tdls_oper = mtk_cfg80211_tdls_oper, + .tdls_mgmt = mtk_cfg80211_tdls_mgmt, +#endif + .update_ft_ies = mtk_cfg80211_update_ft_ies, + +#if CFG_SUPPORT_WPA3 + .external_auth = mtk_cfg80211_external_auth, +#endif +}; +#else /* CFG_ENABLE_UNIFY_WIPHY */ +static struct cfg80211_ops mtk_cfg_ops = { + .add_virtual_intf = mtk_cfg_add_iface, + .del_virtual_intf = mtk_cfg_del_iface, + .change_virtual_intf = mtk_cfg_change_iface, + .add_key = mtk_cfg_add_key, + .get_key = mtk_cfg_get_key, + .del_key = mtk_cfg_del_key, + .set_default_mgmt_key = mtk_cfg_set_default_mgmt_key, + .set_default_key = mtk_cfg_set_default_key, + .get_station = mtk_cfg_get_station, +#if CFG_SUPPORT_TDLS + .change_station = mtk_cfg_change_station, + .add_station = mtk_cfg_add_station, + .tdls_oper = mtk_cfg_tdls_oper, + .tdls_mgmt = mtk_cfg_tdls_mgmt, +#endif + .del_station = mtk_cfg_del_station, /* AP/P2P use this function */ + .scan = mtk_cfg_scan, +#if KERNEL_VERSION(4, 5, 0) <= CFG80211_VERSION_CODE + .abort_scan = mtk_cfg_abort_scan, +#endif +#if CFG_SUPPORT_SCHED_SCAN + .sched_scan_start = mtk_cfg_sched_scan_start, + .sched_scan_stop = mtk_cfg_sched_scan_stop, +#endif /* CFG_SUPPORT_SCHED_SCAN */ + + .connect = mtk_cfg_connect, + .disconnect = mtk_cfg_disconnect, + .join_ibss = mtk_cfg_join_ibss, + .leave_ibss = mtk_cfg_leave_ibss, + .set_power_mgmt = mtk_cfg_set_power_mgmt, + .set_pmksa = mtk_cfg_set_pmksa, + .del_pmksa = mtk_cfg_del_pmksa, + .flush_pmksa = mtk_cfg_flush_pmksa, +#if CONFIG_SUPPORT_GTK_REKEY + .set_rekey_data = mtk_cfg_set_rekey_data, +#endif + .suspend = mtk_cfg_suspend, + .resume = mtk_cfg_resume, + + .assoc = mtk_cfg_assoc, + + /* Action Frame TX/RX */ + .remain_on_channel = mtk_cfg_remain_on_channel, + .cancel_remain_on_channel = mtk_cfg_cancel_remain_on_channel, + .mgmt_tx = mtk_cfg_mgmt_tx, + /* .mgmt_tx_cancel_wait = mtk_cfg80211_mgmt_tx_cancel_wait, */ + .mgmt_frame_register = mtk_cfg_mgmt_frame_register, + +#ifdef CONFIG_NL80211_TESTMODE + .testmode_cmd = mtk_cfg_testmode_cmd, +#endif + +#if (CFG_SUPPORT_DFS_MASTER == 1) + .start_radar_detection = mtk_cfg_start_radar_detection, +#if KERNEL_VERSION(3, 13, 0) <= CFG80211_VERSION_CODE + .channel_switch = mtk_cfg_channel_switch, +#endif +#endif + +#if (CFG_ENABLE_WIFI_DIRECT_CFG_80211 != 0) + .change_bss = mtk_cfg_change_bss, + .mgmt_tx_cancel_wait = mtk_cfg_mgmt_tx_cancel_wait, + .deauth = mtk_cfg_deauth, + .disassoc = mtk_cfg_disassoc, + .start_ap = mtk_cfg_start_ap, + .change_beacon = mtk_cfg_change_beacon, + .stop_ap = mtk_cfg_stop_ap, + .set_wiphy_params = mtk_cfg_set_wiphy_params, + .set_bitrate_mask = mtk_cfg_set_bitrate_mask, + .set_tx_power = mtk_cfg_set_txpower, + .get_tx_power = mtk_cfg_get_txpower, +#endif + .update_ft_ies = mtk_cfg80211_update_ft_ies, +#if CFG_SUPPORT_WPA3 + .external_auth = mtk_cfg80211_external_auth, +#endif +}; +#endif /* CFG_ENABLE_UNIFY_WIPHY */ + +#if KERNEL_VERSION(3, 18, 0) <= CFG80211_VERSION_CODE + +static const struct wiphy_vendor_command + mtk_wlan_vendor_ops[] = { + { + { + .vendor_id = GOOGLE_OUI, + .subcmd = WIFI_SUBCMD_GET_CHANNEL_LIST + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = mtk_cfg80211_vendor_get_channel_list +#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE + , + .policy = VENDOR_CMD_RAW_DATA +#endif + }, + { + { + .vendor_id = GOOGLE_OUI, + .subcmd = WIFI_SUBCMD_SET_COUNTRY_CODE + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = mtk_cfg80211_vendor_set_country_code +#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE + , + .policy = VENDOR_CMD_RAW_DATA +#endif + }, + { + { + .vendor_id = GOOGLE_OUI, + .subcmd = WIFI_SUBCMD_SET_PNO_RANDOM_MAC_OUI + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV + | WIPHY_VENDOR_CMD_NEED_NETDEV + | WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = mtk_cfg80211_vendor_set_scan_mac_oui +#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE + , + .policy = VENDOR_CMD_RAW_DATA +#endif + }, + { + { + .vendor_id = OUI_QCA, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = mtk_cfg80211_vendor_set_band +#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE + , + .policy = VENDOR_CMD_RAW_DATA +#endif + }, +#if CFG_SUPPORT_MBO + { + { + .vendor_id = OUI_QCA, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAM + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = mtk_cfg80211_vendor_set_roaming_param +#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE + , + .policy = VENDOR_CMD_RAW_DATA +#endif + + }, +#endif + { + { + .vendor_id = OUI_QCA, + .subcmd = WIFI_SUBCMD_SET_ROAMING + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = mtk_cfg80211_vendor_set_roaming_policy +#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE + , + .policy = VENDOR_CMD_RAW_DATA +#endif + }, + { + { + .vendor_id = GOOGLE_OUI, + .subcmd = WIFI_SUBCMD_GET_ROAMING_CAPABILITIES + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = mtk_cfg80211_vendor_get_roaming_capabilities +#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE + , + .policy = VENDOR_CMD_RAW_DATA +#endif + }, + { + { + .vendor_id = GOOGLE_OUI, + .subcmd = WIFI_SUBCMD_CONFIG_ROAMING + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = mtk_cfg80211_vendor_config_roaming +#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE + , + .policy = VENDOR_CMD_RAW_DATA +#endif + }, + { + { + .vendor_id = GOOGLE_OUI, + .subcmd = WIFI_SUBCMD_ENABLE_ROAMING + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = mtk_cfg80211_vendor_enable_roaming +#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE + , + .policy = VENDOR_CMD_RAW_DATA +#endif + }, + /* RTT */ + { + { + .vendor_id = GOOGLE_OUI, + .subcmd = RTT_SUBCMD_GETCAPABILITY + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = mtk_cfg80211_vendor_get_rtt_capabilities +#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE + , + .policy = VENDOR_CMD_RAW_DATA +#endif + }, + /* Link Layer Statistics */ + { + { + .vendor_id = GOOGLE_OUI, + .subcmd = LSTATS_SUBCMD_GET_INFO + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = mtk_cfg80211_vendor_llstats_get_info +#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE + , + .policy = VENDOR_CMD_RAW_DATA +#endif + }, + /* RSSI Monitoring */ + { + { + .vendor_id = GOOGLE_OUI, + .subcmd = WIFI_SUBCMD_SET_RSSI_MONITOR + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = mtk_cfg80211_vendor_set_rssi_monitoring +#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE + , + .policy = VENDOR_CMD_RAW_DATA +#endif + }, + /* Packet Keep Alive */ + { + { + .vendor_id = GOOGLE_OUI, + .subcmd = WIFI_OFFLOAD_START_MKEEP_ALIVE + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = mtk_cfg80211_vendor_packet_keep_alive_start +#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE + , + .policy = VENDOR_CMD_RAW_DATA +#endif + }, + { + { + .vendor_id = GOOGLE_OUI, + .subcmd = WIFI_OFFLOAD_STOP_MKEEP_ALIVE + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = mtk_cfg80211_vendor_packet_keep_alive_stop +#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE + , + .policy = VENDOR_CMD_RAW_DATA +#endif + }, + /* Get Driver Version or Firmware Version */ + { + { + .vendor_id = GOOGLE_OUI, + .subcmd = LOGGER_GET_VER + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = mtk_cfg80211_vendor_get_version +#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE + , + .policy = VENDOR_CMD_RAW_DATA +#endif + }, + /* Get Supported Feature Set */ + { + { + .vendor_id = GOOGLE_OUI, + .subcmd = WIFI_SUBCMD_GET_FEATURE_SET + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = mtk_cfg80211_vendor_get_supported_feature_set +#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE + , + .policy = VENDOR_CMD_RAW_DATA +#endif + + }, + /* Set Tx Power Scenario */ + { + { + .vendor_id = GOOGLE_OUI, + .subcmd = WIFI_SUBCMD_SELECT_TX_POWER_SCENARIO + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = mtk_cfg80211_vendor_set_tx_power_scenario +#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE + , + .policy = VENDOR_CMD_RAW_DATA +#endif + }, +#if CFG_SUPPORT_P2P_PREFERRED_FREQ_LIST + /* P2P get preferred freq list */ + { + { + .vendor_id = OUI_QCA, + .subcmd = NL80211_VENDOR_SUBCMD_GET_PREFER_FREQ_LIST + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV + | WIPHY_VENDOR_CMD_NEED_NETDEV + | WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = mtk_cfg80211_vendor_get_preferred_freq_list +#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE + , + .policy = VENDOR_CMD_RAW_DATA +#endif + }, +#endif /* CFG_SUPPORT_P2P_PREFERRED_FREQ_LIST */ +#if CFG_AUTO_CHANNEL_SEL_SUPPORT + { + { + .vendor_id = OUI_QCA, + .subcmd = NL80211_VENDOR_SUBCMD_ACS + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV + | WIPHY_VENDOR_CMD_NEED_NETDEV + | WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = mtk_cfg80211_vendor_acs +#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE + , + .policy = VENDOR_CMD_RAW_DATA +#endif + }, +#endif + { + { + .vendor_id = OUI_QCA, + .subcmd = NL80211_VENDOR_SUBCMD_GET_FEATURES + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV + | WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = mtk_cfg80211_vendor_get_features +#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE + , + .policy = VENDOR_CMD_RAW_DATA +#endif + + }, + /* Get Driver Memory Dump */ + { + { + .vendor_id = GOOGLE_OUI, + .subcmd = LOGGER_DRIVER_MEM_DUMP + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = mtk_cfg80211_vendor_driver_memory_dump +#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE + , + .policy = VENDOR_CMD_RAW_DATA +#endif + } +}; + +static const struct nl80211_vendor_cmd_info + mtk_wlan_vendor_events[] = { + { + .vendor_id = GOOGLE_OUI, + .subcmd = GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS + }, + { + .vendor_id = GOOGLE_OUI, + .subcmd = GSCAN_EVENT_HOTLIST_RESULTS_FOUND + }, + { + .vendor_id = GOOGLE_OUI, + .subcmd = GSCAN_EVENT_SCAN_RESULTS_AVAILABLE + }, + { + .vendor_id = GOOGLE_OUI, + .subcmd = GSCAN_EVENT_FULL_SCAN_RESULTS + }, + { + .vendor_id = GOOGLE_OUI, + .subcmd = RTT_EVENT_COMPLETE + }, + { + .vendor_id = GOOGLE_OUI, + .subcmd = GSCAN_EVENT_COMPLETE_SCAN + }, + { + .vendor_id = GOOGLE_OUI, + .subcmd = GSCAN_EVENT_HOTLIST_RESULTS_LOST + }, + { + .vendor_id = GOOGLE_OUI, + .subcmd = WIFI_EVENT_RSSI_MONITOR + }, +#if CFG_SUPPORT_DATA_STALL + { + .vendor_id = OUI_MTK, + .subcmd = WIFI_EVENT_DRIVER_ERROR + }, +#endif +#if CFG_AUTO_CHANNEL_SEL_SUPPORT + { + .vendor_id = OUI_QCA, + .subcmd = NL80211_VENDOR_SUBCMD_ACS + }, +#endif + + { + .vendor_id = OUI_MTK, + .subcmd = WIFI_EVENT_GENERIC_RESPONSE + }, + +#if CFG_SUPPORT_BIGDATA_PIP + { + .vendor_id = OUI_MTK, + .subcmd = WIFI_EVENT_BIGDATA_PIP + }, +#endif + +}; +#endif + +/* There isn't a lot of sense in it, but you can transmit anything you like */ +static const struct ieee80211_txrx_stypes + mtk_cfg80211_ais_default_mgmt_stypes[NUM_NL80211_IFTYPES] = { + [NL80211_IFTYPE_ADHOC] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ACTION >> 4) + }, + [NL80211_IFTYPE_STATION] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | + BIT(IEEE80211_STYPE_AUTH >> 4) + }, + [NL80211_IFTYPE_AP] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_PROBE_REQ >> 4) + | BIT(IEEE80211_STYPE_ACTION >> 4) +#if CFG_SUPPORT_SOFTAP_WPA3 + | BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_DISASSOC >> 4) | + BIT(IEEE80211_STYPE_AUTH >> 4) | + BIT(IEEE80211_STYPE_DEAUTH >> 4) +#endif + }, + [NL80211_IFTYPE_AP_VLAN] = { + /* copy AP */ + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | + BIT(IEEE80211_STYPE_DISASSOC >> 4) | + BIT(IEEE80211_STYPE_AUTH >> 4) | + BIT(IEEE80211_STYPE_DEAUTH >> 4) | + BIT(IEEE80211_STYPE_ACTION >> 4) + }, + [NL80211_IFTYPE_P2P_CLIENT] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4) + }, + [NL80211_IFTYPE_P2P_GO] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | + BIT(IEEE80211_STYPE_ACTION >> 4) + } +}; + +#ifdef CONFIG_PM +static const struct wiphy_wowlan_support mtk_wlan_wowlan_support = { + .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT | + WIPHY_WOWLAN_ANY, +}; +#endif + +#if CFG_SUPPORT_RM_BEACON_REPORT_BY_SUPPLICANT +/* NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES & NL80211_FEATURE_QUIET + * support in linux kernet version => 3.18 + */ +#if KERNEL_VERSION(3, 18, 0) > CFG80211_VERSION_CODE +#define NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES BIT(19) +#define NL80211_FEATURE_QUIET BIT(21) +#endif +#endif + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#if 0 +/*----------------------------------------------------------------------------*/ +/*! + * \brief Override the implementation of select queue + * + * \param[in] dev Pointer to struct net_device + * \param[in] skb Pointer to struct skb_buff + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +unsigned int _cfg80211_classify8021d(struct sk_buff *skb) +{ + unsigned int dscp = 0; + + /* skb->priority values from 256->263 are magic values + * directly indicate a specific 802.1d priority. This is + * to allow 802.1d priority to be passed directly in from + * tags + */ + + if (skb->priority >= 256 && skb->priority <= 263) + return skb->priority - 256; + switch (skb->protocol) { + case htons(ETH_P_IP): + dscp = ip_hdr(skb)->tos & 0xfc; + break; + } + return dscp >> 5; +} +#endif + +#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE +u16 wlanSelectQueue(struct net_device *dev, + struct sk_buff *skb, + struct net_device *sb_dev) +{ + return mtk_wlan_ndev_select_queue(skb); +} +#elif KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE +u16 wlanSelectQueue(struct net_device *dev, + struct sk_buff *skb, + struct net_device *sb_dev, select_queue_fallback_t fallback) +{ + return mtk_wlan_ndev_select_queue(skb); +} +#elif KERNEL_VERSION(3, 14, 0) <= LINUX_VERSION_CODE +u16 wlanSelectQueue(struct net_device *dev, + struct sk_buff *skb, + void *accel_priv, select_queue_fallback_t fallback) +{ + return mtk_wlan_ndev_select_queue(skb); +} +#elif KERNEL_VERSION(3, 13, 0) <= LINUX_VERSION_CODE +u16 wlanSelectQueue(struct net_device *dev, + struct sk_buff *skb, + void *accel_priv) +{ + return mtk_wlan_ndev_select_queue(skb); +} +#else +u16 wlanSelectQueue(struct net_device *dev, + struct sk_buff *skb) +{ + return mtk_wlan_ndev_select_queue(skb); +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Load NVRAM data and translate it into REG_INFO_T + * + * \param[in] prGlueInfo Pointer to struct GLUE_INFO_T + * \param[out] prRegInfo Pointer to struct REG_INFO_T + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +static void glLoadNvram(struct GLUE_INFO *prGlueInfo, + struct REG_INFO *prRegInfo) +{ + struct WIFI_CFG_PARAM_STRUCT *prNvramSettings; + + ASSERT(prRegInfo); + ASSERT(prGlueInfo); + + DBGLOG(INIT, INFO, "g_NvramFsm = %d\n", g_NvramFsm); + if (g_NvramFsm != NVRAM_STATE_READY) { + DBGLOG(INIT, WARN, "Nvram not available\n"); + return; + } + + if (sizeof(struct WIFI_CFG_PARAM_STRUCT) > + sizeof(g_aucNvram)) { + DBGLOG(INIT, ERROR, + "Size WIFI_CFG_PARAM_STRUCT %zu > size aucNvram %zu\n" + , sizeof(struct WIFI_CFG_PARAM_STRUCT), + sizeof(g_aucNvram)); + return; + } + + prGlueInfo->fgNvramAvailable = TRUE; + + prRegInfo->prNvramSettings = + (struct WIFI_CFG_PARAM_STRUCT *)&g_aucNvram[0]; + prNvramSettings = prRegInfo->prNvramSettings; + +#if CFG_TC1_FEATURE + TC1_FAC_NAME(FacReadWifiMacAddr)(prRegInfo->aucMacAddr); + DBGLOG(INIT, INFO, + "MAC address: " MACSTR, MAC2STR(prRegInfo->aucMacAddr)); +#else + /* load MAC Address */ + kalMemCopy(prRegInfo->aucMacAddr, + prNvramSettings->aucMacAddress, + PARAM_MAC_ADDR_LEN*sizeof(uint8_t)); +#endif + /* load country code */ + /* cast to wide characters */ + prRegInfo->au2CountryCode[0] = + (uint16_t) prNvramSettings->aucCountryCode[0]; + prRegInfo->au2CountryCode[1] = + (uint16_t) prNvramSettings->aucCountryCode[1]; + + prRegInfo->ucSupport5GBand = + prNvramSettings->ucSupport5GBand; + + prRegInfo->ucEnable5GBand = prNvramSettings->ucEnable5GBand; + + /* load regulation subbands */ + prRegInfo->eRegChannelListMap = 0; + prRegInfo->ucRegChannelListIndex = 0; + + if (prRegInfo->eRegChannelListMap == REG_CH_MAP_CUSTOMIZED) { + kalMemCopy(prRegInfo->rDomainInfo.rSubBand, + prNvramSettings->aucRegSubbandInfo, + MAX_SUBBAND_NUM*sizeof(uint8_t)); + } + + log_dbg(INIT, INFO, "u2Part1OwnVersion = %08x, u2Part1PeerVersion = %08x\n", + prNvramSettings->u2Part1OwnVersion, + prNvramSettings->u2Part1PeerVersion); +} + +static void wlanFreeNetDev(void) +{ + uint32_t u4Idx = 0; + + for (u4Idx = 0; u4Idx < KAL_AIS_NUM; u4Idx++) { + if (gprWdev[u4Idx] && gprWdev[u4Idx]->netdev) { + DBGLOG(INIT, INFO, "free_netdev wlan%d netdev start.\n", + u4Idx); + free_netdev(gprWdev[u4Idx]->netdev); + DBGLOG(INIT, INFO, "free_netdev wlan%d netdev end.\n", + u4Idx); + } + } +} + + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Release prDev from wlandev_array and free tasklet object related to + * it. + * + * \param[in] prDev Pointer to struct net_device + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +static void wlanClearDevIdx(struct net_device *prDev) +{ + int i; + + ASSERT(prDev); + + for (i = 0; i < CFG_MAX_WLAN_DEVICES; i++) { + if (arWlanDevInfo[i].prDev == prDev) { + arWlanDevInfo[i].prDev = NULL; + u4WlanDevNum--; + } + } + +} /* end of wlanClearDevIdx() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Allocate an unique interface index, net_device::ifindex member for + * this wlan device. Store the net_device in wlandev_array, and + * initialize tasklet object related to it. + * + * \param[in] prDev Pointer to struct net_device + * + * \retval >= 0 The device number. + * \retval -1 Fail to get index. + */ +/*----------------------------------------------------------------------------*/ +static int wlanGetDevIdx(struct net_device *prDev) +{ + int i; + + ASSERT(prDev); + + for (i = 0; i < CFG_MAX_WLAN_DEVICES; i++) { + if (arWlanDevInfo[i].prDev == (struct net_device *)NULL) { + /* Reserve 2 bytes space to store one digit of + * device number and NULL terminator. + */ + arWlanDevInfo[i].prDev = prDev; + u4WlanDevNum++; + return i; + } +#if CFG_SUPPORT_PERSIST_NETDEV + else if (arWlanDevInfo[i].prDev == prDev) + return i; +#endif + } + + return -1; +} /* end of wlanGetDevIdx() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief A method of struct net_device, a primary SOCKET interface to configure + * the interface lively. Handle an ioctl call on one of our devices. + * Everything Linux ioctl specific is done here. Then we pass the + * contents of the ifr->data to the request message handler. + * + * \param[in] prDev Linux kernel netdevice + * + * \param[in] prIFReq Our private ioctl request structure, typed for the + * generic + * struct ifreq so we can use ptr to function + * + * \param[in] cmd Command ID + * + * \retval WLAN_STATUS_SUCCESS The IOCTL command is executed successfully. + * \retval OTHER The execution of IOCTL command is failed. + */ +/*----------------------------------------------------------------------------*/ +int wlanDoIOCTL(struct net_device *prDev, + struct ifreq *prIfReq, int i4Cmd) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int ret = 0; + + /* Verify input parameters for the following functions */ + ASSERT(prDev && prIfReq); + if (!prDev || !prIfReq) { + DBGLOG(INIT, ERROR, "Invalid input data\n"); + return -EINVAL; + } + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prDev)); + if (!prGlueInfo) { + DBGLOG(INIT, ERROR, "prGlueInfo is NULL\n"); + return -EFAULT; + } + + if (prGlueInfo->u4ReadyFlag == 0) { + DBGLOG(INIT, ERROR, "Adapter is not ready\n"); + return -EINVAL; + } + + if ((i4Cmd >= SIOCIWFIRST) && (i4Cmd < SIOCIWFIRSTPRIV)) { + /* 0x8B00 ~ 0x8BDF, wireless extension region */ + ret = wext_support_ioctl(prDev, prIfReq, i4Cmd); + } else if ((i4Cmd >= SIOCIWFIRSTPRIV) + && (i4Cmd < SIOCIWLASTPRIV)) { + /* 0x8BE0 ~ 0x8BFF, private ioctl region */ + ret = priv_support_ioctl(prDev, prIfReq, i4Cmd); + } else if (i4Cmd == SIOCDEVPRIVATE + 1) { +#ifdef CFG_ANDROID_AOSP_PRIV_CMD + ret = android_private_support_driver_cmd(prDev, prIfReq, i4Cmd); +#else + ret = priv_support_driver_cmd(prDev, prIfReq, i4Cmd); +#endif /* CFG_ANDROID_AOSP_PRIV_CMD */ + } else if (i4Cmd == SIOCDEVPRIVATE + 2) { + ret = priv_support_ioctl(prDev, prIfReq, i4Cmd); + } else { + DBGLOG(INIT, WARN, "Unexpected ioctl command: 0x%04x\n", + i4Cmd); + ret = -EOPNOTSUPP; + } + + return ret; +} /* end of wlanDoIOCTL() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Export wlan GLUE_INFO_T pointer to p2p module + * + * \param[in] prGlueInfo Pointer to struct GLUE_INFO_T + * + * \return TRUE: get GlueInfo pointer successfully + * FALSE: wlan is not started yet + */ +/*---------------------------------------------------------------------------*/ +struct GLUE_INFO *wlanGetGlueInfo(void) +{ + struct net_device *prDev = NULL; + struct GLUE_INFO *prGlueInfo = NULL; + + if (u4WlanDevNum == 0) + return NULL; + + prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev; + if (prDev == NULL) + return NULL; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prDev)); + + return prGlueInfo; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is to set multicast list and set rx mode. + * + * \param[in] prDev Pointer to struct net_device + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ + +static struct delayed_work workq; +struct net_device *gPrDev; + +static void wlanSetMulticastList(struct net_device *prDev) +{ + struct GLUE_INFO *prGlueInfo; + + if (!prDev) + return; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prDev)); + + if (!prGlueInfo || !prGlueInfo->u4ReadyFlag) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return; + } + + /* Allow to receive all multicast for WOW */ + DBGLOG(INIT, TRACE, "flags: 0x%x\n", prDev->flags); + prDev->flags |= (IFF_MULTICAST | IFF_ALLMULTI); + gPrDev = prDev; + schedule_delayed_work(&workq, 0); +} + +/* FIXME: Since we cannot sleep in the wlanSetMulticastList, we arrange + * another workqueue for sleeping. We don't want to block + * main_thread, so we can't let tx_thread to do this + */ + +static void wlanSetMulticastListWorkQueue( + struct work_struct *work) +{ + + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t u4PacketFilter = 0; + uint32_t u4SetInfoLen; + struct net_device *prDev = gPrDev; + uint8_t ucBssIndex = 0; + + ucBssIndex = wlanGetBssIdx(prDev); + if (!IS_BSS_INDEX_VALID(ucBssIndex)) + return; + + down(&g_halt_sem); + if (g_u4HaltFlag) { + up(&g_halt_sem); + return; + } + + prGlueInfo = (prDev != NULL) ? *((struct GLUE_INFO **) + netdev_priv(prDev)) : NULL; + ASSERT(prDev); + ASSERT(prGlueInfo); + if (!prDev || !prGlueInfo) { + DBGLOG(INIT, WARN, + "abnormal dev or skb: prDev(0x%p), prGlueInfo(0x%p)\n", + prDev, prGlueInfo); + up(&g_halt_sem); + return; + } + + if (!prGlueInfo->u4ReadyFlag) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + up(&g_halt_sem); + return; + } + + DBGLOG(INIT, TRACE, + "wlanSetMulticastListWorkQueue prDev->flags:0x%x\n", + prDev->flags); + + if (prDev->flags & IFF_PROMISC) + u4PacketFilter |= PARAM_PACKET_FILTER_PROMISCUOUS; + + if (prDev->flags & IFF_BROADCAST) + u4PacketFilter |= PARAM_PACKET_FILTER_BROADCAST; + + if (prDev->flags & IFF_MULTICAST) { + if ((prDev->flags & IFF_ALLMULTI) + || (netdev_mc_count(prDev) > MAX_NUM_GROUP_ADDR)) + u4PacketFilter |= PARAM_PACKET_FILTER_ALL_MULTICAST; + else + u4PacketFilter |= PARAM_PACKET_FILTER_MULTICAST; + } + + up(&g_halt_sem); + + if (kalIoctl(prGlueInfo, + wlanoidSetCurrentPacketFilter, + &u4PacketFilter, + sizeof(u4PacketFilter), FALSE, FALSE, TRUE, + &u4SetInfoLen) != WLAN_STATUS_SUCCESS) { + return; + } + + if (u4PacketFilter & PARAM_PACKET_FILTER_MULTICAST) { + /* Prepare multicast address list */ + struct netdev_hw_addr *ha; + uint8_t *prMCAddrList = NULL; + uint32_t i = 0; + + down(&g_halt_sem); + if (g_u4HaltFlag) { + up(&g_halt_sem); + return; + } + + prMCAddrList = kalMemAlloc(MAX_NUM_GROUP_ADDR * ETH_ALEN, + VIR_MEM_TYPE); + if (!prMCAddrList) { + DBGLOG(INIT, WARN, "prMCAddrList memory alloc fail!\n"); + up(&g_halt_sem); + return; + } + + /* Avoid race condition with kernel net subsystem */ + netif_addr_lock_bh(prDev); + + netdev_for_each_mc_addr(ha, prDev) { + if (i < MAX_NUM_GROUP_ADDR) { + kalMemCopy((prMCAddrList + i * ETH_ALEN), + GET_ADDR(ha), ETH_ALEN); + i++; + } + } + + netif_addr_unlock_bh(prDev); + + up(&g_halt_sem); + + kalIoctlByBssIdx(prGlueInfo, + wlanoidSetMulticastList, prMCAddrList, (i * ETH_ALEN), + FALSE, FALSE, TRUE, &u4SetInfoLen, + ucBssIndex); + + kalMemFree(prMCAddrList, VIR_MEM_TYPE, + MAX_NUM_GROUP_ADDR * ETH_ALEN); + } + +} /* end of wlanSetMulticastList() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief To indicate scheduled scan has been stopped + * + * \param[in] + * prGlueInfo + * + * \return + * None + */ +/*----------------------------------------------------------------------------*/ +void wlanSchedScanStoppedWorkQueue(struct work_struct *work) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct net_device *prDev = gPrDev; + + DBGLOG(SCN, INFO, "wlanSchedScanStoppedWorkQueue\n"); + prGlueInfo = (prDev != NULL) ? *((struct GLUE_INFO **) + netdev_priv(prDev)) : NULL; + if (!prGlueInfo) { + DBGLOG(SCN, INFO, "prGlueInfo == NULL unexpected\n"); + return; + } + + /* 2. indication to cfg80211 */ + /* 20150205 change cfg80211_sched_scan_stopped to work queue due to + * sched_scan_mtx dead lock issue + */ +#if KERNEL_VERSION(4, 12, 0) <= CFG80211_VERSION_CODE + cfg80211_sched_scan_stopped(priv_to_wiphy(prGlueInfo), 0); +#else + cfg80211_sched_scan_stopped(priv_to_wiphy(prGlueInfo)); +#endif + DBGLOG(SCN, INFO, + "cfg80211_sched_scan_stopped event send done WorkQueue thread return from wlanSchedScanStoppedWorkQueue\n"); + return; + +} + +/* FIXME: Since we cannot sleep in the wlanSetMulticastList, we arrange + * another workqueue for sleeping. We don't want to block + * main_thread, so we can't let tx_thread to do this + */ + +void p2pSetMulticastListWorkQueueWrapper(struct GLUE_INFO + *prGlueInfo) +{ + + + if (!prGlueInfo) { + DBGLOG(INIT, WARN, + "abnormal dev or skb: prGlueInfo(0x%p)\n", prGlueInfo); + return; + } +#if CFG_ENABLE_WIFI_DIRECT + if (prGlueInfo->prAdapter->fgIsP2PRegistered) + mtk_p2p_wext_set_Multicastlist(prGlueInfo); +#endif + +} /* end of p2pSetMulticastListWorkQueueWrapper() */ + +/*----------------------------------------------------------------------------*/ +/* + * \brief This function is TX entry point of NET DEVICE. + * + * \param[in] prSkb Pointer of the sk_buff to be sent + * \param[in] prDev Pointer to struct net_device + * + * \retval NETDEV_TX_OK - on success. + * \retval NETDEV_TX_BUSY - on failure, packet will be discarded by upper layer. + */ +/*----------------------------------------------------------------------------*/ +netdev_tx_t wlanHardStartXmit(struct sk_buff *prSkb, + struct net_device *prDev) +{ + struct NETDEV_PRIVATE_GLUE_INFO *prNetDevPrivate = + (struct NETDEV_PRIVATE_GLUE_INFO *) NULL; + struct GLUE_INFO *prGlueInfo = *((struct GLUE_INFO **) + netdev_priv(prDev)); + uint8_t ucBssIndex; + + ASSERT(prSkb); + ASSERT(prDev); + ASSERT(prGlueInfo); + + prNetDevPrivate = (struct NETDEV_PRIVATE_GLUE_INFO *) + netdev_priv(prDev); + ASSERT(prNetDevPrivate->prGlueInfo == prGlueInfo); + ucBssIndex = prNetDevPrivate->ucBssIdx; + +#if CFG_SUPPORT_PASSPOINT + if (prGlueInfo->fgIsDad) { + /* kalPrint("[Passpoint R2] Due to ipv4_dad...TX is forbidden\n" + * ); + */ + dev_kfree_skb(prSkb); + return NETDEV_TX_OK; + } + if (prGlueInfo->fgIs6Dad) { + /* kalPrint("[Passpoint R2] Due to ipv6_dad...TX is forbidden\n" + * ); + */ + dev_kfree_skb(prSkb); + return NETDEV_TX_OK; + } +#endif /* CFG_SUPPORT_PASSPOINT */ + +#if CFG_CHIP_RESET_SUPPORT + if (!wlanIsDriverReady(prGlueInfo)) { + DBGLOG(INIT, WARN, + "u4ReadyFlag:%u, kalIsResetting():%d, dropping the packet\n", + prGlueInfo->u4ReadyFlag, kalIsResetting()); + dev_kfree_skb(prSkb); + return NETDEV_TX_OK; + } +#endif + kalResetPacket(prGlueInfo, (void *) prSkb); +#if (CFG_SUPPORT_STATISTICS == 1) + STATS_TX_TIME_ARRIVE(prSkb); +#endif + if (kalHardStartXmit(prSkb, prDev, prGlueInfo, + ucBssIndex) == WLAN_STATUS_SUCCESS) { + /* Successfully enqueue to Tx queue */ + /* Successfully enqueue to Tx queue */ + if (netif_carrier_ok(prDev)) + kalPerMonStart(prGlueInfo); + } + + /* For Linux, we'll always return OK FLAG, because we'll free this skb + * by ourself + */ + return NETDEV_TX_OK; +} /* end of wlanHardStartXmit() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief A method of struct net_device, to get the network interface + * statistical information. + * + * Whenever an application needs to get statistics for the interface, this + * method is called. This happens, for example, when ifconfig or netstat -i + * is run. + * + * \param[in] prDev Pointer to struct net_device. + * + * \return net_device_stats buffer pointer. + */ +/*----------------------------------------------------------------------------*/ +struct net_device_stats *wlanGetStats(IN struct net_device + *prDev) +{ + struct NETDEV_PRIVATE_GLUE_INFO *prNetDevPrivate; + + prNetDevPrivate = (struct NETDEV_PRIVATE_GLUE_INFO *) + netdev_priv(prDev); + kalMemCopy(&prNetDevPrivate->stats, &prDev->stats, + sizeof(struct net_device_stats)); +#if CFG_MTK_MCIF_WIFI_SUPPORT + mddpGetMdStats(prDev); +#endif + + return (struct net_device_stats *) &prNetDevPrivate->stats; +} /* end of wlanGetStats() */ + +void wlanDebugInit(void) +{ + /* Set the initial debug level of each module */ +#if DBG + /* enable all */ + wlanSetDriverDbgLevel(DBG_ALL_MODULE_IDX, DBG_CLASS_MASK); +#else +#ifdef CFG_DEFAULT_DBG_LEVEL + wlanSetDriverDbgLevel(DBG_ALL_MODULE_IDX, + CFG_DEFAULT_DBG_LEVEL); +#else + wlanSetDriverDbgLevel(DBG_ALL_MODULE_IDX, + DBG_LOG_LEVEL_DEFAULT); +#endif +#endif /* DBG */ + + LOG_FUNC("Reset ALL DBG module log level to DEFAULT!"); + +} + +#if CFG_SUPPORT_RX_GRO +/*----------------------------------------------------------------------------*/ +/*! + * \brief A method of callback function for napi struct + * + * It just return false because driver indicate Rx packet directly. + * + * \param[in] napi Pointer to struct napi_struct. + * \param[in] budget Polling time interval. + * + * \return false + */ +/*----------------------------------------------------------------------------*/ +static int kal_napi_poll(struct napi_struct *napi, int budget) +{ + return 0; +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief A function for prDev->init + * + * \param[in] prDev Pointer to struct net_device. + * + * \retval 0 The execution of wlanInit succeeds. + * \retval -ENXIO No such device. + */ +/*----------------------------------------------------------------------------*/ +static int wlanInit(struct net_device *prDev) +{ + struct GLUE_INFO *prGlueInfo = NULL; +#if CFG_SUPPORT_RX_GRO + uint8_t ucBssIndex; + struct NETDEV_PRIVATE_GLUE_INFO *prNetDevPrivate = NULL; +#endif + if (!prDev) + return -ENXIO; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prDev)); + INIT_DELAYED_WORK(&workq, wlanSetMulticastListWorkQueue); + + /* 20150205 work queue for sched_scan */ + INIT_DELAYED_WORK(&sched_workq, + wlanSchedScanStoppedWorkQueue); + + /* 20161024 init wow port setting */ +#if CFG_WOW_SUPPORT + kalWowInit(prGlueInfo); +#endif + +#if CFG_SUPPORT_RX_GRO + /* Register GRO function to kernel */ + ucBssIndex = wlanGetBssIdx(prDev); + prDev->features |= NETIF_F_GRO; + prDev->hw_features |= NETIF_F_GRO; + prNetDevPrivate = (struct NETDEV_PRIVATE_GLUE_INFO *) + netdev_priv(prDev); + spin_lock_init(&prNetDevPrivate->napi_spinlock); + prNetDevPrivate->napi.dev = prDev; + netif_napi_add(prNetDevPrivate->napi.dev, + &prNetDevPrivate->napi, kal_napi_poll, 64); + DBGLOG(INIT, INFO, + "GRO interface added successfully:%p\n", prDev); +#endif + return 0; /* success */ +} /* end of wlanInit() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief A function for prDev->uninit + * + * \param[in] prDev Pointer to struct net_device. + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +static void wlanUninit(struct net_device *prDev) +{ +} /* end of wlanUninit() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief A method of struct net_device, to set the randomized mac address + * + * This method is called before Wifi Framework requests a new conenction with + * enabled feature "Connected Random Mac". + * + * \param[in] ndev Pointer to struct net_device. + * \param[in] addr Randomized Mac address passed from WIFI framework. + * + * \return int. + */ +/*----------------------------------------------------------------------------*/ +static int wlanSetMacAddress(struct net_device *ndev, void *addr) +{ + struct ADAPTER *prAdapter = NULL; + struct GLUE_INFO *prGlueInfo = NULL; + struct sockaddr *sa = NULL; + struct BSS_INFO *prAisBssInfo = NULL; + + /********************************************************************** + * Check if kernel passes valid data to us * + ********************************************************************** + */ + if (!ndev || !addr) { + DBGLOG(INIT, ERROR, "Set macaddr with ndev(%d) and addr(%d)\n", + (ndev == NULL) ? 0 : 1, (addr == NULL) ? 0 : 1); + return -EINVAL; + } + + /********************************************************************** + * 1. Change OwnMacAddr which will be updated to FW through * + * rlmActivateNetwork later. * + * 2. Change dev_addr stored in kernel to notify framework that the * + * mac addr has been changed and what the new value is. * + ********************************************************************** + */ + sa = (struct sockaddr *)addr; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(ndev)); + + if (!prGlueInfo || !prGlueInfo->u4ReadyFlag) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -EFAULT; + } + + prAdapter = prGlueInfo->prAdapter; + prAisBssInfo = aisGetAisBssInfo(prAdapter, + wlanGetBssIdx(ndev)); + + COPY_MAC_ADDR(prAisBssInfo->aucOwnMacAddr, sa->sa_data); + COPY_MAC_ADDR(ndev->dev_addr, sa->sa_data); + DBGLOG(INIT, INFO, + "[wlan%d] Set connect random macaddr to " MACSTR ".\n", + prAisBssInfo->ucBssIndex, + MAC2STR(prAisBssInfo->aucOwnMacAddr)); + + return WLAN_STATUS_SUCCESS; +} /* end of wlanSetMacAddr() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief A function for prDev->open + * + * \param[in] prDev Pointer to struct net_device. + * + * \retval 0 The execution of wlanOpen succeeds. + * \retval < 0 The execution of wlanOpen failed. + */ +/*----------------------------------------------------------------------------*/ +static int wlanOpen(struct net_device *prDev) +{ + ASSERT(prDev); + + netif_tx_start_all_queues(prDev); + + return 0; /* success */ +} /* end of wlanOpen() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief A function for prDev->stop + * + * \param[in] prDev Pointer to struct net_device. + * + * \retval 0 The execution of wlanStop succeeds. + * \retval < 0 The execution of wlanStop failed. + */ +/*----------------------------------------------------------------------------*/ +static int wlanStop(struct net_device *prDev) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + GLUE_SPIN_LOCK_DECLARATION(); + + ASSERT(prDev); + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prDev)); + + /* CFG80211 down, report to kernel directly and run normal + * scan abort procedure + */ + GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); + if (prGlueInfo->prScanRequest) { + kalCfg80211ScanDone(prGlueInfo->prScanRequest, TRUE); + aisFsmStateAbort_SCAN(prGlueInfo->prAdapter, + wlanGetBssIdx(prDev)); + prGlueInfo->prScanRequest = NULL; + } + GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); + + netif_tx_stop_all_queues(prDev); + + return 0; /* success */ +} /* end of wlanStop() */ + +#if CFG_SUPPORT_SNIFFER +static int wlanMonOpen(struct net_device *prDev) +{ + ASSERT(prDev); + + netif_tx_start_all_queues(prDev); + + return 0; /* success */ +} + +static int wlanMonStop(struct net_device *prDev) +{ + ASSERT(prDev); + + netif_tx_stop_all_queues(prDev); + + return 0; /* success */ +} + +static const struct net_device_ops wlan_mon_netdev_ops = { + .ndo_open = wlanMonOpen, + .ndo_stop = wlanMonStop, +}; + +void wlanMonWorkHandler(struct work_struct *work) +{ + struct GLUE_INFO *prGlueInfo; + + prGlueInfo = container_of(work, struct GLUE_INFO, monWork); + + if (prGlueInfo->fgIsEnableMon) { + if (prGlueInfo->prMonDevHandler) + return; +#if KERNEL_VERSION(3, 18, 0) <= LINUX_VERSION_CODE + prGlueInfo->prMonDevHandler = + alloc_netdev_mq(sizeof(struct NETDEV_PRIVATE_GLUE_INFO), + NIC_MONITOR_INF_NAME, + NET_NAME_PREDICTABLE, ether_setup, + CFG_MAX_TXQ_NUM); +#else + prGlueInfo->prMonDevHandler = + alloc_netdev_mq(sizeof(struct NETDEV_PRIVATE_GLUE_INFO), + NIC_MONITOR_INF_NAME, + ether_setup, CFG_MAX_TXQ_NUM); +#endif + if (prGlueInfo->prMonDevHandler == NULL) { + DBGLOG(INIT, ERROR, + "wlanMonWorkHandler: Allocated prMonDevHandler context FAIL.\n"); + return; + } + + ((struct NETDEV_PRIVATE_GLUE_INFO *) netdev_priv( + prGlueInfo->prMonDevHandler))->prGlueInfo = prGlueInfo; + prGlueInfo->prMonDevHandler->type = + ARPHRD_IEEE80211_RADIOTAP; + prGlueInfo->prMonDevHandler->netdev_ops = + &wlan_mon_netdev_ops; + netif_carrier_off(prGlueInfo->prMonDevHandler); + netif_tx_stop_all_queues(prGlueInfo->prMonDevHandler); + kalResetStats(prGlueInfo->prMonDevHandler); + + if (register_netdev(prGlueInfo->prMonDevHandler) < 0) { + DBGLOG(INIT, ERROR, + "wlanMonWorkHandler: Registered prMonDevHandler context FAIL.\n"); + free_netdev(prGlueInfo->prMonDevHandler); + prGlueInfo->prMonDevHandler = NULL; + } + DBGLOG(INIT, INFO, + "wlanMonWorkHandler: Registered prMonDevHandler context DONE.\n"); + } else { + if (prGlueInfo->prMonDevHandler) { + unregister_netdev(prGlueInfo->prMonDevHandler); + prGlueInfo->prMonDevHandler = NULL; + DBGLOG(INIT, INFO, + "wlanMonWorkHandler: unRegistered prMonDevHandler context DONE.\n"); + } + } +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Update Channel table for cfg80211 for Wi-Fi Direct based on current + * country code + * + * \param[in] prGlueInfo Pointer to glue info + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void wlanUpdateChannelTable(struct GLUE_INFO *prGlueInfo) +{ + uint8_t i, j; + uint8_t ucNumOfChannel; + struct RF_CHANNEL_INFO aucChannelList[ARRAY_SIZE( + mtk_2ghz_channels) + ARRAY_SIZE(mtk_5ghz_channels)]; + + kalMemZero(aucChannelList, sizeof(aucChannelList)); + + /* 1. Disable all channels */ + for (i = 0; i < ARRAY_SIZE(mtk_2ghz_channels); i++) { + mtk_2ghz_channels[i].flags |= IEEE80211_CHAN_DISABLED; + mtk_2ghz_channels[i].orig_flags |= IEEE80211_CHAN_DISABLED; + } + + for (i = 0; i < ARRAY_SIZE(mtk_5ghz_channels); i++) { + mtk_5ghz_channels[i].flags |= IEEE80211_CHAN_DISABLED; + mtk_5ghz_channels[i].orig_flags |= IEEE80211_CHAN_DISABLED; + } + + /* 2. Get current domain channel list */ + rlmDomainGetChnlList(prGlueInfo->prAdapter, + BAND_NULL, FALSE, + ARRAY_SIZE(mtk_2ghz_channels) + ARRAY_SIZE( + mtk_5ghz_channels), + &ucNumOfChannel, aucChannelList); + + /* 3. Enable specific channel based on domain channel list */ + for (i = 0; i < ucNumOfChannel; i++) { + switch (aucChannelList[i].eBand) { + case BAND_2G4: + for (j = 0; j < ARRAY_SIZE(mtk_2ghz_channels); j++) { + if (mtk_2ghz_channels[j].hw_value == + aucChannelList[i].ucChannelNum) { + mtk_2ghz_channels[j].flags &= + ~IEEE80211_CHAN_DISABLED; + mtk_2ghz_channels[j].orig_flags &= + ~IEEE80211_CHAN_DISABLED; + break; + } + } + break; + + case BAND_5G: + for (j = 0; j < ARRAY_SIZE(mtk_5ghz_channels); j++) { + if (mtk_5ghz_channels[j].hw_value == + aucChannelList[i].ucChannelNum) { + mtk_5ghz_channels[j].flags &= + ~IEEE80211_CHAN_DISABLED; + mtk_5ghz_channels[j].orig_flags &= + ~IEEE80211_CHAN_DISABLED; + mtk_5ghz_channels[j].dfs_state = + (aucChannelList[i].eDFS) ? + NL80211_DFS_USABLE : + NL80211_DFS_UNAVAILABLE; + if (mtk_5ghz_channels[j].dfs_state == + NL80211_DFS_USABLE) + mtk_5ghz_channels[j].flags |= + IEEE80211_CHAN_RADAR; + else + mtk_5ghz_channels[j].flags &= + ~IEEE80211_CHAN_RADAR; + break; + } + } + break; + + default: + DBGLOG(INIT, WARN, "Unknown band %d\n", + aucChannelList[i].eBand); + break; + } + } + +} + +#if CFG_SUPPORT_SAP_DFS_CHANNEL +static u_int8_t wlanIsAdjacentChnl(struct GL_P2P_INFO *prGlueP2pInfo, + uint32_t u4CenterFreq, uint8_t ucBandWidth, + enum ENUM_CHNL_EXT eBssSCO, uint8_t ucAdjacentChannel) +{ + uint32_t u4AdjacentFreq = 0; + uint32_t u4BandWidth = 20; + uint32_t u4StartFreq, u4EndFreq; + struct ieee80211_channel *chnl = NULL; + + u4AdjacentFreq = nicChannelNum2Freq(ucAdjacentChannel) / 1000; + + DBGLOG(INIT, TRACE, + "p2p: %p, center_freq: %d, bw: %d, sco: %d, ad_freq: %d", + prGlueP2pInfo, u4CenterFreq, ucBandWidth, eBssSCO, + u4AdjacentFreq); + + if (!prGlueP2pInfo) + return FALSE; + + if (ucBandWidth == VHT_OP_CHANNEL_WIDTH_20_40 && + eBssSCO == CHNL_EXT_SCN) + return FALSE; + + if (!u4CenterFreq) + return FALSE; + + if (!u4AdjacentFreq) + return FALSE; + + switch (ucBandWidth) { + case VHT_OP_CHANNEL_WIDTH_20_40: + u4BandWidth = 40; + break; + case VHT_OP_CHANNEL_WIDTH_80: + u4BandWidth = 80; + break; + default: + DBGLOG(INIT, WARN, "unsupported bandwidth: %d", ucBandWidth); + return FALSE; + } + u4StartFreq = u4CenterFreq - u4BandWidth / 2 + 10; + u4EndFreq = u4CenterFreq + u4BandWidth / 2 - 10; + DBGLOG(INIT, TRACE, "bw: %d, s_freq: %d, e_freq: %d", + u4BandWidth, u4StartFreq, u4EndFreq); + if (u4AdjacentFreq < u4StartFreq || u4AdjacentFreq > u4EndFreq) + return FALSE; + + /* check valid channel */ + chnl = ieee80211_get_channel(prGlueP2pInfo->prWdev->wiphy, + u4AdjacentFreq); + if (!chnl) { + DBGLOG(INIT, WARN, "invalid channel for freq: %d", + u4AdjacentFreq); + return FALSE; + } + return TRUE; +} + +void wlanUpdateDfsChannelTable(struct GLUE_INFO *prGlueInfo, + uint8_t ucRoleIdx, uint8_t ucChannel, uint8_t ucBandWidth, + enum ENUM_CHNL_EXT eBssSCO, uint32_t u4CenterFreq) +{ + struct GL_P2P_INFO *prGlueP2pInfo = NULL; + uint8_t i, j; + uint8_t ucNumOfChannel; + struct RF_CHANNEL_INFO aucChannelList[ + ARRAY_SIZE(mtk_5ghz_channels)] = {}; + + DBGLOG(INIT, INFO, "r: %d, chnl %u, b: %d, s: %d, freq: %d\n", + ucRoleIdx, ucChannel, ucBandWidth, eBssSCO, + u4CenterFreq); + + /* 1. Get current domain DFS channel list */ + rlmDomainGetDfsChnls(prGlueInfo->prAdapter, + ARRAY_SIZE(mtk_5ghz_channels), + &ucNumOfChannel, aucChannelList); + + if (ucRoleIdx >= 0 && ucRoleIdx < KAL_P2P_NUM) + prGlueP2pInfo = prGlueInfo->prP2PInfo[ucRoleIdx]; + + /* 2. Enable specific channel based on domain channel list */ + for (i = 0; i < ucNumOfChannel; i++) { + for (j = 0; j < ARRAY_SIZE(mtk_5ghz_channels); j++) { + if (aucChannelList[i].ucChannelNum != + mtk_5ghz_channels[j].hw_value) + continue; + + if ((aucChannelList[i].ucChannelNum == ucChannel) || + wlanIsAdjacentChnl(prGlueP2pInfo, + u4CenterFreq, + ucBandWidth, + eBssSCO, + aucChannelList[i].ucChannelNum)) { + mtk_5ghz_channels[j].dfs_state + = NL80211_DFS_AVAILABLE; + mtk_5ghz_channels[j].flags &= + ~IEEE80211_CHAN_RADAR; + mtk_5ghz_channels[j].orig_flags &= + ~IEEE80211_CHAN_RADAR; + DBGLOG(INIT, INFO, + "ch (%d), force NL80211_DFS_AVAILABLE.\n", + aucChannelList[i].ucChannelNum); + } else { + mtk_5ghz_channels[j].dfs_state + = NL80211_DFS_USABLE; + mtk_5ghz_channels[j].flags |= + IEEE80211_CHAN_RADAR; + mtk_5ghz_channels[j].orig_flags |= + IEEE80211_CHAN_RADAR; + DBGLOG(INIT, TRACE, + "ch (%d), force NL80211_DFS_USABLE.\n", + aucChannelList[i].ucChannelNum); + } + } + } +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Register the device to the kernel and return the index. + * + * \param[in] prDev Pointer to struct net_device. + * + * \retval 0 The execution of wlanNetRegister succeeds. + * \retval < 0 The execution of wlanNetRegister failed. + */ +/*----------------------------------------------------------------------------*/ +static int32_t wlanNetRegister(struct wireless_dev *prWdev) +{ + struct GLUE_INFO *prGlueInfo; + int32_t i4DevIdx = -1; + struct NETDEV_PRIVATE_GLUE_INFO *prNetDevPrivate = + (struct NETDEV_PRIVATE_GLUE_INFO *) NULL; + struct ADAPTER *prAdapter = NULL; + uint32_t u4Idx = 0; + + ASSERT(prWdev); + + do { + if (!prWdev) + break; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(prWdev->wiphy); + prAdapter = prGlueInfo->prAdapter; + i4DevIdx = wlanGetDevIdx(prWdev->netdev); + if (i4DevIdx < 0) { + DBGLOG(INIT, ERROR, "net_device number exceeds!\n"); + break; + } + + if (prAdapter && prAdapter->rWifiVar.ucWow) + kalInitDevWakeup(prGlueInfo->prAdapter, + wiphy_dev(prWdev->wiphy)); + + for (u4Idx = 0; u4Idx < KAL_AIS_NUM; u4Idx++) { + prNetDevPrivate = (struct NETDEV_PRIVATE_GLUE_INFO *) + netdev_priv(gprWdev[u4Idx]->netdev); + ASSERT(prNetDevPrivate->prGlueInfo == prGlueInfo); + prNetDevPrivate->ucBssIdx = u4Idx; +#if CFG_ENABLE_UNIFY_WIPHY + prNetDevPrivate->ucIsP2p = FALSE; +#endif +#if CFG_MTK_MCIF_WIFI_SUPPORT + /* only wlan0 supports mddp */ + prNetDevPrivate->ucMddpSupport = (u4Idx == 0); +#else + prNetDevPrivate->ucMddpSupport = FALSE; +#endif + wlanBindBssIdxToNetInterface(prGlueInfo, + u4Idx, + (void *)gprWdev[u4Idx]->netdev); +#if CFG_SUPPORT_PERSIST_NETDEV + if (gprNetdev[u4Idx]->reg_state == NETREG_REGISTERED) + continue; +#endif + if (register_netdev(gprWdev[u4Idx]->netdev) + < 0) { + DBGLOG(INIT, ERROR, + "Register net_device %d failed\n", + u4Idx); + wlanClearDevIdx( + gprWdev[u4Idx]->netdev); + i4DevIdx = -1; + break; + } + } + + if (i4DevIdx != -1) + prGlueInfo->fgIsRegistered = TRUE; + else { + /* Unregister the registered netdev if one of netdev + * registered fail + */ + for (u4Idx = 0; u4Idx < KAL_AIS_NUM; u4Idx++) { + if (!gprWdev[u4Idx] || !gprWdev[u4Idx]->netdev) + continue; + if (gprWdev[u4Idx]->netdev->reg_state != + NETREG_REGISTERED) + continue; + wlanClearDevIdx(gprWdev[u4Idx]->netdev); + unregister_netdev(gprWdev[u4Idx]->netdev); + } + } + } while (FALSE); + + return i4DevIdx; /* success */ +} /* end of wlanNetRegister() */ + + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Unregister the device from the kernel + * + * \param[in] prWdev Pointer to struct net_device. + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +static void wlanNetUnregister(struct wireless_dev *prWdev) +{ + struct GLUE_INFO *prGlueInfo; + + if (!prWdev) { + DBGLOG(INIT, ERROR, "The device context is NULL\n"); + return; + } + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(prWdev->wiphy); + +#if !CFG_SUPPORT_PERSIST_NETDEV + { + uint32_t u4Idx = 0; + + for (u4Idx = 0; u4Idx < KAL_AIS_NUM; u4Idx++) { + if (gprWdev[u4Idx] && gprWdev[u4Idx]->netdev) { + wlanClearDevIdx(gprWdev[u4Idx]->netdev); + unregister_netdev(gprWdev[u4Idx]->netdev); + } + } + + prGlueInfo->fgIsRegistered = FALSE; + } +#endif + +#if CFG_SUPPORT_SNIFFER + if (prGlueInfo->prMonDevHandler) { + unregister_netdev(prGlueInfo->prMonDevHandler); + /* FIXME: Why not free_netdev()? */ + prGlueInfo->prMonDevHandler = NULL; + } + prGlueInfo->fgIsEnableMon = FALSE; +#endif + +} /* end of wlanNetUnregister() */ + +static const struct net_device_ops wlan_netdev_ops = { + .ndo_open = wlanOpen, + .ndo_stop = wlanStop, + .ndo_set_rx_mode = wlanSetMulticastList, + .ndo_get_stats = wlanGetStats, + .ndo_do_ioctl = wlanDoIOCTL, + .ndo_start_xmit = wlanHardStartXmit, + .ndo_init = wlanInit, + .ndo_uninit = wlanUninit, + .ndo_select_queue = wlanSelectQueue, + .ndo_set_mac_address = wlanSetMacAddress, +}; + +#if CFG_ENABLE_UNIFY_WIPHY +const struct net_device_ops *wlanGetNdevOps(void) +{ + return &wlan_netdev_ops; +} +#endif +void wlanNvramSetState(enum ENUM_NVRAM_STATE state) +{ + g_NvramFsm = state; +} +enum ENUM_NVRAM_STATE wlanNvramGetState(void) +{ + return g_NvramFsm; +} +#if CFG_WLAN_ASSISTANT_NVRAM +static void wlanNvramUpdateOnTestMode(void) +{ + struct GLUE_INFO *prGlueInfo = NULL; + enum ENUM_NVRAM_STATE nvrmState; + struct REG_INFO *prRegInfo = NULL; + struct ADAPTER *prAdapter = NULL; + + /* <1> Sanity Check */ + if (u4WlanDevNum == 0) { + DBGLOG(INIT, ERROR, + "wlanNvramUpdateOnTestMode invalid!!\n"); + return; + } + + prGlueInfo = wlanGetGlueInfo(); + if (prGlueInfo == NULL) { + DBGLOG(INIT, WARN, + "prGlueInfo invalid!!\n"); + return; + } + prAdapter = prGlueInfo->prAdapter; + if (prAdapter == NULL) { + DBGLOG(INIT, WARN, + "prAdapter invalid!!\n"); + return; + } + prRegInfo = &prGlueInfo->rRegInfo; + if (prRegInfo == NULL) { + DBGLOG(INIT, WARN, + "prRegInfo invalid!!\n"); + return; + } + + if (prAdapter->fgTestMode == FALSE) { + DBGLOG(INIT, INFO, + "by-pass on Normal mode\n"); + return; + } + + nvrmState = wlanNvramGetState(); + + if (nvrmState == NVRAM_STATE_READY) { + DBGLOG(RFTEST, INFO, + "update nvram to fw on test mode!\n"); + + if (kalIsConfigurationExist(prGlueInfo) == TRUE) + wlanLoadManufactureData(prAdapter, prRegInfo); + else + DBGLOG(INIT, WARN, "%s: load manufacture data fail\n", + __func__); + } +} +static uint8_t wlanNvramBufHandler(void *ctx, + const char *buf, + uint16_t length) +{ + DBGLOG(INIT, INFO, "buf = %p, length = %u\n", buf, length); + if (buf == NULL || length <= 0) + return -EFAULT; + + if (length > sizeof(g_aucNvram)) { + DBGLOG(INIT, ERROR, "is over nvrm size %d\n", + sizeof(g_aucNvram)); + return -EINVAL; + } + + kalMemZero(&g_aucNvram, sizeof(g_aucNvram)); + if (copy_from_user(g_aucNvram, buf, length)) { + DBGLOG(INIT, ERROR, "copy nvram fail\n"); + g_NvramFsm = NVRAM_STATE_INIT; + return -EINVAL; + } + + g_NvramFsm = NVRAM_STATE_READY; + + /*do nvram update on test mode then driver sent new NVRAM to FW*/ + wlanNvramUpdateOnTestMode(); + + return 0; +} + +#endif + +static void wlanCreateWirelessDevice(void) +{ + struct wiphy *prWiphy = NULL; + struct wireless_dev *prWdev[KAL_AIS_NUM] = {NULL}; + unsigned int u4SupportSchedScanFlag = 0; + uint32_t u4Idx = 0; + + /* 4 <1.1> Create wireless_dev */ + for (u4Idx = 0; u4Idx < KAL_AIS_NUM; u4Idx++) { + prWdev[u4Idx] = kzalloc(sizeof(struct wireless_dev), + GFP_KERNEL); + if (!prWdev[u4Idx]) { + DBGLOG(INIT, ERROR, + "Allocating memory to wireless_dev context failed\n"); + return; + } + prWdev[u4Idx]->iftype = NL80211_IFTYPE_STATION; + } + /* 4 <1.2> Create wiphy */ +#if CFG_ENABLE_UNIFY_WIPHY + prWiphy = wiphy_new(&mtk_cfg_ops, sizeof(struct GLUE_INFO)); +#else + prWiphy = wiphy_new(&mtk_wlan_ops, + sizeof(struct GLUE_INFO)); +#endif + + if (!prWiphy) { + DBGLOG(INIT, ERROR, + "Allocating memory to wiphy device failed\n"); + goto free_wdev; + } + + /* 4 <1.3> configure wireless_dev & wiphy */ + prWiphy->iface_combinations = p_mtk_iface_combinations_sta; + prWiphy->n_iface_combinations = + mtk_iface_combinations_sta_num; + prWiphy->max_scan_ssids = SCN_SSID_MAX_NUM + + 1; /* include one wildcard ssid */ + prWiphy->max_scan_ie_len = 512; +#if CFG_SUPPORT_SCHED_SCAN + prWiphy->max_sched_scan_ssids = + CFG_SCAN_HIDDEN_SSID_MAX_NUM; + prWiphy->max_match_sets = + CFG_SCAN_SSID_MATCH_MAX_NUM; + prWiphy->max_sched_scan_ie_len = CFG_CFG80211_IE_BUF_LEN; +#if KERNEL_VERSION(4, 12, 0) <= CFG80211_VERSION_CODE + /* In kernel 4.12 or newer, + * this is obsoletes - WIPHY_FLAG_SUPPORTS_SCHED_SCAN + */ + prWiphy->max_sched_scan_reqs = 1; +#else + u4SupportSchedScanFlag = + WIPHY_FLAG_SUPPORTS_SCHED_SCAN; +#endif +#endif /* CFG_SUPPORT_SCHED_SCAN */ + prWiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_ADHOC); + prWiphy->bands[KAL_BAND_2GHZ] = &mtk_band_2ghz; + /* always assign 5Ghz bands here, if the chip is not support 5Ghz, + * bands[KAL_BAND_5GHZ] will be assign to NULL + */ + prWiphy->bands[KAL_BAND_5GHZ] = &mtk_band_5ghz; + prWiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; + prWiphy->cipher_suites = (const u32 *)mtk_cipher_suites; + prWiphy->n_cipher_suites = ARRAY_SIZE(mtk_cipher_suites); + prWiphy->flags = WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL + | u4SupportSchedScanFlag; + +#if (CFG_SUPPORT_ROAMING == 1) + prWiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM; +#endif /* CFG_SUPPORT_ROAMING */ + +#if KERNEL_VERSION(3, 14, 0) > CFG80211_VERSION_CODE + prWiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; +#else + prWiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; +#if (CFG_SUPPORT_DFS_MASTER == 1) + prWiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH; +#if KERNEL_VERSION(3, 16, 0) <= CFG80211_VERSION_CODE + prWiphy->max_num_csa_counters = 2; +#endif +#endif /* CFG_SUPPORT_DFS_MASTER */ +#endif + +#if KERNEL_VERSION(3, 14, 0) < CFG80211_VERSION_CODE + prWiphy->max_ap_assoc_sta = P2P_MAXIMUM_CLIENT_COUNT; +#endif + + cfg80211_regd_set_wiphy(prWiphy); + +#if (CFG_SUPPORT_TDLS == 1) + TDLSEX_WIPHY_FLAGS_INIT(prWiphy->flags); +#endif /* CFG_SUPPORT_TDLS */ + prWiphy->max_remain_on_channel_duration = 5000; + prWiphy->mgmt_stypes = mtk_cfg80211_ais_default_mgmt_stypes; + +#if (CFG_SUPPORT_SCAN_RANDOM_MAC && \ + (KERNEL_VERSION(3, 19, 0) <= CFG80211_VERSION_CODE)) + prWiphy->features |= NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR; + prWiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR; +#endif + +#if KERNEL_VERSION(4, 10, 0) < CFG80211_VERSION_CODE + wiphy_ext_feature_set(prWiphy, NL80211_EXT_FEATURE_LOW_SPAN_SCAN); +#endif + prWiphy->features |= NL80211_FEATURE_INACTIVITY_TIMER; + +#if CFG_SUPPORT_WPA3 + prWiphy->features |= NL80211_FEATURE_SAE; +#endif +#if KERNEL_VERSION(3, 18, 0) <= CFG80211_VERSION_CODE + prWiphy->vendor_commands = mtk_wlan_vendor_ops; + prWiphy->n_vendor_commands = sizeof(mtk_wlan_vendor_ops) / + sizeof(struct wiphy_vendor_command); + prWiphy->vendor_events = mtk_wlan_vendor_events; + prWiphy->n_vendor_events = ARRAY_SIZE( + mtk_wlan_vendor_events); +#endif + /* 4 <1.4> wowlan support */ +#ifdef CONFIG_PM +#if KERNEL_VERSION(3, 11, 0) <= CFG80211_VERSION_CODE + prWiphy->wowlan = &mtk_wlan_wowlan_support; +#else + kalMemCopy(&prWiphy->wowlan, &mtk_wlan_wowlan_support, + sizeof(struct wiphy_wowlan_support)); +#endif +#endif + +#ifdef CONFIG_CFG80211_WEXT + /* 4 <1.5> Use wireless extension to replace IOCTL */ + +#if CFG_ENABLE_UNIFY_WIPHY + prWiphy->wext = NULL; +#else + prWiphy->wext = &wext_handler_def; +#endif +#endif + /* initialize semaphore for halt control */ + sema_init(&g_halt_sem, 1); + +#if CFG_ENABLE_UNIFY_WIPHY + prWiphy->iface_combinations = p_mtk_iface_combinations_p2p; + prWiphy->n_iface_combinations = + mtk_iface_combinations_p2p_num; + + prWiphy->interface_modes |= BIT(NL80211_IFTYPE_AP) | + BIT(NL80211_IFTYPE_P2P_CLIENT) | + BIT(NL80211_IFTYPE_P2P_GO) | + BIT(NL80211_IFTYPE_STATION); + prWiphy->software_iftypes |= BIT(NL80211_IFTYPE_P2P_DEVICE); + prWiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; + prWiphy->flags |= WIPHY_FLAG_HAVE_AP_SME; + prWiphy->ap_sme_capa = 1; +#endif + +#if CFG_ENABLE_OFFCHANNEL_TX + prWiphy->flags |= WIPHY_FLAG_OFFCHAN_TX; +#endif /* CFG_ENABLE_OFFCHANNEL_TX */ + +#if CFG_SUPPORT_RM_BEACON_REPORT_BY_SUPPLICANT + /* Enable following to indicate supplicant + * to support Beacon report feature + */ + prWiphy->features |= NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES; + prWiphy->features |= NL80211_FEATURE_QUIET; +#endif + + if (wiphy_register(prWiphy) < 0) { + DBGLOG(INIT, ERROR, "wiphy_register error\n"); + goto free_wiphy; + } + for (u4Idx = 0; u4Idx < KAL_AIS_NUM; u4Idx++) { + prWdev[u4Idx]->wiphy = prWiphy; + gprWdev[u4Idx] = prWdev[u4Idx]; + } +#if CFG_WLAN_ASSISTANT_NVRAM + register_file_buf_handler(wlanNvramBufHandler, (void *)NULL, + ENUM_BUF_TYPE_NVRAM); +#endif + DBGLOG(INIT, INFO, "Create wireless device success\n"); + return; + +free_wiphy: + wiphy_free(prWiphy); +free_wdev: + for (u4Idx = 0; u4Idx < KAL_AIS_NUM; u4Idx++) + kfree(prWdev[u4Idx]); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Destroy all wdev (including the P2P device), and unregister wiphy + * + * \param (none) + * + * \return (none) + * + */ +/*----------------------------------------------------------------------------*/ +static void wlanDestroyAllWdev(void) +{ +#if CFG_ENABLE_UNIFY_WIPHY + /* There is only one wiphy, avoid that double free the wiphy */ + struct wiphy *wiphy = NULL; +#endif +#if CFG_ENABLE_WIFI_DIRECT + int i = 0; +#endif + +#if CFG_ENABLE_WIFI_DIRECT + /* free P2P wdev */ + for (i = 0; i < KAL_P2P_NUM; i++) { + if (gprP2pRoleWdev[i] == NULL) + continue; +#if CFG_ENABLE_UNIFY_WIPHY + if (wlanIsAisDev(gprP2pRoleWdev[i]->netdev)) { + /* This is AIS/AP Interface */ + gprP2pRoleWdev[i] = NULL; + continue; + } +#endif + /* Do wiphy_unregister here. Take care the case that the + * gprP2pRoleWdev[i] is created by the cfg80211 add iface ops, + * And the base P2P dev is in the gprP2pWdev. + * Expect that new created gprP2pRoleWdev[i] is freed in + * unregister_netdev/mtk_vif_destructor. And gprP2pRoleWdev[i] + * is reset as gprP2pWdev in mtk_vif_destructor. + */ + if (gprP2pRoleWdev[i] == gprP2pWdev) + gprP2pWdev = NULL; + +#if CFG_ENABLE_UNIFY_WIPHY + wiphy = gprP2pRoleWdev[i]->wiphy; +#else + set_wiphy_dev(gprP2pRoleWdev[i]->wiphy, NULL); + wiphy_unregister(gprP2pRoleWdev[i]->wiphy); + wiphy_free(gprP2pRoleWdev[i]->wiphy); +#endif + + kfree(gprP2pRoleWdev[i]); + gprP2pRoleWdev[i] = NULL; + } + + if (gprP2pWdev != NULL) { + /* This case is that gprP2pWdev isn't equal to gprP2pRoleWdev[0] + * . The gprP2pRoleWdev[0] is created in the p2p cfg80211 add + * iface ops. The two wdev use the same wiphy. Don't double + * free the same wiphy. + * This part isn't expect occur. Because p2pNetUnregister should + * unregister_netdev the new created wdev, and gprP2pRoleWdev[0] + * is reset as gprP2pWdev. + */ +#if CFG_ENABLE_UNIFY_WIPHY + wiphy = gprP2pWdev->wiphy; +#endif + + kfree(gprP2pWdev); + gprP2pWdev = NULL; + } +#endif /* CFG_ENABLE_WIFI_DIRECT */ + + /* free AIS wdev */ + if (gprWdev[0]) { +#if CFG_ENABLE_UNIFY_WIPHY + wiphy = wlanGetWiphy(); +#else + /* trunk doesn't do set_wiphy_dev, but trunk-ce1 does. */ + /* set_wiphy_dev(gprWdev->wiphy, NULL); */ + wiphy_unregister(gprWdev[0]->wiphy); + wiphy_free(gprWdev[0]->wiphy); +#endif + + for (i = 0; i < KAL_AIS_NUM; i++) { + kfree(gprWdev[i]); + gprWdev[i] = NULL; + } + } + +#if CFG_ENABLE_UNIFY_WIPHY + /* unregister & free wiphy */ + if (wiphy) { + /* set_wiphy_dev(wiphy, NULL): set the wiphy->dev->parent = NULL + * The trunk-ce1 does this, but the trunk seems not. + */ + /* set_wiphy_dev(wiphy, NULL); */ + wiphy_unregister(wiphy); + wiphy_free(wiphy); + } +#endif +} + +void wlanWakeLockInit(struct GLUE_INFO *prGlueInfo) +{ +#ifdef CONFIG_ANDROID + KAL_WAKE_LOCK_INIT(NULL, prGlueInfo->rIntrWakeLock, + "WLAN interrupt"); + KAL_WAKE_LOCK_INIT(NULL, prGlueInfo->rTimeoutWakeLock, + "WLAN timeout"); +#endif +} + +void wlanWakeLockUninit(struct GLUE_INFO *prGlueInfo) +{ +#if defined(CONFIG_ANDROID) && (CFG_ENABLE_WAKE_LOCK) + if (KAL_WAKE_LOCK_ACTIVE(NULL, prGlueInfo->rIntrWakeLock)) + KAL_WAKE_UNLOCK(NULL, prGlueInfo->rIntrWakeLock); + KAL_WAKE_LOCK_DESTROY(NULL, prGlueInfo->rIntrWakeLock); + + if (KAL_WAKE_LOCK_ACTIVE(NULL, + prGlueInfo->rTimeoutWakeLock)) + KAL_WAKE_UNLOCK(NULL, prGlueInfo->rTimeoutWakeLock); + KAL_WAKE_LOCK_DESTROY(NULL, prGlueInfo->rTimeoutWakeLock); +#endif +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief A method for creating Linux NET4 struct net_device object and the + * private data(prGlueInfo and prAdapter). Setup the IO address to the + * HIF. + * Assign the function pointer to the net_device object + * + * \param[in] pvData Memory address for the device + * + * \retval Not null The wireless_dev object. + * \retval NULL Fail to create wireless_dev object + */ +/*----------------------------------------------------------------------------*/ +static struct lock_class_key rSpinKey[SPIN_LOCK_NUM]; +struct wireless_dev *wlanNetCreate(void *pvData, + void *pvDriverData) +{ + struct wireless_dev *prWdev = gprWdev[0]; + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + uint32_t i; + struct device *prDev; + struct NETDEV_PRIVATE_GLUE_INFO *prNetDevPrivate = + (struct NETDEV_PRIVATE_GLUE_INFO *) NULL; + struct mt66xx_chip_info *prChipInfo; +#if CFG_ENABLE_UNIFY_WIPHY + struct wiphy *prWiphy = NULL; +#endif + + uint8_t *prInfName = NULL; + + if (prWdev == NULL) { + DBGLOG(INIT, ERROR, + "No wireless dev exist, abort power on\n"); + return NULL; + } + +#if CFG_ENABLE_UNIFY_WIPHY + /* The gprWdev is created at initWlan() and isn't reset when the + * disconnection occur. That cause some issue. + */ + prWiphy = prWdev->wiphy; + for (i = 0; i < KAL_AIS_NUM; i++) { + if (gprWdev[i] +#if CFG_SUPPORT_PERSIST_NETDEV + && !gprNetdev[i] +#endif + ) { + memset(gprWdev[i], 0, sizeof(struct wireless_dev)); + gprWdev[i]->wiphy = prWiphy; + gprWdev[i]->iftype = NL80211_IFTYPE_STATION; + } + } + +#if (CFG_SUPPORT_SINGLE_SKU == 1) + /* XXX: ref from cfg80211_regd_set_wiphy(). + * The error case: Sometimes after unplug/plug usb, the wlan0 STA can't + * scan correctly (FW doesn't do scan). The usb_probe message: + * "mtk_reg_notify:(RLM ERROR) Invalid REG state happened. state = 0x6". + */ + if (rlmDomainGetCtrlState() == REGD_STATE_INVALID) + rlmDomainResetCtrlInfo(TRUE); +#endif +#endif /* CFG_ENABLE_UNIFY_WIPHY */ + + /* 4 <1.3> co-relate wiphy & prDev */ + glGetDev(pvData, &prDev); + if (!prDev) + DBGLOG(INIT, ERROR, "unable to get struct dev for wlan\n"); + /* Some kernel API (ex: cfg80211_get_drvinfo) will use wiphy_dev(). + * Without set_wiphy_dev(prWdev->wiphy, prDev), those API will crash. + */ + set_wiphy_dev(prWdev->wiphy, prDev); + + /* 4 <2> Create Glue structure */ + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(prWdev->wiphy); + kalMemZero(prGlueInfo, sizeof(struct GLUE_INFO)); + + /* 4 <2.1> Create Adapter structure */ + prAdapter = (struct ADAPTER *) wlanAdapterCreate( + prGlueInfo); + + if (!prAdapter) { + DBGLOG(INIT, ERROR, + "Allocating memory to adapter failed\n"); + glClearHifInfo(prGlueInfo); + return NULL; + } + + prChipInfo = ((struct mt66xx_hif_driver_data *) + pvDriverData)->chip_info; + prAdapter->chip_info = prChipInfo; + prGlueInfo->prAdapter = prAdapter; + + /* 4 <3> Initialize Glue structure */ + /* 4 <3.1> Create net device */ + +#ifdef CFG_DRIVER_INF_NAME_CHANGE + + if (kalStrLen(gprifnamesta) > 0) { + prInfName = kalStrCat(gprifnamesta, "%d"); + DBGLOG(INIT, WARN, "Station ifname customized, use %s\n", + prInfName); + } else +#endif /* CFG_DRIVER_INF_NAME_CHANGE */ + prInfName = NIC_INF_NAME; + + for (i = 0; i < KAL_AIS_NUM; i++) { + struct net_device *prDevHandler; + +#if CFG_SUPPORT_PERSIST_NETDEV + if (!gprNetdev[i]) { + prDevHandler = alloc_netdev_mq( + sizeof(struct NETDEV_PRIVATE_GLUE_INFO), + prInfName, +#if KERNEL_VERSION(3, 18, 0) <= CFG80211_VERSION_CODE + NET_NAME_PREDICTABLE, +#endif + ether_setup, + CFG_MAX_TXQ_NUM); + gprNetdev[i] = prDevHandler; + } else + prDevHandler = gprNetdev[i]; +#else + prDevHandler = alloc_netdev_mq( + sizeof(struct NETDEV_PRIVATE_GLUE_INFO), + prInfName, +#if KERNEL_VERSION(3, 18, 0) <= CFG80211_VERSION_CODE + NET_NAME_PREDICTABLE, +#endif + ether_setup, + CFG_MAX_TXQ_NUM); +#endif /* end of CFG_SUPPORT_PERSIST_NETDEV */ + + if (!prDevHandler) { + DBGLOG(INIT, ERROR, + "Allocating memory to net_device context failed\n"); + goto netcreate_err; + } + + /* Device can help us to save at most 3000 packets, + * after we stopped queue + */ + prDevHandler->tx_queue_len = 3000; + DBGLOG(INIT, INFO, "net_device prDev(0x%p) allocated\n", + prDevHandler); + + /* 4 <3.1.1> Initialize net device varaiables */ + prNetDevPrivate = (struct NETDEV_PRIVATE_GLUE_INFO *) + netdev_priv(prDevHandler); + prNetDevPrivate->prGlueInfo = prGlueInfo; + + prDevHandler->needed_headroom = + NIC_TX_DESC_AND_PADDING_LENGTH + + prChipInfo->txd_append_size; + prDevHandler->netdev_ops = &wlan_netdev_ops; +#ifdef CONFIG_WIRELESS_EXT + prDevHandler->wireless_handlers = + &wext_handler_def; +#endif + netif_carrier_off(prDevHandler); + netif_tx_stop_all_queues(prDevHandler); + kalResetStats(prDevHandler); + + /* 4 <3.1.2> co-relate with wiphy bi-directionally */ + prDevHandler->ieee80211_ptr = gprWdev[i]; + + gprWdev[i]->netdev = prDevHandler; + + /* 4 <3.1.3> co-relate net device & prDev */ + SET_NETDEV_DEV(prDevHandler, + wiphy_dev(prWdev->wiphy)); + + /* 4 <3.1.4> set device to glue */ + prGlueInfo->prDev = prDev; + + /* 4 <3.2> Initialize glue variables */ + kalSetMediaStateIndicated(prGlueInfo, + MEDIA_STATE_DISCONNECTED, + i); + } + + prGlueInfo->prDevHandler = gprWdev[0]->netdev; + +#if CFG_SUPPORT_SNIFFER + INIT_WORK(&(prGlueInfo->monWork), wlanMonWorkHandler); +#endif + + prGlueInfo->ePowerState = ParamDeviceStateD0; +#if !CFG_SUPPORT_PERSIST_NETDEV + prGlueInfo->fgIsRegistered = FALSE; +#endif + prGlueInfo->prScanRequest = NULL; + prGlueInfo->prSchedScanRequest = NULL; + + +#if CFG_SUPPORT_PASSPOINT + /* Init DAD */ + prGlueInfo->fgIsDad = FALSE; + prGlueInfo->fgIs6Dad = FALSE; + kalMemZero(prGlueInfo->aucDADipv4, 4); + kalMemZero(prGlueInfo->aucDADipv6, 16); +#endif /* CFG_SUPPORT_PASSPOINT */ + + init_completion(&prGlueInfo->rScanComp); + init_completion(&prGlueInfo->rHaltComp); + init_completion(&prGlueInfo->rPendComp); + +#if CFG_SUPPORT_MULTITHREAD + init_completion(&prGlueInfo->rHifHaltComp); + init_completion(&prGlueInfo->rRxHaltComp); +#endif + +#if CFG_SUPPORT_NCHO + init_completion(&prGlueInfo->rAisChGrntComp); +#endif + + /* initialize timer for OID timeout checker */ + kalOsTimerInitialize(prGlueInfo, kalTimeoutHandler); + + for (i = 0; i < SPIN_LOCK_NUM; i++) { + spin_lock_init(&prGlueInfo->rSpinLock[i]); + lockdep_set_class(&prGlueInfo->rSpinLock[i], &rSpinKey[i]); + } + + for (i = 0; i < MUTEX_NUM; i++) + mutex_init(&prGlueInfo->arMutex[i]); + + /* initialize semaphore for ioctl */ + sema_init(&prGlueInfo->ioctl_sem, 1); + +#if CFG_SUPPORT_SDIO_READ_WRITE_PATTERN + /* initialize SDIO read-write pattern control */ + prGlueInfo->fgEnSdioTestPattern = FALSE; + prGlueInfo->fgIsSdioTestInitialized = FALSE; +#endif + + /* 4 <8> Init Queues */ + init_waitqueue_head(&prGlueInfo->waitq); + QUEUE_INITIALIZE(&prGlueInfo->rCmdQueue); + prGlueInfo->i4TxPendingCmdNum = 0; + QUEUE_INITIALIZE(&prGlueInfo->rTxQueue); + glSetHifInfo(prGlueInfo, (unsigned long) pvData); + + /* Init wakelock */ + wlanWakeLockInit(prGlueInfo); + + /* main thread is created in this function */ +#if CFG_SUPPORT_MULTITHREAD + init_waitqueue_head(&prGlueInfo->waitq_rx); + init_waitqueue_head(&prGlueInfo->waitq_hif); + + prGlueInfo->u4TxThreadPid = 0xffffffff; + prGlueInfo->u4RxThreadPid = 0xffffffff; + prGlueInfo->u4HifThreadPid = 0xffffffff; +#endif + + return prWdev; + +netcreate_err: + if (prAdapter != NULL) { + wlanAdapterDestroy(prAdapter); + prAdapter = NULL; + } + prGlueInfo->prDevHandler = NULL; + + return prWdev; +} /* end of wlanNetCreate() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Destroying the struct net_device object and the private data. + * + * \param[in] prWdev Pointer to struct wireless_dev. + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void wlanNetDestroy(struct wireless_dev *prWdev) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + ASSERT(prWdev); + + if (!prWdev) { + DBGLOG(INIT, ERROR, "The device context is NULL\n"); + return; + } + + /* prGlueInfo is allocated with net_device */ + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(prWdev->wiphy); + ASSERT(prGlueInfo); + + /* prWdev: base AIS dev + * Because the interface dev (ex: usb_device) would be free + * after un-plug event. Should set the wiphy->dev->parent which + * pointer to the interface dev to NULL. Otherwise, the corresponding + * system operation (poweroff, suspend) might reference it. + * set_wiphy_dev(wiphy, NULL): set the wiphy->dev->parent = NULL + * The set_wiphy_dev(prWdev->wiphy, prDev) is done in wlanNetCreate. + * But that is after wiphy_register, and will cause exception in + * wiphy_unregister(), if do not set_wiphy_dev(wiphy, NULL). + */ + set_wiphy_dev(prWdev->wiphy, NULL); + + /* destroy kal OS timer */ + kalCancelTimer(prGlueInfo); + + glClearHifInfo(prGlueInfo); + + wlanAdapterDestroy(prGlueInfo->prAdapter); + prGlueInfo->prAdapter = NULL; + + /* Free net_device and private data, which are allocated by + * alloc_netdev(). + */ +#if CFG_SUPPORT_PERSIST_NETDEV +#ifdef CONFIG_WIRELESS_EXT + { + uint32_t u4Idx = 0; + + for (u4Idx = 0; u4Idx < KAL_AIS_NUM; u4Idx++) { + if (gprWdev[u4Idx] && gprWdev[u4Idx]->netdev) { + rtnl_lock(); + gprWdev[u4Idx]->netdev->wireless_handlers = + NULL; + rtnl_unlock(); + } + } + } +#endif +#else + wlanFreeNetDev(); +#endif + /* gPrDev is assigned by prGlueInfo->prDevHandler, + * set NULL to this global variable. + */ + gPrDev = NULL; + +} /* end of wlanNetDestroy() */ + +void wlanSetSuspendMode(struct GLUE_INFO *prGlueInfo, + u_int8_t fgEnable) +{ + struct net_device *prDev = NULL; + uint32_t u4PacketFilter = 0; + uint32_t u4SetInfoLen = 0; + uint32_t u4Idx = 0; + + if (!prGlueInfo) + return; + + + for (u4Idx = 0; u4Idx < KAL_AIS_NUM; u4Idx++) { + prDev = wlanGetNetDev(prGlueInfo, u4Idx); + if (!prDev) + continue; + + /* new filter should not include p2p mask */ +#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 + u4PacketFilter = + prGlueInfo->prAdapter->u4OsPacketFilter & + (~PARAM_PACKET_FILTER_P2P_MASK); +#endif + if (kalIoctl(prGlueInfo, + wlanoidSetCurrentPacketFilter, + &u4PacketFilter, + sizeof(u4PacketFilter), FALSE, FALSE, TRUE, + &u4SetInfoLen) != WLAN_STATUS_SUCCESS) + DBGLOG(INIT, ERROR, "set packet filter failed.\n"); + +#if !CFG_SUPPORT_DROP_ALL_MC_PACKET + if (fgEnable) { + /* Prepare IPv6 RA packet when suspend */ + uint8_t MC_address[ETH_ALEN] = {0x33, 0x33, 0, 0, 0, 1}; + + kalIoctl(prGlueInfo, + wlanoidSetMulticastList, MC_address, ETH_ALEN, + FALSE, FALSE, TRUE, &u4SetInfoLen); + } else if (u4PacketFilter & PARAM_PACKET_FILTER_MULTICAST) { + /* Prepare multicast address list when resume */ + struct netdev_hw_addr *ha; + uint8_t *prMCAddrList = NULL; + uint32_t i = 0; + + down(&g_halt_sem); + if (g_u4HaltFlag) { + up(&g_halt_sem); + return; + } + + prMCAddrList = kalMemAlloc( + MAX_NUM_GROUP_ADDR * ETH_ALEN, VIR_MEM_TYPE); + if (!prMCAddrList) { + DBGLOG(INIT, WARN, + "prMCAddrList memory alloc fail!\n"); + up(&g_halt_sem); + continue; + } + + /* Avoid race condition with kernel net subsystem */ + netif_addr_lock_bh(prDev); + + netdev_for_each_mc_addr(ha, prDev) { + if (i < MAX_NUM_GROUP_ADDR) { + kalMemCopy( + (prMCAddrList + i * ETH_ALEN), + ha->addr, ETH_ALEN); + i++; + } + } + + netif_addr_unlock_bh(prDev); + + up(&g_halt_sem); + + kalIoctl(prGlueInfo, wlanoidSetMulticastList, + prMCAddrList, (i * ETH_ALEN), FALSE, FALSE, + TRUE, &u4SetInfoLen); + + kalMemFree(prMCAddrList, VIR_MEM_TYPE, + MAX_NUM_GROUP_ADDR * ETH_ALEN); + } +#endif + kalSetNetAddressFromInterface(prGlueInfo, prDev, fgEnable); + wlanNotifyFwSuspend(prGlueInfo, prDev, fgEnable); + } +} + +#if CFG_ENABLE_EARLY_SUSPEND +static struct early_suspend wlan_early_suspend_desc = { + .level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN, +}; + +static void wlan_early_suspend(struct early_suspend *h) +{ + struct net_device *prDev = NULL; + struct GLUE_INFO *prGlueInfo = NULL; + + /* 4 <1> Sanity Check */ + if ((u4WlanDevNum == 0) + && (u4WlanDevNum > CFG_MAX_WLAN_DEVICES)) { + DBGLOG(INIT, ERROR, + "wlanLateResume u4WlanDevNum==0 invalid!!\n"); + return; + } + + prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev; + if (!prDev) + return; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prDev)); + if (!prGlueInfo) + return; + + DBGLOG(INIT, INFO, "********<%s>********\n", __func__); + + if (prGlueInfo->fgIsInSuspendMode == TRUE) { + DBGLOG(INIT, INFO, "%s: Already in suspend mode, SKIP!\n", + __func__); + return; + } + + prGlueInfo->fgIsInSuspendMode = TRUE; + + wlanSetSuspendMode(prGlueInfo, TRUE); + p2pSetSuspendMode(prGlueInfo, TRUE); +} + +static void wlan_late_resume(struct early_suspend *h) +{ + struct net_device *prDev = NULL; + struct GLUE_INFO *prGlueInfo = NULL; + + /* 4 <1> Sanity Check */ + if ((u4WlanDevNum == 0) + && (u4WlanDevNum > CFG_MAX_WLAN_DEVICES)) { + DBGLOG(INIT, ERROR, + "wlanLateResume u4WlanDevNum==0 invalid!!\n"); + return; + } + + prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev; + if (!prDev) + return; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prDev)); + if (!prGlueInfo) + return; + + DBGLOG(INIT, INFO, "********<%s>********\n", __func__); + + if (prGlueInfo->fgIsInSuspendMode == FALSE) { + DBGLOG(INIT, INFO, "%s: Not in suspend mode, SKIP!\n", + __func__); + return; + } + + prGlueInfo->fgIsInSuspendMode = FALSE; + + /* 4 <2> Set suspend mode for each network */ + wlanSetSuspendMode(prGlueInfo, FALSE); + p2pSetSuspendMode(prGlueInfo, FALSE); +} +#endif + +#if (CFG_MTK_ANDROID_WMT || WLAN_INCLUDE_PROC) + +void reset_p2p_mode(struct GLUE_INFO *prGlueInfo) +{ + struct PARAM_CUSTOM_P2P_SET_STRUCT rSetP2P; + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + + if (!prGlueInfo) + return; + + rSetP2P.u4Enable = 0; + rSetP2P.u4Mode = 0; + + p2pNetUnregister(prGlueInfo, FALSE); + + rWlanStatus = kalIoctl(prGlueInfo, wlanoidSetP2pMode, + (void *) &rSetP2P, + sizeof(struct PARAM_CUSTOM_P2P_SET_STRUCT), + FALSE, FALSE, TRUE, &u4BufLen); + + if (rWlanStatus != WLAN_STATUS_SUCCESS) + prGlueInfo->prAdapter->fgIsP2PRegistered = FALSE; + + DBGLOG(INIT, INFO, + "ret = 0x%08x\n", (uint32_t) rWlanStatus); +} + +int set_p2p_mode_handler(struct net_device *netdev, + struct PARAM_CUSTOM_P2P_SET_STRUCT p2pmode) +{ + struct GLUE_INFO *prGlueInfo = *((struct GLUE_INFO **) + netdev_priv(netdev)); + struct PARAM_CUSTOM_P2P_SET_STRUCT rSetP2P; + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + + if (!prGlueInfo) + return -1; + +#if (CFG_MTK_ANDROID_WMT) + if (prGlueInfo->u4ReadyFlag == 0) { + DBGLOG(INIT, ERROR, "adapter is not ready\n"); + return -1; + } +#endif /*CFG_MTK_ANDROID_WMT*/ + + /* Remember original ifindex for reset case */ + if (kalIsResetting()) { + struct GL_P2P_INFO *prP2PInfo = NULL; + int i = 0; + + for (i = 0 ; i < KAL_P2P_NUM; i++) { + prP2PInfo = prGlueInfo->prP2PInfo[i]; + + if (!prP2PInfo || !prP2PInfo->prDevHandler) + continue; + + /* Only restore sap part */ + if (prP2PInfo->prWdev->iftype != NL80211_IFTYPE_AP) + continue; + + g_u4DevIdx[i] = + prP2PInfo->prDevHandler->ifindex; + } + } + + /* Resetting p2p mode if registered to avoid launch KE */ + if (p2pmode.u4Enable + && prGlueInfo->prAdapter->fgIsP2PRegistered + && !kalIsResetting()) { + DBGLOG(INIT, WARN, "Resetting p2p mode\n"); + reset_p2p_mode(prGlueInfo); + } + + rSetP2P.u4Enable = p2pmode.u4Enable; + rSetP2P.u4Mode = p2pmode.u4Mode; + + if ((!rSetP2P.u4Enable) && (kalIsResetting() == FALSE)) + p2pNetUnregister(prGlueInfo, FALSE); + + rWlanStatus = kalIoctl(prGlueInfo, wlanoidSetP2pMode, + (void *) &rSetP2P, + sizeof(struct PARAM_CUSTOM_P2P_SET_STRUCT), + FALSE, FALSE, TRUE, &u4BufLen); + + DBGLOG(INIT, INFO, + "ret = 0x%08x, p2p reg = %d, resetting = %d\n", + (uint32_t) rWlanStatus, + prGlueInfo->prAdapter->fgIsP2PRegistered, + kalIsResetting()); + + + /* Need to check fgIsP2PRegistered, in case of whole chip reset. + * in this case, kalIOCTL return success always, + * and prGlueInfo->prP2PInfo[0] may be NULL + */ + if ((rSetP2P.u4Enable) + && (prGlueInfo->prAdapter->fgIsP2PRegistered) + && (kalIsResetting() == FALSE)) + p2pNetRegister(prGlueInfo, FALSE); + + return 0; +} + +#endif + +#if CFG_SUPPORT_EASY_DEBUG +/*----------------------------------------------------------------------------*/ +/*! + * \brief parse config from wifi.cfg + * + * \param[in] prAdapter + * + * \retval VOID + */ +/*----------------------------------------------------------------------------*/ +void wlanGetParseConfig(struct ADAPTER *prAdapter) +{ + uint8_t *pucConfigBuf; + uint32_t u4ConfigReadLen; + + wlanCfgInit(prAdapter, NULL, 0, 0); + pucConfigBuf = (uint8_t *) kalMemAlloc( + WLAN_CFG_FILE_BUF_SIZE, VIR_MEM_TYPE); + kalMemZero(pucConfigBuf, WLAN_CFG_FILE_BUF_SIZE); + u4ConfigReadLen = 0; + if (pucConfigBuf) { + if (kalRequestFirmware("wifi.cfg", pucConfigBuf, + WLAN_CFG_FILE_BUF_SIZE, &u4ConfigReadLen, + prAdapter->prGlueInfo->prDev) == 0) { + /* ToDo:: Nothing */ + } else if (kalReadToFile("/data/misc/wifi.cfg", + pucConfigBuf, WLAN_CFG_FILE_BUF_SIZE, + &u4ConfigReadLen) == 0) { + /* ToDo:: Nothing */ + } else if (kalReadToFile("/data/misc/wifi/wifi.cfg", + pucConfigBuf, WLAN_CFG_FILE_BUF_SIZE, + &u4ConfigReadLen) == 0) { + /* ToDo:: Nothing */ + } else if (kalReadToFile("/storage/sdcard0/wifi.cfg", + pucConfigBuf, WLAN_CFG_FILE_BUF_SIZE, + &u4ConfigReadLen) == 0) { + /* ToDo:: Nothing */ + } + + if (pucConfigBuf[0] != '\0' && u4ConfigReadLen > 0) + wlanCfgParse(prAdapter, pucConfigBuf, u4ConfigReadLen, + TRUE); + + kalMemFree(pucConfigBuf, VIR_MEM_TYPE, + WLAN_CFG_FILE_BUF_SIZE); + } /* pucConfigBuf */ +} + + +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief get config from wifi.cfg + * + * \param[in] prAdapter + * + * \retval VOID + */ +/*----------------------------------------------------------------------------*/ +void wlanGetConfig(struct ADAPTER *prAdapter) +{ + uint8_t *pucConfigBuf; + uint32_t u4ConfigReadLen; + + wlanCfgInit(prAdapter, NULL, 0, 0); + pucConfigBuf = (uint8_t *) kalMemAlloc( + WLAN_CFG_FILE_BUF_SIZE, VIR_MEM_TYPE); + kalMemZero(pucConfigBuf, WLAN_CFG_FILE_BUF_SIZE); + u4ConfigReadLen = 0; + if (pucConfigBuf) { + if (kalRequestFirmware("wifi.cfg", pucConfigBuf, + WLAN_CFG_FILE_BUF_SIZE, &u4ConfigReadLen, + prAdapter->prGlueInfo->prDev) == 0) { + /* ToDo:: Nothing */ + } else if (kalReadToFile("/data/misc/wifi/wifi.cfg", + pucConfigBuf, WLAN_CFG_FILE_BUF_SIZE, + &u4ConfigReadLen) == 0) { + /* ToDo:: Nothing */ + } else if (kalReadToFile("/storage/sdcard0/wifi.cfg", + pucConfigBuf, WLAN_CFG_FILE_BUF_SIZE, + &u4ConfigReadLen) == 0) { + /* ToDo:: Nothing */ + } + + if (pucConfigBuf[0] != '\0' && u4ConfigReadLen > 0) + wlanCfgInit(prAdapter, + pucConfigBuf, u4ConfigReadLen, 0); + + kalMemFree(pucConfigBuf, VIR_MEM_TYPE, + WLAN_CFG_FILE_BUF_SIZE); + } /* pucConfigBuf */ +} + + +/*----------------------------------------------------------------------------*/ +/*! + * \brief this function send buffer bin EEPROB_MTxxxx.bin to FW. + * + * \param[in] prAdapter + * + * \retval WLAN_STATUS_SUCCESS Success + * \retval WLAN_STATUS_FAILURE Failed + */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanDownloadBufferBin(struct ADAPTER *prAdapter) +{ + struct GLUE_INFO *prGlueInfo = NULL; +#if (CFG_FW_Report_Efuse_Address) + uint16_t u2InitAddr = prAdapter->u4EfuseStartAddress; +#else + uint16_t u2InitAddr = EFUSE_CONTENT_BUFFER_START; +#endif + uint32_t u4BufLen = 0; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + struct PARAM_CUSTOM_EFUSE_BUFFER_MODE *prSetEfuseBufModeInfo + = NULL; + uint32_t u4ContentLen; + uint8_t *pucConfigBuf = NULL; + struct mt66xx_chip_info *prChipInfo; + uint32_t chip_id; + uint8_t aucEeprom[32]; + uint32_t retWlanStat = WLAN_STATUS_FAILURE; + + if (prAdapter->fgIsSupportPowerOnSendBufferModeCMD == + TRUE) { + DBGLOG(INIT, INFO, "Start Efuse Buffer Mode ..\n"); + DBGLOG(INIT, INFO, "ucEfuseBUfferModeCal is %x\n", + prAdapter->rWifiVar.ucEfuseBufferModeCal); + + prChipInfo = prAdapter->chip_info; + chip_id = prChipInfo->chip_id; + prGlueInfo = prAdapter->prGlueInfo; + + if (prGlueInfo == NULL || prGlueInfo->prDev == NULL) + goto label_exit; + + /* allocate memory for buffer mode info */ + prSetEfuseBufModeInfo = + (struct PARAM_CUSTOM_EFUSE_BUFFER_MODE *) + kalMemAlloc(sizeof( + struct PARAM_CUSTOM_EFUSE_BUFFER_MODE), + VIR_MEM_TYPE); + if (prSetEfuseBufModeInfo == NULL) + goto label_exit; + kalMemZero(prSetEfuseBufModeInfo, + sizeof(struct PARAM_CUSTOM_EFUSE_BUFFER_MODE)); + + if (prAdapter->rWifiVar.ucEfuseBufferModeCal == TRUE) { + int ret = 0; + + /* Buffer mode */ + /* Only in buffer mode need to access bin file */ + /* 1 <1> Load bin file*/ + pucConfigBuf = (uint8_t *) kalMemAlloc( + MAX_EEPROM_BUFFER_SIZE, VIR_MEM_TYPE); + if (pucConfigBuf == NULL) + goto label_exit; + + kalMemZero(pucConfigBuf, MAX_EEPROM_BUFFER_SIZE); + + /* 1 <2> Construct EEPROM binary name */ + kalMemZero(aucEeprom, sizeof(aucEeprom)); + + ret = kalSnprintf(aucEeprom, 32, "%s%x.bin", + apucEepromName[0], chip_id); + if (ret < 0 || ret >= 32) { + DBGLOG(INIT, ERROR, + "[%u] kalSnprintf failed, ret: %d\n", + __LINE__, ret); + goto label_exit; + } + + /* 1 <3> Request buffer bin */ + if (kalRequestFirmware(aucEeprom, pucConfigBuf, + MAX_EEPROM_BUFFER_SIZE, &u4ContentLen, + prGlueInfo->prDev) == 0) { + DBGLOG(INIT, INFO, "request file done\n"); + } else { + DBGLOG(INIT, INFO, "can't find file\n"); + goto label_exit; + } + + /* 1 <4> Send CMD with bin file content */ + prGlueInfo = prAdapter->prGlueInfo; + + /* Update contents in local table */ + kalMemCopy(uacEEPROMImage, pucConfigBuf, + MAX_EEPROM_BUFFER_SIZE); + + /* copy to the command buffer */ +#if (CFG_FW_Report_Efuse_Address) + u4ContentLen = (prAdapter->u4EfuseEndAddress) - + (prAdapter->u4EfuseStartAddress) + 1; +#else + u4ContentLen = EFUSE_CONTENT_BUFFER_SIZE; +#endif + if (u4ContentLen > MAX_EEPROM_BUFFER_SIZE) + goto label_exit; + kalMemCopy(prSetEfuseBufModeInfo->aBinContent, + &pucConfigBuf[u2InitAddr], u4ContentLen); + + prSetEfuseBufModeInfo->ucSourceMode = 1; + } else { + /* eFuse mode */ + /* Only need to tell FW the content from, contents are + * directly from efuse + */ + prSetEfuseBufModeInfo->ucSourceMode = 0; + } + prSetEfuseBufModeInfo->ucCmdType = 0x1 | + (prAdapter->rWifiVar.ucCalTimingCtrl << 4); + prSetEfuseBufModeInfo->ucCount = + 0xFF; /* ucCmdType 1 don't care the ucCount */ + + rStatus = kalIoctl(prGlueInfo, wlanoidSetEfusBufferMode, + (void *)prSetEfuseBufModeInfo, + sizeof(struct PARAM_CUSTOM_EFUSE_BUFFER_MODE), + FALSE, TRUE, TRUE, &u4BufLen); + } + + retWlanStat = WLAN_STATUS_SUCCESS; + +label_exit: + + /* free memory */ + if (prSetEfuseBufModeInfo != NULL) + kalMemFree(prSetEfuseBufModeInfo, VIR_MEM_TYPE, + sizeof(struct PARAM_CUSTOM_EFUSE_BUFFER_MODE)); + + if (pucConfigBuf != NULL) + kalMemFree(pucConfigBuf, VIR_MEM_TYPE, + MAX_EEPROM_BUFFER_SIZE); + + return retWlanStat; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief this function send buffer bin EEPROB_MTxxxx.bin to FW. + * + * \param[in] prAdapter + * + * \retval WLAN_STATUS_SUCCESS Success + * \retval WLAN_STATUS_FAILURE Failed + */ +/*----------------------------------------------------------------------------*/ +uint32_t wlanConnacDownloadBufferBin(struct ADAPTER + *prAdapter) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t u4BufLen = 0; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + struct PARAM_CUSTOM_EFUSE_BUFFER_MODE_CONNAC_T + *prSetEfuseBufModeInfo = NULL; + uint32_t u4ContentLen; + uint8_t *pucConfigBuf = NULL; + struct mt66xx_chip_info *prChipInfo; + uint32_t chip_id; + uint8_t aucEeprom[32]; + uint32_t retWlanStat = WLAN_STATUS_FAILURE; + + if (prAdapter->fgIsSupportPowerOnSendBufferModeCMD == FALSE) + return WLAN_STATUS_SUCCESS; + + DBGLOG(INIT, INFO, "Start Efuse Buffer Mode ..\n"); + DBGLOG(INIT, INFO, "ucEfuseBUfferModeCal is %x\n", + prAdapter->rWifiVar.ucEfuseBufferModeCal); + + prChipInfo = prAdapter->chip_info; + chip_id = prChipInfo->chip_id; + prGlueInfo = prAdapter->prGlueInfo; + + if (prGlueInfo == NULL || prGlueInfo->prDev == NULL) + goto label_exit; + + /* allocate memory for buffer mode info */ + prSetEfuseBufModeInfo = + (struct PARAM_CUSTOM_EFUSE_BUFFER_MODE_CONNAC_T *) + kalMemAlloc(sizeof( + struct PARAM_CUSTOM_EFUSE_BUFFER_MODE_CONNAC_T), + VIR_MEM_TYPE); + if (prSetEfuseBufModeInfo == NULL) + goto label_exit; + kalMemZero(prSetEfuseBufModeInfo, + sizeof(struct PARAM_CUSTOM_EFUSE_BUFFER_MODE_CONNAC_T)); + + if (prAdapter->rWifiVar.ucEfuseBufferModeCal == TRUE) { + int ret = 0; + + /* Buffer mode */ + /* Only in buffer mode need to access bin file */ + /* 1 <1> Load bin file*/ + pucConfigBuf = (uint8_t *) kalMemAlloc( + MAX_EEPROM_BUFFER_SIZE, VIR_MEM_TYPE); + if (pucConfigBuf == NULL) + goto label_exit; + + kalMemZero(pucConfigBuf, MAX_EEPROM_BUFFER_SIZE); + + /* 1 <2> Construct EEPROM binary name */ + kalMemZero(aucEeprom, sizeof(aucEeprom)); + + ret = kalSnprintf(aucEeprom, 32, "%s%x.bin", + apucEepromName[0], chip_id); + if (ret < 0 || ret >= 32) { + DBGLOG(INIT, ERROR, + "[%u] kalSnprintf failed, ret: %d\n", + __LINE__, ret); + goto label_exit; + } + + /* 1 <3> Request buffer bin */ + if (kalRequestFirmware(aucEeprom, pucConfigBuf, + MAX_EEPROM_BUFFER_SIZE, &u4ContentLen, prGlueInfo->prDev) + == 0) { + DBGLOG(INIT, INFO, "request file done\n"); + } else { + DBGLOG(INIT, INFO, "can't find file\n"); + goto label_exit; + } + DBGLOG(INIT, INFO, "u4ContentLen = %d\n", u4ContentLen); + + /* 1 <4> Send CMD with bin file content */ + prGlueInfo = prAdapter->prGlueInfo; + + /* Update contents in local table */ + kalMemCopy(uacEEPROMImage, pucConfigBuf, + MAX_EEPROM_BUFFER_SIZE); + + if (u4ContentLen > MAX_EEPROM_BUFFER_SIZE) + goto label_exit; + + kalMemCopy(prSetEfuseBufModeInfo->aBinContent, pucConfigBuf, + u4ContentLen); + + prSetEfuseBufModeInfo->ucSourceMode = 1; + } else { + /* eFuse mode */ + /* Only need to tell FW the content from, contents are directly + * from efuse + */ + prSetEfuseBufModeInfo->ucSourceMode = 0; + u4ContentLen = 0; + } + prSetEfuseBufModeInfo->ucContentFormat = 0x1 | + (prAdapter->rWifiVar.ucCalTimingCtrl << 4); + prSetEfuseBufModeInfo->u2Count = u4ContentLen; + + rStatus = kalIoctl(prGlueInfo, wlanoidConnacSetEfusBufferMode, + (void *)prSetEfuseBufModeInfo, + OFFSET_OF(struct PARAM_CUSTOM_EFUSE_BUFFER_MODE_CONNAC_T, + aBinContent) + u4ContentLen, + FALSE, TRUE, TRUE, &u4BufLen); + + retWlanStat = WLAN_STATUS_SUCCESS; + +label_exit: + + /* free memory */ + if (prSetEfuseBufModeInfo != NULL) + kalMemFree(prSetEfuseBufModeInfo, VIR_MEM_TYPE, + sizeof(struct PARAM_CUSTOM_EFUSE_BUFFER_MODE_CONNAC_T)); + + if (pucConfigBuf != NULL) + kalMemFree(pucConfigBuf, VIR_MEM_TYPE, + MAX_EEPROM_BUFFER_SIZE); + + return retWlanStat; +} +#if (CONFIG_WLAN_SERVICE == 1) +uint32_t wlanServiceInit(struct GLUE_INFO *prGlueInfo) +{ + + struct service_test *prServiceTest; + struct test_wlan_info *winfos; + struct mt66xx_chip_info *prChipInfo; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + + DBGLOG(INIT, TRACE, "%s enter!\n", __func__); + + if (prGlueInfo == NULL) + return WLAN_STATUS_FAILURE; + + prChipInfo = prGlueInfo->prAdapter->chip_info; + prGlueInfo->rService.serv_id = SERV_HANDLE_TEST; + prGlueInfo->rService.serv_handle + = kalMemAlloc(sizeof(struct service_test), VIR_MEM_TYPE); + if (prGlueInfo->rService.serv_handle == NULL) { + DBGLOG(INIT, WARN, + "prGlueInfo->rService.serv_handle memory alloc fail!\n"); + return WLAN_STATUS_FAILURE; + } + + prServiceTest = (struct service_test *)prGlueInfo->rService.serv_handle; + prServiceTest->test_winfo + = kalMemAlloc(sizeof(struct test_wlan_info), VIR_MEM_TYPE); + if (prServiceTest->test_winfo == NULL) { + DBGLOG(INIT, WARN, + "prServiceTest->test_winfo memory alloc fail!\n"); + goto label_exit; + } + winfos = prServiceTest->test_winfo; + + prServiceTest->test_winfo->net_dev = gPrDev; + + if (prChipInfo->asicGetChipID) + prServiceTest->test_winfo->chip_id = + prChipInfo->asicGetChipID(prGlueInfo->prAdapter); + else + prServiceTest->test_winfo->chip_id = prChipInfo->chip_id; + + DBGLOG(INIT, WARN, + "%s chip_id = 0x%x\n", __func__, + prServiceTest->test_winfo->chip_id); + +#if (CFG_MTK_ANDROID_EMI == 1) + prServiceTest->test_winfo->emi_phy_base = gConEmiPhyBaseFinal; + prServiceTest->test_winfo->emi_phy_size = gConEmiSizeFinal; +#else + DBGLOG(RFTEST, WARN, "Platform doesn't support EMI address\n"); +#endif + + prServiceTest->test_op + = kalMemAlloc(sizeof(struct test_operation), VIR_MEM_TYPE); + if (prServiceTest->test_op == NULL) { + DBGLOG(INIT, WARN, + "prServiceTest->test_op memory alloc fail!\n"); + goto label_exit; + } + + prServiceTest->engine_offload = true; + winfos->oid_funcptr = (wlan_oid_handler_t) ServiceWlanOid; + + rStatus = mt_agent_init_service(&prGlueInfo->rService); + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(INIT, WARN, "%s init fail err:%d\n", __func__, rStatus); + + return rStatus; + +label_exit: + + /* free memory */ + if (prGlueInfo->rService.serv_handle != NULL) { + + if (prServiceTest->test_winfo != NULL) + kalMemFree(prServiceTest->test_winfo, VIR_MEM_TYPE, + sizeof(struct test_wlan_info)); + + if (prServiceTest->test_op != NULL) + kalMemFree(prServiceTest->test_op, VIR_MEM_TYPE, + sizeof(struct test_operation)); + + kalMemFree(prGlueInfo->rService.serv_handle, VIR_MEM_TYPE, + sizeof(struct service_test)); + } + + return WLAN_STATUS_FAILURE; +} +uint32_t wlanServiceExit(struct GLUE_INFO *prGlueInfo) +{ + uint32_t rStatus = WLAN_STATUS_SUCCESS; + struct service_test *prServiceTest; + + DBGLOG(INIT, TRACE, "%s enter\n", __func__); + + if (prGlueInfo == NULL) + return WLAN_STATUS_FAILURE; + + rStatus = mt_agent_exit_service(&prGlueInfo->rService); + + prServiceTest = (struct service_test *)prGlueInfo->rService.serv_handle; + + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(INIT, WARN, "wlanServiceExit fail err:%d\n", rStatus); + + if (prGlueInfo->rService.serv_handle) { + if (prServiceTest->test_winfo) + kalMemFree(prServiceTest->test_winfo, + VIR_MEM_TYPE, sizeof(struct test_wlan_info)); + + if (prServiceTest->test_op) + kalMemFree(prServiceTest->test_op, + VIR_MEM_TYPE, sizeof(struct test_operation)); + + kalMemFree(prGlueInfo->rService.serv_handle, + VIR_MEM_TYPE, sizeof(struct service_test)); + } + + prGlueInfo->rService.serv_id = 0; + + return rStatus; +} +#endif + +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH + +#define FW_LOG_CMD_ON_OFF 0 +#define FW_LOG_CMD_SET_LEVEL 1 +static uint32_t u4LogOnOffCache; +static uint32_t u4LogLevelCache = -1; + +struct CMD_CONNSYS_FW_LOG { + int32_t fgCmd; + int32_t fgValue; +}; + +uint32_t +connsysFwLogControl(struct ADAPTER *prAdapter, void *pvSetBuffer, + uint32_t u4SetBufferLen, uint32_t *pu4SetInfoLen) +{ + struct CMD_CONNSYS_FW_LOG *prCmd; + struct CMD_HEADER rCmdV1Header; + struct CMD_FORMAT_V1 rCmd_v1; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + + if ((prAdapter == NULL) || (pvSetBuffer == NULL) + || (pu4SetInfoLen == NULL)) + return WLAN_STATUS_FAILURE; + + /* init */ + *pu4SetInfoLen = sizeof(struct CMD_CONNSYS_FW_LOG); + prCmd = (struct CMD_CONNSYS_FW_LOG *) pvSetBuffer; + + if (prCmd->fgCmd == FW_LOG_CMD_ON_OFF) { + + /*EvtDrvnLogEn 0/1*/ + uint8_t onoff[1] = {'0'}; + + DBGLOG(INIT, TRACE, "FW_LOG_CMD_ON_OFF\n"); + + rCmdV1Header.cmdType = CMD_TYPE_SET; + rCmdV1Header.cmdVersion = CMD_VER_1; + rCmdV1Header.cmdBufferLen = 0; + rCmdV1Header.itemNum = 0; + + kalMemSet(rCmdV1Header.buffer, 0, MAX_CMD_BUFFER_LENGTH); + kalMemSet(&rCmd_v1, 0, sizeof(struct CMD_FORMAT_V1)); + + rCmd_v1.itemType = ITEM_TYPE_STR; + + /*send string format to firmware */ + rCmd_v1.itemStringLength = kalStrLen("EnableDbgLog"); + kalMemZero(rCmd_v1.itemString, MAX_CMD_NAME_MAX_LENGTH); + kalMemCopy(rCmd_v1.itemString, "EnableDbgLog", + rCmd_v1.itemStringLength); + + if (prCmd->fgValue == 1) /* other cases, send 'OFF=0' */ + onoff[0] = '1'; + rCmd_v1.itemValueLength = 1; + kalMemZero(rCmd_v1.itemValue, MAX_CMD_VALUE_MAX_LENGTH); + kalMemCopy(rCmd_v1.itemValue, &onoff, 1); + + DBGLOG(INIT, INFO, "Send key word (%s) WITH (%s) to firmware\n", + rCmd_v1.itemString, rCmd_v1.itemValue); + + kalMemCopy(((struct CMD_FORMAT_V1 *)rCmdV1Header.buffer), + &rCmd_v1, sizeof(struct CMD_FORMAT_V1)); + + rCmdV1Header.cmdBufferLen += sizeof(struct CMD_FORMAT_V1); + rCmdV1Header.itemNum = 1; + + rStatus = wlanSendSetQueryCmd( + prAdapter, /* prAdapter */ + CMD_ID_GET_SET_CUSTOMER_CFG, /* 0x70 */ + TRUE, /* fgSetQuery */ + FALSE, /* fgNeedResp */ + FALSE, /* fgIsOid */ + NULL, /* pfCmdDoneHandler*/ + NULL, /* pfCmdTimeoutHandler */ + sizeof(struct CMD_HEADER), + (uint8_t *)&rCmdV1Header, /* pucInfoBuffer */ + NULL, /* pvSetQueryBuffer */ + 0 /* u4SetQueryBufferLen */ + ); + + /* keep in cache */ + u4LogOnOffCache = prCmd->fgValue; + } else if (prCmd->fgCmd == FW_LOG_CMD_SET_LEVEL) { + /*ENG_LOAD_OFFSET 1*/ + /*USERDEBUG_LOAD_OFFSET 2 */ + /*USER_LOAD_OFFSET 3 */ + int32_t u4LogLevel = ENUM_WIFI_LOG_LEVEL_DEFAULT; + + DBGLOG(INIT, INFO, "FW_LOG_CMD_SET_LEVEL %d\n", prCmd->fgValue); + switch (prCmd->fgValue) { + case 0: + u4LogLevel = ENUM_WIFI_LOG_LEVEL_DEFAULT; + break; + case 1: + u4LogLevel = ENUM_WIFI_LOG_LEVEL_MORE; + break; + case 2: + u4LogLevel = ENUM_WIFI_LOG_LEVEL_EXTREME; + break; + default: + u4LogLevel = ENUM_WIFI_LOG_LEVEL_DEFAULT; + break; + } + wlanDbgSetLogLevelImpl(prAdapter, + ENUM_WIFI_LOG_LEVEL_VERSION_V1, + ENUM_WIFI_LOG_MODULE_DRIVER, + u4LogLevel); + wlanDbgSetLogLevelImpl(prAdapter, + ENUM_WIFI_LOG_LEVEL_VERSION_V1, + ENUM_WIFI_LOG_MODULE_FW, + u4LogLevel); + /* keep in cache */ + u4LogLevelCache = prCmd->fgValue; + } else { + DBGLOG(INIT, INFO, "command can not parse\n"); + } + return WLAN_STATUS_SUCCESS; +} + +static void consys_log_event_notification(int cmd, int value) +{ + struct CMD_CONNSYS_FW_LOG rFwLogCmd; + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + struct net_device *prDev = gPrDev; + uint32_t rStatus = WLAN_STATUS_FAILURE; + uint32_t u4BufLen; + + DBGLOG(INIT, INFO, "gPrDev=%p, cmd=%d, value=%d\n", + gPrDev, cmd, value); + + if (cmd == FW_LOG_CMD_ON_OFF) + u4LogOnOffCache = value; + if (cmd == FW_LOG_CMD_SET_LEVEL) + u4LogLevelCache = value; + + if (kalIsHalted()) { /* power-off */ + DBGLOG(INIT, INFO, + "Power off return, u4LogOnOffCache=%d\n", + u4LogOnOffCache); + return; + } + + prGlueInfo = (prDev != NULL) ? + *((struct GLUE_INFO **) netdev_priv(prDev)) : NULL; + DBGLOG(INIT, TRACE, "prGlueInfo=%p\n", prGlueInfo); + if (!prGlueInfo) { + DBGLOG(INIT, INFO, + "prGlueInfo == NULL return, u4LogOnOffCache=%d\n", + u4LogOnOffCache); + return; + } + prAdapter = prGlueInfo->prAdapter; + DBGLOG(INIT, TRACE, "prAdapter=%p\n", prAdapter); + if (!prAdapter) { + DBGLOG(INIT, INFO, + "prAdapter == NULL return, u4LogOnOffCache=%d\n", + u4LogOnOffCache); + return; + } + + kalMemZero(&rFwLogCmd, sizeof(rFwLogCmd)); + rFwLogCmd.fgCmd = cmd; + rFwLogCmd.fgValue = value; + + rStatus = kalIoctl(prGlueInfo, + connsysFwLogControl, + &rFwLogCmd, + sizeof(struct CMD_CONNSYS_FW_LOG), + FALSE, FALSE, FALSE, + &u4BufLen); +} +#endif + +static +void wlanOnPreAdapterStart(struct GLUE_INFO *prGlueInfo, + struct ADAPTER *prAdapter, + struct REG_INFO **pprRegInfo, + struct mt66xx_chip_info **pprChipInfo) +{ + uint32_t u4Idx = 0; +#if CFG_WMT_WIFI_PATH_SUPPORT + int32_t i4RetVal = 0; +#endif + + DBGLOG(INIT, TRACE, "start.\n"); + prGlueInfo->u4ReadyFlag = 0; +#if CFG_MTK_ANDROID_WMT + update_driver_loaded_status(prGlueInfo->u4ReadyFlag); +#endif +#if CFG_TCP_IP_CHKSUM_OFFLOAD + prAdapter->fgIsSupportCsumOffload = FALSE; + prAdapter->u4CSUMFlags = CSUM_OFFLOAD_EN_ALL; +#endif + +#if CFG_SUPPORT_CFG_FILE + wlanGetConfig(prAdapter); +#endif + + /* Init Chip Capability */ + *pprChipInfo = prAdapter->chip_info; + if ((*pprChipInfo)->asicCapInit) + (*pprChipInfo)->asicCapInit(prAdapter); + + /* Default support 2.4/5G MIMO */ + prAdapter->rWifiFemCfg.u2WifiPath = ( + WLAN_FLAG_2G4_WF0 | WLAN_FLAG_5G_WF0 | + WLAN_FLAG_2G4_WF1 | WLAN_FLAG_5G_WF1); + +#if CFG_WMT_WIFI_PATH_SUPPORT + i4RetVal = mtk_wcn_wmt_wifi_fem_cfg_report(( + void *)&prAdapter->rWifiFemCfg); + if (i4RetVal) + DBGLOG(INIT, ERROR, "Get WifiPath from WMT drv fail\n"); + else + DBGLOG(INIT, INFO, + "Get WifiPath from WMT drv success, WifiPath=0x%x\n", + prAdapter->rWifiFemCfg.u2WifiPath); +#endif + /* 4 <5> Start Device */ + *pprRegInfo = &prGlueInfo->rRegInfo; + + /* P_REG_INFO_T prRegInfo = (P_REG_INFO_T) kmalloc( + * sizeof(REG_INFO_T), GFP_KERNEL); + */ + kalMemSet(*pprRegInfo, 0, sizeof(struct REG_INFO)); + + /* Trigger the action of switching Pwr state to drv_own */ + prAdapter->fgIsFwOwn = TRUE; + + nicpmWakeUpWiFi(prAdapter); + + /* Load NVRAM content to REG_INFO_T */ + glLoadNvram(prGlueInfo, *pprRegInfo); + + /* kalMemCopy(&prGlueInfo->rRegInfo, prRegInfo, + * sizeof(REG_INFO_T)); + */ + + (*pprRegInfo)->u4PowerMode = CFG_INIT_POWER_SAVE_PROF; +#if 0 + prRegInfo->fgEnArpFilter = TRUE; +#endif + + /* The Init value of u4WpaVersion/u4AuthAlg shall be + * DISABLE/OPEN, not zero! + */ + /* The Init value of u4CipherGroup/u4CipherPairwise shall be + * NONE, not zero! + */ + for (u4Idx = 0; u4Idx < KAL_AIS_NUM; u4Idx++) { + struct GL_WPA_INFO *prWpaInfo = + aisGetWpaInfo(prAdapter, u4Idx); + + if (!prWpaInfo) + continue; + + prWpaInfo->u4WpaVersion = + IW_AUTH_WPA_VERSION_DISABLED; + prWpaInfo->u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM; + prWpaInfo->u4CipherGroup = IW_AUTH_CIPHER_NONE; + prWpaInfo->u4CipherPairwise = IW_AUTH_CIPHER_NONE; + } + + tasklet_init(&prGlueInfo->rRxTask, halRxTasklet, + (unsigned long)prGlueInfo); + tasklet_init(&prGlueInfo->rTxCompleteTask, + halTxCompleteTasklet, + (unsigned long)prGlueInfo); +} + +static +void wlanOnPostAdapterStart(struct ADAPTER *prAdapter, + struct GLUE_INFO *prGlueInfo) +{ + DBGLOG(INIT, TRACE, "start.\n"); + if (HAL_IS_TX_DIRECT(prAdapter)) { + if (!prAdapter->fgTxDirectInited) { + skb_queue_head_init( + &prAdapter->rTxDirectSkbQueue); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) + timer_setup(&prAdapter->rTxDirectSkbTimer, + nicTxDirectTimerCheckSkbQ, 0); + timer_setup(&prAdapter->rTxDirectHifTimer, + nicTxDirectTimerCheckHifQ, 0); +#else + init_timer(&prAdapter->rTxDirectSkbTimer); + prAdapter->rTxDirectSkbTimer.data = + (unsigned long)prGlueInfo; + prAdapter->rTxDirectSkbTimer.function = + nicTxDirectTimerCheckSkbQ; + + init_timer(&prAdapter->rTxDirectHifTimer); + prAdapter->rTxDirectHifTimer.data = + (unsigned long)prGlueInfo; + prAdapter->rTxDirectHifTimer.function = + nicTxDirectTimerCheckHifQ; +#endif + prAdapter->fgTxDirectInited = TRUE; + } + } +} + +static int32_t wlanOnPreNetRegister(struct GLUE_INFO *prGlueInfo, + struct ADAPTER *prAdapter, + struct mt66xx_chip_info *prChipInfo, + struct WIFI_VAR *prWifiVar, + const u_int8_t bAtResetFlow) +{ + uint32_t i; + + DBGLOG(INIT, TRACE, "start.\n"); + + if (!bAtResetFlow) { + /* change net device mtu from feature option */ + if (prWifiVar->u4MTU > 0 && prWifiVar->u4MTU <= ETH_DATA_LEN) { + for (i = 0; i < KAL_AIS_NUM; i++) + gprWdev[i]->netdev->mtu = prWifiVar->u4MTU; + } + INIT_DELAYED_WORK(&prGlueInfo->rRxPktDeAggWork, + halDeAggRxPktWorker); + } + INIT_WORK(&prGlueInfo->rTxMsduFreeWork, kalFreeTxMsduWorker); + + prGlueInfo->main_thread = kthread_run(main_thread, + prGlueInfo->prDevHandler, "main_thread"); +#if CFG_SUPPORT_MULTITHREAD + prGlueInfo->hif_thread = kthread_run(hif_thread, + prGlueInfo->prDevHandler, "hif_thread"); + prGlueInfo->rx_thread = kthread_run(rx_thread, + prGlueInfo->prDevHandler, "rx_thread"); +#endif + /* TODO the change schedule API shall be provided by OS glue + * layer + */ + /* Switch the Wi-Fi task priority to higher priority and change + * the scheduling method + */ + if (prGlueInfo->prAdapter->rWifiVar.ucThreadPriority > 0) { +#if KERNEL_VERSION(4, 19, 0) >= LINUX_VERSION_CODE + struct sched_param param = { + .sched_priority = prGlueInfo->prAdapter + ->rWifiVar.ucThreadPriority + }; + sched_setscheduler(prGlueInfo->main_thread, + prGlueInfo->prAdapter->rWifiVar + .ucThreadScheduling, ¶m); +#if CFG_SUPPORT_MULTITHREAD + sched_setscheduler(prGlueInfo->hif_thread, + prGlueInfo->prAdapter->rWifiVar + .ucThreadScheduling, ¶m); + sched_setscheduler(prGlueInfo->rx_thread, + prGlueInfo->prAdapter->rWifiVar + .ucThreadScheduling, ¶m); +#endif +#endif + DBGLOG(INIT, INFO, + "Set pri = %d, sched = %d\n", + prGlueInfo->prAdapter->rWifiVar.ucThreadPriority, + prGlueInfo->prAdapter->rWifiVar + .ucThreadScheduling); + } + + if (!bAtResetFlow) { + g_u4HaltFlag = 0; + +#if CFG_SUPPORT_BUFFER_MODE +#if (CFG_EFUSE_BUFFER_MODE_DELAY_CAL == 1) + if (prChipInfo->downloadBufferBin) { + if (prChipInfo->downloadBufferBin(prAdapter) != + WLAN_STATUS_SUCCESS) + return -1; + } +#endif +#endif + +#if CFG_SUPPORT_DBDC + /* Update DBDC default setting */ + cnmInitDbdcSetting(prAdapter); +#endif /*CFG_SUPPORT_DBDC*/ + } + + /* send regulatory information to firmware */ + rlmDomainSendInfoToFirmware(prAdapter); + + /* set MAC address */ + if (!bAtResetFlow) { + uint32_t rStatus = WLAN_STATUS_FAILURE; + struct sockaddr MacAddr; + uint32_t u4SetInfoLen = 0; + struct net_device *prDevHandler; + + rStatus = kalIoctl(prGlueInfo, wlanoidQueryCurrentAddr, + &MacAddr.sa_data, PARAM_MAC_ADDR_LEN, + TRUE, TRUE, TRUE, &u4SetInfoLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, WARN, "set MAC addr fail 0x%x\n", + rStatus); + } else { + kalMemCopy(prGlueInfo->prDevHandler->dev_addr, + &MacAddr.sa_data, ETH_ALEN); + kalMemCopy(prGlueInfo->prDevHandler->perm_addr, + prGlueInfo->prDevHandler->dev_addr, + ETH_ALEN); + +#if CFG_SHOW_MACADDR_SOURCE + DBGLOG(INIT, INFO, "MAC address: " MACSTR, + MAC2STR(prAdapter->rWifiVar.aucMacAddress)); +#endif + } + + /* wlan1 */ + if (KAL_AIS_NUM > 1) { + prDevHandler = wlanGetNetDev(prGlueInfo, 1); + if (prDevHandler) { + kalMemCopy(prDevHandler->dev_addr, + &prAdapter->rWifiVar.aucMacAddress1, + ETH_ALEN); + kalMemCopy(prDevHandler->perm_addr, + prDevHandler->dev_addr, + ETH_ALEN); +#if CFG_SHOW_MACADDR_SOURCE + DBGLOG(INIT, INFO, + "MAC1 address: " MACSTR, + MAC2STR(prDevHandler->dev_addr)); +#endif + } + } + } + +#if CFG_TCP_IP_CHKSUM_OFFLOAD + /* set HW checksum offload */ + if (!bAtResetFlow && prAdapter->fgIsSupportCsumOffload) { + uint32_t rStatus = WLAN_STATUS_FAILURE; + uint32_t u4CSUMFlags = CSUM_OFFLOAD_EN_ALL; + uint32_t u4SetInfoLen = 0; + + rStatus = kalIoctl(prGlueInfo, wlanoidSetCSUMOffload, + (void *) &u4CSUMFlags, + sizeof(uint32_t), + FALSE, FALSE, TRUE, &u4SetInfoLen); + + if (rStatus == WLAN_STATUS_SUCCESS) { + for (i = 0; i < KAL_AIS_NUM; i++) + gprWdev[i]->netdev->features |= + NETIF_F_IP_CSUM | + NETIF_F_IPV6_CSUM | + NETIF_F_RXCSUM; + } else { + DBGLOG(INIT, WARN, + "set HW checksum offload fail 0x%x\n", + rStatus); + prAdapter->fgIsSupportCsumOffload = FALSE; + } + } +#endif +#if CFG_SUPPORT_802_11K + { + uint32_t u4Idx = 0; + + for (u4Idx = 0; u4Idx < KAL_AIS_NUM; u4Idx++) { + uint32_t rStatus = WLAN_STATUS_FAILURE; + uint32_t u4SetInfoLen = 0; + + rStatus = kalIoctlByBssIdx(prGlueInfo, + wlanoidSync11kCapabilities, NULL, 0, + FALSE, FALSE, TRUE, &u4SetInfoLen, + u4Idx); + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(INIT, WARN, + "[%d] Set 11k Capabilities fail 0x%x\n", + u4Idx, rStatus); + } + } +#endif + return 0; +} + +static void wlanOnPostNetRegister(void) +{ + DBGLOG(INIT, TRACE, "start.\n"); + /* 4 <4> Register early suspend callback */ +#if CFG_ENABLE_EARLY_SUSPEND + glRegisterEarlySuspend(&wlan_early_suspend_desc, + wlan_early_suspend, wlan_late_resume); +#endif + /* 4 <5> Register Notifier callback */ + wlanRegisterInetAddrNotifier(); +} + +static +void wlanOnP2pRegistration(struct GLUE_INFO *prGlueInfo, + struct ADAPTER *prAdapter, + struct wireless_dev *prWdev) +{ + DBGLOG(INIT, TRACE, "start.\n"); + +#if (CFG_ENABLE_WIFI_DIRECT && CFG_MTK_ANDROID_WMT) + register_set_p2p_mode_handler(set_p2p_mode_handler); +#endif + +#if CFG_ENABLE_WIFI_DIRECT + if (prAdapter->rWifiVar.u4RegP2pIfAtProbe) { + struct PARAM_CUSTOM_P2P_SET_STRUCT rSetP2P; + + rSetP2P.u4Enable = 1; + +#ifdef CFG_DRIVER_INITIAL_RUNNING_MODE + rSetP2P.u4Mode = CFG_DRIVER_INITIAL_RUNNING_MODE; +#else + rSetP2P.u4Mode = RUNNING_P2P_MODE; +#endif /* CFG_DRIVER_RUNNING_MODE */ + if (set_p2p_mode_handler(prWdev->netdev, rSetP2P) == 0) + DBGLOG(INIT, INFO, + "%s: p2p device registered\n", + __func__); + else + DBGLOG(INIT, ERROR, + "%s: Failed to register p2p device\n", + __func__); + } +#endif +} + +static +int32_t wlanOnWhenProbeSuccess(struct GLUE_INFO *prGlueInfo, + struct ADAPTER *prAdapter, + const u_int8_t bAtResetFlow) +{ + int32_t u4LogLevel = ENUM_WIFI_LOG_LEVEL_DEFAULT; + + DBGLOG(INIT, TRACE, "start.\n"); + +#if CFG_SUPPORT_EASY_DEBUG + /* move before reading file + * wlanLoadDefaultCustomerSetting(prAdapter); + */ + wlanFeatureToFw(prGlueInfo->prAdapter, WLAN_CFG_DEFAULT); + + /*if driver backup Engineer Mode CFG setting before*/ + wlanResoreEmCfgSetting(prGlueInfo->prAdapter); + wlanFeatureToFw(prGlueInfo->prAdapter, WLAN_CFG_EM); +#endif + +#if CFG_SUPPORT_IOT_AP_BLACKLIST + wlanCfgLoadIotApRule(prAdapter); + wlanCfgDumpIotApRule(prAdapter); +#endif + if (!bAtResetFlow) { +#if CFG_SUPPORT_AGPS_ASSIST + kalIndicateAgpsNotify(prAdapter, AGPS_EVENT_WLAN_ON, NULL, + 0); +#endif + + wlanCfgSetSwCtrl(prGlueInfo->prAdapter); + wlanCfgSetChip(prGlueInfo->prAdapter); +#if (CFG_SUPPORT_CONNINFRA == 1) + wlanCfgSetChipSyncTime(prGlueInfo->prAdapter); +#endif + wlanCfgSetCountryCode(prGlueInfo->prAdapter); + kalPerMonInit(prGlueInfo); +#if CFG_MET_TAG_SUPPORT + if (met_tag_init() != 0) + DBGLOG(INIT, ERROR, "MET_TAG_INIT error!\n"); +#endif + } + +#if CFG_SUPPORT_CAL_RESULT_BACKUP_TO_HOST + /* Calibration Backup Flow */ + if (!g_fgIsCalDataBackuped) { + if (rlmTriggerCalBackup(prGlueInfo->prAdapter, + g_fgIsCalDataBackuped) == WLAN_STATUS_FAILURE) { + DBGLOG(RFTEST, INFO, + "Error : Boot Time Wi-Fi Enable Fail........\n"); + return -1; + } + + g_fgIsCalDataBackuped = TRUE; + } else { + if (rlmTriggerCalBackup(prGlueInfo->prAdapter, + g_fgIsCalDataBackuped) == WLAN_STATUS_FAILURE) { + DBGLOG(RFTEST, INFO, + "Error : Normal Wi-Fi Enable Fail........\n"); + return -1; + } + } +#endif + + /* card is ready */ + prGlueInfo->u4ReadyFlag = 1; +#if CFG_MTK_ANDROID_WMT + update_driver_loaded_status(prGlueInfo->u4ReadyFlag); +#endif + kalSetHalted(FALSE); + + wlanDbgGetGlobalLogLevel(ENUM_WIFI_LOG_MODULE_FW, + &u4LogLevel); + if (u4LogLevel > ENUM_WIFI_LOG_LEVEL_DEFAULT) + wlanDbgSetLogLevelImpl(prAdapter, + ENUM_WIFI_LOG_LEVEL_VERSION_V1, + ENUM_WIFI_LOG_MODULE_FW, + u4LogLevel); + +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH + /* sync log status with firmware */ + consys_log_event_notification((int)FW_LOG_CMD_ON_OFF, + u4LogOnOffCache); + if (u4LogLevelCache != -1) { + consys_log_event_notification((int)FW_LOG_CMD_SET_LEVEL, + u4LogLevelCache); + } +#endif + +#if CFG_CHIP_RESET_HANG + if (fgIsResetHangState == SER_L0_HANG_RST_TRGING) { + DBGLOG(INIT, STATE, "[SER][L0] SET hang!\n"); + fgIsResetHangState = SER_L0_HANG_RST_HANG; + fgIsResetting = TRUE; + } + DBGLOG(INIT, STATE, "[SER][L0] PASS!!\n"); +#endif + +#if CFG_MTK_MCIF_WIFI_SUPPORT + mddpNotifyDrvMac(prGlueInfo->prAdapter); +#endif + +#if CFG_SUPPORT_LOWLATENCY_MODE + wlanProbeSuccessForLowLatency(prAdapter); +#endif + +#if (CFG_SUPPORT_CONNINFRA == 1) + if (prAdapter->chip_info->checkbushang) { + fw_log_bug_hang_register(prAdapter->chip_info->checkbushang); + } +#endif + + wlanOnP2pRegistration(prGlueInfo, prAdapter, gprWdev[0]); + if (prAdapter->u4HostStatusEmiOffset) + kalSetSuspendFlagToEMI(prAdapter, FALSE); + return 0; +} + +void wlanOffStopWlanThreads(IN struct GLUE_INFO *prGlueInfo) +{ + DBGLOG(INIT, TRACE, "start.\n"); + + if (prGlueInfo->main_thread == NULL && + prGlueInfo->hif_thread == NULL && + prGlueInfo->rx_thread == NULL) { + DBGLOG(INIT, INFO, + "Threads are already NULL, skip stop and free\n"); + return; + } + +#if CFG_SUPPORT_MULTITHREAD + wake_up_interruptible(&prGlueInfo->waitq_hif); + wait_for_completion_interruptible( + &prGlueInfo->rHifHaltComp); + wake_up_interruptible(&prGlueInfo->waitq_rx); + wait_for_completion_interruptible(&prGlueInfo->rRxHaltComp); +#endif + + /* wake up main thread */ + wake_up_interruptible(&prGlueInfo->waitq); + /* wait main thread stops */ + wait_for_completion_interruptible(&prGlueInfo->rHaltComp); + + DBGLOG(INIT, INFO, "wlan thread stopped\n"); + + /* prGlueInfo->rHifInfo.main_thread = NULL; */ + prGlueInfo->main_thread = NULL; +#if CFG_SUPPORT_MULTITHREAD + prGlueInfo->hif_thread = NULL; + prGlueInfo->rx_thread = NULL; + + prGlueInfo->u4TxThreadPid = 0xffffffff; + prGlueInfo->u4HifThreadPid = 0xffffffff; +#endif + + if (test_and_clear_bit(GLUE_FLAG_OID_BIT, &prGlueInfo->ulFlag) && + !completion_done(&prGlueInfo->rPendComp)) { + struct GL_IO_REQ *prIoReq; + + DBGLOG(INIT, INFO, "Complete on-going ioctl as failure.\n"); + prIoReq = &(prGlueInfo->OidEntry); + prIoReq->rStatus = WLAN_STATUS_FAILURE; + complete(&prGlueInfo->rPendComp); + } +} + + +#if CFG_CHIP_RESET_SUPPORT +/*----------------------------------------------------------------------------*/ +/*! + * \brief slight off procedure for chip reset + * + * \return + * WLAN_STATUS_FAILURE - reset off fail + * WLAN_STATUS_SUCCESS - reset off success + */ +/*----------------------------------------------------------------------------*/ +static int32_t wlanOffAtReset(void) +{ + struct ADAPTER *prAdapter = NULL; + struct net_device *prDev = NULL; + struct GLUE_INFO *prGlueInfo = NULL; + + DBGLOG(INIT, INFO, "Driver Off during Reset\n"); + + if (u4WlanDevNum > 0 + && u4WlanDevNum <= CFG_MAX_WLAN_DEVICES) { + prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev; + } + + if (prDev == NULL) { + DBGLOG(INIT, ERROR, "prDev is NULL\n"); + return WLAN_STATUS_FAILURE; + } + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prDev)); + if (prGlueInfo == NULL) { + DBGLOG(INIT, INFO, "prGlueInfo is NULL\n"); + wlanFreeNetDev(); + return WLAN_STATUS_FAILURE; + } + + prAdapter = prGlueInfo->prAdapter; + if (prAdapter == NULL) { + DBGLOG(INIT, INFO, "prAdapter is NULL\n"); + wlanFreeNetDev(); + return WLAN_STATUS_FAILURE; + } + + /* to avoid that wpa_supplicant/hostapd triogger new cfg80211 command */ + prGlueInfo->u4ReadyFlag = 0; +#if CFG_MTK_ANDROID_WMT + update_driver_loaded_status(prGlueInfo->u4ReadyFlag); +#endif + kalPerMonDestroy(prGlueInfo); + + /* complete possible pending oid, which may block wlanRemove some time + * and then whole chip reset may failed + */ + wlanReleasePendingOid(prGlueInfo->prAdapter, 1); + + flush_delayed_work(&workq); + + flush_delayed_work(&sched_workq); + + /* 4 <2> Mark HALT, notify main thread to stop, and clean up queued + * requests + */ + set_bit(GLUE_FLAG_HALT_BIT, &prGlueInfo->ulFlag); + + /* Stop works */ + flush_work(&prGlueInfo->rTxMsduFreeWork); + + wlanOffStopWlanThreads(prGlueInfo); + + wlanAdapterStop(prAdapter, TRUE); + + /* 4 Stopping handling interrupt and free IRQ */ + glBusFreeIrq(prDev, prGlueInfo); + +#if (CFG_SUPPORT_TRACE_TC4 == 1) + wlanDebugTC4Uninit(); +#endif + +#if (CFG_SUPPORT_STATISTICS == 1) + wlanWakeStaticsUninit(); +#endif + + fgSimplifyResetFlow = TRUE; + + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief A slight wlan on for chip reset + * + * \return + * WLAN_STATUS_FAILURE - reset on fail + * WLAN_STATUS_SUCCESS - reset on success + */ +/*----------------------------------------------------------------------------*/ +static int32_t wlanOnAtReset(void) +{ + struct net_device *prDev = NULL; + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + uint32_t u4DisconnectReason = DISCONNECT_REASON_CODE_CHIPRESET; + uint32_t u4Idx = 0; + + enum ENUM_PROBE_FAIL_REASON { + BUS_INIT_FAIL, + NET_CREATE_FAIL, + BUS_SET_IRQ_FAIL, + ADAPTER_START_FAIL, + NET_REGISTER_FAIL, + PROC_INIT_FAIL, + FAIL_MET_INIT_PROCFS, + FAIL_REASON_NUM + } eFailReason = FAIL_REASON_NUM; + + DBGLOG(INIT, INFO, "Driver On during Reset\n"); + + if (u4WlanDevNum > 0 + && u4WlanDevNum <= CFG_MAX_WLAN_DEVICES) { + prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev; + } + + if (prDev == NULL) { + DBGLOG(INIT, ERROR, "prDev is NULL\n"); + return WLAN_STATUS_FAILURE; + } + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prDev)); + if (prGlueInfo == NULL) { + DBGLOG(INIT, INFO, "prGlueInfo is NULL\n"); + wlanFreeNetDev(); + return WLAN_STATUS_FAILURE; + } + + prAdapter = prGlueInfo->prAdapter; + if (prAdapter == NULL) { + DBGLOG(INIT, INFO, "prAdapter is NULL\n"); + return WLAN_STATUS_FAILURE; + } + + prGlueInfo->ulFlag = 0; + fgSimplifyResetFlow = FALSE; + do { +#if (CFG_SUPPORT_TRACE_TC4 == 1) + wlanDebugTC4Init(); +#endif +#if (CFG_SUPPORT_STATISTICS == 1) + wlanWakeStaticsInit(); +#endif + /* wlanNetCreate partial process */ + QUEUE_INITIALIZE(&prGlueInfo->rCmdQueue); + prGlueInfo->i4TxPendingCmdNum = 0; + QUEUE_INITIALIZE(&prGlueInfo->rTxQueue); + + rStatus = glBusSetIrq(prDev, NULL, prGlueInfo); + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, ERROR, "Set IRQ error\n"); + eFailReason = BUS_SET_IRQ_FAIL; + break; + } + + /* Trigger the action of switching Pwr state to drv_own */ + prAdapter->fgIsFwOwn = TRUE; + + /* wlanAdapterStart Section Start */ + rStatus = wlanAdapterStart(prAdapter, + &prGlueInfo->rRegInfo, + TRUE); + if (rStatus != WLAN_STATUS_SUCCESS) { + eFailReason = ADAPTER_START_FAIL; + break; + } + + wlanOnPreNetRegister(prGlueInfo, prAdapter, + prAdapter->chip_info, + &prAdapter->rWifiVar, + TRUE); + + /* Resend schedule scan */ + prAdapter->rWifiVar.rScanInfo.fgSchedScanning = FALSE; +#if CFG_SUPPORT_SCHED_SCAN + if (prGlueInfo->prSchedScanRequest) { + rStatus = kalIoctl(prGlueInfo, wlanoidSetStartSchedScan, + prGlueInfo->prSchedScanRequest, + sizeof(struct PARAM_SCHED_SCAN_REQUEST), + false, FALSE, TRUE, &u4BufLen); + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(INIT, WARN, + "SCN: Start sched scan failed after chip reset 0x%x\n", + rStatus); + } +#endif + + for (u4Idx = 0; u4Idx < KAL_AIS_NUM; u4Idx++) { + struct FT_IES *prFtIEs = + aisGetFtIe(prAdapter, u4Idx); + struct CONNECTION_SETTINGS *prConnSettings = + aisGetConnSettings(prAdapter, u4Idx); + + kalMemZero(prFtIEs, + sizeof(*prFtIEs)); + prConnSettings->fgIsScanReqIssued = FALSE; + } + + } while (FALSE); + + if (rStatus == WLAN_STATUS_SUCCESS) { + wlanOnWhenProbeSuccess(prGlueInfo, prAdapter, TRUE); + DBGLOG(INIT, INFO, "reset success\n"); + + /* Send disconnect */ + for (u4Idx = 0; u4Idx < KAL_AIS_NUM; u4Idx++) { + rStatus = kalIoctlByBssIdx(prGlueInfo, + wlanoidSetDisassociate, + &u4DisconnectReason, + 0, FALSE, FALSE, TRUE, &u4BufLen, + u4Idx); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, WARN, + "disassociate error:%x\n", rStatus); + continue; + } + DBGLOG(INIT, INFO, + "%d inform disconnected\n", u4Idx); + } + } else { + prAdapter->u4HifDbgFlag |= DEG_HIF_DEFAULT_DUMP; + halPrintHifDbgInfo(prAdapter); + DBGLOG(INIT, WARN, "Fail reason: %d\n", eFailReason); + + /* Remove error handling here, leave it to coming wlanRemove + * for full clean. + * + * If WMT being removed in the future, you should invoke + * wlanRemove directly from here + */ +#if 0 + switch (eFailReason) { + case ADAPTER_START_FAIL: + glBusFreeIrq(prDev, + *((struct GLUE_INFO **) + netdev_priv(prDev))); + /* fallthrough */ + case BUS_SET_IRQ_FAIL: + wlanWakeLockUninit(prGlueInfo); + wlanNetDestroy(prDev->ieee80211_ptr); + /* prGlueInfo->prAdapter is released in + * wlanNetDestroy + */ + /* Set NULL value for local prAdapter as well */ + prAdapter = NULL; + break; + default: + break; + } +#endif + } + return rStatus; +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Wlan probe function. This function probes and initializes the device. + * + * \param[in] pvData data passed by bus driver init function + * _HIF_EHPI: NULL + * _HIF_SDIO: sdio bus driver handle + * + * \retval 0 Success + * \retval negative value Failed + */ +/*----------------------------------------------------------------------------*/ +static int32_t wlanProbe(void *pvData, void *pvDriverData) +{ + struct wireless_dev *prWdev = NULL; + enum ENUM_PROBE_FAIL_REASON { + BUS_INIT_FAIL, + NET_CREATE_FAIL, + BUS_SET_IRQ_FAIL, + ADAPTER_START_FAIL, + NET_REGISTER_FAIL, + PROC_INIT_FAIL, + FAIL_MET_INIT_PROCFS, + FAIL_BY_RESET, + FAIL_REASON_NUM + } eFailReason; + struct WLANDEV_INFO *prWlandevInfo = NULL; + int32_t i4DevIdx = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + int32_t i4Status = 0; + u_int8_t bRet = FALSE; + u_int8_t i = 0; + struct REG_INFO *prRegInfo; + struct mt66xx_chip_info *prChipInfo; + struct WIFI_VAR *prWifiVar; + uint32_t u4Idx = 0; + +#if CFG_MTK_MCIF_WIFI_SUPPORT + mddpNotifyWifiOnStart(); +#endif + +#if CFG_CHIP_RESET_SUPPORT + if (fgSimplifyResetFlow) { + i4Status = wlanOnAtReset(); +#if CFG_MTK_MCIF_WIFI_SUPPORT + if (i4Status == WLAN_STATUS_SUCCESS) + mddpNotifyWifiOnEnd(); +#endif + return i4Status; + } +#endif + +#if 0 + uint8_t *pucConfigBuf = NULL, pucCfgBuf = NULL; + uint32_t u4ConfigReadLen = 0; +#endif + + eFailReason = FAIL_REASON_NUM; + do { + /* 4 <1> Initialize the IO port of the interface */ + /* GeorgeKuo: pData has different meaning for _HIF_XXX: + * _HIF_EHPI: pointer to memory base variable, which will be + * initialized by glBusInit(). + * _HIF_SDIO: bus driver handle + */ + + DBGLOG(INIT, INFO, "enter wlanProbe\n"); + + bRet = glBusInit(pvData); + +#if (CFG_SUPPORT_TRACE_TC4 == 1) + wlanDebugTC4Init(); +#endif + +#if (CFG_SUPPORT_STATISTICS == 1) + wlanWakeStaticsInit(); +#endif + /* Cannot get IO address from interface */ + if (bRet == FALSE) { + DBGLOG(INIT, ERROR, "wlanProbe: glBusInit() fail\n"); + i4Status = -EIO; + eFailReason = BUS_INIT_FAIL; + break; + } + /* 4 <2> Create network device, Adapter, KalInfo, + * prDevHandler(netdev) + */ + prWdev = wlanNetCreate(pvData, pvDriverData); + if (prWdev == NULL) { + DBGLOG(INIT, ERROR, + "wlanProbe: No memory for dev and its private\n"); + i4Status = -ENOMEM; + eFailReason = NET_CREATE_FAIL; + break; + } + /* 4 <2.5> Set the ioaddr to HIF Info */ + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(prWdev->wiphy); + gPrDev = prGlueInfo->prDevHandler; + + /* 4 <4> Setup IRQ */ + prWlandevInfo = &arWlanDevInfo[i4DevIdx]; + + i4Status = glBusSetIrq(prWdev->netdev, NULL, prGlueInfo); + + if (i4Status != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, ERROR, "wlanProbe: Set IRQ error\n"); + eFailReason = BUS_SET_IRQ_FAIL; + break; + } + + prGlueInfo->i4DevIdx = i4DevIdx; + + prAdapter = prGlueInfo->prAdapter; + prWifiVar = &prAdapter->rWifiVar; + + wlanOnPreAdapterStart(prGlueInfo, + prAdapter, + &prRegInfo, + &prChipInfo); + + if (wlanAdapterStart(prAdapter, + prRegInfo, FALSE) != WLAN_STATUS_SUCCESS) + i4Status = -EIO; + + wlanOnPostAdapterStart(prAdapter, prGlueInfo); + + /* kfree(prRegInfo); */ + + if (i4Status < 0) { + eFailReason = ADAPTER_START_FAIL; + break; + } + + wlanOnPreNetRegister(prGlueInfo, prAdapter, prChipInfo, + prWifiVar, FALSE); + + /* 4 <3> Register the card */ + i4DevIdx = wlanNetRegister(prWdev); + if (i4DevIdx < 0) { + i4Status = -ENXIO; + DBGLOG(INIT, ERROR, + "wlanProbe: Cannot register the net_device context to the kernel\n"); + eFailReason = NET_REGISTER_FAIL; + break; + } + + wlanOnPostNetRegister(); + + /* 4 <6> Initialize /proc filesystem */ +#if WLAN_INCLUDE_PROC + i4Status = procCreateFsEntry(prGlueInfo); + if (i4Status < 0) { + DBGLOG(INIT, ERROR, "wlanProbe: init procfs failed\n"); + eFailReason = PROC_INIT_FAIL; + break; + } +#endif /* WLAN_INCLUDE_PROC */ +#if WLAN_INCLUDE_SYS + i4Status = sysCreateFsEntry(prGlueInfo); + if (i4Status < 0) { + DBGLOG(INIT, ERROR, "wlanProbe: init sysfs failed\n"); + eFailReason = PROC_INIT_FAIL; + break; + } +#endif /* WLAN_INCLUDE_SYS */ + +#if CFG_MET_PACKET_TRACE_SUPPORT + kalMetInit(prGlueInfo); +#endif + + kalWlanUeventInit(); + +#if CFG_ENABLE_BT_OVER_WIFI + prGlueInfo->rBowInfo.fgIsNetRegistered = FALSE; + prGlueInfo->rBowInfo.fgIsRegistered = FALSE; + glRegisterAmpc(prGlueInfo); +#endif + +#if (CONFIG_WLAN_SERVICE == 1) + wlanServiceInit(prGlueInfo); +#endif + +#if (CFG_MET_PACKET_TRACE_SUPPORT == 1) + DBGLOG(INIT, TRACE, "init MET procfs...\n"); + i4Status = kalMetInitProcfs(prGlueInfo); + if (i4Status < 0) { + DBGLOG(INIT, ERROR, + "wlanProbe: init MET procfs failed\n"); + eFailReason = FAIL_MET_INIT_PROCFS; + break; + } +#endif + + for (u4Idx = 0; u4Idx < KAL_AIS_NUM; u4Idx++) { + struct FT_IES *prFtIEs = + aisGetFtIe(prAdapter, u4Idx); + + kalMemZero(prFtIEs, + sizeof(*prFtIEs)); + } + + /* Configure 5G band for registered wiphy */ + if (prAdapter->fgEnable5GBand) + prWdev->wiphy->bands[KAL_BAND_5GHZ] = &mtk_band_5ghz; + else + prWdev->wiphy->bands[KAL_BAND_5GHZ] = NULL; + + for (i = 0 ; i < KAL_P2P_NUM; i++) { + if (gprP2pRoleWdev[i] == NULL) + continue; + + if (prAdapter->fgEnable5GBand) + gprP2pRoleWdev[i]->wiphy->bands[KAL_BAND_5GHZ] = + &mtk_band_5ghz; + else + gprP2pRoleWdev[i]->wiphy->bands[KAL_BAND_5GHZ] = + NULL; + } + } while (FALSE); + + if (i4Status == 0 && kalIsResetting()) { + DBGLOG(INIT, WARN, "Fake wlan on success due to reset.\n"); + eFailReason = FAIL_BY_RESET; + i4Status = WLAN_STATUS_FAILURE; + } + + if (i4Status == 0) { + wlanOnWhenProbeSuccess(prGlueInfo, prAdapter, FALSE); + DBGLOG(INIT, INFO, + "wlanProbe: probe success, feature set: 0x%llx, persistNetdev: %d\n", + wlanGetSupportedFeatureSet(prGlueInfo), + CFG_SUPPORT_PERSIST_NETDEV); +#if CFG_MTK_MCIF_WIFI_SUPPORT + mddpNotifyWifiOnEnd(); +#endif + } else { + DBGLOG(INIT, ERROR, "wlanProbe: probe failed, reason:%d\n", + eFailReason); + switch (eFailReason) { + case FAIL_BY_RESET: + case FAIL_MET_INIT_PROCFS: + kalMetRemoveProcfs(); + case PROC_INIT_FAIL: + wlanNetUnregister(prWdev); + /* Unregister notifier callback */ + wlanUnregisterInetAddrNotifier(); + case NET_REGISTER_FAIL: + set_bit(GLUE_FLAG_HALT_BIT, &prGlueInfo->ulFlag); +#if CFG_SUPPORT_MULTITHREAD + wake_up_interruptible(&prGlueInfo->waitq_hif); + wait_for_completion_interruptible( + &prGlueInfo->rHifHaltComp); + wake_up_interruptible(&prGlueInfo->waitq_rx); + wait_for_completion_interruptible( + &prGlueInfo->rRxHaltComp); +#endif + /* wake up main thread */ + wake_up_interruptible(&prGlueInfo->waitq); + /* wait main thread stops */ + wait_for_completion_interruptible( + &prGlueInfo->rHaltComp); + wlanAdapterStop(prAdapter, FALSE); + /* fallthrough */ + case ADAPTER_START_FAIL: + glBusFreeIrq(prWdev->netdev, + *((struct GLUE_INFO **) + netdev_priv(prWdev->netdev))); + /* fallthrough */ + case BUS_SET_IRQ_FAIL: + wlanWakeLockUninit(prGlueInfo); + wlanNetDestroy(prWdev); + /* prGlueInfo->prAdapter is released in + * wlanNetDestroy + */ + /* Set NULL value for local prAdapter as well */ + prAdapter = NULL; + break; + case NET_CREATE_FAIL: + break; + case BUS_INIT_FAIL: + break; + default: + break; + } + } + return i4Status; +} /* end of wlanProbe() */ + +void +wlanOffNotifyCfg80211Disconnect(IN struct GLUE_INFO *prGlueInfo) +{ + uint32_t u4Idx = 0; + u_int8_t bNotify = FALSE; + + DBGLOG(INIT, TRACE, "start.\n"); + + for (u4Idx = 0; u4Idx < KAL_AIS_NUM; u4Idx++) { + if (kalGetMediaStateIndicated(prGlueInfo, + u4Idx) == + MEDIA_STATE_CONNECTED) { + struct net_device *prDevHandler = + wlanGetNetDev(prGlueInfo, u4Idx); + if (!prDevHandler) + continue; +#if CFG_WPS_DISCONNECT || (KERNEL_VERSION(4, 2, 0) <= CFG80211_VERSION_CODE) + cfg80211_disconnected( + prDevHandler, 0, NULL, 0, + TRUE, GFP_KERNEL); +#else + cfg80211_disconnected( + prDevHandler, 0, NULL, 0, + GFP_KERNEL); +#endif + bNotify = TRUE; + } + } + if (bNotify) + kalMsleep(500); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief A method to stop driver operation and release all resources. Following + * this call, no frame should go up or down through this interface. + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +static void wlanRemove(void) +{ + struct net_device *prDev = NULL; + struct WLANDEV_INFO *prWlandevInfo = NULL; + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + u_int8_t fgResult = FALSE; + + DBGLOG(INIT, INFO, "Remove wlan!\n"); + + kalSetHalted(TRUE); + + /*reset NVRAM State to ready for the next wifi-no*/ + if (g_NvramFsm == NVRAM_STATE_SEND_TO_FW) + g_NvramFsm = NVRAM_STATE_READY; + + +#if CFG_MTK_MCIF_WIFI_SUPPORT + mddpNotifyWifiOffStart(); +#endif + +#if CFG_CHIP_RESET_SUPPORT + /* During chip reset, use simplify remove flow first + * if anything goes wrong in wlanOffAtReset then goes to normal flow + */ + if (fgSimplifyResetFlow) { + if (wlanOffAtReset() == WLAN_STATUS_SUCCESS) { +#if CFG_MTK_MCIF_WIFI_SUPPORT + mddpNotifyWifiOffEnd(); +#endif + return; + } + } +#endif + + /* 4 <0> Sanity check */ + ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES); + if (u4WlanDevNum == 0) { + DBGLOG(INIT, ERROR, "u4WlanDevNum = 0\n"); + return; + } +#if (CFG_ENABLE_WIFI_DIRECT && CFG_MTK_ANDROID_WMT) + register_set_p2p_mode_handler(NULL); +#endif + if (u4WlanDevNum > 0 + && u4WlanDevNum <= CFG_MAX_WLAN_DEVICES) { + prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev; + prWlandevInfo = &arWlanDevInfo[u4WlanDevNum - 1]; + } + + ASSERT(prDev); + if (prDev == NULL) { + DBGLOG(INIT, ERROR, "prDev is NULL\n"); + return; + } + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prDev)); + ASSERT(prGlueInfo); + if (prGlueInfo == NULL) { + DBGLOG(INIT, INFO, "prGlueInfo is NULL\n"); + wlanFreeNetDev(); + return; + } + +#if (CONFIG_WLAN_SERVICE == 1) + wlanServiceExit(prGlueInfo); +#endif + + /* to avoid that wpa_supplicant/hostapd triogger new cfg80211 command */ + prGlueInfo->u4ReadyFlag = 0; +#if CFG_MTK_ANDROID_WMT + update_driver_loaded_status(prGlueInfo->u4ReadyFlag); +#endif + + /* Have tried to do scan done here, but the exception occurs for */ + /* the P2P scan. Keep the original design that scan done in the */ + /* p2pStop/wlanStop. */ + +#if WLAN_INCLUDE_PROC + procRemoveProcfs(); +#endif /* WLAN_INCLUDE_PROC */ +#if WLAN_INCLUDE_SYS + sysRemoveSysfs(); +#endif /* WLAN_INCLUDE_SYS */ + + prAdapter = prGlueInfo->prAdapter; + kalPerMonDestroy(prGlueInfo); + + /* Unregister notifier callback */ + wlanUnregisterInetAddrNotifier(); + + /*backup EM mode cfg setting*/ + wlanBackupEmCfgSetting(prAdapter); + + /* complete possible pending oid, which may block wlanRemove some time + * and then whole chip reset may failed + */ + if (kalIsResetting()) + wlanReleasePendingOid(prGlueInfo->prAdapter, 1); + + nicSerDeInit(prGlueInfo->prAdapter); + +#if CFG_ENABLE_BT_OVER_WIFI + if (prGlueInfo->rBowInfo.fgIsNetRegistered) { + bowNotifyAllLinkDisconnected(prGlueInfo->prAdapter); + /* wait 300ms for BoW module to send deauth */ + kalMsleep(300); + } +#endif + + wlanOffNotifyCfg80211Disconnect(prGlueInfo); + + /* 20150205 work queue for sched_scan */ + + flush_delayed_work(&sched_workq); + + down(&g_halt_sem); + g_u4HaltFlag = 1; + up(&g_halt_sem); + + /* 4 <2> Mark HALT, notify main thread to stop, and clean up queued + * requests + */ + set_bit(GLUE_FLAG_HALT_BIT, &prGlueInfo->ulFlag); + + /* Stop works */ + flush_work(&prGlueInfo->rTxMsduFreeWork); + cancel_delayed_work_sync(&prGlueInfo->rRxPktDeAggWork); + + wlanOffStopWlanThreads(prGlueInfo); + + if (HAL_IS_TX_DIRECT(prAdapter)) { + if (prAdapter->fgTxDirectInited) { + del_timer_sync(&prAdapter->rTxDirectSkbTimer); + del_timer_sync(&prAdapter->rTxDirectHifTimer); + } + } + + /* Destroy wakelock */ + wlanWakeLockUninit(prGlueInfo); + + kalMemSet(&(prGlueInfo->prAdapter->rWlanInfo), 0, + sizeof(struct WLAN_INFO)); + +#if CFG_ENABLE_WIFI_DIRECT + if (prGlueInfo->prAdapter->fgIsP2PRegistered) { + DBGLOG(INIT, INFO, "p2pNetUnregister...\n"); + p2pNetUnregister(prGlueInfo, FALSE); + DBGLOG(INIT, INFO, "p2pRemove...\n"); + /*p2pRemove must before wlanAdapterStop */ + p2pRemove(prGlueInfo); + } +#endif + +#if CFG_ENABLE_BT_OVER_WIFI + if (prGlueInfo->rBowInfo.fgIsRegistered) + glUnregisterAmpc(prGlueInfo); +#endif + +#if (CFG_MET_PACKET_TRACE_SUPPORT == 1) + kalMetRemoveProcfs(); +#endif + + kalWlanUeventDeinit(); + +#if CFG_MET_TAG_SUPPORT + if (GL_MET_TAG_UNINIT() != 0) + DBGLOG(INIT, ERROR, "MET_TAG_UNINIT error!\n"); +#endif + + /* 4 <4> wlanAdapterStop */ +#if CFG_SUPPORT_AGPS_ASSIST + kalIndicateAgpsNotify(prAdapter, AGPS_EVENT_WLAN_OFF, NULL, + 0); +#endif + + wlanAdapterStop(prAdapter, FALSE); + + HAL_LP_OWN_SET(prAdapter, &fgResult); + DBGLOG(INIT, INFO, "HAL_LP_OWN_SET(%d)\n", + (uint32_t) fgResult); + + /* 4 Stopping handling interrupt and free IRQ */ + glBusFreeIrq(prDev, prGlueInfo); + + /* 4 <5> Release the Bus */ + glBusRelease(prDev); + +#if (CFG_SUPPORT_TRACE_TC4 == 1) + wlanDebugTC4Uninit(); +#endif + +#if (CFG_SUPPORT_STATISTICS == 1) + wlanWakeStaticsUninit(); +#endif + + /* 4 <6> Unregister the card */ + wlanNetUnregister(prDev->ieee80211_ptr); + + flush_delayed_work(&workq); + + /* 4 <7> Destroy the device */ + wlanNetDestroy(prDev->ieee80211_ptr); + prDev = NULL; + + tasklet_kill(&prGlueInfo->rTxCompleteTask); + tasklet_kill(&prGlueInfo->rRxTask); + + /* 4 <8> Unregister early suspend callback */ +#if CFG_ENABLE_EARLY_SUSPEND + glUnregisterEarlySuspend(&wlan_early_suspend_desc); +#endif + +#if !CFG_SUPPORT_PERSIST_NETDEV + { + uint32_t u4Idx = 0; + + for (u4Idx = 0; u4Idx < KAL_AIS_NUM; u4Idx++) { + if (gprWdev[u4Idx] && gprWdev[u4Idx]->netdev) + gprWdev[u4Idx]->netdev = NULL; + } + } +#endif + +#if CFG_CHIP_RESET_SUPPORT + fgIsResetting = FALSE; +#if (CFG_SUPPORT_CONNINFRA == 1) + update_driver_reset_status(fgIsResetting); +#endif +#endif + +#if CFG_MTK_MCIF_WIFI_SUPPORT + mddpNotifyWifiOffEnd(); +#endif +} /* end of wlanRemove() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Driver entry point when the driver is configured as a Linux Module, + * and is called once at module load time, by the user-level modutils + * application: insmod or modprobe. + * + * \retval 0 Success + */ +/*----------------------------------------------------------------------------*/ +/* 1 Module Entry Point */ +static int initWlan(void) +{ + int ret = 0; + struct GLUE_INFO *prGlueInfo = NULL; + +#if defined(UT_TEST_MODE) && defined(CFG_BUILD_X86_PLATFORM) + /* Refer 6765 dts setting */ + char *ptr = NULL; + + gConEmiSize = 0x400000; + ptr = kmalloc(gConEmiSize, GFP_KERNEL); + if (!ptr) { + DBGLOG(INIT, INFO, + "initWlan try to allocate 0x%x bytes memory error\n", + gConEmiSize); + return -EINVAL; + } + memset(ptr, 0, gConEmiSize); + gConEmiPhyBase = (phys_addr_t)ptr; +#endif + + gConEmiPhyBaseFinal = gConEmiPhyBase; + gConEmiSizeFinal = gConEmiSize; + +#if (CFG_SUPPORT_CONNINFRA == 1) + conninfra_get_phy_addr( + (unsigned int *)&gConEmiPhyBaseFinal, + (unsigned int *)&gConEmiSizeFinal); +#endif + + DBGLOG(INIT, INFO, "initWlan\n"); + +#ifdef CFG_DRIVER_INF_NAME_CHANGE + + if (kalStrLen(gprifnamesta) > CUSTOM_IFNAMESIZ || + kalStrLen(gprifnamep2p) > CUSTOM_IFNAMESIZ || + kalStrLen(gprifnameap) > CUSTOM_IFNAMESIZ) { + DBGLOG(INIT, ERROR, "custom infname len illegal > %d\n", + CUSTOM_IFNAMESIZ); + return -EINVAL; + } + +#endif /* CFG_DRIVER_INF_NAME_CHANGE */ + + wlanDebugInit(); + + /* memory pre-allocation */ +#if CFG_PRE_ALLOCATION_IO_BUFFER + kalInitIOBuffer(TRUE); +#else + kalInitIOBuffer(FALSE); +#endif + + +#if WLAN_INCLUDE_PROC + procInitFs(); +#endif +#if WLAN_INCLUDE_SYS + sysInitFs(); +#endif + + wlanCreateWirelessDevice(); + if (gprWdev[0] == NULL) + return -ENOMEM; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv( + wlanGetWiphy()); + if (gprWdev[0]) { + /* P2PDev and P2PRole[0] share the same Wdev */ + if (glP2pCreateWirelessDevice(prGlueInfo) == TRUE) + gprP2pWdev = gprP2pRoleWdev[0]; + } + gPrDev = NULL; + +#if CFG_MTK_ANDROID_WMT && (CFG_SUPPORT_CONNINFRA == 0) + mtk_wcn_wmt_mpu_lock_aquire(); +#endif + ret = ((glRegisterBus(wlanProbe, + wlanRemove) == WLAN_STATUS_SUCCESS) ? 0 : -EIO); +#ifdef CONFIG_MTK_EMI + /* Set WIFI EMI protection to consys permitted on system boot up */ + kalSetEmiMpuProtection(gConEmiPhyBaseFinal, true); +#endif +#if CFG_MTK_ANDROID_WMT && (CFG_SUPPORT_CONNINFRA == 0) + mtk_wcn_wmt_mpu_lock_release(); +#endif + + if (ret == -EIO) { + kalUninitIOBuffer(); + return ret; + } +#if (CFG_CHIP_RESET_SUPPORT) + glResetInit(prGlueInfo); +#endif + kalFbNotifierReg((struct GLUE_INFO *) wiphy_priv( + wlanGetWiphy())); + wlanRegisterNetdevNotifier(); + +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH + wifi_fwlog_event_func_register(consys_log_event_notification); +#endif + +#if CFG_MTK_MCIF_WIFI_SUPPORT + mddpInit(); +#endif + + g_u4WlanInitFlag = 1; + DBGLOG(INIT, INFO, "initWlan::End\n"); + + return ret; +} /* end of initWlan() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Driver exit point when the driver as a Linux Module is removed. Called + * at module unload time, by the user level modutils application: rmmod. + * This is our last chance to clean up after ourselves. + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +/* 1 Module Leave Point */ +static void exitWlan(void) +{ +#if CFG_SUPPORT_PERSIST_NETDEV + uint32_t u4Idx = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct wiphy *wiphy = NULL; + + wiphy = wlanGetWiphy(); + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + for (u4Idx = 0; u4Idx < KAL_AIS_NUM; u4Idx++) { + if (gprNetdev[u4Idx]) { + wlanClearDevIdx(gprWdev[u4Idx]->netdev); + DBGLOG(INIT, INFO, "Unregister wlan%d netdev start.\n", + u4Idx); + unregister_netdev(gprWdev[u4Idx]->netdev); + DBGLOG(INIT, INFO, "Unregister wlan%d netdev end.\n", + u4Idx); + gprWdev[u4Idx]->netdev = gprNetdev[u4Idx] = NULL; + } + } + + prGlueInfo->fgIsRegistered = FALSE; + + DBGLOG(INIT, INFO, "Free wlan device..\n"); + wlanFreeNetDev(); +#endif + kalFbNotifierUnReg(); + wlanUnregisterNetdevNotifier(); + + /* printk("remove %p\n", wlanRemove); */ +#if CFG_CHIP_RESET_SUPPORT + glResetUninit(); +#endif + + glUnregisterBus(wlanRemove); + + /* free pre-allocated memory */ + kalUninitIOBuffer(); + + /* For single wiphy case, it's hardly to free wdev & wiphy in 2 func. + * So that, use wlanDestroyAllWdev to replace wlanDestroyWirelessDevice + * and glP2pDestroyWirelessDevice. + */ + wlanDestroyAllWdev(); + +#if WLAN_INCLUDE_PROC + procUninitProcFs(); +#endif +#if WLAN_INCLUDE_SYS + sysUninitSysFs(); +#endif +#if defined(UT_TEST_MODE) && defined(CFG_BUILD_X86_PLATFORM) + kfree((const void *)gConEmiPhyBase); +#endif + + g_u4WlanInitFlag = 0; + DBGLOG(INIT, INFO, "exitWlan\n"); + +} /* end of exitWlan() */ + +#if ((MTK_WCN_HIF_SDIO == 1) && (CFG_BUILT_IN_DRIVER == 1)) || \ + ((MTK_WCN_HIF_AXI == 1) && (CFG_BUILT_IN_DRIVER == 1)) + +int mtk_wcn_wlan_gen4_init(void) +{ + return initWlan(); +} +EXPORT_SYMBOL(mtk_wcn_wlan_gen4_init); + +void mtk_wcn_wlan_gen4_exit(void) +{ + return exitWlan(); +} +EXPORT_SYMBOL(mtk_wcn_wlan_gen4_exit); + +#elif ((MTK_WCN_HIF_SDIO == 0) && (CFG_BUILT_IN_DRIVER == 1)) + +device_initcall(initWlan); + +#else + +module_init(initWlan); +module_exit(exitWlan); + +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_kal.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_kal.c new file mode 100644 index 0000000000000000000000000000000000000000..c1698652b969d3315f8161dbcdaffb99478759eb --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_kal.c @@ -0,0 +1,8897 @@ +/******************************************************************************* + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ +/* + * Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux + * /gl_kal.c#10 + */ + +/*! \file gl_kal.c + * \brief GLUE Layer will export the required procedures here for internal + * driver stack. + * + * This file contains all routines which are exported from GLUE Layer to + * internal driver stack. + */ + + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "gl_os.h" +#include "gl_kal.h" +#include "gl_wext.h" +#include "precomp.h" +#include + +#if CFG_SUPPORT_AGPS_ASSIST +#include +#endif + +#if CFG_TC1_FEATURE +#include +#endif + +/* for rps */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* for uevent */ +#include /* for misc_register, and SYNTH_MINOR */ +#include + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +/* the maximum length of a file name */ +#define FILE_NAME_MAX CFG_FW_NAME_MAX_LEN + +/* the maximum number of all possible file name */ +#define FILE_NAME_TOTAL 8 + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ +#if DBG +int allocatedMemSize; +#endif + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ +static void *pvIoBuffer; +static uint32_t pvIoBufferSize; +static uint32_t pvIoBufferUsage; + +static struct KAL_HALT_CTRL_T rHaltCtrl = { + .lock = __SEMAPHORE_INITIALIZER(rHaltCtrl.lock, 1), + .owner = NULL, + .fgHalt = TRUE, + .fgHeldByKalIoctl = FALSE, + .u4HoldStart = 0, +}; +/* framebuffer callback related variable and status flag */ +u_int8_t wlan_fb_power_down = FALSE; + +#if CFG_FORCE_ENABLE_PERF_MONITOR +u_int8_t wlan_perf_monitor_force_enable = TRUE; +#else +u_int8_t wlan_perf_monitor_force_enable = FALSE; +#endif + +static struct notifier_block wlan_fb_notifier; +void *wlan_fb_notifier_priv_data; + +static struct miscdevice wlan_object; +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +static void kalDumpHifStats(IN struct ADAPTER *prAdapter); +static uint32_t kalPerMonUpdate(IN struct ADAPTER *prAdapter); + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +#if CFG_ENABLE_FW_DOWNLOAD + +#if (defined(CONFIG_UIDGID_STRICT_TYPE_CHECKS) || \ + (KERNEL_VERSION(3, 14, 0) <= LINUX_VERSION_CODE)) +#define KUIDT_VALUE(v) (v.val) +#define KGIDT_VALUE(v) (v.val) +#else +#define KUIDT_VALUE(v) v +#define KGIDT_VALUE(v) v +#endif + +const struct firmware *fw_entry; + +/* Default */ +static uint8_t *apucFwName[] = { + (uint8_t *) CFG_FW_FILENAME "_MT", + (uint8_t *) CFG_FW_FILENAME "_", + NULL +}; + +static uint8_t *apucCr4FwName[] = { + (uint8_t *) CFG_CR4_FW_FILENAME "_MT", + NULL +}; + +#if CFG_ASSERT_DUMP +/* Core dump debug usage */ +#if MTK_WCN_HIF_SDIO +uint8_t *apucCorDumpN9FileName = + "/data/misc/wifi/FW_DUMP_N9"; +uint8_t *apucCorDumpCr4FileName = + "/data/misc/wifi/FW_DUMP_Cr4"; +#else +uint8_t *apucCorDumpN9FileName = "/tmp/FW_DUMP_N9"; +uint8_t *apucCorDumpCr4FileName = "/tmp/FW_DUMP_Cr4"; +#endif +#endif + +#if !CONFIG_WLAN_DRV_BUILD_IN +/*----------------------------------------------------------------------------*/ +/*! + * \brief To leverage systrace, use the same name, i.e. tracing_mark_write, + * which ftrace would write when systrace writes msg to + * /sys/kernel/debug/tracing/trace_marker with trace_options enabling + * print-parent + * + */ +/*----------------------------------------------------------------------------*/ +void tracing_mark_write(const char *fmt, ...) +{ + const uint32_t BUFFER_SIZE = 1024; + va_list ap; + char buf[BUFFER_SIZE]; + + if ((aucDebugModule[DBG_TRACE_IDX] & DBG_CLASS_TEMP) == 0) + return; + + va_start(ap, fmt); + vsnprintf(buf, BUFFER_SIZE, fmt, ap); + buf[BUFFER_SIZE - 1] = '\0'; + va_end(ap); + + trace_printk("%s", buf); +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is provided by GLUE Layer for internal driver stack to + * open firmware image in kernel space + * + * \param[in] prGlueInfo Pointer of GLUE Data Structure + * + * \retval WLAN_STATUS_SUCCESS. + * \retval WLAN_STATUS_FAILURE. + * + */ +/*----------------------------------------------------------------------------*/ +uint32_t kalFirmwareOpen(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t **apucNameTable) +{ + uint8_t ucNameIdx; + /* PPUINT_8 apucNameTable; */ + uint8_t ucCurEcoVer = wlanGetEcoVersion( + prGlueInfo->prAdapter); + u_int8_t fgResult = FALSE; + int ret; + + /* Try to open FW binary */ + for (ucNameIdx = 0; apucNameTable[ucNameIdx]; ucNameIdx++) { + /* + * Driver support request_firmware() to get files + * Android path: "/etc/firmware", "/vendor/firmware", + * "/firmware/image" + * Linux path: "/lib/firmware", "/lib/firmware/update" + */ + ret = _kalRequestFirmware(&fw_entry, apucNameTable[ucNameIdx], + prGlueInfo->prDev); + + if (ret) { + DBGLOG(INIT, TRACE, + "Request FW image: %s failed, errno[%d]\n", + apucNameTable[ucNameIdx], fgResult); + continue; + } else { + DBGLOG(INIT, INFO, "Request FW image: %s done\n", + apucNameTable[ucNameIdx]); + fgResult = TRUE; + break; + } + } + + + /* Check result */ + if (!fgResult) + goto error_open; + + + return WLAN_STATUS_SUCCESS; + +error_open: + DBGLOG(INIT, ERROR, + "Request FW image failed! Cur ECO Ver[E%u]\n", + ucCurEcoVer); + + return WLAN_STATUS_FAILURE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is provided by GLUE Layer for internal driver stack to + * release firmware image in kernel space + * + * \param[in] prGlueInfo Pointer of GLUE Data Structure + * + * \retval WLAN_STATUS_SUCCESS. + * \retval WLAN_STATUS_FAILURE. + * + */ +/*----------------------------------------------------------------------------*/ +uint32_t kalFirmwareClose(IN struct GLUE_INFO *prGlueInfo) +{ + release_firmware(fw_entry); + + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is provided by GLUE Layer for internal driver stack to + * load firmware image in kernel space + * + * \param[in] prGlueInfo Pointer of GLUE Data Structure + * + * \retval WLAN_STATUS_SUCCESS. + * \retval WLAN_STATUS_FAILURE. + * + */ +/*----------------------------------------------------------------------------*/ +uint32_t kalFirmwareLoad(IN struct GLUE_INFO *prGlueInfo, + OUT void *prBuf, IN uint32_t u4Offset, + OUT uint32_t *pu4Size) +{ + ASSERT(prGlueInfo); + ASSERT(pu4Size); + ASSERT(prBuf); + + if ((fw_entry == NULL) || (fw_entry->size == 0) + || (fw_entry->data == NULL)) { + goto error_read; + } else { + memcpy(prBuf, fw_entry->data, fw_entry->size); + *pu4Size = fw_entry->size; + } + + return WLAN_STATUS_SUCCESS; + +error_read: + return WLAN_STATUS_FAILURE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is provided by GLUE Layer for internal driver stack to + * query firmware image size in kernel space + * + * \param[in] prGlueInfo Pointer of GLUE Data Structure + * + * \retval WLAN_STATUS_SUCCESS. + * \retval WLAN_STATUS_FAILURE. + * + */ +/*----------------------------------------------------------------------------*/ + +uint32_t kalFirmwareSize(IN struct GLUE_INFO *prGlueInfo, + OUT uint32_t *pu4Size) +{ + ASSERT(prGlueInfo); + ASSERT(pu4Size); + + *pu4Size = fw_entry->size; + + return WLAN_STATUS_SUCCESS; +} + +void +kalConstructDefaultFirmwarePrio(struct GLUE_INFO + *prGlueInfo, uint8_t **apucNameTable, + uint8_t **apucName, uint8_t *pucNameIdx, + uint8_t ucMaxNameIdx) +{ + struct mt66xx_chip_info *prChipInfo = + prGlueInfo->prAdapter->chip_info; + uint32_t chip_id = prChipInfo->chip_id; + uint8_t sub_idx = 0; + int ret = 0; + + for (sub_idx = 0; apucNameTable[sub_idx]; sub_idx++) { + if ((*pucNameIdx + 3) >= ucMaxNameIdx) { + /* the table is not large enough */ + DBGLOG(INIT, ERROR, + "kalFirmwareImageMapping >> file name array is not enough.\n"); + ASSERT(0); + continue; + } + + /* Type 1. WIFI_RAM_CODE_MTxxxx */ + ret = kalSnprintf(*(apucName + (*pucNameIdx)), FILE_NAME_MAX, + "%s%x", apucNameTable[sub_idx], chip_id); + if (ret >= 0 && ret < CFG_FW_NAME_MAX_LEN) + (*pucNameIdx) += 1; + else + DBGLOG(INIT, ERROR, + "[%u] kalSnprintf failed, ret: %d\n", + __LINE__, ret); + + /* Type 2. WIFI_RAM_CODE_MTxxxx.bin */ + ret = kalSnprintf(*(apucName + (*pucNameIdx)), FILE_NAME_MAX, + "%s%x.bin", + apucNameTable[sub_idx], chip_id); + if (ret >= 0 && ret < CFG_FW_NAME_MAX_LEN) + (*pucNameIdx) += 1; + else + DBGLOG(INIT, ERROR, + "[%u] kalSnprintf failed, ret: %d\n", + __LINE__, ret); + + /* Type 3. WIFI_RAM_CODE_MTxxxx_Ex */ + ret = kalSnprintf(*(apucName + (*pucNameIdx)), FILE_NAME_MAX, + "%s%x_E%u", + apucNameTable[sub_idx], chip_id, + wlanGetEcoVersion(prGlueInfo->prAdapter)); + if (ret >= 0 && ret < CFG_FW_NAME_MAX_LEN) + (*pucNameIdx) += 1; + else + DBGLOG(INIT, ERROR, + "[%u] kalSnprintf failed, ret: %d\n", + __LINE__, ret); + + /* Type 4. WIFI_RAM_CODE_MTxxxx_Ex.bin */ + ret = kalSnprintf(*(apucName + (*pucNameIdx)), FILE_NAME_MAX, + "%s%x_E%u.bin", + apucNameTable[sub_idx], chip_id, + wlanGetEcoVersion(prGlueInfo->prAdapter)); + if (ret >= 0 && ret < CFG_FW_NAME_MAX_LEN) + (*pucNameIdx) += 1; + else + DBGLOG(INIT, ERROR, + "[%u] kalSnprintf failed, ret: %d\n", + __LINE__, ret); + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used to load firmware image + * + * \param pvGlueInfo Pointer of GLUE Data Structure + * \param ppvMapFileBuf Pointer of pointer to memory-mapped firmware image + * \param pu4FileLength File length and memory mapped length as well + * + * \retval Map File Handle, used for unammping + */ +/*----------------------------------------------------------------------------*/ + +void * +kalFirmwareImageMapping(IN struct GLUE_INFO *prGlueInfo, + OUT void **ppvMapFileBuf, OUT uint32_t *pu4FileLength, + IN enum ENUM_IMG_DL_IDX_T eDlIdx) +{ + uint8_t **apucNameTable = NULL; + uint8_t *apucName[FILE_NAME_TOTAL + + 1]; /* extra +1, for the purpose of + * detecting the end of the array + */ + uint8_t idx = 0, max_idx, + aucNameBody[FILE_NAME_TOTAL][FILE_NAME_MAX], sub_idx = 0; + struct mt66xx_chip_info *prChipInfo = + prGlueInfo->prAdapter->chip_info; + uint32_t chip_id = prChipInfo->chip_id; + + DEBUGFUNC("kalFirmwareImageMapping"); + + ASSERT(prGlueInfo); + ASSERT(ppvMapFileBuf); + ASSERT(pu4FileLength); + + *ppvMapFileBuf = NULL; + *pu4FileLength = 0; + + do { + /* <0.0> Get FW name prefix table */ + switch (eDlIdx) { + case IMG_DL_IDX_N9_FW: + apucNameTable = apucFwName; + break; + + case IMG_DL_IDX_CR4_FW: + apucNameTable = apucCr4FwName; + break; + + case IMG_DL_IDX_PATCH: + break; + + default: + ASSERT(0); + break; + } + + /* <0.2> Construct FW name */ + memset(apucName, 0, sizeof(apucName)); + + /* magic number 1: reservation for detection + * of the end of the array + */ + max_idx = (sizeof(apucName) / sizeof(uint8_t *)) - 1; + + idx = 0; + apucName[idx] = (uint8_t *)(aucNameBody + idx); + + if (eDlIdx == IMG_DL_IDX_PATCH) { + /* construct the file name for patch */ + + /* mtxxxx_patch_ex_hdr.bin*/ + if (prChipInfo->fw_dl_ops->constructPatchName) + prChipInfo->fw_dl_ops->constructPatchName( + prGlueInfo, apucName, &idx); + else + kalSnprintf(apucName[idx], FILE_NAME_MAX, + "mt%x_patch_e%x_hdr.bin", chip_id, + wlanGetEcoVersion( + prGlueInfo->prAdapter)); + idx += 1; + } else { + for (sub_idx = 0; sub_idx < max_idx; sub_idx++) + apucName[sub_idx] = + (uint8_t *)(aucNameBody + sub_idx); + + if (prChipInfo->fw_dl_ops->constructFirmwarePrio) + prChipInfo->fw_dl_ops->constructFirmwarePrio( + prGlueInfo, apucNameTable, apucName, + &idx, max_idx); + else + kalConstructDefaultFirmwarePrio( + prGlueInfo, apucNameTable, apucName, + &idx, max_idx); + } + + /* let the last pointer point to NULL + * so that we can detect the end of the array in + * kalFirmwareOpen(). + */ + apucName[idx] = NULL; + + apucNameTable = apucName; + + /* <1> Open firmware */ + if (kalFirmwareOpen(prGlueInfo, + apucNameTable) != WLAN_STATUS_SUCCESS) + break; + { + uint32_t u4FwSize = 0; + void *prFwBuffer = NULL; + /* <2> Query firmare size */ + kalFirmwareSize(prGlueInfo, &u4FwSize); + /* <3> Use vmalloc for allocating large memory trunk */ + prFwBuffer = vmalloc(ALIGN_4(u4FwSize)); + if (!prFwBuffer) { + DBGLOG(INIT, ERROR, "vmalloc(%u) failed\n", + ALIGN_4(u4FwSize)); + kalFirmwareClose(prGlueInfo); + break; + } + /* <4> Load image binary into buffer */ + if (kalFirmwareLoad(prGlueInfo, prFwBuffer, 0, + &u4FwSize) != WLAN_STATUS_SUCCESS) { + vfree(prFwBuffer); + kalFirmwareClose(prGlueInfo); + break; + } + /* <5> write back info */ + *pu4FileLength = u4FwSize; + *ppvMapFileBuf = prFwBuffer; + + return prFwBuffer; + } + } while (FALSE); + + return NULL; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used to unload firmware image mapped memory + * + * \param pvGlueInfo Pointer of GLUE Data Structure + * \param pvFwHandle Pointer to mapping handle + * \param pvMapFileBuf Pointer to memory-mapped firmware image + * + * \retval none + */ +/*----------------------------------------------------------------------------*/ + +void kalFirmwareImageUnmapping(IN struct GLUE_INFO + *prGlueInfo, IN void *prFwHandle, IN void *pvMapFileBuf) +{ + DEBUGFUNC("kalFirmwareImageUnmapping"); + + ASSERT(prGlueInfo); + + /* pvMapFileBuf might be NULL when file doesn't exist */ + if (pvMapFileBuf) + vfree(pvMapFileBuf); + + kalFirmwareClose(prGlueInfo); +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is provided by GLUE Layer for internal driver stack to + * acquire OS SPIN_LOCK. + * + * \param[in] prGlueInfo Pointer of GLUE Data Structure + * \param[in] rLockCategory Specify which SPIN_LOCK + * \param[out] pu4Flags Pointer of a variable for saving IRQ flags + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void kalAcquireSpinLock(IN struct GLUE_INFO *prGlueInfo, + IN enum ENUM_SPIN_LOCK_CATEGORY_E rLockCategory, + OUT unsigned long *plFlags) +{ + unsigned long ulFlags = 0; + + ASSERT(prGlueInfo); + ASSERT(plFlags); + + if (rLockCategory < SPIN_LOCK_NUM) { + /*DBGLOG(INIT, LOUD, "SPIN_LOCK[%u] Acq\n", rLockCategory);*/ +#if CFG_USE_SPIN_LOCK_BOTTOM_HALF + spin_lock_bh(&prGlueInfo->rSpinLock[rLockCategory]); +#else /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */ + spin_lock_irqsave(&prGlueInfo->rSpinLock[rLockCategory], + ulFlags); +#endif /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */ + + *plFlags = ulFlags; + + /*DBGLOG(INIT, LOUD, "SPIN_LOCK[%u] Acqed\n", rLockCategory);*/ + } + +} /* end of kalAcquireSpinLock() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is provided by GLUE Layer for internal driver stack to + * release OS SPIN_LOCK. + * + * \param[in] prGlueInfo Pointer of GLUE Data Structure + * \param[in] rLockCategory Specify which SPIN_LOCK + * \param[in] u4Flags Saved IRQ flags + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void kalReleaseSpinLock(IN struct GLUE_INFO *prGlueInfo, + IN enum ENUM_SPIN_LOCK_CATEGORY_E rLockCategory, + IN unsigned long ulFlags) +{ + ASSERT(prGlueInfo); + + if (rLockCategory < SPIN_LOCK_NUM) { + +#if CFG_USE_SPIN_LOCK_BOTTOM_HALF + spin_unlock_bh(&prGlueInfo->rSpinLock[rLockCategory]); +#else /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */ + spin_unlock_irqrestore( + &prGlueInfo->rSpinLock[rLockCategory], ulFlags); +#endif /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */ + /* DBGLOG(INIT, LOUD, "SPIN_UNLOCK[%u]\n", rLockCategory); */ + } + +} /* end of kalReleaseSpinLock() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is provided by GLUE Layer for internal driver stack to + * acquire OS MUTEX. + * + * \param[in] prGlueInfo Pointer of GLUE Data Structure + * \param[in] rMutexCategory Specify which MUTEX + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void kalAcquireMutex(IN struct GLUE_INFO *prGlueInfo, + IN enum ENUM_MUTEX_CATEGORY_E rMutexCategory) +{ + ASSERT(prGlueInfo); + + if (rMutexCategory < MUTEX_NUM) { + DBGLOG(INIT, TEMP, + "MUTEX_LOCK[%u] Try to acquire\n", rMutexCategory); + mutex_lock(&prGlueInfo->arMutex[rMutexCategory]); + DBGLOG(INIT, TEMP, "MUTEX_LOCK[%u] Acquired\n", rMutexCategory); + } + +} /* end of kalAcquireMutex() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is provided by GLUE Layer for internal driver stack to + * release OS MUTEX. + * + * \param[in] prGlueInfo Pointer of GLUE Data Structure + * \param[in] rMutexCategory Specify which MUTEX + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void kalReleaseMutex(IN struct GLUE_INFO *prGlueInfo, + IN enum ENUM_MUTEX_CATEGORY_E rMutexCategory) +{ + ASSERT(prGlueInfo); + + if (rMutexCategory < MUTEX_NUM) { + mutex_unlock(&prGlueInfo->arMutex[rMutexCategory]); + DBGLOG(INIT, TEMP, "MUTEX_UNLOCK[%u]\n", rMutexCategory); + } + +} /* end of kalReleaseMutex() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is provided by GLUE Layer for internal driver stack to + * update current MAC address. + * + * \param[in] prGlueInfo Pointer of GLUE Data Structure + * \param[in] pucMacAddr Pointer of current MAC address + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void kalUpdateMACAddress(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t *pucMacAddr) +{ + ASSERT(prGlueInfo); + ASSERT(pucMacAddr); + + DBGLOG(INIT, INFO, + MACSTR ", " MACSTR ".\n", + prGlueInfo->prDevHandler->dev_addr, + MAC2STR(pucMacAddr)); + + if (UNEQUAL_MAC_ADDR(prGlueInfo->prDevHandler->dev_addr, + pucMacAddr)) + memcpy(prGlueInfo->prDevHandler->dev_addr, pucMacAddr, + PARAM_MAC_ADDR_LEN); +} + +#if CFG_TCP_IP_CHKSUM_OFFLOAD +/*----------------------------------------------------------------------------*/ +/*! + * \brief To query the packet information for offload related parameters. + * + * \param[in] pvPacket Pointer to the packet descriptor. + * \param[in] pucFlag Points to the offload related parameter. + * + * \return (none) + * + */ +/*----------------------------------------------------------------------------*/ +void kalQueryTxChksumOffloadParam(IN void *pvPacket, + OUT uint8_t *pucFlag) +{ + struct sk_buff *skb = (struct sk_buff *)pvPacket; + uint8_t ucFlag = 0; + + ASSERT(pvPacket); + ASSERT(pucFlag); + + if (skb->ip_summed == CHECKSUM_PARTIAL) { +#if DBG + /* Kevin: do double check, we can remove this part in Normal + * Driver. + * Because we register NIC feature with NETIF_F_IP_CSUM for + * MT5912B MAC, so we'll process IP packet only. + */ + if (skb->protocol != htons(ETH_P_IP)) { + /* printk("Wrong skb->protocol( = %08x) for TX Checksum + * Offload.\n", skb->protocol); + */ + } else +#endif + ucFlag |= (TX_CS_IP_GEN | TX_CS_TCP_UDP_GEN); + } + + *pucFlag = ucFlag; + +} /* kalQueryChksumOffloadParam */ + +/* 4 2007/10/8, mikewu, this is rewritten by Mike */ +/*----------------------------------------------------------------------------*/ +/*! + * \brief To update the checksum offload status to the packet to be indicated to + * OS. + * + * \param[in] pvPacket Pointer to the packet descriptor. + * \param[in] pucFlag Points to the offload related parameter. + * + * \return (none) + * + */ +/*----------------------------------------------------------------------------*/ +void kalUpdateRxCSUMOffloadParam(IN void *pvPacket, + IN enum ENUM_CSUM_RESULT aeCSUM[]) +{ + struct sk_buff *skb = (struct sk_buff *)pvPacket; + + ASSERT(pvPacket); + + if ((aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_SUCCESS + || aeCSUM[CSUM_TYPE_IPV6] == CSUM_RES_SUCCESS) + && ((aeCSUM[CSUM_TYPE_TCP] == CSUM_RES_SUCCESS) + || (aeCSUM[CSUM_TYPE_UDP] == CSUM_RES_SUCCESS))) { + skb->ip_summed = CHECKSUM_UNNECESSARY; + } else { + skb->ip_summed = CHECKSUM_NONE; +#if DBG + if (aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_NONE + && aeCSUM[CSUM_TYPE_IPV6] == CSUM_RES_NONE) + DBGLOG(RX, TRACE, "RX: \"non-IPv4/IPv6\" Packet\n"); + else if (aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_FAILED) + DBGLOG(RX, TRACE, "RX: \"bad IP Checksum\" Packet\n"); + else if (aeCSUM[CSUM_TYPE_TCP] == CSUM_RES_FAILED) + DBGLOG(RX, TRACE, "RX: \"bad TCP Checksum\" Packet\n"); + else if (aeCSUM[CSUM_TYPE_UDP] == CSUM_RES_FAILED) + DBGLOG(RX, TRACE, "RX: \"bad UDP Checksum\" Packet\n"); + +#endif + } + +} /* kalUpdateRxCSUMOffloadParam */ +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is called to free packet allocated from kalPacketAlloc. + * + * \param[in] prGlueInfo Pointer of GLUE Data Structure + * \param[in] pvPacket Pointer of the packet descriptor + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void kalPacketFree(IN struct GLUE_INFO *prGlueInfo, + IN void *pvPacket) +{ + dev_kfree_skb((struct sk_buff *)pvPacket); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Only handles driver own creating packet (coalescing buffer). + * + * \param prGlueInfo Pointer of GLUE Data Structure + * \param u4Size Pointer of Packet Handle + * \param ppucData Status Code for OS upper layer + * + * \return NULL: Failed to allocate skb, Not NULL get skb + */ +/*----------------------------------------------------------------------------*/ +void *kalPacketAlloc(IN struct GLUE_INFO *prGlueInfo, + IN uint32_t u4Size, OUT uint8_t **ppucData) +{ + struct mt66xx_chip_info *prChipInfo; + struct sk_buff *prSkb; + uint32_t u4TxHeadRoomSize; + + prChipInfo = prGlueInfo->prAdapter->chip_info; + u4TxHeadRoomSize = NIC_TX_DESC_AND_PADDING_LENGTH + + prChipInfo->txd_append_size; + + if (in_interrupt()) + prSkb = __dev_alloc_skb(u4Size + u4TxHeadRoomSize, + GFP_ATOMIC | __GFP_NOWARN); + else + prSkb = __dev_alloc_skb(u4Size + u4TxHeadRoomSize, + GFP_KERNEL); + + if (prSkb) { + skb_reserve(prSkb, u4TxHeadRoomSize); + + *ppucData = (uint8_t *) (prSkb->data); + + kalResetPacket(prGlueInfo, (void *) prSkb); + } +#if DBG + { + uint32_t *pu4Head = (uint32_t *) &prSkb->cb[0]; + *pu4Head = (uint32_t) prSkb->head; + DBGLOG(RX, TRACE, "prSkb->head = %#lx, prSkb->cb = %#lx\n", + (uint32_t) prSkb->head, *pu4Head); + } +#endif + return (void *) prSkb; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Only handles driver own creating packet (coalescing buffer). + * + * \param prGlueInfo Pointer of GLUE Data Structure + * \param u4Size Pointer of Packet Handle + * \param ppucData Status Code for OS upper layer + * + * \return NULL: Failed to allocate skb, Not NULL get skb + */ +/*----------------------------------------------------------------------------*/ +void *kalPacketAllocWithHeadroom(IN struct GLUE_INFO + *prGlueInfo, IN uint32_t u4Size, OUT uint8_t **ppucData) +{ + struct sk_buff *prSkb = dev_alloc_skb(u4Size); + + if (!prSkb) { + DBGLOG(TX, WARN, "alloc skb failed\n"); + return NULL; + } + + /* + * Reserve NIC_TX_HEAD_ROOM as this skb + * is allocated by driver instead of kernel. + */ + skb_reserve(prSkb, NIC_TX_HEAD_ROOM); + + *ppucData = (uint8_t *) (prSkb->data); + + kalResetPacket(prGlueInfo, (void *) prSkb); +#if DBG + { + uint32_t *pu4Head = (uint32_t *) &prSkb->cb[0]; + *pu4Head = (uint32_t) prSkb->head; + DBGLOG(RX, TRACE, "prSkb->head = %#lx, prSkb->cb = %#lx\n", + (uint32_t) prSkb->head, *pu4Head); + } +#endif + return (void *) prSkb; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Process the received packet for indicating to OS. + * + * \param[in] prGlueInfo Pointer to the Adapter structure. + * \param[in] pvPacket Pointer of the packet descriptor + * \param[in] pucPacketStart The starting address of the buffer of Rx packet. + * \param[in] u4PacketLen The packet length. + * \param[in] pfgIsRetain Is the packet to be retained. + * \param[in] aerCSUM The result of TCP/ IP checksum offload. + * + * \retval WLAN_STATUS_SUCCESS. + * \retval WLAN_STATUS_FAILURE. + * + */ +/*----------------------------------------------------------------------------*/ +uint32_t +kalProcessRxPacket(IN struct GLUE_INFO *prGlueInfo, + IN void *pvPacket, IN uint8_t *pucPacketStart, + IN uint32_t u4PacketLen, + /* IN PBOOLEAN pfgIsRetain, */ + IN u_int8_t fgIsRetain, IN enum ENUM_CSUM_RESULT aerCSUM[]) +{ + uint32_t rStatus = WLAN_STATUS_SUCCESS; + struct sk_buff *skb = (struct sk_buff *)pvPacket; + + skb->data = (unsigned char *)pucPacketStart; + + /* Reset skb */ + skb_reset_tail_pointer(skb); + skb_trim(skb, 0); + + if (skb_tailroom(skb) < 0 || u4PacketLen > skb_tailroom(skb)) { + DBGLOG(RX, ERROR, +#ifdef NET_SKBUFF_DATA_USES_OFFSET + "[skb:0x%p][skb->len:%d][skb->protocol:0x%02X] tail:%u, end:%u, data:%p\n", +#else + "[skb:0x%p][skb->len:%d][skb->protocol:0x%02X] tail:%p, end:%p, data:%p\n", +#endif + (uint8_t *) skb, + skb->len, + skb->protocol, + skb->tail, + skb->end, + skb->data); + DBGLOG_MEM32(RX, ERROR, (uint32_t *) skb->data, skb->len); + return WLAN_STATUS_FAILURE; + } + + /* Put data */ + skb_put(skb, u4PacketLen); + +#if CFG_TCP_IP_CHKSUM_OFFLOAD + if (prGlueInfo->prAdapter->fgIsSupportCsumOffload) + kalUpdateRxCSUMOffloadParam(skb, aerCSUM); +#endif + + return rStatus; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief To indicate an array of received packets is available for higher + * level protocol uses. + * + * \param[in] prGlueInfo Pointer to the Adapter structure. + * \param[in] apvPkts The packet array to be indicated + * \param[in] ucPktNum The number of packets to be indicated + * + * \retval TRUE Success. + * + */ +/*----------------------------------------------------------------------------*/ +uint32_t kalRxIndicatePkts(IN struct GLUE_INFO *prGlueInfo, + IN void *apvPkts[], IN uint8_t ucPktNum) +{ + uint8_t ucIdx = 0; + + ASSERT(prGlueInfo); + ASSERT(apvPkts); + + for (ucIdx = 0; ucIdx < ucPktNum; ucIdx++) + kalRxIndicateOnePkt(prGlueInfo, apvPkts[ucIdx]); + + KAL_WAKE_LOCK_TIMEOUT(prGlueInfo->prAdapter, + prGlueInfo->rTimeoutWakeLock, MSEC_TO_JIFFIES( + prGlueInfo->prAdapter->rWifiVar.u4WakeLockRxTimeout)); + + return WLAN_STATUS_SUCCESS; +} + +#if CFG_SUPPORT_RX_GRO +/*----------------------------------------------------------------------------*/ +/*! + * \brief To indicate Tput is higher than ucGROEnableTput or not. + * + * \param[in] prAdapter Pointer to the Adapter structure. + * + * \retval TRUE Success. + * + */ +/*----------------------------------------------------------------------------*/ +uint32_t kal_is_skb_gro(struct ADAPTER *prAdapter, uint8_t ucBssIdx) +{ + struct PERF_MONITOR *prPerMonitor; + struct WIFI_VAR *prWifiVar = &prAdapter->rWifiVar; + + prPerMonitor = &prAdapter->rPerMonitor; + if (prPerMonitor->ulRxTp[ucBssIdx] > prWifiVar->ucGROEnableTput) + return 1; + + return 0; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief flush Rx packet to kernel if kernel buffer is full or timeout(1ms) + * + * @param[in] prAdapter Pointer to the Adapter structure. + * + * @retval VOID + * + */ +/*----------------------------------------------------------------------------*/ +void kal_gro_flush(struct ADAPTER *prAdapter, struct net_device *prDev) +{ + struct WIFI_VAR *prWifiVar = &prAdapter->rWifiVar; + struct NETDEV_PRIVATE_GLUE_INFO *prNetDevPrivate = + (struct NETDEV_PRIVATE_GLUE_INFO *) netdev_priv(prDev); + + if (CHECK_FOR_TIMEOUT(kalGetTimeTick(), + prNetDevPrivate->tmGROFlushTimeout, + prWifiVar->ucGROFlushTimeout)) { + napi_gro_flush(&prNetDevPrivate->napi, false); + DBGLOG_LIMITED(INIT, TRACE, "napi_gro_flush:%p\n", prDev); + } + GET_CURRENT_SYSTIME(&prNetDevPrivate->tmGROFlushTimeout); +} +#endif +/*----------------------------------------------------------------------------*/ +/*! + * \brief To indicate one received packets is available for higher + * level protocol uses. + * + * \param[in] prGlueInfo Pointer to the Adapter structure. + * \param[in] pvPkt The packet to be indicated + * + * \retval TRUE Success. + * + */ +/*----------------------------------------------------------------------------*/ +uint32_t kalRxIndicateOnePkt(IN struct GLUE_INFO + *prGlueInfo, IN void *pvPkt) +{ + struct net_device *prNetDev = prGlueInfo->prDevHandler; + struct sk_buff *prSkb = NULL; + struct mt66xx_chip_info *prChipInfo; + uint8_t ucBssIdx; +#if CFG_SUPPORT_RX_GRO + struct NETDEV_PRIVATE_GLUE_INFO *prNetDevPrivate = NULL; +#endif + + ASSERT(prGlueInfo); + ASSERT(pvPkt); + + prSkb = pvPkt; + prChipInfo = prGlueInfo->prAdapter->chip_info; + ucBssIdx = GLUE_GET_PKT_BSS_IDX(prSkb); + RX_INC_CNT(&prGlueInfo->prAdapter->rRxCtrl, RX_DATA_INDICATION_COUNT); +#if DBG && 0 + do { + uint8_t *pu4Head = (uint8_t *) &prSkb->cb[0]; + uint32_t u4HeadValue = 0; + + kalMemCopy(&u4HeadValue, pu4Head, sizeof(u4HeadValue)); + DBGLOG(RX, TRACE, "prSkb->head = 0x%p, prSkb->cb = 0x%lx\n", + pu4Head, u4HeadValue); + } while (0); +#endif + +#if 1 + + if (ucBssIdx < MAX_BSSID_NUM) { + prNetDev = (struct net_device *)wlanGetNetInterfaceByBssIdx( + prGlueInfo, ucBssIdx); + } else { + DBGLOG(RX, WARN, "Error ucBssIdx =%x\n", ucBssIdx); + DBGLOG(RX, WARN, "Error pkt info =%x:%x:%x:%x:%x:%x:%x:%x\n", + GLUE_GET_PKT_TID(prSkb), + GLUE_IS_PKT_FLAG_SET(prSkb), + GLUE_GET_PKT_HEADER_LEN(prSkb), + GLUE_GET_PKT_FRAME_LEN(prSkb), + GLUE_GET_PKT_ARRIVAL_TIME(prSkb), + GLUE_GET_PKT_IP_ID(prSkb), + GLUE_GET_PKT_SEQ_NO(prSkb), + GLUE_GET_PKT_IS_PROF_MET(prSkb)); + } + if (!prNetDev) + prNetDev = prGlueInfo->prDevHandler; +#if CFG_SUPPORT_SNIFFER + if (prGlueInfo->fgIsEnableMon) + prNetDev = prGlueInfo->prMonDevHandler; +#endif + if (prNetDev->dev_addr == NULL) { + DBGLOG(RX, WARN, "dev_addr == NULL\n"); + return WLAN_STATUS_FAILURE; + } + + prNetDev->stats.rx_bytes += prSkb->len; + prNetDev->stats.rx_packets++; +#if CFG_SUPPORT_PERF_IND + if (GLUE_GET_PKT_BSS_IDX(prSkb) < BSS_DEFAULT_NUM) { + /* update Performance Indicator statistics*/ + prGlueInfo->PerfIndCache.u4CurRxBytes + [GLUE_GET_PKT_BSS_IDX(prSkb)] += prSkb->len; + } +#endif + +#else + if (GLUE_GET_PKT_IS_P2P(prSkb)) { + /* P2P */ +#if CFG_ENABLE_WIFI_DIRECT + if (prGlueInfo->prAdapter->fgIsP2PRegistered) + prNetDev = kalP2PGetDevHdlr(prGlueInfo); + /* prNetDev->stats.rx_bytes += prSkb->len; */ + /* prNetDev->stats.rx_packets++; */ + prGlueInfo->prP2PInfo[0]->rNetDevStats.rx_bytes += + prSkb->len; + prGlueInfo->prP2PInfo[0]->rNetDevStats.rx_packets++; + +#else + prNetDev = prGlueInfo->prDevHandler; +#endif + } else if (GLUE_GET_PKT_IS_PAL(prSkb)) { + /* BOW */ +#if CFG_ENABLE_BT_OVER_WIFI && CFG_BOW_SEPARATE_DATA_PATH + if (prGlueInfo->rBowInfo.fgIsNetRegistered) + prNetDev = prGlueInfo->rBowInfo.prDevHandler; +#else + prNetDev = prGlueInfo->prDevHandler; +#endif + } else { + /* AIS */ + prNetDev = prGlueInfo->prDevHandler; + prGlueInfo->rNetDevStats.rx_bytes += prSkb->len; + prGlueInfo->rNetDevStats.rx_packets++; + + } +#endif + +#if (CFG_SUPPORT_STATISTICS == 1) + StatsEnvRxTime2Host(prGlueInfo->prAdapter, prSkb, prNetDev); +#endif + +#if KERNEL_VERSION(4, 11, 0) <= CFG80211_VERSION_CODE + /* ToDo jiffies assignment */ +#else + prNetDev->last_rx = jiffies; +#endif + +#if CFG_SUPPORT_SNIFFER + if (prGlueInfo->fgIsEnableMon) { + skb_reset_mac_header(prSkb); + prSkb->ip_summed = CHECKSUM_UNNECESSARY; + prSkb->pkt_type = PACKET_OTHERHOST; + prSkb->protocol = htons(ETH_P_802_2); + } else { + prSkb->protocol = eth_type_trans(prSkb, prNetDev); + } +#else + prSkb->protocol = eth_type_trans(prSkb, prNetDev); +#endif + prSkb->dev = prNetDev; + /* DBGLOG_MEM32(RX, TRACE, (PUINT_32)prSkb->data, prSkb->len); */ + /* DBGLOG(RX, EVENT, ("kalRxIndicatePkts len = %d\n", prSkb->len)); */ + if (prSkb->tail > prSkb->end) { + DBGLOG(RX, ERROR, +#ifdef NET_SKBUFF_DATA_USES_OFFSET + "kalRxIndicateOnePkt [prSkb = 0x%p][prSkb->len = %d][prSkb->protocol = 0x%02x] %u,%u\n", +#else + "kalRxIndicateOnePkt [prSkb = 0x%p][prSkb->len = %d][prSkb->protocol = 0x%02x] %p,%p\n", +#endif + prSkb, prSkb->len, prSkb->protocol, prSkb->tail, + prSkb->end); + DBGLOG_MEM32(RX, ERROR, (uint32_t *) prSkb->data, + prSkb->len); + } + + if (prSkb->protocol == NTOHS(ETH_P_8021Q) + && !FEAT_SUP_LLC_VLAN_RX(prChipInfo)) { + /* + * DA-MAC + SA-MAC + 0x8100 was removed in eth_type_trans() + * pkt format here is + * TCI(2-bytes) + Len(2-btyes) + payload-type(2-bytes) + payload + * Remove "Len" field inserted by RX VLAN header translation + * Note: TCI+payload-type is a standard 8021Q header + * + * This format update is based on RX VLAN HW header translation. + * If the setting was changed, you may need to change rules here + * as well. + */ + const uint8_t vlan_skb_mem_move = 2; + + /* Remove "Len" and shift data pointer 2 bytes */ + kalMemCopy(prSkb->data + vlan_skb_mem_move, prSkb->data, + vlan_skb_mem_move); + skb_pull_rcsum(prSkb, vlan_skb_mem_move); + + /* Have to update MAC header properly. Otherwise, wrong MACs + * woud be passed up + */ + kalMemMove(prSkb->data - ETH_HLEN, + prSkb->data - ETH_HLEN - vlan_skb_mem_move, + ETH_HLEN); + prSkb->mac_header += vlan_skb_mem_move; + + skb_reset_network_header(prSkb); + skb_reset_transport_header(prSkb); + kal_skb_reset_mac_len(prSkb); + } + + kalTraceEvent("Rx ipid=0x%04x", GLUE_GET_PKT_IP_ID(prSkb)); + +#if CFG_SUPPORT_RX_GRO + if (ucBssIdx < MAX_BSSID_NUM && + kal_is_skb_gro(prGlueInfo->prAdapter, ucBssIdx)) { + /* GRO receive function can't be interrupt so it need to + * disable preempt and protect by spin lock + */ + preempt_disable(); + prNetDevPrivate = (struct NETDEV_PRIVATE_GLUE_INFO *) + netdev_priv(prNetDev); + spin_lock_bh(&prNetDevPrivate->napi_spinlock); + napi_gro_receive(&prNetDevPrivate->napi, prSkb); + kal_gro_flush(prGlueInfo->prAdapter, prNetDev); + spin_unlock_bh(&prNetDevPrivate->napi_spinlock); + preempt_enable(); + DBGLOG_LIMITED(INIT, INFO, "napi_gro_receive:%p\n", prNetDev); + return WLAN_STATUS_SUCCESS; + } +#endif + if (!in_interrupt()) + netif_rx_ni(prSkb); + else + netif_rx(prSkb); + + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Called by driver to indicate event to upper layer, for example, the + * wpa supplicant or wireless tools. + * + * \param[in] pvAdapter Pointer to the adapter descriptor. + * \param[in] eStatus Indicated status. + * \param[in] pvBuf Indicated message buffer. + * \param[in] u4BufLen Indicated message buffer size. + * + * \return (none) + * + */ +/*----------------------------------------------------------------------------*/ +void +kalIndicateStatusAndComplete(IN struct GLUE_INFO + *prGlueInfo, IN uint32_t eStatus, IN void *pvBuf, + IN uint32_t u4BufLen, IN uint8_t ucBssIndex) +{ + + uint32_t bufLen; + struct PARAM_STATUS_INDICATION *pStatus; + struct PARAM_AUTH_EVENT *pAuth; + struct PARAM_PMKID_CANDIDATE_LIST *pPmkid; + uint8_t arBssid[PARAM_MAC_ADDR_LEN]; + struct PARAM_SSID ssid = {0}; + struct ieee80211_channel *prChannel = NULL; + struct cfg80211_bss *bss = NULL; + uint8_t ucChannelNum; + struct BSS_DESC *prBssDesc = NULL; + struct ADAPTER *prAdapter = NULL; + uint8_t fgScanAborted = FALSE; + struct net_device *prDevHandler; + struct CONNECTION_SETTINGS *prConnSettings = NULL; + struct FT_IES *prFtIEs; + +#if KERNEL_VERSION(4, 12, 0) <= CFG80211_VERSION_CODE + struct cfg80211_roam_info rRoamInfo = { 0 }; +#endif + + GLUE_SPIN_LOCK_DECLARATION(); + + kalMemZero(arBssid, MAC_ADDR_LEN); + + ASSERT(prGlueInfo); + prAdapter = prGlueInfo->prAdapter; + ASSERT(prAdapter); + + pStatus = (struct PARAM_STATUS_INDICATION *)pvBuf; + pAuth = (struct PARAM_AUTH_EVENT *)pStatus; + pPmkid = (struct PARAM_PMKID_CANDIDATE_LIST *)(pStatus + 1); + + prDevHandler = wlanGetNetDev(prGlueInfo, ucBssIndex); + + switch (eStatus) { + case WLAN_STATUS_ROAM_OUT_FIND_BEST: + case WLAN_STATUS_MEDIA_CONNECT: +#ifdef CFG_SUPPORT_LINK_QUALITY_MONITOR + /* clear the count */ + prGlueInfo->prAdapter->rLinkQualityInfo.u8TxTotalCount = 0; + prGlueInfo->prAdapter->rLinkQualityInfo.u8RxTotalCount = 0; + prGlueInfo->prAdapter->rLinkQualityInfo.u8RxErrCount = 0; +#endif /* CFG_SUPPORT_LINK_QUALITY_MONITOR */ + kalSetMediaStateIndicated(prGlueInfo, + MEDIA_STATE_CONNECTED, + ucBssIndex); + + /* indicate assoc event */ + SET_IOCTL_BSSIDX(prGlueInfo->prAdapter, ucBssIndex); + wlanQueryInformation(prGlueInfo->prAdapter, wlanoidQueryBssid, + &arBssid[0], sizeof(arBssid), &bufLen); + wext_indicate_wext_event(prGlueInfo, SIOCGIWAP, arBssid, + bufLen, ucBssIndex); + + /* switch netif on */ + netif_carrier_on(prDevHandler); + + do { + + uint8_t aucSsid[PARAM_MAX_LEN_SSID + 1] = {0}; + + /* print message on console */ + SET_IOCTL_BSSIDX(prGlueInfo->prAdapter, ucBssIndex); + wlanQueryInformation(prGlueInfo->prAdapter, + wlanoidQuerySsid, &ssid, sizeof(ssid), &bufLen); + + kalStrnCpy(aucSsid, ssid.aucSsid, sizeof(aucSsid) - 1); + aucSsid[sizeof(aucSsid) - 1] = '\0'; + + DBGLOG(INIT, INFO, + "[wifi] %s netif_carrier_on [ssid:%s " MACSTR + "], Mac:" MACSTR "\n", + prGlueInfo->prDevHandler->name, aucSsid, + MAC2STR(arBssid), + MAC2STR( + prGlueInfo->prAdapter->rWifiVar.aucMacAddress)); + + } while (0); + + if (prGlueInfo->fgIsRegistered == TRUE) { + struct cfg80211_bss *bss_others = NULL; + uint8_t ucLoopCnt = + 15; /* only loop 15 times to avoid dead loop */ + + /* retrieve channel */ + ucChannelNum = + wlanGetChannelNumberByNetwork( + prGlueInfo->prAdapter, + ucBssIndex); + if (ucChannelNum <= 14) { + prChannel = + ieee80211_get_channel( + priv_to_wiphy(prGlueInfo), + ieee80211_channel_to_frequency + (ucChannelNum, KAL_BAND_2GHZ)); + } else { + prChannel = + ieee80211_get_channel( + priv_to_wiphy(prGlueInfo), + ieee80211_channel_to_frequency + (ucChannelNum, KAL_BAND_5GHZ)); + } + + if (!prChannel) + DBGLOG(SCN, ERROR, + "prChannel is NULL and ucChannelNum is %d\n", + ucChannelNum); + + /* ensure BSS exists */ +#if KERNEL_VERSION(4, 1, 0) <= CFG80211_VERSION_CODE + bss = cfg80211_get_bss( + priv_to_wiphy(prGlueInfo), prChannel, arBssid, + ssid.aucSsid, ssid.u4SsidLen, + IEEE80211_BSS_TYPE_ESS, + IEEE80211_PRIVACY_ANY); +#else + bss = cfg80211_get_bss( + priv_to_wiphy(prGlueInfo), prChannel, arBssid, + ssid.aucSsid, ssid.u4SsidLen, + WLAN_CAPABILITY_ESS, + WLAN_CAPABILITY_ESS); +#endif + if (bss == NULL) { + /* create BSS on-the-fly */ + prBssDesc = + aisGetTargetBssDesc(prAdapter, + ucBssIndex); + + if (prBssDesc != NULL && prChannel != NULL) { +#if KERNEL_VERSION(3, 18, 0) <= CFG80211_VERSION_CODE + bss = cfg80211_inform_bss( + priv_to_wiphy(prGlueInfo), + prChannel, + CFG80211_BSS_FTYPE_PRESP, + arBssid, + 0, /* TSF */ + prBssDesc->u2CapInfo, + prBssDesc->u2BeaconInterval, /* beacon interval */ + prBssDesc->aucIEBuf, /* IE */ + prBssDesc->u2IELength, /* IE Length */ + RCPI_TO_dBm(prBssDesc->ucRCPI) * 100, /* MBM */ + GFP_KERNEL); +#else + bss = cfg80211_inform_bss( + priv_to_wiphy(prGlueInfo), + prChannel, + arBssid, + 0, /* TSF */ + prBssDesc->u2CapInfo, + prBssDesc->u2BeaconInterval, /* beacon interval */ + prBssDesc->aucIEBuf, /* IE */ + prBssDesc->u2IELength, /* IE Length */ + RCPI_TO_dBm(prBssDesc->ucRCPI) * 100, /* MBM */ + GFP_KERNEL); +#endif + } + } + +#if (CFG_SUPPORT_STATISTICS == 1) + StatsResetTxRx(); +#endif + /* remove all bsses that before and only channel + * different with the current connected one + * if without this patch, UI will show channel A is + * connected even if AP has change channel from A to B + */ + while (ucLoopCnt--) { +#if KERNEL_VERSION(4, 1, 0) <= CFG80211_VERSION_CODE + bss_others = cfg80211_get_bss( + priv_to_wiphy(prGlueInfo), + NULL, arBssid, ssid.aucSsid, + ssid.u4SsidLen, + IEEE80211_BSS_TYPE_ESS, + IEEE80211_PRIVACY_ANY); +#else + bss_others = cfg80211_get_bss( + priv_to_wiphy(prGlueInfo), + NULL, arBssid, ssid.aucSsid, + ssid.u4SsidLen, + WLAN_CAPABILITY_ESS, + WLAN_CAPABILITY_ESS); +#endif + if (bss && bss_others && bss_others != bss) { + DBGLOG(SCN, INFO, + "remove BSSes that only channel different\n"); + cfg80211_unlink_bss( + priv_to_wiphy(prGlueInfo), + bss_others); + cfg80211_put_bss( + priv_to_wiphy(prGlueInfo), + bss_others); + } else + break; + } + + /* CFG80211 Indication */ + prConnSettings = + aisGetConnSettings(prAdapter, ucBssIndex); + if (eStatus == WLAN_STATUS_ROAM_OUT_FIND_BEST) { +#if KERNEL_VERSION(4, 12, 0) <= CFG80211_VERSION_CODE + rRoamInfo.bss = bss; + rRoamInfo.req_ie = prConnSettings->aucReqIe; + rRoamInfo.req_ie_len = + prConnSettings->u4ReqIeLength; + rRoamInfo.resp_ie = prConnSettings->aucRspIe; + rRoamInfo.resp_ie_len = + prConnSettings->u4RspIeLength; + + cfg80211_roamed(prDevHandler, + &rRoamInfo, GFP_KERNEL); +#else + cfg80211_roamed_bss( + prDevHandler, + bss, + prConnSettings->aucReqIe, + prConnSettings->u4ReqIeLength, + prConnSettings->aucRspIe, + prConnSettings->u4RspIeLength, + GFP_KERNEL); +#endif + } else { + cfg80211_connect_result( + prDevHandler, + arBssid, + prConnSettings->aucReqIe, + prConnSettings->u4ReqIeLength, + prConnSettings->aucRspIe, + prConnSettings->u4RspIeLength, + WLAN_STATUS_SUCCESS, + GFP_KERNEL); + } + + /* Check SAP channel */ + p2pFuncSwitchSapChannel(prGlueInfo->prAdapter); + + } + + break; + + case WLAN_STATUS_MEDIA_DISCONNECT: + case WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY: +#ifdef CFG_SUPPORT_LINK_QUALITY_MONITOR + /* clear the count */ + prGlueInfo->prAdapter->rLinkQualityInfo.u8TxTotalCount = 0; + prGlueInfo->prAdapter->rLinkQualityInfo.u8RxTotalCount = 0; + prGlueInfo->prAdapter->rLinkQualityInfo.u8RxErrCount = 0; +#endif + /* indicate disassoc event */ + wext_indicate_wext_event(prGlueInfo, SIOCGIWAP, NULL, 0 + , ucBssIndex); + /* For CR 90 and CR99, While supplicant do reassociate, driver + * will do netif_carrier_off first, + * after associated success, at joinComplete(), + * do netif_carier_on, + * but for unknown reason, the supplicant 1x pkt will not + * called the driver hardStartXmit, for template workaround + * these bugs, add this compiling flag + */ + /* switch netif off */ + +#if 1 /* CONSOLE_MESSAGE */ + DBGLOG(INIT, INFO, "[wifi] %s netif_carrier_off\n", + prDevHandler->name); +#endif + + netif_carrier_off(prDevHandler); + + /* Full2Partial: reset */ + if (prGlueInfo->prAdapter) { + struct SCAN_INFO *prScanInfo = + &(prGlueInfo->prAdapter->rWifiVar.rScanInfo); + prScanInfo->fgIsScanForFull2Partial = FALSE; + prScanInfo->u4LastFullScanTime = 0; + } + + if (prGlueInfo->fgIsRegistered == TRUE) { + struct BSS_INFO *prBssInfo = + aisGetAisBssInfo(prAdapter, ucBssIndex); + uint16_t u2DeauthReason = 0; +#if CFG_WPS_DISCONNECT || (KERNEL_VERSION(4, 4, 0) <= CFG80211_VERSION_CODE) + + if (prBssInfo) + u2DeauthReason = prBssInfo->u2DeauthReason; + +#if CFG_SUPPORT_BIGDATA_PIP + { + struct _REPORT_DISCONNECT { + uint16_t u2Id; + uint16_t u2Len; + uint8_t ucReasonType; + uint16_t u2ReasonCode; + int8_t cRssi; + uint16_t u2DataRate; + uint8_t ucChannelNo; + } __KAL_ATTRIB_PACKED__; + + struct _REPORT_DISCONNECT rPayload = {0}; + struct BSS_DESC *prTemp = NULL; + int8_t ret = 0; + + /* u2Id: Define category of report data. + * 0 - Antswp + * 1 - GPS Blank On + * 2 - Disconnect Reason + * others - Reserved + * + * u2Len: length of data. + * Report data format: + * | u2Id | u2Len | data | + */ + rPayload.u2Id = 2; + rPayload.u2Len = 7; + + if (eStatus == + WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY) { + rPayload.ucReasonType = 2; + rPayload.u2ReasonCode = 0; + } else if (u2DeauthReason >= + REASON_CODE_BEACON_TIMEOUT*100) { + rPayload.ucReasonType = 0; + rPayload.u2ReasonCode = + u2DeauthReason - REASON_CODE_BEACON_TIMEOUT*100; + } else { + rPayload.ucReasonType = 1; + rPayload.u2ReasonCode = u2DeauthReason; + } + + if (prGlueInfo->prAdapter) { + rPayload.cRssi = + prGlueInfo->prAdapter->rLinkQuality + .rLq[ucBssIndex].cRssi; + rPayload.u2DataRate = + prGlueInfo->prAdapter->rLinkQuality + .rLq[ucBssIndex].u2LinkSpeed; + + prTemp = + aisGetTargetBssDesc( + prGlueInfo->prAdapter, + ucBssIndex); + + if (prTemp) + rPayload.ucChannelNo = + prTemp->ucChannelNum; + + DBGLOG(INIT, TRACE, + "[D2F]type(%u)-reason(%u)-rssi(%d)-speed(%u)-channel(%u)\n", + rPayload.ucReasonType, + rPayload.u2ReasonCode, + rPayload.cRssi, + rPayload.u2DataRate, + rPayload.ucChannelNo); + + /* dumpMemory8((uint8_t *)&rPayload, + * sizeof(rPayload)); + */ + + ret = kalBigDataPip(prGlueInfo->prAdapter, + (uint8_t *)&rPayload, + sizeof(rPayload)); + + if ((ret != 1) && (ret != -ETIME)) + DBGLOG(INIT, ERROR, + "[D2F]data pip report fail(%d).\n", + ret); + + } + } +#endif + /* CFG80211 Indication */ + DBGLOG(INIT, INFO, + "[wifi]Indicate disconnection: Reason=%d Locally[%d]\n", + u2DeauthReason, + (eStatus == + WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY)); + cfg80211_disconnected(prDevHandler, + u2DeauthReason, NULL, 0, + eStatus == WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY, + GFP_KERNEL); + +#else + +#ifdef CONFIG_ANDROID +#if KERNEL_VERSION(3, 10, 0) == LINUX_VERSION_CODE + /* Don't indicate disconnection to upper layer for + * ANDROID kernel 3.10 + */ + /* since cfg80211 will indicate disconnection to + * wpa_supplicant for this kernel + */ + if (eStatus == WLAN_STATUS_MEDIA_DISCONNECT) +#endif +#endif + { + + + if (prBssInfo) + u2DeauthReason = + prBssInfo->u2DeauthReason; + /* CFG80211 Indication */ + cfg80211_disconnected(prDevHandler, + u2DeauthReason, NULL, 0, + GFP_KERNEL); + } + + +#endif + } + prConnSettings = aisGetConnSettings(prAdapter, ucBssIndex); + if (prConnSettings && prConnSettings->assocIeLen > 0) { + kalMemFree(prConnSettings->pucAssocIEs, VIR_MEM_TYPE, + prConnSettings->assocIeLen); + prConnSettings->assocIeLen = 0; + } + + prFtIEs = aisGetFtIe(prAdapter, ucBssIndex); + if (prFtIEs) { + kalMemFree(prFtIEs->pucIEBuf, + VIR_MEM_TYPE, + prFtIEs->u4IeLength); + kalMemZero(prFtIEs, + sizeof(*prFtIEs)); + } + + kalSetMediaStateIndicated(prGlueInfo, + MEDIA_STATE_DISCONNECTED, + ucBssIndex); + + /* Check SAP channel */ + p2pFuncSwitchSapChannel(prGlueInfo->prAdapter); + + break; + + case WLAN_STATUS_SCAN_COMPLETE: + if (pvBuf && u4BufLen == sizeof(uint8_t)) + fgScanAborted = *(uint8_t *)pvBuf; + + /* indicate scan complete event */ + wext_indicate_wext_event(prGlueInfo, SIOCGIWSCAN, NULL, 0, + ucBssIndex); + + if (fgScanAborted == FALSE) { + kalScanLogCacheFlushBSS(prGlueInfo->prAdapter, + SCAN_LOG_MSG_MAX_LEN); + scanlog_dbg(LOG_SCAN_DONE_D2K, INFO, "Call cfg80211_scan_done (aborted=%u)\n", + fgScanAborted); + } else { + scanlog_dbg(LOG_SCAN_ABORT_DONE_D2K, INFO, "Call cfg80211_scan_done (aborted=%u)\n", + fgScanAborted); + } + + /* 1. reset first for newly incoming request */ + GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); + if (prGlueInfo->prScanRequest != NULL) { + kalCfg80211ScanDone(prGlueInfo->prScanRequest, + fgScanAborted); + prGlueInfo->prScanRequest = NULL; + } + GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); + + break; + +#if 0 + case WLAN_STATUS_MSDU_OK: + if (netif_running(prDevHandler)) + netif_wake_queue(prDevHandler); + break; +#endif + + case WLAN_STATUS_MEDIA_SPECIFIC_INDICATION: + if (pStatus) { + switch (pStatus->eStatusType) { + case ENUM_STATUS_TYPE_AUTHENTICATION: + { + struct PARAM_INDICATION_EVENT *prEvent = + (struct PARAM_INDICATION_EVENT *) pvBuf; + + /* + * printk(KERN_NOTICE + * "ENUM_STATUS_TYPE_AUTHENTICATION: + * L(%d) [" MACSTR "] F:%lx\n", + * pAuth->Request[0].Length, + * MAC2STR(pAuth->Request[0].Bssid), + * pAuth->Request[0].Flags); + */ + /* indicate (UC/GC) MIC ERROR event only */ + if ((prEvent->rAuthReq.u4Flags == + PARAM_AUTH_REQUEST_PAIRWISE_ERROR) || + (prEvent->rAuthReq.u4Flags == + PARAM_AUTH_REQUEST_GROUP_ERROR)) { + cfg80211_michael_mic_failure( + prDevHandler, NULL, + (prEvent->rAuthReq.u4Flags == + PARAM_AUTH_REQUEST_PAIRWISE_ERROR) + ? NL80211_KEYTYPE_PAIRWISE : + NL80211_KEYTYPE_GROUP, + 0, NULL, GFP_KERNEL); + wext_indicate_wext_event(prGlueInfo, + IWEVMICHAELMICFAILURE, + (unsigned char *) + &prEvent->rAuthReq, + prEvent->rAuthReq.u4Length, + ucBssIndex); + } + break; + } + case ENUM_STATUS_TYPE_CANDIDATE_LIST: + { + struct PARAM_INDICATION_EVENT *prEvent = + (struct PARAM_INDICATION_EVENT *) pvBuf; + + cfg80211_pmksa_candidate_notify( + prDevHandler, + 1000, + prEvent->rCandi.arBSSID, + prEvent->rCandi.u4Flags, + GFP_KERNEL); + + wext_indicate_wext_event( + prGlueInfo, + IWEVPMKIDCAND, + (unsigned char *) &prEvent->rCandi, + sizeof(struct PARAM_PMKID_CANDIDATE), + ucBssIndex); + + break; + } + case ENUM_STATUS_TYPE_FT_AUTH_STATUS: { + struct cfg80211_ft_event_params *prFtEvent = + aisGetFtEventParam(prAdapter, + ucBssIndex); + + cfg80211_ft_event(prDevHandler, + prFtEvent); + } + break; + + default: + /* case ENUM_STATUS_TYPE_MEDIA_STREAM_MODE */ + /* + * printk(KERN_NOTICE "unknown media specific + * indication type:%x\n", pStatus->StatusType); + */ + break; + } + } else { + /* + * printk(KERN_WARNING "media specific indication + * buffer NULL\n"); + */ + } + break; + +#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS + case WLAN_STATUS_BWCS_UPDATE: { + wext_indicate_wext_event(prGlueInfo, IWEVCUSTOM, pvBuf, + sizeof(struct PTA_IPC), ucBssIndex); + } + + break; + +#endif + case WLAN_STATUS_JOIN_FAILURE: { + struct BSS_DESC *prBssDesc = + aisGetTargetBssDesc(prAdapter, ucBssIndex); + struct CONNECTION_SETTINGS *prConnSettings = + aisGetConnSettings(prAdapter, ucBssIndex); + struct GL_WPA_INFO *prWpaInfo = + aisGetWpaInfo(prAdapter, ucBssIndex); + struct BSS_INFO *prBssInfo = + aisGetAisBssInfo(prAdapter, ucBssIndex); + + /* Make sure we remove all WEP key */ + if (prWpaInfo && prWpaInfo->u4WpaVersion == + IW_AUTH_WPA_VERSION_DISABLED + && prBssInfo && prBssInfo->wepkeyWlanIdx < WTBL_SIZE) { + uint32_t keyId; + uint32_t u4SetLen; + struct PARAM_REMOVE_KEY rRemoveKey; + + for (keyId = 0; keyId <= 3; keyId++) { + if (!prBssInfo->wepkeyUsed[keyId]) + continue; + + rRemoveKey.u4Length = + sizeof(struct PARAM_REMOVE_KEY); + rRemoveKey.u4KeyIndex = keyId; + rRemoveKey.ucBssIdx = ucBssIndex; + if (prBssDesc) + kalMemCopy(rRemoveKey.arBSSID, + prBssDesc->aucBSSID, + MAC_ADDR_LEN); + else + kalMemCopy(rRemoveKey.arBSSID, + prConnSettings->aucBSSIDHint, + MAC_ADDR_LEN); + DBGLOG(INIT, INFO, + "JOIN Failure: remove WEP wlanidx: %d, keyid: %d", + prBssInfo->wepkeyWlanIdx, + rRemoveKey.u4KeyIndex); + wlanSetRemoveKey(prAdapter, + (void *)&rRemoveKey, + sizeof(struct PARAM_REMOVE_KEY), + &u4SetLen, FALSE); + } + } + + if (prBssDesc) { + DBGLOG(INIT, INFO, "JOIN Failure: u2JoinStatus=%d", + prBssDesc->u2JoinStatus); + COPY_MAC_ADDR(arBssid, prBssDesc->aucBSSID); + } else { + DBGLOG(INIT, INFO, "JOIN Failure: No TargetBssDesc"); + COPY_MAC_ADDR(arBssid, + prConnSettings->aucBSSID); + } + if (prBssDesc && prBssDesc->u2JoinStatus + && prBssDesc->u2JoinStatus != STATUS_CODE_AUTH_TIMEOUT + && prBssDesc->u2JoinStatus != STATUS_CODE_ASSOC_TIMEOUT) + cfg80211_connect_result(prDevHandler, + arBssid, + prConnSettings->aucReqIe, + prConnSettings->u4ReqIeLength, + prConnSettings->aucRspIe, + prConnSettings->u4RspIeLength, + prBssDesc->u2JoinStatus, + GFP_KERNEL); + else + cfg80211_connect_result(prDevHandler, + arBssid, + prConnSettings->aucReqIe, + prConnSettings->u4ReqIeLength, + prConnSettings->aucRspIe, + prConnSettings->u4RspIeLength, + WLAN_STATUS_AUTH_TIMEOUT, + GFP_KERNEL); + kalSetMediaStateIndicated(prGlueInfo, + MEDIA_STATE_DISCONNECTED, + ucBssIndex); + + /* Check SAP channel */ + p2pFuncSwitchSapChannel(prGlueInfo->prAdapter); + + break; + } + default: + /* + * printk(KERN_WARNING "unknown indication:%lx\n", eStatus); + */ + break; + } +} /* kalIndicateStatusAndComplete */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to update the (re)association request + * information to the structure used to query and set + * OID_802_11_ASSOCIATION_INFORMATION. + * + * \param[in] prGlueInfo Pointer to the Glue structure. + * \param[in] pucFrameBody Pointer to the frame body of the last + * (Re)Association Request frame from the AP. + * \param[in] u4FrameBodyLen The length of the frame body of the last + * (Re)Association Request frame. + * \param[in] fgReassocRequest TRUE, if it is a Reassociation Request frame. + * + * \return (none) + * + */ +/*----------------------------------------------------------------------------*/ +void +kalUpdateReAssocReqInfo(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t *pucFrameBody, IN uint32_t u4FrameBodyLen, + IN u_int8_t fgReassocRequest, + IN uint8_t ucBssIndex) +{ + uint8_t *cp; + struct CONNECTION_SETTINGS *prConnSettings = NULL; + + ASSERT(prGlueInfo); + + prConnSettings = aisGetConnSettings( + prGlueInfo->prAdapter, + ucBssIndex); + + /* reset */ + prConnSettings->u4ReqIeLength = 0; + + if (fgReassocRequest) { + if (u4FrameBodyLen < 15) { + /* + * printk(KERN_WARNING "frameBodyLen too short:%d\n", + * frameBodyLen); + */ + return; + } + } else { + if (u4FrameBodyLen < 9) { + /* + * printk(KERN_WARNING "frameBodyLen too short:%d\n", + * frameBodyLen); + */ + return; + } + } + + cp = pucFrameBody; + + if (fgReassocRequest) { + /* Capability information field 2 */ + /* Listen interval field 2 */ + /* Current AP address 6 */ + cp += 10; + u4FrameBodyLen -= 10; + } else { + /* Capability information field 2 */ + /* Listen interval field 2 */ + cp += 4; + u4FrameBodyLen -= 4; + } + + wext_indicate_wext_event(prGlueInfo, IWEVASSOCREQIE, cp, + u4FrameBodyLen, ucBssIndex); + + if (u4FrameBodyLen <= CFG_CFG80211_IE_BUF_LEN) { + prConnSettings->u4ReqIeLength = u4FrameBodyLen; + kalMemCopy(prConnSettings->aucReqIe, cp, u4FrameBodyLen); + } + +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is called to update the (re)association + * response information to the structure used to reply with + * cfg80211_connect_result + * + * @param prGlueInfo Pointer to adapter descriptor + * @param pucFrameBody Pointer to the frame body of the last (Re)Association + * Response frame from the AP + * @param u4FrameBodyLen The length of the frame body of the last + * (Re)Association Response frame + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void kalUpdateReAssocRspInfo(IN struct GLUE_INFO + *prGlueInfo, IN uint8_t *pucFrameBody, + IN uint32_t u4FrameBodyLen, + IN uint8_t ucBssIndex) +{ + uint32_t u4IEOffset = + 6; /* cap_info, status_code & assoc_id */ + uint32_t u4IELength = u4FrameBodyLen - u4IEOffset; + struct CONNECTION_SETTINGS *prConnSettings = NULL; + + ASSERT(prGlueInfo); + + prConnSettings = aisGetConnSettings( + prGlueInfo->prAdapter, + ucBssIndex); + + /* reset */ + prConnSettings->u4RspIeLength = 0; + + if (u4IELength <= CFG_CFG80211_IE_BUF_LEN) { + prConnSettings->u4RspIeLength = u4IELength; + kalMemCopy(prConnSettings->aucRspIe, pucFrameBody + u4IEOffset, + u4IELength); + } + +} /* kalUpdateReAssocRspInfo */ + +void kalResetPacket(IN struct GLUE_INFO *prGlueInfo, + IN void *prPacket) +{ + struct sk_buff *prSkb = (struct sk_buff *)prPacket; + + /* Reset cb */ + kalMemZero(prSkb->cb, sizeof(prSkb->cb)); +} + +/*----------------------------------------------------------------------------*/ +/* + * \brief This function is to check the pairwise eapol and wapi 1x. + * + * \param[in] prPacket Pointer to struct net_device + * + * \retval WLAN_STATUS + */ +/*----------------------------------------------------------------------------*/ +u_int8_t kalIsPairwiseEapolPacket(IN void *prPacket) +{ + struct sk_buff *prSkb = (struct sk_buff *)prPacket; + uint8_t *pucPacket = (uint8_t *)prSkb->data; + uint16_t u2EthType = 0; + uint16_t u2KeyInfo = 0; + + WLAN_GET_FIELD_BE16(&pucPacket[ETHER_HEADER_LEN - ETHER_TYPE_LEN], + &u2EthType); +#if CFG_SUPPORT_WAPI + /* prBssInfo && prBssInfo->eNetworkType == NETWORK_TYPE_AIS && + * wlanQueryWapiMode(prAdapter) + */ + if (u2EthType == ETH_WPI_1X) + return TRUE; +#endif + if (u2EthType != ETH_P_1X) + return FALSE; + u2KeyInfo = pucPacket[5 + ETHER_HEADER_LEN] << 8 | + pucPacket[6 + ETHER_HEADER_LEN]; +#if 1 + /* BIT3 is pairwise key bit, and check SM is 0. it means this is 4-way + * handshake frame + */ + DBGLOG(RSN, INFO, "u2KeyInfo=%d\n", u2KeyInfo); + if ((u2KeyInfo & BIT(3)) && !(u2KeyInfo & BIT(13))) + return TRUE; +#else + /* BIT3 is pairwise key bit, bit 8 is key mic bit. + * only the two bits are set, it means this is 4-way handshake 4/4 or + * 2/4 frame + */ + DBGLOG(RSN, INFO, "u2KeyInfo=%d\n", u2KeyInfo); + if ((u2KeyInfo & (BIT(3) | BIT(8))) == (BIT(3) | BIT(8))) + return TRUE; +#endif + return FALSE; +} + +/*----------------------------------------------------------------------------*/ +/* + * \brief This function is TX entry point of NET DEVICE. + * + * \param[in] prSkb Pointer of the sk_buff to be sent + * \param[in] prDev Pointer to struct net_device + * \param[in] prGlueInfo Pointer of prGlueInfo + * \param[in] ucBssIndex BSS index of this net device + * + * \retval WLAN_STATUS + */ +/*----------------------------------------------------------------------------*/ +uint32_t +kalHardStartXmit(struct sk_buff *prOrgSkb, + IN struct net_device *prDev, struct GLUE_INFO *prGlueInfo, + uint8_t ucBssIndex) +{ + struct QUE_ENTRY *prQueueEntry = NULL; + struct QUE *prTxQueue = NULL; + uint16_t u2QueueIdx = 0; + struct sk_buff *prSkbNew = NULL; + struct sk_buff *prSkb = NULL; + uint32_t u4SkbLen = 0; + struct mt66xx_chip_info *prChipInfo; + uint32_t u4TxHeadRoomSize = 0; + struct ADAPTER *prAdapter = NULL; + + ASSERT(prOrgSkb); + ASSERT(prGlueInfo); + + prAdapter = prGlueInfo->prAdapter; + prChipInfo = prGlueInfo->prAdapter->chip_info; + u4TxHeadRoomSize = NIC_TX_DESC_AND_PADDING_LENGTH + + prChipInfo->txd_append_size; + + if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { + DBGLOG(INIT, INFO, "GLUE_FLAG_HALT skip tx\n"); + dev_kfree_skb(prOrgSkb); + return WLAN_STATUS_ADAPTER_NOT_READY; + } + + if (prGlueInfo->prAdapter->fgIsEnableLpdvt) { + DBGLOG(INIT, INFO, "LPDVT enable, skip this frame\n"); + dev_kfree_skb(prOrgSkb); + return WLAN_STATUS_NOT_ACCEPTED; + } + +#if CFG_SUPPORT_WIFI_SYSDVT + if (prAdapter->u2TxTest != TX_TEST_UNLIMITIED) { + if (prAdapter->u2TxTestCount < prAdapter->u2TxTest) { + DBGLOG(INIT, STATE, + "DVT TX Test enable, skip this frame\n"); + dev_kfree_skb(prOrgSkb); + return WLAN_STATUS_SUCCESS; + } + prAdapter->u2TxTestCount++; + } +#endif /* CFG_SUPPORT_WIFI_SYSDVT */ + + if (skb_headroom(prOrgSkb) < u4TxHeadRoomSize) { + /* + * Should not happen + * kernel crash may happen as skb shared info + * channged. + * offer an change for lucky anyway + */ + prSkbNew = skb_realloc_headroom(prOrgSkb, u4TxHeadRoomSize); + if (!prSkbNew) { + dev_kfree_skb(prOrgSkb); + DBGLOG(INIT, ERROR, + "prChipInfo = %pM, u4TxHeadRoomSize: %u\n", + prChipInfo, u4TxHeadRoomSize); + return WLAN_STATUS_NOT_ACCEPTED; + } + dev_kfree_skb(prOrgSkb); + prSkb = prSkbNew; + } else + prSkb = prOrgSkb; + + prQueueEntry = (struct QUE_ENTRY *) + GLUE_GET_PKT_QUEUE_ENTRY(prSkb); + prTxQueue = &prGlueInfo->rTxQueue; + + GLUE_SET_PKT_BSS_IDX(prSkb, ucBssIndex); + + /* Parsing frame info */ + if (!wlanProcessTxFrame(prGlueInfo->prAdapter, + (void *) prSkb)) { + /* Cannot extract packet */ + DBGLOG(INIT, INFO, + "Cannot extract content, skip this frame\n"); + dev_kfree_skb(prSkb); + return WLAN_STATUS_INVALID_PACKET; + } + + /* Tx profiling */ + wlanTxProfilingTagPacket(prGlueInfo->prAdapter, + (void *) prSkb, TX_PROF_TAG_OS_TO_DRV); + + /* Handle normal data frame */ + u2QueueIdx = skb_get_queue_mapping(prSkb); + u4SkbLen = prSkb->len; + + if (u2QueueIdx >= CFG_MAX_TXQ_NUM) { + DBGLOG(INIT, INFO, + "Incorrect queue index, skip this frame\n"); + dev_kfree_skb(prSkb); + return WLAN_STATUS_INVALID_PACKET; + } + + if (!HAL_IS_TX_DIRECT(prGlueInfo->prAdapter)) { + GLUE_SPIN_LOCK_DECLARATION(); + + GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); + QUEUE_INSERT_TAIL(prTxQueue, prQueueEntry); + kalTraceInt(prTxQueue->u4NumElem, "TxQueue"); + GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); + } + + GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingFrameNum); + GLUE_INC_REF_CNT( + prGlueInfo->ai4TxPendingFrameNumPerQueue[ucBssIndex] + [u2QueueIdx]); + + if (GLUE_GET_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue + [ucBssIndex][u2QueueIdx]) >= + prGlueInfo->prAdapter->rWifiVar.u4NetifStopTh) { + netif_stop_subqueue(prDev, u2QueueIdx); + + DBGLOG(TX, INFO, + "Stop subqueue for BSS[%u] QIDX[%u] PKT_LEN[%u] TOT_CNT[%d] PER-Q_CNT[%d]\n", + ucBssIndex, u2QueueIdx, u4SkbLen, + GLUE_GET_REF_CNT(prGlueInfo->i4TxPendingFrameNum), + GLUE_GET_REF_CNT( + prGlueInfo->ai4TxPendingFrameNumPerQueue + [ucBssIndex][u2QueueIdx])); + } + + /* Update NetDev statisitcs */ + prDev->stats.tx_bytes += u4SkbLen; + prDev->stats.tx_packets++; +#if CFG_SUPPORT_PERF_IND + /* update Performance Indicator statistics*/ + prGlueInfo->PerfIndCache.u4CurTxBytes[ucBssIndex] += u4SkbLen; +#endif + + DBGLOG(TX, LOUD, + "Enqueue frame for BSS[%u] QIDX[%u] PKT_LEN[%u] TOT_CNT[%d] PER-Q_CNT[%d]\n", + ucBssIndex, u2QueueIdx, u4SkbLen, + GLUE_GET_REF_CNT(prGlueInfo->i4TxPendingFrameNum), + GLUE_GET_REF_CNT( + prGlueInfo->ai4TxPendingFrameNumPerQueue[ucBssIndex] + [u2QueueIdx])); + + if (HAL_IS_TX_DIRECT(prGlueInfo->prAdapter)) + return nicTxDirectStartXmit(prSkb, prGlueInfo); + + kalSetEvent(prGlueInfo); + + return WLAN_STATUS_SUCCESS; +} /* end of kalHardStartXmit() */ + +uint32_t kalResetStats(IN struct net_device *prDev) +{ + DBGLOG(QM, LOUD, "Reset NetDev[0x%p] statistics\n", prDev); + + kalMemZero(kalGetStats(prDev), + sizeof(struct net_device_stats)); + + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief A method of struct net_device, to get the network interface + * statistical information. + * + * Whenever an application needs to get statistics for the interface, this + * method is called. This happens, for example, when ifconfig or netstat -i is + * run. + * + * \param[in] prDev Pointer to struct net_device. + * + * \return net_device_stats buffer pointer. + */ +/*----------------------------------------------------------------------------*/ +void *kalGetStats(IN struct net_device *prDev) +{ + return (void *) &prDev->stats; +} /* end of wlanGetStats() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Notify OS with SendComplete event of the specific packet. Linux should + * free packets here. + * + * \param[in] prGlueInfo Pointer of GLUE Data Structure + * \param[in] pvPacket Pointer of Packet Handle + * \param[in] status Status Code for OS upper layer + * + * \return - + */ +/*----------------------------------------------------------------------------*/ +void kalSendCompleteAndAwakeQueue(IN struct GLUE_INFO + *prGlueInfo, IN void *pvPacket) +{ + struct net_device *prDev = NULL; + struct sk_buff *prSkb = NULL; + uint16_t u2QueueIdx = 0; + uint8_t ucBssIndex = 0; + u_int8_t fgIsValidDevice = TRUE; + + GLUE_SPIN_LOCK_DECLARATION(); + + ASSERT(pvPacket); + /* ASSERT(prGlueInfo->i4TxPendingFrameNum); */ + + prSkb = (struct sk_buff *)pvPacket; + u2QueueIdx = skb_get_queue_mapping(prSkb); + ASSERT(u2QueueIdx < CFG_MAX_TXQ_NUM); + + ucBssIndex = GLUE_GET_PKT_BSS_IDX(pvPacket); + +#if 0 + if ((GLUE_GET_REF_CNT(prGlueInfo->i4TxPendingFrameNum) <= + 0)) { + uint8_t ucBssIdx; + uint16_t u2QIdx; + + DBGLOG(INIT, INFO, "TxPendingFrameNum[%u] CurFrameId[%u]\n", + prGlueInfo->i4TxPendingFrameNum, + GLUE_GET_PKT_ARRIVAL_TIME(pvPacket)); + + for (ucBssIdx = 0; ucBssIdx < prAdapter->ucHwBssIdNum; + ucBssIdx++) { + for (u2QIdx = 0; u2QIdx < CFG_MAX_TXQ_NUM; u2QIdx++) { + DBGLOG(INIT, INFO, + "BSS[%u] Q[%u] TxPendingFrameNum[%u]\n", + ucBssIdx, u2QIdx, + prGlueInfo->ai4TxPendingFrameNumPerQueue + [ucBssIdx][u2QIdx]); + } + } + } + + ASSERT((GLUE_GET_REF_CNT(prGlueInfo->i4TxPendingFrameNum) > + 0)); +#endif + + GLUE_DEC_REF_CNT(prGlueInfo->i4TxPendingFrameNum); + GLUE_DEC_REF_CNT( + prGlueInfo->ai4TxPendingFrameNumPerQueue[ucBssIndex] + [u2QueueIdx]); + + DBGLOG(TX, LOUD, + "Release frame for BSS[%u] QIDX[%u] PKT_LEN[%u] TOT_CNT[%d] PER-Q_CNT[%d]\n", + ucBssIndex, u2QueueIdx, prSkb->len, + GLUE_GET_REF_CNT(prGlueInfo->i4TxPendingFrameNum), + GLUE_GET_REF_CNT( + prGlueInfo->ai4TxPendingFrameNumPerQueue[ucBssIndex] + [u2QueueIdx])); + + prDev = prSkb->dev; + + ASSERT(prDev); + +#if CFG_ENABLE_WIFI_DIRECT + GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); + + { + struct BSS_INFO *prBssInfo = GET_BSS_INFO_BY_INDEX( + prGlueInfo->prAdapter, ucBssIndex); + struct GL_P2P_INFO *prGlueP2pInfo = (struct GL_P2P_INFO *) + NULL; + struct net_device *prNetdevice = NULL; + + /* in case packet was sent after P2P device is unregistered or + * the net_device was be free + */ + if (prBssInfo->eNetworkType == NETWORK_TYPE_P2P) { + if (prGlueInfo->prAdapter->fgIsP2PRegistered == FALSE) + fgIsValidDevice = FALSE; + else { + ASSERT(prBssInfo->u4PrivateData < KAL_P2P_NUM); + prGlueP2pInfo = + prGlueInfo->prP2PInfo[ + prBssInfo->u4PrivateData]; + if (prGlueP2pInfo) { + prNetdevice = + prGlueP2pInfo->aprRoleHandler; + /* The net_device may be free */ + if ((prDev != prNetdevice) + && (prDev != + prGlueP2pInfo->prDevHandler)) { + fgIsValidDevice = FALSE; + DBGLOG(TX, LOUD, + "kalSendCompleteAndAwakeQueue net device deleted! ucBssIndex = %u\n", + ucBssIndex); + } + } + } + } + } +#endif + + if (fgIsValidDevice == TRUE) { + uint32_t u4StartTh = + prGlueInfo->prAdapter->rWifiVar.u4NetifStartTh; + + if (netif_subqueue_stopped(prDev, prSkb) && + prGlueInfo->ai4TxPendingFrameNumPerQueue[ucBssIndex] + [u2QueueIdx] <= u4StartTh) { + netif_wake_subqueue(prDev, u2QueueIdx); + DBGLOG(TX, INFO, + "WakeUp Queue BSS[%u] QIDX[%u] PKT_LEN[%u] TOT_CNT[%d] PER-Q_CNT[%d]\n", + ucBssIndex, u2QueueIdx, prSkb->len, + GLUE_GET_REF_CNT( + prGlueInfo->i4TxPendingFrameNum), + GLUE_GET_REF_CNT( + prGlueInfo-> + ai4TxPendingFrameNumPerQueue + [ucBssIndex][u2QueueIdx])); + } + } + +#if CFG_ENABLE_WIFI_DIRECT + GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); +#endif + + dev_kfree_skb_any((struct sk_buff *)pvPacket); + + DBGLOG(TX, LOUD, "----- pending frame %d -----\n", + prGlueInfo->i4TxPendingFrameNum); + +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Copy Mac Address setting from registry. It's All Zeros in Linux. + * + * \param[in] prAdapter Pointer to the Adapter structure + * + * \param[out] paucMacAddr Pointer to the Mac Address buffer + * + * \retval WLAN_STATUS_SUCCESS + * + * \note + */ +/*----------------------------------------------------------------------------*/ +void kalQueryRegistryMacAddr(IN struct GLUE_INFO + *prGlueInfo, OUT uint8_t *paucMacAddr) +{ + uint8_t aucZeroMac[MAC_ADDR_LEN] = { 0, 0, 0, 0, 0, 0 } + + DEBUGFUNC("kalQueryRegistryMacAddr"); + + ASSERT(prGlueInfo); + ASSERT(paucMacAddr); + + kalMemCopy((void *) paucMacAddr, (void *) aucZeroMac, + MAC_ADDR_LEN); + +} /* end of kalQueryRegistryMacAddr() */ + +#if CFG_SUPPORT_EXT_CONFIG +/*----------------------------------------------------------------------------*/ +/*! + * \brief Read external configuration, ex. NVRAM or file + * + * \param[in] prGlueInfo Pointer of GLUE Data Structure + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +uint32_t kalReadExtCfg(IN struct GLUE_INFO *prGlueInfo) +{ + ASSERT(prGlueInfo); + + /* External data is given from user space by ioctl or /proc, not read by + * driver. + */ + if (prGlueInfo->u4ExtCfgLength != 0) + DBGLOG(INIT, TRACE, + "Read external configuration data -- OK\n"); + else + DBGLOG(INIT, TRACE, + "Read external configuration data -- fail\n"); + + return prGlueInfo->u4ExtCfgLength; +} +#endif + +u_int8_t +kalIPv4FrameClassifier(IN struct GLUE_INFO *prGlueInfo, + IN void *prPacket, IN uint8_t *pucIpHdr, + OUT struct TX_PACKET_INFO *prTxPktInfo) +{ + uint8_t ucIpVersion, ucIcmpType; + uint8_t ucIpProto; + uint8_t ucSeqNo; + uint8_t *pucUdpHdr, *pucIcmp; + uint16_t u2DstPort; + struct BOOTP_PROTOCOL *prBootp; + uint32_t u4DhcpMagicCode; + uint16_t u2IpId; +#if CFG_SUPPORT_WIFI_SYSDVT +#if (CFG_TCP_IP_CHKSUM_OFFLOAD) + struct ADAPTER *prAdapter = NULL; +#endif +#endif /* Automation */ + + /* IPv4 version check */ + ucIpVersion = (pucIpHdr[0] & IP_VERSION_MASK) >> + IP_VERSION_OFFSET; + if (ucIpVersion != IP_VERSION_4) { + DBGLOG(TX, WARN, "Invalid IPv4 packet version: %u\n", + ucIpVersion); + return FALSE; + } + + ucIpProto = pucIpHdr[IPV4_HDR_IP_PROTOCOL_OFFSET]; + u2IpId = (pucIpHdr[IPV4_ADDR_LEN] << 8) | pucIpHdr[IPV4_ADDR_LEN + 1]; + GLUE_SET_PKT_IP_ID(prPacket, u2IpId); + +#if CFG_SUPPORT_WIFI_SYSDVT +#if (CFG_TCP_IP_CHKSUM_OFFLOAD) + prAdapter = prGlueInfo->prAdapter; + + /* set IP CHECKSUM to 0xff for verify CSO function */ + if (prAdapter->u4CSUMFlags & CSUM_OFFLOAD_EN_TX_IP + && CSO_TX_IPV4_ENABLED(prAdapter)) { + pucIpHdr[IPV4_HDR_IP_CSUM_OFFSET] = 0xff; + pucIpHdr[IPV4_HDR_IP_CSUM_OFFSET+1] = 0xff; + } +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ +#endif /* Automation */ + + if (ucIpProto == IP_PRO_UDP) { + pucUdpHdr = &pucIpHdr[IPV4_HDR_LEN]; + +#if CFG_SUPPORT_WIFI_SYSDVT +#if (CFG_TCP_IP_CHKSUM_OFFLOAD) + /* set UDP CHECKSUM to 0xff for verify CSO function */ + if (prAdapter->u4CSUMFlags & CSUM_OFFLOAD_EN_TX_UDP + && CSO_TX_UDP_ENABLED(prAdapter)) { + pucUdpHdr[UDP_HDR_UDP_CSUM_OFFSET] = 0xff; + pucUdpHdr[UDP_HDR_UDP_CSUM_OFFSET+1] = 0xff; + } +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ +#endif /* Automation */ + + /* Get UDP DST port */ + WLAN_GET_FIELD_BE16(&pucUdpHdr[UDP_HDR_DST_PORT_OFFSET], + &u2DstPort); + + /* BOOTP/DHCP protocol */ + if ((u2DstPort == IP_PORT_BOOTP_SERVER) || + (u2DstPort == IP_PORT_BOOTP_CLIENT)) { + prBootp = (struct BOOTP_PROTOCOL *) + &pucUdpHdr[UDP_HDR_LEN]; + WLAN_GET_FIELD_BE32(&prBootp->aucOptions[0], + &u4DhcpMagicCode); + if (u4DhcpMagicCode == DHCP_MAGIC_NUMBER) { + ucSeqNo = nicIncreaseTxSeqNum( + prGlueInfo->prAdapter); + GLUE_SET_PKT_SEQ_NO(prPacket, ucSeqNo); + prTxPktInfo->u2Flag |= BIT(ENUM_PKT_DHCP); + } + } else if (u2DstPort == UDP_PORT_DNS) { + ucSeqNo = nicIncreaseTxSeqNum(prGlueInfo->prAdapter); + GLUE_SET_PKT_SEQ_NO(prPacket, ucSeqNo); + prTxPktInfo->u2Flag |= BIT(ENUM_PKT_DNS); + } + } else if (ucIpProto == IP_PRO_ICMP) { + pucIcmp = &pucIpHdr[20]; + ucIcmpType = pucIcmp[0]; + if (ucIcmpType == 3) /* don't log network unreachable packet */ + return FALSE; + ucSeqNo = nicIncreaseTxSeqNum(prGlueInfo->prAdapter); + GLUE_SET_PKT_SEQ_NO(prPacket, ucSeqNo); + prTxPktInfo->u2Flag |= BIT(ENUM_PKT_ICMP); + } +#if CFG_SUPPORT_WIFI_SYSDVT +#if (CFG_TCP_IP_CHKSUM_OFFLOAD) + else if (ucIpProto == IP_PRO_TCP) { + uint8_t *pucTcpHdr; + + pucTcpHdr = &pucIpHdr[IPV4_HDR_LEN]; + /* set TCP CHECKSUM to 0xff for verify CSO function */ + if (prAdapter->u4CSUMFlags & CSUM_OFFLOAD_EN_TX_TCP + && CSO_TX_TCP_ENABLED(prAdapter)) { + pucTcpHdr[TCP_HDR_TCP_CSUM_OFFSET] = 0xff; + pucTcpHdr[TCP_HDR_TCP_CSUM_OFFSET+1] = 0xff; + } + } +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ +#endif /* Automation */ + + return TRUE; +} + +u_int8_t +kalIPv6FrameClassifier(IN struct GLUE_INFO *prGlueInfo, + IN void *prPacket, IN uint8_t *pucIpv6Hdr, + OUT struct TX_PACKET_INFO *prTxPktInfo) +{ + uint8_t ucIpv6Proto; + uint8_t *pucL3Hdr; + struct ADAPTER *prAdapter = NULL; + + prAdapter = prGlueInfo->prAdapter; + ucIpv6Proto = pucIpv6Hdr[IPV6_HDR_IP_PROTOCOL_OFFSET]; + + if (ucIpv6Proto == IP_PRO_UDP) { + pucL3Hdr = &pucIpv6Hdr[IPV6_HDR_LEN]; +#if CFG_SUPPORT_WIFI_SYSDVT +#if (CFG_TCP_IP_CHKSUM_OFFLOAD) + /* set UDP CHECKSUM to 0xff for verify CSO function */ + if ((prAdapter->u4CSUMFlags & CSUM_OFFLOAD_EN_TX_UDP) + && CSO_TX_UDP_ENABLED(prAdapter)) { + pucL3Hdr[UDP_HDR_UDP_CSUM_OFFSET] = 0xff; + pucL3Hdr[UDP_HDR_UDP_CSUM_OFFSET+1] = 0xff; + } +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ +#endif /* Automation */ + } else if (ucIpv6Proto == IP_PRO_TCP) { + pucL3Hdr = &pucIpv6Hdr[IPV6_HDR_LEN]; +#if CFG_SUPPORT_WIFI_SYSDVT +#if (CFG_TCP_IP_CHKSUM_OFFLOAD) + /* set TCP CHECKSUM to 0xff for verify CSO function */ + if ((prAdapter->u4CSUMFlags & CSUM_OFFLOAD_EN_TX_TCP) + && CSO_TX_TCP_ENABLED(prAdapter)) { + pucL3Hdr[TCP_HDR_TCP_CSUM_OFFSET] = 0xff; + pucL3Hdr[TCP_HDR_TCP_CSUM_OFFSET+1] = 0xff; + } +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ +#endif /* Automation */ + } + + return TRUE; +} + +u_int8_t +kalArpFrameClassifier(IN struct GLUE_INFO *prGlueInfo, + IN void *prPacket, IN uint8_t *pucIpHdr, + OUT struct TX_PACKET_INFO *prTxPktInfo) +{ + uint8_t ucSeqNo; + ucSeqNo = nicIncreaseTxSeqNum(prGlueInfo->prAdapter); + GLUE_SET_PKT_SEQ_NO(prPacket, ucSeqNo); + prTxPktInfo->u2Flag |= BIT(ENUM_PKT_ARP); + return TRUE; +} + +u_int8_t +kalTdlsFrameClassifier(IN struct GLUE_INFO *prGlueInfo, + IN void *prPacket, IN uint8_t *pucIpHdr, + OUT struct TX_PACKET_INFO *prTxPktInfo) +{ + uint8_t ucSeqNo; + + ucSeqNo = nicIncreaseTxSeqNum(prGlueInfo->prAdapter); + GLUE_SET_PKT_SEQ_NO(prPacket, ucSeqNo); + prTxPktInfo->u2Flag |= BIT(ENUM_PKT_TDLS); + + return TRUE; +} + +u_int8_t +kalSecurityFrameClassifier(IN struct GLUE_INFO *prGlueInfo, + IN void *prPacket, IN uint8_t *pucIpHdr, + IN uint16_t u2EthType, IN uint8_t *aucLookAheadBuf, + OUT struct TX_PACKET_INFO *prTxPktInfo) +{ + uint8_t *pucEapol; + uint8_t ucEapolType; + uint8_t ucSeqNo; + uint8_t ucEAPoLKey = 0; + uint8_t ucEapOffset = ETHER_HEADER_LEN; + uint16_t u2KeyInfo = 0; + + pucEapol = pucIpHdr; + + if (u2EthType == ETH_P_1X) { + + ucEapolType = pucEapol[1]; + + /* Leave EAP to check */ + ucEAPoLKey = aucLookAheadBuf[1 + ucEapOffset]; + if (ucEAPoLKey != ETH_EAPOL_KEY) + prTxPktInfo->u2Flag |= BIT(ENUM_PKT_NON_PROTECTED_1X); + else { + WLAN_GET_FIELD_BE16(&aucLookAheadBuf[5 + ucEapOffset], + &u2KeyInfo); + /* BIT3 is pairwise key bit */ + DBGLOG(TX, INFO, "u2KeyInfo=%d\n", u2KeyInfo); + if (u2KeyInfo & BIT(3)) + prTxPktInfo->u2Flag |= + BIT(ENUM_PKT_NON_PROTECTED_1X); + } + + ucSeqNo = nicIncreaseTxSeqNum(prGlueInfo->prAdapter); + GLUE_SET_PKT_SEQ_NO(prPacket, ucSeqNo); +#if CFG_SUPPORT_WAPI + } else if (u2EthType == ETH_WPI_1X) { + ucSeqNo = nicIncreaseTxSeqNum(prGlueInfo->prAdapter); + GLUE_SET_PKT_SEQ_NO(prPacket, ucSeqNo); + prTxPktInfo->u2Flag |= BIT(ENUM_PKT_NON_PROTECTED_1X); +#endif + } + prTxPktInfo->u2Flag |= BIT(ENUM_PKT_1X); + return TRUE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This inline function is to extract some packet information, including + * user priority, packet length, destination address, 802.1x and BT over + * Wi-Fi or not. + * + * @param prGlueInfo Pointer to the glue structure + * @param prPacket Packet descriptor + * @param prTxPktInfo Extracted packet info + * + * @retval TRUE Success to extract information + * @retval FALSE Fail to extract correct information + */ +/*----------------------------------------------------------------------------*/ +u_int8_t +kalQoSFrameClassifierAndPacketInfo(IN struct GLUE_INFO *prGlueInfo, + IN void *prPacket, OUT struct TX_PACKET_INFO *prTxPktInfo) +{ + uint32_t u4PacketLen; + uint16_t u2EtherTypeLen; + struct sk_buff *prSkb = (struct sk_buff *)prPacket; + uint8_t *aucLookAheadBuf = NULL; + uint8_t ucEthTypeLenOffset = ETHER_HEADER_LEN - + ETHER_TYPE_LEN; + uint8_t *pucNextProtocol = NULL; +#if DSCP_SUPPORT + uint8_t ucUserPriority; +#endif + + u4PacketLen = prSkb->len; + + if (u4PacketLen < ETHER_HEADER_LEN) { + DBGLOG(INIT, WARN, "Invalid Ether packet length: %u\n", + u4PacketLen); + return FALSE; + } + + aucLookAheadBuf = prSkb->data; + + /* Reset Packet Info */ + kalMemZero(prTxPktInfo, sizeof(struct TX_PACKET_INFO)); + + /* 4 <0> Obtain Ether Type/Len */ + WLAN_GET_FIELD_BE16(&aucLookAheadBuf[ucEthTypeLenOffset], + &u2EtherTypeLen); + + /* 4 <1> Skip 802.1Q header (VLAN Tagging) */ + if (u2EtherTypeLen == ETH_P_VLAN) { + prTxPktInfo->u2Flag |= BIT(ENUM_PKT_VLAN_EXIST); + ucEthTypeLenOffset += ETH_802_1Q_HEADER_LEN; + WLAN_GET_FIELD_BE16(&aucLookAheadBuf[ucEthTypeLenOffset], + &u2EtherTypeLen); + } + /* 4 <2> Obtain next protocol pointer */ + pucNextProtocol = &aucLookAheadBuf[ucEthTypeLenOffset + + ETHER_TYPE_LEN]; + + /* 4 <3> Handle ethernet format */ + switch (u2EtherTypeLen) { + case ETH_P_IPV4: + /* IPv4 header length check */ + if (u4PacketLen < (ucEthTypeLenOffset + ETHER_TYPE_LEN + + IPV4_HDR_LEN)) { + DBGLOG(INIT, WARN, "Invalid IPv4 packet length: %u\n", + u4PacketLen); + break; + } +#if DSCP_SUPPORT + if (GLUE_GET_PKT_BSS_IDX(prSkb) != P2P_DEV_BSS_INDEX) { + ucUserPriority = getUpFromDscp( + prGlueInfo, + GLUE_GET_PKT_BSS_IDX(prSkb), + (pucNextProtocol[1] >> 2) & 0x3F); + if (ucUserPriority != 0xFF) + prSkb->priority = ucUserPriority; + } +#endif + kalIPv4FrameClassifier(prGlueInfo, prPacket, + pucNextProtocol, prTxPktInfo); + break; + + case ETH_P_ARP: + kalArpFrameClassifier(prGlueInfo, prPacket, pucNextProtocol, + prTxPktInfo); + break; + + case ETH_P_1X: + case ETH_P_PRE_1X: +#if CFG_SUPPORT_WAPI + case ETH_WPI_1X: +#endif + kalSecurityFrameClassifier(prGlueInfo, prPacket, + pucNextProtocol, u2EtherTypeLen, aucLookAheadBuf, + prTxPktInfo); + break; + + case ETH_PRO_TDLS: + kalTdlsFrameClassifier(prGlueInfo, prPacket, + pucNextProtocol, prTxPktInfo); + break; + + case ETH_P_IPV6: +#if CFG_SUPPORT_WIFI_SYSDVT +#if (CFG_TCP_IP_CHKSUM_OFFLOAD) + kalIPv6FrameClassifier(prGlueInfo, prPacket, + pucNextProtocol, prTxPktInfo); +#endif +#endif + +#if DSCP_SUPPORT + if (GLUE_GET_PKT_BSS_IDX(prSkb) != P2P_DEV_BSS_INDEX) { + uint16_t u2Tmp; + uint8_t ucIpTos; + + WLAN_GET_FIELD_BE16(pucNextProtocol, &u2Tmp); + ucIpTos = u2Tmp >> 4; + + ucUserPriority = getUpFromDscp( + prGlueInfo, + GLUE_GET_PKT_BSS_IDX(prSkb), + (ucIpTos >> 2) & 0x3F); + if (ucUserPriority != 0xFF) + prSkb->priority = ucUserPriority; + } +#endif + break; + + default: + /* 4 <4> Handle 802.3 format if LEN <= 1500 */ + if (u2EtherTypeLen <= ETH_802_3_MAX_LEN) + prTxPktInfo->u2Flag |= BIT(ENUM_PKT_802_3); + break; + } + + STATS_TX_PKT_INFO_DISPLAY(prSkb); + + /* 4 <4.1> Check for PAL (BT over Wi-Fi) */ + /* Move to kalBowFrameClassifier */ + + /* 4 <5> Return the value of Priority Parameter. */ + /* prSkb->priority is assigned by Linux wireless utility + * function(cfg80211_classify8021d) + */ + /* at net_dev selection callback (ndo_select_queue) */ + prTxPktInfo->ucPriorityParam = prSkb->priority; + +#if CFG_CHANGE_PRIORITY_BY_SKB_MARK_FIELD + /* Raise priority for special packet if skb mark filed + * marked with pre-defined value. + */ + if (prSkb->mark == NIC_TX_SKB_PRIORITY_MARK1 || + (prSkb->mark & BIT(NIC_TX_SKB_PRIORITY_MARK_BIT))) { + prTxPktInfo->ucPriorityParam = NIC_TX_PRIORITY_DATA_TID; + DBGLOG_LIMITED(INIT, TRACE, + "skb mark field=[%x]", prSkb->mark); + } +#endif + + /* 4 <6> Retrieve Packet Information - DA */ + /* Packet Length/ Destination Address */ + prTxPktInfo->u4PacketLen = u4PacketLen; + + kalMemCopy(prTxPktInfo->aucEthDestAddr, aucLookAheadBuf, + PARAM_MAC_ADDR_LEN); + + return TRUE; +} /* end of kalQoSFrameClassifier() */ + +u_int8_t kalGetEthDestAddr(IN struct GLUE_INFO *prGlueInfo, + IN void *prPacket, OUT uint8_t *pucEthDestAddr) +{ + struct sk_buff *prSkb = (struct sk_buff *)prPacket; + uint8_t *aucLookAheadBuf = NULL; + + /* Sanity Check */ + if (!prPacket || !prGlueInfo) + return FALSE; + + aucLookAheadBuf = prSkb->data; + + kalMemCopy(pucEthDestAddr, aucLookAheadBuf, + PARAM_MAC_ADDR_LEN); + + return TRUE; +} + +void +kalOidComplete(IN struct GLUE_INFO *prGlueInfo, + IN u_int8_t fgSetQuery, IN uint32_t u4SetQueryInfoLen, + IN uint32_t rOidStatus) +{ + + ASSERT(prGlueInfo); + /* remove timeout check timer */ + wlanoidClearTimeoutCheck(prGlueInfo->prAdapter); + + prGlueInfo->rPendStatus = rOidStatus; + + prGlueInfo->u4OidCompleteFlag = 1; + /* complete ONLY if there are waiters */ + if (!completion_done(&prGlueInfo->rPendComp)) { + complete(&prGlueInfo->rPendComp); + } else { + DBGLOG(INIT, WARN, "SKIP multiple OID complete!\n"); + /* WARN_ON(TRUE); */ + } + + if (rOidStatus == WLAN_STATUS_SUCCESS) + DBGLOG(INIT, TRACE, "Complete OID, status:success\n"); + else + DBGLOG(INIT, WARN, "Complete OID, status:0x%08x\n", + rOidStatus); + + /* else let it timeout on kalIoctl entry */ +} + +void kalOidClearance(IN struct GLUE_INFO *prGlueInfo) +{ + +} + +void kalGetLocalTime(unsigned long long *sec, unsigned long *nsec) +{ + if (sec != NULL && nsec != NULL) { + *sec = local_clock(); + *nsec = do_div(*sec, 1000000000)/1000; + } else + DBGLOG(INIT, ERROR, + "The input parameters error when get local time\n"); +} + +/* + * kalThreadSchedRetrieve + * Retrieve thread's current scheduling statistics and + * stored in output "sched". + * Return value: + * 0 : Schedstats successfully retrieved + * -1 : Kernel's schedstats feature not enabled + * -2 : pThread not yet initialized or sched is a NULL pointer + */ +static int32_t kalThreadSchedRetrieve(struct task_struct *pThread, + struct KAL_THREAD_SCHEDSTATS *pSched) +{ +#ifdef CONFIG_SCHEDSTATS + struct sched_entity se; + unsigned long long sec; + unsigned long usec; + + if (!pSched) + return -2; + + /* always clear sched to simplify error handling at caller side */ + memset(pSched, 0, sizeof(struct KAL_THREAD_SCHEDSTATS)); + + if (!pThread || kalIsResetting()) + return -2; + + memcpy(&se, &pThread->se, sizeof(struct sched_entity)); + kalGetLocalTime(&sec, &usec); + + pSched->time = sec*1000 + usec/1000; + pSched->exec = se.sum_exec_runtime; + pSched->runnable = se.statistics.wait_sum; + pSched->iowait = se.statistics.iowait_sum; + + return 0; +#else + /* always clear sched to simplify error handling at caller side */ + if (pSched) + memset(pSched, 0, sizeof(struct KAL_THREAD_SCHEDSTATS)); + return -1; +#endif +} + +/* + * kalThreadSchedMark + * Record the thread's current schedstats and stored in + * output "schedstats" parameter for profiling at later time. + * Return value: + * 0 : Schedstats successfully recorded + * -1 : Kernel's schedstats feature not enabled + * -2 : pThread not yet initialized or invalid parameters + */ +int32_t kalThreadSchedMark(struct task_struct *pThread, + struct KAL_THREAD_SCHEDSTATS *pSchedstats) +{ + return kalThreadSchedRetrieve(pThread, pSchedstats); +} + +/* + * kalThreadSchedUnmark + * Calculate scheduling statistics against the previously marked point. + * The result will be filled back into the schedstats output parameter. + * Return value: + * 0 : Schedstats successfully calculated + * -1 : Kernel's schedstats feature not enabled + * -2 : pThread not yet initialized or invalid parameters + */ +int32_t kalThreadSchedUnmark(struct task_struct *pThread, + struct KAL_THREAD_SCHEDSTATS *pSchedstats) +{ + int32_t ret; + struct KAL_THREAD_SCHEDSTATS sched_now; + + if (unlikely(!pSchedstats)) { + ret = -2; + } else { + ret = kalThreadSchedRetrieve(pThread, &sched_now); + if (ret == 0) { + pSchedstats->time = + sched_now.time - pSchedstats->time; + pSchedstats->exec = + sched_now.exec - pSchedstats->exec; + pSchedstats->runnable = + sched_now.runnable - pSchedstats->runnable; + pSchedstats->iowait = + sched_now.iowait - pSchedstats->iowait; + } + } + return ret; +} + + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is used to transfer linux ioctl to OID, and we + * need to specify the behavior of the OID by ourself + * + * @param prGlueInfo Pointer to the glue structure + * @param pvInfoBuf Data buffer + * @param u4InfoBufLen Data buffer length + * @param fgRead Is this a read OID + * @param fgWaitResp does this OID need to wait for values + * @param fgCmd does this OID compose command packet + * @param pu4QryInfoLen The data length of the return values + * + * @retval TRUE Success to extract information + * @retval FALSE Fail to extract correct information + */ +/*----------------------------------------------------------------------------*/ + +/* todo: enqueue the i/o requests for multiple processes access */ +/* */ +/* currently, return -1 */ +/* */ + +/* static GL_IO_REQ_T OidEntry; */ + +uint8_t GET_IOCTL_BSSIDX( + IN struct ADAPTER *prAdapter) +{ + uint8_t ucBssIndex = AIS_DEFAULT_INDEX; + + if (prAdapter) { + struct GL_IO_REQ *prIoReq = NULL; + + prIoReq = + &(prAdapter->prGlueInfo + ->OidEntry); + + ucBssIndex = prIoReq->ucBssIndex; + } + + return ucBssIndex; +} + +void SET_IOCTL_BSSIDX( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex) +{ + if (prAdapter) { + struct GL_IO_REQ *prIoReq = NULL; + + prIoReq = + &(prAdapter->prGlueInfo + ->OidEntry); + + prIoReq->ucBssIndex = ucBssIndex; + } +} + +uint32_t +kalIoctl(IN struct GLUE_INFO *prGlueInfo, + IN PFN_OID_HANDLER_FUNC pfnOidHandler, + IN void *pvInfoBuf, + IN uint32_t u4InfoBufLen, IN u_int8_t fgRead, + IN u_int8_t fgWaitResp, IN u_int8_t fgCmd, + OUT uint32_t *pu4QryInfoLen) +{ + return kalIoctlByBssIdx( + prGlueInfo, + pfnOidHandler, + pvInfoBuf, + u4InfoBufLen, + fgRead, + fgWaitResp, + fgCmd, + pu4QryInfoLen, + AIS_DEFAULT_INDEX); +} + +uint32_t +kalIoctlByBssIdx(IN struct GLUE_INFO *prGlueInfo, + IN PFN_OID_HANDLER_FUNC pfnOidHandler, + IN void *pvInfoBuf, + IN uint32_t u4InfoBufLen, IN u_int8_t fgRead, + IN u_int8_t fgWaitResp, IN u_int8_t fgCmd, + OUT uint32_t *pu4QryInfoLen, + IN uint8_t ucBssIndex) +{ + struct GL_IO_REQ *prIoReq = NULL; + struct KAL_THREAD_SCHEDSTATS schedstats; + uint32_t ret = WLAN_STATUS_SUCCESS; + uint32_t waitRet = 0; + + if (kalIsResetting()) + return WLAN_STATUS_SUCCESS; + + ASSERT(prGlueInfo); + ASSERT(prGlueInfo->prAdapter); + + if (wlanIsChipAssert(prGlueInfo->prAdapter)) + return WLAN_STATUS_SUCCESS; + + /* GLUE_SPIN_LOCK_DECLARATION(); */ + + /* <1> Check if driver is halt */ + /* if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) { */ + /* return WLAN_STATUS_ADAPTER_NOT_READY; */ + /* } */ + + if (down_interruptible(&g_halt_sem)) + return WLAN_STATUS_FAILURE; + + if (g_u4HaltFlag) { + up(&g_halt_sem); + return WLAN_STATUS_ADAPTER_NOT_READY; + } + + if (down_interruptible(&prGlueInfo->ioctl_sem)) { + up(&g_halt_sem); + return WLAN_STATUS_FAILURE; + } + + if (prGlueInfo->main_thread == NULL) { + dump_stack(); + DBGLOG(OID, WARN, "skip executing request.\n"); + up(&prGlueInfo->ioctl_sem); + up(&g_halt_sem); + return WLAN_STATUS_FAILURE; + } + + /* <2> TODO: thread-safe */ + + /* <3> point to the OidEntry of Glue layer */ + + prIoReq = &(prGlueInfo->OidEntry); + + ASSERT(prIoReq); + + /* <4> Compose the I/O request */ + prIoReq->prAdapter = prGlueInfo->prAdapter; + prIoReq->pfnOidHandler = pfnOidHandler; + prIoReq->pvInfoBuf = pvInfoBuf; + prIoReq->u4InfoBufLen = u4InfoBufLen; + prIoReq->pu4QryInfoLen = pu4QryInfoLen; + prIoReq->fgRead = fgRead; + prIoReq->fgWaitResp = fgWaitResp; + prIoReq->rStatus = WLAN_STATUS_FAILURE; + SET_IOCTL_BSSIDX( + prGlueInfo->prAdapter, + ucBssIndex); + + /* <5> Reset the status of pending OID */ + prGlueInfo->rPendStatus = WLAN_STATUS_FAILURE; + /* prGlueInfo->u4TimeoutFlag = 0; */ + prGlueInfo->u4OidCompleteFlag = 0; + + /* <6> Check if we use the command queue */ + prIoReq->u4Flag = fgCmd; + + /* <7> schedule the OID bit + * Use memory barrier to ensure OidEntry is written done and then set + * bit. + */ + smp_mb(); + set_bit(GLUE_FLAG_OID_BIT, &prGlueInfo->ulFlag); + + /* <7.1> Hold wakelock to ensure OS won't be suspended */ + KAL_WAKE_LOCK_TIMEOUT(prGlueInfo->prAdapter, + prGlueInfo->rTimeoutWakeLock, MSEC_TO_JIFFIES( + prGlueInfo->prAdapter->rWifiVar.u4WakeLockThreadWakeup)); + + /* <8> Wake up main thread to handle kick start the I/O request. + * Use memory barrier to ensure set bit is done and then wake up main + * thread. + */ + smp_mb(); + wake_up_interruptible(&prGlueInfo->waitq); + + /* <9> Block and wait for event or timeout, + * current the timeout is 30 secs + */ + kalThreadSchedMark(prGlueInfo->main_thread, &schedstats); + waitRet = wait_for_completion_timeout(&prGlueInfo->rPendComp, + MSEC_TO_JIFFIES(30*1000)); + kalThreadSchedUnmark(prGlueInfo->main_thread, &schedstats); + if (waitRet > 0) { + /* Case 1: No timeout. */ + /* if return WLAN_STATUS_PENDING, the status of cmd is stored + * in prGlueInfo + */ + if (prIoReq->rStatus == WLAN_STATUS_PENDING) + ret = prGlueInfo->rPendStatus; + else + ret = prIoReq->rStatus; + if (ret != WLAN_STATUS_SUCCESS) + DBGLOG(OID, WARN, "kalIoctl: ret ErrCode: %x\n", ret); + } else { + +#if 0 + /* Case 2: timeout */ + /* clear pending OID's cmd in CMD queue */ + if (fgCmd) { + prGlueInfo->u4TimeoutFlag = 1; + wlanReleasePendingOid(prGlueInfo->prAdapter, 0); + } +#endif + /* note: do not dump main_thread's call stack here, */ + /* because it may be running on other cpu. */ + DBGLOG(OID, WARN, + "wait main_thread timeout, duration:%llums, sched(x%llu/r%llu/i%llu)\n", + schedstats.time, schedstats.exec, + schedstats.runnable, schedstats.iowait); + + ret = WLAN_STATUS_FAILURE; + } + + /* <10> Clear bit for error handling */ + clear_bit(GLUE_FLAG_OID_BIT, &prGlueInfo->ulFlag); + + up(&prGlueInfo->ioctl_sem); + up(&g_halt_sem); + + return ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used to clear all pending security frames + * + * \param prGlueInfo Pointer of GLUE Data Structure + * + * \retval none + */ +/*----------------------------------------------------------------------------*/ +void kalClearSecurityFrames(IN struct GLUE_INFO *prGlueInfo) +{ + struct QUE *prCmdQue; + struct QUE rTempCmdQue; + struct QUE *prTempCmdQue = &rTempCmdQue; + struct QUE rReturnCmdQue; + struct QUE *prReturnCmdQue = &rReturnCmdQue; + struct QUE_ENTRY *prQueueEntry = (struct QUE_ENTRY *) NULL; + + struct CMD_INFO *prCmdInfo = (struct CMD_INFO *) NULL; + + GLUE_SPIN_LOCK_DECLARATION(); + + ASSERT(prGlueInfo); + + QUEUE_INITIALIZE(prReturnCmdQue); + /* Clear pending security frames in prGlueInfo->rCmdQueue */ + prCmdQue = &prGlueInfo->rCmdQueue; + + GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); + QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); + GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); + + QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, + struct QUE_ENTRY *); + while (prQueueEntry) { + prCmdInfo = (struct CMD_INFO *) prQueueEntry; + + if (prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME || + prCmdInfo->eCmdType == COMMAND_TYPE_DATA_FRAME) { + if (prCmdInfo->pfCmdTimeoutHandler) + prCmdInfo->pfCmdTimeoutHandler( + prGlueInfo->prAdapter, prCmdInfo); + else + wlanReleaseCommand(prGlueInfo->prAdapter, + prCmdInfo, TX_RESULT_QUEUE_CLEARANCE); + cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo); + GLUE_DEC_REF_CNT(prGlueInfo->i4TxPendingCmdNum); + } else { + QUEUE_INSERT_TAIL(prReturnCmdQue, prQueueEntry); + } + + QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, + struct QUE_ENTRY *); + } + + GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); + QUEUE_CONCATENATE_QUEUES_HEAD(prCmdQue, prReturnCmdQue); + GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used to clear pending security frames + * belongs to dedicated network type + * + * \param prGlueInfo Pointer of GLUE Data Structure + * \param eNetworkTypeIdx Network Type Index + * + * \retval none + */ +/*----------------------------------------------------------------------------*/ +void kalClearSecurityFramesByBssIdx(IN struct GLUE_INFO + *prGlueInfo, IN uint8_t ucBssIndex) +{ + struct QUE *prCmdQue; + struct QUE rTempCmdQue; + struct QUE *prTempCmdQue = &rTempCmdQue; + struct QUE rReturnCmdQue; + struct QUE *prReturnCmdQue = &rReturnCmdQue; + struct QUE_ENTRY *prQueueEntry = (struct QUE_ENTRY *) NULL; + struct CMD_INFO *prCmdInfo = (struct CMD_INFO *) NULL; + struct MSDU_INFO *prMsduInfo; + u_int8_t fgFree; + + GLUE_SPIN_LOCK_DECLARATION(); + + ASSERT(prGlueInfo); + + QUEUE_INITIALIZE(prReturnCmdQue); + /* Clear pending security frames in prGlueInfo->rCmdQueue */ + prCmdQue = &prGlueInfo->rCmdQueue; + + GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); + QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); + GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); + + QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, + struct QUE_ENTRY *); + while (prQueueEntry) { + prCmdInfo = (struct CMD_INFO *) prQueueEntry; + prMsduInfo = prCmdInfo->prMsduInfo; + fgFree = FALSE; + + if ((prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME || + prCmdInfo->eCmdType == COMMAND_TYPE_DATA_FRAME) + && prMsduInfo) { + if (prMsduInfo->ucBssIndex == ucBssIndex) + fgFree = TRUE; + } + + if (fgFree) { + if (prCmdInfo->pfCmdTimeoutHandler) + prCmdInfo->pfCmdTimeoutHandler( + prGlueInfo->prAdapter, prCmdInfo); + else + wlanReleaseCommand(prGlueInfo->prAdapter, + prCmdInfo, TX_RESULT_QUEUE_CLEARANCE); + cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo); + GLUE_DEC_REF_CNT(prGlueInfo->i4TxPendingCmdNum); + } else + QUEUE_INSERT_TAIL(prReturnCmdQue, prQueueEntry); + + QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, + struct QUE_ENTRY *); + } + + GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); + QUEUE_CONCATENATE_QUEUES_HEAD(prCmdQue, prReturnCmdQue); + GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used to clear all pending management frames + * + * \param prGlueInfo Pointer of GLUE Data Structure + * + * \retval none + */ +/*----------------------------------------------------------------------------*/ +void kalClearMgmtFrames(IN struct GLUE_INFO *prGlueInfo) +{ + struct QUE *prCmdQue; + struct QUE rTempCmdQue; + struct QUE *prTempCmdQue = &rTempCmdQue; + struct QUE rReturnCmdQue; + struct QUE *prReturnCmdQue = &rReturnCmdQue; + struct QUE_ENTRY *prQueueEntry = (struct QUE_ENTRY *) NULL; + struct CMD_INFO *prCmdInfo = (struct CMD_INFO *) NULL; + + GLUE_SPIN_LOCK_DECLARATION(); + + ASSERT(prGlueInfo); + + QUEUE_INITIALIZE(prReturnCmdQue); + /* Clear pending management frames in prGlueInfo->rCmdQueue */ + prCmdQue = &prGlueInfo->rCmdQueue; + + GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); + QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); + GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); + + QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, + struct QUE_ENTRY *); + while (prQueueEntry) { + prCmdInfo = (struct CMD_INFO *) prQueueEntry; + + if (prCmdInfo->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME) { + wlanReleaseCommand(prGlueInfo->prAdapter, prCmdInfo, + TX_RESULT_QUEUE_CLEARANCE); + cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo); + GLUE_DEC_REF_CNT(prGlueInfo->i4TxPendingCmdNum); + } else { + QUEUE_INSERT_TAIL(prReturnCmdQue, prQueueEntry); + } + + QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, + struct QUE_ENTRY *); + } + + GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); + QUEUE_CONCATENATE_QUEUES_HEAD(prCmdQue, prReturnCmdQue); + GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used to clear all pending management frames + * belongs to dedicated network type + * \param prGlueInfo Pointer of GLUE Data Structure + * + * \retval none + */ +/*----------------------------------------------------------------------------*/ +void kalClearMgmtFramesByBssIdx(IN struct GLUE_INFO + *prGlueInfo, IN uint8_t ucBssIndex) +{ + struct QUE *prCmdQue; + struct QUE rTempCmdQue; + struct QUE *prTempCmdQue = &rTempCmdQue; + struct QUE rReturnCmdQue; + struct QUE *prReturnCmdQue = &rReturnCmdQue; + struct QUE_ENTRY *prQueueEntry = (struct QUE_ENTRY *) NULL; + struct CMD_INFO *prCmdInfo = (struct CMD_INFO *) NULL; + struct MSDU_INFO *prMsduInfo; + u_int8_t fgFree; + + GLUE_SPIN_LOCK_DECLARATION(); + + ASSERT(prGlueInfo); + + QUEUE_INITIALIZE(prReturnCmdQue); + /* Clear pending management frames in prGlueInfo->rCmdQueue */ + prCmdQue = &prGlueInfo->rCmdQueue; + + GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); + QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); + GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); + + QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, + struct QUE_ENTRY *); + while (prQueueEntry) { + prCmdInfo = (struct CMD_INFO *) prQueueEntry; + prMsduInfo = prCmdInfo->prMsduInfo; + fgFree = FALSE; + + if (prCmdInfo->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME + && prMsduInfo) { + if (prMsduInfo->ucBssIndex == ucBssIndex) + fgFree = TRUE; + } + + if (fgFree) { + wlanReleaseCommand(prGlueInfo->prAdapter, prCmdInfo, + TX_RESULT_QUEUE_CLEARANCE); + cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo); + GLUE_DEC_REF_CNT(prGlueInfo->i4TxPendingCmdNum); + } else { + QUEUE_INSERT_TAIL(prReturnCmdQue, prQueueEntry); + } + + QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, + struct QUE_ENTRY *); + } + + GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); + QUEUE_CONCATENATE_QUEUES_HEAD(prCmdQue, prReturnCmdQue); + GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); +} /* kalClearMgmtFramesByBssIdx */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used to clear all commands in command queue + * \param prGlueInfo Pointer of GLUE Data Structure + * + * \retval none + */ +/*----------------------------------------------------------------------------*/ +void kalClearCommandQueue(IN struct GLUE_INFO *prGlueInfo) +{ + struct QUE *prCmdQue; + struct QUE rTempCmdQue; + struct QUE *prTempCmdQue = &rTempCmdQue; + struct QUE rReturnCmdQue; + struct QUE *prReturnCmdQue = &rReturnCmdQue; + struct QUE_ENTRY *prQueueEntry = (struct QUE_ENTRY *) NULL; + struct CMD_INFO *prCmdInfo = (struct CMD_INFO *) NULL; + + GLUE_SPIN_LOCK_DECLARATION(); + + ASSERT(prGlueInfo); + + QUEUE_INITIALIZE(prReturnCmdQue); + + /* Clear ALL in prGlueInfo->rCmdQueue */ + prCmdQue = &prGlueInfo->rCmdQueue; + + GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); + QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); + GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); + + QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, + struct QUE_ENTRY *); + while (prQueueEntry) { + prCmdInfo = (struct CMD_INFO *) prQueueEntry; + + if (prCmdInfo->pfCmdTimeoutHandler) + prCmdInfo->pfCmdTimeoutHandler(prGlueInfo->prAdapter, + prCmdInfo); + else + wlanReleaseCommand(prGlueInfo->prAdapter, prCmdInfo, + TX_RESULT_QUEUE_CLEARANCE); + + cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo); + GLUE_DEC_REF_CNT(prGlueInfo->i4TxPendingCmdNum); + + QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, + struct QUE_ENTRY *); + } +} + +#if CFG_SUPPORT_LOWLATENCY_MODE +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used to check use packet data into command Queue flow + * + * \param prAdapter Pointer of prAdapter Structure + * \param prAdapter Pointer of prAdapter Structure + * \retval is TRUE (run command Data path flow) or FALSE (not use) + */ +/*----------------------------------------------------------------------------*/ +u_int8_t kalIsCommandDataPath(IN struct ADAPTER + *prAdapter, IN void *prPacket) +{ + struct sk_buff *skb = (struct sk_buff *)prPacket; + + if (prAdapter->rWifiVar.ucLowLatencyCmdData == 0) + return FALSE; + + if (!prAdapter->fgTxDupCertificate) + return FALSE; + + if (!prAdapter->fgEnTxDupDetect) + return FALSE; + + /* Only detect for special mark packet */ + if (!prAdapter->rWifiVar.ucLowLatencyCmdDataAllPacket && + !(skb->mark & BIT(NIC_TX_SKB_DUP_DETECT_MARK_BIT))) { + DBGLOG_LIMITED(TX, TRACE, + "mark flag=[%x]\n", skb->mark); + return FALSE; + } + + /* Not send special mark flag packets via command path */ + if (GLUE_IS_PKT_FLAG_SET(prPacket)) { + DBGLOG_LIMITED(TX, TRACE, + "Packet flag=[%d]\n", GLUE_IS_PKT_FLAG_SET(prPacket)); + return FALSE; + } + + /* Only handle checksum calculated packets, must not enable + * checksum offload for command data packet. Refer to + * kalQueryTxChksumOffloadParam() + */ + if (skb->ip_summed != CHECKSUM_NONE) { + DBGLOG_LIMITED(TX, TRACE, + "Packet checksum not calculated, ip_summed=[%d]", + skb->ip_summed); + return FALSE; + } + + if (prAdapter->tmTxDataInterval > 0 && + !CHECK_FOR_TIMEOUT(kalGetTimeTick(), + prAdapter->tmTxDataInterval, 10)) { + DBGLOG_LIMITED(TX, TRACE, "Packet interval too close"); + return FALSE; + } + GET_CURRENT_SYSTIME(&prAdapter->tmTxDataInterval); + + DBGLOG_LIMITED(TX, INFO, + "Change data to cmd data frame. Packet flag=[%d], ip_summed=[%d] mark=[%x]\n", + GLUE_IS_PKT_FLAG_SET(prPacket), + skb->ip_summed, + skb->mark); + + DBGLOG_LIMITED(TX, INFO, + "Change data to cmd data frame. Packet flag=[%d], ip_summed=[%d] mark=[%x]\n", + GLUE_IS_PKT_FLAG_SET(prPacket), + skb->ip_summed, + skb->mark); + + return TRUE; +} +#endif + +uint32_t kalProcessTxPacket(struct GLUE_INFO *prGlueInfo, + struct sk_buff *prSkb) +{ + uint32_t u4Status = WLAN_STATUS_SUCCESS; + + if (prSkb == NULL) { + DBGLOG(INIT, WARN, "prSkb == NULL in tx\n"); + return u4Status; + } + + /* Handle security frame */ + if (0 /* GLUE_TEST_PKT_FLAG(prSkb, ENUM_PKT_1X) */ + /* No more sending via cmd */) { + if (wlanProcessSecurityFrame(prGlueInfo->prAdapter, + (void *) prSkb)) { + u4Status = WLAN_STATUS_SUCCESS; + GLUE_INC_REF_CNT( + prGlueInfo->i4TxPendingSecurityFrameNum); + } else { + u4Status = WLAN_STATUS_RESOURCES; + } + } +#if CFG_SUPPORT_LOWLATENCY_MODE + /* Data frame use command path */ + else if (kalIsCommandDataPath(prGlueInfo->prAdapter, + (void *) prSkb)) { + u4Status = wlanProcessCmdDataFrame(prGlueInfo->prAdapter, + (void *) prSkb); + if (u4Status == WLAN_STATUS_SUCCESS) + GLUE_INC_REF_CNT( + prGlueInfo->i4TxPendingSecurityFrameNum); + + } +#endif + /* Handle normal frame */ + else + u4Status = wlanEnqueueTxPacket(prGlueInfo->prAdapter, + (void *) prSkb); + + return u4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used to process Tx request to main_thread + * + * \param prGlueInfo Pointer of GLUE Data Structure + * + * \retval none + */ +/*----------------------------------------------------------------------------*/ +void kalProcessTxReq(struct GLUE_INFO *prGlueInfo, + u_int8_t *pfgNeedHwAccess) +{ + struct QUE *prCmdQue = NULL; + struct QUE *prTxQueue = NULL; + struct QUE rTempQue; + struct QUE *prTempQue = &rTempQue; + struct QUE rTempReturnQue; + struct QUE *prTempReturnQue = &rTempReturnQue; + struct QUE_ENTRY *prQueueEntry = NULL; + /* struct sk_buff *prSkb = NULL; */ + uint32_t u4Status; +#if CFG_SUPPORT_MULTITHREAD + uint32_t u4CmdCount = 0; +#endif + uint32_t u4TxLoopCount; + + /* for spin lock acquire and release */ + GLUE_SPIN_LOCK_DECLARATION(); + + prTxQueue = &prGlueInfo->rTxQueue; + prCmdQue = &prGlueInfo->rCmdQueue; + + QUEUE_INITIALIZE(prTempQue); + QUEUE_INITIALIZE(prTempReturnQue); + + u4TxLoopCount = + prGlueInfo->prAdapter->rWifiVar.u4TxFromOsLoopCount; + + /* Process Mailbox Messages */ + wlanProcessMboxMessage(prGlueInfo->prAdapter); + + /* Process CMD request */ +#if CFG_SUPPORT_MULTITHREAD + GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); + u4CmdCount = prCmdQue->u4NumElem; + GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); + if (u4CmdCount > 0) + wlanProcessCommandQueue(prGlueInfo->prAdapter, prCmdQue); + +#else + if (prCmdQue->u4NumElem > 0) { + if (*pfgNeedHwAccess == FALSE) { + *pfgNeedHwAccess = TRUE; + + wlanAcquirePowerControl(prGlueInfo->prAdapter); + } + wlanProcessCommandQueue(prGlueInfo->prAdapter, prCmdQue); + } +#endif + + while (u4TxLoopCount--) { + while (QUEUE_IS_NOT_EMPTY(prTxQueue)) { + GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); + QUEUE_MOVE_ALL(prTempQue, prTxQueue); + GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); + + kalTraceBegin("Move TxQueue %d", prTempQue->u4NumElem); + /* Handle Packet Tx */ + while (QUEUE_IS_NOT_EMPTY(prTempQue)) { + QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, + struct QUE_ENTRY *); + + if (prQueueEntry == NULL) + break; + + u4Status = kalProcessTxPacket(prGlueInfo, + (struct sk_buff *) + GLUE_GET_PKT_DESCRIPTOR( + prQueueEntry)); +#if 0 + prSkb = (struct sk_buff *) + GLUE_GET_PKT_DESCRIPTOR(prQueueEntry); + ASSERT(prSkb); + if (prSkb == NULL) { + DBGLOG(INIT, WARN, + "prSkb == NULL in tx\n"); + continue; + } + + /* Handle security frame */ + if (GLUE_GET_PKT_IS_1X(prSkb)) { + if (wlanProcessSecurityFrame( + prGlueInfo->prAdapter, + (void *)prSkb)) { + u4Status = WLAN_STATUS_SUCCESS; + GLUE_INC_REF_CNT(prGlueInfo-> + i4TxPendingSecurityFrameNum); + } else { + u4Status = + WLAN_STATUS_RESOURCES; + } + } + /* Handle normal frame */ + else + u4Status = wlanEnqueueTxPacket( + prGlueInfo->prAdapter, + (void *) prSkb); +#endif + /* Enqueue packet back into TxQueue if resource + * is not enough + */ + if (u4Status == WLAN_STATUS_RESOURCES) { + QUEUE_INSERT_TAIL(prTempReturnQue, + prQueueEntry); + break; + } + + if (wlanGetTxPendingFrameCount( + prGlueInfo->prAdapter) > 0) + wlanTxPendingPackets( + prGlueInfo->prAdapter, + pfgNeedHwAccess); + } + kalTraceEnd(); + + /* Enqueue packet back into TxQueue if resource is not + * enough + */ + if (QUEUE_IS_NOT_EMPTY(prTempReturnQue)) { + QUEUE_CONCATENATE_QUEUES(prTempReturnQue, + prTempQue); + + GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, + SPIN_LOCK_TX_QUE); + QUEUE_CONCATENATE_QUEUES_HEAD(prTxQueue, + prTempReturnQue); + GLUE_RELEASE_SPIN_LOCK(prGlueInfo, + SPIN_LOCK_TX_QUE); + + break; + } + } + if (wlanGetTxPendingFrameCount(prGlueInfo->prAdapter) > 0) + wlanTxPendingPackets(prGlueInfo->prAdapter, + pfgNeedHwAccess); + } + +} + +#if CFG_SUPPORT_MULTITHREAD + +/*----------------------------------------------------------------------------*/ +/*! + * @brief + * + * @param data data pointer to private data of hif_thread + * + * @retval If the function succeeds, the return value is 0. + * Otherwise, an error code is returned. + * + */ +/*----------------------------------------------------------------------------*/ + +int hif_thread(void *data) +{ + struct net_device *dev = data; + struct GLUE_INFO *prGlueInfo = *((struct GLUE_INFO **) + netdev_priv(dev)); + struct ADAPTER *prAdapter = prGlueInfo->prAdapter; + int ret = 0; + bool fgEnInt; +#if defined(CONFIG_ANDROID) && (CFG_ENABLE_WAKE_LOCK) + KAL_WAKE_LOCK_T *prHifThreadWakeLock; + + KAL_WAKE_LOCK_INIT(prGlueInfo->prAdapter, + prHifThreadWakeLock, "WLAN hif_thread"); + KAL_WAKE_LOCK(prGlueInfo->prAdapter, prHifThreadWakeLock); +#endif + + DBGLOG(INIT, INFO, "%s:%u starts running...\n", + KAL_GET_CURRENT_THREAD_NAME(), KAL_GET_CURRENT_THREAD_ID()); + + prGlueInfo->u4HifThreadPid = KAL_GET_CURRENT_THREAD_ID(); + + set_user_nice(current, prAdapter->rWifiVar.cThreadNice); + + while (TRUE) { + + if (prGlueInfo->ulFlag & GLUE_FLAG_HALT + || kalIsResetting() + ) { + DBGLOG(INIT, INFO, "hif_thread should stop now...\n"); + break; + } + + /* Unlock wakelock if hif_thread going to idle */ + if (!(prGlueInfo->ulFlag & GLUE_FLAG_HIF_PROCESS)) + KAL_WAKE_UNLOCK(prGlueInfo->prAdapter, + prHifThreadWakeLock); + + /* + * sleep on waitqueue if no events occurred. Event contain + * (1) GLUE_FLAG_INT (2) GLUE_FLAG_OID (3) GLUE_FLAG_TXREQ + * (4) GLUE_FLAG_HALT + * + */ + do { + ret = wait_event_interruptible(prGlueInfo->waitq_hif, + ((prGlueInfo->ulFlag & GLUE_FLAG_HIF_PROCESS) + != 0)); + } while (ret != 0); + + kalTraceBegin("hif_thread"); + +#if defined(CONFIG_ANDROID) && (CFG_ENABLE_WAKE_LOCK) + if (!KAL_WAKE_LOCK_ACTIVE(prGlueInfo->prAdapter, + prHifThreadWakeLock)) + KAL_WAKE_LOCK(prGlueInfo->prAdapter, + prHifThreadWakeLock); +#endif + if (prAdapter->fgIsFwOwn + && (prGlueInfo->ulFlag == GLUE_FLAG_HIF_FW_OWN)) { + DBGLOG(INIT, INFO, + "Only FW OWN request, but now already done FW OWN\n"); + clear_bit(GLUE_FLAG_HIF_FW_OWN_BIT, + &prGlueInfo->ulFlag); + continue; + } + wlanAcquirePowerControl(prAdapter); + + /* Handle Interrupt */ + fgEnInt = (prGlueInfo->ulFlag | GLUE_FLAG_INT_BIT) != 0; + if (test_and_clear_bit(GLUE_FLAG_INT_BIT, + &prGlueInfo->ulFlag) || + test_and_clear_bit(GLUE_FLAG_DRV_INT_BIT, + &prGlueInfo->ulFlag)) { + kalTraceBegin("INT"); + /* the Wi-Fi interrupt is already disabled in mmc + * thread, so we set the flag only to enable the + * interrupt later + */ + prAdapter->fgIsIntEnable = FALSE; + if (prGlueInfo->ulFlag & GLUE_FLAG_HALT + || kalIsResetting() + ) { + /* Should stop now... skip pending interrupt */ + DBGLOG(INIT, INFO, + "ignore pending interrupt\n"); + } else { + /* DBGLOG(INIT, INFO, ("HIF Interrupt!\n")); */ + prGlueInfo->TaskIsrCnt++; + wlanIST(prAdapter, fgEnInt); + } + kalTraceEnd(); + } + + /* Skip Tx request if SER is operating */ + if ((prAdapter->fgIsFwOwn == FALSE) && + !nicSerIsTxStop(prAdapter)) { + /* TX Commands */ + if (test_and_clear_bit(GLUE_FLAG_HIF_TX_CMD_BIT, + &prGlueInfo->ulFlag)) + TRACE(wlanTxCmdMthread(prAdapter), "TX_CMD"); + + /* Process TX data packet to HIF */ + if (test_and_clear_bit(GLUE_FLAG_HIF_TX_BIT, + &prGlueInfo->ulFlag)) + TRACE(nicTxMsduQueueMthread(prAdapter), "TX"); + } + + /* Read chip status when chip no response */ + if (test_and_clear_bit(GLUE_FLAG_HIF_PRT_HIF_DBG_INFO_BIT, + &prGlueInfo->ulFlag)) + TRACE(halPrintHifDbgInfo(prAdapter), "DBG_INFO"); + + /* Update Tx Quota */ + if (test_and_clear_bit(GLUE_FLAG_UPDATE_WMM_QUOTA_BIT, + &prGlueInfo->ulFlag)) + TRACE(halUpdateTxMaxQuota(prAdapter), "UPDATE_WMM"); + + /* Notify MD crash to FW */ + if (test_and_clear_bit(GLUE_FLAG_NOTIFY_MD_CRASH_BIT, + &prGlueInfo->ulFlag)) + halNotifyMdCrash(prAdapter); + + /* Set FW own */ + if (test_and_clear_bit(GLUE_FLAG_HIF_FW_OWN_BIT, + &prGlueInfo->ulFlag)) + prAdapter->fgWiFiInSleepyState = TRUE; + + kalDumpHifStats(prAdapter); + + /* Release to FW own */ + wlanReleasePowerControl(prAdapter); + kalTraceEnd(); /* hif_thread */ + } + + complete(&prGlueInfo->rHifHaltComp); +#if defined(CONFIG_ANDROID) && (CFG_ENABLE_WAKE_LOCK) + if (KAL_WAKE_LOCK_ACTIVE(prGlueInfo->prAdapter, + prHifThreadWakeLock)) + KAL_WAKE_UNLOCK(prGlueInfo->prAdapter, prHifThreadWakeLock); + KAL_WAKE_LOCK_DESTROY(prGlueInfo->prAdapter, + prHifThreadWakeLock); +#endif + + DBGLOG(INIT, TRACE, "%s:%u stopped!\n", + KAL_GET_CURRENT_THREAD_NAME(), KAL_GET_CURRENT_THREAD_ID()); + +#if CFG_CHIP_RESET_HANG + while (fgIsResetHangState == SER_L0_HANG_RST_HANG) { + kalMsleep(SER_L0_HANG_LOG_TIME_INTERVAL); + DBGLOG(INIT, STATE, "[SER][L0] SQC hang!\n"); + } +#endif + + return 0; +} + +int rx_thread(void *data) +{ + struct net_device *dev = data; + struct GLUE_INFO *prGlueInfo = *((struct GLUE_INFO **) + netdev_priv(dev)); + + struct QUE rTempRxQue; + struct QUE *prTempRxQue = NULL; + struct QUE_ENTRY *prQueueEntry = NULL; + + int ret = 0; +#if defined(CONFIG_ANDROID) && (CFG_ENABLE_WAKE_LOCK) + KAL_WAKE_LOCK_T *prRxThreadWakeLock; +#endif + uint32_t u4LoopCount; + + /* for spin lock acquire and release */ + KAL_SPIN_LOCK_DECLARATION(); + +#if defined(CONFIG_ANDROID) && (CFG_ENABLE_WAKE_LOCK) + KAL_WAKE_LOCK_INIT(prGlueInfo->prAdapter, + prRxThreadWakeLock, "WLAN rx_thread"); + KAL_WAKE_LOCK(prGlueInfo->prAdapter, prRxThreadWakeLock); +#endif + + DBGLOG(INIT, INFO, "%s:%u starts running...\n", + KAL_GET_CURRENT_THREAD_NAME(), KAL_GET_CURRENT_THREAD_ID()); + + prGlueInfo->u4RxThreadPid = KAL_GET_CURRENT_THREAD_ID(); + + set_user_nice(current, + prGlueInfo->prAdapter->rWifiVar.cThreadNice); + + prTempRxQue = &rTempRxQue; + + while (TRUE) { + + if (prGlueInfo->ulFlag & GLUE_FLAG_HALT + || kalIsResetting() + ) { + DBGLOG(INIT, INFO, "rx_thread should stop now...\n"); + break; + } + + /* Unlock wakelock if rx_thread going to idle */ + if (!(prGlueInfo->ulFlag & GLUE_FLAG_RX_PROCESS)) + KAL_WAKE_UNLOCK(prGlueInfo->prAdapter, + prRxThreadWakeLock); + + /* + * sleep on waitqueue if no events occurred. + */ + do { + ret = wait_event_interruptible(prGlueInfo->waitq_rx, + ((prGlueInfo->ulFlag & GLUE_FLAG_RX_PROCESS) != 0)); + } while (ret != 0); + + kalTraceBegin("rx_thread"); + +#if defined(CONFIG_ANDROID) && (CFG_ENABLE_WAKE_LOCK) + if (!KAL_WAKE_LOCK_ACTIVE(prGlueInfo->prAdapter, + prRxThreadWakeLock)) + KAL_WAKE_LOCK(prGlueInfo->prAdapter, + prRxThreadWakeLock); +#endif + if (test_and_clear_bit(GLUE_FLAG_RX_TO_OS_BIT, + &prGlueInfo->ulFlag)) { + kalTraceBegin("RX_TO_OS"); + u4LoopCount = + prGlueInfo->prAdapter->rWifiVar.u4Rx2OsLoopCount; + + while (u4LoopCount--) { + while (QUEUE_IS_NOT_EMPTY( + &prGlueInfo->prAdapter->rRxQueue)) { + QUEUE_INITIALIZE(prTempRxQue); + + GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, + SPIN_LOCK_RX_TO_OS_QUE); + QUEUE_MOVE_ALL(prTempRxQue, + &prGlueInfo->prAdapter->rRxQueue); + GLUE_RELEASE_SPIN_LOCK(prGlueInfo, + SPIN_LOCK_RX_TO_OS_QUE); + + while (QUEUE_IS_NOT_EMPTY( + prTempRxQue)) { + QUEUE_REMOVE_HEAD(prTempRxQue, + prQueueEntry, + struct QUE_ENTRY *); + kalRxIndicateOnePkt(prGlueInfo, + (void *) + GLUE_GET_PKT_DESCRIPTOR( + prQueueEntry)); + } + + KAL_WAKE_LOCK_TIMEOUT(prGlueInfo->prAdapter, + prGlueInfo->rTimeoutWakeLock, + MSEC_TO_JIFFIES(prGlueInfo->prAdapter + ->rWifiVar.u4WakeLockRxTimeout)); + } + } + kalTraceEnd(); /* RX_TO_OS */ + } + + kalTraceEnd(); /* rx_thread*/ + } + + complete(&prGlueInfo->rRxHaltComp); +#if defined(CONFIG_ANDROID) && (CFG_ENABLE_WAKE_LOCK) + if (KAL_WAKE_LOCK_ACTIVE(prGlueInfo->prAdapter, + prRxThreadWakeLock)) + KAL_WAKE_UNLOCK(prGlueInfo->prAdapter, prRxThreadWakeLock); + KAL_WAKE_LOCK_DESTROY(prGlueInfo->prAdapter, + prRxThreadWakeLock); +#endif + + DBGLOG(INIT, TRACE, "%s:%u stopped!\n", + KAL_GET_CURRENT_THREAD_NAME(), KAL_GET_CURRENT_THREAD_ID()); + +#if CFG_CHIP_RESET_HANG + while (fgIsResetHangState == SER_L0_HANG_RST_HANG) { + kalMsleep(SER_L0_HANG_LOG_TIME_INTERVAL); + DBGLOG(INIT, STATE, "[SER][L0] SQC hang!\n"); + } +#endif + + return 0; +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This function is a kernel thread function for handling command packets + * Tx requests and interrupt events + * + * @param data data pointer to private data of main_thread + * + * @retval If the function succeeds, the return value is 0. + * Otherwise, an error code is returned. + * + */ +/*----------------------------------------------------------------------------*/ + +int main_thread(void *data) +{ + struct net_device *dev = data; + struct GLUE_INFO *prGlueInfo = *((struct GLUE_INFO **) + netdev_priv(dev)); + struct GL_IO_REQ *prIoReq = NULL; + int ret = 0; + u_int8_t fgNeedHwAccess = FALSE; +#if defined(CONFIG_ANDROID) && (CFG_ENABLE_WAKE_LOCK) + KAL_WAKE_LOCK_T *prTxThreadWakeLock; +#endif + +#if CFG_SUPPORT_MULTITHREAD + prGlueInfo->u4TxThreadPid = KAL_GET_CURRENT_THREAD_ID(); +#endif + + current->flags |= PF_NOFREEZE; + ASSERT(prGlueInfo); + ASSERT(prGlueInfo->prAdapter); + set_user_nice(current, + prGlueInfo->prAdapter->rWifiVar.cThreadNice); + +#if defined(CONFIG_ANDROID) && (CFG_ENABLE_WAKE_LOCK) + KAL_WAKE_LOCK_INIT(prGlueInfo->prAdapter, + prTxThreadWakeLock, "WLAN main_thread"); + KAL_WAKE_LOCK(prGlueInfo->prAdapter, prTxThreadWakeLock); +#endif + + DBGLOG(INIT, INFO, "%s:%u starts running...\n", + KAL_GET_CURRENT_THREAD_NAME(), KAL_GET_CURRENT_THREAD_ID()); + + while (TRUE) { +#ifdef UT_TEST_MODE + testThreadBegin(prGlueInfo->prAdapter); +#endif + +#if CFG_ENABLE_WIFI_DIRECT + /*run p2p multicast list work. */ + if (test_and_clear_bit(GLUE_FLAG_SUB_MOD_MULTICAST_BIT, + &prGlueInfo->ulFlag)) + p2pSetMulticastListWorkQueueWrapper(prGlueInfo); +#endif + + if (prGlueInfo->ulFlag & GLUE_FLAG_HALT + || kalIsResetting() + ) { + DBGLOG(INIT, INFO, "%s should stop now...\n", + KAL_GET_CURRENT_THREAD_NAME()); + break; + } + + /* Unlock wakelock if main_thread going to idle */ + if (!(prGlueInfo->ulFlag & GLUE_FLAG_MAIN_PROCESS)) + KAL_WAKE_UNLOCK(prGlueInfo->prAdapter, + prTxThreadWakeLock); + + /* + * sleep on waitqueue if no events occurred. Event contain + * (1) GLUE_FLAG_INT (2) GLUE_FLAG_OID (3) GLUE_FLAG_TXREQ + * (4) GLUE_FLAG_HALT + */ + do { + ret = wait_event_interruptible(prGlueInfo->waitq, + ((prGlueInfo->ulFlag & GLUE_FLAG_MAIN_PROCESS) + != 0)); + } while (ret != 0); +#if defined(CONFIG_ANDROID) && (CFG_ENABLE_WAKE_LOCK) + if (!KAL_WAKE_LOCK_ACTIVE(prGlueInfo->prAdapter, + prTxThreadWakeLock)) + KAL_WAKE_LOCK(prGlueInfo->prAdapter, + prTxThreadWakeLock); +#endif + kalTraceBegin("main_thread"); + +#if CFG_ENABLE_WIFI_DIRECT + /*run p2p multicast list work. */ + if (test_and_clear_bit(GLUE_FLAG_SUB_MOD_MULTICAST_BIT, + &prGlueInfo->ulFlag)) + p2pSetMulticastListWorkQueueWrapper(prGlueInfo); + + if (test_and_clear_bit(GLUE_FLAG_FRAME_FILTER_BIT, + &prGlueInfo->ulFlag) + && prGlueInfo->prP2PDevInfo) { + /* P2p info will be null after p2p removed. */ + p2pFuncUpdateMgmtFrameRegister(prGlueInfo->prAdapter, + prGlueInfo->prP2PDevInfo->u4OsMgmtFrameFilter); + } +#endif + + if (test_and_clear_bit(GLUE_FLAG_FRAME_FILTER_AIS_BIT, + &prGlueInfo->ulFlag)) { + uint32_t i; + + kalTraceBegin("FRAME_FILTER_AIS"); + for (i = 0; i < KAL_AIS_NUM; i++) { + struct AIS_FSM_INFO *prAisFsmInfo = + (struct AIS_FSM_INFO *)NULL; + + /* printk("prGlueInfo->u4OsMgmtFrameFilter = %x", + * prGlueInfo->u4OsMgmtFrameFilter); + */ + prAisFsmInfo = + aisGetAisFsmInfo(prGlueInfo->prAdapter, + i); + + if (!prAisFsmInfo) + continue; + + prAisFsmInfo->u4AisPacketFilter = + prGlueInfo->u4OsMgmtFrameFilter; + } + kalTraceEnd(); + } + + if (prGlueInfo->ulFlag & GLUE_FLAG_HALT + || kalIsResetting() + ) { + DBGLOG(INIT, INFO, "%s should stop now...\n", + KAL_GET_CURRENT_THREAD_NAME()); + break; + } + + fgNeedHwAccess = FALSE; + +#if CFG_SUPPORT_SDIO_READ_WRITE_PATTERN + if (prGlueInfo->fgEnSdioTestPattern == TRUE) { + if (fgNeedHwAccess == FALSE) { + fgNeedHwAccess = TRUE; + + wlanAcquirePowerControl(prGlueInfo->prAdapter); + } + + if (prGlueInfo->fgIsSdioTestInitialized == FALSE) { + /* enable PRBS mode */ + kalDevRegWrite(prGlueInfo, MCR_WTMCR, + 0x00080002); + prGlueInfo->fgIsSdioTestInitialized = TRUE; + } + + if (prGlueInfo->fgSdioReadWriteMode == TRUE) { + /* read test */ + kalDevPortRead(prGlueInfo, MCR_WTMDR, 256, + prGlueInfo->aucSdioTestBuffer, + sizeof(prGlueInfo->aucSdioTestBuffer)); + } else { + /* write test */ + kalDevPortWrite(prGlueInfo, MCR_WTMDR, 172, + prGlueInfo->aucSdioTestBuffer, + sizeof(prGlueInfo->aucSdioTestBuffer)); + } + } +#endif +#if CFG_SUPPORT_MULTITHREAD +#else + + /* Handle Interrupt */ + if (test_and_clear_bit(GLUE_FLAG_INT_BIT, + &prGlueInfo->ulFlag)) { + kalTraceBegin("INT"); + if (fgNeedHwAccess == FALSE) { + fgNeedHwAccess = TRUE; + + wlanAcquirePowerControl(prGlueInfo->prAdapter); + } + + /* the Wi-Fi interrupt is already disabled in mmc + * thread, so we set the flag only to enable the + * interrupt later + */ + prGlueInfo->prAdapter->fgIsIntEnable = FALSE; + /* wlanISR(prGlueInfo->prAdapter, TRUE); */ + + if (prGlueInfo->ulFlag & GLUE_FLAG_HALT + || kalIsResetting() + ) { + /* Should stop now... skip pending interrupt */ + DBGLOG(INIT, INFO, + "ignore pending interrupt\n"); + } else { + prGlueInfo->TaskIsrCnt++; + wlanIST(prGlueInfo->prAdapter, true); + } + kalTraceEnd(); + } + + if (test_and_clear_bit(GLUE_FLAG_UPDATE_WMM_QUOTA_BIT, + &prGlueInfo->ulFlag)) + TRACE(halUpdateTxMaxQuota(prGlueInfo->prAdapter), + "UPDATE_WMM"); +#endif + /* transfer ioctl to OID request */ +#ifdef UT_TEST_MODE + testProcessOid(prGlueInfo->prAdapter); +#endif + if (test_and_clear_bit(GLUE_FLAG_OID_BIT, + &prGlueInfo->ulFlag)) { + kalTraceBegin("OID"); + /* get current prIoReq */ + prIoReq = &(prGlueInfo->OidEntry); + if (prIoReq->fgRead == FALSE) { + prIoReq->rStatus = wlanSetInformation( + prIoReq->prAdapter, + prIoReq->pfnOidHandler, + prIoReq->pvInfoBuf, + prIoReq->u4InfoBufLen, + prIoReq->pu4QryInfoLen); + } else { + prIoReq->rStatus = wlanQueryInformation( + prIoReq->prAdapter, + prIoReq->pfnOidHandler, + prIoReq->pvInfoBuf, + prIoReq->u4InfoBufLen, + prIoReq->pu4QryInfoLen); + } + + if (prIoReq->rStatus != WLAN_STATUS_PENDING) { + /* complete ONLY if there are waiters */ + if (!completion_done( + &prGlueInfo->rPendComp)) + complete( + &prGlueInfo->rPendComp); + else + DBGLOG(INIT, WARN, + "SKIP multiple OID complete!\n" + ); + } else { + wlanoidTimeoutCheck( + prGlueInfo->prAdapter, + prIoReq->pfnOidHandler); + } + kalTraceEnd(); + } + + /* + * + * if TX request, clear the TXREQ flag. TXREQ set by + * kalSetEvent/GlueSetEvent + * indicates the following requests occur + * + */ + +#ifdef UT_TEST_MODE + testProcessTxReq(prGlueInfo->prAdapter); +#endif + + if (test_and_clear_bit(GLUE_FLAG_TXREQ_BIT, + &prGlueInfo->ulFlag)) + TRACE(kalProcessTxReq(prGlueInfo, &fgNeedHwAccess), + "TXREQ"); + +#if CFG_SUPPORT_MULTITHREAD + /* Process RX */ +#ifdef UT_TEST_MODE + testProcessRFBs(prGlueInfo->prAdapter); +#endif + + if (test_and_clear_bit(GLUE_FLAG_RX_BIT, + &prGlueInfo->ulFlag)) + TRACE(nicRxProcessRFBs(prGlueInfo->prAdapter), "RX"); + + if (test_and_clear_bit(GLUE_FLAG_TX_CMD_DONE_BIT, + &prGlueInfo->ulFlag)) + TRACE(wlanTxCmdDoneMthread(prGlueInfo->prAdapter), + "TX_CMD"); +#endif + + /* Process RX, In linux, we don't need to free sk_buff by + * ourself + */ + + /* In linux, we don't need to free sk_buff by ourself */ + + /* In linux, we don't do reset */ +#if CFG_SUPPORT_MULTITHREAD +#else + if (fgNeedHwAccess == TRUE) + wlanReleasePowerControl(prGlueInfo->prAdapter); +#endif + /* handle cnmTimer time out */ +#ifdef UT_TEST_MODE + testTimeoutCheck(prGlueInfo->prAdapter); +#endif + + /* update current throughput */ + kalPerMonUpdate(prGlueInfo->prAdapter); + + if (test_and_clear_bit(GLUE_FLAG_TIMEOUT_BIT, + &prGlueInfo->ulFlag)) + TRACE(wlanTimerTimeoutCheck(prGlueInfo->prAdapter), + "TIMEOUT"); + +#if CFG_SUPPORT_SDIO_READ_WRITE_PATTERN + if (prGlueInfo->fgEnSdioTestPattern == TRUE) + kalSetEvent(prGlueInfo); +#endif +#ifdef UT_TEST_MODE + testThreadEnd(prGlueInfo->prAdapter); +#endif +#if (CFG_SUPPORT_CONNINFRA == 1) + if (test_and_clear_bit(GLUE_FLAG_SER_TIMEOUT_BIT, + &prGlueInfo->ulFlag)) + GL_RESET_TRIGGER(prGlueInfo->prAdapter, + RST_FLAG_DO_CORE_DUMP); +#endif + kalTraceEnd(); /* main_thread */ + } + +#if 0 + if (fgNeedHwAccess == TRUE) + wlanReleasePowerControl(prGlueInfo->prAdapter); +#endif + + /* flush the pending TX packets */ + if (GLUE_GET_REF_CNT(prGlueInfo->i4TxPendingFrameNum) > 0) + kalFlushPendingTxPackets(prGlueInfo); + + /* flush pending security frames */ + if (GLUE_GET_REF_CNT( + prGlueInfo->i4TxPendingSecurityFrameNum) > 0) + kalClearSecurityFrames(prGlueInfo); + + /* remove pending oid */ + wlanReleasePendingOid(prGlueInfo->prAdapter, 0); + + complete(&prGlueInfo->rHaltComp); +#if defined(CONFIG_ANDROID) && (CFG_ENABLE_WAKE_LOCK) + if (KAL_WAKE_LOCK_ACTIVE(prGlueInfo->prAdapter, + prTxThreadWakeLock)) + KAL_WAKE_UNLOCK(prGlueInfo->prAdapter, prTxThreadWakeLock); + KAL_WAKE_LOCK_DESTROY(prGlueInfo->prAdapter, + prTxThreadWakeLock); +#endif + + DBGLOG(INIT, TRACE, "%s:%u stopped!\n", + KAL_GET_CURRENT_THREAD_NAME(), KAL_GET_CURRENT_THREAD_ID()); + +#if CFG_CHIP_RESET_HANG + while (fgIsResetHangState == SER_L0_HANG_RST_HANG) { + kalMsleep(SER_L0_HANG_LOG_TIME_INTERVAL); + DBGLOG(INIT, STATE, "[SER][L0] SQC hang!\n"); + } +#endif + + return 0; + +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used to check if card is removed + * + * \param pvGlueInfo Pointer of GLUE Data Structure + * + * \retval TRUE: card is removed + * FALSE: card is still attached + */ +/*----------------------------------------------------------------------------*/ +u_int8_t kalIsCardRemoved(IN struct GLUE_INFO *prGlueInfo) +{ + ASSERT(prGlueInfo); + + return FALSE; + /* Linux MMC doesn't have removal notification yet */ +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used to send command to firmware for overriding + * netweork address + * + * \param pvGlueInfo Pointer of GLUE Data Structure + * + * \retval TRUE + * FALSE + */ +/*----------------------------------------------------------------------------*/ +u_int8_t kalRetrieveNetworkAddress(IN struct GLUE_INFO *prGlueInfo, + IN OUT uint8_t *prMacAddr) +{ + ASSERT(prGlueInfo); + + /* Get MAC address override from wlan feature option */ + prGlueInfo->fgIsMacAddrOverride = + prGlueInfo->prAdapter->rWifiVar.ucMacAddrOverride; + + wlanHwAddrToBin( + prGlueInfo->prAdapter->rWifiVar.aucMacAddrStr, + prGlueInfo->rMacAddrOverride); + + if (prGlueInfo->fgIsMacAddrOverride == FALSE) { + +#ifdef CFG_ENABLE_EFUSE_MAC_ADDR + if (prGlueInfo->prAdapter->fgIsEmbbededMacAddrValid) { + COPY_MAC_ADDR(prMacAddr, + prGlueInfo->prAdapter->rWifiVar.aucMacAddress); + return TRUE; + } else { + return FALSE; + } +#else +#if CFG_TC1_FEATURE + /*LGE_FacReadWifiMacAddr(prMacAddr);*/ + TC1_FAC_NAME(FacReadWifiMacAddr)(prMacAddr); + DBGLOG(INIT, INFO, + "MAC address: " MACSTR, MAC2STR(prMacAddr)); +#else + if (prGlueInfo->fgNvramAvailable == FALSE) { + DBGLOG(INIT, INFO, "glLoadNvram fail\n"); + return FALSE; + } + kalMemCopy(prMacAddr, prGlueInfo->rRegInfo.aucMacAddr, + PARAM_MAC_ADDR_LEN * sizeof(uint8_t)); +#endif + return TRUE; +#endif + } else { + COPY_MAC_ADDR(prMacAddr, prGlueInfo->rMacAddrOverride); + + return TRUE; + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used to flush pending TX packets in glue layer + * + * \param pvGlueInfo Pointer of GLUE Data Structure + * + * \retval none + */ +/*----------------------------------------------------------------------------*/ +void kalFlushPendingTxPackets(IN struct GLUE_INFO + *prGlueInfo) +{ + struct QUE *prTxQue; + struct QUE_ENTRY *prQueueEntry; + void *prPacket; + + ASSERT(prGlueInfo); + + prTxQue = &(prGlueInfo->rTxQueue); + + if (GLUE_GET_REF_CNT(prGlueInfo->i4TxPendingFrameNum) == 0) + return; + + if (HAL_IS_TX_DIRECT()) { + nicTxDirectClearSkbQ(prGlueInfo->prAdapter); + } else { + GLUE_SPIN_LOCK_DECLARATION(); + + while (TRUE) { + GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); + QUEUE_REMOVE_HEAD(prTxQue, prQueueEntry, + struct QUE_ENTRY *); + GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); + + if (prQueueEntry == NULL) + break; + + prPacket = GLUE_GET_PKT_DESCRIPTOR(prQueueEntry); + + kalSendComplete(prGlueInfo, prPacket, + WLAN_STATUS_NOT_ACCEPTED); + } + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is get indicated media state + * + * \param pvGlueInfo Pointer of GLUE Data Structure + * + * \retval + */ +/*----------------------------------------------------------------------------*/ +enum ENUM_PARAM_MEDIA_STATE kalGetMediaStateIndicated( + IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucBssIndex) +{ + ASSERT(prGlueInfo); + + return prGlueInfo->eParamMediaStateIndicated[ucBssIndex]; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used to set indicated media state + * + * \param pvGlueInfo Pointer of GLUE Data Structure + * + * \retval none + */ +/*----------------------------------------------------------------------------*/ +void kalSetMediaStateIndicated(IN struct GLUE_INFO + *prGlueInfo, IN enum ENUM_PARAM_MEDIA_STATE + eParamMediaStateIndicate, + IN uint8_t ucBssIndex) +{ + ASSERT(prGlueInfo); + ASSERT(ucBssIndex >= 0 && ucBssIndex < KAL_AIS_NUM) + prGlueInfo->eParamMediaStateIndicated[ucBssIndex] = + eParamMediaStateIndicate; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used to clear pending OID staying in command queue + * + * \param prGlueInfo Pointer of GLUE Data Structure + * + * \retval none + */ +/*----------------------------------------------------------------------------*/ +void kalOidCmdClearance(IN struct GLUE_INFO *prGlueInfo) +{ + struct QUE *prCmdQue; + struct QUE rTempCmdQue; + struct QUE *prTempCmdQue = &rTempCmdQue; + struct QUE rReturnCmdQue; + struct QUE *prReturnCmdQue = &rReturnCmdQue; + struct QUE_ENTRY *prQueueEntry = (struct QUE_ENTRY *) NULL; + struct CMD_INFO *prCmdInfo = (struct CMD_INFO *) NULL; + + GLUE_SPIN_LOCK_DECLARATION(); + + ASSERT(prGlueInfo); + + QUEUE_INITIALIZE(prReturnCmdQue); + + prCmdQue = &prGlueInfo->rCmdQueue; + + GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); + QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); + GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); + + QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, + struct QUE_ENTRY *); + while (prQueueEntry) { + + if (((struct CMD_INFO *) prQueueEntry)->fgIsOid) { + prCmdInfo = (struct CMD_INFO *) prQueueEntry; + break; + } + QUEUE_INSERT_TAIL(prReturnCmdQue, prQueueEntry); + QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, + struct QUE_ENTRY *); + } + + GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); + QUEUE_CONCATENATE_QUEUES_HEAD(prCmdQue, prReturnCmdQue); + QUEUE_CONCATENATE_QUEUES_HEAD(prCmdQue, prTempCmdQue); + GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); + + if (prCmdInfo) { + if (prCmdInfo->pfCmdTimeoutHandler) + prCmdInfo->pfCmdTimeoutHandler(prGlueInfo->prAdapter, + prCmdInfo); + else + kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, 0, + WLAN_STATUS_NOT_ACCEPTED); + + prGlueInfo->u4OidCompleteFlag = 1; + cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo); + GLUE_DEC_REF_CNT(prGlueInfo->i4TxPendingCmdNum); + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used to insert command into prCmdQueue + * + * \param prGlueInfo Pointer of GLUE Data Structure + * prQueueEntry Pointer of queue entry to be inserted + * + * \retval none + */ +/*----------------------------------------------------------------------------*/ +void kalEnqueueCommand(IN struct GLUE_INFO *prGlueInfo, + IN struct QUE_ENTRY *prQueueEntry) +{ + struct QUE *prCmdQue; + struct CMD_INFO *prCmdInfo; +#if CFG_DBG_MGT_BUF + struct MEM_TRACK *prMemTrack = NULL; +#endif + + GLUE_SPIN_LOCK_DECLARATION(); + + ASSERT(prGlueInfo); + ASSERT(prQueueEntry); + + prCmdQue = &prGlueInfo->rCmdQueue; + + prCmdInfo = (struct CMD_INFO *) prQueueEntry; + +#if CFG_DBG_MGT_BUF + if (prCmdInfo->pucInfoBuffer && + !IS_FROM_BUF(prGlueInfo->prAdapter, + prCmdInfo->pucInfoBuffer)) { + prMemTrack = (struct MEM_TRACK *) + ((uint8_t *)prCmdInfo->pucInfoBuffer - + sizeof(struct MEM_TRACK)); + prMemTrack->u2CmdIdAndWhere = 0; + prMemTrack->u2CmdIdAndWhere |= prCmdInfo->ucCID; + } +#endif + + DBGLOG_LIMITED(INIT, TRACE, + "EN-Q CMD TYPE[%u] ID[0x%02X] SEQ[%u] to CMD Q\n", + prCmdInfo->eCmdType, prCmdInfo->ucCID, + prCmdInfo->ucCmdSeqNum); + + GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); + QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); + GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingCmdNum); + GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Handle EVENT_ID_ASSOC_INFO event packet by indicating to OS with + * proper information + * + * @param pvGlueInfo Pointer of GLUE Data Structure + * @param prAssocInfo Pointer of EVENT_ID_ASSOC_INFO Packet + * + * @return none + */ +/*----------------------------------------------------------------------------*/ +void kalHandleAssocInfo(IN struct GLUE_INFO *prGlueInfo, + IN struct EVENT_ASSOC_INFO *prAssocInfo) +{ + /* to do */ +} + +/*----------------------------------------------------------------------------*/ +/*! + * * @brief Notify OS with SendComplete event of the specific packet. + * * Linux should free packets here. + * * + * * @param pvGlueInfo Pointer of GLUE Data Structure + * * @param pvPacket Pointer of Packet Handle + * * @param status Status Code for OS upper layer + * * + * * @return none + */ +/*----------------------------------------------------------------------------*/ + +/* / Todo */ +void kalSecurityFrameSendComplete(IN struct GLUE_INFO + *prGlueInfo, IN void *pvPacket, IN uint32_t rStatus) +{ + ASSERT(pvPacket); + + /* dev_kfree_skb((struct sk_buff *) pvPacket); */ + kalSendCompleteAndAwakeQueue(prGlueInfo, pvPacket); + GLUE_DEC_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum); +} + +uint32_t kalGetTxPendingFrameCount(IN struct GLUE_INFO + *prGlueInfo) +{ + ASSERT(prGlueInfo); + + return (uint32_t) (GLUE_GET_REF_CNT( + prGlueInfo->i4TxPendingFrameNum)); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used to retrieve the number of pending commands + * (including MMPDU, 802.1X and command packets) + * + * \param prGlueInfo Pointer of GLUE Data Structure + * + * \retval + */ +/*----------------------------------------------------------------------------*/ +uint32_t kalGetTxPendingCmdCount(IN struct GLUE_INFO + *prGlueInfo) +{ + ASSERT(prGlueInfo); + + return (uint32_t)GLUE_GET_REF_CNT( + prGlueInfo->i4TxPendingCmdNum); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Timer Initialization Procedure + * + * \param[in] prGlueInfo Pointer to GLUE Data Structure + * \param[in] prTimerHandler Pointer to timer handling function, whose only + * argument is "prAdapter" + * + * \retval none + * + */ +/*----------------------------------------------------------------------------*/ + +/* static struct timer_list tickfn; */ + +void kalOsTimerInitialize(IN struct GLUE_INFO *prGlueInfo, + IN void *prTimerHandler) +{ + + ASSERT(prGlueInfo); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) + timer_setup(&(prGlueInfo->tickfn), prTimerHandler, 0); +#else + init_timer(&(prGlueInfo->tickfn)); + prGlueInfo->tickfn.function = prTimerHandler; + prGlueInfo->tickfn.data = (unsigned long)prGlueInfo; +#endif +} + +/* Todo */ +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set the time to do the time out check. + * + * \param[in] prGlueInfo Pointer to GLUE Data Structure + * \param[in] rInterval Time out interval from current time. + * + * \retval TRUE Success. + */ +/*----------------------------------------------------------------------------*/ +u_int8_t kalSetTimer(IN struct GLUE_INFO *prGlueInfo, + IN uint32_t u4Interval) +{ + ASSERT(prGlueInfo); + + if (HAL_IS_RX_DIRECT(prGlueInfo->prAdapter)) { + mod_timer(&prGlueInfo->tickfn, + jiffies + u4Interval * HZ / MSEC_PER_SEC); + } else { + del_timer_sync(&(prGlueInfo->tickfn)); + + prGlueInfo->tickfn.expires = jiffies + u4Interval * HZ / + MSEC_PER_SEC; + add_timer(&(prGlueInfo->tickfn)); + } + + return TRUE; /* success */ +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to cancel + * + * \param[in] prGlueInfo Pointer to GLUE Data Structure + * + * \retval TRUE : Timer has been canceled + * FALAE : Timer doens't exist + */ +/*----------------------------------------------------------------------------*/ +u_int8_t kalCancelTimer(IN struct GLUE_INFO *prGlueInfo) +{ + ASSERT(prGlueInfo); + + clear_bit(GLUE_FLAG_TIMEOUT_BIT, &prGlueInfo->ulFlag); + + if (del_timer_sync(&(prGlueInfo->tickfn)) >= 0) + return TRUE; + else + return FALSE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is a callback function for scanning done + * + * \param[in] prGlueInfo Pointer to GLUE Data Structure + * + * \retval none + * + */ +/*----------------------------------------------------------------------------*/ +void kalScanDone(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucBssIndex, + IN uint32_t status) +{ + uint8_t fgAborted = (status != WLAN_STATUS_SUCCESS) ? TRUE : FALSE; + ASSERT(prGlueInfo); + + if (IS_BSS_INDEX_AIS(prGlueInfo->prAdapter, ucBssIndex)) + scanLogEssResult(prGlueInfo->prAdapter); + + scanReportBss2Cfg80211(prGlueInfo->prAdapter, + BSS_TYPE_INFRASTRUCTURE, NULL); + + /* check for system configuration for generating error message on scan + * list + */ + wlanCheckSystemConfiguration(prGlueInfo->prAdapter); + + kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_SCAN_COMPLETE, + &fgAborted, sizeof(fgAborted), ucBssIndex); +} + +#if CFG_SUPPORT_SCAN_CACHE_RESULT +/*----------------------------------------------------------------------------*/ +/*! + * @brief update timestamp information of bss cache in kernel + * + * @param[in] prAdapter Pointer to the Adapter structure. + * @return status 0 if success, error code otherwise + */ +/*----------------------------------------------------------------------------*/ +uint8_t kalUpdateBssTimestamp(IN struct GLUE_INFO *prGlueInfo) +{ + struct wiphy *wiphy; + struct cfg80211_registered_device *rdev; + struct cfg80211_internal_bss *bss = NULL; + struct cfg80211_bss_ies *ies; + uint64_t new_timestamp = kalGetBootTime(); + + ASSERT(prGlueInfo); + wiphy = priv_to_wiphy(prGlueInfo); + if (!wiphy) { + log_dbg(REQ, ERROR, "wiphy is null\n"); + return 1; + } + rdev = container_of(wiphy, struct cfg80211_registered_device, wiphy); + + log_dbg(REQ, INFO, "Update scan timestamp: %llu (%llu)\n", + new_timestamp, le64_to_cpu(new_timestamp)); + + /* add 1 ms to prevent scan time too short */ + new_timestamp += 1000; + + spin_lock_bh(&rdev->bss_lock); + list_for_each_entry(bss, &rdev->bss_list, list) { + ies = *(struct cfg80211_bss_ies **) + (((size_t)&(bss->pub)) + offsetof(struct cfg80211_bss, ies)); + if (rcu_access_pointer(bss->pub.ies) == ies) { + ies->tsf = le64_to_cpu(new_timestamp); + } else { + log_limited_dbg(REQ, WARN, "Update tsf fail. bss->pub.ies=%p ies=%p\n", + bss->pub.ies, ies); + } + } + spin_unlock_bh(&rdev->bss_lock); + + return 0; +} +#endif /* CFG_SUPPORT_SCAN_CACHE_RESULT */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used to generate a random number + * + * \param none + * + * \retval UINT_32 + */ +/*----------------------------------------------------------------------------*/ +uint32_t kalRandomNumber(void) +{ + uint32_t number = 0; + + get_random_bytes(&number, 4); + + return number; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief command timeout call-back function + * + * \param[in] prGlueInfo Pointer to the GLUE data structure. + * + * \retval (none) + */ +/*----------------------------------------------------------------------------*/ +#if KERNEL_VERSION(4, 15, 0) <= LINUX_VERSION_CODE +void kalTimeoutHandler(struct timer_list *timer) +#else +void kalTimeoutHandler(unsigned long arg) +#endif +{ +#if KERNEL_VERSION(4, 15, 0) <= LINUX_VERSION_CODE + struct GLUE_INFO *prGlueInfo = + from_timer(prGlueInfo, timer, tickfn); +#else + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *)arg; +#endif + + ASSERT(prGlueInfo); + + /* Notify tx thread for timeout event */ + set_bit(GLUE_FLAG_TIMEOUT_BIT, &prGlueInfo->ulFlag); + wake_up_interruptible(&prGlueInfo->waitq); + +} + +void kalSetEvent(struct GLUE_INFO *pr) +{ + set_bit(GLUE_FLAG_TXREQ_BIT, &pr->ulFlag); + wake_up_interruptible(&pr->waitq); +} + +void kalSetSerTimeoutEvent(struct GLUE_INFO *pr) +{ + set_bit(GLUE_FLAG_SER_TIMEOUT_BIT, &pr->ulFlag); + wake_up_interruptible(&pr->waitq); +} + +void kalSetIntEvent(struct GLUE_INFO *pr) +{ + KAL_WAKE_LOCK(pr->prAdapter, pr->rIntrWakeLock); + + set_bit(GLUE_FLAG_INT_BIT, &pr->ulFlag); + + /* when we got interrupt, we wake up servie thread */ +#if CFG_SUPPORT_MULTITHREAD + wake_up_interruptible(&pr->waitq_hif); +#else + wake_up_interruptible(&pr->waitq); +#endif +} + +void kalSetDrvIntEvent(struct GLUE_INFO *pr) +{ + KAL_WAKE_LOCK(pr->prAdapter, pr->rIntrWakeLock); + + set_bit(GLUE_FLAG_DRV_INT_BIT, &pr->ulFlag); + + /* when we got interrupt, we wake up servie thread */ +#if CFG_SUPPORT_MULTITHREAD + wake_up_interruptible(&pr->waitq_hif); +#else + wake_up_interruptible(&pr->waitq); +#endif +} + +void kalSetWmmUpdateEvent(struct GLUE_INFO *pr) +{ + set_bit(GLUE_FLAG_UPDATE_WMM_QUOTA_BIT, &pr->ulFlag); +#if CFG_SUPPORT_MULTITHREAD + wake_up_interruptible(&pr->waitq_hif); +#endif +} + +void kalSetMdCrashEvent(struct GLUE_INFO *pr) +{ + set_bit(GLUE_FLAG_NOTIFY_MD_CRASH_BIT, &pr->ulFlag); +#if CFG_SUPPORT_MULTITHREAD + wake_up_interruptible(&pr->waitq_hif); +#endif +} + +void kalSetHifDbgEvent(struct GLUE_INFO *pr) +{ + set_bit(GLUE_FLAG_HIF_PRT_HIF_DBG_INFO_BIT, &(pr->ulFlag)); +#if CFG_SUPPORT_MULTITHREAD + wake_up_interruptible(&pr->waitq_hif); +#endif +} + +#if CFG_SUPPORT_MULTITHREAD +void kalSetTxEvent2Hif(struct GLUE_INFO *pr) +{ + if (!pr->hif_thread) + return; + + KAL_WAKE_LOCK_TIMEOUT(pr->prAdapter, pr->rTimeoutWakeLock, + MSEC_TO_JIFFIES( + pr->prAdapter->rWifiVar.u4WakeLockThreadWakeup)); + + set_bit(GLUE_FLAG_HIF_TX_BIT, &pr->ulFlag); + wake_up_interruptible(&pr->waitq_hif); +} + +void kalSetFwOwnEvent2Hif(struct GLUE_INFO *pr) +{ + if (!pr->hif_thread) + return; + + KAL_WAKE_LOCK_TIMEOUT(pr->prAdapter, pr->rTimeoutWakeLock, + MSEC_TO_JIFFIES( + pr->prAdapter->rWifiVar.u4WakeLockThreadWakeup)); + + set_bit(GLUE_FLAG_HIF_FW_OWN_BIT, &pr->ulFlag); + wake_up_interruptible(&pr->waitq_hif); +} + +void kalSetTxEvent2Rx(struct GLUE_INFO *pr) +{ + if (!pr->rx_thread) + return; + + KAL_WAKE_LOCK_TIMEOUT(pr->prAdapter, pr->rTimeoutWakeLock, + MSEC_TO_JIFFIES( + pr->prAdapter->rWifiVar.u4WakeLockThreadWakeup)); + + set_bit(GLUE_FLAG_RX_TO_OS_BIT, &pr->ulFlag); + wake_up_interruptible(&pr->waitq_rx); +} + +void kalSetTxCmdEvent2Hif(struct GLUE_INFO *pr) +{ + if (!pr->hif_thread) + return; + + KAL_WAKE_LOCK_TIMEOUT(pr->prAdapter, pr->rTimeoutWakeLock, + MSEC_TO_JIFFIES( + pr->prAdapter->rWifiVar.u4WakeLockThreadWakeup)); + + set_bit(GLUE_FLAG_HIF_TX_CMD_BIT, &pr->ulFlag); + wake_up_interruptible(&pr->waitq_hif); +} + +void kalSetTxCmdDoneEvent(struct GLUE_INFO *pr) +{ + /* do we need wake lock here */ + set_bit(GLUE_FLAG_TX_CMD_DONE_BIT, &pr->ulFlag); + wake_up_interruptible(&pr->waitq); +} + +void kalSetRxProcessEvent(struct GLUE_INFO *pr) +{ + /* do we need wake lock here ? */ + set_bit(GLUE_FLAG_RX_BIT, &pr->ulFlag); + wake_up_interruptible(&pr->waitq); +} +#endif +/*----------------------------------------------------------------------------*/ +/*! + * \brief to check if configuration file (NVRAM/Registry) exists + * + * \param[in] + * prGlueInfo + * + * \return + * TRUE + * FALSE + */ +/*----------------------------------------------------------------------------*/ +u_int8_t kalIsConfigurationExist(IN struct GLUE_INFO + *prGlueInfo) +{ +#if !defined(CONFIG_X86) + ASSERT(prGlueInfo); + + return prGlueInfo->fgNvramAvailable; +#else + /* there is no configuration data for x86-linux */ + /*return FALSE;*/ + + + /*Modify for Linux PC support NVRAM Setting*/ + return prGlueInfo->fgNvramAvailable; +#endif +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief to retrieve Registry information + * + * \param[in] + * prGlueInfo + * + * \return + * Pointer of REG_INFO_T + */ +/*----------------------------------------------------------------------------*/ +struct REG_INFO *kalGetConfiguration(IN struct GLUE_INFO + *prGlueInfo) +{ + ASSERT(prGlueInfo); + + return &(prGlueInfo->rRegInfo); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief update RSSI and LinkQuality to GLUE layer + * + * \param[in] + * prGlueInfo + * eNetTypeIdx + * cRssi + * cLinkQuality + * + * \return + * None + */ +/*----------------------------------------------------------------------------*/ +void +kalUpdateRSSI(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucBssIndex, + IN int8_t cRssi, IN int8_t cLinkQuality) +{ + struct iw_statistics *pStats = (struct iw_statistics *)NULL; + struct ADAPTER *prAdapter = NULL; + struct BSS_INFO *prBssInfo = (struct BSS_INFO *) NULL; + + ASSERT(prGlueInfo); + prAdapter = prGlueInfo->prAdapter; + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + + if (IS_BSS_AIS(prBssInfo)) + pStats = (struct iw_statistics *) + (&(prGlueInfo->rIwStats[ucBssIndex])); +#if CFG_ENABLE_WIFI_DIRECT +#if CFG_SUPPORT_P2P_RSSI_QUERY + else if (IS_BSS_P2P(prBssInfo)) + pStats = (struct iw_statistics *) + (&(prGlueInfo->rP2pIwStats)); +#endif +#endif + if (pStats) { + pStats->qual.qual = cLinkQuality; + pStats->qual.noise = 0; + pStats->qual.updated = IW_QUAL_QUAL_UPDATED | + IW_QUAL_NOISE_UPDATED; + pStats->qual.level = 0x100 + cRssi; + pStats->qual.updated |= IW_QUAL_LEVEL_UPDATED; + } + +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Pre-allocate I/O buffer + * + * \param[in] + * none + * + * \return + * TRUE + * FALSE + */ +/*----------------------------------------------------------------------------*/ +u_int8_t kalInitIOBuffer(u_int8_t is_pre_alloc) +{ + uint32_t u4Size; + + /* not pre-allocation for all memory usage */ + if (!is_pre_alloc) { + pvIoBuffer = NULL; + return FALSE; + } + + /* pre-allocation for all memory usage */ + if (HIF_TX_COALESCING_BUFFER_SIZE > + HIF_RX_COALESCING_BUFFER_SIZE) + u4Size = HIF_TX_COALESCING_BUFFER_SIZE; + else + u4Size = HIF_RX_COALESCING_BUFFER_SIZE; + + u4Size += HIF_EXTRA_IO_BUFFER_SIZE; + + pvIoBuffer = kmalloc(u4Size, GFP_KERNEL); + if (pvIoBuffer) { + pvIoBufferSize = u4Size; + pvIoBufferUsage = 0; + + return TRUE; + } + + return FALSE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Free pre-allocated I/O buffer + * + * \param[in] + * none + * + * \return + * none + */ +/*----------------------------------------------------------------------------*/ +void kalUninitIOBuffer(void) +{ + kfree(pvIoBuffer); + + pvIoBuffer = (void *) NULL; + pvIoBufferSize = 0; + pvIoBufferUsage = 0; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Dispatch pre-allocated I/O buffer + * + * \param[in] + * u4AllocSize + * + * \return + * PVOID for pointer of pre-allocated I/O buffer + */ +/*----------------------------------------------------------------------------*/ +void *kalAllocateIOBuffer(IN uint32_t u4AllocSize) +{ + void *ret = (void *) NULL; + + if (pvIoBuffer) { + if (u4AllocSize <= (pvIoBufferSize - pvIoBufferUsage)) { + ret = (void *) + &(((uint8_t *) (pvIoBuffer))[pvIoBufferUsage]); + pvIoBufferUsage += u4AllocSize; + } + } else { + /* fault tolerance */ + ret = (void *) kalMemAlloc(u4AllocSize, PHY_MEM_TYPE); + } + + return ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Release all dispatched I/O buffer + * + * \param[in] + * none + * + * \return + * none + */ +/*----------------------------------------------------------------------------*/ +void kalReleaseIOBuffer(IN void *pvAddr, IN uint32_t u4Size) +{ + if (pvIoBuffer) { + pvIoBufferUsage -= u4Size; + } else { + /* fault tolerance */ + kalMemFree(pvAddr, PHY_MEM_TYPE, u4Size); + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] prAdapter Pointer of ADAPTER_T + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +void +kalGetChannelList(IN struct GLUE_INFO *prGlueInfo, + IN enum ENUM_BAND eSpecificBand, + IN uint8_t ucMaxChannelNum, IN uint8_t *pucNumOfChannel, + IN struct RF_CHANNEL_INFO *paucChannelList) +{ + rlmDomainGetChnlList(prGlueInfo->prAdapter, eSpecificBand, + FALSE, + ucMaxChannelNum, pucNumOfChannel, paucChannelList); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] prAdapter Pointer of ADAPTER_T + * + * \return none + */ +/*----------------------------------------------------------------------------*/ +u_int8_t kalIsAPmode(IN struct GLUE_INFO *prGlueInfo) +{ +#if 0 /* Marked for MT6630 (New ucBssIndex) */ +#if CFG_ENABLE_WIFI_DIRECT + if (IS_NET_ACTIVE(prGlueInfo->prAdapter, + NETWORK_TYPE_P2P_INDEX) && + p2pFuncIsAPMode( + prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo)) + return TRUE; +#endif +#endif + + return FALSE; +} + +#if CFG_SUPPORT_802_11W +/*----------------------------------------------------------------------------*/ +/*! + * \brief to check if the MFP is DISABLD/OPTIONAL/REQUIRED + * + * \param[in] + * prGlueInfo + * + * \return + * RSN_AUTH_MFP_DISABLED + * RSN_AUTH_MFP_OPTIONAL + * RSN_AUTH_MFP_DISABLED + */ +/*----------------------------------------------------------------------------*/ +uint32_t kalGetMfpSetting(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucBssIndex) +{ + uint32_t u4RsnMfp = RSN_AUTH_MFP_DISABLED; + struct GL_WPA_INFO *prWpaInfo; + + prWpaInfo = aisGetWpaInfo(prGlueInfo->prAdapter, + ucBssIndex); + + ASSERT(prGlueInfo); + + switch (prWpaInfo->u4Mfp) { + case IW_AUTH_MFP_DISABLED: + u4RsnMfp = RSN_AUTH_MFP_DISABLED; + break; + case IW_AUTH_MFP_OPTIONAL: + u4RsnMfp = RSN_AUTH_MFP_OPTIONAL; + break; + case IW_AUTH_MFP_REQUIRED: + u4RsnMfp = RSN_AUTH_MFP_REQUIRED; + break; + default: + u4RsnMfp = RSN_AUTH_MFP_DISABLED; + break; + } + + return u4RsnMfp; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief to check if the RSN IE CAP setting from supplicant + * + * \param[in] + * prGlueInfo + * + * \return + * TRUE + * FALSE + */ +/*----------------------------------------------------------------------------*/ +uint8_t kalGetRsnIeMfpCap(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucBssIndex) +{ + struct GL_WPA_INFO *prWpaInfo; + + ASSERT(prGlueInfo); + + prWpaInfo = aisGetWpaInfo(prGlueInfo->prAdapter, + ucBssIndex); + + return prWpaInfo->ucRSNMfpCap; +} +#endif + +struct file *kalFileOpen(const char *filePath, int openModes, + int createModes) +{ + struct file *prFile = NULL; + mm_segment_t oldFs; + long errval = 0; + + oldFs = get_fs(); + set_fs(get_ds()); + prFile = filp_open(filePath, openModes, createModes); + set_fs(oldFs); + if (IS_ERR(prFile)) { + errval = PTR_ERR(prFile); + DBGLOG(INIT, TRACE, "kalFileOpen() fail: %ld\n", errval); + return NULL; + } + return prFile; +} + +void kalFileClose(struct file *prFile) +{ + filp_close(prFile, NULL); +} + +uint32_t kalFileRead(struct file *prFile, + unsigned long long pos, unsigned char *buffer, + unsigned int len) +{ + mm_segment_t oldFs; + int retval; + + oldFs = get_fs(); + set_fs(get_ds()); + +#if KERNEL_VERSION(4, 13, 0) <= CFG80211_VERSION_CODE + retval = kernel_read(prFile, buffer, len, &pos); +#else + retval = vfs_read(prFile, buffer, len, &pos); +#endif + + set_fs(oldFs); + return retval; +} + +uint32_t kalFileWrite(struct file *prFile, + unsigned long long pos, unsigned char *buffer, + unsigned int len) +{ + mm_segment_t oldFs; + int retval; + + oldFs = get_fs(); + set_fs(get_ds()); + +#if KERNEL_VERSION(4, 13, 0) <= CFG80211_VERSION_CODE + retval = kernel_write(prFile, buffer, len, &pos); +#else + retval = vfs_write(prFile, buffer, len, &pos); +#endif + + set_fs(oldFs); + return retval; +} + +uint32_t kalWriteToFile(const uint8_t *pucPath, + u_int8_t fgDoAppend, uint8_t *pucData, uint32_t u4Size) +{ + struct file *file = NULL; + int32_t ret = -1; + uint32_t u4Flags = 0; + + if (fgDoAppend) + u4Flags = O_APPEND; + + file = kalFileOpen(pucPath, O_WRONLY | O_CREAT | u4Flags, 0700); + if (file != NULL) { + kalFileWrite(file, 0, pucData, u4Size); + kalFileClose(file); + ret = 0; + } + return ret; +} + +int32_t kalReadToFile(const uint8_t *pucPath, + uint8_t *pucData, uint32_t u4Size, uint32_t *pu4ReadSize) +{ + struct file *file = NULL; + int32_t ret = -1; + uint32_t u4ReadSize = 0; + + DBGLOG(INIT, TRACE, "kalReadToFile() path %s\n", pucPath); + + file = kalFileOpen(pucPath, O_RDONLY, 0); + + if ((file != NULL) && !IS_ERR(file)) { + u4ReadSize = kalFileRead(file, 0, pucData, u4Size); + kalFileClose(file); + if (pu4ReadSize) + *pu4ReadSize = u4ReadSize; + ret = 0; + } + return ret; +} + +uint32_t kalCheckPath(const uint8_t *pucPath) +{ + struct file *file = NULL; + uint32_t u4Flags = 0; + + file = kalFileOpen(pucPath, O_WRONLY | O_CREAT | u4Flags, 0700); + if (!file) + return -1; + + kalFileClose(file); + return 1; +} + +uint32_t kalTrunkPath(const uint8_t *pucPath) +{ + struct file *file = NULL; + uint32_t u4Flags = O_TRUNC; + + file = kalFileOpen(pucPath, O_WRONLY | O_CREAT | u4Flags, 0700); + if (!file) + return -1; + + kalFileClose(file); + return 1; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief read request firmware file binary to pucData + * + * \param[in] pucPath file name + * \param[out] pucData Request file output buffer + * \param[in] u4Size read size + * \param[out] pu4ReadSize real read size + * \param[in] dev + * + * \return + * 0 success + * >0 fail + */ +/*----------------------------------------------------------------------------*/ +int32_t kalRequestFirmware(const uint8_t *pucPath, + uint8_t *pucData, uint32_t u4Size, + uint32_t *pu4ReadSize, struct device *dev) +{ + const struct firmware *fw; + int ret = 0; + + /* + * Driver support request_firmware() to get files + * Android path: "/etc/firmware", "/vendor/firmware", "/firmware/image" + * Linux path: "/lib/firmware", "/lib/firmware/update" + */ + ret = _kalRequestFirmware(&fw, pucPath, dev); + + if (ret != 0) { + DBGLOG(INIT, TRACE, "kalRequestFirmware %s Fail, errno[%d]!!\n", + pucPath, ret); + pucData = NULL; + *pu4ReadSize = 0; + return ret; + } + + DBGLOG(INIT, INFO, "kalRequestFirmware(): %s OK\n", + pucPath); + + if (fw->size < u4Size) + u4Size = fw->size; + + memcpy(pucData, fw->data, u4Size); + if (pu4ReadSize) + *pu4ReadSize = u4Size; + + release_firmware(fw); + + return ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief To indicate BSS-INFO to NL80211 as scanning result + * + * \param[in] + * prGlueInfo + * pucBeaconProbeResp + * u4FrameLen + * + * + * + * \return + * none + */ +/*----------------------------------------------------------------------------*/ +void +kalIndicateBssInfo(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t *pucBeaconProbeResp, + IN uint32_t u4FrameLen, IN uint8_t ucChannelNum, + IN int32_t i4SignalStrength) +{ + struct wiphy *wiphy; + struct ieee80211_channel *prChannel = NULL; + + ASSERT(prGlueInfo); + wiphy = priv_to_wiphy(prGlueInfo); + + /* search through channel entries */ + if (ucChannelNum <= 14) { + prChannel = ieee80211_get_channel(wiphy, + ieee80211_channel_to_frequency(ucChannelNum, + KAL_BAND_2GHZ)); + } else { + prChannel = ieee80211_get_channel(wiphy, + ieee80211_channel_to_frequency(ucChannelNum, + KAL_BAND_5GHZ)); + } + + if (prChannel != NULL + && prGlueInfo->fgIsRegistered == TRUE) { + struct cfg80211_bss *bss; + struct ieee80211_mgmt *prMgmtFrame = (struct ieee80211_mgmt + *)pucBeaconProbeResp; + char *pucBssSubType = + ieee80211_is_beacon(prMgmtFrame->frame_control) ? + "beacon" : "probe_resp"; + +#if CFG_SUPPORT_TSF_USING_BOOTTIME + prMgmtFrame->u.beacon.timestamp = kalGetBootTime(); +#endif + + kalScanResultLog(prGlueInfo->prAdapter, + (struct ieee80211_mgmt *)pucBeaconProbeResp); + + log_dbg(SCN, TRACE, "cfg80211_inform_bss_frame %s bss=" MACSTR + " sn=%u ch=%u rssi=%d len=%u tsf=%llu\n", pucBssSubType, + MAC2STR(prMgmtFrame->bssid), prMgmtFrame->seq_ctrl, + ucChannelNum, i4SignalStrength, u4FrameLen, + prMgmtFrame->u.beacon.timestamp); + + /* indicate to NL80211 subsystem */ + bss = cfg80211_inform_bss_frame(wiphy, prChannel, + (struct ieee80211_mgmt *)pucBeaconProbeResp, + u4FrameLen, i4SignalStrength * 100, GFP_KERNEL); + + if (!bss) { + /* ToDo:: DBGLOG */ + DBGLOG(REQ, WARN, + "cfg80211_inform_bss_frame() returned with NULL\n"); + } else + cfg80211_put_bss(wiphy, bss); + } + +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief To indicate channel ready + * + * \param[in] + * prGlueInfo + * + * \return + * none + */ +/*----------------------------------------------------------------------------*/ +void +kalReadyOnChannel(IN struct GLUE_INFO *prGlueInfo, + IN uint64_t u8Cookie, + IN enum ENUM_BAND eBand, IN enum ENUM_CHNL_EXT eSco, + IN uint8_t ucChannelNum, IN uint32_t u4DurationMs, + IN uint8_t ucBssIndex) +{ + struct ieee80211_channel *prChannel = NULL; + enum nl80211_channel_type rChannelType; + + /* ucChannelNum = wlanGetChannelNumberByNetwork(prGlueInfo->prAdapter, + * NETWORK_TYPE_AIS_INDEX); + */ + + if (prGlueInfo->fgIsRegistered == TRUE) { + struct net_device *prDevHandler = + wlanGetNetDev(prGlueInfo, ucBssIndex); + + if (ucChannelNum <= 14) { + prChannel = + ieee80211_get_channel(priv_to_wiphy(prGlueInfo), + ieee80211_channel_to_frequency(ucChannelNum, + KAL_BAND_2GHZ)); + } else { + prChannel = + ieee80211_get_channel(priv_to_wiphy(prGlueInfo), + ieee80211_channel_to_frequency(ucChannelNum, + KAL_BAND_5GHZ)); + } + + switch (eSco) { + case CHNL_EXT_SCN: + rChannelType = NL80211_CHAN_NO_HT; + break; + + case CHNL_EXT_SCA: + rChannelType = NL80211_CHAN_HT40MINUS; + break; + + case CHNL_EXT_SCB: + rChannelType = NL80211_CHAN_HT40PLUS; + break; + + case CHNL_EXT_RES: + default: + rChannelType = NL80211_CHAN_HT20; + break; + } + + if (!prChannel) { + DBGLOG(AIS, ERROR, "prChannel is NULL, return!"); + return; + } + + cfg80211_ready_on_channel( + prDevHandler->ieee80211_ptr, + u8Cookie, prChannel, u4DurationMs, GFP_KERNEL); + } + +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief To indicate channel expiration + * + * \param[in] + * prGlueInfo + * + * \return + * none + */ +/*----------------------------------------------------------------------------*/ +void +kalRemainOnChannelExpired(IN struct GLUE_INFO *prGlueInfo, + IN uint64_t u8Cookie, IN enum ENUM_BAND eBand, + IN enum ENUM_CHNL_EXT eSco, IN uint8_t ucChannelNum, + IN uint8_t ucBssIndex) +{ + struct ieee80211_channel *prChannel = NULL; + enum nl80211_channel_type rChannelType; + + ucChannelNum = + wlanGetChannelNumberByNetwork(prGlueInfo->prAdapter, + ucBssIndex); + + if (prGlueInfo->fgIsRegistered == TRUE) { + struct net_device *prDevHandler = + wlanGetNetDev(prGlueInfo, ucBssIndex); + + if (ucChannelNum <= 14) { + prChannel = + ieee80211_get_channel(priv_to_wiphy(prGlueInfo), + ieee80211_channel_to_frequency(ucChannelNum, + KAL_BAND_2GHZ)); + } else { + prChannel = + ieee80211_get_channel(priv_to_wiphy(prGlueInfo), + ieee80211_channel_to_frequency(ucChannelNum, + KAL_BAND_5GHZ)); + } + + switch (eSco) { + case CHNL_EXT_SCN: + rChannelType = NL80211_CHAN_NO_HT; + break; + + case CHNL_EXT_SCA: + rChannelType = NL80211_CHAN_HT40MINUS; + break; + + case CHNL_EXT_SCB: + rChannelType = NL80211_CHAN_HT40PLUS; + break; + + case CHNL_EXT_RES: + default: + rChannelType = NL80211_CHAN_HT20; + break; + } + + if (!prChannel) { + DBGLOG(AIS, ERROR, "prChannel is NULL, return!"); + return; + } + + cfg80211_remain_on_channel_expired( + prDevHandler->ieee80211_ptr, + u8Cookie, prChannel, GFP_KERNEL); + } + +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief To indicate Mgmt tx status + * + * \param[in] + * prGlueInfo + * + * \return + * none + */ +/*----------------------------------------------------------------------------*/ +void +kalIndicateMgmtTxStatus(IN struct GLUE_INFO *prGlueInfo, + IN uint64_t u8Cookie, IN u_int8_t fgIsAck, + IN uint8_t *pucFrameBuf, IN uint32_t u4FrameLen, + IN uint8_t ucBssIndex) +{ + + do { + struct net_device *prDevHandler; + + if ((prGlueInfo == NULL) + || (pucFrameBuf == NULL) + || (u4FrameLen == 0)) { + DBGLOG(AIS, TRACE, + "Unexpected pointer PARAM. 0x%lx, 0x%lx, %d.", + prGlueInfo, pucFrameBuf, u4FrameLen); + ASSERT(FALSE); + break; + } + + prDevHandler = + wlanGetNetDev(prGlueInfo, ucBssIndex); + + cfg80211_mgmt_tx_status( + prDevHandler->ieee80211_ptr, + u8Cookie, pucFrameBuf, u4FrameLen, fgIsAck, GFP_KERNEL); + + } while (FALSE); + +} /* kalIndicateMgmtTxStatus */ + +void kalIndicateRxMgmtFrame(IN struct GLUE_INFO *prGlueInfo, + IN struct SW_RFB *prSwRfb, + IN uint8_t ucBssIndex) +{ + int32_t i4Freq = 0; + uint8_t ucChnlNum = 0; + + do { + struct net_device *prDevHandler; + + if ((prGlueInfo == NULL) || (prSwRfb == NULL)) { + ASSERT(FALSE); + break; + } + + ucChnlNum = prSwRfb->ucChnlNum; + + i4Freq = nicChannelNum2Freq(ucChnlNum) / 1000; + + if (!prGlueInfo->fgIsRegistered) { + DBGLOG(AIS, WARN, + "Net dev is not ready!\n"); + break; + } + + if (prGlueInfo->u4OsMgmtFrameFilter == 0) { + DBGLOG(AIS, WARN, + "The cfg80211 hasn't do mgmt register!\n"); + break; + } + + prDevHandler = + wlanGetNetDev(prGlueInfo, ucBssIndex); + +#if (KERNEL_VERSION(3, 18, 0) <= CFG80211_VERSION_CODE) + cfg80211_rx_mgmt(prDevHandler->ieee80211_ptr, + i4Freq, /* in MHz */ + RCPI_TO_dBm((uint8_t) nicRxGetRcpiValueFromRxv( + prGlueInfo->prAdapter, + RCPI_MODE_MAX, prSwRfb)), + prSwRfb->pvHeader, prSwRfb->u2PacketLen, + NL80211_RXMGMT_FLAG_ANSWERED); + +#elif (KERNEL_VERSION(3, 12, 0) <= CFG80211_VERSION_CODE) + cfg80211_rx_mgmt(prDevHandler->ieee80211_ptr, + i4Freq, /* in MHz */ + RCPI_TO_dBm((uint8_t) + nicRxGetRcpiValueFromRxv( + prGlueInfo->prAdapter, RCPI_MODE_WF0, prSwRfb)), + prSwRfb->pvHeader, prSwRfb->u2PacketLen, + NL80211_RXMGMT_FLAG_ANSWERED, + GFP_ATOMIC); +#else + cfg80211_rx_mgmt(prDevHandler->ieee80211_ptr, + i4Freq, /* in MHz */ + RCPI_TO_dBm((uint8_t) + nicRxGetRcpiValueFromRxv( + prGlueInfo->prAdapter, RCPI_MODE_WF0, prSwRfb)), + prSwRfb->pvHeader, prSwRfb->u2PacketLen, + GFP_ATOMIC); +#endif + + } while (FALSE); + +} /* kalIndicateRxMgmtFrame */ + +#if CFG_SUPPORT_SDIO_READ_WRITE_PATTERN +/*----------------------------------------------------------------------------*/ +/*! + * \brief To configure SDIO test pattern mode + * + * \param[in] + * prGlueInfo + * fgEn + * fgRead + * + * \return + * TRUE + * FALSE + */ +/*----------------------------------------------------------------------------*/ +u_int8_t kalSetSdioTestPattern(IN struct GLUE_INFO + *prGlueInfo, IN u_int8_t fgEn, IN u_int8_t fgRead) +{ + const uint8_t aucPattern[] = { + 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, + 0xaa, 0x55, 0x80, 0x80, 0x80, 0x7f, 0x80, 0x80, + 0x80, 0x7f, 0x7f, 0x7f, 0x80, 0x7f, 0x7f, 0x7f, + 0x40, 0x40, 0x40, 0xbf, 0x40, 0x40, 0x40, 0xbf, + 0xbf, 0xbf, 0x40, 0xbf, 0xbf, 0xbf, 0x20, 0x20, + 0x20, 0xdf, 0x20, 0x20, 0x20, 0xdf, 0xdf, 0xdf, + 0x20, 0xdf, 0xdf, 0xdf, 0x10, 0x10, 0x10, 0xef, + 0x10, 0x10, 0x10, 0xef, 0xef, 0xef, 0x10, 0xef, + 0xef, 0xef, 0x08, 0x08, 0x08, 0xf7, 0x08, 0x08, + 0x08, 0xf7, 0xf7, 0xf7, 0x08, 0xf7, 0xf7, 0xf7, + 0x04, 0x04, 0x04, 0xfb, 0x04, 0x04, 0x04, 0xfb, + 0xfb, 0xfb, 0x04, 0xfb, 0xfb, 0xfb, 0x02, 0x02, + 0x02, 0xfd, 0x02, 0x02, 0x02, 0xfd, 0xfd, 0xfd, + 0x02, 0xfd, 0xfd, 0xfd, 0x01, 0x01, 0x01, 0xfe, + 0x01, 0x01, 0x01, 0xfe, 0xfe, 0xfe, 0x01, 0xfe, + 0xfe, 0xfe, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, + 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff + }; + uint32_t i; + + ASSERT(prGlueInfo); + + /* access to MCR_WTMCR to engage PRBS mode */ + prGlueInfo->fgEnSdioTestPattern = fgEn; + prGlueInfo->fgSdioReadWriteMode = fgRead; + + if (fgRead == FALSE) { + /* fill buffer for data to be written */ + for (i = 0; i < sizeof(aucPattern); i++) + prGlueInfo->aucSdioTestBuffer[i] = aucPattern[i]; + } + + return TRUE; +} +#endif + +#if (CFG_MET_PACKET_TRACE_SUPPORT == 1) +#define PROC_MET_PROF_CTRL "met_ctrl" +#define PROC_MET_PROF_PORT "met_port" + +struct proc_dir_entry *pMetProcDir; +void *pMetGlobalData; + +#endif +/*----------------------------------------------------------------------------*/ +/*! + * \brief To indicate scheduled scan results are avilable + * + * \param[in] + * prGlueInfo + * + * \return + * None + */ +/*----------------------------------------------------------------------------*/ +void kalSchedScanResults(IN struct GLUE_INFO *prGlueInfo) +{ + ASSERT(prGlueInfo); + scanReportBss2Cfg80211(prGlueInfo->prAdapter, + BSS_TYPE_INFRASTRUCTURE, NULL); + + scanlog_dbg(LOG_SCHED_SCAN_DONE_D2K, INFO, "Call cfg80211_sched_scan_results\n"); +#if KERNEL_VERSION(4, 12, 0) <= CFG80211_VERSION_CODE + cfg80211_sched_scan_results(priv_to_wiphy(prGlueInfo), 0); +#else + cfg80211_sched_scan_results(priv_to_wiphy(prGlueInfo)); +#endif +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief To indicate scheduled scan has been stopped + * + * \param[in] + * prGlueInfo + * + * \return + * None + */ +/*----------------------------------------------------------------------------*/ +void kalSchedScanStopped(IN struct GLUE_INFO *prGlueInfo, + u_int8_t fgDriverTriggerd) +{ + /* DBGLOG(SCN, INFO, ("-->kalSchedScanStopped\n" )); */ + + GLUE_SPIN_LOCK_DECLARATION(); + + ASSERT(prGlueInfo); + +#if 1 + /* 1. reset first for newly incoming request */ + GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); + if (prGlueInfo->prSchedScanRequest != NULL) + prGlueInfo->prSchedScanRequest = NULL; + GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); +#endif + DBGLOG(SCN, INFO, "Driver triggerd %d\n", fgDriverTriggerd); + + /* 2. indication to cfg80211 */ + /* 20150205 change cfg80211_sched_scan_stopped to work queue to use K + * thread to send event instead of Tx thread + * due to sched_scan_mtx dead lock issue by Tx thread serves oid cmds + * and send event in the same time + */ + if (fgDriverTriggerd) { + DBGLOG(SCN, INFO, "start work queue to send event\n"); + schedule_delayed_work(&sched_workq, 0); + DBGLOG(SCN, INFO, "main_thread return from %s\n", __func__); + } +} + +#if CFG_SUPPORT_WAKEUP_REASON_DEBUG +/*----------------------------------------------------------------------------*/ +/*! + * \brief To check if device if wake up by wlan + * + * \param[in] + * prAdapter + * + * \return + * TRUE: wake up by wlan; otherwise, FALSE + */ +/*----------------------------------------------------------------------------*/ +u_int8_t kalIsWakeupByWlan(struct ADAPTER *prAdapter) +{ + /* + * SUSPEND_FLAG_FOR_WAKEUP_REASON is set means system has suspended, + * but may be failed duo to some driver suspend failed. so we need + * help of function slp_get_wake_reason + */ + if (test_and_clear_bit(SUSPEND_FLAG_FOR_WAKEUP_REASON, + &prAdapter->ulSuspendFlag) == 0) + return FALSE; + + return TRUE; +} +#endif + + + +u_int8_t +kalGetIPv4Address(IN struct net_device *prDev, + IN uint32_t u4MaxNumOfAddr, OUT uint8_t *pucIpv4Addrs, + OUT uint32_t *pu4NumOfIpv4Addr) +{ + uint32_t u4NumIPv4 = 0; + uint32_t u4AddrLen = IPV4_ADDR_LEN; + struct in_ifaddr *prIfa; + + /* 4 <1> Sanity check of netDevice */ + if (!prDev || !(prDev->ip_ptr) + || !((struct in_device *)(prDev->ip_ptr))->ifa_list) { + DBGLOG(INIT, INFO, + "IPv4 address is not available for dev(0x%p)\n", prDev); + + *pu4NumOfIpv4Addr = 0; + return FALSE; + } + + prIfa = ((struct in_device *)(prDev->ip_ptr))->ifa_list; + + /* 4 <2> copy the IPv4 address */ + while ((u4NumIPv4 < u4MaxNumOfAddr) && prIfa) { + kalMemCopy(&pucIpv4Addrs[u4NumIPv4 * u4AddrLen], + &prIfa->ifa_local, u4AddrLen); + kalMemCopy(&pucIpv4Addrs[(u4NumIPv4+1) * u4AddrLen], + &prIfa->ifa_mask, u4AddrLen); + prIfa = prIfa->ifa_next; + + DBGLOG(INIT, INFO, + "IPv4 addr [%u][" IPV4STR "] mask [" IPV4STR "]\n", + u4NumIPv4, + IPV4TOSTR(&pucIpv4Addrs[u4NumIPv4*u4AddrLen]), + IPV4TOSTR(&pucIpv4Addrs[(u4NumIPv4+1)*u4AddrLen])); + + u4NumIPv4++; + } + + *pu4NumOfIpv4Addr = u4NumIPv4; + + return TRUE; +} + +#if IS_ENABLED(CONFIG_IPV6) +u_int8_t +kalGetIPv6Address(IN struct net_device *prDev, + IN uint32_t u4MaxNumOfAddr, OUT uint8_t *pucIpv6Addrs, + OUT uint32_t *pu4NumOfIpv6Addr) +{ + uint32_t u4NumIPv6 = 0; + uint32_t u4AddrLen = IPV6_ADDR_LEN; + struct inet6_ifaddr *prIfa; + + /* 4 <1> Sanity check of netDevice */ + if (!prDev || !(prDev->ip6_ptr)) { + DBGLOG(INIT, INFO, + "IPv6 address is not available for dev(0x%p)\n", prDev); + + *pu4NumOfIpv6Addr = 0; + return FALSE; + } + + + /* 4 <2> copy the IPv6 address */ + LIST_FOR_EACH_IPV6_ADDR(prIfa, prDev->ip6_ptr) { + kalMemCopy(&pucIpv6Addrs[u4NumIPv6 * u4AddrLen], + &prIfa->addr, u4AddrLen); + + DBGLOG(INIT, INFO, + "IPv6 addr [%u][" IPV6STR "]\n", u4NumIPv6, + IPV6TOSTR(&pucIpv6Addrs[u4NumIPv6 * u4AddrLen])); + + if ((u4NumIPv6 + 1) >= u4MaxNumOfAddr) + break; + u4NumIPv6++; + } + + *pu4NumOfIpv6Addr = u4NumIPv6; + + return TRUE; +} +#endif /* IS_ENABLED(CONFIG_IPV6) */ + +void +kalSetNetAddress(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucBssIdx, + IN uint8_t *pucIPv4Addr, IN uint32_t u4NumIPv4Addr, + IN uint8_t *pucIPv6Addr, IN uint32_t u4NumIPv6Addr) +{ + uint32_t rStatus = WLAN_STATUS_FAILURE; + uint32_t u4SetInfoLen = 0; + uint32_t u4Len = OFFSET_OF(struct + PARAM_NETWORK_ADDRESS_LIST, arAddress); + struct PARAM_NETWORK_ADDRESS_LIST *prParamNetAddrList; + struct PARAM_NETWORK_ADDRESS *prParamNetAddr; + uint32_t i, u4AddrLen; + + /* 4 <1> Calculate buffer size */ + /* IPv4 */ + u4Len += (((sizeof(struct PARAM_NETWORK_ADDRESS) - 1) + + IPV4_ADDR_LEN) * u4NumIPv4Addr * 2); + /* IPv6 */ + u4Len += (((sizeof(struct PARAM_NETWORK_ADDRESS) - 1) + + IPV6_ADDR_LEN) * u4NumIPv6Addr); + + /* 4 <2> Allocate buffer */ + prParamNetAddrList = (struct PARAM_NETWORK_ADDRESS_LIST *) + kalMemAlloc(u4Len, VIR_MEM_TYPE); + + if (!prParamNetAddrList) { + DBGLOG(INIT, WARN, + "Fail to alloc buffer for setting BSS[%u] network address!\n", + ucBssIdx); + return; + } + /* 4 <3> Fill up network address */ + prParamNetAddrList->u2AddressType = + PARAM_PROTOCOL_ID_TCP_IP; + prParamNetAddrList->u4AddressCount = 0; + prParamNetAddrList->ucBssIdx = ucBssIdx; + + /* 4 <3.1> Fill up IPv4 address */ + u4AddrLen = IPV4_ADDR_LEN; + prParamNetAddr = prParamNetAddrList->arAddress; + for (i = 0; i < u4NumIPv4Addr; i++) { + prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; + prParamNetAddr->u2AddressLength = u4AddrLen; + kalMemCopy(prParamNetAddr->aucAddress, + &pucIPv4Addr[i*u4AddrLen*2], u4AddrLen*2); + + prParamNetAddr = (struct PARAM_NETWORK_ADDRESS *) + ((unsigned long) prParamNetAddr + + (unsigned long) (u4AddrLen*2 + + OFFSET_OF(struct PARAM_NETWORK_ADDRESS, aucAddress))); + } + prParamNetAddrList->u4AddressCount += u4NumIPv4Addr; + + /* 4 <3.2> Fill up IPv6 address */ + u4AddrLen = IPV6_ADDR_LEN; + for (i = 0; i < u4NumIPv6Addr; i++) { + prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; + prParamNetAddr->u2AddressLength = u4AddrLen; + kalMemCopy(prParamNetAddr->aucAddress, + &pucIPv6Addr[i * u4AddrLen], u4AddrLen); + + prParamNetAddr = (struct PARAM_NETWORK_ADDRESS *) (( + unsigned long) prParamNetAddr + (unsigned long) ( + u4AddrLen + OFFSET_OF( + struct PARAM_NETWORK_ADDRESS, aucAddress))); + } + prParamNetAddrList->u4AddressCount += u4NumIPv6Addr; + + /* 4 <4> IOCTL to main_thread */ + rStatus = kalIoctl(prGlueInfo, + wlanoidSetNetworkAddress, + (void *) prParamNetAddrList, u4Len, + FALSE, FALSE, TRUE, &u4SetInfoLen); + + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(REQ, WARN, "%s: Fail to set network address\n", + __func__); + + kalMemFree(prParamNetAddrList, VIR_MEM_TYPE, u4Len); + +} + +void kalSetNetAddressFromInterface(IN struct GLUE_INFO + *prGlueInfo, IN struct net_device *prDev, IN u_int8_t fgSet) +{ + uint32_t u4NumIPv4, u4NumIPv6; + uint8_t pucIPv4Addr[IPV4_ADDR_LEN * CFG_PF_ARP_NS_MAX_NUM*2]; + uint8_t pucIPv6Addr[IPV6_ADDR_LEN * CFG_PF_ARP_NS_MAX_NUM]; + struct NETDEV_PRIVATE_GLUE_INFO *prNetDevPrivate = + (struct NETDEV_PRIVATE_GLUE_INFO *) NULL; + + prNetDevPrivate = (struct NETDEV_PRIVATE_GLUE_INFO *) + netdev_priv(prDev); + + if (prNetDevPrivate->prGlueInfo != prGlueInfo) + DBGLOG(REQ, WARN, "%s: unexpected prGlueInfo(0x%p)!\n", + __func__, prNetDevPrivate->prGlueInfo); + + u4NumIPv4 = 0; + u4NumIPv6 = 0; + + if (fgSet) { + kalGetIPv4Address(prDev, CFG_PF_ARP_NS_MAX_NUM, pucIPv4Addr, + &u4NumIPv4); + kalGetIPv6Address(prDev, CFG_PF_ARP_NS_MAX_NUM, pucIPv6Addr, + &u4NumIPv6); + } + + if (u4NumIPv4 + u4NumIPv6 > CFG_PF_ARP_NS_MAX_NUM) { + if (u4NumIPv4 >= CFG_PF_ARP_NS_MAX_NUM) { + u4NumIPv4 = CFG_PF_ARP_NS_MAX_NUM; + u4NumIPv6 = 0; + } else { + u4NumIPv6 = CFG_PF_ARP_NS_MAX_NUM - u4NumIPv4; + } + } + + kalSetNetAddress(prGlueInfo, prNetDevPrivate->ucBssIdx, + pucIPv4Addr, u4NumIPv4, pucIPv6Addr, u4NumIPv6); +} + +#if CFG_MET_PACKET_TRACE_SUPPORT + +u_int8_t kalMetCheckProfilingPacket(IN struct GLUE_INFO + *prGlueInfo, IN void *prPacket) +{ + uint32_t u4PacketLen; + uint16_t u2EtherTypeLen; + struct sk_buff *prSkb = (struct sk_buff *)prPacket; + uint8_t *aucLookAheadBuf = NULL; + uint8_t ucEthTypeLenOffset = ETHER_HEADER_LEN - + ETHER_TYPE_LEN; + uint8_t *pucNextProtocol = NULL; + + u4PacketLen = prSkb->len; + + if (u4PacketLen < ETHER_HEADER_LEN) { + DBGLOG(INIT, WARN, "Invalid Ether packet length: %u\n", + u4PacketLen); + return FALSE; + } + + aucLookAheadBuf = prSkb->data; + + /* 4 <0> Obtain Ether Type/Len */ + WLAN_GET_FIELD_BE16(&aucLookAheadBuf[ucEthTypeLenOffset], + &u2EtherTypeLen); + + /* 4 <1> Skip 802.1Q header (VLAN Tagging) */ + if (u2EtherTypeLen == ETH_P_VLAN) { + ucEthTypeLenOffset += ETH_802_1Q_HEADER_LEN; + WLAN_GET_FIELD_BE16(&aucLookAheadBuf[ucEthTypeLenOffset], + &u2EtherTypeLen); + } + /* 4 <2> Obtain next protocol pointer */ + pucNextProtocol = &aucLookAheadBuf[ucEthTypeLenOffset + + ETHER_TYPE_LEN]; + + /* 4 <3> Handle ethernet format */ + switch (u2EtherTypeLen) { + + /* IPv4 */ + case ETH_P_IPV4: { + uint8_t *pucIpHdr = pucNextProtocol; + uint8_t ucIpVersion; + + /* IPv4 header length check */ + if (u4PacketLen < (ucEthTypeLenOffset + ETHER_TYPE_LEN + + IPV4_HDR_LEN)) { + DBGLOG(INIT, WARN, "Invalid IPv4 packet length: %u\n", + u4PacketLen); + return FALSE; + } + + /* IPv4 version check */ + ucIpVersion = (pucIpHdr[0] & IP_VERSION_MASK) >> + IP_VERSION_OFFSET; + if (ucIpVersion != IP_VERSION_4) { + DBGLOG(INIT, WARN, "Invalid IPv4 packet version: %u\n", + ucIpVersion); + return FALSE; + } + + if (pucIpHdr[IPV4_HDR_IP_PROTOCOL_OFFSET] == IP_PRO_UDP) { + uint8_t *pucUdpHdr = &pucIpHdr[IPV4_HDR_LEN]; + uint16_t u2UdpDstPort; + uint16_t u2UdpSrcPort; + + /* Get UDP DST port */ + WLAN_GET_FIELD_BE16(&pucUdpHdr[UDP_HDR_DST_PORT_OFFSET], + &u2UdpDstPort); + + /* Get UDP SRC port */ + WLAN_GET_FIELD_BE16(&pucUdpHdr[UDP_HDR_SRC_PORT_OFFSET], + &u2UdpSrcPort); + + if (u2UdpSrcPort == prGlueInfo->u2MetUdpPort) { + uint16_t u2IpId; + + /* Store IP ID for Tag */ + WLAN_GET_FIELD_BE16( + &pucIpHdr[IPV4_HDR_IP_IDENTIFICATION_OFFSET], + &u2IpId); +#if 0 + DBGLOG(INIT, INFO, + "TX PKT PROTOCOL[0x%x] UDP DST port[%u] IP_ID[%u]\n", + pucIpHdr[IPV4_HDR_IP_PROTOCOL_OFFSET], + u2UdpDstPort, + u2IpId); +#endif + GLUE_SET_PKT_IP_ID(prPacket, u2IpId); + + return TRUE; + } + } + } + break; + + default: + break; + } + + return FALSE; +} + +#if 0 + +static unsigned long __read_mostly tracing_mark_write_addr; + +static int __mt_find_tracing_mark_write_symbol_fn( + void *prData, const char *pcNameBuf, + struct module *prModule, unsigned long ulAddress) +{ + if (strcmp(pcNameBuf, "tracing_mark_write") == 0) { + tracing_mark_write_addr = ulAddress; + return 1; + } + return 0; +} +#endif + +static inline void __mt_update_tracing_mark_write_addr(void) +{ +#if 0 + if (unlikely(tracing_mark_write_addr == 0)) + kallsyms_on_each_symbol( + __mt_find_tracing_mark_write_symbol_fn, NULL); +#endif +} + +void kalMetTagPacket(IN struct GLUE_INFO *prGlueInfo, + IN void *prPacket, IN enum ENUM_TX_PROFILING_TAG eTag) +{ + if (!prGlueInfo->fgMetProfilingEn) + return; + + switch (eTag) { + case TX_PROF_TAG_OS_TO_DRV: + if (kalMetCheckProfilingPacket(prGlueInfo, prPacket)) { + /* trace_printk("S|%d|%s|%d\n", current->pid, + * "WIFI-CHIP", GLUE_GET_PKT_IP_ID(prPacket)); + */ + __mt_update_tracing_mark_write_addr(); +#if 0 /* #ifdef CONFIG_TRACING */ /* #if CFG_MET_PACKET_TRACE_SUPPORT */ + event_trace_printk(tracing_mark_write_addr, + "S|%d|%s|%d\n", + current->tgid, "WIFI-CHIP", + GLUE_GET_PKT_IP_ID(prPacket)); +#endif + GLUE_SET_PKT_FLAG_PROF_MET(prPacket); + } + break; + + case TX_PROF_TAG_DRV_TX_DONE: + if (GLUE_GET_PKT_IS_PROF_MET(prPacket)) { + /* trace_printk("F|%d|%s|%d\n", current->pid, + * "WIFI-CHIP", GLUE_GET_PKT_IP_ID(prPacket)); + */ + __mt_update_tracing_mark_write_addr(); +#if 0 /* #ifdef CONFIG_TRACING */ /* #if CFG_MET_PACKET_TRACE_SUPPORT */ + event_trace_printk(tracing_mark_write_addr, + "F|%d|%s|%d\n", + current->tgid, "WIFI-CHIP", + GLUE_GET_PKT_IP_ID(prPacket)); +#endif + } + break; + + default: + break; + } +} + +void kalMetInit(IN struct GLUE_INFO *prGlueInfo) +{ + prGlueInfo->fgMetProfilingEn = FALSE; + prGlueInfo->u2MetUdpPort = 0; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief The PROC function for adjusting Debug Level to turn on/off debugging + * message. + * + * \param[in] file pointer to file. + * \param[in] buffer Buffer from user space. + * \param[in] count Number of characters to write + * \param[in] data Pointer to the private data structure. + * + * \return number of characters write from User Space. + */ +/*----------------------------------------------------------------------------*/ +#if 0 +static ssize_t kalMetWriteProcfs(struct file *file, + const char __user *buffer, size_t count, loff_t *off) +{ + char acBuf[128 + 1]; /* + 1 for "\0" */ + uint32_t u4CopySize; + int u16MetUdpPort; + int u8MetProfEnable; + + IN struct GLUE_INFO *prGlueInfo; + ssize_t result; + + u4CopySize = (count < (sizeof(acBuf) - 1)) ? count : + (sizeof(acBuf) - 1); + result = copy_from_user(acBuf, buffer, u4CopySize); + acBuf[u4CopySize] = '\0'; + + if (sscanf(acBuf, " %d %d", &u8MetProfEnable, + &u16MetUdpPort) == 2) + DBGLOG(INIT, INFO, + "MET_PROF: Write MET PROC Enable=%d UDP_PORT=%d\n", + u8MetProfEnable, u16MetUdpPort); + if (pMetGlobalData != NULL) { + prGlueInfo = (struct GLUE_INFO *) pMetGlobalData; + prGlueInfo->fgMetProfilingEn = (u_int8_t) u8MetProfEnable; + prGlueInfo->u2MetUdpPort = (uint16_t) u16MetUdpPort; + } + return count; +} +#endif +static ssize_t kalMetCtrlWriteProcfs(struct file *file, + const char __user *buffer, size_t count, loff_t *off) +{ + char acBuf[128 + 1]; /* + 1 for "\0" */ + uint32_t u4CopySize; + int u8MetProfEnable; + ssize_t result; + + IN struct GLUE_INFO *prGlueInfo; + + u4CopySize = (count < (sizeof(acBuf) - 1)) ? count : + (sizeof(acBuf) - 1); + result = copy_from_user(acBuf, buffer, u4CopySize); + acBuf[u4CopySize] = '\0'; + + if (sscanf(acBuf, " %d", &u8MetProfEnable) == 1) + DBGLOG(INIT, INFO, "MET_PROF: Write MET PROC Enable=%d\n", + u8MetProfEnable); + if (pMetGlobalData != NULL) { + prGlueInfo = (struct GLUE_INFO *) pMetGlobalData; + prGlueInfo->fgMetProfilingEn = (uint8_t) u8MetProfEnable; + } + return count; +} + +static ssize_t kalMetPortWriteProcfs(struct file *file, + const char __user *buffer, size_t count, loff_t *off) +{ + char acBuf[128 + 1]; /* + 1 for "\0" */ + uint32_t u4CopySize; + int u16MetUdpPort; + ssize_t result; + + IN struct GLUE_INFO *prGlueInfo; + + u4CopySize = (count < (sizeof(acBuf) - 1)) ? count : + (sizeof(acBuf) - 1); + result = copy_from_user(acBuf, buffer, u4CopySize); + acBuf[u4CopySize] = '\0'; + + if (sscanf(acBuf, " %d", &u16MetUdpPort) == 1) + DBGLOG(INIT, INFO, "MET_PROF: Write MET PROC UDP_PORT=%d\n", + u16MetUdpPort); + if (pMetGlobalData != NULL) { + prGlueInfo = (struct GLUE_INFO *) pMetGlobalData; + prGlueInfo->u2MetUdpPort = (uint16_t) u16MetUdpPort; + } + return count; +} + +#if 0 +const struct file_operations rMetProcFops = { + .write = kalMetWriteProcfs +}; +#endif +const struct file_operations rMetProcCtrlFops = { + .write = kalMetCtrlWriteProcfs +}; + +const struct file_operations rMetProcPortFops = { + .write = kalMetPortWriteProcfs +}; + +int kalMetInitProcfs(IN struct GLUE_INFO *prGlueInfo) +{ + /* struct proc_dir_entry *pMetProcDir; */ + if (init_net.proc_net == (struct proc_dir_entry *)NULL) { + DBGLOG(INIT, INFO, "init proc fs fail: proc_net == NULL\n"); + return -ENOENT; + } + /* + * Directory: Root (/proc/net/wlan0) + */ + pMetProcDir = proc_mkdir("wlan0", init_net.proc_net); + if (pMetProcDir == NULL) + return -ENOENT; + /* + * /proc/net/wlan0 + * |-- met_ctrl (PROC_MET_PROF_CTRL) + */ + /* proc_create(PROC_MET_PROF_CTRL, 0x0644, pMetProcDir, &rMetProcFops); + */ + proc_create(PROC_MET_PROF_CTRL, 0000, pMetProcDir, + &rMetProcCtrlFops); + proc_create(PROC_MET_PROF_PORT, 0000, pMetProcDir, + &rMetProcPortFops); + + pMetGlobalData = (void *)prGlueInfo; + + return 0; +} + +int kalMetRemoveProcfs(void) +{ + + if (init_net.proc_net == (struct proc_dir_entry *)NULL) { + DBGLOG(INIT, WARN, + "remove proc fs fail: proc_net == NULL\n"); + return -ENOENT; + } + remove_proc_entry(PROC_MET_PROF_CTRL, pMetProcDir); + remove_proc_entry(PROC_MET_PROF_PORT, pMetProcDir); + /* remove root directory (proc/net/wlan0) */ + remove_proc_entry("wlan0", init_net.proc_net); + /* clear MetGlobalData */ + pMetGlobalData = NULL; + + return 0; +} + +#endif + +static u_int8_t kalSendUevent(const char *src) +{ + int ret; + char *envp[2]; + char event_string[32]; + + envp[0] = event_string; + envp[1] = NULL; + + /*send uevent*/ + strlcpy(event_string, src, sizeof(event_string)); + if (event_string[0] == '\0') { /*string is null*/ + return FALSE; + } + ret = kobject_uevent_env( + &wlan_object.this_device->kobj, + KOBJ_CHANGE, envp); + if (ret != 0) { + DBGLOG(INIT, WARN, "uevent failed\n"); + return FALSE; + } + + return TRUE; +} + +int kalWlanUeventInit(void) +{ + int ret = 0; + + /* dev init */ + wlan_object.name = "wlan"; + wlan_object.minor = MISC_DYNAMIC_MINOR; + ret = misc_register(&wlan_object); + if (ret) { + DBGLOG(INIT, WARN, "misc_register error:%d\n", ret); + return ret; + } + + ret = kobject_uevent( + &wlan_object.this_device->kobj, KOBJ_ADD); + + if (ret) { + misc_deregister(&wlan_object); + DBGLOG(INIT, WARN, "uevent creat fail:%d\n", ret); + return ret; + } + + return ret; +} + +void kalWlanUeventDeinit(void) +{ + misc_deregister(&wlan_object); +} + +#if CFG_SUPPORT_DATA_STALL +u_int8_t kalIndicateDriverEvent(struct ADAPTER *prAdapter, + uint32_t event, + uint16_t dataLen, + uint8_t ucBssIdx, + u_int8_t fgForceReport) +{ + struct sk_buff *skb = NULL; + struct wiphy *wiphy; + struct wireless_dev *wdev; + struct WIFI_VAR *prWifiVar = &prAdapter->rWifiVar; + char uevent[30]; + + wiphy = priv_to_wiphy(prAdapter->prGlueInfo); + wdev = (wlanGetNetDev(prAdapter->prGlueInfo, + ucBssIdx))->ieee80211_ptr; + + if (!wiphy || !wdev || !prWifiVar) + return -EINVAL; + + if (!fgForceReport) { + if (prAdapter->tmReportinterval > 0 && + !CHECK_FOR_TIMEOUT(kalGetTimeTick(), + prAdapter->tmReportinterval, + prWifiVar->u4ReportEventInterval*1000)) { + return -ETIME; + } + GET_CURRENT_SYSTIME(&prAdapter->tmReportinterval); + } + + kalSnprintf(uevent, sizeof(uevent), "code=%d", event); + kalSendUevent(uevent); + + skb = cfg80211_vendor_event_alloc(wiphy, wdev, + dataLen, + WIFI_EVENT_DRIVER_ERROR, GFP_KERNEL); + if (!skb) { + DBGLOG(REQ, ERROR, "%s allocate skb failed\n", __func__); + return -ENOMEM; + } + + if (dataLen > 0 && + unlikely(nla_put(skb, WIFI_ATTRIBUTE_ERROR_REASON + , dataLen, &event) < 0)) + goto nla_put_failure; + + DBGLOG(INIT, ERROR, "DPP event to cfg80211[id:%d][len:%d][F:%d]:%d\n", + WIFI_EVENT_DRIVER_ERROR, + dataLen, fgForceReport, event); + + cfg80211_vendor_event(skb, GFP_KERNEL); + return TRUE; +nla_put_failure: + kfree_skb(skb); + return FALSE; +} +#endif + +#if CFG_SUPPORT_BIGDATA_PIP +int8_t kalBigDataPip(struct ADAPTER *prAdapter, + uint8_t *payload, + uint16_t dataLen) +{ + struct sk_buff *skb = NULL; + struct wiphy *wiphy; + struct wireless_dev *wdev; + struct WIFI_VAR *prWifiVar = &prAdapter->rWifiVar; + + wiphy = priv_to_wiphy(prAdapter->prGlueInfo); + wdev = ((prAdapter->prGlueInfo)->prDevHandler)->ieee80211_ptr; + + if (!wiphy || !wdev || !prWifiVar || !payload) + return -EINVAL; + + /* Max length of report data is discussed to 500.*/ + if (dataLen > 500) + return -EINVAL; + + if (prAdapter->tmDataPipReportinterval > 0 && + !CHECK_FOR_TIMEOUT(kalGetTimeTick(), + prAdapter->tmDataPipReportinterval, 20)) { + return -ETIME; + } + GET_CURRENT_SYSTIME(&prAdapter->tmDataPipReportinterval); + + skb = cfg80211_vendor_event_alloc(wiphy, wdev, dataLen, + WIFI_EVENT_BIGDATA_PIP, GFP_KERNEL); + if (!skb) { + DBGLOG(REQ, ERROR, "%s allocate skb failed\n", __func__); + return -ENOMEM; + } + + if (dataLen > 0 && + unlikely(nla_put(skb, WIFI_ATTRIBUTE_PIP_PAYLOAD + , dataLen, payload) < 0)) + goto nla_put_failure; + + cfg80211_vendor_event(skb, GFP_KERNEL); + return TRUE; +nla_put_failure: + kfree_skb(skb); + return FALSE; +} +#endif + +#if CFG_SUPPORT_AGPS_ASSIST +u_int8_t kalIndicateAgpsNotify(struct ADAPTER *prAdapter, + uint8_t cmd, uint8_t *data, uint16_t dataLen) +{ +#ifdef CONFIG_NL80211_TESTMODE + struct GLUE_INFO *prGlueInfo = prAdapter->prGlueInfo; + struct sk_buff *skb = NULL; + + skb = cfg80211_testmode_alloc_event_skb(priv_to_wiphy( + prGlueInfo), + dataLen, GFP_KERNEL); + + /* DBGLOG(CCX, INFO, ("WLAN_STATUS_AGPS_NOTIFY, cmd=%d\n", cmd)); */ + if (unlikely(nla_put(skb, MTK_ATTR_AGPS_CMD, sizeof(cmd), + &cmd) < 0)) + goto nla_put_failure; + if (dataLen > 0 && data + && unlikely(nla_put(skb, MTK_ATTR_AGPS_DATA, dataLen, + data) < 0)) + goto nla_put_failure; + if (unlikely(nla_put(skb, MTK_ATTR_AGPS_IFINDEX, + sizeof(uint32_t), &prGlueInfo->prDevHandler->ifindex) < 0)) + goto nla_put_failure; + /* currently, the ifname maybe wlan0, p2p0, so the maximum name length + * will be 5 bytes + */ + if (unlikely(nla_put(skb, MTK_ATTR_AGPS_IFNAME, 5, + prGlueInfo->prDevHandler->name) < 0)) + goto nla_put_failure; + + cfg80211_testmode_event(skb, GFP_KERNEL); + return TRUE; +nla_put_failure: + kfree_skb(skb); +#else + DBGLOG(INIT, WARN, "CONFIG_NL80211_TESTMODE not enabled\n"); +#endif + return FALSE; +} +#endif + +uint64_t kalGetBootTime(void) +{ +#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE + struct timespec64 ts; +#else + struct timespec ts; +#endif + uint64_t bootTime = 0; + +#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE + ktime_get_boottime_ts64(&ts); +#elif KERNEL_VERSION(2, 6, 39) <= LINUX_VERSION_CODE + get_monotonic_boottime(&ts); +#else + ts = ktime_to_timespec(ktime_get()); +#endif + + bootTime = ts.tv_sec; + bootTime *= USEC_PER_SEC; + bootTime += ts.tv_nsec / NSEC_PER_USEC; + return bootTime; +} + +#if CFG_ASSERT_DUMP +uint32_t kalOpenCorDumpFile(u_int8_t fgIsN9) +{ + /* Move open-op to kalWriteCorDumpFile(). Empty files only */ + uint32_t ret; + uint8_t *apucFileName; + + if (fgIsN9) + apucFileName = apucCorDumpN9FileName; + else + apucFileName = apucCorDumpCr4FileName; + + ret = kalTrunkPath(apucFileName); + + return (ret >= 0)?WLAN_STATUS_SUCCESS:WLAN_STATUS_FAILURE; +} + +uint32_t kalWriteCorDumpFile(uint8_t *pucBuffer, + uint16_t u2Size, u_int8_t fgIsN9) +{ + uint32_t ret; + uint8_t *apucFileName; + + if (fgIsN9) + apucFileName = apucCorDumpN9FileName; + else + apucFileName = apucCorDumpCr4FileName; + + ret = kalWriteToFile(apucFileName, TRUE, pucBuffer, u2Size); + + return (ret >= 0)?WLAN_STATUS_SUCCESS:WLAN_STATUS_FAILURE; +} + +uint32_t kalCloseCorDumpFile(u_int8_t fgIsN9) +{ + /* Move close-op to kalWriteCorDumpFile(). Do nothing here */ + + return WLAN_STATUS_SUCCESS; +} +#endif + +#if CFG_WOW_SUPPORT +void kalWowInit(IN struct GLUE_INFO *prGlueInfo) +{ + kalMemZero(&prGlueInfo->prAdapter->rWowCtrl.stWowPort, + sizeof(struct WOW_PORT)); +} + +void kalWowCmdEventSetCb(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf) +{ + ASSERT(prAdapter); + ASSERT(prCmdInfo); + + + if (prCmdInfo->ucCID == CMD_ID_SET_PF_CAPABILITY) { + DBGLOG(INIT, STATE, "CMD_ID_SET_PF_CAPABILITY cmd done\n"); + prAdapter->fgSetPfCapabilityDone = TRUE; + } + + if (prCmdInfo->ucCID == CMD_ID_SET_WOWLAN) { + DBGLOG(INIT, STATE, "CMD_ID_SET_WOWLAN cmd done\n"); + prAdapter->fgSetWowDone = TRUE; + } + +} + +void kalWowProcess(IN struct GLUE_INFO *prGlueInfo, + uint8_t enable) +{ + struct CMD_WOWLAN_PARAM rCmdWowlanParam; + struct CMD_PACKET_FILTER_CAP rCmdPacket_Filter_Cap; + struct WOW_CTRL *pWOW_CTRL = + &prGlueInfo->prAdapter->rWowCtrl; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t ii, wait = 0; + struct BSS_INFO *prAisBssInfo = NULL; + + kalMemZero(&rCmdWowlanParam, + sizeof(struct CMD_WOWLAN_PARAM)); + + kalMemZero(&rCmdPacket_Filter_Cap, + sizeof(struct CMD_PACKET_FILTER_CAP)); + + prGlueInfo->prAdapter->fgSetPfCapabilityDone = FALSE; + prGlueInfo->prAdapter->fgSetWowDone = FALSE; + + prAisBssInfo = aisGetConnectedBssInfo( + prGlueInfo->prAdapter); + + if (prAisBssInfo) + DBGLOG(PF, INFO, + "PF, pAd ucBssIndex=%d, ucOwnMacIndex=%d\n", + prAisBssInfo->ucBssIndex, + prAisBssInfo->ucOwnMacIndex); + + DBGLOG(PF, INFO, "profile wow=%d, GpioInterval=%d\n", + prGlueInfo->prAdapter->rWifiVar.ucWow, + prGlueInfo->prAdapter->rWowCtrl.astWakeHif[0].u4GpioInterval); + + rCmdPacket_Filter_Cap.packet_cap_type |= + PACKETF_CAP_TYPE_MAGIC; + /* 20160627 Bennett: if receive BMC magic, PF search by bssid index, + * which is different with OM index + */ + /* After discussion, enable all bssid bits */ + /* rCmdPacket_Filter_Cap.ucBssid |= + * BIT(prGlueInfo->prAdapter->prAisBssInfo->ucOwnMacIndex); + */ + rCmdPacket_Filter_Cap.ucBssid |= BITS(0, 3); + + if (enable) + rCmdPacket_Filter_Cap.usEnableBits |= + PACKETF_CAP_TYPE_MAGIC; + else + rCmdPacket_Filter_Cap.usEnableBits &= + ~PACKETF_CAP_TYPE_MAGIC; + + rStatus = wlanSendSetQueryCmd(prGlueInfo->prAdapter, + CMD_ID_SET_PF_CAPABILITY, + TRUE, + FALSE, + FALSE, + kalWowCmdEventSetCb, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_PACKET_FILTER_CAP), + (uint8_t *)&rCmdPacket_Filter_Cap, + NULL, + 0); + + /* ARP offload */ + wlanSetSuspendMode(prGlueInfo, enable); + /* p2pSetSuspendMode(prGlueInfo, TRUE); */ + + /* Let WOW enable/disable as last command, so we can back/restore DMA + * classify filter in FW + */ + rCmdWowlanParam.ucScenarioID = pWOW_CTRL->ucScenarioId; + rCmdWowlanParam.ucBlockCount = pWOW_CTRL->ucBlockCount; + kalMemCopy(&rCmdWowlanParam.astWakeHif[0], + &pWOW_CTRL->astWakeHif[0], sizeof(struct WOW_WAKE_HIF)); + + /* copy UDP/TCP port setting */ + kalMemCopy(&rCmdWowlanParam.stWowPort, + &prGlueInfo->prAdapter->rWowCtrl.stWowPort, + sizeof(struct WOW_PORT)); + + DBGLOG(PF, INFO, + "Cmd: IPV4/UDP=%d, IPV4/TCP=%d, IPV6/UDP=%d, IPV6/TCP=%d\n", + rCmdWowlanParam.stWowPort.ucIPv4UdpPortCnt, + rCmdWowlanParam.stWowPort.ucIPv4TcpPortCnt, + rCmdWowlanParam.stWowPort.ucIPv6UdpPortCnt, + rCmdWowlanParam.stWowPort.ucIPv6TcpPortCnt); + + for (ii = 0; + ii < rCmdWowlanParam.stWowPort.ucIPv4UdpPortCnt; ii++) + DBGLOG(PF, INFO, "IPV4/UDP port[%d]=%d\n", ii, + rCmdWowlanParam.stWowPort.ausIPv4UdpPort[ii]); + + for (ii = 0; + ii < rCmdWowlanParam.stWowPort.ucIPv4TcpPortCnt; ii++) + DBGLOG(PF, INFO, "IPV4/TCP port[%d]=%d\n", ii, + rCmdWowlanParam.stWowPort.ausIPv4TcpPort[ii]); + + for (ii = 0; + ii < rCmdWowlanParam.stWowPort.ucIPv6UdpPortCnt; ii++) + DBGLOG(PF, INFO, "IPV6/UDP port[%d]=%d\n", ii, + rCmdWowlanParam.stWowPort.ausIPv6UdpPort[ii]); + + for (ii = 0; + ii < rCmdWowlanParam.stWowPort.ucIPv6TcpPortCnt; ii++) + DBGLOG(PF, INFO, "IPV6/TCP port[%d]=%d\n", ii, + rCmdWowlanParam.stWowPort.ausIPv6TcpPort[ii]); + + + /* GPIO parameter is necessary in suspend/resume */ + if (enable == 1) { + rCmdWowlanParam.ucCmd = PM_WOWLAN_REQ_START; + rCmdWowlanParam.ucDetectType = WOWLAN_DETECT_TYPE_MAGIC | + WOWLAN_DETECT_TYPE_ONLY_PHONE_SUSPEND; + rCmdWowlanParam.u2FilterFlag = WOWLAN_FF_DROP_ALL | + WOWLAN_FF_SEND_MAGIC_TO_HOST | + WOWLAN_FF_ALLOW_1X | + WOWLAN_FF_ALLOW_ARP_REQ2ME; + } else { + rCmdWowlanParam.ucCmd = PM_WOWLAN_REQ_STOP; + } + + rStatus = wlanSendSetQueryCmd(prGlueInfo->prAdapter, + CMD_ID_SET_WOWLAN, + TRUE, + FALSE, + FALSE, + kalWowCmdEventSetCb, + nicOidCmdTimeoutCommon, + sizeof(struct CMD_WOWLAN_PARAM), + (uint8_t *)&rCmdWowlanParam, + NULL, + 0); + + + while (1) { + kalMsleep(5); + + if (wait > 100) { + DBGLOG(INIT, ERROR, "WoW timeout.PF:%d. WoW:%d\n", + prGlueInfo->prAdapter->fgSetPfCapabilityDone, + prGlueInfo->prAdapter->fgSetWowDone); + break; + } + if ((prGlueInfo->prAdapter->fgSetPfCapabilityDone == TRUE) + && (prGlueInfo->prAdapter->fgSetWowDone == TRUE)) { + DBGLOG(INIT, STATE, "WoW process done\n"); + break; + } + wait++; + } + +} +#endif + +void kalFreeTxMsduWorker(struct work_struct *work) +{ + struct GLUE_INFO *prGlueInfo; + struct ADAPTER *prAdapter; + struct QUE rTmpQue; + struct QUE *prTmpQue = &rTmpQue; + struct MSDU_INFO *prMsduInfo; + + if (g_u4HaltFlag) + return; + + prGlueInfo = ENTRY_OF(work, struct GLUE_INFO, + rTxMsduFreeWork); + prAdapter = prGlueInfo->prAdapter; + + if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) + return; + + KAL_ACQUIRE_MUTEX(prAdapter, MUTEX_TX_DATA_DONE_QUE); + QUEUE_MOVE_ALL(prTmpQue, &prAdapter->rTxDataDoneQueue); + KAL_RELEASE_MUTEX(prAdapter, MUTEX_TX_DATA_DONE_QUE); + + while (QUEUE_IS_NOT_EMPTY(prTmpQue)) { + QUEUE_REMOVE_HEAD(prTmpQue, prMsduInfo, struct MSDU_INFO *); + nicTxFreePacket(prAdapter, prMsduInfo, FALSE); + nicTxReturnMsduInfo(prAdapter, prMsduInfo); + } +} + +void kalFreeTxMsdu(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo) +{ + + KAL_ACQUIRE_MUTEX(prAdapter, MUTEX_TX_DATA_DONE_QUE); + QUEUE_INSERT_TAIL(&prAdapter->rTxDataDoneQueue, + (struct QUE_ENTRY *) prMsduInfo); + KAL_RELEASE_MUTEX(prAdapter, MUTEX_TX_DATA_DONE_QUE); + + schedule_work(&prAdapter->prGlueInfo->rTxMsduFreeWork); +} + +int32_t kalHaltLock(uint32_t waitMs) +{ + int32_t i4Ret = 0; + struct GLUE_INFO *prGlueInfo = NULL; + + if (waitMs) { + i4Ret = down_timeout(&rHaltCtrl.lock, + MSEC_TO_JIFFIES(waitMs)); + if (!i4Ret) + goto success; + if (i4Ret != -ETIME) + return i4Ret; + + prGlueInfo = wlanGetGlueInfo(); + if (rHaltCtrl.fgHeldByKalIoctl) { + DBGLOG(INIT, ERROR, + "kalIoctl was executed longer than %u ms, show backtrace of tx_thread!\n", + kalGetTimeTick() - rHaltCtrl.u4HoldStart); + if (prGlueInfo) + kal_show_stack(prGlueInfo->prAdapter, + prGlueInfo->main_thread, NULL); + } else { + DBGLOG(INIT, ERROR, + "halt lock held by %s pid %d longer than %u ms!\n", + rHaltCtrl.owner->comm, rHaltCtrl.owner->pid, + kalGetTimeTick() - rHaltCtrl.u4HoldStart); + if (prGlueInfo) + kal_show_stack(prGlueInfo->prAdapter, + rHaltCtrl.owner, NULL); + } + return i4Ret; + } + down(&rHaltCtrl.lock); +success: + rHaltCtrl.owner = current; + rHaltCtrl.u4HoldStart = kalGetTimeTick(); + return 0; +} + +int32_t kalHaltTryLock(void) +{ + int32_t i4Ret = 0; + + i4Ret = down_trylock(&rHaltCtrl.lock); + if (i4Ret) + return i4Ret; + rHaltCtrl.owner = current; + rHaltCtrl.u4HoldStart = kalGetTimeTick(); + return 0; +} + +void kalHaltUnlock(void) +{ + if (kalGetTimeTick() - rHaltCtrl.u4HoldStart > + WLAN_OID_TIMEOUT_THRESHOLD * 2 && + rHaltCtrl.owner) + DBGLOG(INIT, ERROR, + "process %s pid %d hold halt lock longer than 4s!\n", + rHaltCtrl.owner->comm, rHaltCtrl.owner->pid); + rHaltCtrl.owner = NULL; + up(&rHaltCtrl.lock); +} + +void kalSetHalted(u_int8_t fgHalt) +{ + rHaltCtrl.fgHalt = fgHalt; +} + +u_int8_t kalIsHalted(void) +{ + return rHaltCtrl.fgHalt; +} + + +#if 0 +void kalPerMonDump(IN struct GLUE_INFO *prGlueInfo) +{ + struct PERF_MONITOR *prPerMonitor; + + prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor; + DBGLOG(SW4, WARN, "ulPerfMonFlag:0x%lx\n", + prPerMonitor->ulPerfMonFlag); + DBGLOG(SW4, WARN, "ulLastTxBytes:%d\n", + prPerMonitor->ulLastTxBytes); + DBGLOG(SW4, WARN, "ulLastRxBytes:%d\n", + prPerMonitor->ulLastRxBytes); + DBGLOG(SW4, WARN, "ulP2PLastTxBytes:%d\n", + prPerMonitor->ulP2PLastTxBytes); + DBGLOG(SW4, WARN, "ulP2PLastRxBytes:%d\n", + prPerMonitor->ulP2PLastRxBytes); + DBGLOG(SW4, WARN, "ulThroughput:%d\n", + prPerMonitor->ulThroughput); + DBGLOG(SW4, WARN, "u4UpdatePeriod:%d\n", + prPerMonitor->u4UpdatePeriod); + DBGLOG(SW4, WARN, "u4TarPerfLevel:%d\n", + prPerMonitor->u4TarPerfLevel); + DBGLOG(SW4, WARN, "u4CurrPerfLevel:%d\n", + prPerMonitor->u4CurrPerfLevel); + DBGLOG(SW4, WARN, "netStats tx_bytes:%d\n", + prGlueInfo->prDevHandler->stats.tx_bytes); + DBGLOG(SW4, WARN, "netStats tx_bytes:%d\n", + prGlueInfo->prDevHandler->stats.rx_bytes); + DBGLOG(SW4, WARN, "p2p netStats tx_bytes:%d\n", + prGlueInfo->prP2PInfo->prDevHandler->stats.tx_bytes); + DBGLOG(SW4, WARN, "p2p netStats tx_bytes:%d\n", + prGlueInfo->prP2PInfo->prDevHandler->stats.rx_bytes); +} +#endif + +#define PERF_UPDATE_PERIOD 1000 /* ms */ +#if (CFG_SUPPORT_PERF_IND == 1) +void kalPerfIndReset(IN struct ADAPTER *prAdapter) +{ + uint8_t i; + + for (i = 0; i < BSSID_NUM; i++) { + prAdapter->prGlueInfo->PerfIndCache.u4CurTxBytes[i] = 0; + prAdapter->prGlueInfo->PerfIndCache.u4CurRxBytes[i] = 0; + prAdapter->prGlueInfo->PerfIndCache.u2CurRxRate[i] = 0; + prAdapter->prGlueInfo->PerfIndCache.ucCurRxRCPI0[i] = 0; + prAdapter->prGlueInfo->PerfIndCache.ucCurRxRCPI1[i] = 0; + } +} /* kalPerfIndReset */ + +void kalSetPerfReport(IN struct ADAPTER *prAdapter) +{ + struct CMD_PERF_IND *prCmdPerfReport; + uint8_t i; + uint32_t u4CurrentTp = 0; + + DEBUGFUNC("kalSetPerfReport()"); + + prCmdPerfReport = (struct CMD_PERF_IND *) + cnmMemAlloc(prAdapter, RAM_TYPE_BUF, + sizeof(struct CMD_PERF_IND)); + + if (!prCmdPerfReport) { + DBGLOG(SW4, ERROR, + "cnmMemAlloc for kalSetPerfReport failed!\n"); + return; + } + kalMemZero(prCmdPerfReport, sizeof(struct CMD_PERF_IND)); + + prCmdPerfReport->ucCmdVer = 0; + prCmdPerfReport->u2CmdLen = sizeof(struct CMD_PERF_IND); + + prCmdPerfReport->u4VaildPeriod = PERF_UPDATE_PERIOD; + + for (i = 0; i < BSS_DEFAULT_NUM; i++) { + prCmdPerfReport->ulCurTxBytes[i] = + prAdapter->prGlueInfo->PerfIndCache.u4CurTxBytes[i]; + prCmdPerfReport->ulCurRxBytes[i] = + prAdapter->prGlueInfo->PerfIndCache.u4CurRxBytes[i]; + prCmdPerfReport->u2CurRxRate[i] = + prAdapter->prGlueInfo->PerfIndCache.u2CurRxRate[i]; + prCmdPerfReport->ucCurRxRCPI0[i] = + prAdapter->prGlueInfo->PerfIndCache.ucCurRxRCPI0[i]; + prCmdPerfReport->ucCurRxRCPI1[i] = + prAdapter->prGlueInfo->PerfIndCache.ucCurRxRCPI1[i]; + prCmdPerfReport->ucCurRxNss[i] = + prAdapter->prGlueInfo->PerfIndCache.ucCurRxNss[i]; + u4CurrentTp += (prCmdPerfReport->ulCurTxBytes[i] + + prCmdPerfReport->ulCurRxBytes[i]); + } + if (u4CurrentTp != 0) { + DBGLOG(SW4, TRACE, + "Total TP[%d] TX-Byte[%d][%d][%d][%d],RX-Byte[%d][%d][%d][%d]\n", + u4CurrentTp, + prCmdPerfReport->ulCurTxBytes[0], + prCmdPerfReport->ulCurTxBytes[1], + prCmdPerfReport->ulCurTxBytes[2], + prCmdPerfReport->ulCurTxBytes[3], + prCmdPerfReport->ulCurRxBytes[0], + prCmdPerfReport->ulCurRxBytes[1], + prCmdPerfReport->ulCurRxBytes[2], + prCmdPerfReport->ulCurRxBytes[3]); + DBGLOG(SW4, INFO, + "Rate[%d][%d][%d][%d] RCPI[%d][%d][%d][%d]\n", + prCmdPerfReport->u2CurRxRate[0], + prCmdPerfReport->u2CurRxRate[1], + prCmdPerfReport->u2CurRxRate[2], + prCmdPerfReport->u2CurRxRate[3], + prCmdPerfReport->ucCurRxRCPI0[0], + prCmdPerfReport->ucCurRxRCPI0[1], + prCmdPerfReport->ucCurRxRCPI0[2], + prCmdPerfReport->ucCurRxRCPI0[3]); + + wlanSendSetQueryCmd(prAdapter, + CMD_ID_PERF_IND, + TRUE, + FALSE, + FALSE, + NULL, + NULL, + sizeof(*prCmdPerfReport), + (uint8_t *) prCmdPerfReport, NULL, 0); + } + cnmMemFree(prAdapter, prCmdPerfReport); +} /* kalSetPerfReport */ +#endif + +inline int32_t kalPerMonInit(IN struct GLUE_INFO + *prGlueInfo) +{ + struct PERF_MONITOR *prPerMonitor; + struct net_device *prDevHandler = NULL; + uint8_t i = 0; + + prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor; + DBGLOG(SW4, TRACE, "enter %s\n", __func__); + if (KAL_TEST_BIT(PERF_MON_RUNNING_BIT, + prPerMonitor->ulPerfMonFlag)) + DBGLOG(SW4, WARN, + "abnormal, perf monitor already running\n"); + KAL_CLR_BIT(PERF_MON_RUNNING_BIT, + prPerMonitor->ulPerfMonFlag); + KAL_CLR_BIT(PERF_MON_DISABLE_BIT, + prPerMonitor->ulPerfMonFlag); + KAL_SET_BIT(PERF_MON_STOP_BIT, prPerMonitor->ulPerfMonFlag); + prPerMonitor->u4UpdatePeriod = + prGlueInfo->prAdapter->rWifiVar.u4PerfMonUpdatePeriod; + cnmTimerInitTimerOption(prGlueInfo->prAdapter, + &prPerMonitor->rPerfMonTimer, + (PFN_MGMT_TIMEOUT_FUNC) kalPerMonHandler, + (unsigned long) NULL, + TIMER_WAKELOCK_NONE); + + /* sync data with netdev */ + GET_BOOT_SYSTIME(&prPerMonitor->rLastUpdateTime); + for (i = 0; i < BSS_DEFAULT_NUM; i++) { + prDevHandler = wlanGetNetDev(prGlueInfo, i); + if (prDevHandler) { + prPerMonitor->ulLastTxBytes[i] = + prDevHandler->stats.tx_bytes; + prPerMonitor->ulLastRxBytes[i] = + prDevHandler->stats.tx_bytes; + prPerMonitor->ulLastTxPackets[i] = + prDevHandler->stats.tx_packets; + prPerMonitor->ulLastRxPackets[i] = + prDevHandler->stats.rx_packets; + } + } + +#if CFG_SUPPORT_PERF_IND + kalPerfIndReset(prGlueInfo->prAdapter); +#endif + /* enable rps on all cpu cores */ + kalSetRpsMap(prGlueInfo, 0xff); + KAL_SET_BIT(PERF_MON_INIT_BIT, prPerMonitor->ulPerfMonFlag); + DBGLOG(SW4, INFO, "exit %s\n", __func__); + return 0; +} + +inline int32_t kalPerMonDisable(IN struct GLUE_INFO + *prGlueInfo) +{ + struct PERF_MONITOR *prPerMonitor; + + prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor; + + DBGLOG(SW4, INFO, "enter %s\n", __func__); + if (KAL_TEST_BIT(PERF_MON_RUNNING_BIT, + prPerMonitor->ulPerfMonFlag)) { + DBGLOG(SW4, TRACE, "need to stop before disable\n"); + kalPerMonStop(prGlueInfo); + } + KAL_SET_BIT(PERF_MON_DISABLE_BIT, + prPerMonitor->ulPerfMonFlag); + DBGLOG(SW4, TRACE, "exit %s\n", __func__); + return 0; +} + +inline int32_t kalPerMonEnable(IN struct GLUE_INFO + *prGlueInfo) +{ + struct PERF_MONITOR *prPerMonitor; + + prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor; + + DBGLOG(SW4, INFO, "enter %s\n", __func__); + KAL_CLR_BIT(PERF_MON_DISABLE_BIT, + prPerMonitor->ulPerfMonFlag); + DBGLOG(SW4, TRACE, "exit %s\n", __func__); + return 0; +} + +inline int32_t kalPerMonStart(IN struct GLUE_INFO + *prGlueInfo) +{ + struct PERF_MONITOR *prPerMonitor; + + prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor; + DBGLOG(SW4, TEMP, "enter %s\n", __func__); + + if (!wlan_perf_monitor_force_enable && + (wlan_fb_power_down + || prGlueInfo->fgIsInSuspendMode + )) + + return 0; + + if (KAL_TEST_BIT(PERF_MON_DISABLE_BIT, + prPerMonitor->ulPerfMonFlag) || + KAL_TEST_BIT(PERF_MON_RUNNING_BIT, + prPerMonitor->ulPerfMonFlag)) + return 0; + + prPerMonitor->u4CurrPerfLevel = 0; + prPerMonitor->u4TarPerfLevel = 0; + prPerMonitor->u4UpdatePeriod = + prGlueInfo->prAdapter->rWifiVar.u4PerfMonUpdatePeriod; + cnmTimerStartTimer(prGlueInfo->prAdapter, + &prPerMonitor->rPerfMonTimer, prPerMonitor->u4UpdatePeriod); + KAL_SET_BIT(PERF_MON_RUNNING_BIT, + prPerMonitor->ulPerfMonFlag); + KAL_CLR_BIT(PERF_MON_STOP_BIT, prPerMonitor->ulPerfMonFlag); + DBGLOG(SW4, INFO, "perf monitor started\n"); + return 0; +} + +inline int32_t kalPerMonStop(IN struct GLUE_INFO + *prGlueInfo) +{ + struct PERF_MONITOR *prPerMonitor; + + prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor; + DBGLOG(SW4, TRACE, "enter %s\n", __func__); + + if (KAL_TEST_BIT(PERF_MON_DISABLE_BIT, + prPerMonitor->ulPerfMonFlag)) { + DBGLOG(SW4, TRACE, "perf monitor disabled\n"); + return 0; + } + + if (KAL_TEST_BIT(PERF_MON_STOP_BIT, + prPerMonitor->ulPerfMonFlag)) { + DBGLOG(SW4, TRACE, "perf monitor already stopped\n"); + return 0; + } + + KAL_SET_BIT(PERF_MON_STOP_BIT, prPerMonitor->ulPerfMonFlag); + if (KAL_TEST_BIT(PERF_MON_RUNNING_BIT, + prPerMonitor->ulPerfMonFlag)) { + cnmTimerStopTimer(prGlueInfo->prAdapter, + &prPerMonitor->rPerfMonTimer); + KAL_CLR_BIT(PERF_MON_RUNNING_BIT, + prPerMonitor->ulPerfMonFlag); + + prPerMonitor->u4CurrPerfLevel = 0; + prPerMonitor->u4TarPerfLevel = 0; + /*Cancel CPU performance mode request*/ + kalBoostCpu(prGlueInfo->prAdapter, + prPerMonitor->u4TarPerfLevel, + prGlueInfo->prAdapter->rWifiVar.u4BoostCpuTh); + } + DBGLOG(SW4, INFO, "perf monitor stopped\n"); + return 0; +} + +inline int32_t kalPerMonDestroy(IN struct GLUE_INFO + *prGlueInfo) +{ + struct PERF_MONITOR *prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor; + + kalPerMonDisable(prGlueInfo); + KAL_CLR_BIT(PERF_MON_INIT_BIT, prPerMonitor->ulPerfMonFlag); + DBGLOG(SW4, INFO, "exit %s\n", __func__); + return 0; +} + +static uint32_t kalPerMonUpdate(IN struct ADAPTER *prAdapter) +{ + struct PERF_MONITOR *perf = &prAdapter->rPerMonitor; + struct GLUE_INFO *glue = prAdapter->prGlueInfo; + struct BSS_INFO *bss; + struct net_device *ndev = NULL; + struct GL_HIF_INFO *hif = &glue->rHifInfo; + struct WIFI_LINK_QUALITY_INFO *lq = &prAdapter->rLinkQualityInfo; + OS_SYSTIME now, last; + int32_t period; + uint8_t i, j; + signed long txDiffBytes[BSS_DEFAULT_NUM], + rxDiffBytes[BSS_DEFAULT_NUM], + rxDiffPkts[BSS_DEFAULT_NUM], + txDiffPkts[BSS_DEFAULT_NUM]; + signed long lastTxBytes, lastRxBytes, lastTxPkts, lastRxPkts; + unsigned long currentTxBytes, currentRxBytes; + unsigned long currentTxPkts, currentRxPkts; + uint64_t throughput = 0; + char *buf = NULL, *head1, *head2, *head3, *head4; + char *pos = NULL, *end = NULL; + uint32_t slen; + + GET_BOOT_SYSTIME(&now); + last = perf->rLastUpdateTime; + + if (!KAL_TEST_BIT(PERF_MON_INIT_BIT, perf->ulPerfMonFlag) || + !CHECK_FOR_TIMEOUT(now, last, + MSEC_TO_SYSTIME(perf->u4UpdatePeriod))) + return WLAN_STATUS_PENDING; + + perf->rLastUpdateTime = now; + + period = ((int32_t) now - (int32_t) last) * MSEC_PER_SEC / KAL_HZ; + if (period < 0) { + /* overflow should not happen */ + DBGLOG(SW4, WARN, "wrong period: now=%u, last=%u, period=%d\n", + now, last, period); + goto fail; + } + + for (i = 0; i < BSS_DEFAULT_NUM; i++) { + ndev = wlanGetNetDev(glue, i); + bss = GET_BSS_INFO_BY_INDEX(prAdapter, i); + if (IS_BSS_ALIVE(prAdapter, bss) && ndev) { + currentTxBytes = ndev->stats.tx_bytes; + currentRxBytes = ndev->stats.rx_bytes; + currentTxPkts = ndev->stats.tx_packets; + currentRxPkts = ndev->stats.rx_packets; + } else { + currentTxBytes = perf->ulLastTxBytes[i]; + currentRxBytes = perf->ulLastRxBytes[i]; + currentTxPkts = perf->ulLastTxPackets[i]; + currentRxPkts = perf->ulLastRxPackets[i]; + } + lastTxBytes = (signed long) perf->ulLastTxBytes[i]; + lastRxBytes = (signed long) perf->ulLastRxBytes[i]; + perf->ulLastTxBytes[i] = currentTxBytes; + perf->ulLastRxBytes[i] = currentRxBytes; + txDiffBytes[i] = (signed long) currentTxBytes - lastTxBytes; + rxDiffBytes[i] = (signed long) currentRxBytes - lastRxBytes; + + lastTxPkts = (signed long) perf->ulLastTxPackets[i]; + lastRxPkts = (signed long) perf->ulLastRxPackets[i]; + perf->ulLastTxPackets[i] = currentTxPkts; + perf->ulLastRxPackets[i] = currentRxPkts; + txDiffPkts[i] = (signed long) currentTxPkts - lastTxPkts; + rxDiffPkts[i] = (signed long) currentRxPkts - lastRxPkts; + + if (txDiffBytes[i] < 0 || rxDiffBytes[i] < 0) { + /* overflow should not happen */ + DBGLOG(SW4, WARN, + "[i]wrong bytes: tx[%llu][%lld][%lld], rx[%llu][%lld][%lld],\n", + i, + (unsigned long long) currentTxBytes, + (long long) lastTxBytes, + (long long) txDiffBytes[i], + (unsigned long long) currentRxBytes, + (long long) lastRxBytes, + (long long) rxDiffBytes[i]); + goto fail; + } + + /* Divsion first to avoid overflow */ + perf->ulTxTp[i] = (txDiffBytes[i] / period) * MSEC_PER_SEC; + perf->ulRxTp[i] = (rxDiffBytes[i] / period) * MSEC_PER_SEC; + + throughput += txDiffBytes[i] + rxDiffBytes[i]; + } + + perf->ulThroughput = throughput * MSEC_PER_SEC; + do_div(perf->ulThroughput, period); + perf->ulThroughput <<= 3; + + /* The length should include + * 1. "[%ld:%ld:%ld:%ld]" for each bss, %ld range is + * [-9223372036854775807, +9223372036854775807] + * 2. "[%d:...:%d]" for pending frame num, %d range is [-32767, 32767] + * 3. "[%u]" for each TX ring, %u range is [0, 65536] + * 4. ["%lu:%lu:%lu:%lu] dropped packets by each ndev, "%lu" range is + * [0, 18446744073709551615] + */ + slen = (20 * 4 + 5) * BSS_DEFAULT_NUM + 1 + + (6 * CFG_MAX_TXQ_NUM + 2 - 1) * MAX_BSSID_NUM + 1 + + (5 + 2) * NUM_OF_TX_RING + 1 + + (20 * 4 + 5) * BSS_DEFAULT_NUM + 1; + pos = buf = kalMemAlloc(slen, VIR_MEM_TYPE); + if (pos == NULL) { + DBGLOG(SW4, INFO, "Can't allocate memory\n"); + return WLAN_STATUS_RESOURCES; + } + memset(buf, 0, slen); + end = buf + slen; + head1 = pos; + for (i = 0; i < BSS_DEFAULT_NUM; ++i) { + pos += kalSnprintf(pos, end - pos, "[%lld:%lld:%lld:%lld]", + (long long) txDiffBytes[i], + (long long) txDiffPkts[i], + (long long) rxDiffBytes[i], + (long long) rxDiffPkts[i]); + } + pos++; + head2 = pos; + for (i = 0; i < MAX_BSSID_NUM; ++i) { + pos += kalSnprintf(pos, end - pos, "["); + for (j = 0; j < CFG_MAX_TXQ_NUM - 1; ++j) { + pos += kalSnprintf(pos, end - pos, "%d:", + glue->ai4TxPendingFrameNumPerQueue[i][j]); + } + pos += kalSnprintf(pos, end - pos, "%d]", + glue->ai4TxPendingFrameNumPerQueue[i][j]); + } + pos++; + head3 = pos; + for (i = 0; i < NUM_OF_TX_RING; ++i) { + pos += kalSnprintf(pos, end - pos, "[%u]", + hif->TxRing[i].u4UsedCnt); + } + pos++; + head4 = pos; + for (i = 0; i < BSS_DEFAULT_NUM; ++i) { + ndev = wlanGetNetDev(glue, i); + if (ndev) { + pos += kalSnprintf(pos, end - pos, + "[%llu:%llu:%llu:%llu]", + (unsigned long long) ndev->stats.tx_dropped, + (unsigned long long) + atomic_long_read(&ndev->tx_dropped), + (unsigned long long) ndev->stats.rx_dropped, + (unsigned long long) + atomic_long_read(&ndev->rx_dropped)); + } + } + +#define TEMP_LOG_TEMPLATE \ + "<%dms> Tput: %llu(%llu.%03llumbps) %s Pending:%d/%d %s Used:" \ + "%u/%d/%d %s LQ[%llu:%llu:%llu] lv:%u th:%u fg:0x%lx\n" + DBGLOG(SW4, INFO, TEMP_LOG_TEMPLATE, + period, (unsigned long long) perf->ulThroughput, + (unsigned long long) (perf->ulThroughput >> 20), + (unsigned long long) ((perf->ulThroughput >> 10) & BITS(0, 9)), + head1, GLUE_GET_REF_CNT(glue->i4TxPendingFrameNum), + prAdapter->rWifiVar.u4NetifStopTh, head2, + hif->rTokenInfo.u4UsedCnt, HIF_TX_MSDU_TOKEN_NUM, + TX_RING_SIZE, head3, + (unsigned long long) lq->u8TxTotalCount, + (unsigned long long) lq->u8RxTotalCount, + (unsigned long long) lq->u8DiffIdleSlotCount, + perf->u4CurrPerfLevel, + prAdapter->rWifiVar.u4BoostCpuTh, + perf->ulPerfMonFlag); +#undef TEMP_LOG_TEMPLATE +#define TEMP_LOG_TEMPLATE \ + "ndevdrp:%s drv[RM,RI,RT,RM,RW,RA,RB,DT,NS,IB,HS,LS,DD,ME,BD,NI," \ + "DR,TE,CE,DN]:%lu,%lu,%lu,%lu,%lu,%lu,%lu,%lu,%lu,%lu,%lu,%lu,%lu," \ + "%lu,%lu,%lu,%lu,%lu,%lu,%lu\n" + DBGLOG(SW4, INFO, TEMP_LOG_TEMPLATE, + head4, + RX_GET_CNT(&prAdapter->rRxCtrl, RX_MPDU_TOTAL_COUNT), + RX_GET_CNT(&prAdapter->rRxCtrl, RX_DATA_INDICATION_COUNT), + RX_GET_CNT(&prAdapter->rRxCtrl, RX_DATA_REORDER_TOTAL_COUNT), + RX_GET_CNT(&prAdapter->rRxCtrl, RX_DATA_REORDER_MISS_COUNT), + RX_GET_CNT(&prAdapter->rRxCtrl, RX_DATA_REORDER_WITHIN_COUNT), + RX_GET_CNT(&prAdapter->rRxCtrl, RX_DATA_REORDER_AHEAD_COUNT), + RX_GET_CNT(&prAdapter->rRxCtrl, RX_DATA_REORDER_BEHIND_COUNT), + RX_GET_CNT(&prAdapter->rRxCtrl, RX_DROP_TOTAL_COUNT), + RX_GET_CNT(&prAdapter->rRxCtrl, RX_NO_STA_DROP_COUNT), + RX_GET_CNT(&prAdapter->rRxCtrl, RX_INACTIVE_BSS_DROP_COUNT), + RX_GET_CNT(&prAdapter->rRxCtrl, RX_HS20_DROP_COUNT), + RX_GET_CNT(&prAdapter->rRxCtrl, RX_LESS_SW_RFB_DROP_COUNT), + RX_GET_CNT(&prAdapter->rRxCtrl, RX_DUPICATE_DROP_COUNT), + RX_GET_CNT(&prAdapter->rRxCtrl, RX_MIC_ERROR_DROP_COUNT), + RX_GET_CNT(&prAdapter->rRxCtrl, RX_BAR_DROP_COUNT), + RX_GET_CNT(&prAdapter->rRxCtrl, RX_NO_INTEREST_DROP_COUNT), + RX_GET_CNT(&prAdapter->rRxCtrl, RX_REORDER_BEHIND_DROP_COUNT), + RX_GET_CNT(&prAdapter->rRxCtrl, RX_TYPE_ERR_DROP_COUNT), + RX_GET_CNT(&prAdapter->rRxCtrl, RX_CLASS_ERR_DROP_COUNT), + RX_GET_CNT(&prAdapter->rRxCtrl, RX_DST_NULL_DROP_COUNT)); +#undef TEMP_LOG_TEMPLATE + + kalTraceEvent("Tput: %llu.%03llumbps", + (unsigned long long) (perf->ulThroughput >> 20), + (unsigned long long) ((perf->ulThroughput >> 10) & BITS(0, 9))); + + kalMemFree(buf, VIR_MEM_TYPE, slen); + return WLAN_STATUS_SUCCESS; +fail: + return WLAN_STATUS_FAILURE; +} + +void kalPerMonHandler(IN struct ADAPTER *prAdapter, + unsigned long ulParam) +{ + /*Calculate current throughput*/ + struct PERF_MONITOR *prPerMonitor; + uint32_t u4Idx = 0; + uint8_t i = 0; + bool keep_alive = FALSE; + struct net_device *prDevHandler = NULL; + struct GLUE_INFO *prGlueInfo = prAdapter->prGlueInfo; +#if CFG_SUPPORT_PERF_IND || CFG_SUPPORT_DATA_STALL + struct WIFI_VAR *prWifiVar = &prAdapter->rWifiVar; +#endif + + if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) + return; + + prPerMonitor = &prAdapter->rPerMonitor; + DBGLOG(SW4, TRACE, "enter kalPerMonHandler\n"); + +#if (CFG_SUPPORT_PERF_IND == 1) + if (prWifiVar->fgPerfIndicatorEn) + kalSetPerfReport(prAdapter); + + kalPerfIndReset(prAdapter); +#endif + for (i = 0; i < BSS_DEFAULT_NUM; i++) { + struct BSS_INFO *prBssInfo; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, i); + prDevHandler = wlanGetNetDev(prGlueInfo, i); + if (IS_BSS_ALIVE(prAdapter, prBssInfo) && prDevHandler) { + keep_alive |= netif_carrier_ok(prDevHandler); + } + } + +#if CFG_SUPPORT_DATA_STALL + /* test mode event */ + if (prWifiVar->u4ReportEventInterval == 0) + KAL_REPORT_ERROR_EVENT(prAdapter, + EVENT_TEST_MODE, 0, 0, FALSE); +#endif + prPerMonitor->u4TarPerfLevel = PERF_MON_TP_MAX_THRESHOLD; + for (u4Idx = 0; u4Idx < PERF_MON_TP_MAX_THRESHOLD; u4Idx++) { + if ((prPerMonitor->ulThroughput >> 20) < + prAdapter->rWifiVar.u4PerfMonTpTh[u4Idx]) { + prPerMonitor->u4TarPerfLevel = u4Idx; + break; + } + } + + if (!wlan_perf_monitor_force_enable && + (wlan_fb_power_down || + prGlueInfo->fgIsInSuspendMode || + !keep_alive)) + kalPerMonStop(prGlueInfo); + else { + if (kalCheckTputLoad(prAdapter, + prPerMonitor->u4CurrPerfLevel, + prPerMonitor->u4TarPerfLevel, + GLUE_GET_REF_CNT(prGlueInfo->i4TxPendingFrameNum), + GLUE_GET_REF_CNT(prPerMonitor->u4UsedCnt))) { + + DBGLOG(SW4, INFO, + "PerfMon overloading total:%3lu.%03lu mbps lv:%u th:%u fg:0x%lx Pending[%d], Used[%d]\n", + (unsigned long) (prPerMonitor->ulThroughput >> 20), + (unsigned long) ((prPerMonitor->ulThroughput >> 10) + & BITS(0, 9)), + prPerMonitor->u4TarPerfLevel, + prAdapter->rWifiVar.u4BoostCpuTh, + prPerMonitor->ulPerfMonFlag, + GLUE_GET_REF_CNT(prGlueInfo->i4TxPendingFrameNum), + GLUE_GET_REF_CNT(prPerMonitor->u4UsedCnt)); + + /* boost current level due to overloading */ + kalBoostCpu(prAdapter, + prPerMonitor->u4TarPerfLevel, + prPerMonitor->u4TarPerfLevel); + } else if ((prPerMonitor->u4TarPerfLevel != + prPerMonitor->u4CurrPerfLevel) && + (prAdapter->rWifiVar.u4BoostCpuTh < + PERF_MON_TP_MAX_THRESHOLD)) { + + DBGLOG(SW4, INFO, + "PerfMon total:%3lu.%03lu mbps lv:%u th:%u fg:0x%lx\n", + (unsigned long) (prPerMonitor->ulThroughput >> 20), + (unsigned long) ((prPerMonitor->ulThroughput >> 10) + & BITS(0, 9)), + prPerMonitor->u4TarPerfLevel, + prAdapter->rWifiVar.u4BoostCpuTh, + prPerMonitor->ulPerfMonFlag); + + kalBoostCpu(prAdapter, prPerMonitor->u4TarPerfLevel, + prAdapter->rWifiVar.u4BoostCpuTh); + } + + prPerMonitor->u4UpdatePeriod = + prAdapter->rWifiVar.u4PerfMonUpdatePeriod; + + cnmTimerStartTimer(prGlueInfo->prAdapter, + &prPerMonitor->rPerfMonTimer, + prPerMonitor->u4UpdatePeriod); + + } + prPerMonitor->u4CurrPerfLevel = + prPerMonitor->u4TarPerfLevel; + +#ifdef CFG_SUPPORT_LINK_QUALITY_MONITOR + prAdapter->u4LinkQualityCounter++; + if ((prAdapter->u4LinkQualityCounter % + CFG_LINK_QUALITY_MONITOR_UPDATE_FREQUENCY) == 0) { + prAdapter->u4LinkQualityCounter = 0; + if (prGlueInfo->fgIsInSuspendMode) + DBGLOG(SW4, TRACE, + "Skip wlanLinkQualityMonitor due to in suspend mode\n"); + else + wlanLinkQualityMonitor(prGlueInfo, FALSE); + } +#endif /* CFG_SUPPORT_LINK_QUALITY_MONITOR */ + + /* check tx hang */ + prAdapter->u4HifChkFlag |= HIF_CHK_TX_HANG; + kalSetHifDbgEvent(prAdapter->prGlueInfo); + + DBGLOG(SW4, TRACE, "exit kalPerMonHandler\n"); +} + +uint32_t kalPerMonGetInfo(IN struct ADAPTER *prAdapter, + IN uint8_t *pucBuf, IN uint32_t u4Max) +{ + struct PERF_MONITOR *prPerMonitor; + uint32_t u4Len = 0; + unsigned long ulWlanTxTpInBits, ulWlanRxTpInBits, + ulP2PTxTpInBits, ulP2PRxTpInBits; + + prPerMonitor = &prAdapter->rPerMonitor; + + ulWlanTxTpInBits = prPerMonitor->ulTxTp[0] << 3; + ulWlanRxTpInBits = prPerMonitor->ulRxTp[0] << 3; + ulP2PTxTpInBits = prPerMonitor->ulTxTp[1] << 3; + ulP2PRxTpInBits = prPerMonitor->ulRxTp[1] << 3; + + LOGBUF(pucBuf, u4Max, u4Len, + "\nWi-Fi Throughput (update period %ums):\n", + prPerMonitor->u4UpdatePeriod); + + LOGBUF(pucBuf, u4Max, u4Len, + "wlan Tx: %3lu.%03lu mbps, Rx %3lu.%03lu mbps\n", + (ulWlanTxTpInBits >> 20), + ((ulWlanTxTpInBits >> 10) & BITS(0, 9)), + (ulWlanRxTpInBits >> 20), + ((ulWlanRxTpInBits >> 10) & BITS(0, 9))); + + LOGBUF(pucBuf, u4Max, u4Len, + "p2p Tx: %3lu.%03lu mbps, Rx %3lu.%03lu mbps\n", + (ulP2PTxTpInBits >> 20), ((ulP2PTxTpInBits >> 10) & BITS(0, + 9)), + (ulP2PRxTpInBits >> 20), ((ulP2PRxTpInBits >> 10) & BITS(0, + 9))); + + LOGBUF(pucBuf, u4Max, u4Len, "Total: %3lu.%03lu mbps\n", + (prPerMonitor->ulThroughput >> 20), + ((prPerMonitor->ulThroughput >> 10) & BITS(0, 9))); + + LOGBUF(pucBuf, u4Max, u4Len, + "Performance level: %u threshold: %u flag: 0x%lx\n", + prPerMonitor->u4CurrPerfLevel, + prAdapter->rWifiVar.u4BoostCpuTh, + prPerMonitor->ulPerfMonFlag); + + return u4Len; +} + +int32_t __weak kalBoostCpu(IN struct ADAPTER *prAdapter, + IN uint32_t u4TarPerfLevel, IN uint32_t u4BoostCpuTh) +{ + DBGLOG(SW4, INFO, "enter kalBoostCpu\n"); + return 0; +} + +uint32_t __weak kalGetCpuBoostThreshold(void) +{ + DBGLOG(SW4, WARN, "enter kalGetCpuBoostThreshold\n"); + /* 1, stands for 20Mbps */ + return 1; +} + +int32_t __weak kalSetCpuNumFreq(uint32_t u4CoreNum, + uint32_t u4Freq) +{ + DBGLOG(SW4, INFO, + "enter weak kalSetCpuNumFreq, u4CoreNum:%d, urFreq:%d\n", + u4CoreNum, u4Freq); + return 0; +} + +int32_t __weak kalGetFwFlavor(uint8_t *flavor) +{ + DBGLOG(SW4, INFO, "NO firmware flavor build.\n"); + return 0; +} + +int32_t __weak kalGetConnsysVerId(void) +{ + DBGLOG(SW4, WARN, "NO CONNSYS version ID.\n"); + return 0; +} + +void __weak kalSetEmiMpuProtection(phys_addr_t emiPhyBase, bool enable) +{ + DBGLOG(SW4, WARN, "EMI MPU function is not defined\n"); +} + +void __weak kalSetDrvEmiMpuProtection(phys_addr_t emiPhyBase, uint32_t offset, + uint32_t size) +{ + DBGLOG(SW4, WARN, "DRV EMI MPU function is not defined\n"); +} + +int32_t __weak kalCheckTputLoad(IN struct ADAPTER *prAdapter, + IN uint32_t u4CurrPerfLevel, + IN uint32_t u4TarPerfLevel, + IN int32_t i4Pending, + IN uint32_t u4Used) +{ + DBGLOG(SW4, TRACE, "enter kalCheckTputLoad\n"); + return FALSE; +} + +/* mimic store_rps_map as net-sysfs.c does */ +int wlan_set_rps_map(struct netdev_rx_queue *queue, unsigned long rps_value) +{ +#if KERNEL_VERSION(4, 14, 0) <= CFG80211_VERSION_CODE + struct rps_map *old_map, *map; + cpumask_var_t mask; + int cpu, i; + static DEFINE_MUTEX(rps_map_mutex); + + if (!alloc_cpumask_var(&mask, GFP_KERNEL)) + return -ENOMEM; + + *cpumask_bits(mask) = rps_value; + map = kzalloc(max_t(unsigned int, + RPS_MAP_SIZE(cpumask_weight(mask)), L1_CACHE_BYTES), + GFP_KERNEL); + if (!map) { + free_cpumask_var(mask); + return -ENOMEM; + } + + i = 0; + for_each_cpu_and(cpu, mask, cpu_online_mask) + map->cpus[i++] = cpu; + + if (i) { + map->len = i; + } else { + kfree(map); + map = NULL; + } + + mutex_lock(&rps_map_mutex); + old_map = rcu_dereference_protected(queue->rps_map, + mutex_is_locked(&rps_map_mutex)); + rcu_assign_pointer(queue->rps_map, map); + if (map) +#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE + static_branch_inc(&rps_needed); +#else + static_key_slow_inc(&rps_needed); +#endif + if (old_map) +#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE + static_branch_dec(&rps_needed); +#else + static_key_slow_dec(&rps_needed); +#endif + mutex_unlock(&rps_map_mutex); + + if (old_map) + kfree_rcu(old_map, rcu); + free_cpumask_var(mask); + + return 0; +#else + return 0; +#endif +} + +void kalSetRpsMap(IN struct GLUE_INFO *glue, IN unsigned long value) +{ + int32_t i = 0, j = 0; + struct net_device *dev = NULL; + + for (i = 0; i < BSS_DEFAULT_NUM; i++) { + dev = wlanGetNetDev(glue, i); + if (dev) { + for (j = 0; j < dev->real_num_rx_queues; ++j) + wlan_set_rps_map(&dev->_rx[j], value); + } + } +} + +int32_t kalPerMonSetForceEnableFlag(uint8_t uFlag) +{ + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *) + wlan_fb_notifier_priv_data; + + wlan_perf_monitor_force_enable = uFlag == 0 ? FALSE : TRUE; + DBGLOG(SW4, INFO, + "uFlag:%d, wlan_perf_monitor_ctrl_flag:%d\n", uFlag, + wlan_perf_monitor_force_enable); + + if (wlan_perf_monitor_force_enable && prGlueInfo + && !kalIsHalted()) + kalPerMonEnable(prGlueInfo); + + return 0; +} + +static int wlan_fb_notifier_callback(struct notifier_block + *self, unsigned long event, void *data) +{ + struct fb_event *evdata = data; + int32_t blank = 0; + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *) + wlan_fb_notifier_priv_data; + + /* If we aren't interested in this event, skip it immediately ... */ + if ((event != FB_EVENT_BLANK) || !prGlueInfo) + return 0; + + if (kalHaltTryLock()) + return 0; + + if (kalIsHalted()) { + kalHaltUnlock(); + return 0; + } + + blank = *(int32_t *)evdata->data; + + switch (blank) { + case FB_BLANK_UNBLANK: + kalPerMonEnable(prGlueInfo); + wlan_fb_power_down = FALSE; + break; + case FB_BLANK_POWERDOWN: + wlan_fb_power_down = TRUE; + if (!wlan_perf_monitor_force_enable) + kalPerMonDisable(prGlueInfo); + break; + default: + break; + } + + kalHaltUnlock(); + return 0; +} + +int32_t kalFbNotifierReg(IN struct GLUE_INFO *prGlueInfo) +{ + int32_t i4Ret; + + wlan_fb_notifier_priv_data = prGlueInfo; + wlan_fb_notifier.notifier_call = wlan_fb_notifier_callback; + + i4Ret = fb_register_client(&wlan_fb_notifier); + if (i4Ret) + DBGLOG(SW4, WARN, "Register wlan_fb_notifier failed:%d\n", + i4Ret); + else + DBGLOG(SW4, TRACE, "Register wlan_fb_notifier succeed\n"); + return i4Ret; +} + +void kalFbNotifierUnReg(void) +{ + fb_unregister_client(&wlan_fb_notifier); + wlan_fb_notifier_priv_data = NULL; +} + +#if CFG_SUPPORT_DFS +void kalIndicateChannelSwitch(IN struct GLUE_INFO *prGlueInfo, + IN enum ENUM_CHNL_EXT eSco, + IN uint8_t ucChannelNum) +{ + struct cfg80211_chan_def chandef; + struct ieee80211_channel *prChannel = NULL; + enum nl80211_channel_type rChannelType; + + if (ucChannelNum <= 14) { + prChannel = + ieee80211_get_channel(priv_to_wiphy(prGlueInfo), + ieee80211_channel_to_frequency(ucChannelNum, + KAL_BAND_2GHZ)); + } else { + prChannel = + ieee80211_get_channel(priv_to_wiphy(prGlueInfo), + ieee80211_channel_to_frequency(ucChannelNum, + KAL_BAND_5GHZ)); + } + + if (!prChannel) { + DBGLOG(REQ, ERROR, "ieee80211_get_channel fail!\n"); + return; + } + + switch (eSco) { + case CHNL_EXT_SCN: + rChannelType = NL80211_CHAN_NO_HT; + break; + + case CHNL_EXT_SCA: + rChannelType = NL80211_CHAN_HT40MINUS; + break; + + case CHNL_EXT_SCB: + rChannelType = NL80211_CHAN_HT40PLUS; + break; + + case CHNL_EXT_RES: + default: + rChannelType = NL80211_CHAN_HT20; + break; + } + + DBGLOG(REQ, STATE, "DFS channel switch to %d\n", ucChannelNum); + + cfg80211_chandef_create(&chandef, prChannel, rChannelType); + cfg80211_ch_switch_notify(prGlueInfo->prDevHandler, &chandef); +} +#endif + +void kalInitDevWakeup(struct ADAPTER *prAdapter, struct device *prDev) +{ + /* + * The remote wakeup function will be disabled after + * first time resume, we need to call device_init_wakeup() + * to notify usbcore that we support wakeup function, + * so usbcore will re-enable our remote wakeup function + * before entering suspend. + */ + if (prAdapter->rWifiVar.ucWow) + device_init_wakeup(prDev, TRUE); +} + +u_int8_t kalIsOuiMask(const uint8_t pucMacAddrMask[MAC_ADDR_LEN]) +{ + return (pucMacAddrMask[0] == 0xFF && + pucMacAddrMask[1] == 0xFF && + pucMacAddrMask[2] == 0xFF); +} + +u_int8_t kalIsValidMacAddr(const uint8_t *addr) +{ + return (addr != NULL) && is_valid_ether_addr(addr); +} + +#if (KERNEL_VERSION(3, 19, 0) <= CFG80211_VERSION_CODE) +u_int8_t kalParseRandomMac(const struct net_device *ndev, + uint8_t *pucMacAddr, uint8_t *pucMacAddrMask, + uint8_t *pucRandomMac) +{ + struct NETDEV_PRIVATE_GLUE_INFO *prNetDevPrivate = NULL; + struct ADAPTER *prAdapter = NULL; + uint8_t ucBssIndex; + struct BSS_INFO *prBssInfo; + uint8_t ucMacAddr[MAC_ADDR_LEN]; + + if (!ndev) { + log_dbg(SCN, ERROR, "Invalid net device\n"); + return FALSE; + } + + prNetDevPrivate = + (struct NETDEV_PRIVATE_GLUE_INFO *) netdev_priv(ndev); + + if (!prNetDevPrivate || !(prNetDevPrivate->prGlueInfo) + || !(prNetDevPrivate->prGlueInfo->prAdapter)) { + log_dbg(SCN, ERROR, "Invalid private param\n"); + return FALSE; + } + + prAdapter = prNetDevPrivate->prGlueInfo->prAdapter; + ucBssIndex = prNetDevPrivate->ucBssIdx; + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex); + + if (!prBssInfo) { + log_dbg(SCN, WARN, "Invalid bss info (ind=%u)\n", ucBssIndex); + return FALSE; + } + + if (pucMacAddr) + COPY_MAC_ADDR(ucMacAddr, pucMacAddr); + else + eth_zero_addr(ucMacAddr); + + /* Randomize all 6-bytes MAC. + * Not to keep first 3-bytes MAC OUI to be constant. + */ + get_random_mask_addr(pucRandomMac, ucMacAddr, pucMacAddrMask); + + return TRUE; +} + +u_int8_t kalScanParseRandomMac(const struct net_device *ndev, + const struct cfg80211_scan_request *request, uint8_t *pucRandomMac) +{ + uint8_t ucMacAddr[MAC_ADDR_LEN]; + uint8_t ucMacAddrMask[MAC_ADDR_LEN]; + + ASSERT(request); + ASSERT(pucRandomMac); + + if (!(request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR)) { + log_dbg(SCN, TRACE, "Scan random mac is not set\n"); + return FALSE; + } +#if KERNEL_VERSION(4, 10, 0) <= CFG80211_VERSION_CODE + { + if (kalIsValidMacAddr(request->bssid)) { + COPY_MAC_ADDR(pucRandomMac, request->bssid); + log_dbg(SCN, INFO, "random mac=" MACSTR "\n", + MAC2STR(pucRandomMac)); + return TRUE; + } + } +#endif + COPY_MAC_ADDR(ucMacAddr, request->mac_addr); + COPY_MAC_ADDR(ucMacAddrMask, request->mac_addr_mask); + + return kalParseRandomMac(ndev, ucMacAddr, ucMacAddrMask, pucRandomMac); +} + +u_int8_t kalSchedScanParseRandomMac(const struct net_device *ndev, + const struct cfg80211_sched_scan_request *request, + uint8_t *pucRandomMac, uint8_t *pucRandomMacMask) +{ + uint8_t ucMacAddr[MAC_ADDR_LEN]; + + ASSERT(request); + ASSERT(pucRandomMac); + ASSERT(pucRandomMacMask); + + if (!(request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR)) { + log_dbg(SCN, TRACE, "Scan random mac is not set\n"); + return FALSE; + } + COPY_MAC_ADDR(ucMacAddr, request->mac_addr); + COPY_MAC_ADDR(pucRandomMacMask, request->mac_addr_mask); + + return kalParseRandomMac(ndev, ucMacAddr, + pucRandomMacMask, pucRandomMac); +} +#else /* if (KERNEL_VERSION(3, 19, 0) <= CFG80211_VERSION_CODE) */ +u_int8_t kalScanParseRandomMac(const struct net_device *ndev, + const struct cfg80211_scan_request *request, uint8_t *pucRandomMac) +{ + return FALSE; +} + +u_int8_t kalSchedScanParseRandomMac(const struct net_device *ndev, + const struct cfg80211_sched_scan_request *request, + uint8_t *pucRandomMac, uint8_t *pucRandomMacMask) +{ + return FALSE; +} +#endif + +void kalScanReqLog(struct cfg80211_scan_request *request) +{ + char *strbuf = NULL, *pos = NULL, *end = NULL; + uint32_t slen = 0; + int i, snum, cnum; + + snum = min_t(int, request->n_ssids, SCN_SSID_MAX_NUM + 1); + cnum = min_t(u32, request->n_channels, MAXIMUM_OPERATION_CHANNEL_LIST); + + for (i = 0; i < snum; ++i) { + if (request->ssids[i].ssid_len > 0) + slen += request->ssids[i].ssid_len + 1; + } + + /* The length should be added 11 + 15 + 8 + 1 for the format + * "n_ssids=%d:" and " n_channels=%u:" and 2 " ..." and null byte. + */ + slen += 35 + 4 * cnum; + pos = strbuf = kalMemAlloc(slen, VIR_MEM_TYPE); + if (strbuf == NULL) { + scanlog_dbg(LOG_SCAN_REQ_K2D, INFO, "Can't allocate memory\n"); + return; + } + end = strbuf + slen; + + pos += kalSnprintf(pos, end - pos, + "n_ssids=%d:", request->n_ssids % 100); + for (i = 0; i < snum; ++i) { + uint8_t len = request->ssids[i].ssid_len; + char ssid[PARAM_MAX_LEN_SSID + 1] = {0}; + + if (len == 0) + continue; + kalStrnCpy(ssid, request->ssids[i].ssid, sizeof(ssid) - 1); + ssid[sizeof(ssid) - 1] = '\0'; + pos += kalSnprintf(pos, end - pos, " %s", ssid); + } + if (snum < request->n_ssids) + pos += kalSnprintf(pos, end - pos, "%s", " ..."); + + pos += kalSnprintf(pos, end - pos, " n_channels=%u:", + request->n_channels % 100); + for (i = 0; i < cnum; ++i) { + pos += kalSnprintf(pos, end - pos, " %u", + request->channels[i]->hw_value % 1000); + } + if (cnum < request->n_channels) + pos += kalSnprintf(pos, end - pos, "%s", " ..."); + +#if (KERNEL_VERSION(3, 19, 0) <= CFG80211_VERSION_CODE) + scanlog_dbg(LOG_SCAN_REQ_K2D, INFO, "Scan flags=0x%x [mac]addr=" + MACSTR " mask=" MACSTR " %s\n", + request->flags, + MAC2STR(request->mac_addr), + MAC2STR(request->mac_addr_mask), strbuf); +#else + scanlog_dbg(LOG_SCAN_REQ_K2D, INFO, "Scan flags=0x%x %s\n", + request->flags, strbuf); +#endif + + kalMemFree(strbuf, VIR_MEM_TYPE, slen); +} + +void kalScanResultLog(struct ADAPTER *prAdapter, struct ieee80211_mgmt *mgmt) +{ + KAL_SPIN_LOCK_DECLARATION(); + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BSSLIST_CFG); + scanLogCacheAddBSS( + &(prAdapter->rWifiVar.rScanInfo.rScanLogCache.rBSSListCFG), + prAdapter->rWifiVar.rScanInfo.rScanLogCache.arBSSListBufCFG, + LOG_SCAN_RESULT_D2K, + mgmt->bssid, + mgmt->seq_ctrl); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BSSLIST_CFG); +} + +void kalScanLogCacheFlushBSS(struct ADAPTER *prAdapter, + const uint16_t logBufLen) +{ + KAL_SPIN_LOCK_DECLARATION(); + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BSSLIST_CFG); + scanLogCacheFlushBSS( + &(prAdapter->rWifiVar.rScanInfo.rScanLogCache.rBSSListCFG), + LOG_SCAN_DONE_D2K); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BSSLIST_CFG); +} + + +u_int8_t +kalChannelScoSwitch(IN enum nl80211_channel_type channel_type, + IN enum ENUM_CHNL_EXT *prChnlSco) +{ + u_int8_t fgIsValid = FALSE; + + do { + if (prChnlSco) { + switch (channel_type) { + case NL80211_CHAN_NO_HT: + *prChnlSco = CHNL_EXT_SCN; + break; + case NL80211_CHAN_HT20: + *prChnlSco = CHNL_EXT_SCN; + break; + case NL80211_CHAN_HT40MINUS: + *prChnlSco = CHNL_EXT_SCA; + break; + case NL80211_CHAN_HT40PLUS: + *prChnlSco = CHNL_EXT_SCB; + break; + default: + ASSERT(FALSE); + *prChnlSco = CHNL_EXT_SCN; + break; + } + } + fgIsValid = TRUE; + } while (FALSE); + + return fgIsValid; +} + +u_int8_t +kalChannelFormatSwitch(IN struct cfg80211_chan_def *channel_def, + IN struct ieee80211_channel *channel, + IN struct RF_CHANNEL_INFO *prRfChnlInfo) +{ + u_int8_t fgIsValid = FALSE; + + do { + if (channel == NULL) + break; + + DBGLOG(P2P, INFO, "switch channel band: %d, freq: %d\n", + channel->band, channel->center_freq); + + if (prRfChnlInfo) { + prRfChnlInfo->ucChannelNum = + nicFreq2ChannelNum(channel->center_freq * 1000); + + switch (channel->band) { + case KAL_BAND_2GHZ: + prRfChnlInfo->eBand = BAND_2G4; + break; + case KAL_BAND_5GHZ: + prRfChnlInfo->eBand = BAND_5G; + break; + default: + prRfChnlInfo->eBand = BAND_2G4; + break; + } + } + + if (channel_def && prRfChnlInfo) { + switch (channel_def->width) { + case NL80211_CHAN_WIDTH_20_NOHT: + case NL80211_CHAN_WIDTH_20: + prRfChnlInfo->ucChnlBw = MAX_BW_20MHZ; + break; + case NL80211_CHAN_WIDTH_40: + prRfChnlInfo->ucChnlBw = MAX_BW_40MHZ; + break; + case NL80211_CHAN_WIDTH_80: + prRfChnlInfo->ucChnlBw = MAX_BW_80MHZ; + break; + case NL80211_CHAN_WIDTH_80P80: + prRfChnlInfo->ucChnlBw = MAX_BW_80_80_MHZ; + break; + case NL80211_CHAN_WIDTH_160: + prRfChnlInfo->ucChnlBw = MAX_BW_160MHZ; + break; + default: + prRfChnlInfo->ucChnlBw = MAX_BW_20MHZ; + break; + } + prRfChnlInfo->u2PriChnlFreq = channel->center_freq; + prRfChnlInfo->u4CenterFreq1 = channel_def->center_freq1; + prRfChnlInfo->u4CenterFreq2 = channel_def->center_freq2; + } + + fgIsValid = TRUE; + } while (FALSE); + + return fgIsValid; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Notify kernel to remove/unlink bss. + * + * \param[in] prGlueInfo Pointer of GLUE Data Structure + * \param[in] prBssDesc Pointer of BSS_DESC we want to remove + * + */ +/*----------------------------------------------------------------------------*/ +void kalRemoveBss(struct GLUE_INFO *prGlueInfo, + uint8_t aucBSSID[], + uint8_t ucChannelNum, + enum ENUM_BAND eBand) +{ + struct cfg80211_bss *bss = NULL; + struct ieee80211_channel *prChannel = NULL; + + if (ucChannelNum <= 14) { + prChannel = ieee80211_get_channel( + priv_to_wiphy(prGlueInfo), + ieee80211_channel_to_frequency( + ucChannelNum, + KAL_BAND_2GHZ) + ); + } else { + prChannel = ieee80211_get_channel( + priv_to_wiphy(prGlueInfo), + ieee80211_channel_to_frequency( + ucChannelNum, + KAL_BAND_5GHZ) + ); + } + +#if (KERNEL_VERSION(4, 1, 0) <= CFG80211_VERSION_CODE) + bss = cfg80211_get_bss(priv_to_wiphy(prGlueInfo), + prChannel, /* channel */ + aucBSSID, + NULL, /* ssid */ + 0, /* ssid length */ + IEEE80211_BSS_TYPE_ESS, + IEEE80211_PRIVACY_ANY); +#else + bss = cfg80211_get_bss(priv_to_wiphy(prGlueInfo), + prChannel, /* channel */ + aucBSSID, + NULL, /* ssid */ + 0, /* ssid length */ + WLAN_CAPABILITY_ESS, + WLAN_CAPABILITY_ESS); +#endif + + if (bss != NULL) { + cfg80211_unlink_bss(priv_to_wiphy(prGlueInfo), bss); + cfg80211_put_bss(priv_to_wiphy(prGlueInfo), bss); + } +} + +int kalMaskMemCmp(const void *cs, const void *ct, + const void *mask, size_t count) +{ + const uint8_t *su1, *su2, *su3; + int res = 0; + + for (su1 = cs, su2 = ct, su3 = mask; + count > 0; ++su1, ++su2, ++su3, count--) { + if (mask != NULL) + res = ((*su1)&(*su3)) - ((*su2)&(*su3)); + else + res = (*su1) - (*su2); + if (res != 0) + break; + } + return res; +} + +/* + * This func is mainly from bionic's strtok.c + */ +int8_t *strtok_r(int8_t *s, const int8_t *delim, int8_t **last) +{ + char *spanp; + int c, sc; + char *tok; + + + if (s == NULL) { + s = *last; + if (s == 0) + return NULL; + } +cont: + c = *s++; + for (spanp = (char *)delim; (sc = *spanp++) != 0;) { + if (c == sc) + goto cont; + } + + if (c == 0) { /* no non-delimiter characters */ + *last = NULL; + return NULL; + } + tok = s - 1; + + for (;;) { + c = *s++; + spanp = (char *)delim; + do { + sc = *spanp++; + if (sc == c) { + if (c == 0) + s = NULL; + else + s[-1] = 0; + *last = s; + return tok; + } + } while (sc != 0); + } +} + +int8_t atoi(uint8_t ch) +{ + if (ch >= 'a' && ch <= 'f') + return ch - 87; + else if (ch >= 'A' && ch <= 'F') + return ch - 55; + else if (ch >= '0' && ch <= '9') + return ch - 48; + + return 0; +} + +#if CFG_SUPPORT_WPA3 +int kalExternalAuthRequest(IN struct ADAPTER *prAdapter, + IN uint8_t uBssIndex) +{ + struct cfg80211_external_auth_params params; + struct AIS_FSM_INFO *prAisFsmInfo = NULL; + struct BSS_DESC *prBssDesc = NULL; + struct net_device *ndev = NULL; + struct GLUE_INFO *prGlueInfo = prAdapter->prGlueInfo; + + prAisFsmInfo = aisGetAisFsmInfo(prAdapter, uBssIndex); + if (!prAisFsmInfo) { + DBGLOG(SAA, WARN, + "SAE auth failed with NULL prAisFsmInfo\n"); + return WLAN_STATUS_INVALID_DATA; + } + + prBssDesc = prAisFsmInfo->prTargetBssDesc; + if (!prBssDesc) { + DBGLOG(SAA, WARN, + "SAE auth failed without prTargetBssDesc\n"); + return WLAN_STATUS_INVALID_DATA; + } + + ndev = wlanGetNetDev(prGlueInfo, uBssIndex); + params.action = NL80211_EXTERNAL_AUTH_START; + COPY_MAC_ADDR(params.bssid, prBssDesc->aucBSSID); + COPY_SSID(params.ssid.ssid, params.ssid.ssid_len, + prBssDesc->aucSSID, prBssDesc->ucSSIDLen); + params.key_mgmt_suite = RSN_AKM_SUITE_SAE; + DBGLOG(AIS, INFO, "[WPA3] "MACSTR" %s %d %d %02x-%02x-%02x-%02x", + MAC2STR(params.bssid), params.ssid.ssid, + params.ssid.ssid_len, params.action, + (uint8_t) (params.key_mgmt_suite & 0x000000FF), + (uint8_t) ((params.key_mgmt_suite >> 8) & 0x000000FF), + (uint8_t) ((params.key_mgmt_suite >> 16) & 0x000000FF), + (uint8_t) ((params.key_mgmt_suite >> 24) & 0x000000FF)); + return cfg80211_external_auth_request(ndev, ¶ms, GFP_KERNEL); +} +#endif + +const uint8_t *kalFindIeMatchMask(uint8_t eid, + const uint8_t *ies, int len, + const uint8_t *match, + int match_len, int match_offset, + const uint8_t *match_mask) +{ + /* match_offset can't be smaller than 2, unless match_len is + * zero, in which case match_offset must be zero as well. + */ + if (WARN_ON((match_len && match_offset < 2) || + (!match_len && match_offset))) + return NULL; + while (len >= 2 && len >= ies[1] + 2) { + if ((ies[0] == eid) && + (ies[1] + 2 >= match_offset + match_len) && + !kalMaskMemCmp(ies + match_offset, + match, match_mask, match_len)) + return ies; + len -= ies[1] + 2; + ies += ies[1] + 2; + } + return NULL; +} + +int _kalSnprintf(char *buf, size_t size, const char *fmt, ...) +{ + int retval; + va_list ap; + + va_start(ap, fmt); + retval = vsnprintf(buf, size, fmt, ap); + va_end(ap); + return (retval < 0)?(0):(retval); +} + +int _kalSprintf(char *buf, const char *fmt, ...) +{ + int retval; + va_list ap; + + va_start(ap, fmt); + retval = vsprintf(buf, fmt, ap); + va_end(ap); + return (retval < 0)?(0):(retval); +} +#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE +void kal_do_gettimeofday(struct timeval *tv) +{ + struct timespec64 now; + + ktime_get_real_ts64(&now); + tv->tv_sec = now.tv_sec; + tv->tv_usec = now.tv_nsec / NSEC_PER_USEC; +} +#endif + +static void kalDumpHifStats(IN struct ADAPTER *prAdapter) +{ + struct HIF_STATS *prHifStats; + struct GL_HIF_INFO *prHifInfo; + struct RTMP_TX_RING *prTxRing; + struct RTMP_RX_RING *prRxRing; + struct RX_CTRL *prRxCtrl; + uint8_t i = 0; + uint32_t u4BufferSize = 512, pos = 0; + char *buf; + + if (!prAdapter) + return; + + prHifStats = &prAdapter->rHifStats; + prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + prRxCtrl = &prAdapter->rRxCtrl; + + if (time_before(jiffies, prHifStats->ulUpdatePeriod)) + return; + + buf = (char *) kalMemAlloc(u4BufferSize, VIR_MEM_TYPE); + if (!buf) + return; + kalMemZero(buf, u4BufferSize); + + prHifStats->ulUpdatePeriod = jiffies + + prAdapter->rWifiVar.u4PerfMonUpdatePeriod * HZ / 1000; + + pos += kalSnprintf(buf + pos, u4BufferSize - pos, + "I[%u %u]", + GLUE_GET_REF_CNT(prHifStats->u4HwIsrCount), + GLUE_GET_REF_CNT(prHifStats->u4SwIsrCount)); + pos += kalSnprintf(buf + pos, u4BufferSize - pos, + " T[%u %u %u / %u %u %u %u]", + GLUE_GET_REF_CNT(prHifStats->u4CmdInCount), + GLUE_GET_REF_CNT(prHifStats->u4CmdTxCount), + GLUE_GET_REF_CNT(prHifStats->u4CmdTxdoneCount), + GLUE_GET_REF_CNT(prHifStats->u4DataInCount), + GLUE_GET_REF_CNT(prHifStats->u4DataTxCount), + GLUE_GET_REF_CNT(prHifStats->u4DataTxdoneCount), + GLUE_GET_REF_CNT(prHifStats->u4DataMsduRptCount)); + pos += kalSnprintf(buf + pos, u4BufferSize - pos, + " R[%u / %u]", + GLUE_GET_REF_CNT(prHifStats->u4DataRxCount), + GLUE_GET_REF_CNT(prHifStats->u4EventRxCount)); + for (i = 0; i < NUM_OF_TX_RING; ++i) { + prTxRing = &prHifInfo->TxRing[i]; + pos += kalSnprintf(buf + pos, u4BufferSize - pos, "%s%u%s", + (i == 0) ? " T_R[" : "", + prTxRing->u4UsedCnt, + (i == NUM_OF_TX_RING - 1) ? "] " : " "); + } + for (i = 0; i < NUM_OF_RX_RING; ++i) { + prRxRing = &prHifInfo->RxRing[i]; + pos += kalSnprintf(buf + pos, u4BufferSize - pos, "%s%u%s", + (i == 0) ? " R_R[" : "", + prRxRing->u4PendingCnt, + (i == NUM_OF_RX_RING - 1) ? "]" : " "); + } + pos += kalSnprintf(buf + pos, u4BufferSize - pos, + " Tok[%u/%u] Rfb[%u/%u]", + prHifInfo->rTokenInfo.u4UsedCnt, + HIF_TX_MSDU_TOKEN_NUM, + prRxCtrl->rFreeSwRfbList.u4NumElem, + CFG_RX_MAX_PKT_NUM); + DBGLOG(HAL, INFO, "%s\n", buf); + kalMemFree(buf, VIR_MEM_TYPE, u4BufferSize); +} + +uint32_t kalSetSuspendFlagToEMI(IN struct ADAPTER + *prAdapter, IN u_int8_t fgSuspend) +{ +#if CFG_MTK_ANDROID_EMI + uint32_t u4Offset = prAdapter->u4HostStatusEmiOffset + & WIFI_EMI_ADDR_MASK; + uint32_t suspendFlag = 0; + + if (!gConEmiPhyBase) { +#if (CFG_SUPPORT_CONNINFRA == 1) + conninfra_get_phy_addr( + (unsigned int *)&gConEmiPhyBase, + (unsigned int *)&gConEmiSize); +#endif + + if (!gConEmiPhyBase) { + DBGLOG(INIT, ERROR, + "[EMI_Suspend] gConEmiPhyBase invalid\n"); + return WLAN_STATUS_FAILURE; + } + } + suspendFlag = (fgSuspend == TRUE) ? 0x11111111 : 0x22222222; + + DBGLOG(INIT, TRACE, + "[EMI_Suspend] EmiPhyBase:0x%llx offset:0x%x set 0x%x", + (uint64_t)gConEmiPhyBase, u4Offset, suspendFlag); + + wf_ioremap_write((gConEmiPhyBase + u4Offset), suspendFlag); + +#endif /* CFG_MTK_ANDROID_EMI */ + return WLAN_STATUS_SUCCESS; +} + +#if KERNEL_VERSION(5, 4, 0) <= CFG80211_VERSION_CODE +MODULE_IMPORT_NS(VFS_internal_I_am_really_a_filesystem_and_am_NOT_a_driver); +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_p2p.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_p2p.c new file mode 100644 index 0000000000000000000000000000000000000000..d796993ac821a80db4b439ac4ad3a1f2697d674b --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_p2p.c @@ -0,0 +1,2252 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: @(#) gl_p2p.c@@ + */ + +/*! \file gl_p2p.c + * \brief Main routines of Linux driver interface for Wi-Fi Direct + * + * This file contains the main routines of Linux driver + * for MediaTek Inc. 802.11 Wireless LAN Adapters. + */ + + +/****************************************************************************** + * C O M P I L E R F L A G S + ****************************************************************************** + */ + +/****************************************************************************** + * E X T E R N A L R E F E R E N C E S + ****************************************************************************** + */ + +#include + +#include + + +#include "gl_os.h" +#include "debug.h" +#include "wlan_lib.h" +#include "gl_wext.h" + +/* #include */ +#include "gl_p2p_ioctl.h" + +#include "precomp.h" +#include "gl_vendor.h" +#include "gl_cfg80211.h" +#if CFG_MTK_MCIF_WIFI_SUPPORT +#include "mddp.h" +#endif +/****************************************************************************** + * C O N S T A N T S + ****************************************************************************** + */ +#define ARGV_MAX_NUM (4) + +/*For CFG80211 - wiphy parameters*/ +#define MAX_SCAN_LIST_NUM (1) +#define MAX_SCAN_IE_LEN (512) + +#if 0 +#define RUNNING_P2P_MODE 0 +#define RUNNING_AP_MODE 1 +#define RUNNING_DUAL_AP_MODE 2 +#endif +/****************************************************************************** + * D A T A T Y P E S + ****************************************************************************** + */ + +/****************************************************************************** + * P U B L I C D A T A + ****************************************************************************** + */ + + +/****************************************************************************** + * P R I V A T E D A T A + ****************************************************************************** + */ + +struct net_device *g_P2pPrDev; +struct wireless_dev *gprP2pWdev; +struct wireless_dev *gprP2pRoleWdev[KAL_P2P_NUM]; +struct net_device *gPrP2pDev[KAL_P2P_NUM]; +uint32_t g_u4DevIdx[KAL_P2P_NUM]; + +#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 +#if (CFG_ENABLE_UNIFY_WIPHY == 0) +static struct cfg80211_ops mtk_p2p_ops = { +#if (CFG_ENABLE_WIFI_DIRECT_CFG_80211 != 0) + /* Froyo */ + .add_virtual_intf = mtk_p2p_cfg80211_add_iface, + .change_virtual_intf = mtk_p2p_cfg80211_change_iface, /* 1 st */ + .del_virtual_intf = mtk_p2p_cfg80211_del_iface, + .change_bss = mtk_p2p_cfg80211_change_bss, + .scan = mtk_p2p_cfg80211_scan, +#if KERNEL_VERSION(4, 5, 0) <= CFG80211_VERSION_CODE + .abort_scan = mtk_p2p_cfg80211_abort_scan, +#endif + .remain_on_channel = mtk_p2p_cfg80211_remain_on_channel, + .cancel_remain_on_channel = mtk_p2p_cfg80211_cancel_remain_on_channel, + .mgmt_tx = mtk_p2p_cfg80211_mgmt_tx, + .mgmt_tx_cancel_wait = mtk_p2p_cfg80211_mgmt_tx_cancel_wait, + .connect = mtk_p2p_cfg80211_connect, + .disconnect = mtk_p2p_cfg80211_disconnect, + .deauth = mtk_p2p_cfg80211_deauth, + .disassoc = mtk_p2p_cfg80211_disassoc, + .start_ap = mtk_p2p_cfg80211_start_ap, + .change_beacon = mtk_p2p_cfg80211_change_beacon, + .stop_ap = mtk_p2p_cfg80211_stop_ap, + .set_wiphy_params = mtk_p2p_cfg80211_set_wiphy_params, + .del_station = mtk_p2p_cfg80211_del_station, + .set_bitrate_mask = mtk_p2p_cfg80211_set_bitrate_mask, + .mgmt_frame_register = mtk_p2p_cfg80211_mgmt_frame_register, + .get_station = mtk_p2p_cfg80211_get_station, + .add_key = mtk_p2p_cfg80211_add_key, + .get_key = mtk_p2p_cfg80211_get_key, + .del_key = mtk_p2p_cfg80211_del_key, + .set_default_key = mtk_p2p_cfg80211_set_default_key, + .set_default_mgmt_key = mtk_p2p_cfg80211_set_mgmt_key, + .join_ibss = mtk_p2p_cfg80211_join_ibss, + .leave_ibss = mtk_p2p_cfg80211_leave_ibss, + .set_tx_power = mtk_p2p_cfg80211_set_txpower, + .get_tx_power = mtk_p2p_cfg80211_get_txpower, + .set_power_mgmt = mtk_p2p_cfg80211_set_power_mgmt, +#if (CFG_SUPPORT_DFS_MASTER == 1) + .start_radar_detection = mtk_p2p_cfg80211_start_radar_detection, +#if KERNEL_VERSION(3, 13, 0) <= CFG80211_VERSION_CODE + .channel_switch = mtk_p2p_cfg80211_channel_switch, +#endif +#endif +#ifdef CONFIG_NL80211_TESTMODE + .testmode_cmd = mtk_p2p_cfg80211_testmode_cmd, +#endif +#endif +}; +#if KERNEL_VERSION(3, 18, 0) <= CFG80211_VERSION_CODE + +static const struct wiphy_vendor_command mtk_p2p_vendor_ops[] = { + { + { + .vendor_id = GOOGLE_OUI, + .subcmd = WIFI_SUBCMD_GET_CHANNEL_LIST + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV + | WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = mtk_cfg80211_vendor_get_channel_list + }, + { + { + .vendor_id = GOOGLE_OUI, + .subcmd = WIFI_SUBCMD_SET_COUNTRY_CODE + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV + | WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = mtk_cfg80211_vendor_set_country_code + }, +#if CFG_SUPPORT_P2P_PREFERRED_FREQ_LIST + /* P2P get preferred freq list */ + { + { + .vendor_id = OUI_QCA, + .subcmd = NL80211_VENDOR_SUBCMD_GET_PREFER_FREQ_LIST + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV + | WIPHY_VENDOR_CMD_NEED_NETDEV + | WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = mtk_cfg80211_vendor_get_preferred_freq_list + }, +#endif /* CFG_SUPPORT_P2P_PREFERRED_FREQ_LIST */ +#if CFG_AUTO_CHANNEL_SEL_SUPPORT + { + { + .vendor_id = OUI_QCA, + .subcmd = NL80211_VENDOR_SUBCMD_ACS + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV + | WIPHY_VENDOR_CMD_NEED_NETDEV + | WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = mtk_cfg80211_vendor_acs + }, +#endif + { + { + .vendor_id = OUI_QCA, + .subcmd = NL80211_VENDOR_SUBCMD_GET_FEATURES + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV + | WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = mtk_cfg80211_vendor_get_features + }, +}; + +static const struct nl80211_vendor_cmd_info mtk_p2p_vendor_events[] = { +#if CFG_AUTO_CHANNEL_SEL_SUPPORT + { + .vendor_id = OUI_QCA, + .subcmd = NL80211_VENDOR_SUBCMD_ACS + }, +#endif +}; + + +#endif + +/* There isn't a lot of sense in it, but you can transmit anything you like */ +static const struct ieee80211_txrx_stypes +mtk_cfg80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = { + [NL80211_IFTYPE_ADHOC] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ACTION >> 4) + }, + [NL80211_IFTYPE_STATION] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ACTION >> 4) + | BIT(IEEE80211_STYPE_PROBE_REQ >> 4) + }, + [NL80211_IFTYPE_AP] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_PROBE_REQ >> 4) + | BIT(IEEE80211_STYPE_ACTION >> 4) +#if CFG_SUPPORT_SOFTAP_WPA3 + | BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_DISASSOC >> 4) | + BIT(IEEE80211_STYPE_AUTH >> 4) | + BIT(IEEE80211_STYPE_DEAUTH >> 4) +#endif + }, + [NL80211_IFTYPE_AP_VLAN] = { + /* copy AP */ + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | + BIT(IEEE80211_STYPE_DISASSOC >> 4) | + BIT(IEEE80211_STYPE_AUTH >> 4) | + BIT(IEEE80211_STYPE_DEAUTH >> 4) | + BIT(IEEE80211_STYPE_ACTION >> 4) + }, + [NL80211_IFTYPE_P2P_CLIENT] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ACTION >> 4) + | BIT(IEEE80211_STYPE_PROBE_REQ >> 4) + }, + [NL80211_IFTYPE_P2P_GO] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_PROBE_REQ >> 4) + | BIT(IEEE80211_STYPE_ACTION >> 4) + } +}; + +#endif +#endif + +static const struct iw_priv_args rP2PIwPrivTable[] = { + { + .cmd = IOC_P2P_CFG_DEVICE, + .set_args = IW_PRIV_TYPE_BYTE + | (__u16) sizeof(struct iw_p2p_cfg_device_type), + .get_args = IW_PRIV_TYPE_NONE, + .name = "P2P_CFG_DEVICE"} + , + { + .cmd = IOC_P2P_START_STOP_DISCOVERY, + .set_args = IW_PRIV_TYPE_BYTE + | (__u16) sizeof(struct iw_p2p_req_device_type), + .get_args = IW_PRIV_TYPE_NONE, + .name = "P2P_DISCOVERY"} + , + { + .cmd = IOC_P2P_DISCOVERY_RESULTS, + .set_args = IW_PRIV_TYPE_NONE, + .get_args = IW_PRIV_TYPE_NONE, + .name = "P2P_RESULT"} + , + { + .cmd = IOC_P2P_WSC_BEACON_PROBE_RSP_IE, + .set_args = IW_PRIV_TYPE_BYTE + | (__u16) sizeof(struct iw_p2p_hostapd_param), + .get_args = IW_PRIV_TYPE_NONE, + .name = "P2P_WSC_IE"} + , + { + .cmd = IOC_P2P_CONNECT_DISCONNECT, + .set_args = IW_PRIV_TYPE_BYTE + | (__u16) sizeof(struct iw_p2p_connect_device), + .get_args = IW_PRIV_TYPE_NONE, + .name = "P2P_CONNECT"} + , + { + .cmd = IOC_P2P_PASSWORD_READY, + .set_args = IW_PRIV_TYPE_BYTE + | (__u16) sizeof(struct iw_p2p_password_ready), + .get_args = IW_PRIV_TYPE_NONE, + .name = "P2P_PASSWD_RDY"} + , + { + .cmd = IOC_P2P_GET_STRUCT, + .set_args = IW_PRIV_TYPE_NONE, + .get_args = 256, + .name = "P2P_GET_STRUCT"} + , + { + .cmd = IOC_P2P_SET_STRUCT, + .set_args = 256, + .get_args = IW_PRIV_TYPE_NONE, + .name = "P2P_SET_STRUCT"} + , + { + .cmd = IOC_P2P_GET_REQ_DEVICE_INFO, + .set_args = IW_PRIV_TYPE_NONE, + .get_args = IW_PRIV_TYPE_BYTE + | (__u16) sizeof(struct iw_p2p_device_req), + .name = "P2P_GET_REQDEV"} + , + { + /* SET STRUCT sub-ioctls commands */ + .cmd = PRIV_CMD_OID, + .set_args = 256, + .get_args = IW_PRIV_TYPE_NONE, + .name = "set_oid"} + , + { + /* GET STRUCT sub-ioctls commands */ + .cmd = PRIV_CMD_OID, + .set_args = IW_PRIV_TYPE_NONE, + .get_args = 256, + .name = "get_oid"} +}; + +#if 0 +const struct iw_handler_def mtk_p2p_wext_handler_def = { + .num_standard = (__u16) sizeof(rP2PIwStandardHandler) + / sizeof(iw_handler), +/* .num_private = (__u16)sizeof(rP2PIwPrivHandler)/sizeof(iw_handler), */ + .num_private_args = (__u16) sizeof(rP2PIwPrivTable) + / sizeof(struct iw_priv_args), + .standard = rP2PIwStandardHandler, +/* .private = rP2PIwPrivHandler, */ + .private_args = rP2PIwPrivTable, +#if CFG_SUPPORT_P2P_RSSI_QUERY + .get_wireless_stats = mtk_p2p_wext_get_wireless_stats, +#else + .get_wireless_stats = NULL, +#endif +}; +#endif + +#ifdef CONFIG_PM +static const struct wiphy_wowlan_support mtk_p2p_wowlan_support = { + .flags = WIPHY_WOWLAN_DISCONNECT | WIPHY_WOWLAN_ANY, +}; +#endif + +static const struct ieee80211_iface_limit mtk_p2p_sta_go_limits[] = { + { + .max = 3, + .types = BIT(NL80211_IFTYPE_STATION), + }, + + { + .max = 1, + .types = BIT(NL80211_IFTYPE_P2P_GO) + | BIT(NL80211_IFTYPE_P2P_CLIENT), + }, +}; + +#if (CFG_SUPPORT_DFS_MASTER == 1) +#if (KERNEL_VERSION(3, 17, 0) > CFG80211_VERSION_CODE) + +static const struct ieee80211_iface_limit mtk_ap_limits[] = { + { + .max = 1, + .types = BIT(NL80211_IFTYPE_AP), + }, +}; +#endif +#endif + +static const struct ieee80211_iface_combination +mtk_iface_combinations_sta[] = { + { +#ifdef CFG_NUM_DIFFERENT_CHANNELS_STA + .num_different_channels = CFG_NUM_DIFFERENT_CHANNELS_STA, +#else + .num_different_channels = 2, +#endif /* CFG_NUM_DIFFERENT_CHANNELS_STA */ + .max_interfaces = 3, + /*.beacon_int_infra_match = true,*/ + .limits = mtk_p2p_sta_go_limits, + .n_limits = 1, /* include p2p */ + }, +}; + +static const struct ieee80211_iface_combination +mtk_iface_combinations_p2p[] = { + { +#if CFG_ENABLE_UNIFY_WIPHY + /* The 2 MCC channels case has been verified */ + .num_different_channels = 2, +#elif defined(CFG_NUM_DIFFERENT_CHANNELS_P2P) + .num_different_channels = CFG_NUM_DIFFERENT_CHANNELS_P2P, +#else + .num_different_channels = 2, +#endif /* CFG_NUM_DIFFERENT_CHANNELS_P2P */ + .max_interfaces = 3, + /*.beacon_int_infra_match = true,*/ + .limits = mtk_p2p_sta_go_limits, + .n_limits = ARRAY_SIZE(mtk_p2p_sta_go_limits), /* include p2p */ + }, +#if (CFG_SUPPORT_DFS_MASTER == 1) +#if (KERNEL_VERSION(3, 17, 0) > CFG80211_VERSION_CODE) + /* ONLY for passing checks in cfg80211_can_use_iftype_chan + * before linux-3.17.0 + */ + { + .num_different_channels = 1, + .max_interfaces = 1, + .limits = mtk_ap_limits, + .n_limits = ARRAY_SIZE(mtk_ap_limits), + .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) | + BIT(NL80211_CHAN_WIDTH_20) | + BIT(NL80211_CHAN_WIDTH_40) | + BIT(NL80211_CHAN_WIDTH_80) | + BIT(NL80211_CHAN_WIDTH_80P80), + }, +#endif +#endif +}; + + +const struct ieee80211_iface_combination + *p_mtk_iface_combinations_sta = mtk_iface_combinations_sta; +const int32_t mtk_iface_combinations_sta_num = + ARRAY_SIZE(mtk_iface_combinations_sta); + +const struct ieee80211_iface_combination + *p_mtk_iface_combinations_p2p = mtk_iface_combinations_p2p; +const int32_t mtk_iface_combinations_p2p_num = + ARRAY_SIZE(mtk_iface_combinations_p2p); + +/****************************************************************************** + * M A C R O S + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N D E C L A R A T I O N S + ****************************************************************************** + */ + +/* Net Device Hooks */ +static int p2pOpen(IN struct net_device *prDev); + +static int p2pStop(IN struct net_device *prDev); + +static struct net_device_stats *p2pGetStats(IN struct net_device *prDev); + +static void p2pSetMulticastList(IN struct net_device *prDev); + +static netdev_tx_t p2pHardStartXmit(IN struct sk_buff *prSkb, + IN struct net_device *prDev); + +static int p2pSetMACAddress(IN struct net_device *prDev, void *addr); + +static int p2pDoIOCTL(struct net_device *prDev, + struct ifreq *prIFReq, + int i4Cmd); + +#if CFG_SUPPORT_RX_GRO +/*----------------------------------------------------------------------------*/ +/*! + * \brief A method of callback function for napi struct + * + * It just return false because driver indicate Rx packet directly. + * + * \param[in] napi Pointer to struct napi_struct. + * \param[in] budget Polling time interval. + * + * \return false + */ +/*----------------------------------------------------------------------------*/ +static int p2p_napi_poll(struct napi_struct *napi, int budget) +{ + return 0; +} +#endif + +/*---------------------------------------------------------------------------*/ +/*! + * \brief A function for prDev->init + * + * \param[in] prDev Pointer to struct net_device. + * + * \retval 0 The execution of wlanInit succeeds. + * \retval -ENXIO No such device. + */ +/*---------------------------------------------------------------------------*/ +static int p2pInit(struct net_device *prDev) +{ +#if CFG_SUPPORT_RX_GRO + struct NETDEV_PRIVATE_GLUE_INFO *prNetDevPrivate = NULL; +#endif + if (!prDev) + return -ENXIO; +#if CFG_SUPPORT_RX_GRO + prNetDevPrivate = (struct NETDEV_PRIVATE_GLUE_INFO *) + netdev_priv(prDev); + prDev->features |= NETIF_F_GRO; + prDev->hw_features |= NETIF_F_GRO; + spin_lock_init(&prNetDevPrivate->napi_spinlock); + prNetDevPrivate->napi.dev = prDev; + netif_napi_add(prNetDevPrivate->napi.dev, + &prNetDevPrivate->napi, p2p_napi_poll, 64); + DBGLOG(INIT, TRACE, + "GRO interface added successfully:%p\n", prDev); +#endif + return 0; /* success */ +} /* end of p2pInit() */ + +/*---------------------------------------------------------------------------*/ +/*! + * \brief A function for prDev->uninit + * + * \param[in] prDev Pointer to struct net_device. + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +static void p2pUninit(IN struct net_device *prDev) +{ +} /* end of p2pUninit() */ + +const struct net_device_ops p2p_netdev_ops = { + .ndo_open = p2pOpen, + .ndo_stop = p2pStop, + .ndo_set_mac_address = p2pSetMACAddress, + .ndo_set_rx_mode = p2pSetMulticastList, + .ndo_get_stats = p2pGetStats, + .ndo_do_ioctl = p2pDoIOCTL, + .ndo_start_xmit = p2pHardStartXmit, + /* .ndo_select_queue = p2pSelectQueue, */ + .ndo_select_queue = wlanSelectQueue, + .ndo_init = p2pInit, + .ndo_uninit = p2pUninit, +}; + +/****************************************************************************** + * F U N C T I O N S + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------*/ +/*! + * \brief Allocate memory for P2P_INFO, GL_P2P_INFO, P2P_CONNECTION_SETTINGS + * P2P_SPECIFIC_BSS_INFO, P2P_FSM_INFO + * + * \param[in] prGlueInfo Pointer to glue info + * + * \return TRUE + * FALSE + */ +/*---------------------------------------------------------------------------*/ +u_int8_t p2PAllocInfo(IN struct GLUE_INFO *prGlueInfo, IN uint8_t ucIdex) +{ + struct ADAPTER *prAdapter = NULL; + struct WIFI_VAR *prWifiVar = NULL; + /* UINT_32 u4Idx = 0; */ + + ASSERT(prGlueInfo); + + prAdapter = prGlueInfo->prAdapter; + prWifiVar = &(prAdapter->rWifiVar); + + ASSERT(prAdapter); + ASSERT(prWifiVar); + + do { + if (prGlueInfo->prP2PInfo[ucIdex] == NULL) { + /*alloc memory for p2p info */ + prGlueInfo->prP2PInfo[ucIdex] = + kalMemAlloc(sizeof(struct GL_P2P_INFO), + VIR_MEM_TYPE); + + if (prGlueInfo->prP2PDevInfo == NULL) { + prGlueInfo->prP2PDevInfo = + kalMemAlloc( + sizeof(struct GL_P2P_DEV_INFO), + VIR_MEM_TYPE); + if (prGlueInfo->prP2PDevInfo) { + kalMemZero(prGlueInfo->prP2PDevInfo, + sizeof(struct GL_P2P_DEV_INFO)); + } + } + + if (prAdapter->prP2pInfo == NULL) { + prAdapter->prP2pInfo = + kalMemAlloc(sizeof(struct P2P_INFO), + VIR_MEM_TYPE); + if (prAdapter->prP2pInfo) { + kalMemZero(prAdapter->prP2pInfo, + sizeof(struct P2P_INFO)); + } + } + + if (prWifiVar->prP2pDevFsmInfo == NULL) { + /* Don't only create P2P device for ucIdex 0. + * Avoid the exception that mtk_init_ap_role + * called without p2p0. + */ + prWifiVar->prP2pDevFsmInfo = + kalMemAlloc( + sizeof(struct P2P_DEV_FSM_INFO), + VIR_MEM_TYPE); + if (prWifiVar->prP2pDevFsmInfo) { + kalMemZero(prWifiVar->prP2pDevFsmInfo, + sizeof(struct + P2P_DEV_FSM_INFO)); + } + } + + prWifiVar->prP2PConnSettings[ucIdex] = + kalMemAlloc( + sizeof(struct P2P_CONNECTION_SETTINGS), + VIR_MEM_TYPE); + prWifiVar->prP2pSpecificBssInfo[ucIdex] = + kalMemAlloc( + sizeof(struct P2P_SPECIFIC_BSS_INFO), + VIR_MEM_TYPE); +#if CFG_ENABLE_PER_STA_STATISTICS_LOG + prWifiVar->prP2pQueryStaStatistics[ucIdex] = + kalMemAlloc( + sizeof(struct PARAM_GET_STA_STATISTICS), + VIR_MEM_TYPE); +#endif + /* TODO: It can be moved + * to the interface been created. + */ +#if 0 + for (u4Idx = 0; u4Idx < BSS_P2P_NUM; u4Idx++) { + prWifiVar->aprP2pRoleFsmInfo[u4Idx] = + kalMemAlloc(sizeof(struct P2P_ROLE_FSM_INFO), + VIR_MEM_TYPE); + } +#endif + } else { + ASSERT(prAdapter->prP2pInfo != NULL); + ASSERT(prWifiVar->prP2PConnSettings[ucIdex] != NULL); + /* ASSERT(prWifiVar->prP2pFsmInfo != NULL); */ + ASSERT(prWifiVar->prP2pSpecificBssInfo[ucIdex] != NULL); + } + /*MUST set memory to 0 */ + kalMemZero(prGlueInfo->prP2PInfo[ucIdex], + sizeof(struct GL_P2P_INFO)); + kalMemZero(prWifiVar->prP2PConnSettings[ucIdex], + sizeof(struct P2P_CONNECTION_SETTINGS)); +/* kalMemZero(prWifiVar->prP2pFsmInfo, sizeof(P2P_FSM_INFO_T)); */ + kalMemZero(prWifiVar->prP2pSpecificBssInfo[ucIdex], + sizeof(struct P2P_SPECIFIC_BSS_INFO)); +#if CFG_ENABLE_PER_STA_STATISTICS_LOG + if (prWifiVar->prP2pQueryStaStatistics[ucIdex]) + kalMemZero(prWifiVar->prP2pQueryStaStatistics[ucIdex], + sizeof(struct PARAM_GET_STA_STATISTICS)); +#endif + } while (FALSE); + + if (!prGlueInfo->prP2PDevInfo) + DBGLOG(P2P, ERROR, "prP2PDevInfo error\n"); + else + DBGLOG(P2P, TRACE, "prP2PDevInfo ok\n"); + + if (!prGlueInfo->prP2PInfo[ucIdex]) + DBGLOG(P2P, ERROR, "prP2PInfo error\n"); + else + DBGLOG(P2P, TRACE, "prP2PInfo ok\n"); + + + + /* chk if alloc successful or not */ + if (prGlueInfo->prP2PInfo[ucIdex] && + prGlueInfo->prP2PDevInfo && + prAdapter->prP2pInfo && + prWifiVar->prP2PConnSettings[ucIdex] && +/* prWifiVar->prP2pFsmInfo && */ + prWifiVar->prP2pSpecificBssInfo[ucIdex]) + return TRUE; + + + DBGLOG(P2P, ERROR, "[fail!]p2PAllocInfo :fail\n"); + + if (prWifiVar->prP2pSpecificBssInfo[ucIdex]) { + kalMemFree(prWifiVar->prP2pSpecificBssInfo[ucIdex], + VIR_MEM_TYPE, + sizeof(struct P2P_SPECIFIC_BSS_INFO)); + + prWifiVar->prP2pSpecificBssInfo[ucIdex] = NULL; + } + +#if CFG_ENABLE_PER_STA_STATISTICS_LOG + if (prWifiVar->prP2pQueryStaStatistics[ucIdex]) { + kalMemFree(prWifiVar->prP2pQueryStaStatistics[ucIdex], + VIR_MEM_TYPE, + sizeof(struct PARAM_GET_STA_STATISTICS)); + prWifiVar->prP2pQueryStaStatistics[ucIdex] = NULL; + } +#endif + +/* if (prWifiVar->prP2pFsmInfo) { */ +/* kalMemFree(prWifiVar->prP2pFsmInfo, + * VIR_MEM_TYPE, sizeof(P2P_FSM_INFO_T)); + */ + +/* prWifiVar->prP2pFsmInfo = NULL; */ +/* } */ + if (prWifiVar->prP2PConnSettings[ucIdex]) { + kalMemFree(prWifiVar->prP2PConnSettings[ucIdex], + VIR_MEM_TYPE, sizeof(struct P2P_CONNECTION_SETTINGS)); + + prWifiVar->prP2PConnSettings[ucIdex] = NULL; + } + if (prGlueInfo->prP2PDevInfo) { + kalMemFree(prGlueInfo->prP2PDevInfo, + VIR_MEM_TYPE, sizeof(struct GL_P2P_DEV_INFO)); + + prGlueInfo->prP2PDevInfo = NULL; + } + if (prGlueInfo->prP2PInfo[ucIdex]) { + kalMemFree(prGlueInfo->prP2PInfo[ucIdex], + VIR_MEM_TYPE, sizeof(struct GL_P2P_INFO)); + + prGlueInfo->prP2PInfo[ucIdex] = NULL; + } + if (prAdapter->prP2pInfo) { + kalMemFree(prAdapter->prP2pInfo, + VIR_MEM_TYPE, sizeof(struct P2P_INFO)); + + prAdapter->prP2pInfo = NULL; + } + return FALSE; + +} + +/*---------------------------------------------------------------------------*/ +/*! + * \brief Free memory for P2P_INFO, GL_P2P_INFO, P2P_CONNECTION_SETTINGS + * P2P_SPECIFIC_BSS_INFO, P2P_FSM_INFO + * + * \param[in] prGlueInfo Pointer to glue info + * [in] ucIdx The BSS with the idx will be freed. + * "ucIdx == 0xff" will free all BSSs. + * Only has meaning for "CFG_ENABLE_UNIFY_WIPHY == 1" + * + * \return TRUE + * FALSE + */ +/*---------------------------------------------------------------------------*/ +u_int8_t p2PFreeInfo(struct GLUE_INFO *prGlueInfo, uint8_t ucIdx) +{ + struct ADAPTER *prAdapter = prGlueInfo->prAdapter; + + ASSERT(prGlueInfo); + ASSERT(prAdapter); + + if (ucIdx >= KAL_P2P_NUM) { + DBGLOG(P2P, ERROR, "ucIdx=%d is invalid\n", ucIdx); + return FALSE; + } + + /* Expect that prAdapter->prP2pInfo must be existing. */ + if (prAdapter->prP2pInfo == NULL) { + DBGLOG(P2P, ERROR, "prAdapter->prP2pInfo is NULL\n"); + return FALSE; + } + + /* TODO: how can I sure that the specific P2P device can be freed? + * The original check is that prGlueInfo->prAdapter->fgIsP2PRegistered. + * For one wiphy feature, this func may be called without + * (fgIsP2PRegistered == FALSE) condition. + */ + + if (prGlueInfo->prP2PInfo[ucIdx] != NULL) { + kalMemFree(prAdapter->rWifiVar.prP2PConnSettings[ucIdx], + VIR_MEM_TYPE, + sizeof(struct P2P_CONNECTION_SETTINGS)); + prAdapter->rWifiVar.prP2PConnSettings[ucIdx] = NULL; + + kalMemFree(prAdapter->rWifiVar.prP2pSpecificBssInfo[ucIdx], + VIR_MEM_TYPE, + sizeof(struct P2P_SPECIFIC_BSS_INFO)); + prAdapter->rWifiVar.prP2pSpecificBssInfo[ucIdx] = NULL; + +#if CFG_ENABLE_PER_STA_STATISTICS_LOG + kalMemFree(prAdapter->rWifiVar.prP2pQueryStaStatistics[ucIdx], + VIR_MEM_TYPE, + sizeof(struct PARAM_GET_STA_STATISTICS)); + prAdapter->rWifiVar.prP2pQueryStaStatistics[ucIdx] = NULL; +#endif + +#if (CFG_SUPPORT_DFS_MASTER == 1) + if (prGlueInfo->prP2PInfo[ucIdx]->chandef) { + if (prGlueInfo->prP2PInfo[ucIdx]->chandef->chan) { + cnmMemFree(prGlueInfo->prAdapter, + prGlueInfo->prP2PInfo[ucIdx] + ->chandef->chan); + prGlueInfo->prP2PInfo[ucIdx] + ->chandef->chan = NULL; + } + cnmMemFree(prGlueInfo->prAdapter, + prGlueInfo->prP2PInfo[ucIdx]->chandef); + prGlueInfo->prP2PInfo[ucIdx]->chandef = NULL; + } +#endif + + kalMemFree(prGlueInfo->prP2PInfo[ucIdx], + VIR_MEM_TYPE, + sizeof(struct GL_P2P_INFO)); + prGlueInfo->prP2PInfo[ucIdx] = NULL; + + prAdapter->prP2pInfo->u4DeviceNum--; + } + + if (prAdapter->prP2pInfo->u4DeviceNum == 0) { + /* all prP2PInfo are freed, and free the general part now */ + + kalMemFree(prAdapter->prP2pInfo, VIR_MEM_TYPE, + sizeof(struct P2P_INFO)); + prAdapter->prP2pInfo = NULL; + + if (prGlueInfo->prP2PDevInfo) { + kalMemFree(prGlueInfo->prP2PDevInfo, VIR_MEM_TYPE, + sizeof(struct GL_P2P_DEV_INFO)); + prGlueInfo->prP2PDevInfo = NULL; + } + if (prAdapter->rWifiVar.prP2pDevFsmInfo) { + kalMemFree(prAdapter->rWifiVar.prP2pDevFsmInfo, + VIR_MEM_TYPE, sizeof(struct P2P_DEV_FSM_INFO)); + prAdapter->rWifiVar.prP2pDevFsmInfo = NULL; + } + + /* Reomve p2p bss scan list */ + scanRemoveAllP2pBssDesc(prAdapter); + } + + return TRUE; +} + +u_int8_t p2pNetRegister(struct GLUE_INFO *prGlueInfo, + u_int8_t fgIsRtnlLockAcquired) +{ + u_int8_t fgDoRegister = FALSE; + u_int8_t fgRollbackRtnlLock = FALSE; + u_int8_t ret; + + GLUE_SPIN_LOCK_DECLARATION(); + + ASSERT(prGlueInfo); + ASSERT(prGlueInfo->prAdapter); + + GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); + if (prGlueInfo->prAdapter->rP2PNetRegState + == ENUM_NET_REG_STATE_UNREGISTERED) { + prGlueInfo->prAdapter->rP2PNetRegState = + ENUM_NET_REG_STATE_REGISTERING; + fgDoRegister = TRUE; + } + GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); + + if (!fgDoRegister) + return TRUE; + + if (fgIsRtnlLockAcquired && rtnl_is_locked()) { + fgRollbackRtnlLock = TRUE; + rtnl_unlock(); + } + + /* net device initialize */ + netif_carrier_off(prGlueInfo->prP2PInfo[0]->prDevHandler); + netif_tx_stop_all_queues(prGlueInfo->prP2PInfo[0]->prDevHandler); + + /* register for net device */ + if (g_u4DevIdx[0]) { + prGlueInfo->prP2PInfo[0]->prDevHandler->ifindex = + g_u4DevIdx[0]; + g_u4DevIdx[0] = 0; + } + + if (register_netdev(prGlueInfo->prP2PInfo[0]->prDevHandler) < 0) { + DBGLOG(INIT, WARN, "unable to register netdevice for p2p\n"); + /* free dev in glUnregisterP2P() */ + /* free_netdev(prGlueInfo->prP2PInfo[0]->prDevHandler); */ + ret = FALSE; + } else { + prGlueInfo->prAdapter->rP2PNetRegState = + ENUM_NET_REG_STATE_REGISTERED; + gPrP2pDev[0] = prGlueInfo->prP2PInfo[0]->prDevHandler; + ret = TRUE; + } + + if (prGlueInfo->prAdapter->prP2pInfo->u4DeviceNum == KAL_P2P_NUM) { + /* net device initialize */ + netif_carrier_off(prGlueInfo->prP2PInfo[1]->prDevHandler); + netif_tx_stop_all_queues( + prGlueInfo->prP2PInfo[1]->prDevHandler); + + if (g_u4DevIdx[1]) { + prGlueInfo->prP2PInfo[1]->prDevHandler->ifindex + = g_u4DevIdx[1]; + g_u4DevIdx[1] = 0; + } + + /* register for net device */ + if (register_netdev( + prGlueInfo->prP2PInfo[1]->prDevHandler) < 0) { + + DBGLOG(INIT, WARN, + "unable to register netdevice for p2p\n"); + /* free dev in glUnregisterP2P() */ + /* free_netdev(prP2PInfo[1]->prDevHandler); */ + + ret = FALSE; + } else { + prGlueInfo->prAdapter->rP2PNetRegState = + ENUM_NET_REG_STATE_REGISTERED; + gPrP2pDev[1] = prGlueInfo->prP2PInfo[1]->prDevHandler; + ret = TRUE; + } + + + DBGLOG(P2P, INFO, "P2P 2nd interface work %d %d\n", + prGlueInfo->prP2PInfo[0]->prDevHandler->ifindex, + prGlueInfo->prP2PInfo[1]->prDevHandler->ifindex); + } + if (fgRollbackRtnlLock) + rtnl_lock(); + + return ret; +} + +u_int8_t p2pNetUnregister(struct GLUE_INFO *prGlueInfo, + u_int8_t fgIsRtnlLockAcquired) +{ + u_int8_t fgDoUnregister = FALSE; + u_int8_t fgRollbackRtnlLock = FALSE; + uint8_t ucRoleIdx; + struct ADAPTER *prAdapter = NULL; + struct NETDEV_PRIVATE_GLUE_INFO *prNetDevPriv = NULL; + struct GL_P2P_INFO *prP2PInfo = NULL; + struct BSS_INFO *prP2pBssInfo = NULL; + int iftype = 0; + struct net_device *prRoleDev = NULL; + + GLUE_SPIN_LOCK_DECLARATION(); + + prAdapter = prGlueInfo->prAdapter; + + ASSERT(prGlueInfo); + ASSERT(prAdapter); + + GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); + if (prAdapter->rP2PNetRegState == ENUM_NET_REG_STATE_REGISTERED) { + prAdapter->rP2PNetRegState = ENUM_NET_REG_STATE_UNREGISTERING; + fgDoUnregister = TRUE; + } + GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); + + if (!fgDoUnregister) + return TRUE; + + if (fgIsRtnlLockAcquired && rtnl_is_locked()) + fgRollbackRtnlLock = TRUE; + + for (ucRoleIdx = 0; ucRoleIdx < KAL_P2P_NUM; ucRoleIdx++) { + prP2PInfo = prGlueInfo->prP2PInfo[ucRoleIdx]; + if (prP2PInfo == NULL) + continue; + +#if CFG_ENABLE_UNIFY_WIPHY + /* don't unregister the dev that share with the AIS */ + if (wlanIsAisDev(prP2PInfo->prDevHandler)) + continue; +#endif + + prRoleDev = prP2PInfo->aprRoleHandler; + if (prRoleDev != NULL) { + /* info cfg80211 disconnect */ + prNetDevPriv = (struct NETDEV_PRIVATE_GLUE_INFO *) + netdev_priv(prRoleDev); + iftype = prRoleDev->ieee80211_ptr->iftype; + prP2pBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prNetDevPriv->ucBssIdx); + + /* FIXME: The p2pRoleFsmUninit may call the + * cfg80211_disconnected. + * p2pRemove()->glUnregisterP2P->p2pRoleFsmUninit(), + * it may be too late. + */ + if ((prP2pBssInfo != NULL) && + (prP2pBssInfo->eConnectionState == + MEDIA_STATE_CONNECTED) && + ((iftype == NL80211_IFTYPE_P2P_CLIENT) || + (iftype == NL80211_IFTYPE_STATION))) { +#if CFG_WPS_DISCONNECT || (KERNEL_VERSION(4, 2, 0) <= CFG80211_VERSION_CODE) + cfg80211_disconnected(prRoleDev, 0, NULL, 0, + TRUE, GFP_KERNEL); +#else + cfg80211_disconnected(prRoleDev, 0, NULL, 0, + GFP_KERNEL); +#endif + } + + if (prRoleDev != prP2PInfo->prDevHandler) { + if (netif_carrier_ok(prRoleDev)) + netif_carrier_off(prRoleDev); + + netif_tx_stop_all_queues(prRoleDev); + } + } + + if (netif_carrier_ok(prP2PInfo->prDevHandler)) + netif_carrier_off(prP2PInfo->prDevHandler); + + netif_tx_stop_all_queues(prP2PInfo->prDevHandler); + + if (fgRollbackRtnlLock) + rtnl_unlock(); + + /* Here are the functions which need rtnl_lock */ + if ((prRoleDev) && (prP2PInfo->prDevHandler != prRoleDev)) { + DBGLOG(INIT, INFO, "unregister p2p[%d]\n", ucRoleIdx); + if (prRoleDev->reg_state == NETREG_REGISTERED) + unregister_netdev(prRoleDev); + + /* This ndev is created in mtk_p2p_cfg80211_add_iface(), + * and unregister_netdev will also free the ndev. + */ + } + + DBGLOG(INIT, INFO, "unregister p2pdev[%d]\n", ucRoleIdx); + if (prP2PInfo->prDevHandler->reg_state == NETREG_REGISTERED) + unregister_netdev(prP2PInfo->prDevHandler); + + if (fgRollbackRtnlLock) + rtnl_lock(); + } + + prGlueInfo->prAdapter->rP2PNetRegState = + ENUM_NET_REG_STATE_UNREGISTERED; + + return TRUE; +} + +/*---------------------------------------------------------------------------*/ +/*! + * \brief Setup the P2P device information + * + * \param[in] prGlueInfo Pointer to glue info + * [in] prP2pWdev Pointer to the wireless device + * [in] prP2pDev Pointer to the net device + * [in] u4Idx The P2P Role index (max : (KAL_P2P_NUM-1)) + * [in] fgIsApMode Indicate that this device is AP Role or not + * + * \return 0 Success + * -1 Failure + */ +/*---------------------------------------------------------------------------*/ +int glSetupP2P(struct GLUE_INFO *prGlueInfo, struct wireless_dev *prP2pWdev, + struct net_device *prP2pDev, uint8_t u4Idx, u_int8_t fgIsApMode) +{ + struct ADAPTER *prAdapter = NULL; + struct GL_P2P_INFO *prP2PInfo = NULL; + struct GL_HIF_INFO *prHif = NULL; + struct NETDEV_PRIVATE_GLUE_INFO *prNetDevPriv = NULL; + struct mt66xx_chip_info *prChipInfo = NULL; + + DBGLOG(INIT, TRACE, "setup the p2p dev\n"); + + if ((prGlueInfo == NULL) || + (prP2pWdev == NULL) || + (prP2pWdev->wiphy == NULL) || + (prP2pDev == NULL)) { + DBGLOG(INIT, ERROR, "parameter is NULL!!\n"); + return -1; + } + + prHif = &prGlueInfo->rHifInfo; + prAdapter = prGlueInfo->prAdapter; + + if ((prAdapter == NULL) || + (prHif == NULL)) { + DBGLOG(INIT, ERROR, "prAdapter/prHif is NULL!!\n"); + return -1; + } + + /* FIXME: check KAL_P2P_NUM in trunk? */ + if (u4Idx < 0 || u4Idx >= KAL_P2P_NUM) { + DBGLOG(INIT, ERROR, "u4Idx(%d) is out of range!!\n", u4Idx); + return -1; + } + + prChipInfo = prAdapter->chip_info; + + /*0. allocate p2pinfo */ + if (p2PAllocInfo(prGlueInfo, u4Idx) != TRUE) { + DBGLOG(INIT, WARN, "Allocate memory for p2p FAILED\n"); + return -1; + } + + prP2PInfo = prGlueInfo->prP2PInfo[u4Idx]; + +#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 + /* fill wiphy parameters */ + + prP2PInfo->prWdev = prP2pWdev; + + if (!prAdapter->fgEnable5GBand) + prP2pWdev->wiphy->bands[BAND_5G] = NULL; + +#endif /* CFG_ENABLE_WIFI_DIRECT_CFG_80211 */ + + /* setup netdev */ + /* Point to shared glue structure */ + prNetDevPriv = (struct NETDEV_PRIVATE_GLUE_INFO *) + netdev_priv(prP2pDev); + prNetDevPriv->prGlueInfo = prGlueInfo; + + /* set ucIsP2p for P2P function device */ + if (fgIsApMode == TRUE) { + prP2pWdev->iftype = NL80211_IFTYPE_AP; +#if CFG_ENABLE_UNIFY_WIPHY + prNetDevPriv->ucIsP2p = FALSE; +#endif +#if CFG_MTK_MDDP_WH_SUPPORT + prNetDevPriv->ucMddpSupport = TRUE; +#else + prNetDevPriv->ucMddpSupport = FALSE; +#endif + } else { + prP2pWdev->iftype = NL80211_IFTYPE_P2P_CLIENT; +#if CFG_ENABLE_UNIFY_WIPHY + prNetDevPriv->ucIsP2p = TRUE; +#endif + prNetDevPriv->ucMddpSupport = FALSE; + } + + /* register callback functions */ + prP2pDev->needed_headroom = + NIC_TX_DESC_AND_PADDING_LENGTH + prChipInfo->txd_append_size; + prP2pDev->netdev_ops = &p2p_netdev_ops; + +#if defined(_HIF_SDIO) +#if (MTK_WCN_HIF_SDIO == 0) + SET_NETDEV_DEV(prP2pDev, &(prHif->func->dev)); +#endif +#endif + +#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 + prP2pDev->ieee80211_ptr = prP2pWdev; + prP2pWdev->netdev = prP2pDev; +#endif + +#if CFG_TCP_IP_CHKSUM_OFFLOAD + /* set HW checksum offload */ + if (prAdapter->fgIsSupportCsumOffload) { + prP2pDev->features |= NETIF_F_IP_CSUM | + NETIF_F_IPV6_CSUM | + NETIF_F_RXCSUM; + } +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ + + kalResetStats(prP2pDev); + + /* finish */ + /* bind netdev pointer to netdev index */ + prP2PInfo->prDevHandler = prP2pDev; + + /* XXX: All the P2P/AP devices do p2pDevFsmInit in the original code */ + p2pDevFsmInit(prAdapter); + prP2PInfo->aprRoleHandler = prP2PInfo->prDevHandler; + + DBGLOG(P2P, INFO, + "check prDevHandler = %p, aprRoleHandler = %p\n", + prP2PInfo->prDevHandler, prP2PInfo->aprRoleHandler); + + prNetDevPriv->ucBssIdx = p2pRoleFsmInit(prAdapter, (uint8_t) u4Idx); + init_completion(&prP2PInfo->rStopApComp); + /* Currently wpasupplicant can't support create interface. */ + /* so initial the corresponding data structure here. */ + wlanBindBssIdxToNetInterface(prGlueInfo, prNetDevPriv->ucBssIdx, + (void *) prP2PInfo->aprRoleHandler); + + /* bind netdev pointer to netdev index */ +#if 0 + wlanBindNetInterface(prGlueInfo, NET_DEV_P2P_IDX, + (void *)prGlueInfo->prP2PInfo->prDevHandler); +#endif + + /* setup running mode */ + p2pFuncInitConnectionSettings(prAdapter, + prAdapter->rWifiVar.prP2PConnSettings[u4Idx], fgIsApMode); + + return 0; +} + +/*---------------------------------------------------------------------------*/ +/*! + * \brief Register for cfg80211 for Wi-Fi Direct + * + * \param[in] prGlueInfo Pointer to glue info + * + * \return TRUE + * FALSE + */ +/*---------------------------------------------------------------------------*/ +u_int8_t glRegisterP2P(struct GLUE_INFO *prGlueInfo, const char *prDevName, + const char *prDevName2, uint8_t ucApMode) +{ + struct ADAPTER *prAdapter = NULL; + uint8_t rMacAddr[PARAM_MAC_ADDR_LEN]; + u_int8_t fgIsApMode = FALSE; + uint8_t ucRegisterNum = 1, i = 0; + struct wireless_dev *prP2pWdev = NULL; + struct net_device *prP2pDev = NULL; + struct wiphy *prWiphy = NULL; + const char *prSetDevName; +#if (CFG_ENABLE_UNIFY_WIPHY == 0) + struct GL_HIF_INFO *prHif = NULL; + struct device *prDev; +#endif + + ASSERT(prGlueInfo); + + prAdapter = prGlueInfo->prAdapter; + ASSERT(prAdapter); + + if ((ucApMode == RUNNING_DUAL_AP_MODE) || + (ucApMode == RUNNING_P2P_AP_MODE)) { + ucRegisterNum = 2; + glP2pCreateWirelessDevice(prGlueInfo); + } + + do { + if (ucApMode == RUNNING_P2P_AP_MODE) { + if (i == 0) { + prSetDevName = prDevName; + fgIsApMode = FALSE; + } else { + prSetDevName = prDevName2; + fgIsApMode = TRUE; + } + } else { + /* RUNNING_AP_MODE + * RUNNING_DUAL_AP_MODE + * RUNNING_P2P_MODE + */ + prSetDevName = prDevName; + + if (ucApMode == RUNNING_P2P_MODE) + fgIsApMode = FALSE; + else + fgIsApMode = TRUE; + } + + if (!gprP2pRoleWdev[i]) { + DBGLOG(P2P, ERROR, "gprP2pRoleWdev[%d] is NULL\n", i); + return FALSE; + } + + prP2pWdev = gprP2pRoleWdev[i]; + DBGLOG(INIT, INFO, "glRegisterP2P(%d), fgIsApMode(%d)\n", + i, fgIsApMode); + + /* Reset prP2pWdev for the issue that the prP2pWdev doesn't + * reset when the usb unplug/plug. + */ + prWiphy = prP2pWdev->wiphy; + memset(prP2pWdev, 0, sizeof(struct wireless_dev)); + prP2pWdev->wiphy = prWiphy; + + /* allocate netdev */ +#if KERNEL_VERSION(3, 17, 0) <= CFG80211_VERSION_CODE + prP2pDev = alloc_netdev_mq( + sizeof(struct NETDEV_PRIVATE_GLUE_INFO), + prSetDevName, NET_NAME_PREDICTABLE, + ether_setup, CFG_MAX_TXQ_NUM); +#else + prP2pDev = alloc_netdev_mq( + sizeof(struct NETDEV_PRIVATE_GLUE_INFO), + prSetDevName, + ether_setup, CFG_MAX_TXQ_NUM); +#endif + if (!prP2pDev) { + DBGLOG(INIT, WARN, "unable to allocate ndev for p2p\n"); + goto err_alloc_netdev; + } + + COPY_MAC_ADDR(rMacAddr, + prAdapter->rWifiVar.aucInterfaceAddress[i]); + + DBGLOG(INIT, INFO, "Set p2p role[%d] mac to " MACSTR "\n", + i, MAC2STR(rMacAddr)); + kalMemCopy(prP2pDev->dev_addr, rMacAddr, ETH_ALEN); + kalMemCopy(prP2pDev->perm_addr, prP2pDev->dev_addr, ETH_ALEN); + + if (glSetupP2P(prGlueInfo, prP2pWdev, prP2pDev, i, fgIsApMode) + != 0) { + DBGLOG(INIT, WARN, "glSetupP2P FAILED\n"); + free_netdev(prP2pDev); + return FALSE; + } + +#if (CFG_ENABLE_UNIFY_WIPHY == 0) + prHif = &prGlueInfo->rHifInfo; + glGetHifDev(prHif, &prDev); + if (!prDev) + DBGLOG(INIT, ERROR, "P2P[%d] parent dev is NULL\n", i); + set_wiphy_dev(prWiphy, prDev); +#endif + + i++; + /* prP2pInfo is alloc at glSetupP2P()->p2PAllocInfo() */ + prAdapter->prP2pInfo->u4DeviceNum++; + + /* set p2p net device register state */ + /* p2pNetRegister() will check prAdapter->rP2PNetRegState. */ + prAdapter->rP2PNetRegState = ENUM_NET_REG_STATE_UNREGISTERED; + } while (i < ucRegisterNum); + + return TRUE; +#if 0 +err_reg_netdev: + free_netdev(prGlueInfo->prP2PInfo->prDevHandler); +#endif +err_alloc_netdev: + return FALSE; +} /* end of glRegisterP2P() */ + +#if CFG_ENABLE_UNIFY_WIPHY +u_int8_t glP2pCreateWirelessDevice(struct GLUE_INFO *prGlueInfo) +{ + struct wiphy *prWiphy = wlanGetWiphy(); + struct wireless_dev *prWdev = NULL; + uint8_t i = 0; + +#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 + if (!prWiphy) { + DBGLOG(P2P, ERROR, "unable to allocate wiphy for p2p\n"); + return FALSE; + } + + for (i = 0 ; i < KAL_P2P_NUM; i++) { + if (!gprP2pRoleWdev[i]) + break; + } + + if (i >= KAL_P2P_NUM) { + DBGLOG(INIT, WARN, "fail to register wiphy to driver\n"); + return FALSE; + } + + prWdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); + if (!prWdev) { + DBGLOG(P2P, ERROR, "allocate p2p wdev fail, no memory\n"); + return FALSE; + } + + /* set priv as pointer to glue structure */ + prWdev->wiphy = prWiphy; + + gprP2pRoleWdev[i] = prWdev; + DBGLOG(INIT, TRACE, "glP2pCreateWirelessDevice (%p)\n", + gprP2pRoleWdev[i]->wiphy); + + return TRUE; +#else + return FALSE; +#endif +} +#else /* (CFG_ENABLE_UNIFY_WIPHY == 0) */ +u_int8_t glP2pCreateWirelessDevice(struct GLUE_INFO *prGlueInfo) +{ + struct wiphy *prWiphy = NULL; + struct wireless_dev *prWdev = NULL; + uint8_t i = 0; +#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 + prWdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); + if (!prWdev) { + DBGLOG(P2P, ERROR, + "allocate p2p wireless device fail, no memory\n"); + return FALSE; + } + /* 1. allocate WIPHY */ + prWiphy = wiphy_new(&mtk_p2p_ops, sizeof(struct GLUE_INFO *)); + if (!prWiphy) { + DBGLOG(P2P, ERROR, "unable to allocate wiphy for p2p\n"); + goto free_wdev; + } + + prWiphy->interface_modes = BIT(NL80211_IFTYPE_AP) + | BIT(NL80211_IFTYPE_P2P_CLIENT) + | BIT(NL80211_IFTYPE_P2P_GO) + | BIT(NL80211_IFTYPE_STATION); + + prWiphy->software_iftypes |= BIT(NL80211_IFTYPE_P2P_DEVICE); + + prWiphy->iface_combinations = p_mtk_iface_combinations_p2p; + prWiphy->n_iface_combinations = mtk_iface_combinations_p2p_num; + + prWiphy->bands[KAL_BAND_2GHZ] = &mtk_band_2ghz; + prWiphy->bands[KAL_BAND_5GHZ] = &mtk_band_5ghz; + + prWiphy->mgmt_stypes = mtk_cfg80211_default_mgmt_stypes; + prWiphy->max_remain_on_channel_duration = 5000; + prWiphy->n_cipher_suites = 5; + prWiphy->cipher_suites = mtk_cipher_suites; +#if KERNEL_VERSION(3, 14, 0) > CFG80211_VERSION_CODE + prWiphy->flags = WIPHY_FLAG_CUSTOM_REGULATORY + | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL + | WIPHY_FLAG_HAVE_AP_SME; +#else +#if (CFG_SUPPORT_DFS_MASTER == 1) + prWiphy->flags = WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL + | WIPHY_FLAG_HAVE_AP_SME + | WIPHY_FLAG_HAS_CHANNEL_SWITCH; + prWiphy->max_num_csa_counters = 2; +#else + prWiphy->flags = WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL + | WIPHY_FLAG_HAVE_AP_SME; +#endif + prWiphy->regulatory_flags = REGULATORY_CUSTOM_REG; +#endif + prWiphy->ap_sme_capa = 1; + +#if CFG_ENABLE_OFFCHANNEL_TX + prWiphy->flags |= WIPHY_FLAG_OFFCHAN_TX; +#endif /* CFG_ENABLE_OFFCHANNEL_TX */ + prWiphy->features |= NL80211_FEATURE_INACTIVITY_TIMER; + + prWiphy->max_scan_ssids = MAX_SCAN_LIST_NUM; + prWiphy->max_scan_ie_len = MAX_SCAN_IE_LEN; + prWiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; +#if KERNEL_VERSION(3, 18, 0) <= CFG80211_VERSION_CODE + prWiphy->vendor_commands = mtk_p2p_vendor_ops; + prWiphy->n_vendor_commands = sizeof(mtk_p2p_vendor_ops) + / sizeof(struct wiphy_vendor_command); + prWiphy->vendor_events = mtk_p2p_vendor_events; + prWiphy->n_vendor_events = ARRAY_SIZE(mtk_p2p_vendor_events); +#endif + +#ifdef CONFIG_PM +#if KERNEL_VERSION(3, 9, 0) > CFG80211_VERSION_CODE + prWiphy->wowlan = &mtk_p2p_wowlan_support; +#endif +#endif + +#if KERNEL_VERSION(3, 14, 0) < CFG80211_VERSION_CODE + prWiphy->max_ap_assoc_sta = P2P_MAXIMUM_CLIENT_COUNT; +#endif + + cfg80211_regd_set_wiphy(prWiphy); + + /* 2.1 set priv as pointer to glue structure */ + *((struct GLUE_INFO **) wiphy_priv(prWiphy)) = prGlueInfo; + /* Here are functions which need rtnl_lock */ + if (wiphy_register(prWiphy) < 0) { + DBGLOG(INIT, WARN, "fail to register wiphy for p2p\n"); + goto free_wiphy; + } + prWdev->wiphy = prWiphy; + + for (i = 0 ; i < KAL_P2P_NUM; i++) { + if (!gprP2pRoleWdev[i]) { + gprP2pRoleWdev[i] = prWdev; + DBGLOG(INIT, INFO, + "glP2pCreateWirelessDevice (%x)\n", + gprP2pRoleWdev[i]->wiphy); + break; + } + } + + if (i == KAL_P2P_NUM) + DBGLOG(INIT, WARN, "fail to register wiphy to driver\n"); + + return TRUE; + +free_wiphy: + wiphy_free(prWiphy); +free_wdev: + kfree(prWdev); +#endif + return FALSE; +} +#endif /* CFG_ENABLE_UNIFY_WIPHY */ + +/*---------------------------------------------------------------------------*/ +/*! + * \brief Unregister Net Device for Wi-Fi Direct + * + * \param[in] prGlueInfo Pointer to glue info + * [in] ucIdx The BSS with the idx will be freed. + * "ucIdx == 0xff" will free all BSSs. + * Only has meaning for "CFG_ENABLE_UNIFY_WIPHY == 1" + * + * \return TRUE + * FALSE + */ +/*---------------------------------------------------------------------------*/ +u_int8_t glUnregisterP2P(struct GLUE_INFO *prGlueInfo, uint8_t ucIdx) +{ + uint8_t ucRoleIdx; + struct ADAPTER *prAdapter; + struct GL_P2P_INFO *prP2PInfo = NULL; + int i4Start = 0, i4End = 0; + + ASSERT(prGlueInfo); + + if (ucIdx == 0xff) { + i4Start = 0; + i4End = BSS_P2P_NUM; + } else if (ucIdx < BSS_P2P_NUM) { + i4Start = ucIdx; + i4End = ucIdx + 1; + } else { + DBGLOG(INIT, WARN, "The ucIdx (%d) is a wrong value\n", ucIdx); + return FALSE; + } + + prAdapter = prGlueInfo->prAdapter; + + /* 4 <1> Uninit P2P dev FSM */ + /* Uninit P2P device FSM */ + /* only do p2pDevFsmUninit, when unregister all P2P device */ + if (ucIdx == 0xff) + p2pDevFsmUninit(prAdapter); + + /* 4 <2> Uninit P2P role FSM */ + for (ucRoleIdx = i4Start; ucRoleIdx < i4End; ucRoleIdx++) { + if (P2P_ROLE_INDEX_2_ROLE_FSM_INFO(prAdapter, ucRoleIdx)) { + /* FIXME: The cfg80211_XXX() is following the + * p2pRoleFsmUninit() sub-progress. + * ex: The cfg80211_del_sta() is called in the + * kalP2PGOStationUpdate(). + * But the netdev had be unregistered at + * p2pNetUnregister(). EXCEPTION!! + */ + p2pRoleFsmUninit(prGlueInfo->prAdapter, ucRoleIdx); + } + } + + /* 4 <3> Free Wiphy & netdev */ + for (ucRoleIdx = i4Start; ucRoleIdx < i4End; ucRoleIdx++) { + prP2PInfo = prGlueInfo->prP2PInfo[ucRoleIdx]; + + if (prP2PInfo == NULL) + continue; + /* For P2P interfaces, prDevHandler points to the net_device of + * p2p0 interface. And aprRoleHandler points to the net_device + * of p2p virtual interface (i.e., p2p1) when it was created. + * And when p2p virtual interface is deleted, aprRoleHandler + * will change to point to prDevHandler. Hence, when + * aprRoleHandler & prDevHandler are pointing to different + * addresses, it means vif p2p1 exists. Otherwise it means p2p1 + * was already deleted. + */ + if ((prP2PInfo->aprRoleHandler != NULL) && + (prP2PInfo->aprRoleHandler != prP2PInfo->prDevHandler)) { + /* This device is added by the P2P, and use + * ndev->destructor to free. The p2pDevFsmUninit() use + * prP2PInfo->aprRoleHandler to do some check. + */ + prP2PInfo->aprRoleHandler = NULL; + DBGLOG(P2P, INFO, "aprRoleHandler idx %d set NULL\n", + ucRoleIdx); + + /* Expect that gprP2pRoleWdev[ucRoleIdx] has been reset + * as gprP2pWdev or NULL in p2pNetUnregister + * (unregister_netdev). + */ + } + + if (prP2PInfo->prDevHandler) { + /* don't free the dev that share with the AIS */ + if (wlanIsAisDev(prP2PInfo->prDevHandler)) + gprP2pRoleWdev[ucRoleIdx] = NULL; + else { + if (prP2PInfo->prDevHandler->reg_state + == NETREG_REGISTERED) { + DBGLOG(INIT, WARN, + "Force unregister netdev\n"); + unregister_netdev( + prP2PInfo->prDevHandler); + prGlueInfo->prAdapter->rP2PNetRegState = + ENUM_NET_REG_STATE_UNREGISTERED; + } + free_netdev(prP2PInfo->prDevHandler); + } + prP2PInfo->prDevHandler = NULL; + } + + /* 4 <4> Free P2P internal memory */ + if (!p2PFreeInfo(prGlueInfo, ucRoleIdx)) { + /* FALSE: (fgIsP2PRegistered!=FALSE)||(ucRoleIdx err) */ + DBGLOG(INIT, ERROR, "p2PFreeInfo FAILED\n"); + return FALSE; + } + } + + return TRUE; +} /* end of glUnregisterP2P() */ + +/* Net Device Hooks */ +/*----------------------------------------------------------------------------*/ +/*! + * \brief A function for net_device open (ifup) + * + * \param[in] prDev Pointer to struct net_device. + * + * \retval 0 The execution succeeds. + * \retval < 0 The execution failed. + */ +/*----------------------------------------------------------------------------*/ +static int p2pOpen(IN struct net_device *prDev) +{ +/* P_GLUE_INFO_T prGlueInfo = NULL; */ +/* P_ADAPTER_T prAdapter = NULL; */ +/* P_MSG_P2P_FUNCTION_SWITCH_T prFuncSwitch; */ + + ASSERT(prDev); + +#if 0 /* Move after device name set. (mtk_p2p_set_local_dev_info) */ + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prDev)); + ASSERT(prGlueInfo); + + prAdapter = prGlueInfo->prAdapter; + ASSERT(prAdapter); + + /* 1. switch P2P-FSM on */ + /* 1.1 allocate for message */ + prFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(prAdapter, + RAM_TYPE_MSG, sizeof(MSG_P2P_FUNCTION_SWITCH_T)); + + if (!prFuncSwitch) { + ASSERT(0); /* Can't trigger P2P FSM */ + return -ENOMEM; + } + + /* 1.2 fill message */ + prFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH; + prFuncSwitch->fgIsFuncOn = TRUE; + + /* 1.3 send message */ + mboxSendMsg(prAdapter, + MBOX_ID_0, + (struct MSG_HDR *) prFuncSwitch, + MSG_SEND_METHOD_BUF); +#endif + + /* 2. carrier on & start TX queue */ + /*DFS todo 20161220_DFS*/ +#if (CFG_SUPPORT_DFS_MASTER == 1) + if (prDev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP) { + /*netif_carrier_on(prDev);*/ + netif_tx_start_all_queues(prDev); + } +#else + /*netif_carrier_on(prDev);*/ + netif_tx_start_all_queues(prDev); +#endif + +#ifdef CONFIG_WIRELESS_EXT + prDev->wireless_handlers = &wext_handler_def; +#endif + + return 0; /* success */ +} /* end of p2pOpen() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief A function for net_device stop (ifdown) + * + * \param[in] prDev Pointer to struct net_device. + * + * \retval 0 The execution succeeds. + * \retval < 0 The execution failed. + */ +/*----------------------------------------------------------------------------*/ +static int p2pStop(IN struct net_device *prDev) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + struct GL_P2P_DEV_INFO *prP2pGlueDevInfo = NULL; +/* P_MSG_P2P_FUNCTION_SWITCH_T prFuncSwitch; */ + + GLUE_SPIN_LOCK_DECLARATION(); + + ASSERT(prDev); + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prDev)); + ASSERT(prGlueInfo); + + prAdapter = prGlueInfo->prAdapter; + ASSERT(prAdapter); + + /* XXX: The p2pStop may be triggered after the wlanRemove. */ + /* And prGlueInfo->prP2PDevInfo is freed in p2PFreeInfo. */ + if (!prAdapter->fgIsP2PRegistered) + return -EFAULT; + + prP2pGlueDevInfo = prGlueInfo->prP2PDevInfo; + ASSERT(prP2pGlueDevInfo); + + /* 0. Do the scan done and set parameter to abort if the scan pending */ + /*DBGLOG(INIT, INFO, "p2pStop and ucRoleIdx = %u\n", ucRoleIdx);*/ + + GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); + if ((prP2pGlueDevInfo->prScanRequest != NULL) && + (prP2pGlueDevInfo->prScanRequest->wdev == prDev->ieee80211_ptr)) { + DBGLOG(INIT, INFO, "p2pStop and abort scan!!\n"); + kalCfg80211ScanDone(prP2pGlueDevInfo->prScanRequest, TRUE); + prP2pGlueDevInfo->prScanRequest = NULL; + } + GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); + + /* zero clear old acs information */ + kalMemZero(&(prGlueInfo->prAdapter->rWifiVar.rChnLoadInfo), + sizeof(prGlueInfo->prAdapter->rWifiVar.rChnLoadInfo)); + wlanInitChnLoadInfoChannelList(prGlueInfo->prAdapter); + + /* 1. stop TX queue */ + netif_tx_stop_all_queues(prDev); +#if 0 + /* 2. switch P2P-FSM off */ + /* 2.1 allocate for message */ + prFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(prAdapter, + RAM_TYPE_MSG, sizeof(MSG_P2P_FUNCTION_SWITCH_T)); + + if (!prFuncSwitch) { + ASSERT(0); /* Can't trigger P2P FSM */ + return -ENOMEM; + } + + /* 2.2 fill message */ + prFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH; + prFuncSwitch->fgIsFuncOn = FALSE; + + /* 2.3 send message */ + mboxSendMsg(prAdapter, + MBOX_ID_0, + (struct MSG_HDR *) prFuncSwitch, + MSG_SEND_METHOD_BUF); +#endif + /* 3. stop queue and turn off carrier */ + /* TH3 multiple P2P */ + /*prGlueInfo->prP2PInfo[0]->eState = MEDIA_STATE_DISCONNECTED;*/ + + netif_tx_stop_all_queues(prDev); + if (netif_carrier_ok(prDev)) + netif_carrier_off(prDev); + +#ifdef CONFIG_WIRELESS_EXT + prDev->wireless_handlers = NULL; +#endif + + return 0; +} /* end of p2pStop() */ + +/*---------------------------------------------------------------------------*/ +/*! + * \brief A method of struct net_device, + * to get the network interface statistical + * information. + * + * Whenever an application needs to get statistics for the interface, + * this method is called. + * This happens, for example, when ifconfig or netstat -i is run. + * + * \param[in] prDev Pointer to struct net_device. + * + * \return net_device_stats buffer pointer. + */ +/*---------------------------------------------------------------------------*/ +struct net_device_stats *p2pGetStats(IN struct net_device *prDev) +{ + struct NETDEV_PRIVATE_GLUE_INFO *prNetDevPrivate; + + prNetDevPrivate = (struct NETDEV_PRIVATE_GLUE_INFO *) + netdev_priv(prDev); + kalMemCopy(&prNetDevPrivate->stats, &prDev->stats, + sizeof(struct net_device_stats)); +#if CFG_MTK_MDDP_WH_SUPPORT + mddpGetMdStats(prDev); +#endif + + return (struct net_device_stats *) &prNetDevPrivate->stats; +} /* end of p2pGetStats() */ + +static void p2pSetMulticastList(IN struct net_device *prDev) +{ + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *) NULL; + + prGlueInfo = (prDev != NULL) + ? *((struct GLUE_INFO **) netdev_priv(prDev)) + : NULL; + + if (!prDev || !prGlueInfo) { + DBGLOG(INIT, WARN, + " abnormal dev or skb: prDev(0x%p), prGlueInfo(0x%p)\n", + prDev, prGlueInfo); + return; + } + + g_P2pPrDev = prDev; + + /* 4 Mark HALT, notify main thread to finish current job */ + set_bit(GLUE_FLAG_SUB_MOD_MULTICAST_BIT, &prGlueInfo->ulFlag); + /* wake up main thread */ + wake_up_interruptible(&prGlueInfo->waitq); + +} /* p2pSetMulticastList */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is to set multicast list and set rx mode. + * + * \param[in] prDev Pointer to struct net_device + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void mtk_p2p_wext_set_Multicastlist(struct GLUE_INFO *prGlueInfo) +{ + uint32_t u4SetInfoLen = 0; + uint32_t u4McCount; + struct net_device *prDev = g_P2pPrDev; + + prGlueInfo = (prDev != NULL) + ? *((struct GLUE_INFO **) netdev_priv(prDev)) + : NULL; + + if (!prDev || !prGlueInfo) { + DBGLOG(INIT, WARN, + " abnormal dev or skb: prDev(0x%p), prGlueInfo(0x%p)\n", + prDev, prGlueInfo); + return; + } + + if (prDev->flags & IFF_PROMISC) + prGlueInfo->prP2PDevInfo->u4PacketFilter + |= PARAM_PACKET_FILTER_PROMISCUOUS; + + if (prDev->flags & IFF_BROADCAST) + prGlueInfo->prP2PDevInfo->u4PacketFilter + |= PARAM_PACKET_FILTER_BROADCAST; + u4McCount = netdev_mc_count(prDev); + + if (prDev->flags & IFF_MULTICAST) { + if ((prDev->flags & IFF_ALLMULTI) + || (u4McCount > MAX_NUM_GROUP_ADDR)) + prGlueInfo->prP2PDevInfo->u4PacketFilter + |= PARAM_PACKET_FILTER_ALL_MULTICAST; + else + prGlueInfo->prP2PDevInfo->u4PacketFilter + |= PARAM_PACKET_FILTER_MULTICAST; + } + + if (prGlueInfo->prP2PDevInfo->u4PacketFilter + & PARAM_PACKET_FILTER_MULTICAST) { + /* Prepare multicast address list */ + struct netdev_hw_addr *ha; + uint32_t i = 0; + + /* Avoid race condition with kernel net subsystem */ + netif_addr_lock_bh(prDev); + + netdev_for_each_mc_addr(ha, prDev) { + /* If ha is null, it will break the loop. */ + /* Check mc count before accessing to ha to + * prevent from kernel crash. + */ + if (i == u4McCount || !ha) + break; + if (i < MAX_NUM_GROUP_ADDR) { + COPY_MAC_ADDR( + &(prGlueInfo->prP2PDevInfo + ->aucMCAddrList[i]), + GET_ADDR(ha)); + i++; + } + } + + netif_addr_unlock_bh(prDev); + + DBGLOG(P2P, TRACE, "SEt Multicast Address List\n"); + + if (i >= MAX_NUM_GROUP_ADDR) + return; + wlanoidSetP2PMulticastList(prGlueInfo->prAdapter, + &(prGlueInfo->prP2PDevInfo->aucMCAddrList[0]), + (i * ETH_ALEN), &u4SetInfoLen); + + } + +} /* end of p2pSetMulticastList() */ + +/*---------------------------------------------------------------------------*/ +/*! + * \brief This function is TX entry point of NET DEVICE. + * + * \param[in] prSkb Pointer of the sk_buff to be sent + * \param[in] prDev Pointer to struct net_device + * + * \retval NETDEV_TX_OK - on success. + * \retval NETDEV_TX_BUSY - on failure, packet will be discarded by upper layer. + */ +/*---------------------------------------------------------------------------*/ +netdev_tx_t p2pHardStartXmit(IN struct sk_buff *prSkb, + IN struct net_device *prDev) +{ + struct NETDEV_PRIVATE_GLUE_INFO *prNetDevPrivate = + (struct NETDEV_PRIVATE_GLUE_INFO *) NULL; + struct GLUE_INFO *prGlueInfo = NULL; + uint8_t ucBssIndex; + struct BSS_INFO *prP2pBssInfo = NULL; + + ASSERT(prSkb); + ASSERT(prDev); + + prNetDevPrivate = (struct NETDEV_PRIVATE_GLUE_INFO *) + netdev_priv(prDev); + prGlueInfo = prNetDevPrivate->prGlueInfo; + ucBssIndex = prNetDevPrivate->ucBssIdx; + + kalResetPacket(prGlueInfo, (void *) prSkb); + + kalHardStartXmit(prSkb, prDev, prGlueInfo, ucBssIndex); + prP2pBssInfo = GET_BSS_INFO_BY_INDEX(prGlueInfo->prAdapter, ucBssIndex); + if ((prP2pBssInfo->eConnectionState == MEDIA_STATE_CONNECTED) || + (prP2pBssInfo->rStaRecOfClientList.u4NumElem > 0)) + kalPerMonStart(prGlueInfo); + + return NETDEV_TX_OK; +} /* end of p2pHardStartXmit() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief A method of struct net_device, a primary SOCKET interface to configure + * the interface lively. Handle an ioctl call on one of our devices. + * Everything Linux ioctl specific is done here. + * Then we pass the contents + * of the ifr->data to the request message handler. + * + * \param[in] prDev Linux kernel netdevice + * + * \param[in] prIFReq Our private ioctl request structure, + * typed for the generic struct ifreq + * so we can use ptr to function + * + * \param[in] cmd Command ID + * + * \retval WLAN_STATUS_SUCCESS The IOCTL command is executed successfully. + * \retval OTHER The execution of IOCTL command is failed. + */ +/*----------------------------------------------------------------------------*/ + +int p2pDoIOCTL(struct net_device *prDev, struct ifreq *prIfReq, int i4Cmd) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int ret = 0; + /* char *prExtraBuf = NULL; */ + /* UINT_32 u4ExtraSize = 0; */ + /* struct iwreq *prIwReq = (struct iwreq *)prIfReq; */ + /* struct iw_request_info rIwReqInfo; */ + + ASSERT(prDev && prIfReq); + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prDev)); + if (!prGlueInfo) { + DBGLOG(P2P, ERROR, "prGlueInfo is NULL\n"); + return -EFAULT; + } + + if (prGlueInfo->u4ReadyFlag == 0) { + DBGLOG(P2P, ERROR, "Adapter is not ready\n"); + return -EINVAL; + } + + if (i4Cmd == SIOCGIWPRIV) { + ret = wext_support_ioctl(prDev, prIfReq, i4Cmd); + } else if ((i4Cmd >= SIOCIWFIRSTPRIV) && (i4Cmd < SIOCIWLASTPRIV)) { + /* 0x8BE0 ~ 0x8BFF, private ioctl region */ + ret = priv_support_ioctl(prDev, prIfReq, i4Cmd); + } else if (i4Cmd == SIOCDEVPRIVATE + 1) { +#ifdef CFG_ANDROID_AOSP_PRIV_CMD + ret = android_private_support_driver_cmd(prDev, prIfReq, i4Cmd); +#else + ret = priv_support_driver_cmd(prDev, prIfReq, i4Cmd); +#endif /* CFG_ANDROID_AOSP_PRIV_CMD */ + } else { + DBGLOG(INIT, WARN, "Unexpected ioctl command: 0x%04x\n", i4Cmd); + ret = -1; + } + +#if 0 + /* fill rIwReqInfo */ + rIwReqInfo.cmd = (__u16) i4Cmd; + rIwReqInfo.flags = 0; + + switch (i4Cmd) { + case SIOCSIWENCODEEXT: + /* Set Encryption Material after 4-way handshaking is done */ + if (prIwReq->u.encoding.pointer) { + u4ExtraSize = prIwReq->u.encoding.length; + prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); + + if (!prExtraBuf) { + ret = -ENOMEM; + break; + } + + if (copy_from_user(prExtraBuf, + prIwReq->u.encoding.pointer, + prIwReq->u.encoding.length)) + ret = -EFAULT; + } else if (prIwReq->u.encoding.length != 0) { + ret = -EINVAL; + break; + } + + if (ret == 0) + ret = mtk_p2p_wext_set_key(prDev, + &rIwReqInfo, + &(prIwReq->u), prExtraBuf); + + kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize); + prExtraBuf = NULL; + break; + + case SIOCSIWMLME: + /* IW_MLME_DISASSOC used for disconnection */ + if (prIwReq->u.data.length != sizeof(struct iw_mlme)) { + DBGLOG(INIT, INFO, + "MLME buffer strange:%d\n", + prIwReq->u.data.length); + ret = -EINVAL; + break; + } + + if (!prIwReq->u.data.pointer) { + ret = -EINVAL; + break; + } + + prExtraBuf = kalMemAlloc(sizeof(struct iw_mlme), VIR_MEM_TYPE); + if (!prExtraBuf) { + ret = -ENOMEM; + break; + } + + if (copy_from_user(prExtraBuf, + prIwReq->u.data.pointer, sizeof(struct iw_mlme))) + ret = -EFAULT; + else + ret = mtk_p2p_wext_mlme_handler(prDev, + &rIwReqInfo, &(prIwReq->u), prExtraBuf); + + kalMemFree(prExtraBuf, VIR_MEM_TYPE, sizeof(struct iw_mlme)); + prExtraBuf = NULL; + break; + + case SIOCGIWPRIV: + /* This ioctl is used to list all IW privilege ioctls */ + ret = mtk_p2p_wext_get_priv(prDev, + &rIwReqInfo, &(prIwReq->u), NULL); + break; + + case SIOCGIWSCAN: + ret = mtk_p2p_wext_discovery_results(prDev, + &rIwReqInfo, &(prIwReq->u), NULL); + break; + + case SIOCSIWAUTH: + ret = mtk_p2p_wext_set_auth(prDev, + &rIwReqInfo, &(prIwReq->u), NULL); + break; + + case IOC_P2P_CFG_DEVICE: + case IOC_P2P_PROVISION_COMPLETE: + case IOC_P2P_START_STOP_DISCOVERY: + case IOC_P2P_DISCOVERY_RESULTS: + case IOC_P2P_WSC_BEACON_PROBE_RSP_IE: + case IOC_P2P_CONNECT_DISCONNECT: + case IOC_P2P_PASSWORD_READY: + case IOC_P2P_GET_STRUCT: + case IOC_P2P_SET_STRUCT: + case IOC_P2P_GET_REQ_DEVICE_INFO: +#if 0 + ret = rP2PIwPrivHandler[i4Cmd - SIOCIWFIRSTPRIV](prDev, + &rIwReqInfo, + &(prIwReq->u), + (char *)&(prIwReq->u)); +#endif + break; +#if CFG_SUPPORT_P2P_RSSI_QUERY + case SIOCGIWSTATS: + ret = mtk_p2p_wext_get_rssi(prDev, + &rIwReqInfo, &(prIwReq->u), NULL); + break; +#endif + default: + ret = -ENOTTY; + } +#endif /* 0 */ + + return ret; +} /* end of p2pDoIOCTL() */ + + +/*---------------------------------------------------------------------------*/ +/*! + * \brief To override p2p interface address + * + * \param[in] prDev Net device requested. + * \param[in] addr Pointer to address + * + * \retval 0 For success. + * \retval -E2BIG For user's buffer size is too small. + * \retval -EFAULT For fail. + * + */ +/*---------------------------------------------------------------------------*/ +int p2pSetMACAddress(IN struct net_device *prDev, void *addr) +{ + struct ADAPTER *prAdapter = NULL; + struct GLUE_INFO *prGlueInfo = NULL; + struct sockaddr *sa = NULL; + struct BSS_INFO *prBssInfo = NULL; + struct BSS_INFO *prDevBssInfo = NULL; + uint8_t ucRoleIdx = 0, ucBssIdx = 0; + struct GL_P2P_INFO *prP2pInfo = NULL; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prDev)); + ASSERT(prGlueInfo); + + prAdapter = prGlueInfo->prAdapter; + ASSERT(prAdapter); + + if (!prDev || !addr) { + DBGLOG(INIT, ERROR, "Set macaddr with ndev(%d) and addr(%d)\n", + (prDev == NULL) ? 0 : 1, (addr == NULL) ? 0 : 1); + return -EINVAL; + } + + if (mtk_Netdev_To_RoleIdx(prGlueInfo, prDev, &ucRoleIdx) != 0) { + DBGLOG(INIT, ERROR, "can't find the matched dev"); + return -EINVAL; + } + + if (p2pFuncRoleToBssIdx(prGlueInfo->prAdapter, + ucRoleIdx, &ucBssIdx) != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, ERROR, "can't find the matched bss"); + return -EINVAL; + } + + prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIdx); + if (!prBssInfo) { + DBGLOG(INIT, ERROR, "bss is not active\n"); + return -EINVAL; + } + + prDevBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, + prAdapter->ucP2PDevBssIdx); + if (!prDevBssInfo) { + DBGLOG(INIT, ERROR, "dev bss is not active\n"); + return -EINVAL; + } + + prP2pInfo = prGlueInfo->prP2PInfo[0]; + if (!prP2pInfo) { + DBGLOG(INIT, ERROR, "p2p info is null\n"); + return -EINVAL; + } + + sa = (struct sockaddr *)addr; + + COPY_MAC_ADDR(prBssInfo->aucOwnMacAddr, sa->sa_data); + COPY_MAC_ADDR(prDev->dev_addr, sa->sa_data); + COPY_MAC_ADDR(prAdapter->rWifiVar.aucInterfaceAddress[ucRoleIdx], + sa->sa_data); + + if ((prP2pInfo->prDevHandler == prDev) + && mtk_IsP2PNetDevice(prGlueInfo, prDev)) { + COPY_MAC_ADDR(prAdapter->rWifiVar.aucDeviceAddress, + sa->sa_data); + COPY_MAC_ADDR(prDevBssInfo->aucOwnMacAddr, sa->sa_data); + DBGLOG(INIT, INFO, + "[%d][%d] Set random macaddr to " MACSTR ".\n", + ucBssIdx, + prDevBssInfo->ucBssIndex, + MAC2STR(prDevBssInfo->aucOwnMacAddr)); + } else { + DBGLOG(INIT, INFO, + "[%d] Set random macaddr to " MACSTR ".\n", + ucBssIdx, + MAC2STR(prBssInfo->aucOwnMacAddr)); + } + + return WLAN_STATUS_SUCCESS; +} + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_p2p_cfg80211.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_p2p_cfg80211.c new file mode 100644 index 0000000000000000000000000000000000000000..ad9a16b340974ac064002a0b5a90c687d5802737 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_p2p_cfg80211.c @@ -0,0 +1,4277 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: @(#) gl_p2p_cfg80211.c@@ + */ + +/*! \file gl_p2p_cfg80211.c + * \brief Main routines of Linux driver interface for Wi-Fi Direct + * using cfg80211 interface + * + * This file contains the main routines of Linux driver + * for MediaTek Inc. 802.11 Wireless LAN Adapters. + */ + + +/****************************************************************************** + * C O M P I L E R F L A G S + ****************************************************************************** + */ + +/****************************************************************************** + * E X T E R N A L R E F E R E N C E S + ****************************************************************************** + */ + +#include "config.h" + +#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_WIFI_DIRECT_CFG_80211 +#include +#include +#include +#include +#include + +#include "precomp.h" +#include "gl_cfg80211.h" +#include "gl_p2p_os.h" + +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-Wformat" +#endif + +/****************************************************************************** + * C O N S T A N T S + ****************************************************************************** + */ + +/****************************************************************************** + * D A T A T Y P E S + ****************************************************************************** + */ + +/****************************************************************************** + * P U B L I C D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * P R I V A T E D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * M A C R O S + ****************************************************************************** + */ + +#if CFG_ENABLE_UNIFY_WIPHY +#define P2P_WIPHY_PRIV(_wiphy, _priv) \ + (_priv = (struct GLUE_INFO *) wiphy_priv(_wiphy)) +#else +#define P2P_WIPHY_PRIV(_wiphy, _priv) \ + (_priv = *((struct GLUE_INFO **) wiphy_priv(_wiphy))) +#endif + +/****************************************************************************** + * F U N C T I O N D E C L A R A T I O N S + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N S + ****************************************************************************** + */ + +int32_t mtk_Netdev_To_RoleIdx(struct GLUE_INFO *prGlueInfo, + struct net_device *ndev, uint8_t *pucRoleIdx) +{ + int32_t i4Ret = -1; + uint32_t u4Idx = 0; + + if ((pucRoleIdx == NULL) || (ndev == NULL)) + return i4Ret; +#if 0 + for (u4Idx = 0; u4Idx < KAL_P2P_NUM; u4Idx++) { + if (prGlP2pInfo->aprRoleHandler[u4Idx] == ndev) { + *pucRoleIdx = (uint8_t) u4Idx; + i4Ret = 0; + } + } +#if 1 + i4Ret = 0; + *pucRoleIdx = 0; +#endif +#else + /* The prP2PInfo[0] may be removed and prP2PInfo[1] is existing + * under cfg80211 operation. So that check all KAL_P2P_NUM not only + * prGlueInfo->prAdapter->prP2pInfo->u4DeviceNum. + */ + for (u4Idx = 0; u4Idx < KAL_P2P_NUM; u4Idx++) { + if ((prGlueInfo->prP2PInfo[u4Idx] != NULL) && + (prGlueInfo->prP2PInfo[u4Idx]->aprRoleHandler != NULL) && + (prGlueInfo->prP2PInfo[u4Idx]->aprRoleHandler == ndev)) { + *pucRoleIdx = (uint8_t) u4Idx; + i4Ret = 0; + } + } +#endif + + return i4Ret; + +} /* mtk_Netdev_To_RoleIdx */ + +static void mtk_vif_destructor(struct net_device *dev) +{ + struct wireless_dev *prWdev = ERR_PTR(-ENOMEM); + uint32_t u4Idx = 0; + + DBGLOG(P2P, INFO, "mtk_vif_destructor\n"); + if (dev) { + prWdev = dev->ieee80211_ptr; + free_netdev(dev); + /* Expect that the gprP2pWdev isn't freed here */ + if ((prWdev) && (prWdev != gprP2pWdev)) { + /* Role[i] and Dev share the same wdev by default */ + for (u4Idx = 0; u4Idx < KAL_P2P_NUM; u4Idx++) { + if (prWdev != gprP2pRoleWdev[u4Idx]) + continue; + /* In the initWlan gprP2pRoleWdev[0] is equal to + * gprP2pWdev. And other gprP2pRoleWdev[] should + * be NULL, if the 2nd P2P dev isn't created. + */ + if (u4Idx == 0) + gprP2pRoleWdev[u4Idx] = gprP2pWdev; + else + gprP2pRoleWdev[u4Idx] = NULL; + break; + } + kfree(prWdev); + } + } +} + +#if KERNEL_VERSION(4, 1, 0) <= CFG80211_VERSION_CODE +struct wireless_dev *mtk_p2p_cfg80211_add_iface(struct wiphy *wiphy, + const char *name, unsigned char name_assign_type, + enum nl80211_iftype type, u32 *flags, struct vif_params *params) +#else +struct wireless_dev *mtk_p2p_cfg80211_add_iface(struct wiphy *wiphy, + const char *name, + enum nl80211_iftype type, u32 *flags, struct vif_params *params) +#endif +{ + /* 2 TODO: Fit kernel 3.10 modification */ + struct ADAPTER *prAdapter; + struct GLUE_INFO *prGlueInfo = NULL; + struct net_device *prNewNetDevice = NULL; + uint32_t u4Idx = 0; + struct GL_P2P_INFO *prP2pInfo = NULL; + struct GL_HIF_INFO *prHif = NULL; + struct MSG_P2P_SWITCH_OP_MODE *prSwitchModeMsg = NULL; + struct wireless_dev *prWdev = NULL; + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = NULL; + struct NETDEV_PRIVATE_GLUE_INFO *prNetDevPriv = NULL; + uint8_t rMacAddr[PARAM_MAC_ADDR_LEN]; + struct MSG_P2P_ACTIVE_DEV_BSS *prMsgActiveBss = NULL; + struct mt66xx_chip_info *prChipInfo; + struct wireless_dev *prOrigWdev = NULL; + + do { + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + + if (prGlueInfo == NULL) + return ERR_PTR(-EINVAL); + + prAdapter = prGlueInfo->prAdapter; + prChipInfo = prAdapter->chip_info; + + for (u4Idx = 0; u4Idx < KAL_P2P_NUM; u4Idx++) { + prP2pInfo = prGlueInfo->prP2PInfo[u4Idx]; + /* Expect that only create the new dev with the p2p0 */ + if (prP2pInfo == NULL) + continue; + if (prP2pInfo->aprRoleHandler == + prP2pInfo->prDevHandler) + break; + if (prP2pInfo->aprRoleHandler == NULL) { + p2pRoleFsmInit(prGlueInfo->prAdapter, u4Idx); + init_completion(&prP2pInfo->rStopApComp); + break; + } + } + + /*u4Idx = 0;*/ + DBGLOG(P2P, TRACE, "%s: u4Idx=%d\n", __func__, u4Idx); + + if (u4Idx == KAL_P2P_NUM) { + /* Role port full. */ + return ERR_PTR(-EINVAL); + } + + prP2pInfo = prGlueInfo->prP2PInfo[u4Idx]; + + /* Alloc all resource here to avoid do unregister_netdev for + * error case (kernel exception). + */ +#if KERNEL_VERSION(3, 18, 0) <= CFG80211_VERSION_CODE + prNewNetDevice = alloc_netdev_mq( + sizeof(struct NETDEV_PRIVATE_GLUE_INFO), name, + NET_NAME_PREDICTABLE, ether_setup, CFG_MAX_TXQ_NUM); +#else + prNewNetDevice = alloc_netdev_mq( + sizeof(struct NETDEV_PRIVATE_GLUE_INFO), name, + ether_setup, CFG_MAX_TXQ_NUM); +#endif + + if (prNewNetDevice == NULL) { + DBGLOG(P2P, ERROR, "can't alloc prNewNetDevice\n"); + break; + } + + prWdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); + if (prWdev == NULL) { + DBGLOG(P2P, ERROR, "can't alloc prWdev\n"); + break; + } + + prSwitchModeMsg = (struct MSG_P2P_SWITCH_OP_MODE *) cnmMemAlloc( + prGlueInfo->prAdapter, RAM_TYPE_MSG, + sizeof(struct MSG_P2P_SWITCH_OP_MODE)); + if (prSwitchModeMsg == NULL) { + DBGLOG(P2P, ERROR, "can't alloc prSwitchModeMsg\n"); + break; + } + + prMsgActiveBss = (struct MSG_P2P_ACTIVE_DEV_BSS *) cnmMemAlloc( + prGlueInfo->prAdapter, RAM_TYPE_MSG, + sizeof(struct MSG_P2P_ACTIVE_DEV_BSS)); + + if (prMsgActiveBss == NULL) { + DBGLOG(P2P, ERROR, "can't alloc prMsgActiveBss\n"); + break; + } + + DBGLOG(P2P, INFO, "type: %d, name = %s, netdev: 0x%p\n", + type, name, prNewNetDevice); + + prP2pInfo->aprRoleHandler = prNewNetDevice; + *((struct GLUE_INFO **) netdev_priv(prNewNetDevice)) = + prGlueInfo; + prNewNetDevice->needed_headroom = + NIC_TX_DESC_AND_PADDING_LENGTH + + prChipInfo->txd_append_size; + prNewNetDevice->netdev_ops = &p2p_netdev_ops; + + prHif = &prGlueInfo->rHifInfo; + ASSERT(prHif); + +#if defined(_HIF_SDIO) +#if (MTK_WCN_HIF_SDIO == 0) + SET_NETDEV_DEV(prNewNetDevice, &(prHif->func->dev)); +#endif +#endif + +#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 + kalMemCopy(prWdev, gprP2pWdev, sizeof(struct wireless_dev)); + prWdev->netdev = prNewNetDevice; + prWdev->iftype = type; + prNewNetDevice->ieee80211_ptr = prWdev; + /* register destructor function for virtual interface */ +#if KERNEL_VERSION(4, 14, 0) <= CFG80211_VERSION_CODE + prNewNetDevice->priv_destructor = mtk_vif_destructor; +#else + prNewNetDevice->destructor = mtk_vif_destructor; +#endif + /* The prOrigWdev is used to do error handle. If return fail, + * set the gprP2pRoleWdev[u4Idx] to original value. + * Expect that the gprP2pRoleWdev[0] = gprP2pWdev, and the + * other is NULL. + */ + prOrigWdev = gprP2pRoleWdev[u4Idx]; + gprP2pRoleWdev[u4Idx] = prWdev; + /*prP2pInfo->prRoleWdev[0] = prWdev;*//* TH3 multiple P2P */ +#endif + +#if CFG_TCP_IP_CHKSUM_OFFLOAD + /* set HW checksum offload */ + if (prAdapter->fgIsSupportCsumOffload) + prNewNetDevice->features |= NETIF_F_IP_CSUM + | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM; +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ + + kalResetStats(prNewNetDevice); + /* net device initialize */ + + /* register for net device */ + if (register_netdevice(prP2pInfo->aprRoleHandler) < 0) { + DBGLOG(INIT, WARN, + "unable to register netdevice for p2p\n"); + break; + + } else { + DBGLOG(P2P, TRACE, "register_netdev OK\n"); + prGlueInfo->prAdapter->rP2PNetRegState = + ENUM_NET_REG_STATE_REGISTERED; + + netif_carrier_off(prP2pInfo->aprRoleHandler); + netif_tx_stop_all_queues(prP2pInfo->aprRoleHandler); + } + prP2pRoleFsmInfo = prAdapter->rWifiVar.aprP2pRoleFsmInfo[u4Idx]; + + /* 13. bind netdev pointer to netdev index */ + wlanBindBssIdxToNetInterface(prGlueInfo, + prP2pRoleFsmInfo->ucBssIndex, + (void *) prP2pInfo->aprRoleHandler); + prNetDevPriv = (struct NETDEV_PRIVATE_GLUE_INFO *) + netdev_priv(prP2pInfo->aprRoleHandler); + prNetDevPriv->prGlueInfo = prGlueInfo; + prNetDevPriv->ucBssIdx = prP2pRoleFsmInfo->ucBssIndex; +#if CFG_ENABLE_UNIFY_WIPHY + /* Expect that only P2P device uses the cfg80211_add_iface */ + prNetDevPriv->ucIsP2p = TRUE; +#endif + + /* 4.2 fill hardware address */ + COPY_MAC_ADDR(rMacAddr, prAdapter->rMyMacAddr); + if (prGlueInfo->prAdapter->rWifiVar.ucP2pShareMacAddr && + (type == NL80211_IFTYPE_P2P_CLIENT + || type == NL80211_IFTYPE_P2P_GO)) { + rMacAddr[0] = gPrP2pDev[0]->dev_addr[0]; + } else { + /* change to local administrated address */ + rMacAddr[0] |= 0x2; + if (u4Idx > 0) + rMacAddr[0] ^= u4Idx << 2; + else + rMacAddr[0] ^= + prGlueInfo->prAdapter + ->prP2pInfo->u4DeviceNum << 2; + } + kalMemCopy(prNewNetDevice->dev_addr, rMacAddr, ETH_ALEN); + kalMemCopy(prNewNetDevice->perm_addr, rMacAddr, ETH_ALEN); + + DBGLOG(P2P, TRACE, + "mtk_p2p_cfg80211_add_iface ucBssIdx=%d\n", + prNetDevPriv->ucBssIdx); + + /* Switch OP MOde. */ + prSwitchModeMsg->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH; + prSwitchModeMsg->ucRoleIdx = 0; + switch (type) { + case NL80211_IFTYPE_P2P_CLIENT: + DBGLOG(P2P, TRACE, "NL80211_IFTYPE_P2P_CLIENT.\n"); + prSwitchModeMsg->eIftype = IFTYPE_P2P_CLIENT; + prSwitchModeMsg->eOpMode = OP_MODE_INFRASTRUCTURE; + kalP2PSetRole(prGlueInfo, 1, u4Idx); + break; + case NL80211_IFTYPE_STATION: + DBGLOG(P2P, TRACE, "NL80211_IFTYPE_STATION.\n"); + prSwitchModeMsg->eIftype = IFTYPE_STATION; + prSwitchModeMsg->eOpMode = OP_MODE_INFRASTRUCTURE; + kalP2PSetRole(prGlueInfo, 1, u4Idx); + break; + case NL80211_IFTYPE_AP: + DBGLOG(P2P, TRACE, "NL80211_IFTYPE_AP.\n"); + prSwitchModeMsg->eIftype = IFTYPE_AP; + prSwitchModeMsg->eOpMode = OP_MODE_ACCESS_POINT; + kalP2PSetRole(prGlueInfo, 2, u4Idx); + break; + case NL80211_IFTYPE_P2P_GO: + DBGLOG(P2P, TRACE, "NL80211_IFTYPE_P2P_GO not AP.\n"); + prSwitchModeMsg->eIftype = IFTYPE_P2P_GO; + prSwitchModeMsg->eOpMode = OP_MODE_ACCESS_POINT; + kalP2PSetRole(prGlueInfo, 2, u4Idx); + break; + default: + DBGLOG(P2P, TRACE, "Other type :%d .\n", type); + prSwitchModeMsg->eIftype = IFTYPE_P2P_DEVICE; + prSwitchModeMsg->eOpMode = OP_MODE_P2P_DEVICE; + kalP2PSetRole(prGlueInfo, 0, u4Idx); + break; + } + mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, + (struct MSG_HDR *) prSwitchModeMsg, + MSG_SEND_METHOD_BUF); + + /* Send Msg to DevFsm and active P2P dev BSS */ + prMsgActiveBss->rMsgHdr.eMsgId = MID_MNY_P2P_ACTIVE_BSS; + mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, + (struct MSG_HDR *) prMsgActiveBss, MSG_SEND_METHOD_BUF); + /* Success */ + return prWdev; + } while (FALSE); + + /* Start Error Handle */ + + if (prNewNetDevice != NULL) { + free_netdev(prNewNetDevice); + prP2pInfo->aprRoleHandler = NULL; + } + + if (prWdev != NULL) { + kfree(prWdev); + + if ((gprP2pRoleWdev[u4Idx] != NULL) && + (gprP2pRoleWdev[u4Idx] != gprP2pWdev)) { + gprP2pRoleWdev[u4Idx] = prOrigWdev; + } + } + + if (prSwitchModeMsg != NULL) + cnmMemFree(prAdapter, prSwitchModeMsg); + + if (prMsgActiveBss != NULL) + cnmMemFree(prAdapter, prMsgActiveBss); + + return ERR_PTR(-ENOMEM); +} /* mtk_p2p_cfg80211_add_iface */ + +int mtk_p2p_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev) +{ +#if 0 + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *) NULL; + struct MSG_P2P_DEL_IFACE *prP2pDelIfaceMsg = + (struct MSG_P2P_DEL_IFACE *) NULL; + struct MSG_P2P_ACTIVE_DEV_BSS *prMsgActiveBss = + (struct MSG_P2P_ACTIVE_DEV_BSS *) NULL; + + prGlueInfo = *((struct GLUE_INFO **) wiphy_priv(wiphy)); + if (prGlueInfo == NULL) + return -EINVAL; + + prP2pDelIfaceMsg = (struct MSG_P2P_DEL_IFACE *) + cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, + sizeof(struct MSG_P2P_DEL_IFACE)); + + if (prP2pDelIfaceMsg == NULL) { + ASSERT(FALSE); + DBGLOG(INIT, WARN, "unable to alloc msg\n"); + } else { + prP2pDelIfaceMsg->rMsgHdr.eMsgId = MID_MNY_P2P_DEL_IFACE; + prP2pDelIfaceMsg->ucRoleIdx = 0; + + mboxSendMsg(prGlueInfo->prAdapter, + MBOX_ID_0, + (struct MSG_HDR *) prP2pDelIfaceMsg, + MSG_SEND_METHOD_BUF); + + /* Send Msg to DevFsm and Deactive P2P dev BSS */ + prMsgActiveBss = cnmMemAlloc(prGlueInfo->prAdapter, + RAM_TYPE_MSG, + sizeof(struct MSG_P2P_ACTIVE_DEV_BSS)); + prMsgActiveBss->rMsgHdr.eMsgId = MID_MNY_P2P_ACTIVE_BSS; + mboxSendMsg(prGlueInfo->prAdapter, + MBOX_ID_0, + (struct MSG_HDR *) prMsgActiveBss, + MSG_SEND_METHOD_BUF); + } + +#else + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *) NULL; + struct MSG_P2P_DEL_IFACE *prP2pDelIfaceMsg = + (struct MSG_P2P_DEL_IFACE *) NULL; + struct ADAPTER *prAdapter; + struct GL_P2P_INFO *prP2pInfo = (struct GL_P2P_INFO *) NULL; + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *) NULL; + struct GL_P2P_DEV_INFO *prP2pGlueDevInfo = + (struct GL_P2P_DEV_INFO *) NULL; + struct net_device *UnregRoleHander = (struct net_device *)NULL; + unsigned char ucBssIdx = 0; + struct BSS_INFO *prP2pBssInfo = NULL; +#if 1 + struct cfg80211_scan_request *prScanRequest = NULL; +#endif + + GLUE_SPIN_LOCK_DECLARATION(); + + DBGLOG(P2P, INFO, "mtk_p2p_cfg80211_del_iface\n"); + + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + + if (prGlueInfo == NULL) + return -EINVAL; + + prAdapter = prGlueInfo->prAdapter; + prP2pInfo = prGlueInfo->prP2PInfo[0]; + prP2pGlueDevInfo = prGlueInfo->prP2PDevInfo; + + if ((prP2pInfo == NULL) || + (prP2pInfo->aprRoleHandler == NULL) || + (prP2pInfo->aprRoleHandler == prP2pInfo->prDevHandler)) { + /* This iface isn't added. */ + return -EINVAL; + } + + KAL_ACQUIRE_MUTEX(prAdapter, MUTEX_DEL_INF); + + prP2pRoleFsmInfo = prAdapter->rWifiVar.aprP2pRoleFsmInfo[0]; + if (prP2pRoleFsmInfo == NULL) { + KAL_RELEASE_MUTEX(prAdapter, MUTEX_DEL_INF); + return -EINVAL; + } + + ucBssIdx = prP2pRoleFsmInfo->ucBssIndex; + wlanBindBssIdxToNetInterface(prGlueInfo, ucBssIdx, + (void *) prGlueInfo->prP2PInfo[0]->prDevHandler); + + UnregRoleHander = prP2pInfo->aprRoleHandler; + + /* fix that the kernel warning occures when the GC is connected */ + prP2pBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIdx); + if ((prP2pBssInfo != NULL) && + (prP2pBssInfo->eConnectionState == MEDIA_STATE_CONNECTED) && + (wdev->iftype == NL80211_IFTYPE_P2P_CLIENT)) { +#if CFG_WPS_DISCONNECT || (KERNEL_VERSION(4, 2, 0) <= CFG80211_VERSION_CODE) + cfg80211_disconnected(UnregRoleHander, 0, NULL, 0, TRUE, + GFP_KERNEL); +#else + cfg80211_disconnected(UnregRoleHander, 0, NULL, 0, GFP_KERNEL); +#endif + } + + /* Wait for kalSendCompleteAndAwakeQueue() complete */ + GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); + prP2pInfo->aprRoleHandler = prP2pInfo->prDevHandler; +#if 1 + prScanRequest = prP2pGlueDevInfo->prScanRequest; + if ((prScanRequest != NULL) && + (prScanRequest->wdev == UnregRoleHander->ieee80211_ptr)) { + kalCfg80211ScanDone(prScanRequest, TRUE); + prP2pGlueDevInfo->prScanRequest = NULL; + } +#else + /* 2017/12/18: This part is for error case that p2p-p2p0-0 which is + * deleted when doing scan causes some exception for scan done action. + * The newest driver doesn't observed this error case, so just do the + * normal scan done process (use prP2pGlueDevInfo->prScanRequest, not + * prP2pGlueDevInfo->rBackupScanRequest). Keep this part for the + * reference, if the exception case occurs again. + * Can reference the related part in the mtk_p2p_cfg80211_scan. + */ + if (prP2pGlueDevInfo->prScanRequest != NULL) { + /* Check the wdev with backup scan req due to */ + /* the kernel will free this request by error handling */ + if (prP2pGlueDevInfo->rBackupScanRequest.wdev + == UnregRoleHander->ieee80211_ptr) { + kalCfg80211ScanDone( + &(prP2pGlueDevInfo->rBackupScanRequest), TRUE); + /* clear the request to avoid the Role FSM + * calls the scan_done again + */ + prP2pGlueDevInfo->prScanRequest = NULL; + } + } +#endif + GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); + + /* prepare for removal */ + if (netif_carrier_ok(UnregRoleHander)) + netif_carrier_off(UnregRoleHander); + + netif_tx_stop_all_queues(UnregRoleHander); + + /* Here are functions which need rtnl_lock */ + unregister_netdevice(UnregRoleHander); + /* free is called at destructor */ + /* free_netdev(UnregRoleHander); */ + + KAL_RELEASE_MUTEX(prAdapter, MUTEX_DEL_INF); + + prP2pDelIfaceMsg = (struct MSG_P2P_DEL_IFACE *) + cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, + sizeof(struct MSG_P2P_DEL_IFACE)); + + if (prP2pDelIfaceMsg == NULL) { + DBGLOG(INIT, WARN, "unable to alloc msg\n"); + } else { + prP2pDelIfaceMsg->rMsgHdr.eMsgId = MID_MNY_P2P_DEL_IFACE; + prP2pDelIfaceMsg->ucRoleIdx = 0; + + mboxSendMsg(prGlueInfo->prAdapter, + MBOX_ID_0, + (struct MSG_HDR *) prP2pDelIfaceMsg, + MSG_SEND_METHOD_BUF); + } +#endif + return 0; +} /* mtk_p2p_cfg80211_del_iface */ + +int mtk_p2p_cfg80211_add_key(struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index, bool pairwise, + const u8 *mac_addr, + struct key_params *params) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4Rslt = -EINVAL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + struct P2P_PARAM_KEY rKey; + uint8_t ucRoleIdx = 0; + const uint8_t aucBCAddr[] = BC_MAC_ADDR; + /* const UINT_8 aucZeroMacAddr[] = NULL_MAC_ADDR; */ + + ASSERT(wiphy); + + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + + if (mtk_Netdev_To_RoleIdx(prGlueInfo, ndev, &ucRoleIdx) != 0) + return -EINVAL; + + DBGLOG(RSN, TRACE, "mtk_p2p_cfg80211_add_key\n"); +#if DBG + if (mac_addr) { + DBGLOG(RSN, INFO, + "keyIdx = %d pairwise = %d mac = " MACSTR "\n", + key_index, pairwise, MAC2STR(mac_addr)); + } else { + DBGLOG(RSN, INFO, + "keyIdx = %d pairwise = %d null mac\n", + key_index, pairwise); + } + DBGLOG(RSN, TRACE, "Cipher = %x\n", params->cipher); + DBGLOG_MEM8(RSN, TRACE, params->key, params->key_len); +#endif + + if (params->key_len > 32) { + DBGLOG(RSN, WARN, "key_len [%d] is invalid!\n", + params->key_len); + return -EINVAL; + } + + /* Todo:: By Cipher to set the key */ + + kalMemZero(&rKey, sizeof(struct P2P_PARAM_KEY)); + + if (p2pFuncRoleToBssIdx(prGlueInfo->prAdapter, + ucRoleIdx, &rKey.ucBssIdx) != WLAN_STATUS_SUCCESS) + return -EINVAL; + + rKey.u4KeyIndex = key_index; + + if (params->cipher) { + switch (params->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + rKey.ucCipher = CIPHER_SUITE_WEP40; + break; + case WLAN_CIPHER_SUITE_WEP104: + rKey.ucCipher = CIPHER_SUITE_WEP104; + break; +#if 0 + case WLAN_CIPHER_SUITE_WEP128: + rKey.ucCipher = CIPHER_SUITE_WEP128; + break; +#endif + case WLAN_CIPHER_SUITE_TKIP: + rKey.ucCipher = CIPHER_SUITE_TKIP; + break; + case WLAN_CIPHER_SUITE_CCMP: + rKey.ucCipher = CIPHER_SUITE_CCMP; + break; +#if 0 + case WLAN_CIPHER_SUITE_GCMP: + rKey.ucCipher = CIPHER_SUITE_GCMP; + break; + case WLAN_CIPHER_SUITE_CCMP_256: + rKey.ucCipher = CIPHER_SUITE_CCMP256; + break; +#endif + case WLAN_CIPHER_SUITE_SMS4: + rKey.ucCipher = CIPHER_SUITE_WPI; + break; + case WLAN_CIPHER_SUITE_AES_CMAC: + rKey.ucCipher = CIPHER_SUITE_BIP; + break; + default: + ASSERT(FALSE); + } + } + + /* For BC addr case: ex: AP mode, + * driver_nl80211 will not have mac_addr + */ + if (pairwise) { + rKey.u4KeyIndex |= BIT(31); /* Tx */ + rKey.u4KeyIndex |= BIT(30); /* Pairwise */ + COPY_MAC_ADDR(rKey.arBSSID, mac_addr); + } else { + COPY_MAC_ADDR(rKey.arBSSID, aucBCAddr); + } + + /* Check if add key under AP mode */ + if (kalP2PGetRole(prGlueInfo, ucRoleIdx) == 2) + rKey.u4KeyIndex |= BIT(28); /* authenticator */ + + + if (params->key) + kalMemCopy(rKey.aucKeyMaterial, params->key, params->key_len); + rKey.u4KeyLength = params->key_len; + rKey.u4Length = OFFSET_OF(struct P2P_PARAM_KEY, aucKeyMaterial) + + rKey.u4KeyLength; + + rStatus = kalIoctl(prGlueInfo, + wlanoidSetAddKey, + &rKey, rKey.u4Length, FALSE, FALSE, TRUE, &u4BufLen); + + if (rStatus == WLAN_STATUS_SUCCESS) + i4Rslt = 0; + + return i4Rslt; +} + +int mtk_p2p_cfg80211_get_key(struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index, + bool pairwise, + const u8 *mac_addr, void *cookie, + void (*callback) + (void *cookie, struct key_params *)) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + ASSERT(wiphy); + + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + + /* not implemented yet */ + DBGLOG(RSN, INFO, "not support this func\n"); + + return -EINVAL; +} + +int mtk_p2p_cfg80211_del_key(struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index, bool pairwise, const u8 *mac_addr) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_REMOVE_KEY rRemoveKey; + int32_t i4Rslt = -EINVAL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + uint8_t ucRoleIdx = 0; + + ASSERT(wiphy); + + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + DBGLOG(RSN, TRACE, "mtk_p2p_cfg80211_del_key\n"); + + if (mtk_Netdev_To_RoleIdx(prGlueInfo, ndev, &ucRoleIdx) < 0) + return -EINVAL; +#if DBG + if (mac_addr) { + DBGLOG(RSN, TRACE, + "keyIdx = %d pairwise = %d mac = " MACSTR "\n", + key_index, pairwise, MAC2STR(mac_addr)); + } else { + DBGLOG(RSN, TRACE, + "keyIdx = %d pairwise = %d null mac\n", + key_index, pairwise); + } +#endif + + kalMemZero(&rRemoveKey, sizeof(struct PARAM_REMOVE_KEY)); + + if (p2pFuncRoleToBssIdx(prGlueInfo->prAdapter, + ucRoleIdx, &rRemoveKey.ucBssIdx) != WLAN_STATUS_SUCCESS) + return -EINVAL; + + if (mac_addr) + COPY_MAC_ADDR(rRemoveKey.arBSSID, mac_addr); + rRemoveKey.u4KeyIndex = key_index; + rRemoveKey.u4Length = sizeof(struct PARAM_REMOVE_KEY); + if (mac_addr) { + COPY_MAC_ADDR(rRemoveKey.arBSSID, mac_addr); + rRemoveKey.u4KeyIndex |= BIT(30); + } + + rStatus = kalIoctl(prGlueInfo, + wlanoidSetRemoveKey, + &rRemoveKey, rRemoveKey.u4Length, + FALSE, FALSE, TRUE, &u4BufLen); + + if (rStatus == WLAN_STATUS_SUCCESS) + i4Rslt = 0; + + return i4Rslt; +} + +int +mtk_p2p_cfg80211_set_default_key(struct wiphy *wiphy, + struct net_device *netdev, + u8 key_index, bool unicast, bool multicast) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_DEFAULT_KEY rDefaultKey; + uint8_t ucRoleIdx = 0; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + int32_t i4Rst = -EINVAL; + uint32_t u4BufLen = 0; + u_int8_t fgDef = FALSE, fgMgtDef = FALSE; + + ASSERT(wiphy); + + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + DBGLOG(RSN, TRACE, "mtk_p2p_cfg80211_set_default_key\n"); + + if (mtk_Netdev_To_RoleIdx(prGlueInfo, netdev, &ucRoleIdx) != 0) + return -EINVAL; +#if DBG + DBGLOG(RSN, TRACE, + "keyIdx = %d unicast = %d multicast = %d\n", + key_index, unicast, multicast); +#endif + + + /* For wep case, this set the key for tx */ + if (p2pFuncRoleToBssIdx(prGlueInfo->prAdapter, + ucRoleIdx, &rDefaultKey.ucBssIdx) != WLAN_STATUS_SUCCESS) + return -EINVAL; + + + rDefaultKey.ucKeyID = key_index; + rDefaultKey.ucUnicast = unicast; + rDefaultKey.ucMulticast = multicast; + if (rDefaultKey.ucUnicast && !rDefaultKey.ucMulticast) + return WLAN_STATUS_SUCCESS; + + if (rDefaultKey.ucUnicast && rDefaultKey.ucMulticast) + fgDef = TRUE; + + if (!rDefaultKey.ucUnicast && rDefaultKey.ucMulticast) + fgMgtDef = TRUE; + + rStatus = kalIoctl(prGlueInfo, + wlanoidSetDefaultKey, + &rDefaultKey, + sizeof(struct PARAM_DEFAULT_KEY), + FALSE, FALSE, TRUE, &u4BufLen); + + + if (rStatus == WLAN_STATUS_SUCCESS) + i4Rst = 0; + + + return i4Rst; +} + +/*---------------------------------------------------------------------------*/ +/*! + * @brief This routine is responsible for setting the default mgmt key index + * + * @param + * + * @retval 0: successful + * others: failure + */ +/*---------------------------------------------------------------------------*/ +int mtk_p2p_cfg80211_set_mgmt_key(struct wiphy *wiphy, + struct net_device *dev, u8 key_index) +{ + DBGLOG(RSN, INFO, "mtk_p2p_cfg80211_set_mgmt_key, kid:%d\n", key_index); + + return 0; +} + +#if KERNEL_VERSION(3, 16, 0) <= CFG80211_VERSION_CODE +int mtk_p2p_cfg80211_get_station(struct wiphy *wiphy, + struct net_device *ndev, + const u8 *mac, struct station_info *sinfo) +#else +int mtk_p2p_cfg80211_get_station(struct wiphy *wiphy, + struct net_device *ndev, + u8 *mac, struct station_info *sinfo) +#endif +{ + int32_t i4RetRslt = -EINVAL; + int32_t i4Rssi = 0; + uint8_t ucRoleIdx = 0; + uint8_t ucBssIdx = 0; + uint32_t u4Rate = 0; + uint32_t u4BufLen = 0; + uint32_t rStatus; + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *) NULL; + struct GL_P2P_INFO *prP2pGlueInfo = (struct GL_P2P_INFO *) NULL; + struct P2P_STATION_INFO rP2pStaInfo; + struct BSS_INFO *prBssInfo; + struct PARAM_LINK_SPEED_EX rLinkSpeed; + + ASSERT(wiphy); + + do { + if ((wiphy == NULL) || (ndev == NULL) + || (sinfo == NULL) || (mac == NULL)) + break; + + DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_get_station\n"); + + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + + if (mtk_Netdev_To_RoleIdx(prGlueInfo, ndev, &ucRoleIdx) != 0) + return -EINVAL; + + prP2pGlueInfo = prGlueInfo->prP2PInfo[ucRoleIdx]; + + /* Get station information. */ + /* 1. Inactive time? */ + p2pFuncGetStationInfo(prGlueInfo->prAdapter, + (uint8_t *)mac, &rP2pStaInfo); + + /* Inactive time. */ +#if KERNEL_VERSION(4, 0, 0) <= CFG80211_VERSION_CODE + sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME); +#else + sinfo->filled |= STATION_INFO_INACTIVE_TIME; +#endif + sinfo->inactive_time = rP2pStaInfo.u4InactiveTime; + sinfo->generation = prP2pGlueInfo->i4Generation; + + /* 2. fill TX rate */ + if (p2pFuncRoleToBssIdx(prGlueInfo->prAdapter, + ucRoleIdx, &ucBssIdx) != WLAN_STATUS_SUCCESS) + return -EINVAL; + prBssInfo = + GET_BSS_INFO_BY_INDEX(prGlueInfo->prAdapter, ucBssIdx); + if (!prBssInfo) { + DBGLOG(P2P, WARN, "bss is not active\n"); + return -EINVAL; + } + if (prBssInfo->eConnectionState + != MEDIA_STATE_CONNECTED) { + /* not connected */ + DBGLOG(P2P, WARN, "not yet connected\n"); + return 0; + } + + rStatus = kalIoctlByBssIdx(prGlueInfo, + wlanoidQueryLinkSpeedEx, + &rLinkSpeed, sizeof(rLinkSpeed), + TRUE, FALSE, FALSE, + &u4BufLen, ucBssIdx); + if (rStatus == WLAN_STATUS_SUCCESS + && ucBssIdx < BSSID_NUM) { + u4Rate = rLinkSpeed.rLq[ucBssIdx].u2LinkSpeed; + i4Rssi = rLinkSpeed.rLq[ucBssIdx].cRssi; + } + + if (i4Rssi > PARAM_WHQL_RSSI_MAX_DBM) + i4Rssi = PARAM_WHQL_RSSI_MAX_DBM; + else if (i4Rssi < PARAM_WHQL_RSSI_MIN_DBM) + i4Rssi = PARAM_WHQL_RSSI_MIN_DBM; + /* convert from 100bps to 100kbps */ + sinfo->txrate.legacy = u4Rate / 1000; + sinfo->signal = i4Rssi; + + DBGLOG(P2P, INFO, + "ucRoleIdx = %d, rate = %u, signal = %d\n", + ucRoleIdx, + sinfo->txrate.legacy, + sinfo->signal); + +#if KERNEL_VERSION(4, 0, 0) <= CFG80211_VERSION_CODE + sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE); + sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL); +#else + sinfo->filled |= STATION_INFO_TX_BITRATE; + sinfo->filled |= STATION_INFO_SIGNAL; +#endif + + i4RetRslt = 0; + } while (FALSE); + + return i4RetRslt; +} + +int mtk_p2p_cfg80211_scan(struct wiphy *wiphy, + struct cfg80211_scan_request *request) +{ + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *) NULL; + struct GL_P2P_INFO *prP2pGlueInfo = (struct GL_P2P_INFO *) NULL; + struct GL_P2P_DEV_INFO *prP2pGlueDevInfo = + (struct GL_P2P_DEV_INFO *) NULL; + struct MSG_P2P_SCAN_REQUEST *prMsgScanRequest = ( + struct MSG_P2P_SCAN_REQUEST *) NULL; + uint32_t u4MsgSize = 0, u4Idx = 0; + int32_t i4RetRslt = -EINVAL; + struct RF_CHANNEL_INFO *prRfChannelInfo = + (struct RF_CHANNEL_INFO *) NULL; + struct P2P_SSID_STRUCT *prSsidStruct = (struct P2P_SSID_STRUCT *) NULL; + struct ieee80211_channel *prChannel = NULL; + struct cfg80211_ssid *prSsid = NULL; + uint8_t ucBssIdx = 0; + uint8_t ucRoleIdx = 0; + u_int8_t fgIsFullChanScan = FALSE; + uint32_t u4SetInfoLen = 0; + uint32_t rStatus; + + /* [-----Channel-----] [-----SSID-----][-----IE-----] */ + + do { + if ((wiphy == NULL) || (request == NULL)) + break; + + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + + if (wlanIsChipAssert(prGlueInfo->prAdapter)) + break; + + prP2pGlueInfo = prGlueInfo->prP2PInfo[0]; + prP2pGlueDevInfo = prGlueInfo->prP2PDevInfo; + + if ((prP2pGlueInfo == NULL) || (prP2pGlueDevInfo == NULL)) { + ASSERT(FALSE); + break; + } + + DBGLOG(P2P, TRACE, "netdev: %p.\n", request->wdev->netdev); + + if (prP2pGlueDevInfo->prScanRequest != NULL) { + /* There have been a scan request + * on-going processing. + */ + DBGLOG(P2P, ERROR, + "There have been a scan request on-going processing.\n"); + break; + } + + /* Should find out why the n_channels so many? */ + if (request->n_channels > MAXIMUM_OPERATION_CHANNEL_LIST) { + request->n_channels = MAXIMUM_OPERATION_CHANNEL_LIST; + fgIsFullChanScan = TRUE; + DBGLOG(P2P, TRACE, + "Channel list exceed the maximun support.\n"); + } + + if (prP2pGlueInfo->aprRoleHandler != + prP2pGlueInfo->prDevHandler) { + if (mtk_Netdev_To_RoleIdx(prGlueInfo, + request->wdev->netdev, + &ucRoleIdx) < 0) { + ucBssIdx = + prGlueInfo->prAdapter->ucP2PDevBssIdx; + } else { + ASSERT(ucRoleIdx < KAL_P2P_NUM); + if (p2pFuncRoleToBssIdx(prGlueInfo->prAdapter, + ucRoleIdx, &ucBssIdx) != + WLAN_STATUS_SUCCESS) { + DBGLOG(P2P, ERROR, + "Can't find BSS index.\n"); + break; + } + } + } else { + ucBssIdx = prGlueInfo->prAdapter->ucP2PDevBssIdx; + } + + u4MsgSize = sizeof(struct MSG_P2P_SCAN_REQUEST) + + (request->n_channels * sizeof(struct RF_CHANNEL_INFO)) + + (request->n_ssids * sizeof(struct PARAM_SSID)) + + request->ie_len; + + prMsgScanRequest = cnmMemAlloc(prGlueInfo->prAdapter, + RAM_TYPE_MSG, u4MsgSize); + + if (prMsgScanRequest == NULL) { + i4RetRslt = -ENOMEM; + break; + } + + DBGLOG(P2P, TRACE, "Generating scan request message.\n"); + + prMsgScanRequest->rMsgHdr.eMsgId = MID_MNY_P2P_DEVICE_DISCOVERY; + prMsgScanRequest->eScanType = SCAN_TYPE_ACTIVE_SCAN; + prMsgScanRequest->ucBssIdx = ucBssIdx; + + DBGLOG(P2P, INFO, + "[%u] Requesting channel number:%d.\n", + ucBssIdx, request->n_channels); + + for (u4Idx = 0; u4Idx < request->n_channels; u4Idx++) { + /* Translate Freq from MHz to channel number. */ + prRfChannelInfo = + &(prMsgScanRequest->arChannelListInfo[u4Idx]); + prChannel = request->channels[u4Idx]; + + prRfChannelInfo->ucChannelNum = + nicFreq2ChannelNum( + prChannel->center_freq * 1000); + + DBGLOG(P2P, TRACE, + "Scanning Channel:%d, freq: %d\n", + prRfChannelInfo->ucChannelNum, + prChannel->center_freq); + + switch (prChannel->band) { + case KAL_BAND_2GHZ: + prRfChannelInfo->eBand = BAND_2G4; + break; + case KAL_BAND_5GHZ: + prRfChannelInfo->eBand = BAND_5G; + break; + default: + DBGLOG(P2P, TRACE, + "UNKNOWN Band info from supplicant\n"); + prRfChannelInfo->eBand = BAND_NULL; + break; + } + + /* Iteration. */ + prRfChannelInfo++; + } + prMsgScanRequest->u4NumChannel = request->n_channels; + if (fgIsFullChanScan) { + prMsgScanRequest->u4NumChannel = + SCN_P2P_FULL_SCAN_PARAM; + DBGLOG(P2P, INFO, + "request->n_channels = SCN_P2P_FULL_SCAN_PARAM\n"); + } + DBGLOG(P2P, TRACE, "Finish channel list.\n"); + + /* SSID */ + prSsid = request->ssids; + prSsidStruct = (struct P2P_SSID_STRUCT *) prRfChannelInfo; + if (request->n_ssids) { + ASSERT((unsigned long) prSsidStruct + == (unsigned long) + &(prMsgScanRequest->arChannelListInfo[u4Idx])); + + prMsgScanRequest->prSSID = prSsidStruct; + } + + for (u4Idx = 0; u4Idx < request->n_ssids; u4Idx++) { + COPY_SSID(prSsidStruct->aucSsid, + prSsidStruct->ucSsidLen, + request->ssids->ssid, + request->ssids->ssid_len); + + prSsidStruct++; + prSsid++; + } + + prMsgScanRequest->i4SsidNum = request->n_ssids; + + DBGLOG(P2P, TRACE, "Finish SSID list:%d.\n", request->n_ssids); + + /* IE BUFFERS */ + prMsgScanRequest->pucIEBuf = (uint8_t *) prSsidStruct; + if (request->ie_len) { + kalMemCopy(prMsgScanRequest->pucIEBuf, + request->ie, request->ie_len); + prMsgScanRequest->u4IELen = request->ie_len; + } else { + prMsgScanRequest->u4IELen = 0; + } + + DBGLOG(P2P, TRACE, "Finish IE Buffer.\n"); + + /* Abort previous scan */ + rStatus = kalIoctl(prGlueInfo, + wlanoidAbortP2pScan, + &ucBssIdx, sizeof(ucBssIdx), + FALSE, FALSE, TRUE, &u4SetInfoLen); + + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(REQ, ERROR, + "mtk_p2p_cfg80211_scan abort scan fail 0x%x\n", + rStatus); + + prP2pGlueDevInfo->prScanRequest = request; + + mboxSendMsg(prGlueInfo->prAdapter, + MBOX_ID_0, + (struct MSG_HDR *) prMsgScanRequest, + MSG_SEND_METHOD_BUF); + + /* Backup scan request structure */ + /* The purpose of this backup is due + * to the kernel free the scan req + * when the wpa supplicant down the iface before down, + * and it will free the original scan request structure + * In this case, the scan resoure could be locked by kernel, + * and driver needs this work around to clear the state + */ +#if 0 + kalMemCopy(&(prP2pGlueDevInfo->rBackupScanRequest), + prP2pGlueDevInfo->prScanRequest, + sizeof(struct cfg80211_scan_request)); +#endif + i4RetRslt = 0; + } while (FALSE); + + return i4RetRslt; +} /* mtk_p2p_cfg80211_scan */ + +void mtk_p2p_cfg80211_abort_scan(struct wiphy *wiphy, + struct wireless_dev *wdev) +{ + uint32_t u4SetInfoLen = 0; + uint32_t rStatus; + struct GL_P2P_DEV_INFO *prP2pGlueDevInfo; + struct GLUE_INFO *prGlueInfo = NULL; + struct GL_P2P_INFO *prP2pGlueInfo = NULL; + uint8_t ucBssIdx = 0; + uint8_t ucRoleIdx = 0; + + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + prP2pGlueInfo = prGlueInfo->prP2PInfo[0]; + prP2pGlueDevInfo = prGlueInfo->prP2PDevInfo; + + if (!prP2pGlueDevInfo->prScanRequest) { + DBGLOG(P2P, ERROR, "no pending scan request.\n"); + return; + } + + if (prP2pGlueInfo->aprRoleHandler != + prP2pGlueInfo->prDevHandler) { + if (mtk_Netdev_To_RoleIdx(prGlueInfo, wdev->netdev, + &ucRoleIdx) < 0) { + /* Device Interface. */ + ucBssIdx = + prGlueInfo->prAdapter->ucP2PDevBssIdx; + } else { + ASSERT(ucRoleIdx < KAL_P2P_NUM); + if (p2pFuncRoleToBssIdx(prGlueInfo->prAdapter, + ucRoleIdx, &ucBssIdx) != + WLAN_STATUS_SUCCESS) { + DBGLOG(P2P, ERROR, + "Can't find BSS index.\n"); + return; + } + } + } else { + ucBssIdx = prGlueInfo->prAdapter->ucP2PDevBssIdx; + } + + DBGLOG(P2P, INFO, "netdev: %p, ucBssIdx: %u\n", wdev->netdev, ucBssIdx); + + rStatus = kalIoctl(prGlueInfo, + wlanoidAbortP2pScan, + &ucBssIdx, sizeof(ucBssIdx), + FALSE, FALSE, TRUE, &u4SetInfoLen); + + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(REQ, ERROR, + "mtk_p2p_cfg80211_abort_scan fail 0x%x\n", + rStatus); +} + +int mtk_p2p_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) +{ + int32_t i4Rslt = -EINVAL; + struct GLUE_INFO *prGlueInfo = NULL; + + do { + if (wiphy == NULL) + break; + + DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_set_wiphy_params\n"); + + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + + if (changed & WIPHY_PARAM_RETRY_SHORT) { + /* TODO: */ + DBGLOG(P2P, TRACE, + "The RETRY short param is changed.\n"); + } + + if (changed & WIPHY_PARAM_RETRY_LONG) { + /* TODO: */ + DBGLOG(P2P, TRACE, + "The RETRY long param is changed.\n"); + } + + if (changed & WIPHY_PARAM_FRAG_THRESHOLD) { + /* TODO: */ + DBGLOG(P2P, TRACE, + "The RETRY fragmentation threshold is changed.\n"); + } + + if (changed & WIPHY_PARAM_RTS_THRESHOLD) { + /* TODO: */ + DBGLOG(P2P, TRACE, + "The RETRY RTS threshold is changed.\n"); + } + + if (changed & WIPHY_PARAM_COVERAGE_CLASS) { + /* TODO: */ + DBGLOG(P2P, TRACE, + "The coverage class is changed???\n"); + } + + i4Rslt = 0; + } while (FALSE); + + return i4Rslt; +} /* mtk_p2p_cfg80211_set_wiphy_params */ + +int mtk_p2p_cfg80211_join_ibss(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_ibss_params *params) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + ASSERT(wiphy); + + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + + DBGLOG(P2P, INFO, "not support now\n"); + /* not implemented yet */ + + return -EINVAL; +} + +int mtk_p2p_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + ASSERT(wiphy); + + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + + DBGLOG(P2P, INFO, "not support now\n"); + /* not implemented yet */ + + return -EINVAL; +} + +int mtk_p2p_cfg80211_set_txpower(struct wiphy *wiphy, + struct wireless_dev *wdev, + enum nl80211_tx_power_setting type, int mbm) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + ASSERT(wiphy); + + DBGLOG(P2P, INFO, "%s: not support now\n", __func__); + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + + /* not implemented yet */ + + return -EINVAL; +} + +int mtk_p2p_cfg80211_get_txpower(struct wiphy *wiphy, + struct wireless_dev *wdev, int *dbm) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + ASSERT(wiphy); + + DBGLOG(P2P, TRACE, "%s: not support now\n", __func__); + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + + /* not implemented yet */ + + return -EINVAL; +} + +int mtk_p2p_cfg80211_set_power_mgmt(struct wiphy *wiphy, + struct net_device *ndev, bool enabled, int timeout) +{ + struct GLUE_INFO *prGlueInfo = NULL; + enum PARAM_POWER_MODE ePowerMode; + struct PARAM_POWER_MODE_ rPowerMode; + uint32_t rStatus; + uint32_t u4Leng; + uint8_t ucRoleIdx; + + ASSERT(wiphy); + + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + + if (enabled) + ePowerMode = Param_PowerModeFast_PSP; + else + ePowerMode = Param_PowerModeCAM; + + DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_set_power_mgmt ps=%d.\n", enabled); + + if (mtk_Netdev_To_RoleIdx(prGlueInfo, + ndev, &ucRoleIdx) != 0) + return -EINVAL; + + if (p2pFuncRoleToBssIdx(prGlueInfo->prAdapter, + ucRoleIdx, &rPowerMode.ucBssIdx) != WLAN_STATUS_SUCCESS) + return -EINVAL; + + rPowerMode.ePowerMode = ePowerMode; + + /* p2p_set_power_save */ + rStatus = kalIoctl(prGlueInfo, + wlanoidSet802dot11PowerSaveProfile, + &rPowerMode, sizeof(rPowerMode), + FALSE, FALSE, TRUE, &u4Leng); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, WARN, "set_power_mgmt error:%x\n", rStatus); + return -EFAULT; + } + + return 0; +} + +int mtk_p2p_cfg80211_start_ap(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_ap_settings *settings) +{ + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *) NULL; + int32_t i4Rslt = -EINVAL; + struct MSG_P2P_BEACON_UPDATE *prP2pBcnUpdateMsg = + (struct MSG_P2P_BEACON_UPDATE *) NULL; + struct MSG_P2P_START_AP *prP2pStartAPMsg = + (struct MSG_P2P_START_AP *) NULL; + uint8_t *pucBuffer = (uint8_t *) NULL; + uint8_t ucRoleIdx = 0; + struct cfg80211_chan_def *chandef; + struct RF_CHANNEL_INFO rRfChnlInfo; + + /* RF_CHANNEL_INFO_T rRfChnlInfo; */ +/* P_IE_SSID_T prSsidIE = (P_IE_SSID_T)NULL; */ + + do { + if ((wiphy == NULL) || (settings == NULL)) + break; + + DBGLOG(P2P, INFO, "inactivity_timeout: %d\n", + settings->inactivity_timeout); + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + + /*DFS todo 20161220_DFS*/ + netif_carrier_on(dev); + netif_tx_start_all_queues(dev); + + chandef = &settings->chandef; + + if (mtk_Netdev_To_RoleIdx(prGlueInfo, dev, &ucRoleIdx) < 0) + break; + + if (chandef) { + kalChannelFormatSwitch(chandef, chandef->chan, + &rRfChnlInfo); + + DBGLOG(P2P, INFO, "pri: %d, s1: %d, s2: %d, bw: %d\n", + rRfChnlInfo.u2PriChnlFreq, + rRfChnlInfo.u4CenterFreq1, + rRfChnlInfo.u4CenterFreq2, + rRfChnlInfo.ucChnlBw); + + /* Follow the channel info from wifi.cfg + * prior to hostapd.conf + */ + { + struct ADAPTER *prAdapter = + (struct ADAPTER *) NULL; + struct WIFI_VAR *prWifiVar = + (struct WIFI_VAR *)NULL; + + prAdapter = prGlueInfo->prAdapter; + prWifiVar = &prAdapter->rWifiVar; + + if ((prWifiVar->ucApChannel != 0) && + (prWifiVar->ucApChnlDefFromCfg != 0) && + (prWifiVar->ucApChannel != + rRfChnlInfo.ucChannelNum)) { + rRfChnlInfo.ucChannelNum = + prWifiVar->ucApChannel; + rRfChnlInfo.eBand = + (rRfChnlInfo.ucChannelNum <= 14) + ? BAND_2G4 : BAND_5G; + /* [TODO][20160829]If we will set SCO + * by nl80211_channel_type afterward, + * to check if we need to modify SCO + * by wifi.cfg here + */ + } + } + + p2pFuncSetChannel(prGlueInfo->prAdapter, + ucRoleIdx, &rRfChnlInfo); + } else + DBGLOG(P2P, INFO, "!!! no CH def!!!\n"); + + prP2pBcnUpdateMsg = (struct MSG_P2P_BEACON_UPDATE *) + cnmMemAlloc(prGlueInfo->prAdapter, + RAM_TYPE_MSG, + (sizeof(struct MSG_P2P_BEACON_UPDATE) + + + settings->beacon.head_len + + settings->beacon.tail_len + + settings->beacon.assocresp_ies_len +#if CFG_SUPPORT_P2P_GO_OFFLOAD_PROBE_RSP + + settings->beacon.proberesp_ies_len +#endif + )); + + if (prP2pBcnUpdateMsg == NULL) { + i4Rslt = -ENOMEM; + break; + } + + prP2pBcnUpdateMsg->ucRoleIndex = ucRoleIdx; + prP2pBcnUpdateMsg->rMsgHdr.eMsgId = MID_MNY_P2P_BEACON_UPDATE; + pucBuffer = prP2pBcnUpdateMsg->aucBuffer; + +#if (CFG_SUPPORT_DFS_MASTER == 1) + if (p2pFuncGetDfsState() == DFS_STATE_DETECTED) + p2pFuncSetDfsState(DFS_STATE_INACTIVE); +#endif + if (settings->beacon.head_len != 0) { + kalMemCopy(pucBuffer, + settings->beacon.head, + settings->beacon.head_len); + + prP2pBcnUpdateMsg->u4BcnHdrLen = + settings->beacon.head_len; + + prP2pBcnUpdateMsg->pucBcnHdr = pucBuffer; + + pucBuffer += settings->beacon.head_len; + } else { + prP2pBcnUpdateMsg->u4BcnHdrLen = 0; + + prP2pBcnUpdateMsg->pucBcnHdr = NULL; + } + + if (settings->beacon.tail_len != 0) { + prP2pBcnUpdateMsg->pucBcnBody = pucBuffer; + kalMemCopy(pucBuffer, + settings->beacon.tail, + settings->beacon.tail_len); + + prP2pBcnUpdateMsg->u4BcnBodyLen = + settings->beacon.tail_len; + + pucBuffer += settings->beacon.tail_len; + } else { + prP2pBcnUpdateMsg->u4BcnBodyLen = 0; + + prP2pBcnUpdateMsg->pucBcnBody = NULL; + } + + if ((settings->crypto.cipher_group == + WLAN_CIPHER_SUITE_WEP40) || + (settings->crypto.cipher_group == + WLAN_CIPHER_SUITE_WEP104)) + prP2pBcnUpdateMsg->fgIsWepCipher = TRUE; + else + prP2pBcnUpdateMsg->fgIsWepCipher = FALSE; + + if (settings->beacon.assocresp_ies_len != 0 + && settings->beacon.assocresp_ies != NULL) { + prP2pBcnUpdateMsg->pucAssocRespIE = pucBuffer; + kalMemCopy(pucBuffer, + settings->beacon.assocresp_ies, + settings->beacon.assocresp_ies_len); + prP2pBcnUpdateMsg->u4AssocRespLen = + settings->beacon.assocresp_ies_len; + } else { + prP2pBcnUpdateMsg->u4AssocRespLen = 0; + prP2pBcnUpdateMsg->pucAssocRespIE = NULL; + } + +#if CFG_SUPPORT_P2P_GO_OFFLOAD_PROBE_RSP + if (settings->beacon.proberesp_ies_len != 0 + && settings->beacon.proberesp_ies != NULL) { + prP2pBcnUpdateMsg->pucProbeRespIE = pucBuffer; + kalMemCopy(pucBuffer, + settings->beacon.proberesp_ies, + settings->beacon.proberesp_ies_len); + prP2pBcnUpdateMsg->u4ProbeRespLen = + settings->beacon.proberesp_ies_len; + } else { + prP2pBcnUpdateMsg->u4ProbeRespLen = 0; + prP2pBcnUpdateMsg->pucProbeRespIE = NULL; + } +#endif + + mboxSendMsg(prGlueInfo->prAdapter, + MBOX_ID_0, + (struct MSG_HDR *) prP2pBcnUpdateMsg, + MSG_SEND_METHOD_BUF); + + prP2pStartAPMsg = (struct MSG_P2P_START_AP *) + cnmMemAlloc(prGlueInfo->prAdapter, + RAM_TYPE_MSG, sizeof(struct MSG_P2P_START_AP)); + + if (prP2pStartAPMsg == NULL) { + i4Rslt = -ENOMEM; + break; + } + + prP2pStartAPMsg->rMsgHdr.eMsgId = MID_MNY_P2P_START_AP; + + prP2pStartAPMsg->fgIsPrivacy = settings->privacy; + + prP2pStartAPMsg->u4BcnInterval = settings->beacon_interval; + + prP2pStartAPMsg->u4DtimPeriod = settings->dtim_period; + + /* Copy NO SSID. */ + prP2pStartAPMsg->ucHiddenSsidType = settings->hidden_ssid; + + prP2pStartAPMsg->ucRoleIdx = ucRoleIdx; + + kalP2PSetRole(prGlueInfo, 2, ucRoleIdx); + + COPY_SSID(prP2pStartAPMsg->aucSsid, + prP2pStartAPMsg->u2SsidLen, + settings->ssid, settings->ssid_len); + + mboxSendMsg(prGlueInfo->prAdapter, + MBOX_ID_0, + (struct MSG_HDR *) prP2pStartAPMsg, + MSG_SEND_METHOD_BUF); + + i4Rslt = 0; + + } while (FALSE); + + return i4Rslt; + +/* /////////////////////// */ +/** + * struct cfg80211_ap_settings - AP configuration + * + * Used to configure an AP interface. + * + * @beacon: beacon data + * @beacon_interval: beacon interval + * @dtim_period: DTIM period + * @ssid: SSID to be used in the BSS (note: may be %NULL if not provided from + * user space) + * @ssid_len: length of @ssid + * @hidden_ssid: whether to hide the SSID in Beacon/Probe Response frames + * @crypto: crypto settings + * @privacy: the BSS uses privacy + * @auth_type: Authentication type (algorithm) + * @inactivity_timeout: time in seconds to determine station's inactivity. + */ +/* struct cfg80211_ap_settings { */ +/* struct cfg80211_beacon_data beacon; */ +/* */ +/* int beacon_interval, dtim_period; */ +/* const u8 *ssid; */ +/* size_t ssid_len; */ +/* enum nl80211_hidden_ssid hidden_ssid; */ +/* struct cfg80211_crypto_settings crypto; */ +/* bool privacy; */ +/* enum nl80211_auth_type auth_type; */ +/* int inactivity_timeout; */ +/* }; */ +/* ////////////////// */ +} /* mtk_p2p_cfg80211_start_ap */ + +#if (CFG_SUPPORT_DFS_MASTER == 1) + +static int mtk_p2p_cfg80211_start_radar_detection_impl(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_chan_def *chandef, + unsigned int cac_time_ms) +{ + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *) NULL; + int32_t i4Rslt = -EINVAL; + struct MSG_P2P_DFS_CAC *prP2pDfsCacMsg = + (struct MSG_P2P_DFS_CAC *) NULL; + uint8_t ucRoleIdx = 0; + struct RF_CHANNEL_INFO rRfChnlInfo; + + do { + if ((wiphy == NULL) || (chandef == NULL)) + break; + + DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_start_radar_detection.\n"); + + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + + if (mtk_Netdev_To_RoleIdx(prGlueInfo, dev, &ucRoleIdx) < 0) + break; + + if (prGlueInfo->prP2PInfo[ucRoleIdx]->chandef == NULL) { + prGlueInfo->prP2PInfo[ucRoleIdx]->chandef = + (struct cfg80211_chan_def *) + cnmMemAlloc(prGlueInfo->prAdapter, + RAM_TYPE_BUF, + sizeof(struct cfg80211_chan_def)); + if (prGlueInfo->prP2PInfo[ucRoleIdx]->chandef == NULL) { + i4Rslt = -ENOMEM; + break; + } + prGlueInfo->prP2PInfo[ucRoleIdx]->chandef->chan = + (struct ieee80211_channel *) + cnmMemAlloc(prGlueInfo->prAdapter, + RAM_TYPE_BUF, + sizeof(struct ieee80211_channel)); + if (prGlueInfo->prP2PInfo[ucRoleIdx]->chandef->chan + == NULL) { + i4Rslt = -ENOMEM; + break; + } + } + + /* Copy chan def to local buffer*/ + prGlueInfo->prP2PInfo[ucRoleIdx] + ->chandef->center_freq1 = chandef->center_freq1; + prGlueInfo->prP2PInfo[ucRoleIdx] + ->chandef->center_freq2 = chandef->center_freq2; + prGlueInfo->prP2PInfo[ucRoleIdx] + ->chandef->width = chandef->width; + memcpy(prGlueInfo->prP2PInfo[ucRoleIdx]->chandef->chan, + chandef->chan, sizeof(struct ieee80211_channel)); + prGlueInfo->prP2PInfo[ucRoleIdx]->cac_time_ms = cac_time_ms; + + if (chandef) { + kalChannelFormatSwitch(chandef, chandef->chan, + &rRfChnlInfo); + + p2pFuncSetChannel(prGlueInfo->prAdapter, + ucRoleIdx, &rRfChnlInfo); + } + + DBGLOG(P2P, INFO, + "mtk_p2p_cfg80211_start_radar_detection.(role %d)\n", + ucRoleIdx); + + p2pFuncSetDfsState(DFS_STATE_INACTIVE); + + prP2pDfsCacMsg = (struct MSG_P2P_DFS_CAC *) + cnmMemAlloc(prGlueInfo->prAdapter, + RAM_TYPE_MSG, sizeof(*prP2pDfsCacMsg)); + + if (prP2pDfsCacMsg == NULL) { + i4Rslt = -ENOMEM; + break; + } + + prP2pDfsCacMsg->rMsgHdr.eMsgId = MID_MNY_P2P_DFS_CAC; + + switch (chandef->width) { + case NL80211_CHAN_WIDTH_20_NOHT: + case NL80211_CHAN_WIDTH_20: + case NL80211_CHAN_WIDTH_40: + prP2pDfsCacMsg->eChannelWidth = CW_20_40MHZ; + break; + + case NL80211_CHAN_WIDTH_80: + prP2pDfsCacMsg->eChannelWidth = CW_80MHZ; + break; + + case NL80211_CHAN_WIDTH_80P80: + prP2pDfsCacMsg->eChannelWidth = CW_80P80MHZ; + break; + + default: + DBGLOG(P2P, ERROR, + "mtk_p2p_cfg80211_start_radar_detection. !!!Bandwidth do not support!!!\n"); + ASSERT(FALSE); + break; + } + + prP2pDfsCacMsg->ucRoleIdx = ucRoleIdx; + + mboxSendMsg(prGlueInfo->prAdapter, + MBOX_ID_0, + (struct MSG_HDR *) prP2pDfsCacMsg, + MSG_SEND_METHOD_BUF); + + i4Rslt = 0; + + } while (FALSE); + + return i4Rslt; +} + +#if KERNEL_VERSION(3, 15, 0) <= CFG80211_VERSION_CODE +int mtk_p2p_cfg80211_start_radar_detection(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_chan_def *chandef, unsigned int cac_time_ms) +{ + return mtk_p2p_cfg80211_start_radar_detection_impl( + wiphy, dev, chandef, cac_time_ms); +} +#else +int mtk_p2p_cfg80211_start_radar_detection(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_chan_def *chandef) +{ + return mtk_p2p_cfg80211_start_radar_detection_impl( + wiphy, dev, chandef, IEEE80211_DFS_MIN_CAC_TIME_MS); +} +#endif + +#if KERNEL_VERSION(3, 13, 0) <= CFG80211_VERSION_CODE +int mtk_p2p_cfg80211_channel_switch(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_csa_settings *params) +{ + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *) NULL; + int32_t i4Rslt = -EINVAL; + struct MSG_P2P_BEACON_UPDATE *prP2pBcnUpdateMsg = + (struct MSG_P2P_BEACON_UPDATE *) NULL; + struct MSG_P2P_SET_NEW_CHANNEL *prP2pSetNewChannelMsg = + (struct MSG_P2P_SET_NEW_CHANNEL *) NULL; + uint8_t *pucBuffer = (uint8_t *) NULL; + uint8_t ucRoleIdx = 0; + struct RF_CHANNEL_INFO rRfChnlInfo; + uint8_t ucBssIdx = 0; + uint32_t u4Len = 0; + + do { + if ((wiphy == NULL) || (params == NULL)) + break; + + DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_channel_switch.\n"); + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + + if (mtk_Netdev_To_RoleIdx(prGlueInfo, dev, &ucRoleIdx) < 0) { + DBGLOG(P2P, ERROR, "get role index fail.\n"); + break; + } else { + ASSERT(ucRoleIdx < KAL_P2P_NUM); + /* Role Interface. */ + if (p2pFuncRoleToBssIdx(prGlueInfo->prAdapter, + ucRoleIdx, &ucBssIdx) != WLAN_STATUS_SUCCESS) { + DBGLOG(P2P, ERROR, + "get bss index fail by role(%d).\n", + ucRoleIdx); + break; + } + } + + /*DFS todo 20161220_DFS*/ + netif_carrier_on(dev); + netif_tx_start_all_queues(dev); + + if (prGlueInfo->prP2PInfo[ucRoleIdx]->chandef == NULL) { + prGlueInfo->prP2PInfo[ucRoleIdx]->chandef = + (struct cfg80211_chan_def *) + cnmMemAlloc(prGlueInfo->prAdapter, + RAM_TYPE_BUF, sizeof(struct cfg80211_chan_def)); + if (prGlueInfo->prP2PInfo[ucRoleIdx]->chandef == NULL) { + i4Rslt = -ENOMEM; + break; + } + prGlueInfo->prP2PInfo[ucRoleIdx]->chandef->chan = + (struct ieee80211_channel *) + cnmMemAlloc(prGlueInfo->prAdapter, + RAM_TYPE_BUF, sizeof(struct ieee80211_channel)); + if (prGlueInfo->prP2PInfo[ucRoleIdx]->chandef->chan + == NULL) { + i4Rslt = -ENOMEM; + break; + } + } + /* Copy chan def to local buffer*/ + prGlueInfo->prP2PInfo[ucRoleIdx] + ->chandef->center_freq1 = params->chandef.center_freq1; + prGlueInfo->prP2PInfo[ucRoleIdx] + ->chandef->center_freq2 = params->chandef.center_freq2; + prGlueInfo->prP2PInfo[ucRoleIdx] + ->chandef->width = params->chandef.width; + memcpy(prGlueInfo->prP2PInfo[ucRoleIdx]->chandef->chan, + params->chandef.chan, + sizeof(struct ieee80211_channel)); + + if (params) { + kalChannelFormatSwitch(¶ms->chandef, + params->chandef.chan, &rRfChnlInfo); + + p2pFuncSetChannel(prGlueInfo->prAdapter, + ucRoleIdx, &rRfChnlInfo); + } + + DBGLOG(P2P, INFO, "ucRoleIdx: %d, ucBssIdx: %d\n", + ucRoleIdx, ucBssIdx); + + p2pFuncSetDfsState(DFS_STATE_INACTIVE); + + /* Set CSA IE parameters */ + prGlueInfo->prAdapter->rWifiVar.fgCsaInProgress = TRUE; + prGlueInfo->prAdapter->rWifiVar.ucChannelSwitchMode = 1; + prGlueInfo->prAdapter->rWifiVar.ucNewChannelNumber = + nicFreq2ChannelNum( + params->chandef.chan->center_freq * 1000); + prGlueInfo->prAdapter->rWifiVar.ucChannelSwitchCount = + params->count; + + /* Set new channel parameters */ + prP2pSetNewChannelMsg = (struct MSG_P2P_SET_NEW_CHANNEL *) + cnmMemAlloc(prGlueInfo->prAdapter, + RAM_TYPE_MSG, sizeof(*prP2pSetNewChannelMsg)); + + if (prP2pSetNewChannelMsg == NULL) { + i4Rslt = -ENOMEM; + break; + } + + prP2pSetNewChannelMsg->rMsgHdr.eMsgId = + MID_MNY_P2P_SET_NEW_CHANNEL; + + switch (params->chandef.width) { + case NL80211_CHAN_WIDTH_20_NOHT: + case NL80211_CHAN_WIDTH_20: + case NL80211_CHAN_WIDTH_40: + prP2pSetNewChannelMsg->eChannelWidth = CW_20_40MHZ; + break; + + case NL80211_CHAN_WIDTH_80: + prP2pSetNewChannelMsg->eChannelWidth = CW_80MHZ; + break; + + case NL80211_CHAN_WIDTH_80P80: + prP2pSetNewChannelMsg->eChannelWidth = CW_80P80MHZ; + break; + + default: + DBGLOG(P2P, ERROR, + "mtk_p2p_cfg80211_channel_switch. !!!Bandwidth do not support!!!\n"); + ASSERT(FALSE); + break; + } + + prP2pSetNewChannelMsg->ucRoleIdx = ucRoleIdx; + prP2pSetNewChannelMsg->ucBssIndex = ucBssIdx; + + mboxSendMsg(prGlueInfo->prAdapter, + MBOX_ID_0, + (struct MSG_HDR *) prP2pSetNewChannelMsg, + MSG_SEND_METHOD_BUF); + + /* Update beacon */ + if ((params->beacon_csa.head_len != 0) + || (params->beacon_csa.tail_len != 0)) { + u4Len = (sizeof(struct MSG_P2P_BEACON_UPDATE) + + params->beacon_csa.head_len + + params->beacon_csa.tail_len); + + prP2pBcnUpdateMsg = (struct MSG_P2P_BEACON_UPDATE *) + cnmMemAlloc(prGlueInfo->prAdapter, + RAM_TYPE_MSG, + u4Len); + + if (prP2pBcnUpdateMsg == NULL) { + i4Rslt = -ENOMEM; + break; + } + + kalMemZero(prP2pBcnUpdateMsg, u4Len); + + prP2pBcnUpdateMsg->ucRoleIndex = ucRoleIdx; + prP2pBcnUpdateMsg->rMsgHdr.eMsgId = + MID_MNY_P2P_BEACON_UPDATE; + pucBuffer = prP2pBcnUpdateMsg->aucBuffer; + + if (params->beacon_csa.head_len != 0) { + kalMemCopy(pucBuffer, + params->beacon_csa.head, + params->beacon_csa.head_len); + + prP2pBcnUpdateMsg->u4BcnHdrLen = + params->beacon_csa.head_len; + + prP2pBcnUpdateMsg->pucBcnHdr = pucBuffer; + + pucBuffer = (uint8_t *) ((unsigned long) + pucBuffer + + (unsigned long) + params->beacon_csa.head_len); + } else { + prP2pBcnUpdateMsg->u4BcnHdrLen = 0; + + prP2pBcnUpdateMsg->pucBcnHdr = NULL; + } + + if (params->beacon_csa.tail_len != 0) { + prP2pBcnUpdateMsg->pucBcnBody = pucBuffer; + kalMemCopy(pucBuffer, + params->beacon_csa.tail, + params->beacon_csa.tail_len); + + prP2pBcnUpdateMsg->u4BcnBodyLen = + params->beacon_csa.tail_len; + } else { + prP2pBcnUpdateMsg->u4BcnBodyLen = 0; + prP2pBcnUpdateMsg->pucBcnBody = NULL; + } + + kalP2PSetRole(prGlueInfo, 2, ucRoleIdx); + + mboxSendMsg(prGlueInfo->prAdapter, + MBOX_ID_0, + (struct MSG_HDR *) prP2pBcnUpdateMsg, + MSG_SEND_METHOD_BUF); + + i4Rslt = 0; /* Return Success */ + } + + } while (FALSE); + + return i4Rslt; +} +#endif +#endif + +#if 0 +struct cfg80211_beacon_data { + const u8 *head, *tail; + const u8 *beacon_ies; + const u8 *proberesp_ies; + const u8 *assocresp_ies; + const u8 *probe_resp; + + size_t head_len, tail_len; + size_t beacon_ies_len; + size_t proberesp_ies_len; + size_t assocresp_ies_len; + size_t probe_resp_len; +}; +#endif + +int mtk_p2p_cfg80211_change_beacon(struct wiphy *wiphy, + struct net_device *dev, struct cfg80211_beacon_data *info) +{ + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *) NULL; + int32_t i4Rslt = -EINVAL; + struct MSG_P2P_BEACON_UPDATE *prP2pBcnUpdateMsg = + (struct MSG_P2P_BEACON_UPDATE *) NULL; + uint8_t *pucBuffer = (uint8_t *) NULL; + uint8_t ucRoleIdx = 0; + uint32_t u4Len = 0; + + do { + if ((wiphy == NULL) || (info == NULL)) + break; + + DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_change_beacon.\n"); + + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + + if (mtk_Netdev_To_RoleIdx(prGlueInfo, dev, &ucRoleIdx) < 0) + break; + + if ((info->head_len != 0) || (info->tail_len != 0)) { + u4Len = (sizeof(struct MSG_P2P_BEACON_UPDATE) + + info->head_len + + info->tail_len + + info->assocresp_ies_len +#if CFG_SUPPORT_P2P_GO_OFFLOAD_PROBE_RSP + + info->proberesp_ies_len +#endif + ); + + prP2pBcnUpdateMsg = (struct MSG_P2P_BEACON_UPDATE *) + cnmMemAlloc(prGlueInfo->prAdapter, + RAM_TYPE_MSG, + u4Len); + + if (prP2pBcnUpdateMsg == NULL) { + i4Rslt = -ENOMEM; + break; + } + + kalMemZero(prP2pBcnUpdateMsg, u4Len); + + prP2pBcnUpdateMsg->ucRoleIndex = ucRoleIdx; + prP2pBcnUpdateMsg->rMsgHdr.eMsgId = + MID_MNY_P2P_BEACON_UPDATE; + pucBuffer = prP2pBcnUpdateMsg->aucBuffer; + + if (info->head_len != 0) { + kalMemCopy(pucBuffer, + info->head, + info->head_len); + + prP2pBcnUpdateMsg->u4BcnHdrLen = info->head_len; + + prP2pBcnUpdateMsg->pucBcnHdr = pucBuffer; + + pucBuffer += info->head_len; + } else { + prP2pBcnUpdateMsg->u4BcnHdrLen = 0; + + prP2pBcnUpdateMsg->pucBcnHdr = NULL; + } + + if (info->tail_len != 0) { + prP2pBcnUpdateMsg->pucBcnBody = pucBuffer; + kalMemCopy(pucBuffer, + info->tail, + info->tail_len); + + prP2pBcnUpdateMsg->u4BcnBodyLen = + info->tail_len; + + pucBuffer += info->tail_len; + } else { + prP2pBcnUpdateMsg->u4BcnBodyLen = 0; + prP2pBcnUpdateMsg->pucBcnBody = NULL; + } + + if (info->assocresp_ies_len != 0 + && info->assocresp_ies != NULL) { + + prP2pBcnUpdateMsg->pucAssocRespIE = pucBuffer; + kalMemCopy(pucBuffer, + info->assocresp_ies, + info->assocresp_ies_len); + prP2pBcnUpdateMsg->u4AssocRespLen = + info->assocresp_ies_len; + } else { + prP2pBcnUpdateMsg->u4AssocRespLen = 0; + prP2pBcnUpdateMsg->pucAssocRespIE = NULL; + } + +#if CFG_SUPPORT_P2P_GO_OFFLOAD_PROBE_RSP + if (info->proberesp_ies_len != 0 + && info->proberesp_ies != NULL) { + + prP2pBcnUpdateMsg->pucProbeRespIE = pucBuffer; + kalMemCopy(pucBuffer, + info->proberesp_ies, + info->proberesp_ies_len); + prP2pBcnUpdateMsg->u4ProbeRespLen = + info->proberesp_ies_len; + } else { + prP2pBcnUpdateMsg->u4ProbeRespLen = 0; + prP2pBcnUpdateMsg->pucProbeRespIE = NULL; + } +#endif + + kalP2PSetRole(prGlueInfo, 2, ucRoleIdx); + + mboxSendMsg(prGlueInfo->prAdapter, + MBOX_ID_0, + (struct MSG_HDR *) prP2pBcnUpdateMsg, + MSG_SEND_METHOD_BUF); + + i4Rslt = 0; /* Return Success */ + } + + /* TODO: Probe Rsp, Assoc Rsp, Beacon IE update. */ + +/* ////////////////////////// */ +/** + * struct cfg80211_beacon_data - beacon data + * @head: head portion of beacon (before TIM IE) + * or %NULL if not changed + * @tail: tail portion of beacon (after TIM IE) + * or %NULL if not changed + * @head_len: length of @head + * @tail_len: length of @tail + * @beacon_ies: extra information element(s) to add into Beacon frames or %NULL + * @beacon_ies_len: length of beacon_ies in octets + * @proberesp_ies: extra information element(s) to add into Probe Response + * frames or %NULL + * @proberesp_ies_len: length of proberesp_ies in octets + * @assocresp_ies: extra information element(s) to add into (Re)Association + * Response frames or %NULL + * @assocresp_ies_len: length of assocresp_ies in octets + * @probe_resp_len: length of probe response template (@probe_resp) + * @probe_resp: probe response template (AP mode only) + */ +/* struct cfg80211_beacon_data { */ +/* const u8 *head, *tail; */ +/* const u8 *beacon_ies; */ +/* const u8 *proberesp_ies; */ +/* const u8 *assocresp_ies; */ +/* const u8 *probe_resp; */ + +/* size_t head_len, tail_len; */ +/* size_t beacon_ies_len; */ +/* size_t proberesp_ies_len; */ +/* size_t assocresp_ies_len; */ +/* size_t probe_resp_len; */ +/* }; */ + +/* ////////////////////////// */ + + } while (FALSE); + + return i4Rslt; +} /* mtk_p2p_cfg80211_change_beacon */ + +int mtk_p2p_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) +{ + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *) NULL; + int32_t i4Rslt = -EINVAL; + struct MSG_P2P_STOP_AP *prP2pStopApMsg = + (struct MSG_P2P_STOP_AP *) NULL; + uint8_t ucRoleIdx = 0; + struct GL_P2P_INFO *prP2PInfo; + + do { + if (wiphy == NULL) + break; + + DBGLOG(P2P, INFO, "mtk_p2p_cfg80211_stop_ap.\n"); + + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + +#if (CFG_SUPPORT_DFS_MASTER == 1) + if (dev->ieee80211_ptr->iftype == NL80211_IFTYPE_AP) { + netif_carrier_off(dev); + netif_tx_stop_all_queues(dev); + } +#endif + + if (mtk_Netdev_To_RoleIdx(prGlueInfo, dev, &ucRoleIdx) < 0) + break; + + prP2pStopApMsg = cnmMemAlloc(prGlueInfo->prAdapter, + RAM_TYPE_MSG, sizeof(struct MSG_P2P_STOP_AP)); + + if (prP2pStopApMsg == NULL) { + i4Rslt = -ENOMEM; + break; + } + + prP2PInfo = prGlueInfo->prP2PInfo[ucRoleIdx]; +#if KERNEL_VERSION(3, 13, 0) <= CFG80211_VERSION_CODE + reinit_completion(&prP2PInfo->rStopApComp); +#else + prP2PInfo->rStopApComp.done = 0; +#endif + + prP2pStopApMsg->rMsgHdr.eMsgId = MID_MNY_P2P_STOP_AP; + prP2pStopApMsg->ucRoleIdx = ucRoleIdx; + + mboxSendMsg(prGlueInfo->prAdapter, + MBOX_ID_0, + (struct MSG_HDR *) prP2pStopApMsg, + MSG_SEND_METHOD_BUF); + + if (1) { /* AP or GO */ + uint32_t waitRet = 0; + + waitRet = wait_for_completion_timeout( + &prP2PInfo->rStopApComp, + MSEC_TO_JIFFIES(P2P_DEAUTH_TIMEOUT_TIME_MS)); + if (!waitRet) + DBGLOG(P2P, WARN, "timeout\n"); + else + DBGLOG(P2P, INFO, "complete\n"); + } + + i4Rslt = 0; + } while (FALSE); + + return i4Rslt; +} /* mtk_p2p_cfg80211_stop_ap */ + +/* TODO: */ +int mtk_p2p_cfg80211_deauth(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_deauth_request *req) +{ + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *) NULL; + + ASSERT(wiphy); + + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + + /* not implemented yet */ + DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_deauth.\n"); + + return -EINVAL; +} /* mtk_p2p_cfg80211_deauth */ + +/* TODO: */ +int mtk_p2p_cfg80211_disassoc(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_disassoc_request *req) +{ + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *) NULL; + + ASSERT(wiphy); + + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + + DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_disassoc.\n"); + + /* not implemented yet */ + + return -EINVAL; +} /* mtk_p2p_cfg80211_disassoc */ + +int mtk_p2p_cfg80211_remain_on_channel(struct wiphy *wiphy, + struct wireless_dev *wdev, + struct ieee80211_channel *chan, + unsigned int duration, u64 *cookie) +{ + int32_t i4Rslt = -EINVAL; + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *) NULL; + struct GL_P2P_DEV_INFO *prGlueP2pDevInfo = + (struct GL_P2P_DEV_INFO *) NULL; + struct MSG_P2P_CHNL_REQUEST *prMsgChnlReq = + (struct MSG_P2P_CHNL_REQUEST *) NULL; + + DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_remain_on_channel\n"); + + do { + if ((wiphy == NULL) || + /* (dev == NULL) || */ + (chan == NULL) || (cookie == NULL)) { + break; + } + + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + + prGlueP2pDevInfo = prGlueInfo->prP2PDevInfo; + + *cookie = prGlueP2pDevInfo->u8Cookie++; + + prMsgChnlReq = cnmMemAlloc(prGlueInfo->prAdapter, + RAM_TYPE_MSG, sizeof(struct MSG_P2P_CHNL_REQUEST)); + + if (prMsgChnlReq == NULL) { + i4Rslt = -ENOMEM; + break; + } + + DBGLOG(P2P, INFO, + "Remain on channel, cookie: 0x%llx\n", + *cookie); + + prMsgChnlReq->rMsgHdr.eMsgId = MID_MNY_P2P_CHNL_REQ; + prMsgChnlReq->u8Cookie = *cookie; + prMsgChnlReq->u4Duration = duration; + prMsgChnlReq->eChnlReqType = CH_REQ_TYPE_ROC; + + kalChannelFormatSwitch(NULL, chan, + &prMsgChnlReq->rChannelInfo); + kalChannelScoSwitch(NL80211_CHAN_NO_HT, + &prMsgChnlReq->eChnlSco); + + mboxSendMsg(prGlueInfo->prAdapter, + MBOX_ID_0, + (struct MSG_HDR *) prMsgChnlReq, + MSG_SEND_METHOD_BUF); + + i4Rslt = 0; + } while (FALSE); + + return i4Rslt; +} + +/* mtk_p2p_cfg80211_remain_on_channel */ + +int mtk_p2p_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, + struct wireless_dev *wdev, u64 cookie) +{ + int32_t i4Rslt = -EINVAL; + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *) NULL; + struct GL_P2P_INFO *prGlueP2pInfo = (struct GL_P2P_INFO *) NULL; + struct MSG_P2P_CHNL_ABORT *prMsgChnlAbort = + (struct MSG_P2P_CHNL_ABORT *) NULL; + + do { + if (wiphy == NULL /* || (dev == NULL) */) + break; + + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + + prGlueP2pInfo = prGlueInfo->prP2PInfo[0]; + + prMsgChnlAbort = cnmMemAlloc(prGlueInfo->prAdapter, + RAM_TYPE_MSG, sizeof(struct MSG_P2P_CHNL_ABORT)); + + if (prMsgChnlAbort == NULL) { + i4Rslt = -ENOMEM; + break; + } + + DBGLOG(P2P, INFO, + "Cancel remain on channel, cookie: 0x%llx\n", cookie); + + prMsgChnlAbort->rMsgHdr.eMsgId = MID_MNY_P2P_CHNL_ABORT; + prMsgChnlAbort->u8Cookie = cookie; + + mboxSendMsg(prGlueInfo->prAdapter, + MBOX_ID_0, + (struct MSG_HDR *) prMsgChnlAbort, + MSG_SEND_METHOD_BUF); + + i4Rslt = 0; + } while (FALSE); + + return i4Rslt; +} /* mtk_p2p_cfg80211_cancel_remain_on_channel */ + +int _mtk_p2p_cfg80211_mgmt_tx(struct wiphy *wiphy, + struct wireless_dev *wdev, struct ieee80211_channel *chan, + bool offchan, unsigned int wait, const u8 *buf, size_t len, + bool no_cck, bool dont_wait_for_ack, u64 *cookie) +{ + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *) NULL; + int32_t i4Rslt = -EINVAL; + struct MSG_MGMT_TX_REQUEST *prMsgTxReq = + (struct MSG_MGMT_TX_REQUEST *) NULL; + struct MSDU_INFO *prMgmtFrame = (struct MSDU_INFO *) NULL; + uint8_t *pucFrameBuf = (uint8_t *) NULL; + uint64_t *pu8GlCookie = (uint64_t *) NULL; + uint8_t ucRoleIdx = 0, ucBssIdx = 0; + struct net_device *dev = NULL; + + do { + if ((wiphy == NULL) || (wdev == NULL) || (cookie == NULL)) + break; + + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + + dev = wdev->netdev; + + if (mtk_Netdev_To_RoleIdx(prGlueInfo, dev, &ucRoleIdx) < 0) { + /* Device Interface. */ + ucBssIdx = prGlueInfo->prAdapter->ucP2PDevBssIdx; + } else { + ASSERT(ucRoleIdx < KAL_P2P_NUM); + /* Role Interface. */ + if (p2pFuncRoleToBssIdx(prGlueInfo->prAdapter, + ucRoleIdx, &ucBssIdx) != WLAN_STATUS_SUCCESS) { + /* Can't find BSS index. */ + break; + } + } + + *cookie = prGlueInfo->prP2PDevInfo->u8Cookie++; + + prMsgTxReq = cnmMemAlloc(prGlueInfo->prAdapter, + RAM_TYPE_MSG, + sizeof(struct MSG_MGMT_TX_REQUEST)); + + if (prMsgTxReq == NULL) { + i4Rslt = -ENOMEM; + DBGLOG(P2P, ERROR, "Allocate TX req msg fails.\n"); + break; + } + + if (offchan) { + prMsgTxReq->fgIsOffChannel = TRUE; + memset(&prMsgTxReq->rChannelInfo, 0, + sizeof(struct RF_CHANNEL_INFO)); + kalChannelFormatSwitch(NULL, chan, + &prMsgTxReq->rChannelInfo); + kalChannelScoSwitch(NL80211_CHAN_NO_HT, + &prMsgTxReq->eChnlExt); + } else { + prMsgTxReq->fgIsOffChannel = FALSE; + } + + if (wait) + prMsgTxReq->u4Duration = wait; + else + prMsgTxReq->u4Duration = 0; + + if (no_cck) + prMsgTxReq->fgNoneCckRate = TRUE; + else + prMsgTxReq->fgNoneCckRate = FALSE; + + if (dont_wait_for_ack) + prMsgTxReq->fgIsWaitRsp = FALSE; + else + prMsgTxReq->fgIsWaitRsp = TRUE; + + prMgmtFrame = cnmMgtPktAlloc(prGlueInfo->prAdapter, + (int32_t) (len + sizeof(uint64_t) + + MAC_TX_RESERVED_FIELD)); + prMsgTxReq->prMgmtMsduInfo = prMgmtFrame; + if (prMsgTxReq->prMgmtMsduInfo == NULL) { + /* ASSERT(FALSE); */ + i4Rslt = -ENOMEM; + DBGLOG(P2P, ERROR, "Allocate TX packet fails.\n"); + break; + } + + prMsgTxReq->u8Cookie = *cookie; + prMsgTxReq->rMsgHdr.eMsgId = MID_MNY_P2P_MGMT_TX; + prMsgTxReq->ucBssIdx = ucBssIdx; + + pucFrameBuf = + (uint8_t *) + ((unsigned long) prMgmtFrame->prPacket + + MAC_TX_RESERVED_FIELD); + + pu8GlCookie = + (uint64_t *) + ((unsigned long) prMgmtFrame->prPacket + + (unsigned long) len + + MAC_TX_RESERVED_FIELD); + + kalMemCopy(pucFrameBuf, buf, len); + + *pu8GlCookie = *cookie; + + prMgmtFrame->u2FrameLength = len; + +#define TEMP_LOG_TEMPLATE "netdev: %p, bssIdx: %d, band: %d, chan: %d, " \ + "offchan: %d, wait: %d, len: %d, no_cck: %d, " \ + "dont_wait_for_ack: %d, cookie: 0x%llx\n" + DBGLOG(P2P, INFO, TEMP_LOG_TEMPLATE, + dev, + prMsgTxReq->ucBssIdx, + prMsgTxReq->rChannelInfo.eBand, + prMsgTxReq->rChannelInfo.ucChannelNum, + prMsgTxReq->fgIsOffChannel, + prMsgTxReq->u4Duration, + prMsgTxReq->prMgmtMsduInfo->u2FrameLength, + prMsgTxReq->fgNoneCckRate, + prMsgTxReq->fgIsWaitRsp, + prMsgTxReq->u8Cookie); +#undef TEMP_LOG_TEMPLATE + + mboxSendMsg(prGlueInfo->prAdapter, + MBOX_ID_0, + (struct MSG_HDR *) prMsgTxReq, + MSG_SEND_METHOD_BUF); + + i4Rslt = 0; + } while (FALSE); + + if ((i4Rslt != 0) && (prMsgTxReq != NULL)) { + if (prMsgTxReq->prMgmtMsduInfo != NULL) + cnmMgtPktFree(prGlueInfo->prAdapter, + prMsgTxReq->prMgmtMsduInfo); + + cnmMemFree(prGlueInfo->prAdapter, prMsgTxReq); + } + + return i4Rslt; +} + +#if KERNEL_VERSION(3, 14, 0) <= CFG80211_VERSION_CODE +int mtk_p2p_cfg80211_mgmt_tx(struct wiphy *wiphy, + struct wireless_dev *wdev, + struct cfg80211_mgmt_tx_params *params, + u64 *cookie) +{ + if (params == NULL) + return -EINVAL; + + return _mtk_p2p_cfg80211_mgmt_tx(wiphy, wdev, params->chan, + params->offchan, params->wait, params->buf, + params->len, params->no_cck, params->dont_wait_for_ack, + cookie); +} /* mtk_p2p_cfg80211_mgmt_tx */ +#else +int mtk_p2p_cfg80211_mgmt_tx(struct wiphy *wiphy, + struct wireless_dev *wdev, + struct ieee80211_channel *chan, bool offchan, + unsigned int wait, const u8 *buf, size_t len, + bool no_cck, bool dont_wait_for_ack, u64 *cookie) +{ + return _mtk_p2p_cfg80211_mgmt_tx(wiphy, wdev, chan, offchan, wait, buf, + len, no_cck, dont_wait_for_ack, cookie); +} /* mtk_p2p_cfg80211_mgmt_tx */ +#endif + +int mtk_p2p_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, + struct wireless_dev *wdev, u64 cookie) +{ + int32_t i4Rslt = -EINVAL; + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *) NULL; + uint8_t ucRoleIdx = 0, ucBssIdx = 0; + struct MSG_CANCEL_TX_WAIT_REQUEST *prMsgCancelTxWait = + (struct MSG_CANCEL_TX_WAIT_REQUEST *) NULL; + + do { + ASSERT(wiphy); + + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + + if (mtk_Netdev_To_RoleIdx(prGlueInfo, + wdev->netdev, &ucRoleIdx) < 0) { + /* Device Interface. */ + ucBssIdx = prGlueInfo->prAdapter->ucP2PDevBssIdx; + } else { + ASSERT(ucRoleIdx < KAL_P2P_NUM); + /* Role Interface. */ + if (p2pFuncRoleToBssIdx(prGlueInfo->prAdapter, + ucRoleIdx, + &ucBssIdx) != WLAN_STATUS_SUCCESS) { + /* Can't find BSS index. */ + break; + } + } + + DBGLOG(P2P, INFO, "bssIdx: %d, cookie: 0x%llx\n", + ucBssIdx, + cookie); + + prMsgCancelTxWait = cnmMemAlloc(prGlueInfo->prAdapter, + RAM_TYPE_MSG, + sizeof(struct MSG_CANCEL_TX_WAIT_REQUEST)); + + if (prMsgCancelTxWait == NULL) { + i4Rslt = -ENOMEM; + break; + } + + prMsgCancelTxWait->rMsgHdr.eMsgId = + MID_MNY_P2P_MGMT_TX_CANCEL_WAIT; + prMsgCancelTxWait->u8Cookie = cookie; + prMsgCancelTxWait->ucBssIdx = ucBssIdx; + + mboxSendMsg(prGlueInfo->prAdapter, + MBOX_ID_0, + (struct MSG_HDR *) prMsgCancelTxWait, + MSG_SEND_METHOD_BUF); + + i4Rslt = 0; + } while (FALSE); + + return i4Rslt; +} /* mtk_p2p_cfg80211_mgmt_tx_cancel_wait */ + +int mtk_p2p_cfg80211_change_bss(struct wiphy *wiphy, + struct net_device *dev, + struct bss_parameters *params) +{ + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *) NULL; + int32_t i4Rslt = -EINVAL; + + ASSERT(wiphy); + + DBGLOG(P2P, INFO, "%s\n", __func__); + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + + switch (params->use_cts_prot) { + case -1: + DBGLOG(P2P, TRACE, "CTS protection no change\n"); + break; + case 0: + DBGLOG(P2P, TRACE, "CTS protection disable.\n"); + break; + case 1: + DBGLOG(P2P, TRACE, "CTS protection enable\n"); + break; + default: + DBGLOG(P2P, TRACE, "CTS protection unknown\n"); + break; + } + + switch (params->use_short_preamble) { + case -1: + DBGLOG(P2P, TRACE, "Short prreamble no change\n"); + break; + case 0: + DBGLOG(P2P, TRACE, "Short prreamble disable.\n"); + break; + case 1: + DBGLOG(P2P, TRACE, "Short prreamble enable\n"); + break; + default: + DBGLOG(P2P, TRACE, "Short prreamble unknown\n"); + break; + } + +#if 0 + /* not implemented yet */ + p2pFuncChangeBssParam(prGlueInfo->prAdapter, + prBssInfo->fgIsProtection, + prBssInfo->fgIsShortPreambleAllowed, + prBssInfo->fgUseShortSlotTime, + /* Basic rates */ + /* basic rates len */ + /* ap isolate */ + /* ht opmode. */ + ); +#else + i4Rslt = 0; +#endif + + return i4Rslt; +} /* mtk_p2p_cfg80211_change_bss */ + +#if KERNEL_VERSION(3, 16, 0) <= CFG80211_VERSION_CODE +#if KERNEL_VERSION(3, 19, 0) <= CFG80211_VERSION_CODE +static const u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; +int mtk_p2p_cfg80211_del_station(struct wiphy *wiphy, + struct net_device *dev, + struct station_del_parameters *params) +{ + const u8 *mac = params->mac ? params->mac : bcast_addr; + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *) NULL; + int32_t i4Rslt = -EINVAL; + struct MSG_P2P_CONNECTION_ABORT *prDisconnectMsg = + (struct MSG_P2P_CONNECTION_ABORT *) NULL; + uint8_t aucBcMac[] = BC_MAC_ADDR; + uint8_t ucRoleIdx = 0; + + do { + if ((wiphy == NULL) || (dev == NULL)) + break; + + if (mac == NULL) + mac = aucBcMac; + + DBGLOG(P2P, INFO, + "mtk_p2p_cfg80211_del_station " MACSTR ". reason: %d\n", + MAC2STR(mac), params->reason_code); + + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + + if (mtk_Netdev_To_RoleIdx(prGlueInfo, dev, &ucRoleIdx) < 0) + break; + /* prDisconnectMsg = (struct MSG_P2P_CONNECTION_ABORT *) + * kalMemAlloc(sizeof(struct MSG_P2P_CONNECTION_ABORT), + * VIR_MEM_TYPE); + */ + + prDisconnectMsg = (struct MSG_P2P_CONNECTION_ABORT *) + cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, + sizeof(struct MSG_P2P_CONNECTION_ABORT)); + + if (prDisconnectMsg == NULL) { + i4Rslt = -ENOMEM; + break; + } + + prDisconnectMsg->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_ABORT; + prDisconnectMsg->ucRoleIdx = ucRoleIdx; + COPY_MAC_ADDR(prDisconnectMsg->aucTargetID, mac); + prDisconnectMsg->u2ReasonCode = params->reason_code; + prDisconnectMsg->fgSendDeauth = TRUE; + + + mboxSendMsg(prGlueInfo->prAdapter, + MBOX_ID_0, + (struct MSG_HDR *) prDisconnectMsg, + MSG_SEND_METHOD_BUF); + + i4Rslt = 0; + } while (FALSE); + + return i4Rslt; + +} /* mtk_p2p_cfg80211_del_station */ +#else +int mtk_p2p_cfg80211_del_station(struct wiphy *wiphy, + struct net_device *dev, const u8 *mac) +{ + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *) NULL; + int32_t i4Rslt = -EINVAL; + struct MSG_P2P_CONNECTION_ABORT *prDisconnectMsg = + (struct MSG_P2P_CONNECTION_ABORT *) NULL; + uint8_t aucBcMac[] = BC_MAC_ADDR; + uint8_t ucRoleIdx = 0; + + do { + if ((wiphy == NULL) || (dev == NULL)) + break; + + if (mac == NULL) + mac = aucBcMac; + + DBGLOG(P2P, INFO, + "mtk_p2p_cfg80211_del_station " MACSTR ".\n", + MAC2STR(mac)); + + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + + if (mtk_Netdev_To_RoleIdx(prGlueInfo, dev, &ucRoleIdx) < 0) + break; + /* prDisconnectMsg = (struct MSG_P2P_CONNECTION_ABORT *) + * kalMemAlloc(sizeof(struct MSG_P2P_CONNECTION_ABORT), + * VIR_MEM_TYPE); + */ + + prDisconnectMsg = (struct MSG_P2P_CONNECTION_ABORT *) + cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, + sizeof(struct MSG_P2P_CONNECTION_ABORT)); + + if (prDisconnectMsg == NULL) { + i4Rslt = -ENOMEM; + break; + } + + prDisconnectMsg->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_ABORT; + prDisconnectMsg->ucRoleIdx = ucRoleIdx; + COPY_MAC_ADDR(prDisconnectMsg->aucTargetID, mac); + prDisconnectMsg->u2ReasonCode = REASON_CODE_UNSPECIFIED; + prDisconnectMsg->fgSendDeauth = TRUE; + + + mboxSendMsg(prGlueInfo->prAdapter, + MBOX_ID_0, + (struct MSG_HDR *) prDisconnectMsg, + MSG_SEND_METHOD_BUF); + + i4Rslt = 0; + } while (FALSE); + + return i4Rslt; + +} /* mtk_p2p_cfg80211_del_station */ +#endif +#else +int mtk_p2p_cfg80211_del_station(struct wiphy *wiphy, + struct net_device *dev, u8 *mac) +{ + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *) NULL; + int32_t i4Rslt = -EINVAL; + struct MSG_P2P_CONNECTION_ABORT *prDisconnectMsg = + (struct MSG_P2P_CONNECTION_ABORT *) NULL; + uint8_t aucBcMac[] = BC_MAC_ADDR; + uint8_t ucRoleIdx = 0; + + do { + if ((wiphy == NULL) || (dev == NULL)) + break; + + if (mac == NULL) + mac = aucBcMac; + + DBGLOG(P2P, INFO, + "mtk_p2p_cfg80211_del_station " MACSTR ".\n", + MAC2STR(mac)); + + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + + if (mtk_Netdev_To_RoleIdx(prGlueInfo, dev, &ucRoleIdx) < 0) + break; + /* prDisconnectMsg = (struct MSG_P2P_CONNECTION_ABORT *) + * kalMemAlloc(sizeof(struct MSG_P2P_CONNECTION_ABORT), + * VIR_MEM_TYPE); + */ + + prDisconnectMsg = + (struct MSG_P2P_CONNECTION_ABORT *) + cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, + sizeof(struct MSG_P2P_CONNECTION_ABORT)); + + if (prDisconnectMsg == NULL) { + i4Rslt = -ENOMEM; + break; + } + + prDisconnectMsg->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_ABORT; + prDisconnectMsg->ucRoleIdx = ucRoleIdx; + COPY_MAC_ADDR(prDisconnectMsg->aucTargetID, mac); + prDisconnectMsg->u2ReasonCode = REASON_CODE_UNSPECIFIED; + prDisconnectMsg->fgSendDeauth = TRUE; + + + mboxSendMsg(prGlueInfo->prAdapter, + MBOX_ID_0, + (struct MSG_HDR *) prDisconnectMsg, + MSG_SEND_METHOD_BUF); + + i4Rslt = 0; + } while (FALSE); + + return i4Rslt; + +} /* mtk_p2p_cfg80211_del_station */ +#endif + +int mtk_p2p_cfg80211_connect(struct wiphy *wiphy, + struct net_device *dev, struct cfg80211_connect_params *sme) +{ + int32_t i4Rslt = -EINVAL; + struct GLUE_INFO *prGlueInfo = NULL; + struct MSG_P2P_CONNECTION_REQUEST *prConnReqMsg = + (struct MSG_P2P_CONNECTION_REQUEST *) NULL; + uint8_t ucRoleIdx = 0; + const u8 *bssid = NULL; + struct ieee80211_channel *channel = NULL; + struct cfg80211_bss *bss = NULL; + + do { + if ((wiphy == NULL) || (dev == NULL) || (sme == NULL)) + break; + + if (sme->bssid) + bssid = sme->bssid; +#if KERNEL_VERSION(3, 15, 0) <= CFG80211_VERSION_CODE + else if (sme->bssid_hint) + bssid = sme->bssid_hint; +#endif + if (sme->channel) + channel = sme->channel; +#if KERNEL_VERSION(3, 15, 0) <= CFG80211_VERSION_CODE + else if (sme->channel_hint) + channel = sme->channel_hint; +#endif + + if ((bssid == NULL) || (channel == NULL)) { +#if KERNEL_VERSION(4, 1, 0) <= CFG80211_VERSION_CODE + bss = cfg80211_get_bss(wiphy, NULL, NULL, + sme->ssid, sme->ssid_len, + IEEE80211_BSS_TYPE_ESS, IEEE80211_PRIVACY_ANY); +#else + bss = cfg80211_get_bss(wiphy, NULL, NULL, + sme->ssid, sme->ssid_len, + WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); +#endif + if (bss == NULL) { + DBGLOG(P2P, ERROR, + "Reject connect without bssid/channel/bss.\n"); + break; + } + + bssid = bss->bssid; + channel = bss->channel; + + if ((bssid == NULL) || (channel == NULL)) { + DBGLOG(P2P, ERROR, + "Reject connect: no bssid/channel in bss.\n"); + break; + } + } + + DBGLOG(P2P, INFO, + "bssid: " MACSTR ", band: %d, freq: %d.\n", + MAC2STR(bssid), channel->band, channel->center_freq); + + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + + if (mtk_Netdev_To_RoleIdx(prGlueInfo, dev, &ucRoleIdx) < 0) + break; + + prConnReqMsg = + (struct MSG_P2P_CONNECTION_REQUEST *) + cnmMemAlloc(prGlueInfo->prAdapter, + RAM_TYPE_MSG, + (sizeof(struct MSG_P2P_CONNECTION_REQUEST) + + sme->ie_len)); + + if (prConnReqMsg == NULL) { + i4Rslt = -ENOMEM; + break; + } + + prConnReqMsg->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_REQ; + prConnReqMsg->ucRoleIdx = ucRoleIdx; + + COPY_SSID(prConnReqMsg->rSsid.aucSsid, + prConnReqMsg->rSsid.ucSsidLen, + sme->ssid, sme->ssid_len); + + COPY_MAC_ADDR(prConnReqMsg->aucBssid, bssid); + COPY_MAC_ADDR(prConnReqMsg->aucSrcMacAddr, dev->dev_addr); + + DBGLOG(P2P, TRACE, + "Assoc Req IE Buffer Length:%zu\n", sme->ie_len); + + kalMemCopy(prConnReqMsg->aucIEBuf, sme->ie, sme->ie_len); + prConnReqMsg->u4IELen = sme->ie_len; + + kalP2PSetCipher(prGlueInfo, IW_AUTH_CIPHER_NONE, ucRoleIdx); + + if (sme->crypto.n_ciphers_pairwise) { + DBGLOG(REQ, TRACE, + "cipher pairwise (%d)\n", + sme->crypto.ciphers_pairwise[0]); + if (aucDebugModule[DBG_P2P_IDX] & DBG_CLASS_TRACE) { + dumpMemory8((uint8_t *) prConnReqMsg->aucIEBuf, + (uint32_t) prConnReqMsg->u4IELen); + } + + switch (sme->crypto.ciphers_pairwise[0]) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + kalP2PSetCipher(prGlueInfo, + IW_AUTH_CIPHER_WEP40, ucRoleIdx); + break; + case WLAN_CIPHER_SUITE_TKIP: + kalP2PSetCipher(prGlueInfo, + IW_AUTH_CIPHER_TKIP, ucRoleIdx); + break; + case WLAN_CIPHER_SUITE_CCMP: + case WLAN_CIPHER_SUITE_AES_CMAC: + kalP2PSetCipher(prGlueInfo, + IW_AUTH_CIPHER_CCMP, ucRoleIdx); + break; + default: + cnmMemFree(prGlueInfo->prAdapter, prConnReqMsg); + DBGLOG(REQ, WARN, + "invalid cipher pairwise (%d)\n", + sme->crypto.ciphers_pairwise[0]); + /* do cfg80211_put_bss before return */ + if (bss) + cfg80211_put_bss(wiphy, bss); + return -EINVAL; + } + } else { + DBGLOG(REQ, WARN, "Null cipher pairwise\n"); + } + + kalChannelFormatSwitch(NULL, channel, + &prConnReqMsg->rChannelInfo); + kalChannelScoSwitch(NL80211_CHAN_NO_HT, + &prConnReqMsg->eChnlSco); + + mboxSendMsg(prGlueInfo->prAdapter, + MBOX_ID_0, + (struct MSG_HDR *) prConnReqMsg, + MSG_SEND_METHOD_BUF); + + i4Rslt = 0; + } while (FALSE); + + /* do cfg80211_put_bss before return */ + if (bss) + cfg80211_put_bss(wiphy, bss); + + return i4Rslt; +} /* mtk_p2p_cfg80211_connect */ + +int mtk_p2p_cfg80211_disconnect(struct wiphy *wiphy, + struct net_device *dev, u16 reason_code) +{ + int32_t i4Rslt = -EINVAL; + struct GLUE_INFO *prGlueInfo = NULL; + struct MSG_P2P_CONNECTION_ABORT *prDisconnMsg = + (struct MSG_P2P_CONNECTION_ABORT *) NULL; + uint8_t aucBCAddr[] = BC_MAC_ADDR; + uint8_t ucRoleIdx = 0; + + do { + if ((wiphy == NULL) || (dev == NULL)) + break; + + DBGLOG(P2P, INFO, + "mtk_p2p_cfg80211_disconnect reason: %d.\n", + reason_code); + + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + + if (mtk_Netdev_To_RoleIdx(prGlueInfo, dev, &ucRoleIdx) < 0) + break; +/* prDisconnMsg = (P_MSG_P2P_CONNECTION_ABORT_T) + * MemAlloc(sizeof(P_MSG_P2P_CONNECTION_ABORT_T), VIR_MEM_TYPE); + */ + prDisconnMsg = + (struct MSG_P2P_CONNECTION_ABORT *) + cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, + sizeof(struct MSG_P2P_CONNECTION_ABORT)); + + if (prDisconnMsg == NULL) { + i4Rslt = -ENOMEM; + break; + } + + prDisconnMsg->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_ABORT; + prDisconnMsg->ucRoleIdx = ucRoleIdx; + prDisconnMsg->u2ReasonCode = reason_code; + prDisconnMsg->fgSendDeauth = TRUE; + COPY_MAC_ADDR(prDisconnMsg->aucTargetID, aucBCAddr); + + mboxSendMsg(prGlueInfo->prAdapter, + MBOX_ID_0, + (struct MSG_HDR *) prDisconnMsg, + MSG_SEND_METHOD_BUF); + + i4Rslt = 0; + } while (FALSE); + + return i4Rslt; +} /* mtk_p2p_cfg80211_disconnect */ + +int +mtk_p2p_cfg80211_change_iface(IN struct wiphy *wiphy, + IN struct net_device *ndev, + IN enum nl80211_iftype type, + IN u32 *flags, + IN struct vif_params *params) +{ + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *) NULL; + int32_t i4Rslt = -EINVAL; + struct MSG_P2P_SWITCH_OP_MODE *prSwitchModeMsg = + (struct MSG_P2P_SWITCH_OP_MODE *) NULL; + uint8_t ucRoleIdx = 0; + + do { + if ((wiphy == NULL) || (ndev == NULL)) { + DBGLOG(P2P, ERROR, "wiphy=%p, ndev=%p.\n", wiphy, ndev); + break; + } + + DBGLOG(P2P, INFO, + "mtk_p2p_cfg80211_change_iface, type: %d\n", type); + + if (ndev->ieee80211_ptr) + ndev->ieee80211_ptr->iftype = type; + + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + + if (mtk_Netdev_To_RoleIdx(prGlueInfo, ndev, &ucRoleIdx) != 0) { + DBGLOG(P2P, TRACE, + "Device Interface no need to change interface type.\n"); + return 0; + } + /* Switch OP MOde. */ + prSwitchModeMsg = + (struct MSG_P2P_SWITCH_OP_MODE *) + cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, + sizeof(struct MSG_P2P_SWITCH_OP_MODE)); + + if (prSwitchModeMsg == NULL) { + i4Rslt = -ENOMEM; + break; + } + + prSwitchModeMsg->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH; + prSwitchModeMsg->ucRoleIdx = ucRoleIdx; + + switch (type) { + case NL80211_IFTYPE_P2P_CLIENT: + DBGLOG(P2P, TRACE, "NL80211_IFTYPE_P2P_CLIENT.\n"); + prSwitchModeMsg->eIftype = IFTYPE_P2P_CLIENT; + /* This case need to fall through */ + case NL80211_IFTYPE_STATION: + if (type == NL80211_IFTYPE_STATION) { + DBGLOG(P2P, TRACE, "NL80211_IFTYPE_STATION.\n"); + prSwitchModeMsg->eIftype = IFTYPE_STATION; + } + prSwitchModeMsg->eOpMode = OP_MODE_INFRASTRUCTURE; + kalP2PSetRole(prGlueInfo, 1, ucRoleIdx); + break; + case NL80211_IFTYPE_AP: + DBGLOG(P2P, TRACE, "NL80211_IFTYPE_AP.\n"); + kalP2PSetRole(prGlueInfo, 2, ucRoleIdx); + prSwitchModeMsg->eIftype = IFTYPE_AP; + /* This case need to fall through */ + case NL80211_IFTYPE_P2P_GO: + if (type == NL80211_IFTYPE_P2P_GO) { + DBGLOG(P2P, TRACE, + "NL80211_IFTYPE_P2P_GO not AP.\n"); + prSwitchModeMsg->eIftype = IFTYPE_P2P_GO; + } + prSwitchModeMsg->eOpMode = OP_MODE_ACCESS_POINT; + kalP2PSetRole(prGlueInfo, 2, ucRoleIdx); + break; + default: + DBGLOG(P2P, TRACE, "Other type :%d .\n", type); + prSwitchModeMsg->eOpMode = OP_MODE_P2P_DEVICE; + kalP2PSetRole(prGlueInfo, 0, ucRoleIdx); + prSwitchModeMsg->eIftype = IFTYPE_P2P_DEVICE; + break; + } + + mboxSendMsg(prGlueInfo->prAdapter, + MBOX_ID_0, + (struct MSG_HDR *) prSwitchModeMsg, + MSG_SEND_METHOD_BUF); + + i4Rslt = 0; + + } while (FALSE); + + return i4Rslt; + +} /* mtk_p2p_cfg80211_change_iface */ + +int mtk_p2p_cfg80211_set_channel(IN struct wiphy *wiphy, + struct cfg80211_chan_def *chandef) +{ + int32_t i4Rslt = -EINVAL; + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *) NULL; + struct RF_CHANNEL_INFO rRfChnlInfo; + uint8_t ucRoleIdx = 0; + struct net_device *dev = NULL; + + if ((wiphy == NULL) || (chandef == NULL)) + return i4Rslt; + + dev = (struct net_device *) wiphy_dev(wiphy); + + do { + DBGLOG(P2P, INFO, "mtk_p2p_cfg80211_set_channel.\n"); + + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + + kalChannelFormatSwitch(chandef, chandef->chan, &rRfChnlInfo); + + if (mtk_Netdev_To_RoleIdx(prGlueInfo, dev, &ucRoleIdx) < 0) + break; + + p2pFuncSetChannel(prGlueInfo->prAdapter, + ucRoleIdx, &rRfChnlInfo); + + i4Rslt = 0; + } while (FALSE); + + return i4Rslt; + +} + +/* mtk_p2p_cfg80211_set_channel */ + +int +mtk_p2p_cfg80211_set_bitrate_mask(IN struct wiphy *wiphy, + IN struct net_device *dev, + IN const u8 *peer, + IN const struct cfg80211_bitrate_mask *mask) +{ + int32_t i4Rslt = -EINVAL; + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *) NULL; + + do { + if ((wiphy == NULL) || (dev == NULL) || (mask == NULL)) + break; + + DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_set_bitrate_mask\n"); + + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + + /* TODO: Set bitrate mask of the peer? */ + + i4Rslt = 0; + } while (FALSE); + + return i4Rslt; +} /* mtk_p2p_cfg80211_set_bitrate_mask */ + +void mtk_p2p_cfg80211_mgmt_frame_register(IN struct wiphy *wiphy, + struct wireless_dev *wdev, + IN u16 frame_type, IN bool reg) +{ +#if 0 + struct MSG_P2P_MGMT_FRAME_REGISTER *prMgmtFrameRegister = + (struct MSG_P2P_MGMT_FRAME_REGISTER *) NULL; +#endif + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *) NULL; + int iftype = 0; + uint8_t ucRoleIdx = 0; + uint32_t *pu4P2pPacketFilter = NULL; + struct P2P_ROLE_FSM_INFO *prP2pRoleFsmInfo = + (struct P2P_ROLE_FSM_INFO *) NULL; + + do { + if ((wiphy == NULL) || (wdev == NULL)) + break; + + DBGLOG(P2P, TRACE, "netdev: 0x%p, frame_type: 0x%x, reg: %d\n", + wdev->netdev, frame_type, reg); + + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + + /* since p2p device share the aprRoleHandler + * so needs to check DevHandler 1st + */ + if (prGlueInfo->prP2PInfo[0]->prDevHandler == wdev->netdev) { + /* P2P device*/ + pu4P2pPacketFilter = + &prGlueInfo->prP2PDevInfo->u4OsMgmtFrameFilter; + } else { + if (mtk_Netdev_To_RoleIdx(prGlueInfo, + wdev->netdev, &ucRoleIdx) < 0) { + DBGLOG(P2P, WARN, "wireless dev match fail!\n"); + break; + } else { + /* Non P2P device*/ + ASSERT(ucRoleIdx < KAL_P2P_NUM); + DBGLOG(P2P, TRACE, + "Open packet filer RoleIdx %u\n", + ucRoleIdx); + prP2pRoleFsmInfo = + prGlueInfo->prAdapter + ->rWifiVar.aprP2pRoleFsmInfo[ucRoleIdx]; + pu4P2pPacketFilter = + &prP2pRoleFsmInfo->u4P2pPacketFilter; + } + } + switch (frame_type) { + case MAC_FRAME_PROBE_REQ: + if (reg) { + *pu4P2pPacketFilter + |= PARAM_PACKET_FILTER_PROBE_REQ; + DBGLOG(P2P, TRACE, + "Open packet filer probe request\n"); + } else { + iftype = wdev->netdev->ieee80211_ptr->iftype; + + /* Skip disabling of Probe Request + * while in AP mode. + */ + if (iftype == NL80211_IFTYPE_AP || + iftype == NL80211_IFTYPE_P2P_GO) { + DBGLOG(P2P, INFO, + "Skip disabling of probe request for %d\n", + iftype); + break; + } + + *pu4P2pPacketFilter + &= ~PARAM_PACKET_FILTER_PROBE_REQ; + DBGLOG(P2P, TRACE, + "Close packet filer probe request\n"); + } + break; + case MAC_FRAME_ACTION: + if (reg) { + *pu4P2pPacketFilter + |= PARAM_PACKET_FILTER_ACTION_FRAME; + DBGLOG(P2P, TRACE, + "Open packet filer action frame.\n"); + } else { + *pu4P2pPacketFilter + &= ~PARAM_PACKET_FILTER_ACTION_FRAME; + DBGLOG(P2P, TRACE, + "Close packet filer action frame.\n"); + } + break; +#if CFG_SUPPORT_SOFTAP_WPA3 + case MAC_FRAME_AUTH: + if (reg) { + *pu4P2pPacketFilter + |= PARAM_PACKET_FILTER_AUTH; + DBGLOG(P2P, TRACE, + "Open packet filer auth request\n"); + } else { + *pu4P2pPacketFilter + &= ~PARAM_PACKET_FILTER_AUTH; + DBGLOG(P2P, TRACE, + "Close packet filer auth request\n"); + } + break; + case MAC_FRAME_ASSOC_REQ: + if (reg) { + *pu4P2pPacketFilter + |= PARAM_PACKET_FILTER_ASSOC_REQ; + DBGLOG(P2P, TRACE, + "Open packet filer assoc request\n"); + } else { + *pu4P2pPacketFilter + &= ~PARAM_PACKET_FILTER_ASSOC_REQ; + DBGLOG(P2P, TRACE, + "Close packet filer assoc request\n"); + } + break; +#endif + default: + DBGLOG(P2P, ERROR, + "Ask frog to add code for mgmt:%x\n", + frame_type); + break; + } + + set_bit(GLUE_FLAG_FRAME_FILTER_BIT, &prGlueInfo->ulFlag); + + /* wake up main thread */ + wake_up_interruptible(&prGlueInfo->waitq); + + if (in_interrupt()) + DBGLOG(P2P, TRACE, "It is in interrupt level\n"); +#if 0 + + prMgmtFrameRegister = + (struct MSG_P2P_MGMT_FRAME_REGISTER *) + cnmMemAlloc(prGlueInfo->prAdapter, + RAM_TYPE_MSG, + sizeof(struct MSG_P2P_MGMT_FRAME_REGISTER)); + + if (prMgmtFrameRegister == NULL) { + ASSERT(FALSE); + break; + } + + prMgmtFrameRegister->rMsgHdr.eMsgId = + MID_MNY_P2P_MGMT_FRAME_REGISTER; + + prMgmtFrameRegister->u2FrameType = frame_type; + prMgmtFrameRegister->fgIsRegister = reg; + + mboxSendMsg(prGlueInfo->prAdapter, + MBOX_ID_0, + (struct MSG_HDR *) prMgmtFrameRegister, + MSG_SEND_METHOD_BUF); + +#endif + + } while (FALSE); + +} /* mtk_p2p_cfg80211_mgmt_frame_register */ + +#ifdef CONFIG_NL80211_TESTMODE + +#if KERNEL_VERSION(3, 12, 0) <= CFG80211_VERSION_CODE +int mtk_p2p_cfg80211_testmode_cmd(struct wiphy *wiphy, + struct wireless_dev *wdev, void *data, + int len) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct NL80211_DRIVER_TEST_PARAMS *prParams = + (struct NL80211_DRIVER_TEST_PARAMS *) NULL; + int32_t i4Status = -EINVAL; + + ASSERT(wiphy); + ASSERT(wdev); + + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + + DBGLOG(P2P, INFO, "mtk_p2p_cfg80211_testmode_cmd\n"); + + if (data && len) { + prParams = (struct NL80211_DRIVER_TEST_PARAMS *) data; + } else { + DBGLOG(P2P, ERROR, + "mtk_p2p_cfg80211_testmode_cmd, data is NULL\n"); + return i4Status; + } + if (prParams->index >> 24 == 0x01) { + /* New version */ + prParams->index = prParams->index & ~BITS(24, 31); + } else { + /* Old version */ + mtk_p2p_cfg80211_testmode_p2p_sigma_pre_cmd(wiphy, data, len); + i4Status = 0; + return i4Status; + } + + /* Clear the version byte */ + prParams->index = prParams->index & ~BITS(24, 31); + + if (prParams) { + switch (prParams->index) { + case 1: /* P2P Simga */ +#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION + { + struct NL80211_DRIVER_SW_CMD_PARAMS + *prParamsCmd; + + prParamsCmd = + (struct NL80211_DRIVER_SW_CMD_PARAMS *) + data; + + if ((prParamsCmd->adr & 0xffff0000) + == 0xffff0000) { + i4Status = + mtk_p2p_cfg80211_testmode_sw_cmd( + wiphy, data, len); + break; + } + } +#endif + i4Status = mtk_p2p_cfg80211_testmode_p2p_sigma_cmd( + wiphy, data, len); + break; + case 2: /* WFD */ +#if CFG_SUPPORT_WFD + /* use normal driver command wifi_display */ + /* i4Status = + * mtk_p2p_cfg80211_testmode_wfd_update_cmd( + * wiphy, data, len); + */ +#endif + break; + case 3: /* Hotspot Client Management */ +#if CFG_SUPPORT_HOTSPOT_WPS_MANAGER + i4Status = + mtk_p2p_cfg80211_testmode_hotspot_block_list_cmd( + wiphy, data, len); +#endif + break; + case 0x10: + i4Status = + mtk_cfg80211_testmode_get_sta_statistics( + wiphy, data, len, prGlueInfo); + break; +#if CFG_SUPPORT_NFC_BEAM_PLUS + case 0x11: /*NFC Beam + Indication */ + if (data && len) { + struct NL80211_DRIVER_SET_NFC_PARAMS *prParams = + (struct NL80211_DRIVER_SET_NFC_PARAMS *) + data; + + DBGLOG(P2P, INFO, + "NFC: BEAM[%d]\n", + prParams->NFC_Enable); + } + break; + case 0x12: /*NFC Beam + Indication */ + DBGLOG(P2P, INFO, "NFC: Polling\n"); + i4Status = + mtk_cfg80211_testmode_get_scan_done( + wiphy, data, len, prGlueInfo); + break; +#endif + case TESTMODE_CMD_ID_HS_CONFIG: + i4Status = + mtk_p2p_cfg80211_testmode_hotspot_config_cmd( + wiphy, data, len); + break; + + default: + i4Status = -EOPNOTSUPP; + break; + } + } + + return i4Status; + +} +#else +int mtk_p2p_cfg80211_testmode_cmd(struct wiphy *wiphy, void *data, int len) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct NL80211_DRIVER_TEST_PARAMS *prParams = + (struct NL80211_DRIVER_TEST_PARAMS *) NULL; + int32_t i4Status = -EINVAL; + + ASSERT(wiphy); + + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + + DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_testmode_cmd\n"); + + if (data && len) { + prParams = (struct NL80211_DRIVER_TEST_PARAMS *) data; + } else { + DBGLOG(P2P, ERROR, "data is NULL\n"); + return i4Status; + } + if (prParams->index >> 24 == 0x01) { + /* New version */ + prParams->index = prParams->index & ~BITS(24, 31); + } else { + /* Old version */ + mtk_p2p_cfg80211_testmode_p2p_sigma_pre_cmd(wiphy, data, len); + i4Status = 0; + return i4Status; + } + + /* Clear the version byte */ + prParams->index = prParams->index & ~BITS(24, 31); + + if (prParams) { + switch (prParams->index) { + case 1: /* P2P Simga */ +#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION + { + struct NL80211_DRIVER_SW_CMD_PARAMS + *prParamsCmd; + + prParamsCmd = + (struct NL80211_DRIVER_SW_CMD_PARAMS *) + data; + + if ((prParamsCmd->adr & 0xffff0000) + == 0xffff0000) { + i4Status = + mtk_p2p_cfg80211_testmode_sw_cmd( + wiphy, data, len); + break; + } + } +#endif + i4Status = mtk_p2p_cfg80211_testmode_p2p_sigma_cmd( + wiphy, data, len); + break; + case 2: /* WFD */ +#if CFG_SUPPORT_WFD + /* use normal driver command wifi_display */ + /* i4Status = mtk_p2p_cfg80211_testmode_wfd_update_cmd( + * wiphy, data, len); + */ +#endif + break; + case 3: /* Hotspot Client Management */ +#if CFG_SUPPORT_HOTSPOT_WPS_MANAGER + i4Status = + mtk_p2p_cfg80211_testmode_hotspot_block_list_cmd( + wiphy, data, len); +#endif + break; + case 0x10: + i4Status = + mtk_cfg80211_testmode_get_sta_statistics( + wiphy, data, len, prGlueInfo); + break; +#if CFG_SUPPORT_NFC_BEAM_PLUS + case 0x11: /*NFC Beam + Indication */ + if (data && len) { + struct NL80211_DRIVER_SET_NFC_PARAMS *prParams = + (struct NL80211_DRIVER_SET_NFC_PARAMS *) + data; + + DBGLOG(P2P, INFO, + "NFC: BEAM[%d]\n", + prParams->NFC_Enable); + } + break; + case 0x12: /*NFC Beam + Indication */ + DBGLOG(P2P, INFO, "NFC: Polling\n"); + i4Status = + mtk_cfg80211_testmode_get_scan_done( + wiphy, data, len, prGlueInfo); + break; +#endif + case TESTMODE_CMD_ID_HS_CONFIG: + i4Status = + mtk_p2p_cfg80211_testmode_hotspot_config_cmd( + wiphy, data, len); + break; + + default: + i4Status = -EOPNOTSUPP; + break; + } + } + + return i4Status; + +} +#endif + +int mtk_p2p_cfg80211_testmode_hotspot_config_cmd(IN struct wiphy *wiphy, + IN void *data, IN int len) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct NL80211_DRIVER_HOTSPOT_CONFIG_PARAMS *prParams = + (struct NL80211_DRIVER_HOTSPOT_CONFIG_PARAMS *) NULL; + uint32_t index; + uint32_t value; + uint32_t i; + + ASSERT(wiphy); + + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + + if (data && len) { + prParams = (struct NL80211_DRIVER_HOTSPOT_CONFIG_PARAMS *) data; + } else { + DBGLOG(P2P, ERROR, "data is NULL or len is 0\n"); + return -EINVAL; + } + + index = prParams->idx; + value = prParams->value; + + DBGLOG(P2P, INFO, "NL80211_ATTR_TESTDATA, idx=%d value=%d\n", + (uint32_t) prParams->idx, (uint32_t) prParams->value); + + switch (index) { + case 1: /* Max Clients */ + for (i = 0; i < KAL_P2P_NUM; i++) + if (p2pFuncIsAPMode(prGlueInfo->prAdapter + ->rWifiVar.prP2PConnSettings[i])) + kalP2PSetMaxClients(prGlueInfo, value, i); + break; + default: + break; + } + + return 0; +} + +int mtk_p2p_cfg80211_testmode_p2p_sigma_pre_cmd(IN struct wiphy *wiphy, + IN void *data, IN int len) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct NL80211_DRIVER_TEST_PRE_PARAMS rParams; + struct P2P_SPECIFIC_BSS_INFO *prP2pSpecificBssInfo = + (struct P2P_SPECIFIC_BSS_INFO *) NULL; + /* P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = + * (P_P2P_CONNECTION_SETTINGS_T)NULL; + */ + uint32_t index_mode; + uint32_t index; + int32_t value; + int status = 0; + uint32_t u4Leng; + uint8_t ucBssIdx; + + if (len > sizeof(struct NL80211_DRIVER_TEST_PRE_PARAMS)) { + DBGLOG(P2P, WARN, "len [%d] is invalid!\n", + len); + return -EINVAL; + } + + ASSERT(wiphy); + + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + + kalMemZero(&rParams, sizeof(struct NL80211_DRIVER_TEST_PRE_PARAMS)); + + prP2pSpecificBssInfo = + prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo[0]; + /* prP2pConnSettings = + * prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings; + */ + + if (data && len) + memcpy(&rParams, data, len); + + DBGLOG(P2P, TRACE, + "NL80211_ATTR_TESTDATA, idx_mode=%d idx=%d value=%u\n", + rParams.idx_mode, + rParams.idx, + rParams.value); + + index_mode = rParams.idx_mode; + index = rParams.idx; + value = rParams.value; + + /* 3 FIX ME: Add p2p role index selection */ + if (p2pFuncRoleToBssIdx( + prGlueInfo->prAdapter, 0, &ucBssIdx) != WLAN_STATUS_SUCCESS) + return -EINVAL; + + switch (index) { + case 0: /* Listen CH */ + break; + case 1: /* P2p mode */ + break; + case 4: /* Noa duration */ + prP2pSpecificBssInfo->rNoaParam.u4NoaDurationMs = value; + /* only to apply setting when setting NOA count */ + /* status = + * mtk_p2p_wext_set_noa_param(prDev, + * info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); + */ + break; + case 5: /* Noa interval */ + prP2pSpecificBssInfo->rNoaParam.u4NoaIntervalMs = value; + /* only to apply setting when setting NOA count */ + /* status = + * mtk_p2p_wext_set_noa_param(prDev, + * info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); + */ + break; + case 6: /* Noa count */ + prP2pSpecificBssInfo->rNoaParam.u4NoaCount = value; + /* status = + * mtk_p2p_wext_set_noa_param(prDev, + * info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); + */ + break; + case 100: /* Oper CH */ + /* 20110920 - frog: + * User configurations are placed in ConnSettings. + */ + /* prP2pConnSettings->ucOperatingChnl = value; */ + break; + case 101: /* Local config Method, for P2P SDK */ + /* prP2pConnSettings->u2LocalConfigMethod = value; */ + break; + case 102: /* Sigma P2p reset */ + /* kalMemZero(prP2pConnSettings->aucTargetDevAddr, + * MAC_ADDR_LEN); + */ + /* prP2pConnSettings->eConnectionPolicy = + * ENUM_P2P_CONNECTION_POLICY_AUTO; + */ + /* p2pFsmUninit(prGlueInfo->prAdapter); */ + /* p2pFsmInit(prGlueInfo->prAdapter); */ + break; + case 103: /* WPS MODE */ + kalP2PSetWscMode(prGlueInfo, value); + break; + case 104: /* P2p send persence, duration */ + break; + case 105: /* P2p send persence, interval */ + break; + case 106: /* P2P set sleep */ + { + struct PARAM_POWER_MODE_ rPowerMode; + uint32_t rStatus; + + rPowerMode.ePowerMode = Param_PowerModeMAX_PSP; + rPowerMode.ucBssIdx = ucBssIdx; + + rStatus = kalIoctl(prGlueInfo, + wlanoidSet802dot11PowerSaveProfile, + &rPowerMode, + sizeof(rPowerMode), + FALSE, FALSE, TRUE, &u4Leng); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, WARN, + "set_power_mgmt error:%x\n", rStatus); + return -EFAULT; + } + } + break; + case 107: /* P2P set opps, CTWindowl */ + prP2pSpecificBssInfo->rOppPsParam.u4CTwindowMs = value; + /* status = mtk_p2p_wext_set_oppps_param(prDev, info, wrqu, + * (char *)&prP2pSpecificBssInfo->rOppPsParam); + */ + break; + case 108: /* p2p_set_power_save */ + { + struct PARAM_POWER_MODE_ rPowerMode; + uint32_t rStatus; + + rPowerMode.ePowerMode = value; + rPowerMode.ucBssIdx = ucBssIdx; + + rStatus = kalIoctl(prGlueInfo, + wlanoidSet802dot11PowerSaveProfile, + &rPowerMode, + sizeof(rPowerMode), + FALSE, FALSE, TRUE, &u4Leng); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, WARN, + "set_power_mgmt error:%x\n", rStatus); + return -EFAULT; + } + } + break; + default: + break; + } + + return status; + +} + +int mtk_p2p_cfg80211_testmode_p2p_sigma_cmd(IN struct wiphy *wiphy, + IN void *data, IN int len) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct NL80211_DRIVER_P2P_SIGMA_PARAMS *prParams = + (struct NL80211_DRIVER_P2P_SIGMA_PARAMS *) NULL; + struct P2P_SPECIFIC_BSS_INFO *prP2pSpecificBssInfo = + (struct P2P_SPECIFIC_BSS_INFO *) NULL; + /* P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = + * (P_P2P_CONNECTION_SETTINGS_T)NULL; + */ + uint32_t rStatus; + uint32_t index; + int32_t value; + int status = 0; + uint32_t u4Leng; + uint8_t ucBssIdx; + uint32_t i; + struct NL80211_DRIVER_P2P_NOA_PARAMS { + struct NL80211_DRIVER_TEST_PARAMS hdr; + uint32_t idx; + uint32_t value; /* should not be used in this case */ + uint32_t count; + uint32_t interval; + uint32_t duration; + }; + struct NL80211_DRIVER_P2P_NOA_PARAMS *prNoaParams = NULL; + + ASSERT(wiphy); + + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + + prP2pSpecificBssInfo = + prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo[0]; + /* prP2pConnSettings = + * prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings; + */ + + if (data && len) + prParams = (struct NL80211_DRIVER_P2P_SIGMA_PARAMS *) data; + else { + DBGLOG(P2P, ERROR, "data is NULL\n"); + return -EINVAL; + } + + index = (int32_t) prParams->idx; + value = (int32_t) prParams->value; + + DBGLOG(P2P, INFO, "NL80211_ATTR_TESTDATA, idx=%u value=%u\n", + prParams->idx, prParams->value); + + /* 3 FIX ME: Add p2p role index selection */ + if (p2pFuncRoleToBssIdx( + prGlueInfo->prAdapter, 0, &ucBssIdx) != WLAN_STATUS_SUCCESS) + return -EINVAL; + + switch (index) { + case 0: /* Listen CH */ + break; + case 1: /* P2p mode */ + break; + case 4: /* Noa duration */ + prNoaParams = data; + prP2pSpecificBssInfo->rNoaParam.u4NoaCount = prNoaParams->count; + prP2pSpecificBssInfo->rNoaParam.u4NoaIntervalMs = + prNoaParams->interval; + prP2pSpecificBssInfo->rNoaParam.u4NoaDurationMs = + prNoaParams->duration; + prP2pSpecificBssInfo->rNoaParam.ucBssIdx = + ucBssIdx; + DBGLOG(P2P, INFO, + "SET NOA[%d]: %d %d %d\n", + ucBssIdx, + prNoaParams->count, + prNoaParams->interval, + prNoaParams->duration); + + /* only to apply setting when setting NOA count */ + rStatus = kalIoctl(prGlueInfo, + wlanoidSetNoaParam, + &prP2pSpecificBssInfo->rNoaParam, + sizeof(struct PARAM_CUSTOM_NOA_PARAM_STRUCT), + FALSE, FALSE, TRUE, &u4Leng); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, WARN, "set_noa error:%x\n", rStatus); + return -EFAULT; + } + break; + case 5: /* Noa interval */ + prP2pSpecificBssInfo->rNoaParam.u4NoaIntervalMs = value; + /* only to apply setting when setting NOA count */ + /* status = + * mtk_p2p_wext_set_noa_param(prDev, + * info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); + */ + break; + case 6: /* Noa count */ + prP2pSpecificBssInfo->rNoaParam.u4NoaCount = value; + /* status = + * mtk_p2p_wext_set_noa_param(prDev, + * info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); + */ + break; + case 100: /* Oper CH */ + /* 20110920 - frog: + * User configurations are placed in ConnSettings. + */ + /* prP2pConnSettings->ucOperatingChnl = value; */ + break; + case 101: /* Local config Method, for P2P SDK */ + /* prP2pConnSettings->u2LocalConfigMethod = value; */ + break; + case 102: /* Sigma P2p reset */ + /* kalMemZero(prP2pConnSettings->aucTargetDevAddr, + * MAC_ADDR_LEN); + */ + /* prP2pConnSettings->eConnectionPolicy = + * ENUM_P2P_CONNECTION_POLICY_AUTO; + */ + break; + case 103: /* WPS MODE */ + kalP2PSetWscMode(prGlueInfo, value); + break; + case 104: /* P2p send persence, duration */ + break; + case 105: /* P2p send persence, interval */ + break; + case 106: /* P2P set sleep */ + { + struct PARAM_POWER_MODE_ rPowerMode; + + rPowerMode.ePowerMode = Param_PowerModeMAX_PSP; + rPowerMode.ucBssIdx = ucBssIdx; + + rStatus = kalIoctl(prGlueInfo, + wlanoidSet802dot11PowerSaveProfile, + &rPowerMode, + sizeof(rPowerMode), + FALSE, FALSE, TRUE, &u4Leng); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, WARN, + "set_power_mgmt error:%x\n", rStatus); + return -EFAULT; + } + } + break; + case 107: /* P2P set opps, CTWindowl */ + prP2pSpecificBssInfo->rOppPsParam.u4CTwindowMs = value; + prP2pSpecificBssInfo->rOppPsParam.ucBssIdx = ucBssIdx; + DBGLOG(P2P, INFO, "SET OPPS[%d]: %d\n", ucBssIdx, value); + rStatus = kalIoctl(prGlueInfo, + wlanoidSetOppPsParam, + &prP2pSpecificBssInfo->rOppPsParam, + sizeof(struct PARAM_CUSTOM_OPPPS_PARAM_STRUCT), + FALSE, FALSE, TRUE, &u4Leng); + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, WARN, + "set_opps error:%x\n", rStatus); + return -EFAULT; + } + break; + case 108: /* p2p_set_power_save */ + { + struct PARAM_POWER_MODE_ rPowerMode; + + rPowerMode.ePowerMode = value; + rPowerMode.ucBssIdx = ucBssIdx; + + rStatus = kalIoctl(prGlueInfo, + wlanoidSet802dot11PowerSaveProfile, + &rPowerMode, sizeof(rPowerMode), + FALSE, FALSE, TRUE, &u4Leng); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, WARN, + "set_power_mgmt error:%x\n", rStatus); + return -EFAULT; + } + } + break; + case 109: /* Max Clients */ +#if CFG_SUPPORT_HOTSPOT_WPS_MANAGER + for (i = 0; i < KAL_P2P_NUM; i++) + if (p2pFuncIsAPMode(prGlueInfo->prAdapter + ->rWifiVar.prP2PConnSettings[i])) + kalP2PSetMaxClients(prGlueInfo, value, i); +#endif + break; + case 110: /* Hotspot WPS mode */ +#if CFG_SUPPORT_HOTSPOT_WPS_MANAGER + rStatus = kalIoctl(prGlueInfo, + wlanoidSetP2pWPSmode, + &value, sizeof(value), + FALSE, FALSE, TRUE, &u4Leng); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, WARN, + "set_wps error:%x\n", rStatus); + return -EFAULT; + } +#endif + break; + default: + break; + } + + return status; + +} + +#if CFG_SUPPORT_WFD && 0 +/* obsolete/decrepated */ +int mtk_p2p_cfg80211_testmode_wfd_update_cmd(IN struct wiphy *wiphy, + IN void *data, IN int len) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct NL80211_DRIVER_WFD_PARAMS *prParams = + (struct NL80211_DRIVER_WFD_PARAMS *) NULL; + int status = 0; + struct WFD_CFG_SETTINGS *prWfdCfgSettings = + (struct WFD_CFG_SETTINGS *) NULL; + struct MSG_WFD_CONFIG_SETTINGS_CHANGED *prMsgWfdCfgUpdate = + (struct MSG_WFD_CONFIG_SETTINGS_CHANGED *) NULL; + + ASSERT(wiphy); + + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + + prParams = (struct NL80211_DRIVER_WFD_PARAMS *) data; + + DBGLOG(P2P, INFO, "mtk_p2p_cfg80211_testmode_wfd_update_cmd\n"); + +#if 1 + + DBGLOG(P2P, INFO, "WFD Enable:%x\n", prParams->WfdEnable); + DBGLOG(P2P, INFO, + "WFD Session Available:%x\n", + prParams->WfdSessionAvailable); + DBGLOG(P2P, INFO, + "WFD Couple Sink Status:%x\n", + prParams->WfdCoupleSinkStatus); + /* aucReserved0[2] */ + DBGLOG(P2P, INFO, "WFD Device Info:%x\n", prParams->WfdDevInfo); + DBGLOG(P2P, INFO, "WFD Control Port:%x\n", prParams->WfdControlPort); + DBGLOG(P2P, INFO, + "WFD Maximum Throughput:%x\n", + prParams->WfdMaximumTp); + DBGLOG(P2P, INFO, "WFD Extend Capability:%x\n", prParams->WfdExtendCap); + DBGLOG(P2P, INFO, + "WFD Couple Sink Addr " MACSTR "\n", + MAC2STR(prParams->WfdCoupleSinkAddress)); + DBGLOG(P2P, INFO, + "WFD Associated BSSID " MACSTR "\n", + MAC2STR(prParams->WfdAssociatedBssid)); + /* UINT_8 aucVideolp[4]; */ + /* UINT_8 aucAudiolp[4]; */ + DBGLOG(P2P, INFO, "WFD Video Port:%x\n", prParams->WfdVideoPort); + DBGLOG(P2P, INFO, "WFD Audio Port:%x\n", prParams->WfdAudioPort); + DBGLOG(P2P, INFO, "WFD Flag:%x\n", prParams->WfdFlag); + DBGLOG(P2P, INFO, "WFD Policy:%x\n", prParams->WfdPolicy); + DBGLOG(P2P, INFO, "WFD State:%x\n", prParams->WfdState); + /* UINT_8 aucWfdSessionInformationIE[24*8]; */ + DBGLOG(P2P, INFO, + "WFD Session Info Length:%x\n", + prParams->WfdSessionInformationIELen); + /* UINT_8 aucReserved1[2]; */ + DBGLOG(P2P, INFO, + "WFD Primary Sink Addr " MACSTR "\n", + MAC2STR(prParams->aucWfdPrimarySinkMac)); + DBGLOG(P2P, INFO, + "WFD Secondary Sink Addr " MACSTR "\n", + MAC2STR(prParams->aucWfdSecondarySinkMac)); + DBGLOG(P2P, INFO, "WFD Advanced Flag:%x\n", prParams->WfdAdvanceFlag); + DBGLOG(P2P, INFO, "WFD Sigma mode:%x\n", prParams->WfdSigmaMode); + /* UINT_8 aucReserved2[64]; */ + /* UINT_8 aucReserved3[64]; */ + /* UINT_8 aucReserved4[64]; */ + +#endif + + prWfdCfgSettings = + &(prGlueInfo->prAdapter->rWifiVar.rWfdConfigureSettings); + + kalMemCopy(&prWfdCfgSettings->u4WfdCmdType, + &prParams->WfdCmdType, + sizeof(struct WFD_CFG_SETTINGS)); + + prMsgWfdCfgUpdate = cnmMemAlloc(prGlueInfo->prAdapter, + RAM_TYPE_MSG, + sizeof(struct MSG_WFD_CONFIG_SETTINGS_CHANGED)); + + if (prMsgWfdCfgUpdate == NULL) { + return status; + } + + prMsgWfdCfgUpdate->rMsgHdr.eMsgId = MID_MNY_P2P_WFD_CFG_UPDATE; + prMsgWfdCfgUpdate->prWfdCfgSettings = prWfdCfgSettings; + + mboxSendMsg(prGlueInfo->prAdapter, + MBOX_ID_0, + (struct MSG_HDR *) prMsgWfdCfgUpdate, + MSG_SEND_METHOD_BUF); + +#if 0 /* Test Only */ +/* prWfdCfgSettings->ucWfdEnable = 1; */ +/* prWfdCfgSettings->u4WfdFlag |= WFD_FLAGS_DEV_INFO_VALID; */ + prWfdCfgSettings->u4WfdFlag |= WFD_FLAGS_DEV_INFO_VALID; + prWfdCfgSettings->u2WfdDevInfo = 123; + prWfdCfgSettings->u2WfdControlPort = 456; + prWfdCfgSettings->u2WfdMaximumTp = 789; + + prWfdCfgSettings->u4WfdFlag |= WFD_FLAGS_SINK_INFO_VALID; + prWfdCfgSettings->ucWfdCoupleSinkStatus = 0xAB; + { + uint8_t aucTestAddr[MAC_ADDR_LEN] = { + 0x77, 0x66, 0x55, 0x44, 0x33, 0x22 }; + + COPY_MAC_ADDR(prWfdCfgSettings->aucWfdCoupleSinkAddress, + aucTestAddr); + } + + prWfdCfgSettings->u4WfdFlag |= WFD_FLAGS_EXT_CAPABILITY_VALID; + prWfdCfgSettings->u2WfdExtendCap = 0xCDE; + +#endif + + return status; + +} +#endif /* CFG_SUPPORT_WFD */ + +#if CFG_SUPPORT_HOTSPOT_WPS_MANAGER + +int mtk_p2p_cfg80211_testmode_hotspot_block_list_cmd(IN struct wiphy *wiphy, + IN void *data, IN int len) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct NL80211_DRIVER_hotspot_block_PARAMS *prParams = + (struct NL80211_DRIVER_hotspot_block_PARAMS *) NULL; + int fgIsValid = 0; + uint32_t i; + + ASSERT(wiphy); + + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + + if (data && len) + prParams = (struct NL80211_DRIVER_hotspot_block_PARAMS *) data; + else + return fgIsValid; + + DBGLOG(P2P, INFO, + "%s" MACSTR "\n", + prParams->ucblocked?"Block":"Unblock", + MAC2STR(prParams->aucBssid)); + + for (i = 0; i < KAL_P2P_NUM; i++) + fgIsValid |= + kalP2PSetBlackList(prGlueInfo, + prParams->aucBssid, prParams->ucblocked, i); + + return fgIsValid; + +} + +#endif + +int mtk_p2p_cfg80211_testmode_sw_cmd(IN struct wiphy *wiphy, + IN void *data, IN int len) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct NL80211_DRIVER_SW_CMD_PARAMS *prParams = + (struct NL80211_DRIVER_SW_CMD_PARAMS *) NULL; + uint32_t rstatus = WLAN_STATUS_SUCCESS; + int fgIsValid = 0; + uint32_t u4SetInfoLen = 0; + + ASSERT(wiphy); + + P2P_WIPHY_PRIV(wiphy, prGlueInfo); + + DBGLOG(P2P, TRACE, "--> %s()\n", __func__); + + if (data && len) + prParams = (struct NL80211_DRIVER_SW_CMD_PARAMS *) data; + + if (prParams) { + if (prParams->set == 1) { + rstatus = kalIoctl(prGlueInfo, + (PFN_OID_HANDLER_FUNC) wlanoidSetSwCtrlWrite, + &prParams->adr, (uint32_t) 8, + FALSE, FALSE, TRUE, &u4SetInfoLen); + } + } + + if (rstatus != WLAN_STATUS_SUCCESS) + fgIsValid = -EFAULT; + + return fgIsValid; +} + +#endif + +#endif /* CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_WIFI_DIRECT_CFG_80211 */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_p2p_init.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_p2p_init.c new file mode 100644 index 0000000000000000000000000000000000000000..32fcee4734da59654326f8c341bb5e8172f420e7 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_p2p_init.c @@ -0,0 +1,291 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: @(#) gl_p2p_init.c@@ + */ + +/*! \file gl_p2p_init.c + * \brief init and exit routines of Linux driver interface for Wi-Fi Direct + * + * This file contains the main routines + * of Linux driver for MediaTek Inc. 802.11 + * Wireless LAN Adapters. + */ + +/****************************************************************************** + * C O M P I L E R F L A G S + ****************************************************************************** + */ + +/****************************************************************************** + * E X T E R N A L R E F E R E N C E S + ****************************************************************************** + */ + +#include "precomp.h" + +/****************************************************************************** + * C O N S T A N T S + ****************************************************************************** + */ + +#define P2P_INF_NAME "p2p%d" +#define AP_INF_NAME "ap%d" + +/****************************************************************************** + * D A T A T Y P E S + ****************************************************************************** + */ + +/****************************************************************************** + * P U B L I C D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * P R I V A T E D A T A + ****************************************************************************** + */ +static uint8_t *ifname = P2P_INF_NAME; +static uint8_t *ifname2 = P2P_INF_NAME; +static uint16_t mode = RUNNING_P2P_MODE; + + +/****************************************************************************** + * M A C R O S + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N D E C L A R A T I O N S + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N S + ****************************************************************************** + */ + +void p2pSetSuspendMode(struct GLUE_INFO *prGlueInfo, u_int8_t fgEnable) +{ + struct net_device *prDev = NULL; + struct GL_P2P_INFO *prP2PInfo = NULL; + + if (!prGlueInfo) + return; + + if (!prGlueInfo->prAdapter->fgIsP2PRegistered) { + DBGLOG(INIT, INFO, "%s: P2P is not enabled, SKIP!\n", __func__); + return; + } + + /* For P2P interfaces, prDevHandler points to the net_device of + * p2p0 interface. And aprRoleHandler points to the net_device + * of p2p virtual interface (i.e., p2p1) when it was created. + * And when p2p virtual interface is deleted, aprRoleHandler + * will change to point to prDevHandler. Hence, when + * aprRoleHandler & prDevHandler are pointing to different + * addresses, it means vif p2p1 exists. Otherwise it means p2p1 + * was already deleted. + */ + prP2PInfo = prGlueInfo->prP2PInfo[0]; + if ((prP2PInfo->aprRoleHandler != NULL) && + (prP2PInfo->aprRoleHandler != prP2PInfo->prDevHandler)) { + prDev = prP2PInfo->aprRoleHandler; + } else { + prDev = prP2PInfo->prDevHandler; + } + + if (!prDev) { + DBGLOG(INIT, INFO, + "%s: P2P dev is not available, SKIP!\n", __func__); + return; + } + + kalSetNetAddressFromInterface(prGlueInfo, prDev, fgEnable); + wlanNotifyFwSuspend(prGlueInfo, prDev, fgEnable); +} + +/*---------------------------------------------------------------------------*/ +/*! + * \brief + * run p2p init procedure, glue register p2p and set p2p registered flag + * + * \retval 1 Success + */ +/*---------------------------------------------------------------------------*/ +u_int8_t p2pLaunch(struct GLUE_INFO *prGlueInfo) +{ + if (prGlueInfo->prAdapter->fgIsP2PRegistered == TRUE) { + DBGLOG(P2P, INFO, "p2p is already registered\n"); + return FALSE; + } + + if (!glRegisterP2P(prGlueInfo, ifname, ifname2, mode)) { + DBGLOG(P2P, ERROR, "Launch failed\n"); + return FALSE; + } + + prGlueInfo->prAdapter->fgIsP2PRegistered = TRUE; + prGlueInfo->prAdapter->p2p_scan_report_all_bss = + CFG_P2P_SCAN_REPORT_ALL_BSS; + DBGLOG(P2P, TRACE, "Launch success, fgIsP2PRegistered TRUE\n"); + return TRUE; +} + +void p2pSetMode(IN uint8_t ucAPMode) +{ + uint8_t *prAPInfName = AP_INF_NAME; + uint8_t *prP2PInfName = P2P_INF_NAME; + +#ifdef CFG_DRIVER_INF_NAME_CHANGE + + if (kalStrLen(gprifnamep2p) > 0) { + prP2PInfName = kalStrCat(gprifnamep2p, "%d"); + DBGLOG(INIT, WARN, + "P2P ifname customized, use %s\n", prP2PInfName); + } + + if (kalStrLen(gprifnameap) > 0) { + prAPInfName = kalStrCat(gprifnameap, "%d"); + DBGLOG(INIT, WARN, + "AP ifname customized, use %s\n", prAPInfName); + } + +#endif /* CFG_DRIVER_INF_NAME_CHANGE */ + + switch (ucAPMode) { + case 0: + mode = RUNNING_P2P_MODE; + ifname = prP2PInfName; + break; + case 1: + mode = RUNNING_AP_MODE; + ifname = prAPInfName; + break; + case 2: + mode = RUNNING_DUAL_AP_MODE; + ifname = prAPInfName; + break; + case 3: + mode = RUNNING_P2P_AP_MODE; + ifname = prP2PInfName; + ifname2 = prAPInfName; + break; + } +} /* p2pSetMode */ + +/*---------------------------------------------------------------------------*/ +/*! + * \brief + * run p2p exit procedure, glue unregister p2p and set p2p registered flag + * + * \retval 1 Success + */ +/*---------------------------------------------------------------------------*/ +u_int8_t p2pRemove(struct GLUE_INFO *prGlueInfo) +{ + u_int8_t idx = 0; + + if (prGlueInfo->prAdapter->fgIsP2PRegistered == FALSE) { + DBGLOG(P2P, INFO, "p2p is not registered\n"); + return FALSE; + } + + prGlueInfo->prAdapter->fgIsP2PRegistered = FALSE; + prGlueInfo->prAdapter->p2p_scan_report_all_bss = FALSE; + + glUnregisterP2P(prGlueInfo, 0xff); + + /* Release ap0 wdev. + * ap0 wdev is created in wlanProbe. So we need to release it in + * wlanRemove. Other wdevs shall be released in exitWlan. + */ + for (idx = 0 ; idx < KAL_P2P_NUM; idx++) { + if (gprP2pRoleWdev[idx] == NULL) + continue; +#if CFG_ENABLE_UNIFY_WIPHY + if (wlanIsAisDev(gprP2pRoleWdev[idx]->netdev)) { + /* This is AIS/AP Interface */ + gprP2pRoleWdev[idx] = NULL; + continue; + } +#endif + /* free gprP2pWdev in wlanDestroyAllWdev */ + if (gprP2pRoleWdev[idx] == gprP2pWdev) + continue; + + DBGLOG(INIT, INFO, "Unregister gprP2pRoleWdev[%d]\n", idx); +#if (CFG_ENABLE_UNIFY_WIPHY == 0) + set_wiphy_dev(gprP2pRoleWdev[idx]->wiphy, NULL); + wiphy_unregister(gprP2pRoleWdev[idx]->wiphy); + wiphy_free(gprP2pRoleWdev[idx]->wiphy); +#endif + kfree(gprP2pRoleWdev[idx]); + gprP2pRoleWdev[idx] = NULL; + break; + } +#if (CFG_ENABLE_UNIFY_WIPHY == 0) + /* gprP2pWdev: base P2P dev + * Becase the interface dev (ex: usb_device) would be free + * after un-plug event. Should set the wiphy->dev->parent which + * pointer to the interface dev to NULL. Otherwise, the corresponding + * system operation (poweroff, suspend) might reference it. + * set_wiphy_dev(wiphy, NULL): set the wiphy->dev->parent = NULL + */ + if (gprP2pWdev != NULL) + set_wiphy_dev(gprP2pWdev->wiphy, NULL); +#endif + + return TRUE; +} + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_p2p_kal.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_p2p_kal.c new file mode 100644 index 0000000000000000000000000000000000000000..d52a964837156fdd11457077f06b8b8b2bf644d6 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_p2p_kal.c @@ -0,0 +1,2383 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: @(#) gl_p2p_cfg80211.c@@ + */ + +/*! \file gl_p2p_kal.c + * \brief + * + */ + +/****************************************************************************** + * C O M P I L E R F L A G S + ****************************************************************************** + */ + +/****************************************************************************** + * E X T E R N A L R E F E R E N C E S + ****************************************************************************** + */ +#include "net/cfg80211.h" +#include "precomp.h" +#include "gl_wext.h" + +/****************************************************************************** + * C O N S T A N T S + ****************************************************************************** + */ + +/****************************************************************************** + * D A T A T Y P E S + ****************************************************************************** + */ + +/****************************************************************************** + * P U B L I C D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * P R I V A T E D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * M A C R O S + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N D E C L A R A T I O N S + ****************************************************************************** + */ + +struct ieee80211_channel *kalP2pFuncGetChannelEntry( + IN struct GL_P2P_INFO *prP2pInfo, + IN struct RF_CHANNEL_INFO *prChannelInfo); + +/****************************************************************************** + * F U N C T I O N S + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------*/ +/*! + * \brief to retrieve Wi-Fi Direct state from glue layer + * + * \param[in] + * prGlueInfo + * rPeerAddr + * \return + * ENUM_BOW_DEVICE_STATE + */ +/*---------------------------------------------------------------------------*/ +#if 0 +enum ENUM_PARAM_MEDIA_STATE kalP2PGetState(IN struct GLUE_INFO *prGlueInfo) +{ + ASSERT(prGlueInfo); + + return prGlueInfo->prP2PInfo[0]->eState; +} /* end of kalP2PGetState() */ +#endif +/*---------------------------------------------------------------------------*/ +/*! + * \brief to update the assoc req to p2p + * + * \param[in] + * prGlueInfo + * pucFrameBody + * u4FrameBodyLen + * fgReassocRequest + * \return + * none + */ +/*---------------------------------------------------------------------------*/ +void +kalP2PUpdateAssocInfo(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t *pucFrameBody, + IN uint32_t u4FrameBodyLen, + IN u_int8_t fgReassocRequest, + IN uint8_t ucBssIndex) +{ + struct BSS_INFO *prBssInfo; + union iwreq_data wrqu; + unsigned char *pucExtraInfo = NULL; + unsigned char *pucDesiredIE = NULL; +/* unsigned char aucExtraInfoBuf[200]; */ + uint8_t *cp; + struct net_device *prNetdevice = (struct net_device *)NULL; + + memset(&wrqu, 0, sizeof(wrqu)); + + if (fgReassocRequest) { + if (u4FrameBodyLen < 15) { + /* + * printk(KERN_WARNING + * "frameBodyLen too short:%ld\n", frameBodyLen); + */ + return; + } + } else { + if (u4FrameBodyLen < 9) { + /* + * printk(KERN_WARNING + * "frameBodyLen too short:%ld\n", frameBodyLen); + */ + return; + } + } + + cp = pucFrameBody; + + if (fgReassocRequest) { + /* Capability information field 2 */ + /* Listen interval field 2 */ + /* Current AP address 6 */ + cp += 10; + u4FrameBodyLen -= 10; + } else { + /* Capability information field 2 */ + /* Listen interval field 2 */ + cp += 4; + u4FrameBodyLen -= 4; + } + + /* do supplicant a favor, parse to the start of WPA/RSN IE */ + if (wextSrchDesiredWPSIE(cp, u4FrameBodyLen, 0xDD, &pucDesiredIE)) { + /* printk("wextSrchDesiredWPSIE!!\n"); */ + /* WPS IE found */ + } else if (wextSrchDesiredWPAIE(cp, + u4FrameBodyLen, 0x30, &pucDesiredIE)) { + /* printk("wextSrchDesiredWPAIE!!\n"); */ + /* RSN IE found */ + } else if (wextSrchDesiredWPAIE(cp, + u4FrameBodyLen, 0xDD, &pucDesiredIE)) { + /* printk("wextSrchDesiredWPAIE!!\n"); */ + /* WPA IE found */ + } else { + /* no WPA/RSN IE found, skip this event */ + return; + } + + /* IWEVASSOCREQIE, indicate binary string */ + pucExtraInfo = pucDesiredIE; + wrqu.data.length = pucDesiredIE[1] + 2; + + prBssInfo = GET_BSS_INFO_BY_INDEX(prGlueInfo->prAdapter, ucBssIndex); + + if (ucBssIndex == prGlueInfo->prAdapter->ucP2PDevBssIdx) + prNetdevice = prGlueInfo->prP2PInfo + [prBssInfo->u4PrivateData]->prDevHandler; + else + prNetdevice = prGlueInfo->prP2PInfo + [prBssInfo->u4PrivateData]->aprRoleHandler; + + /* Send event to user space */ + wireless_send_event(prNetdevice, IWEVASSOCREQIE, &wrqu, pucExtraInfo); +} + +/*---------------------------------------------------------------------------*/ +/*! + * \brief to set Wi-Fi Direct state in glue layer + * + * \param[in] + * prGlueInfo + * eBowState + * rPeerAddr + * \return + * none + */ +/*---------------------------------------------------------------------------*/ +#if 0 +void +kalP2PSetState(IN struct GLUE_INFO *prGlueInfo, + IN enum ENUM_PARAM_MEDIA_STATE eState, + IN uint8_t rPeerAddr[PARAM_MAC_ADDR_LEN], + IN uint8_t ucRole) +{ + union iwreq_data evt; + uint8_t aucBuffer[IW_CUSTOM_MAX]; + + ASSERT(prGlueInfo); + + memset(&evt, 0, sizeof(evt)); + + if (eState == MEDIA_STATE_CONNECTED) { + prGlueInfo->prP2PInfo[0]->eState = MEDIA_STATE_CONNECTED; + + snprintf(aucBuffer, IW_CUSTOM_MAX - 1, + "P2P_STA_CONNECT=" MACSTR, MAC2STR(rPeerAddr)); + evt.data.length = strlen(aucBuffer); + + /* indicate in IWECUSTOM event */ + wireless_send_event(prGlueInfo->prP2PInfo[0]->prDevHandler, + IWEVCUSTOM, &evt, aucBuffer); + + } else if (eState == MEDIA_STATE_DISCONNECTED) { + snprintf(aucBuffer, IW_CUSTOM_MAX - 1, + "P2P_STA_DISCONNECT=" MACSTR, MAC2STR(rPeerAddr)); + evt.data.length = strlen(aucBuffer); + + /* indicate in IWECUSTOM event */ + wireless_send_event(prGlueInfo->prP2PInfo[0]->prDevHandler, + IWEVCUSTOM, &evt, aucBuffer); + } else { + ASSERT(0); + } + +} /* end of kalP2PSetState() */ +#endif +/*---------------------------------------------------------------------------*/ +/*! + * \brief to retrieve Wi-Fi Direct operating frequency + * + * \param[in] + * prGlueInfo + * + * \return + * in unit of KHz + */ +/*---------------------------------------------------------------------------*/ +#if 0 +uint32_t kalP2PGetFreqInKHz(IN struct GLUE_INFO *prGlueInfo) +{ + ASSERT(prGlueInfo); + + return prGlueInfo->prP2PInfo[0]->u4FreqInKHz; +} /* end of kalP2PGetFreqInKHz() */ +#endif + +/*---------------------------------------------------------------------------*/ +/*! + * \brief to retrieve Bluetooth-over-Wi-Fi role + * + * \param[in] + * prGlueInfo + * + * \return + * 0: P2P Device + * 1: Group Client + * 2: Group Owner + */ +/*----------------------------------------------------------------------------*/ +uint8_t kalP2PGetRole(IN struct GLUE_INFO *prGlueInfo, IN uint8_t ucRoleIdx) +{ + ASSERT(prGlueInfo); + + return prGlueInfo->prP2PInfo[ucRoleIdx]->ucRole; +} /* end of kalP2PGetRole() */ + +/*---------------------------------------------------------------------------*/ +/*! + * \brief to set Wi-Fi Direct role + * + * \param[in] + * prGlueInfo + * ucResult + * 0: successful + * 1: error + * ucRole + * 0: P2P Device + * 1: Group Client + * 2: Group Owner + * + * \return + * none + */ +/*---------------------------------------------------------------------------*/ +#if 1 +void kalP2PSetRole(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRole, IN uint8_t ucRoleIdx) +{ + ASSERT(prGlueInfo); + ASSERT(ucRole <= 2); + + prGlueInfo->prP2PInfo[ucRoleIdx]->ucRole = ucRole; + /* Remove non-used code */ +} /* end of kalP2PSetRole() */ + +#else +void +kalP2PSetRole(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucResult, IN uint8_t *pucSSID, + IN uint8_t ucSSIDLen, IN uint8_t ucRole) +{ + union iwreq_data evt; + uint8_t aucBuffer[IW_CUSTOM_MAX]; + + ASSERT(prGlueInfo); + ASSERT(ucRole <= 2); + + memset(&evt, 0, sizeof(evt)); + + if (ucResult == 0) + prGlueInfo->prP2PInfo[0]->ucRole = ucRole; + + if (pucSSID) + snprintf(aucBuffer, IW_CUSTOM_MAX - 1, + "P2P_FORMATION_RST=%d%d%d%c%c", ucResult, + ucRole, 1 /* persistence or not */, + pucSSID[7], pucSSID[8]); + else + snprintf(aucBuffer, IW_CUSTOM_MAX - 1, + "P2P_FORMATION_RST=%d%d%d%c%c", ucResult, + ucRole, 1 /* persistence or not */, '0', '0'); + + evt.data.length = strlen(aucBuffer); + + /* if (pucSSID) */ + /* printk("P2P GO SSID DIRECT-%c%c\n", pucSSID[7], pucSSID[8]); */ + + /* indicate in IWECUSTOM event */ + wireless_send_event(prGlueInfo->prP2PInfo[0]->prDevHandler, + IWEVCUSTOM, &evt, aucBuffer); + +} /* end of kalP2PSetRole() */ + +#endif +/*---------------------------------------------------------------------------*/ +/*! + * \brief to set the cipher for p2p + * + * \param[in] + * prGlueInfo + * u4Cipher + * + * \return + * none + */ +/*---------------------------------------------------------------------------*/ +void kalP2PSetCipher(IN struct GLUE_INFO *prGlueInfo, + IN uint32_t u4Cipher, IN uint8_t ucRoleIdx) +{ + ASSERT(prGlueInfo); + ASSERT(prGlueInfo->prP2PInfo[ucRoleIdx]); + + /* It can be WEP40 (used to identify cipher is WEP), TKIP and CCMP */ + prGlueInfo->prP2PInfo[ucRoleIdx]->u4CipherPairwise = u4Cipher; + +} + +/*---------------------------------------------------------------------------*/ +/*! + * \brief to get the cipher, return false for security is none + * + * \param[in] + * prGlueInfo + * + * \return + * TRUE: cipher is ccmp + * FALSE: cipher is none + */ +/*---------------------------------------------------------------------------*/ +u_int8_t kalP2PGetCipher(IN struct GLUE_INFO *prGlueInfo, IN uint8_t ucRoleIdx) +{ + ASSERT(prGlueInfo); + ASSERT(prGlueInfo->prP2PInfo[ucRoleIdx]); + + if (prGlueInfo->prP2PInfo[ucRoleIdx]->u4CipherPairwise + == IW_AUTH_CIPHER_CCMP) + return TRUE; + + if (prGlueInfo->prP2PInfo[ucRoleIdx]->u4CipherPairwise + == IW_AUTH_CIPHER_TKIP) + return TRUE; + + if (prGlueInfo->prP2PInfo[ucRoleIdx]->u4CipherPairwise + == IW_AUTH_CIPHER_WEP40) + return TRUE; + + return FALSE; +} + +u_int8_t kalP2PGetWepCipher(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRoleIdx) +{ + ASSERT(prGlueInfo); + ASSERT(prGlueInfo->prP2PInfo[ucRoleIdx]); + + if (prGlueInfo->prP2PInfo[ucRoleIdx]->u4CipherPairwise + == IW_AUTH_CIPHER_WEP40) + return TRUE; + + if (prGlueInfo->prP2PInfo[ucRoleIdx]->u4CipherPairwise + == IW_AUTH_CIPHER_WEP104) + return TRUE; + + return FALSE; +} + +u_int8_t kalP2PGetCcmpCipher(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRoleIdx) +{ + ASSERT(prGlueInfo); + ASSERT(prGlueInfo->prP2PInfo[ucRoleIdx]); + + DBGLOG(P2P, TRACE, + "P2P get ccmp cipher: %d\n", + prGlueInfo->prP2PInfo[ucRoleIdx]->u4CipherPairwise); + + if (prGlueInfo->prP2PInfo[ucRoleIdx]->u4CipherPairwise + == IW_AUTH_CIPHER_CCMP) + return TRUE; + + if (prGlueInfo->prP2PInfo[ucRoleIdx]->u4CipherPairwise + == IW_AUTH_CIPHER_TKIP) + return FALSE; + + return FALSE; +} + +u_int8_t kalP2PGetTkipCipher(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRoleIdx) +{ + ASSERT(prGlueInfo); + ASSERT(prGlueInfo->prP2PInfo[ucRoleIdx]); + + if (prGlueInfo->prP2PInfo[ucRoleIdx]->u4CipherPairwise + == IW_AUTH_CIPHER_CCMP) + return FALSE; + + if (prGlueInfo->prP2PInfo[ucRoleIdx]->u4CipherPairwise + == IW_AUTH_CIPHER_TKIP) + return TRUE; + + return FALSE; +} + +/*---------------------------------------------------------------------------*/ +/*! + * \brief to set the status of WSC + * + * \param[in] + * prGlueInfo + * + * \return + */ +/*---------------------------------------------------------------------------*/ +void kalP2PSetWscMode(IN struct GLUE_INFO *prGlueInfo, IN uint8_t ucWscMode) +{ + ASSERT(prGlueInfo); + ASSERT(prGlueInfo->prP2PDevInfo); + + prGlueInfo->prP2PDevInfo->ucWSCRunning = ucWscMode; +} + +/*---------------------------------------------------------------------------*/ +/*! + * \brief to get the status of WSC + * + * \param[in] + * prGlueInfo + * + * \return + */ +/*---------------------------------------------------------------------------*/ +uint8_t kalP2PGetWscMode(IN struct GLUE_INFO *prGlueInfo) +{ + ASSERT(prGlueInfo); + ASSERT(prGlueInfo->prP2PDevInfo); + + return prGlueInfo->prP2PDevInfo->ucWSCRunning; +} + +/*---------------------------------------------------------------------------*/ +/*! + * \brief to get the wsc ie length + * + * \param[in] + * prGlueInfo + * ucType : 0 for beacon, 1 for probe req, 2 for probe resp + * + * \return + * The WSC IE length + */ +/*---------------------------------------------------------------------------*/ +uint16_t kalP2PCalWSC_IELen(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucType, IN uint8_t ucRoleIdx) +{ + ASSERT(prGlueInfo); + + ASSERT(ucType < 4); + + return prGlueInfo->prP2PInfo[ucRoleIdx]->u2WSCIELen[ucType]; +} + +/*---------------------------------------------------------------------------*/ +/*! + * \brief to copy the wsc ie setting from p2p supplicant + * + * \param[in] + * prGlueInfo + * + * \return + * The WPS IE length + */ +/*---------------------------------------------------------------------------*/ +void kalP2PGenWSC_IE(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucType, IN uint8_t *pucBuffer, IN uint8_t ucRoleIdx) +{ + struct GL_P2P_INFO *prGlP2pInfo = (struct GL_P2P_INFO *) NULL; + + do { + if ((prGlueInfo == NULL) + || (ucType >= 4) || (pucBuffer == NULL)) + break; + + prGlP2pInfo = prGlueInfo->prP2PInfo[ucRoleIdx]; + + kalMemCopy(pucBuffer, + prGlP2pInfo->aucWSCIE[ucType], + prGlP2pInfo->u2WSCIELen[ucType]); + + } while (FALSE); + +} + +void kalP2PUpdateWSC_IE(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucType, IN uint8_t *pucBuffer, + IN uint16_t u2BufferLength, IN uint8_t ucRoleIdx) +{ + struct GL_P2P_INFO *prGlP2pInfo = (struct GL_P2P_INFO *) NULL; + + do { + if ((prGlueInfo == NULL) || (ucType >= 4) + || ((u2BufferLength > 0) && (pucBuffer == NULL))) + break; + + if (u2BufferLength > 400) { + log_dbg(P2P, ERROR, + "Buffer length is not enough, GLUE only 400 bytes but %d received\n", + u2BufferLength); + ASSERT(FALSE); + break; + } + + prGlP2pInfo = prGlueInfo->prP2PInfo[ucRoleIdx]; + + kalMemCopy(prGlP2pInfo->aucWSCIE[ucType], + pucBuffer, u2BufferLength); + + prGlP2pInfo->u2WSCIELen[ucType] = u2BufferLength; + + } while (FALSE); + +} /* kalP2PUpdateWSC_IE */ + +uint16_t kalP2PCalP2P_IELen(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucIndex, IN uint8_t ucRoleIdx) +{ + ASSERT(prGlueInfo); + + ASSERT(ucIndex < MAX_P2P_IE_SIZE); + + return prGlueInfo->prP2PInfo[ucRoleIdx]->u2P2PIELen[ucIndex]; +} + +void kalP2PGenP2P_IE(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucIndex, IN uint8_t *pucBuffer, IN uint8_t ucRoleIdx) +{ + struct GL_P2P_INFO *prGlP2pInfo = (struct GL_P2P_INFO *) NULL; + + do { + if ((prGlueInfo == NULL) || (ucIndex >= MAX_P2P_IE_SIZE) + || (pucBuffer == NULL)) + break; + + prGlP2pInfo = prGlueInfo->prP2PInfo[ucRoleIdx]; + + kalMemCopy(pucBuffer, + prGlP2pInfo->aucP2PIE[ucIndex], + prGlP2pInfo->u2P2PIELen[ucIndex]); + + } while (FALSE); +} + +void kalP2PUpdateP2P_IE(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucIndex, IN uint8_t *pucBuffer, + IN uint16_t u2BufferLength, IN uint8_t ucRoleIdx) +{ + struct GL_P2P_INFO *prGlP2pInfo = (struct GL_P2P_INFO *) NULL; + + do { + if ((prGlueInfo == NULL) || + (ucIndex >= MAX_P2P_IE_SIZE) || + ((u2BufferLength > 0) && (pucBuffer == NULL))) + break; + + if (u2BufferLength > 400) { + log_dbg(P2P, ERROR, + "kalP2PUpdateP2P_IE > Buffer length is not enough, GLUE only 400 bytes but %d received\n", + u2BufferLength); + ASSERT(FALSE); + break; + } + + prGlP2pInfo = prGlueInfo->prP2PInfo[ucRoleIdx]; + + kalMemCopy(prGlP2pInfo->aucP2PIE[ucIndex], + pucBuffer, u2BufferLength); + + prGlP2pInfo->u2P2PIELen[ucIndex] = u2BufferLength; + + } while (FALSE); + +} + +#if 0 +/*---------------------------------------------------------------------------*/ +/*! + * \brief indicate an event to supplicant for device connection request + * + * \param[in] prGlueInfo Pointer of GLUE_INFO_T + * + * \retval none + */ +/*---------------------------------------------------------------------------*/ +void kalP2PIndicateConnReq(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t *pucDevName, IN int32_t u4NameLength, + IN uint8_t rPeerAddr[PARAM_MAC_ADDR_LEN], + IN uint8_t ucDevType,/* 0: P2P Device / 1: GC / 2: GO */ + IN int32_t i4ConfigMethod, IN int32_t i4ActiveConfigMethod +) +{ + union iwreq_data evt; + uint8_t aucBuffer[IW_CUSTOM_MAX]; + + ASSERT(prGlueInfo); + + /* buffer peer information + * for later IOC_P2P_GET_REQ_DEVICE_INFO access + */ + prGlueInfo->prP2PInfo[0]->u4ConnReqNameLength = + u4NameLength > 32 ? 32 : u4NameLength; + kalMemCopy(prGlueInfo->prP2PInfo[0]->aucConnReqDevName, + pucDevName, + prGlueInfo->prP2PInfo[0]->u4ConnReqNameLength); + COPY_MAC_ADDR(prGlueInfo->prP2PInfo[0]->rConnReqPeerAddr, rPeerAddr); + prGlueInfo->prP2PInfo[0]->ucConnReqDevType = ucDevType; + prGlueInfo->prP2PInfo[0]->i4ConnReqConfigMethod = i4ConfigMethod; + prGlueInfo->prP2PInfo[0]->i4ConnReqActiveConfigMethod = + i4ActiveConfigMethod; + + /* prepare event structure */ + memset(&evt, 0, sizeof(evt)); + + snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_DVC_REQ"); + evt.data.length = strlen(aucBuffer); + + /* indicate in IWEVCUSTOM event */ + wireless_send_event(prGlueInfo->prP2PInfo[0]->prDevHandler, + IWEVCUSTOM, &evt, aucBuffer); + +} /* end of kalP2PIndicateConnReq() */ + +/*---------------------------------------------------------------------------*/ +/*! + * \brief Indicate an event to supplicant + * for device connection request from other device. + * + * \param[in] prGlueInfo Pointer of GLUE_INFO_T + * \param[in] pucGroupBssid Only valid when invitation Type equals to 0. + * + * \retval none + */ +/*---------------------------------------------------------------------------*/ +void +kalP2PInvitationIndication(IN struct GLUE_INFO *prGlueInfo, + IN struct P2P_DEVICE_DESC *prP2pDevDesc, + IN uint8_t *pucSsid, + IN uint8_t ucSsidLen, + IN uint8_t ucOperatingChnl, + IN uint8_t ucInvitationType, + IN uint8_t *pucGroupBssid) +{ +#if 1 + union iwreq_data evt; + uint8_t aucBuffer[IW_CUSTOM_MAX]; + + ASSERT(prGlueInfo); + + /* buffer peer information for later IOC_P2P_GET_STRUCT access */ + prGlueInfo->prP2PInfo[0]->u4ConnReqNameLength = + (uint32_t) ((prP2pDevDesc->u2NameLength > 32) + ? 32 : prP2pDevDesc->u2NameLength); + kalMemCopy(prGlueInfo->prP2PInfo[0]->aucConnReqDevName, + prP2pDevDesc->aucName, + prGlueInfo->prP2PInfo[0]->u4ConnReqNameLength); + COPY_MAC_ADDR(prGlueInfo->prP2PInfo[0]->rConnReqPeerAddr, + prP2pDevDesc->aucDeviceAddr); + COPY_MAC_ADDR(prGlueInfo->prP2PInfo[0]->rConnReqGroupAddr, + pucGroupBssid); + prGlueInfo->prP2PInfo[0]->i4ConnReqConfigMethod = (int32_t) + (prP2pDevDesc->u2ConfigMethod); + prGlueInfo->prP2PInfo[0]->ucOperatingChnl = ucOperatingChnl; + prGlueInfo->prP2PInfo[0]->ucInvitationType = ucInvitationType; + + /* prepare event structure */ + memset(&evt, 0, sizeof(evt)); + + snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_INV_INDICATE"); + evt.data.length = strlen(aucBuffer); + + /* indicate in IWEVCUSTOM event */ + wireless_send_event(prGlueInfo->prP2PInfo[0]->prDevHandler, + IWEVCUSTOM, &evt, aucBuffer); + +#else + struct MSG_P2P_CONNECTION_REQUEST *prP2pConnReq = + (struct MSG_P2P_CONNECTION_REQUEST *) NULL; + struct P2P_SPECIFIC_BSS_INFO *prP2pSpecificBssInfo = + (struct P2P_SPECIFIC_BSS_INFO *) NULL; + struct P2P_CONNECTION_SETTINGS *prP2pConnSettings = + (struct P2P_CONNECTION_SETTINGS *) NULL; + + do { + ASSERT_BREAK((prGlueInfo != NULL) && (prP2pDevDesc != NULL)); + + /* Not a real solution */ + + prP2pSpecificBssInfo = + prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo; + prP2pConnSettings = + prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings; + + prP2pConnReq = (struct MSG_P2P_CONNECTION_REQUEST *) + cnmMemAlloc(prGlueInfo->prAdapter, + RAM_TYPE_MSG, + sizeof(struct MSG_P2P_CONNECTION_REQUEST)); + + if (prP2pConnReq == NULL) + break; + + kalMemZero(prP2pConnReq, + sizeof(struct MSG_P2P_CONNECTION_REQUEST)); + + prP2pConnReq->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_REQ; + + prP2pConnReq->eFormationPolicy = ENUM_P2P_FORMATION_POLICY_AUTO; + + COPY_MAC_ADDR(prP2pConnReq->aucDeviceID, + prP2pDevDesc->aucDeviceAddr); + + prP2pConnReq->u2ConfigMethod = prP2pDevDesc->u2ConfigMethod; + + if (ucInvitationType == P2P_INVITATION_TYPE_INVITATION) { + prP2pConnReq->fgIsPersistentGroup = FALSE; + prP2pConnReq->fgIsTobeGO = FALSE; + + } + + else if (ucInvitationType == P2P_INVITATION_TYPE_REINVOKE) { + DBGLOG(P2P, TRACE, "Re-invoke Persistent Group\n"); + prP2pConnReq->fgIsPersistentGroup = TRUE; + prP2pConnReq->fgIsTobeGO = + (prGlueInfo->prP2PInfo[0]->ucRole == 2) + ? TRUE : FALSE; + + } + + p2pFsmRunEventDeviceDiscoveryAbort(prGlueInfo->prAdapter, NULL); + + if (ucOperatingChnl != 0) + prP2pSpecificBssInfo->ucPreferredChannel = + ucOperatingChnl; + + if ((ucSsidLen < 32) && (pucSsid != NULL)) + COPY_SSID(prP2pConnSettings->aucSSID, + prP2pConnSettings->ucSSIDLen, + pucSsid, ucSsidLen); + + mboxSendMsg(prGlueInfo->prAdapter, + MBOX_ID_0, + (struct MSG_HDR *) prP2pConnReq, + MSG_SEND_METHOD_BUF); + + } while (FALSE); + + /* frog add. */ + /* TODO: Invitation Indication */ + +#endif + +} /* kalP2PInvitationIndication */ +#endif + +#if 0 +/*---------------------------------------------------------------------------*/ +/*! + * \brief Indicate an status to supplicant for device invitation status. + * + * \param[in] prGlueInfo Pointer of GLUE_INFO_T + * + * \retval none + */ +/*---------------------------------------------------------------------------*/ +void kalP2PInvitationStatus(IN struct GLUE_INFO *prGlueInfo, + IN uint32_t u4InvStatus) +{ + union iwreq_data evt; + uint8_t aucBuffer[IW_CUSTOM_MAX]; + + ASSERT(prGlueInfo); + + /* buffer peer information for later IOC_P2P_GET_STRUCT access */ + prGlueInfo->prP2PInfo[0]->u4InvStatus = u4InvStatus; + + /* prepare event structure */ + memset(&evt, 0, sizeof(evt)); + + snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_INV_STATUS"); + evt.data.length = strlen(aucBuffer); + + /* indicate in IWEVCUSTOM event */ + wireless_send_event(prGlueInfo->prP2PInfo[0]->prDevHandler, + IWEVCUSTOM, &evt, aucBuffer); + +} /* kalP2PInvitationStatus */ +#endif + +/*---------------------------------------------------------------------------*/ +/*! + * \brief Indicate an event to supplicant + * for Service Discovery request from other device. + * + * \param[in] prGlueInfo Pointer of GLUE_INFO_T + * + * \retval none + */ +/*---------------------------------------------------------------------------*/ +void kalP2PIndicateSDRequest(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t rPeerAddr[PARAM_MAC_ADDR_LEN], IN uint8_t ucSeqNum) +{ + union iwreq_data evt; + uint8_t aucBuffer[IW_CUSTOM_MAX]; + int32_t i4Ret = 0; + + ASSERT(prGlueInfo); + + memset(&evt, 0, sizeof(evt)); + + i4Ret = + snprintf(aucBuffer, IW_CUSTOM_MAX - 1, + "P2P_SD_REQ %d", ucSeqNum); + if (i4Ret < 0) { + DBGLOG(INIT, WARN, "sprintf failed:%d\n", i4Ret); + return; + } + + evt.data.length = strlen(aucBuffer); + + /* indicate IWEVP2PSDREQ event */ + wireless_send_event(prGlueInfo->prP2PInfo[0]->prDevHandler, + IWEVCUSTOM, &evt, aucBuffer); +} /* end of kalP2PIndicateSDRequest() */ + +/*---------------------------------------------------------------------------*/ +/*! + * \brief Indicate an event to supplicant for Service Discovery response + * from other device. + * + * \param[in] prGlueInfo Pointer of GLUE_INFO_T + * + * \retval none + */ +/*---------------------------------------------------------------------------*/ +void kalP2PIndicateSDResponse(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t rPeerAddr[PARAM_MAC_ADDR_LEN], IN uint8_t ucSeqNum) +{ + union iwreq_data evt; + uint8_t aucBuffer[IW_CUSTOM_MAX]; + int32_t i4Ret = 0; + + ASSERT(prGlueInfo); + + memset(&evt, 0, sizeof(evt)); + + i4Ret = + snprintf(aucBuffer, IW_CUSTOM_MAX - 1, + "P2P_SD_RESP %d", ucSeqNum); + if (i4Ret < 0) { + DBGLOG(INIT, WARN, "sprintf failed:%d\n", i4Ret); + return; + } + evt.data.length = strlen(aucBuffer); + + /* indicate IWEVP2PSDREQ event */ + wireless_send_event(prGlueInfo->prP2PInfo[0]->prDevHandler, + IWEVCUSTOM, &evt, aucBuffer); +} /* end of kalP2PIndicateSDResponse() */ + +/*---------------------------------------------------------------------------*/ +/*! + * \brief Indicate an event to supplicant for Service Discovery TX Done + * from other device. + * + * \param[in] prGlueInfo Pointer of GLUE_INFO_T + * \param[in] ucSeqNum Sequence number of the frame + * \param[in] ucStatus Status code for TX + * + * \retval none + */ +/*---------------------------------------------------------------------------*/ +void kalP2PIndicateTXDone(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucSeqNum, IN uint8_t ucStatus) +{ + union iwreq_data evt; + uint8_t aucBuffer[IW_CUSTOM_MAX]; + int32_t i4Ret = 0; + + ASSERT(prGlueInfo); + + memset(&evt, 0, sizeof(evt)); + + i4Ret = + snprintf(aucBuffer, IW_CUSTOM_MAX - 1, + "P2P_SD_XMITTED: %d %d", ucSeqNum, ucStatus); + if (i4Ret < 0) { + DBGLOG(INIT, WARN, "sprintf failed:%d\n", i4Ret); + return; + } + evt.data.length = strlen(aucBuffer); + + /* indicate IWEVP2PSDREQ event */ + wireless_send_event(prGlueInfo->prP2PInfo[0]->prDevHandler, + IWEVCUSTOM, &evt, aucBuffer); +} /* end of kalP2PIndicateSDResponse() */ + +struct net_device *kalP2PGetDevHdlr(struct GLUE_INFO *prGlueInfo) +{ + ASSERT(prGlueInfo); + ASSERT(prGlueInfo->prP2PInfo[0]); + return prGlueInfo->prP2PInfo[0]->prDevHandler; +} + +#if CFG_SUPPORT_ANTI_PIRACY +#if 0 +/*---------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] prAdapter Pointer of ADAPTER_T + * + * \return none + */ +/*---------------------------------------------------------------------------*/ +void kalP2PIndicateSecCheckRsp(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t *pucRsp, IN uint16_t u2RspLen) +{ + union iwreq_data evt; + uint8_t aucBuffer[IW_CUSTOM_MAX]; + + ASSERT(prGlueInfo); + + memset(&evt, 0, sizeof(evt)); + snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_SEC_CHECK_RSP="); + + kalMemCopy(prGlueInfo->prP2PInfo[0]->aucSecCheckRsp, pucRsp, u2RspLen); + evt.data.length = strlen(aucBuffer); + +#if DBG + DBGLOG_MEM8(SEC, LOUD, + prGlueInfo->prP2PInfo[0]->aucSecCheckRsp, u2RspLen); +#endif + /* indicate in IWECUSTOM event */ + wireless_send_event(prGlueInfo->prP2PInfo[0]->prDevHandler, + IWEVCUSTOM, &evt, aucBuffer); +} /* p2pFsmRunEventRxDisassociation */ +#endif +#endif + +/*---------------------------------------------------------------------------*/ +/*! + * \brief + * + * \param[in] prAdapter Pointer of ADAPTER_T + * + * \return none + */ +/*---------------------------------------------------------------------------*/ +void +kalGetChnlList(IN struct GLUE_INFO *prGlueInfo, + IN enum ENUM_BAND eSpecificBand, + IN uint8_t ucMaxChannelNum, + IN uint8_t *pucNumOfChannel, + IN struct RF_CHANNEL_INFO *paucChannelList) +{ + rlmDomainGetChnlList(prGlueInfo->prAdapter, eSpecificBand, + FALSE, ucMaxChannelNum, pucNumOfChannel, paucChannelList); +} /* kalGetChnlList */ + +/* ////////////////////////////ICS SUPPORT////////////////////////////// */ + +void +kalP2PIndicateChannelReady(IN struct GLUE_INFO *prGlueInfo, + IN uint64_t u8SeqNum, + IN uint32_t u4ChannelNum, + IN enum ENUM_BAND eBand, + IN enum ENUM_CHNL_EXT eSco, + IN uint32_t u4Duration) +{ + struct ieee80211_channel *prIEEE80211ChnlStruct = + (struct ieee80211_channel *)NULL; + struct RF_CHANNEL_INFO rChannelInfo; + enum nl80211_channel_type eChnlType = NL80211_CHAN_NO_HT; + + do { + if (prGlueInfo == NULL) + break; + + kalMemZero(&rChannelInfo, sizeof(struct RF_CHANNEL_INFO)); + + rChannelInfo.ucChannelNum = u4ChannelNum; + rChannelInfo.eBand = eBand; + + prIEEE80211ChnlStruct = + kalP2pFuncGetChannelEntry(prGlueInfo->prP2PInfo[0], + &rChannelInfo); + + kalP2pFuncGetChannelType(eSco, &eChnlType); + + if (!prIEEE80211ChnlStruct) { + DBGLOG(P2P, WARN, "prIEEE80211ChnlStruct is NULL\n"); + break; + } + + cfg80211_ready_on_channel( + /* struct wireless_dev, */ + prGlueInfo->prP2PInfo[0]->prWdev, + /* u64 cookie, */ + u8SeqNum, + /* struct ieee80211_channel * chan, */ + prIEEE80211ChnlStruct, + /* unsigned int duration, */ + u4Duration, + /* gfp_t gfp *//* allocation flags */ + GFP_KERNEL); + } while (FALSE); + +} /* kalP2PIndicateChannelReady */ + +void +kalP2PIndicateChannelExpired(IN struct GLUE_INFO *prGlueInfo, + IN uint64_t u8SeqNum, + IN uint32_t u4ChannelNum, + IN enum ENUM_BAND eBand, + IN enum ENUM_CHNL_EXT eSco) +{ + + struct GL_P2P_INFO *prGlueP2pInfo = (struct GL_P2P_INFO *) NULL; + struct ieee80211_channel *prIEEE80211ChnlStruct = + (struct ieee80211_channel *)NULL; + enum nl80211_channel_type eChnlType = NL80211_CHAN_NO_HT; + struct RF_CHANNEL_INFO rRfChannelInfo; + + do { + if (prGlueInfo == NULL) { + ASSERT(FALSE); + break; + } + + prGlueP2pInfo = prGlueInfo->prP2PInfo[0]; + + if (prGlueP2pInfo == NULL) { + ASSERT(FALSE); + break; + } + + DBGLOG(P2P, TRACE, "kalP2PIndicateChannelExpired\n"); + + rRfChannelInfo.eBand = eBand; + rRfChannelInfo.ucChannelNum = u4ChannelNum; + + prIEEE80211ChnlStruct = + kalP2pFuncGetChannelEntry(prGlueP2pInfo, + &rRfChannelInfo); + + kalP2pFuncGetChannelType(eSco, &eChnlType); + + if (!prIEEE80211ChnlStruct) { + DBGLOG(P2P, WARN, "prIEEE80211ChnlStruct is NULL\n"); + break; + } + + /* struct wireless_dev, */ + cfg80211_remain_on_channel_expired(prGlueP2pInfo->prWdev, + u8SeqNum, prIEEE80211ChnlStruct, GFP_KERNEL); + } while (FALSE); + +} /* kalP2PIndicateChannelExpired */ + +void kalP2PIndicateScanDone(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRoleIndex, IN u_int8_t fgIsAbort) +{ + struct GL_P2P_DEV_INFO *prP2pGlueDevInfo = + (struct GL_P2P_DEV_INFO *) NULL; + struct GL_P2P_INFO *prGlueP2pInfo = (struct GL_P2P_INFO *) NULL; + struct cfg80211_scan_request *prScanRequest = NULL; + + GLUE_SPIN_LOCK_DECLARATION(); + + do { + if (prGlueInfo == NULL) { + + ASSERT(FALSE); + break; + } + + prGlueP2pInfo = prGlueInfo->prP2PInfo[0]; + prP2pGlueDevInfo = prGlueInfo->prP2PDevInfo; + + if ((prGlueP2pInfo == NULL) || (prP2pGlueDevInfo == NULL)) { + ASSERT(FALSE); + break; + } + + DBGLOG(INIT, INFO, + "[p2p] scan complete %p\n", + prP2pGlueDevInfo->prScanRequest); + + KAL_ACQUIRE_MUTEX(prGlueInfo->prAdapter, MUTEX_DEL_INF); + GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); + + if ((prP2pGlueDevInfo->prScanRequest != NULL) + && (prGlueInfo->prAdapter->fgIsP2PRegistered == TRUE)) { + prScanRequest = prP2pGlueDevInfo->prScanRequest; + kalCfg80211ScanDone(prScanRequest, fgIsAbort); + prP2pGlueDevInfo->prScanRequest = NULL; + } + GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); + + if ((prScanRequest != NULL) + && (prGlueInfo->prAdapter->fgIsP2PRegistered == TRUE)) { + + /* report all queued beacon/probe response frames + * to upper layer + */ + scanReportBss2Cfg80211(prGlueInfo->prAdapter, + BSS_TYPE_P2P_DEVICE, NULL); + + DBGLOG(INIT, TRACE, "DBG:p2p_cfg_scan_done\n"); + } + KAL_RELEASE_MUTEX(prGlueInfo->prAdapter, MUTEX_DEL_INF); + + } while (FALSE); + +} /* kalP2PIndicateScanDone */ + +void +kalP2PIndicateBssInfo(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t *pucFrameBuf, + IN uint32_t u4BufLen, + IN struct RF_CHANNEL_INFO *prChannelInfo, + IN int32_t i4SignalStrength) +{ + struct GL_P2P_INFO *prGlueP2pInfo = (struct GL_P2P_INFO *) NULL; + struct ieee80211_channel *prChannelEntry = + (struct ieee80211_channel *)NULL; + struct ieee80211_mgmt *prBcnProbeRspFrame = + (struct ieee80211_mgmt *)pucFrameBuf; + struct cfg80211_bss *prCfg80211Bss = (struct cfg80211_bss *)NULL; + + do { + if ((prGlueInfo == NULL) || (pucFrameBuf == NULL) + || (prChannelInfo == NULL)) { + ASSERT(FALSE); + break; + } + + prGlueP2pInfo = prGlueInfo->prP2PInfo[0]; + + if (prGlueP2pInfo == NULL) { + ASSERT(FALSE); + break; + } + + prChannelEntry = + kalP2pFuncGetChannelEntry(prGlueP2pInfo, + prChannelInfo); + + if (prChannelEntry == NULL) { + DBGLOG(P2P, TRACE, "Unknown channel info\n"); + break; + } + + /* rChannelInfo.center_freq = + * nicChannelNum2Freq((UINT_32)prChannelInfo->ucChannelNum) + * / 1000; + */ + + if (u4BufLen > 0) { +#if CFG_SUPPORT_TSF_USING_BOOTTIME + prBcnProbeRspFrame->u.beacon.timestamp = + kalGetBootTime(); +#endif + prCfg80211Bss = cfg80211_inform_bss_frame( + /* struct wiphy * wiphy, */ + prGlueP2pInfo->prWdev->wiphy, + prChannelEntry, + prBcnProbeRspFrame, + u4BufLen, i4SignalStrength, GFP_KERNEL); + } + + /* Return this structure. */ + if (prCfg80211Bss) + cfg80211_put_bss(prGlueP2pInfo->prWdev->wiphy, + prCfg80211Bss); + else + DBGLOG(P2P, WARN, + "indicate BSS to cfg80211 failed [" MACSTR + "]: bss channel %d, rcpi %d, frame_len=%d\n", + MAC2STR(prBcnProbeRspFrame->bssid), + prChannelInfo->ucChannelNum, + i4SignalStrength, u4BufLen); + + } while (FALSE); + + return; + +} /* kalP2PIndicateBssInfo */ + +void kalP2PIndicateMgmtTxStatus(IN struct GLUE_INFO *prGlueInfo, + IN struct MSDU_INFO *prMsduInfo, IN u_int8_t fgIsAck) +{ + struct GL_P2P_INFO *prGlueP2pInfo = (struct GL_P2P_INFO *) NULL; + uint64_t *pu8GlCookie = (uint64_t *) NULL; + struct net_device *prNetdevice = (struct net_device *)NULL; + + do { + if ((prGlueInfo == NULL) || (prMsduInfo == NULL)) { + DBGLOG(P2P, WARN, + "Unexpected pointer PARAM. 0x%lx, 0x%lx.\n", + prGlueInfo, prMsduInfo); + ASSERT(FALSE); + break; + } + + pu8GlCookie = + (uint64_t *) ((unsigned long) prMsduInfo->prPacket + + (unsigned long) prMsduInfo->u2FrameLength + + MAC_TX_RESERVED_FIELD); + + if (prMsduInfo->ucBssIndex + == prGlueInfo->prAdapter->ucP2PDevBssIdx) { + + prGlueP2pInfo = prGlueInfo->prP2PInfo[0]; + + if (prGlueP2pInfo == NULL) + return; + + prNetdevice = prGlueP2pInfo->prDevHandler; + + } else { + struct BSS_INFO *prP2pBssInfo = + GET_BSS_INFO_BY_INDEX(prGlueInfo->prAdapter, + prMsduInfo->ucBssIndex); + + prGlueP2pInfo = + prGlueInfo->prP2PInfo + [prP2pBssInfo->u4PrivateData]; + + if (prGlueP2pInfo == NULL) + return; + + prNetdevice = prGlueP2pInfo->aprRoleHandler; + } + + cfg80211_mgmt_tx_status( + /* struct net_device * dev, */ + prNetdevice->ieee80211_ptr, + *pu8GlCookie, + (uint8_t *) ((unsigned long) prMsduInfo->prPacket + + MAC_TX_RESERVED_FIELD), + prMsduInfo->u2FrameLength, fgIsAck, GFP_KERNEL); + + } while (FALSE); + +} /* kalP2PIndicateMgmtTxStatus */ + +void +kalP2PIndicateRxMgmtFrame(IN struct GLUE_INFO *prGlueInfo, + IN struct SW_RFB *prSwRfb, + IN u_int8_t fgIsDevInterface, + IN uint8_t ucRoleIdx) +{ +#define DBG_P2P_MGMT_FRAME_INDICATION 1 + struct GL_P2P_INFO *prGlueP2pInfo = (struct GL_P2P_INFO *) NULL; + int32_t i4Freq = 0; + uint8_t ucChnlNum = 0; +#if DBG_P2P_MGMT_FRAME_INDICATION + struct WLAN_MAC_HEADER *prWlanHeader = (struct WLAN_MAC_HEADER *) NULL; +#endif + struct net_device *prNetdevice = (struct net_device *)NULL; + + do { + if ((prGlueInfo == NULL) || (prSwRfb == NULL)) { + ASSERT(FALSE); + break; + } + + prGlueP2pInfo = prGlueInfo->prP2PInfo[ucRoleIdx]; + + /* ToDo[6630]: Get the following by channel freq */ + /* HAL_RX_STATUS_GET_CHAN_FREQ( prSwRfb->prRxStatus) */ + /* ucChnlNum = prSwRfb->prHifRxHdr->ucHwChannelNum; */ + + ucChnlNum = prSwRfb->ucChnlNum; + +#if DBG_P2P_MGMT_FRAME_INDICATION + + prWlanHeader = (struct WLAN_MAC_HEADER *) prSwRfb->pvHeader; + + switch (prWlanHeader->u2FrameCtrl) { + case MAC_FRAME_PROBE_REQ: + DBGLOG(P2P, TRACE, + "RX Probe Req at channel %d ", + ucChnlNum); + break; + case MAC_FRAME_PROBE_RSP: + DBGLOG(P2P, TRACE, + "RX Probe Rsp at channel %d ", + ucChnlNum); + break; + case MAC_FRAME_ACTION: + DBGLOG(P2P, TRACE, + "RX Action frame at channel %d ", + ucChnlNum); + break; + default: + DBGLOG(P2P, TRACE, + "RX Packet:%d at channel %d ", + prWlanHeader->u2FrameCtrl, ucChnlNum); + break; + } +#endif + i4Freq = nicChannelNum2Freq(ucChnlNum) / 1000; + + if (fgIsDevInterface) + prNetdevice = prGlueP2pInfo->prDevHandler; + else + prNetdevice = prGlueP2pInfo->aprRoleHandler; + + DBGLOG(P2P, TRACE, "from: " MACSTR ", netdev: %p\n", + MAC2STR(prWlanHeader->aucAddr2), + prNetdevice); + + if (!prGlueInfo->fgIsRegistered || + (prNetdevice == NULL) || + (prNetdevice->ieee80211_ptr == NULL)) { + DBGLOG(P2P, WARN, + "prNetdevice is not ready or NULL!\n"); + break; + } + +#if (KERNEL_VERSION(3, 18, 0) <= CFG80211_VERSION_CODE) + cfg80211_rx_mgmt( + /* struct net_device * dev, */ + prNetdevice->ieee80211_ptr, + i4Freq, + RCPI_TO_dBm( + nicRxGetRcpiValueFromRxv(prGlueInfo->prAdapter, + RCPI_MODE_MAX, + prSwRfb)), + prSwRfb->pvHeader, + prSwRfb->u2PacketLen, + NL80211_RXMGMT_FLAG_ANSWERED); +#elif (KERNEL_VERSION(3, 12, 0) <= CFG80211_VERSION_CODE) + cfg80211_rx_mgmt( + /* struct net_device * dev, */ + prNetdevice->ieee80211_ptr, + i4Freq, + RCPI_TO_dBm( + nicRxGetRcpiValueFromRxv(prGlueInfo->prAdapter, + RCPI_MODE_WF0, + prSwRfb)), + prSwRfb->pvHeader, + prSwRfb->u2PacketLen, + NL80211_RXMGMT_FLAG_ANSWERED, + GFP_ATOMIC); +#else + cfg80211_rx_mgmt( + /* struct net_device * dev, */ + prNetdevice->ieee80211_ptr, + i4Freq, + RCPI_TO_dBm( + nicRxGetRcpiValueFromRxv(prGlueInfo->prAdapter, + RCPI_MODE_WF0, + prSwRfb)), + prSwRfb->pvHeader, + prSwRfb->u2PacketLen, + GFP_ATOMIC); +#endif + + + } while (FALSE); + +} /* kalP2PIndicateRxMgmtFrame */ + +#if CFG_WPS_DISCONNECT || (KERNEL_VERSION(4, 4, 0) <= CFG80211_VERSION_CODE) +void +kalP2PGCIndicateConnectionStatus(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRoleIndex, + IN struct P2P_CONNECTION_REQ_INFO *prP2pConnInfo, + IN uint8_t *pucRxIEBuf, + IN uint16_t u2RxIELen, + IN uint16_t u2StatusReason, + IN uint32_t eStatus) +{ + struct GL_P2P_INFO *prGlueP2pInfo = (struct GL_P2P_INFO *) NULL; + struct ADAPTER *prAdapter = NULL; + + do { + if (prGlueInfo == NULL) { + ASSERT(FALSE); + break; + } + + prAdapter = prGlueInfo->prAdapter; + prGlueP2pInfo = prGlueInfo->prP2PInfo[ucRoleIndex]; + + /* FIXME: This exception occurs at wlanRemove. */ + if ((prGlueP2pInfo == NULL) || + (prGlueP2pInfo->aprRoleHandler == NULL) || + (prGlueP2pInfo->aprRoleHandler->reg_state != + NETREG_REGISTERED) || + (prAdapter->rP2PNetRegState != + ENUM_NET_REG_STATE_REGISTERED) || + ((prGlueInfo->ulFlag & GLUE_FLAG_HALT) == 1)) { + break; + } + + if (prP2pConnInfo) { + /* switch netif on */ + netif_carrier_on(prGlueP2pInfo->aprRoleHandler); + + cfg80211_connect_result(prGlueP2pInfo->aprRoleHandler, + /* struct net_device * dev, */ + prP2pConnInfo->aucBssid, + prP2pConnInfo->aucIEBuf, + prP2pConnInfo->u4BufLength, + pucRxIEBuf, u2RxIELen, + u2StatusReason, + /* gfp_t gfp *//* allocation flags */ + GFP_KERNEL); + + prP2pConnInfo->eConnRequest = P2P_CONNECTION_TYPE_IDLE; + } else { + /* Disconnect, what if u2StatusReason == 0? */ + cfg80211_disconnected(prGlueP2pInfo->aprRoleHandler, + /* struct net_device * dev, */ + u2StatusReason, + pucRxIEBuf, u2RxIELen, + eStatus == WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY, + GFP_KERNEL); + } + + } while (FALSE); + +} /* kalP2PGCIndicateConnectionStatus */ + +#else +void +kalP2PGCIndicateConnectionStatus(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRoleIndex, + IN struct P2P_CONNECTION_REQ_INFO *prP2pConnInfo, + IN uint8_t *pucRxIEBuf, + IN uint16_t u2RxIELen, + IN uint16_t u2StatusReason) +{ + struct GL_P2P_INFO *prGlueP2pInfo = (struct GL_P2P_INFO *) NULL; + struct ADAPTER *prAdapter = NULL; + + do { + if (prGlueInfo == NULL) { + ASSERT(FALSE); + break; + } + + prAdapter = prGlueInfo->prAdapter; + prGlueP2pInfo = prGlueInfo->prP2PInfo[ucRoleIndex]; + + /* FIXME: This exception occurs at wlanRemove. */ + if ((prGlueP2pInfo == NULL) || + (prGlueP2pInfo->aprRoleHandler == NULL) || + (prAdapter->rP2PNetRegState != + ENUM_NET_REG_STATE_REGISTERED) || + ((prGlueInfo->ulFlag & GLUE_FLAG_HALT) == 1)) { + break; + } + + if (prP2pConnInfo) { + /* switch netif on */ + netif_carrier_on(prGlueP2pInfo->aprRoleHandler); + + cfg80211_connect_result(prGlueP2pInfo->aprRoleHandler, + /* struct net_device * dev, */ + prP2pConnInfo->aucBssid, + prP2pConnInfo->aucIEBuf, + prP2pConnInfo->u4BufLength, + pucRxIEBuf, u2RxIELen, + u2StatusReason, + /* gfp_t gfp *//* allocation flags */ + GFP_KERNEL); + + prP2pConnInfo->eConnRequest = P2P_CONNECTION_TYPE_IDLE; + } else { + /* Disconnect, what if u2StatusReason == 0? */ + cfg80211_disconnected(prGlueP2pInfo->aprRoleHandler, + /* struct net_device * dev, */ + u2StatusReason, pucRxIEBuf, + u2RxIELen, GFP_KERNEL); + } + + } while (FALSE); + +} /* kalP2PGCIndicateConnectionStatus */ + +#endif + +void +kalP2PGOStationUpdate(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRoleIndex, + IN struct STA_RECORD *prCliStaRec, + IN u_int8_t fgIsNew) +{ + struct GL_P2P_INFO *prP2pGlueInfo = (struct GL_P2P_INFO *) NULL; + + do { + if ((prGlueInfo == NULL) || (prCliStaRec == NULL) + || (ucRoleIndex >= 2)) + break; + + prP2pGlueInfo = prGlueInfo->prP2PInfo[ucRoleIndex]; + + if ((prP2pGlueInfo == NULL) || + (prP2pGlueInfo->aprRoleHandler == NULL)) { + /* This case may occur when the usb is unplugged */ + break; + } + + if (fgIsNew) { + struct station_info rStationInfo; + + if (prCliStaRec->fgIsConnected == TRUE) + break; + prCliStaRec->fgIsConnected = TRUE; + + kalMemZero(&rStationInfo, sizeof(rStationInfo)); + +#if KERNEL_VERSION(4, 0, 0) > CFG80211_VERSION_CODE + rStationInfo.filled = STATION_INFO_ASSOC_REQ_IES; +#endif + rStationInfo.generation = ++prP2pGlueInfo->i4Generation; + + rStationInfo.assoc_req_ies = prCliStaRec->pucAssocReqIe; + rStationInfo.assoc_req_ies_len = + prCliStaRec->u2AssocReqIeLen; + + cfg80211_new_sta(prP2pGlueInfo->aprRoleHandler, + /* struct net_device * dev, */ + prCliStaRec->aucMacAddr, + &rStationInfo, GFP_KERNEL); + } else { + ++prP2pGlueInfo->i4Generation; + + /* FIXME: The exception occurs at wlanRemove, and + * check GLUE_FLAG_HALT is the temporarily solution. + */ + if ((prGlueInfo->ulFlag & GLUE_FLAG_HALT) == 0) { + if (prCliStaRec->fgIsConnected == FALSE) + break; + prCliStaRec->fgIsConnected = FALSE; + cfg80211_del_sta(prP2pGlueInfo->aprRoleHandler, + /* struct net_device * dev, */ + prCliStaRec->aucMacAddr, GFP_KERNEL); + } + } + + } while (FALSE); + + return; + +} /* kalP2PGOStationUpdate */ + +#if (CFG_SUPPORT_DFS_MASTER == 1) +void kalP2PRddDetectUpdate(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRoleIndex) +{ + struct GL_P2P_INFO *prGlueP2pInfo = (struct GL_P2P_INFO *) NULL; + struct net_device *prNetdevice = (struct net_device *) NULL; + + DBGLOG(INIT, INFO, "Radar Detection event\n"); + + do { + if (prGlueInfo == NULL) { + ASSERT(FALSE); + break; + } + + prGlueP2pInfo = prGlueInfo->prP2PInfo[ucRoleIndex]; + + if ((prGlueP2pInfo->aprRoleHandler != NULL) && + (prGlueP2pInfo->aprRoleHandler != + prGlueP2pInfo->prDevHandler)) + prNetdevice = prGlueP2pInfo->aprRoleHandler; + else + prNetdevice = prGlueP2pInfo->prDevHandler; + + if (prGlueP2pInfo->chandef == NULL) { + ASSERT(FALSE); + break; + } + + /* cac start disable for next cac slot + * if enable in dfs channel + */ + prGlueP2pInfo->prWdev->cac_started = FALSE; + DBGLOG(INIT, INFO, + "kalP2PRddDetectUpdate: Update to OS\n"); + cfg80211_radar_event( + prGlueP2pInfo->prWdev->wiphy, + prGlueP2pInfo->chandef, + GFP_KERNEL); + DBGLOG(INIT, INFO, + "kalP2PRddDetectUpdate: Update to OS Done\n"); + + netif_carrier_off(prNetdevice); + netif_tx_stop_all_queues(prNetdevice); + + if (prGlueP2pInfo->chandef->chan) + cnmMemFree(prGlueInfo->prAdapter, + prGlueP2pInfo->chandef->chan); + + prGlueP2pInfo->chandef->chan = NULL; + + if (prGlueP2pInfo->chandef) + cnmMemFree(prGlueInfo->prAdapter, + prGlueP2pInfo->chandef); + + prGlueP2pInfo->chandef = NULL; + + } while (FALSE); + +} /* kalP2PRddDetectUpdate */ + +void kalP2PCacFinishedUpdate(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRoleIndex) +{ + struct GL_P2P_INFO *prGlueP2pInfo = (struct GL_P2P_INFO *) NULL; + struct net_device *prNetdevice = (struct net_device *) NULL; + + DBGLOG(INIT, INFO, "CAC Finished event\n"); + + do { + if (prGlueInfo == NULL) { + ASSERT(FALSE); + break; + } + + prGlueP2pInfo = prGlueInfo->prP2PInfo[ucRoleIndex]; + + if ((prGlueP2pInfo->aprRoleHandler != NULL) && + (prGlueP2pInfo->aprRoleHandler != + prGlueP2pInfo->prDevHandler)) + prNetdevice = prGlueP2pInfo->aprRoleHandler; + else + prNetdevice = prGlueP2pInfo->prDevHandler; + + if (prGlueP2pInfo->chandef == NULL) { + ASSERT(FALSE); + break; + } + + DBGLOG(INIT, INFO, "kalP2PCacFinishedUpdate: Update to OS\n"); +#if KERNEL_VERSION(3, 14, 0) <= CFG80211_VERSION_CODE + cfg80211_cac_event( + prNetdevice, + prGlueP2pInfo->chandef, + NL80211_RADAR_CAC_FINISHED, GFP_KERNEL); +#else + cfg80211_cac_event( + prNetdevice, + NL80211_RADAR_CAC_FINISHED, GFP_KERNEL); +#endif + DBGLOG(INIT, INFO, + "kalP2PCacFinishedUpdate: Update to OS Done\n"); + + } while (FALSE); + +} /* kalP2PRddDetectUpdate */ +#endif + +u_int8_t kalP2pFuncGetChannelType(IN enum ENUM_CHNL_EXT rChnlSco, + OUT enum nl80211_channel_type *channel_type) +{ + u_int8_t fgIsValid = FALSE; + + do { + if (channel_type) { + + switch (rChnlSco) { + case CHNL_EXT_SCN: + *channel_type = NL80211_CHAN_NO_HT; + break; + case CHNL_EXT_SCA: + *channel_type = NL80211_CHAN_HT40MINUS; + break; + case CHNL_EXT_SCB: + *channel_type = NL80211_CHAN_HT40PLUS; + break; + default: + ASSERT(FALSE); + *channel_type = NL80211_CHAN_NO_HT; + break; + } + + } + + fgIsValid = TRUE; + } while (FALSE); + + return fgIsValid; +} /* kalP2pFuncGetChannelType */ + +struct ieee80211_channel *kalP2pFuncGetChannelEntry( + IN struct GL_P2P_INFO *prP2pInfo, + IN struct RF_CHANNEL_INFO *prChannelInfo) +{ + struct ieee80211_channel *prTargetChannelEntry = + (struct ieee80211_channel *)NULL; + uint32_t u4TblSize = 0, u4Idx = 0; + struct wiphy *wiphy = NULL; + + if ((prP2pInfo == NULL) || (prChannelInfo == NULL)) + return NULL; + + wiphy = prP2pInfo->prWdev->wiphy; + + do { + + switch (prChannelInfo->eBand) { + case BAND_2G4: + if (wiphy->bands[KAL_BAND_2GHZ] == NULL) + DBGLOG(P2P, ERROR, + "kalP2pFuncGetChannelEntry 2.4G NULL Bands!!\n"); + else { + prTargetChannelEntry = + wiphy->bands[KAL_BAND_2GHZ]->channels; + u4TblSize = + wiphy->bands[KAL_BAND_2GHZ]->n_channels; + } + break; + case BAND_5G: + if (wiphy->bands[KAL_BAND_5GHZ] == NULL) + DBGLOG(P2P, ERROR, + "kalP2pFuncGetChannelEntry 5G NULL Bands!!\n"); + else { + prTargetChannelEntry = + wiphy->bands[KAL_BAND_5GHZ]->channels; + u4TblSize = + wiphy->bands[KAL_BAND_5GHZ]->n_channels; + } + break; + default: + break; + } + + if (prTargetChannelEntry == NULL) + break; + + for (u4Idx = 0; u4Idx < u4TblSize + ; u4Idx++, prTargetChannelEntry++) { + if (prTargetChannelEntry->hw_value + == prChannelInfo->ucChannelNum) + break; + + } + + if (u4Idx == u4TblSize) { + prTargetChannelEntry = NULL; + break; + } + + } while (FALSE); + + return prTargetChannelEntry; +} /* kalP2pFuncGetChannelEntry */ + +#if CFG_SUPPORT_HOTSPOT_WPS_MANAGER + +/*---------------------------------------------------------------------------*/ +/*! + * \brief to set the block list of Hotspot + * + * \param[in] + * prGlueInfo + * + * \return + */ +/*---------------------------------------------------------------------------*/ +u_int8_t kalP2PSetBlackList(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t rbssid[PARAM_MAC_ADDR_LEN], + IN u_int8_t fgIsblock, + IN uint8_t ucRoleIndex) +{ + uint8_t aucNullAddr[] = NULL_MAC_ADDR; + uint32_t i; + + ASSERT(prGlueInfo); + + /*if only one ap mode register, prGlueInfo->prP2PInfo[1] would be null*/ + if (!prGlueInfo->prP2PInfo[ucRoleIndex]) + return FALSE; + + if (EQUAL_MAC_ADDR(rbssid, aucNullAddr)) + return FALSE; + + if (fgIsblock) { + for (i = 0; i < P2P_MAXIMUM_CLIENT_COUNT; i++) { + if (EQUAL_MAC_ADDR( + &(prGlueInfo->prP2PInfo[ucRoleIndex] + ->aucblackMACList[i]), rbssid)) { + DBGLOG(P2P, WARN, MACSTR + " already in black list\n", + MAC2STR(rbssid)); + return FALSE; + } + } + for (i = 0; i < P2P_MAXIMUM_CLIENT_COUNT; i++) { + if (EQUAL_MAC_ADDR( + &(prGlueInfo->prP2PInfo + [ucRoleIndex] + ->aucblackMACList[i]), + aucNullAddr)) { + COPY_MAC_ADDR( + &(prGlueInfo->prP2PInfo + [ucRoleIndex] + ->aucblackMACList[i]), + rbssid); + return FALSE; + } + } + } else { + for (i = 0; i < P2P_MAXIMUM_CLIENT_COUNT; i++) { + if (EQUAL_MAC_ADDR( + &(prGlueInfo->prP2PInfo[ucRoleIndex] + ->aucblackMACList[i]), rbssid)) { + COPY_MAC_ADDR( + &(prGlueInfo->prP2PInfo[ucRoleIndex] + ->aucblackMACList[i]), aucNullAddr); + + return FALSE; + } + } + } + + return FALSE; + +} + +u_int8_t kalP2PResetBlackList(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRoleIndex) +{ + uint8_t aucNullAddr[] = NULL_MAC_ADDR; + uint32_t i; + + if (!prGlueInfo || !prGlueInfo->prP2PInfo[ucRoleIndex]) + return FALSE; + + for (i = 0; i < P2P_MAXIMUM_CLIENT_COUNT; i++) { + COPY_MAC_ADDR( + &(prGlueInfo->prP2PInfo[ucRoleIndex] + ->aucblackMACList[i]), aucNullAddr); + } + + return TRUE; +} + +/*---------------------------------------------------------------------------*/ +/*! + * \brief to compare the black list of Hotspot + * + * \param[in] + * prGlueInfo + * + * \return + */ +/*---------------------------------------------------------------------------*/ +u_int8_t kalP2PCmpBlackList(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t rbssid[PARAM_MAC_ADDR_LEN], + IN uint8_t ucRoleIndex) +{ + uint8_t aucNullAddr[] = NULL_MAC_ADDR; + u_int8_t fgIsExsit = FALSE; + uint32_t i; + + ASSERT(prGlueInfo); + ASSERT(prGlueInfo->prP2PInfo[ucRoleIndex]); + + for (i = 0; i < P2P_MAXIMUM_CLIENT_COUNT; i++) { + if (UNEQUAL_MAC_ADDR(rbssid, aucNullAddr)) { + if (EQUAL_MAC_ADDR( + &(prGlueInfo->prP2PInfo + [ucRoleIndex]->aucblackMACList[i]), + rbssid)) { + fgIsExsit = TRUE; + return fgIsExsit; + } + } + } + + return fgIsExsit; + +} + +/*---------------------------------------------------------------------------*/ +/*! + * \brief to return the max clients of Hotspot + * + * \param[in] + * prGlueInfo + * + * \return + */ +/*---------------------------------------------------------------------------*/ +void kalP2PSetMaxClients(IN struct GLUE_INFO *prGlueInfo, + IN uint32_t u4MaxClient, + IN uint8_t ucRoleIndex) +{ + ASSERT(prGlueInfo); + + if (prGlueInfo->prP2PInfo[ucRoleIndex] == NULL) + return; + + if (u4MaxClient == 0 || + u4MaxClient >= P2P_MAXIMUM_CLIENT_COUNT) + prGlueInfo->prP2PInfo[ucRoleIndex]->ucMaxClients = + P2P_MAXIMUM_CLIENT_COUNT; + else + prGlueInfo->prP2PInfo[ucRoleIndex]->ucMaxClients = u4MaxClient; + + DBGLOG(P2P, TRACE, + "Role(%d) max client count = %u\n", + ucRoleIndex, + prGlueInfo->prP2PInfo[ucRoleIndex]->ucMaxClients); +} + +/*---------------------------------------------------------------------------*/ +/*! + * \brief to return the max clients of Hotspot + * + * \param[in] + * prGlueInfo + * + * \return + */ +/*---------------------------------------------------------------------------*/ +u_int8_t kalP2PMaxClients(IN struct GLUE_INFO *prGlueInfo, + IN uint32_t u4NumClient, IN uint8_t ucRoleIndex) +{ + ASSERT(prGlueInfo); + + if (prGlueInfo->prP2PInfo[ucRoleIndex] && + prGlueInfo->prP2PInfo[ucRoleIndex]->ucMaxClients) { + if ((uint8_t) u4NumClient + >= prGlueInfo->prP2PInfo[ucRoleIndex]->ucMaxClients) + return TRUE; + else + return FALSE; + } + + return FALSE; +} + +#endif + +void kalP2pUnlinkBss(IN struct GLUE_INFO *prGlueInfo, IN uint8_t aucBSSID[]) +{ + struct GL_P2P_INFO *prGlueP2pInfo = (struct GL_P2P_INFO *) NULL; + + ASSERT(prGlueInfo); + ASSERT(aucBSSID); + + DBGLOG(P2P, INFO, "bssid: " MACSTR "\n", MAC2STR(aucBSSID)); + + prGlueP2pInfo = prGlueInfo->prP2PInfo[0]; + + if (prGlueP2pInfo == NULL) + return; + + if (scanSearchBssDescByBssidAndSsid(prGlueInfo->prAdapter, + aucBSSID, FALSE, NULL) != NULL) + scanRemoveBssDescByBssid(prGlueInfo->prAdapter, aucBSSID); +} + +void kalP2pIndicateQueuedMgmtFrame(IN struct GLUE_INFO *prGlueInfo, + IN struct P2P_QUEUED_ACTION_FRAME *prFrame) +{ + struct GL_P2P_INFO *prGlueP2pInfo = (struct GL_P2P_INFO *) NULL; + struct net_device *prNetdevice = (struct net_device *) NULL; + + if ((prGlueInfo == NULL) || (prFrame == NULL)) { + ASSERT(FALSE); + return; + } + + DBGLOG(P2P, INFO, "Indicate queued p2p action frame.\n"); + + if (prFrame->prHeader == NULL || prFrame->u2Length == 0) { + DBGLOG(P2P, WARN, "Frame pointer is null or length is 0.\n"); + return; + } + + prGlueP2pInfo = prGlueInfo->prP2PInfo[prFrame->ucRoleIdx]; + + if ((prGlueP2pInfo->aprRoleHandler != NULL) && + (prGlueP2pInfo->aprRoleHandler != prGlueP2pInfo->prDevHandler)) + prNetdevice = prGlueP2pInfo->aprRoleHandler; + else + prNetdevice = prGlueP2pInfo->prDevHandler; + +#if (KERNEL_VERSION(3, 18, 0) <= CFG80211_VERSION_CODE) + cfg80211_rx_mgmt( + /* struct net_device * dev, */ + prNetdevice->ieee80211_ptr, + prFrame->u4Freq, + 0, + prFrame->prHeader, + prFrame->u2Length, + NL80211_RXMGMT_FLAG_ANSWERED); +#elif (KERNEL_VERSION(3, 12, 0) <= CFG80211_VERSION_CODE) + cfg80211_rx_mgmt( + /* struct net_device * dev, */ + prNetdevice->ieee80211_ptr, + prFrame->u4Freq, + 0, + prFrame->prHeader, + prFrame->u2Length, + NL80211_RXMGMT_FLAG_ANSWERED, + GFP_ATOMIC); +#else + cfg80211_rx_mgmt( + /* struct net_device * dev, */ + prNetdevice->ieee80211_ptr, + prFrame->u4Freq, + 0, + prFrame->prHeader, + prFrame->u2Length, + GFP_ATOMIC); +#endif +} + +void kalP2pIndicateAcsResult(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRoleIndex, + IN uint8_t ucPrimaryCh, + IN uint8_t ucSecondCh, + IN uint8_t ucSeg0Ch, + IN uint8_t ucSeg1Ch, + IN enum ENUM_MAX_BANDWIDTH_SETTING eChnlBw) +{ + struct GL_P2P_INFO *prGlueP2pInfo = (struct GL_P2P_INFO *) NULL; + struct sk_buff *vendor_event = NULL; + uint16_t ch_width = MAX_BW_20MHZ; + + prGlueP2pInfo = prGlueInfo->prP2PInfo[ucRoleIndex]; + + if (!prGlueP2pInfo) { + DBGLOG(P2P, ERROR, "p2p glue info null.\n"); + return; + } + + switch (eChnlBw) { + case MAX_BW_20MHZ: + ch_width = 20; + break; + case MAX_BW_40MHZ: + ch_width = 40; + break; + case MAX_BW_80MHZ: + ch_width = 80; + break; + case MAX_BW_160MHZ: + ch_width = 160; + break; + default: + DBGLOG(P2P, ERROR, "unsupport width: %d.\n", ch_width); + break; + } + + DBGLOG(P2P, INFO, "r=%d, c=%d, s=%d, s0=%d, s1=%d, ch_w=%d\n", + ucRoleIndex, + ucPrimaryCh, + ucSecondCh, + ucSeg0Ch, + ucSeg1Ch, + ch_width); + +#if KERNEL_VERSION(3, 14, 0) <= LINUX_VERSION_CODE + vendor_event = cfg80211_vendor_event_alloc(prGlueP2pInfo->prWdev->wiphy, +#if KERNEL_VERSION(4, 1, 0) <= LINUX_VERSION_CODE + prGlueP2pInfo->prWdev, +#endif + 4 * sizeof(u8) + 1 * sizeof(u16) + 4 + NLMSG_HDRLEN, + WIFI_EVENT_ACS, + GFP_KERNEL); +#endif + + if (!vendor_event) { + DBGLOG(P2P, ERROR, "allocate vendor event fail.\n"); + goto nla_put_failure; + } + + if (unlikely(nla_put_u8(vendor_event, + WIFI_VENDOR_ATTR_ACS_PRIMARY_CHANNEL, + ucPrimaryCh) < 0)) { + DBGLOG(P2P, ERROR, "put primary channel fail.\n"); + goto nla_put_failure; + } + + if (unlikely(nla_put_u8(vendor_event, + WIFI_VENDOR_ATTR_ACS_SECONDARY_CHANNEL, + ucSecondCh) < 0)) { + DBGLOG(P2P, ERROR, "put secondary channel fail.\n"); + goto nla_put_failure; + } + + if (unlikely(nla_put_u8(vendor_event, + WIFI_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL, + ucSeg0Ch) < 0)) { + DBGLOG(P2P, ERROR, "put vht seg0 fail.\n"); + goto nla_put_failure; + } + + if (unlikely(nla_put_u8(vendor_event, + WIFI_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL, + ucSeg1Ch) < 0)) { + DBGLOG(P2P, ERROR, "put vht seg1 fail.\n"); + goto nla_put_failure; + } + + if (unlikely(nla_put_u16(vendor_event, + WIFI_VENDOR_ATTR_ACS_CHWIDTH, + ch_width) < 0)) { + DBGLOG(P2P, ERROR, "put ch width fail.\n"); + goto nla_put_failure; + } + + if (unlikely(nla_put_u8(vendor_event, + WIFI_VENDOR_ATTR_ACS_HW_MODE, + ucPrimaryCh > 14 ? + P2P_VENDOR_ACS_HW_MODE_11A : + P2P_VENDOR_ACS_HW_MODE_11G) < 0)) { + DBGLOG(P2P, ERROR, "put hw mode fail.\n"); + goto nla_put_failure; + } +#if KERNEL_VERSION(3, 14, 0) <= LINUX_VERSION_CODE + cfg80211_vendor_event(vendor_event, GFP_KERNEL); +#endif + return; + +nla_put_failure: + if (vendor_event) + kfree_skb(vendor_event); +} + +void kalP2pNotifyStopApComplete(IN struct ADAPTER *prAdapter, + IN uint8_t ucRoleIndex) +{ + struct GL_P2P_INFO *prP2PInfo; + + if (!prAdapter) + return; + + prP2PInfo = prAdapter->prGlueInfo->prP2PInfo[ucRoleIndex]; + if (prP2PInfo && !completion_done(&prP2PInfo->rStopApComp)) + complete(&prP2PInfo->rStopApComp); +} + +void kalP2pIndicateChnlSwitch(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo) +{ + struct GL_P2P_INFO *prP2PInfo; + struct net_device *prNetdevice = (struct net_device *) NULL; + uint8_t role_idx = 0; + + if (!prAdapter || !prBssInfo) + return; + + role_idx = prBssInfo->u4PrivateData; + prP2PInfo = prAdapter->prGlueInfo->prP2PInfo[role_idx]; + + if (!prP2PInfo) { + DBGLOG(P2P, WARN, "p2p glue info is not active\n"); + return; + } + + if ((prP2PInfo->aprRoleHandler != NULL) && + (prP2PInfo->aprRoleHandler != prP2PInfo->prDevHandler)) + prNetdevice = prP2PInfo->aprRoleHandler; + else + prNetdevice = prP2PInfo->prDevHandler; + + /* Compose ch info. */ + if (prP2PInfo->chandef == NULL) { + struct ieee80211_channel *chan; + + prP2PInfo->chandef = (struct cfg80211_chan_def *) + cnmMemAlloc(prAdapter, RAM_TYPE_BUF, + sizeof(struct cfg80211_chan_def)); + if (!prP2PInfo->chandef) { + DBGLOG(P2P, WARN, "cfg80211_chan_def alloc fail\n"); + return; + } + + prP2PInfo->chandef->chan = (struct ieee80211_channel *) + cnmMemAlloc(prAdapter, RAM_TYPE_BUF, + sizeof(struct ieee80211_channel)); + + if (!prP2PInfo->chandef->chan) { + DBGLOG(P2P, WARN, "ieee80211_channel alloc fail\n"); + return; + } + + chan = ieee80211_get_channel(prP2PInfo->prWdev->wiphy, + nicChannelNum2Freq( + prBssInfo->ucPrimaryChannel) / 1000); + if (!chan) { + DBGLOG(P2P, WARN, + "get channel fail\n"); + return; + } + + /* Fill chan def */ + prP2PInfo->chandef->chan->band = + (prBssInfo->eBand == BAND_5G) ? + KAL_BAND_5GHZ : KAL_BAND_2GHZ; + prP2PInfo->chandef->chan->center_freq = nicChannelNum2Freq( + prBssInfo->ucPrimaryChannel) / 1000; + + prP2PInfo->chandef->chan->dfs_state = chan->dfs_state; + + switch (prBssInfo->ucVhtChannelWidth) { + case VHT_OP_CHANNEL_WIDTH_80P80: + prP2PInfo->chandef->width + = NL80211_CHAN_WIDTH_80P80; + prP2PInfo->chandef->center_freq1 + = nicChannelNum2Freq( + prBssInfo->ucVhtChannelFrequencyS1) / 1000; + prP2PInfo->chandef->center_freq2 + = nicChannelNum2Freq( + prBssInfo->ucVhtChannelFrequencyS2) / 1000; + break; + case VHT_OP_CHANNEL_WIDTH_160: + prP2PInfo->chandef->width + = NL80211_CHAN_WIDTH_160; + prP2PInfo->chandef->center_freq1 + = nicChannelNum2Freq( + prBssInfo->ucVhtChannelFrequencyS1) / 1000; + prP2PInfo->chandef->center_freq2 + = nicChannelNum2Freq( + prBssInfo->ucVhtChannelFrequencyS2) / 1000; + break; + case VHT_OP_CHANNEL_WIDTH_80: + prP2PInfo->chandef->width + = NL80211_CHAN_WIDTH_80; + prP2PInfo->chandef->center_freq1 + = nicChannelNum2Freq( + prBssInfo->ucVhtChannelFrequencyS1) / 1000; + prP2PInfo->chandef->center_freq2 + = nicChannelNum2Freq( + prBssInfo->ucVhtChannelFrequencyS2) / 1000; + break; + case VHT_OP_CHANNEL_WIDTH_20_40: + prP2PInfo->chandef->center_freq1 + = prP2PInfo->chandef->chan->center_freq; + if (prBssInfo->eBssSCO == CHNL_EXT_SCA) { + prP2PInfo->chandef->width + = NL80211_CHAN_WIDTH_40; + prP2PInfo->chandef->center_freq1 += 10; + } else if (prBssInfo->eBssSCO == CHNL_EXT_SCB) { + prP2PInfo->chandef->width + = NL80211_CHAN_WIDTH_40; + prP2PInfo->chandef->center_freq1 -= 10; + } else { + prP2PInfo->chandef->width + = NL80211_CHAN_WIDTH_20; + } + prP2PInfo->chandef->center_freq2 = 0; + break; + default: + prP2PInfo->chandef->width + = NL80211_CHAN_WIDTH_20; + prP2PInfo->chandef->center_freq1 + = prP2PInfo->chandef->chan->center_freq; + prP2PInfo->chandef->center_freq2 = 0; + break; + } + + DBGLOG(P2P, INFO, + "role(%d) b=%d f=%d w=%d s1=%d s2=%d dfs=%d\n", + role_idx, + prP2PInfo->chandef->chan->band, + prP2PInfo->chandef->chan->center_freq, + prP2PInfo->chandef->width, + prP2PInfo->chandef->center_freq1, + prP2PInfo->chandef->center_freq2, + prP2PInfo->chandef->chan->dfs_state); + } + + /* Ch notify */ + cfg80211_ch_switch_notify( + prNetdevice, + prP2PInfo->chandef); +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_proc.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_proc.c new file mode 100644 index 0000000000000000000000000000000000000000..7d21f4dcac482e87f507428838decd92717bdb7c --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_proc.c @@ -0,0 +1,1981 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: /os/linux/gl_proc.c + */ + +/*! \file "gl_proc.c" + * \brief This file defines the interface which can interact with users + * in /proc fs. + * + * Detail description. + */ + + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" +#include "gl_os.h" +#include "gl_kal.h" +#include "debug.h" +#include "wlan_lib.h" +#include "debug.h" +#include "wlan_oid.h" +#include + +#if (CFG_TWT_SMART_STA == 1) +#include "twt.h" +#endif + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#define PROC_MCR_ACCESS "mcr" +#define PROC_ROOT_NAME "wlan" + +#if CFG_SUPPORT_DEBUG_FS +#define PROC_ROAM_PARAM "roam_param" +#endif +#define PROC_COUNTRY "country" +#define PROC_DRV_STATUS "status" +#define PROC_RX_STATISTICS "rx_statistics" +#define PROC_TX_STATISTICS "tx_statistics" +#define PROC_DBG_LEVEL_NAME "dbgLevel" +#define PROC_DRIVER_CMD "driver" +#define PROC_CFG "cfg" +#define PROC_EFUSE_DUMP "efuse_dump" +#define PROC_PKT_DELAY_DBG "pktDelay" +#if CFG_SUPPORT_SET_CAM_BY_PROC +#define PROC_SET_CAM "setCAM" +#endif +#define PROC_AUTO_PERF_CFG "autoPerfCfg" +#if (CFG_TWT_SMART_STA == 1) +#define PROC_TWT_SMART "twt_smart_sta" +#endif +#if (CFG_SUPPORT_PRE_ON_PHY_ACTION == 1) +#define PROC_CAL_RESULT "cal_result" +#endif /*(CFG_SUPPORT_PRE_ON_PHY_ACTION == 1)*/ + +#define PROC_MCR_ACCESS_MAX_USER_INPUT_LEN 20 +#define PROC_RX_STATISTICS_MAX_USER_INPUT_LEN 10 +#define PROC_TX_STATISTICS_MAX_USER_INPUT_LEN 10 +#define PROC_DBG_LEVEL_MAX_USER_INPUT_LEN 20 +#define PROC_DBG_LEVEL_MAX_DISPLAY_STR_LEN 30 +#define PROC_UID_SHELL 2000 +#define PROC_GID_WIFI 1010 + +/* notice: str only can be an array */ +#define SNPRINTF(buf, str, arg) {buf += \ + snprintf((char *)(buf), sizeof(str)-kalStrLen(str), PRINTF_ARG arg); } + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ +#if (CFG_TWT_SMART_STA == 1) +struct _TWT_SMART_STA_T g_TwtSmartStaCtrl; +#endif + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ +static struct GLUE_INFO *g_prGlueInfo_proc; +static uint32_t u4McrOffset; +static struct proc_dir_entry *gprProcRoot; +static uint8_t aucDbModuleName[][PROC_DBG_LEVEL_MAX_DISPLAY_STR_LEN] = { + "INIT", "HAL", "INTR", "REQ", "TX", "RX", "RFTEST", "EMU", + "SW1", "SW2", "SW3", "SW4", "HEM", "AIS", "RLM", "MEM", + "CNM", "RSN", "BSS", "SCN", "SAA", "AAA", "P2P", "QM", + "SEC", "BOW", "WAPI", "ROAMING", "TDLS", "PF", "OID", "NIC" +}; + +/* This buffer could be overwrite by any proc commands */ +static uint8_t g_aucProcBuf[3000]; + +/* This u32 is only for DriverCmdRead/Write, + * should not be used by other function + */ +static int32_t g_i4NextDriverReadLen; +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +static ssize_t procDbgLevelRead(struct file *filp, char __user *buf, + size_t count, loff_t *f_pos) +{ + uint8_t *temp = &g_aucProcBuf[0]; + uint8_t *str = NULL; + uint32_t u4CopySize = 0; + uint16_t i; + uint16_t u2ModuleNum = 0; + uint32_t u4StrLen = 0; + uint32_t u4Level1, u4Level2; + + /* if *f_ops>0, we should return 0 to make cat command exit */ + if (*f_pos > 0 || buf == NULL) + return 0; + + str = "\nTEMP|LOUD|INFO|TRACE | EVENT|STATE|WARN|ERROR\n" + "bit7|bit6|bit5|bit4 | bit3|bit2|bit1|bit0\n\n" + "Usage: Module Index:Module Level, such as 0x00:0xff\n\n" + "Debug Module\tIndex\tLevel\tDebug Module\tIndex\tLevel\n\n"; + u4StrLen = kalStrLen(str); + kalStrnCpy(temp, str, u4StrLen); + temp += u4StrLen; + + u2ModuleNum = + (sizeof(aucDbModuleName) / + PROC_DBG_LEVEL_MAX_DISPLAY_STR_LEN) & 0xfe; + + for (i = 0; i < u2ModuleNum; i += 2) { + wlanGetDriverDbgLevel(i, &u4Level1); + wlanGetDriverDbgLevel(i + 1, &u4Level2); + SNPRINTF(temp, g_aucProcBuf, + ("DBG_%s_IDX\t(0x%02x):\t0x%02x\t" + "DBG_%s_IDX\t(0x%02x):\t0x%02x\n", + &aucDbModuleName[i][0], i, (uint8_t) u4Level1, + &aucDbModuleName[i + 1][0], i + 1, + (uint8_t) u4Level2)); + } + + if ((sizeof(aucDbModuleName) / + PROC_DBG_LEVEL_MAX_DISPLAY_STR_LEN) & 0x1) { + wlanGetDriverDbgLevel(u2ModuleNum, &u4Level1); + SNPRINTF(temp, g_aucProcBuf, + ("DBG_%s_IDX\t(0x%02x):\t0x%02x\n", + &aucDbModuleName[u2ModuleNum][0], u2ModuleNum, + (uint8_t) u4Level1)); + } + + u4CopySize = kalStrLen(g_aucProcBuf); + if (u4CopySize > count) + u4CopySize = count; + if (copy_to_user(buf, g_aucProcBuf, u4CopySize)) { + pr_err("copy to user failed\n"); + return -EFAULT; + } + + *f_pos += u4CopySize; + return (ssize_t) u4CopySize; +} + +#if WLAN_INCLUDE_PROC +#if CFG_SUPPORT_EASY_DEBUG + +static void *procEfuseDump_start(struct seq_file *s, loff_t *pos) +{ + static unsigned long counter; + + if (*pos == 0) + counter = *pos; /* read file init */ + + if (counter >= EFUSE_ADDR_MAX) + return NULL; + return &counter; +} + +static void *procEfuseDump_next(struct seq_file *s, void *v, loff_t *pos) +{ + unsigned long *tmp_v = (unsigned long *)v; + + (*tmp_v) += EFUSE_BLOCK_SIZE; + + if (*tmp_v >= EFUSE_ADDR_MAX) + return NULL; + return tmp_v; +} + +static void procEfuseDump_stop(struct seq_file *s, void *v) +{ + /* nothing to do, we use a static value in start() */ +} + +static int procEfuseDump_show(struct seq_file *s, void *v) +{ + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + struct GLUE_INFO *prGlueInfo; + uint32_t idx_addr, idx_value; + struct PARAM_CUSTOM_ACCESS_EFUSE rAccessEfuseInfo = { }; + + prGlueInfo = g_prGlueInfo_proc; + +#if (CFG_EEPROM_PAGE_ACCESS == 1) + if (prGlueInfo == NULL) { + seq_puts(s, "prGlueInfo is null\n"); + return -EPERM; + } + + if (prGlueInfo && + prGlueInfo->prAdapter && + prGlueInfo->prAdapter->chip_info && + !prGlueInfo->prAdapter->chip_info->is_support_efuse) { + seq_puts(s, "efuse ops is invalid\n"); + return -EPERM; /* return negative value to stop read process */ + } + + idx_addr = *(loff_t *) v; + rAccessEfuseInfo.u4Address = + (idx_addr / EFUSE_BLOCK_SIZE) * EFUSE_BLOCK_SIZE; + + rStatus = kalIoctl(prGlueInfo, + wlanoidQueryProcessAccessEfuseRead, + &rAccessEfuseInfo, + sizeof(struct PARAM_CUSTOM_ACCESS_EFUSE), TRUE, TRUE, + TRUE, &u4BufLen); + if (rStatus != WLAN_STATUS_SUCCESS) { + seq_printf(s, "efuse read fail (0x%03X)\n", + rAccessEfuseInfo.u4Address); + return 0; + } + + for (idx_value = 0; idx_value < EFUSE_BLOCK_SIZE; idx_value++) + seq_printf(s, "0x%03X=0x%02X\n", + rAccessEfuseInfo.u4Address + idx_value, + prGlueInfo->prAdapter->aucEepromVaule[idx_value]); + return 0; +#else + seq_puts(s, "efuse ops is invalid\n"); + return -EPERM; /* return negative value to stop read process */ +#endif +} + +static int procEfuseDumpOpen(struct inode *inode, struct file *file) +{ + static const struct seq_operations procEfuseDump_ops = { + .start = procEfuseDump_start, + .next = procEfuseDump_next, + .stop = procEfuseDump_stop, + .show = procEfuseDump_show + }; + + return seq_open(file, &procEfuseDump_ops); +} + +static ssize_t procCfgRead(struct file *filp, char __user *buf, size_t count, + loff_t *f_pos) +{ + uint8_t *temp = &g_aucProcBuf[0]; + uint8_t *str = NULL; + uint8_t *str2 = "\nERROR DUMP CONFIGURATION:\n"; + uint32_t u4CopySize = 0; + uint32_t i; + uint32_t u4StrLen = 0; + +#define BUFFER_RESERVE_BYTE 50 + + struct GLUE_INFO *prGlueInfo; + + struct WLAN_CFG_ENTRY *prWlanCfgEntry; + struct ADAPTER *prAdapter; + + prGlueInfo = *((struct GLUE_INFO **)netdev_priv(gPrDev)); + + if (!prGlueInfo) { + pr_err("procCfgRead prGlueInfo is NULL????\n"); + return 0; + } + + prAdapter = prGlueInfo->prAdapter; + + if (!prAdapter) { + pr_err("procCfgRead prAdapter is NULL????\n"); + return 0; + } + + /* if *f_ops>0, we should return 0 to make cat command exit */ + if (*f_pos > 0 || buf == NULL) + return 0; + + str = "\nDUMP CONFIGURATION :\n" + " OR \n" + "'D': driver part current setting\n" + "===================================\n"; + u4StrLen = kalStrLen(str); + kalStrnCpy(temp, str, u4StrLen); + temp += u4StrLen; + + for (i = 0; i < WLAN_CFG_ENTRY_NUM_MAX; i++) { + prWlanCfgEntry = + wlanCfgGetEntryByIndex(prAdapter, i, WLAN_CFG_DEFAULT); + + if ((!prWlanCfgEntry) || (prWlanCfgEntry->aucKey[0] == '\0')) + break; + + SNPRINTF(temp, g_aucProcBuf, + ("%s|%s\n", prWlanCfgEntry->aucKey, + prWlanCfgEntry->aucValue)); + + if ((temp - g_aucProcBuf) != kalStrLen(g_aucProcBuf)) { + DBGLOG(INIT, ERROR, + "Dump configuration error: temp offset=%d, buf length=%u, key[%d]=[%u], val[%d]=[%u]\n", + (int)(temp - g_aucProcBuf), + (uint32_t)kalStrLen(g_aucProcBuf), + WLAN_CFG_KEY_LEN_MAX, + (uint32_t)prWlanCfgEntry->aucKey[ + WLAN_CFG_KEY_LEN_MAX - 1], + WLAN_CFG_VALUE_LEN_MAX, + (uint32_t)prWlanCfgEntry->aucValue[ + WLAN_CFG_VALUE_LEN_MAX - 1]); + kalMemSet(g_aucProcBuf, ' ', u4StrLen); + kalStrnCpy(g_aucProcBuf, str2, kalStrLen(str2) + 1); + g_aucProcBuf[u4StrLen-1] = 0; + goto procCfgReadLabel; + } + + if (kalStrLen(g_aucProcBuf) > + (sizeof(g_aucProcBuf) - BUFFER_RESERVE_BYTE)) + break; + } + + for (i = 0; i < WLAN_CFG_REC_ENTRY_NUM_MAX; i++) { + prWlanCfgEntry = + wlanCfgGetEntryByIndex(prAdapter, i, WLAN_CFG_REC); + + if ((!prWlanCfgEntry) || (prWlanCfgEntry->aucKey[0] == '\0')) + break; + + SNPRINTF(temp, g_aucProcBuf, + ("D:%s|%s\n", prWlanCfgEntry->aucKey, + prWlanCfgEntry->aucValue)); + + if ((temp - g_aucProcBuf) != kalStrLen(g_aucProcBuf)) { + DBGLOG(INIT, ERROR, + "D:Dump configuration error: temp offset=%d, buf length=%u, key[%d]=[%u], val[%d]=[%u]\n", + (int)(temp - g_aucProcBuf), + (uint32_t)kalStrLen(g_aucProcBuf), + WLAN_CFG_KEY_LEN_MAX, + (uint32_t)prWlanCfgEntry->aucKey[ + WLAN_CFG_KEY_LEN_MAX - 1], + WLAN_CFG_VALUE_LEN_MAX, + (uint32_t)prWlanCfgEntry->aucValue[ + WLAN_CFG_VALUE_LEN_MAX - 1]); + kalMemSet(g_aucProcBuf, ' ', u4StrLen); + kalStrnCpy(g_aucProcBuf, str2, kalStrLen(str2) + 1); + g_aucProcBuf[u4StrLen-1] = 0; + goto procCfgReadLabel; + } + + if (kalStrLen(g_aucProcBuf) > + (sizeof(g_aucProcBuf) - BUFFER_RESERVE_BYTE)) + break; + } + +procCfgReadLabel: + u4CopySize = kalStrLen(g_aucProcBuf); + if (u4CopySize > count) + u4CopySize = count; + if (copy_to_user(buf, g_aucProcBuf, u4CopySize)) { + pr_err("copy to user failed\n"); + return -EFAULT; + } + + *f_pos += u4CopySize; + return (ssize_t) u4CopySize; +} + +static ssize_t procCfgWrite(struct file *file, const char __user *buffer, + size_t count, loff_t *data) +{ + + /* uint32_t u4DriverCmd, u4DriverValue; + *uint8_t *temp = &g_aucProcBuf[0]; + */ + uint32_t u4CopySize = sizeof(g_aucProcBuf)-8; + struct GLUE_INFO *prGlueInfo; + uint8_t *pucTmp; + /* PARAM_CUSTOM_P2P_SET_STRUCT_T rSetP2P; */ + uint32_t i = 0; + + kalMemSet(g_aucProcBuf, 0, u4CopySize); + u4CopySize = (count < u4CopySize) ? count : (u4CopySize - 1); + + pucTmp = g_aucProcBuf; + SNPRINTF(pucTmp, g_aucProcBuf, ("%s ", "set_cfg")); + + if (copy_from_user(pucTmp, buffer, u4CopySize)) { + pr_err("error of copy from user\n"); + return -EFAULT; + } + g_aucProcBuf[u4CopySize + 8] = '\0'; + + for (i = 8 ; i < u4CopySize+8; i++) { + if (!isalnum(g_aucProcBuf[i]) && /* alphanumeric */ + g_aucProcBuf[i] != 0x20 && /* space */ + g_aucProcBuf[i] != 0x0a && /* control char */ + g_aucProcBuf[i] != 0x0d) { + DBGLOG(INIT, ERROR, "wrong char[%d] 0x%x\n", + i, g_aucProcBuf[i]); + return -EFAULT; + } + } + + prGlueInfo = g_prGlueInfo_proc; + /* if g_i4NextDriverReadLen >0, + * the content for next DriverCmdRead will be + * in : g_aucProcBuf with length : g_i4NextDriverReadLen + */ + g_i4NextDriverReadLen = + priv_driver_set_cfg(prGlueInfo->prDevHandler, g_aucProcBuf, + sizeof(g_aucProcBuf)); + + return count; + +} + +static ssize_t procDriverCmdRead(struct file *filp, char __user *buf, + size_t count, loff_t *f_pos) +{ + /* DriverCmd read should only be executed right after + * a DriverCmd write because content buffer 'g_aucProcBuf' + * is a global buffer for all proc command, otherwise , + * the content could be overwrite by other proc command + */ + uint32_t u4CopySize = 0; + + /* if *f_ops>0, we should return 0 to make cat command exit */ + if (*f_pos > 0 || buf == NULL) + return 0; + + if (g_i4NextDriverReadLen > 0) /* Detect content to show */ + u4CopySize = g_i4NextDriverReadLen; + + if (u4CopySize > count) { + pr_err("count is too small: u4CopySize=%u, count=%u\n", + u4CopySize, (uint32_t)count); + return -EFAULT; + } + + if (copy_to_user(buf, g_aucProcBuf, u4CopySize)) { + pr_err("copy to user failed\n"); + return -EFAULT; + } + g_i4NextDriverReadLen = 0; + + *f_pos += u4CopySize; + return (ssize_t) u4CopySize; +} + + + +static ssize_t procDriverCmdWrite(struct file *file, const char __user *buffer, + size_t count, loff_t *data) +{ +/* UINT_32 u4DriverCmd, u4DriverValue; + * UINT_8 *temp = &g_aucProcBuf[0]; + */ + uint32_t u4CopySize = sizeof(g_aucProcBuf); + struct GLUE_INFO *prGlueInfo; +/* PARAM_CUSTOM_P2P_SET_STRUCT_T rSetP2P; */ + + kalMemSet(g_aucProcBuf, 0, u4CopySize); + u4CopySize = (count < u4CopySize) ? count : (u4CopySize - 1); + + if (copy_from_user(g_aucProcBuf, buffer, u4CopySize)) { + pr_err("error of copy from user\n"); + return -EFAULT; + } + g_aucProcBuf[u4CopySize] = '\0'; + + + prGlueInfo = g_prGlueInfo_proc; + /* if g_u4NextDriverReadLen >0, + * the content for next DriverCmdRead will be + * in : g_aucProcBuf with length : g_u4NextDriverReadLen + */ + if (strlen(g_aucProcBuf) > 0) { + g_i4NextDriverReadLen = + priv_driver_cmds(prGlueInfo->prDevHandler, g_aucProcBuf, + sizeof(g_aucProcBuf)); + } + + return count; +} +#endif +#endif + +static ssize_t procDbgLevelWrite(struct file *file, const char __user *buffer, + size_t count, loff_t *data) +{ + uint32_t u4NewDbgModule, u4NewDbgLevel; + uint8_t *temp = &g_aucProcBuf[0]; + uint32_t u4CopySize = sizeof(g_aucProcBuf); + + kalMemSet(g_aucProcBuf, 0, u4CopySize); + u4CopySize = (count < u4CopySize) ? count : (u4CopySize - 1); + + if (copy_from_user(g_aucProcBuf, buffer, u4CopySize)) { + pr_err("error of copy from user\n"); + return -EFAULT; + } + g_aucProcBuf[u4CopySize] = '\0'; + + while (temp) { + if (sscanf(temp, + "0x%x:0x%x", &u4NewDbgModule, &u4NewDbgLevel) != 2) { + pr_info("debug module and debug level should be one byte in length\n"); + break; + } + if (u4NewDbgModule == 0xFF) { + wlanSetDriverDbgLevel(DBG_ALL_MODULE_IDX, + (u4NewDbgLevel & DBG_CLASS_MASK)); + break; + } + if (u4NewDbgModule >= DBG_MODULE_NUM) { + pr_info("debug module index should less than %d\n", + DBG_MODULE_NUM); + break; + } + wlanSetDriverDbgLevel(u4NewDbgModule, + (u4NewDbgLevel & DBG_CLASS_MASK)); + temp = kalStrChr(temp, ','); + if (!temp) + break; + temp++; /* skip ',' */ + } + return count; +} + +static const struct file_operations dbglevel_ops = { + .owner = THIS_MODULE, + .read = procDbgLevelRead, + .write = procDbgLevelWrite, +}; + +#if WLAN_INCLUDE_PROC +#if CFG_SUPPORT_EASY_DEBUG + +static const struct file_operations efusedump_ops = { + .owner = THIS_MODULE, + .open = procEfuseDumpOpen, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +static const struct file_operations drivercmd_ops = { + .owner = THIS_MODULE, + .read = procDriverCmdRead, + .write = procDriverCmdWrite, +}; + +static const struct file_operations cfg_ops = { + .owner = THIS_MODULE, + .read = procCfgRead, + .write = procCfgWrite, +}; +#endif +#endif + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +/*----------------------------------------------------------------------------*/ +/*! + * \brief The PROC function for reading MCR register to User Space, the offset + * of the MCR is specified in u4McrOffset. + * + * \param[in] page Buffer provided by kernel. + * \param[in out] start Start Address to read(3 methods). + * \param[in] off Offset. + * \param[in] count Allowable number to read. + * \param[out] eof End of File indication. + * \param[in] data Pointer to the private data structure. + * + * \return number of characters print to the buffer from User Space. + */ +/*----------------------------------------------------------------------------*/ +static ssize_t procMCRRead(struct file *filp, char __user *buf, + size_t count, loff_t *f_pos) +{ + struct GLUE_INFO *prGlueInfo; + struct PARAM_CUSTOM_MCR_RW_STRUCT rMcrInfo; + uint32_t u4BufLen; + uint32_t u4Count; + uint8_t *temp = &g_aucProcBuf[0]; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + + /* Kevin: Apply PROC read method 1. */ + if (*f_pos > 0) + return 0; /* To indicate end of file. */ + + prGlueInfo = g_prGlueInfo_proc; + + rMcrInfo.u4McrOffset = u4McrOffset; + + rStatus = kalIoctl(prGlueInfo, + wlanoidQueryMcrRead, (void *)&rMcrInfo, + sizeof(rMcrInfo), TRUE, TRUE, TRUE, &u4BufLen); + kalMemZero(g_aucProcBuf, sizeof(g_aucProcBuf)); + SNPRINTF(temp, g_aucProcBuf, + ("MCR (0x%08xh): 0x%08x\n", rMcrInfo.u4McrOffset, + rMcrInfo.u4McrData)); + + u4Count = kalStrLen(g_aucProcBuf); + if (copy_to_user(buf, g_aucProcBuf, u4Count)) { + pr_err("copy to user failed\n"); + return -EFAULT; + } + + *f_pos += u4Count; + + return (int)u4Count; + +} /* end of procMCRRead() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief The PROC function for writing MCR register to HW or update u4McrOffset + * for reading MCR later. + * + * \param[in] file pointer to file. + * \param[in] buffer Buffer from user space. + * \param[in] count Number of characters to write + * \param[in] data Pointer to the private data structure. + * + * \return number of characters write from User Space. + */ +/*----------------------------------------------------------------------------*/ +static ssize_t procMCRWrite(struct file *file, const char __user *buffer, + size_t count, loff_t *data) +{ + struct GLUE_INFO *prGlueInfo; + /* + 1 for "\0" */ + char acBuf[PROC_MCR_ACCESS_MAX_USER_INPUT_LEN + 1]; + int i4CopySize; + struct PARAM_CUSTOM_MCR_RW_STRUCT rMcrInfo; + uint32_t u4BufLen; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + int num = 0; + + ASSERT(data); + + i4CopySize = + (count < (sizeof(acBuf) - 1)) ? count : (sizeof(acBuf) - 1); + if (copy_from_user(acBuf, buffer, i4CopySize) || + i4CopySize < 0 || + i4CopySize > PROC_MCR_ACCESS_MAX_USER_INPUT_LEN) + return 0; + acBuf[i4CopySize] = '\0'; + + num = + sscanf(acBuf, "0x%x 0x%x", &rMcrInfo.u4McrOffset, + &rMcrInfo.u4McrData); + switch (num) { + case 2: + /* NOTE: Sometimes we want to test if bus will still be ok, + * after accessing the MCR which is not align to DW boundary. + */ + /* if (IS_ALIGN_4(rMcrInfo.u4McrOffset)) */ + { + prGlueInfo = g_prGlueInfo_proc; + + u4McrOffset = rMcrInfo.u4McrOffset; + + /* printk("Write 0x%lx to MCR 0x%04lx\n", */ + /* rMcrInfo.u4McrOffset, rMcrInfo.u4McrData); */ + + rStatus = kalIoctl(prGlueInfo, + wlanoidSetMcrWrite, + (void *)&rMcrInfo, sizeof(rMcrInfo), + FALSE, FALSE, TRUE, &u4BufLen); + + } + break; + case 1: + /* if (IS_ALIGN_4(rMcrInfo.u4McrOffset)) */ + { + u4McrOffset = rMcrInfo.u4McrOffset; + } + break; + + default: + break; + } + + return count; + +} /* end of procMCRWrite() */ + +static const struct file_operations mcr_ops = { + .owner = THIS_MODULE, + .read = procMCRRead, + .write = procMCRWrite, +}; + +#if CFG_SUPPORT_SET_CAM_BY_PROC +static ssize_t procSetCamCfgWrite(struct file *file, const char __user *buffer, + size_t count, loff_t *data) +{ +#define MODULE_NAME_LEN_1 5 + + uint32_t u4CopySize = sizeof(g_aucProcBuf); + uint8_t *temp = &g_aucProcBuf[0]; + u_int8_t fgSetCamCfg = FALSE; + uint8_t aucModule[MODULE_NAME_LEN_1]; + uint32_t u4Enabled; + uint8_t aucModuleArray[MODULE_NAME_LEN_1] = "CAM"; + u_int8_t fgParamValue = TRUE; + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + + kalMemSet(g_aucProcBuf, 0, u4CopySize); + u4CopySize = (count < u4CopySize) ? count : (u4CopySize - 1); + + if (copy_from_user(g_aucProcBuf, buffer, u4CopySize)) { + pr_err("error of copy from user\n"); + return -EFAULT; + } + g_aucProcBuf[u4CopySize] = '\0'; + temp = &g_aucProcBuf[0]; + while (temp) { + kalMemSet(aucModule, 0, MODULE_NAME_LEN_1); + + /* pick up a string and teminated after meet : */ + if (sscanf(temp, "%4s %d", aucModule, &u4Enabled) != 2) { + pr_info("read param fail, aucModule=%s\n", aucModule); + fgParamValue = FALSE; + break; + } + + if (kalStrnCmp + (aucModule, aucModuleArray, MODULE_NAME_LEN_1) == 0) { + if (u4Enabled) + fgSetCamCfg = TRUE; + else + fgSetCamCfg = FALSE; + } + temp = kalStrChr(temp, ','); + if (!temp) + break; + temp++; /* skip ',' */ + } + + if (fgParamValue) { + uint8_t i; + + prGlueInfo = wlanGetGlueInfo(); + if (!prGlueInfo) + return count; + + prAdapter = prGlueInfo->prAdapter; + if (!prAdapter) + return count; + + for (i = 0; i < KAL_AIS_NUM; i++) { + nicConfigProcSetCamCfgWrite(prAdapter, + fgSetCamCfg, + i); + } + } + + return count; +} + +static const struct file_operations proc_set_cam_ops = { + .owner = THIS_MODULE, + .write = procSetCamCfgWrite, +}; +#endif /*CFG_SUPPORT_SET_CAM_BY_PROC */ + +static ssize_t procPktDelayDbgCfgRead(struct file *filp, char __user *buf, + size_t count, loff_t *f_pos) +{ + uint8_t *temp = &g_aucProcBuf[0]; + uint8_t *str = NULL; + uint32_t u4CopySize = 0; + uint8_t ucTxRxFlag = 0; + uint8_t ucTxIpProto = 0; + uint16_t u2TxUdpPort = 0; + uint32_t u4TxDelayThreshold = 0; + uint8_t ucRxIpProto = 0; + uint16_t u2RxUdpPort = 0; + uint32_t u4RxDelayThreshold = 0; + uint32_t u4StrLen = 0; + + /* if *f_ops>0, we should return 0 to make cat command exit */ + if (*f_pos > 0 || buf == NULL) + return 0; + + str = "\nUsage: txLog/rxLog/reset 1(ICMP)/6(TCP)/11(UDP) Dst/SrcPortNum DelayThreshold(us)\n" + "Print tx delay log, such as: echo txLog 0 0 0 > pktDelay\n" + "Print tx UDP delay log, such as: echo txLog 11 0 0 > pktDelay\n" + "Print tx UDP dst port19305 delay log, such as: echo txLog 11 19305 0 > pktDelay\n" + "Print rx UDP src port19305 delay more than 500us log, such as: echo rxLog 11 19305 500 > pktDelay\n" + "Print tx TCP delay more than 500us log, such as: echo txLog 6 0 500 > pktDelay\n" + "Close log, such as: echo reset 0 0 0 > pktDelay\n\n"; + u4StrLen = kalStrLen(str); + kalStrnCpy(temp, str, u4StrLen); + temp += u4StrLen; + +#if (CFG_SUPPORT_STATISTICS == 1) + StatsEnvGetPktDelay(&ucTxRxFlag, &ucTxIpProto, &u2TxUdpPort, + &u4TxDelayThreshold, &ucRxIpProto, &u2RxUdpPort, + &u4RxDelayThreshold); +#endif + + if (ucTxRxFlag & BIT(0)) { + SNPRINTF(temp, g_aucProcBuf, + ("txLog %x %d %d\n", ucTxIpProto, u2TxUdpPort, + u4TxDelayThreshold)); + } + if (ucTxRxFlag & BIT(1)) { + SNPRINTF(temp, g_aucProcBuf, + ("rxLog %x %d %d\n", ucRxIpProto, u2RxUdpPort, + u4RxDelayThreshold)); + } + if (ucTxRxFlag == 0) + SNPRINTF(temp, g_aucProcBuf, + ("reset 0 0 0, there is no tx/rx delay log\n")); + + u4CopySize = kalStrLen(g_aucProcBuf); + if (u4CopySize > count) + u4CopySize = count; + if (copy_to_user(buf, g_aucProcBuf, u4CopySize)) { + pr_err("copy to user failed\n"); + return -EFAULT; + } + + *f_pos += u4CopySize; + return (ssize_t) u4CopySize; +} + +static ssize_t procPktDelayDbgCfgWrite(struct file *file, const char *buffer, + size_t count, loff_t *data) +{ +#define MODULE_NAME_LENGTH 7 +#define MODULE_RESET 0 +#define MODULE_TX 1 +#define MODULE_RX 2 + + uint32_t u4CopySize = sizeof(g_aucProcBuf); + uint8_t *temp = &g_aucProcBuf[0]; + uint8_t aucModule[MODULE_NAME_LENGTH]; + uint32_t u4DelayThreshold = 0; + uint32_t u4PortNum = 0; + uint32_t u4IpProto = 0; + uint8_t aucResetArray[MODULE_NAME_LENGTH] = "reset"; + uint8_t aucTxArray[MODULE_NAME_LENGTH] = "txLog"; + uint8_t aucRxArray[MODULE_NAME_LENGTH] = "rxLog"; + uint8_t ucTxOrRx = 0; + + kalMemSet(g_aucProcBuf, 0, u4CopySize); + u4CopySize = (count < u4CopySize) ? count : (u4CopySize - 1); + + if (copy_from_user(g_aucProcBuf, buffer, u4CopySize)) { + pr_err("error of copy from user\n"); + return -EFAULT; + } + g_aucProcBuf[u4CopySize] = '\0'; + + while (temp) { + kalMemSet(aucModule, 0, MODULE_NAME_LENGTH); + + /* pick up a string and teminated after meet : */ + if (sscanf + (temp, "%6s %x %d %d", aucModule, &u4IpProto, &u4PortNum, + &u4DelayThreshold) != 4) { + pr_info("read param fail, aucModule=%s\n", aucModule); + break; + } + + if (kalStrnCmp + (aucModule, aucResetArray, MODULE_NAME_LENGTH) == 0) { + ucTxOrRx = MODULE_RESET; + } else if (kalStrnCmp + (aucModule, aucTxArray, MODULE_NAME_LENGTH) == 0) { + ucTxOrRx = MODULE_TX; + } else if (kalStrnCmp + (aucModule, aucRxArray, MODULE_NAME_LENGTH) == 0) { + ucTxOrRx = MODULE_RX; + } else { + pr_info("input module error!\n"); + break; + } + + temp = kalStrChr(temp, ','); + if (!temp) + break; + temp++; /* skip ',' */ + } + +#if (CFG_SUPPORT_STATISTICS == 1) + StatsEnvSetPktDelay(ucTxOrRx, (uint8_t) u4IpProto, (uint16_t) u4PortNum, + u4DelayThreshold); +#endif + return count; +} + +static const struct file_operations proc_pkt_delay_dbg_ops = { + .owner = THIS_MODULE, + .read = procPktDelayDbgCfgRead, + .write = procPktDelayDbgCfgWrite, +}; + +#if CFG_SUPPORT_DEBUG_FS +static ssize_t procRoamRead(struct file *filp, char __user *buf, + size_t count, loff_t *f_pos) +{ + uint32_t u4CopySize; + uint32_t rStatus; + uint32_t u4BufLen; + + /* if *f_pos > 0, it means has read successed last time, + * don't try again + */ + if (*f_pos > 0 || buf == NULL) + return 0; + + rStatus = + kalIoctl(g_prGlueInfo_proc, wlanoidGetRoamParams, g_aucProcBuf, + sizeof(g_aucProcBuf), TRUE, FALSE, TRUE, &u4BufLen); + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, INFO, "failed to read roam params\n"); + return -EINVAL; + } + + u4CopySize = kalStrLen(g_aucProcBuf); + if (copy_to_user(buf, g_aucProcBuf, u4CopySize)) { + pr_err("copy to user failed\n"); + return -EFAULT; + } + *f_pos += u4CopySize; + + return (int32_t) u4CopySize; +} + +static ssize_t procRoamWrite(struct file *file, const char __user *buffer, + size_t count, loff_t *data) +{ + uint32_t rStatus; + uint32_t u4BufLen = 0; + uint32_t u4CopySize = sizeof(g_aucProcBuf); + + kalMemSet(g_aucProcBuf, 0, u4CopySize); + u4CopySize = (count < u4CopySize) ? count : (u4CopySize - 1); + + if (copy_from_user(g_aucProcBuf, buffer, u4CopySize)) { + pr_err("error of copy from user\n"); + return -EFAULT; + } + g_aucProcBuf[u4CopySize] = '\0'; + + if (kalStrnCmp(g_aucProcBuf, "force_roam", 10) == 0) + rStatus = + kalIoctl(g_prGlueInfo_proc, wlanoidSetForceRoam, NULL, 0, + FALSE, FALSE, TRUE, &u4BufLen); + else + rStatus = + kalIoctl(g_prGlueInfo_proc, wlanoidSetRoamParams, + g_aucProcBuf, kalStrLen(g_aucProcBuf), FALSE, + FALSE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, INFO, "failed to set roam params: %s\n", + g_aucProcBuf); + return -EINVAL; + } + return count; +} + +static const struct file_operations roam_ops = { + .owner = THIS_MODULE, + .read = procRoamRead, + .write = procRoamWrite, +}; +#endif + +static ssize_t procCountryRead(struct file *filp, char __user *buf, + size_t count, loff_t *f_pos) +{ + uint32_t u4CopySize; + uint32_t country = 0; + + /* if *f_pos > 0, it means has read successed last time */ + if (*f_pos > 0) + return 0; + + country = rlmDomainGetCountryCode(); + + kalMemZero(g_aucProcBuf, sizeof(g_aucProcBuf)); + if (country) + kalSnprintf(g_aucProcBuf, sizeof(g_aucProcBuf), + "Current Country Code: %d\n", country); + else + kalSnprintf(g_aucProcBuf, sizeof(g_aucProcBuf), + "Current Country Code: NULL\n"); + + u4CopySize = kalStrLen(g_aucProcBuf); + if (copy_to_user(buf, g_aucProcBuf, u4CopySize)) { + pr_err("copy to user failed\n"); + return -EFAULT; + } + *f_pos += u4CopySize; + + return (int32_t) u4CopySize; +} + +static ssize_t procCountryWrite(struct file *file, const char __user *buffer, + size_t count, loff_t *data) +{ + uint32_t u4BufLen = 0; + uint32_t rStatus; + uint32_t u4CopySize = sizeof(g_aucProcBuf); + + kalMemSet(g_aucProcBuf, 0, u4CopySize); + u4CopySize = (count < u4CopySize) ? count : (u4CopySize - 1); + + if (copy_from_user(g_aucProcBuf, buffer, u4CopySize)) { + pr_err("error of copy from user\n"); + return -EFAULT; + } + g_aucProcBuf[u4CopySize] = '\0'; + + rStatus = kalIoctl(g_prGlueInfo_proc, wlanoidSetCountryCode, + &g_aucProcBuf[0], 2, FALSE, FALSE, TRUE, &u4BufLen); + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, INFO, "failed set country code: %s\n", + g_aucProcBuf); + return -EINVAL; + } + return count; +} + +static const struct file_operations country_ops = { + .owner = THIS_MODULE, + .read = procCountryRead, + .write = procCountryWrite, +}; + +static ssize_t procAutoPerfCfgRead(struct file *filp, char __user *buf, + size_t count, loff_t *f_pos) +{ + uint8_t *temp = &g_aucProcBuf[0]; + uint8_t *str = NULL; + uint32_t u4CopySize = 0; + uint32_t u4StrLen = 0; + + /* if *f_ops>0, we should return 0 to make cat command exit */ + if (*f_pos > 0) + return 0; + + str = "Auto Performance Configure Usage:\n" + "\n" + "echo ForceEnable:0 or 1 > /proc/net/wlan/autoPerfCfg\n" + " 1: always enable performance monitor\n" + " 0: restore performance monitor's default strategy\n"; + u4StrLen = kalStrLen(str); + kalStrnCpy(temp, str, u4StrLen + 1); + + u4CopySize = kalStrLen(g_aucProcBuf); + if (u4CopySize > count) + u4CopySize = count; + + if (copy_to_user(buf, g_aucProcBuf, u4CopySize)) { + DBGLOG(INIT, WARN, "copy_to_user error\n"); + return -EFAULT; + } + + *f_pos += u4CopySize; + return (ssize_t) u4CopySize; +} + +static ssize_t procAutoPerfCfgWrite(struct file *file, const char *buffer, + size_t count, loff_t *data) +{ + uint32_t u4CoreNum = 0; + uint32_t u4CoreFreq = 0; + uint8_t *temp = &g_aucProcBuf[0]; + uint32_t u4CopySize = count; + uint8_t i = 0; + uint32_t u4ForceEnable = 0; + uint8_t aucBuf[32]; + + if (u4CopySize >= sizeof(g_aucProcBuf)) + u4CopySize = sizeof(g_aucProcBuf) - 1; + + kalMemSet(g_aucProcBuf, 0, u4CopySize); + + if (copy_from_user(g_aucProcBuf, buffer, u4CopySize)) { + DBGLOG(INIT, WARN, "copy_from_user error\n"); + return -EFAULT; + } + + g_aucProcBuf[u4CopySize] = '\0'; + + i = sscanf(temp, "%d:%d", &u4CoreNum, &u4CoreFreq); + if (i == 2) { + DBGLOG(INIT, INFO, "u4CoreNum:%d, u4CoreFreq:%d\n", u4CoreNum, + u4CoreFreq); + kalSetCpuNumFreq(u4CoreNum, u4CoreFreq); + return u4CopySize; + } + + if (strlen(temp) > sizeof(aucBuf)) { + DBGLOG(INIT, WARN, + "input string(%s) len is too long, over %d\n", + g_aucProcBuf, (uint32_t) sizeof(aucBuf)); + return -EFAULT; + } + + i = sscanf(temp, "%11s:%d", aucBuf, &u4ForceEnable); + + if ((i == 2) && strstr(aucBuf, "ForceEnable")) { + kalPerMonSetForceEnableFlag(u4ForceEnable); + return u4CopySize; + } + + DBGLOG(INIT, WARN, "parameter format should be ForceEnable:0 or 1\n"); + + return -EFAULT; +} + +static const struct file_operations auto_perf_ops = { + .owner = THIS_MODULE, + .read = procAutoPerfCfgRead, + .write = procAutoPerfCfgWrite, +}; + +#if (CFG_TWT_SMART_STA == 1) +static ssize_t procTwtSmartRead(struct file *filp, char __user *buf, + size_t count, loff_t *f_pos) +{ + uint32_t u4CopySize; + + /* if *f_pos > 0, it means has read successed last time */ + if (*f_pos > 0) + return 0; + + kalMemZero(g_aucProcBuf, sizeof(g_aucProcBuf)); + + kalSnprintf(g_aucProcBuf, sizeof(g_aucProcBuf), + "Twt Smart Req:%d, TDReq:%d, Act:%d, State:%d\n", + g_TwtSmartStaCtrl.fgTwtSmartStaReq, + g_TwtSmartStaCtrl.fgTwtSmartStaTeardownReq, + g_TwtSmartStaCtrl.fgTwtSmartStaActivated, + g_TwtSmartStaCtrl.eState); + + u4CopySize = kalStrLen(g_aucProcBuf); + if (copy_to_user(buf, g_aucProcBuf, u4CopySize)) { + pr_err("copy to user failed\n"); + return -EFAULT; + } + *f_pos += u4CopySize; + + return (int32_t) u4CopySize; + +} + +static ssize_t procTwtSmartWrite(struct file *file, const char *buffer, + size_t count, loff_t *data) +{ + size_t len = count; + char buf[256]; + char *pBuf; + int32_t x = 0; + char *pToken = NULL; + char *pDelimiter = " \t"; + int32_t res; + + if (len >= sizeof(buf)) + len = sizeof(buf) - 1; + + if (copy_from_user(buf, buffer, len)) { + DBGLOG(INIT, WARN, "copy_from_user error\n"); + return -EFAULT; + } + + buf[len] = '\0'; + DBGLOG(INIT, INFO, "%s: write parameter data = %s", __func__, buf); + pBuf = buf; + pToken = strsep(&pBuf, pDelimiter); + + if (pToken != NULL) { + kalkStrtos32(pToken, 16, &res); + x = (int)res; + } else { + DBGLOG(INIT, ERROR, + "%s:%s input parameter fail![0]", __func__, buf); + return -1; + } + + switch (x) { + case 0: + break; + + case 1: + g_TwtSmartStaCtrl.fgTwtSmartStaReq = TRUE; + DBGLOG(INIT, INFO, + "twt landing stareq %d", + g_TwtSmartStaCtrl.fgTwtSmartStaReq); + break; + + case 2: + g_TwtSmartStaCtrl.u4TwtSwitch = 0; + if (g_TwtSmartStaCtrl.fgTwtSmartStaActivated == TRUE) + g_TwtSmartStaCtrl.fgTwtSmartStaTeardownReq = TRUE; + + g_TwtSmartStaCtrl.fgTwtSmartStaReq = FALSE; + g_TwtSmartStaCtrl.eState = TWT_SMART_STA_STATE_IDLE; + DBGLOG(INIT, INFO, + "twt landing tdreq %d", + g_TwtSmartStaCtrl.fgTwtSmartStaTeardownReq); + break; + } + + return len; + +} + +static const struct file_operations auto_twt_smart_ops = { + .owner = THIS_MODULE, + .read = procTwtSmartRead, + .write = procTwtSmartWrite, +}; + +#endif + +#if (CFG_SUPPORT_PRE_ON_PHY_ACTION == 1) +static ssize_t procCalResultRead(struct file *filp, char __user *buf, + size_t count, loff_t *f_pos) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + struct mt66xx_chip_info *prChipInfo = NULL; + uint32_t u4CalSize = 0; + uint8_t *prCalResult = NULL; + + /* if *f_pos > 0, it means has read successed last time */ + if (*f_pos > 0) + return 0; + + prGlueInfo = wlanGetGlueInfo(); + if (!prGlueInfo) + return 0; + + prAdapter = prGlueInfo->prAdapter; + if (!prAdapter) + return 0; + + prChipInfo = prAdapter->chip_info; + if (!prChipInfo) + return 0; + + if (prChipInfo->getCalResult) + prCalResult = prChipInfo->getCalResult(&u4CalSize); + else + return 0; + + if ((prCalResult == NULL) || (u4CalSize == 0)) { + DBGLOG(INIT, WARN, "prCalResult NULL\n"); + return 0; + } + + if (copy_to_user(buf, prCalResult, u4CalSize)) { + pr_err("copy to user failed\n"); + return -EFAULT; + } + + *f_pos += u4CalSize; + + return (int32_t)u4CalSize; +} + +static ssize_t procCalResultWrite(struct file *file, const char __user *buffer, + size_t count, loff_t *data) +{ + uint32_t u4CopySize = sizeof(g_aucProcBuf); + + kalMemSet(g_aucProcBuf, 0, u4CopySize); + u4CopySize = (count < u4CopySize) ? count : (u4CopySize - 1); + + if (copy_from_user(g_aucProcBuf, buffer, u4CopySize)) { + pr_err("error of copy from user\n"); + return -EFAULT; + } + + g_aucProcBuf[u4CopySize] = '\0'; + + return count; +} + +static const struct file_operations cal_result_ops = { + .owner = THIS_MODULE, + .read = procCalResultRead, + .write = procCalResultWrite, +}; +#endif /*(CFG_SUPPORT_PRE_ON_PHY_ACTION == 1)*/ + +int32_t procInitFs(void) +{ + struct proc_dir_entry *prEntry; + + g_i4NextDriverReadLen = 0; + + if (init_net.proc_net == (struct proc_dir_entry *)NULL) { + pr_err("init proc fs fail: proc_net == NULL\n"); + return -ENOENT; + } + + /* + * Directory: Root (/proc/net/wlan0) + */ + + gprProcRoot = proc_mkdir(PROC_ROOT_NAME, init_net.proc_net); + if (!gprProcRoot) { + pr_err("gprProcRoot == NULL\n"); + return -ENOENT; + } + proc_set_user(gprProcRoot, KUIDT_INIT(PROC_UID_SHELL), + KGIDT_INIT(PROC_GID_WIFI)); + + prEntry = + proc_create(PROC_DBG_LEVEL_NAME, 0664, gprProcRoot, &dbglevel_ops); + if (prEntry == NULL) { + pr_err("Unable to create /proc entry dbgLevel\n\r"); + return -1; + } + proc_set_user(prEntry, KUIDT_INIT(PROC_UID_SHELL), + KGIDT_INIT(PROC_GID_WIFI)); + + prEntry = + proc_create(PROC_AUTO_PERF_CFG, 0664, gprProcRoot, &auto_perf_ops); + if (prEntry == NULL) { + DBGLOG(INIT, ERROR, "Unable to create /proc entry %s/n", + PROC_AUTO_PERF_CFG); + return -1; + } + proc_set_user(prEntry, KUIDT_INIT(PROC_UID_SHELL), + KGIDT_INIT(PROC_GID_WIFI)); + +#if (CFG_TWT_SMART_STA == 1) + prEntry = + proc_create(PROC_TWT_SMART, 0664, gprProcRoot, &auto_twt_smart_ops); + if (prEntry == NULL) { + DBGLOG(INIT, ERROR, "Unable to create /twt smart entry %s/n", + PROC_TWT_SMART); + return -1; + } + proc_set_user(prEntry, KUIDT_INIT(PROC_UID_SHELL), + KGIDT_INIT(PROC_GID_WIFI)); + + + g_TwtSmartStaCtrl.fgTwtSmartStaActivated = FALSE; + g_TwtSmartStaCtrl.fgTwtSmartStaReq = FALSE; + g_TwtSmartStaCtrl.fgTwtSmartStaTeardownReq = FALSE; + g_TwtSmartStaCtrl.ucBssIndex = 0; + g_TwtSmartStaCtrl.ucFlowId = 0; + g_TwtSmartStaCtrl.u4CurTp = 0; + g_TwtSmartStaCtrl.u4LastTp = 0; + g_TwtSmartStaCtrl.u4TwtSwitch == 0; + g_TwtSmartStaCtrl.eState = TWT_SMART_STA_STATE_IDLE; +#endif + +#if (CFG_SUPPORT_PRE_ON_PHY_ACTION == 1) + prEntry = proc_create(PROC_CAL_RESULT, + 0664, + gprProcRoot, + &cal_result_ops); + if (prEntry == NULL) { + DBGLOG(INIT, ERROR, "Unable to create /proc entry %s/n", + PROC_CAL_RESULT); + return -1; + } + proc_set_user(prEntry, KUIDT_INIT(PROC_UID_SHELL), + KGIDT_INIT(PROC_GID_WIFI)); +#endif /*(CFG_SUPPORT_PRE_ON_PHY_ACTION == 1)*/ + + return 0; +} /* end of procInitProcfs() */ + +int32_t procUninitProcFs(void) +{ +#if KERNEL_VERSION(3, 9, 0) <= LINUX_VERSION_CODE + +#if (CFG_TWT_SMART_STA == 1) + remove_proc_subtree(PROC_TWT_SMART, gprProcRoot); + + g_TwtSmartStaCtrl.fgTwtSmartStaActivated = FALSE; + g_TwtSmartStaCtrl.fgTwtSmartStaReq = FALSE; + g_TwtSmartStaCtrl.fgTwtSmartStaTeardownReq = FALSE; + g_TwtSmartStaCtrl.ucBssIndex = 0; + g_TwtSmartStaCtrl.ucFlowId = 0; + g_TwtSmartStaCtrl.u4CurTp = 0; + g_TwtSmartStaCtrl.u4LastTp = 0; + g_TwtSmartStaCtrl.u4TwtSwitch == 0; + g_TwtSmartStaCtrl.eState = TWT_SMART_STA_STATE_IDLE; +#endif + +#if (CFG_SUPPORT_PRE_ON_PHY_ACTION == 1) + remove_proc_subtree(PROC_CAL_RESULT, gprProcRoot); +#endif /*(CFG_SUPPORT_PRE_ON_PHY_ACTION == 1)*/ + + remove_proc_subtree(PROC_AUTO_PERF_CFG, gprProcRoot); + remove_proc_subtree(PROC_DBG_LEVEL_NAME, gprProcRoot); + + /* + * move PROC_ROOT_NAME to last since it's root directory of the others + * incorrect sequence would cause use-after-free error + */ + remove_proc_subtree(PROC_ROOT_NAME, init_net.proc_net); +#else + +#if (CFG_SUPPORT_PRE_ON_PHY_ACTION == 1) + remove_proc_entry(PROC_CAL_RESULT, gprProcRoot); +#endif /*(CFG_SUPPORT_PRE_ON_PHY_ACTION == 1)*/ + + remove_proc_entry(PROC_AUTO_PERF_CFG, gprProcRoot); + remove_proc_entry(PROC_DBG_LEVEL_NAME, gprProcRoot); + + /* + * move PROC_ROOT_NAME to last since it's root directory of the others + * incorrect sequence would cause use-after-free error + */ + remove_proc_entry(PROC_ROOT_NAME, init_net.proc_net); +#endif + + return 0; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function clean up a PROC fs created by procInitProcfs(). + * + * \param[in] prDev Pointer to the struct net_device. + * \param[in] pucDevName Pointer to the name of net_device. + * + * \return N/A + */ +/*----------------------------------------------------------------------------*/ +int32_t procRemoveProcfs(void) +{ + remove_proc_entry(PROC_MCR_ACCESS, gprProcRoot); + remove_proc_entry(PROC_DRIVER_CMD, gprProcRoot); + remove_proc_entry(PROC_CFG, gprProcRoot); + remove_proc_entry(PROC_EFUSE_DUMP, gprProcRoot); + remove_proc_entry(PROC_PKT_DELAY_DBG, gprProcRoot); +#if CFG_SUPPORT_SET_CAM_BY_PROC + remove_proc_entry(PROC_SET_CAM, gprProcRoot); +#endif +#if CFG_SUPPORT_DEBUG_FS + remove_proc_entry(PROC_ROAM_PARAM, gprProcRoot); +#endif + remove_proc_entry(PROC_COUNTRY, gprProcRoot); + return 0; +} /* end of procRemoveProcfs() */ + +int32_t procCreateFsEntry(struct GLUE_INFO *prGlueInfo) +{ + struct proc_dir_entry *prEntry; + + DBGLOG(INIT, TRACE, "[%s]\n", __func__); + g_prGlueInfo_proc = prGlueInfo; + + prEntry = proc_create(PROC_MCR_ACCESS, 0664, gprProcRoot, &mcr_ops); + if (prEntry == NULL) { + DBGLOG(INIT, ERROR, "Unable to create /proc entry mcr\n\r"); + return -1; + } + + prEntry = + proc_create(PROC_PKT_DELAY_DBG, 0664, gprProcRoot, + &proc_pkt_delay_dbg_ops); + if (prEntry == NULL) { + DBGLOG(INIT, ERROR, + "Unable to create /proc entry pktDelay\n\r"); + return -1; + } + proc_set_user(prEntry, KUIDT_INIT(PROC_UID_SHELL), + KGIDT_INIT(PROC_GID_WIFI)); + +#if CFG_SUPPORT_SET_CAM_BY_PROC + prEntry = + proc_create(PROC_SET_CAM, 0664, gprProcRoot, &proc_set_cam_ops); + if (prEntry == NULL) { + DBGLOG(INIT, ERROR, "Unable to create /proc entry SetCAM\n\r"); + return -1; + } + proc_set_user(prEntry, KUIDT_INIT(PROC_UID_SHELL), + KGIDT_INIT(PROC_GID_WIFI)); +#endif +#if CFG_SUPPORT_DEBUG_FS + prEntry = proc_create(PROC_ROAM_PARAM, 0664, gprProcRoot, &roam_ops); + if (prEntry == NULL) { + DBGLOG(INIT, ERROR, + "Unable to create /proc entry roam_param\n\r"); + return -1; + } +#endif + prEntry = proc_create(PROC_COUNTRY, 0664, gprProcRoot, &country_ops); + if (prEntry == NULL) { + DBGLOG(INIT, ERROR, "Unable to create /proc entry country\n\r"); + return -1; + } + +#if CFG_SUPPORT_EASY_DEBUG + + prEntry = + proc_create(PROC_DRIVER_CMD, 0664, gprProcRoot, &drivercmd_ops); + if (prEntry == NULL) { + pr_err("Unable to create /proc entry for driver command\n\r"); + return -1; + } + + prEntry = proc_create(PROC_CFG, 0664, gprProcRoot, &cfg_ops); + if (prEntry == NULL) { + pr_err("Unable to create /proc entry for driver cfg\n\r"); + return -1; + } + + prEntry = + proc_create(PROC_EFUSE_DUMP, 0664, gprProcRoot, &efusedump_ops); + if (prEntry == NULL) { + pr_err("Unable to create /proc entry efuse\n\r"); + return -1; + } +#endif + + return 0; +} + +#if 0 +/*----------------------------------------------------------------------------*/ +/*! + * \brief The PROC function for reading Driver Status to User Space. + * + * \param[in] page Buffer provided by kernel. + * \param[in out] start Start Address to read(3 methods). + * \param[in] off Offset. + * \param[in] count Allowable number to read. + * \param[out] eof End of File indication. + * \param[in] data Pointer to the private data structure. + * + * \return number of characters print to the buffer from User Space. + */ +/*----------------------------------------------------------------------------*/ +static int procDrvStatusRead(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + struct GLUE_INFO *prGlueInfo = ((struct net_device *)data)->priv; + char *p = page; + uint32_t u4Count; + + GLUE_SPIN_LOCK_DECLARATION(); + + ASSERT(data); + + /* Kevin: Apply PROC read method 1. */ + if (off != 0) + return 0; /* To indicate end of file. */ + + SNPRINTF(p, page, ("GLUE LAYER STATUS:")); + SNPRINTF(p, page, ("\n==================")); + + SNPRINTF(p, page, + ("\n* Number of Pending Frames: %ld\n", + prGlueInfo->u4TxPendingFrameNum)); + + GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); + + wlanoidQueryDrvStatusForLinuxProc(prGlueInfo->prAdapter, p, &u4Count); + + GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); + + u4Count += (uint32_t) (p - page); + + *eof = 1; + + return (int)u4Count; + +} /* end of procDrvStatusRead() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief The PROC function for reading Driver RX Statistic Counters + * to User Space. + * + * \param[in] page Buffer provided by kernel. + * \param[in out] start Start Address to read(3 methods). + * \param[in] off Offset. + * \param[in] count Allowable number to read. + * \param[out] eof End of File indication. + * \param[in] data Pointer to the private data structure. + * + * \return number of characters print to the buffer from User Space. + */ +/*----------------------------------------------------------------------------*/ +static int procRxStatisticsRead(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + struct GLUE_INFO *prGlueInfo = ((struct net_device *)data)->priv; + char *p = page; + uint32_t u4Count; + + GLUE_SPIN_LOCK_DECLARATION(); + + ASSERT(data); + + /* Kevin: Apply PROC read method 1. */ + if (off != 0) + return 0; /* To indicate end of file. */ + + SNPRINTF(p, page, ("RX STATISTICS (Write 1 to clear):")); + SNPRINTF(p, page, ("\n=================================\n")); + + GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); + + wlanoidQueryRxStatisticsForLinuxProc(prGlueInfo->prAdapter, p, + &u4Count); + + GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); + + u4Count += (uint32_t) (p - page); + + *eof = 1; + + return (int)u4Count; + +} /* end of procRxStatisticsRead() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief The PROC function for reset Driver RX Statistic Counters. + * + * \param[in] file pointer to file. + * \param[in] buffer Buffer from user space. + * \param[in] count Number of characters to write + * \param[in] data Pointer to the private data structure. + * + * \return number of characters write from User Space. + */ +/*----------------------------------------------------------------------------*/ +static int procRxStatisticsWrite(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + struct GLUE_INFO *prGlueInfo = ((struct net_device *)data)->priv; + /* + 1 for "\0" */ + char acBuf[PROC_RX_STATISTICS_MAX_USER_INPUT_LEN + 1]; + uint32_t u4CopySize; + uint32_t u4ClearCounter; + int32_t rv; + + GLUE_SPIN_LOCK_DECLARATION(); + + ASSERT(data); + + u4CopySize = + (count < (sizeof(acBuf) - 1)) ? count : (sizeof(acBuf) - 1); + copy_from_user(acBuf, buffer, u4CopySize); + acBuf[u4CopySize] = '\0'; + + rv = kstrtoint(acBuf, 0, &u4ClearCounter); + if (rv == 1) { + if (u4ClearCounter == 1) { + GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); + + wlanoidSetRxStatisticsForLinuxProc(prGlueInfo-> + prAdapter); + + GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); + } + } + + return count; + +} /* end of procRxStatisticsWrite() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief The PROC function for reading Driver TX Statistic Counters + * to User Space. + * + * \param[in] page Buffer provided by kernel. + * \param[in out] start Start Address to read(3 methods). + * \param[in] off Offset. + * \param[in] count Allowable number to read. + * \param[out] eof End of File indication. + * \param[in] data Pointer to the private data structure. + * + * \return number of characters print to the buffer from User Space. + */ +/*----------------------------------------------------------------------------*/ +static int procTxStatisticsRead(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + struct GLUE_INFO *prGlueInfo = ((struct net_device *)data)->priv; + char *p = page; + uint32_t u4Count; + + GLUE_SPIN_LOCK_DECLARATION(); + + ASSERT(data); + + /* Kevin: Apply PROC read method 1. */ + if (off != 0) + return 0; /* To indicate end of file. */ + + SNPRINTF(p, page, ("TX STATISTICS (Write 1 to clear):")); + SNPRINTF(p, page, ("\n=================================\n")); + + GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); + + wlanoidQueryTxStatisticsForLinuxProc(prGlueInfo->prAdapter, p, + &u4Count); + + GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); + + u4Count += (uint32_t) (p - page); + + *eof = 1; + + return (int)u4Count; + +} /* end of procTxStatisticsRead() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief The PROC function for reset Driver TX Statistic Counters. + * + * \param[in] file pointer to file. + * \param[in] buffer Buffer from user space. + * \param[in] count Number of characters to write + * \param[in] data Pointer to the private data structure. + * + * \return number of characters write from User Space. + */ +/*----------------------------------------------------------------------------*/ +static int procTxStatisticsWrite(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + struct GLUE_INFO *prGlueInfo = ((struct net_device *)data)->priv; + /* + 1 for "\0" */ + char acBuf[PROC_RX_STATISTICS_MAX_USER_INPUT_LEN + 1]; + uint32_t u4CopySize; + uint32_t u4ClearCounter; + int32_t rv; + + GLUE_SPIN_LOCK_DECLARATION(); + + ASSERT(data); + + u4CopySize = + (count < (sizeof(acBuf) - 1)) ? count : (sizeof(acBuf) - 1); + copy_from_user(acBuf, buffer, u4CopySize); + acBuf[u4CopySize] = '\0'; + + rv = kstrtoint(acBuf, 0, &u4ClearCounter); + if (rv == 1) { + if (u4ClearCounter == 1) { + GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); + + wlanoidSetTxStatisticsForLinuxProc(prGlueInfo-> + prAdapter); + + GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); + } + } + + return count; + +} /* end of procTxStatisticsWrite() */ +#endif + +#ifdef FW_CFG_SUPPORT +#define MAX_CFG_OUTPUT_BUF_LENGTH 1024 +static uint8_t aucCfgBuf[CMD_FORMAT_V1_LENGTH]; +static uint8_t aucCfgQueryKey[MAX_CMD_NAME_MAX_LENGTH]; +static uint8_t aucCfgOutputBuf[MAX_CFG_OUTPUT_BUF_LENGTH]; + +static ssize_t cfgRead(struct file *filp, char __user *buf, size_t count, + loff_t *f_pos) +{ + uint32_t rStatus = WLAN_STATUS_FAILURE; + uint8_t *temp = &aucCfgOutputBuf[0]; + uint32_t u4CopySize = 0; + + struct CMD_HEADER cmdV1Header; + struct CMD_FORMAT_V1 *pr_cmd_v1 = + (struct CMD_FORMAT_V1 *)cmdV1Header.buffer; + + /* if *f_pos > 0, we should return 0 to make cat command exit */ + if (*f_pos > 0 || gprGlueInfo == NULL) + return 0; + if (!kalStrLen(aucCfgQueryKey)) + return 0; + + kalMemSet(aucCfgOutputBuf, 0, MAX_CFG_OUTPUT_BUF_LENGTH); + + SNPRINTF(temp, aucCfgOutputBuf, + ("\nprocCfgRead() %s:\n", aucCfgQueryKey)); + + /* send to FW */ + cmdV1Header.cmdVersion = CMD_VER_1; + cmdV1Header.cmdType = CMD_TYPE_QUERY; + cmdV1Header.itemNum = 1; + cmdV1Header.cmdBufferLen = sizeof(struct CMD_FORMAT_V1); + kalMemSet(cmdV1Header.buffer, 0, MAX_CMD_BUFFER_LENGTH); + + pr_cmd_v1->itemStringLength = kalStrLen(aucCfgQueryKey); + + kalMemCopy(pr_cmd_v1->itemString, aucCfgQueryKey, + kalStrLen(aucCfgQueryKey)); + + rStatus = kalIoctl(gprGlueInfo, + wlanoidQueryCfgRead, + (void *)&cmdV1Header, + sizeof(cmdV1Header), TRUE, TRUE, TRUE, &u4CopySize); + if (rStatus == WLAN_STATUS_FAILURE) + DBGLOG(INIT, ERROR, + "kalIoctl wlanoidQueryCfgRead fail 0x%x\n", + rStatus); + + SNPRINTF(temp, aucCfgOutputBuf, + ("%s\n", cmdV1Header.buffer)); + + u4CopySize = kalStrLen(aucCfgOutputBuf); + if (u4CopySize > count) + u4CopySize = count; + + if (copy_to_user(buf, aucCfgOutputBuf, u4CopySize)) + DBGLOG(INIT, ERROR, "copy to user failed\n"); + + *f_pos += u4CopySize; + return (ssize_t) u4CopySize; +} + +static ssize_t cfgWrite(struct file *filp, const char __user *buf, + size_t count, loff_t *f_pos) +{ + /* echo xxx xxx > /proc/net/wlan/cfg */ + uint8_t i = 0; + uint32_t u4CopySize = sizeof(aucCfgBuf); + uint8_t token_num = 1; + + kalMemSet(aucCfgBuf, 0, u4CopySize); + u4CopySize = (count < u4CopySize) ? count : (u4CopySize - 1); + + if (copy_from_user(aucCfgBuf, buf, u4CopySize)) { + DBGLOG(INIT, ERROR, "copy from user failed\n"); + return -EFAULT; + } + aucCfgBuf[u4CopySize] = '\0'; + for (; i < u4CopySize; i++) { + if (aucCfgBuf[i] == ' ') { + token_num++; + break; + } + } + + if (token_num == 1) { + kalMemSet(aucCfgQueryKey, 0, sizeof(aucCfgQueryKey)); + /* remove the 0x0a */ + memcpy(aucCfgQueryKey, aucCfgBuf, u4CopySize); + if (aucCfgQueryKey[u4CopySize - 1] == 0x0a) + aucCfgQueryKey[u4CopySize - 1] = '\0'; + } else { + if (u4CopySize) + wlanFwCfgParse(gprGlueInfo->prAdapter, aucCfgBuf); + } + + return count; +} + +static const struct file_operations fwcfg_ops = { + .owner = THIS_MODULE, + .read = cfgRead, + .write = cfgWrite, +}; + +int32_t cfgRemoveProcEntry(void) +{ + remove_proc_entry(PROC_CFG_NAME, gprProcRoot); + return 0; +} + +int32_t cfgCreateProcEntry(struct GLUE_INFO *prGlueInfo) +{ + struct proc_dir_entry *prEntry; + + prGlueInfo->pProcRoot = gprProcRoot; + gprGlueInfo = prGlueInfo; + + prEntry = proc_create(PROC_CFG_NAME, 0664, gprProcRoot, &fwcfg_ops); + if (prEntry == NULL) { + DBGLOG(INIT, ERROR, "Unable to create /proc entry cfg\n\r"); + return -1; + } + proc_set_user(prEntry, KUIDT_INIT(PROC_UID_SHELL), + KGIDT_INIT(PROC_GID_WIFI)); + + return 0; +} +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_qa_agent.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_qa_agent.c new file mode 100644 index 0000000000000000000000000000000000000000..e6333dab76e1df1bc88ef2ddc63393d2d8230287 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_qa_agent.c @@ -0,0 +1,9660 @@ +/******************************************************************************* + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ +/* + Module Name: + gl_ate_agent.c +*/ +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +#include "precomp.h" +#if (CFG_SUPPORT_QA_TOOL == 1) +#include "gl_wext.h" +#include "gl_cfg80211.h" +#include "gl_ate_agent.h" +#include "gl_qa_agent.h" +#include "gl_hook_api.h" +#if KERNEL_VERSION(3, 8, 0) <= CFG80211_VERSION_CODE +#include +#endif +#if (CONFIG_WLAN_SERVICE == 1) +#include "agent.h" +#endif + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +struct PARAM_RX_STAT g_HqaRxStat; +uint32_t u4RxStatSeqNum; +u_int8_t g_DBDCEnable = FALSE; +/* For SA Buffer Mode Temp Solution */ +u_int8_t g_BufferDownload = FALSE; +uint32_t u4EepromMode = 4; +uint32_t g_u4Chip_ID; + +static struct hqa_rx_stat_band_format g_backup_band0_info; +static struct hqa_rx_stat_band_format g_backup_band1_info; + +#if CFG_SUPPORT_BUFFER_MODE +uint8_t uacEEPROMImage[MAX_EEPROM_BUFFER_SIZE] = { + /* 0x000 ~ 0x00F */ + 0xAE, 0x86, 0x06, 0x00, 0x18, 0x0D, 0x00, 0x00, + 0xC0, 0x1F, 0xBD, 0x81, 0x3F, 0x01, 0x19, 0x00, + /* 0x010 ~ 0x01F */ + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, + /* 0x020 ~ 0x02F */ + 0x80, 0x02, 0x00, 0x00, 0x32, 0x66, 0xC3, 0x14, + 0x32, 0x66, 0xC3, 0x14, 0x03, 0x22, 0xFF, 0xFF, + /* 0x030 ~ 0x03F */ + 0x23, 0x04, 0x0D, 0xF2, 0x8F, 0x02, 0x00, 0x80, + 0x0A, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x040 ~ 0x04F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x33, 0x40, 0x00, 0x00, + /* 0x050 ~ 0x05F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x08, + /* 0x060 ~ 0x06F */ + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x08, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x08, + /* 0x070 ~ 0x07F */ + 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x080 ~ 0x08F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x090 ~ 0x09F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x0A0 ~ 0x0AF */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x0B0 ~ 0x0BF */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x92, 0x10, 0x10, 0x28, 0x00, 0x00, 0x00, 0x00, + /* 0x0C0 ~ 0x0CF */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x0D0 ~ 0x0DF */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x0E0 ~ 0x0EF */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x0F0 ~ 0x0FF */ + 0x0E, 0x05, 0x06, 0x06, 0x06, 0x0F, 0x00, 0x00, + 0x0E, 0x05, 0x06, 0x05, 0x05, 0x09, 0xFF, 0x00, + /* 0x100 ~ 0x10F */ + 0x12, 0x34, 0x56, 0x78, 0x2C, 0x2C, 0x28, 0x28, + 0x28, 0x26, 0x26, 0x28, 0x28, 0x28, 0x26, 0xFF, + /* 0x110 ~ 0x11F */ + 0x26, 0x25, 0x28, 0x21, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x27, 0x27, 0x27, 0x25, + /* 0x120 ~ 0x12F */ + 0x25, 0x25, 0x25, 0x25, 0x23, 0x23, 0x23, 0x21, + 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, + /* 0x130 ~ 0x13F */ + 0x40, 0x40, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, + 0xD0, 0xD0, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, + /* 0x140 ~ 0x14F */ + 0x25, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x150 ~ 0x15F */ + 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x40, 0x40, 0x40, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, + /* 0x160 ~ 0x16F */ + 0xD0, 0xD0, 0xD0, 0x25, 0x25, 0x25, 0x25, 0x25, + 0x25, 0x25, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x170 ~ 0x17F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xC2, 0xC4, 0xC5, 0xC8, + /* 0x180 ~ 0x18F */ + 0x00, 0x26, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x190 ~ 0x19F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x1A0 ~ 0x1AF */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0xD0, + 0xD0, 0x0E, 0x05, 0x06, 0x05, 0x09, 0x0E, 0x00, + /* 0x1B0 ~ 0x1BF */ + 0x05, 0x06, 0x05, 0x05, 0x09, 0x00, 0x00, 0x00, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + /* 0x1C0 ~ 0x1CF */ + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x00, 0x00, + /* 0x1D0 ~ 0x1DF */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x1E0 ~ 0x1EF */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x1F0 ~ 0x1FF */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x200 ~ 0x20F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x210 ~ 0x21F */ + 0x48, 0xF5, 0x27, 0x49, 0x48, 0xF5, 0x57, 0x12, + 0x4B, 0x71, 0x80, 0x50, 0x91, 0xF6, 0x87, 0x50, + /* 0x220 ~ 0x22F */ + 0x7D, 0x29, 0x09, 0x42, 0x7D, 0x29, 0x41, 0x44, + 0x7D, 0x29, 0x41, 0x3C, 0x7D, 0x29, 0x31, 0x4D, + /* 0x230 ~ 0x23F */ + 0x49, 0x71, 0x24, 0x49, 0x49, 0x71, 0x54, 0x12, + 0x4B, 0x71, 0x80, 0x50, 0x91, 0xF6, 0x87, 0x50, + /* 0x240 ~ 0x24F */ + 0x7D, 0x29, 0x09, 0x42, 0x7D, 0x29, 0x41, 0x04, + 0x7D, 0x29, 0x41, 0x04, 0x7D, 0x29, 0x01, 0x40, + /* 0x250 ~ 0x25F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x260 ~ 0x26F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x270 ~ 0x27F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x280 ~ 0x28F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x290 ~ 0x29F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x2A0 ~ 0x2AF */ + 0x7D, 0x29, 0xC9, 0x16, 0x7D, 0x29, 0xC9, 0x16, + 0x44, 0x22, 0x32, 0x15, 0xEE, 0xEE, 0xEE, 0x08, + /* 0x2B0 ~ 0x2BF */ + 0x78, 0x90, 0x79, 0x1C, 0x78, 0x90, 0x79, 0x1C, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x2C0 ~ 0x2CF */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x2D0 ~ 0x2DF */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x2E0 ~ 0x2EF */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x2F0 ~ 0x2FF */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x300 ~ 0x30F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x310 ~ 0x31F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x42, 0x10, 0x42, 0x08, 0x21, + /* 0x320 ~ 0x32F */ + 0x10, 0x42, 0x08, 0x21, 0x10, 0x42, 0x08, 0x21, + 0x10, 0x42, 0x08, 0x21, 0x10, 0x42, 0x08, 0x21, + /* 0x330 ~ 0x33F */ + 0x10, 0x42, 0x08, 0x21, 0x10, 0x42, 0x08, 0x21, + 0x10, 0x42, 0x08, 0x21, 0x10, 0x42, 0x08, 0x21, + /* 0x340 ~ 0x34F */ + 0x10, 0x42, 0x08, 0x21, 0x10, 0x42, 0x08, 0x21, + 0x10, 0x42, 0x08, 0x21, 0x10, 0x42, 0x08, 0x01, + /* 0x350 ~ 0x35F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x360 ~ 0x36F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x370 ~ 0x37F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x380 ~ 0x38F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x390 ~ 0x39F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x3A0 ~ 0x3AF */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x3B0 ~ 0x3BF */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x3C0 ~ 0x3CF */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x3D0 ~ 0x3DF */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x3E0 ~ 0x3EF */ + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + /* 0x3F0 ~ 0x3FF */ + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + /* 0x400 ~ 0x40F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x410 ~ 0x41F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x420 ~ 0x42F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x430 ~ 0x43F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x440 ~ 0x44F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x450 ~ 0x45F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x460 ~ 0x46F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x470 ~ 0x47F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x480 ~ 0x48F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x490 ~ 0x49F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x4A0 ~ 0x4AF */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For Response ACK to QA Tool DLL. + * + * \param[in] HqaCmdFrame Ethernet Frame Format respond to QA Tool DLL + * \param[in] prIwReqData + * \param[in] i4Length Length of Ethernet Frame data field + * \param[in] i4Status Status to respond + * \param[out] None + * + * \retval 0 On success. + * \retval -EFAULT If copy_to_user fail + */ +/*----------------------------------------------------------------------------*/ +static int32_t ResponseToQA(struct HQA_CMD_FRAME + *HqaCmdFrame, + IN union iwreq_data *prIwReqData, int32_t i4Length, + int32_t i4Status) +{ + if (!prIwReqData) + return -EINVAL; + + HqaCmdFrame->Length = ntohs((i4Length)); + i4Status = ntohs((i4Status)); + memcpy(HqaCmdFrame->Data, &i4Status, 2); + + prIwReqData->data.length = sizeof((HqaCmdFrame)->MagicNo) + + sizeof((HqaCmdFrame)->Type) + + sizeof((HqaCmdFrame)->Id) + + sizeof((HqaCmdFrame)->Length) + + sizeof((HqaCmdFrame)->Sequence) + + ntohs((HqaCmdFrame)->Length); + + if (prIwReqData->data.length == 0) + return -EFAULT; + + if (copy_to_user(prIwReqData->data.pointer, + (uint8_t *) (HqaCmdFrame), prIwReqData->data.length)) { + DBGLOG(RFTEST, INFO, "QA_AGENT copy_to_user() fail in %s\n", + __func__); + return -EFAULT; + } + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA command(0x%04x)[Magic number(0x%08x)] is done\n", + ntohs(HqaCmdFrame->Id), ntohl(HqaCmdFrame->MagicNo)); + + return 0; +} + +static int32_t ToDoFunction(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT ToDoFunction\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For Open Adapter (called when QA Tool UI Open). + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_OpenAdapter(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_OpenAdapter\n"); + + i4Ret = MT_ATEStart(prNetDev, "ATESTART"); + + /* For SA Buffer Mode Temp Solution */ + g_BufferDownload = FALSE; + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For Close Adapter (called when QA Tool UI Close). + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_CloseAdapter(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_CloseAdapter\n"); + + i4Ret = MT_ATEStop(prNetDev, "ATESTOP"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For Start TX. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_StartTx(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t TxCount; + uint16_t TxLength; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_StartTx\n"); + + memcpy((uint8_t *)&TxCount, HqaCmdFrame->Data + 4 * 0, 4); + TxCount = ntohl(TxCount); + memcpy((uint8_t *)&TxLength, HqaCmdFrame->Data + 4 * 1, 2); + TxLength = ntohs(TxLength); + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_StartTx TxCount = %d\n", + TxCount); + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_StartTx TxLength = %d\n", + TxLength); + + i4Ret = MT_ATESetTxCount(prNetDev, TxCount); + i4Ret = MT_ATESetTxLength(prNetDev, (uint32_t) TxLength); + i4Ret = MT_ATEStartTX(prNetDev, "TXFRAME"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +/* 1 todo not support yet */ +static int32_t HQA_StartTxExt(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_StartTxExt\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For Start Continuous TX. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +/* 1 todo not support yet */ +static int32_t HQA_StartTxContiTx(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_StartTxContiTx\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +/* 1 todo not support yets */ +static int32_t HQA_StartTxCarrier(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_StartTxCarrier\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For Start RX (Legacy function). + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_StartRx(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_StartRx\n"); + + MT_ATESetDBDCBandIndex(prNetDev, 0); + MT_ATEStartRX(prNetDev, "RXFRAME"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For Stop TX (Legacy function). + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_StopTx(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_StopTx\n"); + + MT_ATESetDBDCBandIndex(prNetDev, 0); + MT_ATEStopRX(prNetDev, "RXSTOP"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For Stop Continuous TX. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_StopContiTx(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_StopContiTx\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_StopTxCarrier(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_StopTxCarrier\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For Stop RX (Legacy function). + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_StopRx(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_StopRx\n"); + + MT_ATESetDBDCBandIndex(prNetDev, 0); + MT_ATEStopRX(prNetDev, "RXSTOP"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For Set TX Path. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_SetTxPath(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0, value = 0; + uint8_t band_idx = 0; + uint16_t tx_ant = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + uint32_t u4BufLen = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_SetTxPath\n"); + + if (HqaCmdFrame->Length > 2) { + memcpy(&value, HqaCmdFrame->Data + 4 * 0, 4); + tx_ant = ntohl(value); + memcpy(&value, HqaCmdFrame->Data + 4 * 1, 4); + band_idx = ntohl(value); + + if (band_idx && tx_ant > 0x3) + tx_ant >>= 2; + DBGLOG(RFTEST, INFO, "tx_path:%d, band:%d\n", tx_ant, band_idx); + } else { + memcpy(&tx_ant, HqaCmdFrame->Data + 2 * 0, 2); + tx_ant = ntohs(tx_ant); + DBGLOG(RFTEST, INFO, "tx_path:%d, ", tx_ant); + } + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_DBDC_BAND_IDX; + rRfATInfo.u4FuncData = band_idx; + + i4Ret = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Ret != WLAN_STATUS_SUCCESS) + return -EFAULT; + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_TX_PATH; + rRfATInfo.u4FuncData = tx_ant; + + i4Ret = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Ret != WLAN_STATUS_SUCCESS) + return -EFAULT; + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For Set RX Path. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_SetRxPath(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0, value = 0; + uint8_t band_idx = 0; + uint32_t rx_ant = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + uint32_t u4BufLen = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_SetRxPath\n"); + + if (HqaCmdFrame->Length > 2) { + memcpy(&value, HqaCmdFrame->Data + 4 * 0, 4); + rx_ant = ntohl(value); + memcpy(&value, HqaCmdFrame->Data + 4 * 1, 4); + band_idx = ntohl(value); + + if (band_idx && rx_ant > 0x3) + rx_ant >>= 2; + DBGLOG(RFTEST, INFO, "rx_path:%d, band:%d\n", rx_ant, band_idx); + } else { + memcpy(&rx_ant, HqaCmdFrame->Data + 2 * 0, 2); + rx_ant = ntohs(rx_ant); + DBGLOG(RFTEST, INFO, "rx_path:%d, ", rx_ant); + } + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_DBDC_BAND_IDX; + rRfATInfo.u4FuncData = band_idx; + + i4Ret = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Ret != WLAN_STATUS_SUCCESS) + return -EFAULT; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_RX_PATH; + rRfATInfo.u4FuncData = (uint32_t) ((rx_ant << 16) + || (0 & BITS(0, 15))); + + i4Ret = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Ret != WLAN_STATUS_SUCCESS) + return -EFAULT; + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For Set TX Inter-Packet Guard. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_SetTxIPG(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t u4Aifs = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_SetTxIPG\n"); + + memcpy(&u4Aifs, HqaCmdFrame->Data + 4 * 0, 4); + u4Aifs = ntohs(u4Aifs); + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_SetTxIPG u4Aifs : %d\n", + u4Aifs); + + MT_ATESetTxIPG(prNetDev, u4Aifs); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For Set TX Power0 (Legacy Function). + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_SetTxPower0(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_SetTxPower0\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For Set TX Power1. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HAQ_SetTxPower1(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HAQ_SetTxPower1\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_SetTxPowerExt(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t u4Power = 0; + uint32_t u4Channel = 0; + uint32_t u4Dbdc_idx = 0; + uint32_t u4Band_idx = 0; + uint32_t u4Ant_idx = 0; + + memcpy(&u4Power, HqaCmdFrame->Data + 4 * 0, 4); + u4Power = ntohl(u4Power); + memcpy(&u4Dbdc_idx, HqaCmdFrame->Data + 4 * 1, 4); + u4Dbdc_idx = ntohl(u4Dbdc_idx); + memcpy(&u4Channel, HqaCmdFrame->Data + 4 * 2, 4); + u4Channel = ntohl(u4Channel); + memcpy(&u4Band_idx, HqaCmdFrame->Data + 4 * 3, 4); + u4Band_idx = ntohl(u4Band_idx); + memcpy(&u4Ant_idx, HqaCmdFrame->Data + 4 * 4, 4); + u4Ant_idx = ntohl(u4Ant_idx); + + DBGLOG(RFTEST, INFO, + " QA_AGENT HQA_SetTxPowerExt u4Power : %u,u4Dbdc_idx:%u, u4Channel:%u,u4Band_idx:%u, u4Ant_idx:%u\n", + u4Power, u4Dbdc_idx, u4Channel, u4Band_idx, u4Ant_idx); + + MT_ATESetDBDCBandIndex(prNetDev, u4Dbdc_idx); + MT_ATESetTxPower0(prNetDev, u4Power); + /* u4Freq = nicChannelNum2Freq(u4Channel); */ + /* i4Ret = MT_ATESetChannel(prNetDev, 0, u4Freq); */ + /* MT_ATESetBand(prNetDev, u4Band_idx); */ + /* Antenna?? */ + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_SetOnOff(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_SetOnOff\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For Antenna Selection. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_AntennaSel(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_AntennaSel\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_FWPacketCMD_ClockSwitchDisable( + struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_FWPacketCMD_ClockSwitchDisable\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +static HQA_CMD_HANDLER HQA_CMD_SET0[] = { + /* cmd id start from 0x1000 */ + HQA_OpenAdapter, /* 0x1000 */ + HQA_CloseAdapter, /* 0x1001 */ + HQA_StartTx, /* 0x1002 */ + HQA_StartTxExt, /* 0x1003 */ + HQA_StartTxContiTx, /* 0x1004 */ + HQA_StartTxCarrier, /* 0x1005 */ + HQA_StartRx, /* 0x1006 */ + HQA_StopTx, /* 0x1007 */ + HQA_StopContiTx, /* 0x1008 */ + HQA_StopTxCarrier, /* 0x1009 */ + HQA_StopRx, /* 0x100A */ + HQA_SetTxPath, /* 0x100B */ + HQA_SetRxPath, /* 0x100C */ + HQA_SetTxIPG, /* 0x100D */ + HQA_SetTxPower0, /* 0x100E */ + HAQ_SetTxPower1, /* 0x100F */ + ToDoFunction, /* 0x1010 */ + HQA_SetTxPowerExt, /* 0x1011 */ + HQA_SetOnOff, /* 0x1012 */ + HQA_AntennaSel, /* 0x1013 */ + HQA_FWPacketCMD_ClockSwitchDisable, /* 0x1014 */ +}; + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For Set Channel Frequency (Legacy Function). + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_SetChannel(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + uint32_t i4SetFreq = 0, i4SetChan = 0; + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_SetChannel\n"); + + memcpy((uint8_t *)&i4SetChan, HqaCmdFrame->Data, 4); + i4SetChan = ntohl(i4SetChan); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_SetChannel Channel = %d\n", i4SetChan); + + i4SetFreq = nicChannelNum2Freq(i4SetChan); + i4Ret = MT_ATESetChannel(prNetDev, 0, i4SetFreq); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For Set Preamble (Legacy Function). + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_SetPreamble(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Mode = 0; + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_SetPreamble\n"); + + memcpy((uint8_t *)&i4Mode, HqaCmdFrame->Data, 4); + i4Mode = ntohl(i4Mode); + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_SetPreamble Mode = %d\n", + i4Mode); + + i4Ret = MT_ATESetPreamble(prNetDev, i4Mode); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For Set Rate (Legacy Function). + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_SetRate(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + /* INT_32 i4Value = 0; */ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_SetRate\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For Set Nss. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_SetNss(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_SetNss\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For Set System BW (Legacy Function). + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_SetSystemBW(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + uint32_t i4BW; + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_SetSystemBW\n"); + + memcpy((uint8_t *)&i4BW, HqaCmdFrame->Data, 4); + i4BW = ntohl(i4BW); + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_SetSystemBW BW = %d\n", + i4BW); + + i4Ret = MT_ATESetSystemBW(prNetDev, i4BW); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For Set Data BW (Legacy Function). + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_SetPerPktBW(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t u4Perpkt_bw; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_SetPerPktBW\n"); + + memcpy((uint8_t *)&u4Perpkt_bw, HqaCmdFrame->Data, 4); + u4Perpkt_bw = ntohl(u4Perpkt_bw); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_SetPerPktBW u4Perpkt_bw = %d\n", u4Perpkt_bw); + + i4Ret = MT_ATESetPerPacketBW(prNetDev, u4Perpkt_bw); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For Set Primary BW. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_SetPrimaryBW(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t u4Pri_sel = 0; + + memcpy(&u4Pri_sel, HqaCmdFrame->Data, 4); + u4Pri_sel = ntohl(u4Pri_sel); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_SetPrimaryBW u4Pri_sel : %d\n", u4Pri_sel); + + i4Ret = MT_ATEPrimarySetting(prNetDev, u4Pri_sel); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For Set Frequency Offset. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_SetFreqOffset(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t u4FreqOffset = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + uint32_t u4BufLen = 0; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + memcpy(&u4FreqOffset, HqaCmdFrame->Data, 4); + u4FreqOffset = ntohl(u4FreqOffset); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_SetFreqOffset u4FreqOffset : %d\n", + u4FreqOffset); + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_FRWQ_OFFSET; + rRfATInfo.u4FuncData = (uint32_t) u4FreqOffset; + + i4Ret = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Ret != WLAN_STATUS_SUCCESS) + return -EFAULT; + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_SetAutoResponder(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_SetAutoResponder\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_SetTssiOnOff(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_SetTssiOnOff\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +/* 1 todo not support yet */ + +static int32_t HQA_SetRxHighLowTemperatureCompensation( + struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_SetRxHighLowTemperatureCompensation\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_LowPower(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_LowPower\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +#if CFG_SUPPORT_ANT_SWAP +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For query ant swap capablity + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_GetAntSwapCapability(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t value = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct mt66xx_chip_info *prChipInfo = NULL; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + if (!prGlueInfo || !prGlueInfo->prAdapter) { + DBGLOG(RFTEST, ERROR, "prGlueInfo or prAdapter is NULL\n"); + return -EFAULT; + } + + prChipInfo = prGlueInfo->prAdapter->chip_info; + if (!prChipInfo) { + DBGLOG(RFTEST, ERROR, "prChipInfo is NULL\n"); + return -EFAULT; + } + + DBGLOG(RFTEST, INFO, "HQA_GetAntSwapCapability [%d]\n", + prGlueInfo->prAdapter->fgIsSupportAntSwp); + + DBGLOG(RFTEST, INFO, "ucMaxSwapAntenna = [%d]\n", + prChipInfo->ucMaxSwapAntenna); + + if (prGlueInfo->prAdapter->fgIsSupportAntSwp) + value = ntohl(prChipInfo->ucMaxSwapAntenna); + else + value = 0; + + memcpy(HqaCmdFrame->Data + 2, &value, sizeof(value)); + ResponseToQA(HqaCmdFrame, prIwReqData, 2 + sizeof(value), i4Ret); + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For setting antenna swap + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_SetAntSwap(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t u4Ant = 0, u4Band = 0; + + memcpy(&u4Band, HqaCmdFrame->Data, sizeof(uint32_t)); + memcpy(&u4Ant, HqaCmdFrame->Data + sizeof(uint32_t), sizeof(uint32_t)); + u4Ant = ntohl(u4Ant); + + DBGLOG(RFTEST, INFO, "Band = %d, Ant = %d\n", u4Band, u4Ant); + + i4Ret = MT_ATESetAntSwap(prNetDev, u4Ant); + if (i4Ret != WLAN_STATUS_SUCCESS) + return -EFAULT; + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + return i4Ret; + +} +#endif + + +static HQA_CMD_HANDLER HQA_CMD_SET1[] = { + /* cmd id start from 0x1100 */ + HQA_SetChannel, /* 0x1100 */ + HQA_SetPreamble, /* 0x1101 */ + HQA_SetRate, /* 0x1102 */ + HQA_SetNss, /* 0x1103 */ + HQA_SetSystemBW, /* 0x1104 */ + HQA_SetPerPktBW, /* 0x1105 */ + HQA_SetPrimaryBW, /* 0x1106 */ + HQA_SetFreqOffset, /* 0x1107 */ + HQA_SetAutoResponder, /* 0x1108 */ + HQA_SetTssiOnOff, /* 0x1109 */ + HQA_SetRxHighLowTemperatureCompensation, /* 0x110A */ + HQA_LowPower, /* 0x110B */ + NULL, /* 0x110C */ +#if CFG_SUPPORT_ANT_SWAP + HQA_GetAntSwapCapability, /* 0x110D */ + HQA_SetAntSwap, /* 0x110E */ +#endif +}; + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For Reset TRX Counter + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_ResetTxRxCounter(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + uint32_t i4Status; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_ResetTxRxCounter\n"); + + i4Status = MT_ATEResetTXRXCounter(prNetDev); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Status); + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_GetStatistics(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_GetStatistics\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_GetRxOKData(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_GetRxOKData\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_GetRxOKOther(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_GetRxOKOther\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_GetRxAllPktCount(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_GetRxAllPktCount\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_GetTxTransmitted(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_GetTxTransmitted\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_GetHwCounter(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_GetHwCounter\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_CalibrationOperation(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_CalibrationOperation\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_CalibrationBypassExt(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Status = 0; + uint32_t u4Item = 0; + uint32_t u4Band_idx = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + uint32_t u4BufLen = 0; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + memcpy(&u4Item, HqaCmdFrame->Data, 4); + u4Item = ntohl(u4Item); + memcpy(&u4Band_idx, HqaCmdFrame->Data + 4, 4); + u4Band_idx = ntohl(u4Band_idx); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_CalibrationBypassExt u4Item : 0x%08x\n", + u4Item); + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_CalibrationBypassExt u4Band_idx : %d\n", + u4Band_idx); + + MT_ATESetDBDCBandIndex(prNetDev, u4Band_idx); + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_BYPASS_CAL_STEP; + rRfATInfo.u4FuncData = u4Item; + + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Status); + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_SetRXVectorIdx(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t band_idx = 0; + uint32_t Group_1 = 0, Group_2 = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + uint32_t u4BufLen = 0; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + memcpy(&band_idx, HqaCmdFrame->Data + 4 * 0, 4); + band_idx = ntohl(band_idx); + memcpy(&Group_1, HqaCmdFrame->Data + 4 * 1, 4); + Group_1 = ntohl(Group_1); + memcpy(&Group_2, HqaCmdFrame->Data + 4 * 2, 4); + Group_2 = ntohl(Group_2); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_SetRXVectorIdx band_idx : %d\n", band_idx); + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_SetRXVectorIdx Group_1 : %d\n", Group_1); + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_SetRXVectorIdx Group_2 : %d\n", Group_2); + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_RXV_INDEX; + rRfATInfo.u4FuncData = (uint32_t) (Group_1); + rRfATInfo.u4FuncData |= (uint32_t) (Group_2 << 8); + rRfATInfo.u4FuncData |= (uint32_t) (band_idx << 16); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_SetRXVectorIdx rRfATInfo.u4FuncData : 0x%08x\n", + rRfATInfo.u4FuncData); + + i4Ret = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Ret != WLAN_STATUS_SUCCESS) + return -EFAULT; + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For Set FAGC Rssi Path + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_SetFAGCRssiPath(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t u4band_idx = 0; + uint32_t u4FAGC_Path = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + uint32_t u4BufLen = 0; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + memcpy(&u4band_idx, HqaCmdFrame->Data + 4 * 0, 4); + u4band_idx = ntohl(u4band_idx); + memcpy(&u4FAGC_Path, HqaCmdFrame->Data + 4 * 1, 4); + u4FAGC_Path = ntohl(u4FAGC_Path); + + DBGLOG(RFTEST, INFO, "u4band_idx : %d, u4FAGC_Path : %d\n", + u4band_idx, u4FAGC_Path); + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_FAGC_RSSI_PATH; + rRfATInfo.u4FuncData = (uint32_t) ((u4band_idx << 16) | + (u4FAGC_Path & BITS(0, 15))); + + i4Ret = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Ret != WLAN_STATUS_SUCCESS) + return -EFAULT; + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +static HQA_CMD_HANDLER HQA_CMD_SET2[] = { + /* cmd id start from 0x1200 */ + HQA_ResetTxRxCounter, /* 0x1200 */ + HQA_GetStatistics, /* 0x1201 */ + HQA_GetRxOKData, /* 0x1202 */ + HQA_GetRxOKOther, /* 0x1203 */ + HQA_GetRxAllPktCount, /* 0x1204 */ + HQA_GetTxTransmitted, /* 0x1205 */ + HQA_GetHwCounter, /* 0x1206 */ + HQA_CalibrationOperation, /* 0x1207 */ + HQA_CalibrationBypassExt, /* 0x1208 */ + HQA_SetRXVectorIdx, /* 0x1209 */ + HQA_SetFAGCRssiPath, /* 0x120A */ +}; + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For MAC CR Read. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_MacBbpRegRead(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + uint32_t u4Offset, u4Value; + int32_t i4Status; + uint32_t u4BufLen = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_CUSTOM_MCR_RW_STRUCT rMcrInfo; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_MacBbpRegRead\n"); + + memcpy(&u4Offset, HqaCmdFrame->Data, 4); + u4Offset = ntohl(u4Offset); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_MacBbpRegRead Offset = 0x%08x\n", u4Offset); + + rMcrInfo.u4McrOffset = u4Offset; + rMcrInfo.u4McrData = 0; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + i4Status = kalIoctl(prGlueInfo, wlanoidQueryMcrRead, + &rMcrInfo, sizeof(rMcrInfo), + TRUE, TRUE, TRUE, &u4BufLen); + + if (i4Status == 0) { + u4Value = rMcrInfo.u4McrData; + + DBGLOG(RFTEST, INFO, + "QA_AGENT Address = 0x%08x, Result = 0x%08x\n", u4Offset, + u4Value); + + u4Value = ntohl(u4Value); + memcpy(HqaCmdFrame->Data + 2, &u4Value, 4); + } + + ResponseToQA(HqaCmdFrame, prIwReqData, 6, i4Status); + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For MAC CR Write. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_MacBbpRegWrite(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + + /* INT_32 i4Ret = 0; */ + uint32_t u4Offset, u4Value; + int32_t i4Status = 0; + uint32_t u4BufLen = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_CUSTOM_MCR_RW_STRUCT rMcrInfo; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_MacBbpRegWrite\n"); + + memcpy(&u4Offset, HqaCmdFrame->Data, 4); + memcpy(&u4Value, HqaCmdFrame->Data + 4, 4); + + u4Offset = ntohl(u4Offset); + u4Value = ntohl(u4Value); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_MacBbpRegWrite Offset = 0x%08x\n", u4Offset); + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_MacBbpRegWrite Value = 0x%08x\n", u4Value); + + rMcrInfo.u4McrOffset = u4Offset; + rMcrInfo.u4McrData = u4Value; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + i4Status = kalIoctl(prGlueInfo, wlanoidSetMcrWrite, &rMcrInfo, + sizeof(rMcrInfo), FALSE, FALSE, TRUE, &u4BufLen); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Status); + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For Read Bulk MAC CR. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_MACBbpRegBulkRead(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + uint32_t u4Index, u4Offset, u4Value; + uint16_t u2Len; + int32_t i4Status = 0; + uint32_t u4BufLen = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_CUSTOM_MCR_RW_STRUCT rMcrInfo; + + memcpy(&u4Offset, HqaCmdFrame->Data, 4); + u4Offset = ntohl(u4Offset); + memcpy(&u2Len, HqaCmdFrame->Data + 4, 2); + u2Len = ntohs(u2Len); + + DBGLOG(RFTEST, INFO, "Offset = 0x%08x, Len = 0x%08x\n", + u4Offset, u2Len); + + for (u4Index = 0; u4Index < u2Len; u4Index++) { + rMcrInfo.u4McrOffset = u4Offset + u4Index * 4; + rMcrInfo.u4McrData = 0; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + i4Status = kalIoctl(prGlueInfo, wlanoidQueryMcrRead, + &rMcrInfo, sizeof(rMcrInfo), + TRUE, TRUE, TRUE, &u4BufLen); + + if (i4Status == 0) { + u4Value = rMcrInfo.u4McrData; + + DBGLOG(RFTEST, INFO, + "Address = 0x%08x, Result = 0x%08x\n", + u4Offset + u4Index * 4, u4Value); + + u4Value = ntohl(u4Value); + memcpy(HqaCmdFrame->Data + 2 + (u4Index * 4), &u4Value, + 4); + } + } + + ResponseToQA(HqaCmdFrame, prIwReqData, 2 + (u2Len * 4), + i4Status); + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For Read Bulk RF CR. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_RfRegBulkRead(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + uint32_t u4Index, u4WfSel, u4Offset, u4Length, u4Value; + int32_t i4Status = 0; + uint32_t u4BufLen = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_CUSTOM_MCR_RW_STRUCT rMcrInfo; + + memcpy(&u4WfSel, HqaCmdFrame->Data, 4); + u4WfSel = ntohl(u4WfSel); + memcpy(&u4Offset, HqaCmdFrame->Data + 4, 4); + u4Offset = ntohl(u4Offset); + memcpy(&u4Length, HqaCmdFrame->Data + 8, 4); + u4Length = ntohl(u4Length); + + DBGLOG(RFTEST, INFO, " WfSel = %u, Offset = 0x%08x, Length = %u\n", + u4WfSel, u4Offset, u4Length); + + if (u4WfSel == 0) + u4Offset = u4Offset | 0x99900000; + else if (u4WfSel == 1) + u4Offset = u4Offset | 0x99910000; + else if (u4WfSel == 15) + u4Offset = u4Offset | 0x999F0000; + + + for (u4Index = 0; u4Index < u4Length; u4Index++) { + rMcrInfo.u4McrOffset = u4Offset + u4Index * 4; + rMcrInfo.u4McrData = 0; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + i4Status = kalIoctl(prGlueInfo, wlanoidQueryMcrRead, + &rMcrInfo, sizeof(rMcrInfo), + TRUE, TRUE, TRUE, &u4BufLen); + + if (i4Status == 0) { + u4Value = rMcrInfo.u4McrData; + + DBGLOG(RFTEST, INFO, + "Address = 0x%08x, Result = 0x%08x\n", + u4Offset + u4Index * 4, u4Value); + + u4Value = ntohl(u4Value); + memcpy(HqaCmdFrame->Data + 2 + (u4Index * 4), &u4Value, + 4); + } + } + + ResponseToQA(HqaCmdFrame, prIwReqData, 2 + (u4Length * 4), + i4Status); + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For Write RF CR. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_RfRegBulkWrite(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + uint32_t u4WfSel, u4Offset, u4Length, u4Value; + int32_t i4Status; + uint32_t u4BufLen = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_CUSTOM_MCR_RW_STRUCT rMcrInfo; + + memcpy(&u4WfSel, HqaCmdFrame->Data, 4); + u4WfSel = ntohl(u4WfSel); + memcpy(&u4Offset, HqaCmdFrame->Data + 4, 4); + u4Offset = ntohl(u4Offset); + memcpy(&u4Length, HqaCmdFrame->Data + 8, 4); + u4Length = ntohl(u4Length); + memcpy(&u4Value, HqaCmdFrame->Data + 12, 4); + u4Value = ntohl(u4Value); + + DBGLOG(RFTEST, INFO, + "WfSel = %u, Offset = 0x%08x, Length = %u, Value = 0x%08x\n", + u4WfSel, u4Offset, u4Length, u4Value); + + if (u4WfSel == 0) + u4Offset = u4Offset | 0x99900000; + else if (u4WfSel == 1) + u4Offset = u4Offset | 0x99910000; + + + rMcrInfo.u4McrOffset = u4Offset; + rMcrInfo.u4McrData = u4Value; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + i4Status = kalIoctl(prGlueInfo, wlanoidSetMcrWrite, + &rMcrInfo, sizeof(rMcrInfo), + FALSE, FALSE, TRUE, &u4BufLen); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Status); + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_ReadEEPROM(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + + uint16_t Offset; + uint16_t Len; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + +#if (CFG_EEPROM_PAGE_ACCESS == 1) + uint32_t u4BufLen = 0; + uint8_t u4Index = 0; + uint16_t u4Value = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_CUSTOM_ACCESS_EFUSE rAccessEfuseInfo; +#endif + + DBGLOG(INIT, INFO, "QA_AGENT HQA_ReadEEPROM\n"); + + memcpy(&Offset, HqaCmdFrame->Data + 2 * 0, 2); + Offset = ntohs(Offset); + memcpy(&Len, HqaCmdFrame->Data + 2 * 1, 2); + Len = ntohs(Len); + +#if (CFG_EEPROM_PAGE_ACCESS == 1) + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + if (!prGlueInfo) { + log_dbg(RFTEST, ERROR, "prGlueInfo is NULL\n"); + ResponseToQA(HqaCmdFrame, prIwReqData, 2, rStatus); + return rStatus; + } + + if (prGlueInfo->prAdapter && + prGlueInfo->prAdapter->chip_info && + !prGlueInfo->prAdapter->chip_info->is_support_efuse) { + rStatus = WLAN_STATUS_NOT_SUPPORTED; + log_dbg(RFTEST, WARN, "Efuse not support\n"); + ResponseToQA(HqaCmdFrame, prIwReqData, 2, rStatus); + return rStatus; + } + + kalMemSet(&rAccessEfuseInfo, 0, + sizeof(struct PARAM_CUSTOM_ACCESS_EFUSE)); + + rAccessEfuseInfo.u4Address = + (Offset / EFUSE_BLOCK_SIZE) * EFUSE_BLOCK_SIZE; + + + rStatus = kalIoctl(prGlueInfo, + wlanoidQueryProcessAccessEfuseRead, + &rAccessEfuseInfo, + sizeof(struct PARAM_CUSTOM_ACCESS_EFUSE), + TRUE, TRUE, TRUE, &u4BufLen); + + u4Index = Offset % EFUSE_BLOCK_SIZE; + if (u4Index <= 14) + u4Value = + (prGlueInfo->prAdapter->aucEepromVaule[u4Index]) | + (prGlueInfo->prAdapter->aucEepromVaule[u4Index + 1] << 8); + + + /* isVaild = pResult->u4Valid; */ + + if (rStatus == WLAN_STATUS_SUCCESS) { + + DBGLOG(INIT, INFO, "QA_AGENT HQA_ReadEEPROM u4Value = %x\n", + u4Value); + + u4Value = ntohl(u4Value); + memcpy(HqaCmdFrame->Data + 2, &u4Value, sizeof(u4Value)); + } +#endif + + ResponseToQA(HqaCmdFrame, prIwReqData, 4, rStatus); + + return rStatus; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_WriteEEPROM(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + +#if (CFG_EEPROM_PAGE_ACCESS == 1) + uint16_t u4WriteData = 0; + uint32_t u4BufLen = 0; + uint8_t u4Index = 0; + uint16_t Offset; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_CUSTOM_ACCESS_EFUSE rAccessEfuseInfoWrite; + + memcpy(&Offset, HqaCmdFrame->Data + 2 * 0, 2); + Offset = ntohs(Offset); + memcpy(&u4WriteData, HqaCmdFrame->Data + 2 * 1, 2); + u4WriteData = ntohs(u4WriteData); + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); +#if 0 + /* Read */ + DBGLOG(INIT, INFO, "QA_AGENT HQA_ReadEEPROM\n"); + kalMemSet(&rAccessEfuseInfoRead, 0, + sizeof(struct PARAM_CUSTOM_ACCESS_EFUSE)); + rAccessEfuseInfoRead.u4Address = (Offset / EFUSE_BLOCK_SIZE) + * EFUSE_BLOCK_SIZE; + rStatus = kalIoctl(prGlueInfo, + wlanoidQueryProcessAccessEfuseRead, + &rAccessEfuseInfoRead, + sizeof(struct PARAM_CUSTOM_ACCESS_EFUSE), + FALSE, FALSE, TRUE, &u4BufLen); +#endif + + /* Write */ + DBGLOG(INIT, INFO, "QA_AGENT HQA_WriteEEPROM\n"); + kalMemSet(&rAccessEfuseInfoWrite, 0, + sizeof(struct PARAM_CUSTOM_ACCESS_EFUSE)); + u4Index = Offset % EFUSE_BLOCK_SIZE; + + if (prGlueInfo->prAdapter->rWifiVar.ucEfuseBufferModeCal == + TRUE && Offset >= 0 && Offset < MAX_EEPROM_BUFFER_SIZE - 1) { + uacEEPROMImage[Offset] = u4WriteData & 0xff; + uacEEPROMImage[Offset + 1] = u4WriteData >> 8 & 0xff; + } else if (u4Index >= EFUSE_BLOCK_SIZE - 1) { + DBGLOG(INIT, ERROR, "u4Index [%d] overrun\n", u4Index); + } else { + prGlueInfo->prAdapter->aucEepromVaule[u4Index] = u4WriteData + & 0xff; /* Note: u4WriteData is UINT_16 */ + prGlueInfo->prAdapter->aucEepromVaule[u4Index + 1] = + u4WriteData >> 8 & 0xff; + + kalMemCopy(rAccessEfuseInfoWrite.aucData, + prGlueInfo->prAdapter->aucEepromVaule, 16); + rAccessEfuseInfoWrite.u4Address = + (Offset / EFUSE_BLOCK_SIZE) * EFUSE_BLOCK_SIZE; + + rStatus = kalIoctl(prGlueInfo, + wlanoidQueryProcessAccessEfuseWrite, + &rAccessEfuseInfoWrite, + sizeof(struct PARAM_CUSTOM_ACCESS_EFUSE), + FALSE, FALSE, TRUE, &u4BufLen); + } +#endif + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_ReadBulkEEPROM(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint16_t Offset; + uint16_t Len; +#if (CFG_EEPROM_PAGE_ACCESS == 1) + struct PARAM_CUSTOM_ACCESS_EFUSE rAccessEfuseInfo; + uint32_t u4BufLen = 0; + uint8_t u4Loop = 0; + + uint16_t Buffer; + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint8_t tmp = 0; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + kalMemSet(&rAccessEfuseInfo, 0, + sizeof(struct PARAM_CUSTOM_ACCESS_EFUSE)); +#endif + + DBGLOG(INIT, INFO, "QA_AGENT HQA_ReadBulkEEPROM\n"); + if (prAdapter->chip_info && + !prAdapter->chip_info->is_support_efuse) { + log_dbg(RFTEST, WARN, "Efuse not support\n"); + rStatus = WLAN_STATUS_NOT_SUPPORTED; + ResponseToQA(HqaCmdFrame, prIwReqData, + 2, rStatus); + return rStatus; + } + + memcpy(&Offset, HqaCmdFrame->Data + 2 * 0, 2); + Offset = ntohs(Offset); + memcpy(&Len, HqaCmdFrame->Data + 2 * 1, 2); + Len = ntohs(Len); + tmp = Offset; + DBGLOG(INIT, INFO, + "QA_AGENT HQA_ReadBulkEEPROM Offset : %d\n", Offset); + DBGLOG(INIT, INFO, "QA_AGENT HQA_ReadBulkEEPROM Len : %d\n", + Len); + +#if (CFG_EEPROM_PAGE_ACCESS == 1) + rAccessEfuseInfo.u4Address = (Offset / EFUSE_BLOCK_SIZE) * + EFUSE_BLOCK_SIZE; + + DBGLOG(INIT, INFO, + "QA_AGENT HQA_ReadBulkEEPROM Address : %d\n", + rAccessEfuseInfo.u4Address); + + if ((prGlueInfo->prAdapter->rWifiVar.ucEfuseBufferModeCal != + TRUE) + && (prGlueInfo->prAdapter->fgIsSupportQAAccessEfuse == + TRUE)) { + + /* Read from Efuse */ + DBGLOG(INIT, INFO, + "QA_AGENT HQA_ReadBulkEEPROM Efuse Mode\n"); + rStatus = kalIoctl(prGlueInfo, + wlanoidQueryProcessAccessEfuseRead, + &rAccessEfuseInfo, + sizeof(struct PARAM_CUSTOM_ACCESS_EFUSE), + TRUE, TRUE, TRUE, &u4BufLen); + + if (rStatus == WLAN_STATUS_FAILURE) + DBGLOG(INIT, INFO, + "QA_AGENT HQA_ReadBulkEEPROM kal fail\n"); + + Offset = Offset % EFUSE_BLOCK_SIZE; + +#if 0 + for (u4Loop = 0; u4Loop < 16; u4Loop++) { + DBGLOG(INIT, INFO, + "MT6632:QA_AGENT HQA_ReadBulkEEPROM Efuse Offset=%x u4Loop=%d u4Value=%x\n", + Offset, u4Loop, + prGlueInfo->prAdapter->aucEepromVaule[u4Loop]); + } +#endif + for (u4Loop = 0; u4Loop < Len; u4Loop += 2) { + memcpy(&Buffer, prGlueInfo->prAdapter->aucEepromVaule + + Offset + u4Loop, 2); + Buffer = ntohs(Buffer); + DBGLOG(INIT, INFO, + ":From Efuse u4Loop=%d Buffer=%x\n", + u4Loop, Buffer); + memcpy(HqaCmdFrame->Data + 2 + u4Loop, &Buffer, 2); + } + + } else { /* Read from EEPROM */ + for (u4Loop = 0; u4Loop < Len; u4Loop += 2) { + memcpy(&Buffer, uacEEPROMImage + Offset + u4Loop, 2); + Buffer = ntohs(Buffer); + memcpy(HqaCmdFrame->Data + 2 + u4Loop, &Buffer, 2); + DBGLOG(INIT, INFO, + "QA_AGENT HQA_ReadBulkEEPROM u4Loop=%d u4Value=%x\n", + u4Loop, uacEEPROMImage[Offset + u4Loop]); + } + } +#endif + + /*kfree(Buffer);*/ + + /* Read from buffer array in driver */ + /* Pass these data to FW also */ +#if 0 + for (i = 0 ; i < Len ; i += 2) { + memcpy(&u2Temp, uacEEPROMImage + Offset + i, 2); + u2Temp = ntohs(u2Temp); + memcpy(HqaCmdFrame->Data + 2 + i, &u2Temp, 2); + } +#endif + /* For SA Buffer Mode Temp Solution */ +#if 0 + if (Offset == 0x4A0 && !g_BufferDownload) { + + uint16_t u2InitAddr = 0x000; + uint32_t i = 0, j = 0; + uint32_t u4BufLen = 0; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_CUSTOM_EFUSE_BUFFER_MODE rSetEfuseBufModeInfo; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + for (i = 0 ; i < MAX_EEPROM_BUFFER_SIZE / 16 ; i++) { + for (j = 0 ; j < 16 ; j++) { + rSetEfuseBufModeInfo.aBinContent[j].u2Addr = + u2InitAddr; + rSetEfuseBufModeInfo.aBinContent[j].ucValue = + uacEEPROMImage[u2InitAddr]; + u2InitAddr += 1; + } + + rSetEfuseBufModeInfo.ucSourceMode = 1; + rSetEfuseBufModeInfo.ucCount = EFUSE_CONTENT_SIZE; + rStatus = kalIoctl(prGlueInfo, wlanoidSetEfusBufferMode, + &rSetEfuseBufModeInfo, + sizeof(struct PARAM_CUSTOM_EFUSE_BUFFER_MODE), + FALSE, FALSE, TRUE, &u4BufLen); + } + + g_BufferDownload = TRUE; + } +#endif + ResponseToQA(HqaCmdFrame, prIwReqData, 2 + Len, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_WriteBulkEEPROM(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint16_t Offset; + uint16_t Len; + struct ADAPTER *prAdapter = NULL; + + uint32_t u4BufLen = 0; + struct PARAM_CUSTOM_ACCESS_EFUSE rAccessEfuseInfoRead, + rAccessEfuseInfoWrite; + uint16_t testBuffer1, testBuffer2, testBuffer; + uint16_t *Buffer = NULL; + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint8_t u4Loop = 0, u4Index = 0; + uint16_t ucTemp2; + uint16_t i = 0; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + kalMemSet(&rAccessEfuseInfoRead, 0, + sizeof(struct PARAM_CUSTOM_ACCESS_EFUSE)); + kalMemSet(&rAccessEfuseInfoWrite, 0, + sizeof(struct PARAM_CUSTOM_ACCESS_EFUSE)); + + DBGLOG(INIT, INFO, "QA_AGENT HQA_WriteBulkEEPROM\n"); + + + memcpy(&Offset, HqaCmdFrame->Data + 2 * 0, 2); + Offset = ntohs(Offset); + memcpy(&Len, HqaCmdFrame->Data + 2 * 1, 2); + Len = ntohs(Len); + + memcpy(&testBuffer1, HqaCmdFrame->Data + 2 * 2, Len); + testBuffer2 = ntohs(testBuffer1); + testBuffer = ntohs(testBuffer1); + + DBGLOG(INIT, INFO, "Offset : %x, Len : %u\n", Offset, Len); + + /* Support Delay Calibraiton */ + if (prGlueInfo->prAdapter->fgIsSupportQAAccessEfuse == + TRUE) { + + Buffer = kmalloc(sizeof(uint8_t) * (EFUSE_BLOCK_SIZE), + GFP_KERNEL); + ASSERT(Buffer); + kalMemSet(Buffer, 0, sizeof(uint8_t) * (EFUSE_BLOCK_SIZE)); + + kalMemCopy((uint8_t *)Buffer, + (uint8_t *)HqaCmdFrame->Data + 4, Len); + + for (u4Loop = 0; u4Loop < (Len); u4Loop++) { + + DBGLOG(INIT, INFO, + "QA_AGENT HQA_WriteBulkEEPROM u4Loop=%d u4Value=%x\n", + u4Loop, Buffer[u4Loop]); + } + + if (prGlueInfo->prAdapter->rWifiVar.ucEfuseBufferModeCal == + TRUE && + Offset >= 0 && Offset < MAX_EEPROM_BUFFER_SIZE - 1) { + /* EEPROM */ + DBGLOG(INIT, INFO, "Direct EEPROM buffer, offset=%x\n", + Offset); +#if 0 + for (i = 0; i < EFUSE_BLOCK_SIZE; i++) + memcpy(uacEEPROMImage + Offset + i, Buffer + i, + 1); + +#endif + *Buffer = ntohs(*Buffer); + uacEEPROMImage[Offset] = *Buffer & 0xff; + uacEEPROMImage[Offset + 1] = *Buffer >> 8 & 0xff; + } else { + /* EFUSE */ + /* Read */ + DBGLOG(INIT, INFO, + "QA_AGENT HQA_WriteBulkEEPROM Read\n"); + if (prAdapter->chip_info && + !prAdapter->chip_info->is_support_efuse) { + log_dbg(RFTEST, WARN, "Efuse not support\n"); + rStatus = WLAN_STATUS_NOT_SUPPORTED; + ResponseToQA(HqaCmdFrame, prIwReqData, + 2, rStatus); + kfree(Buffer); + return rStatus; + } + kalMemSet(&rAccessEfuseInfoRead, 0, + sizeof(struct PARAM_CUSTOM_ACCESS_EFUSE)); + rAccessEfuseInfoRead.u4Address = + (Offset / EFUSE_BLOCK_SIZE) * EFUSE_BLOCK_SIZE; + rStatus = kalIoctl(prGlueInfo, + wlanoidQueryProcessAccessEfuseRead, + &rAccessEfuseInfoRead, + sizeof(struct PARAM_CUSTOM_ACCESS_EFUSE), + TRUE, TRUE, TRUE, &u4BufLen); + + /* Write */ + kalMemSet(&rAccessEfuseInfoWrite, 0, + sizeof(struct PARAM_CUSTOM_ACCESS_EFUSE)); + + if (Len > 2) { + for (u4Loop = 0; u4Loop < 8 ; u4Loop++) + Buffer[u4Loop] = ntohs(Buffer[u4Loop]); + memcpy(rAccessEfuseInfoWrite.aucData, Buffer, + 16); + } else { + u4Index = Offset % EFUSE_BLOCK_SIZE; + DBGLOG(INIT, INFO, + "MT6632:QA_AGENT HQA_WriteBulkEEPROM Wr,u4Index=%x,Buffer=%x\n", + u4Index, testBuffer); + + *Buffer = ntohs(*Buffer); + DBGLOG(INIT, INFO, + "Buffer[0]=%x, Buffer[0]&0xff=%x\n", + Buffer[0], Buffer[0] & 0xff); + DBGLOG(INIT, INFO, "Buffer[0] >> 8 & 0xff=%x\n" + , Buffer[0] >> 8 & 0xff); + + if (u4Index < EFUSE_BLOCK_SIZE - 1) { + prGlueInfo->prAdapter + ->aucEepromVaule[u4Index] = + *Buffer & 0xff; + prGlueInfo->prAdapter + ->aucEepromVaule[u4Index + 1] = + *Buffer >> 8 & 0xff; + kalMemCopy( + rAccessEfuseInfoWrite.aucData, + prGlueInfo->prAdapter + ->aucEepromVaule, 16); + } else { + DBGLOG(INIT, ERROR, + "u4Index [%d] overrun\n", + u4Index); + goto end; + } + } + + rAccessEfuseInfoWrite.u4Address = + (Offset / EFUSE_BLOCK_SIZE) * EFUSE_BLOCK_SIZE; + for (u4Loop = 0; u4Loop < (EFUSE_BLOCK_SIZE); + u4Loop++) { + DBGLOG(INIT, INFO, " Loop=%d aucData=%x\n", + u4Loop, + rAccessEfuseInfoWrite.aucData[u4Loop]); + } + + DBGLOG(INIT, INFO, "Going for e-Fuse\n"); + + rStatus = kalIoctl(prGlueInfo, + wlanoidQueryProcessAccessEfuseWrite, + &rAccessEfuseInfoWrite, + sizeof(struct PARAM_CUSTOM_ACCESS_EFUSE), + FALSE, TRUE, TRUE, &u4BufLen); + } + + } else { + + if (Len == 2) { + memcpy(&ucTemp2, HqaCmdFrame->Data + 2 * 2, 2); + ucTemp2 = ntohs(ucTemp2); + memcpy(uacEEPROMImage + Offset, &ucTemp2, Len); + } else { + for (i = 0 ; i < 8 ; i++) { + memcpy(&ucTemp2, + HqaCmdFrame->Data + 2 * 2 + 2 * i, 2); + ucTemp2 = ntohs(ucTemp2); + memcpy(uacEEPROMImage + Offset + 2 * i, + &ucTemp2, 2); + } + + if (!g_BufferDownload) { + uint16_t u2InitAddr = Offset; + uint32_t j = 0; + uint32_t u4BufLen = 0; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_CUSTOM_EFUSE_BUFFER_MODE + *prSetEfuseBufModeInfo = NULL; + struct BIN_CONTENT *pBinContent; + + prSetEfuseBufModeInfo = + ( + struct PARAM_CUSTOM_EFUSE_BUFFER_MODE *) + kalMemAlloc(sizeof( + struct PARAM_CUSTOM_EFUSE_BUFFER_MODE), + VIR_MEM_TYPE); + if (prSetEfuseBufModeInfo == NULL) + return 0; + kalMemZero(prSetEfuseBufModeInfo, + sizeof( + struct PARAM_CUSTOM_EFUSE_BUFFER_MODE)); + + prGlueInfo = + *((struct GLUE_INFO **) + netdev_priv(prNetDev)); + pBinContent = (struct BIN_CONTENT *) + prSetEfuseBufModeInfo->aBinContent; + + for (j = 0 ; j < 16 ; j++) { + pBinContent->u2Addr = u2InitAddr; + pBinContent->ucValue = + uacEEPROMImage[u2InitAddr]; + + pBinContent++; + } + + prSetEfuseBufModeInfo->ucSourceMode = 1; + prSetEfuseBufModeInfo->ucCount = + EFUSE_CONTENT_SIZE; + rStatus = kalIoctl(prGlueInfo, + wlanoidSetEfusBufferMode, + (void *)prSetEfuseBufModeInfo, sizeof( + struct PARAM_CUSTOM_EFUSE_BUFFER_MODE), + FALSE, FALSE, TRUE, &u4BufLen); + + kalMemFree(prSetEfuseBufModeInfo, VIR_MEM_TYPE, + sizeof( + struct PARAM_CUSTOM_EFUSE_BUFFER_MODE)); + + if (Offset == 0x4A0) + g_BufferDownload = TRUE; + } + } + } + +end: + ResponseToQA(HqaCmdFrame, prIwReqData, 2 + Len, i4Ret); + kfree(Buffer); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_CheckEfuseMode(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t Value = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_CheckEfuseMode\n"); + + /* Value: 0:eeprom mode, 1:eFuse mode */ + Value = ntohl(Value); + memcpy(HqaCmdFrame->Data + 2, &(Value), sizeof(Value)); + + ResponseToQA(HqaCmdFrame, prIwReqData, 6, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_GetFreeEfuseBlock(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + + int32_t i4Ret = 0, u4FreeBlockCount = 0; + +#if (CFG_EEPROM_PAGE_ACCESS == 1) + struct PARAM_CUSTOM_EFUSE_FREE_BLOCK rEfuseFreeBlock; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + struct GLUE_INFO *prGlueInfo = NULL; +#endif + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(INIT, INFO, "QA_AGENT HQA_GetFreeEfuseBlock\n"); + +#if (CFG_EEPROM_PAGE_ACCESS == 1) + if (prGlueInfo->prAdapter->fgIsSupportGetFreeEfuseBlockCount + == TRUE) { + kalMemSet(&rEfuseFreeBlock, 0, + sizeof(struct PARAM_CUSTOM_EFUSE_FREE_BLOCK)); + + + rStatus = kalIoctl(prGlueInfo, + wlanoidQueryEfuseFreeBlock, + &rEfuseFreeBlock, + sizeof(struct PARAM_CUSTOM_EFUSE_FREE_BLOCK), + TRUE, TRUE, TRUE, &u4BufLen); + + u4FreeBlockCount = prGlueInfo->prAdapter->u4FreeBlockNum; + u4FreeBlockCount = ntohl(u4FreeBlockCount); + kalMemCopy(HqaCmdFrame->Data + 2, &u4FreeBlockCount, 4); + } +#endif + + ResponseToQA(HqaCmdFrame, prIwReqData, 6, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_GetEfuseBlockNr(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_GetEfuseBlockNr\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_WriteEFuseFromBuffer(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_WriteEFuseFromBuffer\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_GetTxPower(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t u4Channel = 0, u4Band = 0, u4Ch_Band = 0, + u4TxTargetPower = 0; + /* UINT_32 u4EfuseAddr = 0, u4Power = 0; */ + +#if (CFG_EEPROM_PAGE_ACCESS == 1) + struct PARAM_CUSTOM_GET_TX_POWER rGetTxPower; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + struct GLUE_INFO *prGlueInfo = NULL; +#endif + + memcpy(&u4Channel, HqaCmdFrame->Data + 4 * 0, 4); + u4Channel = ntohl(u4Channel); + memcpy(&u4Band, HqaCmdFrame->Data + 4 * 1, 4); + u4Band = ntohl(u4Band); + memcpy(&u4Ch_Band, HqaCmdFrame->Data + 4 * 2, 4); + u4Ch_Band = ntohl(u4Ch_Band); + + DBGLOG(RFTEST, INFO, "u4Channel : %u, u4Band : %u, u4Ch_Band : %u\n", + u4Channel, u4Band, u4Ch_Band); + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + if (prGlueInfo->prAdapter->fgIsSupportGetTxPower == TRUE) { + kalMemSet(&rGetTxPower, 0, + sizeof(struct PARAM_CUSTOM_GET_TX_POWER)); + + rGetTxPower.ucCenterChannel = u4Channel; + rGetTxPower.ucBand = u4Band; + rGetTxPower.ucDbdcIdx = u4Ch_Band; + + rStatus = kalIoctl(prGlueInfo, + wlanoidQueryGetTxPower, + &rGetTxPower, + sizeof(struct PARAM_CUSTOM_GET_TX_POWER), + TRUE, TRUE, TRUE, &u4BufLen); + + u4TxTargetPower = prGlueInfo->prAdapter->u4GetTxPower; + u4TxTargetPower = ntohl(u4TxTargetPower); + kalMemCopy(HqaCmdFrame->Data + 6, &u4TxTargetPower, 4); + } + ResponseToQA(HqaCmdFrame, prIwReqData, 10, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_SetCfgOnOff(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t Type, Enable, Band; + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + uint32_t u4BufLen = 0; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + memcpy(&Type, HqaCmdFrame->Data + 4 * 0, 4); + Type = ntohl(Type); + memcpy(&Enable, HqaCmdFrame->Data + 4 * 1, 4); + Enable = ntohl(Enable); + memcpy(&Band, HqaCmdFrame->Data + 4 * 2, 4); + Band = ntohl(Band); + + DBGLOG(RFTEST, INFO, "Type : %u, Enable : %u, Band : %u\n", + Type, Enable, Band); + + switch (Type) { + case 0: /* TSSI */ + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_TSSI; + break; + case 1: /* DPD */ + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_DPD_MODE; + break; + default: + DBGLOG(RFTEST, WARN, "Type [%d] not support\n", Type); + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + return i4Ret; + } + + + + rRfATInfo.u4FuncData = 0; + + if (Enable == 0) + rRfATInfo.u4FuncData &= ~BIT(0); + else + rRfATInfo.u4FuncData |= BIT(0); + + if (Band == 0) + rRfATInfo.u4FuncData &= ~BIT(1); + else + rRfATInfo.u4FuncData |= BIT(1); + + rStatus = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (rStatus != WLAN_STATUS_SUCCESS) + return -EFAULT; + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_GetFreqOffset(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t u4FreqOffset = 0; + uint32_t u4BufLen = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct mt66xx_chip_info *prChipInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + if (!prGlueInfo) { + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + return i4Ret; + } + + if (prGlueInfo->prAdapter) + prChipInfo = prGlueInfo->prAdapter->chip_info; + + /* Mobile chips don't support GetFreqOffset */ + if (prChipInfo && prChipInfo->u4ChipIpVersion + == CONNAC_CHIP_IP_VERSION) { + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + return i4Ret; + } + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_GET_FREQ_OFFSET; + rRfATInfo.u4FuncData = 0; + + i4Ret = kalIoctl(prGlueInfo, + wlanoidRftestQueryAutoTest, &rRfATInfo, + sizeof(rRfATInfo), TRUE, TRUE, TRUE, &u4BufLen); + + if (i4Ret == 0) { + u4FreqOffset = rRfATInfo.u4FuncData; + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_GetFreqOffset u4FreqOffset = %d\n", + u4FreqOffset); + + u4FreqOffset = ntohl(u4FreqOffset); + memcpy(HqaCmdFrame->Data + 2, &u4FreqOffset, + sizeof(u4FreqOffset)); + } + + ResponseToQA(HqaCmdFrame, prIwReqData, 6, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_DBDCTXTone(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + int32_t i4BandIdx = 0, i4Control = 0, i4AntIndex = 0, + i4ToneType = 0, i4ToneFreq = 0; + int32_t i4DcOffsetI = 0, i4DcOffsetQ = 0, i4Band = 0, + i4RF_Power = 0, i4Digi_Power = 0; + + memcpy(&i4BandIdx, HqaCmdFrame->Data + 4 * 0, + 4); /* DBDC Band Index : Band0, Band1 */ + i4BandIdx = ntohl(i4BandIdx); + memcpy(&i4Control, HqaCmdFrame->Data + 4 * 1, + 4); /* Control TX Tone Start and Stop */ + i4Control = ntohl(i4Control); + memcpy(&i4AntIndex, HqaCmdFrame->Data + 4 * 2, + 4); /* Select TX Antenna */ + i4AntIndex = ntohl(i4AntIndex); + memcpy(&i4ToneType, HqaCmdFrame->Data + 4 * 3, + 4); /* ToneType : Single or Two */ + i4ToneType = ntohl(i4ToneType); + memcpy(&i4ToneFreq, HqaCmdFrame->Data + 4 * 4, + 4); /* ToneFreq: DC/5M/10M/20M/40M */ + i4ToneFreq = ntohl(i4ToneFreq); + memcpy(&i4DcOffsetI, HqaCmdFrame->Data + 4 * 5, + 4); /* DC Offset I : -512~1535 */ + i4DcOffsetI = ntohl(i4DcOffsetI); + memcpy(&i4DcOffsetQ, HqaCmdFrame->Data + 4 * 6, + 4); /* DC Offset Q : -512~1535 */ + i4DcOffsetQ = ntohl(i4DcOffsetQ); + memcpy(&i4Band, HqaCmdFrame->Data + 4 * 7, + 4); /* Band : 2.4G/5G */ + i4Band = ntohl(i4Band); + memcpy(&i4RF_Power, HqaCmdFrame->Data + 4 * 8, + 4); /* RF_Power: (1db) 0~15 */ + i4RF_Power = ntohl(i4RF_Power); + memcpy(&i4Digi_Power, HqaCmdFrame->Data + 4 * 9, + 4); /* Digi_Power: (0.25db) -32~31 */ + i4Digi_Power = ntohl(i4Digi_Power); + + DBGLOG(RFTEST, INFO, "BandIdx = 0x%08x\n", i4BandIdx); + DBGLOG(RFTEST, INFO, "Control = 0x%08x\n", i4Control); + DBGLOG(RFTEST, INFO, "AntIndex = 0x%08x\n", i4AntIndex); + DBGLOG(RFTEST, INFO, "ToneType = 0x%08x\n", i4ToneType); + DBGLOG(RFTEST, INFO, "ToneFreq = 0x%08x\n", i4ToneFreq); + DBGLOG(RFTEST, INFO, "DcOffsetI = 0x%08x\n", i4DcOffsetI); + DBGLOG(RFTEST, INFO, "DcOffsetQ = 0x%08x\n", i4DcOffsetQ); + DBGLOG(RFTEST, INFO, "Band = 0x%08x\n", i4Band); + DBGLOG(RFTEST, INFO, "RF_Power = 0x%08x\n", i4RF_Power); + DBGLOG(RFTEST, INFO, "Digi_Power = 0x%08x\n", i4Digi_Power); + + /* + * Select TX Antenna + * RF_Power: (1db) 0~15 + * Digi_Power: (0.25db) -32~31 + */ + MT_ATESetDBDCTxTonePower(prNetDev, i4AntIndex, i4RF_Power, + i4Digi_Power); + + /* DBDC Band Index : Band0, Band1 */ + MT_ATESetDBDCBandIndex(prNetDev, i4BandIdx); + + if (i4Control) { + /* Band : 2.4G/5G */ + MT_ATESetBand(prNetDev, i4Band); + + /* ToneType : Single or Two */ + MT_ATESetTxToneType(prNetDev, i4ToneType); + + /* ToneFreq: DC/5M/10M/20M/40M */ + MT_ATESetTxToneBW(prNetDev, i4ToneFreq); + + /* DC Offset I, DC Offset Q */ + MT_ATESetTxToneDCOffset(prNetDev, i4DcOffsetI, i4DcOffsetQ); + + /* Control TX Tone Start and Stop */ + MT_ATEDBDCTxTone(prNetDev, i4Control); + } else { + /* Control TX Tone Start and Stop */ + MT_ATEDBDCTxTone(prNetDev, i4Control); + } + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +static uint8_t _whPhyGetPrimChOffset(uint32_t u4BW, + uint32_t u4Pri_Ch, + uint32_t u4Cen_ch) +{ + uint8_t ucPrimChOffset = 0; + + /* BW Mapping in QA Tool + * 0: BW20 + * 1: BW40 + * 2: BW80 + * 3: BW10 + * 4: BW5 + * 5: BW160C + * 6: BW160NC + */ + u4Pri_Ch &= 0xFF; + u4Cen_ch &= 0xFF; + switch (u4BW) { + case 1: + ucPrimChOffset = (u4Pri_Ch < u4Cen_ch) ? 0 : 1; + break; + case 2: + ucPrimChOffset = (((u4Pri_Ch - u4Cen_ch) + 6) >> 2); + break; + default: + break; + } + return ucPrimChOffset; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_DBDCContinuousTX(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t u4Band = 0, u4Control = 0, u4AntMask = 0, + u4Phymode = 0, u4BW = 0; + uint32_t u4Pri_Ch = 0, u4Rate = 0, u4Central_Ch = 0, + u4TxfdMode = 0, u4Freq = 0; + uint32_t u4BufLen = 0; + uint8_t ucPriChOffset = 0; + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + memcpy(&u4Band, HqaCmdFrame->Data + 4 * 0, 4); + u4Band = ntohl(u4Band); + memcpy(&u4Control, HqaCmdFrame->Data + 4 * 1, 4); + u4Control = ntohl(u4Control); + memcpy(&u4AntMask, HqaCmdFrame->Data + 4 * 2, 4); + u4AntMask = ntohl(u4AntMask); + memcpy(&u4Phymode, HqaCmdFrame->Data + 4 * 3, 4); + u4Phymode = ntohl(u4Phymode); + memcpy(&u4BW, HqaCmdFrame->Data + 4 * 4, 4); + u4BW = ntohl(u4BW); + memcpy(&u4Pri_Ch, HqaCmdFrame->Data + 4 * 5, 4); + u4Pri_Ch = ntohl(u4Pri_Ch); + memcpy(&u4Rate, HqaCmdFrame->Data + 4 * 6, 4); + u4Rate = ntohl(u4Rate); + memcpy(&u4Central_Ch, HqaCmdFrame->Data + 4 * 7, 4); + u4Central_Ch = ntohl(u4Central_Ch); + memcpy(&u4TxfdMode, HqaCmdFrame->Data + 4 * 8, 4); + u4TxfdMode = ntohl(u4TxfdMode); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_DBDCContinuousTX u4Band : %d\n", + u4Band); /* ok */ + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_DBDCContinuousTX u4Control : %d\n", + u4Control); /* ok */ + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_DBDCContinuousTX u4AntMask : %d\n", + u4AntMask); /* ok */ + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_DBDCContinuousTX u4Phymode : %d\n", + u4Phymode); /* ok */ + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_DBDCContinuousTX u4BW : %d\n", u4BW); /* ok */ + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_DBDCContinuousTX u4Pri_Ch : %d\n", + u4Pri_Ch); /* ok */ + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_DBDCContinuousTX u4Rate : %d\n", + u4Rate); /* ok */ + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_DBDCContinuousTX u4Central_Ch : %d\n", + u4Central_Ch); /* ok */ + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_DBDCContinuousTX u4TxfdMode : %d\n", + u4TxfdMode); /* ok */ + + if (u4Control) { + MT_ATESetDBDCBandIndex(prNetDev, u4Band); + u4Freq = nicChannelNum2Freq(u4Central_Ch); + MT_ATESetChannel(prNetDev, 0, u4Freq); + ucPriChOffset = _whPhyGetPrimChOffset(u4BW, + u4Pri_Ch, + u4Central_Ch); + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_DBDCContinuousTX ucPriChOffset : %d\n", + ucPriChOffset); /* ok */ + MT_ATEPrimarySetting(prNetDev, ucPriChOffset); + + if (u4Phymode == 1) { + u4Phymode = 0; + u4Rate += 4; + } else if ((u4Phymode == 0) && + ((u4Rate == 9) || (u4Rate == 10) || (u4Rate == 11))) + u4Phymode = 1; + MT_ATESetPreamble(prNetDev, u4Phymode); + + if (u4Phymode == 0) { + u4Rate |= 0x00000000; + + DBGLOG(RFTEST, INFO, + "QA_AGENT CCK/OFDM (normal preamble) rate : %d\n", + u4Rate); + + MT_ATESetRate(prNetDev, u4Rate); + } else if (u4Phymode == 1) { + if (u4Rate == 9) + u4Rate = 1; + else if (u4Rate == 10) + u4Rate = 2; + else if (u4Rate == 11) + u4Rate = 3; + u4Rate |= 0x00000000; + + DBGLOG(RFTEST, INFO, + "QA_AGENT CCK (short preamble) rate : %d\n", + u4Rate); + + MT_ATESetRate(prNetDev, u4Rate); + } else if (u4Phymode >= 2 && u4Phymode <= 4) { + u4Rate |= 0x80000000; + + DBGLOG(RFTEST, INFO, "QA_AGENT HT/VHT rate : %d\n", + u4Rate); + + MT_ATESetRate(prNetDev, u4Rate); + } + + MT_ATESetSystemBW(prNetDev, u4BW); + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_CW_MODE; + rRfATInfo.u4FuncData = u4TxfdMode; + + rStatus = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (rStatus != WLAN_STATUS_SUCCESS) + return -EFAULT; + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_ANTMASK; + rRfATInfo.u4FuncData = u4AntMask; + + rStatus = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (rStatus != WLAN_STATUS_SUCCESS) + return -EFAULT; + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_COMMAND; + rRfATInfo.u4FuncData = RF_AT_COMMAND_CW; + + rStatus = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (rStatus != WLAN_STATUS_SUCCESS) + return -EFAULT; + } else { + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_COMMAND; + rRfATInfo.u4FuncData = RF_AT_COMMAND_STOPTEST; + + rStatus = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (rStatus != WLAN_STATUS_SUCCESS) + return -EFAULT; + } + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_SetRXFilterPktLen(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t u4Band = 0, u4Control = 0, u4RxPktlen = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + uint32_t u4BufLen = 0; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + memcpy(&u4Band, HqaCmdFrame->Data + 4 * 0, 4); + u4Band = ntohl(u4Band); + memcpy(&u4Control, HqaCmdFrame->Data + 4 * 1, 4); + u4Control = ntohl(u4Control); + memcpy(&u4RxPktlen, HqaCmdFrame->Data + 4 * 2, 4); + u4RxPktlen = ntohl(u4RxPktlen); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_SetRXFilterPktLen Band : %d\n", u4Band); + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_SetRXFilterPktLen Control : %d\n", u4Control); + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_SetRXFilterPktLen RxPktlen : %d\n", + u4RxPktlen); + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_RX_FILTER_PKT_LEN; + rRfATInfo.u4FuncData = (uint32_t) (u4RxPktlen & BITS(0, + 23)); + rRfATInfo.u4FuncData |= (uint32_t) (u4Band << 24); + + if (u4Control == 1) + rRfATInfo.u4FuncData |= BIT(30); + else + rRfATInfo.u4FuncData &= ~BIT(30); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_SetRXFilterPktLen rRfATInfo.u4FuncData : 0x%08x\n", + rRfATInfo.u4FuncData); + + i4Ret = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Ret != WLAN_STATUS_SUCCESS) + return -EFAULT; + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_GetTXInfo(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + uint32_t u4Txed_band0 = 0; + uint32_t u4Txed_band1 = 0; + int32_t i4Status; + uint32_t u4BufLen = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_GetTXInfo\n"); + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_TXED_COUNT; + rRfATInfo.u4FuncData = 0; + + i4Status = kalIoctl(prGlueInfo, + wlanoidRftestQueryAutoTest, &rRfATInfo, + sizeof(rRfATInfo), + TRUE, TRUE, TRUE, &u4BufLen); + + if (i4Status == 0) { + u4Txed_band0 = rRfATInfo.u4FuncData; + + DBGLOG(RFTEST, INFO, + "QA_AGENT u4Txed_band0 packet count = %d\n", + u4Txed_band0); + + u4Txed_band0 = ntohl(u4Txed_band0); + memcpy(HqaCmdFrame->Data + 2, &u4Txed_band0, + sizeof(u4Txed_band0)); + } + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_TXED_COUNT; + rRfATInfo.u4FuncIndex |= BIT(8); + rRfATInfo.u4FuncData = 0; + + i4Status = kalIoctl(prGlueInfo, + wlanoidRftestQueryAutoTest, &rRfATInfo, + sizeof(rRfATInfo), + TRUE, TRUE, TRUE, &u4BufLen); + + if (i4Status == 0) { + u4Txed_band1 = rRfATInfo.u4FuncData; + + DBGLOG(RFTEST, INFO, + "QA_AGENT u4Txed_band1 packet count = %d\n", + u4Txed_band1); + + u4Txed_band1 = ntohl(u4Txed_band1); + memcpy(HqaCmdFrame->Data + 2 + 4, &u4Txed_band1, + sizeof(u4Txed_band1)); + } + + ResponseToQA(HqaCmdFrame, prIwReqData, + 2 + sizeof(u4Txed_band0) + sizeof(u4Txed_band1), i4Status); + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_GetCfgOnOff(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_GetCfgOnOff\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +static HQA_CMD_HANDLER HQA_CMD_SET3[] = { + /* cmd id start from 0x1300 */ + HQA_MacBbpRegRead, /* 0x1300 */ + HQA_MacBbpRegWrite, /* 0x1301 */ + HQA_MACBbpRegBulkRead, /* 0x1302 */ + HQA_RfRegBulkRead, /* 0x1303 */ + HQA_RfRegBulkWrite, /* 0x1304 */ + HQA_ReadEEPROM, /* 0x1305 */ + HQA_WriteEEPROM, /* 0x1306 */ + HQA_ReadBulkEEPROM, /* 0x1307 */ + HQA_WriteBulkEEPROM, /* 0x1308 */ + HQA_CheckEfuseMode, /* 0x1309 */ + HQA_GetFreeEfuseBlock, /* 0x130A */ + HQA_GetEfuseBlockNr, /* 0x130B */ + HQA_WriteEFuseFromBuffer, /* 0x130C */ + HQA_GetTxPower, /* 0x130D */ + HQA_SetCfgOnOff, /* 0x130E */ + HQA_GetFreqOffset, /* 0x130F */ + HQA_DBDCTXTone, /* 0x1310 */ + HQA_DBDCContinuousTX, /* 0x1311 */ + HQA_SetRXFilterPktLen, /* 0x1312 */ + HQA_GetTXInfo, /* 0x1313 */ + HQA_GetCfgOnOff, /* 0x1314 */ +}; + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_ReadTempReferenceValue( + struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_ReadTempReferenceValue\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For Get Thermal Value. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_GetThermalValue(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + uint32_t u4Value; + uint32_t u4BufLen = 0; + int32_t i4Status; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_TEMP_SENSOR; + rRfATInfo.u4FuncData = 0; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + i4Status = kalIoctl(prGlueInfo, + wlanoidRftestQueryAutoTest, &rRfATInfo, + sizeof(rRfATInfo), TRUE, TRUE, TRUE, &u4BufLen); + + if (i4Status == 0) { + u4Value = rRfATInfo.u4FuncData; + u4Value = u4Value >> 16; + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_GetThermalValue Value = %d\n", u4Value); + + u4Value = ntohl(u4Value); + memcpy(HqaCmdFrame->Data + 2, &u4Value, 4); + } + + ResponseToQA(HqaCmdFrame, prIwReqData, 6, i4Status); + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_SetSideBandOption(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_SetSideBandOption\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +static HQA_CMD_HANDLER HQA_CMD_SET4[] = { + /* cmd id start from 0x1400 */ + HQA_ReadTempReferenceValue, /* 0x1400 */ + HQA_GetThermalValue, /* 0x1401 */ + HQA_SetSideBandOption, /* 0x1402 */ +}; + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_GetFWInfo(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_GetFWInfo\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_StartContinousTx(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_StartContinousTx\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_SetSTBC(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_SetSTBC\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For Set short GI. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_SetShortGI(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t u4ShortGi; + + memcpy(&u4ShortGi, HqaCmdFrame->Data, 4); + u4ShortGi = ntohl(u4ShortGi); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_SetShortGI u4ShortGi = %d\n", u4ShortGi); + + i4Ret = MT_ATESetTxGi(prNetDev, u4ShortGi); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_SetDPD(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_SetDPD\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For Get Rx Statistics. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_GetRxStatisticsAll(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t u4BufLen = 0; + struct PARAM_CUSTOM_ACCESS_RX_STAT rRxStatisticsTest; + + /* memset(&g_HqaRxStat, 0, sizeof(PARAM_RX_STAT_T)); */ + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_GetRxStatisticsAll\n"); + + rRxStatisticsTest.u4SeqNum = u4RxStatSeqNum; + rRxStatisticsTest.u4TotalNum = HQA_RX_STATISTIC_NUM + 6; + + i4Ret = kalIoctl(prGlueInfo, + wlanoidQueryRxStatistics, + &rRxStatisticsTest, sizeof(rRxStatisticsTest), + TRUE, TRUE, TRUE, &u4BufLen); + + /* ASSERT(rRxStatisticsTest.u4SeqNum == u4RxStatSeqNum); */ + + u4RxStatSeqNum++; + + memcpy(HqaCmdFrame->Data + 2, &(g_HqaRxStat), + sizeof(struct PARAM_RX_STAT)); + ResponseToQA(HqaCmdFrame, prIwReqData, + (2 + sizeof(struct PARAM_RX_STAT)), i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_StartContiTxTone(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_StartContiTxTone\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_StopContiTxTone(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_StopContiTxTone\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_CalibrationTestMode(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t u4Mode = 0; + uint32_t u4IcapLen = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_CalibrationTestMode\n"); + + memcpy(&u4Mode, HqaCmdFrame->Data + 4 * 0, 4); + u4Mode = ntohl(u4Mode); + memcpy(&u4IcapLen, HqaCmdFrame->Data + 4 * 1, 4); + u4IcapLen = ntohl(u4IcapLen); + + if (u4Mode == 2) + i4Ret = MT_ICAPStart(prNetDev, "ICAPSTART"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_DoCalibrationTestItem(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Status = 0; + uint32_t u4Item = 0; + uint32_t u4Band_idx = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + struct ADAPTER *prAdapter; + uint32_t u4BufLen = 0; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + ASSERT(prGlueInfo); + prAdapter = prGlueInfo->prAdapter; + ASSERT(prAdapter); + + memcpy(&u4Item, HqaCmdFrame->Data, 4); + u4Item = ntohl(u4Item); + + memcpy(&u4Band_idx, HqaCmdFrame->Data + 4, 4); + u4Band_idx = ntohl(u4Band_idx); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_DoCalibrationTestItem item : 0x%08x\n", + u4Item); + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_DoCalibrationTestItem band_idx : %d\n", + u4Band_idx); + + MT_ATESetDBDCBandIndex(prNetDev, u4Band_idx); + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_RECAL_CAL_STEP; + rRfATInfo.u4FuncData = u4Item; + + kalMemSet((void *)&prAdapter->rReCalInfo, + 0, + sizeof(struct RECAL_INFO_T)); + i4Status = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Status); + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_eFusePhysicalWrite(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_eFusePhysicalWrite\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_eFusePhysicalRead(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_eFusePhysicalRead\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_eFuseLogicalRead(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_eFuseLogicalRead\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_eFuseLogicalWrite(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_eFuseLogicalWrite\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_TMRSetting(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t u4Setting; + uint32_t u4Version; + uint32_t u4MPThres; + uint32_t u4MPIter; + + memcpy(&u4Setting, HqaCmdFrame->Data + 4 * 0, 4); + u4Setting = ntohl(u4Setting); + memcpy(&u4Version, HqaCmdFrame->Data + 4 * 1, 4); + u4Version = ntohl(u4Version); + memcpy(&u4MPThres, HqaCmdFrame->Data + 4 * 2, 4); + u4MPThres = ntohl(u4MPThres); + memcpy(&u4MPIter, HqaCmdFrame->Data + 4 * 3, 4); + u4MPIter = ntohl(u4MPIter); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_TMRSetting u4Setting : %d\n", u4Setting); + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_TMRSetting u4Version : %d\n", u4Version); + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_TMRSetting u4MPThres : %d\n", u4MPThres); + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_TMRSetting u4MPIter : %d\n", u4MPIter); + + i4Ret = MT_ATE_TMRSetting(prNetDev, u4Setting, u4Version, + u4MPThres, u4MPIter); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_GetRxSNR(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_GetRxSNR\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_WriteBufferDone(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + /* UINT_16 u2InitAddr = 0x000; */ + uint32_t Value; + /* UINT_32 i = 0, j = 0; + * UINT_32 u4BufLen = 0; + */ + /* WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; */ + struct GLUE_INFO *prGlueInfo = NULL; + /* PARAM_CUSTOM_EFUSE_BUFFER_MODE_T rSetEfuseBufModeInfo; */ + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + memcpy(&Value, HqaCmdFrame->Data + 4 * 0, 4); + Value = ntohl(Value); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_WriteBufferDone Value : %d\n", Value); + + u4EepromMode = Value; + +#if 0 + for (i = 0 ; i < MAX_EEPROM_BUFFER_SIZE / 16 ; i++) { + for (j = 0 ; j < 16 ; j++) { + rSetEfuseBufModeInfo.aBinContent[j].u2Addr = u2InitAddr; + rSetEfuseBufModeInfo.aBinContent[j].ucValue = + uacEEPROMImage[u2InitAddr]; + DBGLOG(RFTEST, INFO, "u2Addr = %x\n", + rSetEfuseBufModeInfo.aBinContent[j].u2Addr); + DBGLOG(RFTEST, INFO, "ucValue = %x\n", + rSetEfuseBufModeInfo.aBinContent[j].ucValue); + u2InitAddr += 1; + } + + rSetEfuseBufModeInfo.ucSourceMode = 1; + rSetEfuseBufModeInfo.ucCount = EFUSE_CONTENT_SIZE; + rStatus = kalIoctl(prGlueInfo, + wlanoidSetEfusBufferMode, + &rSetEfuseBufModeInfo, + sizeof(struct PARAM_CUSTOM_EFUSE_BUFFER_MODE), + FALSE, FALSE, TRUE, &u4BufLen); + } +#endif + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_FFT(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_FFT\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_SetTxTonePower(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_SetTxTonePower\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_GetChipID(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t u4ChipId; + struct mt66xx_chip_info *prChipInfo = NULL; + struct ADAPTER *prAdapter = NULL; + struct GLUE_INFO *prGlueInfo = NULL; + /* UINT_32 u4BufLen = 0; + * PARAM_CUSTOM_MCR_RW_STRUCT_T rMcrInfo; + */ + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + prChipInfo = prAdapter->chip_info; + g_u4Chip_ID = prChipInfo->chip_id; + DBGLOG(RFTEST, INFO, + "QA_AGENT IPVer= 0x%08x, Adie = 0x%08x\n", + prChipInfo->u4ChipIpVersion, + prChipInfo->u2ADieChipVersion); + + /* Check A-Die information for mobile solution */ + switch (prChipInfo->u2ADieChipVersion) { + case 0x6631: + u4ChipId = 0x00066310; /* use 66310 to diff from gen3 6631 */ + break; + case 0x6635: + u4ChipId = 0x0006635; /* return A die directly */ + break; + default: + u4ChipId = g_u4Chip_ID; + break; + } + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_GetChipID ChipId = 0x%08x\n", u4ChipId); + + u4ChipId = ntohl(u4ChipId); + memcpy(HqaCmdFrame->Data + 2, &u4ChipId, 4); + ResponseToQA(HqaCmdFrame, prIwReqData, 6, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_MPSSetSeqData(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t *mps_setting = NULL; + uint32_t u4Band_idx = 0; + uint32_t u4Offset = 0; + uint32_t u4Len = 0; + uint32_t i = 0; + uint32_t u4Value = 0; + uint32_t u4Mode = 0; + uint32_t u4TxPath = 0; + uint32_t u4Mcs = 0; + + u4Len = ntohs(HqaCmdFrame->Length) / sizeof(uint32_t) - 1; + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_MPSSetSeqData u4Len : %d\n", u4Len); + + mps_setting = kmalloc(sizeof(uint32_t) * (u4Len), + GFP_KERNEL); + ASSERT(mps_setting); + + memcpy(&u4Band_idx, HqaCmdFrame->Data + 4 * 0, 4); + u4Band_idx = ntohl(u4Band_idx); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_MPSSetSeqData u4Band_idx : %d\n", u4Band_idx); + + for (i = 0 ; i < u4Len ; i++) { + u4Offset = 4 + 4 * i; + /* Reserved at least 4 byte availbale data */ + if (u4Offset + 4 > sizeof(HqaCmdFrame->Data)) + break; + memcpy(&u4Value, HqaCmdFrame->Data + 4 + 4 * i, 4); + u4Value = ntohl(u4Value); + + u4Mode = (u4Value & BITS(24, 27)) >> 24; + u4TxPath = (u4Value & BITS(8, 23)) >> 8; + u4Mcs = (u4Value & BITS(0, 7)); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_MPSSetSeqData mps_setting Case %d (Mode : %d / TX Path : %d / MCS : %d)\n" + , i, u4Mode, u4TxPath, u4Mcs); + + if (u4Mode == 1) { + u4Mode = 0; + u4Mcs += 4; + } else if ((u4Mode == 0) && ((u4Mcs == 9) || (u4Mcs == 10) + || (u4Mcs == 11))) + u4Mode = 1; + + if (u4Mode == 0) { + u4Mcs |= 0x00000000; + + DBGLOG(RFTEST, INFO, + "QA_AGENT CCK/OFDM (normal preamble) rate : %d\n", + u4Mcs); + } else if (u4Mode == 1) { + if (u4Mcs == 9) + u4Mcs = 1; + else if (u4Mcs == 10) + u4Mcs = 2; + else if (u4Mcs == 11) + u4Mcs = 3; + u4Mcs |= 0x00000000; + + DBGLOG(RFTEST, INFO, + "QA_AGENT CCK (short preamble) rate : %d\n", + u4Mcs); + } else if (u4Mode >= 2 && u4Mode <= 4) { + u4Mcs |= 0x80000000; + + DBGLOG(RFTEST, INFO, "QA_AGENT HT/VHT rate : %d\n", + u4Mcs); + } + + mps_setting[i] = (u4Mcs) | (u4TxPath << 8) | (u4Mode << 24); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_MPSSetSeqData mps_setting Case %d (Mode : %d / TX Path : %d / MCS : %d)\n", + i, + (int)((mps_setting[i] & BITS(24, 27)) >> 24), + (int)((mps_setting[i] & BITS(8, 23)) >> 8), + (int)((mps_setting[i] & BITS(0, 7)))); + + } + + i4Ret = MT_ATEMPSSetSeqData(prNetDev, u4Len, mps_setting, + u4Band_idx); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + kfree(mps_setting); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_MPSSetPayloadLength(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t *mps_setting = NULL; + uint32_t u4Band_idx = 0; + uint32_t u4Offset = 0; + uint32_t u4Len = 0; + uint32_t i = 0; + uint32_t u4Value = 0; + + u4Len = ntohs(HqaCmdFrame->Length) / sizeof(uint32_t) - 1; + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_MPSSetPayloadLength u4Len : %d\n", u4Len); + + mps_setting = kmalloc(sizeof(uint32_t) * (u4Len), + GFP_KERNEL); + ASSERT(mps_setting); + + memcpy(&u4Band_idx, HqaCmdFrame->Data + 4 * 0, 4); + u4Band_idx = ntohl(u4Band_idx); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_MPSSetPayloadLength u4Band_idx : %d\n", + u4Band_idx); + + for (i = 0 ; i < u4Len ; i++) { + u4Offset = 4 + 4 * i; + /* Reserved at least 4 byte availbale data */ + if (u4Offset + 4 > sizeof(HqaCmdFrame->Data)) + break; + memcpy(&u4Value, HqaCmdFrame->Data + 4 + 4 * i, 4); + mps_setting[i] = ntohl(u4Value); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_MPSSetPayloadLength mps_setting Case %d (Payload Length : %d)\n", + i, mps_setting[i]); + } + + i4Ret = MT_ATEMPSSetPayloadLength(prNetDev, u4Len, + mps_setting, u4Band_idx); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + kfree(mps_setting); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_MPSSetPacketCount(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t *mps_setting = NULL; + uint32_t u4Band_idx = 0; + uint32_t u4Offset = 0; + uint32_t u4Len = 0; + uint32_t i = 0; + uint32_t u4Value = 0; + + u4Len = ntohs(HqaCmdFrame->Length) / sizeof(uint32_t) - 1; + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_MPSSetPacketCount u4Len : %d\n", u4Len); + + mps_setting = kmalloc(sizeof(uint32_t) * (u4Len), + GFP_KERNEL); + ASSERT(mps_setting); + + memcpy(&u4Band_idx, HqaCmdFrame->Data + 4 * 0, 4); + u4Band_idx = ntohl(u4Band_idx); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_MPSSetPacketCount u4Band_idx : %d\n", + u4Band_idx); + + for (i = 0 ; i < u4Len ; i++) { + u4Offset = 4 + 4 * i; + /* Reserved at least 4 byte availbale data */ + if (u4Offset + 4 > sizeof(HqaCmdFrame->Data)) + break; + memcpy(&u4Value, HqaCmdFrame->Data + 4 + 4 * i, 4); + mps_setting[i] = ntohl(u4Value); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_MPSSetPacketCount mps_setting Case %d (Packet Count : %d)\n", + i, mps_setting[i]); + } + + i4Ret = MT_ATEMPSSetPacketCount(prNetDev, u4Len, + mps_setting, u4Band_idx); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + kfree(mps_setting); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_MPSSetPowerGain(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t *mps_setting = NULL; + uint32_t u4Band_idx = 0; + uint32_t u4Offset = 0; + uint32_t u4Len = 0; + uint32_t i = 0; + uint32_t u4Value = 0; + + u4Len = ntohs(HqaCmdFrame->Length) / sizeof(uint32_t) - 1; + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_MPSSetPowerGain u4Len : %d\n", u4Len); + + mps_setting = kmalloc(sizeof(uint32_t) * (u4Len), + GFP_KERNEL); + ASSERT(mps_setting); + + memcpy(&u4Band_idx, HqaCmdFrame->Data + 4 * 0, 4); + u4Band_idx = ntohl(u4Band_idx); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_MPSSetPowerGain u4Band_idx : %d\n", + u4Band_idx); + + for (i = 0 ; i < u4Len ; i++) { + u4Offset = 4 + 4 * i; + /* Reserved at least 4 byte availbale data */ + if (u4Offset + 4 > sizeof(HqaCmdFrame->Data)) + break; + memcpy(&u4Value, HqaCmdFrame->Data + 4 + 4 * i, 4); + mps_setting[i] = ntohl(u4Value); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_MPSSetPowerGain mps_setting Case %d (Power : %d)\n", + i, mps_setting[i]); + } + + i4Ret = MT_ATEMPSSetPowerGain(prNetDev, u4Len, mps_setting, + u4Band_idx); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + kfree(mps_setting); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_MPSStart(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t u4Band_idx = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_MPSStart\n"); + + memcpy(&u4Band_idx, HqaCmdFrame->Data + 4 * 0, 4); + u4Band_idx = ntohl(u4Band_idx); + + MT_ATESetDBDCBandIndex(prNetDev, u4Band_idx); + MT_ATEStartTX(prNetDev, "TXFRAME"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_MPSStop(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t u4Band_idx = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_MPSStop\n"); + + memcpy(&u4Band_idx, HqaCmdFrame->Data + 4 * 0, 4); + u4Band_idx = ntohl(u4Band_idx); + + /* To Do : MPS Stop for Specific Band. */ + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + + +/*----------------------------------------------------------------------------*/ +/*! + * \brief internal function used by HQA_GetRxStatisticsAllV2. + */ +/*----------------------------------------------------------------------------*/ +int32_t hqa_genStatBandReport( + u_int8_t band_idx, + u_int8_t blk_idx, + struct hqa_rx_stat_band_format *rx_st_band) +{ + + int32_t ret = 0; + + if (band_idx == HQA_M_BAND_0) { + rx_st_band->mac_rx_fcs_err_cnt = + ntohl(g_HqaRxStat.MAC_FCS_Err) + + ntohl(g_backup_band0_info.mac_rx_fcs_err_cnt); + rx_st_band->mac_rx_mdrdy_cnt = + ntohl(g_HqaRxStat.MAC_Mdrdy) + + ntohl(g_backup_band0_info.mac_rx_mdrdy_cnt); + rx_st_band->mac_rx_len_mismatch = + ntohl(g_HqaRxStat.LengthMismatchCount_B0) + + ntohl(g_backup_band0_info.mac_rx_len_mismatch); + rx_st_band->mac_rx_fcs_ok_cnt = 0; + rx_st_band->phy_rx_fcs_err_cnt_cck = + ntohl(g_HqaRxStat.FCSErr_CCK); + rx_st_band->phy_rx_fcs_err_cnt_ofdm = + ntohl(g_HqaRxStat.FCSErr_OFDM); + rx_st_band->phy_rx_pd_cck = + ntohl(g_HqaRxStat.CCK_PD); + rx_st_band->phy_rx_pd_ofdm = + ntohl(g_HqaRxStat.OFDM_PD); + rx_st_band->phy_rx_sig_err_cck = + ntohl(g_HqaRxStat.CCK_SIG_Err); + rx_st_band->phy_rx_sfd_err_cck = + ntohl(g_HqaRxStat.CCK_SFD_Err); + rx_st_band->phy_rx_sig_err_ofdm = + ntohl(g_HqaRxStat.OFDM_SIG_Err); + rx_st_band->phy_rx_tag_err_ofdm = + ntohl(g_HqaRxStat.OFDM_TAG_Err); + rx_st_band->phy_rx_mdrdy_cnt_cck = + ntohl(g_HqaRxStat.PhyMdrdyCCK); + rx_st_band->phy_rx_mdrdy_cnt_ofdm = + ntohl(g_HqaRxStat.PhyMdrdyOFDM); + + /* Backup Band1 info */ + g_backup_band1_info.mac_rx_fcs_err_cnt += + g_HqaRxStat.MAC_FCS_Err1; + + g_backup_band1_info.mac_rx_mdrdy_cnt += + g_HqaRxStat.MAC_Mdrdy1; + + g_backup_band1_info.mac_rx_len_mismatch += + g_HqaRxStat.LengthMismatchCount_B1; + + /* Reset Band0 backup info */ + kalMemZero(&g_backup_band0_info, + sizeof(struct hqa_rx_stat_band_format)); + } else { + rx_st_band->mac_rx_fcs_err_cnt = + ntohl( + g_HqaRxStat.MAC_FCS_Err1) + + ntohl( + g_backup_band1_info.mac_rx_fcs_err_cnt); + rx_st_band->mac_rx_mdrdy_cnt = + ntohl( + g_HqaRxStat.MAC_Mdrdy1) + + ntohl( + g_backup_band1_info.mac_rx_mdrdy_cnt); + rx_st_band->mac_rx_len_mismatch = + ntohl( + g_HqaRxStat.LengthMismatchCount_B1) + + ntohl( + g_backup_band1_info.mac_rx_len_mismatch); + rx_st_band->mac_rx_fcs_ok_cnt = 0; + rx_st_band->phy_rx_fcs_err_cnt_cck = + ntohl( + g_HqaRxStat.CCK_FCS_Err_Band1); + rx_st_band->phy_rx_fcs_err_cnt_ofdm = + ntohl( + g_HqaRxStat.OFDM_FCS_Err_Band1); + rx_st_band->phy_rx_pd_cck = + ntohl( + g_HqaRxStat.CCK_PD_Band1); + rx_st_band->phy_rx_pd_ofdm = + ntohl( + g_HqaRxStat.OFDM_PD_Band1); + rx_st_band->phy_rx_sig_err_cck = + ntohl( + g_HqaRxStat.CCK_SIG_Err_Band1); + rx_st_band->phy_rx_sfd_err_cck = + ntohl( + g_HqaRxStat.CCK_SFD_Err_Band1); + rx_st_band->phy_rx_sig_err_ofdm = + ntohl( + g_HqaRxStat.OFDM_SIG_Err_Band1); + rx_st_band->phy_rx_tag_err_ofdm = + ntohl( + g_HqaRxStat.OFDM_TAG_Err_Band1); + rx_st_band->phy_rx_mdrdy_cnt_cck = + ntohl( + g_HqaRxStat.PHY_CCK_MDRDY_Band1); + rx_st_band->phy_rx_mdrdy_cnt_ofdm = + ntohl( + g_HqaRxStat.PHY_OFDM_MDRDY_Band1); + + + /* Backup Band0 info */ + g_backup_band0_info.mac_rx_fcs_err_cnt += + g_HqaRxStat.MAC_FCS_Err; + + g_backup_band0_info.mac_rx_mdrdy_cnt += + g_HqaRxStat.MAC_Mdrdy; + + g_backup_band0_info.mac_rx_len_mismatch += + g_HqaRxStat.LengthMismatchCount_B0; + + /* Reset Band1 backup info */ + kalMemZero(&g_backup_band1_info, + sizeof(struct hqa_rx_stat_band_format)); + } + + return ret; +} + +int32_t hqa_genStatPathReport( + u_int8_t band_idx, + u_int8_t blk_idx, + struct hqa_rx_stat_path_format *rx_st_path) +{ + int32_t ret = 0; + + switch (blk_idx) { + case HQA_ANT_WF0: + rx_st_path->rcpi = + ntohl(g_HqaRxStat.RCPI0); + rx_st_path->rssi = + ntohl(g_HqaRxStat.RSSI0); + rx_st_path->fagc_ib_rssi = + ntohl(g_HqaRxStat.FAGCRssiIBR0); + rx_st_path->fagc_wb_rssi = + ntohl(g_HqaRxStat.FAGCRssiWBR0); + rx_st_path->inst_ib_rssi = + ntohl(g_HqaRxStat.InstRssiIBR0); + rx_st_path->inst_wb_rssi = + ntohl(g_HqaRxStat.InstRssiWBR0); + break; + case HQA_ANT_WF1: + rx_st_path->rcpi = + ntohl(g_HqaRxStat.RCPI1); + rx_st_path->rssi = + ntohl(g_HqaRxStat.RSSI1); + rx_st_path->fagc_ib_rssi = + ntohl(g_HqaRxStat.FAGCRssiIBR1); + rx_st_path->fagc_wb_rssi = + ntohl(g_HqaRxStat.FAGCRssiWBR1); + rx_st_path->inst_ib_rssi = + ntohl(g_HqaRxStat.InstRssiIBR1); + rx_st_path->inst_wb_rssi = + ntohl(g_HqaRxStat.InstRssiWBR1); + break; + + default: + ret = WLAN_STATUS_INVALID_DATA; + break; + } + + return ret; +} + +int32_t hqa_genStatUserReport( + u_int8_t band_idx, + u_int8_t blk_idx, + struct hqa_rx_stat_user_format *rx_st_user) +{ + int32_t ret = WLAN_STATUS_SUCCESS; + + rx_st_user->freq_offset_from_rx = + ntohl(g_HqaRxStat.FreqOffsetFromRX); + if (band_idx == HQA_M_BAND_0) + rx_st_user->snr = ntohl(g_HqaRxStat.SNR0); + else + rx_st_user->snr = ntohl(g_HqaRxStat.SNR1); + + rx_st_user->fcs_error_cnt = + ntohl(g_HqaRxStat.MAC_FCS_Err); + + return ret; +} + +int32_t hqa_genStatCommReport( + u_int8_t band_idx, + u_int8_t blk_idx, + struct hqa_rx_stat_comm_format *rx_st_comm) +{ + int32_t ret = WLAN_STATUS_SUCCESS; + + rx_st_comm->rx_fifo_full = + ntohl(g_HqaRxStat.OutOfResource); + rx_st_comm->aci_hit_low = + ntohl(g_HqaRxStat.ACIHitLower); + rx_st_comm->aci_hit_high = + ntohl(g_HqaRxStat.ACIHitUpper); + rx_st_comm->mu_pkt_count = + ntohl(g_HqaRxStat.MRURxCount); + rx_st_comm->sig_mcs = + ntohl(g_HqaRxStat.SIGMCS); + rx_st_comm->sinr = + ntohl(g_HqaRxStat.SINR); + if (band_idx == HQA_M_BAND_0) { + rx_st_comm->driver_rx_count = + ntohl(g_HqaRxStat.DriverRxCount); + } else { + rx_st_comm->driver_rx_count = + ntohl(g_HqaRxStat.DriverRxCount1); + } + return ret; +} + + +int32_t hqa_getRxStatisticsByType( + struct GLUE_INFO *prGlueInfo, + u_int8_t band_idx, + u_int8_t blk_idx, + u_int8_t test_rx_stat_cat, + struct hqa_rx_stat_u *st) +{ + int32_t i4Ret = 0; + uint32_t u4BufLen = 0; + struct PARAM_CUSTOM_ACCESS_RX_STAT rx_stat_test; + + rx_stat_test.u4SeqNum = 0; + rx_stat_test.u4TotalNum = 72; + + /* only TEST_RX_STAT_BAND send query command to FW. */ + if (test_rx_stat_cat == HQA_RX_STAT_BAND) { + i4Ret = kalIoctl(prGlueInfo, + wlanoidQueryRxStatistics, + &rx_stat_test, sizeof(rx_stat_test), + TRUE, TRUE, TRUE, &u4BufLen); + } + + switch (test_rx_stat_cat) { + case HQA_RX_STAT_BAND: + i4Ret = hqa_genStatBandReport( + band_idx, + blk_idx, + &(st->u.rx_st_band)); + break; + case HQA_RX_STAT_PATH: + i4Ret = hqa_genStatPathReport( + band_idx, + blk_idx, + &(st->u.rx_st_path)); + break; + case HQA_RX_STAT_USER: + i4Ret = hqa_genStatUserReport( + band_idx, + blk_idx, + &(st->u.rx_st_user)); + break; + case HQA_RX_STAT_COMM: + i4Ret = hqa_genStatCommReport( + band_idx, + blk_idx, + &(st->u.rx_st_comm)); + break; + default: + break; + } + + if (i4Ret) + DBGLOG(RFTEST, INFO, "err=0x%08x\n.", i4Ret); + + return i4Ret; + +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For Get Rx Statistics. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_GetRxStatisticsAllV2(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + struct GLUE_INFO *prGlueInfo = NULL; + u_int32_t buf_size = 0; + u_int32_t type_mask = 0, band_idx = 0, type_num = 0, length; + u_int32_t blk_idx = 0, type_idx = 0, buf = 0; + u_int32_t dw_idx = 0, dw_cnt = 0; + u_int32_t *ptr2 = NULL; + struct hqa_rx_stat_u *rx_stat = NULL; + u_int8_t path[HQA_ANT_NUM] = {0}; + u_int8_t path_len = 0; + u_int8_t *ptr = NULL; + u_int8_t i = 0; + + struct hqa_rx_stat_resp_field st_form[HQA_SERV_RX_STAT_TYPE_NUM] = { + {HQA_SERV_RX_STAT_TYPE_BAND, 0, 0, 0, + sizeof(struct hqa_rx_stat_band_format)}, + {HQA_SERV_RX_STAT_TYPE_PATH, 0, 0, 0, + sizeof(struct hqa_rx_stat_path_format)}, + {HQA_SERV_RX_STAT_TYPE_USER, 0, 0, 0, + sizeof(struct hqa_rx_stat_user_format)}, + {HQA_SERV_RX_STAT_TYPE_COMM, 0, 0, 0, + sizeof(struct hqa_rx_stat_comm_format)} + }; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_GetRxStatisticsAllV2\n"); + + + /* Request format type */ + memcpy(&type_mask, HqaCmdFrame->Data + 4 * 0, 4); + type_mask = ntohl(type_mask); + + memcpy(&band_idx, HqaCmdFrame->Data + 4 * 1, 4); + band_idx = ntohl(band_idx); + + DBGLOG(RFTEST, INFO, "type_mask = %d, band_idx = %d\n", + type_mask, band_idx); + + /* sanity check for band index param */ + if ((!g_DBDCEnable) && (band_idx != HQA_M_BAND_0)) + goto error2; + + /* check wifi path combination for specific band */ + /* check with Yenchih */ + if (g_DBDCEnable) { + path_len = 1; + if (band_idx == HQA_M_BAND_0) + path[0] = 0; + else + path[0] = 1; + } else { + path_len = 2; + for (i = 0; i < path_len; i++) + path[i] = i; + } + + /* update item mask for each type */ + st_form[HQA_SERV_RX_STAT_TYPE_BAND].item_mask = BIT(band_idx); + for (blk_idx = 0; blk_idx < path_len; blk_idx++) + st_form[HQA_SERV_RX_STAT_TYPE_PATH].item_mask |= + BIT(path[blk_idx]); + for (blk_idx = 0; blk_idx < HQA_USER_NUM; blk_idx++) + st_form[HQA_SERV_RX_STAT_TYPE_USER].item_mask |= + BIT(blk_idx); + st_form[HQA_SERV_RX_STAT_TYPE_COMM].item_mask = BIT(0); + + /* update block count for each type */ + for (type_idx = HQA_SERV_RX_STAT_TYPE_BAND; + type_idx < HQA_SERV_RX_STAT_TYPE_NUM; type_idx++) { + for (blk_idx = 0; blk_idx < 32; blk_idx++) { + if (st_form[type_idx].item_mask & BIT(blk_idx)) + st_form[type_idx].blk_cnt++; + } + } + + ptr = HqaCmdFrame->Data + 2 + sizeof(type_num); + + /* allocate dynamic memory for rx stat info */ + rx_stat = kalMemAlloc(sizeof(struct hqa_rx_stat_u), VIR_MEM_TYPE); + if (!rx_stat) { + i4Ret = WLAN_STATUS_RESOURCES; + goto error1; + } + + for (type_idx = HQA_SERV_RX_STAT_TYPE_BAND; + type_idx < HQA_SERV_RX_STAT_TYPE_NUM; type_idx++) { + if (type_mask & BIT(type_idx)) { + type_num++; + length = st_form[type_idx].blk_cnt * + st_form[type_idx].blk_size; + + /* fill in type */ + buf = htonl(st_form[type_idx].type); + kalMemMove(ptr, &buf, sizeof(buf)); + ptr += sizeof(st_form[type_idx].type); + buf_size += sizeof(st_form[type_idx].type); + + /* fill in version */ + buf = htonl(st_form[type_idx].version); + kalMemMove(ptr, &buf, sizeof(buf)); + ptr += sizeof(st_form[type_idx].version); + buf_size += sizeof(st_form[type_idx].version); + + /* fill in item mask */ + buf = htonl(st_form[type_idx].item_mask); + kalMemMove(ptr, &buf, sizeof(buf)); + ptr += sizeof(st_form[type_idx].item_mask); + buf_size += sizeof(st_form[type_idx].item_mask); + + /* fill in length */ + buf = htonl(length); + kalMemMove(ptr, &buf, sizeof(buf)); + ptr += sizeof(length); + buf_size += sizeof(length); + + for (blk_idx = 0; blk_idx < 32; blk_idx++) { + if (st_form[type_idx].item_mask + & BIT(blk_idx)) { + /* service handle for rx stat info */ + hqa_getRxStatisticsByType(prGlueInfo, + band_idx, + blk_idx, + type_idx, + rx_stat); + ptr2 = (u_int32_t *) rx_stat; + dw_cnt = st_form[type_idx].blk_size + >> 2; + for (dw_idx = 0; dw_idx < dw_cnt; + dw_idx++, ptr2++, + ptr += 4) { + /* endian transform */ + buf = htonl(*ptr2); + /* fill in block content */ + kalMemMove(ptr, &buf, + sizeof(buf)); + } + + buf_size += st_form[type_idx].blk_size; + } + } + } + } + + /* free allocated memory */ + kalMemFree(rx_stat, VIR_MEM_TYPE, sizeof(struct hqa_rx_stat_u)); + + /* fill in type num */ + ptr = HqaCmdFrame->Data + 2; + buf = htonl(type_num); + kalMemMove(ptr, &buf, sizeof(buf)); + buf_size += sizeof(type_num); + + ResponseToQA(HqaCmdFrame, prIwReqData, + (2 + buf_size), i4Ret); + + return i4Ret; + +error1: + DBGLOG(RFTEST, INFO, "memory allocation fail for rx stat."); + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + return i4Ret; + +error2: + DBGLOG(RFTEST, INFO, "invalid band index for non-dbdc mode\n"); + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_MPSSetNss(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t *mps_setting = NULL; + uint32_t u4Band_idx = 0; + uint32_t u4Offset = 0; + uint32_t u4Len = 0; + uint32_t i = 0; + uint32_t u4Value = 0; + + u4Len = ntohs(HqaCmdFrame->Length) / sizeof(uint32_t) - 1; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_MPSSetNss u4Len : %d\n", + u4Len); + + mps_setting = kmalloc(sizeof(uint32_t) * (u4Len), + GFP_KERNEL); + ASSERT(mps_setting); + + memcpy(&u4Band_idx, HqaCmdFrame->Data + 4 * 0, 4); + u4Band_idx = ntohl(u4Band_idx); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_MPSSetNss u4Band_idx : %d\n", u4Band_idx); + + for (i = 0; i < u4Len; i++) { + u4Offset = 4 + 4 * i; + /* Reserved at least 4 byte availbale data */ + if (u4Offset + 4 > sizeof(HqaCmdFrame->Data)) + break; + memcpy(&u4Value, HqaCmdFrame->Data + 4 + 4 * i, 4); + mps_setting[i] = ntohl(u4Value); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_MPSSetNss mps_setting Case %d (Nss : %d)\n", + i, mps_setting[i]); + } + + i4Ret = MT_ATEMPSSetNss(prNetDev, u4Len, mps_setting, + u4Band_idx); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + kfree(mps_setting); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_MPSSetPerpacketBW( + struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t *mps_setting = NULL; + uint32_t u4Band_idx = 0; + uint32_t u4Offset = 0; + uint32_t u4Len = 0; + uint32_t i = 0; + uint32_t u4Value = 0; + + u4Len = ntohs(HqaCmdFrame->Length) / sizeof(uint32_t) - 1; + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_MPSSetPerpacketBW u4Len : %d\n", u4Len); + + mps_setting = kmalloc(sizeof(uint32_t) * (u4Len), + GFP_KERNEL); + ASSERT(mps_setting); + + memcpy(&u4Band_idx, HqaCmdFrame->Data + 4 * 0, 4); + u4Band_idx = ntohl(u4Band_idx); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_MPSSetPerpacketBW u4Band_idx : %d\n", + u4Band_idx); + + for (i = 0 ; i < u4Len ; i++) { + u4Offset = 4 + 4 * i; + /* Reserved at least 4 byte availbale data */ + if (u4Offset + 4 > sizeof(HqaCmdFrame->Data)) + break; + memcpy(&u4Value, HqaCmdFrame->Data + 4 + 4 * i, 4); + mps_setting[i] = ntohl(u4Value); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_MPSSetPerpacketBW mps_setting Case %d (BW : %d)\n", + i, mps_setting[i]); + } + + i4Ret = MT_ATEMPSSetPerpacketBW(prNetDev, u4Len, + mps_setting, u4Band_idx); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + kfree(mps_setting); + + return i4Ret; +} + + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_SetAIFS(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t SlotTime = 0; + uint32_t SifsTime = 0; + + memcpy(&SlotTime, HqaCmdFrame->Data + 4 * 0, 4); + SlotTime = ntohl(SlotTime); + memcpy(&SifsTime, HqaCmdFrame->Data + 4 * 1, 4); + SifsTime = ntohl(SifsTime); + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_SetAIFS SlotTime = %d\n", + SlotTime); + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_SetAIFS SifsTime = %d\n", + SifsTime); + + i4Ret = MT_ATESetTxIPG(prNetDev, SifsTime); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_CheckEfuseModeType(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t Value = u4EepromMode; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_CheckEfuseModeType\n"); + + /* + * Value: + * 1 -> efuse Mode + * 2 -> flash Mode + * 3 -> eeprom Mode + * 4 -> bin Mode + */ + Value = ntohl(Value); + memcpy(HqaCmdFrame->Data + 2, &(Value), sizeof(Value)); + + ResponseToQA(HqaCmdFrame, prIwReqData, 6, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_CheckEfuseNativeModeType( + struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_CheckEfuseNativeModeType\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_SetBandMode(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t u4Band_mode = 0; + uint32_t u4Band_type = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + uint32_t u4BufLen = 0; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + memcpy((uint8_t *)&u4Band_mode, HqaCmdFrame->Data + 4 * 0, + 4); + u4Band_mode = ntohl(u4Band_mode); + memcpy((uint8_t *)&u4Band_type, HqaCmdFrame->Data + 4 * 1, + 4); + u4Band_type = ntohl(u4Band_type); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_SetBandMode u4Band_mode : %d\n", u4Band_mode); + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_SetBandMode u4Band_type : %d\n", u4Band_type); + + if (u4Band_mode == 2) + g_DBDCEnable = TRUE; + else if (u4Band_mode == 1) + g_DBDCEnable = FALSE; + + /* notifiy FW */ + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_DBDC_ENABLE; + if (g_DBDCEnable) + rRfATInfo.u4FuncData = 1; + else + rRfATInfo.u4FuncData = 0; + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_GetBandMode g_DBDCEnable = %d\n", + g_DBDCEnable); + + i4Ret = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Ret != WLAN_STATUS_SUCCESS) + return -EFAULT; + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_GetBandMode(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t u4Band_mode = 0; + uint32_t u4Band_idx = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + uint32_t u4BufLen = 0; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + memcpy((uint8_t *)&u4Band_idx, HqaCmdFrame->Data, 4); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_GetBandMode u4Band_idx : %d\n", u4Band_idx); + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_DBDC_ENABLE; + if (g_DBDCEnable) + rRfATInfo.u4FuncData = 1; + else + rRfATInfo.u4FuncData = 0; + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_GetBandMode g_DBDCEnable = %d\n", + g_DBDCEnable); + + i4Ret = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Ret != WLAN_STATUS_SUCCESS) + return -EFAULT; + + if (u4Band_idx == 0) { + u4Band_mode = 3; + } else { + if (g_DBDCEnable) + u4Band_mode = 3; + else + u4Band_mode = 0; + } + + u4Band_mode = ntohl(u4Band_mode); + + memcpy(HqaCmdFrame->Data + 2, &(u4Band_mode), + sizeof(u4Band_mode)); + + ResponseToQA(HqaCmdFrame, prIwReqData, + 2 + sizeof(u4Band_mode), i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_RDDStartExt(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_RDDStartExt\n"); + + DBGLOG(RFTEST, INFO, "[RDD DUMP START]\n"); + + i4Ret = MT_ATERDDStart(prNetDev, "RDDSTART"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_RDDStopExt(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_RDDStopExt\n"); + + i4Ret = MT_ATERDDStop(prNetDev, "RDDSTOP"); + + DBGLOG(RFTEST, INFO, "[RDD DUMP END]\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_BssInfoUpdate(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t OwnMacIdx = 0, BssIdx = 0; + uint8_t ucAddr1[MAC_ADDR_LEN]; + uint8_t *prInBuf; + + prInBuf = kmalloc(sizeof(uint8_t) * (HQA_BF_STR_SIZE), + GFP_KERNEL); + ASSERT(prInBuf); + + memcpy(&OwnMacIdx, HqaCmdFrame->Data + 4 * 0, 4); + OwnMacIdx = ntohl(OwnMacIdx); + memcpy(&BssIdx, HqaCmdFrame->Data + 4 * 1, 4); + BssIdx = ntohl(BssIdx); + memcpy(ucAddr1, HqaCmdFrame->Data + 4 * 2, 6); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_BssInfoUpdate OwnMacIdx : %d\n", OwnMacIdx); + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_BssInfoUpdate BssIdx : %d\n", BssIdx); + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_BssInfoUpdate addr1:%02x:%02x:%02x:%02x:%02x:%02x\n", + ucAddr1[0], ucAddr1[1], ucAddr1[2], ucAddr1[3], ucAddr1[4], + ucAddr1[5]); + + kalMemSet(prInBuf, 0, sizeof(uint8_t) * (HQA_BF_STR_SIZE)); + kalSprintf(prInBuf, + "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", + OwnMacIdx, BssIdx, ucAddr1[0], ucAddr1[1], ucAddr1[2], + ucAddr1[3], ucAddr1[4], ucAddr1[5]); + + DBGLOG(RFTEST, ERROR, "prInBuf = %s\n", prInBuf); + + i4Ret = Set_BssInfoUpdate(prNetDev, prInBuf); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + kfree(prInBuf); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_DevInfoUpdate(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t Band = 0, OwnMacIdx = 0; + uint8_t ucAddr1[MAC_ADDR_LEN]; + uint8_t *prInBuf; + + prInBuf = kmalloc(sizeof(uint8_t) * (HQA_BF_STR_SIZE), + GFP_KERNEL); + ASSERT(prInBuf); + + memcpy(&Band, HqaCmdFrame->Data + 4 * 0, 4); + Band = ntohl(Band); + memcpy(&OwnMacIdx, HqaCmdFrame->Data + 4 * 1, 4); + OwnMacIdx = ntohl(OwnMacIdx); + memcpy(ucAddr1, HqaCmdFrame->Data + 4 * 2, 6); + + DBGLOG(RFTEST, INFO, "Band : %d, OwnMacIdx : %d\n", Band, OwnMacIdx); + DBGLOG(RFTEST, INFO, "addr1:%02x:%02x:%02x:%02x:%02x:%02x\n", + ucAddr1[0], ucAddr1[1], ucAddr1[2], + ucAddr1[3], ucAddr1[4], ucAddr1[5]); + + kalMemSet(prInBuf, 0, sizeof(uint8_t) * (HQA_BF_STR_SIZE)); + kalSprintf(prInBuf, + "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", + OwnMacIdx, ucAddr1[0], ucAddr1[1], ucAddr1[2], ucAddr1[3], + ucAddr1[4], ucAddr1[5], Band); + + DBGLOG(RFTEST, ERROR, "prInBuf = %s\n", prInBuf); + + i4Ret = Set_DevInfoUpdate(prNetDev, prInBuf); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + kfree(prInBuf); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_LogOnOff(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t u4Band_idx = 0; + uint32_t u4Log_type = 0; + uint32_t u4Log_ctrl = 0; + uint32_t u4Log_size = 200; + + memcpy(&u4Band_idx, HqaCmdFrame->Data, 4); + u4Band_idx = ntohl(u4Band_idx); + memcpy(&u4Log_type, HqaCmdFrame->Data + 4, 4); + u4Log_type = ntohl(u4Log_type); + memcpy(&u4Log_ctrl, HqaCmdFrame->Data + 4 + 4, 4); + u4Log_ctrl = ntohl(u4Log_ctrl); + memcpy(&u4Log_size, HqaCmdFrame->Data + 4 + 4 + 4, 4); + u4Log_size = ntohl(u4Log_size); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_LogOnOff band_idx : %d\n", u4Band_idx); + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_LogOnOff log_type : %d\n", u4Log_type); + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_LogOnOff log_ctrl : %d\n", u4Log_ctrl); + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_LogOnOff log_size : %d\n", u4Log_size); + + i4Ret = MT_ATELogOnOff(prNetDev, u4Log_type, u4Log_ctrl, + u4Log_size); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + + +static int32_t HQA_GetDumpRecal(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + struct RECAL_INFO_T *prReCalInfo = NULL; + struct RECAL_DATA_T *prCalArray = NULL; + uint32_t i = 0, u4Value = 0, u4RespLen = 0; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + ASSERT(prGlueInfo); + prAdapter = prGlueInfo->prAdapter; + ASSERT(prAdapter); + prReCalInfo = &prAdapter->rReCalInfo; + prCalArray = prReCalInfo->prCalArray; + + DBGLOG(RFTEST, INFO, "prReCalInfo->u4Count = [%d]\n", + prReCalInfo->u4Count); + if (prReCalInfo->u4Count > 0) { + for (i = 0; i < prReCalInfo->u4Count; i++) { + u4Value = ntohl(prCalArray[i].u4CalId); + kalMemCopy(HqaCmdFrame->Data + 6 + u4RespLen, + &u4Value, + sizeof(u4Value)); + u4RespLen += sizeof(u4Value); + + u4Value = ntohl(prCalArray[i].u4CalAddr); + DBGLOG(RFTEST, INFO, "CalAddr[%d] = [0x%08x]\n", + i, prCalArray[i].u4CalAddr); + kalMemCopy(HqaCmdFrame->Data + 6 + u4RespLen, + &u4Value, + sizeof(u4Value)); + u4RespLen += sizeof(u4Value); + + u4Value = ntohl(prCalArray[i].u4CalValue); + kalMemCopy(HqaCmdFrame->Data + 6 + u4RespLen, + &u4Value, + sizeof(u4Value)); + u4RespLen += sizeof(u4Value); + } + + u4Value = ntohl(prReCalInfo->u4Count); + kalMemCopy(HqaCmdFrame->Data + 2, &u4Value, sizeof(u4Value)); + ResponseToQA(HqaCmdFrame, + prIwReqData, + 6 + prReCalInfo->u4Count * 12, + 0); + } else { + kalMemCopy(HqaCmdFrame->Data + 2, &prReCalInfo->u4Count, 4); + ResponseToQA(HqaCmdFrame, prIwReqData, 6, 0); + } + + /* free resources */ + if (prReCalInfo->prCalArray != NULL) { + kalMemFree(prReCalInfo->prCalArray, + VIR_MEM_TYPE, + 2048 * sizeof(struct RECAL_DATA_T)); + prReCalInfo->prCalArray = 0; + prReCalInfo->u4Count = 0; + } + + return 0; +} + +static int32_t HQA_GetDumpRXV(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Count = 0, i4Ret = 0; + + i4Ret = MT_ATEGetDumpRXV(prNetDev, HqaCmdFrame->Data, &i4Count); + ResponseToQA(HqaCmdFrame, prIwReqData, 6 + i4Count, i4Ret); + return i4Ret; +} + +static HQA_CMD_HANDLER HQA_ReCal_CMDS[] = { + HQA_GetDumpRecal, /*0x1581 */ +}; + +static HQA_CMD_HANDLER HQA_RXV_CMDS[] = { + HQA_GetDumpRXV, /* 0x1581 */ +}; + + +static HQA_CMD_HANDLER HQA_CMD_SET5[] = { + /* cmd id start from 0x1500 */ + HQA_GetFWInfo, /* 0x1500 */ + HQA_StartContinousTx, /* 0x1501 */ + HQA_SetSTBC, /* 0x1502 */ + HQA_SetShortGI, /* 0x1503 */ + HQA_SetDPD, /* 0x1504 */ + HQA_SetTssiOnOff, /* 0x1505 */ + HQA_GetRxStatisticsAll, /* 0x1506 */ + HQA_StartContiTxTone, /* 0x1507 */ + HQA_StopContiTxTone, /* 0x1508 */ + HQA_CalibrationTestMode, /* 0x1509 */ + HQA_DoCalibrationTestItem, /* 0x150A */ + HQA_eFusePhysicalWrite, /* 0x150B */ + HQA_eFusePhysicalRead, /* 0x150C */ + HQA_eFuseLogicalRead, /* 0x150D */ + HQA_eFuseLogicalWrite, /* 0x150E */ + HQA_TMRSetting, /* 0x150F */ + HQA_GetRxSNR, /* 0x1510 */ + HQA_WriteBufferDone, /* 0x1511 */ + HQA_FFT, /* 0x1512 */ + HQA_SetTxTonePower, /* 0x1513 */ + HQA_GetChipID, /* 0x1514 */ + HQA_MPSSetSeqData, /* 0x1515 */ + HQA_MPSSetPayloadLength, /* 0x1516 */ + HQA_MPSSetPacketCount, /* 0x1517 */ + HQA_MPSSetPowerGain, /* 0x1518 */ + HQA_MPSStart, /* 0x1519 */ + HQA_MPSStop, /* 0x151A */ + ToDoFunction, /* 0x151B */ + HQA_GetRxStatisticsAllV2, /* 0x151C */ + ToDoFunction, /* 0x151D */ + ToDoFunction, /* 0x151E */ + ToDoFunction, /* 0x151F */ + ToDoFunction, /* 0x1520 */ + HQA_SetAIFS, /* 0x1521 */ + HQA_CheckEfuseModeType, /* 0x1522 */ + HQA_CheckEfuseNativeModeType, /* 0x1523 */ + ToDoFunction, /* 0x1524 */ + ToDoFunction, /* 0x1525 */ + ToDoFunction, /* 0x1526 */ + ToDoFunction, /* 0x1527 */ + ToDoFunction, /* 0x1528 */ + ToDoFunction, /* 0x1529 */ + ToDoFunction, /* 0x152A */ + ToDoFunction, /* 0x152B */ + HQA_SetBandMode, /* 0x152C */ + HQA_GetBandMode, /* 0x152D */ + HQA_RDDStartExt, /* 0x152E */ + HQA_RDDStopExt, /* 0x152F */ + ToDoFunction, /* 0x1530 */ + HQA_BssInfoUpdate, /* 0x1531 */ + HQA_DevInfoUpdate, /* 0x1532 */ + HQA_LogOnOff, /* 0x1533 */ + ToDoFunction, /* 0x1534 */ + ToDoFunction, /* 0x1535 */ + HQA_MPSSetNss, /* 0x1536 */ + HQA_MPSSetPerpacketBW, /* 0x1537 */ +}; + +#if CFG_SUPPORT_TX_BF +static int32_t HQA_TxBfProfileTagInValid(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t invalid = 0; + uint8_t *prInBuf; + + prInBuf = kmalloc(sizeof(invalid), GFP_KERNEL); + ASSERT(prInBuf); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_TxBfProfileTagInValid\n"); + + memcpy(&invalid, HqaCmdFrame->Data, 4); + invalid = ntohl(invalid); + + kalMemSet(prInBuf, 0, sizeof(invalid)); + kalSprintf(prInBuf, "%u", invalid); + + DBGLOG(RFTEST, ERROR, "prInBuf = %s\n", prInBuf); + + i4Ret = Set_TxBfProfileTag_InValid(prNetDev, prInBuf); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + kfree(prInBuf); + + return i4Ret; +} + +static int32_t HQA_TxBfProfileTagPfmuIdx(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t pfmuidx = 0; + uint8_t *prInBuf; + + prInBuf = kmalloc(sizeof(pfmuidx), GFP_KERNEL); + ASSERT(prInBuf); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_TxBfProfileTagPfmuIdx\n"); + + memcpy(&pfmuidx, HqaCmdFrame->Data, 4); + pfmuidx = ntohl(pfmuidx); + + kalMemSet(prInBuf, 0, sizeof(pfmuidx)); + kalSprintf(prInBuf, "%u", pfmuidx); + + DBGLOG(RFTEST, ERROR, "prInBuf = %s\n", prInBuf); + + i4Ret = Set_TxBfProfileTag_PfmuIdx(prNetDev, prInBuf); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + kfree(prInBuf); + + return i4Ret; +} + +static int32_t HQA_TxBfProfileTagBfType(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t bftype = 0; + uint8_t *prInBuf; + + prInBuf = kmalloc(sizeof(bftype), GFP_KERNEL); + ASSERT(prInBuf); + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_TxBfProfileTagBfType\n"); + + memcpy(&bftype, HqaCmdFrame->Data, 4); + bftype = ntohl(bftype); + + kalMemSet(prInBuf, 0, sizeof(bftype)); + kalSprintf(prInBuf, "%u", bftype); + + DBGLOG(RFTEST, ERROR, "prInBuf = %s\n", prInBuf); + + i4Ret = Set_TxBfProfileTag_BfType(prNetDev, prInBuf); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + kfree(prInBuf); + + return i4Ret; +} + +static int32_t HQA_TxBfProfileTagBw(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t tag_bw = 0; + uint8_t *prInBuf; + + prInBuf = kmalloc(sizeof(tag_bw), GFP_KERNEL); + ASSERT(prInBuf); + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_TxBfProfileTagBw\n"); + + memcpy(&tag_bw, HqaCmdFrame->Data, 4); + tag_bw = ntohl(tag_bw); + + kalMemSet(prInBuf, 0, sizeof(tag_bw)); + kalSprintf(prInBuf, "%u", tag_bw); + + DBGLOG(RFTEST, ERROR, "prInBuf = %s\n", prInBuf); + + i4Ret = Set_TxBfProfileTag_DBW(prNetDev, prInBuf); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + kfree(prInBuf); + + return i4Ret; +} + +static int32_t HQA_TxBfProfileTagSuMu(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t su_mu = 0; + uint8_t *prInBuf; + + prInBuf = kmalloc(sizeof(su_mu), GFP_KERNEL); + ASSERT(prInBuf); + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_TxBfProfileTagSuMu\n"); + + memcpy(&su_mu, HqaCmdFrame->Data, 4); + su_mu = ntohl(su_mu); + + kalMemSet(prInBuf, 0, sizeof(su_mu)); + kalSprintf(prInBuf, "%u", su_mu); + + DBGLOG(RFTEST, ERROR, "prInBuf = %s\n", prInBuf); + + i4Ret = Set_TxBfProfileTag_SuMu(prNetDev, prInBuf); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + kfree(prInBuf); + + return i4Ret; +} + +static int32_t HQA_TxBfProfileTagMemAlloc( + struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t col_idx0, row_idx0, col_idx1, row_idx1; + uint32_t col_idx2, row_idx2, col_idx3, row_idx3; + uint8_t *prInBuf; + + prInBuf = kmalloc(sizeof(uint8_t) * (HQA_BF_STR_SIZE), + GFP_KERNEL); + ASSERT(prInBuf); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_TxBfProfileTagMemAlloc\n"); + + memcpy(&col_idx0, HqaCmdFrame->Data + 4 * 0, 4); + col_idx0 = ntohl(col_idx0); + memcpy(&row_idx0, HqaCmdFrame->Data + 4 * 1, 4); + row_idx0 = ntohl(row_idx0); + memcpy(&col_idx1, HqaCmdFrame->Data + 4 * 2, 4); + col_idx1 = ntohl(col_idx1); + memcpy(&row_idx1, HqaCmdFrame->Data + 4 * 3, 4); + row_idx1 = ntohl(row_idx1); + memcpy(&col_idx2, HqaCmdFrame->Data + 4 * 4, 4); + col_idx2 = ntohl(col_idx2); + memcpy(&row_idx2, HqaCmdFrame->Data + 4 * 5, 4); + row_idx2 = ntohl(row_idx2); + memcpy(&col_idx3, HqaCmdFrame->Data + 4 * 6, 4); + col_idx3 = ntohl(col_idx3); + memcpy(&row_idx3, HqaCmdFrame->Data + 4 * 7, 4); + row_idx3 = ntohl(row_idx3); + + kalMemSet(prInBuf, 0, sizeof(uint8_t) * (HQA_BF_STR_SIZE)); + kalSprintf(prInBuf, + "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", + col_idx0, row_idx0, col_idx1, row_idx1, col_idx2, row_idx2, + col_idx3, row_idx3); + + DBGLOG(RFTEST, ERROR, "prInBuf = %s\n", prInBuf); + + i4Ret = Set_TxBfProfileTag_Mem(prNetDev, prInBuf); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + kfree(prInBuf); + + return i4Ret; +} + +static int32_t HQA_TxBfProfileTagMatrix(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t nrow, ncol, ngroup, LM, code_book, htc_exist; + uint8_t *prInBuf; + + prInBuf = kmalloc(sizeof(uint8_t) * (HQA_BF_STR_SIZE), + GFP_KERNEL); + ASSERT(prInBuf); + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_TxBfProfileTagMatrix\n"); + + memcpy(&nrow, HqaCmdFrame->Data + 4 * 0, 4); + nrow = ntohl(nrow); + memcpy(&ncol, HqaCmdFrame->Data + 4 * 1, 4); + ncol = ntohl(ncol); + memcpy(&ngroup, HqaCmdFrame->Data + 4 * 2, 4); + ngroup = ntohl(ngroup); + memcpy(&LM, HqaCmdFrame->Data + 4 * 3, 4); + LM = ntohl(LM); + memcpy(&code_book, HqaCmdFrame->Data + 4 * 4, 4); + code_book = ntohl(code_book); + memcpy(&htc_exist, HqaCmdFrame->Data + 4 * 5, 4); + htc_exist = ntohl(htc_exist); + + kalMemSet(prInBuf, 0, sizeof(uint8_t) * (HQA_BF_STR_SIZE)); + kalSprintf(prInBuf, "%02x:%02x:%02x:%02x:%02x:%02x", nrow, + ncol, ngroup, LM, code_book, htc_exist); + + DBGLOG(RFTEST, ERROR, "prInBuf = %s\n", prInBuf); + + i4Ret = Set_TxBfProfileTag_Matrix(prNetDev, prInBuf); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + kfree(prInBuf); + + return i4Ret; +} + +static int32_t HQA_TxBfProfileTagSnr(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t snr_sts0, snr_sts1, snr_sts2, snr_sts3; + uint8_t *prInBuf; + + prInBuf = kmalloc(sizeof(uint8_t) * (HQA_BF_STR_SIZE), + GFP_KERNEL); + ASSERT(prInBuf); + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_TxBfProfileTagSnr\n"); + + memcpy(&snr_sts0, HqaCmdFrame->Data + 4 * 0, 4); + snr_sts0 = ntohl(snr_sts0); + memcpy(&snr_sts1, HqaCmdFrame->Data + 4 * 1, 4); + snr_sts1 = ntohl(snr_sts1); + memcpy(&snr_sts2, HqaCmdFrame->Data + 4 * 2, 4); + snr_sts2 = ntohl(snr_sts2); + memcpy(&snr_sts3, HqaCmdFrame->Data + 4 * 3, 4); + snr_sts3 = ntohl(snr_sts3); + + kalMemSet(prInBuf, 0, sizeof(uint8_t) * (HQA_BF_STR_SIZE)); + kalSprintf(prInBuf, "%02x:%02x:%02x:%02x", snr_sts0, + snr_sts1, snr_sts2, snr_sts3); + + DBGLOG(RFTEST, ERROR, "prInBuf = %s\n", prInBuf); + + i4Ret = Set_TxBfProfileTag_SNR(prNetDev, prInBuf); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + kfree(prInBuf); + + return i4Ret; +} + +static int32_t HQA_TxBfProfileTagSmtAnt(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t smt_ant = 0; + uint8_t *prInBuf; + + prInBuf = kmalloc(sizeof(smt_ant), GFP_KERNEL); + ASSERT(prInBuf); + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_TxBfProfileTagSmtAnt\n"); + + memcpy(&smt_ant, HqaCmdFrame->Data + 4 * 0, 4); + smt_ant = ntohl(smt_ant); + + kalMemSet(prInBuf, 0, sizeof(smt_ant)); + kalSprintf(prInBuf, "%u", smt_ant); + + DBGLOG(RFTEST, ERROR, "prInBuf = %s\n", prInBuf); + + i4Ret = Set_TxBfProfileTag_SmartAnt(prNetDev, prInBuf); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + kfree(prInBuf); + + return i4Ret; +} + +static int32_t HQA_TxBfProfileTagSeIdx(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t se_idx = 0; + uint8_t *prInBuf; + + prInBuf = kmalloc(sizeof(se_idx), GFP_KERNEL); + ASSERT(prInBuf); + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_TxBfProfileTagSeIdx\n"); + + memcpy(&se_idx, HqaCmdFrame->Data + 4 * 0, 4); + se_idx = ntohl(se_idx); + + kalMemSet(prInBuf, 0, sizeof(se_idx)); + kalSprintf(prInBuf, "%u", se_idx); + + DBGLOG(RFTEST, ERROR, "prInBuf = %s\n", prInBuf); + + i4Ret = Set_TxBfProfileTag_SeIdx(prNetDev, prInBuf); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + kfree(prInBuf); + + return i4Ret; +} + +static int32_t HQA_TxBfProfileTagRmsdThrd( + struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t rmsd_thrd = 0; + uint8_t *prInBuf; + + prInBuf = kmalloc(sizeof(rmsd_thrd), GFP_KERNEL); + ASSERT(prInBuf); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_TxBfProfileTagRmsdThrd\n"); + + memcpy(&rmsd_thrd, HqaCmdFrame->Data + 4 * 0, 4); + rmsd_thrd = ntohl(rmsd_thrd); + + kalMemSet(prInBuf, 0, sizeof(rmsd_thrd)); + kalSprintf(prInBuf, "%u", rmsd_thrd); + + DBGLOG(RFTEST, ERROR, "prInBuf = %s\n", prInBuf); + + i4Ret = Set_TxBfProfileTag_RmsdThrd(prNetDev, prInBuf); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + kfree(prInBuf); + + return i4Ret; +} + +static int32_t HQA_TxBfProfileTagMcsThrd(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t mcs_lss0, mcs_sss0, mcs_lss1, mcs_sss1, mcs_lss2, + mcs_sss2; + uint8_t *prInBuf; + + prInBuf = kmalloc(sizeof(uint8_t) * (HQA_BF_STR_SIZE), + GFP_KERNEL); + ASSERT(prInBuf); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_TxBfProfileTagMcsThrd\n"); + + memcpy(&mcs_lss0, HqaCmdFrame->Data + 4 * 0, 4); + mcs_lss0 = ntohl(mcs_lss0); + memcpy(&mcs_sss0, HqaCmdFrame->Data + 4 * 1, 4); + mcs_sss0 = ntohl(mcs_sss0); + memcpy(&mcs_lss1, HqaCmdFrame->Data + 4 * 2, 4); + mcs_lss1 = ntohl(mcs_lss1); + memcpy(&mcs_sss1, HqaCmdFrame->Data + 4 * 3, 4); + mcs_sss1 = ntohl(mcs_sss1); + memcpy(&mcs_lss2, HqaCmdFrame->Data + 4 * 4, 4); + mcs_lss2 = ntohl(mcs_lss2); + memcpy(&mcs_sss2, HqaCmdFrame->Data + 4 * 5, 4); + mcs_sss2 = ntohl(mcs_sss2); + + kalMemSet(prInBuf, 0, sizeof(uint8_t) * (HQA_BF_STR_SIZE)); + kalSprintf(prInBuf, "%02x:%02x:%02x:%02x:%02x:%02x", + mcs_lss0, mcs_sss0, mcs_lss1, mcs_sss1, mcs_lss2, + mcs_sss2); + + DBGLOG(RFTEST, ERROR, "prInBuf = %s\n", prInBuf); + + i4Ret = Set_TxBfProfileTag_McsThrd(prNetDev, prInBuf); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + kfree(prInBuf); + + return i4Ret; +} + +static int32_t HQA_TxBfProfileTagTimeOut(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t bf_tout = 0; + uint8_t *prInBuf; + + prInBuf = kmalloc(sizeof(bf_tout), GFP_KERNEL); + ASSERT(prInBuf); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_TxBfProfileTagTimeOut\n"); + + memcpy(&bf_tout, HqaCmdFrame->Data + 4 * 0, 4); + bf_tout = ntohl(bf_tout); + + kalMemSet(prInBuf, 0, sizeof(bf_tout)); + kalSprintf(prInBuf, "%x", bf_tout); + + DBGLOG(RFTEST, ERROR, "prInBuf = %s\n", prInBuf); + + i4Ret = Set_TxBfProfileTag_TimeOut(prNetDev, prInBuf); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + kfree(prInBuf); + + return i4Ret; +} + +static int32_t HQA_TxBfProfileTagDesiredBw( + struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t desire_bw = 0; + uint8_t *prInBuf; + + prInBuf = kmalloc(sizeof(desire_bw), GFP_KERNEL); + ASSERT(prInBuf); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_TxBfProfileTagDesiredBw\n"); + + memcpy(&desire_bw, HqaCmdFrame->Data + 4 * 0, 4); + desire_bw = ntohl(desire_bw); + + kalMemSet(prInBuf, 0, sizeof(desire_bw)); + kalSprintf(prInBuf, "%u", desire_bw); + + DBGLOG(RFTEST, ERROR, "prInBuf = %s\n", prInBuf); + + i4Ret = Set_TxBfProfileTag_DesiredBW(prNetDev, prInBuf); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + kfree(prInBuf); + + return i4Ret; +} + +static int32_t HQA_TxBfProfileTagDesiredNc( + struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t desire_nc = 0; + uint8_t *prInBuf; + + prInBuf = kmalloc(sizeof(desire_nc), GFP_KERNEL); + ASSERT(prInBuf); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_TxBfProfileTagDesiredNc\n"); + + memcpy(&desire_nc, HqaCmdFrame->Data + 4 * 0, 4); + desire_nc = ntohl(desire_nc); + + kalMemSet(prInBuf, 0, sizeof(desire_nc)); + kalSprintf(prInBuf, "%u", desire_nc); + + DBGLOG(RFTEST, ERROR, "prInBuf = %s\n", prInBuf); + + i4Ret = Set_TxBfProfileTag_DesiredNc(prNetDev, prInBuf); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + kfree(prInBuf); + + return i4Ret; +} + +static int32_t HQA_TxBfProfileTagDesiredNr( + struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t desire_nr = 0; + uint8_t *prInBuf; + + prInBuf = kmalloc(sizeof(desire_nr), GFP_KERNEL); + ASSERT(prInBuf); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_TxBfProfileTagDesiredNr\n"); + + memcpy(&desire_nr, HqaCmdFrame->Data + 4 * 0, 4); + desire_nr = ntohl(desire_nr); + + kalMemSet(prInBuf, 0, sizeof(desire_nr)); + kalSprintf(prInBuf, "%u", desire_nr); + + DBGLOG(RFTEST, ERROR, "prInBuf = %s\n", prInBuf); + + i4Ret = Set_TxBfProfileTag_DesiredNr(prNetDev, prInBuf); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + kfree(prInBuf); + + return i4Ret; +} + +static int32_t HQA_TxBfProfileTagWrite(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t idx = 0; /* WLAN_IDX */ + uint8_t *prInBuf; + + prInBuf = kmalloc(sizeof(idx), GFP_KERNEL); + ASSERT(prInBuf); + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_TxBfProfileTagWrite\n"); + + memcpy(&idx, HqaCmdFrame->Data + 4 * 0, 4); + idx = ntohl(idx); + + kalMemSet(prInBuf, 0, sizeof(idx)); + kalSprintf(prInBuf, "%u", idx); + + DBGLOG(RFTEST, ERROR, "prInBuf = %s\n", prInBuf); + + i4Ret = Set_TxBfProfileTagWrite(prNetDev, prInBuf); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + kfree(prInBuf); + + return i4Ret; +} + +static int32_t HQA_TxBfProfileTagRead(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t idx = 0, isBFer = 0; + uint8_t *prInBuf; + union PFMU_PROFILE_TAG1 rPfmuTag1; + union PFMU_PROFILE_TAG2 rPfmuTag2; + + prInBuf = kmalloc(sizeof(uint8_t) * (HQA_BF_STR_SIZE), + GFP_KERNEL); + ASSERT(prInBuf); + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_TxBfProfileTagRead\n"); + + memcpy(&idx, HqaCmdFrame->Data + 4 * 0, 4); + idx = ntohl(idx); + memcpy(&isBFer, HqaCmdFrame->Data + 4 * 1, 4); + isBFer = ntohl(isBFer); + + kalMemSet(prInBuf, 0, sizeof(uint8_t) * (HQA_BF_STR_SIZE)); + kalSprintf(prInBuf, "%02x:%02x", idx, isBFer); + + DBGLOG(RFTEST, ERROR, "prInBuf = %s\n", prInBuf); + + i4Ret = Set_TxBfProfileTagRead(prNetDev, prInBuf); + + rPfmuTag1.au4RawData[0] = ntohl(g_rPfmuTag1.au4RawData[0]); + rPfmuTag1.au4RawData[1] = ntohl(g_rPfmuTag1.au4RawData[1]); + rPfmuTag1.au4RawData[2] = ntohl(g_rPfmuTag1.au4RawData[2]); + rPfmuTag1.au4RawData[3] = ntohl(g_rPfmuTag1.au4RawData[3]); + + rPfmuTag2.au4RawData[0] = ntohl(g_rPfmuTag2.au4RawData[0]); + rPfmuTag2.au4RawData[1] = ntohl(g_rPfmuTag2.au4RawData[1]); + rPfmuTag2.au4RawData[2] = ntohl(g_rPfmuTag2.au4RawData[2]); + + memcpy(HqaCmdFrame->Data + 2, &rPfmuTag1, + sizeof(union PFMU_PROFILE_TAG1)); + memcpy(HqaCmdFrame->Data + 2 + sizeof(union + PFMU_PROFILE_TAG1), &rPfmuTag2, + sizeof(union PFMU_PROFILE_TAG2)); + + ResponseToQA(HqaCmdFrame, prIwReqData, + 2 + sizeof(union PFMU_PROFILE_TAG1) + sizeof( + union PFMU_PROFILE_TAG2), i4Ret); + kfree(prInBuf); + + return i4Ret; +} + +static int32_t HQA_StaRecCmmUpdate(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t wlan_idx, bss_idx, aid; + uint8_t mac[MAC_ADDR_LEN]; + uint8_t *prInBuf; + + prInBuf = kmalloc(sizeof(uint8_t) * (HQA_BF_STR_SIZE), + GFP_KERNEL); + ASSERT(prInBuf); + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_StaRecCmmUpdate\n"); + + memcpy(&wlan_idx, HqaCmdFrame->Data + 4 * 0, 4); + wlan_idx = ntohl(wlan_idx); + memcpy(&bss_idx, HqaCmdFrame->Data + 4 * 1, 4); + bss_idx = ntohl(bss_idx); + memcpy(&aid, HqaCmdFrame->Data + 4 * 2, 4); + aid = ntohl(aid); + + memcpy(mac, HqaCmdFrame->Data + 4 * 3, 6); + + kalMemSet(prInBuf, 0, sizeof(uint8_t) * (HQA_BF_STR_SIZE)); + kalSprintf(prInBuf, + "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", + wlan_idx, bss_idx, aid, mac[0], mac[1], mac[2], mac[3], + mac[4], mac[5]); + + DBGLOG(RFTEST, ERROR, "prInBuf = %s\n", prInBuf); + + i4Ret = Set_StaRecCmmUpdate(prNetDev, prInBuf); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + kfree(prInBuf); + + return i4Ret; +} + +static int32_t HQA_StaRecBfUpdate(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t wlan_idx, bss_idx, PfmuId, su_mu, etxbf_cap, + ndpa_rate, ndp_rate; + uint32_t report_poll_rate, tx_mode, nc, nr, cbw, spe_idx, + tot_mem_req; + uint32_t mem_req_20m, mem_row0, mem_col0, mem_row1, + mem_col1; + uint32_t mem_row2, mem_col2, mem_row3, mem_col3; + uint8_t *prInBuf; + + prInBuf = kmalloc(sizeof(uint8_t) * (HQA_BF_STR_SIZE), + GFP_KERNEL); + ASSERT(prInBuf); + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_StaRecBfUpdate\n"); + + memcpy(&wlan_idx, HqaCmdFrame->Data + 4 * 0, 4); + wlan_idx = ntohl(wlan_idx); + memcpy(&bss_idx, HqaCmdFrame->Data + 4 * 1, 4); + bss_idx = ntohl(bss_idx); + memcpy(&PfmuId, HqaCmdFrame->Data + 4 * 2, 4); + PfmuId = ntohl(PfmuId); + memcpy(&su_mu, HqaCmdFrame->Data + 4 * 3, 4); + su_mu = ntohl(su_mu); + memcpy(&etxbf_cap, HqaCmdFrame->Data + 4 * 4, 4); + etxbf_cap = ntohl(etxbf_cap); + memcpy(&ndpa_rate, HqaCmdFrame->Data + 4 * 5, 4); + ndpa_rate = ntohl(ndpa_rate); + memcpy(&ndp_rate, HqaCmdFrame->Data + 4 * 6, 4); + ndp_rate = ntohl(ndp_rate); + memcpy(&report_poll_rate, HqaCmdFrame->Data + 4 * 7, 4); + report_poll_rate = ntohl(report_poll_rate); + memcpy(&tx_mode, HqaCmdFrame->Data + 4 * 8, 4); + tx_mode = ntohl(tx_mode); + memcpy(&nc, HqaCmdFrame->Data + 4 * 9, 4); + nc = ntohl(nc); + memcpy(&nr, HqaCmdFrame->Data + 4 * 10, 4); + nr = ntohl(nr); + memcpy(&cbw, HqaCmdFrame->Data + 4 * 11, 4); + cbw = ntohl(cbw); + memcpy(&spe_idx, HqaCmdFrame->Data + 4 * 12, 4); + spe_idx = ntohl(spe_idx); + memcpy(&tot_mem_req, HqaCmdFrame->Data + 4 * 13, 4); + tot_mem_req = ntohl(tot_mem_req); + memcpy(&mem_req_20m, HqaCmdFrame->Data + 4 * 14, 4); + mem_req_20m = ntohl(mem_req_20m); + memcpy(&mem_row0, HqaCmdFrame->Data + 4 * 15, 4); + mem_row0 = ntohl(mem_row0); + memcpy(&mem_col0, HqaCmdFrame->Data + 4 * 16, 4); + mem_col0 = ntohl(mem_col0); + memcpy(&mem_row1, HqaCmdFrame->Data + 4 * 17, 4); + mem_row1 = ntohl(mem_row1); + memcpy(&mem_col1, HqaCmdFrame->Data + 4 * 18, 4); + mem_col1 = ntohl(mem_col1); + memcpy(&mem_row2, HqaCmdFrame->Data + 4 * 19, 4); + mem_row2 = ntohl(mem_row2); + memcpy(&mem_col2, HqaCmdFrame->Data + 4 * 20, 4); + mem_col2 = ntohl(mem_col2); + memcpy(&mem_row3, HqaCmdFrame->Data + 4 * 21, 4); + mem_row3 = ntohl(mem_row3); + memcpy(&mem_col3, HqaCmdFrame->Data + 4 * 22, 4); + mem_col3 = ntohl(mem_col3); + + /* For Tool wrong memory row and col num 20160501 */ + if (PfmuId == 0) { + mem_row0 = 0; + mem_col0 = 0; + mem_row1 = 1; + mem_col1 = 0; + mem_row2 = 2; + mem_col2 = 0; + mem_row3 = 3; + mem_col3 = 0; + } else if (PfmuId == 1) { + mem_row0 = 0; + mem_col0 = 2; + mem_row1 = 1; + mem_col1 = 2; + mem_row2 = 2; + mem_col2 = 2; + mem_row3 = 3; + mem_col3 = 2; + } + + kalMemSet(prInBuf, 0, sizeof(uint8_t) * (HQA_BF_STR_SIZE)); + kalSprintf(prInBuf, + "%02x:%02x:%02x:%02x:%02x:%02d:%02d:%02d:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", + wlan_idx, bss_idx, PfmuId, su_mu, etxbf_cap, ndpa_rate, + ndp_rate, report_poll_rate, tx_mode, nc, nr, + cbw, spe_idx, tot_mem_req, mem_req_20m, mem_row0, mem_col0, + mem_row1, mem_col1, mem_row2, mem_col2, + mem_row3, mem_col3); + + DBGLOG(RFTEST, ERROR, "prInBuf = %s\n", prInBuf); + + i4Ret = Set_StaRecBfUpdate(prNetDev, prInBuf); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + kfree(prInBuf); + + return i4Ret; +} + +static int32_t HQA_BFProfileDataRead(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t idx = 0, fgBFer = 0, subcarrIdx = 0, + subcarr_start = 0, subcarr_end = 0; + uint32_t NumOfsub = 0; + uint32_t offset = 0; + uint8_t *SubIdx = NULL; + uint8_t *prInBuf; + union PFMU_DATA rPfmuData; + + prInBuf = kmalloc(sizeof(uint8_t) * (HQA_BF_STR_SIZE), + GFP_KERNEL); + ASSERT(prInBuf); + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_BFProfileDataRead\n"); + + memcpy(&idx, HqaCmdFrame->Data + 4 * 0, 4); + idx = ntohl(idx); + memcpy(&fgBFer, HqaCmdFrame->Data + 4 * 1, 4); + fgBFer = ntohl(fgBFer); + memcpy(&subcarr_start, HqaCmdFrame->Data + 4 * 2, 4); + subcarr_start = ntohl(subcarr_start); + memcpy(&subcarr_end, HqaCmdFrame->Data + 4 * 3, 4); + subcarr_end = ntohl(subcarr_end); + + NumOfsub = subcarr_end - subcarr_start + 1; + NumOfsub = ntohl(NumOfsub); + + memcpy(HqaCmdFrame->Data + 2, &NumOfsub, sizeof(NumOfsub)); + offset += sizeof(NumOfsub); + + for (subcarrIdx = subcarr_start; subcarrIdx <= subcarr_end; + subcarrIdx++) { + SubIdx = (uint8_t *) &subcarrIdx; + + kalMemSet(prInBuf, 0, sizeof(uint8_t) * (HQA_BF_STR_SIZE)); + kalSprintf(prInBuf, "%02x:%02x:%02x:%02x", idx, fgBFer, + SubIdx[1], SubIdx[0]); + + DBGLOG(RFTEST, ERROR, "prInBuf = %s\n", prInBuf); + + i4Ret = Set_TxBfProfileDataRead(prNetDev, prInBuf); + + rPfmuData.au4RawData[0] = ntohl(g_rPfmuData.au4RawData[0]); + rPfmuData.au4RawData[1] = ntohl(g_rPfmuData.au4RawData[1]); + rPfmuData.au4RawData[2] = ntohl(g_rPfmuData.au4RawData[2]); + rPfmuData.au4RawData[3] = ntohl(g_rPfmuData.au4RawData[3]); + rPfmuData.au4RawData[4] = ntohl(g_rPfmuData.au4RawData[4]); + + memcpy(HqaCmdFrame->Data + 2 + offset, &rPfmuData, + sizeof(rPfmuData)); + offset += sizeof(rPfmuData); + } + + ResponseToQA(HqaCmdFrame, prIwReqData, 2 + offset, i4Ret); + kfree(prInBuf); + + return i4Ret; +} + +static int32_t HQA_BFProfileDataWrite(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t pfmuid, subcarrier, phi11, psi21, phi21, psi31, + phi31, psi41; + uint32_t phi22, psi32, phi32, psi42, phi33, psi43, snr00, + snr01, snr02, snr03; + uint8_t *prInBuf; + + prInBuf = kmalloc(sizeof(uint8_t) * (HQA_BF_STR_SIZE), + GFP_KERNEL); + ASSERT(prInBuf); + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_BFProfileDataWrite\n"); + + memcpy(&pfmuid, HqaCmdFrame->Data + 4 * 0, 4); + pfmuid = ntohl(pfmuid); + memcpy(&subcarrier, HqaCmdFrame->Data + 4 * 1, 4); + subcarrier = ntohl(subcarrier); + memcpy(&phi11, HqaCmdFrame->Data + 4 * 2, 4); + phi11 = ntohl(phi11); + memcpy(&psi21, HqaCmdFrame->Data + 4 * 3, 4); + psi21 = ntohl(psi21); + memcpy(&phi21, HqaCmdFrame->Data + 4 * 4, 4); + phi21 = ntohl(phi21); + memcpy(&psi31, HqaCmdFrame->Data + 4 * 5, 4); + psi31 = ntohl(psi31); + memcpy(&phi31, HqaCmdFrame->Data + 4 * 6, 4); + phi31 = ntohl(phi31); + memcpy(&psi41, HqaCmdFrame->Data + 4 * 7, 4); + psi41 = ntohl(psi41); + memcpy(&phi22, HqaCmdFrame->Data + 4 * 8, 4); + phi22 = ntohl(phi22); + memcpy(&psi32, HqaCmdFrame->Data + 4 * 9, 4); + psi32 = ntohl(psi32); + memcpy(&phi32, HqaCmdFrame->Data + 4 * 10, 4); + phi32 = ntohl(phi32); + memcpy(&psi42, HqaCmdFrame->Data + 4 * 11, 4); + psi42 = ntohl(psi42); + memcpy(&phi33, HqaCmdFrame->Data + 4 * 12, 4); + phi33 = ntohl(phi33); + memcpy(&psi43, HqaCmdFrame->Data + 4 * 13, 4); + psi43 = ntohl(psi43); + memcpy(&snr00, HqaCmdFrame->Data + 4 * 14, 4); + snr00 = ntohl(snr00); + memcpy(&snr01, HqaCmdFrame->Data + 4 * 15, 4); + snr01 = ntohl(snr01); + memcpy(&snr02, HqaCmdFrame->Data + 4 * 16, 4); + snr02 = ntohl(snr02); + memcpy(&snr03, HqaCmdFrame->Data + 4 * 17, 4); + snr03 = ntohl(snr03); + + kalMemSet(prInBuf, 0, sizeof(uint8_t) * (HQA_BF_STR_SIZE)); + kalSprintf(prInBuf, + "%02x:%03x:%03x:%02x:%03x:%02x:%03x:%02x:%03x:%02x:%03x:%02x:%03x:%02x:%02x:%02x:%02x:%02x", + pfmuid, subcarrier, phi11, psi21, phi21, psi31, phi31, + psi41, + phi22, psi32, phi32, psi42, phi33, psi43, snr00, snr01, + snr02, snr03); + + DBGLOG(RFTEST, ERROR, "prInBuf = %s\n", prInBuf); + + i4Ret = Set_TxBfProfileDataWrite(prNetDev, prInBuf); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + kfree(prInBuf); + + return i4Ret; +} + +static int32_t HQA_BFSounding(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t su_mu, mu_num, snd_interval, wlan_id0; + uint32_t wlan_id1, wlan_id2, wlan_id3, band_idx; + uint8_t *prInBuf; + + prInBuf = kmalloc(sizeof(uint8_t) * (HQA_BF_STR_SIZE), + GFP_KERNEL); + ASSERT(prInBuf); + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_BFSounding\n"); + + memcpy(&su_mu, HqaCmdFrame->Data + 4 * 0, 4); + su_mu = ntohl(su_mu); + memcpy(&mu_num, HqaCmdFrame->Data + 4 * 1, 4); + mu_num = ntohl(mu_num); + memcpy(&snd_interval, HqaCmdFrame->Data + 4 * 2, 4); + snd_interval = ntohl(snd_interval); + memcpy(&wlan_id0, HqaCmdFrame->Data + 4 * 3, 4); + wlan_id0 = ntohl(wlan_id0); + memcpy(&wlan_id1, HqaCmdFrame->Data + 4 * 4, 4); + wlan_id1 = ntohl(wlan_id1); + memcpy(&wlan_id2, HqaCmdFrame->Data + 4 * 5, 4); + wlan_id2 = ntohl(wlan_id2); + memcpy(&wlan_id3, HqaCmdFrame->Data + 4 * 6, 4); + wlan_id3 = ntohl(wlan_id3); + memcpy(&band_idx, HqaCmdFrame->Data + 4 * 7, 4); + band_idx = ntohl(band_idx); + + kalMemSet(prInBuf, 0, sizeof(uint8_t) * (HQA_BF_STR_SIZE)); + kalSprintf(prInBuf, "%02x:%02x:%02x:%02x:%02x:%02x:%02x", + su_mu, mu_num, snd_interval, wlan_id0, wlan_id1, wlan_id2, + wlan_id3); + + DBGLOG(RFTEST, ERROR, "prInBuf = %s\n", prInBuf); + + i4Ret = Set_Trigger_Sounding_Proc(prNetDev, prInBuf); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + kfree(prInBuf); + + return i4Ret; +} + +static int32_t HQA_TXBFSoundingStop(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_TXBFSoundingStop\n"); + + i4Ret = Set_Stop_Sounding_Proc(prNetDev, NULL); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +static int32_t HQA_TXBFProfileDataWriteAllExt( + struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +static int32_t HQA_TxBfTxApply(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t eBF_enable = 0; + uint32_t iBF_enable = 0; + uint32_t wlan_id = 0; + uint32_t MuTx_enable = 0; + uint8_t *prInBuf; + + prInBuf = kmalloc(sizeof(uint8_t) * (HQA_BF_STR_SIZE), + GFP_KERNEL); + ASSERT(prInBuf); + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_TxBfTxApply\n"); + + memcpy(&eBF_enable, HqaCmdFrame->Data + 4 * 0, 4); + eBF_enable = ntohl(eBF_enable); + memcpy(&iBF_enable, HqaCmdFrame->Data + 4 * 1, 4); + iBF_enable = ntohl(iBF_enable); + memcpy(&wlan_id, HqaCmdFrame->Data + 4 * 2, 4); + wlan_id = ntohl(wlan_id); + memcpy(&MuTx_enable, HqaCmdFrame->Data + 4 * 3, 4); + MuTx_enable = ntohl(MuTx_enable); + + kalMemSet(prInBuf, 0, sizeof(uint8_t) * (HQA_BF_STR_SIZE)); + kalSprintf(prInBuf, "%02x:%02x:%02x:%02x", wlan_id, + eBF_enable, iBF_enable, MuTx_enable); + + DBGLOG(RFTEST, ERROR, "prInBuf = %s\n", prInBuf); + + i4Ret = Set_TxBfTxApply(prNetDev, prInBuf); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + kfree(prInBuf); + + return i4Ret; +} + +static int32_t HQA_ManualAssoc(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t type; + uint32_t wtbl_idx; + uint32_t ownmac_idx; + uint32_t phymode; + uint32_t bw; + uint32_t pfmuid; + uint32_t marate_mode; + uint32_t marate_mcs; + uint32_t spe_idx; + uint32_t aid; + uint8_t ucAddr1[MAC_ADDR_LEN]; + uint32_t nss = 1; + uint8_t *prInBuf; + + prInBuf = kmalloc(sizeof(uint8_t) * (HQA_BF_STR_SIZE), + GFP_KERNEL); + ASSERT(prInBuf); + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_ManualAssoc\n"); + + memcpy(&type, HqaCmdFrame->Data + 4 * 0, 4); + type = ntohl(type); + memcpy(&wtbl_idx, HqaCmdFrame->Data + 4 * 1, 4); + wtbl_idx = ntohl(wtbl_idx); + memcpy(&ownmac_idx, HqaCmdFrame->Data + 4 * 2, 4); + ownmac_idx = ntohl(ownmac_idx); + memcpy(&phymode, HqaCmdFrame->Data + 4 * 3, 4); + phymode = ntohl(phymode); + memcpy(&bw, HqaCmdFrame->Data + 4 * 4, 4); + bw = ntohl(bw); + memcpy(&pfmuid, HqaCmdFrame->Data + 4 * 5, 4); + pfmuid = ntohl(pfmuid); + memcpy(&marate_mode, HqaCmdFrame->Data + 4 * 6, 4); + marate_mode = ntohl(marate_mode); + memcpy(&marate_mcs, HqaCmdFrame->Data + 4 * 7, 4); + marate_mcs = ntohl(marate_mcs); + memcpy(&spe_idx, HqaCmdFrame->Data + 4 * 8, 4); + spe_idx = ntohl(spe_idx); + memcpy(&aid, HqaCmdFrame->Data + 4 * 9, 4); + aid = ntohl(aid); + memcpy(ucAddr1, HqaCmdFrame->Data + 4 * 10, 6); + + kalMemSet(prInBuf, 0, sizeof(uint8_t) * (HQA_BF_STR_SIZE)); + kalSprintf(prInBuf, + "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", + ucAddr1[0], ucAddr1[1], ucAddr1[2], ucAddr1[3], ucAddr1[4], + ucAddr1[5], type, wtbl_idx, ownmac_idx, + phymode, bw, nss, pfmuid, marate_mode, marate_mcs, spe_idx, + aid, 0); + + DBGLOG(RFTEST, ERROR, "prInBuf = %s\n", prInBuf); + + i4Ret = Set_TxBfManualAssoc(prNetDev, prInBuf); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + kfree(prInBuf); + + return i4Ret; +} + +static HQA_CMD_HANDLER HQA_TXBF_CMDS[] = { + HQA_TxBfProfileTagInValid, /* 0x1540 */ + HQA_TxBfProfileTagPfmuIdx, /* 0x1541 */ + HQA_TxBfProfileTagBfType, /* 0x1542 */ + HQA_TxBfProfileTagBw, /* 0x1543 */ + HQA_TxBfProfileTagSuMu, /* 0x1544 */ + HQA_TxBfProfileTagMemAlloc, /* 0x1545 */ + HQA_TxBfProfileTagMatrix, /* 0x1546 */ + HQA_TxBfProfileTagSnr, /* 0x1547 */ + HQA_TxBfProfileTagSmtAnt, /* 0x1548 */ + HQA_TxBfProfileTagSeIdx, /* 0x1549 */ + HQA_TxBfProfileTagRmsdThrd, /* 0x154A */ + HQA_TxBfProfileTagMcsThrd, /* 0x154B */ + HQA_TxBfProfileTagTimeOut, /* 0x154C */ + HQA_TxBfProfileTagDesiredBw, /* 0x154D */ + HQA_TxBfProfileTagDesiredNc, /* 0x154E */ + HQA_TxBfProfileTagDesiredNr, /* 0x154F */ + HQA_TxBfProfileTagWrite, /* 0x1550 */ + HQA_TxBfProfileTagRead, /* 0x1551 */ + HQA_StaRecCmmUpdate, /* 0x1552 */ + HQA_StaRecBfUpdate, /* 0x1553 */ + HQA_BFProfileDataRead, /* 0x1554 */ + HQA_BFProfileDataWrite, /* 0x1555 */ + HQA_BFSounding, /* 0x1556 */ + HQA_TXBFSoundingStop, /* 0x1557 */ + HQA_TXBFProfileDataWriteAllExt, /* 0x1558 */ + HQA_TxBfTxApply, /* 0x1559 */ + HQA_ManualAssoc, /* 0x155A */ +}; + +#if CFG_SUPPORT_MU_MIMO +static int32_t HQA_MUGetInitMCS(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t u4Gid = 0; + uint32_t u4User0InitMCS = 0; + uint32_t u4User1InitMCS = 0; + uint32_t u4User2InitMCS = 0; + uint32_t u4User3InitMCS = 0; + uint8_t *prInBuf; + + prInBuf = kmalloc(sizeof(uint8_t) * (HQA_BF_STR_SIZE), + GFP_KERNEL); + ASSERT(prInBuf); + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_MUGetInitMCS\n"); + + memcpy(&u4Gid, HqaCmdFrame->Data, 4); + u4Gid = ntohl(u4Gid); + + kalMemSet(prInBuf, 0, sizeof(u4Gid)); + kalSprintf(prInBuf, "%u", u4Gid); + + DBGLOG(RFTEST, ERROR, "prInBuf = %s\n", prInBuf); + + i4Ret = Set_MUGetInitMCS(prNetDev, prInBuf); + + u4User0InitMCS = ntohl(u4User0InitMCS); + u4User1InitMCS = ntohl(u4User1InitMCS); + u4User2InitMCS = ntohl(u4User2InitMCS); + u4User3InitMCS = ntohl(u4User3InitMCS); + + memcpy(HqaCmdFrame->Data + 2, &u4User0InitMCS, + sizeof(uint32_t)); + memcpy(HqaCmdFrame->Data + 2 + 1 * sizeof(uint32_t), + &u4User1InitMCS, sizeof(uint32_t)); + memcpy(HqaCmdFrame->Data + 2 + 2 * sizeof(uint32_t), + &u4User2InitMCS, sizeof(uint32_t)); + memcpy(HqaCmdFrame->Data + 2 + 3 * sizeof(uint32_t), + &u4User3InitMCS, sizeof(uint32_t)); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + kfree(prInBuf); + + return i4Ret; +} + +static int32_t HQA_MUCalInitMCS(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t u4Num_of_user; + uint32_t u4Bandwidth; + uint32_t u4Nss_of_user0; + uint32_t u4Nss_of_user1; + uint32_t u4Nss_of_user2; + uint32_t u4Nss_of_user3; + uint32_t u4Pf_mu_id_of_user0; + uint32_t u4Pf_mu_id_of_user1; + uint32_t u4Pf_mu_id_of_user2; + uint32_t u4Pf_mu_id_of_user3; + uint32_t u4Num_of_txer; /* number of antenna */ + uint32_t u4Spe_index; + uint32_t u4Group_index; + uint8_t *prInBuf; + + prInBuf = kmalloc(sizeof(uint8_t) * (HQA_BF_STR_SIZE), + GFP_KERNEL); + ASSERT(prInBuf); + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_MUCalInitMCS\n"); + + memcpy(&u4Num_of_user, HqaCmdFrame->Data + 4 * 0, 4); + u4Num_of_user = ntohl(u4Num_of_user); + memcpy(&u4Bandwidth, HqaCmdFrame->Data + 4 * 1, 4); + u4Bandwidth = ntohl(u4Bandwidth); + memcpy(&u4Nss_of_user0, HqaCmdFrame->Data + 4 * 2, 4); + u4Nss_of_user0 = ntohl(u4Nss_of_user0); + memcpy(&u4Nss_of_user1, HqaCmdFrame->Data + 4 * 3, 4); + u4Nss_of_user1 = ntohl(u4Nss_of_user1); + memcpy(&u4Nss_of_user2, HqaCmdFrame->Data + 4 * 4, 4); + u4Nss_of_user2 = ntohl(u4Nss_of_user2); + memcpy(&u4Nss_of_user3, HqaCmdFrame->Data + 4 * 5, 4); + u4Nss_of_user3 = ntohl(u4Nss_of_user3); + memcpy(&u4Pf_mu_id_of_user0, HqaCmdFrame->Data + 4 * 6, 4); + u4Pf_mu_id_of_user0 = ntohl(u4Pf_mu_id_of_user0); + memcpy(&u4Pf_mu_id_of_user1, HqaCmdFrame->Data + 4 * 7, 4); + u4Pf_mu_id_of_user1 = ntohl(u4Pf_mu_id_of_user1); + memcpy(&u4Pf_mu_id_of_user2, HqaCmdFrame->Data + 4 * 8, 4); + u4Pf_mu_id_of_user2 = ntohl(u4Pf_mu_id_of_user2); + memcpy(&u4Pf_mu_id_of_user3, HqaCmdFrame->Data + 4 * 9, 4); + u4Pf_mu_id_of_user3 = ntohl(u4Pf_mu_id_of_user3); + memcpy(&u4Num_of_txer, HqaCmdFrame->Data + 4 * 10, 4); + u4Num_of_txer = ntohl(u4Num_of_txer); + memcpy(&u4Spe_index, HqaCmdFrame->Data + 4 * 11, 4); + u4Spe_index = ntohl(u4Spe_index); + memcpy(&u4Group_index, HqaCmdFrame->Data + 4 * 12, 4); + u4Group_index = ntohl(u4Group_index); + + kalMemSet(prInBuf, 0, sizeof(uint8_t) * (HQA_BF_STR_SIZE)); + kalSprintf(prInBuf, + "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", + u4Num_of_user, u4Bandwidth, u4Nss_of_user0, u4Nss_of_user1, + u4Pf_mu_id_of_user0, u4Pf_mu_id_of_user1, + u4Num_of_txer, u4Spe_index, u4Group_index); + + DBGLOG(RFTEST, ERROR, "prInBuf = %s\n", prInBuf); + + i4Ret = Set_MUCalInitMCS(prNetDev, prInBuf); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + kfree(prInBuf); + + return i4Ret; +} + +static int32_t HQA_MUCalLQ(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t u4Type = 0; + uint32_t u4Num_of_user; + uint32_t u4Bandwidth; + uint32_t u4Nss_of_user0; + uint32_t u4Nss_of_user1; + uint32_t u4Nss_of_user2; + uint32_t u4Nss_of_user3; + uint32_t u4Pf_mu_id_of_user0; + uint32_t u4Pf_mu_id_of_user1; + uint32_t u4Pf_mu_id_of_user2; + uint32_t u4Pf_mu_id_of_user3; + uint32_t u4Num_of_txer; /* number of antenna */ + uint32_t u4Spe_index; + uint32_t u4Group_index; + uint8_t *prInBuf; + + prInBuf = kmalloc(sizeof(uint8_t) * (HQA_BF_STR_SIZE), + GFP_KERNEL); + ASSERT(prInBuf); + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_MUCalLQ\n"); + + memcpy(&u4Type, HqaCmdFrame->Data + 4 * 0, 4); + u4Type = ntohl(u4Type); + memcpy(&u4Num_of_user, HqaCmdFrame->Data + 4 * 1, 4); + u4Num_of_user = ntohl(u4Num_of_user); + memcpy(&u4Bandwidth, HqaCmdFrame->Data + 4 * 2, 4); + u4Bandwidth = ntohl(u4Bandwidth); + memcpy(&u4Nss_of_user0, HqaCmdFrame->Data + 4 * 3, 4); + u4Nss_of_user0 = ntohl(u4Nss_of_user0); + memcpy(&u4Nss_of_user1, HqaCmdFrame->Data + 4 * 4, 4); + u4Nss_of_user1 = ntohl(u4Nss_of_user1); + memcpy(&u4Nss_of_user2, HqaCmdFrame->Data + 4 * 5, 4); + u4Nss_of_user2 = ntohl(u4Nss_of_user2); + memcpy(&u4Nss_of_user3, HqaCmdFrame->Data + 4 * 6, 4); + u4Nss_of_user3 = ntohl(u4Nss_of_user3); + memcpy(&u4Pf_mu_id_of_user0, HqaCmdFrame->Data + 4 * 7, 4); + u4Pf_mu_id_of_user0 = ntohl(u4Pf_mu_id_of_user0); + memcpy(&u4Pf_mu_id_of_user1, HqaCmdFrame->Data + 4 * 8, 4); + u4Pf_mu_id_of_user1 = ntohl(u4Pf_mu_id_of_user1); + memcpy(&u4Pf_mu_id_of_user2, HqaCmdFrame->Data + 4 * 9, 4); + u4Pf_mu_id_of_user2 = ntohl(u4Pf_mu_id_of_user2); + memcpy(&u4Pf_mu_id_of_user3, HqaCmdFrame->Data + 4 * 10, 4); + u4Pf_mu_id_of_user3 = ntohl(u4Pf_mu_id_of_user3); + memcpy(&u4Num_of_txer, HqaCmdFrame->Data + 4 * 11, 4); + u4Num_of_txer = ntohl(u4Num_of_txer); + memcpy(&u4Spe_index, HqaCmdFrame->Data + 4 * 12, 4); + u4Spe_index = ntohl(u4Spe_index); + memcpy(&u4Group_index, HqaCmdFrame->Data + 4 * 13, 4); + u4Group_index = ntohl(u4Group_index); + + kalMemSet(prInBuf, 0, sizeof(uint8_t) * (HQA_BF_STR_SIZE)); + kalSprintf(prInBuf, + "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", + u4Num_of_user, u4Bandwidth, u4Nss_of_user0, u4Nss_of_user1, + u4Pf_mu_id_of_user0, u4Pf_mu_id_of_user1, + u4Num_of_txer, u4Spe_index, u4Group_index); + + DBGLOG(RFTEST, ERROR, "prInBuf = %s\n", prInBuf); + + i4Ret = Set_MUCalLQ(prNetDev, prInBuf); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + kfree(prInBuf); + + return i4Ret; +} + +static int32_t HQA_MUGetLQ(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t i; + uint8_t u4LqReport[NUM_OF_USER * NUM_OF_MODUL] = {0}; + uint8_t *prInBuf; + + prInBuf = kmalloc(sizeof(uint8_t) * (HQA_BF_STR_SIZE), + GFP_KERNEL); + ASSERT(prInBuf); + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_MUGetLQ\n"); + + DBGLOG(RFTEST, ERROR, "prInBuf = %s\n", prInBuf); + + i4Ret = Set_MUGetLQ(prNetDev, prInBuf); + + for (i = 0; i < NUM_OF_USER * NUM_OF_MODUL; i++) { + u4LqReport[i] = ntohl(u4LqReport[i]); + memcpy(HqaCmdFrame->Data + 2 + i * sizeof(uint32_t), + &u4LqReport[i], sizeof(uint32_t)); + } + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + kfree(prInBuf); + + return i4Ret; +} + +static int32_t HQA_MUSetSNROffset(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t u4Offset = 0; + uint8_t *prInBuf; + + prInBuf = kmalloc(sizeof(uint8_t) * (HQA_BF_STR_SIZE), + GFP_KERNEL); + ASSERT(prInBuf); + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_MUSetSNROffset\n"); + + memcpy(&u4Offset, HqaCmdFrame->Data + 4 * 0, 4); + u4Offset = ntohl(u4Offset); + + kalMemSet(prInBuf, 0, sizeof(uint8_t) * (HQA_BF_STR_SIZE)); + kalSprintf(prInBuf, "%02x", u4Offset); + + DBGLOG(RFTEST, ERROR, "prInBuf = %s\n", prInBuf); + + i4Ret = Set_MUSetSNROffset(prNetDev, prInBuf); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + kfree(prInBuf); + + return i4Ret; +} + +static int32_t HQA_MUSetZeroNss(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t u4Zero_nss = 0; + uint8_t *prInBuf; + + prInBuf = kmalloc(sizeof(uint8_t) * (HQA_BF_STR_SIZE), + GFP_KERNEL); + ASSERT(prInBuf); + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_MUSetZeroNss\n"); + + memcpy(&u4Zero_nss, HqaCmdFrame->Data + 4 * 0, 4); + u4Zero_nss = ntohl(u4Zero_nss); + + kalMemSet(prInBuf, 0, sizeof(uint8_t) * (HQA_BF_STR_SIZE)); + kalSprintf(prInBuf, "%02x", u4Zero_nss); + + DBGLOG(RFTEST, ERROR, "prInBuf = %s\n", prInBuf); + + i4Ret = Set_MUSetZeroNss(prNetDev, prInBuf); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + kfree(prInBuf); + + return i4Ret; +} + +static int32_t HQA_MUSetSpeedUpLQ(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t u4SpeedUpLq = 0; + uint8_t *prInBuf; + + prInBuf = kmalloc(sizeof(uint8_t) * (HQA_BF_STR_SIZE), + GFP_KERNEL); + ASSERT(prInBuf); + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_MUSetSpeedUpLQ\n"); + + memcpy(&u4SpeedUpLq, HqaCmdFrame->Data + 4 * 0, 4); + u4SpeedUpLq = ntohl(u4SpeedUpLq); + + kalMemSet(prInBuf, 0, sizeof(uint8_t) * (HQA_BF_STR_SIZE)); + kalSprintf(prInBuf, "%02x", u4SpeedUpLq); + + DBGLOG(RFTEST, ERROR, "prInBuf = %s\n", prInBuf); + + i4Ret = Set_MUSetSpeedUpLQ(prNetDev, prInBuf); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + kfree(prInBuf); + + return i4Ret; + +} + +static int32_t HQA_MUSetMUTable(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint8_t *prTable; + uint16_t u2Len = 0; + uint32_t u4SuMu = 0; + + prTable = kmalloc_array(u2Len, sizeof(uint8_t), GFP_KERNEL); + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_MUSetMUTable\n"); + + u2Len = ntohl(HqaCmdFrame->Length) - sizeof(u4SuMu); + + memcpy(&u4SuMu, HqaCmdFrame->Data + 4 * 0, 4); + u4SuMu = ntohl(u4SuMu); + + memcpy(prTable, HqaCmdFrame->Data + 4, u2Len); + + i4Ret = Set_MUSetMUTable(prNetDev, prTable); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +static int32_t HQA_MUSetGroup(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t u4GroupIndex, u4NumOfUser, u4User0Ldpc, + u4User1Ldpc, u4User2Ldpc, u4User3Ldpc; + uint32_t u4ShortGI, u4Bw, u4User0Nss, u4User1Nss, + u4User2Nss, u4User3Nss; + uint32_t u4GroupId, u4User0UP, u4User1UP, u4User2UP, + u4User3UP; + uint32_t u4User0MuPfId, u4User1MuPfId, u4User2MuPfId, + u4User3MuPfId; + uint32_t u4User0InitMCS, u4User1InitMCS, u4User2InitMCS, + u4User3InitMCS; + uint8_t ucAddr1[MAC_ADDR_LEN], ucAddr2[MAC_ADDR_LEN], + ucAddr3[MAC_ADDR_LEN], ucAddr4[MAC_ADDR_LEN]; + uint8_t *prInBuf; + + prInBuf = kmalloc(sizeof(uint8_t) * (HQA_BF_STR_SIZE), + GFP_KERNEL); + ASSERT(prInBuf); + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_MUSetGroup\n"); + + memcpy(&u4GroupIndex, HqaCmdFrame->Data + 4 * 0, 4); + u4GroupIndex = ntohl(u4GroupIndex); + memcpy(&u4NumOfUser, HqaCmdFrame->Data + 4 * 1, 4); + u4NumOfUser = ntohl(u4NumOfUser); + memcpy(&u4User0Ldpc, HqaCmdFrame->Data + 4 * 2, 4); + u4User0Ldpc = ntohl(u4User0Ldpc); + memcpy(&u4User1Ldpc, HqaCmdFrame->Data + 4 * 3, 4); + u4User1Ldpc = ntohl(u4User1Ldpc); + memcpy(&u4User2Ldpc, HqaCmdFrame->Data + 4 * 4, 4); + u4User2Ldpc = ntohl(u4User2Ldpc); + memcpy(&u4User3Ldpc, HqaCmdFrame->Data + 4 * 5, 4); + u4User3Ldpc = ntohl(u4User3Ldpc); + memcpy(&u4ShortGI, HqaCmdFrame->Data + 4 * 6, 4); + u4ShortGI = ntohl(u4ShortGI); + memcpy(&u4Bw, HqaCmdFrame->Data + 4 * 7, 4); + u4Bw = ntohl(u4Bw); + memcpy(&u4User0Nss, HqaCmdFrame->Data + 4 * 8, 4); + u4User0Nss = ntohl(u4User0Nss); + memcpy(&u4User1Nss, HqaCmdFrame->Data + 4 * 9, 4); + u4User1Nss = ntohl(u4User1Nss); + memcpy(&u4User2Nss, HqaCmdFrame->Data + 4 * 10, 4); + u4User2Nss = ntohl(u4User2Nss); + memcpy(&u4User3Nss, HqaCmdFrame->Data + 4 * 11, 4); + u4User3Nss = ntohl(u4User3Nss); + memcpy(&u4GroupId, HqaCmdFrame->Data + 4 * 12, 4); + u4GroupId = ntohl(u4GroupId); + memcpy(&u4User0UP, HqaCmdFrame->Data + 4 * 13, 4); + u4User0UP = ntohl(u4User0UP); + memcpy(&u4User1UP, HqaCmdFrame->Data + 4 * 14, 4); + u4User1UP = ntohl(u4User1UP); + memcpy(&u4User2UP, HqaCmdFrame->Data + 4 * 15, 4); + u4User2UP = ntohl(u4User2UP); + memcpy(&u4User3UP, HqaCmdFrame->Data + 4 * 16, 4); + u4User3UP = ntohl(u4User3UP); + memcpy(&u4User0MuPfId, HqaCmdFrame->Data + 4 * 17, 4); + u4User0MuPfId = ntohl(u4User0MuPfId); + memcpy(&u4User1MuPfId, HqaCmdFrame->Data + 4 * 18, 4); + u4User1MuPfId = ntohl(u4User1MuPfId); + memcpy(&u4User2MuPfId, HqaCmdFrame->Data + 4 * 19, 4); + u4User2MuPfId = ntohl(u4User2MuPfId); + memcpy(&u4User3MuPfId, HqaCmdFrame->Data + 4 * 20, 4); + u4User3MuPfId = ntohl(u4User3MuPfId); + memcpy(&u4User0InitMCS, HqaCmdFrame->Data + 4 * 21, 4); + u4User0InitMCS = ntohl(u4User0InitMCS); + memcpy(&u4User1InitMCS, HqaCmdFrame->Data + 4 * 22, 4); + u4User1InitMCS = ntohl(u4User1InitMCS); + memcpy(&u4User2InitMCS, HqaCmdFrame->Data + 4 * 23, 4); + u4User2InitMCS = ntohl(u4User2InitMCS); + memcpy(&u4User3InitMCS, HqaCmdFrame->Data + 4 * 24, 4); + u4User3InitMCS = ntohl(u4User3InitMCS); + + memcpy(ucAddr1, HqaCmdFrame->Data + 4 * 25, 6); + memcpy(ucAddr2, HqaCmdFrame->Data + 4 * 25 + 6 * 1, 6); + memcpy(ucAddr3, HqaCmdFrame->Data + 4 * 25 + 6 * 2, 6); + memcpy(ucAddr4, HqaCmdFrame->Data + 4 * 25 + 6 * 3, 6); + + kalMemSet(prInBuf, 0, sizeof(uint8_t) * (HQA_BF_STR_SIZE)); + kalSprintf(prInBuf, + "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", + u4GroupIndex, u4NumOfUser, u4User0Ldpc, u4User1Ldpc, + u4ShortGI, u4Bw, u4User0Nss, u4User1Nss, + u4GroupId, u4User0UP, u4User1UP, u4User0MuPfId, + u4User1MuPfId, u4User0InitMCS, u4User1InitMCS, + ucAddr1[0], ucAddr1[1], ucAddr1[2], ucAddr1[3], ucAddr1[4], + ucAddr1[5], ucAddr2[0], ucAddr2[1], + ucAddr2[2], ucAddr2[3], ucAddr2[4], ucAddr2[5]); + + DBGLOG(RFTEST, ERROR, "prInBuf = %s\n", prInBuf); + + i4Ret = Set_MUSetGroup(prNetDev, prInBuf); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + kfree(prInBuf); + + return i4Ret; +} + +static int32_t HQA_MUGetQD(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t u4SubIdx = 0; + + /* TODO */ + uint32_t u4User0InitMCS = 0; + uint32_t u4User1InitMCS = 0; + uint32_t u4User2InitMCS = 0; + uint32_t u4User3InitMCS = 0; + + uint8_t *prInBuf; + + prInBuf = kmalloc(sizeof(uint8_t) * (HQA_BF_STR_SIZE), + GFP_KERNEL); + ASSERT(prInBuf); + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_MUGetQD\n"); + + memcpy(&u4SubIdx, HqaCmdFrame->Data, 4); + u4SubIdx = ntohl(u4SubIdx); + + kalMemSet(prInBuf, 0, sizeof(u4SubIdx)); + kalSprintf(prInBuf, "%u", u4SubIdx); + + DBGLOG(RFTEST, ERROR, "prInBuf = %s\n", prInBuf); + + i4Ret = Set_MUGetQD(prNetDev, prInBuf); + + /* TODO */ + u4User0InitMCS = ntohl(u4User0InitMCS); + u4User1InitMCS = ntohl(u4User1InitMCS); + u4User2InitMCS = ntohl(u4User2InitMCS); + u4User3InitMCS = ntohl(u4User3InitMCS); + + memcpy(HqaCmdFrame->Data + 2, &u4User0InitMCS, + sizeof(uint32_t)); + memcpy(HqaCmdFrame->Data + 2 + 1 * sizeof(uint32_t), + &u4User1InitMCS, sizeof(uint32_t)); + memcpy(HqaCmdFrame->Data + 2 + 2 * sizeof(uint32_t), + &u4User2InitMCS, sizeof(uint32_t)); + memcpy(HqaCmdFrame->Data + 2 + 3 * sizeof(uint32_t), + &u4User3InitMCS, sizeof(uint32_t)); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + kfree(prInBuf); + + return i4Ret; +} + +static int32_t HQA_MUSetEnable(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t u4Enable = 0; + uint8_t *prInBuf; + + prInBuf = kmalloc(sizeof(uint8_t) * (HQA_BF_STR_SIZE), + GFP_KERNEL); + ASSERT(prInBuf); + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_MUSetEnable\n"); + + memcpy(&u4Enable, HqaCmdFrame->Data + 4 * 0, 4); + u4Enable = ntohl(u4Enable); + + kalMemSet(prInBuf, 0, sizeof(uint8_t) * (HQA_BF_STR_SIZE)); + kalSprintf(prInBuf, "%02x", u4Enable); + + DBGLOG(RFTEST, ERROR, "prInBuf = %s\n", prInBuf); + + i4Ret = Set_MUSetEnable(prNetDev, prInBuf); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + kfree(prInBuf); + + return i4Ret; +} + +static int32_t HQA_MUSetGID_UP(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t au4Gid[2]; + uint32_t au4Up[4]; + uint8_t *prInBuf; + + prInBuf = kmalloc(sizeof(uint8_t) * (HQA_BF_STR_SIZE), + GFP_KERNEL); + ASSERT(prInBuf); + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_MUSetGID_UP\n"); + + memcpy(&au4Gid[0], HqaCmdFrame->Data + 4 * 0, 4); + au4Gid[0] = ntohl(au4Gid[0]); + memcpy(&au4Gid[1], HqaCmdFrame->Data + 4 * 1, 4); + au4Gid[1] = ntohl(au4Gid[1]); + memcpy(&au4Up[0], HqaCmdFrame->Data + 4 * 2, 4); + au4Up[0] = ntohl(au4Up[0]); + memcpy(&au4Up[1], HqaCmdFrame->Data + 4 * 3, 4); + au4Up[1] = ntohl(au4Up[1]); + memcpy(&au4Up[2], HqaCmdFrame->Data + 4 * 4, 4); + au4Up[2] = ntohl(au4Up[2]); + memcpy(&au4Up[3], HqaCmdFrame->Data + 4 * 5, 4); + au4Up[3] = ntohl(au4Up[3]); + + kalMemSet(prInBuf, 0, sizeof(uint8_t) * (HQA_BF_STR_SIZE)); + kalSprintf(prInBuf, "%02x:%02x:%02x:%02x:%02x:%02x", + au4Gid[0], au4Gid[1], au4Up[0], au4Up[1], au4Up[2], + au4Up[3]); + + DBGLOG(RFTEST, ERROR, "prInBuf = %s\n", prInBuf); + + i4Ret = Set_MUSetGID_UP(prNetDev, prInBuf); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + kfree(prInBuf); + + return i4Ret; +} + +static int32_t HQA_MUTriggerTx(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t u4BandIdx, u4IsRandomPattern; + uint32_t u4MsduPayloadLength0, u4MsduPayloadLength1, + u4MsduPayloadLength2, u4MsduPayloadLength3; + uint32_t u4MuPacketCount, u4NumOfSTAs; + uint8_t ucAddr1[MAC_ADDR_LEN], ucAddr2[MAC_ADDR_LEN], + ucAddr3[MAC_ADDR_LEN], ucAddr4[MAC_ADDR_LEN]; + uint8_t *prInBuf; + + prInBuf = kmalloc(sizeof(uint8_t) * (HQA_BF_STR_SIZE), + GFP_KERNEL); + ASSERT(prInBuf); + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_MUTriggerTx\n"); + + memcpy(&u4BandIdx, HqaCmdFrame->Data + 4 * 0, 4); + u4BandIdx = ntohl(u4BandIdx); + memcpy(&u4IsRandomPattern, HqaCmdFrame->Data + 4 * 1, 4); + u4IsRandomPattern = ntohl(u4IsRandomPattern); + memcpy(&u4MsduPayloadLength0, HqaCmdFrame->Data + 4 * 2, 4); + u4MsduPayloadLength0 = ntohl(u4MsduPayloadLength0); + memcpy(&u4MsduPayloadLength1, HqaCmdFrame->Data + 4 * 3, 4); + u4MsduPayloadLength1 = ntohl(u4MsduPayloadLength1); + memcpy(&u4MsduPayloadLength2, HqaCmdFrame->Data + 4 * 4, 4); + u4MsduPayloadLength2 = ntohl(u4MsduPayloadLength2); + memcpy(&u4MsduPayloadLength3, HqaCmdFrame->Data + 4 * 5, 4); + u4MsduPayloadLength3 = ntohl(u4MsduPayloadLength3); + memcpy(&u4MuPacketCount, HqaCmdFrame->Data + 4 * 6, 4); + u4MuPacketCount = ntohl(u4MuPacketCount); + memcpy(&u4NumOfSTAs, HqaCmdFrame->Data + 4 * 7, 4); + u4NumOfSTAs = ntohl(u4NumOfSTAs); + memcpy(ucAddr1, HqaCmdFrame->Data + 4 * 8, 6); + memcpy(ucAddr2, HqaCmdFrame->Data + 4 * 8 + 6 * 1, 6); + memcpy(ucAddr3, HqaCmdFrame->Data + 4 * 8 + 6 * 2, 6); + memcpy(ucAddr4, HqaCmdFrame->Data + 4 * 8 + 6 * 3, 6); + + kalMemSet(prInBuf, 0, sizeof(uint8_t) * (HQA_BF_STR_SIZE)); + kalSprintf(prInBuf, + "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", + u4IsRandomPattern, u4MsduPayloadLength0, + u4MsduPayloadLength1, u4MuPacketCount, u4NumOfSTAs, + ucAddr1[0], ucAddr1[1], ucAddr1[2], ucAddr1[3], ucAddr1[4], + ucAddr1[5], + ucAddr2[0], ucAddr2[1], ucAddr2[2], ucAddr2[3], ucAddr2[4], + ucAddr2[5]); + + DBGLOG(RFTEST, ERROR, "prInBuf = %s\n", prInBuf); + + i4Ret = Set_MUTriggerTx(prNetDev, prInBuf); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + kfree(prInBuf); + + return i4Ret; +} + +static HQA_CMD_HANDLER HQA_TXMU_CMDS[] = { + HQA_MUGetInitMCS, /* 0x1560 */ + HQA_MUCalInitMCS, /* 0x1561 */ + HQA_MUCalLQ, /* 0x1562 */ + HQA_MUGetLQ, /* 0x1563 */ + HQA_MUSetSNROffset, /* 0x1564 */ + HQA_MUSetZeroNss, /* 0x1565 */ + HQA_MUSetSpeedUpLQ, /* 0x1566 */ + HQA_MUSetMUTable, /* 0x1567 */ + HQA_MUSetGroup, /* 0x1568 */ + HQA_MUGetQD, /* 0x1569 */ + HQA_MUSetEnable, /* 0x156A */ + HQA_MUSetGID_UP, /* 0x156B */ + HQA_MUTriggerTx, /* 0x156C */ +}; +#endif +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For ICAP + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t HQA_CapWiFiSpectrum(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct mt66xx_chip_info *prChipInfo = NULL; + struct ATE_OPS_T *prAteOps = NULL; + uint32_t u4Control = 0; + uint32_t u4Trigger = 0; + uint32_t u4RingCapEn = 0; + uint32_t u4Event = 0; + uint32_t u4Node = 0; + uint32_t u4Len = 0; + uint32_t u4StopCycle = 0; + uint32_t u4BW = 0; + uint32_t u4MacTriggerEvent = 0; + uint32_t u4SourceAddrLSB = 0; + uint32_t u4SourceAddrMSB = 0; + uint8_t aucSourceAddress[MAC_ADDR_LEN]; + uint32_t u4Band = 0; + uint32_t u4WFNum; + uint32_t u4IQ; + uint32_t u4DataLen = 0, u4TempLen = 0; + int32_t i4Ret = 0; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prChipInfo = prGlueInfo->prAdapter->chip_info; + prAteOps = prChipInfo->prAteOps; + + memcpy((uint8_t *)&u4Control, HqaCmdFrame->Data + 4 * 0, 4); + u4Control = ntohl(u4Control); + + DBGLOG(RFTEST, INFO, "u4Control = %d\n", u4Control); + + if (u4Control == 1) { + if (prAteOps->setICapStart) { + memcpy((uint8_t *)&u4Trigger, + HqaCmdFrame->Data + 4 * 1, 4); + u4Trigger = ntohl(u4Trigger); + memcpy((uint8_t *)&u4RingCapEn, + HqaCmdFrame->Data + 4 * 2, 4); + u4RingCapEn = ntohl(u4RingCapEn); + memcpy((uint8_t *)&u4Event, + HqaCmdFrame->Data + 4 * 3, 4); + u4Event = ntohl(u4Event); + memcpy((uint8_t *)&u4Node, + HqaCmdFrame->Data + 4 * 4, 4); + u4Node = ntohl(u4Node); + memcpy((uint8_t *)&u4Len, HqaCmdFrame->Data + 4 * 5, 4); + u4Len = ntohl(u4Len); + memcpy((uint8_t *)&u4StopCycle, + HqaCmdFrame->Data + 4 * 6, + 4); + u4StopCycle = ntohl(u4StopCycle); + memcpy((uint8_t *)&u4BW, HqaCmdFrame->Data + 4 * 7, 4); + u4BW = ntohl(u4BW); + memcpy((uint8_t *)&u4MacTriggerEvent, + HqaCmdFrame->Data + 4 * 8, 4); + u4MacTriggerEvent = ntohl(u4MacTriggerEvent); + memcpy((uint8_t *)&aucSourceAddress, + HqaCmdFrame->Data + 4 * 9, MAC_ADDR_LEN); + memcpy((uint8_t *)&u4Band, + HqaCmdFrame->Data + 4 * 9 + MAC_ADDR_LEN, 4); + u4Band = ntohl(u4Band); + + /* AT Command #1, Trigger always = 1 */ + DBGLOG(RFTEST, INFO, + "u4Trigger=%u, u4RingCapEn=%u, u4TriggerEvent=%u\n", + u4Trigger, u4RingCapEn, u4Trigger); + /* AT Command #81 */ + DBGLOG(RFTEST, INFO, + "u4Node=%u, u4Len=%u, u4topCycle=%u, u4BW=%u, u4Band=%d", + u4Node, u4Len, u4StopCycle, u4BW, u4Band); + + u4SourceAddrLSB = ((aucSourceAddress[0]) | + (aucSourceAddress[1] << 8) | + (aucSourceAddress[2]) << 16 | + (aucSourceAddress[3]) << 24); + u4SourceAddrMSB = ((aucSourceAddress[4]) | + (aucSourceAddress[5] << 8) | + (0x1 << 16)); + + prGlueInfo->prAdapter->rIcapInfo.u4CapNode = u4Node; + i4Ret = prAteOps->setICapStart(prGlueInfo, u4Trigger, + u4RingCapEn, u4Event, u4Node, + u4Len, u4StopCycle, u4BW, + u4MacTriggerEvent, + u4SourceAddrLSB, + u4SourceAddrMSB, u4Band); + } else + i4Ret = 1; + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + } else if (u4Control == 2) { + if (prAteOps->getICapStatus) + i4Ret = prAteOps->getICapStatus(prGlueInfo); + else + i4Ret = 1; + /* Query whether ICAP Done */ + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + } else if (u4Control == 3) { + if (prAteOps->getICapIQData) { + kalMemCopy((uint8_t *)&u4WFNum, + HqaCmdFrame->Data + 4 * 1, + 4); + u4WFNum = ntohl(u4WFNum); + kalMemCopy((uint8_t *)&u4IQ, + HqaCmdFrame->Data + 4 * 2, + 4); + u4IQ = ntohl(u4IQ); + + DBGLOG(RFTEST, INFO, + "u4WFNum = %d, u4IQ = %d\n", u4WFNum, u4IQ); + + u4DataLen = prAteOps->getICapIQData( + prGlueInfo, + &HqaCmdFrame->Data[2 + 4 * 4], + u4IQ, + u4WFNum); + /* tool want data count instead of buff length */ + u4TempLen = u4DataLen / 4; + u4Control = ntohl(u4Control); + kalMemCopy(HqaCmdFrame->Data + 2 + 4 * 0, + (uint8_t *)&u4Control, + sizeof(u4Control)); + u4WFNum = ntohl(u4WFNum); + kalMemCopy(HqaCmdFrame->Data + 2 + 4 * 1, + (uint8_t *)&u4WFNum, + sizeof(u4WFNum)); + u4IQ = ntohl(u4IQ); + kalMemCopy(HqaCmdFrame->Data + 2 + 4 * 2, + (uint8_t *)&u4IQ, + sizeof(u4IQ)); + u4TempLen = ntohl(u4TempLen); + kalMemCopy(HqaCmdFrame->Data + 2 + 4 * 3, + (uint8_t *)&u4TempLen, + sizeof(u4TempLen)); + + } + + i4Ret = 0; + /* Get IQ Data and transmit them to UI DLL */ + ResponseToQA(HqaCmdFrame, + prIwReqData, + 2 + 4 * 4 + u4DataLen, + i4Ret); + } else { + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + } + return 0; +} + +int32_t mt6632SetICapStart(struct GLUE_INFO *prGlueInfo, + uint32_t u4Trigger, uint32_t u4RingCapEn, + uint32_t u4Event, uint32_t u4Node, uint32_t u4Len, + uint32_t u4StopCycle, + uint32_t u4BW, uint32_t u4MacTriggerEvent, + uint32_t u4SourceAddrLSB, + uint32_t u4SourceAddrMSB, uint32_t u4Band) +{ + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + + /* iwpriv wlan205 set_test_cmd 75 0 (J mode Setting) */ + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_J_MODE; + rRfATInfo.u4FuncData = 0; + + rStatus = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (rStatus != WLAN_STATUS_SUCCESS) + return -EFAULT; + + /* iwpriv wlan205 set_test_cmd 71 0 (Channel Bandwidth) */ + if (u4BW == 4) + u4BW = 3; + else if (u4BW == 3) + u4BW = 4; + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_CBW; + rRfATInfo.u4FuncData = u4BW; + + rStatus = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (rStatus != WLAN_STATUS_SUCCESS) + return -EFAULT; + + /* iwpriv wlan205 set_test_cmd 24 0 (ADC clock mode) */ + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_ADC_CLK_MODE; + rRfATInfo.u4FuncData = 0; + + rStatus = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (rStatus != WLAN_STATUS_SUCCESS) + return -EFAULT; + + /* iwpriv wlan205 set_test_cmd 84 18000 + * (Internal Capture Trigger Offset) + */ + rRfATInfo.u4FuncIndex = + RF_AT_FUNCID_SET_ICAP_TRIGGER_OFFSET; + rRfATInfo.u4FuncData = u4StopCycle; + + rStatus = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (rStatus != WLAN_STATUS_SUCCESS) + return -EFAULT; + + if (u4Len == 0) + u4Len = 196615;/* 24000; */ + /* iwpriv wlan205 set_test_cmd 83 24576 (Internal Capture Size) */ + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_ICAP_SIZE; + rRfATInfo.u4FuncData = u4Len; + + rStatus = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (rStatus != WLAN_STATUS_SUCCESS) + return -EFAULT; + /* iwpriv wlan205 set_test_cmd 80 0 (Internal Capture Content) */ + if (u4Node == 0x6) + u4Node = 0x10000006; + else if (u4Node == 0x8) + u4Node = 0x49; + else if (u4Node == 0x9) + u4Node = 0x48; + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_ICAP_CONTENT; + rRfATInfo.u4FuncData = u4Node; + + rStatus = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (rStatus != WLAN_STATUS_SUCCESS) + return -EFAULT; + + /* iwpriv wlan205 set_test_cmd 81 0 (Internal Capture Trigger mode) */ + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_ICAP_MODE; + rRfATInfo.u4FuncData = u4Trigger; + + rStatus = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (rStatus != WLAN_STATUS_SUCCESS) + return -EFAULT; + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_ICAP_RING; + rRfATInfo.u4FuncData = u4RingCapEn; + + rStatus = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (rStatus != WLAN_STATUS_SUCCESS) + return -EFAULT; + /* iwpriv wlan205 set_test_cmd 1 13 */ + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_COMMAND; + rRfATInfo.u4FuncData = RF_AT_COMMAND_CH_SWITCH_FOR_ICAP; + + rStatus = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (rStatus != WLAN_STATUS_SUCCESS) + return -EFAULT; + /* iwpriv wlan205 set_test_cmd 1 11 */ + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_COMMAND; + rRfATInfo.u4FuncData = RF_AT_COMMAND_ICAP; + + rStatus = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (rStatus != WLAN_STATUS_SUCCESS) + return -EFAULT; + return 0; +} + +int32_t mt6632GetICapStatus(struct GLUE_INFO *prGlueInfo) +{ + struct ADAPTER *prAdapter; + + ASSERT(prGlueInfo); + prAdapter = prGlueInfo->prAdapter; + ASSERT(prAdapter); + + if (prAdapter->rIcapInfo.eIcapState == ICAP_STATE_FW_DUMP_DONE) { + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_CapWiFiSpectrum Done!!!!!!!!!!!!!!!!!\n"); + return 0; + } + return 1; +} + +int32_t connacSetICapStart(struct GLUE_INFO *prGlueInfo, + uint32_t u4Trigger, uint32_t u4RingCapEn, + uint32_t u4Event, uint32_t u4Node, uint32_t u4Len, + uint32_t u4StopCycle, + uint32_t u4BW, uint32_t u4MacTriggerEvent, + uint32_t u4SourceAddrLSB, + uint32_t u4SourceAddrMSB, uint32_t u4Band) +{ + struct PARAM_MTK_WIFI_TEST_STRUCT_EXT_T rRfATInfo; + struct RBIST_CAP_START_T *prICapInfo = NULL; + uint32_t u4BufLen = 0, u4IQArrayLen = 0; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + + if (u4Trigger) { + if (prGlueInfo->prAdapter->rIcapInfo.eIcapState + != ICAP_STATE_INIT) { + log_dbg(RFTEST, ERROR, "Already starting, ignore\n"); + return 1; + } + } else { + log_dbg(RFTEST, INFO, "Shutdown Icap\n"); + prGlueInfo->prAdapter->rIcapInfo.eIcapState = ICAP_STATE_INIT; + if (prGlueInfo->prAdapter->rIcapInfo.prIQArray != NULL) + kalMemFree(prGlueInfo->prAdapter->rIcapInfo.prIQArray, + VIR_MEM_TYPE, + u4IQArrayLen); + prGlueInfo->prAdapter->rIcapInfo.u4IQArrayIndex = 0; + prGlueInfo->prAdapter->rIcapInfo.u4ICapEventCnt = 0; + prGlueInfo->prAdapter->rIcapInfo.prIQArray = NULL; + return 0; + } + + prICapInfo = &(rRfATInfo.Data.rICapInfo); + prICapInfo->u4Trigger = u4Trigger; + prICapInfo->u4TriggerEvent = u4Event; + + u4IQArrayLen = MAX_ICAP_IQ_DATA_CNT * sizeof(struct _RBIST_IQ_DATA_T); +#if 0 + if (prGlueInfo->prAdapter->rIcapInfo.prIQArray != NULL) + kalMemFree(prGlueInfo->prAdapter->rIcapInfo.prIQArray, + VIR_MEM_TYPE, + u4IQArrayLen); +#endif + + if (!prGlueInfo->prAdapter->rIcapInfo.prIQArray) { + prGlueInfo->prAdapter->rIcapInfo.prIQArray = + kalMemAlloc(u4IQArrayLen, VIR_MEM_TYPE); + if (!prGlueInfo->prAdapter->rIcapInfo.prIQArray) { + DBGLOG(RFTEST, ERROR, + "Not enough memory for IQ_Array\n"); + return 0; + } + } + + prGlueInfo->prAdapter->rIcapInfo.u4IQArrayIndex = 0; + prGlueInfo->prAdapter->rIcapInfo.u4ICapEventCnt = 0; + kalMemZero(prGlueInfo->prAdapter->rIcapInfo.au4ICapDumpIndex, + sizeof(prGlueInfo->prAdapter->rIcapInfo.au4ICapDumpIndex)); + kalMemZero(prGlueInfo->prAdapter->rIcapInfo.prIQArray, u4IQArrayLen); + + if (prICapInfo->u4TriggerEvent == CAP_FREE_RUN) + prICapInfo->u4RingCapEn = CAP_RING_MODE_DISABLE; + else + prICapInfo->u4RingCapEn = CAP_RING_MODE_ENABLE; + + prICapInfo->u4CaptureNode = u4Node; + prICapInfo->u4CaptureLen = u4Len; + prICapInfo->u4CapStopCycle = u4StopCycle; + prICapInfo->u4BW = u4BW; + prICapInfo->u4MacTriggerEvent = u4MacTriggerEvent; + prICapInfo->u4SourceAddressLSB = u4SourceAddrLSB; + prICapInfo->u4SourceAddressMSB = u4SourceAddrMSB; + prICapInfo->u4BandIdx = u4Band; + prICapInfo->u4EnBitWidth = 0; + prICapInfo->u4Architech = 1; + prICapInfo->u4PhyIdx = 0; +#if (CFG_MTK_ANDROID_EMI == 1) + prICapInfo->u4EmiStartAddress = + (uint32_t) (gConEmiPhyBaseFinal & 0xFFFFFFFF); + prICapInfo->u4EmiEndAddress = + (uint32_t) ((gConEmiPhyBaseFinal + gConEmiSizeFinal) & + 0xFFFFFFFF); + prICapInfo->u4EmiMsbAddress = + (uint32_t) ((((uint64_t) gConEmiPhyBaseFinal) >> 32) & + 0xFFFFFFFF); + + DBGLOG(RFTEST, INFO, + "startAddr = 0x%08x, endAddress = 0x%08x, MsbAddr = 0x%08x\n", + prICapInfo->u4EmiStartAddress, + prICapInfo->u4EmiEndAddress, + prICapInfo->u4EmiMsbAddress); +#else + DBGLOG(RFTEST, WARN, "Platform doesn't support WMT, no EMI address\n"); +#endif + + DBGLOG(RFTEST, INFO, + "%s :\n prICapInfo->u4Trigger = 0x%08x\n prICapInfo->u4RingCapEn = 0x%08x\n" + "prICapInfo->u4TriggerEvent = 0x%08x\n prICapInfo->u4CaptureNode = 0x%08x\n" + "prICapInfo->u4CaptureLen = 0x%08x\n prICapInfo->u4CapStopCycle = 0x%08x\n" + "prICapInfo->ucBW = 0x%08x\n prICapInfo->u4MacTriggerEvent = 0x%08x\n" + "prICapInfo->u4SourceAddressLSB = 0x%08x\n prICapInfo->u4SourceAddressMSB = 0x%08x\n" + "prICapInfo->u4BandIdx = 0x%08x\n", + __func__, + prICapInfo->u4Trigger, prICapInfo->u4RingCapEn, + prICapInfo->u4TriggerEvent, prICapInfo->u4CaptureNode, + prICapInfo->u4CaptureLen, + prICapInfo->u4CapStopCycle, prICapInfo->u4BW, + prICapInfo->u4MacTriggerEvent, + prICapInfo->u4SourceAddressLSB, + prICapInfo->u4SourceAddressMSB, prICapInfo->u4BandIdx); + + rStatus = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidExtRfTestICapStart, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + return 0; +} + +int32_t connacGetICapStatus(struct GLUE_INFO *prGlueInfo) +{ + struct ADAPTER *prAdapter; + struct PARAM_MTK_WIFI_TEST_STRUCT_EXT_T rRfATInfo; + uint32_t u4BufLen = 0; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + enum ENUM_ICAP_STATE eIcapState = ICAP_STATE_INIT; + + + ASSERT(prGlueInfo); + prAdapter = prGlueInfo->prAdapter; + ASSERT(prAdapter); + + eIcapState = prGlueInfo->prAdapter->rIcapInfo.eIcapState; + + /*FW dump IQ data done*/ + if (eIcapState == ICAP_STATE_FW_DUMP_DONE) { + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_CapWiFiSpectrum Done!!!!!!!!!!!!!!!!!\n"); + return 0; + } + + if (eIcapState != ICAP_STATE_FW_DUMPING) { + rStatus = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidExtRfTestICapStatus, + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + } + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_CapWiFiSpectrum Wait!!!!!!!!!!!!\n"); + return 1; +} + +int32_t commonGetICapIQData(struct GLUE_INFO *prGlueInfo, + uint8_t *pData, uint32_t u4IQType, uint32_t u4WFNum) +{ + struct ADAPTER *prAdapter; + uint32_t u4TempLen = 0; + uint32_t u4DataLen = 0; + int32_t *prIQAry; + int32_t i = 0; + + ASSERT(prGlueInfo); + prAdapter = prGlueInfo->prAdapter; + ASSERT(prAdapter); + + if (u4WFNum <= 1) { + GetIQData(prAdapter, &prIQAry, &u4DataLen, u4IQType, + u4WFNum); + u4TempLen = u4DataLen; + u4DataLen /= 4; + + u4DataLen = ntohl(u4DataLen); + memcpy(pData + 2 + 4 * 3, (uint8_t *) &u4DataLen, + sizeof(u4DataLen)); + + for (i = 0; i < u4TempLen / sizeof(uint32_t); i++) + prIQAry[i] = ntohl(prIQAry[i]); + + memcpy(pData + 2 + 4 * 4, (uint8_t *) &prIQAry[0], + u4TempLen); + } + return u4TempLen; +} + +int32_t connacGetICapIQData(struct GLUE_INFO *prGlueInfo, + uint8_t *pData, uint32_t u4IQType, uint32_t u4WFNum) +{ + struct RBIST_DUMP_IQ_T rRbistDump; + struct ADAPTER *prAdapter; + struct ICAP_INFO_T *prICapInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + uint32_t i = 0; + uint32_t u4Value = 0; + + ASSERT(prGlueInfo); + prAdapter = prGlueInfo->prAdapter; + ASSERT(prAdapter); + prICapInfo = &prAdapter->rIcapInfo; + + rRbistDump.u4IQType = u4IQType; + rRbistDump.u4WfNum = u4WFNum; + rRbistDump.u4IcapCnt = 0; + rRbistDump.u4IcapDataLen = 0; + rRbistDump.pucIcapData = pData; + + if ((prICapInfo->eIcapState == ICAP_STATE_FW_DUMP_DONE) || + (prICapInfo->eIcapState == ICAP_STATE_QA_TOOL_CAPTURE)) { + rStatus = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRfTestICapGetIQData, + &rRbistDump, /* pvInfoBuf */ + sizeof(rRbistDump), /* u4InfoBufLen */ + TRUE, /* fgRead */ + TRUE, /* fgWaitResp */ + FALSE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + } else + DBGLOG(RFTEST, ERROR, "ICAP IQ Dump fail in State = %d\n", + prICapInfo->eIcapState); + + /*IQ data network byte oder transfer to host byte order*/ + /*each (I or Q) data size is 4Byte*/ + if (rStatus == WLAN_STATUS_SUCCESS) { + for (i = 0; i < rRbistDump.u4IcapDataLen; + i += sizeof(uint32_t)) { + u4Value = *(pData + i); + u4Value = ntohl(u4Value); + kalMemCopy((pData + i), + (uint8_t *) &u4Value, + sizeof(u4Value)); + } + } + + return rRbistDump.u4IcapDataLen; +} + + +static HQA_CMD_HANDLER HQA_ICAP_CMDS[] = { + HQA_CapWiFiSpectrum, /* 0x1580 */ +}; + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t hqa_set_channel_ext(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t u4Ext_id = 0; + uint32_t u4Param_num = 0; + uint32_t u4Band_idx = 0; + uint32_t u4Central_ch0 = 0; + uint32_t u4Central_ch1 = 0; + uint32_t u4Sys_bw = 0; + uint32_t u4Perpkt_bw = 0; + uint32_t u4Pri_sel = 0; + uint32_t u4Reason = 0; + uint32_t u4Ch_band = 0; + uint32_t u4SetFreq = 0; + + memcpy(&u4Ext_id, HqaCmdFrame->Data + 4 * 0, 4); + u4Ext_id = ntohl(u4Ext_id); + memcpy(&u4Param_num, HqaCmdFrame->Data + 4 * 1, 4); + u4Param_num = ntohl(u4Param_num); + memcpy(&u4Band_idx, HqaCmdFrame->Data + 4 * 2, 4); + u4Band_idx = ntohl(u4Band_idx); + memcpy(&u4Central_ch0, HqaCmdFrame->Data + 4 * 3, 4); + u4Central_ch0 = ntohl(u4Central_ch0); + memcpy(&u4Central_ch1, HqaCmdFrame->Data + 4 * 4, 4); + u4Central_ch1 = ntohl(u4Central_ch1); + memcpy(&u4Sys_bw, HqaCmdFrame->Data + 4 * 5, 4); + u4Sys_bw = ntohl(u4Sys_bw); + memcpy(&u4Perpkt_bw, HqaCmdFrame->Data + 4 * 6, 4); + u4Perpkt_bw = ntohl(u4Perpkt_bw); + memcpy(&u4Pri_sel, HqaCmdFrame->Data + 4 * 7, 4); + u4Pri_sel = ntohl(u4Pri_sel); + memcpy(&u4Reason, HqaCmdFrame->Data + 4 * 8, 4); + u4Reason = ntohl(u4Reason); + memcpy(&u4Ch_band, HqaCmdFrame->Data + 4 * 9, 4); + u4Ch_band = ntohl(u4Ch_band); + + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_set_channel_ext ext_id : %d\n", u4Ext_id); + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_set_channel_ext param_num : %d\n", + u4Param_num); + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_set_channel_ext band_idx : %d\n", u4Band_idx); + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_set_channel_ext central_ch0 : %d\n", + u4Central_ch0); + /* for BW80+80 */ + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_set_channel_ext central_ch1 : %d\n", + u4Central_ch1); + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_set_channel_ext sys_bw : %d\n", u4Sys_bw); + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_set_channel_ext perpkt_bw : %d\n", + u4Perpkt_bw); + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_set_channel_ext pri_sel : %d\n", u4Pri_sel); + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_set_channel_ext reason : %d\n", u4Reason); + /* 0:2.4G 1:5G */ + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_set_channel_ext ch_band : %d\n", u4Ch_band); + + /* BW Mapping in QA Tool + * 0: BW20 + * 1: BW40 + * 2: BW80 + * 3: BW10 + * 4: BW5 + * 5: BW160C + * 6: BW160NC + */ + /* BW Mapping in FW + * 0: BW20 + * 1: BW40 + * 2: BW80 + * 3: BW160C + * 4: BW160NC + * 5: BW5 + * 6: BW10 + */ + /* For POR Cal Setting - 20160601 */ + if ((u4Central_ch0 == u4Central_ch1) && (u4Sys_bw == 6) + && (u4Perpkt_bw == 6)) { + DBGLOG(RFTEST, INFO, "Wrong Setting for POR Cal\n"); + goto exit; + } + + MT_ATESetDBDCBandIndex(prNetDev, u4Band_idx); + if ((u4Central_ch0 >= 7 && u4Central_ch0 <= 16) + && u4Ch_band == 1) { + /*Ch7 - Ch12, 5G (5035-5060)*/ + u4SetFreq = 1000 * (5000 + u4Central_ch0 * 5); + } else if (u4Central_ch0 == 6 && u4Ch_band == 1) { + u4SetFreq = 1000 * 5032; + } else { + u4SetFreq = nicChannelNum2Freq(u4Central_ch0); + } + MT_ATESetChannel(prNetDev, 0, u4SetFreq); + + if (u4Sys_bw == 6) { + u4SetFreq = nicChannelNum2Freq(u4Central_ch1); + MT_ATESetChannel(prNetDev, 1, u4SetFreq); + } + + MT_ATESetSystemBW(prNetDev, u4Sys_bw); + + /* For POR Cal Setting - 20160601 */ + if ((u4Sys_bw == 6) && (u4Perpkt_bw == 6)) + MT_ATESetPerPacketBW(prNetDev, 5); + else + MT_ATESetPerPacketBW(prNetDev, u4Perpkt_bw); + + MT_ATEPrimarySetting(prNetDev, u4Pri_sel); + /* PeiHsuan Memo : No Set Reason ? */ + MT_ATESetBand(prNetDev, u4Ch_band); + +exit: + u4Ext_id = ntohl(u4Ext_id); + memcpy(HqaCmdFrame->Data + 2, (uint8_t *) &u4Ext_id, + sizeof(u4Ext_id)); + + ResponseToQA(HqaCmdFrame, prIwReqData, 6, i4Ret); + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t hqa_set_txcontent_ext(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t u4Len = 0; + uint32_t u4Ext_id = 0; + uint32_t u4Param_num = 0; + uint32_t u4Band_idx = 0; + uint32_t u4FC = 0; + uint32_t u4Dur = 0; + uint32_t u4Seq = 0; + uint32_t u4Gen_payload_rule = 0; + uint32_t u4Txlen = 0; + uint32_t u4Payload_len = 0; + uint8_t ucAddr1[MAC_ADDR_LEN]; + uint8_t ucAddr2[MAC_ADDR_LEN]; + uint8_t ucAddr3[MAC_ADDR_LEN]; + uint32_t ucPayload = 0; + + u4Len = ntohs(HqaCmdFrame->Length); + + memcpy(&u4Ext_id, HqaCmdFrame->Data + 4 * 0, 4); + u4Ext_id = ntohl(u4Ext_id); + memcpy(&u4Param_num, HqaCmdFrame->Data + 4 * 1, 4); + u4Param_num = ntohl(u4Param_num); + memcpy(&u4Band_idx, HqaCmdFrame->Data + 4 * 2, 4); + u4Band_idx = ntohl(u4Band_idx); + memcpy(&u4FC, HqaCmdFrame->Data + 4 * 3, 4); + u4FC = ntohl(u4FC); + memcpy(&u4Dur, HqaCmdFrame->Data + 4 * 4, 4); + u4Dur = ntohl(u4Dur); + memcpy(&u4Seq, HqaCmdFrame->Data + 4 * 5, 4); + u4Seq = ntohl(u4Seq); + memcpy(&u4Gen_payload_rule, HqaCmdFrame->Data + 4 * 6, 4); + u4Gen_payload_rule = ntohl(u4Gen_payload_rule); + memcpy(&u4Txlen, HqaCmdFrame->Data + 4 * 7, 4); + u4Txlen = ntohl(u4Txlen); + memcpy(&u4Payload_len, HqaCmdFrame->Data + 4 * 8, 4); + u4Payload_len = ntohl(u4Payload_len); + memcpy(ucAddr1, HqaCmdFrame->Data + 4 * 9, 6); + memcpy(ucAddr2, HqaCmdFrame->Data + 4 * 9 + 6 * 1, 6); + memcpy(ucAddr3, HqaCmdFrame->Data + 4 * 9 + 6 * 2, 6); + memcpy(&ucPayload, HqaCmdFrame->Data + 4 * 9 + 6 * 3, 1); + + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_set_txcontent_ext ext_id : %d\n", u4Ext_id); + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_set_txcontent_ext param_num : %d\n", + u4Param_num); + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_set_txcontent_ext band_idx : %d\n", + u4Band_idx); + /* Frame Control...0800 : Beacon */ + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_set_txcontent_ext FC : 0x%x\n", u4FC); + /* Duration....NAV */ + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_set_txcontent_ext dur : 0x%x\n", u4Dur); + /* Sequence Control */ + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_set_txcontent_ext seq : 0x%x\n", u4Seq); + /* Normal:0,Repeat:1,Random:2 */ + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_set_txcontent_ext gen_payload_rule : %d\n", + u4Gen_payload_rule); + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_set_txcontent_ext txlen : %d\n", u4Txlen); + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_set_txcontent_ext payload_len : %d\n", + u4Payload_len); + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_set_txcontent_ext addr1:%02x:%02x:%02x:%02x:%02x:%02x\n", + ucAddr1[0], ucAddr1[1], ucAddr1[2], ucAddr1[3], ucAddr1[4], + ucAddr1[5]); + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_set_txcontent_ext addr2:%02x:%02x:%02x:%02x:%02x:%02x\n", + ucAddr2[0], ucAddr2[1], ucAddr2[2], ucAddr2[3], ucAddr2[4], + ucAddr2[5]); + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_set_txcontent_ext addr3:%02x:%02x:%02x:%02x:%02x:%02x\n", + ucAddr3[0], ucAddr3[1], ucAddr3[2], ucAddr3[3], ucAddr3[4], + ucAddr3[5]); + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_start_tx_ext payload : 0x%x\n", ucPayload); + + MT_ATESetDBDCBandIndex(prNetDev, u4Band_idx); + MT_ATESetMacHeader(prNetDev, u4FC, u4Dur, u4Seq); + MT_ATESetTxPayLoad(prNetDev, u4Gen_payload_rule, ucPayload); + MT_ATESetTxLength(prNetDev, u4Txlen); + MT_ATESetMACAddress(prNetDev, RF_AT_FUNCID_SET_MAC_ADDRESS, + ucAddr1); + MT_ATESetMACAddress(prNetDev, RF_AT_FUNCID_SET_TA, ucAddr2); + /* PeiHsuan Memo : No Set Addr3 */ + + u4Ext_id = ntohl(u4Ext_id); + memcpy(HqaCmdFrame->Data + 2, (uint8_t *) &u4Ext_id, + sizeof(u4Ext_id)); + ResponseToQA(HqaCmdFrame, prIwReqData, 2 + sizeof(u4Ext_id), + i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t hqa_start_tx_ext(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t u4Ext_id = 0; + uint32_t u4Param_num = 0; + uint32_t u4Band_idx = 0; + uint32_t u4Pkt_cnt = 0; + uint32_t u4Phymode = 0; + uint32_t u4Rate = 0; + uint32_t u4Pwr = 0; + uint32_t u4Stbc = 0; + uint32_t u4Ldpc = 0; + uint32_t u4iBF = 0; + uint32_t u4eBF = 0; + uint32_t u4Wlan_id = 0; + uint32_t u4Aifs = 0; + uint32_t u4Gi = 0; + uint32_t u4Tx_path = 0; + uint32_t u4Nss = 0; + + memcpy(&u4Ext_id, HqaCmdFrame->Data + 4 * 0, 4); + u4Ext_id = ntohl(u4Ext_id); + memcpy(&u4Param_num, HqaCmdFrame->Data + 4 * 1, 4); + u4Param_num = ntohl(u4Param_num); + memcpy(&u4Band_idx, HqaCmdFrame->Data + 4 * 2, 4); + u4Band_idx = ntohl(u4Band_idx); + memcpy(&u4Pkt_cnt, HqaCmdFrame->Data + 4 * 3, 4); + u4Pkt_cnt = ntohl(u4Pkt_cnt); + memcpy(&u4Phymode, HqaCmdFrame->Data + 4 * 4, 4); + u4Phymode = ntohl(u4Phymode); + memcpy(&u4Rate, HqaCmdFrame->Data + 4 * 5, 4); + u4Rate = ntohl(u4Rate); + memcpy(&u4Pwr, HqaCmdFrame->Data + 4 * 6, 4); + u4Pwr = ntohl(u4Pwr); + memcpy(&u4Stbc, HqaCmdFrame->Data + 4 * 7, 4); + u4Stbc = ntohl(u4Stbc); + memcpy(&u4Ldpc, HqaCmdFrame->Data + 4 * 8, 4); + u4Ldpc = ntohl(u4Ldpc); + memcpy(&u4iBF, HqaCmdFrame->Data + 4 * 9, 4); + u4iBF = ntohl(u4iBF); + memcpy(&u4eBF, HqaCmdFrame->Data + 4 * 10, 4); + u4eBF = ntohl(u4eBF); + memcpy(&u4Wlan_id, HqaCmdFrame->Data + 4 * 11, 4); + u4Wlan_id = ntohl(u4Wlan_id); + memcpy(&u4Aifs, HqaCmdFrame->Data + 4 * 12, 4); + u4Aifs = ntohl(u4Aifs); + memcpy(&u4Gi, HqaCmdFrame->Data + 4 * 13, 4); + u4Gi = ntohl(u4Gi); + memcpy(&u4Tx_path, HqaCmdFrame->Data + 4 * 14, 4); + u4Tx_path = ntohl(u4Tx_path); + memcpy(&u4Nss, HqaCmdFrame->Data + 4 * 15, 4); + u4Nss = ntohl(u4Nss); + + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_start_tx_ext ext_id : %d\n", u4Ext_id); + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_start_tx_ext param_num : %d\n", u4Param_num); + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_start_tx_ext band_idx : %d\n", u4Band_idx); + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_start_tx_ext pkt_cnt : %d\n", u4Pkt_cnt); + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_start_tx_ext phymode : %d\n", u4Phymode); + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_start_tx_ext rate : %d\n", u4Rate); + DBGLOG(RFTEST, INFO, "QA_AGENT hqa_start_tx_ext pwr : %d\n", + u4Pwr); + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_start_tx_ext stbc : %d\n", u4Stbc); + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_start_tx_ext ldpc : %d\n", u4Ldpc); + DBGLOG(RFTEST, INFO, "QA_AGENT hqa_start_tx_ext ibf : %d\n", + u4iBF); + DBGLOG(RFTEST, INFO, "QA_AGENT hqa_start_tx_ext ebf : %d\n", + u4eBF); + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_start_tx_ext wlan_id : %d\n", u4Wlan_id); + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_start_tx_ext aifs : %d\n", u4Aifs); + DBGLOG(RFTEST, INFO, "QA_AGENT hqa_start_tx_ext gi : %d\n", + u4Gi); + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_start_tx_ext tx_path : %d\n", u4Tx_path); + DBGLOG(RFTEST, INFO, "QA_AGENT hqa_start_tx_ext nss : %d\n", + u4Nss); + + MT_ATESetDBDCBandIndex(prNetDev, u4Band_idx); + MT_ATESetTxCount(prNetDev, u4Pkt_cnt); + +#if 1 + if (u4Phymode == 1) { + u4Phymode = 0; + u4Rate += 4; + } else if ((u4Phymode == 0) && ((u4Rate == 9) + || (u4Rate == 10) || (u4Rate == 11))) + u4Phymode = 1; + MT_ATESetPreamble(prNetDev, u4Phymode); + + if (u4Phymode == 0) { + u4Rate |= 0x00000000; + + DBGLOG(RFTEST, INFO, + "QA_AGENT CCK/OFDM (normal preamble) rate : %d\n", + u4Rate); + + MT_ATESetRate(prNetDev, u4Rate); + } else if (u4Phymode == 1) { + if (u4Rate == 9) + u4Rate = 1; + else if (u4Rate == 10) + u4Rate = 2; + else if (u4Rate == 11) + u4Rate = 3; + u4Rate |= 0x00000000; + + DBGLOG(RFTEST, INFO, + "QA_AGENT CCK (short preamble) rate : %d\n", u4Rate); + + MT_ATESetRate(prNetDev, u4Rate); + } else if (u4Phymode >= 2 && u4Phymode <= 4) { + u4Rate |= 0x80000000; + + DBGLOG(RFTEST, INFO, "QA_AGENT HT/VHT rate : %d\n", u4Rate); + + MT_ATESetRate(prNetDev, u4Rate); + } +#endif + + MT_ATESetTxPower0(prNetDev, u4Pwr); + MT_ATESetTxSTBC(prNetDev, u4Stbc); + MT_ATESetEncodeMode(prNetDev, u4Ldpc); + MT_ATESetiBFEnable(prNetDev, u4iBF); + MT_ATESeteBFEnable(prNetDev, u4eBF); + /* PeiHsuan Memo : No Set Wlan ID */ + MT_ATESetTxIPG(prNetDev, u4Aifs); + MT_ATESetTxGi(prNetDev, u4Gi); + MT_ATESetTxVhtNss(prNetDev, u4Nss); + MT_ATESetTxPath(prNetDev, u4Tx_path); + MT_ATEStartTX(prNetDev, "TXFRAME"); + + u4Ext_id = ntohl(u4Ext_id); + memcpy(HqaCmdFrame->Data + 2, (uint8_t *) &u4Ext_id, + sizeof(u4Ext_id)); + ResponseToQA(HqaCmdFrame, prIwReqData, 2 + sizeof(u4Ext_id), + i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t hqa_start_rx_ext(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t u4Ext_id = 0; + uint32_t u4Param_num = 0; + uint32_t u4Band_idx = 0; + uint32_t u4Rx_path = 0; + uint8_t ucOwn_mac[MAC_ADDR_LEN]; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + uint32_t u4BufLen = 0; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + memcpy(&u4Ext_id, HqaCmdFrame->Data, 4); + u4Ext_id = ntohl(u4Ext_id); + memcpy(&u4Param_num, HqaCmdFrame->Data + 4, 4); + u4Param_num = ntohl(u4Param_num); + memcpy(&u4Band_idx, HqaCmdFrame->Data + 4 + 4, 4); + u4Band_idx = ntohl(u4Band_idx); + memcpy(ucOwn_mac, HqaCmdFrame->Data + 4 + 4 + 4, 6); + memcpy(&u4Rx_path, HqaCmdFrame->Data + 4 + 4 + 4 + 6, 4); + u4Rx_path = ntohl(u4Rx_path); + + memset(&g_HqaRxStat, 0, sizeof(struct PARAM_RX_STAT)); + + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_start_rx_ext ext_id : %d\n", u4Ext_id); + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_start_rx_ext param_num : %d\n", u4Param_num); + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_start_rx_ext band_idx : %d\n", u4Band_idx); + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_start_rx_ext own_mac:%02x:%02x:%02x:%02x:%02x:%02x\n", + ucOwn_mac[0], ucOwn_mac[1], ucOwn_mac[2], ucOwn_mac[3], + ucOwn_mac[4], ucOwn_mac[5]); + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_start_rx_ext rx_path : 0x%x\n", u4Rx_path); + + u4RxStatSeqNum = 0; + + MT_ATESetDBDCBandIndex(prNetDev, u4Band_idx); + + rRfATInfo.u4FuncIndex = RF_AT_FUNCID_SET_RX_PATH; + rRfATInfo.u4FuncData = u4Rx_path << 16 | u4Band_idx; + + i4Ret = kalIoctl(prGlueInfo, /* prGlueInfo */ + wlanoidRftestSetAutoTest, /* pfnOidHandler */ + &rRfATInfo, /* pvInfoBuf */ + sizeof(rRfATInfo), /* u4InfoBufLen */ + FALSE, /* fgRead */ + FALSE, /* fgWaitResp */ + TRUE, /* fgCmd */ + &u4BufLen); /* pu4QryInfoLen */ + + if (i4Ret != WLAN_STATUS_SUCCESS) + return -EFAULT; + /* PeiHsuan Memo : No Set Own MAC Address */ + MT_ATEStartRX(prNetDev, "RXFRAME"); + + u4Ext_id = ntohl(u4Ext_id); + memcpy(HqaCmdFrame->Data + 2, (uint8_t *) &u4Ext_id, + sizeof(u4Ext_id)); + ResponseToQA(HqaCmdFrame, prIwReqData, 2 + sizeof(u4Ext_id), + i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t hqa_stop_tx_ext(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t u4Ext_id = 0; + uint32_t u4Param_num = 0; + uint32_t u4Band_idx = 0; + + memcpy(&u4Ext_id, HqaCmdFrame->Data, 4); + u4Ext_id = ntohl(u4Ext_id); + memcpy(&u4Param_num, HqaCmdFrame->Data + 4, 4); + u4Param_num = ntohl(u4Param_num); + memcpy(&u4Band_idx, HqaCmdFrame->Data + 4 + 4, 4); + u4Band_idx = ntohl(u4Band_idx); + + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_stop_tx_ext ext_id : %d\n", u4Ext_id); + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_stop_tx_ext param_num : %d\n", u4Param_num); + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_stop_tx_ext band_idx : %d\n", u4Band_idx); + + MT_ATESetDBDCBandIndex(prNetDev, u4Band_idx); + MT_ATEStopTX(prNetDev, "TXSTOP"); + + u4Ext_id = ntohl(u4Ext_id); + memcpy(HqaCmdFrame->Data + 2, (uint8_t *) &u4Ext_id, + sizeof(u4Ext_id)); + ResponseToQA(HqaCmdFrame, prIwReqData, 6, i4Ret); + + return i4Ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t hqa_stop_rx_ext(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t u4Ext_id = 0; + uint32_t u4Param_num = 0; + uint32_t u4Band_idx = 0; + + memcpy(&u4Ext_id, HqaCmdFrame->Data, 4); + u4Ext_id = ntohl(u4Ext_id); + memcpy(&u4Param_num, HqaCmdFrame->Data + 4, 4); + u4Param_num = ntohl(u4Param_num); + memcpy(&u4Band_idx, HqaCmdFrame->Data + 4 + 4, 4); + u4Band_idx = ntohl(u4Band_idx); + + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_stop_rx_ext ext_id : %d\n", u4Ext_id); + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_stop_rx_ext param_num : %d\n", u4Param_num); + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_stop_rx_ext band_idx : %d\n", u4Band_idx); + + MT_ATESetDBDCBandIndex(prNetDev, u4Band_idx); + MT_ATEStopRX(prNetDev, "RXSTOP"); + + u4Ext_id = ntohl(u4Ext_id); + memcpy(HqaCmdFrame->Data + 2, (uint8_t *) &u4Ext_id, + sizeof(u4Ext_id)); + ResponseToQA(HqaCmdFrame, prIwReqData, 6, i4Ret); + + return i4Ret; +} + +static int32_t HQA_iBFInit(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_iBFInit\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +static int32_t HQA_iBFSetValue(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_iBFSetValue\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +static int32_t HQA_iBFGetStatus(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_iBFGetStatus\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +static int32_t HQA_iBFChanProfUpdate(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_iBFChanProfUpdate\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +static int32_t HQA_iBFProfileRead(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_iBFProfileRead\n"); + + ResponseToQA(HqaCmdFrame, prIwReqData, 2, i4Ret); + + return i4Ret; +} + +static int32_t HQA_IRRSetADC(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t u4WFIdx; + uint32_t u4ChFreq; + uint32_t u4BW; + uint32_t u4Sx; + uint32_t u4Band; + uint32_t u4Ext_id; + uint32_t u4RunType; + uint32_t u4FType; + + memcpy(&u4Ext_id, HqaCmdFrame->Data + 4 * 0, 4); + u4Ext_id = ntohl(u4Ext_id); + memcpy(&u4WFIdx, HqaCmdFrame->Data + 4 * 1, 4); + u4WFIdx = ntohl(u4WFIdx); + memcpy(&u4ChFreq, HqaCmdFrame->Data + 4 * 2, 4); + u4ChFreq = ntohl(u4ChFreq); + memcpy(&u4BW, HqaCmdFrame->Data + 4 * 3, 4); + u4BW = ntohl(u4BW); + memcpy(&u4Sx, HqaCmdFrame->Data + 4 * 4, 4); + u4Sx = ntohl(u4Sx); + memcpy(&u4Band, HqaCmdFrame->Data + 4 * 5, 4); + u4Band = ntohl(u4Band); + memcpy(&u4RunType, HqaCmdFrame->Data + 4 * 6, 4); + u4RunType = ntohl(u4RunType); + memcpy(&u4FType, HqaCmdFrame->Data + 4 * 7, 4); + u4FType = ntohl(u4FType); + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_IRRSetADC ext_id : %d\n", + u4Ext_id); + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_IRRSetADC u4WFIdx : %d\n", u4WFIdx); + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_IRRSetADC u4ChFreq : %d\n", u4ChFreq); + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_IRRSetADC u4BW : %d\n", + u4BW); + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_IRRSetADC u4Sx : %d\n", + u4Sx); /* SX : 0, 2 */ + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_IRRSetADC u4Band : %d\n", + u4Band); + /* RunType : 0 -> QA, 1 -> ATE */ + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_IRRSetADC u4RunType : %d\n", u4RunType); + /* FType : 0 -> FI, 1 -> FD */ + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_IRRSetADC u4FType : %d\n", u4FType); + + i4Ret = MT_ATE_IRRSetADC(prNetDev, u4WFIdx, u4ChFreq, u4BW, + u4Sx, u4Band, u4RunType, u4FType); + + u4Ext_id = ntohl(u4Ext_id); + memcpy(HqaCmdFrame->Data + 2, (uint8_t *) &u4Ext_id, + sizeof(u4Ext_id)); + ResponseToQA(HqaCmdFrame, prIwReqData, 6, i4Ret); + + return i4Ret; +} + +static int32_t HQA_IRRSetRxGain(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t u4PgaLpfg; + uint32_t u4Lna; + uint32_t u4Band; + uint32_t u4WF_inx; + uint32_t u4Rfdgc; + uint32_t u4Ext_id; + + memcpy(&u4Ext_id, HqaCmdFrame->Data + 4 * 0, 4); + u4Ext_id = ntohl(u4Ext_id); + memcpy(&u4PgaLpfg, HqaCmdFrame->Data + 4 * 1, 4); + u4PgaLpfg = ntohl(u4PgaLpfg); + memcpy(&u4Lna, HqaCmdFrame->Data + 4 * 2, 4); + u4Lna = ntohl(u4Lna); + memcpy(&u4Band, HqaCmdFrame->Data + 4 * 3, 4); + u4Band = ntohl(u4Band); + memcpy(&u4WF_inx, HqaCmdFrame->Data + 4 * 4, 4); + u4WF_inx = ntohl(u4WF_inx); + memcpy(&u4Rfdgc, HqaCmdFrame->Data + 4 * 5, 4); + u4Rfdgc = ntohl(u4Rfdgc); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_IRRSetRxGain ext_id : %d\n", u4Ext_id); + /* PGA is for MT663, LPFG is for MT7615 */ + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_IRRSetRxGain u4PgaLpfg : %d\n", u4PgaLpfg); + /* 5 : UH, 4 : H, 3 : M, 2 : L, 1 : UL */ + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_IRRSetRxGain u4Lna : %d\n", u4Lna); + /* DBDC band0 or band1 */ + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_IRRSetRxGain u4Band : %d\n", u4Band); + /* (each bit for each WF) */ + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_IRRSetRxGain u4WF_inx : 0x%x\n", u4WF_inx); + /* only for */ + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_IRRSetRxGain u4Rfdgc : %d\n", u4Rfdgc); + + i4Ret = MT_ATE_IRRSetRxGain(prNetDev, u4PgaLpfg, u4Lna, + u4Band, u4WF_inx, u4Rfdgc); + + u4Ext_id = ntohl(u4Ext_id); + memcpy(HqaCmdFrame->Data + 2, (uint8_t *) &u4Ext_id, + sizeof(u4Ext_id)); + ResponseToQA(HqaCmdFrame, prIwReqData, 6, i4Ret); + + return i4Ret; +} + +static int32_t HQA_IRRSetTTG(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t u4Ext_id; + uint32_t u4TTGPwrIdx; + uint32_t u4ChFreq; + uint32_t u4FIToneFreq; + uint32_t u4Band; + + memcpy(&u4Ext_id, HqaCmdFrame->Data + 4 * 0, 4); + u4Ext_id = ntohl(u4Ext_id); + memcpy(&u4TTGPwrIdx, HqaCmdFrame->Data + 4 * 1, 4); + u4TTGPwrIdx = ntohl(u4TTGPwrIdx); + memcpy(&u4ChFreq, HqaCmdFrame->Data + 4 * 2, 4); + u4ChFreq = ntohl(u4ChFreq); + memcpy(&u4FIToneFreq, HqaCmdFrame->Data + 4 * 3, 4); + u4FIToneFreq = ntohl(u4FIToneFreq); + memcpy(&u4Band, HqaCmdFrame->Data + 4 * 4, 4); + u4Band = ntohl(u4Band); + + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_IRRSetTTG ext_id : %d\n", + u4Ext_id); + /* TTG Power Index: Power index value 0~15 */ + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_IRRSetTTG u4TTGPwrIdx : %d\n", u4TTGPwrIdx); + /* Ch Freq: channel frequency value */ + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_IRRSetTTG u4ChFreq : %d\n", u4ChFreq); + /* FI Tone Freq(float): driver calculate TTG Freq(TTG Freq = Ch_freq + + * FI tone freq) + */ + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_IRRSetTTG u4FIToneFreq : %d\n", u4FIToneFreq); + /* Band: DBDC band0 or band1 */ + DBGLOG(RFTEST, INFO, "QA_AGENT HQA_IRRSetTTG u4Band : %d\n", + u4Band); + + i4Ret = MT_ATE_IRRSetTTG(prNetDev, u4TTGPwrIdx, u4ChFreq, + u4FIToneFreq, u4Band); + + u4Ext_id = ntohl(u4Ext_id); + memcpy(HqaCmdFrame->Data + 2, (uint8_t *) &u4Ext_id, + sizeof(u4Ext_id)); + ResponseToQA(HqaCmdFrame, prIwReqData, 6, i4Ret); + + return i4Ret; +} + +static int32_t HQA_IRRSetTrunOnTTG(struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t u4Ext_id; + uint32_t u4TTGOnOff; + uint32_t u4Band; + uint32_t u4WF_inx = 0; + + memcpy(&u4Ext_id, HqaCmdFrame->Data + 4 * 0, 4); + u4Ext_id = ntohl(u4Ext_id); + memcpy(&u4TTGOnOff, HqaCmdFrame->Data + 4 * 1, 4); + u4TTGOnOff = ntohl(u4TTGOnOff); + memcpy(&u4Band, HqaCmdFrame->Data + 4 * 2, 4); + u4Band = ntohl(u4Band); + + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_IRRSetTrunOnTTG ext_id : %d\n", u4Ext_id); + /* TTG on/off: 0:off, 1: on */ + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_IRRSetTrunOnTTG u4TTGOnOff : %d\n", + u4TTGOnOff); + /* Band: DBDC band0 or band1 */ + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_IRRSetTrunOnTTG u4Band : %d\n", u4Band); + /* (each bit for each WF) */ + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA_IRRSetTrunOnTTG u4WF_inx : %d\n", u4WF_inx); + + i4Ret = MT_ATE_IRRSetTrunOnTTG(prNetDev, u4TTGOnOff, u4Band, + u4WF_inx); + + u4Ext_id = ntohl(u4Ext_id); + memcpy(HqaCmdFrame->Data + 2, (uint8_t *) &u4Ext_id, + sizeof(u4Ext_id)); + ResponseToQA(HqaCmdFrame, prIwReqData, 6, i4Ret); + + return i4Ret; +} + +static HQA_CMD_HANDLER hqa_ext_cmd_set[] = { + NULL, + hqa_set_channel_ext, /* 0x00000001 */ + hqa_set_txcontent_ext, /* 0x00000002 */ + hqa_start_tx_ext, /* 0x00000003 */ + hqa_start_rx_ext, /* 0x00000004 */ + hqa_stop_tx_ext, /* 0x00000005 */ + hqa_stop_rx_ext, /* 0x00000006 */ + HQA_iBFInit, /* 0x00000007 */ + HQA_iBFSetValue, /* 0x00000008 */ + HQA_iBFGetStatus, /* 0x00000009 */ + HQA_iBFChanProfUpdate, /* 0x0000000A */ + HQA_iBFProfileRead, /* 0x0000000B */ + ToDoFunction, /* 0x0000000C */ + ToDoFunction, /* 0x0000000D */ + ToDoFunction, /* 0x0000000E */ + ToDoFunction, /* 0x0000000F */ + ToDoFunction, /* 0x00000010 */ + ToDoFunction, /* 0x00000011 */ + ToDoFunction, /* 0x00000012 */ + ToDoFunction, /* 0x00000013 */ + ToDoFunction, /* 0x00000014 */ + ToDoFunction, /* 0x00000015 */ + ToDoFunction, /* 0x00000016 */ + ToDoFunction, /* 0x00000017 */ + ToDoFunction, /* 0x00000018 */ + ToDoFunction, /* 0x00000019 */ + ToDoFunction, /* 0x0000001A */ + ToDoFunction, /* 0x0000001B */ + ToDoFunction, /* 0x0000001C */ + ToDoFunction, /* 0x0000001D */ + ToDoFunction, /* 0x0000001E */ + ToDoFunction, /* 0x0000001F */ + HQA_IRRSetADC, /* 0x00000020 */ + HQA_IRRSetRxGain, /* 0x00000021 */ + HQA_IRRSetTTG, /* 0x00000022 */ + HQA_IRRSetTrunOnTTG, /* 0x00000023 */ +}; + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For Extension Commands (For MT7615). + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +static int32_t hqa_ext_cmds(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Ret = 0; + uint32_t u4Idx = 0; + + memmove((uint8_t *)&u4Idx, (uint8_t *)&HqaCmdFrame->Data, + 4); + u4Idx = ntohl(u4Idx); + + DBGLOG(RFTEST, INFO, "QA_AGENT hqa_ext_cmds index : %d\n", + u4Idx); + + if (u4Idx < (sizeof(hqa_ext_cmd_set) / sizeof(HQA_CMD_HANDLER))) { + if (hqa_ext_cmd_set[u4Idx] != NULL) { + /* valid command */ + i4Ret = (*hqa_ext_cmd_set[u4Idx])(prNetDev, + prIwReqData, HqaCmdFrame); + } else { + /* invalid command */ + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_ext_cmds cmd idx is NULL: %d\n", + u4Idx); + } + } else { + /* invalid command */ + DBGLOG(RFTEST, INFO, + "QA_AGENT hqa_ext_cmds cmd idx is not supported: %d\n", u4Idx); + } + + return i4Ret; +} + +static HQA_CMD_HANDLER HQA_CMD_SET6[] = { + /* cmd id start from 0x1600 */ + hqa_ext_cmds, /* 0x1600 */ +}; + +static struct HQA_CMD_TABLE HQA_CMD_TABLES[] = { + { + HQA_CMD_SET0, + sizeof(HQA_CMD_SET0) / sizeof(HQA_CMD_HANDLER), + 0x1000, + } + , + { + HQA_CMD_SET1, + sizeof(HQA_CMD_SET1) / sizeof(HQA_CMD_HANDLER), + 0x1100, + } + , + { + HQA_CMD_SET2, + sizeof(HQA_CMD_SET2) / sizeof(HQA_CMD_HANDLER), + 0x1200, + } + , + { + HQA_CMD_SET3, + sizeof(HQA_CMD_SET3) / sizeof(HQA_CMD_HANDLER), + 0x1300, + } + , + { + HQA_CMD_SET4, + sizeof(HQA_CMD_SET4) / sizeof(HQA_CMD_HANDLER), + 0x1400, + } + , + { + HQA_CMD_SET5, + sizeof(HQA_CMD_SET5) / sizeof(HQA_CMD_HANDLER), + 0x1500, + } + , +#if CFG_SUPPORT_TX_BF + { + HQA_TXBF_CMDS, + sizeof(HQA_TXBF_CMDS) / sizeof(HQA_CMD_HANDLER), + 0x1540, + } + , +#if CFG_SUPPORT_MU_MIMO + { + HQA_TXMU_CMDS, + sizeof(HQA_TXMU_CMDS) / sizeof(HQA_CMD_HANDLER), + 0x1560, + } + , +#endif +#endif + { + HQA_ICAP_CMDS, + sizeof(HQA_ICAP_CMDS) / sizeof(HQA_CMD_HANDLER), + 0x1580, + } + , + { + HQA_ReCal_CMDS, + sizeof(HQA_ReCal_CMDS) / sizeof(HQA_CMD_HANDLER), + 0x1581, + } + , + { + HQA_RXV_CMDS, + sizeof(HQA_RXV_CMDS) / sizeof(HQA_CMD_HANDLER), + 0x1582, + } + , + { + HQA_CMD_SET6, + sizeof(HQA_CMD_SET6) / sizeof(HQA_CMD_HANDLER), + 0x1600, + } + , +}; + +/*----------------------------------------------------------------------------*/ +/*! + * \brief QA Agent For Handle Ethernet command by Command Idx. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqData + * \param[in] HqaCmdFrame Ethernet Frame Format receive from QA Tool DLL + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +int HQA_CMDHandler(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame) +{ + int32_t i4Status = 0; + uint32_t u4CmdId; + uint32_t u4TableIndex = 0; + + u4CmdId = ntohs(HqaCmdFrame->Id); + + while (u4TableIndex < (sizeof(HQA_CMD_TABLES) / sizeof( + struct HQA_CMD_TABLE))) { + int CmdIndex = 0; + + CmdIndex = u4CmdId - HQA_CMD_TABLES[u4TableIndex].CmdOffset; + if ((CmdIndex >= 0) + && (CmdIndex < HQA_CMD_TABLES[u4TableIndex].CmdSetSize)) { + HQA_CMD_HANDLER *pCmdSet; + + pCmdSet = HQA_CMD_TABLES[u4TableIndex].CmdSet; + + if (pCmdSet[CmdIndex] != NULL) + i4Status = (*pCmdSet[CmdIndex])(prNetDev, + prIwReqData, HqaCmdFrame); + break; + } + u4TableIndex++; + } + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Ioctl entry from ATE Daemon. + * + * \param[in] prNetDev Pointer to the Net Device + * \param[in] prIwReqInfo + * \param[in] prIwReqData + * \param[in] pcExtra + * \param[out] None + * + * \retval 0 On success. + */ +/*----------------------------------------------------------------------------*/ +int priv_qa_agent(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN union iwreq_data *prIwReqData, IN char *pcExtra) +{ + int32_t i4Status = 0; + struct HQA_CMD_FRAME *HqaCmdFrame; + uint32_t u4ATEMagicNum, u4ATEId, u4ATEData; + struct GLUE_INFO *prGlueInfo = NULL; +#if (CONFIG_WLAN_SERVICE == 1) + struct hqa_frame_ctrl local_hqa; +#endif + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + ASSERT(prGlueInfo); + + /* workaroud for meta tool */ + if (prGlueInfo->prAdapter->fgTestMode == FALSE) + MT_ATEStart(prNetDev, "ATESTART"); + + if (!prIwReqData || prIwReqData->data.length == 0) { + i4Status = -EINVAL; + goto ERROR0; + } + + HqaCmdFrame = kmalloc(sizeof(*HqaCmdFrame), GFP_KERNEL); + + if (!HqaCmdFrame) { + i4Status = -ENOMEM; + goto ERROR0; + } + + memset(HqaCmdFrame, 0, sizeof(*HqaCmdFrame)); + if (copy_from_user(HqaCmdFrame, prIwReqData->data.pointer, + prIwReqData->data.length)) { + i4Status = -EFAULT; + goto ERROR1; + } + + u4ATEMagicNum = ntohl(HqaCmdFrame->MagicNo); + u4ATEId = ntohs(HqaCmdFrame->Id); + memcpy((uint8_t *)&u4ATEData, HqaCmdFrame->Data, 4); + u4ATEData = ntohl(u4ATEData); + + switch (u4ATEMagicNum) { + case HQA_CMD_MAGIC_NO: +#if (CONFIG_WLAN_SERVICE == 1) + /* OLD QA TOOL API use 6620 */ + if (prGlueInfo->prAdapter->chip_info + ->custom_oid_interface_version != 0x00006620) { + local_hqa.type = 0; + local_hqa.hqa_frame_comm.hqa_frame_eth = + (struct hqa_frame *)HqaCmdFrame; + + i4Status = mt_agent_hqa_cmd_handler(&prGlueInfo->rService, + (struct hqa_frame_ctrl *)&local_hqa); + + if (i4Status == WLAN_STATUS_SUCCESS) { + /*Response to QA */ + prIwReqData->data.length + = sizeof((HqaCmdFrame)->MagicNo) + + sizeof((HqaCmdFrame)->Type) + + sizeof((HqaCmdFrame)->Id) + + sizeof((HqaCmdFrame)->Length) + + sizeof((HqaCmdFrame)->Sequence) + + ntohs((HqaCmdFrame)->Length); + + if (copy_to_user(prIwReqData->data.pointer + , (uint8_t *) (HqaCmdFrame) + , prIwReqData->data.length)) { + DBGLOG(RFTEST, INFO + , "QA_AGENT copy_to_user() fail in %s\n" + , __func__); + goto ERROR1; + } + DBGLOG(RFTEST, INFO, + "QA_AGENT HQA cmd(0x%04x)Magic num(0x%08x) is done\n", + ntohs(HqaCmdFrame->Id), + ntohl(HqaCmdFrame->MagicNo)); + } + } else + i4Status = HQA_CMDHandler(prNetDev, prIwReqData, HqaCmdFrame); +#else + i4Status = HQA_CMDHandler(prNetDev, prIwReqData, HqaCmdFrame); +#endif + break; + default: + i4Status = -EINVAL; + DBGLOG(RFTEST, INFO, "QA_AGENT ATEMagicNum Error!!!\n"); + break; + } + + + +ERROR1: + kfree(HqaCmdFrame); +ERROR0: + return i4Status; +} +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_rst.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_rst.c new file mode 100644 index 0000000000000000000000000000000000000000..1c1032004e373549763578b440fea697c813ece5 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_rst.c @@ -0,0 +1,1093 @@ +/******************************************************************************* + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ +/* + ** Id: @(#) gl_rst.c@@ + */ + +/*! \file gl_rst.c + * \brief Main routines for supporintg MT6620 whole-chip reset mechanism + * + * This file contains the support routines of Linux driver for MediaTek Inc. + * 802.11 Wireless LAN Adapters. + */ + + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include +#include + +#include "precomp.h" +#include "gl_rst.h" + +#if (CFG_ANDORID_CONNINFRA_COREDUMP_SUPPORT == 1) +#include "fw_log_wifi.h" +#endif + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + + + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ +u_int8_t fgSimplifyResetFlow = FALSE; +uint64_t u8ResetTime; + +#if CFG_CHIP_RESET_HANG +u_int8_t fgIsResetHangState = SER_L0_HANG_RST_NONE; +#endif + +#if (CFG_SUPPORT_CONNINFRA == 1) +uint32_t g_u4WlanRstThreadPid; +wait_queue_head_t g_waitq_rst; +unsigned long g_ulFlag;/* GLUE_FLAG_XXX */ +struct completion g_RstOffComp; +struct completion g_RstOnComp; +struct completion g_triggerComp; +KAL_WAKE_LOCK_T *g_IntrWakeLock; +struct task_struct *wlan_reset_thread; +static int g_rst_data; +u_int8_t g_IsWholeChipRst = FALSE; +u_int8_t g_SubsysRstCnt; +int g_SubsysRstTotalCnt; +int g_WholeChipRstTotalCnt; +bool g_IsTriggerTimeout = FALSE; +u_int8_t g_IsSubsysRstOverThreshold = FALSE; +u_int8_t g_IsWfsysBusHang = FALSE; +char *g_reason; +enum consys_drv_type g_WholeChipRstType; +char *g_WholeChipRstReason; +u_int8_t g_IsWfsysResetOnFail = FALSE; +u_int8_t g_IsWfsysRstDone = TRUE; +u_int8_t g_fgRstRecover = FALSE; +#endif + +#if (CFG_ANDORID_CONNINFRA_COREDUMP_SUPPORT == 1) +static uint8_t *apucRstReason[RST_REASON_MAX] = { + (uint8_t *) DISP_STRING("RST_UNKNOWN"), + (uint8_t *) DISP_STRING("RST_PROCESS_ABNORMAL_INT"), + (uint8_t *) DISP_STRING("RST_DRV_OWN_FAIL"), + (uint8_t *) DISP_STRING("RST_FW_ASSERT"), + (uint8_t *) DISP_STRING("RST_BT_TRIGGER"), + (uint8_t *) DISP_STRING("RST_OID_TIMEOUT"), + (uint8_t *) DISP_STRING("RST_CMD_TRIGGER"), +}; +#endif + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ +static enum _ENUM_CHIP_RESET_REASON_TYPE_T eResetReason; + +#if CFG_CHIP_RESET_SUPPORT +static struct RESET_STRUCT wifi_rst; +u_int8_t fgIsResetting = FALSE; +#if (CFG_SUPPORT_CONNINFRA == 1) +enum ENUM_WF_RST_SOURCE g_eWfRstSource = WF_RST_SOURCE_NONE; +#endif +#endif + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +#if CFG_CHIP_RESET_SUPPORT + +#if CFG_WMT_RESET_API_SUPPORT +#if (CFG_SUPPORT_CONNINFRA == 0) +static void mtk_wifi_reset(struct work_struct *work); +static void mtk_wifi_trigger_reset(struct work_struct *work); +static void glResetCallback(enum _ENUM_WMTDRV_TYPE_T eSrcType, + enum _ENUM_WMTDRV_TYPE_T eDstType, + enum _ENUM_WMTMSG_TYPE_T eMsgType, void *prMsgBody, + unsigned int u4MsgLength); +#endif /*end of CFG_SUPPORT_CONNINFRA == 0*/ +#else +static u_int8_t is_bt_exist(void); +static u_int8_t rst_L0_notify_step1(void); +static void wait_core_dump_end(void); +#endif +#endif + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +void glSetRstReason(enum _ENUM_CHIP_RESET_REASON_TYPE_T + eReason) +{ + if (kalIsResetting()) + return; + + u8ResetTime = sched_clock(); + eResetReason = eReason; +} + +int glGetRstReason(void) +{ + return eResetReason; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is called for checking if connectivity chip is resetting + * + * @param None + * + * @retval TRUE + * FALSE + */ +/*----------------------------------------------------------------------------*/ +u_int8_t kalIsResetting(void) +{ +#if CFG_CHIP_RESET_SUPPORT + return fgIsResetting; +#else + return FALSE; +#endif +} + +#if CFG_CHIP_RESET_SUPPORT + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is responsible for + * 1. register wifi reset callback + * 2. initialize wifi reset work + * + * @param none + * + * @retval none + */ +/*----------------------------------------------------------------------------*/ +void glResetInit(struct GLUE_INFO *prGlueInfo) +{ +#if CFG_WMT_RESET_API_SUPPORT + /* 1. Register reset callback */ +#if (CFG_SUPPORT_CONNINFRA == 0) + mtk_wcn_wmt_msgcb_reg(WMTDRV_TYPE_WIFI, glResetCallback); + /* 2. Initialize reset work */ + INIT_WORK(&(wifi_rst.rst_trigger_work), + mtk_wifi_trigger_reset); + INIT_WORK(&(wifi_rst.rst_work), mtk_wifi_reset); +#endif +#endif + fgIsResetting = FALSE; + wifi_rst.prGlueInfo = prGlueInfo; + +#if (CFG_SUPPORT_CONNINFRA == 1) + +#if (CFG_ANDORID_CONNINFRA_COREDUMP_SUPPORT == 1) + fw_log_connsys_coredump_init(); +#endif + update_driver_reset_status(fgIsResetting); + KAL_WAKE_LOCK_INIT(NULL, g_IntrWakeLock, "WLAN Reset"); + init_waitqueue_head(&g_waitq_rst); + init_completion(&g_RstOffComp); + init_completion(&g_RstOnComp); + init_completion(&g_triggerComp); + wlan_reset_thread = kthread_run(wlan_reset_thread_main, + &g_rst_data, "wlan_rst_thread"); + g_SubsysRstCnt = 0; + +#endif /* CFG_SUPPORT_CONNINFRA */ +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is responsible for + * 1. deregister wifi reset callback + * + * @param none + * + * @retval none + */ +/*----------------------------------------------------------------------------*/ +void glResetUninit(void) +{ +#if CFG_WMT_RESET_API_SUPPORT + /* 1. Deregister reset callback */ +#if (CFG_SUPPORT_CONNINFRA == 0) + mtk_wcn_wmt_msgcb_unreg(WMTDRV_TYPE_WIFI); +#else + +#if (CFG_ANDORID_CONNINFRA_COREDUMP_SUPPORT == 1) + fw_log_connsys_coredump_deinit(); +#endif + + set_bit(GLUE_FLAG_HALT_BIT, &g_ulFlag); + wake_up_interruptible(&g_waitq_rst); +#endif +#endif +} +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is called for generating reset request to WMT + * + * @param None + * + * @retval None + */ +/*----------------------------------------------------------------------------*/ +void glSendResetRequest(void) +{ +#if CFG_WMT_RESET_API_SUPPORT + + /* WMT thread would trigger whole chip reset itself */ +#endif +} + +u_int8_t glResetTrigger(struct ADAPTER *prAdapter, + uint32_t u4RstFlag, const uint8_t *pucFile, uint32_t u4Line) +{ + u_int8_t fgResult = TRUE; + uint16_t u2FwOwnVersion; + uint16_t u2FwPeerVersion; +#if (CFG_SUPPORT_CONNINFRA == 1) + struct mt66xx_chip_info *prChipInfo; +#endif + dump_stack(); + if (kalIsResetting()) + return fgResult; + + fgIsResetting = TRUE; +#if (CFG_SUPPORT_CONNINFRA == 1) + update_driver_reset_status(fgIsResetting); +#endif +#if (CFG_SUPPORT_CONNINFRA == 0) + if (eResetReason != RST_BT_TRIGGER) + DBGLOG(INIT, STATE, "[SER][L0] wifi trigger eResetReason=%d\n", + eResetReason); + else + DBGLOG(INIT, STATE, "[SER][L0] BT trigger\n"); +#endif + +#if CFG_WMT_RESET_API_SUPPORT + if (u4RstFlag & RST_FLAG_DO_CORE_DUMP) + if (glIsWmtCodeDump()) + DBGLOG(INIT, WARN, "WMT is code dumping !\n"); +#endif + if (prAdapter == NULL) + prAdapter = wifi_rst.prGlueInfo->prAdapter; +#if (CFG_SUPPORT_CONNINFRA == 1) + prChipInfo = prAdapter->chip_info; +#endif + u2FwOwnVersion = prAdapter->rVerInfo.u2FwOwnVersion; + u2FwPeerVersion = prAdapter->rVerInfo.u2FwPeerVersion; + + DBGLOG(INIT, ERROR, + "Trigger chip reset in %s line %u! Chip[%04X E%u] FW Ver DEC[%u.%u] HEX[%x.%x], Driver Ver[%u.%u]\n", + pucFile, u4Line, MTK_CHIP_REV, + wlanGetEcoVersion(prAdapter), + (uint16_t)(u2FwOwnVersion >> 8), + (uint16_t)(u2FwOwnVersion & BITS(0, 7)), + (uint16_t)(u2FwOwnVersion >> 8), + (uint16_t)(u2FwOwnVersion & BITS(0, 7)), + (uint16_t)(u2FwPeerVersion >> 8), + (uint16_t)(u2FwPeerVersion & BITS(0, 7))); + + prAdapter->u4HifDbgFlag |= DEG_HIF_DEFAULT_DUMP; + halPrintHifDbgInfo(prAdapter); + +#if CFG_WMT_RESET_API_SUPPORT +#if (CFG_SUPPORT_CONNINFRA == 0) + wifi_rst.rst_trigger_flag = u4RstFlag; + schedule_work(&(wifi_rst.rst_trigger_work)); +#else + if (u4RstFlag & RST_FLAG_DO_CORE_DUMP) + g_fgRstRecover = FALSE; + else + g_fgRstRecover = TRUE; + + if (u4RstFlag & RST_FLAG_DO_WHOLE_RESET) { + if (prChipInfo->trigger_wholechiprst) + prChipInfo->trigger_wholechiprst(g_reason); + } else { + if (prChipInfo->triggerfwassert) + prChipInfo->triggerfwassert(); + } +#endif /*end of CFG_SUPPORT_CONNINFRA == 0*/ + +#else + wifi_rst.prGlueInfo = prAdapter->prGlueInfo; + schedule_work(&(wifi_rst.rst_work)); +#endif + + return fgResult; +} + + + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is called for wifi reset + * + * @param skb + * info + * + * @retval 0 + * nonzero + */ +/*----------------------------------------------------------------------------*/ +static void mtk_wifi_reset_main(struct RESET_STRUCT *rst) +{ + u_int8_t fgResult = FALSE; + int32_t ret; +#if CFG_WMT_RESET_API_SUPPORT + /* wlanOnAtReset(); */ + ret = wifi_reset_end(rst->rst_data); +#if (CFG_SUPPORT_CONNINFRA == 1) + update_driver_reset_status(fgIsResetting); + if (g_IsWholeChipRst == TRUE) { + g_IsWholeChipRst = FALSE; + g_IsWfsysBusHang = FALSE; + complete(&g_RstOnComp); + } +#endif +#else + fgResult = rst_L0_notify_step1(); + + wait_core_dump_end(); + + fgResult = rst->prGlueInfo->prAdapter->chip_info->rst_L0_notify_step2(); + +#if CFG_CHIP_RESET_HANG + if (fgIsResetHangState == SER_L0_HANG_RST_NONE) + fgIsResetHangState = SER_L0_HANG_RST_TRGING; +#endif + + if (is_bt_exist() == FALSE) + kalRemoveProbe(rst->prGlueInfo); + +#endif + if (fgSimplifyResetFlow) { + DBGLOG(INIT, INFO, "Force down the reset flag.\n"); + fgSimplifyResetFlow = FALSE; + } +#if (CFG_SUPPORT_CONNINFRA == 1) + if (ret != 0) { + g_IsWfsysResetOnFail = TRUE; + fgSimplifyResetFlow = TRUE; + DBGLOG(INIT, STATE, + "Wi-Fi reset on fail, set flag(%d).\n", + g_IsWfsysResetOnFail); + } else { + g_IsWfsysResetOnFail = FALSE; + DBGLOG(INIT, STATE, + "Wi-Fi reset on success, set flag(%d).\n", + g_IsWfsysResetOnFail); + } +#endif + DBGLOG(INIT, STATE, "[SER][L0] flow end, fgResult=%d\n", fgResult); +} + +#if CFG_WMT_RESET_API_SUPPORT +#if (CFG_SUPPORT_CONNINFRA == 0) +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is called for wifi reset + * + * @param skb + * info + * + * @retval 0 + * nonzero + */ +/*----------------------------------------------------------------------------*/ +static void mtk_wifi_reset(struct work_struct *work) +{ + struct RESET_STRUCT *rst = container_of(work, + struct RESET_STRUCT, rst_work); + mtk_wifi_reset_main(rst); +} + +static void mtk_wifi_trigger_reset(struct work_struct *work) +{ + u_int8_t fgResult = FALSE; + struct RESET_STRUCT *rst = container_of(work, + struct RESET_STRUCT, rst_trigger_work); + + fgIsResetting = TRUE; + /* Set the power off flag to FALSE in WMT to prevent chip power off + * after wlanProbe return failure, because we need to do core dump + * afterward. + */ + if (rst->rst_trigger_flag & RST_FLAG_PREVENT_POWER_OFF) + mtk_wcn_set_connsys_power_off_flag(FALSE); + + fgResult = mtk_wcn_wmt_assert_timeout(WMTDRV_TYPE_WIFI, 0x40, 0); + DBGLOG(INIT, INFO, "reset result %d, trigger flag 0x%x\n", + fgResult, rst->rst_trigger_flag); +} +#endif +/* Weak reference for those platform doesn't support wmt functions */ +int32_t __weak mtk_wcn_stp_coredump_start_get(void) +{ + return FALSE; +} + + +/*0= f/w assert flag is not set, others=f/w assert flag is set */ +int32_t glIsWmtCodeDump(void) +{ + return mtk_wcn_stp_coredump_start_get(); +} + +static void triggerHifDumpIfNeed(void) +{ + struct GLUE_INFO *prGlueInfo; + struct ADAPTER *prAdapter; + + if (fgIsResetting) + return; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wlanGetWiphy()); + if (!prGlueInfo || !prGlueInfo->u4ReadyFlag || !prGlueInfo->prAdapter) + return; + + prAdapter = prGlueInfo->prAdapter; + prAdapter->u4HifDbgFlag |= DEG_HIF_DEFAULT_DUMP; + kalSetHifDbgEvent(prAdapter->prGlueInfo); + /* wait for hif_thread finish dump */ + kalMsleep(100); +} + +#if (CFG_SUPPORT_CONNINFRA == 0) +static void dumpWlanThreadsIfNeed(void) +{ + struct GLUE_INFO *prGlueInfo; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wlanGetWiphy()); + if (!prGlueInfo || !prGlueInfo->u4ReadyFlag || !prGlueInfo->prAdapter) + return; + + if (fgIsResetting) + return; + + DBGLOG(INIT, INFO, "prGlueInfo->ulFlag: 0x%lx\n", prGlueInfo->ulFlag); + + if (prGlueInfo->main_thread) { + DBGLOG(INIT, INFO, "Show backtrace of main_thread.\n"); + kal_show_stack(prGlueInfo->prAdapter, prGlueInfo->main_thread, + NULL); + } + if (prGlueInfo->rx_thread) { + DBGLOG(INIT, INFO, "Show backtrace of rx_thread.\n"); + kal_show_stack(prGlueInfo->prAdapter, prGlueInfo->rx_thread, + NULL); + } + if (prGlueInfo->hif_thread) { + DBGLOG(INIT, INFO, "Show backtrace of hif_thread.\n"); + kal_show_stack(prGlueInfo->prAdapter, prGlueInfo->hif_thread, + NULL); + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is invoked when there is reset messages indicated + * + * @param eSrcType + * eDstType + * eMsgType + * prMsgBody + * u4MsgLength + * + * @retval + */ +/*----------------------------------------------------------------------------*/ +static void glResetCallback(enum _ENUM_WMTDRV_TYPE_T eSrcType, + enum _ENUM_WMTDRV_TYPE_T eDstType, + enum _ENUM_WMTMSG_TYPE_T eMsgType, void *prMsgBody, + unsigned int u4MsgLength) +{ + switch (eMsgType) { + case WMTMSG_TYPE_RESET: + if (u4MsgLength == sizeof(enum _ENUM_WMTRSTMSG_TYPE_T)) { + enum _ENUM_WMTRSTMSG_TYPE_T *prRstMsg = + (enum _ENUM_WMTRSTMSG_TYPE_T *) prMsgBody; + + switch (*prRstMsg) { + case WMTRSTMSG_RESET_START: + DBGLOG(INIT, WARN, "Whole chip reset start!\n"); + dumpWlanThreadsIfNeed(); + triggerHifDumpIfNeed(); + fgIsResetting = TRUE; + fgSimplifyResetFlow = TRUE; + wifi_reset_start(); + break; + + case WMTRSTMSG_RESET_END: + DBGLOG(INIT, WARN, "Whole chip reset end!\n"); + wifi_rst.rst_data = RESET_SUCCESS; + fgIsResetting = FALSE; + schedule_work(&(wifi_rst.rst_work)); + break; + + case WMTRSTMSG_RESET_END_FAIL: + DBGLOG(INIT, WARN, "Whole chip reset fail!\n"); + fgIsResetting = FALSE; + wifi_rst.rst_data = RESET_FAIL; + schedule_work(&(wifi_rst.rst_work)); + break; + + default: + break; + } + } + break; + + default: + break; + } +} +#else + +void glSetRstReasonString(char *reason) +{ + g_reason = reason; +} + + +static u_int8_t glResetMsgHandler(enum ENUM_WMTMSG_TYPE eMsgType, + enum ENUM_WMTRSTMSG_TYPE MsgBody) +{ + switch (eMsgType) { + case WMTMSG_TYPE_RESET: + + switch (MsgBody) { + case WMTRSTMSG_RESET_START: + DBGLOG(INIT, WARN, "Whole chip reset start!\n"); + fgIsResetting = TRUE; + fgSimplifyResetFlow = TRUE; + wifi_reset_start(); + hifAxiRemove(); + complete(&g_RstOffComp); + break; + + case WMTRSTMSG_RESET_END: + DBGLOG(INIT, WARN, "WF reset end!\n"); + fgIsResetting = FALSE; + wifi_rst.rst_data = RESET_SUCCESS; + mtk_wifi_reset_main(&wifi_rst); + break; + + case WMTRSTMSG_RESET_END_FAIL: + DBGLOG(INIT, WARN, "Whole chip reset fail!\n"); + fgIsResetting = FALSE; + wifi_rst.rst_data = RESET_FAIL; + schedule_work(&(wifi_rst.rst_work)); + break; + case WMTRSTMSG_0P5RESET_START: + DBGLOG(INIT, WARN, "WF chip reset start!\n"); + fgIsResetting = TRUE; + fgSimplifyResetFlow = TRUE; + wifi_reset_start(); + hifAxiRemove(); + break; + default: + break; + } + break; + + default: + break; + } + + return TRUE; +} +bool glRstCheckRstCriteria(void) +{ + /* + * for those cases which need to trigger whole chip reset + * when fgIsResetting = TRUE + */ + if (g_IsSubsysRstOverThreshold || g_IsWfsysBusHang) + return FALSE; + else + return TRUE; +} +void glRstWholeChipRstParamInit(void) +{ + g_IsSubsysRstOverThreshold = FALSE; + g_SubsysRstCnt = 0; + g_IsTriggerTimeout = FALSE; + g_WholeChipRstTotalCnt++; +} +void glRstSetRstEndEvent(void) +{ + KAL_WAKE_LOCK(NULL, g_IntrWakeLock); + + set_bit(GLUE_FLAG_RST_END_BIT, &g_ulFlag); + + /* when we got interrupt, we wake up servie thread */ + wake_up_interruptible(&g_waitq_rst); + +} + +int glRstwlanPreWholeChipReset(enum consys_drv_type type, char *reason) +{ + bool bRet = 0; + struct GLUE_INFO *prGlueInfo; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wlanGetWiphy()); + DBGLOG(INIT, INFO, + "Enter glRstwlanPreWholeChipReset.\n"); + while (get_wifi_process_status() == 1) { + DBGLOG(REQ, WARN, + "Wi-Fi on/off process is ongoing, wait here.\n"); + msleep(100); + } + if (!get_wifi_powered_status()) { + DBGLOG(REQ, WARN, "wifi driver is off now\n"); + return bRet; + } + + triggerHifDumpIfNeed(); + + g_WholeChipRstType = type; + g_WholeChipRstReason = reason; + + if (glRstCheckRstCriteria()) { + while (kalIsResetting()) { + DBGLOG(REQ, WARN, "wifi driver is resetting\n"); + msleep(100); + } + while ((!prGlueInfo) || + (prGlueInfo->u4ReadyFlag == 0) || + (g_IsWfsysRstDone == FALSE)) { + prGlueInfo = + (struct GLUE_INFO *) wiphy_priv(wlanGetWiphy()); + DBGLOG(REQ, WARN, "wifi driver is not ready\n"); + if (g_IsWfsysResetOnFail == TRUE) { + DBGLOG(REQ, WARN, + "wifi driver reset fail, need whole chip reset.\n"); + g_IsWholeChipRst = TRUE; + return bRet; + } + msleep(100); + } + g_IsWholeChipRst = TRUE; + DBGLOG(INIT, INFO, + "Wi-Fi Driver processes whole chip reset start.\n"); + GL_RESET_TRIGGER(prGlueInfo->prAdapter, + RST_FLAG_WF_RESET); + } else { + if (g_IsSubsysRstOverThreshold) + DBGLOG(INIT, INFO, "Reach subsys reset threshold!!!\n"); + else if (g_IsWfsysBusHang) + DBGLOG(INIT, INFO, "WFSYS bus hang!!!\n"); + g_IsWholeChipRst = TRUE; + kalSetRstEvent(); + } + wait_for_completion(&g_RstOffComp); + DBGLOG(INIT, INFO, "Wi-Fi is off successfully.\n"); + + return bRet; +} + +int glRstwlanPostWholeChipReset(void) +{ + while (get_wifi_process_status() == 1) { + DBGLOG(REQ, WARN, + "Wi-Fi on/off process is ongoing, wait here.\n"); + msleep(100); + } + if (!get_wifi_powered_status()) { + DBGLOG(REQ, WARN, "wifi driver is off now\n"); + return 0; + } + glRstSetRstEndEvent(); + DBGLOG(INIT, INFO, "Wait Wi-Fi state recover.\n"); + wait_for_completion(&g_RstOnComp); + + DBGLOG(INIT, INFO, + "Leave glRstwlanPostWholeChipReset (%d).\n", + g_IsWholeChipRst); + return 0; +} +u_int8_t kalIsWholeChipResetting(void) +{ +#if CFG_CHIP_RESET_SUPPORT + return g_IsWholeChipRst; +#else + return FALSE; +#endif +} +void glReset_timeinit(struct timeval *rNowTs, struct timeval *rLastTs) +{ + rNowTs->tv_sec = 0; + rNowTs->tv_usec = 0; + rLastTs->tv_sec = 0; + rLastTs->tv_usec = 0; +} + +bool IsOverRstTimeThreshold(struct timeval *rNowTs, struct timeval *rLastTs) +{ + struct timeval rTimeout, rTime = {0}; + bool fgIsTimeout = FALSE; + + rTimeout.tv_sec = 30; + rTimeout.tv_usec = 0; + do_gettimeofday(rNowTs); + DBGLOG(INIT, INFO, + "Reset happen time :%d.%d, last happen time :%d.%d\n", + rNowTs->tv_sec, + rNowTs->tv_usec, + rLastTs->tv_sec, + rLastTs->tv_usec); + if (rLastTs->tv_sec != 0) { + /* Ignore now time < token time */ + if (halTimeCompare(rNowTs, rLastTs) > 0) { + rTime.tv_sec = rNowTs->tv_sec - rLastTs->tv_sec; + rTime.tv_usec = rNowTs->tv_usec; + if (rLastTs->tv_usec > rNowTs->tv_usec) { + rTime.tv_sec -= 1; + rTime.tv_usec += SEC_TO_USEC(1); + } + rTime.tv_usec -= rLastTs->tv_usec; + if (halTimeCompare(&rTime, &rTimeout) >= 0) + fgIsTimeout = TRUE; + else + fgIsTimeout = FALSE; + } + DBGLOG(INIT, INFO, + "Reset rTimeout :%d.%d, calculate time :%d.%d\n", + rTimeout.tv_sec, + rTimeout.tv_usec, + rTime.tv_sec, + rTime.tv_usec); + } + return fgIsTimeout; +} +void glResetSubsysRstProcedure( + struct ADAPTER *prAdapter, + struct timeval *rNowTs, + struct timeval *rLastTs) +{ + bool fgIsTimeout; + struct mt66xx_chip_info *prChipInfo; + struct WIFI_VAR *prWifiVar = &prAdapter->rWifiVar; + + if (prWifiVar->fgRstRecover == 1) + g_fgRstRecover = TRUE; +#if 0 + if (prAdapter->chip_info->checkbushang) + prAdapter->chip_info->checkbushang(FALSE); +#endif + fgIsTimeout = IsOverRstTimeThreshold(rNowTs, rLastTs); + if (g_IsWfsysBusHang == TRUE) { + /* dump host cr */ + if (prAdapter->chip_info->dumpBusHangCr) + prAdapter->chip_info->dumpBusHangCr(prAdapter); + glSetRstReasonString( + "fw detect bus hang"); + prChipInfo = prAdapter->chip_info; + if (prChipInfo->trigger_wholechiprst) + prChipInfo->trigger_wholechiprst(g_reason); + g_IsTriggerTimeout = FALSE; + return; + } + if (g_SubsysRstCnt > 3) { + if (fgIsTimeout == TRUE) { + /* + * g_SubsysRstCnt > 3, > 30 sec, + * need to update rLastTs, still do wfsys reset + */ +#if (CFG_ANDORID_CONNINFRA_COREDUMP_SUPPORT == 1) + if (eResetReason >= RST_REASON_MAX) + eResetReason = 0; + if (g_fgRstRecover == TRUE) + g_fgRstRecover = FALSE; + else { + if (g_eWfRstSource == WF_RST_SOURCE_FW) + fw_log_connsys_coredump_start(-1, NULL); + else + fw_log_connsys_coredump_start( + CONNDRV_TYPE_WIFI, + apucRstReason[eResetReason]); + } +#endif + glResetMsgHandler(WMTMSG_TYPE_RESET, + WMTRSTMSG_0P5RESET_START); + glResetMsgHandler(WMTMSG_TYPE_RESET, + WMTRSTMSG_RESET_END); + g_SubsysRstTotalCnt++; + g_SubsysRstCnt = 1; + } else { + /*g_SubsysRstCnt > 3, < 30 sec, do whole chip reset */ + g_IsSubsysRstOverThreshold = TRUE; + /*coredump is done, no need do again*/ + g_IsTriggerTimeout = TRUE; + glSetRstReasonString( + "subsys reset more than 3 times"); + prChipInfo = prAdapter->chip_info; + if (prChipInfo->trigger_wholechiprst) + prChipInfo->trigger_wholechiprst(g_reason); + } + } else { +#if (CFG_ANDORID_CONNINFRA_COREDUMP_SUPPORT == 1) + if (eResetReason >= RST_REASON_MAX) + eResetReason = 0; + if (g_fgRstRecover == TRUE) + g_fgRstRecover = FALSE; + else { + if (g_eWfRstSource == WF_RST_SOURCE_FW) + fw_log_connsys_coredump_start(-1, NULL); + else + fw_log_connsys_coredump_start( + CONNDRV_TYPE_WIFI, + apucRstReason[eResetReason]); + } + +#endif + glResetMsgHandler(WMTMSG_TYPE_RESET, + WMTRSTMSG_0P5RESET_START); + glResetMsgHandler(WMTMSG_TYPE_RESET, + WMTRSTMSG_RESET_END); + g_SubsysRstTotalCnt++; + /*g_SubsysRstCnt < 3, but >30 sec,need to update rLastTs*/ + if (fgIsTimeout == TRUE) + g_SubsysRstCnt = 1; + } + if (g_SubsysRstCnt == 1) { + rLastTs->tv_sec = rNowTs->tv_sec; + rLastTs->tv_usec = rNowTs->tv_usec; + } + g_IsTriggerTimeout = FALSE; +#if (CFG_ANDORID_CONNINFRA_COREDUMP_SUPPORT == 1) + g_eWfRstSource = WF_RST_SOURCE_NONE; +#endif +} +int wlan_reset_thread_main(void *data) +{ + int ret = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct timeval rNowTs, rLastTs; + +#if defined(CONFIG_ANDROID) && (CFG_ENABLE_WAKE_LOCK) + KAL_WAKE_LOCK_T *prWlanRstThreadWakeLock; + + KAL_WAKE_LOCK_INIT(NULL, + prWlanRstThreadWakeLock, "WLAN rst_thread"); + KAL_WAKE_LOCK(NULL, prWlanRstThreadWakeLock); +#endif + + glReset_timeinit(&rNowTs, &rLastTs); + + DBGLOG(INIT, INFO, "%s:%u starts running...\n", + KAL_GET_CURRENT_THREAD_NAME(), KAL_GET_CURRENT_THREAD_ID()); + + g_u4WlanRstThreadPid = KAL_GET_CURRENT_THREAD_ID(); + + while (TRUE) { + /* Unlock wakelock if hif_thread going to idle */ + KAL_WAKE_UNLOCK(NULL, prWlanRstThreadWakeLock); + /* + * sleep on waitqueue if no events occurred. Event contain + * (1) GLUE_FLAG_HALT (2) GLUE_FLAG_RST + * + */ + do { + ret = wait_event_interruptible(g_waitq_rst, + ((g_ulFlag & GLUE_FLAG_RST_PROCESS) + != 0)); + } while (ret != 0); +#if defined(CONFIG_ANDROID) && (CFG_ENABLE_WAKE_LOCK) + if (!KAL_WAKE_LOCK_ACTIVE(NULL, + prWlanRstThreadWakeLock)) + KAL_WAKE_LOCK(NULL, + prWlanRstThreadWakeLock); +#endif + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wlanGetWiphy()); + if (test_and_clear_bit(GLUE_FLAG_RST_START_BIT, &g_ulFlag) && + ((prGlueInfo) && (prGlueInfo->u4ReadyFlag))) { + if (KAL_WAKE_LOCK_ACTIVE(NULL, g_IntrWakeLock)) + KAL_WAKE_UNLOCK(NULL, g_IntrWakeLock); + + if (g_IsWholeChipRst) { +#if (CFG_ANDORID_CONNINFRA_COREDUMP_SUPPORT == 1) + if (eResetReason >= RST_REASON_MAX) + eResetReason = 0; + fw_log_connsys_coredump_start( + g_WholeChipRstType, + g_WholeChipRstReason); +#endif + glResetMsgHandler(WMTMSG_TYPE_RESET, + WMTRSTMSG_RESET_START); + glRstWholeChipRstParamInit(); + glReset_timeinit(&rNowTs, &rLastTs); + } else { + /*wfsys reset start*/ + g_IsWfsysRstDone = FALSE; + g_SubsysRstCnt++; + DBGLOG(INIT, INFO, + "WF reset count = %d.\n", + g_SubsysRstCnt); + glResetSubsysRstProcedure(prGlueInfo->prAdapter, + &rNowTs, + &rLastTs); + /*wfsys reset done*/ + g_IsWfsysRstDone = TRUE; + } + DBGLOG(INIT, INFO, + "Whole Chip rst count /WF reset total count = (%d)/(%d).\n", + g_WholeChipRstTotalCnt, + g_SubsysRstTotalCnt); + } + if (test_and_clear_bit(GLUE_FLAG_RST_END_BIT, &g_ulFlag)) { + if (KAL_WAKE_LOCK_ACTIVE(NULL, g_IntrWakeLock)) + KAL_WAKE_UNLOCK(NULL, g_IntrWakeLock); + DBGLOG(INIT, INFO, "Whole chip reset end start\n"); + glResetMsgHandler(WMTMSG_TYPE_RESET, + WMTRSTMSG_RESET_END); + } + if (test_and_clear_bit(GLUE_FLAG_HALT_BIT, &g_ulFlag)) { + DBGLOG(INIT, INFO, "rst_thread should stop now...\n"); + break; + } + } + +#if defined(CONFIG_ANDROID) && (CFG_ENABLE_WAKE_LOCK) + if (KAL_WAKE_LOCK_ACTIVE(NULL, + prWlanRstThreadWakeLock)) + KAL_WAKE_UNLOCK(NULL, prWlanRstThreadWakeLock); + KAL_WAKE_LOCK_DESTROY(NULL, + prWlanRstThreadWakeLock); +#endif + + DBGLOG(INIT, TRACE, "%s:%u stopped!\n", + KAL_GET_CURRENT_THREAD_NAME(), KAL_GET_CURRENT_THREAD_ID()); + + return 0; +} +#endif +#else +static u_int8_t is_bt_exist(void) +{ + typedef int (*p_bt_fun_type) (int); + p_bt_fun_type bt_func; + char *bt_func_name = "WF_rst_L0_notify_BT_step1"; + + bt_func = (p_bt_fun_type) kallsyms_lookup_name(bt_func_name); + if (bt_func) + return TRUE; + + DBGLOG(INIT, ERROR, "[SER][L0] %s does not exist\n", bt_func_name); + return FALSE; + +} + +static u_int8_t rst_L0_notify_step1(void) +{ + if (eResetReason != RST_BT_TRIGGER) { + typedef int (*p_bt_fun_type) (int); + p_bt_fun_type bt_func; + char *bt_func_name = "WF_rst_L0_notify_BT_step1"; + + DBGLOG(INIT, STATE, "[SER][L0] %s\n", bt_func_name); + bt_func = (p_bt_fun_type) kallsyms_lookup_name(bt_func_name); + if (bt_func) { + bt_func(0); + } else { + DBGLOG(INIT, ERROR, + "[SER][L0] %s does not exist\n", bt_func_name); + return FALSE; + } + } + + return TRUE; +} + +static void wait_core_dump_end(void) +{ +#ifdef CFG_SUPPORT_CONNAC2X + if (eResetReason == RST_OID_TIMEOUT) + return; + DBGLOG(INIT, WARN, "[SER][L0] not support..\n"); +#endif +} + +int32_t BT_rst_L0_notify_WF_step1(int32_t reserved) +{ + glSetRstReason(RST_BT_TRIGGER); + GL_RESET_TRIGGER(NULL, RST_FLAG_CHIP_RESET); + + return 0; +} +EXPORT_SYMBOL(BT_rst_L0_notify_WF_step1); + +int32_t BT_rst_L0_notify_WF_2(int32_t reserved) +{ + DBGLOG(INIT, WARN, "[SER][L0] not support...\n"); + + return 0; +} +EXPORT_SYMBOL(BT_rst_L0_notify_WF_2); + +#endif +#endif + + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_sec.o.new b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_sec.o.new new file mode 100644 index 0000000000000000000000000000000000000000..0756dd14f46395dfcdf67ae6ef41c2c0d3563772 Binary files /dev/null and b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_sec.o.new differ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_sys.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_sys.c new file mode 100644 index 0000000000000000000000000000000000000000..62229ee690b5c2c91fb8a63b97a0e9fa9f3bc566 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_sys.c @@ -0,0 +1,568 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +/* + ** Id: /os/linux/gl_sys.c + */ + +/*! \file "gl_sys.c" + * \brief This file defines the interface which can interact with users + * in /sys fs. + * + * Detail description. + */ + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" +#include "gl_os.h" +#include "gl_kal.h" +#include "debug.h" +#include "wlan_lib.h" +#include "debug.h" +#include "wlan_oid.h" +#include +#include +#include +#include +#include +#include + +#if WLAN_INCLUDE_SYS + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#define MTK_INFO_MAX_SIZE 128 + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +static struct GLUE_INFO *g_prGlueInfo; +static struct kobject *wifi_kobj; +static uint8_t aucMacAddrOverride[] = "FF:FF:FF:FF:FF:FF"; +static uint8_t aucDefaultFWVersion[] = "Unknown"; +static u_int8_t fgIsMacAddrOverride = FALSE; +static int32_t g_i4PM = -1; +static char acVerInfo[MTK_INFO_MAX_SIZE]; +static char acSoftAPInfo[MTK_INFO_MAX_SIZE]; + +#if BUILD_QA_DBG +static uint32_t g_u4Memdump = 3; +#else +static uint32_t g_u4Memdump = 2; +#endif + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +static ssize_t pm_show( + struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + return snprintf(buf, + sizeof(g_i4PM), + "%d", g_i4PM); +} + +static void pm_EnterCtiaMode(void) +{ + if (!g_prGlueInfo) + DBGLOG(INIT, ERROR, "g_prGlueInfo is null\n"); + else if (g_i4PM == -1) + DBGLOG(INIT, TRACE, "keep default\n"); + else { + g_prGlueInfo->prAdapter->fgEnDbgPowerMode = !g_i4PM; + nicEnterCtiaMode(g_prGlueInfo->prAdapter, + !g_i4PM, + FALSE); + } +} + +static ssize_t pm_store( + struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t count) +{ + int32_t i4Ret = 0; + + i4Ret = kstrtoint(buf, 10, &g_i4PM); + + if (i4Ret) + DBGLOG(INIT, ERROR, "sscanf pm fail u4Ret=%d\n", i4Ret); + else { + DBGLOG(INIT, INFO, + "Set PM to %d.\n", + g_i4PM); + + pm_EnterCtiaMode(); + } + + return (i4Ret == 0) ? count : 0; +} + +static ssize_t macaddr_show( + struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + return snprintf(buf, + sizeof(aucMacAddrOverride), + "%s", aucMacAddrOverride); +} + +static ssize_t macaddr_store( + struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t count) +{ + int32_t i4Ret = 0; + + i4Ret = sscanf(buf, "%18s", (uint8_t *)&aucMacAddrOverride); + + if (!i4Ret) + DBGLOG(INIT, ERROR, "sscanf mac format fail u4Ret=%d\n", i4Ret); + else { + DBGLOG(INIT, INFO, + "Set macaddr to %s.\n", + aucMacAddrOverride); + } + + fgIsMacAddrOverride = TRUE; + + return (i4Ret > 0) ? count : 0; +} + +static ssize_t wifiver_show( + struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + return snprintf(buf, + sizeof(acVerInfo), "%s", + acVerInfo); +} + +static ssize_t softap_show( + struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + return snprintf(buf, sizeof(acSoftAPInfo), "%s", acSoftAPInfo); +} + +static ssize_t memdump_show( + struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + return snprintf(buf, + sizeof(g_u4Memdump), + "%d", g_u4Memdump); +} + +static ssize_t memdump_store( + struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t count) +{ + int32_t i4Ret = 0; + + i4Ret = kstrtouint(buf, 10, &g_u4Memdump); + + if (i4Ret) + DBGLOG(INIT, ERROR, "sscanf memdump fail u4Ret=%d\n", i4Ret); + else { + DBGLOG(INIT, INFO, + "Set memdump to %d.\n", + g_u4Memdump); + } + + return (i4Ret == 0) ? count : 0; +} + + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +static struct kobj_attribute macaddr_attr + = __ATTR(mac_addr, 0664, macaddr_show, macaddr_store); + +static struct kobj_attribute wifiver_attr + = __ATTR(wifiver, 0664, wifiver_show, NULL); + +static struct kobj_attribute softap_attr + = __ATTR(softap, 0664, softap_show, NULL); + +static struct kobj_attribute pm_attr + = __ATTR(pm, 0664, pm_show, pm_store); + +static struct kobj_attribute memdump_attr + = __ATTR(memdump, 0664, memdump_show, memdump_store); + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +void sysCreateMacAddr(void) +{ + if (g_prGlueInfo) { + uint8_t rMacAddr[MAC_ADDR_LEN]; + + COPY_MAC_ADDR(rMacAddr, + g_prGlueInfo->prAdapter->rWifiVar.aucMacAddress); + + kalSnprintf(aucMacAddrOverride, + sizeof(aucMacAddrOverride), + "%pM", + MAC2STR(rMacAddr)); + + DBGLOG(INIT, TRACE, + "Init macaddr to " MACSTR ".\n", + MAC2STR(rMacAddr)); + } +} + +void sysInitMacAddr(void) +{ + int32_t i4Ret = 0; + + if (!wifi_kobj) { + DBGLOG(INIT, ERROR, "wifi_kobj is null\n"); + return; + } + + i4Ret = sysfs_create_file(wifi_kobj, &macaddr_attr.attr); + if (i4Ret) + DBGLOG(INIT, ERROR, "Unable to create macaddr entry\n"); +} + +void sysUninitMacAddr(void) +{ + if (!wifi_kobj) { + DBGLOG(INIT, ERROR, "wifi_kobj is null\n"); + return; + } + + sysfs_remove_file(wifi_kobj, &macaddr_attr.attr); +} + +void sysInitPM(void) +{ + int32_t i4Ret = 0; + + if (!wifi_kobj) { + DBGLOG(INIT, ERROR, "wifi_kobj is null\n"); + return; + } + + i4Ret = sysfs_create_file(wifi_kobj, &pm_attr.attr); + if (i4Ret) + DBGLOG(INIT, ERROR, "Unable to create macaddr entry\n"); +} + +void sysUninitPM(void) +{ + if (!wifi_kobj) { + DBGLOG(INIT, ERROR, "wifi_kobj is null\n"); + return; + } + + sysfs_remove_file(wifi_kobj, &pm_attr.attr); +} + +void sysCreateWifiVer(void) +{ +#define STR_HELPER(x) #x +#define STR(x) STR_HELPER(x) + + char aucDriverVersionStr[] = STR(NIC_DRIVER_MAJOR_VERSION) "_" + STR(NIC_DRIVER_MINOR_VERSION) "_" + STR(NIC_DRIVER_SERIAL_VERSION) "-" + DRIVER_BUILD_DATE; + uint16_t u2NvramVer = 0; + uint8_t ucOffset = 0; + + kalMemZero(acVerInfo, sizeof(acVerInfo)); + + ucOffset += kalSnprintf(acVerInfo + ucOffset + , MTK_INFO_MAX_SIZE - ucOffset + , "%s\n", "Mediatek"); + + ucOffset += kalSnprintf(acVerInfo + ucOffset + , MTK_INFO_MAX_SIZE - ucOffset + , "DRIVER_VER: %s\n", aucDriverVersionStr); + + if (g_prGlueInfo) + ucOffset += kalSnprintf(acVerInfo + ucOffset + , MTK_INFO_MAX_SIZE - ucOffset + , "FW_VER: %s\n" + , g_prGlueInfo->prAdapter->rVerInfo.aucReleaseManifest); + else { + ucOffset += kalSnprintf(acVerInfo + ucOffset + , MTK_INFO_MAX_SIZE - ucOffset + , "FW_VER: %s\n" + , aucDefaultFWVersion); + } + + if (g_prGlueInfo) { + kalCfgDataRead16(g_prGlueInfo, + OFFSET_OF(struct WIFI_CFG_PARAM_STRUCT, + u2Part1OwnVersion), &u2NvramVer); + ucOffset += kalSnprintf(acVerInfo + ucOffset + , MTK_INFO_MAX_SIZE - ucOffset + , "NVRAM: 0x%x\n", u2NvramVer); + } else { + ucOffset += kalSnprintf(acVerInfo + ucOffset + , MTK_INFO_MAX_SIZE - ucOffset + , "NVRAM: Unknown\n"); + } +} + +void sysInitWifiVer(void) +{ + int32_t i4Ret = 0; + + if (!wifi_kobj) { + DBGLOG(INIT, ERROR, "wifi_kobj is null\n"); + return; + } + + i4Ret = sysfs_create_file(wifi_kobj, &wifiver_attr.attr); + if (i4Ret) + DBGLOG(INIT, ERROR, "Unable to create wifiver entry\n"); + + sysCreateWifiVer(); +} + +void sysUninitWifiVer(void) +{ + if (!wifi_kobj) { + DBGLOG(INIT, ERROR, "wifi_kobj is null\n"); + return; + } + + sysfs_remove_file(wifi_kobj, &wifiver_attr.attr); +} + +void sysCreateSoftap(void) +{ + struct REG_INFO *prRegInfo = NULL; + + uint8_t ucOffset = 0; + u_int8_t fgDbDcModeEn = FALSE; + + /* Log SoftAP/hotspot information into .softap.info + * #Support wifi and hotspot at the same time? + * DualBandConcurrency=no + * # Supporting 5Ghz + * 5G=check NVRAM ucEnable5GBand + * # Max support client count + * maxClient=P2P_MAXIMUM_CLIENT_COUNT + * #Supporting android_net_wifi_set_Country_Code_Hal + * HalFn_setCountryCodeHal=yes , + * call mtk_cfg80211_vendor_set_country_code + * #Supporting android_net_wifi_getValidChannels + * HalFn_getValidChannels=yes, + * call mtk_cfg80211_vendor_get_channel_list + */ + + if (g_prGlueInfo) { + prRegInfo = &(g_prGlueInfo->rRegInfo); +#if CFG_SUPPORT_DBDC + fgDbDcModeEn = g_prGlueInfo->prAdapter->rWifiVar.fgDbDcModeEn; +#endif + } + + kalMemZero(acSoftAPInfo, sizeof(acSoftAPInfo)); + + ucOffset = 0; + + if (g_prGlueInfo) { + ucOffset += kalSnprintf(acSoftAPInfo + ucOffset + , MTK_INFO_MAX_SIZE - ucOffset + , "DualBandConcurrency=%s\n" + , fgDbDcModeEn ? "yes" : "no"); + } else + ucOffset += kalSnprintf(acSoftAPInfo + ucOffset + , MTK_INFO_MAX_SIZE - ucOffset + , "DualBandConcurrency=no\n"); + + if (prRegInfo) + ucOffset += kalSnprintf(acSoftAPInfo + ucOffset + , MTK_INFO_MAX_SIZE - ucOffset + , "5G=%s\n", prRegInfo->ucEnable5GBand ? "yes" : "no"); + else + ucOffset += kalSnprintf(acSoftAPInfo + ucOffset + , MTK_INFO_MAX_SIZE - ucOffset + , "5G=yes\n"); + + ucOffset += kalSnprintf(acSoftAPInfo + ucOffset + , MTK_INFO_MAX_SIZE - ucOffset + , "maxClient=%d\n", P2P_MAXIMUM_CLIENT_COUNT); + + ucOffset += kalSnprintf(acSoftAPInfo + ucOffset + , MTK_INFO_MAX_SIZE - ucOffset + , "HalFn_setCountryCodeHal=%s\n", "yes"); + + ucOffset += kalSnprintf(acSoftAPInfo + ucOffset + , MTK_INFO_MAX_SIZE - ucOffset + , "HalFn_getValidChannels=%s\n", "yes"); + + ucOffset += kalSnprintf(acSoftAPInfo + ucOffset + , MTK_INFO_MAX_SIZE - ucOffset + , "DualInterface=%s\n", "yes"); +} + +void sysInitSoftap(void) +{ + int32_t i4Ret = 0; + + if (!wifi_kobj) { + DBGLOG(INIT, ERROR, "wifi_kobj is null\n"); + return; + } + + i4Ret = sysfs_create_file(wifi_kobj, &softap_attr.attr); + if (i4Ret) + DBGLOG(INIT, ERROR, "Unable to create softap entry\n"); + + sysCreateSoftap(); +} + +void sysUninitSoftap(void) +{ + if (!wifi_kobj) { + DBGLOG(INIT, ERROR, "wifi_kobj is null\n"); + return; + } + + sysfs_remove_file(wifi_kobj, &softap_attr.attr); +} + +void sysInitMemdump(void) +{ + int32_t i4Ret = 0; + + if (!wifi_kobj) { + DBGLOG(INIT, ERROR, "wifi_kobj is null\n"); + return; + } + + i4Ret = sysfs_create_file(wifi_kobj, &memdump_attr.attr); + if (i4Ret) + DBGLOG(INIT, ERROR, "Unable to create softap entry\n"); +} + +void sysUninitMemdump(void) +{ + if (!wifi_kobj) { + DBGLOG(INIT, ERROR, "wifi_kobj is null\n"); + return; + } + + sysfs_remove_file(wifi_kobj, &memdump_attr.attr); +} + +int32_t sysCreateFsEntry(struct GLUE_INFO *prGlueInfo) +{ + DBGLOG(INIT, TRACE, "[%s]\n", __func__); + + g_prGlueInfo = prGlueInfo; + + sysCreateMacAddr(); + pm_EnterCtiaMode(); + sysCreateWifiVer(); + sysCreateSoftap(); + + return 0; +} + +int32_t sysRemoveSysfs(void) +{ + g_prGlueInfo = NULL; + + return 0; +} + +int32_t sysInitFs(void) +{ + DBGLOG(INIT, TRACE, "[%s]\n", __func__); + + wifi_kobj = kobject_create_and_add("wifi", NULL); + kobject_get(wifi_kobj); + kobject_uevent(wifi_kobj, KOBJ_ADD); + + sysInitMacAddr(); + sysInitWifiVer(); + sysInitSoftap(); + sysInitPM(); + sysInitMemdump(); + + return 0; +} + +int32_t sysUninitSysFs(void) +{ + DBGLOG(INIT, TRACE, "[%s]\n", __func__); + + sysUninitMemdump(); + sysUninitPM(); + sysUninitSoftap(); + sysUninitWifiVer(); + sysUninitMacAddr(); + + kobject_put(wifi_kobj); + kobject_uevent(wifi_kobj, KOBJ_REMOVE); + wifi_kobj = NULL; + + return 0; +} + +void sysMacAddrOverride(uint8_t *prMacAddr) +{ + DBGLOG(INIT, TRACE, + "Override=%d\n", fgIsMacAddrOverride); + + if (!fgIsMacAddrOverride) + return; + + wlanHwAddrToBin( + aucMacAddrOverride, + prMacAddr); + + DBGLOG(INIT, TRACE, + "Init macaddr to " MACSTR ".\n", + MAC2STR(prMacAddr)); +} + +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_vendor.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_vendor.c new file mode 100644 index 0000000000000000000000000000000000000000..14e048ba6b47b1ccc28e027fddc61830d0f25357 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_vendor.c @@ -0,0 +1,1981 @@ +/******************************************************************************* + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ +/* + ** gl_vendor.c + ** + ** + */ + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "gl_os.h" +#include "debug.h" +#include "wlan_lib.h" +#include "gl_wext.h" +#include "precomp.h" +#include +#include +#include +#include "gl_cfg80211.h" +#include "gl_vendor.h" +#include "wlan_oid.h" + +#if KERNEL_VERSION(3, 16, 0) <= LINUX_VERSION_CODE + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ +uint8_t g_GetResultsBufferedCnt; +uint8_t g_GetResultsCmdCnt; + +static struct nla_policy nla_parse_wifi_policy[ + WIFI_ATTRIBUTE_ROAMING_STATE + 1] = { + [WIFI_ATTRIBUTE_BAND] = {.type = NLA_U32}, + [WIFI_ATTRIBUTE_NUM_CHANNELS] = {.type = NLA_U32}, + [WIFI_ATTRIBUTE_CHANNEL_LIST] = {.type = NLA_UNSPEC}, + + [WIFI_ATTRIBUTE_NUM_FEATURE_SET] = {.type = NLA_U32}, + [WIFI_ATTRIBUTE_FEATURE_SET] = {.type = NLA_UNSPEC}, + [WIFI_ATTRIBUTE_PNO_RANDOM_MAC_OUI] = {.type = NLA_UNSPEC}, + [WIFI_ATTRIBUTE_NODFS_VALUE] = {.type = NLA_U32}, + [WIFI_ATTRIBUTE_COUNTRY_CODE] = {.type = NLA_STRING}, + + [WIFI_ATTRIBUTE_MAX_RSSI] = {.type = NLA_U32}, + [WIFI_ATTRIBUTE_MIN_RSSI] = {.type = NLA_U32}, + [WIFI_ATTRIBUTE_RSSI_MONITOR_START] = {.type = NLA_U32}, + + [WIFI_ATTRIBUTE_ROAMING_CAPABILITIES] = {.type = NLA_UNSPEC}, + [WIFI_ATTRIBUTE_ROAMING_BLACKLIST_NUM] = {.type = NLA_U32}, + [WIFI_ATTRIBUTE_ROAMING_BLACKLIST_BSSID] = {.type = NLA_UNSPEC}, + [WIFI_ATTRIBUTE_ROAMING_WHITELIST_NUM] = {.type = NLA_U32}, + [WIFI_ATTRIBUTE_ROAMING_WHITELIST_SSID] = {.type = NLA_UNSPEC}, + [WIFI_ATTRIBUTE_ROAMING_STATE] = {.type = NLA_U32}, +}; + +static struct nla_policy nla_parse_offloading_policy[ + MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC + 1] = { + [MKEEP_ALIVE_ATTRIBUTE_ID] = {.type = NLA_U8}, + [MKEEP_ALIVE_ATTRIBUTE_IP_PKT] = {.type = NLA_UNSPEC}, + [MKEEP_ALIVE_ATTRIBUTE_IP_PKT_LEN] = {.type = NLA_U16}, + [MKEEP_ALIVE_ATTRIBUTE_SRC_MAC_ADDR] = {.type = NLA_UNSPEC}, + [MKEEP_ALIVE_ATTRIBUTE_DST_MAC_ADDR] = {.type = NLA_UNSPEC}, + [MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC] = {.type = NLA_U32}, +}; + +static struct nla_policy nla_get_preferred_freq_list_policy[ + WIFI_VENDOR_ATTR_PREFERRED_FREQ_LIST_MAX] = { + [WIFI_VENDOR_ATTR_PREFERRED_FREQ_LIST_IFACE_TYPE] = {.type = NLA_U32}, +}; + +static const struct nla_policy nla_get_acs_policy[ + WIFI_VENDOR_ATTR_ACS_MAX + 1] = { + [WIFI_VENDOR_ATTR_ACS_HW_MODE] = { .type = NLA_U8 }, + [WIFI_VENDOR_ATTR_ACS_HT_ENABLED] = { .type = NLA_FLAG }, + [WIFI_VENDOR_ATTR_ACS_HT40_ENABLED] = { .type = NLA_FLAG }, + [WIFI_VENDOR_ATTR_ACS_VHT_ENABLED] = { .type = NLA_FLAG }, + [WIFI_VENDOR_ATTR_ACS_CHWIDTH] = { .type = NLA_U16 }, + [WIFI_VENDOR_ATTR_ACS_CH_LIST] = { .type = NLA_UNSPEC }, + [WIFI_VENDOR_ATTR_ACS_FREQ_LIST] = { .type = NLA_UNSPEC }, +}; + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +int mtk_cfg80211_NLA_PUT(struct sk_buff *skb, int attrtype, + int attrlen, const void *data) +{ + if (unlikely(nla_put(skb, attrtype, attrlen, data) < 0)) + return 0; + return 1; +} + +int mtk_cfg80211_nla_put_type(struct sk_buff *skb, + enum ENUM_NLA_PUT_DATE_TYPE type, int attrtype, + const void *value) +{ + u8 u8data = 0; + u16 u16data = 0; + u32 u32data = 0; + u64 u64data = 0; + + switch (type) { + case NLA_PUT_DATE_U8: + u8data = *(u8 *)value; + return mtk_cfg80211_NLA_PUT(skb, attrtype, sizeof(u8), + &u8data); + case NLA_PUT_DATE_U16: + u16data = *(u16 *)value; + return mtk_cfg80211_NLA_PUT(skb, attrtype, sizeof(u16), + &u16data); + case NLA_PUT_DATE_U32: + u32data = *(u32 *)value; + return mtk_cfg80211_NLA_PUT(skb, attrtype, sizeof(u32), + &u32data); + case NLA_PUT_DATE_U64: + u64data = *(u64 *)value; + return mtk_cfg80211_NLA_PUT(skb, attrtype, sizeof(u64), + &u64data); + default: + break; + } + + return 0; +} + +int mtk_cfg80211_vendor_get_channel_list(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len) +{ + struct GLUE_INFO *prGlueInfo; + struct nlattr *attr; + uint32_t band = 0; + uint8_t ucNumOfChannel, i, j; + struct RF_CHANNEL_INFO *aucChannelList; + uint32_t num_channels; + uint32_t channels[MAX_CHN_NUM]; + struct sk_buff *skb; + uint16_t u2CountryCode; + + ASSERT(wiphy && wdev); + if ((data == NULL) || !data_len) + return -EINVAL; + + DBGLOG(REQ, TRACE, "data_len=%d, iftype=%d\n", data_len, wdev->iftype); + + attr = (struct nlattr *)data; + if (attr->nla_type == WIFI_ATTRIBUTE_BAND) + band = nla_get_u32(attr); + + DBGLOG(REQ, TRACE, "Get channel list for band: %d\n", band); + + prGlueInfo = wlanGetGlueInfo(); + if (!prGlueInfo) + return -EFAULT; + + aucChannelList = (struct RF_CHANNEL_INFO *) + kalMemAlloc(sizeof(struct RF_CHANNEL_INFO)*MAX_CHN_NUM, + VIR_MEM_TYPE); + if (!aucChannelList) { + DBGLOG(REQ, ERROR, + "Can not alloc memory for rf channel info\n"); + return -ENOMEM; + } + kalMemZero(aucChannelList, + sizeof(struct RF_CHANNEL_INFO)*MAX_CHN_NUM); + + switch (band) { + case 1: /* 2.4G band */ + rlmDomainGetChnlList(prGlueInfo->prAdapter, BAND_2G4, TRUE, + MAX_CHN_NUM, &ucNumOfChannel, aucChannelList); + break; + case 2: /* 5G band without DFS channels */ + rlmDomainGetChnlList(prGlueInfo->prAdapter, BAND_5G, TRUE, + MAX_CHN_NUM, &ucNumOfChannel, aucChannelList); + break; + case 4: /* 5G band DFS channels only */ + rlmDomainGetDfsChnls(prGlueInfo->prAdapter, MAX_CHN_NUM, + &ucNumOfChannel, aucChannelList); + break; + default: + ucNumOfChannel = 0; + break; + } + + kalMemZero(channels, sizeof(channels)); + u2CountryCode = prGlueInfo->prAdapter->rWifiVar.u2CountryCode; + for (i = 0, j = 0; i < ucNumOfChannel; i++) { + /* We need to report frequency list to HAL */ + channels[j] = + nicChannelNum2Freq(aucChannelList[i].ucChannelNum) / 1000; + if (channels[j] == 0) + continue; + else if ((u2CountryCode == COUNTRY_CODE_TW) && + (channels[j] >= 5180 && channels[j] <= 5260)) { + /* Taiwan NCC has resolution to follow FCC spec + * to support 5G Band 1/2/3/4 + * (CH36~CH48, CH52~CH64, CH100~CH140, CH149~CH165) + * Filter CH36~CH52 for compatible with some old + * devices. + */ + DBGLOG(REQ, TRACE, "skip channels[%d]=%d, country=%d\n", + j, channels[j], u2CountryCode); + continue; + } else { + DBGLOG(REQ, TRACE, "channels[%d] = %d\n", j, + channels[j]); + j++; + } + } + num_channels = j; + DBGLOG(REQ, INFO, "Get channel list for band: %d, num_channels=%d\n", + band, num_channels); + + kalMemFree(aucChannelList, VIR_MEM_TYPE, + sizeof(struct RF_CHANNEL_INFO)*MAX_CHN_NUM); + + skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(channels)); + if (!skb) { + DBGLOG(REQ, ERROR, "Allocate skb failed\n"); + return -ENOMEM; + } + + if (unlikely(nla_put_u32(skb, WIFI_ATTRIBUTE_NUM_CHANNELS, + num_channels) < 0)) + goto nla_put_failure; + + if (unlikely(nla_put(skb, WIFI_ATTRIBUTE_CHANNEL_LIST, + (sizeof(uint32_t) * num_channels), channels) < 0)) + goto nla_put_failure; + + return cfg80211_vendor_cmd_reply(skb); + +nla_put_failure: + kfree_skb(skb); + return -EFAULT; +} + +int mtk_cfg80211_vendor_set_country_code(struct wiphy + *wiphy, struct wireless_dev *wdev, const void *data, + int data_len) +{ + struct GLUE_INFO *prGlueInfo; + uint32_t rStatus; + uint32_t u4BufLen; + struct nlattr *attr; + uint8_t country[2] = {0}; + + ASSERT(wiphy && wdev); + if ((data == NULL) || (data_len == 0)) + return -EINVAL; + + DBGLOG(REQ, INFO, + "vendor command: data_len=%d, iftype=%d\n", data_len, + wdev->iftype); + + attr = (struct nlattr *)data; + if (attr->nla_type == WIFI_ATTRIBUTE_COUNTRY_CODE) { + country[0] = *((uint8_t *)nla_data(attr)); + country[1] = *((uint8_t *)nla_data(attr) + 1); + } + + DBGLOG(REQ, INFO, "Set country code: %c%c\n", country[0], + country[1]); + + prGlueInfo = wlanGetGlueInfo(); + if (!prGlueInfo) + return -EFAULT; + + rStatus = kalIoctl(prGlueInfo, wlanoidSetCountryCode, + country, 2, FALSE, FALSE, TRUE, &u4BufLen); + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, ERROR, "Set country code error: %x\n", rStatus); + return -EFAULT; + } + + return 0; +} + +int mtk_cfg80211_vendor_set_scan_mac_oui(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int data_len) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + struct nlattr *attr; + uint32_t i = 0; + struct PARAM_BSS_MAC_OUI rParamMacOui; + uint32_t u4BufLen = 0; + struct NETDEV_PRIVATE_GLUE_INFO *prNetDevPrivate = NULL; + + ASSERT(wiphy); + ASSERT(wdev); + + if (data == NULL || data_len <= 0) { + log_dbg(REQ, ERROR, "data error(len=%d)\n", data_len); + return -EINVAL; + } + + prGlueInfo = wlanGetGlueInfo(); + if (!prGlueInfo) { + log_dbg(REQ, ERROR, "Invalid glue info\n"); + return -EFAULT; + } + prNetDevPrivate = + (struct NETDEV_PRIVATE_GLUE_INFO *) netdev_priv(wdev->netdev); + if (!prNetDevPrivate) { + log_dbg(REQ, ERROR, "Invalid net device private\n"); + return -EFAULT; + } + rParamMacOui.ucBssIndex = prNetDevPrivate->ucBssIdx; + + attr = (struct nlattr *)data; + kalMemZero(rParamMacOui.ucMacOui, MAC_OUI_LEN); + if (nla_type(attr) != WIFI_ATTRIBUTE_PNO_RANDOM_MAC_OUI) { + log_dbg(REQ, ERROR, "Set MAC oui type error(%u)\n", + nla_type(attr)); + return -EINVAL; + } + + if (nla_len(attr) != MAC_OUI_LEN) { + log_dbg(REQ, ERROR, "Set MAC oui length error(%u), %u needed\n", + nla_len(attr), MAC_OUI_LEN); + return -EINVAL; + } + + for (i = 0; i < MAC_OUI_LEN; i++) + rParamMacOui.ucMacOui[i] = *((uint8_t *)nla_data(attr) + i); + + log_dbg(REQ, INFO, "Set MAC oui: %02x-%02x-%02x\n", + rParamMacOui.ucMacOui[0], rParamMacOui.ucMacOui[1], + rParamMacOui.ucMacOui[2]); + + rStatus = kalIoctl(prGlueInfo, wlanoidSetScanMacOui, + &rParamMacOui, sizeof(rParamMacOui), + FALSE, FALSE, FALSE, &u4BufLen); + if (rStatus != WLAN_STATUS_SUCCESS) { + log_dbg(REQ, ERROR, "Set MAC oui error: 0x%X\n", rStatus); + return -EFAULT; + } + + return 0; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is to answer FWK that we can support FW Roaming. + * + * \param[in] wiphy wiphy for AIS STA. + * + * \param[in] wdev (not used here). + * + * \param[in] data (not used here). + * + * \param[in] data_len (not used here). + * + * \retval TRUE Success. + * + * \note we use cfg80211_vendor_cmd_reply to send the max number of our + * blacklist and whiltlist directly without receiving any data + * from the upper layer. + */ +/*----------------------------------------------------------------------------*/ +int mtk_cfg80211_vendor_get_roaming_capabilities(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int data_len) +{ + uint32_t maxNumOfList[2] = { MAX_FW_ROAMING_BLACKLIST_SIZE, + MAX_FW_ROAMING_WHITELIST_SIZE }; + struct sk_buff *skb; + + ASSERT(wiphy); + + DBGLOG(REQ, INFO, + "Get roaming capabilities: max black/whitelist=%d/%d", + maxNumOfList[0], maxNumOfList[1]); + + skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(maxNumOfList)); + if (!skb) { + DBGLOG(REQ, ERROR, "Allocate skb failed\n"); + return -ENOMEM; + } + + if (unlikely(nla_put(skb, WIFI_ATTRIBUTE_ROAMING_BLACKLIST_NUM, + sizeof(uint32_t), &maxNumOfList[0]) < 0)) + goto nla_put_failure; + if (unlikely(nla_put(skb, WIFI_ATTRIBUTE_ROAMING_WHITELIST_NUM, + sizeof(uint32_t), &maxNumOfList[1]) < 0)) + goto nla_put_failure; + + return cfg80211_vendor_cmd_reply(skb); + +nla_put_failure: + kfree_skb(skb); + return -EFAULT; +} + + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is to receive the black/whiltelist. from FWK. + * + * \param[in] wiphy wiphy for AIS STA. + * + * \param[in] wdev (not used here). + * + * \param[in] data BSSIDs in the FWK blact&whitelist. + * + * \param[in] data_len the byte-length of the FWK blact&whitelist. + * + * \retval TRUE Success. + * + * \note we iterate each BSSID in 'data' and put it into driver blacklist. + * For now, whiltelist doesn't be implemented by the FWK currently. + */ +/*----------------------------------------------------------------------------*/ +int mtk_cfg80211_vendor_config_roaming(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int data_len) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct nlattr *attrlist; + struct AIS_BLACKLIST_ITEM *prBlackList; + struct BSS_DESC *prBssDesc = NULL; + uint32_t len_shift = 0; + uint32_t numOfList[2] = { 0 }; + uint8_t *aucBSSID = NULL; + int i; + + DBGLOG(REQ, INFO, + "Receives roaming blacklist & whitelist with data_len=%d\n", + data_len); + ASSERT(wiphy); + ASSERT(wdev); + if ((data == NULL) || (data_len == 0)) + return -EINVAL; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + if (!prGlueInfo) + return -EINVAL; + + if (prGlueInfo->u4FWRoamingEnable == 0) { + DBGLOG(REQ, INFO, + "FWRoaming is disabled (FWRoamingEnable=%d)\n", + prGlueInfo->u4FWRoamingEnable); + return WLAN_STATUS_SUCCESS; + } + + attrlist = (struct nlattr *)((uint8_t *) data); + + /* get the number of blacklist and copy those mac addresses from HAL */ + if (attrlist->nla_type == + WIFI_ATTRIBUTE_ROAMING_BLACKLIST_NUM) { + numOfList[0] = nla_get_u32(attrlist); + len_shift += NLA_ALIGN(attrlist->nla_len); + } + DBGLOG(REQ, INFO, "Get the number of blacklist=%d\n", + numOfList[0]); + + if (numOfList[0] < 0 + || numOfList[0] > MAX_FW_ROAMING_BLACKLIST_SIZE) + return -EINVAL; + + /*Refresh all the FWKBlacklist */ + aisRefreshFWKBlacklist(prGlueInfo->prAdapter); + + /* Start to receive blacklist mac addresses and set to FWK blacklist */ + attrlist = (struct nlattr *)((uint8_t *) data + len_shift); + for (i = 0; i < numOfList[0]; i++) { + if (attrlist->nla_type == + WIFI_ATTRIBUTE_ROAMING_BLACKLIST_BSSID) { + prBssDesc = + scanSearchBssDescByBssid(prGlueInfo->prAdapter, + nla_data(attrlist)); + len_shift += NLA_ALIGN(attrlist->nla_len); + attrlist = + (struct nlattr *)((uint8_t *) data + len_shift); + + if (prBssDesc == NULL) { + aucBSSID = nla_data(attrlist); + DBGLOG(REQ, ERROR, "No found blacklist BSS=" + MACSTR "\n", + MAC2STR(aucBSSID)); + continue; + } + + prBlackList = aisAddBlacklist(prGlueInfo->prAdapter, + prBssDesc); + + if (prBlackList) { + prBlackList->fgIsInFWKBlacklist = TRUE; + DBGLOG(REQ, INFO, + "Gets roaming blacklist SSID=%s addr=" + MACSTR "\n", + HIDE(prBssDesc->aucSSID), + MAC2STR(prBssDesc->aucBSSID)); + } else { + DBGLOG(REQ, ERROR, + "prBlackList is NULL, return -EINVAL!"); + return -EINVAL; + } + } + } + + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is to turn on/off FW Roaming. + * + * \param[in] wiphy wiphy for AIS STA. + * + * \param[in] wdev (not used here). + * + * \param[in] data 1 for ON / 0 for OFF. + * + * \param[in] data_len the byte-length of the data. + * + * \retval TRUE Success. + * + * \note we only receive the data and make the interface available to FWK. + * For now, this SUBCMD woundn't be sent from the FWK currently. + */ +/*----------------------------------------------------------------------------*/ +int mtk_cfg80211_vendor_enable_roaming(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int data_len) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct nlattr *attr; + + ASSERT(wiphy); /* change to if (wiphy == NULL) then return? */ + ASSERT(wdev); /* change to if (wiphy == NULL) then return? */ + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + if (!prGlueInfo) + return -EFAULT; + + attr = (struct nlattr *)data; + if (attr->nla_type == WIFI_ATTRIBUTE_ROAMING_STATE) + prGlueInfo->u4FWRoamingEnable = nla_get_u32(attr); + + DBGLOG(REQ, INFO, "FWK set FWRoamingEnable = %d\n", + prGlueInfo->u4FWRoamingEnable); + + return WLAN_STATUS_SUCCESS; +} + +int mtk_cfg80211_vendor_get_rtt_capabilities( + struct wiphy *wiphy, struct wireless_dev *wdev, + const void *data, int data_len) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4Status = -EINVAL; + struct PARAM_WIFI_RTT_CAPABILITIES rRttCapabilities; + struct sk_buff *skb; + + DBGLOG(REQ, TRACE, "vendor command\r\n"); + + ASSERT(wiphy); + ASSERT(wdev); + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + + skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, + sizeof(rRttCapabilities)); + if (!skb) { + DBGLOG(REQ, ERROR, "%s allocate skb failed:%x\n", + __func__, i4Status); + return -ENOMEM; + } + + kalMemZero(&rRttCapabilities, sizeof(rRttCapabilities)); + + /* RTT Capabilities return from driver not firmware */ + rRttCapabilities.rtt_one_sided_supported = 0; + rRttCapabilities.rtt_ftm_supported = 1; + rRttCapabilities.lci_support = 1; + rRttCapabilities.lcr_support = 1; + rRttCapabilities.preamble_support = 0x07; + rRttCapabilities.bw_support = 0x1c; + + if (unlikely(nla_put(skb, RTT_ATTRIBUTE_CAPABILITIES, + sizeof(rRttCapabilities), &rRttCapabilities) < 0)) + goto nla_put_failure; + + i4Status = cfg80211_vendor_cmd_reply(skb); + return i4Status; + +nla_put_failure: + kfree_skb(skb); + return i4Status; +} + +int mtk_cfg80211_vendor_llstats_get_info( + struct wiphy *wiphy, struct wireless_dev *wdev, + const void *data, int data_len) +{ + int32_t i4Status = -EINVAL; + struct WIFI_RADIO_STAT *pRadioStat = NULL; + struct sk_buff *skb = NULL; + uint32_t u4BufLen = 0; + + ASSERT(wiphy); + ASSERT(wdev); + + u4BufLen = sizeof(struct WIFI_RADIO_STAT) + sizeof( + struct WIFI_IFACE_STAT); + pRadioStat = kalMemAlloc(u4BufLen, VIR_MEM_TYPE); + if (!pRadioStat) { + DBGLOG(REQ, ERROR, "%s kalMemAlloc pRadioStat failed\n", + __func__); + i4Status = -ENOMEM; + goto nla_put_failure; + } + kalMemZero(pRadioStat, u4BufLen); + + skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, u4BufLen); + if (!skb) { + DBGLOG(REQ, TRACE, "%s allocate skb failed:%x\n", __func__, + i4Status); + i4Status = -ENOMEM; + goto nla_put_failure; + } + +#if 0 + rStatus = kalIoctl(prGlueInfo, + wlanoidQueryStatistics, + &rRadioStat, + sizeof(rRadioStat), + TRUE, + TRUE, + TRUE, + FALSE, + &u4BufLen); +#endif + /* only for test */ + pRadioStat->radio = 10; + pRadioStat->on_time = 11; + pRadioStat->tx_time = 12; + pRadioStat->num_channels = 4; + + /*NLA_PUT(skb, LSTATS_ATTRIBUTE_STATS, u4BufLen, pRadioStat);*/ + if (unlikely(nla_put(skb, LSTATS_ATTRIBUTE_STATS, u4BufLen, + pRadioStat) < 0)) + goto nla_put_failure; + + i4Status = cfg80211_vendor_cmd_reply(skb); + kalMemFree(pRadioStat, VIR_MEM_TYPE, u4BufLen); + return -1; /* not support LLS now*/ + /* return i4Status; */ + +nla_put_failure: + if (skb != NULL) + kfree_skb(skb); + if (pRadioStat != NULL) + kalMemFree(pRadioStat, VIR_MEM_TYPE, u4BufLen); + return i4Status; +} + +int mtk_cfg80211_vendor_set_band(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct nlattr *attr; + uint8_t setBand = 0; + enum ENUM_BAND band; + + ASSERT(wiphy); + ASSERT(wdev); + + DBGLOG(REQ, INFO, "%s()\n", __func__); + + if ((data == NULL) || !data_len) + goto nla_put_failure; + + DBGLOG(REQ, TRACE, + "vendor command: data_len=%d, data=0x%x 0x%x\r\n", + data_len, *((uint32_t *) data), *((uint32_t *) data + 1)); + + attr = (struct nlattr *)data; + setBand = nla_get_u32(attr); + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + ASSERT(prGlueInfo); + + DBGLOG(REQ, INFO, "Vendor Set Band value=%d\r\n", setBand); + + if (setBand == QCA_SETBAND_5G) + band = BAND_5G; + else if (setBand == QCA_SETBAND_2G) + band = BAND_2G4; + else + band = BAND_NULL; + + prGlueInfo->prAdapter->aePreferBand[NETWORK_TYPE_AIS] = + band; + return 0; + +nla_put_failure: + return -1; +} + +#if CFG_SUPPORT_MBO +static const struct nla_policy +qca_roaming_param_policy[QCA_ATTR_ROAMING_PARAM_MAX + 1] = { + [QCA_ATTR_ROAMING_SUBCMD] = {.type = NLA_U32}, + [QCA_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_NUM_BSSID] = {.type = NLA_U32}, + [QCA_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS] = {.type = NLA_NESTED}, + [QCA_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_BSSID] = { + .type = NLA_BINARY, + .len = MAC_ADDR_LEN}, +}; + +#define SET_BSSID_PARAMS_NUM_BSSID \ + QCA_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_NUM_BSSID +#define SET_BSSID_PARAMS \ + QCA_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS +#define SET_BSSID_PARAMS_BSSID \ + QCA_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_BSSID + +int mtk_cfg80211_vendor_set_roaming_param(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct nlattr *tb[QCA_ATTR_ROAMING_PARAM_MAX + 1] = {}; + struct nlattr *tb2[QCA_ATTR_ROAMING_PARAM_MAX + 1] = {}; + struct nlattr *attr; + uint32_t rStatus, u4BufLen, cmd_type, count, index; + int tmp; + uint8_t i = 0; + + ASSERT(wiphy); + ASSERT(wdev); + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + if (!prGlueInfo) + return -EFAULT; + + if ((data == NULL) || (data_len == 0)) + goto fail; + + if (NLA_PARSE(tb, QCA_ATTR_ROAMING_PARAM_MAX, + data, data_len, qca_roaming_param_policy)) { + DBGLOG(REQ, ERROR, "Wrong ROAM ATTR.\n"); + goto fail; + } + + /* Parse and fetch Command Type*/ + if (!tb[QCA_ATTR_ROAMING_SUBCMD]) { + DBGLOG(REQ, ERROR, "Invalid roam cmd type\n"); + goto fail; + } + + cmd_type = nla_get_u32(tb[QCA_ATTR_ROAMING_SUBCMD]); + if (cmd_type == QCA_ATTR_ROAM_SUBCMD_SET_BLACKLIST_BSSID) { + struct PARAM_BSS_DISALLOWED_LIST request = {}; + + /* Parse and fetch number of blacklist BSSID */ + if (!tb[SET_BSSID_PARAMS_NUM_BSSID]) { + DBGLOG(REQ, ERROR, "Invlaid num of blacklist bssid\n"); + goto fail; + } + count = nla_get_u32(tb[SET_BSSID_PARAMS_NUM_BSSID]); + if (count > MAX_FW_ROAMING_BLACKLIST_SIZE) { + DBGLOG(REQ, ERROR, "Count %u exceeds\n", count); + goto fail; + } + request.u4NumBssDisallowed = count; + i = 0; + if (count && tb[SET_BSSID_PARAMS]) { + nla_for_each_nested(attr, tb[SET_BSSID_PARAMS], tmp) { + char *bssid = NULL; + + if (i == count) { + DBGLOG(REQ, ERROR, "Excess num\n"); + break; + } + if (NLA_PARSE(tb2, + QCA_ATTR_ROAMING_PARAM_MAX, + nla_data(attr), nla_len(attr), + qca_roaming_param_policy)) { + DBGLOG(REQ, ERROR, "Wrong ROAM ATTR\n"); + goto fail; + } + /* Parse and fetch MAC address */ + if (!tb2[SET_BSSID_PARAMS_BSSID]) { + DBGLOG(REQ, ERROR, "addr failed\n"); + goto fail; + } + bssid = nla_data(tb2[SET_BSSID_PARAMS_BSSID]); + index = i * MAC_ADDR_LEN; + COPY_MAC_ADDR(&request.aucList[index], bssid); + DBGLOG(REQ, INFO, "disallow #%d " MACSTR "\n", + i, MAC2STR(bssid)); + i++; + } + } + if (i != count) + DBGLOG(REQ, ERROR, "Count %u, expected %u\n", i, count); + + rStatus = kalIoctl(prGlueInfo, wlanoidBssDisallowedList, + &request, + sizeof(struct PARAM_BSS_DISALLOWED_LIST), + FALSE, FALSE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, ERROR, "disallowed error:%x\n", rStatus); + return -EFAULT; + } + } else { + DBGLOG(REQ, INFO, "unhandled cmd_type %d\n", cmd_type); + goto fail; + } + + return WLAN_STATUS_SUCCESS; +fail: + return -EINVAL; +} + +#undef SET_BSSID_PARAMS_NUM_BSSID +#undef SET_BSSID_PARAMS +#undef SET_BSSID_PARAMS_BSSID + +#endif + +int mtk_cfg80211_vendor_set_roaming_policy( + struct wiphy *wiphy, struct wireless_dev *wdev, + const void *data, int data_len) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + struct nlattr *attr; + uint32_t setRoaming = 0; + uint32_t u4BufLen = 0; + int32_t i4Status = -EINVAL; + uint8_t ucBssIndex = 0; + + ASSERT(wiphy); + ASSERT(wdev); + + if ((data == NULL) || !data_len) + goto nla_put_failure; + + attr = (struct nlattr *)data; + setRoaming = nla_get_u32(attr); + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + ucBssIndex = wlanGetBssIdx(wdev->netdev); + ASSERT(prGlueInfo); + + DBGLOG(REQ, INFO, + "vendor command: data_len=%d, data=0x%x 0x%x, roaming policy=%d\r\n", + data_len, *((uint32_t *) data), *((uint32_t *) data + 1), + setRoaming); + + rStatus = kalIoctlByBssIdx(prGlueInfo, + wlanoidSetDrvRoamingPolicy, + &setRoaming, sizeof(uint32_t), FALSE, FALSE, TRUE, + &u4BufLen, + ucBssIndex); + + return rStatus; + +nla_put_failure: + return i4Status; + +} + +int mtk_cfg80211_vendor_set_rssi_monitoring( + struct wiphy *wiphy, struct wireless_dev *wdev, + const void *data, int data_len) +{ + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + struct GLUE_INFO *prGlueInfo = NULL; + + int32_t i4Status = -EINVAL; + struct PARAM_RSSI_MONITOR_T rRSSIMonitor; + struct nlattr *attr[WIFI_ATTRIBUTE_RSSI_MONITOR_START + 1]; + uint32_t i = 0; + + ASSERT(wiphy); + ASSERT(wdev); + + DBGLOG(REQ, TRACE, "vendor command: data_len=%d\r\n", + data_len); + kalMemZero(&rRSSIMonitor, + sizeof(struct PARAM_RSSI_MONITOR_T)); + if ((data == NULL) || !data_len) + goto nla_put_failure; + kalMemZero(attr, sizeof(struct nlattr *) * + (WIFI_ATTRIBUTE_RSSI_MONITOR_START + 1)); + if (NLA_PARSE_NESTED(attr, + WIFI_ATTRIBUTE_RSSI_MONITOR_START, + (struct nlattr *)(data - NLA_HDRLEN), + nla_parse_wifi_policy) < 0) { + DBGLOG(REQ, ERROR, "%s nla_parse_nested failed\n", + __func__); + goto nla_put_failure; + } + + for (i = WIFI_ATTRIBUTE_MAX_RSSI; + i <= WIFI_ATTRIBUTE_RSSI_MONITOR_START; i++) { + if (attr[i]) { + switch (i) { + case WIFI_ATTRIBUTE_MAX_RSSI: + rRSSIMonitor.max_rssi_value = + nla_get_u32(attr[i]); + break; + case WIFI_ATTRIBUTE_MIN_RSSI: + rRSSIMonitor.min_rssi_value + = nla_get_u32(attr[i]); + break; + case WIFI_ATTRIBUTE_RSSI_MONITOR_START: + rRSSIMonitor.enable = nla_get_u32(attr[i]); + break; + } + } + } + + DBGLOG(REQ, TRACE, + "mMax_rssi=%d, mMin_rssi=%d enable=%d\r\n", + rRSSIMonitor.max_rssi_value, rRSSIMonitor.min_rssi_value, + rRSSIMonitor.enable); + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + ASSERT(prGlueInfo); + + rStatus = kalIoctl(prGlueInfo, + wlanoidRssiMonitor, + &rRSSIMonitor, sizeof(struct PARAM_RSSI_MONITOR_T), + FALSE, FALSE, TRUE, &u4BufLen); + return rStatus; + +nla_put_failure: + return i4Status; +} + +int mtk_cfg80211_vendor_packet_keep_alive_start( + struct wiphy *wiphy, struct wireless_dev *wdev, + const void *data, int data_len) +{ + uint32_t rStatus = WLAN_STATUS_SUCCESS; + unsigned short u2IpPktLen = 0; + uint32_t u4BufLen = 0; + struct GLUE_INFO *prGlueInfo = NULL; + + int32_t i4Status = -EINVAL; + struct PARAM_PACKET_KEEPALIVE_T *prPkt = NULL; + struct nlattr *attr[MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC + 1]; + uint32_t i = 0; + + ASSERT(wiphy); + ASSERT(wdev); + if ((data == NULL) || !data_len) + goto nla_put_failure; + + DBGLOG(REQ, TRACE, "vendor command: data_len=%d\r\n", + data_len); + prPkt = (struct PARAM_PACKET_KEEPALIVE_T *) + kalMemAlloc(sizeof(struct PARAM_PACKET_KEEPALIVE_T), + VIR_MEM_TYPE); + if (!prPkt) { + DBGLOG(REQ, ERROR, + "Can not alloc memory for struct PARAM_PACKET_KEEPALIVE_T\n"); + return -ENOMEM; + } + kalMemZero(prPkt, sizeof(struct PARAM_PACKET_KEEPALIVE_T)); + kalMemZero(attr, sizeof(struct nlattr *) + * (MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC + 1)); + + prPkt->enable = TRUE; /*start packet keep alive*/ + if (NLA_PARSE_NESTED(attr, + MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC, + (struct nlattr *)(data - NLA_HDRLEN), + nla_parse_offloading_policy) < 0) { + DBGLOG(REQ, ERROR, "%s nla_parse_nested failed\n", + __func__); + goto nla_put_failure; + } + + for (i = MKEEP_ALIVE_ATTRIBUTE_ID; + i <= MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC; i++) { + if (attr[i]) { + switch (i) { + case MKEEP_ALIVE_ATTRIBUTE_ID: + prPkt->index = nla_get_u8(attr[i]); + break; + case MKEEP_ALIVE_ATTRIBUTE_IP_PKT_LEN: + prPkt->u2IpPktLen = nla_get_u16(attr[i]); + break; + case MKEEP_ALIVE_ATTRIBUTE_IP_PKT: + u2IpPktLen = prPkt->u2IpPktLen <= 256 + ? prPkt->u2IpPktLen : 256; + kalMemCopy(prPkt->pIpPkt, nla_data(attr[i]), + u2IpPktLen); + break; + case MKEEP_ALIVE_ATTRIBUTE_SRC_MAC_ADDR: + kalMemCopy(prPkt->ucSrcMacAddr, + nla_data(attr[i]), sizeof(uint8_t) * 6); + break; + case MKEEP_ALIVE_ATTRIBUTE_DST_MAC_ADDR: + kalMemCopy(prPkt->ucDstMacAddr, + nla_data(attr[i]), sizeof(uint8_t) * 6); + break; + case MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC: + prPkt->u4PeriodMsec = nla_get_u32(attr[i]); + break; + } + } + } + + DBGLOG(REQ, INFO, + "enable=%d, index=%d, u2IpPktLen=%d u4PeriodMsec=%d\n", + prPkt->enable, prPkt->index, + prPkt->u2IpPktLen, prPkt->u4PeriodMsec); + DBGLOG(REQ, TRACE, "prPkt->pIpPkt=0x%02x%02x%02x%02x\n", + prPkt->pIpPkt[0], prPkt->pIpPkt[1], + prPkt->pIpPkt[2], prPkt->pIpPkt[3]); + DBGLOG(REQ, TRACE, "%02x%02x%02x%02x, %02x%02x%02x%02x\n", + prPkt->pIpPkt[4], prPkt->pIpPkt[5], + prPkt->pIpPkt[6], prPkt->pIpPkt[7], + prPkt->pIpPkt[8], prPkt->pIpPkt[9], + prPkt->pIpPkt[10], prPkt->pIpPkt[11]); + DBGLOG(REQ, TRACE, "%02x%02x%02x%02x\n", + prPkt->pIpPkt[12], prPkt->pIpPkt[13], + prPkt->pIpPkt[14], prPkt->pIpPkt[15]); + DBGLOG(REQ, TRACE, + "prPkt->srcMAC=%02x:%02x:%02x:%02x:%02x:%02x\n", + prPkt->ucSrcMacAddr[0], prPkt->ucSrcMacAddr[1], + prPkt->ucSrcMacAddr[2], prPkt->ucSrcMacAddr[3], + prPkt->ucSrcMacAddr[4], prPkt->ucSrcMacAddr[5]); + DBGLOG(REQ, TRACE, "dstMAC=%02x:%02x:%02x:%02x:%02x:%02x\n", + prPkt->ucDstMacAddr[0], prPkt->ucDstMacAddr[1], + prPkt->ucDstMacAddr[2], prPkt->ucDstMacAddr[3], + prPkt->ucDstMacAddr[4], prPkt->ucDstMacAddr[5]); + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + ASSERT(prGlueInfo); + + rStatus = kalIoctl(prGlueInfo, + wlanoidPacketKeepAlive, + prPkt, sizeof(struct PARAM_PACKET_KEEPALIVE_T), + FALSE, FALSE, TRUE, &u4BufLen); + kalMemFree(prPkt, VIR_MEM_TYPE, + sizeof(struct PARAM_PACKET_KEEPALIVE_T)); + return rStatus; + +nla_put_failure: + if (prPkt != NULL) + kalMemFree(prPkt, VIR_MEM_TYPE, + sizeof(struct PARAM_PACKET_KEEPALIVE_T)); + return i4Status; +} + +int mtk_cfg80211_vendor_packet_keep_alive_stop( + struct wiphy *wiphy, struct wireless_dev *wdev, + const void *data, int data_len) +{ + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + struct GLUE_INFO *prGlueInfo = NULL; + + int32_t i4Status = -EINVAL; + struct PARAM_PACKET_KEEPALIVE_T *prPkt = NULL; + struct nlattr *attr; + + ASSERT(wiphy); + ASSERT(wdev); + if ((data == NULL) || !data_len) + goto nla_put_failure; + + DBGLOG(REQ, TRACE, "vendor command: data_len=%d\r\n", + data_len); + prPkt = (struct PARAM_PACKET_KEEPALIVE_T *) + kalMemAlloc(sizeof(struct PARAM_PACKET_KEEPALIVE_T), + VIR_MEM_TYPE); + if (!prPkt) { + DBGLOG(REQ, ERROR, + "Can not alloc memory for PARAM_PACKET_KEEPALIVE_T\n"); + return -ENOMEM; + } + kalMemZero(prPkt, sizeof(struct PARAM_PACKET_KEEPALIVE_T)); + + prPkt->enable = FALSE; /*stop packet keep alive*/ + attr = (struct nlattr *)data; + if (attr->nla_type == MKEEP_ALIVE_ATTRIBUTE_ID) + prPkt->index = nla_get_u8(attr); + + DBGLOG(REQ, INFO, "enable=%d, index=%d\r\n", + prPkt->enable, prPkt->index); + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + ASSERT(prGlueInfo); + + rStatus = kalIoctl(prGlueInfo, + wlanoidPacketKeepAlive, + prPkt, sizeof(struct PARAM_PACKET_KEEPALIVE_T), + FALSE, FALSE, TRUE, &u4BufLen); + kalMemFree(prPkt, VIR_MEM_TYPE, + sizeof(struct PARAM_PACKET_KEEPALIVE_T)); + return rStatus; + +nla_put_failure: + if (prPkt != NULL) + kalMemFree(prPkt, VIR_MEM_TYPE, + sizeof(struct PARAM_PACKET_KEEPALIVE_T)); + return i4Status; +} + +int mtk_cfg80211_vendor_get_version(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct sk_buff *skb = NULL; + struct nlattr *attrlist = NULL; + char aucVersionBuf[256]; + uint16_t u2CopySize = 0; + uint16_t u2Len = 0; + + ASSERT(wiphy); + ASSERT(wdev); + + if ((data == NULL) || !data_len) + return -ENOMEM; + + kalMemZero(aucVersionBuf, 256); + attrlist = (struct nlattr *)((uint8_t *) data); + if (attrlist->nla_type == LOGGER_ATTRIBUTE_DRIVER_VER) { + char aucDriverVersionStr[] = STR(NIC_DRIVER_MAJOR_VERSION) "_" + STR(NIC_DRIVER_MINOR_VERSION) "_" + STR(NIC_DRIVER_SERIAL_VERSION) "-" + STR(DRIVER_BUILD_DATE); + + u2Len = kalStrLen(aucDriverVersionStr); + DBGLOG(REQ, TRACE, "Get driver version len: %d\n", u2Len); + u2CopySize = (u2Len >= 256) ? 255 : u2Len; + if (u2CopySize > 0) + kalMemCopy(aucVersionBuf, &aucDriverVersionStr[0], + u2CopySize); + } else if (attrlist->nla_type == LOGGER_ATTRIBUTE_FW_VER) { + struct ADAPTER *prAdapter; + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + ASSERT(prGlueInfo); + prAdapter = prGlueInfo->prAdapter; + if (prAdapter) { + u2Len = kalStrLen( + prAdapter->rVerInfo.aucReleaseManifest); + DBGLOG(REQ, TRACE, + "Get FW manifest version len: %d\n", u2Len); + u2CopySize = (u2Len >= 256) ? 255 : u2Len; + if (u2CopySize > 0) + kalMemCopy(aucVersionBuf, + prAdapter->rVerInfo.aucReleaseManifest, + u2CopySize); + } + } + + DBGLOG(REQ, TRACE, "Get version(%d)=[%s]\n", u2CopySize, aucVersionBuf); + + if (u2CopySize == 0) + return -EFAULT; + + skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, u2CopySize); + if (!skb) { + DBGLOG(REQ, ERROR, "Allocate skb failed\n"); + return -ENOMEM; + } + + if (unlikely(nla_put_nohdr(skb, u2CopySize, &aucVersionBuf[0]) < 0)) + goto nla_put_failure; + + return cfg80211_vendor_cmd_reply(skb); + +nla_put_failure: + kfree_skb(skb); + return -EFAULT; +} + +int mtk_cfg80211_vendor_event_generic_response( + struct wiphy *wiphy, struct wireless_dev *wdev, + uint32_t len, uint8_t *data) +{ + struct sk_buff *skb; + + if (!wiphy || !wdev || !data || len <= 0) { + DBGLOG(REQ, ERROR, "%s wrong input parameters\n", __func__); + return -EINVAL; + } + + skb = cfg80211_vendor_event_alloc(wiphy, +#if KERNEL_VERSION(4, 4, 0) <= CFG80211_VERSION_CODE + wdev, +#endif + len, WIFI_EVENT_GENERIC_RESPONSE, GFP_KERNEL); + if (!skb) { + DBGLOG(REQ, ERROR, "%s allocate skb failed\n", __func__); + return -ENOMEM; + } + + /* Do not use nla_put_nohdr because it aligns buffer + * + * if (unlikely(nla_put_nohdr(skb, len, data) < 0)) + * goto nla_put_failure; + */ + kalMemCopy(skb_put(skb, len), data, len); + + cfg80211_vendor_event(skb, GFP_KERNEL); + return 0; +} + +int mtk_cfg80211_vendor_get_supported_feature_set(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int data_len) +{ + uint64_t u8FeatureSet; + struct GLUE_INFO *prGlueInfo; + struct sk_buff *skb; + + ASSERT(wiphy); + ASSERT(wdev); + + prGlueInfo = wlanGetGlueInfo(); + if (!prGlueInfo) + return -EFAULT; + + u8FeatureSet = wlanGetSupportedFeatureSet(prGlueInfo); + + skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u8FeatureSet)); + if (!skb) { + DBGLOG(REQ, ERROR, "Allocate skb failed\n"); + return -ENOMEM; + } + + if (unlikely( + nla_put_nohdr(skb, sizeof(u8FeatureSet), &u8FeatureSet) < 0)) { + DBGLOG(REQ, ERROR, "nla_put_nohdr failed\n"); + goto nla_put_failure; + } + + DBGLOG(REQ, TRACE, "supported feature set=0x%llx\n", u8FeatureSet); + + return cfg80211_vendor_cmd_reply(skb); + +nla_put_failure: + kfree_skb(skb); + return -EFAULT; +} + +int mtk_cfg80211_vendor_event_rssi_beyond_range( + struct wiphy *wiphy, struct wireless_dev *wdev, int rssi) +{ + struct sk_buff *skb; + struct PARAM_RSSI_MONITOR_EVENT rRSSIEvt; + struct BSS_INFO *prAisBssInfo; + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter; + uint8_t ucBssIndex = AIS_DEFAULT_INDEX; + + ASSERT(wiphy); + ASSERT(wdev); + + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + ASSERT(prGlueInfo); + + DBGLOG(REQ, TRACE, "vendor command rssi=%d\r\n", rssi); + kalMemZero(&rRSSIEvt, + sizeof(struct PARAM_RSSI_MONITOR_EVENT)); + +#if KERNEL_VERSION(4, 4, 0) <= LINUX_VERSION_CODE + skb = cfg80211_vendor_event_alloc(wiphy, wdev, + sizeof(struct PARAM_RSSI_MONITOR_EVENT), + WIFI_EVENT_RSSI_MONITOR, GFP_KERNEL); +#else + skb = cfg80211_vendor_event_alloc(wiphy, + sizeof(struct PARAM_RSSI_MONITOR_EVENT), + WIFI_EVENT_RSSI_MONITOR, GFP_KERNEL); +#endif /* KERNEL_VERSION(4, 4, 0) <= LINUX_VERSION_CODE */ + + if (!skb) { + DBGLOG(REQ, ERROR, "%s allocate skb failed\n", __func__); + return -ENOMEM; + } + + prAdapter = prGlueInfo->prAdapter; + prAisBssInfo = aisGetAisBssInfo(prAdapter, ucBssIndex); + kalMemCopy(rRSSIEvt.BSSID, prAisBssInfo->aucBSSID, + sizeof(uint8_t) * MAC_ADDR_LEN); + + rRSSIEvt.version = 1; /* RSSI_MONITOR_EVT_VERSION = 1 */ + if (rssi > PARAM_WHQL_RSSI_MAX_DBM) + rssi = PARAM_WHQL_RSSI_MAX_DBM; + else if (rssi < -120) + rssi = -120; + rRSSIEvt.rssi = (int8_t)rssi; + DBGLOG(REQ, INFO, + "RSSI Event: version=%d, rssi=%d, BSSID=" MACSTR "\r\n", + rRSSIEvt.version, rRSSIEvt.rssi, MAC2STR(rRSSIEvt.BSSID)); + + /*NLA_PUT_U32(skb, GOOGLE_RSSI_MONITOR_EVENT, rssi);*/ + { + /* unsigned int __tmp = rssi; */ + + if (unlikely(nla_put(skb, WIFI_EVENT_RSSI_MONITOR, + sizeof(struct PARAM_RSSI_MONITOR_EVENT), + &rRSSIEvt) < 0)) + goto nla_put_failure; + } + + cfg80211_vendor_event(skb, GFP_KERNEL); + return 0; + +nla_put_failure: + kfree_skb(skb); + return -ENOMEM; +} + +int mtk_cfg80211_vendor_set_tx_power_scenario(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int data_len) +{ +#if CFG_SUPPORT_DYNAMIC_PWR_LIMIT + struct PARAM_TX_PWR_CTRL_IOCTL rPwrCtrlParam = { 0 }; + struct GLUE_INFO *prGlueInfo; + struct nlattr *attr; + struct sk_buff *skb; + uint32_t u4Scenario; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4SetInfoLen = 0; + uint8_t index = 0; + char name[] = { "_G_Scenario" }; + + ASSERT(wiphy); + ASSERT(wdev); + +#if CFG_ENABLE_UNIFY_WIPHY + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); +#else /* CFG_ENABLE_UNIFY_WIPHY */ + if (wdev == gprWdev) /* wlan0 */ + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + else + prGlueInfo = *((struct GLUE_INFO **) wiphy_priv(wiphy)); +#endif /* CFG_ENABLE_UNIFY_WIPHY */ + + if (!prGlueInfo) + return -EFAULT; + + attr = (struct nlattr *)data; + if (attr->nla_type == WIFI_ATTRIBUTE_TX_POWER_SCENARIO) + u4Scenario = nla_get_u32(attr); + else + return -EINVAL; + + if (u4Scenario == UINT_MAX) { + index = 0; + } else if ((u4Scenario >= 0) && (u4Scenario <= 4)) { + index = u4Scenario + 1; + } else { + DBGLOG(REQ, ERROR, "invalid scenario index: %u\n", u4Scenario); + return -EINVAL; + } + + rPwrCtrlParam.fgApplied = (index == 0) ? FALSE : TRUE; + rPwrCtrlParam.name = name; + rPwrCtrlParam.index = index; + + DBGLOG(REQ, INFO, + "applied=[%d], name=[%s], index=[%u], setting=[%s], UINT_MAX=[%u], iftype=[%d]\n", + rPwrCtrlParam.fgApplied, + rPwrCtrlParam.name, + rPwrCtrlParam.index, + rPwrCtrlParam.newSetting, + UINT_MAX, + wdev->iftype); + + rStatus = kalIoctl(prGlueInfo, + wlanoidTxPowerControl, + (void *)&rPwrCtrlParam, + sizeof(struct PARAM_TX_PWR_CTRL_IOCTL), + FALSE, + FALSE, + TRUE, + &u4SetInfoLen); + + skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(rStatus)); + if (!skb) { + DBGLOG(REQ, ERROR, "Allocate skb failed\n"); + return -ENOMEM; + } + + if (unlikely( + nla_put_nohdr(skb, sizeof(rStatus), &rStatus) < 0)) { + DBGLOG(REQ, ERROR, "nla_put_nohdr failed\n"); + goto errHandleLabel; + } + + DBGLOG(REQ, INFO, "rStatus=0x%x\n", rStatus); + + return cfg80211_vendor_cmd_reply(skb); + +errHandleLabel: + kfree_skb(skb); +#endif + return -EFAULT; +} + +int mtk_cfg80211_vendor_get_preferred_freq_list(struct wiphy + *wiphy, struct wireless_dev *wdev, const void *data, + int data_len) +{ + struct GLUE_INFO *prGlueInfo; + struct sk_buff *skb; + struct nlattr *tb[WIFI_VENDOR_ATTR_PREFERRED_FREQ_LIST_LAST] = {}; + uint32_t freq_list[MAX_CHN_NUM] = {}; + uint32_t num_freq_list = 0; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + enum CONN_MODE_IFACE_TYPE type; + enum ENUM_IFTYPE eIftype; + uint32_t i; + + ASSERT(wiphy); + ASSERT(wdev); + + if ((data == NULL) || !data_len) + return -EINVAL; + + prGlueInfo = wlanGetGlueInfo(); + if (!prGlueInfo) + return -EFAULT; + + if (NLA_PARSE(tb, WIFI_VENDOR_ATTR_PREFERRED_FREQ_LIST_MAX, + data, data_len, nla_get_preferred_freq_list_policy)) { + DBGLOG(REQ, ERROR, "Invalid ATTR.\n"); + return -EINVAL; + } + + type = nla_get_u32(tb[WIFI_VENDOR_ATTR_PREFERRED_FREQ_LIST_IFACE_TYPE]); + + DBGLOG(REQ, INFO, "type: %d\n", type); + + switch (type) { + case CONN_MODE_IFACE_TYPE_STA: + eIftype = IFTYPE_STATION; + break; + case CONN_MODE_IFACE_TYPE_SAP: + eIftype = IFTYPE_AP; + break; + case CONN_MODE_IFACE_TYPE_P2P_GC: + eIftype = IFTYPE_P2P_CLIENT; + break; + case CONN_MODE_IFACE_TYPE_P2P_GO: + eIftype = IFTYPE_P2P_GO; + break; + default: + eIftype = IFTYPE_NUM; + break; + } + + if (eIftype != IFTYPE_P2P_CLIENT && eIftype != IFTYPE_P2P_GO) { + DBGLOG(REQ, ERROR, "Only support p2p gc/go type.\n"); + return -EINVAL; + } + + rStatus = p2pFunGetPreferredFreqList(prGlueInfo->prAdapter, eIftype, + freq_list, &num_freq_list); + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, ERROR, "get preferred freq list failed.\n"); + return -EINVAL; + } + + DBGLOG(P2P, INFO, "num. of preferred freq list = %d\n", num_freq_list); + for (i = 0; i < num_freq_list; i++) + DBGLOG(P2P, INFO, "dump preferred freq list[%d] = %d\n", + i, freq_list[i]); + + skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) + + sizeof(uint32_t) * num_freq_list + NLMSG_HDRLEN); + if (!skb) { + DBGLOG(REQ, ERROR, "Allocate skb failed.\n"); + return -ENOMEM; + } + + if (unlikely(nla_put_u32(skb, + WIFI_VENDOR_ATTR_PREFERRED_FREQ_LIST_IFACE_TYPE, + type) < 0)) { + DBGLOG(REQ, ERROR, "put iface into skb failed.\n"); + goto nla_put_failure; + } + + if (unlikely(nla_put(skb, WIFI_VENDOR_ATTR_PREFERRED_FREQ_LIST_GET, + sizeof(uint32_t) * num_freq_list, freq_list) < 0)) { + DBGLOG(REQ, ERROR, "put freq list into skb failed.\n"); + goto nla_put_failure; + } + + return cfg80211_vendor_cmd_reply(skb); + +nla_put_failure: + kfree_skb(skb); + return -EFAULT; +} + +int mtk_cfg80211_vendor_acs(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int data_len) +{ + struct GLUE_INFO *prGlueInfo; + struct nlattr *tb[WIFI_VENDOR_ATTR_ACS_MAX + 1] = {}; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + bool ht_enabled, ht40_enabled, vht_enabled; + uint8_t ch_width = 0; + enum P2P_VENDOR_ACS_HW_MODE hw_mode; + uint8_t *ch_list = NULL; + uint8_t ch_list_count = 0; + uint8_t i; + uint32_t msg_size; + struct MSG_P2P_ACS_REQUEST *prMsgAcsRequest; + struct RF_CHANNEL_INFO *prRfChannelInfo; + struct sk_buff *reply_skb; + uint8_t role_idx; + + if (!wiphy || !wdev || !data || !data_len) { + DBGLOG(REQ, ERROR, "input data null.\n"); + rStatus = -EINVAL; + goto exit; + } + +#if CFG_ENABLE_UNIFY_WIPHY + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); +#else /* CFG_ENABLE_UNIFY_WIPHY */ + if (wdev == gprWdev) /* wlan0 */ + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + else + prGlueInfo = *((struct GLUE_INFO **) wiphy_priv(wiphy)); +#endif /* CFG_ENABLE_UNIFY_WIPHY */ + + if (!prGlueInfo) { + DBGLOG(REQ, ERROR, "get glue structure fail.\n"); + rStatus = -EFAULT; + goto exit; + } + + if (mtk_Netdev_To_RoleIdx(prGlueInfo, wdev->netdev, &role_idx) < 0) { + DBGLOG(REQ, ERROR, "get role index fail.\n"); + rStatus = -EFAULT; + goto exit; + } + + if (NLA_PARSE(tb, WIFI_VENDOR_ATTR_ACS_MAX, data, data_len, + nla_get_acs_policy)) { + DBGLOG(REQ, ERROR, "parse acs attr fail.\n"); + rStatus = -EINVAL; + goto exit; + } + + if (!tb[WIFI_VENDOR_ATTR_ACS_HW_MODE]) { + DBGLOG(REQ, ERROR, "attr hw_mode failed.\n"); + rStatus = -EINVAL; + goto exit; + } + hw_mode = nla_get_u8(tb[WIFI_VENDOR_ATTR_ACS_HW_MODE]); + + if (tb[WIFI_VENDOR_ATTR_ACS_HT_ENABLED]) + ht_enabled = + nla_get_flag(tb[WIFI_VENDOR_ATTR_ACS_HT_ENABLED]); + else + ht_enabled = 0; + + if (tb[WIFI_VENDOR_ATTR_ACS_HT40_ENABLED]) + ht40_enabled = + nla_get_flag(tb[WIFI_VENDOR_ATTR_ACS_HT40_ENABLED]); + else + ht40_enabled = 0; + + if (tb[WIFI_VENDOR_ATTR_ACS_VHT_ENABLED]) + vht_enabled = + nla_get_flag(tb[WIFI_VENDOR_ATTR_ACS_VHT_ENABLED]); + else + vht_enabled = 0; + + if (tb[WIFI_VENDOR_ATTR_ACS_CHWIDTH]) + ch_width = nla_get_u16(tb[WIFI_VENDOR_ATTR_ACS_CHWIDTH]); + + if (tb[WIFI_VENDOR_ATTR_ACS_CH_LIST]) { + char *tmp = nla_data(tb[WIFI_VENDOR_ATTR_ACS_CH_LIST]); + + ch_list_count = nla_len(tb[WIFI_VENDOR_ATTR_ACS_CH_LIST]); + if (ch_list_count) { + if (ch_list_count > MAX_CHN_NUM) { + DBGLOG(REQ, ERROR, "Invalid channel count.\n"); + rStatus = -EINVAL; + goto exit; + } + ch_list = kalMemAlloc(sizeof(uint8_t) * ch_list_count, + VIR_MEM_TYPE); + if (ch_list == NULL) { + DBGLOG(REQ, ERROR, "allocate ch_list fail.\n"); + rStatus = -ENOMEM; + goto exit; + } + + kalMemCopy(ch_list, tmp, ch_list_count); + } + } else if (tb[WIFI_VENDOR_ATTR_ACS_FREQ_LIST]) { + uint32_t *freq = + nla_data(tb[WIFI_VENDOR_ATTR_ACS_FREQ_LIST]); + + ch_list_count = nla_len(tb[WIFI_VENDOR_ATTR_ACS_FREQ_LIST]) / + sizeof(uint32_t); + if (ch_list_count) { + if (ch_list_count > MAX_CHN_NUM) { + DBGLOG(REQ, ERROR, "Invalid freq count.\n"); + rStatus = -EINVAL; + goto exit; + } + ch_list = kalMemAlloc(sizeof(uint8_t) * ch_list_count, + VIR_MEM_TYPE); + if (ch_list == NULL) { + DBGLOG(REQ, ERROR, "allocate ch_list fail.\n"); + rStatus = -ENOMEM; + goto exit; + } + + for (i = 0; i < ch_list_count; i++) + ch_list[i] = + ieee80211_frequency_to_channel(freq[i]); + } + } + + if (!ch_list_count) { + DBGLOG(REQ, ERROR, "channel list count can NOT be 0\n"); + rStatus = -EINVAL; + goto exit; + } + + msg_size = sizeof(struct MSG_P2P_ACS_REQUEST) + + (ch_list_count * sizeof(struct RF_CHANNEL_INFO)); + + prMsgAcsRequest = cnmMemAlloc(prGlueInfo->prAdapter, + RAM_TYPE_MSG, msg_size); + + if (prMsgAcsRequest == NULL) { + DBGLOG(REQ, ERROR, "allocate msg acs req. fail.\n"); + rStatus = -ENOMEM; + goto exit; + } + + kalMemSet(prMsgAcsRequest, 0, msg_size); + prMsgAcsRequest->rMsgHdr.eMsgId = MID_MNY_P2P_ACS; + prMsgAcsRequest->ucRoleIdx = role_idx; + prMsgAcsRequest->fgIsHtEnable = ht_enabled; + prMsgAcsRequest->fgIsHt40Enable = ht40_enabled; + prMsgAcsRequest->fgIsVhtEnable = vht_enabled; + switch (ch_width) { + case 20: + prMsgAcsRequest->eChnlBw = MAX_BW_20MHZ; + break; + case 40: + prMsgAcsRequest->eChnlBw = MAX_BW_40MHZ; + break; + case 80: + prMsgAcsRequest->eChnlBw = MAX_BW_80MHZ; + break; + case 160: + prMsgAcsRequest->eChnlBw = MAX_BW_160MHZ; + break; + default: + DBGLOG(REQ, ERROR, "unsupport width: %d.\n", ch_width); + prMsgAcsRequest->eChnlBw = MAX_BW_UNKNOWN; + break; + } + prMsgAcsRequest->eHwMode = hw_mode; + prMsgAcsRequest->u4NumChannel = ch_list_count; + + for (i = 0; i < ch_list_count; i++) { + /* Translate Freq from MHz to channel number. */ + prRfChannelInfo = + &(prMsgAcsRequest->arChannelListInfo[i]); + + prRfChannelInfo->ucChannelNum = ch_list[i]; + + if (prRfChannelInfo->ucChannelNum <= 14) + prRfChannelInfo->eBand = BAND_2G4; + else + prRfChannelInfo->eBand = BAND_5G; + + /* Iteration. */ + prRfChannelInfo++; + } + + mboxSendMsg(prGlueInfo->prAdapter, + MBOX_ID_0, + (struct MSG_HDR *) prMsgAcsRequest, + MSG_SEND_METHOD_BUF); + +exit: + if (ch_list) + kalMemFree(ch_list, VIR_MEM_TYPE, + sizeof(uint8_t) * ch_list_count); + if (rStatus == WLAN_STATUS_SUCCESS) { + reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, + NLMSG_HDRLEN); + if (reply_skb != NULL) + return cfg80211_vendor_cmd_reply(reply_skb); + } + return rStatus; +} + +int mtk_cfg80211_vendor_get_features(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int data_len) +{ + struct sk_buff *reply_skb; + uint8_t feature_flags[(NUM_VENDOR_FEATURES + 7) / 8] = {0}; + uint8_t i; + + ASSERT(wiphy); + ASSERT(wdev); + +#if CFG_AUTO_CHANNEL_SEL_SUPPORT + feature_flags[(VENDOR_FEATURE_SUPPORT_HW_MODE_ANY / 8)] |= + (1 << (VENDOR_FEATURE_SUPPORT_HW_MODE_ANY % 8)); +#endif + + for (i = 0; i < ((NUM_VENDOR_FEATURES + 7) / 8); i++) { + DBGLOG(REQ, TRACE, "Dump feature flags[%d]=0x%x.\n", i, + feature_flags[i]); + } + + reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, + sizeof(feature_flags) + NLMSG_HDRLEN); + + if (!reply_skb) + goto nla_put_failure; + + if (nla_put(reply_skb, WIFI_VENDOR_ATTR_FEATURE_FLAGS, + sizeof(feature_flags), feature_flags)) + goto nla_put_failure; + + return cfg80211_vendor_cmd_reply(reply_skb); + +nla_put_failure: + kfree_skb(reply_skb); + return -EINVAL; +} + +int mtk_cfg80211_vendor_driver_memory_dump(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int data_len) +{ +#ifdef CFG_SUPPORT_LINK_QUALITY_MONITOR + struct LINK_QUALITY_INFO_OUTPUT_DATA { + uint16_t u2Tag01; /* cur tx rate */ + uint16_t u2Len01; + uint32_t u4CurTxRate; + uint16_t u2Tag02; /* tx total count */ + uint16_t u2Len02; + uint64_t u8TxTotalCount; + uint16_t u2Tag03; /* tx retry count */ + uint16_t u2Len03; + uint64_t u8TxRetryCount; + uint16_t u2Tag04; /* tx fail Count */ + uint16_t u2Len04; + uint64_t u8TxFailCount; + uint16_t u2Tag05; /* Rts fail count */ + uint16_t u2Len05; + uint64_t u8TxRtsFailCount; + uint16_t u2Tag06; /* Ack fail count */ + uint16_t u2Len06; + uint64_t u8TxAckFailCount; + uint16_t u2Tag07; /* cur rx rate */ + uint16_t u2Len07; + uint32_t u4CurRxRate; + uint16_t u2Tag08; /* Rx total count */ + uint16_t u2Len08; + uint64_t u8RxTotalCount; + uint16_t u2Tag09; /* Rx dup count */ + uint16_t u2Len09; + uint32_t u4RxDupCount; + uint16_t u2Tag10; /* Rx err count */ + uint16_t u2Len10; + uint64_t u8RxErrCount; + uint16_t u2Tag11; /* Idle slot count */ + uint16_t u2Len11; + uint64_t u8IdleSlotCount; + uint16_t u2Tag12; /* Awake duration */ + uint16_t u2Len12; + uint64_t u8HwMacAwakeDuration; + uint16_t u2Tag13; /* Scan Flag */ + uint16_t u2Len13; + uint16_t u2FlagScanning; + } __packed outputData = { + .u2Tag01 = 1, /* tag: 1, cur tx rate */ + .u2Len01 = 4, /* len: 4, bytes */ + .u2Tag02 = 2, /* tag: 2, tx total count */ + .u2Len02 = 8, /* len: 8, bytes */ + .u2Tag03 = 3, /* tag: 3, tx retry count */ + .u2Len03 = 8, /* len: 8, bytes */ + .u2Tag04 = 4, /* tag: 4, tx fail count */ + .u2Len04 = 8, /* len: 8, bytes */ + .u2Tag05 = 5, /* tag: 5, tx rts fail count */ + .u2Len05 = 8, /* len: 8, bytes */ + .u2Tag06 = 6, /* tag: 6, tx ack fail count */ + .u2Len06 = 8, /* len: 8, bytes */ + .u2Tag07 = 7, /* tag: 7, cur rx rate */ + .u2Len07 = 4, /* len: 4, bytes */ + .u2Tag08 = 8, /* tag: 8, rx total count */ + .u2Len08 = 8, /* len: 8, bytes */ + .u2Tag09 = 9, /* tag: 9, rx dup count */ + .u2Len09 = 4, /* len: 4, bytes */ + .u2Tag10 = 10, /* tag: 10, rx err count */ + .u2Len10 = 8, /* len: 8, bytes */ + .u2Tag11 = 11, + .u2Len11 = 8, + .u2Tag12 = 12, /* tag: 12, Hw Mac Awake Duration */ + .u2Len12 = 8, /* len: 8, bytes */ + .u2Tag13 = 13, /* tag: 13, Scanning Flag */ + .u2Len13 = 2, /* len: 2, bytes */ + }; + struct PARAM_GET_LINK_QUALITY_INFO rParam; + struct NETDEV_PRIVATE_GLUE_INFO *prNetDevPrivate; + struct WIFI_LINK_QUALITY_INFO rLinkQualityInfo; + struct GLUE_INFO *prGlueInfo; +#endif + struct sk_buff *skb = NULL; + uint32_t *puBuffer = NULL; + int32_t i4Status = -EINVAL; + uint32_t u4BufLen; + uint16_t u2CopySize = 0; + + ASSERT(wiphy); + ASSERT(wdev); +#ifdef CFG_SUPPORT_LINK_QUALITY_MONITOR + prNetDevPrivate = + (struct NETDEV_PRIVATE_GLUE_INFO *) netdev_priv(wdev->netdev); + if (!prNetDevPrivate) { + DBGLOG(REQ, ERROR, "Invalid net device private\n"); + return -EFAULT; + } + rParam.ucBssIdx = 0; /* prNetDevPrivate->ucBssIdx; */ + rParam.prLinkQualityInfo = &rLinkQualityInfo; + prGlueInfo = (struct GLUE_INFO *) wiphy_priv(wiphy); + i4Status = kalIoctl(prGlueInfo, wlanoidGetLinkQualityInfo, + &rParam, sizeof(struct PARAM_GET_LINK_QUALITY_INFO), + TRUE, FALSE, FALSE, &u4BufLen); + if (i4Status != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, ERROR, "wlanoidGetLinkQualityInfo error\n"); + goto err_handle_label; + } + + outputData.u4CurTxRate = rLinkQualityInfo.u4CurTxRate; + outputData.u8TxTotalCount = rLinkQualityInfo.u8TxTotalCount; + outputData.u8TxRetryCount = rLinkQualityInfo.u8TxRetryCount; + outputData.u8TxFailCount = rLinkQualityInfo.u8TxFailCount; + outputData.u8TxRtsFailCount = rLinkQualityInfo.u8TxRtsFailCount; + outputData.u8TxAckFailCount = rLinkQualityInfo.u8TxAckFailCount; + outputData.u4CurRxRate = rLinkQualityInfo.u4CurRxRate; + outputData.u8RxTotalCount = rLinkQualityInfo.u8RxTotalCount; + outputData.u4RxDupCount = rLinkQualityInfo.u4RxDupCount; + outputData.u8RxErrCount = rLinkQualityInfo.u8RxErrCount; + outputData.u8IdleSlotCount = rLinkQualityInfo.u8IdleSlotCount; + outputData.u8HwMacAwakeDuration = rLinkQualityInfo.u4HwMacAwakeDuration; + outputData.u2FlagScanning = rLinkQualityInfo.u2FlagScanning; + + DBGLOG(REQ, INFO, + "LQ: Tx(rate:%u, total:%u, Rty:%lu, fail:%lu, RTSF:%lu, ACKF:%lu), Rx(rate:%u, total:%u, dup:%u, error:%lu), Idle:%lu AwakeDur:%lu\n", + outputData.u4CurTxRate, /* tx rate, current tx link speed */ + outputData.u8TxTotalCount, /* tx total packages */ + outputData.u8TxRetryCount, /* tx retry count */ + outputData.u8TxFailCount, /* tx fail count */ + outputData.u8TxRtsFailCount, /* tx RTS fail count */ + outputData.u8TxAckFailCount, /* tx ACK fail count */ + outputData.u4CurRxRate, /* current rx rate */ + outputData.u8RxTotalCount, /* rx total packages */ + outputData.u4RxDupCount, /* rx duplicate package count */ + outputData.u8RxErrCount, /* rx error count */ + outputData.u8IdleSlotCount, + outputData.u8HwMacAwakeDuration + ); + + u2CopySize = sizeof(struct LINK_QUALITY_INFO_OUTPUT_DATA); + puBuffer = (uint32_t *)&outputData; +#endif + + skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, u2CopySize); + if (!skb) { + DBGLOG(REQ, ERROR, "allocate skb failed\n"); + i4Status = -ENOMEM; + goto err_handle_label; + } + + if (unlikely(nla_put_nohdr(skb, u2CopySize, puBuffer) < 0)) { + DBGLOG(REQ, ERROR, "nla_put_nohdr failed: len=%u, ptr=%p\n", + u2CopySize, puBuffer); + i4Status = -EINVAL; + goto err_handle_label; + } + + return cfg80211_vendor_cmd_reply(skb); + +err_handle_label: + kfree_skb(skb); + return i4Status; +} + +#endif /* KERNEL_VERSION(3, 16, 0) <= LINUX_VERSION_CODE */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_wext.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_wext.c new file mode 100644 index 0000000000000000000000000000000000000000..59a99640f36e00894d32300a7b62a0607eb49709 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_wext.c @@ -0,0 +1,5002 @@ +/******************************************************************************* + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux + * /gl_wext.c#5 + */ + +/*! \file gl_wext.c + * \brief ioctl() (mostly Linux Wireless Extensions) routines for STA + * driver. + */ + + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +#include "gl_os.h" + +#include "config.h" +#include "wlan_oid.h" + +#include "gl_wext.h" +#include "gl_wext_priv.h" + +#include "precomp.h" + +#if CFG_SUPPORT_WAPI +#include "gl_sec.h" +#endif + +/* compatibility to wireless extensions */ +#ifdef WIRELESS_EXT + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +const long channel_freq[] = { + 2412, 2417, 2422, 2427, 2432, 2437, 2442, + 2447, 2452, 2457, 2462, 2467, 2472, 2484 +}; + +#define NUM_CHANNELS (ARRAY_SIZE(channel_freq)) + +#define MAX_SSID_LEN 32 +#define COUNTRY_CODE_LEN 10 /* country code length */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ +/* NOTE: name in iwpriv_args only have 16 bytes */ +static const struct iw_priv_args rIwPrivTable[] = { + {IOCTL_SET_INT, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, ""}, + {IOCTL_GET_INT, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, ""}, + {IOCTL_SET_INT, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, ""}, + {IOCTL_GET_INT, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, ""}, + {IOCTL_SET_INT, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, ""}, + + { + IOCTL_GET_INT, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "" + }, + { + IOCTL_GET_INT, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "" + }, + + {IOCTL_SET_INTS, IW_PRIV_TYPE_INT | 4, 0, ""}, + {IOCTL_GET_INT, 0, IW_PRIV_TYPE_INT | 50, ""}, + + /* added for set_oid and get_oid */ + {IOCTL_SET_STRUCT, 256, 0, ""}, + {IOCTL_GET_STRUCT, 0, 256, ""}, + + {IOCTL_GET_DRIVER, IW_PRIV_TYPE_CHAR | 2000, IW_PRIV_TYPE_CHAR | + 2000, "driver"}, + +#if CFG_SUPPORT_QA_TOOL + /* added for ATE iwpriv Command */ + {IOCTL_IWPRIV_ATE, IW_PRIV_TYPE_CHAR | 2000, 0, ""}, +#endif + {IOC_AP_SET_CFG, IW_PRIV_TYPE_CHAR | 256, + IW_PRIV_TYPE_CHAR | 1024, "AP_SET_CFG"}, + {IOC_AP_GET_STA_LIST, IW_PRIV_TYPE_CHAR | 1024, + IW_PRIV_TYPE_CHAR | 1024, "AP_GET_STA_LIST"}, + {IOC_AP_SET_MAC_FLTR, IW_PRIV_TYPE_CHAR | 256, + IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 1024, "AP_SET_MAC_FLTR"}, + {IOC_AP_STA_DISASSOC, IW_PRIV_TYPE_CHAR | 256, + IW_PRIV_TYPE_CHAR | 1024, "AP_STA_DISASSOC"}, + {IOC_AP_SET_NSS, IW_PRIV_TYPE_CHAR | 256, + IW_PRIV_TYPE_CHAR | 1024, "AP_SET_NSS"}, + + /* sub-ioctl definitions */ +#if 0 + {PRIV_CMD_REG_DOMAIN, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | + 1, 0, "set_reg_domain"}, + {PRIV_CMD_REG_DOMAIN, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | + 1, "get_reg_domain"}, +#endif + +#if CFG_TCP_IP_CHKSUM_OFFLOAD + {PRIV_CMD_CSUM_OFFLOAD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | + 1, 0, "set_tcp_csum"}, +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ + + {PRIV_CMD_POWER_MODE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | + 1, 0, "set_power_mode"}, + {PRIV_CMD_POWER_MODE, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | + 1, "get_power_mode"}, + + {PRIV_CMD_WMM_PS, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | + 3, 0, "set_wmm_ps"}, + + {PRIV_CMD_TEST_MODE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | + 1, 0, "set_test_mode"}, + {PRIV_CMD_TEST_CMD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | + 2, 0, "set_test_cmd"}, + { + PRIV_CMD_TEST_CMD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_test_result" + }, +#if CFG_SUPPORT_PRIV_MCR_RW + {PRIV_CMD_ACCESS_MCR, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | + 2, 0, "set_mcr"}, + { + PRIV_CMD_ACCESS_MCR, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_mcr" + }, +#endif + +#if CFG_SUPPORT_QA_TOOL + {PRIV_QACMD_SET, IW_PRIV_TYPE_CHAR | 2000, 0, "set"}, +#endif + + {PRIV_CMD_SW_CTRL, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | + 2, 0, "set_sw_ctrl"}, + { + PRIV_CMD_SW_CTRL, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_sw_ctrl" + }, + +#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS + {PRIV_CUSTOM_BWCS_CMD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | + 1, 0, "set_bwcs"}, + /* GET STRUCT sub-ioctls commands */ + { + PRIV_CUSTOM_BWCS_CMD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_bwcs" + }, +#endif + + /* SET STRUCT sub-ioctls commands */ + {PRIV_CMD_OID, 256, 0, "set_oid"}, + /* GET STRUCT sub-ioctls commands */ + {PRIV_CMD_OID, 0, 256, "get_oid"}, + + {PRIV_CMD_BAND_CONFIG, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | + 1, 0, "set_band"}, + {PRIV_CMD_BAND_CONFIG, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | + 1, "get_band"}, + {PRIV_CMD_GET_CH_LIST, 0, IW_PRIV_TYPE_INT | 50, "get_ch_list"}, + { + PRIV_CMD_DUMP_MEM, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_mem" + }, + +#if CFG_ENABLE_WIFI_DIRECT + {PRIV_CMD_P2P_MODE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | + 2, 0, "set_p2p_mode"}, +#endif + {PRIV_CMD_MET_PROFILING, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | + 2, 0, "set_met_prof"}, + {PRIV_CMD_SET_SER, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | + 1, 0, "set_ser"}, + +}; + +static const iw_handler rIwPrivHandler[] = { + [IOCTL_SET_INT - SIOCIWFIRSTPRIV] = priv_set_int, + [IOCTL_GET_INT - SIOCIWFIRSTPRIV] = priv_get_int, + [IOCTL_SET_ADDRESS - SIOCIWFIRSTPRIV] = NULL, + [IOCTL_GET_ADDRESS - SIOCIWFIRSTPRIV] = NULL, + [IOCTL_SET_STR - SIOCIWFIRSTPRIV] = NULL, + [IOCTL_GET_STR - SIOCIWFIRSTPRIV] = NULL, + [IOCTL_SET_KEY - SIOCIWFIRSTPRIV] = NULL, + [IOCTL_GET_KEY - SIOCIWFIRSTPRIV] = NULL, + [IOCTL_SET_STRUCT - SIOCIWFIRSTPRIV] = priv_set_struct, + [IOCTL_GET_STRUCT - SIOCIWFIRSTPRIV] = priv_get_struct, + [IOCTL_SET_STRUCT_FOR_EM - SIOCIWFIRSTPRIV] = priv_set_struct, + [IOCTL_SET_INTS - SIOCIWFIRSTPRIV] = priv_set_ints, + [IOCTL_GET_INTS - SIOCIWFIRSTPRIV] = priv_get_ints, + [IOCTL_GET_DRIVER - SIOCIWFIRSTPRIV] = priv_set_driver, + [IOC_AP_GET_STA_LIST - SIOCIWFIRSTPRIV] = priv_set_ap, + [IOC_AP_SET_MAC_FLTR - SIOCIWFIRSTPRIV] = priv_set_ap, + [IOC_AP_SET_CFG - SIOCIWFIRSTPRIV] = priv_set_ap, + [IOC_AP_STA_DISASSOC - SIOCIWFIRSTPRIV] = priv_set_ap, + [IOC_AP_SET_NSS - SIOCIWFIRSTPRIV] = priv_set_ap, +#if CFG_SUPPORT_QA_TOOL + [IOCTL_QA_TOOL_DAEMON - SIOCIWFIRSTPRIV] = priv_qa_agent, + [IOCTL_IWPRIV_ATE - SIOCIWFIRSTPRIV] = priv_ate_set +#endif +}; + +/* standard ioctls */ +static int std_get_name(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra); + +static int std_set_freq(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra); + +static int std_get_freq(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra); + +static int std_set_mode(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra); + +static int std_get_mode(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra); + +static int std_set_ap(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra); + +static int std_get_ap(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra); + +static int std_get_rate(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra); + +static int std_set_rts(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra); + +static int std_get_rts(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra); + +static int std_get_frag(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra); + +static int std_set_txpow(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra); + +static int std_get_txpow(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra); + +static int std_set_power(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra); + +static int std_get_power(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra); + +static int std_get_range(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra); + +static int std_set_priv(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra); + +static int std_get_priv(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra); + +static int std_set_mlme(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra); + +static int std_set_scan(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra); + +static int std_get_scan(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra); + +static int std_set_essid(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra); + +static int std_get_essid(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra); + +static int std_set_encode(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra); + +static int std_get_encode(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra); + +static int std_set_auth(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra); + +#if (WIRELESS_EXT > 17) +static int std_set_genie(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra); +#endif + +static int std_set_encode_ext(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra); + +static int std_set_pmska(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra); + +static const iw_handler mtk_std_handler[] = { + IW_HANDLER(SIOCGIWNAME, std_get_name), /* factory mode used */ + IW_HANDLER(SIOCSIWFREQ, std_set_freq), + IW_HANDLER(SIOCGIWFREQ, std_get_freq), /* factory mode used */ + IW_HANDLER(SIOCSIWMODE, std_set_mode), /* factory mode used */ + IW_HANDLER(SIOCGIWMODE, std_get_mode), /* factory mode used */ + IW_HANDLER(SIOCGIWRANGE, std_get_range), /* factory mode used */ + IW_HANDLER(SIOCSIWPRIV, std_set_priv), + IW_HANDLER(SIOCGIWPRIV, std_get_priv), + IW_HANDLER(SIOCSIWAP, std_set_ap), + IW_HANDLER(SIOCGIWAP, std_get_ap), /* factory mode used */ + IW_HANDLER(SIOCSIWMLME, std_set_mlme), + IW_HANDLER(SIOCSIWSCAN, std_set_scan), /* factory mode used */ + IW_HANDLER(SIOCGIWSCAN, std_get_scan), /* factory mode used */ + IW_HANDLER(SIOCSIWESSID, std_set_essid), /* factory mode used */ + IW_HANDLER(SIOCGIWESSID, std_get_essid), /* factory mode used */ + IW_HANDLER(SIOCGIWRATE, std_get_rate), /* factory mode used */ + IW_HANDLER(SIOCSIWRTS, std_set_rts), + IW_HANDLER(SIOCGIWRTS, std_get_rts), /* factory mode used */ + IW_HANDLER(SIOCGIWFRAG, std_get_frag), /* factory mode used */ + IW_HANDLER(SIOCSIWTXPOW, std_set_txpow), + IW_HANDLER(SIOCGIWTXPOW, std_get_txpow), /* factory mode used */ + IW_HANDLER(SIOCSIWENCODE, std_set_encode), + IW_HANDLER(SIOCGIWENCODE, std_get_encode),/* factory mode used */ + IW_HANDLER(SIOCSIWPOWER, std_set_power), + IW_HANDLER(SIOCGIWPOWER, std_get_power), /* factory mode used */ + IW_HANDLER(SIOCSIWAUTH, std_set_auth), +#if (WIRELESS_EXT > 17) + IW_HANDLER(SIOCSIWGENIE, std_set_genie), +#endif + IW_HANDLER(SIOCSIWENCODEEXT, std_set_encode_ext), + IW_HANDLER(SIOCSIWPMKSA, std_set_pmska), +}; + +const struct iw_handler_def wext_handler_def = { + .num_standard = (__u16) sizeof(mtk_std_handler) / sizeof(iw_handler), +#ifdef CONFIG_WEXT_PRIV + .num_private = (__u16) sizeof(rIwPrivHandler) / sizeof(iw_handler), + .num_private_args = (__u16) sizeof(rIwPrivTable) / + sizeof(struct iw_priv_args), +#endif + .standard = (iw_handler *) mtk_std_handler, +#ifdef CONFIG_WEXT_PRIV + .private = rIwPrivHandler, + .private_args = rIwPrivTable, +#endif + .get_wireless_stats = wext_get_wireless_stats, +}; + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +static void wext_support_ioctl_SIOCSIWGENIE( + IN struct net_device *prDev, IN char *prExtraBuf, + IN uint32_t u4ExtraSize); + +static void +wext_support_ioctl_SIOCSIWPMKSA_Action(IN struct net_device + *prDev, IN char *prExtraBuf, IN int ioMode, OUT int *ret); + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +#if 0 /* not in use */ +void MAP_CHANNEL_ID_TO_KHZ(uint32_t ch, uint32_t khz) +{ + switch (ch) { + case 1: + khz = 2412000; + break; + case 2: + khz = 2417000; + break; + case 3: + khz = 2422000; + break; + case 4: + khz = 2427000; + break; + case 5: + khz = 2432000; + break; + case 6: + khz = 2437000; + break; + case 7: + khz = 2442000; + break; + case 8: + khz = 2447000; + break; + case 9: + khz = 2452000; + break; + case 10: + khz = 2457000; + break; + case 11: + khz = 2462000; + break; + case 12: + khz = 2467000; + break; + case 13: + khz = 2472000; + break; + case 14: + khz = 2484000; + break; + case 36: /* UNII */ + khz = 5180000; + break; + case 40: /* UNII */ + khz = 5200000; + break; + case 44: + khz = 5220000; + break; + case 48: + khz = 5240000; + break; + case 52: + khz = 5260000; + break; + case 56: + khz = 5280000; + break; + case 60: + khz = 5300000; + break; + case 64: + khz = 5320000; + break; + case 149: + khz = 5745000; + break; + case 153: + khz = 5765000; + break; + case 157: + khz = 5785000; + break; + case 161: /* UNII */ + khz = 5805000; + break; + case 165: /* UNII */ + khz = 5825000; + break; + case 100: /* HiperLAN2 */ + khz = 5500000; + break; + case 104: /* HiperLAN2 */ + khz = 5520000; + break; + case 108: /* HiperLAN2 */ + khz = 5540000; + break; + case 112: /* HiperLAN2 */ + khz = 5560000; + break; + case 116: /* HiperLAN2 */ + khz = 5580000; + break; + case 120: /* HiperLAN2 */ + khz = 5600000; + break; + case 124: /* HiperLAN2 */ + khz = 5620000; + break; + case 128: /* HiperLAN2 */ + khz = 5640000; + break; + case 132: /* HiperLAN2 */ + khz = 5660000; + break; + case 136: /* HiperLAN2 */ + khz = 5680000; + break; + case 140: /* HiperLAN2 */ + khz = 5700000; + break; + case 34: /* Japan MMAC */ + khz = 5170000; + break; + case 38: /* Japan MMAC */ + khz = 5190000; + break; + case 42: /* Japan MMAC */ + khz = 5210000; + break; + case 46: /* Japan MMAC */ + khz = 5230000; + break; + case 184: /* Japan */ + khz = 4920000; + break; + case 188: /* Japan */ + khz = 4940000; + break; + case 192: /* Japan */ + khz = 4960000; + break; + case 196: /* Japan */ + khz = 4980000; + break; + case 208: /* Japan, means J08 */ + khz = 5040000; + break; + case 212: /* Japan, means J12 */ + khz = 5060000; + break; + case 216: /* Japan, means J16 */ + khz = 5080000; + break; + default: + khz = 2412000; + break; + } +} +#endif +/*----------------------------------------------------------------------------*/ +/*! + * \brief Find the desired WPA/RSN Information Element according to + * desiredElemID. + * + * \param[in] pucIEStart IE starting address. + * \param[in] i4TotalIeLen Total length of all the IE. + * \param[in] ucDesiredElemId Desired element ID. + * \param[out] ppucDesiredIE Pointer to the desired IE. + * + * \retval TRUE Find the desired IE. + * \retval FALSE Desired IE not found. + * + * \note + */ +/*----------------------------------------------------------------------------*/ +u_int8_t +wextSrchDesiredWPAIE(IN uint8_t *pucIEStart, + IN int32_t i4TotalIeLen, IN uint8_t ucDesiredElemId, + OUT uint8_t **ppucDesiredIE) +{ + int32_t i4InfoElemLen; + + ASSERT(pucIEStart); + ASSERT(ppucDesiredIE); + + while (i4TotalIeLen >= 2) { + i4InfoElemLen = (int32_t) pucIEStart[1] + 2; + + if (pucIEStart[0] == ucDesiredElemId + && i4InfoElemLen <= i4TotalIeLen) { + if (ucDesiredElemId != 0xDD) { + /* Non 0xDD, OK! */ + *ppucDesiredIE = &pucIEStart[0]; + return TRUE; + } /* EID == 0xDD, check WPA IE */ + if (pucIEStart[1] >= 4) { + if (memcmp(&pucIEStart[2], "\x00\x50\xf2\x01", + 4) == 0) { + *ppucDesiredIE = &pucIEStart[0]; + return TRUE; + } + } /* check WPA IE length */ + /* check EID == 0xDD */ + } + + /* check desired EID */ + /* Select next information element. */ + i4TotalIeLen -= i4InfoElemLen; + pucIEStart += i4InfoElemLen; + } + + return FALSE; +} /* parseSearchDesiredWPAIE */ + +#if CFG_SUPPORT_WAPI +/*----------------------------------------------------------------------------*/ +/*! + * \brief Find the desired WAPI Information Element . + * + * \param[in] pucIEStart IE starting address. + * \param[in] i4TotalIeLen Total length of all the IE. + * \param[out] ppucDesiredIE Pointer to the desired IE. + * + * \retval TRUE Find the desired IE. + * \retval FALSE Desired IE not found. + * + * \note + */ +/*----------------------------------------------------------------------------*/ +u_int8_t wextSrchDesiredWAPIIE(IN uint8_t *pucIEStart, + IN int32_t i4TotalIeLen, OUT uint8_t **ppucDesiredIE) +{ + int32_t i4InfoElemLen; + + ASSERT(pucIEStart); + ASSERT(ppucDesiredIE); + + while (i4TotalIeLen >= 2) { + i4InfoElemLen = (int32_t) pucIEStart[1] + 2; + + if (pucIEStart[0] == ELEM_ID_WAPI + && i4InfoElemLen <= i4TotalIeLen) { + *ppucDesiredIE = &pucIEStart[0]; + return TRUE; + } + + /* check desired EID */ + /* Select next information element. */ + i4TotalIeLen -= i4InfoElemLen; + pucIEStart += i4InfoElemLen; + } + + return FALSE; +} /* wextSrchDesiredWAPIIE */ +#endif + +#if CFG_SUPPORT_PASSPOINT +/*----------------------------------------------------------------------------*/ +/*! + * \brief Check if exist the desired HS2.0 Information Element according to + * desiredElemID. + * + * \param[in] pucIEStart IE starting address. + * \param[in] i4TotalIeLen Total length of all the IE. + * \param[in] ucDesiredElemId Desired element ID. + * \param[out] ppucDesiredIE Pointer to the desired IE. + * + * \retval TRUE Find the desired IE. + * \retval FALSE Desired IE not found. + * + * \note + */ +/*----------------------------------------------------------------------------*/ +u_int8_t wextIsDesiredHS20IE(IN uint8_t *pucCurIE, + IN int32_t i4TotalIeLen) +{ + int32_t i4InfoElemLen; + + ASSERT(pucCurIE); + + i4InfoElemLen = (int32_t) pucCurIE[1] + 2; + + if (pucCurIE[0] == ELEM_ID_VENDOR + && i4InfoElemLen <= i4TotalIeLen) { + if (pucCurIE[1] >= ELEM_MIN_LEN_HS20_INDICATION) { + if (memcmp(&pucCurIE[2], "\x50\x6f\x9a\x10", 4) == 0) + return TRUE; + } + } + /* check desired EID */ + return FALSE; +} /* wextIsDesiredHS20IE */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Check if exist the desired interworking Information Element according + * to desiredElemID. + * + * \param[in] pucIEStart IE starting address. + * \param[in] i4TotalIeLen Total length of all the IE. + * \param[in] ucDesiredElemId Desired element ID. + * \param[out] ppucDesiredIE Pointer to the desired IE. + * + * \retval TRUE Find the desired IE. + * \retval FALSE Desired IE not found. + * + * \note + */ +/*----------------------------------------------------------------------------*/ +u_int8_t wextIsDesiredInterworkingIE(IN uint8_t *pucCurIE, + IN int32_t i4TotalIeLen) +{ + int32_t i4InfoElemLen; + + ASSERT(pucCurIE); + + i4InfoElemLen = (int32_t) pucCurIE[1] + 2; + + if (pucCurIE[0] == ELEM_ID_INTERWORKING + && i4InfoElemLen <= i4TotalIeLen) { + switch (pucCurIE[1]) { + case IW_IE_LENGTH_ANO: + case IW_IE_LENGTH_ANO_HESSID: + case IW_IE_LENGTH_ANO_VENUE: + case IW_IE_LENGTH_ANO_VENUE_HESSID: + return TRUE; + default: + break; + } + + } + /* check desired EID */ + return FALSE; +} /* wextIsDesiredInterworkingIE */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Check if exist the desired Adv Protocol Information Element according + * to desiredElemID. + * + * \param[in] pucIEStart IE starting address. + * \param[in] i4TotalIeLen Total length of all the IE. + * \param[in] ucDesiredElemId Desired element ID. + * \param[out] ppucDesiredIE Pointer to the desired IE. + * + * \retval TRUE Find the desired IE. + * \retval FALSE Desired IE not found. + * + * \note + */ +/*----------------------------------------------------------------------------*/ +u_int8_t wextIsDesiredAdvProtocolIE(IN uint8_t *pucCurIE, + IN int32_t i4TotalIeLen) +{ + int32_t i4InfoElemLen; + + ASSERT(pucCurIE); + + i4InfoElemLen = (int32_t) pucCurIE[1] + 2; + + if (pucCurIE[0] == ELEM_ID_ADVERTISEMENT_PROTOCOL + && i4InfoElemLen <= i4TotalIeLen) + return TRUE; + /* check desired EID */ + return FALSE; +} /* wextIsDesiredAdvProtocolIE */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Check if exist the desired Roaming Consortium Information Element + * according to desiredElemID. + * + * \param[in] pucIEStart IE starting address. + * \param[in] i4TotalIeLen Total length of all the IE. + * \param[in] ucDesiredElemId Desired element ID. + * \param[out] ppucDesiredIE Pointer to the desired IE. + * + * \retval TRUE Find the desired IE. + * \retval FALSE Desired IE not found. + * + * \note + */ +/*----------------------------------------------------------------------------*/ +u_int8_t wextIsDesiredRoamingConsortiumIE( + IN uint8_t *pucCurIE, IN int32_t i4TotalIeLen) +{ + int32_t i4InfoElemLen; + + ASSERT(pucCurIE); + + i4InfoElemLen = (int32_t) pucCurIE[1] + 2; + + if (pucCurIE[0] == ELEM_ID_ROAMING_CONSORTIUM + && i4InfoElemLen <= i4TotalIeLen) + return TRUE; + /* check desired EID */ + return FALSE; +} /* wextIsDesiredRoamingConsortiumIE */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Find the desired HS2.0 Information Element according to desiredElemID. + * + * \param[in] pucIEStart IE starting address. + * \param[in] i4TotalIeLen Total length of all the IE. + * \param[in] ucDesiredElemId Desired element ID. + * \param[out] ppucDesiredIE Pointer to the desired IE. + * + * \retval TRUE Find the desired IE. + * \retval FALSE Desired IE not found. + * + * \note + */ +/*----------------------------------------------------------------------------*/ +u_int8_t wextSrchDesiredHS20IE(IN uint8_t *pucIEStart, + IN int32_t i4TotalIeLen, OUT uint8_t **ppucDesiredIE) +{ + int32_t i4InfoElemLen; + + ASSERT(pucIEStart); + ASSERT(ppucDesiredIE); + + while (i4TotalIeLen >= 2) { + i4InfoElemLen = (int32_t) pucIEStart[1] + 2; + + if (pucIEStart[0] == ELEM_ID_VENDOR + && i4InfoElemLen <= i4TotalIeLen) { + if (pucIEStart[1] >= ELEM_MIN_LEN_HS20_INDICATION) { + if (memcmp(&pucIEStart[2], "\x50\x6f\x9a\x10", + 4) == 0) { + *ppucDesiredIE = &pucIEStart[0]; + return TRUE; + } + } + } + + /* check desired EID */ + /* Select next information element. */ + i4TotalIeLen -= i4InfoElemLen; + pucIEStart += i4InfoElemLen; + } + + return FALSE; +} /* wextSrchDesiredHS20IE */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Find the desired HS2.0 Information Element according to desiredElemID. + * + * \param[in] pucIEStart IE starting address. + * \param[in] i4TotalIeLen Total length of all the IE. + * \param[in] ucDesiredElemId Desired element ID. + * \param[out] ppucDesiredIE Pointer to the desired IE. + * + * \retval TRUE Find the desired IE. + * \retval FALSE Desired IE not found. + * + * \note + */ +/*----------------------------------------------------------------------------*/ +u_int8_t wextSrchDesiredOsenIE(IN uint8_t *pucIEStart, + IN int32_t i4TotalIeLen, OUT uint8_t **ppucDesiredIE) +{ + int32_t i4InfoElemLen; + + ASSERT(pucIEStart); + ASSERT(ppucDesiredIE); + + while (i4TotalIeLen >= 2) { + i4InfoElemLen = (int32_t) pucIEStart[1] + 2; + if (pucIEStart[0] == ELEM_ID_VENDOR + && i4InfoElemLen <= i4TotalIeLen) { + if (pucIEStart[1] >= 4) { + if (memcmp(&pucIEStart[2], "\x50\x6f\x9a\x12", + 4) == 0) { + *ppucDesiredIE = &pucIEStart[0]; + return TRUE; + } + } + } + + /* check desired EID */ + /* Select next information element. */ + i4TotalIeLen -= i4InfoElemLen; + pucIEStart += i4InfoElemLen; + } + + return FALSE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Find the desired Adv Protocol Information Element according to + * desiredElemID. + * + * \param[in] pucIEStart IE starting address. + * \param[in] i4TotalIeLen Total length of all the IE. + * \param[in] ucDesiredElemId Desired element ID. + * \param[out] ppucDesiredIE Pointer to the desired IE. + * + * \retval TRUE Find the desired IE. + * \retval FALSE Desired IE not found. + * + * \note + */ +/*----------------------------------------------------------------------------*/ +u_int8_t wextSrchDesiredAdvProtocolIE(IN uint8_t + *pucIEStart, IN int32_t i4TotalIeLen, + OUT uint8_t **ppucDesiredIE) +{ + int32_t i4InfoElemLen; + + ASSERT(pucIEStart); + ASSERT(ppucDesiredIE); + + while (i4TotalIeLen >= 2) { + i4InfoElemLen = (int32_t) pucIEStart[1] + 2; + + if (pucIEStart[0] == ELEM_ID_ADVERTISEMENT_PROTOCOL + && i4InfoElemLen <= i4TotalIeLen) { + *ppucDesiredIE = &pucIEStart[0]; + return TRUE; + } + + /* check desired EID */ + /* Select next information element. */ + i4TotalIeLen -= i4InfoElemLen; + pucIEStart += i4InfoElemLen; + } + + return FALSE; +} /* wextSrchDesiredAdvProtocolIE */ + +#endif /* CFG_SUPPORT_PASSPOINT */ + +#if CFG_SUPPORT_WPS +/*----------------------------------------------------------------------------*/ +/*! + * \brief Find the desired WPS Information Element according to desiredElemID. + * + * \param[in] pucIEStart IE starting address. + * \param[in] i4TotalIeLen Total length of all the IE. + * \param[in] ucDesiredElemId Desired element ID. + * \param[out] ppucDesiredIE Pointer to the desired IE. + * + * \retval TRUE Find the desired IE. + * \retval FALSE Desired IE not found. + * + * \note + */ +/*----------------------------------------------------------------------------*/ +u_int8_t +wextSrchDesiredWPSIE(IN uint8_t *pucIEStart, + IN int32_t i4TotalIeLen, IN uint8_t ucDesiredElemId, + OUT uint8_t **ppucDesiredIE) +{ + int32_t i4InfoElemLen; + + ASSERT(pucIEStart); + ASSERT(ppucDesiredIE); + + while (i4TotalIeLen >= 2) { + i4InfoElemLen = (int32_t) pucIEStart[1] + 2; + + if (pucIEStart[0] == ucDesiredElemId + && i4InfoElemLen <= i4TotalIeLen) { + if (ucDesiredElemId != 0xDD) { + /* Non 0xDD, OK! */ + *ppucDesiredIE = &pucIEStart[0]; + return TRUE; + } + /* EID == 0xDD, check WPS IE */ + if (pucIEStart[1] >= 4) { + if (memcmp(&pucIEStart[2], "\x00\x50\xf2\x04", + 4) == 0) { + *ppucDesiredIE = &pucIEStart[0]; + return TRUE; + } + } /* check WPS IE length */ + /* check EID == 0xDD */ + } + + /* check desired EID */ + /* Select next information element. */ + i4TotalIeLen -= i4InfoElemLen; + pucIEStart += i4InfoElemLen; + } + + return FALSE; +} /* parseSearchDesiredWPSIE */ +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Get the name of the protocol used on the air. + * + * \param[in] prDev Net device requested. + * \param[in] prIwrInfo NULL. + * \param[out] pcName Buffer to store protocol name string + * \param[in] pcExtra NULL. + * + * \retval 0 For success. + * + * \note If netif_carrier_ok, protocol name is returned; + * otherwise, "disconnected" is returned. + */ +/*----------------------------------------------------------------------------*/ +static int +wext_get_name(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwrInfo, + OUT char *pcName, IN uint32_t pcNameSize, IN char *pcExtra) +{ + enum ENUM_PARAM_NETWORK_TYPE eNetWorkType; + + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + + ASSERT(prNetDev); + ASSERT(pcName); + if (GLUE_CHK_PR2(prNetDev, pcName) == FALSE) + return -EINVAL; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + if (netif_carrier_ok(prNetDev)) { + + rStatus = kalIoctl(prGlueInfo, wlanoidQueryNetworkTypeInUse, + &eNetWorkType, sizeof(eNetWorkType), + TRUE, FALSE, FALSE, &u4BufLen); + + switch (eNetWorkType) { + case PARAM_NETWORK_TYPE_DS: + strncpy(pcName, "IEEE 802.11b", pcNameSize); + break; + case PARAM_NETWORK_TYPE_OFDM24: + strncpy(pcName, "IEEE 802.11bgn", pcNameSize); + break; + case PARAM_NETWORK_TYPE_AUTOMODE: + case PARAM_NETWORK_TYPE_OFDM5: + strncpy(pcName, "IEEE 802.11abgn", pcNameSize); + break; + case PARAM_NETWORK_TYPE_FH: + default: + strncpy(pcName, "IEEE 802.11", pcNameSize); + break; + } + } else { + strncpy(pcName, "Disconnected", pcNameSize); + } + + pcName[pcNameSize - 1] = '\0'; + + return 0; +} /* wext_get_name */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief To set the operating channel in the wireless device. + * + * \param[in] prDev Net device requested. + * \param[in] prIwrInfo NULL + * \param[in] prFreq Buffer to store frequency information + * \param[in] pcExtra NULL + * + * \retval 0 For success. + * \retval -EOPNOTSUPP If infrastructure mode is not NET NET_TYPE_IBSS. + * \retval -EINVAL Invalid channel frequency. + * + * \note If infrastructure mode is IBSS, new channel frequency is set to device. + * The range of channel number depends on different regulatory domain. + */ +/*----------------------------------------------------------------------------*/ +static int +wext_set_freq(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN struct iw_freq *prIwFreq, IN char *pcExtra) +{ + +#if 0 + uint32_t u4ChnlFreq; /* Store channel or frequency information */ + + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + + ASSERT(prNetDev); + ASSERT(prIwFreq); + if (GLUE_CHK_PR2(prNetDev, prIwFreq) == FALSE) + return -EINVAL; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + /* + * printk("set m:%d, e:%d, i:%d, flags:%d\n", + * prIwFreq->m, prIwFreq->e, prIwFreq->i, prIwFreq->flags); + */ + + /* If setting by frequency, convert to a channel */ + if ((prIwFreq->e == 1) && (prIwFreq->m >= 2.412e8) + && (prIwFreq->m <= 2.484e8)) { + + /* Change to KHz format */ + u4ChnlFreq = (uint32_t) (prIwFreq->m / (KILO / 10)); + + rStatus = kalIoctl(prGlueInfo, wlanoidSetFrequency, &u4ChnlFreq, + sizeof(u4ChnlFreq), + FALSE, FALSE, FALSE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) + return -EINVAL; + } + /* Setting by channel number */ + else if ((prIwFreq->m > KILO) || (prIwFreq->e > 0)) + return -EOPNOTSUPP; + /* Change to channel number format */ + u4ChnlFreq = (uint32_t) prIwFreq->m; + + rStatus = kalIoctl(prGlueInfo, wlanoidSetChannel, &u4ChnlFreq, + sizeof(u4ChnlFreq), FALSE, FALSE, FALSE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) + return -EINVAL; + +#endif + + return 0; + +} /* wext_set_freq */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief To get the operating channel in the wireless device. + * + * \param[in] prDev Net device requested. + * \param[in] prIwrInfo NULL. + * \param[out] prFreq Buffer to store frequency information. + * \param[in] pcExtra NULL. + * + * \retval 0 If netif_carrier_ok. + * \retval -ENOTCONN Otherwise + * + * \note If netif_carrier_ok, channel frequency information is stored in pFreq. + */ +/*----------------------------------------------------------------------------*/ +static int +wext_get_freq(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwrInfo, + OUT struct iw_freq *prIwFreq, IN char *pcExtra) +{ + uint32_t u4Channel = 0; + + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + + ASSERT(prNetDev); + ASSERT(prIwFreq); + if (GLUE_CHK_PR2(prNetDev, prIwFreq) == FALSE) + return -EINVAL; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + /* GeorgeKuo: TODO skip checking in IBSS mode */ + if (!netif_carrier_ok(prNetDev)) + return -ENOTCONN; + + rStatus = kalIoctl(prGlueInfo, wlanoidQueryFrequency, &u4Channel, + sizeof(u4Channel), TRUE, FALSE, FALSE, &u4BufLen); + + prIwFreq->m = (int)u4Channel; /* freq in KHz */ + prIwFreq->e = 3; + + return 0; + +} /* wext_get_freq */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief To set operating mode. + * + * \param[in] prDev Net device requested. + * \param[in] prIwrInfo NULL. + * \param[in] pu4Mode Pointer to new operation mode. + * \param[in] pcExtra NULL. + * + * \retval 0 For success. + * \retval -EOPNOTSUPP If new mode is not supported. + * + * \note Device will run in new operation mode if it is valid. + */ +/*----------------------------------------------------------------------------*/ +static int +wext_set_mode(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN unsigned int *pu4Mode, IN char *pcExtra) +{ + struct PARAM_OP_MODE rOpMode; + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + struct GL_WPA_INFO *prWpaInfo; + uint8_t ucBssIndex = AIS_DEFAULT_INDEX; + + ASSERT(prNetDev); + ASSERT(pu4Mode); + if (GLUE_CHK_PR2(prNetDev, pu4Mode) == FALSE) + return -EINVAL; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + switch (*pu4Mode) { + case IW_MODE_AUTO: + rOpMode.eOpMode = NET_TYPE_AUTO_SWITCH; + break; + + case IW_MODE_ADHOC: + rOpMode.eOpMode = NET_TYPE_IBSS; + break; + + case IW_MODE_INFRA: + rOpMode.eOpMode = NET_TYPE_INFRA; + break; + + default: + DBGLOG(INIT, INFO, "%s(): Set UNSUPPORTED Mode = %d.\n", + __func__, *pu4Mode); + return -EOPNOTSUPP; + } + + /* printk("%s(): Set Mode = %d\n", __FUNCTION__, *pu4Mode); */ + rOpMode.ucBssIdx = ucBssIndex; + rStatus = kalIoctl(prGlueInfo, wlanoidSetInfrastructureMode, + (void *)&rOpMode, sizeof(struct PARAM_OP_MODE), + FALSE, FALSE, TRUE, &u4BufLen); + + /* after set operation mode, key table are cleared */ + + prWpaInfo = aisGetWpaInfo(prGlueInfo->prAdapter, + ucBssIndex); + + /* reset wpa info */ + prWpaInfo->u4WpaVersion = + IW_AUTH_WPA_VERSION_DISABLED; + prWpaInfo->u4KeyMgmt = 0; + prWpaInfo->u4CipherGroup = IW_AUTH_CIPHER_NONE; + prWpaInfo->u4CipherPairwise = IW_AUTH_CIPHER_NONE; + prWpaInfo->u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM; +#if CFG_SUPPORT_802_11W + prWpaInfo->u4Mfp = IW_AUTH_MFP_DISABLED; +#endif + + return 0; +} /* wext_set_mode */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief To get operating mode. + * + * \param[in] prNetDev Net device requested. + * \param[in] prIwReqInfo NULL. + * \param[out] pu4Mode Buffer to store operating mode information. + * \param[in] pcExtra NULL. + * + * \retval 0 If data is valid. + * \retval -EINVAL Otherwise. + * + * \note If netif_carrier_ok, operating mode information is stored in pu4Mode. + */ +/*----------------------------------------------------------------------------*/ +static int +wext_get_mode(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + OUT unsigned int *pu4Mode, IN char *pcExtra) +{ + enum ENUM_PARAM_OP_MODE eOpMode; + + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + + ASSERT(prNetDev); + ASSERT(pu4Mode); + if (GLUE_CHK_PR2(prNetDev, pu4Mode) == FALSE) + return -EINVAL; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + rStatus = kalIoctl(prGlueInfo, wlanoidQueryInfrastructureMode, &eOpMode, + sizeof(eOpMode), TRUE, FALSE, FALSE, &u4BufLen); + + switch (eOpMode) { + case NET_TYPE_IBSS: + *pu4Mode = IW_MODE_ADHOC; + break; + + case NET_TYPE_INFRA: + *pu4Mode = IW_MODE_INFRA; + break; + + case NET_TYPE_AUTO_SWITCH: + *pu4Mode = IW_MODE_AUTO; + break; + + default: + DBGLOG(INIT, INFO, "%s(): Get UNKNOWN Mode.\n", __func__); + return -EINVAL; + } + + return 0; +} /* wext_get_mode */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief To get the valid range for each configurable STA setting value. + * + * \param[in] prDev Net device requested. + * \param[in] prIwrInfo NULL. + * \param[in] prData Pointer to iw_point structure, not used. + * \param[out] pcExtra Pointer to buffer which is allocated by caller of this + * function, wext_support_ioctl() or ioctl_standard_call() + * in wireless.c. + * + * \retval 0 If data is valid. + * + * \note The extra buffer (pcExtra) is filled with information from driver. + */ +/*----------------------------------------------------------------------------*/ +static int +wext_get_range(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwrInfo, + IN struct iw_point *prData, OUT char *pcExtra) +{ + struct iw_range *prRange = NULL; + uint8_t aucSuppRate[PARAM_MAX_LEN_RATES_EX] = { 0 }; /* data buffers */ + int i = 0; + + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + + ASSERT(prNetDev); + ASSERT(pcExtra); + if (GLUE_CHK_PR2(prNetDev, pcExtra) == FALSE) + return -EINVAL; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + prRange = (struct iw_range *)pcExtra; + + memset(prRange, 0, sizeof(*prRange)); + prRange->throughput = 20000000; /* 20Mbps */ + prRange->min_nwid = 0; /* not used */ + prRange->max_nwid = 0; /* not used */ + + /* scan_capa not implemented */ + + /* event_capa[6]: kernel + driver capabilities */ + prRange->event_capa[0] = + (IW_EVENT_CAPA_K_0 + | IW_EVENT_CAPA_MASK(SIOCGIWAP) + | IW_EVENT_CAPA_MASK(SIOCGIWSCAN) + /* can't display meaningful string in iwlist + * | IW_EVENT_CAPA_MASK(SIOCGIWTXPOW) + * | IW_EVENT_CAPA_MASK(IWEVMICHAELMICFAILURE) + * | IW_EVENT_CAPA_MASK(IWEVASSOCREQIE) + * | IW_EVENT_CAPA_MASK(IWEVPMKIDCAND) + */ + ); + prRange->event_capa[1] = IW_EVENT_CAPA_K_1; + + /* report 2.4G channel and frequency only */ + prRange->num_channels = (__u16) NUM_CHANNELS; + prRange->num_frequency = (__u8) NUM_CHANNELS; + for (i = 0; i < NUM_CHANNELS; i++) { + /* iwlib takes this number as channel number */ + prRange->freq[i].i = i + 1; + prRange->freq[i].m = channel_freq[i]; + prRange->freq[i].e = 6; /* Values in table in MHz */ + } + + rStatus = kalIoctl(prGlueInfo, + wlanoidQuerySupportedRates, + &aucSuppRate, sizeof(aucSuppRate), + TRUE, FALSE, FALSE, &u4BufLen); + + for (i = 0; i < IW_MAX_BITRATES + && i < PARAM_MAX_LEN_RATES_EX; i++) { + if (aucSuppRate[i] == 0) + break; + prRange->bitrate[i] = (aucSuppRate[i] & 0x7F) * + 500000; /* 0.5Mbps */ + } + prRange->num_bitrates = i; + + prRange->min_rts = 0; + prRange->max_rts = 2347; + prRange->min_frag = 256; + prRange->max_frag = 2346; + + prRange->min_pmp = 0; /* power management by driver */ + prRange->max_pmp = 0; /* power management by driver */ + prRange->min_pmt = 0; /* power management by driver */ + prRange->max_pmt = 0; /* power management by driver */ + prRange->pmp_flags = + IW_POWER_RELATIVE; /* pm default flag */ + prRange->pmt_flags = IW_POWER_ON; /* pm timeout flag */ + prRange->pm_capa = + IW_POWER_ON; /* power management by driver */ + + prRange->encoding_size[0] = 5; /* wep40 */ + prRange->encoding_size[1] = 16; /* tkip */ + prRange->encoding_size[2] = 16; /* ckip */ + prRange->encoding_size[3] = 16; /* ccmp */ + prRange->encoding_size[4] = 13; /* wep104 */ + prRange->encoding_size[5] = 16; /* wep128 */ + prRange->num_encoding_sizes = 6; + prRange->max_encoding_tokens = 6; /* token? */ + +#if WIRELESS_EXT < 17 + prRange->txpower_capa = 0x0002; /* IW_TXPOW_RELATIVE */ +#else + prRange->txpower_capa = IW_TXPOW_RELATIVE; +#endif + prRange->num_txpower = 5; + prRange->txpower[0] = 0; /* minimum */ + prRange->txpower[1] = 25; /* 25% */ + prRange->txpower[2] = 50; /* 50% */ + prRange->txpower[3] = 100; /* 100% */ + + prRange->we_version_compiled = WIRELESS_EXT; + prRange->we_version_source = WIRELESS_EXT; + + prRange->retry_capa = IW_RETRY_LIMIT; + prRange->retry_flags = IW_RETRY_LIMIT; + prRange->min_retry = 7; + prRange->max_retry = 7; + prRange->r_time_flags = IW_RETRY_ON; + prRange->min_r_time = 0; + prRange->max_r_time = 0; + + /* signal strength and link quality */ + /* Just define range here, reporting value moved to wext_get_stats() */ + prRange->sensitivity = -83; /* fixed value */ + prRange->max_qual.qual = 100; /* max 100% */ + prRange->max_qual.level = (__u8) (0x100 - + 0); /* max 0 dbm */ + prRange->max_qual.noise = (__u8) (0x100 - + 0); /* max 0 dbm */ + + /* enc_capa */ +#if WIRELESS_EXT > 17 + prRange->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | + IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; +#endif + + /* min_pms; Minimal PM saving */ + /* max_pms; Maximal PM saving */ + /* pms_flags; How to decode max/min PM saving */ + + /* modul_capa; IW_MODUL_* bit field */ + /* bitrate_capa; Types of bitrates supported */ + + return 0; +} /* wext_get_range */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief To set BSSID of AP to connect. + * + * \param[in] prDev Net device requested. + * \param[in] prIwrInfo NULL. + * \param[in] prAddr Pointer to struct sockaddr structure containing AP's BSSID. + * \param[in] pcExtra NULL. + * + * \retval 0 For success. + * + * \note Desired AP's BSSID is set to driver. + */ +/*----------------------------------------------------------------------------*/ +static int +wext_set_ap(IN struct net_device *prDev, + IN struct iw_request_info *prIwrInfo, + IN struct sockaddr *prAddr, IN char *pcExtra) +{ + return 0; +} /* wext_set_ap */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief To get AP MAC address. + * + * \param[in] prDev Net device requested. + * \param[in] prIwrInfo NULL. + * \param[out] prAddr Pointer to struct sockaddr structure storing AP's BSSID. + * \param[in] pcExtra NULL. + * + * \retval 0 If netif_carrier_ok. + * \retval -ENOTCONN Otherwise. + * + * \note If netif_carrier_ok, AP's mac address is stored in pAddr->sa_data. + */ +/*----------------------------------------------------------------------------*/ +static int +wext_get_ap(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwrInfo, + OUT struct sockaddr *prAddr, IN char *pcExtra) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + uint8_t ucBssIndex = AIS_DEFAULT_INDEX; + + ASSERT(prNetDev); + ASSERT(prAddr); + if (GLUE_CHK_PR2(prNetDev, prAddr) == FALSE) + return -EINVAL; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + /* if (!netif_carrier_ok(prNetDev)) { */ + /* return -ENOTCONN; */ + /* } */ + + if (kalGetMediaStateIndicated(prGlueInfo, + ucBssIndex) == + MEDIA_STATE_DISCONNECTED) { + memset(prAddr, 0, sizeof(struct sockaddr)); + return 0; + } + + rStatus = kalIoctl(prGlueInfo, wlanoidQueryBssid, prAddr->sa_data, + ETH_ALEN, TRUE, FALSE, FALSE, &u4BufLen); + + return 0; +} /* wext_get_ap */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief To set mlme operation request. + * + * \param[in] prDev Net device requested. + * \param[in] prIwrInfo NULL. + * \param[in] prData Pointer of iw_point header. + * \param[in] pcExtra Pointer to iw_mlme structure mlme request information. + * + * \retval 0 For success. + * \retval -EOPNOTSUPP unsupported IW_MLME_ command. + * \retval -EINVAL Set MLME Fail, different bssid. + * + * \note Driver will start mlme operation if valid. + */ +/*----------------------------------------------------------------------------*/ +static int +wext_set_mlme(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwrInfo, + IN struct iw_point *prData, IN char *pcExtra) +{ + struct iw_mlme *prMlme = NULL; + + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + + ASSERT(prNetDev); + ASSERT(pcExtra); + if (GLUE_CHK_PR2(prNetDev, pcExtra) == FALSE) + return -EINVAL; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + prMlme = (struct iw_mlme *)pcExtra; + if (prMlme->cmd == IW_MLME_DEAUTH + || prMlme->cmd == IW_MLME_DISASSOC) { + if (!netif_carrier_ok(prNetDev)) { + DBGLOG(INIT, INFO, + "[wifi] Set MLME Deauth/Disassoc, but netif_carrier_off\n"); + return 0; + } + + rStatus = kalIoctl(prGlueInfo, wlanoidSetDisassociate, NULL, + 0, FALSE, FALSE, TRUE, &u4BufLen); + return 0; + } + DBGLOG(INIT, INFO, + "[wifi] unsupported IW_MLME_ command :%d\n", prMlme->cmd); + return -EOPNOTSUPP; +} /* wext_set_mlme */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief To issue scan request. + * + * \param[in] prDev Net device requested. + * \param[in] prIwrInfo NULL. + * \param[in] prData NULL. + * \param[in] pcExtra NULL. + * + * \retval 0 For success. + * \retval -EFAULT Tx power is off. + * + * \note Device will start scanning. + */ +/*----------------------------------------------------------------------------*/ +static int +wext_set_scan(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwrInfo, + IN union iwreq_data *prData, IN char *pcExtra) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + int essid_len = 0; + + ASSERT(prNetDev); + if (GLUE_CHK_DEV(prNetDev) == FALSE) + return -EINVAL; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + +#if WIRELESS_EXT > 17 + /* retrieve SSID */ + if (prData) + essid_len = ((struct iw_scan_req *)(((struct iw_point *) + prData)->pointer))->essid_len; +#endif + + init_completion(&prGlueInfo->rScanComp); + + /* TODO: parse flags and issue different scan requests? */ + + rStatus = kalIoctl(prGlueInfo, wlanoidSetBssidListScan, + pcExtra, essid_len, FALSE, FALSE, FALSE, &u4BufLen); + + /* wait_for_completion_interruptible_timeout(&prGlueInfo->rScanComp, + * 2 * KAL_HZ); + */ + /* kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_SCAN_COMPLETE, + * NULL, 0); + */ + + return 0; +} /* wext_set_scan */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief To write the ie to buffer + * + */ +/*----------------------------------------------------------------------------*/ +static inline int snprintf_hex(char *buf, size_t buf_size, + const u8 *data, size_t len) +{ + size_t i; + char *pos = buf, *end = buf + buf_size; + int ret; + + if (buf_size == 0) + return 0; + + for (i = 0; i < len; i++) { + ret = snprintf(pos, end - pos, "%02x", data[i]); + if (ret < 0 || ret >= end - pos) { + end[-1] = '\0'; + return pos - buf; + } + pos += ret; + } + end[-1] = '\0'; + return pos - buf; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief To get scan results, transform results from driver's format to WE's. + * + * \param[in] prDev Net device requested. + * \param[in] prIwrInfo NULL. + * \param[out] prData Pointer to iw_point structure, pData->length is the size + * of pcExtra buffer before used, and is updated after filling + * scan results. + * \param[out] pcExtra Pointer to buffer which is allocated by caller of this + * function, wext_support_ioctl() or ioctl_standard_call() + * in wireless.c. + * + * \retval 0 For success. + * \retval -ENOMEM If dynamic memory allocation fail. + * \retval -E2BIG Invalid length. + * + * \note Scan results is filled into pcExtra buffer, data size is updated in + * pData->length. + */ +/*----------------------------------------------------------------------------*/ +static int +wext_get_scan(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwrInfo, + IN OUT struct iw_point *prData, IN char *pcExtra) +{ + uint32_t i = 0; + uint32_t j = 0; + struct PARAM_BSSID_LIST_EX *prList = NULL; + struct PARAM_BSSID_EX *prBss = NULL; + struct PARAM_VARIABLE_IE *prDesiredIE = NULL; + struct iw_event iwEvent; /* local iw_event buffer */ + + /* write pointer of extra buffer */ + char *pcCur = NULL; + /* pointer to the end of last full entry in extra buffer */ + char *pcValidEntryEnd = NULL; + char *pcEnd = NULL; /* end of extra buffer */ + + uint32_t u4AllocBufLen = 0; + + /* arrange rate information */ + uint32_t u4HighestRate = 0; + char aucRatesBuf[64]; + uint32_t u4BufIndex; + + /* return value */ + int ret = 0; + + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + + ASSERT(prNetDev); + ASSERT(prData); + ASSERT(pcExtra); + if (GLUE_CHK_PR3(prNetDev, prData, pcExtra) == FALSE) + return -EINVAL; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + /* Initialize local variables */ + pcCur = pcExtra; + pcValidEntryEnd = pcExtra; + pcEnd = pcExtra + prData->length; /* end of extra buffer */ + + /* Allocate another query buffer with the same size of extra buffer */ + u4AllocBufLen = prData->length; + prList = kalMemAlloc(u4AllocBufLen, VIR_MEM_TYPE); + if (prList == NULL) { + DBGLOG(INIT, INFO, "[wifi] no memory for scan list:%d\n", + prData->length); + ret = -ENOMEM; + goto error; + } + prList->u4NumberOfItems = 0; + + /* wait scan done */ + /* printk ("wait for scan results\n"); */ + /* wait_for_completion_interruptible_timeout(&prGlueInfo->rScanComp, + * 4 * KAL_HZ); + */ + + rStatus = kalIoctl(prGlueInfo, wlanoidQueryBssidList, prList, + u4AllocBufLen, TRUE, FALSE, FALSE, &u4BufLen); + + if (rStatus == WLAN_STATUS_INVALID_LENGTH) { + /* Buffer length is not large enough. */ + /* printk(KERN_INFO "[wifi] buf:%d result:%d\n", + * pData->length, u4BufLen); + */ + +#if WIRELESS_EXT >= 17 + /* This feature is supported in WE-17 or above, limited by + * iwlist. + * Return -E2BIG and iwlist will request again with a larger + * buffer. + */ + ret = -E2BIG; + /* Update length to give application a hint on result length */ + prData->length = (__u16) u4BufLen; + goto error; +#else + /* Realloc a larger query buffer here, but don't write too + * much to extra buffer when filling it later. + */ + kalMemFree(prList, VIR_MEM_TYPE, u4AllocBufLen); + + u4AllocBufLen = u4BufLen; + prList = kalMemAlloc(u4AllocBufLen, VIR_MEM_TYPE); + if (prList == NULL) { + DBGLOG(INIT, INFO, + "[wifi] no memory for larger scan list :%d\n", + u4BufLen); + ret = -ENOMEM; + goto error; + } + prList->NumberOfItems = 0; + + rStatus = kalIoctl(prGlueInfo, wlanoidQueryBssidList, prList, + u4AllocBufLen, + TRUE, FALSE, FALSE, &u4BufLen); + + if (rStatus == WLAN_STATUS_INVALID_LENGTH) { + DBGLOG(INIT, INFO, "[wifi] larger buf:%d result:%d\n", + u4AllocBufLen, u4BufLen); + ret = -E2BIG; + prData->length = (__u16) u4BufLen; + goto error; + } +#endif /* WIRELESS_EXT >= 17 */ + + } + + if (prList->u4NumberOfItems > CFG_MAX_NUM_BSS_LIST) { + DBGLOG(INIT, INFO, "[wifi] strange scan result count:%d\n", + prList->u4NumberOfItems); + goto error; + } + + /* Copy required data from pList to pcExtra */ + prBss = &prList->arBssid[0]; /* set to the first entry */ + for (i = 0; i < prList->u4NumberOfItems; ++i) { + /* BSSID */ + iwEvent.cmd = SIOCGIWAP; + iwEvent.len = IW_EV_ADDR_LEN; + if ((pcCur + iwEvent.len) > pcEnd) + break; + iwEvent.u.ap_addr.sa_family = ARPHRD_ETHER; + kalMemCopy(iwEvent.u.ap_addr.sa_data, prBss->arMacAddress, + ETH_ALEN); + memcpy(pcCur, &iwEvent, IW_EV_ADDR_LEN); + pcCur += IW_EV_ADDR_LEN; + + /* SSID */ + iwEvent.cmd = SIOCGIWESSID; + /* Modification to user space pointer(essid.pointer) is not + * needed. + */ + iwEvent.u.essid.length = (__u16) prBss->rSsid.u4SsidLen; + iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.essid.length; + + if ((pcCur + iwEvent.len) > pcEnd) + break; + iwEvent.u.essid.flags = 1; + iwEvent.u.essid.pointer = NULL; + +#if WIRELESS_EXT <= 18 + memcpy(pcCur, &iwEvent, iwEvent.len); +#else + memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); + memcpy(pcCur + IW_EV_LCP_LEN, &iwEvent.u.data.length, + sizeof(struct iw_point) - IW_EV_POINT_OFF); +#endif + memcpy(pcCur + IW_EV_POINT_LEN, prBss->rSsid.aucSsid, + iwEvent.u.essid.length); + pcCur += iwEvent.len; + /* Frequency */ + iwEvent.cmd = SIOCGIWFREQ; + iwEvent.len = IW_EV_FREQ_LEN; + if ((pcCur + iwEvent.len) > pcEnd) + break; + iwEvent.u.freq.m = prBss->rConfiguration.u4DSConfig; + iwEvent.u.freq.e = 3; /* (in KHz) */ + iwEvent.u.freq.i = 0; + memcpy(pcCur, &iwEvent, IW_EV_FREQ_LEN); + pcCur += IW_EV_FREQ_LEN; + + /* Operation Mode */ + iwEvent.cmd = SIOCGIWMODE; + iwEvent.len = IW_EV_UINT_LEN; + if ((pcCur + iwEvent.len) > pcEnd) + break; + if (prBss->eOpMode == NET_TYPE_IBSS) + iwEvent.u.mode = IW_MODE_ADHOC; + else if (prBss->eOpMode == NET_TYPE_INFRA) + iwEvent.u.mode = IW_MODE_INFRA; + else + iwEvent.u.mode = IW_MODE_AUTO; + memcpy(pcCur, &iwEvent, IW_EV_UINT_LEN); + pcCur += IW_EV_UINT_LEN; + + /* Quality */ + iwEvent.cmd = IWEVQUAL; + iwEvent.len = IW_EV_QUAL_LEN; + if ((pcCur + iwEvent.len) > pcEnd) + break; + iwEvent.u.qual.qual = 0; /* Quality not available now */ + /* -100 < Rssi < -10, normalized by adding 0x100 */ + iwEvent.u.qual.level = 0x100 + prBss->rRssi; + iwEvent.u.qual.noise = 0; /* Noise not available now */ + iwEvent.u.qual.updated = IW_QUAL_QUAL_INVALID | + IW_QUAL_LEVEL_UPDATED | + IW_QUAL_NOISE_INVALID; + memcpy(pcCur, &iwEvent, IW_EV_QUAL_LEN); + pcCur += IW_EV_QUAL_LEN; + + /* Security Mode */ + iwEvent.cmd = SIOCGIWENCODE; + iwEvent.len = IW_EV_POINT_LEN; + if ((pcCur + iwEvent.len) > pcEnd) + break; + iwEvent.u.data.pointer = NULL; + iwEvent.u.data.flags = 0; + iwEvent.u.data.length = 0; + if (!prBss->u4Privacy) + iwEvent.u.data.flags |= IW_ENCODE_DISABLED; +#if WIRELESS_EXT <= 18 + memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN); +#else + memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); + memcpy(pcCur + IW_EV_LCP_LEN, &iwEvent.u.data.length, + sizeof(struct iw_point) - IW_EV_POINT_OFF); +#endif + pcCur += IW_EV_POINT_LEN; + + /* rearrange rate information */ + u4BufIndex = snprintf(aucRatesBuf, sizeof(aucRatesBuf), + "Rates (Mb/s):"); + u4HighestRate = 0; + for (j = 0; j < PARAM_MAX_LEN_RATES_EX; ++j) { + uint8_t curRate = prBss->rSupportedRates[j] & 0x7F; + + if (curRate == 0) + break; + + if (curRate > u4HighestRate) + u4HighestRate = curRate; + + if (curRate == RATE_5_5M) + u4BufIndex += snprintf(aucRatesBuf + u4BufIndex, + sizeof(aucRatesBuf) + - u4BufIndex, " 5.5"); + else + u4BufIndex += snprintf(aucRatesBuf + u4BufIndex, + sizeof(aucRatesBuf) + - u4BufIndex, " %d", + curRate / 2); +#if DBG + if (u4BufIndex > sizeof(aucRatesBuf)) { + /* printk("rate info too long\n"); */ + break; + } +#endif + } + /* Report Highest Rates */ + iwEvent.cmd = SIOCGIWRATE; + iwEvent.len = IW_EV_PARAM_LEN; + if ((pcCur + iwEvent.len) > pcEnd) + break; + iwEvent.u.bitrate.value = u4HighestRate * 500000; + iwEvent.u.bitrate.fixed = 0; + iwEvent.u.bitrate.disabled = 0; + iwEvent.u.bitrate.flags = 0; + memcpy(pcCur, &iwEvent, iwEvent.len); + pcCur += iwEvent.len; + +#if WIRELESS_EXT >= 15 /* IWEVCUSTOM is available in WE-15 or above */ + /* Report Residual Rates */ + iwEvent.cmd = IWEVCUSTOM; + iwEvent.u.data.length = u4BufIndex; + iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length; + if ((pcCur + iwEvent.len) > pcEnd) + break; + iwEvent.u.data.flags = 0; +#if WIRELESS_EXT <= 18 + memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN); +#else + memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); + memcpy(pcCur + IW_EV_LCP_LEN, &iwEvent.u.data.length, + sizeof(struct iw_point) - IW_EV_POINT_OFF); +#endif + memcpy(pcCur + IW_EV_POINT_LEN, aucRatesBuf, u4BufIndex); + pcCur += iwEvent.len; +#endif /* WIRELESS_EXT >= 15 */ + + if (wextSrchDesiredWPAIE(&prBss->aucIEs[sizeof( + struct PARAM_FIXED_IEs)], + prBss->u4IELength - sizeof(struct PARAM_FIXED_IEs), 0xDD, + (uint8_t **) &prDesiredIE)) { + iwEvent.cmd = IWEVGENIE; + iwEvent.u.data.flags = 1; + iwEvent.u.data.length = 2 + + (__u16) prDesiredIE->ucLength; + iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length; + if ((pcCur + iwEvent.len) > pcEnd) + break; +#if WIRELESS_EXT <= 18 + memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN); +#else + memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); + memcpy(pcCur + IW_EV_LCP_LEN, + &iwEvent.u.data.length, + sizeof(struct iw_point) - IW_EV_POINT_OFF); +#endif + memcpy(pcCur + IW_EV_POINT_LEN, prDesiredIE, + 2 + prDesiredIE->ucLength); + pcCur += iwEvent.len; + } +#if CFG_SUPPORT_WPS /* search WPS IE (0xDD, 221, OUI: 0x0050f204) */ + if (wextSrchDesiredWPSIE(&prBss->aucIEs[sizeof( + struct PARAM_FIXED_IEs)], + prBss->u4IELength - sizeof(struct PARAM_FIXED_IEs), 0xDD, + (uint8_t **) &prDesiredIE)) { + iwEvent.cmd = IWEVGENIE; + iwEvent.u.data.flags = 1; + iwEvent.u.data.length = 2 + + (__u16) prDesiredIE->ucLength; + iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length; + if ((pcCur + iwEvent.len) > pcEnd) + break; +#if WIRELESS_EXT <= 18 + memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN); +#else + memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); + memcpy(pcCur + IW_EV_LCP_LEN, + &iwEvent.u.data.length, + sizeof(struct iw_point) - IW_EV_POINT_OFF); +#endif + memcpy(pcCur + IW_EV_POINT_LEN, prDesiredIE, + 2 + prDesiredIE->ucLength); + pcCur += iwEvent.len; + } +#endif + + /* Search RSN IE (0x30, 48). pBss->IEs starts from timestamp. */ + /* pBss->IEs starts from timestamp */ + if (wextSrchDesiredWPAIE(&prBss->aucIEs[sizeof( + struct PARAM_FIXED_IEs)], + prBss->u4IELength - sizeof(struct PARAM_FIXED_IEs), 0x30, + (uint8_t **) &prDesiredIE)) { + + iwEvent.cmd = IWEVGENIE; + iwEvent.u.data.flags = 1; + iwEvent.u.data.length = 2 + + (__u16) prDesiredIE->ucLength; + iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length; + if ((pcCur + iwEvent.len) > pcEnd) + break; +#if WIRELESS_EXT <= 18 + memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN); +#else + memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); + memcpy(pcCur + IW_EV_LCP_LEN, + &iwEvent.u.data.length, + sizeof(struct iw_point) - IW_EV_POINT_OFF); +#endif + memcpy(pcCur + IW_EV_POINT_LEN, prDesiredIE, + 2 + prDesiredIE->ucLength); + pcCur += iwEvent.len; + } +#if CFG_SUPPORT_WAPI /* Android+ */ + if (wextSrchDesiredWAPIIE(&prBss->aucIEs[ + sizeof(struct PARAM_FIXED_IEs)], + prBss->u4IELength - sizeof(struct PARAM_FIXED_IEs), + (uint8_t **) &prDesiredIE)) { + +#if 0 + iwEvent.cmd = IWEVGENIE; + iwEvent.u.data.flags = 1; + iwEvent.u.data.length = 2 + + (__u16) prDesiredIE->ucLength; + iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length; + if ((pcCur + iwEvent.len) > pcEnd) + break; +#if WIRELESS_EXT <= 18 + memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN); +#else + memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); + memcpy(pcCur + IW_EV_LCP_LEN, + &iwEvent.u.data.length, + sizeof(struct iw_point) - IW_EV_POINT_OFF); +#endif + memcpy(pcCur + IW_EV_POINT_LEN, prDesiredIE, + 2 + prDesiredIE->ucLength); + pcCur += iwEvent.len; +#else + iwEvent.cmd = IWEVCUSTOM; + iwEvent.u.data.length = (2 + prDesiredIE->ucLength) * 2 + + 8 /* wapi_ie= */; + iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length; + if ((pcCur + iwEvent.len) > pcEnd) + break; + iwEvent.u.data.flags = 1; + + memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); + memcpy(pcCur + IW_EV_LCP_LEN, + &iwEvent.u.data.length, + sizeof(struct iw_point) - IW_EV_POINT_OFF); + + pcCur += (IW_EV_POINT_LEN); + + pcCur += sprintf(pcCur, "wapi_ie="); + + snprintf_hex(pcCur, pcEnd - pcCur, + (uint8_t *) prDesiredIE, + prDesiredIE->ucLength + 2); + + pcCur += (2 + prDesiredIE->ucLength) + * 2 /* iwEvent.len */; +#endif + } +#endif + /* Complete an entry. Update end of valid entry */ + pcValidEntryEnd = pcCur; + /* Extract next bss */ + prBss = (struct PARAM_BSSID_EX *) ((char *)prBss + + prBss->u4Length); + } + + /* Update valid data length for caller function and upper layer + * applications. + */ + prData->length = (pcValidEntryEnd - pcExtra); + /* printk(KERN_INFO "[wifi] buf:%d result:%d\n", + * pData->length, u4BufLen); + */ + + /* kalIndicateStatusAndComplete(prGlueInfo, + * WLAN_STATUS_SCAN_COMPLETE, NULL, 0); + */ + +error: + /* free local query buffer */ + if (prList) + kalMemFree(prList, VIR_MEM_TYPE, u4AllocBufLen); + + return ret; +} /* wext_get_scan */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief To set desired network name ESSID. + * + * \param[in] prDev Net device requested. + * \param[in] prIwrInfo NULL. + * \param[in] prEssid Pointer of iw_point header. + * \param[in] pcExtra Pointer to buffer srtoring essid string. + * + * \retval 0 If netif_carrier_ok. + * \retval -E2BIG Essid string length is too big. + * \retval -EINVAL pcExtra is null pointer. + * \retval -EFAULT Driver fail to set new essid. + * + * \note If string length is ok, device will try connecting to the new network. + */ +/*----------------------------------------------------------------------------*/ +static int +wext_set_essid(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwrInfo, + IN struct iw_point *prEssid, IN char *pcExtra) +{ + struct PARAM_SSID rNewSsid; + uint32_t cipher; + enum ENUM_WEP_STATUS eEncStatus; + enum ENUM_PARAM_AUTH_MODE eAuthMode; + + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + struct GL_WPA_INFO *prWpaInfo; + uint8_t ucBssIndex = AIS_DEFAULT_INDEX; + + ASSERT(prNetDev); + ASSERT(prEssid); + ASSERT(pcExtra); + if (GLUE_CHK_PR3(prNetDev, prEssid, pcExtra) == FALSE) + return -EINVAL; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + if (prEssid->length > IW_ESSID_MAX_SIZE) + return -E2BIG; + + prWpaInfo = aisGetWpaInfo(prGlueInfo->prAdapter, + ucBssIndex); + + /* set auth mode */ + if (prWpaInfo->u4WpaVersion == + IW_AUTH_WPA_VERSION_DISABLED) { + eAuthMode = (prWpaInfo->u4AuthAlg == + IW_AUTH_ALG_OPEN_SYSTEM) ? + AUTH_MODE_OPEN : AUTH_MODE_AUTO_SWITCH; + /* printk(KERN_INFO + * "IW_AUTH_WPA_VERSION_DISABLED->Param_AuthMode%s\n",/ + * (eAuthMode == AUTH_MODE_OPEN) ? "Open" : "Shared"); + */ + } else { + /* set auth mode */ + switch (prWpaInfo->u4KeyMgmt) { + case IW_AUTH_KEY_MGMT_802_1X: + eAuthMode = + (prWpaInfo->u4WpaVersion == + IW_AUTH_WPA_VERSION_WPA) ? + AUTH_MODE_WPA : AUTH_MODE_WPA2; + /* printk("IW_AUTH_KEY_MGMT_802_1X->AUTH_MODE_WPA%s\n", + * (eAuthMode == AUTH_MODE_WPA) ? "" : "2"); + */ + break; + case IW_AUTH_KEY_MGMT_PSK: + eAuthMode = + (prWpaInfo->u4WpaVersion == + IW_AUTH_WPA_VERSION_WPA) ? + AUTH_MODE_WPA_PSK : AUTH_MODE_WPA2_PSK; + /* printk("IW_AUTH_KEY_MGMT_PSK->AUTH_MODE_WPA%sPSK\n", + * (eAuthMode == AUTH_MODE_WPA_PSK) ? "" : "2"); + */ + break; +#if CFG_SUPPORT_WAPI /* Android+ */ + case IW_AUTH_KEY_MGMT_WAPI_PSK: + break; + case IW_AUTH_KEY_MGMT_WAPI_CERT: + break; +#endif + + /* #if defined (IW_AUTH_KEY_MGMT_WPA_NONE) */ + /* case IW_AUTH_KEY_MGMT_WPA_NONE: */ + /* eAuthMode = AUTH_MODE_WPA_NONE; */ + /* //printk( + * "IW_AUTH_KEY_MGMT_WPA_NONE->AUTH_MODE_WPA_NONE\n"); + */ + /* break; */ + /* #endif */ +#if CFG_SUPPORT_802_11W + case IW_AUTH_KEY_MGMT_802_1X_SHA256: + eAuthMode = AUTH_MODE_WPA2; + break; + case IW_AUTH_KEY_MGMT_PSK_SHA256: + eAuthMode = AUTH_MODE_WPA2_PSK; + break; +#endif + default: + /* printk(KERN_INFO DRV_NAME + * "strange IW_AUTH_KEY_MGMT : %d set auto switch\n", + * prWpaInfo->u4KeyMgmt); + */ + eAuthMode = AUTH_MODE_AUTO_SWITCH; + break; + } + } + + rStatus = kalIoctl(prGlueInfo, wlanoidSetAuthMode, &eAuthMode, + sizeof(eAuthMode), FALSE, FALSE, FALSE, &u4BufLen); + + /* set encryption status */ + cipher = prWpaInfo->u4CipherGroup | + prWpaInfo->u4CipherPairwise; + if (cipher & IW_AUTH_CIPHER_CCMP) { + /* printk("IW_AUTH_CIPHER_CCMP->ENUM_ENCRYPTION3_ENABLED\n"); */ + eEncStatus = ENUM_ENCRYPTION3_ENABLED; + } else if (cipher & IW_AUTH_CIPHER_TKIP) { + /* printk("IW_AUTH_CIPHER_TKIP->ENUM_ENCRYPTION2_ENABLED\n"); */ + eEncStatus = ENUM_ENCRYPTION2_ENABLED; + } else if (cipher & (IW_AUTH_CIPHER_WEP104 | + IW_AUTH_CIPHER_WEP40)) { + /* printk("IW_AUTH_CIPHER_WEPx->ENUM_ENCRYPTION1_ENABLED\n"); */ + eEncStatus = ENUM_ENCRYPTION1_ENABLED; + } else if (cipher & IW_AUTH_CIPHER_NONE) { + /* printk("IW_AUTH_CIPHER_NONE->ENUM_ENCRYPTION_DISABLED\n"); */ + if (prWpaInfo->fgPrivacyInvoke) + eEncStatus = ENUM_ENCRYPTION1_ENABLED; + else + eEncStatus = ENUM_ENCRYPTION_DISABLED; + } else { + /* printk( + * "unknown IW_AUTH_CIPHER->Param_EncryptionDisabled\n" + * ); + */ + eEncStatus = ENUM_ENCRYPTION_DISABLED; + } + + rStatus = kalIoctl(prGlueInfo, wlanoidSetEncryptionStatus, &eEncStatus, + sizeof(eEncStatus), + FALSE, FALSE, FALSE, &u4BufLen); + +#if WIRELESS_EXT < 21 + /* GeorgeKuo: a length error bug exists in (WE < 21) cases, kernel + * before 2.6.19. Cut the trailing '\0'. + */ + rNewSsid.u4SsidLen = (prEssid->length) ? prEssid->length - + 1 : 0; +#else + rNewSsid.u4SsidLen = prEssid->length; +#endif + kalMemCopy(rNewSsid.aucSsid, pcExtra, rNewSsid.u4SsidLen); + + /* + * rNewSsid.aucSsid[rNewSsid.u4SsidLen] = '\0'; + * printk("set ssid(%u): %s\n", rNewSsid.u4SsidLen, rNewSsid.aucSsid); + */ + if (kalIoctl(prGlueInfo, + wlanoidSetSsid, + (void *)&rNewSsid, sizeof(struct PARAM_SSID), FALSE, FALSE, + TRUE, &u4BufLen) != WLAN_STATUS_SUCCESS) { + /* printk(KERN_WARNING "Fail to set ssid\n"); */ + return -EFAULT; + } + + return 0; +} /* wext_set_essid */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief To get current network name ESSID. + * + * \param[in] prDev Net device requested. + * \param[in] prIwrInfo NULL. + * \param[in] prEssid Pointer to iw_point structure containing essid + * information. + * \param[out] pcExtra Pointer to buffer srtoring essid string. + * + * \retval 0 If netif_carrier_ok. + * \retval -ENOTCONN Otherwise. + * + * \note If netif_carrier_ok, network essid is stored in pcExtra. + */ +/*----------------------------------------------------------------------------*/ +/* static PARAM_SSID_T ssid; */ +static int +wext_get_essid(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwrInfo, + IN struct iw_point *prEssid, OUT char *pcExtra) +{ + /* PARAM_SSID_T ssid; */ + + struct PARAM_SSID *prSsid; + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + + ASSERT(prNetDev); + ASSERT(prEssid); + ASSERT(pcExtra); + + if (GLUE_CHK_PR3(prNetDev, prEssid, pcExtra) == FALSE) + return -EINVAL; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + /* if (!netif_carrier_ok(prNetDev)) { */ + /* return -ENOTCONN; */ + /* } */ + + prSsid = kalMemAlloc(sizeof(struct PARAM_SSID), + VIR_MEM_TYPE); + + if (!prSsid) + return -ENOMEM; + rStatus = kalIoctl(prGlueInfo, wlanoidQuerySsid, prSsid, + sizeof(struct PARAM_SSID), + TRUE, FALSE, FALSE, &u4BufLen); + + if ((rStatus == WLAN_STATUS_SUCCESS) + && (prSsid->u4SsidLen <= MAX_SSID_LEN)) { + kalMemCopy(pcExtra, prSsid->aucSsid, prSsid->u4SsidLen); + prEssid->length = prSsid->u4SsidLen; + prEssid->flags = 1; + } + + kalMemFree(prSsid, VIR_MEM_TYPE, sizeof(struct PARAM_SSID)); + + return 0; +} /* wext_get_essid */ + +#if 0 + +/*----------------------------------------------------------------------------*/ +/*! + * \brief To set tx desired bit rate. Three cases here + * iwconfig wlan0 auto -> Set to origianl supported rate set. + * iwconfig wlan0 18M -> Imply "fixed" case, set to 18Mbps as desired rate. + * iwconfig wlan0 18M auto -> Set to auto rate lower and equal to 18Mbps + * + * \param[in] prNetDev Pointer to the net_device handler. + * \param[in] prIwReqInfo Pointer to the Request Info. + * \param[in] prRate Pointer to the Rate Parameter. + * \param[in] pcExtra Pointer to the extra buffer. + * + * \retval 0 Update desired rate. + * \retval -EINVAL Wrong parameter + */ +/*----------------------------------------------------------------------------*/ +int +wext_set_rate(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN struct iw_param *prRate, IN char *pcExtra) +{ + uint8_t aucSuppRate[PARAM_MAX_LEN_RATES_EX] = { 0 }; + uint8_t aucNewRate[PARAM_MAX_LEN_RATES_EX] = { 0 }; + uint32_t u4NewRateLen = 0; + uint32_t i; + + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + + ASSERT(prNetDev); + ASSERT(prRate); + if (GLUE_CHK_PR2(prNetDev, prRate) == FALSE) + return -EINVAL; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + /* + * printk("value = %d, fixed = %d, disable = %d, flags = %d\n", + * prRate->value, prRate->fixed, prRate->disabled, prRate->flags); + */ + + rStatus = wlanQueryInformation(prGlueInfo->prAdapter, + wlanoidQuerySupportedRates, &aucSuppRate, + sizeof(aucSuppRate), &u4BufLen); + + /* Case: AUTO */ + if (prRate->value < 0) { + if (prRate->fixed == 0) { + /* iwconfig wlan0 rate auto */ + + /* set full supported rate to device */ + /* printk( + * "wlanoidQuerySupportedRates():u4BufLen = %d\n", + * u4BufLen); + */ + rStatus = wlanSetInformation(prGlueInfo->prAdapter, + wlanoidSetDesiredRates, + &aucSuppRate, + sizeof(aucSuppRate), + &u4BufLen); + return 0; + } + /* iwconfig wlan0 rate fixed */ + + /* fix rate to what? DO NOTHING */ + return -EINVAL; + } + + aucNewRate[0] = prRate->value / + 500000; /* In unit of 500k */ + + for (i = 0; i < PARAM_MAX_LEN_RATES_EX; i++) { + /* check the given value is supported */ + if (aucSuppRate[i] == 0) + break; + + if (aucNewRate[0] == aucSuppRate[i]) { + u4NewRateLen = 1; + break; + } + } + + if (u4NewRateLen == 0) { + /* the given value is not supported */ + /* return error or use given rate as upper bound? */ + return -EINVAL; + } + + if (prRate->fixed == 0) { + /* add all rates lower than desired rate */ + for (i = 0; i < PARAM_MAX_LEN_RATES_EX; ++i) { + if (aucSuppRate[i] == 0) + break; + + if (aucSuppRate[i] < aucNewRate[0]) + aucNewRate[u4NewRateLen++] = aucSuppRate[i]; + } + } + + rStatus = wlanSetInformation(prGlueInfo->prAdapter, + wlanoidSetDesiredRates, &aucNewRate, + sizeof(aucNewRate), &u4BufLen); + return 0; +} /* wext_set_rate */ + +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief To get current tx bit rate. + * + * \param[in] prDev Net device requested. + * \param[in] prIwrInfo NULL. + * \param[out] prRate Pointer to iw_param structure to store current tx rate. + * \param[in] pcExtra NULL. + * + * \retval 0 If netif_carrier_ok. + * \retval -ENOTCONN Otherwise. + * + * \note If netif_carrier_ok, current tx rate is stored in pRate. + */ +/*----------------------------------------------------------------------------*/ +static int +wext_get_rate(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwrInfo, + OUT struct iw_param *prRate, IN char *pcExtra) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_LINK_SPEED_EX rLinkSpeed; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + uint32_t u4Rate = 0; + uint8_t ucBssIndex = AIS_DEFAULT_INDEX; + + ASSERT(prNetDev); + ASSERT(prRate); + if (GLUE_CHK_PR2(prNetDev, prRate) == FALSE) + return -EINVAL; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + ucBssIndex = wlanGetBssIdx(prNetDev); + + if (!netif_carrier_ok(prNetDev)) + return -ENOTCONN; + + if (ucBssIndex >= BSSID_NUM) + return -EFAULT; + + rStatus = kalIoctlByBssIdx(prGlueInfo, wlanoidQueryLinkSpeedEx, + &rLinkSpeed, sizeof(rLinkSpeed), + TRUE, FALSE, FALSE, + &u4BufLen, ucBssIndex); + + if (rStatus != WLAN_STATUS_SUCCESS) + return -EFAULT; + u4Rate = rLinkSpeed.rLq[ucBssIndex].u2LinkSpeed; + /* u4Rate is in unit of 100bps */ + prRate->value = u4Rate * 100; + prRate->fixed = 0; + + return 0; +} /* wext_get_rate */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief To set RTS/CTS theshold. + * + * \param[in] prDev Net device requested. + * \param[in] prIwrInfo NULL. + * \param[in] prRts Pointer to iw_param structure containing rts threshold. + * \param[in] pcExtra NULL. + * + * \retval 0 For success. + * \retval -EINVAL Given value is out of range. + * + * \note If given value is valid, device will follow the new setting. + */ +/*----------------------------------------------------------------------------*/ +static int +wext_set_rts(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwrInfo, + IN struct iw_param *prRts, IN char *pcExtra) +{ + uint32_t u4RtsThresh; + + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + + ASSERT(prNetDev); + ASSERT(prRts); + if (GLUE_CHK_PR2(prNetDev, prRts) == FALSE) + return -EINVAL; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + if (prRts->value < 0 || prRts->value > 2347) + return -EINVAL; + + if (prRts->disabled == 1) + u4RtsThresh = 2347; + else + u4RtsThresh = (uint32_t) prRts->value; + + rStatus = kalIoctl(prGlueInfo, wlanoidSetRtsThreshold, &u4RtsThresh, + sizeof(u4RtsThresh), + FALSE, FALSE, FALSE, &u4BufLen); + + prRts->value = (typeof(prRts->value)) u4RtsThresh; + prRts->disabled = (prRts->value > 2347) ? 1 : 0; + prRts->fixed = 1; + + return 0; +} /* wext_set_rts */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief To get RTS/CTS theshold. + * + * \param[in] prDev Net device requested. + * \param[in] prIwrInfo NULL. + * \param[out] prRts Pointer to iw_param structure containing rts threshold. + * \param[in] pcExtra NULL. + * + * \retval 0 Success. + * + * \note RTS threshold is stored in pRts. + */ +/*----------------------------------------------------------------------------*/ +static int +wext_get_rts(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwrInfo, + OUT struct iw_param *prRts, IN char *pcExtra) +{ + uint32_t u4RtsThresh; + + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + + ASSERT(prNetDev); + ASSERT(prRts); + if (GLUE_CHK_PR2(prNetDev, prRts) == FALSE) + return -EINVAL; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + rStatus = kalIoctl(prGlueInfo, wlanoidQueryRtsThreshold, &u4RtsThresh, + sizeof(u4RtsThresh), TRUE, FALSE, FALSE, &u4BufLen); + + prRts->value = (typeof(prRts->value)) u4RtsThresh; + prRts->disabled = (prRts->value > 2347 + || prRts->value < 0) ? 1 : 0; + prRts->fixed = 1; + + return 0; +} /* wext_get_rts */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief To get fragmentation threshold. + * + * \param[in] prDev Net device requested. + * \param[in] prIwrInfo NULL. + * \param[out] prFrag Pointer to iw_param structure containing frag threshold. + * \param[in] pcExtra NULL. + * + * \retval 0 Success. + * + * \note RTS threshold is stored in pFrag. Fragmentation is disabled. + */ +/*----------------------------------------------------------------------------*/ +static int +wext_get_frag(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwrInfo, + OUT struct iw_param *prFrag, IN char *pcExtra) +{ + ASSERT(prFrag); + + prFrag->value = 2346; + prFrag->fixed = 1; + prFrag->disabled = 1; + return 0; +} /* wext_get_frag */ + +#if 1 +/*----------------------------------------------------------------------------*/ +/*! + * \brief To set TX power, or enable/disable the radio. + * + * \param[in] prDev Net device requested. + * \param[in] prIwrInfo NULL. + * \param[in] prTxPow Pointer to iw_param structure containing tx power setting. + * \param[in] pcExtra NULL. + * + * \retval 0 Success. + * + * \note Tx power is stored in pTxPow. iwconfig wlan0 txpow on/off are used + * to enable/disable the radio. + */ +/*----------------------------------------------------------------------------*/ + +static int +wext_set_txpow(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwrInfo, + IN struct iw_param *prTxPow, IN char *pcExtra) +{ + int ret = 0; + /* PARAM_DEVICE_POWER_STATE ePowerState; */ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + + ASSERT(prNetDev); + ASSERT(prTxPow); + if (GLUE_CHK_PR2(prNetDev, prTxPow) == FALSE) + return -EINVAL; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + if (prTxPow->disabled) { + /* <1> disconnect */ + rStatus = kalIoctl(prGlueInfo, wlanoidSetDisassociate, NULL, + 0, FALSE, FALSE, TRUE, &u4BufLen); + if (rStatus != WLAN_STATUS_SUCCESS) { + /* ToDo:: DBGLOG */ + DBGLOG(INIT, INFO, "######set disassoc failed\n"); + } else { + DBGLOG(INIT, INFO, "######set assoc ok\n"); + } + /* <2> mark to power state flag */ + DBGLOG(INIT, INFO, "set to acpi d3(0)\n"); + wlanSetAcpiState(prGlueInfo->prAdapter, ACPI_STATE_D0); + + } else { + DBGLOG(INIT, INFO, "set to acpi d0\n"); + wlanSetAcpiState(prGlueInfo->prAdapter, ACPI_STATE_D0); + } + + prGlueInfo->ePowerState = ParamDeviceStateD0; + return ret; +} /* wext_set_txpow */ + +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief To get TX power. + * + * \param[in] prDev Net device requested. + * \param[in] prIwrInfo NULL. + * \param[out] prTxPow Pointer to iw_param structure containing tx power + * setting. + * \param[in] pcExtra NULL. + * + * \retval 0 Success. + * + * \note Tx power is stored in pTxPow. + */ +/*----------------------------------------------------------------------------*/ +static int +wext_get_txpow(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwrInfo, + OUT struct iw_param *prTxPow, IN char *pcExtra) +{ + /* PARAM_DEVICE_POWER_STATE ePowerState; */ + + struct GLUE_INFO *prGlueInfo = NULL; + + ASSERT(prNetDev); + ASSERT(prTxPow); + if (GLUE_CHK_PR2(prNetDev, prTxPow) == FALSE) + return -EINVAL; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + /* GeorgeKuo: wlanoidQueryAcpiDevicePowerState() reports capability, not + * current state. Use struct GLUE_INFO to store state. + */ + /* ePowerState = prGlueInfo->ePowerState; */ + + /* TxPow parameters: Fixed at relative 100% */ +#if WIRELESS_EXT < 17 + prTxPow->flags = 0x0002; /* IW_TXPOW_RELATIVE */ +#else + prTxPow->flags = IW_TXPOW_RELATIVE; +#endif + prTxPow->value = 100; + prTxPow->fixed = 1; + /* prTxPow->disabled = (ePowerState != ParamDeviceStateD3) ? + * FALSE : TRUE; + */ + prTxPow->disabled = TRUE; + + return 0; +} /* wext_get_txpow */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief To get encryption cipher and key. + * + * \param[in] prDev Net device requested. + * \param[in] prIwrInfo NULL. + * \param[out] prEnc Pointer to iw_point structure containing securiry + * information. + * \param[in] pcExtra Buffer to store key content. + * + * \retval 0 Success. + * + * \note Securiry information is stored in pEnc except key content. + */ +/*----------------------------------------------------------------------------*/ +static int +wext_get_encode(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwrInfo, + OUT struct iw_point *prEnc, IN char *pcExtra) +{ +#if 1 + /* ENUM_ENCRYPTION_STATUS_T eEncMode; */ + enum ENUM_WEP_STATUS eEncMode; + + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + + ASSERT(prNetDev); + ASSERT(prEnc); + if (GLUE_CHK_PR2(prNetDev, prEnc) == FALSE) + return -EINVAL; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + rStatus = kalIoctl(prGlueInfo, wlanoidQueryEncryptionStatus, &eEncMode, + sizeof(eEncMode), TRUE, FALSE, FALSE, &u4BufLen); + + switch (eEncMode) { + case ENUM_WEP_DISABLED: + prEnc->flags = IW_ENCODE_DISABLED; + break; + case ENUM_WEP_ENABLED: + prEnc->flags = IW_ENCODE_ENABLED; + break; + case ENUM_WEP_KEY_ABSENT: + prEnc->flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; + break; + default: + prEnc->flags = IW_ENCODE_ENABLED; + break; + } + + /* Cipher, Key Content, Key ID can't be queried */ + prEnc->flags |= IW_ENCODE_NOKEY; +#endif + return 0; +} /* wext_get_encode */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief To set encryption cipher and key. + * + * \param[in] prDev Net device requested. + * \param[in] prIwrInfo NULL. + * \param[in] prEnc Pointer to iw_point structure containing securiry + * information. + * \param[in] pcExtra Pointer to key string buffer. + * + * \retval 0 Success. + * \retval -EINVAL Key ID error for WEP. + * \retval -EFAULT Setting parameters to driver fail. + * \retval -EOPNOTSUPP Key size not supported. + * + * \note Securiry information is stored in pEnc. + */ +/*----------------------------------------------------------------------------*/ +static uint8_t wepBuf[48]; + +static int +wext_set_encode(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwrInfo, + IN struct iw_point *prEnc, IN char *pcExtra) +{ +#if 1 + enum ENUM_WEP_STATUS eEncStatus; + enum ENUM_PARAM_AUTH_MODE eAuthMode; + /* UINT_8 wepBuf[48]; */ + struct PARAM_WEP *prWepKey = (struct PARAM_WEP *) wepBuf; + + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + struct GL_WPA_INFO *prWpaInfo; + uint8_t ucBssIndex = AIS_DEFAULT_INDEX; + + ASSERT(prNetDev); + ASSERT(prEnc); + ASSERT(pcExtra); + if (GLUE_CHK_PR3(prNetDev, prEnc, pcExtra) == FALSE) + return -EINVAL; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + prWpaInfo = aisGetWpaInfo(prGlueInfo->prAdapter, + ucBssIndex); + + /* reset to default mode */ + prWpaInfo->u4WpaVersion = + IW_AUTH_WPA_VERSION_DISABLED; + prWpaInfo->u4KeyMgmt = 0; + prWpaInfo->u4CipherPairwise = IW_AUTH_CIPHER_NONE; + prWpaInfo->u4CipherGroup = IW_AUTH_CIPHER_NONE; + prWpaInfo->u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM; +#if CFG_SUPPORT_802_11W + prWpaInfo->u4Mfp = IW_AUTH_MFP_DISABLED; +#endif + + /* iwconfig wlan0 key off */ + if ((prEnc->flags & IW_ENCODE_MODE) == IW_ENCODE_DISABLED) { + eAuthMode = AUTH_MODE_OPEN; + + rStatus = kalIoctl(prGlueInfo, wlanoidSetAuthMode, &eAuthMode, + sizeof(eAuthMode), + FALSE, FALSE, FALSE, &u4BufLen); + + eEncStatus = ENUM_ENCRYPTION_DISABLED; + + rStatus = kalIoctl(prGlueInfo, wlanoidSetEncryptionStatus, + &eEncStatus, sizeof(eEncStatus), + FALSE, FALSE, FALSE, &u4BufLen); + + return 0; + } + + /* iwconfig wlan0 key 0123456789 */ + /* iwconfig wlan0 key s:abcde */ + /* iwconfig wlan0 key 0123456789 [1] */ + /* iwconfig wlan0 key 01234567890123456789012345 [1] */ + /* check key size for WEP */ + if (prEnc->length == 5 || prEnc->length == 13 + || prEnc->length == 16) { + /* prepare PARAM_WEP key structure */ + prWepKey->u4KeyIndex = (prEnc->flags & IW_ENCODE_INDEX) ? + (prEnc->flags & IW_ENCODE_INDEX) - 1 : 0; + if (prWepKey->u4KeyIndex > 3) { + /* key id is out of range */ + return -EINVAL; + } + prWepKey->u4KeyIndex |= 0x80000000; + prWepKey->u4Length = 12 + prEnc->length; + prWepKey->u4KeyLength = prEnc->length; + kalMemCopy(prWepKey->aucKeyMaterial, pcExtra, + prEnc->length); + + rStatus = kalIoctl(prGlueInfo, wlanoidSetAddWep, prWepKey, + prWepKey->u4Length, + FALSE, FALSE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, INFO, "wlanoidSetAddWep fail 0x%x\n", + rStatus); + return -EFAULT; + } + + /* change to auto switch */ + prWpaInfo->u4AuthAlg = IW_AUTH_ALG_SHARED_KEY | + IW_AUTH_ALG_OPEN_SYSTEM; + eAuthMode = AUTH_MODE_AUTO_SWITCH; + + rStatus = kalIoctl(prGlueInfo, wlanoidSetAuthMode, &eAuthMode, + sizeof(eAuthMode), + FALSE, FALSE, FALSE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + /* printk(KERN_INFO DRV_NAME + * "wlanoidSetAuthMode fail 0x%x\n", rStatus); + */ + return -EFAULT; + } + + prWpaInfo->u4CipherPairwise = + IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40; + prWpaInfo->u4CipherGroup = IW_AUTH_CIPHER_WEP104 | + IW_AUTH_CIPHER_WEP40; + + eEncStatus = ENUM_WEP_ENABLED; + + rStatus = kalIoctl(prGlueInfo, + wlanoidSetEncryptionStatus, + &eEncStatus, sizeof(enum ENUM_WEP_STATUS), + FALSE, FALSE, FALSE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + /* printk(KERN_INFO DRV_NAME + * "wlanoidSetEncryptionStatus fail 0x%x\n", + * rStatus); + */ + return -EFAULT; + } + + return 0; + } +#endif + return -EOPNOTSUPP; +} /* wext_set_encode */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief To set power management. + * + * \param[in] prDev Net device requested. + * \param[in] prIwrInfo NULL. + * \param[in] prPower Pointer to iw_param structure containing tx power setting. + * \param[in] pcExtra NULL. + * + * \retval 0 Success. + * + * \note New Power Management Mode is set to driver. + */ +/*----------------------------------------------------------------------------*/ +static int +wext_set_power(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwrInfo, + IN struct iw_param *prPower, IN char *pcExtra) +{ +#if 1 + enum PARAM_POWER_MODE ePowerMode; + int32_t i4PowerValue; + + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + struct PARAM_POWER_MODE_ rPowerMode; + + ASSERT(prNetDev); + ASSERT(prPower); + if (GLUE_CHK_PR2(prNetDev, prPower) == FALSE) + return -EINVAL; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + if (!prGlueInfo) + return -EFAULT; + + /* printk(KERN_INFO + * "wext_set_power value(%d) disabled(%d) flag(0x%x)\n", + * prPower->value, prPower->disabled, prPower->flags); + */ + + if (prPower->disabled) { + ePowerMode = Param_PowerModeCAM; + } else { + i4PowerValue = prPower->value; +#if WIRELESS_EXT < 21 + i4PowerValue /= 1000000; +#endif + if (i4PowerValue == 0) { + ePowerMode = Param_PowerModeCAM; + } else if (i4PowerValue == 1) { + ePowerMode = Param_PowerModeMAX_PSP; + } else if (i4PowerValue == 2) { + ePowerMode = Param_PowerModeFast_PSP; + } else { + DBGLOG(INIT, INFO, + "%s(): unsupported power management mode value = %d.\n", + __func__, prPower->value); + + return -EINVAL; + } + } + + rPowerMode.ePowerMode = ePowerMode; + rPowerMode.ucBssIdx = wlanGetBssIdx(prNetDev); + + rStatus = kalIoctl(prGlueInfo, + wlanoidSet802dot11PowerSaveProfile, + &rPowerMode, sizeof(struct PARAM_POWER_MODE_), + FALSE, FALSE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + /* printk(KERN_INFO DRV_NAME + * "wlanoidSet802dot11PowerSaveProfile fail 0x%x\n", + * rStatus); + */ + return -EFAULT; + } +#endif + return 0; +} /* wext_set_power */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief To get power management. + * + * \param[in] prDev Net device requested. + * \param[in] prIwrInfo NULL. + * \param[out] prPower Pointer to iw_param structure containing tx power + * setting. + * \param[in] pcExtra NULL. + * + * \retval 0 Success. + * + * \note Power management mode is stored in pTxPow->value. + */ +/*----------------------------------------------------------------------------*/ +static int +wext_get_power(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwrInfo, + OUT struct iw_param *prPower, IN char *pcExtra) +{ + + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + enum PARAM_POWER_MODE ePowerMode = Param_PowerModeCAM; + + ASSERT(prNetDev); + ASSERT(prPower); + if (GLUE_CHK_PR2(prNetDev, prPower) == FALSE) + return -EINVAL; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + +#if 0 +#if defined(_HIF_SDIO) + rStatus = sdio_io_ctrl(prGlueInfo, + wlanoidQuery802dot11PowerSaveProfile, + &ePowerMode, sizeof(ePowerMode), TRUE, TRUE, + &u4BufLen); +#else + rStatus = wlanQueryInformation(prGlueInfo->prAdapter, + wlanoidQuery802dot11PowerSaveProfile, + &ePowerMode, sizeof(ePowerMode), + &u4BufLen); +#endif +#else + rStatus = wlanQueryInformation(prGlueInfo->prAdapter, + wlanoidQuery802dot11PowerSaveProfile, + &ePowerMode, sizeof(ePowerMode), + &u4BufLen); +#endif + + if (rStatus != WLAN_STATUS_SUCCESS) + return -EFAULT; + + prPower->value = 0; + prPower->disabled = 1; + + if (Param_PowerModeCAM == ePowerMode) { + prPower->value = 0; + prPower->disabled = 1; + } else if (Param_PowerModeMAX_PSP == ePowerMode) { + prPower->value = 1; + prPower->disabled = 0; + } else if (Param_PowerModeFast_PSP == ePowerMode) { + prPower->value = 2; + prPower->disabled = 0; + } + + prPower->flags = IW_POWER_PERIOD | IW_POWER_RELATIVE; +#if WIRELESS_EXT < 21 + prPower->value *= 1000000; +#endif + + /* printk(KERN_INFO + * "wext_get_power value(%d) disabled(%d) flag(0x%x)\n", + * prPower->value, prPower->disabled, prPower->flags); + */ + + return 0; +} /* wext_get_power */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief To set authentication parameters. + * + * \param[in] prDev Net device requested. + * \param[in] prIwrInfo NULL. + * \param[in] rpAuth Pointer to iw_param structure containing authentication + * information. + * \param[in] pcExtra Pointer to key string buffer. + * + * \retval 0 Success. + * \retval -EINVAL Key ID error for WEP. + * \retval -EFAULT Setting parameters to driver fail. + * \retval -EOPNOTSUPP Key size not supported. + * + * \note Securiry information is stored in pEnc. + */ +/*----------------------------------------------------------------------------*/ +static int +wext_set_auth(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwrInfo, + IN struct iw_param *prAuth, IN char *pcExtra) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct GL_WPA_INFO *prWpaInfo; + struct CONNECTION_SETTINGS *prConnSettings; + uint8_t ucBssIndex = AIS_DEFAULT_INDEX; + + ASSERT(prNetDev); + ASSERT(prAuth); + if (GLUE_CHK_PR2(prNetDev, prAuth) == FALSE) + return -EINVAL; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + prWpaInfo = aisGetWpaInfo(prGlueInfo->prAdapter, + ucBssIndex); + prConnSettings = aisGetConnSettings(prGlueInfo->prAdapter, + ucBssIndex); + + /* Save information to glue info and process later when ssid is set. */ + switch (prAuth->flags & IW_AUTH_INDEX) { + case IW_AUTH_WPA_VERSION: +#if CFG_SUPPORT_WAPI + if (aisGetWapiMode(prGlueInfo->prAdapter, + ucBssIndex)) { + prWpaInfo->u4WpaVersion = + IW_AUTH_WPA_VERSION_DISABLED; + prWpaInfo->u4AuthAlg = + IW_AUTH_ALG_OPEN_SYSTEM; + } else { + prWpaInfo->u4WpaVersion = prAuth->value; + } +#else + prWpaInfo->u4WpaVersion = prAuth->value; +#endif + break; + + case IW_AUTH_CIPHER_PAIRWISE: + prWpaInfo->u4CipherPairwise = prAuth->value; + break; + + case IW_AUTH_CIPHER_GROUP: + prWpaInfo->u4CipherGroup = prAuth->value; + break; + + case IW_AUTH_KEY_MGMT: + prWpaInfo->u4KeyMgmt = prAuth->value; +#if CFG_SUPPORT_WAPI + if (prWpaInfo->u4KeyMgmt == + IW_AUTH_KEY_MGMT_WAPI_PSK || + prWpaInfo->u4KeyMgmt == + IW_AUTH_KEY_MGMT_WAPI_CERT) { + uint32_t u4BufLen; + uint32_t rStatus; + + rStatus = kalIoctl(prGlueInfo, wlanoidSetWapiMode, + &prAuth->value, sizeof(uint32_t), + FALSE, FALSE, TRUE, &u4BufLen); + DBGLOG(INIT, INFO, "IW_AUTH_WAPI_ENABLED :%d\n", + prAuth->value); + } +#endif + if (prWpaInfo->u4KeyMgmt == IW_AUTH_KEY_MGMT_WPS) + prConnSettings->fgWpsActive = TRUE; + else + prConnSettings->fgWpsActive = FALSE; + break; + + case IW_AUTH_80211_AUTH_ALG: + prWpaInfo->u4AuthAlg = prAuth->value; + break; + + case IW_AUTH_PRIVACY_INVOKED: + prWpaInfo->fgPrivacyInvoke = prAuth->value; + break; +#if CFG_SUPPORT_802_11W + case IW_AUTH_MFP: + /* printk("wext_set_auth IW_AUTH_MFP=%d\n", prAuth->value); */ + prWpaInfo->u4Mfp = prAuth->value; + break; +#endif +#if CFG_SUPPORT_WAPI + case IW_AUTH_WAPI_ENABLED: { + uint32_t u4BufLen; + uint32_t rStatus; + + rStatus = kalIoctl(prGlueInfo, wlanoidSetWapiMode, + &prAuth->value, sizeof(uint32_t), + FALSE, FALSE, TRUE, &u4BufLen); + } + DBGLOG(INIT, INFO, "IW_AUTH_WAPI_ENABLED :%d\n", + prAuth->value); + break; +#endif + default: + /* + * printk(KERN_INFO "[wifi] unsupported IW_AUTH_INDEX :%d\n", + * prAuth->flags); + */ + break; + } + return 0; +} /* wext_set_auth */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief To set encryption cipher and key. + * + * \param[in] prDev Net device requested. + * \param[in] prIwrInfo NULL. + * \param[in] prEnc Pointer to iw_point structure containing securiry + * information. + * \param[in] pcExtra Pointer to key string buffer. + * + * \retval 0 Success. + * \retval -EINVAL Key ID error for WEP. + * \retval -EFAULT Setting parameters to driver fail. + * \retval -EOPNOTSUPP Key size not supported. + * + * \note Securiry information is stored in pEnc. + */ +/*----------------------------------------------------------------------------*/ +#if CFG_SUPPORT_WAPI +uint8_t keyStructBuf[1024]; /* add/remove key shared buffer */ +#else +uint8_t keyStructBuf[100]; /* add/remove key shared buffer */ +#endif + +static int +wext_set_encode_ext(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwrInfo, + IN struct iw_point *prEnc, IN char *pcExtra) +{ + struct PARAM_REMOVE_KEY *prRemoveKey = + (struct PARAM_REMOVE_KEY *) keyStructBuf; + struct PARAM_KEY *prKey = (struct PARAM_KEY *) keyStructBuf; + + struct PARAM_WEP *prWepKey = (struct PARAM_WEP *) wepBuf; + + struct iw_encode_ext *prIWEncExt = (struct iw_encode_ext *) + pcExtra; + + enum ENUM_WEP_STATUS eEncStatus; + enum ENUM_PARAM_AUTH_MODE eAuthMode; + /* ENUM_PARAM_OP_MODE_T eOpMode = NET_TYPE_AUTO_SWITCH; */ + +#if CFG_SUPPORT_WAPI + struct PARAM_WPI_KEY *prWpiKey = (struct PARAM_WPI_KEY *) + keyStructBuf; +#endif + + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + struct GL_WPA_INFO *prWpaInfo; + uint8_t ucBssIndex = AIS_DEFAULT_INDEX; + + ASSERT(prNetDev); + ASSERT(prEnc); + if (GLUE_CHK_PR3(prNetDev, prEnc, pcExtra) == FALSE) + return -EINVAL; + + if (prIWEncExt == NULL) { + DBGLOG(REQ, ERROR, "prIWEncExt is NULL!\n"); + return -EINVAL; + } + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + prWpaInfo = aisGetWpaInfo(prGlueInfo->prAdapter, + ucBssIndex); + + memset(keyStructBuf, 0, sizeof(keyStructBuf)); + +#if CFG_SUPPORT_WAPI + if (prIWEncExt->alg == IW_ENCODE_ALG_SMS4) { + if (prEnc->flags & IW_ENCODE_DISABLED) { + /* printk(KERN_INFO "[wapi] IW_ENCODE_DISABLED\n"); */ + return 0; + } + /* KeyID */ + prWpiKey->ucKeyID = (prEnc->flags & IW_ENCODE_INDEX); + prWpiKey->ucKeyID--; + if (prWpiKey->ucKeyID > 1) { + /* key id is out of range */ + /* printk(KERN_INFO + * "[wapi] add key error: key_id invalid %d\n", + * prWpiKey->ucKeyID); + */ + return -EINVAL; + } + + if (prIWEncExt->key_len != 32) { + /* key length not valid */ + /* printk(KERN_INFO + * "[wapi] add key error: key_len invalid %d\n", + * prIWEncExt->key_len); + */ + return -EINVAL; + } + /* printk(KERN_INFO "[wapi] %d ext_flags %d\n", prEnc->flags, + * prIWEncExt->ext_flags); + */ + + if (prIWEncExt->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { + prWpiKey->eKeyType = ENUM_WPI_GROUP_KEY; + prWpiKey->eDirection = ENUM_WPI_RX; + } else if (prIWEncExt->ext_flags & + IW_ENCODE_EXT_SET_TX_KEY) { + prWpiKey->eKeyType = ENUM_WPI_PAIRWISE_KEY; + prWpiKey->eDirection = ENUM_WPI_RX_TX; + } + + /* PN */ + memcpy(&prWpiKey->aucPN[0], &prIWEncExt->tx_seq[0], + IW_ENCODE_SEQ_MAX_SIZE); + memcpy(&prWpiKey->aucPN[IW_ENCODE_SEQ_MAX_SIZE], + &prIWEncExt->rx_seq[0], IW_ENCODE_SEQ_MAX_SIZE); + + /* BSSID */ + memcpy(prWpiKey->aucAddrIndex, prIWEncExt->addr.sa_data, 6); + + memcpy(prWpiKey->aucWPIEK, prIWEncExt->key, 16); + prWpiKey->u4LenWPIEK = 16; + + memcpy(prWpiKey->aucWPICK, &prIWEncExt->key[16], 16); + prWpiKey->u4LenWPICK = 16; + prWpiKey->ucBssIdx = ucBssIndex; + rStatus = kalIoctl(prGlueInfo, wlanoidSetWapiKey, prWpiKey, + sizeof(struct PARAM_WPI_KEY), + FALSE, FALSE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + /* do nothing */ + /* printk(KERN_INFO "[wapi] add key error:%x\n", + * rStatus); + */ + } + + } else +#endif + { + + if ((prEnc->flags & IW_ENCODE_MODE) == IW_ENCODE_DISABLED) { + prRemoveKey->u4Length = sizeof(*prRemoveKey); + memcpy(prRemoveKey->arBSSID, + prIWEncExt->addr.sa_data, 6); + /* + * printk("IW_ENCODE_DISABLED: ID:%d, Addr:[" + * MACSTR "]\n", prRemoveKey->KeyIndex, + * MAC2STR(prRemoveKey->BSSID)); + */ + prRemoveKey->ucBssIdx = ucBssIndex; + rStatus = kalIoctl(prGlueInfo, wlanoidSetRemoveKey, + prRemoveKey, prRemoveKey->u4Length, + FALSE, FALSE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(INIT, INFO, "remove key error:%x\n", + rStatus); + return 0; + } + /* return 0; */ + /* printk ("alg %x\n", prIWEncExt->alg); */ + + switch (prIWEncExt->alg) { + case IW_ENCODE_ALG_NONE: + break; + case IW_ENCODE_ALG_WEP: + /* iwconfig wlan0 key 0123456789 */ + /* iwconfig wlan0 key s:abcde */ + /* iwconfig wlan0 key 0123456789 [1] */ + /* iwconfig wlan0 key 01234567890123456789012345 [1] */ + /* check key size for WEP */ + if (prIWEncExt->key_len == 5 || + prIWEncExt->key_len == 13 || + prIWEncExt->key_len == 16) { + /* prepare PARAM_WEP key structure */ + prWepKey->u4KeyIndex = + (prEnc->flags & IW_ENCODE_INDEX) ? + (prEnc->flags & IW_ENCODE_INDEX) - 1 : + 0; + if (prWepKey->u4KeyIndex > 3) { + /* key id is out of range */ + return -EINVAL; + } + prWepKey->u4KeyIndex |= 0x80000000; + prWepKey->u4Length = 12 + prIWEncExt->key_len; + prWepKey->u4KeyLength = prIWEncExt->key_len; + /* kalMemCopy(prWepKey->aucKeyMaterial, pcExtra, + * prIWEncExt->key_len); + */ + kalMemCopy(prWepKey->aucKeyMaterial, + prIWEncExt->key, + prIWEncExt->key_len); + + rStatus = kalIoctl(prGlueInfo, + wlanoidSetAddWep, + prWepKey, prWepKey->u4Length, + FALSE, FALSE, TRUE, + &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, INFO, + "wlanoidSetAddWep fail 0x%x\n", + rStatus); + return -EFAULT; + } + + /* change to auto switch */ + prWpaInfo->u4AuthAlg = + IW_AUTH_ALG_SHARED_KEY | + IW_AUTH_ALG_OPEN_SYSTEM; + eAuthMode = AUTH_MODE_AUTO_SWITCH; + + rStatus = kalIoctl(prGlueInfo, + wlanoidSetAuthMode, + &eAuthMode, + sizeof(eAuthMode), + FALSE, FALSE, FALSE, + &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, INFO, + "wlanoidSetAuthMode fail 0x%x\n", + rStatus); + return -EFAULT; + } + + prWpaInfo->u4CipherPairwise = + IW_AUTH_CIPHER_WEP104 | + IW_AUTH_CIPHER_WEP40; + prWpaInfo->u4CipherGroup = + IW_AUTH_CIPHER_WEP104 | + IW_AUTH_CIPHER_WEP40; + + eEncStatus = ENUM_WEP_ENABLED; + + rStatus = kalIoctl(prGlueInfo, + wlanoidSetEncryptionStatus, + &eEncStatus, + sizeof(enum ENUM_WEP_STATUS), + FALSE, FALSE, FALSE, + &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, INFO, + "wlanoidSetEncryptionStatus fail 0x%x\n", + rStatus); + return -EFAULT; + } + + } else { + DBGLOG(INIT, INFO, "key length %x\n", + prIWEncExt->key_len); + DBGLOG(INIT, INFO, "key error\n"); + } + + break; + case IW_ENCODE_ALG_TKIP: + case IW_ENCODE_ALG_CCMP: +#if CFG_SUPPORT_802_11W + case IW_ENCODE_ALG_AES_CMAC: +#endif + { + + /* KeyID */ + prKey->u4KeyIndex = (prEnc->flags & IW_ENCODE_INDEX) ? + (prEnc->flags & IW_ENCODE_INDEX) - 1 : 0; +#if CFG_SUPPORT_802_11W + if (prKey->u4KeyIndex > 5) { +#else + if (prKey->u4KeyIndex > 3) { +#endif + DBGLOG(INIT, INFO, "key index error:0x%x\n", + prKey->u4KeyIndex); + /* key id is out of range */ + return -EINVAL; + } + + /* bit(31) and bit(30) are shared by pKey and + * pRemoveKey + */ + /* Tx Key Bit(31) */ + if (prIWEncExt->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) + prKey->u4KeyIndex |= 0x1UL << 31; + + /* Pairwise Key Bit(30) */ + if (prIWEncExt->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { + /* group key */ + } else { + /* pairwise key */ + prKey->u4KeyIndex |= 0x1UL << 30; + } + + } + /* Rx SC Bit(29) */ + if (prIWEncExt->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) { + prKey->u4KeyIndex |= 0x1UL << 29; + memcpy(&prKey->rKeyRSC, prIWEncExt->rx_seq, + IW_ENCODE_SEQ_MAX_SIZE); + } + + /* BSSID */ + memcpy(prKey->arBSSID, prIWEncExt->addr.sa_data, 6); + + /* switch tx/rx MIC key for sta */ + if (prIWEncExt->alg == IW_ENCODE_ALG_TKIP + && prIWEncExt->key_len == 32) { + memcpy(prKey->aucKeyMaterial, prIWEncExt->key, 16); + memcpy(((uint8_t *) prKey->aucKeyMaterial) + 16, + prIWEncExt->key + 24, 8); + memcpy((prKey->aucKeyMaterial) + 24, + prIWEncExt->key + 16, 8); + } else { + if (prIWEncExt->key_len > + sizeof(prKey->aucKeyMaterial)) { + DBGLOG(REQ, ERROR, + "prIWEncExt->key_len: %u is too long!\n", + prIWEncExt->key_len); + return -EINVAL; + } + memcpy(prKey->aucKeyMaterial, prIWEncExt->key, + prIWEncExt->key_len); + } + + prKey->u4KeyLength = prIWEncExt->key_len; + prKey->u4Length = ((unsigned long) &(((struct PARAM_KEY *) + 0)->aucKeyMaterial)) + prKey->u4KeyLength; + prKey->ucBssIdx = ucBssIndex; + rStatus = kalIoctl(prGlueInfo, wlanoidSetAddKey, prKey, + prKey->u4Length, + FALSE, FALSE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, INFO, "add key error:%x\n", rStatus); + return -EFAULT; + } + break; + } + } + + return 0; +} /* wext_set_encode_ext */ + + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Set country code + * + * \param[in] prNetDev Net device requested. + * \param[in] prData iwreq.u.data carries country code value. + * + * \retval 0 For success. + * \retval -EEFAULT For fail. + * + * \note Country code is stored and channel list is updated based on current + * country domain. + */ +/*----------------------------------------------------------------------------*/ +static int wext_set_country(IN struct net_device *prNetDev, + IN struct iw_point *prData) +{ + struct GLUE_INFO *prGlueInfo; + uint32_t rStatus; + uint32_t u4BufLen; + uint8_t aucCountry[COUNTRY_CODE_LEN]; + + ASSERT(prNetDev); + + /* prData->pointer should be like "COUNTRY US", "COUNTRY EU" + * and "COUNTRY JP" + */ + if (GLUE_CHK_PR2(prNetDev, prData) == FALSE + || !prData->pointer || prData->length < COUNTRY_CODE_LEN) + return -EINVAL; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + if (copy_from_user(aucCountry, prData->pointer, + COUNTRY_CODE_LEN)) + return -EFAULT; + + rStatus = kalIoctl(prGlueInfo, + wlanoidSetCountryCode, + &aucCountry[COUNTRY_CODE_LEN - 2], 2, + FALSE, FALSE, TRUE, &u4BufLen); + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, ERROR, "Set country code error: %x\n", rStatus); + return -EFAULT; + } + + return 0; +} + + +/*----------------------------------------------------------------------------*/ +/*! + * \brief To report the iw private args table to user space. + * + * \param[in] prNetDev Net device requested. + * \param[out] prData iwreq.u.data to carry the private args table. + * + * \retval 0 For success. + * \retval -E2BIG For user's buffer size is too small. + * \retval -EFAULT For fail. + * + */ +/*----------------------------------------------------------------------------*/ +int wext_get_priv(IN struct net_device *prNetDev, + OUT struct iw_point *prData) +{ + uint16_t u2BufferSize = prData->length; + + /* Update our private args table size */ + prData->length = (__u16)sizeof(rIwPrivTable); + if (u2BufferSize < prData->length) + return -E2BIG; + + if (prData->length) { + if (copy_to_user(prData->pointer, rIwPrivTable, + sizeof(rIwPrivTable))) + return -EFAULT; + } + + return 0; +} /* wext_get_priv */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief ioctl() (Linux Wireless Extensions) routines + * + * \param[in] prDev Net device requested. + * \param[in] ifr The ifreq structure for seeting the wireless extension. + * \param[in] i4Cmd The wireless extension ioctl command. + * + * \retval zero On success. + * \retval -EOPNOTSUPP If the cmd is not supported. + * \retval -EFAULT If copy_to_user goes wrong. + * \retval -EINVAL If any value's out of range. + * + * \note + */ +/*----------------------------------------------------------------------------*/ +int wext_support_ioctl(IN struct net_device *prDev, + IN struct ifreq *prIfReq, IN int i4Cmd) +{ + /* prIfReq is verified in the caller function wlanDoIOCTL() */ + struct iwreq *iwr = (struct iwreq *)prIfReq; + struct iw_request_info rIwReqInfo; + int ret = 0; + char *prExtraBuf = NULL; + uint32_t u4ExtraSize = 0; + + /* prDev is verified in the caller function wlanDoIOCTL() */ + + /* printk("%d CMD:0x%x\n", jiffies_to_msecs(jiffies), i4Cmd); */ + + /* Prepare the call */ + rIwReqInfo.cmd = (__u16) i4Cmd; + rIwReqInfo.flags = 0; + + switch (i4Cmd) { + case SIOCGIWNAME: /* 0x8B01, get wireless protocol name */ + ret = wext_get_name(prDev, &rIwReqInfo, (char *)&iwr->u.name, + sizeof(iwr->u.name), NULL); + break; + + /* case SIOCSIWNWID: 0x8B02, deprecated */ + /* case SIOCGIWNWID: 0x8B03, deprecated */ + + case SIOCSIWFREQ: /* 0x8B04, set channel */ + ret = wext_set_freq(prDev, NULL, &iwr->u.freq, NULL); + break; + + case SIOCGIWFREQ: /* 0x8B05, get channel */ + ret = wext_get_freq(prDev, NULL, &iwr->u.freq, NULL); + break; + + case SIOCSIWMODE: /* 0x8B06, set operation mode */ + ret = wext_set_mode(prDev, NULL, &iwr->u.mode, NULL); + /* ret = 0; */ + break; + + case SIOCGIWMODE: /* 0x8B07, get operation mode */ + ret = wext_get_mode(prDev, NULL, &iwr->u.mode, NULL); + break; + + /* case SIOCSIWSENS: 0x8B08, unsupported */ + /* case SIOCGIWSENS: 0x8B09, unsupported */ + + /* case SIOCSIWRANGE: 0x8B0A, unused */ + case SIOCGIWRANGE: /* 0x8B0B, get range of parameters */ + if (iwr->u.data.pointer != NULL) { + /* Buffer size should be large enough */ + if (iwr->u.data.length < sizeof(struct iw_range)) { + ret = -E2BIG; + break; + } + + prExtraBuf = kalMemAlloc(sizeof(struct iw_range), + VIR_MEM_TYPE); + if (!prExtraBuf) { + ret = -ENOMEM; + break; + } + + /* reset all fields */ + memset(prExtraBuf, 0, sizeof(struct iw_range)); + iwr->u.data.length = sizeof(struct iw_range); + + ret = wext_get_range(prDev, NULL, &iwr->u.data, + prExtraBuf); + /* Push up to the caller */ + if (copy_to_user(iwr->u.data.pointer, prExtraBuf, + iwr->u.data.length)) + ret = -EFAULT; + + kalMemFree(prExtraBuf, VIR_MEM_TYPE, + sizeof(struct iw_range)); + prExtraBuf = NULL; + } else { + ret = -EINVAL; + } + break; + + case SIOCSIWPRIV: /* 0x8B0C, set country code */ + ret = wext_set_country(prDev, &iwr->u.data); + break; + + case SIOCGIWPRIV: /* 0x8B0D, get private args table */ + ret = wext_get_priv(prDev, &iwr->u.data); + break; + + /* caes SIOCSIWSTATS: 0x8B0E, unused */ + /* case SIOCGIWSTATS: + * get statistics, intercepted by wireless_process_ioctl() + * in wireless.c, + * redirected to dev_iwstats(), dev->get_wireless_stats(). + */ + /* case SIOCSIWSPY: 0x8B10, unsupported */ + /* case SIOCGIWSPY: 0x8B11, unsupported */ + /* case SIOCSIWTHRSPY: 0x8B12, unsupported */ + /* case SIOCGIWTHRSPY: 0x8B13, unsupported */ + + case SIOCSIWAP: /* 0x8B14, set access point MAC addresses (BSSID) */ + if (iwr->u.ap_addr.sa_data[0] == 0 && + iwr->u.ap_addr.sa_data[1] == 0 && + iwr->u.ap_addr.sa_data[2] == 0 && + iwr->u.ap_addr.sa_data[3] == 0 && + iwr->u.ap_addr.sa_data[4] == 0 + && iwr->u.ap_addr.sa_data[5] == 0) { + /* WPA Supplicant will set 000000000000 in + * wpa_driver_wext_deinit(), do nothing here or + * disassoc again? + */ + ret = 0; + break; + } + ret = wext_set_ap(prDev, NULL, &iwr->u.ap_addr, NULL); + break; + + case SIOCGIWAP: /* 0x8B15, get access point MAC addresses (BSSID) */ + ret = wext_get_ap(prDev, NULL, &iwr->u.ap_addr, NULL); + break; + + case SIOCSIWMLME: /* 0x8B16, request MLME operation */ + /* Fixed length structure */ + if (iwr->u.data.length != sizeof(struct iw_mlme)) { + DBGLOG(INIT, INFO, "MLME buffer strange:%d\n", + iwr->u.data.length); + ret = -EINVAL; + break; + } + + if (!iwr->u.data.pointer) { + ret = -EINVAL; + break; + } + + prExtraBuf = kalMemAlloc(sizeof(struct iw_mlme), + VIR_MEM_TYPE); + if (!prExtraBuf) { + ret = -ENOMEM; + break; + } + + if (copy_from_user(prExtraBuf, iwr->u.data.pointer, + sizeof(struct iw_mlme))) + ret = -EFAULT; + else + ret = wext_set_mlme(prDev, NULL, &(iwr->u.data), + prExtraBuf); + + kalMemFree(prExtraBuf, VIR_MEM_TYPE, + sizeof(struct iw_mlme)); + prExtraBuf = NULL; + break; + + /* case SIOCGIWAPLIST: 0x8B17, deprecated */ + case SIOCSIWSCAN: /* 0x8B18, scan request */ + if (iwr->u.data.pointer == NULL) + ret = wext_set_scan(prDev, NULL, NULL, NULL); +#if WIRELESS_EXT > 17 + else if (iwr->u.data.length == sizeof(struct iw_scan_req)) { + struct iw_scan_req iw; + + if (copy_from_user(&iw, + (struct iw_scan_req *)(iwr->u.data.pointer), + sizeof(struct iw_scan_req))) { + ret = -EFAULT; + break; + } + + if (iw.essid_len > MAX_SSID_LEN) { + ret = -EFAULT; + break; + } + + prExtraBuf = kalMemAlloc(MAX_SSID_LEN, VIR_MEM_TYPE); + if (!prExtraBuf) { + ret = -ENOMEM; + break; + } + + if (copy_from_user(prExtraBuf, &iw.essid, + iw.essid_len)) { + ret = -EFAULT; + } else { + ret = wext_set_scan(prDev, NULL, + (union iwreq_data *)&(iwr->u.data), + prExtraBuf); + } + + kalMemFree(prExtraBuf, VIR_MEM_TYPE, MAX_SSID_LEN); + prExtraBuf = NULL; + } +#endif + else + ret = -EINVAL; + break; +#if 1 + case SIOCGIWSCAN: /* 0x8B19, get scan results */ + if (!iwr->u.data.pointer || !iwr->u.essid.pointer) { + ret = -EINVAL; + break; + } + + u4ExtraSize = iwr->u.data.length; + /* allocate the same size of kernel buffer to store scan + * results. + */ + prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); + if (!prExtraBuf) { + ret = -ENOMEM; + break; + } + + /* iwr->u.data.length may be updated by wext_get_scan() */ + ret = wext_get_scan(prDev, NULL, &iwr->u.data, prExtraBuf); + if (ret != 0) { + if (ret == -E2BIG) + DBGLOG(INIT, INFO, + "[wifi] wext_get_scan -E2BIG\n"); + } else { + /* check updated length is valid */ + ASSERT(iwr->u.data.length <= u4ExtraSize); + if (iwr->u.data.length > u4ExtraSize) { + DBGLOG(INIT, INFO, + "Updated result length is larger than allocated (%d > %d)\n", + iwr->u.data.length, u4ExtraSize); + iwr->u.data.length = u4ExtraSize; + } + + if (copy_to_user(iwr->u.data.pointer, prExtraBuf, + iwr->u.data.length)) + ret = -EFAULT; + } + + kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize); + prExtraBuf = NULL; + + break; + +#endif + +#if 1 + case SIOCSIWESSID: /* 0x8B1A, set SSID (network name) */ + u4ExtraSize = iwr->u.essid.length; + if (u4ExtraSize > IW_ESSID_MAX_SIZE) { + ret = -E2BIG; + break; + } + if (!iwr->u.essid.pointer) { + ret = -EINVAL; + break; + } + + prExtraBuf = kalMemAlloc(IW_ESSID_MAX_SIZE + 4, + VIR_MEM_TYPE); + if (!prExtraBuf) { + ret = -ENOMEM; + break; + } + + if (copy_from_user(prExtraBuf, iwr->u.essid.pointer, + u4ExtraSize)) { + ret = -EFAULT; + } else { + /* Add trailing '\0' for printk */ + /* prExtraBuf[iwr->u.essid.length] = 0; */ + /* printk(KERN_INFO "wext_set_essid: %s (%d)\n", + * prExtraBuf, iwr->u.essid.length); + */ + ret = wext_set_essid(prDev, NULL, &iwr->u.essid, + prExtraBuf); + /* printk ("set essid %d\n", ret); */ + } + + kalMemFree(prExtraBuf, VIR_MEM_TYPE, IW_ESSID_MAX_SIZE + 4); + prExtraBuf = NULL; + break; + +#endif + + case SIOCGIWESSID: /* 0x8B1B, get SSID */ + u4ExtraSize = iwr->u.essid.length; + if (!iwr->u.essid.pointer) { + ret = -EINVAL; + break; + } + + if (u4ExtraSize != IW_ESSID_MAX_SIZE + && u4ExtraSize != IW_ESSID_MAX_SIZE + 1) { + DBGLOG(INIT, INFO, + "[wifi] iwr->u.essid.length:%d too small\n", + iwr->u.essid.length); + ret = -E2BIG; /* let caller try larger buffer */ + break; + } + + prExtraBuf = kalMemAlloc(IW_ESSID_MAX_SIZE + 1, + VIR_MEM_TYPE); + if (!prExtraBuf) { + ret = -ENOMEM; + break; + } + + /* iwr->u.essid.length is updated by wext_get_essid() */ + + ret = wext_get_essid(prDev, NULL, &iwr->u.essid, + prExtraBuf); + if (ret == 0) { + if (copy_to_user(iwr->u.essid.pointer, prExtraBuf, + iwr->u.essid.length)) + ret = -EFAULT; + } + + kalMemFree(prExtraBuf, VIR_MEM_TYPE, IW_ESSID_MAX_SIZE + 1); + prExtraBuf = NULL; + + break; + + /* case SIOCSIWNICKN: 0x8B1C, not supported */ + /* case SIOCGIWNICKN: 0x8B1D, not supported */ + + case SIOCSIWRATE: /* 0x8B20, set default bit rate (bps) */ + /* ret = wext_set_rate(prDev, &rIwReqInfo, &iwr->u.bitrate, + * NULL); + */ + break; + + case SIOCGIWRATE: /* 0x8B21, get current bit rate (bps) */ + ret = wext_get_rate(prDev, NULL, &iwr->u.bitrate, NULL); + break; + + case SIOCSIWRTS: /* 0x8B22, set rts/cts threshold */ + ret = wext_set_rts(prDev, NULL, &iwr->u.rts, NULL); + break; + + case SIOCGIWRTS: /* 0x8B23, get rts/cts threshold */ + ret = wext_get_rts(prDev, NULL, &iwr->u.rts, NULL); + break; + + /* case SIOCSIWFRAG: 0x8B24, unsupported */ + case SIOCGIWFRAG: /* 0x8B25, get frag threshold */ + ret = wext_get_frag(prDev, NULL, &iwr->u.frag, NULL); + break; + + case SIOCSIWTXPOW: /* 0x8B26, set relative tx power (in %) */ + ret = wext_set_txpow(prDev, NULL, &iwr->u.txpower, NULL); + break; + + case SIOCGIWTXPOW: /* 0x8B27, get relative tx power (in %) */ + ret = wext_get_txpow(prDev, NULL, &iwr->u.txpower, NULL); + break; + + /* case SIOCSIWRETRY: 0x8B28, unsupported */ + /* case SIOCGIWRETRY: 0x8B29, unsupported */ + +#if 1 + case SIOCSIWENCODE: /* 0x8B2A, set encoding token & mode */ + /* Only DISABLED case has NULL pointer and length == 0 */ + u4ExtraSize = iwr->u.encoding.length; + if (iwr->u.encoding.pointer) { + if (u4ExtraSize > 16) { + ret = -E2BIG; + break; + } + + prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); + if (!prExtraBuf) { + ret = -ENOMEM; + break; + } + + if (copy_from_user(prExtraBuf, iwr->u.encoding.pointer, + u4ExtraSize)) + ret = -EFAULT; + + if (ret == 0) + ret = wext_set_encode(prDev, NULL, + &iwr->u.encoding, + prExtraBuf); + + kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize); + prExtraBuf = NULL; + + } else if (u4ExtraSize != 0) + ret = -EINVAL; + break; + + case SIOCGIWENCODE: /* 0x8B2B, get encoding token & mode */ + /* check pointer */ + ret = wext_get_encode(prDev, NULL, &iwr->u.encoding, NULL); + break; + + case SIOCSIWPOWER: /* 0x8B2C, set power management */ + ret = wext_set_power(prDev, NULL, &iwr->u.power, NULL); + break; + + case SIOCGIWPOWER: /* 0x8B2D, get power management */ + ret = wext_get_power(prDev, NULL, &iwr->u.power, NULL); + break; + +#if WIRELESS_EXT > 17 + case SIOCSIWGENIE: /* 0x8B30, set gen ie */ + if (iwr->u.data.pointer) { + u4ExtraSize = iwr->u.data.length; + if (1 /* wlanQueryWapiMode(prGlueInfo->prAdapter) */) { + /* Fixed length structure */ +#if CFG_SUPPORT_WAPI + if (u4ExtraSize > 42 /* The max wapi ie buffer + */ + ) { + ret = -EINVAL; + break; + } +#endif + if (u4ExtraSize) { + prExtraBuf = kalMemAlloc(u4ExtraSize, + VIR_MEM_TYPE); + if (!prExtraBuf) { + ret = -ENOMEM; + break; + } + if (copy_from_user(prExtraBuf, + iwr->u.data.pointer, u4ExtraSize)) + ret = -EFAULT; + else + wext_support_ioctl_SIOCSIWGENIE( + prDev, prExtraBuf, + u4ExtraSize); + kalMemFree(prExtraBuf, VIR_MEM_TYPE, + u4ExtraSize); + prExtraBuf = NULL; + } + } + } + break; + + case SIOCGIWGENIE: /* 0x8B31, get gen ie, unused */ + break; + +#endif + + case SIOCSIWAUTH: /* 0x8B32, set auth mode params */ + ret = wext_set_auth(prDev, NULL, &iwr->u.param, NULL); + break; + + /* case SIOCGIWAUTH: 0x8B33, unused? */ + case SIOCSIWENCODEEXT: /* 0x8B34, set extended encoding token & mode */ + if (iwr->u.encoding.pointer) { + u4ExtraSize = iwr->u.encoding.length; + if (u4ExtraSize > sizeof(struct iw_encode_ext)) { + ret = -EINVAL; + break; + } + + prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); + if (!prExtraBuf) { + ret = -ENOMEM; + break; + } + + if (copy_from_user(prExtraBuf, iwr->u.encoding.pointer, + u4ExtraSize)) + ret = -EFAULT; + } else if (iwr->u.encoding.length != 0) { + ret = -EINVAL; + break; + } + + if (ret == 0) + ret = wext_set_encode_ext(prDev, NULL, &iwr->u.encoding, + prExtraBuf); + + if (prExtraBuf) { + kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize); + prExtraBuf = NULL; + } + break; + + /* case SIOCGIWENCODEEXT: 0x8B35, unused? */ + + case SIOCSIWPMKSA: /* 0x8B36, pmksa cache operation */ +#if 1 + if (iwr->u.data.pointer) { + /* Fixed length structure */ + if (iwr->u.data.length != sizeof(struct iw_pmksa)) { + ret = -EINVAL; + break; + } + + u4ExtraSize = sizeof(struct iw_pmksa); + prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); + if (!prExtraBuf) { + ret = -ENOMEM; + break; + } + + if (copy_from_user(prExtraBuf, iwr->u.data.pointer, + sizeof(struct iw_pmksa))) { + ret = -EFAULT; + } else { + switch (((struct iw_pmksa *)prExtraBuf)->cmd) { + case IW_PMKSA_ADD: + /* + * printk(KERN_INFO "IW_PMKSA_ADD [" + * MACSTR "]\n", MAC2STR(( + * (struct iw_pmksa *)pExtraBuf) + * ->bssid.sa_data)); + */ + { + wext_support_ioctl_SIOCSIWPMKSA_Action( + prDev, prExtraBuf, + IW_PMKSA_ADD, &ret); + } + break; + case IW_PMKSA_REMOVE: + /* + * printk(KERN_INFO "IW_PMKSA_REMOVE [" + * MACSTR "]\n", MAC2STR( + * ((struct iw_pmksa *)buf) + * ->bssid.sa_data)); + */ + break; + case IW_PMKSA_FLUSH: + /* + * printk(KERN_INFO + * "IW_PMKSA_FLUSH\n"); + */ + { + wext_support_ioctl_SIOCSIWPMKSA_Action( + prDev, prExtraBuf, + IW_PMKSA_FLUSH, &ret); + } + break; + default: + DBGLOG(INIT, INFO, + "UNKNOWN iw_pmksa command:%d\n", + ((struct iw_pmksa *)prExtraBuf) + ->cmd); + ret = -EFAULT; + break; + } + } + + if (prExtraBuf) { + kalMemFree(prExtraBuf, VIR_MEM_TYPE, + u4ExtraSize); + prExtraBuf = NULL; + } + } else if (iwr->u.data.length != 0) { + ret = -EINVAL; + break; + } +#endif + break; + +#endif + + default: + /* printk(KERN_NOTICE "unsupported IOCTL: 0x%x\n", i4Cmd); */ + ret = -EOPNOTSUPP; + break; + } + + /* printk("%d CMD:0x%x ret:%d\n", jiffies_to_msecs(jiffies), + * i4Cmd, ret); + */ + + return ret; +} /* wext_support_ioctl */ + +static void wext_support_ioctl_SIOCSIWGENIE( + IN struct net_device *prDev, IN char *prExtraBuf, + IN uint32_t u4ExtraSize) +{ + struct GLUE_INFO *prGlueInfo = *((struct GLUE_INFO **) + netdev_priv(prDev)); + uint32_t rStatus; + uint32_t u4BufLen; + +#if CFG_SUPPORT_WAPI + rStatus = kalIoctl(prGlueInfo, wlanoidSetWapiAssocInfo, prExtraBuf, + u4ExtraSize, FALSE, FALSE, TRUE, &u4BufLen); + if (rStatus != WLAN_STATUS_SUCCESS) { + /* do nothing */ + /* printk(KERN_INFO + * "[WSC] set WSC assoc info error:%x\n", + * rStatus); + */ + } +#endif + +} + +static void +wext_support_ioctl_SIOCSIWPMKSA_Action(IN struct net_device + *prDev, IN char *prExtraBuf, IN int ioMode, OUT int *ret) +{ + struct GLUE_INFO *prGlueInfo = *((struct GLUE_INFO **) + netdev_priv(prDev)); + uint32_t rStatus; + uint32_t u4BufLen; + struct PARAM_PMKID pmkid; + uint8_t ucBssIndex = AIS_DEFAULT_INDEX; + + pmkid.ucBssIdx = ucBssIndex; + + switch (ioMode) { + case IW_PMKSA_ADD: + kalMemCopy(pmkid.arBSSID, + ((struct iw_pmksa *)prExtraBuf)->bssid.sa_data, + PARAM_MAC_ADDR_LEN); + kalMemCopy(pmkid.arPMKID, + ((struct iw_pmksa *)prExtraBuf)->pmkid, IW_PMKID_LEN); + + rStatus = kalIoctl(prGlueInfo, wlanoidSetPmkid, &pmkid, + sizeof(struct PARAM_PMKID), + FALSE, FALSE, TRUE, &u4BufLen); + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(INIT, INFO, "add pmkid error:%x\n", rStatus); + break; + case IW_PMKSA_FLUSH: + rStatus = kalIoctl(prGlueInfo, wlanoidFlushPmkid, NULL, 0, + FALSE, FALSE, TRUE, &u4BufLen); + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(INIT, INFO, "flush pmkid error:%x\n", rStatus); + break; + default: + break; + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief To send an event (RAW socket pacekt) to user process actively. + * + * \param[in] prGlueInfo Glue layer info. + * \param[in] u4cmd Which event command we want to indicate to user process. + * \param[in] pData Data buffer to be indicated. + * \param[in] dataLen Available data size in pData. + * + * \return (none) + * + * \note Event is indicated to upper layer if cmd is supported and data is + * valid. Using of kernel symbol wireless_send_event(), which is defined + * in after WE-14 (2.4.20). + */ +/*----------------------------------------------------------------------------*/ +void +wext_indicate_wext_event(IN struct GLUE_INFO *prGlueInfo, + IN unsigned int u4Cmd, IN unsigned char *pucData, + IN unsigned int u4dataLen, + IN uint8_t ucBssIndex) +{ + union iwreq_data wrqu; + unsigned char *pucExtraInfo = NULL; +#if WIRELESS_EXT >= 15 + unsigned char *pucDesiredIE = NULL; + unsigned char aucExtraInfoBuf[200]; +#endif +#if WIRELESS_EXT < 18 + int i; +#endif + struct GL_WPA_INFO *prWpaInfo; + struct net_device *prDevHandler; + + memset(&wrqu, 0, sizeof(wrqu)); + + prWpaInfo = aisGetWpaInfo(prGlueInfo->prAdapter, + ucBssIndex); + + prDevHandler = + wlanGetNetDev(prGlueInfo, ucBssIndex); + + switch (u4Cmd) { + case SIOCGIWTXPOW: + memcpy(&wrqu.power, pucData, u4dataLen); + break; + case SIOCGIWSCAN: + complete_all(&prGlueInfo->rScanComp); + break; + + case SIOCGIWAP: + if (pucData) + kalMemCopy(&wrqu.ap_addr.sa_data, pucData, ETH_ALEN); + else + eth_zero_addr((u8 *)&wrqu.ap_addr.sa_data); + break; + + case IWEVASSOCREQIE: +#if WIRELESS_EXT < 15 + /* under WE-15, no suitable Event can be used */ + goto skip_indicate_event; +#else + /* do supplicant a favor, parse to the start of WPA/RSN IE */ + if (wextSrchDesiredWPAIE(pucData, u4dataLen, 0x30, + &pucDesiredIE)) { + /* RSN IE found */ + /* RSN IE found */ + } +#if 0 + else if (wextSrchDesiredWPSIE(pucData, u4dataLen, 0xDD, + &pucDesiredIE)) { + /* WPS IE found */ + /* WPS IE found */ + } +#endif + else if (wextSrchDesiredWPAIE(pucData, u4dataLen, 0xDD, + &pucDesiredIE)) { + /* WPA IE found */ + /* WPA IE found */ + } +#if CFG_SUPPORT_WAPI /* Android+ */ + else if (wextSrchDesiredWAPIIE(pucData, u4dataLen, + &pucDesiredIE)) { + /* printk("wextSrchDesiredWAPIIE!!\n"); */ + /* WAPI IE found */ + } +#endif + else { + /* no WPA/RSN IE found, skip this event */ + goto skip_indicate_event; + } + +#if WIRELESS_EXT < 18 + /* under WE-18, only IWEVCUSTOM can be used */ + u4Cmd = IWEVCUSTOM; + pucExtraInfo = aucExtraInfoBuf; + pucExtraInfo += sprintf(pucExtraInfo, "ASSOCINFO(ReqIEs="); + /* printk(KERN_DEBUG "assoc info buffer size needed:%d\n", + * infoElemLen * 2 + 17); + */ + /* translate binary string to hex string, requirement of + * IWEVCUSTOM + */ + for (i = 0; i < pucDesiredIE[1] + 2; ++i) + pucExtraInfo += sprintf(pucExtraInfo, "%02x", + pucDesiredIE[i]); + pucExtraInfo = aucExtraInfoBuf; + wrqu.data.length = 17 + (pucDesiredIE[1] + 2) * 2; +#else + /* IWEVASSOCREQIE, indicate binary string */ + pucExtraInfo = pucDesiredIE; + wrqu.data.length = pucDesiredIE[1] + 2; +#endif +#endif /* WIRELESS_EXT < 15 */ + break; + + case IWEVMICHAELMICFAILURE: +#if WIRELESS_EXT < 15 + /* under WE-15, no suitable Event can be used */ + goto skip_indicate_event; +#else + if (pucData) { + struct PARAM_AUTH_REQUEST *pAuthReq = + (struct PARAM_AUTH_REQUEST *) pucData; + uint32_t nleft = 0, nsize = 0; + /* under WE-18, only IWEVCUSTOM can be used */ + u4Cmd = IWEVCUSTOM; + pucExtraInfo = aucExtraInfoBuf; + nleft = sizeof(aucExtraInfoBuf); + nsize = snprintf(pucExtraInfo, nleft, + "MLME-MICHAELMICFAILURE.indication "); + if (nsize < nleft) { + nleft -= nsize; + pucExtraInfo += nsize; + } + + nsize = snprintf(pucExtraInfo, + nleft, "%s", + (pAuthReq->u4Flags == + PARAM_AUTH_REQUEST_GROUP_ERROR) ? + "groupcast " : "unicast "); + + if (nsize < nleft) { + nleft -= nsize; + pucExtraInfo += nsize; + } + wrqu.data.length = sizeof(aucExtraInfoBuf) - nleft; + pucExtraInfo = aucExtraInfoBuf; + } +#endif /* WIRELESS_EXT < 15 */ + break; + + case IWEVPMKIDCAND: + if (prWpaInfo->u4WpaVersion == + IW_AUTH_WPA_VERSION_WPA2 && + prWpaInfo->u4KeyMgmt == IW_AUTH_KEY_MGMT_802_1X) { + + /* only used in WPA2 */ +#if WIRELESS_EXT >= 18 + struct PARAM_PMKID_CANDIDATE *prPmkidCand = + (struct PARAM_PMKID_CANDIDATE *) pucData; + + struct iw_pmkid_cand rPmkidCand; + + pucExtraInfo = aucExtraInfoBuf; + + rPmkidCand.flags = prPmkidCand->u4Flags; + rPmkidCand.index = 0; + kalMemCopy(rPmkidCand.bssid.sa_data, + prPmkidCand->arBSSID, 6); + + kalMemCopy(pucExtraInfo, (uint8_t *) &rPmkidCand, + sizeof(struct iw_pmkid_cand)); + wrqu.data.length = sizeof(struct iw_pmkid_cand); + + /* pmkid canadidate list is supported after WE-18 */ + /* indicate struct iw_pmkid_cand */ +#else + /* printk(KERN_INFO + * "IWEVPMKIDCAND event skipped, WE < 18\n"); + */ + goto skip_indicate_event; +#endif + } else { + /* printk(KERN_INFO + * "IWEVPMKIDCAND event skipped, NOT WPA2\n"); + */ + goto skip_indicate_event; + } + break; + + case IWEVCUSTOM: + u4Cmd = IWEVCUSTOM; + pucExtraInfo = aucExtraInfoBuf; + kalMemCopy(pucExtraInfo, pucData, sizeof(struct PTA_IPC)); + wrqu.data.length = sizeof(struct PTA_IPC); + break; + + default: + /* printk(KERN_INFO "Unsupported wext event:%x\n", cmd); */ + goto skip_indicate_event; + } + + /* Send event to user space */ + wireless_send_event(prDevHandler, u4Cmd, &wrqu, + pucExtraInfo); +skip_indicate_event: + return; +} /* wext_indicate_wext_event */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief A method of struct net_device, to get the network interface + * statistical information. + * + * Whenever an application needs to get statistics for the interface, this + * method is called. This happens, for example, when ifconfig or netstat -i is + * run. + * + * \param[in] pDev Pointer to struct net_device. + * + * \return net_device_stats buffer pointer. + * + */ +/*----------------------------------------------------------------------------*/ +struct iw_statistics *wext_get_wireless_stats( + struct net_device *prDev) +{ + + uint32_t rStatus = WLAN_STATUS_FAILURE; + struct GLUE_INFO *prGlueInfo = NULL; + struct iw_statistics *pStats = NULL; + struct PARAM_LINK_SPEED_EX rLinkSpeed; + uint32_t bufLen = 0; + uint8_t ucBssIndex = AIS_DEFAULT_INDEX; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prDev)); + ASSERT(prGlueInfo); + if (!prGlueInfo) + goto stat_out; + + ucBssIndex = wlanGetBssIdx(prDev); + if (IS_BSS_INDEX_VALID(ucBssIndex)) + pStats = (struct iw_statistics *) + (&(prGlueInfo->rIwStats[ucBssIndex])); + + if (!prDev || !netif_carrier_ok(prDev)) { + /* network not connected */ + goto stat_out; + } + + rStatus = kalIoctlByBssIdx(prGlueInfo, + wlanoidQueryRssi, + &rLinkSpeed, sizeof(rLinkSpeed), + TRUE, TRUE, TRUE, + &bufLen, ucBssIndex); + +stat_out: + return pStats; +} /* wlan_get_wireless_stats */ + + +/* Standard call implementations */ +static int std_get_name(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra) +{ + DBGLOG(INIT, INFO, " mtk std ioctl is called.\n"); + return wext_get_name(prDev, NULL, (char *)(&(prData->name)), + sizeof(prData->name), NULL); +} + +static int std_set_freq(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra) +{ + DBGLOG(INIT, INFO, " mtk std ioctl is called.\n"); + return wext_set_freq(prDev, NULL, &(prData->freq), NULL); +} + +static int std_get_freq(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra) +{ + DBGLOG(INIT, INFO, " mtk std ioctl is called.\n"); + return wext_get_freq(prDev, NULL, &(prData->freq), NULL); +} + +static int std_set_mode(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra) +{ + DBGLOG(INIT, INFO, " mtk std ioctl is called.\n"); + return wext_set_mode(prDev, NULL, &prData->mode, NULL); +} + +static int std_get_mode(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra) +{ + DBGLOG(INIT, INFO, " mtk std ioctl is called.\n"); + return wext_get_mode(prDev, NULL, &prData->mode, NULL); +} + +static int std_set_ap(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra) +{ + int ret = 0; + + DBGLOG(INIT, INFO, " mtk std ioctl is called.\n"); + + if (prData->ap_addr.sa_data[0] == 0 && + prData->ap_addr.sa_data[1] == 0 && + prData->ap_addr.sa_data[2] == 0 && + prData->ap_addr.sa_data[3] == 0 && + prData->ap_addr.sa_data[4] == 0 + && prData->ap_addr.sa_data[5] == 0) { + /* WPA Supplicant will set 000000000000 in + * wpa_driver_wext_deinit(), do nothing here or + * disassoc again? + */ + ret = 0; + } else { + ret = wext_set_ap(prDev, NULL, &(prData->ap_addr), NULL); + } + return ret; +} + +static int std_get_ap(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra) +{ + DBGLOG(INIT, INFO, " mtk std ioctl is called.\n"); + return wext_get_ap(prDev, NULL, &(prData->ap_addr), NULL); +} + +static int std_get_rate(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra) +{ + DBGLOG(INIT, INFO, " mtk std ioctl is called.\n"); + return wext_get_rate(prDev, NULL, &prData->bitrate, NULL); +} + +static int std_set_rts(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra) +{ + DBGLOG(INIT, INFO, " mtk std ioctl is called.\n"); + return wext_set_rts(prDev, NULL, &(prData->rts), NULL); +} + +static int std_get_rts(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra) +{ + DBGLOG(INIT, INFO, " mtk std ioctl is called.\n"); + return wext_get_rts(prDev, NULL, &prData->rts, NULL); +} + +static int std_get_frag(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra) +{ + DBGLOG(INIT, INFO, " mtk std ioctl is called.\n"); + return wext_get_frag(prDev, NULL, &prData->frag, NULL); +} + +static int std_set_txpow(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra) +{ + DBGLOG(INIT, INFO, " mtk std ioctl is called.\n"); + return wext_set_txpow(prDev, NULL, &(prData->txpower), NULL); +} + +static int std_get_txpow(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra) +{ + DBGLOG(INIT, INFO, " mtk std ioctl is called.\n"); + return wext_get_txpow(prDev, NULL, &prData->txpower, NULL); +} + +static int std_set_power(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra) +{ + DBGLOG(INIT, INFO, " mtk std ioctl is called.\n"); + return wext_set_power(prDev, NULL, &prData->power, NULL); +} + +static int std_get_power(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra) +{ + DBGLOG(INIT, INFO, " mtk std ioctl is called.\n"); + return wext_get_power(prDev, NULL, &prData->power, NULL); +} + +static int std_get_range(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra) +{ + DBGLOG(INIT, INFO, " mtk std ioctl is called.\n"); + return wext_get_range(prDev, NULL, &(prData->data), + pcExtra); +} + +static int std_set_priv(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra) +{ + DBGLOG(INIT, INFO, " mtk std ioctl is called.\n"); +#ifdef CONFIG_COMPAT + if (rIwReqInfo->flags & IW_REQUEST_FLAG_COMPAT) { + int ret = 0; + struct compat_iw_point *iwp_compat = NULL; + struct iw_point iwp; + + iwp_compat = (struct compat_iw_point *) &prData->data; + iwp.pointer = compat_ptr(iwp_compat->pointer); + iwp.length = iwp_compat->length; + iwp.flags = iwp_compat->flags; + + ret = wext_set_country(prDev, &iwp); + + iwp_compat->pointer = ptr_to_compat(iwp.pointer); + iwp_compat->length = iwp.length; + iwp_compat->flags = iwp.flags; + + return ret; + } +#endif /* CONFIG_COMPAT */ + return wext_set_country(prDev, &(prData->data)); +} + +static int std_get_priv(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra) +{ + DBGLOG(INIT, INFO, " mtk std ioctl is called.\n"); + return wext_get_priv(prDev, &(prData->data)); +} + +static int std_set_scan(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra) +{ + DBGLOG(INIT, INFO, " mtk std ioctl is called.\n"); + return wext_set_scan(prDev, NULL, NULL, NULL); +} + +static int std_set_mlme(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra) +{ + DBGLOG(INIT, INFO, " mtk std ioctl is called.\n"); + return wext_set_mlme(prDev, NULL, &(prData->data), pcExtra); +} + +static int std_get_scan(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra) +{ + DBGLOG(INIT, INFO, " mtk std ioctl is called.\n"); + return wext_get_scan(prDev, NULL, &(prData->data), pcExtra); +} + +static int std_set_essid(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra) +{ + DBGLOG(INIT, INFO, " mtk std ioctl is called.\n"); + return wext_set_essid(prDev, NULL, &(prData->essid), pcExtra); +} + +static int std_get_essid(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra) +{ + DBGLOG(INIT, INFO, " mtk std ioctl is called.\n"); + return wext_get_essid(prDev, NULL, &(prData->essid), pcExtra); +} + +static int std_set_encode(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra) +{ + DBGLOG(INIT, INFO, " mtk std ioctl is called.\n"); + return wext_set_encode(prDev, NULL, + &(prData->encoding), + pcExtra); +} + +static int std_get_encode(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra) +{ + DBGLOG(INIT, INFO, " mtk std ioctl is called.\n"); + return wext_get_encode(prDev, NULL, &(prData->encoding), NULL); +} + +static int std_set_auth(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra) +{ + DBGLOG(INIT, INFO, " mtk std ioctl is called.\n"); + return wext_set_auth(prDev, NULL, &(prData->param), NULL); +} + +#if WIRELESS_EXT > 17 +static int std_set_genie(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra) +{ + uint32_t u4ExtraSize = prData->data.length; + struct GLUE_INFO *prGlueInfo = NULL; + + DBGLOG(INIT, INFO, " mtk std ioctl is called.\n"); + +#if CFG_SUPPORT_WAPI + /* The max wapi ie buffer */ + if (u4ExtraSize > 42) + return -EINVAL; +#endif + + if (prData->data.pointer) { + u4ExtraSize = prData->data.length; + prGlueInfo = *((struct GLUE_INFO **) + netdev_priv(prDev)); + wext_support_ioctl_SIOCSIWGENIE( + prDev, pcExtra, + u4ExtraSize); + } + + return 0; +} +#endif /* end of WIRELESS_EXT */ + +static int std_set_encode_ext(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra) +{ + DBGLOG(INIT, INFO, " mtk std ioctl is called.\n"); + return wext_set_encode_ext(prDev, NULL, &(prData->encoding), + pcExtra); +} + +static int std_set_pmska(struct net_device *prDev, + struct iw_request_info *rIwReqInfo, + union iwreq_data *prData, + char *pcExtra) +{ + int ret = 0; + + DBGLOG(INIT, INFO, " mtk std ioctl is called.\n"); + + switch (((struct iw_pmksa *)pcExtra)->cmd) { + case IW_PMKSA_ADD: + wext_support_ioctl_SIOCSIWPMKSA_Action( + prDev, pcExtra, + IW_PMKSA_ADD, &ret); + break; + case IW_PMKSA_REMOVE: + break; + case IW_PMKSA_FLUSH: + wext_support_ioctl_SIOCSIWPMKSA_Action( + prDev, pcExtra, + IW_PMKSA_FLUSH, &ret); + break; + default: + DBGLOG(INIT, INFO, + "UNKNOWN iw_pmksa command:%d\n", + ((struct iw_pmksa *)pcExtra) + ->cmd); + ret = -EFAULT; + break; + } + return ret; +} + + +#endif /* WIRELESS_EXT */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_wext_priv.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_wext_priv.c new file mode 100644 index 0000000000000000000000000000000000000000..9e8f9aab6a095231aead9485d78f4698dce5befe --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/gl_wext_priv.c @@ -0,0 +1,14241 @@ +/******************************************************************************* + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux + * /gl_wext_priv.c#8 + */ + +/*! \file gl_wext_priv.c + * \brief This file includes private ioctl support. + */ + + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" +#include "gl_os.h" +#include "gl_wext_priv.h" + +#if CFG_SUPPORT_QA_TOOL +#include "gl_ate_agent.h" +#include "gl_qa_agent.h" +#endif + +#if CFG_SUPPORT_WAPI +#include "gl_sec.h" +#endif +#if CFG_ENABLE_WIFI_DIRECT +#include "gl_p2p_os.h" +#endif + +/* + * #if CFG_SUPPORT_QA_TOOL + * extern UINT_16 g_u2DumpIndex; + * #endif + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#define NUM_SUPPORTED_OIDS (sizeof(arWlanOidReqTable) / \ + sizeof(struct WLAN_REQ_ENTRY)) +#define CMD_OID_BUF_LENGTH 4096 + +#if (CFG_SUPPORT_TWT == 1) +#define CMD_TWT_ACTION_TEN_PARAMS 10 +#define CMD_TWT_ACTION_THREE_PARAMS 3 +#define CMD_TWT_MAX_PARAMS CMD_TWT_ACTION_TEN_PARAMS +#endif + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +static int +priv_get_ndis(IN struct net_device *prNetDev, + IN struct NDIS_TRANSPORT_STRUCT *prNdisReq, + OUT uint32_t *pu4OutputLen); + +static int +priv_set_ndis(IN struct net_device *prNetDev, + IN struct NDIS_TRANSPORT_STRUCT *prNdisReq, + OUT uint32_t *pu4OutputLen); + +#if 0 /* CFG_SUPPORT_WPS */ +static int +priv_set_appie(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN union iwreq_data *prIwReqData, OUT char *pcExtra); + +static int +priv_set_filter(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN union iwreq_data *prIwReqData, OUT char *pcExtra); +#endif /* CFG_SUPPORT_WPS */ + +static u_int8_t reqSearchSupportedOidEntry(IN uint32_t rOid, + OUT struct WLAN_REQ_ENTRY **ppWlanReqEntry); + +#if 0 +static uint32_t +reqExtQueryConfiguration(IN struct GLUE_INFO *prGlueInfo, + OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen); + +static uint32_t +reqExtSetConfiguration(IN struct GLUE_INFO *prGlueInfo, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); +#endif + +static uint32_t +reqExtSetAcpiDevicePowerState(IN struct GLUE_INFO + *prGlueInfo, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen); + +#if CFG_SUPPORT_DYNAMIC_PWR_LIMIT +/* dynamic tx power control */ +static int priv_driver_set_power_control(IN struct net_device *prNetDev, + IN char *pcCommand, + IN int i4TotalLen); +#endif +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ +static uint8_t aucOidBuf[CMD_OID_BUF_LENGTH] = { 0 }; + +/* OID processing table */ +/* Order is important here because the OIDs should be in order of + * increasing value for binary searching. + */ +static struct WLAN_REQ_ENTRY arWlanOidReqTable[] = { +#if 0 + { + (NDIS_OID)rOid, + (uint8_t *)pucOidName, + fgQryBufLenChecking, fgSetBufLenChecking, + fgIsHandleInGlueLayerOnly, u4InfoBufLen, + pfOidQueryHandler, + pfOidSetHandler + } +#endif + /* General Operational Characteristics */ + + /* Ethernet Operational Characteristics */ + { + OID_802_3_CURRENT_ADDRESS, + DISP_STRING("OID_802_3_CURRENT_ADDRESS"), + TRUE, TRUE, ENUM_OID_DRIVER_CORE, 6, + (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryCurrentAddr, + NULL + }, + + /* OID_802_3_MULTICAST_LIST */ + /* OID_802_3_MAXIMUM_LIST_SIZE */ + /* Ethernet Statistics */ + + /* NDIS 802.11 Wireless LAN OIDs */ + { + OID_802_11_SUPPORTED_RATES, + DISP_STRING("OID_802_11_SUPPORTED_RATES"), + TRUE, FALSE, ENUM_OID_DRIVER_CORE, + (sizeof(uint8_t) * PARAM_MAX_LEN_RATES_EX), + (PFN_OID_HANDLER_FUNC_REQ) wlanoidQuerySupportedRates, + NULL + } + , + /* + * {OID_802_11_CONFIGURATION, + * DISP_STRING("OID_802_11_CONFIGURATION"), + * TRUE, TRUE, ENUM_OID_GLUE_EXTENSION, + * sizeof(struct PARAM_802_11_CONFIG), + * (PFN_OID_HANDLER_FUNC_REQ)reqExtQueryConfiguration, + * (PFN_OID_HANDLER_FUNC_REQ)reqExtSetConfiguration}, + */ + { + OID_PNP_SET_POWER, + DISP_STRING("OID_PNP_SET_POWER"), + TRUE, FALSE, ENUM_OID_GLUE_EXTENSION, + sizeof(enum PARAM_DEVICE_POWER_STATE), + NULL, + (PFN_OID_HANDLER_FUNC_REQ) reqExtSetAcpiDevicePowerState + } + , + + /* Custom OIDs */ + { + OID_CUSTOM_OID_INTERFACE_VERSION, + DISP_STRING("OID_CUSTOM_OID_INTERFACE_VERSION"), + TRUE, FALSE, ENUM_OID_DRIVER_CORE, 4, + (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryOidInterfaceVersion, + NULL + } + , +#if 0 +#if PTA_ENABLED + { + OID_CUSTOM_BT_COEXIST_CTRL, + DISP_STRING("OID_CUSTOM_BT_COEXIST_CTRL"), + FALSE, TRUE, ENUM_OID_DRIVER_CORE, + sizeof(PARAM_CUSTOM_BT_COEXIST_T), + NULL, + (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetBtCoexistCtrl + }, +#endif + + { + OID_CUSTOM_POWER_MANAGEMENT_PROFILE, + DISP_STRING("OID_CUSTOM_POWER_MANAGEMENT_PROFILE"), + FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, + (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryPwrMgmtProfParam, + (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetPwrMgmtProfParam}, + { + OID_CUSTOM_PATTERN_CONFIG, + DISP_STRING("OID_CUSTOM_PATTERN_CONFIG"), + TRUE, TRUE, ENUM_OID_DRIVER_CORE, + sizeof(PARAM_CUSTOM_PATTERN_SEARCH_CONFIG_STRUCT_T), + NULL, + (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetPatternConfig + }, + { + OID_CUSTOM_BG_SSID_SEARCH_CONFIG, + DISP_STRING("OID_CUSTOM_BG_SSID_SEARCH_CONFIG"), + FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, + NULL, + (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetBgSsidParam + }, + { + OID_CUSTOM_VOIP_SETUP, + DISP_STRING("OID_CUSTOM_VOIP_SETUP"), + TRUE, TRUE, ENUM_OID_DRIVER_CORE, 4, + (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryVoipConnectionStatus, + (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetVoipConnectionStatus + }, + { + OID_CUSTOM_ADD_TS, + DISP_STRING("OID_CUSTOM_ADD_TS"), + TRUE, TRUE, ENUM_OID_DRIVER_CORE, 4, + NULL, + (PFN_OID_HANDLER_FUNC_REQ)wlanoidAddTS + }, + { + OID_CUSTOM_DEL_TS, + DISP_STRING("OID_CUSTOM_DEL_TS"), + TRUE, TRUE, ENUM_OID_DRIVER_CORE, 4, + NULL, + (PFN_OID_HANDLER_FUNC_REQ)wlanoidDelTS + }, + +#if CFG_LP_PATTERN_SEARCH_SLT + { + OID_CUSTOM_SLT, + DISP_STRING("OID_CUSTOM_SLT"), + FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, + (PFN_OID_HANDLER_FUNC_REQ)wlanoidQuerySltResult, + (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetSltMode + }, +#endif + + { + OID_CUSTOM_ROAMING_EN, + DISP_STRING("OID_CUSTOM_ROAMING_EN"), + TRUE, TRUE, ENUM_OID_DRIVER_CORE, 4, + (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryRoamingFunction, + (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetRoamingFunction}, + { + OID_CUSTOM_WMM_PS_TEST, + DISP_STRING("OID_CUSTOM_WMM_PS_TEST"), + TRUE, TRUE, ENUM_OID_DRIVER_CORE, 4, + NULL, + (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetWiFiWmmPsTest + }, + { + OID_CUSTOM_COUNTRY_STRING, + DISP_STRING("OID_CUSTOM_COUNTRY_STRING"), + FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, + (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryCurrentCountry, + (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetCurrentCountry + }, + +#if CFG_SUPPORT_802_11D + { + OID_CUSTOM_MULTI_DOMAIN_CAPABILITY, + DISP_STRING("OID_CUSTOM_MULTI_DOMAIN_CAPABILITY"), + FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, + (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryMultiDomainCap, + (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetMultiDomainCap + }, +#endif + + { + OID_CUSTOM_GPIO2_MODE, + DISP_STRING("OID_CUSTOM_GPIO2_MODE"), + FALSE, TRUE, ENUM_OID_DRIVER_CORE, + sizeof(ENUM_PARAM_GPIO2_MODE_T), + NULL, + (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetGPIO2Mode}, + { + OID_CUSTOM_CONTINUOUS_POLL, + DISP_STRING("OID_CUSTOM_CONTINUOUS_POLL"), + FALSE, TRUE, ENUM_OID_DRIVER_CORE, + sizeof(PARAM_CONTINUOUS_POLL_T), + (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryContinuousPollInterval, + (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetContinuousPollProfile + }, + { + OID_CUSTOM_DISABLE_BEACON_DETECTION, + DISP_STRING("OID_CUSTOM_DISABLE_BEACON_DETECTION"), + FALSE, TRUE, ENUM_OID_DRIVER_CORE, 4, + (PFN_OID_HANDLER_FUNC_REQ) + wlanoidQueryDisableBeaconDetectionFunc, + (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetDisableBeaconDetectionFunc + }, + + /* WPS */ + { + OID_CUSTOM_DISABLE_PRIVACY_CHECK, + DISP_STRING("OID_CUSTOM_DISABLE_PRIVACY_CHECK"), + FALSE, TRUE, ENUM_OID_DRIVER_CORE, 4, + NULL, + (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetDisablePriavcyCheck + }, +#endif + + { + OID_CUSTOM_MCR_RW, + DISP_STRING("OID_CUSTOM_MCR_RW"), + TRUE, TRUE, ENUM_OID_DRIVER_CORE, + sizeof(struct PARAM_CUSTOM_MCR_RW_STRUCT), + (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryMcrRead, + (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetMcrWrite} + , + + { + OID_CUSTOM_EEPROM_RW, + DISP_STRING("OID_CUSTOM_EEPROM_RW"), + TRUE, TRUE, ENUM_OID_DRIVER_CORE, + sizeof(struct PARAM_CUSTOM_EEPROM_RW_STRUCT), + (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryEepromRead, + (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetEepromWrite + } + , + + { + OID_CUSTOM_SW_CTRL, + DISP_STRING("OID_CUSTOM_SW_CTRL"), + TRUE, TRUE, ENUM_OID_DRIVER_CORE, + sizeof(struct PARAM_CUSTOM_SW_CTRL_STRUCT), + (PFN_OID_HANDLER_FUNC_REQ) wlanoidQuerySwCtrlRead, + (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetSwCtrlWrite + } + , + + { + OID_CUSTOM_MEM_DUMP, + DISP_STRING("OID_CUSTOM_MEM_DUMP"), + TRUE, TRUE, ENUM_OID_DRIVER_CORE, + sizeof(struct PARAM_CUSTOM_MEM_DUMP_STRUCT), + (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryMemDump, + NULL + } + , + + { + OID_CUSTOM_TEST_MODE, + DISP_STRING("OID_CUSTOM_TEST_MODE"), + FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, + NULL, + (PFN_OID_HANDLER_FUNC_REQ) wlanoidRftestSetTestMode + } + , + +#if 0 + { + OID_CUSTOM_TEST_RX_STATUS, + DISP_STRING("OID_CUSTOM_TEST_RX_STATUS"), + FALSE, TRUE, ENUM_OID_DRIVER_CORE, + sizeof(struct PARAM_CUSTOM_RFTEST_RX_STATUS_STRUCT), + (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryRfTestRxStatus, + NULL + }, + { + OID_CUSTOM_TEST_TX_STATUS, + DISP_STRING("OID_CUSTOM_TEST_TX_STATUS"), + FALSE, TRUE, ENUM_OID_DRIVER_CORE, + sizeof(struct PARAM_CUSTOM_RFTEST_TX_STATUS_STRUCT), + (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryRfTestTxStatus, + NULL + }, +#endif + { + OID_CUSTOM_ABORT_TEST_MODE, + DISP_STRING("OID_CUSTOM_ABORT_TEST_MODE"), + FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, + NULL, + (PFN_OID_HANDLER_FUNC_REQ) wlanoidRftestSetAbortTestMode + } + , + { + OID_CUSTOM_MTK_WIFI_TEST, + DISP_STRING("OID_CUSTOM_MTK_WIFI_TEST"), + /* PeiHsuan Temp Remove this check for workaround Gen2/Gen3 EM + * Mode Modification + */ + /* TRUE, TRUE, ENUM_OID_DRIVER_CORE, + * sizeof(PARAM_MTK_WIFI_TEST_STRUCT_T), + */ + FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, + (PFN_OID_HANDLER_FUNC_REQ) wlanoidRftestQueryAutoTest, + (PFN_OID_HANDLER_FUNC_REQ) wlanoidRftestSetAutoTest + } + , + { + OID_CUSTOM_TEST_ICAP_MODE, + DISP_STRING("OID_CUSTOM_TEST_ICAP_MODE"), + FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, + NULL, + (PFN_OID_HANDLER_FUNC_REQ) wlanoidRftestSetTestIcapMode + } + , + + /* OID_CUSTOM_EMULATION_VERSION_CONTROL */ + + /* BWCS */ +#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS + { + OID_CUSTOM_BWCS_CMD, + DISP_STRING("OID_CUSTOM_BWCS_CMD"), + FALSE, FALSE, ENUM_OID_DRIVER_CORE, sizeof(struct PTA_IPC), + (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryBT, + (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetBT + } + , +#endif +#if 0 + { + OID_CUSTOM_SINGLE_ANTENNA, + DISP_STRING("OID_CUSTOM_SINGLE_ANTENNA"), + FALSE, FALSE, ENUM_OID_DRIVER_CORE, 4, + (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryBtSingleAntenna, + (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetBtSingleAntenna + }, + { + OID_CUSTOM_SET_PTA, + DISP_STRING("OID_CUSTOM_SET_PTA"), + FALSE, FALSE, ENUM_OID_DRIVER_CORE, 4, + (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryPta, + (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetPta + }, +#endif + + { + OID_CUSTOM_MTK_NVRAM_RW, + DISP_STRING("OID_CUSTOM_MTK_NVRAM_RW"), + TRUE, TRUE, ENUM_OID_DRIVER_CORE, + sizeof(struct PARAM_CUSTOM_EEPROM_RW_STRUCT), + (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryNvramRead, + (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetNvramWrite} + , + + { + OID_CUSTOM_CFG_SRC_TYPE, + DISP_STRING("OID_CUSTOM_CFG_SRC_TYPE"), + FALSE, FALSE, ENUM_OID_DRIVER_CORE, + sizeof(enum ENUM_CFG_SRC_TYPE), + (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryCfgSrcType, + NULL + } + , + + { + OID_CUSTOM_EEPROM_TYPE, + DISP_STRING("OID_CUSTOM_EEPROM_TYPE"), + FALSE, FALSE, ENUM_OID_DRIVER_CORE, + sizeof(enum ENUM_EEPROM_TYPE), + (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryEepromType, + NULL + } + , + +#if CFG_SUPPORT_WAPI + { + OID_802_11_WAPI_MODE, + DISP_STRING("OID_802_11_WAPI_MODE"), + FALSE, TRUE, ENUM_OID_DRIVER_CORE, 4, + NULL, + (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetWapiMode + } + , + { + OID_802_11_WAPI_ASSOC_INFO, + DISP_STRING("OID_802_11_WAPI_ASSOC_INFO"), + FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, + NULL, + (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetWapiAssocInfo + } + , + { + OID_802_11_SET_WAPI_KEY, + DISP_STRING("OID_802_11_SET_WAPI_KEY"), + FALSE, FALSE, ENUM_OID_DRIVER_CORE, + sizeof(struct PARAM_WPI_KEY), + NULL, + (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetWapiKey + } + , +#endif + +#if CFG_SUPPORT_LOWLATENCY_MODE + /* Note: we should put following code in order */ + { + OID_CUSTOM_LOWLATENCY_MODE, /* 0xFFA0CC00 */ + DISP_STRING("OID_CUSTOM_LOWLATENCY_MODE"), + FALSE, FALSE, ENUM_OID_DRIVER_CORE, sizeof(uint32_t), + NULL, + (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetLowLatencyMode + } + , +#endif /* CFG_SUPPORT_LOWLATENCY_MODE */ + + { + OID_IPC_WIFI_LOG_UI, + DISP_STRING("OID_IPC_WIFI_LOG_UI"), + FALSE, + FALSE, + ENUM_OID_DRIVER_CORE, + sizeof(struct PARAM_WIFI_LOG_LEVEL_UI), + (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryWifiLogLevelSupport, + NULL + } + , + + { + OID_IPC_WIFI_LOG_LEVEL, + DISP_STRING("OID_IPC_WIFI_LOG_LEVEL"), + FALSE, + FALSE, + ENUM_OID_DRIVER_CORE, + sizeof(struct PARAM_WIFI_LOG_LEVEL), + (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryWifiLogLevel, + (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetWifiLogLevel + } + , +#if CFG_SUPPORT_ANT_SWAP + { + OID_CUSTOM_QUERY_ANT_SWAP_CAPABILITY, /* 0xFFA0CD00 */ + DISP_STRING("OID_CUSTOM_QUERY_ANT_SWAP_CAPABILITY"), + FALSE, FALSE, ENUM_OID_DRIVER_CORE, sizeof(uint32_t), + (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryAntennaSwap, + NULL + } + , +#endif +}; + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +static int compat_priv(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN union iwreq_data *prIwReqData, IN char *pcExtra, + int (*priv_func)(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN union iwreq_data *prIwReqData, IN char *pcExtra)) +{ + struct iw_point *prIwp; + int ret = 0; +#ifdef CONFIG_COMPAT + struct compat_iw_point *iwp_compat = NULL; + struct iw_point iwp = {0}; +#endif + + if (!prIwReqData) + return -EINVAL; + +#ifdef CONFIG_COMPAT + if (prIwReqInfo->flags & IW_REQUEST_FLAG_COMPAT) { + iwp_compat = (struct compat_iw_point *) &prIwReqData->data; + iwp.pointer = compat_ptr(iwp_compat->pointer); + iwp.length = iwp_compat->length; + iwp.flags = iwp_compat->flags; + prIwp = &iwp; + } else +#endif + prIwp = &prIwReqData->data; + + + ret = priv_func(prNetDev, prIwReqInfo, + (union iwreq_data *)prIwp, pcExtra); + +#ifdef CONFIG_COMPAT + if (prIwReqInfo->flags & IW_REQUEST_FLAG_COMPAT) { + iwp_compat->pointer = ptr_to_compat(iwp.pointer); + iwp_compat->length = iwp.length; + iwp_compat->flags = iwp.flags; + } +#endif + return ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Dispatching function for private ioctl region (SIOCIWFIRSTPRIV ~ + * SIOCIWLASTPRIV). + * + * \param[in] prNetDev Net device requested. + * \param[in] prIfReq Pointer to ifreq structure. + * \param[in] i4Cmd Command ID between SIOCIWFIRSTPRIV and SIOCIWLASTPRIV. + * + * \retval 0 for success. + * \retval -EOPNOTSUPP If cmd is not supported. + * \retval -EFAULT For fail. + * + */ +/*----------------------------------------------------------------------------*/ +int priv_support_ioctl(IN struct net_device *prNetDev, + IN OUT struct ifreq *prIfReq, IN int i4Cmd) +{ + /* prIfReq is verified in the caller function wlanDoIOCTL() */ + struct iwreq *prIwReq = (struct iwreq *)prIfReq; + struct iw_request_info rIwReqInfo; + + /* prNetDev is verified in the caller function wlanDoIOCTL() */ + + /* Prepare the call */ + rIwReqInfo.cmd = (__u16) i4Cmd; + rIwReqInfo.flags = 0; + + switch (i4Cmd) { + case IOCTL_SET_INT: + /* NOTE(Kevin): 1/3 INT Type <= IFNAMSIZ, so we don't need + * copy_from/to_user() + */ + return priv_set_int(prNetDev, &rIwReqInfo, &(prIwReq->u), + (char *) &(prIwReq->u)); + + case IOCTL_GET_INT: + /* NOTE(Kevin): 1/3 INT Type <= IFNAMSIZ, so we don't need + * copy_from/to_user() + */ + return priv_get_int(prNetDev, &rIwReqInfo, &(prIwReq->u), + (char *) &(prIwReq->u)); + + case IOCTL_SET_STRUCT: + case IOCTL_SET_STRUCT_FOR_EM: + return priv_set_struct(prNetDev, &rIwReqInfo, &prIwReq->u, + (char *) &(prIwReq->u)); + + case IOCTL_GET_STRUCT: + return priv_get_struct(prNetDev, &rIwReqInfo, &prIwReq->u, + (char *) &(prIwReq->u)); + +#if (CFG_SUPPORT_QA_TOOL) + case IOCTL_QA_TOOL_DAEMON: + case SIOCDEVPRIVATE+2: + return priv_qa_agent(prNetDev, &rIwReqInfo, &(prIwReq->u), + (char *) &(prIwReq->u)); +#endif + + /* This case need to fall through */ + case IOC_AP_GET_STA_LIST: + /* This case need to fall through */ + case IOC_AP_SET_MAC_FLTR: + /* This case need to fall through */ + case IOC_AP_SET_CFG: + /* This case need to fall through */ + case IOC_AP_STA_DISASSOC: + /* This case need to fall through */ + case IOC_AP_SET_NSS: + return priv_set_ap(prNetDev, &rIwReqInfo, &(prIwReq->u), + (char *) &(prIwReq->u)); + + case IOCTL_GET_STR: + + default: + return -EOPNOTSUPP; + + } /* end of switch */ + +} /* priv_support_ioctl */ + +#if CFG_SUPPORT_BATCH_SCAN + +struct EVENT_BATCH_RESULT + g_rEventBatchResult[CFG_BATCH_MAX_MSCAN]; + +uint32_t batchChannelNum2Freq(uint32_t u4ChannelNum) +{ + uint32_t u4ChannelInMHz; + + if (u4ChannelNum >= 1 && u4ChannelNum <= 13) + u4ChannelInMHz = 2412 + (u4ChannelNum - 1) * 5; + else if (u4ChannelNum == 14) + u4ChannelInMHz = 2484; + else if (u4ChannelNum == 133) + u4ChannelInMHz = 3665; /* 802.11y */ + else if (u4ChannelNum == 137) + u4ChannelInMHz = 3685; /* 802.11y */ + else if (u4ChannelNum >= 34 && u4ChannelNum <= 165) + u4ChannelInMHz = 5000 + u4ChannelNum * 5; + else if (u4ChannelNum >= 183 && u4ChannelNum <= 196) + u4ChannelInMHz = 4000 + u4ChannelNum * 5; + else + u4ChannelInMHz = 0; + + return u4ChannelInMHz; +} + +#define TMP_TEXT_LEN_S 40 +#define TMP_TEXT_LEN_L 60 +static uint8_t text1[TMP_TEXT_LEN_S], text2[TMP_TEXT_LEN_L], + text3[TMP_TEXT_LEN_L]; /* A safe len */ + +uint32_t +batchConvertResult(IN struct EVENT_BATCH_RESULT + *prEventBatchResult, + OUT void *pvBuffer, IN uint32_t u4MaxBufferLen, + OUT uint32_t *pu4RetLen) +{ + int8_t *p = pvBuffer; + int8_t ssid[ELEM_MAX_LEN_SSID + 1]; + int32_t nsize, nsize1, nsize2, nsize3, scancount; + int32_t i, j, nleft; + uint32_t freq; + + struct EVENT_BATCH_RESULT_ENTRY *prEntry; + struct EVENT_BATCH_RESULT *pBr; + + nsize = 0; + nleft = u4MaxBufferLen - 5; /* -5 for "----\n" */ + + pBr = prEventBatchResult; + scancount = 0; + for (j = 0; j < CFG_BATCH_MAX_MSCAN; j++) { + scancount += pBr->ucScanCount; + pBr++; + } + + nsize1 = kalSnprintf(text1, TMP_TEXT_LEN_S, + "scancount=%d\nnextcount=%d\n", scancount, + scancount); + if (nsize1 < nleft) { + kalStrnCpy(p, text1, nsize1); + p += nsize1; + nleft -= nsize1; + } else + goto short_buf; + + pBr = prEventBatchResult; + for (j = 0; j < CFG_BATCH_MAX_MSCAN; j++) { + DBGLOG(SCN, TRACE, + "convert mscan = %d, apcount=%d, nleft=%d\n", j, + pBr->ucScanCount, nleft); + + if (pBr->ucScanCount == 0) { + pBr++; + continue; + } + + nleft -= 5; /* -5 for "####\n" */ + + /* We only support one round scan result now. */ + nsize1 = kalSnprintf(text1, TMP_TEXT_LEN_S, "apcount=%d\n", + pBr->ucScanCount); + if (nsize1 < nleft) { + kalStrnCpy(p, text1, nsize1); + p += nsize1; + nleft -= nsize1; + } else + goto short_buf; + + for (i = 0; i < pBr->ucScanCount; i++) { + prEntry = &pBr->arBatchResult[i]; + + nsize1 = kalSnprintf(text1, TMP_TEXT_LEN_S, + "bssid=" MACSTR "\n", + MAC2STR(prEntry->aucBssid)); + kalMemCopy(ssid, + prEntry->aucSSID, + (prEntry->ucSSIDLen < ELEM_MAX_LEN_SSID ? + prEntry->ucSSIDLen : ELEM_MAX_LEN_SSID)); + ssid[(prEntry->ucSSIDLen < + (ELEM_MAX_LEN_SSID - 1) ? prEntry->ucSSIDLen : + (ELEM_MAX_LEN_SSID - 1))] = '\0'; + nsize2 = kalSnprintf(text2, TMP_TEXT_LEN_L, "ssid=%s\n", + ssid); + + freq = batchChannelNum2Freq(prEntry->ucFreq); + nsize3 = + kalSnprintf(text3, TMP_TEXT_LEN_L, + "freq=%u\nlevel=%d\ndist=%u\ndistSd=%u\n====\n", + freq, prEntry->cRssi, prEntry->u4Dist, + prEntry->u4Distsd); + + nsize = nsize1 + nsize2 + nsize3; + if (nsize < nleft) { + + kalStrnCpy(p, text1, TMP_TEXT_LEN_S); + p += nsize1; + + kalStrnCpy(p, text2, TMP_TEXT_LEN_L); + p += nsize2; + + kalStrnCpy(p, text3, TMP_TEXT_LEN_L); + p += nsize3; + + nleft -= nsize; + } else { + DBGLOG(SCN, TRACE, + "Warning: Early break! (%d)\n", i); + break; /* discard following entries, + * TODO: apcount? + */ + } + } + + nsize1 = kalSnprintf(text1, TMP_TEXT_LEN_S, "%s", "####\n"); + if (nsize1 < nleft) { + kalStrnCpy(p, text1, nsize1); + p += nsize1; + nleft -= nsize1; + } + + pBr++; + } + + nsize1 = kalSnprintf(text1, TMP_TEXT_LEN_S, "%s", "----\n"); + if (nsize1 < nleft) { + kalStrnCpy(p, text1, nsize1); + p += nsize1; + nleft -= nsize1; + } + + *pu4RetLen = u4MaxBufferLen - nleft; + DBGLOG(SCN, TRACE, "total len = %d (max len = %d)\n", + *pu4RetLen, u4MaxBufferLen); + + return WLAN_STATUS_SUCCESS; + +short_buf: + DBGLOG(SCN, TRACE, + "Short buffer issue! %d > %d, %s\n", + u4MaxBufferLen + (nsize - nleft), u4MaxBufferLen, + (char *)pvBuffer); + return WLAN_STATUS_INVALID_LENGTH; +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Private ioctl set int handler. + * + * \param[in] prNetDev Net device requested. + * \param[in] prIwReqInfo Pointer to iwreq structure. + * \param[in] prIwReqData The ioctl data structure, use the field of + * sub-command. + * \param[in] pcExtra The buffer with input value + * + * \retval 0 For success. + * \retval -EOPNOTSUPP If cmd is not supported. + * \retval -EINVAL If a value is out of range. + * + */ +/*----------------------------------------------------------------------------*/ +int +__priv_set_int(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN union iwreq_data *prIwReqData, IN char *pcExtra) +{ + uint32_t u4SubCmd; + uint32_t *pu4IntBuf; + struct NDIS_TRANSPORT_STRUCT *prNdisReq; + struct GLUE_INFO *prGlueInfo; + uint32_t u4BufLen = 0; + int status = 0; + struct PTA_IPC *prPtaIpc; + + ASSERT(prNetDev); + ASSERT(prIwReqInfo); + ASSERT(prIwReqData); + ASSERT(pcExtra); + + if (GLUE_CHK_PR3(prNetDev, prIwReqData, pcExtra) == FALSE) + return -EINVAL; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + u4SubCmd = (uint32_t) prIwReqData->mode; + pu4IntBuf = (uint32_t *) pcExtra; + + switch (u4SubCmd) { + case PRIV_CMD_TEST_MODE: + /* printk("TestMode=%ld\n", pu4IntBuf[1]); */ + prNdisReq = (struct NDIS_TRANSPORT_STRUCT *) &aucOidBuf[0]; + + if (pu4IntBuf[1] == PRIV_CMD_TEST_MAGIC_KEY) { + prNdisReq->ndisOidCmd = OID_CUSTOM_TEST_MODE; + } else if (pu4IntBuf[1] == 0) { + prNdisReq->ndisOidCmd = OID_CUSTOM_ABORT_TEST_MODE; + } else if (pu4IntBuf[1] == PRIV_CMD_TEST_MAGIC_KEY_ICAP) { + prNdisReq->ndisOidCmd = OID_CUSTOM_TEST_ICAP_MODE; + } else { + status = 0; + break; + } + prNdisReq->inNdisOidlength = 0; + prNdisReq->outNdisOidLength = 0; + + /* Execute this OID */ + status = priv_set_ndis(prNetDev, prNdisReq, &u4BufLen); + break; + + case PRIV_CMD_TEST_CMD: + /* printk("CMD=0x%08lx, data=0x%08lx\n", pu4IntBuf[1], + * pu4IntBuf[2]); + */ + prNdisReq = (struct NDIS_TRANSPORT_STRUCT *) &aucOidBuf[0]; + + kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8); + + prNdisReq->ndisOidCmd = OID_CUSTOM_MTK_WIFI_TEST; + prNdisReq->inNdisOidlength = 8; + prNdisReq->outNdisOidLength = 8; + + /* Execute this OID */ + status = priv_set_ndis(prNetDev, prNdisReq, &u4BufLen); + break; + +#if CFG_SUPPORT_PRIV_MCR_RW + case PRIV_CMD_ACCESS_MCR: + /* printk("addr=0x%08lx, data=0x%08lx\n", pu4IntBuf[1], + * pu4IntBuf[2]); + */ + prNdisReq = (struct NDIS_TRANSPORT_STRUCT *) &aucOidBuf[0]; + + if (!prGlueInfo->fgMcrAccessAllowed) { + if (pu4IntBuf[1] == PRIV_CMD_TEST_MAGIC_KEY + && pu4IntBuf[2] == PRIV_CMD_TEST_MAGIC_KEY) + prGlueInfo->fgMcrAccessAllowed = TRUE; + status = 0; + break; + } + + if (pu4IntBuf[1] == PRIV_CMD_TEST_MAGIC_KEY + && pu4IntBuf[2] == PRIV_CMD_TEST_MAGIC_KEY) { + status = 0; + break; + } + + kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8); + + prNdisReq->ndisOidCmd = OID_CUSTOM_MCR_RW; + prNdisReq->inNdisOidlength = 8; + prNdisReq->outNdisOidLength = 8; + + /* Execute this OID */ + status = priv_set_ndis(prNetDev, prNdisReq, &u4BufLen); + break; +#endif + + case PRIV_CMD_SW_CTRL: + /* printk("addr=0x%08lx, data=0x%08lx\n", pu4IntBuf[1], + * pu4IntBuf[2]); + */ + prNdisReq = (struct NDIS_TRANSPORT_STRUCT *) &aucOidBuf[0]; + + kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8); + + prNdisReq->ndisOidCmd = OID_CUSTOM_SW_CTRL; + prNdisReq->inNdisOidlength = 8; + prNdisReq->outNdisOidLength = 8; + + /* Execute this OID */ + status = priv_set_ndis(prNetDev, prNdisReq, &u4BufLen); + break; + +#if 0 + case PRIV_CMD_BEACON_PERIOD: + /* pu4IntBuf[0] is used as input SubCmd */ + rStatus = wlanSetInformation(prGlueInfo->prAdapter, + wlanoidSetBeaconInterval, (void *)&pu4IntBuf[1], + sizeof(uint32_t), &u4BufLen); + break; +#endif + +#if CFG_TCP_IP_CHKSUM_OFFLOAD + case PRIV_CMD_CSUM_OFFLOAD: { + uint32_t u4CSUMFlags; + + if (pu4IntBuf[1] == 1) + u4CSUMFlags = CSUM_OFFLOAD_EN_ALL; + else if (pu4IntBuf[1] == 0) + u4CSUMFlags = 0; + else + return -EINVAL; + + if (kalIoctl(prGlueInfo, wlanoidSetCSUMOffload, + (void *)&u4CSUMFlags, sizeof(uint32_t), FALSE, FALSE, TRUE, + &u4BufLen) == WLAN_STATUS_SUCCESS) { + if (pu4IntBuf[1] == 1) + prNetDev->features |= NETIF_F_IP_CSUM | + NETIF_F_IPV6_CSUM | + NETIF_F_RXCSUM; + else if (pu4IntBuf[1] == 0) + prNetDev->features &= ~(NETIF_F_IP_CSUM | + NETIF_F_IPV6_CSUM | + NETIF_F_RXCSUM); + } + } + break; +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ + + case PRIV_CMD_POWER_MODE: { + struct PARAM_POWER_MODE_ rPowerMode; + + rPowerMode.ePowerMode = (enum PARAM_POWER_MODE) + pu4IntBuf[1]; + rPowerMode.ucBssIdx = wlanGetBssIdx(prNetDev); + + /* pu4IntBuf[0] is used as input SubCmd */ + kalIoctl(prGlueInfo, wlanoidSet802dot11PowerSaveProfile, + &rPowerMode, sizeof(struct PARAM_POWER_MODE_), + FALSE, FALSE, TRUE, &u4BufLen); + } + break; + + case PRIV_CMD_WMM_PS: { + struct PARAM_CUSTOM_WMM_PS_TEST_STRUCT rWmmPsTest; + + rWmmPsTest.bmfgApsdEnAc = (uint8_t) pu4IntBuf[1]; + rWmmPsTest.ucIsEnterPsAtOnce = (uint8_t) pu4IntBuf[2]; + rWmmPsTest.ucIsDisableUcTrigger = (uint8_t) pu4IntBuf[3]; + rWmmPsTest.reserved = 0; + rWmmPsTest.ucBssIdx = wlanGetBssIdx(prNetDev); + kalIoctl(prGlueInfo, wlanoidSetWiFiWmmPsTest, + (void *)&rWmmPsTest, + sizeof(struct PARAM_CUSTOM_WMM_PS_TEST_STRUCT), + FALSE, FALSE, TRUE, &u4BufLen); + } + break; + +#if 0 + case PRIV_CMD_ADHOC_MODE: + /* pu4IntBuf[0] is used as input SubCmd */ + rStatus = wlanSetInformation(prGlueInfo->prAdapter, + wlanoidSetAdHocMode, (void *)&pu4IntBuf[1], + sizeof(uint32_t), &u4BufLen); + break; +#endif + + case PRIV_CUSTOM_BWCS_CMD: + + DBGLOG(REQ, INFO, + "pu4IntBuf[1] = %x, size of struct PTA_IPC = %d.\n", + pu4IntBuf[1], (uint32_t) sizeof(struct PTA_IPC)); + + prPtaIpc = (struct PTA_IPC *) aucOidBuf; + prPtaIpc->u.aucBTPParams[0] = (uint8_t) (pu4IntBuf[1] >> + 24); + prPtaIpc->u.aucBTPParams[1] = (uint8_t) (pu4IntBuf[1] >> + 16); + prPtaIpc->u.aucBTPParams[2] = (uint8_t) (pu4IntBuf[1] >> 8); + prPtaIpc->u.aucBTPParams[3] = (uint8_t) (pu4IntBuf[1]); + + DBGLOG(REQ, INFO, + "BCM BWCS CMD : PRIV_CUSTOM_BWCS_CMD : aucBTPParams[0] = %02x, aucBTPParams[1] = %02x.\n", + prPtaIpc->u.aucBTPParams[0], + prPtaIpc->u.aucBTPParams[1]); + DBGLOG(REQ, INFO, + "BCM BWCS CMD : PRIV_CUSTOM_BWCS_CMD : aucBTPParams[2] = %02x, aucBTPParams[3] = %02x.\n", + prPtaIpc->u.aucBTPParams[2], + prPtaIpc->u.aucBTPParams[3]); + +#if 0 + status = wlanSetInformation(prGlueInfo->prAdapter, wlanoidSetBT, + (void *)&aucOidBuf[0], u4CmdLen, &u4BufLen); +#endif + + status = wlanoidSetBT(prGlueInfo->prAdapter, + (void *)&aucOidBuf[0], sizeof(struct PTA_IPC), + &u4BufLen); + + if (status != WLAN_STATUS_SUCCESS) + status = -EFAULT; + + break; + + case PRIV_CMD_BAND_CONFIG: { + DBGLOG(INIT, INFO, "CMD set_band = %u\n", + (uint32_t) pu4IntBuf[1]); + } + break; + +#if CFG_ENABLE_WIFI_DIRECT + case PRIV_CMD_P2P_MODE: { + struct PARAM_CUSTOM_P2P_SET_STRUCT rSetP2P; + uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; + + rSetP2P.u4Enable = pu4IntBuf[1]; + rSetP2P.u4Mode = pu4IntBuf[2]; +#if 1 + if (!rSetP2P.u4Enable) + p2pNetUnregister(prGlueInfo, TRUE); + + /* pu4IntBuf[0] is used as input SubCmd */ + rWlanStatus = kalIoctl(prGlueInfo, wlanoidSetP2pMode, + (void *)&rSetP2P, + sizeof(struct PARAM_CUSTOM_P2P_SET_STRUCT), + FALSE, FALSE, TRUE, &u4BufLen); + + if ((rSetP2P.u4Enable) + && (rWlanStatus == WLAN_STATUS_SUCCESS)) + p2pNetRegister(prGlueInfo, TRUE); +#endif + + } + break; +#endif + +#if (CFG_MET_PACKET_TRACE_SUPPORT == 1) + case PRIV_CMD_MET_PROFILING: { + /* PARAM_CUSTOM_WFD_DEBUG_STRUCT_T rWfdDebugModeInfo; */ + /* rWfdDebugModeInfo.ucWFDDebugMode=(UINT_8)pu4IntBuf[1]; */ + /* rWfdDebugModeInfo.u2SNPeriod=(UINT_16)pu4IntBuf[2]; */ + /* DBGLOG(REQ, INFO, ("WFD Debug Mode:%d Period:%d\n", + * rWfdDebugModeInfo.ucWFDDebugMode, + * rWfdDebugModeInfo.u2SNPeriod)); + */ + prGlueInfo->fgMetProfilingEn = (uint8_t) pu4IntBuf[1]; + prGlueInfo->u2MetUdpPort = (uint16_t) pu4IntBuf[2]; + /* DBGLOG(INIT, INFO, ("MET_PROF: Enable=%d UDP_PORT=%d\n", + * prGlueInfo->fgMetProfilingEn, prGlueInfo->u2MetUdpPort); + */ + + } + break; + +#endif + case PRIV_CMD_SET_SER: + kalIoctl(prGlueInfo, wlanoidSetSer, (void *)&pu4IntBuf[1], + sizeof(uint32_t), FALSE, FALSE, TRUE, &u4BufLen); + break; + + default: + return -EOPNOTSUPP; + } + + return status; +} /* __priv_set_int */ + +int +priv_set_int(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) +{ + DBGLOG(REQ, LOUD, "cmd=%x, flags=%x\n", + prIwReqInfo->cmd, prIwReqInfo->flags); + DBGLOG(REQ, LOUD, "mode=%x, flags=%x\n", + prIwReqData->mode, prIwReqData->data.flags); + + return compat_priv(prNetDev, prIwReqInfo, + prIwReqData, pcExtra, __priv_set_int); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Private ioctl get int handler. + * + * \param[in] pDev Net device requested. + * \param[out] pIwReq Pointer to iwreq structure. + * \param[in] prIwReqData The ioctl req structure, use the field of sub-command. + * \param[out] pcExtra The buffer with put the return value + * + * \retval 0 For success. + * \retval -EOPNOTSUPP If cmd is not supported. + * \retval -EFAULT For fail. + * + */ +/*----------------------------------------------------------------------------*/ +int +__priv_get_int(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) +{ + uint32_t u4SubCmd; + uint32_t *pu4IntBuf; + struct GLUE_INFO *prGlueInfo; + uint32_t u4BufLen = 0; + int status = 0; + struct NDIS_TRANSPORT_STRUCT *prNdisReq; + int32_t ch[50] = {0}; + + ASSERT(prNetDev); + ASSERT(prIwReqInfo); + ASSERT(prIwReqData); + ASSERT(pcExtra); + if (GLUE_CHK_PR3(prNetDev, prIwReqData, pcExtra) == FALSE) + return -EINVAL; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + u4SubCmd = (uint32_t) prIwReqData->mode; + pu4IntBuf = (uint32_t *) pcExtra; + + switch (u4SubCmd) { + case PRIV_CMD_TEST_CMD: + /* printk("CMD=0x%08lx, data=0x%08lx\n", pu4IntBuf[1], + * pu4IntBuf[2]); + */ + prNdisReq = (struct NDIS_TRANSPORT_STRUCT *) &aucOidBuf[0]; + + kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8); + + prNdisReq->ndisOidCmd = OID_CUSTOM_MTK_WIFI_TEST; + prNdisReq->inNdisOidlength = 8; + prNdisReq->outNdisOidLength = 8; + + status = priv_get_ndis(prNetDev, prNdisReq, &u4BufLen); + if (status == 0) { + /* printk("Result=%ld\n", + * *(uint32_t *)&prNdisReq->ndisOidContent[4]); + */ + prIwReqData->mode = *(uint32_t *) + &prNdisReq->ndisOidContent[4]; + /* + * if (copy_to_user(prIwReqData->data.pointer, + * &prNdisReq->ndisOidContent[4], 4)) { + * printk(KERN_NOTICE + * "priv_get_int() copy_to_user oidBuf fail(3)\n"); + * return -EFAULT; + * } + */ + } + return status; + +#if CFG_SUPPORT_PRIV_MCR_RW + case PRIV_CMD_ACCESS_MCR: + /* printk("addr=0x%08lx\n", pu4IntBuf[1]); */ + prNdisReq = (struct NDIS_TRANSPORT_STRUCT *) &aucOidBuf[0]; + + if (!prGlueInfo->fgMcrAccessAllowed) { + status = 0; + return status; + } + + kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8); + + prNdisReq->ndisOidCmd = OID_CUSTOM_MCR_RW; + prNdisReq->inNdisOidlength = 8; + prNdisReq->outNdisOidLength = 8; + + status = priv_get_ndis(prNetDev, prNdisReq, &u4BufLen); + if (status == 0) { + /* printk("Result=%ld\n", + * *(uint32_t *)&prNdisReq->ndisOidContent[4]); + */ + prIwReqData->mode = *(uint32_t *) + &prNdisReq->ndisOidContent[4]; + } + return status; +#endif + + case PRIV_CMD_DUMP_MEM: + prNdisReq = (struct NDIS_TRANSPORT_STRUCT *) &aucOidBuf[0]; + +#if 1 + if (!prGlueInfo->fgMcrAccessAllowed) { + status = 0; + return status; + } +#endif + kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8); + + prNdisReq->ndisOidCmd = OID_CUSTOM_MEM_DUMP; + prNdisReq->inNdisOidlength = sizeof(struct + PARAM_CUSTOM_MEM_DUMP_STRUCT); + prNdisReq->outNdisOidLength = sizeof(struct + PARAM_CUSTOM_MEM_DUMP_STRUCT); + + status = priv_get_ndis(prNetDev, prNdisReq, &u4BufLen); + if (status == 0) + prIwReqData->mode = *(uint32_t *) + &prNdisReq->ndisOidContent[0]; + return status; + + case PRIV_CMD_SW_CTRL: + /* printk(" addr=0x%08lx\n", pu4IntBuf[1]); */ + + prNdisReq = (struct NDIS_TRANSPORT_STRUCT *) &aucOidBuf[0]; + + kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8); + + prNdisReq->ndisOidCmd = OID_CUSTOM_SW_CTRL; + prNdisReq->inNdisOidlength = 8; + prNdisReq->outNdisOidLength = 8; + + status = priv_get_ndis(prNetDev, prNdisReq, &u4BufLen); + if (status == 0) { + /* printk("Result=%ld\n", + * *(uint32_t *)&prNdisReq->ndisOidContent[4]); + */ + prIwReqData->mode = *(uint32_t *) + &prNdisReq->ndisOidContent[4]; + } + return status; + +#if 0 + case PRIV_CMD_BEACON_PERIOD: + status = wlanQueryInformation(prGlueInfo->prAdapter, + wlanoidQueryBeaconInterval, (void *) pu4IntBuf, + sizeof(uint32_t), &u4BufLen); + return status; + + case PRIV_CMD_POWER_MODE: + status = wlanQueryInformation(prGlueInfo->prAdapter, + wlanoidQuery802dot11PowerSaveProfile, + (void *)pu4IntBuf, sizeof(uint32_t), &u4BufLen); + return status; + + case PRIV_CMD_ADHOC_MODE: + status = wlanQueryInformation(prGlueInfo->prAdapter, + wlanoidQueryAdHocMode, (void *) pu4IntBuf, + sizeof(uint32_t), &u4BufLen); + return status; +#endif + + case PRIV_CMD_BAND_CONFIG: + DBGLOG(INIT, INFO, "CMD get_band=\n"); + prIwReqData->mode = 0; + return status; + + default: + break; + } + + u4SubCmd = (uint32_t) prIwReqData->data.flags; + + switch (u4SubCmd) { + case PRIV_CMD_GET_CH_LIST: { + uint16_t i, j = 0; + uint8_t NumOfChannel = 50; + uint8_t ucMaxChannelNum = 50; + struct RF_CHANNEL_INFO *aucChannelList; + + DBGLOG(RLM, INFO, "Domain: Query Channel List.\n"); + aucChannelList = (struct RF_CHANNEL_INFO *) + kalMemAlloc(sizeof(struct RF_CHANNEL_INFO) + *ucMaxChannelNum, VIR_MEM_TYPE); + if (!aucChannelList) { + DBGLOG(REQ, ERROR, + "Can not alloc memory for rf channel info\n"); + return -ENOMEM; + } + kalMemZero(aucChannelList, + sizeof(struct RF_CHANNEL_INFO)*ucMaxChannelNum); + + kalGetChannelList(prGlueInfo, BAND_NULL, ucMaxChannelNum, + &NumOfChannel, aucChannelList); + if (NumOfChannel > ucMaxChannelNum) + NumOfChannel = ucMaxChannelNum; + + if (kalIsAPmode(prGlueInfo)) { + for (i = 0; i < NumOfChannel; i++) { + if ((aucChannelList[i].ucChannelNum <= 13) || + (aucChannelList[i].ucChannelNum == 36 + || aucChannelList[i].ucChannelNum == 40 + || aucChannelList[i].ucChannelNum == 44 + || aucChannelList[i].ucChannelNum == 48)) { + ch[j] = (int32_t) aucChannelList[i] + .ucChannelNum; + j++; + } + } + } else { + for (j = 0; j < NumOfChannel; j++) + ch[j] = (int32_t)aucChannelList[j].ucChannelNum; + } + kalMemFree(aucChannelList, VIR_MEM_TYPE, + sizeof(struct RF_CHANNEL_INFO)*ucMaxChannelNum); + + prIwReqData->data.length = j; + if (copy_to_user(prIwReqData->data.pointer, ch, + NumOfChannel * sizeof(int32_t))) + return -EFAULT; + else + return status; + } + case PRIV_CMD_GET_FW_VERSION: { + uint16_t u2Len = 0; + struct ADAPTER *prAdapter; + + prAdapter = prGlueInfo->prAdapter; + if (prAdapter) { + u2Len = kalStrLen( + prAdapter->rVerInfo.aucReleaseManifest); + DBGLOG(REQ, INFO, + "Get FW manifest version: %d\n", u2Len); + prIwReqData->data.length = u2Len; + if (copy_to_user(prIwReqData->data.pointer, + prAdapter->rVerInfo.aucReleaseManifest, + u2Len * sizeof(uint8_t))) + return -EFAULT; + else + return status; + } + DBGLOG(REQ, WARN, "Fail to get FW manifest version\n"); + return status; + } + default: + return -EOPNOTSUPP; + } + + return status; +} /* __priv_get_int */ + +int +priv_get_int(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) +{ + DBGLOG(REQ, LOUD, "cmd=%x, flags=%x\n", + prIwReqInfo->cmd, prIwReqInfo->flags); + DBGLOG(REQ, LOUD, "mode=%x, flags=%x\n", + prIwReqData->mode, prIwReqData->data.flags); + + return compat_priv(prNetDev, prIwReqInfo, + prIwReqData, pcExtra, __priv_get_int); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Private ioctl set int array handler. + * + * \param[in] prNetDev Net device requested. + * \param[in] prIwReqInfo Pointer to iwreq structure. + * \param[in] prIwReqData The ioctl data structure, use the field of + * sub-command. + * \param[in] pcExtra The buffer with input value + * + * \retval 0 For success. + * \retval -EOPNOTSUPP If cmd is not supported. + * \retval -EINVAL If a value is out of range. + * + */ +/*----------------------------------------------------------------------------*/ +int +__priv_set_ints(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN union iwreq_data *prIwReqData, IN char *pcExtra) +{ + DBGLOG(REQ, LOUD, "not support now"); + return -EINVAL; +} /* __priv_set_ints */ + +int +priv_set_ints(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) +{ + DBGLOG(REQ, LOUD, "cmd=%x, flags=%x\n", + prIwReqInfo->cmd, prIwReqInfo->flags); + DBGLOG(REQ, LOUD, "mode=%x, flags=%x\n", + prIwReqData->mode, prIwReqData->data.flags); + + return compat_priv(prNetDev, prIwReqInfo, + prIwReqData, pcExtra, __priv_set_ints); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Private ioctl get int array handler. + * + * \param[in] pDev Net device requested. + * \param[out] pIwReq Pointer to iwreq structure. + * \param[in] prIwReqData The ioctl req structure, use the field of sub-command. + * \param[out] pcExtra The buffer with put the return value + * + * \retval 0 For success. + * \retval -EOPNOTSUPP If cmd is not supported. + * \retval -EFAULT For fail. + * + */ +/*----------------------------------------------------------------------------*/ +int +__priv_get_ints(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) +{ + uint32_t u4SubCmd; + struct GLUE_INFO *prGlueInfo; + int status = 0; + int32_t ch[50]; + + ASSERT(prNetDev); + ASSERT(prIwReqInfo); + ASSERT(prIwReqData); + ASSERT(pcExtra); + if (GLUE_CHK_PR3(prNetDev, prIwReqData, pcExtra) == FALSE) + return -EINVAL; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + u4SubCmd = (uint32_t) prIwReqData->data.flags; + + switch (u4SubCmd) { + case PRIV_CMD_GET_CH_LIST: { + uint16_t i; + uint8_t NumOfChannel = 50; + uint8_t ucMaxChannelNum = 50; + struct RF_CHANNEL_INFO *aucChannelList; + + aucChannelList = (struct RF_CHANNEL_INFO *) + kalMemAlloc(sizeof(struct RF_CHANNEL_INFO) + *ucMaxChannelNum, VIR_MEM_TYPE); + if (!aucChannelList) { + DBGLOG(REQ, ERROR, + "Can not alloc memory for rf channel info\n"); + return -ENOMEM; + } + kalMemZero(aucChannelList, + sizeof(struct RF_CHANNEL_INFO)*ucMaxChannelNum); + + kalGetChannelList(prGlueInfo, BAND_NULL, ucMaxChannelNum, + &NumOfChannel, aucChannelList); + if (NumOfChannel > ucMaxChannelNum) + NumOfChannel = ucMaxChannelNum; + + for (i = 0; i < NumOfChannel; i++) + ch[i] = (int32_t) aucChannelList[i].ucChannelNum; + + kalMemFree(aucChannelList, VIR_MEM_TYPE, + sizeof(struct RF_CHANNEL_INFO)*ucMaxChannelNum); + + prIwReqData->data.length = NumOfChannel; + if (copy_to_user(prIwReqData->data.pointer, ch, + NumOfChannel * sizeof(int32_t))) + return -EFAULT; + else + return status; + } + default: + break; + } + + return status; +} /* __priv_get_ints */ + +int +priv_get_ints(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) +{ + DBGLOG(REQ, LOUD, "cmd=%x, flags=%x\n", + prIwReqInfo->cmd, prIwReqInfo->flags); + DBGLOG(REQ, LOUD, "mode=%x, flags=%x\n", + prIwReqData->mode, prIwReqData->data.flags); + + return compat_priv(prNetDev, prIwReqInfo, + prIwReqData, pcExtra, __priv_get_ints); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Private ioctl set structure handler. + * + * \param[in] pDev Net device requested. + * \param[in] prIwReqData Pointer to iwreq_data structure. + * + * \retval 0 For success. + * \retval -EOPNOTSUPP If cmd is not supported. + * \retval -EINVAL If a value is out of range. + * + */ +/*----------------------------------------------------------------------------*/ +int +__priv_set_struct(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN union iwreq_data *prIwReqData, IN char *pcExtra) +{ + uint32_t u4SubCmd = 0; + int status = 0; + /* WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; */ + uint32_t u4CmdLen = 0; + struct NDIS_TRANSPORT_STRUCT *prNdisReq; + + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t u4BufLen = 0; + uint8_t ucBssIndex = AIS_DEFAULT_INDEX; + + ASSERT(prNetDev); + /* ASSERT(prIwReqInfo); */ + ASSERT(prIwReqData); + /* ASSERT(pcExtra); */ + + kalMemZero(&aucOidBuf[0], sizeof(aucOidBuf)); + + if (GLUE_CHK_PR2(prNetDev, prIwReqData) == FALSE) + return -EINVAL; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + u4SubCmd = (uint32_t) prIwReqData->data.flags; + +#if 0 + DBGLOG(INIT, INFO, + "priv_set_struct(): prIwReqInfo->cmd(0x%X), u4SubCmd(%ld)\n", + prIwReqInfo->cmd, u4SubCmd); +#endif + + switch (u4SubCmd) { +#if 0 /* PTA_ENABLED */ + case PRIV_CMD_BT_COEXIST: + u4CmdLen = prIwReqData->data.length * sizeof(uint32_t); + ASSERT(sizeof(PARAM_CUSTOM_BT_COEXIST_T) >= u4CmdLen); + if (sizeof(PARAM_CUSTOM_BT_COEXIST_T) < u4CmdLen) + return -EFAULT; + + if (copy_from_user(&aucOidBuf[0], prIwReqData->data.pointer, + u4CmdLen)) { + status = -EFAULT; /* return -EFAULT; */ + break; + } + + rStatus = wlanSetInformation(prGlueInfo->prAdapter, + wlanoidSetBtCoexistCtrl, (void *)&aucOidBuf[0], + u4CmdLen, &u4BufLen); + if (rStatus != WLAN_STATUS_SUCCESS) + status = -EFAULT; + break; +#endif + + case PRIV_CUSTOM_BWCS_CMD: + u4CmdLen = prIwReqData->data.length * sizeof(uint32_t); + ASSERT(sizeof(struct PTA_IPC) >= u4CmdLen); + if (sizeof(struct PTA_IPC) < u4CmdLen) + return -EFAULT; +#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS && CFG_SUPPORT_BCM_BWCS_DEBUG + DBGLOG(REQ, INFO, + "ucCmdLen = %d, size of struct PTA_IPC = %d, prIwReqData->data = 0x%x.\n", + u4CmdLen, sizeof(struct PTA_IPC), prIwReqData->data); + + DBGLOG(REQ, INFO, + "priv_set_struct(): prIwReqInfo->cmd(0x%X), u4SubCmd(%ld)\n", + prIwReqInfo->cmd, + u4SubCmd); + DBGLOG(REQ, INFO, "*pcExtra = 0x%x\n", *pcExtra); +#endif + + if (copy_from_user(&aucOidBuf[0], prIwReqData->data.pointer, + u4CmdLen)) { + status = -EFAULT; /* return -EFAULT; */ + break; + } +#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS && CFG_SUPPORT_BCM_BWCS_DEBUG + DBGLOG(REQ, INFO, + "priv_set_struct(): BWCS CMD = %02x%02x%02x%02x\n", + aucOidBuf[2], aucOidBuf[3], + aucOidBuf[4], aucOidBuf[5]); +#endif + +#if 0 + status = wlanSetInformation(prGlueInfo->prAdapter, wlanoidSetBT, + (void *)&aucOidBuf[0], u4CmdLen, &u4BufLen); +#endif + +#if 1 + status = wlanoidSetBT(prGlueInfo->prAdapter, + (void *)&aucOidBuf[0], u4CmdLen, &u4BufLen); +#endif + + if (status != WLAN_STATUS_SUCCESS) + status = -EFAULT; + + break; + +#if CFG_SUPPORT_WPS2 + case PRIV_CMD_WSC_PROBE_REQ: { + struct CONNECTION_SETTINGS *prConnSettings = + aisGetConnSettings(prGlueInfo->prAdapter, + ucBssIndex); + + /* retrieve IE for Probe Request */ + u4CmdLen = prIwReqData->data.length; + if (u4CmdLen > GLUE_INFO_WSCIE_LENGTH) { + DBGLOG(REQ, ERROR, "Input data length is invalid %u\n", + u4CmdLen); + return -EINVAL; + } + + if (prIwReqData->data.length > 0) { + if (copy_from_user(prConnSettings->aucWSCIE, + prIwReqData->data.pointer, + u4CmdLen)) { + status = -EFAULT; + break; + } + prConnSettings->u2WSCIELen = u4CmdLen; + } else { + prConnSettings->u2WSCIELen = 0; + } + } + break; +#endif + case PRIV_CMD_OID: + u4CmdLen = prIwReqData->data.length; + if (u4CmdLen > CMD_OID_BUF_LENGTH) { + DBGLOG(REQ, ERROR, "Input data length is invalid %u\n", + u4CmdLen); + return -EINVAL; + } + if (copy_from_user(&aucOidBuf[0], prIwReqData->data.pointer, + u4CmdLen)) { + status = -EFAULT; + break; + } + if (!kalMemCmp(&aucOidBuf[0], pcExtra, u4CmdLen)) { + /* ToDo:: DBGLOG */ + DBGLOG(REQ, INFO, "pcExtra buffer is valid\n"); + } else { + DBGLOG(REQ, INFO, "pcExtra 0x%p\n", pcExtra); + } + /* Execute this OID */ + status = priv_set_ndis(prNetDev, + (struct NDIS_TRANSPORT_STRUCT *) &aucOidBuf[0], + &u4BufLen); + /* Copy result to user space */ + ((struct NDIS_TRANSPORT_STRUCT *) + &aucOidBuf[0])->outNdisOidLength = u4BufLen; + + if (copy_to_user(prIwReqData->data.pointer, &aucOidBuf[0], + OFFSET_OF(struct NDIS_TRANSPORT_STRUCT, ndisOidContent))) { + DBGLOG(REQ, INFO, "copy_to_user oidBuf fail\n"); + status = -EFAULT; + } + + break; + + case PRIV_CMD_SW_CTRL: + u4CmdLen = prIwReqData->data.length; + prNdisReq = (struct NDIS_TRANSPORT_STRUCT *) &aucOidBuf[0]; + + if (u4CmdLen > sizeof(prNdisReq->ndisOidContent)) { + DBGLOG(REQ, ERROR, "Input data length is invalid %u\n", + u4CmdLen); + return -EINVAL; + } + + if (copy_from_user(&prNdisReq->ndisOidContent[0], + prIwReqData->data.pointer, u4CmdLen)) { + status = -EFAULT; + break; + } + prNdisReq->ndisOidCmd = OID_CUSTOM_SW_CTRL; + prNdisReq->inNdisOidlength = 8; + prNdisReq->outNdisOidLength = 8; + + /* Execute this OID */ + status = priv_set_ndis(prNetDev, prNdisReq, &u4BufLen); + break; + + case PRIV_CMD_GET_WIFI_TYPE: + { + int32_t i4ResultLen; + + u4CmdLen = prIwReqData->data.length; + if (u4CmdLen >= CMD_OID_BUF_LENGTH) { + DBGLOG(REQ, ERROR, + "u4CmdLen:%u >= CMD_OID_BUF_LENGTH:%d\n", + u4CmdLen, CMD_OID_BUF_LENGTH); + return -EINVAL; + } + if (copy_from_user(&aucOidBuf[0], + prIwReqData->data.pointer, + u4CmdLen)) { + DBGLOG(REQ, ERROR, "copy_from_user fail\n"); + return -EFAULT; + } + aucOidBuf[u4CmdLen] = 0; + i4ResultLen = priv_driver_cmds(prNetDev, aucOidBuf, + u4CmdLen); + if (i4ResultLen > 1) { + if (copy_to_user(prIwReqData->data.pointer, + &aucOidBuf[0], i4ResultLen)) { + DBGLOG(REQ, ERROR, + "copy_to_user fail\n"); + return -EFAULT; + } + prIwReqData->data.length = i4ResultLen; + } else { + DBGLOG(REQ, ERROR, + "i4ResultLen:%d <= 1\n", i4ResultLen); + return -EFAULT; + } + } + break; /* case PRIV_CMD_GET_WIFI_TYPE: */ + + /* dynamic tx power control */ + case PRIV_CMD_SET_PWR_CTRL: + { + char *pCommand = NULL; + + u4CmdLen = prIwReqData->data.length; + if (u4CmdLen >= CMD_OID_BUF_LENGTH) + return -EINVAL; + if (copy_from_user(&aucOidBuf[0], + prIwReqData->data.pointer, + u4CmdLen)) { + status = -EFAULT; + break; + } + aucOidBuf[u4CmdLen] = 0; + if (strlen(aucOidBuf) <= 0) { + status = -EFAULT; + break; + } + pCommand = kalMemAlloc(u4CmdLen + 1, VIR_MEM_TYPE); + if (pCommand == NULL) { + DBGLOG(REQ, INFO, "alloc fail\n"); + return -EINVAL; + } + kalMemZero(pCommand, u4CmdLen + 1); + kalMemCopy(pCommand, aucOidBuf, u4CmdLen); + priv_driver_cmds(prNetDev, pCommand, u4CmdLen); + kalMemFree(pCommand, VIR_MEM_TYPE, i4TotalLen); + } + break; + + default: + return -EOPNOTSUPP; + } + + return status; +} /* __priv_set_struct */ + +int +priv_set_struct(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) +{ + DBGLOG(REQ, LOUD, "cmd=%x, flags=%x\n", + prIwReqInfo->cmd, prIwReqInfo->flags); + DBGLOG(REQ, LOUD, "mode=%x, flags=%x\n", + prIwReqData->mode, prIwReqData->data.flags); + + return compat_priv(prNetDev, prIwReqInfo, + prIwReqData, pcExtra, __priv_set_struct); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Private ioctl get struct handler. + * + * \param[in] pDev Net device requested. + * \param[out] pIwReq Pointer to iwreq structure. + * \param[in] cmd Private sub-command. + * + * \retval 0 For success. + * \retval -EFAULT If copy from user space buffer fail. + * \retval -EOPNOTSUPP Parameter "cmd" not recognized. + * + */ +/*----------------------------------------------------------------------------*/ +int +__priv_get_struct(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) +{ + uint32_t u4SubCmd = 0; + struct NDIS_TRANSPORT_STRUCT *prNdisReq = NULL; + + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t u4BufLen = 0; + /* uint32_t *pu4IntBuf = NULL; */ + int status = 0; + + kalMemZero(&aucOidBuf[0], sizeof(aucOidBuf)); + + ASSERT(prNetDev); + ASSERT(prIwReqData); + if (!prNetDev || !prIwReqData) { + DBGLOG(REQ, INFO, + "priv_get_struct(): invalid param(0x%p, 0x%p)\n", + prNetDev, prIwReqData); + return -EINVAL; + } + + u4SubCmd = (uint32_t) prIwReqData->data.flags; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + ASSERT(prGlueInfo); + if (!prGlueInfo) { + DBGLOG(REQ, INFO, + "priv_get_struct(): invalid prGlueInfo(0x%p, 0x%p)\n", + prNetDev, + *((struct GLUE_INFO **) netdev_priv(prNetDev))); + return -EINVAL; + } +#if 0 + DBGLOG(INIT, INFO, + "priv_get_struct(): prIwReqInfo->cmd(0x%X), u4SubCmd(%ld)\n", + prIwReqInfo->cmd, u4SubCmd); +#endif + memset(aucOidBuf, 0, sizeof(aucOidBuf)); + + switch (u4SubCmd) { + case PRIV_CMD_OID: + if (copy_from_user(&aucOidBuf[0], prIwReqData->data.pointer, + sizeof(struct NDIS_TRANSPORT_STRUCT))) { + DBGLOG(REQ, INFO, + "priv_get_struct() copy_from_user oidBuf fail\n"); + return -EFAULT; + } + + prNdisReq = (struct NDIS_TRANSPORT_STRUCT *) &aucOidBuf[0]; +#if 0 + DBGLOG(INIT, INFO, + "\n priv_get_struct cmd 0x%02x len:%d OID:0x%08x OID Len:%d\n", + cmd, + pIwReq->u.data.length, ndisReq->ndisOidCmd, + ndisReq->inNdisOidlength); +#endif + if (priv_get_ndis(prNetDev, prNdisReq, &u4BufLen) == 0) { + prNdisReq->outNdisOidLength = u4BufLen; + if (copy_to_user(prIwReqData->data.pointer, + &aucOidBuf[0], u4BufLen + + sizeof(struct NDIS_TRANSPORT_STRUCT) - + sizeof(prNdisReq->ndisOidContent))) { + DBGLOG(REQ, INFO, + "priv_get_struct() copy_to_user oidBuf fail(1)\n" + ); + return -EFAULT; + } + return 0; + } + prNdisReq->outNdisOidLength = u4BufLen; + if (copy_to_user(prIwReqData->data.pointer, + &aucOidBuf[0], OFFSET_OF(struct NDIS_TRANSPORT_STRUCT, + ndisOidContent))) { + DBGLOG(REQ, INFO, + "priv_get_struct() copy_to_user oidBuf fail(2)\n" + ); + } + return -EFAULT; + + case PRIV_CMD_SW_CTRL: + /* pu4IntBuf = (uint32_t *) prIwReqData->data.pointer; */ + prNdisReq = (struct NDIS_TRANSPORT_STRUCT *) &aucOidBuf[0]; + + if (prIwReqData->data.length > (sizeof(aucOidBuf) - + OFFSET_OF(struct NDIS_TRANSPORT_STRUCT, ndisOidContent))) { + DBGLOG(REQ, INFO, + "priv_get_struct() exceeds length limit\n"); + return -EFAULT; + } + + /* if (copy_from_user(&prNdisReq->ndisOidContent[0], + * prIwReqData->data.pointer, + */ + /* Coverity uanble to detect real size of ndisOidContent, + * it's 4084 bytes instead of 16 bytes + */ + if (copy_from_user(&aucOidBuf[OFFSET_OF(struct + NDIS_TRANSPORT_STRUCT, ndisOidContent)], + prIwReqData->data.pointer, + prIwReqData->data.length)) { + DBGLOG(REQ, INFO, + "priv_get_struct() copy_from_user oidBuf fail\n"); + return -EFAULT; + } + + prNdisReq->ndisOidCmd = OID_CUSTOM_SW_CTRL; + prNdisReq->inNdisOidlength = 8; + prNdisReq->outNdisOidLength = 8; + + status = priv_get_ndis(prNetDev, prNdisReq, &u4BufLen); + if (status == 0) { + prNdisReq->outNdisOidLength = u4BufLen; + /* printk("len=%d Result=%08lx\n", u4BufLen, + * *(uint32_t *)&prNdisReq->ndisOidContent[4]); + */ + + if (copy_to_user(prIwReqData->data.pointer, + &prNdisReq->ndisOidContent[4], 4)) + DBGLOG(REQ, INFO, + "priv_get_struct() copy_to_user oidBuf fail(2)\n" + ); + } + return 0; + default: + DBGLOG(REQ, WARN, "get struct cmd:0x%x\n", u4SubCmd); + return -EOPNOTSUPP; + } +} /* __priv_get_struct */ + +int +priv_get_struct(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) +{ + DBGLOG(REQ, LOUD, "cmd=%x, flags=%x\n", + prIwReqInfo->cmd, prIwReqInfo->flags); + DBGLOG(REQ, LOUD, "mode=%x, flags=%x\n", + prIwReqData->mode, prIwReqData->data.flags); + + return compat_priv(prNetDev, prIwReqInfo, + prIwReqData, pcExtra, __priv_get_struct); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief The routine handles a set operation for a single OID. + * + * \param[in] pDev Net device requested. + * \param[in] ndisReq Ndis request OID information copy from user. + * \param[out] outputLen_p If the call is successful, returns the number of + * bytes written into the query buffer. If the + * call failed due to invalid length of the query + * buffer, returns the amount of storage needed.. + * + * \retval 0 On success. + * \retval -EOPNOTSUPP If cmd is not supported. + * + */ +/*----------------------------------------------------------------------------*/ +static int +priv_set_ndis(IN struct net_device *prNetDev, + IN struct NDIS_TRANSPORT_STRUCT *prNdisReq, + OUT uint32_t *pu4OutputLen) +{ + struct WLAN_REQ_ENTRY *prWlanReqEntry = NULL; + uint32_t status = WLAN_STATUS_SUCCESS; + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t u4SetInfoLen = 0; + + ASSERT(prNetDev); + ASSERT(prNdisReq); + ASSERT(pu4OutputLen); + + if (!prNetDev || !prNdisReq || !pu4OutputLen) { + DBGLOG(REQ, INFO, + "priv_set_ndis(): invalid param(0x%p, 0x%p, 0x%p)\n", + prNetDev, prNdisReq, pu4OutputLen); + return -EINVAL; + } + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + ASSERT(prGlueInfo); + if (!prGlueInfo) { + DBGLOG(REQ, INFO, + "priv_set_ndis(): invalid prGlueInfo(0x%p, 0x%p)\n", + prNetDev, + *((struct GLUE_INFO **) netdev_priv(prNetDev))); + return -EINVAL; + } +#if 0 + DBGLOG(INIT, INFO, + "priv_set_ndis(): prNdisReq->ndisOidCmd(0x%lX)\n", + prNdisReq->ndisOidCmd); +#endif + + if (reqSearchSupportedOidEntry(prNdisReq->ndisOidCmd, + &prWlanReqEntry) == FALSE) { + /* WARNLOG( + * ("Set OID: 0x%08lx (unknown)\n", + * prNdisReq->ndisOidCmd)); + */ + return -EOPNOTSUPP; + } + + if (prWlanReqEntry->pfOidSetHandler == NULL) { + /* WARNLOG( + * ("Set %s: Null set handler\n", + * prWlanReqEntry->pucOidName)); + */ + return -EOPNOTSUPP; + } +#if 0 + DBGLOG(INIT, INFO, "priv_set_ndis(): %s\n", + prWlanReqEntry->pucOidName); +#endif + + if (prWlanReqEntry->fgSetBufLenChecking) { + if (prNdisReq->inNdisOidlength != + prWlanReqEntry->u4InfoBufLen) { + DBGLOG(REQ, WARN, + "Set %s: Invalid length (current=%d, needed=%d)\n", + prWlanReqEntry->pucOidName, + prNdisReq->inNdisOidlength, + prWlanReqEntry->u4InfoBufLen); + + *pu4OutputLen = prWlanReqEntry->u4InfoBufLen; + return -EINVAL; + } + } + + if (prWlanReqEntry->eOidMethod == ENUM_OID_GLUE_ONLY) { + /* GLUE sw info only */ + status = prWlanReqEntry->pfOidSetHandler(prGlueInfo, + prNdisReq->ndisOidContent, + prNdisReq->inNdisOidlength, &u4SetInfoLen); + } else if (prWlanReqEntry->eOidMethod == + ENUM_OID_GLUE_EXTENSION) { + /* multiple sw operations */ + status = prWlanReqEntry->pfOidSetHandler(prGlueInfo, + prNdisReq->ndisOidContent, + prNdisReq->inNdisOidlength, &u4SetInfoLen); + } else if (prWlanReqEntry->eOidMethod == + ENUM_OID_DRIVER_CORE) { + /* driver core */ + + status = kalIoctl(prGlueInfo, + (PFN_OID_HANDLER_FUNC) prWlanReqEntry->pfOidSetHandler, + prNdisReq->ndisOidContent, + prNdisReq->inNdisOidlength, + FALSE, FALSE, TRUE, &u4SetInfoLen); + } else { + DBGLOG(REQ, INFO, + "priv_set_ndis(): unsupported OID method:0x%x\n", + prWlanReqEntry->eOidMethod); + return -EOPNOTSUPP; + } + + *pu4OutputLen = u4SetInfoLen; + + switch (status) { + case WLAN_STATUS_SUCCESS: + break; + + case WLAN_STATUS_INVALID_LENGTH: + /* WARNLOG( + * ("Set %s: Invalid length (current=%ld, needed=%ld)\n", + * prWlanReqEntry->pucOidName, + * prNdisReq->inNdisOidlength, + * u4SetInfoLen)); + */ + break; + } + + if (status != WLAN_STATUS_SUCCESS) + return -EFAULT; + + return 0; +} /* priv_set_ndis */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief The routine handles a query operation for a single OID. Basically we + * return information about the current state of the OID in question. + * + * \param[in] pDev Net device requested. + * \param[in] ndisReq Ndis request OID information copy from user. + * \param[out] outputLen_p If the call is successful, returns the number of + * bytes written into the query buffer. If the + * call failed due to invalid length of the query + * buffer, returns the amount of storage needed.. + * + * \retval 0 On success. + * \retval -EOPNOTSUPP If cmd is not supported. + * \retval -EINVAL invalid input parameters + * + */ +/*----------------------------------------------------------------------------*/ +static int +priv_get_ndis(IN struct net_device *prNetDev, + IN struct NDIS_TRANSPORT_STRUCT *prNdisReq, + OUT uint32_t *pu4OutputLen) +{ + struct WLAN_REQ_ENTRY *prWlanReqEntry = NULL; + uint32_t u4BufLen = 0; + uint32_t status = WLAN_STATUS_SUCCESS; + struct GLUE_INFO *prGlueInfo = NULL; + + ASSERT(prNetDev); + ASSERT(prNdisReq); + ASSERT(pu4OutputLen); + + if (!prNetDev || !prNdisReq || !pu4OutputLen) { + DBGLOG(REQ, INFO, + "priv_get_ndis(): invalid param(0x%p, 0x%p, 0x%p)\n", + prNetDev, prNdisReq, pu4OutputLen); + return -EINVAL; + } + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + ASSERT(prGlueInfo); + if (!prGlueInfo) { + DBGLOG(REQ, INFO, + "priv_get_ndis(): invalid prGlueInfo(0x%p, 0x%p)\n", + prNetDev, + *((struct GLUE_INFO **) netdev_priv(prNetDev))); + return -EINVAL; + } +#if 0 + DBGLOG(INIT, INFO, + "priv_get_ndis(): prNdisReq->ndisOidCmd(0x%lX)\n", + prNdisReq->ndisOidCmd); +#endif + + if (reqSearchSupportedOidEntry(prNdisReq->ndisOidCmd, + &prWlanReqEntry) == FALSE) { + /* WARNLOG( + * ("Query OID: 0x%08lx (unknown)\n", + * prNdisReq->ndisOidCmd)); + */ + return -EOPNOTSUPP; + } + + if (prWlanReqEntry->pfOidQueryHandler == NULL) { + /* WARNLOG( + * ("Query %s: Null query handler\n", + * prWlanReqEntry->pucOidName)); + */ + return -EOPNOTSUPP; + } +#if 0 + DBGLOG(INIT, INFO, "priv_get_ndis(): %s\n", + prWlanReqEntry->pucOidName); +#endif + + if (prWlanReqEntry->fgQryBufLenChecking) { + if (prNdisReq->inNdisOidlength < + prWlanReqEntry->u4InfoBufLen) { + /* Not enough room in InformationBuffer. Punt */ + /* WARNLOG( + * ("Query %s: Buffer too short (current=%ld, + * needed=%ld)\n", + * prWlanReqEntry->pucOidName, + * prNdisReq->inNdisOidlength, + * prWlanReqEntry->u4InfoBufLen)); + */ + + *pu4OutputLen = prWlanReqEntry->u4InfoBufLen; + + status = WLAN_STATUS_INVALID_LENGTH; + return -EINVAL; + } + } + + if (prWlanReqEntry->eOidMethod == ENUM_OID_GLUE_ONLY) { + /* GLUE sw info only */ + status = prWlanReqEntry->pfOidQueryHandler(prGlueInfo, + prNdisReq->ndisOidContent, + prNdisReq->inNdisOidlength, &u4BufLen); + } else if (prWlanReqEntry->eOidMethod == + ENUM_OID_GLUE_EXTENSION) { + /* multiple sw operations */ + status = prWlanReqEntry->pfOidQueryHandler(prGlueInfo, + prNdisReq->ndisOidContent, + prNdisReq->inNdisOidlength, &u4BufLen); + } else if (prWlanReqEntry->eOidMethod == + ENUM_OID_DRIVER_CORE) { + /* driver core */ + + status = kalIoctl(prGlueInfo, + (PFN_OID_HANDLER_FUNC)prWlanReqEntry->pfOidQueryHandler, + prNdisReq->ndisOidContent, prNdisReq->inNdisOidlength, + TRUE, TRUE, TRUE, &u4BufLen); + } else { + DBGLOG(REQ, INFO, + "priv_set_ndis(): unsupported OID method:0x%x\n", + prWlanReqEntry->eOidMethod); + return -EOPNOTSUPP; + } + + *pu4OutputLen = u4BufLen; + + switch (status) { + case WLAN_STATUS_SUCCESS: + break; + + case WLAN_STATUS_INVALID_LENGTH: + /* WARNLOG( + * ("Set %s: Invalid length (current=%ld, needed=%ld)\n", + * prWlanReqEntry->pucOidName, + * prNdisReq->inNdisOidlength, + * u4BufLen)); + */ + break; + } + + if (status != WLAN_STATUS_SUCCESS) + return -EOPNOTSUPP; + + return 0; +} /* priv_get_ndis */ + +#if CFG_SUPPORT_QA_TOOL +/*----------------------------------------------------------------------------*/ +/*! + * \brief The routine handles ATE set operation. + * + * \param[in] pDev Net device requested. + * \param[in] ndisReq Ndis request OID information copy from user. + * \param[out] outputLen_p If the call is successful, returns the number of + * bytes written into the query buffer. If the + * call failed due to invalid length of the query + * buffer, returns the amount of storage needed.. + * + * \retval 0 On success. + * \retval -EOPNOTSUPP If cmd is not supported. + * \retval -EFAULT If copy from user space buffer fail. + * + */ +/*----------------------------------------------------------------------------*/ +int +__priv_ate_set(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN union iwreq_data *prIwReqData, + IN char *pcExtra) +{ + int32_t i4Status; + /* uint8_t *InBuf; + * uint8_t *addr_str, *value_str; + * uint32_t InBufLen; + */ + uint32_t u4SubCmd; + /* u_int8_t isWrite = 0; + * uint32_t u4BufLen = 0; + * struct NDIS_TRANSPORT_STRUCT *prNdisReq; + * uint32_t pu4IntBuf[2]; + */ + uint32_t u4CopySize = sizeof(aucOidBuf); + + /* sanity check */ + ASSERT(prNetDev); + ASSERT(prIwReqInfo); + ASSERT(prIwReqData); + ASSERT(pcExtra); + + if (GLUE_CHK_PR3(prNetDev, prIwReqData, pcExtra) == FALSE) + return -EINVAL; + + u4SubCmd = (uint32_t) prIwReqData->data.flags; + DBGLOG(REQ, INFO, "MT6632: %s, u4SubCmd=%d mode=%d\n", __func__, + u4SubCmd, (uint32_t) prIwReqData->mode); + + switch (u4SubCmd) { + case PRIV_QACMD_SET: + u4CopySize = (prIwReqData->data.length < u4CopySize) + ? prIwReqData->data.length : (u4CopySize - 1); + if (copy_from_user(&aucOidBuf[0], prIwReqData->data.pointer, + u4CopySize)) + return -EFAULT; + aucOidBuf[u4CopySize] = '\0'; + DBGLOG(REQ, INFO, + "PRIV_QACMD_SET: priv_set_string=(%s)(%u,%d)\n", + aucOidBuf, u4CopySize, + (int32_t)prIwReqData->data.length); + i4Status = AteCmdSetHandle(prNetDev, &aucOidBuf[0], + u4CopySize); + break; + default: + return -EOPNOTSUPP; + } + return 0; +} + +int +priv_ate_set(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) +{ + DBGLOG(REQ, LOUD, "cmd=%x, flags=%x\n", + prIwReqInfo->cmd, prIwReqInfo->flags); + DBGLOG(REQ, LOUD, "mode=%x, flags=%x\n", + prIwReqData->mode, prIwReqData->data.flags); + + return compat_priv(prNetDev, prIwReqInfo, + prIwReqData, pcExtra, __priv_ate_set); +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to search desired OID. + * + * \param rOid[in] Desired NDIS_OID + * \param ppWlanReqEntry[out] Found registered OID entry + * + * \retval TRUE: Matched OID is found + * \retval FALSE: No matched OID is found + */ +/*----------------------------------------------------------------------------*/ +static u_int8_t reqSearchSupportedOidEntry(IN uint32_t rOid, + OUT struct WLAN_REQ_ENTRY **ppWlanReqEntry) +{ + int32_t i, j, k; + + i = 0; + j = NUM_SUPPORTED_OIDS - 1; + + while (i <= j) { + k = i + (j - i) / 2; + + if (rOid == arWlanOidReqTable[k].rOid) { + *ppWlanReqEntry = &arWlanOidReqTable[k]; + return TRUE; + } else if (rOid < arWlanOidReqTable[k].rOid) { + j = k - 1; + } else { + i = k + 1; + } + } + + return FALSE; +} /* reqSearchSupportedOidEntry */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Private ioctl driver handler. + * + * \param[in] pDev Net device requested. + * \param[out] pIwReq Pointer to iwreq structure. + * \param[in] cmd Private sub-command. + * + * \retval 0 For success. + * \retval -EFAULT If copy from user space buffer fail. + * \retval -EOPNOTSUPP Parameter "cmd" not recognized. + * + */ +/*----------------------------------------------------------------------------*/ +int +priv_set_driver(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) +{ + uint32_t u4SubCmd = 0; + uint16_t u2Cmd = 0; + + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4BytesWritten = 0; + + ASSERT(prNetDev); + ASSERT(prIwReqData); + if (!prNetDev || !prIwReqData) { + DBGLOG(REQ, INFO, + "priv_set_driver(): invalid param(0x%p, 0x%p)\n", + prNetDev, prIwReqData); + return -EINVAL; + } + + u2Cmd = prIwReqInfo->cmd; + DBGLOG(REQ, INFO, "prIwReqInfo->cmd %u\n", u2Cmd); + + u4SubCmd = (uint32_t) prIwReqData->data.flags; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + ASSERT(prGlueInfo); + if (!prGlueInfo) { + DBGLOG(REQ, INFO, + "priv_set_driver(): invalid prGlueInfo(0x%p, 0x%p)\n", + prNetDev, + *((struct GLUE_INFO **) netdev_priv(prNetDev))); + return -EINVAL; + } + + /* trick,hack in ./net/wireless/wext-priv.c ioctl_private_iw_point */ + /* because the cmd number is odd (get), the input string will not be + * copy_to_user + */ + + DBGLOG(REQ, INFO, "prIwReqData->data.length %u\n", + prIwReqData->data.length); + + /* Use GET type becauase large data by iwpriv. */ + + ASSERT(IW_IS_GET(u2Cmd)); + if (prIwReqData->data.length != 0) { + if (!kal_access_ok(VERIFY_READ, prIwReqData->data.pointer, + prIwReqData->data.length)) { + DBGLOG(REQ, INFO, + "%s access_ok Read fail written = %d\n", + __func__, i4BytesWritten); + return -EFAULT; + } + if (copy_from_user(pcExtra, prIwReqData->data.pointer, + prIwReqData->data.length)) { + DBGLOG(REQ, INFO, + "%s copy_form_user fail written = %d\n", + __func__, prIwReqData->data.length); + return -EFAULT; + } + /* prIwReqData->data.length include the terminate '\0' */ + pcExtra[prIwReqData->data.length] = 0; + } + + if (pcExtra) { + DBGLOG(REQ, INFO, "pcExtra %s\n", pcExtra); + /* Please check max length in rIwPrivTable */ + DBGLOG(REQ, INFO, "%s prIwReqData->data.length = %d\n", + __func__, prIwReqData->data.length); + i4BytesWritten = priv_driver_cmds(prNetDev, pcExtra, + 2000 /*prIwReqData->data.length */); + DBGLOG(REQ, INFO, "%s i4BytesWritten = %d\n", __func__, + i4BytesWritten); + } + + DBGLOG(REQ, INFO, "pcExtra done\n"); + + if (i4BytesWritten > 0) { + + if (i4BytesWritten > 2000) + i4BytesWritten = 2000; + prIwReqData->data.length = + i4BytesWritten; /* the iwpriv will use the length */ + + } else if (i4BytesWritten == 0) { + prIwReqData->data.length = i4BytesWritten; + } +#if 0 + /* trick,hack in ./net/wireless/wext-priv.c ioctl_private_iw_point */ + /* because the cmd number is even (set), the return string will not be + * copy_to_user + */ + ASSERT(IW_IS_SET(u2Cmd)); + if (!access_ok(VERIFY_WRITE, prIwReqData->data.pointer, + i4BytesWritten)) { + DBGLOG(REQ, INFO, "%s access_ok Write fail written = %d\n", + __func__, i4BytesWritten); + return -EFAULT; + } + if (copy_to_user(prIwReqData->data.pointer, pcExtra, + i4BytesWritten)) { + DBGLOG(REQ, INFO, "%s copy_to_user fail written = %d\n", + __func__, i4BytesWritten); + return -EFAULT; + } + DBGLOG(RSN, INFO, "%s copy_to_user written = %d\n", + __func__, i4BytesWritten); +#endif + return 0; + +} /* priv_set_driver */ +#if 0 +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to query the radio configuration used in IBSS + * mode and RF test mode. + * + * \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. + * \param[out] pvQueryBuffer Pointer to the buffer that holds the result of + * the query. + * \param[in] u4QueryBufferLen The length of the query buffer. + * \param[out] pu4QueryInfoLen If the call is successful, returns the number + * of bytes written into the query buffer. If the + * call failed due to invalid length of the query + * buffer, returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + */ +/*----------------------------------------------------------------------------*/ +static uint32_t +reqExtQueryConfiguration(IN struct GLUE_INFO *prGlueInfo, + OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, + OUT uint32_t *pu4QueryInfoLen) +{ + struct PARAM_802_11_CONFIG *prQueryConfig = + (struct PARAM_802_11_CONFIG *) pvQueryBuffer; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4QueryInfoLen = 0; + + DEBUGFUNC("wlanoidQueryConfiguration"); + + ASSERT(prGlueInfo); + ASSERT(pu4QueryInfoLen); + + *pu4QueryInfoLen = sizeof(struct PARAM_802_11_CONFIG); + if (u4QueryBufferLen < sizeof(struct PARAM_802_11_CONFIG)) + return WLAN_STATUS_INVALID_LENGTH; + + ASSERT(pvQueryBuffer); + + kalMemZero(prQueryConfig, + sizeof(struct PARAM_802_11_CONFIG)); + + /* Update the current radio configuration. */ + prQueryConfig->u4Length = sizeof(struct PARAM_802_11_CONFIG); + +#if defined(_HIF_SDIO) + rStatus = sdio_io_ctrl(prGlueInfo, + wlanoidSetBeaconInterval, + &prQueryConfig->u4BeaconPeriod, sizeof(uint32_t), + TRUE, TRUE, &u4QueryInfoLen); +#else + rStatus = wlanQueryInformation(prGlueInfo->prAdapter, + wlanoidQueryBeaconInterval, + &prQueryConfig->u4BeaconPeriod, + sizeof(uint32_t), &u4QueryInfoLen); +#endif + if (rStatus != WLAN_STATUS_SUCCESS) + return rStatus; +#if defined(_HIF_SDIO) + rStatus = sdio_io_ctrl(prGlueInfo, + wlanoidQueryAtimWindow, + &prQueryConfig->u4ATIMWindow, sizeof(uint32_t), + TRUE, TRUE, &u4QueryInfoLen); +#else + rStatus = wlanQueryInformation(prGlueInfo->prAdapter, + wlanoidQueryAtimWindow, + &prQueryConfig->u4ATIMWindow, + sizeof(uint32_t), + &u4QueryInfoLen); +#endif + if (rStatus != WLAN_STATUS_SUCCESS) + return rStatus; +#if defined(_HIF_SDIO) + rStatus = sdio_io_ctrl(prGlueInfo, + wlanoidQueryFrequency, + &prQueryConfig->u4DSConfig, sizeof(uint32_t), + TRUE, TRUE, &u4QueryInfoLen); +#else + rStatus = wlanQueryInformation(prGlueInfo->prAdapter, + wlanoidQueryFrequency, + &prQueryConfig->u4DSConfig, + sizeof(uint32_t), + &u4QueryInfoLen); +#endif + if (rStatus != WLAN_STATUS_SUCCESS) + return rStatus; + + prQueryConfig->rFHConfig.u4Length = sizeof( + struct PARAM_802_11_CONFIG_FH); + + return rStatus; + +} /* end of reqExtQueryConfiguration() */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set the radio configuration used in IBSS + * mode. + * + * \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be + * set. + * \param[in] u4SetBufferLen The length of the set buffer. + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed + * due to invalid length of the set buffer, returns + * the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_LENGTH + * \retval WLAN_STATUS_NOT_ACCEPTED + */ +/*----------------------------------------------------------------------------*/ +static uint32_t +reqExtSetConfiguration(IN struct GLUE_INFO *prGlueInfo, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + uint32_t rStatus = WLAN_STATUS_SUCCESS; + struct PARAM_802_11_CONFIG *prNewConfig = + (struct PARAM_802_11_CONFIG *) pvSetBuffer; + uint32_t u4SetInfoLen = 0; + + DEBUGFUNC("wlanoidSetConfiguration"); + + ASSERT(prGlueInfo); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(struct PARAM_802_11_CONFIG); + + if (u4SetBufferLen < *pu4SetInfoLen) + return WLAN_STATUS_INVALID_LENGTH; + + /* OID_802_11_CONFIGURATION. If associated, NOT_ACCEPTED shall be + * returned. + */ + if (prGlueInfo->eParamMediaStateIndicated == + MEDIA_STATE_CONNECTED) + return WLAN_STATUS_NOT_ACCEPTED; + + ASSERT(pvSetBuffer); + +#if defined(_HIF_SDIO) + rStatus = sdio_io_ctrl(prGlueInfo, + wlanoidSetBeaconInterval, + &prNewConfig->u4BeaconPeriod, sizeof(uint32_t), + FALSE, TRUE, &u4SetInfoLen); +#else + rStatus = wlanSetInformation(prGlueInfo->prAdapter, + wlanoidSetBeaconInterval, + &prNewConfig->u4BeaconPeriod, + sizeof(uint32_t), + &u4SetInfoLen); +#endif + if (rStatus != WLAN_STATUS_SUCCESS) + return rStatus; +#if defined(_HIF_SDIO) + rStatus = sdio_io_ctrl(prGlueInfo, + wlanoidSetAtimWindow, + &prNewConfig->u4ATIMWindow, sizeof(uint32_t), + FALSE, TRUE, &u4SetInfoLen); +#else + rStatus = wlanSetInformation(prGlueInfo->prAdapter, + wlanoidSetAtimWindow, + &prNewConfig->u4ATIMWindow, + sizeof(uint32_t), &u4SetInfoLen); +#endif + if (rStatus != WLAN_STATUS_SUCCESS) + return rStatus; +#if defined(_HIF_SDIO) + rStatus = sdio_io_ctrl(prGlueInfo, wlanoidSetFrequency, + &prNewConfig->u4DSConfig, sizeof(uint32_t), + FALSE, TRUE, &u4SetInfoLen); +#else + rStatus = wlanSetInformation(prGlueInfo->prAdapter, wlanoidSetFrequency, + &prNewConfig->u4DSConfig, + sizeof(uint32_t), &u4SetInfoLen); +#endif + + if (rStatus != WLAN_STATUS_SUCCESS) + return rStatus; + + return rStatus; + +} /* end of reqExtSetConfiguration() */ +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is called to set beacon detection function enable/disable + * state. + * This is mainly designed for usage under BT inquiry state + * (disable function). + * + * \param[in] pvAdapter Pointer to the Adapter structure + * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set + * \param[in] u4SetBufferLen The length of the set buffer + * \param[out] pu4SetInfoLen If the call is successful, returns the number of + * bytes read from the set buffer. If the call failed due to invalid length of + * the set buffer, returns the amount of storage needed. + * + * \retval WLAN_STATUS_SUCCESS + * \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. + * \retval WLAN_STATUS_INVALID_LENGTH + * + */ +/*----------------------------------------------------------------------------*/ +static uint32_t +reqExtSetAcpiDevicePowerState(IN struct GLUE_INFO + *prGlueInfo, + IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, + OUT uint32_t *pu4SetInfoLen) +{ + uint32_t rStatus = WLAN_STATUS_SUCCESS; + + ASSERT(prGlueInfo); + ASSERT(pvSetBuffer); + ASSERT(pu4SetInfoLen); + + /* WIFI is enabled, when ACPI is + * D0 (ParamDeviceStateD0 = 1). And vice versa + */ + + /* rStatus = wlanSetInformation(prGlueInfo->prAdapter, */ + /* wlanoidSetAcpiDevicePowerState, */ + /* pvSetBuffer, */ + /* u4SetBufferLen, */ + /* pu4SetInfoLen); */ + return rStatus; +} + +#define CMD_START "START" +#define CMD_STOP "STOP" +#define CMD_SCAN_ACTIVE "SCAN-ACTIVE" +#define CMD_SCAN_PASSIVE "SCAN-PASSIVE" +#define CMD_RSSI "RSSI" +#define CMD_LINKSPEED "LINKSPEED" +#define CMD_RXFILTER_START "RXFILTER-START" +#define CMD_RXFILTER_STOP "RXFILTER-STOP" +#define CMD_RXFILTER_ADD "RXFILTER-ADD" +#define CMD_RXFILTER_REMOVE "RXFILTER-REMOVE" +#define CMD_BTCOEXSCAN_START "BTCOEXSCAN-START" +#define CMD_BTCOEXSCAN_STOP "BTCOEXSCAN-STOP" +#define CMD_BTCOEXMODE "BTCOEXMODE" +#define CMD_SETSUSPENDOPT "SETSUSPENDOPT" +#define CMD_SETSUSPENDMODE "SETSUSPENDMODE" +#define CMD_P2P_DEV_ADDR "P2P_DEV_ADDR" +#define CMD_SETFWPATH "SETFWPATH" +#define CMD_SETBAND "SETBAND" +#define CMD_GETBAND "GETBAND" +#define CMD_AP_START "AP_START" + +#if CFG_SUPPORT_QA_TOOL +#define CMD_GET_RX_STATISTICS "GET_RX_STATISTICS" +#endif +#define CMD_GET_STAT "GET_STAT" +#define CMD_GET_BSS_STATISTICS "GET_BSS_STATISTICS" +#define CMD_GET_STA_STATISTICS "GET_STA_STATISTICS" +#define CMD_GET_WTBL_INFO "GET_WTBL" +#define CMD_GET_MIB_INFO "GET_MIB" +#define CMD_GET_STA_INFO "GET_STA" +#define CMD_SET_FW_LOG "SET_FWLOG" +#define CMD_GET_QUE_INFO "GET_QUE" +#define CMD_GET_MEM_INFO "GET_MEM" +#define CMD_GET_HIF_INFO "GET_HIF" +#define CMD_GET_TP_INFO "GET_TP" +#define CMD_GET_STA_KEEP_CNT "KEEPCOUNTER" +#define CMD_STAT_RESET_CNT "RESETCOUNTER" +#define CMD_STAT_NOISE_SEL "NOISESELECT" +#define CMD_STAT_GROUP_SEL "GROUP" + +#define CMD_SET_TXPOWER "SET_TXPOWER" +#define CMD_COUNTRY "COUNTRY" +#define CMD_CSA "CSA" +#define CMD_GET_COUNTRY "GET_COUNTRY" +#define CMD_GET_CHANNELS "GET_CHANNELS" +#define CMD_P2P_SET_NOA "P2P_SET_NOA" +#define CMD_P2P_GET_NOA "P2P_GET_NOA" +#define CMD_P2P_SET_PS "P2P_SET_PS" +#define CMD_SET_AP_WPS_P2P_IE "SET_AP_WPS_P2P_IE" +#define CMD_SETROAMMODE "SETROAMMODE" +#define CMD_MIRACAST "MIRACAST" + +#if (CFG_SUPPORT_DFS_MASTER == 1) +#define CMD_SHOW_DFS_STATE "SHOW_DFS_STATE" +#define CMD_SHOW_DFS_RADAR_PARAM "SHOW_DFS_RADAR_PARAM" +#define CMD_SHOW_DFS_HELP "SHOW_DFS_HELP" +#define CMD_SHOW_DFS_CAC_TIME "SHOW_DFS_CAC_TIME" +#endif + +#define CMD_PNOSSIDCLR_SET "PNOSSIDCLR" +#define CMD_PNOSETUP_SET "PNOSETUP " +#define CMD_PNOENABLE_SET "PNOFORCE" +#define CMD_PNODEBUG_SET "PNODEBUG" +#define CMD_WLS_BATCHING "WLS_BATCHING" + +#define CMD_OKC_SET_PMK "SET_PMK" +#define CMD_OKC_ENABLE "OKC_ENABLE" + +#define CMD_SETMONITOR "MONITOR" +#define CMD_SETBUFMODE "BUFFER_MODE" + +#define CMD_GET_CH_RANK_LIST "GET_CH_RANK_LIST" +#define CMD_GET_CH_DIRTINESS "GET_CH_DIRTINESS" + +#if CFG_CHIP_RESET_HANG +#define CMD_SET_RST_HANG "RST_HANG_SET" + +#define CMD_SET_RST_HANG_ARG_NUM 2 +#endif + + +#define CMD_EFUSE "EFUSE" + +#if (CFG_SUPPORT_TWT == 1) +#define CMD_SET_TWT_PARAMS "SET_TWT_PARAMS" +#endif + +#define CMD_CCCR "CCCR" + +/* miracast related definition */ +#define MIRACAST_MODE_OFF 0 +#define MIRACAST_MODE_SOURCE 1 +#define MIRACAST_MODE_SINK 2 + +#ifndef MIRACAST_AMPDU_SIZE +#define MIRACAST_AMPDU_SIZE 8 +#endif + +#ifndef MIRACAST_MCHAN_ALGO +#define MIRACAST_MCHAN_ALGO 1 +#endif + +#ifndef MIRACAST_MCHAN_BW +#define MIRACAST_MCHAN_BW 25 +#endif + +#define CMD_BAND_TYPE_AUTO 0 +#define CMD_BAND_TYPE_5G 1 +#define CMD_BAND_TYPE_2G 2 +#define CMD_BAND_TYPE_ALL 3 + +/* Mediatek private command */ +#define CMD_SET_MCR "SET_MCR" +#define CMD_GET_MCR "GET_MCR" +#define CMD_SET_NVRAM "SET_NVRAM" +#define CMD_GET_NVRAM "GET_NVRAM" +#define CMD_SET_DRV_MCR "SET_DRV_MCR" +#define CMD_GET_DRV_MCR "GET_DRV_MCR" +#define CMD_SET_SW_CTRL "SET_SW_CTRL" +#define CMD_GET_SW_CTRL "GET_SW_CTRL" +#define CMD_SET_CFG "SET_CFG" +#define CMD_GET_CFG "GET_CFG" +#define CMD_SET_EM_CFG "SET_EM_CFG" +#define CMD_GET_EM_CFG "GET_EM_CFG" +#define CMD_SET_CHIP "SET_CHIP" +#define CMD_GET_CHIP "GET_CHIP" +#define CMD_SET_DBG_LEVEL "SET_DBG_LEVEL" +#define CMD_GET_DBG_LEVEL "GET_DBG_LEVEL" +#define CMD_ADD_TS "addts" +#define CMD_DEL_TS "delts" +#define CMD_DUMP_TS "dumpts" +#define CMD_RM_IT "RM-IT" +#define CMD_DUMP_UAPSD "dumpuapsd" +#define CMD_FW_EVENT "FW-EVENT " +#define CMD_GET_WIFI_TYPE "GET_WIFI_TYPE" +#define CMD_SET_PWR_CTRL "SET_PWR_CTRL" +#define PRIV_CMD_SIZE 512 +#define CMD_SET_FIXED_RATE "FixedRate" +#define CMD_GET_VERSION "VER" +#define CMD_SET_TEST_MODE "SET_TEST_MODE" +#define CMD_SET_TEST_CMD "SET_TEST_CMD" +#define CMD_GET_TEST_RESULT "GET_TEST_RESULT" +#define CMD_GET_STA_STAT "STAT" +#define CMD_GET_STA_STAT2 "STAT2" +#define CMD_GET_STA_RX_STAT "RX_STAT" +#define CMD_SET_ACL_POLICY "SET_ACL_POLICY" +#define CMD_ADD_ACL_ENTRY "ADD_ACL_ENTRY" +#define CMD_DEL_ACL_ENTRY "DEL_ACL_ENTRY" +#define CMD_SHOW_ACL_ENTRY "SHOW_ACL_ENTRY" +#define CMD_CLEAR_ACL_ENTRY "CLEAR_ACL_ENTRY" +#define CMD_SET_RA_DBG "RADEBUG" +#define CMD_SET_FIXED_FALLBACK "FIXEDRATEFALLBACK" +#define CMD_GET_STA_IDX "GET_STA_IDX" +#define CMD_GET_TX_POWER_INFO "TxPowerInfo" +#define CMD_TX_POWER_MANUAL_SET "TxPwrManualSet" + + +/* neptune doens't support "show" entry, use "driver" to handle + * MU GET request, and MURX_PKTCNT comes from RX_STATS, + * so this command will reuse RX_STAT's flow + */ +#define CMD_GET_MU_RX_PKTCNT "hqa_get_murx_pktcnt" +#define CMD_RUN_HQA "hqa" +#define CMD_CALIBRATION "cal" + +#if CFG_WOW_SUPPORT +#define CMD_WOW_START "WOW_START" +#define CMD_SET_WOW_ENABLE "SET_WOW_ENABLE" +#define CMD_SET_WOW_PAR "SET_WOW_PAR" +#define CMD_SET_WOW_UDP "SET_WOW_UDP" +#define CMD_SET_WOW_TCP "SET_WOW_TCP" +#define CMD_GET_WOW_PORT "GET_WOW_PORT" +#endif +#define CMD_SET_ADV_PWS "SET_ADV_PWS" +#define CMD_SET_MDTIM "SET_MDTIM" + +#define CMD_SET_DBDC "SET_DBDC" +#define CMD_SET_STA1NSS "SET_STA1NSS" + +#define CMD_SET_AMPDU_TX "SET_AMPDU_TX" +#define CMD_SET_AMPDU_RX "SET_AMPDU_RX" +#define CMD_SET_BF "SET_BF" +#define CMD_SET_NSS "SET_NSS" +#define CMD_SET_AMSDU_TX "SET_AMSDU_TX" +#define CMD_SET_AMSDU_RX "SET_AMSDU_RX" +#define CMD_SET_QOS "SET_QOS" +#if (CFG_SUPPORT_802_11AX == 1) +#define CMD_SET_BA_SIZE "SET_BA_SIZE" +#define CMD_SET_TP_TEST_MODE "SET_TP_TEST_MODE" +#define CMD_SET_MUEDCA_OVERRIDE "MUEDCA_OVERRIDE" +#define CMD_SET_TX_MCSMAP "SET_MCS_MAP" +#define CMD_SET_TX_PPDU "TX_PPDU" +#define CMD_SET_LDPC "SET_LDPC" +#define CMD_FORCE_AMSDU_TX "FORCE_AMSDU_TX" +#define CMD_SET_OM_CH_BW "SET_OM_CHBW" +#define CMD_SET_OM_RX_NSS "SET_OM_RXNSS" +#define CMD_SET_OM_TX_NSS "SET_OM_TXNSTS" +#define CMD_SET_OM_MU_DISABLE "SET_OM_MU_DISABLE" +#define CMD_SET_TX_OM_PACKET "TX_OM_PACKET" +#define CMD_SET_TX_CCK_1M_PWR "TX_CCK_1M_PWR" +#define CMD_SET_PAD_DUR "SET_PAD_DUR" +#endif /* CFG_SUPPORT_802_11AX == 1 */ + +#if CFG_SUPPORT_CAL_RESULT_BACKUP_TO_HOST +#define CMD_SET_CALBACKUP_TEST_DRV_FW "SET_CALBACKUP_TEST_DRV_FW" +#endif + +#define CMD_GET_CNM "GET_CNM" +#define CMD_GET_CAPAB_RSDB "GET_CAPAB_RSDB" + +#ifdef UT_TEST_MODE +#define CMD_RUN_UT "UT" +#endif + +#if CFG_SUPPORT_ADVANCE_CONTROL +#define CMD_SW_DBGCTL_ADVCTL_SET_ID 0xa1260000 +#define CMD_SW_DBGCTL_ADVCTL_GET_ID 0xb1260000 +#define CMD_SET_NOISE "SET_NOISE" +#define CMD_GET_NOISE "GET_NOISE" +#define CMD_SET_POP "SET_POP" +#define CMD_SET_ED "SET_ED" +#define CMD_SET_PD "SET_PD" +#define CMD_SET_MAX_RFGAIN "SET_MAX_RFGAIN" +#endif + +#if CFG_SUPPORT_WIFI_SYSDVT +#define CMD_WIFI_SYSDVT "DVT" +#define CMD_SET_TXS_TEST "TXS_TEST" +#define CMD_SET_TXS_TEST_RESULT "TXS_RESULT" +#define CMD_SET_RXV_TEST "RXV_TEST" +#define CMD_SET_RXV_TEST_RESULT "RXV_RESULT" +#if CFG_TCP_IP_CHKSUM_OFFLOAD +#define CMD_SET_CSO_TEST "CSO_TEST" +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ +#define CMD_SET_TX_TEST "TX_TEST" +#define CMD_SET_TX_AC_TEST "TX_AC_TEST" +#define CMD_SET_SKIP_CH_CHECK "SKIP_CH_CHECK" + +#if (CFG_SUPPORT_DMASHDL_SYSDVT) +#define CMD_SET_DMASHDL_DUMP "DMASHDL_DUMP_MEM" +#define CMD_SET_DMASHDL_DVT_ITEM "DMASHDL_DVT_ITEM" +#endif /* CFG_SUPPORT_DMASHDL_SYSDVT */ +#endif /* CFG_SUPPORT_WIFI_SYSDVT */ + +#define CMD_SET_SW_AMSDU_NUM "SET_SW_AMSDU_NUM" +#define CMD_SET_SW_AMSDU_SIZE "SET_SW_AMSDU_SIZE" + +#define CMD_SET_DRV_SER "SET_DRV_SER" + +#define CMD_GET_WFDMA_INFO "GET_WFDMA_INFO" +#define CMD_GET_PLE_INFO "GET_PLE_INFO" +#define CMD_GET_PSE_INFO "GET_PSE_INFO" +#define CMD_GET_DMASCH_INFO "GET_DMASCH_INFO" +#define CMD_SHOW_TXD_INFO "SHOW_TXD_INFO" + +#if (CFG_SUPPORT_CONNAC2X == 1) +#define CMD_GET_FWTBL_UMAC "GET_UMAC_FWTBL" +#endif /* CFG_SUPPORT_CONNAC2X == 1 */ + +/* Debug for consys */ +#define CMD_DBG_SHOW_TR_INFO "show-tr" +#define CMD_DBG_SHOW_PLE_INFO "show-ple" +#define CMD_DBG_SHOW_PSE_INFO "show-pse" +#define CMD_DBG_SHOW_CSR_INFO "show-csr" +#define CMD_DBG_SHOW_DMASCH_INFO "show-dmasch" + +#if CFG_SUPPORT_EASY_DEBUG +#define CMD_FW_PARAM "set_fw_param" +#endif /* CFG_SUPPORT_EASY_DEBUG */ + +#if (CFG_SUPPORT_CONNINFRA == 1) +#define CMD_SET_WHOLE_CHIP_RESET "SET_WHOLE_CHIP_RESET" +#define CMD_SET_WFSYS_RESET "SET_WFSYS_RESET" +#endif +static uint8_t g_ucMiracastMode = MIRACAST_MODE_OFF; + +struct cmd_tlv { + char prefix; + char version; + char subver; + char reserved; +}; + +struct priv_driver_cmd_s { + char buf[PRIV_CMD_SIZE]; + int used_len; + int total_len; +}; + +#ifdef CFG_ANDROID_AOSP_PRIV_CMD +struct android_wifi_priv_cmd { + char *buf; + int used_len; + int total_len; +}; +#endif /* CFG_ANDROID_AOSP_PRIV_CMD */ + +int priv_driver_get_dbg_level(IN struct net_device + *prNetDev, IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint32_t u4DbgIdx = DBG_MODULE_NUM, u4DbgMask = 0; + u_int8_t fgIsCmdAccept = FALSE; + int32_t u4Ret = 0; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + if (i4Argc >= 2) { + /* u4DbgIdx = kalStrtoul(apcArgv[1], NULL, 0); */ + u4Ret = kalkStrtou32(apcArgv[1], 0, &u4DbgIdx); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse apcArgv error u4Ret=%d\n", + u4Ret); + + if (wlanGetDriverDbgLevel(u4DbgIdx, &u4DbgMask) == + WLAN_STATUS_SUCCESS) { + fgIsCmdAccept = TRUE; + i4BytesWritten = + kalSnprintf(pcCommand, i4TotalLen, + "Get DBG module[%u] log level => [0x%02x]!", + u4DbgIdx, + (uint8_t) u4DbgMask); + } + } + + if (!fgIsCmdAccept) + i4BytesWritten = kalSnprintf(pcCommand, i4TotalLen, + "Get DBG module log level failed!"); + + return i4BytesWritten; + +} /* priv_driver_get_sw_ctrl */ + +static int priv_cmd_not_support(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + DBGLOG(REQ, WARN, "not support priv command: %s\n", pcCommand); + + return -EOPNOTSUPP; +} + +#if CFG_SUPPORT_QA_TOOL +#if CFG_SUPPORT_BUFFER_MODE +static int priv_driver_set_efuse_buffer_mode( + IN struct net_device *prNetDev, IN char *pcCommand, + IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + int32_t i4Argc = 0; + int32_t i4BytesWritten = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + struct PARAM_CUSTOM_EFUSE_BUFFER_MODE + *prSetEfuseBufModeInfo = NULL; +#if (CFG_EFUSE_BUFFER_MODE_DELAY_CAL == 0) + struct BIN_CONTENT *pBinContent; + int i = 0; +#endif + uint8_t *pucConfigBuf = NULL; + uint32_t u4ConfigReadLen; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + + pucConfigBuf = (uint8_t *) kalMemAlloc(2048, VIR_MEM_TYPE); + + if (!pucConfigBuf) { + DBGLOG(INIT, INFO, "allocate pucConfigBuf failed\n"); + i4BytesWritten = -1; + goto out; + } + + kalMemZero(pucConfigBuf, 2048); + u4ConfigReadLen = 0; + + if (kalReadToFile("/MT6632_eFuse_usage_table.xlsm.bin", + pucConfigBuf, 2048, &u4ConfigReadLen) == 0) { + /* ToDo:: Nothing */ + } else { + DBGLOG(INIT, INFO, "can't find file\n"); + i4BytesWritten = -1; + goto out; + } + + /* pucConfigBuf */ + prSetEfuseBufModeInfo = + (struct PARAM_CUSTOM_EFUSE_BUFFER_MODE *) kalMemAlloc( + sizeof(struct PARAM_CUSTOM_EFUSE_BUFFER_MODE), + VIR_MEM_TYPE); + + if (prSetEfuseBufModeInfo == NULL) { + DBGLOG(INIT, INFO, + "allocate prSetEfuseBufModeInfo failed\n"); + i4BytesWritten = -1; + goto out; + } + + kalMemZero(prSetEfuseBufModeInfo, + sizeof(struct PARAM_CUSTOM_EFUSE_BUFFER_MODE)); + + prSetEfuseBufModeInfo->ucSourceMode = 1; + prSetEfuseBufModeInfo->ucCount = (uint8_t) + EFUSE_CONTENT_SIZE; + +#if (CFG_EFUSE_BUFFER_MODE_DELAY_CAL == 0) + pBinContent = (struct BIN_CONTENT *) + prSetEfuseBufModeInfo->aBinContent; + for (i = 0; i < EFUSE_CONTENT_SIZE; i++) { + pBinContent->u2Addr = i; + pBinContent->ucValue = *(pucConfigBuf + i); + + pBinContent++; + } + + for (i = 0; i < 20; i++) + DBGLOG(INIT, INFO, "%x\n", + prSetEfuseBufModeInfo->aBinContent[i].ucValue); +#endif + + rStatus = kalIoctl(prGlueInfo, wlanoidSetEfusBufferMode, + prSetEfuseBufModeInfo, + sizeof(struct PARAM_CUSTOM_EFUSE_BUFFER_MODE), + FALSE, FALSE, TRUE, &u4BufLen); + + i4BytesWritten = + kalSnprintf(pcCommand, i4TotalLen, "set buffer mode %s", + (rStatus == WLAN_STATUS_SUCCESS) ? "success" : "fail"); + +out: + if (pucConfigBuf) + kalMemFree(pucConfigBuf, VIR_MEM_TYPE, 2048); + + if (prSetEfuseBufModeInfo) + kalMemFree(prSetEfuseBufModeInfo, VIR_MEM_TYPE, + sizeof(truct PARAM_CUSTOM_EFUSE_BUFFER_MODE)); + + return i4BytesWritten; +} +#endif /* CFG_SUPPORT_BUFFER_MODE */ + +static int priv_driver_get_rx_statistics(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + int32_t u4Ret = 0; + struct PARAM_CUSTOM_ACCESS_RX_STAT rRxStatisticsTest; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + DBGLOG(INIT, ERROR, + "MT6632 : priv_driver_get_rx_statistics\n"); + + if (i4Argc >= 2) { + u4Ret = kalkStrtou32(apcArgv[1], 0, + &(rRxStatisticsTest.u4SeqNum)); + rRxStatisticsTest.u4TotalNum = sizeof(struct + PARAM_RX_STAT) / 4; + + rStatus = kalIoctl(prGlueInfo, wlanoidQueryRxStatistics, + &rRxStatisticsTest, sizeof(rRxStatisticsTest), + TRUE, TRUE, TRUE, &u4BufLen); + + DBGLOG(REQ, LOUD, "rStatus %u\n", rStatus); + if (rStatus != WLAN_STATUS_SUCCESS) + return -1; + } + + return i4BytesWritten; +} +#endif /* CFG_SUPPORT_QA_TOOL */ + +#if CFG_SUPPORT_MSP +#if 0 +static int priv_driver_get_stat(IN struct net_device + *prNetDev, IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = { 0 }; + int32_t i4ArgNum = 2; + struct PARAM_GET_STA_STATISTICS rQueryStaStatistics; + int32_t rRssi; + uint16_t u2LinkSpeed; + uint32_t u4Per; + UINTT_8 i; + + ASSERT(prNetDev); + + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + kalMemZero(&rQueryStaStatistics, + sizeof(rQueryStaStatistics)); + + if (i4Argc >= i4ArgNum) { + wlanHwAddrToBin(apcArgv[1], + &rQueryStaStatistics.aucMacAddr[0]); + + rQueryStaStatistics.ucReadClear = TRUE; + + rStatus = kalIoctl(prGlueInfo, wlanoidQueryStaStatistics, + &rQueryStaStatistics, + sizeof(rQueryStaStatistics), + TRUE, FALSE, TRUE, &u4BufLen); + + if (rStatus == WLAN_STATUS_SUCCESS) { + rRssi = RCPI_TO_dBm(rQueryStaStatistics.ucRcpi); + u2LinkSpeed = rQueryStaStatistics.u2LinkSpeed == 0 ? 0 : + rQueryStaStatistics.u2LinkSpeed / 2; + + i4BytesWritten = kalSnprintf(pcCommand, i4TotalLen, + "%s", "\n\nSTA Stat:\n"); + + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "CurrentTemperature = %d\n", 0); + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "Tx success = %lu\n", 0); + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "Tx fail count = %ld, PER=%ld.%1ld%%\n", + 0, 0, 0); + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "Rx success = %lu\n", 0); + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "Rx with CRC = %ld, PER=%ld.%1ld%%\n", + 0, 0, 0); + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "Rx with PhyErr = %lu\n", 0); + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "Rx with PlcpErr = %lu\n", 0); + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "Rx drop due to out of resource= %lu\n", 0); + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "Rx duplicate frame = %lu\n", 0); + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "False CCA = %lu\n", 0); + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "RSSI = %d %d %d %d\n", + 0, 0, 0, 0); + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "Last TX Rate = %s, %s, %s, %s, %s\n", + "NA", "NA", "NA", "NA", "NA"); + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "Last RX Rate = %s, %s, %s, %s, %s\n", + "NA", "NA", "NA", "NA", "NA"); + + for (i = 0; i < 2 /* band num */; i++) { + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "BandIdx: = %d\n", i); + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s", + "\tRange: 1 2~5 6~15 16~22 23~33 34~49 50~57 58~64\n" + ); + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\t\t%d \t%d \t%d \t%d \t%d \t%d \t%d \t%d\n", + 0, 0, 0, 0, 0, 0, 0, 0); + } + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "Tx success = %ld\n", + rQueryStaStatistics.u4TransmitCount - + rQueryStaStatistics.u4TransmitFailCount); + + u4Per = rQueryStaStatistics.u4TransmitFailCount == 0 ? + 0 : + (1000 * (rQueryStaStatistics.u4TransmitFailCount)) + / rQueryStaStatistics.u4TransmitCount; + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "Tx fail count = %ld, PER=%ld.%1ld%%\n", + rQueryStaStatistics.u4TransmitFailCount, + u4Per / 10, u4Per % 10); + + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "RSSI = %d\n", rRssi); + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "LinkSpeed = %d\n", u2LinkSpeed); + } + } else + i4BytesWritten = kalSnprintf(pcCommand, i4TotalLen, "%s", + "\n\nNo STA Stat:\n"); + + return i4BytesWritten; +} +#endif + + +static int priv_driver_get_sta_statistics( + IN struct net_device *prNetDev, IN char *pcCommand, + IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = { 0 }; + int32_t i4ArgNum = 3; + struct PARAM_GET_STA_STATISTICS rQueryStaStatistics; + int32_t rRssi; + uint16_t u2LinkSpeed; + uint32_t u4Per; + + ASSERT(prNetDev); + + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + kalMemZero(&rQueryStaStatistics, + sizeof(rQueryStaStatistics)); + rQueryStaStatistics.ucReadClear = TRUE; + + if (i4Argc >= i4ArgNum) { + if (strnicmp(apcArgv[1], CMD_GET_STA_KEEP_CNT, + strlen(CMD_GET_STA_KEEP_CNT)) == 0) { + wlanHwAddrToBin(apcArgv[2], + &rQueryStaStatistics.aucMacAddr[0]); + rQueryStaStatistics.ucReadClear = FALSE; + } else if (strnicmp(apcArgv[2], CMD_GET_STA_KEEP_CNT, + strlen(CMD_GET_STA_KEEP_CNT)) == 0) { + wlanHwAddrToBin(apcArgv[1], + &rQueryStaStatistics.aucMacAddr[0]); + rQueryStaStatistics.ucReadClear = FALSE; + } + } else { + struct BSS_INFO *prAisBssInfo = aisGetAisBssInfo( + prGlueInfo->prAdapter, wlanGetBssIdx(prNetDev)); + + /* Get AIS AP address for no argument */ + if (prAisBssInfo->prStaRecOfAP) { + COPY_MAC_ADDR(rQueryStaStatistics.aucMacAddr, + prAisBssInfo + ->prStaRecOfAP->aucMacAddr); + DBGLOG(RSN, INFO, "use ais ap "MACSTR"\n", + MAC2STR(prAisBssInfo + ->prStaRecOfAP->aucMacAddr)); + } else { + DBGLOG(RSN, INFO, "not connect to ais ap %lx\n", + prAisBssInfo + ->prStaRecOfAP); + i4BytesWritten = kalSnprintf(pcCommand, i4TotalLen, + "%s", "\n\nNo STA Stat:\n"); + return i4BytesWritten; + } + + if (i4Argc == 2) { + if (strnicmp(apcArgv[1], CMD_GET_STA_KEEP_CNT, + strlen(CMD_GET_STA_KEEP_CNT)) == 0) + rQueryStaStatistics.ucReadClear = FALSE; + } + } + + rStatus = kalIoctl(prGlueInfo, wlanoidQueryStaStatistics, + &rQueryStaStatistics, sizeof(rQueryStaStatistics), + TRUE, FALSE, TRUE, &u4BufLen); + + if (rStatus == WLAN_STATUS_SUCCESS) { + rRssi = RCPI_TO_dBm(rQueryStaStatistics.ucRcpi); + u2LinkSpeed = rQueryStaStatistics.u2LinkSpeed == 0 ? 0 : + rQueryStaStatistics.u2LinkSpeed / 2; + + i4BytesWritten = kalSnprintf(pcCommand, i4TotalLen, "%s", + "\n\nSTA Stat:\n"); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "Tx total cnt = %d\n", + rQueryStaStatistics.u4TransmitCount); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "Tx success = %d\n", + rQueryStaStatistics.u4TransmitCount - + rQueryStaStatistics.u4TransmitFailCount); + + u4Per = rQueryStaStatistics.u4TransmitCount == 0 ? 0 : + (1000 * (rQueryStaStatistics.u4TransmitFailCount)) / + rQueryStaStatistics.u4TransmitCount; + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "Tx fail count = %d, PER=%d.%d%%\n", + rQueryStaStatistics.u4TransmitFailCount, u4Per / 10, + u4Per % 10); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "RSSI = %d\n", rRssi); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "LinkSpeed = %d\n", u2LinkSpeed); + + } else + i4BytesWritten = kalSnprintf(pcCommand, i4TotalLen, "%s", + "\n\nNo STA Stat:\n"); + + return i4BytesWritten; + +} + + +static int priv_driver_get_bss_statistics( + IN struct net_device *prNetDev, IN char *pcCommand, + IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus; + uint8_t arBssid[PARAM_MAC_ADDR_LEN]; + uint32_t u4BufLen; + struct PARAM_LINK_SPEED_EX *prLinkSpeed; + struct PARAM_GET_BSS_STATISTICS rQueryBssStatistics; + uint8_t ucBssIndex = AIS_DEFAULT_INDEX; + int32_t i4BytesWritten = 0; +#if 0 + int8_t *apcArgv[WLAN_CFG_ARGV_MAX]; + int32_t i4Argc = 0; + uint32_t u4Index; +#endif + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + ASSERT(prGlueInfo); + + kalMemZero(arBssid, MAC_ADDR_LEN); + wlanQueryInformation(prGlueInfo->prAdapter, wlanoidQueryBssid, + &arBssid[0], sizeof(arBssid), &u4BufLen); + +#if 0 /* Todo:: Get the none-AIS statistics */ + if (i4Argc >= 2) + u4Ret = kalkStrtou32(apcArgv[1], 0, &u4Index); +#endif + ucBssIndex = wlanGetBssIdx(prNetDev); + if (!IS_BSS_INDEX_AIS(prGlueInfo->prAdapter, ucBssIndex)) + return WLAN_STATUS_FAILURE; + + /* 2. fill RSSI */ + if (kalGetMediaStateIndicated(prGlueInfo, + ucBssIndex) != + MEDIA_STATE_CONNECTED) { + /* not connected */ + DBGLOG(REQ, WARN, "not yet connected\n"); + return WLAN_STATUS_SUCCESS; + } + rStatus = kalIoctlByBssIdx(prGlueInfo, + wlanoidQueryRssi, + &prLinkSpeed, sizeof(prLinkSpeed), + TRUE, FALSE, FALSE, + &u4BufLen, ucBssIndex); + if (rStatus != WLAN_STATUS_SUCCESS) + DBGLOG(REQ, WARN, "unable to retrieve rssi\n"); + + + /* 3 get per-BSS link statistics */ + if (rStatus == WLAN_STATUS_SUCCESS) { + kalMemZero(&rQueryBssStatistics, + sizeof(rQueryBssStatistics)); + rQueryBssStatistics.ucBssIndex = ucBssIndex; + + rQueryBssStatistics.ucReadClear = TRUE; + + rStatus = kalIoctl(prGlueInfo, wlanoidQueryBssStatistics, + &rQueryBssStatistics, + sizeof(rQueryBssStatistics), + TRUE, FALSE, TRUE, &u4BufLen); + + if (rStatus == WLAN_STATUS_SUCCESS) { + i4BytesWritten = kalSnprintf(pcCommand, i4TotalLen, + "%s", "\n\nStat:\n"); + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", "CurrentTemperature = -\n"); + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "Tx success = %d\n", + rQueryBssStatistics.u4TransmitCount - + rQueryBssStatistics.u4TransmitFailCount); + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "Tx fail count = %d\n", + rQueryBssStatistics.u4TransmitFailCount); +#if 0 + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "Rx success = %ld\n", 0); + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "Rx with CRC = %ld\n", + prStatistics->rFCSErrorCount.QuadPart); + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", "Rx with PhyErr = 0\n"); + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + "%s", "Rx with PlcpErr = 0\n"); + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", "Rx drop due to out of resource = 0\n"); + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "Rx duplicate frame = %ld\n", + prStatistics->rFrameDuplicateCount.QuadPart); + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", "False CCA = 0\n"); + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "RSSI = %d\n", i4Rssi); + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "Last TX Rate = %s, %s, %s, %s, %s\n", + "NA", "NA", "NA", "NA", "NA"); + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "Last RX Rate = %s, %s, %s, %s, %s\n", + "NA", "NA", "NA", "NA", "NA"); +#endif + + } + + } else { + DBGLOG(REQ, WARN, + "unable to retrieve per-BSS link statistics\n"); + } + + + DBGLOG(REQ, INFO, "%s: command result is %s\n", __func__, + pcCommand); + + return i4BytesWritten; + +} + +static u_int8_t priv_driver_get_sgi_info( + IN struct PARAM_PEER_CAP *prWtblPeerCap) +{ + if (!prWtblPeerCap) + return FALSE; + + switch (prWtblPeerCap->ucFrequencyCapability) { + case BW_20: + return prWtblPeerCap->fgG2; + case BW_40: + return prWtblPeerCap->fgG4; + case BW_80: + return prWtblPeerCap->fgG8; + case BW_160: + return prWtblPeerCap->fgG16; + default: + return FALSE; + } +} + +static u_int8_t priv_driver_get_ldpc_info( + IN struct PARAM_TX_CONFIG *prWtblTxConfig) +{ + if (!prWtblTxConfig) + return FALSE; + + if (prWtblTxConfig->fgIsVHT) + return prWtblTxConfig->fgVhtLDPC; + else + return prWtblTxConfig->fgLDPC; +} + +int32_t priv_driver_rate_to_string(IN char *pcCommand, + IN int i4TotalLen, uint8_t TxRx, + struct PARAM_HW_WLAN_INFO *prHwWlanInfo) +{ + uint8_t i, txmode, rate, stbc; + uint8_t nss; + int32_t i4BytesWritten = 0; + + for (i = 0; i < AUTO_RATE_NUM; i++) { + + txmode = HW_TX_RATE_TO_MODE( + prHwWlanInfo->rWtblRateInfo.au2RateCode[i]); + if (txmode >= ENUM_TX_MODE_NUM) + txmode = ENUM_TX_MODE_NUM - 1; + rate = HW_TX_RATE_TO_MCS( + prHwWlanInfo->rWtblRateInfo.au2RateCode[i]); + nss = HW_TX_RATE_TO_NSS( + prHwWlanInfo->rWtblRateInfo.au2RateCode[i]) + 1; + stbc = HW_TX_RATE_TO_STBC( + prHwWlanInfo->rWtblRateInfo.au2RateCode[i]); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tRate index[%d] ", i); + + if (prHwWlanInfo->rWtblRateInfo.ucRateIdx == i) { + if (TxRx == 0) + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", "[Last RX Rate] "); + else + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", "[Last TX Rate] "); + } else + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", " "); + + if (txmode == TX_RATE_MODE_CCK) + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s, ", + rate < 4 ? HW_TX_RATE_CCK_STR[rate] : + HW_TX_RATE_CCK_STR[4]); + else if (txmode == TX_RATE_MODE_OFDM) + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s, ", + nicHwRateOfdmStr(rate)); + else { + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "NSS%d_MCS%d, ", nss, rate); + } + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s, ", HW_TX_RATE_BW[ + prHwWlanInfo->rWtblPeerCap.ucFrequencyCapability]); + + if (txmode == TX_RATE_MODE_CCK) + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s, ", + rate < 4 ? "LP" : "SP"); + else if (txmode == TX_RATE_MODE_OFDM) + ; + else + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s, ", + priv_driver_get_sgi_info( + &prHwWlanInfo->rWtblPeerCap) == 0 ? + "LGI" : "SGI"); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s%s %s\n", + HW_TX_MODE_STR[txmode], stbc ? "STBC" : " ", + priv_driver_get_ldpc_info(&prHwWlanInfo->rWtblTxConfig) + == 0 ? "BCC" : "LDPC"); + } + + return i4BytesWritten; +} + +static int32_t priv_driver_dump_helper_wtbl_info(IN char *pcCommand, + IN int i4TotalLen, struct PARAM_HW_WLAN_INFO *prHwWlanInfo) +{ + uint8_t i; + int32_t i4BytesWritten = 0; + + if (!pcCommand) { + DBGLOG(HAL, ERROR, "%s: pcCommand is NULL.\n", + __func__); + return i4BytesWritten; + } + + i4BytesWritten = kalSnprintf(pcCommand, i4TotalLen, "%s", + "\n\nwtbl:\n"); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "Dump WTBL info of WLAN_IDX = %d\n", + prHwWlanInfo->u4Index); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "\tAddr="MACSTR"\n", + MAC2STR(prHwWlanInfo->rWtblTxConfig.aucPA)); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "\tMUAR_Idx = %d\n", + prHwWlanInfo->rWtblSecConfig.ucMUARIdx); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "\trc_a1/rc_a2:%d/%d\n", + prHwWlanInfo->rWtblSecConfig.fgRCA1, + prHwWlanInfo->rWtblSecConfig.fgRCA2); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tKID:%d/RCID:%d/RKV:%d/RV:%d/IKV:%d/WPI_FLAG:%d\n", + prHwWlanInfo->rWtblSecConfig.ucKeyID, + prHwWlanInfo->rWtblSecConfig.fgRCID, + prHwWlanInfo->rWtblSecConfig.fgRKV, + prHwWlanInfo->rWtblSecConfig.fgRV, + prHwWlanInfo->rWtblSecConfig.fgIKV, + prHwWlanInfo->rWtblSecConfig.fgEvenPN); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s", "\tGID_SU:NA"); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "\tsw/DIS_RHTR:%d/%d\n", + prHwWlanInfo->rWtblTxConfig.fgSW, + prHwWlanInfo->rWtblTxConfig.fgDisRxHdrTran); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tHT/VHT/HT-LDPC/VHT-LDPC/DYN_BW/MMSS:%d/%d/%d/%d/%d/%d\n", + prHwWlanInfo->rWtblTxConfig.fgIsHT, + prHwWlanInfo->rWtblTxConfig.fgIsVHT, + prHwWlanInfo->rWtblTxConfig.fgLDPC, + prHwWlanInfo->rWtblTxConfig.fgVhtLDPC, + prHwWlanInfo->rWtblTxConfig.fgDynBw, + prHwWlanInfo->rWtblPeerCap.ucMMSS); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tFCAP/G2/G4/G8/G16/CBRN:%d/%d/%d/%d/%d/%d\n", + prHwWlanInfo->rWtblPeerCap.ucFrequencyCapability, + prHwWlanInfo->rWtblPeerCap.fgG2, + prHwWlanInfo->rWtblPeerCap.fgG4, + prHwWlanInfo->rWtblPeerCap.fgG8, + prHwWlanInfo->rWtblPeerCap.fgG16, + prHwWlanInfo->rWtblPeerCap.ucChangeBWAfterRateN); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tHT-TxBF(tibf/tebf):%d/%d, VHT-TxBF(tibf/tebf):%d/%d, PFMU_IDX=%d\n", + prHwWlanInfo->rWtblTxConfig.fgTIBF, + prHwWlanInfo->rWtblTxConfig.fgTEBF, + prHwWlanInfo->rWtblTxConfig.fgVhtTIBF, + prHwWlanInfo->rWtblTxConfig.fgVhtTEBF, + prHwWlanInfo->rWtblTxConfig.ucPFMUIdx); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s", "\tSPE_IDX=NA\n"); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tBA Enable:0x%x, BAFail Enable:%d\n", + prHwWlanInfo->rWtblBaConfig.ucBaEn, + prHwWlanInfo->rWtblTxConfig.fgBAFEn); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tQoS Enable:%d\n", prHwWlanInfo->rWtblTxConfig.fgIsQoS); + if (prHwWlanInfo->rWtblTxConfig.fgIsQoS) { + for (i = 0; i < 8; i += 2) { + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\t\tBA WinSize: TID 0 - %d, TID 1 - %d\n", + (uint32_t) + ((prHwWlanInfo->rWtblBaConfig.u4BaWinSize >> + (i * 3)) & BITS(0, 2)), + (uint32_t) + ((prHwWlanInfo->rWtblBaConfig.u4BaWinSize >> + ((i + 1) * 3)) & BITS(0, 2))); + } + } + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "\tpartial_aid:%d\n", + prHwWlanInfo->rWtblTxConfig.u2PartialAID); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "\twpi_even:%d\n", + prHwWlanInfo->rWtblSecConfig.fgEvenPN); + i4BytesWritten += scnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "\tAAD_OM/CipherSuit:%d/%d\n", + prHwWlanInfo->rWtblTxConfig.fgAADOM, + prHwWlanInfo->rWtblSecConfig.ucCipherSuit); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "\taf:%d\n", + prHwWlanInfo->rWtblPeerCap.ucAmpduFactor); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "\trdg_ba:%d/rdg capability:%d\n", + prHwWlanInfo->rWtblTxConfig.fgRdgBA, + prHwWlanInfo->rWtblTxConfig.fgRDG); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "\tcipher_suit:%d\n", + prHwWlanInfo->rWtblSecConfig.ucCipherSuit); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "\tFromDS:%d\n", + prHwWlanInfo->rWtblTxConfig.fgIsFromDS); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "\tToDS:%d\n", + prHwWlanInfo->rWtblTxConfig.fgIsToDS); +#if 0 + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tRCPI = %d %d %d %d\n", + prHwWlanInfo->rWtblRxCounter.ucRxRcpi0, + prHwWlanInfo->rWtblRxCounter.ucRxRcpi1, + prHwWlanInfo->rWtblRxCounter.ucRxRcpi2, + prHwWlanInfo->rWtblRxCounter.ucRxRcpi3); +#endif + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tRSSI = %d %d %d %d\n", + RCPI_TO_dBm(prHwWlanInfo->rWtblRxCounter.ucRxRcpi0), + RCPI_TO_dBm(prHwWlanInfo->rWtblRxCounter.ucRxRcpi1), + RCPI_TO_dBm(prHwWlanInfo->rWtblRxCounter.ucRxRcpi2), + RCPI_TO_dBm(prHwWlanInfo->rWtblRxCounter.ucRxRcpi3)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s", "\tRate Info\n"); + + i4BytesWritten += priv_driver_rate_to_string(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, 1, prHwWlanInfo); + +#if 0 + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, i4TotalLen - + i4BytesWritten, + "%s", "\t===Key======\n"); + for (i = 0; i < 32; i += 8) { + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\t0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", + prHwWlanInfo->rWtblKeyConfig.aucKey[i + 0], + prHwWlanInfo->rWtblKeyConfig.aucKey[i + 1], + prHwWlanInfo->rWtblKeyConfig.aucKey[i + 2], + prHwWlanInfo->rWtblKeyConfig.aucKey[i + 3], + prHwWlanInfo->rWtblKeyConfig.aucKey[i + 4], + prHwWlanInfo->rWtblKeyConfig.aucKey[i + 5], + prHwWlanInfo->rWtblKeyConfig.aucKey[i + 6], + prHwWlanInfo->rWtblKeyConfig.aucKey[i + 7]); + } +#endif + + return i4BytesWritten; +} + +static int priv_driver_get_wtbl_info_default( + IN struct GLUE_INFO *prGlueInfo, + IN uint32_t u4Index, + IN char *pcCommand, + IN int i4TotalLen) +{ + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + int32_t i4BytesWritten = 0; + struct PARAM_HW_WLAN_INFO *prHwWlanInfo; + + prHwWlanInfo = (struct PARAM_HW_WLAN_INFO *)kalMemAlloc( + sizeof(struct PARAM_HW_WLAN_INFO), VIR_MEM_TYPE); + if (!prHwWlanInfo) + return i4BytesWritten; + + prHwWlanInfo->u4Index = u4Index; + DBGLOG(REQ, INFO, "%s : index = %d\n", + __func__, + prHwWlanInfo->u4Index); + + rStatus = kalIoctl(prGlueInfo, wlanoidQueryWlanInfo, + prHwWlanInfo, + sizeof(struct PARAM_HW_WLAN_INFO), + TRUE, TRUE, TRUE, &u4BufLen); + + DBGLOG(REQ, INFO, "rStatus %u u4BufLen = %d\n", rStatus, u4BufLen); + if (rStatus != WLAN_STATUS_SUCCESS) { + kalMemFree(prHwWlanInfo, VIR_MEM_TYPE, + sizeof(struct PARAM_HW_WLAN_INFO)); + return i4BytesWritten; + } + i4BytesWritten = priv_driver_dump_helper_wtbl_info( + pcCommand, + i4TotalLen, + prHwWlanInfo); + + DBGLOG(REQ, INFO, "%s: command result is %s\n", __func__, pcCommand); + + kalMemFree(prHwWlanInfo, VIR_MEM_TYPE, + sizeof(struct PARAM_HW_WLAN_INFO)); + + return i4BytesWritten; +} + +static int priv_driver_get_wtbl_info(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4Argc = 0; + int32_t u4Ret = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint32_t u4Index = 0; + struct CHIP_DBG_OPS *prDbgOps; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + if (i4Argc >= 2) + u4Ret = kalkStrtou32(apcArgv[1], 0, &u4Index); + + if (u4Ret) + return -1; + + prDbgOps = prGlueInfo->prAdapter->chip_info->prDebugOps; + + if (prDbgOps->showWtblInfo) + return prDbgOps->showWtblInfo( + prGlueInfo->prAdapter, u4Index, pcCommand, i4TotalLen); + else + return priv_driver_get_wtbl_info_default( + prGlueInfo, u4Index, pcCommand, i4TotalLen); +} + +static int priv_driver_get_sta_info(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint8_t aucMacAddr[MAC_ADDR_LEN]; + uint8_t ucWlanIndex = 0; + uint8_t *pucMacAddr = NULL; + struct PARAM_HW_WLAN_INFO *prHwWlanInfo; + struct PARAM_GET_STA_STATISTICS rQueryStaStatistics; + int32_t rRssi; + uint16_t u2LinkSpeed; + uint32_t u4Per; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + kalMemZero(&rQueryStaStatistics, sizeof(rQueryStaStatistics)); + rQueryStaStatistics.ucReadClear = TRUE; + + /* DBGLOG(RSN, INFO, "MT6632 : priv_driver_get_sta_info\n"); */ + if (i4Argc >= 3) { + if (strnicmp(apcArgv[1], CMD_GET_STA_KEEP_CNT, + strlen(CMD_GET_STA_KEEP_CNT)) == 0) { + wlanHwAddrToBin(apcArgv[2], &aucMacAddr[0]); + rQueryStaStatistics.ucReadClear = FALSE; + } else if (strnicmp(apcArgv[2], CMD_GET_STA_KEEP_CNT, + strlen(CMD_GET_STA_KEEP_CNT)) == 0) { + wlanHwAddrToBin(apcArgv[1], &aucMacAddr[0]); + rQueryStaStatistics.ucReadClear = FALSE; + } + + if (!wlanGetWlanIdxByAddress(prGlueInfo->prAdapter, + &aucMacAddr[0], &ucWlanIndex)) + return i4BytesWritten; + } else { + struct BSS_INFO *prAisBssInfo = aisGetAisBssInfo( + prGlueInfo->prAdapter, wlanGetBssIdx(prNetDev)); + + /* Get AIS AP address for no argument */ + if (prAisBssInfo->prStaRecOfAP) + ucWlanIndex = prAisBssInfo + ->prStaRecOfAP->ucWlanIndex; + else if (!wlanGetWlanIdxByAddress(prGlueInfo->prAdapter, NULL, + &ucWlanIndex)) /* try get a peer */ + return i4BytesWritten; + + if (i4Argc == 2) { + if (strnicmp(apcArgv[1], CMD_GET_STA_KEEP_CNT, + strlen(CMD_GET_STA_KEEP_CNT)) == 0) + rQueryStaStatistics.ucReadClear = FALSE; + } + } + + prHwWlanInfo = (struct PARAM_HW_WLAN_INFO *)kalMemAlloc( + sizeof(struct PARAM_HW_WLAN_INFO), VIR_MEM_TYPE); + if (prHwWlanInfo == NULL) { + DBGLOG(REQ, INFO, "prHwWlanInfo is null\n"); + return -1; + } + + prHwWlanInfo->u4Index = ucWlanIndex; + + DBGLOG(REQ, INFO, "MT6632 : index = %d i4TotalLen = %d\n", + prHwWlanInfo->u4Index, i4TotalLen); + + rStatus = kalIoctl(prGlueInfo, wlanoidQueryWlanInfo, prHwWlanInfo, + sizeof(struct PARAM_HW_WLAN_INFO), + TRUE, TRUE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + kalMemFree(prHwWlanInfo, VIR_MEM_TYPE, + sizeof(struct PARAM_HW_WLAN_INFO)); + return -1; + } + + i4BytesWritten = priv_driver_dump_helper_wtbl_info(pcCommand, + i4TotalLen, prHwWlanInfo); + + pucMacAddr = wlanGetStaAddrByWlanIdx(prGlueInfo->prAdapter, + ucWlanIndex); + if (pucMacAddr) { + COPY_MAC_ADDR(rQueryStaStatistics.aucMacAddr, pucMacAddr); + /* i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + * i4TotalLen - i4BytesWritten, + * "\tAddr="MACSTR"\n", + * MAC2STR(rQueryStaStatistics.aucMacAddr)); + */ + + rStatus = kalIoctl(prGlueInfo, wlanoidQueryStaStatistics, + &rQueryStaStatistics, + sizeof(rQueryStaStatistics), + TRUE, FALSE, TRUE, &u4BufLen); + + if (rStatus == WLAN_STATUS_SUCCESS) { + rRssi = RCPI_TO_dBm(rQueryStaStatistics.ucRcpi); + u2LinkSpeed = rQueryStaStatistics.u2LinkSpeed == 0 ? + 0 : rQueryStaStatistics.u2LinkSpeed/2; + + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", "\n\nSTA Stat:\n"); + + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "Tx total cnt = %d\n", + rQueryStaStatistics.u4TransmitCount); + + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "Tx success = %d\n", + rQueryStaStatistics.u4TransmitCount - + rQueryStaStatistics.u4TransmitFailCount); + + u4Per = rQueryStaStatistics.u4TransmitCount == 0 ? 0 : + (1000 * + (rQueryStaStatistics.u4TransmitFailCount)) / + rQueryStaStatistics.u4TransmitCount; + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "Tx fail count = %d, PER=%d.%1d%%\n", + rQueryStaStatistics.u4TransmitFailCount, + u4Per/10, u4Per%10); + + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "RSSI = %d\n", rRssi); + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "LinkSpeed = %d\n", u2LinkSpeed); + } + } + DBGLOG(REQ, INFO, "%s: command result is %s\n", __func__, pcCommand); + + kalMemFree(prHwWlanInfo, VIR_MEM_TYPE, + sizeof(struct PARAM_HW_WLAN_INFO)); + + return i4BytesWritten; +} + +static int priv_driver_get_mib_info(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + uint8_t i; + uint32_t u4Per; + int32_t u4Ret = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + struct PARAM_HW_MIB_INFO *prHwMibInfo; + struct RX_CTRL *prRxCtrl; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + prRxCtrl = &prGlueInfo->prAdapter->rRxCtrl; + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + DBGLOG(REQ, INFO, "MT6632 : priv_driver_get_mib_info\n"); + + prHwMibInfo = (struct PARAM_HW_MIB_INFO *)kalMemAlloc( + sizeof(struct PARAM_HW_MIB_INFO), VIR_MEM_TYPE); + if (!prHwMibInfo) + return -1; + + if (i4Argc == 1) + prHwMibInfo->u4Index = 0; + + if (i4Argc >= 2) + u4Ret = kalkStrtou32(apcArgv[1], 0, &prHwMibInfo->u4Index); + + DBGLOG(REQ, INFO, "MT6632 : index = %d\n", prHwMibInfo->u4Index); + + rStatus = kalIoctl(prGlueInfo, wlanoidQueryMibInfo, prHwMibInfo, + sizeof(struct PARAM_HW_MIB_INFO), + TRUE, TRUE, TRUE, &u4BufLen); + + DBGLOG(REQ, LOUD, "rStatus %u\n", rStatus); + if (rStatus != WLAN_STATUS_SUCCESS) { + kalMemFree(prHwMibInfo, VIR_MEM_TYPE, + sizeof(struct PARAM_HW_MIB_INFO)); + return -1; + } + + if (prHwMibInfo->u4Index < 2) { + i4BytesWritten = kalSnprintf(pcCommand, i4TotalLen, "%s", + "\n\nmib state:\n"); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "Dump MIB info of IDX = %d\n", + prHwMibInfo->u4Index); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", "===Rx Related Counters===\n"); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "\tRx with CRC=%d\n", + prHwMibInfo->rHwMibCnt.u4RxFcsErrCnt); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tRx drop due to out of resource=%d\n", + prHwMibInfo->rHwMibCnt.u4RxFifoFullCnt); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "\tRx Mpdu=%d\n", + prHwMibInfo->rHwMibCnt.u4RxMpduCnt); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "\tRx AMpdu=%d\n", + prHwMibInfo->rHwMibCnt.u4RxAMPDUCnt); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "\tRx PF Drop=%d\n", + prHwMibInfo->rHwMibCnt.u4PFDropCnt); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tRx Len Mismatch=%d\n", + prHwMibInfo->rHwMibCnt.u4RxLenMismatchCnt); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tRx data indicate total=%llu\n", + RX_GET_CNT(prRxCtrl, RX_DATA_INDICATION_COUNT)); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tRx data retain total=%llu\n", + RX_GET_CNT(prRxCtrl, RX_DATA_RETAINED_COUNT)); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tRx drop by SW total=%llu\n", + RX_GET_CNT(prRxCtrl, RX_DROP_TOTAL_COUNT)); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "\tRx reorder miss=%llu\n", + RX_GET_CNT(prRxCtrl, RX_DATA_REORDER_MISS_COUNT)); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tRx reorder within=%llu\n", + RX_GET_CNT(prRxCtrl, RX_DATA_REORDER_WITHIN_COUNT)); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tRx reorder ahead=%llu\n", + RX_GET_CNT(prRxCtrl, RX_DATA_REORDER_AHEAD_COUNT)); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tRx reorder behind=%llu\n", RX_GET_CNT(prRxCtrl, + RX_DATA_REORDER_BEHIND_COUNT)); + + do { + uint32_t u4AmsduCntx100 = 0; + + if (RX_GET_CNT(prRxCtrl, RX_DATA_AMSDU_COUNT)) + u4AmsduCntx100 = + (uint32_t)div64_u64(RX_GET_CNT(prRxCtrl, + RX_DATA_MSDU_IN_AMSDU_COUNT) * 100, + RX_GET_CNT(prRxCtrl, + RX_DATA_AMSDU_COUNT)); + + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tRx avg MSDU in AMSDU=%1d.%02d\n", + u4AmsduCntx100 / 100, u4AmsduCntx100 % 100); + } while (FALSE); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tRx total MSDU in AMSDU=%llu\n", RX_GET_CNT(prRxCtrl, + RX_DATA_MSDU_IN_AMSDU_COUNT)); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tRx AMSDU=%llu\n", RX_GET_CNT(prRxCtrl, + RX_DATA_AMSDU_COUNT)); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "\tRx AMSDU miss=%llu\n", + RX_GET_CNT(prRxCtrl, RX_DATA_AMSDU_MISS_COUNT)); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tRx no StaRec drop=%llu\n", + RX_GET_CNT(prRxCtrl, RX_NO_STA_DROP_COUNT)); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tRx inactive BSS drop=%llu\n", + RX_GET_CNT(prRxCtrl, RX_INACTIVE_BSS_DROP_COUNT)); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tRx HS20 drop=%llu\n", + RX_GET_CNT(prRxCtrl, RX_HS20_DROP_COUNT)); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tRx low SwRfb drop=%llu\n", RX_GET_CNT(prRxCtrl, + RX_LESS_SW_RFB_DROP_COUNT)); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tRx dupicate drop=%llu\n", + RX_GET_CNT(prRxCtrl, RX_DUPICATE_DROP_COUNT)); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "\tRx MIC err drop=%llu\n", + RX_GET_CNT(prRxCtrl, RX_MIC_ERROR_DROP_COUNT)); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "\tRx BAR handle=%llu\n", + RX_GET_CNT(prRxCtrl, RX_BAR_DROP_COUNT)); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tRx non-interest drop=%llu\n", RX_GET_CNT(prRxCtrl, + RX_NO_INTEREST_DROP_COUNT)); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tRx type err drop=%llu\n", + RX_GET_CNT(prRxCtrl, RX_TYPE_ERR_DROP_COUNT)); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tRx class err drop=%llu\n", RX_GET_CNT(prRxCtrl, + RX_CLASS_ERR_DROP_COUNT)); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", "===Phy/Timing Related Counters===\n"); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "\tChannelIdleCnt=%d\n", + prHwMibInfo->rHwMibCnt.u4ChannelIdleCnt); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "\tCCA_NAV_Tx_Time=%d\n", + prHwMibInfo->rHwMibCnt.u4CcaNavTx); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "\tRx_MDRDY_CNT=%d\n", + prHwMibInfo->rHwMibCnt.u4MdrdyCnt); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tCCK_MDRDY=%d, OFDM_MDRDY=0x%x, OFDM_GREEN_MDRDY=0x%x\n", + prHwMibInfo->rHwMibCnt.u4CCKMdrdyCnt, + prHwMibInfo->rHwMibCnt.u4OFDMLGMixMdrdy, + prHwMibInfo->rHwMibCnt.u4OFDMGreenMdrdy); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "\tPrim CCA Time=%d\n", + prHwMibInfo->rHwMibCnt.u4PCcaTime); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "\tSec CCA Time=%d\n", + prHwMibInfo->rHwMibCnt.u4SCcaTime); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "\tPrim ED Time=%d\n", + prHwMibInfo->rHwMibCnt.u4PEDTime); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s", + "===Tx Related Counters(Generic)===\n"); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "\tBeaconTxCnt=%d\n", + prHwMibInfo->rHwMibCnt.u4BeaconTxCnt); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "\tTx 40MHz Cnt=%d\n", + prHwMibInfo->rHwMib2Cnt.u4Tx40MHzCnt); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "\tTx 80MHz Cnt=%d\n", + prHwMibInfo->rHwMib2Cnt.u4Tx80MHzCnt); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "\tTx 160MHz Cnt=%d\n", + prHwMibInfo->rHwMib2Cnt.u4Tx160MHzCnt); + for (i = 0; i < BSSID_NUM; i++) { + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\t===BSSID[%d] Related Counters===\n", i); + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tBA Miss Cnt=%d\n", + prHwMibInfo->rHwMibCnt.au4BaMissedCnt[i]); + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tRTS Tx Cnt=%d\n", + prHwMibInfo->rHwMibCnt.au4RtsTxCnt[i]); + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tFrame Retry Cnt=%d\n", + prHwMibInfo->rHwMibCnt.au4FrameRetryCnt[i]); + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tFrame Retry 2 Cnt=%d\n", + prHwMibInfo->rHwMibCnt.au4FrameRetry2Cnt[i]); + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tRTS Retry Cnt=%d\n", + prHwMibInfo->rHwMibCnt.au4RtsRetryCnt[i]); + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tAck Failed Cnt=%d\n", + prHwMibInfo->rHwMibCnt.au4AckFailedCnt[i]); + } + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", "===AMPDU Related Counters===\n"); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "\tTx AMPDU_Pkt_Cnt=%d\n", + prHwMibInfo->rHwTxAmpduMts.u2TxAmpduCnt); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tTx AMPDU_MPDU_Pkt_Cnt=%d\n", + prHwMibInfo->rHwTxAmpduMts.u4TxSfCnt); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "\tAMPDU SuccessCnt=%d\n", + prHwMibInfo->rHwTxAmpduMts.u4TxAckSfCnt); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tAMPDU Tx success = %d\n", + prHwMibInfo->rHwTxAmpduMts.u4TxAckSfCnt); + + u4Per = prHwMibInfo->rHwTxAmpduMts.u4TxSfCnt == 0 ? 0 : + (1000 * (prHwMibInfo->rHwTxAmpduMts.u4TxSfCnt - + prHwMibInfo->rHwTxAmpduMts.u4TxAckSfCnt)) / + prHwMibInfo->rHwTxAmpduMts.u4TxSfCnt; + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\tAMPDU Tx fail count = %d, PER=%d.%1d%%\n", + prHwMibInfo->rHwTxAmpduMts.u4TxSfCnt - + prHwMibInfo->rHwTxAmpduMts.u4TxAckSfCnt, + u4Per/10, u4Per%10); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s", "\tTx Agg\n"); +#if (CFG_SUPPORT_802_11AX == 1) + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", "\tRange: 1 2~9 10~18 19~27 "); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", "28~36 37~45 46~54 55~78\n"); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\t\t%d \t%d \t%d \t%d \t%d \t%d \t%d \t%d\n", + prHwMibInfo->rHwTxAmpduMts.u2TxRange1AmpduCnt, + prHwMibInfo->rHwTxAmpduMts.u2TxRange2AmpduCnt, + prHwMibInfo->rHwTxAmpduMts.u2TxRange3AmpduCnt, + prHwMibInfo->rHwTxAmpduMts.u2TxRange4AmpduCnt, + prHwMibInfo->rHwTxAmpduMts.u2TxRange5AmpduCnt, + prHwMibInfo->rHwTxAmpduMts.u2TxRange6AmpduCnt, + prHwMibInfo->rHwTxAmpduMts.u2TxRange7AmpduCnt, + prHwMibInfo->rHwTxAmpduMts.u2TxRange8AmpduCnt); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", "\tRange: 79~102 103~126 127~150 151~174 "); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", "174~198 199~222 223~246 247~255\n"); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\t\t%d \t%d \t%d \t%d \t%d \t%d \t%d \t%d\n", + prHwMibInfo->rHwTxAmpduMts.u2TxRange9AmpduCnt, + prHwMibInfo->rHwTxAmpduMts.u2TxRange10AmpduCnt, + prHwMibInfo->rHwTxAmpduMts.u2TxRange11AmpduCnt, + prHwMibInfo->rHwTxAmpduMts.u2TxRange12AmpduCnt, + prHwMibInfo->rHwTxAmpduMts.u2TxRange13AmpduCnt, + prHwMibInfo->rHwTxAmpduMts.u2TxRange14AmpduCnt, + prHwMibInfo->rHwTxAmpduMts.u2TxRange15AmpduCnt, + prHwMibInfo->rHwTxAmpduMts.u2TxRange16AmpduCnt); +#else + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s", + "\tRange: 1 2~5 6~15 16~22 23~33 34~49 50~57 58~64\n" + ); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\t\t%d \t%d \t%d \t%d \t%d \t%d \t%d \t%d\n", + prHwMibInfo->rHwTxAmpduMts.u2TxRange1AmpduCnt, + prHwMibInfo->rHwTxAmpduMts.u2TxRange2AmpduCnt, + prHwMibInfo->rHwTxAmpduMts.u2TxRange3AmpduCnt, + prHwMibInfo->rHwTxAmpduMts.u2TxRange4AmpduCnt, + prHwMibInfo->rHwTxAmpduMts.u2TxRange5AmpduCnt, + prHwMibInfo->rHwTxAmpduMts.u2TxRange6AmpduCnt, + prHwMibInfo->rHwTxAmpduMts.u2TxRange7AmpduCnt, + prHwMibInfo->rHwTxAmpduMts.u2TxRange8AmpduCnt); +#endif + } else + i4BytesWritten = kalSnprintf(pcCommand, i4TotalLen, "%s", + "\nClear All Statistics\n"); + + DBGLOG(REQ, INFO, "%s: command result is %s\n", __func__, pcCommand); + + kalMemFree(prHwMibInfo, VIR_MEM_TYPE, sizeof(struct PARAM_HW_MIB_INFO)); + + nicRxClearStatistics(prGlueInfo->prAdapter); + + return i4BytesWritten; +} + +static int priv_driver_set_fw_log(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint32_t u4McuDest = 0; + uint32_t u4LogType = 0; + struct CMD_FW_LOG_2_HOST_CTRL *prFwLog2HostCtrl; + uint32_t u4Ret = 0; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(RSN, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + DBGLOG(RSN, INFO, "MT6632 : priv_driver_set_fw_log\n"); + + prFwLog2HostCtrl = (struct CMD_FW_LOG_2_HOST_CTRL *)kalMemAlloc( + sizeof(struct CMD_FW_LOG_2_HOST_CTRL), VIR_MEM_TYPE); + if (!prFwLog2HostCtrl) + return -1; + + if (i4Argc == 3) { + u4Ret = kalkStrtou32(apcArgv[1], 0, &u4McuDest); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse u4McuDest error u4Ret=%d\n", + u4Ret); + + u4Ret = kalkStrtou32(apcArgv[2], 0, &u4LogType); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse u4LogType error u4Ret=%d\n", + u4Ret); + + prFwLog2HostCtrl->ucMcuDest = (uint8_t)u4McuDest; + prFwLog2HostCtrl->ucFwLog2HostCtrl = (uint8_t)u4LogType; + + rStatus = kalIoctl(prGlueInfo, wlanoidSetFwLog2Host, + prFwLog2HostCtrl, + sizeof(struct CMD_FW_LOG_2_HOST_CTRL), + TRUE, TRUE, TRUE, &u4BufLen); + + DBGLOG(REQ, INFO, "%s: command result is %s (%d %d)\n", + __func__, pcCommand, u4McuDest, u4LogType); + DBGLOG(REQ, LOUD, "rStatus %u\n", rStatus); + + if (rStatus != WLAN_STATUS_SUCCESS) { + kalMemFree(prFwLog2HostCtrl, VIR_MEM_TYPE, + sizeof(struct CMD_FW_LOG_2_HOST_CTRL)); + return -1; + } + } else { + DBGLOG(REQ, ERROR, "argc %i is not equal to 3\n", i4Argc); + i4BytesWritten = -1; + } + + kalMemFree(prFwLog2HostCtrl, VIR_MEM_TYPE, + sizeof(struct CMD_FW_LOG_2_HOST_CTRL)); + return i4BytesWritten; +} +#endif + +static int priv_driver_get_mcr(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint32_t u4Ret; + int32_t i4ArgNum = 2; + struct CMD_ACCESS_REG rCmdAccessReg; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + if (i4Argc >= i4ArgNum) { + rCmdAccessReg.u4Address = 0; + u4Ret = kalkStrtou32(apcArgv[1], 0, &(rCmdAccessReg.u4Address)); + if (u4Ret) + DBGLOG(REQ, LOUD, + "parse get_mcr error (Address) u4Ret=%d\n", + u4Ret); + + /* rCmdAccessReg.u4Address = kalStrtoul(apcArgv[1], NULL, 0); */ + rCmdAccessReg.u4Data = 0; + + DBGLOG(REQ, LOUD, "address is %x\n", rCmdAccessReg.u4Address); + + rStatus = kalIoctl(prGlueInfo, wlanoidQueryMcrRead, + &rCmdAccessReg, sizeof(rCmdAccessReg), + TRUE, TRUE, TRUE, &u4BufLen); + + DBGLOG(REQ, LOUD, "rStatus %u\n", rStatus); + if (rStatus != WLAN_STATUS_SUCCESS) + return -1; + + i4BytesWritten = kalSnprintf(pcCommand, i4TotalLen, "0x%08x", + (unsigned int)rCmdAccessReg.u4Data); + DBGLOG(REQ, INFO, "%s: command result is %s\n", __func__, + pcCommand); + } + + return i4BytesWritten; + +} /* priv_driver_get_mcr */ + +int priv_driver_set_mcr(IN struct net_device *prNetDev, IN char *pcCommand, + IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = { 0 }; + uint32_t u4Ret; + int32_t i4ArgNum = 3; + struct CMD_ACCESS_REG rCmdAccessReg; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + if (i4Argc >= i4ArgNum) { + u4Ret = kalkStrtou32(apcArgv[1], 0, &(rCmdAccessReg.u4Address)); + if (u4Ret) + DBGLOG(REQ, LOUD, + "parse get_mcr error (Address) u4Ret=%d\n", + u4Ret); + + u4Ret = kalkStrtou32(apcArgv[2], 0, &(rCmdAccessReg.u4Data)); + if (u4Ret) + DBGLOG(REQ, LOUD, + "parse get_mcr error (Data) u4Ret=%d\n", u4Ret); + + /* rCmdAccessReg.u4Address = kalStrtoul(apcArgv[1], NULL, 0); */ + /* rCmdAccessReg.u4Data = kalStrtoul(apcArgv[2], NULL, 0); */ + + rStatus = kalIoctl(prGlueInfo, wlanoidSetMcrWrite, + &rCmdAccessReg, sizeof(rCmdAccessReg), + FALSE, FALSE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) + return -1; + + } + + return i4BytesWritten; + +} + +static int priv_driver_set_test_mode(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint32_t u4Ret; + int32_t i4ArgNum = 2, u4MagicKey = -1; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + if (i4Argc >= i4ArgNum) { + + u4Ret = kalkStrtou32(apcArgv[1], 0, &(u4MagicKey)); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse Magic Key error u4Ret=%d\n", + u4Ret); + + DBGLOG(REQ, LOUD, "The Set Test Mode Magic Key is %d\n", + u4MagicKey); + + if (u4MagicKey == PRIV_CMD_TEST_MAGIC_KEY) { + rStatus = kalIoctl(prGlueInfo, + wlanoidRftestSetTestMode, + NULL, 0, FALSE, FALSE, TRUE, + &u4BufLen); + } else if (u4MagicKey == 0) { + rStatus = kalIoctl(prGlueInfo, + wlanoidRftestSetAbortTestMode, + NULL, 0, FALSE, FALSE, TRUE, + &u4BufLen); + } + + DBGLOG(REQ, LOUD, "rStatus %u\n", rStatus); + + if (rStatus != WLAN_STATUS_SUCCESS) + return -1; + } + + return i4BytesWritten; + +} /* priv_driver_set_test_mode */ + +static int priv_driver_set_test_cmd(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint32_t u4Ret; + int32_t i4ArgNum = 3; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + if (i4Argc >= i4ArgNum) { + rRfATInfo.u4FuncIndex = 0; + u4Ret = kalkStrtou32(apcArgv[1], 0, &(rRfATInfo.u4FuncIndex)); + if (u4Ret) + DBGLOG(REQ, LOUD, + "Parse Test CMD Index error u4Ret=%d\n", u4Ret); + + rRfATInfo.u4FuncData = 0; + u4Ret = kalkStrtou32(apcArgv[2], 0, &(rRfATInfo.u4FuncData)); + if (u4Ret) + DBGLOG(REQ, LOUD, + "Parse Test CMD Data error u4Ret=%d\n", u4Ret); + + DBGLOG(REQ, LOUD, + "Set Test CMD FuncIndex = %d, FuncData = %d\n", + rRfATInfo.u4FuncIndex, rRfATInfo.u4FuncData); + + rStatus = kalIoctl(prGlueInfo, wlanoidRftestSetAutoTest, + &rRfATInfo, sizeof(rRfATInfo), + FALSE, FALSE, TRUE, &u4BufLen); + + DBGLOG(REQ, LOUD, "rStatus %u\n", rStatus); + if (rStatus != WLAN_STATUS_SUCCESS) + return -1; + } + + return i4BytesWritten; + +} /* priv_driver_set_test_cmd */ + +static int priv_driver_get_test_result(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint32_t u4Ret; + uint32_t u4Data = 0; + int32_t i4ArgNum = 3; + struct PARAM_MTK_WIFI_TEST_STRUCT rRfATInfo; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + if (i4Argc >= i4ArgNum) { + rRfATInfo.u4FuncIndex = 0; + u4Ret = kalkStrtou32(apcArgv[1], 0, &(rRfATInfo.u4FuncIndex)); + if (u4Ret) + DBGLOG(REQ, LOUD, + "Parse Test CMD Index error u4Ret=%d\n", u4Ret); + + rRfATInfo.u4FuncData = 0; + u4Ret = kalkStrtou32(apcArgv[2], 0, &(rRfATInfo.u4FuncData)); + if (u4Ret) + DBGLOG(REQ, LOUD, + "Parse Test CMD Data error u4Ret=%d\n", u4Ret); + + DBGLOG(REQ, LOUD, + "Get Test CMD FuncIndex = %d, FuncData = %d\n", + rRfATInfo.u4FuncIndex, rRfATInfo.u4FuncData); + + rStatus = kalIoctl(prGlueInfo, wlanoidRftestQueryAutoTest, + &rRfATInfo, sizeof(rRfATInfo), + TRUE, TRUE, TRUE, &u4BufLen); + + DBGLOG(REQ, LOUD, "rStatus %u\n", rStatus); + if (rStatus != WLAN_STATUS_SUCCESS) + return -1; + u4Data = (unsigned int)rRfATInfo.u4FuncData; + i4BytesWritten = kalSnprintf(pcCommand, i4TotalLen, + "%d[0x%08x]", u4Data, u4Data); + DBGLOG(REQ, INFO, "%s: command result is %s\n", __func__, + pcCommand); + } + + return i4BytesWritten; + +} /* priv_driver_get_test_result */ + +#if (CFG_SUPPORT_RA_GEN == 1) + +static int32_t priv_driver_set_ra_debug_proc(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + int8_t *this_char = NULL; + int32_t i4Recv = 0; + uint32_t u4WCID = 0, u4DebugType = 0; + uint32_t u4Id = 0xa0650000; + struct PARAM_CUSTOM_SW_CTRL_STRUCT *prSwCtrlInfo; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %d, apcArgv[0] = %s\n\n", i4Argc, *apcArgv); + + this_char = kalStrStr(*apcArgv, "="); + if (!this_char) + return -1; + this_char++; + + DBGLOG(REQ, LOUD, "string = %s\n", this_char); + + i4Recv = sscanf(this_char, "%d:%d", &(u4WCID), &(u4DebugType)); + if (i4Recv < 0) + return -1; + + prSwCtrlInfo = + (struct PARAM_CUSTOM_SW_CTRL_STRUCT *)kalMemAlloc( + sizeof(struct PARAM_CUSTOM_SW_CTRL_STRUCT), + VIR_MEM_TYPE); + if (!prSwCtrlInfo) + return -1; + + if (i4Recv == 2) { + prSwCtrlInfo->u4Id = u4Id; + prSwCtrlInfo->u4Data = u4WCID | + ((u4DebugType & BITS(0, 15)) << 16); + + rStatus = kalIoctl(prGlueInfo, wlanoidSetSwCtrlWrite, + prSwCtrlInfo, + sizeof(struct PARAM_CUSTOM_SW_CTRL_STRUCT), + FALSE, FALSE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + kalMemFree(prSwCtrlInfo, VIR_MEM_TYPE, + sizeof(struct PARAM_CUSTOM_SW_CTRL_STRUCT)); + return -1; + } + + DBGLOG(REQ, LOUD, "WlanIdx=%d\nDebugType=%d\nu4Data=0x%08x\n", + u4WCID, u4DebugType, prSwCtrlInfo->u4Data); + } else { + DBGLOG(INIT, ERROR, + "iwpriv wlanXX driver RaDebug=[wlanIdx]:[debugType]\n"); + } + + kalMemFree(prSwCtrlInfo, VIR_MEM_TYPE, + sizeof(struct PARAM_CUSTOM_SW_CTRL_STRUCT)); + + return i4BytesWritten; +} + +int priv_driver_set_fixed_fallback(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + /* INT_32 u4Ret = 0; */ + uint32_t u4WCID = 0; + uint32_t u4Mode = 0, u4Bw = 0, u4Mcs = 0, u4VhtNss = 0, u4Band = 0; + uint32_t u4SGI = 0, u4Preamble = 0, u4STBC = 0, u4LDPC = 0, u4SpeEn = 0; + int32_t i4Recv = 0; + int8_t *this_char = NULL; + uint32_t u4Id = 0xa0660000; + uint32_t u4Data = 0x80000000; + uint32_t u4Id2 = 0xa0600000; + uint8_t u4Nsts = 1; + u_int8_t fgStatus = TRUE; + static uint8_t fgIsUseWCID = FALSE; + + struct PARAM_CUSTOM_SW_CTRL_STRUCT rSwCtrlInfo; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %d, apcArgv[0] = %s\n\n", i4Argc, *apcArgv); + + this_char = kalStrStr(*apcArgv, "="); + if (!this_char) + return -1; + this_char++; + + DBGLOG(REQ, LOUD, "string = %s\n", this_char); + + if (strnicmp(this_char, "auto", strlen("auto")) == 0) { + i4Recv = 1; + } else if (strnicmp(this_char, "UseWCID", strlen("UseWCID")) == 0) { + i4Recv = 2; + fgIsUseWCID = TRUE; + } else if (strnicmp(this_char, "ApplyAll", strlen("ApplyAll")) == 0) { + i4Recv = 3; + fgIsUseWCID = FALSE; + } else { + i4Recv = sscanf(this_char, "%d-%d-%d-%d-%d-%d-%d-%d-%d-%d-%d", + &(u4WCID), &(u4Mode), &(u4Bw), &(u4Mcs), + &(u4VhtNss), &(u4SGI), &(u4Preamble), &(u4STBC), + &(u4LDPC), &(u4SpeEn), &(u4Band)); + + DBGLOG(REQ, LOUD, "u4WCID=%d\nu4Mode=%d\nu4Bw=%d\n", + u4WCID, u4Mode, u4Bw); + DBGLOG(REQ, LOUD, "u4Mcs=%d\nu4VhtNss=%d\nu4SGI=%d\n", + u4Mcs, u4VhtNss, u4SGI); + DBGLOG(REQ, LOUD, "u4Preamble=%d\nu4STBC=%d\n", + u4Preamble, u4STBC); + DBGLOG(REQ, LOUD, "u4LDPC=%d\nu4SpeEn=%d\nu4Band=%d\n", + u4LDPC, u4SpeEn, u4Band); + DBGLOG(REQ, LOUD, "fgIsUseWCID=%d\n\n", + fgIsUseWCID); + } + + if (i4Recv == 1) { + rSwCtrlInfo.u4Id = u4Id2; + rSwCtrlInfo.u4Data = 0; + + rStatus = kalIoctl(prGlueInfo, wlanoidSetSwCtrlWrite, + &rSwCtrlInfo, sizeof(rSwCtrlInfo), + FALSE, FALSE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) + return -1; + } else if (i4Recv == 2 || i4Recv == 3) { + i4BytesWritten = kalSnprintf(pcCommand, i4TotalLen, + "Update fgIsUseWCID %d\n", fgIsUseWCID); + } else if (i4Recv == 11) { + rSwCtrlInfo.u4Id = u4Id; + rSwCtrlInfo.u4Data = u4Data; + if (fgIsUseWCID && u4WCID < WTBL_SIZE && + prAdapter->rWifiVar.arWtbl[u4WCID].ucUsed) { + rSwCtrlInfo.u4Id |= u4WCID; + rSwCtrlInfo.u4Id |= BIT(8); + i4BytesWritten = kalSnprintf( + pcCommand, i4TotalLen, + "Apply WCID %d\n", u4WCID); + } else { + i4BytesWritten = kalSnprintf( + pcCommand, i4TotalLen, "Apply All\n"); + } + + if (u4SGI) + rSwCtrlInfo.u4Data |= BIT(30); + if (u4LDPC) + rSwCtrlInfo.u4Data |= BIT(29); + if (u4SpeEn) + rSwCtrlInfo.u4Data |= BIT(28); + if (u4Band) + rSwCtrlInfo.u4Data |= BIT(25); + if (u4STBC) + rSwCtrlInfo.u4Data |= BIT(11); + + if (u4Bw <= 3) + rSwCtrlInfo.u4Data |= ((u4Bw << 26) & BITS(26, 27)); + else { + fgStatus = FALSE; + DBGLOG(INIT, ERROR, + "Wrong BW! BW20=0, BW40=1, BW80=2,BW160=3\n"); + } + if (u4Mode <= 4) { + rSwCtrlInfo.u4Data |= ((u4Mode << 6) & BITS(6, 8)); + + switch (u4Mode) { + case 0: + if (u4Mcs <= 3) + rSwCtrlInfo.u4Data |= u4Mcs; + else { + fgStatus = FALSE; + DBGLOG(INIT, ERROR, + "CCK mode but wrong MCS!\n"); + } + + if (u4Preamble) + rSwCtrlInfo.u4Data |= BIT(2); + else + rSwCtrlInfo.u4Data &= ~BIT(2); + break; + case 1: + switch (u4Mcs) { + case 0: + /* 6'b001011 */ + rSwCtrlInfo.u4Data |= 11; + break; + case 1: + /* 6'b001111 */ + rSwCtrlInfo.u4Data |= 15; + break; + case 2: + /* 6'b001010 */ + rSwCtrlInfo.u4Data |= 10; + break; + case 3: + /* 6'b001110 */ + rSwCtrlInfo.u4Data |= 14; + break; + case 4: + /* 6'b001001 */ + rSwCtrlInfo.u4Data |= 9; + break; + case 5: + /* 6'b001101 */ + rSwCtrlInfo.u4Data |= 13; + break; + case 6: + /* 6'b001000 */ + rSwCtrlInfo.u4Data |= 8; + break; + case 7: + /* 6'b001100 */ + rSwCtrlInfo.u4Data |= 12; + break; + default: + fgStatus = FALSE; + DBGLOG(INIT, ERROR, + "OFDM mode but wrong MCS!\n"); + break; + } + break; + case 2: + case 3: + if (u4Mcs <= 32) + rSwCtrlInfo.u4Data |= u4Mcs; + else { + fgStatus = FALSE; + DBGLOG(INIT, ERROR, + "HT mode but wrong MCS!\n"); + } + + if (u4Mcs != 32) { + u4Nsts += (u4Mcs >> 3); + if (u4STBC && (u4Nsts == 1)) + u4Nsts++; + } + break; + case 4: + if (u4Mcs <= 9) + rSwCtrlInfo.u4Data |= u4Mcs; + else { + fgStatus = FALSE; + DBGLOG(INIT, ERROR, + "VHT mode but wrong MCS!\n"); + } + if (u4STBC && (u4VhtNss == 1)) + u4Nsts++; + else + u4Nsts = u4VhtNss; + break; + default: + break; + } + } else { + fgStatus = FALSE; + DBGLOG(INIT, ERROR, + "Wrong TxMode! CCK=0, OFDM=1, HT=2, GF=3, VHT=4\n"); + } + + rSwCtrlInfo.u4Data |= (((u4Nsts - 1) << 9) & BITS(9, 10)); + + if (fgStatus) { + rStatus = kalIoctl(prGlueInfo, wlanoidSetSwCtrlWrite, + &rSwCtrlInfo, sizeof(rSwCtrlInfo), + FALSE, FALSE, TRUE, &u4BufLen); + } + + if (rStatus != WLAN_STATUS_SUCCESS) + return -1; + } else { + DBGLOG(INIT, ERROR, "iwpriv wlanXX driver FixedRate=Option\n"); + DBGLOG(INIT, ERROR, + "Option:[WCID]-[Mode]-[BW]-[MCS]-[VhtNss]-[SGI]-[Preamble]-[STBC]-[LDPC]-[SPE_EN]-[BAND]\n"); + DBGLOG(INIT, ERROR, "[WCID]Wireless Client ID\n"); + DBGLOG(INIT, ERROR, "[Mode]CCK=0, OFDM=1, HT=2, GF=3, VHT=4\n"); + DBGLOG(INIT, ERROR, "[BW]BW20=0, BW40=1, BW80=2,BW160=3\n"); + DBGLOG(INIT, ERROR, + "[MCS]CCK=0~3, OFDM=0~7, HT=0~32, VHT=0~9\n"); + DBGLOG(INIT, ERROR, "[VhtNss]VHT=1~4, Other=ignore\n"); + DBGLOG(INIT, ERROR, "[Preamble]Long=0, Other=Short\n"); + DBGLOG(INIT, ERROR, "[BAND]2G=0, Other=5G\n"); + } + + return i4BytesWritten; +} +#endif + +#if (CFG_SUPPORT_TXPOWER_INFO == 1) +static int32_t priv_driver_dump_txpower_info(struct ADAPTER *prAdapter, + IN char *pcCommand, IN int i4TotalLen, + struct PARAM_TXPOWER_ALL_RATE_POWER_INFO_T *prTxPowerInfo) +{ + int32_t i4BytesWritten = 0; + + if (prTxPowerInfo->ucTxPowerCategory == + TXPOWER_EVENT_SHOW_ALL_RATE_TXPOWER_INFO) { + uint8_t ucTxPwrIdx = 0, ucTxPwrType = 0, ucIdx = 0, + ucIdxOffset = 0; + + char *rateStr = NULL; + struct FRAME_POWER_CONFIG_INFO_T rRatePowerInfo; + char *cckRateStr[MODULATION_SYSTEM_CCK_NUM] = { + "1M", "2M", "5M", "11M"}; + char *ofdmRateStr[MODULATION_SYSTEM_OFDM_NUM] = { + "6M", "9M", "12M", "18M", "24M", "36M", "48M", "54M" }; + char *ht20RateStr[MODULATION_SYSTEM_HT20_NUM] = { + "M0", "M1", "M2", "M3", "M4", "M5", "M6", "M7" }; + char *ht40RateStr[MODULATION_SYSTEM_HT40_NUM] = { + "M0", "M1", "M2", "M3", "M4", "M5", "M6", + "M7", "M32" }; + char *vhtRateStr[MODULATION_SYSTEM_VHT20_NUM] = { + "M0", "M1", "M2", "M3", "M4", "M5", "M6", + "M7", "M8", "M9" }; + char *ruRateStr[MODULATION_SYSTEM_HE_26_MCS_NUM] = { + "M0", "M1", "M2", "M3", "M4", "M5", "M6", "M7", + "M8", "M9", "M10", "M11" }; + + uint8_t *pucStr = NULL; + uint8_t *POWER_TYPE_STR[] = { + "CCK", "OFDM", "HT20", "HT40", + "VHT20", "VHT40", "VHT80", + "VHT160", "RU26", "RU52", "RU106", + "RU242", "RU484", "RU996"}; + uint8_t ucPwrIdxLen[] = { + MODULATION_SYSTEM_CCK_NUM, + MODULATION_SYSTEM_OFDM_NUM, + MODULATION_SYSTEM_HT20_NUM, + MODULATION_SYSTEM_HT40_NUM, + MODULATION_SYSTEM_VHT20_NUM, + MODULATION_SYSTEM_VHT40_NUM, + MODULATION_SYSTEM_VHT80_NUM, + MODULATION_SYSTEM_VHT160_NUM, + MODULATION_SYSTEM_HE_26_MCS_NUM, + MODULATION_SYSTEM_HE_52_MCS_NUM, + MODULATION_SYSTEM_HE_106_MCS_NUM, + MODULATION_SYSTEM_HE_242_MCS_NUM, + MODULATION_SYSTEM_HE_484_MCS_NUM, + MODULATION_SYSTEM_HE_996_MCS_NUM}; + + uint8_t ucBandIdx; + uint8_t ucFormat; + + if ((sizeof(POWER_TYPE_STR)/sizeof(uint8_t *)) != + (sizeof(ucPwrIdxLen)/sizeof(uint8_t))) + return i4BytesWritten; + + ucBandIdx = prTxPowerInfo->ucBandIdx; + ucFormat = prTxPowerInfo->u1Format; + + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "%s", + "\n====== TX POWER INFO ======\n"); + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "DBDC Index: %d, Channel Band: %s\n", + ucBandIdx, + (prTxPowerInfo->ucChBand) ? + ("5G") : ("2G")); + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", "===========================\n"); + + rRatePowerInfo = + prTxPowerInfo->rRatePowerInfo; + + + for (ucTxPwrType = 0; + ucTxPwrType < sizeof(POWER_TYPE_STR)/sizeof(uint8_t *); + ucTxPwrType++) { + + pucStr = POWER_TYPE_STR[ucTxPwrType]; + + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "[%6s] > ", pucStr); + + for (ucTxPwrIdx = 0; + ucTxPwrIdx < ucPwrIdxLen[ucTxPwrType]; + ucTxPwrIdx++) { + /*Legcay format*/ + if (kalStrCmp(pucStr, "CCK") == 0) + rateStr = cckRateStr[ucTxPwrIdx]; + else if (kalStrCmp(pucStr, "OFDM") == 0) + rateStr = ofdmRateStr[ucTxPwrIdx]; + else if (kalStrCmp(pucStr, "HT20") == 0) + rateStr = ht20RateStr[ucTxPwrIdx]; + else if (kalStrCmp(pucStr, "HT40") == 0) + rateStr = ht40RateStr[ucTxPwrIdx]; + else if (kalStrnCmp(pucStr, "VHT", 3) == 0) + rateStr = vhtRateStr[ucTxPwrIdx]; + /*HE format*/ + else if ((kalStrnCmp(pucStr, "RU", 2) == 0) + && (ucFormat == TXPOWER_FORMAT_HE)) + rateStr = ruRateStr[ucTxPwrIdx]; + else + continue; + + ucIdx = ucTxPwrIdx + ucIdxOffset; + + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%3s:%03d, ", + rateStr, + rRatePowerInfo. + aicFramePowerConfig[ucIdx][ucBandIdx]. + icFramePowerDbm); + } + i4BytesWritten += kalScnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\n"); + + ucIdxOffset += ucPwrIdxLen[ucTxPwrType]; + } + + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "[MAX][Bound]: 0x%02x (%03d)\n", + prTxPowerInfo->icPwrMaxBnd, + prTxPowerInfo->icPwrMaxBnd); + + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "[MIN][Bound]: 0x%02x (%03d)\n", + prTxPowerInfo->icPwrMinBnd, + prTxPowerInfo->icPwrMinBnd); + } + + return i4BytesWritten; +} + +static int32_t priv_driver_get_txpower_info(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0, u4Size = 0; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + int8_t *this_char = NULL; + uint32_t u4ParamNum = 0; + uint8_t ucParam = 0; + uint8_t ucBandIdx = 0; + struct PARAM_TXPOWER_ALL_RATE_POWER_INFO_T *prTxPowerInfo = NULL; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + DBGLOG(REQ, INFO, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, INFO, "argc is %d, apcArgv[0] = %s\n\n", i4Argc, *apcArgv); + + this_char = kalStrStr(*apcArgv, "="); + if (!this_char) + return -1; + this_char++; + + DBGLOG(REQ, INFO, "string = %s\n", this_char); + + u4ParamNum = sscanf(this_char, "%d:%d", &ucParam, &ucBandIdx); + if (u4ParamNum < 0) + return -1; + DBGLOG(REQ, INFO, "ParamNum=%d,Param=%d,Band=%d\n", + u4ParamNum, ucParam, ucBandIdx); + + u4Size = sizeof(struct PARAM_TXPOWER_ALL_RATE_POWER_INFO_T); + + prTxPowerInfo = + (struct PARAM_TXPOWER_ALL_RATE_POWER_INFO_T *)kalMemAlloc( + u4Size, VIR_MEM_TYPE); + if (!prTxPowerInfo) + return -1; + + if (u4ParamNum == TXPOWER_INFO_INPUT_ARG_NUM) { + prTxPowerInfo->ucTxPowerCategory = ucParam; + prTxPowerInfo->ucBandIdx = ucBandIdx; + + rStatus = kalIoctl(prGlueInfo, wlanoidQueryTxPowerInfo, + prTxPowerInfo, + sizeof(struct PARAM_TXPOWER_ALL_RATE_POWER_INFO_T), + TRUE, TRUE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + kalMemFree(prTxPowerInfo, VIR_MEM_TYPE, + sizeof(struct PARAM_TXPOWER_ALL_RATE_POWER_INFO_T)); + return -1; + } + + i4BytesWritten = priv_driver_dump_txpower_info(prAdapter, + pcCommand, i4TotalLen, prTxPowerInfo); + } else { + DBGLOG(INIT, ERROR, + "[Error]iwpriv wlanXX driver TxPowerInfo=[Param]:[BandIdx]\n"); + } + + kalMemFree(prTxPowerInfo, VIR_MEM_TYPE, + sizeof(struct PARAM_TXPOWER_ALL_RATE_POWER_INFO_T)); + + return i4BytesWritten; +} +#endif +static int32_t priv_driver_txpower_man_set(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0, u4Size = 0; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + int8_t *this_char = NULL; + uint32_t u4ParamNum = 0; + uint8_t ucPhyMode = 0; + uint8_t ucTxRate = 0; + uint8_t ucBw = 0; + int8_t iTargetPwr = 0; + struct PARAM_TXPOWER_BY_RATE_SET_T *prPwrCtl = NULL; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + DBGLOG(REQ, INFO, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, INFO, "argc is %d, apcArgv[0] = %s\n\n", i4Argc, *apcArgv); + + this_char = kalStrStr(*apcArgv, "="); + if (!this_char) + return -1; + this_char++; + + DBGLOG(REQ, INFO, "string = %s\n", this_char); + + u4ParamNum = sscanf(this_char, "%d:%d:%d:%d", &ucPhyMode, &ucTxRate, + &ucBw, &iTargetPwr); + + if (u4ParamNum < 0) { + DBGLOG(REQ, WARN, "sscanf input fail\n"); + return -1; + } + + DBGLOG(REQ, INFO, "ParamNum=%d,PhyMod=%d,Rate=%d,Bw=%d,Pwr=%d\n", + u4ParamNum, ucPhyMode, ucTxRate, ucBw, iTargetPwr); + + u4Size = sizeof(struct PARAM_TXPOWER_BY_RATE_SET_T); + + prPwrCtl = + (struct PARAM_TXPOWER_BY_RATE_SET_T *)kalMemAlloc( + u4Size, VIR_MEM_TYPE); + if (!prPwrCtl) + return -1; + + if (u4ParamNum == TXPOWER_MAN_SET_INPUT_ARG_NUM) { + prPwrCtl->u1PhyMode = ucPhyMode; + prPwrCtl->u1TxRate = ucTxRate; + prPwrCtl->u1BW = ucBw; + prPwrCtl->i1TxPower = iTargetPwr; + + rStatus = kalIoctl(prGlueInfo, wlanoidSetTxPowerByRateManual, + prPwrCtl, + sizeof(struct PARAM_TXPOWER_BY_RATE_SET_T), + FALSE, FALSE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + kalMemFree(prPwrCtl, VIR_MEM_TYPE, + sizeof(struct PARAM_TXPOWER_BY_RATE_SET_T)); + return -1; + } + + } else { + DBGLOG(INIT, ERROR, + "[Error]iwpriv wlanXX driver TxPwrManualSet=PhyMode:Rate:Bw:Pwr\n"); + } + + kalMemFree(prPwrCtl, VIR_MEM_TYPE, + sizeof(struct PARAM_TXPOWER_BY_RATE_SET_T)); + + return i4BytesWritten; +} + +static int priv_driver_get_sta_stat(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0, u4Ret, u4StatGroup = 0xFFFFFFFF; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint8_t aucMacAddr[MAC_ADDR_LEN]; + uint8_t ucWlanIndex = 0; + uint8_t *pucMacAddr = NULL; + struct PARAM_HW_WLAN_INFO *prHwWlanInfo = NULL; + struct PARAM_GET_STA_STATISTICS *prQueryStaStatistics = NULL; + u_int8_t fgResetCnt = FALSE; + u_int8_t fgRxCCSel = FALSE; + u_int8_t fgSearchMacAddr = FALSE; + struct BSS_INFO *prAisBssInfo = NULL; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + prAisBssInfo = aisGetAisBssInfo( + prGlueInfo->prAdapter, wlanGetBssIdx(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + if (i4Argc >= 4) { + if (strnicmp(apcArgv[2], CMD_STAT_GROUP_SEL, + strlen(CMD_STAT_GROUP_SEL)) == 0) { + u4Ret = kalkStrtou32(apcArgv[3], 0, &(u4StatGroup)); + + if (u4Ret) + DBGLOG(REQ, LOUD, + "parse get_sta_stat error (Group) u4Ret=%d\n", + u4Ret); + if (u4StatGroup == 0) + u4StatGroup = 0xFFFFFFFF; + + wlanHwAddrToBin(apcArgv[1], &aucMacAddr[0]); + + if (!wlanGetWlanIdxByAddress(prGlueInfo->prAdapter, + &aucMacAddr[0], &ucWlanIndex)) { + DBGLOG(REQ, INFO, + "wlan index of "MACSTR" is not found!\n", + MAC2STR(aucMacAddr)); + goto out; + } + } else { + goto out; + } + } else if (i4Argc >= 3) { + if (strnicmp(apcArgv[1], CMD_STAT_GROUP_SEL, + strlen(CMD_STAT_GROUP_SEL)) == 0) { + u4Ret = kalkStrtou32(apcArgv[2], 0, &(u4StatGroup)); + + if (u4Ret) + DBGLOG(REQ, LOUD, + "parse get_sta_stat error (Group) u4Ret=%d\n", + u4Ret); + if (u4StatGroup == 0) + u4StatGroup = 0xFFFFFFFF; + + if (prAisBssInfo->prStaRecOfAP) { + ucWlanIndex = prAisBssInfo->prStaRecOfAP + ->ucWlanIndex; + } else if (!wlanGetWlanIdxByAddress( + prGlueInfo->prAdapter, NULL, + &ucWlanIndex)) { + DBGLOG(REQ, INFO, + "wlan index of "MACSTR" is not found!\n", + MAC2STR(aucMacAddr)); + goto out; + } + } else { + if (strnicmp(apcArgv[1], CMD_STAT_RESET_CNT, + strlen(CMD_STAT_RESET_CNT)) == 0) { + wlanHwAddrToBin(apcArgv[2], &aucMacAddr[0]); + fgResetCnt = TRUE; + } else if (strnicmp(apcArgv[2], CMD_STAT_RESET_CNT, + strlen(CMD_STAT_RESET_CNT)) == 0) { + wlanHwAddrToBin(apcArgv[1], &aucMacAddr[0]); + fgResetCnt = TRUE; + } else { + wlanHwAddrToBin(apcArgv[1], &aucMacAddr[0]); + fgResetCnt = FALSE; + } + + if (!wlanGetWlanIdxByAddress(prGlueInfo->prAdapter, + &aucMacAddr[0], &ucWlanIndex)) { + DBGLOG(REQ, INFO, + "wlan index of "MACSTR" is not found!\n", + MAC2STR(aucMacAddr)); + goto out; + } + } + } else { + if (i4Argc == 1) { + fgSearchMacAddr = TRUE; + } else if (i4Argc == 2) { + if (strnicmp(apcArgv[1], CMD_STAT_RESET_CNT, + strlen(CMD_STAT_RESET_CNT)) == 0) { + fgResetCnt = TRUE; + fgSearchMacAddr = TRUE; + } else if (strnicmp(apcArgv[1], CMD_STAT_NOISE_SEL, + strlen(CMD_STAT_NOISE_SEL)) == 0) { + fgRxCCSel = TRUE; + fgSearchMacAddr = TRUE; + } else { + wlanHwAddrToBin(apcArgv[1], &aucMacAddr[0]); + + if (!wlanGetWlanIdxByAddress(prGlueInfo-> + prAdapter, &aucMacAddr[0], &ucWlanIndex)) { + DBGLOG(REQ, INFO, + "No connected peer found!\n"); + goto out; + } + } + } + + if (fgSearchMacAddr) { + /* Get AIS AP address for no argument */ + if (prAisBssInfo->prStaRecOfAP) { + ucWlanIndex = prAisBssInfo->prStaRecOfAP + ->ucWlanIndex; + } else if (!wlanGetWlanIdxByAddress(prGlueInfo-> + prAdapter, NULL, &ucWlanIndex)) { + DBGLOG(REQ, INFO, "No connected peer found!\n"); + goto out; + } + } + } + + prHwWlanInfo = (struct PARAM_HW_WLAN_INFO *)kalMemAlloc( + sizeof(struct PARAM_HW_WLAN_INFO), VIR_MEM_TYPE); + if (!prHwWlanInfo) { + DBGLOG(REQ, ERROR, + "Allocate prHwWlanInfo failed!\n"); + i4BytesWritten = -1; + goto out; + } + + prHwWlanInfo->u4Index = ucWlanIndex; + if (fgRxCCSel == TRUE) + prHwWlanInfo->rWtblRxCounter.fgRxCCSel = TRUE; + else + prHwWlanInfo->rWtblRxCounter.fgRxCCSel = FALSE; + + DBGLOG(REQ, INFO, "index = %d i4TotalLen = %d\n", + prHwWlanInfo->u4Index, i4TotalLen); + + /* Get WTBL info */ + rStatus = kalIoctl(prGlueInfo, wlanoidQueryWlanInfo, prHwWlanInfo, + sizeof(struct PARAM_HW_WLAN_INFO), + TRUE, TRUE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, ERROR, "Query prHwWlanInfo failed!\n"); + i4BytesWritten = -1; + goto out; + } + + /* Get Statistics info */ + prQueryStaStatistics = + (struct PARAM_GET_STA_STATISTICS *)kalMemAlloc( + sizeof(struct PARAM_GET_STA_STATISTICS), VIR_MEM_TYPE); + if (!prQueryStaStatistics) { + DBGLOG(REQ, ERROR, + "Allocate prQueryStaStatistics failed!\n"); + i4BytesWritten = -1; + goto out; + } + + prQueryStaStatistics->ucResetCounter = fgResetCnt; + + pucMacAddr = wlanGetStaAddrByWlanIdx(prGlueInfo->prAdapter, + ucWlanIndex); + + if (!pucMacAddr) { + DBGLOG(REQ, ERROR, "Addr of WlanIndex %d is not found!\n", + ucWlanIndex); + i4BytesWritten = -1; + goto out; + } + COPY_MAC_ADDR(prQueryStaStatistics->aucMacAddr, pucMacAddr); + + rStatus = kalIoctl(prGlueInfo, wlanoidQueryStaStatistics, + prQueryStaStatistics, + sizeof(struct PARAM_GET_STA_STATISTICS), + TRUE, TRUE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, ERROR, "Query prQueryStaStatistics failed!\n"); + i4BytesWritten = -1; + goto out; + } + + if (pucMacAddr) { + struct CHIP_DBG_OPS *prChipDbg; + + prChipDbg = prAdapter->chip_info->prDebugOps; + + if (prChipDbg && prChipDbg->show_stat_info) + i4BytesWritten = prChipDbg->show_stat_info(prAdapter, + pcCommand, i4TotalLen, prHwWlanInfo, + prQueryStaStatistics, fgResetCnt, u4StatGroup); + } + DBGLOG(REQ, INFO, "%s: command result is %s\n", __func__, pcCommand); + +out: + if (prHwWlanInfo) + kalMemFree(prHwWlanInfo, VIR_MEM_TYPE, + sizeof(struct PARAM_HW_WLAN_INFO)); + + if (prQueryStaStatistics) + kalMemFree(prQueryStaStatistics, VIR_MEM_TYPE, + sizeof(struct PARAM_GET_STA_STATISTICS)); + + + if (fgResetCnt) + nicRxClearStatistics(prGlueInfo->prAdapter); + + return i4BytesWritten; +} + +static int32_t priv_driver_dump_stat2_info(struct ADAPTER *prAdapter, + IN char *pcCommand, IN int i4TotalLen, + struct UMAC_STAT2_GET *prUmacStat2GetInfo, + struct PARAM_GET_DRV_STATISTICS *prQueryDrvStatistics) +{ + int32_t i4BytesWritten = 0; + uint16_t u2PleTotalRevPage = 0; + uint16_t u2PleTotalSrcPage = 0; + uint16_t u2PseTotalRevPage = 0; + uint16_t u2PseTotalSrcPage = 0; + + u2PleTotalRevPage = prUmacStat2GetInfo->u2PleRevPgHif0Group0 + + prUmacStat2GetInfo->u2PleRevPgCpuGroup2; + + u2PleTotalSrcPage = prUmacStat2GetInfo->u2PleSrvPgHif0Group0 + + prUmacStat2GetInfo->u2PleSrvPgCpuGroup2; + + u2PseTotalRevPage = prUmacStat2GetInfo->u2PseRevPgHif0Group0 + + prUmacStat2GetInfo->u2PseRevPgHif1Group1 + + prUmacStat2GetInfo->u2PseRevPgCpuGroup2 + + prUmacStat2GetInfo->u2PseRevPgLmac0Group3 + + prUmacStat2GetInfo->u2PseRevPgLmac1Group4 + + prUmacStat2GetInfo->u2PseRevPgLmac2Group5 + + prUmacStat2GetInfo->u2PseRevPgPleGroup6; + + u2PseTotalSrcPage = prUmacStat2GetInfo->u2PseSrvPgHif0Group0 + + prUmacStat2GetInfo->u2PseSrvPgHif1Group1 + + prUmacStat2GetInfo->u2PseSrvPgCpuGroup2 + + prUmacStat2GetInfo->u2PseSrvPgLmac0Group3 + + prUmacStat2GetInfo->u2PseSrvPgLmac1Group4 + + prUmacStat2GetInfo->u2PseSrvPgLmac2Group5 + + prUmacStat2GetInfo->u2PseSrvPgPleGroup6; + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", "\n----- Stat2 Info -----\n"); + + + /* Rev Page number Info. */ + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", "\n----- PLE Reservation Page Info. -----\n"); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-26s%s%d\n", "Ple Hif0 Group0 RevPage", " = ", + prUmacStat2GetInfo->u2PleRevPgHif0Group0); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-26s%s%d\n", "Ple Cpu Group2 RevPage", " = ", + prUmacStat2GetInfo->u2PleRevPgCpuGroup2); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-26s%s%d\n", "Ple Total RevPage", " = ", + u2PleTotalRevPage); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", "\n----- PLE Source Page Info. ----------\n"); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-26s%s%d\n", "Ple Hif0 Group0 SrcPage", " = ", + prUmacStat2GetInfo->u2PleSrvPgHif0Group0); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-26s%s%d\n", "Ple Cpu Group2 SrcPage", " = ", + prUmacStat2GetInfo->u2PleSrvPgCpuGroup2); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-26s%s%d\n", "Ple Total SrcPage", " = ", + u2PleTotalSrcPage); + + /* umac MISC Info. */ + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", "\n----- PLE Misc Info. -----------------\n"); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-26s%s%d\n", "ple Total Page Number", " = ", + prUmacStat2GetInfo->u2PleTotalPageNum); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-26s%s%d\n", "ple Free Page Number", " = ", + prUmacStat2GetInfo->u2PleFreePageNum); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-26s%s%d\n", "ple FFA Page Number", " = ", + prUmacStat2GetInfo->u2PleFfaNum); + + /* PSE Info. */ + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", "\n----- PSE Reservation Page Info. -----\n"); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-26s%s%d\n", "Pse Hif0 Group0 RevPage", " = ", + prUmacStat2GetInfo->u2PseRevPgHif0Group0); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-26s%s%d\n", "Pse Hif1 Group1 RevPage", " = ", + prUmacStat2GetInfo->u2PseRevPgHif1Group1); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-26s%s%d\n", "Pse Cpu Group2 RevPage", " = ", + prUmacStat2GetInfo->u2PseRevPgCpuGroup2); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-26s%s%d\n", "Pse Lmac0 Group3 RevPage", " = ", + prUmacStat2GetInfo->u2PseRevPgLmac0Group3); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-26s%s%d\n", "Pse Lmac1 Group4 RevPage", " = ", + prUmacStat2GetInfo->u2PseRevPgLmac1Group4); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-26s%s%d\n", "Pse Lmac2 Group5 RevPage", " = ", + prUmacStat2GetInfo->u2PseRevPgLmac2Group5); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-26s%s%d\n", "Pse Ple Group6 RevPage", " = ", + prUmacStat2GetInfo->u2PseRevPgPleGroup6); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-26s%s%d\n", "Pse Total RevPage", " = ", + u2PseTotalRevPage); + + /* PSE Info. */ + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", "\n----- PSE Source Page Info. ----------\n"); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-26s%s%d\n", "Pse Hif0 Group0 SrcPage", " = ", + prUmacStat2GetInfo->u2PseSrvPgHif0Group0); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-26s%s%d\n", "Pse Hif1 Group1 SrcPage", " = ", + prUmacStat2GetInfo->u2PseSrvPgHif1Group1); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-26s%s%d\n", "Pse Cpu Group2 SrcPage", " = ", + prUmacStat2GetInfo->u2PseSrvPgCpuGroup2); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-26s%s%d\n", "Pse Lmac0 Group3 SrcPage", " = ", + prUmacStat2GetInfo->u2PseSrvPgLmac0Group3); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-26s%s%d\n", "Pse Lmac1 Group4 SrcPage", " = ", + prUmacStat2GetInfo->u2PseSrvPgLmac1Group4); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-26s%s%d\n", "Pse Lmac2 Group5 SrcPage", " = ", + prUmacStat2GetInfo->u2PseSrvPgLmac2Group5); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-26s%s%d\n", "Pse Ple Group6 SrcPage", " = ", + prUmacStat2GetInfo->u2PseSrvPgPleGroup6); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-26s%s%d\n", "Pse Total SrcPage", " = ", + u2PseTotalSrcPage); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", "\n----- PSE Misc Info. -----------------\n"); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-26s%s%d\n", "pse Total Page Number", " = ", + prUmacStat2GetInfo->u2PseTotalPageNum); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-26s%s%d\n", "pse Free Page Number", " = ", + prUmacStat2GetInfo->u2PseFreePageNum); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-26s%s%d\n", "pse FFA Page Number", " = ", + prUmacStat2GetInfo->u2PseFfaNum); + + + /* driver info */ + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", "\n\n----- DRV Stat -----------------------\n\n"); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-26s%s%d\n", "Pending Data", " = ", + prQueryDrvStatistics->i4TxPendingFrameNum); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-26s%s%d\n", "Pending Sec", " = ", + prQueryDrvStatistics->i4TxPendingSecurityFrameNum); +#if 0 + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-26s%s%s\n", "Tx Pending Cmd Number", " = ", + prQueryDrvStatistics->i4TxPendingCmdNum); +#endif + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-26s%s%d\n", "Tx Pending For-pkt Number", " = ", + prQueryDrvStatistics->i4PendingFwdFrameCount); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-26s%s%d\n", "MsduInfo Available Number", " = ", + prQueryDrvStatistics->u4MsduNumElem); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-26s%s%d\n", "MgmtTxRing Pending Number", " = ", + prQueryDrvStatistics->u4TxMgmtTxringQueueNumElem); + + /* Driver Rx Info. */ + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-26s%s%d\n", "Rx Free Sw Rfb Number", " = ", + prQueryDrvStatistics->u4RxFreeSwRfbMsduNumElem); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-26s%s%d\n", "Rx Received Sw Rfb Number", " = ", + prQueryDrvStatistics->u4RxReceivedRfbNumElem); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-26s%s%d\n", "Rx Indicated Sw Rfb Number", " = ", + prQueryDrvStatistics->u4RxIndicatedNumElem); + + return i4BytesWritten; +} + +static int priv_driver_get_sta_stat2(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + int32_t i4BytesWritten = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + int32_t i4ArgNum = 1; + struct UMAC_STAT2_GET *prUmacStat2GetInfo; + struct PARAM_GET_DRV_STATISTICS *prQueryDrvStatistics; + struct QUE *prQueList, *prTxMgmtTxRingQueList; + struct RX_CTRL *prRxCtrl; + + KAL_SPIN_LOCK_DECLARATION(); + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + if (i4Argc < i4ArgNum) + return -1; + + prQueList = &prAdapter->rTxCtrl.rFreeMsduInfoList; + + prTxMgmtTxRingQueList = &prAdapter->rTxCtrl.rTxMgmtTxingQueue; + + prRxCtrl = &prAdapter->rRxCtrl; + ASSERT(prRxCtrl); + + /* to do for UMAC Dump */ + prUmacStat2GetInfo = (struct UMAC_STAT2_GET *)kalMemAlloc( + sizeof(struct UMAC_STAT2_GET), VIR_MEM_TYPE); + if (prUmacStat2GetInfo == NULL) + return -1; + + halUmacInfoGetMiscStatus(prAdapter, prUmacStat2GetInfo); + + + /* Get Driver stat info */ + prQueryDrvStatistics = + (struct PARAM_GET_DRV_STATISTICS *)kalMemAlloc(sizeof( + struct PARAM_GET_DRV_STATISTICS), VIR_MEM_TYPE); + if (prQueryDrvStatistics == NULL) { + kalMemFree(prUmacStat2GetInfo, VIR_MEM_TYPE, + sizeof(struct UMAC_STAT2_GET)); + return -1; + } + + prQueryDrvStatistics->i4TxPendingFrameNum = + (uint32_t) GLUE_GET_REF_CNT(prGlueInfo->i4TxPendingFrameNum); + prQueryDrvStatistics->i4TxPendingSecurityFrameNum = + (uint32_t) GLUE_GET_REF_CNT( + prGlueInfo->i4TxPendingSecurityFrameNum); +#if 0 + prQueryDrvStatistics->i4TxPendingCmdNum = + (uint32_t) GLUE_GET_REF_CNT(prGlueInfo->i4TxPendingCmdNum); +#endif + + prQueryDrvStatistics->i4PendingFwdFrameCount = + prAdapter->rTxCtrl.i4PendingFwdFrameCount; + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); + prQueryDrvStatistics->u4MsduNumElem = prQueList->u4NumElem; + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); + prQueryDrvStatistics->u4TxMgmtTxringQueueNumElem = + prTxMgmtTxRingQueList->u4NumElem; + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); + + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_FREE_QUE); + prQueryDrvStatistics->u4RxFreeSwRfbMsduNumElem = + prRxCtrl->rFreeSwRfbList.u4NumElem; + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_FREE_QUE); + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); + prQueryDrvStatistics->u4RxReceivedRfbNumElem = + prRxCtrl->rReceivedRfbList.u4NumElem; + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_FREE_QUE); + prQueryDrvStatistics->u4RxIndicatedNumElem = + prRxCtrl->rIndicatedRfbList.u4NumElem; + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_FREE_QUE); + + i4BytesWritten = priv_driver_dump_stat2_info(prAdapter, pcCommand, + i4TotalLen, prUmacStat2GetInfo, prQueryDrvStatistics); + + kalMemFree(prUmacStat2GetInfo, VIR_MEM_TYPE, + sizeof(struct UMAC_STAT2_GET)); + kalMemFree(prQueryDrvStatistics, VIR_MEM_TYPE, + sizeof(struct PARAM_GET_DRV_STATISTICS)); + + return i4BytesWritten; +} + + +static int32_t priv_driver_dump_rx_stat_info(struct ADAPTER *prAdapter, + IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen, + IN u_int8_t fgResetCnt) +{ + int32_t i4BytesWritten = 0; + uint32_t u4RxVector0 = 0, u4RxVector2 = 0, u4RxVector3 = 0, + u4RxVector4 = 0; + uint8_t ucStaIdx, ucWlanIndex = 0, cbw; + u_int8_t fgWlanIdxFound = TRUE, fgSkipRxV = FALSE; + uint32_t u4FAGCRssiWBR0, u4FAGCRssiIBR0; + uint32_t u4Value, u4Foe, foe_const; + static uint32_t au4MacMdrdy[ENUM_BAND_NUM] = {0}; + static uint32_t au4FcsError[ENUM_BAND_NUM] = {0}; + static uint32_t au4OutOfResource[ENUM_BAND_NUM] = {0}; + static uint32_t au4LengthMismatch[ENUM_BAND_NUM] = {0}; + struct STA_RECORD *prStaRecOfAP; + + uint8_t ucBssIndex = AIS_DEFAULT_INDEX; + + prStaRecOfAP = + aisGetStaRecOfAP(prAdapter, ucBssIndex); + + au4MacMdrdy[ENUM_BAND_0] += htonl(g_HqaRxStat.MAC_Mdrdy); + au4MacMdrdy[ENUM_BAND_1] += htonl(g_HqaRxStat.MAC_Mdrdy1); + au4FcsError[ENUM_BAND_0] += htonl(g_HqaRxStat.MAC_FCS_Err); + au4FcsError[ENUM_BAND_1] += htonl(g_HqaRxStat.MAC_FCS_Err1); + au4OutOfResource[ENUM_BAND_0] += htonl(g_HqaRxStat.OutOfResource); + au4OutOfResource[ENUM_BAND_1] += htonl(g_HqaRxStat.OutOfResource1); + au4LengthMismatch[ENUM_BAND_0] += htonl( + g_HqaRxStat.LengthMismatchCount_B0); + au4LengthMismatch[ENUM_BAND_1] += htonl( + g_HqaRxStat.LengthMismatchCount_B1); + + DBGLOG(INIT, INFO, "fgResetCnt = %d\n", fgResetCnt); + if (fgResetCnt) { + kalMemZero(au4MacMdrdy, sizeof(au4MacMdrdy)); + kalMemZero(au4FcsError, sizeof(au4FcsError)); + kalMemZero(au4OutOfResource, sizeof(au4OutOfResource)); + kalMemZero(au4LengthMismatch, sizeof(au4LengthMismatch)); + } + + if (prStaRecOfAP) + ucWlanIndex = + prStaRecOfAP->ucWlanIndex; + else if (!wlanGetWlanIdxByAddress(prAdapter, NULL, &ucWlanIndex)) + fgWlanIdxFound = FALSE; + + if (fgWlanIdxFound) { + if (wlanGetStaIdxByWlanIdx(prAdapter, ucWlanIndex, &ucStaIdx) + == WLAN_STATUS_SUCCESS) { + u4RxVector0 = prAdapter->arStaRec[ucStaIdx].u4RxVector0; + u4RxVector2 = prAdapter->arStaRec[ucStaIdx].u4RxVector2; + u4RxVector3 = prAdapter->arStaRec[ucStaIdx].u4RxVector3; + u4RxVector4 = prAdapter->arStaRec[ucStaIdx].u4RxVector4; + } else{ + fgSkipRxV = TRUE; + } + } else{ + fgSkipRxV = TRUE; + } + DBGLOG(INIT, INFO, "g_HqaRxStat.MAC_Mdrdy = %d\n", + htonl(g_HqaRxStat.MAC_Mdrdy)); + DBGLOG(INIT, INFO, "au4MacMdrdy[ENUM_BAND_0] = %d\n", + au4MacMdrdy[ENUM_BAND_0]); + DBGLOG(INIT, INFO, "g_HqaRxStat.PhyMdrdyOFDM = %d\n", + htonl(g_HqaRxStat.PhyMdrdyOFDM)); + DBGLOG(INIT, INFO, "g_HqaRxStat.MAC_FCS_Err= %d\n", + htonl(g_HqaRxStat.MAC_FCS_Err)); + DBGLOG(INIT, INFO, "au4FcsError[ENUM_BAND_0]= %d\n", + au4FcsError[ENUM_BAND_0]); + DBGLOG(INIT, INFO, "g_HqaRxStat.FCSErr_OFDM = %d\n", + htonl(g_HqaRxStat.FCSErr_OFDM)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%s", "\n\nRX Stat:\n"); +#if 1 + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "PER0", " = ", + htonl(g_HqaRxStat.PER0)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "PER1", " = ", + htonl(g_HqaRxStat.PER1)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "RX OK0", " = ", + au4MacMdrdy[ENUM_BAND_0] - au4FcsError[ENUM_BAND_0]); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "RX OK1", " = ", + au4MacMdrdy[ENUM_BAND_1] - au4FcsError[ENUM_BAND_1]); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "RCPI0", " = ", + htonl(g_HqaRxStat.RCPI0)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "RCPI1", " = ", + htonl(g_HqaRxStat.RCPI1)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "MuRxCnt", " = ", + htonl(g_HqaRxStat.MRURxCount)); +#endif + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "MAC Mdrdy0 diff", " = ", + htonl(g_HqaRxStat.MAC_Mdrdy)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "MAC Mdrdy0", " = ", + au4MacMdrdy[ENUM_BAND_0]); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "MAC Mdrdy1 diff", " = ", + htonl(g_HqaRxStat.MAC_Mdrdy1)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "MAC Mdrdy1", " = ", + au4MacMdrdy[ENUM_BAND_1]); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "FCS Err0", " = ", + au4FcsError[ENUM_BAND_0]); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "FCS Err1", " = ", + au4FcsError[ENUM_BAND_1]); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "CCK PD Cnt B0", " = ", + htonl(g_HqaRxStat.CCK_PD)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "CCK PD Cnt B1", " = ", + htonl(g_HqaRxStat.CCK_PD_Band1)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "CCK SIG Err B0", " = ", + htonl(g_HqaRxStat.CCK_SIG_Err)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "CCK SIG Err B1", " = ", + htonl(g_HqaRxStat.CCK_SIG_Err_Band1)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "OFDM PD Cnt B0", " = ", + htonl(g_HqaRxStat.OFDM_PD)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "OFDM PD Cnt B1", " = ", + htonl(g_HqaRxStat.OFDM_PD_Band1)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "OFDM TAG Error", " = ", + htonl(g_HqaRxStat.OFDM_TAG_Err)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "CCK SFD Err B0", " = ", + htonl(g_HqaRxStat.CCK_SFD_Err)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "CCK SFD Err B1", " = ", + htonl(g_HqaRxStat.CCK_SFD_Err_Band1)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "OFDM SIG Err B0", " = ", + htonl(g_HqaRxStat.OFDM_SIG_Err)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "OFDM SIG Err B1", " = ", + htonl(g_HqaRxStat.OFDM_SIG_Err_Band1)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "CCK FCS Err B0", " = ", + htonl(g_HqaRxStat.FCSErr_CCK)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "CCK FCS Err B1", " = ", + htonl(g_HqaRxStat.CCK_FCS_Err_Band1)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "OFDM FCS Err B0", " = ", + htonl(g_HqaRxStat.FCSErr_OFDM)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "OFDM FCS Err B1", " = ", + htonl(g_HqaRxStat.OFDM_FCS_Err_Band1)); + + if (!fgSkipRxV) { + u4FAGCRssiIBR0 = (u4RxVector2 & BITS(16, 23)) >> 16; + u4FAGCRssiWBR0 = (u4RxVector2 & BITS(24, 31)) >> 24; + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "FAGC RSSI W", " = ", + (u4FAGCRssiWBR0 >= 128) ? (u4FAGCRssiWBR0 - 256) : + (u4FAGCRssiWBR0)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "FAGC RSSI I", " = ", + (u4FAGCRssiIBR0 >= 128) ? (u4FAGCRssiIBR0 - 256) : + (u4FAGCRssiIBR0)); + } else{ + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "FAGC RSSI W", " = ", + htonl(g_HqaRxStat.FAGCRssiWBR0)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "FAGC RSSI I", " = ", + htonl(g_HqaRxStat.FAGCRssiIBR0)); + } + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "CCK MDRDY B0", " = ", + htonl(g_HqaRxStat.PhyMdrdyCCK)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "CCK MDRDY B1", " = ", + htonl(g_HqaRxStat.PHY_CCK_MDRDY_Band1)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "OFDM MDRDY B0", " = ", + htonl(g_HqaRxStat.PhyMdrdyOFDM)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "OFDM MDRDY B1", " = ", + htonl(g_HqaRxStat.PHY_OFDM_MDRDY_Band1)); + + if (!fgSkipRxV) { +#if 0 + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "Driver RX Cnt0", " = ", + htonl(g_HqaRxStat.DriverRxCount)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "Driver RX Cnt1", " = ", + htonl(g_HqaRxStat.DriverRxCount1)); +#endif + u4Value = (u4RxVector0 & BITS(12, 14)) >> 12; + if (u4Value == 0) { + u4Foe = (((u4RxVector4 & BITS(7, 31)) >> 7) & 0x7ff); + u4Foe = (u4Foe * 1000)>>11; + } else{ + cbw = ((u4RxVector0 & BITS(15, 16)) >> 15); + foe_const = ((1 << (cbw + 1)) & 0xf) * 10000; + u4Foe = (((u4RxVector4 & BITS(7, 31)) >> 7) & 0xfff); + u4Foe = (u4Foe * foe_const) >> 15; + } + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "Freq Offset From RX", " = ", u4Foe); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "RX SNR (dB)", " = ", + (uint32_t)(((u4RxVector4 & BITS(26, 31)) >> 26) - 16)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "uint8_t RX0", " = ", + (uint32_t)(u4RxVector3 & BITS(0, 7))); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "uint8_t RX1", " = ", + (uint32_t)((u4RxVector3 & BITS(8, 15)) >> 8)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "uint8_t RX2", " = ", + ((u4RxVector3 & BITS(16, 23)) >> 16) == 0xFF ? + (0) : ((uint32_t)(u4RxVector3 & BITS(16, 23)) >> 16)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "uint8_t RX3", " = ", + ((u4RxVector3 & BITS(24, 31)) >> 24) == 0xFF ? + (0) : ((uint32_t)(u4RxVector3 & BITS(24, 31)) >> 24)); + } else{ +#if 1 + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "Driver RX Cnt0", + " = ", + htonl(g_HqaRxStat.DriverRxCount)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "Driver RX Cnt1", + " = ", + htonl(g_HqaRxStat.DriverRxCount1)); +#endif + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", + "Freq Offset From RX", + " = ", + htonl(g_HqaRxStat.FreqOffsetFromRX)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%s\n", "RX SNR (dB)", + " = ", "N/A"); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%s\n", "uint8_t RX0", + " = ", "N/A"); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%s\n", "uint8_t RX1", + " = ", "N/A"); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%s\n", "uint8_t RX2", + " = ", "N/A"); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%s\n", "uint8_t RX3", + " = ", "N/A"); + } + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "Inst RSSI IB R0", " = ", + htonl(g_HqaRxStat.InstRssiIBR0)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "Inst RSSI WB R0", " = ", + htonl(g_HqaRxStat.InstRssiWBR0)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "Inst RSSI IB R1", " = ", + htonl(g_HqaRxStat.InstRssiIBR1)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "Inst RSSI WB R1", " = ", + htonl(g_HqaRxStat.InstRssiWBR1)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "Inst RSSI IB R2", " = ", + htonl(g_HqaRxStat.InstRssiIBR2)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "Inst RSSI WB R2", " = ", + htonl(g_HqaRxStat.InstRssiWBR2)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "Inst RSSI IB R3", " = ", + htonl(g_HqaRxStat.InstRssiIBR3)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "Inst RSSI WB R3", " = ", + htonl(g_HqaRxStat.InstRssiWBR3)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "ACI Hit Lower", " = ", + htonl(g_HqaRxStat.ACIHitLower)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "ACI Hit Higher", + " = ", htonl(g_HqaRxStat.ACIHitUpper)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "OutOf Resource Pkt0", + " = ", au4OutOfResource[ENUM_BAND_0]); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "OutOf Resource Pkt1", + " = ", au4OutOfResource[ENUM_BAND_1]); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "Len Mismatch Cnt B0", + " = ", au4LengthMismatch[ENUM_BAND_0]); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "Len Mismatch Cnt B1", + " = ", au4LengthMismatch[ENUM_BAND_1]); +#if 0 + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%-20s%s%d\n", "MU RX Cnt", " = ", + htonl(g_HqaRxStat.MRURxCount)); +#endif + return i4BytesWritten; +} + + +static int priv_driver_show_rx_stat(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + struct PARAM_CUSTOM_ACCESS_RX_STAT *prRxStatisticsTest; + u_int8_t fgResetCnt = FALSE; + struct PARAM_CUSTOM_SW_CTRL_STRUCT rSwCtrlInfo; + uint32_t u4Id = 0x99980000; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + DBGLOG(INIT, ERROR, + "MT6632 : priv_driver_show_rx_stat %s, i4Argc[%d]\n", + pcCommand, i4Argc); + + if (i4Argc >= 2) { + if (strnicmp(apcArgv[1], CMD_STAT_RESET_CNT, + strlen(CMD_STAT_RESET_CNT)) == 0) + fgResetCnt = TRUE; + } + + if (i4Argc >= 1) { + if (fgResetCnt) { + rSwCtrlInfo.u4Id = u4Id; + rSwCtrlInfo.u4Data = 0; + + rStatus = kalIoctl(prGlueInfo, wlanoidSetSwCtrlWrite, + &rSwCtrlInfo, sizeof(rSwCtrlInfo), + FALSE, FALSE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) + return -1; + } + + prRxStatisticsTest = + (struct PARAM_CUSTOM_ACCESS_RX_STAT *)kalMemAlloc( + sizeof(struct PARAM_CUSTOM_ACCESS_RX_STAT), + VIR_MEM_TYPE); + if (!prRxStatisticsTest) + return -1; + + prRxStatisticsTest->u4SeqNum = u4RxStatSeqNum; + prRxStatisticsTest->u4TotalNum = + sizeof(struct PARAM_RX_STAT) / 4; + + rStatus = kalIoctl(prGlueInfo, wlanoidQueryRxStatistics, + prRxStatisticsTest, + sizeof(struct PARAM_CUSTOM_ACCESS_RX_STAT), + TRUE, TRUE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + kalMemFree(prRxStatisticsTest, VIR_MEM_TYPE, + sizeof(struct PARAM_CUSTOM_ACCESS_RX_STAT)); + return -1; + } + + i4BytesWritten = priv_driver_dump_rx_stat_info(prAdapter, + prNetDev, pcCommand, i4TotalLen, fgResetCnt); + + kalMemFree(prRxStatisticsTest, VIR_MEM_TYPE, + sizeof(struct PARAM_CUSTOM_ACCESS_RX_STAT)); + } + + return i4BytesWritten; +} + +/*----------------------------------------------------------------------------*/ +/* + * @ The function will set policy of ACL. + * 0: disable ACL + * 1: enable accept list + * 2: enable deny list + * example: iwpriv p2p0 driver "set_acl_policy 1" + */ +/*----------------------------------------------------------------------------*/ +static int priv_driver_set_acl_policy(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + struct BSS_INFO *prBssInfo = NULL; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + int32_t i4Argc = 0, i4BytesWritten = 0, i4Ret = 0, i4Policy = 0; + uint8_t ucRoleIdx = 0, ucBssIdx = 0; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + /* get Bss Index from ndev */ + if (mtk_Netdev_To_RoleIdx(prGlueInfo, prNetDev, &ucRoleIdx) != 0) + return -1; + if (p2pFuncRoleToBssIdx(prGlueInfo->prAdapter, ucRoleIdx, &ucBssIdx) != + WLAN_STATUS_SUCCESS) + return -1; + + prBssInfo = prAdapter->aprBssInfo[ucBssIdx]; + + DBGLOG(REQ, LOUD, "ucRoleIdx %hhu ucBssIdx %hhu\n", ucRoleIdx, + ucBssIdx); + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + if (i4Argc < 2) + return -1; + + i4Ret = kalkStrtou32(apcArgv[1], 0, &i4Policy); + if (i4Ret) { + DBGLOG(REQ, ERROR, "integer format error i4Ret=%d\n", i4Ret); + return -1; + } + + switch (i4Policy) { + case PARAM_CUSTOM_ACL_POLICY_DISABLE: + case PARAM_CUSTOM_ACL_POLICY_ACCEPT: + case PARAM_CUSTOM_ACL_POLICY_DENY: + prBssInfo->rACL.ePolicy = i4Policy; + break; + default: /*Invalid argument */ + DBGLOG(REQ, ERROR, "Invalid ACL Policy=%d\n", i4Policy); + return -1; + } + + DBGLOG(REQ, TRACE, "ucBssIdx[%hhu] ACL Policy=%d\n", ucBssIdx, + prBssInfo->rACL.ePolicy); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "ucBssIdx[%hhu] ACL Policy=%d\n", + ucBssIdx, prBssInfo->rACL.ePolicy); + + /* check if the change in ACL affects any existent association */ + if (prBssInfo->rACL.ePolicy != PARAM_CUSTOM_ACL_POLICY_DISABLE) + p2pRoleUpdateACLEntry(prAdapter, ucBssIdx); + + DBGLOG(REQ, INFO, "%s: command result is %s\n", __func__, pcCommand); + + return i4BytesWritten; +} /* priv_driver_set_acl_policy */ + +static int32_t priv_driver_inspect_mac_addr(IN char *pcMacAddr) +{ + int32_t i = 0; + + if (pcMacAddr == NULL) + return -1; + + for (i = 0; i < 17; i++) { + if ((i % 3 != 2) && (!kalIsXdigit(pcMacAddr[i]))) { + DBGLOG(REQ, ERROR, "[%c] is not hex digit\n", + pcMacAddr[i]); + return -1; + } + if ((i % 3 == 2) && (pcMacAddr[i] != ':')) { + DBGLOG(REQ, ERROR, "[%c]separate symbol is error\n", + pcMacAddr[i]); + return -1; + } + } + + if (pcMacAddr[17] != '\0') { + DBGLOG(REQ, ERROR, "no null-terminated character\n"); + return -1; + } + + return 0; +} + +/*----------------------------------------------------------------------------*/ +/* + * @ The function will add entry to ACL for accept or deny list. + * example: iwpriv p2p0 driver "add_acl_entry 01:02:03:04:05:06" + */ +/*----------------------------------------------------------------------------*/ +static int priv_driver_add_acl_entry(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + struct BSS_INFO *prBssInfo = NULL; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint8_t aucMacAddr[MAC_ADDR_LEN] = {0}; + int32_t i = 0, i4Argc = 0, i4BytesWritten = 0, i4Ret = 0; + uint8_t ucRoleIdx = 0, ucBssIdx = 0; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + /* get Bss Index from ndev */ + if (mtk_Netdev_To_RoleIdx(prGlueInfo, prNetDev, &ucRoleIdx) != 0) + return -1; + if (p2pFuncRoleToBssIdx(prGlueInfo->prAdapter, ucRoleIdx, &ucBssIdx) != + WLAN_STATUS_SUCCESS) + return -1; + + prBssInfo = prAdapter->aprBssInfo[ucBssIdx]; + + DBGLOG(REQ, LOUD, "ucRoleIdx %hhu ucBssIdx %hhu\n", ucRoleIdx, + ucBssIdx); + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + if (i4Argc < 2) + return -1; + + i4Ret = priv_driver_inspect_mac_addr(apcArgv[1]); + if (i4Ret) { + DBGLOG(REQ, ERROR, "inspect mac format error u4Ret=%d\n", + i4Ret); + return -1; + } + + i4Ret = sscanf(apcArgv[1], "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", + &aucMacAddr[0], &aucMacAddr[1], &aucMacAddr[2], + &aucMacAddr[3], &aucMacAddr[4], &aucMacAddr[5]); + + if (i4Ret != MAC_ADDR_LEN) { + DBGLOG(REQ, ERROR, "sscanf mac format fail u4Ret=%d\n", i4Ret); + return -1; + } + + for (i = 0; i <= prBssInfo->rACL.u4Num; i++) { + if (memcmp(prBssInfo->rACL.rEntry[i].aucAddr, &aucMacAddr, + MAC_ADDR_LEN) == 0) { + DBGLOG(REQ, ERROR, "add this mac [" MACSTR + "] is duplicate.\n", MAC2STR(aucMacAddr)); + return -1; + } + } + + if ((i < 1) || (i > MAX_NUMBER_OF_ACL)) { + DBGLOG(REQ, ERROR, "idx[%d] error or ACL is full.\n", i); + return -1; + } + + memcpy(prBssInfo->rACL.rEntry[i-1].aucAddr, &aucMacAddr, MAC_ADDR_LEN); + prBssInfo->rACL.u4Num = i; + DBGLOG(REQ, TRACE, "add mac addr [" MACSTR "] to ACL(%d).\n", + MAC2STR(prBssInfo->rACL.rEntry[i-1].aucAddr), i); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "add mac addr [" MACSTR "] to ACL(%d)\n", + MAC2STR(prBssInfo->rACL.rEntry[i-1].aucAddr), + i); + + /* Check if the change in ACL affects any existent association. */ + if (prBssInfo->rACL.ePolicy == PARAM_CUSTOM_ACL_POLICY_DENY) + p2pRoleUpdateACLEntry(prAdapter, ucBssIdx); + + DBGLOG(REQ, INFO, "%s: command result is %s\n", __func__, pcCommand); + + return i4BytesWritten; +} /* priv_driver_add_acl_entry */ + +/*----------------------------------------------------------------------------*/ +/* + * @ The function will delete entry to ACL for accept or deny list. + * example: iwpriv p2p0 driver "add_del_entry 01:02:03:04:05:06" + */ +/*----------------------------------------------------------------------------*/ +static int priv_driver_del_acl_entry(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + struct BSS_INFO *prBssInfo = NULL; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint8_t aucMacAddr[MAC_ADDR_LEN] = {0}; + int32_t i = 0, j = 0, i4Argc = 0, i4BytesWritten = 0, i4Ret = 0; + uint8_t ucRoleIdx = 0, ucBssIdx = 0; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + /* get Bss Index from ndev */ + if (mtk_Netdev_To_RoleIdx(prGlueInfo, prNetDev, &ucRoleIdx) != 0) + return -1; + if (p2pFuncRoleToBssIdx(prGlueInfo->prAdapter, ucRoleIdx, &ucBssIdx) != + WLAN_STATUS_SUCCESS) + return -1; + + prBssInfo = prAdapter->aprBssInfo[ucBssIdx]; + + DBGLOG(REQ, LOUD, "ucRoleIdx %hhu ucBssIdx %hhu\n", ucRoleIdx, + ucBssIdx); + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + if (i4Argc < 2) + return -1; + + i4Ret = priv_driver_inspect_mac_addr(apcArgv[1]); + if (i4Ret) { + DBGLOG(REQ, ERROR, "inspect mac format error u4Ret=%d\n", + i4Ret); + return -1; + } + + i4Ret = sscanf(apcArgv[1], "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", + &aucMacAddr[0], &aucMacAddr[1], &aucMacAddr[2], + &aucMacAddr[3], &aucMacAddr[4], &aucMacAddr[5]); + + if (i4Ret != MAC_ADDR_LEN) { + DBGLOG(REQ, ERROR, "sscanf mac format fail u4Ret=%d\n", i4Ret); + return -1; + } + + for (i = 0; i < prBssInfo->rACL.u4Num; i++) { + if (memcmp(prBssInfo->rACL.rEntry[i].aucAddr, &aucMacAddr, + MAC_ADDR_LEN) == 0) { + memset(&prBssInfo->rACL.rEntry[i], 0x00, + sizeof(struct PARAM_CUSTOM_ACL_ENTRY)); + DBGLOG(REQ, TRACE, "delete this mac [" MACSTR "]\n", + MAC2STR(aucMacAddr)); + + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "delete this mac [" MACSTR "] from ACL(%d)\n", + MAC2STR(aucMacAddr), i+1); + break; + } + } + + if ((prBssInfo->rACL.u4Num == 0) || (i == MAX_NUMBER_OF_ACL)) { + DBGLOG(REQ, ERROR, "delete entry fail, num of entries=%d\n", i); + return -1; + } + + for (j = i+1; j < prBssInfo->rACL.u4Num; j++) + memcpy(prBssInfo->rACL.rEntry[j-1].aucAddr, + prBssInfo->rACL.rEntry[j].aucAddr, MAC_ADDR_LEN); + + prBssInfo->rACL.u4Num = j-1; + memset(prBssInfo->rACL.rEntry[j-1].aucAddr, 0x00, MAC_ADDR_LEN); + + /* check if the change in ACL affects any existent association */ + if (prBssInfo->rACL.ePolicy == PARAM_CUSTOM_ACL_POLICY_ACCEPT) + p2pRoleUpdateACLEntry(prAdapter, ucBssIdx); + + DBGLOG(REQ, INFO, "%s: command result is %s\n", __func__, pcCommand); + + return i4BytesWritten; +} /* priv_driver_del_acl_entry */ + +/*----------------------------------------------------------------------------*/ +/* + * @ The function will show all entries to ACL for accept or deny list. + * example: iwpriv p2p0 driver "show_acl_entry" + */ +/*----------------------------------------------------------------------------*/ +static int priv_driver_show_acl_entry(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + struct BSS_INFO *prBssInfo = NULL; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + int32_t i = 0, i4Argc = 0, i4BytesWritten = 0; + uint8_t ucRoleIdx = 0, ucBssIdx = 0; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + /* get Bss Index from ndev */ + if (mtk_Netdev_To_RoleIdx(prGlueInfo, prNetDev, &ucRoleIdx) != 0) + return -1; + if (p2pFuncRoleToBssIdx(prGlueInfo->prAdapter, ucRoleIdx, &ucBssIdx) != + WLAN_STATUS_SUCCESS) + return -1; + + prBssInfo = prAdapter->aprBssInfo[ucBssIdx]; + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + DBGLOG(REQ, TRACE, "ACL Policy = %d\n", prBssInfo->rACL.ePolicy); + DBGLOG(REQ, TRACE, "Total ACLs = %d\n", prBssInfo->rACL.u4Num); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "ACL Policy = %d, Total ACLs = %d\n", + prBssInfo->rACL.ePolicy, + prBssInfo->rACL.u4Num); + + for (i = 0; i < prBssInfo->rACL.u4Num; i++) { + DBGLOG(REQ, TRACE, "ACL(%d): [" MACSTR "]\n", i+1, + MAC2STR(prBssInfo->rACL.rEntry[i].aucAddr)); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "ACL(%d): [" MACSTR + "]\n", i+1, MAC2STR(prBssInfo->rACL.rEntry[i].aucAddr)); + } + + return i4BytesWritten; +} /* priv_driver_show_acl_entry */ + +/*----------------------------------------------------------------------------*/ +/* + * @ The function will clear all entries to ACL for accept or deny list. + * example: iwpriv p2p0 driver "clear_acl_entry" + */ +/*----------------------------------------------------------------------------*/ +static int priv_driver_clear_acl_entry(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + struct BSS_INFO *prBssInfo = NULL; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + int32_t i4Argc = 0, i4BytesWritten = 0; + uint8_t ucRoleIdx = 0, ucBssIdx = 0; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + /* get Bss Index from ndev */ + if (mtk_Netdev_To_RoleIdx(prGlueInfo, prNetDev, &ucRoleIdx) != 0) + return -1; + if (p2pFuncRoleToBssIdx(prGlueInfo->prAdapter, ucRoleIdx, &ucBssIdx) != + WLAN_STATUS_SUCCESS) + return -1; + + prBssInfo = prAdapter->aprBssInfo[ucBssIdx]; + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + if (prBssInfo->rACL.u4Num) { + memset(&prBssInfo->rACL.rEntry[0], 0x00, + sizeof(struct PARAM_CUSTOM_ACL_ENTRY) * MAC_ADDR_LEN); + prBssInfo->rACL.u4Num = 0; + } + + DBGLOG(REQ, TRACE, "ACL Policy = %d\n", prBssInfo->rACL.ePolicy); + DBGLOG(REQ, TRACE, "Total ACLs = %d\n", prBssInfo->rACL.u4Num); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "ACL Policy = %d, Total ACLs = %d\n", + prBssInfo->rACL.ePolicy, + prBssInfo->rACL.u4Num); + + /* check if the change in ACL affects any existent association */ + if (prBssInfo->rACL.ePolicy == PARAM_CUSTOM_ACL_POLICY_ACCEPT) + p2pRoleUpdateACLEntry(prAdapter, ucBssIdx); + + return i4BytesWritten; +} /* priv_driver_clear_acl_entry */ + +static int priv_driver_get_drv_mcr(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint32_t u4Ret; + + /* Add Antenna Selection Input */ + /* INT_32 i4ArgNum_with_ant_sel = 3; */ + + int32_t i4ArgNum = 2; + + struct CMD_ACCESS_REG rCmdAccessReg; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + if (i4Argc >= i4ArgNum) { + rCmdAccessReg.u4Address = 0; + u4Ret = kalkStrtou32(apcArgv[1], 0, &(rCmdAccessReg.u4Address)); + if (u4Ret) + DBGLOG(REQ, LOUD, + "parse get_drv_mcr error (Address) u4Ret=%d\n", + u4Ret); + + /* rCmdAccessReg.u4Address = kalStrtoul(apcArgv[1], NULL, 0); */ + rCmdAccessReg.u4Data = 0; + + DBGLOG(REQ, LOUD, "address is %x\n", rCmdAccessReg.u4Address); + + rStatus = kalIoctl(prGlueInfo, wlanoidQueryDrvMcrRead, + &rCmdAccessReg, sizeof(rCmdAccessReg), + TRUE, TRUE, TRUE, &u4BufLen); + + DBGLOG(REQ, LOUD, "rStatus %u\n", rStatus); + if (rStatus != WLAN_STATUS_SUCCESS) + return -1; + + i4BytesWritten = kalSnprintf(pcCommand, i4TotalLen, "0x%08x", + (unsigned int)rCmdAccessReg.u4Data); + DBGLOG(REQ, INFO, "%s: command result is %s\n", __func__, + pcCommand); + } + + return i4BytesWritten; + +} /* priv_driver_get_drv_mcr */ + +int priv_driver_set_drv_mcr(IN struct net_device *prNetDev, IN char *pcCommand, + IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = { 0 }; + uint32_t u4Ret; + + /* Add Antenna Selection Input */ + /* INT_32 i4ArgNum_with_ant_sel = 4; */ + + int32_t i4ArgNum = 3; + + struct CMD_ACCESS_REG rCmdAccessReg; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + if (i4Argc >= i4ArgNum) { + u4Ret = kalkStrtou32(apcArgv[1], 0, &(rCmdAccessReg.u4Address)); + if (u4Ret) + DBGLOG(REQ, LOUD, + "parse get_drv_mcr error (Address) u4Ret=%d\n", + u4Ret); + + u4Ret = kalkStrtou32(apcArgv[2], 0, &(rCmdAccessReg.u4Data)); + if (u4Ret) + DBGLOG(REQ, LOUD, + "parse get_drv_mcr error (Data) u4Ret=%d\n", + u4Ret); + + rStatus = kalIoctl(prGlueInfo, wlanoidSetDrvMcrWrite, + &rCmdAccessReg, sizeof(rCmdAccessReg), + FALSE, FALSE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) + return -1; + + } + + return i4BytesWritten; + +} + +static int priv_driver_get_sw_ctrl(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + int32_t u4Ret = 0; + + struct PARAM_CUSTOM_SW_CTRL_STRUCT rSwCtrlInfo; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + if (i4Argc >= 2) { + rSwCtrlInfo.u4Id = 0; + rSwCtrlInfo.u4Data = 0; + u4Ret = kalkStrtou32(apcArgv[1], 0, &(rSwCtrlInfo.u4Id)); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse rSwCtrlInfo error u4Ret=%d\n", + u4Ret); + + DBGLOG(REQ, LOUD, "id is %x\n", rSwCtrlInfo.u4Id); + + rStatus = kalIoctl(prGlueInfo, wlanoidQuerySwCtrlRead, + &rSwCtrlInfo, sizeof(rSwCtrlInfo), + TRUE, TRUE, TRUE, &u4BufLen); + + DBGLOG(REQ, LOUD, "rStatus %u\n", rStatus); + if (rStatus != WLAN_STATUS_SUCCESS) + return -1; + + i4BytesWritten = kalSnprintf(pcCommand, i4TotalLen, "0x%08x", + (unsigned int)rSwCtrlInfo.u4Data); + DBGLOG(REQ, INFO, "%s: command result is %s\n", __func__, + pcCommand); + } + + return i4BytesWritten; + +} /* priv_driver_get_sw_ctrl */ + + +int priv_driver_set_sw_ctrl(IN struct net_device *prNetDev, IN char *pcCommand, + IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = { 0 }; + int32_t u4Ret = 0; + + struct PARAM_CUSTOM_SW_CTRL_STRUCT rSwCtrlInfo; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + if (i4Argc >= 3) { + /* rSwCtrlInfo.u4Id = kalStrtoul(apcArgv[1], NULL, 0); + * rSwCtrlInfo.u4Data = kalStrtoul(apcArgv[2], NULL, 0); + */ + u4Ret = kalkStrtou32(apcArgv[1], 0, &(rSwCtrlInfo.u4Id)); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse rSwCtrlInfo error u4Ret=%d\n", + u4Ret); + u4Ret = kalkStrtou32(apcArgv[2], 0, &(rSwCtrlInfo.u4Data)); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse rSwCtrlInfo error u4Ret=%d\n", + u4Ret); + + rStatus = kalIoctl(prGlueInfo, wlanoidSetSwCtrlWrite, + &rSwCtrlInfo, sizeof(rSwCtrlInfo), + FALSE, FALSE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) + return -1; + + } + + return i4BytesWritten; + +} /* priv_driver_set_sw_ctrl */ + + + +int priv_driver_set_fixed_rate(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + /* INT_32 u4Ret = 0; */ + uint32_t u4WCID = 0; + int32_t i4Recv = 0; + int8_t *this_char = NULL; + uint32_t u4Id = 0xa0610000; + uint32_t u4Id2 = 0xa0600000; + static uint8_t fgIsUseWCID = FALSE; + struct FIXED_RATE_INFO rFixedRate; + + struct PARAM_CUSTOM_SW_CTRL_STRUCT rSwCtrlInfo; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %d, apcArgv[0] = %s\n\n", i4Argc, *apcArgv); + + this_char = kalStrStr(*apcArgv, "="); + if (!this_char) + return -1; + this_char++; + kalMemZero(&rFixedRate, sizeof(struct FIXED_RATE_INFO)); + DBGLOG(REQ, LOUD, "string = %s\n", this_char); + + if (strnicmp(this_char, "auto", strlen("auto")) == 0) { + i4Recv = 1; + } else if (strnicmp(this_char, "UseWCID", strlen("UseWCID")) == 0) { + i4Recv = 2; + fgIsUseWCID = TRUE; + } else if (strnicmp(this_char, "ApplyAll", strlen("ApplyAll")) == 0) { + i4Recv = 3; + fgIsUseWCID = FALSE; + } else { + i4Recv = sscanf(this_char, + "%d-%d-%d-%d-%d-%d-%d-%d-%d-%d-%d-%d-%d", + &(u4WCID), + &(rFixedRate.u4Mode), + &(rFixedRate.u4Bw), + &(rFixedRate.u4Mcs), + &(rFixedRate.u4VhtNss), + &(rFixedRate.u4SGI), + &(rFixedRate.u4Preamble), + &(rFixedRate.u4STBC), + &(rFixedRate.u4LDPC), + &(rFixedRate.u4SpeEn), + &(rFixedRate.u4HeLTF), + &(rFixedRate.u4HeErDCM), + &(rFixedRate.u4HeEr106t)); + + + DBGLOG(REQ, LOUD, "u4WCID=%d\nu4Mode=%d\nu4Bw=%d\n", u4WCID, + rFixedRate.u4Mode, rFixedRate.u4Bw); + DBGLOG(REQ, LOUD, "u4Mcs=%d\nu4VhtNss=%d\nu4GI=%d\n", + rFixedRate.u4Mcs, + rFixedRate.u4VhtNss, rFixedRate.u4SGI); + DBGLOG(REQ, LOUD, "u4Preamble=%d\nu4STBC=%d\n", + rFixedRate.u4Preamble, + rFixedRate.u4STBC); + DBGLOG(REQ, LOUD, "u4LDPC=%d\nu4SpeEn=%d\nu4HeLTF=%d\n", + rFixedRate.u4LDPC, rFixedRate.u4SpeEn, + rFixedRate.u4HeLTF); + DBGLOG(REQ, LOUD, "u4HeErDCM=%d\nu4HeEr106t=%d\n", + rFixedRate.u4HeErDCM, rFixedRate.u4HeEr106t); + DBGLOG(REQ, LOUD, "fgIsUseWCID=%d\n", fgIsUseWCID); + } + + if (i4Recv == 1) { + rSwCtrlInfo.u4Id = u4Id2; + rSwCtrlInfo.u4Data = 0; + + rStatus = kalIoctl(prGlueInfo, wlanoidSetSwCtrlWrite, + &rSwCtrlInfo, sizeof(rSwCtrlInfo), + FALSE, FALSE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) + return -1; + } else if (i4Recv == 2 || i4Recv == 3) { + i4BytesWritten = kalSnprintf(pcCommand, i4TotalLen, + "Update fgIsUseWCID %d\n", fgIsUseWCID); + } else if (i4Recv == 10 || i4Recv == 13) { + rSwCtrlInfo.u4Id = u4Id; + if (fgIsUseWCID && u4WCID < prAdapter->ucWtblEntryNum && + prAdapter->rWifiVar.arWtbl[u4WCID].ucUsed) { + rSwCtrlInfo.u4Id |= u4WCID; + rSwCtrlInfo.u4Id |= BIT(8); + i4BytesWritten = kalSnprintf( + pcCommand, i4TotalLen, + "Apply WCID %d\n", u4WCID); + } else { + i4BytesWritten = kalSnprintf( + pcCommand, i4TotalLen, "Apply All\n"); + } + + if (rFixedRate.u4Mode >= TX_RATE_MODE_HE_SU) { + if (i4Recv == 10) { + /* Give default value */ + rFixedRate.u4HeLTF = HE_LTF_4X; + rFixedRate.u4HeErDCM = 0; + rFixedRate.u4HeEr106t = 0; + } + /* check HE-LTF and HE GI combinations */ + rStatus = nicRateHeLtfCheckGi(&rFixedRate); + + if (rStatus != WLAN_STATUS_SUCCESS) + return -1; + } + + rStatus = nicSetFixedRateData(&rFixedRate, &rSwCtrlInfo.u4Data); + + if (rStatus == WLAN_STATUS_SUCCESS) { + rStatus = kalIoctl(prGlueInfo, wlanoidSetSwCtrlWrite, + &rSwCtrlInfo, sizeof(rSwCtrlInfo), + FALSE, FALSE, TRUE, &u4BufLen); + } + + if (rStatus != WLAN_STATUS_SUCCESS) + return -1; + } else { + DBGLOG(REQ, ERROR, "iwpriv wlanXX driver FixedRate=Option\n"); + DBGLOG(REQ, ERROR, "Option support 10 or 13 parameters\n"); + DBGLOG(REQ, ERROR, + "Option:[WCID]-[Mode]-[BW]-[MCS]-[VhtHeNss]-[GI]-[Preamble]-[STBC]-[LDPC]-[SPE_EN]\n"); + DBGLOG(REQ, ERROR, + "13 param support another [HE-LTF]-[HE-ER-DCM]-[HE-ER-106]\n"); + DBGLOG(REQ, ERROR, "[WCID]Wireless Client ID\n"); + DBGLOG(REQ, ERROR, "[Mode]CCK=0, OFDM=1, HT=2, GF=3, VHT=4"); + DBGLOG(REQ, ERROR, + "PLR=5, HE_SU=8, HE_ER_SU=9, HE_TRIG=10, HE_MU=11\n"); + DBGLOG(REQ, ERROR, "[BW]BW20=0, BW40=1, BW80=2,BW160=3\n"); + DBGLOG(REQ, ERROR, + "[MCS]CCK=0~3, OFDM=0~7, HT=0~32, VHT=0~9, HE=0~11\n"); + DBGLOG(REQ, ERROR, "[VhtHeNss]1~8, Other=ignore\n"); + DBGLOG(REQ, ERROR, "[GI]HT/VHT: 0:Long, 1:Short, "); + DBGLOG(REQ, ERROR, + "HE: SGI=0(0.8us), MGI=1(1.6us), LGI=2(3.2us)\n"); + DBGLOG(REQ, ERROR, "[Preamble]Long=0, Other=Short\n"); + DBGLOG(REQ, ERROR, "[STBC]Enable=1, Disable=0\n"); + DBGLOG(REQ, ERROR, "[LDPC]BCC=0, LDPC=1\n"); + DBGLOG(REQ, ERROR, "[HE-LTF]1X=0, 2X=1, 4X=2\n"); + DBGLOG(REQ, ERROR, "[HE-ER-DCM]Enable=1, Disable=0\n"); + DBGLOG(REQ, ERROR, "[HE-ER-106]106-tone=1\n"); + } + + return i4BytesWritten; +} /* priv_driver_set_fixed_rate */ + +int priv_driver_set_em_cfg(IN struct net_device *prNetDev, IN char *pcCommand, + IN int i4TotalLen) +{ + uint32_t rStatus = WLAN_STATUS_SUCCESS; + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + uint32_t u4CfgSetNum = 0, u4Ret = 0; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = { 0 }; + uint32_t u4BufLen; + + struct PARAM_CUSTOM_KEY_CFG_STRUCT rKeyCfgInfo; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + prAdapter = prGlueInfo->prAdapter; + if (prAdapter == NULL) + return -1; /* WLAN_STATUS_ADAPTER_NOT_READY */ + + kalMemZero(&rKeyCfgInfo, sizeof(rKeyCfgInfo)); + + wlanCleanAllEmCfgSetting(prAdapter); + + + if (i4Argc >= 3) { + + uint8_t i = 0; + + u4Ret = kalkStrtou32(apcArgv[1], 10, &u4CfgSetNum); + + if (u4Ret != 0) { + DBGLOG(REQ, ERROR, + "apcArgv[2] format fail erro code:%d\n", + u4Ret); + return -1; + } + + if (u4CfgSetNum*2 > i4Argc) { + DBGLOG(REQ, ERROR, + "Set Num(%d) over input arg num(%d)\n", + u4CfgSetNum, i4Argc); + return -1; + } + + DBGLOG(REQ, INFO, "Total Cfg Num=%d\n", u4CfgSetNum); + + for (i = 0; i < (u4CfgSetNum*2); i += 2) { + + kalStrnCpy(rKeyCfgInfo.aucKey, apcArgv[2+i], + WLAN_CFG_KEY_LEN_MAX - 1); + kalStrnCpy(rKeyCfgInfo.aucValue, apcArgv[2+(i+1)], + WLAN_CFG_VALUE_LEN_MAX - 1); + rKeyCfgInfo.u4Flag = WLAN_CFG_EM; + + DBGLOG(REQ, INFO, + "Update to driver EM CFG [%s]:[%s],OP:%d\n", + rKeyCfgInfo.aucKey, + rKeyCfgInfo.aucValue, + rKeyCfgInfo.u4Flag); + + rStatus = kalIoctl(prGlueInfo, + wlanoidSetKeyCfg, + &rKeyCfgInfo, + sizeof(rKeyCfgInfo), + FALSE, + FALSE, + TRUE, + &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) + return -1; + + + } + + } + + return i4BytesWritten; + +} /* priv_driver_set_cfg_em */ + +int priv_driver_get_em_cfg(IN struct net_device *prNetDev, IN char *pcCommand, + IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = { 0 }; + struct WLAN_CFG_ENTRY *prWlanCfgEntry; + int32_t i = 0; + uint32_t u4Offset = 0; + uint32_t u4CfgNum = 0; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, INFO, + "command is %s, i4TotalLen=%d\n", + pcCommand, + i4TotalLen); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, INFO, "argc is %i\n", i4Argc); + prAdapter = prGlueInfo->prAdapter; + + if (i4Argc >= 1) { + + u4CfgNum = wlanCfgGetTotalCfgNum(prAdapter, WLAN_CFG_EM); + + DBGLOG(REQ, INFO, + "Total cfg Num:%d\n", u4CfgNum); + + u4Offset += snprintf(pcCommand + u4Offset, + (i4TotalLen - u4Offset), + "%d,", + u4CfgNum); + + for (i = 0; i < u4CfgNum; i++) { + prWlanCfgEntry = wlanCfgGetEntryByIndex( + prAdapter, + i, + WLAN_CFG_EM); + + if ((!prWlanCfgEntry) + || (prWlanCfgEntry->aucKey[0] == '\0')) + break; + + DBGLOG(REQ, INFO, + "cfg dump:(%s,%s)\n", + prWlanCfgEntry->aucKey, + prWlanCfgEntry->aucValue); + + if (u4Offset >= i4TotalLen) { + DBGLOG(REQ, ERROR, + "out of bound\n"); + break; + } + + u4Offset += snprintf(pcCommand + u4Offset, + (i4TotalLen - u4Offset), + "%s,%s,", + prWlanCfgEntry->aucKey, + prWlanCfgEntry->aucValue); + + } + + pcCommand[u4Offset-1] = '\n'; + pcCommand[u4Offset] = '\0'; + + } + + return (int32_t)u4Offset; + +} /* priv_driver_get_cfg_em */ + + +int priv_driver_set_cfg(IN struct net_device *prNetDev, IN char *pcCommand, + IN int i4TotalLen) +{ + uint32_t rStatus = WLAN_STATUS_SUCCESS; + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + uint32_t u4BufLen = 0; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = { 0 }; + + struct PARAM_CUSTOM_KEY_CFG_STRUCT rKeyCfgInfo; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + prAdapter = prGlueInfo->prAdapter; + if (prAdapter == NULL) + return -1; /* WLAN_STATUS_ADAPTER_NOT_READY */ + + kalMemZero(&rKeyCfgInfo, sizeof(rKeyCfgInfo)); + + if (i4Argc >= 3) { + + int8_t ucTmp[WLAN_CFG_VALUE_LEN_MAX]; + uint8_t *pucCurrBuf = ucTmp; + uint8_t i = 0; + uint32_t offset = 0; + + pucCurrBuf = ucTmp; + kalMemZero(ucTmp, WLAN_CFG_VALUE_LEN_MAX); + + if (i4Argc == 3) { + /* no space for it, driver can't accept space in the end + * of the line + */ + /* ToDo: skip the space when parsing */ + u4BufLen = kalStrLen(apcArgv[2]); + if (offset + u4BufLen > WLAN_CFG_VALUE_LEN_MAX - 1) { + DBGLOG(INIT, ERROR, + "apcArgv[2] length [%d] overrun\n", + u4BufLen); + return -1; + } + kalStrnCpy(pucCurrBuf + offset, apcArgv[2], u4BufLen); + offset += u4BufLen; + } else { + for (i = 2; i < i4Argc; i++) { + u4BufLen = kalStrLen(apcArgv[i]); + if (offset + u4BufLen > + WLAN_CFG_VALUE_LEN_MAX - 1) { + DBGLOG(INIT, ERROR, + "apcArgv[%d] length [%d] overrun\n", + i, u4BufLen); + return -1; + } + kalStrnCpy(pucCurrBuf + offset, apcArgv[i], + u4BufLen); + offset += u4BufLen; + } + } + + DBGLOG(INIT, WARN, "Update to driver temp buffer as [%s]\n", + ucTmp); + + /* wlanCfgSet(prAdapter, apcArgv[1], apcArgv[2], 0); */ + /* Call by wlanoid because the set_cfg will trigger callback */ + kalStrnCpy(rKeyCfgInfo.aucKey, apcArgv[1], + WLAN_CFG_KEY_LEN_MAX - 1); + kalStrnCpy(rKeyCfgInfo.aucValue, ucTmp, + WLAN_CFG_VALUE_LEN_MAX - 1); + + rKeyCfgInfo.u4Flag = WLAN_CFG_DEFAULT; + rStatus = kalIoctl(prGlueInfo, wlanoidSetKeyCfg, &rKeyCfgInfo, + sizeof(rKeyCfgInfo), FALSE, FALSE, TRUE, + &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) + return -1; + } + + return i4BytesWritten; + +} /* priv_driver_set_cfg */ + +int priv_driver_get_cfg(IN struct net_device *prNetDev, IN char *pcCommand, + IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = { 0 }; + int8_t aucValue[WLAN_CFG_VALUE_LEN_MAX]; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + prAdapter = prGlueInfo->prAdapter; + + if (i4Argc >= 2) { + /* by wlanoid ? */ + if (wlanCfgGet(prAdapter, apcArgv[1], aucValue, "", 0) == + WLAN_STATUS_SUCCESS) { + kalStrnCpy(pcCommand, aucValue, WLAN_CFG_VALUE_LEN_MAX); + i4BytesWritten = kalStrnLen(pcCommand, + WLAN_CFG_VALUE_LEN_MAX); + } + } + + return i4BytesWritten; + +} /* priv_driver_get_cfg */ + +int priv_driver_set_chip_config(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + uint32_t rStatus = WLAN_STATUS_SUCCESS; + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + uint32_t u4BufLen = 0; + int32_t i4BytesWritten = 0; + uint32_t u4CmdLen = 0; + uint32_t u4PrefixLen = 0; + /* INT_32 i4Argc = 0; */ + /* PCHAR apcArgv[WLAN_CFG_ARGV_MAX] = {0}; */ + + struct PARAM_CUSTOM_CHIP_CONFIG_STRUCT rChipConfigInfo = {0}; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + if ((!prGlueInfo) || + (prGlueInfo->u4ReadyFlag == 0) || + kalIsResetting()) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -1; + } + + prAdapter = prGlueInfo->prAdapter; + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + /* wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); */ + /* DBGLOG(REQ, LOUD,("argc is %i\n",i4Argc)); */ + /* */ + u4CmdLen = kalStrnLen(pcCommand, i4TotalLen); + u4PrefixLen = kalStrLen(CMD_SET_CHIP) + 1 /*space */; + + kalMemZero(&rChipConfigInfo, sizeof(rChipConfigInfo)); + + /* if(i4Argc >= 2) { */ + if (u4CmdLen > u4PrefixLen) { + rChipConfigInfo.ucType = CHIP_CONFIG_TYPE_WO_RESPONSE; + /* rChipConfigInfo.u2MsgSize = kalStrnLen(apcArgv[1], + * CHIP_CONFIG_RESP_SIZE); + */ + rChipConfigInfo.u2MsgSize = u4CmdLen - u4PrefixLen; + /* kalStrnCpy(rChipConfigInfo.aucCmd, apcArgv[1], + * CHIP_CONFIG_RESP_SIZE); + */ + kalStrnCpy(rChipConfigInfo.aucCmd, pcCommand + u4PrefixLen, + CHIP_CONFIG_RESP_SIZE - 1); + rChipConfigInfo.aucCmd[CHIP_CONFIG_RESP_SIZE - 1] = '\0'; + +#if (CFG_SUPPORT_802_11AX == 1) + if (kalStrnCmp("FrdHeTrig2Host", + pcCommand, kalStrLen("FrdHeTrig2Host"))) { + uint32_t idx = kalStrLen("set_chip FrdHeTrig2Host "); + + prAdapter->fgEnShowHETrigger = pcCommand[idx] - 0x30; + DBGLOG(REQ, STATE, "set flag fgEnShowHETrigger:%x\n", + prAdapter->fgEnShowHETrigger); + } +#endif /* CFG_SUPPORT_802_11AX == 1 */ + + rStatus = kalIoctl(prGlueInfo, wlanoidSetChipConfig, + &rChipConfigInfo, sizeof(rChipConfigInfo), + FALSE, FALSE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, INFO, "%s: kalIoctl ret=%d\n", __func__, + rStatus); + i4BytesWritten = -1; + } + } + + return i4BytesWritten; + +} /* priv_driver_set_chip_config */ + +void +priv_driver_get_chip_config_16(uint8_t *pucStartAddr, uint32_t u4Length, + uint32_t u4Line, int i4TotalLen, + int32_t i4BytesWritten, char *pcCommand) +{ + + while (u4Length >= 16) { + if (i4TotalLen > i4BytesWritten) { + i4BytesWritten += + kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%04x %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x %02x %02x %02x %02x %02x\n", + u4Line, pucStartAddr[0], + pucStartAddr[1], pucStartAddr[2], + pucStartAddr[3], pucStartAddr[4], + pucStartAddr[5], pucStartAddr[6], + pucStartAddr[7], pucStartAddr[8], + pucStartAddr[9], pucStartAddr[10], + pucStartAddr[11], pucStartAddr[12], + pucStartAddr[13], pucStartAddr[14], + pucStartAddr[15]); + } + + pucStartAddr += 16; + u4Length -= 16; + u4Line += 16; + } /* u4Length */ +} + + +void +priv_driver_get_chip_config_4(uint32_t *pu4StartAddr, uint32_t u4Length, + uint32_t u4Line, int i4TotalLen, + int32_t i4BytesWritten, char *pcCommand) +{ + while (u4Length >= 16) { + if (i4TotalLen > i4BytesWritten) { + i4BytesWritten += + kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "%04x %08x %08x %08x %08x\n", u4Line, + pu4StartAddr[0], pu4StartAddr[1], + pu4StartAddr[2], pu4StartAddr[3]); + } + + pu4StartAddr += 4; + u4Length -= 16; + u4Line += 4; + } /* u4Length */ +} + +int priv_driver_get_chip_config(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + uint32_t rStatus = WLAN_STATUS_SUCCESS; + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + int32_t i4BytesWritten = 0; + uint32_t u4BufLen = 0; + uint32_t u2MsgSize = 0; + uint32_t u4CmdLen = 0; + uint32_t u4PrefixLen = 0; + /* INT_32 i4Argc = 0; */ + /* PCHAR apcArgv[WLAN_CFG_ARGV_MAX]; */ + + struct PARAM_CUSTOM_CHIP_CONFIG_STRUCT rChipConfigInfo = {0}; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + /* wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); */ + /* DBGLOG(REQ, LOUD,("argc is %i\n",i4Argc)); */ + + u4CmdLen = kalStrnLen(pcCommand, i4TotalLen); + u4PrefixLen = kalStrLen(CMD_GET_CHIP) + 1 /*space */; + + /* if(i4Argc >= 2) { */ + if (u4CmdLen > u4PrefixLen) { + rChipConfigInfo.ucType = CHIP_CONFIG_TYPE_ASCII; + /* rChipConfigInfo.u2MsgSize = kalStrnLen(apcArgv[1], + * CHIP_CONFIG_RESP_SIZE); + */ + rChipConfigInfo.u2MsgSize = u4CmdLen - u4PrefixLen; + /* kalStrnCpy(rChipConfigInfo.aucCmd, apcArgv[1], + * CHIP_CONFIG_RESP_SIZE); + */ + kalStrnCpy(rChipConfigInfo.aucCmd, pcCommand + u4PrefixLen, + CHIP_CONFIG_RESP_SIZE - 1); + rChipConfigInfo.aucCmd[CHIP_CONFIG_RESP_SIZE - 1] = '\0'; + rStatus = kalIoctl(prGlueInfo, wlanoidQueryChipConfig, + &rChipConfigInfo, sizeof(rChipConfigInfo), + TRUE, TRUE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, INFO, "%s: kalIoctl ret=%d\n", __func__, + rStatus); + return -1; + } + + /* Check respType */ + u2MsgSize = rChipConfigInfo.u2MsgSize; + DBGLOG(REQ, INFO, "%s: RespTyep %u\n", __func__, + rChipConfigInfo.ucRespType); + DBGLOG(REQ, INFO, "%s: u2MsgSize %u\n", __func__, + rChipConfigInfo.u2MsgSize); + + if (u2MsgSize > sizeof(rChipConfigInfo.aucCmd)) { + DBGLOG(REQ, INFO, "%s: u2MsgSize error ret=%u\n", + __func__, rChipConfigInfo.u2MsgSize); + return -1; + } + + if (u2MsgSize > 0) { + + if (rChipConfigInfo.ucRespType == + CHIP_CONFIG_TYPE_ASCII) { + i4BytesWritten = + kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen, "%s", + rChipConfigInfo.aucCmd); + } else { + uint32_t u4Length; + uint32_t u4Line; + + if (rChipConfigInfo.ucRespType == + CHIP_CONFIG_TYPE_MEM8) { + uint8_t *pucStartAddr = NULL; + + pucStartAddr = (uint8_t *) + rChipConfigInfo.aucCmd; + /* align 16 bytes because one print line + * is 16 bytes + */ + u4Length = (((u2MsgSize + 15) >> 4)) + << 4; + u4Line = 0; + priv_driver_get_chip_config_16( + pucStartAddr, u4Length, u4Line, + i4TotalLen, i4BytesWritten, + pcCommand); + } else { + uint32_t *pu4StartAddr = NULL; + + pu4StartAddr = (uint32_t *) + rChipConfigInfo.aucCmd; + /* align 16 bytes because one print line + * is 16 bytes + */ + u4Length = (((u2MsgSize + 15) >> 4)) + << 4; + u4Line = 0; + + if (IS_ALIGN_4( + (unsigned long) pu4StartAddr)) { + priv_driver_get_chip_config_4( + pu4StartAddr, u4Length, + u4Line, i4TotalLen, + i4BytesWritten, + pcCommand); + } else { + DBGLOG(REQ, INFO, + "%s: rChipConfigInfo.aucCmd is not 4 bytes alignment %p\n", + __func__, + rChipConfigInfo.aucCmd); + } + } /* ChipConfigInfo.ucRespType */ + } + } + /* u2MsgSize > 0 */ + DBGLOG(REQ, INFO, "%s: command result is %s\n", __func__, + pcCommand); + } + /* i4Argc */ + return i4BytesWritten; + +} /* priv_driver_get_chip_config */ + + + +int priv_driver_set_ap_start(IN struct net_device *prNetDev, IN char *pcCommand, + IN int i4TotalLen) +{ + + struct PARAM_CUSTOM_P2P_SET_STRUCT rSetP2P; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = { 0 }; + uint32_t u4Ret; + int32_t i4ArgNum = 2; + + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + if (i4Argc >= i4ArgNum) { + + u4Ret = kalkStrtou32(apcArgv[1], 0, &(rSetP2P.u4Mode)); + if (u4Ret) + DBGLOG(REQ, LOUD, + "parse ap-start error (u4Enable) u4Ret=%d\n", + u4Ret); + + if (rSetP2P.u4Mode >= RUNNING_P2P_MODE_NUM) { + rSetP2P.u4Mode = 0; + rSetP2P.u4Enable = 0; + } else + rSetP2P.u4Enable = 1; + + set_p2p_mode_handler(prNetDev, rSetP2P); + } + + return 0; +} + +int priv_driver_get_linkspeed(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_LINK_SPEED_EX rLinkSpeed; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + uint32_t u4Rate = 0; + int32_t i4BytesWritten = 0; + uint8_t ucBssIndex = AIS_DEFAULT_INDEX; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + ucBssIndex = wlanGetBssIdx(prNetDev); + + if (!netif_carrier_ok(prNetDev)) + return -1; + + if (ucBssIndex >= BSSID_NUM) + return -EFAULT; + + rStatus = kalIoctl(prGlueInfo, + wlanoidQueryLinkSpeedEx, + &rLinkSpeed, sizeof(rLinkSpeed), + TRUE, TRUE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) + return -1; + u4Rate = rLinkSpeed.rLq[ucBssIndex].u2LinkSpeed; + i4BytesWritten = kalSnprintf(pcCommand, i4TotalLen, "LinkSpeed %u", + (unsigned int)(u4Rate * 100)); + DBGLOG(REQ, INFO, "%s: command result is %s\n", __func__, pcCommand); + return i4BytesWritten; + +} /* priv_driver_get_linkspeed */ + +int priv_driver_set_band(IN struct net_device *prNetDev, IN char *pcCommand, + IN int i4TotalLen) +{ + struct ADAPTER *prAdapter = NULL; + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4Argc = 0; + uint32_t ucBand = 0; + enum ENUM_BAND eBand = BAND_NULL; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + int32_t u4Ret = 0; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + prAdapter = prGlueInfo->prAdapter; + if (i4Argc >= 2) { + /* ucBand = kalStrtoul(apcArgv[1], NULL, 0); */ + u4Ret = kalkStrtou32(apcArgv[1], 0, &ucBand); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse ucBand error u4Ret=%d\n", + u4Ret); + + eBand = BAND_NULL; + if (ucBand == CMD_BAND_TYPE_5G) + eBand = BAND_5G; + else if (ucBand == CMD_BAND_TYPE_2G) + eBand = BAND_2G4; + prAdapter->aePreferBand[KAL_NETWORK_TYPE_AIS_INDEX] = eBand; + /* XXX call wlanSetPreferBandByNetwork directly in different + * thread + */ + /* wlanSetPreferBandByNetwork (prAdapter, eBand, ucBssIndex); */ + } + + return 0; +} + + +int priv_driver_set_country(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint8_t aucCountry[2]; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + if (regd_is_single_sku_en()) { + uint8_t aucCountry_code[4] = {0, 0, 0, 0}; + uint8_t i, count; + + /* command like "COUNTRY US", "COUNTRY US1" and + * "COUNTRY US01" + */ + count = kalStrnLen(apcArgv[1], sizeof(aucCountry_code)); + for (i = 0; i < count; i++) + aucCountry_code[i] = apcArgv[1][i]; + + + rStatus = kalIoctl(prGlueInfo, wlanoidSetCountryCode, + &aucCountry_code[0], count, + FALSE, FALSE, TRUE, &u4BufLen); + if (rStatus != WLAN_STATUS_SUCCESS) + return -1; + + return 0; + } + + + if (i4Argc >= 2) { + /* command like "COUNTRY US", "COUNTRY EU" and "COUNTRY JP" */ + aucCountry[0] = apcArgv[1][0]; + aucCountry[1] = apcArgv[1][1]; + + rStatus = kalIoctl(prGlueInfo, wlanoidSetCountryCode, + &aucCountry[0], 2, FALSE, FALSE, TRUE, + &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) + return -1; + } + return 0; +} + +int priv_driver_set_csa(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint32_t ch_num = 0; + uint32_t u4Ret = 0; + uint8_t ucRoleIdx = 0; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + if (mtk_Netdev_To_RoleIdx(prGlueInfo, prNetDev, &ucRoleIdx) != 0) + return -1; + + DBGLOG(REQ, INFO, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, INFO, "argc is %i\n", i4Argc); + + if (i4Argc >= 2) { + u4Ret = kalkStrtou32(apcArgv[1], 0, &ch_num); + u4Ret = cnmIdcCsaReq(prGlueInfo->prAdapter, ch_num, ucRoleIdx); + DBGLOG(REQ, INFO, "u4Ret is %d\n", u4Ret); + } else { + DBGLOG(REQ, INFO, "Input insufficent\n"); + } + + return 0; +} + +int priv_driver_get_country(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint32_t i4BytesWritten = 0; + uint32_t country = 0; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + if (!regd_is_single_sku_en()) { + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "Not Supported."); + return i4BytesWritten; + } + + country = rlmDomainGetCountryCode(); + + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "\nCountry Code: (0x%x)", + country); + + return i4BytesWritten; +} + +int priv_driver_get_channels(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + uint32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; +#if (CFG_SUPPORT_SINGLE_SKU == 1) + uint32_t ch_idx, start_idx, end_idx; + struct CMD_DOMAIN_CHANNEL *pCh; + uint32_t ch_num = 0; + uint8_t maxbw = 160; + uint32_t u4Ret = 0; +#endif + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + if (!regd_is_single_sku_en()) { + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "Not Supported."); + return i4BytesWritten; + } + +#if (CFG_SUPPORT_SINGLE_SKU == 1) + /** + * Usage: iwpriv wlan0 driver "get_channels [2g |5g |ch_num]" + **/ + if (i4Argc >= 2 && (apcArgv[1][0] == '2') && (apcArgv[1][1] == 'g')) { + start_idx = 0; + end_idx = rlmDomainGetActiveChannelCount(KAL_BAND_2GHZ); + } else if (i4Argc >= 2 && (apcArgv[1][0] == '5') && + (apcArgv[1][1] == 'g')) { + start_idx = rlmDomainGetActiveChannelCount(KAL_BAND_2GHZ); + end_idx = rlmDomainGetActiveChannelCount(KAL_BAND_2GHZ) + + rlmDomainGetActiveChannelCount(KAL_BAND_5GHZ); + } else { + start_idx = 0; + end_idx = rlmDomainGetActiveChannelCount(KAL_BAND_2GHZ) + + rlmDomainGetActiveChannelCount(KAL_BAND_5GHZ); + if (i4Argc >= 2) + /* Dump only specified channel */ + u4Ret = kalkStrtou32(apcArgv[1], 0, &ch_num); + } + + if (regd_is_single_sku_en()) { + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "\n"); + + for (ch_idx = start_idx; ch_idx < end_idx; ch_idx++) { + + pCh = (rlmDomainGetActiveChannels() + ch_idx); + + if (ch_num && (ch_num != pCh->u2ChNum)) + continue; /*show specific channel information*/ + + /* Channel number */ + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "CH-%d:", + pCh->u2ChNum); + + /* Active/Passive */ + if (pCh->eFlags & IEEE80211_CHAN_PASSIVE_FLAG) { + /* passive channel */ + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + " " IEEE80211_CHAN_PASSIVE_STR); + } else + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + " ACTIVE"); + + /* Max BW */ + if ((pCh->eFlags & IEEE80211_CHAN_NO_160MHZ) == + IEEE80211_CHAN_NO_160MHZ) + maxbw = 80; + if ((pCh->eFlags & IEEE80211_CHAN_NO_80MHZ) == + IEEE80211_CHAN_NO_80MHZ) + maxbw = 40; + if ((pCh->eFlags & IEEE80211_CHAN_NO_HT40) == + IEEE80211_CHAN_NO_HT40) + maxbw = 20; + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + " BW_%dMHz", maxbw); + /* Channel flags */ + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + " (flags=0x%x)\n", pCh->eFlags); + } + } +#endif + + return i4BytesWritten; +} + +#if (CFG_SUPPORT_DFS_MASTER == 1) +int priv_driver_show_dfs_state(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + int32_t i4BytesWritten = 0; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "\nDFS State: \"%s\"", + p2pFuncShowDfsState()); + + return i4BytesWritten; +} + +int priv_driver_show_dfs_radar_param(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + int32_t i4BytesWritten = 0; + uint8_t ucCnt = 0; + struct P2P_RADAR_INFO *prP2pRadarInfo = (struct P2P_RADAR_INFO *) NULL; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + prP2pRadarInfo = (struct P2P_RADAR_INFO *) cnmMemAlloc( + prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(*prP2pRadarInfo)); + if (prP2pRadarInfo == NULL) + return -1; + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + p2pFuncGetRadarInfo(prP2pRadarInfo); + + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "\nRDD idx: %d\n", + prP2pRadarInfo->ucRddIdx); + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "\nLong Pulse detected: %d\n", prP2pRadarInfo->ucLongDetected); + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "\nPeriodic Pulse detected: %d\n", + prP2pRadarInfo->ucPeriodicDetected); + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "\nLPB Num: %d\n", + prP2pRadarInfo->ucLPBNum); + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "\nPPB Num: %d\n", + prP2pRadarInfo->ucPPBNum); + + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "\n==========================="); + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "\nLong Pulse Buffer Contents:\n"); + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "\npulse_time pulse_width PRI\n"); + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "\n%-10d %-11d -\n" + , prP2pRadarInfo->arLpbContent[ucCnt].u4LongStartTime + , prP2pRadarInfo->arLpbContent[ucCnt].u2LongPulseWidth); + for (ucCnt = 1; ucCnt < prP2pRadarInfo->ucLPBNum; ucCnt++) { + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "\n%-10d %-11d %d\n", + prP2pRadarInfo->arLpbContent[ucCnt].u4LongStartTime, + prP2pRadarInfo->arLpbContent[ucCnt].u2LongPulseWidth, + (prP2pRadarInfo->arLpbContent[ucCnt].u4LongStartTime + - prP2pRadarInfo->arLpbContent[ucCnt-1] + .u4LongStartTime) * 2 / 5); + } + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "\nLPB Period Valid: %d", prP2pRadarInfo->ucLPBPeriodValid); + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "\nLPB Period Valid: %d\n", prP2pRadarInfo->ucLPBWidthValid); + + ucCnt = 0; + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "\n==========================="); + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "\nPeriod Pulse Buffer Contents:\n"); + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "\npulse_time pulse_width PRI\n"); + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "\n%-10d %-11d -\n" + , prP2pRadarInfo->arPpbContent[ucCnt].u4PeriodicStartTime + , prP2pRadarInfo->arPpbContent[ucCnt].u2PeriodicPulseWidth); + for (ucCnt = 1; ucCnt < prP2pRadarInfo->ucPPBNum; ucCnt++) { + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "\n%-10d %-11d %d\n" + , prP2pRadarInfo->arPpbContent[ucCnt].u4PeriodicStartTime + , prP2pRadarInfo->arPpbContent[ucCnt] + .u2PeriodicPulseWidth + , (prP2pRadarInfo->arPpbContent[ucCnt] + .u4PeriodicStartTime + - prP2pRadarInfo->arPpbContent[ucCnt-1] + .u4PeriodicStartTime) * 2 / 5); + } + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "\nPRI Count M1 TH: %d; PRI Count M1: %d", + prP2pRadarInfo->ucPRICountM1TH, prP2pRadarInfo->ucPRICountM1); + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "\nPRI Count M2 TH: %d; PRI Count M2: %d", + prP2pRadarInfo->ucPRICountM2TH, + prP2pRadarInfo->ucPRICountM2); + + + cnmMemFree(prGlueInfo->prAdapter, prP2pRadarInfo); + + return i4BytesWritten; +} + +int priv_driver_show_dfs_help(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + int32_t i4BytesWritten = 0; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "\n--iwpriv wlanX driver \"show_dfs_state\"\n"); + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "\nINACTIVE: RDD disable or temporary RDD disable"); + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "\nCHECKING: During CAC time"); + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "\nACTIVE : In-serive monitoring"); + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "\nDETECTED: Has detected radar but hasn't moved to new channel\n"); + + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "\n--iwpriv wlanX driver \"show_dfs_radar_param\"\n"); + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "\nShow the latest pulse information\n"); + + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "\n--iwpriv wlanX driver \"show_dfs_cac_time\"\n"); + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "\nShow the remaining time of CAC\n"); + + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "\n--iwpriv wlanX set ByPassCac=yy\n"); + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "\nValue yy: set the time of CAC\n"); + + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "\n--iwpriv wlanX set RDDReport=yy\n"); + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "\nValue yy is \"0\" or \"1\""); + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "\n\"0\": Emulate RDD0 manual radar event"); + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "\n\"1\": Emulate RDD1 manual radar event\n"); + + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "\n--iwpriv wlanX set RadarDetectMode=yy\n"); + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "\nValue yy is \"0\" or \"1\""); + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "\n\"0\": Switch channel when radar detected (default)"); + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "\n\"1\": Do not switch channel when radar detected"); + + return i4BytesWritten; +} + +int priv_driver_show_dfs_cac_time(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + int32_t i4BytesWritten = 0; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + if (p2pFuncGetDfsState() != DFS_STATE_CHECKING) { + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "\nNot in CAC period"); + return i4BytesWritten; + } + + LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, + "\nRemaining time of CAC: %dsec", p2pFuncGetCacRemainingTime()); + + return i4BytesWritten; +} + +#endif +int priv_driver_set_miracast(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + + struct ADAPTER *prAdapter = NULL; + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t i4BytesWritten = 0; + /* WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; */ + /* UINT_32 u4BufLen = 0; */ + int32_t i4Argc = 0; + uint32_t ucMode = 0; + struct WFD_CFG_SETTINGS *prWfdCfgSettings = + (struct WFD_CFG_SETTINGS *) NULL; + struct MSG_WFD_CONFIG_SETTINGS_CHANGED *prMsgWfdCfgUpdate = + (struct MSG_WFD_CONFIG_SETTINGS_CHANGED *) NULL; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + int32_t u4Ret = 0; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + prAdapter = prGlueInfo->prAdapter; + if (i4Argc >= 2) { + /* ucMode = kalStrtoul(apcArgv[1], NULL, 0); */ + u4Ret = kalkStrtou32(apcArgv[1], 0, &ucMode); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse ucMode error u4Ret=%d\n", + u4Ret); + + if (g_ucMiracastMode == (uint8_t) ucMode) { + /* XXX: continue or skip */ + /* XXX: continue or skip */ + } + + g_ucMiracastMode = (uint8_t) ucMode; + prMsgWfdCfgUpdate = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, + sizeof(struct MSG_WFD_CONFIG_SETTINGS_CHANGED)); + + if (prMsgWfdCfgUpdate != NULL) { + + prWfdCfgSettings = + &(prAdapter->rWifiVar.rWfdConfigureSettings); + prMsgWfdCfgUpdate->rMsgHdr.eMsgId = + MID_MNY_P2P_WFD_CFG_UPDATE; + prMsgWfdCfgUpdate->prWfdCfgSettings = prWfdCfgSettings; + + if (ucMode == MIRACAST_MODE_OFF) { + prWfdCfgSettings->ucWfdEnable = 0; + kalSnprintf(pcCommand, i4TotalLen, + CMD_SET_CHIP " mira 0"); + } else if (ucMode == MIRACAST_MODE_SOURCE) { + prWfdCfgSettings->ucWfdEnable = 1; + kalSnprintf(pcCommand, i4TotalLen, + CMD_SET_CHIP " mira 1"); + } else if (ucMode == MIRACAST_MODE_SINK) { + prWfdCfgSettings->ucWfdEnable = 2; + kalSnprintf(pcCommand, i4TotalLen, + CMD_SET_CHIP " mira 2"); + } else { + prWfdCfgSettings->ucWfdEnable = 0; + kalSnprintf(pcCommand, i4TotalLen, + CMD_SET_CHIP " mira 0"); + } + + mboxSendMsg(prAdapter, MBOX_ID_0, (struct MSG_HDR *) + prMsgWfdCfgUpdate, MSG_SEND_METHOD_BUF); + + priv_driver_set_chip_config(prNetDev, pcCommand, + i4TotalLen); + } /* prMsgWfdCfgUpdate */ + else { + ASSERT(FALSE); + i4BytesWritten = -1; + } + } + + /* i4Argc */ + return i4BytesWritten; +} + +int parseValueInString( + IN char **pcCommand, + IN const char *acDelim, + IN void *aucValue, + IN int u4MaxLen) +{ + uint8_t *pcPtr; + uint32_t u4Len; + uint8_t *pucValueHead = NULL; + uint8_t *pucValueTail = NULL; + + if (*pcCommand + && !kalStrnCmp(*pcCommand, acDelim, kalStrLen(acDelim))) { + pcPtr = kalStrSep(pcCommand, "=,"); + pucValueHead = *pcCommand; + pcPtr = kalStrSep(pcCommand, "=,"); + DBGLOG(REQ, TRACE, "pucValueHead = %s\n", pucValueHead); + if (pucValueHead) { + u4Len = kalStrLen(pucValueHead); + if (*pcCommand) { + pucValueTail = *pcCommand - 1; + u4Len = pucValueTail - pucValueHead; + } + if (u4Len > u4MaxLen) + u4Len = u4MaxLen; + + /* MAC */ + if (!kalStrnCmp(acDelim, "MAC=", kalStrLen(acDelim))) { + u8 *addr = aucValue; + + wlanHwAddrToBin(pucValueHead, addr); + DBGLOG(REQ, TRACE, "MAC type"); + } else { + u8 *addr = aucValue; + + kalStrnCpy(addr, pucValueHead, u4Len); + *((char *)aucValue + u4Len) = '\0'; + DBGLOG(REQ, TRACE, + "STR type = %s\n", (char *)aucValue); + } + return 0; + } + } + + return -1; +} + +int priv_driver_set_ap_set_mac_acl(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + struct BSS_INFO *prBssInfo = NULL; + uint8_t aucValue[WLAN_CFG_ARGV_MAX] = {0}; + uint8_t ucRoleIdx = 0, ucBssIdx = 0; + int32_t i4BytesWritten = 0; + int32_t i4Count = 0, i4Mode = 0; + int i = 0; + + DBGLOG(REQ, INFO, "command is %s\n", pcCommand); + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + goto error; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + /* get Bss Index from ndev */ + if (mtk_Netdev_To_RoleIdx(prGlueInfo, prNetDev, &ucRoleIdx) != 0) + goto error; + if (p2pFuncRoleToBssIdx(prGlueInfo->prAdapter, ucRoleIdx, &ucBssIdx) != + WLAN_STATUS_SUCCESS) + goto error; + + DBGLOG(REQ, INFO, "ucRoleIdx = %d\n", ucRoleIdx); + prBssInfo = prAdapter->aprBssInfo[ucBssIdx]; + if (!prBssInfo) { + DBGLOG(REQ, WARN, "bss is not active\n"); + goto error; + } + + /* Mode */ + if (parseValueInString(&pcCommand, + "MAC_MODE=", &aucValue, WLAN_CFG_ARGV_MAX)) { + DBGLOG(REQ, ERROR, "[MODE] parse error\n"); + goto error; + } + if (kalkStrtou32(aucValue, 0, &i4Mode)) { + DBGLOG(REQ, ERROR, "[MODE] convert to int error\n"); + goto error; + } + if (i4Mode == 0) + prBssInfo->rACL.ePolicy = PARAM_CUSTOM_ACL_POLICY_DISABLE; + else if (i4Mode == 1) + prBssInfo->rACL.ePolicy = PARAM_CUSTOM_ACL_POLICY_DENY; + else if (i4Mode == 2) + prBssInfo->rACL.ePolicy = PARAM_CUSTOM_ACL_POLICY_ACCEPT; + else { + DBGLOG(REQ, ERROR, "[MODE] invalid ACL policy= %d\n", i4Mode); + goto error; + } + + /* Count */ + /* No need to parse count for diabled mode */ + if (prBssInfo->rACL.ePolicy != PARAM_CUSTOM_ACL_POLICY_DISABLE) { + if (parseValueInString(&pcCommand, + "MAC_CNT=", &aucValue, WLAN_CFG_ARGV_MAX)) { + DBGLOG(REQ, ERROR, "[CNT] parse count error\n"); + goto error; + } + if (kalkStrtou32(aucValue, 0, &i4Count)) { + DBGLOG(REQ, ERROR, "[CNT] convert to int error\n"); + goto error; + } + if (i4Count > MAX_NUMBER_OF_ACL) { + DBGLOG(REQ, ERROR, "[CNT] invalid count > max ACL\n"); + goto error; + } + } + + /* MAC */ + if (prBssInfo->rACL.u4Num) { + /* Clear */ + kalMemZero(&prBssInfo->rACL.rEntry[0], + sizeof(struct PARAM_CUSTOM_ACL_ENTRY) * MAC_ADDR_LEN); + prBssInfo->rACL.u4Num = 0; + } + + if (prBssInfo->rACL.ePolicy != PARAM_CUSTOM_ACL_POLICY_DISABLE) { + for (i = 0; i < i4Count; i++) { + /* Add */ + if (parseValueInString(&pcCommand, + "MAC=", &aucValue, WLAN_CFG_ARGV_MAX)) + break; + kalMemCopy(prBssInfo->rACL.rEntry[i].aucAddr, + &aucValue, MAC_ADDR_LEN); + DBGLOG(REQ, INFO, + "[MAC] add mac addr " MACSTR " to ACL(%d).\n", + MAC2STR(prBssInfo->rACL.rEntry[i].aucAddr), i); + } + + prBssInfo->rACL.u4Num = i; + /* check ACL affects any existent association */ + p2pRoleUpdateACLEntry(prAdapter, ucBssIdx); + DBGLOG(REQ, INFO, + "[MAC] Mode = %d, #ACL = %d, count = %d\n", + i4Mode, i, i4Count); + } + + return i4BytesWritten; + +error: + return -1; +} + +int priv_driver_set_ap_set_cfg(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + struct WIFI_VAR *prWifiVar = NULL; + uint8_t aucValue[WLAN_CFG_ARGV_MAX] = {0}; + uint8_t ucRoleIdx = 0; + int32_t i4BytesWritten = 0; + int32_t i4MaxCount = 0, i4Channel = 0; + + DBGLOG(REQ, INFO, "command is %s\n", pcCommand); + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + goto error; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + prWifiVar = &prAdapter->rWifiVar; + + /* get role index from ndev */ + if (mtk_Netdev_To_RoleIdx(prGlueInfo, prNetDev, &ucRoleIdx) != 0) + goto error; + + DBGLOG(REQ, INFO, "ucRoleIdx = %d\n", ucRoleIdx); + + /* Cfg */ + if (parseValueInString(&pcCommand, "ASCII_CMD=", + &aucValue, WLAN_CFG_ARGV_MAX)) { + DBGLOG(REQ, ERROR, "[CFG] cmd parse error\n"); + goto error; + } + if (kalStrnCmp(aucValue, "AP_CFG", 6)) { + DBGLOG(REQ, ERROR, "[CFG] sub cmd parse error\n"); + goto error; + } + + /* Channel */ + if (parseValueInString(&pcCommand, "CHANNEL=", + &aucValue, WLAN_CFG_ARGV_MAX)) { + DBGLOG(REQ, ERROR, "[CH] parse error\n"); + goto error; + } + if (kalkStrtou32(aucValue, 0, &i4Channel)) { + DBGLOG(REQ, ERROR, "[CH] convert to int error\n"); + goto error; + } + + /* Max SCB */ + if (parseValueInString(&pcCommand, "MAX_SCB=", + &aucValue, WLAN_CFG_ARGV_MAX)) { + DBGLOG(REQ, ERROR, "[MAX_SCB] parse error\n"); + goto error; + } + if (kalkStrtou32(aucValue, 0, &i4MaxCount)) { + DBGLOG(REQ, ERROR, "[MAX_SCB] convert to int error\n"); + goto error; + } + + /* Overwrite AP channel */ + prWifiVar->ucApChannel = i4Channel; + + /* Set max clients of Hotspot */ + kalP2PSetMaxClients(prGlueInfo, i4MaxCount, ucRoleIdx); + + DBGLOG(REQ, INFO, + "[CFG] CH = %d, MAX_SCB = %d\n", + i4Channel, i4MaxCount); + + /* Stop ap */ +#if 0 + { + struct PARAM_CUSTOM_P2P_SET_STRUCT rSetP2P; + + rSetP2P.u4Mode = 0; + rSetP2P.u4Enable = 0; + set_p2p_mode_handler(prNetDev, rSetP2P); + } +#endif + + return i4BytesWritten; + +error: + return -1; +} + +int priv_driver_set_ap_get_sta_list(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + struct BSS_INFO *prBssInfo = NULL; + struct LINK *prClientList; + struct STA_RECORD *prCurrStaRec, *prNextStaRec; + uint8_t ucRoleIdx = 0, ucBssIdx = 0; + int32_t i4BytesWritten = 0; + + DBGLOG(REQ, INFO, "command is %s\n", pcCommand); + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + goto error; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + /* get Bss Index from ndev */ + if (mtk_Netdev_To_RoleIdx(prGlueInfo, prNetDev, &ucRoleIdx) != 0) + goto error; + if (p2pFuncRoleToBssIdx(prGlueInfo->prAdapter, ucRoleIdx, &ucBssIdx) != + WLAN_STATUS_SUCCESS) + goto error; + + DBGLOG(REQ, INFO, "ucRoleIdx = %d\n", ucRoleIdx); + prBssInfo = prAdapter->aprBssInfo[ucBssIdx]; + if (!prBssInfo) { + DBGLOG(REQ, WARN, "bss is not active\n"); + goto error; + } + + prClientList = &prBssInfo->rStaRecOfClientList; + LINK_FOR_EACH_ENTRY_SAFE(prCurrStaRec, + prNextStaRec, prClientList, rLinkEntry, struct STA_RECORD) { + if (!prCurrStaRec) { + DBGLOG(REQ, WARN, "NULL STA_REC\n"); + break; + } + DBGLOG(SW4, INFO, "STA[%u] [" MACSTR "]\n", + prCurrStaRec->ucIndex, + MAC2STR(prCurrStaRec->aucMacAddr)); + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + ""MACSTR"\n", + MAC2STR(prCurrStaRec->aucMacAddr)); + } + + return i4BytesWritten; + +error: + return -1; +} + +int priv_driver_set_ap_sta_disassoc(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + uint8_t aucValue[WLAN_CFG_ARGV_MAX] = {0}; + uint8_t ucRoleIdx = 0; + int32_t i4BytesWritten = 0; + struct MSG_P2P_CONNECTION_ABORT *prDisconnectMsg = + (struct MSG_P2P_CONNECTION_ABORT *) NULL; + + DBGLOG(REQ, INFO, "command is %s\n", pcCommand); + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + goto error; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + /* get role index from ndev */ + if (mtk_Netdev_To_RoleIdx(prGlueInfo, prNetDev, &ucRoleIdx) != 0) + goto error; + + DBGLOG(REQ, INFO, "ucRoleIdx = %d\n", ucRoleIdx); + + if (parseValueInString(&pcCommand, "MAC=", + &aucValue, WLAN_CFG_ARGV_MAX)) { + DBGLOG(REQ, ERROR, "[MAC] parse error\n"); + goto error; + } + + prDisconnectMsg = + (struct MSG_P2P_CONNECTION_ABORT *) + cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, + sizeof(struct MSG_P2P_CONNECTION_ABORT)); + if (prDisconnectMsg == NULL) { + ASSERT(FALSE); + goto error; + } + + prDisconnectMsg->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_ABORT; + prDisconnectMsg->ucRoleIdx = ucRoleIdx; + COPY_MAC_ADDR(prDisconnectMsg->aucTargetID, aucValue); + prDisconnectMsg->u2ReasonCode = REASON_CODE_UNSPECIFIED; + prDisconnectMsg->fgSendDeauth = TRUE; + + mboxSendMsg(prGlueInfo->prAdapter, + MBOX_ID_0, + (struct MSG_HDR *) prDisconnectMsg, + MSG_SEND_METHOD_BUF); + + return i4BytesWritten; + +error: + return -1; +} + +int priv_driver_set_ap_nss(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint32_t u4Ret, u4Parse = 0; + uint8_t ucNSS; + + ASSERT(prNetDev); + + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + + if (i4Argc == 2) { + u4Ret = kalkStrtou32(apcArgv[1], 0, &u4Parse); + if (u4Ret) { + DBGLOG(REQ, WARN, "parse apcArgv error u4Ret=%d\n", + u4Ret); + goto error; + } + ucNSS = (uint8_t) u4Parse; + + if ((ucNSS == 1) || (ucNSS == 2)) { + prGlueInfo->prAdapter->rWifiVar.ucAp5gNSS = ucNSS; + prGlueInfo->prAdapter->rWifiVar.ucAp2gNSS = ucNSS; + + DBGLOG(REQ, STATE, + "Ap2gNSS = %d\n", + prGlueInfo->prAdapter->rWifiVar.ucAp2gNSS); + } else + DBGLOG(REQ, WARN, "Invalid nss=%d\n", + ucNSS); + } else { + DBGLOG(INIT, ERROR, + "iwpriv wlanXX SET_AP_NSS \n"); + } + + return i4BytesWritten; + +error: + return -1; +} + +int +__priv_set_ap(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) +{ + uint32_t u4SubCmd = 0; + uint16_t u2Cmd = 0; + int32_t i4TotalFixLen = 1024; + int32_t i4CmdFound = 0; + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4BytesWritten = 0; + + ASSERT(prNetDev); + ASSERT(prIwReqData); + if (!prNetDev || !prIwReqData) { + DBGLOG(REQ, INFO, + "invalid param(0x%p, 0x%p)\n", + prNetDev, prIwReqData); + return -EINVAL; + } + + u2Cmd = prIwReqInfo->cmd; + DBGLOG(REQ, INFO, "prIwReqInfo->cmd %x\n", u2Cmd); + + u4SubCmd = (uint32_t) prIwReqData->data.flags; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + ASSERT(prGlueInfo); + if (!prGlueInfo) { + DBGLOG(REQ, INFO, + "invalid prGlueInfo(0x%p, 0x%p)\n", + prNetDev, + *((struct GLUE_INFO **) netdev_priv(prNetDev))); + return -EINVAL; + } + + DBGLOG(REQ, INFO, "prIwReqData->data.length %u\n", + prIwReqData->data.length); + + ASSERT(IW_IS_GET(u2Cmd)); + if (prIwReqData->data.length != 0) { + if (!kal_access_ok(VERIFY_READ, prIwReqData->data.pointer, + prIwReqData->data.length)) { + DBGLOG(REQ, INFO, + "%s access_ok Read fail written = %d\n", + __func__, i4BytesWritten); + return -EFAULT; + } + if (copy_from_user(aucOidBuf, + prIwReqData->data.pointer, + prIwReqData->data.length)) { + DBGLOG(REQ, INFO, + "%s copy_form_user fail written = %d\n", + __func__, + prIwReqData->data.length); + return -EFAULT; + } + /* prIwReqData->data.length include the terminate '\0' */ + aucOidBuf[prIwReqData->data.length - 1] = 0; + } + + DBGLOG(REQ, INFO, "%s aucBuf %s\n", __func__, aucOidBuf); + + if (!pcExtra) + goto exit; + + i4CmdFound = 1; + switch (u2Cmd) { + case IOC_AP_GET_STA_LIST: + i4BytesWritten = + priv_driver_set_ap_get_sta_list( + prNetDev, + pcExtra, + i4TotalFixLen); + break; + case IOC_AP_SET_MAC_FLTR: + i4BytesWritten = + priv_driver_set_ap_set_mac_acl( + prNetDev, + aucOidBuf, + i4TotalFixLen); + break; + case IOC_AP_SET_CFG: + i4BytesWritten = + priv_driver_set_ap_set_cfg( + prNetDev, + aucOidBuf, + i4TotalFixLen); + break; + case IOC_AP_STA_DISASSOC: + i4BytesWritten = + priv_driver_set_ap_sta_disassoc( + prNetDev, + aucOidBuf, + i4TotalFixLen); + break; + case IOC_AP_SET_NSS: + i4BytesWritten = + priv_driver_set_ap_nss( + prNetDev, + aucOidBuf, + i4TotalFixLen); + break; + default: + i4CmdFound = 0; + break; + } + + if (i4CmdFound == 0) + DBGLOG(REQ, INFO, + "Unknown driver command\n"); + + if (i4BytesWritten >= 0) { + if ((i4BytesWritten == 0) && (i4TotalFixLen > 0)) { + /* reset the command buffer */ + pcExtra[0] = '\0'; + } else if (i4BytesWritten >= i4TotalFixLen) { + DBGLOG(REQ, INFO, + "%s: i4BytesWritten %d > i4TotalFixLen < %d\n", + __func__, i4BytesWritten, i4TotalFixLen); + i4BytesWritten = i4TotalFixLen; + } else { + pcExtra[i4BytesWritten] = '\0'; + i4BytesWritten++; + } + } + + DBGLOG(REQ, INFO, "%s i4BytesWritten = %d\n", __func__, + i4BytesWritten); + +exit: + + DBGLOG(REQ, INFO, "pcExtra done\n"); + + if (i4BytesWritten >= 0) + prIwReqData->data.length = i4BytesWritten; + + return 0; +} + +int +priv_set_ap(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) +{ +#if 0 + return compat_priv(prNetDev, prIwReqInfo, + prIwReqData, pcExtra, __priv_set_ap); +#else + return __priv_set_ap(prNetDev, prIwReqInfo, + prIwReqData, pcExtra); +#endif +} + +#if CFG_SUPPORT_CAL_RESULT_BACKUP_TO_HOST +/* + * Memo + * 00 : Reset All Cal Data in Driver + * 01 : Trigger All Cal Function + * 02 : Get Thermal Temp from FW + * 03 : Get Cal Data Size from FW + * 04 : Get Cal Data from FW (Rom) + * 05 : Get Cal Data from FW (Ram) + * 06 : Print Cal Data in Driver (Rom) + * 07 : Print Cal Data in Driver (Ram) + * 08 : Print Cal Data in FW (Rom) + * 09 : Print Cal Data in FW (Ram) + * 10 : Send Cal Data to FW (Rom) + * 11 : Send Cal Data to FW (Ram) + */ +static int priv_driver_set_calbackup_test_drv_fw(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint32_t u4Ret, u4GetInput; + int32_t i4ArgNum = 2; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(RFTEST, INFO, "%s\r\n", __func__); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + if (i4Argc >= i4ArgNum) { + u4Ret = kalkStrtou32(apcArgv[1], 0, &u4GetInput); + if (u4Ret) + DBGLOG(RFTEST, INFO, + "priv_driver_set_calbackup_test_drv_fw Parsing Fail\n"); + + if (u4GetInput == 0) { + DBGLOG(RFTEST, INFO, + "(New Flow) CMD#0 : Reset All Cal Data in Driver.\n"); + /* (New Flow 20160720) Step 0 : Reset All Cal Data + * Structure + */ + memset(&g_rBackupCalDataAllV2, 1, + sizeof(struct RLM_CAL_RESULT_ALL_V2)); + g_rBackupCalDataAllV2.u4MagicNum1 = 6632; + g_rBackupCalDataAllV2.u4MagicNum2 = 6632; + } else if (u4GetInput == 1) { + DBGLOG(RFTEST, INFO, + "CMD#1 : Trigger FW Do All Cal.\n"); + /* Step 1 : Trigger All Cal Function */ + + rStatus = rlmCalBackup(prGlueInfo->prAdapter, 1, 2, 0); + DBGLOG(RFTEST, INFO, + "Trigger FW Do All Cal, rStatus = 0x%08x\n", + rStatus); + } else if (u4GetInput == 2) { + DBGLOG(RFTEST, INFO, + "(New Flow) CMD#2 : Get Thermal Temp from FW.\n"); + /* (New Flow 20160720) Step 2 : Get Thermal Temp from + * FW + */ + + rStatus = rlmCalBackup(prGlueInfo->prAdapter, 0, 0, 0); + DBGLOG(RFTEST, INFO, + "Get Thermal Temp from FW, rStatus = 0x%08x\n", + rStatus); + + } else if (u4GetInput == 3) { + DBGLOG(RFTEST, INFO, + "(New Flow) CMD#3 : Get Cal Data Size from FW.\n"); + /* (New Flow 20160720) Step 3 : Get Cal Data Size from + * FW + */ + + rStatus = rlmCalBackup(prGlueInfo->prAdapter, 0, 1, 0); + DBGLOG(RFTEST, INFO, + "Get Rom Cal Data Size, rStatus = 0x%08x\n", + rStatus); + + rStatus = rlmCalBackup(prGlueInfo->prAdapter, 0, 1, 1); + DBGLOG(RFTEST, INFO, + "Get Ram Cal Data Size, rStatus = 0x%08x\n", + rStatus); + + } else if (u4GetInput == 4) { +#if 1 + DBGLOG(RFTEST, INFO, + "(New Flow) CMD#4 : Print Cal Data in FW (Ram) (Part 1 - [0]~[3327]).\n"); + /* Debug Use : Print Cal Data in FW (Ram) */ + rStatus = rlmCalBackup(prGlueInfo->prAdapter, 4, 6, 1); + DBGLOG(RFTEST, INFO, + "Print Cal Data in FW (Ram), rStatus = 0x%08x\n", + rStatus); +#else /* For Temp Use this Index */ + DBGLOG(RFTEST, INFO, + "(New Flow) CMD#4 : Get Cal Data from FW (Rom). Start!!!!!!!!!!!\n"); + DBGLOG(RFTEST, INFO, "Thermal Temp = %d\n", + g_rBackupCalDataAllV2.u4ThermalInfo); + DBGLOG(RFTEST, INFO, "Total Length (Rom) = %d\n", + g_rBackupCalDataAllV2.u4ValidRomCalDataLength); + /* (New Flow 20160720) Step 3 : Get Cal Data from FW */ + + rStatus = rlmCalBackup(prGlueInfo->prAdapter, 2, 4, 0); + DBGLOG(RFTEST, INFO, + "Get Cal Data from FW (Rom), rStatus = 0x%08x\n", + rStatus); +#endif + } else if (u4GetInput == 5) { +#if 1 + DBGLOG(RFTEST, INFO, + "(New Flow) CMD#5 : Print RAM Cal Data in Driver (Part 1 - [0]~[3327]).\n"); + DBGLOG(RFTEST, INFO, + "==================================================================\n"); + /* RFTEST_INFO_LOGDUMP32( + * &(g_rBackupCalDataAllV2.au4RamCalData[0]), + * 3328*sizeof(uint32_t)); + */ + DBGLOG(RFTEST, INFO, + "==================================================================\n"); + DBGLOG(RFTEST, INFO, + "Dumped Ram Cal Data Szie : %d bytes\n", + 3328*sizeof(uint32_t)); + DBGLOG(RFTEST, INFO, + "Total Ram Cal Data Szie : %d bytes\n", + g_rBackupCalDataAllV2.u4ValidRamCalDataLength); + DBGLOG(RFTEST, INFO, + "==================================================================\n"); +#else /* For Temp Use this Index */ + DBGLOG(RFTEST, INFO, + "(New Flow) CMD#5 : Get Cal Data from FW (Ram). Start!!!!!!!!!!!\n"); + DBGLOG(RFTEST, INFO, "Thermal Temp = %d\n", + g_rBackupCalDataAllV2.u4ThermalInfo); + DBGLOG(RFTEST, INFO, "Total Length (Ram) = %d\n", + g_rBackupCalDataAllV2.u4ValidRamCalDataLength); + /* (New Flow 20160720) Step 3 : Get Cal Data from FW */ + + rStatus = rlmCalBackup(prGlueInfo->prAdapter, 2, 4, 1); + DBGLOG(RFTEST, INFO, + "Get Cal Data from FW (Ram), rStatus = 0x%08x\n", + rStatus); +#endif + } else if (u4GetInput == 6) { + DBGLOG(RFTEST, INFO, + "(New Flow) CMD#6 : Print ROM Cal Data in Driver.\n"); + DBGLOG(RFTEST, INFO, + "==================================================================\n"); + /* RFTEST_INFO_LOGDUMP32( + * &(g_rBackupCalDataAllV2.au4RomCalData[0]), + * g_rBackupCalDataAllV2.u4ValidRomCalDataLength); + */ + DBGLOG(RFTEST, INFO, + "==================================================================\n"); + DBGLOG(RFTEST, INFO, + "Total Rom Cal Data Szie : %d bytes\n", + g_rBackupCalDataAllV2.u4ValidRomCalDataLength); + DBGLOG(RFTEST, INFO, + "==================================================================\n"); + } else if (u4GetInput == 7) { + DBGLOG(RFTEST, INFO, + "(New Flow) CMD#7 : Print RAM Cal Data in Driver (Part 2 - [3328]~[6662]).\n"); + DBGLOG(RFTEST, INFO, + "==================================================================\n"); + /* RFTEST_INFO_LOGDUMP32( + * &(g_rBackupCalDataAllV2.au4RamCalData[3328]), + * (g_rBackupCalDataAllV2.u4ValidRamCalDataLength - + * 3328*sizeof(uint32_t))); + */ + DBGLOG(RFTEST, INFO, + "==================================================================\n"); + DBGLOG(RFTEST, INFO, + "Dumped Ram Cal Data Szie : %d bytes\n", + (g_rBackupCalDataAllV2.u4ValidRamCalDataLength - + 3328*sizeof(uint32_t))); + DBGLOG(RFTEST, INFO, + "Total Ram Cal Data Szie : %d bytes\n", + g_rBackupCalDataAllV2.u4ValidRamCalDataLength); + DBGLOG(RFTEST, INFO, + "==================================================================\n"); + } else if (u4GetInput == 8) { + DBGLOG(RFTEST, INFO, + "(New Flow) CMD#8 : Print Cal Data in FW (Rom).\n"); + /* Debug Use : Print Cal Data in FW (Rom) */ + + rStatus = rlmCalBackup(prGlueInfo->prAdapter, 4, 6, 0); + DBGLOG(RFTEST, INFO, + "Print Cal Data in FW (Rom), rStatus = 0x%08x\n", + rStatus); + + } else if (u4GetInput == 9) { + DBGLOG(RFTEST, INFO, + "(New Flow) CMD#9 : Print Cal Data in FW (Ram) (Part 2 - [3328]~[6662]).\n"); + /* Debug Use : Print Cal Data in FW (Ram) */ + + rStatus = rlmCalBackup(prGlueInfo->prAdapter, 4, 6, 2); + DBGLOG(RFTEST, INFO, + "Print Cal Data in FW (Ram), rStatus = 0x%08x\n", + rStatus); + + } else if (u4GetInput == 10) { + DBGLOG(RFTEST, INFO, + "(New Flow) CMD#10 : Send Cal Data to FW (Rom).\n"); + /* Send Cal Data to FW (Rom) */ + + rStatus = rlmCalBackup(prGlueInfo->prAdapter, 3, 5, 0); + DBGLOG(RFTEST, INFO, + "Send Cal Data to FW (Rom), rStatus = 0x%08x\n", + rStatus); + + } else if (u4GetInput == 11) { + DBGLOG(RFTEST, INFO, + "(New Flow) CMD#11 : Send Cal Data to FW (Ram).\n"); + /* Send Cal Data to FW (Ram) */ + + rStatus = rlmCalBackup(prGlueInfo->prAdapter, 3, 5, 1); + DBGLOG(RFTEST, INFO, + "Send Cal Data to FW (Ram), rStatus = 0x%08x\n", + rStatus); + + } + } + + return i4BytesWritten; +} /* priv_driver_set_calbackup_test_drv_fw */ +#endif + +#if CFG_WOW_SUPPORT +static int priv_driver_set_wow(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct WOW_CTRL *pWOW_CTRL = NULL; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = { 0 }; + uint32_t u4Ret = 0; + uint32_t Enable = 0; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + pWOW_CTRL = &prGlueInfo->prAdapter->rWowCtrl; + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + u4Ret = kalkStrtou32(apcArgv[1], 0, &Enable); + + if (u4Ret) + DBGLOG(REQ, LOUD, "parse bEnable error u4Ret=%d\n", u4Ret); + + DBGLOG(INIT, INFO, "CMD set_wow_enable = %d\n", Enable); + DBGLOG(INIT, INFO, "Scenario ID %d\n", pWOW_CTRL->ucScenarioId); + DBGLOG(INIT, INFO, "ucBlockCount %d\n", pWOW_CTRL->ucBlockCount); + DBGLOG(INIT, INFO, "interface %d\n", + pWOW_CTRL->astWakeHif[0].ucWakeupHif); + DBGLOG(INIT, INFO, "gpio_pin %d\n", + pWOW_CTRL->astWakeHif[0].ucGpioPin); + DBGLOG(INIT, INFO, "gpio_level 0x%x\n", + pWOW_CTRL->astWakeHif[0].ucTriggerLvl); + DBGLOG(INIT, INFO, "gpio_timer %d\n", + pWOW_CTRL->astWakeHif[0].u4GpioInterval); + kalWowProcess(prGlueInfo, Enable); + + return 0; +} + +static int priv_driver_set_wow_enable(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct WOW_CTRL *pWOW_CTRL = NULL; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = { 0 }; + uint32_t u4Ret = 0; + uint8_t ucEnable = 0; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + pWOW_CTRL = &prGlueInfo->prAdapter->rWowCtrl; + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + u4Ret = kalkStrtou8(apcArgv[1], 0, &ucEnable); + + if (u4Ret) + DBGLOG(REQ, LOUD, "parse bEnable error u4Ret=%d\n", u4Ret); + + pWOW_CTRL->fgWowEnable = ucEnable; + + DBGLOG(PF, INFO, "WOW enable %d\n", pWOW_CTRL->fgWowEnable); + + return 0; +} + +static int priv_driver_set_wow_par(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct WOW_CTRL *pWOW_CTRL = NULL; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = { 0 }; + int32_t u4Ret = 0; + uint8_t ucWakeupHif = 0, GpioPin = 0, ucGpioLevel = 0, ucBlockCount = 0, + ucScenario = 0; + uint32_t u4GpioTimer = 0; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + pWOW_CTRL = &prGlueInfo->prAdapter->rWowCtrl; + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + if (i4Argc > 3) { + + u4Ret = kalkStrtou8(apcArgv[1], 0, &ucWakeupHif); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse ucWakeupHif error u4Ret=%d\n", + u4Ret); + pWOW_CTRL->astWakeHif[0].ucWakeupHif = ucWakeupHif; + + u4Ret = kalkStrtou8(apcArgv[2], 0, &GpioPin); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse GpioPin error u4Ret=%d\n", + u4Ret); + pWOW_CTRL->astWakeHif[0].ucGpioPin = GpioPin; + + u4Ret = kalkStrtou8(apcArgv[3], 0, &ucGpioLevel); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse Gpio level error u4Ret=%d\n", + u4Ret); + pWOW_CTRL->astWakeHif[0].ucTriggerLvl = ucGpioLevel; + + u4Ret = kalkStrtou32(apcArgv[4], 0, &u4GpioTimer); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse u4GpioTimer error u4Ret=%d\n", + u4Ret); + pWOW_CTRL->astWakeHif[0].u4GpioInterval = u4GpioTimer; + + u4Ret = kalkStrtou8(apcArgv[5], 0, &ucScenario); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse ucScenario error u4Ret=%d\n", + u4Ret); + pWOW_CTRL->ucScenarioId = ucScenario; + + u4Ret = kalkStrtou8(apcArgv[6], 0, &ucBlockCount); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse ucBlockCnt error u4Ret=%d\n", + u4Ret); + pWOW_CTRL->ucBlockCount = ucBlockCount; + + DBGLOG(INIT, INFO, "gpio_scenario%d\n", + pWOW_CTRL->ucScenarioId); + DBGLOG(INIT, INFO, "interface %d\n", + pWOW_CTRL->astWakeHif[0].ucWakeupHif); + DBGLOG(INIT, INFO, "gpio_pin %d\n", + pWOW_CTRL->astWakeHif[0].ucGpioPin); + DBGLOG(INIT, INFO, "gpio_level %d\n", + pWOW_CTRL->astWakeHif[0].ucTriggerLvl); + DBGLOG(INIT, INFO, "gpio_timer %d\n", + pWOW_CTRL->astWakeHif[0].u4GpioInterval); + + return 0; + } else + return -1; + + +} + +static int priv_driver_set_wow_udpport(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct WOW_CTRL *pWOW_CTRL = NULL; + int32_t i4Argc = 0; + int8_t *apcPortArgv[WLAN_CFG_ARGV_MAX_LONG] = { 0 }; /* to input 20 port + */ + int32_t u4Ret = 0, ii; + uint8_t ucVer = 0, ucCount; + uint16_t u2Port = 0; + uint16_t *pausPortArry; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + pWOW_CTRL = &prGlueInfo->prAdapter->rWowCtrl; + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgumentLong(pcCommand, &i4Argc, apcPortArgv); + DBGLOG(REQ, WARN, "argc is %i\n", i4Argc); + + /* example: set_wow_udp 0 5353,8080 (set) */ + /* example: set_wow_udp 1 (clear) */ + + if (i4Argc >= 3) { + + /* Pick Max */ + ucCount = ((i4Argc - 2) > MAX_TCP_UDP_PORT) ? MAX_TCP_UDP_PORT : + (i4Argc - 2); + DBGLOG(PF, INFO, "UDP ucCount=%d\n", ucCount); + + u4Ret = kalkStrtou8(apcPortArgv[1], 0, &ucVer); + if (u4Ret) { + DBGLOG(REQ, LOUD, "parse ucWakeupHif error u4Ret=%d\n", + u4Ret); + return -1; + } + + /* IPv4/IPv6 */ + DBGLOG(PF, INFO, "ucVer=%d\n", ucVer); + if (ucVer == 0) { + pWOW_CTRL->stWowPort.ucIPv4UdpPortCnt = ucCount; + pausPortArry = pWOW_CTRL->stWowPort.ausIPv4UdpPort; + } else { + pWOW_CTRL->stWowPort.ucIPv6UdpPortCnt = ucCount; + pausPortArry = pWOW_CTRL->stWowPort.ausIPv6UdpPort; + } + + /* Port */ + for (ii = 0; ii < ucCount; ii++) { + u4Ret = kalkStrtou16(apcPortArgv[ii+2], 0, &u2Port); + if (u4Ret) { + DBGLOG(PF, ERROR, + "parse u2Port error u4Ret=%d\n", u4Ret); + return -1; + } + + pausPortArry[ii] = u2Port; + DBGLOG(PF, INFO, "ucPort=%d, idx=%d\n", u2Port, ii); + } + + return 0; + } else if (i4Argc == 2) { + + u4Ret = kalkStrtou8(apcPortArgv[1], 0, &ucVer); + if (u4Ret) { + DBGLOG(REQ, LOUD, "parse ucWakeupHif error u4Ret=%d\n", + u4Ret); + return -1; + } + + if (ucVer == 0) { + kalMemZero(prGlueInfo->prAdapter->rWowCtrl.stWowPort + .ausIPv4UdpPort, + sizeof(uint16_t) * MAX_TCP_UDP_PORT); + prGlueInfo->prAdapter->rWowCtrl.stWowPort + .ucIPv4UdpPortCnt = 0; + } else { + kalMemZero(prGlueInfo->prAdapter->rWowCtrl.stWowPort + .ausIPv6UdpPort, + sizeof(uint16_t) * MAX_TCP_UDP_PORT); + prGlueInfo->prAdapter->rWowCtrl.stWowPort + .ucIPv6UdpPortCnt = 0; + } + + return 0; + } else + return -1; + +} + +static int priv_driver_set_wow_tcpport(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct WOW_CTRL *pWOW_CTRL = NULL; + int32_t i4Argc = 0; + int8_t *apcPortArgv[WLAN_CFG_ARGV_MAX_LONG] = { 0 }; /* to input 20 port + */ + int32_t u4Ret = 0, ii; + uint8_t ucVer = 0, ucCount; + uint16_t u2Port = 0; + uint16_t *pausPortArry; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + pWOW_CTRL = &prGlueInfo->prAdapter->rWowCtrl; + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgumentLong(pcCommand, &i4Argc, apcPortArgv); + DBGLOG(REQ, WARN, "argc is %i\n", i4Argc); + + /* example: set_wow_tcp 0 5353,8080 (Set) */ + /* example: set_wow_tcp 1 (clear) */ + + if (i4Argc >= 3) { + + /* Pick Max */ + ucCount = ((i4Argc - 2) > MAX_TCP_UDP_PORT) ? MAX_TCP_UDP_PORT : + (i4Argc - 2); + DBGLOG(PF, INFO, "TCP ucCount=%d\n", ucCount); + + u4Ret = kalkStrtou8(apcPortArgv[1], 0, &ucVer); + if (u4Ret) { + DBGLOG(REQ, LOUD, "parse ucWakeupHif error u4Ret=%d\n", + u4Ret); + return -1; + } + + /* IPv4/IPv6 */ + DBGLOG(PF, INFO, "Ver=%d\n", ucVer); + if (ucVer == 0) { + pWOW_CTRL->stWowPort.ucIPv4TcpPortCnt = ucCount; + pausPortArry = pWOW_CTRL->stWowPort.ausIPv4TcpPort; + } else { + pWOW_CTRL->stWowPort.ucIPv6TcpPortCnt = ucCount; + pausPortArry = pWOW_CTRL->stWowPort.ausIPv6TcpPort; + } + + /* Port */ + for (ii = 0; ii < ucCount; ii++) { + u4Ret = kalkStrtou16(apcPortArgv[ii+2], 0, &u2Port); + if (u4Ret) { + DBGLOG(PF, ERROR, + "parse u2Port error u4Ret=%d\n", u4Ret); + return -1; + } + + pausPortArry[ii] = u2Port; + DBGLOG(PF, INFO, "ucPort=%d, idx=%d\n", u2Port, ii); + } + + return 0; + } else if (i4Argc == 2) { + + u4Ret = kalkStrtou8(apcPortArgv[1], 0, &ucVer); + if (u4Ret) { + DBGLOG(REQ, LOUD, "parse ucWakeupHif error u4Ret=%d\n", + u4Ret); + return -1; + } + + if (ucVer == 0) { + kalMemZero( + prGlueInfo->prAdapter->rWowCtrl.stWowPort + .ausIPv4UdpPort, + sizeof(uint16_t) * MAX_TCP_UDP_PORT); + prGlueInfo->prAdapter->rWowCtrl.stWowPort + .ucIPv4UdpPortCnt = 0; + } else { + kalMemZero( + prGlueInfo->prAdapter->rWowCtrl.stWowPort + .ausIPv6UdpPort, + sizeof(uint16_t) * MAX_TCP_UDP_PORT); + prGlueInfo->prAdapter->rWowCtrl.stWowPort + .ucIPv6UdpPortCnt = 0; + } + + return 0; + } else + return -1; + +} + +static int priv_driver_get_wow_port(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct WOW_CTRL *pWOW_CTRL = NULL; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = { 0 }; + int32_t u4Ret = 0, ii; + uint8_t ucVer = 0, ucProto = 0; + uint16_t ucCount; + uint16_t *pausPortArry; + int8_t *aucIp[2] = {"IPv4", "IPv6"}; + int8_t *aucProto[2] = {"UDP", "TCP"}; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + pWOW_CTRL = &prGlueInfo->prAdapter->rWowCtrl; + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + + /* example: get_wow_port 0 0 (ipv4-udp) */ + /* example: get_wow_port 0 1 (ipv4-tcp) */ + /* example: get_wow_port 1 0 (ipv6-udp) */ + /* example: get_wow_port 1 1 (ipv6-tcp) */ + + if (i4Argc >= 3) { + + /* 0=IPv4, 1=IPv6 */ + u4Ret = kalkStrtou8(apcArgv[1], 0, &ucVer); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse argc[1] error u4Ret=%d\n", + u4Ret); + + /* 0=UDP, 1=TCP */ + u4Ret = kalkStrtou8(apcArgv[2], 0, &ucProto); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse argc[2] error u4Ret=%d\n", + u4Ret); + + if (ucVer > 1) + ucVer = 0; + + if (ucProto > 1) + ucProto = 0; + + if (ucVer == 0) { + if (ucProto == 0) { + /* IPv4/UDP */ + ucCount = pWOW_CTRL->stWowPort.ucIPv4UdpPortCnt; + pausPortArry = + pWOW_CTRL->stWowPort.ausIPv4UdpPort; + } else { + /* IPv4/TCP */ + ucCount = pWOW_CTRL->stWowPort.ucIPv4TcpPortCnt; + pausPortArry = + pWOW_CTRL->stWowPort.ausIPv4TcpPort; + } + } else { + if (ucProto == 0) { + /* IPv6/UDP */ + ucCount = pWOW_CTRL->stWowPort.ucIPv6UdpPortCnt; + pausPortArry = + pWOW_CTRL->stWowPort.ausIPv6UdpPort; + } else { + /* IPv6/TCP */ + ucCount = pWOW_CTRL->stWowPort.ucIPv6TcpPortCnt; + pausPortArry = + pWOW_CTRL->stWowPort.ausIPv6TcpPort; + } + } + + /* Dunp Port */ + for (ii = 0; ii < ucCount; ii++) + DBGLOG(PF, INFO, "ucPort=%d, idx=%d\n", + pausPortArry[ii], ii); + + + DBGLOG(PF, INFO, "[%s/%s] count:%d\n", aucIp[ucVer], + aucProto[ucProto], ucCount); + + return 0; + } else + return -1; + +} +#endif + +static int priv_driver_set_adv_pws(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = { 0 }; + uint32_t u4Ret = 0; + uint8_t ucAdvPws = 0; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + u4Ret = kalkStrtou8(apcArgv[1], 0, &ucAdvPws); + + if (u4Ret) + DBGLOG(REQ, LOUD, "parse bEnable error u4Ret=%d\n", + u4Ret); + + prGlueInfo->prAdapter->rWifiVar.ucAdvPws = ucAdvPws; + + DBGLOG(INIT, INFO, "AdvPws:%d\n", + prGlueInfo->prAdapter->rWifiVar.ucAdvPws); + + return 0; + +} + +static int priv_driver_set_mdtim(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = { 0 }; + uint32_t u4Ret = 0; + uint8_t ucMultiDtim = 0, ucVer = 0; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + /* iwpriv wlan0 driver "set_mdtim 1 3 */ + if (i4Argc >= 3) { + + u4Ret = kalkStrtou8(apcArgv[1], 0, &ucVer); + if (u4Ret) { + DBGLOG(REQ, ERROR, "parse apcArgv1 error u4Ret=%d\n", + u4Ret); + return -1; + } + + u4Ret = kalkStrtou8(apcArgv[2], 0, &ucMultiDtim); + if (u4Ret) { + DBGLOG(REQ, ERROR, "parse apcArgv2 error u4Ret=%d\n", + u4Ret); + return -1; + } + + if (ucVer == 0) { + prGlueInfo->prAdapter->rWifiVar.ucWowOnMdtim = + ucMultiDtim; + DBGLOG(REQ, INFO, "WOW On MDTIM:%d\n", + prGlueInfo->prAdapter->rWifiVar.ucWowOnMdtim); + } else { + prGlueInfo->prAdapter->rWifiVar.ucWowOffMdtim = + ucMultiDtim; + DBGLOG(REQ, INFO, "WOW Off MDTIM:%d\n", + prGlueInfo->prAdapter->rWifiVar.ucWowOffMdtim); + } + } + + return 0; + +} + +int priv_driver_set_suspend_mode(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + u_int8_t fgEnable; + uint32_t u4Enable = 0; + int32_t u4Ret = 0; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + if (i4Argc >= 2) { + /* fgEnable = (kalStrtoul(apcArgv[1], NULL, 0) == 1) ? TRUE : + * FALSE; + */ + u4Ret = kalkStrtou32(apcArgv[1], 0, &u4Enable); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse u4Enable error u4Ret=%d\n", + u4Ret); + if (u4Enable == 1) + fgEnable = TRUE; + else + fgEnable = FALSE; + + if (prGlueInfo->fgIsInSuspendMode == fgEnable) { + DBGLOG(REQ, INFO, + "%s: Already in suspend mode [%u], SKIP!\n", + __func__, fgEnable); + return 0; + } + + DBGLOG(REQ, INFO, "%s: Set suspend mode [%u]\n", __func__, + fgEnable); + + prGlueInfo->fgIsInSuspendMode = fgEnable; + + wlanSetSuspendMode(prGlueInfo, fgEnable); + p2pSetSuspendMode(prGlueInfo, fgEnable); + } + + return 0; +} + +#if CFG_SUPPORT_SNIFFER +int priv_driver_set_monitor(IN struct net_device *prNetDev, IN char *pcCommand, + IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + int32_t i4Argc = 0; + int32_t i4BytesWritten = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + struct PARAM_CUSTOM_MONITOR_SET_STRUCT rMonitorSetInfo; + uint8_t ucEnable = 0; + uint8_t ucPriChannel = 0; + uint8_t ucChannelWidth = 0; + uint8_t ucExt = 0; + uint8_t ucSco = 0; + uint8_t ucChannelS1 = 0; + uint8_t ucChannelS2 = 0; + u_int8_t fgIsLegalChannel = FALSE; + u_int8_t fgError = FALSE; + u_int8_t fgEnable = FALSE; + enum ENUM_BAND eBand = BAND_NULL; + uint32_t u4Parse = 0; + int32_t u4Ret = 0; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + + if (i4Argc >= 5) { + /* ucEnable = (uint8_t) (kalStrtoul(apcArgv[1], NULL, 0)); + * ucPriChannel = (uint8_t) (kalStrtoul(apcArgv[2], NULL, 0)); + * ucChannelWidth = (uint8_t) (kalStrtoul(apcArgv[3], NULL, 0)); + * ucExt = (uint8_t) (kalStrtoul(apcArgv[4], NULL, 0)); + */ + u4Ret = kalkStrtou32(apcArgv[1], 0, &u4Parse); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse apcArgv error u4Ret=%d\n", + u4Ret); + ucEnable = (uint8_t) u4Parse; + u4Ret = kalkStrtou32(apcArgv[2], 0, &u4Parse); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse apcArgv error u4Ret=%d\n", + u4Ret); + ucPriChannel = (uint8_t) u4Parse; + u4Ret = kalkStrtou32(apcArgv[3], 0, &u4Parse); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse apcArgv error u4Ret=%d\n", + u4Ret); + ucChannelWidth = (uint8_t) u4Parse; + u4Ret = kalkStrtou32(apcArgv[4], 0, &u4Parse); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse apcArgv error u4Ret=%d\n", + u4Ret); + ucExt = (uint8_t) u4Parse; + + eBand = (ucPriChannel <= 14) ? BAND_2G4 : BAND_5G; + fgIsLegalChannel = rlmDomainIsLegalChannel(prAdapter, eBand, + ucPriChannel); + + if (fgIsLegalChannel == FALSE) { + i4BytesWritten = kalSnprintf(pcCommand, i4TotalLen, + "Illegal primary channel %d", + ucPriChannel); + return i4BytesWritten; + } + + switch (ucChannelWidth) { + case 160: + ucChannelWidth = (uint8_t) CW_160MHZ; + ucSco = (uint8_t) CHNL_EXT_SCN; + + if (ucPriChannel >= 36 && ucPriChannel <= 64) + ucChannelS2 = 50; + else if (ucPriChannel >= 100 && ucPriChannel <= 128) + ucChannelS2 = 114; + else + fgError = TRUE; + break; + + case 80: + ucChannelWidth = (uint8_t) CW_80MHZ; + ucSco = (uint8_t) CHNL_EXT_SCN; + + if (ucPriChannel >= 36 && ucPriChannel <= 48) + ucChannelS1 = 42; + else if (ucPriChannel >= 52 && ucPriChannel <= 64) + ucChannelS1 = 58; + else if (ucPriChannel >= 100 && ucPriChannel <= 112) + ucChannelS1 = 106; + else if (ucPriChannel >= 116 && ucPriChannel <= 128) + ucChannelS1 = 122; + else if (ucPriChannel >= 132 && ucPriChannel <= 144) + ucChannelS1 = 138; + else if (ucPriChannel >= 149 && ucPriChannel <= 161) + ucChannelS1 = 155; + else + fgError = TRUE; + break; + + case 40: + ucChannelWidth = (uint8_t) CW_20_40MHZ; + ucSco = (ucExt) ? (uint8_t) CHNL_EXT_SCA : + (uint8_t) CHNL_EXT_SCB; + break; + + case 20: + ucChannelWidth = (uint8_t) CW_20_40MHZ; + ucSco = (uint8_t) CHNL_EXT_SCN; + break; + + default: + fgError = TRUE; + break; + } + + if (fgError) { + i4BytesWritten = + kalSnprintf(pcCommand, i4TotalLen, + "Invalid primary channel %d with bandwidth %d", + ucPriChannel, ucChannelWidth); + return i4BytesWritten; + } + + fgEnable = (ucEnable) ? TRUE : FALSE; + + if (prGlueInfo->fgIsEnableMon != fgEnable) { + prGlueInfo->fgIsEnableMon = fgEnable; + schedule_work(&prGlueInfo->monWork); + } + + kalMemZero(&rMonitorSetInfo, sizeof(rMonitorSetInfo)); + + rMonitorSetInfo.ucEnable = ucEnable; + rMonitorSetInfo.ucPriChannel = ucPriChannel; + rMonitorSetInfo.ucSco = ucSco; + rMonitorSetInfo.ucChannelWidth = ucChannelWidth; + rMonitorSetInfo.ucChannelS1 = ucChannelS1; + rMonitorSetInfo.ucChannelS2 = ucChannelS2; + + rStatus = kalIoctl(prGlueInfo, wlanoidSetMonitor, + &rMonitorSetInfo, sizeof(rMonitorSetInfo), + FALSE, FALSE, TRUE, &u4BufLen); + + i4BytesWritten = + kalSnprintf(pcCommand, i4TotalLen, "set monitor config %s", + (rStatus == WLAN_STATUS_SUCCESS) ? + "success" : "fail"); + + return i4BytesWritten; + } + + i4BytesWritten = kalSnprintf(pcCommand, i4TotalLen, + "monitor [Enable][PriChannel][ChannelWidth][Sco]"); + + return i4BytesWritten; +} +#endif + +int priv_driver_set_bf(IN struct net_device *prNetDev, IN char *pcCommand, + IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint32_t u4Ret, u4Parse = 0; + uint8_t ucBfEnable; + /*UINT_8 ucBssIndex;*/ + /*P_BSS_INFO_T prBssInfo;*/ + + + ASSERT(prNetDev); + + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + + if (i4Argc == 2) { + + u4Ret = kalkStrtou32(apcArgv[1], 0, &u4Parse); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse apcArgv error u4Ret=%d\n", + u4Ret); + + ucBfEnable = (uint8_t) u4Parse; + prGlueInfo->prAdapter->rWifiVar.ucStaHtBfee = ucBfEnable; + prGlueInfo->prAdapter->rWifiVar.ucStaVhtBfee = ucBfEnable; +#if (CFG_SUPPORT_802_11AX == 1) + prGlueInfo->prAdapter->rWifiVar.ucStaHeBfee = ucBfEnable; +#endif /* CFG_SUPPORT_802_11AX == 1 */ + prGlueInfo->prAdapter->rWifiVar.ucStaVhtMuBfee = ucBfEnable; + DBGLOG(REQ, ERROR, "ucBfEnable = %d\n", ucBfEnable); + } else { + DBGLOG(INIT, ERROR, "iwpriv wlanXX driver SET_NSS \n"); + } + + return i4BytesWritten; +} + +int priv_driver_set_nss(IN struct net_device *prNetDev, IN char *pcCommand, + IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint32_t u4Ret, u4Parse = 0; + uint8_t ucNSS; + + ASSERT(prNetDev); + + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + + if (i4Argc == 2) { + u4Ret = kalkStrtou32(apcArgv[1], 0, &u4Parse); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse apcArgv error u4Ret=%d\n", + u4Ret); + + ucNSS = (uint8_t) u4Parse; + prGlueInfo->prAdapter->rWifiVar.ucNSS = ucNSS; + DBGLOG(REQ, LOUD, "ucNSS = %d\n", ucNSS); + } else { + DBGLOG(INIT, ERROR, "iwpriv wlanXX driver SET_NSS \n"); + } + + return i4BytesWritten; +} + + +int priv_driver_set_amsdu_tx(IN struct net_device *prNetDev, IN char *pcCommand, + IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint32_t u4Ret, u4Parse = 0; + uint8_t ucAmsduTx; + + ASSERT(prNetDev); + + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + + if (i4Argc == 2) { + u4Ret = kalkStrtou32(apcArgv[1], 0, &u4Parse); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse apcArgv error u4Ret=%d\n", + u4Ret); + + ucAmsduTx = (uint8_t) u4Parse; + prGlueInfo->prAdapter->rWifiVar.ucAmsduInAmpduTx = ucAmsduTx; + prGlueInfo->prAdapter->rWifiVar.ucHtAmsduInAmpduTx = ucAmsduTx; + prGlueInfo->prAdapter->rWifiVar.ucVhtAmsduInAmpduTx = ucAmsduTx; +#if (CFG_SUPPORT_802_11AX == 1) + prGlueInfo->prAdapter->rWifiVar.ucHeAmsduInAmpduTx = ucAmsduTx; +#endif + DBGLOG(REQ, LOUD, "ucAmsduTx = %d\n", ucAmsduTx); + } else { + DBGLOG(INIT, ERROR, "iwpriv wlanXX driver SET_NSS \n"); + } + + return i4BytesWritten; +} + + +int priv_driver_set_amsdu_rx(IN struct net_device *prNetDev, IN char *pcCommand, + IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint32_t u4Ret, u4Parse = 0; + uint8_t ucAmsduRx; + + ASSERT(prNetDev); + + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + + if (i4Argc == 2) { + u4Ret = kalkStrtou32(apcArgv[1], 0, &u4Parse); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse apcArgv error u4Ret=%d\n", + u4Ret); + + ucAmsduRx = (uint8_t) u4Parse; + prGlueInfo->prAdapter->rWifiVar.ucAmsduInAmpduRx = ucAmsduRx; + prGlueInfo->prAdapter->rWifiVar.ucHtAmsduInAmpduRx = ucAmsduRx; + prGlueInfo->prAdapter->rWifiVar.ucVhtAmsduInAmpduRx = ucAmsduRx; +#if (CFG_SUPPORT_802_11AX == 1) + prGlueInfo->prAdapter->rWifiVar.ucHeAmsduInAmpduRx = ucAmsduRx; +#endif + DBGLOG(REQ, LOUD, "ucAmsduRx = %d\n", ucAmsduRx); + } else { + DBGLOG(INIT, ERROR, "iwpriv wlanXX driver SET_NSS \n"); + } + + return i4BytesWritten; +} + +int priv_driver_set_ampdu_tx(IN struct net_device *prNetDev, IN char *pcCommand, + IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint32_t u4Ret, u4Parse = 0; + uint8_t ucAmpduEnable; + /*UINT_8 ucBssIndex;*/ + /*P_BSS_INFO_T prBssInfo;*/ + + + ASSERT(prNetDev); + + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + + if (i4Argc == 2) { + + u4Ret = kalkStrtou32(apcArgv[1], 0, &u4Parse); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse apcArgv error u4Ret=%d\n", + u4Ret); + + ucAmpduEnable = (uint8_t) u4Parse; + prGlueInfo->prAdapter->rWifiVar.ucAmpduTx = ucAmpduEnable; + DBGLOG(REQ, ERROR, "ucAmpduTx = %d\n", ucAmpduEnable); + } else { + DBGLOG(INIT, ERROR, "iwpriv wlan0 driver SET_AMPDU_TX \n"); + DBGLOG(INIT, ERROR, " 1: enable. 0: disable.\n"); + } + + return i4BytesWritten; +} + +int priv_driver_set_ampdu_rx(IN struct net_device *prNetDev, IN char *pcCommand, + IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint32_t u4Ret, u4Parse = 0; + uint8_t ucAmpduEnable; + /*UINT_8 ucBssIndex;*/ + /*P_BSS_INFO_T prBssInfo;*/ + + + ASSERT(prNetDev); + + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + + if (i4Argc == 2) { + + u4Ret = kalkStrtou32(apcArgv[1], 0, &u4Parse); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse apcArgv error u4Ret=%d\n", + u4Ret); + + ucAmpduEnable = (uint8_t) u4Parse; + prGlueInfo->prAdapter->rWifiVar.ucAmpduRx = ucAmpduEnable; + DBGLOG(REQ, ERROR, "ucAmpduRx = %d\n", + prGlueInfo->prAdapter->rWifiVar.ucAmpduRx); + } else { + DBGLOG(INIT, ERROR, "iwpriv wlan0 driver SET_AMPDU_RX \n"); + DBGLOG(INIT, ERROR, " 1: enable. 0: disable.\n"); + } + + return i4BytesWritten; +} + +int priv_driver_set_qos(IN struct net_device *prNetDev, IN char *pcCommand, + IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint32_t u4Ret, u4Parse = 0; + uint8_t ucQoSEnable; + /*UINT_8 ucBssIndex;*/ + /*P_BSS_INFO_T prBssInfo;*/ + + + ASSERT(prNetDev); + + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + + if (i4Argc == 2) { + + u4Ret = kalkStrtou32(apcArgv[1], 0, &u4Parse); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse apcArgv error u4Ret=%d\n", + u4Ret); + + ucQoSEnable = (uint8_t) u4Parse; + prGlueInfo->prAdapter->rWifiVar.ucQoS = ucQoSEnable; + DBGLOG(REQ, ERROR, "ucQoS = %d\n", + prGlueInfo->prAdapter->rWifiVar.ucQoS); + } else { + DBGLOG(INIT, ERROR, "iwpriv wlanXX driver SET_QOS \n"); + DBGLOG(INIT, ERROR, " 1: enable. 0: disable.\n"); + } + + return i4BytesWritten; +} + +#if (CFG_SUPPORT_802_11AX == 1) +int priv_driver_muedca_override( + IN struct net_device *prNetDev, + IN char *pcCommand, + IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint32_t u4Ret, u4Parse = 0; + uint8_t ucMuEdcaOverride; + + ASSERT(prNetDev); + + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + + if (i4Argc == 2) { + u4Ret = kalkStrtou32(apcArgv[1], 0, &u4Parse); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse apcArgv error u4Ret=%d\n", + u4Ret); + + ucMuEdcaOverride = (uint8_t) u4Parse; +#if (CFG_SUPPORT_802_11AX == 1) + prGlueInfo->prAdapter->fgMuEdcaOverride = ucMuEdcaOverride; +#endif + DBGLOG(REQ, LOUD, "ucMuEdcaOverride = %d\n", ucMuEdcaOverride); + } else { + DBGLOG(INIT, ERROR, + "iwpriv wlanXX driver MUEDCA_OVERRIDE \n"); + } + + return i4BytesWritten; +} + +int priv_driver_set_mcsmap(IN struct net_device *prNetDev, IN char *pcCommand, + IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint32_t u4Ret, u4Parse = 0; + uint8_t ucTxMcsMap; + struct ADAPTER *prAdapter = NULL; + /*UINT_8 ucBssIndex;*/ + /*P_BSS_INFO_T prBssInfo;*/ + + + ASSERT(prNetDev); + + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + + if (i4Argc == 2) { + + u4Ret = kalkStrtou32(apcArgv[1], 0, &u4Parse); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse apcArgv error u4Ret=%d\n", + u4Ret); + + ucTxMcsMap = (uint8_t) u4Parse; +#if (CFG_SUPPORT_802_11AX == 1) + if (ucTxMcsMap >= 0 && ucTxMcsMap <= 2) { + prAdapter = prGlueInfo->prAdapter; + prAdapter->ucMcsMapSetFromSigma = ucTxMcsMap; + + DBGLOG(REQ, ERROR, "ucMcsMapSetFromSigma = %d\n", + prGlueInfo->prAdapter->ucMcsMapSetFromSigma); + + prGlueInfo->prAdapter->fgMcsMapBeenSet = TRUE; + } else { + prGlueInfo->prAdapter->fgMcsMapBeenSet = FALSE; + } +#endif + } else { + DBGLOG(INIT, ERROR, "iwpriv wlan0 driver SET_TX_MCSMAP \n"); + DBGLOG(INIT, ERROR, " 1: enable. 0: disable.\n"); + } + + return i4BytesWritten; +} + +int priv_driver_set_ba_size(IN struct net_device *prNetDev, IN char *pcCommand, + IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint32_t u4Ret, u4Parse = 0; + uint16_t u2HeBaSize; + /*UINT_8 ucBssIndex;*/ + /*P_BSS_INFO_T prBssInfo;*/ + + + ASSERT(prNetDev); + + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + + if (i4Argc == 2) { + + u4Ret = kalkStrtou32(apcArgv[1], 0, &u4Parse); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse apcArgv error u4Ret=%d\n", + u4Ret); + + u2HeBaSize = (uint16_t) u4Parse; + + prGlueInfo->prAdapter->rWifiVar.u2TxHeBaSize = u2HeBaSize; + prGlueInfo->prAdapter->rWifiVar.u2RxHeBaSize = u2HeBaSize; + } else { + DBGLOG(INIT, ERROR, "iwpriv wlanXX driver SET_BA_SIZE\n"); + DBGLOG(INIT, ERROR, " 1: enable. 0: disable.\n"); + } + + return i4BytesWritten; +} + +/* This command is for sigma to disable TpTestMode. */ +int priv_driver_set_tp_test_mode(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint32_t u4Ret, u4Parse = 0; + uint8_t ucTpTestMode; + /*UINT_8 ucBssIndex;*/ + /*P_BSS_INFO_T prBssInfo;*/ + + + ASSERT(prNetDev); + + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + + if (i4Argc == 2) { + + u4Ret = kalkStrtou32(apcArgv[1], 0, &u4Parse); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse apcArgv error u4Ret=%d\n", + u4Ret); + + ucTpTestMode = (uint8_t) u4Parse; + + prGlueInfo->prAdapter->rWifiVar.ucTpTestMode = ucTpTestMode; + } else { + DBGLOG(INIT, ERROR, "iwpriv wlanXX driver SET_TP_TEST_MODE\n"); + DBGLOG(INIT, ERROR, " 1: enable. 0: disable.\n"); + } + + return i4BytesWritten; +} + +/* This command is for sigma to disable TxPPDU. */ +int priv_driver_set_tx_ppdu(IN struct net_device *prNetDev, IN char *pcCommand, + IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint32_t u4Ret, u4Parse = 0; + struct ADAPTER *prAdapter = NULL; + struct STA_RECORD *prStaRec; + + ASSERT(prNetDev); + + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + prStaRec = cnmGetStaRecByIndex(prAdapter, 0); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + + if (i4Argc == 2) { + + u4Ret = kalkStrtou32(apcArgv[1], 0, &u4Parse); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse apcArgv error u4Ret=%d\n", + u4Ret); + + if (u4Parse) { + /* HE_SU is allowed. */ + prAdapter->fgTxPPDU = TRUE; + NIC_TX_PPDU_ENABLE(prAdapter); + } else { + /* HE_SU is not allowed. */ + prAdapter->fgTxPPDU = FALSE; + if (prStaRec && prStaRec->fgIsTxAllowed) + NIC_TX_PPDU_DISABLE(prAdapter); + } + + DBGLOG(REQ, STATE, "fgTxPPDU is %d\n", prAdapter->fgTxPPDU); + } else { + DBGLOG(INIT, ERROR, "iwpriv wlanXX driver TX_PPDU\n"); + DBGLOG(INIT, ERROR, " 1: enable. 0: disable.\n"); + } + + return i4BytesWritten; +} + +/* This command is for sigma to disable LDPC capability. */ +int priv_driver_set_ldpc(IN struct net_device *prNetDev, IN char *pcCommand, + IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint32_t u4Ret, u4Parse = 0; + struct ADAPTER *prAdapter = NULL; + + ASSERT(prNetDev); + + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + + if (i4Argc == 2) { + u4Ret = kalkStrtou32(apcArgv[1], 0, &u4Parse); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse apcArgv error u4Ret=%d\n", + u4Ret); + if (u4Parse) { + /* LDPC is enabled. */ + prAdapter->rWifiVar.ucTxLdpc = TRUE; + prAdapter->rWifiVar.ucRxLdpc = TRUE; + } else { + /* LDPC is disabled. */ + prAdapter->rWifiVar.ucTxLdpc = FALSE; + prAdapter->rWifiVar.ucRxLdpc = FALSE; + } + + DBGLOG(REQ, STATE, "prAdapter->rWifiVar.ucTxLdpc is %d\n", + prAdapter->rWifiVar.ucTxLdpc); + DBGLOG(REQ, STATE, "prAdapter->rWifiVar.ucRxLdpc is %d\n", + prAdapter->rWifiVar.ucRxLdpc); + } else { + DBGLOG(INIT, ERROR, "iwpriv wlanXX driver TX_PPDU\n"); + DBGLOG(INIT, ERROR, " 1: enable. 0: disable.\n"); + } + + return i4BytesWritten; +} + +/* This command is for sigma to force tx amsdu. */ +int priv_driver_set_tx_force_amsdu(IN struct net_device *prNetDev, + IN char *pcCommand, + IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint32_t u4Ret, u4Parse = 0; + struct ADAPTER *prAdapter = NULL; + + ASSERT(prNetDev); + + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + + if (i4Argc == 2) { + u4Ret = kalkStrtou32(apcArgv[1], 0, &u4Parse); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse apcArgv error u4Ret=%d\n", + u4Ret); + if (u4Parse) { + /* forceAmsdu is enabled. */ + prAdapter->rWifiVar.ucHeCertForceAmsdu = TRUE; + } else { + /* forceAmsdu is disabled. */ + prAdapter->rWifiVar.ucHeCertForceAmsdu = FALSE; + } + + DBGLOG(REQ, STATE, + "prAdapter->rWifiVar.ucHeCertForceAmsdu is %d\n", + prAdapter->rWifiVar.ucHeCertForceAmsdu); + } else { + DBGLOG(INIT, ERROR, "iwpriv wlanXX driver FORCE_AMSDU_TX %d\n"); + DBGLOG(INIT, ERROR, " 1: enable. 0: disable.\n"); + } + + return i4BytesWritten; +} + + + + +/* This command is for sigma to change OM CH BW. */ +int priv_driver_set_om_ch_bw(IN struct net_device *prNetDev, IN char *pcCommand, + IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint32_t u4Ret, u4Parse = 0; + struct ADAPTER *prAdapter = NULL; + + ASSERT(prNetDev); + + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + + if (i4Argc == 2) { + + u4Ret = kalkStrtou32(apcArgv[1], 0, &u4Parse); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse apcArgv error u4Ret=%d\n", + u4Ret); + + DBGLOG(REQ, STATE, + "priv_driver_set_om_ch_bw:: ch bw = %d\n", u4Parse); + if (u4Parse <= CH_BW_160) + HE_SET_HTC_HE_OM_CH_WIDTH( + prAdapter->u4HeHtcOM, u4Parse); + } else { + DBGLOG(INIT, ERROR, + "iwpriv wlanXX driver TX_ACTION \n"); + DBGLOG(INIT, ERROR, " action frame count.\n"); + } + + return i4BytesWritten; +} + +/* This command is for sigma to change OM RX NSS. */ +int priv_driver_set_om_rx_nss( + IN struct net_device *prNetDev, + IN char *pcCommand, + IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint32_t u4Ret, u4Parse = 0; + struct ADAPTER *prAdapter = NULL; + + ASSERT(prNetDev); + + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + + if (i4Argc == 2) { + u4Ret = kalkStrtou32(apcArgv[1], 0, &u4Parse); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse apcArgv error u4Ret=%d\n", + u4Ret); + + DBGLOG(REQ, STATE, + "priv_driver_set_om_rx_nss:: rx nss = %d\n", u4Parse); + HE_SET_HTC_HE_OM_RX_NSS(prAdapter->u4HeHtcOM, u4Parse); + } else { + DBGLOG(INIT, ERROR, + "iwpriv wlanXX driver TX_ACTION \n"); + DBGLOG(INIT, ERROR, " action frame count.\n"); + } + + return i4BytesWritten; +} + +int priv_driver_set_om_tx_nss( + IN struct net_device *prNetDev, + IN char *pcCommand, + IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint32_t u4Ret, u4Parse = 0; + struct ADAPTER *prAdapter = NULL; + + ASSERT(prNetDev); + + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + + if (i4Argc == 2) { + u4Ret = kalkStrtou32(apcArgv[1], 0, &u4Parse); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse apcArgv error u4Ret=%d\n", + u4Ret); + + DBGLOG(REQ, STATE, + "priv_driver_set_om_tx_nss:: tx nss = %d\n", u4Parse); + HE_SET_HTC_HE_OM_TX_NSTS(prAdapter->u4HeHtcOM, u4Parse); + } else { + DBGLOG(INIT, ERROR, + "iwpriv wlanXX driver SET_OM_TXNSTS \n"); + DBGLOG(INIT, ERROR, " action frame count.\n"); + } + + return i4BytesWritten; +} + +int priv_driver_set_om_mu_dis( + IN struct net_device *prNetDev, + IN char *pcCommand, + IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint32_t u4Ret, u4Parse = 0; + struct ADAPTER *prAdapter = NULL; + + ASSERT(prNetDev); + + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + + if (i4Argc == 2) { + u4Ret = kalkStrtou32(apcArgv[1], 0, &u4Parse); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse apcArgv error u4Ret=%d\n", + u4Ret); + + DBGLOG(REQ, STATE, + "priv_driver_set_om_mu_dis:: disable = %d\n", u4Parse); + HE_SET_HTC_HE_OM_UL_MU_DISABLE(prAdapter->u4HeHtcOM, u4Parse); + } else { + DBGLOG(INIT, ERROR, + "iwpriv wlanXX driver SET_OM_MU_DISABLE \n"); + DBGLOG(INIT, ERROR, " action frame count.\n"); + } + + return i4BytesWritten; +} + +int priv_driver_set_tx_om_packet( + IN struct net_device *prNetDev, + IN char *pcCommand, + IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint32_t u4Ret, u4Parse = 0; + struct ADAPTER *prAdapter = NULL; + int32_t index; + struct STA_RECORD *prStaRec = NULL; + + ASSERT(prNetDev); + + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + + if (i4Argc == 2) { + + u4Ret = kalkStrtou32(apcArgv[1], 0, &u4Parse); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse apcArgv error u4Ret=%d\n", + u4Ret); + + DBGLOG(REQ, STATE, + "tx om packet:: Send %d htc null frame\n", + u4Parse); + if (u4Parse) { + prStaRec = cnmGetStaRecByIndex(prAdapter, 0); + if (prStaRec != NULL) { + for (index = 0; index < u4Parse; index++) + heRlmSendHtcNullFrame(prAdapter, + prStaRec, 7, NULL); + } + } + } else { + DBGLOG(INIT, ERROR, + "iwpriv wlanXX driver TX_ACTION \n"); + DBGLOG(INIT, ERROR, " action frame count.\n"); + } + + return i4BytesWritten; +} + +int priv_driver_set_tx_cck_1m_pwr( + IN struct net_device *prNetDev, + IN char *pcCommand, + IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint32_t u4Ret, u4Parse = 0; + struct ADAPTER *prAdapter = NULL; + uint8_t pwr; + + ASSERT(prNetDev); + + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + + if (i4Argc == 2) { + + u4Ret = kalkStrtou32(apcArgv[1], 0, &u4Parse); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse apcArgv error u4Ret=%d\n", + u4Ret); + + DBGLOG(REQ, STATE, + "priv_driver_set_tx_cck_1m_pwr:: set cck pwr %d\n", + u4Parse); + + if (u4Parse) { + pwr = u4Parse; + + wlanSendSetQueryCmd(prAdapter, + CMD_ID_SET_CCK_1M_PWR, + TRUE, + FALSE, + FALSE, + NULL, + NULL, + sizeof(uint8_t), + (uint8_t *)&pwr, NULL, 0); + } + } else { + DBGLOG(INIT, ERROR, + "iwpriv wlanXX driver TX_CCK_1M_PWR \n"); + DBGLOG(INIT, ERROR, " power of CCK 1M.\n"); + } + + return i4BytesWritten; +} + +#endif /* CFG_SUPPORT_802_11AX == 1 */ + + +static int priv_driver_get_sta_index(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter; + int32_t i4BytesWritten = 0, i4Argc = 0; + uint8_t ucStaIdx, ucWlanIndex = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint8_t aucMacAddr[MAC_ADDR_LEN]; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + if (i4Argc >= 2) { + wlanHwAddrToBin(apcArgv[1], &aucMacAddr[0]); + + if (!wlanGetWlanIdxByAddress(prGlueInfo->prAdapter, + &aucMacAddr[0], &ucWlanIndex)) + return i4BytesWritten; + + if (wlanGetStaIdxByWlanIdx(prAdapter, ucWlanIndex, &ucStaIdx) + != WLAN_STATUS_SUCCESS) + return i4BytesWritten; + + i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "StaIdx = %d, WlanIdx = %d\n", ucStaIdx, + ucWlanIndex); + } + + return i4BytesWritten; +} + +static int priv_driver_get_version(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter; + int32_t i4BytesWritten = 0; + uint32_t u4Offset = 0; + + ASSERT(prNetDev); + + prGlueInfo = *((struct GLUE_INFO **)netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + u4Offset += fwDlGetFwdlInfo(prAdapter, pcCommand, i4TotalLen); + u4Offset += kalSnprintf(pcCommand + u4Offset, i4TotalLen - u4Offset, + "WiFi Driver Version %u.%u.%u\n", + NIC_DRIVER_MAJOR_VERSION, + NIC_DRIVER_MINOR_VERSION, + NIC_DRIVER_SERIAL_VERSION); + + i4BytesWritten = (int32_t)u4Offset; + + return i4BytesWritten; +} + +#if CFG_CHIP_RESET_HANG +static int priv_driver_set_rst_hang(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint32_t u4Ret; + + + ASSERT(prNetDev); + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + if (i4Argc == 0) { + DBGLOG(REQ, INFO, "set_rst_hang Argc = %d\n", i4Argc); + return -EFAULT; + } + + if (strnicmp(apcArgv[0], CMD_SET_RST_HANG, + strlen(CMD_SET_RST_HANG)) == 0) { + if (i4Argc < CMD_SET_RST_HANG_ARG_NUM) { + DBGLOG(REQ, STATE, + "[SER][L0] RST_HANG_SET arg num=%d,must be %d\n", + i4Argc, CMD_SET_RST_HANG_ARG_NUM); + return -EFAULT; + } + u4Ret = kalkStrtou8(apcArgv[1], 0, &fgIsResetHangState); + if (u4Ret) + DBGLOG(REQ, ERROR, "u4Ret=%d\n", u4Ret); + + DBGLOG(REQ, STATE, "[SER][L0] set fgIsResetHangState=%d\n", + fgIsResetHangState); + + if (fgIsResetHangState == SER_L0_HANG_RST_CMD_TRG) { + DBGLOG(REQ, STATE, "[SER][L0] cmd trigger\n"); + glSetRstReason(RST_CMD_TRIGGER); + GL_RESET_TRIGGER(NULL, RST_FLAG_CHIP_RESET); + } + + } else { + DBGLOG(REQ, STATE, "[SER][L0] get fgIsResetSqcState=%d\n", + fgIsResetHangState); + DBGLOG(REQ, ERROR, "[SER][L0] RST HANG subcmd(%s) error !\n", + apcArgv[0]); + + return -EFAULT; + } + + return 0; + +} +#endif + +#if CFG_SUPPORT_DBDC +int priv_driver_set_dbdc(IN struct net_device *prNetDev, IN char *pcCommand, + IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint32_t u4Ret, u4Parse = 0; + uint8_t ucDBDCEnable; + /*UINT_8 ucBssIndex;*/ + /*P_BSS_INFO_T prBssInfo;*/ + + + ASSERT(prNetDev); + + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); +#if 0 + for (ucBssIndex = 0; ucBssIndex < (prAdapter->ucHwBssIdNum + 1); + ucBssIndex++) { + prBssInfo = prGlueInfo->prAdapter->aprBssInfo[ucBssIndex]; + pr_info("****BSS %u inUse %u active %u Mode %u priCh %u state %u rfBand %u\n", + ucBssIndex, + prBssInfo->fgIsInUse, + prBssInfo->fgIsNetActive, + prBssInfo->eCurrentOPMode, + prBssInfo->ucPrimaryChannel, + prBssInfo->eConnectionState, + prBssInfo->eBand); + } +#endif + if (prGlueInfo->prAdapter->rWifiVar.eDbdcMode != + ENUM_DBDC_MODE_DYNAMIC) { + DBGLOG(REQ, LOUD, + "Current DBDC mode %u cannot enable/disable DBDC!!\n", + prGlueInfo->prAdapter->rWifiVar.eDbdcMode); + return -1; + } + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + + if (i4Argc == 2) { + + u4Ret = kalkStrtou32(apcArgv[1], 0, &u4Parse); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse apcArgv error u4Ret=%d\n", + u4Ret); + + ucDBDCEnable = (uint8_t) u4Parse; + if ((!prGlueInfo->prAdapter->rWifiVar.fgDbDcModeEn && + !ucDBDCEnable) || + (prGlueInfo->prAdapter->rWifiVar.fgDbDcModeEn && + ucDBDCEnable)) + return i4BytesWritten; + + rStatus = kalIoctl(prGlueInfo, wlanoidSetDbdcEnable, + &ucDBDCEnable, 1, FALSE, FALSE, TRUE, + &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) + return -1; + + } else { + DBGLOG(INIT, ERROR, "iwpriv wlanXX driver SET_DBDC \n"); + DBGLOG(INIT, ERROR, " 1: enable. 0: disable.\n"); + } + + return i4BytesWritten; +} + +int priv_driver_set_sta1ss(IN struct net_device *prNetDev, IN char *pcCommand, + IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint32_t u4Ret, u4Parse = 0; + + ASSERT(prNetDev); + + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + + if (i4Argc == 2) { + u4Ret = kalkStrtou32(apcArgv[1], 0, &u4Parse); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse apcArgv error u4Ret=%d\n", + u4Ret); + + prGlueInfo->prAdapter->rWifiVar.fgSta1NSS = + (uint8_t) u4Parse; + + } else { + DBGLOG(INIT, ERROR, + "iwpriv wlanXX driver SET_STA1NSS \n"); + DBGLOG(INIT, ERROR, + " 1: enable. 0: disable.\n"); + } + + return i4BytesWritten; +} + +#endif /*CFG_SUPPORT_DBDC*/ + +#if CFG_SUPPORT_BATCH_SCAN +#define CMD_BATCH_SET "WLS_BATCHING SET" +#define CMD_BATCH_GET "WLS_BATCHING GET" +#define CMD_BATCH_STOP "WLS_BATCHING STOP" +#endif + +static int priv_driver_get_que_info(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + ASSERT(prNetDev); + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + return qmDumpQueueStatus(prGlueInfo->prAdapter, pcCommand, i4TotalLen); +} + +static int priv_driver_get_mem_info(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + ASSERT(prNetDev); + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + return cnmDumpMemoryStatus(prGlueInfo->prAdapter, pcCommand, + i4TotalLen); +} + +static int priv_driver_get_hif_info(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + ASSERT(prNetDev); + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + return halDumpHifStatus(prGlueInfo->prAdapter, pcCommand, i4TotalLen); +} + +static int priv_driver_get_capab_rsdb(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4BytesWritten = 0; + uint32_t u4Offset = 0; + u_int8_t fgDbDcModeEn = FALSE; + + prGlueInfo = wlanGetGlueInfo(); + if (!prGlueInfo) { + DBGLOG(REQ, WARN, "prGlueInfo is NULL\n"); + return -EFAULT; + } + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + +#if CFG_SUPPORT_DBDC + if (prGlueInfo->prAdapter->rWifiVar.eDbdcMode != + ENUM_DBDC_MODE_DISABLED) + fgDbDcModeEn = TRUE; + + if (prGlueInfo->prAdapter->rWifiFemCfg.u2WifiPath == + (WLAN_FLAG_2G4_WF0 | WLAN_FLAG_5G_WF1)) + fgDbDcModeEn = FALSE; +#endif + + DBGLOG(REQ, INFO, "RSDB:%d\n", fgDbDcModeEn); + + u4Offset += kalScnprintf(pcCommand + u4Offset, i4TotalLen - u4Offset, + "RSDB:%d", + fgDbDcModeEn); + + i4BytesWritten = (int32_t)u4Offset; + + return i4BytesWritten; + +} + +static int priv_driver_get_cnm(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + struct PARAM_GET_CNM_T *prCnmInfo = NULL; + + enum ENUM_DBDC_BN eDbdcIdx, eDbdcIdxMax; + uint8_t ucBssIdx; + struct BSS_INFO *prBssInfo; + enum ENUM_CNM_NETWORK_TYPE_T eNetworkType; + uint8_t ucOpRxNss, ucOpTxNss; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + + prCnmInfo = (struct PARAM_GET_CNM_T *)kalMemAlloc( + sizeof(struct PARAM_GET_CNM_T), VIR_MEM_TYPE); + if (prCnmInfo == NULL) + return -1; + + kalMemZero(prCnmInfo, sizeof(struct PARAM_GET_CNM_T)); + + rStatus = kalIoctl(prGlueInfo, wlanoidQueryCnm, prCnmInfo, + sizeof(struct PARAM_GET_CNM_T), + TRUE, TRUE, TRUE, &u4BufLen); + + DBGLOG(REQ, INFO, "%s: command result is %s\n", __func__, pcCommand); + if (rStatus != WLAN_STATUS_SUCCESS) { + kalMemFree(prCnmInfo, + VIR_MEM_TYPE, sizeof(struct PARAM_GET_CNM_T)); + return -1; + } + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "\n[CNM Info]\n"); + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "DBDC Mode : %s\n\n", + (prCnmInfo->fgIsDbdcEnable) ? + "Enable" : "Disable"); + + eDbdcIdxMax = (prCnmInfo->fgIsDbdcEnable)?ENUM_BAND_NUM:ENUM_BAND_1; + for (eDbdcIdx = ENUM_BAND_0; eDbdcIdx < eDbdcIdxMax; eDbdcIdx++) { + /* Do not clean history information */ + /* if argc is bigger than 1 */ + if (i4Argc < 2) { + if (prCnmInfo->ucOpChNum[eDbdcIdx] < 3) + prCnmInfo->ucChList[eDbdcIdx][2] = 0; + if (prCnmInfo->ucOpChNum[eDbdcIdx] < 2) + prCnmInfo->ucChList[eDbdcIdx][1] = 0; + if (prCnmInfo->ucOpChNum[eDbdcIdx] < 1) + prCnmInfo->ucChList[eDbdcIdx][0] = 0; + } + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "Band %u OPCH %d [%u, %u, %u]\n", + eDbdcIdx, + prCnmInfo->ucOpChNum[eDbdcIdx], + prCnmInfo->ucChList[eDbdcIdx][0], + prCnmInfo->ucChList[eDbdcIdx][1], + prCnmInfo->ucChList[eDbdcIdx][2]); + } + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "\n"); + + for (ucBssIdx = BSSID_0; ucBssIdx < (BSSID_NUM+1); ucBssIdx++) { + + prBssInfo = prGlueInfo->prAdapter->aprBssInfo[ucBssIdx]; + if (!prBssInfo) + continue; + + eNetworkType = cnmGetBssNetworkType(prBssInfo); + if (prCnmInfo->ucBssInuse[ucBssIdx] && + prCnmInfo->ucBssActive[ucBssIdx] && + ((eNetworkType == ENUM_CNM_NETWORK_TYPE_P2P_GO) || + ((eNetworkType == ENUM_CNM_NETWORK_TYPE_AIS || + eNetworkType == ENUM_CNM_NETWORK_TYPE_P2P_GC) && + (prCnmInfo->ucBssConnectState[ucBssIdx] == + MEDIA_STATE_CONNECTED)))) { + ucOpRxNss = prBssInfo->ucOpRxNss; + if (eNetworkType == ENUM_CNM_NETWORK_TYPE_P2P_GO) { + struct STA_RECORD *prCurrStaRec = + (struct STA_RECORD *) NULL; + + prCurrStaRec = LINK_PEEK_HEAD( + &prBssInfo->rStaRecOfClientList, + struct STA_RECORD, rLinkEntry); + + if (prCurrStaRec != NULL && + IS_CONNECTION_NSS2(prBssInfo, + prCurrStaRec)) { + ucOpTxNss = 2; + } else + ucOpTxNss = 1; + + ucOpRxNss = prBssInfo->ucOpRxNss; + } else if (prBssInfo->prStaRecOfAP != NULL && + IS_CONNECTION_NSS2(prBssInfo, + prBssInfo->prStaRecOfAP)) { + ucOpTxNss = 2; + } else + ucOpTxNss = 1; + } else { + eNetworkType = ENUM_CNM_NETWORK_TYPE_OTHER; + ucOpTxNss = prBssInfo->ucOpTxNss; + ucOpRxNss = prBssInfo->ucOpRxNss; + /* Do not show history information */ + /* if argc is 1 */ + if (i4Argc < 2) + continue; + } + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "BSS%u Inuse%u Act%u ConnStat%u [NetType%u][CH%3u][DBDC b%u][WMM%u b%u][OMAC%u b%u][BW%3u][TxNSS%u][RxNss%u]\n", + ucBssIdx, + prCnmInfo->ucBssInuse[ucBssIdx], + prCnmInfo->ucBssActive[ucBssIdx], + prCnmInfo->ucBssConnectState[ucBssIdx], + eNetworkType, + prCnmInfo->ucBssCh[ucBssIdx], + prCnmInfo->ucBssDBDCBand[ucBssIdx], + prCnmInfo->ucBssWmmSet[ucBssIdx], + prCnmInfo->ucBssWmmDBDCBand[ucBssIdx], + prCnmInfo->ucBssOMACSet[ucBssIdx], + prCnmInfo->ucBssOMACDBDCBand[ucBssIdx], + 20 * (0x01 << rlmGetBssOpBwByVhtAndHtOpInfo(prBssInfo)), + ucOpTxNss, + ucOpRxNss); +#ifdef CONFIG_SUPPORT_OPENWRT + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "BW=BW%u\n", + 20 * (0x01 << rlmGetBssOpBwByVhtAndHtOpInfo(prBssInfo)) + ); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "[TxNSS%u][RxNss%u]\n", + ucOpTxNss, ucOpRxNss); + +#if (CFG_SUPPORT_802_11AX == 1) + { + + struct STA_RECORD *prStaRec; + + prStaRec = cnmGetStaRecByAddress(prGlueInfo->prAdapter, + ucBssIdx, prBssInfo->aucBSSID); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "Mcs1=%u\n", + (prStaRec->u2HeRxMcsMapBW80) & 0x3); + + i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, "Mcs2=%u\n", + ((prStaRec->u2HeRxMcsMapBW80) >> 2) & 0x3); + } +#endif /* CFG_SUPPORT_802_11AX */ +#endif + + } + + kalMemFree(prCnmInfo, VIR_MEM_TYPE, sizeof(struct PARAM_GET_CNM_T)); + return i4BytesWritten; +} /* priv_driver_get_sw_ctrl */ + +static int priv_driver_get_ch_rank_list(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t i4BytesWritten = 0; + int8_t ucIdx = 0, ucIdx2 = 0, ucChannelNum = 0, + ucNumOf2gChannel = 0, ucNumOf5gChannel = 0; + struct PARAM_GET_CHN_INFO *prChnLoadInfo = NULL; + struct RF_CHANNEL_INFO *prChannelList = NULL, + auc2gChannelList[MAX_2G_BAND_CHN_NUM], + auc5gChannelList[MAX_5G_BAND_CHN_NUM]; + + ASSERT(prNetDev); + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prChnLoadInfo = &(prGlueInfo->prAdapter->rWifiVar.rChnLoadInfo); + kalMemZero(pcCommand, i4TotalLen); + + rlmDomainGetChnlList(prGlueInfo->prAdapter, BAND_2G4, TRUE, + MAX_2G_BAND_CHN_NUM, &ucNumOf2gChannel, + auc2gChannelList); + rlmDomainGetChnlList(prGlueInfo->prAdapter, BAND_5G, TRUE, + MAX_5G_BAND_CHN_NUM, &ucNumOf5gChannel, + auc5gChannelList); + + for (ucIdx = 0; ucIdx < MAX_CHN_NUM; ucIdx++) { + + if (prChnLoadInfo->rChnRankList[ucIdx].ucChannel > 14) { + prChannelList = auc5gChannelList; + ucChannelNum = ucNumOf5gChannel; + } else { + prChannelList = auc2gChannelList; + ucChannelNum = ucNumOf2gChannel; + } + + for (ucIdx2 = 0; ucIdx2 < ucChannelNum; ucIdx2++) { + if (prChnLoadInfo->rChnRankList[ucIdx].ucChannel == + prChannelList[ucIdx2].ucChannelNum) { + pcCommand[i4BytesWritten++] = + prChnLoadInfo->rChnRankList[ucIdx] + .ucChannel; + DBGLOG(SCN, TRACE, "ch %u, dirtiness %d\n", + prChnLoadInfo->rChnRankList[ucIdx] + .ucChannel, + prChnLoadInfo->rChnRankList[ucIdx] + .u4Dirtiness); + break; + } + } + } + + return i4BytesWritten; +} + +static int priv_driver_get_ch_dirtiness(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int8_t cIdx = 0; + uint8_t ucNumOf2gChannel = 0; + uint8_t ucNumOf5gChannel = 0; + uint32_t i4BytesWritten = 0; + struct PARAM_GET_CHN_INFO *prChnLoadInfo = NULL; + struct RF_CHANNEL_INFO ar2gChannelList[MAX_2G_BAND_CHN_NUM]; + struct RF_CHANNEL_INFO ar5gChannelList[MAX_5G_BAND_CHN_NUM]; + + ASSERT(prNetDev); + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prChnLoadInfo = &(prGlueInfo->prAdapter->rWifiVar.rChnLoadInfo); + kalMemZero(pcCommand, i4TotalLen); + + rlmDomainGetChnlList(prGlueInfo->prAdapter, BAND_2G4, TRUE, + MAX_2G_BAND_CHN_NUM, &ucNumOf2gChannel, + ar2gChannelList); + rlmDomainGetChnlList(prGlueInfo->prAdapter, BAND_5G, TRUE, + MAX_5G_BAND_CHN_NUM, &ucNumOf5gChannel, + ar5gChannelList); + + for (cIdx = 0; cIdx < MAX_CHN_NUM; cIdx++) { + int8_t cIdx2 = 0; + uint8_t ucChannelNum = 0; + uint32_t u4Offset = 0; + struct RF_CHANNEL_INFO *prChannelList = NULL; + + if (prChnLoadInfo->rChnRankList[cIdx].ucChannel > 14) { + prChannelList = ar5gChannelList; + ucChannelNum = ucNumOf5gChannel; + } else { + prChannelList = ar2gChannelList; + ucChannelNum = ucNumOf2gChannel; + } + + for (cIdx2 = 0; cIdx2 < ucChannelNum; cIdx2++) { + if (prChnLoadInfo->rChnRankList[cIdx].ucChannel == + prChannelList[cIdx2].ucChannelNum) { + u4Offset = kalSprintf( + pcCommand + i4BytesWritten, + "\nch %03u -> dirtiness %u", + prChnLoadInfo->rChnRankList[cIdx] + .ucChannel, + prChnLoadInfo->rChnRankList[cIdx] + .u4Dirtiness); + i4BytesWritten += u4Offset; + break; + } + } + } + + return i4BytesWritten; +} + +static int priv_driver_efuse_ops(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + enum EFUSE_OP_MODE { + EFUSE_READ, + EFUSE_WRITE, + EFUSE_FREE, + EFUSE_INVALID, + }; + uint8_t ucOpMode = EFUSE_INVALID; + uint8_t ucOpChar; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint32_t u4Ret; + int32_t i4Parameter = 0; + uint32_t u4Efuse_addr = 0; + uint8_t ucEfuse_value = 0; + +#if (CFG_EEPROM_PAGE_ACCESS == 1) + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4Offset = 0; + uint32_t u4BufLen = 0; + uint8_t u4Index = 0; + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_CUSTOM_ACCESS_EFUSE rAccessEfuseInfo; +#endif + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + + /* Sanity check */ + if (i4Argc < 2) + goto efuse_op_invalid; + + ucOpChar = (uint8_t)apcArgv[1][0]; + if ((i4Argc == 3) && (ucOpChar == 'r' || ucOpChar == 'R')) + ucOpMode = EFUSE_READ; + else if ((i4Argc == 4) && (ucOpChar == 'w' || ucOpChar == 'W')) + ucOpMode = EFUSE_WRITE; + else if ((ucOpChar == 'f' || ucOpChar == 'F')) + ucOpMode = EFUSE_FREE; + + /* Print out help if input format is wrong */ + if (ucOpMode == EFUSE_INVALID) + goto efuse_op_invalid; + + /* convert address */ + if (ucOpMode == EFUSE_READ || ucOpMode == EFUSE_WRITE) { + u4Ret = kalkStrtos32(apcArgv[2], 16, &i4Parameter); + u4Efuse_addr = (uint32_t)i4Parameter; + } + + /* convert value */ + if (ucOpMode == EFUSE_WRITE) { + u4Ret = kalkStrtos32(apcArgv[3], 16, &i4Parameter); + ucEfuse_value = (uint8_t)i4Parameter; + } + + /* Start operation */ +#if (CFG_EEPROM_PAGE_ACCESS == 1) + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + if (prGlueInfo == NULL) { + DBGLOG(REQ, ERROR, "prGlueInfo is null\n"); + goto efuse_op_invalid; + } + + if (prGlueInfo && + prGlueInfo->prAdapter && + prGlueInfo->prAdapter->chip_info && + !prGlueInfo->prAdapter->chip_info->is_support_efuse) { + u4Offset += kalSnprintf(pcCommand + u4Offset, + i4TotalLen - u4Offset, + "efuse ops is invalid\n"); + return (int32_t)u4Offset; + } + + kalMemSet(&rAccessEfuseInfo, 0, + sizeof(struct PARAM_CUSTOM_ACCESS_EFUSE)); + rAccessEfuseInfo.u4Address = (u4Efuse_addr / EFUSE_BLOCK_SIZE) + * EFUSE_BLOCK_SIZE; + + u4Index = u4Efuse_addr % EFUSE_BLOCK_SIZE; + + if (ucOpMode == EFUSE_READ) { + rStatus = kalIoctl(prGlueInfo, + wlanoidQueryProcessAccessEfuseRead, + &rAccessEfuseInfo, + sizeof(struct PARAM_CUSTOM_ACCESS_EFUSE), + TRUE, TRUE, TRUE, &u4BufLen); + + if (rStatus == WLAN_STATUS_SUCCESS) { + u4Offset += kalSnprintf(pcCommand + u4Offset, + i4TotalLen - u4Offset, + "Read success 0x%X = 0x%X\n", u4Efuse_addr, + prGlueInfo->prAdapter->aucEepromVaule[u4Index]); + } + } else if (ucOpMode == EFUSE_WRITE) { + + prGlueInfo->prAdapter->aucEepromVaule[u4Index] = ucEfuse_value; + + kalMemCopy(rAccessEfuseInfo.aucData, + prGlueInfo->prAdapter->aucEepromVaule, 16); + + rStatus = kalIoctl(prGlueInfo, + wlanoidQueryProcessAccessEfuseWrite, + &rAccessEfuseInfo, + sizeof(struct PARAM_CUSTOM_ACCESS_EFUSE), + FALSE, FALSE, TRUE, &u4BufLen); + if (rStatus == WLAN_STATUS_SUCCESS) { + u4Offset += kalSnprintf(pcCommand + u4Offset, + i4TotalLen - u4Offset, + "Write success 0x%X = 0x%X\n", + u4Efuse_addr, ucEfuse_value); + } + } else if (ucOpMode == EFUSE_FREE) { + struct PARAM_CUSTOM_EFUSE_FREE_BLOCK rEfuseFreeBlock = {}; + + if (prGlueInfo->prAdapter->fgIsSupportGetFreeEfuseBlockCount + == FALSE) { + u4Offset += kalSnprintf(pcCommand + u4Offset, + i4TotalLen - u4Offset, + "Cannot read free block size\n"); + return (int32_t)u4Offset; + } + rStatus = kalIoctl(prGlueInfo, wlanoidQueryEfuseFreeBlock, + &rEfuseFreeBlock, + sizeof(struct PARAM_CUSTOM_EFUSE_FREE_BLOCK), + TRUE, TRUE, TRUE, &u4BufLen); + if (rStatus == WLAN_STATUS_SUCCESS) { + u4Offset += kalSnprintf(pcCommand + u4Offset, + i4TotalLen - u4Offset, + "Free block size 0x%X\n", + prGlueInfo->prAdapter->u4FreeBlockNum); + } + } +#else + u4Offset += kalSnprintf(pcCommand + u4Offset, i4TotalLen - u4Offset, + "efuse ops is invalid\n"); +#endif + + return (int32_t)u4Offset; + +efuse_op_invalid: + + u4Offset += kalSnprintf(pcCommand + u4Offset, i4TotalLen - u4Offset, + "\nHelp menu\n"); + u4Offset += kalSnprintf(pcCommand + u4Offset, i4TotalLen - u4Offset, + "\tRead:\t\"efuse read addr_hex\"\n"); + u4Offset += kalSnprintf(pcCommand + u4Offset, i4TotalLen - u4Offset, + "\tWrite:\t\"efuse write addr_hex val_hex\"\n"); + u4Offset += kalSnprintf(pcCommand + u4Offset, i4TotalLen - u4Offset, + "\tFree Blocks:\t\"efuse free\"\n"); + return (int32_t)u4Offset; +} + +#if defined(_HIF_SDIO) && (MTK_WCN_HIF_SDIO == 0) +static int priv_driver_cccr_ops(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + enum CCCR_OP_MODE { + CCCR_READ, + CCCR_WRITE, + CCCR_FREE, + CCCR_INVALID, + }; + uint8_t ucOpMode = CCCR_INVALID; + uint8_t ucOpChar; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + int32_t i4Ret; + int32_t i4Parameter; + uint32_t u4CCCR_addr = 0; + uint8_t ucCCCR_value = 0; + + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4Offset = 0; + struct GLUE_INFO *prGlueInfo = NULL; + + struct sdio_func *func; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + ASSERT(prGlueInfo); + + if(!IS_SDIO_INF(prGlueInfo)){ + u4Offset += kalSnprintf(pcCommand + u4Offset, + i4TotalLen - u4Offset, + "Not SDIO bus(%d)\n", + prGlueInfo->u4InfType); + return (int32_t)u4Offset; + } + + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + + /* Sanity check */ + if (i4Argc < 2) + goto cccr_op_invalid; + + ucOpChar = (uint8_t)apcArgv[1][0]; + if ((i4Argc == 3) && (ucOpChar == 'r' || ucOpChar == 'R')) + ucOpMode = CCCR_READ; + else if ((i4Argc == 4) && (ucOpChar == 'w' || ucOpChar == 'W')) + ucOpMode = CCCR_WRITE; + + /* Print out help if input format is wrong */ + if (ucOpMode == CCCR_INVALID) + goto cccr_op_invalid; + + /* convert address */ + if (ucOpMode == CCCR_READ || ucOpMode == CCCR_WRITE) { + i4Ret = kalkStrtos32(apcArgv[2], 16, &i4Parameter); + /* Valid address 0x0~0xFF */ + u4CCCR_addr = (uint32_t)(i4Parameter & 0xFF); + } + + /* convert value */ + if (ucOpMode == CCCR_WRITE) { + i4Ret = kalkStrtos32(apcArgv[3], 16, &i4Parameter); + ucCCCR_value = (uint8_t)i4Parameter; + } + + /* Set SDIO host reference */ + func = prGlueInfo->rHifInfo.func; + + /* Start operation */ + if (ucOpMode == CCCR_READ) { + sdio_claim_host(func); + ucCCCR_value = sdio_f0_readb(func, u4CCCR_addr, &rStatus); + sdio_release_host(func); + + if (rStatus) /* Fail case */ + u4Offset += kalSnprintf(pcCommand + u4Offset, + i4TotalLen - u4Offset, + "Read Fail 0x%X (ret=%d)\n", + u4CCCR_addr, rStatus); + else + u4Offset += kalSnprintf(pcCommand + u4Offset, + i4TotalLen - u4Offset, + "Read success 0x%X = 0x%X\n", + u4CCCR_addr, ucCCCR_value); + } else if (ucOpMode == CCCR_WRITE) { + uint32_t quirks_bak; + sdio_claim_host(func); + /* Enable capability to write CCCR */ + quirks_bak = func->card->quirks; + func->card->quirks |= MMC_QUIRK_LENIENT_FN0; + /* Write CCCR into card */ + sdio_f0_writeb(func, ucCCCR_value, u4CCCR_addr, &rStatus); + func->card->quirks = quirks_bak; + sdio_release_host(func); + + if (rStatus) /* Fail case */ + u4Offset += kalSnprintf(pcCommand + u4Offset, + i4TotalLen - u4Offset, + "Write Fail 0x%X (ret=%d)\n", + u4CCCR_addr, rStatus); + else + u4Offset += kalSnprintf(pcCommand + u4Offset, + i4TotalLen - u4Offset, + "Write success 0x%X = 0x%X\n", + u4CCCR_addr, ucCCCR_value); + } + + return (int32_t)u4Offset; + +cccr_op_invalid: + + u4Offset += kalSnprintf(pcCommand + u4Offset, i4TotalLen - u4Offset, + "\nHelp menu\n"); + u4Offset += kalSnprintf(pcCommand + u4Offset, i4TotalLen - u4Offset, + "\tRead:\t\"cccr read addr_hex\"\n"); + u4Offset += kalSnprintf(pcCommand + u4Offset, i4TotalLen - u4Offset, + "\tWrite:\t\"cccr write addr_hex val_hex\"\n"); + return (int32_t)u4Offset; +} +#endif /* _HIF_SDIO && (MTK_WCN_HIF_SDIO == 0) */ + +#if CFG_SUPPORT_ADVANCE_CONTROL +static int priv_driver_set_noise(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = { 0 }; + int32_t u4Ret = 0; + uint32_t u4Id = CMD_SW_DBGCTL_ADVCTL_SET_ID + 1; + uint32_t u4Sel = 0; + struct PARAM_CUSTOM_SW_CTRL_STRUCT rSwCtrlInfo; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + rSwCtrlInfo.u4Id = u4Id; + + if (i4Argc <= 1) { + DBGLOG(REQ, ERROR, "Argc(%d) ERR: SET_NOISE \n", i4Argc); + return -1; + } + + u4Ret = kalkStrtou32(apcArgv[1], 0, &u4Sel); + if (u4Ret) + DBGLOG(REQ, ERROR, "parse rSwCtrlInfo error u4Ret=%d\n", u4Ret); + + rSwCtrlInfo.u4Data = u4Sel << 30; + DBGLOG(REQ, LOUD, "u4Sel=%d u4Data=0x%x,\n", u4Sel, rSwCtrlInfo.u4Data); + rStatus = kalIoctl(prGlueInfo, wlanoidSetSwCtrlWrite, &rSwCtrlInfo, + sizeof(rSwCtrlInfo), FALSE, FALSE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, ERROR, "ERR: kalIoctl fail (%d)\n", rStatus); + return -1; + } + + return i4BytesWritten; + +} + +static int priv_driver_get_noise(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = { 0 }; + uint32_t u4Id = CMD_SW_DBGCTL_ADVCTL_GET_ID + 1; + uint32_t u4Offset = 0; + struct PARAM_CUSTOM_SW_CTRL_STRUCT rSwCtrlInfo; + int16_t u2Wf0AvgPwr, u2Wf1AvgPwr; + + ASSERT(prNetDev); + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + + rSwCtrlInfo.u4Data = 0; + rSwCtrlInfo.u4Id = u4Id; + + rStatus = kalIoctl(prGlueInfo, wlanoidQuerySwCtrlRead, &rSwCtrlInfo, + sizeof(rSwCtrlInfo), TRUE, TRUE, TRUE, &u4BufLen); + + DBGLOG(REQ, LOUD, "rStatus %u\n", rStatus); + if (rStatus != WLAN_STATUS_SUCCESS) + return -1; + + u2Wf0AvgPwr = rSwCtrlInfo.u4Data & 0xFFFF; + u2Wf1AvgPwr = (rSwCtrlInfo.u4Data >> 16) & 0xFFFF; + + u4Offset += kalSnprintf(pcCommand + u4Offset, i4TotalLen - u4Offset, + "Noise Idle Avg. Power: WF0:%ddB WF1:%ddB\n", + u2Wf0AvgPwr, u2Wf1AvgPwr); + + i4BytesWritten = (int32_t)u4Offset; + + return i4BytesWritten; + +} /* priv_driver_get_sw_ctrl */ + +static int priv_driver_set_pop(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = { 0 }; + int32_t u4Ret = 0; + uint32_t u4Id = CMD_SW_DBGCTL_ADVCTL_SET_ID + 2; + uint32_t u4Sel = 0, u4CckTh = 0, u4OfdmTh = 0; + struct PARAM_CUSTOM_SW_CTRL_STRUCT rSwCtrlInfo; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + rSwCtrlInfo.u4Id = u4Id; + + if (i4Argc <= 3) { + DBGLOG(REQ, ERROR, + "Argc(%d) ERR: SET_POP \n", + i4Argc); + return -1; + } + + u4Ret = kalkStrtou32(apcArgv[1], 0, &u4Sel); + if (u4Ret) + DBGLOG(REQ, ERROR, "parse rSwCtrlInfo error u4Ret=%d\n", u4Ret); + u4Ret = kalkStrtou32(apcArgv[2], 0, &u4CckTh); + if (u4Ret) + DBGLOG(REQ, ERROR, "parse rSwCtrlInfo error u4Ret=%d\n", u4Ret); + u4Ret = kalkStrtou32(apcArgv[3], 0, &u4OfdmTh); + if (u4Ret) + DBGLOG(REQ, ERROR, "parse rSwCtrlInfo error u4Ret=%d\n", u4Ret); + + rSwCtrlInfo.u4Data = (u4CckTh | (u4OfdmTh<<8) | (u4Sel<<30)); + DBGLOG(REQ, LOUD, "u4Sel=%d u4CckTh=%d u4OfdmTh=%d, u4Data=0x%x,\n", + u4Sel, u4CckTh, u4OfdmTh, rSwCtrlInfo.u4Data); + rStatus = kalIoctl(prGlueInfo, wlanoidSetSwCtrlWrite, &rSwCtrlInfo, + sizeof(rSwCtrlInfo), FALSE, FALSE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, ERROR, "ERR: kalIoctl fail (%d)\n", rStatus); + return -1; + } + + return i4BytesWritten; + +} + +static int priv_driver_set_ed(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = { 0 }; + int32_t u4Ret = 0, u4EdVal = 0; + uint32_t u4Id = CMD_SW_DBGCTL_ADVCTL_SET_ID + 3; + uint32_t u4Sel = 0; + struct PARAM_CUSTOM_SW_CTRL_STRUCT rSwCtrlInfo; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + rSwCtrlInfo.u4Id = u4Id; + + if (i4Argc <= 2) { + DBGLOG(REQ, ERROR, + "Argc(%d) ERR: SET_ED \n", + i4Argc); + return -1; + } + + u4Ret = kalkStrtou32(apcArgv[1], 0, &u4Sel); + if (u4Ret) + DBGLOG(REQ, ERROR, "parse rSwCtrlInfo error u4Ret=%d\n", u4Ret); + u4Ret = kalkStrtos32(apcArgv[2], 0, &u4EdVal); + if (u4Ret) + DBGLOG(REQ, ERROR, "parse rSwCtrlInfo error u4Ret=%d\n", u4Ret); + + rSwCtrlInfo.u4Data = ((u4EdVal & 0xFF) | (u4Sel << 31)); + DBGLOG(REQ, LOUD, "u4Sel=%d u4EdCcaVal=%d, u4Data=0x%x,\n", + u4Sel, u4EdVal, rSwCtrlInfo.u4Data); + + rStatus = kalIoctl(prGlueInfo, wlanoidSetSwCtrlWrite, &rSwCtrlInfo, + sizeof(rSwCtrlInfo), FALSE, FALSE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, ERROR, "ERR: kalIoctl fail (%d)\n", rStatus); + return -1; + } + + return i4BytesWritten; + +} + +static int priv_driver_get_tp_info(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + ASSERT(prNetDev); + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + return kalPerMonGetInfo(prGlueInfo->prAdapter, pcCommand, i4TotalLen); +} + +static int priv_driver_set_pd(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = { 0 }; + int32_t u4Ret = 0; + uint32_t u4Id = CMD_SW_DBGCTL_ADVCTL_SET_ID + 4; + uint32_t u4Sel = 0; + int32_t u4CckTh = 0, u4OfdmTh = 0; + struct PARAM_CUSTOM_SW_CTRL_STRUCT rSwCtrlInfo; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + rSwCtrlInfo.u4Id = u4Id; + + if (i4Argc <= 1) { + DBGLOG(REQ, ERROR, + "Argc(%d) ERR: SET_PD [CCK TH] [OFDM TH]\n", + i4Argc); + return -1; + } + + u4Ret = kalkStrtou32(apcArgv[1], 0, &u4Sel); + if (u4Ret) + DBGLOG(REQ, ERROR, "parse rSwCtrlInfo error u4Ret=%d\n", u4Ret); + + if (u4Sel == 1) { + if (i4Argc <= 3) { + DBGLOG(REQ, ERROR, + "Argc(%d) ERR: SET_PD 1 \n", + i4Argc); + return -1; + } + u4Ret = kalkStrtos32(apcArgv[2], 0, &u4CckTh); + if (u4Ret) + DBGLOG(REQ, ERROR, "parse rSwCtrlInfo error u4Ret=%d\n", + u4Ret); + u4Ret = kalkStrtos32(apcArgv[3], 0, &u4OfdmTh); + if (u4Ret) + DBGLOG(REQ, ERROR, "parse rSwCtrlInfo error u4Ret=%d\n", + u4Ret); + } + + rSwCtrlInfo.u4Data = ((u4OfdmTh & 0xFFFF) | ((u4CckTh & 0xFF) << 16) | + (u4Sel << 30)); + DBGLOG(REQ, LOUD, "u4Sel=%d u4OfdmTh=%d, u4CckTh=%d, u4Data=0x%x,\n", + u4Sel, u4OfdmTh, u4CckTh, rSwCtrlInfo.u4Data); + + rStatus = kalIoctl(prGlueInfo, wlanoidSetSwCtrlWrite, &rSwCtrlInfo, + sizeof(rSwCtrlInfo), FALSE, FALSE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, ERROR, "ERR: kalIoctl fail (%d)\n", rStatus); + return -1; + } + + return i4BytesWritten; +} + +static int priv_driver_set_maxrfgain(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = { 0 }; + int32_t u4Ret = 0; + uint32_t u4Id = CMD_SW_DBGCTL_ADVCTL_SET_ID + 5; + uint32_t u4Sel = 0; + int32_t u4Wf0Gain = 0, u4Wf1Gain = 0; + struct PARAM_CUSTOM_SW_CTRL_STRUCT rSwCtrlInfo; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + rSwCtrlInfo.u4Id = u4Id; + + if (i4Argc <= 1) { + DBGLOG(REQ, ERROR, + "Argc(%d) ERR: SET_RFGAIN \n", + i4Argc); + return -1; + } + + u4Ret = kalkStrtou32(apcArgv[1], 0, &u4Sel); + if (u4Ret) + DBGLOG(REQ, ERROR, "parse rSwCtrlInfo error u4Ret=%d\n", u4Ret); + + if (u4Sel == 1) { + if (i4Argc <= 3) { + DBGLOG(REQ, ERROR, + "Argc(%d) ERR: SET_RFGAIN 1 \n", + i4Argc); + return -1; + } + u4Ret = kalkStrtos32(apcArgv[2], 0, &u4Wf0Gain); + if (u4Ret) + DBGLOG(REQ, ERROR, "parse rSwCtrlInfo error u4Ret=%d\n", + u4Ret); + u4Ret = kalkStrtos32(apcArgv[3], 0, &u4Wf1Gain); + if (u4Ret) + DBGLOG(REQ, ERROR, "parse rSwCtrlInfo error u4Ret=%d\n", + u4Ret); + } + + rSwCtrlInfo.u4Data = ((u4Wf0Gain & 0xFF) | ((u4Wf1Gain & 0xFF) << 8) | + (u4Sel << 31)); + DBGLOG(REQ, LOUD, "u4Sel=%d u4Wf0Gain=%d, u4Wf1Gain=%d, u4Data=0x%x,\n", + u4Sel, u4Wf0Gain, u4Wf1Gain, rSwCtrlInfo.u4Data); + + rStatus = kalIoctl(prGlueInfo, wlanoidSetSwCtrlWrite, &rSwCtrlInfo, + sizeof(rSwCtrlInfo), FALSE, FALSE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, ERROR, "ERR: kalIoctl fail (%d)\n", rStatus); + return -1; + } + + return i4BytesWritten; +} + +#endif + + +#if (CFG_SUPPORT_TWT == 1) +static int priv_driver_set_twtparams( + struct net_device *prNetDev, + char *pcCommand, + int i4TotalLen) +{ + struct ADAPTER *prAdapter = NULL; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX_LONG] = { 0 }; + struct _TWT_CTRL_T rTWTCtrl; + struct _TWT_PARAMS_T *prTWTParams; + uint16_t i; + int32_t u4Ret = 0; + uint16_t au2Setting[CMD_TWT_MAX_PARAMS]; + struct NETDEV_PRIVATE_GLUE_INFO *prNetDevPrivate = NULL; + struct _MSG_TWT_PARAMS_SET_T *prTWTParamSetMsg; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prNetDevPrivate = + (struct NETDEV_PRIVATE_GLUE_INFO *) netdev_priv(prNetDev); + + DBGLOG(REQ, INFO, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, INFO, "argc is %i\n", i4Argc); + + prAdapter = prNetDevPrivate->prGlueInfo->prAdapter; + + /* Check param number and convert TWT params to integer type */ + if (i4Argc == CMD_TWT_ACTION_TEN_PARAMS || + i4Argc == CMD_TWT_ACTION_THREE_PARAMS) { + for (i = 0; i < (i4Argc - 1); i++) { + + u4Ret = kalkStrtou16(apcArgv[i + 1], + 0, &(au2Setting[i])); + + if (u4Ret) + DBGLOG(REQ, INFO, "Argv error ret=%d\n", u4Ret); + } + } else { + DBGLOG(REQ, INFO, "set_twtparams wrong argc : %d\n", i4Argc); + return -1; + } + + if ((IS_TWT_PARAM_ACTION_DEL(au2Setting[0]) || + IS_TWT_PARAM_ACTION_SUSPEND(au2Setting[0]) || + IS_TWT_PARAM_ACTION_RESUME(au2Setting[0])) && + i4Argc == CMD_TWT_ACTION_THREE_PARAMS) { + + DBGLOG(REQ, INFO, "Action=%d\n", au2Setting[0]); + DBGLOG(REQ, INFO, "TWT Flow ID=%d\n", au2Setting[1]); + + if (au2Setting[1] >= TWT_MAX_FLOW_NUM) { + /* Simple sanity check failure */ + DBGLOG(REQ, INFO, "Invalid TWT Params\n"); + return -1; + } + + rTWTCtrl.ucBssIdx = prNetDevPrivate->ucBssIdx; + rTWTCtrl.ucCtrlAction = au2Setting[0]; + rTWTCtrl.ucTWTFlowId = au2Setting[1]; + + } else if (i4Argc == CMD_TWT_ACTION_TEN_PARAMS) { + DBGLOG(REQ, INFO, "Action bitmap=%d\n", au2Setting[0]); + DBGLOG(REQ, INFO, + "TWT Flow ID=%d Setup Command=%d Trig enabled=%d\n", + au2Setting[1], au2Setting[2], au2Setting[3]); + DBGLOG(REQ, INFO, + "Unannounced enabled=%d Wake Interval Exponent=%d\n", + au2Setting[4], au2Setting[5]); + DBGLOG(REQ, INFO, "Protection enabled=%d Duration=%d\n", + au2Setting[6], au2Setting[7]); + DBGLOG(REQ, INFO, "Wake Interval Mantissa=%d\n", au2Setting[8]); + /* + * au2Setting[0]: Whether bypassing nego or not + * au2Setting[1]: TWT Flow ID + * au2Setting[2]: TWT Setup Command + * au2Setting[3]: Trigger enabled + * au2Setting[4]: Unannounced enabled + * au2Setting[5]: TWT Wake Interval Exponent + * au2Setting[6]: TWT Protection enabled + * au2Setting[7]: Nominal Minimum TWT Wake Duration + * au2Setting[8]: TWT Wake Interval Mantissa + */ + if (au2Setting[1] >= TWT_MAX_FLOW_NUM || + au2Setting[2] > TWT_SETUP_CMD_DEMAND || + au2Setting[5] > TWT_MAX_WAKE_INTVAL_EXP) { + /* Simple sanity check failure */ + DBGLOG(REQ, INFO, "Invalid TWT Params\n"); + return -1; + } + + prTWTParams = &(rTWTCtrl.rTWTParams); + kalMemSet(prTWTParams, 0, sizeof(struct _TWT_PARAMS_T)); + prTWTParams->fgReq = TRUE; + prTWTParams->ucSetupCmd = (uint8_t) au2Setting[2]; + prTWTParams->fgTrigger = (au2Setting[3]) ? TRUE : FALSE; + prTWTParams->fgUnannounced = (au2Setting[4]) ? TRUE : FALSE; + prTWTParams->ucWakeIntvalExponent = (uint8_t) au2Setting[5]; + prTWTParams->fgProtect = (au2Setting[6]) ? TRUE : FALSE; + prTWTParams->ucMinWakeDur = (uint8_t) au2Setting[7]; + prTWTParams->u2WakeIntvalMantiss = au2Setting[8]; + + rTWTCtrl.ucBssIdx = prNetDevPrivate->ucBssIdx; + rTWTCtrl.ucCtrlAction = au2Setting[0]; + rTWTCtrl.ucTWTFlowId = au2Setting[1]; + } else { + DBGLOG(REQ, INFO, "wrong argc for update agrt: %d\n", i4Argc); + return -1; + } + + prTWTParamSetMsg = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, + sizeof(struct _MSG_TWT_REQFSM_RESUME_T)); + if (prTWTParamSetMsg) { + prTWTParamSetMsg->rMsgHdr.eMsgId = + MID_TWT_PARAMS_SET; + kalMemCopy(&prTWTParamSetMsg->rTWTCtrl, + &rTWTCtrl, sizeof(rTWTCtrl)); + + mboxSendMsg(prAdapter, MBOX_ID_0, + (struct MSG_HDR *) prTWTParamSetMsg, + MSG_SEND_METHOD_BUF); + } else + return -1; + + return 0; +} +#endif + +#if (CFG_SUPPORT_802_11AX == 1) +int priv_driver_set_pad_dur(IN struct net_device *prNetDev, IN char *pcCommand, + IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint32_t u4Ret, u4Parse = 0; + uint8_t u1HePadDur; + + ASSERT(prNetDev); + + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + + if (i4Argc == 2) { + + u4Ret = kalkStrtou32(apcArgv[1], 0, &u4Parse); + if (u4Ret) + DBGLOG(REQ, LOUD, "parse apcArgv error u4Ret=%d\n", + u4Ret); + + u1HePadDur = (uint8_t) u4Parse; + + if (u1HePadDur == 0 || u1HePadDur == 8 || + u1HePadDur == 16) { + prGlueInfo->prAdapter->rWifiVar.ucTrigMacPadDur + = u1HePadDur/8; + } else { + DBGLOG(INIT, ERROR, + "iwpriv wlanXX driver SET_PAD_DUR <0,1,2>\n"); + } + } else { + DBGLOG(INIT, ERROR, + "iwpriv wlanXX driver SET_PAD_DUR <0,1,2>\n"); + } + + return i4BytesWritten; +} +#endif + + +static int priv_driver_get_wifi_type(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct PARAM_GET_WIFI_TYPE rParamGetWifiType; + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus; + uint32_t u4BytesWritten = 0; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) { + DBGLOG(REQ, ERROR, "GLUE_CHK_PR2 fail\n"); + return -1; + } + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + rParamGetWifiType.prNetDev = prNetDev; + rStatus = kalIoctl(prGlueInfo, + wlanoidGetWifiType, + (void *)&rParamGetWifiType, + sizeof(void *), + FALSE, + FALSE, + FALSE, + &u4BytesWritten); + if (rStatus == WLAN_STATUS_SUCCESS) { + if (u4BytesWritten > 0) { + if (u4BytesWritten > i4TotalLen) + u4BytesWritten = i4TotalLen; + kalMemCopy(pcCommand, rParamGetWifiType.arWifiTypeName, + u4BytesWritten); + } + } else { + DBGLOG(REQ, ERROR, "rStatus=%x\n", rStatus); + u4BytesWritten = 0; + } + + return (int)u4BytesWritten; +} + +#if CFG_ENABLE_WIFI_DIRECT +static int priv_driver_set_p2p_ps(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + struct BSS_INFO *prBssInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = { 0 }; + uint32_t ucRoleIdx; + uint8_t ucBssIdx; + uint32_t u4CTwindowMs; + struct P2P_SPECIFIC_BSS_INFO *prP2pSpecBssInfo = NULL; + struct PARAM_CUSTOM_OPPPS_PARAM_STRUCT *rOppPsParam = NULL; + + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + + if (i4Argc < 2) { + DBGLOG(REQ, ERROR, + "Expect param: . argc=%d now\n", i4Argc); + return -1; + } + + if (kalkStrtou32(apcArgv[1], 0, &ucRoleIdx)) { + DBGLOG(REQ, ERROR, "parse ucRoleIdx error\n"); + return -1; + } + + if (kalkStrtou32(apcArgv[2], 0, &u4CTwindowMs)) { + DBGLOG(REQ, ERROR, "parse u4CTwindowMs error\n"); + return -1; + } + + /* get Bss Index from ndev */ + if (p2pFuncRoleToBssIdx(prAdapter, ucRoleIdx, &ucBssIdx) != + WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, ERROR, "can't find ucBssIdx\n"); + return -1; + } + + prBssInfo = prAdapter->aprBssInfo[ucBssIdx]; + + if (!(prBssInfo->fgIsInUse) || (prBssInfo->eIftype != IFTYPE_P2P_GO)) { + DBGLOG(REQ, ERROR, "wrong bss InUse=%d, iftype=%d\n", + prBssInfo->fgIsInUse, prBssInfo->eIftype); + return -1; + } + + DBGLOG(REQ, INFO, "ucRoleIdx=%d, ucBssIdx=%d, u4CTwindowMs=%d\n", + ucRoleIdx, ucBssIdx, u4CTwindowMs); + + if (u4CTwindowMs > 0) + u4CTwindowMs |= BIT(7); /* FW checks BIT(7) for enable */ + + prP2pSpecBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo[ucRoleIdx]; + rOppPsParam = &prP2pSpecBssInfo->rOppPsParam; + rOppPsParam->u4CTwindowMs = u4CTwindowMs; + rOppPsParam->ucBssIdx = ucBssIdx; + + rStatus = kalIoctl(prGlueInfo, wlanoidSetOppPsParam, rOppPsParam, + sizeof(struct PARAM_CUSTOM_OPPPS_PARAM_STRUCT), + FALSE, FALSE, TRUE, &u4BufLen); + + return !(rStatus == WLAN_STATUS_SUCCESS); +} + +static int priv_driver_set_p2p_noa(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + struct BSS_INFO *prBssInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = { 0 }; + uint8_t ucBssIdx; + uint32_t ucRoleIdx; + uint32_t u4NoaDurationMs; + uint32_t u4NoaIntervalMs; + uint32_t u4NoaCount; + struct P2P_SPECIFIC_BSS_INFO *prP2pSpecBssInfo = NULL; + struct PARAM_CUSTOM_NOA_PARAM_STRUCT *rNoaParam = NULL; + + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prAdapter = prGlueInfo->prAdapter; + + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + + if (i4Argc < 4) { + DBGLOG(REQ, ERROR, + "SET_P2P_NOA \n"); + return -1; + } + + if (kalkStrtou32(apcArgv[1], 0, &ucRoleIdx)) { + DBGLOG(REQ, ERROR, "parse ucRoleIdx error\n"); + return -1; + } + + if (kalkStrtou32(apcArgv[2], 0, &u4NoaCount)) { + DBGLOG(REQ, ERROR, "parse u4NoaCount error\n"); + return -1; + } + + if (kalkStrtou32(apcArgv[3], 0, &u4NoaIntervalMs)) { + DBGLOG(REQ, ERROR, "parse u4NoaIntervalMs error\n"); + return -1; + } + + if (kalkStrtou32(apcArgv[4], 0, &u4NoaDurationMs)) { + DBGLOG(REQ, ERROR, "parse u4NoaDurationMs error\n"); + return -1; + } + + /* get Bss Index from ndev */ + if (p2pFuncRoleToBssIdx(prAdapter, ucRoleIdx, &ucBssIdx) != + WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, ERROR, "can't find ucBssIdx\n"); + return -1; + } + + prBssInfo = prAdapter->aprBssInfo[ucBssIdx]; + + if (!(prBssInfo->fgIsInUse) || (prBssInfo->eIftype != IFTYPE_P2P_GO)) { + DBGLOG(REQ, ERROR, "wrong bss InUse=%d, iftype=%d\n", + prBssInfo->fgIsInUse, prBssInfo->eIftype); + return -1; + } + + DBGLOG(REQ, INFO, + "RoleIdx=%d, BssIdx=%d, count=%d, interval=%d, duration=%d\n", + ucRoleIdx, ucBssIdx, u4NoaCount, u4NoaIntervalMs, + u4NoaDurationMs); + + prP2pSpecBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo[ucRoleIdx]; + rNoaParam = &prP2pSpecBssInfo->rNoaParam; + rNoaParam->u4NoaCount = u4NoaCount; + rNoaParam->u4NoaIntervalMs = u4NoaIntervalMs; + rNoaParam->u4NoaDurationMs = u4NoaDurationMs; + rNoaParam->ucBssIdx = ucBssIdx; + + rStatus = kalIoctl(prGlueInfo, wlanoidSetNoaParam, rNoaParam, + sizeof(struct PARAM_CUSTOM_NOA_PARAM_STRUCT), + FALSE, FALSE, TRUE, &u4BufLen); + + return !(rStatus == WLAN_STATUS_SUCCESS); +} +#endif /* CFG_ENABLE_WIFI_DIRECT */ + +static int priv_driver_set_drv_ser(struct net_device *prNetDev, + char *pcCommand, int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = { 0 }; + int32_t i4Argc = 0; + int32_t i4BytesWritten = 0; + uint32_t u4Num = 0; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + if (i4Argc <= 0) { + DBGLOG(REQ, ERROR, "Argc(%d) ERR: Set driver SER\n", i4Argc); + return -1; + } + + rStatus = kalIoctl(prGlueInfo, wlanoidSetDrvSer, + (void *)&u4Num, sizeof(uint32_t), + FALSE, FALSE, FALSE, &u4BufLen); + + i4BytesWritten += kalSnprintf(pcCommand, i4TotalLen, + "trigger driver SER\n"); + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, ERROR, "ERR: kalIoctl fail (%d)\n", rStatus); + return -1; + } + + return i4BytesWritten; +} + +#ifdef UT_TEST_MODE +int priv_driver_run_ut(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + int32_t u4Ret = 0; + uint32_t u4Input = 0; + + ASSERT(prNetDev); + + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + if (!prGlueInfo || !prGlueInfo->prAdapter) { + DBGLOG(REQ, ERROR, "prGlueInfo or prAdapter is NULL\n"); + return -1; + } + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + if (i4Argc < 2) { + DBGLOG(REQ, ERROR, "Argc(%d) ERR: RUN_UT COMMAND\n", i4Argc); + return -1; + } + + if (strlen(apcArgv[1]) == strlen("all") && + strnicmp(apcArgv[1], "all", strlen("all")) == 0) + testRunAllTestCases(prGlueInfo->prAdapter); + else if (i4Argc >= 3) { + if (strlen(apcArgv[1]) == strlen("tc") && + strnicmp(apcArgv[1], "tc", strlen("tc")) == 0) { + u4Ret = kalkStrtou32(apcArgv[2], 0, &u4Input); + if (u4Ret) { + DBGLOG(REQ, ERROR, "parse error u4Ret=%d\n", + u4Ret); + return -1; + } + testRunTestCase(prGlueInfo->prAdapter, u4Input); + + } else if (strlen(apcArgv[1]) == strlen("group") && + strnicmp(apcArgv[1], "group", + strlen("group")) == 0) { + testRunGroupTestCases(prGlueInfo->prAdapter, + apcArgv[2]); + + } else if (strlen(apcArgv[1]) == strlen("list") && + strnicmp(apcArgv[1], "list", strlen("list")) == 0) { + if (strlen(apcArgv[2]) == strlen("all") && + strnicmp(apcArgv[2], "all", strlen("all")) == 0) { + testRunAllTestCaseLists(prGlueInfo->prAdapter); + } else { + u4Ret = kalkStrtou32(apcArgv[2], 0, &u4Input); + if (u4Ret) { + DBGLOG(REQ, ERROR, + "parse error u4Ret=%d\n", u4Ret); + return -1; + } + testRunTestCaseList(prGlueInfo->prAdapter, + u4Input); + } + } + } + + return 0; +} +#endif /* UT_TEST_MODE */ + +static int priv_driver_set_amsdu_num(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = { 0 }; + int32_t i4Argc = 0; + int32_t i4BytesWritten = 0; + int32_t u4Ret = 0; + uint32_t u4Num = 0; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + if (i4Argc <= 1) { + DBGLOG(REQ, ERROR, "Argc(%d) ERR: Sw Amsdu Num\n", i4Argc); + return -1; + } + + u4Ret = kalkStrtou32(apcArgv[1], 0, &u4Num); + if (u4Ret) + DBGLOG(REQ, ERROR, "parse amsdu num error u4Ret=%d\n", u4Ret); + + rStatus = kalIoctl(prGlueInfo, + wlanoidSetAmsduNum, + (void *)&u4Num, sizeof(uint32_t), + FALSE, FALSE, FALSE, &u4BufLen); + + i4BytesWritten += kalSnprintf(pcCommand, i4TotalLen, + "Set Sw Amsdu Num:%u\n", u4Num); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, ERROR, "ERR: kalIoctl fail (%d)\n", rStatus); + return -1; + } + + return i4BytesWritten; + +} + +static int priv_driver_set_amsdu_size(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = { 0 }; + int32_t i4Argc = 0; + int32_t i4BytesWritten = 0; + int32_t u4Ret = 0; + uint32_t u4Size = 0; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + if (i4Argc <= 1) { + DBGLOG(REQ, ERROR, "Argc(%d) ERR: Sw Amsdu Max Size\n", i4Argc); + return -1; + } + + u4Ret = kalkStrtou32(apcArgv[1], 0, &u4Size); + if (u4Ret) + DBGLOG(REQ, ERROR, "parse amsdu size error u4Ret=%d\n", u4Ret); + + rStatus = kalIoctl(prGlueInfo, + wlanoidSetAmsduSize, + (void *)&u4Size, sizeof(uint32_t), + FALSE, FALSE, FALSE, &u4BufLen); + + i4BytesWritten += kalSnprintf(pcCommand, i4TotalLen, + "Set Sw Amsdu Max Size:%u\n", u4Size); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, ERROR, "ERR: kalIoctl fail (%d)\n", rStatus); + return -1; + } + + return i4BytesWritten; + +} + +#if (CFG_SUPPORT_CONNINFRA == 1) +static int priv_driver_trigger_whole_chip_reset( + struct net_device *prNetDev, + char *pcCommand, + int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct mt66xx_chip_info *prChipInfo; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + if ((!prGlueInfo) || + (prGlueInfo->u4ReadyFlag == 0) || + kalIsResetting()) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -1; + } + prChipInfo = prGlueInfo->prAdapter->chip_info; + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + glSetRstReason(RST_CMD_TRIGGER); + glSetRstReasonString( + "cmd test trigger whole chip reset"); + if (prChipInfo->trigger_wholechiprst) + prChipInfo->trigger_wholechiprst(g_reason); + + return i4BytesWritten; +} +static int priv_driver_trigger_wfsys_reset( + struct net_device *prNetDev, + char *pcCommand, + int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + if ((!prGlueInfo) || + (prGlueInfo->u4ReadyFlag == 0) || + kalIsResetting()) { + DBGLOG(REQ, WARN, "driver is not ready\n"); + return -1; + } + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + glSetRstReason(RST_CMD_TRIGGER); + GL_RESET_TRIGGER(prGlueInfo->prAdapter, RST_FLAG_WF_RESET); + + return i4BytesWritten; +} +#endif +#if (CFG_SUPPORT_CONNAC2X == 1) +static int priv_driver_get_umac_fwtbl( + struct net_device *prNetDev, + char *pcCommand, + int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4Argc = 0; + int32_t u4Ret = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint32_t u4Index = 0; + struct CHIP_DBG_OPS *prDbgOps; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + if (i4Argc >= 2) + u4Ret = kalkStrtou32(apcArgv[1], 0, &u4Index); + + if (u4Ret) + return -1; + + prDbgOps = prGlueInfo->prAdapter->chip_info->prDebugOps; + + if (prDbgOps->showUmacFwtblInfo) + return prDbgOps->showUmacFwtblInfo( + prGlueInfo->prAdapter, u4Index, pcCommand, i4TotalLen); + else + return -1; +} +#endif /* CFG_SUPPORT_CONNAC2X == 1 */ + +static int priv_driver_show_txd_info( + IN struct net_device *prNetDev, + IN char *pcCommand, + IN int i4TotalLen +) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4BytesWritten = 0; + int32_t u4Ret = -1; + int32_t idx = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + struct CHIP_DBG_OPS *prDbgOps; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prDbgOps = prGlueInfo->prAdapter->chip_info->prDebugOps; + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); + + if (i4Argc >= 2) + u4Ret = kalkStrtos32(apcArgv[1], 16, &idx); + + if (!u4Ret && prDbgOps && prDbgOps->showTxdInfo) { + DBGLOG(HAL, INFO, "idx = %d 0x%x\n", idx, idx); + prDbgOps->showTxdInfo(prGlueInfo->prAdapter, idx); + } + return i4BytesWritten; +} +#if (CONFIG_WLAN_SERVICE == 1) +int8_t *RxStatCommonUser[] = { + /* common user stat info */ + "rx_fifo_full : 0x%08x\n", + "aci_hit_low : 0x%08x\n", + "aci_hit_high : 0x%08x\n", + "mu_pkt_cnt : 0x%08x\n", + "sig_mcs : 0x%08x\n", + "sinr : 0x%08x\n", + "driver_rx_count: 0x%08x\n" +}; + +int8_t *RxStatPerUser[] = { + /* per user stat info */ + "freq_ofst_from_rx: 0x%08x\n", + "snr : 0x%08x\n", + "fcs_err_cnt : 0x%08x\n" +}; + +int8_t *RxStatPerAnt[] = { + /* per anternna stat info */ + "rcpi : %d\n", + "rssi : %d\n", + "fagc_ib_rssi : %d\n", + "fagc_wb_rssi : %d\n", + "inst_ib_rssi : %d\n", + "inst_wb_rssi : %d\n" +}; + +int8_t *RxStatPerBand[] = { + /* per band stat info */ + "mac_fcs_err_cnt : 0x%08x\n", + "mac_mdy_cnt : 0x%08x\n", + "mac_len_mismatch: 0x%08x\n", + "mac_fcs_ok_cnt : 0x%08x\n", + "phy_fcs_err_cnt_cck: 0x%08x\n", + "phy_fcs_err_cnt_ofdm: 0x%08x\n", + "phy_pd_cck : 0x%08x\n", + "phy_pd_ofdm : 0x%08x\n", + "phy_sig_err_cck : 0x%08x\n", + "phy_sfd_err_cck : 0x%08x\n", + "phy_sig_err_ofdm: 0x%08x\n", + "phy_tag_err_ofdm: 0x%08x\n", + "phy_mdy_cnt_cck : 0x%08x\n", + "phy_mdy_cnt_ofdm: 0x%08x\n" +}; + +int32_t priv_driver_rx_stat_parser( + IN uint8_t *dataptr, + IN int i4TotalLen, + OUT char *pcCommand +) +{ + int32_t i4BytesWritten = 0; + int32_t i4tmpContent = 0; + int32_t i4TypeNum = 0, i4Type = 0, i4Version = 0; + int32_t i = 0, j = 0, i4ItemMask = 0, i4TypeLen = 0, i4SubLen = 0; + /*Get type num*/ + i4TypeNum = NTOHL(dataptr[3] << 24 | dataptr[2] << 16 | + dataptr[1] << 8 | dataptr[0]); + dataptr += 4; + DBGLOG(REQ, LOUD, "i4TypeNum is %x\n", i4TypeNum); + while (i4TypeNum) { + i4TypeNum--; + /*Get type*/ + i4Type = NTOHL(dataptr[3] << 24 | dataptr[2] << 16 | + dataptr[1] << 8 | dataptr[0]); + dataptr += 4; + DBGLOG(REQ, LOUD, "i4Type is %x\n", i4Type); + + /*Get Version*/ + i4Version = NTOHL(dataptr[3] << 24 | dataptr[2] << 16 | + dataptr[1] << 8 | dataptr[0]); + dataptr += 4; + DBGLOG(REQ, LOUD, "i4Version is %x\n", i4Version); + + /*Get Item Mask*/ + i4ItemMask = NTOHL(dataptr[3] << 24 | dataptr[2] << 16 | + dataptr[1] << 8 | dataptr[0]); + j = i4ItemMask; + dataptr += 4; + DBGLOG(REQ, LOUD, "i4ItemMask is %x\n", i4ItemMask); + + /*Get Len*/ + i4TypeLen = NTOHL(dataptr[3] << 24 | dataptr[2] << 16 | + dataptr[1] << 8 | dataptr[0]); + dataptr += 4; + DBGLOG(REQ, LOUD, "i4TypeLen is %x\n", i4TypeLen); + + /*Get Sub Len*/ + while (j) { + i++; + j = j >> 1; + } + + if (i != 0) + i4SubLen = i4TypeLen / i; + + i = 0; + DBGLOG(REQ, LOUD, "i4SubLen is %x\n", i4SubLen); + + while (i4TypeLen) { + while (i < i4SubLen) { + /*Get Content*/ + i4tmpContent = NTOHL(dataptr[3] << 24 | + dataptr[2] << 16 | dataptr[1] << 8 | + dataptr[0]); + DBGLOG(REQ, LOUD, + "i4tmpContent is %x\n", i4tmpContent); + + if (i4Type == 0) { + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen, RxStatPerBand[i/4], + i4tmpContent); + } else if (i4Type == 1) { + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen, RxStatPerAnt[i/4], + i4tmpContent); + } else if (i4Type == 2) { + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen, RxStatPerUser[i/4], + i4tmpContent); + } else { + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen, + RxStatCommonUser[i/4], + i4tmpContent); + } + i += 4; + dataptr += 4; + } + i = 0; + i4TypeLen -= i4SubLen; + } + } + return i4BytesWritten; +} +#endif + +static int priv_driver_run_hqa( + IN struct net_device *prNetDev, + IN char *pcCommand, + IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4BytesWritten = 0; + int8_t *this_char = NULL; +#if (CONFIG_WLAN_SERVICE == 1) + struct hqa_frame_ctrl local_hqa; + bool IsShowRxStat = FALSE; + uint8_t *dataptr = NULL; + uint8_t *oridataptr = NULL; + int32_t datalen = 0; + int32_t oridatalen = 0; + int32_t ret = WLAN_STATUS_FAILURE; + int16_t i2tmpVal = 0; + int32_t i4tmpVal = 0; +#endif + int32_t i = 0; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); + + /*Roll over "HQA ", handle xxx=y,y,y,y,y,y....*/ + /* iwpriv wlan0 driver HQA xxx=y,y,y,y,y,y.....*/ + this_char = kalStrStr(pcCommand, "HQA "); + if (!this_char) + return -1; + this_char += strlen("HQA "); + + /*handle white space*/ + i = strspn(this_char, " "); + this_char += i; + + DBGLOG(REQ, LOUD, "this_char is %s\n", this_char); +#if (CONFIG_WLAN_SERVICE == 1) + if (this_char) { + if (strncasecmp(this_char, + "GetRXStatisticsAllNew", + strlen("GetRXStatisticsAllNew")) == 0) + IsShowRxStat = TRUE; + + local_hqa.type = 1; + local_hqa.hqa_frame_comm.hqa_frame_string = this_char; + ret = mt_agent_hqa_cmd_handler(&prGlueInfo->rService, + &local_hqa); + } + + if (ret != WLAN_STATUS_SUCCESS) + return -1; + + datalen = NTOHS(local_hqa.hqa_frame_comm.hqa_frame_eth->length); + dataptr = kalMemAlloc(datalen, VIR_MEM_TYPE); + if (dataptr == NULL) + return -1; + + /* Backup Original Ptr /Len for mem Free */ + oridataptr = dataptr; + oridatalen = datalen; + kalMemCopy(dataptr, + local_hqa.hqa_frame_comm.hqa_frame_eth->data, datalen); + + DBGLOG(REQ, LOUD, + "priv_driver_run_hqa datalen is %d\n", datalen); + DBGLOG_MEM8(REQ, LOUD, dataptr, datalen); + + /*parsing ret 2 bytes*/ + if ((dataptr) && (datalen)) { + i2tmpVal = dataptr[1] << 8 | dataptr[0]; + i4BytesWritten = kalSnprintf(pcCommand, i4TotalLen, + "Return : 0x%04x\n", i2tmpVal); + + datalen -= 2; + dataptr += 2; + } else { + DBGLOG(REQ, ERROR, + "priv_driver_run_hqa not support\n"); + kalMemFree(oridataptr, VIR_MEM_TYPE, oridatalen); + return -1; + } + + /*parsing remaining data n bytes ( 4 bytes per parameter)*/ + for (i = 0; i < datalen ; i += 4, dataptr += 4) { + if ((dataptr) && (datalen)) { + i4tmpVal = dataptr[3] << 24 | dataptr[2] << 16 | + dataptr[1] << 8 | dataptr[0]; + if (datalen == 4) { + i4BytesWritten += + kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen, "ExtId : 0x%08x\n", i4tmpVal); + } else if (datalen == 8) { + i4BytesWritten += + kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen, "Band%d TX : 0x%08x\n", i/4, + NTOHL(i4tmpVal)); + } else { + if (IsShowRxStat) { + i += datalen; + i4BytesWritten += + priv_driver_rx_stat_parser(dataptr, + i4TotalLen, pcCommand + i4BytesWritten); + } else { + i4BytesWritten += + kalSnprintf(pcCommand + i4BytesWritten, + i4TotalLen, "id%d : 0x%08x\n", i/4, + NTOHL(i4tmpVal)); + } + } + } + } + kalMemFree(oridataptr, VIR_MEM_TYPE, oridatalen); +#else + DBGLOG(REQ, ERROR, + "wlan_service not support\n"); +#endif + return i4BytesWritten; + +} + +static int priv_driver_calibration( + struct net_device *prNetDev, + char *pcCommand, + int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct mt66xx_chip_info *prChipInfo; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint32_t u4Ret, u4GetInput = 0, u4GetInput2 = 0; + int32_t i4ArgNum = 2; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + prChipInfo = prGlueInfo->prAdapter->chip_info; + + DBGLOG(RFTEST, INFO, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(RFTEST, INFO, "argc is %i\n", i4Argc); + + if (i4Argc >= i4ArgNum) { + u4Ret = kalkStrtou32(apcArgv[1], 0, &u4GetInput); + if (u4Ret) { + DBGLOG(RFTEST, INFO, + "%s: Parsing Fail\n", __func__); + } else if (u4GetInput == 0) { + + i4BytesWritten = kalSnprintf(pcCommand, + i4TotalLen, + "reset driver calibration result\n"); + + if (prChipInfo->calDebugCmd) + prChipInfo->calDebugCmd(u4GetInput, 0); + + } else if (u4GetInput == 1) { + + u4Ret = kalkStrtou32(apcArgv[2], 0, &u4GetInput2); + if (u4Ret) { + DBGLOG(RFTEST, INFO, + "%s: Parsing 2 Fail\n", __func__); + } else if (u4GetInput2 == 0) { + i4BytesWritten = kalSnprintf(pcCommand, + i4TotalLen, + "driver result write back EMI\n"); + } else { + i4BytesWritten = kalSnprintf(pcCommand, + i4TotalLen, + "FW use EMI original data\n"); + } + + if (prChipInfo->calDebugCmd) + prChipInfo->calDebugCmd(u4GetInput, + u4GetInput2); + } + } else { + i4BytesWritten = kalSnprintf(pcCommand, + i4TotalLen, + "support parameter as below:\n"); + + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "0: reset driver calibration result\n"); + + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "1,0: driver result write back EMI\n"); + + i4BytesWritten += kalSnprintf( + pcCommand + i4BytesWritten, + i4TotalLen - i4BytesWritten, + "1,1: FW use EMI original data\n"); + } + + return i4BytesWritten; +} + +static int priv_driver_get_nvram(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = {0}; + uint32_t u4Ret; + int32_t i4ArgNum = 2; + uint32_t u4Offset = 0; + uint16_t u2Index = 0; + struct PARAM_CUSTOM_EEPROM_RW_STRUCT rNvrRwInfo; + struct WIFI_CFG_PARAM_STRUCT *prNvSet; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + kalMemZero(&rNvrRwInfo, sizeof(rNvrRwInfo)); + + prNvSet = prGlueInfo->rRegInfo.prNvramSettings; + ASSERT(prNvSet); + + + DBGLOG(REQ, INFO, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, INFO, "argc is %i\n", i4Argc); + + + if (i4Argc == i4ArgNum) { + u4Ret = kalkStrtou16(apcArgv[1], 0, &u2Index); + + if (u4Ret) + DBGLOG(REQ, INFO, + "parse get_nvram error (Index) u4Ret=%d\n", + u4Ret); + + + DBGLOG(REQ, INFO, "Index is 0x%x\n", u2Index); + + /* NVRAM Check */ + if (prGlueInfo->fgNvramAvailable == TRUE) + u4Offset += snprintf(pcCommand + u4Offset, + (i4TotalLen - u4Offset), + "NVRAM Version is[%d.%d.%d]\n", + (prNvSet->u2Part1OwnVersion & 0x00FF), + (prNvSet->u2Part1OwnVersion & 0xFF00) >> 8, + (prNvSet->u2Part1PeerVersion & 0xFF)); + else { + u4Offset += snprintf(pcCommand + u4Offset, + i4TotalLen - u4Offset, + "[WARNING] NVRAM is unavailable!\n"); + + return (int32_t) u4Offset; + } + + rNvrRwInfo.ucMethod = PARAM_EEPROM_READ_NVRAM; + rNvrRwInfo.info.rNvram.u2NvIndex = u2Index; + + rStatus = kalIoctl(prGlueInfo, wlanoidQueryNvramRead, + &rNvrRwInfo, sizeof(rNvrRwInfo), + TRUE, TRUE, TRUE, &u4BufLen); + + DBGLOG(REQ, INFO, "rStatus %u\n", rStatus); + if (rStatus != WLAN_STATUS_SUCCESS) + return -1; + + u4Offset += snprintf(pcCommand + u4Offset, + (i4TotalLen - u4Offset), + "NVRAM [0x%02X] = %d (0x%02X)\n", + (unsigned int)rNvrRwInfo.info.rNvram.u2NvIndex, + (unsigned int)rNvrRwInfo.info.rNvram.u2NvData, + (unsigned int)rNvrRwInfo.info.rNvram.u2NvData); + + DBGLOG(REQ, INFO, "%s: command result is %s\n", __func__, + pcCommand); + } + + return (int32_t)u4Offset; + +} /* priv_driver_get_nvram */ + +int priv_driver_set_nvram(IN struct net_device *prNetDev, IN char *pcCommand, + IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + uint32_t u4BufLen = 0; + int32_t i4BytesWritten = 0; + int32_t i4Argc = 0; + int8_t *apcArgv[WLAN_CFG_ARGV_MAX] = { 0 }; + uint32_t u4Ret; + int32_t i4ArgNum = 3; + + struct PARAM_CUSTOM_EEPROM_RW_STRUCT rNvRwInfo; + + ASSERT(prNetDev); + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + DBGLOG(REQ, INFO, "command is %s\n", pcCommand); + wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); + DBGLOG(REQ, INFO, "argc is %i\n", i4Argc); + + kalMemZero(&rNvRwInfo, sizeof(rNvRwInfo)); + + if (i4Argc >= i4ArgNum) { + + rNvRwInfo.ucMethod = PARAM_EEPROM_WRITE_NVRAM; + + u4Ret = kalkStrtou16(apcArgv[1], 0, + &(rNvRwInfo.info.rNvram.u2NvIndex)); + if (u4Ret) + DBGLOG(REQ, ERROR, + "parse set_nvram error (Add) Ret=%d\n", + u4Ret); + + u4Ret = kalkStrtou16(apcArgv[2], 0, + &(rNvRwInfo.info.rNvram.u2NvData)); + if (u4Ret) + DBGLOG(REQ, ERROR, + "parse set_nvram error (Data) Ret=%d\n", + u4Ret); + + rStatus = kalIoctl(prGlueInfo, wlanoidSetNvramWrite, + &rNvRwInfo, sizeof(rNvRwInfo), + FALSE, FALSE, TRUE, &u4BufLen); + + if (rStatus != WLAN_STATUS_SUCCESS) + return -1; + + } else + DBGLOG(INIT, ERROR, + "[Error]iwpriv wlanXX driver set_nvram [addr] [value]\n"); + + + return i4BytesWritten; + +} + +typedef int(*PRIV_CMD_FUNCTION) ( + IN struct net_device *prNetDev, + IN char *pcCommand, + IN int i4TotalLen); + +struct PRIV_CMD_HANDLER { + uint8_t *pcCmdStr; + PRIV_CMD_FUNCTION pfHandler; +}; + +struct PRIV_CMD_HANDLER priv_cmd_handlers[] = { + {CMD_RSSI, NULL /*wl_android_get_rssi*/}, + {CMD_AP_START, priv_driver_set_ap_start}, + {CMD_LINKSPEED, priv_driver_get_linkspeed}, + {CMD_PNOSSIDCLR_SET, NULL /*Nothing*/}, + {CMD_PNOSETUP_SET, NULL /*Nothing*/}, + {CMD_PNOENABLE_SET, NULL /*Nothing*/}, + {CMD_SETSUSPENDOPT, NULL /*wl_android_set_suspendopt*/}, + {CMD_SETSUSPENDMODE, priv_driver_set_suspend_mode}, + {CMD_SETBAND, priv_driver_set_band}, + {CMD_GETBAND, NULL /*wl_android_get_band*/}, + {CMD_COUNTRY, priv_driver_set_country}, + {CMD_CSA, priv_driver_set_csa}, + {CMD_GET_COUNTRY, priv_driver_get_country}, + {CMD_GET_CHANNELS, priv_driver_get_channels}, + {CMD_MIRACAST, priv_driver_set_miracast}, + /* Mediatek private command */ + {CMD_SET_SW_CTRL, priv_driver_set_sw_ctrl}, +#if (CFG_SUPPORT_RA_GEN == 1) + {CMD_SET_FIXED_FALLBACK, priv_driver_set_fixed_fallback}, + {CMD_SET_RA_DBG, priv_driver_set_ra_debug_proc}, +#endif +#if (CFG_SUPPORT_TXPOWER_INFO == 1) + {CMD_GET_TX_POWER_INFO, priv_driver_get_txpower_info}, +#endif + {CMD_TX_POWER_MANUAL_SET, priv_driver_txpower_man_set}, + {CMD_SET_FIXED_RATE, priv_driver_set_fixed_rate}, + {CMD_GET_SW_CTRL, priv_driver_get_sw_ctrl}, + {CMD_SET_MCR, priv_driver_set_mcr}, + {CMD_GET_MCR, priv_driver_get_mcr}, + {CMD_SET_DRV_MCR, priv_driver_set_drv_mcr}, + {CMD_GET_DRV_MCR, priv_driver_get_drv_mcr}, + {CMD_SET_TEST_MODE, priv_driver_set_test_mode}, + {CMD_SET_TEST_CMD, priv_driver_set_test_cmd}, + {CMD_GET_TEST_RESULT, priv_driver_get_test_result}, + {CMD_GET_STA_STAT2, priv_driver_get_sta_stat2}, + {CMD_GET_STA_STAT, priv_driver_get_sta_stat}, + {CMD_GET_STA_RX_STAT, priv_driver_show_rx_stat}, + {CMD_SET_ACL_POLICY, priv_driver_set_acl_policy}, + {CMD_ADD_ACL_ENTRY, priv_driver_add_acl_entry}, + {CMD_DEL_ACL_ENTRY, priv_driver_del_acl_entry}, + {CMD_SHOW_ACL_ENTRY, priv_driver_show_acl_entry}, + {CMD_CLEAR_ACL_ENTRY, priv_driver_clear_acl_entry}, +#if (CFG_SUPPORT_DFS_MASTER == 1) + {CMD_SHOW_DFS_STATE, priv_driver_show_dfs_state}, + {CMD_SHOW_DFS_RADAR_PARAM, priv_driver_show_dfs_radar_param}, + {CMD_SHOW_DFS_HELP, priv_driver_show_dfs_help}, + {CMD_SHOW_DFS_CAC_TIME, priv_driver_show_dfs_cac_time}, +#endif +#if CFG_SUPPORT_CAL_RESULT_BACKUP_TO_HOST + {CMD_SET_CALBACKUP_TEST_DRV_FW, priv_driver_set_calbackup_test_drv_fw}, +#endif +#if CFG_WOW_SUPPORT + {CMD_WOW_START, priv_driver_set_wow}, + {CMD_SET_WOW_ENABLE, priv_driver_set_wow_enable}, + {CMD_SET_WOW_PAR, priv_driver_set_wow_par}, + {CMD_SET_WOW_UDP, priv_driver_set_wow_udpport}, + {CMD_SET_WOW_TCP, priv_driver_set_wow_tcpport}, + {CMD_GET_WOW_PORT, priv_driver_get_wow_port}, +#endif + {CMD_SET_ADV_PWS, priv_driver_set_adv_pws}, + {CMD_SET_MDTIM, priv_driver_set_mdtim}, +#if CFG_SUPPORT_QA_TOOL + {CMD_GET_RX_STATISTICS, priv_driver_get_rx_statistics}, +#if CFG_SUPPORT_BUFFER_MODE + {CMD_SETBUFMODE, priv_driver_set_efuse_buffer_mode}, +#endif +#endif +#if CFG_SUPPORT_MSP +#if 0 + {CMD_GET_STAT, priv_driver_get_stat}, +#endif + {CMD_GET_STA_STATISTICS, priv_driver_get_sta_statistics}, + {CMD_GET_BSS_STATISTICS, priv_driver_get_bss_statistics}, + {CMD_GET_STA_IDX, priv_driver_get_sta_index}, + {CMD_GET_STA_INFO, priv_driver_get_sta_info}, + {CMD_GET_WTBL_INFO, priv_driver_get_wtbl_info}, + {CMD_GET_MIB_INFO, priv_driver_get_mib_info}, + {CMD_SET_FW_LOG, priv_driver_set_fw_log}, +#endif + {CMD_SET_CFG, priv_driver_set_cfg}, + {CMD_GET_CFG, priv_driver_get_cfg}, + {CMD_SET_EM_CFG, priv_driver_set_em_cfg}, + {CMD_GET_EM_CFG, priv_driver_get_em_cfg}, + {CMD_SET_CHIP, priv_driver_set_chip_config}, + {CMD_GET_CHIP, priv_driver_get_chip_config}, + {CMD_GET_VERSION, priv_driver_get_version}, + {CMD_GET_CNM, priv_driver_get_cnm}, + {CMD_GET_CAPAB_RSDB, priv_driver_get_capab_rsdb}, +#if CFG_SUPPORT_DBDC + {CMD_SET_DBDC, priv_driver_set_dbdc}, +#endif /*CFG_SUPPORT_DBDC*/ +#if CFG_SUPPORT_SNIFFER + {CMD_SETMONITOR, priv_driver_set_monitor}, +#endif + {CMD_GET_QUE_INFO, priv_driver_get_que_info}, + {CMD_GET_MEM_INFO, priv_driver_get_mem_info}, + {CMD_GET_HIF_INFO, priv_driver_get_hif_info}, + {CMD_GET_TP_INFO, priv_driver_get_tp_info}, + {CMD_GET_CH_RANK_LIST, priv_driver_get_ch_rank_list}, + {CMD_GET_CH_DIRTINESS, priv_driver_get_ch_dirtiness}, + {CMD_EFUSE, priv_driver_efuse_ops}, +#if defined(_HIF_SDIO) && (MTK_WCN_HIF_SDIO == 0) + {CMD_CCCR, priv_driver_cccr_ops}, +#endif /* _HIF_SDIO && (MTK_WCN_HIF_SDIO == 0) */ +#if CFG_SUPPORT_ADVANCE_CONTROL + {CMD_SET_NOISE, priv_driver_set_noise}, + {CMD_GET_NOISE, priv_driver_get_noise}, + {CMD_SET_POP, priv_driver_set_pop}, + {CMD_SET_ED, priv_driver_set_ed}, + {CMD_SET_PD, priv_driver_set_pd}, + {CMD_SET_MAX_RFGAIN, priv_driver_set_maxrfgain}, +#endif + {CMD_SET_DRV_SER, priv_driver_set_drv_ser}, + {CMD_SET_SW_AMSDU_NUM, priv_driver_set_amsdu_num}, + {CMD_SET_SW_AMSDU_SIZE, priv_driver_set_amsdu_size}, +#if CFG_ENABLE_WIFI_DIRECT + {CMD_P2P_SET_PS, priv_driver_set_p2p_ps}, + {CMD_P2P_SET_NOA, priv_driver_set_p2p_noa}, +#endif +#ifdef UT_TEST_MODE + {CMD_RUN_UT, priv_driver_run_ut}, +#endif /* UT_TEST_MODE */ + {CMD_GET_WIFI_TYPE, priv_driver_get_wifi_type}, +#if CFG_SUPPORT_DYNAMIC_PWR_LIMIT + {CMD_SET_PWR_CTRL, priv_driver_set_power_control}, +#endif +#if (CFG_SUPPORT_CONNINFRA == 1) + {CMD_SET_WHOLE_CHIP_RESET, priv_driver_trigger_whole_chip_reset}, + {CMD_SET_WFSYS_RESET, priv_driver_trigger_wfsys_reset}, +#endif +#if (CFG_SUPPORT_CONNAC2X == 1) + {CMD_GET_FWTBL_UMAC, priv_driver_get_umac_fwtbl}, +#endif /* CFG_SUPPORT_CONNAC2X == 1 */ + {CMD_SHOW_TXD_INFO, priv_driver_show_txd_info}, + {CMD_GET_MU_RX_PKTCNT, priv_driver_show_rx_stat}, + {CMD_RUN_HQA, priv_driver_run_hqa}, + {CMD_CALIBRATION, priv_driver_calibration}, + {CMD_SET_STA1NSS, priv_driver_set_sta1ss}, + {CMD_SET_NVRAM, priv_driver_set_nvram}, + {CMD_GET_NVRAM, priv_driver_get_nvram}, +}; + +int32_t priv_driver_cmds(IN struct net_device *prNetDev, IN int8_t *pcCommand, + IN int32_t i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t i4BytesWritten = 0; + int32_t i4CmdFound = 0; + int i; + + if (g_u4HaltFlag) { + DBGLOG(REQ, WARN, "wlan is halt, skip priv_driver_cmds\n"); + return -1; + } + + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + return -1; + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + + for (i = 0; i < sizeof(priv_cmd_handlers) / sizeof(struct + PRIV_CMD_HANDLER); i++) { + if (strnicmp(pcCommand, + priv_cmd_handlers[i].pcCmdStr, + strlen(priv_cmd_handlers[i].pcCmdStr)) == 0) { + + if (priv_cmd_handlers[i].pfHandler != NULL) { + i4BytesWritten = + priv_cmd_handlers[i].pfHandler( + prNetDev, + pcCommand, + i4TotalLen); + i4CmdFound = 1; + } + } + } + + if (i4CmdFound == 0) { + i4CmdFound = 1; + if (strnicmp(pcCommand, CMD_RSSI, strlen(CMD_RSSI)) == 0) { + /* i4BytesWritten = + * wl_android_get_rssi(net, command, i4TotalLen); + */ +#if CFG_SUPPORT_BATCH_SCAN + } else if (strnicmp(pcCommand, CMD_BATCH_SET, + strlen(CMD_BATCH_SET)) == 0) { + kalIoctl(prGlueInfo, wlanoidSetBatchScanReq, + (void *) pcCommand, i4TotalLen, + FALSE, FALSE, TRUE, &i4BytesWritten); + } else if (strnicmp(pcCommand, CMD_BATCH_GET, + strlen(CMD_BATCH_GET)) == 0) { + /* strcpy(pcCommand, "BATCH SCAN DATA FROM FIRMWARE"); + */ + /* i4BytesWritten = + * strlen("BATCH SCAN DATA FROM FIRMWARE") + * + 1; + */ + /* i4BytesWritten = priv_driver_get_linkspeed (prNetDev, + * pcCommand, i4TotalLen); + */ + + uint32_t u4BufLen; + int i; + /* int rlen=0; */ + + for (i = 0; i < CFG_BATCH_MAX_MSCAN; i++) { + /* for get which mscan */ + g_rEventBatchResult[i].ucScanCount = i + 1; + + kalIoctl(prGlueInfo, + wlanoidQueryBatchScanResult, + (void *)&g_rEventBatchResult[i], + sizeof(struct EVENT_BATCH_RESULT), + TRUE, TRUE, TRUE, &u4BufLen); + } + +#if 0 + DBGLOG(SCN, INFO, + "Batch Scan Results, scan count = %u\n", + g_rEventBatchResult.ucScanCount); + for (i = 0; i < g_rEventBatchResult.ucScanCount; i++) { + prEntry = &g_rEventBatchResult.arBatchResult[i]; + DBGLOG(SCN, INFO, "Entry %u\n", i); + DBGLOG(SCN, INFO, " BSSID = " MACSTR "\n", + MAC2STR(prEntry->aucBssid)); + DBGLOG(SCN, INFO, " SSID = %s\n", + prEntry->aucSSID); + DBGLOG(SCN, INFO, " SSID len = %u\n", + prEntry->ucSSIDLen); + DBGLOG(SCN, INFO, " RSSI = %d\n", + prEntry->cRssi); + DBGLOG(SCN, INFO, " Freq = %u\n", + prEntry->ucFreq); + } +#endif + + batchConvertResult(&g_rEventBatchResult[0], pcCommand, + i4TotalLen, &i4BytesWritten); + + /* Dump for debug */ + /* print_hex_dump(KERN_INFO, + * "BATCH", DUMP_PREFIX_ADDRESS, 16, 1, pcCommand, + * i4BytesWritten, TRUE); + */ + + } else if (strnicmp(pcCommand, CMD_BATCH_STOP, + strlen(CMD_BATCH_STOP)) == 0) { + kalIoctl(prGlueInfo, wlanoidSetBatchScanReq, + (void *) pcCommand, i4TotalLen, + FALSE, FALSE, TRUE, &i4BytesWritten); +#endif + } +#if CFG_SUPPORT_WIFI_SYSDVT + else if (strnicmp(pcCommand, CMD_SET_TXS_TEST, + strlen(CMD_SET_TXS_TEST)) == 0) + i4BytesWritten = + priv_driver_txs_test(prNetDev, pcCommand, i4TotalLen); + else if (strnicmp(pcCommand, CMD_SET_TXS_TEST_RESULT, + strlen(CMD_SET_TXS_TEST_RESULT)) == 0) + i4BytesWritten = + priv_driver_txs_test_result(prNetDev, + pcCommand, i4TotalLen); + else if (strnicmp(pcCommand, CMD_SET_RXV_TEST, + strlen(CMD_SET_RXV_TEST)) == 0) + i4BytesWritten = + priv_driver_rxv_test(prNetDev, pcCommand, i4TotalLen); + else if (strnicmp(pcCommand, CMD_SET_RXV_TEST_RESULT, + strlen(CMD_SET_RXV_TEST_RESULT)) == 0) + i4BytesWritten = + priv_driver_rxv_test_result(prNetDev, + pcCommand, i4TotalLen); +#if CFG_TCP_IP_CHKSUM_OFFLOAD + else if (strnicmp(pcCommand, CMD_SET_CSO_TEST, + strlen(CMD_SET_CSO_TEST)) == 0) + i4BytesWritten = + priv_driver_cso_test(prNetDev, pcCommand, i4TotalLen); +#endif + else if (strnicmp(pcCommand, CMD_SET_TX_AC_TEST, + strlen(CMD_SET_TX_AC_TEST)) == 0) + i4BytesWritten = + priv_driver_set_tx_test_ac(prNetDev, + pcCommand, i4TotalLen); + else if (strnicmp(pcCommand, CMD_SET_TX_TEST, + strlen(CMD_SET_TX_TEST)) == 0) + i4BytesWritten = + priv_driver_set_tx_test(prNetDev, + pcCommand, i4TotalLen); + else if (strnicmp(pcCommand, CMD_SET_SKIP_CH_CHECK, + strlen(CMD_SET_SKIP_CH_CHECK)) == 0) + i4BytesWritten = + priv_driver_skip_legal_ch_check(prNetDev, + pcCommand, i4TotalLen); +#if (CFG_SUPPORT_DMASHDL_SYSDVT) + else if (strnicmp(pcCommand, CMD_SET_DMASHDL_DUMP, + strlen(CMD_SET_DMASHDL_DUMP)) == 0) + i4BytesWritten = + priv_driver_show_dmashdl_allcr(prNetDev, + pcCommand, i4TotalLen); + else if (strnicmp(pcCommand, CMD_SET_DMASHDL_DVT_ITEM, + strlen(CMD_SET_DMASHDL_DVT_ITEM)) == 0) + i4BytesWritten = + priv_driver_dmashdl_dvt_item(prNetDev, + pcCommand, i4TotalLen); +#endif /* CFG_SUPPORT_DMASHDL_SYSDVT */ +#endif /* CFG_SUPPORT_WIFI_SYSDVT */ + else if (strnicmp(pcCommand, CMD_DBG_SHOW_TR_INFO, + strlen(CMD_DBG_SHOW_TR_INFO)) == 0) { + kalIoctl(prGlueInfo, + wlanoidShowPdmaInfo, + (void *) pcCommand, i4TotalLen, + FALSE, FALSE, TRUE, &i4BytesWritten); + } else if (strnicmp(pcCommand, CMD_DBG_SHOW_PLE_INFO, + strlen(CMD_DBG_SHOW_PLE_INFO)) == 0) { + kalIoctl(prGlueInfo, + wlanoidShowPleInfo, + (void *) pcCommand, i4TotalLen, + FALSE, FALSE, TRUE, &i4BytesWritten); + } else if (strnicmp(pcCommand, CMD_DBG_SHOW_PSE_INFO, + strlen(CMD_DBG_SHOW_PSE_INFO)) == 0) { + kalIoctl(prGlueInfo, + wlanoidShowPseInfo, + (void *) pcCommand, i4TotalLen, + FALSE, FALSE, TRUE, &i4BytesWritten); + } else if (strnicmp(pcCommand, CMD_DBG_SHOW_CSR_INFO, + strlen(CMD_DBG_SHOW_CSR_INFO)) == 0) { + kalIoctl(prGlueInfo, + wlanoidShowCsrInfo, + (void *) pcCommand, i4TotalLen, + FALSE, FALSE, TRUE, &i4BytesWritten); + } else if (strnicmp(pcCommand, CMD_DBG_SHOW_DMASCH_INFO, + strlen(CMD_DBG_SHOW_DMASCH_INFO)) == 0) { + kalIoctl(prGlueInfo, + wlanoidShowDmaschInfo, + (void *) pcCommand, i4TotalLen, + FALSE, FALSE, TRUE, &i4BytesWritten); +#if CFG_SUPPORT_EASY_DEBUG + } else if (strnicmp(pcCommand, CMD_FW_PARAM, + strlen(CMD_FW_PARAM)) == 0) { + kalIoctl(prGlueInfo, wlanoidSetFwParam, + (void *)(pcCommand + 13), + i4TotalLen - 13, FALSE, FALSE, FALSE, + &i4BytesWritten); +#endif /* CFG_SUPPORT_EASY_DEBUG */ + } else if (strnicmp(pcCommand, CMD_GET_WFDMA_INFO, + strlen(CMD_GET_WFDMA_INFO)) == 0) { + kalIoctl(prGlueInfo, + wlanoidShowPdmaInfo, + (void *) pcCommand, i4TotalLen, + FALSE, FALSE, TRUE, &i4BytesWritten); + } else if (strnicmp(pcCommand, CMD_GET_PLE_INFO, + strlen(CMD_GET_PLE_INFO)) == 0) { + kalIoctl(prGlueInfo, + wlanoidShowPleInfo, + (void *) pcCommand, i4TotalLen, + FALSE, FALSE, TRUE, &i4BytesWritten); + } else if (strnicmp(pcCommand, CMD_GET_PSE_INFO, + strlen(CMD_GET_PSE_INFO)) == 0) { + kalIoctl(prGlueInfo, + wlanoidShowPseInfo, + (void *) pcCommand, i4TotalLen, + FALSE, FALSE, TRUE, &i4BytesWritten); + } else if (strnicmp(pcCommand, CMD_GET_DMASCH_INFO, + strlen(CMD_GET_DMASCH_INFO)) == 0) { + kalIoctl(prGlueInfo, + wlanoidShowDmaschInfo, + (void *) pcCommand, i4TotalLen, + FALSE, FALSE, TRUE, &i4BytesWritten); + } else if (!strnicmp(pcCommand, CMD_DUMP_TS, + strlen(CMD_DUMP_TS)) || + !strnicmp(pcCommand, CMD_ADD_TS, + strlen(CMD_ADD_TS)) || + !strnicmp(pcCommand, CMD_DEL_TS, + strlen(CMD_DEL_TS))) { + kalIoctl(prGlueInfo, wlanoidTspecOperation, + (void *)pcCommand, i4TotalLen, FALSE, FALSE, + FALSE, &i4BytesWritten); + } else if (kalStrStr(pcCommand, "-IT")) { + kalIoctl(prGlueInfo, wlanoidPktProcessIT, + (void *)pcCommand, i4TotalLen, FALSE, FALSE, + FALSE, &i4BytesWritten); + } else if (!strnicmp(pcCommand, CMD_FW_EVENT, 9)) { + kalIoctl(prGlueInfo, wlanoidFwEventIT, + (void *)(pcCommand + 9), i4TotalLen, FALSE, + FALSE, FALSE, &i4BytesWritten); + } else if (!strnicmp(pcCommand, CMD_DUMP_UAPSD, + strlen(CMD_DUMP_UAPSD))) { + kalIoctl(prGlueInfo, wlanoidDumpUapsdSetting, + (void *)pcCommand, i4TotalLen, FALSE, FALSE, + FALSE, &i4BytesWritten); +#if CFG_SUPPORT_DYNAMIC_PWR_LIMIT + } else if (strnicmp(pcCommand, CMD_SET_PWR_CTRL, + strlen(CMD_SET_PWR_CTRL)) == 0) { + priv_driver_set_power_control(prNetDev, + pcCommand, i4TotalLen); +#endif + } else if (strnicmp(pcCommand, CMD_SET_BF, + strlen(CMD_SET_BF)) == 0) { + i4BytesWritten = priv_driver_set_bf(prNetDev, + pcCommand, i4TotalLen); + } else if (strnicmp(pcCommand, CMD_SET_NSS, + strlen(CMD_SET_NSS)) == 0) { + i4BytesWritten = priv_driver_set_nss(prNetDev, + pcCommand, i4TotalLen); + } else if (strnicmp(pcCommand, CMD_SET_AMSDU_TX, + strlen(CMD_SET_AMSDU_TX)) == 0) { + i4BytesWritten = priv_driver_set_amsdu_tx(prNetDev, + pcCommand, i4TotalLen); + } else if (strnicmp(pcCommand, CMD_SET_AMSDU_RX, + strlen(CMD_SET_AMSDU_RX)) == 0) { + i4BytesWritten = priv_driver_set_amsdu_rx(prNetDev, + pcCommand, i4TotalLen); + } else if (strnicmp(pcCommand, CMD_SET_AMPDU_TX, + strlen(CMD_SET_AMPDU_TX)) == 0) { + i4BytesWritten = priv_driver_set_ampdu_tx(prNetDev, + pcCommand, i4TotalLen); + } else if (strnicmp(pcCommand, CMD_SET_AMPDU_RX, + strlen(CMD_SET_AMPDU_RX)) == 0) { + i4BytesWritten = priv_driver_set_ampdu_rx(prNetDev, + pcCommand, i4TotalLen); + } else if (strnicmp(pcCommand, CMD_SET_QOS, + strlen(CMD_SET_QOS)) == 0) { + i4BytesWritten = priv_driver_set_qos(prNetDev, + pcCommand, i4TotalLen); +#if (CFG_SUPPORT_802_11AX == 1) + } else if (strnicmp(pcCommand, CMD_SET_MUEDCA_OVERRIDE, + strlen(CMD_SET_MUEDCA_OVERRIDE)) == 0) { + i4BytesWritten = priv_driver_muedca_override(prNetDev, + pcCommand, i4TotalLen); + } else if (strnicmp(pcCommand, CMD_SET_BA_SIZE, + strlen(CMD_SET_BA_SIZE)) == 0) { + i4BytesWritten = priv_driver_set_ba_size(prNetDev, + pcCommand, i4TotalLen); + } else if (strnicmp(pcCommand, CMD_SET_TP_TEST_MODE, + strlen(CMD_SET_TP_TEST_MODE)) == 0) { + i4BytesWritten = priv_driver_set_tp_test_mode(prNetDev, + pcCommand, i4TotalLen); + } else if (strnicmp(pcCommand, CMD_SET_TX_MCSMAP, + strlen(CMD_SET_TX_MCSMAP)) == 0) { + i4BytesWritten = priv_driver_set_mcsmap(prNetDev, + pcCommand, i4TotalLen); + } else if (strnicmp(pcCommand, CMD_SET_TX_PPDU, + strlen(CMD_SET_TX_PPDU)) == 0) { + i4BytesWritten = priv_driver_set_tx_ppdu(prNetDev, + pcCommand, i4TotalLen); + } else if (strnicmp(pcCommand, CMD_SET_LDPC, + strlen(CMD_SET_LDPC)) == 0) { + i4BytesWritten = priv_driver_set_ldpc(prNetDev, + pcCommand, i4TotalLen); + } else if (strnicmp(pcCommand, CMD_FORCE_AMSDU_TX, + strlen(CMD_FORCE_AMSDU_TX)) == 0) { + i4BytesWritten = priv_driver_set_tx_force_amsdu( + prNetDev, pcCommand, i4TotalLen); + } else if (strnicmp(pcCommand, CMD_SET_OM_CH_BW, + strlen(CMD_SET_OM_CH_BW)) == 0) { + i4BytesWritten = priv_driver_set_om_ch_bw(prNetDev, + pcCommand, i4TotalLen); + } else if (strnicmp(pcCommand, CMD_SET_OM_RX_NSS, + strlen(CMD_SET_OM_RX_NSS)) == 0) { + i4BytesWritten = priv_driver_set_om_rx_nss(prNetDev, + pcCommand, i4TotalLen); + } else if (strnicmp(pcCommand, CMD_SET_OM_TX_NSS, + strlen(CMD_SET_OM_TX_NSS)) == 0) { + i4BytesWritten = priv_driver_set_om_tx_nss(prNetDev, + pcCommand, i4TotalLen); + } else if (strnicmp(pcCommand, CMD_SET_OM_MU_DISABLE, + strlen(CMD_SET_OM_MU_DISABLE)) == 0) { + i4BytesWritten = priv_driver_set_om_mu_dis(prNetDev, + pcCommand, i4TotalLen); + } else if (strnicmp(pcCommand, CMD_SET_TX_OM_PACKET, + strlen(CMD_SET_TX_OM_PACKET)) == 0) { + i4BytesWritten = priv_driver_set_tx_om_packet(prNetDev, + pcCommand, i4TotalLen); + } else if (strnicmp(pcCommand, CMD_SET_TX_CCK_1M_PWR, + strlen(CMD_SET_TX_CCK_1M_PWR)) == 0) { + i4BytesWritten = priv_driver_set_tx_cck_1m_pwr(prNetDev, + pcCommand, i4TotalLen); + } else if (strnicmp(pcCommand, CMD_SET_PAD_DUR, + strlen(CMD_SET_PAD_DUR)) == 0) { + i4BytesWritten = priv_driver_set_pad_dur(prNetDev, + pcCommand, i4TotalLen); +#endif + +#if CFG_CHIP_RESET_HANG + } else if (strnicmp(pcCommand, CMD_SET_RST_HANG, + strlen(CMD_SET_RST_HANG)) == 0) { + i4BytesWritten = priv_driver_set_rst_hang( + prNetDev, pcCommand, i4TotalLen); +#endif + +#if (CFG_SUPPORT_TWT == 1) + } else if (strnicmp(pcCommand, CMD_SET_TWT_PARAMS, + strlen(CMD_SET_TWT_PARAMS)) == 0) { + i4BytesWritten = priv_driver_set_twtparams(prNetDev, + pcCommand, i4TotalLen); +#endif + } else + i4BytesWritten = priv_cmd_not_support + (prNetDev, pcCommand, i4TotalLen); + } + + if (i4BytesWritten >= 0) { + if ((i4BytesWritten == 0) && (i4TotalLen > 0)) { + /* reset the command buffer */ + pcCommand[0] = '\0'; + } + + if (i4BytesWritten >= i4TotalLen) { + DBGLOG(REQ, INFO, + "%s: i4BytesWritten %d > i4TotalLen < %d\n", + __func__, i4BytesWritten, i4TotalLen); + i4BytesWritten = i4TotalLen - 1; + } + pcCommand[i4BytesWritten] = '\0'; + i4BytesWritten++; + + } + + return i4BytesWritten; + +} /* priv_driver_cmds */ + +#ifdef CFG_ANDROID_AOSP_PRIV_CMD +int android_private_support_driver_cmd(IN struct net_device *prNetDev, + IN OUT struct ifreq *prReq, IN int i4Cmd) +{ + struct android_wifi_priv_cmd priv_cmd; + char *command = NULL; + int ret = 0, bytes_written = 0; + + if (!prReq->ifr_data) + return -EINVAL; + + if (copy_from_user(&priv_cmd, prReq->ifr_data, sizeof(priv_cmd))) + return -EFAULT; + /* total_len is controlled by the user. need check length */ + if (priv_cmd.total_len <= 0) + return -EINVAL; + + command = kzalloc(priv_cmd.total_len, GFP_KERNEL); + if (!command) { + DBGLOG(REQ, WARN, "%s, alloc mem failed\n", __func__); + return -ENOMEM; + } + + if (copy_from_user(command, priv_cmd.buf, priv_cmd.total_len)) { + ret = -EFAULT; + goto FREE; + } + + bytes_written = priv_driver_cmds(prNetDev, command, priv_cmd.total_len); + + if (bytes_written == -EOPNOTSUPP) { + /* Report positive status */ + bytes_written = kalSnprintf(command, priv_cmd.total_len, + "%s", "NotSupport"); + } + + if (bytes_written >= 0) { + /* priv_cmd in but no response */ + if ((bytes_written == 0) && (priv_cmd.total_len > 0)) + command[0] = '\0'; + + if (bytes_written >= priv_cmd.total_len) + bytes_written = priv_cmd.total_len; + else + bytes_written++; + + priv_cmd.used_len = bytes_written; + + if (copy_to_user(priv_cmd.buf, command, bytes_written)) + ret = -EFAULT; + } else + ret = bytes_written; + +FREE: + kfree(command); + + return ret; +} +#endif /* CFG_ANDROID_AOSP_PRIV_CMD */ + +int priv_support_driver_cmd(IN struct net_device *prNetDev, + IN OUT struct ifreq *prReq, IN int i4Cmd) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int ret = 0; + char *pcCommand = NULL; + struct priv_driver_cmd_s *priv_cmd = NULL; + int i4BytesWritten = 0; + int i4TotalLen = 0; + + if (!prReq->ifr_data) { + ret = -EINVAL; + goto exit; + } + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + if (!prGlueInfo) { + DBGLOG(REQ, WARN, "No glue info\n"); + ret = -EFAULT; + goto exit; + } + if (prGlueInfo->u4ReadyFlag == 0) { + ret = -EINVAL; + goto exit; + } + + priv_cmd = kzalloc(sizeof(struct priv_driver_cmd_s), GFP_KERNEL); + if (!priv_cmd) { + DBGLOG(REQ, WARN, "%s, alloc mem failed\n", __func__); + return -ENOMEM; + } + + if (copy_from_user(priv_cmd, prReq->ifr_data, + sizeof(struct priv_driver_cmd_s))) { + DBGLOG(REQ, INFO, "%s: copy_from_user fail\n", __func__); + ret = -EFAULT; + goto exit; + } + + i4TotalLen = priv_cmd->total_len; + + if (i4TotalLen <= 0 || i4TotalLen > PRIV_CMD_SIZE) { + ret = -EINVAL; + DBGLOG(REQ, INFO, "%s: i4TotalLen invalid\n", __func__); + goto exit; + } + priv_cmd->buf[PRIV_CMD_SIZE - 1] = '\0'; + pcCommand = priv_cmd->buf; + + DBGLOG(REQ, INFO, "%s: driver cmd \"%s\" on %s\n", __func__, pcCommand, + prReq->ifr_name); + + i4BytesWritten = priv_driver_cmds(prNetDev, pcCommand, i4TotalLen); + + if (i4BytesWritten == -EOPNOTSUPP) { + /* Report positive status */ + i4BytesWritten = kalSnprintf(pcCommand, i4TotalLen, + "%s", "UNSUPPORTED"); + i4BytesWritten++; + } + + if (i4BytesWritten >= 0) { + priv_cmd->used_len = i4BytesWritten; + if ((i4BytesWritten == 0) && (priv_cmd->total_len > 0)) + pcCommand[0] = '\0'; + if (i4BytesWritten >= priv_cmd->total_len) + i4BytesWritten = priv_cmd->total_len; + else + i4BytesWritten++; + priv_cmd->used_len = i4BytesWritten; + if (copy_to_user(prReq->ifr_data, priv_cmd, + sizeof(struct priv_driver_cmd_s))) { + ret = -EFAULT; + DBGLOG(REQ, INFO, "copy fail"); + } + } else + ret = i4BytesWritten; + +exit: + kfree(priv_cmd); + + return ret; +} /* priv_support_driver_cmd */ + +#if CFG_SUPPORT_DYNAMIC_PWR_LIMIT +/* dynamic tx power control */ +static int priv_driver_set_power_control(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct PARAM_TX_PWR_CTRL_IOCTL rPwrCtrlParam = { 0 }; + u_int8_t fgIndex = FALSE; + char *ptr = pcCommand, *ptr2 = NULL; + char *str = NULL, *cmd = NULL, *name = NULL, *setting = NULL; + uint8_t index = 0; + uint32_t u4SetInfoLen = 0; + + while ((str = strsep(&ptr, " ")) != NULL) { + if (kalStrLen(str) <= 0) + continue; + if (cmd == NULL) + cmd = str; + else if (name == NULL) + name = str; + else if (fgIndex == FALSE) { + ptr2 = str; + if (kalkStrtou8(str, 0, &index) != 0) { + DBGLOG(REQ, INFO, + "index is wrong: %s\n", ptr2); + return -1; + } + fgIndex = TRUE; + } else if (setting == NULL) { + setting = str; + break; + } + } + + if ((name == NULL) || (fgIndex == FALSE)) { + DBGLOG(REQ, INFO, "name(%s) or fgIndex(%d) is wrong\n", + name, fgIndex); + return -1; + } + + rPwrCtrlParam.fgApplied = (index == 0) ? FALSE : TRUE; + rPwrCtrlParam.name = name; + rPwrCtrlParam.index = index; + rPwrCtrlParam.newSetting = setting; + + DBGLOG(REQ, INFO, "applied=[%d], name=[%s], index=[%u], setting=[%s]\n", + rPwrCtrlParam.fgApplied, + rPwrCtrlParam.name, + rPwrCtrlParam.index, + rPwrCtrlParam.newSetting); + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prNetDev)); + kalIoctl(prGlueInfo, + wlanoidTxPowerControl, + (void *)&rPwrCtrlParam, + sizeof(struct PARAM_TX_PWR_CTRL_IOCTL), + FALSE, + FALSE, + TRUE, + &u4SetInfoLen); + + return 0; +} +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/axi/axi.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/axi/axi.c new file mode 100644 index 0000000000000000000000000000000000000000..d3ae96db222b771799c5581752e5fd3b6d2b3478 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/axi/axi.c @@ -0,0 +1,1590 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/****************************************************************************** + *[File] axi.c + *[Version] v1.0 + *[Revision Date] 2010-03-01 + *[Author] + *[Description] + * The program provides AXI HIF driver + *[Copyright] + * Copyright (C) 2010 MediaTek Incorporation. All Rights Reserved. + ******************************************************************************/ + + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +#include "gl_os.h" + +#include "hif_pdma.h" + +#include "precomp.h" + +#include +#include +#include +#include +#ifndef CONFIG_X86 +#include +#endif +#include +#include + +#include "mt66xx_reg.h" + +#include +#include +#include + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +static const struct platform_device_id mtk_axi_ids[] = { + { .name = "CONNAC", +#ifdef CONNAC + .driver_data = (kernel_ulong_t)&mt66xx_driver_data_connac}, +#endif /* CONNAC */ +#ifdef CONNAC2X2 + .driver_data = (kernel_ulong_t)&mt66xx_driver_data_connac2x2}, +#endif /* CONNAC2X2 */ +#ifdef SOC3_0 + .driver_data = (kernel_ulong_t)&mt66xx_driver_data_soc3_0}, +#endif /* SOC3_0 */ + + { /* end: all zeroes */ }, +}; + +MODULE_DEVICE_TABLE(axi, mtk_axi_ids); + +#ifdef CONFIG_OF +const struct of_device_id mtk_axi_of_ids[] = { + {.compatible = "mediatek,wifi",}, + {} +}; +#endif + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ +static probe_card pfWlanProbe; +static remove_card pfWlanRemove; + +static struct platform_driver mtk_axi_driver = { + .driver = { + .name = "wlan", + .owner = THIS_MODULE, +#ifdef CONFIG_OF + .of_match_table = mtk_axi_of_ids, +#endif + }, + .id_table = mtk_axi_ids, + .probe = NULL, + .remove = NULL, +}; + +struct platform_device *g_prPlatDev; + +static struct GLUE_INFO *g_prGlueInfo; +static void *CSRBaseAddress; +static u64 g_u8CsrOffset; +static u32 g_u4CsrSize; +static u_int8_t g_fgDriverProbed = FALSE; + +#if AXI_CFG_PREALLOC_MEMORY_BUFFER +struct HIF_PREALLOC_MEM grMem; +unsigned long long gWifiRsvMemSize; + +struct wifi_rsrv_mem { + phys_addr_t phy_base; + void *vir_base; + unsigned long long size; +}; + +/* Assume reserved memory size < BIT(32) */ +static struct wifi_rsrv_mem wifi_rsrv_mems[32]; +#endif + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +#if AXI_CFG_PREALLOC_MEMORY_BUFFER +static int _init_resv_mem(struct platform_device *pdev); + +static void axiAllocTxDesc(struct GL_HIF_INFO *prHifInfo, + struct RTMP_DMABUF *prDescRing, + uint32_t u4Num); +static void axiAllocRxDesc(struct GL_HIF_INFO *prHifInfo, + struct RTMP_DMABUF *prDescRing, + uint32_t u4Num); +static bool axiAllocTxCmdBuf(struct RTMP_DMABUF *prDmaBuf, + uint32_t u4Num, uint32_t u4Idx); +#else +static void axiAllocDesc(struct GL_HIF_INFO *prHifInfo, + struct RTMP_DMABUF *prDescRing, + uint32_t u4Num); +static void *axiAllocRuntimeMem(uint32_t u4SrcLen); +static phys_addr_t axiMapTxBuf(struct GL_HIF_INFO *prHifInfo, + void *pucBuf, uint32_t u4Offset, uint32_t u4Len); +static phys_addr_t axiMapRxBuf(struct GL_HIF_INFO *prHifInfo, + void *pucBuf, uint32_t u4Offset, uint32_t u4Len); +static void axiUnmapTxBuf(struct GL_HIF_INFO *prHifInfo, + phys_addr_t rDmaAddr, uint32_t u4Len); +static void axiUnmapRxBuf(struct GL_HIF_INFO *prHifInfo, + phys_addr_t rDmaAddr, uint32_t u4Len); +static void axiFreeDesc(struct GL_HIF_INFO *prHifInfo, + struct RTMP_DMABUF *prDescRing); +static void axiFreeBuf(void *pucSrc, uint32_t u4Len); +static void axiFreePacket(void *pvPacket); +#endif /* AXI_CFG_PREALLOC_MEMORY_BUFFER */ + +static void axiAllocTxDataBuf(struct MSDU_TOKEN_ENTRY *prToken, uint32_t u4Idx); +static void *axiAllocRxBuf(struct GL_HIF_INFO *prHifInfo, + struct RTMP_DMABUF *prDmaBuf, + uint32_t u4Num, uint32_t u4Idx); +static bool axiCopyCmd(struct GL_HIF_INFO *prHifInfo, + struct RTMP_DMACB *prTxCell, void *pucBuf, + void *pucSrc1, uint32_t u4SrcLen1, + void *pucSrc2, uint32_t u4SrcLen2); +static bool axiCopyEvent(struct GL_HIF_INFO *prHifInfo, + struct RTMP_DMACB *pRxCell, + struct RXD_STRUCT *pRxD, + struct RTMP_DMABUF *prDmaBuf, + uint8_t *pucDst, uint32_t u4Len); +static bool axiCopyTxData(struct MSDU_TOKEN_ENTRY *prToken, + void *pucSrc, uint32_t u4Len); +static bool axiCopyRxData(struct GL_HIF_INFO *prHifInfo, + struct RTMP_DMACB *pRxCell, + struct RTMP_DMABUF *prDmaBuf, + struct SW_RFB *prSwRfb); +static void axiDumpTx(struct GL_HIF_INFO *prHifInfo, + struct RTMP_TX_RING *prTxRing, + uint32_t u4Idx, uint32_t u4DumpLen); +static void axiDumpRx(struct GL_HIF_INFO *prHifInfo, + struct RTMP_RX_RING *prRxRing, + uint32_t u4Idx, uint32_t u4DumpLen); + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +static struct mt66xx_hif_driver_data *get_platform_driver_data(void) +{ + ASSERT(g_prPlatDev); + if (!g_prPlatDev) + return NULL; + + return (struct mt66xx_hif_driver_data *) platform_get_drvdata( + g_prPlatDev); +} + +static int hifAxiProbe(void) +{ + int ret = 0; + struct mt66xx_hif_driver_data *prDriverData; + struct mt66xx_chip_info *prChipInfo; + + ASSERT(g_prPlatDev); + + prDriverData = get_platform_driver_data(); + prChipInfo = prDriverData->chip_info; + +#if CFG_MTK_ANDROID_WMT +#if (CFG_SUPPORT_CONNINFRA == 0) + mtk_wcn_consys_hw_wifi_paldo_ctrl(1); +#endif +#endif + if (prChipInfo->wmmcupwron) + ret = prChipInfo->wmmcupwron(); + if (ret != 0) { + DBGLOG(INIT, INFO, "wmmcu pwr on fail!\n"); + if (prChipInfo->wmmcupwroff) + prChipInfo->wmmcupwroff(); + goto out; + } + if (pfWlanProbe((void *) g_prPlatDev, (void *) prDriverData) != + WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, INFO, "pfWlanProbe fail!\n"); + ret = -1; + if (prChipInfo->wmmcupwroff) + prChipInfo->wmmcupwroff(); + goto out; + } + g_fgDriverProbed = TRUE; +out: + DBGLOG(INIT, TRACE, "hifAxiProbe() done(%d)\n", ret); + + return ret; +} + +int hifAxiRemove(void) +{ + struct mt66xx_hif_driver_data *prDriverData; + struct mt66xx_chip_info *prChipInfo; + + prDriverData = get_platform_driver_data(); + prChipInfo = prDriverData->chip_info; + + if (g_fgDriverProbed) { + pfWlanRemove(); + DBGLOG(INIT, TRACE, "pfWlanRemove done\n"); + } + +#if (CFG_SUPPORT_CONNINFRA == 1) + if (prChipInfo->coexpccifoff) { + prChipInfo->coexpccifoff(); + DBGLOG(INIT, TRACE, "pccif off\n"); + } +#endif + + if (prChipInfo->coantVFE28Dis) + prChipInfo->coantVFE28Dis(); + + if (prChipInfo->wmmcupwroff) + prChipInfo->wmmcupwroff(); +#if CFG_MTK_ANDROID_WMT +#if (CFG_SUPPORT_CONNINFRA == 0) + mtk_wcn_consys_hw_wifi_paldo_ctrl(0); +#endif +#endif + g_fgDriverProbed = FALSE; + + DBGLOG(INIT, TRACE, "hifAxiRemove() done\n"); + return 0; +} + +#if CFG_MTK_ANDROID_WMT +#if (CFG_SUPPORT_CONNINFRA == 0) +static int hifAxiGetBusCnt(void) +{ + if (!g_prGlueInfo) + return 0; + + return g_prGlueInfo->rHifInfo.u4HifCnt; +} + +static int hifAxiClrBusCnt(void) +{ + if (g_prGlueInfo) + g_prGlueInfo->rHifInfo.u4HifCnt = 0; + + return 0; +} + +static int hifAxiSetMpuProtect(bool enable) +{ +#if CFG_MTK_ANDROID_EMI + kalSetEmiMpuProtection(gConEmiPhyBaseFinal, enable); +#endif + return 0; +} + + +static int hifAxiIsWifiDrvOwn(void) +{ + if (!g_prGlueInfo || !g_prGlueInfo->prAdapter) + return 0; + + return (g_prGlueInfo->prAdapter->fgIsFwOwn == FALSE) ? 1 : 0; +} +#endif +#endif /* CFG_MTK_ANDROID_WMT */ + +static int axiDmaSetup(struct platform_device *pdev, + struct mt66xx_hif_driver_data *prDriverData) +{ + struct mt66xx_chip_info *prChipInfo; + u64 dma_mask; + int ret = 0; + + prChipInfo = prDriverData->chip_info; + +#if AXI_CFG_PREALLOC_MEMORY_BUFFER + ret = _init_resv_mem(pdev); + if (ret) + goto exit; + ret = of_reserved_mem_device_init(&pdev->dev); + if (ret) { + DBGLOG(INIT, ERROR, "of_reserved_mem_device_init failed(%d).\n", + ret); + goto exit; + } +#else + ret = of_dma_configure(&pdev->dev, pdev->dev.of_node, true); + if (ret) { + DBGLOG(INIT, ERROR, "of_dma_configure failed(%d).\n", + ret); + goto exit; + } +#endif + + dma_mask = DMA_BIT_MASK(prChipInfo->bus_info->u4DmaMask); + ret = dma_set_mask_and_coherent(&pdev->dev, dma_mask); + if (ret) { + DBGLOG(INIT, ERROR, "dma_set_mask_and_coherent failed(%d)\n", + ret); + goto exit; + } + +exit: + return ret; +} + + +static bool axiCsrIoremap(struct platform_device *pdev) +{ +#ifdef CONFIG_OF + struct device_node *node = NULL; + struct resource res; + + node = of_find_compatible_node(NULL, NULL, "mediatek,wifi"); + if (!node) { + DBGLOG(INIT, ERROR, "WIFI-OF: get wifi device node fail\n"); + return false; + } + + if (of_address_to_resource(node, 0, &res)) { + DBGLOG(INIT, ERROR, "WIFI-OF: of_address_to_resource fail\n"); + of_node_put(node); + return false; + } + of_node_put(node); + + g_u8CsrOffset = (u64)res.start; + g_u4CsrSize = resource_size(&res); +#else + g_u8CsrOffset = axi_resource_start(pdev, 0); + g_u4CsrSize = axi_resource_len(pdev, 0); +#endif + if (CSRBaseAddress) { + DBGLOG(INIT, ERROR, "CSRBaseAddress not iounmap!\n"); + return false; + } + + request_mem_region(g_u8CsrOffset, g_u4CsrSize, axi_name(pdev)); + + /* map physical address to virtual address for accessing register */ +#ifdef CONFIG_OF + CSRBaseAddress = of_iomap(node, 0); +#else + CSRBaseAddress = ioremap(g_u8CsrOffset, g_u4CsrSize); +#endif + + if (!CSRBaseAddress) { + DBGLOG(INIT, INFO, + "ioremap failed for device %s, region 0x%X @ 0x%lX\n", + axi_name(pdev), g_u4CsrSize, g_u8CsrOffset); + release_mem_region(g_u8CsrOffset, g_u4CsrSize); + return false; + } + + DBGLOG(INIT, INFO, "CSRBaseAddress:0x%lX ioremap region 0x%X @ 0x%lX\n", + CSRBaseAddress, g_u4CsrSize, g_u8CsrOffset); + + return true; +} + +static void axiCsrIounmap(struct platform_device *pdev) +{ + if (!CSRBaseAddress) + return; + + /* Unmap CSR base address */ + iounmap(CSRBaseAddress); + release_mem_region(g_u8CsrOffset, g_u4CsrSize); + + CSRBaseAddress = NULL; + g_u8CsrOffset = 0; + g_u4CsrSize = 0; +} + +#if AXI_CFG_PREALLOC_MEMORY_BUFFER +static bool axiAllocRsvMem(uint32_t u4Size, struct HIF_MEM *prMem) +{ + /* 8 bytes alignment */ + if (u4Size & 7) + u4Size += 8 - (u4Size & 7); + + if ((grMem.u4Offset + u4Size) >= gWifiRsvMemSize) + return false; + + prMem->pa = grMem.pucRsvMemBase + grMem.u4Offset; + prMem->va = grMem.pucRsvMemVirBase + grMem.u4Offset; + grMem.u4Offset += u4Size; + + return prMem->va != NULL; +} + +static int axiAllocHifMem(struct platform_device *pdev, + struct mt66xx_hif_driver_data *prDriverData) +{ + struct mt66xx_chip_info *prChipInfo; + uint32_t u4Idx; + uint32_t i = sizeof(wifi_rsrv_mems) / sizeof(struct wifi_rsrv_mem); + + prChipInfo = prDriverData->chip_info; + + /* Allocation size should be a power of two */ + while (i > 0) { + i--; + if (!(gWifiRsvMemSize & BIT(i))) + continue; + + wifi_rsrv_mems[i].size = BIT(i); + wifi_rsrv_mems[i].vir_base = KAL_DMA_ALLOC_COHERENT(&pdev->dev, + wifi_rsrv_mems[i].size, + &wifi_rsrv_mems[i].phy_base); + if (!wifi_rsrv_mems[i].vir_base) { + DBGLOG(INIT, ERROR, + "[%d] DMA_ALLOC_COHERENT failed, size: 0x%x\n", + i, wifi_rsrv_mems[i].size); + return -1; + } + if (!grMem.pucRsvMemBase) { + grMem.pucRsvMemBase = wifi_rsrv_mems[i].phy_base; + grMem.pucRsvMemVirBase = wifi_rsrv_mems[i].vir_base; + grMem.u4RsvMemSize = (uint64_t) gWifiRsvMemSize; + } + } + if (!grMem.pucRsvMemBase) + return -1; + DBGLOG(INIT, INFO, "pucRsvMemBase[%pa], pucRsvMemVirBase[%pa]\n", + &grMem.pucRsvMemBase, + &grMem.pucRsvMemVirBase); + + kalSetDrvEmiMpuProtection(grMem.pucRsvMemBase, 0, grMem.u4RsvMemSize); + + for (u4Idx = 0; u4Idx < NUM_OF_TX_RING; u4Idx++) { + if (!axiAllocRsvMem(TX_RING_SIZE * TXD_SIZE, + &grMem.rTxDesc[u4Idx])) + DBGLOG(INIT, ERROR, "TxDesc[%u] alloc fail\n", u4Idx); + } + + if (!axiAllocRsvMem(RX_RING0_SIZE * RXD_SIZE, &grMem.rRxDesc[0])) + DBGLOG(INIT, ERROR, "RxDesc[0] alloc fail\n"); + +#if (CFG_SUPPORT_CONNAC2X == 1) + + if (!axiAllocRsvMem(RX_RING0_SIZE * RXD_SIZE, &grMem.rRxDesc[1])) + DBGLOG(INIT, ERROR, "RxDesc[1] alloc fail\n"); + + if (!axiAllocRsvMem(RX_RING1_SIZE * RXD_SIZE, &grMem.rRxDesc[2])) + DBGLOG(INIT, ERROR, "RxDesc[2] alloc fail\n"); + + if (!axiAllocRsvMem(RX_RING1_SIZE * RXD_SIZE, &grMem.rRxDesc[3])) + DBGLOG(INIT, ERROR, "RxDesc[3] alloc fail\n"); + + if (!axiAllocRsvMem(RX_RING1_SIZE * RXD_SIZE, &grMem.rRxDesc[4])) + DBGLOG(INIT, ERROR, "RxDesc[4] alloc fail\n"); + +#else + + if (!axiAllocRsvMem(RX_RING1_SIZE * RXD_SIZE, &grMem.rRxDesc[1])) + DBGLOG(INIT, ERROR, "RxDesc[1] alloc fail\n"); + +#endif + + for (u4Idx = 0; u4Idx < TX_RING_SIZE; u4Idx++) { + if (!axiAllocRsvMem(AXI_TX_CMD_BUFF_SIZE, + &grMem.rTxCmdBuf[u4Idx])) + DBGLOG(INIT, ERROR, "TxCmdBuf[%u] alloc fail\n", u4Idx); + } + + for (u4Idx = 0; u4Idx < RX_RING0_SIZE; u4Idx++) { + if (!axiAllocRsvMem(CFG_RX_MAX_PKT_SIZE, + &grMem.rRxDataBuf[u4Idx])) + DBGLOG(INIT, ERROR, + "RxDataBuf[%u] alloc fail\n", u4Idx); + } + +#if (CFG_SUPPORT_CONNAC2X == 1) + + for (u4Idx = 0; u4Idx < RX_RING0_SIZE; u4Idx++) { + if (!axiAllocRsvMem(RX_BUFFER_AGGRESIZE, + &grMem.rRxEventBuf[u4Idx])) + DBGLOG(INIT, ERROR, + "RxDataBuf[%u] alloc fail\n", u4Idx); + } + + for (u4Idx = 0; u4Idx < RX_RING1_SIZE; u4Idx++) { + if (!axiAllocRsvMem(RX_BUFFER_AGGRESIZE, + &grMem.wfdma0_rx_ring_idx2[u4Idx])) + DBGLOG(INIT, ERROR, + "RxEventBuf[%u] alloc fail\n", u4Idx); + } + + for (u4Idx = 0; u4Idx < RX_RING1_SIZE; u4Idx++) { + if (!axiAllocRsvMem(RX_BUFFER_AGGRESIZE, + &grMem.wfdma0_rx_ring_idx3[u4Idx])) + DBGLOG(INIT, ERROR, + "RxEventBuf[%u] alloc fail\n", u4Idx); + } + + for (u4Idx = 0; u4Idx < RX_RING1_SIZE; u4Idx++) { + if (!axiAllocRsvMem(RX_BUFFER_AGGRESIZE, + &grMem.wfdma1_rx_ring_idx0[u4Idx])) + DBGLOG(INIT, ERROR, + "RxEventBuf[%u] alloc fail\n", u4Idx); + } +#else + for (u4Idx = 0; u4Idx < RX_RING1_SIZE; u4Idx++) { + if (!axiAllocRsvMem(RX_BUFFER_AGGRESIZE, + &grMem.rRxEventBuf[u4Idx])) + DBGLOG(INIT, ERROR, + "RxEventBuf[%u] alloc fail\n", u4Idx); + } + +#endif + +#if HIF_TX_PREALLOC_DATA_BUFFER + for (u4Idx = 0; u4Idx < HIF_TX_MSDU_TOKEN_NUM; u4Idx++) { + if (!axiAllocRsvMem(AXI_TX_MAX_SIZE_PER_FRAME + + prChipInfo->txd_append_size, + &grMem.rMsduBuf[u4Idx])) + DBGLOG(INIT, ERROR, "MsduBuf[%u] alloc fail\n", u4Idx); + } +#endif + + DBGLOG(INIT, INFO, "grMem.u4Offset[0x%x]\n", grMem.u4Offset); + + return 0; +} + +static void axiFreeHifMem(struct platform_device *pdev) +{ + uint32_t i = 0; + uint32_t count = sizeof(wifi_rsrv_mems) / sizeof(struct wifi_rsrv_mem); + + for (i = 0; i < count; i++) { + if (!wifi_rsrv_mems[i].vir_base) + continue; + KAL_DMA_FREE_COHERENT(&pdev->dev, + wifi_rsrv_mems[i].size, + wifi_rsrv_mems[i].vir_base, + (dma_addr_t) wifi_rsrv_mems[i].phy_base); + } +} + +static int _init_resv_mem(struct platform_device *pdev) +{ +#ifdef CONFIG_OF + int ret = 0; + struct device_node *np; + + np = of_parse_phandle(pdev->dev.of_node, "memory-region", 0); + if (!np) { + DBGLOG(INIT, ERROR, "can NOT find memory-region.\n"); + return -1; + } + + ret = of_property_read_u64_array(np, "size", &gWifiRsvMemSize, 1); + if (ret != 0) + DBGLOG(INIT, ERROR, "get rsrv mem size failed(%d).\n", ret); + else + DBGLOG(INIT, INFO, "gWifiRsvMemSize: 0x%x\n", gWifiRsvMemSize); + + of_node_put(np); + + return ret; +#else + DBGLOG(INIT, ERROR, "kernel option CONFIG_OF not enabled.\n"); + return -1; +#endif +} + +#endif /* AXI_CFG_PREALLOC_MEMORY_BUFFER */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is a AXI interrupt callback function + * + * \param[in] func pointer to AXI handle + * + * \return void + */ +/*----------------------------------------------------------------------------*/ +static irqreturn_t mtk_axi_interrupt(int irq, void *dev_instance) +{ + struct GLUE_INFO *prGlueInfo = NULL; + static DEFINE_RATELIMIT_STATE(_rs, 2 * HZ, 1); + + prGlueInfo = (struct GLUE_INFO *)dev_instance; + if (!prGlueInfo) { + DBGLOG(HAL, INFO, "No glue info in mtk_axi_interrupt()\n"); + return IRQ_NONE; + } + + GLUE_INC_REF_CNT(prGlueInfo->prAdapter->rHifStats.u4HwIsrCount); + halDisableInterrupt(prGlueInfo->prAdapter); + + if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { + DBGLOG(HAL, INFO, "GLUE_FLAG_HALT skip INT\n"); + return IRQ_NONE; + } + + kalSetIntEvent(prGlueInfo); + if (__ratelimit(&_rs)) + pr_info("[wlan] In HIF ISR.\n"); + + return IRQ_HANDLED; +} +#if (CFG_SUPPORT_CONNINFRA == 1) +void kalSetRstEvent(void) +{ + KAL_WAKE_LOCK(NULL, g_IntrWakeLock); + + set_bit(GLUE_FLAG_RST_START_BIT, &g_ulFlag); + + /* when we got interrupt, we wake up servie thread */ + wake_up_interruptible(&g_waitq_rst); + +} + +static irqreturn_t mtk_sw_interrupt(int irq, void *dev_instance) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct mt66xx_chip_info *prChipInfo; + + prGlueInfo = (struct GLUE_INFO *)dev_instance; + GLUE_INC_REF_CNT(prGlueInfo->prAdapter->rHifStats.u4SwIsrCount); + prChipInfo = prGlueInfo->prAdapter->chip_info; + if (prChipInfo->sw_interrupt_handler) + prChipInfo->sw_interrupt_handler(prGlueInfo->prAdapter); + + return IRQ_HANDLED; +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is a AXI probe function + * + * \param[in] func pointer to AXI handle + * \param[in] id pointer to AXI device id table + * + * \return void + */ +/*----------------------------------------------------------------------------*/ +static int mtk_axi_probe(IN struct platform_device *pdev) +{ + struct mt66xx_hif_driver_data *prDriverData; + struct mt66xx_chip_info *prChipInfo; + int ret = 0; +#if CFG_MTK_ANDROID_WMT +#if (CFG_SUPPORT_CONNINFRA == 0) + struct _MTK_WCN_WMT_WLAN_CB_INFO rWmtCb; +#else + struct MTK_WCN_WLAN_CB_INFO rWlanCb; +#endif +#endif + + g_prPlatDev = pdev; + prDriverData = (struct mt66xx_hif_driver_data *) + mtk_axi_ids[0].driver_data; + prChipInfo = prDriverData->chip_info; + prChipInfo->pdev = (void *) pdev; + + platform_set_drvdata(pdev, (void *) prDriverData); + + if (!axiCsrIoremap(pdev)) + goto exit; + + ret = axiDmaSetup(pdev, prDriverData); + if (ret) + goto exit; + +#if AXI_CFG_PREALLOC_MEMORY_BUFFER + ret = axiAllocHifMem(pdev, prDriverData); + if (ret) + goto exit; +#endif + +#if CFG_MTK_ANDROID_WMT +#if (CFG_SUPPORT_CONNINFRA == 0) + memset(&rWmtCb, 0, sizeof(struct _MTK_WCN_WMT_WLAN_CB_INFO)); + rWmtCb.wlan_probe_cb = hifAxiProbe; + rWmtCb.wlan_remove_cb = hifAxiRemove; + rWmtCb.wlan_bus_cnt_get_cb = hifAxiGetBusCnt; + rWmtCb.wlan_bus_cnt_clr_cb = hifAxiClrBusCnt; + rWmtCb.wlan_emi_mpu_set_protection_cb = hifAxiSetMpuProtect; + rWmtCb.wlan_is_wifi_drv_own_cb = hifAxiIsWifiDrvOwn; + mtk_wcn_wmt_wlan_reg(&rWmtCb); +#else + + rWlanCb.wlan_probe_cb = hifAxiProbe; + rWlanCb.wlan_remove_cb = hifAxiRemove; + mtk_wcn_wlan_reg(&rWlanCb); + + if (prChipInfo->conninra_cb_register) + prChipInfo->conninra_cb_register(); + +#endif +#else + hifAxiProbe(); +#endif + +exit: + DBGLOG(INIT, INFO, "mtk_axi_probe() done, ret: %d\n", ret); + return ret; +} + +static int mtk_axi_remove(IN struct platform_device *pdev) +{ + axiCsrIounmap(pdev); + +#if AXI_CFG_PREALLOC_MEMORY_BUFFER + axiFreeHifMem(pdev); +#endif + +#if CFG_MTK_ANDROID_WMT +#if (CFG_SUPPORT_CONNINFRA == 0) + mtk_wcn_wmt_wlan_unreg(); +#else + mtk_wcn_wlan_unreg(); +#endif /*end of CFG_SUPPORT_CONNINFRA == 0*/ +#else + hifAxiRemove(); +#endif + platform_set_drvdata(pdev, NULL); + return 0; +} + +static int mtk_axi_suspend(IN struct platform_device *pdev, + IN pm_message_t state) +{ + return 0; +} + +int mtk_axi_resume(IN struct platform_device *pdev) +{ + return 0; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function will register pci bus to the os + * + * \param[in] pfProbe Function pointer to detect card + * \param[in] pfRemove Function pointer to remove card + * + * \return The result of registering pci bus + */ +/*----------------------------------------------------------------------------*/ +uint32_t glRegisterBus(probe_card pfProbe, remove_card pfRemove) +{ + int ret = 0; + + ASSERT(pfProbe); + ASSERT(pfRemove); + + pfWlanProbe = pfProbe; + pfWlanRemove = pfRemove; + + mtk_axi_driver.probe = mtk_axi_probe; + mtk_axi_driver.remove = mtk_axi_remove; + + mtk_axi_driver.suspend = mtk_axi_suspend; + mtk_axi_driver.resume = mtk_axi_resume; + + ret = (platform_driver_register(&mtk_axi_driver) == 0) ? + WLAN_STATUS_SUCCESS : WLAN_STATUS_FAILURE; + return ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function will unregister pci bus to the os + * + * \param[in] pfRemove Function pointer to remove card + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void glUnregisterBus(remove_card pfRemove) +{ + if (g_fgDriverProbed) { + pfRemove(); + g_fgDriverProbed = FALSE; + } + platform_driver_unregister(&mtk_axi_driver); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function stores hif related info, which is initialized before. + * + * \param[in] prGlueInfo Pointer to glue info structure + * \param[in] u4Cookie Pointer to UINT_32 memory base variable for _HIF_HPI + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void glSetHifInfo(struct GLUE_INFO *prGlueInfo, unsigned long ulCookie) +{ + struct GL_HIF_INFO *prHif = NULL; + struct HIF_MEM_OPS *prMemOps; + + g_prGlueInfo = prGlueInfo; + prHif = &prGlueInfo->rHifInfo; + prMemOps = &prHif->rMemOps; + + prHif->pdev = (struct platform_device *)ulCookie; + prHif->prDmaDev = &prHif->pdev->dev; + + prHif->CSRBaseAddress = CSRBaseAddress; + + SET_NETDEV_DEV(prGlueInfo->prDevHandler, &prHif->pdev->dev); + + prGlueInfo->u4InfType = MT_DEV_INF_AXI; + + prHif->fgIsPowerOff = true; + prHif->fgIsDumpLog = false; + +#if AXI_CFG_PREALLOC_MEMORY_BUFFER + prMemOps->allocTxDesc = axiAllocTxDesc; + prMemOps->allocRxDesc = axiAllocRxDesc; + prMemOps->allocTxCmdBuf = axiAllocTxCmdBuf; + prMemOps->allocTxDataBuf = axiAllocTxDataBuf; + prMemOps->allocRxBuf = axiAllocRxBuf; + prMemOps->allocRuntimeMem = NULL; + prMemOps->copyCmd = axiCopyCmd; + prMemOps->copyEvent = axiCopyEvent; + prMemOps->copyTxData = axiCopyTxData; + prMemOps->copyRxData = axiCopyRxData; + prMemOps->mapTxBuf = NULL; + prMemOps->mapRxBuf = NULL; + prMemOps->unmapTxBuf = NULL; + prMemOps->unmapRxBuf = NULL; + prMemOps->freeDesc = NULL; + prMemOps->freeBuf = NULL; + prMemOps->freePacket = NULL; + prMemOps->dumpTx = axiDumpTx; + prMemOps->dumpRx = axiDumpRx; +#else + prMemOps->allocTxDesc = axiAllocDesc; + prMemOps->allocRxDesc = axiAllocDesc; + prMemOps->allocTxCmdBuf = NULL; + prMemOps->allocTxDataBuf = axiAllocTxDataBuf; + prMemOps->allocRxBuf = axiAllocRxBuf; + prMemOps->allocRuntimeMem = axiAllocRuntimeMem; + prMemOps->copyCmd = axiCopyCmd; + prMemOps->copyEvent = axiCopyEvent; + prMemOps->copyTxData = axiCopyTxData; + prMemOps->copyRxData = axiCopyRxData; + prMemOps->mapTxBuf = axiMapTxBuf; + prMemOps->mapRxBuf = axiMapRxBuf; + prMemOps->unmapTxBuf = axiUnmapTxBuf; + prMemOps->unmapRxBuf = axiUnmapRxBuf; + prMemOps->freeDesc = axiFreeDesc; + prMemOps->freeBuf = axiFreeBuf; + prMemOps->freePacket = axiFreePacket; + prMemOps->dumpTx = axiDumpTx; + prMemOps->dumpRx = axiDumpRx; +#endif /* AXI_CFG_PREALLOC_MEMORY_BUFFER */ +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function clears hif related info. + * + * \param[in] prGlueInfo Pointer to glue info structure + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void glClearHifInfo(struct GLUE_INFO *prGlueInfo) +{ +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Initialize bus operation and hif related information, request + * resources. + * + * \param[out] pvData A pointer to HIF-specific data type buffer. + * For eHPI, pvData is a pointer to UINT_32 type and + * stores a mapped base address. + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +u_int8_t glBusInit(void *pvData) +{ + ASSERT(pvData); + + return TRUE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Stop bus operation and release resources. + * + * \param[in] pvData A pointer to struct net_device. + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void glBusRelease(void *pvData) +{ +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Setup bus interrupt operation and interrupt handler for os. + * + * \param[in] pvData A pointer to struct net_device. + * \param[in] pfnIsr A pointer to interrupt handler function. + * \param[in] pvCookie Private data for pfnIsr function. + * + * \retval WLAN_STATUS_SUCCESS if success + * NEGATIVE_VALUE if fail + */ +/*----------------------------------------------------------------------------*/ + +int32_t glBusSetIrq(void *pvData, void *pfnIsr, void *pvCookie) +{ + struct net_device *prNetDevice = NULL; + struct GLUE_INFO *prGlueInfo = NULL; + struct GL_HIF_INFO *prHifInfo = NULL; + struct platform_device *pdev = NULL; +#ifdef CONFIG_OF + struct device_node *node = NULL; +#endif + int ret = 0; + + ASSERT(pvData); + if (!pvData) + return -1; + + prNetDevice = (struct net_device *)pvData; + prGlueInfo = (struct GLUE_INFO *)pvCookie; + ASSERT(prGlueInfo); + if (!prGlueInfo) + return -1; + + prHifInfo = &prGlueInfo->rHifInfo; + pdev = prHifInfo->pdev; + + prHifInfo->u4IrqId = AXI_WLAN_IRQ_NUMBER; +#ifdef CONFIG_OF + node = of_find_compatible_node(NULL, NULL, "mediatek,wifi"); + if (node) { + prHifInfo->u4IrqId = irq_of_parse_and_map(node, 0); +#if (CFG_SUPPORT_CONNINFRA == 1) + prHifInfo->u4IrqId_1 = irq_of_parse_and_map(node, 1); +#endif + } + else + DBGLOG(INIT, ERROR, + "WIFI-OF: get wifi device node fail\n"); +#endif +#if (CFG_SUPPORT_CONNINFRA == 1) + DBGLOG(INIT, INFO, "glBusSetIrq: request_irq num(%d), num(%d)\n", + prHifInfo->u4IrqId, prHifInfo->u4IrqId_1); +#else + DBGLOG(INIT, INFO, "glBusSetIrq: request_irq num(%d)\n", + prHifInfo->u4IrqId); +#endif /*end of CFG_SUPPORT_CONNINFRA == 1*/ + ret = request_irq(prHifInfo->u4IrqId, mtk_axi_interrupt, IRQF_SHARED, + prNetDevice->name, prGlueInfo); + if (ret != 0) { + DBGLOG(INIT, INFO, "request_irq(%u) ERROR(%d)\n", + prHifInfo->u4IrqId, ret); + goto exit; + } +#if KERNEL_VERSION(5, 4, 0) <= CFG80211_VERSION_CODE + ret = enable_irq_wake(prHifInfo->u4IrqId); + if (ret) { + DBGLOG(INIT, INFO, "enable_irq_wake(%u) ERROR(%d)\n", + prHifInfo->u4IrqId, ret); + goto exit; + } +#endif +#if (CFG_SUPPORT_CONNINFRA == 1) + ret = request_irq(prHifInfo->u4IrqId_1, mtk_sw_interrupt, IRQF_SHARED, + prNetDevice->name, prGlueInfo); + if (ret != 0) { + DBGLOG(INIT, INFO, "request_irq(%u) ERROR(%d)\n", + prHifInfo->u4IrqId_1, ret); + goto exit; + } +#if KERNEL_VERSION(5, 4, 0) <= CFG80211_VERSION_CODE + ret = enable_irq_wake(prHifInfo->u4IrqId_1); + if (ret) { + DBGLOG(INIT, INFO, "enable_irq_wake(%u) ERROR(%d)\n", + prHifInfo->u4IrqId_1, ret); + goto exit; + } +#endif +#endif + +exit: + return ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Stop bus interrupt operation and disable interrupt handling for os. + * + * \param[in] pvData A pointer to struct net_device. + * \param[in] pvCookie Private data for pfnIsr function. + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void glBusFreeIrq(void *pvData, void *pvCookie) +{ + struct net_device *prNetDevice = NULL; + struct GLUE_INFO *prGlueInfo = NULL; + struct GL_HIF_INFO *prHifInfo = NULL; + struct platform_device *pdev = NULL; + + ASSERT(pvData); + if (!pvData) { + DBGLOG(INIT, INFO, "%s null pvData\n", __func__); + return; + } + prNetDevice = (struct net_device *)pvData; + prGlueInfo = (struct GLUE_INFO *) pvCookie; + ASSERT(prGlueInfo); + if (!prGlueInfo) { + DBGLOG(INIT, INFO, "%s no glue info\n", __func__); + return; + } + + prHifInfo = &prGlueInfo->rHifInfo; + pdev = prHifInfo->pdev; + + synchronize_irq(prHifInfo->u4IrqId); + free_irq(prHifInfo->u4IrqId, prGlueInfo); +#if (CFG_SUPPORT_CONNINFRA == 1) + synchronize_irq(prHifInfo->u4IrqId_1); + free_irq(prHifInfo->u4IrqId_1, prGlueInfo); +#endif +} + +u_int8_t glIsReadClearReg(uint32_t u4Address) +{ + return TRUE; +} + +void glSetPowerState(IN struct GLUE_INFO *prGlueInfo, IN uint32_t ePowerMode) +{ +} + +void glGetDev(void *ctx, struct device **dev) +{ + *dev = &((struct platform_device *)ctx)->dev; +} + +void glGetHifDev(struct GL_HIF_INFO *prHif, struct device **dev) +{ + *dev = &(prHif->pdev->dev); +} + +#if AXI_CFG_PREALLOC_MEMORY_BUFFER +static void axiAllocTxDesc(struct GL_HIF_INFO *prHifInfo, + struct RTMP_DMABUF *prDescRing, + uint32_t u4Num) +{ + prDescRing->AllocVa = grMem.rTxDesc[u4Num].va; + prDescRing->AllocPa = grMem.rTxDesc[u4Num].pa; + if (prDescRing->AllocVa == NULL) + DBGLOG(HAL, ERROR, "prDescRing->AllocVa is NULL\n"); + else + memset(prDescRing->AllocVa, 0, prDescRing->AllocSize); +} + +static void axiAllocRxDesc(struct GL_HIF_INFO *prHifInfo, + struct RTMP_DMABUF *prDescRing, + uint32_t u4Num) +{ + prDescRing->AllocVa = grMem.rRxDesc[u4Num].va; + prDescRing->AllocPa = grMem.rRxDesc[u4Num].pa; + if (prDescRing->AllocVa == NULL) + DBGLOG(HAL, ERROR, "prDescRing->AllocVa is NULL\n"); + else + memset(prDescRing->AllocVa, 0, prDescRing->AllocSize); +} + +static bool axiAllocTxCmdBuf(struct RTMP_DMABUF *prDmaBuf, + uint32_t u4Num, uint32_t u4Idx) +{ + /* only for cmd & fw download ring */ + if (u4Num == 2 || u4Num == 3) { + prDmaBuf->AllocSize = AXI_TX_CMD_BUFF_SIZE; + prDmaBuf->AllocPa = grMem.rTxCmdBuf[u4Idx].pa; + prDmaBuf->AllocVa = grMem.rTxCmdBuf[u4Idx].va; + if (prDmaBuf->AllocVa == NULL) { + DBGLOG(HAL, ERROR, "prDescRing->AllocVa is NULL\n"); + return false; + } + memset(prDmaBuf->AllocVa, 0, prDmaBuf->AllocSize); + } + return true; +} + +static void axiAllocTxDataBuf(struct MSDU_TOKEN_ENTRY *prToken, uint32_t u4Idx) +{ + prToken->prPacket = grMem.rMsduBuf[u4Idx].va; + prToken->rDmaAddr = grMem.rMsduBuf[u4Idx].pa; +} + +static void *axiAllocRxBuf(struct GL_HIF_INFO *prHifInfo, + struct RTMP_DMABUF *prDmaBuf, + uint32_t u4Num, uint32_t u4Idx) +{ + /* ring 0 for data, ring 1 for event */ + if (u4Num == 0) { + prDmaBuf->AllocPa = grMem.rRxDataBuf[u4Idx].pa; + prDmaBuf->AllocVa = grMem.rRxDataBuf[u4Idx].va; + } else if (u4Num == 1) { + prDmaBuf->AllocPa = grMem.rRxEventBuf[u4Idx].pa; + prDmaBuf->AllocVa = grMem.rRxEventBuf[u4Idx].va; + } + /* Add for connac2x RX ring */ +#if (CFG_SUPPORT_CONNAC2X == 1) + + else if (u4Num == 2) { + prDmaBuf->AllocPa = grMem.wfdma0_rx_ring_idx2[u4Idx].pa; + prDmaBuf->AllocVa = grMem.wfdma0_rx_ring_idx2[u4Idx].va; + } else if (u4Num == 3) { + prDmaBuf->AllocPa = grMem.wfdma0_rx_ring_idx3[u4Idx].pa; + prDmaBuf->AllocVa = grMem.wfdma0_rx_ring_idx3[u4Idx].va; + } else if (u4Num == 4) { + prDmaBuf->AllocPa = grMem.wfdma1_rx_ring_idx0[u4Idx].pa; + prDmaBuf->AllocVa = grMem.wfdma1_rx_ring_idx0[u4Idx].va; + } + +#endif + else { + DBGLOG(RX, ERROR, "RX alloc fail error number=%d\n", u4Num); + return prDmaBuf->AllocVa; + } + if (prDmaBuf->AllocVa == NULL) + DBGLOG(HAL, ERROR, "prDmaBuf->AllocVa is NULL\n"); + else + memset(prDmaBuf->AllocVa, 0, prDmaBuf->AllocSize); + + return prDmaBuf->AllocVa; +} + +static bool axiCopyCmd(struct GL_HIF_INFO *prHifInfo, + struct RTMP_DMACB *prTxCell, void *pucBuf, + void *pucSrc1, uint32_t u4SrcLen1, + void *pucSrc2, uint32_t u4SrcLen2) +{ + struct RTMP_DMABUF *prDmaBuf = &prTxCell->DmaBuf; + + memcpy(prDmaBuf->AllocVa, pucSrc1, u4SrcLen1); + if (pucSrc2 != NULL && u4SrcLen2 > 0) + memcpy(prDmaBuf->AllocVa + u4SrcLen1, pucSrc2, u4SrcLen2); + prTxCell->PacketPa = prDmaBuf->AllocPa; + + return true; +} + +static bool axiCopyEvent(struct GL_HIF_INFO *prHifInfo, + struct RTMP_DMACB *pRxCell, + struct RXD_STRUCT *pRxD, + struct RTMP_DMABUF *prDmaBuf, + uint8_t *pucDst, uint32_t u4Len) +{ + memcpy(pucDst, prDmaBuf->AllocVa, u4Len); + + return true; +} + +static bool axiCopyTxData(struct MSDU_TOKEN_ENTRY *prToken, + void *pucSrc, uint32_t u4Len) +{ + memcpy(prToken->prPacket, pucSrc, u4Len); + + return true; +} + +static bool axiCopyRxData(struct GL_HIF_INFO *prHifInfo, + struct RTMP_DMACB *pRxCell, + struct RTMP_DMABUF *prDmaBuf, + struct SW_RFB *prSwRfb) +{ + struct RXD_STRUCT *pRxD = (struct RXD_STRUCT *)pRxCell->AllocVa; + struct sk_buff *prSkb = ((struct sk_buff *)prSwRfb->pvPacket); + uint32_t u4Size = pRxD->SDLen0; + + if (u4Size > CFG_RX_MAX_PKT_SIZE) { + DBGLOG(RX, ERROR, "Rx Data too large[%u]\n", u4Size); + return false; + } + + memcpy(prSkb->data, prDmaBuf->AllocVa, u4Size); + + return true; +} + +static void axiDumpTx(struct GL_HIF_INFO *prHifInfo, + struct RTMP_TX_RING *prTxRing, + uint32_t u4Idx, uint32_t u4DumpLen) +{ + struct RTMP_DMACB *prTxCell; + struct RTMP_DMABUF *prDmaBuf; + void *prAddr = NULL; + + prTxCell = &prTxRing->Cell[u4Idx]; + prDmaBuf = &prTxCell->DmaBuf; + + if (prTxCell->prToken) + prAddr = prTxCell->prToken->prPacket; + else if (prDmaBuf->AllocVa) + prAddr = prDmaBuf->AllocVa; + + if (prAddr) + DBGLOG_MEM32(HAL, INFO, prAddr, u4DumpLen); +} + +static void axiDumpRx(struct GL_HIF_INFO *prHifInfo, + struct RTMP_RX_RING *prRxRing, + uint32_t u4Idx, uint32_t u4DumpLen) +{ + struct RTMP_DMACB *prRxCell; + struct RTMP_DMABUF *prDmaBuf; + + prRxCell = &prRxRing->Cell[u4Idx]; + prDmaBuf = &prRxCell->DmaBuf; + + if (prRxCell->pPacket) + DBGLOG_MEM32(HAL, INFO, prRxCell->pPacket, u4DumpLen); +} +#else /* AXI_CFG_PREALLOC_MEMORY_BUFFER */ +static void axiAllocDesc(struct GL_HIF_INFO *prHifInfo, + struct RTMP_DMABUF *prDescRing, + uint32_t u4Num) +{ + dma_addr_t rAddr; + + prDescRing->AllocVa = (void *)KAL_DMA_ALLOC_COHERENT( + prHifInfo->prDmaDev, prDescRing->AllocSize, &rAddr); + prDescRing->AllocPa = (phys_addr_t)rAddr; + if (prDescRing->AllocVa) + memset(prDescRing->AllocVa, 0, prDescRing->AllocSize); +} + +static void *axiAllocRxBuf(struct GL_HIF_INFO *prHifInfo, + struct RTMP_DMABUF *prDmaBuf, + uint32_t u4Num, uint32_t u4Idx) +{ + struct sk_buff *pkt = dev_alloc_skb(prDmaBuf->AllocSize); + dma_addr_t rAddr; + + if (!pkt) { + DBGLOG(HAL, ERROR, "can't allocate rx %u size packet\n", + prDmaBuf->AllocSize); + prDmaBuf->AllocPa = 0; + prDmaBuf->AllocVa = NULL; + return NULL; + } + + prDmaBuf->AllocVa = (void *)pkt->data; + memset(prDmaBuf->AllocVa, 0, prDmaBuf->AllocSize); + + rAddr = KAL_DMA_MAP_SINGLE(prHifInfo->prDmaDev, prDmaBuf->AllocVa, + prDmaBuf->AllocSize, KAL_DMA_FROM_DEVICE); + if (KAL_DMA_MAPPING_ERROR(prHifInfo->prDmaDev, rAddr)) { + DBGLOG(HAL, ERROR, "sk_buff dma mapping error!\n"); + dev_kfree_skb(pkt); + return NULL; + } + prDmaBuf->AllocPa = (phys_addr_t)rAddr; + return (void *)pkt; +} + +static void axiAllocTxDataBuf(struct MSDU_TOKEN_ENTRY *prToken, uint32_t u4Idx) +{ + prToken->prPacket = kalMemAlloc(prToken->u4DmaLength, PHY_MEM_TYPE); + prToken->rDmaAddr = 0; +} + +static void *axiAllocRuntimeMem(uint32_t u4SrcLen) +{ + return kalMemAlloc(u4SrcLen, PHY_MEM_TYPE); +} + +static bool axiCopyCmd(struct GL_HIF_INFO *prHifInfo, + struct RTMP_DMACB *prTxCell, void *pucBuf, + void *pucSrc1, uint32_t u4SrcLen1, + void *pucSrc2, uint32_t u4SrcLen2) +{ + dma_addr_t rAddr; + uint32_t u4TotalLen = u4SrcLen1 + u4SrcLen2; + + prTxCell->pBuffer = pucBuf; + + memcpy(pucBuf, pucSrc1, u4SrcLen1); + if (pucSrc2 != NULL && u4SrcLen2 > 0) + memcpy(pucBuf + u4SrcLen1, pucSrc2, u4SrcLen2); + rAddr = KAL_DMA_MAP_SINGLE(prHifInfo->prDmaDev, pucBuf, + u4TotalLen, KAL_DMA_TO_DEVICE); + if (KAL_DMA_MAPPING_ERROR(prHifInfo->prDmaDev, rAddr)) { + DBGLOG(HAL, ERROR, "KAL_DMA_MAP_SINGLE() error!\n"); + return false; + } + + prTxCell->PacketPa = (phys_addr_t)rAddr; + + return true; +} + +static bool axiCopyEvent(struct GL_HIF_INFO *prHifInfo, + struct RTMP_DMACB *pRxCell, + struct RXD_STRUCT *pRxD, + struct RTMP_DMABUF *prDmaBuf, + uint8_t *pucDst, uint32_t u4Len) +{ + struct sk_buff *prSkb = NULL; + void *pRxPacket = NULL; + dma_addr_t rAddr; + + KAL_DMA_UNMAP_SINGLE(prHifInfo->prDmaDev, + (dma_addr_t)prDmaBuf->AllocPa, + prDmaBuf->AllocSize, KAL_DMA_FROM_DEVICE); + + pRxPacket = pRxCell->pPacket; + ASSERT(pRxPacket); + + prSkb = (struct sk_buff *)pRxPacket; + memcpy(pucDst, (uint8_t *)prSkb->data, u4Len); + + prDmaBuf->AllocVa = ((struct sk_buff *)pRxCell->pPacket)->data; + rAddr = KAL_DMA_MAP_SINGLE(prHifInfo->prDmaDev, prDmaBuf->AllocVa, + prDmaBuf->AllocSize, KAL_DMA_FROM_DEVICE); + if (KAL_DMA_MAPPING_ERROR(prHifInfo->prDmaDev, rAddr)) { + DBGLOG(HAL, ERROR, "KAL_DMA_MAP_SINGLE() error!\n"); + return false; + } + prDmaBuf->AllocPa = (phys_addr_t)rAddr; + return true; +} + +static bool axiCopyTxData(struct MSDU_TOKEN_ENTRY *prToken, + void *pucSrc, uint32_t u4Len) +{ + memcpy(prToken->prPacket, pucSrc, u4Len); + return true; +} + +static bool axiCopyRxData(struct GL_HIF_INFO *prHifInfo, + struct RTMP_DMACB *pRxCell, + struct RTMP_DMABUF *prDmaBuf, + struct SW_RFB *prSwRfb) +{ + void *pRxPacket = NULL; + dma_addr_t rAddr; + + pRxPacket = pRxCell->pPacket; + ASSERT(pRxPacket); + + pRxCell->pPacket = prSwRfb->pvPacket; + + KAL_DMA_UNMAP_SINGLE(prHifInfo->prDmaDev, + (dma_addr_t)prDmaBuf->AllocPa, + prDmaBuf->AllocSize, KAL_DMA_FROM_DEVICE); + prSwRfb->pvPacket = pRxPacket; + + prDmaBuf->AllocVa = ((struct sk_buff *)pRxCell->pPacket)->data; + rAddr = KAL_DMA_MAP_SINGLE(prHifInfo->prDmaDev, + prDmaBuf->AllocVa, prDmaBuf->AllocSize, KAL_DMA_FROM_DEVICE); + if (KAL_DMA_MAPPING_ERROR(prHifInfo->prDmaDev, rAddr)) { + DBGLOG(HAL, ERROR, "KAL_DMA_MAP_SINGLE() error!\n"); + ASSERT(0); + return false; + } + prDmaBuf->AllocPa = (phys_addr_t)rAddr; + + return true; +} + +static phys_addr_t axiMapTxBuf(struct GL_HIF_INFO *prHifInfo, + void *pucBuf, uint32_t u4Offset, uint32_t u4Len) +{ + dma_addr_t rDmaAddr = 0; + + rDmaAddr = KAL_DMA_MAP_SINGLE(prHifInfo->prDmaDev, pucBuf + u4Offset, + u4Len, KAL_DMA_TO_DEVICE); + if (KAL_DMA_MAPPING_ERROR(prHifInfo->prDmaDev, rDmaAddr)) { + DBGLOG(HAL, ERROR, "KAL_DMA_MAP_SINGLE() error!\n"); + return 0; + } + + return (phys_addr_t)rDmaAddr; +} + +static phys_addr_t axiMapRxBuf(struct GL_HIF_INFO *prHifInfo, + void *pucBuf, uint32_t u4Offset, uint32_t u4Len) +{ + dma_addr_t rDmaAddr = 0; + + rDmaAddr = KAL_DMA_MAP_SINGLE(prHifInfo->prDmaDev, pucBuf + u4Offset, + u4Len, KAL_DMA_FROM_DEVICE); + if (KAL_DMA_MAPPING_ERROR(prHifInfo->prDmaDev, rDmaAddr)) { + DBGLOG(HAL, ERROR, "KAL_DMA_MAP_SINGLE() error!\n"); + return 0; + } + + return (phys_addr_t)rDmaAddr; +} + +static void axiUnmapTxBuf(struct GL_HIF_INFO *prHifInfo, + phys_addr_t rDmaAddr, uint32_t u4Len) +{ + KAL_DMA_UNMAP_SINGLE(prHifInfo->prDmaDev, + (dma_addr_t)rDmaAddr, + u4Len, KAL_DMA_TO_DEVICE); +} + +static void axiUnmapRxBuf(struct GL_HIF_INFO *prHifInfo, + phys_addr_t rDmaAddr, uint32_t u4Len) +{ + KAL_DMA_UNMAP_SINGLE(prHifInfo->prDmaDev, + (dma_addr_t)rDmaAddr, + u4Len, KAL_DMA_FROM_DEVICE); +} + +static void axiFreeDesc(struct GL_HIF_INFO *prHifInfo, + struct RTMP_DMABUF *prDescRing) +{ + if (prDescRing->AllocVa == NULL) + return; + + KAL_DMA_FREE_COHERENT(prHifInfo->prDmaDev, + prDescRing->AllocSize, + prDescRing->AllocVa, + (dma_addr_t)prDescRing->AllocPa); + memset(prDescRing, 0, sizeof(struct RTMP_DMABUF)); +} + +static void axiFreeBuf(void *pucSrc, uint32_t u4Len) +{ + kalMemFree(pucSrc, PHY_MEM_TYPE, u4Len); +} + +static void axiFreePacket(void *pvPacket) +{ + kalPacketFree(NULL, pvPacket); +} + +static void axiDumpTx(struct GL_HIF_INFO *prHifInfo, + struct RTMP_TX_RING *prTxRing, + uint32_t u4Idx, uint32_t u4DumpLen) +{ + struct RTMP_DMACB *prTxCell; + void *prAddr = NULL; + + prTxCell = &prTxRing->Cell[u4Idx]; + + if (prTxCell->prToken) + prAddr = prTxCell->prToken->prPacket; + else + prAddr = prTxCell->pBuffer; + + if (prAddr) + DBGLOG_MEM32(HAL, INFO, prAddr, u4DumpLen); +} + +static void axiDumpRx(struct GL_HIF_INFO *prHifInfo, + struct RTMP_RX_RING *prRxRing, + uint32_t u4Idx, uint32_t u4DumpLen) +{ + struct RTMP_DMACB *prRxCell; + struct RTMP_DMABUF *prDmaBuf; + + prRxCell = &prRxRing->Cell[u4Idx]; + prDmaBuf = &prRxCell->DmaBuf; + + if (!prRxCell->pPacket) + return; + + axiUnmapRxBuf(prHifInfo, prDmaBuf->AllocPa, prDmaBuf->AllocSize); + + DBGLOG_MEM32(HAL, INFO, ((struct sk_buff *)prRxCell->pPacket)->data, + u4DumpLen); + + prDmaBuf->AllocPa = axiMapRxBuf(prHifInfo, prDmaBuf->AllocVa, + 0, prDmaBuf->AllocSize); +} +#endif /* AXI_CFG_PREALLOC_MEMORY_BUFFER */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/axi/include/hif.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/axi/include/hif.h new file mode 100644 index 0000000000000000000000000000000000000000..0a3680beb8b368a062e58958b68d7d363c36746f --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/axi/include/hif.h @@ -0,0 +1,409 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/*! \file "hif.h" + * \brief Functions for the driver to register bus and setup the IRQ + * + * Functions for the driver to register bus and setup the IRQ + */ + +#ifndef _HIF_H +#define _HIF_H + +#include "hif_pdma.h" + +#if defined(_HIF_AXI) +#define HIF_NAME "AXI" +#else +#error "No HIF defined!" +#endif + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#if CFG_MTK_ANDROID_WMT +#if (CFG_SUPPORT_CONNINFRA == 0) +extern int mtk_wcn_consys_hw_wifi_paldo_ctrl(unsigned int enable); +#else +struct MTK_WCN_WLAN_CB_INFO; +extern int mtk_wcn_wlan_reg( + struct MTK_WCN_WLAN_CB_INFO *pWlanCbInfo); +extern int mtk_wcn_wlan_unreg(void); +#endif /*end of CFG_SUPPORT_CONNINFRA == 0*/ +#endif /*end of CFG_MTK_ANDROID_WMT */ + +#if (CFG_SUPPORT_CONNINFRA == 1) +extern wait_queue_head_t g_waitq_rst; +extern unsigned long g_ulFlag; +extern KAL_WAKE_LOCK_T *g_IntrWakeLock; +#endif +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#define AXI_CFG_PREALLOC_MEMORY_BUFFER 1 + +#define AXI_TX_MAX_SIZE_PER_FRAME (NIC_TX_MAX_SIZE_PER_FRAME + \ + NIC_TX_DESC_AND_PADDING_LENGTH) + +#define AXI_TX_CMD_BUFF_SIZE 4096 +#define AXI_WLAN_IRQ_NUMBER 16 + +#if (CFG_SUPPORT_CONNINFRA == 1) +#define WIFI_EMI_WFDMA_OFFSET 0x450000 +#define WIFI_EMI_WFDMA_SIZE 0xF20000 +#endif + + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +struct GL_HIF_INFO; + +struct HIF_MEM_OPS { + void (*allocTxDesc)(struct GL_HIF_INFO *prHifInfo, + struct RTMP_DMABUF *prDescRing, + uint32_t u4Num); + void (*allocRxDesc)(struct GL_HIF_INFO *prHifInfo, + struct RTMP_DMABUF *prDescRing, + uint32_t u4Num); + bool (*allocTxCmdBuf)(struct RTMP_DMABUF *prDmaBuf, + uint32_t u4Num, uint32_t u4Idx); + void (*allocTxDataBuf)(struct MSDU_TOKEN_ENTRY *prToken, + uint32_t u4Idx); + void *(*allocRxBuf)(struct GL_HIF_INFO *prHifInfo, + struct RTMP_DMABUF *prDmaBuf, + uint32_t u4Num, uint32_t u4Idx); + void *(*allocRuntimeMem)(uint32_t u4SrcLen); + bool (*copyCmd)(struct GL_HIF_INFO *prHifInfo, + struct RTMP_DMACB *prTxCell, void *pucBuf, + void *pucSrc1, uint32_t u4SrcLen1, + void *pucSrc2, uint32_t u4SrcLen2); + bool (*copyEvent)(struct GL_HIF_INFO *prHifInfo, + struct RTMP_DMACB *pRxCell, + struct RXD_STRUCT *pRxD, + struct RTMP_DMABUF *prDmaBuf, + uint8_t *pucDst, uint32_t u4Len); + bool (*copyTxData)(struct MSDU_TOKEN_ENTRY *prToken, + void *pucSrc, uint32_t u4Len); + bool (*copyRxData)(struct GL_HIF_INFO *prHifInfo, + struct RTMP_DMACB *pRxCell, + struct RTMP_DMABUF *prDmaBuf, + struct SW_RFB *prSwRfb); + phys_addr_t (*mapTxBuf)(struct GL_HIF_INFO *prHifInfo, + void *pucBuf, uint32_t u4Offset, uint32_t u4Len); + phys_addr_t (*mapRxBuf)(struct GL_HIF_INFO *prHifInfo, + void *pucBuf, uint32_t u4Offset, uint32_t u4Len); + void (*unmapTxBuf)(struct GL_HIF_INFO *prHifInfo, + phys_addr_t rDmaAddr, uint32_t u4Len); + void (*unmapRxBuf)(struct GL_HIF_INFO *prHifInfo, + phys_addr_t rDmaAddr, uint32_t u4Len); + void (*freeDesc)(struct GL_HIF_INFO *prHifInfo, + struct RTMP_DMABUF *prDescRing); + void (*freeBuf)(void *pucSrc, uint32_t u4Len); + void (*freePacket)(void *pvPacket); + void (*dumpTx)(struct GL_HIF_INFO *prHifInfo, + struct RTMP_TX_RING *prTxRing, + uint32_t u4Idx, uint32_t u4DumpLen); + void (*dumpRx)(struct GL_HIF_INFO *prHifInfo, + struct RTMP_RX_RING *prRxRing, + uint32_t u4Idx, uint32_t u4DumpLen); +}; + +/* host interface's private data structure, which is attached to os glue + ** layer info structure. + */ +struct GL_HIF_INFO { + struct platform_device *pdev; + struct device *prDmaDev; + struct HIF_MEM_OPS rMemOps; + + uint32_t u4IrqId; +#if (CFG_SUPPORT_CONNINFRA == 1) + uint32_t u4IrqId_1; +#endif + int32_t u4HifCnt; + + /* AXI MMIO Base Address, all access will use */ + void *CSRBaseAddress; + + /* Shared memory of all 1st pre-allocated + * TxBuf associated with each TXD + */ + /* Shared memory for Tx descriptors */ + struct RTMP_DMABUF TxDescRing[NUM_OF_TX_RING]; + struct RTMP_TX_RING TxRing[NUM_OF_TX_RING]; /* AC0~3 + HCCA */ + + /* Shared memory for RX descriptors */ + struct RTMP_DMABUF RxDescRing[NUM_OF_RX_RING]; + struct RTMP_RX_RING RxRing[NUM_OF_RX_RING]; + + u_int8_t fgIntReadClear; + u_int8_t fgMbxReadClear; + + uint32_t u4IntStatus; + + struct MSDU_TOKEN_INFO rTokenInfo; + + struct ERR_RECOVERY_CTRL_T rErrRecoveryCtl; + struct timer_list rSerTimer; + u_int64_t rSerTimerData; + struct list_head rTxCmdQ; + struct list_head rTxDataQ; + uint32_t u4TxDataQLen; + + bool fgIsPowerOff; + bool fgIsDumpLog; +}; + +struct BUS_INFO { + const uint32_t top_cfg_base; /* TOP_CFG_BASE address */ + const struct PCIE_CHIP_CR_MAPPING *bus2chip; + const uint32_t tx_ring_cmd_idx; + const uint32_t tx_ring_wa_cmd_idx; + const uint32_t tx_ring_fwdl_idx; + const uint32_t tx_ring0_data_idx; + const uint32_t tx_ring1_data_idx; + const uint32_t max_static_map_addr; + const uint32_t fw_own_clear_addr; + const uint32_t fw_own_clear_bit; + const bool fgCheckDriverOwnInt; + const uint32_t u4DmaMask; + /* host pdma/wfdma0 base address */ + const uint32_t host_dma0_base; + /* host wfdma1 base address */ + const uint32_t host_dma1_base; + /* host ext conn hif wrap */ + const uint32_t host_ext_conn_hif_wrap_base; + const uint32_t host_int_status_addr; + const uint32_t host_int_txdone_bits; + const uint32_t host_int_rxdone_bits; + + /* tx pdma/wfdma ring base address */ + const uint32_t host_tx_ring_base; + /* tx pdma/wfdma ring ext control base address */ + const uint32_t host_tx_ring_ext_ctrl_base; + /* tx pdma/wfdma ring cpu index address */ + const uint32_t host_tx_ring_cidx_addr; + /* tx pdma/wfdma ring dma index address */ + const uint32_t host_tx_ring_didx_addr; + /* tx pdma/wfdma ring count address */ + const uint32_t host_tx_ring_cnt_addr; + + /* rx pdma/wfdma ring base address */ + const uint32_t host_rx_ring_base; + /* rx pdma/wfdma ring ext control base address */ + const uint32_t host_rx_ring_ext_ctrl_base; + /* rx pdma/wfdma ring cpu index address */ + const uint32_t host_rx_ring_cidx_addr; + /* rx pdma/wfdma ring dma index address */ + const uint32_t host_rx_ring_didx_addr; + /* rx pdma/wfdma ring count address */ + const uint32_t host_rx_ring_cnt_addr; + +#if (CFG_SUPPORT_CONNAC2X == 1) + /* rx wfdma_1 ring base address */ + const uint32_t host_wfdma1_rx_ring_base; + /* rx wfdma_1 ring cpu index address */ + const uint32_t host_wfdma1_rx_ring_cidx_addr; + /* rx wfdma_1 ring dma index address */ + const uint32_t host_wfdma1_rx_ring_didx_addr; + /* rx wfdma_1 ring count address */ + const uint32_t host_wfdma1_rx_ring_cnt_addr; + /* rx wfdma_1 ring ext control base address */ + const uint32_t host_wfdma1_rx_ring_ext_ctrl_base; +#endif /* CFG_SUPPORT_CONNAC2X == 1 */ + + void (*pdmaSetup)(struct GLUE_INFO *prGlueInfo, u_int8_t enable, + bool fgResetHif); + uint32_t (*updateTxRingMaxQuota)(struct ADAPTER *prAdapter, + uint16_t u2Port, uint32_t u4MaxQuota); + void (*enableInterrupt)(struct ADAPTER *prAdapter); + void (*disableInterrupt)(struct ADAPTER *prAdapter); + void (*processTxInterrupt)(struct ADAPTER *prAdapter); + void (*processRxInterrupt)(struct ADAPTER *prAdapter); + void (*lowPowerOwnRead)(struct ADAPTER *prAdapter, u_int8_t *pfgResult); + void (*lowPowerOwnSet)(struct ADAPTER *prAdapter, u_int8_t *pfgResult); + void (*lowPowerOwnClear)(struct ADAPTER *prAdapter, + u_int8_t *pfgResult); + void (*wakeUpWiFi)(struct ADAPTER *prAdapter); + bool (*isValidRegAccess)(struct ADAPTER *prAdapter, + uint32_t u4Register); + void (*getMailboxStatus)(struct ADAPTER *prAdapter, uint32_t *pu4Val); + void (*setDummyReg)(struct GLUE_INFO *prGlueInfo); + void (*checkDummyReg)(struct GLUE_INFO *prGlueInfo); + void (*tx_ring_ext_ctrl)(struct GLUE_INFO *prGlueInfo, + struct RTMP_TX_RING *tx_ring, uint32_t index); + void (*rx_ring_ext_ctrl)(struct GLUE_INFO *prGlueInfo, + struct RTMP_RX_RING *rx_ring, uint32_t index); + void (*wfdmaManualPrefetch)(struct GLUE_INFO *prGlueInfo); + void (*processSoftwareInterrupt)(IN struct ADAPTER *prAdapter); + void (*softwareInterruptMcu)(IN struct ADAPTER *prAdapter, + u_int32_t intrBitMask); + void (*hifRst)(struct GLUE_INFO *prGlueInfo); + void (*initPcieInt)(struct GLUE_INFO *prGlueInfo); + void (*devReadIntStatus)(struct ADAPTER *prAdapter, + OUT uint32_t *pu4IntStatus); + void (*DmaShdlInit)(IN struct ADAPTER *prAdapter); + uint8_t (*setRxRingHwAddr)(struct RTMP_RX_RING *prRxRing, + struct BUS_INFO *prBusInfo, + uint32_t u4SwRingIdx); + bool (*wfdmaAllocRxRing)( + struct GLUE_INFO *prGlueInfo, + bool fgAllocMem); + void (*setPdmaIntMask)(struct GLUE_INFO *prGlueInfo, u_int8_t fgEnable); +}; + +struct HIF_MEM { + phys_addr_t pa; + void *va; +}; + +struct HIF_PREALLOC_MEM { + struct HIF_MEM rTxDesc[NUM_OF_TX_RING]; + struct HIF_MEM rRxDesc[NUM_OF_RX_RING]; + /* Tx Command */ + struct HIF_MEM rTxCmdBuf[TX_RING_SIZE]; + /* Rx Data */ + struct HIF_MEM rRxDataBuf[RX_RING0_SIZE]; + +#if (CFG_SUPPORT_CONNAC2X == 1) + /* Connac1.0 = RX Event, Connac2.0 = Rx Data band1 */ + struct HIF_MEM rRxEventBuf[RX_RING0_SIZE]; + /* Band 0 TxFreeDoneEvent */ + struct HIF_MEM wfdma0_rx_ring_idx2[RX_RING1_SIZE]; + /* Band 1 TxFreeDoneEvent */ + struct HIF_MEM wfdma0_rx_ring_idx3[RX_RING1_SIZE]; + /* WM Event */ + struct HIF_MEM wfdma1_rx_ring_idx0[RX_RING1_SIZE]; +#else + /* Connac1.0 = RX Event, Connac2.0 = Rx Data band1 */ + struct HIF_MEM rRxEventBuf[RX_RING1_SIZE]; +#endif /* CFG_SUPPORT_CONNAC2X == 1 */ + +#if HIF_TX_PREALLOC_DATA_BUFFER + /* Tx Data */ + struct HIF_MEM rMsduBuf[HIF_TX_MSDU_TOKEN_NUM]; +#endif + phys_addr_t pucRsvMemBase; + void *pucRsvMemVirBase; + uint64_t u4RsvMemSize; + uint32_t u4Offset; +}; + +#if CFG_MTK_ANDROID_WMT +#if (CFG_SUPPORT_CONNINFRA == 1) +struct MTK_WCN_WLAN_CB_INFO { + int (*wlan_probe_cb)(void); + int (*wlan_remove_cb)(void); +}; + +#endif /*end of CFG_SUPPORT_CONNINFRA == 0*/ +#endif /*end of CFG_MTK_ANDROID_WMT */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +#define axi_resource_start(d, v) (0x18000000) +#define axi_resource_len(d, v) (0x100000) +#define axi_name(d) ("AXI-BUS") + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +uint32_t glRegisterBus(probe_card pfProbe, remove_card pfRemove); + +void glUnregisterBus(remove_card pfRemove); + +void glSetHifInfo(struct GLUE_INFO *prGlueInfo, unsigned long ulCookie); + +void glClearHifInfo(struct GLUE_INFO *prGlueInfo); + +u_int8_t glBusInit(void *pvData); + +void glBusRelease(void *pData); + +int32_t glBusSetIrq(void *pvData, void *pfnIsr, void *pvCookie); + +void glBusFreeIrq(void *pvData, void *pvCookie); + +void glSetPowerState(IN struct GLUE_INFO *prGlueInfo, IN uint32_t ePowerMode); + +void glGetDev(void *ctx, struct device **dev); + +void glGetHifDev(struct GL_HIF_INFO *prHif, struct device **dev); + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +#endif /* _HIF_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/common/dbg_pdma.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/common/dbg_pdma.c new file mode 100644 index 0000000000000000000000000000000000000000..5cc5c941a625e01a5e4edb75184deb3413c82d5c --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/common/dbg_pdma.c @@ -0,0 +1,898 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/****************************************************************************** + *[File] dbg_pdma.c + *[Version] v1.0 + *[Revision Date] 2015-09-08 + *[Author] + *[Description] + * The program provides PDMA HIF APIs + *[Copyright] + * Copyright (C) 2015 MediaTek Incorporation. All Rights Reserved. + ******************************************************************************/ + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" + +#include "pse.h" +#include "wf_ple.h" +#include "host_csr.h" +#include "dma_sch.h" +#include "mt_dmac.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +struct wfdma_ring_info { + char name[20]; + uint32_t ring_idx; + bool dump_ring_content; + + /* query from register */ + uint32_t base; + uint32_t base_ext; + uint32_t cnt; + uint32_t cidx; + uint32_t didx; +}; + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +static void halCheckHifState(struct ADAPTER *prAdapter); +static void halDumpHifDebugLog(struct ADAPTER *prAdapter); +static bool halIsTxHang(struct ADAPTER *prAdapter); + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +void halPrintHifDbgInfo(IN struct ADAPTER *prAdapter) +{ + if (!prAdapter->fgIsFwOwn) { + halCheckHifState(prAdapter); + halDumpHifDebugLog(prAdapter); + } + if (prAdapter->chip_info->dumpwfsyscpupcr) + prAdapter->chip_info->dumpwfsyscpupcr(prAdapter); +} + +static void halCheckHifState(struct ADAPTER *prAdapter) +{ + uint32_t u4DebugLevel = 0; + if (prAdapter->u4HifChkFlag & HIF_CHK_TX_HANG) { + if (halIsTxHang(prAdapter)) { + DBGLOG(HAL, ERROR, + "Tx timeout, set hif debug info flag\n"); + wlanGetDriverDbgLevel(DBG_TX_IDX, &u4DebugLevel); + if (u4DebugLevel & DBG_CLASS_TRACE) { + DBGLOG(HAL, ERROR, "Set debug flag bit\n"); + prAdapter->u4HifDbgFlag |= DEG_HIF_ALL; + } + else { + struct CHIP_DBG_OPS *prDbgOps; + + prDbgOps = prAdapter->chip_info->prDebugOps; + DBGLOG(HAL, ERROR, "Dump debug info\n"); + if (prDbgOps && prDbgOps->showPleInfo) + prDbgOps->showPleInfo(prAdapter, FALSE); + + if (prDbgOps && prDbgOps->showPseInfo) + prDbgOps->showPseInfo(prAdapter); + + if (prDbgOps && prDbgOps->showPdmaInfo) + prDbgOps->showPdmaInfo(prAdapter); + + if (prDbgOps && prDbgOps->showDmaschInfo) + prDbgOps->showDmaschInfo(prAdapter); + + if (prDbgOps && prDbgOps->dumpMacInfo) + prDbgOps->dumpMacInfo(prAdapter); + + } + } + } + + if (prAdapter->u4HifChkFlag & HIF_DRV_SER) + halSetDrvSer(prAdapter); + + prAdapter->u4HifChkFlag = 0; +} + +static void halDumpHifDebugLog(struct ADAPTER *prAdapter) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct GL_HIF_INFO *prHifInfo = NULL; + struct CHIP_DBG_OPS *prDbgOps; + uint32_t ret = 0; + + ASSERT(prAdapter); + prGlueInfo = prAdapter->prGlueInfo; + ASSERT(prGlueInfo); + prHifInfo = &prGlueInfo->rHifInfo; + + /* Avoid register checking */ + prHifInfo->fgIsDumpLog = true; + + prDbgOps = prAdapter->chip_info->prDebugOps; + + if (prAdapter->u4HifDbgFlag & (DEG_HIF_ALL | DEG_HIF_HOST_CSR)) { + if (prDbgOps->showCsrInfo) { + bool fgIsClkEn = prDbgOps->showCsrInfo(prAdapter); + + if (!fgIsClkEn) + return; + } + } + + /* need to check Bus readable */ + if (prAdapter->chip_info->checkbushang) { + ret = prAdapter->chip_info->checkbushang((void *) prAdapter, + TRUE); + if (ret != 0) { + DBGLOG(HAL, ERROR, + "return due to checkbushang fail %d\n", ret); + return; + } + } + + /* Check Driver own HW CR */ + { + struct BUS_INFO *prBusInfo = NULL; + u_int8_t driver_owen_result = 0; + + prBusInfo = prGlueInfo->prAdapter->chip_info->bus_info; + + if (prBusInfo->lowPowerOwnRead) + prBusInfo->lowPowerOwnRead(prGlueInfo->prAdapter, + &driver_owen_result); + else { + DBGLOG(HAL, ERROR, "retrun due to null API\n"); + return; + } + + if (driver_owen_result == 0) { + DBGLOG(HAL, ERROR, "return, not driver-own[%d]\n", + driver_owen_result); + return; + } + } + + if (prAdapter->u4HifDbgFlag & (DEG_HIF_ALL | DEG_HIF_PLE)) { + if (prDbgOps && prDbgOps->showPleInfo) + prDbgOps->showPleInfo(prAdapter, FALSE); + } + + if (prAdapter->u4HifDbgFlag & (DEG_HIF_ALL | DEG_HIF_PSE)) { + if (prDbgOps && prDbgOps->showPseInfo) + prDbgOps->showPseInfo(prAdapter); + } + + if (prAdapter->u4HifDbgFlag & (DEG_HIF_ALL | DEG_HIF_PDMA)) { + if (prDbgOps && prDbgOps->showPdmaInfo) + prDbgOps->showPdmaInfo(prAdapter); + } + + if (prAdapter->u4HifDbgFlag & (DEG_HIF_ALL | DEG_HIF_DMASCH)) { + if (prDbgOps && prDbgOps->showDmaschInfo) + prDbgOps->showDmaschInfo(prAdapter); + } + + if (prAdapter->u4HifDbgFlag & (DEG_HIF_ALL | DEG_HIF_MAC)) { + if (prDbgOps && prDbgOps->dumpMacInfo) + prDbgOps->dumpMacInfo(prAdapter); + } + + if (prAdapter->u4HifDbgFlag & (DEG_HIF_ALL | DEG_HIF_PHY)) + haldumpPhyInfo(prAdapter); + + prHifInfo->fgIsDumpLog = false; + prAdapter->u4HifDbgFlag = 0; +} + +static void halDumpTxRing(IN struct GLUE_INFO *prGlueInfo, + IN uint16_t u2Port, IN uint32_t u4Idx) +{ + struct GL_HIF_INFO *prHifInfo = &prGlueInfo->rHifInfo; + struct RTMP_TX_RING *prTxRing; + struct TXD_STRUCT *pTxD; + + if (u2Port >= NUM_OF_TX_RING || u4Idx >= TX_RING_SIZE) { + DBGLOG(HAL, INFO, "Dump fail u2Port[%u] u4Idx[%u]\n", + u2Port, u4Idx); + return; + } + + prTxRing = &prHifInfo->TxRing[u2Port]; + + pTxD = (struct TXD_STRUCT *) prTxRing->Cell[u4Idx].AllocVa; + + log_dbg(SW4, INFO, "TX Ring[%u] Idx[%04u] SDP0[0x%08x] SDL0[%u] LS[%u] B[%u] DDONE[%u] SDP0_EXT[%u]\n", + u2Port, u4Idx, pTxD->SDPtr0, pTxD->SDLen0, pTxD->LastSec0, + pTxD->Burst, pTxD->DMADONE, pTxD->SDPtr0Ext); +} + +uint32_t halDumpHifStatus(IN struct ADAPTER *prAdapter, + IN uint8_t *pucBuf, IN uint32_t u4Max) +{ + struct GLUE_INFO *prGlueInfo = prAdapter->prGlueInfo; + struct GL_HIF_INFO *prHifInfo = &prGlueInfo->rHifInfo; + uint32_t u4Idx, u4DmaIdx = 0; + uint32_t u4CpuIdx = 0, u4MaxCnt = 0; + uint32_t u4Len = 0; + struct RTMP_TX_RING *prTxRing; + struct RTMP_RX_RING *prRxRing; + + LOGBUF(pucBuf, u4Max, u4Len, "\n------------\n"); + + for (u4Idx = 0; u4Idx < NUM_OF_TX_RING; u4Idx++) { + prTxRing = &prHifInfo->TxRing[u4Idx]; + kalDevRegRead(prGlueInfo, prTxRing->hw_cnt_addr, &u4MaxCnt); + kalDevRegRead(prGlueInfo, prTxRing->hw_cidx_addr, &u4CpuIdx); + kalDevRegRead(prGlueInfo, prTxRing->hw_didx_addr, &u4DmaIdx); + + LOGBUF(pucBuf, u4Max, u4Len, + "TX[%u] SZ[%04u] CPU[%04u/%04u] DMA[%04u/%04u] SW_UD[%04u] Used[%u]\n", + u4Idx, u4MaxCnt, prTxRing->TxCpuIdx, + u4CpuIdx, prTxRing->TxDmaIdx, + u4DmaIdx, prTxRing->TxSwUsedIdx, prTxRing->u4UsedCnt); + + if (u4Idx == TX_RING_DATA0_IDX_0) { + halDumpTxRing(prGlueInfo, u4Idx, prTxRing->TxCpuIdx); + halDumpTxRing(prGlueInfo, u4Idx, u4CpuIdx); + halDumpTxRing(prGlueInfo, u4Idx, u4DmaIdx); + halDumpTxRing(prGlueInfo, u4Idx, prTxRing->TxSwUsedIdx); + } + + if (u4Idx == TX_RING_DATA1_IDX_1) { + halDumpTxRing(prGlueInfo, u4Idx, prTxRing->TxCpuIdx); + halDumpTxRing(prGlueInfo, u4Idx, u4CpuIdx); + halDumpTxRing(prGlueInfo, u4Idx, u4DmaIdx); + halDumpTxRing(prGlueInfo, u4Idx, prTxRing->TxSwUsedIdx); + } + } + + for (u4Idx = 0; u4Idx < NUM_OF_RX_RING; u4Idx++) { + prRxRing = &prHifInfo->RxRing[u4Idx]; + + kalDevRegRead(prGlueInfo, prRxRing->hw_cnt_addr, &u4MaxCnt); + kalDevRegRead(prGlueInfo, prRxRing->hw_cidx_addr, &u4CpuIdx); + kalDevRegRead(prGlueInfo, prRxRing->hw_didx_addr, &u4DmaIdx); + + LOGBUF(pucBuf, u4Max, u4Len, + "RX[%u] SZ[%04u] CPU[%04u/%04u] DMA[%04u/%04u]\n", + u4Idx, u4MaxCnt, prRxRing->RxCpuIdx, u4CpuIdx, + prRxRing->RxDmaIdx, u4DmaIdx); + } + + LOGBUF(pucBuf, u4Max, u4Len, "MSDU Tok: Free[%u] Used[%u]\n", + halGetMsduTokenFreeCnt(prGlueInfo->prAdapter), + prGlueInfo->rHifInfo.rTokenInfo.u4UsedCnt); + LOGBUF(pucBuf, u4Max, u4Len, "Pending QLen Normal[%u] Sec[%u]\n", + prGlueInfo->i4TxPendingFrameNum, + prGlueInfo->i4TxPendingSecurityFrameNum); + + LOGBUF(pucBuf, u4Max, u4Len, "---------------------------------\n\n"); + + return u4Len; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Compare two struct timeval + * + * @param prTs1 a pointer to timeval + * @param prTs2 a pointer to timeval + * + * + * @retval 0 two time value is equal + * @retval 1 prTs1 value > prTs2 value + * @retval -1 prTs1 value < prTs2 value + */ +/*----------------------------------------------------------------------------*/ +int halTimeCompare(struct timeval *prTs1, struct timeval *prTs2) +{ + if (prTs1->tv_sec > prTs2->tv_sec) + return 1; + else if (prTs1->tv_sec < prTs2->tv_sec) + return -1; + /* sec part is equal */ + else if (prTs1->tv_usec > prTs2->tv_usec) + return 1; + else if (prTs1->tv_usec < prTs2->tv_usec) + return -1; + return 0; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Checking tx hang + * + * @param prAdapter a pointer to adapter private data structure. + * + * @retval true tx is hang because msdu report too long + */ +/*----------------------------------------------------------------------------*/ +static bool halIsTxHang(struct ADAPTER *prAdapter) +{ + struct MSDU_TOKEN_INFO *prTokenInfo; + struct MSDU_TOKEN_ENTRY *prToken; + struct timeval rNowTs, rTime, rLongest, rTimeout; + uint32_t u4Idx = 0, u4TokenId = 0; + bool fgIsTimeout = false; + struct WIFI_VAR *prWifiVar; + + ASSERT(prAdapter); + ASSERT(prAdapter->prGlueInfo); + + prTokenInfo = &prAdapter->prGlueInfo->rHifInfo.rTokenInfo; + prWifiVar = &prAdapter->rWifiVar; + + rTimeout.tv_sec = prWifiVar->ucMsduReportTimeout; + rTimeout.tv_usec = 0; + rLongest.tv_sec = 0; + rLongest.tv_usec = 0; + do_gettimeofday(&rNowTs); + + for (u4Idx = 0; u4Idx < HIF_TX_MSDU_TOKEN_NUM; u4Idx++) { + prToken = &prTokenInfo->arToken[u4Idx]; + if (!prToken->fgInUsed) + continue; + + /* Ignore now time < token time */ + if (halTimeCompare(&rNowTs, &prToken->rTs) < 0) + continue; + + rTime.tv_sec = rNowTs.tv_sec - prToken->rTs.tv_sec; + rTime.tv_usec = rNowTs.tv_usec; + if (prToken->rTs.tv_usec > rNowTs.tv_usec) { + rTime.tv_sec -= 1; + rTime.tv_usec += SEC_TO_USEC(1); + } + rTime.tv_usec -= prToken->rTs.tv_usec; + + if (halTimeCompare(&rTime, &rTimeout) >= 0) + fgIsTimeout = true; + + /* rTime > rLongest */ + if (halTimeCompare(&rTime, &rLongest) > 0) { + rLongest.tv_sec = rTime.tv_sec; + rLongest.tv_usec = rTime.tv_usec; + u4TokenId = u4Idx; + } + } + + if (fgIsTimeout) { + prToken = &prTokenInfo->arToken[u4TokenId]; + DBGLOG(HAL, INFO, "TokenId[%u] Wlan_Idx[%u] timeout[sec:%ld]\n", + u4TokenId, + prToken->ucWlanIndex, + rLongest.tv_sec); + if (prToken->prPacket) + DBGLOG_MEM32(HAL, INFO, prToken->prPacket, 64); + } + + return fgIsTimeout; +} + +void kalDumpTxRing(struct GLUE_INFO *prGlueInfo, + struct RTMP_TX_RING *prTxRing, + uint32_t u4Num, bool fgDumpContent) +{ + struct GL_HIF_INFO *prHifInfo = NULL; + struct HIF_MEM_OPS *prMemOps; + struct RTMP_DMACB *pTxCell; + struct TXD_STRUCT *pTxD; + uint32_t u4DumpLen = 64; + + ASSERT(prGlueInfo); + prHifInfo = &prGlueInfo->rHifInfo; + prMemOps = &prHifInfo->rMemOps; + + if (u4Num >= TX_RING_SIZE) + return; + + pTxCell = &prTxRing->Cell[u4Num]; + pTxD = (struct TXD_STRUCT *) pTxCell->AllocVa; + + if (!pTxD) + return; + + DBGLOG(HAL, INFO, "Tx Dese Num[%u]\n", u4Num); + DBGLOG_MEM32(HAL, INFO, pTxD, sizeof(struct TXD_STRUCT)); + + if (!fgDumpContent) + return; + + DBGLOG(HAL, INFO, "Tx Contents\n"); + if (prMemOps->dumpTx) + prMemOps->dumpTx(prHifInfo, prTxRing, u4Num, u4DumpLen); + DBGLOG(HAL, INFO, "\n\n"); +} + +void kalDumpRxRing(struct GLUE_INFO *prGlueInfo, + struct RTMP_RX_RING *prRxRing, + uint32_t u4Num, bool fgDumpContent) +{ + struct GL_HIF_INFO *prHifInfo = NULL; + struct HIF_MEM_OPS *prMemOps; + struct RTMP_DMACB *pRxCell; + struct RXD_STRUCT *pRxD; + uint32_t u4DumpLen = 64; + + ASSERT(prGlueInfo); + prHifInfo = &prGlueInfo->rHifInfo; + prMemOps = &prHifInfo->rMemOps; + + if (u4Num >= prRxRing->u4RingSize) + return; + + pRxCell = &prRxRing->Cell[u4Num]; + pRxD = (struct RXD_STRUCT *) pRxCell->AllocVa; + + if (!pRxD) + return; + + DBGLOG(HAL, INFO, "Rx Dese Num[%u]\n", u4Num); + DBGLOG_MEM32(HAL, INFO, pRxD, sizeof(struct RXD_STRUCT)); + + if (!fgDumpContent) + return; + + if (u4DumpLen > pRxD->SDLen0) + u4DumpLen = pRxD->SDLen0; + + DBGLOG(HAL, INFO, "Rx Contents\n"); + if (prMemOps->dumpRx) + prMemOps->dumpRx(prHifInfo, prRxRing, u4Num, u4DumpLen); + DBGLOG(HAL, INFO, "\n\n"); +} + +void halShowPdmaInfo(IN struct ADAPTER *prAdapter) +{ +#define BUF_SIZE 1024 + + uint32_t i = 0, u4Value = 0, pos = 0; + uint32_t offset, offset_ext, SwIdx; + char *buf; + struct GL_HIF_INFO *prHifInfo = NULL; + struct BUS_INFO *prBus_info = prAdapter->chip_info->bus_info; + struct RTMP_TX_RING *prTxRing; + struct RTMP_RX_RING *prRxRing; + struct wfdma_ring_info wfmda_tx_group[] = { + {"AP DATA0", prBus_info->tx_ring0_data_idx, true}, + {"AP DATA1", prBus_info->tx_ring1_data_idx, true}, + {"AP CMD", prBus_info->tx_ring_cmd_idx, true}, + {"FWDL", prBus_info->tx_ring_fwdl_idx, true}, +#if CFG_MTK_MCIF_WIFI_SUPPORT + {"MD DATA0", 8, false}, + {"MD DATA1", 9, false}, + {"MD CMD", 14, false}, +#endif + }; + struct wfdma_ring_info wfmda_rx_group[] = { + {"AP DATA", 0, true}, + {"AP EVENT", 1, true}, +#if CFG_MTK_MCIF_WIFI_SUPPORT + {"MD DATA", 2, false}, + {"MD EVENT", 3, false}, +#endif + }; + + buf = (char *) kalMemAlloc(BUF_SIZE, VIR_MEM_TYPE); + + /* PDMA HOST_INT */ + HAL_MCR_RD(prAdapter, WPDMA_INT_STA, &u4Value); + DBGLOG(HAL, INFO, "WPDMA HOST_INT:0x%08x = 0x%08x\n", + WPDMA_INT_STA, u4Value); + + /* PDMA GLOBAL_CFG */ + HAL_MCR_RD(prAdapter, WPDMA_GLO_CFG, &u4Value); + DBGLOG(HAL, INFO, "WPDMA GLOBAL_CFG:0x%08x = 0x%08x\n", + WPDMA_GLO_CFG, u4Value); + + HAL_MCR_RD(prAdapter, CONN_HIF_RST, &u4Value); + DBGLOG(HAL, INFO, "WPDMA CONN_HIF_RST:0x%08x = 0x%08x\n", + CONN_HIF_RST, u4Value); + + HAL_MCR_RD(prAdapter, MCU2HOST_SW_INT_STA, &u4Value); + DBGLOG(HAL, INFO, "WPDMA MCU2HOST_SW_INT_STA:0x%08x = 0x%08x\n", + MCU2HOST_SW_INT_STA, u4Value); + +#if CFG_MTK_MCIF_WIFI_SUPPORT + HAL_MCR_RD(prAdapter, MD_INT_STA, &u4Value); + DBGLOG(HAL, INFO, "MD_INT_STA:0x%08x = 0x%08x\n", + MD_INT_STA, u4Value); + HAL_MCR_RD(prAdapter, MD_WPDMA_GLO_CFG, &u4Value); + DBGLOG(HAL, INFO, "MD_WPDMA_GLO_CFG:0x%08x = 0x%08x\n", + MD_WPDMA_GLO_CFG, u4Value); + HAL_MCR_RD(prAdapter, MD_INT_ENA, &u4Value); + DBGLOG(HAL, INFO, "MD_INT_ENA:0x%08x = 0x%08x\n", + MD_INT_ENA, u4Value); + HAL_MCR_RD(prAdapter, MD_WPDMA_DLY_INIT_CFG, &u4Value); + DBGLOG(HAL, INFO, "MD_WPDMA_DLY_INIT_CFG:0x%08x = 0x%08x\n", + MD_WPDMA_DLY_INIT_CFG, u4Value); + HAL_MCR_RD(prAdapter, MD_WPDMA_MISC, &u4Value); + DBGLOG(HAL, INFO, "MD_WPDMA_MISC:0x%08x = 0x%08x\n", + MD_WPDMA_MISC, u4Value); +#endif + + /* PDMA Tx/Rx Ring Info */ + DBGLOG(HAL, INFO, "Tx Ring configuration\n"); + DBGLOG(HAL, INFO, "%10s%10s%12s%20s%10s%10s%10s\n", + "Tx Ring", "Idx", "Reg", "Base", "Cnt", "CIDX", "DIDX"); + + if (buf) { + kalMemZero(buf, BUF_SIZE); + for (i = 0; i < sizeof(wfmda_tx_group) / + sizeof(struct wfdma_ring_info); i++) { + int ret; + + offset = wfmda_tx_group[i].ring_idx * + MT_RINGREG_DIFF; + offset_ext = wfmda_tx_group[i].ring_idx * + MT_RINGREG_EXT_DIFF; + + HAL_MCR_RD(prAdapter, WPDMA_TX_RING0_CTRL0 + offset, + &wfmda_tx_group[i].base); + HAL_MCR_RD(prAdapter, WPDMA_TX_RING0_BASE_PTR_EXT + + offset_ext, + &wfmda_tx_group[i].base_ext); + HAL_MCR_RD(prAdapter, WPDMA_TX_RING0_CTRL1 + offset, + &wfmda_tx_group[i].cnt); + HAL_MCR_RD(prAdapter, WPDMA_TX_RING0_CTRL2 + offset, + &wfmda_tx_group[i].cidx); + HAL_MCR_RD(prAdapter, WPDMA_TX_RING0_CTRL3 + offset, + &wfmda_tx_group[i].didx); + + ret = kalSnprintf(buf, BUF_SIZE, + "%10s%10d 0x%08x 0x%016llx%10d%10d%10d", + wfmda_tx_group[i].name, + wfmda_tx_group[i].ring_idx, + WPDMA_TX_RING0_CTRL0 + offset, + (wfmda_tx_group[i].base + ((uint64_t) + wfmda_tx_group[i].base_ext << 32)), + wfmda_tx_group[i].cnt, + wfmda_tx_group[i].cidx, + wfmda_tx_group[i].didx); + if (ret >= 0 || ret < BUF_SIZE) + DBGLOG(HAL, INFO, "%s\n", buf); + else + DBGLOG(INIT, ERROR, + "[%u] kalSnprintf failed, ret: %d\n", + __LINE__, ret); + } + + DBGLOG(HAL, INFO, "Rx Ring configuration\n"); + DBGLOG(HAL, INFO, "%10s%10s%12s%20s%10s%10s%10s\n", + "Rx Ring", "Idx", "Reg", "Base", "Cnt", "CIDX", "DIDX"); + + kalMemZero(buf, BUF_SIZE); + for (i = 0; i < sizeof(wfmda_rx_group) / + sizeof(struct wfdma_ring_info); i++) { + int ret; + + offset = wfmda_rx_group[i].ring_idx * MT_RINGREG_DIFF; + offset_ext = wfmda_rx_group[i].ring_idx * + MT_RINGREG_EXT_DIFF; + + HAL_MCR_RD(prAdapter, WPDMA_RX_RING0_CTRL0 + offset, + &wfmda_rx_group[i].base); + HAL_MCR_RD(prAdapter, WPDMA_RX_RING0_BASE_PTR_EXT + + offset_ext, + &wfmda_rx_group[i].base_ext); + HAL_MCR_RD(prAdapter, WPDMA_RX_RING0_CTRL1 + offset, + &wfmda_rx_group[i].cnt); + HAL_MCR_RD(prAdapter, WPDMA_RX_RING0_CTRL2 + offset, + &wfmda_rx_group[i].cidx); + HAL_MCR_RD(prAdapter, WPDMA_RX_RING0_CTRL3 + offset, + &wfmda_rx_group[i].didx); + + ret = kalSnprintf(buf, BUF_SIZE, + "%10s%10d 0x%08x 0x%016llx%10d%10d%10d", + wfmda_rx_group[i].name, + wfmda_rx_group[i].ring_idx, + WPDMA_RX_RING0_CTRL0 + offset, + (wfmda_rx_group[i].base + ((uint64_t) + wfmda_rx_group[i].base_ext << 32)), + wfmda_rx_group[i].cnt, + wfmda_rx_group[i].cidx, + wfmda_rx_group[i].didx); + if (ret >= 0 || ret < BUF_SIZE) + DBGLOG(HAL, INFO, "%s\n", buf); + else + DBGLOG(INIT, ERROR, + "[%u] kalSnprintf failed, ret: %d\n", + __LINE__, ret); + } + } + + /* PDMA Tx/Rx descriptor & packet content */ + prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + + for (i = 0; i < sizeof(wfmda_tx_group) / + sizeof(struct wfdma_ring_info); i++) { + if (!wfmda_tx_group[i].dump_ring_content) + continue; + DBGLOG(HAL, INFO, "Dump PDMA Tx Ring[%u]\n", + wfmda_tx_group[i].ring_idx); + prTxRing = &prHifInfo->TxRing[i]; + SwIdx = wfmda_tx_group[i].didx; + kalDumpTxRing(prAdapter->prGlueInfo, prTxRing, + SwIdx, true); + SwIdx = wfmda_tx_group[i].didx == 0 ? + wfmda_tx_group[i].cnt - 1 : + wfmda_tx_group[i].didx - 1; + kalDumpTxRing(prAdapter->prGlueInfo, prTxRing, + SwIdx, true); + } + + for (i = 0; i < sizeof(wfmda_rx_group) / + sizeof(struct wfdma_ring_info); i++) { + if (!wfmda_rx_group[i].dump_ring_content) + continue; + DBGLOG(HAL, INFO, "Dump PDMA Rx Ring[%u]\n", + wfmda_rx_group[i].ring_idx); + prRxRing = &prHifInfo->RxRing[i]; + SwIdx = wfmda_rx_group[i].didx; + kalDumpRxRing(prAdapter->prGlueInfo, prRxRing, + SwIdx, true); + SwIdx = wfmda_rx_group[i].didx == 0 ? + wfmda_rx_group[i].cnt - 1 : + wfmda_rx_group[i].didx - 1; + kalDumpRxRing(prAdapter->prGlueInfo, prRxRing, + SwIdx, true); + } + + /* PDMA Busy Status */ + HAL_MCR_RD(prAdapter, PDMA_DEBUG_BUSY_STATUS, &u4Value); + DBGLOG(HAL, INFO, "PDMA busy status:0x%08x = 0x%08x\n", + PDMA_DEBUG_STATUS, u4Value); + HAL_MCR_RD(prAdapter, PDMA_DEBUG_HIF_BUSY_STATUS, &u4Value); + DBGLOG(HAL, INFO, "CONN_HIF busy status:0x%08x = 0x%08x\n\n", + PDMA_DEBUG_HIF_BUSY_STATUS, u4Value); + + /* PDMA Debug Flag Info */ + DBGLOG(HAL, INFO, "PDMA core dbg"); + if (buf) { + kalMemZero(buf, BUF_SIZE); + pos = 0; + for (i = 0; i < 24; i++) { + u4Value = 256 + i; + HAL_MCR_WR(prAdapter, PDMA_DEBUG_EN, u4Value); + HAL_MCR_RD(prAdapter, PDMA_DEBUG_STATUS, &u4Value); + pos += kalSnprintf(buf + pos, 40, + "Set:0x%02x, result=0x%08x%s", + i, u4Value, i == 23 ? "\n" : "; "); + mdelay(1); + } + DBGLOG(HAL, INFO, "%s", buf); + } + + /* AXI Debug Flag */ + HAL_MCR_WR(prAdapter, AXI_DEBUG_DEBUG_EN, PDMA_AXI_DEBUG_FLAG); + HAL_MCR_RD(prAdapter, CONN_HIF_DEBUG_STATUS, &u4Value); + DBGLOG(HAL, INFO, "Set:0x%04x, pdma axi dbg:0x%08x", + PDMA_AXI_DEBUG_FLAG, u4Value); + + HAL_MCR_WR(prAdapter, AXI_DEBUG_DEBUG_EN, GALS_AXI_DEBUG_FLAG); + HAL_MCR_RD(prAdapter, CONN_HIF_DEBUG_STATUS, &u4Value); + DBGLOG(HAL, INFO, "Set:0x%04x, gals axi dbg:0x%08x", + GALS_AXI_DEBUG_FLAG, u4Value); + + HAL_MCR_WR(prAdapter, AXI_DEBUG_DEBUG_EN, MCU_AXI_DEBUG_FLAG); + HAL_MCR_RD(prAdapter, CONN_HIF_DEBUG_STATUS, &u4Value); + DBGLOG(HAL, INFO, "Set:0x%04x, mcu axi dbg:0x%08x", + MCU_AXI_DEBUG_FLAG, u4Value); + + /* Rbus Bridge Debug Flag */ + DBGLOG(HAL, INFO, "rbus dbg"); + HAL_MCR_WR(prAdapter, PDMA_DEBUG_EN, RBUS_DEBUG_FLAG); + if (buf) { + kalMemZero(buf, BUF_SIZE); + pos = 0; + for (i = 0; i < 9; i++) { + u4Value = i << 16; + HAL_MCR_WR(prAdapter, AXI_DEBUG_DEBUG_EN, u4Value); + HAL_MCR_RD(prAdapter, PDMA_DEBUG_STATUS, &u4Value); + pos += kalSnprintf(buf + pos, 40, + "Set[19:16]:0x%02x, result = 0x%08x%s", + i, u4Value, i == 8 ? "\n" : "; "); + } + DBGLOG(HAL, INFO, "%s", buf); + } + if (prAdapter->chip_info->prDebugOps->showHifInfo) + prAdapter->chip_info->prDebugOps->showHifInfo(prAdapter); + if (buf) + kalMemFree(buf, VIR_MEM_TYPE, BUF_SIZE); + +#undef BUF_SIZE +} + +bool halShowHostCsrInfo(IN struct ADAPTER *prAdapter) +{ + uint32_t i = 0, u4Value = 0; + bool fgIsDriverOwn = false; + bool fgEnClock = false; + + DBGLOG(HAL, INFO, "Host CSR Configuration Info:\n\n"); + + HAL_MCR_RD(prAdapter, HOST_CSR_BASE, &u4Value); + DBGLOG(HAL, INFO, "Get 0x87654321: 0x%08x = 0x%08x\n", + HOST_CSR_BASE, u4Value); + + HAL_MCR_RD(prAdapter, HOST_CSR_DRIVER_OWN_INFO, &u4Value); + DBGLOG(HAL, INFO, "Driver own info: 0x%08x = 0x%08x\n", + HOST_CSR_BASE, u4Value); + fgIsDriverOwn = (u4Value & PCIE_LPCR_HOST_SET_OWN) == 0; + + for (i = 0; i < 5; i++) { + HAL_MCR_RD(prAdapter, HOST_CSR_MCU_PORG_COUNT, &u4Value); + DBGLOG(HAL, INFO, + "MCU programming Counter info (no sync): 0x%08x = 0x%08x\n", + HOST_CSR_MCU_PORG_COUNT, u4Value); + } + + HAL_MCR_RD(prAdapter, HOST_CSR_RGU, &u4Value); + DBGLOG(HAL, INFO, "RGU Info: 0x%08x = 0x%08x\n", HOST_CSR_RGU, u4Value); + + HAL_MCR_RD(prAdapter, HOST_CSR_HIF_BUSY_CORQ_WFSYS_ON, &u4Value); + DBGLOG(HAL, INFO, "HIF_BUSY / CIRQ / WFSYS_ON info: 0x%08x = 0x%08x\n", + HOST_CSR_HIF_BUSY_CORQ_WFSYS_ON, u4Value); + + HAL_MCR_RD(prAdapter, HOST_CSR_PINMUX_MON_FLAG, &u4Value); + DBGLOG(HAL, INFO, "Pinmux/mon_flag info: 0x%08x = 0x%08x\n", + HOST_CSR_PINMUX_MON_FLAG, u4Value); + + HAL_MCR_RD(prAdapter, HOST_CSR_MCU_PWR_STAT, &u4Value); + DBGLOG(HAL, INFO, "Bit[5] mcu_pwr_stat: 0x%08x = 0x%08x\n", + HOST_CSR_MCU_PWR_STAT, u4Value); + + HAL_MCR_RD(prAdapter, HOST_CSR_FW_OWN_SET, &u4Value); + DBGLOG(HAL, INFO, "Bit[15] fw_own_stat: 0x%08x = 0x%08x\n", + HOST_CSR_FW_OWN_SET, u4Value); + + HAL_MCR_RD(prAdapter, HOST_CSR_MCU_SW_MAILBOX_0, &u4Value); + DBGLOG(HAL, INFO, "WF Mailbox[0]: 0x%08x = 0x%08x\n", + HOST_CSR_MCU_SW_MAILBOX_0, u4Value); + + HAL_MCR_RD(prAdapter, HOST_CSR_MCU_SW_MAILBOX_1, &u4Value); + DBGLOG(HAL, INFO, "MCU Mailbox[1]: 0x%08x = 0x%08x\n", + HOST_CSR_MCU_SW_MAILBOX_1, u4Value); + + HAL_MCR_RD(prAdapter, HOST_CSR_MCU_SW_MAILBOX_2, &u4Value); + DBGLOG(HAL, INFO, "BT Mailbox[2]: 0x%08x = 0x%08x\n", + HOST_CSR_MCU_SW_MAILBOX_2, u4Value); + + HAL_MCR_RD(prAdapter, HOST_CSR_MCU_SW_MAILBOX_3, &u4Value); + DBGLOG(HAL, INFO, "GPS Mailbox[3]: 0x%08x = 0x%08x\n", + HOST_CSR_MCU_SW_MAILBOX_3, u4Value); + + HAL_MCR_RD(prAdapter, HOST_CSR_CONN_CFG_ON, &u4Value); + DBGLOG(HAL, INFO, "Conn_cfg_on info: 0x%08x = 0x%08x\n", + HOST_CSR_CONN_CFG_ON, u4Value); + +#if (CFG_ENABLE_HOST_BUS_TIMEOUT == 1) + HAL_MCR_RD(prAdapter, HOST_CSR_AP2CONN_AHB_HADDR, &u4Value); + DBGLOG(HAL, INFO, "HOST_CSR_AP2CONN_AHB_HADDR: 0x%08x = 0x%08x\n", + HOST_CSR_AP2CONN_AHB_HADDR, u4Value); +#endif + +#if CFG_MTK_MCIF_WIFI_SUPPORT + HAL_MCR_RD(prAdapter, HOST_CSR_CONN_HIF_ON_MD_LPCTL_ADDR, &u4Value); + DBGLOG(HAL, INFO, "CONN_HIF_ON_MD_LPCTL_ADDR: 0x%08x = 0x%08x\n", + HOST_CSR_CONN_HIF_ON_MD_LPCTL_ADDR, u4Value); + HAL_MCR_RD(prAdapter, HOST_CSR_CONN_HIF_ON_MD_IRQ_STAT_ADDR, &u4Value); + DBGLOG(HAL, INFO, "CONN_HIF_ON_MD_IRQ_STAT_ADDR: 0x%08x = 0x%08x\n", + HOST_CSR_CONN_HIF_ON_MD_IRQ_STAT_ADDR, u4Value); + HAL_MCR_RD(prAdapter, HOST_CSR_CONN_HIF_ON_MD_IRQ_ENA_ADDR, &u4Value); + DBGLOG(HAL, INFO, "CONN_HIF_ON_MD_IRQ_ENA_ADDR: 0x%08x = 0x%08x\n", + HOST_CSR_CONN_HIF_ON_MD_IRQ_ENA_ADDR, u4Value); +#endif + + HAL_MCR_WR(prAdapter, HOST_CSR_DRIVER_OWN_INFO, 0x00030000); + kalUdelay(1); + HAL_MCR_RD(prAdapter, HOST_CSR_DRIVER_OWN_INFO, &u4Value); + DBGLOG(HAL, INFO, "Bit[17]/[16], Get HCLK info: 0x%08x = 0x%08x\n", + HOST_CSR_DRIVER_OWN_INFO, u4Value); + + /* check clock is enabled */ + fgEnClock = ((u4Value & BIT(17)) != 0) && ((u4Value & BIT(16)) != 0); + + return fgIsDriverOwn && fgEnClock; +} + +void haldumpPhyInfo(struct ADAPTER *prAdapter) +{ + uint32_t i = 0, value = 0; + + for (i = 0; i < 20; i++) { + HAL_MCR_RD(prAdapter, 0x82072644, &value); + DBGLOG(HAL, INFO, "0x82072644: 0x%08x\n", value); + HAL_MCR_RD(prAdapter, 0x82072654, &value); + DBGLOG(HAL, INFO, "0x82072654: 0x%08x\n", value); + kalMdelay(1); + } +} + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/common/hal_pdma.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/common/hal_pdma.c new file mode 100644 index 0000000000000000000000000000000000000000..461cc1fea733ef40932ec60413ee6fafeb81cd5b --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/common/hal_pdma.c @@ -0,0 +1,3095 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/****************************************************************************** + *[File] hif_pdma.c + *[Version] v1.0 + *[Revision Date] 2015-09-08 + *[Author] + *[Description] + * The program provides PDMA HIF APIs + *[Copyright] + * Copyright (C) 2015 MediaTek Incorporation. All Rights Reserved. + ******************************************************************************/ + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "precomp.h" + +#include "hif_pdma.h" + +#include +#ifndef CONFIG_X86 +#include +#endif + +#include "mt66xx_reg.h" +#include "gl_kal.h" +#include "host_csr.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#define RX_RESPONSE_TIMEOUT (3000) + + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +static uint8_t halRingDataSelectByWmmIndex( + IN struct ADAPTER *prAdapter, + IN uint8_t ucWmmIndex) +{ + struct BUS_INFO *bus_info; + uint16_t u2Port = TX_RING_DATA0_IDX_0; + + bus_info = prAdapter->chip_info->bus_info; + if (bus_info->tx_ring0_data_idx != bus_info->tx_ring1_data_idx) { + u2Port = (ucWmmIndex == 1) ? + TX_RING_DATA1_IDX_1 : TX_RING_DATA0_IDX_0; + } + return u2Port; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Decide TxRingData number by MsduInfo + * + * @param prGlueInfo + * + * @param prMsduInfo + * + * @return TxRingData number + */ +/*----------------------------------------------------------------------------*/ +uint8_t halTxRingDataSelect(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo) +{ + ASSERT(prAdapter); + return halRingDataSelectByWmmIndex(prAdapter, prMsduInfo->ucWmmQueSet); +} + + +/*----------------------------------------------------------------------------*/ +/*! + * @brief check is timeout or not + * + * @param u4StartTime start time + * + * @param u4Timeout timeout value + * + * @return is timeout + */ +/*----------------------------------------------------------------------------*/ +static inline bool halIsTimeout(uint32_t u4StartTime, uint32_t u4Timeout) +{ + uint32_t u4CurTime = kalGetTimeTick(); + uint32_t u4Time = 0; + + if (u4CurTime >= u4StartTime) + u4Time = u4CurTime - u4StartTime; + else + u4Time = u4CurTime + (0xFFFFFFFF - u4StartTime); + + return u4Time > u4Timeout; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Verify the CHIP ID + * + * @param prAdapter a pointer to adapter private data structure. + * + * + * @retval TRUE CHIP ID is the same as the setting compiled + * @retval FALSE CHIP ID is different from the setting compiled + */ +/*----------------------------------------------------------------------------*/ +u_int8_t halVerifyChipID(IN struct ADAPTER *prAdapter) +{ + struct mt66xx_chip_info *prChipInfo; + struct BUS_INFO *prBusInfo; + uint32_t u4CIR = 0; + + ASSERT(prAdapter); + + prChipInfo = prAdapter->chip_info; + prBusInfo = prChipInfo->bus_info; + + if (prAdapter->fgIsReadRevID || !prChipInfo->should_verify_chip_id) + return TRUE; + + HAL_MCR_RD(prAdapter, prBusInfo->top_cfg_base + TOP_HW_CONTROL, &u4CIR); + + DBGLOG(INIT, INFO, "WCIR_CHIP_ID = 0x%x, chip_id = 0x%x\n", + (uint32_t)(u4CIR & WCIR_CHIP_ID), prChipInfo->chip_id); + + if ((u4CIR & WCIR_CHIP_ID) != prChipInfo->chip_id) + return FALSE; + + HAL_MCR_RD(prAdapter, prBusInfo->top_cfg_base + TOP_HW_VERSION, &u4CIR); + + prAdapter->ucRevID = (uint8_t)(u4CIR & 0xF); + prAdapter->fgIsReadRevID = TRUE; + + return TRUE; +} + +uint32_t halRxWaitResponse(IN struct ADAPTER *prAdapter, IN uint8_t ucPortIdx, + OUT uint8_t *pucRspBuffer, IN uint32_t u4MaxRespBufferLen, + OUT uint32_t *pu4Length) +{ + struct GLUE_INFO *prGlueInfo; + uint32_t u4PktLen = 0, u4Value = 0, u4Time; + u_int8_t fgStatus; + struct mt66xx_chip_info *prChipInfo; + + DEBUGFUNC("nicRxWaitResponse"); + + ASSERT(prAdapter); + prGlueInfo = prAdapter->prGlueInfo; + prChipInfo = prAdapter->chip_info; + ASSERT(prGlueInfo); + ASSERT(pucRspBuffer); + + if (prChipInfo->is_support_wfdma1) + ucPortIdx = prChipInfo->rx_event_port; + else { + ASSERT(ucPortIdx < 2); + ucPortIdx = HIF_IMG_DL_STATUS_PORT_IDX; + } + + u4Time = kalGetTimeTick(); + u4PktLen = u4MaxRespBufferLen; + + do { + if (wlanIsChipNoAck(prAdapter)) { + DBGLOG(HAL, ERROR, "Chip No Ack\n"); + return WLAN_STATUS_FAILURE; + } + + fgStatus = kalDevPortRead( + prGlueInfo, ucPortIdx, u4PktLen, + pucRspBuffer, HIF_RX_COALESCING_BUFFER_SIZE); + if (fgStatus) { + *pu4Length = u4PktLen; + break; + } + + if (halIsTimeout(u4Time, RX_RESPONSE_TIMEOUT)) { + kalDevRegRead(prGlueInfo, CONN_HIF_ON_DBGCR01, + &u4Value); + DBGLOG(HAL, ERROR, "CONN_HIF_ON_DBGCR01[0x%x]\n", + u4Value); + return WLAN_STATUS_FAILURE; + } + + /* Response packet is not ready */ + kalUdelay(50); + } while (TRUE); + + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief enable global interrupt + * + * @param prAdapter pointer to the Adapter handler + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void halEnableInterrupt(IN struct ADAPTER *prAdapter) +{ + struct BUS_INFO *prBusInfo = NULL; + + ASSERT(prAdapter); + + prBusInfo = prAdapter->chip_info->bus_info; + + if (prBusInfo->enableInterrupt) + prBusInfo->enableInterrupt(prAdapter); + + prAdapter->fgIsIntEnable = TRUE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief disable global interrupt + * + * @param prAdapter pointer to the Adapter handler + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void halDisableInterrupt(IN struct ADAPTER *prAdapter) +{ + struct BUS_INFO *prBusInfo; + + ASSERT(prAdapter); + + prBusInfo = prAdapter->chip_info->bus_info; + + if (prBusInfo->disableInterrupt) + prBusInfo->disableInterrupt(prAdapter); + + prAdapter->fgIsIntEnable = FALSE; +} + +static u_int8_t halDriverOwnCheckCR4(struct ADAPTER *prAdapter) +{ + struct mt66xx_chip_info *prChipInfo; + uint32_t u4CurrTick; + uint32_t ready_bits; + u_int8_t fgStatus = TRUE; + u_int8_t fgReady = FALSE; + u_int8_t fgDummyReq = FALSE; + bool fgTimeout; + + ASSERT(prAdapter); + + prChipInfo = prAdapter->chip_info; + ready_bits = prChipInfo->sw_ready_bits; + + HAL_WIFI_FUNC_READY_CHECK(prAdapter, + WIFI_FUNC_DUMMY_REQ, &fgDummyReq); + + u4CurrTick = kalGetTimeTick(); + /* Wait CR4 ready */ + while (1) { + fgTimeout = halIsTimeout(u4CurrTick, + LP_OWN_BACK_TOTAL_DELAY_MS); + HAL_WIFI_FUNC_READY_CHECK(prAdapter, ready_bits, &fgReady); + + if (fgReady) { + break; + } else if (kalIsCardRemoved(prAdapter->prGlueInfo) || + fgIsBusAccessFailed || fgTimeout + || wlanIsChipNoAck(prAdapter)) { + DBGLOG(INIT, INFO, + "Skip waiting CR4 ready for next %ums\n", + LP_OWN_BACK_FAILED_LOG_SKIP_MS); + fgStatus = FALSE; +#if CFG_CHIP_RESET_SUPPORT + glSetRstReason(RST_DRV_OWN_FAIL); + GL_RESET_TRIGGER(prAdapter, + RST_FLAG_CHIP_RESET); +#endif + break; + } + /* Delay for CR4 to complete its operation. */ + kalUsleep_range(LP_OWN_BACK_LOOP_DELAY_MIN_US, + LP_OWN_BACK_LOOP_DELAY_MAX_US); + } + + /* Send dummy cmd and clear flag */ + if (fgDummyReq) { + wlanSendDummyCmd(prAdapter, FALSE); + HAL_CLEAR_DUMMY_REQ(prAdapter); + } + + return fgStatus; +} + +static void halDriverOwnTimeout(struct ADAPTER *prAdapter, + uint32_t u4CurrTick, u_int8_t fgTimeout) +{ + struct CHIP_DBG_OPS *prChipDbgOps = prAdapter->chip_info->prDebugOps; + + if ((prAdapter->u4OwnFailedCount == 0) || + CHECK_FOR_TIMEOUT(u4CurrTick, prAdapter->rLastOwnFailedLogTime, + MSEC_TO_SYSTIME(LP_OWN_BACK_FAILED_LOG_SKIP_MS)) + ) { + DBGLOG(INIT, ERROR, + "LP cannot be own back, Timeout[%u](%ums), BusAccessError[%u]", + fgTimeout, + kalGetTimeTick() - u4CurrTick, + fgIsBusAccessFailed); + DBGLOG(INIT, ERROR, + "Resetting[%u], CardRemoved[%u] NoAck[%u] Cnt[%u]\n", + kalIsResetting(), + kalIsCardRemoved(prAdapter->prGlueInfo), + wlanIsChipNoAck(prAdapter), + prAdapter->u4OwnFailedCount); + DBGLOG(INIT, INFO, + "Skip LP own back failed log for next %ums\n", + LP_OWN_BACK_FAILED_LOG_SKIP_MS); + if (prAdapter->chip_info->dumpwfsyscpupcr) + prAdapter->chip_info->dumpwfsyscpupcr(prAdapter); + + prAdapter->u4OwnFailedLogCount++; + if (prAdapter->u4OwnFailedLogCount > + LP_OWN_BACK_FAILED_RESET_CNT) { + if (prChipDbgOps->showCsrInfo) + prChipDbgOps->showCsrInfo(prAdapter); +#if CFG_CHIP_RESET_SUPPORT + /* Trigger RESET */ + glSetRstReason(RST_DRV_OWN_FAIL); +#if (CFG_SUPPORT_CONNINFRA == 0) + GL_RESET_TRIGGER(prAdapter, RST_FLAG_CHIP_RESET); +#else + GL_RESET_TRIGGER(prAdapter, RST_FLAG_WF_RESET); +#endif + +#endif + } + GET_CURRENT_SYSTIME(&prAdapter->rLastOwnFailedLogTime); + } + + prAdapter->u4OwnFailedCount++; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used to process the POWER OFF procedure. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +u_int8_t halSetDriverOwn(IN struct ADAPTER *prAdapter) +{ + struct mt66xx_chip_info *prChipInfo; + struct BUS_INFO *prBusInfo; + u_int8_t fgStatus = TRUE; + uint32_t i, u4CurrTick, u4WriteTick, u4WriteTickTemp; + u_int8_t fgTimeout; + u_int8_t fgResult; + + KAL_TIME_INTERVAL_DECLARATION(); + + ASSERT(prAdapter); + + prChipInfo = prAdapter->chip_info; + prBusInfo = prChipInfo->bus_info; + + GLUE_INC_REF_CNT(prAdapter->u4PwrCtrlBlockCnt); + + if (prAdapter->fgIsFwOwn == FALSE) + return fgStatus; + + DBGLOG(INIT, TRACE, "DRIVER OWN Start\n"); + KAL_REC_TIME_START(); + + u4WriteTick = 0; + u4CurrTick = kalGetTimeTick(); + i = 0; + + /* PCIE/AXI need to do clear own, then could start polling status */ + HAL_LP_OWN_CLR(prAdapter, &fgResult); + fgResult = FALSE; + + while (1) { + if (!prBusInfo->fgCheckDriverOwnInt || + test_bit(GLUE_FLAG_INT_BIT, &prAdapter->prGlueInfo->ulFlag)) + HAL_LP_OWN_RD(prAdapter, &fgResult); + + fgTimeout = ((kalGetTimeTick() - u4CurrTick) > + LP_OWN_BACK_TOTAL_DELAY_MS) ? TRUE : FALSE; + + if (fgResult) { + /* Check WPDMA FW own interrupt status and clear */ + if (prBusInfo->fgCheckDriverOwnInt) + HAL_MCR_WR(prAdapter, + prBusInfo->fw_own_clear_addr, + prBusInfo->fw_own_clear_bit); + prAdapter->fgIsFwOwn = FALSE; + prAdapter->u4OwnFailedCount = 0; + prAdapter->u4OwnFailedLogCount = 0; + break; + } else if (wlanIsChipNoAck(prAdapter)) { + DBGLOG(INIT, INFO, + "Driver own return due to chip reset and chip no response.\n"); + fgStatus = FALSE; + break; + } else if ((i > LP_OWN_BACK_FAILED_RETRY_CNT) && + (kalIsCardRemoved(prAdapter->prGlueInfo) || + fgIsBusAccessFailed || fgTimeout)) { + halDriverOwnTimeout(prAdapter, u4CurrTick, fgTimeout); + fgStatus = FALSE; + break; + } + + u4WriteTickTemp = kalGetTimeTick(); + if ((i == 0) || TIME_AFTER(u4WriteTickTemp, + (u4WriteTick + LP_OWN_REQ_CLR_INTERVAL_MS))) { + /* Driver get LP ownership per 200 ms, + * to avoid iteration time not accurate + */ + HAL_LP_OWN_CLR(prAdapter, &fgResult); + u4WriteTick = u4WriteTickTemp; + } + + /* Delay for LP engine to complete its operation. */ + kalUsleep_range(LP_OWN_BACK_LOOP_DELAY_MIN_US, + LP_OWN_BACK_LOOP_DELAY_MAX_US); + i++; + } + + /* For Low power Test */ + /* 1. Driver need to polling until CR4 ready, + * then could do normal Tx/Rx + * 2. After CR4 ready, send a dummy command to change data path + * to store-forward mode + */ + if (prAdapter->fgIsFwDownloaded && prChipInfo->is_support_cr4) + fgStatus &= halDriverOwnCheckCR4(prAdapter); + + if (fgStatus) { + if (prAdapter->fgIsFwDownloaded) { + /*WFDMA re-init flow after chip deep sleep*/ + if (prChipInfo->asicWfdmaReInit) + prChipInfo->asicWfdmaReInit(prAdapter); + } + /* Check consys enter sleep mode DummyReg(0x0F) */ + if (prBusInfo->checkDummyReg) + prBusInfo->checkDummyReg(prAdapter->prGlueInfo); + } + + KAL_REC_TIME_END(); + DBGLOG(INIT, INFO, + "DRIVER OWN Done[%lu us]\n", KAL_GET_TIME_INTERVAL()); + + return fgStatus; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This routine is used to process the POWER ON procedure. + * + * \param[in] pvAdapter Pointer to the Adapter structure. + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void halSetFWOwn(IN struct ADAPTER *prAdapter, IN u_int8_t fgEnableGlobalInt) +{ + struct BUS_INFO *prBusInfo; + u_int8_t fgResult; + + ASSERT(prAdapter); + + prBusInfo = prAdapter->chip_info->bus_info; + + /* Decrease Block to Enter Low Power Semaphore count */ + GLUE_DEC_REF_CNT(prAdapter->u4PwrCtrlBlockCnt); + if (!(prAdapter->fgWiFiInSleepyState && + (prAdapter->u4PwrCtrlBlockCnt == 0))) + return; + + if (prAdapter->fgIsFwOwn == TRUE) + return; + + if (nicProcessIST(prAdapter) != WLAN_STATUS_NOT_INDICATING) { + DBGLOG(INIT, STATE, "Skip FW OWN due to pending INT\n"); + /* pending interrupts */ + return; + } + + if (fgEnableGlobalInt) { + prAdapter->fgIsIntEnableWithLPOwnSet = TRUE; + } else { + /* Write sleep mode magic num to dummy reg */ + if (prBusInfo->setDummyReg) + prBusInfo->setDummyReg(prAdapter->prGlueInfo); + + HAL_LP_OWN_SET(prAdapter, &fgResult); + + prAdapter->fgIsFwOwn = TRUE; + + DBGLOG(INIT, INFO, "FW OWN:%u\n", fgResult); + } +} + +void halWakeUpWiFi(IN struct ADAPTER *prAdapter) +{ + struct BUS_INFO *prBusInfo; + + ASSERT(prAdapter); + + prBusInfo = prAdapter->chip_info->bus_info; + if (prBusInfo->wakeUpWiFi) + prBusInfo->wakeUpWiFi(prAdapter); +} + +void halTxCancelSendingCmd(IN struct ADAPTER *prAdapter, + IN struct CMD_INFO *prCmdInfo) +{ +} + +u_int8_t halTxIsDataBufEnough(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo) +{ + struct GL_HIF_INFO *prHifInfo = NULL; + struct RTMP_TX_RING *prTxRing; + uint16_t u2Port; + + u2Port = halTxRingDataSelect(prAdapter, prMsduInfo); + prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + prTxRing = &prHifInfo->TxRing[u2Port]; + + if ((prHifInfo->u4TxDataQLen < halGetMsduTokenFreeCnt(prAdapter)) && + (prTxRing->u4UsedCnt + prHifInfo->u4TxDataQLen + 1 < TX_RING_SIZE)) + return TRUE; + + DBGLOG(HAL, TRACE, + "Low Tx Data Resource Tok[%u] Ring%d[%u] List[%u]\n", + halGetMsduTokenFreeCnt(prAdapter), + u2Port, + (TX_RING_SIZE - prTxRing->u4UsedCnt), + prHifInfo->u4TxDataQLen); + kalTraceEvent("Low T[%u]Ring%d[%u]L[%u] id=0x%04x sn=%d", + halGetMsduTokenFreeCnt(prAdapter), + u2Port, + (TX_RING_SIZE - prTxRing->u4UsedCnt), + prHifInfo->u4TxDataQLen, + GLUE_GET_PKT_IP_ID(prMsduInfo->prPacket), + GLUE_GET_PKT_SEQ_NO(prMsduInfo->prPacket)); + return FALSE; +} + +static void halDefaultProcessTxInterrupt(IN struct ADAPTER *prAdapter) +{ + struct BUS_INFO *prBusInfo = prAdapter->chip_info->bus_info; + struct GL_HIF_INFO *prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + union WPDMA_INT_STA_STRUCT rIntrStatus; + bool fgIsSetHifTxEvent = false; + + rIntrStatus = (union WPDMA_INT_STA_STRUCT)prHifInfo->u4IntStatus; + + if (rIntrStatus.field.tx_done & BIT(prBusInfo->tx_ring_fwdl_idx)) + halWpdmaProcessCmdDmaDone(prAdapter->prGlueInfo, + TX_RING_FWDL_IDX_3); + + if (rIntrStatus.field.tx_done & BIT(prBusInfo->tx_ring_cmd_idx)) + halWpdmaProcessCmdDmaDone(prAdapter->prGlueInfo, + TX_RING_CMD_IDX_2); + + if (rIntrStatus.field.tx_done & BIT(prBusInfo->tx_ring0_data_idx)) { + halWpdmaProcessDataDmaDone(prAdapter->prGlueInfo, + TX_RING_DATA0_IDX_0); + fgIsSetHifTxEvent = true; + } + + if (prBusInfo->tx_ring0_data_idx != prBusInfo->tx_ring1_data_idx && + rIntrStatus.field.tx_done & BIT(prBusInfo->tx_ring1_data_idx)) { + halWpdmaProcessDataDmaDone(prAdapter->prGlueInfo, + TX_RING_DATA1_IDX_1); + fgIsSetHifTxEvent = true; + } + + if (fgIsSetHifTxEvent) + kalSetTxEvent2Hif(prAdapter->prGlueInfo); +} + + +void halProcessTxInterrupt(IN struct ADAPTER *prAdapter) +{ + struct BUS_INFO *prBusInfo = prAdapter->chip_info->bus_info; + + if (prBusInfo->processTxInterrupt) + prBusInfo->processTxInterrupt(prAdapter); + else + halDefaultProcessTxInterrupt(prAdapter); +} + + +void halInitMsduTokenInfo(IN struct ADAPTER *prAdapter) +{ + struct GL_HIF_INFO *prHifInfo; + struct HIF_MEM_OPS *prMemOps; + struct MSDU_TOKEN_INFO *prTokenInfo; + struct MSDU_TOKEN_ENTRY *prToken; + struct mt66xx_chip_info *prChipInfo; + uint32_t u4Idx; + uint32_t u4TxHeadRoomSize; + + prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + prMemOps = &prHifInfo->rMemOps; + prTokenInfo = &prHifInfo->rTokenInfo; + prChipInfo = prAdapter->chip_info; + + prTokenInfo->u4UsedCnt = 0; + u4TxHeadRoomSize = NIC_TX_DESC_AND_PADDING_LENGTH + + prChipInfo->txd_append_size; + + for (u4Idx = 0; u4Idx < HIF_TX_MSDU_TOKEN_NUM; u4Idx++) { + prToken = &prTokenInfo->arToken[u4Idx]; + prToken->fgInUsed = FALSE; + prToken->prMsduInfo = NULL; + +#if HIF_TX_PREALLOC_DATA_BUFFER + prToken->u4DmaLength = NIC_TX_MAX_SIZE_PER_FRAME + + u4TxHeadRoomSize; + if (prMemOps->allocTxDataBuf) + prMemOps->allocTxDataBuf(prToken, u4Idx); + + if (prToken->prPacket) { + /* DBGLOG(HAL, TRACE, + "Msdu Entry[0x%p] Tok[%u] Buf[0x%p] len[%u]\n", + prToken, u4Idx, prToken->prPacket, + prToken->u4DmaLength); + */ + } else { + prTokenInfo->u4UsedCnt++; + DBGLOG(HAL, WARN, + "Msdu Token Memory alloc failed[%u]\n", + u4Idx); + continue; + } +#else + prToken->prPacket = NULL; + prToken->u4DmaLength = 0; + prToken->rDmaAddr = 0; +#endif + prToken->rPktDmaAddr = 0; + prToken->u4PktDmaLength = 0; + prToken->u4Token = u4Idx; + prToken->u4CpuIdx = TX_RING_SIZE; + + prTokenInfo->aprTokenStack[u4Idx] = prToken; + } + + spin_lock_init(&prTokenInfo->rTokenLock); + + DBGLOG(HAL, INFO, "Msdu Token Init: Tot[%u] Used[%u]\n", + HIF_TX_MSDU_TOKEN_NUM, prTokenInfo->u4UsedCnt); +} + +void halUninitMsduTokenInfo(IN struct ADAPTER *prAdapter) +{ + struct GL_HIF_INFO *prHifInfo; + struct HIF_MEM_OPS *prMemOps; + struct MSDU_TOKEN_INFO *prTokenInfo; + struct MSDU_TOKEN_ENTRY *prToken; + uint32_t u4Idx; + + prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + prMemOps = &prHifInfo->rMemOps; + prTokenInfo = &prHifInfo->rTokenInfo; + + for (u4Idx = 0; u4Idx < HIF_TX_MSDU_TOKEN_NUM; u4Idx++) { + prToken = &prTokenInfo->arToken[u4Idx]; + + if (prToken->fgInUsed) { + if (prMemOps->unmapTxBuf) { + prMemOps->unmapTxBuf( + prHifInfo, prToken->rPktDmaAddr, + prToken->u4PktDmaLength); + prMemOps->unmapTxBuf( + prHifInfo, prToken->rDmaAddr, + prToken->u4DmaLength); + } + + log_dbg(HAL, TRACE, "Clear pending Tok[%u] Msdu[0x%p] Free[%u]\n", + prToken->u4Token, prToken->prMsduInfo, + halGetMsduTokenFreeCnt(prAdapter)); + +#if !HIF_TX_PREALLOC_DATA_BUFFER + nicTxFreePacket(prAdapter, prToken->prMsduInfo, FALSE); + nicTxReturnMsduInfo(prAdapter, prToken->prMsduInfo); +#endif + } + +#if HIF_TX_PREALLOC_DATA_BUFFER + if (prMemOps->freeBuf) + prMemOps->freeBuf(prToken->prPacket, + prToken->u4DmaLength); + prToken->prPacket = NULL; +#endif + } + + prTokenInfo->u4UsedCnt = 0; + + DBGLOG(HAL, INFO, "Msdu Token Uninit: Tot[%u] Used[%u]\n", + HIF_TX_MSDU_TOKEN_NUM, prTokenInfo->u4UsedCnt); +} + +uint32_t halGetMsduTokenFreeCnt(IN struct ADAPTER *prAdapter) +{ + struct PERF_MONITOR *prPerMonitor; + struct MSDU_TOKEN_INFO *prTokenInfo = + &prAdapter->prGlueInfo->rHifInfo.rTokenInfo; + prPerMonitor = &prAdapter->rPerMonitor; + prPerMonitor->u4UsedCnt = prTokenInfo->u4UsedCnt; + + return HIF_TX_MSDU_TOKEN_NUM - prTokenInfo->u4UsedCnt; +} + +struct MSDU_TOKEN_ENTRY *halGetMsduTokenEntry(IN struct ADAPTER *prAdapter, + uint32_t u4TokenNum) +{ + struct MSDU_TOKEN_INFO *prTokenInfo = + &prAdapter->prGlueInfo->rHifInfo.rTokenInfo; + + return &prTokenInfo->arToken[u4TokenNum]; +} + +struct MSDU_TOKEN_ENTRY *halAcquireMsduToken(IN struct ADAPTER *prAdapter) +{ + struct MSDU_TOKEN_INFO *prTokenInfo = + &prAdapter->prGlueInfo->rHifInfo.rTokenInfo; + struct MSDU_TOKEN_ENTRY *prToken; + unsigned long flags = 0; + + if (!halGetMsduTokenFreeCnt(prAdapter)) { + DBGLOG(HAL, INFO, "No more free MSDU token, Used[%u]\n", + prTokenInfo->u4UsedCnt); + return NULL; + } + + spin_lock_irqsave(&prTokenInfo->rTokenLock, flags); + + prToken = prTokenInfo->aprTokenStack[prTokenInfo->u4UsedCnt]; + do_gettimeofday(&prToken->rTs); + prToken->fgInUsed = TRUE; + prTokenInfo->u4UsedCnt++; + + spin_unlock_irqrestore(&prTokenInfo->rTokenLock, flags); + + DBGLOG_LIMITED(HAL, TRACE, + "Acquire Entry[0x%p] Tok[%u] Buf[%p] Len[%u]\n", + prToken, prToken->u4Token, + prToken->prPacket, prToken->u4DmaLength); + + return prToken; +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Reset all msdu token. Return used msdu & re-init token. + * + * @param prAdapter a pointer to adapter private data structure. + * + */ +/*----------------------------------------------------------------------------*/ + +static void halResetMsduToken(IN struct ADAPTER *prAdapter) +{ + struct GL_HIF_INFO *prHifInfo; + struct HIF_MEM_OPS *prMemOps; + struct MSDU_TOKEN_INFO *prTokenInfo; + struct MSDU_TOKEN_ENTRY *prToken; + uint32_t u4Idx = 0; + + prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + prMemOps = &prHifInfo->rMemOps; + prTokenInfo = &prHifInfo->rTokenInfo; + + for (u4Idx = 0; u4Idx < HIF_TX_MSDU_TOKEN_NUM; u4Idx++) { + prToken = &prTokenInfo->arToken[u4Idx]; + if (prToken->fgInUsed) { + if (prMemOps->unmapTxBuf) { + prMemOps->unmapTxBuf( + prHifInfo, prToken->rPktDmaAddr, + prToken->u4PktDmaLength); + prMemOps->unmapTxBuf( + prHifInfo, prToken->rDmaAddr, + prToken->u4DmaLength); + prToken->rPktDmaAddr = 0; + prToken->u4PktDmaLength = 0; + prToken->rDmaAddr = 0; + } + +#if !HIF_TX_PREALLOC_DATA_BUFFER + nicTxFreePacket(prAdapter, prToken->prMsduInfo, FALSE); + nicTxReturnMsduInfo(prAdapter, prToken->prMsduInfo); +#endif + } + + prToken->fgInUsed = FALSE; + prTokenInfo->aprTokenStack[u4Idx] = prToken; + } + prTokenInfo->u4UsedCnt = 0; +} + +void halReturnMsduToken(IN struct ADAPTER *prAdapter, uint32_t u4TokenNum) +{ + struct MSDU_TOKEN_INFO *prTokenInfo = + &prAdapter->prGlueInfo->rHifInfo.rTokenInfo; + struct MSDU_TOKEN_ENTRY *prToken; + unsigned long flags = 0; + + if (!prTokenInfo->u4UsedCnt) { + DBGLOG(HAL, WARN, "MSDU token is full, Used[%u]\n", + prTokenInfo->u4UsedCnt); + return; + } + + prToken = &prTokenInfo->arToken[u4TokenNum]; + if (!prToken->fgInUsed) { + DBGLOG(HAL, ERROR, "Return unuse token[%u]\n", u4TokenNum); + return; + } + + spin_lock_irqsave(&prTokenInfo->rTokenLock, flags); + + prToken->fgInUsed = FALSE; + prTokenInfo->u4UsedCnt--; + prTokenInfo->aprTokenStack[prTokenInfo->u4UsedCnt] = prToken; + + spin_unlock_irqrestore(&prTokenInfo->rTokenLock, flags); +} + + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Return all timeout msdu token. + * + * @param prAdapter a pointer to adapter private data structure. + * + */ +/*----------------------------------------------------------------------------*/ +void halReturnTimeoutMsduToken(struct ADAPTER *prAdapter) +{ + struct MSDU_TOKEN_INFO *prTokenInfo; + struct MSDU_TOKEN_ENTRY *prToken; + struct timeval rNowTs, rTime; + struct timeval rTimeout; + uint32_t u4Idx = 0; + + ASSERT(prAdapter); + ASSERT(prAdapter->prGlueInfo); + + prTokenInfo = &prAdapter->prGlueInfo->rHifInfo.rTokenInfo; + + rTimeout.tv_sec = HIF_MSDU_REPORT_RETURN_TIMEOUT; + rTimeout.tv_usec = 0; + do_gettimeofday(&rNowTs); + + for (u4Idx = 0; u4Idx < HIF_TX_MSDU_TOKEN_NUM; u4Idx++) { + prToken = &prTokenInfo->arToken[u4Idx]; + if (!prToken->fgInUsed) + continue; + + /* Ignore now time < token time */ + if (halTimeCompare(&rNowTs, &prToken->rTs) < 0) + continue; + + rTime.tv_sec = rNowTs.tv_sec - prToken->rTs.tv_sec; + rTime.tv_usec = rNowTs.tv_usec; + if (prToken->rTs.tv_usec > rNowTs.tv_usec) { + rTime.tv_sec -= 1; + rTime.tv_usec += SEC_TO_USEC(1); + } + rTime.tv_usec -= prToken->rTs.tv_usec; + + /* Return token to free stack */ + if (halTimeCompare(&rTime, &rTimeout) >= 0) { + DBGLOG(HAL, INFO, + "Free TokenId[%u] timeout[sec:%ld, usec:%ld]\n", + u4Idx, rTime.tv_sec, rTime.tv_usec); + halReturnMsduToken(prAdapter, u4Idx); + } + } +} + +bool halHifSwInfoInit(IN struct ADAPTER *prAdapter) +{ + struct GL_HIF_INFO *prHifInfo = NULL; + struct BUS_INFO *prBusInfo = NULL; + struct mt66xx_chip_info *prChipInfo; + + prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + prBusInfo = prAdapter->chip_info->bus_info; + if (prBusInfo->DmaShdlInit) + prBusInfo->DmaShdlInit(prAdapter); + + if (!halWpdmaAllocRing(prAdapter->prGlueInfo, true)) + return false; + + halWpdmaInitRing(prAdapter->prGlueInfo, true); + halInitMsduTokenInfo(prAdapter); + /* Initialize wfdma reInit handshake parameters */ + prChipInfo = prAdapter->chip_info; + if ((prChipInfo->asicWfdmaReInit) + && (prChipInfo->asicWfdmaReInit_handshakeInit)) + prChipInfo->asicWfdmaReInit_handshakeInit(prAdapter); + +#if defined(_HIF_PCIE) || defined(_HIF_AXI) + prAdapter->ucSerState = SER_IDLE_DONE; + prHifInfo->rErrRecoveryCtl.eErrRecovState = ERR_RECOV_STOP_IDLE; + prHifInfo->rErrRecoveryCtl.u4Status = 0; + +#if (KERNEL_VERSION(4, 15, 0) <= CFG80211_VERSION_CODE) + timer_setup(&prHifInfo->rSerTimer, halHwRecoveryTimeout, 0); + prHifInfo->rSerTimerData = (unsigned long)prAdapter->prGlueInfo; +#else + init_timer(&prHifInfo->rSerTimer); + prHifInfo->rSerTimer.function = halHwRecoveryTimeout; + prHifInfo->rSerTimer.data = (unsigned long)prAdapter->prGlueInfo; +#endif + prHifInfo->rSerTimer.expires = + jiffies + HIF_SER_TIMEOUT * HZ / MSEC_PER_SEC; + + INIT_LIST_HEAD(&prHifInfo->rTxCmdQ); + INIT_LIST_HEAD(&prHifInfo->rTxDataQ); + prHifInfo->u4TxDataQLen = 0; +#endif + +#if (CFG_ENABLE_HOST_BUS_TIMEOUT == 1) + DBGLOG(HAL, INFO, "Enable Host CSR timeout mechanism.\n"); + HAL_MCR_WR(prAdapter, HOST_CSR_BUS_TIMOUT_CTRL_ADDR, 0x80EFFFFF); +#endif + + prHifInfo->fgIsPowerOff = false; + + return true; +} + +void halHifSwInfoUnInit(IN struct GLUE_INFO *prGlueInfo) +{ +#if defined(_HIF_PCIE) || defined(_HIF_AXI) + struct GL_HIF_INFO *prHifInfo = &prGlueInfo->rHifInfo; + struct list_head *prCur, *prNext; + struct TX_CMD_REQ *prTxCmdReq; + struct TX_DATA_REQ *prTxDataReq; + + del_timer_sync(&prHifInfo->rSerTimer); + + halUninitMsduTokenInfo(prGlueInfo->prAdapter); + halWpdmaFreeRing(prGlueInfo); + + list_for_each_safe(prCur, prNext, &prHifInfo->rTxCmdQ) { + prTxCmdReq = list_entry(prCur, struct TX_CMD_REQ, list); + list_del(prCur); + kfree(prTxCmdReq); + } + + list_for_each_safe(prCur, prNext, &prHifInfo->rTxDataQ) { + prTxDataReq = list_entry(prCur, struct TX_DATA_REQ, list); + list_del(prCur); + prHifInfo->u4TxDataQLen--; + } +#endif +} + +void halRxProcessMsduReport(IN struct ADAPTER *prAdapter, + IN OUT struct SW_RFB *prSwRfb) +{ + struct GL_HIF_INFO *prHifInfo; + struct HIF_MEM_OPS *prMemOps; + struct RTMP_DMACB *prTxCell; + struct RTMP_TX_RING *prTxRing; + struct HW_MAC_MSDU_REPORT *prMsduReport; + struct MSDU_TOKEN_ENTRY *prTokenEntry; +#if !HIF_TX_PREALLOC_DATA_BUFFER + struct MSDU_INFO *prMsduInfo; +#endif + struct QUE rFreeQueue; + struct QUE *prFreeQueue; + uint16_t u2TokenCnt, u2TotalTokenCnt; + uint32_t u4Idx, u4Token; + uint8_t ucVer; + + ASSERT(prAdapter); + ASSERT(prAdapter->prGlueInfo); + + prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + prMemOps = &prHifInfo->rMemOps; + + prFreeQueue = &rFreeQueue; + QUEUE_INITIALIZE(prFreeQueue); + + prMsduReport = (struct HW_MAC_MSDU_REPORT *)prSwRfb->pucRecvBuff; + ucVer = prMsduReport->DW1.field.u4Ver; + if (ucVer == TFD_EVT_VER_3) + u2TotalTokenCnt = prMsduReport->DW0.field_v3.u2MsduCount; + else + u2TotalTokenCnt = prMsduReport->DW0.field.u2MsduCount; + + u4Idx = u2TokenCnt = 0; + while (u2TokenCnt < u2TotalTokenCnt) { + /* Format version of this tx done event. + * 0: MT7615 + * 1: MT7622, CONNAC (X18/P18/MT7663) + * 2: MT7915 E1/Petrus + * 3: MT7915 E2/Buzzard + */ + if (ucVer == TFD_EVT_VER_0) + u4Token = prMsduReport->au4MsduToken[u4Idx >> 1]. + rFormatV0.u2MsduID[u4Idx & 1]; + else if (ucVer == TFD_EVT_VER_1) + u4Token = prMsduReport->au4MsduToken[u4Idx]. + rFormatV1.u2MsduID; + else if (ucVer == TFD_EVT_VER_2) + u4Token = prMsduReport->au4MsduToken[u4Idx]. + rFormatV2.u2MsduID; + else { + if (!prMsduReport->au4MsduToken[u4Idx]. + rFormatV3.rP0.u4Pair) + u4Token = prMsduReport->au4MsduToken[u4Idx]. + rFormatV3.rP0.u4MsduID; + else { + u4Idx++; + continue; + } + } + u4Idx++; + u2TokenCnt++; + + if (u4Token >= HIF_TX_MSDU_TOKEN_NUM) { + DBGLOG(HAL, ERROR, "Error MSDU report[%u]\n", u4Token); + DBGLOG_MEM32(HAL, ERROR, prMsduReport, 64); + prAdapter->u4HifDbgFlag |= DEG_HIF_DEFAULT_DUMP; + halPrintHifDbgInfo(prAdapter); + return; + } + + prTokenEntry = halGetMsduTokenEntry(prAdapter, u4Token); + +#if HIF_TX_PREALLOC_DATA_BUFFER + DBGLOG_LIMITED(HAL, TRACE, + "MsduRpt: Cnt[%u] Tok[%u] Free[%u]\n", + u2TokenCnt, u4Token, + halGetMsduTokenFreeCnt(prAdapter)); +#else + prMsduInfo = prTokenEntry->prMsduInfo; + prMsduInfo->prToken = NULL; + if (!prMsduInfo->pfTxDoneHandler) + QUEUE_INSERT_TAIL(prFreeQueue, + (struct QUE_ENTRY *) prMsduInfo); + + DBGLOG_LIMITED(HAL, TRACE, + "MsduRpt: Cnt[%u] Tok[%u] Msdu[0x%p] TxDone[%u] Free[%u]\n", + u2TokenCnt, u4Token, prMsduInfo, + (prMsduInfo->pfTxDoneHandler ? TRUE : FALSE), + halGetMsduTokenFreeCnt(prAdapter)); +#endif + if (prMemOps->unmapTxBuf) { + prMemOps->unmapTxBuf(prHifInfo, + prTokenEntry->rPktDmaAddr, + prTokenEntry->u4PktDmaLength); + prMemOps->unmapTxBuf(prHifInfo, + prTokenEntry->rDmaAddr, + prTokenEntry->u4DmaLength); + } + + if (prTokenEntry->u4CpuIdx < TX_RING_SIZE) { + prTxRing = &prHifInfo->TxRing[prTokenEntry->u2Port]; + prTxCell = &prTxRing->Cell[prTokenEntry->u4CpuIdx]; + prTxCell->prToken = NULL; + } + prTokenEntry->u4CpuIdx = TX_RING_SIZE; + halReturnMsduToken(prAdapter, u4Token); + GLUE_INC_REF_CNT(prAdapter->rHifStats.u4DataMsduRptCount); + } + +#if !HIF_TX_PREALLOC_DATA_BUFFER + nicTxMsduDoneCb(prAdapter->prGlueInfo, prFreeQueue); +#endif + + /* Indicate Service Thread */ + if (wlanGetTxPendingFrameCount(prAdapter) > 0) + kalSetEvent(prAdapter->prGlueInfo); + + kalSetTxEvent2Hif(prAdapter->prGlueInfo); +} + +void halTxUpdateCutThroughDesc(struct GLUE_INFO *prGlueInfo, + struct MSDU_INFO *prMsduInfo, + struct MSDU_TOKEN_ENTRY *prFillToken, + struct MSDU_TOKEN_ENTRY *prDataToken, + uint32_t u4Idx, bool fgIsLast) +{ + struct GL_HIF_INFO *prHifInfo; + struct HIF_MEM_OPS *prMemOps; + struct mt66xx_chip_info *prChipInfo; + struct TX_DESC_OPS_T *prTxDescOps; + uint8_t *pucBufferTxD; + uint32_t u4TxHeadRoomSize; + phys_addr_t rPhyAddr = 0; + + prHifInfo = &prGlueInfo->rHifInfo; + prMemOps = &prHifInfo->rMemOps; + prChipInfo = prGlueInfo->prAdapter->chip_info; + prTxDescOps = prChipInfo->prTxDescOps; + pucBufferTxD = prDataToken->prPacket; + u4TxHeadRoomSize = NIC_TX_DESC_AND_PADDING_LENGTH + + prChipInfo->txd_append_size; + + if (prMemOps->mapTxBuf) { + rPhyAddr = prMemOps->mapTxBuf( + prHifInfo, pucBufferTxD, u4TxHeadRoomSize, + prMsduInfo->u2FrameLength); + } else { + if (prDataToken->rDmaAddr) + rPhyAddr = prDataToken->rDmaAddr + u4TxHeadRoomSize; + } + + if (!rPhyAddr) { + DBGLOG(HAL, ERROR, "Get address error!\n"); + return; + } + + if (prTxDescOps->fillHifAppend) + prTxDescOps->fillHifAppend(prGlueInfo->prAdapter, + prMsduInfo, prDataToken->u4Token, + rPhyAddr, u4Idx, fgIsLast, prFillToken->prPacket); + + prDataToken->rPktDmaAddr = rPhyAddr; + prDataToken->u4PktDmaLength = prMsduInfo->u2FrameLength; +} + +uint32_t halTxGetPageCount(IN struct ADAPTER *prAdapter, + IN uint32_t u4FrameLength, IN u_int8_t fgIncludeDesc) +{ + return 1; +} + +uint32_t halTxPollingResource(IN struct ADAPTER *prAdapter, IN uint8_t ucTC) +{ + nicTxReleaseResource(prAdapter, ucTC, 1, TRUE, FALSE); + return WLAN_STATUS_SUCCESS; +} + +void halSerHifReset(IN struct ADAPTER *prAdapter) +{ +} + +void halRxReceiveRFBs(IN struct ADAPTER *prAdapter, uint32_t u4Port, + uint8_t fgRxData) +{ + struct RX_CTRL *prRxCtrl; + struct SW_RFB *prSwRfb = (struct SW_RFB *) NULL; + uint8_t *pucBuf = NULL; + void *prRxStatus; + u_int8_t fgStatus; + uint32_t u4RxCnt; + struct RX_DESC_OPS_T *prRxDescOps; + struct RTMP_RX_RING *prRxRing; + struct GL_HIF_INFO *prHifInfo; + uint32_t u4MsduReportCnt = 0; + + KAL_SPIN_LOCK_DECLARATION(); + + DEBUGFUNC("nicRxPCIeReceiveRFBs"); + + ASSERT(prAdapter); + + prRxCtrl = &prAdapter->rRxCtrl; + ASSERT(prRxCtrl); + prRxDescOps = prAdapter->chip_info->prRxDescOps; + ASSERT(prRxDescOps->nic_rxd_get_rx_byte_count); + ASSERT(prRxDescOps->nic_rxd_get_pkt_type); + ASSERT(prRxDescOps->nic_rxd_get_wlan_idx); +#if DBG + ASSERT(prRxDescOps->nic_rxd_get_sec_mode); +#endif /* DBG */ + + prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + prRxRing = &prHifInfo->RxRing[u4Port]; + + u4RxCnt = halWpdmaGetRxDmaDoneCnt(prAdapter->prGlueInfo, u4Port); + + DBGLOG(RX, TEMP, "halRxReceiveRFBs: u4RxCnt:%d\n", u4RxCnt); + + while (u4RxCnt--) { + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_FREE_QUE); + QUEUE_REMOVE_HEAD(&prRxCtrl->rFreeSwRfbList, + prSwRfb, struct SW_RFB *); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_FREE_QUE); + + if (!prSwRfb) { + DBGLOG_LIMITED(RX, WARN, "No More RFB for P[%u]\n", + u4Port); + prAdapter->u4NoMoreRfb |= BIT(u4Port); + break; + } + + /* unset no more rfb port bit */ + prAdapter->u4NoMoreRfb &= ~BIT(u4Port); + + if (fgRxData) { + fgStatus = kalDevReadData(prAdapter->prGlueInfo, + u4Port, prSwRfb); + } else { + pucBuf = prSwRfb->pucRecvBuff; + ASSERT(pucBuf); + + fgStatus = kalDevPortRead(prAdapter->prGlueInfo, + u4Port, CFG_RX_MAX_PKT_SIZE, + pucBuf, CFG_RX_MAX_PKT_SIZE); + } + if (!fgStatus) { + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_FREE_QUE); + QUEUE_INSERT_TAIL(&prRxCtrl->rFreeSwRfbList, + &prSwRfb->rQueEntry); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_FREE_QUE); + DBGLOG(RX, TEMP, "fgStatus:%d\n", fgStatus); + continue; + } + + prRxStatus = prSwRfb->prRxStatus; + ASSERT(prRxStatus); + + prSwRfb->ucPacketType = + prRxDescOps->nic_rxd_get_pkt_type(prRxStatus); +#if DBG + DBGLOG_LIMITED(RX, LOUD, "ucPacketType = %u, ucSecMode = %u\n", + prSwRfb->ucPacketType, + prRxDescOps->nic_rxd_get_sec_mode( + prRxStatus)); +#endif /* DBG */ + + if (prSwRfb->ucPacketType == RX_PKT_TYPE_MSDU_REPORT) { + nicRxProcessMsduReport(prAdapter, prSwRfb); + u4MsduReportCnt++; + continue; + } + + if (prSwRfb->ucPacketType == RX_PKT_TYPE_RX_REPORT) { + nicRxProcessRxReport(prAdapter, prSwRfb); + nicRxReturnRFB(prAdapter, prSwRfb); + + continue; + } + + GLUE_RX_SET_PKT_INT_TIME(prSwRfb->pvPacket, + prAdapter->prGlueInfo->u8HifIntTime); + GLUE_RX_SET_PKT_RX_TIME(prSwRfb->pvPacket, sched_clock()); + + prSwRfb->ucStaRecIdx = + secGetStaIdxByWlanIdx( + prAdapter, + prRxDescOps->nic_rxd_get_wlan_idx(prRxStatus)); + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); + QUEUE_INSERT_TAIL(&prRxCtrl->rReceivedRfbList, + &prSwRfb->rQueEntry); + RX_INC_CNT(prRxCtrl, RX_MPDU_TOTAL_COUNT); + DBGLOG(RX, TEMP, "Recv p=%p total:%lu\n", + prSwRfb, RX_GET_CNT(prRxCtrl, RX_MPDU_TOTAL_COUNT)); + kalTraceEvent("Recv p=%p total:%lu", + prSwRfb, RX_GET_CNT(prRxCtrl, RX_MPDU_TOTAL_COUNT)); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); + } + prRxRing->u4PendingCnt = halWpdmaGetRxDmaDoneCnt(prAdapter->prGlueInfo, + u4Port); + if (u4MsduReportCnt > 0) + DBGLOG(RX, TEMP, "Recv %d msdu reports\n", u4MsduReportCnt); +} + +static void halDefaultProcessRxInterrupt(IN struct ADAPTER *prAdapter) +{ + struct GL_HIF_INFO *prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + union WPDMA_INT_STA_STRUCT rIntrStatus; + + rIntrStatus = (union WPDMA_INT_STA_STRUCT)prHifInfo->u4IntStatus; + prAdapter->prGlueInfo->u8HifIntTime = sched_clock(); + + if (rIntrStatus.field.rx_done_1 || + (prAdapter->u4NoMoreRfb & BIT(RX_RING_EVT_IDX_1))) + halRxReceiveRFBs(prAdapter, RX_RING_EVT_IDX_1, FALSE); + + if (rIntrStatus.field.rx_done_0 || + (prAdapter->u4NoMoreRfb & BIT(RX_RING_DATA_IDX_0))) + halRxReceiveRFBs(prAdapter, RX_RING_DATA_IDX_0, TRUE); +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief Read frames from the data port for PCIE + * I/F, fill RFB and put each frame into the rReceivedRFBList queue. + * + * @param prAdapter Pointer to the Adapter structure. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void halProcessRxInterrupt(IN struct ADAPTER *prAdapter) +{ + struct BUS_INFO *prBusInfo = prAdapter->chip_info->bus_info; + + if (prBusInfo->processRxInterrupt) + prBusInfo->processRxInterrupt(prAdapter); + else + halDefaultProcessRxInterrupt(prAdapter); +} + +static int32_t halWpdmaFreeRingDesc(struct GLUE_INFO *prGlueInfo, + struct RTMP_DMABUF *prDescRing) +{ + struct GL_HIF_INFO *prHifInfo; + struct HIF_MEM_OPS *prMemOps; + + ASSERT(prGlueInfo); + + prHifInfo = &prGlueInfo->rHifInfo; + prMemOps = &prHifInfo->rMemOps; + + if (prMemOps->freeDesc) + prMemOps->freeDesc(prHifInfo, prDescRing); + + return TRUE; +} + +bool halWpdmaAllocTxRing(struct GLUE_INFO *prGlueInfo, uint32_t u4Num, + uint32_t u4Size, uint32_t u4DescSize, bool fgAllocMem) +{ + struct GL_HIF_INFO *prHifInfo; + struct HIF_MEM_OPS *prMemOps; + struct RTMP_TX_RING *pTxRing; + struct RTMP_DMABUF *prTxDesc; + struct RTMP_DMACB *prTxCell; + phys_addr_t RingBasePa; + void *RingBaseVa; + uint32_t u4Idx; + + ASSERT(prGlueInfo); + prHifInfo = &prGlueInfo->rHifInfo; + prMemOps = &prHifInfo->rMemOps; + prTxDesc = &prHifInfo->TxDescRing[u4Num]; + + /* Don't re-alloc memory when second time call alloc ring */ + prTxDesc->AllocSize = u4Size * u4DescSize; + if (fgAllocMem && prMemOps->allocTxDesc) + prMemOps->allocTxDesc(prHifInfo, prTxDesc, u4Num); + + if (prTxDesc->AllocVa == NULL) { + DBGLOG(HAL, ERROR, "TxDescRing[%d] allocation failed\n", u4Num); + return false; + } + + DBGLOG(HAL, TRACE, "TxDescRing[%p]: total %lu bytes allocated\n", + prTxDesc->AllocVa, prTxDesc->AllocSize); + + /* Save PA & VA for further operation */ + RingBasePa = prTxDesc->AllocPa; + RingBaseVa = prTxDesc->AllocVa; + + /* + * Initialize Tx Ring Descriptor and associated buffer memory + */ + pTxRing = &prHifInfo->TxRing[u4Num]; + for (u4Idx = 0; u4Idx < u4Size; u4Idx++) { + prTxCell = &pTxRing->Cell[u4Idx]; + prTxCell->pPacket = NULL; + prTxCell->pBuffer = NULL; + + /* Init Tx Ring Size, Va, Pa variables */ + prTxCell->AllocSize = u4DescSize; + prTxCell->AllocVa = RingBaseVa; + prTxCell->AllocPa = RingBasePa; + prTxCell->prToken = NULL; + + RingBasePa += u4DescSize; + RingBaseVa += u4DescSize; + + if (fgAllocMem && prMemOps->allocTxCmdBuf) { + bool ret; + + ret = prMemOps->allocTxCmdBuf(&prTxCell->DmaBuf, + u4Num, u4Idx); + if (ret == false) { + DBGLOG(HAL, ERROR, + "TxRing[%u] TxCmd[%u] alloc failed\n", + u4Num, u4Idx); + return false; + } + } + } + + DBGLOG(HAL, TRACE, "TxRing[%d]: total %d entry allocated\n", + u4Num, u4Idx); + + return true; +} + +bool halWpdmaAllocRxRing(struct GLUE_INFO *prGlueInfo, uint32_t u4Num, + uint32_t u4Size, uint32_t u4DescSize, + uint32_t u4BufSize, bool fgAllocMem) +{ + struct GL_HIF_INFO *prHifInfo; + struct HIF_MEM_OPS *prMemOps; + struct RTMP_RX_RING *pRxRing; + struct RTMP_DMABUF *prRxDesc; + struct RTMP_DMABUF *pDmaBuf; + struct RTMP_DMACB *prRxCell; + struct RXD_STRUCT *pRxD; + phys_addr_t RingBasePa; + void *RingBaseVa; + uint32_t u4Idx; + + ASSERT(prGlueInfo); + prHifInfo = &prGlueInfo->rHifInfo; + prMemOps = &prHifInfo->rMemOps; + prRxDesc = &prHifInfo->RxDescRing[u4Num]; + + /* Don't re-alloc memory when second time call alloc ring */ + prRxDesc->AllocSize = u4Size * u4DescSize; + if (fgAllocMem && prMemOps->allocRxDesc) + prMemOps->allocRxDesc(prHifInfo, prRxDesc, u4Num); + + if (prRxDesc->AllocVa == NULL) { + DBGLOG(HAL, ERROR, "RxDescRing allocation failed!!\n"); + return false; + } + + DBGLOG(HAL, TRACE, "RxDescRing[%p]: total %lu bytes allocated\n", + prRxDesc->AllocVa, prRxDesc->AllocSize); + + /* Initialize Rx Ring and associated buffer memory */ + RingBasePa = prRxDesc->AllocPa; + RingBaseVa = prRxDesc->AllocVa; + + pRxRing = &prHifInfo->RxRing[u4Num]; + pRxRing->u4BufSize = u4BufSize; + pRxRing->u4RingSize = u4Size; + pRxRing->fgRxSegPkt = FALSE; + + for (u4Idx = 0; u4Idx < u4Size; u4Idx++) { + /* Init RX Ring Size, Va, Pa variables */ + prRxCell = &pRxRing->Cell[u4Idx]; + prRxCell->AllocSize = u4DescSize; + prRxCell->AllocVa = RingBaseVa; + prRxCell->AllocPa = RingBasePa; + prRxCell->prToken = NULL; + + /* Offset to next ring descriptor address */ + RingBasePa += u4DescSize; + RingBaseVa += u4DescSize; + + /* Setup Rx associated Buffer size & allocate share memory */ + pDmaBuf = &prRxCell->DmaBuf; + pDmaBuf->AllocSize = u4BufSize; + + if (fgAllocMem && prMemOps->allocRxBuf) + prRxCell->pPacket = prMemOps->allocRxBuf( + prHifInfo, pDmaBuf, u4Num, u4Idx); + if (pDmaBuf->AllocVa == NULL) { + log_dbg(HAL, ERROR, "\nFailed to allocate RxRing buffer idx[%u]\n", + u4Idx); + return false; + } + + /* Write RxD buffer address & allocated buffer length */ + pRxD = (struct RXD_STRUCT *)prRxCell->AllocVa; + pRxD->SDPtr0 = ((uint64_t)pDmaBuf->AllocPa) & + DMA_LOWER_32BITS_MASK; +#ifdef CONFIG_PHYS_ADDR_T_64BIT + pRxD->SDPtr1 = (((uint64_t)pDmaBuf->AllocPa >> + DMA_BITS_OFFSET) & DMA_HIGHER_4BITS_MASK); +#else + pRxD->SDPtr1 = 0; +#endif + pRxD->SDLen0 = u4BufSize; + pRxD->DMADONE = 0; + } + + DBGLOG(HAL, TRACE, "Rx[%d] Ring: total %d entry allocated\n", + u4Num, u4Idx); + + return true; +} + +static void halDefaultHifRst(struct GLUE_INFO *prGlueInfo) +{ + /* Reset Conn HIF logic */ + kalDevRegWrite(prGlueInfo, CONN_HIF_RST, 0x00000020); + kalDevRegWrite(prGlueInfo, CONN_HIF_RST, 0x00000030); +} + +void halHifRst(struct GLUE_INFO *prGlueInfo) +{ + struct ADAPTER *prAdapter; + struct BUS_INFO *prBusInfo; + + prAdapter = prGlueInfo->prAdapter; + prBusInfo = prAdapter->chip_info->bus_info; + + /* Reset dmashdl and wpdma */ + if (prBusInfo->hifRst) + prBusInfo->hifRst(prGlueInfo); + else + halDefaultHifRst(prGlueInfo); +} + +bool halWpdmaAllocRing(struct GLUE_INFO *prGlueInfo, bool fgAllocMem) +{ + struct GL_HIF_INFO *prHifInfo; + int32_t u4Num, u4Index; +#if (CFG_SUPPORT_CONNAC2X == 1) + struct BUS_INFO *prBusInfo = NULL; +#endif /* CFG_SUPPORT_CONNAC2X == 1 */ + + ASSERT(prGlueInfo); + prHifInfo = &prGlueInfo->rHifInfo; +#if (CFG_SUPPORT_CONNAC2X == 1) + prBusInfo = prGlueInfo->prAdapter->chip_info->bus_info; +#endif /* CFG_SUPPORT_CONNAC2X == 1 */ + + /* + * Allocate all ring descriptors, include TxD, RxD, MgmtD. + * Although each size is different, to prevent cacheline and alignment + * issue, I intentional set them all to 64 bytes + */ + for (u4Num = 0; u4Num < NUM_OF_TX_RING; u4Num++) { + if (!halWpdmaAllocTxRing(prGlueInfo, u4Num, TX_RING_SIZE, + TXD_SIZE, fgAllocMem)) { + DBGLOG(HAL, ERROR, "AllocTxRing[%d] fail\n", u4Num); + return false; + } + } + + /* Data Rx path */ + if (!halWpdmaAllocRxRing(prGlueInfo, RX_RING_DATA_IDX_0, + RX_RING0_SIZE, RXD_SIZE, + CFG_RX_MAX_PKT_SIZE, fgAllocMem)) { + DBGLOG(HAL, ERROR, "AllocRxRing[0] fail\n"); + return false; + } + + /* For connac & old ic: Event Rx path */ + /* For falcon: TxFreeDoneEvent to Host Rx path */ + /* For buzzard(costdown wfdma): Event Rx path */ + /* Event Rx path */ +#if (CFG_SUPPORT_CONNAC2X_2x2 == 1) + + if (!halWpdmaAllocRxRing(prGlueInfo, RX_RING_EVT_IDX_1, + RX_RING0_SIZE, RXD_SIZE, + RX_BUFFER_AGGRESIZE, fgAllocMem)) { + DBGLOG(HAL, ERROR, "AllocRxRing[1] fail\n"); + return false; + } +#else + if (!halWpdmaAllocRxRing(prGlueInfo, RX_RING_EVT_IDX_1, + RX_RING1_SIZE, RXD_SIZE, + RX_BUFFER_AGGRESIZE, fgAllocMem)) { + DBGLOG(HAL, ERROR, "AllocRxRing[1] fail\n"); + return false; + } +#endif + +#if (CFG_SUPPORT_CONNAC2X == 1) + if (prBusInfo->wfdmaAllocRxRing) + if (!prBusInfo->wfdmaAllocRxRing(prGlueInfo, fgAllocMem)) { + DBGLOG(HAL, ERROR, "wfdmaAllocRxRing fail\n"); + return false; + } +#endif /* CFG_SUPPORT_CONNAC2X == 1 */ + + /* Initialize all transmit related software queues */ + + /* Init TX rings index pointer */ + for (u4Index = 0; u4Index < NUM_OF_TX_RING; u4Index++) { + prHifInfo->TxRing[u4Index].TxSwUsedIdx = 0; + prHifInfo->TxRing[u4Index].TxCpuIdx = 0; + } + + return true; +} + +void halWpdmaFreeRing(struct GLUE_INFO *prGlueInfo) +{ + struct GL_HIF_INFO *prHifInfo; + struct HIF_MEM_OPS *prMemOps; + struct RTMP_TX_RING *pTxRing; + struct RTMP_RX_RING *pRxRing; + struct TXD_STRUCT *pTxD; + struct RTMP_DMACB *prDmaCb; + void *pPacket, *pBuffer; + uint32_t i, j; + + prHifInfo = &prGlueInfo->rHifInfo; + prMemOps = &prHifInfo->rMemOps; + + /* Free Tx Ring Packet */ + for (i = 0; i < NUM_OF_TX_RING; i++) { + pTxRing = &prHifInfo->TxRing[i]; + for (j = 0; j < TX_RING_SIZE; j++) { + pTxD = (struct TXD_STRUCT *) (pTxRing->Cell[j].AllocVa); + + pPacket = pTxRing->Cell[j].pPacket; + pBuffer = pTxRing->Cell[j].pBuffer; + if (prMemOps->unmapTxBuf && pPacket) + prMemOps->unmapTxBuf( + prHifInfo, pTxRing->Cell[j].PacketPa, + pTxD->SDLen0); + pTxRing->Cell[j].pPacket = NULL; + + if (prMemOps->freeBuf && pBuffer) + prMemOps->freeBuf(pBuffer, pTxD->SDLen0); + pTxRing->Cell[j].pBuffer = NULL; + } + + halWpdmaFreeRingDesc(prGlueInfo, &prHifInfo->TxDescRing[i]); + } + + for (i = 0; i < NUM_OF_RX_RING; i++) { + pRxRing = &prHifInfo->RxRing[i]; + for (j = 0; j < pRxRing->u4RingSize; j++) { + prDmaCb = &pRxRing->Cell[j]; + if (prMemOps->unmapRxBuf && prDmaCb->DmaBuf.AllocVa) + prMemOps->unmapRxBuf(prHifInfo, + prDmaCb->DmaBuf.AllocPa, + prDmaCb->DmaBuf.AllocSize); + if (prMemOps->freePacket && prDmaCb->pPacket) + prMemOps->freePacket(prDmaCb->pPacket); + } + + halWpdmaFreeRingDesc(prGlueInfo, &prHifInfo->RxDescRing[i]); + } +} + +/*----------------------------------------------------------------------------*/ +/*! + * @brief enable firmware download. + * + * @param[in] fgEnable 1 for fw download, 0 for normal data operation. + * + * @return (none) + */ +/*----------------------------------------------------------------------------*/ +void halEnableFWDownload(IN struct ADAPTER *prAdapter, IN u_int8_t fgEnable) +{ + struct mt66xx_chip_info *prChipInfo; + + ASSERT(prAdapter); + + prChipInfo = prAdapter->chip_info; + + if (prChipInfo->asicEnableFWDownload) + prChipInfo->asicEnableFWDownload(prAdapter, fgEnable); +} + +u_int8_t halWpdmaWaitIdle(struct GLUE_INFO *prGlueInfo, + int32_t round, int32_t wait_us) +{ + int32_t i = 0; + union WPDMA_GLO_CFG_STRUCT GloCfg; + + do { + kalDevRegRead(prGlueInfo, WPDMA_GLO_CFG, &GloCfg.word); + if ((GloCfg.field.TxDMABusy == 0) && + (GloCfg.field.RxDMABusy == 0)) { + DBGLOG(HAL, TRACE, + "==> DMAIdle, GloCfg=0x%x\n", GloCfg.word); + return TRUE; + } + kalUdelay(wait_us); + } while ((i++) < round); + + DBGLOG(HAL, INFO, "==> DMABusy, GloCfg=0x%x\n", GloCfg.word); + + return FALSE; +} + +void halWpdmaInitRing(struct GLUE_INFO *prGlueInfo, bool fgResetHif) +{ + struct GL_HIF_INFO *prHifInfo; + struct BUS_INFO *prBusInfo; + + ASSERT(prGlueInfo); + + prHifInfo = &prGlueInfo->rHifInfo; + prBusInfo = prGlueInfo->prAdapter->chip_info->bus_info; + + /* Set DMA global configuration except TX_DMA_EN and RX_DMA_EN bits */ + if (prBusInfo->pdmaSetup) + prBusInfo->pdmaSetup(prGlueInfo, FALSE, fgResetHif); + + halWpdmaInitTxRing(prGlueInfo); + + /* Init RX Ring0 Base/Size/Index pointer CSR */ + halWpdmaInitRxRing(prGlueInfo); + + if (prBusInfo->wfdmaManualPrefetch) + prBusInfo->wfdmaManualPrefetch(prGlueInfo); + + if (prBusInfo->pdmaSetup) + prBusInfo->pdmaSetup(prGlueInfo, TRUE, fgResetHif); + + /* Write sleep mode magic num to dummy reg */ + if (prBusInfo->setDummyReg) + prBusInfo->setDummyReg(prGlueInfo); +} + +void halWpdmaInitTxRing(IN struct GLUE_INFO *prGlueInfo) +{ + struct GL_HIF_INFO *prHifInfo = NULL; + struct BUS_INFO *prBusInfo = NULL; + struct RTMP_TX_RING *prTxRing = NULL; + struct RTMP_DMACB *prTxCell; + uint32_t i = 0, offset = 0, phy_addr = 0; + struct mt66xx_chip_info *prChipInfo; + + prHifInfo = &prGlueInfo->rHifInfo; + prBusInfo = prGlueInfo->prAdapter->chip_info->bus_info; + prChipInfo = prGlueInfo->prAdapter->chip_info; + + /* reset all TX Ring register */ + for (i = 0; i < NUM_OF_TX_RING; i++) { + prTxRing = &prHifInfo->TxRing[i]; + prTxCell = &prTxRing->Cell[0]; + + if (i == TX_RING_CMD_IDX_2) + offset = prBusInfo->tx_ring_cmd_idx * MT_RINGREG_DIFF; + else if (i == TX_RING_FWDL_IDX_3) + offset = prBusInfo->tx_ring_fwdl_idx * MT_RINGREG_DIFF; +#if (CFG_SUPPORT_CONNAC2X == 1) + else if (prChipInfo->is_support_wacpu) { + uint32_t idx = 0; + + if (i == TX_RING_DATA0_IDX_0) + idx = prBusInfo->tx_ring0_data_idx; + else if (i == TX_RING_DATA1_IDX_1) + idx = prBusInfo->tx_ring1_data_idx; + else if (i == TX_RING_WA_CMD_IDX_4) + idx = prBusInfo->tx_ring_wa_cmd_idx; + offset = idx * MT_RINGREG_DIFF; + } +#endif /* CFG_SUPPORT_CONNAC2X == 1 */ + else + offset = i * MT_RINGREG_DIFF; + + phy_addr = ((uint64_t)prTxCell->AllocPa) & + DMA_LOWER_32BITS_MASK; + prTxRing->TxSwUsedIdx = 0; + prTxRing->u4UsedCnt = 0; + prTxRing->TxCpuIdx = 0; + + prTxRing->hw_desc_base = + prBusInfo->host_tx_ring_base + offset; + + prTxRing->hw_cidx_addr = + prBusInfo->host_tx_ring_cidx_addr + offset; + prTxRing->hw_didx_addr = + prBusInfo->host_tx_ring_didx_addr + offset; + prTxRing->hw_cnt_addr = + prBusInfo->host_tx_ring_cnt_addr + offset; + + kalDevRegWrite(prGlueInfo, prTxRing->hw_desc_base, phy_addr); + kalDevRegWrite(prGlueInfo, prTxRing->hw_cidx_addr, + prTxRing->TxCpuIdx); + kalDevRegWrite(prGlueInfo, prTxRing->hw_cnt_addr, + TX_RING_SIZE); + + if (prBusInfo->tx_ring_ext_ctrl) + prBusInfo->tx_ring_ext_ctrl(prGlueInfo, prTxRing, i); + + DBGLOG(HAL, TRACE, "-->TX_RING_%d[0x%x]: Base=0x%x, Cnt=%d!\n", + i, prHifInfo->TxRing[i].hw_desc_base, + phy_addr, TX_RING_SIZE); + } +} + +static uint8_t defaultSetRxRingHwAddr( + struct RTMP_RX_RING *prRxRing, + struct BUS_INFO *prBusInfo, + struct mt66xx_chip_info *prChipInfo, + uint32_t u4SwRingIdx) +{ + uint32_t offset = 0; + + if (u4SwRingIdx >= WFDMA1_RX_RING_IDX_0) { +#if (CFG_SUPPORT_CONNAC2X == 1) + if (prChipInfo->is_support_wfdma1) { + offset = (u4SwRingIdx - WFDMA1_RX_RING_IDX_0) + * MT_RINGREG_DIFF; + prRxRing->hw_desc_base = + prBusInfo->host_wfdma1_rx_ring_base + + offset; + prRxRing->hw_cidx_addr = + prBusInfo->host_wfdma1_rx_ring_cidx_addr + + offset; + prRxRing->hw_didx_addr = + prBusInfo->host_wfdma1_rx_ring_didx_addr + + offset; + prRxRing->hw_cnt_addr = + prBusInfo->host_wfdma1_rx_ring_cnt_addr + + offset; + } else +#endif /* CFG_SUPPORT_CONNAC2X == 1 */ + return FALSE; + } else { + offset = u4SwRingIdx * MT_RINGREG_DIFF; + prRxRing->hw_desc_base = + prBusInfo->host_rx_ring_base + offset; + prRxRing->hw_cidx_addr = + prBusInfo->host_rx_ring_cidx_addr + offset; + prRxRing->hw_didx_addr = + prBusInfo->host_rx_ring_didx_addr + offset; + prRxRing->hw_cnt_addr = + prBusInfo->host_rx_ring_cnt_addr + offset; + } + + return TRUE; +} + +void halWpdmaInitRxRing(IN struct GLUE_INFO *prGlueInfo) +{ + struct GL_HIF_INFO *prHifInfo = NULL; + struct RTMP_RX_RING *prRxRing = NULL; + uint32_t i = 0, phy_addr = 0; + struct BUS_INFO *prBusInfo = NULL; + struct mt66xx_chip_info *prChipInfo; + uint8_t rv; + + ASSERT(prGlueInfo); + prHifInfo = &prGlueInfo->rHifInfo; + prChipInfo = prGlueInfo->prAdapter->chip_info; + prBusInfo = prChipInfo->bus_info; + + /* reset all RX Ring register */ + for (i = 0; i < NUM_OF_RX_RING; i++) { + prRxRing = &prHifInfo->RxRing[i]; + if (prBusInfo->setRxRingHwAddr) + rv = prBusInfo->setRxRingHwAddr(prRxRing, prBusInfo, i); + else + rv = defaultSetRxRingHwAddr( + prRxRing, prBusInfo, prChipInfo, i); + + if (!rv) + break; + phy_addr = ((uint64_t)prRxRing->Cell[0].AllocPa & + DMA_LOWER_32BITS_MASK); + prRxRing->RxCpuIdx = prRxRing->u4RingSize - 1; + kalDevRegWrite(prGlueInfo, prRxRing->hw_desc_base, phy_addr); + kalDevRegWrite(prGlueInfo, prRxRing->hw_cidx_addr, + prRxRing->RxCpuIdx); + kalDevRegWrite(prGlueInfo, prRxRing->hw_cnt_addr, + prRxRing->u4RingSize); + + if (prBusInfo->rx_ring_ext_ctrl) + prBusInfo->rx_ring_ext_ctrl(prGlueInfo, prRxRing, i); + + prRxRing->fgIsDumpLog = false; + + DBGLOG(HAL, TRACE, "-->RX_RING_%d[0x%x]: Base=0x%x, Cnt=%d\n", + i, prRxRing->hw_desc_base, + phy_addr, prRxRing->u4RingSize); + } +} + +void halWpdmaProcessCmdDmaDone(IN struct GLUE_INFO *prGlueInfo, + IN uint16_t u2Port) +{ + struct GL_HIF_INFO *prHifInfo = NULL; + struct HIF_MEM_OPS *prMemOps; + struct RTMP_TX_RING *prTxRing; + struct TXD_STRUCT *pTxD; + phys_addr_t PacketPa = 0; + void *pBuffer = NULL; + uint32_t u4SwIdx, u4DmaIdx = 0; + + ASSERT(prGlueInfo); + + prHifInfo = &prGlueInfo->rHifInfo; + prMemOps = &prHifInfo->rMemOps; + prTxRing = &prHifInfo->TxRing[u2Port]; + + kalDevRegRead(prGlueInfo, prTxRing->hw_didx_addr, &u4DmaIdx); + u4SwIdx = prTxRing->TxSwUsedIdx; + + do { + pBuffer = prTxRing->Cell[u4SwIdx].pBuffer; + PacketPa = prTxRing->Cell[u4SwIdx].PacketPa; + pTxD = (struct TXD_STRUCT *) prTxRing->Cell[u4SwIdx].AllocVa; + + if (pTxD->DMADONE == 0) + break; + + log_dbg(HAL, TRACE, "DMA done: port[%u] dma[%u] idx[%u] done[%u] pkt[0x%p] used[%u]\n", + u2Port, u4DmaIdx, u4SwIdx, pTxD->DMADONE, + prTxRing->Cell[u4SwIdx].pPacket, prTxRing->u4UsedCnt); + + if (prMemOps->unmapTxBuf && PacketPa) + prMemOps->unmapTxBuf(prHifInfo, PacketPa, pTxD->SDLen0); + + pTxD->DMADONE = 0; + if (prMemOps->freeBuf && pBuffer) + prMemOps->freeBuf(pBuffer, 0); + prTxRing->Cell[u4SwIdx].pBuffer = NULL; + prTxRing->Cell[u4SwIdx].pPacket = NULL; + prTxRing->u4UsedCnt--; + + GLUE_INC_REF_CNT( + prGlueInfo->prAdapter->rHifStats.u4CmdTxdoneCount); + + INC_RING_INDEX(u4SwIdx, TX_RING_SIZE); + } while (u4SwIdx != u4DmaIdx); + + prTxRing->TxSwUsedIdx = u4SwIdx; + +} + +void halWpdmaProcessDataDmaDone(IN struct GLUE_INFO *prGlueInfo, + IN uint16_t u2Port) +{ + struct GL_HIF_INFO *prHifInfo = NULL; + uint32_t u4SwIdx, u4DmaIdx = 0, u4Diff = 0; + struct RTMP_TX_RING *prTxRing; + + ASSERT(prGlueInfo); + + prHifInfo = &prGlueInfo->rHifInfo; + prTxRing = &prHifInfo->TxRing[u2Port]; + + kalDevRegRead(prGlueInfo, prTxRing->hw_didx_addr, &u4DmaIdx); + u4SwIdx = prTxRing->TxSwUsedIdx; + + if (u4DmaIdx > u4SwIdx) { + u4Diff = u4DmaIdx - u4SwIdx; + prTxRing->u4UsedCnt -= u4Diff; + } else if (u4DmaIdx < u4SwIdx) { + u4Diff = (TX_RING_SIZE + u4DmaIdx) - u4SwIdx; + prTxRing->u4UsedCnt -= u4Diff; + } else { + /* DMA index == SW used index */ + if (prTxRing->u4UsedCnt == TX_RING_SIZE) { + u4Diff = TX_RING_SIZE; + prTxRing->u4UsedCnt = 0; + } + } + + DBGLOG_LIMITED(HAL, TRACE, + "DMA done: port[%u] dma[%u] idx[%u] used[%u]\n", u2Port, + u4DmaIdx, u4SwIdx, prTxRing->u4UsedCnt); + + GLUE_ADD_REF_CNT(u4Diff, + prGlueInfo->prAdapter->rHifStats.u4DataTxdoneCount); + + prTxRing->TxSwUsedIdx = u4DmaIdx; +} + +uint32_t halWpdmaGetRxDmaDoneCnt(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRingNum) +{ + struct RTMP_RX_RING *prRxRing; + struct GL_HIF_INFO *prHifInfo; + uint32_t u4MaxCnt = 0, u4CpuIdx = 0, u4DmaIdx = 0, u4RxPktCnt; + + prHifInfo = &prGlueInfo->rHifInfo; + prRxRing = &prHifInfo->RxRing[ucRingNum]; + + kalDevRegRead(prGlueInfo, prRxRing->hw_cnt_addr, &u4MaxCnt); + kalDevRegRead(prGlueInfo, prRxRing->hw_cidx_addr, &u4CpuIdx); + kalDevRegRead(prGlueInfo, prRxRing->hw_didx_addr, &u4DmaIdx); + + if (u4MaxCnt == 0 || u4MaxCnt > RX_RING_SIZE) + return 0; + + if (u4CpuIdx > u4DmaIdx) + u4RxPktCnt = u4MaxCnt + u4DmaIdx - u4CpuIdx - 1; + else if (u4CpuIdx < u4DmaIdx) + u4RxPktCnt = u4DmaIdx - u4CpuIdx - 1; + else + u4RxPktCnt = u4MaxCnt - 1; + + return u4RxPktCnt; +} + +enum ENUM_CMD_TX_RESULT halWpdmaWriteCmd(IN struct GLUE_INFO *prGlueInfo, + IN struct CMD_INFO *prCmdInfo, IN uint8_t ucTC) +{ + struct GL_HIF_INFO *prHifInfo = NULL; + struct HIF_MEM_OPS *prMemOps; + struct RTMP_TX_RING *prTxRing; + struct RTMP_DMACB *pTxCell; + struct TXD_STRUCT *pTxD; + uint16_t u2Port = TX_RING_CMD_IDX_2; + uint32_t u4TotalLen; + void *pucSrc = NULL; +#if (CFG_SUPPORT_CONNAC2X == 1) + struct mt66xx_chip_info *prChipInfo; +#endif /* CFG_SUPPORT_CONNAC2 == 1 */ + + ASSERT(prGlueInfo); + +#if (CFG_SUPPORT_CONNAC2X == 1) + prChipInfo = prGlueInfo->prAdapter->chip_info; + if (prChipInfo->is_support_wacpu) + u2Port = TX_RING_WA_CMD_IDX_4; +#endif /* CFG_SUPPORT_CONNAC2X == 1 */ + + prHifInfo = &prGlueInfo->rHifInfo; + prMemOps = &prHifInfo->rMemOps; + prTxRing = &prHifInfo->TxRing[u2Port]; + + u4TotalLen = prCmdInfo->u4TxdLen + prCmdInfo->u4TxpLen; +#if (CFG_SUPPORT_CONNAC2X == 1) + if (u4TotalLen > prChipInfo->cmd_max_pkt_size) { + DBGLOG(HAL, ERROR, + "type: %u, cid: 0x%x, seq: %u, txd: %u, txp: %u\n", + prCmdInfo->eCmdType, + prCmdInfo->ucCID, + prCmdInfo->ucCmdSeqNum, + prCmdInfo->u4TxdLen, + prCmdInfo->u4TxpLen); + if (prCmdInfo->u4TxdLen) + DBGLOG_MEM32(HAL, ERROR, prCmdInfo->pucTxd, + prCmdInfo->u4TxdLen); + if (prCmdInfo->u4TxpLen) + DBGLOG_MEM32(HAL, ERROR, prCmdInfo->pucTxp, + prCmdInfo->u4TxpLen); + return FALSE; + } +#endif /* CFG_SUPPORT_CONNAC2X == 1 */ + if (prMemOps->allocRuntimeMem) + pucSrc = prMemOps->allocRuntimeMem(u4TotalLen); + + kalDevRegRead(prGlueInfo, prTxRing->hw_cidx_addr, &prTxRing->TxCpuIdx); + if (prTxRing->TxCpuIdx >= TX_RING_SIZE) { + DBGLOG(HAL, ERROR, "Error TxCpuIdx[%u]\n", prTxRing->TxCpuIdx); + if (prMemOps->freeBuf) + prMemOps->freeBuf(pucSrc, u4TotalLen); + return CMD_TX_RESULT_FAILED; + } + + pTxCell = &prTxRing->Cell[prTxRing->TxCpuIdx]; + pTxD = (struct TXD_STRUCT *)pTxCell->AllocVa; + pTxCell->pPacket = (void *)prCmdInfo; + pTxCell->pBuffer = pucSrc; + + if (prMemOps->copyCmd && + !prMemOps->copyCmd(prHifInfo, pTxCell, pucSrc, + prCmdInfo->pucTxd, prCmdInfo->u4TxdLen, + prCmdInfo->pucTxp, prCmdInfo->u4TxpLen)) { + if (prMemOps->freeBuf) + prMemOps->freeBuf(pucSrc, u4TotalLen); + ASSERT(0); + return CMD_TX_RESULT_FAILED; + } + + pTxD->SDPtr0 = (uint64_t)pTxCell->PacketPa & DMA_LOWER_32BITS_MASK; +#ifdef CONFIG_PHYS_ADDR_T_64BIT + pTxD->SDPtr0Ext = ((uint64_t)pTxCell->PacketPa >> DMA_BITS_OFFSET) & + DMA_HIGHER_4BITS_MASK; +#else + pTxD->SDPtr0Ext = 0; +#endif + pTxD->SDLen0 = u4TotalLen; + pTxD->SDPtr1 = 0; + pTxD->SDLen1 = 0; + pTxD->LastSec0 = 1; + pTxD->LastSec1 = 0; + pTxD->Burst = 0; + pTxD->DMADONE = 0; + + /* Increase TX_CTX_IDX, but write to register later. */ + INC_RING_INDEX(prTxRing->TxCpuIdx, TX_RING_SIZE); + + prTxRing->u4UsedCnt++; + kalDevRegWrite(prGlueInfo, prTxRing->hw_cidx_addr, prTxRing->TxCpuIdx); + + GLUE_INC_REF_CNT(prGlueInfo->prAdapter->rHifStats.u4CmdTxCount); + + DBGLOG(HAL, TRACE, + "%s: CmdInfo[0x%p], TxD[0x%p/%u] TxP[0x%p/%u] CPU idx[%u] Used[%u]\n", + __func__, prCmdInfo, prCmdInfo->pucTxd, prCmdInfo->u4TxdLen, + prCmdInfo->pucTxp, prCmdInfo->u4TxpLen, + prTxRing->TxCpuIdx, prTxRing->u4UsedCnt); + DBGLOG_MEM32(HAL, TRACE, prCmdInfo->pucTxd, prCmdInfo->u4TxdLen); + + if (u2Port == TX_RING_CMD_IDX_2 +#if (CFG_SUPPORT_CONNAC2X == 1) + || u2Port == TX_RING_WA_CMD_IDX_4 +#endif /* CFG_SUPPORT_CONNAC2 == 1 */ + ) + nicTxReleaseResource_PSE(prGlueInfo->prAdapter, + TC4_INDEX, + nicTxGetPageCount(prGlueInfo->prAdapter, + pTxD->SDLen0, + TRUE), + TRUE); + + return CMD_TX_RESULT_SUCCESS; +} + +static bool halWpdmaFillTxRing(struct GLUE_INFO *prGlueInfo, + struct MSDU_TOKEN_ENTRY *prToken) +{ + struct GL_HIF_INFO *prHifInfo = NULL; + struct mt66xx_chip_info *prChipInfo; + struct RTMP_TX_RING *prTxRing; + struct RTMP_DMACB *pTxCell; + struct TXD_STRUCT *pTxD; + uint16_t u2Port = TX_RING_DATA0_IDX_0; + + ASSERT(prGlueInfo); + + prHifInfo = &prGlueInfo->rHifInfo; + prChipInfo = prGlueInfo->prAdapter->chip_info; + + u2Port = halTxRingDataSelect( + prGlueInfo->prAdapter, prToken->prMsduInfo); + prTxRing = &prHifInfo->TxRing[u2Port]; + + kalDevRegRead(prGlueInfo, prTxRing->hw_cidx_addr, &prTxRing->TxCpuIdx); + if (prTxRing->TxCpuIdx >= TX_RING_SIZE) { + DBGLOG(HAL, ERROR, "Error TxCpuIdx[%u]\n", prTxRing->TxCpuIdx); + halReturnMsduToken(prGlueInfo->prAdapter, prToken->u4Token); + return FALSE; + } + + pTxCell = &prTxRing->Cell[prTxRing->TxCpuIdx]; + prToken->u4CpuIdx = prTxRing->TxCpuIdx; + prToken->u2Port = u2Port; + pTxCell->prToken = prToken; + + pTxD = (struct TXD_STRUCT *)pTxCell->AllocVa; + pTxD->SDPtr0 = (uint64_t)prToken->rDmaAddr & DMA_LOWER_32BITS_MASK; +#ifdef CONFIG_PHYS_ADDR_T_64BIT + pTxD->SDPtr0Ext = ((uint64_t)prToken->rDmaAddr >> DMA_BITS_OFFSET) & + DMA_HIGHER_4BITS_MASK; +#else + pTxD->SDPtr0Ext = 0; +#endif + pTxD->SDLen0 = NIC_TX_DESC_AND_PADDING_LENGTH + + prChipInfo->txd_append_size; + if (prChipInfo->is_support_cr4) + pTxD->SDLen0 += HIF_TX_PAYLOAD_LENGTH; + pTxD->SDPtr1 = 0; + pTxD->SDLen1 = 0; + pTxD->LastSec0 = 1; + pTxD->LastSec1 = 0; + pTxD->Burst = 0; + pTxD->DMADONE = 0; + + /* Increase TX_CTX_IDX, but write to register later. */ + INC_RING_INDEX(prTxRing->TxCpuIdx, TX_RING_SIZE); + + /* Update HW Tx DMA ring */ + prTxRing->u4UsedCnt++; + kalDevRegWrite(prGlueInfo, prTxRing->hw_cidx_addr, prTxRing->TxCpuIdx); + + DBGLOG_LIMITED(HAL, TRACE, + "Tx Data:Ring%d CPU idx[0x%x] Used[%u]\n", + u2Port, prTxRing->TxCpuIdx, prTxRing->u4UsedCnt); + + GLUE_INC_REF_CNT(prGlueInfo->prAdapter->rHifStats.u4DataTxCount); + + return TRUE; +} + +static bool halFlushToken(struct GLUE_INFO *prGlueInfo, + struct MSDU_TOKEN_ENTRY *prToken) +{ + struct GL_HIF_INFO *prHifInfo = NULL; + struct HIF_MEM_OPS *prMemOps; + + ASSERT(prGlueInfo); + prHifInfo = &prGlueInfo->rHifInfo; + prMemOps = &prHifInfo->rMemOps; + + if (prMemOps->mapTxBuf) { + prToken->rDmaAddr = prMemOps->mapTxBuf( + prHifInfo, prToken->prPacket, 0, prToken->u4DmaLength); + if (!prToken->rDmaAddr) + return false; + } + + return true; +} + +static bool halWpdmaWriteData(struct GLUE_INFO *prGlueInfo, + struct MSDU_INFO *prMsduInfo, + struct MSDU_TOKEN_ENTRY *prFillToken, + struct MSDU_TOKEN_ENTRY *prToken, + uint32_t u4Idx, uint32_t u4Num) +{ + struct GL_HIF_INFO *prHifInfo = NULL; + struct mt66xx_chip_info *prChipInfo; + bool fgIsLast = (u4Idx + 1) == u4Num; + + ASSERT(prGlueInfo); + prHifInfo = &prGlueInfo->rHifInfo; + prChipInfo = prGlueInfo->prAdapter->chip_info; + + /* Update Tx descriptor */ + halTxUpdateCutThroughDesc(prGlueInfo, prMsduInfo, prFillToken, + prToken, u4Idx, fgIsLast); + + /* Update token exclude FillToken */ + if (prToken != prFillToken) { + if (!halFlushToken(prGlueInfo, prToken)) + return false; + } + + /* Update FillToken */ + if (fgIsLast) { + if (!halFlushToken(prGlueInfo, prFillToken)) + return false; + halWpdmaFillTxRing(prGlueInfo, prFillToken); + } + + return true; +} + +void halWpdamFreeMsdu(struct GLUE_INFO *prGlueInfo, + struct MSDU_INFO *prMsduInfo, + bool fgSetEvent) +{ + DBGLOG(HAL, LOUD, "Tx Data: Msdu[0x%p], TokFree[%u] TxDone[%u]\n", + prMsduInfo, halGetMsduTokenFreeCnt(prGlueInfo->prAdapter), + (prMsduInfo->pfTxDoneHandler ? TRUE : FALSE)); + + nicTxReleaseResource_PSE(prGlueInfo->prAdapter, prMsduInfo->ucTC, + nicTxGetPageCount(prGlueInfo->prAdapter, + prMsduInfo->u2FrameLength, TRUE), TRUE); + +#if HIF_TX_PREALLOC_DATA_BUFFER + if (!prMsduInfo->pfTxDoneHandler) { + nicTxFreePacket(prGlueInfo->prAdapter, prMsduInfo, FALSE); + nicTxReturnMsduInfo(prGlueInfo->prAdapter, prMsduInfo); + } +#endif + + if (fgSetEvent && wlanGetTxPendingFrameCount(prGlueInfo->prAdapter)) + kalSetEvent(prGlueInfo); +} + +bool halWpdmaWriteMsdu(struct GLUE_INFO *prGlueInfo, + struct MSDU_INFO *prMsduInfo, + struct list_head *prCurList) +{ + struct GL_HIF_INFO *prHifInfo = NULL; + struct HIF_MEM_OPS *prMemOps; + struct MSDU_TOKEN_ENTRY *prToken = NULL; + struct sk_buff *prSkb; + uint8_t *pucSrc; + uint32_t u4TotalLen; + + uint32_t u4TxDescAppendSize; + + ASSERT(prGlueInfo); + ASSERT(prMsduInfo); + + prHifInfo = &prGlueInfo->rHifInfo; + prMemOps = &prHifInfo->rMemOps; + prSkb = (struct sk_buff *)prMsduInfo->prPacket; + + if (prSkb == NULL || prSkb->data == NULL) { + DBGLOG(HAL, ERROR, "prSkb is 0x%p\n", prSkb); + + if (prCurList) { + list_del(prCurList); + prHifInfo->u4TxDataQLen--; + } + halWpdamFreeMsdu(prGlueInfo, prMsduInfo, true); + + return false; + } + + pucSrc = prSkb->data; + + u4TotalLen = prSkb->len; + + if (prGlueInfo->prAdapter != NULL && + prGlueInfo->prAdapter->chip_info != NULL) { + + u4TxDescAppendSize = + prGlueInfo->prAdapter->chip_info->txd_append_size; + } else { + DBGLOG(HAL, ERROR, "prGlueInfo->prAdapter is null\n"); + + if (prCurList) { + list_del(prCurList); + prHifInfo->u4TxDataQLen--; + } + halWpdamFreeMsdu(prGlueInfo, prMsduInfo, true); + + return false; + } + + if (u4TotalLen <= (AXI_TX_MAX_SIZE_PER_FRAME + u4TxDescAppendSize)) { + + /* Acquire MSDU token */ + prToken = halAcquireMsduToken(prGlueInfo->prAdapter); + if (!prToken) { + DBGLOG(HAL, ERROR, "Write MSDU acquire token fail\n"); + return false; + } + + /* Use MsduInfo to select TxRing */ + prToken->prMsduInfo = prMsduInfo; + prToken->ucWlanIndex = prMsduInfo->ucWlanIndex; + +#if HIF_TX_PREALLOC_DATA_BUFFER + if (prMemOps->copyTxData) + prMemOps->copyTxData(prToken, pucSrc, u4TotalLen); +#else + prToken->prPacket = pucSrc; + prToken->u4DmaLength = u4TotalLen; + prMsduInfo->prToken = prToken; +#endif + + if (!halWpdmaWriteData(prGlueInfo, prMsduInfo, prToken, + prToken, 0, 1)) { + halReturnMsduToken(prGlueInfo->prAdapter, + prToken->u4Token); + return false; + } + + } else { + DBGLOG(HAL, ERROR, "u4Len=%u, 0x%p, txd_append_size=%d\n", + u4TotalLen, prSkb, + prGlueInfo->prAdapter->chip_info->txd_append_size); + + DBGLOG(HAL, ERROR, "%u,%u,%u,%u,%u,%u,%u,%u\n", + prMsduInfo->eSrc, prMsduInfo->ucUserPriority, + prMsduInfo->ucTC, prMsduInfo->ucPacketType, + prMsduInfo->ucStaRecIndex, prMsduInfo->ucBssIndex, + prMsduInfo->ucWlanIndex, prMsduInfo->ucPacketFormat); + } + + if (prCurList) { + list_del(prCurList); + prHifInfo->u4TxDataQLen--; + } + if (prMsduInfo->pfHifTxMsduDoneCb) + prMsduInfo->pfHifTxMsduDoneCb(prGlueInfo->prAdapter, + prMsduInfo); + halWpdamFreeMsdu(prGlueInfo, prMsduInfo, true); + + return true; +} + +bool halWpdmaWriteAmsdu(struct GLUE_INFO *prGlueInfo, + struct list_head *prList, + uint32_t u4Num, uint16_t u2Size) +{ + struct GL_HIF_INFO *prHifInfo = NULL; + struct HIF_MEM_OPS *prMemOps; + struct list_head *prCur, *prNext; + struct TX_DATA_REQ *prTxReq; + struct MSDU_TOKEN_ENTRY *prFillToken = NULL, *prToken = NULL; + struct MSDU_INFO *prMsduInfo; + struct AMSDU_MAC_TX_DESC *prTxD = NULL; + struct sk_buff *prSkb; + uint8_t *pucSrc; + uint32_t u4TotalLen, u4Idx, u4FreeToken, u4FreeRing; + uint16_t u2Port; + bool fgIsLast; + + ASSERT(prGlueInfo); + + prHifInfo = &prGlueInfo->rHifInfo; + prMemOps = &prHifInfo->rMemOps; + u4FreeToken = halGetMsduTokenFreeCnt(prGlueInfo->prAdapter); + + /* Peek head to select TxRing */ + prTxReq = list_entry(prList, struct TX_DATA_REQ, list); + u2Port = halTxRingDataSelect( + prGlueInfo->prAdapter, prTxReq->prMsduInfo); + u4FreeRing = TX_RING_SIZE - prHifInfo->TxRing[u2Port].u4UsedCnt; + + if ((u4FreeToken < u4Num) || (u4FreeRing <= 1)) { + DBGLOG(HAL, WARN, + "Amsdu low tx res acquire[%u], tok[%u], ring%d[%u]\n", + u4Num, u4FreeToken, u2Port, u4FreeRing); + return false; + } + + prCur = prList; + for (u4Idx = 0; u4Idx < u4Num; u4Idx++) { + prTxReq = list_entry(prCur, struct TX_DATA_REQ, list); + prMsduInfo = prTxReq->prMsduInfo; + prSkb = (struct sk_buff *)prMsduInfo->prPacket; + pucSrc = prSkb->data; + u4TotalLen = prSkb->len; + fgIsLast = (u4Idx == u4Num - 1); + + /* Acquire MSDU token */ + prToken = halAcquireMsduToken(prGlueInfo->prAdapter); + if (!prToken) { + DBGLOG(HAL, ERROR, "Write AMSDU acquire token fail\n"); + return false; + } + + /* Use MsduInfo to select TxRing */ + prToken->prMsduInfo = prMsduInfo; + prToken->ucWlanIndex = prMsduInfo->ucWlanIndex; + +#if HIF_TX_PREALLOC_DATA_BUFFER + if (prMemOps->copyTxData) + prMemOps->copyTxData(prToken, pucSrc, u4TotalLen); +#else + prToken->prPacket = pucSrc; + prToken->u4DmaLength = u4TotalLen; + prMsduInfo->prToken = prToken; +#endif + + if (!prFillToken) { + prFillToken = prToken; + prTxD = (struct AMSDU_MAC_TX_DESC *)prToken->prPacket; + } + + if (fgIsLast) { + prTxD->u2TxByteCount = u2Size; + prTxD->u4DW1 |= TXD_DW1_AMSDU_C; + } + + if (!halWpdmaWriteData(prGlueInfo, prMsduInfo, prFillToken, + prToken, u4Idx, u4Num)) { + halReturnMsduToken(prGlueInfo->prAdapter, + prToken->u4Token); + return false; + } + prCur = prCur->next; + } + + prCur = prList; + for (u4Idx = 0; u4Idx < u4Num; u4Idx++) { + prNext = prCur->next; + prTxReq = list_entry(prCur, struct TX_DATA_REQ, list); + prMsduInfo = prTxReq->prMsduInfo; + + list_del(prCur); + prHifInfo->u4TxDataQLen--; + if (prMsduInfo->pfHifTxMsduDoneCb) + prMsduInfo->pfHifTxMsduDoneCb(prGlueInfo->prAdapter, + prMsduInfo); + halWpdamFreeMsdu(prGlueInfo, prMsduInfo, true); + prCur = prNext; + } + + DBGLOG(HAL, LOUD, "Amsdu num:%d tx byte: %d\n", u4Num, u2Size); + return true; +} + +u_int8_t halIsStaticMapBusAddr(IN struct ADAPTER *prAdapter, + IN uint32_t u4Addr) +{ + if (u4Addr < prAdapter->chip_info->bus_info->max_static_map_addr) + return TRUE; + else + return FALSE; +} + +u_int8_t halChipToStaticMapBusAddr(IN struct GLUE_INFO *prGlueInfo, + IN uint32_t u4ChipAddr, + OUT uint32_t *pu4BusAddr) +{ + struct BUS_INFO *prBusInfo = prGlueInfo->prAdapter->chip_info->bus_info; + uint32_t u4StartAddr, u4EndAddr, u4BusAddr; + uint32_t u4Idx = 0; + + if (halIsStaticMapBusAddr(prGlueInfo->prAdapter, u4ChipAddr)) { + *pu4BusAddr = u4ChipAddr; + return TRUE; + } + + while (TRUE) { + u4StartAddr = prBusInfo->bus2chip[u4Idx].u4ChipAddr; + u4EndAddr = prBusInfo->bus2chip[u4Idx].u4ChipAddr + + prBusInfo->bus2chip[u4Idx].u4Range; + + /* End of mapping table */ + if (u4EndAddr == 0x0) + return FALSE; + + if ((u4ChipAddr >= u4StartAddr) && (u4ChipAddr <= u4EndAddr)) { + u4BusAddr = (u4ChipAddr - u4StartAddr) + + prBusInfo->bus2chip[u4Idx].u4BusAddr; + break; + } + + u4Idx++; + } + + *pu4BusAddr = u4BusAddr; + return TRUE; +} + +u_int8_t halGetDynamicMapReg(IN struct GLUE_INFO *prGlueInfo, + IN uint32_t u4ChipAddr, OUT uint32_t *pu4Value) +{ + struct GL_HIF_INFO *prHifInfo = &prGlueInfo->rHifInfo; + uint32_t u4ReMapReg, u4BusAddr; + + if (!halChipToStaticMapBusAddr(prGlueInfo, MCU_CFG_PCIE_REMAP2, + &u4ReMapReg)) + return FALSE; + + + RTMP_IO_WRITE32(prHifInfo, u4ReMapReg, u4ChipAddr & PCIE_REMAP2_MASK); + u4BusAddr = PCIE_REMAP2_BUS_ADDR + (u4ChipAddr & ~PCIE_REMAP2_MASK); + RTMP_IO_READ32(prHifInfo, u4BusAddr, pu4Value); + + return TRUE; +} + +u_int8_t halSetDynamicMapReg(IN struct GLUE_INFO *prGlueInfo, + IN uint32_t u4ChipAddr, IN uint32_t u4Value) +{ + struct GL_HIF_INFO *prHifInfo = &prGlueInfo->rHifInfo; + uint32_t u4ReMapReg, u4BusAddr; + + if (!halChipToStaticMapBusAddr(prGlueInfo, MCU_CFG_PCIE_REMAP2, + &u4ReMapReg)) + return FALSE; + + RTMP_IO_WRITE32(prHifInfo, u4ReMapReg, u4ChipAddr & PCIE_REMAP2_MASK); + u4BusAddr = PCIE_REMAP2_BUS_ADDR + (u4ChipAddr & ~PCIE_REMAP2_MASK); + RTMP_IO_WRITE32(prHifInfo, u4BusAddr, u4Value); + + return TRUE; +} + +u_int8_t halIsPendingRx(IN struct ADAPTER *prAdapter) +{ + /* TODO: check pending Rx + * if previous Rx handling is break due to lack of SwRfb + */ + return FALSE; +} + +uint32_t halGetValidCoalescingBufSize(IN struct ADAPTER *prAdapter) +{ + uint32_t u4BufSize; + + if (HIF_TX_COALESCING_BUFFER_SIZE > HIF_RX_COALESCING_BUFFER_SIZE) + u4BufSize = HIF_TX_COALESCING_BUFFER_SIZE; + else + u4BufSize = HIF_RX_COALESCING_BUFFER_SIZE; + + return u4BufSize; +} + +uint32_t halAllocateIOBuffer(IN struct ADAPTER *prAdapter) +{ + return WLAN_STATUS_SUCCESS; +} + +uint32_t halReleaseIOBuffer(IN struct ADAPTER *prAdapter) +{ + return WLAN_STATUS_SUCCESS; +} + +void halProcessAbnormalInterrupt(IN struct ADAPTER *prAdapter) +{ + +} + +static void halDefaultProcessSoftwareInterrupt( + IN struct ADAPTER *prAdapter) +{ + struct GLUE_INFO *prGlueInfo; + struct GL_HIF_INFO *prHifInfo; + struct ERR_RECOVERY_CTRL_T *prErrRecoveryCtrl; + uint32_t u4Status = 0; + + if (prAdapter->prGlueInfo == NULL) { + DBGLOG(HAL, ERROR, "prGlueInfo is NULL\n"); + return; + } + + prGlueInfo = prAdapter->prGlueInfo; + prHifInfo = &prGlueInfo->rHifInfo; + prErrRecoveryCtrl = &prHifInfo->rErrRecoveryCtl; + + kalDevRegRead(prGlueInfo, MCU2HOST_SW_INT_STA, &u4Status); + if (u4Status & ERROR_DETECT_MASK) { + prErrRecoveryCtrl->u4Status = u4Status; + kalDevRegWrite(prGlueInfo, MCU2HOST_SW_INT_STA, + ERROR_DETECT_MASK); + halHwRecoveryFromError(prAdapter); + } +} + +void halProcessSoftwareInterrupt(IN struct ADAPTER *prAdapter) +{ + struct BUS_INFO *prBusInfo = NULL; + + if (prAdapter == NULL) { + DBGLOG(HAL, ERROR, "prAdapter is NULL\n"); + return; + } + + prBusInfo = prAdapter->chip_info->bus_info; + + if (prBusInfo->processSoftwareInterrupt) + prBusInfo->processSoftwareInterrupt(prAdapter); + else + halDefaultProcessSoftwareInterrupt(prAdapter); +} +#if KERNEL_VERSION(4, 15, 0) <= LINUX_VERSION_CODE +void halHwRecoveryTimeout(struct timer_list *timer) +#else +void halHwRecoveryTimeout(unsigned long arg) +#endif +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) + struct GL_HIF_INFO *prHif = from_timer(prHif, timer, rSerTimer); + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *)prHif->rSerTimerData; +#else + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *)arg; +#endif + struct ADAPTER *prAdapter = NULL; + + ASSERT(prGlueInfo); + prAdapter = prGlueInfo->prAdapter; + ASSERT(prAdapter); + + DBGLOG(HAL, ERROR, "SER timer Timeout\n"); + +#if CFG_CHIP_RESET_SUPPORT +#if (CFG_SUPPORT_CONNINFRA == 0) + GL_RESET_TRIGGER(prAdapter, RST_FLAG_CHIP_RESET); +#else + kalSetSerTimeoutEvent(prGlueInfo); +#endif +#endif +} + +void halSetDrvSer(struct ADAPTER *prAdapter) +{ + struct BUS_INFO *prBusInfo = NULL; + + ASSERT(prAdapter); + ASSERT(prAdapter->prGlueInfo); + + prBusInfo = prAdapter->chip_info->bus_info; + + DBGLOG(HAL, INFO, "Set Driver Ser\n"); + if (prBusInfo->softwareInterruptMcu) + prBusInfo->softwareInterruptMcu(prAdapter, + MCU_INT_DRIVER_SER); + else + kalDevRegWrite(prAdapter->prGlueInfo, HOST2MCU_SW_INT_SET, + MCU_INT_DRIVER_SER); +} + +static void halStartSerTimer(IN struct ADAPTER *prAdapter) +{ + struct GLUE_INFO *prGlueInfo; + struct GL_HIF_INFO *prHifInfo; + + prGlueInfo = prAdapter->prGlueInfo; + prHifInfo = &prGlueInfo->rHifInfo; + mod_timer(&prHifInfo->rSerTimer, + jiffies + HIF_SER_TIMEOUT * HZ / MSEC_PER_SEC); + DBGLOG(HAL, INFO, "Start SER timer\n"); +} + +void halHwRecoveryFromError(IN struct ADAPTER *prAdapter) +{ + struct GLUE_INFO *prGlueInfo; + struct mt66xx_chip_info *prChipInfo; + struct GL_HIF_INFO *prHifInfo; + struct BUS_INFO *prBusInfo = NULL; + struct ERR_RECOVERY_CTRL_T *prErrRecoveryCtrl; + uint32_t u4Status = 0; + + prGlueInfo = prAdapter->prGlueInfo; + prHifInfo = &prGlueInfo->rHifInfo; + prBusInfo = prGlueInfo->prAdapter->chip_info->bus_info; + prErrRecoveryCtrl = &prHifInfo->rErrRecoveryCtl; + + u4Status = prErrRecoveryCtrl->u4Status; + prErrRecoveryCtrl->u4Status = 0; + + if (prAdapter->rWifiVar.fgEnableSer == FALSE) + return; + + switch (prErrRecoveryCtrl->eErrRecovState) { + case ERR_RECOV_STOP_IDLE: + if (u4Status & ERROR_DETECT_STOP_PDMA) { + prChipInfo = prAdapter->chip_info; + if (prChipInfo->asicDumpSerDummyCR) + prChipInfo->asicDumpSerDummyCR(prAdapter); + halStartSerTimer(prAdapter); + DBGLOG(HAL, INFO, + "SER(E) Host stop PDMA tx/rx ring operation & receive\n"); + nicSerStopTxRx(prAdapter); +#if (CFG_SUPPORT_CONNAC2X == 1) + /*get WFDMA HW data before Layer 1 SER*/ + /*event*/ + halRxReceiveRFBs(prAdapter, WFDMA1_RX_RING_IDX_0, + FALSE); +#endif +#if CFG_SUPPORT_MULTITHREAD + kalSetRxProcessEvent(prAdapter->prGlueInfo); + DBGLOG(HAL, INFO, + "SER(F) kalSetRxProcessEvent\n"); +#else + DBGLOG(HAL, INFO, + "SER(F) nicRxProcessRFBs\n"); + nicRxProcessRFBs(prAdapter); +#endif + + DBGLOG(HAL, INFO, + "SER(F) Host ACK PDMA tx/rx ring stop operation\n"); + + if (prBusInfo->softwareInterruptMcu) { + prBusInfo->softwareInterruptMcu(prAdapter, + MCU_INT_PDMA0_STOP_DONE); + } else { + kalDevRegWrite(prGlueInfo, HOST2MCU_SW_INT_SET, + MCU_INT_PDMA0_STOP_DONE); + } + + /* re-call for change status to stop dma0 */ + prErrRecoveryCtrl->eErrRecovState = + ERR_RECOV_STOP_PDMA0; + } else { + DBGLOG(HAL, ERROR, "SER CurStat=%u Event=%x\n", + prErrRecoveryCtrl->eErrRecovState, u4Status); + } + break; + + case ERR_RECOV_STOP_PDMA0: + if (u4Status & ERROR_DETECT_RESET_DONE) { + DBGLOG(HAL, INFO, "SER(L) Host re-initialize PDMA\n"); + /* only reset TXD & RXD */ + halWpdmaAllocRing(prAdapter->prGlueInfo, false); + nicFreePendingTxMsduInfo(prAdapter, 0xFF, + MSDU_REMOVE_BY_ALL); + wlanClearPendingCommandQueue(prAdapter); + halResetMsduToken(prAdapter); + prAdapter->u4NoMoreRfb = 0; + + DBGLOG(HAL, INFO, "SER(M) Host enable PDMA\n"); + halWpdmaInitRing(prGlueInfo, false); + + /* reset SW value after InitRing */ + prChipInfo = prAdapter->chip_info; + if (prChipInfo->asicWfdmaReInit) + prChipInfo->asicWfdmaReInit(prAdapter); + + DBGLOG(HAL, INFO, + "SER(N) Host interrupt MCU PDMA ring init done\n"); + prErrRecoveryCtrl->eErrRecovState = + ERR_RECOV_RESET_PDMA0; + if (prBusInfo->softwareInterruptMcu) { + prBusInfo->softwareInterruptMcu(prAdapter, + MCU_INT_PDMA0_INIT_DONE); + } else { + kalDevRegWrite(prGlueInfo, HOST2MCU_SW_INT_SET, + MCU_INT_PDMA0_INIT_DONE); + } + } else { + DBGLOG(HAL, ERROR, "SER CurStat=%u Event=%x\n", + prErrRecoveryCtrl->eErrRecovState, u4Status); + } + break; + + case ERR_RECOV_RESET_PDMA0: + if (u4Status & ERROR_DETECT_RECOVERY_DONE) { + DBGLOG(HAL, INFO, + "SER(Q) Host interrupt MCU SER handle done\n"); + prErrRecoveryCtrl->eErrRecovState = + ERR_RECOV_WAIT_MCU_NORMAL; + if (prBusInfo->softwareInterruptMcu) { + prBusInfo->softwareInterruptMcu(prAdapter, + MCU_INT_PDMA0_RECOVERY_DONE); + } else { + kalDevRegWrite(prGlueInfo, HOST2MCU_SW_INT_SET, + MCU_INT_PDMA0_RECOVERY_DONE); + } + } else { + DBGLOG(HAL, ERROR, "SER CurStat=%u Event=%x\n", + prErrRecoveryCtrl->eErrRecovState, u4Status); + } + break; + + case ERR_RECOV_WAIT_MCU_NORMAL: + if (u4Status & ERROR_DETECT_MCU_NORMAL_STATE) { + del_timer_sync(&prHifInfo->rSerTimer); + + /* update Beacon frame if operating in AP mode. */ + DBGLOG(HAL, INFO, "SER(T) Host re-initialize BCN\n"); + nicSerReInitBeaconFrame(prAdapter); + + kalDevKickCmd(prAdapter->prGlueInfo); + kalDevKickData(prAdapter->prGlueInfo); + halRxReceiveRFBs(prAdapter, RX_RING_EVT_IDX_1, FALSE); + halRxReceiveRFBs(prAdapter, RX_RING_DATA_IDX_0, TRUE); + nicSerStartTxRx(prAdapter); +#if CFG_SUPPORT_MULTITHREAD + kalSetTxEvent2Hif(prAdapter->prGlueInfo); +#endif + prErrRecoveryCtrl->eErrRecovState = ERR_RECOV_STOP_IDLE; + } else { + DBGLOG(HAL, ERROR, "SER CurStat=%u Event=%x\n", + prErrRecoveryCtrl->eErrRecovState, u4Status); + } + break; + + default: + DBGLOG(HAL, ERROR, "SER CurStat=%u Event=%x!!!\n", + prErrRecoveryCtrl->eErrRecovState, u4Status); + break; + } +} + +void halDeAggRxPktWorker(struct work_struct *work) +{ + +} + +void halRxTasklet(unsigned long data) +{ + +} + +void halTxCompleteTasklet(unsigned long data) +{ + +} + +/* Hif power off wifi */ +uint32_t halHifPowerOffWifi(IN struct ADAPTER *prAdapter) +{ + struct GL_HIF_INFO *prHifInfo = NULL; + uint32_t rStatus = WLAN_STATUS_SUCCESS; + struct BUS_INFO *prBusInfo = NULL; + + prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + prBusInfo = prAdapter->chip_info->bus_info; + + DBGLOG(INIT, INFO, "Power off Wi-Fi!\n"); + + ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); + +#if defined(_HIF_AXI) + if (nicProcessISTWithSpecifiedCount(prAdapter, 5) != + WLAN_STATUS_NOT_INDICATING) + DBGLOG(INIT, INFO, + "Handle pending interrupt\n"); +#endif + /* Power off Wi-Fi */ + wlanSendNicPowerCtrlCmd(prAdapter, TRUE); + + prHifInfo->fgIsPowerOff = true; + + /* prAdapter->fgWiFiInSleepyState = TRUE; */ + RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); + + rStatus = wlanCheckWifiFunc(prAdapter, FALSE); + + if (prBusInfo->setPdmaIntMask) + prBusInfo->setPdmaIntMask(prAdapter->prGlueInfo, FALSE); + nicDisableInterrupt(prAdapter); + + return rStatus; +} + +u_int8_t halIsTxResourceControlEn(IN struct ADAPTER *prAdapter) +{ + return FALSE; +} + +void halTxResourceResetHwTQCounter(IN struct ADAPTER *prAdapter) +{ +} + +uint32_t halGetHifTxPageSize(IN struct ADAPTER *prAdapter) +{ + return HIF_TX_PAGE_SIZE; +} + +/*----------------------------------------------------------------------------*/ +/*! +* @brief Check if HIF state is READY for upper layer cfg80211 +* +* @param prAdapter Pointer to the Adapter structure. +* +* @return (TRUE: ready, FALSE: not ready) +*/ +/*----------------------------------------------------------------------------*/ +bool halIsHifStateReady(IN struct ADAPTER *prAdapter, uint8_t *pucState) +{ + /* PCIE owner should implement this function */ + + return TRUE; +} + +/*----------------------------------------------------------------------------*/ +/*! +* @brief Check if HIF state is during supend process +* +* @param prAdapter Pointer to the Adapter structure. +* +* @return (TRUE: suspend, reject the caller action. FALSE: not suspend) +*/ +/*----------------------------------------------------------------------------*/ +bool halIsHifStateSuspend(IN struct ADAPTER *prAdapter) +{ + /* PCIE owner should implement this function */ + + return FALSE; +} + +void halUpdateTxMaxQuota(IN struct ADAPTER *prAdapter) +{ + struct BUS_INFO *prBusInfo; + uint32_t u4Ret; + uint32_t u4Quota; + uint16_t u2PortIdx; + bool fgRun; + uint8_t ucWmmIndex; + + KAL_SPIN_LOCK_DECLARATION(); + + prBusInfo = prAdapter->chip_info->bus_info; + + for (ucWmmIndex = 0; ucWmmIndex < prAdapter->ucWmmSetNum; + ucWmmIndex++) { + + u4Ret = WLAN_STATUS_SUCCESS; + u2PortIdx = halRingDataSelectByWmmIndex(prAdapter, ucWmmIndex); + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_UPDATE_WMM_QUOTA); + u4Quota = prAdapter->rWmmQuotaReqCS[ucWmmIndex].u4Quota; + fgRun = prAdapter->rWmmQuotaReqCS[ucWmmIndex].fgRun; + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_UPDATE_WMM_QUOTA); + + if (fgRun) { + if (prBusInfo->updateTxRingMaxQuota) { + u4Ret = prBusInfo->updateTxRingMaxQuota( + prAdapter, u2PortIdx, u4Quota); + } else { + DBGLOG(HAL, INFO, + "updateTxRingMaxQuota not implemented\n"); + u4Ret = WLAN_STATUS_NOT_ACCEPTED; + } + } + + DBGLOG(HAL, INFO, + "WmmQuota,Run,%u,Wmm,%u,Port,%u,Quota,0x%x,ret=0x%x\n", + fgRun, ucWmmIndex, u2PortIdx, u4Quota, u4Ret); + + if (u4Ret != WLAN_STATUS_PENDING) { + KAL_ACQUIRE_SPIN_LOCK(prAdapter, + SPIN_LOCK_UPDATE_WMM_QUOTA); + prAdapter->rWmmQuotaReqCS[ucWmmIndex].fgRun + = false; + KAL_RELEASE_SPIN_LOCK(prAdapter, + SPIN_LOCK_UPDATE_WMM_QUOTA); + } + } +} + +void halEnableSlpProt(struct GLUE_INFO *prGlueInfo) +{ + uint32_t u4Val = 0; + uint32_t u4WaitDelay = 20000; + + kalDevRegRead(prGlueInfo, CONN_HIF_PDMA_CSR_PDMA_SLP_PROT_ADDR, &u4Val); + u4Val |= CONN_HIF_PDMA_CSR_PDMA_SLP_PROT_PDMA_AXI_SLPPROT_ENABLE_MASK; + kalDevRegWrite(prGlueInfo, CONN_HIF_PDMA_CSR_PDMA_SLP_PROT_ADDR, u4Val); + while (TRUE) { + u4WaitDelay--; + kalDevRegRead(prGlueInfo, CONN_HIF_PDMA_CSR_PDMA_SLP_PROT_ADDR, + &u4Val); + if (CONN_HIF_PDMA_CSR_PDMA_SLP_PROT_PDMA_AXI_SLPPROT_RDY_MASK & + u4Val) + break; + if (u4WaitDelay == 0) { + DBGLOG(HAL, ERROR, "wait for sleep protect timeout.\n"); + GL_RESET_TRIGGER(prGlueInfo->prAdapter, + RST_FLAG_CHIP_RESET); + break; + } + kalUdelay(1); + } +} + +void halDisableSlpProt(struct GLUE_INFO *prGlueInfo) +{ + uint32_t u4Val = 0; + + kalDevRegRead(prGlueInfo, CONN_HIF_PDMA_CSR_PDMA_SLP_PROT_ADDR, &u4Val); + u4Val &= ~CONN_HIF_PDMA_CSR_PDMA_SLP_PROT_PDMA_AXI_SLPPROT_ENABLE_MASK; + kalDevRegWrite(prGlueInfo, CONN_HIF_PDMA_CSR_PDMA_SLP_PROT_ADDR, u4Val); +} + +void halNotifyMdCrash(IN struct ADAPTER *prAdapter) +{ + if (!prAdapter) { + DBGLOG(HAL, ERROR, "Null prAdapter.\n"); + return; + } + DBGLOG(HAL, INFO, "halNotifyMdCrash.\n"); + kalDevRegWrite(prAdapter->prGlueInfo, HOST2MCU_SW_INT_SET, + MCU_INT_NOTIFY_MD_CRASH); +} + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/common/include/hif_pdma.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/common/include/hif_pdma.h new file mode 100644 index 0000000000000000000000000000000000000000..2cd6b0f9354e295d411bf5cc30739c40b63e5d1c --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/common/include/hif_pdma.h @@ -0,0 +1,504 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + Module Name: + hif_pdma.h + */ + +#ifndef __HIF_PDMA_H__ +#define __HIF_PDMA_H__ + +#include + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#define NUM_OF_WFDMA1_TX_RING 0 +#define NUM_OF_WFDMA1_RX_RING 0 + +#if (CFG_SUPPORT_CONNAC2X == 1) +#undef NUM_OF_WFDMA1_TX_RING +#define NUM_OF_WFDMA1_TX_RING (CONFIG_NUM_OF_WFDMA_TX_RING) +#undef NUM_OF_WFDMA1_RX_RING +#define NUM_OF_WFDMA1_RX_RING (CONFIG_NUM_OF_WFDMA_RX_RING) +#endif /* CFG_SUPPORT_CONNAC2X == 1 */ + +#define NUM_OF_TX_RING (4+NUM_OF_WFDMA1_TX_RING) +#define NUM_OF_RX_RING (2+NUM_OF_WFDMA1_RX_RING) + +#if (CFG_SUPPORT_CONNAC2X_2x2 == 1) +#define TX_RING_SIZE 1024 +#define RX_RING_SIZE 1024 /* Max Rx ring size */ +/* Data Rx ring */ +#define RX_RING0_SIZE 1024 +/* Event/MSDU_report Rx ring */ +#define RX_RING1_SIZE 16 +#else +#ifdef CONNAC2X2 +#define TX_RING_SIZE 512 +#define RX_RING_SIZE 512 /* Max Rx ring size */ +/* Data Rx ring */ +#define RX_RING0_SIZE 512 +#else +#define TX_RING_SIZE 256 +#define RX_RING_SIZE 256 /* Max Rx ring size */ +/* Data Rx ring */ +#define RX_RING0_SIZE 256 +#endif /* CONNAC2X2 */ +/* Event/MSDU_report Rx ring */ +#define RX_RING1_SIZE 16 +#endif + +/* TXD_SIZE = TxD + TxInfo */ +#define TXD_SIZE 16 +#define RXD_SIZE 16 + +#define RX_BUFFER_AGGRESIZE 3840 +#define RX_BUFFER_NORMSIZE 3840 +#define TX_BUFFER_NORMSIZE 3840 + +#define HIF_TX_PREALLOC_DATA_BUFFER 1 + +#define HIF_NUM_OF_QM_RX_PKT_NUM 2048 +#define HIF_IST_LOOP_COUNT 32 +/* Min msdu count to trigger Tx during INT polling state */ +#define HIF_IST_TX_THRESHOLD 1 + +#define HIF_TX_BUFF_COUNT_TC0 4096 +#define HIF_TX_BUFF_COUNT_TC1 4096 +#define HIF_TX_BUFF_COUNT_TC2 4096 +#define HIF_TX_BUFF_COUNT_TC3 4096 +#define HIF_TX_BUFF_COUNT_TC4 (TX_RING_SIZE - 1) +#define HIF_TX_BUFF_COUNT_TC5 4096 + +/* enable/disable TX resource control */ +#define HIF_TX_RESOURCE_CTRL 1 +/* enable/disable TX resource control PLE */ +#define HIF_TX_RESOURCE_CTRL_PLE 0 + + +#define HIF_TX_PAGE_SIZE_IN_POWER_OF_2 11 +/* in unit of bytes */ +#define HIF_TX_PAGE_SIZE 2048 + +#define HIF_EXTRA_IO_BUFFER_SIZE 0 + +#define HIF_TX_COALESCING_BUFFER_SIZE (TX_BUFFER_NORMSIZE) +#define HIF_RX_COALESCING_BUFFER_SIZE (RX_BUFFER_AGGRESIZE) + +#define HIF_CR4_FWDL_SECTION_NUM 1 +#define HIF_IMG_DL_STATUS_PORT_IDX 1 + +#define HIF_TX_INIT_CMD_PORT TX_RING_FWDL_IDX_3 + +#ifdef CONNAC2X2 +#define HIF_TX_MSDU_TOKEN_NUM (TX_RING_SIZE * 3) +#else +#define HIF_TX_MSDU_TOKEN_NUM (TX_RING_SIZE * 2) +#endif + +#define HIF_TX_PAYLOAD_LENGTH 72 + +#define HIF_MSDU_REPORT_RETURN_TIMEOUT 10 /* sec */ +#define HIF_SER_TIMEOUT 10000 /* msec */ + +#define MT_RINGREG_DIFF 0x10 +#define MT_RINGREG_EXT_DIFF 0x04 + +#define MT_TX_RING_BASE WPDMA_TX_RING0_CTRL0 +#define MT_TX_RING_PTR WPDMA_TX_RING0_CTRL0 +#define MT_TX_RING_CNT WPDMA_TX_RING0_CTRL1 +#define MT_TX_RING_CIDX WPDMA_TX_RING0_CTRL2 +#define MT_TX_RING_DIDX WPDMA_TX_RING0_CTRL3 + +#define MT_RX_RING_BASE WPDMA_RX_RING0_CTRL0 +#define MT_RX_RING_PTR WPDMA_RX_RING0_CTRL0 +#define MT_RX_RING_CNT WPDMA_RX_RING0_CTRL1 +#define MT_RX_RING_CIDX WPDMA_RX_RING0_CTRL2 +#define MT_RX_RING_DIDX WPDMA_RX_RING0_CTRL3 + +#define DMA_LOWER_32BITS_MASK 0x00000000FFFFFFFF +#define DMA_HIGHER_4BITS_MASK 0x0000000F +#define DMA_BITS_OFFSET 32 + +#define DMA_DONE_WAITING_TIME 10 +#define DMA_DONE_WAITING_COUNT 100 + +#define MT_TX_RING_BASE_EXT WPDMA_TX_RING0_BASE_PTR_EXT +#define MT_RX_RING_BASE_EXT WPDMA_RX_RING0_BASE_PTR_EXT + +#define PDMA_DUMMY_RESET_VALUE 0x0F +#define PDMA_DUMMY_MAGIC_NUM 0x13 + +#define TXD_DW1_RMVL BIT(10) +#define TXD_DW1_VLAN BIT(11) +#define TXD_DW1_ETYP BIT(12) +#define TXD_DW1_AMSDU_C BIT(20) + +#define HIF_DEADFEED_VALUE 0xdeadfeed + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +#define INC_RING_INDEX(_idx, _RingSize) \ +{ \ + (_idx) = (_idx+1) % (_RingSize); \ +} + +#define RTMP_IO_READ32(_A, _R, _pV) \ +{ \ + (*(_pV) = readl((void *)((_A)->CSRBaseAddress + (_R)))); \ +} + +#define RTMP_IO_WRITE32(_A, _R, _V) \ +{ \ + writel(_V, (void *)((_A)->CSRBaseAddress + (_R))); \ +} + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +enum ENUM_TX_RING_IDX { + TX_RING_DATA0_IDX_0 = 0, + TX_RING_DATA1_IDX_1, + TX_RING_CMD_IDX_2, + TX_RING_FWDL_IDX_3, + TX_RING_WA_CMD_IDX_4, +}; + +enum ENUM_RX_RING_IDX { + RX_RING_DATA_IDX_0 = 0, /*Rx Data */ + RX_RING_EVT_IDX_1, + WFDMA0_RX_RING_IDX_2, /* Band0 TxFreeDoneEvent */ + WFDMA0_RX_RING_IDX_3, /* Band1 TxFreeDoneEvent */ + WFDMA1_RX_RING_IDX_0, /* WM Event */ + WFDMA1_RX_RING_IDX_1, /*WA Band 0 Event*/ + WFDMA1_RX_RING_IDX_2, /*WA Band 1 Event*/ +}; + +/* ============================================================================ + * PCI/RBUS TX / RX Frame Descriptors format + * + * Memory Layout + * + * 1. Tx Descriptor + * TxD (12 bytes) + TXINFO (4 bytes) + * 2. Packet Buffer + * TXWI + 802.11 + * 31 0 + * +--------------------------------------------------------------------------+ + * | SDP0[31:0] | + * +-+--+---------------------+-+--+------------------------------------------+ + * |D |L0| SDL0[13:0] |B|L1| SDL1[13:0] | + * +-+--+---------------------+-+--+------------------------------------------+ + * | SDP1[31:0] | + * +--------------------------------------------------------------------------+ + * | TX / RX INFO | + * +--------------------------------------------------------------------------+ + * ========================================================================= + */ +/* + * TX descriptor format for Tx Data/Mgmt Rings + */ +struct TXD_STRUCT { + /* Word 0 */ + uint32_t SDPtr0; + + /* Word 1 */ + uint32_t SDLen1:14; + uint32_t LastSec1:1; + uint32_t Burst:1; + uint32_t SDLen0:14; + uint32_t LastSec0:1; + uint32_t DMADONE:1; + + /*Word2 */ + uint32_t SDPtr1; + + /*Word3 */ + uint16_t SDPtr0Ext; + uint16_t SDPtr1Ext; +}; + +/* + * Rx descriptor format for Rx Rings + */ +struct RXD_STRUCT { + /* Word 0 */ + uint32_t SDPtr0; + + /* Word 1 */ + uint32_t SDLen1:14; + uint32_t LastSec1:1; + uint32_t Burst:1; + uint32_t SDLen0:14; + uint32_t LastSec0:1; + uint32_t DMADONE:1; + + /* Word 2 */ + uint32_t SDPtr1; + + /* Word 3 */ + uint32_t RXINFO; +}; + +/* + * Data buffer for DMA operation, the buffer must be contiguous + * physical memory Both DMA to / from CPU use the same structure. + */ +struct RTMP_DMABUF { + unsigned long AllocSize; + void *AllocVa; /* TxBuf virtual address */ + phys_addr_t AllocPa; /* TxBuf physical address */ +}; + +/* + * Control block (Descriptor) for all ring descriptor DMA operation, + * buffer must be contiguous physical memory. NDIS_PACKET stored the + * binding Rx packet descriptor which won't be released, driver has to + * wait until upper layer return the packet before giveing up this rx + * ring descriptor to ASIC. NDIS_BUFFER is assocaited pair to describe + * the packet buffer. For Tx, NDIS_PACKET stored the tx packet descriptor + * which driver should ACK upper layer when the tx is physically done or + * failed. + */ +struct RTMP_DMACB { + unsigned long AllocSize; /* Control block size */ + void *AllocVa; /* Control block virtual address */ + phys_addr_t AllocPa; /* Control block physical address */ + void *pPacket; + void *pBuffer; + phys_addr_t PacketPa; + struct RTMP_DMABUF DmaBuf; /* Associated DMA buffer structure */ + struct MSDU_TOKEN_ENTRY *prToken; +}; + +struct RTMP_TX_RING { + struct RTMP_DMACB Cell[TX_RING_SIZE]; + uint32_t TxCpuIdx; + uint32_t TxDmaIdx; + uint32_t u4BufSize; + uint32_t TxSwUsedIdx; + uint32_t u4UsedCnt; + uint32_t hw_desc_base; + uint32_t hw_desc_base_ext; + uint32_t hw_cidx_addr; + uint32_t hw_didx_addr; + uint32_t hw_cnt_addr; +}; + +struct RTMP_RX_RING { + struct RTMP_DMACB Cell[RX_RING_SIZE]; + uint32_t RxCpuIdx; + uint32_t RxDmaIdx; + uint32_t u4BufSize; + uint32_t u4RingSize; + u_int8_t fgRxSegPkt; + uint32_t hw_desc_base; + uint32_t hw_desc_base_ext; + uint32_t hw_cidx_addr; + uint32_t hw_didx_addr; + uint32_t hw_cnt_addr; + bool fgIsDumpLog; + uint32_t u4PendingCnt; +}; + +struct PCIE_CHIP_CR_MAPPING { + uint32_t u4ChipAddr; + uint32_t u4BusAddr; + uint32_t u4Range; +}; + +struct MSDU_TOKEN_ENTRY { + uint32_t u4Token; + u_int8_t fgInUsed; + struct timeval rTs; /* token tx timestamp */ + uint32_t u4CpuIdx; /* tx ring cell index */ + struct MSDU_INFO *prMsduInfo; + void *prPacket; + phys_addr_t rDmaAddr; + uint32_t u4DmaLength; + phys_addr_t rPktDmaAddr; + uint32_t u4PktDmaLength; + uint16_t u2Port; /* tx ring number */ + uint8_t ucWlanIndex; +}; + +struct MSDU_TOKEN_INFO { + uint32_t u4UsedCnt; + struct MSDU_TOKEN_ENTRY *aprTokenStack[HIF_TX_MSDU_TOKEN_NUM]; + spinlock_t rTokenLock; + struct MSDU_TOKEN_ENTRY arToken[HIF_TX_MSDU_TOKEN_NUM]; +}; + +struct TX_CMD_REQ { + struct CMD_INFO *prCmdInfo; + uint8_t ucTC; + struct list_head list; +}; + +struct TX_DATA_REQ { + struct MSDU_INFO *prMsduInfo; + struct list_head list; +}; + +struct AMSDU_MAC_TX_DESC { + uint16_t u2TxByteCount; + uint16_t u2DW0; + uint32_t u4DW1; + uint32_t u4DW2:31; + uint32_t u4FR:1; + uint32_t u4DW3; + uint32_t u4DW4; + uint32_t u4DW5_1:9; + uint32_t u4TXS:2; + uint32_t u4DW5_2:21; + uint32_t u4DW6; + uint32_t u4DW7; +}; + + +struct ERR_RECOVERY_CTRL_T { + uint8_t eErrRecovState; + uint32_t u4Status; +}; + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +void halHifRst(struct GLUE_INFO *prGlueInfo); +bool halWpdmaAllocRing(struct GLUE_INFO *prGlueInfo, bool fgAllocMem); +void halWpdmaFreeRing(struct GLUE_INFO *prGlueInfo); +void halWpdmaInitRing(struct GLUE_INFO *prGlueInfo, bool fgResetHif); +void halWpdmaInitTxRing(IN struct GLUE_INFO *prGlueInfo); +void halWpdmaInitRxRing(IN struct GLUE_INFO *prGlueInfo); +void halWpdmaProcessCmdDmaDone(IN struct GLUE_INFO *prGlueInfo, + IN uint16_t u2Port); +void halWpdmaProcessDataDmaDone(IN struct GLUE_INFO *prGlueInfo, + IN uint16_t u2Port); +uint32_t halWpdmaGetRxDmaDoneCnt(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRingNum); +void halInitMsduTokenInfo(IN struct ADAPTER *prAdapter); +void halUninitMsduTokenInfo(IN struct ADAPTER *prAdapter); +uint32_t halGetMsduTokenFreeCnt(IN struct ADAPTER *prAdapter); +struct MSDU_TOKEN_ENTRY *halGetMsduTokenEntry(IN struct ADAPTER *prAdapter, + uint32_t u4TokenNum); +struct MSDU_TOKEN_ENTRY *halAcquireMsduToken(IN struct ADAPTER *prAdapter); +void halReturnMsduToken(IN struct ADAPTER *prAdapter, uint32_t u4TokenNum); +void halReturnTimeoutMsduToken(struct ADAPTER *prAdapter); +void halTxUpdateCutThroughDesc(struct GLUE_INFO *prGlueInfo, + struct MSDU_INFO *prMsduInfo, + struct MSDU_TOKEN_ENTRY *prFillToken, + struct MSDU_TOKEN_ENTRY *prDataToken, + uint32_t u4Idx, bool fgIsLast); +u_int8_t halIsStaticMapBusAddr(IN struct ADAPTER *prAdapter, + IN uint32_t u4Addr); +u_int8_t halChipToStaticMapBusAddr(IN struct GLUE_INFO *prGlueInfo, + IN uint32_t u4ChipAddr, + OUT uint32_t *pu4BusAddr); +u_int8_t halGetDynamicMapReg(IN struct GLUE_INFO *prGlueInfo, + IN uint32_t u4ChipAddr, + OUT uint32_t *pu4Value); +u_int8_t halSetDynamicMapReg(IN struct GLUE_INFO *prGlueInfo, + IN uint32_t u4ChipAddr, + IN uint32_t u4Value); +void halConnacWpdmaConfig(struct GLUE_INFO *prGlueInfo, u_int8_t enable); +void halConnacEnableInterrupt(IN struct ADAPTER *prAdapter); +enum ENUM_CMD_TX_RESULT halWpdmaWriteCmd(struct GLUE_INFO *prGlueInfo, + struct CMD_INFO *prCmdInfo, + uint8_t ucTC); +bool halWpdmaWriteMsdu(struct GLUE_INFO *prGlueInfo, + struct MSDU_INFO *prMsduInfo, + struct list_head *prCurList); +bool halWpdmaWriteAmsdu(struct GLUE_INFO *prGlueInfo, + struct list_head *prList, + uint32_t u4Num, uint16_t u2Size); +void halWpdamFreeMsdu(struct GLUE_INFO *prGlueInfo, + struct MSDU_INFO *prMsduInfo, + bool fgSetEvent); + +bool kalDevReadData(struct GLUE_INFO *prGlueInfo, uint16_t u2Port, + struct SW_RFB *prSwRfb); +bool kalDevKickCmd(struct GLUE_INFO *prGlueInfo); + +/* SER functions */ +void halSetDrvSer(struct ADAPTER *prAdapter); +#if KERNEL_VERSION(4, 15, 0) <= LINUX_VERSION_CODE +void halHwRecoveryTimeout(struct timer_list *timer); +#else +void halHwRecoveryTimeout(unsigned long arg); +#endif +void halHwRecoveryFromError(IN struct ADAPTER *prAdapter); + +/* Debug functions */ +int halTimeCompare(struct timeval *prTs1, struct timeval *prTs2); +void halShowPdmaInfo(IN struct ADAPTER *prAdapter); +bool halShowHostCsrInfo(IN struct ADAPTER *prAdapter); +void kalDumpTxRing(struct GLUE_INFO *prGlueInfo, + struct RTMP_TX_RING *prTxRing, + uint32_t u4Num, bool fgDumpContent); +void kalDumpRxRing(struct GLUE_INFO *prGlueInfo, + struct RTMP_RX_RING *prRxRing, + uint32_t u4Num, bool fgDumpContent); +void haldumpPhyInfo(struct ADAPTER *prAdapter); +int wf_ioremap_read(size_t addr, unsigned int *val); +int wf_ioremap_write(phys_addr_t addr, unsigned int val); +void halEnableSlpProt(struct GLUE_INFO *prGlueInfo); +void halDisableSlpProt(struct GLUE_INFO *prGlueInfo); +#endif /* HIF_PDMA_H__ */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/common/kal_pdma.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/common/kal_pdma.c new file mode 100644 index 0000000000000000000000000000000000000000..02bd4cf636e1632ce6520b67eedf2277ec708c42 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/common/kal_pdma.c @@ -0,0 +1,1007 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/****************************************************************************** + *[File] kal_pdma.c + *[Version] v1.0 + *[Revision Date] 2010-03-01 + *[Author] + *[Description] + * The program provides PCIE HIF driver + *[Copyright] + * Copyright (C) 2010 MediaTek Incorporation. All Rights Reserved. + ******************************************************************************/ + + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +#include "gl_os.h" + +#include "hif_pdma.h" + +#include "precomp.h" + +#include +#ifndef CONFIG_X86 +#include +#endif + +#include "mt66xx_reg.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +static enum ENUM_CMD_TX_RESULT kalDevWriteCmdByQueue( + struct GLUE_INFO *prGlueInfo, struct CMD_INFO *prCmdInfo, + uint8_t ucTC); +static bool kalDevWriteDataByQueue(struct GLUE_INFO *prGlueInfo, + struct MSDU_INFO *prMsduInfo); +static bool kalDevKickMsduData(struct GLUE_INFO *prGlueInfo); +static bool kalDevKickAmsduData(struct GLUE_INFO *prGlueInfo); + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Check connsys is dead or not + * + * \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. + * \param[in] u4Register Register address + * \param[in] pu4Value Pointer to read value + * + * \retval TRUE connsys is dead + * \retval FALSE connsys is alive + */ +/*----------------------------------------------------------------------------*/ +static inline bool kalIsChipDead(struct GLUE_INFO *prGlueInfo, + uint32_t u4Register, uint32_t *pu4Value) +{ + struct GL_HIF_INFO *prHifInfo = NULL; + uint32_t u4Value; + uint32_t u4BusAddr; + + prHifInfo = &prGlueInfo->rHifInfo; + +#if (CFG_ENABLE_HOST_BUS_TIMEOUT == 1) + if (*pu4Value == 0xdead0001) { + DBGLOG(HAL, ERROR, "Host bus hang timeout, CR[0x%08x]\n", + u4Register); + return true; + } +#endif + + if (*pu4Value != HIF_DEADFEED_VALUE) + return false; + + if (!halChipToStaticMapBusAddr(prGlueInfo, CONN_CFG_CHIP_ID_ADDR, + &u4BusAddr)) { + DBGLOG(HAL, ERROR, "Not exist CR read[0x%08x]\n", u4Register); + return false; + } + + RTMP_IO_READ32(prHifInfo, u4BusAddr, &u4Value); + + return u4Value == HIF_DEADFEED_VALUE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Read a 32-bit device register + * + * \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. + * \param[in] u4Register Register offset + * \param[in] pu4Value Pointer to variable used to store read value + * + * \retval TRUE operation success + * \retval FALSE operation fail + */ +/*----------------------------------------------------------------------------*/ +u_int8_t kalDevRegRead(IN struct GLUE_INFO *prGlueInfo, + IN uint32_t u4Register, OUT uint32_t *pu4Value) +{ + struct GL_HIF_INFO *prHifInfo = NULL; + struct ADAPTER *prAdapter = NULL; + struct BUS_INFO *prBusInfo = NULL; + uint32_t u4BusAddr = u4Register; + + ASSERT(prGlueInfo); + ASSERT(pu4Value); + + prHifInfo = &prGlueInfo->rHifInfo; + prAdapter = prGlueInfo->prAdapter; + ASSERT(prAdapter); + prBusInfo = prAdapter->chip_info->bus_info; + + if (!prHifInfo->fgIsDumpLog && prBusInfo->isValidRegAccess && + !prBusInfo->isValidRegAccess(prAdapter, u4Register)) { + /* Don't printk log when resetting */ + if (!wlanIsChipNoAck(prAdapter)) { + DBGLOG(HAL, ERROR, + "Invalid access! Get CR[0x%08x/0x%08x] value[0x%08x]\n", + u4Register, u4BusAddr, *pu4Value); + } + *pu4Value = HIF_DEADFEED_VALUE; + return FALSE; + } + + /* Static mapping */ + if (halChipToStaticMapBusAddr(prGlueInfo, u4Register, &u4BusAddr)) { + RTMP_IO_READ32(prHifInfo, u4BusAddr, pu4Value); + if (kalIsChipDead(prGlueInfo, u4Register, pu4Value)) { + /* Don't printk log when resetting */ + if (!wlanIsChipNoAck(prAdapter)) { + DBGLOG(HAL, ERROR, + "Read register is deadfeed\n"); + GL_RESET_TRIGGER(prAdapter, + RST_FLAG_CHIP_RESET); + } + return FALSE; + } + } else { + DBGLOG(HAL, ERROR, "Not exist CR read[0x%08x]\n", u4Register); + } + + return TRUE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Write a 32-bit device register + * + * \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. + * \param[in] u4Register Register offset + * \param[in] u4Value Value to be written + * + * \retval TRUE operation success + * \retval FALSE operation fail + */ +/*----------------------------------------------------------------------------*/ +u_int8_t kalDevRegWrite(IN struct GLUE_INFO *prGlueInfo, + IN uint32_t u4Register, IN uint32_t u4Value) +{ + struct GL_HIF_INFO *prHifInfo = NULL; + struct ADAPTER *prAdapter = NULL; + struct BUS_INFO *prBusInfo = NULL; + uint32_t u4BusAddr = u4Register; + + ASSERT(prGlueInfo); + + prHifInfo = &prGlueInfo->rHifInfo; + prAdapter = prGlueInfo->prAdapter; + ASSERT(prAdapter); + prBusInfo = prAdapter->chip_info->bus_info; + + if (!prHifInfo->fgIsDumpLog && prBusInfo->isValidRegAccess && + !prBusInfo->isValidRegAccess(prAdapter, u4Register)) { + /* Don't printk log when resetting */ + if (!wlanIsChipNoAck(prAdapter)) { + DBGLOG(HAL, ERROR, + "Invalid access! Set CR[0x%08x/0x%08x] value[0x%08x]\n", + u4Register, u4BusAddr, u4Value); + } + return FALSE; + } + + /* Static mapping */ + if (halChipToStaticMapBusAddr(prGlueInfo, u4Register, &u4BusAddr)) { + RTMP_IO_WRITE32(prHifInfo, u4BusAddr, u4Value); + } else { + DBGLOG(HAL, ERROR, "Not exist CR write[0x%08x] value[0x%08x]\n", + u4Register, u4Value); + } + + prHifInfo->u4HifCnt++; + + return TRUE; +} + +static bool kalWaitRxDmaDone(struct GLUE_INFO *prGlueInfo, + struct RTMP_RX_RING *prRxRing, + struct RXD_STRUCT *pRxD, + uint16_t u2Port) +{ + uint32_t u4Count = 0; + + for (u4Count = 0; pRxD->DMADONE == 0; u4Count++) { + kalDevRegRead(prGlueInfo, prRxRing->hw_didx_addr, + &prRxRing->RxDmaIdx); + if (u4Count > DMA_DONE_WAITING_COUNT) { + DBGLOG(HAL, INFO, + "Rx DMA done P[%u] DMA[%u] CPU[%u]\n", + u2Port, prRxRing->RxDmaIdx, prRxRing->RxCpuIdx); + return false; + } + + kalMdelay(DMA_DONE_WAITING_TIME); + } + return true; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Read device I/O port + * + * \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. + * \param[in] u2Port I/O port offset + * \param[in] u2Len Length to be read + * \param[out] pucBuf Pointer to read buffer + * \param[in] u2ValidOutBufSize Length of the buffer valid to be accessed + * + * \retval TRUE operation success + * \retval FALSE operation fail + */ +/*----------------------------------------------------------------------------*/ +u_int8_t kalDevPortRead(IN struct GLUE_INFO *prGlueInfo, + IN uint16_t u2Port, IN uint32_t u4Len, + OUT uint8_t *pucBuf, IN uint32_t u4ValidOutBufSize) +{ + struct ADAPTER *prAdapter = NULL; + struct GL_HIF_INFO *prHifInfo = NULL; + struct HIF_MEM_OPS *prMemOps; + struct RTMP_RX_RING *prRxRing; + struct RTMP_DMACB *pRxCell; + struct RXD_STRUCT *pRxD; + struct RTMP_DMABUF *prDmaBuf; + u_int8_t fgRet = TRUE; + uint32_t u4CpuIdx = 0; + + ASSERT(prGlueInfo); + ASSERT(pucBuf); + ASSERT(u4Len <= u4ValidOutBufSize); + + prAdapter = prGlueInfo->prAdapter; + prHifInfo = &prGlueInfo->rHifInfo; + prMemOps = &prHifInfo->rMemOps; + prRxRing = &prHifInfo->RxRing[u2Port]; + + kalDevRegRead(prGlueInfo, prRxRing->hw_cidx_addr, &prRxRing->RxCpuIdx); + u4CpuIdx = prRxRing->RxCpuIdx; + INC_RING_INDEX(u4CpuIdx, prRxRing->u4RingSize); + + pRxCell = &prRxRing->Cell[u4CpuIdx]; + pRxD = (struct RXD_STRUCT *)pRxCell->AllocVa; + + if (halWpdmaGetRxDmaDoneCnt(prGlueInfo, u2Port) == 0) + return FALSE; + + if (!kalWaitRxDmaDone(prGlueInfo, prRxRing, pRxD, u2Port)) { + if (!prRxRing->fgIsDumpLog) { + DBGLOG(HAL, ERROR, "RX Done bit not ready(PortRead)\n"); + } + prRxRing->fgIsDumpLog = true; + return FALSE; + } + + if (pRxD->LastSec0 == 0 || prRxRing->fgRxSegPkt) { + /* Rx segmented packet */ + DBGLOG(HAL, WARN, + "Skip Rx segmented packet, SDL0[%u] LS0[%u]\n", + pRxD->SDLen0, pRxD->LastSec0); + if (pRxD->LastSec0 == 1) { + /* Last segmented packet */ + prRxRing->fgRxSegPkt = FALSE; + } else { + /* Segmented packet */ + prRxRing->fgRxSegPkt = TRUE; + } + + fgRet = FALSE; + goto skip; + } + + if (pRxD->SDLen0 > u4Len) { + DBGLOG(HAL, WARN, + "Skip Rx packet, SDL0[%u] > SwRfb max len[%u]\n", + pRxD->SDLen0, u4Len); + goto skip; + } + + prDmaBuf = &pRxCell->DmaBuf; + if (prMemOps->copyEvent && + !prMemOps->copyEvent(prHifInfo, pRxCell, pRxD, + prDmaBuf, pucBuf, u4Len)) { + ASSERT(0); + return FALSE; + } + + pRxD->SDPtr0 = (uint64_t)prDmaBuf->AllocPa & DMA_LOWER_32BITS_MASK; +#ifdef CONFIG_PHYS_ADDR_T_64BIT + pRxD->SDPtr1 = ((uint64_t)prDmaBuf->AllocPa >> DMA_BITS_OFFSET) & + DMA_HIGHER_4BITS_MASK; +#else + pRxD->SDPtr1 = 0; +#endif +skip: + pRxD->SDLen0 = prRxRing->u4BufSize; + pRxD->DMADONE = 0; + + prRxRing->RxCpuIdx = u4CpuIdx; + kalDevRegWrite(prGlueInfo, prRxRing->hw_cidx_addr, prRxRing->RxCpuIdx); + prRxRing->fgIsDumpLog = false; + + GLUE_INC_REF_CNT(prGlueInfo->prAdapter->rHifStats.u4EventRxCount); + + return fgRet; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Write device I/O port + * + * \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. + * \param[in] u2Port I/O port offset + * \param[in] u2Len Length to be write + * \param[in] pucBuf Pointer to write buffer + * \param[in] u2ValidInBufSize Length of the buffer valid to be accessed + * + * \retval TRUE operation success + * \retval FALSE operation fail + */ +/*----------------------------------------------------------------------------*/ +u_int8_t +kalDevPortWrite(IN struct GLUE_INFO *prGlueInfo, + IN uint16_t u2Port, IN uint32_t u4Len, IN uint8_t *pucBuf, + IN uint32_t u4ValidInBufSize) +{ + struct GL_HIF_INFO *prHifInfo = NULL; + struct HIF_MEM_OPS *prMemOps; + struct RTMP_TX_RING *prTxRing; + struct RTMP_DMACB *pTxCell; + struct TXD_STRUCT *pTxD; + void *pucDst = NULL; + + ASSERT(prGlueInfo); + ASSERT(pucBuf); + ASSERT(u4Len <= u4ValidInBufSize); + + prHifInfo = &prGlueInfo->rHifInfo; + prMemOps = &prHifInfo->rMemOps; + prTxRing = &prHifInfo->TxRing[u2Port]; + + if (prMemOps->allocRuntimeMem) + pucDst = prMemOps->allocRuntimeMem(u4Len); + + kalDevRegRead(prGlueInfo, prTxRing->hw_cidx_addr, &prTxRing->TxCpuIdx); + if (prTxRing->TxCpuIdx >= TX_RING_SIZE) { + DBGLOG(HAL, ERROR, "Error TxCpuIdx[%u]\n", prTxRing->TxCpuIdx); + if (prMemOps->freeBuf) + prMemOps->freeBuf(pucDst, u4Len); + return FALSE; + } + + pTxCell = &prTxRing->Cell[prTxRing->TxCpuIdx]; + pTxD = (struct TXD_STRUCT *)pTxCell->AllocVa; + + pTxCell->pPacket = NULL; + pTxCell->pBuffer = pucDst; + + if (prMemOps->copyCmd && + !prMemOps->copyCmd(prHifInfo, pTxCell, pucDst, + pucBuf, u4Len, NULL, 0)) { + if (prMemOps->freeBuf) + prMemOps->freeBuf(pucDst, u4Len); + ASSERT(0); + return FALSE; + } + + pTxD->LastSec0 = 1; + pTxD->LastSec1 = 0; + pTxD->SDLen0 = u4Len; + pTxD->SDLen1 = 0; + pTxD->SDPtr0 = (uint64_t)pTxCell->PacketPa & DMA_LOWER_32BITS_MASK; +#ifdef CONFIG_PHYS_ADDR_T_64BIT + pTxD->SDPtr0Ext = ((uint64_t)pTxCell->PacketPa >> DMA_BITS_OFFSET) & + DMA_HIGHER_4BITS_MASK; +#else + pTxD->SDPtr0Ext = 0; +#endif + pTxD->SDPtr1 = 0; + pTxD->Burst = 0; + pTxD->DMADONE = 0; + + /* Increase TX_CTX_IDX, but write to register later. */ + INC_RING_INDEX(prTxRing->TxCpuIdx, TX_RING_SIZE); + + prTxRing->u4UsedCnt++; + + kalDevRegWrite(prGlueInfo, prTxRing->hw_cidx_addr, prTxRing->TxCpuIdx); + + GLUE_INC_REF_CNT(prGlueInfo->prAdapter->rHifStats.u4CmdTxCount); + + return TRUE; +} + +void kalDevReadIntStatus(IN struct ADAPTER *prAdapter, + OUT uint32_t *pu4IntStatus) +{ + uint32_t u4RegValue = 0; + struct GL_HIF_INFO *prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + + *pu4IntStatus = 0; + + HAL_MCR_RD(prAdapter, WPDMA_INT_STA, &u4RegValue); + + if (HAL_IS_RX_DONE_INTR(u4RegValue)) + *pu4IntStatus |= WHISR_RX0_DONE_INT; + + if (HAL_IS_TX_DONE_INTR(u4RegValue)) + *pu4IntStatus |= WHISR_TX_DONE_INT; + + if (u4RegValue & CONNAC_MCU_SW_INT) + *pu4IntStatus |= WHISR_D2H_SW_INT; + + prHifInfo->u4IntStatus = u4RegValue; + + /* clear interrupt */ + HAL_MCR_WR(prAdapter, WPDMA_INT_STA, u4RegValue); + +} + +enum ENUM_CMD_TX_RESULT kalDevWriteCmd(IN struct GLUE_INFO *prGlueInfo, + IN struct CMD_INFO *prCmdInfo, IN uint8_t ucTC) +{ + struct GL_HIF_INFO *prHifInfo = NULL; + + ASSERT(prGlueInfo); + prHifInfo = &prGlueInfo->rHifInfo; + + if (nicSerIsTxStop(prGlueInfo->prAdapter)) + return kalDevWriteCmdByQueue(prGlueInfo, prCmdInfo, ucTC); + + return halWpdmaWriteCmd(prGlueInfo, prCmdInfo, ucTC); +} + +static enum ENUM_CMD_TX_RESULT kalDevWriteCmdByQueue( + struct GLUE_INFO *prGlueInfo, struct CMD_INFO *prCmdInfo, + uint8_t ucTC) +{ + struct GL_HIF_INFO *prHifInfo = NULL; + struct TX_CMD_REQ *prTxReq; + + ASSERT(prGlueInfo); + prHifInfo = &prGlueInfo->rHifInfo; + prTxReq = kalMemAlloc(sizeof(struct TX_CMD_REQ), PHY_MEM_TYPE); + + if (prTxReq == NULL) { + DBGLOG(HAL, ERROR, "kmalloc() TX_CMD_REQ error\n"); + halWpdmaWriteCmd(prGlueInfo, prCmdInfo, ucTC); + return CMD_TX_RESULT_FAILED; + } + + prTxReq->prCmdInfo = prCmdInfo; + prTxReq->ucTC = ucTC; + list_add_tail(&prTxReq->list, &prHifInfo->rTxCmdQ); + + return CMD_TX_RESULT_QUEUED; +} + +bool kalDevKickCmd(IN struct GLUE_INFO *prGlueInfo) +{ + struct GL_HIF_INFO *prHifInfo = NULL; + struct list_head *prCur, *prNext; + struct TX_CMD_REQ *prTxReq; + enum ENUM_CMD_TX_RESULT ret; + + ASSERT(prGlueInfo); + prHifInfo = &prGlueInfo->rHifInfo; + + list_for_each_safe(prCur, prNext, &prHifInfo->rTxCmdQ) { + prTxReq = list_entry(prCur, struct TX_CMD_REQ, list); + if (prTxReq->prCmdInfo) { + ret = halWpdmaWriteCmd(prGlueInfo, + prTxReq->prCmdInfo, prTxReq->ucTC); + if (ret == CMD_TX_RESULT_SUCCESS) { + if (prTxReq->prCmdInfo->pfHifTxCmdDoneCb) + prTxReq->prCmdInfo->pfHifTxCmdDoneCb( + prGlueInfo->prAdapter, + prTxReq->prCmdInfo); + } else { + DBGLOG(HAL, ERROR, "ret: %d\n", ret); + } + } + list_del(prCur); + kfree(prTxReq); + } + + return true; +} + +static uint8_t kalGetSwAmsduNum(struct GLUE_INFO *prGlueInfo, + struct MSDU_INFO *prMsduInfo) +{ + struct ADAPTER *prAdapter; + struct STA_RECORD *prStaRec; + uint8_t ucTid, ucStaRecIndex; + struct TX_DESC_OPS_T *prTxDescOps; + + ASSERT(prGlueInfo); + ASSERT(prMsduInfo); + + prAdapter = prGlueInfo->prAdapter; + prTxDescOps = prAdapter->chip_info->prTxDescOps; + + ucTid = prMsduInfo->ucUserPriority; + ucStaRecIndex = prMsduInfo->ucStaRecIndex; + if (ucStaRecIndex >= CFG_STA_REC_NUM || ucTid >= TX_DESC_TID_NUM) + return 0; + + prStaRec = cnmGetStaRecByIndex(prAdapter, ucStaRecIndex); + if (!prStaRec || !(prStaRec->ucAmsduEnBitmap & BIT(ucTid))) + return 0; + + return prStaRec->ucMaxMpduCount; +} + +u_int8_t kalDevWriteData(IN struct GLUE_INFO *prGlueInfo, + IN struct MSDU_INFO *prMsduInfo) +{ + struct GL_HIF_INFO *prHifInfo = NULL; + struct mt66xx_chip_info *prChipInfo; + + ASSERT(prGlueInfo); + + prHifInfo = &prGlueInfo->rHifInfo; + prChipInfo = prGlueInfo->prAdapter->chip_info; + + if (nicSerIsTxStop(prGlueInfo->prAdapter) || + (prChipInfo->ucMaxSwAmsduNum > 1 && + kalGetSwAmsduNum(prGlueInfo, prMsduInfo) > 1)) + return kalDevWriteDataByQueue(prGlueInfo, prMsduInfo); + + return halWpdmaWriteMsdu(prGlueInfo, prMsduInfo, NULL); +} + +static bool kalDevWriteDataByQueue(IN struct GLUE_INFO *prGlueInfo, + IN struct MSDU_INFO *prMsduInfo) +{ + struct GL_HIF_INFO *prHifInfo = NULL; + struct TX_DATA_REQ *prTxReq; + + ASSERT(prGlueInfo); + prHifInfo = &prGlueInfo->rHifInfo; + + prTxReq = &prMsduInfo->rTxReq; + prTxReq->prMsduInfo = prMsduInfo; + list_add_tail(&prTxReq->list, &prHifInfo->rTxDataQ); + prHifInfo->u4TxDataQLen++; + + return true; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Kick Tx data to device + * + * \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. + * + * \retval TRUE operation success + * \retval FALSE operation fail + */ +/*----------------------------------------------------------------------------*/ +u_int8_t kalDevKickData(IN struct GLUE_INFO *prGlueInfo) +{ + struct mt66xx_chip_info *prChipInfo; + + ASSERT(prGlueInfo); + + prChipInfo = prGlueInfo->prAdapter->chip_info; + + if (prChipInfo->ucMaxSwAmsduNum > 1) + return kalDevKickAmsduData(prGlueInfo); + + return kalDevKickMsduData(prGlueInfo); +} + +static uint16_t kalGetPaddingSize(uint16_t u2TxByteCount) +{ + uint16_t u2Size = 0; + + if (u2TxByteCount & 3) + u2Size = 4 - (u2TxByteCount & 3); + return u2Size; +} + +static uint16_t kalGetMoreSizeForAmsdu(uint32_t u4TxdDW1) +{ + /* + * ETYPE=0/VLAN=0/RMVL=X PLlength = PL length + * ETYPE=0/VLAN=1/RMVL=1 PLlength = PL length - 4 + * ETYPE=0/VLAN=1/RMVL=0 PLlength = PL length + 6 + * ETYPE=1/VLAN=0/RMVL=X PLlength = PL length + 8 + * ETYPE=1/VLAN=1/RMVL=1 PLlength = PL length + 4 + * ETYPE=1/VLAN=1/RMVL=0 PLlength = PL length + 14 + */ + uint16_t u2Size = 0; + + if (u4TxdDW1 & TXD_DW1_ETYP) + u2Size += 8; + if (u4TxdDW1 & TXD_DW1_VLAN) { + if (u4TxdDW1 & TXD_DW1_RMVL) { + if (u2Size >= 4) + u2Size -= 4; + } else + u2Size += 6; + } + return u2Size; +} + +static bool kalDevKickMsduData(struct GLUE_INFO *prGlueInfo) +{ + struct GL_HIF_INFO *prHifInfo = NULL; + struct BUS_INFO *prBusInfo = NULL; + struct list_head *prCur, *prNext; + struct TX_DATA_REQ *prTxReq; + struct MSDU_INFO *prMsduInfo; + bool fgRet = true; + + ASSERT(prGlueInfo); + + prHifInfo = &prGlueInfo->rHifInfo; + prBusInfo = prGlueInfo->prAdapter->chip_info->bus_info; + + list_for_each_safe(prCur, prNext, &prHifInfo->rTxDataQ) { + prTxReq = list_entry(prCur, struct TX_DATA_REQ, list); + prMsduInfo = prTxReq->prMsduInfo; + if (!prMsduInfo || + !halWpdmaWriteMsdu(prGlueInfo, prMsduInfo, prCur)) { + fgRet = false; + break; + } + } + + return fgRet; +} + +static int kalAmsduTxDCmp(void *prPriv, struct list_head *prList1, + struct list_head *prList2) +{ + struct TX_DATA_REQ *prTxReq1, *prTxReq2; + struct sk_buff *prSkb1, *prSkb2; + struct AMSDU_MAC_TX_DESC *prTxD1, *prTxD2; + + prTxReq1 = list_entry(prList1, struct TX_DATA_REQ, list); + prTxReq2 = list_entry(prList2, struct TX_DATA_REQ, list); + prSkb1 = (struct sk_buff *)prTxReq1->prMsduInfo->prPacket; + prSkb2 = (struct sk_buff *)prTxReq2->prMsduInfo->prPacket; + prTxD1 = (struct AMSDU_MAC_TX_DESC *)prSkb1->data; + prTxD2 = (struct AMSDU_MAC_TX_DESC *)prSkb2->data; + + if (prTxD1->u2DW0 != prTxD2->u2DW0) + return prTxD2->u2DW0 - prTxD1->u2DW0; + + return prTxD1->u4DW1 - prTxD2->u4DW1; +} + +static bool kalIsAggregatedMsdu(struct GLUE_INFO *prGlueInfo, + struct MSDU_INFO *prMsduInfo) +{ + struct sk_buff *prSkb; + struct AMSDU_MAC_TX_DESC *prTxD; + + prSkb = (struct sk_buff *)prMsduInfo->prPacket; + prTxD = (struct AMSDU_MAC_TX_DESC *)prSkb->data; + + if (prTxD->u4FR || prTxD->u4TXS) + return false; + return true; +} + +static uint32_t kalGetNumOfAmsdu(struct GLUE_INFO *prGlueInfo, + struct list_head *prTarget, + struct list_head *prHead, + uint16_t *pu2Size) +{ + struct TX_DATA_REQ *prTxReq; + struct MSDU_INFO *prMsduInfo; + struct sk_buff *prSkb; + struct AMSDU_MAC_TX_DESC *prTxD; + struct STA_RECORD *prStaRec; + struct list_head *prCur; + uint16_t u2TotalSize, u2Size; + uint32_t u4Cnt = 1; + uint8_t ucStaRecIndex; + + prTxReq = list_entry(prTarget, struct TX_DATA_REQ, list); + prMsduInfo = prTxReq->prMsduInfo; + prSkb = (struct sk_buff *)prMsduInfo->prPacket; + prTxD = (struct AMSDU_MAC_TX_DESC *)prSkb->data; + + ucStaRecIndex = prMsduInfo->ucStaRecIndex; + prStaRec = cnmGetStaRecByIndex(prGlueInfo->prAdapter, ucStaRecIndex); + if (!prStaRec) + return 1; + + u2TotalSize = NIC_TX_DESC_LONG_FORMAT_LENGTH; + u2TotalSize += prMsduInfo->u2FrameLength; + u2TotalSize += kalGetMoreSizeForAmsdu(prTxD->u4DW1); + + for (prCur = prTarget->next; prCur != prHead; prCur = prCur->next) { + if (u4Cnt >= kalGetSwAmsduNum(prGlueInfo, prMsduInfo) || + kalAmsduTxDCmp((void *)prGlueInfo, prTarget, prCur)) + break; + + prTxReq = list_entry(prCur, struct TX_DATA_REQ, list); + prMsduInfo = prTxReq->prMsduInfo; + prSkb = (struct sk_buff *)prMsduInfo->prPacket; + prTxD = (struct AMSDU_MAC_TX_DESC *)prSkb->data; + + u2Size = prMsduInfo->u2FrameLength; + u2Size += kalGetMoreSizeForAmsdu(prTxD->u4DW1); + u2Size += kalGetPaddingSize(u2TotalSize); + if ((u2TotalSize + u2Size) > prStaRec->u4MaxMpduLen) + break; + + u2TotalSize += u2Size; + u4Cnt++; + } + + if (u2TotalSize < prStaRec->u4MinMpduLen) + return 1; + + *pu2Size = u2TotalSize; + return u4Cnt; +} + +static bool kalDevKickAmsduData(struct GLUE_INFO *prGlueInfo) +{ + struct GL_HIF_INFO *prHifInfo = NULL; + struct BUS_INFO *prBusInfo = NULL; + struct list_head *prHead, *prCur, *prNext; + struct TX_DATA_REQ *prTxReq; + struct MSDU_INFO *prMsduInfo; + uint32_t u4Num = 0, u4Idx; + uint16_t u2Size = 0; + bool fgRet = true; + + ASSERT(prGlueInfo); + + prHifInfo = &prGlueInfo->rHifInfo; + prBusInfo = prGlueInfo->prAdapter->chip_info->bus_info; + + prHead = &prHifInfo->rTxDataQ; + list_for_each_safe(prCur, prNext, prHead) { + prTxReq = list_entry(prCur, struct TX_DATA_REQ, list); + prMsduInfo = prTxReq->prMsduInfo; + if (!kalIsAggregatedMsdu(prGlueInfo, prMsduInfo)) { + if (!halWpdmaWriteMsdu(prGlueInfo, prMsduInfo, prCur)) + return false; + } + } + + list_sort((void *)prGlueInfo, prHead, kalAmsduTxDCmp); + + for (prCur = prHead->next; prCur != prHead; prCur = prNext) { + u4Num = kalGetNumOfAmsdu(prGlueInfo, prCur, prHead, &u2Size); + prNext = prCur->next; + if (u4Num > 1) { + for (u4Idx = 1; u4Idx < u4Num; u4Idx++) + prNext = prNext->next; + fgRet = halWpdmaWriteAmsdu(prGlueInfo, prCur, + u4Num, u2Size); + } else { + prTxReq = list_entry(prCur, struct TX_DATA_REQ, list); + prMsduInfo = prTxReq->prMsduInfo; + fgRet = halWpdmaWriteMsdu(prGlueInfo, prMsduInfo, + prCur); + } + if (!fgRet) + break; + } + + return fgRet; +} + +bool kalDevReadData(struct GLUE_INFO *prGlueInfo, uint16_t u2Port, + struct SW_RFB *prSwRfb) +{ + struct ADAPTER *prAdapter = NULL; + struct GL_HIF_INFO *prHifInfo = NULL; + struct HIF_MEM_OPS *prMemOps; + struct RXD_STRUCT *pRxD; + struct RTMP_RX_RING *prRxRing; + struct RTMP_DMACB *pRxCell; + struct RTMP_DMABUF *prDmaBuf; + u_int8_t fgRet = TRUE; + uint32_t u4CpuIdx = 0; + + ASSERT(prGlueInfo); + + prAdapter = prGlueInfo->prAdapter; + prHifInfo = &prGlueInfo->rHifInfo; + prMemOps = &prHifInfo->rMemOps; + prRxRing = &prHifInfo->RxRing[u2Port]; + + kalDevRegRead(prGlueInfo, prRxRing->hw_cidx_addr, &prRxRing->RxCpuIdx); + u4CpuIdx = prRxRing->RxCpuIdx; + INC_RING_INDEX(u4CpuIdx, prRxRing->u4RingSize); + + pRxCell = &prRxRing->Cell[u4CpuIdx]; + pRxD = (struct RXD_STRUCT *)pRxCell->AllocVa; + + if (halWpdmaGetRxDmaDoneCnt(prGlueInfo, u2Port) == 0) + return FALSE; + + if (!kalWaitRxDmaDone(prGlueInfo, prRxRing, pRxD, u2Port)) { + if (!prRxRing->fgIsDumpLog) { + DBGLOG(HAL, ERROR, "RX Done bit not ready(ReadData)\n"); + } + prRxRing->fgIsDumpLog = true; + return false; + } + + if (pRxD->LastSec0 == 0 || prRxRing->fgRxSegPkt) { + /* Rx segmented packet */ + DBGLOG(HAL, WARN, + "Skip Rx segmented data packet, SDL0[%u] LS0[%u]\n", + pRxD->SDLen0, pRxD->LastSec0); + if (pRxD->LastSec0 == 1) { + /* Last segmented packet */ + prRxRing->fgRxSegPkt = FALSE; + } else { + /* Segmented packet */ + prRxRing->fgRxSegPkt = TRUE; + } + + fgRet = false; + goto skip; + } + + prDmaBuf = &pRxCell->DmaBuf; + + if (prMemOps->copyRxData && + !prMemOps->copyRxData(prHifInfo, pRxCell, prDmaBuf, prSwRfb)) { + fgRet = false; + goto skip; + } + + prSwRfb->pucRecvBuff = ((struct sk_buff *)prSwRfb->pvPacket)->data; + prSwRfb->prRxStatus = (void *)prSwRfb->pucRecvBuff; + +#if CFG_TCP_IP_CHKSUM_OFFLOAD + prSwRfb->u4TcpUdpIpCksStatus = pRxD->RXINFO; +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ + + pRxD->SDPtr0 = (uint64_t)prDmaBuf->AllocPa & DMA_LOWER_32BITS_MASK; +#ifdef CONFIG_PHYS_ADDR_T_64BIT + pRxD->SDPtr1 = ((uint64_t)prDmaBuf->AllocPa >> + DMA_BITS_OFFSET) & DMA_HIGHER_4BITS_MASK; +#else + pRxD->SDPtr1 = 0; +#endif +skip: + pRxD->SDLen0 = prRxRing->u4BufSize; + pRxD->DMADONE = 0; + + prRxRing->RxCpuIdx = u4CpuIdx; + kalDevRegWrite(prGlueInfo, prRxRing->hw_cidx_addr, prRxRing->RxCpuIdx); + prRxRing->fgIsDumpLog = false; + + GLUE_INC_REF_CNT(prGlueInfo->prAdapter->rHifStats.u4DataRxCount); + +#if CFG_TCP_IP_CHKSUM_OFFLOAD + if (fgRet) + DBGLOG(RX, LOUD, "u4TcpUdpIpCksStatus[0x%02x]\n", + prSwRfb->u4TcpUdpIpCksStatus); +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ + + return fgRet; +} + +int wf_ioremap_read(size_t addr, unsigned int *val) +{ + void *vir_addr = NULL; + + vir_addr = ioremap_nocache(addr, 0x10); + if (!vir_addr) { + DBGLOG(INIT, ERROR, "%s: Cannot remap address.\n", __func__); + return -1; + } + + *val = readl(vir_addr); + iounmap(vir_addr); + DBGLOG(INIT, TRACE, "Read CONSYS 0x%08x=0x%08x.\n", addr, *val); + + return 0; +} + +int wf_ioremap_write(phys_addr_t addr, unsigned int val) +{ + void *vir_addr = NULL; + + vir_addr = ioremap_nocache(addr, 0x10); + if (!vir_addr) { + DBGLOG(INIT, ERROR, "%s: Cannot remap address.\n", __func__); + return -1; + } + + writel(val, vir_addr); + iounmap(vir_addr); + DBGLOG(INIT, TRACE, "Write CONSYS 0x%08x=0x%08x.\n", addr, val); + + return 0; +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/ehpi/arm.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/ehpi/arm.c new file mode 100644 index 0000000000000000000000000000000000000000..2d9cf7e82e1004d1bd2e02e6e803e3a3dd97555e --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/ehpi/arm.c @@ -0,0 +1,536 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* +** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/hif/ehpi/arm.c#1 +*/ + +/*! \file "colibri.c" +* \brief Brief description. +* +* Detail description. +*/ + + +/****************************************************************************** +* C O M P I L E R F L A G S +******************************************************************************* +*/ +#if !defined(MCR_EHTCR) +#define MCR_EHTCR 0x0054 +#endif + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include "gl_os.h" +#include "colibri.h" +#include "wlan_lib.h" + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ +static void __iomem *mt5931_mcr_base; + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +#if CFG_EHPI_FASTER_BUS_TIMING +#define EHPI_CONFIG MSC_CS(4, MSC_RBUFF_SLOW | \ + MSC_RRR(4) | \ + MSC_RDN(8) | \ + MSC_RDF(7) | \ + MSC_RBW_16 | \ + MSC_RT_VLIO) +#else +#define EHPI_CONFIG MSC_CS(4, MSC_RBUFF_SLOW | \ + MSC_RRR(7) | \ + MSC_RDN(13) | \ + MSC_RDF(12) | \ + MSC_RBW_16 | \ + MSC_RT_VLIO) +#endif /* CFG_EHPI_FASTER_BUS_TIMING */ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +static void collibri_ehpi_reg_init(void); + +static void collibri_ehpi_reg_uninit(void); + +static void mt5931_ehpi_reg_init(void); + +static void mt5931_ehpi_reg_uninit(void); + +static void busSetIrq(void); + +static void busFreeIrq(void); + +static irqreturn_t glEhpiInterruptHandler(int irq, void *dev_id); + +#if DBG +static void initTrig(void); +#endif + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function will register sdio bus to the os +* +* \param[in] pfProbe Function pointer to detect card +* \param[in] pfRemove Function pointer to remove card +* +* \return The result of registering sdio bus +*/ +/*----------------------------------------------------------------------------*/ +uint32_t glRegisterBus(probe_card pfProbe, remove_card pfRemove) +{ + + ASSERT(pfProbe); + ASSERT(pfRemove); + + pr_info("mtk_sdio: MediaTek eHPI WLAN driver\n"); + pr_info("mtk_sdio: Copyright MediaTek Inc.\n"); + + if (pfProbe(NULL) != WLAN_STATUS_SUCCESS) { + pfRemove(); + return WLAN_STATUS_FAILURE; + } + + return WLAN_STATUS_SUCCESS; +} /* end of glRegisterBus() */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function will unregister sdio bus to the os +* +* \param[in] pfRemove Function pointer to remove card +* +* \return (none) +*/ +/*----------------------------------------------------------------------------*/ +void glUnregisterBus(remove_card pfRemove) +{ + ASSERT(pfRemove); + pfRemove(); + + /* TODO: eHPI uninitialization */ +} /* end of glUnregisterBus() */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function stores hif related info, which is initialized before. +* +* \param[in] prGlueInfo Pointer to glue info structure +* \param[in] u4Cookie Pointer to UINT_32 memory base variable for _HIF_HPI +* +* \return (none) +*/ +/*----------------------------------------------------------------------------*/ +void glSetHifInfo(struct GLUE_INFO *prGlueInfo, unsigned long ulCookie) +{ + struct GL_HIF_INFO *prHif = NULL; + + ASSERT(prGlueInfo); + + prHif = &prGlueInfo->rHifInfo; + + /* fill some buffered information into prHif */ + prHif->mcr_addr_base = mt5931_mcr_base + EHPI_OFFSET_ADDR; + prHif->mcr_data_base = mt5931_mcr_base + EHPI_OFFSET_DATA; + + prGlueInfo->u4InfType = MT_DEV_INF_EHPI; +} /* end of glSetHifInfo() */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function clears hif related info. +* +* \param[in] prGlueInfo Pointer to glue info structure +* +* \return (none) +*/ +/*----------------------------------------------------------------------------*/ +void glClearHifInfo(struct GLUE_INFO *prGlueInfo) +{ + struct GL_HIF_INFO *prHif = NULL; + + ASSERT(prGlueInfo); + + prHif = &prGlueInfo->rHifInfo; + + /* do something */ + prHif->mcr_addr_base = 0; + prHif->mcr_data_base = 0; +} /* end of glClearHifInfo() */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Initialize bus operation and hif related information, request resources. +* +* \param[out] pvData A pointer to HIF-specific data type buffer. +* For eHPI, pvData is a pointer to UINT_32 type and stores a +* mapped base address. +* +* \return (none) +*/ +/*----------------------------------------------------------------------------*/ +u_int8_t glBusInit(void *pvData) +{ +#if DBG + initTrig(); +#endif + + /* 1. initialize eHPI control registers */ + collibri_ehpi_reg_init(); + + /* 2. memory remapping for MT5931 */ + mt5931_ehpi_reg_init(); + + return TRUE; +}; + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Stop bus operation and release resources. +* +* \param[in] pvData A pointer to struct net_device. +* +* \return (none) +*/ +/*----------------------------------------------------------------------------*/ +void glBusRelease(void *pvData) +{ + /* 1. memory unmapping for MT5931 */ + mt5931_ehpi_reg_uninit(); + + /* 2. uninitialize eHPI control registers */ + collibri_ehpi_reg_uninit(); +} /* end of glBusRelease() */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Setup bus interrupt operation and interrupt handler for os. +* +* \param[in] pvData A pointer to struct net_device. +* \param[in] pfnIsr A pointer to interrupt handler function. +* \param[in] pvCookie Private data for pfnIsr function. +* +* \retval WLAN_STATUS_SUCCESS if success +* NEGATIVE_VALUE if fail +*/ +/*----------------------------------------------------------------------------*/ +int32_t glBusSetIrq(void *pvData, void *pfnIsr, void *pvCookie) +{ + struct net_device *pDev = (struct net_device *)pvData; + int i4Status = 0; + + /* 1. enable GPIO pin as IRQ */ + busSetIrq(); + + /* 2. Specify IRQ number into net_device */ + pDev->irq = WLAN_STA_IRQ; + + /* 3. register ISR callback */ + + i4Status = request_irq(pDev->irq, + glEhpiInterruptHandler, + IRQF_DISABLED | IRQF_SHARED | IRQF_TRIGGER_FALLING, pDev->name, pvCookie); + + if (i4Status < 0) + pr_debug("request_irq(%d) failed\n", pDev->irq); + else + pr_info("request_irq(%d) success with dev_id(%x)\n", pDev->irq, (unsigned int)pvCookie); + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Stop bus interrupt operation and disable interrupt handling for os. +* +* \param[in] pvData A pointer to struct net_device. +* \param[in] pvCookie Private data for pfnIsr function. +* +* \return (none) +*/ +/*----------------------------------------------------------------------------*/ +void glBusFreeIrq(void *pvData, void *pvCookie) +{ + struct net_device *prDev = (struct net_device *)pvData; + + if (!prDev) { + pr_info("Invalid net_device context.\n"); + return; + } + + if (prDev->irq) { + disable_irq(prDev->irq); + free_irq(prDev->irq, pvCookie); + prDev->irq = 0; + } + + busFreeIrq(); +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Set power state +* +* \param[in] pvGlueInfo A pointer to GLUE_INFO_T +* \param[in] ePowerMode Power Mode Setting +* +* \return (none) +*/ +/*----------------------------------------------------------------------------*/ +void glSetPowerState(IN struct GLUE_INFO *prGlueInfo, IN uint32_t ePowerMode) +{ +} + +#if DBG +/*----------------------------------------------------------------------------*/ +/*! +* \brief Setup the GPIO pin. +* +* \return N/A +*/ +/*----------------------------------------------------------------------------*/ +void setTrig(void) +{ + GPSR1 = (0x1UL << 8); +} /* end of setTrig() */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Clear the GPIO pin. +* +* \return N/A +*/ +/*----------------------------------------------------------------------------*/ +void clearTrig(void) +{ + GPCR1 = (0x1UL << 8); +} /* end of clearTrig() */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Set a specified GPIO pin to H or L. +* +* \return N/A +*/ +/*----------------------------------------------------------------------------*/ +static void initTrig(void) +{ + set_GPIO_mode(GPIO40_FFDTR | GPIO_OUT); + clearTrig(); +} /* end of initTrig() */ +#endif + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function congifure platform-dependent interrupt triger type. +* +* \return N/A +*/ +/*----------------------------------------------------------------------------*/ +void busSetIrq(void) +{ +#if defined(WLAN_STA_IRQ_GPIO) + pxa_gpio_mode(WLAN_STA_IRQ_GPIO | GPIO_IN); + set_irq_type(WLAN_STA_IRQ, IRQT_FALLING); +#endif +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function should restore settings changed by busSetIrq(). +* +* \return N/A +*/ +/*----------------------------------------------------------------------------*/ +void busFreeIrq(void) +{ +#if defined(WLAN_STA_IRQ_GPIO) + pxa_gpio_mode(WLAN_STA_IRQ_GPIO | GPIO_OUT); +#endif +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function configures colibri memory controller registers +* +* \return N/A +*/ +/*----------------------------------------------------------------------------*/ +static void collibri_ehpi_reg_init(void) +{ + uint32_t u4RegValue; + + /* 1. enable nCS as memory controller */ + pxa_gpio_mode(GPIO80_nCS_4_MD); + + /* 2. nCS<4> configuration */ + u4RegValue = MSC2; + u4RegValue &= ~MSC_CS(4, 0xFFFF); + u4RegValue |= EHPI_CONFIG; + MSC2 = u4RegValue; + + pr_info("EHPI new MSC2:0x%08x\n", MSC2); +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function restores colibri memory controller registers +* +* \return N/A +*/ +/*----------------------------------------------------------------------------*/ +static void collibri_ehpi_reg_uninit(void) +{ + uint32_t u4RegValue; + + /* 1. restore nCS<4> configuration */ + u4RegValue = MSC2; + u4RegValue &= ~MSC_CS(4, 0xFFFF); + MSC2 = u4RegValue; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function configures MT5931 mapped registers on colibri +* +* \return N/A +*/ +/*----------------------------------------------------------------------------*/ +static void mt5931_ehpi_reg_init(void) +{ + struct resource *reso = NULL; + + /* 1. request memory regioin */ + reso = request_mem_region((unsigned long)MEM_MAPPED_ADDR, (unsigned long)MEM_MAPPED_LEN, (char *)MODULE_PREFIX); + if (!reso) { + pr_err("request_mem_region(0x%08X) failed.\n", MEM_MAPPED_ADDR); + return; + } + + /* 2. memory regioin remapping */ + mt5931_mcr_base = ioremap_nocache(MEM_MAPPED_ADDR, MEM_MAPPED_LEN); + if (!(mt5931_mcr_base)) { + release_mem_region(MEM_MAPPED_ADDR, MEM_MAPPED_LEN); + pr_err("ioremap_nocache(0x%08X) failed.\n", MEM_MAPPED_ADDR); + return; + } +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function releases MT5931 mapped registers on colibri +* +* \return N/A +*/ +/*----------------------------------------------------------------------------*/ +static void mt5931_ehpi_reg_uninit(void) +{ + iounmap(mt5931_mcr_base); + mt5931_mcr_base = NULL; + + release_mem_region(MEM_MAPPED_ADDR, MEM_MAPPED_LEN); +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Callback for interrupt coming from device +* +* \return N/A +*/ +/*----------------------------------------------------------------------------*/ +static irqreturn_t glEhpiInterruptHandler(int irq, void *dev_id) +{ + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *) dev_id; + + ASSERT(prGlueInfo); + + if (!prGlueInfo) + return IRQ_HANDLED; + + /* 1. Running for ISR */ + wlanISR(prGlueInfo->prAdapter, TRUE); + + /* 1.1 Halt flag Checking */ + if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) + return IRQ_HANDLED; + + /* 2. Flag marking for interrupt */ + set_bit(GLUE_FLAG_INT_BIT, &prGlueInfo->ulFlag); + + /* 3. wake up tx service thread */ + wake_up_interruptible(&prGlueInfo->waitq); + + return IRQ_HANDLED; +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/ehpi/colibri.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/ehpi/colibri.c new file mode 100644 index 0000000000000000000000000000000000000000..803a8e824080484d2181591272feefc043e58a48 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/ehpi/colibri.c @@ -0,0 +1,536 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* +** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/hif/ehpi/colibri.c#1 +*/ + +/*! \file "colibri.c" +* \brief Brief description. +* +* Detail description. +*/ + + +/****************************************************************************** +* C O M P I L E R F L A G S +******************************************************************************* +*/ +#if !defined(MCR_EHTCR) +#define MCR_EHTCR 0x0054 +#endif + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include "gl_os.h" +#include "colibri.h" +#include "wlan_lib.h" + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ +static void __iomem *mt5931_mcr_base; + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +#if CFG_EHPI_FASTER_BUS_TIMING +#define EHPI_CONFIG MSC_CS(4, MSC_RBUFF_SLOW | \ + MSC_RRR(4) | \ + MSC_RDN(8) | \ + MSC_RDF(7) | \ + MSC_RBW_16 | \ + MSC_RT_VLIO) +#else +#define EHPI_CONFIG MSC_CS(4, MSC_RBUFF_SLOW | \ + MSC_RRR(7) | \ + MSC_RDN(13) | \ + MSC_RDF(12) | \ + MSC_RBW_16 | \ + MSC_RT_VLIO) +#endif /* CFG_EHPI_FASTER_BUS_TIMING */ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +static void collibri_ehpi_reg_init(void); + +static void collibri_ehpi_reg_uninit(void); + +static void mt5931_ehpi_reg_init(void); + +static void mt5931_ehpi_reg_uninit(void); + +static void busSetIrq(void); + +static void busFreeIrq(void); + +static irqreturn_t glEhpiInterruptHandler(int irq, void *dev_id); + +#if DBG +static void initTrig(void); +#endif + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function will register sdio bus to the os +* +* \param[in] pfProbe Function pointer to detect card +* \param[in] pfRemove Function pointer to remove card +* +* \return The result of registering sdio bus +*/ +/*----------------------------------------------------------------------------*/ +uint32_t glRegisterBus(probe_card pfProbe, remove_card pfRemove) +{ + + ASSERT(pfProbe); + ASSERT(pfRemove); + + pr_info("mtk_sdio: MediaTek eHPI WLAN driver\n"); + pr_info("mtk_sdio: Copyright MediaTek Inc.\n"); + + if (pfProbe(NULL) != WLAN_STATUS_SUCCESS) { + pfRemove(); + return WLAN_STATUS_FAILURE; + } + + return WLAN_STATUS_SUCCESS; +} /* end of glRegisterBus() */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function will unregister sdio bus to the os +* +* \param[in] pfRemove Function pointer to remove card +* +* \return (none) +*/ +/*----------------------------------------------------------------------------*/ +void glUnregisterBus(remove_card pfRemove) +{ + ASSERT(pfRemove); + pfRemove(); + + /* TODO: eHPI uninitialization */ +} /* end of glUnregisterBus() */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function stores hif related info, which is initialized before. +* +* \param[in] prGlueInfo Pointer to glue info structure +* \param[in] u4Cookie Pointer to UINT_32 memory base variable for _HIF_HPI +* +* \return (none) +*/ +/*----------------------------------------------------------------------------*/ +void glSetHifInfo(struct GLUE_INFO *prGlueInfo, unsigned long ulCookie) +{ + struct GL_HIF_INFO *prHif = NULL; + + ASSERT(prGlueInfo); + + prHif = &prGlueInfo->rHifInfo; + + /* fill some buffered information into prHif */ + prHif->mcr_addr_base = mt5931_mcr_base + EHPI_OFFSET_ADDR; + prHif->mcr_data_base = mt5931_mcr_base + EHPI_OFFSET_DATA; + + prGlueInfo->u4InfType = MT_DEV_INF_EHPI; +} /* end of glSetHifInfo() */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function clears hif related info. +* +* \param[in] prGlueInfo Pointer to glue info structure +* +* \return (none) +*/ +/*----------------------------------------------------------------------------*/ +void glClearHifInfo(struct GLUE_INFO *prGlueInfo) +{ + struct GL_HIF_INFO *prHif = NULL; + + ASSERT(prGlueInfo); + + prHif = &prGlueInfo->rHifInfo; + + /* do something */ + prHif->mcr_addr_base = 0; + prHif->mcr_data_base = 0; +} /* end of glClearHifInfo() */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Initialize bus operation and hif related information, request resources. +* +* \param[out] pvData A pointer to HIF-specific data type buffer. +* For eHPI, pvData is a pointer to UINT_32 type and stores a +* mapped base address. +* +* \return (none) +*/ +/*----------------------------------------------------------------------------*/ +u_int8_t glBusInit(void *pvData) +{ +#if DBG + initTrig(); +#endif + + /* 1. initialize eHPI control registers */ + collibri_ehpi_reg_init(); + + /* 2. memory remapping for MT5931 */ + mt5931_ehpi_reg_init(); + + return TRUE; +}; + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Stop bus operation and release resources. +* +* \param[in] pvData A pointer to struct net_device. +* +* \return (none) +*/ +/*----------------------------------------------------------------------------*/ +void glBusRelease(void *pvData) +{ + /* 1. memory unmapping for MT5931 */ + mt5931_ehpi_reg_uninit(); + + /* 2. uninitialize eHPI control registers */ + collibri_ehpi_reg_uninit(); +} /* end of glBusRelease() */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Setup bus interrupt operation and interrupt handler for os. +* +* \param[in] pvData A pointer to struct net_device. +* \param[in] pfnIsr A pointer to interrupt handler function. +* \param[in] pvCookie Private data for pfnIsr function. +* +* \retval WLAN_STATUS_SUCCESS if success +* NEGATIVE_VALUE if fail +*/ +/*----------------------------------------------------------------------------*/ +int32_t glBusSetIrq(void *pvData, void *pfnIsr, void *pvCookie) +{ + struct net_device *pDev = (struct net_device *)pvData; + int i4Status = 0; + + /* 1. enable GPIO pin as IRQ */ + busSetIrq(); + + /* 2. Specify IRQ number into net_device */ + pDev->irq = WLAN_STA_IRQ; + + /* 3. register ISR callback */ + + i4Status = request_irq(pDev->irq, + glEhpiInterruptHandler, + IRQF_DISABLED | IRQF_SHARED | IRQF_TRIGGER_FALLING, pDev->name, pvCookie); + + if (i4Status < 0) + pr_debug("request_irq(%d) failed\n", pDev->irq); + else + pr_info("request_irq(%d) success with dev_id(%x)\n", pDev->irq, (unsigned int)pvCookie); + + return i4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Stop bus interrupt operation and disable interrupt handling for os. +* +* \param[in] pvData A pointer to struct net_device. +* \param[in] pvCookie Private data for pfnIsr function. +* +* \return (none) +*/ +/*----------------------------------------------------------------------------*/ +void glBusFreeIrq(void *pvData, void *pvCookie) +{ + struct net_device *prDev = (struct net_device *)pvData; + + if (!prDev) { + pr_info("Invalid net_device context.\n"); + return; + } + + if (prDev->irq) { + disable_irq(prDev->irq); + free_irq(prDev->irq, pvCookie); + prDev->irq = 0; + } + + busFreeIrq(); +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Set power state +* +* \param[in] pvGlueInfo A pointer to GLUE_INFO_T +* \param[in] ePowerMode Power Mode Setting +* +* \return (none) +*/ +/*----------------------------------------------------------------------------*/ +void glSetPowerState(IN struct GLUE_INFO *prGlueInfo, IN uint32_t ePowerMode) +{ +} + +#if DBG +/*----------------------------------------------------------------------------*/ +/*! +* \brief Setup the GPIO pin. +* +* \return N/A +*/ +/*----------------------------------------------------------------------------*/ +void setTrig(void) +{ + GPSR1 = (0x1UL << 8); +} /* end of setTrig() */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Clear the GPIO pin. +* +* \return N/A +*/ +/*----------------------------------------------------------------------------*/ +void clearTrig(void) +{ + GPCR1 = (0x1UL << 8); +} /* end of clearTrig() */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Set a specified GPIO pin to H or L. +* +* \return N/A +*/ +/*----------------------------------------------------------------------------*/ +static void initTrig(void) +{ + set_GPIO_mode(GPIO40_FFDTR | GPIO_OUT); + clearTrig(); +} /* end of initTrig() */ +#endif + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function congifure platform-dependent interrupt triger type. +* +* \return N/A +*/ +/*----------------------------------------------------------------------------*/ +void busSetIrq(void) +{ +#if defined(WLAN_STA_IRQ_GPIO) + pxa_gpio_mode(WLAN_STA_IRQ_GPIO | GPIO_IN); + set_irq_type(WLAN_STA_IRQ, IRQT_FALLING); +#endif +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function should restore settings changed by busSetIrq(). +* +* \return N/A +*/ +/*----------------------------------------------------------------------------*/ +void busFreeIrq(void) +{ +#if defined(WLAN_STA_IRQ_GPIO) + pxa_gpio_mode(WLAN_STA_IRQ_GPIO | GPIO_OUT); +#endif +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function configures colibri memory controller registers +* +* \return N/A +*/ +/*----------------------------------------------------------------------------*/ +static void collibri_ehpi_reg_init(void) +{ + uint32_t u4RegValue; + + /* 1. enable nCS as memory controller */ + pxa_gpio_mode(GPIO80_nCS_4_MD); + + /* 2. nCS<4> configuration */ + u4RegValue = MSC2; + u4RegValue &= ~MSC_CS(4, 0xFFFF); + u4RegValue |= EHPI_CONFIG; + MSC2 = u4RegValue; + + pr_info("EHPI new MSC2:0x%08x\n", MSC2); +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function restores colibri memory controller registers +* +* \return N/A +*/ +/*----------------------------------------------------------------------------*/ +static void collibri_ehpi_reg_uninit(void) +{ + uint32_t u4RegValue; + + /* 1. restore nCS<4> configuration */ + u4RegValue = MSC2; + u4RegValue &= ~MSC_CS(4, 0xFFFF); + MSC2 = u4RegValue; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function configures MT5931 mapped registers on colibri +* +* \return N/A +*/ +/*----------------------------------------------------------------------------*/ +static void mt5931_ehpi_reg_init(void) +{ + struct resource *reso = NULL; + + /* 1. request memory regioin */ + reso = request_mem_region((unsigned long)MEM_MAPPED_ADDR, (unsigned long)MEM_MAPPED_LEN, (char *)MODULE_PREFIX); + if (!reso) { + pr_err("request_mem_region(0x%08X) failed.\n", MEM_MAPPED_ADDR); + return; + } + + /* 2. memory regioin remapping */ + mt5931_mcr_base = ioremap_nocache(MEM_MAPPED_ADDR, MEM_MAPPED_LEN); + if (!(mt5931_mcr_base)) { + release_mem_region(MEM_MAPPED_ADDR, MEM_MAPPED_LEN); + pr_err("ioremap_nocache(0x%08X) failed.\n", MEM_MAPPED_ADDR); + return; + } +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function releases MT5931 mapped registers on colibri +* +* \return N/A +*/ +/*----------------------------------------------------------------------------*/ +static void mt5931_ehpi_reg_uninit(void) +{ + iounmap(mt5931_mcr_base); + mt5931_mcr_base = NULL; + + release_mem_region(MEM_MAPPED_ADDR, MEM_MAPPED_LEN); +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Callback for interrupt coming from device +* +* \return N/A +*/ +/*----------------------------------------------------------------------------*/ +static irqreturn_t glEhpiInterruptHandler(int irq, void *dev_id) +{ + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *) dev_id; + + ASSERT(prGlueInfo); + + if (!prGlueInfo) + return IRQ_HANDLED; + + /* 1. Running for ISR */ + wlanISR(prGlueInfo->prAdapter, TRUE); + + /* 1.1 Halt flag Checking */ + if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) + return IRQ_HANDLED; + + /* 2. Flag marking for interrupt */ + set_bit(GLUE_FLAG_INT_BIT, &prGlueInfo->ulFlag); + + /* 3. wake up tx service thread */ + wake_up_interruptible(&prGlueInfo->waitq); + + return IRQ_HANDLED; +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/ehpi/ehpi.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/ehpi/ehpi.c new file mode 100644 index 0000000000000000000000000000000000000000..1ca0aaf9feeedfb4efeaf97d83a8169c2bfd5073 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/ehpi/ehpi.c @@ -0,0 +1,414 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* +** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/hif/ehpi/ehpi.c#1 +*/ + +/*! \file "ehpi.c" +* \brief Brief description. +* +* Detail description. +*/ + + +/****************************************************************************** +* C O M P I L E R F L A G S +******************************************************************************* +*/ +#if !defined(MCR_EHTCR) +#define MCR_EHTCR 0x0054 +#endif + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include "gl_os.h" +#include "colibri.h" +#include "wlan_lib.h" + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +static u_int8_t kalDevRegRead_impl(IN struct GLUE_INFO *prGlueInfo, IN uint32_t u4Register, OUT uint32_t *pu4Value); + +static u_int8_t kalDevRegWrite_impl(IN struct GLUE_INFO *prGlueInfo, IN uint32_t u4Register, IN uint32_t u4Value); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This routine is used to read a 32 bit register value from device. +* +* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. +* \param[in] u4Register The register offset. +* \param[out] pu4Value Pointer to the 32-bit value of the register been read. +* +* \retval TRUE +* \retval FALSE +*/ +/*----------------------------------------------------------------------------*/ +u_int8_t kalDevRegRead(IN struct GLUE_INFO *prGlueInfo, IN uint32_t u4Register, OUT uint32_t *pu4Value) +{ + GLUE_SPIN_LOCK_DECLARATION(); + + ASSERT(prGlueInfo); + ASSERT(pu4Value); + + /* 0. acquire spinlock */ + GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_EHPI_BUS); + + /* 1. I/O stuff */ + kalDevRegRead_impl(prGlueInfo, u4Register, pu4Value); + + /* 2. release spin lock */ + GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_EHPI_BUS); + + return TRUE; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This routine is used to write a 32 bit register value to device. +* +* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. +* \param[in] u4Register The register offset. +* \param[out] u4Value The 32-bit value of the register to be written. +* +* \retval TRUE +* \retval FALSE +*/ +/*----------------------------------------------------------------------------*/ +u_int8_t kalDevRegWrite(struct GLUE_INFO *prGlueInfo, IN uint32_t u4Register, IN uint32_t u4Value) +{ + GLUE_SPIN_LOCK_DECLARATION(); + + ASSERT(prGlueInfo); + + /* 0. acquire spinlock */ + GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_EHPI_BUS); + + /* 1. I/O stuff */ + kalDevRegWrite_impl(prGlueInfo, u4Register, u4Value); + + /* 2. release spin lock */ + GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_EHPI_BUS); + + return TRUE; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This routine is used to read port data from device in unit of byte. +* +* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. +* \param[in] u2Port The register offset. +* \param[in] u2Len The number of byte to be read. +* \param[out] pucBuf Pointer to data buffer for read +* \param[in] u2ValidOutBufSize Length of the buffer valid to be accessed +* +* \retval TRUE +* \retval FALSE +*/ +/*----------------------------------------------------------------------------*/ +u_int8_t +kalDevPortRead(IN struct GLUE_INFO *prGlueInfo, + IN uint16_t u2Port, IN uint16_t u2Len, OUT uint8_t *pucBuf, IN uint16_t u2ValidOutBufSize) +{ + uint32_t i; + + GLUE_SPIN_LOCK_DECLARATION(); + + ASSERT(prGlueInfo); + + /* 0. acquire spinlock */ + GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_EHPI_BUS); + + /* 1. indicate correct length to HIFSYS if larger than 4-bytes */ + if (u2Len > 4) + kalDevRegWrite_impl(prGlueInfo, MCR_EHTCR, ALIGN_4(u2Len)); + + /* 2. address cycle */ +#if EHPI16 + writew(u2Port, prGlueInfo->rHifInfo.mcr_addr_base); +#elif EHPI8 + writew((u2Port & 0xFF), prGlueInfo->rHifInfo.mcr_addr_base); + writew(((u2Port & 0xFF00) >> 8), prGlueInfo->rHifInfo.mcr_addr_base); +#endif + + /* 3. data cycle */ + for (i = 0; i < ALIGN_4(u2Len); i += 4) { +#if EHPI16 + *((uint16_t *)&(pucBuf[i])) = (uint16_t) (readw(prGlueInfo->rHifInfo.mcr_data_base) & 0xFFFF); + *((uint16_t *)&(pucBuf[i + 2])) = (uint16_t) (readw(prGlueInfo->rHifInfo.mcr_data_base) & 0xFFFF); +#elif EHPI8 + *((uint8_t *)&(pucBuf[i])) = (uint8_t) (readw(prGlueInfo->rHifInfo.mcr_data_base) & 0xFF); + *((uint8_t *)&(pucBuf[i + 1])) = (uint8_t) (readw(prGlueInfo->rHifInfo.mcr_data_base) & 0xFF); + *((uint8_t *)&(pucBuf[i + 2])) = (uint8_t) (readw(prGlueInfo->rHifInfo.mcr_data_base) & 0xFF); + *((uint8_t *)&(pucBuf[i + 3])) = (uint8_t) (readw(prGlueInfo->rHifInfo.mcr_data_base) & 0xFF); +#endif + } + + /* 4. restore length to 4 if necessary */ + if (u2Len > 4) + kalDevRegWrite_impl(prGlueInfo, MCR_EHTCR, 4); + + /* 5. release spin lock */ + GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_EHPI_BUS); + + return TRUE; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This routine is used to write port data to device in unit of byte. +* +* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. +* \param[in] u2Port The register offset. +* \param[in] u2Len The number of byte to be write. +* \param[out] pucBuf Pointer to data buffer for write +* \param[in] u2ValidOutBufSize Length of the buffer valid to be accessed +* +* \retval TRUE +* \retval FALSE +*/ +/*----------------------------------------------------------------------------*/ +u_int8_t +kalDevPortWrite(struct GLUE_INFO *prGlueInfo, + IN uint16_t u2Port, IN uint16_t u2Len, IN uint8_t *pucBuf, IN uint16_t u2ValidInBufSize) +{ + uint32_t i; + + GLUE_SPIN_LOCK_DECLARATION(); + + ASSERT(prGlueInfo); + + /* 0. acquire spinlock */ + GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_EHPI_BUS); + + /* 1. indicate correct length to HIFSYS if larger than 4-bytes */ + if (u2Len > 4) + kalDevRegWrite_impl(prGlueInfo, MCR_EHTCR, ALIGN_4(u2Len)); + + /* 2. address cycle */ +#if EHPI16 + writew(u2Port, prGlueInfo->rHifInfo.mcr_addr_base); +#elif EHPI8 + writew((u2Port & 0xFF), prGlueInfo->rHifInfo.mcr_addr_base); + writew(((u2Port & 0xFF00) >> 8), prGlueInfo->rHifInfo.mcr_addr_base); +#endif + + /* 3. data cycle */ + for (i = 0; i < ALIGN_4(u2Len); i += 4) { +#if EHPI16 + writew((uint32_t) (*((uint16_t *)&(pucBuf[i]))), prGlueInfo->rHifInfo.mcr_data_base); + writew((uint32_t) (*((uint16_t *)&(pucBuf[i + 2]))), prGlueInfo->rHifInfo.mcr_data_base); +#elif EHPI8 + writew((uint32_t) (*((uint8_t *)&(pucBuf[i]))), prGlueInfo->rHifInfo.mcr_data_base); + writew((uint32_t) (*((uint8_t *)&(pucBuf[i + 1]))), prGlueInfo->rHifInfo.mcr_data_base); + writew((uint32_t) (*((uint8_t *)&(pucBuf[i + 2]))), prGlueInfo->rHifInfo.mcr_data_base); + writew((uint32_t) (*((uint8_t *)&(pucBuf[i + 3]))), prGlueInfo->rHifInfo.mcr_data_base); +#endif + } + + /* 4. restore length to 4 if necessary */ + if (u2Len > 4) + kalDevRegWrite_impl(prGlueInfo, MCR_EHTCR, 4); + + /* 5. release spin lock */ + GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_EHPI_BUS); + + return TRUE; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Write device I/O port with single byte (for SDIO compatibility) +* +* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. +* \param[in] u4Addr I/O port offset +* \param[in] ucData single byte of data to be written +* \param[in] u4ValidInBufSize Length of the buffer valid to be accessed +* +* \retval TRUE operation success +* \retval FALSE operation fail +*/ +/*----------------------------------------------------------------------------*/ +u_int8_t kalDevWriteWithSdioCmd52(IN struct GLUE_INFO *prGlueInfo, IN uint32_t u4Addr, IN uint8_t ucData) +{ + uint32_t u4RegValue; + u_int8_t bRet; + + GLUE_SPIN_LOCK_DECLARATION(); + + ASSERT(prGlueInfo); + + /* 0. acquire spinlock */ + GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_EHPI_BUS); + + /* 1. there is no single byte access support for eHPI, use 4-bytes write-after-read approach instead */ + if (kalDevRegRead_impl(prGlueInfo, u4Addr, &u4RegValue) == TRUE) { + u4RegValue &= 0x00; + u4RegValue |= ucData; + + bRet = kalDevRegWrite_impl(prGlueInfo, u4Addr, u4RegValue); + } else { + bRet = FALSE; + } + + /* 2. release spin lock */ + GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_EHPI_BUS); + + return bRet; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This routine is used to read a 32 bit register value from device +* without spin lock protection and dedicated for internal use +* +* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. +* \param[in] u4Register The register offset. +* \param[out] pu4Value Pointer to the 32-bit value of the register been read. +* +* \retval TRUE +* \retval FALSE +*/ +/*----------------------------------------------------------------------------*/ +static u_int8_t kalDevRegRead_impl(IN struct GLUE_INFO *prGlueInfo, IN uint32_t u4Register, OUT uint32_t *pu4Value) +{ + ASSERT(prGlueInfo); + + /* 1. address cycle */ +#if EHPI16 + writew(u4Register, prGlueInfo->rHifInfo.mcr_addr_base); +#elif EHPI8 + writew((u4Register & 0xFF), prGlueInfo->rHifInfo.mcr_addr_base); + writew(((u4Register & 0xFF00) >> 8), prGlueInfo->rHifInfo.mcr_addr_base); +#endif + + /* 2. data cycle */ +#if EHPI16 + *pu4Value = (readw(prGlueInfo->rHifInfo.mcr_data_base) & 0xFFFF); + *pu4Value |= ((readw(prGlueInfo->rHifInfo.mcr_data_base) & 0xFFFF) << 16); +#elif EHPI8 + *pu4Value = (readw(prGlueInfo->rHifInfo.mcr_data_base) & 0xFF); + *pu4Value |= ((readw(prGlueInfo->rHifInfo.mcr_data_base) & 0xFF) << 8); + *pu4Value |= ((readw(prGlueInfo->rHifInfo.mcr_data_base) & 0xFF) << 16); + *pu4Value |= ((readw(prGlueInfo->rHifInfo.mcr_data_base) & 0xFF) << 24); +#endif + + return TRUE; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This routine is used to write a 32 bit register value to device. +* without spin lock protection and dedicated for internal use +* +* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. +* \param[in] u4Register The register offset. +* \param[out] u4Value The 32-bit value of the register to be written. +* +* \retval TRUE +* \retval FALSE +*/ +/*----------------------------------------------------------------------------*/ +static u_int8_t kalDevRegWrite_impl(IN struct GLUE_INFO *prGlueInfo, IN uint32_t u4Register, IN uint32_t u4Value) +{ + ASSERT(prGlueInfo); + + /* 1. address cycle */ +#if EHPI16 + writew(u4Register, prGlueInfo->rHifInfo.mcr_addr_base); +#elif EHPI8 + writew((u4Register & 0xFF), prGlueInfo->rHifInfo.mcr_addr_base); + writew(((u4Register & 0xFF00) >> 8), prGlueInfo->rHifInfo.mcr_addr_base); +#endif + + /* 2. data cycle */ +#if EHPI16 + writew(u4Value, prGlueInfo->rHifInfo.mcr_data_base); + writew((u4Value & 0xFFFF0000) >> 16, prGlueInfo->rHifInfo.mcr_data_base); +#elif EHPI8 + writew((u4Value & 0x000000FF), prGlueInfo->rHifInfo.mcr_data_base); + writew((u4Value & 0x0000FF00) >> 8, prGlueInfo->rHifInfo.mcr_data_base); + writew((u4Value & 0x00FF0000) >> 16, prGlueInfo->rHifInfo.mcr_data_base); + writew((u4Value & 0xFF000000) >> 24, prGlueInfo->rHifInfo.mcr_data_base); +#endif + + return TRUE; +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/ehpi/include/colibri.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/ehpi/include/colibri.h new file mode 100644 index 0000000000000000000000000000000000000000..a877b79d8fa96e6327fa03eb522d4292aef98954 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/ehpi/include/colibri.h @@ -0,0 +1,190 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* +** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/hif/ehpi/include/colibri.h#1 +*/ + +/*! \file "colibri.h" +* \brief This file contains colibri BSP configuration based on eHPI interface +* +* N/A +*/ + +#ifndef _COLIBRI_H +#define _COLIBRI_H +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +#include +#include +#include +#include +#include + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +#define WLAN_STA_IRQ_GPIO 23 /* use SSP_EXTCLK as interrupt source */ +#define WLAN_STA_IRQ IRQ_GPIO(WLAN_STA_IRQ_GPIO) + +#define MSC_CS(cs, val) ((val)<<(((cs)&1)<<4)) + +#define MSC_RBUFF_SHIFT 15 +#define MSC_RBUFF(x) ((x)< +#ifndef CONFIG_X86 +#include +#endif + +#include "mt66xx_reg.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +#define MTK_PCI_VENDOR_ID 0x14C3 +#define NIC6632_PCIe_DEVICE_ID 0x6632 +#define NIC7668_PCIe_DEVICE_ID 0x7668 +#define MT7663_PCI_PFGA2_VENDOR_ID 0x0E8D +#define NIC7663_PCIe_DEVICE_ID 0x7663 +#define CONNAC_PCI_VENDOR_ID 0x0E8D +#define CONNAC_PCIe_DEVICE_ID 0x3280 +#define NIC7915_PCIe_DEVICE_ID 0x7915 +#define NICSOC3_0_PCIe_DEVICE_ID 0x0789 +#define NIC7961_PCIe_DEVICE_ID 0x7961 + +static const struct pci_device_id mtk_pci_ids[] = { +#ifdef MT6632 + { PCI_DEVICE(MTK_PCI_VENDOR_ID, NIC6632_PCIe_DEVICE_ID), + .driver_data = (kernel_ulong_t)&mt66xx_driver_data_mt6632}, +#endif /* MT6632 */ +#ifdef MT7668 + { PCI_DEVICE(MTK_PCI_VENDOR_ID, NIC7668_PCIe_DEVICE_ID), + .driver_data = (kernel_ulong_t)&mt66xx_driver_data_mt7668}, +#endif /* MT7668 */ +#ifdef MT7663 + { PCI_DEVICE(MTK_PCI_VENDOR_ID, NIC7663_PCIe_DEVICE_ID), + .driver_data = (kernel_ulong_t)&mt66xx_driver_data_mt7663}, + /* For FPGA2 temparay */ + { PCI_DEVICE(MT7663_PCI_PFGA2_VENDOR_ID, NIC7663_PCIe_DEVICE_ID), + .driver_data = (kernel_ulong_t)&mt66xx_driver_data_mt7663}, +#endif /* MT7663 */ +#ifdef CONNAC + { PCI_DEVICE(CONNAC_PCI_VENDOR_ID, CONNAC_PCIe_DEVICE_ID), + .driver_data = (kernel_ulong_t)&mt66xx_driver_data_connac}, +#endif /* CONNAC */ +#ifdef CONNAC2X2 + { PCI_DEVICE(CONNAC_PCI_VENDOR_ID, CONNAC_PCIe_DEVICE_ID), + .driver_data = (kernel_ulong_t)&mt66xx_driver_data_connac2x2}, +#endif /* CONNAC */ +#ifdef MT7915 + { PCI_DEVICE(MTK_PCI_VENDOR_ID, NIC7915_PCIe_DEVICE_ID), + .driver_data = (kernel_ulong_t)&mt66xx_driver_data_mt7915}, +#endif /* MT7915 */ +#ifdef SOC3_0 + { PCI_DEVICE(MTK_PCI_VENDOR_ID, NICSOC3_0_PCIe_DEVICE_ID), + .driver_data = (kernel_ulong_t)&mt66xx_driver_data_soc3_0 }, +#endif /* SOC3_0 */ +#ifdef MT7961 + { PCI_DEVICE(MTK_PCI_VENDOR_ID, NIC7961_PCIe_DEVICE_ID), + .driver_data = (kernel_ulong_t)&mt66xx_driver_data_mt7961}, +#endif /* MT7961 */ + { /* end: all zeroes */ }, +}; + +MODULE_DEVICE_TABLE(pci, mtk_pci_ids); + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ +static probe_card pfWlanProbe; +static remove_card pfWlanRemove; + +static struct pci_driver mtk_pci_driver = { + .name = "wlan", + .id_table = mtk_pci_ids, + .probe = NULL, + .remove = NULL, +}; + +static u_int8_t g_fgDriverProbed = FALSE; +static uint32_t g_u4DmaMask = 32; +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +static void pcieAllocDesc(struct GL_HIF_INFO *prHifInfo, + struct RTMP_DMABUF *prDescRing, + uint32_t u4Num); +static void *pcieAllocRxBuf(struct GL_HIF_INFO *prHifInfo, + struct RTMP_DMABUF *prDmaBuf, + uint32_t u4Num, uint32_t u4Idx); +static void pcieAllocTxDataBuf(struct MSDU_TOKEN_ENTRY *prToken, + uint32_t u4Idx); +static void *pcieAllocRuntimeMem(uint32_t u4SrcLen); +static bool pcieCopyCmd(struct GL_HIF_INFO *prHifInfo, + struct RTMP_DMACB *prTxCell, void *pucBuf, + void *pucSrc1, uint32_t u4SrcLen1, + void *pucSrc2, uint32_t u4SrcLen2); +static bool pcieCopyEvent(struct GL_HIF_INFO *prHifInfo, + struct RTMP_DMACB *pRxCell, + struct RXD_STRUCT *pRxD, + struct RTMP_DMABUF *prDmaBuf, + uint8_t *pucDst, uint32_t u4Len); +static bool pcieCopyTxData(struct MSDU_TOKEN_ENTRY *prToken, + void *pucSrc, uint32_t u4Len); +static bool pcieCopyRxData(struct GL_HIF_INFO *prHifInfo, + struct RTMP_DMACB *pRxCell, + struct RTMP_DMABUF *prDmaBuf, + struct SW_RFB *prSwRfb); +static phys_addr_t pcieMapTxBuf(struct GL_HIF_INFO *prHifInfo, + void *pucBuf, uint32_t u4Offset, uint32_t u4Len); +static phys_addr_t pcieMapRxBuf(struct GL_HIF_INFO *prHifInfo, + void *pucBuf, uint32_t u4Offset, uint32_t u4Len); +static void pcieUnmapTxBuf(struct GL_HIF_INFO *prHifInfo, + phys_addr_t rDmaAddr, uint32_t u4Len); +static void pcieUnmapRxBuf(struct GL_HIF_INFO *prHifInfo, + phys_addr_t rDmaAddr, uint32_t u4Len); +static void pcieFreeDesc(struct GL_HIF_INFO *prHifInfo, + struct RTMP_DMABUF *prDescRing); +static void pcieFreeBuf(void *pucSrc, uint32_t u4Len); +static void pcieFreePacket(void *pvPacket); +static void pcieDumpTx(struct GL_HIF_INFO *prHifInfo, + struct RTMP_TX_RING *prTxRing, + uint32_t u4Idx, uint32_t u4DumpLen); +static void pcieDumpRx(struct GL_HIF_INFO *prHifInfo, + struct RTMP_RX_RING *prRxRing, + uint32_t u4Idx, uint32_t u4DumpLen); + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is a PCIE interrupt callback function + * + * \param[in] func pointer to PCIE handle + * + * \return void + */ +/*----------------------------------------------------------------------------*/ +static void *CSRBaseAddress; + +static irqreturn_t mtk_pci_interrupt(int irq, void *dev_instance) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + prGlueInfo = (struct GLUE_INFO *) dev_instance; + if (!prGlueInfo) { + DBGLOG(HAL, INFO, "No glue info in mtk_pci_interrupt()\n"); + return IRQ_NONE; + } + + halDisableInterrupt(prGlueInfo->prAdapter); + + if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { + DBGLOG(HAL, INFO, "GLUE_FLAG_HALT skip INT\n"); + return IRQ_NONE; + } + + kalSetIntEvent(prGlueInfo); + + return IRQ_HANDLED; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is a PCIE probe function + * + * \param[in] func pointer to PCIE handle + * \param[in] id pointer to PCIE device id table + * + * \return void + */ +/*----------------------------------------------------------------------------*/ +static int mtk_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) +{ + int ret = 0; + struct mt66xx_chip_info *prChipInfo; + + ASSERT(pdev); + ASSERT(id); + + ret = pci_enable_device(pdev); + + if (ret) { + DBGLOG(INIT, INFO, "pci_enable_device failed!\n"); + goto out; + } + +#if defined(SOC3_0) + if ((void *)&mt66xx_driver_data_soc3_0 == (void *)id->driver_data) + DBGLOG(INIT, INFO, + "[MJ]&mt66xx_driver_data_soc3_0 == id->driver_data\n"); +#endif + + DBGLOG(INIT, INFO, "pci_enable_device done!\n"); + + prChipInfo = ((struct mt66xx_hif_driver_data *) + id->driver_data)->chip_info; + prChipInfo->pdev = (void *)pdev; + +#if (CFG_POWER_ON_DOWNLOAD_EMI_ROM_PATCH == 1) + g_fgDriverProbed = TRUE; + g_u4DmaMask = prChipInfo->bus_info->u4DmaMask; +#else + if (pfWlanProbe((void *) pdev, + (void *) id->driver_data) != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, INFO, "pfWlanProbe fail!call pfWlanRemove()\n"); + pfWlanRemove(); + ret = -1; + } else { + g_fgDriverProbed = TRUE; + g_u4DmaMask = prChipInfo->bus_info->u4DmaMask; + } +#endif + +out: + DBGLOG(INIT, INFO, "mtk_pci_probe() done(%d)\n", ret); + + return ret; +} + +static void mtk_pci_remove(struct pci_dev *pdev) +{ + ASSERT(pdev); + + if (g_fgDriverProbed) + pfWlanRemove(); + DBGLOG(INIT, INFO, "pfWlanRemove done\n"); + + /* Unmap CSR base address */ + iounmap(CSRBaseAddress); + + /* release memory region */ + pci_release_regions(pdev); + + pci_disable_device(pdev); + DBGLOG(INIT, INFO, "mtk_pci_remove() done\n"); +} + +static int mtk_pci_suspend(struct pci_dev *pdev, pm_message_t state) +{ + return 0; +} + +int mtk_pci_resume(struct pci_dev *pdev) +{ + return 0; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function will register pci bus to the os + * + * \param[in] pfProbe Function pointer to detect card + * \param[in] pfRemove Function pointer to remove card + * + * \return The result of registering pci bus + */ +/*----------------------------------------------------------------------------*/ +uint32_t glRegisterBus(probe_card pfProbe, remove_card pfRemove) +{ + int ret = 0; + + ASSERT(pfProbe); + ASSERT(pfRemove); + + pfWlanProbe = pfProbe; + pfWlanRemove = pfRemove; + + mtk_pci_driver.probe = mtk_pci_probe; + mtk_pci_driver.remove = mtk_pci_remove; + + mtk_pci_driver.suspend = mtk_pci_suspend; + mtk_pci_driver.resume = mtk_pci_resume; + + ret = (pci_register_driver(&mtk_pci_driver) == 0) ? + WLAN_STATUS_SUCCESS : WLAN_STATUS_FAILURE; + + return ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function will unregister pci bus to the os + * + * \param[in] pfRemove Function pointer to remove card + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void glUnregisterBus(remove_card pfRemove) +{ + if (g_fgDriverProbed) { + pfRemove(); + g_fgDriverProbed = FALSE; + } + pci_unregister_driver(&mtk_pci_driver); +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function stores hif related info, which is initialized before. + * + * \param[in] prGlueInfo Pointer to glue info structure + * \param[in] u4Cookie Pointer to UINT_32 memory base variable for _HIF_HPI + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void glSetHifInfo(struct GLUE_INFO *prGlueInfo, unsigned long ulCookie) +{ + struct GL_HIF_INFO *prHif = NULL; + struct HIF_MEM_OPS *prMemOps; + + prHif = &prGlueInfo->rHifInfo; + + prHif->pdev = (struct pci_dev *)ulCookie; + prMemOps = &prHif->rMemOps; + prHif->prDmaDev = prHif->pdev; + + prHif->CSRBaseAddress = CSRBaseAddress; + + pci_set_drvdata(prHif->pdev, prGlueInfo); + + SET_NETDEV_DEV(prGlueInfo->prDevHandler, &prHif->pdev->dev); + + prGlueInfo->u4InfType = MT_DEV_INF_PCIE; + + prMemOps->allocTxDesc = pcieAllocDesc; + prMemOps->allocRxDesc = pcieAllocDesc; + prMemOps->allocTxCmdBuf = NULL; + prMemOps->allocTxDataBuf = pcieAllocTxDataBuf; + prMemOps->allocRxBuf = pcieAllocRxBuf; + prMemOps->allocRuntimeMem = pcieAllocRuntimeMem; + prMemOps->copyCmd = pcieCopyCmd; + prMemOps->copyEvent = pcieCopyEvent; + prMemOps->copyTxData = pcieCopyTxData; + prMemOps->copyRxData = pcieCopyRxData; + prMemOps->mapTxBuf = pcieMapTxBuf; + prMemOps->mapRxBuf = pcieMapRxBuf; + prMemOps->unmapTxBuf = pcieUnmapTxBuf; + prMemOps->unmapRxBuf = pcieUnmapRxBuf; + prMemOps->freeDesc = pcieFreeDesc; + prMemOps->freeBuf = pcieFreeBuf; + prMemOps->freePacket = pcieFreePacket; + prMemOps->dumpTx = pcieDumpTx; + prMemOps->dumpRx = pcieDumpRx; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function clears hif related info. + * + * \param[in] prGlueInfo Pointer to glue info structure + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void glClearHifInfo(struct GLUE_INFO *prGlueInfo) +{ +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Initialize bus operation and hif related information, request + * resources. + * + * \param[out] pvData A pointer to HIF-specific data type buffer. + * For eHPI, pvData is a pointer to UINT_32 type and + * stores a mapped base address. + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +u_int8_t glBusInit(void *pvData) +{ + int ret = 0; + struct pci_dev *pdev = NULL; + + ASSERT(pvData); + + pdev = (struct pci_dev *)pvData; + + ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(g_u4DmaMask)); + if (ret != 0) { + DBGLOG(INIT, INFO, "set DMA mask failed!errno=%d\n", ret); + return FALSE; + } + + ret = pci_request_regions(pdev, pci_name(pdev)); + if (ret != 0) { + DBGLOG(INIT, INFO, + "Request PCI resource failed, errno=%d!\n", ret); + } + + /* map physical address to virtual address for accessing register */ + CSRBaseAddress = ioremap(pci_resource_start(pdev, 0), + pci_resource_len(pdev, 0)); + DBGLOG(INIT, INFO, "ioremap for device %s, region 0x%lX @ 0x%lX\n", + pci_name(pdev), (unsigned long) pci_resource_len(pdev, 0), + (unsigned long) pci_resource_start(pdev, 0)); + if (!CSRBaseAddress) { + DBGLOG(INIT, INFO, + "ioremap failed for device %s, region 0x%lX @ 0x%lX\n", + pci_name(pdev), + (unsigned long) pci_resource_len(pdev, 0), + (unsigned long) pci_resource_start(pdev, 0)); + goto err_out_free_res; + } + + /* Set DMA master */ + pci_set_master(pdev); + + return TRUE; + +err_out_free_res: + pci_release_regions(pdev); + + pci_disable_device(pdev); + + return FALSE; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Stop bus operation and release resources. + * + * \param[in] pvData A pointer to struct net_device. + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void glBusRelease(void *pvData) +{ +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Setup bus interrupt operation and interrupt handler for os. + * + * \param[in] pvData A pointer to struct net_device. + * \param[in] pfnIsr A pointer to interrupt handler function. + * \param[in] pvCookie Private data for pfnIsr function. + * + * \retval WLAN_STATUS_SUCCESS if success + * NEGATIVE_VALUE if fail + */ +/*----------------------------------------------------------------------------*/ +int32_t glBusSetIrq(void *pvData, void *pfnIsr, void *pvCookie) +{ + struct BUS_INFO *prBusInfo; + struct net_device *prNetDevice = NULL; + struct GLUE_INFO *prGlueInfo = NULL; + struct GL_HIF_INFO *prHifInfo = NULL; + struct pci_dev *pdev = NULL; + int ret = 0; + + ASSERT(pvData); + if (!pvData) + return -1; + + prNetDevice = (struct net_device *)pvData; + prGlueInfo = (struct GLUE_INFO *)pvCookie; + ASSERT(prGlueInfo); + if (!prGlueInfo) + return -1; + + prBusInfo = prGlueInfo->prAdapter->chip_info->bus_info; + + prHifInfo = &prGlueInfo->rHifInfo; + pdev = prHifInfo->pdev; + + prHifInfo->u4IrqId = pdev->irq; + ret = request_irq(prHifInfo->u4IrqId, mtk_pci_interrupt, + IRQF_SHARED, prNetDevice->name, prGlueInfo); + if (ret != 0) + DBGLOG(INIT, INFO, + "glBusSetIrq: request_irq ERROR(%d)\n", ret); + else if (prBusInfo->initPcieInt) + prBusInfo->initPcieInt(prGlueInfo); + + return ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Stop bus interrupt operation and disable interrupt handling for os. + * + * \param[in] pvData A pointer to struct net_device. + * \param[in] pvCookie Private data for pfnIsr function. + * + * \return (none) + */ +/*----------------------------------------------------------------------------*/ +void glBusFreeIrq(void *pvData, void *pvCookie) +{ + struct net_device *prNetDevice = NULL; + struct GLUE_INFO *prGlueInfo = NULL; + struct GL_HIF_INFO *prHifInfo = NULL; + struct pci_dev *pdev = NULL; + + ASSERT(pvData); + if (!pvData) { + DBGLOG(INIT, INFO, "%s null pvData\n", __func__); + return; + } + prNetDevice = (struct net_device *)pvData; + prGlueInfo = (struct GLUE_INFO *) pvCookie; + ASSERT(prGlueInfo); + if (!prGlueInfo) { + DBGLOG(INIT, INFO, "%s no glue info\n", __func__); + return; + } + + prHifInfo = &prGlueInfo->rHifInfo; + pdev = prHifInfo->pdev; + + synchronize_irq(pdev->irq); + free_irq(pdev->irq, prGlueInfo); +} + +u_int8_t glIsReadClearReg(uint32_t u4Address) +{ + return TRUE; +} + +void glSetPowerState(IN struct GLUE_INFO *prGlueInfo, IN uint32_t ePowerMode) +{ +} + +void glGetDev(void *ctx, struct device **dev) +{ + + *dev = &((struct pci_dev *)ctx)->dev; +} + +void glGetHifDev(struct GL_HIF_INFO *prHif, struct device **dev) +{ + *dev = &(prHif->pdev->dev); +} + +static void pcieAllocDesc(struct GL_HIF_INFO *prHifInfo, + struct RTMP_DMABUF *prDescRing, + uint32_t u4Num) +{ + dma_addr_t rAddr; + + prDescRing->AllocVa = KAL_DMA_ALLOC_COHERENT( + prHifInfo->prDmaDev, prDescRing->AllocSize, &rAddr); + prDescRing->AllocPa = (phys_addr_t)rAddr; + if (prDescRing->AllocVa) + memset(prDescRing->AllocVa, 0, prDescRing->AllocSize); +} + +static void pcieAllocTxDataBuf(struct MSDU_TOKEN_ENTRY *prToken, uint32_t u4Idx) +{ + prToken->prPacket = kalMemAlloc(prToken->u4DmaLength, PHY_MEM_TYPE); + prToken->rDmaAddr = 0; +} + +static void *pcieAllocRxBuf(struct GL_HIF_INFO *prHifInfo, + struct RTMP_DMABUF *prDmaBuf, + uint32_t u4Num, uint32_t u4Idx) +{ + struct sk_buff *pkt = dev_alloc_skb(prDmaBuf->AllocSize); + dma_addr_t rAddr; + + if (!pkt) { + DBGLOG(HAL, ERROR, "can't allocate rx %lu size packet\n", + prDmaBuf->AllocSize); + prDmaBuf->AllocPa = 0; + prDmaBuf->AllocVa = NULL; + return NULL; + } + + prDmaBuf->AllocVa = (void *)pkt->data; + memset(prDmaBuf->AllocVa, 0, prDmaBuf->AllocSize); + + rAddr = KAL_DMA_MAP_SINGLE(prHifInfo->prDmaDev, prDmaBuf->AllocVa, + prDmaBuf->AllocSize, KAL_DMA_FROM_DEVICE); + if (KAL_DMA_MAPPING_ERROR(prHifInfo->prDmaDev, rAddr)) { + DBGLOG(HAL, ERROR, "sk_buff dma mapping error!\n"); + dev_kfree_skb(pkt); + return NULL; + } + prDmaBuf->AllocPa = (phys_addr_t)rAddr; + return (void *)pkt; +} + +static void *pcieAllocRuntimeMem(uint32_t u4SrcLen) +{ + return kalMemAlloc(u4SrcLen, PHY_MEM_TYPE); +} + +static bool pcieCopyCmd(struct GL_HIF_INFO *prHifInfo, + struct RTMP_DMACB *prTxCell, void *pucBuf, + void *pucSrc1, uint32_t u4SrcLen1, + void *pucSrc2, uint32_t u4SrcLen2) +{ + dma_addr_t rAddr; + uint32_t u4TotalLen = u4SrcLen1 + u4SrcLen2; + + prTxCell->pBuffer = pucBuf; + + memcpy(pucBuf, pucSrc1, u4SrcLen1); + if (pucSrc2 != NULL && u4SrcLen2 > 0) + memcpy(pucBuf + u4SrcLen1, pucSrc2, u4SrcLen2); + rAddr = KAL_DMA_MAP_SINGLE(prHifInfo->prDmaDev, pucBuf, + u4TotalLen, KAL_DMA_TO_DEVICE); + if (KAL_DMA_MAPPING_ERROR(prHifInfo->prDmaDev, rAddr)) { + DBGLOG(HAL, ERROR, "KAL_DMA_MAP_SINGLE() error!\n"); + return false; + } + + prTxCell->PacketPa = (phys_addr_t)rAddr; + + return true; +} + +static bool pcieCopyEvent(struct GL_HIF_INFO *prHifInfo, + struct RTMP_DMACB *pRxCell, + struct RXD_STRUCT *pRxD, + struct RTMP_DMABUF *prDmaBuf, + uint8_t *pucDst, uint32_t u4Len) +{ + struct sk_buff *prSkb = NULL; + void *pRxPacket = NULL; + dma_addr_t rAddr; + + KAL_DMA_UNMAP_SINGLE(prHifInfo->prDmaDev, + (dma_addr_t)prDmaBuf->AllocPa, + prDmaBuf->AllocSize, KAL_DMA_FROM_DEVICE); + + pRxPacket = pRxCell->pPacket; + ASSERT(pRxPacket) + + prSkb = (struct sk_buff *)pRxPacket; + memcpy(pucDst, (uint8_t *)prSkb->data, u4Len); + + prDmaBuf->AllocVa = ((struct sk_buff *)pRxCell->pPacket)->data; + rAddr = KAL_DMA_MAP_SINGLE(prHifInfo->prDmaDev, prDmaBuf->AllocVa, + prDmaBuf->AllocSize, KAL_DMA_FROM_DEVICE); + if (KAL_DMA_MAPPING_ERROR(prHifInfo->prDmaDev, rAddr)) { + DBGLOG(HAL, ERROR, "KAL_DMA_MAP_SINGLE() error!\n"); + return false; + } + prDmaBuf->AllocPa = (phys_addr_t)rAddr; + return true; +} + +static bool pcieCopyTxData(struct MSDU_TOKEN_ENTRY *prToken, + void *pucSrc, uint32_t u4Len) +{ + memcpy(prToken->prPacket, pucSrc, u4Len); + return true; +} + +static bool pcieCopyRxData(struct GL_HIF_INFO *prHifInfo, + struct RTMP_DMACB *pRxCell, + struct RTMP_DMABUF *prDmaBuf, + struct SW_RFB *prSwRfb) +{ + void *pRxPacket = NULL; + dma_addr_t rAddr; + + pRxPacket = pRxCell->pPacket; + ASSERT(pRxPacket); + + pRxCell->pPacket = prSwRfb->pvPacket; + + KAL_DMA_UNMAP_SINGLE(prHifInfo->prDmaDev, + (dma_addr_t)prDmaBuf->AllocPa, + prDmaBuf->AllocSize, KAL_DMA_FROM_DEVICE); + prSwRfb->pvPacket = pRxPacket; + + prDmaBuf->AllocVa = ((struct sk_buff *)pRxCell->pPacket)->data; + rAddr = KAL_DMA_MAP_SINGLE(prHifInfo->prDmaDev, + prDmaBuf->AllocVa, prDmaBuf->AllocSize, KAL_DMA_FROM_DEVICE); + if (KAL_DMA_MAPPING_ERROR(prHifInfo->prDmaDev, rAddr)) { + DBGLOG(HAL, ERROR, "KAL_DMA_MAP_SINGLE() error!\n"); + ASSERT(0); + return false; + } + prDmaBuf->AllocPa = (phys_addr_t)rAddr; + + return true; +} + +static phys_addr_t pcieMapTxBuf(struct GL_HIF_INFO *prHifInfo, + void *pucBuf, uint32_t u4Offset, uint32_t u4Len) +{ + dma_addr_t rDmaAddr; + + rDmaAddr = KAL_DMA_MAP_SINGLE(prHifInfo->prDmaDev, pucBuf + u4Offset, + u4Len, KAL_DMA_TO_DEVICE); + if (KAL_DMA_MAPPING_ERROR(prHifInfo->prDmaDev, rDmaAddr)) { + DBGLOG(HAL, ERROR, "KAL_DMA_MAP_SINGLE() error!\n"); + return 0; + } + + return (phys_addr_t)rDmaAddr; +} + +static phys_addr_t pcieMapRxBuf(struct GL_HIF_INFO *prHifInfo, + void *pucBuf, uint32_t u4Offset, uint32_t u4Len) +{ + dma_addr_t rDmaAddr; + + rDmaAddr = KAL_DMA_MAP_SINGLE(prHifInfo->prDmaDev, pucBuf + u4Offset, + u4Len, KAL_DMA_FROM_DEVICE); + if (KAL_DMA_MAPPING_ERROR(prHifInfo->prDmaDev, rDmaAddr)) { + DBGLOG(HAL, ERROR, "KAL_DMA_MAP_SINGLE() error!\n"); + return 0; + } + + return (phys_addr_t)rDmaAddr; +} + +static void pcieUnmapTxBuf(struct GL_HIF_INFO *prHifInfo, + phys_addr_t rDmaAddr, uint32_t u4Len) +{ + KAL_DMA_UNMAP_SINGLE(prHifInfo->prDmaDev, + (dma_addr_t)rDmaAddr, + u4Len, KAL_DMA_TO_DEVICE); +} + +static void pcieUnmapRxBuf(struct GL_HIF_INFO *prHifInfo, + phys_addr_t rDmaAddr, uint32_t u4Len) +{ + KAL_DMA_UNMAP_SINGLE(prHifInfo->prDmaDev, + (dma_addr_t)rDmaAddr, + u4Len, KAL_DMA_FROM_DEVICE); +} + +static void pcieFreeDesc(struct GL_HIF_INFO *prHifInfo, + struct RTMP_DMABUF *prDescRing) +{ + if (prDescRing->AllocVa == NULL) + return; + + KAL_DMA_FREE_COHERENT(prHifInfo->prDmaDev, + prDescRing->AllocSize, + prDescRing->AllocVa, + (dma_addr_t)prDescRing->AllocPa); + memset(prDescRing, 0, sizeof(struct RTMP_DMABUF)); +} + +static void pcieFreeBuf(void *pucSrc, uint32_t u4Len) +{ + kalMemFree(pucSrc, PHY_MEM_TYPE, u4Len); +} + +static void pcieFreePacket(void *pvPacket) +{ + kalPacketFree(NULL, pvPacket); +} + +static void pcieDumpTx(struct GL_HIF_INFO *prHifInfo, + struct RTMP_TX_RING *prTxRing, + uint32_t u4Idx, uint32_t u4DumpLen) +{ + struct RTMP_DMACB *prTxCell; + void *prAddr = NULL; + + prTxCell = &prTxRing->Cell[u4Idx]; + + if (prTxCell->prToken) + prAddr = prTxCell->prToken->prPacket; + else + prAddr = prTxCell->pBuffer; + + if (prAddr) + DBGLOG_MEM32(HAL, INFO, prAddr, u4DumpLen); +} + +static void pcieDumpRx(struct GL_HIF_INFO *prHifInfo, + struct RTMP_RX_RING *prRxRing, + uint32_t u4Idx, uint32_t u4DumpLen) +{ + struct RTMP_DMACB *prRxCell; + struct RTMP_DMABUF *prDmaBuf; + + prRxCell = &prRxRing->Cell[u4Idx]; + prDmaBuf = &prRxCell->DmaBuf; + + if (!prRxCell->pPacket) + return; + + pcieUnmapRxBuf(prHifInfo, prDmaBuf->AllocPa, prDmaBuf->AllocSize); + + DBGLOG_MEM32(HAL, INFO, ((struct sk_buff *)prRxCell->pPacket)->data, + u4DumpLen); + + prDmaBuf->AllocPa = pcieMapRxBuf(prHifInfo, prDmaBuf->AllocVa, + 0, prDmaBuf->AllocSize); +} + +#if CFG_CHIP_RESET_SUPPORT +void kalRemoveProbe(IN struct GLUE_INFO *prGlueInfo) +{ + DBGLOG(INIT, WARN, "[SER][L0] not support...\n"); +} +#endif + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/sdio/arm.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/sdio/arm.c new file mode 100644 index 0000000000000000000000000000000000000000..7cbc34e29cdef6751cc0d82f42af191370f61e46 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/sdio/arm.c @@ -0,0 +1,62 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/****************************************************************************** +*[File] mt6516-evb.c +*[Version] v1.0 +*[Revision Date] 2010-03-01 +*[Author] +*[Description] +* dummy file for build system +*[Copyright] +* Copyright (C) 2010 MediaTek Incorporation. All Rights Reserved. +******************************************************************************/ + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/sdio/hal_api.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/sdio/hal_api.c new file mode 100644 index 0000000000000000000000000000000000000000..5b8d5edad2cecc01b8adf2cc7d030b392c58cace --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/sdio/hal_api.c @@ -0,0 +1,2940 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/****************************************************************************** +*[File] hif_api.c +*[Version] v1.0 +*[Revision Date] 2015-09-08 +*[Author] +*[Description] +* The program provides SDIO HIF APIs +*[Copyright] +* Copyright (C) 2015 MediaTek Incorporation. All Rights Reserved. +******************************************************************************/ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include "precomp.h" + +#if MTK_WCN_HIF_SDIO +#include "hif_sdio.h" +#else +#include +#include +#include +#include /* sdio_readl(), etc */ +#include +#endif + +#include +#ifndef CONFIG_X86 +#include +#endif + +#include "mt66xx_reg.h" + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ +#define RX_RESPONSE_TIMEOUT (3000) + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +/* + *TX Done Counter Layout + * + * enum HIF_TX_COUNT_IDX_T { + * + * /==== First WMM ====/ + * + * HIF_TXC_IDX_0, ==>AC0 PSE + * HIF_TXC_IDX_1, ==>AC1 PSE + * HIF_TXC_IDX_2, ==>AC2 PSE + * HIF_TXC_IDX_3, ==>AC3 PLE + * HIF_TXC_IDX_4, ==>CPU PSE + * HIF_TXC_IDX_5, ==>AC0 PLE + * HIF_TXC_IDX_6, ==>AC1 PLE + * HIF_TXC_IDX_7, ==>AC2 PLE + * HIF_TXC_IDX_8, ==>AC3 PLE + * + * /==== Second WMM ====/ + * + * HIF_TXC_IDX_9, ==>AC10, AC11 PSE + * HIF_TXC_IDX_10, ==> AC12 PSE + * HIF_TXC_IDX_11, ==>AC13 PSE + * HIF_TXC_IDX_12, ==>AC10, AC11 PLE + * HIF_TXC_IDX_13, ==>AC12 PLE + * HIF_TXC_IDX_14, ==>Reservec + * HIF_TXC_IDX_15, ==>AC13 PLE + * }; +*/ +#define HIF_TXC_IDX_2_TC_IDX_PSE(hif_idx) (hif_idx) +#define HIF_TXC_IDX_2_TC_IDX_PLE(hif_idx) (hif_idx - HIF_TXC_IDX_5) +#define TC_IDX_PSE_2_HIF_TXC_IDX(ucTc) (ucTc) +#define TC_IDX_PLE_2_HIF_TXC_IDX(ucTc) (ucTc + HIF_TXC_IDX_5) + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +/*----------------------------------------------------------------------------*/ +/*! +* @brief Verify the CHIP ID +* +* @param prAdapter a pointer to adapter private data structure. +* +* +* @retval TRUE CHIP ID is the same as the setting compiled +* @retval FALSE CHIP ID is different from the setting compiled +*/ +/*----------------------------------------------------------------------------*/ +u_int8_t halVerifyChipID(IN struct ADAPTER *prAdapter) +{ + uint32_t u4CIR = 0; + struct mt66xx_chip_info *prChipInfo; + + ASSERT(prAdapter); + + if (prAdapter->fgIsReadRevID) + return TRUE; + + HAL_MCR_RD(prAdapter, MCR_WCIR, &u4CIR); + + DBGLOG(INIT, TRACE, "Chip ID: 0x%lx\n", u4CIR & WCIR_CHIP_ID); + DBGLOG(INIT, TRACE, "Revision ID: 0x%lx\n", ((u4CIR & WCIR_REVISION_ID) >> 16)); + + prChipInfo = prAdapter->chip_info; + + if ((u4CIR & WCIR_CHIP_ID) != prChipInfo->chip_id) + return FALSE; + + prAdapter->ucRevID = (uint8_t) (((u4CIR & WCIR_REVISION_ID) >> 16) & 0xF); + prAdapter->fgIsReadRevID = TRUE; + + return TRUE; +} + +uint32_t +halRxWaitResponse(IN struct ADAPTER *prAdapter, IN uint8_t ucPortIdx, OUT uint8_t *pucRspBuffer, + IN uint32_t u4MaxRespBufferLen, OUT uint32_t *pu4Length) +{ + struct mt66xx_chip_info *prChipInfo; + uint32_t u4Value = 0, u4PktLen = 0, i = 0, u4CpyLen; + uint32_t u4Status = WLAN_STATUS_SUCCESS; + uint32_t u4Time, u4Current; + struct RX_CTRL *prRxCtrl; + struct WIFI_EVENT *prEvent; + + DEBUGFUNC("halRxWaitResponse"); + + ASSERT(prAdapter); + ASSERT(pucRspBuffer); + prChipInfo = prAdapter->chip_info; + + prRxCtrl = &prAdapter->rRxCtrl; + + u4Time = (uint32_t) kalGetTimeTick(); + + do { + /* Read the packet length */ + HAL_MCR_RD(prAdapter, MCR_WRPLR, &u4Value); + + if ((u4Value & 0xFFFF) != 0) { + u4PktLen = u4Value & 0xFFFF; + i = 0; + } else { + u4PktLen = (u4Value >> 16) & 0xFFFF; + i = 1; + } + + if (u4PktLen > u4MaxRespBufferLen) { + DBGLOG(RX, ERROR, "Packet length over buffer! Dump Response buffer, length = 0x%x\n", + *pu4Length); + prEvent = (struct WIFI_EVENT *) + (pucRspBuffer + prChipInfo->rxd_size); + DBGLOG(RX, ERROR, "RX EVENT: ID[0x%02X] SEQ[%u] LEN[%u]\n", + prEvent->ucEID, prEvent->ucSeqNum, prEvent->u2PacketLength); + DBGLOG_MEM8(RX, ERROR, pucRspBuffer, u4MaxRespBufferLen); + return WLAN_STATUS_FAILURE; + } + + if (u4PktLen == 0) { + /* timeout exceeding check */ + u4Current = (uint32_t) kalGetTimeTick(); + + if ((u4Current > u4Time) && ((u4Current - u4Time) > RX_RESPONSE_TIMEOUT)) { + DBGLOG(RX, ERROR, "Timeout! %d - %d = %d\n", u4Current, u4Time, (u4Current-u4Time)); + return WLAN_STATUS_FAILURE; + } else if (u4Current < u4Time && ((u4Current + (0xFFFFFFFF - u4Time)) > RX_RESPONSE_TIMEOUT)) { + DBGLOG(RX, ERROR, "Timeout! %d - %d = %d\n", + u4Current, u4Time, (u4Current + (0xFFFFFFFF - u4Time))); + return WLAN_STATUS_FAILURE; + } + + /* Response packet is not ready */ + kalUdelay(50); + } else { + +#if (CFG_ENABLE_READ_EXTRA_4_BYTES == 1) +#if CFG_SDIO_RX_AGG + /* decide copy length */ + if (u4PktLen > u4MaxRespBufferLen) + u4CpyLen = u4MaxRespBufferLen; + else + u4CpyLen = u4PktLen; + + /* read from SDIO to tmp. buffer */ + HAL_PORT_RD(prAdapter, i == 0 ? MCR_WRDR0 : MCR_WRDR1, + ALIGN_4(u4PktLen + 4), prRxCtrl->pucRxCoalescingBufPtr, + HIF_RX_COALESCING_BUFFER_SIZE); + + /* copy to destination buffer */ + kalMemCopy(pucRspBuffer, prRxCtrl->pucRxCoalescingBufPtr, u4CpyLen); + + /* update valid buffer count */ + u4PktLen = u4CpyLen; +#else +#error "Please turn on RX coalescing" +#endif +#else + HAL_PORT_RD(prAdapter, + i == 0 ? MCR_WRDR0 : MCR_WRDR1, u4PktLen, pucRspBuffer, u4MaxRespBufferLen); +#endif + *pu4Length = u4PktLen; + break; + } + } while (TRUE); + + return u4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! +* @brief enable global interrupt +* +* @param prAdapter pointer to the Adapter handler +* +* @return (none) +*/ +/*----------------------------------------------------------------------------*/ +void halEnableInterrupt(IN struct ADAPTER *prAdapter) +{ + u_int8_t fgIsIntEnableCache, fgIsPendingInt; + + ASSERT(prAdapter); + fgIsIntEnableCache = prAdapter->fgIsIntEnable; + /* Not to enable interrupt if there is pending interrupt */ + fgIsPendingInt = prAdapter->prGlueInfo->rHifInfo.fgIsPendingInt; + + if (!fgIsPendingInt) + prAdapter->fgIsIntEnable = TRUE; /* NOTE(Kevin): It must be placed before MCR GINT write. */ + + /* If need enable INT and also set LPOwn at the same time. */ + if (prAdapter->fgIsIntEnableWithLPOwnSet) { + prAdapter->fgIsIntEnableWithLPOwnSet = FALSE; /* NOTE(Kevin): It's better to place it + * before MCR GINT write. + */ + /* If INT was enabled, only set LPOwn */ + if (fgIsIntEnableCache) { + HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_SET); + prAdapter->fgIsFwOwn = TRUE; + } + /* If INT was not enabled, enable it and also set LPOwn now */ + else if (!fgIsPendingInt) { + HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_SET | WHLPCR_INT_EN_SET); + prAdapter->fgIsFwOwn = TRUE; + } + } + /* If INT was not enabled, enable it now */ + else if (!fgIsIntEnableCache && !fgIsPendingInt) + HAL_BYTE_WR(prAdapter, MCR_WHLPCR, WHLPCR_INT_EN_SET); + + if (fgIsPendingInt) + kalSetIntEvent(prAdapter->prGlueInfo); +} /* end of nicEnableInterrupt() */ + + +/*----------------------------------------------------------------------------*/ +/*! +* @brief disable global interrupt +* +* @param prAdapter pointer to the Adapter handler +* +* @return (none) +*/ +/*----------------------------------------------------------------------------*/ +void halDisableInterrupt(IN struct ADAPTER *prAdapter) +{ + + ASSERT(prAdapter); + + HAL_BYTE_WR(prAdapter, MCR_WHLPCR, WHLPCR_INT_EN_CLR); + + prAdapter->fgIsIntEnable = FALSE; + +} + + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This routine is used to process the POWER OFF procedure. +* +* \param[in] pvAdapter Pointer to the Adapter structure. +* +* \return (none) +*/ +/*----------------------------------------------------------------------------*/ +u_int8_t halSetDriverOwn(IN struct ADAPTER *prAdapter) +{ + u_int8_t fgStatus = TRUE; + uint32_t i, j, u4CurrTick = 0, u4WriteTick, u4WriteTickTemp; + u_int8_t fgTimeout; + u_int8_t fgResult; + u_int8_t fgReady = FALSE; + uint32_t u4DriverOwnTime = 0, u4Cr4ReadyTime = 0; + struct GL_HIF_INFO *prHifInfo; + u_int8_t fgWmtCoreDump = FALSE; + + ASSERT(prAdapter); + + KAL_ACQUIRE_MUTEX(prAdapter, MUTEX_SET_OWN); + + GLUE_INC_REF_CNT(prAdapter->u4PwrCtrlBlockCnt); + + if (prAdapter->fgIsFwOwn == FALSE) + goto unlock; + + prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + + DBGLOG(INIT, TRACE, "DRIVER OWN\n"); + + u4WriteTick = 0; + u4CurrTick = kalGetTimeTick(); + i = 0; + j = 0; + + glWakeupSdio(prAdapter->prGlueInfo); + + while (1) { + HAL_LP_OWN_RD(prAdapter, &fgResult); + + if (TIME_BEFORE(kalGetTimeTick(), u4CurrTick)) { /* To prevent timer wraparound */ + fgTimeout = + ((kalGetTimeTick() + (~u4CurrTick)) > LP_OWN_BACK_TOTAL_DELAY_MS) ? TRUE : FALSE; + } else { + fgTimeout = + ((kalGetTimeTick() - u4CurrTick) > LP_OWN_BACK_TOTAL_DELAY_MS) ? TRUE : FALSE; + } + + if (fgResult) { + prAdapter->fgIsFwOwn = FALSE; + prAdapter->u4OwnFailedCount = 0; + prAdapter->u4OwnFailedLogCount = 0; + + if (nicSerIsWaitingReset(prAdapter)) { + /* SER is done, start Tx/Rx */ + nicSerStartTxRx(prAdapter); + } + break; + } else if ((i > LP_OWN_BACK_FAILED_RETRY_CNT) && + (kalIsCardRemoved(prAdapter->prGlueInfo) || fgIsBusAccessFailed || fgTimeout + || wlanIsChipNoAck(prAdapter))) { + + /* For driver own back fail debug, get current PC value */ + halPrintMailbox(prAdapter); + halPollDbgCr(prAdapter, LP_OWN_BACK_FAILED_DBGCR_POLL_ROUND); + + if ((prAdapter->u4OwnFailedCount == 0) || + CHECK_FOR_TIMEOUT(u4CurrTick, prAdapter->rLastOwnFailedLogTime, + MSEC_TO_SYSTIME(LP_OWN_BACK_FAILED_LOG_SKIP_MS))) { + + DBGLOG(INIT, ERROR, + "LP cannot be own back, Timeout[%u](%ums), BusAccessError[%u]", + fgTimeout, kalGetTimeTick() - u4CurrTick, fgIsBusAccessFailed); + DBGLOG(INIT, ERROR, + "Resetting[%u], CardRemoved[%u] NoAck[%u] Cnt[%u] fgCoreDump[%u]\n", + kalIsResetting(), + kalIsCardRemoved(prAdapter->prGlueInfo), wlanIsChipNoAck(prAdapter), + prAdapter->u4OwnFailedCount, fgWmtCoreDump); + + DBGLOG(INIT, INFO, + "Skip LP own back failed log for next %ums\n", LP_OWN_BACK_FAILED_LOG_SKIP_MS); + + prAdapter->u4OwnFailedLogCount++; + if (prAdapter->u4OwnFailedLogCount > LP_OWN_BACK_FAILED_RESET_CNT) { + /* Trigger RESET */ + glSetRstReason(RST_DRV_OWN_FAIL); + GL_RESET_TRIGGER(prAdapter, + RST_FLAG_DO_CORE_DUMP); + } + GET_CURRENT_SYSTIME(&prAdapter->rLastOwnFailedLogTime); + } + + prAdapter->u4OwnFailedCount++; + fgStatus = FALSE; + break; + } + + u4WriteTickTemp = kalGetTimeTick(); + if ((i == 0) || TIME_AFTER(u4WriteTickTemp, (u4WriteTick + LP_OWN_REQ_CLR_INTERVAL_MS))) { + /* Driver get LP ownership per 200 ms, to avoid iteration time not accurate */ + HAL_LP_OWN_CLR(prAdapter, &fgResult); + u4WriteTick = u4WriteTickTemp; + } + + /* Delay for LP engine to complete its operation. */ + kalUsleep_range(LP_OWN_BACK_LOOP_DELAY_MIN_US, LP_OWN_BACK_LOOP_DELAY_MAX_US); + i++; + } + u4DriverOwnTime = ((kalGetTimeTick() >= u4CurrTick) ? + (kalGetTimeTick() - u4CurrTick) : (kalGetTimeTick() + (~u4CurrTick))); + + /* 1. Driver need to polling until CR4 ready, then could do normal Tx/Rx */ + /* 2. Send a dummy command to change data path to store-forward mode */ +#if 1 + if (prAdapter->fgIsFwDownloaded) { + const uint32_t ready_bits = prAdapter->chip_info->sw_ready_bits; + + DBGLOG(INIT, INFO, "halSetDriverOwn:: Check ready_bits(=0x%x)\n", ready_bits); + u4CurrTick = kalGetTimeTick(); + while (1) { + HAL_WIFI_FUNC_READY_CHECK(prAdapter, ready_bits/*WIFI_FUNC_READY_BITS*/, &fgReady); + + if (TIME_BEFORE(kalGetTimeTick(), u4CurrTick)) { /* To prevent timer wraparound */ + fgTimeout = + ((kalGetTimeTick() + (~u4CurrTick)) > LP_OWN_BACK_TOTAL_DELAY_MS) + ? TRUE : FALSE; + } else { + fgTimeout = + ((kalGetTimeTick() - u4CurrTick) > LP_OWN_BACK_TOTAL_DELAY_MS) + ? TRUE : FALSE; + } + + if (fgReady) { + break; + } else if (kalIsCardRemoved(prAdapter->prGlueInfo) || fgIsBusAccessFailed || fgTimeout + || wlanIsChipNoAck(prAdapter)) { + + /* For driver own back fail debug, get current PC value */ + halPrintMailbox(prAdapter); + halPollDbgCr(prAdapter, LP_OWN_BACK_FAILED_DBGCR_POLL_ROUND); + + DBGLOG(INIT, ERROR, + "Resetting[%u], CardRemoved[%u] NoAck[%u] Timeout[%u](%u - %u)ms, fgCoreDump[%u]\n", + kalIsResetting(), + kalIsCardRemoved(prAdapter->prGlueInfo), wlanIsChipNoAck(prAdapter), + fgTimeout, kalGetTimeTick(), u4CurrTick, fgWmtCoreDump); + + + DBGLOG(INIT, INFO, + "Skip waiting CR4 ready for next %ums\n", LP_OWN_BACK_FAILED_LOG_SKIP_MS); + fgStatus = FALSE; + + if (fgTimeout) { + /* Trigger RESET */ + glSetRstReason(RST_DRV_OWN_FAIL); + GL_RESET_TRIGGER(prAdapter, + RST_FLAG_DO_CORE_DUMP); + } + + break; + } + /* Delay for CR4 to complete its operation. */ + kalUsleep_range(LP_OWN_BACK_LOOP_DELAY_MIN_US, LP_OWN_BACK_LOOP_DELAY_MAX_US); + } + + halTagIntLog(prAdapter, SDIO_INT_DRV_OWN); + HAL_MCR_RD(prAdapter, MCR_D2HRM1R, &j); + + if (j == 0x77889901) { + + struct mt66xx_chip_info *prChipInfo = prAdapter->chip_info; + + if (halIsPendingTxDone(prAdapter)) { + /* Workaround for missing Tx done */ + halSerHifReset(prAdapter); + } + + /* fgIsWakeupFromDeepSleep */ + wlanSendDummyCmd(prAdapter, FALSE); + + /* Workaround for dummy command which is not count in Tx done count */ + if (prChipInfo->is_support_cr4) + prAdapter->prGlueInfo->rHifInfo.au4PendingTxDoneCount[TC4_INDEX]--; + halTagIntLog(prAdapter, SDIO_INT_WAKEUP_DSLP); + } + u4Cr4ReadyTime = ((kalGetTimeTick() >= u4CurrTick) ? + (kalGetTimeTick() - u4CurrTick) : (kalGetTimeTick() + (~u4CurrTick))); + } +#endif + + DBGLOG(NIC, INFO, "DRIVER OWN %d, %d, DSLP %s, count %d\n", + u4DriverOwnTime, u4Cr4ReadyTime, ((j == 0x77889901)?"1":"0"), i); + +unlock: + KAL_RELEASE_MUTEX(prAdapter, MUTEX_SET_OWN); + + return fgStatus; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This routine is used to process the POWER ON procedure. +* +* \param[in] pvAdapter Pointer to the Adapter structure. +* +* \return (none) +*/ +/*----------------------------------------------------------------------------*/ +void halSetFWOwn(IN struct ADAPTER *prAdapter, IN u_int8_t fgEnableGlobalInt) +{ + + u_int8_t fgResult; + struct GL_HIF_INFO *prHifInfo = NULL; + + ASSERT(prAdapter); + ASSERT(prAdapter->u4PwrCtrlBlockCnt != 0); + + KAL_ACQUIRE_MUTEX(prAdapter, MUTEX_SET_OWN); + + /* Decrease Block to Enter Low Power Semaphore count */ + GLUE_DEC_REF_CNT(prAdapter->u4PwrCtrlBlockCnt); + + prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + + if (prAdapter->u4PwrCtrlBlockCnt != 0) { + DBGLOG(INIT, INFO, "prAdapter->u4PwrCtrlBlockCnt = %d\n", + prAdapter->u4PwrCtrlBlockCnt); + goto unlock; + } + + if (prHifInfo->fgForceFwOwn == FALSE + && prAdapter->fgWiFiInSleepyState == FALSE) + goto unlock; + + if (prAdapter->fgIsFwOwn == TRUE) + goto unlock; + + if ((nicProcessIST(prAdapter) != WLAN_STATUS_NOT_INDICATING) && + !nicSerIsWaitingReset(prAdapter)) { + DBGLOG(INIT, INFO, "FW OWN Skipped due to pending INT\n"); + /* pending interrupts */ + goto unlock; + } + + if (fgEnableGlobalInt) { + prAdapter->fgIsIntEnableWithLPOwnSet = TRUE; + } else { + HAL_LP_OWN_SET(prAdapter, &fgResult); + + if (fgResult) { + /* if set firmware own not successful (possibly pending interrupts), */ + /* indicate an own clear event */ + HAL_LP_OWN_CLR(prAdapter, &fgResult); + } else { + prAdapter->fgIsFwOwn = TRUE; + + DBGLOG(INIT, INFO, "FW OWN\n"); + } + } + +unlock: + KAL_RELEASE_MUTEX(prAdapter, MUTEX_SET_OWN); +} + +void halWakeUpWiFi(IN struct ADAPTER *prAdapter) +{ + + u_int8_t fgResult; + + ASSERT(prAdapter); + + HAL_LP_OWN_RD(prAdapter, &fgResult); + + if (fgResult) + prAdapter->fgIsFwOwn = FALSE; + else + HAL_LP_OWN_CLR(prAdapter, &fgResult); +} + +void halDevInit(IN struct ADAPTER *prAdapter) +{ + uint32_t u4Value = 0; + + ASSERT(prAdapter); + +#if CFG_SDIO_INTR_ENHANCE + /* 4 <1> Check STATUS Buffer is DW alignment. */ + ASSERT(IS_ALIGN_4((unsigned long)&prAdapter->prGlueInfo->rHifInfo.prSDIOCtrl->u4WHISR)); + + /* 4 <2> Setup STATUS count. */ + { + HAL_MCR_RD(prAdapter, MCR_WHCR, &u4Value); + + /* 4 <2.1> Setup the number of maximum RX length to be report */ + u4Value &= ~(WHCR_MAX_HIF_RX_LEN_NUM); + u4Value |= ((SDIO_MAXIMUM_RX_LEN_NUM << WHCR_OFFSET_MAX_HIF_RX_LEN_NUM)); + + /* 4 <2.2> Setup RX enhancement mode */ +#if CFG_SDIO_RX_ENHANCE + u4Value |= WHCR_RX_ENHANCE_MODE_EN; +#else + u4Value &= ~WHCR_RX_ENHANCE_MODE_EN; +#endif /* CFG_SDIO_RX_AGG */ + + HAL_MCR_WR(prAdapter, MCR_WHCR, u4Value); + } +#endif /* CFG_SDIO_INTR_ENHANCE */ + + HAL_MCR_WR(prAdapter, MCR_WHIER, WHIER_DEFAULT); + + HAL_CFG_MAX_HIF_RX_LEN_NUM(prAdapter, HIF_RX_MAX_AGG_NUM); +} + +void halTxCancelSendingCmd(IN struct ADAPTER *prAdapter, IN struct CMD_INFO *prCmdInfo) +{ +} + +u_int8_t halTxIsDataBufEnough(IN struct ADAPTER *prAdapter, IN struct MSDU_INFO *prMsduInfo) +{ + return TRUE; +} + +uint8_t halTxRingDataSelect(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo) +{ + return 0; +} + +void halUpdateTxMaxQuota(IN struct ADAPTER *prAdapter) +{ +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Driver maintain a variable that is synchronous with the usage of individual +* TC Buffer Count. This function will calculate TC page count according to +* the given TX_STATUS COUNTER after TX Done. +* +* \param[in] prAdapter Pointer to the Adapter structure. +* \param[in] au2TxRlsCnt array of TX STATUS +* \param[in] au2FreeTcResource array of free & available resource count +* +* @return TRUE there are available resource to release +* @return FALSE no available resource to release +*/ +/*----------------------------------------------------------------------------*/ +u_int8_t halTxCalculateResource(IN struct ADAPTER *prAdapter, IN uint16_t *au2TxRlsCnt, OUT uint16_t *au2FreeTcResource) +{ + struct TX_TCQ_STATUS *prTcqStatus; + u_int8_t bStatus = FALSE; + uint8_t ucTcIdx; + uint32_t u4TotalTxDoneCnt = 0; + uint32_t u4TotalExtraTxDone = 0; + uint32_t au4UsedCnt[TC_NUM]; + uint32_t au4ExtraTxDone[TC_NUM]; + + uint32_t *au4TxDoneCnt; + uint32_t *au4PreUsedCnt; + uint32_t u4AvaliableCnt; + u_int8_t fgEnExtraTxDone; + + KAL_SPIN_LOCK_DECLARATION(); + + ASSERT(prAdapter); + prTcqStatus = &prAdapter->rTxCtrl.rTc; + + au4TxDoneCnt = prTcqStatus->au4TxDonePageCount; + au4PreUsedCnt = prTcqStatus->au4PreUsedPageCount; + u4AvaliableCnt = prTcqStatus->u4AvaliablePageCount; + fgEnExtraTxDone = prAdapter->rWifiVar.ucExtraTxDone; + + /* Get used page count */ + if (fgEnExtraTxDone) { + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); + for (ucTcIdx = TC0_INDEX; ucTcIdx < TC_NUM; ucTcIdx++) { + au4UsedCnt[ucTcIdx] = prTcqStatus->au4MaxNumOfPage[ucTcIdx] - + prTcqStatus->au4FreePageCount[ucTcIdx]; + } + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); + } + + /* Get Tx done & available page count */ + u4AvaliableCnt += au2TxRlsCnt[HIF_TX_FFA_INDEX]; + for (ucTcIdx = TC0_INDEX; ucTcIdx < TC_NUM; ucTcIdx++) { + + /* Get Tx done count from Tx interrupt status */ + au4TxDoneCnt[ucTcIdx] += au2TxRlsCnt[nicTxGetTxQByTc(prAdapter, ucTcIdx)]; + + /* Get available EXTRA Tx done */ + if (fgEnExtraTxDone) { + /* Release Tx done if there are pre-used resource */ + if (au4TxDoneCnt[ucTcIdx] >= au4PreUsedCnt[ucTcIdx]) { + au4TxDoneCnt[ucTcIdx] -= au4PreUsedCnt[ucTcIdx]; + au4PreUsedCnt[ucTcIdx] = 0; + } else { + au4PreUsedCnt[ucTcIdx] -= au4TxDoneCnt[ucTcIdx]; + au4TxDoneCnt[ucTcIdx] = 0; + } + + /* Calculate extra Tx done to share rest FFA resource */ + if (au4TxDoneCnt[ucTcIdx] >= au4UsedCnt[ucTcIdx]) { + au4TxDoneCnt[ucTcIdx] = au4UsedCnt[ucTcIdx]; + au4ExtraTxDone[ucTcIdx] = 0; + } else { + au4ExtraTxDone[ucTcIdx] = au4UsedCnt[ucTcIdx] - au4TxDoneCnt[ucTcIdx]; + } + u4TotalExtraTxDone += au4ExtraTxDone[ucTcIdx]; + } + + u4TotalTxDoneCnt += au4TxDoneCnt[ucTcIdx]; + + } + + DBGLOG(TX, TRACE, "TxDone result, FFA[%u] AC[%u:%u:%u:%u] CPU[%u]\n", + au2TxRlsCnt[HIF_TX_FFA_INDEX], au2TxRlsCnt[HIF_TX_AC0_INDEX], + au2TxRlsCnt[HIF_TX_AC1_INDEX], au2TxRlsCnt[HIF_TX_AC2_INDEX], + au2TxRlsCnt[HIF_TX_AC3_INDEX], au2TxRlsCnt[HIF_TX_CPU_INDEX]); + + DBGLOG(TX, TRACE, "TxDone Page count, TC[%u:%u:%u:%u:%u]\n", + au4TxDoneCnt[TC0_INDEX], au4TxDoneCnt[TC1_INDEX], au4TxDoneCnt[TC2_INDEX], + au4TxDoneCnt[TC3_INDEX], au4TxDoneCnt[TC4_INDEX]); + + /* Calculate free Tc page count */ + if (u4AvaliableCnt && u4TotalTxDoneCnt) { + /* Distribute resource by Tx done counter */ + if (u4AvaliableCnt >= u4TotalTxDoneCnt) { + /* Fulfill all TC resource */ + kalMemCopy(au2FreeTcResource, prTcqStatus->au4TxDonePageCount, + sizeof(prTcqStatus->au4TxDonePageCount)); + + kalMemZero(prTcqStatus->au4TxDonePageCount, sizeof(prTcqStatus->au4TxDonePageCount)); + + u4AvaliableCnt -= u4TotalTxDoneCnt; + } else { + /* Round-robin distribute resource */ + ucTcIdx = prTcqStatus->ucNextTcIdx; + while (u4AvaliableCnt) { + /* Enough resource, fulfill this TC */ + if (u4AvaliableCnt >= au4TxDoneCnt[ucTcIdx]) { + au2FreeTcResource[ucTcIdx] = au4TxDoneCnt[ucTcIdx]; + u4AvaliableCnt -= au4TxDoneCnt[ucTcIdx]; + au4TxDoneCnt[ucTcIdx] = 0; + + /* Round-robin get next TC */ + ucTcIdx++; + ucTcIdx %= TC_NUM; + } + /* no more resource, distribute rest of resource to this TC */ + else { + au2FreeTcResource[ucTcIdx] = u4AvaliableCnt; + au4TxDoneCnt[ucTcIdx] -= u4AvaliableCnt; + u4AvaliableCnt = 0; + } + } + prTcqStatus->ucNextTcIdx = ucTcIdx; + } + bStatus = TRUE; + } + + if (u4AvaliableCnt && u4TotalExtraTxDone && fgEnExtraTxDone) { + /* Distribute resource by EXTRA Tx done counter */ + if (u4AvaliableCnt >= u4TotalExtraTxDone) { + for (ucTcIdx = TC0_INDEX; ucTcIdx < TC_NUM; ucTcIdx++) { + au2FreeTcResource[ucTcIdx] += au4ExtraTxDone[ucTcIdx]; + au4PreUsedCnt[ucTcIdx] += au4ExtraTxDone[ucTcIdx]; + au4ExtraTxDone[ucTcIdx] = 0; + } + + u4AvaliableCnt -= u4TotalExtraTxDone; + } else { + /* Round-robin distribute resource */ + ucTcIdx = prTcqStatus->ucNextTcIdx; + while (u4AvaliableCnt) { + /* Enough resource, fulfill this TC */ + if (u4AvaliableCnt >= au4ExtraTxDone[ucTcIdx]) { + au2FreeTcResource[ucTcIdx] += au4ExtraTxDone[ucTcIdx]; + au4PreUsedCnt[ucTcIdx] += au4ExtraTxDone[ucTcIdx]; + u4AvaliableCnt -= au4ExtraTxDone[ucTcIdx]; + au4ExtraTxDone[ucTcIdx] = 0; + + /* Round-robin get next TC */ + ucTcIdx++; + ucTcIdx %= TC_NUM; + } + /* no more resource, distribute rest of resource to this TC */ + else { + au2FreeTcResource[ucTcIdx] += u4AvaliableCnt; + au4PreUsedCnt[ucTcIdx] += u4AvaliableCnt; + au4ExtraTxDone[ucTcIdx] -= u4AvaliableCnt; + u4AvaliableCnt = 0; + } + } + prTcqStatus->ucNextTcIdx = ucTcIdx; + } + bStatus = TRUE; + } + + prTcqStatus->u4AvaliablePageCount = u4AvaliableCnt; + + return bStatus; +} +u_int8_t halTxReleaseResource(IN struct ADAPTER *prAdapter, IN uint16_t *au2TxRlsCnt) +{ + struct TX_TCQ_STATUS *prTcqStatus; + u_int8_t bStatus = FALSE; + uint32_t i; + struct SDIO_STAT_COUNTER *prStatCnt; + uint16_t au2TxDoneCnt[HIF_TX_NUM] = { 0 }; + + ASSERT(prAdapter); + prTcqStatus = &prAdapter->rTxCtrl.rTc; + prStatCnt = &prAdapter->prGlueInfo->rHifInfo.rStatCounter; + + /* Update Free Tc resource counter */ + halTxGetFreeResource(prAdapter, au2TxDoneCnt, au2TxRlsCnt); + + /* Return free Tc page count */ + halTxReturnFreeResource(prAdapter, au2TxDoneCnt); + bStatus = TRUE; + + /* Update Statistic counter */ + prStatCnt->u4TxDonePendingPktCnt += nicTxGetMsduPendingCnt(prAdapter); + prStatCnt->u4TxDoneIntTotCnt++; + + for (i = HIF_TXC_IDX_0; i < HIF_TXC_IDX_NUM; i++) { + if (au2TxRlsCnt[i]) { + prStatCnt->u4TxDoneCnt[i] += au2TxRlsCnt[i]; + prStatCnt->u4TxDoneIntCnt[i]++; + } + } + + if (!nicTxSanityCheckResource(prAdapter)) + DBGLOG(TX, ERROR, "Tx Done INT result, FFA[%u] AC[%u:%u:%u:%u] CPU[%u]\n", + au2TxRlsCnt[HIF_TX_FFA_INDEX], au2TxRlsCnt[HIF_TX_AC0_INDEX], + au2TxRlsCnt[HIF_TX_AC1_INDEX], au2TxRlsCnt[HIF_TX_AC2_INDEX], + au2TxRlsCnt[HIF_TX_AC3_INDEX], au2TxRlsCnt[HIF_TX_CPU_INDEX]); + + DBGLOG(TX, LOUD, "TCQ Status Free Page <>:Buf[%u:%u, %u:%u, %u:%u, %u:%u, %u:%u]\n", + prTcqStatus->au4FreePageCount[TC0_INDEX], prTcqStatus->au4FreeBufferCount[TC0_INDEX], + prTcqStatus->au4FreePageCount[TC1_INDEX], prTcqStatus->au4FreeBufferCount[TC1_INDEX], + prTcqStatus->au4FreePageCount[TC2_INDEX], prTcqStatus->au4FreeBufferCount[TC2_INDEX], + prTcqStatus->au4FreePageCount[TC3_INDEX], prTcqStatus->au4FreeBufferCount[TC3_INDEX], + prTcqStatus->au4FreePageCount[TC4_INDEX], prTcqStatus->au4FreeBufferCount[TC4_INDEX]); + + + if (prAdapter->rTxCtrl.rTc.fgNeedPleCtrl) + DBGLOG(TX, LOUD, "TCQ Status Free Page <>:Buf[%u:%u, %u:%u, %u:%u, %u:%u, %u:%u]\n", + prTcqStatus->au4FreePageCount_PLE[TC0_INDEX], prTcqStatus->au4FreePageCount_PLE[TC0_INDEX], + prTcqStatus->au4FreePageCount_PLE[TC1_INDEX], prTcqStatus->au4FreePageCount_PLE[TC1_INDEX], + prTcqStatus->au4FreePageCount_PLE[TC2_INDEX], prTcqStatus->au4FreePageCount_PLE[TC2_INDEX], + prTcqStatus->au4FreePageCount_PLE[TC3_INDEX], prTcqStatus->au4FreePageCount_PLE[TC3_INDEX], + prTcqStatus->au4FreePageCount_PLE[TC4_INDEX], prTcqStatus->au4FreePageCount_PLE[TC4_INDEX]); + + return bStatus; +} + +uint32_t halTxPollingResource(IN struct ADAPTER *prAdapter, IN uint8_t ucTC) +{ + struct TX_CTRL *prTxCtrl; + uint32_t u4Status = WLAN_STATUS_RESOURCES; + uint32_t au4WTSR[8]; + struct GL_HIF_INFO *prHifInfo; + + prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + + prTxCtrl = &prAdapter->rTxCtrl; + + if (prHifInfo->fgIsPendingInt && (prHifInfo->prSDIOCtrl->u4WHISR & WHISR_TX_DONE_INT)) { + /* Get Tx done resource from pending interrupt status */ + kalMemCopy(au4WTSR, &prHifInfo->prSDIOCtrl->rTxInfo, sizeof(uint32_t) * 8); + + /* Clear pending Tx done interrupt */ + prHifInfo->prSDIOCtrl->u4WHISR &= ~WHISR_TX_DONE_INT; + } else + HAL_READ_TX_RELEASED_COUNT(prAdapter, au4WTSR); + + if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { + u4Status = WLAN_STATUS_FAILURE; + } else if (halTxReleaseResource(prAdapter, (uint16_t *) au4WTSR)) { + if (prTxCtrl->rTc.au4FreeBufferCount[ucTC] > 0) + u4Status = WLAN_STATUS_SUCCESS; + } + + return u4Status; +} + +void halTxInterruptSanityCheck(IN struct ADAPTER *prAdapter, IN uint16_t *au2TxRlsCnt) +{ + uint8_t ucIdx; + u_int8_t fgError = FALSE; + + if (prAdapter->rWifiVar.ucTxDbg & BIT(1)) { + for (ucIdx = HIF_TX_AC0_INDEX; ucIdx < HIF_TX_NUM; ucIdx++) { + if (au2TxRlsCnt[ucIdx] > prAdapter->rTxCtrl.u4TotalPageNum) + fgError = TRUE; + } + + if (fgError) + DBGLOG(TX, ERROR, "Tx Done INT result, FFA[%u] AC[%u:%u:%u:%u] CPU[%u]\n", + au2TxRlsCnt[HIF_TX_FFA_INDEX], au2TxRlsCnt[HIF_TX_AC0_INDEX], + au2TxRlsCnt[HIF_TX_AC1_INDEX], au2TxRlsCnt[HIF_TX_AC2_INDEX], + au2TxRlsCnt[HIF_TX_AC3_INDEX], au2TxRlsCnt[HIF_TX_CPU_INDEX]); + } +} + +#if CFG_SDIO_INTR_ENHANCE +void halProcessEnhanceInterruptStatus(IN struct ADAPTER *prAdapter) +{ + struct ENHANCE_MODE_DATA_STRUCT *prSDIOCtrl = prAdapter->prGlueInfo->rHifInfo.prSDIOCtrl; + + /* Set Tx done interrupt if there are Tx done count */ + if ((prSDIOCtrl->u4WHISR & WHISR_TX_DONE_INT) == 0 && + (prSDIOCtrl->rTxInfo.au4WTSR[0] | prSDIOCtrl->rTxInfo.au4WTSR[1] | + prSDIOCtrl->rTxInfo.au4WTSR[2] | prSDIOCtrl->rTxInfo.au4WTSR[3] | + prSDIOCtrl->rTxInfo.au4WTSR[4] | prSDIOCtrl->rTxInfo.au4WTSR[5] | + prSDIOCtrl->rTxInfo.au4WTSR[6] | prSDIOCtrl->rTxInfo.au4WTSR[7])) { + + prSDIOCtrl->u4WHISR |= WHISR_TX_DONE_INT; + } + + /* Set SW ASSERT INFO interrupt if there are pending mail box */ + if (((prSDIOCtrl->u4WHISR & WHISR_D2H_SW_ASSERT_INFO_INT) == 0) && + HAL_GET_MAILBOX_READ_CLEAR(prAdapter) && + (prSDIOCtrl->u4RcvMailbox0 || prSDIOCtrl->u4RcvMailbox1)) { + + prSDIOCtrl->u4WHISR |= WHISR_D2H_SW_ASSERT_INFO_INT; + } +} +#endif + +void halProcessTxInterrupt(IN struct ADAPTER *prAdapter) +{ + struct TX_CTRL *prTxCtrl; +#if CFG_SDIO_INTR_ENHANCE + struct ENHANCE_MODE_DATA_STRUCT *prSDIOCtrl; +#else + uint32_t au4TxCount[2]; +#endif /* CFG_SDIO_INTR_ENHANCE */ + SDIO_TIME_INTERVAL_DEC(); + + ASSERT(prAdapter); + + prTxCtrl = &prAdapter->rTxCtrl; + ASSERT(prTxCtrl); + + SDIO_REC_TIME_START(); + + /* Get the TX STATUS */ +#if CFG_SDIO_INTR_ENHANCE + + prSDIOCtrl = prAdapter->prGlueInfo->rHifInfo.prSDIOCtrl; +#if DBG + /* DBGLOG_MEM8(RX, TRACE, (PUINT_8)prSDIOCtrl, sizeof(SDIO_CTRL_T)); */ +#endif + + halTxInterruptSanityCheck(prAdapter, (uint16_t *)&prSDIOCtrl->rTxInfo); + halTxReleaseResource(prAdapter, (uint16_t *)&prSDIOCtrl->rTxInfo); + kalMemZero(&prSDIOCtrl->rTxInfo, sizeof(prSDIOCtrl->rTxInfo)); + +#else + + HAL_MCR_RD(prAdapter, MCR_WTSR0, &au4TxCount[0]); + HAL_MCR_RD(prAdapter, MCR_WTSR1, &au4TxCount[1]); + DBGLOG(EMU, TRACE, "MCR_WTSR0: 0x%x, MCR_WTSR1: 0x%x\n", au4TxCount[0], au4TxCount[1]); + + halTxReleaseResource(prAdapter, (uint8_t *) au4TxCount); + +#endif /* CFG_SDIO_INTR_ENHANCE */ + + nicTxAdjustTcq(prAdapter); + + SDIO_REC_TIME_END(); + SDIO_ADD_TIME_INTERVAL(prAdapter->prGlueInfo->rHifInfo.rStatCounter.u4TxDoneIntTime); + +} /* end of nicProcessTxInterrupt() */ + +#if !CFG_SDIO_INTR_ENHANCE +/*----------------------------------------------------------------------------*/ +/*! +* @brief Read the rx data from data port and setup RFB +* +* @param prAdapter pointer to the Adapter handler +* @param prSWRfb the RFB to receive rx data +* +* @retval WLAN_STATUS_SUCCESS: SUCCESS +* @retval WLAN_STATUS_FAILURE: FAILURE +* +*/ +/*----------------------------------------------------------------------------*/ +uint32_t halRxReadBuffer(IN struct ADAPTER *prAdapter, IN OUT struct SW_RFB *prSwRfb) +{ + struct RX_CTRL *prRxCtrl; + uint8_t *pucBuf; + void *prRxStatus; + uint32_t u4PktLen = 0, u4ReadBytes; + uint32_t u4Status = WLAN_STATUS_SUCCESS; + u_int8_t fgResult = TRUE; + uint32_t u4RegValue; + uint32_t rxNum; +#if CFG_TCP_IP_CHKSUM_OFFLOAD + uint32_t *pu4HwAppendDW; +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ + struct RX_DESC_OPS_T *prRxDescOps; + uint16_t u2RxByteCount = 0; + + DEBUGFUNC("halRxReadBuffer"); + + ASSERT(prAdapter); + ASSERT(prSwRfb); + + prRxCtrl = &prAdapter->rRxCtrl; + ASSERT(prRxCtrl); + + pucBuf = prSwRfb->pucRecvBuff; + prRxStatus = prSwRfb->prRxStatus; + + ASSERT(prRxStatus); + ASSERT(pucBuf); + prRxDescOps = prAdapter->chip_info->prRxDescOps; + ASSERT(prRxDescOps->nic_rxd_get_rx_byte_count); + ASSERT(prRxDescOps->nic_rxd_get_pkt_type); + ASSERT(prRxDescOps->nic_rxd_get_wlan_idx); + + u2RxByteCount = prRxDescOps->nic_rxd_get_rx_byte_count(prRxStatus); + do { + /* Read the RFB DW length and packet length */ + HAL_MCR_RD(prAdapter, MCR_WRPLR, &u4RegValue); + if (!fgResult) { + DBGLOG(RX, ERROR, "Read RX Packet Lentgh Error\n"); + return WLAN_STATUS_FAILURE; + } + /* 20091021 move the line to get the HIF RX header (for RX0/1) */ + if (u4RegValue == 0) { + DBGLOG(RX, ERROR, "No RX packet\n"); + return WLAN_STATUS_FAILURE; + } + + u4PktLen = u4RegValue & BITS(0, 15); + if (u4PktLen != 0) { + rxNum = 0; + } else { + rxNum = 1; + u4PktLen = (u4RegValue & BITS(16, 31)) >> 16; + } + + DBGLOG(RX, TRACE, "RX%d: u4PktLen = %d\n", rxNum, u4PktLen); + + /* 4 <4> Read Entire RFB and packet, include HW appended DW (Checksum Status) */ + u4ReadBytes = ALIGN_4(u4PktLen) + 4; + HAL_READ_RX_PORT(prAdapter, rxNum, u4ReadBytes, pucBuf, CFG_RX_MAX_PKT_SIZE); + + /* 20091021 move the line to get the HIF RX header */ + /* u4PktLen = (UINT_32)prHifRxHdr->u2PacketLen; */ + if (u4PktLen != (uint32_t) u2RxByteCount) { + DBGLOG(RX, ERROR, "Read u4PktLen = %d, prHifRxHdr->u2PacketLen: %d\n", + u4PktLen, + u2RxByteCount); +#if DBG + DBGLOG_MEM8(RX, TRACE, (uint8_t *) prRxStatus, + (u2RxByteCount > + 4096) ? 4096 : u2RxByteCount); +#endif + ASSERT(0); + } + /* u4PktLen is byte unit, not inlude HW appended DW */ + + prSwRfb->ucPacketType = + prRxDescOps->nic_rxd_get_pkt_type(prRxStatus); + DBGLOG(RX, TRACE, "ucPacketType = %d\n", prSwRfb->ucPacketType); + +#if CFG_TCP_IP_CHKSUM_OFFLOAD + pu4HwAppendDW = (uint32_t *) prRxStatus; + pu4HwAppendDW += (ALIGN_4(u2RxByteCount) >> 2); + prSwRfb->u4TcpUdpIpCksStatus = *pu4HwAppendDW; + DBGLOG(RX, TRACE, "u4TcpUdpIpCksStatus[0x%02x]\n", prSwRfb->u4TcpUdpIpCksStatus); +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ + + prSwRfb->ucStaRecIdx = + secGetStaIdxByWlanIdx( + prAdapter, + prRxDescOps->nic_rxd_get_wlan_idx(prRxStatus)); + + /* fgResult will be updated in MACRO */ + if (!fgResult) + return WLAN_STATUS_FAILURE; + + DBGLOG(RX, TRACE, "Dump RX buffer, length = 0x%x\n", u4ReadBytes); + DBGLOG_MEM8(RX, TRACE, pucBuf, u4ReadBytes); + } while (FALSE); + + return u4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! +* @brief Read frames from the data port, fill RFB +* and put each frame into the rReceivedRFBList queue. +* +* @param prAdapter Pointer to the Adapter structure. +* +* @return (none) +*/ +/*----------------------------------------------------------------------------*/ +void halRxSDIOReceiveRFBs(IN struct ADAPTER *prAdapter) +{ + struct RX_CTRL *prRxCtrl; + struct SW_RFB *prSwRfb = (struct SW_RFB *) NULL; + void *prRxStatus; + uint32_t u4HwAppendDW; + uint32_t *pu4Temp; + struct RX_DESC_OPS_T *prRxDescOps; + uint16_t u2RxByteCount; + + KAL_SPIN_LOCK_DECLARATION(); + + DEBUGFUNC("halRxSDIOReceiveRFBs"); + + ASSERT(prAdapter); + + prRxCtrl = &prAdapter->rRxCtrl; + ASSERT(prRxCtrl); + + prRxDescOps = prAdapter->chip_info->prRxDescOps; + ASSERT(prRxDescOps->nic_rxd_get_rx_byte_count); + do { + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_FREE_QUE); + QUEUE_REMOVE_HEAD(&prRxCtrl->rFreeSwRfbList, prSwRfb, struct SW_RFB *); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_FREE_QUE); + + if (!prSwRfb) { + DBGLOG(RX, TRACE, "No More RFB\n"); + break; + } + /* need to consider */ + if (halRxReadBuffer(prAdapter, prSwRfb) == WLAN_STATUS_FAILURE) { + DBGLOG(RX, TRACE, "halRxFillRFB failed\n"); + nicRxReturnRFB(prAdapter, prSwRfb); + break; + } + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); + QUEUE_INSERT_TAIL(&prRxCtrl->rReceivedRfbList, &prSwRfb->rQueEntry); + RX_INC_CNT(prRxCtrl, RX_MPDU_TOTAL_COUNT); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); + + prRxStatus = prSwRfb->prRxStatus; + ASSERT(prRxStatus); + + pu4Temp = (uint32_t *) prRxStatus; + u2RxByteCount = + prRxDescOps->nic_rxd_get_rx_byte_count(prRxStatus); + u4HwAppendDW = *(pu4Temp + (ALIGN_4(u2RxByteCount) >> 2)); + DBGLOG(RX, TRACE, "u4HwAppendDW = 0x%x\n", u4HwAppendDW); + DBGLOG(RX, TRACE, "u2PacketLen = 0x%x\n", u2RxByteCount); + } while (FALSE); + +} /* end of nicReceiveRFBs() */ + +#else +/*----------------------------------------------------------------------------*/ +/*! +* @brief Read frames from the data port, fill RFB +* and put each frame into the rReceivedRFBList queue. +* +* @param prAdapter Pointer to the Adapter structure. +* @param u4DataPort Specify which port to read +* @param u2RxLength Specify to the the rx packet length in Byte. +* @param prSwRfb the RFB to receive rx data. +* +* @return (none) +*/ +/*----------------------------------------------------------------------------*/ + +uint32_t +halRxEnhanceReadBuffer(IN struct ADAPTER *prAdapter, + IN uint32_t u4DataPort, IN uint16_t u2RxLength, IN OUT struct SW_RFB *prSwRfb) +{ + struct RX_CTRL *prRxCtrl; + uint8_t *pucBuf; + void *prRxStatus; + uint32_t u4PktLen = 0; + uint32_t u4Status = WLAN_STATUS_FAILURE; + u_int8_t fgResult = TRUE; +#if CFG_TCP_IP_CHKSUM_OFFLOAD + uint32_t *pu4HwAppendDW; +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ + struct RX_DESC_OPS_T *prRxDescOps; + + DEBUGFUNC("halRxEnhanceReadBuffer"); + + ASSERT(prAdapter); + ASSERT(prSwRfb); + + prRxCtrl = &prAdapter->rRxCtrl; + ASSERT(prRxCtrl); + + pucBuf = prSwRfb->pucRecvBuff; + ASSERT(pucBuf); + + prRxStatus = prSwRfb->prRxStatus; + ASSERT(prRxStatus); + + prRxDescOps = prAdapter->chip_info->prRxDescOps; + ASSERT(prRxDescOps->nic_rxd_get_rx_byte_count); + ASSERT(prRxDescOps->nic_rxd_get_pkt_type); + ASSERT(prRxDescOps->nic_rxd_get_wlan_idx); + + /* DBGLOG(RX, TRACE, ("u2RxLength = %d\n", u2RxLength)); */ + + do { + /* 4 <1> Read RFB frame from MCR_WRDR0, include HW appended DW */ + HAL_READ_RX_PORT(prAdapter, + u4DataPort, ALIGN_4(u2RxLength + HIF_RX_HW_APPENDED_LEN), pucBuf, CFG_RX_MAX_PKT_SIZE); + + if (!fgResult) { + DBGLOG(RX, ERROR, "Read RX Packet Lentgh Error\n"); + break; + } + + u4PktLen = (uint32_t)(prRxDescOps->nic_rxd_get_rx_byte_count( + prRxStatus)); + /* DBGLOG(RX, TRACE, ("u4PktLen = %d\n", u4PktLen)); */ + + prSwRfb->ucPacketType = (uint8_t) + prRxDescOps->nic_rxd_get_pkt_type(prRxStatus); + /* DBGLOG(RX, TRACE, ("ucPacketType = %d\n", prSwRfb->ucPacketType)); */ + + prSwRfb->ucStaRecIdx = + secGetStaIdxByWlanIdx( + prAdapter, + prRxDescOps->nic_rxd_get_wlan_idx(prRxStatus)); + + /* 4 <2> if the RFB dw size or packet size is zero */ + if (u4PktLen == 0) { + DBGLOG(RX, ERROR, "Packet Length = %u\n", + u4PktLen); + ASSERT(0); + break; + } + /* 4 <3> if the packet is too large or too small */ + /* ToDo[6630]: adjust CFG_RX_MAX_PKT_SIZE */ + if (u4PktLen > CFG_RX_MAX_PKT_SIZE) { + DBGLOG(RX, TRACE, "Read RX Packet Lentgh Error (%u)\n", + u4PktLen); + ASSERT(0); + break; + } + +#if CFG_TCP_IP_CHKSUM_OFFLOAD + pu4HwAppendDW = (uint32_t *) prRxStatus; + pu4HwAppendDW += (ALIGN_4(u4PktLen) >> 2); + prSwRfb->u4TcpUdpIpCksStatus = *pu4HwAppendDW; + DBGLOG(RX, TRACE, "u4TcpUdpIpCksStatus[0x%02x]\n", prSwRfb->u4TcpUdpIpCksStatus); +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ + + u4Status = WLAN_STATUS_SUCCESS; + } while (FALSE); + + DBGLOG_MEM8(RX, TRACE, pucBuf, ALIGN_4(u2RxLength + HIF_RX_HW_APPENDED_LEN)); + return u4Status; +} + +/*----------------------------------------------------------------------------*/ +/*! +* @brief Read frames from the data port for SDIO +* I/F, fill RFB and put each frame into the rReceivedRFBList queue. +* +* @param prAdapter Pointer to the Adapter structure. +* +* @return (none) +*/ +/*----------------------------------------------------------------------------*/ +void halRxSDIOEnhanceReceiveRFBs(IN struct ADAPTER *prAdapter) +{ + struct ENHANCE_MODE_DATA_STRUCT *prSDIOCtrl; + struct RX_CTRL *prRxCtrl; + struct SW_RFB *prSwRfb = (struct SW_RFB *) NULL; + uint32_t i, rxNum; + uint16_t u2RxPktNum, u2RxLength = 0, u2Tmp = 0; + + KAL_SPIN_LOCK_DECLARATION(); + + DEBUGFUNC("halRxSDIOEnhanceReceiveRFBs"); + + ASSERT(prAdapter); + + prSDIOCtrl = prAdapter->prGlueInfo->rHifInfo.prSDIOCtrl; + ASSERT(prSDIOCtrl); + + prRxCtrl = &prAdapter->rRxCtrl; + ASSERT(prRxCtrl); + + for (rxNum = 0; rxNum < 2; rxNum++) { + u2RxPktNum = + (rxNum == 0 ? prSDIOCtrl->rRxInfo.u.u2NumValidRx0Len : prSDIOCtrl->rRxInfo.u.u2NumValidRx1Len); + + if (u2RxPktNum == 0) + continue; + + for (i = 0; i < u2RxPktNum; i++) { + if (rxNum == 0) { + /* HAL_READ_RX_LENGTH */ + HAL_READ_RX_LENGTH(prAdapter, &u2RxLength, &u2Tmp); + } else if (rxNum == 1) { + /* HAL_READ_RX_LENGTH */ + HAL_READ_RX_LENGTH(prAdapter, &u2Tmp, &u2RxLength); + } + + if (!u2RxLength) + break; + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_FREE_QUE); + QUEUE_REMOVE_HEAD(&prRxCtrl->rFreeSwRfbList, prSwRfb, struct SW_RFB *); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_FREE_QUE); + + if (!prSwRfb) { + DBGLOG(RX, TRACE, "No More RFB\n"); + break; + } + ASSERT(prSwRfb); + + if (halRxEnhanceReadBuffer(prAdapter, rxNum, u2RxLength, prSwRfb) == WLAN_STATUS_FAILURE) { + DBGLOG(RX, TRACE, "nicRxEnhanceRxReadBuffer failed\n"); + nicRxReturnRFB(prAdapter, prSwRfb); + break; + } + /* prSDIOCtrl->au4RxLength[i] = 0; */ + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); + QUEUE_INSERT_TAIL(&prRxCtrl->rReceivedRfbList, &prSwRfb->rQueEntry); + RX_INC_CNT(prRxCtrl, RX_MPDU_TOTAL_COUNT); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); + } + } + + prSDIOCtrl->rRxInfo.u.u2NumValidRx0Len = 0; + prSDIOCtrl->rRxInfo.u.u2NumValidRx1Len = 0; + +} /* end of nicRxSDIOReceiveRFBs() */ + +#endif /* CFG_SDIO_INTR_ENHANCE */ + +#if CFG_SDIO_RX_AGG +/*----------------------------------------------------------------------------*/ +/*! +* @brief Read frames from the data port for SDIO with Rx aggregation enabled +* I/F, fill RFB and put each frame into the rReceivedRFBList queue. +* +* @param prAdapter Pointer to the Adapter structure. +* +* @return (none) +*/ +/*----------------------------------------------------------------------------*/ +void halRxSDIOAggReceiveRFBs(IN struct ADAPTER *prAdapter) +{ + struct ENHANCE_MODE_DATA_STRUCT *prEnhDataStr; + struct RX_CTRL *prRxCtrl; + uint32_t u4RxLength; + uint32_t i, rxNum; + uint32_t u4RxAggCount = 0, u4RxAggLength = 0; + uint32_t u4RxAvailAggLen; + uint8_t *pucSrcAddr; + uint16_t u2RxPktNum; + struct GL_HIF_INFO *prHifInfo; + struct SDIO_RX_COALESCING_BUF *prRxBuf; + u_int8_t fgNoFreeBuf = FALSE; + + SDIO_TIME_INTERVAL_DEC(); + + DEBUGFUNC("halRxSDIOAggReceiveRFBs"); + + ASSERT(prAdapter); + + prRxCtrl = &prAdapter->rRxCtrl; + prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + prEnhDataStr = prHifInfo->prSDIOCtrl; + + if (prEnhDataStr->rRxInfo.u.u2NumValidRx0Len == 0 && prEnhDataStr->rRxInfo.u.u2NumValidRx1Len == 0) + return; + + for (rxNum = 0; rxNum < 2; rxNum++) { + u2RxPktNum = (rxNum == 0 ? prEnhDataStr->rRxInfo.u.u2NumValidRx0Len : + prEnhDataStr->rRxInfo.u.u2NumValidRx1Len); + + if (u2RxPktNum > HIF_RX_MAX_AGG_NUM) { + halProcessAbnormalInterrupt(prAdapter); + GL_RESET_TRIGGER(prAdapter, RST_FLAG_DO_CORE_DUMP); + return; + } + + if (u2RxPktNum == 0) + continue; + +#if CFG_HIF_STATISTICS + prRxCtrl->u4TotalRxAccessNum++; + prRxCtrl->u4TotalRxPacketNum += u2RxPktNum; +#endif + + mutex_lock(&prHifInfo->rRxFreeBufQueMutex); + fgNoFreeBuf = QUEUE_IS_EMPTY(&prHifInfo->rRxFreeBufQueue); + mutex_unlock(&prHifInfo->rRxFreeBufQueMutex); + + if (fgNoFreeBuf) { + DBGLOG(RX, TRACE, "[%s] No free Rx buffer\n", __func__); + prHifInfo->rStatCounter.u4RxBufUnderFlowCnt++; + + if (prAdapter->prGlueInfo->ulFlag & GLUE_FLAG_HALT) { + struct QUE rTempQue; + struct QUE *prTempQue = &rTempQue; + + /* During halt state, move all pending Rx buffer to free queue */ + mutex_lock(&prHifInfo->rRxDeAggQueMutex); + QUEUE_MOVE_ALL(prTempQue, &prHifInfo->rRxDeAggQueue); + mutex_unlock(&prHifInfo->rRxDeAggQueMutex); + + mutex_lock(&prHifInfo->rRxFreeBufQueMutex); + QUEUE_CONCATENATE_QUEUES(&prHifInfo->rRxFreeBufQueue, prTempQue); + mutex_unlock(&prHifInfo->rRxFreeBufQueMutex); + } + + continue; + } + + u4RxAvailAggLen = HIF_RX_COALESCING_BUFFER_SIZE; +#if CFG_SDIO_RX_ENHANCE + u4RxAvailAggLen -= (sizeof(struct ENHANCE_MODE_DATA_STRUCT) + HIF_RX_ENHANCE_MODE_PAD_LEN); +#endif + u4RxAggCount = 0; + + for (i = 0; i < u2RxPktNum; i++) { + u4RxLength = (rxNum == 0 ? (uint32_t) prEnhDataStr->rRxInfo.u.au2Rx0Len[i] : + (uint32_t) prEnhDataStr->rRxInfo.u.au2Rx1Len[i]); + + if (!u4RxLength) { + DBGLOG(RX, ERROR, "[%s] RxLength == 0\n", __func__); + halProcessAbnormalInterrupt(prAdapter); + GL_RESET_TRIGGER(prAdapter, RST_FLAG_DO_CORE_DUMP); + return; + } + + if (ALIGN_4(u4RxLength + HIF_RX_HW_APPENDED_LEN) < u4RxAvailAggLen) { + u4RxAvailAggLen -= ALIGN_4(u4RxLength + HIF_RX_HW_APPENDED_LEN); + u4RxAggCount++; + } else { + /* CFG_RX_COALESCING_BUFFER_SIZE is not large enough */ + DBGLOG(RX, ERROR, "[%s] Request_len(%d) >= Available_len(%d)\n", + __func__, (ALIGN_4(u4RxLength + HIF_RX_HW_APPENDED_LEN)), u4RxAvailAggLen); + halProcessAbnormalInterrupt(prAdapter); + GL_RESET_TRIGGER(prAdapter, RST_FLAG_DO_CORE_DUMP); + return; + } + } + + mutex_lock(&prHifInfo->rRxFreeBufQueMutex); + QUEUE_REMOVE_HEAD(&prHifInfo->rRxFreeBufQueue, prRxBuf, struct SDIO_RX_COALESCING_BUF *); + mutex_unlock(&prHifInfo->rRxFreeBufQueMutex); + + prRxBuf->u4PktCount = u4RxAggCount; + + u4RxAggLength = (HIF_RX_COALESCING_BUFFER_SIZE - u4RxAvailAggLen); + + prRxBuf->u4PktTotalLength = u4RxAggLength - sizeof(struct ENHANCE_MODE_DATA_STRUCT); + + prRxBuf->u4IntLogIdx = prHifInfo->u4IntLogIdx; + + SDIO_REC_TIME_START(); + HAL_READ_RX_PORT(prAdapter, rxNum, u4RxAggLength, + prRxBuf->pvRxCoalescingBuf, HIF_RX_COALESCING_BUFFER_SIZE); + SDIO_REC_TIME_END(); + SDIO_ADD_TIME_INTERVAL(prHifInfo->rStatCounter.u4PortReadTime); + +#if CFG_SDIO_RX_ENHANCE + pucSrcAddr = prRxBuf->pvRxCoalescingBuf + u4RxAggLength - sizeof(struct ENHANCE_MODE_DATA_STRUCT); + + /* Sanity check of zero padding before interrupt status */ + if (((uint32_t)*(pucSrcAddr - HIF_RX_ENHANCE_MODE_PAD_LEN)) == 0) { + kalMemCopy(prHifInfo->prSDIOCtrl, pucSrcAddr, sizeof(struct ENHANCE_MODE_DATA_STRUCT)); + + halProcessEnhanceInterruptStatus(prAdapter); + + if (prHifInfo->prSDIOCtrl->u4WHISR) { + /* Interrupt status without Rx done */ + /* Mask Rx done interrupt to avoid recurrsion */ + uint32_t u4IntStatus = prHifInfo->prSDIOCtrl->u4WHISR & + (~(WHISR_RX0_DONE_INT | WHISR_RX1_DONE_INT)); + + if ((rxNum == 0) && prEnhDataStr->rRxInfo.u.u2NumValidRx1Len && u4IntStatus) { + /* Handle interrupt here if there are pending Rx port1 */ + + nicProcessIST_impl(prAdapter, u4IntStatus); + } else { + prAdapter->prGlueInfo->rHifInfo.fgIsPendingInt = TRUE; + } + } + } +#endif + halDeAggRxPkt(prAdapter, prRxBuf); + + /* Update statistic counter */ + prHifInfo->rStatCounter.u4PktReadCnt[rxNum] += u4RxAggCount; + prHifInfo->rStatCounter.u4PortReadCnt[rxNum]++; + } + +} +#endif /* CFG_SDIO_RX_AGG */ + + +void halProcessRxInterrupt(IN struct ADAPTER *prAdapter) +{ + if (prAdapter->prGlueInfo->rHifInfo.fgSkipRx) + return; + +#if CFG_SDIO_INTR_ENHANCE +#if CFG_SDIO_RX_AGG + halRxSDIOAggReceiveRFBs(prAdapter); +#else + halRxSDIOEnhanceReceiveRFBs(prAdapter); +#endif +#else + halRxSDIOReceiveRFBs(prAdapter); +#endif /* CFG_SDIO_INTR_ENHANCE */ +} + +bool halHifSwInfoInit(IN struct ADAPTER *prAdapter) +{ + return true; +} + +void halRxProcessMsduReport(IN struct ADAPTER *prAdapter, IN OUT struct SW_RFB *prSwRfb) +{ + +} + +uint32_t halTxGetPageCountPSE(IN struct ADAPTER *prAdapter, IN uint32_t u4FrameLength) +{ + uint32_t u4PageSize = prAdapter->rTxCtrl.u4PageSize; + + return ((u4FrameLength + prAdapter->nicTxReousrce.ucPpTxAddCnt + u4PageSize - 1)/u4PageSize); +} + +uint32_t halTxGetPageCount(IN struct ADAPTER *prAdapter, IN uint32_t u4FrameLength, IN u_int8_t fgIncludeDesc) +{ + struct mt66xx_chip_info *prChipInfo = prAdapter->chip_info; + + if (prChipInfo->is_support_cr4) + return 1; + + return halTxGetPageCountPSE(prAdapter, u4FrameLength); +} + +uint32_t halDumpHifStatus(IN struct ADAPTER *prAdapter, IN uint8_t *pucBuf, IN uint32_t u4Max) +{ + struct GLUE_INFO *prGlueInfo = prAdapter->prGlueInfo; + struct GL_HIF_INFO *prHifInfo = &prGlueInfo->rHifInfo; + struct SDIO_STAT_COUNTER *prStatCnt = &prHifInfo->rStatCounter; + uint32_t u4Len = 0; + uint32_t u4Idx; + + /* Print out counter */ + LOGBUF(pucBuf, u4Max, u4Len, "\n"); + LOGBUF(pucBuf, u4Max, u4Len, "------------\n"); + + LOGBUF(pucBuf, u4Max, u4Len, "Coalescing buffer size[%u] Rx Cnt[%u/%u] DeAgg[%u] UF Cnt[%u]\n", + prAdapter->u4CoalescingBufCachedSize, prHifInfo->rRxFreeBufQueue.u4NumElem, + HIF_RX_COALESCING_BUF_COUNT, prHifInfo->rRxDeAggQueue.u4NumElem, + prStatCnt->u4RxBufUnderFlowCnt); + + LOGBUF(pucBuf, u4Max, u4Len, "Pkt cnt Tx[%u] RxP0[%u] RxP1[%u] Tx/Rx ratio[%u.%u]\n", + prStatCnt->u4DataPktWriteCnt, prStatCnt->u4PktReadCnt[0], prStatCnt->u4PktReadCnt[1], + DIV2INT(prStatCnt->u4DataPktWriteCnt, prStatCnt->u4PktReadCnt[0]), + DIV2DEC(prStatCnt->u4DataPktWriteCnt, prStatCnt->u4PktReadCnt[0])); + + LOGBUF(pucBuf, u4Max, u4Len, "Tx pkt/wt[%u.%u] pkt/kick[%u.%u] cmd/wt[%u.%u]\n", + DIV2INT(prStatCnt->u4DataPktWriteCnt, prStatCnt->u4DataPortWriteCnt), + DIV2DEC(prStatCnt->u4DataPktWriteCnt, prStatCnt->u4DataPortWriteCnt), + DIV2INT(prStatCnt->u4DataPktWriteCnt, prStatCnt->u4DataPortKickCnt), + DIV2DEC(prStatCnt->u4DataPktWriteCnt, prStatCnt->u4DataPortKickCnt), + DIV2INT(prStatCnt->u4CmdPktWriteCnt, prStatCnt->u4CmdPortWriteCnt), + DIV2DEC(prStatCnt->u4CmdPktWriteCnt, prStatCnt->u4CmdPortWriteCnt)); + + LOGBUF(pucBuf, u4Max, u4Len, "Rx P0 pkt/rd[%u.%u] P1 pkt/rd[%u.%u]\n", + DIV2INT(prStatCnt->u4PktReadCnt[0], prStatCnt->u4PortReadCnt[0]), + DIV2DEC(prStatCnt->u4PktReadCnt[0], prStatCnt->u4PortReadCnt[0]), + DIV2INT(prStatCnt->u4PktReadCnt[1], prStatCnt->u4PortReadCnt[1]), + DIV2DEC(prStatCnt->u4PktReadCnt[1], prStatCnt->u4PortReadCnt[1])); + + LOGBUF(pucBuf, u4Max, u4Len, "Tx done pending cnt HIF_TXC00~04[%u, %u, %u, %u, %u]\n", + prHifInfo->au4PendingTxDoneCount[HIF_TXC_IDX_0], + prHifInfo->au4PendingTxDoneCount[HIF_TXC_IDX_1], + prHifInfo->au4PendingTxDoneCount[HIF_TXC_IDX_2], + prHifInfo->au4PendingTxDoneCount[HIF_TXC_IDX_3], + prHifInfo->au4PendingTxDoneCount[HIF_TXC_IDX_4]); + + LOGBUF(pucBuf, u4Max, u4Len, "Tx done pending cnt HIF_TXC05~09[%u, %u, %u, %u, %u]\n", + prHifInfo->au4PendingTxDoneCount[HIF_TXC_IDX_5], + prHifInfo->au4PendingTxDoneCount[HIF_TXC_IDX_6], + prHifInfo->au4PendingTxDoneCount[HIF_TXC_IDX_7], + prHifInfo->au4PendingTxDoneCount[HIF_TXC_IDX_8], + prHifInfo->au4PendingTxDoneCount[HIF_TXC_IDX_9]); + + LOGBUF(pucBuf, u4Max, u4Len, "Tx done pending cnt HIF_TXC10~15[%u, %u, %u, %u, %u, %u]\n", + prHifInfo->au4PendingTxDoneCount[HIF_TXC_IDX_10], + prHifInfo->au4PendingTxDoneCount[HIF_TXC_IDX_11], + prHifInfo->au4PendingTxDoneCount[HIF_TXC_IDX_12], + prHifInfo->au4PendingTxDoneCount[HIF_TXC_IDX_13], + prHifInfo->au4PendingTxDoneCount[HIF_TXC_IDX_14], + prHifInfo->au4PendingTxDoneCount[HIF_TXC_IDX_15]); + + + LOGBUF(pucBuf, u4Max, u4Len, "Tx done counter/int:\n"); + LOGBUF(pucBuf, u4Max, u4Len, "AC00~03[%u.%u, %u.%u, %u.%u, %u.%u]\n", + DIV2INT(prStatCnt->u4TxDoneCnt[0], prStatCnt->u4TxDoneIntCnt[0]), + DIV2DEC(prStatCnt->u4TxDoneCnt[0], prStatCnt->u4TxDoneIntCnt[0]), + DIV2INT(prStatCnt->u4TxDoneCnt[1], prStatCnt->u4TxDoneIntCnt[1]), + DIV2DEC(prStatCnt->u4TxDoneCnt[1], prStatCnt->u4TxDoneIntCnt[1]), + DIV2INT(prStatCnt->u4TxDoneCnt[2], prStatCnt->u4TxDoneIntCnt[2]), + DIV2DEC(prStatCnt->u4TxDoneCnt[2], prStatCnt->u4TxDoneIntCnt[2]), + DIV2INT(prStatCnt->u4TxDoneCnt[3], prStatCnt->u4TxDoneIntCnt[3]), + DIV2DEC(prStatCnt->u4TxDoneCnt[3], prStatCnt->u4TxDoneIntCnt[3])); + + LOGBUF(pucBuf, u4Max, u4Len, "AC10~13[%u.%u, %u.%u, %u.%u, %u.%u]\n", + DIV2INT(prStatCnt->u4TxDoneCnt[4], prStatCnt->u4TxDoneIntCnt[4]), + DIV2DEC(prStatCnt->u4TxDoneCnt[4], prStatCnt->u4TxDoneIntCnt[4]), + DIV2INT(prStatCnt->u4TxDoneCnt[5], prStatCnt->u4TxDoneIntCnt[5]), + DIV2DEC(prStatCnt->u4TxDoneCnt[5], prStatCnt->u4TxDoneIntCnt[5]), + DIV2INT(prStatCnt->u4TxDoneCnt[6], prStatCnt->u4TxDoneIntCnt[6]), + DIV2DEC(prStatCnt->u4TxDoneCnt[5], prStatCnt->u4TxDoneIntCnt[5]), + DIV2INT(prStatCnt->u4TxDoneCnt[7], prStatCnt->u4TxDoneIntCnt[7]), + DIV2DEC(prStatCnt->u4TxDoneCnt[7], prStatCnt->u4TxDoneIntCnt[7])); + + LOGBUF(pucBuf, u4Max, u4Len, "AC20~23[%u.%u, %u.%u, %u.%u, %u.%u] FFA,CPU[%u.%u, %u.%u]\n", + DIV2INT(prStatCnt->u4TxDoneCnt[8], prStatCnt->u4TxDoneIntCnt[8]), + DIV2DEC(prStatCnt->u4TxDoneCnt[8], prStatCnt->u4TxDoneIntCnt[8]), + DIV2INT(prStatCnt->u4TxDoneCnt[9], prStatCnt->u4TxDoneIntCnt[9]), + DIV2DEC(prStatCnt->u4TxDoneCnt[9], prStatCnt->u4TxDoneIntCnt[9]), + DIV2INT(prStatCnt->u4TxDoneCnt[10], prStatCnt->u4TxDoneIntCnt[10]), + DIV2DEC(prStatCnt->u4TxDoneCnt[10], prStatCnt->u4TxDoneIntCnt[10]), + DIV2INT(prStatCnt->u4TxDoneCnt[11], prStatCnt->u4TxDoneIntCnt[11]), + DIV2DEC(prStatCnt->u4TxDoneCnt[11], prStatCnt->u4TxDoneIntCnt[11]), + DIV2INT(prStatCnt->u4TxDoneCnt[14], prStatCnt->u4TxDoneIntCnt[14]), + DIV2DEC(prStatCnt->u4TxDoneCnt[14], prStatCnt->u4TxDoneIntCnt[14]), + DIV2INT(prStatCnt->u4TxDoneCnt[15], prStatCnt->u4TxDoneIntCnt[15]), + DIV2DEC(prStatCnt->u4TxDoneCnt[15], prStatCnt->u4TxDoneIntCnt[15])); + + LOGBUF(pucBuf, u4Max, u4Len, "Pending pkt/int[%u.%u] kick/int[%u.%u] rx_enh/sts[%u.%u]\n", + DIV2INT(prStatCnt->u4TxDonePendingPktCnt, prStatCnt->u4TxDoneIntTotCnt), + DIV2DEC(prStatCnt->u4TxDonePendingPktCnt, prStatCnt->u4TxDoneIntTotCnt), + DIV2INT(prStatCnt->u4DataPortKickCnt, prStatCnt->u4TxDoneIntTotCnt), + DIV2DEC(prStatCnt->u4DataPortKickCnt, prStatCnt->u4TxDoneIntTotCnt), + DIV2INT((prStatCnt->u4IntCnt - prStatCnt->u4IntReadCnt), prStatCnt->u4IntCnt), + DIV2DEC((prStatCnt->u4IntCnt - prStatCnt->u4IntReadCnt), prStatCnt->u4IntCnt)); + +#if CFG_SDIO_TIMING_PROFILING + LOGBUF(pucBuf, u4Max, u4Len, "Tx cp_t/pkt[%u.%uus] free/pkt[%u.%uus]\n", + DIV2INT(prStatCnt->u4TxDataCpTime, prStatCnt->u4DataPktWriteCnt), + DIV2DEC(prStatCnt->u4TxDataCpTime, prStatCnt->u4DataPktWriteCnt), + DIV2INT(prStatCnt->u4TxDataFreeTime, prStatCnt->u4DataPktWriteCnt), + DIV2DEC(prStatCnt->u4TxDataFreeTime, prStatCnt->u4DataPktWriteCnt)); + + LOGBUF(pucBuf, u4Max, u4Len, "Rx P0 cp_t/pkt[%u.%uus] avg read[%u.%uus]\n", + DIV2INT(prStatCnt->u4RxDataCpTime, prStatCnt->u4PktReadCnt[0]), + DIV2DEC(prStatCnt->u4RxDataCpTime, prStatCnt->u4PktReadCnt[0]), + DIV2INT(prStatCnt->u4PortReadTime, prStatCnt->u4PortReadCnt[0]), + DIV2DEC(prStatCnt->u4PortReadTime, prStatCnt->u4PortReadCnt[0])); + + LOGBUF(pucBuf, u4Max, u4Len, "INT rd_sts/sts[%u.%uus] tx_sts/sts[%u.%uus]\n", + DIV2INT(prStatCnt->u4IntReadTime, prStatCnt->u4IntReadCnt), + DIV2DEC(prStatCnt->u4IntReadTime, prStatCnt->u4IntReadCnt), + DIV2INT(prStatCnt->u4TxDoneIntTime, prStatCnt->u4TxDoneIntTotCnt), + DIV2DEC(prStatCnt->u4TxDoneIntTime, prStatCnt->u4TxDoneIntTotCnt)); +#endif + + LOGBUF(pucBuf, u4Max, u4Len, "---------------------------------\n"); + + for (u4Idx = 0; u4Idx < CFG_SDIO_INT_LOG_CNT; u4Idx++) { + struct SDIO_INT_LOG_T *prIntLog = &prHifInfo->arIntLog[u4Idx]; + struct ENHANCE_MODE_DATA_STRUCT *prIntSts = (struct ENHANCE_MODE_DATA_STRUCT *)&prIntLog->aucIntSts[0]; + uint8_t ucPktIdx; + + LOGBUF(pucBuf, u4Max, u4Len, "INT IDX[%u] STS[0x%08x] FG[0x%08x] Rx Pkt[%u] Sts0/1[%u:%u]\n", + prIntLog->u4Idx, prIntSts->u4WHISR, prIntLog->u4Flag, prIntLog->ucRxPktCnt, + prIntSts->rRxInfo.u.u2NumValidRx0Len, prIntSts->rRxInfo.u.u2NumValidRx1Len); + + if (prIntLog->ucRxPktCnt) { + LOGBUF(pucBuf, u4Max, u4Len, "RxDAggLen["); + for (ucPktIdx = 0; ucPktIdx < prIntLog->ucRxPktCnt; ucPktIdx++) + LOGBUF(pucBuf, u4Max, u4Len, "%4u:", prIntLog->au2RxPktLen[ucPktIdx]); + LOGBUF(pucBuf, u4Max, u4Len, "]\n"); + + LOGBUF(pucBuf, u4Max, u4Len, "RxDAggSn ["); + for (ucPktIdx = 0; ucPktIdx < prIntLog->ucRxPktCnt; ucPktIdx++) + LOGBUF(pucBuf, u4Max, u4Len, "0x%08x: ", prIntLog->au4RxPktInfo[ucPktIdx]); + LOGBUF(pucBuf, u4Max, u4Len, "]\n"); + } + + if (prIntSts->rRxInfo.u.u2NumValidRx0Len) { + LOGBUF(pucBuf, u4Max, u4Len, "Rx0StsLen["); + for (ucPktIdx = 0; ucPktIdx < prIntSts->rRxInfo.u.u2NumValidRx0Len; ucPktIdx++) + LOGBUF(pucBuf, u4Max, u4Len, "%4u:", prIntSts->rRxInfo.u.au2Rx0Len[ucPktIdx]); + LOGBUF(pucBuf, u4Max, u4Len, "]\n"); + } + + if (prIntSts->rRxInfo.u.u2NumValidRx1Len) { + LOGBUF(pucBuf, u4Max, u4Len, "Rx1StsLen["); + for (ucPktIdx = 0; ucPktIdx < HIF_RX_MAX_AGG_NUM; ucPktIdx++) + LOGBUF(pucBuf, u4Max, u4Len, "%4u:", prIntSts->rRxInfo.u.au2Rx1Len[ucPktIdx]); + LOGBUF(pucBuf, u4Max, u4Len, "]\n"); + } + } + + LOGBUF(pucBuf, u4Max, u4Len, "---------------------------------\n"); + + /* Reset statistic counter */ + kalMemZero(prStatCnt, sizeof(struct SDIO_STAT_COUNTER)); + + halDumpIntLog(prAdapter); + + return u4Len; +} + +#if (CFG_SDIO_ACCESS_N9_REGISTER_BY_MAILBOX == 1) +/*----------------------------------------------------------------------------*/ +/*! +* \brief +* This routine is used to get the value of N9 register +* by SDIO SW interrupt and mailbox. +* +* \param[in] +* pvAdapter: Pointer to the Adapter structure. +* addr: the interested address to be read +* prresult: to stored the value of the addr +* +* \return +* the error of the reading operation +*/ +/*----------------------------------------------------------------------------*/ + +u_int8_t halReadN9RegisterByMailBox(IN struct ADAPTER *prAdapter, IN uint32_t addr, IN uint32_t *prresult) +{ + uint32_t ori_whlpcr, temp, counter = 0; + u_int8_t err = TRUE, stop = FALSE; + + /* use polling mode */ + HAL_MCR_RD(prAdapter, MCR_WHLPCR, &ori_whlpcr); /* backup the original setting of W_INT_EN */ + ori_whlpcr &= WHLPCR_INT_EN_SET; + HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_INT_EN_CLR); /* disabel interrupt */ + + /* progrqm h2d mailbox0 as interested register address */ + HAL_MCR_WR(prAdapter, MCR_H2DSM0R, addr); + + /* set h2d interrupt to notify firmware (bit16) */ + HAL_MCR_WR(prAdapter, MCR_WSICR, SDIO_MAILBOX_FUNC_READ_REG_IDX); + + /* polling interrupt status for the returned result */ + while (!stop) { + HAL_MCR_RD(prAdapter, MCR_WHISR, &temp); /* read clear mode */ + if (temp & SDIO_MAILBOX_FUNC_READ_REG_IDX) { + /* get the result */ + + /* read d2h mailbox0 for interested register address */ + HAL_MCR_RD(prAdapter, MCR_D2HRM0R, &temp); + if (temp == addr) { + /* read d2h mailbox1 for the value of the register */ + HAL_MCR_RD(prAdapter, MCR_D2HRM1R, prresult); + err = FALSE; + } else { + DBGLOG(HAL, ERROR, "halReadN9RegisterByMailBox >> interested address is not correct.\n"); + } + stop = TRUE; + } else { +counter++; + +if (counter > 300000) { + DBGLOG(HAL, ERROR, "halReadN9RegisterByMailBox >> get response failure.\n"); + ASSERT(0); + break; + } + } + } + + HAL_MCR_WR(prAdapter, MCR_WHLPCR, ori_whlpcr); /* restore the W_INT_EN */ + + return err; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief +* This routine is used to write the value of N9 register by SDIO SW interrupt and mailbox. +* +* \param[in] +* pvAdapter: Pointer to the Adapter structure. +* addr: the interested address to be write +* value: the value to write into the addr +* +* \return +* the error of the write operation +*/ +/*----------------------------------------------------------------------------*/ + +u_int8_t halWriteN9RegisterByMailBox(IN struct ADAPTER *prAdapter, IN uint32_t addr, IN uint32_t value) +{ + uint32_t ori_whlpcr, temp, counter = 0; + u_int8_t err = TRUE, stop = FALSE; + + /* use polling mode */ + HAL_MCR_RD(prAdapter, MCR_WHLPCR, &ori_whlpcr); /* backup the original setting of W_INT_EN */ + ori_whlpcr &= WHLPCR_INT_EN_SET; + HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_INT_EN_CLR); /* disabel interrupt */ + + /* progrqm h2d mailbox0 as interested register address */ + HAL_MCR_WR(prAdapter, MCR_H2DSM0R, addr); + + /* progrqm h2d mailbox1 as the value to write */ + HAL_MCR_WR(prAdapter, MCR_H2DSM1R, value); + + /* set h2d interrupt to notify firmware (bit17) */ + HAL_MCR_WR(prAdapter, MCR_WSICR, SDIO_MAILBOX_FUNC_WRITE_REG_IDX); + + /* polling interrupt status for the returned result */ + while (!stop) { + HAL_MCR_RD(prAdapter, MCR_WHISR, &temp); /* read clear mode */ + + if (temp & SDIO_MAILBOX_FUNC_WRITE_REG_IDX) { + /* get the result */ + + /* read d2h mailbox0 for interested register address */ + HAL_MCR_RD(prAdapter, MCR_D2HRM0R, &temp); + if (temp == addr) + err = FALSE; + else { + DBGLOG(HAL, ERROR, "halWriteN9RegisterByMailBox >> "); + DBGLOG(HAL, ERROR, "interested address is not correct.\n"); + } + stop = TRUE; + } else { + counter++; + +if (counter > 300000) { + DBGLOG(HAL, ERROR, "halWriteN9RegisterByMailBox >> get response failure.\n"); + ASSERT(0); + break; + } + } + } + + HAL_MCR_WR(prAdapter, MCR_WHLPCR, ori_whlpcr); /* restore the W_INT_EN */ + + return err; +} +#endif + +u_int8_t halIsPendingRx(IN struct ADAPTER *prAdapter) +{ + return FALSE; +} + +uint32_t halGetValidCoalescingBufSize(IN struct ADAPTER *prAdapter) +{ + struct GL_HIF_INFO *prHifInfo; + uint32_t u4BufSize; +#if (MTK_WCN_HIF_SDIO == 0) + struct sdio_func *prSdioFunc; + uint32_t u4RuntimeMaxBuf; + +#endif + + prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + + if (HIF_TX_COALESCING_BUFFER_SIZE > HIF_RX_COALESCING_BUFFER_SIZE) + u4BufSize = HIF_TX_COALESCING_BUFFER_SIZE; + else + u4BufSize = HIF_RX_COALESCING_BUFFER_SIZE; + +#if (MTK_WCN_HIF_SDIO == 0) + prSdioFunc = prHifInfo->func; + + /* Check host capability */ + /* 1. Should less than host-max_req_size */ + if (u4BufSize > prSdioFunc->card->host->max_req_size) + u4BufSize = prSdioFunc->card->host->max_req_size; + + /* 2. Should less than runtime-blksize * host-blk_count */ + u4RuntimeMaxBuf = prSdioFunc->cur_blksize * + prSdioFunc->card->host->max_blk_count; + if (u4BufSize > u4RuntimeMaxBuf) + u4BufSize = u4RuntimeMaxBuf; + + DBGLOG(INIT, TRACE, "\n" + "Final buf : 0x%X\n" + "Default TX buf : 0x%X\n" + "Default RX buf : 0x%X\n" + "Host caps -\n" + "max_req_size : 0x%X\n" + "max_seg_size : 0x%X\n" + "max_segs : 0x%X\n" + "max_blk_size : 0x%X\n" + "max_blk_count : 0x%X\n" + "Runtime -\n" + "cur_blksize : 0x%X\n", + u4BufSize, + HIF_TX_COALESCING_BUFFER_SIZE, + HIF_RX_COALESCING_BUFFER_SIZE, + prSdioFunc->card->host->max_req_size, + prSdioFunc->card->host->max_seg_size, + prSdioFunc->card->host->max_segs, + prSdioFunc->card->host->max_blk_size, + prSdioFunc->card->host->max_blk_count, + prSdioFunc->cur_blksize); +#endif + + return u4BufSize; +} + +uint32_t halAllocateIOBuffer(IN struct ADAPTER *prAdapter) +{ + struct GL_HIF_INFO *prHifInfo; + uint8_t ucIdx; + struct SDIO_RX_COALESCING_BUF *prRxBuf; + + prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + + /* 4 <5> Memory for enhanced interrupt response */ + prHifInfo->prSDIOCtrl = (struct ENHANCE_MODE_DATA_STRUCT *) + kalAllocateIOBuffer(sizeof(struct ENHANCE_MODE_DATA_STRUCT)); + + if (prHifInfo->prSDIOCtrl == NULL) { + DBGLOG(HAL, ERROR, + "Could not allocate %d bytes for interrupt response.\n", + sizeof(struct ENHANCE_MODE_DATA_STRUCT)); + + return WLAN_STATUS_RESOURCES; + } + + /* Alloc coalescing buffer */ + for (ucIdx = 0; ucIdx < HIF_RX_COALESCING_BUF_COUNT; ucIdx++) { + prRxBuf = &prHifInfo->rRxCoalesingBuf[ucIdx]; + + prRxBuf->u4PktCount = 0; + + prRxBuf->u4BufSize = HIF_RX_COALESCING_BUFFER_SIZE; + prRxBuf->pvRxCoalescingBuf = kalAllocateIOBuffer(prRxBuf->u4BufSize); + if (!prRxBuf->pvRxCoalescingBuf) { + DBGLOG(HAL, ERROR, "Rx coalescing alloc failed!\n"); + continue; + } + + QUEUE_INSERT_TAIL(&prHifInfo->rRxFreeBufQueue, &prRxBuf->rQueEntry); + } + + return WLAN_STATUS_SUCCESS; +} + +uint32_t halReleaseIOBuffer(IN struct ADAPTER *prAdapter) +{ + struct GL_HIF_INFO *prHifInfo; + uint8_t ucIdx; + struct SDIO_RX_COALESCING_BUF *prRxBuf; + + prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + + /* Release coalescing buffer */ + for (ucIdx = 0; ucIdx < HIF_RX_COALESCING_BUF_COUNT; ucIdx++) { + prRxBuf = &prHifInfo->rRxCoalesingBuf[ucIdx]; + kalReleaseIOBuffer(prRxBuf->pvRxCoalescingBuf, prRxBuf->u4BufSize); + prRxBuf->pvRxCoalescingBuf = NULL; + } + + /* 4 <5> Memory for enhanced interrupt response */ + if (prHifInfo->prSDIOCtrl) { + kalReleaseIOBuffer((void *) prHifInfo->prSDIOCtrl, sizeof(struct ENHANCE_MODE_DATA_STRUCT)); + prHifInfo->prSDIOCtrl = (struct ENHANCE_MODE_DATA_STRUCT *) NULL; + } + + return WLAN_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief dump firmware Assert message +* +* \param[in] +* prAdapter +* +* \return +* TRUE +* FALSE +*/ +/*----------------------------------------------------------------------------*/ +void halPrintFirmwareAssertInfo(IN struct ADAPTER *prAdapter) +{ + uint32_t u4MailBox0, u4MailBox1; + uint32_t line = 0; + uint8_t aucAssertFile[7]; + /* UINT_32 u4ChipId; */ + +#if CFG_SDIO_INTR_ENHANCE + u4MailBox0 = prAdapter->prGlueInfo->rHifInfo.prSDIOCtrl->u4RcvMailbox0; + u4MailBox1 = prAdapter->prGlueInfo->rHifInfo.prSDIOCtrl->u4RcvMailbox1; +#else + halGetMailbox(prAdapter, 0, &u4MailBox0); + halGetMailbox(prAdapter, 1, &u4MailBox1); +#endif + + line = u4MailBox0 & 0x0000FFFF; + + u4MailBox0 = ((u4MailBox0 >> 16) & 0x0000FFFF); + + kalMemCopy(&aucAssertFile[0], &u4MailBox0, 2); + kalMemCopy(&aucAssertFile[2], &u4MailBox1, 4); + + aucAssertFile[6] = '\0'; + + LOG_FUNC("[%s][wifi][Firmware] Assert at \"%s\" #%u\n\n", + NIC_NAME, aucAssertFile, line); + +} + +void halPrintMailbox(IN struct ADAPTER *prAdapter) +{ + uint32_t u4MailBoxStatus0, u4MailBoxStatus1; + uint8_t fgResult; + + HAL_LP_OWN_RD(prAdapter, &fgResult); + if (fgResult != TRUE) + return; + + halGetMailbox(prAdapter, 0, &u4MailBoxStatus0); + halGetMailbox(prAdapter, 1, &u4MailBoxStatus1); + DBGFWLOG(INIT, ERROR, "MailBox Status = 0x%08X, 0x%08X\n", u4MailBoxStatus0, u4MailBoxStatus1); +} + +void halPrintIntStatus(IN struct ADAPTER *prAdapter) +{ +#if CFG_SDIO_INTR_ENHANCE + struct ENHANCE_MODE_DATA_STRUCT *prSDIOCtrl; + + prSDIOCtrl = prAdapter->prGlueInfo->rHifInfo.prSDIOCtrl; + ASSERT(prSDIOCtrl); + + DBGLOG_MEM32(REQ, WARN, prSDIOCtrl, sizeof(struct ENHANCE_MODE_DATA_STRUCT)); +#else + uint32_t u4IntStatus; + + HAL_MCR_RD(prAdapter, MCR_WHISR, u4IntStatus); + + DBGLOG(REQ, WARN, "INT status[0x%08x]\n", u4IntStatus); +#endif /* CFG_SDIO_INTR_ENHANCE */ +} + +void halDumpIntLog(IN struct ADAPTER *prAdapter) +{ + struct GL_HIF_INFO *prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + struct SDIO_INT_LOG_T *prIntLog; + struct ENHANCE_MODE_DATA_STRUCT *prIntSts; + uint32_t u4Idx; + + for (u4Idx = 0; u4Idx < CFG_SDIO_INT_LOG_CNT; u4Idx++) { + prIntLog = &prHifInfo->arIntLog[u4Idx]; + prIntSts = (struct ENHANCE_MODE_DATA_STRUCT *)&prIntLog->aucIntSts[0]; + + DBGLOG(INTR, ERROR, "INT IDX[%u] STS[0x%08x] FG[0x%08x] Rx Pkt[%u] Sts0/1[%u:%u]\n", + prIntLog->u4Idx, prIntSts->u4WHISR, prIntLog->u4Flag, prIntLog->ucRxPktCnt, + prIntSts->rRxInfo.u.u2NumValidRx0Len, prIntSts->rRxInfo.u.u2NumValidRx1Len); + DBGLOG_MEM32(INTR, ERROR, &prIntLog->au2RxPktLen[0], sizeof(uint16_t) * HIF_RX_MAX_AGG_NUM); + DBGLOG_MEM32(INTR, ERROR, &prIntLog->au4RxPktInfo[0], sizeof(uint32_t) * HIF_RX_MAX_AGG_NUM); + DBGLOG_MEM32(INTR, ERROR, prIntSts, sizeof(struct ENHANCE_MODE_DATA_STRUCT)); + } + + DBGLOG(INTR, ERROR, "---------------------------------\n"); +} + +void halTagIntLog(IN struct ADAPTER *prAdapter, IN enum HIF_SDIO_INT_STS eTag) +{ + struct GL_HIF_INFO *prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + + prHifInfo->arIntLog[prHifInfo->ucIntLogEntry].u4Flag |= BIT(eTag); +} + +void halRecIntLog(IN struct ADAPTER *prAdapter, IN struct ENHANCE_MODE_DATA_STRUCT *prSDIOCtrl) +{ + struct SDIO_INT_LOG_T *prIntLog; + uint8_t ucLogEntry; + struct GL_HIF_INFO *prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + + prHifInfo->u4IntLogIdx++; + ucLogEntry = prHifInfo->u4IntLogIdx % CFG_SDIO_INT_LOG_CNT; + prIntLog = &prHifInfo->arIntLog[ucLogEntry]; + kalMemZero(prIntLog, sizeof(struct SDIO_INT_LOG_T)); + + prIntLog->u4Idx = prHifInfo->u4IntLogIdx; + prHifInfo->ucIntLogEntry = ucLogEntry; + kalMemCopy(&prIntLog->aucIntSts[0], prSDIOCtrl, sizeof(struct ENHANCE_MODE_DATA_STRUCT)); +} + +struct SDIO_INT_LOG_T *halGetIntLog(IN struct ADAPTER *prAdapter, IN uint32_t u4Idx) +{ + struct GL_HIF_INFO *prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + + return &prHifInfo->arIntLog[u4Idx % CFG_SDIO_INT_LOG_CNT]; +} + +void halProcessAbnormalInterrupt(IN struct ADAPTER *prAdapter) +{ + uint32_t u4Data = 0; + uint8_t fgResult; + + HAL_LP_OWN_RD(prAdapter, &fgResult); + if (fgResult == TRUE) { + /* Need driver own */ + HAL_MCR_RD(prAdapter, MCR_WASR, &u4Data); + } + + halPollDbgCr(prAdapter, 5); + halPrintIntStatus(prAdapter); + + if (u4Data & (WASR_RX0_UNDER_FLOW | WASR_RX1_UNDER_FLOW)) { + DBGLOG(REQ, WARN, "Skip all SDIO Rx due to Rx underflow error!\n"); + prAdapter->prGlueInfo->rHifInfo.fgSkipRx = TRUE; + halDumpHifStatus(prAdapter, NULL, 0); + GL_RESET_TRIGGER(prAdapter, RST_FLAG_DO_CORE_DUMP); + } + + halDumpIntLog(prAdapter); +} + +void halProcessSoftwareInterrupt(IN struct ADAPTER *prAdapter) +{ + uint32_t u4IntrBits; + + ASSERT(prAdapter); + + u4IntrBits = prAdapter->u4IntStatus & BITS(8, 31); + + if ((u4IntrBits & WHISR_D2H_SW_ASSERT_INFO_INT) != 0) { + halPrintFirmwareAssertInfo(prAdapter); +#if CFG_CHIP_RESET_SUPPORT + glSendResetRequest(); +#endif + } + + if (u4IntrBits & WHISR_D2H_WKUP_BY_RX_PACKET) + DBGLOG(RX, INFO, "Wake up by Rx\n"); + + if (u4IntrBits & WHISR_D2H_SW_RD_MAILBOX_INT) + halPrintMailbox(prAdapter); + + if (u4IntrBits & SER_SDIO_N9_HOST_STOP_TX_OP) { + halPrintMailbox(prAdapter); + /* Stop HIF Tx operation */ + nicSerStopTx(prAdapter); + } + + if (u4IntrBits & SER_SDIO_N9_HOST_STOP_TX_RX_OP) { + halPrintMailbox(prAdapter); + /* Stop HIF Tx/Rx operation */ + nicSerStopTxRx(prAdapter); + } + + if ((u4IntrBits & ~WHISR_D2H_WKUP_BY_RX_PACKET) != 0) + DBGLOG(SW4, WARN, "u4IntrBits: 0x%08x\n", u4IntrBits); + +} /* end of halProcessSoftwareInterrupt() */ + +void halPutMailbox(IN struct ADAPTER *prAdapter, IN uint32_t u4MailboxNum, IN uint32_t u4Data) +{ + + switch (u4MailboxNum) { + case 0: + HAL_MCR_WR(prAdapter, MCR_H2DSM0R, u4Data); + break; + case 1: + HAL_MCR_WR(prAdapter, MCR_H2DSM1R, u4Data); + break; + + default: + ASSERT(0); + } + +} + +void halGetMailbox(IN struct ADAPTER *prAdapter, IN uint32_t u4MailboxNum, OUT uint32_t *pu4Data) +{ + switch (u4MailboxNum) { + case 0: + HAL_MCR_RD(prAdapter, MCR_D2HRM0R, pu4Data); + break; + case 1: + HAL_MCR_RD(prAdapter, MCR_D2HRM1R, pu4Data); + break; + + default: + ASSERT(0); + } +} + +u_int8_t halDeAggErrorCheck(struct ADAPTER *prAdapter, + struct SDIO_RX_COALESCING_BUF *prRxBuf, + uint8_t *pucPktAddr) +{ + struct mt66xx_chip_info *prChipInfo; + uint16_t u2PktLength = 0; + uint8_t *pucRxBufEnd; + struct RX_DESC_OPS_T *prRxDescOps; + + ASSERT(prAdapter); + prChipInfo = prAdapter->chip_info; + prRxDescOps = prChipInfo->prRxDescOps; + + pucRxBufEnd = (uint8_t *)prRxBuf->pvRxCoalescingBuf + prRxBuf->u4PktTotalLength; + + if (prRxDescOps->nic_rxd_get_rx_byte_count) + u2PktLength = + prRxDescOps->nic_rxd_get_rx_byte_count(pucPktAddr); + + /* Rx buffer boundary check */ + if ((pucPktAddr + ALIGN_4(u2PktLength + HIF_RX_HW_APPENDED_LEN)) >= pucRxBufEnd) + return TRUE; + + /* Rx packet min length check */ + if (u2PktLength <= prChipInfo->rxd_size) + return TRUE; + + /* Rx packet max length check */ + if (u2PktLength >= CFG_RX_MAX_PKT_SIZE) + return TRUE; + + return FALSE; +} + +void halDeAggRxPktWorker(struct work_struct *work) +{ + struct GLUE_INFO *prGlueInfo; + struct GL_HIF_INFO *prHifInfo; + struct ADAPTER *prAdapter; + struct SDIO_RX_COALESCING_BUF *prRxBuf; + uint32_t i; + struct QUE rTempFreeRfbList, rTempRxRfbList; + struct QUE *prTempFreeRfbList = &rTempFreeRfbList; + struct QUE *prTempRxRfbList = &rTempRxRfbList; + struct RX_CTRL *prRxCtrl; + struct SW_RFB *prSwRfb = (struct SW_RFB *) NULL; + uint8_t *pucSrcAddr; + uint16_t u2PktLength; + u_int8_t fgReschedule = FALSE; +#if CFG_TCP_IP_CHKSUM_OFFLOAD + uint32_t *pu4HwAppendDW; +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ + u_int8_t fgDeAggErr = FALSE; + struct SDIO_INT_LOG_T *prIntLog; + uint64_t u8Current = 0; + struct RX_DESC_OPS_T *prRxDescOps; + + KAL_SPIN_LOCK_DECLARATION(); + SDIO_TIME_INTERVAL_DEC(); + + if (g_u4HaltFlag) + return; + + prGlueInfo = ENTRY_OF(work, struct GLUE_INFO, rRxPktDeAggWork); + prHifInfo = &prGlueInfo->rHifInfo; + prAdapter = prGlueInfo->prAdapter; + prRxDescOps = prAdapter->chip_info->prRxDescOps; + ASSERT(prRxDescOps->nic_rxd_get_rx_byte_count); + ASSERT(prRxDescOps->nic_rxd_get_pkt_type); + + if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) + return; + + prRxCtrl = &prAdapter->rRxCtrl; + prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + + QUEUE_INITIALIZE(prTempFreeRfbList); + QUEUE_INITIALIZE(prTempRxRfbList); + + mutex_lock(&prHifInfo->rRxDeAggQueMutex); + QUEUE_REMOVE_HEAD(&prHifInfo->rRxDeAggQueue, prRxBuf, struct SDIO_RX_COALESCING_BUF *); + mutex_unlock(&prHifInfo->rRxDeAggQueMutex); + while (prRxBuf) { + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_FREE_QUE); + if (prRxCtrl->rFreeSwRfbList.u4NumElem < prRxBuf->u4PktCount) { + fgReschedule = TRUE; + } else { + /* Get enough free SW_RFB to be Rx */ + for (i = 0; i < prRxBuf->u4PktCount; i++) { + QUEUE_REMOVE_HEAD(&prRxCtrl->rFreeSwRfbList, prSwRfb, struct SW_RFB *); + QUEUE_INSERT_TAIL(prTempFreeRfbList, &prSwRfb->rQueEntry); + } + fgReschedule = FALSE; + } + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_FREE_QUE); + + if (fgReschedule) { + mutex_lock(&prHifInfo->rRxDeAggQueMutex); + QUEUE_INSERT_HEAD(&prHifInfo->rRxDeAggQueue, (struct QUE_ENTRY *)prRxBuf); + mutex_unlock(&prHifInfo->rRxDeAggQueMutex); + + /* Reschedule this work */ + if ((prGlueInfo->ulFlag & GLUE_FLAG_HALT) == 0) + schedule_delayed_work(&prAdapter->prGlueInfo->rRxPktDeAggWork, 0); + + return; + } + + pucSrcAddr = prRxBuf->pvRxCoalescingBuf; + fgDeAggErr = FALSE; + + prIntLog = halGetIntLog(prAdapter, prRxBuf->u4IntLogIdx); + u8Current = sched_clock(); + + SDIO_REC_TIME_START(); + for (i = 0; i < prRxBuf->u4PktCount; i++) { + /* Rx de-aggregation check */ + if (halDeAggErrorCheck(prAdapter, prRxBuf, + pucSrcAddr)) { + fgDeAggErr = TRUE; + break; + } + + u2PktLength = prRxDescOps->nic_rxd_get_rx_byte_count( + pucSrcAddr); + + prIntLog->au2RxPktLen[i] = u2PktLength; + + QUEUE_REMOVE_HEAD(prTempFreeRfbList, prSwRfb, struct SW_RFB *); + kalMemCopy(prSwRfb->pucRecvBuff, pucSrcAddr, ALIGN_4(u2PktLength + HIF_RX_HW_APPENDED_LEN)); + + prSwRfb->ucPacketType = + prRxDescOps->nic_rxd_get_pkt_type(pucSrcAddr); + +#if CFG_TCP_IP_CHKSUM_OFFLOAD + pu4HwAppendDW = (uint32_t *) prSwRfb->prRxStatus; + pu4HwAppendDW += (ALIGN_4(u2PktLength) >> 2); + prSwRfb->u4TcpUdpIpCksStatus = *pu4HwAppendDW; + DBGLOG(RX, TRACE, "u4TcpUdpIpCksStatus[0x%02x]\n", prSwRfb->u4TcpUdpIpCksStatus); +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ + + kalMemCopy(&prIntLog->au4RxPktInfo[i], pucSrcAddr + ALIGN_4(u2PktLength), sizeof(uint32_t)); + + GLUE_RX_SET_PKT_INT_TIME(prSwRfb->pvPacket, prAdapter->prGlueInfo->u8HifIntTime); + + GLUE_RX_SET_PKT_RX_TIME(prSwRfb->pvPacket, u8Current); + + QUEUE_INSERT_TAIL(prTempRxRfbList, &prSwRfb->rQueEntry); + + pucSrcAddr += ALIGN_4(u2PktLength + HIF_RX_HW_APPENDED_LEN); + } + SDIO_REC_TIME_END(); + SDIO_ADD_TIME_INTERVAL(prHifInfo->rStatCounter.u4RxDataCpTime); + + prIntLog->ucRxPktCnt = i; + + if (fgDeAggErr) { + /* Rx de-aggregation error */ + /* Dump current Rx buffer */ + DBGLOG(RX, ERROR, "Rx de-aggregation error!, INT sts: total len[%u] pkt cnt[%u]\n", + prRxBuf->u4PktTotalLength, prRxBuf->u4PktCount); + DBGLOG_MEM32(RX, ERROR, prRxBuf->pvRxCoalescingBuf, prRxBuf->u4PktTotalLength); + + halDumpIntLog(prAdapter); + + /* Free all de-aggregated SwRfb */ + QUEUE_CONCATENATE_QUEUES(prTempFreeRfbList, prTempRxRfbList); + } else { + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); + RX_ADD_CNT(prRxCtrl, RX_MPDU_TOTAL_COUNT, prTempRxRfbList->u4NumElem); + QUEUE_CONCATENATE_QUEUES(&prRxCtrl->rReceivedRfbList, prTempRxRfbList); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); + + /* Wake up Rx handling thread */ + set_bit(GLUE_FLAG_RX_BIT, &(prAdapter->prGlueInfo->ulFlag)); + wake_up_interruptible(&(prAdapter->prGlueInfo->waitq)); + } + + if (prTempFreeRfbList->u4NumElem) { + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_FREE_QUE); + QUEUE_CONCATENATE_QUEUES(&prRxCtrl->rFreeSwRfbList, prTempFreeRfbList); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_FREE_QUE); + } + + prRxBuf->u4PktCount = 0; + mutex_lock(&prHifInfo->rRxFreeBufQueMutex); + QUEUE_INSERT_TAIL(&prHifInfo->rRxFreeBufQueue, (struct QUE_ENTRY *)prRxBuf); + mutex_unlock(&prHifInfo->rRxFreeBufQueMutex); + + if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) + return; + + mutex_lock(&prHifInfo->rRxDeAggQueMutex); + QUEUE_REMOVE_HEAD(&prHifInfo->rRxDeAggQueue, prRxBuf, struct SDIO_RX_COALESCING_BUF *); + mutex_unlock(&prHifInfo->rRxDeAggQueMutex); + } +} + +void halDeAggRxPkt(struct ADAPTER *prAdapter, struct SDIO_RX_COALESCING_BUF *prRxBuf) +{ + struct GL_HIF_INFO *prHifInfo; + + prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + + /* Avoid to schedule DeAggWorker during uninit flow */ + if (prAdapter->prGlueInfo->ulFlag & GLUE_FLAG_HALT) { + mutex_lock(&prHifInfo->rRxFreeBufQueMutex); + QUEUE_INSERT_TAIL(&prHifInfo->rRxFreeBufQueue, (struct QUE_ENTRY *)prRxBuf); + mutex_unlock(&prHifInfo->rRxFreeBufQueMutex); + + return; + } + + mutex_lock(&prHifInfo->rRxDeAggQueMutex); + QUEUE_INSERT_TAIL(&prHifInfo->rRxDeAggQueue, (struct QUE_ENTRY *)prRxBuf); + mutex_unlock(&prHifInfo->rRxDeAggQueMutex); + + schedule_delayed_work(&prAdapter->prGlueInfo->rRxPktDeAggWork, 0); +} + +void halRxTasklet(unsigned long data) +{ + +} + +void halTxCompleteTasklet(unsigned long data) +{ + +} + +/* Hif power off wifi */ +uint32_t halHifPowerOffWifi(IN struct ADAPTER *prAdapter) +{ + uint32_t rStatus = WLAN_STATUS_SUCCESS; + + if (prAdapter->rAcpiState == ACPI_STATE_D0 && + !wlanIsChipNoAck(prAdapter) && !kalIsCardRemoved(prAdapter->prGlueInfo)) { + /* 0. Disable interrupt, this can be done without Driver own */ + nicDisableInterrupt(prAdapter); + + ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); + + /* 1. Set CMD to FW to tell WIFI to stop (enter power off state) */ + if (prAdapter->fgIsFwOwn == FALSE && wlanSendNicPowerCtrlCmd(prAdapter, 1) == WLAN_STATUS_SUCCESS) { + uint32_t i; + /* 2. Clear pending interrupt */ + i = 0; + while (i < CFG_IST_LOOP_COUNT && nicProcessIST(prAdapter) != WLAN_STATUS_NOT_INDICATING) { + i++; + }; + + /* 3. Wait til RDY bit has been cleaerd */ + rStatus = wlanCheckWifiFunc(prAdapter, FALSE); + } +#if !CFG_ENABLE_FULL_PM + /* 4. Set Onwership to F/W */ + nicpmSetFWOwn(prAdapter, FALSE); +#endif + +#if CFG_FORCE_RESET_UNDER_BUS_ERROR + if (HAL_TEST_FLAG(prAdapter, ADAPTER_FLAG_HW_ERR) == TRUE) { + /* force acquire firmware own */ + kalDevRegWrite(prAdapter->prGlueInfo, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_CLR); + + /* delay for 10ms */ + kalMdelay(10); + + /* force firmware reset via software interrupt */ + kalDevRegWrite(prAdapter->prGlueInfo, MCR_WSICR, WSICR_H2D_SW_INT_SET); + + /* force release firmware own */ + kalDevRegWrite(prAdapter->prGlueInfo, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_SET); + } +#endif + + RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); + } + return rStatus; +} + +void halPollDbgCr(IN struct ADAPTER *prAdapter, IN uint32_t u4LoopCount) +{ + uint32_t au4Value[] = {MCR_WCIR, MCR_WHLPCR, MCR_D2HRM2R}; + uint32_t au4Value1[] = {MCR_WHIER, MCR_D2HRM0R, MCR_D2HRM1R}; + uint32_t u4Loop = 0; + uint32_t u4Data = 0; + uint8_t i = 0, fgResult; +#if MTK_WCN_HIF_SDIO + uint8_t *pucCCR = (uint8_t *)&au4Value[0]; + unsigned long cltCtx = prAdapter->prGlueInfo->rHifInfo.cltCtx; +#endif + + for (; i < sizeof(au4Value)/sizeof(uint32_t); i++) + HAL_MCR_RD(prAdapter, au4Value[i], &au4Value[i]); + DBGLOG(REQ, WARN, "MCR_WCIR:0x%x, MCR_WHLPCR:0x%x, MCR_D2HRM2R:0x%x\n", + au4Value[0], au4Value[1], au4Value[2]); + + /* Need driver own */ + HAL_LP_OWN_RD(prAdapter, &fgResult); + if (fgResult == TRUE) { + /* dump N9 programming counter */ + for (u4Loop = 0; u4Loop < u4LoopCount; u4Loop++) { + HAL_MCR_RD(prAdapter, MCR_SWPCDBGR, &u4Data); + DBGLOG(INIT, WARN, "SWPCDBGR 0x%08X\n", u4Data); + } + + /* dump others */ + for (i = 0; i < sizeof(au4Value1)/sizeof(uint32_t); i++) + HAL_MCR_RD(prAdapter, au4Value1[i], &au4Value1[i]); + + DBGLOG(REQ, WARN, "MCR_WHIER:0x%x, MCR_D2HRM0R:0x%x", + au4Value1[0], au4Value1[1]); + DBGLOG(REQ, WARN, "MCR_D2HRM1R:0x%x\n", + au4Value1[2]); + } + +#if MTK_WCN_HIF_SDIO + for (i = 0; i < 8; i++) + mtk_wcn_hif_sdio_f0_readb(cltCtx, 0xf8 + i, &pucCCR[i]); + DBGLOG(REQ, WARN, "CCCR %02x %02x %02x %02x %02x %02x %02x %02x\n", + pucCCR[0], pucCCR[1], pucCCR[2], pucCCR[3], pucCCR[4], pucCCR[5], pucCCR[6], pucCCR[7]); +#endif +} + +void halSerHifReset(IN struct ADAPTER *prAdapter) +{ + struct GL_HIF_INFO *prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + + /* Restore Tx resource */ + halRestoreTxResource(prAdapter); + + /* Clear interrupt status from Rx interrupt enhance mode */ + prHifInfo->fgIsPendingInt = FALSE; + kalMemZero(prHifInfo->prSDIOCtrl, sizeof(struct ENHANCE_MODE_DATA_STRUCT)); +} + +u_int8_t halIsPendingTxDone(IN struct ADAPTER *prAdapter) +{ + struct GL_HIF_INFO *prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + uint32_t i; + u_int8_t fgIsPendingTxDone = FALSE; + + for (i = TC0_INDEX; i <= TC4_INDEX; i++) { + if (prHifInfo->au4PendingTxDoneCount[i]) { + fgIsPendingTxDone = TRUE; + break; + } + } + + if (fgIsPendingTxDone) + DBGLOG(NIC, ERROR, "Missing Tx done[%u:%u:%u:%u:%u]\n", + prHifInfo->au4PendingTxDoneCount[TC0_INDEX], + prHifInfo->au4PendingTxDoneCount[TC1_INDEX], + prHifInfo->au4PendingTxDoneCount[TC2_INDEX], + prHifInfo->au4PendingTxDoneCount[TC3_INDEX], + prHifInfo->au4PendingTxDoneCount[TC4_INDEX]); + + return fgIsPendingTxDone; +} + +void halPrintHifDbgInfo(IN struct ADAPTER *prAdapter) +{ + if (prAdapter->u4HifDbgFlag & DEG_HIF_ALL || + prAdapter->u4HifDbgFlag & DEG_HIF_DEFAULT_DUMP) { + halPrintMailbox(prAdapter); + halPollDbgCr(prAdapter, LP_DBGCR_POLL_ROUND); + } + prAdapter->u4HifDbgFlag = 0; +} + +u_int8_t halIsTxResourceControlEn(IN struct ADAPTER *prAdapter) +{ + return TRUE; +} + +void halTxResourceResetHwTQCounter(IN struct ADAPTER *prAdapter) +{ + uint32_t *pu4WHISR = NULL; + uint16_t au2TxCount[16]; + + pu4WHISR = (uint32_t *)kalMemAlloc(sizeof(uint32_t), PHY_MEM_TYPE); + if (!pu4WHISR) { + DBGLOG(INIT, ERROR, "Allocate pu4WHISR fail\n"); + return; + } + + HAL_READ_INTR_STATUS(prAdapter, sizeof(uint32_t), (uint8_t *)pu4WHISR); + if (HAL_IS_TX_DONE_INTR(*pu4WHISR)) + HAL_READ_TX_RELEASED_COUNT(prAdapter, au2TxCount); + + if (pu4WHISR) + kalMemFree(pu4WHISR, PHY_MEM_TYPE, sizeof(uint32_t)); +} + +uint32_t halGetHifTxPageSize(IN struct ADAPTER *prAdapter) +{ + if (!prAdapter->chip_info->is_support_cr4) { + if (prAdapter->fgIsNicTxReousrceValid) + return prAdapter->nicTxReousrce.u4DataResourceUnit; + else + return HIF_TX_PAGE_SIZE_STORED_FORWARD; + } + + /*cr4 mode*/ + return HIF_TX_PAGE_SIZE; +} +/*----------------------------------------------------------------------------*/ +/*! +* @brief Generic update Tx done counter +* +* @param prAdapter Pointer to the Adapter structure. +* @param au2TxDoneCnt Pointer to the final reference table +* @param au2TxRlsCnt Pointer to the Tx done counter result got fom interrupt +* +* @return (none) +*/ +/*----------------------------------------------------------------------------*/ + +void halTxGetFreeResource(IN struct ADAPTER *prAdapter, IN uint16_t *au2TxDoneCnt, IN uint16_t *au2TxRlsCnt) +{ + uint8_t i; + struct BUS_INFO *prBusInfo = prAdapter->chip_info->bus_info; + + if (prBusInfo->halTxGetFreeResource) + return prBusInfo->halTxGetFreeResource(prAdapter, au2TxDoneCnt, au2TxRlsCnt); + + /* 6632, 7668 ways */ + for (i = HIF_TX_AC0_INDEX; i <= HIF_TX_AC23_INDEX; i++) + au2TxDoneCnt[i % WMM_AC_INDEX_NUM] += au2TxRlsCnt[i]; + au2TxDoneCnt[HIF_TX_CPU_INDEX] = au2TxRlsCnt[HIF_TX_CPU_INDEX]; +} + +/*----------------------------------------------------------------------------*/ +/*! +* @brief Update Tx done counter for mt7663 +* +* @param prAdapter Pointer to the Adapter structure. +* @param au2TxDoneCnt Pointer to the final reference table +* @param au2TxRlsCnt Pointer to the Tx done counter result got fom interrupt +* +* @return (none) +*/ +/*----------------------------------------------------------------------------*/ + +void halTxGetFreeResource_v1(IN struct ADAPTER *prAdapter, IN uint16_t *au2TxDoneCnt, IN uint16_t *au2TxRlsCnt) +{ + uint8_t i; + + for (i = HIF_TXC_IDX_0; i < HIF_TXC_IDX_NUM; i++) + au2TxDoneCnt[i] = au2TxRlsCnt[i]; +} + +/*----------------------------------------------------------------------------*/ +/*! +* @brief Generic return free resource to TCs +* +* @param prAdapter Pointer to the Adapter structure. +* @param au2TxDoneCnt Pointer to the final reference table +* @param au2TxRlsCnt Pointer to the Tx done counter result got fom interrupt +* +* @return (none) +*/ +/*----------------------------------------------------------------------------*/ + +void halTxReturnFreeResource(IN struct ADAPTER *prAdapter, IN uint16_t *au2TxDoneCnt) +{ + uint8_t i; + struct BUS_INFO *prBusInfo = prAdapter->chip_info->bus_info; + uint16_t u2ReturnCnt; + + KAL_SPIN_LOCK_DECLARATION(); + + + if (prBusInfo->halTxReturnFreeResource) + prBusInfo->halTxReturnFreeResource(prAdapter, au2TxDoneCnt); + else { + /* 6632, 7668 ways */ + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); + for (i = TC0_INDEX; i < TC_NUM; i++) { + u2ReturnCnt = au2TxDoneCnt[nicTxGetTxQByTc(prAdapter, i)]; + nicTxReleaseResource_PSE(prAdapter, i, u2ReturnCnt, FALSE); + prAdapter->prGlueInfo->rHifInfo.au4PendingTxDoneCount[i] -= u2ReturnCnt; + } + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); + } +} + +/*----------------------------------------------------------------------------*/ +/*! +* @brief Return free resource to TCs for mt7663 +* +* @param prAdapter Pointer to the Adapter structure. +* @param au2TxDoneCnt Pointer to the final reference table +* +* @return (none) +*/ +/*----------------------------------------------------------------------------*/ +void halTxReturnFreeResource_v1(IN struct ADAPTER *prAdapter, IN uint16_t *au2TxDoneCnt) +{ + uint8_t i; + uint16_t u2ReturnCnt; + + KAL_SPIN_LOCK_DECLARATION(); + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); + + /* WMM 1 */ + for (i = HIF_TXC_IDX_0; i <= HIF_TXC_IDX_8; i++) { + uint8_t ucTc; + + u2ReturnCnt = au2TxDoneCnt[i]; + + if (i < HIF_TXC_IDX_5) { + ucTc = HIF_TXC_IDX_2_TC_IDX_PSE(i); + nicTxReleaseResource_PSE(prAdapter, ucTc, u2ReturnCnt, FALSE); + } else { + ucTc = HIF_TXC_IDX_2_TC_IDX_PLE(i); + nicTxReleaseResource_PLE(prAdapter, ucTc, u2ReturnCnt, FALSE); + } + + prAdapter->prGlueInfo->rHifInfo.au4PendingTxDoneCount[i] -= u2ReturnCnt; + } + + /* WMM 2,3 */ + /*TBD*/ + + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); +} + +/*----------------------------------------------------------------------------*/ +/*! +* @brief Generic rollback resource to TCs +* +* @param prAdapter Pointer to the Adapter structure. +* +* @return (none) +*/ +/*----------------------------------------------------------------------------*/ + +void halRestoreTxResource(IN struct ADAPTER *prAdapter) +{ + uint8_t i; + struct BUS_INFO *prBusInfo = prAdapter->chip_info->bus_info; + struct GL_HIF_INFO *prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + + KAL_SPIN_LOCK_DECLARATION(); + + if (prBusInfo->halRestoreTxResource) + prBusInfo->halRestoreTxResource(prAdapter); + else { + /* 6632, 7668 ways */ + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); + for (i = TC0_INDEX; i < TC_NUM; i++) { + nicTxReleaseResource_PSE(prAdapter, i, prHifInfo->au4PendingTxDoneCount[i], FALSE); + prHifInfo->au4PendingTxDoneCount[i] = 0; + } + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); + } +} + +/*----------------------------------------------------------------------------*/ +/*! +* @brief Rollback resource to TCs for mt7663 +* +* @param prAdapter Pointer to the Adapter structure. +* +* @return (none) +*/ +/*----------------------------------------------------------------------------*/ + +void halRestoreTxResource_v1(IN struct ADAPTER *prAdapter) +{ + uint8_t i; + + KAL_SPIN_LOCK_DECLARATION(); + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); + + /* WMM 1 */ + /* PSE pages: HIF_TXC_IDX_0- */ + for (i = HIF_TXC_IDX_0; i <= HIF_TXC_IDX_4; i++) { + nicTxReleaseResource_PSE(prAdapter, HIF_TXC_IDX_2_TC_IDX_PSE(i), + prAdapter->prGlueInfo->rHifInfo.au4PendingTxDoneCount[i], + FALSE); + + prAdapter->prGlueInfo->rHifInfo.au4PendingTxDoneCount[i] = 0; + } + + /* PLE pages */ + for (i = HIF_TXC_IDX_5; i <= HIF_TXC_IDX_8; i++) { + nicTxReleaseResource_PLE(prAdapter, HIF_TXC_IDX_2_TC_IDX_PLE(i), + prAdapter->prGlueInfo->rHifInfo.au4PendingTxDoneCount[i], + FALSE); + + prAdapter->prGlueInfo->rHifInfo.au4PendingTxDoneCount[i] = 0; + } + + /* WMM 2,3 */ + /*TBD*/ + + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); +} + +void halUpdateTxDonePendingCount(IN struct ADAPTER *prAdapter, IN u_int8_t isIncr, IN uint8_t ucTc, IN uint32_t u4Len) +{ + uint8_t u2PageCnt; + struct BUS_INFO *prBusInfo = prAdapter->chip_info->bus_info; + + u2PageCnt = halTxGetPageCount(prAdapter, u4Len, FALSE); + + if (prBusInfo->halUpdateTxDonePendingCount) + prBusInfo->halUpdateTxDonePendingCount(prAdapter, isIncr, ucTc, u2PageCnt); + else { + /* 6632, 7668 ways */ + if (isIncr) + prAdapter->prGlueInfo->rHifInfo.au4PendingTxDoneCount[ucTc] += u2PageCnt; + else + prAdapter->prGlueInfo->rHifInfo.au4PendingTxDoneCount[ucTc] -= u2PageCnt; + } +} + +void halUpdateTxDonePendingCount_v1(IN struct ADAPTER *prAdapter, IN u_int8_t isIncr, IN uint8_t ucTc, IN uint16_t u2Cnt) +{ + uint8_t idx; + + /* Update PSE part */ + idx = TC_IDX_PSE_2_HIF_TXC_IDX(ucTc); + + if (idx >= HIF_TXC_IDX_NUM) + ASSERT(0); + + if (isIncr) + prAdapter->prGlueInfo->rHifInfo.au4PendingTxDoneCount[idx] += u2Cnt; + else + prAdapter->prGlueInfo->rHifInfo.au4PendingTxDoneCount[idx] -= u2Cnt; + + /* Update PLE part */ + if (!nicTxResourceIsPleCtrlNeeded(prAdapter, ucTc)) + return; + + idx = TC_IDX_PLE_2_HIF_TXC_IDX(ucTc); + + if (idx >= HIF_TXC_IDX_NUM) + ASSERT(0); + + if (isIncr) + prAdapter->prGlueInfo->rHifInfo.au4PendingTxDoneCount[idx] += NIX_TX_PLE_PAGE_CNT_PER_FRAME; + else + prAdapter->prGlueInfo->rHifInfo.au4PendingTxDoneCount[idx] -= NIX_TX_PLE_PAGE_CNT_PER_FRAME; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* @brief Check if HIF state is READY for upper layer cfg80211 +* +* @param prAdapter Pointer to the Adapter structure. +* +* @return (TRUE: ready, FALSE: not ready) +*/ +/*----------------------------------------------------------------------------*/ +bool halIsHifStateReady(IN struct ADAPTER *prAdapter, uint8_t *pucState) +{ + /* SDIO owner should implement this function */ + + return TRUE; +} + +/*----------------------------------------------------------------------------*/ +/*! +* @brief Check if HIF state is during supend process +* +* @param prAdapter Pointer to the Adapter structure. +* +* @return (TRUE: suspend, reject the caller action. FALSE: not suspend) +*/ +/*----------------------------------------------------------------------------*/ +bool halIsHifStateSuspend(IN struct ADAPTER *prAdapter) +{ + /* SDIO owner should implement this function */ + + return FALSE; +} + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/sdio/include/hif.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/sdio/include/hif.h new file mode 100644 index 0000000000000000000000000000000000000000..8a95d92791f2b90265d15086736c1ca175344c91 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/sdio/include/hif.h @@ -0,0 +1,403 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* +** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/hif/sdio/include/hif.h#1 +*/ + +/*! \file "hif.h" +* \brief Functions for the driver to register bus and setup the IRQ +* +* Functions for the driver to register bus and setup the IRQ +*/ + + +#ifndef _HIF_H +#define _HIF_H + +#if MTK_WCN_HIF_SDIO +#include "hif_sdio.h" +#endif + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ +#if MTK_WCN_HIF_SDIO +#define HIF_SDIO_SUPPORT_GPIO_SLEEP_MODE 1 +#else +#define HIF_SDIO_SUPPORT_GPIO_SLEEP_MODE 0 +#endif + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ +#if defined(_HIF_SDIO) +#define HIF_NAME "SDIO" +#else +#error "No HIF defined!" +#endif + + +/* Enable driver timing profiling */ +#define CFG_SDIO_TIMING_PROFILING 0 + +#define CFG_SDIO_INT_LOG_CNT 8 + +#define SDIO_X86_WORKAROUND_WRITE_MCR 0x00C4 +#define HIF_NUM_OF_QM_RX_PKT_NUM 512 + +#define HIF_TX_INIT_CMD_PORT TX_RING_FWDL_IDX_3 + +#define HIF_IST_LOOP_COUNT 128 +#define HIF_IST_TX_THRESHOLD 32 /* Min msdu count to trigger Tx during INT polling state */ + +#define HIF_TX_MAX_AGG_LENGTH (511 * 512) /* 511 blocks x 512 */ + +#define HIF_RX_MAX_AGG_NUM 16 +/*!< Setting the maximum RX aggregation number 0: no limited (16) */ + +#define HIF_TX_BUFF_COUNT_TC0 8 +#define HIF_TX_BUFF_COUNT_TC1 167 +#define HIF_TX_BUFF_COUNT_TC2 8 +#define HIF_TX_BUFF_COUNT_TC3 8 +#define HIF_TX_BUFF_COUNT_TC4 7 +#define HIF_TX_BUFF_COUNT_TC5 0 + +#define HIF_TX_RESOURCE_CTRL 1 /* enable/disable TX resource control */ +#define HIF_TX_RESOURCE_CTRL_PLE 1 /* enable/disable TX resource control PLE */ + + +#define HIF_TX_PAGE_SIZE_IN_POWER_OF_2 11 +#define HIF_TX_PAGE_SIZE 2048 /* in unit of bytes */ +#define HIF_TX_PAGE_SIZE_STORED_FORWARD 128 /* in unit of bytes */ + +#define HIF_EXTRA_IO_BUFFER_SIZE \ + (sizeof(struct ENHANCE_MODE_DATA_STRUCT) + HIF_RX_COALESCING_BUF_COUNT * HIF_RX_COALESCING_BUFFER_SIZE) + +#define HIF_CR4_FWDL_SECTION_NUM 2 +#define HIF_IMG_DL_STATUS_PORT_IDX 0 + +#define HIF_RX_ENHANCE_MODE_PAD_LEN 4 + +#define HIF_TX_TERMINATOR_LEN 4 + +#if CFG_SDIO_TX_AGG +#define HIF_TX_COALESCING_BUFFER_SIZE (HIF_TX_MAX_AGG_LENGTH) +#else +#define HIF_TX_COALESCING_BUFFER_SIZE (CFG_TX_MAX_PKT_SIZE) +#endif + +#if CFG_SDIO_RX_AGG +#define HIF_RX_COALESCING_BUFFER_SIZE ((HIF_RX_MAX_AGG_NUM + 1) * CFG_RX_MAX_PKT_SIZE) +#else +#define HIF_RX_COALESCING_BUFFER_SIZE (CFG_RX_MAX_PKT_SIZE) +#endif + +#define HIF_RX_COALESCING_BUF_COUNT 16 + +/* WHISR device to host (D2H) */ +/* N9 Interrupt Host to stop tx/rx operation (at the moment, HIF tx/rx are stopted) */ +#define SER_SDIO_N9_HOST_STOP_TX_RX_OP BIT(8) +/* N9 Interrupt Host to stop tx operation (at the moment, HIF tx are stopted) */ +#define SER_SDIO_N9_HOST_STOP_TX_OP BIT(9) +/* N9 Interrupt Host all modules were reset done (to let host reinit HIF) */ +#define SER_SDIO_N9_HOST_RESET_DONE BIT(10) +/* N9 Interrupt Host System Error Recovery Done */ +#define SER_SDIO_N9_HOST_RECOVERY_DONE BIT(11) + +/* WSICR host to device (H2D) */ +/* Host ACK HIF tx/rx ring stop operatio */ +#define SER_SDIO_HOST_N9_STOP_TX_RX_OP_ACK BIT(19) +/* Host interrupt N9 HIF init done */ +#define SER_SDIO_HOST_N9_RESET_DONE_ACK BIT(20) +/* Host interrupt N9 System Error Recovery done */ +#define SER_SDIO_HOST_N9_RECOVERY_DONE_ACK BIT(21) +enum HIF_TX_COUNT_IDX_T { + HIF_TXC_IDX_0, + HIF_TXC_IDX_1, + HIF_TXC_IDX_2, + HIF_TXC_IDX_3, + HIF_TXC_IDX_4, + HIF_TXC_IDX_5, + HIF_TXC_IDX_6, + HIF_TXC_IDX_7, + HIF_TXC_IDX_8, + HIF_TXC_IDX_9, + HIF_TXC_IDX_10, + HIF_TXC_IDX_11, + HIF_TXC_IDX_12, + HIF_TXC_IDX_13, + HIF_TXC_IDX_14, + HIF_TXC_IDX_15, + HIF_TXC_IDX_NUM +}; + + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +struct ENHANCE_MODE_DATA_STRUCT; /* declare SDIO_CTRL_T */ + +struct SDIO_STAT_COUNTER { + /* Tx data */ + uint32_t u4DataPortWriteCnt; + uint32_t u4DataPktWriteCnt; + uint32_t u4DataPortKickCnt; + + /* Tx command */ + uint32_t u4CmdPortWriteCnt; + uint32_t u4CmdPktWriteCnt; + + /* Tx done interrupt */ + uint32_t u4TxDoneCnt[HIF_TXC_IDX_NUM]; + uint32_t u4TxDoneIntCnt[HIF_TXC_IDX_NUM]; + uint32_t u4TxDoneIntTotCnt; + uint32_t u4TxDonePendingPktCnt; + + uint32_t u4IntReadCnt; + uint32_t u4IntCnt; + + /* Rx data/cmd*/ + uint32_t u4PortReadCnt[2]; + uint32_t u4PktReadCnt[2]; + + uint32_t u4RxBufUnderFlowCnt; + +#if CFG_SDIO_TIMING_PROFILING + uint32_t u4TxDataCpTime; + uint32_t u4TxDataFreeTime; + + uint32_t u4RxDataCpTime; + uint32_t u4PortReadTime; + + uint32_t u4TxDoneIntTime; + uint32_t u4IntReadTime; +#endif +}; + +struct SDIO_RX_COALESCING_BUF { + struct QUE_ENTRY rQueEntry; + void *pvRxCoalescingBuf; + uint32_t u4BufSize; + uint32_t u4PktCount; + uint32_t u4PktTotalLength; + + uint32_t u4IntLogIdx; +}; + +struct SDIO_INT_LOG_T { + uint32_t u4Idx; + uint8_t aucIntSts[128]; + uint32_t u4Flag; + uint16_t au2RxPktLen[HIF_RX_MAX_AGG_NUM]; + uint32_t au4RxPktInfo[HIF_RX_MAX_AGG_NUM]; + uint8_t ucRxPktCnt; +}; + +/* host interface's private data structure, which is attached to os glue +** layer info structure. + */ +struct GL_HIF_INFO { +#if MTK_WCN_HIF_SDIO + unsigned long cltCtx; + + const struct MTK_WCN_HIF_SDIO_FUNCINFO *prFuncInfo; +#else + struct sdio_func *func; +#endif + + struct ENHANCE_MODE_DATA_STRUCT *prSDIOCtrl; + + u_int8_t fgIntReadClear; + u_int8_t fgMbxReadClear; + struct QUE rFreeQueue; + u_int8_t fgIsPendingInt; + + uint32_t au4PendingTxDoneCount[HIF_TXC_IDX_NUM]; + + /* Statistic counter */ + struct SDIO_STAT_COUNTER rStatCounter; + + struct SDIO_RX_COALESCING_BUF rRxCoalesingBuf[HIF_RX_COALESCING_BUF_COUNT]; + + struct QUE rRxDeAggQueue; + struct QUE rRxFreeBufQueue; + + struct mutex rRxFreeBufQueMutex; + struct mutex rRxDeAggQueMutex; + + /* Error handling */ + u_int8_t fgSkipRx; + + struct SDIO_INT_LOG_T arIntLog[CFG_SDIO_INT_LOG_CNT]; + uint32_t u4IntLogIdx; + uint8_t ucIntLogEntry; + uint8_t fgForceFwOwn; +}; + +struct BUS_INFO { + void (*halTxGetFreeResource)(IN struct ADAPTER *prAdapter, IN uint16_t *au2TxDoneCnt, IN uint16_t *au2TxRlsCnt); + void (*halTxReturnFreeResource)(IN struct ADAPTER *prAdapter, IN uint16_t *au2TxDoneCnt); + void (*halRestoreTxResource)(IN struct ADAPTER *prAdapter); + void (*halUpdateTxDonePendingCount)(IN struct ADAPTER *prAdapter, + IN u_int8_t isIncr, IN uint8_t ucTc, IN uint16_t u2Cnt); +}; + +enum HIF_SDIO_INT_STS { + SDIO_INT_RX_ENHANCE = 0, + SDIO_INT_DRV_OWN, + SDIO_INT_WAKEUP_DSLP +}; + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +#if CFG_SDIO_TIMING_PROFILING +#define SDIO_TIME_INTERVAL_DEC() KAL_TIME_INTERVAL_DECLARATION() +#define SDIO_REC_TIME_START() KAL_REC_TIME_START() +#define SDIO_REC_TIME_END() KAL_REC_TIME_END() +#define SDIO_GET_TIME_INTERVAL() KAL_GET_TIME_INTERVAL() +#define SDIO_ADD_TIME_INTERVAL(_Interval) KAL_ADD_TIME_INTERVAL(_Interval) +#else +#define SDIO_TIME_INTERVAL_DEC() +#define SDIO_REC_TIME_START() +#define SDIO_REC_TIME_END() +#define SDIO_GET_TIME_INTERVAL() +#define SDIO_ADD_TIME_INTERVAL(_Interval) +#endif + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +uint32_t glRegisterBus(probe_card pfProbe, remove_card pfRemove); + +void glUnregisterBus(remove_card pfRemove); + +void glSetHifInfo(struct GLUE_INFO *prGlueInfo, unsigned long ulCookie); + +void glClearHifInfo(struct GLUE_INFO *prGlueInfo); + +u_int8_t glBusInit(void *pvData); + +void glBusRelease(void *pData); + +int32_t glBusSetIrq(void *pvData, void *pfnIsr, void *pvCookie); + +void glBusFreeIrq(void *pvData, void *pvCookie); + +void glSetPowerState(IN struct GLUE_INFO *prGlueInfo, IN uint32_t ePowerMode); + +void glGetDev(void *ctx, struct device **dev); + +void glGetHifDev(struct GL_HIF_INFO *prHif, struct device **dev); + +u_int8_t glWakeupSdio(struct GLUE_INFO *prGlueInfo); + +#if !CFG_SDIO_INTR_ENHANCE +void halRxSDIOReceiveRFBs(IN struct ADAPTER *prAdapter); + +uint32_t halRxReadBuffer(IN struct ADAPTER *prAdapter, IN OUT struct SW_RFB *prSwRfb); + +#else +void halRxSDIOEnhanceReceiveRFBs(IN struct ADAPTER *prAdapter); + +uint32_t halRxEnhanceReadBuffer(IN struct ADAPTER *prAdapter, IN uint32_t u4DataPort, + IN uint16_t u2RxLength, IN OUT struct SW_RFB *prSwRfb); + +void halProcessEnhanceInterruptStatus(IN struct ADAPTER *prAdapter); + +#endif /* CFG_SDIO_INTR_ENHANCE */ + +#if CFG_SDIO_RX_AGG +void halRxSDIOAggReceiveRFBs(IN struct ADAPTER *prAdapter); +#endif + +void halPutMailbox(IN struct ADAPTER *prAdapter, IN uint32_t u4MailboxNum, IN uint32_t u4Data); +void halGetMailbox(IN struct ADAPTER *prAdapter, IN uint32_t u4MailboxNum, OUT uint32_t *pu4Data); +void halDeAggRxPkt(struct ADAPTER *prAdapter, struct SDIO_RX_COALESCING_BUF *prRxBuf); +void halPrintMailbox(IN struct ADAPTER *prAdapter); +void halPollDbgCr(IN struct ADAPTER *prAdapter, IN uint32_t u4LoopCount); +void halTxGetFreeResource_v1(IN struct ADAPTER *prAdapter, IN uint16_t *au2TxDoneCnt, IN uint16_t *au2TxRlsCnt); + +u_int8_t halIsPendingTxDone(IN struct ADAPTER *prAdapter); +void halDumpIntLog(IN struct ADAPTER *prAdapter); +void halTagIntLog(IN struct ADAPTER *prAdapter, IN enum HIF_SDIO_INT_STS eTag); +void halRecIntLog(IN struct ADAPTER *prAdapter, IN struct ENHANCE_MODE_DATA_STRUCT *prSDIOCtrl); +struct SDIO_INT_LOG_T *halGetIntLog(IN struct ADAPTER *prAdapter, IN uint32_t u4Idx); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +#endif /* _HIF_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/sdio/include/hif_sdio.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/sdio/include/hif_sdio.h new file mode 100644 index 0000000000000000000000000000000000000000..9adba8b18dd7bbd641d8b0a2b88cc21476c74fdb --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/sdio/include/hif_sdio.h @@ -0,0 +1,267 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* +** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/hif/sdio/include/hif_sdio.h#2 +*/ + +/*! \file "hif_sdio.h" +* \brief +* +* +*/ + + +#ifndef _HIF_SDIO_H +#define _HIF_SDIO_H +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ +#define HIF_SDIO_DEBUG (0) /* 0:turn off debug msg and assert, 1:turn off debug msg and assert */ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include "mtk_porting.h" + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ +#define CFG_CLIENT_COUNT (8) + +#define HIF_DEFAULT_BLK_SIZE (256) +#define HIF_DEFAULT_VENDOR (0x037A) + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/* sdio driver data mapping */ +struct MTK_WCN_SDIO_DRIVER_DATA_MAPPING { + uint16_t card_id; /* TPLMID_CARD: card ID */ + struct mt66xx_hif_driver_data *mt66xx_driver_data; +}; + + +/* Function info provided by client driver */ +struct MTK_WCN_HIF_SDIO_FUNCINFO; /* declare MTK_WCN_HIF_SDIO_FUNCINFO */ + +/* Client context provided by hif_sdio driver for the following function call */ + +/* Callback functions provided by client driver */ +typedef int32_t(*MTK_WCN_HIF_SDIO_PROBE)(unsigned long, const struct MTK_WCN_HIF_SDIO_FUNCINFO *prFuncInfo); +typedef int32_t(*MTK_WCN_HIF_SDIO_REMOVE)(unsigned long); +typedef int32_t(*MTK_WCN_HIF_SDIO_IRQ)(unsigned long); + +/* Function info provided by client driver */ +struct MTK_WCN_HIF_SDIO_FUNCINFO { + uint16_t manf_id; /* TPLMID_MANF: manufacturer ID */ + uint16_t card_id; /* TPLMID_CARD: card ID */ + uint16_t func_num; /* Function Number */ + uint16_t blk_sz; /* Function block size */ +}; + +/* Client info provided by client driver */ +struct MTK_WCN_HIF_SDIO_CLTINFO { + const struct MTK_WCN_HIF_SDIO_FUNCINFO *func_tbl; /* supported function info table */ + uint32_t func_tbl_size; /* supported function table info element number */ + MTK_WCN_HIF_SDIO_PROBE hif_clt_probe; /* callback function for probing */ + MTK_WCN_HIF_SDIO_REMOVE hif_clt_remove; /* callback function for removing */ + MTK_WCN_HIF_SDIO_IRQ hif_clt_irq; /* callback function for interrupt handling */ +}; + +/* function info provided by registed function */ +struct MTK_WCN_HIF_SDIO_REGISTINFO { + const struct MTK_WCN_HIF_SDIO_CLTINFO *sdio_cltinfo; /* client's MTK_WCN_HIF_SDIO_CLTINFO pointer */ + const struct MTK_WCN_HIF_SDIO_FUNCINFO *func_info; /* supported function info pointer */ +}; + +/* Card info provided by probed function */ +struct MTK_WCN_HIF_SDIO_PROBEINFO { + struct sdio_func *func; /* probed sdio function pointer */ + int8_t clt_idx; /* registered function table info element number (initial value is -1) */ + int interrupted; /* TRUE: interrupted, FALSE: not interrupted */ + void *private_data_p; /* clt's private data pointer */ +}; + +/* work queue info needed by worker */ +struct MTK_WCN_HIF_SDIO_CLT_PROBE_WORKERINFO { + struct work_struct probe_work; /* work queue structure */ + struct MTK_WCN_HIF_SDIO_REGISTINFO *registinfo_p; /* MTK_WCN_HIF_SDIO_REGISTINFO pointer of the client */ + int8_t probe_idx; /* probed function table info element number (initial value is -1) */ +}; + +/* error code returned by hif_sdio driver (use NEGATIVE number) */ +enum MTK_WCN_HIF_SDIO_ERR { + HIF_SDIO_ERR_SUCCESS = 0, + HIF_SDIO_ERR_FAIL, /* generic error */ + HIF_SDIO_ERR_INVALID_PARAM, + HIF_SDIO_ERR_DUPLICATED, + HIF_SDIO_ERR_UNSUP_MANF_ID, + HIF_SDIO_ERR_UNSUP_CARD_ID, + HIF_SDIO_ERR_INVALID_FUNC_NUM, + HIF_SDIO_ERR_INVALID_BLK_SZ, +}; + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/*! + * \brief A macro used to describe an SDIO function + * + * Fill an MTK_WCN_HIF_SDIO_FUNCINFO structure with function-specific information + * + * \param manf the 16 bit manufacturer id + * \param card the 16 bit card id + * \param func the 16 bit function number + * \param b_sz the 16 bit function block size + */ +#define MTK_WCN_HIF_SDIO_FUNC(manf, card, func, b_sz) \ + .manf_id = (manf), .card_id = (card), .func_num = (func), .blk_sz = (b_sz) + +/*! + * \brief A debug print used to print debug messages while compiler flag HIF_SDIO_DEBUG on. + * + */ +#if HIF_SDIO_DEBUG +#define DPRINTK(fmt, args...) pr_debug("%s: " fmt, __func__, ## args) +#else +#define DPRINTK(fmt, args...) +#endif + +/*! + * \brief ASSERT function definition. + * + */ +#if HIF_SDIO_DEBUG +#define ASSERT(expr) \ + { \ + if (!(expr)) { \ + LOG_FUNC("assertion failed! %s[%d]: %s\n",\ + __func__, __LINE__, #expr); \ + WARN_ON(!(expr));\ + } \ + } +#else +#define ASSERT(expr) do {} while (0) +#endif + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/*! + * \brief MTK hif sdio client registration function + * + * Client uses this function to do hif sdio registration + * + * \param pinfo a pointer of client's information + * + * \retval 0 register successfully + * \retval < 0 error code + */ +extern int32_t mtk_wcn_hif_sdio_client_reg(const struct MTK_WCN_HIF_SDIO_CLTINFO *pinfo); + +extern int32_t mtk_wcn_hif_sdio_client_unreg(const struct MTK_WCN_HIF_SDIO_CLTINFO *pinfo); + +extern int32_t mtk_wcn_hif_sdio_readb(unsigned long ctx, uint32_t offset, uint8_t *pvb); + +extern int32_t mtk_wcn_hif_sdio_writeb(unsigned long ctx, uint32_t offset, uint8_t vb); + +extern int32_t mtk_wcn_hif_sdio_f0_readb(unsigned long ctx, uint32_t offset, uint8_t *pvb); + +extern int32_t mtk_wcn_hif_sdio_f0_writeb(unsigned long ctx, uint32_t offset, uint8_t vb); + +extern int32_t mtk_wcn_hif_sdio_readl(unsigned long ctx, uint32_t offset, uint32_t *pvl); + +extern int32_t mtk_wcn_hif_sdio_writel(unsigned long ctx, uint32_t offset, uint32_t vl); + +extern int32_t mtk_wcn_hif_sdio_read_buf(unsigned long ctx, uint32_t offset, uint32_t *pbuf, uint32_t len); + +extern int32_t mtk_wcn_hif_sdio_write_buf(unsigned long ctx, uint32_t offset, uint32_t *pbuf, uint32_t len); + +extern void mtk_wcn_hif_sdio_set_drvdata(unsigned long ctx, void *private_data_p); + +extern void *mtk_wcn_hif_sdio_get_drvdata(unsigned long ctx); + +extern void mtk_wcn_hif_sdio_get_dev(unsigned long ctx, struct device **dev); + +extern void mtk_wcn_hif_sdio_enable_irq(unsigned long ctx, int enable); + +#if KERNEL_VERSION(4, 4, 0) <= CFG80211_VERSION_CODE +extern int32_t mtk_wcn_stp_sdio_wake_up_ctrl(unsigned long ctx); +#else +extern int32_t mtk_wcn_hif_sdio_wake_up_ctrl(unsigned long ctx); +#endif + + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +#endif /* _HIF_SDIO_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/sdio/include/mtk_porting.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/sdio/include/mtk_porting.h new file mode 100644 index 0000000000000000000000000000000000000000..9be2f55d64c634c0bdf43d19cafb03b46cbb4cfd --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/sdio/include/mtk_porting.h @@ -0,0 +1,89 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* porting layer */ +/* Android */ + +#ifndef _MTK_PORTING_H_ +#define _MTK_PORTING_H_ + +#include /* include stddef.h for NULL */ + +/* typedef void VOID, *PVOID; */ + +#ifndef MTK_WCN_BOOL_TRUE +#define MTK_WCN_BOOL_FALSE ((int) 0) +#define MTK_WCN_BOOL_TRUE ((int) 1) +#endif + + + +/* system APIs */ +/* mutex */ +typedef int(*MUTEX_CREATE) (const char *const name); +typedef int32_t(*MUTEX_DESTROY) (int mtx); +typedef int32_t(*MUTEX_LOCK) (int mtx); +typedef int32_t(*MUTEX_UNLOCK) (int mtx, unsigned long flags); +/* debug */ +typedef int32_t(*DBG_PRINT) (const char *str, ...); +typedef int32_t(*DBG_ASSERT) (int32_t expr, const char *file, int32_t line); +/* timer */ +typedef void (*MTK_WCN_TIMER_CB) (void); +typedef int(*TIMER_CREATE) (const char *const name); +typedef int32_t(*TIMER_DESTROY) (int tmr); +typedef int32_t(*TIMER_START) (int tmr, uint32_t timeout, MTK_WCN_TIMER_CB tmr_cb, void *param); +typedef int32_t(*TIMER_STOP) (int tmr); +/* kernel lib */ +typedef void *(*SYS_MEMCPY) (void *dest, const void *src, uint32_t n); +typedef void *(*SYS_MEMSET) (void *s, int32_t c, uint32_t n); +typedef int32_t(*SYS_SPRINTF) (char *str, const char *format, ...); + +#endif /* _MTK_PORTING_H_ */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/sdio/include/test_driver_sdio_ops.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/sdio/include/test_driver_sdio_ops.h new file mode 100644 index 0000000000000000000000000000000000000000..e396c4622965782b23afce5745387061b5abdb6d --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/sdio/include/test_driver_sdio_ops.h @@ -0,0 +1,48 @@ +/* + * linux/drivers/mmc/sdio_ops.c + * + * Copyright 2006-2007 Pierre Ossman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + */ + + +#ifndef __TEST_DRV_SDIO_OPS_H__ +#define __TEST_DRV_SDIO_OPS_H__ + +#include +#include +#include +#include +#include + + +int mmc_send_io_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr); +int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn, + unsigned addr, u8 in, u8 *out); +int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn, + unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz); + +int sdio_disable_wide(struct mmc_card *card); +int sdio_enable_4bit_bus(struct mmc_card *card); + + + +#include +#include +#define MMC_CMD_RETRIES 3 + +static inline void mmc_delay(unsigned int ms) +{ + if (ms < 1000 / HZ) { + cond_resched(); + mdelay(ms); + } else { + msleep(ms); + } +} + +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/sdio/sdio.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/sdio/sdio.c new file mode 100644 index 0000000000000000000000000000000000000000..a098ebe883077785676675c24ef29b5adc593740 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/sdio/sdio.c @@ -0,0 +1,1730 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/****************************************************************************** +*[File] sdio.c +*[Version] v1.0 +*[Revision Date] 2010-03-01 +*[Author] +*[Description] +* The program provides SDIO HIF driver +*[Copyright] +* Copyright (C) 2010 MediaTek Incorporation. All Rights Reserved. +******************************************************************************/ + + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +#include "gl_os.h" +#include "precomp.h" + +#if MTK_WCN_HIF_SDIO +#include "hif_sdio.h" +#else +#include +#include +#include +#include /* sdio_readl(), etc */ +#include +#endif + +#include +#ifndef CONFIG_X86 +#include +#endif + +#include "mt66xx_reg.h" + +#if (CFG_SDIO_1BIT_DATA_MODE == 1) +#include "test_driver_sdio_ops.h" +#endif + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +#define HIF_SDIO_ERR_TITLE_STR "["CHIP_NAME"] SDIO Access Error!" +#define HIF_SDIO_ERR_DESC_STR "**SDIO Access Error**\n" + +#define HIF_SDIO_ACCESS_RETRY_LIMIT 250 +#define HIF_SDIO_INTERRUPT_RESPONSE_TIMEOUT (15000) + +#if MTK_WCN_HIF_SDIO + +/* + * function prototypes + * + */ + +static int32_t mtk_sdio_probe(unsigned long, const struct MTK_WCN_HIF_SDIO_FUNCINFO *); + +static int32_t mtk_sdio_remove(unsigned long); +static int32_t mtk_sdio_interrupt(unsigned long); + +/* + * sdio function info table + */ + +static struct MTK_WCN_HIF_SDIO_FUNCINFO funcInfo[] = { + {MTK_WCN_HIF_SDIO_FUNC(0x037a, 0x6602, 0x1, 512)}, +}; + +static struct MTK_WCN_SDIO_DRIVER_DATA_MAPPING sdio_driver_data_mapping[] = { + {0x6602, &mt66xx_driver_data_mt6632}, +}; + +static struct MTK_WCN_HIF_SDIO_CLTINFO cltInfo = { + .func_tbl = funcInfo, + .func_tbl_size = sizeof(funcInfo) / sizeof(struct MTK_WCN_HIF_SDIO_FUNCINFO), + .hif_clt_probe = mtk_sdio_probe, + .hif_clt_remove = mtk_sdio_remove, + .hif_clt_irq = mtk_sdio_interrupt, +}; + +#else +/* + * function prototypes + * + */ +static int mtk_sdio_pm_suspend(struct device *pDev); +static int mtk_sdio_pm_resume(struct device *pDev); + +static const struct sdio_device_id mtk_sdio_ids[] = { +#ifdef MT6632 + { SDIO_DEVICE(0x037a, 0x6602), + .driver_data = (kernel_ulong_t)&mt66xx_driver_data_mt6632},/* Not an SDIO standard class device */ +#endif /* MT6632 */ +#ifdef MT7668 + { SDIO_DEVICE(0x037a, 0x7608), + .driver_data = (kernel_ulong_t)&mt66xx_driver_data_mt7668},/* Not an SDIO standard class device */ +#endif /* MT7668 */ +#ifdef MT7663 + { SDIO_DEVICE(0x037a, 0x7603), + .driver_data = (kernel_ulong_t)&mt66xx_driver_data_mt7663}, +#endif /* MT7663 */ + { /* end: all zeroes */ }, +}; + +MODULE_DEVICE_TABLE(sdio, mtk_sdio_ids); + +#endif + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ +static probe_card pfWlanProbe; +static remove_card pfWlanRemove; + +#if (MTK_WCN_HIF_SDIO == 0) +static const struct dev_pm_ops mtk_sdio_pm_ops = { + .suspend = mtk_sdio_pm_suspend, + .resume = mtk_sdio_pm_resume, +}; + +static struct sdio_driver mtk_sdio_driver = { + .name = "wlan", /* "MTK SDIO WLAN Driver" */ + .id_table = mtk_sdio_ids, + .probe = NULL, + .remove = NULL, + .drv = { + .owner = THIS_MODULE, + .pm = &mtk_sdio_pm_ops, + } +}; +#endif + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +#define dev_to_sdio_func(d) container_of(d, struct sdio_func, dev) + + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function is a SDIO interrupt callback function +* +* \param[in] func pointer to SDIO handle +* +* \return void +*/ +/*----------------------------------------------------------------------------*/ + +#if MTK_WCN_HIF_SDIO + +static int32_t mtk_sdio_interrupt(unsigned long cltCtx) +{ + struct GLUE_INFO *prGlueInfo = NULL; + int32_t ret = 0; + + prGlueInfo = mtk_wcn_hif_sdio_get_drvdata(cltCtx); + + /* ASSERT(prGlueInfo); */ + + if (!prGlueInfo) { + /* printk(KERN_INFO DRV_NAME"No glue info in mtk_sdio_interrupt()\n"); */ + return -HIF_SDIO_ERR_FAIL; + } + + prGlueInfo->u8HifIntTime = sched_clock(); + + prGlueInfo->IsrCnt++; + + if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { + /* printk(KERN_INFO DRV_NAME"GLUE_FLAG_HALT skip INT\n"); */ + ret = mtk_wcn_hif_sdio_writeb(cltCtx, MCR_WHLPCR, WHLPCR_INT_EN_CLR); + return ret; + } + + ret = mtk_wcn_hif_sdio_writeb(cltCtx, MCR_WHLPCR, WHLPCR_INT_EN_CLR); + + prGlueInfo->rHifInfo.fgIsPendingInt = FALSE; + + kalSetIntEvent(prGlueInfo); + prGlueInfo->IsrPassCnt++; + + return ret; +} + +#else +static void mtk_sdio_interrupt(struct sdio_func *func) +{ + struct GLUE_INFO *prGlueInfo = NULL; + + int ret = 0; + + prGlueInfo = sdio_get_drvdata(func); + /* ASSERT(prGlueInfo); */ + + if (!prGlueInfo) { + /* printk(KERN_INFO DRV_NAME"No glue info in mtk_sdio_interrupt()\n"); */ + return; + } + + if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { + sdio_writeb(prGlueInfo->rHifInfo.func, WHLPCR_INT_EN_CLR, MCR_WHLPCR, &ret); + /* printk(KERN_INFO DRV_NAME"GLUE_FLAG_HALT skip INT\n"); */ + return; + } + + sdio_writeb(prGlueInfo->rHifInfo.func, WHLPCR_INT_EN_CLR, MCR_WHLPCR, &ret); + + prGlueInfo->rHifInfo.fgIsPendingInt = FALSE; + + kalSetIntEvent(prGlueInfo); +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function is a SDIO probe function +* +* \param[in] func pointer to SDIO handle +* \param[in] id pointer to SDIO device id table +* +* \return void +*/ +/*----------------------------------------------------------------------------*/ + +#if MTK_WCN_HIF_SDIO + +/* FIXME: global variable */ +static const struct MTK_WCN_HIF_SDIO_FUNCINFO *prFunc; + +static int32_t mtk_sdio_probe(unsigned long cltCtx, const struct MTK_WCN_HIF_SDIO_FUNCINFO *prFuncInfo) +{ + int32_t ret = HIF_SDIO_ERR_SUCCESS; + int32_t i = 0; + int32_t dd_table_len = sizeof(sdio_driver_data_mapping) / sizeof(struct MTK_WCN_SDIO_DRIVER_DATA_MAPPING); + struct mt66xx_hif_driver_data *sdio_driver_data = NULL; + + prFunc = prFuncInfo; + + for (i = 0; i < dd_table_len; i++) { + if (prFunc->card_id == sdio_driver_data_mapping[i].card_id) { + sdio_driver_data = sdio_driver_data_mapping[i].mt66xx_driver_data; + break; + } + } + + if (sdio_driver_data == NULL) { + DBGLOG(HAL, ERROR, "sdio probe error: %x driver data not found!\n", prFunc->card_id); + return HIF_SDIO_ERR_UNSUP_CARD_ID; + } + + if (pfWlanProbe((void *)&cltCtx, (void *) sdio_driver_data) != WLAN_STATUS_SUCCESS) { + /* printk(KERN_WARNING DRV_NAME"pfWlanProbe fail!call pfWlanRemove()\n"); */ + pfWlanRemove(); + ret = -(HIF_SDIO_ERR_FAIL); + } else { + /* printk(KERN_INFO DRV_NAME"mtk_wifi_sdio_probe() done(%d)\n", ret); */ + } + return ret; +} +#else +static int mtk_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) +{ + int ret = 0; + /* int i = 0; */ + + /* printk(KERN_INFO DRV_NAME "mtk_sdio_probe()\n"); */ + + ASSERT(func); + ASSERT(id); + /* + *printk(KERN_INFO DRV_NAME "Basic struct size checking...\n"); + *printk(KERN_INFO DRV_NAME "sizeof(struct device) = %d\n", sizeof(struct device)); + *printk(KERN_INFO DRV_NAME "sizeof(struct mmc_host) = %d\n", sizeof(struct mmc_host)); + *printk(KERN_INFO DRV_NAME "sizeof(struct mmc_card) = %d\n", sizeof(struct mmc_card)); + *printk(KERN_INFO DRV_NAME "sizeof(struct mmc_driver) = %d\n", sizeof(struct mmc_driver)); + *printk(KERN_INFO DRV_NAME "sizeof(struct mmc_data) = %d\n", sizeof(struct mmc_data)); + *printk(KERN_INFO DRV_NAME "sizeof(struct mmc_command) = %d\n", sizeof(struct mmc_command)); + *printk(KERN_INFO DRV_NAME "sizeof(struct mmc_request) = %d\n", sizeof(struct mmc_request)); + *printk(KERN_INFO DRV_NAME "sizeof(struct sdio_func) = %d\n", sizeof(struct sdio_func)); + * + *printk(KERN_INFO DRV_NAME "Card information checking...\n"); + *printk(KERN_INFO DRV_NAME "func = 0x%p\n", func); + *printk(KERN_INFO DRV_NAME "Number of info = %d:\n", func->card->num_info); + * + * + *for (i = 0; i < func->card->num_info; i++) + * printk(KERN_INFO DRV_NAME "info[%d]: %s\n", i, func->card->info[i]); + * + */ + + sdio_claim_host(func); + ret = sdio_enable_func(func); + sdio_release_host(func); + + if (ret) { + /* printk(KERN_INFO DRV_NAME"sdio_enable_func failed!\n"); */ + goto out; + } + /* printk(KERN_INFO DRV_NAME"sdio_enable_func done!\n"); */ + + if (pfWlanProbe((void *) func, (void *) id->driver_data) != WLAN_STATUS_SUCCESS) { + /* printk(KERN_WARNING DRV_NAME"pfWlanProbe fail!call pfWlanRemove()\n"); */ + pfWlanRemove(); + ret = -1; + } + +out: + /* printk(KERN_INFO DRV_NAME"mtk_sdio_probe() done(%d)\n", ret); */ + return ret; +} +#endif + +#if MTK_WCN_HIF_SDIO +static int32_t mtk_sdio_remove(unsigned long cltCtx) +{ + int32_t ret = HIF_SDIO_ERR_SUCCESS; + /* printk(KERN_INFO DRV_NAME"pfWlanRemove done\n"); */ + pfWlanRemove(); + + return ret; +} +#else +static void mtk_sdio_remove(struct sdio_func *func) +{ + /* printk(KERN_INFO DRV_NAME"mtk_sdio_remove()\n"); */ + + ASSERT(func); + /* printk(KERN_INFO DRV_NAME"pfWlanRemove done\n"); */ + pfWlanRemove(); + + sdio_claim_host(func); + sdio_disable_func(func); + /* printk(KERN_INFO DRV_NAME"sdio_disable_func() done\n"); */ + sdio_release_host(func); + + /* printk(KERN_INFO DRV_NAME"mtk_sdio_remove() done\n"); */ +} +#endif + +#if (MTK_WCN_HIF_SDIO == 0) +static int mtk_sdio_pm_suspend(struct device *pDev) +{ + int ret = 0, wait = 0; + int pm_caps, set_flag; + const char *func_id; + struct sdio_func *func; + struct GLUE_INFO *prGlueInfo = NULL; + struct ADAPTER *prAdapter = NULL; + uint8_t drv_own_fail = FALSE; + + DBGLOG(HAL, STATE, "==>\n"); + + func = dev_to_sdio_func(pDev); + prGlueInfo = sdio_get_drvdata(func); + prAdapter = prGlueInfo->prAdapter; + + DBGLOG(REQ, STATE, "Wow:%d, WowEnable:%d, state:%d\n", + prAdapter->rWifiVar.ucWow, + prAdapter->rWowCtrl.fgWowEnable, + kalGetMediaStateIndicated(prGlueInfo, AIS_DEFAULT_INDEX)); + + /* 1) wifi cfg "Wow" is true + * 2) wow is enable + * 3) WIfI connected => execute WOW flow + */ + if (prAdapter->rWifiVar.ucWow && prAdapter->rWowCtrl.fgWowEnable && + (kalGetMediaStateIndicated(prGlueInfo, AIS_DEFAULT_INDEX) == + MEDIA_STATE_CONNECTED)) { + DBGLOG(HAL, STATE, "enter WOW flow\n"); + kalWowProcess(prGlueInfo, TRUE); + } + + prGlueInfo->rHifInfo.fgForceFwOwn = TRUE; + + /* Wait for + * 1. The other unfinished ownership handshakes + * 2. FW own back + */ + while (wait < 100) { + if ((prAdapter->u4PwrCtrlBlockCnt == 0) && + (prAdapter->fgIsFwOwn == TRUE) && + (drv_own_fail == FALSE)) { + DBGLOG(HAL, STATE, "************************\n"); + DBGLOG(HAL, STATE, "* Entered SDIO Suspend *\n"); + DBGLOG(HAL, STATE, "************************\n"); + DBGLOG(HAL, INFO, "wait = %d\n\n", wait); + break; + } + + ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); + /* Prevent that suspend without FW Own: + * Set Drv own has failed, and then Set FW Own is skipped + */ + if (prAdapter->fgIsFwOwn == FALSE) + drv_own_fail = FALSE; + else + drv_own_fail = TRUE; + /* For single core CPU, let hif_thread can be completed */ + kalMsleep(10); + RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); + + wait++; + } + + if (wait >= 100) { + DBGLOG(HAL, ERROR, "Set FW Own Timeout !!\n"); + return -EAGAIN; + } + + pm_caps = sdio_get_host_pm_caps(func); + func_id = sdio_func_id(func); + + /* Ask kernel keeping SDIO bus power-on */ + set_flag = MMC_PM_KEEP_POWER; + ret = sdio_set_host_pm_flags(func, set_flag); + if (ret) { + DBGLOG(HAL, ERROR, "set flag %d err %d\n", set_flag, ret); + DBGLOG(HAL, ERROR, + "%s: cannot remain alive(0x%X)\n", func_id, pm_caps); + } + + /* If wow enable, ask kernel accept SDIO IRQ in suspend mode */ + if (prAdapter->rWifiVar.ucWow && + prAdapter->rWowCtrl.fgWowEnable) { + set_flag = MMC_PM_WAKE_SDIO_IRQ; + ret = sdio_set_host_pm_flags(func, set_flag); + if (ret) { + DBGLOG(HAL, ERROR, "set flag %d err %d\n", set_flag, ret); + DBGLOG(HAL, ERROR, + "%s: cannot sdio wake-irq(0x%X)\n", func_id, pm_caps); + } + } + + DBGLOG(HAL, STATE, "<==\n"); + return 0; +} + +static int mtk_sdio_pm_resume(struct device *pDev) +{ + struct sdio_func *func; + struct GLUE_INFO *prGlueInfo = NULL; + + DBGLOG(HAL, STATE, "==>\n"); + + func = dev_to_sdio_func(pDev); + prGlueInfo = sdio_get_drvdata(func); + + DBGLOG(REQ, STATE, "Wow:%d, WowEnable:%d, state:%d\n", + prGlueInfo->prAdapter->rWifiVar.ucWow, + prGlueInfo->prAdapter->rWowCtrl.fgWowEnable, + kalGetMediaStateIndicated(prGlueInfo, AIS_DEFAULT_INDEX)); + + prGlueInfo->rHifInfo.fgForceFwOwn = FALSE; + + if (prGlueInfo->prAdapter->rWifiVar.ucWow && + prGlueInfo->prAdapter->rWowCtrl.fgWowEnable && + (kalGetMediaStateIndicated(prGlueInfo, AIS_DEFAULT_INDEX) == + MEDIA_STATE_CONNECTED)) { + DBGLOG(HAL, STATE, "leave WOW flow\n"); + kalWowProcess(prGlueInfo, FALSE); + } + + DBGLOG(HAL, STATE, "<==\n"); + return 0; +} + +static int mtk_sdio_suspend(struct device *pDev, pm_message_t state) +{ + /* printk(KERN_INFO "mtk_sdio: mtk_sdio_suspend dev(0x%p)\n", pDev); */ + /* printk(KERN_INFO "mtk_sdio: MediaTek SDIO WLAN driver\n"); */ + + return mtk_sdio_pm_suspend(pDev); +} + +int mtk_sdio_resume(struct device *pDev) +{ + /* printk(KERN_INFO "mtk_sdio: mtk_sdio_resume dev(0x%p)\n", pDev); */ + + return mtk_sdio_pm_resume(pDev); +} +#if (CFG_SDIO_ASYNC_IRQ_AUTO_ENABLE == 1) +int mtk_sdio_async_irq_enable(struct sdio_func *func) +{ +#define SDIO_CCCR_IRQ_EXT 0x16 +#define SDIO_IRQ_EXT_SAI BIT(0) +#define SDIO_IRQ_EXT_EAI BIT(1) + unsigned char data = 0; + unsigned int quirks_bak; + int ret; + + /* Read CCCR 0x16 (interrupt extension)*/ + data = sdio_f0_readb(func, SDIO_CCCR_IRQ_EXT, &ret); + if (ret) { + DBGLOG(HAL, ERROR, "CCCR 0x%X read fail (%d).\n", SDIO_CCCR_IRQ_EXT, ret); + return FALSE; + } + /* Check CCCR capability status */ + if (!(data & SDIO_IRQ_EXT_SAI)) { + /* SAI = 0 */ + DBGLOG(HAL, ERROR, "No Async-IRQ capability.\n"); + return FALSE; + } else if (data & SDIO_IRQ_EXT_EAI) { + /* EAI = 1 */ + DBGLOG(INIT, INFO, "Async-IRQ enabled already.\n"); + return TRUE; + } + + /* Set EAI bit */ + data |= SDIO_IRQ_EXT_EAI; + + /* Enable capability to write CCCR */ + quirks_bak = func->card->quirks; + func->card->quirks |= MMC_QUIRK_LENIENT_FN0; + /* Write CCCR into card */ + sdio_f0_writeb(func, data, SDIO_CCCR_IRQ_EXT, &ret); + if (ret) { + DBGLOG(HAL, ERROR, "CCCR 0x%X write fail (%d).\n", SDIO_CCCR_IRQ_EXT, ret); + return FALSE; + } + func->card->quirks = quirks_bak; + + data = sdio_f0_readb(func, SDIO_CCCR_IRQ_EXT, &ret); + if (ret || !(data & SDIO_IRQ_EXT_EAI)) { + DBGLOG(HAL, ERROR, "CCCR 0x%X write fail (%d).\n", SDIO_CCCR_IRQ_EXT, ret); + return FALSE; + } + return TRUE; +} +#endif +#endif + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function will register sdio bus to the os +* +* \param[in] pfProbe Function pointer to detect card +* \param[in] pfRemove Function pointer to remove card +* +* \return The result of registering sdio bus +*/ +/*----------------------------------------------------------------------------*/ +uint32_t glRegisterBus(probe_card pfProbe, remove_card pfRemove) +{ + int ret = 0; + + ASSERT(pfProbe); + ASSERT(pfRemove); + + /* printk(KERN_INFO "mtk_sdio: MediaTek SDIO WLAN driver\n"); */ + /* printk(KERN_INFO "mtk_sdio: Copyright MediaTek Inc.\n"); */ + + pfWlanProbe = pfProbe; + pfWlanRemove = pfRemove; + +#if MTK_WCN_HIF_SDIO + /* register MTK sdio client */ + ret = + ((mtk_wcn_hif_sdio_client_reg(&cltInfo) == + HIF_SDIO_ERR_SUCCESS) ? WLAN_STATUS_SUCCESS : WLAN_STATUS_FAILURE); +#else + mtk_sdio_driver.probe = mtk_sdio_probe; + mtk_sdio_driver.remove = mtk_sdio_remove; + + mtk_sdio_driver.drv.suspend = mtk_sdio_suspend; + mtk_sdio_driver.drv.resume = mtk_sdio_resume; + + ret = (sdio_register_driver(&mtk_sdio_driver) == 0) ? WLAN_STATUS_SUCCESS : WLAN_STATUS_FAILURE; +#endif + + return ret; +} /* end of glRegisterBus() */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function will unregister sdio bus to the os +* +* \param[in] pfRemove Function pointer to remove card +* +* \return (none) +*/ +/*----------------------------------------------------------------------------*/ +void glUnregisterBus(remove_card pfRemove) +{ + ASSERT(pfRemove); + pfRemove(); + +#if MTK_WCN_HIF_SDIO + /* unregister MTK sdio client */ + mtk_wcn_hif_sdio_client_unreg(&cltInfo); +#else + sdio_unregister_driver(&mtk_sdio_driver); +#endif +} /* end of glUnregisterBus() */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function stores hif related info, which is initialized before. +* +* \param[in] prGlueInfo Pointer to glue info structure +* \param[in] u4Cookie Pointer to UINT_32 memory base variable for _HIF_HPI +* +* \return (none) +*/ +/*----------------------------------------------------------------------------*/ +void glSetHifInfo(struct GLUE_INFO *prGlueInfo, unsigned long ulCookie) +{ + struct GL_HIF_INFO *prHif = NULL; + uint8_t ucIdx; + + prHif = &prGlueInfo->rHifInfo; + + QUEUE_INITIALIZE(&prHif->rFreeQueue); + QUEUE_INITIALIZE(&prHif->rRxDeAggQueue); + QUEUE_INITIALIZE(&prHif->rRxFreeBufQueue); + +#if MTK_WCN_HIF_SDIO + /* prHif->prFuncInfo = ((MTK_WCN_HIF_SDIO_FUNCINFO *) u4Cookie); */ + prHif->prFuncInfo = prFunc; + prHif->cltCtx = *((unsigned long *) ulCookie); + mtk_wcn_hif_sdio_set_drvdata(prHif->cltCtx, prGlueInfo); + +#else + prHif->func = (struct sdio_func *)ulCookie; + + /* printk(KERN_INFO DRV_NAME"prHif->func->dev = 0x%p\n", &prHif->func->dev); */ + /* printk(KERN_INFO DRV_NAME"prHif->func->vendor = 0x%04X\n", prHif->func->vendor); */ + /* printk(KERN_INFO DRV_NAME"prHif->func->device = 0x%04X\n", prHif->func->device); */ + /* printk(KERN_INFO DRV_NAME"prHif->func->func = 0x%04X\n", prHif->func->num); */ + + sdio_set_drvdata(prHif->func, prGlueInfo); + + SET_NETDEV_DEV(prGlueInfo->prDevHandler, &prHif->func->dev); +#endif + + /* Reset statistic counter */ + kalMemZero(&prHif->rStatCounter, sizeof(struct SDIO_STAT_COUNTER)); + + for (ucIdx = HIF_TXC_IDX_0; ucIdx < HIF_TXC_IDX_NUM; ucIdx++) + prHif->au4PendingTxDoneCount[ucIdx] = 0; + + mutex_init(&prHif->rRxFreeBufQueMutex); + mutex_init(&prHif->rRxDeAggQueMutex); + + prHif->fgSkipRx = FALSE; + prGlueInfo->u4InfType = MT_DEV_INF_SDIO; +} /* end of glSetHifInfo() */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function clears hif related info. +* +* \param[in] prGlueInfo Pointer to glue info structure +* +* \return (none) +*/ +/*----------------------------------------------------------------------------*/ +void glClearHifInfo(struct GLUE_INFO *prGlueInfo) +{ + /* P_GL_HIF_INFO_T prHif = NULL; */ + /* ASSERT(prGlueInfo); */ + /* prHif = &prGlueInfo->rHifInfo; */ +} /* end of glClearHifInfo() */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Initialize bus operation and hif related information, request resources. +* +* \param[out] pvData A pointer to HIF-specific data type buffer. +* For eHPI, pvData is a pointer to UINT_32 type and stores a +* mapped base address. +* +* \return (none) +*/ +/*----------------------------------------------------------------------------*/ +u_int8_t glBusInit(void *pvData) +{ +#if (MTK_WCN_HIF_SDIO == 0) + int ret = 0; + struct sdio_func *func = NULL; + + ASSERT(pvData); + + func = (struct sdio_func *)pvData; + + sdio_claim_host(func); + +#if (CFG_SDIO_1BIT_DATA_MODE == 1) + ret = sdio_disable_wide(func->card); + if (ret) + DBGLOG(HAL, ERROR, "glBusInit() Error at enabling SDIO 1-BIT data mode.\n"); + else + DBGLOG(HAL, INFO, "glBusInit() SDIO 1-BIT data mode is working.\n"); +#endif + +#if (CFG_SDIO_ASYNC_IRQ_AUTO_ENABLE == 1) + ret = mtk_sdio_async_irq_enable(func); + if (ret == FALSE) + DBGLOG(HAL, ERROR, "Async-IRQ auto-enable fail.\n"); + else + DBGLOG(INIT, INFO, "Async-IRQ is enabled.\n"); +#endif + + ret = sdio_set_block_size(func, 512); + sdio_release_host(func); + + if (ret) { + /* printk(KERN_INFO + * DRV_NAME"sdio_set_block_size 512 failed!\n"); + */ + } else { + /* printk(KERN_INFO + * DRV_NAME"sdio_set_block_size 512 done!\n"); + */ + } + + /* printk(KERN_INFO DRV_NAME"param: func->cur_blksize(%d)\n", func->cur_blksize); */ + /* printk(KERN_INFO DRV_NAME"param: func->max_blksize(%d)\n", func->max_blksize); */ + /* printk(KERN_INFO DRV_NAME"param: func->card->host->max_blk_size(%d)\n", func->card->host->max_blk_size); */ + /* printk(KERN_INFO DRV_NAME"param: func->card->host->max_blk_count(%d)\n", func->card->host->max_blk_count); */ +#endif + return TRUE; +} /* end of glBusInit() */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Stop bus operation and release resources. +* +* \param[in] pvData A pointer to struct net_device. +* +* \return (none) +*/ +/*----------------------------------------------------------------------------*/ +void glBusRelease(void *pvData) +{ +} /* end of glBusRelease() */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Setup bus interrupt operation and interrupt handler for os. +* +* \param[in] pvData A pointer to struct net_device. +* \param[in] pfnIsr A pointer to interrupt handler function. +* \param[in] pvCookie Private data for pfnIsr function. +* +* \retval WLAN_STATUS_SUCCESS if success +* NEGATIVE_VALUE if fail +*/ +/*----------------------------------------------------------------------------*/ +int32_t glBusSetIrq(void *pvData, void *pfnIsr, void *pvCookie) +{ + int ret = 0; + + struct net_device *prNetDevice = NULL; + struct GLUE_INFO *prGlueInfo = NULL; + struct GL_HIF_INFO *prHifInfo = NULL; + + ASSERT(pvData); + if (!pvData) + return -1; + + prNetDevice = (struct net_device *)pvData; + prGlueInfo = (struct GLUE_INFO *) pvCookie; + ASSERT(prGlueInfo); + if (!prGlueInfo) + return -1; + + prHifInfo = &prGlueInfo->rHifInfo; + +#if (MTK_WCN_HIF_SDIO == 0) + sdio_claim_host(prHifInfo->func); + ret = sdio_claim_irq(prHifInfo->func, mtk_sdio_interrupt); + sdio_release_host(prHifInfo->func); +#else + mtk_wcn_hif_sdio_enable_irq(prHifInfo->cltCtx, TRUE); +#endif + + prHifInfo->fgIsPendingInt = FALSE; + + prHifInfo->u4IntLogIdx = 0; + prHifInfo->ucIntLogEntry = 0; + + return ret; +} /* end of glBusSetIrq() */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Stop bus interrupt operation and disable interrupt handling for os. +* +* \param[in] pvData A pointer to struct net_device. +* \param[in] pvCookie Private data for pfnIsr function. +* +* \return (none) +*/ +/*----------------------------------------------------------------------------*/ +void glBusFreeIrq(void *pvData, void *pvCookie) +{ + struct net_device *prNetDevice = NULL; + struct GLUE_INFO *prGlueInfo = NULL; + struct GL_HIF_INFO *prHifInfo = NULL; + + ASSERT(pvData); + if (!pvData) { + /* printk(KERN_INFO DRV_NAME"%s null pvData\n", __FUNCTION__); */ + return; + } + prNetDevice = (struct net_device *)pvData; + prGlueInfo = (struct GLUE_INFO *) pvCookie; + ASSERT(prGlueInfo); + if (!prGlueInfo) { + /* printk(KERN_INFO DRV_NAME"%s no glue info\n", __FUNCTION__); */ + return; + } + + prHifInfo = &prGlueInfo->rHifInfo; +#if (MTK_WCN_HIF_SDIO == 0) + sdio_claim_host(prHifInfo->func); + sdio_release_irq(prHifInfo->func); + sdio_release_host(prHifInfo->func); +#else + mtk_wcn_hif_sdio_enable_irq(prHifInfo->cltCtx, FALSE); +#endif +} /* end of glBusreeIrq() */ + +u_int8_t glIsReadClearReg(uint32_t u4Address) +{ + switch (u4Address) { + case MCR_WHISR: + case MCR_WASR: + case MCR_D2HRM0R: + case MCR_D2HRM1R: + case MCR_WTQCR0: + case MCR_WTQCR1: + case MCR_WTQCR2: + case MCR_WTQCR3: + case MCR_WTQCR4: + case MCR_WTQCR5: + case MCR_WTQCR6: + case MCR_WTQCR7: + return TRUE; + + default: + return FALSE; + } +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Read a 32-bit device register of SDIO host driver domian +* +* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. +* \param[in] u4Register Register offset +* \param[in] pu4Value Pointer to variable used to store read value +* +* \retval TRUE operation success +* \retval FALSE operation fail +*/ +/*----------------------------------------------------------------------------*/ +u_int8_t kalDevRegRead(IN struct GLUE_INFO *prGlueInfo, IN uint32_t u4Register, OUT uint32_t *pu4Value) +{ + int ret = 0; + uint8_t ucRetryCount = 0; + + ASSERT(prGlueInfo); + ASSERT(pu4Value); + + do { +#if MTK_WCN_HIF_SDIO + ret = mtk_wcn_hif_sdio_readl(prGlueInfo->rHifInfo.cltCtx, u4Register, (uint32_t *) pu4Value); +#else + sdio_claim_host(prGlueInfo->rHifInfo.func); + *pu4Value = sdio_readl(prGlueInfo->rHifInfo.func, u4Register, &ret); + sdio_release_host(prGlueInfo->rHifInfo.func); +#endif + + if (ret || ucRetryCount) { + /* DBGLOG(HAL, ERROR, + * ("sdio_readl() addr: 0x%08x value: 0x%08x status: %x retry: %u\n", + * u4Register, (unsigned int)*pu4Value, (unsigned int)ret, ucRetryCount)); + */ + + if (glIsReadClearReg(u4Register) && (ucRetryCount == 0)) { + /* Read Snapshot CR instead */ + u4Register = MCR_WSR; + } + } + + ucRetryCount++; + if (ucRetryCount > HIF_SDIO_ACCESS_RETRY_LIMIT) + break; + } while (ret); + + if (ret) { + kalSendAeeWarning(HIF_SDIO_ERR_TITLE_STR, + HIF_SDIO_ERR_DESC_STR "sdio_readl() reports error: %x retry: %u", ret, ucRetryCount); + DBGLOG(HAL, ERROR, "sdio_readl() reports error: %x retry: %u\n", ret, ucRetryCount); + } + + return (ret) ? FALSE : TRUE; +} /* end of kalDevRegRead() */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Read a 32-bit device register of chip firmware register domain +* +* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. +* \param[in] u4Register Register offset +* \param[in] pu4Value Pointer to variable used to store read value +* +* \retval TRUE operation success +* \retval FALSE operation fail +*/ +/*----------------------------------------------------------------------------*/ +u_int8_t kalDevRegRead_mac(IN struct GLUE_INFO *prGlueInfo, IN uint32_t u4Register, OUT uint32_t *pu4Value) +{ + uint32_t value; + uint32_t u4Time, u4Current; + uint8_t ucResult;/* For Unchecked return value*/ + + /* progrqm h2d mailbox0 as interested register address */ + ucResult = kalDevRegWrite(prGlueInfo, MCR_H2DSM0R, u4Register); + + /* set h2d interrupt to notify firmware. bit16 */ + ucResult = kalDevRegWrite(prGlueInfo, MCR_WSICR, + SDIO_MAILBOX_FUNC_READ_REG_IDX); + + /* polling interrupt status asserted. bit16 */ + + /* first, disable interrupt enable for SDIO_MAILBOX_FUNC_READ_REG_IDX */ + ucResult = kalDevRegRead(prGlueInfo, MCR_WHIER, &value); + ucResult = kalDevRegWrite(prGlueInfo, MCR_WHIER, + (value & ~SDIO_MAILBOX_FUNC_READ_REG_IDX)); + + u4Time = (uint32_t) kalGetTimeTick(); + + do { + /* check bit16 of WHISR assert for read register response */ + ucResult = kalDevRegRead(prGlueInfo, MCR_WHISR, &value); + + if (value & SDIO_MAILBOX_FUNC_READ_REG_IDX) { + /* read d2h mailbox0 for interested register address */ + ucResult = kalDevRegRead(prGlueInfo, + MCR_D2HRM0R, &value); + + if (value != u4Register) { + DBGLOG(HAL, ERROR, "ERROR! kalDevRegRead_mac():register address mis-match"); + DBGLOG(HAL, ERROR, "(u4Register = 0x%08x, reported register = 0x%08x)\n", + u4Register, value); + return FALSE; + } + + /* read d2h mailbox1 for the value of the register */ + ucResult = kalDevRegRead(prGlueInfo, + MCR_D2HRM1R, &value); + *pu4Value = value; + return TRUE; + } + + /* timeout exceeding check */ + u4Current = (uint32_t) kalGetTimeTick(); + + if (((u4Current > u4Time) && ((u4Current - u4Time) > HIF_SDIO_INTERRUPT_RESPONSE_TIMEOUT)) + || (u4Current < u4Time && ((u4Current + (0xFFFFFFFF - u4Time)) + > HIF_SDIO_INTERRUPT_RESPONSE_TIMEOUT))) { + DBGLOG(HAL, ERROR, "ERROR: kalDevRegRead_mac(): response timeout\n"); + return FALSE; + } + + /* Response packet is not ready */ + kalUdelay(50); + } while (1); +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Write a 32-bit device register of SDIO driver domian +* +* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. +* \param[in] u4Register Register offset +* \param[in] u4Value Value to be written +* +* \retval TRUE operation success +* \retval FALSE operation fail +*/ +/*----------------------------------------------------------------------------*/ +u_int8_t kalDevRegWrite(IN struct GLUE_INFO *prGlueInfo, IN uint32_t u4Register, IN uint32_t u4Value) +{ + int ret = 0; + uint8_t ucRetryCount = 0; + + ASSERT(prGlueInfo); + + do { +#if MTK_WCN_HIF_SDIO + ret = mtk_wcn_hif_sdio_writel(prGlueInfo->rHifInfo.cltCtx, u4Register, u4Value); +#else + sdio_claim_host(prGlueInfo->rHifInfo.func); + sdio_writel(prGlueInfo->rHifInfo.func, u4Value, u4Register, &ret); + sdio_release_host(prGlueInfo->rHifInfo.func); +#endif + + if (ret || ucRetryCount) { + /* DBGLOG(HAL, ERROR, + * ("sdio_writel() addr: 0x%x status: %x retry: %u\n", u4Register, + * ret, ucRetryCount)); + */ + } + + ucRetryCount++; + if (ucRetryCount > HIF_SDIO_ACCESS_RETRY_LIMIT) + break; + + } while (ret); + + if (ret) { + kalSendAeeWarning(HIF_SDIO_ERR_TITLE_STR, + HIF_SDIO_ERR_DESC_STR "sdio_writel() reports error: %x retry: %u", ret, ucRetryCount); + DBGLOG(HAL, ERROR, "sdio_writel() reports error: %x retry: %u\n", ret, ucRetryCount); + } + + return (ret) ? FALSE : TRUE; +} /* end of kalDevRegWrite() */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Write a 32-bit device register of chip firmware register domain +* +* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. +* \param[in] u4Register Register offset +* \param[in] u4Value Value to be written +* +* \retval TRUE operation success +* \retval FALSE operation fail +*/ +/*----------------------------------------------------------------------------*/ +u_int8_t kalDevRegWrite_mac(IN struct GLUE_INFO *prGlueInfo, IN uint32_t u4Register, IN uint32_t u4Value) +{ + uint32_t value; + uint32_t u4Time, u4Current; + uint8_t ucResult; /* For Unchecked return value*/ + + /* progrqm h2d mailbox0 as interested register address */ + ucResult = kalDevRegWrite(prGlueInfo, MCR_H2DSM0R, u4Register); + + /* progrqm h2d mailbox1 as the value to write */ + ucResult = kalDevRegWrite(prGlueInfo, MCR_H2DSM1R, u4Value); + + /* set h2d interrupt to notify firmware bit17 */ + ucResult = kalDevRegWrite(prGlueInfo, MCR_WSICR, + SDIO_MAILBOX_FUNC_WRITE_REG_IDX); + + /* polling interrupt status asserted. bit17 */ + + /* first, disable interrupt enable for SDIO_MAILBOX_FUNC_WRITE_REG_IDX */ + ucResult = kalDevRegRead(prGlueInfo, MCR_WHIER, &value); + ucResult = kalDevRegWrite(prGlueInfo, MCR_WHIER, + (value & ~SDIO_MAILBOX_FUNC_WRITE_REG_IDX)); + + u4Time = (uint32_t) kalGetTimeTick(); + + do { + /* check bit17 of WHISR assert for response */ + ucResult = kalDevRegRead(prGlueInfo, MCR_WHISR, &value); + + if (value & SDIO_MAILBOX_FUNC_WRITE_REG_IDX) { + /* read d2h mailbox0 for interested register address */ + ucResult = kalDevRegRead(prGlueInfo, + MCR_D2HRM0R, &value); + + if (value != u4Register) { + DBGLOG(HAL, ERROR, "ERROR! kalDevRegWrite_mac():register address mis-match"); + DBGLOG(HAL, ERROR, "(u4Register = 0x%08x, reported register = 0x%08x)\n", + u4Register, value); + return FALSE; + } + return TRUE; + } + + /* timeout exceeding check */ + u4Current = (uint32_t) kalGetTimeTick(); + + if (((u4Current > u4Time) && ((u4Current - u4Time) > HIF_SDIO_INTERRUPT_RESPONSE_TIMEOUT)) + || (u4Current < u4Time && ((u4Current + (0xFFFFFFFF - u4Time)) + > HIF_SDIO_INTERRUPT_RESPONSE_TIMEOUT))) { + DBGLOG(HAL, ERROR, "ERROR: kalDevRegWrite_mac(): response timeout\n"); + return FALSE; + } + + /* Response packet is not ready */ + kalUdelay(50); + } while (1); +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Read device I/O port +* +* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. +* \param[in] u2Port I/O port offset +* \param[in] u2Len Length to be read +* \param[out] pucBuf Pointer to read buffer +* \param[in] u2ValidOutBufSize Length of the buffer valid to be accessed +* +* \retval TRUE operation success +* \retval FALSE operation fail +*/ +/*----------------------------------------------------------------------------*/ +u_int8_t +kalDevPortRead(IN struct GLUE_INFO *prGlueInfo, + IN uint16_t u2Port, IN uint32_t u4Len, OUT uint8_t *pucBuf, IN uint32_t u4ValidOutBufSize) +{ + struct GL_HIF_INFO *prHifInfo = NULL; + uint8_t *pucDst = NULL; + int count = u4Len; + int ret = 0; + int bNum = 0; + +#if (MTK_WCN_HIF_SDIO == 0) + struct sdio_func *prSdioFunc = NULL; +#endif + +#if DBG + /* printk(KERN_INFO DRV_NAME"++kalDevPortRead++ buf:0x%p, port:0x%x, length:%d\n", pucBuf, u2Port, u4Len); */ +#endif + + ASSERT(prGlueInfo); + prHifInfo = &prGlueInfo->rHifInfo; + + ASSERT(pucBuf); + pucDst = pucBuf; + + ASSERT(u4Len <= u4ValidOutBufSize); + +#if (MTK_WCN_HIF_SDIO == 0) + prSdioFunc = prHifInfo->func; + + ASSERT(prSdioFunc->cur_blksize > 0); + + sdio_claim_host(prSdioFunc); + + /* Split buffer into multiple single block to workaround hifsys */ + while (count >= prSdioFunc->cur_blksize) { + count -= prSdioFunc->cur_blksize; + bNum++; + } + if (count > 0 && bNum > 0) + bNum++; + + if (bNum > 0) { + ret = sdio_readsb(prSdioFunc, pucDst, u2Port, prSdioFunc->cur_blksize * bNum); + +#ifdef CONFIG_X86 + /* ENE workaround */ + { + int tmp; + + sdio_writel(prSdioFunc, 0x0, SDIO_X86_WORKAROUND_WRITE_MCR, &tmp); + } +#endif + + } else { + ret = sdio_readsb(prSdioFunc, pucDst, u2Port, count); + } + + sdio_release_host(prSdioFunc); +#else + + /* Split buffer into multiple single block to workaround hifsys */ + while (count >= (prGlueInfo->rHifInfo).prFuncInfo->blk_sz) { + count -= ((prGlueInfo->rHifInfo).prFuncInfo->blk_sz); + bNum++; + } + if (count > 0 && bNum > 0) + bNum++; + + if (bNum > 0) { + ret = + mtk_wcn_hif_sdio_read_buf(prGlueInfo->rHifInfo.cltCtx, u2Port, (uint32_t *) pucDst, + ((prGlueInfo->rHifInfo).prFuncInfo->blk_sz) * bNum); + } else { + ret = mtk_wcn_hif_sdio_read_buf(prGlueInfo->rHifInfo.cltCtx, u2Port, (uint32_t *) pucDst, count); + } +#endif + + if (ret) { + kalSendAeeWarning(HIF_SDIO_ERR_TITLE_STR, HIF_SDIO_ERR_DESC_STR "sdio_readsb() reports error: %d", ret); + + DBGLOG(HAL, ERROR, "\n"); + DBGLOG(HAL, ERROR, "\nSDIO BUS ERROR: "); + DBGLOG(HAL, ERROR, "sdio_readsb() reports error: %d\n", ret); + DBGLOG(HAL, ERROR, "\n"); + } + + return (ret) ? FALSE : TRUE; +} /* end of kalDevPortRead() */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Write device I/O port +* +* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. +* \param[in] u2Port I/O port offset +* \param[in] u2Len Length to be write +* \param[in] pucBuf Pointer to write buffer +* \param[in] u2ValidInBufSize Length of the buffer valid to be accessed +* +* \retval TRUE operation success +* \retval FALSE operation fail +*/ +/*----------------------------------------------------------------------------*/ +u_int8_t +kalDevPortWrite(IN struct GLUE_INFO *prGlueInfo, + IN uint16_t u2Port, IN uint32_t u4Len, IN uint8_t *pucBuf, IN uint32_t u4ValidInBufSize) +{ + struct GL_HIF_INFO *prHifInfo = NULL; + uint8_t *pucSrc = NULL; + int count = u4Len; + int ret = 0; + int bNum = 0; + +#if (MTK_WCN_HIF_SDIO == 0) + struct sdio_func *prSdioFunc = NULL; +#endif + +#if DBG + /* printk(KERN_INFO DRV_NAME"++kalDevPortWrite++ buf:0x%p, port:0x%x, length:%d\n", pucBuf, u2Port, u2Len); */ +#endif + + ASSERT(prGlueInfo); + prHifInfo = &prGlueInfo->rHifInfo; + + ASSERT(pucBuf); + pucSrc = pucBuf; + + ASSERT(u4Len <= u4ValidInBufSize); + +#if (MTK_WCN_HIF_SDIO == 0) + prSdioFunc = prHifInfo->func; + ASSERT(prSdioFunc->cur_blksize > 0); + + sdio_claim_host(prSdioFunc); + + /* Split buffer into multiple single block to workaround hifsys */ + while (count >= prSdioFunc->cur_blksize) { + count -= prSdioFunc->cur_blksize; + bNum++; + } + if (count > 0 && bNum > 0) + bNum++; + + if (bNum > 0) { /* block mode */ + ret = sdio_writesb(prSdioFunc, u2Port, pucSrc, prSdioFunc->cur_blksize * bNum); + +#ifdef CONFIG_X86 + /* ENE workaround */ + { + int tmp; + + sdio_writel(prSdioFunc, 0x0, SDIO_X86_WORKAROUND_WRITE_MCR, &tmp); + } +#endif + + } else { /* byte mode */ + + ret = sdio_writesb(prSdioFunc, u2Port, pucSrc, count); + } + + sdio_release_host(prSdioFunc); +#else + /* Split buffer into multiple single block to workaround hifsys */ + while (count >= ((prGlueInfo->rHifInfo).prFuncInfo->blk_sz)) { + count -= ((prGlueInfo->rHifInfo).prFuncInfo->blk_sz); + bNum++; + } + if (count > 0 && bNum > 0) + bNum++; + + if (bNum > 0) { /* block mode */ + ret = + mtk_wcn_hif_sdio_write_buf(prGlueInfo->rHifInfo.cltCtx, u2Port, + (uint32_t *) pucSrc, ((prGlueInfo->rHifInfo).prFuncInfo->blk_sz) * bNum); + } else { /* byte mode */ + ret = mtk_wcn_hif_sdio_write_buf(prGlueInfo->rHifInfo.cltCtx, u2Port, (uint32_t *) pucSrc, count); + } +#endif + + if (ret) { + kalSendAeeWarning(HIF_SDIO_ERR_TITLE_STR, + HIF_SDIO_ERR_DESC_STR "sdio_writesb() reports error: %d", ret); + + DBGLOG(HAL, ERROR, "\n"); + DBGLOG(HAL, ERROR, "\nSDIO BUS ERROR: "); + DBGLOG(HAL, ERROR, "sdio_writesb() reports error: %d\n", ret); + DBGLOG(HAL, ERROR, "\n"); + } + + return (ret) ? FALSE : TRUE; +} /* end of kalDevPortWrite() */ + +/*----------------------------------------------------------------------------*/ +/*! +* @brief Read interrupt status from hardware +* +* @param prAdapter pointer to the Adapter handler +* @param the interrupts +* +* @return N/A +* +*/ +/*----------------------------------------------------------------------------*/ +void kalDevReadIntStatus(IN struct ADAPTER *prAdapter, OUT uint32_t *pu4IntStatus) +{ +#if CFG_SDIO_INTR_ENHANCE + struct ENHANCE_MODE_DATA_STRUCT *prSDIOCtrl; + struct SDIO_STAT_COUNTER *prStatCounter; + u_int8_t fgPendingInt = FALSE; + + SDIO_TIME_INTERVAL_DEC(); + + DEBUGFUNC("nicSDIOReadIntStatus"); + + ASSERT(prAdapter); + ASSERT(pu4IntStatus); + + prSDIOCtrl = prAdapter->prGlueInfo->rHifInfo.prSDIOCtrl; + ASSERT(prSDIOCtrl); + + prStatCounter = &prAdapter->prGlueInfo->rHifInfo.rStatCounter; + + /* There are pending interrupt to be handled */ + if (prAdapter->prGlueInfo->rHifInfo.fgIsPendingInt) { + prAdapter->prGlueInfo->rHifInfo.fgIsPendingInt = FALSE; + fgPendingInt = TRUE; + } + else { + SDIO_REC_TIME_START(); + HAL_PORT_RD(prAdapter, MCR_WHISR, sizeof(struct ENHANCE_MODE_DATA_STRUCT), + (uint8_t *) prSDIOCtrl, sizeof(struct ENHANCE_MODE_DATA_STRUCT)); + SDIO_REC_TIME_END(); + SDIO_ADD_TIME_INTERVAL(prStatCounter->u4IntReadTime); + prStatCounter->u4IntReadCnt++; + } + + prStatCounter->u4IntCnt++; + + if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { + *pu4IntStatus = 0; + return; + } + + halProcessEnhanceInterruptStatus(prAdapter); + + if (prSDIOCtrl->u4WHISR) { + halRecIntLog(prAdapter, prSDIOCtrl); + if (fgPendingInt) + halTagIntLog(prAdapter, SDIO_INT_RX_ENHANCE); + } + + *pu4IntStatus = prSDIOCtrl->u4WHISR; +#else + HAL_MCR_RD(prAdapter, MCR_WHISR, pu4IntStatus); +#endif /* CFG_SDIO_INTR_ENHANCE */ + + if (*pu4IntStatus & ~(WHIER_DEFAULT | WHIER_FW_OWN_BACK_INT_EN)) { + DBGLOG(INTR, WARN, + "Un-handled HISR %lx, HISR = %lx (HIER:0x%lx)\n", + (*pu4IntStatus & ~WHIER_DEFAULT), *pu4IntStatus, + WHIER_DEFAULT); + *pu4IntStatus &= WHIER_DEFAULT; + } +} /* end of nicSDIOReadIntStatus() */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Write device I/O port in byte with CMD52 +* +* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. +* \param[in] u4Addr I/O port offset +* \param[in] ucData Single byte of data to be written +* +* \retval TRUE operation success +* \retval FALSE operation fail +*/ +/*----------------------------------------------------------------------------*/ +u_int8_t kalDevWriteWithSdioCmd52(IN struct GLUE_INFO *prGlueInfo, IN uint32_t u4Addr, IN uint8_t ucData) +{ + int ret = 0; + +#if (MTK_WCN_HIF_SDIO == 0) + sdio_claim_host(prGlueInfo->rHifInfo.func); + sdio_writeb(prGlueInfo->rHifInfo.func, ucData, u4Addr, &ret); + sdio_release_host(prGlueInfo->rHifInfo.func); +#else + ret = mtk_wcn_hif_sdio_writeb(prGlueInfo->rHifInfo.cltCtx, u4Addr, ucData); +#endif + + if (ret) { + kalSendAeeWarning(HIF_SDIO_ERR_TITLE_STR, HIF_SDIO_ERR_DESC_STR "sdio_writeb() reports error: %x", ret); + DBGLOG(HAL, ERROR, "sdio_writeb() reports error: %x\n", ret); + } + + return (ret) ? FALSE : TRUE; + +} /* end of kalDevWriteWithSdioCmd52() */ + +void glSetPowerState(IN struct GLUE_INFO *prGlueInfo, IN uint32_t ePowerMode) +{ +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Write data to device +* +* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. +* \param[in] prMsduInfo msdu info +* +* \retval TRUE operation success +* \retval FALSE operation fail +*/ +/*----------------------------------------------------------------------------*/ +u_int8_t kalDevWriteData(IN struct GLUE_INFO *prGlueInfo, IN struct MSDU_INFO *prMsduInfo) +{ + struct ADAPTER *prAdapter = prGlueInfo->prAdapter; + struct GL_HIF_INFO *prHifInfo = &prGlueInfo->rHifInfo; + struct TX_CTRL *prTxCtrl; + uint8_t *pucOutputBuf = (uint8_t *) NULL; + uint32_t u4PaddingLength; + struct sk_buff *skb; + uint8_t *pucBuf; + uint32_t u4Length; + uint8_t ucTC; + + SDIO_TIME_INTERVAL_DEC(); + + skb = (struct sk_buff *)prMsduInfo->prPacket; + pucBuf = skb->data; + u4Length = skb->len; + ucTC = prMsduInfo->ucTC; + + prTxCtrl = &prAdapter->rTxCtrl; + pucOutputBuf = prTxCtrl->pucTxCoalescingBufPtr; + + if (prTxCtrl->u4WrIdx + ALIGN_4(u4Length) > prAdapter->u4CoalescingBufCachedSize) { + if ((prAdapter->u4CoalescingBufCachedSize - ALIGN_4(prTxCtrl->u4WrIdx)) >= HIF_TX_TERMINATOR_LEN) { + /* fill with single dword of zero as TX-aggregation termination */ + *(uint32_t *) (&((pucOutputBuf)[ALIGN_4(prTxCtrl->u4WrIdx)])) = 0; + } + + if (HAL_TEST_FLAG(prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { + if (kalDevPortWrite(prGlueInfo, MCR_WTDR1, prTxCtrl->u4WrIdx, + pucOutputBuf, prAdapter->u4CoalescingBufCachedSize) == FALSE) { + HAL_SET_FLAG(prAdapter, ADAPTER_FLAG_HW_ERR); + fgIsBusAccessFailed = TRUE; + } + prHifInfo->rStatCounter.u4DataPortWriteCnt++; + } + prTxCtrl->u4WrIdx = 0; + } + + SDIO_REC_TIME_START(); + memcpy(pucOutputBuf + prTxCtrl->u4WrIdx, pucBuf, u4Length); + SDIO_REC_TIME_END(); + SDIO_ADD_TIME_INTERVAL(prHifInfo->rStatCounter.u4TxDataCpTime); + + prTxCtrl->u4WrIdx += u4Length; + + u4PaddingLength = (ALIGN_4(u4Length) - u4Length); + if (u4PaddingLength) { + memset(pucOutputBuf + prTxCtrl->u4WrIdx, 0, u4PaddingLength); + prTxCtrl->u4WrIdx += u4PaddingLength; + } + + SDIO_REC_TIME_START(); + if (!prMsduInfo->pfTxDoneHandler) + kalFreeTxMsdu(prAdapter, prMsduInfo); + SDIO_REC_TIME_END(); + SDIO_ADD_TIME_INTERVAL(prHifInfo->rStatCounter.u4TxDataFreeTime); + + /* Update pending Tx done count */ + halUpdateTxDonePendingCount(prAdapter, TRUE, ucTC, u4Length); + + prHifInfo->rStatCounter.u4DataPktWriteCnt++; + + return TRUE; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Kick Tx data to device +* +* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. +* +* \retval TRUE operation success +* \retval FALSE operation fail +*/ +/*----------------------------------------------------------------------------*/ +u_int8_t kalDevKickData(IN struct GLUE_INFO *prGlueInfo) +{ + struct ADAPTER *prAdapter = prGlueInfo->prAdapter; + struct GL_HIF_INFO *prHifInfo = &prGlueInfo->rHifInfo; + struct TX_CTRL *prTxCtrl; + uint8_t *pucOutputBuf = (uint8_t *) NULL; + + prTxCtrl = &prAdapter->rTxCtrl; + pucOutputBuf = prTxCtrl->pucTxCoalescingBufPtr; + + if (prTxCtrl->u4WrIdx == 0) + return FALSE; + + if ((prAdapter->u4CoalescingBufCachedSize - ALIGN_4(prTxCtrl->u4WrIdx)) >= HIF_TX_TERMINATOR_LEN) { + /* fill with single dword of zero as TX-aggregation termination */ + *(uint32_t *) (&((pucOutputBuf)[ALIGN_4(prTxCtrl->u4WrIdx)])) = 0; + } + + if (HAL_TEST_FLAG(prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { + if (kalDevPortWrite(prGlueInfo, MCR_WTDR1, prTxCtrl->u4WrIdx, + pucOutputBuf, prAdapter->u4CoalescingBufCachedSize) == FALSE) { + HAL_SET_FLAG(prAdapter, ADAPTER_FLAG_HW_ERR); + fgIsBusAccessFailed = TRUE; + } + prHifInfo->rStatCounter.u4DataPortWriteCnt++; + } + + prTxCtrl->u4WrIdx = 0; + + prHifInfo->rStatCounter.u4DataPortKickCnt++; + + return TRUE; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Write command to device +* +* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. +* \param[in] u4Addr I/O port offset +* \param[in] ucData Single byte of data to be written +* +* \retval TRUE operation success +* \retval FALSE operation fail +*/ +/*----------------------------------------------------------------------------*/ +enum ENUM_CMD_TX_RESULT kalDevWriteCmd(IN struct GLUE_INFO *prGlueInfo, + IN struct CMD_INFO *prCmdInfo, IN uint8_t ucTC) +{ + struct ADAPTER *prAdapter = prGlueInfo->prAdapter; +/* P_GL_HIF_INFO_T prHifInfo = &prGlueInfo->rHifInfo; */ + struct TX_CTRL *prTxCtrl; + uint8_t *pucOutputBuf = (uint8_t *) NULL; + uint16_t u2OverallBufferLength = 0; +/* WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; */ + + prTxCtrl = &prAdapter->rTxCtrl; + pucOutputBuf = prTxCtrl->pucTxCoalescingBufPtr; + + if (TFCB_FRAME_PAD_TO_DW(prCmdInfo->u4TxdLen + prCmdInfo->u4TxpLen) > + prAdapter->u4CoalescingBufCachedSize) { + DBGLOG(HAL, ERROR, "Command TX buffer underflow!\n"); + return CMD_TX_RESULT_FAILED; + } + + if (prCmdInfo->u4TxdLen) { + memcpy((pucOutputBuf + u2OverallBufferLength), prCmdInfo->pucTxd, prCmdInfo->u4TxdLen); + u2OverallBufferLength += prCmdInfo->u4TxdLen; + } + + if (prCmdInfo->u4TxpLen) { + memcpy((pucOutputBuf + u2OverallBufferLength), prCmdInfo->pucTxp, prCmdInfo->u4TxpLen); + u2OverallBufferLength += prCmdInfo->u4TxpLen; + } + + memset(pucOutputBuf + u2OverallBufferLength, 0, + (TFCB_FRAME_PAD_TO_DW(u2OverallBufferLength) - u2OverallBufferLength)); + + if ((prAdapter->u4CoalescingBufCachedSize - ALIGN_4(u2OverallBufferLength)) >= HIF_TX_TERMINATOR_LEN) { + /* fill with single dword of zero as TX-aggregation termination */ + *(uint32_t *) (&((pucOutputBuf)[ALIGN_4(u2OverallBufferLength)])) = 0; + } + if (HAL_TEST_FLAG(prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { + if (kalDevPortWrite(prGlueInfo, MCR_WTDR1, TFCB_FRAME_PAD_TO_DW(u2OverallBufferLength), + pucOutputBuf, prAdapter->u4CoalescingBufCachedSize) == FALSE) { + HAL_SET_FLAG(prAdapter, ADAPTER_FLAG_HW_ERR); + fgIsBusAccessFailed = TRUE; + } + prGlueInfo->rHifInfo.rStatCounter.u4CmdPortWriteCnt++; + } + + /* Update pending Tx done count */ + halUpdateTxDonePendingCount(prAdapter, TRUE, ucTC, + (prCmdInfo->u4TxdLen + prCmdInfo->u4TxpLen)); + + prGlueInfo->rHifInfo.rStatCounter.u4CmdPktWriteCnt++; + return CMD_TX_RESULT_SUCCESS; +} + +void glGetDev(void *ctx, struct device **dev) +{ +#if MTK_WCN_HIF_SDIO + mtk_wcn_hif_sdio_get_dev(*((unsigned long *) ctx), dev); +#else + *dev = &((struct sdio_func *)ctx)->dev; +#endif +} + +void glGetHifDev(struct GL_HIF_INFO *prHif, struct device **dev) +{ +#if MTK_WCN_HIF_SDIO + mtk_wcn_hif_sdio_get_dev(prHif->cltCtx, dev); +#else + *dev = &(prHif->func->dev); +#endif +} + +u_int8_t glWakeupSdio(struct GLUE_INFO *prGlueInfo) +{ + u_int8_t fgSuccess = TRUE; + +#if (HIF_SDIO_SUPPORT_GPIO_SLEEP_MODE && MTK_WCN_HIF_SDIO) + #if KERNEL_VERSION(4, 4, 0) <= CFG80211_VERSION_CODE + if (mtk_wcn_stp_sdio_wake_up_ctrl(prGlueInfo->rHifInfo.cltCtx) != 0) + #else + if (mtk_wcn_hif_sdio_wake_up_ctrl(prGlueInfo->rHifInfo.cltCtx) != 0) + #endif + fgSuccess = FALSE; +#endif + + return fgSuccess; +} + +#if (CFG_CHIP_RESET_SUPPORT == 1) && (MTK_WCN_HIF_SDIO == 0) +void kalRemoveProbe(IN struct GLUE_INFO *prGlueInfo) +{ + struct mmc_host *host; + + ASSERT(prGlueInfo); + + host = prGlueInfo->rHifInfo.func->card->host; + host->rescan_entered = 0; + + /* clear trx fifo */ + DBGLOG(INIT, STATE, "[SER][L0] mmc_remove_host\n"); + mmc_remove_host(prGlueInfo->rHifInfo.func->card->host); + + DBGLOG(INIT, STATE, "[SER][L0] mmc_add_host\n"); + mmc_add_host(host); + +} +#endif + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/sdio/sdio_test_driver_core.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/sdio/sdio_test_driver_core.c new file mode 100644 index 0000000000000000000000000000000000000000..996f4137b3f9f2e724248c3ab717a49300ded40b --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/sdio/sdio_test_driver_core.c @@ -0,0 +1,448 @@ +#include "gl_os.h" + +#if (CFG_SDIO_1BIT_DATA_MODE == 1) +/* + * linux/drivers/mmc/core/core.c + * + * Copyright (C) 2003-2004 Russell King, All Rights Reserved. + * SD support Copyright (C) 2004 Ian Molton, All Rights Reserved. + * Copyright (C) 2005-2008 Pierre Ossman, All Rights Reserved. + * MMCv4 support Copyright (C) 2006 Philip Langdale, All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + + +#include "test_driver_sdio_ops.h" + + +/* + * Internal function that does the actual ios call to the host driver, + * optionally printing some debug output. + */ +static inline void mmc_set_ios(struct mmc_host *host) +{ + struct mmc_ios *ios = &host->ios; + + pr_debug("%s: clock %uHz busmode %u powermode %u cs %u Vdd %u width %u timing %u\n", + mmc_hostname(host), ios->clock, ios->bus_mode, + ios->power_mode, ios->chip_select, ios->vdd, + ios->bus_width, ios->timing); + + host->ops->set_ios(host, ios); +} + +/* + * Control chip select pin on a host. + */ +void mmc_set_chip_select(struct mmc_host *host, int mode) +{ + host->ios.chip_select = mode; + mmc_set_ios(host); +} + +/* + * Sets the host clock to the highest possible frequency that + * is below "hz". + */ +void mmc_set_clock(struct mmc_host *host, unsigned int hz) +{ + WARN_ON(hz < host->f_min); + + if (hz > host->f_max) + hz = host->f_max; + + #if 1 + pr_debug("%s(): %dHz\n", __func__, hz); + #endif + + host->ios.clock = hz; + mmc_set_ios(host); +} + +/* + * Change the bus mode (open drain/push-pull) of a host. + */ +void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode) +{ + host->ios.bus_mode = mode; + mmc_set_ios(host); +} + +/* + * Change data bus width of a host. + */ +void mmc_set_bus_width(struct mmc_host *host, unsigned int width) +{ + host->ios.bus_width = width; + mmc_set_ios(host); +} + +/* + * Mask off any voltages we don't support and select + * the lowest voltage + */ +u32 mmc_select_voltage(struct mmc_host *host, u32 ocr) +{ + int bit; + + ocr &= host->ocr_avail; + + bit = ffs(ocr); + if (bit) { + bit -= 1; + + ocr &= 3 << bit; + + host->ios.vdd = bit; + mmc_set_ios(host); + } else { + pr_warn("%s: host doesn't support card's voltages\n", + mmc_hostname(host)); + ocr = 0; + } + + return ocr; +} + +/* + * Select timing parameters for host. + */ +void mmc_set_timing(struct mmc_host *host, unsigned int timing) +{ + host->ios.timing = timing; + mmc_set_ios(host); +} + + +static void mmc_power_off(struct mmc_host *host) +{ + host->ios.clock = 0; + host->ios.vdd = 0; + if (!mmc_host_is_spi(host)) { + host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; + host->ios.chip_select = MMC_CS_DONTCARE; + } + host->ios.power_mode = MMC_POWER_OFF; + host->ios.bus_width = MMC_BUS_WIDTH_1; + host->ios.timing = MMC_TIMING_LEGACY; + mmc_set_ios(host); +} + +/* + * Cleanup when the last reference to the bus operator is dropped. + */ +static void __mmc_release_bus(struct mmc_host *host) +{ + BUG_ON(!host); + BUG_ON(host->bus_refs); + BUG_ON(!host->bus_dead); + + host->bus_ops = NULL; +} + +/* + * Increase reference count of bus operator + */ +static inline void mmc_bus_get(struct mmc_host *host) +{ + unsigned long flags; + + spin_lock_irqsave(&host->lock, flags); + host->bus_refs++; + spin_unlock_irqrestore(&host->lock, flags); +} + +/* + * Decrease reference count of bus operator and free it if + * it is the last reference. + */ +static inline void mmc_bus_put(struct mmc_host *host) +{ + unsigned long flags; + + spin_lock_irqsave(&host->lock, flags); + host->bus_refs--; + if ((host->bus_refs == 0) && host->bus_ops) + __mmc_release_bus(host); + spin_unlock_irqrestore(&host->lock, flags); +} + +/* + * Assign a mmc bus handler to a host. Only one bus handler may control a + * host at any given time. + */ +void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops) +{ + unsigned long flags; + + BUG_ON(!host); + BUG_ON(!ops); + + WARN_ON(!host->claimed); + + spin_lock_irqsave(&host->lock, flags); + + BUG_ON(host->bus_ops); + BUG_ON(host->bus_refs); + + host->bus_ops = ops; + host->bus_refs = 1; + host->bus_dead = 0; + + spin_unlock_irqrestore(&host->lock, flags); +} + +/* + * Remove the current bus handler from a host. Assumes that there are + * no interesting cards left, so the bus is powered down. + */ +void mmc_detach_bus(struct mmc_host *host) +{ + unsigned long flags; + + BUG_ON(!host); + + WARN_ON(!host->claimed); + WARN_ON(!host->bus_ops); + + spin_lock_irqsave(&host->lock, flags); + + host->bus_dead = 1; + + spin_unlock_irqrestore(&host->lock, flags); + + mmc_power_off(host); + + mmc_bus_put(host); +} + +int mmc_app_set_bus_width(struct mmc_card *card, int width) +{ + int err; + struct mmc_command cmd; + + BUG_ON(!card); + BUG_ON(!card->host); + + memset(&cmd, 0, sizeof(struct mmc_command)); + + cmd.opcode = SD_APP_SET_BUS_WIDTH; + cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; + + switch (width) { + case MMC_BUS_WIDTH_1: + cmd.arg = SD_BUS_WIDTH_1; + break; + case MMC_BUS_WIDTH_4: + cmd.arg = SD_BUS_WIDTH_4; + break; + default: + return -EINVAL; + } + + err = mmc_wait_for_app_cmd(card->host, card, &cmd, MMC_CMD_RETRIES); + if (err) + return err; + + return 0; +} + +int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) +{ + struct mmc_command cmd; + int i, err = 0; + + BUG_ON(!host); + + memset(&cmd, 0, sizeof(struct mmc_command)); + + cmd.opcode = SD_APP_OP_COND; + if (mmc_host_is_spi(host)) + cmd.arg = ocr & (1 << 30); /* SPI only defines one bit */ + else + cmd.arg = ocr; + cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R3 | MMC_CMD_BCR; + + for (i = 100; i; i--) { + err = mmc_wait_for_app_cmd(host, NULL, &cmd, MMC_CMD_RETRIES); + if (err) + break; + + /* if we're just probing, do a single pass */ + if (ocr == 0) + break; + + /* otherwise wait until reset completes */ + if (mmc_host_is_spi(host)) { + if (!(cmd.resp[0] & R1_SPI_IDLE)) + break; + } else { + if (cmd.resp[0] & MMC_CARD_BUSY) + break; + } + + err = -ETIMEDOUT; + + mmc_delay(10); + } + + if (rocr && !mmc_host_is_spi(host)) + *rocr = cmd.resp[0]; + + return err; +} + +int mmc_send_if_cond(struct mmc_host *host, u32 ocr) +{ + struct mmc_command cmd; + int err; + static const u8 test_pattern = 0xAA; + u8 result_pattern; + + /* + * To support SD 2.0 cards, we must always invoke SD_SEND_IF_COND + * before SD_APP_OP_COND. This command will harmlessly fail for + * SD 1.0 cards. + */ + cmd.opcode = SD_SEND_IF_COND; + cmd.arg = ((ocr & 0xFF8000) != 0) << 8 | test_pattern; + cmd.flags = MMC_RSP_SPI_R7 | MMC_RSP_R7 | MMC_CMD_BCR; + + err = mmc_wait_for_cmd(host, &cmd, 0); + if (err) + return err; + + if (mmc_host_is_spi(host)) + result_pattern = cmd.resp[1] & 0xFF; + else + result_pattern = cmd.resp[0] & 0xFF; + + if (result_pattern != test_pattern) + return -EIO; + + return 0; +} + + + +static int sdio_enable_wide(struct mmc_card *card) +{ + int ret; + u8 ctrl; + + if (!(card->host->caps & MMC_CAP_4_BIT_DATA)) + return 0; + + + if (card->cccr.low_speed && !card->cccr.wide_bus) + return 0; + + + ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_IF, 0, &ctrl); + if (ret) + return ret; + + + if ((ctrl & SDIO_BUS_WIDTH_MASK) == SDIO_BUS_WIDTH_RESERVED) + pr_warn("%s: SDIO_CCCR_IF is invalid: 0x%02x\n", + mmc_hostname(card->host), ctrl); + + /* set as 4-bit bus width */ + ctrl &= ~SDIO_BUS_WIDTH_MASK; + ctrl |= SDIO_BUS_WIDTH_4BIT; + + ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_IF, ctrl, NULL); + if (ret) + return ret; + + return 1; +} + + + +/* + * Devices that remain active during a system suspend are + * put back into 1-bit mode. + */ +int sdio_disable_wide(struct mmc_card *card) +{ + int ret; + u8 ctrl; + + if (!(card->host->caps & MMC_CAP_4_BIT_DATA)) + return 0; + + + if (card->cccr.low_speed && !card->cccr.wide_bus) + return 0; + + + ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_IF, 0, &ctrl); + if (ret) + return ret; + + + if (!(ctrl & SDIO_BUS_WIDTH_4BIT)) + return 0; + + + ctrl &= ~SDIO_BUS_WIDTH_4BIT; + ctrl |= SDIO_BUS_ASYNC_INT; + + ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_IF, ctrl, NULL); + if (ret) + return ret; + + + mmc_set_bus_width(card->host, MMC_BUS_WIDTH_1); + + return 0; +} + + +int sdio_enable_4bit_bus(struct mmc_card *card) +{ + int err; + + if (card->type == MMC_TYPE_SDIO) + return sdio_enable_wide(card); + + + if ((card->host->caps & MMC_CAP_4_BIT_DATA) && + (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) { + + err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4); + if (err) + return err; + } else + return 0; + + + err = sdio_enable_wide(card); + if (err <= 0) + mmc_app_set_bus_width(card, MMC_BUS_WIDTH_1); + + return err; +} +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/sdio/sdio_test_driver_ops.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/sdio/sdio_test_driver_ops.c new file mode 100644 index 0000000000000000000000000000000000000000..82dfd14889c71dfd0eaf54502cd3b4054b5fa47c --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/sdio/sdio_test_driver_ops.c @@ -0,0 +1,194 @@ + +#include "gl_os.h" + +#if (CFG_SDIO_1BIT_DATA_MODE == 1) +/* + * linux/drivers/mmc/sdio_ops.c + * + * Copyright 2006-2007 Pierre Ossman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + */ + +#include + +#if 0 +#include +#include +#include +#include +#include +#endif + +#include "test_driver_sdio_ops.h" + +int mmc_send_io_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) +{ + struct mmc_command cmd; + int i, err = 0; + + BUG_ON(!host); + + memset(&cmd, 0, sizeof(struct mmc_command)); + + cmd.opcode = SD_IO_SEND_OP_COND; + cmd.arg = ocr; + cmd.flags = MMC_RSP_SPI_R4 | MMC_RSP_R4 | MMC_CMD_BCR; + + for (i = 100; i; i--) { + err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); + if (err) + break; + + /* if we're just probing, do a single pass */ + if (ocr == 0) { + pr_warn("PROBE ONLY! RESP[0] = 0x%08x\n", cmd.resp[0]); + break; + } + + /* otherwise wait until reset completes */ + if (mmc_host_is_spi(host)) { + /* + * Both R1_SPI_IDLE and MMC_CARD_BUSY indicate + * an initialized card under SPI, but some cards + * (Marvell's) only behave when looking at this + * one. + */ + if (cmd.resp[1] & MMC_CARD_BUSY) + break; + } else { + if (cmd.resp[0] & MMC_CARD_BUSY) + break; + } + + err = -ETIMEDOUT; + + mmc_delay(10); + } + + if (rocr) + *rocr = cmd.resp[mmc_host_is_spi(host) ? 1 : 0]; + + return err; +} + +int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn, + unsigned addr, u8 in, u8 *out) +{ + struct mmc_command cmd; + int err; + + BUG_ON(!card); + BUG_ON(fn > 7); + + /* sanity check */ + if (addr & ~0x1FFFF) + return -EINVAL; + + memset(&cmd, 0, sizeof(struct mmc_command)); + + cmd.opcode = SD_IO_RW_DIRECT; + cmd.arg = write ? 0x80000000 : 0x00000000; + cmd.arg |= fn << 28; + cmd.arg |= (write && out) ? 0x08000000 : 0x00000000; + cmd.arg |= addr << 9; + cmd.arg |= in; + cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_AC; + + err = mmc_wait_for_cmd(card->host, &cmd, 0); + if (err) + return err; + + if (mmc_host_is_spi(card->host)) { + /* host driver already reported errors */ + } else { + if (cmd.resp[0] & R5_ERROR) + return -EIO; + if (cmd.resp[0] & R5_FUNCTION_NUMBER) + return -EINVAL; + if (cmd.resp[0] & R5_OUT_OF_RANGE) + return -ERANGE; + } + + if (out) { + if (mmc_host_is_spi(card->host)) + *out = (cmd.resp[0] >> 8) & 0xFF; + else + *out = cmd.resp[0] & 0xFF; + } + + return 0; +} + +int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn, + unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz) +{ + struct mmc_request mrq; + struct mmc_command cmd; + struct mmc_data data; + struct scatterlist sg; + + BUG_ON(!card); + BUG_ON(fn > 7); + BUG_ON(blocks == 1 && blksz > 512); + WARN_ON(blocks == 0); + WARN_ON(blksz == 0); + + /* sanity check */ + if (addr & ~0x1FFFF) + return -EINVAL; + + memset(&mrq, 0, sizeof(struct mmc_request)); + memset(&cmd, 0, sizeof(struct mmc_command)); + memset(&data, 0, sizeof(struct mmc_data)); + + mrq.cmd = &cmd; + mrq.data = &data; + + cmd.opcode = SD_IO_RW_EXTENDED; + cmd.arg = write ? 0x80000000 : 0x00000000; + cmd.arg |= fn << 28; + cmd.arg |= incr_addr ? 0x04000000 : 0x00000000; + cmd.arg |= addr << 9; + if (blocks == 1 && blksz <= 512) + cmd.arg |= (blksz == 512) ? 0 : blksz; /* byte mode */ + else + cmd.arg |= 0x08000000 | blocks; /* block mode */ + cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC; + + data.blksz = blksz; + data.blocks = blocks; + data.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ; + data.sg = &sg; + data.sg_len = 1; + + sg_init_one(&sg, buf, blksz * blocks); + + mmc_set_data_timeout(&data, card); + + mmc_wait_for_req(card->host, &mrq); + + if (cmd.error) + return cmd.error; + if (data.error) + return data.error; + + if (mmc_host_is_spi(card->host)) { + /* host driver already reported errors */ + } else { + if (cmd.resp[0] & R5_ERROR) + return -EIO; + if (cmd.resp[0] & R5_FUNCTION_NUMBER) + return -EINVAL; + if (cmd.resp[0] & R5_OUT_OF_RANGE) + return -ERANGE; + } + + return 0; +} + +#endif + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/sdio/x86.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/sdio/x86.c new file mode 100644 index 0000000000000000000000000000000000000000..7cbc34e29cdef6751cc0d82f42af191370f61e46 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/sdio/x86.c @@ -0,0 +1,62 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/****************************************************************************** +*[File] mt6516-evb.c +*[Version] v1.0 +*[Revision Date] 2010-03-01 +*[Author] +*[Description] +* dummy file for build system +*[Copyright] +* Copyright (C) 2010 MediaTek Incorporation. All Rights Reserved. +******************************************************************************/ + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/usb/hal_api.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/usb/hal_api.c new file mode 100644 index 0000000000000000000000000000000000000000..e6279b8b2fe4227b2fc8c6567d2df896c3dcf0ed --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/usb/hal_api.c @@ -0,0 +1,1945 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/****************************************************************************** +*[File] hif_api.c +*[Version] v1.0 +*[Revision Date] 2015-09-08 +*[Author] +*[Description] +* The program provides USB HIF APIs +*[Copyright] +* Copyright (C) 2015 MediaTek Incorporation. All Rights Reserved. +******************************************************************************/ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include "precomp.h" + +#include +#include + +#include +#ifndef CONFIG_X86 +#include +#endif + +#include "mt66xx_reg.h" + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ +static const uint16_t arTcToUSBEP[USB_TC_NUM] = { + USB_DATA_BULK_OUT_EP4, + USB_DATA_BULK_OUT_EP5, + USB_DATA_BULK_OUT_EP6, + USB_DATA_BULK_OUT_EP7, + USB_DATA_BULK_OUT_EP8, + USB_DATA_BULK_OUT_EP9, + + /* Second HW queue */ +#if NIC_TX_ENABLE_SECOND_HW_QUEUE + USB_DATA_BULK_OUT_EP9, + USB_DATA_BULK_OUT_EP9, + USB_DATA_BULK_OUT_EP9, + USB_DATA_BULK_OUT_EP9, +#endif +}; + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +/*----------------------------------------------------------------------------*/ +/*! +* @brief Verify the CHIP ID +* +* @param prAdapter a pointer to adapter private data structure. +* +* +* @retval TRUE CHIP ID is the same as the setting compiled +* @retval FALSE CHIP ID is different from the setting compiled +*/ +/*----------------------------------------------------------------------------*/ +u_int8_t halVerifyChipID(IN struct ADAPTER *prAdapter) +{ + uint32_t u4CIR = 0; + struct mt66xx_chip_info *prChipInfo; + + ASSERT(prAdapter); + + if (prAdapter->fgIsReadRevID) + return TRUE; + + prChipInfo = prAdapter->chip_info; + + HAL_MCR_RD(prAdapter, prChipInfo->top_hcr, &u4CIR); + DBGLOG(INIT, TRACE, "Chip ID: 0x%4x\n", u4CIR); + + if (u4CIR != prChipInfo->chip_id) + return FALSE; + + HAL_MCR_RD(prAdapter, prChipInfo->top_hvr, &u4CIR); + DBGLOG(INIT, TRACE, "Revision ID: 0x%4x\n", u4CIR); + + prAdapter->ucRevID = (uint8_t) (u4CIR & 0xF); + prAdapter->fgIsReadRevID = TRUE; + return TRUE; +} + +uint32_t +halRxWaitResponse(IN struct ADAPTER *prAdapter, IN uint8_t ucPortIdx, OUT uint8_t *pucRspBuffer, + IN uint32_t u4MaxRespBufferLen, OUT uint32_t *pu4Length) +{ + struct GL_HIF_INFO *prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + uint32_t u4Status = WLAN_STATUS_SUCCESS; + struct RX_CTRL *prRxCtrl; + u_int8_t ret = FALSE; + struct BUS_INFO *prBusInfo; + + DEBUGFUNC("halRxWaitResponse"); + + ASSERT(prAdapter); + ASSERT(pucRspBuffer); + + prRxCtrl = &prAdapter->rRxCtrl; + prBusInfo = prAdapter->chip_info->bus_info; + + if (prBusInfo->asicUsbEventEpDetected) + ucPortIdx = prBusInfo->asicUsbEventEpDetected(prAdapter); + else { + if (prHifInfo->fgEventEpDetected == FALSE) { + /* NOTE: This is temporary compatiable code with old/new CR4 FW to detect + * which EVENT endpoint that. + * CR4 FW is using. If the new EP4IN-using CR4 FW works without + * any issue for a while, + * this code block will be removed. + */ + if (prAdapter->fgIsCr4FwDownloaded) { + ucPortIdx = USB_DATA_EP_IN; + ret = kalDevPortRead(prAdapter->prGlueInfo, ucPortIdx, + ALIGN_4(u4MaxRespBufferLen) + LEN_USB_RX_PADDING_CSO, + prRxCtrl->pucRxCoalescingBufPtr, HIF_RX_COALESCING_BUFFER_SIZE); + + if (ret == TRUE) { + prHifInfo->eEventEpType = EVENT_EP_TYPE_DATA_EP; + } else { + ucPortIdx = USB_EVENT_EP_IN; + ret = kalDevPortRead(prAdapter->prGlueInfo, ucPortIdx, + ALIGN_4(u4MaxRespBufferLen) + LEN_USB_RX_PADDING_CSO, + prRxCtrl->pucRxCoalescingBufPtr, HIF_RX_COALESCING_BUFFER_SIZE); + } + prHifInfo->fgEventEpDetected = TRUE; + + kalMemCopy(pucRspBuffer, prRxCtrl->pucRxCoalescingBufPtr, u4MaxRespBufferLen); + *pu4Length = u4MaxRespBufferLen; + + if (ret == FALSE) + u4Status = WLAN_STATUS_FAILURE; + return u4Status; + } + + ucPortIdx = USB_EVENT_EP_IN; + } else { + if (prHifInfo->eEventEpType == EVENT_EP_TYPE_DATA_EP) + if (prAdapter->fgIsCr4FwDownloaded) + ucPortIdx = USB_DATA_EP_IN; + else + ucPortIdx = USB_EVENT_EP_IN; + else + ucPortIdx = USB_EVENT_EP_IN; + } + } + ret = kalDevPortRead(prAdapter->prGlueInfo, ucPortIdx, + ALIGN_4(u4MaxRespBufferLen) + LEN_USB_RX_PADDING_CSO, + prRxCtrl->pucRxCoalescingBufPtr, HIF_RX_COALESCING_BUFFER_SIZE); + + kalMemCopy(pucRspBuffer, prRxCtrl->pucRxCoalescingBufPtr, u4MaxRespBufferLen); + *pu4Length = u4MaxRespBufferLen; + + if (ret == FALSE) + u4Status = WLAN_STATUS_FAILURE; + + return u4Status; +} + +uint32_t halTxUSBSendCmd(IN struct GLUE_INFO *prGlueInfo, IN uint8_t ucTc, IN struct CMD_INFO *prCmdInfo) +{ + struct GL_HIF_INFO *prHifInfo = &prGlueInfo->rHifInfo; + uint32_t u4Status = WLAN_STATUS_SUCCESS; + struct USB_REQ *prUsbReq; + struct BUF_CTRL *prBufCtrl; + uint16_t u2OverallBufferLength = 0; + unsigned long flags; + uint8_t ucQueIdx; + struct mt66xx_chip_info *prChipInfo; + int ret; + struct TX_DESC_OPS_T *prTxDescOps; + + if (!(prHifInfo->state == USB_STATE_LINK_UP || + prHifInfo->state == USB_STATE_PRE_RESUME || + prHifInfo->state == USB_STATE_PRE_SUSPEND_START || + prHifInfo->state == USB_STATE_READY)) + return WLAN_STATUS_FAILURE; + + prUsbReq = glUsbDequeueReq(prHifInfo, &prHifInfo->rTxCmdFreeQ, &prHifInfo->rTxCmdQLock); + if (prUsbReq == NULL) + return WLAN_STATUS_RESOURCES; + + prBufCtrl = prUsbReq->prBufCtrl; + + if ((TFCB_FRAME_PAD_TO_DW(prCmdInfo->u4TxdLen + prCmdInfo->u4TxpLen) + LEN_USB_UDMA_TX_TERMINATOR) > + prBufCtrl->u4BufSize) { + DBGLOG(HAL, ERROR, "Command TX buffer underflow!\n"); + glUsbEnqueueReq(prHifInfo, &prHifInfo->rTxCmdFreeQ, prUsbReq, + &prHifInfo->rTxCmdQLock, FALSE); + return WLAN_STATUS_RESOURCES; + } + + DBGLOG(HAL, INFO, "TX URB[0x%p]\n", prUsbReq->prUrb); + + prChipInfo = prGlueInfo->prAdapter->chip_info; + prTxDescOps = prChipInfo->prTxDescOps; + HAL_WRITE_HIF_TXD(prChipInfo, prBufCtrl->pucBuf, (prCmdInfo->u4TxdLen + prCmdInfo->u4TxpLen)); + u2OverallBufferLength += prChipInfo->u2HifTxdSize; + + if (prCmdInfo->u4TxdLen) { + memcpy((prBufCtrl->pucBuf + u2OverallBufferLength), prCmdInfo->pucTxd, prCmdInfo->u4TxdLen); + u2OverallBufferLength += prCmdInfo->u4TxdLen; + } + + if (prCmdInfo->u4TxpLen) { + memcpy((prBufCtrl->pucBuf + u2OverallBufferLength), prCmdInfo->pucTxp, prCmdInfo->u4TxpLen); + u2OverallBufferLength += prCmdInfo->u4TxpLen; + } + + if (prChipInfo->is_support_cr4 && prTxDescOps->nic_txd_queue_idx_op) { + void *prTxDesc = (void *)(prBufCtrl->pucBuf + + prChipInfo->u2HifTxdSize); + ucQueIdx = prTxDescOps->nic_txd_queue_idx_op( + prTxDesc, 0, FALSE); + /* For H2CDMA Tx CMD mapping + * Mapping port1 queue0~3 to queue28~31, + * and CR4 will unmask this. + */ + prTxDescOps->nic_txd_queue_idx_op( + prTxDesc, + (ucQueIdx | USB_TX_CMD_QUEUE_MASK), + TRUE); + } + + /* DBGLOG_MEM32(SW4, INFO, prBufCtrl->pucBuf, 32); */ + memset(prBufCtrl->pucBuf + u2OverallBufferLength, 0, + ((TFCB_FRAME_PAD_TO_DW(u2OverallBufferLength) - u2OverallBufferLength) + LEN_USB_UDMA_TX_TERMINATOR)); + prBufCtrl->u4WrIdx = TFCB_FRAME_PAD_TO_DW(u2OverallBufferLength) + LEN_USB_UDMA_TX_TERMINATOR; + + prUsbReq->prPriv = (void *) prCmdInfo; + usb_fill_bulk_urb(prUsbReq->prUrb, + prHifInfo->udev, + usb_sndbulkpipe(prHifInfo->udev, arTcToUSBEP[ucTc]), + (void *)prUsbReq->prBufCtrl->pucBuf, + prBufCtrl->u4WrIdx, halTxUSBSendCmdComplete, (void *)prUsbReq); + +#if CFG_USB_CONSISTENT_DMA + prUsbReq->prUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; +#endif + spin_lock_irqsave(&prHifInfo->rTxCmdQLock, flags); + ret = glUsbSubmitUrb(prHifInfo, prUsbReq->prUrb, SUBMIT_TYPE_TX_CMD); + if (ret) { + DBGLOG(HAL, ERROR, + "glUsbSubmitUrb() reports error (%d) [%s] (EP%d OUT)\n", + ret, __func__, arTcToUSBEP[ucTc]); + list_add_tail(&prUsbReq->list, &prHifInfo->rTxCmdFreeQ); + spin_unlock_irqrestore(&prHifInfo->rTxCmdQLock, flags); + return WLAN_STATUS_FAILURE; + } + list_add_tail(&prUsbReq->list, &prHifInfo->rTxCmdSendingQ); + spin_unlock_irqrestore(&prHifInfo->rTxCmdQLock, flags); + + if (wlanIsChipRstRecEnabled(prGlueInfo->prAdapter) + && wlanIsChipNoAck(prGlueInfo->prAdapter)) { + wlanChipRstPreAct(prGlueInfo->prAdapter); + DBGLOG(HAL, ERROR, "usb trigger whole reset\n"); + HAL_WIFI_FUNC_CHIP_RESET(prGlueInfo->prAdapter); + } + return u4Status; +} + +void halTxUSBSendCmdComplete(struct urb *urb) +{ + struct USB_REQ *prUsbReq = urb->context; + struct GL_HIF_INFO *prHifInfo = prUsbReq->prHifInfo; + struct GLUE_INFO *prGlueInfo = prHifInfo->prGlueInfo; + unsigned long flags; + +#if CFG_USB_TX_HANDLE_IN_HIF_THREAD + spin_lock_irqsave(&prHifInfo->rTxCmdQLock, flags); + list_del_init(&prUsbReq->list); + list_add_tail(&prUsbReq->list, &prHifInfo->rTxCmdCompleteQ); + spin_unlock_irqrestore(&prHifInfo->rTxCmdQLock, flags); + + kalSetIntEvent(prGlueInfo); +#else + spin_lock_irqsave(&prHifInfo->rTxCmdQLock, flags); + list_del_init(&prUsbReq->list); + spin_unlock_irqrestore(&prHifInfo->rTxCmdQLock, flags); + + halTxUSBProcessCmdComplete(prGlueInfo->prAdapter, prUsbReq); +#endif +} + +void halTxUSBProcessCmdComplete(IN struct ADAPTER *prAdapter, struct USB_REQ *prUsbReq) +{ + struct urb *urb = prUsbReq->prUrb; + uint32_t u4SentDataSize; + struct GL_HIF_INFO *prHifInfo = prUsbReq->prHifInfo; + + if (urb->status != 0) { + DBGLOG(TX, ERROR, "[%s] send CMD fail (status = %d)\n", __func__, urb->status); + /* TODO: handle error */ + } + + DBGLOG(HAL, INFO, "TX CMD DONE: URB[0x%p]\n", urb); + + glUsbEnqueueReq(prHifInfo, &prHifInfo->rTxCmdFreeQ, prUsbReq, &prHifInfo->rTxCmdQLock, FALSE); + + u4SentDataSize = urb->actual_length - LEN_USB_UDMA_TX_TERMINATOR; + nicTxReleaseResource_PSE(prAdapter, TC4_INDEX, nicTxGetPageCount(prAdapter, u4SentDataSize, TRUE), TRUE); +} + +void halTxCancelSendingCmd(IN struct ADAPTER *prAdapter, IN struct CMD_INFO *prCmdInfo) +{ + struct USB_REQ *prUsbReq, *prNext; + unsigned long flags; + struct urb *urb = NULL; + struct GL_HIF_INFO *prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + + spin_lock_irqsave(&prHifInfo->rTxCmdQLock, flags); + list_for_each_entry_safe(prUsbReq, prNext, &prHifInfo->rTxCmdSendingQ, list) { + if (prUsbReq->prPriv == (void *) prCmdInfo) { + list_del_init(&prUsbReq->list); + urb = prUsbReq->prUrb; + break; + } + } + spin_unlock_irqrestore(&prHifInfo->rTxCmdQLock, flags); + + if (urb) { + prCmdInfo->pfHifTxCmdDoneCb = NULL; + usb_kill_urb(urb); + } +} + +void halTxCancelAllSending(IN struct ADAPTER *prAdapter) +{ + struct GLUE_INFO *prGlueInfo; + struct USB_REQ *prUsbReq, *prUsbReqNext; + struct GL_HIF_INFO *prHifInfo; +#if CFG_USB_TX_AGG + uint8_t ucTc; +#endif + + ASSERT(prAdapter); + prGlueInfo = prAdapter->prGlueInfo; + prHifInfo = &prGlueInfo->rHifInfo; + + list_for_each_entry_safe(prUsbReq, prUsbReqNext, &prHifInfo->rTxCmdSendingQ, list) { + usb_kill_urb(prUsbReq->prUrb); + } + +#if CFG_USB_TX_AGG + for (ucTc = 0; ucTc < USB_TC_NUM; ++ucTc) + usb_kill_anchored_urbs(&prHifInfo->rTxDataAnchor[ucTc]); +#else + usb_kill_anchored_urbs(&prHifInfo->rTxDataAnchor); +#endif +} + +#if CFG_USB_TX_AGG +uint32_t halTxUSBSendAggData(IN struct GL_HIF_INFO *prHifInfo, IN uint8_t ucTc, IN struct USB_REQ *prUsbReq) +{ + struct GLUE_INFO *prGlueInfo = prHifInfo->prGlueInfo; + struct BUF_CTRL *prBufCtrl = prUsbReq->prBufCtrl; + uint32_t u4Status = WLAN_STATUS_SUCCESS; + int ret; + + memset(prBufCtrl->pucBuf + prBufCtrl->u4WrIdx, 0, LEN_USB_UDMA_TX_TERMINATOR); + prBufCtrl->u4WrIdx += LEN_USB_UDMA_TX_TERMINATOR; + + if (!(prHifInfo->state == USB_STATE_LINK_UP || + prHifInfo->state == USB_STATE_READY)) { + /* No need to dequeue prUsbReq because LINK is not up */ + prBufCtrl->u4WrIdx = 0; + return WLAN_STATUS_FAILURE; + } + + list_del_init(&prUsbReq->list); + + usb_fill_bulk_urb(prUsbReq->prUrb, + prHifInfo->udev, + usb_sndbulkpipe(prHifInfo->udev, arTcToUSBEP[ucTc]), + (void *)prBufCtrl->pucBuf, prBufCtrl->u4WrIdx, halTxUSBSendDataComplete, (void *)prUsbReq); +#if CFG_USB_CONSISTENT_DMA + prUsbReq->prUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; +#endif + + usb_anchor_urb(prUsbReq->prUrb, &prHifInfo->rTxDataAnchor[ucTc]); + ret = glUsbSubmitUrb(prHifInfo, prUsbReq->prUrb, SUBMIT_TYPE_TX_DATA); + if (ret) { + DBGLOG(HAL, ERROR, + "glUsbSubmitUrb() reports error (%d) [%s] (EP%d OUT)\n", + ret, __func__, arTcToUSBEP[ucTc]); + halTxUSBProcessMsduDone(prGlueInfo, prUsbReq); + prBufCtrl->u4WrIdx = 0; + usb_unanchor_urb(prUsbReq->prUrb); + list_add_tail(&prUsbReq->list, &prHifInfo->rTxDataCompleteQ); +#if CFG_USB_TX_HANDLE_IN_HIF_THREAD + kalSetIntEvent(prGlueInfo); +#else + /*tasklet_hi_schedule(&prGlueInfo->rTxCompleteTask);*/ + tasklet_schedule(&prGlueInfo->rTxCompleteTask); +#endif + return WLAN_STATUS_FAILURE; + } + + return u4Status; +} +#endif + +uint32_t halTxUSBSendData(IN struct GLUE_INFO *prGlueInfo, IN struct MSDU_INFO *prMsduInfo) +{ + struct GL_HIF_INFO *prHifInfo = &prGlueInfo->rHifInfo; + struct mt66xx_chip_info *prChipInfo; + uint32_t u4Status = WLAN_STATUS_SUCCESS; + struct USB_REQ *prUsbReq; + struct BUF_CTRL *prBufCtrl; + uint32_t u4PaddingLength; + struct sk_buff *skb; + uint8_t ucTc; + uint8_t *pucBuf; + uint32_t u4Length; + uint32_t u4TotalLen; +#if CFG_USB_TX_AGG + unsigned long flags; +#else + int ret; +#endif + + prChipInfo = prGlueInfo->prAdapter->chip_info; + skb = (struct sk_buff *)prMsduInfo->prPacket; + pucBuf = skb->data; + u4Length = skb->len; + u4TotalLen = u4Length + prChipInfo->u2HifTxdSize; + ucTc = USB_TRANS_MSDU_TC(prMsduInfo); +#if (CFG_SUPPORT_DMASHDL_SYSDVT) + if (prMsduInfo->ucPktType == ENUM_PKT_ICMP) { + if (DMASHDL_DVT_QUEUE_MAPPING_TYPE1(prGlueInfo->prAdapter) + || DMASHDL_DVT_QUEUE_MAPPING_TYPE2(prGlueInfo->prAdapter)) { + /* send ping packets to each EP for DMASHDL DVT */ + ucTc = prMsduInfo->ucTarQueue % TC_NUM; + /* skip TC4, TC4=>EP8 is reserved for CMD */ + if (ucTc == TC4_INDEX) + ucTc = TC_NUM; + DMASHDL_DVT_INC_PING_PKT_CNT(prGlueInfo->prAdapter, + prMsduInfo->ucTarQueue); + } + } +#endif /* CFG_SUPPORT_DMASHDL_SYSDVT */ + +#if CFG_USB_TX_AGG + spin_lock_irqsave(&prHifInfo->rTxDataQLock, flags); + + if (list_empty(&prHifInfo->rTxDataFreeQ[ucTc])) { + if (glUsbBorrowFfaReq(prHifInfo, ucTc) == FALSE) { + spin_unlock_irqrestore(&prHifInfo->rTxDataQLock, flags); + DBGLOG(HAL, ERROR, "run out of rTxDataFreeQ #1!!\n"); + wlanProcessQueuedMsduInfo(prGlueInfo->prAdapter, prMsduInfo); + return WLAN_STATUS_RESOURCES; + } + } + prUsbReq = list_entry(prHifInfo->rTxDataFreeQ[ucTc].next, struct USB_REQ, list); + prBufCtrl = prUsbReq->prBufCtrl; + + if (prHifInfo->u4AggRsvSize[ucTc] < ALIGN_4(u4TotalLen)) + DBGLOG(HAL, ERROR, "u4AggRsvSize[%hhu] count FAIL (%u, %u)\n", + ucTc, prHifInfo->u4AggRsvSize[ucTc], u4TotalLen); + prHifInfo->u4AggRsvSize[ucTc] -= ALIGN_4(u4TotalLen); + + if (prBufCtrl->u4WrIdx + ALIGN_4(u4TotalLen) + LEN_USB_UDMA_TX_TERMINATOR > prBufCtrl->u4BufSize) { + halTxUSBSendAggData(prHifInfo, ucTc, prUsbReq); + + if (list_empty(&prHifInfo->rTxDataFreeQ[ucTc])) { + if (glUsbBorrowFfaReq(prHifInfo, ucTc) == FALSE) { + spin_unlock_irqrestore(&prHifInfo->rTxDataQLock, + flags); + DBGLOG(HAL, ERROR, "run out of rTxDataFreeQ #2!!\n"); + wlanProcessQueuedMsduInfo(prGlueInfo->prAdapter, prMsduInfo); + return WLAN_STATUS_FAILURE; + } + } + + prUsbReq = list_entry(prHifInfo->rTxDataFreeQ[ucTc].next, struct USB_REQ, list); + prBufCtrl = prUsbReq->prBufCtrl; + } + + HAL_WRITE_HIF_TXD(prChipInfo, prBufCtrl->pucBuf + prBufCtrl->u4WrIdx, u4Length); + prBufCtrl->u4WrIdx += prChipInfo->u2HifTxdSize; + memcpy(prBufCtrl->pucBuf + prBufCtrl->u4WrIdx, pucBuf, u4Length); + prBufCtrl->u4WrIdx += u4Length; + + u4PaddingLength = (ALIGN_4(u4TotalLen) - u4TotalLen); + if (u4PaddingLength) { + memset(prBufCtrl->pucBuf + prBufCtrl->u4WrIdx, 0, u4PaddingLength); + prBufCtrl->u4WrIdx += u4PaddingLength; + } + + if (!prMsduInfo->pfTxDoneHandler) + QUEUE_INSERT_TAIL(&prUsbReq->rSendingDataMsduInfoList, (struct QUE_ENTRY *) prMsduInfo); + + if (usb_anchor_empty(&prHifInfo->rTxDataAnchor[ucTc])) + halTxUSBSendAggData(prHifInfo, ucTc, prUsbReq); + + spin_unlock_irqrestore(&prHifInfo->rTxDataQLock, flags); +#else + prUsbReq = glUsbDequeueReq(prHifInfo, &prHifInfo->rTxDataFreeQ, + &prHifInfo->rTxDataQLock); + if (prUsbReq == NULL) { + DBGLOG(HAL, ERROR, "run out of rTxDataFreeQ!!\n"); + wlanProcessQueuedMsduInfo(prGlueInfo->prAdapter, prMsduInfo); + return WLAN_STATUS_RESOURCES; + } + + prBufCtrl = prUsbReq->prBufCtrl; + prBufCtrl->u4WrIdx = 0; + + HAL_WRITE_HIF_TXD(prChipInfo, prBufCtrl->pucBuf, u4Length); + prBufCtrl->u4WrIdx += prChipInfo->u2HifTxdSize; + + memcpy(prBufCtrl->pucBuf + prChipInfo->u2HifTxdSize, pucBuf, u4Length); + prBufCtrl->u4WrIdx += u4Length; + + u4PaddingLength = (ALIGN_4(u4TotalLen) - u4TotalLen); + if (u4PaddingLength) { + memset(prBufCtrl->pucBuf + prBufCtrl->u4WrIdx, 0, u4PaddingLength); + prBufCtrl->u4WrIdx += u4PaddingLength; + } + + memset(prBufCtrl->pucBuf + prBufCtrl->u4WrIdx, 0, LEN_USB_UDMA_TX_TERMINATOR); + prBufCtrl->u4WrIdx += LEN_USB_UDMA_TX_TERMINATOR; + + if (!prMsduInfo->pfTxDoneHandler) + QUEUE_INSERT_TAIL(&prUsbReq->rSendingDataMsduInfoList, (struct QUE_ENTRY *) prMsduInfo); + + *((uint8_t *)&prUsbReq->prPriv) = ucTc; + usb_fill_bulk_urb(prUsbReq->prUrb, + prHifInfo->udev, + usb_sndbulkpipe(prHifInfo->udev, arTcToUSBEP[ucTc]), + (void *)prUsbReq->prBufCtrl->pucBuf, + prBufCtrl->u4WrIdx, halTxUSBSendDataComplete, (void *)prUsbReq); +#if CFG_USB_CONSISTENT_DMA + prUsbReq->prUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; +#endif + + usb_anchor_urb(prUsbReq->prUrb, &prHifInfo->rTxDataAnchor); + ret = glUsbSubmitUrb(prHifInfo, prUsbReq->prUrb, SUBMIT_TYPE_TX_DATA); + if (ret) { + DBGLOG(HAL, ERROR, + "glUsbSubmitUrb() reports error (%d) [%s] (EP%d OUT)\n", + ret, __func__, arTcToUSBEP[ucTc]); + halTxUSBProcessMsduDone(prHifInfo->prGlueInfo, prUsbReq); + prBufCtrl->u4WrIdx = 0; + usb_unanchor_urb(prUsbReq->prUrb); + glUsbEnqueueReq(prHifInfo, &prHifInfo->rTxDataFreeQ, prUsbReq, + &prHifInfo->rTxDataQLock, FALSE); + return WLAN_STATUS_FAILURE; + } +#endif + + if (wlanIsChipRstRecEnabled(prGlueInfo->prAdapter) + && wlanIsChipNoAck(prGlueInfo->prAdapter)) { + wlanChipRstPreAct(prGlueInfo->prAdapter); + DBGLOG(HAL, ERROR, "usb trigger whole reset\n"); + HAL_WIFI_FUNC_CHIP_RESET(prGlueInfo->prAdapter); + } + return u4Status; +} + +uint32_t halTxUSBKickData(IN struct GLUE_INFO *prGlueInfo) +{ +#if CFG_USB_TX_AGG + struct GL_HIF_INFO *prHifInfo = &prGlueInfo->rHifInfo; + struct USB_REQ *prUsbReq; + struct BUF_CTRL *prBufCtrl; + uint8_t ucTc; + unsigned long flags; + + spin_lock_irqsave(&prHifInfo->rTxDataQLock, flags); + + for (ucTc = TC0_INDEX; ucTc < USB_TC_NUM; ucTc++) { + if (list_empty(&prHifInfo->rTxDataFreeQ[ucTc])) + continue; + + prUsbReq = list_entry(prHifInfo->rTxDataFreeQ[ucTc].next, struct USB_REQ, list); + prBufCtrl = prUsbReq->prBufCtrl; + + if (prBufCtrl->u4WrIdx) + halTxUSBSendAggData(prHifInfo, ucTc, prUsbReq); + } + + spin_unlock_irqrestore(&prHifInfo->rTxDataQLock, flags); +#endif + + return WLAN_STATUS_SUCCESS; +} + +void halTxUSBSendDataComplete(struct urb *urb) +{ + struct USB_REQ *prUsbReq = urb->context; + struct GL_HIF_INFO *prHifInfo = prUsbReq->prHifInfo; + struct GLUE_INFO *prGlueInfo = prHifInfo->prGlueInfo; + + glUsbEnqueueReq(prHifInfo, &prHifInfo->rTxDataCompleteQ, prUsbReq, &prHifInfo->rTxDataQLock, FALSE); + +#if CFG_USB_TX_HANDLE_IN_HIF_THREAD + kalSetIntEvent(prGlueInfo); +#else + /*tasklet_hi_schedule(&prGlueInfo->rTxCompleteTask);*/ + tasklet_schedule(&prGlueInfo->rTxCompleteTask); +#endif +} + +void halTxUSBProcessMsduDone(IN struct GLUE_INFO *prGlueInfo, struct USB_REQ *prUsbReq) +{ + uint8_t ucTc; + struct QUE rFreeQueue; + struct QUE *prFreeQueue; + struct urb *urb = prUsbReq->prUrb; + uint32_t u4SentDataSize; + + ucTc = *((uint8_t *)&prUsbReq->prPriv) & TC_MASK; + + prFreeQueue = &rFreeQueue; + QUEUE_INITIALIZE(prFreeQueue); + QUEUE_MOVE_ALL((prFreeQueue), (&(prUsbReq->rSendingDataMsduInfoList))); + if (g_pfTxDataDoneCb) + g_pfTxDataDoneCb(prGlueInfo, prFreeQueue); + + u4SentDataSize = urb->actual_length - LEN_USB_UDMA_TX_TERMINATOR; + nicTxReleaseResource_PSE(prGlueInfo->prAdapter, ucTc, + nicTxGetPageCount(prGlueInfo->prAdapter, u4SentDataSize, TRUE), TRUE); +} + +void halTxUSBProcessDataComplete(IN struct ADAPTER *prAdapter, struct USB_REQ *prUsbReq) +{ + uint8_t ucTc; + u_int8_t fgFfa; + struct urb *urb = prUsbReq->prUrb; + struct GL_HIF_INFO *prHifInfo = prUsbReq->prHifInfo; +#if CFG_USB_TX_AGG + struct BUF_CTRL *prBufCtrl = prUsbReq->prBufCtrl; +#endif + unsigned long flags; + + ucTc = *((uint8_t *)&prUsbReq->prPriv) & TC_MASK; + fgFfa = *((uint8_t *)&prUsbReq->prPriv) & FFA_MASK; + + if (urb->status != 0) { + DBGLOG(TX, ERROR, "[%s] send DATA fail (status = %d)\n", __func__, urb->status); + /* TODO: handle error */ + } + + halTxUSBProcessMsduDone(prAdapter->prGlueInfo, prUsbReq); + + spin_lock_irqsave(&prHifInfo->rTxDataQLock, flags); +#if CFG_USB_TX_AGG + prBufCtrl->u4WrIdx = 0; + + if ((fgFfa == FALSE) || list_empty(&prHifInfo->rTxDataFreeQ[ucTc])) + list_add_tail(&prUsbReq->list, &prHifInfo->rTxDataFreeQ[ucTc]); + else + list_add_tail(&prUsbReq->list, &prHifInfo->rTxDataFfaQ); + + if (usb_anchor_empty(&prHifInfo->rTxDataAnchor[ucTc])) { + prUsbReq = list_entry(prHifInfo->rTxDataFreeQ[ucTc].next, struct USB_REQ, list); + prBufCtrl = prUsbReq->prBufCtrl; + + if (prBufCtrl->u4WrIdx != 0) + halTxUSBSendAggData(prHifInfo, ucTc, prUsbReq); /* TODO */ + } +#else + list_add_tail(&prUsbReq->list, &prHifInfo->rTxDataFreeQ); +#endif + spin_unlock_irqrestore(&prHifInfo->rTxDataQLock, flags); + + if (!HAL_IS_TX_DIRECT(prAdapter)) { + if (kalGetTxPendingCmdCount(prAdapter->prGlueInfo) > 0 || wlanGetTxPendingFrameCount(prAdapter) > 0) + kalSetEvent(prAdapter->prGlueInfo); + kalSetTxEvent2Hif(prAdapter->prGlueInfo); + } +} + +uint32_t halRxUSBEnqueueRFB( + IN struct ADAPTER *prAdapter, + IN uint8_t *pucBuf, + IN uint32_t u4Length, + IN uint32_t u4MinRfbCnt, + IN struct list_head *prCompleteQ) +{ + struct GLUE_INFO *prGlueInfo = prAdapter->prGlueInfo; + struct mt66xx_chip_info *prChipInfo; + struct RX_CTRL *prRxCtrl = &prAdapter->rRxCtrl; + struct SW_RFB *prSwRfb = (struct SW_RFB *) NULL; + void *prRxStatus; + uint32_t u4RemainCount; + uint16_t u2RxByteCount; + uint8_t *pucRxFrame; + uint32_t u4EnqCnt = 0; + struct BUS_INFO *prBusInfo; +#if CFG_TCP_IP_CHKSUM_OFFLOAD + uint32_t *pu4HwAppendDW; +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ + struct RX_DESC_OPS_T *prRxDescOps; + + KAL_SPIN_LOCK_DECLARATION(); + + ASSERT(prAdapter); + prChipInfo = prAdapter->chip_info; + prBusInfo = prChipInfo->bus_info; + prRxDescOps = prChipInfo->prRxDescOps; + ASSERT(prRxDescOps->nic_rxd_get_rx_byte_count); + ASSERT(prRxDescOps->nic_rxd_get_pkt_type); + + pucRxFrame = pucBuf; + u4RemainCount = u4Length; + while (u4RemainCount > 4) { + /* + * For different align support. + * Ex. We need to do 8byte align for 7915u. + */ + if (prBusInfo->asicUsbRxByteCount) + u2RxByteCount = prBusInfo->asicUsbRxByteCount(prAdapter, + prBusInfo, pucRxFrame); + else { + u2RxByteCount = + prRxDescOps->nic_rxd_get_rx_byte_count( + pucRxFrame); + u2RxByteCount = ALIGN_4(u2RxByteCount) + + LEN_USB_RX_PADDING_CSO; + } + + if (u2RxByteCount <= CFG_RX_MAX_PKT_SIZE) { + prSwRfb = NULL; + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_FREE_QUE); + if (prRxCtrl->rFreeSwRfbList.u4NumElem > u4MinRfbCnt) + QUEUE_REMOVE_HEAD(&prRxCtrl->rFreeSwRfbList, prSwRfb, struct SW_RFB *); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_FREE_QUE); + + if (!prSwRfb) + return u4Length - u4RemainCount; + + kalMemCopy(prSwRfb->pucRecvBuff, pucRxFrame, u2RxByteCount); + + prRxStatus = prSwRfb->prRxStatus; + ASSERT(prRxStatus); + + prSwRfb->ucPacketType = + prRxDescOps->nic_rxd_get_pkt_type(prRxStatus); + /* DBGLOG(RX, TRACE, ("ucPacketType = %d\n", prSwRfb->ucPacketType)); */ +#if CFG_TCP_IP_CHKSUM_OFFLOAD + pu4HwAppendDW = (uint32_t *) prRxStatus; + pu4HwAppendDW += + (ALIGN_4(u2RxByteCount - LEN_USB_RX_PADDING_CSO) + >> 2); + prSwRfb->u4TcpUdpIpCksStatus = *pu4HwAppendDW; +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ + + if (HAL_IS_RX_DIRECT(prAdapter)) { + switch (prSwRfb->ucPacketType) { + case RX_PKT_TYPE_RX_DATA: + spin_lock_bh(&prGlueInfo->rSpinLock[SPIN_LOCK_RX_DIRECT]); + if (HAL_MON_EN(prAdapter)) + nicRxProcessMonitorPacket( + prAdapter, prSwRfb); + else + nicRxProcessDataPacket( + prAdapter, prSwRfb); + spin_unlock_bh(&prGlueInfo->rSpinLock[SPIN_LOCK_RX_DIRECT]); + break; + default: + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); + QUEUE_INSERT_TAIL(&prRxCtrl->rReceivedRfbList, &prSwRfb->rQueEntry); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); + u4EnqCnt++; + break; + } + } else { + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); + QUEUE_INSERT_TAIL(&prRxCtrl->rReceivedRfbList, &prSwRfb->rQueEntry); + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); + u4EnqCnt++; + } + RX_INC_CNT(prRxCtrl, RX_MPDU_TOTAL_COUNT); + } else { + DBGLOG(RX, WARN, "Rx byte count:%u exceeds SW_RFB max length:%u\n!", + u2RxByteCount, CFG_RX_MAX_PKT_SIZE); + DBGLOG_MEM32(RX, WARN, pucRxFrame, + prChipInfo->rxd_size); + break; + } + + u4RemainCount -= u2RxByteCount; + pucRxFrame += u2RxByteCount; + } + + if (u4EnqCnt) { + set_bit(GLUE_FLAG_RX_BIT, &(prGlueInfo->ulFlag)); + wake_up_interruptible(&(prGlueInfo->waitq)); + } + + return u4Length; +} + +uint32_t halRxUSBReceiveEvent(IN struct ADAPTER *prAdapter, IN u_int8_t fgFillUrb) +{ + struct GLUE_INFO *prGlueInfo = prAdapter->prGlueInfo; + struct GL_HIF_INFO *prHifInfo = &prGlueInfo->rHifInfo; + struct USB_REQ *prUsbReq; + uint32_t u4Status = WLAN_STATUS_SUCCESS; + int ret; + + while (1) { + prUsbReq = glUsbDequeueReq(prHifInfo, &prHifInfo->rRxEventFreeQ, &prHifInfo->rRxEventQLock); + if (prUsbReq == NULL) + return WLAN_STATUS_RESOURCES; + + usb_anchor_urb(prUsbReq->prUrb, &prHifInfo->rRxEventAnchor); + + prUsbReq->prBufCtrl->u4ReadSize = 0; + if (prHifInfo->eEventEpType == EVENT_EP_TYPE_INTR && fgFillUrb) { + usb_fill_int_urb(prUsbReq->prUrb, + prHifInfo->udev, + usb_rcvintpipe(prHifInfo->udev, + USB_EVENT_EP_IN), + (void *)prUsbReq->prBufCtrl->pucBuf, + prUsbReq->prBufCtrl->u4BufSize, + halRxUSBReceiveEventComplete, + (void *)prUsbReq, + 1); + } else if (prHifInfo->eEventEpType == EVENT_EP_TYPE_BULK) { + usb_fill_bulk_urb(prUsbReq->prUrb, + prHifInfo->udev, + usb_rcvbulkpipe(prHifInfo->udev, + USB_EVENT_EP_IN), + (void *)prUsbReq->prBufCtrl->pucBuf, + prUsbReq->prBufCtrl->u4BufSize, + halRxUSBReceiveEventComplete, + (void *)prUsbReq); + } + ret = glUsbSubmitUrb(prHifInfo, prUsbReq->prUrb, + SUBMIT_TYPE_RX_EVENT); + if (ret) { + DBGLOG(HAL, ERROR, + "glUsbSubmitUrb() reports error (%d) [%s] (EP%d IN)\n", + ret, __func__, (USB_EVENT_EP_IN & 0x0F)); + usb_unanchor_urb(prUsbReq->prUrb); + glUsbEnqueueReq(prHifInfo, &prHifInfo->rRxEventFreeQ, prUsbReq, + &prHifInfo->rRxEventQLock, FALSE); + break; + } + } + + return u4Status; +} + +void halRxUSBReceiveEventComplete(struct urb *urb) +{ + struct USB_REQ *prUsbReq = urb->context; + struct GL_HIF_INFO *prHifInfo = prUsbReq->prHifInfo; + struct GLUE_INFO *prGlueInfo = prHifInfo->prGlueInfo; + + if (!(prHifInfo->state == USB_STATE_LINK_UP || + prHifInfo->state == USB_STATE_READY || + prHifInfo->state == USB_STATE_PRE_RESUME || + prHifInfo->state == USB_STATE_PRE_SUSPEND_START)) { + glUsbEnqueueReq(prHifInfo, &prHifInfo->rRxEventFreeQ, prUsbReq, &prHifInfo->rRxEventQLock, FALSE); + return; + } + + /* Hif power off wifi, drop rx packets and continue polling RX packets until RX path empty */ + if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { + glUsbEnqueueReq(prHifInfo, &prHifInfo->rRxEventFreeQ, prUsbReq, &prHifInfo->rRxEventQLock, FALSE); + halRxUSBReceiveEvent(prGlueInfo->prAdapter, FALSE); + return; + } + + if (urb->status == -ESHUTDOWN || urb->status == -ENOENT) { + glUsbEnqueueReq(prHifInfo, &prHifInfo->rRxEventFreeQ, prUsbReq, &prHifInfo->rRxEventQLock, FALSE); + DBGLOG(RX, ERROR, "USB device shutdown skip Rx [%s]\n", __func__); + return; + } + +#if CFG_USB_RX_HANDLE_IN_HIF_THREAD + DBGLOG(RX, TRACE, "[%s] Rx URB[0x%p] Len[%u] Sts[%u]\n", __func__, urb, urb->actual_length, urb->status); + + glUsbEnqueueReq(prHifInfo, &prHifInfo->rRxEventCompleteQ, prUsbReq, &prHifInfo->rRxEventQLock, FALSE); + + kalSetIntEvent(prGlueInfo); +#else + if (urb->status == 0) { + glUsbEnqueueReq(prHifInfo, &prHifInfo->rRxEventCompleteQ, prUsbReq, &prHifInfo->rRxEventQLock, FALSE); + + /*tasklet_hi_schedule(&prGlueInfo->rRxTask);*/ + tasklet_schedule(&prGlueInfo->rRxTask); + } else { + DBGLOG(RX, ERROR, "[%s] receive EVENT fail (status = %d)\n", __func__, urb->status); + glUsbEnqueueReq(prHifInfo, &prHifInfo->rRxEventFreeQ, prUsbReq, &prHifInfo->rRxEventQLock, FALSE); + + halRxUSBReceiveEvent(prGlueInfo->prAdapter, FALSE); + } +#endif +} + +uint32_t halRxUSBReceiveData(IN struct ADAPTER *prAdapter) +{ + struct GLUE_INFO *prGlueInfo = prAdapter->prGlueInfo; + struct GL_HIF_INFO *prHifInfo = &prGlueInfo->rHifInfo; + struct USB_REQ *prUsbReq; + uint32_t u4Status = WLAN_STATUS_SUCCESS; + int ret; + + while (1) { + prUsbReq = glUsbDequeueReq(prHifInfo, &prHifInfo->rRxDataFreeQ, &prHifInfo->rRxDataQLock); + if (prUsbReq == NULL) + return WLAN_STATUS_RESOURCES; + + usb_anchor_urb(prUsbReq->prUrb, &prHifInfo->rRxDataAnchor); + + prUsbReq->prBufCtrl->u4ReadSize = 0; + usb_fill_bulk_urb(prUsbReq->prUrb, + prHifInfo->udev, + usb_rcvbulkpipe(prHifInfo->udev, USB_DATA_EP_IN), + (void *)prUsbReq->prBufCtrl->pucBuf, + prUsbReq->prBufCtrl->u4BufSize, halRxUSBReceiveDataComplete, (void *)prUsbReq); + ret = glUsbSubmitUrb(prHifInfo, prUsbReq->prUrb, + SUBMIT_TYPE_RX_DATA); + if (ret) { + DBGLOG(HAL, ERROR, + "glUsbSubmitUrb() reports error (%d) [%s] (EP%d IN)\n", + ret, __func__, (USB_EVENT_EP_IN & 0x0F)); + usb_unanchor_urb(prUsbReq->prUrb); + glUsbEnqueueReq(prHifInfo, &prHifInfo->rRxDataFreeQ, prUsbReq, &prHifInfo->rRxDataQLock, FALSE); + break; + } + } + + return u4Status; +} + +void halRxUSBReceiveDataComplete(struct urb *urb) +{ + struct USB_REQ *prUsbReq = urb->context; + struct GL_HIF_INFO *prHifInfo = prUsbReq->prHifInfo; + struct GLUE_INFO *prGlueInfo = prHifInfo->prGlueInfo; + + if (!(prHifInfo->state == USB_STATE_LINK_UP || + prHifInfo->state == USB_STATE_READY)) { + glUsbEnqueueReq(prHifInfo, &prHifInfo->rRxDataFreeQ, prUsbReq, &prHifInfo->rRxDataQLock, FALSE); + return; + } + + /* Hif power off wifi, drop rx packets and continue polling RX packets until RX path empty */ + if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { + glUsbEnqueueReq(prHifInfo, &prHifInfo->rRxDataFreeQ, prUsbReq, &prHifInfo->rRxDataQLock, FALSE); + halRxUSBReceiveData(prGlueInfo->prAdapter); + return; + } + + if (urb->status == -ESHUTDOWN || urb->status == -ENOENT) { + glUsbEnqueueReq(prHifInfo, &prHifInfo->rRxDataFreeQ, prUsbReq, &prHifInfo->rRxDataQLock, FALSE); + DBGLOG(RX, ERROR, "USB device shutdown skip Rx [%s]\n", __func__); + return; + } + +#if CFG_USB_RX_HANDLE_IN_HIF_THREAD + glUsbEnqueueReq(prHifInfo, &prHifInfo->rRxDataCompleteQ, prUsbReq, &prHifInfo->rRxDataQLock, FALSE); + + kalSetIntEvent(prGlueInfo); +#else + if (urb->status == 0) { + glUsbEnqueueReq(prHifInfo, &prHifInfo->rRxDataCompleteQ, prUsbReq, &prHifInfo->rRxDataQLock, FALSE); + + /*tasklet_hi_schedule(&prGlueInfo->rRxTask);*/ + tasklet_schedule(&prGlueInfo->rRxTask); + } else { + DBGLOG(RX, ERROR, "[%s] receive DATA fail (status = %d)\n", __func__, urb->status); + glUsbEnqueueReq(prHifInfo, &prHifInfo->rRxDataFreeQ, prUsbReq, &prHifInfo->rRxDataQLock, FALSE); + + halRxUSBReceiveData(prGlueInfo->prAdapter); + } +#endif +} + +void halRxUSBProcessEventDataComplete(IN struct ADAPTER *prAdapter, + struct list_head *prCompleteQ, struct list_head *prFreeQ, uint32_t u4MinRfbCnt) +{ + struct USB_REQ *prUsbReq; + struct urb *prUrb; + struct BUF_CTRL *prBufCtrl; + struct GLUE_INFO *prGlueInfo = prAdapter->prGlueInfo; + struct GL_HIF_INFO *prHifInfo = &prGlueInfo->rHifInfo; + uint8_t *pucBufAddr; + uint32_t u4BufLen; + static u_int8_t s_fgOutOfSwRfb = FALSE; + static uint32_t s_u4OutOfSwRfbPrintLimit; + + /* lock with rRxDataQLock if processing queue is data queue */ + /* and vice versa */ + spinlock_t *prLock = + (prCompleteQ == &prHifInfo->rRxDataCompleteQ) ? + (&prHifInfo->rRxDataQLock) : + (&prHifInfo->rRxEventQLock); + + /* Process complete event/data */ + prUsbReq = glUsbDequeueReq(prHifInfo, prCompleteQ, prLock); + while (prUsbReq) { + prUrb = prUsbReq->prUrb; + prBufCtrl = prUsbReq->prBufCtrl; + + DBGLOG(RX, LOUD, "[%s] Rx URB[0x%p] Len[%u] Sts[%u]\n", __func__, + prUrb, prUrb->actual_length, prUrb->status); + + if (prUrb->status != 0) { + DBGLOG(RX, ERROR, "[%s] receive EVENT/DATA fail (status = %d)\n", __func__, prUrb->status); + + glUsbEnqueueReq(prHifInfo, prFreeQ, prUsbReq, prLock, + FALSE); + prUsbReq = glUsbDequeueReq(prHifInfo, prCompleteQ, + prLock); + continue; + } + + pucBufAddr = prBufCtrl->pucBuf + prBufCtrl->u4ReadSize; + u4BufLen = prUrb->actual_length - prBufCtrl->u4ReadSize; + + prBufCtrl->u4ReadSize += halRxUSBEnqueueRFB( + prAdapter, + pucBufAddr, + u4BufLen, + u4MinRfbCnt, + prCompleteQ); + + if (unlikely(prUrb->actual_length - prBufCtrl->u4ReadSize > 4)) { + if (s_fgOutOfSwRfb == FALSE) { + if ((long)jiffies - (long)s_u4OutOfSwRfbPrintLimit > 0) { + DBGLOG(RX, WARN, "Out of SwRfb!\n"); + s_u4OutOfSwRfbPrintLimit = jiffies + MSEC_TO_JIFFIES(SW_RFB_LOG_LIMIT_MS); + } + s_fgOutOfSwRfb = TRUE; + } + glUsbEnqueueReq(prHifInfo, prCompleteQ, prUsbReq, + prLock, TRUE); + + set_bit(GLUE_FLAG_RX_BIT, &prGlueInfo->ulFlag); + wake_up_interruptible(&prGlueInfo->waitq); + + schedule_delayed_work(&prGlueInfo->rRxPktDeAggWork, MSEC_TO_JIFFIES(SW_RFB_RECHECK_MS)); + break; + } + + if (unlikely(s_fgOutOfSwRfb == TRUE)) + s_fgOutOfSwRfb = FALSE; + + glUsbEnqueueReq(prHifInfo, prFreeQ, prUsbReq, prLock, FALSE); + prUsbReq = glUsbDequeueReq(prHifInfo, prCompleteQ, prLock); + } +} + +/*----------------------------------------------------------------------------*/ +/*! +* @brief enable global interrupt +* +* @param prAdapter pointer to the Adapter handler +* +* @return (none) +*/ +/*----------------------------------------------------------------------------*/ +void halEnableInterrupt(IN struct ADAPTER *prAdapter) +{ + struct GLUE_INFO *prGlueInfo; + struct GL_HIF_INFO *prHifInfo; + + ASSERT(prAdapter); + + prGlueInfo = prAdapter->prGlueInfo; + prHifInfo = &prGlueInfo->rHifInfo; + + halRxUSBReceiveData(prAdapter); + if (prHifInfo->eEventEpType != EVENT_EP_TYPE_DATA_EP) + halRxUSBReceiveEvent(prAdapter, TRUE); + + glUdmaRxAggEnable(prGlueInfo, TRUE); +} /* end of halEnableInterrupt() */ + +/*----------------------------------------------------------------------------*/ +/*! +* @brief disable global interrupt +* +* @param prAdapter pointer to the Adapter handler +* +* @return (none) +*/ +/*----------------------------------------------------------------------------*/ +void halDisableInterrupt(IN struct ADAPTER *prAdapter) +{ + struct GLUE_INFO *prGlueInfo; + struct GL_HIF_INFO *prHifInfo; + + ASSERT(prAdapter); + prGlueInfo = prAdapter->prGlueInfo; + prHifInfo = &prGlueInfo->rHifInfo; + + usb_kill_anchored_urbs(&prHifInfo->rRxDataAnchor); + usb_kill_anchored_urbs(&prHifInfo->rRxEventAnchor); + + glUdmaRxAggEnable(prGlueInfo, FALSE); + prAdapter->fgIsIntEnable = FALSE; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This routine is used to process the POWER OFF procedure. +* +* \param[in] pvAdapter Pointer to the Adapter structure. +* +* \return (none) +*/ +/*----------------------------------------------------------------------------*/ +u_int8_t halSetDriverOwn(IN struct ADAPTER *prAdapter) +{ + return TRUE; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This routine is used to process the POWER ON procedure. +* +* \param[in] pvAdapter Pointer to the Adapter structure. +* +* \return (none) +*/ +/*----------------------------------------------------------------------------*/ +void halSetFWOwn(IN struct ADAPTER *prAdapter, IN u_int8_t fgEnableGlobalInt) +{ +} + +void halWakeUpWiFi(IN struct ADAPTER *prAdapter) +{ + u_int8_t fgResult; + uint8_t ucCount = 0; + + DBGLOG(INIT, INFO, "Power on Wi-Fi....\n"); + + HAL_WIFI_FUNC_READY_CHECK(prAdapter, WIFI_FUNC_INIT_DONE, &fgResult); + + while (!fgResult) { + HAL_WIFI_FUNC_POWER_ON(prAdapter); + kalMdelay(50); + HAL_WIFI_FUNC_READY_CHECK(prAdapter, WIFI_FUNC_INIT_DONE, &fgResult); + + ucCount++; + + if (ucCount >= 5) { + DBGLOG(INIT, WARN, "Power on failed!!!\n"); + break; + } + } + + prAdapter->fgIsFwOwn = FALSE; +} + +void halEnableFWDownload(IN struct ADAPTER *prAdapter, IN u_int8_t fgEnable) +{ +#if (CFG_UMAC_GENERATION >= 0x20) + struct mt66xx_chip_info *prChipInfo; + + ASSERT(prAdapter); + + prChipInfo = prAdapter->chip_info; + if (prChipInfo->asicEnableFWDownload) { + prChipInfo->asicEnableFWDownload(prAdapter, fgEnable); + } else { + uint32_t u4Value = 0; + + HAL_MCR_RD(prAdapter, UDMA_TX_QSEL, &u4Value); + + if (fgEnable) + u4Value |= FW_DL_EN; + else + u4Value &= ~FW_DL_EN; + + HAL_MCR_WR(prAdapter, UDMA_TX_QSEL, u4Value); + } +#endif +} + +void halDevInit(IN struct ADAPTER *prAdapter) +{ + struct GLUE_INFO *prGlueInfo; + + ASSERT(prAdapter); + prGlueInfo = prAdapter->prGlueInfo; + + glUdmaRxAggEnable(prGlueInfo, FALSE); + glUdmaTxRxEnable(prGlueInfo, TRUE); +} + +u_int8_t halTxIsDataBufEnough(IN struct ADAPTER *prAdapter, IN struct MSDU_INFO *prMsduInfo) +{ + struct GLUE_INFO *prGlueInfo = prAdapter->prGlueInfo; + struct GL_HIF_INFO *prHifInfo = &prGlueInfo->rHifInfo; +#if CFG_USB_TX_AGG + struct USB_REQ *prUsbReq; + struct BUF_CTRL *prBufCtrl; +#endif + uint8_t ucTc; + struct sk_buff *skb; + uint32_t u4Length; + struct mt66xx_chip_info *prChipInfo; + + unsigned long flags; + + prChipInfo = prAdapter->chip_info; + skb = (struct sk_buff *)prMsduInfo->prPacket; + u4Length = skb->len; + u4Length += prChipInfo->u2HifTxdSize; + ucTc = USB_TRANS_MSDU_TC(prMsduInfo); + + spin_lock_irqsave(&prHifInfo->rTxDataQLock, flags); + +#if CFG_USB_TX_AGG + if (list_empty(&prHifInfo->rTxDataFreeQ[ucTc])) { + if (glUsbBorrowFfaReq(prHifInfo, ucTc) == FALSE) { + spin_unlock_irqrestore(&prHifInfo->rTxDataQLock, flags); + return FALSE; + } + } + + prUsbReq = list_entry(prHifInfo->rTxDataFreeQ[ucTc].next, struct USB_REQ, list); + prBufCtrl = prUsbReq->prBufCtrl; + + if (prHifInfo->rTxDataFreeQ[ucTc].next->next == &prHifInfo->rTxDataFreeQ[ucTc]) { + /* length of rTxDataFreeQ equals 1 */ + if (prBufCtrl->u4WrIdx + ALIGN_4(u4Length) > + prBufCtrl->u4BufSize - prHifInfo->u4AggRsvSize[ucTc] - LEN_USB_UDMA_TX_TERMINATOR) { + /* Buffer is not enough */ + if (glUsbBorrowFfaReq(prHifInfo, ucTc) == FALSE) { + spin_unlock_irqrestore(&prHifInfo->rTxDataQLock, + flags); + return FALSE; + } + } + } + prHifInfo->u4AggRsvSize[ucTc] += ALIGN_4(u4Length); +#else + if (list_empty(&prHifInfo->rTxDataFreeQ)) { + spin_unlock_irqrestore(&prHifInfo->rTxDataQLock, flags); + + return FALSE; + } +#endif + + spin_unlock_irqrestore(&prHifInfo->rTxDataQLock, flags); + return TRUE; +} + +uint8_t halTxRingDataSelect(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo) +{ + return 0; +} + +void halUpdateTxMaxQuota(IN struct ADAPTER *prAdapter) +{ +} + +void halProcessTxInterrupt(IN struct ADAPTER *prAdapter) +{ +#if CFG_USB_TX_HANDLE_IN_HIF_THREAD + struct USB_REQ *prUsbReq; + struct GL_HIF_INFO *prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + + /* Process complete Tx cmd */ + prUsbReq = glUsbDequeueReq(prHifInfo, &prHifInfo->rTxCmdCompleteQ, &prHifInfo->rTxCmdQLock); + while (prUsbReq) { + halTxUSBProcessCmdComplete(prAdapter, prUsbReq); + prUsbReq = glUsbDequeueReq(prHifInfo, + &prHifInfo->rTxCmdCompleteQ, + &prHifInfo->rTxCmdQLock); + } + + /* Process complete Tx data */ + prUsbReq = glUsbDequeueReq(prHifInfo, &prHifInfo->rTxDataCompleteQ, + &prHifInfo->rTxDataQLock); + while (prUsbReq) { + halTxUSBProcessDataComplete(prAdapter, prUsbReq); + prUsbReq = glUsbDequeueReq(prHifInfo, + &prHifInfo->rTxDataCompleteQ, + &prHifInfo->rTxDataQLock); + } +#endif +} + +bool halHifSwInfoInit(IN struct ADAPTER *prAdapter) +{ + return true; +} + +void halRxProcessMsduReport(IN struct ADAPTER *prAdapter, IN OUT struct SW_RFB *prSwRfb) +{ + +} + +uint32_t halTxGetPageCount(IN struct ADAPTER *prAdapter, IN uint32_t u4FrameLength, IN u_int8_t fgIncludeDesc) +{ +#if CFG_USB_TX_AGG + struct mt66xx_chip_info *prChipInfo = prAdapter->chip_info; + uint32_t u4RequiredBufferSize; + uint32_t u4PageCount; + uint32_t u4TxHeadRoomSize = NIC_TX_DESC_AND_PADDING_LENGTH + prChipInfo->txd_append_size; + + /* Frame Buffer + * |<--Tx Descriptor-->|<--Tx descriptor padding-->| + * <--802.3/802.11 Header-->|<--Header padding-->|<--Payload-->| + */ + + if (fgIncludeDesc) + u4RequiredBufferSize = u4FrameLength; + else + u4RequiredBufferSize = u4TxHeadRoomSize + u4FrameLength; + + u4RequiredBufferSize = ALIGN_4(u4RequiredBufferSize); + + if (NIC_TX_PAGE_SIZE_IS_POWER_OF_2) + u4PageCount = (u4RequiredBufferSize + (NIC_TX_PAGE_SIZE - 1)) >> NIC_TX_PAGE_SIZE_IN_POWER_OF_2; + else + u4PageCount = (u4RequiredBufferSize + (NIC_TX_PAGE_SIZE - 1)) / NIC_TX_PAGE_SIZE; + + return u4PageCount; +#else + return 1; +#endif +} + +uint32_t halTxPollingResource(IN struct ADAPTER *prAdapter, IN uint8_t ucTC) +{ + return WLAN_STATUS_SUCCESS; +} + +void halSerHifReset(IN struct ADAPTER *prAdapter) +{ + uint32_t i; + + /** + * usb_reset_endpoint - Reset an endpoint's state. + * @dev: the device whose endpoint is to be reset + * @epaddr: the endpoint's address. Endpoint number for output, + * endpoint number + USB_DIR_IN for input + * + * Resets any host-side endpoint state such as the toggle bit, + * sequence number or current window. + * + * void usb_reset_endpoint(struct usb_device *dev, unsigned int epaddr); + */ + + /* SER new flow: just flush out ep out fifo, + * not to reset ep out endpoint + */ +#if 0 + /* reset ALL BULK OUT endpoints */ + for (i = USB_DATA_BULK_OUT_EP4; i <= USB_DATA_BULK_OUT_EP9; i++) + usb_reset_endpoint(prAdapter->prGlueInfo->rHifInfo.udev, i); +#endif + /* reset ALL BULK IN endpoints */ + for (i = USB_DATA_BULK_IN_EP4; i <= USB_DATA_BULK_IN_EP5; i++) + usb_reset_endpoint(prAdapter->prGlueInfo->rHifInfo.udev, + i | USB_DIR_IN); +} + +void halProcessRxInterrupt(IN struct ADAPTER *prAdapter) +{ + struct GL_HIF_INFO *prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + + /* Process complete data */ + halRxUSBProcessEventDataComplete(prAdapter, &prHifInfo->rRxDataCompleteQ, + &prHifInfo->rRxDataFreeQ, USB_RX_DATA_RFB_RSV_CNT); + halRxUSBReceiveData(prAdapter); + + if (prHifInfo->eEventEpType != EVENT_EP_TYPE_DATA_EP) { + /* Process complete event */ + halRxUSBProcessEventDataComplete(prAdapter, &prHifInfo->rRxEventCompleteQ, + &prHifInfo->rRxEventFreeQ, USB_RX_EVENT_RFB_RSV_CNT); + halRxUSBReceiveEvent(prAdapter, FALSE); + } +} + +uint32_t halDumpHifStatus(IN struct ADAPTER *prAdapter, IN uint8_t *pucBuf, IN uint32_t u4Max) +{ + uint32_t u4CpuIdx, u4DmaIdx, u4Int, u4GloCfg, u4Reg; + uint32_t u4Len = 0; + struct GLUE_INFO *prGlueInfo = prAdapter->prGlueInfo; + uint8_t pBuffer[512] = {0}; + + HAL_MCR_RD(prAdapter, 0x820b0118, &u4CpuIdx); + HAL_MCR_RD(prAdapter, 0x820b011c, &u4DmaIdx); + HAL_MCR_RD(prAdapter, 0x820b0220, &u4Int); + HAL_MCR_RD(prAdapter, 0x820b0204, &u4GloCfg); + + LOGBUF(pucBuf, u4Max, u4Len, "\n"); + LOGBUF(pucBuf, u4Max, u4Len, "PDMA1R1 CPU[%u] DMA[%u] INT[0x%08x] CFG[0x%08x]\n", u4CpuIdx, + u4DmaIdx, u4Int, u4GloCfg); + + HAL_MCR_RD(prAdapter, UDMA_WLCFG_0, &u4Reg); + + LOGBUF(pucBuf, u4Max, u4Len, "UDMA WLCFG[0x%08x]\n", u4Reg); + + LOGBUF(pucBuf, u4Max, u4Len, "\n"); + LOGBUF(pucBuf, u4Max, u4Len, "VenderID: %04x\n", + glGetUsbDeviceVendorId(prGlueInfo->rHifInfo.udev)); + LOGBUF(pucBuf, u4Max, u4Len, "ProductID: %04x\n", + glGetUsbDeviceProductId(prGlueInfo->rHifInfo.udev)); + + glGetUsbDeviceManufacturerName(prGlueInfo->rHifInfo.udev, pBuffer, + sizeof(pBuffer)); + LOGBUF(pucBuf, u4Max, u4Len, "Manufacturer: %s\n", + pBuffer); + + glGetUsbDeviceProductName(prGlueInfo->rHifInfo.udev, pBuffer, + sizeof(pBuffer)); + LOGBUF(pucBuf, u4Max, u4Len, "Product: %s\n", pBuffer); + + glGetUsbDeviceSerialNumber(prGlueInfo->rHifInfo.udev, pBuffer, + sizeof(pBuffer)); + LOGBUF(pucBuf, u4Max, u4Len, "SerialNumber: %s\n", + pBuffer); + + return u4Len; +} + +void halGetCompleteStatus(IN struct ADAPTER *prAdapter, OUT uint32_t *pu4IntStatus) +{ +#if CFG_USB_RX_HANDLE_IN_HIF_THREAD || CFG_USB_TX_HANDLE_IN_HIF_THREAD + struct GL_HIF_INFO *prHifInfo = &prAdapter->prGlueInfo->rHifInfo; +#endif + + *pu4IntStatus = 0; + +#if CFG_USB_RX_HANDLE_IN_HIF_THREAD + if (!list_empty(&prHifInfo->rRxDataCompleteQ) || !list_empty(&prHifInfo->rRxEventCompleteQ)) + *pu4IntStatus |= WHISR_RX0_DONE_INT; +#endif + +#if CFG_USB_TX_HANDLE_IN_HIF_THREAD + if (!list_empty(&prHifInfo->rTxDataCompleteQ) || !list_empty(&prHifInfo->rTxCmdCompleteQ)) + *pu4IntStatus |= WHISR_TX_DONE_INT; +#endif +} + +u_int8_t halIsPendingRx(IN struct ADAPTER *prAdapter) +{ +#if CFG_USB_RX_HANDLE_IN_HIF_THREAD + struct GL_HIF_INFO *prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + + if (!list_empty(&prHifInfo->rRxDataCompleteQ) || !list_empty(&prHifInfo->rRxEventCompleteQ)) + return TRUE; + else + return FALSE; +#else + return FALSE; +#endif +} + +/*----------------------------------------------------------------------------*/ +/*! +* @brief Send HIF_CTRL command to inform FW stop send packet/event to host +* suspend = 1 +* +* @param prAdapter Pointer to the Adapter structure. +* +* @return (void) +*/ +/*----------------------------------------------------------------------------*/ +void halUSBPreSuspendCmd(IN struct ADAPTER *prAdapter) +{ + struct CMD_HIF_CTRL rCmdHifCtrl; + uint32_t rStatus; + + rCmdHifCtrl.ucHifType = ENUM_HIF_TYPE_USB; + rCmdHifCtrl.ucHifDirection = ENUM_HIF_TX; + rCmdHifCtrl.ucHifStop = 1; + rCmdHifCtrl.ucHifSuspend = 1; + rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ + CMD_ID_HIF_CTRL, /* ucCID */ + TRUE, /* fgSetQuery */ + FALSE, /* fgNeedResp */ + FALSE, /* fgIsOid */ + NULL, /* pfCmdDoneHandler */ + NULL, /* pfCmdTimeoutHandler */ + sizeof(struct CMD_HIF_CTRL), /* u4SetQueryInfoLen */ + (uint8_t *)&rCmdHifCtrl, /* pucInfoBuffer */ + NULL, /* pvSetQueryBuffer */ + 0 /* u4SetQueryBufferLen */ + ); + + ASSERT(rStatus == WLAN_STATUS_PENDING); +} + +/*----------------------------------------------------------------------------*/ +/*! +* @brief Send HIF_CTRL command to inform FW allow send packet/event to host +* suspend = 0 +* +* @param prAdapter Pointer to the Adapter structure. +* +* @return (void) +*/ +/*----------------------------------------------------------------------------*/ +void halUSBPreResumeCmd(IN struct ADAPTER *prAdapter) +{ + struct CMD_HIF_CTRL rCmdHifCtrl; + uint32_t rStatus; + + rCmdHifCtrl.ucHifType = ENUM_HIF_TYPE_USB; + rCmdHifCtrl.ucHifDirection = ENUM_HIF_TX; + rCmdHifCtrl.ucHifStop = 0; + rCmdHifCtrl.ucHifSuspend = 0; + + rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ + CMD_ID_HIF_CTRL, /* ucCID */ + TRUE, /* fgSetQuery */ + FALSE, /* fgNeedResp */ + FALSE, /* fgIsOid */ + NULL, /* nicEventHifCtrl */ + NULL, /* pfCmdTimeoutHandler */ + sizeof(struct CMD_HIF_CTRL), + (uint8_t *)&rCmdHifCtrl, /* pucInfoBuffer */ + NULL, /* pvSetQueryBuffer */ + 0 /* u4SetQueryBufferLen */ + ); + + ASSERT(rStatus == WLAN_STATUS_PENDING); +} + +void halUSBPreSuspendDone(IN struct ADAPTER *prAdapter, IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf) +{ + unsigned long flags; + struct GL_HIF_INFO *prHifInfo; + + ASSERT(prAdapter); + prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + + spin_lock_irqsave(&prHifInfo->rStateLock, flags); + + if (prHifInfo->state == USB_STATE_LINK_UP + || prHifInfo->state == USB_STATE_PRE_SUSPEND_START) + prHifInfo->state = USB_STATE_PRE_SUSPEND_DONE; + else + DBGLOG(HAL, ERROR, "Previous USB state (%d)!\n", + prHifInfo->state); + + spin_unlock_irqrestore(&prHifInfo->rStateLock, flags); +} + +void halUSBPreSuspendTimeout(IN struct ADAPTER *prAdapter, IN struct CMD_INFO *prCmdInfo) +{ + unsigned long flags; + struct GL_HIF_INFO *prHifInfo; + + ASSERT(prAdapter); + prHifInfo = &prAdapter->prGlueInfo->rHifInfo; + + spin_lock_irqsave(&prHifInfo->rStateLock, flags); + + if (prHifInfo->state == USB_STATE_LINK_UP + || prHifInfo->state == USB_STATE_PRE_SUSPEND_START) + prHifInfo->state = USB_STATE_PRE_SUSPEND_FAIL; + else + DBGLOG(HAL, ERROR, "Previous USB state (%d)!\n", + prHifInfo->state); + + spin_unlock_irqrestore(&prHifInfo->rStateLock, flags); +} + +uint32_t halGetValidCoalescingBufSize(IN struct ADAPTER *prAdapter) +{ + uint32_t u4BufSize; + + if (HIF_TX_COALESCING_BUFFER_SIZE > HIF_RX_COALESCING_BUFFER_SIZE) + u4BufSize = HIF_TX_COALESCING_BUFFER_SIZE; + else + u4BufSize = HIF_RX_COALESCING_BUFFER_SIZE; + + return u4BufSize; +} + +uint32_t halAllocateIOBuffer(IN struct ADAPTER *prAdapter) +{ + return WLAN_STATUS_SUCCESS; +} + +uint32_t halReleaseIOBuffer(IN struct ADAPTER *prAdapter) +{ + return WLAN_STATUS_SUCCESS; +} + +void halProcessAbnormalInterrupt(IN struct ADAPTER *prAdapter) +{ + +} + +void halProcessSoftwareInterrupt(IN struct ADAPTER *prAdapter) +{ + +} + +void halDeAggRxPktWorker(struct work_struct *work) +{ + struct GLUE_INFO *prGlueInfo = ENTRY_OF(work, struct GLUE_INFO, rRxPktDeAggWork); + + /*tasklet_hi_schedule(&prGlueInfo->rRxTask);*/ + tasklet_schedule(&prGlueInfo->rRxTask); +} + +void halRxTasklet(unsigned long data) +{ + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *)data; + + halProcessRxInterrupt(prGlueInfo->prAdapter); +} + +void halTxCompleteTasklet(unsigned long data) +{ + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *)data; + struct GL_HIF_INFO *prHifInfo = &prGlueInfo->rHifInfo; + struct USB_REQ *prUsbReq; + + /* Process complete Tx data */ + prUsbReq = glUsbDequeueReq(prHifInfo, &prHifInfo->rTxDataCompleteQ, &prHifInfo->rTxDataQLock); + while (prUsbReq) { + halTxUSBProcessDataComplete(prGlueInfo->prAdapter, prUsbReq); + prUsbReq = glUsbDequeueReq(prHifInfo, &prHifInfo->rTxDataCompleteQ, &prHifInfo->rTxDataQLock); + } +} + +/* Hif power off wifi */ +uint32_t halHifPowerOffWifi(IN struct ADAPTER *prAdapter) +{ + uint32_t rStatus = WLAN_STATUS_SUCCESS; + + DBGLOG(INIT, INFO, "Power off Wi-Fi!\n"); + + /* Power off Wi-Fi */ + wlanSendNicPowerCtrlCmd(prAdapter, TRUE); + + rStatus = wlanCheckWifiFunc(prAdapter, FALSE); + + glUsbSetState(&prAdapter->prGlueInfo->rHifInfo, USB_STATE_WIFI_OFF); + + nicDisableInterrupt(prAdapter); + + wlanClearPendingInterrupt(prAdapter); + + halTxCancelAllSending(prAdapter); + + return rStatus; +} + +void halPrintHifDbgInfo(IN struct ADAPTER *prAdapter) +{ + +} + +u_int8_t halIsTxResourceControlEn(IN struct ADAPTER *prAdapter) +{ + return FALSE; +} + +void halTxResourceResetHwTQCounter(IN struct ADAPTER *prAdapter) +{ +} + +uint32_t halGetHifTxPageSize(IN struct ADAPTER *prAdapter) +{ + return HIF_TX_PAGE_SIZE; +} + +void halSerSyncTimerHandler(IN struct ADAPTER *prAdapter) +{ + static u_int8_t ucSerState = ERR_RECOV_STOP_IDLE; + uint32_t u4SerAction; + struct mt66xx_chip_info *prChipInfo; + + if (prAdapter->prGlueInfo->rHifInfo.state == USB_STATE_SUSPEND) + return; + + prChipInfo = prAdapter->chip_info; + + /* get MCU SER event */ + kalDevRegRead(prAdapter->prGlueInfo, prChipInfo->u4SerUsbMcuEventAddr, + &u4SerAction); + + if (u4SerAction) { + DBGLOG(NIC, INFO, "%s u4SerAction=0x%08X\n", __func__, + u4SerAction); + + /* clear MCU SER event */ + kalDevRegWrite(prAdapter->prGlueInfo, + prChipInfo->u4SerUsbMcuEventAddr, 0); + } + + switch (ucSerState) { + case ERR_RECOV_STOP_IDLE: + if (u4SerAction == ERROR_DETECT_STOP_PDMA) { + if (prChipInfo->asicDumpSerDummyCR) + prChipInfo->asicDumpSerDummyCR(prAdapter); + + DBGLOG(HAL, INFO, + "SER(E) Host stop HIF tx/rx operation\n"); + + /* change SER FSM to SER_STOP_HOST_TX_RX */ + nicSerStopTxRx(prAdapter); + /* stop TX BULK OUT URB */ + halTxCancelAllSending(prAdapter); + /* stop RX BULK IN URB */ + halDisableInterrupt(prAdapter); + + DBGLOG(HAL, INFO, + "SER(F) Host ACK HIF tx/rx stop operation done\n"); + + /* Send Host stops TX/RX done response to mcu */ + kalDevRegWrite(prAdapter->prGlueInfo, + prChipInfo->u4SerUsbHostAckAddr, + MCU_INT_PDMA0_STOP_DONE); + ucSerState = ERR_RECOV_STOP_PDMA0; + } else { + /* do nothing */ + } + break; + + case ERR_RECOV_STOP_PDMA0: + if (u4SerAction == ERROR_DETECT_RESET_DONE) { + DBGLOG(HAL, INFO, "SER(L) Host re-initialize WFDMA\n"); + DBGLOG(HAL, INFO, "SER(M) Host enable WFDMA\n"); + if (prChipInfo->asicUsbInit) + prChipInfo->asicUsbInit(prAdapter, prChipInfo); + + DBGLOG(HAL, INFO, + "SER(N) Host ACK WFDMA init done\n"); + /* Send Host stops TX/RX done response to mcu */ + kalDevRegWrite(prAdapter->prGlueInfo, + prChipInfo->u4SerUsbHostAckAddr, + MCU_INT_PDMA0_INIT_DONE); + + ucSerState = ERR_RECOV_RESET_PDMA0; + } else { + /* do nothing */ + } + break; + case ERR_RECOV_RESET_PDMA0: + if (u4SerAction == ERROR_DETECT_RECOVERY_DONE) { + DBGLOG(HAL, INFO, + "SER(Q) Host ACK MCU SER handle done\n"); + /* Send Host stops TX/RX done response to mcu */ + kalDevRegWrite(prAdapter->prGlueInfo, + prChipInfo->u4SerUsbHostAckAddr, + MCU_INT_PDMA0_RECOVERY_DONE); + ucSerState = ERR_RECOV_WAIT_MCU_NORMAL; + } else { + /* do nothing */ + } + break; + + case ERR_RECOV_WAIT_MCU_NORMAL: + if (u4SerAction == ERROR_DETECT_MCU_NORMAL_STATE) { + + /* update Beacon frame if operating in AP mode. */ + DBGLOG(HAL, INFO, "SER(T) Host re-initialize BCN\n"); + nicSerReInitBeaconFrame(prAdapter); + + DBGLOG(HAL, INFO, + "SER(U) Host reset TX/RX endpoint\n"); + + halSerHifReset(prAdapter); + halEnableInterrupt(prAdapter); + + /* resume TX/RX */ + nicSerStartTxRx(prAdapter); + ucSerState = ERR_RECOV_STOP_IDLE; + } else { + /* do nothing */ + } + break; + } +} + +/*----------------------------------------------------------------------------*/ +/*! +* @brief Check if HIF state is READY for upper layer cfg80211 +* +* @param prAdapter Pointer to the Adapter structure. +* +* @return (TRUE: ready, FALSE: not ready) +*/ +/*----------------------------------------------------------------------------*/ +bool halIsHifStateReady(IN struct ADAPTER *prAdapter, uint8_t *pucState) +{ + if (!prAdapter) + return FALSE; + + if (!prAdapter->prGlueInfo) + return FALSE; + + if (prAdapter->prGlueInfo->u4ReadyFlag == 0) + return FALSE; + + if (pucState) + *pucState = prAdapter->prGlueInfo->rHifInfo.state; + + if (prAdapter->prGlueInfo->rHifInfo.state != USB_STATE_READY) + return FALSE; + + return TRUE; +} + +/*----------------------------------------------------------------------------*/ +/*! +* @brief Check if HIF state is LINK_UP or READY for USB TX/RX +* +* @param prAdapter Pointer to the Adapter structure. +* +* @return (TRUE: ready, FALSE: not ready) +*/ +/*----------------------------------------------------------------------------*/ +bool halIsHifStateLinkup(IN struct ADAPTER *prAdapter) +{ + if (!prAdapter) + return FALSE; + + if (!prAdapter->prGlueInfo) + return FALSE; + + if ((prAdapter->prGlueInfo->rHifInfo.state != USB_STATE_LINK_UP) && + (prAdapter->prGlueInfo->rHifInfo.state != USB_STATE_READY)) + return FALSE; + + return TRUE; +} + +/*----------------------------------------------------------------------------*/ +/*! +* @brief Check if HIF state is during supend process +* +* @param prAdapter Pointer to the Adapter structure. +* +* @return (TRUE: suspend, reject the caller action. FALSE: not suspend) +*/ +/*----------------------------------------------------------------------------*/ +bool halIsHifStateSuspend(IN struct ADAPTER *prAdapter) +{ + enum usb_state state; + + if (!prAdapter) + return FALSE; + + if (!prAdapter->prGlueInfo) + return FALSE; + + state = prAdapter->prGlueInfo->rHifInfo.state; + + if (state == USB_STATE_SUSPEND) + return TRUE; + + return FALSE; +} + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/usb/include/cust_usb_id.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/usb/include/cust_usb_id.h new file mode 100644 index 0000000000000000000000000000000000000000..412b92096c9c03b84645a714cdc4600b08f925f1 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/usb/include/cust_usb_id.h @@ -0,0 +1,116 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/*! \file "cust_usb_id.h" + * \brief Define USB vid/pid table for customers + */ + + +#ifndef _CUST_USB_ID_H +#define _CUST_USB_ID_H +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/*! + * \brief Additional USB vid/pid tables for customers. + * Please add your vid/pid in table below as the example shows. + * + */ +#define CUST_USB_ID_TABLES \ +/* + * { USB_DEVICE_AND_INTERFACE_INFO(0x0E8D, 0x7618, 0xff, 0xff, 0xff), \ + * .driver_info = (kernel_ulong_t)&mt66xx_driver_data_mt7668},\ + * { USB_DEVICE_AND_INTERFACE_INFO(0x0E8D, 0x7658, 0xff, 0xff, 0xff), \ + * .driver_info = (kernel_ulong_t)&mt66xx_driver_data_mt7668},\ +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +#endif /* _CUST_USB_ID_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/usb/include/hif.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/usb/include/hif.h new file mode 100644 index 0000000000000000000000000000000000000000..c3487b6b7e8750d3f6fe81626f0ded054eee4ba0 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/usb/include/hif.h @@ -0,0 +1,461 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/*! \file "hif.h" +* \brief Functions for the driver to register bus and setup the IRQ +* +* Functions for the driver to register bus and setup the IRQ +*/ + + +#ifndef _HIF_H +#define _HIF_H + +#include "nic_cmd_event.h" +#include "wlan_typedef.h" + +enum ENUM_USB_END_POINT { + USB_DATA_BULK_OUT_EP4 = 4, + USB_DATA_BULK_OUT_EP5, + USB_DATA_BULK_OUT_EP6, + USB_DATA_BULK_OUT_EP7, + USB_DATA_BULK_OUT_EP8, + USB_DATA_BULK_OUT_EP9, + + USB_DATA_BULK_IN_EP4 = 4, + USB_DATA_BULK_IN_EP5, + +}; + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +#if defined(_HIF_USB) +#define HIF_NAME "USB" +#else +#error "No HIF defined!" +#endif +#define HIF_CR4_FWDL_SECTION_NUM 2 +#define HIF_IMG_DL_STATUS_PORT_IDX 0 +#define HIF_IST_LOOP_COUNT (4) +#define HIF_IST_TX_THRESHOLD (1) /* Min msdu count to trigger Tx during INT polling state */ + +#define HIF_NUM_OF_QM_RX_PKT_NUM (512) + +#define HIF_TX_BUFF_COUNT_TC0 256 +#define HIF_TX_BUFF_COUNT_TC1 256 +#define HIF_TX_BUFF_COUNT_TC2 256 +#define HIF_TX_BUFF_COUNT_TC3 256 +#define HIF_TX_BUFF_COUNT_TC4 256 +#define HIF_TX_BUFF_COUNT_TC5 256 + +#define HIF_TX_RESOURCE_CTRL 0 /* enable/disable TX resource control */ +#define HIF_TX_RESOURCE_CTRL_PLE 0 /* enable/disable TX resource control PLE */ + + +#if CFG_USB_TX_AGG +#define HIF_TX_PAGE_SIZE_IN_POWER_OF_2 0 +#define HIF_TX_PAGE_SIZE 1 /* in unit of bytes */ +#else +#define HIF_TX_PAGE_SIZE_IN_POWER_OF_2 11 +#define HIF_TX_PAGE_SIZE 2048 /* in unit of bytes */ +#endif + +#define USB_EVENT_TYPE (EVENT_EP_TYPE_UNKONW) + +#define USB_CMD_EP_OUT (USB_DATA_BULK_OUT_EP8) +#define USB_EVENT_EP_IN (0x85) +#define USB_DATA_EP_IN (0x84) + +#define HIF_TX_INIT_CMD_PORT USB_CMD_EP_OUT + +#ifdef CFG_USB_REQ_TX_DATA_FFA_CNT +#define USB_REQ_TX_DATA_FFA_CNT (CFG_USB_REQ_TX_DATA_FFA_CNT) /* platform specific USB_REQ_TX_DATA_FFA_CNT */ +#else +#define USB_REQ_TX_DATA_FFA_CNT (10) +#endif + +#ifdef CFG_USB_REQ_TX_DATA_CNT +#define USB_REQ_TX_DATA_CNT (CFG_USB_REQ_TX_DATA_CNT) /* platform specific USB_REQ_TX_DATA_CNT */ +#else +#if CFG_USB_TX_AGG +#define USB_REQ_TX_DATA_CNT (2) /* must be >= 2 */ +#else +#define USB_REQ_TX_DATA_CNT (CFG_TX_MAX_PKT_NUM) +#endif +#endif + +#define USB_REQ_TX_CMD_CNT (CFG_TX_MAX_CMD_PKT_NUM) +#define USB_REQ_RX_EVENT_CNT (1) +#ifdef CFG_USB_REQ_RX_DATA_CNT +#define USB_REQ_RX_DATA_CNT (CFG_USB_REQ_RX_DATA_CNT) /* platform specific USB_REQ_RX_DATA_CNT */ +#else +#define USB_REQ_RX_DATA_CNT (2) +#endif + +#define USB_RX_AGGREGTAION_LIMIT (32) /* Unit: K-bytes */ +#define USB_RX_AGGREGTAION_TIMEOUT (100) /* Unit: us */ +#define USB_RX_AGGREGTAION_PKT_LIMIT (30) + +#define USB_TX_CMD_BUF_SIZE (1600) +#if CFG_USB_TX_AGG +#define USB_TX_DATA_BUFF_SIZE (32*1024) +#else +#define USB_TX_DATA_BUF_SIZE (NIC_TX_DESC_AND_PADDING_LENGTH + NIC_TX_DESC_HEADER_PADDING_LENGTH + \ + NIC_TX_MAX_SIZE_PER_FRAME + LEN_USB_UDMA_TX_TERMINATOR) +#endif +#define USB_RX_EVENT_BUF_SIZE (CFG_RX_MAX_PKT_SIZE + 3 + LEN_USB_RX_PADDING_CSO + 4) +#define USB_RX_DATA_BUF_SIZE (CFG_RX_MAX_PKT_SIZE + \ + min(USB_RX_AGGREGTAION_LIMIT * 1024, \ + (USB_RX_AGGREGTAION_PKT_LIMIT * \ + (CFG_RX_MAX_PKT_SIZE + 3 + LEN_USB_RX_PADDING_CSO) + 4))) + +#define LEN_USB_UDMA_TX_TERMINATOR (4) /*HW design spec */ +#define LEN_USB_RX_PADDING_CSO (4) /*HW design spec */ + +#define USB_RX_EVENT_RFB_RSV_CNT (0) +#define USB_RX_DATA_RFB_RSV_CNT (4) + +#define DEVICE_VENDOR_REQUEST_IN (0xc0) +#define DEVICE_VENDOR_REQUEST_IN_CONNAC2 (0xdF) +#define DEVICE_VENDOR_REQUEST_OUT (0x40) +#define DEVICE_VENDOR_REQUEST_OUT_CONNAC2 (0x5F) +#define VENDOR_TIMEOUT_MS (1000) +#define BULK_TIMEOUT_MS (1500) +#define INTERRUPT_TIMEOUT_MS (1000) +#define SW_RFB_RECHECK_MS (10) +#define SW_RFB_LOG_LIMIT_MS (5000) + +/* Vendor Request */ +#define VND_REQ_POWER_ON_WIFI (0x4) +#define VND_REQ_REG_READ (0x63) +#define VND_REQ_REG_WRITE (0x66) +#define VND_REQ_EP5_IN_INFO (0x67) +#define VND_REQ_FEATURE_SET (0x91) +#define FEATURE_SET_WVALUE_RESUME (0x5) +#define FEATURE_SET_WVALUE_SUSPEND (0x6) +#define VND_REQ_BUF_SIZE (16) + +#define USB_TX_CMD_QUEUE_MASK (BITS(2, 4)) /* For H2CDMA Tx CMD mapping */ + +#define USB_DBDC1_TC (TC_NUM)/* for DBDC1 */ +#define USB_TC_NUM (TC_NUM + 1)/* for DBDC1 */ +#define USB_TX_EPOUT_NUM (5) + +#define HIF_EXTRA_IO_BUFFER_SIZE (0) + +#define HIF_TX_COALESCING_BUFFER_SIZE (USB_TX_CMD_BUF_SIZE) +#define HIF_RX_COALESCING_BUFFER_SIZE (USB_RX_EVENT_BUF_SIZE) + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/* host interface's private data structure, which is attached to os glue +** layer info structure. + */ + +enum usb_state { + USB_STATE_WIFI_OFF, /* Hif power off wifi */ + USB_STATE_LINK_DOWN, + USB_STATE_PRE_SUSPEND_START, + USB_STATE_PRE_SUSPEND_DONE, + USB_STATE_PRE_SUSPEND_FAIL, + USB_STATE_SUSPEND, + USB_STATE_PRE_RESUME, + USB_STATE_LINK_UP, + USB_STATE_READY +}; + +enum usb_submit_type { + SUBMIT_TYPE_TX_CMD, + SUBMIT_TYPE_TX_DATA, + SUBMIT_TYPE_RX_EVENT, + SUBMIT_TYPE_RX_DATA +}; + +enum EVENT_EP_TYPE { + EVENT_EP_TYPE_UNKONW, + EVENT_EP_TYPE_BULK, + EVENT_EP_TYPE_INTR, + EVENT_EP_TYPE_DATA_EP +}; + +enum ENUM_SUSPEND_VERSION { + SUSPEND_V1 = 1, + SUSPEND_V2 +}; + +struct BUF_CTRL { + uint8_t *pucBuf; + uint32_t u4BufSize; + uint32_t u4WrIdx; + uint32_t u4ReadSize; +}; + +struct GL_HIF_INFO { + struct usb_interface *intf; + struct usb_device *udev; + + struct GLUE_INFO *prGlueInfo; + enum usb_state state; + + spinlock_t rTxDataQLock; + spinlock_t rTxCmdQLock; + spinlock_t rRxEventQLock; + spinlock_t rRxDataQLock; + spinlock_t rStateLock; + + void *prTxCmdReqHead; + void *arTxDataFfaReqHead; + void *arTxDataReqHead[USB_TC_NUM]; + void *prRxEventReqHead; + void *prRxDataReqHead; + struct list_head rTxCmdFreeQ; + spinlock_t rTxCmdFreeQLock; + struct list_head rTxCmdSendingQ; + spinlock_t rTxCmdSendingQLock; + struct list_head rTxDataFfaQ; +#if CFG_USB_TX_AGG + uint32_t u4AggRsvSize[USB_TC_NUM]; + struct list_head rTxDataFreeQ[USB_TC_NUM]; + struct usb_anchor rTxDataAnchor[USB_TC_NUM]; +#else + struct list_head rTxDataFreeQ; + struct usb_anchor rTxDataAnchor; +#endif + /*spinlock_t rTxDataFreeQLock;*/ + struct list_head rRxEventFreeQ; + /*spinlock_t rRxEventFreeQLock;*/ + struct usb_anchor rRxEventAnchor; + struct list_head rRxDataFreeQ; + /*spinlock_t rRxDataFreeQLock;*/ + struct usb_anchor rRxDataAnchor; + struct list_head rRxEventCompleteQ; + /*spinlock_t rRxEventCompleteQLock;*/ + struct list_head rRxDataCompleteQ; + /*spinlock_t rRxDataCompleteQLock;*/ + struct list_head rTxCmdCompleteQ; + struct list_head rTxDataCompleteQ; + + struct BUF_CTRL rTxCmdBufCtrl[USB_REQ_TX_CMD_CNT]; + struct BUF_CTRL rTxDataFfaBufCtrl[USB_REQ_TX_DATA_FFA_CNT]; +#if CFG_USB_TX_AGG + struct BUF_CTRL rTxDataBufCtrl[USB_TC_NUM][USB_REQ_TX_DATA_CNT]; +#else + struct BUF_CTRL rTxDataBufCtrl[USB_REQ_TX_DATA_CNT]; +#endif + struct BUF_CTRL rRxEventBufCtrl[USB_REQ_RX_EVENT_CNT]; + struct BUF_CTRL rRxDataBufCtrl[USB_REQ_RX_DATA_CNT]; + + struct mutex vendor_req_sem; + void *vendor_req_buf; + u_int32_t vendor_req_buf_sz; + u_int8_t fgIntReadClear; + u_int8_t fgMbxReadClear; + u_int8_t fgEventEpDetected; + enum EVENT_EP_TYPE eEventEpType; +}; + +struct USB_REQ { + struct list_head list; + struct urb *prUrb; + struct BUF_CTRL *prBufCtrl; + struct GL_HIF_INFO *prHifInfo; + void *prPriv; + struct QUE rSendingDataMsduInfoList; +}; + +struct BUS_INFO { + const uint32_t u4UdmaWlCfg_0_Addr; + const uint32_t u4UdmaWlCfg_1_Addr; + const uint32_t u4UdmaTxQsel; + const uint32_t u4device_vender_request_in; + const uint32_t u4device_vender_request_out; + const uint32_t u4usb_tx_cmd_queue_mask; + uint32_t u4UdmaWlCfg_0; + uint32_t u4UdmaTxTimeout; /* UDMA Tx time out limit, unit: us */ + uint32_t u4SuspendVer; + u_int8_t (*asicUsbSuspend)( + IN struct ADAPTER *prAdapter, + IN struct GLUE_INFO *prGlueInfo); + u_int8_t (*asicUsbResume)( + IN struct ADAPTER *prAdapter, + IN struct GLUE_INFO *prGlueInfo); + uint8_t (*asicUsbEventEpDetected)(IN struct ADAPTER *prAdapter); + uint16_t (*asicUsbRxByteCount)(IN struct ADAPTER *prAdapter, + IN struct BUS_INFO *prBusInfo, + IN uint8_t *pRXD); + void (*DmaShdlInit)(IN struct ADAPTER *prAdapter); +}; + +/* USB_REQ_T prPriv field for TxData */ +#define FFA_MASK BIT(7) /* Indicate if this UsbReq is from FFA queue. */ +#define TC_MASK BITS(0, 6) /* Indicate which TC this UsbReq belongs to */ + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +#define USB_TRANS_MSDU_TC(_prMsduInfo) \ + ((_prMsduInfo)->ucWmmQueSet ? USB_DBDC1_TC : (_prMsduInfo)->ucTC) + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +uint32_t glRegisterBus(probe_card pfProbe, remove_card pfRemove); + +void glUnregisterBus(remove_card pfRemove); + +void glSetHifInfo(struct GLUE_INFO *prGlueInfo, unsigned long ulCookie); + +void glClearHifInfo(struct GLUE_INFO *prGlueInfo); + +u_int8_t glBusInit(void *pvData); + +void glBusRelease(void *pData); + +int32_t glBusSetIrq(void *pvData, void *pfnIsr, void *pvCookie); + +void glBusFreeIrq(void *pvData, void *pvCookie); + +void glSetPowerState(IN struct GLUE_INFO *prGlueInfo, IN uint32_t ePowerMode); + +void glUdmaTxRxEnable(struct GLUE_INFO *prGlueInfo, u_int8_t enable); + +void glUdmaRxAggEnable(struct GLUE_INFO *prGlueInfo, u_int8_t enable); + +int32_t mtk_usb_vendor_request(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t uEndpointAddress, IN uint8_t RequestType, + IN uint8_t Request, IN uint16_t Value, IN uint16_t Index, + IN void *TransferBuffer, IN uint32_t TransferBufferLength); + +void glUsbEnqueueReq(struct GL_HIF_INFO *prHifInfo, struct list_head *prHead, struct USB_REQ *prUsbReq, + spinlock_t *prLock, u_int8_t fgHead); +struct USB_REQ *glUsbDequeueReq(struct GL_HIF_INFO *prHifInfo, struct list_head *prHead, spinlock_t *prLock); +u_int8_t glUsbBorrowFfaReq(struct GL_HIF_INFO *prHifInfo, uint8_t ucTc); + +void glUsbSetState(IN struct GL_HIF_INFO *prHifInfo, enum usb_state state); + +int glUsbSubmitUrb(IN struct GL_HIF_INFO *prHifInfo, struct urb *urb, + enum usb_submit_type type); + +uint32_t halTxUSBSendCmd(IN struct GLUE_INFO *prGlueInfo, IN uint8_t ucTc, IN struct CMD_INFO *prCmdInfo); +void halTxUSBSendCmdComplete(struct urb *urb); +void halTxUSBProcessCmdComplete(IN struct ADAPTER *prAdapter, struct USB_REQ *prUsbReq); + +uint32_t halTxUSBSendData(IN struct GLUE_INFO *prGlueInfo, IN struct MSDU_INFO *prMsduInfo); +uint32_t halTxUSBKickData(IN struct GLUE_INFO *prGlueInfo); +void halTxUSBSendDataComplete(struct urb *urb); +void halTxUSBProcessMsduDone(IN struct GLUE_INFO *prGlueInfo, struct USB_REQ *prUsbReq); +void halTxUSBProcessDataComplete(IN struct ADAPTER *prAdapter, struct USB_REQ *prUsbReq); + +uint32_t halRxUSBEnqueueRFB( + IN struct ADAPTER *prAdapter, + IN uint8_t *pucBuf, + IN uint32_t u4Length, + IN uint32_t u4MinRfbCnt, + IN struct list_head *prCompleteQ); +uint32_t halRxUSBReceiveEvent(IN struct ADAPTER *prAdapter, IN u_int8_t fgFillUrb); +void halRxUSBReceiveEventComplete(struct urb *urb); +uint32_t halRxUSBReceiveData(IN struct ADAPTER *prAdapter); +void halRxUSBReceiveDataComplete(struct urb *urb); +void halRxUSBProcessEventDataComplete(IN struct ADAPTER *prAdapter, + struct list_head *prCompleteQ, struct list_head *prFreeQ, uint32_t u4MinRfbCnt); + +void halUSBPreSuspendCmd(IN struct ADAPTER *prAdapter); +void halUSBPreResumeCmd(IN struct ADAPTER *prAdapter); +void halUSBPreSuspendDone(IN struct ADAPTER *prAdapter, IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf); +void halUSBPreSuspendTimeout(IN struct ADAPTER *prAdapter, IN struct CMD_INFO *prCmdInfo); + +void glGetDev(void *ctx, struct device **dev); +void glGetHifDev(struct GL_HIF_INFO *prHif, struct device **dev); + +void halGetCompleteStatus(IN struct ADAPTER *prAdapter, OUT uint32_t *pu4IntStatus); + +uint16_t glGetUsbDeviceVendorId(struct usb_device *dev); +uint16_t glGetUsbDeviceProductId(struct usb_device *dev); + +int32_t glGetUsbDeviceManufacturerName(struct usb_device *dev, uint8_t *buffer, uint32_t bufLen); +int32_t glGetUsbDeviceProductName(struct usb_device *dev, uint8_t *buffer, uint32_t bufLen); +int32_t glGetUsbDeviceSerialNumber(struct usb_device *dev, uint8_t *buffer, uint32_t bufLen); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +#endif /* _HIF_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/usb/include/hif_usb.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/usb/include/hif_usb.h new file mode 100644 index 0000000000000000000000000000000000000000..acb7ad32ad802843f770168efdd383ec933a9848 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/usb/include/hif_usb.h @@ -0,0 +1,131 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/*! \file "hif_usb.h" + * \brief + */ + + +#ifndef _HIF_USB_H +#define _HIF_USB_H +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ +#define HIF_USB_DEBUG (0) /* 0:turn off debug msg and assert, 1:turn off debug msg and assert */ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/*! + * \brief A debug print used to print debug messages while compiler flag HIF_SDIO_DEBUG on. + * + */ +#if HIF_USB_DEBUG +#define DPRINTK(fmt, args...) pr_debug("%s: " fmt, __func__, ## args) +#else +#define DPRINTK(fmt, args...) +#endif + +/*! + * \brief ASSERT function definition. + * + */ +#if HIF_USB_DEBUG +#define ASSERT(expr) \ + do { \ + if (!(expr)) { \ + pr_err("assertion failed! %s[%d]: %s\n", \ + __func__, __LINE__, #expr); \ + WARN_ON(!(expr)); \ + } \ + } while (0) +#else +#define ASSERT(expr) do {} while (0) +#endif + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +#endif /* _HIF_USB_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/usb/usb.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/usb/usb.c new file mode 100644 index 0000000000000000000000000000000000000000..7d97542c52602213e416e445c51c82fb0a66d9cd --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/hif/usb/usb.c @@ -0,0 +1,1658 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/****************************************************************************** +*[File] usb.c +*[Version] v1.0 +*[Revision Date] 2010-03-01 +*[Author] +*[Description] +* The program provides USB HIF driver +*[Copyright] +* Copyright (C) 2010 MediaTek Incorporation. All Rights Reserved. +******************************************************************************/ + + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +#include "precomp.h" + +#include +#include + +#include +#ifndef CONFIG_X86 +#include +#endif + +#include "mt66xx_reg.h" +#include "cust_usb_id.h" + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +#define HIF_USB_ERR_TITLE_STR "["CHIP_NAME"] USB Access Error!" +#define HIF_USB_ERR_DESC_STR "**USB Access Error**\n" + +#define HIF_USB_ACCESS_RETRY_LIMIT 1 + +#define MT_MAC_BASE 0x2 + +#define MTK_USB_PORT_MASK 0x0F +#define MTK_USB_BULK_IN_MIN_EP 4 +#define MTK_USB_BULK_IN_MAX_EP 5 +#define MTK_USB_BULK_OUT_MIN_EP 4 +#define MTK_USB_BULK_OUT_MAX_EP 9 + +static const struct usb_device_id mtk_usb_ids[] = { + /* {USB_DEVICE(0x0E8D,0x6632), .driver_info = MT_MAC_BASE}, */ +#ifdef MT6632 + { USB_DEVICE_AND_INTERFACE_INFO(0x0E8D, 0x6632, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&mt66xx_driver_data_mt6632}, + { USB_DEVICE_AND_INTERFACE_INFO(0x0E8D, 0x7666, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&mt66xx_driver_data_mt6632}, +#endif /* MT6632 */ +#ifdef MT7668 + { USB_DEVICE_AND_INTERFACE_INFO(0x0E8D, 0x7668, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&mt66xx_driver_data_mt7668}, +#endif /* MT7668 */ +#ifdef MT7663 + { USB_DEVICE_AND_INTERFACE_INFO(0x0E8D, 0x7663, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&mt66xx_driver_data_mt7663}, +#endif /* MT7663 */ +#ifdef MT7915 + { USB_DEVICE_AND_INTERFACE_INFO(0x0E8D, 0x7915, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&mt66xx_driver_data_mt7915}, +#endif /* MT7915 */ +#ifdef MT7961 + { USB_DEVICE_AND_INTERFACE_INFO(0x0E8D, 0x7961, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&mt66xx_driver_data_mt7961}, +#endif /* MT7961 */ + /* If customer usb id is presented, add to the table. */ + CUST_USB_ID_TABLES + { /* end: all zeroes */ }, +}; + +MODULE_DEVICE_TABLE(usb, mtk_usb_ids); + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ +static probe_card pfWlanProbe; +static remove_card pfWlanRemove; + +static u_int8_t g_fgDriverProbed = FALSE; + +static struct usb_driver mtk_usb_driver = { + .name = "wlan", /* "MTK USB WLAN Driver" */ + .id_table = mtk_usb_ids, + .probe = NULL, + .disconnect = NULL, + .suspend = NULL, + .resume = NULL, + .reset_resume = NULL, + .supports_autosuspend = 0, +}; + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +static int mtk_usb_probe(struct usb_interface *intf, + const struct usb_device_id *id); +static void mtk_usb_disconnect(struct usb_interface *intf); +static int mtk_usb_suspend(struct usb_interface *intf, pm_message_t message); +static int mtk_usb_resume(struct usb_interface *intf); +static int mtk_usb_reset_resume(struct usb_interface *intf); +static int mtk_usb_bulk_in_msg(struct GL_HIF_INFO *prHifInfo, uint32_t len, + uint8_t *buffer, int InEp); +static int mtk_usb_intr_in_msg(struct GL_HIF_INFO *prHifInfo, uint32_t len, + uint8_t *buffer, int InEp); +static int mtk_usb_bulk_out_msg(struct GL_HIF_INFO *prHifInfo, uint32_t len, + uint8_t *buffer, int OutEp); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function is a USB probe function +* +* \param[in] intf USB interface +* \param[in] id USB device id +* +* \return void +*/ +/*----------------------------------------------------------------------------*/ +static int mtk_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) +{ + int ret = 0; + struct usb_device *dev; + + DBGLOG(HAL, EVENT, "mtk_usb_probe()\n"); + + ASSERT(intf); + ASSERT(id); + + dev = interface_to_usbdev(intf); + dev = usb_get_dev(dev); + + /* Prevent un-expected usb operation */ + if (g_fgDriverProbed) { + DBGLOG(HAL, ERROR, "wlan_probe(): Device already probed!!\n"); + return -EBUSY; + } + + DBGLOG(HAL, EVENT, "wlan_probe()\n"); + if (pfWlanProbe((void *) intf, (void *) id->driver_info) != WLAN_STATUS_SUCCESS) { + /* printk(KERN_WARNING DRV_NAME"pfWlanProbe fail!call pfWlanRemove()\n"); */ + pfWlanRemove(); + DBGLOG(HAL, ERROR, "wlan_probe() failed\n"); + ret = -1; + } else { + g_fgDriverProbed = TRUE; + } + + return ret; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function is a USB remove function +* +* \param[in] intf USB interface +* +* \return void +*/ +/*----------------------------------------------------------------------------*/ +static void mtk_usb_disconnect(struct usb_interface *intf) +{ + struct GLUE_INFO *prGlueInfo; + + DBGLOG(HAL, STATE, "mtk_usb_disconnect()\n"); + + ASSERT(intf); + prGlueInfo = (struct GLUE_INFO *)usb_get_intfdata(intf); + + glUsbSetState(&prGlueInfo->rHifInfo, USB_STATE_LINK_DOWN); + + if (g_fgDriverProbed) + pfWlanRemove(); + + usb_set_intfdata(intf, NULL); + usb_put_dev(interface_to_usbdev(intf)); + + g_fgDriverProbed = FALSE; + + DBGLOG(HAL, STATE, "mtk_usb_disconnect() done\n"); +} + +static int mtk_usb_resume(struct usb_interface *intf) +{ + int ret = 0; + struct GLUE_INFO *prGlueInfo = + (struct GLUE_INFO *)usb_get_intfdata(intf); + struct BUS_INFO *prBusInfo = NULL; + + DBGLOG(HAL, STATE, "mtk_usb_resume()\n"); + prBusInfo = prGlueInfo->prAdapter->chip_info->bus_info; + + if (prBusInfo->asicUsbResume) { + /* callback func registered for each chip */ + if (prBusInfo->asicUsbResume(prGlueInfo->prAdapter, prGlueInfo)) + ret = 0; + else + ret = -1; + } else { + /* Do general method if no callback func registered */ + /* NOTE: USB bus may not really do suspend and resume*/ + ret = usb_control_msg(prGlueInfo->rHifInfo.udev, + usb_sndctrlpipe(prGlueInfo->rHifInfo.udev, 0), + VND_REQ_FEATURE_SET, + prBusInfo->u4device_vender_request_out, + FEATURE_SET_WVALUE_RESUME, 0, NULL, 0, + VENDOR_TIMEOUT_MS); + if (ret) + DBGLOG(HAL, ERROR, + "VendorRequest FeatureSetResume ERROR: %x\n", + (unsigned int)ret); + + glUsbSetState(&prGlueInfo->rHifInfo, USB_STATE_PRE_RESUME); + /* To trigger CR4 path */ + wlanSendDummyCmd(prGlueInfo->prAdapter, FALSE); + + glUsbSetState(&prGlueInfo->rHifInfo, USB_STATE_LINK_UP); + halEnableInterrupt(prGlueInfo->prAdapter); + + if (prGlueInfo->prAdapter->rWifiVar.ucWow) { + DBGLOG(HAL, EVENT, "leave WOW flow\n"); + kalWowProcess(prGlueInfo, FALSE); + } + } + + /* Allow upper layers to call the device hard_start_xmit routine. */ + netif_tx_start_all_queues(prGlueInfo->prDevHandler); + + DBGLOG(HAL, STATE, "mtk_usb_resume() done ret=%d!\n", ret); + + /* TODO */ + return ret; +} + +static int mtk_usb_suspend(struct usb_interface *intf, pm_message_t message) +{ + struct GLUE_INFO *prGlueInfo = (struct GLUE_INFO *)usb_get_intfdata(intf); + uint8_t count = 0; + struct BUS_INFO *prBusInfo = NULL; + int ret = 0; + + DBGLOG(HAL, STATE, "mtk_usb_suspend()\n"); + + /* Stop upper layers calling the device hard_start_xmit routine. */ + netif_tx_stop_all_queues(prGlueInfo->prDevHandler); + + /* change to non-READY state to block cfg80211 ops */ + glUsbSetState(&prGlueInfo->rHifInfo, USB_STATE_PRE_SUSPEND_START); + + wlanSuspendPmHandle(prGlueInfo); + + prBusInfo = prGlueInfo->prAdapter->chip_info->bus_info; + if (prBusInfo->asicUsbSuspend) { + if (prBusInfo->asicUsbSuspend(prGlueInfo->prAdapter, prGlueInfo)) + return 0; + else + return -1; + } + + halUSBPreSuspendCmd(prGlueInfo->prAdapter); + + while (prGlueInfo->rHifInfo.state != USB_STATE_PRE_SUSPEND_DONE) { + if (count > 25) { + DBGLOG(HAL, ERROR, "pre_suspend timeout\n"); + ret = -EFAULT; + break; + } + msleep(20); + count++; + } + + glUsbSetState(&prGlueInfo->rHifInfo, USB_STATE_SUSPEND); + halDisableInterrupt(prGlueInfo->prAdapter); + halTxCancelAllSending(prGlueInfo->prAdapter); + + DBGLOG(HAL, STATE, "mtk_usb_suspend() done!\n"); + + if (ret && PMSG_IS_AUTO(message)) + mtk_usb_resume(intf); + + return ret; +} + +static int mtk_usb_reset_resume(struct usb_interface *intf) +{ + DBGLOG(HAL, STATE, "mtk_usb_reset_resume()\n"); + + mtk_usb_resume(intf); + + DBGLOG(HAL, STATE, "mtk_usb_reset_resume done!()\n"); + + /* TODO */ + return 0; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief USB EP0 vendor request +* +* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. +* \param[in] uEndpointAddress +* \param[in] RequestType +* \param[in] Request +* \param[in] Value +* \param[in] Index +* \param[in] TransferBuffer +* \param[in] TransferBufferLength +* +* \retval 0 if success +* non-zero if fail, the return value of usb_control_msg() +*/ +/*----------------------------------------------------------------------------*/ +int32_t mtk_usb_vendor_request(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t uEndpointAddress, IN uint8_t RequestType, + IN uint8_t Request, IN uint16_t Value, IN uint16_t Index, + IN void *TransferBuffer, IN uint32_t TransferBufferLength) +{ + struct GL_HIF_INFO *prHifInfo = &prGlueInfo->rHifInfo; + struct BUS_INFO *prBusInfo = NULL; + void *xfer_buf; + + /* refer to RTUSB_VendorRequest */ + int ret = 0; + prBusInfo = prGlueInfo->prAdapter->chip_info->bus_info; + + /* TODO: semaphore */ + + if (in_interrupt()) { + DBGLOG(REQ, ERROR, "BUG: mtk_usb_vendor_request is called from invalid context\n"); + return -EFAULT; + } + + if (unlikely(TransferBufferLength > prHifInfo->vendor_req_buf_sz)) { + DBGLOG(REQ, ERROR, "len %u exceeds limit %zu\n", + TransferBufferLength, + prHifInfo->vendor_req_buf_sz); + return -E2BIG; + } + + if (unlikely(TransferBuffer && !prHifInfo->vendor_req_buf)) { + DBGLOG(REQ, ERROR, "NULL vendor_req_buf\n"); + return -EFAULT; + } + + /* use heap instead of old stack memory */ + xfer_buf = (TransferBuffer) ? prHifInfo->vendor_req_buf : NULL; + + mutex_lock(&prHifInfo->vendor_req_sem); + + if (RequestType == prBusInfo->u4device_vender_request_out) { + if (xfer_buf) + memcpy(xfer_buf, TransferBuffer, TransferBufferLength); + ret = usb_control_msg(prHifInfo->udev, + usb_sndctrlpipe(prHifInfo->udev, + uEndpointAddress), + Request, RequestType, Value, Index, + xfer_buf, TransferBufferLength, + VENDOR_TIMEOUT_MS); + } else if (RequestType == prBusInfo->u4device_vender_request_in) { + ret = usb_control_msg(prHifInfo->udev, + usb_rcvctrlpipe(prHifInfo->udev, + uEndpointAddress), + Request, RequestType, Value, Index, + xfer_buf, TransferBufferLength, + VENDOR_TIMEOUT_MS); + if (xfer_buf && (ret > 0)) + memcpy(TransferBuffer, xfer_buf, TransferBufferLength); + } + mutex_unlock(&prHifInfo->vendor_req_sem); + + return (ret == TransferBufferLength) ? 0 : ret; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief USB Bulk IN msg +* +* \param[in] prHifInfo Pointer to the struct GL_HIF_INFO structure +* \param[in] len +* \param[in] buffer +* \param[in] InEp +* +* \retval +*/ +/*----------------------------------------------------------------------------*/ +static int mtk_usb_bulk_in_msg(IN struct GL_HIF_INFO *prHifInfo, IN uint32_t len, OUT uint8_t *buffer, int InEp) +{ + int ret = 0; + uint32_t count; + + if (in_interrupt()) { + DBGLOG(REQ, ERROR, "BUG: mtk_usb_bulk_in_msg is called from invalid context\n"); + return FALSE; + } + + mutex_lock(&prHifInfo->vendor_req_sem); + + /* do a blocking bulk read to get data from the device */ + ret = usb_bulk_msg(prHifInfo->udev, + usb_rcvbulkpipe(prHifInfo->udev, InEp), buffer, len, &count, BULK_TIMEOUT_MS); + + mutex_unlock(&prHifInfo->vendor_req_sem); + + if (ret >= 0) { +#if 0 /* maximize buff len for usb in */ + if (count != len) { + DBGLOG(HAL, WARN, "usb_bulk_msg(IN=%d) Warning. Data is not completed. (receive %d/%u)\n", + InEp, count, len); + } +#endif + return count; + } + + DBGLOG(HAL, ERROR, "usb_bulk_msg(IN=%d) Fail. Error code = %d.\n", InEp, ret); + return ret; +} + +static int mtk_usb_intr_in_msg(IN struct GL_HIF_INFO *prHifInfo, IN uint32_t len, OUT uint8_t *buffer, int InEp) +{ + int ret = 0; + uint32_t count; + + if (in_interrupt()) { + DBGLOG(REQ, ERROR, "BUG: mtk_usb_intr_in_msg is called from invalid context\n"); + return FALSE; + } + + mutex_lock(&prHifInfo->vendor_req_sem); + + /* do a blocking interrupt read to get data from the device */ + ret = usb_interrupt_msg(prHifInfo->udev, + usb_rcvintpipe(prHifInfo->udev, InEp), buffer, len, &count, INTERRUPT_TIMEOUT_MS); + + mutex_unlock(&prHifInfo->vendor_req_sem); + + if (ret >= 0) { +#if 0 /* maximize buff len for usb in */ + if (count != len) { + DBGLOG(HAL, WARN, "usb_interrupt_msg(IN=%d) Warning. Data is not completed. (receive %d/%u)\n", + InEp, count, len); + } +#endif + return count; + } + + DBGLOG(HAL, ERROR, "usb_interrupt_msg(IN=%d) Fail. Error code = %d.\n", InEp, ret); + return ret; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief USB Bulk OUT msg +* +* \param[in] prHifInfo Pointer to the struct GL_HIF_INFO structure +* \param[in] len +* \param[in] buffer +* \param[in] OutEp +* +* \retval +*/ +/*----------------------------------------------------------------------------*/ +static int mtk_usb_bulk_out_msg(IN struct GL_HIF_INFO *prHifInfo, IN uint32_t len, IN uint8_t *buffer, int OutEp) +{ + int ret = 0; + uint32_t count; + + if (in_interrupt()) { + DBGLOG(REQ, ERROR, "BUG: mtk_usb_bulk_out_msg is called from invalid context\n"); + return FALSE; + } + + mutex_lock(&prHifInfo->vendor_req_sem); + + /* do a blocking bulk read to get data from the device */ + ret = usb_bulk_msg(prHifInfo->udev, + usb_sndbulkpipe(prHifInfo->udev, OutEp), buffer, len, &count, BULK_TIMEOUT_MS); + + mutex_unlock(&prHifInfo->vendor_req_sem); + + if (ret >= 0) { +#if 0 + if (count != len) { + DBGLOG(HAL, ERROR, "usb_bulk_msg(OUT=%d) Warning. Data is not completed. (send %d/%u)\n", OutEp, + count, len); + } +#endif + return count; + } + + DBGLOG(HAL, ERROR, "usb_bulk_msg(OUT=%d) Fail. Error code = %d.\n", OutEp, ret); + return ret; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function will register USB bus to the os +* +* \param[in] pfProbe Function pointer to detect card +* \param[in] pfRemove Function pointer to remove card +* +* \return The result of registering USB bus +*/ +/*----------------------------------------------------------------------------*/ +uint32_t glRegisterBus(probe_card pfProbe, remove_card pfRemove) +{ + int ret = 0; + + ASSERT(pfProbe); + ASSERT(pfRemove); + + pfWlanProbe = pfProbe; + pfWlanRemove = pfRemove; + + mtk_usb_driver.probe = mtk_usb_probe; + mtk_usb_driver.disconnect = mtk_usb_disconnect; + mtk_usb_driver.suspend = mtk_usb_suspend; + mtk_usb_driver.resume = mtk_usb_resume; + mtk_usb_driver.reset_resume = mtk_usb_reset_resume; + mtk_usb_driver.supports_autosuspend = 1; + + ret = (usb_register(&mtk_usb_driver) == 0) ? WLAN_STATUS_SUCCESS : WLAN_STATUS_FAILURE; + + return ret; +} /* end of glRegisterBus() */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function will unregister USB bus to the os +* +* \param[in] pfRemove Function pointer to remove card +* +* \return (none) +*/ +/*----------------------------------------------------------------------------*/ +void glUnregisterBus(remove_card pfRemove) +{ + if (g_fgDriverProbed) { + pfRemove(); + g_fgDriverProbed = FALSE; + } + usb_deregister(&mtk_usb_driver); +} /* end of glUnregisterBus() */ + +void glUdmaTxRxEnable(struct GLUE_INFO *prGlueInfo, u_int8_t enable) +{ + uint32_t u4Value = 0; + struct BUS_INFO *prBusInfo; + + prBusInfo = prGlueInfo->prAdapter->chip_info->bus_info; + kalDevRegRead(prGlueInfo, prBusInfo->u4UdmaWlCfg_0_Addr, &u4Value); + + /* enable UDMA TX & RX */ + if (enable) + u4Value |= prBusInfo->u4UdmaWlCfg_0; + else + u4Value &= ~prBusInfo->u4UdmaWlCfg_0; + + kalDevRegWrite(prGlueInfo, prBusInfo->u4UdmaWlCfg_0_Addr, u4Value); +} + +void glUdmaRxAggEnable(struct GLUE_INFO *prGlueInfo, u_int8_t enable) +{ + uint32_t u4Value = 0; + struct BUS_INFO *prBusInfo; + + prBusInfo = prGlueInfo->prAdapter->chip_info->bus_info; + if (enable) { + kalDevRegRead(prGlueInfo, prBusInfo->u4UdmaWlCfg_0_Addr, &u4Value); + /* enable UDMA TX & RX */ + u4Value &= ~(UDMA_WLCFG_0_RX_AGG_EN_MASK | + UDMA_WLCFG_0_RX_AGG_LMT_MASK | + UDMA_WLCFG_0_RX_AGG_TO_MASK); + u4Value |= UDMA_WLCFG_0_RX_AGG_EN(1) | + UDMA_WLCFG_0_RX_AGG_LMT(USB_RX_AGGREGTAION_LIMIT) | + UDMA_WLCFG_0_RX_AGG_TO(USB_RX_AGGREGTAION_TIMEOUT); + kalDevRegWrite(prGlueInfo, prBusInfo->u4UdmaWlCfg_0_Addr, u4Value); + + kalDevRegRead(prGlueInfo, prBusInfo->u4UdmaWlCfg_1_Addr, &u4Value); + u4Value &= ~UDMA_WLCFG_1_RX_AGG_PKT_LMT_MASK; + u4Value |= UDMA_WLCFG_1_RX_AGG_PKT_LMT(USB_RX_AGGREGTAION_PKT_LIMIT); + kalDevRegWrite(prGlueInfo, prBusInfo->u4UdmaWlCfg_1_Addr, u4Value); + } else { + kalDevRegRead(prGlueInfo, prBusInfo->u4UdmaWlCfg_0_Addr, &u4Value); + u4Value &= ~UDMA_WLCFG_0_RX_AGG_EN(1); + kalDevRegWrite(prGlueInfo, prBusInfo->u4UdmaWlCfg_0_Addr, u4Value); + } +} + +void *glUsbInitQ(struct GL_HIF_INFO *prHifInfo, struct list_head *prHead, uint32_t u4Cnt) +{ + uint32_t i; + struct USB_REQ *prUsbReqs, *prUsbReq; + + INIT_LIST_HEAD(prHead); + + prUsbReqs = kcalloc(u4Cnt, sizeof(struct USB_REQ), GFP_ATOMIC); + prUsbReq = prUsbReqs; + + for (i = 0; i < u4Cnt; ++i) { + prUsbReq->prHifInfo = prHifInfo; + prUsbReq->prUrb = usb_alloc_urb(0, GFP_ATOMIC); + + if (prUsbReq->prUrb == NULL) + DBGLOG(HAL, ERROR, "usb_alloc_urb() reports error\n"); + + prUsbReq->prBufCtrl = NULL; + + INIT_LIST_HEAD(&prUsbReq->list); + list_add_tail(&prUsbReq->list, prHead); + + prUsbReq++; + } + + return (void *) prUsbReqs; +} + +void glUsbUnInitQ(struct list_head *prHead) +{ + struct USB_REQ *prUsbReq, *prUsbReqNext; + + list_for_each_entry_safe(prUsbReq, prUsbReqNext, prHead, list) { + usb_free_urb(prUsbReq->prUrb); + list_del_init(&prUsbReq->list); + } +} + +void glUsbEnqueueReq(struct GL_HIF_INFO *prHifInfo, struct list_head *prHead, struct USB_REQ *prUsbReq, spinlock_t *prLock, + u_int8_t fgHead) +{ + unsigned long flags; + + spin_lock_irqsave(prLock, flags); + if (fgHead) + list_add(&prUsbReq->list, prHead); + else + list_add_tail(&prUsbReq->list, prHead); + spin_unlock_irqrestore(prLock, flags); +} + +struct USB_REQ *glUsbDequeueReq(struct GL_HIF_INFO *prHifInfo, struct list_head *prHead, spinlock_t *prLock) +{ + struct USB_REQ *prUsbReq; + unsigned long flags; + + spin_lock_irqsave(prLock, flags); + if (list_empty(prHead)) { + spin_unlock_irqrestore(prLock, flags); + return NULL; + } + prUsbReq = list_entry(prHead->next, struct USB_REQ, list); + list_del_init(prHead->next); + spin_unlock_irqrestore(prLock, flags); + + return prUsbReq; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function borrow UsbReq from Tx data FFA queue to the spcified TC Tx data free queue +* +* \param[in] prHifInfo Pointer to the struct GL_HIF_INFO structure +* \param[in] ucTc Specify TC index +* +* \retval TRUE operation success +* \retval FALSE operation fail +*/ +/*----------------------------------------------------------------------------*/ +u_int8_t glUsbBorrowFfaReq(struct GL_HIF_INFO *prHifInfo, uint8_t ucTc) +{ + struct USB_REQ *prUsbReq; + + if (list_empty(&prHifInfo->rTxDataFfaQ)) + return FALSE; + prUsbReq = list_entry(prHifInfo->rTxDataFfaQ.next, struct USB_REQ, list); + list_del_init(prHifInfo->rTxDataFfaQ.next); + + *((uint8_t *)&prUsbReq->prPriv) = FFA_MASK | ucTc; + list_add_tail(&prUsbReq->list, &prHifInfo->rTxDataFreeQ[ucTc]); + + return TRUE; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function set USB state +* +* \param[in] prHifInfo Pointer to the struct GL_HIF_INFO structure +* \param[in] state Specify TC index +* +* \retval TRUE operation success +* \retval FALSE operation fail +*/ +/*----------------------------------------------------------------------------*/ +void glUsbSetState(struct GL_HIF_INFO *prHifInfo, enum usb_state state) +{ + unsigned long flags; + + spin_lock_irqsave(&prHifInfo->rStateLock, flags); + prHifInfo->state = state; + spin_unlock_irqrestore(&prHifInfo->rStateLock, flags); +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function is a wrapper of submit urb to ensure driver can transmit +* WiFi packet when WiFi path of device is allowed. +* +* \param[in] prHifInfo Pointer to the struct GL_HIF_INFO structure +* \param[in] type Specify submit type +* +* \retval 0 Successful submissions. +* \retval negative Error number. +*/ +/*----------------------------------------------------------------------------*/ +int glUsbSubmitUrb(struct GL_HIF_INFO *prHifInfo, struct urb *urb, + enum usb_submit_type type) +{ + unsigned long flags; + uint32_t ret = 0; + + if (type == SUBMIT_TYPE_RX_EVENT || type == SUBMIT_TYPE_RX_DATA) + return usb_submit_urb(urb, GFP_ATOMIC); + + spin_lock_irqsave(&prHifInfo->rStateLock, flags); + if (type == SUBMIT_TYPE_TX_CMD) { + if (!(prHifInfo->state == USB_STATE_LINK_UP || + prHifInfo->state == USB_STATE_PRE_RESUME || + prHifInfo->state == USB_STATE_PRE_SUSPEND_START || + prHifInfo->state == USB_STATE_READY)) { + spin_unlock_irqrestore(&prHifInfo->rStateLock, flags); + DBGLOG(HAL, INFO, + "not allowed to transmit CMD packet. (%d)\n", + prHifInfo->state); + return -ESHUTDOWN; + } + } else if (type == SUBMIT_TYPE_TX_DATA) { + if (prHifInfo->state != USB_STATE_LINK_UP || + prHifInfo->state == USB_STATE_READY) { + spin_unlock_irqrestore(&prHifInfo->rStateLock, flags); + DBGLOG(HAL, INFO, + "not allowed to transmit DATA packet. (%d)\n", + prHifInfo->state); + return -ESHUTDOWN; + } + } + + if (nicSerIsTxStop(prHifInfo->prGlueInfo->prAdapter)) { + DBGLOG(HAL, ERROR, "[SER] BYPASS USB send packet\n"); + spin_unlock_irqrestore(&prHifInfo->rStateLock, flags); + return -EBUSY; + } + + ret = usb_submit_urb(urb, GFP_ATOMIC); + spin_unlock_irqrestore(&prHifInfo->rStateLock, flags); + + return ret; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function stores hif related info, which is initialized before. +* +* \param[in] prGlueInfo Pointer to glue info structure +* \param[in] u4Cookie Pointer to uint32_t memory base variable for _HIF_HPI +* +* \return (none) +*/ +/*----------------------------------------------------------------------------*/ +void glSetHifInfo(struct GLUE_INFO *prGlueInfo, unsigned long ulCookie) +{ + struct usb_host_interface *alts; + struct usb_host_endpoint *ep; + struct usb_endpoint_descriptor *ep_desc; + struct GL_HIF_INFO *prHifInfo = &prGlueInfo->rHifInfo; + struct USB_REQ *prUsbReq, *prUsbReqNext; + uint32_t i; +#if CFG_USB_TX_AGG + uint8_t ucTc; +#endif + + prHifInfo->eEventEpType = USB_EVENT_TYPE; + prHifInfo->fgEventEpDetected = FALSE; + + prHifInfo->intf = (struct usb_interface *)ulCookie; + prHifInfo->udev = interface_to_usbdev(prHifInfo->intf); + + alts = prHifInfo->intf->cur_altsetting; + DBGLOG(HAL, STATE, "USB Device speed: %x [%u]\n", + prHifInfo->udev->speed, alts->endpoint[0].desc.wMaxPacketSize); + + if (prHifInfo->eEventEpType == EVENT_EP_TYPE_UNKONW) { + for (i = 0; i < alts->desc.bNumEndpoints; ++i) { + ep = &alts->endpoint[i]; + if (ep->desc.bEndpointAddress == USB_EVENT_EP_IN) { + ep_desc = &alts->endpoint[i].desc; + switch (ep_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { + case USB_ENDPOINT_XFER_INT: + prHifInfo->eEventEpType = EVENT_EP_TYPE_INTR; + break; + case USB_ENDPOINT_XFER_BULK: + default: + prHifInfo->eEventEpType = EVENT_EP_TYPE_BULK; + break; + } + } + } + } + ASSERT(prHifInfo->eEventEpType != EVENT_EP_TYPE_UNKONW); + DBGLOG(HAL, INFO, "Event EP Type: %x\n", prHifInfo->eEventEpType); + + prHifInfo->prGlueInfo = prGlueInfo; + usb_set_intfdata(prHifInfo->intf, prGlueInfo); + + SET_NETDEV_DEV(prGlueInfo->prDevHandler, &prHifInfo->udev->dev); + + spin_lock_init(&prHifInfo->rTxCmdQLock); + spin_lock_init(&prHifInfo->rTxDataQLock); + spin_lock_init(&prHifInfo->rRxEventQLock); + spin_lock_init(&prHifInfo->rRxDataQLock); + spin_lock_init(&prHifInfo->rStateLock); + + mutex_init(&prHifInfo->vendor_req_sem); + prHifInfo->vendor_req_buf = kzalloc(VND_REQ_BUF_SIZE, GFP_KERNEL); + if (!prHifInfo->vendor_req_buf) { + DBGLOG(HAL, ERROR, "kzalloc vendor_req_buf %zu error\n", + VND_REQ_BUF_SIZE); + goto error; + } + prHifInfo->vendor_req_buf_sz = VND_REQ_BUF_SIZE; + +#if CFG_USB_TX_AGG + for (ucTc = 0; ucTc < USB_TC_NUM; ++ucTc) { + prHifInfo->u4AggRsvSize[ucTc] = 0; + init_usb_anchor(&prHifInfo->rTxDataAnchor[ucTc]); + } +#else + init_usb_anchor(&prHifInfo->rTxDataAnchor); +#endif + init_usb_anchor(&prHifInfo->rRxDataAnchor); + init_usb_anchor(&prHifInfo->rRxEventAnchor); + + /* TX CMD */ + prHifInfo->prTxCmdReqHead = glUsbInitQ(prHifInfo, &prHifInfo->rTxCmdFreeQ, USB_REQ_TX_CMD_CNT); + prUsbReq = list_entry(prHifInfo->rTxCmdFreeQ.next, struct USB_REQ, list); + i = 0; + list_for_each_entry_safe(prUsbReq, prUsbReqNext, &prHifInfo->rTxCmdFreeQ, list) { + prUsbReq->prBufCtrl = &prHifInfo->rTxCmdBufCtrl[i]; +#if CFG_USB_CONSISTENT_DMA + prUsbReq->prBufCtrl->pucBuf = usb_alloc_coherent(prHifInfo->udev, USB_TX_CMD_BUF_SIZE, GFP_ATOMIC, + &prUsbReq->prUrb->transfer_dma); +#else + prUsbReq->prBufCtrl->pucBuf = kmalloc(USB_TX_CMD_BUF_SIZE, GFP_ATOMIC); +#endif + if (prUsbReq->prBufCtrl->pucBuf == NULL) { + DBGLOG(HAL, ERROR, "kmalloc() reports error\n"); + goto error; + } + prUsbReq->prBufCtrl->u4BufSize = USB_TX_CMD_BUF_SIZE; + ++i; + } + + glUsbInitQ(prHifInfo, &prHifInfo->rTxCmdSendingQ, 0); + + /* TX Data FFA */ + prHifInfo->arTxDataFfaReqHead = glUsbInitQ(prHifInfo, + &prHifInfo->rTxDataFfaQ, USB_REQ_TX_DATA_FFA_CNT); + i = 0; + list_for_each_entry_safe(prUsbReq, prUsbReqNext, &prHifInfo->rTxDataFfaQ, list) { + QUEUE_INITIALIZE(&prUsbReq->rSendingDataMsduInfoList); + *((uint8_t *)&prUsbReq->prPriv) = FFA_MASK; + prUsbReq->prBufCtrl = &prHifInfo->rTxDataFfaBufCtrl[i]; +#if CFG_USB_CONSISTENT_DMA + prUsbReq->prBufCtrl->pucBuf = + usb_alloc_coherent(prHifInfo->udev, USB_TX_DATA_BUFF_SIZE, GFP_ATOMIC, + &prUsbReq->prUrb->transfer_dma); +#else + prUsbReq->prBufCtrl->pucBuf = kmalloc(USB_TX_DATA_BUFF_SIZE, GFP_ATOMIC); +#endif + if (prUsbReq->prBufCtrl->pucBuf == NULL) { + DBGLOG(HAL, ERROR, "kmalloc() reports error\n"); + goto error; + } + prUsbReq->prBufCtrl->u4BufSize = USB_TX_DATA_BUFF_SIZE; + prUsbReq->prBufCtrl->u4WrIdx = 0; + ++i; + } + + /* TX Data */ +#if CFG_USB_TX_AGG + for (ucTc = 0; ucTc < USB_TC_NUM; ++ucTc) { + /* Only for TC0 ~ TC3 and DBDC1_TC */ + if (ucTc >= TC4_INDEX && ucTc < USB_DBDC1_TC) + continue; + prHifInfo->arTxDataReqHead[ucTc] = glUsbInitQ(prHifInfo, + &prHifInfo->rTxDataFreeQ[ucTc], USB_REQ_TX_DATA_CNT); + i = 0; + list_for_each_entry_safe(prUsbReq, prUsbReqNext, &prHifInfo->rTxDataFreeQ[ucTc], list) { + QUEUE_INITIALIZE(&prUsbReq->rSendingDataMsduInfoList); + /* TODO: every endpoint should has an unique and only TC */ + *((uint8_t *)&prUsbReq->prPriv) = ucTc; + prUsbReq->prBufCtrl = &prHifInfo->rTxDataBufCtrl[ucTc][i]; +#if CFG_USB_CONSISTENT_DMA + prUsbReq->prBufCtrl->pucBuf = + usb_alloc_coherent(prHifInfo->udev, USB_TX_DATA_BUFF_SIZE, GFP_ATOMIC, + &prUsbReq->prUrb->transfer_dma); +#else + prUsbReq->prBufCtrl->pucBuf = kmalloc(USB_TX_DATA_BUFF_SIZE, GFP_ATOMIC); +#endif + if (prUsbReq->prBufCtrl->pucBuf == NULL) { + DBGLOG(HAL, ERROR, "kmalloc() reports error\n"); + goto error; + } + prUsbReq->prBufCtrl->u4BufSize = USB_TX_DATA_BUFF_SIZE; + prUsbReq->prBufCtrl->u4WrIdx = 0; + ++i; + } + + DBGLOG(INIT, INFO, "USB Tx URB INIT Tc[%u] cnt[%u] len[%u]\n", ucTc, i, + prHifInfo->rTxDataBufCtrl[ucTc][0].u4BufSize); + } +#else + glUsbInitQ(prHifInfo, &prHifInfo->rTxDataFreeQ, USB_REQ_TX_DATA_CNT); + prUsbReq = list_entry(prHifInfo->rTxDataFreeQ.next, struct USB_REQ, list); + i = 0; + list_for_each_entry_safe(prUsbReq, prUsbReqNext, &prHifInfo->rTxDataFreeQ, list) { + QUEUE_INITIALIZE(&prUsbReq->rSendingDataMsduInfoList); + prUsbReq->prBufCtrl = &prHifInfo->rTxDataBufCtrl[i]; +#if CFG_USB_CONSISTENT_DMA + prUsbReq->prBufCtrl->pucBuf = + usb_alloc_coherent(prHifInfo->udev, USB_TX_DATA_BUF_SIZE, GFP_ATOMIC, + &prUsbReq->prUrb->transfer_dma); +#else + prUsbReq->prBufCtrl->pucBuf = kmalloc(USB_TX_DATA_BUF_SIZE, GFP_ATOMIC); +#endif + if (prUsbReq->prBufCtrl->pucBuf == NULL) { + DBGLOG(HAL, ERROR, "kmalloc() reports error\n"); + goto error; + } + prUsbReq->prBufCtrl->u4BufSize = USB_TX_DATA_BUF_SIZE; + ++i; + } +#endif + + glUsbInitQ(prHifInfo, &prHifInfo->rTxCmdCompleteQ, 0); + glUsbInitQ(prHifInfo, &prHifInfo->rTxDataCompleteQ, 0); + + /* RX EVENT */ + prHifInfo->prRxEventReqHead = glUsbInitQ(prHifInfo, &prHifInfo->rRxEventFreeQ, USB_REQ_RX_EVENT_CNT); + i = 0; + list_for_each_entry_safe(prUsbReq, prUsbReqNext, &prHifInfo->rRxEventFreeQ, list) { + prUsbReq->prBufCtrl = &prHifInfo->rRxEventBufCtrl[i]; + prUsbReq->prBufCtrl->pucBuf = kmalloc(USB_RX_EVENT_BUF_SIZE, GFP_ATOMIC); + if (prUsbReq->prBufCtrl->pucBuf == NULL) { + DBGLOG(HAL, ERROR, "kmalloc() reports error\n"); + goto error; + } + prUsbReq->prBufCtrl->u4BufSize = USB_RX_EVENT_BUF_SIZE; + prUsbReq->prBufCtrl->u4ReadSize = 0; + ++i; + } + + /* RX Data */ + prHifInfo->prRxDataReqHead = glUsbInitQ(prHifInfo, &prHifInfo->rRxDataFreeQ, USB_REQ_RX_DATA_CNT); + i = 0; + list_for_each_entry_safe(prUsbReq, prUsbReqNext, &prHifInfo->rRxDataFreeQ, list) { + prUsbReq->prBufCtrl = &prHifInfo->rRxDataBufCtrl[i]; + prUsbReq->prBufCtrl->pucBuf = kmalloc(USB_RX_DATA_BUF_SIZE, GFP_ATOMIC); + if (prUsbReq->prBufCtrl->pucBuf == NULL) { + DBGLOG(HAL, ERROR, "kmalloc() reports error\n"); + goto error; + } + prUsbReq->prBufCtrl->u4BufSize = USB_RX_DATA_BUF_SIZE; + prUsbReq->prBufCtrl->u4ReadSize = 0; + ++i; + } + + glUsbInitQ(prHifInfo, &prHifInfo->rRxEventCompleteQ, 0); + glUsbInitQ(prHifInfo, &prHifInfo->rRxDataCompleteQ, 0); + + glUsbSetState(prHifInfo, USB_STATE_LINK_UP); + prGlueInfo->u4InfType = MT_DEV_INF_USB; + + return; + +error: + /* TODO */ + ; +} /* end of glSetHifInfo() */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function clears hif related info. +* +* \param[in] prGlueInfo Pointer to glue info structure +* +* \return (none) +*/ +/*----------------------------------------------------------------------------*/ +void glClearHifInfo(struct GLUE_INFO *prGlueInfo) +{ + /* struct GL_HIF_INFO *prHifInfo = NULL; */ + /* ASSERT(prGlueInfo); */ + /* prHifInfo = &prGlueInfo->rHifInfo; */ +#if CFG_USB_TX_AGG + uint8_t ucTc; +#endif + struct USB_REQ *prUsbReq, *prUsbReqNext; + struct GL_HIF_INFO *prHifInfo = &prGlueInfo->rHifInfo; + +#if CFG_USB_TX_AGG + for (ucTc = 0; ucTc < USB_TC_NUM; ++ucTc) { + if (ucTc >= TC4_INDEX && ucTc < USB_DBDC1_TC) + continue; + list_for_each_entry_safe(prUsbReq, prUsbReqNext, &prHifInfo->rTxDataFreeQ[ucTc], list) { +#if CFG_USB_CONSISTENT_DMA + usb_free_coherent(prHifInfo->udev, USB_TX_DATA_BUFF_SIZE, + prUsbReq->prBufCtrl->pucBuf, prUsbReq->prUrb->transfer_dma); +#else + kfree(prUsbReq->prBufCtrl->pucBuf); +#endif + usb_free_urb(prUsbReq->prUrb); + } + } +#else + list_for_each_entry_safe(prUsbReq, prUsbReqNext, &prHifInfo->rTxDataFreeQ, list) { +#if CFG_USB_CONSISTENT_DMA + usb_free_coherent(prHifInfo->udev, USB_TX_DATA_BUFF_SIZE, + prUsbReq->prBufCtrl->pucBuf, prUsbReq->prUrb->transfer_dma); +#else + kfree(prUsbReq->prBufCtrl->pucBuf); +#endif + usb_free_urb(prUsbReq->prUrb); + } +#endif + + list_for_each_entry_safe(prUsbReq, prUsbReqNext, &prHifInfo->rTxDataFfaQ, list) { +#if CFG_USB_CONSISTENT_DMA + usb_free_coherent(prHifInfo->udev, USB_TX_DATA_BUFF_SIZE, + prUsbReq->prBufCtrl->pucBuf, prUsbReq->prUrb->transfer_dma); +#else + kfree(prUsbReq->prBufCtrl->pucBuf); +#endif + usb_free_urb(prUsbReq->prUrb); + } + + list_for_each_entry_safe(prUsbReq, prUsbReqNext, &prHifInfo->rTxCmdFreeQ, list) { +#if CFG_USB_CONSISTENT_DMA + usb_free_coherent(prHifInfo->udev, USB_TX_CMD_BUF_SIZE, + prUsbReq->prBufCtrl->pucBuf, prUsbReq->prUrb->transfer_dma); +#else + kfree(prUsbReq->prBufCtrl->pucBuf); +#endif + usb_free_urb(prUsbReq->prUrb); + } + + list_for_each_entry_safe(prUsbReq, prUsbReqNext, &prHifInfo->rTxCmdCompleteQ, list) { +#if CFG_USB_CONSISTENT_DMA + usb_free_coherent(prHifInfo->udev, USB_TX_CMD_BUF_SIZE, + prUsbReq->prBufCtrl->pucBuf, prUsbReq->prUrb->transfer_dma); +#else + kfree(prUsbReq->prBufCtrl->pucBuf); +#endif + usb_free_urb(prUsbReq->prUrb); + } + + list_for_each_entry_safe(prUsbReq, prUsbReqNext, &prHifInfo->rTxDataCompleteQ, list) { +#if CFG_USB_CONSISTENT_DMA + usb_free_coherent(prHifInfo->udev, USB_TX_CMD_BUF_SIZE, + prUsbReq->prBufCtrl->pucBuf, prUsbReq->prUrb->transfer_dma); +#else + kfree(prUsbReq->prBufCtrl->pucBuf); +#endif + usb_free_urb(prUsbReq->prUrb); + } + + list_for_each_entry_safe(prUsbReq, prUsbReqNext, &prHifInfo->rRxDataFreeQ, list) { + kfree(prUsbReq->prBufCtrl->pucBuf); + usb_free_urb(prUsbReq->prUrb); + } + + list_for_each_entry_safe(prUsbReq, prUsbReqNext, &prHifInfo->rRxEventFreeQ, list) { + kfree(prUsbReq->prBufCtrl->pucBuf); + usb_free_urb(prUsbReq->prUrb); + } + + list_for_each_entry_safe(prUsbReq, prUsbReqNext, &prHifInfo->rRxDataCompleteQ, list) { + kfree(prUsbReq->prBufCtrl->pucBuf); + usb_free_urb(prUsbReq->prUrb); + } + + list_for_each_entry_safe(prUsbReq, prUsbReqNext, &prHifInfo->rRxEventCompleteQ, list) { + kfree(prUsbReq->prBufCtrl->pucBuf); + usb_free_urb(prUsbReq->prUrb); + } + + kfree(prHifInfo->prTxCmdReqHead); + kfree(prHifInfo->arTxDataFfaReqHead); + for (ucTc = 0; ucTc < USB_TC_NUM; ++ucTc) + kfree(prHifInfo->arTxDataReqHead[ucTc]); + kfree(prHifInfo->prRxEventReqHead); + kfree(prHifInfo->prRxDataReqHead); + + mutex_destroy(&prHifInfo->vendor_req_sem); + kfree(prHifInfo->vendor_req_buf); + prHifInfo->vendor_req_buf = NULL; + prHifInfo->vendor_req_buf_sz = 0; +} /* end of glClearHifInfo() */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Initialize bus operation and hif related information, request resources. +* +* \param[out] pvData A pointer to HIF-specific data type buffer. +* For eHPI, pvData is a pointer to uint32_t type and +* stores a mapped base address. +* +* \return (none) +*/ +/*----------------------------------------------------------------------------*/ +u_int8_t glBusInit(void *pvData) +{ + return TRUE; +} /* end of glBusInit() */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Stop bus operation and release resources. +* +* \param[in] pvData A pointer to struct net_device. +* +* \return (none) +*/ +/*----------------------------------------------------------------------------*/ +void glBusRelease(void *pvData) +{ +} /* end of glBusRelease() */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Setup bus interrupt operation and interrupt handler for os. +* +* \param[in] pvData A pointer to struct net_device. +* \param[in] pfnIsr A pointer to interrupt handler function. +* \param[in] pvCookie Private data for pfnIsr function. +* +* \retval WLAN_STATUS_SUCCESS if success +* NEGATIVE_VALUE if fail +*/ +/*----------------------------------------------------------------------------*/ +int32_t glBusSetIrq(void *pvData, void *pfnIsr, void *pvCookie) +{ + int ret = 0; + + struct net_device *prNetDevice = NULL; + struct GLUE_INFO *prGlueInfo = NULL; + struct GL_HIF_INFO *prHifInfo = NULL; + + ASSERT(pvData); + if (!pvData) + return -1; + + prNetDevice = (struct net_device *)pvData; + prGlueInfo = (struct GLUE_INFO *) pvCookie; + ASSERT(prGlueInfo); + if (!prGlueInfo) + return -1; + + prHifInfo = &prGlueInfo->rHifInfo; + + return ret; +} /* end of glBusSetIrq() */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Stop bus interrupt operation and disable interrupt handling for os. +* +* \param[in] pvData A pointer to struct net_device. +* \param[in] pvCookie Private data for pfnIsr function. +* +* \return (none) +*/ +/*----------------------------------------------------------------------------*/ +void glBusFreeIrq(void *pvData, void *pvCookie) +{ + struct net_device *prNetDevice = NULL; + struct GLUE_INFO *prGlueInfo = NULL; + struct GL_HIF_INFO *prHifInfo = NULL; + + ASSERT(pvData); + if (!pvData) { + /* printk(KERN_INFO DRV_NAME"%s null pvData\n", __FUNCTION__); */ + return; + } + prNetDevice = (struct net_device *)pvData; + prGlueInfo = (struct GLUE_INFO *) pvCookie; + ASSERT(prGlueInfo); + if (!prGlueInfo) { + /* printk(KERN_INFO DRV_NAME"%s no glue info\n", __FUNCTION__); */ + return; + } + + prHifInfo = &prGlueInfo->rHifInfo; +} /* end of glBusreeIrq() */ + +u_int8_t glIsReadClearReg(uint32_t u4Address) +{ + switch (u4Address) { + case MCR_WHISR: + case MCR_WASR: + case MCR_D2HRM0R: + case MCR_D2HRM1R: + case MCR_WTQCR0: + case MCR_WTQCR1: + case MCR_WTQCR2: + case MCR_WTQCR3: + case MCR_WTQCR4: + case MCR_WTQCR5: + case MCR_WTQCR6: + case MCR_WTQCR7: + return TRUE; + + default: + return FALSE; + } +} + +uint16_t glGetUsbDeviceVendorId(struct usb_device *dev) +{ + return dev->descriptor.idVendor; +} /* end of glGetUsbDeviceVendorId() */ + +uint16_t glGetUsbDeviceProductId(struct usb_device *dev) +{ + return dev->descriptor.idProduct; +} /* end of glGetUsbDeviceProductId() */ + +int32_t glGetUsbDeviceManufacturerName(struct usb_device *dev, uint8_t *buffer, uint32_t bufLen) +{ + return usb_string(dev, dev->descriptor.iManufacturer, buffer, bufLen); +} /* end of glGetUsbDeviceManufacturerName() */ + +int32_t glGetUsbDeviceProductName(struct usb_device *dev, uint8_t *buffer, uint32_t bufLen) +{ + return usb_string(dev, dev->descriptor.iProduct, buffer, bufLen); +} /* end of glGetUsbDeviceManufacturerName() */ + +int32_t glGetUsbDeviceSerialNumber(struct usb_device *dev, uint8_t *buffer, uint32_t bufLen) +{ + return usb_string(dev, dev->descriptor.iSerialNumber, buffer, bufLen); +} /* end of glGetUsbDeviceSerialNumber() */ + + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Read a 32-bit device register +* +* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. +* \param[in] u4Register Register offset +* \param[in] pu4Value Pointer to variable used to store read value +* +* \retval TRUE operation success +* \retval FALSE operation fail +*/ +/*----------------------------------------------------------------------------*/ +u_int8_t kalDevRegRead(IN struct GLUE_INFO *prGlueInfo, IN uint32_t u4Register, OUT uint32_t *pu4Value) +{ + struct BUS_INFO *prBusInfo = NULL; + int ret = 0; + uint8_t ucRetryCount = 0; + + ASSERT(prGlueInfo); + ASSERT(pu4Value); + + prBusInfo = prGlueInfo->prAdapter->chip_info->bus_info; + *pu4Value = 0xFFFFFFFF; + + do { + ret = mtk_usb_vendor_request(prGlueInfo, + 0, + prBusInfo->u4device_vender_request_in, + VND_REQ_REG_READ, + (u4Register & 0xffff0000) >> 16, + (u4Register & 0x0000ffff), pu4Value, + sizeof(*pu4Value)); + + if (ret || ucRetryCount) + DBGLOG(HAL, ERROR, + "usb_control_msg() status: %d retry: %u\n", + ret, ucRetryCount); + + + ucRetryCount++; + if (ucRetryCount > HIF_USB_ACCESS_RETRY_LIMIT) + break; + } while (ret); + + if (ret) { + kalSendAeeWarning(HIF_USB_ERR_TITLE_STR, + HIF_USB_ERR_DESC_STR "USB() reports error: %x retry: %u", ret, ucRetryCount); + DBGLOG(HAL, ERROR, "usb_readl() reports error: %x retry: %u\n", ret, ucRetryCount); + } else { + DBGLOG(HAL, TRACE, "Get CR[0x%08x] value[0x%08x]\n", + u4Register, *pu4Value); + } + + return (ret) ? FALSE : TRUE; +} /* end of kalDevRegRead() */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Write a 32-bit device register +* +* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. +* \param[in] u4Register Register offset +* \param[in] u4Value Value to be written +* +* \retval TRUE operation success +* \retval FALSE operation fail +*/ +/*----------------------------------------------------------------------------*/ +u_int8_t kalDevRegWrite(IN struct GLUE_INFO *prGlueInfo, IN uint32_t u4Register, IN uint32_t u4Value) +{ + int ret = 0; + uint8_t ucRetryCount = 0; + struct BUS_INFO *prBusInfo = NULL; + + ASSERT(prGlueInfo); + prBusInfo = prGlueInfo->prAdapter->chip_info->bus_info; + do { + ret = mtk_usb_vendor_request(prGlueInfo, + 0, + prBusInfo->u4device_vender_request_out, + VND_REQ_REG_WRITE, + (u4Register & 0xffff0000) >> 16, + (u4Register & 0x0000ffff), + &u4Value, + sizeof(u4Value)); + + if (ret || ucRetryCount) + DBGLOG(HAL, ERROR, + "usb_control_msg() status: %d retry: %u\n", + ret, ucRetryCount); + + ucRetryCount++; + if (ucRetryCount > HIF_USB_ACCESS_RETRY_LIMIT) + break; + + } while (ret); + + if (ret) { + kalSendAeeWarning(HIF_USB_ERR_TITLE_STR, + HIF_USB_ERR_DESC_STR "usb_writel() reports error: %x retry: %u", ret, ucRetryCount); + DBGLOG(HAL, ERROR, "usb_writel() reports error: %x retry: %u\n", ret, ucRetryCount); + } else { + DBGLOG(HAL, INFO, "Set CR[0x%08x] value[0x%08x]\n", u4Register, u4Value); + } + + return (ret) ? FALSE : TRUE; +} /* end of kalDevRegWrite() */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Read device I/O port +* +* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. +* \param[in] u2Port I/O port offset +* \param[in] u2Len Length to be read +* \param[out] pucBuf Pointer to read buffer +* \param[in] u2ValidOutBufSize Length of the buffer valid to be accessed +* +* \retval TRUE operation success +* \retval FALSE operation fail +*/ +/*----------------------------------------------------------------------------*/ +u_int8_t +kalDevPortRead(IN struct GLUE_INFO *prGlueInfo, + IN uint16_t u2Port, IN uint32_t u4Len, OUT uint8_t *pucBuf, IN uint32_t u4ValidOutBufSize) +{ + struct GL_HIF_INFO *prHifInfo = NULL; + uint8_t *pucDst = NULL; + /* int count = u4Len; */ + int ret = 0; + /* int bNum = 0; */ + +#if DBG + DBGLOG(HAL, INFO, "++kalDevPortRead++ buf:0x%p, port:0x%x, length:%d\n", pucBuf, u2Port, u4Len); +#endif + + ASSERT(prGlueInfo); + prHifInfo = &prGlueInfo->rHifInfo; + + ASSERT(pucBuf); + pucDst = pucBuf; + + ASSERT(u4Len <= u4ValidOutBufSize); + + u2Port &= MTK_USB_PORT_MASK; + if (prGlueInfo->rHifInfo.eEventEpType == EVENT_EP_TYPE_INTR && + u2Port == (USB_EVENT_EP_IN & USB_ENDPOINT_NUMBER_MASK)) { + /* maximize buff len for usb in */ + ret = mtk_usb_intr_in_msg(&prGlueInfo->rHifInfo, u4ValidOutBufSize, pucDst, u2Port); + if (ret != u4Len) { + DBGLOG(HAL, WARN, "usb_interrupt_msg(IN=%d) Warning. Data is not completed. (receive %d/%u)\n", + u2Port, ret, u4Len); + } + ret = ret >= 0 ? 0 : ret; + } else if (u2Port >= MTK_USB_BULK_IN_MIN_EP && u2Port <= MTK_USB_BULK_IN_MAX_EP) { + /* maximize buff len for usb in */ + ret = mtk_usb_bulk_in_msg(&prGlueInfo->rHifInfo, u4ValidOutBufSize, pucDst, u2Port); + if (ret != u4Len) { + DBGLOG(HAL, WARN, "usb_bulk_msg(IN=%d) Warning. Data is not completed. (receive %d/%u)\n", + u2Port, ret, u4Len); + } + ret = ret >= 0 ? 0 : ret; + } else { + DBGLOG(HAL, ERROR, "kalDevPortRead reports error: invalid port %x\n", u2Port); + ret = -EINVAL; + } + + if (ret) { + kalSendAeeWarning(HIF_USB_ERR_TITLE_STR, HIF_USB_ERR_DESC_STR "usb_readsb() reports error: %x", ret); + DBGLOG(HAL, ERROR, "usb_readsb() reports error: %x\n", ret); + } + + return (ret) ? FALSE : TRUE; +} /* end of kalDevPortRead() */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Write device I/O port +* +* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. +* \param[in] u2Port I/O port offset +* \param[in] u2Len Length to be write +* \param[in] pucBuf Pointer to write buffer +* \param[in] u2ValidInBufSize Length of the buffer valid to be accessed +* +* \retval TRUE operation success +* \retval FALSE operation fail +*/ +/*----------------------------------------------------------------------------*/ +u_int8_t +kalDevPortWrite(IN struct GLUE_INFO *prGlueInfo, + IN uint16_t u2Port, IN uint32_t u4Len, IN uint8_t *pucBuf, IN uint32_t u4ValidInBufSize) +{ + struct GL_HIF_INFO *prHifInfo = NULL; + uint8_t *pucSrc = NULL; + /* int count = u4Len; */ + int ret = 0; + /* int bNum = 0; */ + +#if DBG + DBGLOG(HAL, INFO, "++kalDevPortWrite++ buf:0x%p, port:0x%x, length:%d\n", pucBuf, u2Port, u4Len); +#endif + + ASSERT(prGlueInfo); + prHifInfo = &prGlueInfo->rHifInfo; + + ASSERT(pucBuf); + pucSrc = pucBuf; + + ASSERT((u4Len + LEN_USB_UDMA_TX_TERMINATOR) <= u4ValidInBufSize); + + kalMemZero(pucSrc + u4Len, LEN_USB_UDMA_TX_TERMINATOR); + u4Len += LEN_USB_UDMA_TX_TERMINATOR; + + u2Port &= MTK_USB_PORT_MASK; + if (u2Port >= MTK_USB_BULK_OUT_MIN_EP && u2Port <= MTK_USB_BULK_OUT_MAX_EP) { + ret = mtk_usb_bulk_out_msg(&prGlueInfo->rHifInfo, u4Len, pucSrc, u2Port/*8*/); + if (ret != u4Len) { + DBGLOG(HAL, WARN, "usb_bulk_msg(OUT=%d) Warning. Data is not completed. (receive %d/%u)\n", + u2Port, ret, u4Len); + } + ret = ret >= 0 ? 0 : ret; + } else { + DBGLOG(HAL, ERROR, "kalDevPortWrite reports error: invalid port %x\n", u2Port); + ret = -EINVAL; + } + + if (ret) { + kalSendAeeWarning(HIF_USB_ERR_TITLE_STR, HIF_USB_ERR_DESC_STR "usb_writesb() reports error: %x", ret); + DBGLOG(HAL, ERROR, "usb_writesb() reports error: %x\n", ret); + } + + return (ret) ? FALSE : TRUE; +} /* end of kalDevPortWrite() */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Set power state +* +* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. +* \param[in] ePowerMode +* +* \return (none) +*/ +/*----------------------------------------------------------------------------*/ +void glSetPowerState(IN struct GLUE_INFO *prGlueInfo, IN uint32_t ePowerMode) +{ +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Write data to device +* +* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. +* \param[in] prMsduInfo msdu info +* +* \retval TRUE operation success +* \retval FALSE operation fail +*/ +/*----------------------------------------------------------------------------*/ +u_int8_t kalDevWriteData(IN struct GLUE_INFO *prGlueInfo, IN struct MSDU_INFO *prMsduInfo) +{ + halTxUSBSendData(prGlueInfo, prMsduInfo); + return TRUE; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Kick Tx data to device +* +* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. +* +* \retval TRUE operation success +* \retval FALSE operation fail +*/ +/*----------------------------------------------------------------------------*/ +u_int8_t kalDevKickData(IN struct GLUE_INFO *prGlueInfo) +{ +#if 0 + halTxUSBKickData(prGlueInfo); +#endif + return TRUE; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Write command to device +* +* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. +* \param[in] u4Addr I/O port offset +* \param[in] ucData Single byte of data to be written +* +* \retval TRUE operation success +* \retval FALSE operation fail +*/ +/*----------------------------------------------------------------------------*/ +enum ENUM_CMD_TX_RESULT kalDevWriteCmd(IN struct GLUE_INFO *prGlueInfo, + IN struct CMD_INFO *prCmdInfo, IN uint8_t ucTC) +{ + halTxUSBSendCmd(prGlueInfo, ucTC, prCmdInfo); + return CMD_TX_RESULT_SUCCESS; +} + +void glGetDev(void *ctx, struct device **dev) +{ + struct usb_interface *prUsbIntf = (struct usb_interface *) ctx; + struct usb_device *prUsbDev = interface_to_usbdev(prUsbIntf); + + *dev = &prUsbDev->dev; +} + +void glGetHifDev(struct GL_HIF_INFO *prHif, struct device **dev) +{ + *dev = &(prHif->udev->dev); +} + +#if CFG_CHIP_RESET_SUPPORT +void kalRemoveProbe(IN struct GLUE_INFO *prGlueInfo) +{ + DBGLOG(INIT, WARN, "[SER][L0] not support..\n"); +} +#endif + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_ate_agent.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_ate_agent.h new file mode 100644 index 0000000000000000000000000000000000000000..afa0f148e25426bdc25f88b9dc3657344c29a8e3 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_ate_agent.h @@ -0,0 +1,300 @@ +/******************************************************************************* + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ +/*! \file gl_ate_agent.h + * \brief This file includes private ioctl support. + */ + +#ifndef _GL_ATE_AGENT_H +#define _GL_ATE_AGENT_H +#if CFG_SUPPORT_QA_TOOL +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +extern uint32_t u4RxStatSeqNum; + +#if CFG_SUPPORT_TX_BF +extern union PFMU_PROFILE_TAG1 g_rPfmuTag1; +extern union PFMU_PROFILE_TAG2 g_rPfmuTag2; +extern union PFMU_DATA g_rPfmuData; +#endif + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +struct STA_REC_BF_UPD_ARGUMENT { + uint32_t u4WlanId; + uint32_t u4BssId; + uint32_t u4PfmuId; + uint32_t u4SuMu; + uint32_t u4eTxBfCap; + uint32_t u4NdpaRate; + uint32_t u4NdpRate; + uint32_t u4ReptPollRate; + uint32_t u4TxMode; + uint32_t u4Nc; + uint32_t u4Nr; + uint32_t u4Bw; + uint32_t u4SpeIdx; + uint32_t u4TotalMemReq; + uint32_t u4MemReq20M; + uint32_t au4MemRow[4]; + uint32_t au4MemCol[4]; +}; + +struct ATE_OPS_T { + int32_t (*setICapStart)(struct GLUE_INFO *prGlueInfo, + uint32_t fgTrigger, + uint32_t fgRingCapEn, + uint32_t u4Event, + uint32_t u4Node, + uint32_t u4Len, + uint32_t u4StopCycle, + uint32_t u4BW, + uint32_t u4MACTriggerEvent, + uint32_t u4SourceAddrLSB, + uint32_t u4SourceAddrMSB, + uint32_t u4Band); + int32_t (*getICapStatus)(struct GLUE_INFO *prGlueInfo); + int32_t (*getICapIQData)(struct GLUE_INFO *prGlueInfo, + uint8_t *pData, + uint32_t u4IQType, + uint32_t u4WFNum); + void (*getRbistDataDumpEvent)(struct ADAPTER *prAdapter, + uint8_t *pucEventBuf); + void (*icapRiseVcoreClockRate)(void); + void (*icapDownVcoreClockRate)(void); +}; + + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +int Set_ResetStatCounter_Proc(struct net_device *prNetDev, + uint8_t *prInBuf); +int SetATE(struct net_device *prNetDev, uint8_t *prInBuf); +int SetATEDa(struct net_device *prNetDev, uint8_t *prInBuf); +int SetATESa(struct net_device *prNetDev, uint8_t *prInBuf); +int SetATEChannel(struct net_device *prNetDev, + uint8_t *prInBuf); +int SetATETxPower0(struct net_device *prNetDev, + uint8_t *prInBuf); +int SetATETxGi(struct net_device *prNetDev, + uint8_t *prInBuf); +int SetATETxBw(struct net_device *prNetDev, + uint8_t *prInBuf); +int SetATETxMode(struct net_device *prNetDev, + uint8_t *prInBuf); +int SetATETxLength(struct net_device *prNetDev, + uint8_t *prInBuf); +int SetATETxCount(struct net_device *prNetDev, + uint8_t *prInBuf); +int SetATETxMcs(struct net_device *prNetDev, + uint8_t *prInBuf); +int SetATEIpg(struct net_device *prNetDev, + uint8_t *prInBuf); +int SetATETxVhtNss(struct net_device *prNetDev, + uint8_t *prInBuf); +int SetATETxPath(struct net_device *prNetDev, + uint8_t *prInBuf); +int SetATERxPath(struct net_device *prNetDev, + uint8_t *prInBuf); +#if CFG_SUPPORT_ANT_SWAP +int SetATEAntSwp(struct net_device *prNetDev, + uint8_t *prInBuf); +#endif + +#if CFG_SUPPORT_TX_BF +int Set_TxBfProfileTag_Help(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfProfileTag_InValid(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfProfileTag_PfmuIdx(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfProfileTag_BfType(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfProfileTag_DBW(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfProfileTag_SuMu(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfProfileTag_Mem(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfProfileTag_Matrix(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfProfileTag_SNR(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfProfileTag_SmartAnt(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfProfileTag_SeIdx(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfProfileTag_RmsdThrd(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfProfileTag_McsThrd(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfProfileTag_TimeOut(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfProfileTag_DesiredBW(struct net_device + *prNetDev, uint8_t *prInBuf); +int Set_TxBfProfileTag_DesiredNc(struct net_device + *prNetDev, uint8_t *prInBuf); +int Set_TxBfProfileTag_DesiredNr(struct net_device + *prNetDev, uint8_t *prInBuf); +int Set_TxBfProfileTagRead(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfProfileTagWrite(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_StaRecCmmUpdate(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_StaRecBfUpdate(struct net_device *prNetDev, + uint8_t *prInBuf); + +int Set_DevInfoUpdate(struct net_device *prNetDev, + uint8_t *prInBuf); + +int Set_BssInfoUpdate(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfProfileDataRead(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfProfileDataWrite(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_Trigger_Sounding_Proc(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_Stop_Sounding_Proc(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfTxApply(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfProfilePnRead(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfProfilePnWrite(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfManualAssoc(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfPfmuMemAlloc(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfPfmuMemRelease(struct net_device *prNetDev, + uint8_t *prInBuf); + +#if CFG_SUPPORT_MU_MIMO +int Set_MUGetInitMCS(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_MUCalInitMCS(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_MUCalLQ(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_MUGetLQ(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_MUSetSNROffset(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_MUSetZeroNss(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_MUSetSpeedUpLQ(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_MUSetMUTable(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_MUSetGroup(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_MUGetQD(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_MUSetEnable(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_MUSetGID_UP(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_MUTriggerTx(struct net_device *prNetDev, + uint8_t *prInBuf); +#endif + +#if CFG_SUPPORT_TX_BF_FPGA +int Set_TxBfProfileSwTagWrite(struct net_device *prNetDev, + uint8_t *prInBuf); +#endif +#endif + + +int WriteEfuse(struct net_device *prNetDev, + uint8_t *prInBuf); +int SetTxTargetPower(struct net_device *prNetDev, + uint8_t *prInBuf); + +#if (CFG_SUPPORT_DFS_MASTER == 1) +int SetRddReport(struct net_device *prNetDev, + uint8_t *prInBuf); +int SetByPassCac(struct net_device *prNetDev, + uint8_t *prInBuf); +int SetRadarDetectMode(struct net_device *prNetDev, + uint8_t *prInBuf); +#endif + +int AteCmdSetHandle(struct net_device *prNetDev, + uint8_t *prInBuf, uint32_t u4InBufLen); + +#endif /*CFG_SUPPORT_QA_TOOL */ +#endif /* _GL_ATE_AGENT_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_cfg80211.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_cfg80211.h new file mode 100644 index 0000000000000000000000000000000000000000..9b428bb8dec0729deddea53192411bdf72161475 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_cfg80211.h @@ -0,0 +1,779 @@ +/******************************************************************************* + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include + * /gl_cfg80211.h#1 + */ + +/*! \file gl_cfg80211.h + * \brief This file is for Portable Driver linux cfg80211 support. + */ + + +#ifndef _GL_CFG80211_H +#define _GL_CFG80211_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include +#include +#include +#include +#include + +#include "gl_os.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#ifdef CONFIG_NL80211_TESTMODE +#define NL80211_DRIVER_TESTMODE_VERSION 2 +#endif + +#if KERNEL_VERSION(4, 19, 0) > CFG80211_VERSION_CODE +#define NL80211_EXT_FEATURE_LOW_SPAN_SCAN 22 +#define NL80211_SCAN_FLAG_LOW_SPAN (1 << 8) +#endif + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +#ifdef CONFIG_NL80211_TESTMODE +#if CFG_SUPPORT_NFC_BEAM_PLUS + +struct NL80211_DRIVER_SET_NFC_PARAMS { + struct NL80211_DRIVER_TEST_MODE_PARAMS hdr; + uint32_t NFC_Enable; + +}; + +#endif + + + +struct NL80211_DRIVER_GET_STA_STATISTICS_PARAMS { + struct NL80211_DRIVER_TEST_MODE_PARAMS hdr; + uint32_t u4Version; + uint32_t u4Flag; + uint8_t aucMacAddr[MAC_ADDR_LEN]; +}; + +enum _ENUM_TESTMODE_LINK_DETECTION_ATTR { + NL80211_TESTMODE_LINK_INVALID = 0, + NL80211_TESTMODE_LINK_TX_FAIL_CNT, + NL80211_TESTMODE_LINK_TX_RETRY_CNT, + NL80211_TESTMODE_LINK_TX_MULTI_RETRY_CNT, + NL80211_TESTMODE_LINK_ACK_FAIL_CNT, + NL80211_TESTMODE_LINK_FCS_ERR_CNT, + NL80211_TESTMODE_LINK_TX_CNT, + NL80211_TESTMODE_LINK_RX_CNT, + NL80211_TESTMODE_LINK_RST_REASON, + NL80211_TESTMODE_LINK_RST_TIME, + NL80211_TESTMODE_LINK_ROAM_FAIL_TIMES, + NL80211_TESTMODE_LINK_ROAM_FAIL_TIME, + NL80211_TESTMODE_LINK_TX_DONE_DELAY_IS_ARP, + NL80211_TESTMODE_LINK_ARRIVE_DRV_TICK, + NL80211_TESTMODE_LINK_ENQUE_TICK, + NL80211_TESTMODE_LINK_DEQUE_TICK, + NL80211_TESTMODE_LINK_LEAVE_DRV_TICK, + NL80211_TESTMODE_LINK_CURR_TICK, + NL80211_TESTMODE_LINK_CURR_TIME, + + NL80211_TESTMODE_LINK_DETECT_NUM +}; + +enum ENUM_TESTMODE_STA_STATISTICS_ATTR { + NL80211_TESTMODE_STA_STATISTICS_INVALID = 0, + NL80211_TESTMODE_STA_STATISTICS_VERSION, + NL80211_TESTMODE_STA_STATISTICS_MAC, + NL80211_TESTMODE_STA_STATISTICS_LINK_SCORE, + NL80211_TESTMODE_STA_STATISTICS_FLAG, + + NL80211_TESTMODE_STA_STATISTICS_PER, + NL80211_TESTMODE_STA_STATISTICS_RSSI, + NL80211_TESTMODE_STA_STATISTICS_PHY_MODE, + NL80211_TESTMODE_STA_STATISTICS_TX_RATE, + + NL80211_TESTMODE_STA_STATISTICS_TOTAL_CNT, + NL80211_TESTMODE_STA_STATISTICS_THRESHOLD_CNT, + + NL80211_TESTMODE_STA_STATISTICS_AVG_PROCESS_TIME, + NL80211_TESTMODE_STA_STATISTICS_MAX_PROCESS_TIME, + NL80211_TESTMODE_STA_STATISTICS_AVG_HIF_PROCESS_TIME, + NL80211_TESTMODE_STA_STATISTICS_MAX_HIF_PROCESS_TIME, + + NL80211_TESTMODE_STA_STATISTICS_FAIL_CNT, + NL80211_TESTMODE_STA_STATISTICS_TIMEOUT_CNT, + NL80211_TESTMODE_STA_STATISTICS_AVG_AIR_TIME, + + NL80211_TESTMODE_STA_STATISTICS_TC_EMPTY_CNT_ARRAY, + NL80211_TESTMODE_STA_STATISTICS_TC_QUE_LEN_ARRAY, + + NL80211_TESTMODE_STA_STATISTICS_TC_AVG_QUE_LEN_ARRAY, + NL80211_TESTMODE_STA_STATISTICS_TC_CUR_QUE_LEN_ARRAY, + + /* + * how many packages TX during statistics interval + */ + NL80211_TESTMODE_STA_STATISTICS_ENQUEUE, + + /* + * how many packages this TX during statistics interval + */ + NL80211_TESTMODE_STA_STATISTICS_STA_ENQUEUE, + + /* + * how many packages dequeue during statistics interval + */ + NL80211_TESTMODE_STA_STATISTICS_DEQUEUE, + + /* + * how many packages this sta dequeue during statistics interval + */ + NL80211_TESTMODE_STA_STATISTICS_STA_DEQUEUE, + + /* + * how many TC[0-3] resource back from firmware during + * statistics interval + */ + NL80211_TESTMODE_STA_STATISTICS_RB_ARRAY, + NL80211_TESTMODE_STA_STATISTICS_NO_TC_ARRAY, + NL80211_TESTMODE_STA_STATISTICS_USED_TC_PGCT_ARRAY, + NL80211_TESTMODE_STA_STATISTICS_WANTED_TC_PGCT_ARRAY, + + NL80211_TESTMODE_STA_STATISTICS_IRQ_ISR_CNT, + NL80211_TESTMODE_STA_STATISTICS_IRQ_ISR_PASS_CNT, + NL80211_TESTMODE_STA_STATISTICS_IRQ_TASK_CNT, + NL80211_TESTMODE_STA_STATISTICS_IRQ_AB_CNT, + NL80211_TESTMODE_STA_STATISTICS_IRQ_SW_CNT, + NL80211_TESTMODE_STA_STATISTICS_IRQ_TX_CNT, + NL80211_TESTMODE_STA_STATISTICS_IRQ_RX_CNT, + + NL80211_TESTMODE_STA_STATISTICS_RESERVED_ARRAY, + + NL80211_TESTMODE_STA_STATISTICS_NUM +}; +#endif +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +/* cfg80211 hooks */ +int +mtk_cfg80211_change_iface(struct wiphy *wiphy, + struct net_device *ndev, enum nl80211_iftype type, + u32 *flags, struct vif_params *params); + +int +mtk_cfg80211_add_key(struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index, bool pairwise, const u8 *mac_addr, + struct key_params *params); + +int +mtk_cfg80211_get_key(struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index, + bool pairwise, + const u8 *mac_addr, void *cookie, + void (*callback)(void *cookie, struct key_params *)); + +int +mtk_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_index, + bool pairwise, const u8 *mac_addr); + +int +mtk_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev, + u8 key_index, bool unicast, bool multicast); + +#if KERNEL_VERSION(3, 16, 0) <= CFG80211_VERSION_CODE +int mtk_cfg80211_get_station(struct wiphy *wiphy, + struct net_device *ndev, const u8 *mac, + struct station_info *sinfo); +#else +int mtk_cfg80211_get_station(struct wiphy *wiphy, + struct net_device *ndev, u8 *mac, + struct station_info *sinfo); +#endif + +int +mtk_cfg80211_get_link_statistics(struct wiphy *wiphy, + struct net_device *ndev, u8 *mac, + struct station_info *sinfo); + +int mtk_cfg80211_scan(struct wiphy *wiphy, + struct cfg80211_scan_request *request); + +void mtk_cfg80211_abort_scan(struct wiphy *wiphy, + struct wireless_dev *wdev); + +int mtk_cfg80211_connect(struct wiphy *wiphy, + struct net_device *ndev, + struct cfg80211_connect_params *sme); + +int mtk_cfg80211_disconnect(struct wiphy *wiphy, + struct net_device *ndev, u16 reason_code); + +int mtk_cfg80211_join_ibss(struct wiphy *wiphy, + struct net_device *ndev, + struct cfg80211_ibss_params *params); + +int mtk_cfg80211_leave_ibss(struct wiphy *wiphy, + struct net_device *ndev); + +int mtk_cfg80211_set_power_mgmt(struct wiphy *wiphy, + struct net_device *ndev, bool enabled, int timeout); + +int mtk_cfg80211_set_pmksa(struct wiphy *wiphy, + struct net_device *ndev, struct cfg80211_pmksa *pmksa); + +int mtk_cfg80211_del_pmksa(struct wiphy *wiphy, + struct net_device *ndev, struct cfg80211_pmksa *pmksa); + +int mtk_cfg80211_flush_pmksa(struct wiphy *wiphy, + struct net_device *ndev); + +int mtk_cfg80211_set_rekey_data(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_gtk_rekey_data *data); + +int mtk_cfg80211_remain_on_channel(struct wiphy *wiphy, + struct wireless_dev *wdev, struct ieee80211_channel *chan, + unsigned int duration, u64 *cookie); + +int mtk_cfg80211_cancel_remain_on_channel( + struct wiphy *wiphy, struct wireless_dev *wdev, u64 cookie); + +#if KERNEL_VERSION(3, 14, 0) <= CFG80211_VERSION_CODE +int mtk_cfg80211_mgmt_tx(struct wiphy *wiphy, + struct wireless_dev *wdev, + struct cfg80211_mgmt_tx_params *params, + u64 *cookie); +#else +int mtk_cfg80211_mgmt_tx(struct wiphy *wiphy, + struct wireless_dev *wdev, + struct ieee80211_channel *channel, bool offscan, + unsigned int wait, + const u8 *buf, size_t len, bool no_cck, + bool dont_wait_for_ack, u64 *cookie); +#endif + +void mtk_cfg80211_mgmt_frame_register(IN struct wiphy *wiphy, + IN struct wireless_dev *wdev, IN u16 frame_type, IN bool reg); + +int mtk_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, + struct wireless_dev *wdev, u64 cookie); + +#ifdef CONFIG_NL80211_TESTMODE +int +mtk_cfg80211_testmode_get_sta_statistics(IN struct wiphy + *wiphy, + IN void *data, IN int len, IN struct GLUE_INFO *prGlueInfo); + +int mtk_cfg80211_testmode_get_scan_done(IN struct wiphy + *wiphy, IN void *data, IN int len, + IN struct GLUE_INFO *prGlueInfo); + +#if KERNEL_VERSION(3, 12, 0) <= CFG80211_VERSION_CODE +int mtk_cfg80211_testmode_cmd(struct wiphy *wiphy, + struct wireless_dev *wdev, + void *data, int len); +#else +int mtk_cfg80211_testmode_cmd(struct wiphy *wiphy, + struct wireless_dev *wdev, + void *data, int len); +#endif + +int mtk_cfg80211_testmode_sw_cmd(IN struct wiphy *wiphy, + IN struct wireless_dev *wdev, + IN void *data, IN int len); + +#if CFG_SUPPORT_PASSPOINT +int mtk_cfg80211_testmode_hs20_cmd(IN struct wiphy *wiphy, + IN struct wireless_dev *wdev, + IN void *data, IN int len); +#endif /* CFG_SUPPORT_PASSPOINT */ + +#if CFG_SUPPORT_WAPI +int mtk_cfg80211_testmode_set_key_ext(IN struct wiphy + *wiphy, + IN struct wireless_dev *wdev, + IN void *data, IN int len); +#endif +#if CFG_SUPPORT_NFC_BEAM_PLUS +int mtk_cfg80211_testmode_get_scan_done(IN struct wiphy *wiphy, + IN void *data, IN int len, IN struct GLUE_INFO *prGlueInfo); +#endif +#else +/* IGNORE KERNEL DEPENCY ERRORS */ +/* #error "Please ENABLE kernel config (CONFIG_NL80211_TESTMODE) to support + * Wi-Fi Direct" + */ +#endif + +#if CFG_SUPPORT_SCHED_SCAN +int +mtk_cfg80211_sched_scan_start(IN struct wiphy *wiphy, + IN struct net_device *ndev, + IN struct cfg80211_sched_scan_request *request); + +#if KERNEL_VERSION(4, 12, 0) <= CFG80211_VERSION_CODE +int mtk_cfg80211_sched_scan_stop(IN struct wiphy *wiphy, + IN struct net_device *ndev, + IN u64 reqid); +#else +int mtk_cfg80211_sched_scan_stop(IN struct wiphy *wiphy, + IN struct net_device *ndev); +#endif +#endif /* CFG_SUPPORT_SCHED_SCAN */ + +int mtk_cfg80211_assoc(struct wiphy *wiphy, + struct net_device *ndev, + struct cfg80211_assoc_request *req); + +#if KERNEL_VERSION(3, 16, 0) <= CFG80211_VERSION_CODE +int +mtk_cfg80211_change_station(struct wiphy *wiphy, + struct net_device *ndev, + const u8 *mac, struct station_parameters *params); + +int mtk_cfg80211_add_station(struct wiphy *wiphy, + struct net_device *ndev, + const u8 *mac, struct station_parameters *params); + +#if KERNEL_VERSION(3, 19, 0) <= CFG80211_VERSION_CODE +int mtk_cfg80211_del_station(struct wiphy *wiphy, + struct net_device *ndev, + struct station_del_parameters *params); +#else +int mtk_cfg80211_del_station(struct wiphy *wiphy, + struct net_device *ndev, + const u8 *mac); +#endif +#if KERNEL_VERSION(3, 18, 0) <= CFG80211_VERSION_CODE +int mtk_cfg80211_tdls_mgmt(struct wiphy *wiphy, + struct net_device *dev, + const u8 *peer, u8 action_code, u8 dialog_token, + u16 status_code, u32 peer_capability, + bool initiator, const u8 *buf, size_t len); +#else +int mtk_cfg80211_tdls_mgmt(struct wiphy *wiphy, + struct net_device *dev, + const u8 *peer, u8 action_code, u8 dialog_token, + u16 status_code, u32 peer_capability, + const u8 *buf, size_t len); +#endif + +int mtk_cfg80211_tdls_oper(struct wiphy *wiphy, + struct net_device *dev, + const u8 *peer, enum nl80211_tdls_operation oper); +#else +int +mtk_cfg80211_change_station(struct wiphy *wiphy, + struct net_device *ndev, u8 *mac, + struct station_parameters *params); + +int mtk_cfg80211_add_station(struct wiphy *wiphy, + struct net_device *ndev, u8 *mac, + struct station_parameters *params); + +int mtk_cfg80211_del_station(struct wiphy *wiphy, + struct net_device *ndev, u8 *mac); + +int +mtk_cfg80211_tdls_mgmt(struct wiphy *wiphy, + struct net_device *dev, + u8 *peer, u8 action_code, + u8 dialog_token, u16 status_code, + const u8 *buf, size_t len); + +int mtk_cfg80211_tdls_oper(struct wiphy *wiphy, + struct net_device *dev, u8 *peer, + enum nl80211_tdls_operation oper); +#endif + +int32_t mtk_cfg80211_process_str_cmd(struct wiphy *wiphy, + struct wireless_dev *wdev, + uint8_t *cmd, int32_t len); + +int32_t mtk_cfg80211_process_str_cmd_reply( + IN struct wiphy *wiphy, IN char *data, IN int len); + +void mtk_reg_notify(IN struct wiphy *pWiphy, + IN struct regulatory_request *pRequest); +void cfg80211_regd_set_wiphy(IN struct wiphy *pWiphy); + +int mtk_cfg80211_suspend(struct wiphy *wiphy, + struct cfg80211_wowlan *wow); + +int mtk_cfg80211_resume(struct wiphy *wiphy); + +/* cfg80211 wrapper hooks */ +#if CFG_ENABLE_UNIFY_WIPHY +#if KERNEL_VERSION(4, 12, 0) <= CFG80211_VERSION_CODE +struct wireless_dev *mtk_cfg_add_iface(struct wiphy *wiphy, + const char *name, + unsigned char name_assign_type, + enum nl80211_iftype type, + struct vif_params *params); +#elif KERNEL_VERSION(4, 1, 0) <= CFG80211_VERSION_CODE +struct wireless_dev *mtk_cfg_add_iface(struct wiphy *wiphy, + const char *name, + unsigned char name_assign_type, + enum nl80211_iftype type, + u32 *flags, + struct vif_params *params); +#else +struct wireless_dev *mtk_cfg_add_iface(struct wiphy *wiphy, + const char *name, + enum nl80211_iftype type, u32 *flags, + struct vif_params *params); +#endif +int mtk_cfg_del_iface(struct wiphy *wiphy, + struct wireless_dev *wdev); +#if KERNEL_VERSION(4, 12, 0) <= CFG80211_VERSION_CODE +int mtk_cfg_change_iface(struct wiphy *wiphy, + struct net_device *ndev, + enum nl80211_iftype type, + struct vif_params *params); +#else +int mtk_cfg_change_iface(struct wiphy *wiphy, + struct net_device *ndev, + enum nl80211_iftype type, u32 *flags, + struct vif_params *params); +#endif +int mtk_cfg_add_key(struct wiphy *wiphy, + struct net_device *ndev, u8 key_index, + bool pairwise, const u8 *mac_addr, + struct key_params *params); +int mtk_cfg_get_key(struct wiphy *wiphy, + struct net_device *ndev, u8 key_index, + bool pairwise, const u8 *mac_addr, void *cookie, + void (*callback)(void *cookie, struct key_params *)); +int mtk_cfg_del_key(struct wiphy *wiphy, + struct net_device *ndev, u8 key_index, + bool pairwise, const u8 *mac_addr); +int mtk_cfg_set_default_key(struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index, bool unicast, bool multicast); + +int mtk_cfg_set_default_mgmt_key(struct wiphy *wiphy, + struct net_device *ndev, u8 key_index); + +#if KERNEL_VERSION(3, 16, 0) <= CFG80211_VERSION_CODE +int mtk_cfg_get_station(struct wiphy *wiphy, + struct net_device *ndev, + const u8 *mac, struct station_info *sinfo); +#else +int mtk_cfg_get_station(struct wiphy *wiphy, + struct net_device *ndev, + u8 *mac, struct station_info *sinfo); +#endif + +#if CFG_SUPPORT_TDLS +#if KERNEL_VERSION(3, 16, 0) <= CFG80211_VERSION_CODE +int mtk_cfg_change_station(struct wiphy *wiphy, + struct net_device *ndev, + const u8 *mac, struct station_parameters *params); +#else +int mtk_cfg_change_station(struct wiphy *wiphy, + struct net_device *ndev, + u8 *mac, struct station_parameters *params); +#endif +#if KERNEL_VERSION(3, 16, 0) <= CFG80211_VERSION_CODE +int mtk_cfg_add_station(struct wiphy *wiphy, + struct net_device *ndev, + const u8 *mac, struct station_parameters *params); +#else +int mtk_cfg_add_station(struct wiphy *wiphy, + struct net_device *ndev, + u8 *mac, struct station_parameters *params); +#endif +#if KERNEL_VERSION(3, 16, 0) <= CFG80211_VERSION_CODE +int mtk_cfg_tdls_oper(struct wiphy *wiphy, + struct net_device *ndev, + const u8 *peer, enum nl80211_tdls_operation oper); +#else +int mtk_cfg_tdls_oper(struct wiphy *wiphy, + struct net_device *ndev, + u8 *peer, enum nl80211_tdls_operation oper); +#endif +#if KERNEL_VERSION(3, 18, 0) <= CFG80211_VERSION_CODE +int mtk_cfg_tdls_mgmt(struct wiphy *wiphy, + struct net_device *ndev, + const u8 *peer, u8 action_code, u8 dialog_token, + u16 status_code, + u32 peer_capability, bool initiator, const u8 *buf, + size_t len); +#elif KERNEL_VERSION(3, 16, 0) <= CFG80211_VERSION_CODE +int mtk_cfg_tdls_mgmt(struct wiphy *wiphy, + struct net_device *ndev, + const u8 *peer, u8 action_code, u8 dialog_token, + u16 status_code, + u32 peer_capability, const u8 *buf, size_t len); +#else +int mtk_cfg_tdls_mgmt(struct wiphy *wiphy, + struct net_device *ndev, + u8 *peer, u8 action_code, + u8 dialog_token, u16 status_code, + const u8 *buf, size_t len); +#endif +#endif /* CFG_SUPPORT_TDLS */ + +#if KERNEL_VERSION(3, 19, 0) <= CFG80211_VERSION_CODE +int mtk_cfg_del_station(struct wiphy *wiphy, + struct net_device *ndev, + struct station_del_parameters *params); +#elif KERNEL_VERSION(3, 16, 0) <= CFG80211_VERSION_CODE +int mtk_cfg_del_station(struct wiphy *wiphy, + struct net_device *ndev, + const u8 *mac); +#else +int mtk_cfg_del_station(struct wiphy *wiphy, + struct net_device *ndev, u8 *mac); +#endif +int mtk_cfg_scan(struct wiphy *wiphy, + struct cfg80211_scan_request *request); +#if KERNEL_VERSION(4, 5, 0) <= CFG80211_VERSION_CODE +void mtk_cfg_abort_scan(struct wiphy *wiphy, + struct wireless_dev *wdev); +#endif + +#if CFG_SUPPORT_SCHED_SCAN +int mtk_cfg_sched_scan_start(IN struct wiphy *wiphy, + IN struct net_device *ndev, + IN struct cfg80211_sched_scan_request *request); + +#if KERNEL_VERSION(4, 12, 0) <= CFG80211_VERSION_CODE +int mtk_cfg_sched_scan_stop(IN struct wiphy *wiphy, + IN struct net_device *ndev, + IN u64 reqid); +#else +int mtk_cfg_sched_scan_stop(IN struct wiphy *wiphy, + IN struct net_device *ndev); +#endif + +#endif /* CFG_SUPPORT_SCHED_SCAN */ + +int mtk_cfg_connect(struct wiphy *wiphy, + struct net_device *ndev, + struct cfg80211_connect_params *sme); +int mtk_cfg_disconnect(struct wiphy *wiphy, + struct net_device *ndev, + u16 reason_code); +int mtk_cfg_join_ibss(struct wiphy *wiphy, + struct net_device *ndev, + struct cfg80211_ibss_params *params); +int mtk_cfg_leave_ibss(struct wiphy *wiphy, + struct net_device *ndev); +int mtk_cfg_set_power_mgmt(struct wiphy *wiphy, + struct net_device *ndev, + bool enabled, int timeout); +int mtk_cfg_set_pmksa(struct wiphy *wiphy, + struct net_device *ndev, + struct cfg80211_pmksa *pmksa); +int mtk_cfg_del_pmksa(struct wiphy *wiphy, + struct net_device *ndev, + struct cfg80211_pmksa *pmksa); +int mtk_cfg_flush_pmksa(struct wiphy *wiphy, + struct net_device *ndev); +#if CONFIG_SUPPORT_GTK_REKEY +int mtk_cfg_set_rekey_data(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_gtk_rekey_data *data); +#endif /* CONFIG_SUPPORT_GTK_REKEY */ +int mtk_cfg_suspend(struct wiphy *wiphy, + struct cfg80211_wowlan *wow); +int mtk_cfg_resume(struct wiphy *wiphy); +int mtk_cfg_assoc(struct wiphy *wiphy, + struct net_device *ndev, + struct cfg80211_assoc_request *req); +int mtk_cfg_remain_on_channel(struct wiphy *wiphy, + struct wireless_dev *wdev, + struct ieee80211_channel *chan, + unsigned int duration, + u64 *cookie); +int mtk_cfg_cancel_remain_on_channel(struct wiphy *wiphy, + struct wireless_dev *wdev, u64 cookie); +uint16_t cfg80211_get_non_wfa_vendor_ie( + struct GLUE_INFO *prGlueInfo, + uint8_t *ies, int32_t len, + uint8_t ucBssIndex); + +#if KERNEL_VERSION(3, 14, 0) <= CFG80211_VERSION_CODE +int mtk_cfg_mgmt_tx(struct wiphy *wiphy, + struct wireless_dev *wdev, + struct cfg80211_mgmt_tx_params *params, u64 *cookie); +#else +int mtk_cfg_mgmt_tx(struct wiphy *wiphy, + struct wireless_dev *wdev, + struct ieee80211_channel *channel, bool offscan, + unsigned int wait, + const u8 *buf, size_t len, bool no_cck, + bool dont_wait_for_ack, + u64 *cookie); +#endif +void mtk_cfg_mgmt_frame_register(struct wiphy *wiphy, + struct wireless_dev *wdev, + u16 frame_type, bool reg); + +#ifdef CONFIG_NL80211_TESTMODE +#if KERNEL_VERSION(3, 12, 0) <= CFG80211_VERSION_CODE +int mtk_cfg_testmode_cmd(struct wiphy *wiphy, + struct wireless_dev *wdev, + void *data, int len); +#else +int mtk_cfg_testmode_cmd(struct wiphy *wiphy, void *data, + int len); +#endif +#endif /* CONFIG_NL80211_TESTMODE */ + +#if (CFG_SUPPORT_DFS_MASTER == 1) +#if KERNEL_VERSION(3, 15, 0) <= CFG80211_VERSION_CODE +int mtk_cfg_start_radar_detection(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_chan_def *chandef, + unsigned int cac_time_ms); +#else +int mtk_cfg_start_radar_detection(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_chan_def *chandef); +#endif + + +#if KERNEL_VERSION(3, 13, 0) <= CFG80211_VERSION_CODE +int mtk_cfg_channel_switch(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_csa_settings *params); +#endif +#endif + + +#if (CFG_ENABLE_WIFI_DIRECT_CFG_80211 != 0) +int mtk_cfg_change_bss(struct wiphy *wiphy, + struct net_device *dev, + struct bss_parameters *params); +int mtk_cfg_mgmt_tx_cancel_wait(struct wiphy *wiphy, + struct wireless_dev *wdev, + u64 cookie); +int mtk_cfg_deauth(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_deauth_request *req); +int mtk_cfg_disassoc(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_disassoc_request *req); +int mtk_cfg_start_ap(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_ap_settings *settings); +int mtk_cfg_change_beacon(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_beacon_data *info); +int mtk_cfg_stop_ap(struct wiphy *wiphy, + struct net_device *dev); +int mtk_cfg_set_wiphy_params(struct wiphy *wiphy, + u32 changed); +int mtk_cfg_set_bitrate_mask(struct wiphy *wiphy, + struct net_device *dev, + const u8 *peer, + const struct cfg80211_bitrate_mask *mask); +int mtk_cfg_set_txpower(struct wiphy *wiphy, + struct wireless_dev *wdev, + enum nl80211_tx_power_setting type, int mbm); +int mtk_cfg_get_txpower(struct wiphy *wiphy, + struct wireless_dev *wdev, + int *dbm); +#endif /* (CFG_ENABLE_WIFI_DIRECT_CFG_80211 != 0) */ + +#endif /* CFG_ENABLE_UNIFY_WIPHY */ + +int mtk_cfg80211_update_ft_ies(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_update_ft_ies_params *ftie); + +#if CFG_SUPPORT_WPA3 +int mtk_cfg80211_external_auth(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_external_auth_params *params); +#endif + +int mtk_IsP2PNetDevice(struct GLUE_INFO *prGlueInfo, + struct net_device *ndev); + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#endif /* _GL_CFG80211_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_hook_api.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_hook_api.h new file mode 100644 index 0000000000000000000000000000000000000000..71ff629fc214e792a0aa3c54296b4889319f06ba --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_hook_api.h @@ -0,0 +1,353 @@ +/******************************************************************************* + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ +/*! \file gl_hook_api.h + * \brief This file includes private ioctl support. + */ + +#ifndef _GL_HOOK_API_H +#define _GL_HOOK_API_H +#if CFG_SUPPORT_QA_TOOL +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +int32_t MT_ATEStart(struct net_device *prNetDev, + uint8_t *prInBuf); +int32_t MT_ICAPStart(struct net_device *prNetDev, + uint8_t *prInBuf); +int32_t MT_ICAPCommand(struct net_device *prNetDev, + uint8_t *prInBuf); +int32_t MT_ATEStop(struct net_device *prNetDev, + uint8_t *prInBuf); +int32_t MT_ATEStartTX(struct net_device *prNetDev, + uint8_t *prInBuf); +int32_t MT_ATEStopTX(struct net_device *prNetDev, + uint8_t *prInBuf); +int32_t MT_ATEStartRX(struct net_device *prNetDev, + uint8_t *prInBuf); +int32_t MT_ATEStopRX(struct net_device *prNetDev, + uint8_t *prInBuf); +int32_t MT_ATESetChannel(struct net_device *prNetDev, + uint32_t u4SXIdx, uint32_t u4SetFreq); +int32_t MT_ATESetPreamble(struct net_device *prNetDev, + uint32_t u4Mode); +int32_t MT_ATESetSystemBW(struct net_device *prNetDev, + uint32_t u4BW); +int32_t MT_ATESetTxLength(struct net_device *prNetDev, + uint32_t u4TxLength); +int32_t MT_ATESetTxCount(struct net_device *prNetDev, + uint32_t u4TxCount); +int32_t MT_ATESetTxIPG(struct net_device *prNetDev, + uint32_t u4TxIPG); +int32_t MT_ATESetTxPath(struct net_device *prNetDev, + uint32_t u4Tx_path); +int32_t MT_ATESetRxPath(struct net_device *prNetDev, + uint32_t u4Rx_path); +int32_t MT_ATESetTxPower0(struct net_device *prNetDev, + uint32_t u4TxPower0); +int32_t MT_ATESetPerPacketBW(struct net_device *prNetDev, + uint32_t u4BW); +int32_t MT_ATEPrimarySetting(struct net_device *prNetDev, + uint32_t u4PrimaryCh); +int32_t MT_ATESetTxGi(struct net_device *prNetDev, + uint32_t u4SetTxGi); +int32_t MT_ATESetTxPayLoad(struct net_device *prNetDev, + uint32_t u4Gen_payload_rule, uint8_t ucPayload); +int32_t MT_ATESetTxSTBC(struct net_device *prNetDev, + uint32_t u4Stbc); +int32_t MT_ATESetTxPath(struct net_device *prNetDev, + uint32_t u4Tx_path); +int32_t MT_ATESetTxVhtNss(struct net_device *prNetDev, + uint32_t u4VhtNss); +int32_t MT_ATESetRate(struct net_device *prNetDev, + uint32_t u4Rate); +int32_t MT_ATESetEncodeMode(struct net_device *prNetDev, + uint32_t u4Ldpc); +int32_t MT_ATESetiBFEnable(struct net_device *prNetDev, + uint32_t u4iBF); +int32_t MT_ATESeteBFEnable(struct net_device *prNetDev, + uint32_t u4eBF); +int32_t MT_ATESetMACAddress(struct net_device *prNetDev, + uint32_t u4Type, uint8_t ucAddr[]); +int32_t MT_ATELogOnOff(struct net_device *prNetDev, + uint32_t u4Type, uint32_t u4On_off, uint32_t u4Size); +int32_t MT_ATEGetDumpRXV(struct net_device *prNetDev, + uint8_t *pData, int32_t *pCount); +int32_t MT_ATEResetTXRXCounter(struct net_device *prNetDev); +int32_t MT_ATESetDBDCBandIndex(struct net_device *prNetDev, + uint32_t u4BandIdx); +int32_t MT_ATESetBand(struct net_device *prNetDev, + int32_t i4Band); +int32_t MT_ATESetTxToneType(struct net_device *prNetDev, + int32_t i4ToneType); +int32_t MT_ATESetTxToneBW(struct net_device *prNetDev, + int32_t i4ToneFreq); +int32_t MT_ATESetTxToneDCOffset(struct net_device *prNetDev, + int32_t i4DcOffsetI, int32_t i4DcOffsetQ); +int32_t MT_ATESetDBDCTxTonePower(struct net_device *prNetDev, + int32_t i4AntIndex, int32_t i4RF_Power, int32_t i4Digi_Power); +int32_t MT_ATEDBDCTxTone(struct net_device *prNetDev, + int32_t i4Control); +int32_t MT_ATESetMacHeader(struct net_device *prNetDev, + uint32_t u2FrameCtrl, uint32_t u2DurationID, + uint32_t u4SeqCtrl); +int32_t MT_ATE_IRRSetADC(struct net_device *prNetDev, + uint32_t u4WFIdx, + uint32_t u4ChFreq, + uint32_t u4BW, uint32_t u4Sx, uint32_t u4Band, + uint32_t u4RunType, uint32_t u4FType); +int32_t MT_ATE_IRRSetRxGain(struct net_device *prNetDev, + uint32_t u4PgaLpfg, uint32_t u4Lna, uint32_t u4Band, + uint32_t u4WF_inx, uint32_t u4Rfdgc); +int32_t MT_ATE_IRRSetTTG(struct net_device *prNetDev, + uint32_t u4TTGPwrIdx, uint32_t u4ChFreq, + uint32_t u4FIToneFreq, uint32_t u4Band); +int32_t MT_ATE_IRRSetTrunOnTTG(struct net_device *prNetDev, uint32_t u4TTGOnOff, + uint32_t u4Band, uint32_t u4WF_inx); +int32_t MT_ATE_TMRSetting(struct net_device *prNetDev, uint32_t u4Setting, + uint32_t u4Version, uint32_t u4MPThres, uint32_t u4MPIter); +int32_t MT_ATERDDStart(struct net_device *prNetDev, + uint8_t *prInBuf); +int32_t MT_ATERDDStop(struct net_device *prNetDev, + uint8_t *prInBuf); +int32_t MT_ATEMPSSetSeqData(struct net_device *prNetDev, uint32_t u4TestNum, + uint32_t *pu4Phy, uint32_t u4Band); +int32_t MT_ATEMPSSetPayloadLength(struct net_device *prNetDev, + uint32_t u4TestNum, uint32_t *pu4Length, uint32_t u4Band); +int32_t MT_ATEMPSSetPacketCount(struct net_device *prNetDev, uint32_t u4TestNum, + uint32_t *pu4PktCnt, uint32_t u4Band); +int32_t MT_ATEMPSSetPowerGain(struct net_device *prNetDev, uint32_t u4TestNum, + uint32_t *pu4PwrGain, uint32_t u4Band); +int32_t MT_ATEMPSSetNss(struct net_device *prNetDev, + uint32_t u4TestNum, uint32_t *pu4Nss, uint32_t u4Band); +int32_t MT_ATEMPSSetPerpacketBW(struct net_device *prNetDev, uint32_t u4TestNum, + uint32_t *pu4PerPktBW, uint32_t u4Band); + + +int32_t MT_ATEWriteEfuse(struct net_device *prNetDev, + uint16_t u2Offset, uint16_t u2Content); +int32_t MT_ATESetTxTargetPower(struct net_device *prNetDev, + uint8_t ucTxTargetPower); + +#if CFG_SUPPORT_ANT_SWAP +int32_t MT_ATESetAntSwap(struct net_device *prNetDev, uint32_t u4Ant); +#endif + +#if (CFG_SUPPORT_DFS_MASTER == 1) +int32_t MT_ATESetRddReport(struct net_device *prNetDev, + uint8_t ucDbdcIdx); +int32_t MT_ATESetRadarDetectMode(struct net_device + *prNetDev, uint8_t ucRadarDetectMode); +#endif + + +#if CFG_SUPPORT_TX_BF +int32_t TxBfProfileTag_InValid(struct net_device *prNetDev, + union PFMU_PROFILE_TAG1 *prPfmuTag1, + uint8_t ucInValid); +int32_t TxBfProfileTag_PfmuIdx(struct net_device *prNetDev, + union PFMU_PROFILE_TAG1 *prPfmuTag1, + uint8_t ucProfileIdx); +int32_t TxBfProfileTag_TxBfType(struct net_device *prNetDev, + union PFMU_PROFILE_TAG1 *prPfmuTag1, + uint8_t ucBFType); +int32_t TxBfProfileTag_DBW(struct net_device *prNetDev, + union PFMU_PROFILE_TAG1 *prPfmuTag1, uint8_t ucBW); +int32_t TxBfProfileTag_SuMu(struct net_device *prNetDev, + union PFMU_PROFILE_TAG1 *prPfmuTag1, uint8_t ucSuMu); +int32_t TxBfProfileTag_Mem(struct net_device *prNetDev, + union PFMU_PROFILE_TAG1 *prPfmuTag1, + uint8_t *aucMemAddrColIdx, uint8_t *aucMemAddrRowIdx); +int32_t TxBfProfileTag_Matrix(struct net_device *prNetDev, + union PFMU_PROFILE_TAG1 *prPfmuTag1, + uint8_t ucNrow, + uint8_t ucNcol, uint8_t ucNgroup, uint8_t ucLM, + uint8_t ucCodeBook, uint8_t ucHtcExist); +int32_t TxBfProfileTag_SNR(struct net_device *prNetDev, + union PFMU_PROFILE_TAG1 *prPfmuTag1, + uint8_t ucSNR_STS0, uint8_t ucSNR_STS1, + uint8_t ucSNR_STS2, + uint8_t ucSNR_STS3); +int32_t TxBfProfileTag_SmtAnt(struct net_device *prNetDev, + union PFMU_PROFILE_TAG2 *prPfmuTag2, + uint8_t ucSmartAnt); +int32_t TxBfProfileTag_SeIdx(struct net_device *prNetDev, + union PFMU_PROFILE_TAG2 *prPfmuTag2, + uint8_t ucSeIdx); +int32_t TxBfProfileTag_RmsdThd(struct net_device *prNetDev, + union PFMU_PROFILE_TAG2 *prPfmuTag2, + uint8_t ucRmsdThrd); +int32_t TxBfProfileTag_McsThd(struct net_device *prNetDev, + union PFMU_PROFILE_TAG2 *prPfmuTag2, + uint8_t *pMCSThLSS, + uint8_t *pMCSThSSS); +int32_t TxBfProfileTag_TimeOut(struct net_device *prNetDev, + union PFMU_PROFILE_TAG2 *prPfmuTag2, + uint8_t ucTimeOut); +int32_t TxBfProfileTag_DesiredBW(struct net_device + *prNetDev, union PFMU_PROFILE_TAG2 *prPfmuTag2, + uint8_t ucDesiredBW); +int32_t TxBfProfileTag_DesiredNc(struct net_device + *prNetDev, union PFMU_PROFILE_TAG2 *prPfmuTag2, + uint8_t ucDesiredNc); +int32_t TxBfProfileTag_DesiredNr(struct net_device + *prNetDev, union PFMU_PROFILE_TAG2 *prPfmuTag2, + uint8_t ucDesiredNr); +int32_t TxBfProfileTagWrite(struct net_device *prNetDev, + union PFMU_PROFILE_TAG1 *prPfmuTag1, + union PFMU_PROFILE_TAG2 *prPfmuTag2, + uint8_t profileIdx); +int32_t TxBfProfileTagRead(struct net_device *prNetDev, + uint8_t PfmuIdx, uint8_t fgBFer); +int32_t TxBfProfileDataRead(struct net_device *prNetDev, + uint8_t profileIdx, uint8_t fgBFer, + uint8_t subcarrierIdxMsb, uint8_t subcarrierIdxLsb); +int32_t TxBfProfileDataWrite(struct net_device *prNetDev, + uint8_t profileIdx, + uint16_t subcarrierIdx, + uint16_t au2Phi[6], + uint8_t aucPsi[6], uint8_t aucDSnr[4] + ); +int32_t TxBfProfilePnRead(struct net_device *prNetDev, + uint8_t profileIdx); +int32_t TxBfProfilePnWrite(struct net_device *prNetDev, uint8_t ucProfileIdx, + uint16_t u2bw, uint16_t au2XSTS[12]); + +int32_t TxBfSounding(struct net_device *prNetDev, + uint8_t ucSuMu, /* 0/1/2/3 */ + uint8_t ucNumSta, /* 00~04 */ + uint8_t ucSndInterval, /* 00~FF */ + uint8_t ucWLan0, /* 00~7F */ + uint8_t ucWLan1, /* 00~7F */ + uint8_t ucWLan2, /* 00~7F */ + + uint8_t ucWLan3 /* 00~7F */ + ); +int32_t TxBfSoundingStop(struct net_device *prNetDev); +int32_t TxBfTxApply(struct net_device *prNetDev, + uint8_t ucWlanId, uint8_t fgETxBf, uint8_t fgITxBf, + uint8_t fgMuTxBf); + +int32_t TxBfManualAssoc(struct net_device *prNetDev, + uint8_t aucMac[MAC_ADDR_LEN], + uint8_t ucType, + uint8_t ucWtbl, + uint8_t ucOwnmac, + uint8_t ucPhyMode, + uint8_t ucBw, + uint8_t ucNss, uint8_t ucPfmuId, uint8_t ucMarate, + uint8_t ucSpeIdx, uint8_t ucRca2, uint8_t ucRv); + +int32_t TxBfPfmuMemAlloc(struct net_device *prNetDev, + uint8_t ucSuMuMode, uint8_t ucWlanIdx); + +int32_t TxBfPfmuMemRelease(struct net_device *prNetDev, + uint8_t ucWlanId); + +int32_t DevInfoUpdate(struct net_device *prNetDev, + uint8_t ucOwnMacIdx, uint8_t fgBand, + uint8_t aucMacAddr[MAC_ADDR_LEN]); + +int32_t BssInfoUpdate(struct net_device *prNetDev, + uint8_t u4OwnMacIdx, uint8_t u4BssIdx, + uint8_t u4BssId[MAC_ADDR_LEN]); + +int32_t StaRecCmmUpdate(struct net_device *prNetDev, + uint8_t ucWlanId, uint8_t ucBssId, uint8_t u4Aid, + uint8_t aucMacAddr[MAC_ADDR_LEN] + ); + +int32_t StaRecBfUpdate(struct net_device *prNetDev, + struct STA_REC_BF_UPD_ARGUMENT rStaRecBfUpdArg, + uint8_t aucMemRow[4], uint8_t aucMemCol[4] + ); + +#if CFG_SUPPORT_TX_BF_FPGA +int32_t TxBfPseudoTagUpdate(struct net_device *prNetDev, + uint8_t ucLm, uint8_t ucNr, + uint8_t ucNc, uint8_t ucBw, uint8_t ucCodeBook, + uint8_t ucGroup); +#endif + +#endif +#endif /*CFG_SUPPORT_QA_TOOL */ +#if (CONFIG_WLAN_SERVICE == 1) +uint32_t ServiceWlanOid(void *prNetDev, + uint32_t oidType, + void *param, + uint32_t paramLen, + uint32_t *u4BufLen, + void *rsp_data); +#endif /*#if (CONFIG_WLAN_SERVICE == 1)*/ + +#endif /* _GL_HOOK_API_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_kal.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_kal.h new file mode 100644 index 0000000000000000000000000000000000000000..d08a0211496986ecd832f3292871fdea69e6b0ca --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_kal.h @@ -0,0 +1,1841 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: /os/linux/include/gl_kal.h + */ + +/*! \file gl_kal.h + * \brief Declaration of KAL functions - kal*() which is provided + * by GLUE Layer. + * + * Any definitions in this file will be shared among GLUE Layer + * and internal Driver Stack. + */ + +#ifndef _GL_KAL_H +#define _GL_KAL_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "config.h" +#include "gl_typedef.h" +#include "gl_wext_priv.h" +#include "link.h" +#include "nic/mac.h" +#include "nic/wlan_def.h" +#include "wlan_lib.h" +#include "wlan_oid.h" + +#if CFG_ENABLE_BT_OVER_WIFI +#include "nic/bow.h" +#endif + +#include "linux/kallsyms.h" +#include "linux/sched.h" +#if KERNEL_VERSION(4, 11, 0) <= CFG80211_VERSION_CODE +#include "linux/sched/types.h" +#endif + +#if CFG_SUPPORT_SCAN_CACHE_RESULT +#include "wireless/core.h" +#endif + +#if DBG +extern int allocatedMemSize; +#endif + +extern struct semaphore g_halt_sem; +extern int g_u4HaltFlag; +extern int g_u4WlanInitFlag; + +extern struct delayed_work sched_workq; + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +/* Define how many concurrent operation networks. */ +#define KAL_BSS_NUM 4 + +#if CFG_SUPPORT_DUAL_STA +#define KAL_AIS_NUM 2 +#else +#define KAL_AIS_NUM 1 +#endif + +#if CFG_DUAL_P2PLIKE_INTERFACE +#define KAL_P2P_NUM 2 +#else +#define KAL_P2P_NUM 1 +#endif + +#if CFG_SUPPORT_MULTITHREAD +#define GLUE_FLAG_MAIN_PROCESS \ + (GLUE_FLAG_HALT | GLUE_FLAG_SUB_MOD_MULTICAST | \ + GLUE_FLAG_TX_CMD_DONE | GLUE_FLAG_TXREQ | GLUE_FLAG_TIMEOUT | \ + GLUE_FLAG_FRAME_FILTER | GLUE_FLAG_OID | GLUE_FLAG_RX | \ + GLUE_FLAG_SER_TIMEOUT) + +#define GLUE_FLAG_HIF_PROCESS \ + (GLUE_FLAG_HALT | GLUE_FLAG_INT | GLUE_FLAG_HIF_TX | \ + GLUE_FLAG_HIF_TX_CMD | GLUE_FLAG_HIF_FW_OWN | \ + GLUE_FLAG_HIF_PRT_HIF_DBG_INFO | \ + GLUE_FLAG_UPDATE_WMM_QUOTA | \ + GLUE_FLAG_NOTIFY_MD_CRASH | \ + GLUE_FLAG_DRV_INT) + +#define GLUE_FLAG_RX_PROCESS (GLUE_FLAG_HALT | GLUE_FLAG_RX_TO_OS) +#else +/* All flags for single thread driver */ +#define GLUE_FLAG_TX_PROCESS 0xFFFFFFFF +#endif + +#if CFG_SUPPORT_SNIFFER +#define RADIOTAP_FIELD_TSFT BIT(0) +#define RADIOTAP_FIELD_FLAGS BIT(1) +#define RADIOTAP_FIELD_RATE BIT(2) +#define RADIOTAP_FIELD_CHANNEL BIT(3) +#define RADIOTAP_FIELD_ANT_SIGNAL BIT(5) +#define RADIOTAP_FIELD_ANT_NOISE BIT(6) +#define RADIOTAP_FIELD_ANT BIT(11) +#define RADIOTAP_FIELD_MCS BIT(19) +#define RADIOTAP_FIELD_AMPDU BIT(20) +#define RADIOTAP_FIELD_VHT BIT(21) +#define RADIOTAP_FIELD_VENDOR BIT(30) + +#define RADIOTAP_LEN_VHT 48 +#define RADIOTAP_FIELDS_VHT (RADIOTAP_FIELD_TSFT | \ + RADIOTAP_FIELD_FLAGS | \ + RADIOTAP_FIELD_RATE | \ + RADIOTAP_FIELD_CHANNEL | \ + RADIOTAP_FIELD_ANT_SIGNAL | \ + RADIOTAP_FIELD_ANT_NOISE | \ + RADIOTAP_FIELD_ANT | \ + RADIOTAP_FIELD_AMPDU | \ + RADIOTAP_FIELD_VHT | \ + RADIOTAP_FIELD_VENDOR) + +#define RADIOTAP_LEN_HT 36 +#define RADIOTAP_FIELDS_HT (RADIOTAP_FIELD_TSFT | \ + RADIOTAP_FIELD_FLAGS | \ + RADIOTAP_FIELD_RATE | \ + RADIOTAP_FIELD_CHANNEL | \ + RADIOTAP_FIELD_ANT_SIGNAL | \ + RADIOTAP_FIELD_ANT_NOISE | \ + RADIOTAP_FIELD_ANT | \ + RADIOTAP_FIELD_MCS | \ + RADIOTAP_FIELD_AMPDU | \ + RADIOTAP_FIELD_VENDOR) + +#define RADIOTAP_LEN_LEGACY 26 +#define RADIOTAP_FIELDS_LEGACY (RADIOTAP_FIELD_TSFT | \ + RADIOTAP_FIELD_FLAGS | \ + RADIOTAP_FIELD_RATE | \ + RADIOTAP_FIELD_CHANNEL | \ + RADIOTAP_FIELD_ANT_SIGNAL | \ + RADIOTAP_FIELD_ANT_NOISE | \ + RADIOTAP_FIELD_ANT | \ + RADIOTAP_FIELD_VENDOR) +#endif + +#define PERF_MON_INIT_BIT (0) +#define PERF_MON_DISABLE_BIT (1) +#define PERF_MON_STOP_BIT (2) +#define PERF_MON_RUNNING_BIT (3) + +#define PERF_MON_UPDATE_INTERVAL (1000) +#define PERF_MON_TP_MAX_THRESHOLD (10) + +#define PERF_MON_TP_CONDITION (125000) + +#if CFG_SUPPORT_DATA_STALL +#define REPORT_EVENT_INTERVAL 30 +#define EVENT_PER_HIGH_THRESHOLD 80 +#define EVENT_TX_LOW_RATE_THRESHOLD 20 +#define EVENT_RX_LOW_RATE_THRESHOLD 20 +#define TRAFFIC_RHRESHOLD 150 +#endif + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +enum ENUM_SPIN_LOCK_CATEGORY_E { + SPIN_LOCK_FSM = 0, + +#if CFG_SUPPORT_MULTITHREAD + SPIN_LOCK_TX_PORT_QUE, + SPIN_LOCK_TX_CMD_QUE, + SPIN_LOCK_TX_CMD_DONE_QUE, + SPIN_LOCK_TC_RESOURCE, + SPIN_LOCK_RX_TO_OS_QUE, +#endif + + /* FIX ME */ + SPIN_LOCK_RX_QUE, + SPIN_LOCK_RX_FREE_QUE, + SPIN_LOCK_TX_QUE, + SPIN_LOCK_CMD_QUE, + SPIN_LOCK_TX_RESOURCE, + SPIN_LOCK_CMD_RESOURCE, + SPIN_LOCK_QM_TX_QUEUE, + SPIN_LOCK_CMD_PENDING, + SPIN_LOCK_CMD_SEQ_NUM, + SPIN_LOCK_TX_MSDU_INFO_LIST, + SPIN_LOCK_TXING_MGMT_LIST, + SPIN_LOCK_TX_SEQ_NUM, + SPIN_LOCK_TX_COUNT, + SPIN_LOCK_TXS_COUNT, + /* end */ + SPIN_LOCK_TX, + /* TX/RX Direct : BEGIN */ + SPIN_LOCK_TX_DIRECT, + SPIN_LOCK_RX_DIRECT, + SPIN_LOCK_RX_DIRECT_REORDER, + /* TX/RX Direct : END */ + SPIN_LOCK_IO_REQ, + SPIN_LOCK_INT, + SPIN_LOCK_UPDATE_WMM_QUOTA, + + SPIN_LOCK_MGT_BUF, + SPIN_LOCK_MSG_BUF, + SPIN_LOCK_STA_REC, + + SPIN_LOCK_MAILBOX, + SPIN_LOCK_TIMER, + + SPIN_LOCK_BOW_TABLE, + + SPIN_LOCK_EHPI_BUS, /* only for EHPI */ + SPIN_LOCK_NET_DEV, + + SPIN_LOCK_BSSLIST_FW, + SPIN_LOCK_BSSLIST_CFG, + SPIN_LOCK_NUM +}; + +enum ENUM_MUTEX_CATEGORY_E { + MUTEX_TX_CMD_CLEAR, + MUTEX_TX_DATA_DONE_QUE, + MUTEX_DEL_INF, + MUTEX_CHIP_RST, + MUTEX_SET_OWN, + MUTEX_BOOST_CPU, + MUTEX_NUM +}; + +/* event for assoc information update */ +struct EVENT_ASSOC_INFO { + uint8_t ucAssocReq; /* 1 for assoc req, 0 for assoc rsp */ + uint8_t ucReassoc; /* 0 for assoc, 1 for reassoc */ + uint16_t u2Length; + uint8_t *pucIe; +}; + +enum ENUM_KAL_NETWORK_TYPE_INDEX { + KAL_NETWORK_TYPE_AIS_INDEX = 0, +#if CFG_ENABLE_WIFI_DIRECT + KAL_NETWORK_TYPE_P2P_INDEX, +#endif +#if CFG_ENABLE_BT_OVER_WIFI + KAL_NETWORK_TYPE_BOW_INDEX, +#endif + KAL_NETWORK_TYPE_INDEX_NUM +}; + +enum ENUM_KAL_MEM_ALLOCATION_TYPE_E { + PHY_MEM_TYPE, /* physically continuous */ + VIR_MEM_TYPE, /* virtually continuous */ + MEM_TYPE_NUM +}; + +#ifdef CONFIG_ANDROID /* Defined in Android kernel source */ +#if (KERNEL_VERSION(4, 19, 0) <= CFG80211_VERSION_CODE) +#define KAL_WAKE_LOCK_T struct wakeup_source +#elif (KERNEL_VERSION(4, 9, 0) <= CFG80211_VERSION_CODE) +#define KAL_WAKE_LOCK_T struct wakeup_source +#else +#define KAL_WAKE_LOCK_T struct wake_lock +#endif +#else +#define KAL_WAKE_LOCK_T uint32_t +#endif + +#if CFG_SUPPORT_AGPS_ASSIST +enum ENUM_MTK_AGPS_ATTR { + MTK_ATTR_AGPS_INVALID, + MTK_ATTR_AGPS_CMD, + MTK_ATTR_AGPS_DATA, + MTK_ATTR_AGPS_IFINDEX, + MTK_ATTR_AGPS_IFNAME, + MTK_ATTR_AGPS_MAX +}; + +enum ENUM_AGPS_EVENT { + AGPS_EVENT_WLAN_ON, + AGPS_EVENT_WLAN_OFF, + AGPS_EVENT_WLAN_AP_LIST, +}; +u_int8_t kalIndicateAgpsNotify(struct ADAPTER *prAdapter, + uint8_t cmd, + uint8_t *data, uint16_t dataLen); +#endif /* CFG_SUPPORT_AGPS_ASSIST */ + +#if CFG_SUPPORT_SNIFFER +/* Vendor Namespace + * Bit Number 30 + * Required Alignment 2 bytes + */ +struct RADIOTAP_FIELD_VENDOR_ { + uint8_t aucOUI[3]; + uint8_t ucSubNamespace; + uint16_t u2DataLen; + uint8_t ucData; +} __KAL_ATTRIB_PACKED__; + +struct MONITOR_RADIOTAP { + /* radiotap header */ + uint8_t ucItVersion; /* set to 0 */ + uint8_t ucItPad; + uint16_t u2ItLen; /* entire length */ + uint32_t u4ItPresent; /* fields present */ + + /* TSFT + * Bit Number 0 + * Required Alignment 8 bytes + * Unit microseconds + */ + uint64_t u8MacTime; + + /* Flags + * Bit Number 1 + */ + uint8_t ucFlags; + + /* Rate + * Bit Number 2 + * Unit 500 Kbps + */ + uint8_t ucRate; + + /* Channel + * Bit Number 3 + * Required Alignment 2 bytes + */ + uint16_t u2ChFrequency; + uint16_t u2ChFlags; + + /* Antenna signal + * Bit Number 5 + * Unit dBm + */ + uint8_t ucAntennaSignal; + + /* Antenna noise + * Bit Number 6 + * Unit dBm + */ + uint8_t ucAntennaNoise; + + /* Antenna + * Bit Number 11 + * Unit antenna index + */ + uint8_t ucAntenna; + + /* MCS + * Bit Number 19 + * Required Alignment 1 byte + */ + uint8_t ucMcsKnown; + uint8_t ucMcsFlags; + uint8_t ucMcsMcs; + + /* A-MPDU status + * Bit Number 20 + * Required Alignment 4 bytes + */ + uint32_t u4AmpduRefNum; + uint16_t u2AmpduFlags; + uint8_t ucAmpduDelimiterCRC; + uint8_t ucAmpduReserved; + + /* VHT + * Bit Number 21 + * Required Alignment 2 bytes + */ + uint16_t u2VhtKnown; + uint8_t ucVhtFlags; + uint8_t ucVhtBandwidth; + uint8_t aucVhtMcsNss[4]; + uint8_t ucVhtCoding; + uint8_t ucVhtGroupId; + uint16_t u2VhtPartialAid; + + /* extension space */ + uint8_t aucReserve[12]; +} __KAL_ATTRIB_PACKED__; +#endif + +struct KAL_HALT_CTRL_T { + struct semaphore lock; + struct task_struct *owner; + u_int8_t fgHalt; + u_int8_t fgHeldByKalIoctl; + OS_SYSTIME u4HoldStart; +}; + +struct KAL_THREAD_SCHEDSTATS { + /* when marked: the profiling start time(ms), + * when unmarked: total duration(ms) + */ + unsigned long long time; + /* time spent in exec (sum_exec_runtime) */ + unsigned long long exec; + /* time spent in run-queue while not being scheduled (wait_sum) */ + unsigned long long runnable; + /* time spent waiting for I/O (iowait_sum) */ + unsigned long long iowait; +}; + +#if CFG_SUPPORT_DATA_STALL +enum ENUM_VENDOR_DRIVER_EVENT { + EVENT_TEST_MODE, + EVENT_ARP_NO_RESPONSE, + EVENT_PER_HIGH, + EVENT_TX_LOW_RATE, + EVENT_RX_LOW_RATE, + EVENT_SG_DISABLE, + EVENT_SG_1T1R, + EVENT_SG_2T2R, + EVENT_TX_DUP_OFF = 100, + EVENT_TX_DUP_ON = 101, + EVENT_TX_DUP_CERT_CHANGE = 102 +}; +#endif + +enum ENUM_CMD_TX_RESULT { + CMD_TX_RESULT_SUCCESS, + CMD_TX_RESULT_FAILED, + CMD_TX_RESULT_QUEUED, + CMD_TX_RESULT_NUM +}; + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +#define KAL_SET_BIT(bitOffset, value) set_bit(bitOffset, &value) +#define KAL_CLR_BIT(bitOffset, value) clear_bit(bitOffset, &value) +#define KAL_TEST_AND_CLEAR_BIT(bitOffset, value) \ + test_and_clear_bit(bitOffset, &value) +#define KAL_TEST_BIT(bitOffset, value) test_bit(bitOffset, &value) +#define SUSPEND_FLAG_FOR_WAKEUP_REASON (0) +#define SUSPEND_FLAG_CLEAR_WHEN_RESUME (1) + + +/*----------------------------------------------------------------------------*/ +/* Macros of getting current thread id */ +/*----------------------------------------------------------------------------*/ +#define KAL_GET_CURRENT_THREAD_ID() (current->pid) +#define KAL_GET_CURRENT_THREAD_NAME() (current->comm) + +/*----------------------------------------------------------------------------*/ +/* Macros of SPIN LOCK operations for using in Driver Layer */ +/*----------------------------------------------------------------------------*/ +#define KAL_SPIN_LOCK_DECLARATION() unsigned long __ulFlags + +#define KAL_ACQUIRE_SPIN_LOCK(_prAdapter, _rLockCategory) \ + kalAcquireSpinLock(((struct ADAPTER *)_prAdapter)->prGlueInfo, \ + _rLockCategory, &__ulFlags) + +#define KAL_RELEASE_SPIN_LOCK(_prAdapter, _rLockCategory) \ + kalReleaseSpinLock(((struct ADAPTER *)_prAdapter)->prGlueInfo, \ + _rLockCategory, __ulFlags) + +/*----------------------------------------------------------------------------*/ +/* Macros of MUTEX operations for using in Driver Layer */ +/*----------------------------------------------------------------------------*/ +#define KAL_ACQUIRE_MUTEX(_prAdapter, _rLockCategory) \ + kalAcquireMutex(((struct ADAPTER *)_prAdapter)->prGlueInfo, \ + _rLockCategory) + +#define KAL_RELEASE_MUTEX(_prAdapter, _rLockCategory) \ + kalReleaseMutex(((struct ADAPTER *)_prAdapter)->prGlueInfo, \ + _rLockCategory) + +/*----------------------------------------------------------------------------*/ +/* Macros for accessing Reserved Fields of native packet */ +/*----------------------------------------------------------------------------*/ +#define KAL_GET_PKT_QUEUE_ENTRY(_p) GLUE_GET_PKT_QUEUE_ENTRY(_p) +#define KAL_GET_PKT_DESCRIPTOR(_prQueueEntry) \ + GLUE_GET_PKT_DESCRIPTOR(_prQueueEntry) +#define KAL_GET_PKT_TID(_p) GLUE_GET_PKT_TID(_p) +#define KAL_GET_PKT_IS1X(_p) GLUE_GET_PKT_IS1X(_p) +#define KAL_GET_PKT_HEADER_LEN(_p) GLUE_GET_PKT_HEADER_LEN(_p) +#define KAL_GET_PKT_PAYLOAD_LEN(_p) GLUE_GET_PKT_PAYLOAD_LEN(_p) +#define KAL_GET_PKT_ARRIVAL_TIME(_p) GLUE_GET_PKT_ARRIVAL_TIME(_p) + +/*----------------------------------------------------------------------------*/ +/* Macros for kernel related defines */ +/*----------------------------------------------------------------------------*/ +#if KERNEL_VERSION(3, 14, 0) > CFG80211_VERSION_CODE +#define IEEE80211_CHAN_PASSIVE_FLAG IEEE80211_CHAN_PASSIVE_SCAN +#define IEEE80211_CHAN_PASSIVE_STR "PASSIVE" +#else +#define IEEE80211_CHAN_PASSIVE_FLAG IEEE80211_CHAN_NO_IR +#define IEEE80211_CHAN_PASSIVE_STR "NO_IR" +#endif + +#if KERNEL_VERSION(4, 7, 0) <= CFG80211_VERSION_CODE +/** + * enum nl80211_band - Frequency band + * @NL80211_BAND_2GHZ: 2.4 GHz ISM band + * @NL80211_BAND_5GHZ: around 5 GHz band (4.9 - 5.7 GHz) + * @NL80211_BAND_60GHZ: around 60 GHz band (58.32 - 64.80 GHz) + * @NUM_NL80211_BANDS: number of bands, avoid using this in userspace + * since newer kernel versions may support more bands + */ +#define KAL_BAND_2GHZ NL80211_BAND_2GHZ +#define KAL_BAND_5GHZ NL80211_BAND_5GHZ +#define KAL_NUM_BANDS NUM_NL80211_BANDS +#else +#define KAL_BAND_2GHZ IEEE80211_BAND_2GHZ +#define KAL_BAND_5GHZ IEEE80211_BAND_5GHZ +#define KAL_NUM_BANDS IEEE80211_NUM_BANDS +#endif + +/** + * enum nl80211_reg_rule_flags - regulatory rule flags + * @NL80211_RRF_NO_OFDM: OFDM modulation not allowed + * @NL80211_RRF_AUTO_BW: maximum available bandwidth should be calculated + * base on contiguous rules and wider channels will be allowed to cross + * multiple contiguous/overlapping frequency ranges. + * @NL80211_RRF_DFS: DFS support is required to be used + */ +#define KAL_RRF_NO_OFDM NL80211_RRF_NO_OFDM +#define KAL_RRF_DFS NL80211_RRF_DFS +#if KERNEL_VERSION(3, 15, 0) > CFG80211_VERSION_CODE +#define KAL_RRF_AUTO_BW 0 +#else +#define KAL_RRF_AUTO_BW NL80211_RRF_AUTO_BW +#endif + +/** + * kalCfg80211ScanDone - abstraction of cfg80211_scan_done + * + * @request: the corresponding scan request (sanity checked by callers!) + * @aborted: set to true if the scan was aborted for any reason, + * userspace will be notified of that + * + * Since linux-4.8.y the 2nd parameter is changed from bool to + * struct cfg80211_scan_info, but we don't use all fields yet. + */ +#if KERNEL_VERSION(4, 8, 0) <= CFG80211_VERSION_CODE +static inline void kalCfg80211ScanDone(struct cfg80211_scan_request *request, + bool aborted) +{ + struct cfg80211_scan_info info = {.aborted = aborted }; + + cfg80211_scan_done(request, &info); +} +#else +static inline void kalCfg80211ScanDone(struct cfg80211_scan_request *request, + bool aborted) +{ + cfg80211_scan_done(request, aborted); +} +#endif + +/* Consider on some Android platform, using request_firmware_direct() + * may cause system failed to load firmware. So we still use + * request_firmware(). + */ +#define REQUEST_FIRMWARE(_fw, _name, _dev) \ + request_firmware(_fw, _name, _dev) + +/*----------------------------------------------------------------------------*/ +/* Macros of wake_lock operations for using in Driver Layer */ +/*----------------------------------------------------------------------------*/ +#if defined(CONFIG_ANDROID) && (CFG_ENABLE_WAKE_LOCK) +/* CONFIG_ANDROID is defined in Android kernel source */ +#if (KERNEL_VERSION(4, 9, 0) <= LINUX_VERSION_CODE) +#if (KERNEL_VERSION(4, 14, 149) <= LINUX_VERSION_CODE) +#define KAL_WAKE_LOCK_INIT(_prAdapter, _prWakeLock, _pcName) \ + _prWakeLock = wakeup_source_register(NULL, _pcName); + +#define KAL_WAKE_LOCK_DESTROY(_prAdapter, _prWakeLock) \ +{ \ + wakeup_source_unregister(_prWakeLock); \ + _prWakeLock = NULL; \ +} +#else +#define KAL_WAKE_LOCK_INIT(_prAdapter, _prWakeLock, _pcName) \ +{ \ + _prWakeLock = kalMemAlloc(sizeof(KAL_WAKE_LOCK_T), \ + VIR_MEM_TYPE); \ + if (!_prWakeLock) { \ + DBGLOG(HAL, ERROR, \ + "KAL_WAKE_LOCK_INIT init fail!\n"); \ + } \ + else { \ + wakeup_source_init(_prWakeLock, _pcName); \ + } \ +} + +#define KAL_WAKE_LOCK_DESTROY(_prAdapter, _prWakeLock) \ +{ \ + if (_prWakeLock) { \ + wakeup_source_trash(_prWakeLock); \ + _prWakeLock = NULL; \ + } \ +} +#endif +#define KAL_WAKE_LOCK(_prAdapter, _prWakeLock) \ +{ \ + if (_prWakeLock) { \ + __pm_stay_awake(_prWakeLock); \ + } \ +} + +#define KAL_WAKE_LOCK_TIMEOUT(_prAdapter, _prWakeLock, _u4Timeout) \ +{ \ + if (_prWakeLock) { \ + __pm_wakeup_event(_prWakeLock, JIFFIES_TO_MSEC(_u4Timeout)); \ + } \ +} + +#define KAL_WAKE_UNLOCK(_prAdapter, _prWakeLock) \ +{ \ + if (_prWakeLock) { \ + __pm_relax(_prWakeLock); \ + } \ +} + +#define KAL_WAKE_LOCK_ACTIVE(_prAdapter, _prWakeLock) \ + ((_prWakeLock) && ((_prWakeLock)->active)) + +#else +#define KAL_WAKE_LOCK_INIT(_prAdapter, _prWakeLock, _pcName) \ +{ \ + _prWakeLock = kalMemAlloc(sizeof(KAL_WAKE_LOCK_T), \ + VIR_MEM_TYPE); \ + if (!_prWakeLock) { \ + DBGLOG(HAL, ERROR, \ + "KAL_WAKE_LOCK_INIT init fail!\n"); \ + } \ + else { \ + wake_lock_init(_prWakeLock, WAKE_LOCK_SUSPEND, _pcName); \ + } \ +} + +#define KAL_WAKE_LOCK_DESTROY(_prAdapter, _prWakeLock) \ +{ \ + if (_prWakeLock) { \ + wake_lock_destroy(_prWakeLock); \ + } \ +} + +#define KAL_WAKE_LOCK(_prAdapter, _prWakeLock) \ +{ \ + if (_prWakeLock) { \ + wake_lock(_prWakeLock); \ + } \ +} + +#define KAL_WAKE_LOCK_TIMEOUT(_prAdapter, _prWakeLock, _u4Timeout) \ +{ \ + if (_prWakeLock) { \ + wake_lock_timeout(_prWakeLock, _u4Timeout); \ + } \ +} + +#define KAL_WAKE_UNLOCK(_prAdapter, _prWakeLock) \ +{ \ + if (_prWakeLock) { \ + wake_unlock(_prWakeLock); \ + } \ +} + +#define KAL_WAKE_LOCK_ACTIVE(_prAdapter, _prWakeLock) \ + ((_prWakeLock) && wake_lock_active(_prWakeLock)) +#endif + +#else +#define KAL_WAKE_LOCK_INIT(_prAdapter, _prWakeLock, _pcName) +#define KAL_WAKE_LOCK_DESTROY(_prAdapter, _prWakeLock) +#define KAL_WAKE_LOCK(_prAdapter, _prWakeLock) +#define KAL_WAKE_LOCK_TIMEOUT(_prAdapter, _prWakeLock, _u4Timeout) +#define KAL_WAKE_UNLOCK(_prAdapter, _prWakeLock) +#define KAL_WAKE_LOCK_ACTIVE(_prAdapter, _prWakeLock) +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Cache memory allocation + * + * \param[in] u4Size Required memory size. + * \param[in] eMemType Memory allocation type + * + * \return Pointer to allocated memory + * or NULL + */ +/*----------------------------------------------------------------------------*/ +#if DBG +#define kalMemAlloc(u4Size, eMemType) ({ \ + void *pvAddr; \ + if (eMemType == PHY_MEM_TYPE) { \ + if (in_interrupt()) \ + pvAddr = kmalloc(u4Size, GFP_ATOMIC); \ + else \ + pvAddr = kmalloc(u4Size, GFP_KERNEL); \ + } \ + else { \ + if (u4Size > PAGE_SIZE) \ + pvAddr = vmalloc(u4Size); \ + else \ + pvAddr = kmalloc(u4Size, GFP_KERNEL); \ + } \ + if (pvAddr) { \ + allocatedMemSize += u4Size; \ + DBGLOG(INIT, INFO, "0x%p(%ld) allocated (%s:%s)\n", \ + pvAddr, (uint32_t)u4Size, __FILE__, __func__); \ + } \ + pvAddr; \ +}) +#else +#define kalMemAlloc(u4Size, eMemType) ({ \ + void *pvAddr; \ + if (eMemType == PHY_MEM_TYPE) { \ + if (in_interrupt()) \ + pvAddr = kmalloc(u4Size, GFP_ATOMIC); \ + else \ + pvAddr = kmalloc(u4Size, GFP_KERNEL); \ + } \ + else { \ + if (u4Size > PAGE_SIZE) \ + pvAddr = vmalloc(u4Size); \ + else \ + pvAddr = kmalloc(u4Size, GFP_KERNEL); \ + } \ + if (!pvAddr) \ + ASSERT_NOMEM(); \ + pvAddr; \ +}) +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Free allocated cache memory + * + * \param[in] pvAddr Required memory size. + * \param[in] eMemType Memory allocation type + * \param[in] u4Size Allocated memory size. + * + * \return - + */ +/*----------------------------------------------------------------------------*/ +#if DBG +#define kalMemFree(pvAddr, eMemType, u4Size) \ +{ \ + if (pvAddr) { \ + allocatedMemSize -= u4Size; \ + DBGLOG(INIT, INFO, "0x%p(%ld) freed (%s:%s)\n", \ + pvAddr, (uint32_t)u4Size, __FILE__, __func__); \ + } \ + kvfree(pvAddr); \ +} +#else +#define kalMemFree(pvAddr, eMemType, u4Size) \ +{ \ + kvfree(pvAddr); \ +} +#endif + +#define kalUdelay(u4USec) udelay(u4USec) + +#define kalMdelay(u4MSec) mdelay(u4MSec) +#define kalMsleep(u4MSec) msleep(u4MSec) +#define kalUsleep_range(u4MinUSec, u4MaxUSec) \ + usleep_range(u4MinUSec, u4MaxUSec) + +/* Copy memory from user space to kernel space */ +#define kalMemCopyFromUser(_pvTo, _pvFrom, _u4N) \ + copy_from_user(_pvTo, _pvFrom, _u4N) + +/* Copy memory from kernel space to user space */ +#define kalMemCopyToUser(_pvTo, _pvFrom, _u4N) \ + copy_to_user(_pvTo, _pvFrom, _u4N) + +/* Copy memory block with specific size */ +#define kalMemCopy(pvDst, pvSrc, u4Size) \ + memcpy(pvDst, pvSrc, u4Size) + +/* Set memory block with specific pattern */ +#define kalMemSet(pvAddr, ucPattern, u4Size) \ + memset(pvAddr, ucPattern, u4Size) + +/* Compare two memory block with specific length. + * Return zero if they are the same. + */ +#define kalMemCmp(pvAddr1, pvAddr2, u4Size) \ + memcmp(pvAddr1, pvAddr2, u4Size) + +/* Zero specific memory block */ +#define kalMemZero(pvAddr, u4Size) \ + memset(pvAddr, 0, u4Size) + +/* Move memory block with specific size */ +#define kalMemMove(pvDst, pvSrc, u4Size) \ + memmove(pvDst, pvSrc, u4Size) + +#if KERNEL_VERSION(4, 0, 0) <= LINUX_VERSION_CODE +#define strnicmp(s1, s2, n) strncasecmp(s1, s2, n) +#endif + +/* string operation */ +#define kalStrCpy(dest, src) strcpy(dest, src) +#define kalStrnCpy(dest, src, n) strncpy(dest, src, n) +#define kalStrCmp(ct, cs) strcmp(ct, cs) +#define kalStrnCmp(ct, cs, n) strncmp(ct, cs, n) +#define kalStrChr(s, c) strchr(s, c) +#define kalStrrChr(s, c) strrchr(s, c) +#define kalStrnChr(s, n, c) strnchr(s, n, c) +#define kalStrLen(s) strlen(s) +#define kalStrnLen(s, b) strnlen(s, b) +#define kalStrniCmp(ct, cs, n) strncasecmp(ct, cs, n) +/* #define kalStrtoul(cp, endp, base) simple_strtoul(cp, endp, base) */ +/* #define kalStrtol(cp, endp, base) simple_strtol(cp, endp, base) */ +#define kalkStrtou8(cp, base, resp) kstrtou8(cp, base, resp) +#define kalkStrtou16(cp, base, resp) kstrtou16(cp, base, resp) +#define kalkStrtou32(cp, base, resp) kstrtou32(cp, base, resp) +#define kalkStrtos32(cp, base, resp) kstrtos32(cp, base, resp) +#define kalSnprintf(buf, size, fmt, ...) \ + _kalSnprintf((char *)(buf), (size_t)(size), \ + (const char *)(fmt), ##__VA_ARGS__) +#define kalScnprintf(buf, size, fmt, ...) \ + scnprintf(buf, size, fmt, ##__VA_ARGS__) +#define kalSprintf(buf, fmt, ...) \ + _kalSprintf((char *)(buf), (const char *)(fmt), ##__VA_ARGS__) +/* remove for AOSP */ +/* #define kalSScanf(buf, fmt, ...) sscanf(buf, fmt, __VA_ARGS__) */ +#define kalStrStr(ct, cs) strstr(ct, cs) +#define kalStrSep(s, ct) strsep(s, ct) +#define kalStrCat(dest, src) strcat(dest, src) +#define kalIsXdigit(c) isxdigit(c) +#define kalStrtoint(_data, _base, _res) kstrtoint(_data, _base, _res) +#define kalStrtoul(_data, _base, _res) kstrtoul(_data, _base, _res) + +int8_t *strtok_r(int8_t *s, const int8_t *delim, int8_t **last); +#define kalStrtokR(_buf, _tok, _saved) \ + strtok_r((int8_t *)_buf, _tok, (int8_t **)_saved) + +int8_t atoi(uint8_t ch); +#define kalAtoi(_ch) atoi(_ch) + +/* defined for wince sdio driver only */ +#if defined(_HIF_SDIO) +#define kalDevSetPowerState(prGlueInfo, ePowerMode) \ + glSetPowerState(prGlueInfo, ePowerMode) +#else +#define kalDevSetPowerState(prGlueInfo, ePowerMode) +#endif + +#if CFG_MTK_ANDROID_WMT +#define _kalRequestFirmware request_firmware_direct +#else +#define _kalRequestFirmware request_firmware +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Notify OS with SendComplete event of the specific packet. + * Linux should free packets here. + * + * \param[in] prGlueInfo Pointer of GLUE Data Structure + * \param[in] pvPacket Pointer of Packet Handle + * \param[in] status Status Code for OS upper layer + * + * \return - + */ +/*----------------------------------------------------------------------------*/ +#define kalSendComplete(prGlueInfo, pvPacket, status) \ + kalSendCompleteAndAwakeQueue(prGlueInfo, pvPacket) + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is used to locate the starting address of incoming + * ethernet frame for skb. + * + * \param[in] prGlueInfo Pointer of GLUE Data Structure + * \param[in] pvPacket Pointer of Packet Handle + * + * \return starting address of ethernet frame buffer. + */ +/*----------------------------------------------------------------------------*/ +#define kalQueryBufferPointer(prGlueInfo, pvPacket) \ + ((uint8_t *)((struct sk_buff *)pvPacket)->data) + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is used to query the length of valid buffer which is + * accessible during port read/write. + * + * \param[in] prGlueInfo Pointer of GLUE Data Structure + * \param[in] pvPacket Pointer of Packet Handle + * + * \return starting address of ethernet frame buffer. + */ +/*----------------------------------------------------------------------------*/ +#define kalQueryValidBufferLength(prGlueInfo, pvPacket) \ + ((uint32_t)((struct sk_buff *)pvPacket)->end - \ + (uint32_t)((struct sk_buff *)pvPacket)->data) + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is used to copy the entire frame from skb to the + * destination address in the input parameter. + * + * \param[in] prGlueInfo Pointer of GLUE Data Structure + * \param[in] pvPacket Pointer of Packet Handle + * \param[in] pucDestBuffer Destination Address + * + * \return - + */ +/*----------------------------------------------------------------------------*/ +#define kalCopyFrame(prGlueInfo, pvPacket, pucDestBuffer) \ + do {struct sk_buff *skb = (struct sk_buff *)pvPacket; \ + memcpy(pucDestBuffer, skb->data, skb->len); } while (0) + +#define kalGetTimeTick() jiffies_to_msecs(jiffies) + +#define WLAN_TAG "[wlan]" +#define kalPrint(_Fmt...) pr_info(WLAN_TAG _Fmt) +#define kalPrintLimited(_Fmt...) pr_info_ratelimited(WLAN_TAG _Fmt) + +#define kalBreakPoint() \ +do { \ + WARN_ON(1); \ + panic("Oops"); \ +} while (0) + +#if CFG_ENABLE_AEE_MSG +#define kalSendAeeException aee_kernel_exception +#define kalSendAeeWarning aee_kernel_warning +#define kalSendAeeReminding aee_kernel_reminding +#else +#define kalSendAeeException(_module, _desc, ...) +#define kalSendAeeWarning(_module, _desc, ...) +#define kalSendAeeReminding(_module, _desc, ...) +#endif + +#define PRINTF_ARG(...) __VA_ARGS__ +#define SPRINTF(buf, arg) {buf += sprintf((char *)(buf), PRINTF_ARG arg); } + +#define USEC_TO_SYSTIME(_usec) ((_usec) / USEC_PER_MSEC) +#define MSEC_TO_SYSTIME(_msec) (_msec) + +#define MSEC_TO_JIFFIES(_msec) msecs_to_jiffies(_msec) +#define JIFFIES_TO_MSEC(_jiffie) jiffies_to_msecs(_jiffie) + +#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE +#define do_gettimeofday(_tv) kal_do_gettimeofday(_tv) +#define get_ds() KERNEL_DS +#define kal_access_ok(type, addr, size) access_ok(addr, size) +#else +#define kal_access_ok(type, addr, size) access_ok(type, addr, size) +#endif + +#define KAL_TIME_INTERVAL_DECLARATION() struct timeval __rTs, __rTe +#define KAL_REC_TIME_START() do_gettimeofday(&__rTs) +#define KAL_REC_TIME_END() do_gettimeofday(&__rTe) +#define KAL_GET_TIME_INTERVAL() \ + ((SEC_TO_USEC(__rTe.tv_sec) + __rTe.tv_usec) - \ + (SEC_TO_USEC(__rTs.tv_sec) + __rTs.tv_usec)) +#define KAL_ADD_TIME_INTERVAL(_Interval) \ + { \ + (_Interval) += KAL_GET_TIME_INTERVAL(); \ + } + +#if defined(_HIF_PCIE) +#define KAL_DMA_TO_DEVICE PCI_DMA_TODEVICE +#define KAL_DMA_FROM_DEVICE PCI_DMA_FROMDEVICE + +#define KAL_DMA_ALLOC_COHERENT(_dev, _size, _handle) \ + pci_alloc_consistent(_dev, _size, _handle) +#define KAL_DMA_FREE_COHERENT(_dev, _size, _addr, _handle) \ + pci_free_consistent(_dev, _size, _addr, _handle) +#define KAL_DMA_MAP_SINGLE(_dev, _ptr, _size, _dir) \ + pci_map_single(_dev, _ptr, _size, _dir) +#define KAL_DMA_UNMAP_SINGLE(_dev, _addr, _size, _dir) \ + pci_unmap_single(_dev, _addr, _size, _dir) +#define KAL_DMA_MAPPING_ERROR(_dev, _addr) \ + pci_dma_mapping_error(_dev, _addr) +#else +#define KAL_DMA_TO_DEVICE DMA_TO_DEVICE +#define KAL_DMA_FROM_DEVICE DMA_FROM_DEVICE + +#define KAL_DMA_ALLOC_COHERENT(_dev, _size, _handle) \ + dma_alloc_coherent(_dev, _size, _handle, GFP_DMA) +#define KAL_DMA_FREE_COHERENT(_dev, _size, _addr, _handle) \ + dma_free_coherent(_dev, _size, _addr, _handle) +#define KAL_DMA_MAP_SINGLE(_dev, _ptr, _size, _dir) \ + dma_map_single(_dev, _ptr, _size, _dir) +#define KAL_DMA_UNMAP_SINGLE(_dev, _addr, _size, _dir) \ + dma_unmap_single(_dev, _addr, _size, _dir) +#define KAL_DMA_MAPPING_ERROR(_dev, _addr) \ + dma_mapping_error(_dev, _addr) +#endif + +#if CFG_SUPPORT_DATA_STALL +#define KAL_REPORT_ERROR_EVENT kalIndicateDriverEvent +#endif + +#if CFG_SUPPORT_BIGDATA_PIP +#define KAL_REPORT_BIGDATA_PIP kalBigDataPip +#endif + +/*----------------------------------------------------------------------------*/ +/* Macros of show stack operations for using in Driver Layer */ +/*----------------------------------------------------------------------------*/ +#if CFG_MTK_ANDROID_WMT +#define kal_show_stack(_adapter, _task, _sp) \ + connectivity_export_show_stack(_task, _sp) +#else +#define kal_show_stack(_adapter, _task, _sp) +#endif + +/*----------------------------------------------------------------------------*/ +/* Macros of systrace operations for using in Driver Layer */ +/*----------------------------------------------------------------------------*/ +#if !CONFIG_WLAN_DRV_BUILD_IN + +#define kalTraceBegin(_fmt, ...) \ + tracing_mark_write("B|%d|" _fmt "\n", current->tgid, ##__VA_ARGS__) + +#define kalTraceEnd() \ + tracing_mark_write("E|%d\n", current->tgid) + +#define kalTraceInt(_value, _fmt, ...) \ + tracing_mark_write("C|%d|" _fmt "|%d\n", \ + current->tgid, ##__VA_ARGS__, _value) + +#define kalTraceCall() \ + { kalTraceBegin("%s", __func__); kalTraceEnd(); } + +#define kalTraceEvent(_fmt, ...) \ + { kalTraceBegin(_fmt, ##__VA_ARGS__); kalTraceEnd(); } + +#define __type_is_void(expr) __builtin_types_compatible_p(typeof(expr), void) +#define __expr_zero(expr) __builtin_choose_expr(__type_is_void(expr), 0, (expr)) + +#define TRACE(_expr, _fmt, ...) \ + __builtin_choose_expr(__type_is_void(_expr), \ + __TRACE_VOID(_expr, _fmt, ##__VA_ARGS__), \ + __TRACE(__expr_zero(_expr), _fmt, ##__VA_ARGS__)) + +#define __TRACE(_expr, _fmt, ...) \ + ({ \ + typeof(_expr) __ret; \ + kalTraceBegin(_fmt, ##__VA_ARGS__); \ + __ret = (_expr); \ + kalTraceEnd(); \ + __ret; \ + }) + +#define __TRACE_VOID(_expr, _fmt, ...) \ + ({ \ + kalTraceBegin(_fmt, ##__VA_ARGS__); \ + (void) (_expr); \ + kalTraceEnd(); \ + }) +#else + +#define kalTraceBegin(_fmt, ...) +#define kalTraceEnd() +#define kalTraceInt(_value, _fmt, ...) +#define kalTraceCall() +#define kalTraceEvent(_fmt, ...) +#define TRACE(_expr, _fmt, ...) _expr + +#endif +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +/*----------------------------------------------------------------------------*/ +/* Routines in gl_kal.c */ +/*----------------------------------------------------------------------------*/ +void kalAcquireSpinLock(IN struct GLUE_INFO *prGlueInfo, + IN enum ENUM_SPIN_LOCK_CATEGORY_E rLockCategory, + OUT unsigned long *plFlags); + +void kalReleaseSpinLock(IN struct GLUE_INFO *prGlueInfo, + IN enum ENUM_SPIN_LOCK_CATEGORY_E rLockCategory, + IN unsigned long ulFlags); + +void kalUpdateMACAddress(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t *pucMacAddr); + +void kalAcquireMutex(IN struct GLUE_INFO *prGlueInfo, + IN enum ENUM_MUTEX_CATEGORY_E rMutexCategory); + +void kalReleaseMutex(IN struct GLUE_INFO *prGlueInfo, + IN enum ENUM_MUTEX_CATEGORY_E rMutexCategory); + +void kalPacketFree(IN struct GLUE_INFO *prGlueInfo, + IN void *pvPacket); + +void *kalPacketAlloc(IN struct GLUE_INFO *prGlueInfo, + IN uint32_t u4Size, + OUT uint8_t **ppucData); + +void *kalPacketAllocWithHeadroom(IN struct GLUE_INFO + *prGlueInfo, + IN uint32_t u4Size, OUT uint8_t **ppucData); + +void kalOsTimerInitialize(IN struct GLUE_INFO *prGlueInfo, + IN void *prTimerHandler); + +u_int8_t kalSetTimer(IN struct GLUE_INFO *prGlueInfo, + IN OS_SYSTIME rInterval); + +uint32_t +kalProcessRxPacket(IN struct GLUE_INFO *prGlueInfo, + IN void *pvPacket, + IN uint8_t *pucPacketStart, IN uint32_t u4PacketLen, + /* IN PBOOLEAN pfgIsRetain, */ + IN u_int8_t fgIsRetain, IN enum ENUM_CSUM_RESULT aeCSUM[]); + +uint32_t kalRxIndicatePkts(IN struct GLUE_INFO *prGlueInfo, + IN void *apvPkts[], + IN uint8_t ucPktNum); + +uint32_t kalRxIndicateOnePkt(IN struct GLUE_INFO + *prGlueInfo, IN void *pvPkt); + +void +kalIndicateStatusAndComplete(IN struct GLUE_INFO + *prGlueInfo, + IN uint32_t eStatus, IN void *pvBuf, + IN uint32_t u4BufLen, + IN uint8_t ucBssIndex); + +void +kalUpdateReAssocReqInfo(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t *pucFrameBody, IN uint32_t u4FrameBodyLen, + IN u_int8_t fgReassocRequest, + IN uint8_t ucBssIndex); + +void kalUpdateReAssocRspInfo(IN struct GLUE_INFO + *prGlueInfo, + IN uint8_t *pucFrameBody, + IN uint32_t u4FrameBodyLen, + IN uint8_t ucBssIndex); + +#if CFG_TX_FRAGMENT +u_int8_t +kalQueryTxPacketHeader(IN struct GLUE_INFO *prGlueInfo, + IN void *pvPacket, OUT uint16_t *pu2EtherTypeLen, + OUT uint8_t *pucEthDestAddr); +#endif /* CFG_TX_FRAGMENT */ + +void kalSendCompleteAndAwakeQueue(IN struct GLUE_INFO + *prGlueInfo, + IN void *pvPacket); + +#if CFG_TCP_IP_CHKSUM_OFFLOAD +void kalQueryTxChksumOffloadParam(IN void *pvPacket, + OUT uint8_t *pucFlag); + +void kalUpdateRxCSUMOffloadParam(IN void *pvPacket, + IN enum ENUM_CSUM_RESULT eCSUM[]); +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ + +u_int8_t kalRetrieveNetworkAddress(IN struct GLUE_INFO *prGlueInfo, + IN OUT uint8_t *prMacAddr); + +void +kalReadyOnChannel(IN struct GLUE_INFO *prGlueInfo, + IN uint64_t u8Cookie, + IN enum ENUM_BAND eBand, IN enum ENUM_CHNL_EXT eSco, + IN uint8_t ucChannelNum, IN uint32_t u4DurationMs, + IN uint8_t ucBssIndex); + +void +kalRemainOnChannelExpired(IN struct GLUE_INFO *prGlueInfo, + IN uint64_t u8Cookie, IN enum ENUM_BAND eBand, + IN enum ENUM_CHNL_EXT eSco, IN uint8_t ucChannelNum, + IN uint8_t ucBssIndex); + +#if CFG_SUPPORT_DFS +void +kalIndicateChannelSwitch(IN struct GLUE_INFO *prGlueInfo, + IN enum ENUM_CHNL_EXT eSco, + IN uint8_t ucChannelNum); +#endif + +void +kalIndicateMgmtTxStatus(IN struct GLUE_INFO *prGlueInfo, + IN uint64_t u8Cookie, IN u_int8_t fgIsAck, + IN uint8_t *pucFrameBuf, IN uint32_t u4FrameLen, + IN uint8_t ucBssIndex); + +void kalIndicateRxMgmtFrame(IN struct GLUE_INFO *prGlueInfo, + IN struct SW_RFB *prSwRfb, + IN uint8_t ucBssIndex); + +#if CFG_SUPPORT_DATA_STALL +u_int8_t kalIndicateDriverEvent(struct ADAPTER *prAdapter, + uint32_t event, + uint16_t dataLen, + uint8_t ucBssIdx, + u_int8_t fgForceReport); +#endif + +#if CFG_SUPPORT_BIGDATA_PIP +int8_t kalBigDataPip(struct ADAPTER *prAdapter, + uint8_t *payload, + uint16_t dataLen); +#endif + +/*----------------------------------------------------------------------------*/ +/* Routines in interface - ehpi/sdio.c */ +/*----------------------------------------------------------------------------*/ +u_int8_t kalDevRegRead(IN struct GLUE_INFO *prGlueInfo, + IN uint32_t u4Register, + OUT uint32_t *pu4Value); +u_int8_t kalDevRegRead_mac(IN struct GLUE_INFO *prGlueInfo, + IN uint32_t u4Register, OUT uint32_t *pu4Value); + +u_int8_t kalDevRegWrite(struct GLUE_INFO *prGlueInfo, + IN uint32_t u4Register, + IN uint32_t u4Value); +u_int8_t kalDevRegWrite_mac(struct GLUE_INFO *prGlueInfo, + IN uint32_t u4Register, IN uint32_t u4Value); + +u_int8_t +kalDevPortRead(IN struct GLUE_INFO *prGlueInfo, + IN uint16_t u2Port, IN uint32_t u2Len, OUT uint8_t *pucBuf, + IN uint32_t u2ValidOutBufSize); + +u_int8_t +kalDevPortWrite(struct GLUE_INFO *prGlueInfo, + IN uint16_t u2Port, IN uint32_t u2Len, IN uint8_t *pucBuf, + IN uint32_t u2ValidInBufSize); + +u_int8_t kalDevWriteData(IN struct GLUE_INFO *prGlueInfo, + IN struct MSDU_INFO *prMsduInfo); +enum ENUM_CMD_TX_RESULT kalDevWriteCmd(IN struct GLUE_INFO *prGlueInfo, + IN struct CMD_INFO *prCmdInfo, IN uint8_t ucTC); +u_int8_t kalDevKickData(IN struct GLUE_INFO *prGlueInfo); +void kalDevReadIntStatus(IN struct ADAPTER *prAdapter, + OUT uint32_t *pu4IntStatus); + +u_int8_t kalDevWriteWithSdioCmd52(IN struct GLUE_INFO + *prGlueInfo, + IN uint32_t u4Addr, IN uint8_t ucData); + +#if CFG_SUPPORT_EXT_CONFIG +uint32_t kalReadExtCfg(IN struct GLUE_INFO *prGlueInfo); +#endif + +u_int8_t +kalQoSFrameClassifierAndPacketInfo(IN struct GLUE_INFO + *prGlueInfo, + IN void *prPacket, + OUT struct TX_PACKET_INFO *prTxPktInfo); + +u_int8_t kalGetEthDestAddr(IN struct GLUE_INFO *prGlueInfo, + IN void *prPacket, + OUT uint8_t *pucEthDestAddr); + +void +kalOidComplete(IN struct GLUE_INFO *prGlueInfo, + IN u_int8_t fgSetQuery, IN uint32_t u4SetQueryInfoLen, + IN uint32_t rOidStatus); + +uint32_t +kalIoctl(IN struct GLUE_INFO *prGlueInfo, + IN PFN_OID_HANDLER_FUNC pfnOidHandler, + IN void *pvInfoBuf, + IN uint32_t u4InfoBufLen, IN u_int8_t fgRead, + IN u_int8_t fgWaitResp, + IN u_int8_t fgCmd, OUT uint32_t *pu4QryInfoLen); + +uint32_t +kalIoctlByBssIdx(IN struct GLUE_INFO *prGlueInfo, + IN PFN_OID_HANDLER_FUNC pfnOidHandler, + IN void *pvInfoBuf, + IN uint32_t u4InfoBufLen, IN u_int8_t fgRead, + IN u_int8_t fgWaitResp, IN u_int8_t fgCmd, + OUT uint32_t *pu4QryInfoLen, + IN uint8_t ucBssIndex); + +void SET_IOCTL_BSSIDX( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +uint8_t GET_IOCTL_BSSIDX( + IN struct ADAPTER *prAdapter); + +void kalHandleAssocInfo(IN struct GLUE_INFO *prGlueInfo, + IN struct EVENT_ASSOC_INFO *prAssocInfo); + +#if CFG_ENABLE_FW_DOWNLOAD +void *kalFirmwareImageMapping(IN struct GLUE_INFO + *prGlueInfo, + OUT void **ppvMapFileBuf, + OUT uint32_t *pu4FileLength, + IN enum ENUM_IMG_DL_IDX_T eDlIdx); +void kalFirmwareImageUnmapping(IN struct GLUE_INFO + *prGlueInfo, + IN void *prFwHandle, IN void *pvMapFileBuf); +#endif + +#if CFG_CHIP_RESET_SUPPORT +void kalRemoveProbe(IN struct GLUE_INFO *prGlueInfo); +#endif +/*----------------------------------------------------------------------------*/ +/* Card Removal Check */ +/*----------------------------------------------------------------------------*/ +u_int8_t kalIsCardRemoved(IN struct GLUE_INFO *prGlueInfo); + +/*----------------------------------------------------------------------------*/ +/* TX */ +/*----------------------------------------------------------------------------*/ +void kalFlushPendingTxPackets(IN struct GLUE_INFO + *prGlueInfo); + +/*----------------------------------------------------------------------------*/ +/* Media State Indication */ +/*----------------------------------------------------------------------------*/ +enum ENUM_PARAM_MEDIA_STATE kalGetMediaStateIndicated( + IN struct GLUE_INFO + *prGlueInfo, IN uint8_t ucBssIndex); + +void kalSetMediaStateIndicated(IN struct GLUE_INFO *prGlueInfo, + IN enum ENUM_PARAM_MEDIA_STATE eParamMediaStateIndicate, + IN uint8_t ucBssIndex); + +/*----------------------------------------------------------------------------*/ +/* OID handling */ +/*----------------------------------------------------------------------------*/ +void kalOidCmdClearance(IN struct GLUE_INFO *prGlueInfo); + +void kalOidClearance(IN struct GLUE_INFO *prGlueInfo); + +void kalEnqueueCommand(IN struct GLUE_INFO *prGlueInfo, + IN struct QUE_ENTRY *prQueueEntry); + +#if CFG_ENABLE_BT_OVER_WIFI +/*----------------------------------------------------------------------------*/ +/* Bluetooth over Wi-Fi handling */ +/*----------------------------------------------------------------------------*/ +void kalIndicateBOWEvent(IN struct GLUE_INFO *prGlueInfo, + IN struct BT_OVER_WIFI_EVENT *prEvent); + +enum ENUM_BOW_DEVICE_STATE kalGetBowState( + IN struct GLUE_INFO *prGlueInfo, + IN uint8_t rPeerAddr[PARAM_MAC_ADDR_LEN]); + +u_int8_t kalSetBowState(IN struct GLUE_INFO *prGlueInfo, + IN enum ENUM_BOW_DEVICE_STATE eBowState, + uint8_t rPeerAddr[PARAM_MAC_ADDR_LEN]); + +enum ENUM_BOW_DEVICE_STATE kalGetBowGlobalState( + IN struct GLUE_INFO + *prGlueInfo); + +uint32_t kalGetBowFreqInKHz(IN struct GLUE_INFO + *prGlueInfo); + +uint8_t kalGetBowRole(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t rPeerAddr[PARAM_MAC_ADDR_LEN]); + +void kalSetBowRole(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRole, + IN uint8_t rPeerAddr[PARAM_MAC_ADDR_LEN]); + +uint8_t kalGetBowAvailablePhysicalLinkCount( + IN struct GLUE_INFO *prGlueInfo); + +#if CFG_BOW_SEPARATE_DATA_PATH +/*----------------------------------------------------------------------------*/ +/* Bluetooth over Wi-Fi Net Device Init/Uninit */ +/*----------------------------------------------------------------------------*/ +u_int8_t kalInitBowDevice(IN struct GLUE_INFO *prGlueInfo, + IN const char *prDevName); + +u_int8_t kalUninitBowDevice(IN struct GLUE_INFO + *prGlueInfo); +#endif /* CFG_BOW_SEPARATE_DATA_PATH */ +#endif /* CFG_ENABLE_BT_OVER_WIFI */ + +/*----------------------------------------------------------------------------*/ +/* Security Frame Clearance */ +/*----------------------------------------------------------------------------*/ +void kalClearSecurityFrames(IN struct GLUE_INFO + *prGlueInfo); + +void kalClearSecurityFramesByBssIdx(IN struct GLUE_INFO + *prGlueInfo, + IN uint8_t ucBssIndex); + +void kalSecurityFrameSendComplete(IN struct GLUE_INFO + *prGlueInfo, + IN void *pvPacket, IN uint32_t rStatus); + +/*----------------------------------------------------------------------------*/ +/* Management Frame Clearance */ +/*----------------------------------------------------------------------------*/ +void kalClearMgmtFrames(IN struct GLUE_INFO *prGlueInfo); + +void kalClearMgmtFramesByBssIdx(IN struct GLUE_INFO + *prGlueInfo, + IN uint8_t ucBssIndex); + +uint32_t kalGetTxPendingFrameCount(IN struct GLUE_INFO + *prGlueInfo); + +uint32_t kalGetTxPendingCmdCount(IN struct GLUE_INFO + *prGlueInfo); + +void kalClearCommandQueue(IN struct GLUE_INFO *prGlueInfo); + +u_int8_t kalSetTimer(IN struct GLUE_INFO *prGlueInfo, + IN uint32_t u4Interval); + +u_int8_t kalCancelTimer(IN struct GLUE_INFO *prGlueInfo); + +void kalScanDone(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucBssIndex, + IN uint32_t status); + +#if CFG_SUPPORT_SCAN_CACHE_RESULT +uint8_t kalUpdateBssTimestamp(IN struct GLUE_INFO *prGlueInfo); +#endif /* CFG_SUPPORT_SCAN_CACHE_RESULT */ + +uint32_t kalRandomNumber(void); + +#if KERNEL_VERSION(4, 15, 0) <= LINUX_VERSION_CODE +void kalTimeoutHandler(struct timer_list *timer); +#else +void kalTimeoutHandler(unsigned long arg); +#endif + +void kalSetEvent(struct GLUE_INFO *pr); + +void kalSetSerTimeoutEvent(struct GLUE_INFO *pr); + +void kalSetIntEvent(struct GLUE_INFO *pr); + +void kalSetDrvIntEvent(struct GLUE_INFO *pr); + +void kalSetWmmUpdateEvent(struct GLUE_INFO *pr); + +void kalSetMdCrashEvent(struct GLUE_INFO *pr); + +void kalSetHifDbgEvent(struct GLUE_INFO *pr); + +#if CFG_SUPPORT_MULTITHREAD +void kalSetTxEvent2Hif(struct GLUE_INFO *pr); + +void kalSetTxEvent2Rx(struct GLUE_INFO *pr); + +void kalSetTxCmdEvent2Hif(struct GLUE_INFO *pr); + +void kalSetTxCmdDoneEvent(struct GLUE_INFO *pr); + +void kalSetRxProcessEvent(struct GLUE_INFO *pr); +#endif +/*----------------------------------------------------------------------------*/ +/* NVRAM/Registry Service */ +/*----------------------------------------------------------------------------*/ +u_int8_t kalIsConfigurationExist(IN struct GLUE_INFO + *prGlueInfo); + +struct REG_INFO *kalGetConfiguration(IN struct GLUE_INFO + *prGlueInfo); + +u_int8_t kalCfgDataRead(IN struct GLUE_INFO *prGlueInfo, + IN uint32_t u4Offset, + IN ssize_t len, OUT uint16_t *pu2Data); + +u_int8_t kalCfgDataRead16(IN struct GLUE_INFO *prGlueInfo, + IN uint32_t u4Offset, + OUT uint16_t *pu2Data); + +u_int8_t kalCfgDataWrite16(IN struct GLUE_INFO *prGlueInfo, + IN uint32_t u4Offset, IN uint16_t u2Data); + +u_int8_t kalCfgDataWrite8(IN struct GLUE_INFO *prGlueInfo, + IN uint32_t u4Offset, IN uint8_t u2Data); + + +/*----------------------------------------------------------------------------*/ +/* RSSI Updating */ +/*----------------------------------------------------------------------------*/ +void +kalUpdateRSSI(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucBssIndex, + IN int8_t cRssi, + IN int8_t cLinkQuality); + +/*----------------------------------------------------------------------------*/ +/* I/O Buffer Pre-allocation */ +/*----------------------------------------------------------------------------*/ +u_int8_t kalInitIOBuffer(u_int8_t is_pre_alloc); + +void kalUninitIOBuffer(void); + +void *kalAllocateIOBuffer(IN uint32_t u4AllocSize); + +void kalReleaseIOBuffer(IN void *pvAddr, + IN uint32_t u4Size); + +void +kalGetChannelList(IN struct GLUE_INFO *prGlueInfo, + IN enum ENUM_BAND eSpecificBand, + IN uint8_t ucMaxChannelNum, IN uint8_t *pucNumOfChannel, + IN struct RF_CHANNEL_INFO *paucChannelList); + +u_int8_t kalIsAPmode(IN struct GLUE_INFO *prGlueInfo); + +#if CFG_SUPPORT_802_11W +/*----------------------------------------------------------------------------*/ +/* 802.11W */ +/*----------------------------------------------------------------------------*/ +uint32_t kalGetMfpSetting(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucBssIndex); +uint8_t kalGetRsnIeMfpCap(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucBssIndex); +#endif + +/*----------------------------------------------------------------------------*/ +/* file opetation */ +/*----------------------------------------------------------------------------*/ +uint32_t kalWriteToFile(const uint8_t *pucPath, + u_int8_t fgDoAppend, + uint8_t *pucData, uint32_t u4Size); + +uint32_t kalCheckPath(const uint8_t *pucPath); + +uint32_t kalTrunkPath(const uint8_t *pucPath); + +int32_t kalReadToFile(const uint8_t *pucPath, + uint8_t *pucData, + uint32_t u4Size, uint32_t *pu4ReadSize); + +int32_t kalRequestFirmware(const uint8_t *pucPath, + uint8_t *pucData, + uint32_t u4Size, uint32_t *pu4ReadSize, + struct device *dev); + + +/*----------------------------------------------------------------------------*/ +/* NL80211 */ +/*----------------------------------------------------------------------------*/ +void +kalIndicateBssInfo(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t *pucFrameBuf, IN uint32_t u4BufLen, + IN uint8_t ucChannelNum, IN int32_t i4SignalStrength); + +/*----------------------------------------------------------------------------*/ +/* Net device */ +/*----------------------------------------------------------------------------*/ +uint32_t +kalHardStartXmit(struct sk_buff *prSkb, + IN struct net_device *prDev, + struct GLUE_INFO *prGlueInfo, uint8_t ucBssIndex); + +u_int8_t kalIsPairwiseEapolPacket(IN void *prPacket); + +u_int8_t +kalGetIPv4Address(IN struct net_device *prDev, + IN uint32_t u4MaxNumOfAddr, OUT uint8_t *pucIpv4Addrs, + OUT uint32_t *pu4NumOfIpv4Addr); + +#if IS_ENABLED(CONFIG_IPV6) +u_int8_t +kalGetIPv6Address(IN struct net_device *prDev, + IN uint32_t u4MaxNumOfAddr, OUT uint8_t *pucIpv6Addrs, + OUT uint32_t *pu4NumOfIpv6Addr); +#else +static inline u_int8_t +kalGetIPv6Address(IN struct net_device *prDev, + IN uint32_t u4MaxNumOfAddr, OUT uint8_t *pucIpv6Addrs, + OUT uint32_t *pu4NumOfIpv6Addr) { + /* Not support IPv6 */ + *pu4NumOfIpv6Addr = 0; + return 0; +} +#endif /* IS_ENABLED(CONFIG_IPV6) */ + +void kalSetNetAddressFromInterface(IN struct GLUE_INFO + *prGlueInfo, + IN struct net_device *prDev, + IN u_int8_t fgSet); + +uint32_t kalResetStats(IN struct net_device *prDev); + +void *kalGetStats(IN struct net_device *prDev); + +void kalResetPacket(IN struct GLUE_INFO *prGlueInfo, + IN void *prPacket); + +#if CFG_SUPPORT_QA_TOOL +struct file *kalFileOpen(const char *path, int flags, + int rights); + +void kalFileClose(struct file *file); + +uint32_t kalFileRead(struct file *file, + unsigned long long offset, + unsigned char *data, unsigned int size); +#endif + +#if CFG_SUPPORT_SDIO_READ_WRITE_PATTERN +/*----------------------------------------------------------------------------*/ +/* SDIO Read/Write Pattern Support */ +/*----------------------------------------------------------------------------*/ +u_int8_t kalSetSdioTestPattern(IN struct GLUE_INFO + *prGlueInfo, + IN u_int8_t fgEn, IN u_int8_t fgRead); +#endif + +/*----------------------------------------------------------------------------*/ +/* PNO Support */ +/*----------------------------------------------------------------------------*/ +void kalSchedScanResults(IN struct GLUE_INFO *prGlueInfo); + +void kalSchedScanStopped(IN struct GLUE_INFO *prGlueInfo, + u_int8_t fgDriverTriggerd); + +void kalSetFwOwnEvent2Hif(struct GLUE_INFO *pr); +#if CFG_ASSERT_DUMP +/* Core Dump out put file */ +uint32_t kalOpenCorDumpFile(u_int8_t fgIsN9); +uint32_t kalWriteCorDumpFile(uint8_t *pucBuffer, + uint16_t u2Size, + u_int8_t fgIsN9); +uint32_t kalCloseCorDumpFile(u_int8_t fgIsN9); +#endif +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#if CFG_WOW_SUPPORT +void kalWowInit(IN struct GLUE_INFO *prGlueInfo); +void kalWowProcess(IN struct GLUE_INFO *prGlueInfo, + uint8_t enable); +#endif + +int main_thread(void *data); + +#if CFG_SUPPORT_MULTITHREAD +int hif_thread(void *data); +int rx_thread(void *data); +#endif +uint64_t kalGetBootTime(void); + +int kalMetInitProcfs(IN struct GLUE_INFO *prGlueInfo); +int kalMetRemoveProcfs(void); + +uint8_t kalGetEapolKeyType(void *prPacket); + +#if CFG_SUPPORT_WAKEUP_REASON_DEBUG +u_int8_t kalIsWakeupByWlan(struct ADAPTER *prAdapter); +#endif + +int32_t kalHaltLock(uint32_t waitMs); +int32_t kalHaltTryLock(void); +void kalHaltUnlock(void); +void kalSetHalted(u_int8_t fgHalt); +u_int8_t kalIsHalted(void); + +void kalFreeTxMsduWorker(struct work_struct *work); +void kalFreeTxMsdu(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo); + +int32_t kalPerMonInit(IN struct GLUE_INFO *prGlueInfo); +int32_t kalPerMonDisable(IN struct GLUE_INFO *prGlueInfo); +int32_t kalPerMonEnable(IN struct GLUE_INFO *prGlueInfo); +int32_t kalPerMonStart(IN struct GLUE_INFO *prGlueInfo); +int32_t kalPerMonStop(IN struct GLUE_INFO *prGlueInfo); +int32_t kalPerMonDestroy(IN struct GLUE_INFO *prGlueInfo); +void kalPerMonHandler(IN struct ADAPTER *prAdapter, + unsigned long ulParam); +uint32_t kalPerMonGetInfo(IN struct ADAPTER *prAdapter, + IN uint8_t *pucBuf, + IN uint32_t u4Max); +int32_t kalBoostCpu(IN struct ADAPTER *prAdapter, + IN uint32_t u4TarPerfLevel, + IN uint32_t u4BoostCpuTh); +int32_t kalCheckTputLoad(IN struct ADAPTER *prAdapter, + IN uint32_t u4CurrPerfLevel, + IN uint32_t u4TarPerfLevel, + IN int32_t i4Pending, + IN uint32_t u4Used); +uint32_t kalGetCpuBoostThreshold(void); +void kalSetRpsMap(IN struct GLUE_INFO *glue, IN unsigned long value); +extern int set_task_util_min_pct(pid_t pid, unsigned int min); + +#if CFG_MTK_ANDROID_EMI +void kalSetEmiMpuProtection(phys_addr_t emiPhyBase, bool enable); +void kalSetDrvEmiMpuProtection(phys_addr_t emiPhyBase, uint32_t offset, + uint32_t size); +#endif +int32_t kalSetCpuNumFreq(uint32_t u4CoreNum, + uint32_t u4Freq); +int32_t kalGetFwFlavor(uint8_t *flavor); +int32_t kalGetConnsysVerId(void); +int32_t kalPerMonSetForceEnableFlag(uint8_t uFlag); +int32_t kalFbNotifierReg(IN struct GLUE_INFO *prGlueInfo); +void kalFbNotifierUnReg(void); + +#if KERNEL_VERSION(3, 0, 0) <= LINUX_VERSION_CODE +/* since: 0b5c9db1b11d3175bb42b80663a9f072f801edf5 */ +static inline void kal_skb_reset_mac_len(struct sk_buff + *skb) +{ + skb_reset_mac_len(skb); +} +#else +static inline void kal_skb_reset_mac_len(struct sk_buff + *skb) +{ + skb->mac_len = skb->network_header - skb->mac_header; +} +#endif + +void kalInitDevWakeup(struct ADAPTER *prAdapter, struct device *prDev); + +u_int8_t kalIsValidMacAddr(const uint8_t *addr); + +u_int8_t kalScanParseRandomMac(const struct net_device *ndev, + const struct cfg80211_scan_request *request, uint8_t *pucRandomMac); + +u_int8_t kalSchedScanParseRandomMac(const struct net_device *ndev, + const struct cfg80211_sched_scan_request *request, + uint8_t *pucRandomMac, uint8_t *pucRandomMacMask); + +void kalScanReqLog(struct cfg80211_scan_request *request); +void kalScanResultLog(struct ADAPTER *prAdapter, struct ieee80211_mgmt *mgmt); +void kalScanLogCacheFlushBSS(struct ADAPTER *prAdapter, + const uint16_t logBufLen); +int kalMaskMemCmp(const void *cs, const void *ct, + const void *mask, size_t count); + +u_int8_t +kalChannelScoSwitch(IN enum nl80211_channel_type channel_type, + IN enum ENUM_CHNL_EXT *prChnlSco); + +u_int8_t +kalChannelFormatSwitch(IN struct cfg80211_chan_def *channel_def, + IN struct ieee80211_channel *channel, + IN struct RF_CHANNEL_INFO *prRfChnlInfo); + +#if CFG_SUPPORT_RX_GRO +uint32_t kal_is_skb_gro(struct ADAPTER *prAdapter, uint8_t ucBssIdx); +void kal_gro_flush(struct ADAPTER *prAdapter, struct net_device *prDev); +#endif + +void kalRemoveBss(struct GLUE_INFO *prGlueInfo, + uint8_t aucBSSID[], + uint8_t ucChannelNum, + enum ENUM_BAND eBand); + +#if CFG_SUPPORT_WPA3 +int kalExternalAuthRequest(IN struct ADAPTER *prAdapter, + IN uint8_t uBssIndex); +#endif + +int kalWlanUeventInit(void); +void kalWlanUeventDeinit(void); + +int _kalSnprintf(char *buf, size_t size, const char *fmt, ...); +int _kalSprintf(char *buf, const char *fmt, ...); + +/* systrace utilities */ +#if !CONFIG_WLAN_DRV_BUILD_IN +void tracing_mark_write(const char *fmt, ...); +#endif + +#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE +void kal_do_gettimeofday(struct timeval *tv); +#endif + +uint32_t kalSetSuspendFlagToEMI(IN struct ADAPTER + *prAdapter, IN u_int8_t fgSuspend); + +#endif /* _GL_KAL_H */ + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_os.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_os.h new file mode 100644 index 0000000000000000000000000000000000000000..42d9fc8a1f38fe011cfe894a028018bcd881bf80 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_os.h @@ -0,0 +1,1422 @@ + +/******************************************************************************* + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include + * /gl_os.h#4 + */ + +/*! \file gl_os.h + * \brief List the external reference to OS for GLUE Layer. + * + * In this file we define the data structure - GLUE_INFO_T to store those + * objects + * we acquired from OS - e.g. TIMER, SPINLOCK, NET DEVICE ... . And all the + * external reference (header file, extern func() ..) to OS for GLUE Layer + * should also list down here. + */ + + +#ifndef _GL_OS_H +#define _GL_OS_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ +/*------------------------------------------------------------------------------ + * Flags for LINUX(OS) dependent + *------------------------------------------------------------------------------ + */ +#define CFG_MAX_WLAN_DEVICES 1 /* number of wlan card will coexist */ + +#define CFG_MAX_TXQ_NUM 4 /* number of tx queue for support multi-queue h/w */ + +/* 1: Enable use of SPIN LOCK Bottom Half for LINUX */ +/* 0: Disable - use SPIN LOCK IRQ SAVE instead */ +#define CFG_USE_SPIN_LOCK_BOTTOM_HALF 0 + +/* 1: Enable - Drop ethernet packet if it < 14 bytes. + * And pad ethernet packet with dummy 0 if it < 60 bytes. + * 0: Disable + */ +#define CFG_TX_PADDING_SMALL_ETH_PACKET 0 + +#define CFG_TX_STOP_NETIF_QUEUE_THRESHOLD 256 /* packets */ + +#if (CFG_SUPPORT_CONNAC2X == 1) +#define CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD 1024 /* packets */ +#define CFG_TX_START_NETIF_PER_QUEUE_THRESHOLD 512 /* packets */ +#else +#define CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD 256 /* packets */ +#define CFG_TX_START_NETIF_PER_QUEUE_THRESHOLD 128 /* packets */ +#endif + + +#define CHIP_NAME "MT6632" + +#define DRV_NAME "["CHIP_NAME"]: " + +/* Define if target platform is Android. + * It should already be defined in Android kernel source + */ +#ifndef CONFIG_ANDROID +/* #define CONFIG_ANDROID 0 */ + +#endif + +/* for CFG80211 IE buffering mechanism */ +#define CFG_CFG80211_IE_BUF_LEN (512) +#define GLUE_INFO_WSCIE_LENGTH (500) +/* for non-wfa vendor specific IE buffer */ +#define NON_WFA_VENDOR_IE_MAX_LEN (128) + + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include /* constant of kernel version */ + +#include /* bitops.h */ + +#include /* struct timer_list */ +#include /* jiffies */ +#include /* udelay and mdelay macro */ +#include +#include +#include + +#ifdef CONFIG_ANDROID +#if (KERNEL_VERSION(4, 9, 0) <= LINUX_VERSION_CODE) +#include +#include +#else +#include +#endif +#endif + +#if KERNEL_VERSION(2, 6, 12) < LINUX_VERSION_CODE +#include /* IRQT_FALLING */ +#endif + +#include /* struct net_device, struct net_device_stats */ +#include /* for eth_type_trans() function */ +#include /* struct iw_statistics */ +#include +#include /* struct in_device */ + +#include /* struct iphdr */ + +#include /* for memcpy()/memset() function */ +#include /* for offsetof() macro */ + +#include /* The proc filesystem constants/structures */ + +#include /* for rtnl_lock() and rtnl_unlock() */ +#include /* kthread_should_stop(), kthread_run() */ +#include /* for copy_from_user() */ +#include /* for firmware download */ +#include + +#include /* for kfifo interface */ +#include /* for cdev interface */ + +#include /* for firmware download */ +#include + +#include + +#if defined(_HIF_USB) +#include +#include +#include +#endif + +#if defined(_HIF_PCIE) +#include +#endif + +#if defined(_HIF_SDIO) +#include +#include +#include +#endif + +#include + +#include /* readw and writew */ + +#if WIRELESS_EXT > 12 +#include +#endif + +#ifdef CFG_CFG80211_VERSION +#define CFG80211_VERSION_CODE CFG_CFG80211_VERSION +#else +#define CFG80211_VERSION_CODE LINUX_VERSION_CODE +#endif + +#include "version.h" +#include "config.h" + +#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 +#include +#include +#endif + +#include +#include +#include + +#if IS_ENABLED(CONFIG_IPV6) +#include +#include +#include +#endif + +#if CFG_SUPPORT_PASSPOINT +#include +#endif /* CFG_SUPPORT_PASSPOINT */ + +#if KERNEL_VERSION(3, 8, 0) <= CFG80211_VERSION_CODE +#include +#endif + +#ifdef UDP_SKT_WIFI +#if (KERNEL_VERSION(4, 4, 0) <= CFG80211_VERSION_CODE) +#include +#else +#include +#endif +#endif + +#include "gl_typedef.h" +#include "typedef.h" +#include "queue.h" +#include "gl_kal.h" +#include "gl_rst.h" +#include "hif.h" + +#if CFG_SUPPORT_TDLS +#include "tdls.h" +#endif + +#include "debug.h" + +#include "wlan_lib.h" +#include "wlan_oid.h" + +#if CFG_ENABLE_AEE_MSG +#ifdef CONFIG_ANDROID +#include +#else +#include +#endif +#endif + +#if CFG_MET_TAG_SUPPORT +#include +#endif +#include +#include + +#if (CONFIG_WLAN_SERVICE == 1) +#include "agent.h" +#endif + +extern u_int8_t fgIsBusAccessFailed; +extern const struct ieee80211_iface_combination + *p_mtk_iface_combinations_sta; +extern const int32_t mtk_iface_combinations_sta_num; +extern const struct ieee80211_iface_combination + *p_mtk_iface_combinations_p2p; +extern const int32_t mtk_iface_combinations_p2p_num; +extern uint8_t g_aucNvram[]; + +#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH +typedef void (*wifi_fwlog_event_func_cb)(int, int); +/* adaptor ko */ +extern int wifi_fwlog_onoff_status(void); +extern void wifi_fwlog_event_func_register(wifi_fwlog_event_func_cb pfFwlog); +#endif +#if CFG_MTK_ANDROID_WMT +extern void update_driver_loaded_status(uint8_t loaded); +#endif + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#define GLUE_FLAG_HALT BIT(0) +#define GLUE_FLAG_INT BIT(1) +#define GLUE_FLAG_OID BIT(2) +#define GLUE_FLAG_TIMEOUT BIT(3) +#define GLUE_FLAG_TXREQ BIT(4) +#define GLUE_FLAG_SER_TIMEOUT BIT(5) +#define GLUE_FLAG_SUB_MOD_MULTICAST BIT(7) +#define GLUE_FLAG_FRAME_FILTER BIT(8) +#define GLUE_FLAG_FRAME_FILTER_AIS BIT(9) + +#define GLUE_FLAG_HALT_BIT (0) +#define GLUE_FLAG_INT_BIT (1) +#define GLUE_FLAG_OID_BIT (2) +#define GLUE_FLAG_TIMEOUT_BIT (3) +#define GLUE_FLAG_TXREQ_BIT (4) +#define GLUE_FLAG_SER_TIMEOUT_BIT (5) +#define GLUE_FLAG_SUB_MOD_MULTICAST_BIT (7) +#define GLUE_FLAG_FRAME_FILTER_BIT (8) +#define GLUE_FLAG_FRAME_FILTER_AIS_BIT (9) + +#if CFG_SUPPORT_MULTITHREAD +#define GLUE_FLAG_RX BIT(10) +#define GLUE_FLAG_TX_CMD_DONE BIT(11) +#define GLUE_FLAG_HIF_TX BIT(12) +#define GLUE_FLAG_HIF_TX_CMD BIT(13) +#define GLUE_FLAG_RX_TO_OS BIT(14) +#define GLUE_FLAG_HIF_FW_OWN BIT(15) +#define GLUE_FLAG_HIF_PRT_HIF_DBG_INFO BIT(16) +#define GLUE_FLAG_UPDATE_WMM_QUOTA BIT(17) +#define GLUE_FLAG_NOTIFY_MD_CRASH BIT(18) +#define GLUE_FLAG_DRV_INT BIT(19) + +#define GLUE_FLAG_RX_BIT (10) +#define GLUE_FLAG_TX_CMD_DONE_BIT (11) +#define GLUE_FLAG_HIF_TX_BIT (12) +#define GLUE_FLAG_HIF_TX_CMD_BIT (13) +#define GLUE_FLAG_RX_TO_OS_BIT (14) +#define GLUE_FLAG_HIF_FW_OWN_BIT (15) +#define GLUE_FLAG_HIF_PRT_HIF_DBG_INFO_BIT (16) +#define GLUE_FLAG_UPDATE_WMM_QUOTA_BIT (17) +#define GLUE_FLAG_NOTIFY_MD_CRASH_BIT (18) +#define GLUE_FLAG_DRV_INT_BIT (19) +#endif +#if (CFG_SUPPORT_CONNINFRA == 1) +#define GLUE_FLAG_RST_START BIT(18) +#define GLUE_FLAG_RST_START_BIT 18 +#define GLUE_FLAG_RST_END BIT(19) +#define GLUE_FLAG_RST_END_BIT 19 + +#endif +#define GLUE_BOW_KFIFO_DEPTH (1024) +/* #define GLUE_BOW_DEVICE_NAME "MT6620 802.11 AMP" */ +#define GLUE_BOW_DEVICE_NAME "ampc0" + +#define WAKE_LOCK_RX_TIMEOUT 300 /* ms */ +#define WAKE_LOCK_THREAD_WAKEUP_TIMEOUT 50 /* ms */ + +#define STR_HELPER(x) #x +#define STR(x) STR_HELPER(x) + +#define IW_AUTH_CIPHER_GCMP256 0x00000080 + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +struct GLUE_INFO; + +struct GL_WPA_INFO { + uint32_t u4WpaVersion; + uint32_t u4KeyMgmt; + uint32_t u4CipherGroup; + uint32_t u4CipherPairwise; + uint32_t u4AuthAlg; + u_int8_t fgPrivacyInvoke; +#if CFG_SUPPORT_802_11W + uint32_t u4Mfp; + uint8_t ucRSNMfpCap; +#endif +}; + +#if CFG_SUPPORT_REPLAY_DETECTION +struct GL_REPLEY_PN_INFO { + uint8_t auPN[16]; + u_int8_t fgRekey; + u_int8_t fgFirstPkt; +}; +struct GL_DETECT_REPLAY_INFO { + uint8_t ucCurKeyId; + uint8_t ucKeyType; + struct GL_REPLEY_PN_INFO arReplayPNInfo[4]; +}; +#endif + +enum ENUM_NET_DEV_IDX { + NET_DEV_WLAN_IDX = 0, + NET_DEV_P2P_IDX, + NET_DEV_BOW_IDX, + NET_DEV_NUM +}; + +enum ENUM_RSSI_TRIGGER_TYPE { + ENUM_RSSI_TRIGGER_NONE, + ENUM_RSSI_TRIGGER_GREATER, + ENUM_RSSI_TRIGGER_LESS, + ENUM_RSSI_TRIGGER_TRIGGERED, + ENUM_RSSI_TRIGGER_NUM +}; + +#if CFG_ENABLE_WIFI_DIRECT +enum ENUM_NET_REG_STATE { + ENUM_NET_REG_STATE_UNREGISTERED, + ENUM_NET_REG_STATE_REGISTERING, + ENUM_NET_REG_STATE_REGISTERED, + ENUM_NET_REG_STATE_UNREGISTERING, + ENUM_NET_REG_STATE_NUM +}; +#endif + +enum ENUM_PKT_FLAG { + ENUM_PKT_802_11, /* 802.11 or non-802.11 */ + ENUM_PKT_802_3, /* 802.3 or ethernetII */ + ENUM_PKT_1X, /* 1x frame or not */ + ENUM_PKT_PROTECTED_1X, /* protected 1x frame */ + ENUM_PKT_NON_PROTECTED_1X, /* Non protected 1x frame */ + ENUM_PKT_VLAN_EXIST, /* VLAN tag exist */ + ENUM_PKT_DHCP, /* DHCP frame */ + ENUM_PKT_ARP, /* ARP */ + ENUM_PKT_ICMP, /* ICMP */ + ENUM_PKT_TDLS, /* TDLS */ + ENUM_PKT_DNS, /* DNS */ + + ENUM_PKT_FLAG_NUM +}; + +enum ENUM_WLAN_DRV_BUF_TYPE_T { + ENUM_BUF_TYPE_NVRAM, + ENUM_BUF_TYPE_DRV_CFG, + ENUM_BUF_TYPE_FW_CFG, + ENUM_BUF_TYPE_NUM +}; + +enum ENUM_NVRAM_STATE { + NVRAM_STATE_INIT = 0, + NVRAM_STATE_READY, /*power on or update*/ + NVRAM_STATE_SEND_TO_FW, + NVRAM_STATE_NUM +}; + +/* WMM QOS user priority from 802.1D/802.11e */ +enum ENUM_WMM_UP { + WMM_UP_BE_INDEX = 0, + WMM_UP_BK_INDEX, + WMM_UP_RESV_INDEX, + WMM_UP_EE_INDEX, + WMM_UP_CL_INDEX, + WMM_UP_VI_INDEX, + WMM_UP_VO_INDEX, + WMM_UP_NC_INDEX, + WMM_UP_INDEX_NUM +}; + +struct GL_IO_REQ { + struct QUE_ENTRY rQueEntry; + /* wait_queue_head_t cmdwait_q; */ + u_int8_t fgRead; + u_int8_t fgWaitResp; + struct ADAPTER *prAdapter; + PFN_OID_HANDLER_FUNC pfnOidHandler; + void *pvInfoBuf; + uint32_t u4InfoBufLen; + uint32_t *pu4QryInfoLen; + uint32_t rStatus; + uint32_t u4Flag; + uint8_t ucBssIndex; +}; + +#if CFG_ENABLE_BT_OVER_WIFI +struct GL_BOW_INFO { + u_int8_t fgIsRegistered; + dev_t u4DeviceNumber; /* dynamic device number */ + /* struct kfifo *prKfifo; */ /* for buffering indicated events */ + struct kfifo rKfifo; /* for buffering indicated events */ + spinlock_t rSpinLock; /* spin lock for kfifo */ + struct cdev cdev; + uint32_t u4FreqInKHz; /* frequency */ + + uint8_t aucRole[CFG_BOW_PHYSICAL_LINK_NUM]; /* 0: Responder, + * 1: Initiator + */ + enum ENUM_BOW_DEVICE_STATE + aeState[CFG_BOW_PHYSICAL_LINK_NUM]; + uint8_t arPeerAddr[CFG_BOW_PHYSICAL_LINK_NUM][PARAM_MAC_ADDR_LEN]; + + wait_queue_head_t outq; + +#if CFG_BOW_SEPARATE_DATA_PATH + /* Device handle */ + struct net_device *prDevHandler; + u_int8_t fgIsNetRegistered; +#endif + +}; +#endif + +#if CFG_SUPPORT_SCAN_CACHE_RESULT +struct GL_SCAN_CACHE_INFO { + struct GLUE_INFO *prGlueInfo; + + /* for cfg80211 scan done indication */ + struct cfg80211_scan_request *prRequest; + + /* total number of channels to scan */ + uint32_t n_channels; + + /* Scan period time */ + OS_SYSTIME u4LastScanTime; + + /* Bss index */ + uint8_t ucBssIndex; + + /* scan request flags */ + uint32_t u4Flags; +}; +#endif /* CFG_SUPPORT_SCAN_CACHE_RESULT */ + +#if CFG_SUPPORT_PERF_IND + struct GL_PERF_IND_INFO { + uint32_t u4CurTxBytes[BSSID_NUM]; /* Byte */ + uint32_t u4CurRxBytes[BSSID_NUM]; /* Byte */ + uint16_t u2CurRxRate[BSSID_NUM]; /* Unit 500 Kbps */ + uint8_t ucCurRxRCPI0[BSSID_NUM]; + uint8_t ucCurRxRCPI1[BSSID_NUM]; + uint8_t ucCurRxNss[BSSID_NUM]; + }; +#endif /* CFG_SUPPORT_SCAN_CACHE_RESULT */ + +struct FT_IES { + uint16_t u2MDID; + struct IE_MOBILITY_DOMAIN *prMDIE; + struct IE_FAST_TRANSITION *prFTIE; + struct IE_TIMEOUT_INTERVAL *prTIE; + struct RSN_INFO_ELEM *prRsnIE; + uint8_t *pucIEBuf; + uint32_t u4IeLength; +}; + +/* + * type definition of pointer to p2p structure + */ +struct GL_P2P_INFO; /* declare GL_P2P_INFO_T */ +struct GL_P2P_DEV_INFO; /* declare GL_P2P_DEV_INFO_T */ + +struct GLUE_INFO { + /* Device handle */ + struct net_device *prDevHandler; + + /* Device */ + struct device *prDev; + + /* Device Index(index of arWlanDevInfo[]) */ + int32_t i4DevIdx; + + /* Device statistics */ + /* struct net_device_stats rNetDevStats; */ + + /* Wireless statistics struct net_device */ + struct iw_statistics rIwStats[BSSID_NUM]; + + /* spinlock to sync power save mechanism */ + spinlock_t rSpinLock[SPIN_LOCK_NUM]; + + /* Mutex to protect interruptible section */ + struct mutex arMutex[MUTEX_NUM]; + + /* semaphore for ioctl */ + struct semaphore ioctl_sem; + + uint64_t u8Cookie; + + unsigned long ulFlag; /* GLUE_FLAG_XXX */ + uint32_t u4PendFlag; + /* UINT_32 u4TimeoutFlag; */ + uint32_t u4OidCompleteFlag; + uint32_t u4ReadyFlag; /* check if card is ready */ + + uint32_t u4OsMgmtFrameFilter; + + /* Number of pending frames, also used for debuging if any frame is + * missing during the process of unloading Driver. + * + * NOTE(Kevin): In Linux, we also use this variable as the threshold + * for manipulating the netif_stop(wake)_queue() func. + */ + int32_t ai4TxPendingFrameNumPerQueue[MAX_BSSID_NUM][CFG_MAX_TXQ_NUM]; + int32_t i4TxPendingFrameNum; + int32_t i4TxPendingSecurityFrameNum; + int32_t i4TxPendingCmdNum; + + /* Tx: for NetDev to BSS index mapping */ + struct NET_INTERFACE_INFO arNetInterfaceInfo[MAX_BSSID_NUM]; + + /* Rx: for BSS index to NetDev mapping */ + /* P_NET_INTERFACE_INFO_T aprBssIdxToNetInterfaceInfo[HW_BSSID_NUM]; */ + + /* current IO request for kalIoctl */ + struct GL_IO_REQ OidEntry; + + /* registry info */ + struct REG_INFO rRegInfo; + + /* firmware */ + struct firmware *prFw; + + /* Host interface related information */ + /* defined in related hif header file */ + struct GL_HIF_INFO rHifInfo; + + /*! \brief wext wpa related information */ + struct GL_WPA_INFO rWpaInfo[KAL_AIS_NUM]; +#if CFG_SUPPORT_REPLAY_DETECTION + struct GL_DETECT_REPLAY_INFO prDetRplyInfo[KAL_AIS_NUM]; +#endif + + /* Pointer to ADAPTER_T - main data structure of internal protocol + * stack + */ + struct ADAPTER *prAdapter; + +#if WLAN_INCLUDE_PROC + struct proc_dir_entry *pProcRoot; +#endif /* WLAN_INCLUDE_PROC */ + + /* Indicated media state */ + enum ENUM_PARAM_MEDIA_STATE + eParamMediaStateIndicated[KAL_AIS_NUM]; + + /* Device power state D0~D3 */ + enum PARAM_DEVICE_POWER_STATE ePowerState; + + struct completion rScanComp; /* indicate scan complete */ + struct completion + rHaltComp; /* indicate main thread halt complete */ + struct completion + rPendComp; /* indicate main thread halt complete */ +#if CFG_SUPPORT_MULTITHREAD + struct completion + rHifHaltComp; /* indicate hif_thread halt complete */ + struct completion + rRxHaltComp; /* indicate hif_thread halt complete */ + + uint32_t u4TxThreadPid; + uint32_t u4RxThreadPid; + uint32_t u4HifThreadPid; +#endif + +#if CFG_SUPPORT_NCHO + struct completion + rAisChGrntComp; /* indicate Ais channel grant complete */ +#endif + + uint32_t rPendStatus; + + struct QUE rTxQueue; + + /* OID related */ + struct QUE rCmdQueue; + /* PVOID pvInformationBuffer; */ + /* UINT_32 u4InformationBufferLength; */ + /* PVOID pvOidEntry; */ + /* PUINT_8 pucIOReqBuff; */ + /* QUE_T rIOReqQueue; */ + /* QUE_T rFreeIOReqQueue; */ + + wait_queue_head_t waitq; + struct task_struct *main_thread; + +#if CFG_SUPPORT_MULTITHREAD + wait_queue_head_t waitq_hif; + struct task_struct *hif_thread; + + wait_queue_head_t waitq_rx; + struct task_struct *rx_thread; + +#endif + struct tasklet_struct rRxTask; + struct tasklet_struct rTxCompleteTask; + + struct work_struct rTxMsduFreeWork; + struct delayed_work rRxPktDeAggWork; + + struct timer_list tickfn; + +#if CFG_SUPPORT_EXT_CONFIG + uint16_t au2ExtCfg[256]; /* NVRAM data buffer */ + uint32_t u4ExtCfgLength; /* 0 means data is NOT valid */ +#endif + +#if CFG_ENABLE_BT_OVER_WIFI + struct GL_BOW_INFO rBowInfo; +#endif + +#if CFG_ENABLE_WIFI_DIRECT + struct GL_P2P_DEV_INFO *prP2PDevInfo; + struct GL_P2P_INFO *prP2PInfo[KAL_P2P_NUM]; +#if CFG_SUPPORT_P2P_RSSI_QUERY + /* Wireless statistics struct net_device */ + struct iw_statistics rP2pIwStats; +#endif +#endif + + /* NVRAM availability */ + u_int8_t fgNvramAvailable; + + u_int8_t fgMcrAccessAllowed; + + /* MAC Address Overridden by IOCTL */ + u_int8_t fgIsMacAddrOverride; + uint8_t rMacAddrOverride[PARAM_MAC_ADDR_LEN]; + + struct SET_TXPWR_CTRL rTxPwr; + + /* for cfg80211 scan done indication */ + struct cfg80211_scan_request *prScanRequest; + +#if CFG_SUPPORT_SCHED_SCAN + struct PARAM_SCHED_SCAN_REQUEST *prSchedScanRequest; +#else + /* for cfg80211 scheduled scan */ + struct cfg80211_sched_scan_request *prSchedScanRequest; +#endif + + /* to indicate registered or not */ + u_int8_t fgIsRegistered; + +#if CFG_SUPPORT_SDIO_READ_WRITE_PATTERN + u_int8_t fgEnSdioTestPattern; + u_int8_t fgSdioReadWriteMode; + u_int8_t fgIsSdioTestInitialized; + uint8_t aucSdioTestBuffer[256]; +#endif + + u_int8_t fgIsInSuspendMode; + +#if CFG_SUPPORT_PASSPOINT + u_int8_t fgIsDad; + uint8_t aucDADipv4[4]; + u_int8_t fgIs6Dad; + uint8_t aucDADipv6[16]; +#endif /* CFG_SUPPORT_PASSPOINT */ + + KAL_WAKE_LOCK_T *rIntrWakeLock; + KAL_WAKE_LOCK_T *rTimeoutWakeLock; + +#if CFG_MET_PACKET_TRACE_SUPPORT + u_int8_t fgMetProfilingEn; + uint16_t u2MetUdpPort; +#endif + +#if CFG_SUPPORT_SNIFFER + u_int8_t fgIsEnableMon; + struct net_device *prMonDevHandler; + struct work_struct monWork; +#endif + + int32_t i4RssiCache[BSSID_NUM]; + uint32_t u4LinkSpeedCache[BSSID_NUM]; + + + uint32_t u4InfType; + + uint32_t IsrCnt; + uint32_t IsrPassCnt; + uint32_t TaskIsrCnt; + + uint32_t IsrAbnormalCnt; + uint32_t IsrSoftWareCnt; + uint32_t IsrTxCnt; + uint32_t IsrRxCnt; + uint64_t u8HifIntTime; + + /* save partial scan channel information */ + /* PARTIAL_SCAN_INFO rScanChannelInfo; */ + uint8_t *pucScanChannel; + +#if CFG_SUPPORT_SCAN_CACHE_RESULT + struct GL_SCAN_CACHE_INFO scanCache; +#endif /* CFG_SUPPORT_SCAN_CACHE_RESULT */ +#if (CFG_SUPPORT_PERF_IND == 1) + struct GL_PERF_IND_INFO PerfIndCache; +#endif + + /* Full2Partial */ + OS_SYSTIME u4LastFullScanTime; + /* full scan or partial scan */ + uint8_t ucTrScanType; + /* UINT_8 aucChannelNum[FULL_SCAN_MAX_CHANNEL_NUM]; */ + /* PARTIAL_SCAN_INFO rFullScanApChannel; */ + uint8_t *pucFullScan2PartialChannel; + + uint32_t u4RoamFailCnt; + uint64_t u8RoamFailTime; + u_int8_t fgTxDoneDelayIsARP; + uint32_t u4ArriveDrvTick; + uint32_t u4EnQueTick; + uint32_t u4DeQueTick; + uint32_t u4LeaveDrvTick; + uint32_t u4CurrTick; + uint64_t u8CurrTime; + + /* FW Roaming */ + /* store the FW roaming enable state which FWK determines */ + /* if it's = 0, ignore the black/whitelists settings from FWK */ + uint32_t u4FWRoamingEnable; + + /*service for test mode*/ +#if (CONFIG_WLAN_SERVICE == 1) + struct service rService; +#endif +}; + +typedef irqreturn_t(*PFN_WLANISR) (int irq, void *dev_id, + struct pt_regs *regs); + +typedef void (*PFN_LINUX_TIMER_FUNC) (unsigned long); + +/* generic sub module init/exit handler + * now, we only have one sub module, p2p + */ +#if CFG_ENABLE_WIFI_DIRECT +typedef u_int8_t(*SUB_MODULE_INIT) (struct GLUE_INFO + *prGlueInfo); +typedef u_int8_t(*SUB_MODULE_EXIT) (struct GLUE_INFO + *prGlueInfo); + +struct SUB_MODULE_HANDLER { + SUB_MODULE_INIT subModInit; + SUB_MODULE_EXIT subModExit; + u_int8_t fgIsInited; +}; + +#endif + +#ifdef CONFIG_NL80211_TESTMODE + +enum TestModeCmdType { + TESTMODE_CMD_ID_SW_CMD = 1, + TESTMODE_CMD_ID_WAPI = 2, + TESTMODE_CMD_ID_HS20 = 3, + + /* Hotspot managerment testmode command */ + TESTMODE_CMD_ID_HS_CONFIG = 51, + + TESTMODE_CMD_ID_STR_CMD = 102, + NUM_OF_TESTMODE_CMD_ID +}; + +#if CFG_SUPPORT_PASSPOINT +enum Hs20CmdType { + HS20_CMD_ID_SET_BSSID_POOL = 0, + NUM_OF_HS20_CMD_ID +}; +#endif /* CFG_SUPPORT_PASSPOINT */ + +struct NL80211_DRIVER_TEST_MODE_PARAMS { + uint32_t index; + uint32_t buflen; +}; + +struct NL80211_DRIVER_STRING_CMD_PARAMS { + struct NL80211_DRIVER_TEST_MODE_PARAMS hdr; + uint32_t reply_buf_size; + uint32_t reply_len; + uint8_t *reply_buf; +}; + +/*SW CMD */ +struct NL80211_DRIVER_SW_CMD_PARAMS { + struct NL80211_DRIVER_TEST_MODE_PARAMS hdr; + uint8_t set; + uint32_t adr; + uint32_t data; +}; + +struct iw_encode_exts { + __u32 ext_flags; /*!< IW_ENCODE_EXT_* */ + __u8 tx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /*!< LSB first */ + __u8 rx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /*!< LSB first */ + /*!< ff:ff:ff:ff:ff:ff for broadcast/multicast + * (group) keys or unicast address for + * individual keys + */ + __u8 addr[MAC_ADDR_LEN]; + __u16 alg; /*!< IW_ENCODE_ALG_* */ + __u16 key_len; + __u8 key[32]; +}; + +/*SET KEY EXT */ +struct NL80211_DRIVER_SET_KEY_EXTS { + struct NL80211_DRIVER_TEST_MODE_PARAMS hdr; + uint8_t key_index; + uint8_t key_len; + struct iw_encode_exts ext; +}; + +#if CFG_SUPPORT_PASSPOINT + +struct param_hs20_set_bssid_pool { + uint8_t fgBssidPoolIsEnable; + uint8_t ucNumBssidPool; + uint8_t arBssidPool[8][ETH_ALEN]; +}; + +struct wpa_driver_hs20_data_s { + struct NL80211_DRIVER_TEST_MODE_PARAMS hdr; + enum Hs20CmdType CmdType; + struct param_hs20_set_bssid_pool hs20_set_bssid_pool; +}; + +#endif /* CFG_SUPPORT_PASSPOINT */ + +#endif + +struct NETDEV_PRIVATE_GLUE_INFO { + struct GLUE_INFO *prGlueInfo; + uint8_t ucBssIdx; +#if CFG_ENABLE_UNIFY_WIPHY + u_int8_t ucIsP2p; +#endif + u_int8_t ucMddpSupport; +#if CFG_SUPPORT_RX_GRO + struct napi_struct napi; + OS_SYSTIME tmGROFlushTimeout; + spinlock_t napi_spinlock; +#endif + struct net_device_stats stats; +}; + +struct PACKET_PRIVATE_DATA { + /* tx/rx both use cb */ + struct QUE_ENTRY rQueEntry; /* 16byte total:16 */ + + uint8_t ucBssIdx; /* 1byte */ + /* only rx use cb */ + u_int8_t fgIsIndependentPkt; /* 1byte */ + /* only tx use cb */ + uint8_t ucTid; /* 1byte */ + uint8_t ucHeaderLen; /* 1byte */ + uint8_t ucProfilingFlag; /* 1byte */ + uint8_t ucSeqNo; /* 1byte */ + uint16_t u2Flag; /* 2byte total:24 */ + + uint16_t u2IpId; /* 2byte */ + uint16_t u2FrameLen; /* 2byte */ + OS_SYSTIME rArrivalTime;/* 4byte total:32 */ + + uint64_t u8ArriveTime; /* 8byte total:40 */ +}; + +struct PACKET_PRIVATE_RX_DATA { + uint64_t u8IntTime; /* 8byte */ + uint64_t u8RxTime; /* 8byte */ +}; + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ +/*----------------------------------------------------------------------------*/ +/* Macros of SPIN LOCK operations for using in Glue Layer */ +/*----------------------------------------------------------------------------*/ +#if CFG_USE_SPIN_LOCK_BOTTOM_HALF +#define GLUE_SPIN_LOCK_DECLARATION() +#define GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, rLockCategory) \ + { \ + if (rLockCategory < SPIN_LOCK_NUM) \ + spin_lock_bh(&(prGlueInfo->rSpinLock[rLockCategory])); \ + } +#define GLUE_RELEASE_SPIN_LOCK(prGlueInfo, rLockCategory) \ + { \ + if (rLockCategory < SPIN_LOCK_NUM) \ + spin_unlock_bh(\ + &(prGlueInfo->rSpinLock[rLockCategory])); \ + } +#else /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */ +#define GLUE_SPIN_LOCK_DECLARATION() unsigned long __ulFlags = 0 +#define GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, rLockCategory) \ + { \ + if (rLockCategory < SPIN_LOCK_NUM) \ + spin_lock_irqsave(\ + &(prGlueInfo)->rSpinLock[rLockCategory], __ulFlags); \ + } +#define GLUE_RELEASE_SPIN_LOCK(prGlueInfo, rLockCategory) \ + { \ + if (rLockCategory < SPIN_LOCK_NUM) \ + spin_unlock_irqrestore(\ + &(prGlueInfo->rSpinLock[rLockCategory]), __ulFlags); \ + } +#endif /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */ + +/*----------------------------------------------------------------------------*/ +/* Macros for accessing Reserved Fields of native packet */ +/*----------------------------------------------------------------------------*/ + +#define GLUE_GET_PKT_PRIVATE_DATA(_p) \ + ((struct PACKET_PRIVATE_DATA *)(&(((struct sk_buff *)(_p))->cb[0]))) + +#define GLUE_GET_PKT_QUEUE_ENTRY(_p) \ + (&(GLUE_GET_PKT_PRIVATE_DATA(_p)->rQueEntry)) + +#define GLUE_GET_PKT_DESCRIPTOR(_prQueueEntry) \ + ((void *) (((unsigned long)_prQueueEntry) \ + - offsetof(struct sk_buff, cb[0]))) + +#define GLUE_SET_PKT_TID(_p, _tid) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->ucTid = (uint8_t)(_tid)) + +#define GLUE_GET_PKT_TID(_p) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->ucTid) + +#define GLUE_SET_PKT_FLAG(_p, _flag) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->u2Flag |= BIT(_flag)) + +#define GLUE_TEST_PKT_FLAG(_p, _flag) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->u2Flag & BIT(_flag)) + +#define GLUE_IS_PKT_FLAG_SET(_p) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->u2Flag) + +#define GLUE_SET_PKT_BSS_IDX(_p, _ucBssIndex) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->ucBssIdx = (uint8_t)(_ucBssIndex)) + +#define GLUE_GET_PKT_BSS_IDX(_p) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->ucBssIdx) + +#define GLUE_SET_PKT_HEADER_LEN(_p, _ucMacHeaderLen) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->ucHeaderLen = \ + (uint8_t)(_ucMacHeaderLen)) + +#define GLUE_GET_PKT_HEADER_LEN(_p) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->ucHeaderLen) + +#define GLUE_SET_PKT_FRAME_LEN(_p, _u2PayloadLen) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->u2FrameLen = (uint16_t)(_u2PayloadLen)) + +#define GLUE_GET_PKT_FRAME_LEN(_p) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->u2FrameLen) + +#define GLUE_SET_PKT_ARRIVAL_TIME(_p, _rSysTime) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->rArrivalTime = (OS_SYSTIME)(_rSysTime)) + +#define GLUE_GET_PKT_ARRIVAL_TIME(_p) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->rArrivalTime) + +#define GLUE_SET_PKT_IP_ID(_p, _u2IpId) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->u2IpId = (uint16_t)(_u2IpId)) + +#define GLUE_GET_PKT_IP_ID(_p) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->u2IpId) + +#define GLUE_SET_PKT_SEQ_NO(_p, _ucSeqNo) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->ucSeqNo = (uint8_t)(_ucSeqNo)) + +#define GLUE_GET_PKT_SEQ_NO(_p) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->ucSeqNo) + +#define GLUE_SET_PKT_FLAG_PROF_MET(_p) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->ucProfilingFlag |= BIT(0)) + +#define GLUE_GET_PKT_IS_PROF_MET(_p) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->ucProfilingFlag & BIT(0)) + +#define GLUE_SET_PKT_XTIME(_p, _rSysTime) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->u8ArriveTime = (uint64_t)(_rSysTime)) + +#define GLUE_GET_PKT_XTIME(_p) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->u8ArriveTime) + +#define GLUE_GET_INDEPENDENT_PKT(_p) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->fgIsIndependentPkt) + +#define GLUE_SET_INDEPENDENT_PKT(_p, _fgIsIndePkt) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->fgIsIndependentPkt = _fgIsIndePkt) + +#define GLUE_GET_PKT_PRIVATE_RX_DATA(_p) \ + ((struct PACKET_PRIVATE_RX_DATA *)(&(((struct sk_buff *)(_p))->cb[24]))) + +#define GLUE_RX_SET_PKT_INT_TIME(_p, _rTime) \ + (GLUE_GET_PKT_PRIVATE_RX_DATA(_p)->u8IntTime = (uint64_t)(_rTime)) + +#define GLUE_RX_GET_PKT_INT_TIME(_p) \ + (GLUE_GET_PKT_PRIVATE_RX_DATA(_p)->u8IntTime) + +#define GLUE_RX_SET_PKT_RX_TIME(_p, _rTime) \ + (GLUE_GET_PKT_PRIVATE_RX_DATA(_p)->u8RxTime = (uint64_t)(_rTime)) + +#define GLUE_RX_GET_PKT_RX_TIME(_p) \ + (GLUE_GET_PKT_PRIVATE_RX_DATA(_p)->u8RxTime) + +#define GLUE_GET_PKT_ETHER_DEST_ADDR(_p) \ + ((uint8_t *)&(((struct sk_buff *)(_p))->data)) + +#define GLUE_COPY_PRIV_DATA(_pDst, _pSrc) \ + (kalMemCopy(GLUE_GET_PKT_PRIVATE_DATA(_pDst), \ + GLUE_GET_PKT_PRIVATE_DATA(_pSrc), sizeof(struct PACKET_PRIVATE_DATA))) + +/* Check validity of prDev, private data, and pointers */ +#define GLUE_CHK_DEV(prDev) \ + ((prDev && *((struct GLUE_INFO **) netdev_priv(prDev))) ? TRUE : FALSE) + +#define GLUE_CHK_PR2(prDev, pr2) \ + ((GLUE_CHK_DEV(prDev) && pr2) ? TRUE : FALSE) + +#define GLUE_CHK_PR3(prDev, pr2, pr3) \ + ((GLUE_CHK_PR2(prDev, pr2) && pr3) ? TRUE : FALSE) + +#define GLUE_CHK_PR4(prDev, pr2, pr3, pr4) \ + ((GLUE_CHK_PR3(prDev, pr2, pr3) && pr4) ? TRUE : FALSE) + +#define GLUE_SET_EVENT(pr) \ + kalSetEvent(pr) + +#define GLUE_INC_REF_CNT(_refCount) atomic_inc((atomic_t *)&(_refCount)) +#define GLUE_DEC_REF_CNT(_refCount) atomic_dec((atomic_t *)&(_refCount)) +#define GLUE_ADD_REF_CNT(_value, _refCount) \ + atomic_add(_value, (atomic_t *)&(_refCount)) +#define GLUE_SUB_REF_CNT(_value, _refCount) \ + atomic_sub(_value, (atomic_t *)&(_refCount)) +#define GLUE_GET_REF_CNT(_refCount) atomic_read((atomic_t *)&(_refCount)) + +#define DbgPrint(...) + +#define GLUE_LOOKUP_FUN(fun_name) kallsyms_lookup_name(fun_name) + + +#if CFG_MET_TAG_SUPPORT +#define GL_MET_TAG_START(_id, _name) met_tag_start(_id, _name) +#define GL_MET_TAG_END(_id, _name) met_tag_end(_id, _name) +#define GL_MET_TAG_ONESHOT(_id, _name, _value) \ + met_tag_oneshot(_id, _name, _value) +#define GL_MET_TAG_DISABLE(_id) met_tag_disable(_id) +#define GL_MET_TAG_ENABLE(_id) met_tag_enable(_id) +#define GL_MET_TAG_REC_ON() met_tag_record_on() +#define GL_MET_TAG_REC_OFF() met_tag_record_off() +#define GL_MET_TAG_INIT() met_tag_init() +#define GL_MET_TAG_UNINIT() met_tag_uninit() +#else +#define GL_MET_TAG_START(_id, _name) +#define GL_MET_TAG_END(_id, _name) +#define GL_MET_TAG_ONESHOT(_id, _name, _value) +#define GL_MET_TAG_DISABLE(_id) +#define GL_MET_TAG_ENABLE(_id) +#define GL_MET_TAG_REC_ON() +#define GL_MET_TAG_REC_OFF() +#define GL_MET_TAG_INIT() +#define GL_MET_TAG_UNINIT() +#endif + +#define MET_TAG_ID 0 + +/*----------------------------------------------------------------------------*/ +/* Macros of Data Type Check */ +/*----------------------------------------------------------------------------*/ +/* Kevin: we don't have to call following function to inspect the data + * structure. + * It will check automatically while at compile time. + */ +static __KAL_INLINE__ void glPacketDataTypeCheck(void) +{ + DATA_STRUCT_INSPECTING_ASSERT(sizeof(struct + PACKET_PRIVATE_DATA) <= sizeof(((struct sk_buff *) 0)->cb)); +} + +static bool is_critical_packet(struct sk_buff *skb) +{ +#if CFG_CHANGE_CRITICAL_PACKET_PRIORITY + uint8_t *pucPkt; + uint16_t u2EtherType; + bool is_critical = false; + + if (!skb) + return false; + + pucPkt = skb->data; + u2EtherType = (pucPkt[ETH_TYPE_LEN_OFFSET] << 8) + | (pucPkt[ETH_TYPE_LEN_OFFSET + 1]); + + switch (u2EtherType) { + case ETH_P_ARP: + case ETH_P_1X: + case ETH_P_PRE_1X: +#if CFG_SUPPORT_WAPI + case ETH_WPI_1X: +#endif + is_critical = true; + break; + default: + is_critical = false; + break; + } + return is_critical; +#else + return false; +#endif +} + +static inline u16 mtk_wlan_ndev_select_queue( + struct sk_buff *skb) +{ + static u16 ieee8021d_to_queue[8] = { 1, 0, 0, 1, 2, 2, 3, 3 }; + + if (is_critical_packet(skb)) { + skb->priority = WMM_UP_VO_INDEX; + } else { + /* cfg80211_classify8021d returns 0~7 */ +#if KERNEL_VERSION(3, 14, 0) > CFG80211_VERSION_CODE + skb->priority = cfg80211_classify8021d(skb); +#else + skb->priority = cfg80211_classify8021d(skb, NULL); +#endif + } + return ieee8021d_to_queue[skb->priority]; +} + +#if KERNEL_VERSION(2, 6, 34) > LINUX_VERSION_CODE +#define netdev_for_each_mc_addr(mclist, dev) \ + for (mclist = dev->mc_list; mclist; mclist = mclist->next) +#endif + +#if KERNEL_VERSION(2, 6, 34) > LINUX_VERSION_CODE +#define GET_ADDR(ha) (ha->da_addr) +#else +#define GET_ADDR(ha) (ha->addr) +#endif + +#if KERNEL_VERSION(2, 6, 35) <= LINUX_VERSION_CODE +#define LIST_FOR_EACH_IPV6_ADDR(_prIfa, _ip6_ptr) \ + list_for_each_entry(_prIfa, &((struct inet6_dev *) \ + _ip6_ptr)->addr_list, if_list) +#else +#define LIST_FOR_EACH_IPV6_ADDR(_prIfa, _ip6_ptr) \ + for (_prIfa = ((struct inet6_dev *) _ip6_ptr)->addr_list; _prIfa; \ + _prIfa = _prIfa->if_next) +#endif + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +#if WLAN_INCLUDE_PROC +int32_t procCreateFsEntry(struct GLUE_INFO *prGlueInfo); +int32_t procRemoveProcfs(void); + + +int32_t procInitFs(void); +int32_t procUninitProcFs(void); + + + +int32_t procInitProcfs(struct net_device *prDev, + char *pucDevName); +#endif /* WLAN_INCLUDE_PROC */ + +#if WLAN_INCLUDE_SYS +int32_t sysCreateFsEntry(struct GLUE_INFO *prGlueInfo); +int32_t sysRemoveSysfs(void); +int32_t sysInitFs(void); +int32_t sysUninitSysFs(void); +void sysMacAddrOverride(uint8_t *prMacAddr); +#endif /* WLAN_INCLUDE_SYS */ + +#if CFG_ENABLE_BT_OVER_WIFI +u_int8_t glRegisterAmpc(struct GLUE_INFO *prGlueInfo); + +u_int8_t glUnregisterAmpc(struct GLUE_INFO *prGlueInfo); +#endif + +#if CFG_ENABLE_WIFI_DIRECT +void p2pSetMulticastListWorkQueueWrapper(struct GLUE_INFO + *prGlueInfo); +#endif + +struct GLUE_INFO *wlanGetGlueInfo(void); +#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE +u16 wlanSelectQueue(struct net_device *dev, + struct sk_buff *skb, + struct net_device *sb_dev); +#elif KERNEL_VERSION(4, 19, 0) <= CFG80211_VERSION_CODE +u16 wlanSelectQueue(struct net_device *dev, + struct sk_buff *skb, + struct net_device *sb_dev, select_queue_fallback_t fallback); +#elif KERNEL_VERSION(3, 14, 0) <= CFG80211_VERSION_CODE +u16 wlanSelectQueue(struct net_device *dev, + struct sk_buff *skb, + void *accel_priv, select_queue_fallback_t fallback); +#elif KERNEL_VERSION(3, 13, 0) <= LINUX_VERSION_CODE +u16 wlanSelectQueue(struct net_device *dev, + struct sk_buff *skb, + void *accel_priv); +#else +u16 wlanSelectQueue(struct net_device *dev, + struct sk_buff *skb); +#endif + +void wlanDebugInit(void); + +uint32_t wlanSetDriverDbgLevel(IN uint32_t u4DbgIdx, + IN uint32_t u4DbgMask); + +uint32_t wlanGetDriverDbgLevel(IN uint32_t u4DbgIdx, + OUT uint32_t *pu4DbgMask); + +void wlanSetSuspendMode(struct GLUE_INFO *prGlueInfo, + u_int8_t fgEnable); + +void wlanGetConfig(struct ADAPTER *prAdapter); + +uint32_t wlanDownloadBufferBin(struct ADAPTER *prAdapter); + +uint32_t wlanConnacDownloadBufferBin(struct ADAPTER + *prAdapter); + +/******************************************************************************* + * E X T E R N A L F U N C T I O N S / V A R I A B L E + ******************************************************************************* + */ +extern struct net_device *gPrP2pDev[KAL_P2P_NUM]; +extern struct net_device *gPrDev; +extern struct wireless_dev *gprWdev[KAL_AIS_NUM]; +extern uint32_t g_u4DevIdx[KAL_P2P_NUM]; +extern enum ENUM_NVRAM_STATE g_NvramFsm; + + +#ifdef CFG_DRIVER_INF_NAME_CHANGE +extern char *gprifnameap; +extern char *gprifnamep2p; +extern char *gprifnamesta; +#endif /* CFG_DRIVER_INF_NAME_CHANGE */ + +void wlanRegisterInetAddrNotifier(void); +void wlanUnregisterInetAddrNotifier(void); +void wlanRegisterNetdevNotifier(void); +void wlanUnregisterNetdevNotifier(void); +#if CFG_MTK_ANDROID_WMT +typedef int (*set_p2p_mode) (struct net_device *netdev, + struct PARAM_CUSTOM_P2P_SET_STRUCT p2pmode); +extern void register_set_p2p_mode_handler( + set_p2p_mode handler); +#endif + +#if CFG_ENABLE_EARLY_SUSPEND +extern int glRegisterEarlySuspend(struct early_suspend + *prDesc, + early_suspend_callback wlanSuspend, + late_resume_callback wlanResume); + +extern int glUnregisterEarlySuspend(struct early_suspend + *prDesc); +#endif + +#if CFG_MET_PACKET_TRACE_SUPPORT +void kalMetTagPacket(IN struct GLUE_INFO *prGlueInfo, + IN void *prPacket, IN enum ENUM_TX_PROFILING_TAG eTag); + +void kalMetInit(IN struct GLUE_INFO *prGlueInfo); +#endif + +void wlanUpdateChannelTable(struct GLUE_INFO *prGlueInfo); + +#if CFG_SUPPORT_SAP_DFS_CHANNEL +void wlanUpdateDfsChannelTable(struct GLUE_INFO *prGlueInfo, + uint8_t ucRoleIdx, uint8_t ucChannel, uint8_t ucBandWidth, + enum ENUM_CHNL_EXT eBssSCO, uint32_t u4CenterFreq); +#endif + +#if (CFG_MTK_ANDROID_WMT || WLAN_INCLUDE_PROC) +int set_p2p_mode_handler(struct net_device *netdev, + struct PARAM_CUSTOM_P2P_SET_STRUCT p2pmode); +#endif + +#if CFG_ENABLE_UNIFY_WIPHY +const struct net_device_ops *wlanGetNdevOps(void); +#endif + +#if CFG_MTK_ANDROID_WMT +extern void connectivity_export_show_stack(struct task_struct *tsk, + unsigned long *sp); +#endif + +netdev_tx_t wlanHardStartXmit(struct sk_buff *prSkb, struct net_device *prDev); + +typedef uint8_t (*file_buf_handler) (void *ctx, + const char __user *buf, + uint16_t length); +extern void register_file_buf_handler(file_buf_handler handler, + void *ctx, + uint8_t ucType); + +/* extern from wifi wmt cdev wifi */ +extern uint32_t get_low_latency_mode(void); + +extern const uint8_t *kalFindIeMatchMask(uint8_t eid, + const uint8_t *ies, int len, + const uint8_t *match, + int match_len, int match_offset, + const uint8_t *match_mask); + + +void wlanNvramSetState(enum ENUM_NVRAM_STATE state); +enum ENUM_NVRAM_STATE wlanNvramGetState(void); + +#endif /* _GL_OS_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_p2p_ioctl.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_p2p_ioctl.h new file mode 100644 index 0000000000000000000000000000000000000000..8613e2190401d762ea806354e7dd748885073e81 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_p2p_ioctl.h @@ -0,0 +1,849 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/ + * os/linux/include/gl_p2p_ioctl.h#9 + */ + +/*! \file gl_p2p_ioctl.h + * \brief This file is for custom ioctls for Wi-Fi Direct only + */ + + +#ifndef _GL_P2P_IOCTL_H +#define _GL_P2P_IOCTL_H + +/****************************************************************************** + * C O M P I L E R F L A G S + ****************************************************************************** + */ + +/****************************************************************************** + * E X T E R N A L R E F E R E N C E S + ****************************************************************************** + */ +#include +#include +#include +#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 +#include +#include +#endif + +#include "wlan_oid.h" + +/****************************************************************************** + * C O N S T A N T S + ****************************************************************************** + */ + +/* (WirelessExtension) Private I/O Controls */ +#define IOC_P2P_CFG_DEVICE (SIOCIWFIRSTPRIV+0) +#define IOC_P2P_PROVISION_COMPLETE (SIOCIWFIRSTPRIV+2) +#define IOC_P2P_START_STOP_DISCOVERY (SIOCIWFIRSTPRIV+4) +#define IOC_P2P_DISCOVERY_RESULTS (SIOCIWFIRSTPRIV+5) +#define IOC_P2P_WSC_BEACON_PROBE_RSP_IE (SIOCIWFIRSTPRIV+6) +#define IOC_P2P_GO_WSC_IE IOC_P2P_WSC_BEACON_PROBE_RSP_IE +#define IOC_P2P_CONNECT_DISCONNECT (SIOCIWFIRSTPRIV+8) +#define IOC_P2P_PASSWORD_READY (SIOCIWFIRSTPRIV+10) +/* #define IOC_P2P_SET_PWR_MGMT_PARAM (SIOCIWFIRSTPRIV+12) */ +#define IOC_P2P_SET_INT (SIOCIWFIRSTPRIV+12) +#define IOC_P2P_GET_STRUCT (SIOCIWFIRSTPRIV+13) +#define IOC_P2P_SET_STRUCT (SIOCIWFIRSTPRIV+14) +#define IOC_P2P_GET_REQ_DEVICE_INFO (SIOCIWFIRSTPRIV+15) + +#define PRIV_CMD_INT_P2P_SET 0 + +/* IOC_P2P_PROVISION_COMPLETE (iw_point . flags) */ +#define P2P_PROVISIONING_SUCCESS 0 +#define P2P_PROVISIONING_FAIL 1 + +/* IOC_P2P_START_STOP_DISCOVERY (iw_point . flags) */ +#define P2P_STOP_DISCOVERY 0 +#define P2P_START_DISCOVERY 1 + +/* IOC_P2P_CONNECT_DISCONNECT (iw_point . flags) */ +#define P2P_CONNECT 0 +#define P2P_DISCONNECT 1 + +/* IOC_P2P_START_STOP_DISCOVERY (scan_type) */ +#define P2P_SCAN_FULL_AND_FIND 0 +#define P2P_SCAN_FULL 1 +#define P2P_SCAN_SEARCH_AND_LISTEN 2 +#define P2P_LISTEN 3 + +/* IOC_P2P_GET_STRUCT/IOC_P2P_SET_STRUCT */ +#define P2P_SEND_SD_RESPONSE 0 +#define P2P_GET_SD_REQUEST 1 +#define P2P_SEND_SD_REQUEST 2 +#define P2P_GET_SD_RESPONSE 3 +#define P2P_TERMINATE_SD_PHASE 4 + +#define CHN_DIRTY_WEIGHT_UPPERBOUND 4 + +/****************************************************************************** + * D A T A T Y P E S + ****************************************************************************** + */ +/*------------------------------------------------------------------------*/ +/* Wireless Extension: Private I/O Control */ +/*------------------------------------------------------------------------*/ +struct iw_p2p_cfg_device_type { + void __user *ssid; + uint8_t ssid_len; + uint8_t pri_device_type[8]; + uint8_t snd_device_type[8]; + void __user *device_name; + uint8_t device_name_len; + uint8_t intend; + uint8_t persistence; + uint8_t sec_mode; + uint8_t ch; + uint8_t ch_width; /* 0: 20 Mhz 1:20/40 Mhz auto */ + uint8_t max_scb; +}; + +struct iw_p2p_hostapd_param { + uint8_t cmd; + uint8_t rsv[3]; + uint8_t sta_addr[6]; + void __user *data; + uint16_t len; +}; + +struct iw_p2p_req_device_type { + uint8_t scan_type; /* 0: Full scan + Find + * 1: Full scan + * 2: Scan (Search +Listen) + * 3: Listen + * other : reserved + */ + uint8_t pri_device_type[8]; + void __user *probe_req_ie; + uint16_t probe_req_len; + void __user *probe_rsp_ie; + uint16_t probe_rsp_len; +}; + +struct iw_p2p_connect_device { + uint8_t sta_addr[6]; + /* 0: P2P Device, 1:GC, 2: GO */ + uint8_t p2pRole; + /* 0: Don't needed provision, 1: doing the wsc provision first */ + uint8_t needProvision; + /* 1: auth peer invitation request */ + uint8_t authPeer; + /* Request Peer Device used config method */ + uint8_t intend_config_method; +}; + +struct iw_p2p_password_ready { + uint8_t active_config_method; + void __user *probe_req_ie; + uint16_t probe_req_len; + void __user *probe_rsp_ie; + uint16_t probe_rsp_len; +}; + +struct iw_p2p_device_req { + uint8_t name[33]; + uint32_t name_len; + uint8_t device_addr[6]; + uint8_t device_type; + int32_t config_method; + int32_t active_config_method; +}; + +struct iw_p2p_transport_struct { + uint32_t u4CmdId; + uint32_t inBufferLength; + uint32_t outBufferLength; + uint8_t aucBuffer[16]; +}; + +/* For Invitation */ +struct iw_p2p_ioctl_invitation_struct { + uint8_t aucDeviceID[6]; + /* BSSID */ + uint8_t aucGroupID[6]; + uint8_t aucSsid[32]; + uint32_t u4SsidLen; + uint8_t ucReinvoke; +}; + +struct iw_p2p_ioctl_abort_invitation { + uint8_t dev_addr[6]; +}; + +struct iw_p2p_ioctl_invitation_indicate { + uint8_t dev_addr[6]; + uint8_t group_bssid[6]; + /* peer device supported config method */ + int32_t config_method; + /* for reinvoke */ + uint8_t dev_name[32]; + uint32_t name_len; + /* for re-invoke, target operating channel */ + uint8_t operating_channel; + /* invitation or re-invoke */ + uint8_t invitation_type; +}; + +struct iw_p2p_ioctl_invitation_status { + uint32_t status_code; +}; + +/* For Formation */ +struct iw_p2p_ioctl_start_formation { + /* bssid */ + uint8_t dev_addr[6]; + /* 0: P2P Device, 1:GC, 2: GO */ + uint8_t role; + /* 0: Don't needed provision, 1: doing the wsc provision first */ + uint8_t needProvision; + /* 1: auth peer invitation request */ + uint8_t auth; + /* Request Peer Device used config method */ + + uint8_t config_method; +}; + +/* SET_STRUCT / GET_STRUCT */ +enum ENUM_P2P_CMD_ID { + P2P_CMD_ID_SEND_SD_RESPONSE = 0, /* 0x00 (Set) */ + P2P_CMD_ID_GET_SD_REQUEST, /* 0x01 (Get) */ + P2P_CMD_ID_SEND_SD_REQUEST, /* 0x02 (Set) */ + P2P_CMD_ID_GET_SD_RESPONSE, /* 0x03 (Get) */ + P2P_CMD_ID_TERMINATE_SD_PHASE, /* 0x04 (Set) */ +#if 1 /* CFG_SUPPORT_ANTI_PIRACY */ + P2P_CMD_ID_SEC_CHECK, /* 0x05(Set) */ +#endif + P2P_CMD_ID_INVITATION, /* 0x06 (Set) */ + P2P_CMD_ID_INVITATION_INDICATE, /* 0x07 (Get) */ + P2P_CMD_ID_INVITATION_STATUS, /* 0x08 (Get) */ + P2P_CMD_ID_INVITATION_ABORT, /* 0x09 (Set) */ + P2P_CMD_ID_START_FORMATION, /* 0x0A (Set) */ + P2P_CMD_ID_P2P_VERSION, /* 0x0B (Set/Get) */ + P2P_CMD_ID_GET_CH_LIST = 12, /* 0x0C (Get) */ + P2P_CMD_ID_GET_OP_CH = 14 /* 0x0E (Get) */ +}; + +/* Service Discovery */ +struct iw_p2p_cmd_send_sd_response { + uint8_t rReceiverAddr[PARAM_MAC_ADDR_LEN]; + uint8_t fgNeedTxDoneIndication; + uint8_t ucSeqNum; + uint16_t u2PacketLength; + uint8_t aucPacketContent[0]; /*native 802.11 */ +}; + +struct iw_p2p_cmd_get_sd_request { + uint8_t rTransmitterAddr[PARAM_MAC_ADDR_LEN]; + uint16_t u2PacketLength; + uint8_t aucPacketContent[0]; /*native 802.11 */ +}; + +struct iw_p2p_cmd_send_service_discovery_request { + uint8_t rReceiverAddr[PARAM_MAC_ADDR_LEN]; + uint8_t fgNeedTxDoneIndication; + uint8_t ucSeqNum; + uint16_t u2PacketLength; + uint8_t aucPacketContent[0]; /*native 802.11 */ +}; + +struct iw_p2p_cmd_get_sd_response { + uint8_t rTransmitterAddr[PARAM_MAC_ADDR_LEN]; + uint16_t u2PacketLength; + uint8_t aucPacketContent[0]; /*native 802.11 */ +}; + +struct iw_p2p_cmd_terminate_sd_phase { + uint8_t rPeerAddr[PARAM_MAC_ADDR_LEN]; +}; + +struct iw_p2p_version { + uint32_t u4Version; +}; + +/****************************************************************************** + * P U B L I C D A T A + ****************************************************************************** + */ +extern struct ieee80211_supported_band mtk_band_2ghz; +extern struct ieee80211_supported_band mtk_band_5ghz; + +extern const uint32_t mtk_cipher_suites[8]; + + +/****************************************************************************** + * P R I V A T E D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * M A C R O S + ****************************************************************************** + */ +/* Macros used for cfg80211 */ +#define RATETAB_ENT(_rate, _rateid, _flags) \ +{ \ + .bitrate = (_rate), \ + .hw_value = (_rateid), \ + .flags = (_flags), \ +} + +#define CHAN2G(_channel, _freq, _flags) \ +{ \ + .band = KAL_BAND_2GHZ, \ + .center_freq = (_freq), \ + .hw_value = (_channel), \ + .flags = (_flags), \ + .max_antenna_gain = 0, \ + .max_power = 30, \ +} + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +#if (CFG_ENABLE_WIFI_DIRECT_CFG_80211 != 0) + +#if KERNEL_VERSION(4, 1, 0) <= CFG80211_VERSION_CODE +struct wireless_dev *mtk_p2p_cfg80211_add_iface(struct wiphy *wiphy, + const char *name, + unsigned char name_assign_type, + enum nl80211_iftype type, + u32 *flags, + struct vif_params *params); +#else +struct wireless_dev *mtk_p2p_cfg80211_add_iface(struct wiphy *wiphy, + const char *name, + enum nl80211_iftype type, + u32 *flags, + struct vif_params *params); +#endif + +int +mtk_p2p_cfg80211_change_iface(struct wiphy *wiphy, + struct net_device *ndev, + enum nl80211_iftype type, + u32 *flags, + struct vif_params *params); + +int mtk_p2p_cfg80211_del_iface(struct wiphy *wiphy, + struct wireless_dev *wdev); + +int +mtk_p2p_cfg80211_add_key(struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index, + bool pairwise, + const u8 *mac_addr, + struct key_params *params); + +int +mtk_p2p_cfg80211_get_key(struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index, + bool pairwise, + const u8 *mac_addr, + void *cookie, + void (*callback)(void *cookie, struct key_params *)); + +int +mtk_p2p_cfg80211_del_key(struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index, + bool pairwise, + const u8 *mac_addr); + +int +mtk_p2p_cfg80211_set_default_key(struct wiphy *wiphy, + struct net_device *netdev, + u8 key_index, + bool unicast, + bool multicast); + +int +mtk_p2p_cfg80211_set_mgmt_key(struct wiphy *wiphy, + struct net_device *dev, + u8 key_index); + +#if KERNEL_VERSION(3, 16, 0) <= CFG80211_VERSION_CODE +int mtk_p2p_cfg80211_get_station(struct wiphy *wiphy, + struct net_device *ndev, + const u8 *mac, + struct station_info *sinfo); +#else +int mtk_p2p_cfg80211_get_station(struct wiphy *wiphy, + struct net_device *ndev, + u8 *mac, + struct station_info *sinfo); +#endif +int mtk_p2p_cfg80211_scan(struct wiphy *wiphy, + struct cfg80211_scan_request *request); + +void mtk_p2p_cfg80211_abort_scan(struct wiphy *wiphy, + struct wireless_dev *wdev); + +int mtk_p2p_cfg80211_set_wiphy_params(struct wiphy *wiphy, + u32 changed); + +int mtk_p2p_cfg80211_connect(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_connect_params *sme); + +int mtk_p2p_cfg80211_disconnect(struct wiphy *wiphy, + struct net_device *dev, + u16 reason_code); + +int mtk_p2p_cfg80211_join_ibss(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_ibss_params *params); + +int mtk_p2p_cfg80211_leave_ibss(struct wiphy *wiphy, + struct net_device *dev); + +int mtk_p2p_cfg80211_set_txpower(struct wiphy *wiphy, + struct wireless_dev *wdev, + enum nl80211_tx_power_setting type, + int mbm); + +int mtk_p2p_cfg80211_get_txpower(struct wiphy *wiphy, + struct wireless_dev *wdev, + int *dbm); + +int mtk_p2p_cfg80211_remain_on_channel(struct wiphy *wiphy, + struct wireless_dev *wdev, + struct ieee80211_channel *chan, + unsigned int duration, + u64 *cookie); + +int mtk_p2p_cfg80211_cancel_remain_on_channel( + struct wiphy *wiphy, + struct wireless_dev *wdev, + u64 cookie); + +int mtk_p2p_cfg80211_set_power_mgmt(struct wiphy *wiphy, + struct net_device *dev, + bool enabled, + int timeout); + +#if (CFG_SUPPORT_DFS_MASTER == 1) + +#if KERNEL_VERSION(3, 15, 0) <= CFG80211_VERSION_CODE +int mtk_p2p_cfg80211_start_radar_detection(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_chan_def *chandef, + unsigned int cac_time_ms); +#else +int mtk_p2p_cfg80211_start_radar_detection(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_chan_def *chandef); +#endif + + +#if KERNEL_VERSION(3, 13, 0) <= CFG80211_VERSION_CODE +int mtk_p2p_cfg80211_channel_switch(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_csa_settings *params); +#endif +#endif + +int mtk_p2p_cfg80211_change_bss(struct wiphy *wiphy, + struct net_device *dev, + struct bss_parameters *params); + +int mtk_p2p_cfg80211_deauth(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_deauth_request *req); + +int mtk_p2p_cfg80211_disassoc(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_disassoc_request *req); + +int mtk_p2p_cfg80211_start_ap(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_ap_settings *settings); + +int mtk_p2p_cfg80211_change_beacon(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_beacon_data *info); + +#if KERNEL_VERSION(3, 14, 0) <= CFG80211_VERSION_CODE +int mtk_p2p_cfg80211_mgmt_tx(struct wiphy *wiphy, + struct wireless_dev *wdev, + struct cfg80211_mgmt_tx_params *params, + u64 *cookie); +#else +int mtk_p2p_cfg80211_mgmt_tx(struct wiphy *wiphy, + struct wireless_dev *wdev, + struct ieee80211_channel *chan, + bool offchan, + unsigned int wait, + const u8 *buf, + size_t len, + bool no_cck, + bool dont_wait_for_ack, + u64 *cookie); +#endif + +#if KERNEL_VERSION(3, 19, 0) <= CFG80211_VERSION_CODE +int mtk_p2p_cfg80211_del_station(struct wiphy *wiphy, + struct net_device *dev, + struct station_del_parameters *params); +#elif KERNEL_VERSION(3, 16, 0) <= CFG80211_VERSION_CODE +int mtk_p2p_cfg80211_del_station(struct wiphy *wiphy, + struct net_device *dev, + const u8 *mac); +#else +int mtk_p2p_cfg80211_del_station(struct wiphy *wiphy, + struct net_device *dev, + u8 *mac); +#endif + +int mtk_p2p_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, + struct wireless_dev *wdev, + u64 cookie); + +int mtk_p2p_cfg80211_stop_ap(struct wiphy *wiphy, + struct net_device *dev); + +int mtk_p2p_cfg80211_set_channel(struct wiphy *wiphy, + struct cfg80211_chan_def *chandef); + +void mtk_p2p_cfg80211_mgmt_frame_register(IN struct wiphy *wiphy, + struct wireless_dev *wdev, + IN u16 frame_type, + IN bool reg); + +int +mtk_p2p_cfg80211_set_bitrate_mask(IN struct wiphy *wiphy, + IN struct net_device *dev, + IN const u8 *peer, + IN const struct cfg80211_bitrate_mask *mask); + +#ifdef CONFIG_NL80211_TESTMODE +#if KERNEL_VERSION(3, 12, 0) <= CFG80211_VERSION_CODE +int mtk_p2p_cfg80211_testmode_cmd(struct wiphy *wiphy, + struct wireless_dev *wdev, + void *data, + int len); +#else +int mtk_p2p_cfg80211_testmode_cmd(struct wiphy *wiphy, + void *data, + int len); +#endif +int mtk_p2p_cfg80211_testmode_p2p_sigma_pre_cmd(IN struct wiphy *wiphy, + IN void *data, + IN int len); + +int mtk_p2p_cfg80211_testmode_p2p_sigma_cmd(IN struct wiphy *wiphy, + IN void *data, + IN int len); + +#if CFG_SUPPORT_WFD +int mtk_p2p_cfg80211_testmode_wfd_update_cmd(IN struct wiphy *wiphy, + IN void *data, + IN int len); +#endif + +int mtk_p2p_cfg80211_testmode_hotspot_block_list_cmd(IN struct wiphy *wiphy, + IN void *data, + IN int len); + +int mtk_p2p_cfg80211_testmode_hotspot_config_cmd(IN struct wiphy *wiphy, + IN void *data, + IN int len); + +#else +/* IGNORE KERNEL DEPENCY ERRORS*/ +/*#error "Please ENABLE kernel config (CONFIG_NL80211_TESTMODE) + * to support Wi-Fi Direct" + */ +#endif + +#endif + +/* I/O control handlers */ + +int +mtk_p2p_wext_get_priv(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_reconnect(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_set_auth(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_set_key(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_mlme_handler(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_set_powermode(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_get_powermode(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +/* Private Wireless I/O Controls takes use of iw_handler */ +int +mtk_p2p_wext_set_local_dev_info(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_set_provision_complete(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_start_stop_discovery(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_discovery_results(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_wsc_ie(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_connect_disconnect(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_password_ready(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_request_dev_info(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_invitation_indicate(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_invitation_status(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_set_pm_param(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_set_ps_profile(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_set_network_address(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_set_int(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +/* Private Wireless I/O Controls for IOC_SET_STRUCT/IOC_GET_STRUCT */ +int +mtk_p2p_wext_set_struct(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_get_struct(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +/* IOC_SET_STRUCT/IOC_GET_STRUCT: Service Discovery */ +int +mtk_p2p_wext_get_service_discovery_request(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_get_service_discovery_response(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_send_service_discovery_request(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_send_service_discovery_response(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_terminate_service_discovery_phase(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +#if CFG_SUPPORT_ANTI_PIRACY +int +mtk_p2p_wext_set_sec_check_request(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_get_sec_check_response(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); +#endif + +int +mtk_p2p_wext_set_noa_param(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_set_oppps_param(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_set_p2p_version(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_get_p2p_version(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +void mtk_p2p_wext_set_Multicastlist(IN struct GLUE_INFO *prGlueInfo); + +#if CFG_SUPPORT_P2P_RSSI_QUERY +int +mtk_p2p_wext_get_rssi(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +struct iw_statistics *mtk_p2p_wext_get_wireless_stats( + struct net_device *prDev); + +#endif + +int +mtk_p2p_wext_set_txpow(IN struct net_device *prDev, + IN struct iw_request_info *prIwrInfo, + IN OUT union iwreq_data *prTxPow, + IN char *pcExtra); + +#endif /* _GL_P2P_IOCTL_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_p2p_kal.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_p2p_kal.h new file mode 100644 index 0000000000000000000000000000000000000000..b2123bf68602a64bf9b209cba501dcb38c9b136e --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_p2p_kal.h @@ -0,0 +1,388 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/ + * os/linux/include/gl_p2p_kal.h#2 + */ + +/*! \file gl_p2p_kal.h + * \brief Declaration of KAL functions for Wi-Fi Direct support + * - kal*() which is provided by GLUE Layer. + * + * Any definitions in this file will be shared among GLUE Layer + * and internal Driver Stack. + */ + + +#ifndef _GL_P2P_KAL_H +#define _GL_P2P_KAL_H + +/****************************************************************************** + * C O M P I L E R F L A G S + ****************************************************************************** + */ + +/****************************************************************************** + * E X T E R N A L R E F E R E N C E S + ****************************************************************************** + */ +#include "config.h" +#include "gl_typedef.h" +#include "gl_os.h" +#include "wlan_lib.h" +#include "wlan_oid.h" +#include "wlan_p2p.h" +#include "gl_kal.h" +#include "gl_wext_priv.h" +#include "gl_p2p_ioctl.h" +#include "nic/p2p.h" + +#if DBG +extern int allocatedMemSize; +#endif + +u_int8_t kalP2pFuncGetChannelType(IN enum ENUM_CHNL_EXT rChnlSco, + OUT enum nl80211_channel_type *channel_type); + +/****************************************************************************** + * C O N S T A N T S + ****************************************************************************** + */ + +/****************************************************************************** + * M A C R O S + ****************************************************************************** + */ + +/****************************************************************************** + * D A T A T Y P E S + ****************************************************************************** + */ + +/****************************************************************************** + * P U B L I C D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * P R I V A T E D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N D E C L A R A T I O N S + ****************************************************************************** + */ + +/* Service Discovery */ +void kalP2PIndicateSDRequest(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t rPeerAddr[PARAM_MAC_ADDR_LEN], + IN uint8_t ucSeqNum); + +void kalP2PIndicateSDResponse(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t rPeerAddr[PARAM_MAC_ADDR_LEN], + IN uint8_t ucSeqNum); + +void kalP2PIndicateTXDone(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucSeqNum, IN uint8_t ucStatus); + +/*------------------------------------------------------------------------*/ +/* Wi-Fi Direct handling */ +/*------------------------------------------------------------------------*/ +/*ENUM_PARAM_MEDIA_STATE_T kalP2PGetState(IN P_GLUE_INFO_T prGlueInfo);*/ + +/*VOID + *kalP2PSetState(IN P_GLUE_INFO_T prGlueInfo, + * IN ENUM_PARAM_MEDIA_STATE_T eState, + * IN PARAM_MAC_ADDRESS rPeerAddr, + * IN UINT_8 ucRole); + */ + +void +kalP2PUpdateAssocInfo(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t *pucFrameBody, + IN uint32_t u4FrameBodyLen, + IN u_int8_t fgReassocRequest, + IN uint8_t ucBssIndex); + +/*UINT_32 kalP2PGetFreqInKHz(IN P_GLUE_INFO_T prGlueInfo);*/ + +int32_t mtk_Netdev_To_RoleIdx(struct GLUE_INFO *prGlueInfo, + struct net_device *ndev, + uint8_t *pucRoleIdx); + +uint8_t kalP2PGetRole(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRoleIdx); + +#if 1 +void kalP2PSetRole(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRole, + IN uint8_t ucRoleIdx); + +#else +void +kalP2PSetRole(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucResult, + IN uint8_t *pucSSID, + IN uint8_t ucSSIDLen, + IN uint8_t ucRole); +#endif + +void kalP2PSetCipher(IN struct GLUE_INFO *prGlueInfo, + IN uint32_t u4Cipher, + IN uint8_t ucRoleIdx); + +u_int8_t kalP2PGetCipher(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRoleIdx); + +u_int8_t kalP2PGetWepCipher(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRoleIdx); + +u_int8_t kalP2PGetTkipCipher(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRoleIdx); + +u_int8_t kalP2PGetCcmpCipher(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRoleIdx); + +void kalP2PSetWscMode(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucWscMode); + +uint8_t kalP2PGetWscMode(IN struct GLUE_INFO *prGlueInfo); + +uint16_t kalP2PCalWSC_IELen(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucType, + IN uint8_t ucRoleIdx); + +void kalP2PGenWSC_IE(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucType, + IN uint8_t *pucBuffer, + IN uint8_t ucRoleIdx); + +void kalP2PUpdateWSC_IE(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucType, + IN uint8_t *pucBuffer, + IN uint16_t u2BufferLength, + IN uint8_t ucRoleIdx); + +uint16_t kalP2PCalP2P_IELen(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucIndex, + IN uint8_t ucRoleIdx); + +void kalP2PGenP2P_IE(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucIndex, + IN uint8_t *pucBuffer, + IN uint8_t ucRoleIdx); + +void kalP2PUpdateP2P_IE(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucIndex, + IN uint8_t *pucBuffer, + IN uint16_t u2BufferLength, + IN uint8_t ucRoleIdx); + +u_int8_t kalP2PIndicateFound(IN struct GLUE_INFO *prGlueInfo); + +void kalP2PIndicateConnReq(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t *pucDevName, + IN int32_t u4NameLength, + IN uint8_t rPeerAddr[PARAM_MAC_ADDR_LEN], + IN uint8_t ucDevType, /* 0: P2P Device / 1: GC / 2: GO */ + IN int32_t i4ConfigMethod, + IN int32_t i4ActiveConfigMethod); + +/*VOID kalP2PInvitationStatus(IN P_GLUE_INFO_T prGlueInfo, + * IN UINT_32 u4InvStatus); + */ + +void +kalP2PInvitationIndication(IN struct GLUE_INFO *prGlueInfo, + IN struct P2P_DEVICE_DESC *prP2pDevDesc, + IN uint8_t *pucSsid, + IN uint8_t ucSsidLen, + IN uint8_t ucOperatingChnl, + IN uint8_t ucInvitationType, + IN uint8_t *pucGroupBssid); + +struct net_device *kalP2PGetDevHdlr(struct GLUE_INFO *prGlueInfo); + +void +kalGetChnlList(IN struct GLUE_INFO *prGlueInfo, + IN enum ENUM_BAND eSpecificBand, + IN uint8_t ucMaxChannelNum, + IN uint8_t *pucNumOfChannel, + IN struct RF_CHANNEL_INFO *paucChannelList); + +#if CFG_SUPPORT_ANTI_PIRACY +void kalP2PIndicateSecCheckRsp(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t *pucRsp, + IN uint16_t u2RspLen); +#endif + +/****************************************************************************** + * F U N C T I O N S + ****************************************************************************** + */ + +void +kalP2PIndicateChannelReady(IN struct GLUE_INFO *prGlueInfo, + IN uint64_t u8SeqNum, + IN uint32_t u4ChannelNum, + IN enum ENUM_BAND eBand, + IN enum ENUM_CHNL_EXT eSco, + IN uint32_t u4Duration); + +void kalP2PIndicateScanDone(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRoleIndex, + IN u_int8_t fgIsAbort); + +void +kalP2PIndicateBssInfo(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t *pucFrameBuf, + IN uint32_t u4BufLen, + IN struct RF_CHANNEL_INFO *prChannelInfo, + IN int32_t i4SignalStrength); + +void +kalP2PIndicateRxMgmtFrame(IN struct GLUE_INFO *prGlueInfo, + IN struct SW_RFB *prSwRfb, + IN u_int8_t fgIsDevInterface, + IN uint8_t ucRoleIdx); + +void kalP2PIndicateMgmtTxStatus(IN struct GLUE_INFO *prGlueInfo, + IN struct MSDU_INFO *prMsduInfo, + IN u_int8_t fgIsAck); + +void +kalP2PIndicateChannelExpired(IN struct GLUE_INFO *prGlueInfo, + IN uint64_t u8SeqNum, + IN uint32_t u4ChannelNum, + IN enum ENUM_BAND eBand, + IN enum ENUM_CHNL_EXT eSco); + +#if CFG_WPS_DISCONNECT || (KERNEL_VERSION(4, 4, 0) <= CFG80211_VERSION_CODE) +void +kalP2PGCIndicateConnectionStatus(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRoleIndex, + IN struct P2P_CONNECTION_REQ_INFO *prP2pConnInfo, + IN uint8_t *pucRxIEBuf, + IN uint16_t u2RxIELen, + IN uint16_t u2StatusReason, + IN uint32_t eStatus); +#else +void +kalP2PGCIndicateConnectionStatus(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRoleIndex, + IN struct P2P_CONNECTION_REQ_INFO *prP2pConnInfo, + IN uint8_t *pucRxIEBuf, + IN uint16_t u2RxIELen, + IN uint16_t u2StatusReason); + +#endif +void +kalP2PGOStationUpdate(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRoleIndex, + IN struct STA_RECORD *prCliStaRec, + IN u_int8_t fgIsNew); + +#if (CFG_SUPPORT_DFS_MASTER == 1) +void +kalP2PRddDetectUpdate(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRoleIndex); + +void +kalP2PCacFinishedUpdate(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRoleIndex); +#endif + +#if CFG_SUPPORT_HOTSPOT_WPS_MANAGER + +u_int8_t kalP2PSetBlackList(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t rbssid[PARAM_MAC_ADDR_LEN], + IN u_int8_t fgIsblock, + IN uint8_t ucRoleIndex); + +u_int8_t kalP2PResetBlackList(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRoleIndex); + +u_int8_t kalP2PCmpBlackList(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t rbssid[PARAM_MAC_ADDR_LEN], + IN uint8_t ucRoleIndex); + +void kalP2PSetMaxClients(IN struct GLUE_INFO *prGlueInfo, + IN uint32_t u4MaxClient, + IN uint8_t ucRoleIndex); + +u_int8_t kalP2PMaxClients(IN struct GLUE_INFO *prGlueInfo, + IN uint32_t u4NumClient, + IN uint8_t ucRoleIndex); + +#endif + +void kalP2pUnlinkBss(IN struct GLUE_INFO *prGlueInfo, IN uint8_t aucBSSID[]); + +void kalP2pIndicateQueuedMgmtFrame(IN struct GLUE_INFO *prGlueInfo, + IN struct P2P_QUEUED_ACTION_FRAME *prFrame); + +void kalP2pIndicateAcsResult(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRoleIndex, + IN uint8_t ucPrimaryCh, + IN uint8_t ucSecondCh, + IN uint8_t ucSeg0Ch, + IN uint8_t ucSeg1Ch, + IN enum ENUM_MAX_BANDWIDTH_SETTING eChnlBw); + +void kalP2pNotifyStopApComplete(IN struct ADAPTER *prAdapter, + IN uint8_t ucRoleIndex); + +void kalP2pIndicateChnlSwitch(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo); + +#endif /* _GL_P2P_KAL_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_p2p_os.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_p2p_os.h new file mode 100644 index 0000000000000000000000000000000000000000..6522cca779d556791e4558ca13ef250ecc2937dd --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_p2p_os.h @@ -0,0 +1,379 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: + * //Department/DaVinci/TRUNK/MT6620_5931_WiFi_Driver/ + * os/linux/include/gl_p2p_os.h#28 + */ + +/*! \file gl_p2p_os.h + * \brief List the external reference to OS for p2p GLUE Layer. + * + * In this file we define the data structure - GLUE_INFO_T to + * store those objects we acquired from OS - + * e.g. TIMER, SPINLOCK, NET DEVICE ... . And all the + * external reference (header file, extern func() ..) to OS + * for GLUE Layer should also list down here. + */ + +#ifndef _GL_P2P_OS_H +#define _GL_P2P_OS_H + +#define VENDOR_SPECIFIC_IE_LENGTH 400 +/****************************************************************************** + * C O M P I L E R F L A G S + ****************************************************************************** + */ + +/****************************************************************************** + * E X T E R N A L R E F E R E N C E S + ****************************************************************************** + */ + +/****************************************************************************** + * E X T E R N A L V A R I A B L E + ****************************************************************************** + */ +#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_WIFI_DIRECT_CFG_80211 +extern const struct net_device_ops p2p_netdev_ops; +#endif + +/****************************************************************************** + * C O N S T A N T S + ****************************************************************************** + */ + +/****************************************************************************** + * M A C R O S + ****************************************************************************** + */ + +/* For SET_STRUCT/GET_STRUCT */ +#define OID_SET_GET_STRUCT_LENGTH 4096 + +#define MAX_P2P_IE_SIZE 5 + +#define P2P_MAXIMUM_CLIENT_COUNT 16 +#define P2P_DEFAULT_CLIENT_COUNT 4 + +/****************************************************************************** + * D A T A T Y P E S + ****************************************************************************** + */ + +/****************************************************************************** + * P U B L I C D A T A + ****************************************************************************** + */ + +extern struct net_device *g_P2pPrDev; +extern struct wireless_dev *gprP2pWdev; +extern struct wireless_dev *gprP2pRoleWdev[KAL_P2P_NUM]; + +/****************************************************************************** + * P R I V A T E D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N D E C L A R A T I O N S + ****************************************************************************** + */ + +struct GL_P2P_INFO { + + /* P2P Device interface handle */ + /*only first p2p have this devhandler*/ + struct net_device *prDevHandler; + /*struct net_device *prRoleDevHandler;*//* TH3 multiple P2P */ + + struct net_device *aprRoleHandler; + + /* Todo : should move to the glueinfo or not*/ + /*UINT_8 ucRoleInterfaceNum;*//* TH3 multiple P2P */ + +#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 + /* cfg80211 */ + struct wireless_dev *prWdev; + /*struct wireless_dev *prRoleWdev[KAL_P2P_NUM];*//* TH3 multiple P2P */ + + /*struct cfg80211_scan_request *prScanRequest;*//* TH3 multiple P2P */ + + /*UINT_64 u8Cookie;*//* TH3 multiple P2P */ + + /* Generation for station list update. */ + int32_t i4Generation; + + /*UINT_32 u4OsMgmtFrameFilter;*//* TH3 multiple P2P */ + +#endif + + /* Device statistics */ + /*struct net_device_stats rNetDevStats;*//* TH3 multiple P2P */ + + /* glue layer variables */ + /*move to glueinfo->adapter */ + /* BOOLEAN fgIsRegistered; */ + /*UINT_32 u4FreqInKHz;*//* TH3 multiple P2P */ /* frequency */ + /* 0: P2P Device, 1: Group Client, 2: Group Owner */ + uint8_t ucRole; + /*UINT_8 ucIntent;*//* TH3 multiple P2P */ /* range: 0-15 */ + /* 0: Search & Listen, 1: Scan without probe response */ + /*UINT_8 ucScanMode;*//* TH3 multiple P2P */ + + /*ENUM_PARAM_MEDIA_STATE_T eState;*//* TH3 multiple P2P */ + /*UINT_32 u4PacketFilter;*//* TH3 multiple P2P */ + /* TH3 multiple P2P */ + /*PARAM_MAC_ADDRESS aucMCAddrList[MAX_NUM_GROUP_ADDR];*/ + + /* connection-requested peer information *//* TH3 multiple P2P */ + /*UINT_8 aucConnReqDevName[32];*//* TH3 multiple P2P */ + /*INT_32 u4ConnReqNameLength;*//* TH3 multiple P2P */ + /*PARAM_MAC_ADDRESS rConnReqPeerAddr;*//* TH3 multiple P2P */ + /* For invitation group. */ + /*PARAM_MAC_ADDRESS rConnReqGroupAddr;*//* TH3 multiple P2P */ + /*UINT_8 ucConnReqDevType;*//* TH3 multiple P2P */ + /*INT_32 i4ConnReqConfigMethod;*//* TH3 multiple P2P */ + /*INT_32 i4ConnReqActiveConfigMethod;*//* TH3 multiple P2P */ + + uint32_t u4CipherPairwise; + /*UINT_8 ucWSCRunning;*//* TH3 multiple P2P */ + + /* 0: beacon, 1: probe req, 2:probe response, 3: assoc response */ + uint8_t aucWSCIE[4][VENDOR_SPECIFIC_IE_LENGTH]; + uint16_t u2WSCIELen[4]; + + uint8_t aucP2PIE[MAX_P2P_IE_SIZE][VENDOR_SPECIFIC_IE_LENGTH]; + uint16_t u2P2PIELen[MAX_P2P_IE_SIZE]; + +#if CFG_SUPPORT_WFD + /* 0 for beacon, 1 for probe req, 2 for probe response */ + uint8_t aucWFDIE[VENDOR_SPECIFIC_IE_LENGTH]; + uint16_t u2WFDIELen; + /* Save the other IE for probe resp */ +#endif +#if CFG_SUPPORT_CUSTOM_VENDOR_IE + uint8_t aucVenderIE[1024]; + uint16_t u2VenderIELen; +#endif + + /*UINT_8 ucOperatingChnl;*//* TH3 multiple P2P */ + /*UINT_8 ucInvitationType;*//* TH3 multiple P2P */ + + /*UINT_32 u4InvStatus;*//* TH3 multiple P2P */ + + /* For SET_STRUCT/GET_STRUCT */ + /*UINT_8 aucOidBuf[OID_SET_GET_STRUCT_LENGTH];*//* TH3 multiple P2P */ + +#if 1 /* CFG_SUPPORT_ANTI_PIRACY */ + /*UINT_8 aucSecCheck[256];*//* TH3 multiple P2P */ + /*UINT_8 aucSecCheckRsp[256];*//* TH3 multiple P2P */ +#endif + +#if (CFG_SUPPORT_DFS_MASTER == 1) + struct cfg80211_chan_def *chandef; + uint32_t cac_time_ms; +#endif + +#if CFG_SUPPORT_HOTSPOT_WPS_MANAGER + uint8_t aucblackMACList[P2P_MAXIMUM_CLIENT_COUNT][PARAM_MAC_ADDR_LEN]; + uint8_t ucMaxClients; +#endif + +#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION + /*BOOLEAN fgEnableHotspotOptimization;*//* TH3 multiple P2P */ + /*UINT_32 u4PsLevel;*//* TH3 multiple P2P */ +#endif + + /* indicate caller thread for stop ap complete */ + struct completion rStopApComp; + + enum ENUM_CHNL_SWITCH_POLICY eChnlSwitchPolicy; +}; + +struct GL_P2P_DEV_INFO { +#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 + struct cfg80211_scan_request *prScanRequest; +#if 0 + struct cfg80211_scan_request rBackupScanRequest; +#endif + uint64_t u8Cookie; + uint32_t u4OsMgmtFrameFilter; +#endif + uint32_t u4PacketFilter; + uint8_t aucMCAddrList[MAX_NUM_GROUP_ADDR][PARAM_MAC_ADDR_LEN]; + uint8_t ucWSCRunning; +}; + +#ifdef CONFIG_NL80211_TESTMODE +struct NL80211_DRIVER_TEST_PRE_PARAMS { + uint16_t idx_mode; + uint16_t idx; + uint32_t value; +}; + +struct NL80211_DRIVER_TEST_PARAMS { + uint32_t index; + uint32_t buflen; +}; + +/* P2P Sigma*/ +struct NL80211_DRIVER_P2P_SIGMA_PARAMS { + struct NL80211_DRIVER_TEST_PARAMS hdr; + uint32_t idx; + uint32_t value; +}; + +/* Hotspot Client Management */ +struct NL80211_DRIVER_hotspot_block_PARAMS { + struct NL80211_DRIVER_TEST_PARAMS hdr; + uint8_t ucblocked; + uint8_t aucBssid[MAC_ADDR_LEN]; +}; + +/* Hotspot Management set config */ +struct NL80211_DRIVER_HOTSPOT_CONFIG_PARAMS { + struct NL80211_DRIVER_TEST_PARAMS hdr; + uint32_t idx; + uint32_t value; +}; + +#if CFG_SUPPORT_WFD +struct NL80211_DRIVER_WFD_PARAMS { + struct NL80211_DRIVER_TEST_PARAMS hdr; + uint32_t WfdCmdType; + uint8_t WfdEnable; + uint8_t WfdCoupleSinkStatus; + uint8_t WfdSessionAvailable; + uint8_t WfdSigmaMode; + uint16_t WfdDevInfo; + uint16_t WfdControlPort; + uint16_t WfdMaximumTp; + uint16_t WfdExtendCap; + uint8_t WfdCoupleSinkAddress[MAC_ADDR_LEN]; + uint8_t WfdAssociatedBssid[MAC_ADDR_LEN]; + uint8_t WfdVideoIp[4]; + uint8_t WfdAudioIp[4]; + uint16_t WfdVideoPort; + uint16_t WfdAudioPort; + uint32_t WfdFlag; + uint32_t WfdPolicy; + uint32_t WfdState; + /* Include Subelement ID, length */ + uint8_t WfdSessionInformationIE[24 * 8]; + uint16_t WfdSessionInformationIELen; + uint8_t aucReserved1[2]; + uint8_t aucWfdPrimarySinkMac[MAC_ADDR_LEN]; + uint8_t aucWfdSecondarySinkMac[MAC_ADDR_LEN]; + uint32_t WfdAdvanceFlag; + /* Group 1 64 bytes */ + uint8_t aucWfdLocalIp[4]; + uint16_t WfdLifetimeAc2; /* Unit is 2 TU */ + uint16_t WfdLifetimeAc3; /* Unit is 2 TU */ + uint16_t WfdCounterThreshold; /* Unit is ms */ + uint8_t aucReserved2[54]; + /* Group 3 64 bytes */ + uint8_t aucReserved3[64]; + /* Group 3 64 bytes */ + uint8_t aucReserved4[64]; +}; +#endif +#endif + +/****************************************************************************** + * P U B L I C D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * P R I V A T E D A T A + ****************************************************************************** + */ + +u_int8_t p2pRegisterToWlan(struct GLUE_INFO *prGlueInfo); + +u_int8_t p2pUnregisterToWlan(struct GLUE_INFO *prGlueInfo); + +u_int8_t p2pLaunch(struct GLUE_INFO *prGlueInfo); + +u_int8_t p2pRemove(struct GLUE_INFO *prGlueInfo); + +void p2pSetMode(IN uint8_t ucAPMode); + +u_int8_t glRegisterP2P(struct GLUE_INFO *prGlueInfo, + const char *prDevName, + const char *prDevName2, + uint8_t ucApMode); + +int glSetupP2P(struct GLUE_INFO *prGlueInfo, + struct wireless_dev *prP2pWdev, + struct net_device *prP2pDev, + uint8_t u4Idx, + u_int8_t fgIsApMode); + +u_int8_t glUnregisterP2P(struct GLUE_INFO *prGlueInfo, uint8_t ucIdx); + +u_int8_t p2pNetRegister(struct GLUE_INFO *prGlueInfo, + u_int8_t fgIsRtnlLockAcquired); + +u_int8_t p2pNetUnregister(struct GLUE_INFO *prGlueInfo, + u_int8_t fgIsRtnlLockAcquired); + + +u_int8_t p2PAllocInfo(IN struct GLUE_INFO *prGlueInfo, IN uint8_t ucIdex); +u_int8_t p2PFreeInfo(struct GLUE_INFO *prGlueInfo, uint8_t ucIdx); + +void p2pSetSuspendMode(struct GLUE_INFO *prGlueInfo, u_int8_t fgEnable); +u_int8_t glP2pCreateWirelessDevice(struct GLUE_INFO *prGlueInfo); +void glP2pDestroyWirelessDevice(void); +void p2pUpdateChannelTableByDomain(struct GLUE_INFO *prGlueInfo); +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_qa_agent.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_qa_agent.h new file mode 100644 index 0000000000000000000000000000000000000000..23dc37f1f43dbac6e88fc1b910432c827e773175 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_qa_agent.h @@ -0,0 +1,438 @@ +/******************************************************************************* + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ +/*! \file gl_qa_agent.h + * \brief This file includes private ioctl support. + */ + +#ifndef _GL_QA_AGENT_H +#define _GL_QA_AGENT_H + +#if CFG_SUPPORT_QA_TOOL + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#if CFG_MTK_ANDROID_EMI +extern phys_addr_t gConEmiPhyBaseFinal; +extern unsigned long long gConEmiSizeFinal; +#endif + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/* Trigger Event */ +#define CAP_FREE_RUN 0 + +/* Ring Mode */ +#define CAP_RING_MODE_ENABLE 1 +#define CAP_RING_MODE_DISABLE 0 + +/* Capture Bit Width */ +#define CAP_96BIT 0 +#define CAP_128BIT + +/* I/Q Type */ +#define CAP_I_TYPE 0 +#define CAP_Q_TYPE 1 +#define NUM_OF_CAP_TYPE 2 + +/* ACTION */ +#define ACTION_SWITCH_TO_RFTEST 0 /* to switch firmware mode between normal mode + * or rf test mode + */ +#define ACTION_IN_RFTEST 1 + +#define HQA_CMD_MAGIC_NO 0x18142880 +#define HQA_CHIP_ID_6632 0x6632 +#define HQA_CHIP_ID_7668 0x7668 + +/*soc3_0 EMI size= 320KB, 1 Sample Count (IQ) =4B (32bit) */ +#define MAX_ICAP_IQ_DATA_CNT (320 * 256) +#define ICAP_EVENT_DATA_SAMPLE 256 + + +#if CFG_SUPPORT_TX_BF +#define HQA_BF_STR_SIZE 512 +#endif + +#define HQA_RX_STATISTIC_NUM 66 + +#ifdef MAX_EEPROM_BUFFER_SIZE +#undef MAX_EEPROM_BUFFER_SIZE +#endif +#define MAX_EEPROM_BUFFER_SIZE 1200 + +#define HQA_DBDC_BAND_NUM 2 +#define HQA_ANT_NUM 4 +#define HQA_USER_NUM 16 + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +extern uint8_t uacEEPROMImage[MAX_EEPROM_BUFFER_SIZE]; + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +#if 0 +struct PARAM_RX_STAT { + uint32_t MacFCSErr; /* Y 0x820F_D014 */ + uint32_t MacMdrdy; /* Y 0x820F_D030 */ + uint32_t FCSErr_CCK; /* Y 0x8207_021C [15:00] */ + uint32_t FCSErr_OFDM; /* Y 0x8207_021C [31:16] */ + uint32_t CCK_PD; /* Y 0x8207_020C [15:00] */ + uint32_t OFDM_PD; /* Y 0x8207_020C [15:00] */ + uint32_t CCK_SIG_Err; /* Y 0x8207_0210 [31:16] */ + uint32_t CCK_SFD_Err; /* Y 0x8207_0210 [15:00] */ + uint32_t OFDM_SIG_Err; /* Y 0x8207_0214 [31:16] */ + uint32_t OFDM_TAG_Err; /* Y 0x8207_0214 [15:00] */ + uint32_t WB_RSSSI0; /* Y 0x8207_21A8 [23:16] */ + uint32_t IB_RSSSI0; /* Y 0x8207_21A8 [31:24] */ + uint32_t WB_RSSSI1; /* Y 0x8207_21A8 [07:00] */ + uint32_t IB_RSSSI1; /* Y 0x8207_21A8 [15:08] */ + uint32_t PhyMdrdyCCK; /* Y 0x8207_0220 [15:00] */ + uint32_t PhyMdrdyOFDM; /* Y 0x8207_0220 [31:16] */ + uint32_t DriverRxCount; /* Y FW Counter Band0 */ + uint32_t RCPI0; /* Y RXV4 [07:00] */ + uint32_t RCPI1; /* Y RXV4 [15:08] */ + uint32_t FreqOffsetFromRX; /* Y RXV5 MISC1[24:00] OFDM:[11:00] + * CCK:[10:00] + */ + uint32_t RSSI0; /* N */ + uint32_t RSSI1; /* N */ + uint32_t rx_fifo_full; /* N */ + uint32_t RxLenMismatch; /* N */ + uint32_t MacFCSErr_band1; /* Y 0x820F_D214 */ + uint32_t MacMdrdy_band1; /* Y 0x820F_D230 */ + /* Y RXV3 [23:16] (must set 0x8207066C[1:0] = 0x0 ~ 0x3) */ + uint32_t FAGC_IB_RSSSI[4]; + /* Y RXV3 [31:24] (must set 0x8207066C[1:0] = 0x0 ~ 0x3) */ + uint32_t FAGC_WB_RSSSI[4]; + /* Y 0x8207_21A8 [31:24] [15:08] 0x8207_29A8 [31:24] [15:08] */ + uint32_t Inst_IB_RSSSI[4]; + /* Y 0x8207_21A8 [23:16] [07:00] 0x8207_29A8 [23:16] [07:00] */ + uint32_t Inst_WB_RSSSI[4]; + uint32_t ACIHitLow; /* Y 0x8207_21B0 [18] */ + uint32_t ACIHitHigh; /* Y 0x8207_29B0 [18] */ + uint32_t DriverRxCount1; /* Y FW Counter Band1 */ + uint32_t RCPI2; /* Y RXV4 [23:16] */ + uint32_t RCPI3; /* Y RXV4 [31:24] */ + uint32_t RSSI2; /* N */ + uint32_t RSSI3; /* N */ + uint32_t SNR0; /* Y RXV5 (MISC1 >> 19) - 16 */ + uint32_t SNR1; /* N */ + uint32_t SNR2; /* N */ + uint32_t SNR3; /* N */ + uint32_t rx_fifo_full_band1; /* N */ + uint32_t RxLenMismatch_band1; /* N */ + uint32_t CCK_PD_band1; /* Y 0x8207_040C [15:00] */ + uint32_t OFDM_PD_band1; /* Y 0x8207_040C [31:16] */ + uint32_t CCK_SIG_Err_band1; /* Y 0x8207_0410 [31:16] */ + uint32_t CCK_SFD_Err_band1; /* Y 0x8207_0410 [15:00] */ + uint32_t OFDM_SIG_Err_band1; /* Y 0x8207_0414 [31:16] */ + uint32_t OFDM_TAG_Err_band1; /* Y 0x8207_0414 [15:00] */ + uint32_t PhyMdrdyCCK_band1; /* Y 0x8207_0420 [15:00] */ + uint32_t PhyMdrdyOFDM_band1; /* Y 0x8207_0420 [31:16] */ + uint32_t CCK_FCS_Err_band1; /* Y 0x8207_041C [15:00] */ + uint32_t OFDM_FCS_Err_band1; /* Y 0x8207_041C [31:16] */ + uint32_t MuPktCount; /* Y MT_ATEUpdateRxStatistic + * RXV1_2ND_CYCLE->GroupId + */ +}; +#else +struct PARAM_RX_STAT { + uint32_t MAC_FCS_Err; /* b0 */ + uint32_t MAC_Mdrdy; /* b0 */ + uint32_t FCSErr_CCK; + uint32_t FCSErr_OFDM; + uint32_t CCK_PD; + uint32_t OFDM_PD; + uint32_t CCK_SIG_Err; + uint32_t CCK_SFD_Err; + uint32_t OFDM_SIG_Err; + uint32_t OFDM_TAG_Err; + uint32_t WB_RSSI0; + uint32_t IB_RSSI0; + uint32_t WB_RSSI1; + uint32_t IB_RSSI1; + uint32_t PhyMdrdyCCK; + uint32_t PhyMdrdyOFDM; + uint32_t DriverRxCount; + uint32_t RCPI0; + uint32_t RCPI1; + uint32_t FreqOffsetFromRX; + uint32_t RSSI0; + uint32_t RSSI1; /* insert new member here */ + uint32_t OutOfResource; /* MT7615 begin here */ + uint32_t LengthMismatchCount_B0; + uint32_t MAC_FCS_Err1; /* b1 */ + uint32_t MAC_Mdrdy1; /* b1 */ + uint32_t FAGCRssiIBR0; + uint32_t FAGCRssiIBR1; + uint32_t FAGCRssiIBR2; + uint32_t FAGCRssiIBR3; + uint32_t FAGCRssiWBR0; + uint32_t FAGCRssiWBR1; + uint32_t FAGCRssiWBR2; + uint32_t FAGCRssiWBR3; + + uint32_t InstRssiIBR0; + uint32_t InstRssiIBR1; + uint32_t InstRssiIBR2; + uint32_t InstRssiIBR3; + uint32_t InstRssiWBR0; + uint32_t InstRssiWBR1; + uint32_t InstRssiWBR2; + uint32_t InstRssiWBR3; + uint32_t ACIHitLower; + uint32_t ACIHitUpper; + uint32_t DriverRxCount1; + uint32_t RCPI2; + uint32_t RCPI3; + uint32_t RSSI2; + uint32_t RSSI3; + uint32_t SNR0; + uint32_t SNR1; + uint32_t SNR2; + uint32_t SNR3; + uint32_t OutOfResource1; + uint32_t LengthMismatchCount_B1; + uint32_t CCK_PD_Band1; + uint32_t OFDM_PD_Band1; + uint32_t CCK_SIG_Err_Band1; + uint32_t CCK_SFD_Err_Band1; + uint32_t OFDM_SIG_Err_Band1; + uint32_t OFDM_TAG_Err_Band1; + uint32_t PHY_CCK_MDRDY_Band1; + uint32_t PHY_OFDM_MDRDY_Band1; + uint32_t CCK_FCS_Err_Band1; + uint32_t OFDM_FCS_Err_Band1; + uint32_t MRURxCount; + uint32_t SIGMCS; + uint32_t SINR; + uint32_t RXVRSSI; + uint32_t Reserved[184]; + uint32_t PHY_Mdrdy; + uint32_t Noise_Floor; + uint32_t AllLengthMismatchCount_B0; + uint32_t AllLengthMismatchCount_B1; + uint32_t AllMacMdrdy0; + uint32_t AllMacMdrdy1; + uint32_t AllFCSErr0; + uint32_t AllFCSErr1; + uint32_t RXOK0; + uint32_t RXOK1; + uint32_t PER0; + uint32_t PER1; +}; +extern struct PARAM_RX_STAT g_HqaRxStat; + +struct hqa_rx_stat_resp_field { + uint32_t type; + uint32_t version; + uint32_t item_mask; + uint32_t blk_cnt; + uint32_t blk_size; +}; + +struct hqa_rx_stat_band_format { + u_int32_t mac_rx_fcs_err_cnt; + u_int32_t mac_rx_mdrdy_cnt; + u_int32_t mac_rx_len_mismatch; + u_int32_t mac_rx_fcs_ok_cnt; + u_int32_t phy_rx_fcs_err_cnt_cck; + u_int32_t phy_rx_fcs_err_cnt_ofdm; + u_int32_t phy_rx_pd_cck; + u_int32_t phy_rx_pd_ofdm; + u_int32_t phy_rx_sig_err_cck; + u_int32_t phy_rx_sfd_err_cck; + u_int32_t phy_rx_sig_err_ofdm; + u_int32_t phy_rx_tag_err_ofdm; + u_int32_t phy_rx_mdrdy_cnt_cck; + u_int32_t phy_rx_mdrdy_cnt_ofdm; +}; + +struct hqa_rx_stat_path_format { + u_int32_t rcpi; + u_int32_t rssi; + u_int32_t fagc_ib_rssi; + u_int32_t fagc_wb_rssi; + u_int32_t inst_ib_rssi; + u_int32_t inst_wb_rssi; +}; + +struct hqa_rx_stat_user_format { + int32_t freq_offset_from_rx; + u_int32_t snr; + u_int32_t fcs_error_cnt; +}; + +struct hqa_rx_stat_comm_format { + u_int32_t rx_fifo_full; + u_int32_t aci_hit_low; + u_int32_t aci_hit_high; + u_int32_t mu_pkt_count; + u_int32_t sig_mcs; + u_int32_t sinr; + u_int32_t driver_rx_count; +}; + + +struct hqa_rx_stat_u { + union { + struct hqa_rx_stat_band_format rx_st_band; + struct hqa_rx_stat_path_format rx_st_path; + struct hqa_rx_stat_user_format rx_st_user; + struct hqa_rx_stat_comm_format rx_st_comm; + } u; +}; + +enum { + HQA_SERV_RX_STAT_TYPE_BAND = 0, + HQA_SERV_RX_STAT_TYPE_PATH, + HQA_SERV_RX_STAT_TYPE_USER, + HQA_SERV_RX_STAT_TYPE_COMM, + HQA_SERV_RX_STAT_TYPE_NUM +}; + +enum { + HQA_ANT_WF0 = 0, + HQA_ANT_WF1 = 1, + HQA_MAX_ANT_NUM +}; + +enum { + HQA_M_BAND_0 = 0, + HQA_M_BAND_1 = 1, + HQA_M_BAND_NUM +}; + +enum { + HQA_RX_STAT_BAND = 0, + HQA_RX_STAT_PATH, + HQA_RX_STAT_USER, + HQA_RX_STAT_COMM, + HQA_RX_STAT_NUM +}; +#endif + +struct HQA_CMD_FRAME { + uint32_t MagicNo; + uint16_t Type; + uint16_t Id; + uint16_t Length; + uint16_t Sequence; + uint8_t Data[2048]; +} __KAL_ATTRIB_PACKED__; + +typedef int32_t(*HQA_CMD_HANDLER) (struct net_device + *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame); + +struct HQA_CMD_TABLE { + HQA_CMD_HANDLER *CmdSet; + uint32_t CmdSetSize; + uint32_t CmdOffset; +}; + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +int HQA_CMDHandler(struct net_device *prNetDev, + IN union iwreq_data *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame); + +int priv_qa_agent(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN union iwreq_data *prIwReqData, IN char *pcExtra); + +int32_t mt6632SetICapStart(struct GLUE_INFO *prGlueInfo, + uint32_t u4Trigger, uint32_t u4RingCapEn, + uint32_t u4Event, uint32_t u4Node, uint32_t u4Len, + uint32_t u4StopCycle, + uint32_t u4BW, uint32_t u4MacTriggerEvent, + uint32_t u4SourceAddrLSB, + uint32_t u4SourceAddrMSB, uint32_t u4Band); +int32_t mt6632GetICapStatus(struct GLUE_INFO *prGlueInfo); + +int32_t connacSetICapStart(struct GLUE_INFO *prGlueInfo, + uint32_t u4Trigger, uint32_t u4RingCapEn, + uint32_t u4Event, uint32_t u4Node, uint32_t u4Len, + uint32_t u4StopCycle, + uint32_t u4BW, uint32_t u4MacTriggerEvent, + uint32_t u4SourceAddrLSB, + uint32_t u4SourceAddrMSB, uint32_t u4Band); +int32_t connacGetICapStatus(struct GLUE_INFO *prGlueInfo); + +int32_t commonGetICapIQData(struct GLUE_INFO *prGlueInfo, + uint8_t *pData, uint32_t u4IQType, uint32_t u4WFNum); +int32_t connacGetICapIQData(struct GLUE_INFO *prGlueInfo, + uint8_t *pData, uint32_t u4IQType, uint32_t u4WFNum); + + +#endif /*CFG_SUPPORT_QA_TOOL */ +#endif /* _GL_QA_AGENT_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_rst.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_rst.h new file mode 100644 index 0000000000000000000000000000000000000000..7cce675108fb9ef4f80d29aec3dd041665ca3c69 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_rst.h @@ -0,0 +1,313 @@ +/******************************************************************************* + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include + * /gl_rst.h#1 + */ + +/*! \file gl_rst.h + * \brief Declaration of functions and finite state machine for + * MT6620 Whole-Chip Reset Mechanism + */ + +#ifndef _GL_RST_H +#define _GL_RST_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "gl_typedef.h" + +#if CFG_MTK_ANDROID_WMT && (CFG_SUPPORT_CONNINFRA == 0) +#include "wmt_exp.h" +#endif + +#if 0 +#include "mtk_porting.h" +#endif +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#if (MTK_WCN_HIF_SDIO == 1) || (MTK_WCN_HIF_AXI == 1) +#define CFG_WMT_RESET_API_SUPPORT 1 +#else +#define CFG_WMT_RESET_API_SUPPORT 0 +#endif + +#define RST_FLAG_CHIP_RESET 0 +#define RST_FLAG_DO_CORE_DUMP BIT(0) +#define RST_FLAG_PREVENT_POWER_OFF BIT(1) +#define RST_FLAG_DO_WHOLE_RESET BIT(2) + +#if CFG_CHIP_RESET_HANG +#define SER_L0_HANG_RST_NONE 0 +#define SER_L0_HANG_RST_TRGING 1 +#define SER_L0_HANG_RST_HAND_DISABLE 2 +#define SER_L0_HANG_RST_HANG 3 +#define SER_L0_HANG_RST_CMD_TRG 9 + +#define SER_L0_HANG_LOG_TIME_INTERVAL 3000 +#endif +#if (CFG_SUPPORT_CONNINFRA == 1) +#include "conninfra.h" +#define WIFI_TRIGGER_ASSERT_TIMEOUT 2000 +#define GLUE_FLAG_RST_PROCESS (GLUE_FLAG_HALT |\ + GLUE_FLAG_RST_START |\ + GLUE_FLAG_RST_END) +#define RST_FLAG_WHOLE_RESET (RST_FLAG_DO_CORE_DUMP | \ + RST_FLAG_PREVENT_POWER_OFF |\ + RST_FLAG_DO_WHOLE_RESET) +#define RST_FLAG_WF_RESET (RST_FLAG_DO_CORE_DUMP | RST_FLAG_PREVENT_POWER_OFF) +#endif +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +enum ENUM_RESET_STATUS { + RESET_FAIL, + RESET_SUCCESS +}; + +enum _ENUM_CHIP_RESET_REASON_TYPE_T { + RST_PROCESS_ABNORMAL_INT = 1, + RST_DRV_OWN_FAIL, + RST_FW_ASSERT, + RST_BT_TRIGGER, + RST_OID_TIMEOUT, + RST_CMD_TRIGGER, + RST_REASON_MAX +}; + +struct RESET_STRUCT { + struct GLUE_INFO *prGlueInfo; + struct work_struct rst_work; +#if CFG_WMT_RESET_API_SUPPORT + enum ENUM_RESET_STATUS rst_data; + struct work_struct rst_trigger_work; + uint32_t rst_trigger_flag; +#endif +}; + +#if CFG_WMT_RESET_API_SUPPORT +#if (CFG_SUPPORT_CONNINFRA == 1) +/* duplicated from wmt_exp.h for better driver isolation */ +enum ENUM_WMTDRV_TYPE { + WMTDRV_TYPE_BT = 0, + WMTDRV_TYPE_FM = 1, + WMTDRV_TYPE_GPS = 2, + WMTDRV_TYPE_WIFI = 3, + WMTDRV_TYPE_WMT = 4, + WMTDRV_TYPE_STP = 5, + WMTDRV_TYPE_SDIO1 = 6, + WMTDRV_TYPE_SDIO2 = 7, + WMTDRV_TYPE_LPBK = 8, + WMTDRV_TYPE_MAX +}; + +enum ENUM_WMTMSG_TYPE { + WMTMSG_TYPE_POWER_ON = 0, + WMTMSG_TYPE_POWER_OFF = 1, + WMTMSG_TYPE_RESET = 2, + WMTMSG_TYPE_STP_RDY = 3, + WMTMSG_TYPE_HW_FUNC_ON = 4, + WMTMSG_TYPE_MAX +}; + +enum ENUM_WMTRSTMSG_TYPE { + WMTRSTMSG_RESET_START = 0x0, /*whole chip reset (include other radio)*/ + WMTRSTMSG_RESET_END = 0x1, + WMTRSTMSG_RESET_END_FAIL = 0x2, + WMTRSTMSG_0P5RESET_START = 0x3, /*wfsys reset ( wifi only )*/ + WMTRSTMSG_RESET_MAX, + WMTRSTMSG_RESET_INVALID = 0xff +}; + +enum ENUM_WF_RST_SOURCE { + WF_RST_SOURCE_NONE = 0x0, + WF_RST_SOURCE_DRIVER = 0x1, + WF_RST_SOURCE_FW = 0x2, + WF_RST_SOURCE_MAX +}; +#endif +#endif + +/******************************************************************************* + * E X T E R N A L F U N C T I O N S + ******************************************************************************* + */ +#if CFG_CHIP_RESET_SUPPORT + +#if CFG_WMT_RESET_API_SUPPORT +extern int wifi_reset_start(void); +extern int wifi_reset_end(enum ENUM_RESET_STATUS); + +#if (CFG_SUPPORT_CONNINFRA == 1) +extern int hifAxiRemove(void); +extern void kalSetRstEvent(void); +extern void update_driver_reset_status(uint8_t fgIsResetting); +extern int32_t get_wifi_process_status(void); +extern int32_t get_wifi_powered_status(void); +#endif /* CFG_SUPPORT_CONNINFRA */ + +#endif /* CFG_WMT_RESET_API_SUPPORT */ +#endif /* CFG_CHIP_RESET_SUPPORT */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ +#if CFG_CHIP_RESET_SUPPORT +extern u_int8_t fgIsResetting; +#if (CFG_SUPPORT_CONNINFRA == 1) +extern enum ENUM_WF_RST_SOURCE g_eWfRstSource; +#endif + +#if CFG_CHIP_RESET_HANG +extern u_int8_t fgIsResetHangState; +#endif + +#endif +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ +#define GL_COREDUMP_TRIGGER(_prAdapter) \ +{ \ + wlanoidSerExtCmd(_prAdapter, SER_ACTION_RECOVER, \ + SER_SET_L0_RECOVER, 0); \ +} + +#if CFG_CHIP_RESET_SUPPORT +#if CFG_WMT_RESET_API_SUPPORT +#define GL_RESET_TRIGGER(_prAdapter, _u4Flags) \ + glResetTrigger(_prAdapter, (_u4Flags), \ + (const uint8_t *)__FILE__, __LINE__) +#else +#define GL_RESET_TRIGGER(_prAdapter, _u4Flags) \ +{ \ + if (glGetRstReason() == RST_OID_TIMEOUT || \ + glGetRstReason() == RST_FW_ASSERT || \ + glGetRstReason() == RST_CMD_TRIGGER || \ + glGetRstReason() == RST_BT_TRIGGER) { \ + glResetTrigger(_prAdapter, (_u4Flags), \ + (const uint8_t *)__FILE__, __LINE__); \ + } else { \ + GL_COREDUMP_TRIGGER(_prAdapter); \ + DBGLOG(INIT, ERROR, "Trigger coredump in %s line %u!\n", \ + __FILE__, __LINE__); \ + } \ +} +#endif +#else +#define GL_RESET_TRIGGER(_prAdapter, _u4Flags) \ + DBGLOG(INIT, INFO, "DO NOT support chip reset\n") +#endif + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +#if CFG_CHIP_RESET_SUPPORT +extern uint64_t u8ResetTime; +extern u_int8_t fgSimplifyResetFlow; +extern char *g_reason; +#else + +#endif +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +void glSetRstReason(enum _ENUM_CHIP_RESET_REASON_TYPE_T eReason); +int glGetRstReason(void); + +u_int8_t kalIsResetting(void); + +#if CFG_CHIP_RESET_SUPPORT +void glResetInit(struct GLUE_INFO *prGlueInfo); + +void glResetUninit(void); + +void glSendResetRequest(void); + +u_int8_t glResetTrigger(struct ADAPTER *prAdapter, + uint32_t u4RstFlag, const uint8_t *pucFile, + uint32_t u4Line); + +#if CFG_WMT_RESET_API_SUPPORT +int32_t glIsWmtCodeDump(void); +#endif +#if (CFG_SUPPORT_CONNINFRA == 1) + +int wlan_reset_thread_main(void *data); +int glRstwlanPreWholeChipReset(enum consys_drv_type type, char *reason); +int glRstwlanPostWholeChipReset(void); +u_int8_t kalIsWholeChipResetting(void); +void glSetRstReasonString(char *reason); + +#endif /*end of CFG_SUPPORT_CONNINFRA == 0*/ + +#else + +#endif +#endif /* _GL_RST_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_sec.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_sec.h new file mode 100644 index 0000000000000000000000000000000000000000..e00aab1ff55e5333f9b4614ca76f6f2507198a7c --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_sec.h @@ -0,0 +1,79 @@ +/******************************************************************************* + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ +/* + * Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include + * /gl_sec.h#1 + */ + +/*! \file p2p_fsm.h + * \brief Declaration of functions and finite state machine for P2P Module. + * + * Declaration of functions and finite state machine for P2P Module. + */ + +#ifndef _GL_SEC_H +#define _GL_SEC_H + +extern void handle_sec_msg_1(unsigned char *msg_in, int msg_in_len, + unsigned char *msg_out, int *msg_out_len); +extern void handle_sec_msg_2(unsigned char *msg_in, int msg_in_len, + unsigned char *msg_out, int *msg_out_len); +extern void handle_sec_msg_3(unsigned char *msg_in, int msg_in_len, + unsigned char *msg_out, int *msg_out_len); +extern void handle_sec_msg_4(unsigned char *msg_in, int msg_in_len, + unsigned char *msg_out, int *msg_out_len); +extern void handle_sec_msg_5(unsigned char *msg_in, int msg_in_len, + unsigned char *msg_out, int *msg_out_len); +extern void handle_sec_msg_final(unsigned char *msg_in, int msg_in_len, + unsigned char *msg_out, int *msg_out_len); + +#endif /* _GL_SEC_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_typedef.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_typedef.h new file mode 100644 index 0000000000000000000000000000000000000000..fb82f83bb26ddaa98073c3e180af4df8f1025819 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_typedef.h @@ -0,0 +1,322 @@ +/******************************************************************************* + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ +/* + * Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include + * /gl_typedef.h#1 + */ + +/*! \file gl_typedef.h + * \brief Definition of basic data type(os dependent). + * + * In this file we define the basic data type. + */ + + +#ifndef _GL_TYPEDEF_H +#define _GL_TYPEDEF_H + +#if CFG_ENABLE_EARLY_SUSPEND +#include +#endif + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +/* Define HZ of timer tick for function kalGetTimeTick() */ +#define KAL_HZ (1000) + +/* Miscellaneous Equates */ +#ifndef FALSE +#define FALSE ((u_int8_t) 0) +#define TRUE ((u_int8_t) 1) +#endif /* FALSE */ + +#ifndef NULL +#if defined(__cplusplus) +#define NULL 0 +#else +#define NULL ((void *) 0) +#endif +#endif + +#if CFG_ENABLE_EARLY_SUSPEND +typedef void (*early_suspend_callback) (struct early_suspend + *h); +typedef void (*late_resume_callback) (struct early_suspend + *h); +#endif + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +/* Type definition for void */ + +/* Type definition for Boolean */ + +/* Type definition for signed integers */ + +/* Type definition for unsigned integers */ + + +#define OS_SYSTIME uint32_t + +/* Type definition of large integer (64bits) union to be comptaible with + * Windows definition, so we won't apply our own coding style to these data + * types. + * NOTE: LARGE_INTEGER must NOT be floating variable. + * : Check for big-endian compatibility. + */ +union LARGE_INTEGER { + struct { + uint32_t LowPart; + int32_t HighPart; + } u; + int64_t QuadPart; +}; + +union ULARGE_INTEGER { + struct { + uint32_t LowPart; + uint32_t HighPart; + } u; + uint64_t QuadPart; +}; + +typedef int32_t(*probe_card) (void *pvData, + void *pvDriverData); +typedef void(*remove_card) (void); + + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ +#define IN /* volatile */ +#define OUT /* volatile */ + +#define __KAL_INLINE__ inline +#define __KAL_ATTRIB_PACKED__ __attribute__((__packed__)) +#define __KAL_ATTRIB_ALIGN_4__ __aligned(4) + +#ifndef BIT +#define BIT(n) ((uint32_t) 1UL << (n)) +#endif /* BIT */ + +#ifndef BITS +/* bits range: for example BITS(16,23) = 0xFF0000 + * ==> (BIT(m)-1) = 0x0000FFFF ~(BIT(m)-1) => 0xFFFF0000 + * ==> (BIT(n+1)-1) = 0x00FFFFFF + */ +#define BITS(m, n) (~(BIT(m)-1) & ((BIT(n) - 1) | BIT(n))) +#endif /* BIT */ + +/* This macro returns the byte offset of a named field in a known structure + * type. + * _type - structure name, + * _field - field name of the structure + */ +#ifndef OFFSET_OF +#define OFFSET_OF(_type, _field) offsetof(_type, _field) +#endif /* OFFSET_OF */ + +/* This macro returns the base address of an instance of a structure + * given the type of the structure and the address of a field within the + * containing structure. + * _addrOfField - address of current field of the structure, + * _type - structure name, + * _field - field name of the structure + */ +#ifndef ENTRY_OF +#define ENTRY_OF(_addrOfField, _type, _field) \ + ((_type *)((int8_t *)(_addrOfField) - \ + (int8_t *)OFFSET_OF(_type, _field))) +#endif /* ENTRY_OF */ + +/* This macro align the input value to the DW boundary. + * _value - value need to check + */ +#ifndef ALIGN_4 +#define ALIGN_4(_value) (((_value) + 3) & ~3u) +#endif /* ALIGN_4 */ + +#ifndef ALIGN_8 +#define ALIGN_8(_value) (((_value) + 7) & ~7u) +#endif /* ALIGN_4 */ + +/* This macro check the DW alignment of the input value. + * _value - value of address need to check + */ +#ifndef IS_ALIGN_4 +#define IS_ALIGN_4(_value) (((_value) & 0x3) ? FALSE : TRUE) +#endif /* IS_ALIGN_4 */ + +#ifndef IS_NOT_ALIGN_4 +#define IS_NOT_ALIGN_4(_value) (((_value) & 0x3) ? TRUE : FALSE) +#endif /* IS_NOT_ALIGN_4 */ + +/* This macro evaluate the input length in unit of Double Word(4 Bytes). + * _value - value in unit of Byte, output will round up to DW boundary. + */ +#ifndef BYTE_TO_DWORD +#define BYTE_TO_DWORD(_value) ((_value + 3) >> 2) +#endif /* BYTE_TO_DWORD */ + +/* This macro evaluate the input length in unit of Byte. + * _value - value in unit of DW, output is in unit of Byte. + */ +#ifndef DWORD_TO_BYTE +#define DWORD_TO_BYTE(_value) ((_value) << 2) +#endif /* DWORD_TO_BYTE */ + +#if 1 /* Little-Endian */ +#define CONST_NTOHS(_x) ntohs(_x) + +#define CONST_HTONS(_x) htons(_x) + +#define NTOHS(_x) ntohs(_x) + +#define HTONS(_x) htons(_x) + +#define NTOHL(_x) ntohl(_x) + +#define HTONL(_x) htonl(_x) + +#else /* Big-Endian */ + +#define CONST_NTOHS(_x) + +#define CONST_HTONS(_x) + +#define NTOHS(_x) + +#define HTONS(_x) + +#endif + +#define CPU_TO_LE16 cpu_to_le16 +#define CPU_TO_LE32 cpu_to_le32 +#define CPU_TO_LE64 cpu_to_le64 + +#define LE16_TO_CPU le16_to_cpu +#define LE32_TO_CPU le32_to_cpu +#define LE64_TO_CPU le64_to_cpu + +#define SWAP32(x) \ + ((uint32_t) (\ + (((uint32_t) (x) & (uint32_t) 0x000000ffUL) << 24) | \ + (((uint32_t) (x) & (uint32_t) 0x0000ff00UL) << 8) | \ + (((uint32_t) (x) & (uint32_t) 0x00ff0000UL) >> 8) | \ + (((uint32_t) (x) & (uint32_t) 0xff000000UL) >> 24))) + +/* Endian byte swapping codes */ +#ifdef __LITTLE_ENDIAN +#define LE48_TO_CPU(x) (x) +#define CPU_TO_LE48(x) (x) +#define cpu2le32(x) ((uint32_t)(x)) +#define le2cpu32(x) ((uint32_t)(x)) +#define cpu2be32(x) SWAP32((x)) +#define be2cpu32(x) SWAP32((x)) + +#else + + +#define SWAP48(x) \ + ((uint64_t)( \ + (uint64_t)(((UINT_64)(x) & (uint64_t) 0x0000000000ffULL) << 40) | \ + (uint64_t)(((UINT_64)(x) & (uint64_t) 0x00000000ff00ULL) << 24) | \ + (uint64_t)(((UINT_64)(x) & (uint64_t) 0x000000ff0000ULL) << 8) | \ + (uint64_t)(((UINT_64)(x) & (uint64_t) 0x0000ff000000ULL) >> 8) | \ + (uint64_t)(((UINT_64)(x) & (uint64_t) 0x00ff00000000ULL) >> 24) | \ + (uint64_t)(((UINT_64)(x) & (uint64_t) 0xff0000000000ULL) >> 40))) +#define LE48_TO_CPU(x) SWAP48(x) +#define CPU_TO_LE48(x) SWAP48(x) +#define cpu2le32(x) SWAP32((x)) +#define le2cpu32(x) SWAP32((x)) +#define cpu2be32(x) ((uint32_t)(x)) +#define be2cpu32(x) ((uint32_t)(x)) + + +#endif + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#endif /* _GL_TYPEDEF_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_vendor.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_vendor.h new file mode 100644 index 0000000000000000000000000000000000000000..6d5a850b0c4c4ecbd2a23a9cee2416a76a8b2fcb --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_vendor.h @@ -0,0 +1,797 @@ +/******************************************************************************* + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ +/* + * Log: gl_vendor.h + * + * 10 14 2014 + * add vendor declaration + * + * + */ + +#ifndef _GL_VENDOR_H +#define _GL_VENDOR_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include +#include +#include +#include +#include +#include +#include +#include "wlan_lib.h" +#include "gl_wext.h" + + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#define GOOGLE_OUI 0x001A11 +#define OUI_QCA 0x001374 +#if CFG_SUPPORT_DATA_STALL +#define OUI_MTK 0x000CE7 +#endif + +#define NL80211_VENDOR_SUBCMD_GET_PREFER_FREQ_LIST 103 +#define NL80211_VENDOR_SUBCMD_ACS 54 +#define NL80211_VENDOR_SUBCMD_GET_FEATURES 55 +#define QCA_NL80211_VENDOR_SUBCMD_ROAM 64 +#define QCA_NL80211_VENDOR_SUBCMD_SETBAND 105 + +#define WIFI_VENDOR_ATTR_FEATURE_FLAGS 7 + +enum NL80211_VENDOR_FEATURES { + VENDOR_FEATURE_KEY_MGMT_OFFLOAD = 0, + VENDOR_FEATURE_SUPPORT_HW_MODE_ANY = 1, + VENDOR_FEATURE_OFFCHANNEL_SIMULTANEOUS = 2, + VENDOR_FEATURE_P2P_LISTEN_OFFLOAD = 3, + VENDOR_FEATURE_OCE_STA = 4, + VENDOR_FEATURE_OCE_AP = 5, + VENDOR_FEATURE_OCE_STA_CFON = 6, + NUM_VENDOR_FEATURES /* keep last */ +}; + +enum ANDROID_VENDOR_SUB_COMMAND { + /* Don't use 0 as a valid subcommand */ + ANDROID_NL80211_SUBCMD_UNSPECIFIED, + + /* Define all vendor startup commands between 0x0 and 0x0FFF */ + ANDROID_NL80211_SUBCMD_WIFI_RANGE_START = 0x0001, + ANDROID_NL80211_SUBCMD_WIFI_RANGE_END = 0x0FFF, + + /* Define all GScan related commands between 0x1000 and 0x10FF */ + ANDROID_NL80211_SUBCMD_GSCAN_RANGE_START = 0x1000, + ANDROID_NL80211_SUBCMD_GSCAN_RANGE_END = 0x10FF, + + /* Define all RTT related commands between 0x1100 and 0x11FF */ + ANDROID_NL80211_SUBCMD_RTT_RANGE_START = 0x1100, + ANDROID_NL80211_SUBCMD_RTT_RANGE_END = 0x11FF, + + ANDROID_NL80211_SUBCMD_LSTATS_RANGE_START = 0x1200, + ANDROID_NL80211_SUBCMD_LSTATS_RANGE_END = 0x12FF, + + /* Define all Logger related commands between 0x1400 and 0x14FF */ + ANDROID_NL80211_SUBCMD_DEBUG_RANGE_START = 0x1400, + ANDROID_NL80211_SUBCMD_DEBUG_RANGE_END = 0x14FF, + + /* Define all wifi offload related commands between 0x1600 and 0x16FF */ + ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_START = 0x1600, + ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_END = 0x16FF, + + /* This is reserved for future usage */ + +}; + +enum WIFI_SUB_COMMAND { + WIFI_SUBCMD_GET_CHANNEL_LIST = ANDROID_NL80211_SUBCMD_WIFI_RANGE_START, + + WIFI_SUBCMD_GET_FEATURE_SET, /* 0x0002 */ + WIFI_SUBCMD_GET_FEATURE_SET_MATRIX, /* 0x0003 */ + WIFI_SUBCMD_SET_PNO_RANDOM_MAC_OUI, /* 0x0004 */ + WIFI_SUBCMD_NODFS_SET, /* 0x0005 */ + WIFI_SUBCMD_SET_COUNTRY_CODE, /* 0x0006 */ + WIFI_SUBCMD_SET_RSSI_MONITOR, /* 0x0007 */ + + /* Add more sub commands here */ + WIFI_SUBCMD_GET_ROAMING_CAPABILITIES, /* 0x0008 */ + WIFI_SUBCMD_SET_ROAMING = 0x0009, /* 0x0009 */ + WIFI_SUBCMD_CONFIG_ROAMING = 0x000a, /* 0x000a */ + WIFI_SUBCMD_ENABLE_ROAMING, /* 0x000b */ + WIFI_SUBCMD_SELECT_TX_POWER_SCENARIO, /* 0x000c */ +}; + +enum RTT_SUB_COMMAND { + RTT_SUBCMD_SET_CONFIG = ANDROID_NL80211_SUBCMD_RTT_RANGE_START, + RTT_SUBCMD_CANCEL_CONFIG, + RTT_SUBCMD_GETCAPABILITY, +}; + +enum LSTATS_SUB_COMMAND { + LSTATS_SUBCMD_GET_INFO = ANDROID_NL80211_SUBCMD_LSTATS_RANGE_START, +}; + +/* moved from wifi_logger.cpp */ +enum DEBUG_SUB_COMMAND { + LOGGER_START_LOGGING = ANDROID_NL80211_SUBCMD_DEBUG_RANGE_START, + LOGGER_GET_VER, + LOGGER_DRIVER_MEM_DUMP, +}; + +enum WIFI_OFFLOAD_SUB_COMMAND { + WIFI_OFFLOAD_START_MKEEP_ALIVE = + ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_START, + WIFI_OFFLOAD_STOP_MKEEP_ALIVE, +}; + +enum WIFI_VENDOR_EVENT { + GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS, + GSCAN_EVENT_HOTLIST_RESULTS_FOUND, + GSCAN_EVENT_SCAN_RESULTS_AVAILABLE, + GSCAN_EVENT_FULL_SCAN_RESULTS, + RTT_EVENT_COMPLETE, + GSCAN_EVENT_COMPLETE_SCAN, + GSCAN_EVENT_HOTLIST_RESULTS_LOST, + WIFI_EVENT_RSSI_MONITOR, + WIFI_EVENT_DRIVER_ERROR, + WIFI_EVENT_ACS, + WIFI_EVENT_GENERIC_RESPONSE, + WIFI_EVENT_BIGDATA_PIP + /* Always add at the end.*/ +}; + +enum WIFI_ATTRIBUTE { + WIFI_ATTRIBUTE_BAND = 1, + WIFI_ATTRIBUTE_NUM_CHANNELS, + WIFI_ATTRIBUTE_CHANNEL_LIST, + + WIFI_ATTRIBUTE_NUM_FEATURE_SET, + WIFI_ATTRIBUTE_FEATURE_SET, + WIFI_ATTRIBUTE_PNO_RANDOM_MAC_OUI, + WIFI_ATTRIBUTE_NODFS_VALUE, + WIFI_ATTRIBUTE_COUNTRY_CODE, + + WIFI_ATTRIBUTE_MAX_RSSI, + WIFI_ATTRIBUTE_MIN_RSSI, + WIFI_ATTRIBUTE_RSSI_MONITOR_START, + + WIFI_ATTRIBUTE_ROAMING_CAPABILITIES, + WIFI_ATTRIBUTE_ROAMING_BLACKLIST_NUM, + WIFI_ATTRIBUTE_ROAMING_BLACKLIST_BSSID, + WIFI_ATTRIBUTE_ROAMING_WHITELIST_NUM, + WIFI_ATTRIBUTE_ROAMING_WHITELIST_SSID, + WIFI_ATTRIBUTE_ROAMING_STATE, + WIFI_ATTRIBUTE_TX_POWER_SCENARIO, +}; + +/* moved from wifi_logger.cpp */ +enum LOGGER_ATTRIBUTE { + LOGGER_ATTRIBUTE_DRIVER_VER, + LOGGER_ATTRIBUTE_FW_VER +}; + +enum RTT_ATTRIBUTE { + RTT_ATTRIBUTE_CAPABILITIES = 1, + + RTT_ATTRIBUTE_TARGET_CNT = 10, + RTT_ATTRIBUTE_TARGET_INFO, + RTT_ATTRIBUTE_TARGET_MAC, + RTT_ATTRIBUTE_TARGET_TYPE, + RTT_ATTRIBUTE_TARGET_PEER, + RTT_ATTRIBUTE_TARGET_CHAN, + RTT_ATTRIBUTE_TARGET_PERIOD, + RTT_ATTRIBUTE_TARGET_NUM_BURST, + RTT_ATTRIBUTE_TARGET_NUM_FTM_BURST, + RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTM, + RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTMR, + RTT_ATTRIBUTE_TARGET_LCI, + RTT_ATTRIBUTE_TARGET_LCR, + RTT_ATTRIBUTE_TARGET_BURST_DURATION, + RTT_ATTRIBUTE_TARGET_PREAMBLE, + RTT_ATTRIBUTE_TARGET_BW, + RTT_ATTRIBUTE_RESULTS_COMPLETE = 30, + RTT_ATTRIBUTE_RESULTS_PER_TARGET, + RTT_ATTRIBUTE_RESULT_CNT, + RTT_ATTRIBUTE_RESULT +}; + +enum LSTATS_ATTRIBUTE { + LSTATS_ATTRIBUTE_STATS = 2, +}; + +enum WIFI_MKEEP_ALIVE_ATTRIBUTE { + MKEEP_ALIVE_ATTRIBUTE_ID = 1, + MKEEP_ALIVE_ATTRIBUTE_IP_PKT_LEN, + MKEEP_ALIVE_ATTRIBUTE_IP_PKT, + MKEEP_ALIVE_ATTRIBUTE_SRC_MAC_ADDR, + MKEEP_ALIVE_ATTRIBUTE_DST_MAC_ADDR, + MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC +}; + +/* QCA Vender CMD */ +enum QCA_SET_BAND { + QCA_SETBAND_AUTO, + QCA_SETBAND_5G, + QCA_SETBAND_2G, +}; + +enum QCA_ATTR_ROAM_SUBCMD { + QCA_ATTR_ROAM_SUBCMD_INVALID = 0, + QCA_ATTR_ROAM_SUBCMD_SET_BLACKLIST_BSSID = 6, + + /* keep last */ + QCA_ATTR_ROAM_SUBCMD_AFTER_LAST, + QCA_ATTR_ROAM_SUBCMD_MAX = + QCA_ATTR_ROAM_SUBCMD_AFTER_LAST - 1, +}; + +enum QCA_ATTR_ROAMING_PARAMS { + QCA_ATTR_ROAMING_PARAM_INVALID = 0, + + QCA_ATTR_ROAMING_SUBCMD = 1, + + /* Attribute for set_blacklist bssid params */ + QCA_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS = 18, + QCA_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_NUM_BSSID = 19, + QCA_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_BSSID = 20, + + /* keep last */ + QCA_ATTR_ROAMING_PARAM_AFTER_LAST, + QCA_ATTR_ROAMING_PARAM_MAX = + QCA_ATTR_ROAMING_PARAM_AFTER_LAST - 1, +}; + +enum WIFI_VENDOR_ATTR_PREFERRED_FREQ_LIST { + WIFI_VENDOR_ATTR_PREFERRED_FREQ_LIST_INVALID, + WIFI_VENDOR_ATTR_PREFERRED_FREQ_LIST_IFACE_TYPE, + WIFI_VENDOR_ATTR_PREFERRED_FREQ_LIST_GET, + WIFI_VENDOR_ATTR_PREFERRED_FREQ_LIST_LAST, + WIFI_VENDOR_ATTR_PREFERRED_FREQ_LIST_MAX = + WIFI_VENDOR_ATTR_PREFERRED_FREQ_LIST_LAST - 1 +}; + +enum WIFI_VENDOR_ATTR_ACS { + WIFI_VENDOR_ATTR_ACS_CHANNEL_INVALID = 0, + WIFI_VENDOR_ATTR_ACS_PRIMARY_CHANNEL, + WIFI_VENDOR_ATTR_ACS_SECONDARY_CHANNEL, + WIFI_VENDOR_ATTR_ACS_HW_MODE, + WIFI_VENDOR_ATTR_ACS_HT_ENABLED, + WIFI_VENDOR_ATTR_ACS_HT40_ENABLED, + WIFI_VENDOR_ATTR_ACS_VHT_ENABLED, + WIFI_VENDOR_ATTR_ACS_CHWIDTH, + WIFI_VENDOR_ATTR_ACS_CH_LIST, + WIFI_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL, + WIFI_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL, + WIFI_VENDOR_ATTR_ACS_FREQ_LIST, + WIFI_VENDOR_ATTR_ACS_AFTER_LAST, + WIFI_VENDOR_ATTR_ACS_MAX = + WIFI_VENDOR_ATTR_ACS_AFTER_LAST - 1 +}; + +#define MAX_FW_ROAMING_BLACKLIST_SIZE 16 +#define MAX_FW_ROAMING_WHITELIST_SIZE 8 + +#if CFG_SUPPORT_DATA_STALL +enum WIFI_DATA_STALL_ATTRIBUTE { + WIFI_ATTRIBUTE_ERROR_REASON = 0, +}; +#endif + +#if CFG_SUPPORT_BIGDATA_PIP +enum WIFI_BIGDATA_PIP_ATTRIBUTE { + WIFI_ATTRIBUTE_PIP_PAYLOAD = 0, +}; +#endif +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ +#if CFG_SUPPORT_WAPI +extern uint8_t +keyStructBuf[1024]; /* add/remove key shared buffer */ +#else +extern uint8_t +keyStructBuf[100]; /* add/remove key shared buffer */ +#endif + +/******************************************************************************* + * MACROS + ******************************************************************************* + */ + +#if KERNEL_VERSION(3, 5, 0) <= LINUX_VERSION_CODE +/* + * #define NLA_PUT(skb, attrtype, attrlen, data) \ + * do { \ + * if (unlikely(nla_put(skb, attrtype, attrlen, data) < 0)) \ + * goto nla_put_failure; \ + * } while (0) + * + *#define NLA_PUT_TYPE(skb, type, attrtype, value) \ + * do { \ + * type __tmp = value; \ + * NLA_PUT(skb, attrtype, sizeof(type), &__tmp); \ + * } while (0) + */ +#define NLA_PUT(skb, attrtype, attrlen, data) \ + mtk_cfg80211_NLA_PUT(skb, attrtype, attrlen, data) + +#define NLA_PUT_TYPE(skb, type, attrtype, value) \ + mtk_cfg80211_nla_put_type(skb, type, attrtype, value) + +#define NLA_PUT_U8(skb, attrtype, value) \ + NLA_PUT_TYPE(skb, NLA_PUT_DATE_U8, attrtype, value) + +#define NLA_PUT_U16(skb, attrtype, value) \ + NLA_PUT_TYPE(skb, NLA_PUT_DATE_U16, attrtype, value) + +#define NLA_PUT_U32(skb, attrtype, value) \ + NLA_PUT_TYPE(skb, NLA_PUT_DATE_U32, attrtype, value) + +#define NLA_PUT_U64(skb, attrtype, value) \ + NLA_PUT_TYPE(skb, NLA_PUT_DATE_U64, attrtype, value) + +#endif + +#if KERNEL_VERSION(4, 12, 0) <= CFG80211_VERSION_CODE +#define NLA_PARSE_NESTED(nlattr, maxtype, nla, policy) \ + nla_parse_nested(nlattr, maxtype, nla, policy, NULL) +#define NLA_PARSE(tb, maxtype, head, len, policy) \ + nla_parse(tb, maxtype, head, len, policy, NULL) +#else +#define NLA_PARSE_NESTED(nlattr, maxtype, nla, policy) \ + nla_parse_nested(nlattr, maxtype, nla, policy) +#define NLA_PARSE(tb, maxtype, head, len, policy) \ + nla_parse(tb, maxtype, head, len, policy) +#endif + +/******************************************************************************* + * P R I V A T E D A T A + * + ******************************************************************************* + */ +struct PARAM_WIFI_CHANGE_RESULT { + uint16_t flags; + uint16_t channel; + uint8_t bssid[6]; /* BSSID */ + int8_t rssi[8]; /* RSSI history in db */ +}; + +struct PARAM_AP_THRESHOLD { + uint8_t bssid[6]; /* AP BSSID */ + int32_t low; /* low threshold */ + int32_t high; /* high threshold */ + uint32_t channel; /* channel hint */ +}; + +/* channel operating width */ +enum WIFI_CHANNEL_WIDTH { + WIFI_CHAN_WIDTH_20 = 0, + WIFI_CHAN_WIDTH_40 = 1, + WIFI_CHAN_WIDTH_80 = 2, + WIFI_CHAN_WIDTH_160 = 3, + WIFI_CHAN_WIDTH_80P80 = 4, + WIFI_CHAN_WIDTH_5 = 5, + WIFI_CHAN_WIDTH_10 = 6, + WIFI_CHAN_WIDTH_INVALID = -1 +}; + +/* channel information */ +struct WIFI_CHANNEL_INFO { + enum WIFI_CHANNEL_WIDTH width; + uint32_t center_freq; + uint32_t center_freq0; + uint32_t center_freq1; +}; + +/* channel statistics */ +struct WIFI_CHANNEL_STAT { + struct WIFI_CHANNEL_INFO channel; + uint32_t on_time; + uint32_t cca_busy_time; +}; + +/* radio statistics */ +struct WIFI_RADIO_STAT { + uint32_t radio; + uint32_t on_time; + uint32_t tx_time; + uint32_t rx_time; + uint32_t on_time_scan; + uint32_t on_time_nbd; + uint32_t on_time_gscan; + uint32_t on_time_roam_scan; + uint32_t on_time_pno_scan; + uint32_t on_time_hs20; + uint32_t num_channels; + struct WIFI_CHANNEL_STAT channels[]; +}; + +/* wifi rate */ +struct WIFI_RATE { + uint32_t preamble: 3; + uint32_t nss: 2; + uint32_t bw: 3; + uint32_t rateMcsIdx: 8; + + uint32_t reserved: 16; + uint32_t bitrate; +}; + +/* per rate statistics */ +struct WIFI_RATE_STAT { + struct WIFI_RATE rate; + uint32_t tx_mpdu; + uint32_t rx_mpdu; + uint32_t mpdu_lost; + uint32_t retries; + uint32_t retries_short; + uint32_t retries_long; +}; + +/*wifi_interface_link_layer_info*/ +enum WIFI_CONNECTION_STATE { + WIFI_DISCONNECTED = 0, + WIFI_AUTHENTICATING = 1, + WIFI_ASSOCIATING = 2, + WIFI_ASSOCIATED = 3, + WIFI_EAPOL_STARTED = 4, + WIFI_EAPOL_COMPLETED = 5, +}; + +enum WIFI_ROAM_STATE { + WIFI_ROAMING_IDLE = 0, + WIFI_ROAMING_ACTIVE = 1, +}; + +enum WIFI_INTERFACE_MODE { + WIFI_INTERFACE_STA = 0, + WIFI_INTERFACE_SOFTAP = 1, + WIFI_INTERFACE_IBSS = 2, + WIFI_INTERFACE_P2P_CLIENT = 3, + WIFI_INTERFACE_P2P_GO = 4, + WIFI_INTERFACE_NAN = 5, + WIFI_INTERFACE_MESH = 6, + WIFI_INTERFACE_UNKNOWN = -1 +}; + +struct WIFI_INTERFACE_LINK_LAYER_INFO { + enum WIFI_INTERFACE_MODE mode; + u8 mac_addr[6]; + enum WIFI_CONNECTION_STATE state; + enum WIFI_ROAM_STATE roaming; + u32 capabilities; + u8 ssid[33]; + u8 bssid[6]; + u8 ap_country_str[3]; + u8 country_str[3]; +}; + +/* access categories */ +enum WIFI_TRAFFIC_AC { + WIFI_AC_VO = 0, + WIFI_AC_VI = 1, + WIFI_AC_BE = 2, + WIFI_AC_BK = 3, + WIFI_AC_MAX = 4, +}; + +/* wifi peer type */ +enum WIFI_PEER_TYPE { + WIFI_PEER_STA, + WIFI_PEER_AP, + WIFI_PEER_P2P_GO, + WIFI_PEER_P2P_CLIENT, + WIFI_PEER_NAN, + WIFI_PEER_TDLS, + WIFI_PEER_INVALID, +}; + +/* per peer statistics */ +struct WIFI_PEER_INFO { + enum WIFI_PEER_TYPE type; + uint8_t peer_mac_address[6]; + uint32_t capabilities; + uint32_t num_rate; + struct WIFI_RATE_STAT rate_stats[]; +}; + +/* per access category statistics */ +struct WIFI_WMM_AC_STAT_ { + enum WIFI_TRAFFIC_AC ac; + uint32_t tx_mpdu; + uint32_t rx_mpdu; + uint32_t tx_mcast; + + uint32_t rx_mcast; + uint32_t rx_ampdu; + uint32_t tx_ampdu; + uint32_t mpdu_lost; + uint32_t retries; + uint32_t retries_short; + uint32_t retries_long; + uint32_t contention_time_min; + uint32_t contention_time_max; + uint32_t contention_time_avg; + uint32_t contention_num_samples; +}; + +/* RTT Capabilities */ +struct PARAM_WIFI_RTT_CAPABILITIES { + /* if 1-sided rtt data collection is supported */ + uint8_t rtt_one_sided_supported; + /* if ftm rtt data collection is supported */ + uint8_t rtt_ftm_supported; + /* if initiator supports LCI request. Applies to 2-sided RTT */ + uint8_t lci_support; + /* if initiator supports LCR request. Applies to 2-sided RTT */ + uint8_t lcr_support; + /* bit mask indicates what preamble is supported by initiator */ + uint8_t preamble_support; + /* bit mask indicates what BW is supported by initiator */ + uint8_t bw_support; +}; + +/* interface statistics */ +struct WIFI_IFACE_STAT { + struct WIFI_INTERFACE_LINK_LAYER_INFO info; + uint32_t beacon_rx; + uint32_t mgmt_rx; + uint32_t mgmt_action_rx; + uint32_t mgmt_action_tx; + int32_t rssi_mgmt; + int32_t rssi_data; + int32_t rssi_ack; + struct WIFI_WMM_AC_STAT_ ac[WIFI_AC_MAX]; + uint32_t num_peers; + struct WIFI_PEER_INFO peer_info[]; +}; + +enum ENUM_NLA_PUT_DATE_TYPE { + NLA_PUT_DATE_U8 = 0, + NLA_PUT_DATE_U16, + NLA_PUT_DATE_U32, + NLA_PUT_DATE_U64, +}; + +/* RSSI Monitoring */ +struct PARAM_RSSI_MONITOR_T { + bool enable; /* 1=Start, 0=Stop*/ + int8_t max_rssi_value; + int8_t min_rssi_value; + uint8_t reserved[1]; + uint8_t reserved2[4]; /* reserved for MT6632 */ +}; + +struct PARAM_RSSI_MONITOR_EVENT { + uint8_t version; + int8_t rssi; + uint8_t BSSID[PARAM_MAC_ADDR_LEN]; +}; + +/* Packet Keep Alive */ +struct PARAM_PACKET_KEEPALIVE_T { + bool enable; /* 1=Start, 0=Stop*/ + uint8_t index; + int16_t u2IpPktLen; + uint8_t pIpPkt[256]; + uint8_t ucSrcMacAddr[PARAM_MAC_ADDR_LEN]; + uint8_t ucDstMacAddr[PARAM_MAC_ADDR_LEN]; + uint32_t u4PeriodMsec; + uint8_t reserved[8]; /* reserved for MT6632 */ +}; + +struct PARAM_BSS_MAC_OUI { + uint8_t ucBssIndex; + uint8_t ucMacOui[MAC_OUI_LEN]; +}; + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + + + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +int mtk_cfg80211_NLA_PUT(struct sk_buff *skb, int attrtype, + int attrlen, const void *data); + +int mtk_cfg80211_nla_put_type(struct sk_buff *skb, + enum ENUM_NLA_PUT_DATE_TYPE type, int attrtype, + const void *value); + +int mtk_cfg80211_vendor_get_capabilities(struct wiphy + *wiphy, struct wireless_dev *wdev, + const void *data, int data_len); + +int mtk_cfg80211_vendor_set_config(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len); + +int mtk_cfg80211_vendor_set_scan_config(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len); + +int mtk_cfg80211_vendor_set_significant_change( + struct wiphy *wiphy, struct wireless_dev *wdev, + const void *data, int data_len); + +int mtk_cfg80211_vendor_set_hotlist(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len); + +int mtk_cfg80211_vendor_enable_scan(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len); + +int mtk_cfg80211_vendor_enable_full_scan_results( + struct wiphy *wiphy, struct wireless_dev *wdev, + const void *data, int data_len); + +int mtk_cfg80211_vendor_get_scan_results(struct wiphy + *wiphy, struct wireless_dev *wdev, + const void *data, int data_len); + +int mtk_cfg80211_vendor_get_channel_list(struct wiphy + *wiphy, struct wireless_dev *wdev, + const void *data, int data_len); + +int mtk_cfg80211_vendor_set_country_code(struct wiphy + *wiphy, struct wireless_dev *wdev, + const void *data, int data_len); + +int mtk_cfg80211_vendor_get_rtt_capabilities( + struct wiphy *wiphy, struct wireless_dev *wdev, + const void *data, int data_len); + +int mtk_cfg80211_vendor_llstats_get_info(struct wiphy + *wiphy, struct wireless_dev *wdev, + const void *data, int data_len); + +int mtk_cfg80211_vendor_set_band(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len); + +int mtk_cfg80211_vendor_set_scan_mac_oui(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len); + +#if CFG_SUPPORT_MBO +int mtk_cfg80211_vendor_set_roaming_param( + struct wiphy *wiphy, struct wireless_dev *wdev, + const void *data, int data_len); +#endif + +int mtk_cfg80211_vendor_set_roaming_policy( + struct wiphy *wiphy, struct wireless_dev *wdev, + const void *data, int data_len); + +int mtk_cfg80211_vendor_get_roaming_capabilities( + struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int data_len); + +int mtk_cfg80211_vendor_config_roaming(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len); + +int mtk_cfg80211_vendor_enable_roaming(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len); + +int mtk_cfg80211_vendor_set_rssi_monitoring( + struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int data_len); + +int mtk_cfg80211_vendor_packet_keep_alive_start( + struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int data_len); + +int mtk_cfg80211_vendor_packet_keep_alive_stop( + struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int data_len); + +int mtk_cfg80211_vendor_get_version(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len); + +int mtk_cfg80211_vendor_event_generic_response( + struct wiphy *wiphy, struct wireless_dev *wdev, + uint32_t len, uint8_t *data); + +int mtk_cfg80211_vendor_get_supported_feature_set( + struct wiphy *wiphy, struct wireless_dev *wdev, + const void *data, int data_len); + +int mtk_cfg80211_vendor_event_rssi_beyond_range( + struct wiphy *wiphy, + struct wireless_dev *wdev, int rssi); + +int mtk_cfg80211_vendor_set_tx_power_scenario( + struct wiphy *wiphy, struct wireless_dev *wdev, + const void *data, int data_len); + +int mtk_cfg80211_vendor_get_preferred_freq_list(struct wiphy + *wiphy, struct wireless_dev *wdev, const void *data, + int data_len); + +int mtk_cfg80211_vendor_acs(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int data_len); + +int mtk_cfg80211_vendor_get_features(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int data_len); + +int mtk_cfg80211_vendor_driver_memory_dump(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len); + +#endif /* _GL_VENDOR_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_wext.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_wext.h new file mode 100644 index 0000000000000000000000000000000000000000..f11c272d716d4ffb226ed219649bfeafe707d8ba --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_wext.h @@ -0,0 +1,390 @@ +/******************************************************************************* + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ +/* + * Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include + * /gl_wext.h#1 + */ + +/*! \file gl_wext.h + * \brief This file is for Portable Driver linux wireless extension support. + */ + + +#ifndef _GL_WEXT_H +#define _GL_WEXT_H + +#ifdef WIRELESS_EXT +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +extern void wlanUpdateChannelTable(struct GLUE_INFO + *prGlueInfo); + +#if CFG_SUPPORT_WAPI +extern uint8_t +keyStructBuf[1024]; /* add/remove key shared buffer */ +#else +extern uint8_t +keyStructBuf[100]; /* add/remove key shared buffer */ +#endif + +/* for IE Searching */ +extern u_int8_t +wextSrchDesiredWPAIE(IN uint8_t *pucIEStart, + IN int32_t i4TotalIeLen, IN uint8_t ucDesiredElemId, + OUT uint8_t **ppucDesiredIE); + +#if CFG_SUPPORT_WPS +extern u_int8_t +wextSrchDesiredWPSIE(IN uint8_t *pucIEStart, + IN int32_t i4TotalIeLen, IN uint8_t ucDesiredElemId, + OUT uint8_t **ppucDesiredIE); +#endif + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#define KILO 1000 +#define RATE_5_5M 11 /* 5.5M */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +struct PARAM_FIXED_IEs { + uint8_t aucTimestamp[8]; + uint16_t u2BeaconInterval; + uint16_t u2Capabilities; +}; + +struct PARAM_VARIABLE_IE { + uint8_t ucElementID; + uint8_t ucLength; + uint8_t aucData[1]; +}; + +#if WIRELESS_EXT < 18 + +#define SIOCSIWMLME 0x8B16 /* request MLME operation; uses struct iw_mlme */ +/* MLME requests (SIOCSIWMLME / struct iw_mlme) */ +#define IW_MLME_DEAUTH 0 +#define IW_MLME_DISASSOC 1 + +/*! \brief SIOCSIWMLME data */ +struct iw_mlme { + __u16 cmd; /*!< IW_MLME_* */ + __u16 reason_code; + struct sockaddr addr; +}; + +#define SIOCSIWAUTH 0x8B32 /* set authentication mode params */ +#define SIOCGIWAUTH 0x8B33 /* get authentication mode params */ +/* SIOCSIWAUTH/SIOCGIWAUTH struct iw_param flags */ +#define IW_AUTH_INDEX 0x0FFF +#define IW_AUTH_FLAGS 0xF000 +/* SIOCSIWAUTH/SIOCGIWAUTH parameters (0 .. 4095) + * (IW_AUTH_INDEX mask in struct iw_param flags; this is the index of the + * parameter that is being set/get to; value will be read/written to + * struct iw_param value field) + */ +#define IW_AUTH_WPA_VERSION 0 +#define IW_AUTH_CIPHER_PAIRWISE 1 +#define IW_AUTH_CIPHER_GROUP 2 +#define IW_AUTH_KEY_MGMT 3 +#define IW_AUTH_TKIP_COUNTERMEASURES 4 +#define IW_AUTH_DROP_UNENCRYPTED 5 +#define IW_AUTH_80211_AUTH_ALG 6 +#define IW_AUTH_WPA_ENABLED 7 +#define IW_AUTH_RX_UNENCRYPTED_EAPOL 8 +#define IW_AUTH_ROAMING_CONTROL 9 +#define IW_AUTH_PRIVACY_INVOKED 10 +#if CFG_SUPPORT_802_11W +#define IW_AUTH_MFP 12 + +#define IW_AUTH_MFP_DISABLED 0 /* MFP disabled */ +#define IW_AUTH_MFP_OPTIONAL 1 /* MFP optional */ +#define IW_AUTH_MFP_REQUIRED 2 /* MFP required */ +#endif + +/* IW_AUTH_WPA_VERSION values (bit field) */ +#define IW_AUTH_WPA_VERSION_DISABLED 0x00000001 +#define IW_AUTH_WPA_VERSION_WPA 0x00000002 +#define IW_AUTH_WPA_VERSION_WPA2 0x00000004 + +/* IW_AUTH_PAIRWISE_CIPHER and IW_AUTH_GROUP_CIPHER values (bit field) */ +#define IW_AUTH_CIPHER_NONE 0x00000001 +#define IW_AUTH_CIPHER_WEP40 0x00000002 +#define IW_AUTH_CIPHER_TKIP 0x00000004 +#define IW_AUTH_CIPHER_CCMP 0x00000008 +#define IW_AUTH_CIPHER_WEP104 0x00000010 + +/* IW_AUTH_KEY_MGMT values (bit field) */ +#define IW_AUTH_KEY_MGMT_802_1X 1 +#define IW_AUTH_KEY_MGMT_PSK 2 +#define IW_AUTH_KEY_MGMT_WPA_NONE 4 + +/* IW_AUTH_80211_AUTH_ALG values (bit field) */ +#define IW_AUTH_ALG_OPEN_SYSTEM 0x00000001 +#define IW_AUTH_ALG_SHARED_KEY 0x00000002 +#define IW_AUTH_ALG_LEAP 0x00000004 + +/* IW_AUTH_ROAMING_CONTROL values */ +#define IW_AUTH_ROAMING_ENABLE 0 /* driver/firmware based roaming */ +#define IW_AUTH_ROAMING_DISABLE 1 /* user space program used for roaming + * control + */ + +#define SIOCSIWENCODEEXT 0x8B34 /* set encoding token & mode */ +#define SIOCGIWENCODEEXT 0x8B35 /* get encoding token & mode */ +/* SIOCSIWENCODEEXT definitions */ +#define IW_ENCODE_SEQ_MAX_SIZE 8 +/* struct iw_encode_ext ->alg */ +#define IW_ENCODE_ALG_NONE 0 +#define IW_ENCODE_ALG_WEP 1 +#define IW_ENCODE_ALG_TKIP 2 +#define IW_ENCODE_ALG_CCMP 3 +#if CFG_SUPPORT_802_11W +#define IW_ENCODE_ALG_AES_CMAC 5 +#endif + +/* struct iw_encode_ext ->ext_flags */ +#define IW_ENCODE_EXT_TX_SEQ_VALID 0x00000001 +#define IW_ENCODE_EXT_RX_SEQ_VALID 0x00000002 +#define IW_ENCODE_EXT_GROUP_KEY 0x00000004 +#define IW_ENCODE_EXT_SET_TX_KEY 0x00000008 + +struct iw_encode_ext { + __u32 ext_flags; /*!< IW_ENCODE_EXT_* */ + __u8 tx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /*!< LSB first */ + __u8 rx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /*!< LSB first */ + struct sockaddr addr; /*!< ff:ff:ff:ff:ff:ff for broadcast/multicast + * (group) keys or unicast address for + * individual keys + */ + __u16 alg; /*!< IW_ENCODE_ALG_* */ + __u16 key_len; + __u8 key[0]; +}; + +#define SIOCSIWPMKSA 0x8B36 /* PMKSA cache operation */ +#define IW_PMKSA_ADD 1 +#define IW_PMKSA_REMOVE 2 +#define IW_PMKSA_FLUSH 3 + +#define IW_PMKID_LEN 16 + +struct iw_pmksa { + __u32 cmd; /*!< IW_PMKSA_* */ + struct sockaddr bssid; + __u8 pmkid[IW_PMKID_LEN]; +}; + +#define IWEVGENIE 0x8C05 /* Generic IE (WPA, RSN, WMM, ..) + * (scan results); This includes id and + * length fields. One IWEVGENIE may + * contain more than one IE. Scan + * results may contain one or more + * IWEVGENIE events. + */ +#define IWEVMICHAELMICFAILURE 0x8C06 /* Michael MIC failure + * (struct iw_michaelmicfailure) + */ +#define IWEVASSOCREQIE 0x8C07 /* IEs used in (Re)Association Request. + * The data includes id and length + * fields and may contain more than one + * IE. This event is required in + * Managed mode if the driver + * generates its own WPA/RSN IE. This + * should be sent just before + * IWEVREGISTERED event for the + * association. + */ +#define IWEVASSOCRESPIE 0x8C08 /* IEs used in (Re)Association + * Response. The data includes id and + * length fields and may contain more + * than one IE. This may be sent + * between IWEVASSOCREQIE and + * IWEVREGISTERED events for the + * association. + */ +#define IWEVPMKIDCAND 0x8C09 /* PMKID candidate for RSN + * pre-authentication + * (struct iw_pmkid_cand) + */ + +#endif /* WIRELESS_EXT < 18 */ + +#if WIRELESS_EXT < 17 +/* Statistics flags (bitmask in updated) */ +#define IW_QUAL_QUAL_UPDATED 0x1 /* Value was updated since last read */ +#define IW_QUAL_LEVEL_UPDATED 0x2 +#define IW_QUAL_NOISE_UPDATED 0x4 +#define IW_QUAL_QUAL_INVALID 0x10 /* Driver doesn't provide value */ +#define IW_QUAL_LEVEL_INVALID 0x20 +#define IW_QUAL_NOISE_INVALID 0x40 +#endif + +enum { + IEEE80211_FILTER_TYPE_BEACON = 1 << 0, + IEEE80211_FILTER_TYPE_PROBE_REQ = 1 << 1, + IEEE80211_FILTER_TYPE_PROBE_RESP = 1 << 2, + IEEE80211_FILTER_TYPE_ASSOC_REQ = 1 << 3, + IEEE80211_FILTER_TYPE_ASSOC_RESP = 1 << 4, + IEEE80211_FILTER_TYPE_AUTH = 1 << 5, + IEEE80211_FILTER_TYPE_DEAUTH = 1 << 6, + IEEE80211_FILTER_TYPE_DISASSOC = 1 << 7, + /* used to check the valid filter bits */ + IEEE80211_FILTER_TYPE_ALL = 0xFF +}; + +#if CFG_SUPPORT_WAPI +#define IW_AUTH_WAPI_ENABLED 0x20 +#define IW_ENCODE_ALG_SMS4 0x20 +#endif + +#if CFG_SUPPORT_WAPI /* Android+ */ +#define IW_AUTH_KEY_MGMT_WAPI_PSK 3 +#define IW_AUTH_KEY_MGMT_WAPI_CERT 4 +#endif +#define IW_AUTH_KEY_MGMT_WPS 5 + +#if CFG_SUPPORT_802_11W +#define IW_AUTH_KEY_MGMT_802_1X_SHA256 7 +#define IW_AUTH_KEY_MGMT_PSK_SHA256 8 +#endif +#define IW_AUTH_ALG_FT 0x00000008 +#define IW_AUTH_ALG_SAE 0x00000010 + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ +extern const struct iw_handler_def wext_handler_def; + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +/* wireless extensions' ioctls */ +int wext_support_ioctl(IN struct net_device *prDev, + IN struct ifreq *prIfReq, IN int i4Cmd); + +int +wext_set_rate(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN struct iw_param *prRate, IN char *pcExtra); + +void +wext_indicate_wext_event(IN struct GLUE_INFO *prGlueInfo, + IN unsigned int u4Cmd, IN unsigned char *pucData, + IN unsigned int u4DataLen, + IN uint8_t ucBssIndex); + +struct iw_statistics *wext_get_wireless_stats( + struct net_device *prDev); + + +u_int8_t +wextSrchDesiredWPAIE(IN uint8_t *pucIEStart, + IN int32_t i4TotalIeLen, IN uint8_t ucDesiredElemId, + OUT uint8_t **ppucDesiredIE); + +#if CFG_SUPPORT_WPS +u_int8_t +wextSrchDesiredWPSIE(IN uint8_t *pucIEStart, + IN int32_t i4TotalIeLen, IN uint8_t ucDesiredElemId, + OUT uint8_t **ppucDesiredIE); +#endif + +#if CFG_SUPPORT_PASSPOINT +u_int8_t wextSrchDesiredHS20IE(IN uint8_t *pucIEStart, + IN int32_t i4TotalIeLen, + OUT uint8_t **ppucDesiredIE); + +u_int8_t wextSrchDesiredAdvProtocolIE(IN uint8_t + *pucIEStart, IN int32_t i4TotalIeLen, + OUT uint8_t **ppucDesiredIE); + +u_int8_t wextSrchDesiredOsenIE(IN uint8_t *pucIEStart, + IN int32_t i4TotalIeLen, + OUT uint8_t **ppucDesiredIE); +#endif /* CFG_SUPPORT_PASSPOINT */ + +u_int8_t wextSrchDesiredWAPIIE(IN uint8_t *pucIEStart, + IN int32_t i4TotalIeLen, + OUT uint8_t **ppucDesiredIE); + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#endif /* WIRELESS_EXT */ + +#endif /* _GL_WEXT_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_wext_priv.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_wext_priv.h new file mode 100644 index 0000000000000000000000000000000000000000..de8b95a439b123b230abf829f3ef027e3a03e0f1 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/include/gl_wext_priv.h @@ -0,0 +1,410 @@ +/******************************************************************************* + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ +/* + * Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include + /gl_wext_priv.h#3 + */ + +/*! \file gl_wext_priv.h + * \brief This file includes private ioctl support. + */ + + +#ifndef _GL_WEXT_PRIV_H +#define _GL_WEXT_PRIV_H +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ +/* If it is set to 1, iwpriv will support register read/write */ +#define CFG_SUPPORT_PRIV_MCR_RW 1 + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +/* New wireless extensions API - SET/GET convention (even ioctl numbers are + * root only) + */ +#define IOCTL_SET_INT (SIOCIWFIRSTPRIV + 0) +#define IOCTL_GET_INT (SIOCIWFIRSTPRIV + 1) + +#define IOCTL_SET_ADDRESS (SIOCIWFIRSTPRIV + 2) +#define IOCTL_GET_ADDRESS (SIOCIWFIRSTPRIV + 3) +#define IOCTL_SET_STR (SIOCIWFIRSTPRIV + 4) +#define IOCTL_GET_STR (SIOCIWFIRSTPRIV + 5) +#define IOCTL_SET_KEY (SIOCIWFIRSTPRIV + 6) +#define IOCTL_GET_KEY (SIOCIWFIRSTPRIV + 7) +#define IOCTL_SET_STRUCT (SIOCIWFIRSTPRIV + 8) +#define IOCTL_GET_STRUCT (SIOCIWFIRSTPRIV + 9) +#define IOCTL_SET_STRUCT_FOR_EM (SIOCIWFIRSTPRIV + 11) +#define IOCTL_SET_INTS (SIOCIWFIRSTPRIV + 12) +#define IOCTL_GET_INTS (SIOCIWFIRSTPRIV + 13) +#define IOCTL_SET_DRIVER (SIOCIWFIRSTPRIV + 14) +#define IOCTL_GET_DRIVER (SIOCIWFIRSTPRIV + 15) + +#if CFG_SUPPORT_QA_TOOL +#define IOCTL_QA_TOOL_DAEMON (SIOCIWFIRSTPRIV + 16) +#define IOCTL_IWPRIV_ATE (SIOCIWFIRSTPRIV + 17) +#endif + +#define IOC_AP_GET_STA_LIST (SIOCIWFIRSTPRIV+19) +#define IOC_AP_SET_MAC_FLTR (SIOCIWFIRSTPRIV+21) +#define IOC_AP_SET_CFG (SIOCIWFIRSTPRIV+23) +#define IOC_AP_STA_DISASSOC (SIOCIWFIRSTPRIV+25) +#define IOC_AP_SET_NSS (SIOCIWFIRSTPRIV+27) + +#define PRIV_CMD_REG_DOMAIN 0 +#define PRIV_CMD_BEACON_PERIOD 1 +#define PRIV_CMD_ADHOC_MODE 2 + +#if CFG_TCP_IP_CHKSUM_OFFLOAD +#define PRIV_CMD_CSUM_OFFLOAD 3 +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ + +#define PRIV_CMD_ROAMING 4 +#define PRIV_CMD_VOIP_DELAY 5 +#define PRIV_CMD_POWER_MODE 6 + +#define PRIV_CMD_WMM_PS 7 +#define PRIV_CMD_BT_COEXIST 8 +#define PRIV_GPIO2_MODE 9 + +#define PRIV_CUSTOM_SET_PTA 10 +#define PRIV_CUSTOM_CONTINUOUS_POLL 11 +#define PRIV_CUSTOM_SINGLE_ANTENNA 12 +#define PRIV_CUSTOM_BWCS_CMD 13 +#define PRIV_CUSTOM_DISABLE_BEACON_DETECTION 14 /* later */ +#define PRIV_CMD_OID 15 +#define PRIV_SEC_MSG_OID 16 + +#define PRIV_CMD_TEST_MODE 17 +#define PRIV_CMD_TEST_CMD 18 +#define PRIV_CMD_ACCESS_MCR 19 +#define PRIV_CMD_SW_CTRL 20 + +#if 1 /* ANTI_PRIVCY */ +#define PRIV_SEC_CHECK_OID 21 +#endif + +#define PRIV_CMD_WSC_PROBE_REQ 22 + +#define PRIV_CMD_P2P_VERSION 23 + +#define PRIV_CMD_GET_CH_LIST 24 + +#define PRIV_CMD_SET_TX_POWER_NO_USED 25 + +#define PRIV_CMD_BAND_CONFIG 26 + +#define PRIV_CMD_DUMP_MEM 27 + +#define PRIV_CMD_P2P_MODE 28 + +#if CFG_SUPPORT_QA_TOOL +#define PRIV_QACMD_SET 29 +#endif + +#define PRIV_CMD_MET_PROFILING 33 + +#if CFG_WOW_SUPPORT +#define PRIV_CMD_SET_WOW_ENABLE 34 +#define PRIV_CMD_SET_WOW_PAR 35 +#endif + +#ifdef UT_TEST_MODE +#define PRIV_CMD_UT 36 +#endif /* UT_TEST_MODE */ + +#define PRIV_CMD_SET_SER 37 + +/* Get FW manifest version */ +#define PRIV_CMD_GET_FW_VERSION 38 + + +/* dynamic tx power control */ +#define PRIV_CMD_SET_PWR_CTRL 40 + +/* wifi type: 11g, 11n, ... */ +#define PRIV_CMD_GET_WIFI_TYPE 41 + +/* 802.3 Objects (Ethernet) */ +#define OID_802_3_CURRENT_ADDRESS 0x01010102 + +/* IEEE 802.11 OIDs */ +#define OID_802_11_SUPPORTED_RATES 0x0D01020E +#define OID_802_11_CONFIGURATION 0x0D010211 + +/* PnP and PM OIDs, NDIS default OIDS */ +#define OID_PNP_SET_POWER 0xFD010101 + +#define OID_CUSTOM_OID_INTERFACE_VERSION 0xFFA0C000 + +/* MT5921 specific OIDs */ +#define OID_CUSTOM_BT_COEXIST_CTRL 0xFFA0C580 +#define OID_CUSTOM_POWER_MANAGEMENT_PROFILE 0xFFA0C581 +#define OID_CUSTOM_PATTERN_CONFIG 0xFFA0C582 +#define OID_CUSTOM_BG_SSID_SEARCH_CONFIG 0xFFA0C583 +#define OID_CUSTOM_VOIP_SETUP 0xFFA0C584 +#define OID_CUSTOM_ADD_TS 0xFFA0C585 +#define OID_CUSTOM_DEL_TS 0xFFA0C586 +#define OID_CUSTOM_SLT 0xFFA0C587 +#define OID_CUSTOM_ROAMING_EN 0xFFA0C588 +#define OID_CUSTOM_WMM_PS_TEST 0xFFA0C589 +#define OID_CUSTOM_COUNTRY_STRING 0xFFA0C58A +#define OID_CUSTOM_MULTI_DOMAIN_CAPABILITY 0xFFA0C58B +#define OID_CUSTOM_GPIO2_MODE 0xFFA0C58C +#define OID_CUSTOM_CONTINUOUS_POLL 0xFFA0C58D +#define OID_CUSTOM_DISABLE_BEACON_DETECTION 0xFFA0C58E + +/* CR1460, WPS privacy bit check disable */ +#define OID_CUSTOM_DISABLE_PRIVACY_CHECK 0xFFA0C600 + +/* Precedent OIDs */ +#define OID_CUSTOM_MCR_RW 0xFFA0C801 +#define OID_CUSTOM_EEPROM_RW 0xFFA0C803 +#define OID_CUSTOM_SW_CTRL 0xFFA0C805 +#define OID_CUSTOM_MEM_DUMP 0xFFA0C807 + +/* RF Test specific OIDs */ +#define OID_CUSTOM_TEST_MODE 0xFFA0C901 +#define OID_CUSTOM_TEST_RX_STATUS 0xFFA0C903 +#define OID_CUSTOM_TEST_TX_STATUS 0xFFA0C905 +#define OID_CUSTOM_ABORT_TEST_MODE 0xFFA0C906 +#define OID_CUSTOM_MTK_WIFI_TEST 0xFFA0C911 +#define OID_CUSTOM_TEST_ICAP_MODE 0xFFA0C913 + +/* BWCS */ +#define OID_CUSTOM_BWCS_CMD 0xFFA0C931 +#define OID_CUSTOM_SINGLE_ANTENNA 0xFFA0C932 +#define OID_CUSTOM_SET_PTA 0xFFA0C933 + +/* NVRAM */ +#define OID_CUSTOM_MTK_NVRAM_RW 0xFFA0C941 +#define OID_CUSTOM_CFG_SRC_TYPE 0xFFA0C942 +#define OID_CUSTOM_EEPROM_TYPE 0xFFA0C943 + +#if CFG_SUPPORT_WAPI +#define OID_802_11_WAPI_MODE 0xFFA0CA00 +#define OID_802_11_WAPI_ASSOC_INFO 0xFFA0CA01 +#define OID_802_11_SET_WAPI_KEY 0xFFA0CA02 +#endif + +#if CFG_SUPPORT_WPS2 +#define OID_802_11_WSC_ASSOC_INFO 0xFFA0CB00 +#endif + +#if CFG_SUPPORT_LOWLATENCY_MODE +#define OID_CUSTOM_LOWLATENCY_MODE 0xFFA0CC00 +#endif /* CFG_SUPPORT_LOWLATENCY_MODE */ + +#define OID_IPC_WIFI_LOG_UI 0xFFA0CC01 +#define OID_IPC_WIFI_LOG_LEVEL 0xFFA0CC02 + +#if CFG_SUPPORT_ANT_SWAP +#define OID_CUSTOM_QUERY_ANT_SWAP_CAPABILITY 0xFFA0CD00 +#endif + +#if CFG_SUPPORT_NCHO +#define CMD_NCHO_COMP_TIMEOUT 1500 /* ms */ +#define CMD_NCHO_AF_DATA_LENGTH 1040 +#endif + +#ifdef UT_TEST_MODE +#define OID_UT 0xFFA0CD00 +#endif /* UT_TEST_MODE */ + +/* Define magic key of test mode (Don't change it for future compatibity) */ +#define PRIV_CMD_TEST_MAGIC_KEY 2011 +#define PRIV_CMD_TEST_MAGIC_KEY_ICAP 2013 + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +/* NIC BBCR configuration entry structure */ +struct PRIV_CONFIG_ENTRY { + uint8_t ucOffset; + uint8_t ucValue; +}; + +typedef uint32_t(*PFN_OID_HANDLER_FUNC_REQ) ( + IN void *prAdapter, + IN OUT void *pvBuf, IN uint32_t u4BufLen, + OUT uint32_t *pu4OutInfoLen); + +enum ENUM_OID_METHOD { + ENUM_OID_GLUE_ONLY, + ENUM_OID_GLUE_EXTENSION, + ENUM_OID_DRIVER_CORE +}; + +/* OID set/query processing entry */ +struct WLAN_REQ_ENTRY { + uint32_t rOid; /* OID */ + uint8_t *pucOidName; /* OID name text */ + u_int8_t fgQryBufLenChecking; + u_int8_t fgSetBufLenChecking; + enum ENUM_OID_METHOD eOidMethod; + uint32_t u4InfoBufLen; + PFN_OID_HANDLER_FUNC_REQ pfOidQueryHandler; /* PFN_OID_HANDLER_FUNC */ + PFN_OID_HANDLER_FUNC_REQ pfOidSetHandler; /* PFN_OID_HANDLER_FUNC */ +}; + +struct NDIS_TRANSPORT_STRUCT { + uint32_t ndisOidCmd; + uint32_t inNdisOidlength; + uint32_t outNdisOidLength; + uint8_t ndisOidContent[16]; +}; + +enum AGG_RANGE_TYPE_T { + ENUM_AGG_RANGE_TYPE_TX = 0, + ENUM_AGG_RANGE_TYPE_TRX = 1, + ENUM_AGG_RANGE_TYPE_RX = 2 +}; + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +int +priv_set_int(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN union iwreq_data *prIwReqData, IN char *pcExtra); + +int +priv_get_int(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN union iwreq_data *prIwReqData, IN OUT char *pcExtra); + +int +priv_set_ints(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN union iwreq_data *prIwReqData, IN char *pcExtra); + +int +priv_get_ints(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN union iwreq_data *prIwReqData, IN OUT char *pcExtra); + +int +priv_set_struct(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN union iwreq_data *prIwReqData, IN char *pcExtra); + +int +priv_get_struct(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN union iwreq_data *prIwReqData, IN OUT char *pcExtra); + +int +priv_set_driver(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN union iwreq_data *prIwReqData, IN OUT char *pcExtra); + +int +priv_set_ap(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN union iwreq_data *prIwReqData, IN OUT char *pcExtra); + +int priv_support_ioctl(IN struct net_device *prDev, + IN OUT struct ifreq *prReq, IN int i4Cmd); + +int priv_support_driver_cmd(IN struct net_device *prDev, + IN OUT struct ifreq *prReq, IN int i4Cmd); + +#ifdef CFG_ANDROID_AOSP_PRIV_CMD +int android_private_support_driver_cmd(IN struct net_device *prDev, +IN OUT struct ifreq *prReq, IN int i4Cmd); +#endif /* CFG_ANDROID_AOSP_PRIV_CMD */ + +int32_t priv_driver_cmds(IN struct net_device *prNetDev, + IN int8_t *pcCommand, IN int32_t i4TotalLen); + +int priv_driver_set_cfg(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen); + +#if CFG_SUPPORT_QA_TOOL +int +priv_ate_set(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN union iwreq_data *prIwReqData, IN char *pcExtra); +#endif + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#endif /* _GL_WEXT_PRIV_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/plat/mt6765/plat_priv.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/plat/mt6765/plat_priv.c new file mode 100644 index 0000000000000000000000000000000000000000..0a7ce56267c2d830c20604065243af5559a2e9d5 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/plat/mt6765/plat_priv.c @@ -0,0 +1,103 @@ +/* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. +*/ + +#include +#include +#include "gl_os.h" + +#if KERNEL_VERSION(4, 19, 0) <= CFG80211_VERSION_CODE +#include +#define pm_qos_add_request(_req, _class, _value) \ + mtk_pm_qos_add_request(_req, _class, _value) +#define pm_qos_update_request(_req, _value) \ + mtk_pm_qos_update_request(_req, _value) +#define pm_qos_remove_request(_req) \ + mtk_pm_qos_remove_request(_req) +#define pm_qos_request mtk_pm_qos_request +#define PM_QOS_DDR_OPP MTK_PM_QOS_DDR_OPP +#define ppm_limit_data cpu_ctrl_data +#else +#include +#include +#endif + +#include "precomp.h" + +#ifdef CONFIG_MTK_EMI +#include +#define WIFI_EMI_MEM_OFFSET 0x140000 +#define WIFI_EMI_MEM_SIZE 0x130000 +#endif + +#define MAX_CPU_FREQ (3 * 1024 * 1024) /* in kHZ */ +#define MAX_CLUSTER_NUM 3 + +int32_t kalBoostCpu(IN struct ADAPTER *prAdapter, + IN uint32_t u4TarPerfLevel, + IN uint32_t u4BoostCpuTh) +{ + struct ppm_limit_data freq_to_set[MAX_CLUSTER_NUM]; + int32_t i = 0, i4Freq = -1; + static struct pm_qos_request wifi_qos_request; + static u_int8_t fgRequested; + uint32_t u4ClusterNum = topo_ctrl_get_nr_clusters(); + + ASSERT(u4ClusterNum <= MAX_CLUSTER_NUM); + /* ACAO, we dont have to set core number */ + i4Freq = (u4TarPerfLevel >= u4BoostCpuTh) ? MAX_CPU_FREQ : -1; + for (i = 0; i < u4ClusterNum; i++) { + freq_to_set[i].min = i4Freq; + freq_to_set[i].max = i4Freq; + } + + update_userlimit_cpu_freq(CPU_KIR_WIFI, u4ClusterNum, freq_to_set); + + if (u4TarPerfLevel >= u4BoostCpuTh) { + if (!fgRequested) { + fgRequested = 1; + pm_qos_add_request(&wifi_qos_request, + PM_QOS_DDR_OPP, + DDR_OPP_0); + } + pm_qos_update_request(&wifi_qos_request, DDR_OPP_0); + } else if (fgRequested) { + pm_qos_update_request(&wifi_qos_request, DDR_OPP_UNREQ); + pm_qos_remove_request(&wifi_qos_request); + fgRequested = 0; + } + return 0; +} + +#ifdef CONFIG_MTK_EMI +void kalSetEmiMpuProtection(phys_addr_t emiPhyBase, bool enable) +{ +} + +void kalSetDrvEmiMpuProtection(phys_addr_t emiPhyBase, uint32_t offset, + uint32_t size) +{ + struct emi_region_info_t region_info; + + DBGLOG(INIT, INFO, "emiPhyBase: 0x%x, offset: %u, size: %u\n", + emiPhyBase, offset, size); + + /*set MPU for EMI share Memory */ + region_info.start = emiPhyBase + offset; + region_info.end = emiPhyBase + offset + size - 1; + region_info.region = 29; + SET_ACCESS_PERMISSION(region_info.apc, LOCK, FORBIDDEN, FORBIDDEN, + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, + FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION, + FORBIDDEN, NO_PROTECTION); + emi_mpu_set_protection(®ion_info); +} +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/plat/mt6768/plat_priv.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/plat/mt6768/plat_priv.c new file mode 100644 index 0000000000000000000000000000000000000000..341ab19d74b295c447b23483f68c751fe22eecc3 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/plat/mt6768/plat_priv.c @@ -0,0 +1,107 @@ +/* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. +*/ + +#include +#include +#ifdef WLAN_FORCE_DDR_OPP +#include +#endif + +#include "precomp.h" + +#ifdef CONFIG_MTK_EMI +#include +#define WIFI_EMI_MEM_OFFSET 0x140000 +#define WIFI_EMI_MEM_SIZE 0x130000 +#endif + +#define MAX_CPU_FREQ (3 * 1024 * 1024) /* in kHZ */ +#define MAX_CLUSTER_NUM 3 + + +uint32_t kalGetCpuBoostThreshold(void) +{ + DBGLOG(SW4, TRACE, "enter kalGetCpuBoostThreshold\n"); + /* 3, stands for 100Mbps */ + return 3; +} + +int32_t kalBoostCpu(IN struct ADAPTER *prAdapter, + IN uint32_t u4TarPerfLevel, + IN uint32_t u4BoostCpuTh) +{ + struct ppm_limit_data freq_to_set[MAX_CLUSTER_NUM]; + int32_t i = 0, i4Freq = -1; +#ifdef WLAN_FORCE_DDR_OPP + static struct pm_qos_request wifi_qos_request; + static u_int8_t fgRequested; +#endif + uint32_t u4ClusterNum = topo_ctrl_get_nr_clusters(); + + ASSERT(u4ClusterNum <= MAX_CLUSTER_NUM); + /* ACAO, we dont have to set core number */ + i4Freq = (u4TarPerfLevel >= u4BoostCpuTh) ? MAX_CPU_FREQ : -1; + for (i = 0; i < u4ClusterNum; i++) { + freq_to_set[i].min = i4Freq; + freq_to_set[i].max = i4Freq; + } + + update_userlimit_cpu_freq(CPU_KIR_WIFI, u4ClusterNum, freq_to_set); + +#ifdef WLAN_FORCE_DDR_OPP + if (u4TarPerfLevel >= u4BoostCpuTh) { + if (!fgRequested) { + fgRequested = 1; + pm_qos_add_request(&wifi_qos_request, + PM_QOS_DDR_OPP, + DDR_OPP_0); + } + pm_qos_update_request(&wifi_qos_request, DDR_OPP_0); + } else if (fgRequested) { + pm_qos_update_request(&wifi_qos_request, DDR_OPP_UNREQ); + pm_qos_remove_request(&wifi_qos_request); + fgRequested = 0; + } +#endif + return 0; +} + +#ifdef CONFIG_MTK_EMI +void kalSetEmiMpuProtection(phys_addr_t emiPhyBase, bool enable) +{ +} + +void kalSetDrvEmiMpuProtection(phys_addr_t emiPhyBase, uint32_t offset, + uint32_t size) +{ + struct emi_region_info_t region_info; + + DBGLOG(INIT, INFO, "emiPhyBase: 0x%x, offset: %u, size: %u\n", + emiPhyBase, offset, size); + + /*set MPU for EMI share Memory */ + region_info.start = emiPhyBase + offset; + region_info.end = emiPhyBase + offset + size - 1; + region_info.region = 29; + SET_ACCESS_PERMISSION(region_info.apc, LOCK, FORBIDDEN, FORBIDDEN, + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, + FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION, + FORBIDDEN, NO_PROTECTION); + emi_mpu_set_protection(®ion_info); +} +#endif + +int32_t kalGetFwFlavor(uint8_t *flavor) +{ + *flavor = 'a'; + return 1; +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/plat/mt6779/plat_priv.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/plat/mt6779/plat_priv.c new file mode 100644 index 0000000000000000000000000000000000000000..695a94ef1f04d612bde83e7c5a7f42151730b4b2 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/plat/mt6779/plat_priv.c @@ -0,0 +1,111 @@ +/* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. +*/ + +#include +#include +#include "precomp.h" +#include "wmt_exp.h" + +#ifdef CONFIG_MTK_EMI +#include +#define WIFI_EMI_MEM_OFFSET 0x1D0000 +#define WIFI_EMI_MEM_SIZE 0x140000 +#define REGION_PDMA 18 +#define REGION_WIFI 26 +#define DOMAIN_AP 0 +#define DOMAIN_CONN 2 +#endif + +#define MAX_CPU_FREQ (3 * 1024 * 1024) /* in kHZ */ +#define MAX_CLUSTER_NUM 3 + +uint32_t kalGetCpuBoostThreshold(void) +{ + DBGLOG(SW4, TRACE, "enter kalGetCpuBoostThreshold\n"); + /* 5, stands for 250Mbps */ + return 5; +} + +int32_t kalBoostCpu(IN struct ADAPTER *prAdapter, + IN uint32_t u4TarPerfLevel, + IN uint32_t u4BoostCpuTh) +{ + struct cpu_ctrl_data freq_to_set[MAX_CLUSTER_NUM]; + int32_t i = 0, i4Freq = -1; + + uint32_t u4ClusterNum = topo_ctrl_get_nr_clusters(); + + ASSERT(u4ClusterNum <= MAX_CLUSTER_NUM); + /* ACAO, we dont have to set core number */ + i4Freq = (u4TarPerfLevel >= u4BoostCpuTh) ? MAX_CPU_FREQ : -1; + for (i = 0; i < u4ClusterNum; i++) { + freq_to_set[i].min = i4Freq; + freq_to_set[i].max = i4Freq; + } + + update_userlimit_cpu_freq(CPU_KIR_WIFI, u4ClusterNum, freq_to_set); + + return 0; +} + +#ifdef CONFIG_MTK_EMI +void kalSetEmiMpuProtection(phys_addr_t emiPhyBase, bool enable) +{ +} + +void kalSetDrvEmiMpuProtection(phys_addr_t emiPhyBase, uint32_t offset, + uint32_t size) +{ + struct emimpu_region_t region; + unsigned long long start = emiPhyBase + offset; + unsigned long long end = emiPhyBase + offset + size - 1; + int ret; + + DBGLOG(INIT, INFO, "emiPhyBase: 0x%p, offset: %d, size: %d\n", + emiPhyBase, offset, size); + + ret = mtk_emimpu_init_region(®ion, REGION_PDMA); + if (ret) { + DBGLOG(INIT, ERROR, "mtk_emimpu_init_region(%u) failed %d\n", + REGION_PDMA, ret); + return; + } + mtk_emimpu_set_addr(®ion, start, end); + mtk_emimpu_set_apc(®ion, DOMAIN_AP, MTK_EMIMPU_NO_PROTECTION); + mtk_emimpu_set_apc(®ion, DOMAIN_CONN, MTK_EMIMPU_NO_PROTECTION); + mtk_emimpu_lock_region(®ion, MTK_EMIMPU_LOCK); + ret = mtk_emimpu_set_protection(®ion); + if (ret) + DBGLOG(INIT, ERROR, + "mtk_emimpu_set_protection(%u) failed %d\n", + REGION_PDMA, ret); + mtk_emimpu_free_region(®ion); +} +#endif + +int32_t kalGetFwFlavor(uint8_t *flavor) +{ + int32_t ret = 1; + const uint32_t adie_chip_id = mtk_wcn_wmt_ic_info_get(WMTCHIN_ADIE); + + DBGLOG(INIT, INFO, "adie_chip_id: 0x%x\n", adie_chip_id); + + switch (adie_chip_id) { + case 0x6631: + *flavor = 'a'; + break; + default: + ret = 0; + break; + } + + return ret; +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/plat/mt6785/plat_priv.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/plat/mt6785/plat_priv.c new file mode 100644 index 0000000000000000000000000000000000000000..28a93be4bb19063faaecce2166e1fd8139dca7a2 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/plat/mt6785/plat_priv.c @@ -0,0 +1,108 @@ +/* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. +*/ + +#include +#include +#ifdef WLAN_FORCE_DDR_OPP +#include +#endif + +#include "precomp.h" + +#ifdef CONFIG_MTK_EMI +#include +#define WIFI_EMI_MEM_OFFSET 0x140000 +#define WIFI_EMI_MEM_SIZE 0x130000 +#endif + + +#define MAX_CPU_FREQ (3 * 1024 * 1024) /* in kHZ */ +#define MAX_CLUSTER_NUM 3 + + +uint32_t kalGetCpuBoostThreshold(void) +{ + DBGLOG(SW4, TRACE, "enter kalGetCpuBoostThreshold\n"); + /* 3, stands for 100Mbps */ + return 3; +} + +int32_t kalBoostCpu(IN struct ADAPTER *prAdapter, + IN uint32_t u4TarPerfLevel, + IN uint32_t u4BoostCpuTh) +{ + struct ppm_limit_data freq_to_set[MAX_CLUSTER_NUM]; + int32_t i = 0, i4Freq = -1; +#ifdef WLAN_FORCE_DDR_OPP + static struct pm_qos_request wifi_qos_request; + static u_int8_t fgRequested; +#endif + uint32_t u4ClusterNum = topo_ctrl_get_nr_clusters(); + + ASSERT(u4ClusterNum <= MAX_CLUSTER_NUM); + /* ACAO, we dont have to set core number */ + i4Freq = (u4TarPerfLevel >= u4BoostCpuTh) ? MAX_CPU_FREQ : -1; + for (i = 0; i < u4ClusterNum; i++) { + freq_to_set[i].min = i4Freq; + freq_to_set[i].max = i4Freq; + } + + update_userlimit_cpu_freq(CPU_KIR_WIFI, u4ClusterNum, freq_to_set); + +#ifdef WLAN_FORCE_DDR_OPP + if (u4TarPerfLevel >= u4BoostCpuTh) { + if (!fgRequested) { + fgRequested = 1; + pm_qos_add_request(&wifi_qos_request, + PM_QOS_DDR_OPP, + DDR_OPP_0); + } + pm_qos_update_request(&wifi_qos_request, DDR_OPP_0); + } else if (fgRequested) { + pm_qos_update_request(&wifi_qos_request, DDR_OPP_UNREQ); + pm_qos_remove_request(&wifi_qos_request); + fgRequested = 0; + } +#endif + return 0; +} + +#ifdef CONFIG_MTK_EMI +void kalSetEmiMpuProtection(phys_addr_t emiPhyBase, bool enable) +{ +} + +void kalSetDrvEmiMpuProtection(phys_addr_t emiPhyBase, uint32_t offset, + uint32_t size) +{ + struct emi_region_info_t region_info; + + DBGLOG(INIT, INFO, "emiPhyBase: 0x%x, offset: %u, size: %u\n", + emiPhyBase, offset, size); + + /*set MPU for EMI share Memory */ + region_info.start = emiPhyBase + offset; + region_info.end = emiPhyBase + offset + size - 1; + region_info.region = 18; + SET_ACCESS_PERMISSION(region_info.apc, LOCK, FORBIDDEN, FORBIDDEN, + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, + FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION, + FORBIDDEN, NO_PROTECTION); + emi_mpu_set_protection(®ion_info); +} +#endif + +int32_t kalGetFwFlavor(uint8_t *flavor) +{ + *flavor = 'a'; + return 1; +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/plat/mt6853/plat_priv.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/plat/mt6853/plat_priv.c new file mode 100644 index 0000000000000000000000000000000000000000..8749118986b3e2766796a22a7359968e9c8ad0d3 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/plat/mt6853/plat_priv.c @@ -0,0 +1,188 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include +#include +#include +#include + +#include "precomp.h" +#include "wmt_exp.h" + +#ifdef CONFIG_MEDIATEK_EMI +#include +#define WIFI_EMI_MEM_OFFSET 0x1D0000 +#define WIFI_EMI_MEM_SIZE 0x140000 +#define DOMAIN_AP 0 +#define DOMAIN_CONN 2 +#endif + +#define MAX_CPU_FREQ (3 * 1024 * 1024) /* in kHZ */ +#define MAX_CLUSTER_NUM 3 +#define CPU_BIG_CORE (0xc0) +#define CPU_SMALL_CORE (0xff - CPU_BIG_CORE) + +enum ENUM_CPU_BOOST_STATUS { + ENUM_CPU_BOOST_STATUS_INIT = 0, + ENUM_CPU_BOOST_STATUS_START, + ENUM_CPU_BOOST_STATUS_STOP, + ENUM_CPU_BOOST_STATUS_NUM +}; + +uint32_t kalGetCpuBoostThreshold(void) +{ + DBGLOG(SW4, TRACE, "enter kalGetCpuBoostThreshold\n"); + /* 5, stands for 250Mbps */ + return 5; +} + +int32_t kalCheckTputLoad(IN struct ADAPTER *prAdapter, + IN uint32_t u4CurrPerfLevel, + IN uint32_t u4TarPerfLevel, + IN int32_t i4Pending, + IN uint32_t u4Used) +{ + uint32_t pendingTh = + CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD * + prAdapter->rWifiVar.u4PerfMonPendingTh / 100; + uint32_t usedTh = (HIF_TX_MSDU_TOKEN_NUM / 2) * + prAdapter->rWifiVar.u4PerfMonUsedTh / 100; + return u4TarPerfLevel >= 3 && + u4TarPerfLevel < prAdapter->rWifiVar.u4BoostCpuTh && + i4Pending >= pendingTh && + u4Used >= usedTh ? + TRUE : FALSE; +} + +int32_t kalBoostCpu(IN struct ADAPTER *prAdapter, + IN uint32_t u4TarPerfLevel, + IN uint32_t u4BoostCpuTh) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct ppm_limit_data freq_to_set[MAX_CLUSTER_NUM]; + int32_t i = 0, i4Freq = -1; + + static struct pm_qos_request wifi_qos_request; + static u_int8_t fgRequested = ENUM_CPU_BOOST_STATUS_INIT; + + uint32_t u4ClusterNum = topo_ctrl_get_nr_clusters(); + + prGlueInfo = (struct GLUE_INFO *)wiphy_priv(wlanGetWiphy()); + ASSERT(u4ClusterNum <= MAX_CLUSTER_NUM); + /* ACAO, we dont have to set core number */ + i4Freq = (u4TarPerfLevel >= u4BoostCpuTh) ? MAX_CPU_FREQ : -1; + for (i = 0; i < u4ClusterNum; i++) { + freq_to_set[i].min = i4Freq; + freq_to_set[i].max = i4Freq; + } + + if (fgRequested == ENUM_CPU_BOOST_STATUS_INIT) { + /* initially enable rps working at small cores */ + kalSetRpsMap(prGlueInfo, CPU_SMALL_CORE); + fgRequested = ENUM_CPU_BOOST_STATUS_STOP; + } + + if (u4TarPerfLevel >= u4BoostCpuTh) { + if (fgRequested == ENUM_CPU_BOOST_STATUS_STOP) { + pr_info("kalBoostCpu start (%d>=%d)\n", + u4TarPerfLevel, u4BoostCpuTh); + fgRequested = ENUM_CPU_BOOST_STATUS_START; + + set_task_util_min_pct(prGlueInfo->u4TxThreadPid, 100); + set_task_util_min_pct(prGlueInfo->u4RxThreadPid, 100); + set_task_util_min_pct(prGlueInfo->u4HifThreadPid, 100); + kalSetRpsMap(prGlueInfo, CPU_BIG_CORE); + update_userlimit_cpu_freq(CPU_KIR_WIFI, + u4ClusterNum, freq_to_set); + + KAL_ACQUIRE_MUTEX(prAdapter, MUTEX_BOOST_CPU); + pr_info("Max Dram Freq start\n"); + pm_qos_add_request(&wifi_qos_request, + PM_QOS_DDR_OPP, + DDR_OPP_0); + pm_qos_update_request(&wifi_qos_request, DDR_OPP_0); + KAL_RELEASE_MUTEX(prAdapter, MUTEX_BOOST_CPU); + } + } else { + if (fgRequested == ENUM_CPU_BOOST_STATUS_START) { + pr_info("kalBoostCpu stop (%d<%d)\n", + u4TarPerfLevel, u4BoostCpuTh); + fgRequested = ENUM_CPU_BOOST_STATUS_STOP; + + set_task_util_min_pct(prGlueInfo->u4TxThreadPid, 0); + set_task_util_min_pct(prGlueInfo->u4RxThreadPid, 0); + set_task_util_min_pct(prGlueInfo->u4HifThreadPid, 0); + kalSetRpsMap(prGlueInfo, CPU_SMALL_CORE); + update_userlimit_cpu_freq(CPU_KIR_WIFI, + u4ClusterNum, freq_to_set); + + KAL_ACQUIRE_MUTEX(prAdapter, MUTEX_BOOST_CPU); + pr_info("Max Dram Freq end\n"); + pm_qos_update_request(&wifi_qos_request, DDR_OPP_UNREQ); + pm_qos_remove_request(&wifi_qos_request); + KAL_RELEASE_MUTEX(prAdapter, MUTEX_BOOST_CPU); + } + } + kalTraceInt(fgRequested == ENUM_CPU_BOOST_STATUS_START, "kalBoostCpu"); + + return 0; +} + +#ifdef CONFIG_MEDIATEK_EMI +void kalSetEmiMpuProtection(phys_addr_t emiPhyBase, bool enable) +{ +} + +void kalSetDrvEmiMpuProtection(phys_addr_t emiPhyBase, uint32_t offset, + uint32_t size) +{ + struct emimpu_region_t region; + unsigned long long start = emiPhyBase + offset; + unsigned long long end = emiPhyBase + offset + size - 1; + int ret; + + DBGLOG(INIT, INFO, "emiPhyBase: 0x%p, offset: %d, size: %d\n", + emiPhyBase, offset, size); + + ret = mtk_emimpu_init_region(®ion, 18); + if (ret) { + DBGLOG(INIT, ERROR, "mtk_emimpu_init_region failed, ret: %d\n", + ret); + return; + } + mtk_emimpu_set_addr(®ion, start, end); + mtk_emimpu_set_apc(®ion, DOMAIN_AP, MTK_EMIMPU_NO_PROTECTION); + mtk_emimpu_set_apc(®ion, DOMAIN_CONN, MTK_EMIMPU_NO_PROTECTION); + mtk_emimpu_lock_region(®ion, MTK_EMIMPU_LOCK); + ret = mtk_emimpu_set_protection(®ion); + if (ret) + DBGLOG(INIT, ERROR, + "mtk_emimpu_set_protection failed, ret: %d\n", + ret); + mtk_emimpu_free_region(®ion); +} +#endif + +int32_t kalGetFwFlavor(uint8_t *flavor) +{ + int32_t ret = 1; + const uint32_t adie_chip_id = mtk_wcn_wmt_ic_info_get(WMTCHIN_ADIE); + + DBGLOG(INIT, INFO, "adie_chip_id: 0x%x\n", adie_chip_id); + + switch (adie_chip_id) { + case 0x6631: + *flavor = 'c'; + break; + case 0x6635: + *flavor = 'd'; + break; + default: + ret = 0; + break; + } + + return ret; +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/plat/mt6873/plat_priv.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/plat/mt6873/plat_priv.c new file mode 100644 index 0000000000000000000000000000000000000000..90cd923cbcb41d9ab109e09481f8b886136e6ef7 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/plat/mt6873/plat_priv.c @@ -0,0 +1,182 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include /* constant of kernel version */ +#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE +/*TODO kernel 5.4 boost CPU */ +#else +#include +#include +#include +#endif +#include +#include "precomp.h" + + +#if CONFIG_MTK_EMI +#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE +#include +#else +#include +#endif +#define WIFI_EMI_MEM_OFFSET 0x1D0000 +#define WIFI_EMI_MEM_SIZE 0x140000 +#define DOMAIN_AP 0 +#define DOMAIN_CONN 2 +#endif + + +#define MAX_CPU_FREQ (3 * 1024 * 1024) /* in kHZ */ +#define MAX_CLUSTER_NUM 3 + +enum ENUM_CPU_BOOST_STATUS { + ENUM_CPU_BOOST_STATUS_INIT = 0, + ENUM_CPU_BOOST_STATUS_START, + ENUM_CPU_BOOST_STATUS_STOP, + ENUM_CPU_BOOST_STATUS_NUM +}; + +uint32_t kalGetCpuBoostThreshold(void) +{ + DBGLOG(SW4, TRACE, "enter kalGetCpuBoostThreshold\n"); + /* 5, stands for 250Mbps */ + return 5; +} + +int32_t kalCheckTputLoad(IN struct ADAPTER *prAdapter, + IN uint32_t u4CurrPerfLevel, + IN uint32_t u4TarPerfLevel, + IN int32_t i4Pending, + IN uint32_t u4Used) +{ + uint32_t pendingTh = + CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD * + prAdapter->rWifiVar.u4PerfMonPendingTh / 100; + uint32_t usedTh = (HIF_TX_MSDU_TOKEN_NUM / 2) * + prAdapter->rWifiVar.u4PerfMonUsedTh / 100; + return u4TarPerfLevel >= 3 && + u4TarPerfLevel < prAdapter->rWifiVar.u4BoostCpuTh && + i4Pending >= pendingTh && + u4Used >= usedTh ? + TRUE : FALSE; +} + +#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE +#else +int32_t kalBoostCpu(IN struct ADAPTER *prAdapter, + IN uint32_t u4TarPerfLevel, + IN uint32_t u4BoostCpuTh) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct ppm_limit_data freq_to_set[MAX_CLUSTER_NUM]; + int32_t i = 0, i4Freq = -1; + + static struct pm_qos_request wifi_qos_request; + static u_int8_t fgRequested = ENUM_CPU_BOOST_STATUS_INIT; + + uint32_t u4ClusterNum = topo_ctrl_get_nr_clusters(); + + prGlueInfo = (struct GLUE_INFO *)wiphy_priv(wlanGetWiphy()); + ASSERT(u4ClusterNum <= MAX_CLUSTER_NUM); + /* ACAO, we dont have to set core number */ + i4Freq = (u4TarPerfLevel >= u4BoostCpuTh) ? MAX_CPU_FREQ : -1; + for (i = 0; i < u4ClusterNum; i++) { + freq_to_set[i].min = i4Freq; + freq_to_set[i].max = i4Freq; + } + + if (fgRequested == ENUM_CPU_BOOST_STATUS_INIT) { + /* initially enable rps working at small cores */ + kalSetRpsMap(prGlueInfo, 0x0f); + fgRequested = ENUM_CPU_BOOST_STATUS_STOP; + } + + if (u4TarPerfLevel >= u4BoostCpuTh) { + if (fgRequested == ENUM_CPU_BOOST_STATUS_STOP) { + pr_info("kalBoostCpu start (%d>=%d)\n", + u4TarPerfLevel, u4BoostCpuTh); + fgRequested = ENUM_CPU_BOOST_STATUS_START; + + set_task_util_min_pct(prGlueInfo->u4TxThreadPid, 100); + set_task_util_min_pct(prGlueInfo->u4RxThreadPid, 100); + set_task_util_min_pct(prGlueInfo->u4HifThreadPid, 100); + kalSetRpsMap(prGlueInfo, 0xf0); /* big cores */ + update_userlimit_cpu_freq(CPU_KIR_WIFI, + u4ClusterNum, freq_to_set); + + KAL_ACQUIRE_MUTEX(prAdapter, MUTEX_BOOST_CPU); + pr_info("Max Dram Freq start\n"); + pm_qos_add_request(&wifi_qos_request, + PM_QOS_DDR_OPP, + DDR_OPP_0); + pm_qos_update_request(&wifi_qos_request, DDR_OPP_0); + KAL_RELEASE_MUTEX(prAdapter, MUTEX_BOOST_CPU); + } + } else { + if (fgRequested == ENUM_CPU_BOOST_STATUS_START) { + pr_info("kalBoostCpu stop (%d<%d)\n", + u4TarPerfLevel, u4BoostCpuTh); + fgRequested = ENUM_CPU_BOOST_STATUS_STOP; + + set_task_util_min_pct(prGlueInfo->u4TxThreadPid, 0); + set_task_util_min_pct(prGlueInfo->u4RxThreadPid, 0); + set_task_util_min_pct(prGlueInfo->u4HifThreadPid, 0); + kalSetRpsMap(prGlueInfo, 0x0f); /* small cores */ + update_userlimit_cpu_freq(CPU_KIR_WIFI, + u4ClusterNum, freq_to_set); + + KAL_ACQUIRE_MUTEX(prAdapter, MUTEX_BOOST_CPU); + pr_info("Max Dram Freq end\n"); + pm_qos_update_request(&wifi_qos_request, DDR_OPP_UNREQ); + pm_qos_remove_request(&wifi_qos_request); + KAL_RELEASE_MUTEX(prAdapter, MUTEX_BOOST_CPU); + } + } + kalTraceInt(fgRequested == ENUM_CPU_BOOST_STATUS_START, "kalBoostCpu"); + + return 0; +} +#endif + +#ifdef CONFIG_MTK_EMI +void kalSetEmiMpuProtection(phys_addr_t emiPhyBase, bool enable) +{ +} + +void kalSetDrvEmiMpuProtection(phys_addr_t emiPhyBase, uint32_t offset, + uint32_t size) +{ + struct emimpu_region_t region; + unsigned long long start = emiPhyBase + offset; + unsigned long long end = emiPhyBase + offset + size - 1; + int ret; + + DBGLOG(INIT, INFO, "emiPhyBase: 0x%p, offset: %d, size: %d\n", + emiPhyBase, offset, size); + + ret = mtk_emimpu_init_region(®ion, 18); + if (ret) { + DBGLOG(INIT, ERROR, "mtk_emimpu_init_region failed, ret: %d\n", + ret); + return; + } + mtk_emimpu_set_addr(®ion, start, end); + mtk_emimpu_set_apc(®ion, DOMAIN_AP, MTK_EMIMPU_NO_PROTECTION); + mtk_emimpu_set_apc(®ion, DOMAIN_CONN, MTK_EMIMPU_NO_PROTECTION); + mtk_emimpu_lock_region(®ion, MTK_EMIMPU_LOCK); + ret = mtk_emimpu_set_protection(®ion); + if (ret) + DBGLOG(INIT, ERROR, + "mtk_emimpu_set_protection failed, ret: %d\n", + ret); + mtk_emimpu_free_region(®ion); +} +#endif + +int32_t kalGetFwFlavor(uint8_t *flavor) +{ + *flavor = 'b'; + return 1; +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/plat/mt6885/plat_priv.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/plat/mt6885/plat_priv.c new file mode 100644 index 0000000000000000000000000000000000000000..82d880db7926c915b525a9b19582db8379d8018d --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/plat/mt6885/plat_priv.c @@ -0,0 +1,178 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include +#include + +#include +#include + +#include "precomp.h" + +#ifdef CFG_MTK_ANDROID_EMI +#include +#include +#define REGION_WIFI 26 +#define WIFI_EMI_MEM_SIZE 0x140000 +#define WIFI_EMI_MEM_OFFSET 0x2B0000 +#define DOMAIN_AP 0 +#define DOMAIN_CONN 2 +#endif + + +#define MAX_CPU_FREQ (3 * 1024 * 1024) /* in kHZ */ +#define MAX_CLUSTER_NUM 3 +#define CPU_BIG_CORE (0xf0) +#define CPU_SMALL_CORE (0xff - CPU_BIG_CORE) + +#define CONNSYS_VERSION_ID 0x20010000 + +enum ENUM_CPU_BOOST_STATUS { + ENUM_CPU_BOOST_STATUS_INIT = 0, + ENUM_CPU_BOOST_STATUS_START, + ENUM_CPU_BOOST_STATUS_STOP, + ENUM_CPU_BOOST_STATUS_NUM +}; + +uint32_t kalGetCpuBoostThreshold(void) +{ + DBGLOG(SW4, TRACE, "enter kalGetCpuBoostThreshold\n"); + /* 5, stands for 250Mbps */ + return 5; +} + +int32_t kalCheckTputLoad(IN struct ADAPTER *prAdapter, + IN uint32_t u4CurrPerfLevel, + IN uint32_t u4TarPerfLevel, + IN int32_t i4Pending, + IN uint32_t u4Used) +{ + uint32_t pendingTh = + CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD * + prAdapter->rWifiVar.u4PerfMonPendingTh / 100; + uint32_t usedTh = (HIF_TX_MSDU_TOKEN_NUM / 2) * + prAdapter->rWifiVar.u4PerfMonUsedTh / 100; + return u4TarPerfLevel >= 3 && + u4TarPerfLevel < prAdapter->rWifiVar.u4BoostCpuTh && + i4Pending >= pendingTh && + u4Used >= usedTh ? + TRUE : FALSE; +} + +int32_t kalBoostCpu(IN struct ADAPTER *prAdapter, + IN uint32_t u4TarPerfLevel, + IN uint32_t u4BoostCpuTh) +{ + struct GLUE_INFO *prGlueInfo = NULL; + struct ppm_limit_data freq_to_set[MAX_CLUSTER_NUM]; + int32_t i = 0, i4Freq = -1; + + static struct pm_qos_request wifi_qos_request; + static u_int8_t fgRequested = ENUM_CPU_BOOST_STATUS_INIT; + + uint32_t u4ClusterNum = topo_ctrl_get_nr_clusters(); + + prGlueInfo = (struct GLUE_INFO *)wiphy_priv(wlanGetWiphy()); + ASSERT(u4ClusterNum <= MAX_CLUSTER_NUM); + /* ACAO, we dont have to set core number */ + i4Freq = (u4TarPerfLevel >= u4BoostCpuTh) ? MAX_CPU_FREQ : -1; + for (i = 0; i < u4ClusterNum; i++) { + freq_to_set[i].min = i4Freq; + freq_to_set[i].max = i4Freq; + } + + if (fgRequested == ENUM_CPU_BOOST_STATUS_INIT) { + /* initially enable rps working at small cores */ + kalSetRpsMap(prGlueInfo, CPU_SMALL_CORE); + fgRequested = ENUM_CPU_BOOST_STATUS_STOP; + } + + if (u4TarPerfLevel >= u4BoostCpuTh) { + if (fgRequested == ENUM_CPU_BOOST_STATUS_STOP) { + pr_info("kalBoostCpu start (%d>=%d)\n", + u4TarPerfLevel, u4BoostCpuTh); + fgRequested = ENUM_CPU_BOOST_STATUS_START; + + set_task_util_min_pct(prGlueInfo->u4TxThreadPid, 100); + set_task_util_min_pct(prGlueInfo->u4RxThreadPid, 100); + set_task_util_min_pct(prGlueInfo->u4HifThreadPid, 100); + kalSetRpsMap(prGlueInfo, CPU_BIG_CORE); + update_userlimit_cpu_freq(CPU_KIR_WIFI, + u4ClusterNum, freq_to_set); + + KAL_ACQUIRE_MUTEX(prAdapter, MUTEX_BOOST_CPU); + pr_info("Max Dram Freq start\n"); + pm_qos_add_request(&wifi_qos_request, + PM_QOS_DDR_OPP, + DDR_OPP_0); + pm_qos_update_request(&wifi_qos_request, DDR_OPP_0); + KAL_RELEASE_MUTEX(prAdapter, MUTEX_BOOST_CPU); + } + } else { + if (fgRequested == ENUM_CPU_BOOST_STATUS_START) { + pr_info("kalBoostCpu stop (%d<%d)\n", + u4TarPerfLevel, u4BoostCpuTh); + fgRequested = ENUM_CPU_BOOST_STATUS_STOP; + + set_task_util_min_pct(prGlueInfo->u4TxThreadPid, 0); + set_task_util_min_pct(prGlueInfo->u4RxThreadPid, 0); + set_task_util_min_pct(prGlueInfo->u4HifThreadPid, 0); + kalSetRpsMap(prGlueInfo, CPU_SMALL_CORE); + update_userlimit_cpu_freq(CPU_KIR_WIFI, + u4ClusterNum, freq_to_set); + + KAL_ACQUIRE_MUTEX(prAdapter, MUTEX_BOOST_CPU); + pr_info("Max Dram Freq end\n"); + pm_qos_update_request(&wifi_qos_request, DDR_OPP_UNREQ); + pm_qos_remove_request(&wifi_qos_request); + KAL_RELEASE_MUTEX(prAdapter, MUTEX_BOOST_CPU); + } + } + kalTraceInt(fgRequested == ENUM_CPU_BOOST_STATUS_START, "kalBoostCpu"); + + return 0; +} + +#ifdef CFG_MTK_ANDROID_EMI +void kalSetEmiMpuProtection(phys_addr_t emiPhyBase, bool enable) +{ +} + +void kalSetDrvEmiMpuProtection(phys_addr_t emiPhyBase, uint32_t offset, + uint32_t size) +{ + struct emimpu_region_t region; + unsigned long long start = emiPhyBase + offset; + unsigned long long end = emiPhyBase + offset + size - 1; + int ret; + + DBGLOG(INIT, INFO, "emiPhyBase: 0x%p, offset: %d, size: %d\n", + emiPhyBase, offset, size); + + ret = mtk_emimpu_init_region(®ion, 18); + if (ret) { + DBGLOG(INIT, ERROR, "mtk_emimpu_init_region failed, ret: %d\n", + ret); + return; + } + mtk_emimpu_set_addr(®ion, start, end); + mtk_emimpu_set_apc(®ion, DOMAIN_AP, MTK_EMIMPU_NO_PROTECTION); + mtk_emimpu_set_apc(®ion, DOMAIN_CONN, MTK_EMIMPU_NO_PROTECTION); + mtk_emimpu_lock_region(®ion, MTK_EMIMPU_LOCK); + ret = mtk_emimpu_set_protection(®ion); + if (ret) + DBGLOG(INIT, ERROR, + "mtk_emimpu_set_protection failed, ret: %d\n", + ret); + mtk_emimpu_free_region(®ion); +} + +#endif + +int32_t kalGetConnsysVerId(void) +{ + return CONNSYS_VERSION_ID; +} + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/platform.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/platform.c new file mode 100644 index 0000000000000000000000000000000000000000..76396a347ffb1b6f35c97e1dd689018246a1418b --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/linux/platform.c @@ -0,0 +1,679 @@ +/******************************************************************************* + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux + * /platform.c#3 + */ + +/*! \file "platform.c" + * \brief This file including the protocol layer privacy function. + * + * This file provided the macros and functions library support for the + * protocol layer security setting from wlan_oid.c and for parse.c and + * rsn.c and nic_privacy.c + * + */ + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include +#include +#include +#include +#include + +#include +#include "precomp.h" +#include "gl_os.h" + +#if CFG_ENABLE_EARLY_SUSPEND +#include +#endif + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#define WIFI_NVRAM_FILE_NAME "/data/nvram/APCFG/APRDEB/WIFI" +#define WIFI_NVRAM_CUSTOM_NAME "/data/nvram/APCFG/APRDEB/WIFI_CUSTOM" + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ +static const uint8_t *apucDebugNetdevState[] = { + (uint8_t *) DISP_STRING("NETDEV_UNKNOWN"), + (uint8_t *) DISP_STRING("NETDEV_UP"), + (uint8_t *) DISP_STRING("NETDEV_DOWN"), + (uint8_t *) DISP_STRING("NETDEV_REBOOT"), + (uint8_t *) DISP_STRING("NETDEV_CHANGE"), + (uint8_t *) DISP_STRING("NETDEV_REGISTER"), + (uint8_t *) DISP_STRING("NETDEV_UNREGISTER"), + (uint8_t *) DISP_STRING("NETDEV_CHANGEMTU"), + (uint8_t *) DISP_STRING("NETDEV_CHANGEADDR"), + (uint8_t *) DISP_STRING("NETDEV_GOING_DOWN"), + (uint8_t *) DISP_STRING("NETDEV_CHANGENAME"), + (uint8_t *) DISP_STRING("NETDEV_FEAT_CHANGE"), + (uint8_t *) DISP_STRING("NETDEV_BONDING_FAILOVER"), + (uint8_t *) DISP_STRING("NETDEV_PRE_UP"), + (uint8_t *) DISP_STRING("NETDEV_PRE_TYPE_CHANGE"), + (uint8_t *) DISP_STRING("NETDEV_POST_TYPE_CHANGE"), + (uint8_t *) DISP_STRING("NETDEV_POST_INIT"), + (uint8_t *) DISP_STRING("NETDEV_UNREGISTER_FINAL"), + (uint8_t *) DISP_STRING("NETDEV_RELEASE"), + (uint8_t *) DISP_STRING("NETDEV_NOTIFY_PEERS"), + (uint8_t *) DISP_STRING("NETDEV_JOIN"), + (uint8_t *) DISP_STRING("NETDEV_CHANGEUPPER"), + (uint8_t *) DISP_STRING("NETDEV_RESEND_IGMP"), + (uint8_t *) DISP_STRING("NETDEV_PRECHANGEMTU"), + (uint8_t *) DISP_STRING("NETDEV_CHANGEINFODATA"), + (uint8_t *) DISP_STRING("NETDEV_BONDING_INFO"), + (uint8_t *) DISP_STRING("NETDEV_PRECHANGEUPPER"), + (uint8_t *) DISP_STRING("NETDEV_CHANGELOWERSTATE"), + (uint8_t *) DISP_STRING("NETDEV_UDP_TUNNEL_PUSH_INFO"), + (uint8_t *) DISP_STRING("NETDEV_UNKNOWN"), + (uint8_t *) DISP_STRING("NETDEV_CHANGE_TX_QUEUE_LEN"), +}; + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +static int wlan_netdev_notifier_call(struct notifier_block *nb, + unsigned long state, void *ndev); + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +#if 1 +static int netdev_event(struct notifier_block *nb, + unsigned long notification, void *ptr) +{ + struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; + struct net_device *prDev = ifa->ifa_dev->dev; + struct GLUE_INFO *prGlueInfo = NULL; + + if (prDev == NULL) { + /* DBGLOG(REQ, INFO, ("netdev_event: device is empty.\n")); */ + return NOTIFY_DONE; + } + + if ((strncmp(prDev->name, "p2p", 3) != 0) + && (strncmp(prDev->name, "wlan", 4) != 0)) { + /* DBGLOG(REQ, INFO, ("netdev_event: xxx\n")); */ + return NOTIFY_DONE; + } +#if 0 /* CFG_SUPPORT_PASSPOINT */ + { + /* printk(KERN_INFO + * "[netdev_event] IPV4_DAD is unlock now!!\n"); + */ + prGlueInfo->fgIsDad = FALSE; + } +#endif /* CFG_SUPPORT_PASSPOINT */ + + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prDev)); + if (prGlueInfo == NULL) { + DBGLOG(REQ, INFO, "netdev_event: prGlueInfo is empty.\n"); + return NOTIFY_DONE; + } + + if (prGlueInfo->fgIsInSuspendMode == FALSE) { + /* DBGLOG(REQ, INFO, + * ("netdev_event: MEDIA_STATE_DISCONNECTED. (%d)\n", + * prGlueInfo->eParamMediaStateIndicated)); + */ + return NOTIFY_DONE; + } + + kalSetNetAddressFromInterface(prGlueInfo, prDev, TRUE); + + return NOTIFY_DONE; + +} +#endif +#if 0 /* CFG_SUPPORT_PASSPOINT */ +static int net6dev_event(struct notifier_block *nb, + unsigned long notification, void *ptr) +{ + struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr; + struct net_device *prDev = ifa->idev->dev; + struct GLUE_INFO *prGlueInfo = NULL; + + if (prDev == NULL) { + DBGLOG(REQ, INFO, "net6dev_event: device is empty.\n"); + return NOTIFY_DONE; + } + + if ((strncmp(prDev->name, "p2p", 3) != 0) + && (strncmp(prDev->name, "wlan", 4) != 0)) { + DBGLOG(REQ, INFO, "net6dev_event: xxx\n"); + return NOTIFY_DONE; + } + + if (strncmp(prDev->name, "p2p", 3) == 0) { + /* because we store the address of prGlueInfo in p2p's private + * date of net device + */ + /* *((P_GLUE_INFO_T *) netdev_priv( + * prGlueInfo->prP2PInfo[0]->prDevHandler)) = prGlueInfo; + */ + prGlueInfo = *((struct GLUE_INFO **) netdev_priv(prDev)); + } else { /* wlan0 */ + prGlueInfo = (struct GLUE_INFO *) netdev_priv(prDev); + } + + if (prGlueInfo == NULL) { + DBGLOG(REQ, INFO, "netdev_event: prGlueInfo is empty.\n"); + return NOTIFY_DONE; + } + /* printk(KERN_INFO "[net6dev_event] IPV6_DAD is unlock now!!\n"); */ + prGlueInfo->fgIs6Dad = FALSE; + + return NOTIFY_DONE; +} +#endif /* CFG_SUPPORT_PASSPOINT */ + +#if 1 /* unused */ +static struct notifier_block inetaddr_notifier = { + .notifier_call = netdev_event, +}; +#endif + +#if 0 /* CFG_SUPPORT_PASSPOINT */ +static struct notifier_block inet6addr_notifier = { + .notifier_call = net6dev_event, +}; +#endif /* CFG_SUPPORT_PASSPOINT */ + +void wlanRegisterInetAddrNotifier(void) +{ +#if CFG_ENABLE_NET_DEV_NOTIFY + + register_inetaddr_notifier(&inetaddr_notifier); +#if 0 /* CFG_SUPPORT_PASSPOINT */ + register_inet6addr_notifier(&inet6addr_notifier); +#endif /* CFG_SUPPORT_PASSPOINT */ + +#endif +} + +void wlanUnregisterInetAddrNotifier(void) +{ +#if CFG_ENABLE_NET_DEV_NOTIFY + + unregister_inetaddr_notifier(&inetaddr_notifier); +#if 0 /* CFG_SUPPORT_PASSPOINT */ + unregister_inetaddr_notifier(&inet6addr_notifier); +#endif /* CFG_SUPPORT_PASSPOINT */ + +#endif +} + +#if CFG_ENABLE_EARLY_SUSPEND +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function will register platform driver to os + * + * \param[in] wlanSuspend Function pointer to platform suspend function + * \param[in] wlanResume Function pointer to platform resume function + * + * \return The result of registering earlysuspend + */ +/*----------------------------------------------------------------------------*/ + +int glRegisterEarlySuspend(struct early_suspend *prDesc, + early_suspend_callback wlanSuspend, + late_resume_callback wlanResume) +{ + int ret = 0; + + if (wlanSuspend != NULL) + prDesc->suspend = wlanSuspend; + else { + DBGLOG(REQ, INFO, + "glRegisterEarlySuspend wlanSuspend ERROR.\n"); + ret = -1; + } + + if (wlanResume != NULL) + prDesc->resume = wlanResume; + else { + DBGLOG(REQ, INFO, + "glRegisterEarlySuspend wlanResume ERROR.\n"); + ret = -1; + } + + register_early_suspend(prDesc); + return ret; +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function will un-register platform driver to os + * + * \return The result of un-registering earlysuspend + */ +/*----------------------------------------------------------------------------*/ + +int glUnregisterEarlySuspend(struct early_suspend *prDesc) +{ + int ret = 0; + + unregister_early_suspend(prDesc); + + prDesc->suspend = NULL; + prDesc->resume = NULL; + + return ret; +} +#endif + +#if 0 +/*----------------------------------------------------------------------------*/ +/*! + * \brief Utility function for reading data from files on NVRAM-FS + * + * \param[in] + * filename + * len + * offset + * \param[out] + * buf + * \return + * actual length of data being read + */ +/*----------------------------------------------------------------------------*/ +static int nvram_read(char *filename, char *buf, + ssize_t len, int offset) +{ +#if CFG_SUPPORT_NVRAM + struct file *fd; + int retLen = -1; +#if KERNEL_VERSION(4, 4, 0) <= LINUX_VERSION_CODE + loff_t pos; + char __user *p; +#endif + + mm_segment_t old_fs = get_fs(); + + set_fs(KERNEL_DS); + + fd = filp_open(filename, O_RDONLY, 0644); + + if (IS_ERR(fd)) { + DBGLOG(INIT, INFO, "[nvram_read] : failed to open!!\n"); + set_fs(old_fs); + return -1; + } + + do { + if (fd->f_op == NULL) { + DBGLOG(INIT, INFO, "[nvram_read] : f_op is NULL!!\n"); + break; + } + + if (fd->f_pos != offset) { + if (fd->f_op->llseek) { + if (fd->f_op->llseek(fd, offset, 0) != offset) { + DBGLOG(INIT, INFO, + "[nvram_read] : failed to seek!!\n"); + break; + } + } else { + fd->f_pos = offset; + } + } + +#if KERNEL_VERSION(4, 4, 0) <= LINUX_VERSION_CODE + p = (__force char __user *)buf; + pos = (loff_t)offset; + + retLen = __vfs_read(fd, p, len, &pos); +#else + retLen = fd->f_op->read(fd, buf, len, &fd->f_pos); +#endif + if (retLen < 0) + DBGLOG(INIT, ERROR, + "[nvram_read] : read failed!! Error code: %d\n", + retLen); + } while (FALSE); + + filp_close(fd, NULL); + + set_fs(old_fs); + + return retLen; + +#else /* !CFG_SUPPORT_NVRAM */ + + return -EIO; + +#endif +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Utility function for writing data to files on NVRAM-FS + * + * \param[in] + * filename + * buf + * len + * offset + * \return + * actual length of data being written + */ +/*----------------------------------------------------------------------------*/ +static int nvram_write(char *filename, char *buf, + ssize_t len, int offset) +{ +#if CFG_SUPPORT_NVRAM + struct file *fd; + int retLen = -1; +#if KERNEL_VERSION(4, 4, 0) <= LINUX_VERSION_CODE + loff_t pos; + char __user *p; +#endif + + mm_segment_t old_fs = get_fs(); + + set_fs(KERNEL_DS); + + fd = filp_open(filename, O_WRONLY | O_CREAT, 0644); + + if (IS_ERR(fd)) { + DBGLOG(INIT, INFO, "[nvram_write] : failed to open!!\n"); + set_fs(old_fs); + return -1; + } + + do { + if (fd->f_op == NULL) { + DBGLOG(INIT, INFO, "[nvram_write] : f_op is NULL!!\n"); + break; + } + /* End of if */ + if (fd->f_pos != offset) { + if (fd->f_op->llseek) { + if (fd->f_op->llseek(fd, offset, 0) != offset) { + DBGLOG(INIT, INFO, + "[nvram_write] : failed to seek!!\n"); + break; + } + } else { + fd->f_pos = offset; + } + } + +#if KERNEL_VERSION(4, 4, 0) <= LINUX_VERSION_CODE + p = (__force char __user *)buf; + pos = (loff_t)offset; + + retLen = __vfs_write(fd, p, len, &pos); +#else + retLen = fd->f_op->write(fd, buf, len, &fd->f_pos); +#endif + if (retLen < 0) + DBGLOG(INIT, ERROR, + "[nvram_write] : write failed!! Error code: %d\n", + retLen); + } while (FALSE); + + filp_close(fd, NULL); + + set_fs(old_fs); + + return retLen; + +#else /* !CFG_SUPPORT_NVRAMS */ + + return -EIO; + +#endif +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief API for reading data on NVRAM with flexible length. + * + * \param[in] + * prGlueInfo + * u4Offset + * len + * \param[out] + * pu2Data + * \return + * TRUE + * FALSE + */ +/*----------------------------------------------------------------------------*/ +u_int8_t kalCfgDataRead(IN struct GLUE_INFO *prGlueInfo, + IN uint32_t u4Offset, + IN ssize_t len, OUT uint16_t *pu2Data) +{ + if (pu2Data == NULL) + return FALSE; + + if (u4Offset + len > MAX_CFG_FILE_WIFI_REC_SIZE) + return FALSE; + + kalMemCopy(pu2Data, &g_aucNvram[u4Offset], len); + return TRUE; +#if 0 + if (nvram_read(WIFI_NVRAM_FILE_NAME, + (char *)pu2Data, len, u4Offset) != len) { + return FALSE; + } else { + return TRUE; + } +#endif +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief API for reading data on NVRAM with 2 bytes fixed length. + * + * \param[in] + * prGlueInfo + * u4Offset + * \param[out] + * pu2Data + * \return + * TRUE + * FALSE + */ +/*----------------------------------------------------------------------------*/ +u_int8_t kalCfgDataRead16(IN struct GLUE_INFO *prGlueInfo, + IN uint32_t u4Offset, OUT uint16_t *pu2Data) +{ + if (pu2Data == NULL) + return FALSE; + + if (u4Offset + sizeof(unsigned short) > MAX_CFG_FILE_WIFI_REC_SIZE) + return FALSE; + + kalMemCopy(pu2Data, &g_aucNvram[u4Offset], + sizeof(unsigned short)); + return TRUE; +#if 0 + if (nvram_read(WIFI_NVRAM_FILE_NAME, + (char *)pu2Data, sizeof(unsigned short), + u4Offset) != sizeof(unsigned short)) { + return FALSE; + } else { + return TRUE; + } +#endif +} + +/*----------------------------------------------------------------------------*/ +/*! + * \brief API for writing data on NVRAM with 2 bytes fixed length. + * + * \param[in] + * prGlueInfo + * u4Offset + * u2Data + * \return + * TRUE + * FALSE + */ +/*----------------------------------------------------------------------------*/ +u_int8_t kalCfgDataWrite16(IN struct GLUE_INFO *prGlueInfo, + uint32_t u4Offset, uint16_t u2Data) +{ + if (u4Offset + sizeof(unsigned short) > MAX_CFG_FILE_WIFI_REC_SIZE) + return FALSE; + + kalMemCopy(&g_aucNvram[u4Offset], &u2Data, + sizeof(unsigned short)); + return TRUE; +#if 0 + if (nvram_write(WIFI_NVRAM_FILE_NAME, + (char *)&u2Data, sizeof(unsigned short), + u4Offset) != sizeof(unsigned short)) { + return FALSE; + } else { + return TRUE; + } +#endif +} +/*----------------------------------------------------------------------------*/ +/*! + * \brief API for writing data on NVRAM with 1 bytes fixed length. + * + * \param[in] + * prGlueInfo + * u4Offset + * u1Data + * \return + * TRUE + * FALSE + */ +/*----------------------------------------------------------------------------*/ + +u_int8_t kalCfgDataWrite8(IN struct GLUE_INFO *prGlueInfo, + IN uint32_t u4Offset, IN uint8_t u1Data) +{ + if (u4Offset + sizeof(unsigned char) > MAX_CFG_FILE_WIFI_REC_SIZE) + return FALSE; + + kalMemCopy(&g_aucNvram[u4Offset], &u1Data, + sizeof(unsigned char)); + return TRUE; + +} + +static int wlan_netdev_notifier_call(struct notifier_block *nb, + unsigned long state, void *ndev) +{ +#if KERNEL_VERSION(3, 11, 0) <= CFG80211_VERSION_CODE + struct netdev_notifier_info *dev_notif_info = ndev; + struct net_device *dev = dev_notif_info != NULL ? + dev_notif_info->dev : NULL; +#else + struct net_device *dev = ndev; +#endif + + if (!dev) + return NOTIFY_DONE; + + if ((strncmp(dev->name, "wlan", 4) != 0) && + (strncmp(dev->name, "p2p", 3) != 0) && + (strncmp(dev->name, "ap", 2) != 0)) { + return NOTIFY_DONE; + } + + DBGLOG(REQ, TRACE, "%s's new state: %lu %s.\n", + dev->name, state, apucDebugNetdevState[state]); + + return NOTIFY_DONE; +} + +static struct notifier_block wlan_netdev_notifier = { + .notifier_call = wlan_netdev_notifier_call, +}; + +void wlanRegisterNetdevNotifier(void) +{ + register_netdevice_notifier(&wlan_netdev_notifier); +} + +void wlanUnregisterNetdevNotifier(void) +{ + unregister_netdevice_notifier(&wlan_netdev_notifier); +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/gl_ate_agent.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/gl_ate_agent.c new file mode 100644 index 0000000000000000000000000000000000000000..1457db39482f090fb453aef9486104849a4d2caf --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/gl_ate_agent.c @@ -0,0 +1,118 @@ +/**************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ***************************************************************************/ +/**************************************************************************** + *[File] gl_ate_agent.c + *[Version] v1.0 + *[Revision Date] 2019/01/01 + *[Author] + *[Description] + * DUT API implementation for test tool + *[Copyright] + * Copyright (C) 2010 MediaTek Incorporation. All Rights Reserved. + ****************************************************************************/ + + +/***************************************************************************** + * C O M P I L E R F L A G S + ***************************************************************************** + */ + +/***************************************************************************** + * E X T E R N A L R E F E R E N C E S + ***************************************************************************** + */ + +#include "gl_os.h" + +#include "precomp.h" + +/***************************************************************************** + * C O N S T A N T S + ***************************************************************************** + */ + +/***************************************************************************** + * D A T A T Y P E S + ***************************************************************************** + */ + +/***************************************************************************** + * P U B L I C D A T A + ***************************************************************************** + */ +/* export to other common part file */ +#if CFG_SUPPORT_TX_BF +union PFMU_PROFILE_TAG1 g_rPfmuTag1; +union PFMU_PROFILE_TAG2 g_rPfmuTag2; +union PFMU_DATA g_rPfmuData; +#endif +/***************************************************************************** + * P R I V A T E D A T A + ***************************************************************************** + */ + + +/***************************************************************************** + * M A C R O S + ***************************************************************************** + */ + +/***************************************************************************** + * F U N C T I O N D E C L A R A T I O N S + ***************************************************************************** + */ + + +/***************************************************************************** + * F U N C T I O N S + ***************************************************************************** + */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/gl_dependent.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/gl_dependent.c new file mode 100644 index 0000000000000000000000000000000000000000..d2e73892d73227f29be72fc76f22c97021054c14 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/gl_dependent.c @@ -0,0 +1,369 @@ +/**************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ***************************************************************************/ +/**************************************************************************** + *[File] gl_dependency.c + *[Version] v1.0 + *[Revision Date] 2019/01/01 + *[Author] + *[Description] + * The implementation for os-related API provided to common part. + * mainly Linux related code block in common part + *[Copyright] + * Copyright (C) 2010 MediaTek Incorporation. All Rights Reserved. + ****************************************************************************/ + + +/***************************************************************************** + * C O M P I L E R F L A G S + ***************************************************************************** + */ + +/***************************************************************************** + * E X T E R N A L R E F E R E N C E S + ***************************************************************************** + */ + +#include "gl_os.h" + +#include "precomp.h" + +#include "stdio.h" +/***************************************************************************** + * C O N S T A N T S + ***************************************************************************** + */ + +/***************************************************************************** + * D A T A T Y P E S + ***************************************************************************** + */ + +/***************************************************************************** + * P U B L I C D A T A + ***************************************************************************** + */ + +/***************************************************************************** + * P R I V A T E D A T A + ***************************************************************************** + */ + + +/***************************************************************************** + * M A C R O S + ***************************************************************************** + */ + +/***************************************************************************** + * F U N C T I O N D E C L A R A T I O N S + ***************************************************************************** + */ + + +/***************************************************************************** + * F U N C T I O N S + ***************************************************************************** + */ +long KAL_NEED_IMPLEMENT(const char *f, const char *func, int line, ...) +{ + /* please refer to the implementation on other os. eg. Linux */ + DBGLOG(INIT, ERROR, "%s not supported here, %s@%d\n", + func, f, line); + return 0; +} + +int test(struct net_device *a) +{ + return 0; +} +/* + * for GCC to build under user space, please remove/keep it + * dependent to the OS + */ +int main(int argc, char *argv[]) +{ + wlanSetDriverDbgLevel(DBG_ALL_MODULE_IDX, + DBG_LOG_LEVEL_DEFAULT); + DBGLOG(INIT, ERROR, "test run\n"); + return 0; +} +#if 0 +int kal_dbg_print(const char *s, ...) +{ + printf((s), ...); + return 0; +} +#endif +int kal_hex_dump_to_buffer(const void *buf, size_t len, int rowsize, + int groupsize, char *linebuf, size_t linebuflen, bool ascii) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); + return 0; +} + +void kal_warn_on(uint8_t condition) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); +} + +void kal_do_gettimeofday(struct timeval *tv) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); +} + +void kal_get_monotonic_boottime(struct timespec *ts) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); +} + +int kal_mod_timer(struct timer_list *timer, unsigned long expires) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); + return 0; +} + +int kal_strtoint(const char *s, unsigned int base, int *res) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); + return 0; +} + +int kal_strtou8(const char *s, unsigned int base, uint8_t *res) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); + return 0; +} + +int kal_strtou16(const char *s, unsigned int base, uint16_t *res) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); + return 0; +} + +int kal_strtou32(const char *s, unsigned int base, uint32_t *res) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); + return 0; +} + +int kal_strtos32(const char *s, unsigned int base, int32_t *res) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); + return 0; +} + +int kal_strtoul(const char *s, unsigned int base, unsigned long *res) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); + return 0; +} + +int kal_scnprintf(char *buf, size_t size, const char *fmt, ...) +{ + va_list args; + int i = 0; + + va_start(args, fmt); + /* i = vscnprintf(buf, size, fmt, args); */ + va_end(args); + + return i; +} + +void *kal_kmalloc(size_t size, enum gfp_t type) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); + return NULL; +} + +void *kal_vmalloc(size_t size) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); + return NULL; +} + +void kal_kfree(void *addr) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); +} + +void kal_vfree(void *addr) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); +} + +void kal_spin_lock_bh(spinlock_t *lock) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); +} + +void kal_spin_unlock_bh(spinlock_t *lock) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); +} + +void kal_spin_lock_irqsave(spinlock_t *lock, unsigned long flags) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); +} + +void kal_spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); +} + +uint32_t kal_skb_queue_len(const struct sk_buff_head *list) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); + return list->qlen; +} + +void kal_skb_queue_tail(struct sk_buff_head *list, struct sk_buff *newsk) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); +} + +void *kal_skb_push(struct sk_buff *skb, unsigned int len) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); + return NULL; +} + +unsigned char *kal_skb_put(struct sk_buff *skb, unsigned int len) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); + return NULL; +} + +struct sk_buff *kal_skb_dequeue_tail(struct sk_buff_head *list) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); + return NULL; +} + +void kal_skb_queue_head(struct sk_buff_head *list, struct sk_buff *newsk) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); +} + +void kal_skb_reset_tail_pointer(struct sk_buff *skb) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); +} + +void kal_skb_trim(struct sk_buff *skb, unsigned int len) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); +} + +struct sk_buff *kal_dev_alloc_skb(unsigned int length) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); + return NULL; +} + +void kal_kfree_skb(struct sk_buff *skb) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); +} + +int kal_test_and_clear_bit(unsigned long bit, unsigned long *p) +{ + unsigned int res; + unsigned long mask = 1UL << (bit & 31); + + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); + p += bit >> 5; + /* TODO: disable interrupt */ + res = *p; + *p = res & ~mask; + /* TODO: restore interrupt */ + + return (res & mask) != 0; +} + +void kal_clear_bit(unsigned long bit, unsigned long *p) +{ + unsigned long mask = 1UL << (bit & 31); + + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); + p += bit >> 5; + /* TODO: disable interrupt */ + *p &= ~mask; + /* TOD: restore interrupt */ +} + +void kal_set_bit(unsigned long nr, unsigned long *addr) +{ + unsigned long mask = BIT(nr % 32); + unsigned long *p = ((unsigned long *)addr) + (nr / 32); + + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); + /* TODO: disable interrupt */ + *p |= mask; + /* TODO: restore interrupt */ +} + +int kal_test_bit(unsigned long nr, unsigned long *addr) +{ + unsigned long mask = BIT(nr % 32); + unsigned long *p = ((unsigned long *)addr) + (nr / 32); + int res = 0; + + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); + /* TODO: disable interrupt */ + + res = mask & *p; + /* TODO: restore interrupt */ + + return res; +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/gl_init.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/gl_init.c new file mode 100644 index 0000000000000000000000000000000000000000..e5fe37d6b652e4011cb711897477e9531df11cc5 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/gl_init.c @@ -0,0 +1,125 @@ +/**************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ***************************************************************************/ +/**************************************************************************** + *[File] gl_init.c + *[Version] v1.0 + *[Revision Date] 2019/01/01 + *[Author] + *[Description] + * DUT initialization API implementation for os related logic. + *[Copyright] + * Copyright (C) 2010 MediaTek Incorporation. All Rights Reserved. + ****************************************************************************/ + + +/***************************************************************************** + * C O M P I L E R F L A G S + ***************************************************************************** + */ + +/***************************************************************************** + * E X T E R N A L R E F E R E N C E S + ***************************************************************************** + */ + +#include "precomp.h" + +#include "gl_os.h" + +/***************************************************************************** + * C O N S T A N T S + ***************************************************************************** + */ + +struct wireless_dev *gprWdev[KAL_AIS_NUM]; + +/***************************************************************************** + * D A T A T Y P E S + ***************************************************************************** + */ + +/***************************************************************************** + * P U B L I C D A T A + ***************************************************************************** + */ + +/***************************************************************************** + * P R I V A T E D A T A + ***************************************************************************** + */ + + +/***************************************************************************** + * M A C R O S + ***************************************************************************** + */ + +/***************************************************************************** + * F U N C T I O N D E C L A R A T I O N S + ***************************************************************************** + */ + + +/***************************************************************************** + * F U N C T I O N S + ***************************************************************************** + */ +uint32_t wlanDownloadBufferBin(struct ADAPTER *prAdapter) +{ + return KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); +} + + +uint32_t wlanConnacDownloadBufferBin(struct ADAPTER *prAdapter) +{ + return KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/gl_kal.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/gl_kal.c new file mode 100644 index 0000000000000000000000000000000000000000..c0242b679c25a90b5cbafc0dad903015290aee3e --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/gl_kal.c @@ -0,0 +1,130 @@ +/**************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ***************************************************************************/ +/**************************************************************************** + *[File] gl_kal.c + *[Version] v1.0 + *[Revision Date] 2019/01/01 + *[Author] + *[Description] + * API implementation for os related logic. eg. threading, packet buf + *[Copyright] + * Copyright (C) 2010 MediaTek Incorporation. All Rights Reserved. + ****************************************************************************/ + + +/***************************************************************************** + * C O M P I L E R F L A G S + ***************************************************************************** + */ + +/***************************************************************************** + * E X T E R N A L R E F E R E N C E S + ***************************************************************************** + */ + +#include "gl_os.h" + +#include "precomp.h" + +/***************************************************************************** + * C O N S T A N T S + ***************************************************************************** + */ + +/***************************************************************************** + * D A T A T Y P E S + ***************************************************************************** + */ + +/***************************************************************************** + * P U B L I C D A T A + ***************************************************************************** + */ +/* + * debug level maintain in os-related part for(?) + * DBG_MODULE_NUM: include/debug.h + * ENUM_WIFI_LOG_MODULE_NUM: include/wlan_oid.h + * ENUM_WIFI_LOG_LEVEL_DEFAULT: include/wlan_oid.h + * + * access method in include/debug.h: + * extern uint8_t aucDebugModule[]; + * extern uint32_t au4LogLevel[]; + */ +uint8_t aucDebugModule[DBG_MODULE_NUM]; +uint32_t au4LogLevel[ENUM_WIFI_LOG_MODULE_NUM] = {ENUM_WIFI_LOG_LEVEL_DEFAULT}; +/***************************************************************************** + * P R I V A T E D A T A + ***************************************************************************** + */ + + +/***************************************************************************** + * M A C R O S + ***************************************************************************** + */ + +/***************************************************************************** + * F U N C T I O N D E C L A R A T I O N S + ***************************************************************************** + */ + + +/***************************************************************************** + * F U N C T I O N S + ***************************************************************************** + */ +#if CFG_CHIP_RESET_SUPPORT +void kalRemoveProbe(IN struct GLUE_INFO *prGlueInfo) +{ + DBGLOG(INIT, WARN, "[SER][L0] not support..\n"); +} +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/gl_qa_agent.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/gl_qa_agent.c new file mode 100644 index 0000000000000000000000000000000000000000..54a56bb295b6852325dad4352c4f43dba3d26064 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/gl_qa_agent.c @@ -0,0 +1,156 @@ +/**************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ***************************************************************************/ +/**************************************************************************** + *[File] gl_qa_agent.c + *[Version] v1.0 + *[Revision Date] 2019/01/01 + *[Author] + *[Description] + * DUT API implementation for test tool + *[Copyright] + * Copyright (C) 2010 MediaTek Incorporation. All Rights Reserved. + ****************************************************************************/ + + +/***************************************************************************** + * C O M P I L E R F L A G S + ***************************************************************************** + */ + +/***************************************************************************** + * E X T E R N A L R E F E R E N C E S + ***************************************************************************** + */ + +#include "gl_os.h" + +#include "precomp.h" + +/***************************************************************************** + * C O N S T A N T S + ***************************************************************************** + */ + +/***************************************************************************** + * D A T A T Y P E S + ***************************************************************************** + */ + +/***************************************************************************** + * P U B L I C D A T A + ***************************************************************************** + */ +/* export to other common part file */ +struct PARAM_RX_STAT g_HqaRxStat; +uint32_t u4RxStatSeqNum; +/***************************************************************************** + * P R I V A T E D A T A + ***************************************************************************** + */ + + +/***************************************************************************** + * M A C R O S + ***************************************************************************** + */ + +/***************************************************************************** + * F U N C T I O N D E C L A R A T I O N S + ***************************************************************************** + */ + + +/***************************************************************************** + * F U N C T I O N S + ***************************************************************************** + */ +int32_t connacSetICapStart(struct GLUE_INFO *prGlueInfo, + uint32_t u4Trigger, uint32_t u4RingCapEn, + uint32_t u4Event, uint32_t u4Node, uint32_t u4Len, + uint32_t u4StopCycle, + uint32_t u4BW, uint32_t u4MacTriggerEvent, + uint32_t u4SourceAddrLSB, + uint32_t u4SourceAddrMSB, uint32_t u4Band) +{ + return KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); +} + +int32_t connacGetICapStatus(struct GLUE_INFO *prGlueInfo) +{ + return KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); +} + +int32_t connacGetICapIQData(struct GLUE_INFO *prGlueInfo, + uint8_t *pData, uint32_t u4IQType, uint32_t u4WFNum) +{ + return KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); +} + +int32_t mt6632SetICapStart(struct GLUE_INFO *prGlueInfo, + uint32_t u4Trigger, uint32_t u4RingCapEn, + uint32_t u4Event, uint32_t u4Node, uint32_t u4Len, + uint32_t u4StopCycle, uint32_t u4BW, uint32_t u4MacTriggerEvent, + uint32_t u4SourceAddrLSB, uint32_t u4SourceAddrMSB, uint32_t u4Band) +{ + return KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); +} + +int32_t mt6632GetICapStatus(struct GLUE_INFO *prGlueInfo) +{ + return KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); +} + +int32_t commonGetICapIQData(struct GLUE_INFO *prGlueInfo, + uint8_t *pData, uint32_t u4IQType, uint32_t u4WFNum) +{ + return KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/hif/none/include/hif.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/hif/none/include/hif.h new file mode 100644 index 0000000000000000000000000000000000000000..b415dd9799198563660f3da47c7374933fc6e05d --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/hif/none/include/hif.h @@ -0,0 +1,264 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/*! \file "hif.h" + * \brief Functions for the driver to register bus and setup the IRQ + * + * Functions for the driver to register bus and setup the IRQ + */ + +#ifndef _HIF_H +#define _HIF_H + +#if defined(_HIF_NONE) +#define HIF_NAME "NONE" +#else +#error "No HIF defined!" +#endif + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +struct GL_HIF_INFO; + + +/* host interface's private data structure, which is attached to os glue + ** layer info structure. + */ +struct GL_HIF_INFO { +}; + +struct BUS_INFO { +}; + + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ +/* Common data type */ +#define HIF_NUM_OF_QM_RX_PKT_NUM 512 + +/* chip dependent? used in wlanHarvardFormatDownload */ +#define HIF_CR4_FWDL_SECTION_NUM 2 +#define HIF_IMG_DL_STATUS_PORT_IDX 0 + +/* enable/disable TX resource control */ +#define HIF_TX_RESOURCE_CTRL 1 + +/* enable/disable TX resource control PLE */ +#define HIF_TX_RESOURCE_CTRL_PLE 0 + +#define HIF_IST_LOOP_COUNT 128 + +/* Min msdu count to trigger Tx during INT polling state */ +#define HIF_IST_TX_THRESHOLD 32 + +#define HIF_TX_BUFF_COUNT_TC0 3 +#define HIF_TX_BUFF_COUNT_TC1 3 +#define HIF_TX_BUFF_COUNT_TC2 3 +#define HIF_TX_BUFF_COUNT_TC3 3 +#define HIF_TX_BUFF_COUNT_TC4 2 +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +/* kal internal use */ +#define glRegisterBus(_pfProbe, _pfRemove) + +#define glUnregisterBus(_pfRemove) + +#define glSetHifInfo(_prGlueInfo, _ulCookie) + +#define glClearHifInfo(_prGlueInfo) + +#define glBusInit(_pvData) + +#define glBusRelease(_pData) + +#define glBusSetIrq(_pvData, _pfnIsr, _pvCookie) + +#define glBusFreeIrq(_pvData, _pvCookie) + +#define glSetPowerState(_prGlueInfo, _ePowerMode) + +#define glGetDev(_prCtx, _ppDev) + +#define glGetHifDev(_prHif, _ppDev) + +#define HAL_WAKE_UP_WIFI(_prAdapter) + +#define halWpdmaInitRing(_glueinfo, __fgResetHif) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +uint8_t halTxRingDataSelect(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo); + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +/* for nic/hal.h */ +/* + * kal_virt_write_tx_port: Write frame to data port + * @ad: structure for adapter private data + * @pid: port id to write data, eg.NIC_TX_INIT_CMD_PORT + * @len: data len to write + * @buf: data buf pointer + * @buf_size: maximum size for data buffer, buf_size >= len + * + * not: implementation for different HIF may refer to nic/hal.h + */ +void kal_virt_write_tx_port(struct ADAPTER *ad, + uint16_t pid, uint32_t len, uint8_t *buf, uint32_t buf_size); + +/* + * kal_virt_get_wifi_func_stat: check HW status when check ready fail + * @ad: structure for adapter private data + * @res: status for return + * + * not: implementation for different HIF may refer to nic/hal.h + */ +void kal_virt_get_wifi_func_stat(struct ADAPTER *ad, uint32_t *res); + +/* + * kal_virt_chk_wifi_func_off: check HW status for function OFF + * @ad: structure for adapter private data + * @ready_bits: asserted bit if function is off correctly + * @res: status for return + * + * not: implementation for different HIF may refer to nic/hal.h + */ +void kal_virt_chk_wifi_func_off(struct ADAPTER *ad, uint32_t ready_bits, + uint8_t *res); + +/* + * kal_virt_chk_wifi_func_off: check HW status for function ready + * @ad: structure for adapter private data + * @ready_bits: asserted bit if function is ready + * @res: status for return + * + * not: implementation for different HIF may refer to nic/hal.h + */ +void kal_virt_chk_wifi_func_ready(struct ADAPTER *ad, uint32_t ready_bits, + uint8_t *res); + +/* + * kal_virt_set_mailbox_readclear: set read clear on hw mailbox (?) + * @ad: structure for adapter private data + * @enable: enable read clear or not + * + * not: implementation for different HIF may refer to nic/hal.h + */ +void kal_virt_set_mailbox_readclear(struct ADAPTER *ad, bool enable); + +/* + * kal_virt_set_int_stat_readclear: set hardware interrupt read clear + * @ad: structure for adapter private data + * + * not: no disable command + * not: implementation for different HIF may refer to nic/hal.h + */ +void kal_virt_set_int_stat_readclear(struct ADAPTER *ad); + +/* + * kal_virt_init_hif: do device related initialization + * @ad: structure for adapter private data + * + * not: implementation for different HIF may refer to nic/hal.h + */ +void kal_virt_init_hif(struct ADAPTER *ad); + +/* + * kal_virt_enable_fwdl: enable firmware download + * @ad: structure for adapter private data + * + * not: implementation for different HIF may refer to nic/hal.h + */ +void kal_virt_enable_fwdl(struct ADAPTER *ad, bool enable); + +/* + * kal_virt_get_int_status: read interrupt status + * @ad: structure for adapter private data + * @status: return value for interrupt status + * + * not: implementation for different HIF may refer to nic/hal.h + */ +void kal_virt_get_int_status(struct ADAPTER *ad, uint32_t *status); +#endif /* _HIF_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/hif/none/none.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/hif/none/none.c new file mode 100644 index 0000000000000000000000000000000000000000..6349c996b715915430960e4521d69bcb33d107c4 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/hif/none/none.c @@ -0,0 +1,333 @@ +/**************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ***************************************************************************/ +/**************************************************************************** + *[File] axi.c + *[Version] v1.0 + *[Revision Date] 2010-03-01 + *[Author] + *[Description] + * The program provides AXI HIF driver + *[Copyright] + * Copyright (C) 2010 MediaTek Incorporation. All Rights Reserved. + ****************************************************************************/ + + +/***************************************************************************** + * C O M P I L E R F L A G S + ***************************************************************************** + */ + +/***************************************************************************** + * E X T E R N A L R E F E R E N C E S + ***************************************************************************** + */ + +#include "gl_os.h" + +#include "precomp.h" + +#include "hif.h" + +/***************************************************************************** + * C O N S T A N T S + ***************************************************************************** + */ + +/***************************************************************************** + * D A T A T Y P E S + ***************************************************************************** + */ + +/***************************************************************************** + * P U B L I C D A T A + ***************************************************************************** + */ + +/***************************************************************************** + * P R I V A T E D A T A + ***************************************************************************** + */ + + +/***************************************************************************** + * M A C R O S + ***************************************************************************** + */ + +/***************************************************************************** + * F U N C T I O N D E C L A R A T I O N S + ***************************************************************************** + */ + + +/***************************************************************************** + * F U N C T I O N S + ***************************************************************************** + */ + +void kal_virt_write_tx_port(struct ADAPTER *ad, + uint16_t pid, uint32_t len, uint8_t *buf, uint32_t buf_size) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); +} + +void kal_virt_get_wifi_func_stat(struct ADAPTER *ad, uint32_t *res) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); +} + +void kal_virt_chk_wifi_func_off(struct ADAPTER *ad, uint32_t ready_bits, + uint8_t *res) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); +} + +void kal_virt_chk_wifi_func_ready(struct ADAPTER *ad, uint32_t ready_bits, + uint8_t *res) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); +} + +void kal_virt_set_mailbox_readclear(struct ADAPTER *ad, bool enable) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); +} + +void kal_virt_set_int_stat_readclear(struct ADAPTER *ad) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); +} + +void kal_virt_init_hif(struct ADAPTER *ad) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); +} + +void kal_virt_enable_fwdl(struct ADAPTER *ad, bool enable) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); +} + +void kal_virt_get_int_status(struct ADAPTER *ad, uint32_t *status) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); +} + +/* the following functions are defined in include/nic/hal.h + * need to be implemented directly in os/hif + */ +bool halHifSwInfoInit(IN struct ADAPTER *prAdapter) +{ + return KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, prAdapter); +} + +void halPrintHifDbgInfo(IN struct ADAPTER *prAdapter) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, prAdapter); +} + +uint32_t halHifPowerOffWifi(IN struct ADAPTER *prAdapter) +{ + return KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, prAdapter); +} + +void halTxResourceResetHwTQCounter(struct ADAPTER *prAdapter) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, prAdapter); +} + +uint32_t halDumpHifStatus(struct ADAPTER *prAdapter, + uint8_t *pucBuf, uint32_t u4Max) +{ + return KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, prAdapter); +} + +uint32_t halGetValidCoalescingBufSize(IN struct ADAPTER *prAdapter) +{ + return KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, prAdapter); +} + +uint32_t halAllocateIOBuffer(IN struct ADAPTER *prAdapter) +{ + return KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, prAdapter); +} + +uint32_t halReleaseIOBuffer(IN struct ADAPTER *prAdapter) +{ + return KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, prAdapter); +} + +void halDisableInterrupt(IN struct ADAPTER *prAdapter) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, prAdapter); +} + +void halEnableInterrupt(IN struct ADAPTER *prAdapter) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, prAdapter); +} + +u_int8_t halVerifyChipID(IN struct ADAPTER *prAdapter) +{ + return KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, prAdapter); +} + +void halProcessAbnormalInterrupt(IN struct ADAPTER *prAdapter) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, prAdapter); +} + +void halProcessSoftwareInterrupt(IN struct ADAPTER *prAdapter) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, prAdapter); +} + +void halProcessRxInterrupt(IN struct ADAPTER *prAdapter) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, prAdapter); +} + +void halProcessTxInterrupt(IN struct ADAPTER *prAdapter) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, prAdapter); +} + +void halSerHifReset(IN struct ADAPTER *prAdapter) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, prAdapter); +} + +u_int8_t halIsTxResourceControlEn(IN struct ADAPTER *prAdapter) +{ + return KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, prAdapter); +} + +uint32_t halTxPollingResource(IN struct ADAPTER *prAdapter, IN uint8_t ucTC) +{ + return KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, prAdapter); +} + +uint32_t halGetHifTxPageSize(IN struct ADAPTER *prAdapter) +{ + return KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, prAdapter); +} + +u_int8_t halTxIsDataBufEnough(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo) +{ + return KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, prAdapter); +} + +uint32_t halTxGetPageCount(IN struct ADAPTER *prAdapter, + IN uint32_t u4FrameLength, IN u_int8_t fgIncludeDesc) +{ + return KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, prAdapter); +} + +void halTxCancelSendingCmd(struct ADAPTER *prAdapter, + struct CMD_INFO *prCmdInfo) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, prAdapter); +} + +void halRxProcessMsduReport(IN struct ADAPTER *prAdapter, + IN OUT struct SW_RFB *prSwRfb) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, prAdapter); +} + +u_int8_t halIsPendingRx(IN struct ADAPTER *prAdapter) +{ + /* TODO: check pending Rx + * if previous Rx handling is break due to lack of SwRfb + */ + return KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, prAdapter); +} + +uint32_t +halRxWaitResponse(struct ADAPTER *prAdapter, uint8_t ucPortIdx, + uint8_t *pucRspBuffer, uint32_t u4MaxRespBufferLen, uint32_t *pu4Length) +{ + return KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, prAdapter); +} + +void halSetFWOwn(IN struct ADAPTER *prAdapter, IN u_int8_t fgEnableGlobalInt) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, prAdapter); +} + +u_int8_t halSetDriverOwn(IN struct ADAPTER *prAdapter) +{ + return KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, prAdapter); +} + +uint8_t halTxRingDataSelect(IN struct ADAPTER *prAdapter, + IN struct MSDU_INFO *prMsduInfo) +{ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, prAdapter); +} + +/*----------------------------------------------------------------------------*/ +/*! +* @brief Check if HIF state is during supend process +* +* @param prAdapter Pointer to the Adapter structure. +* +* @return (TRUE: suspend, reject the caller action. FALSE: not suspend) +*/ +/*----------------------------------------------------------------------------*/ +bool halIsHifStateSuspend(IN struct ADAPTER *prAdapter) +{ + /* HIF owner should implement this function */ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, prAdapter); + return FALSE; +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/include/gl_ate_agent.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/include/gl_ate_agent.h new file mode 100644 index 0000000000000000000000000000000000000000..81b2de9871547c0448f85623b7c5081ac9c501a6 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/include/gl_ate_agent.h @@ -0,0 +1,288 @@ +/******************************************************************************* + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ +/*! \file gl_ate_agent.h + * \brief This file includes private ioctl support. + */ + +#ifndef _GL_ATE_AGENT_H +#define _GL_ATE_AGENT_H +#if CFG_SUPPORT_QA_TOOL +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +extern uint32_t u4RxStatSeqNum; + +#if CFG_SUPPORT_TX_BF +extern union PFMU_PROFILE_TAG1 g_rPfmuTag1; +extern union PFMU_PROFILE_TAG2 g_rPfmuTag2; +extern union PFMU_DATA g_rPfmuData; +#endif + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +struct STA_REC_BF_UPD_ARGUMENT { + uint32_t u4WlanId; + uint32_t u4BssId; + uint32_t u4PfmuId; + uint32_t u4SuMu; + uint32_t u4eTxBfCap; + uint32_t u4NdpaRate; + uint32_t u4NdpRate; + uint32_t u4ReptPollRate; + uint32_t u4TxMode; + uint32_t u4Nc; + uint32_t u4Nr; + uint32_t u4Bw; + uint32_t u4SpeIdx; + uint32_t u4TotalMemReq; + uint32_t u4MemReq20M; + uint32_t au4MemRow[4]; + uint32_t au4MemCol[4]; +}; + +struct ATE_OPS_T { + int32_t (*setICapStart)(struct GLUE_INFO *prGlueInfo, + uint32_t fgTrigger, + uint32_t fgRingCapEn, + uint32_t u4Event, + uint32_t u4Node, + uint32_t u4Len, + uint32_t u4StopCycle, + uint32_t u4BW, + uint32_t u4MACTriggerEvent, + uint32_t u4SourceAddrLSB, + uint32_t u4SourceAddrMSB, + uint32_t u4Band); + int32_t (*getICapStatus)(struct GLUE_INFO *prGlueInfo); + int32_t (*getICapIQData)(struct GLUE_INFO *prGlueInfo, + uint8_t *pData, + uint32_t u4IQType, + uint32_t u4WFNum); + void (*getRbistDataDumpEvent)(struct ADAPTER *prAdapter, + uint8_t *pucEventBuf); +}; + + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +int Set_ResetStatCounter_Proc(struct net_device *prNetDev, + uint8_t *prInBuf); +int SetATE(struct net_device *prNetDev, uint8_t *prInBuf); +int SetATEDa(struct net_device *prNetDev, uint8_t *prInBuf); +int SetATESa(struct net_device *prNetDev, uint8_t *prInBuf); +int SetATEChannel(struct net_device *prNetDev, + uint8_t *prInBuf); +int SetATETxPower0(struct net_device *prNetDev, + uint8_t *prInBuf); +int SetATETxGi(struct net_device *prNetDev, + uint8_t *prInBuf); +int SetATETxBw(struct net_device *prNetDev, + uint8_t *prInBuf); +int SetATETxMode(struct net_device *prNetDev, + uint8_t *prInBuf); +int SetATETxLength(struct net_device *prNetDev, + uint8_t *prInBuf); +int SetATETxCount(struct net_device *prNetDev, + uint8_t *prInBuf); +int SetATETxMcs(struct net_device *prNetDev, + uint8_t *prInBuf); +int SetATEIpg(struct net_device *prNetDev, + uint8_t *prInBuf); + +#if CFG_SUPPORT_TX_BF +int Set_TxBfProfileTag_Help(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfProfileTag_InValid(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfProfileTag_PfmuIdx(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfProfileTag_BfType(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfProfileTag_DBW(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfProfileTag_SuMu(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfProfileTag_Mem(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfProfileTag_Matrix(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfProfileTag_SNR(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfProfileTag_SmartAnt(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfProfileTag_SeIdx(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfProfileTag_RmsdThrd(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfProfileTag_McsThrd(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfProfileTag_TimeOut(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfProfileTag_DesiredBW(struct net_device + *prNetDev, uint8_t *prInBuf); +int Set_TxBfProfileTag_DesiredNc(struct net_device + *prNetDev, uint8_t *prInBuf); +int Set_TxBfProfileTag_DesiredNr(struct net_device + *prNetDev, uint8_t *prInBuf); +int Set_TxBfProfileTagRead(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfProfileTagWrite(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_StaRecCmmUpdate(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_StaRecBfUpdate(struct net_device *prNetDev, + uint8_t *prInBuf); + +int Set_DevInfoUpdate(struct net_device *prNetDev, + uint8_t *prInBuf); + +int Set_BssInfoUpdate(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfProfileDataRead(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfProfileDataWrite(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_Trigger_Sounding_Proc(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_Stop_Sounding_Proc(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfTxApply(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfProfilePnRead(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfProfilePnWrite(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfManualAssoc(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfPfmuMemAlloc(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_TxBfPfmuMemRelease(struct net_device *prNetDev, + uint8_t *prInBuf); + +#if CFG_SUPPORT_MU_MIMO +int Set_MUGetInitMCS(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_MUCalInitMCS(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_MUCalLQ(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_MUGetLQ(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_MUSetSNROffset(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_MUSetZeroNss(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_MUSetSpeedUpLQ(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_MUSetMUTable(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_MUSetGroup(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_MUGetQD(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_MUSetEnable(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_MUSetGID_UP(struct net_device *prNetDev, + uint8_t *prInBuf); +int Set_MUTriggerTx(struct net_device *prNetDev, + uint8_t *prInBuf); +#endif + +#if CFG_SUPPORT_TX_BF_FPGA +int Set_TxBfProfileSwTagWrite(struct net_device *prNetDev, + uint8_t *prInBuf); +#endif +#endif + + +int WriteEfuse(struct net_device *prNetDev, + uint8_t *prInBuf); +int SetTxTargetPower(struct net_device *prNetDev, + uint8_t *prInBuf); + +#if (CFG_SUPPORT_DFS_MASTER == 1) +int SetRddReport(struct net_device *prNetDev, + uint8_t *prInBuf); +int SetByPassCac(struct net_device *prNetDev, + uint8_t *prInBuf); +int SetRadarDetectMode(struct net_device *prNetDev, + uint8_t *prInBuf); +#endif + +int AteCmdSetHandle(struct net_device *prNetDev, + uint8_t *prInBuf, uint32_t u4InBufLen); + +#endif /*CFG_SUPPORT_QA_TOOL */ +#endif /* _GL_ATE_AGENT_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/include/gl_cfg80211.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/include/gl_cfg80211.h new file mode 100644 index 0000000000000000000000000000000000000000..1175faf583cf486339551d3d352ac50500f13dd2 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/include/gl_cfg80211.h @@ -0,0 +1,762 @@ +/******************************************************************************* + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include + * /gl_cfg80211.h#1 + */ + +/*! \file gl_cfg80211.h + * \brief This file is for Portable Driver linux cfg80211 support. + */ + + +#ifndef _GL_CFG80211_H +#define _GL_CFG80211_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "gl_os.h" + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#ifdef CONFIG_NL80211_TESTMODE +#define NL80211_DRIVER_TESTMODE_VERSION 2 +#endif + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +#ifdef CONFIG_NL80211_TESTMODE +#if CFG_SUPPORT_NFC_BEAM_PLUS + +struct NL80211_DRIVER_SET_NFC_PARAMS { + struct NL80211_DRIVER_TEST_MODE_PARAMS hdr; + uint32_t NFC_Enable; + +}; + +#endif + + + +struct NL80211_DRIVER_GET_STA_STATISTICS_PARAMS { + struct NL80211_DRIVER_TEST_MODE_PARAMS hdr; + uint32_t u4Version; + uint32_t u4Flag; + uint8_t aucMacAddr[MAC_ADDR_LEN]; +}; + +enum _ENUM_TESTMODE_LINK_DETECTION_ATTR { + NL80211_TESTMODE_LINK_INVALID = 0, + NL80211_TESTMODE_LINK_TX_FAIL_CNT, + NL80211_TESTMODE_LINK_TX_RETRY_CNT, + NL80211_TESTMODE_LINK_TX_MULTI_RETRY_CNT, + NL80211_TESTMODE_LINK_ACK_FAIL_CNT, + NL80211_TESTMODE_LINK_FCS_ERR_CNT, + NL80211_TESTMODE_LINK_TX_CNT, + NL80211_TESTMODE_LINK_RX_CNT, + NL80211_TESTMODE_LINK_RST_REASON, + NL80211_TESTMODE_LINK_RST_TIME, + NL80211_TESTMODE_LINK_ROAM_FAIL_TIMES, + NL80211_TESTMODE_LINK_ROAM_FAIL_TIME, + NL80211_TESTMODE_LINK_TX_DONE_DELAY_IS_ARP, + NL80211_TESTMODE_LINK_ARRIVE_DRV_TICK, + NL80211_TESTMODE_LINK_ENQUE_TICK, + NL80211_TESTMODE_LINK_DEQUE_TICK, + NL80211_TESTMODE_LINK_LEAVE_DRV_TICK, + NL80211_TESTMODE_LINK_CURR_TICK, + NL80211_TESTMODE_LINK_CURR_TIME, + + NL80211_TESTMODE_LINK_DETECT_NUM +}; + +enum ENUM_TESTMODE_STA_STATISTICS_ATTR { + NL80211_TESTMODE_STA_STATISTICS_INVALID = 0, + NL80211_TESTMODE_STA_STATISTICS_VERSION, + NL80211_TESTMODE_STA_STATISTICS_MAC, + NL80211_TESTMODE_STA_STATISTICS_LINK_SCORE, + NL80211_TESTMODE_STA_STATISTICS_FLAG, + + NL80211_TESTMODE_STA_STATISTICS_PER, + NL80211_TESTMODE_STA_STATISTICS_RSSI, + NL80211_TESTMODE_STA_STATISTICS_PHY_MODE, + NL80211_TESTMODE_STA_STATISTICS_TX_RATE, + + NL80211_TESTMODE_STA_STATISTICS_TOTAL_CNT, + NL80211_TESTMODE_STA_STATISTICS_THRESHOLD_CNT, + + NL80211_TESTMODE_STA_STATISTICS_AVG_PROCESS_TIME, + NL80211_TESTMODE_STA_STATISTICS_MAX_PROCESS_TIME, + NL80211_TESTMODE_STA_STATISTICS_AVG_HIF_PROCESS_TIME, + NL80211_TESTMODE_STA_STATISTICS_MAX_HIF_PROCESS_TIME, + + NL80211_TESTMODE_STA_STATISTICS_FAIL_CNT, + NL80211_TESTMODE_STA_STATISTICS_TIMEOUT_CNT, + NL80211_TESTMODE_STA_STATISTICS_AVG_AIR_TIME, + + NL80211_TESTMODE_STA_STATISTICS_TC_EMPTY_CNT_ARRAY, + NL80211_TESTMODE_STA_STATISTICS_TC_QUE_LEN_ARRAY, + + NL80211_TESTMODE_STA_STATISTICS_TC_AVG_QUE_LEN_ARRAY, + NL80211_TESTMODE_STA_STATISTICS_TC_CUR_QUE_LEN_ARRAY, + + /* + * how many packages TX during statistics interval + */ + NL80211_TESTMODE_STA_STATISTICS_ENQUEUE, + + /* + * how many packages this TX during statistics interval + */ + NL80211_TESTMODE_STA_STATISTICS_STA_ENQUEUE, + + /* + * how many packages dequeue during statistics interval + */ + NL80211_TESTMODE_STA_STATISTICS_DEQUEUE, + + /* + * how many packages this sta dequeue during statistics interval + */ + NL80211_TESTMODE_STA_STATISTICS_STA_DEQUEUE, + + /* + * how many TC[0-3] resource back from firmware during + * statistics interval + */ + NL80211_TESTMODE_STA_STATISTICS_RB_ARRAY, + NL80211_TESTMODE_STA_STATISTICS_NO_TC_ARRAY, + NL80211_TESTMODE_STA_STATISTICS_USED_TC_PGCT_ARRAY, + NL80211_TESTMODE_STA_STATISTICS_WANTED_TC_PGCT_ARRAY, + + NL80211_TESTMODE_STA_STATISTICS_IRQ_ISR_CNT, + NL80211_TESTMODE_STA_STATISTICS_IRQ_ISR_PASS_CNT, + NL80211_TESTMODE_STA_STATISTICS_IRQ_TASK_CNT, + NL80211_TESTMODE_STA_STATISTICS_IRQ_AB_CNT, + NL80211_TESTMODE_STA_STATISTICS_IRQ_SW_CNT, + NL80211_TESTMODE_STA_STATISTICS_IRQ_TX_CNT, + NL80211_TESTMODE_STA_STATISTICS_IRQ_RX_CNT, + + NL80211_TESTMODE_STA_STATISTICS_RESERVED_ARRAY, + + NL80211_TESTMODE_STA_STATISTICS_NUM +}; +#endif +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +/* cfg80211 hooks */ +#if 0 +int +mtk_cfg80211_change_iface(struct wiphy *wiphy, + struct net_device *ndev, enum nl80211_iftype type, + u32 *flags, struct vif_params *params); + +int +mtk_cfg80211_add_key(struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index, bool pairwise, const u8 *mac_addr, + struct key_params *params); + +int +mtk_cfg80211_get_key(struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index, + bool pairwise, + const u8 *mac_addr, void *cookie, + void (*callback)(void *cookie, struct key_params *)); + +int +mtk_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_index, + bool pairwise, const u8 *mac_addr); + +int +mtk_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev, + u8 key_index, bool unicast, bool multicast); + +#if KERNEL_VERSION(3, 16, 0) <= CFG80211_VERSION_CODE +int mtk_cfg80211_get_station(struct wiphy *wiphy, + struct net_device *ndev, const u8 *mac, + struct station_info *sinfo); +#else +int mtk_cfg80211_get_station(struct wiphy *wiphy, + struct net_device *ndev, u8 *mac, + struct station_info *sinfo); +#endif + +int +mtk_cfg80211_get_link_statistics(struct wiphy *wiphy, + struct net_device *ndev, u8 *mac, + struct station_info *sinfo); + +int mtk_cfg80211_scan(struct wiphy *wiphy, + struct cfg80211_scan_request *request); + +void mtk_cfg80211_abort_scan(struct wiphy *wiphy, + struct wireless_dev *wdev); + +int mtk_cfg80211_connect(struct wiphy *wiphy, + struct net_device *ndev, + struct cfg80211_connect_params *sme); + +int mtk_cfg80211_disconnect(struct wiphy *wiphy, + struct net_device *ndev, u16 reason_code); + +int mtk_cfg80211_join_ibss(struct wiphy *wiphy, + struct net_device *ndev, + struct cfg80211_ibss_params *params); + +int mtk_cfg80211_leave_ibss(struct wiphy *wiphy, + struct net_device *ndev); + +int mtk_cfg80211_set_power_mgmt(struct wiphy *wiphy, + struct net_device *ndev, bool enabled, int timeout); + +int mtk_cfg80211_set_pmksa(struct wiphy *wiphy, + struct net_device *ndev, struct cfg80211_pmksa *pmksa); + +int mtk_cfg80211_del_pmksa(struct wiphy *wiphy, + struct net_device *ndev, struct cfg80211_pmksa *pmksa); + +int mtk_cfg80211_flush_pmksa(struct wiphy *wiphy, + struct net_device *ndev); + +int mtk_cfg80211_set_rekey_data(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_gtk_rekey_data *data); + +int mtk_cfg80211_remain_on_channel(struct wiphy *wiphy, + struct wireless_dev *wdev, struct ieee80211_channel *chan, + unsigned int duration, u64 *cookie); + +int mtk_cfg80211_cancel_remain_on_channel( + struct wiphy *wiphy, struct wireless_dev *wdev, u64 cookie); +#if KERNEL_VERSION(3, 14, 0) <= CFG80211_VERSION_CODE +int mtk_cfg80211_mgmt_tx(struct wiphy *wiphy, + struct wireless_dev *wdev, + struct cfg80211_mgmt_tx_params *params, + u64 *cookie); +#else +int mtk_cfg80211_mgmt_tx(struct wiphy *wiphy, + struct wireless_dev *wdev, + struct ieee80211_channel *channel, bool offscan, + unsigned int wait, + const u8 *buf, size_t len, bool no_cck, + bool dont_wait_for_ack, u64 *cookie); +#endif + +void mtk_cfg80211_mgmt_frame_register(IN struct wiphy *wiphy, + IN struct wireless_dev *wdev, IN u16 frame_type, IN bool reg); + +int mtk_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, + struct wireless_dev *wdev, u64 cookie); + +#ifdef CONFIG_NL80211_TESTMODE +int +mtk_cfg80211_testmode_get_sta_statistics(IN struct wiphy + *wiphy, + IN void *data, IN int len, IN struct GLUE_INFO *prGlueInfo); + +int mtk_cfg80211_testmode_get_scan_done(IN struct wiphy + *wiphy, IN void *data, IN int len, + IN struct GLUE_INFO *prGlueInfo); + +#if KERNEL_VERSION(3, 12, 0) <= CFG80211_VERSION_CODE +int mtk_cfg80211_testmode_cmd(struct wiphy *wiphy, + struct wireless_dev *wdev, + void *data, int len); +#else +int mtk_cfg80211_testmode_cmd(struct wiphy *wiphy, + void *data, int len); +#endif + +int mtk_cfg80211_testmode_sw_cmd(IN struct wiphy *wiphy, + IN void *data, IN int len); + +#if CFG_SUPPORT_PASSPOINT +int mtk_cfg80211_testmode_hs20_cmd(IN struct wiphy *wiphy, + IN void *data, IN int len); +#endif /* CFG_SUPPORT_PASSPOINT */ + +#if CFG_SUPPORT_WAPI +int mtk_cfg80211_testmode_set_key_ext(IN struct wiphy + *wiphy, IN void *data, IN int len); +#endif +#if CFG_SUPPORT_NFC_BEAM_PLUS +int mtk_cfg80211_testmode_get_scan_done(IN struct wiphy *wiphy, + IN void *data, IN int len, IN struct GLUE_INFO *prGlueInfo); +#endif +#else +/* IGNORE KERNEL DEPENCY ERRORS */ +/* #error "Please ENABLE kernel config (CONFIG_NL80211_TESTMODE) to support + * Wi-Fi Direct" + */ +#endif + +#if CFG_SUPPORT_SCHED_SCAN +int +mtk_cfg80211_sched_scan_start(IN struct wiphy *wiphy, + IN struct net_device *ndev, + IN struct cfg80211_sched_scan_request *request); + +#if KERNEL_VERSION(4, 12, 0) <= CFG80211_VERSION_CODE +int mtk_cfg80211_sched_scan_stop(IN struct wiphy *wiphy, + IN struct net_device *ndev, + IN u64 reqid); +#else +int mtk_cfg80211_sched_scan_stop(IN struct wiphy *wiphy, + IN struct net_device *ndev); +#endif +#endif /* CFG_SUPPORT_SCHED_SCAN */ + +int mtk_cfg80211_assoc(struct wiphy *wiphy, + struct net_device *ndev, + struct cfg80211_assoc_request *req); + +#if KERNEL_VERSION(3, 16, 0) <= CFG80211_VERSION_CODE +int +mtk_cfg80211_change_station(struct wiphy *wiphy, + struct net_device *ndev, + const u8 *mac, struct station_parameters *params); + +int mtk_cfg80211_add_station(struct wiphy *wiphy, + struct net_device *ndev, + const u8 *mac, struct station_parameters *params); + +#if KERNEL_VERSION(3, 19, 0) <= CFG80211_VERSION_CODE +int mtk_cfg80211_del_station(struct wiphy *wiphy, + struct net_device *ndev, + struct station_del_parameters *params); +#else +int mtk_cfg80211_del_station(struct wiphy *wiphy, + struct net_device *ndev, + const u8 *mac); +#endif +#if KERNEL_VERSION(3, 18, 0) <= CFG80211_VERSION_CODE +int mtk_cfg80211_tdls_mgmt(struct wiphy *wiphy, + struct net_device *dev, + const u8 *peer, u8 action_code, u8 dialog_token, + u16 status_code, u32 peer_capability, + bool initiator, const u8 *buf, size_t len); +#else +int mtk_cfg80211_tdls_mgmt(struct wiphy *wiphy, + struct net_device *dev, + const u8 *peer, u8 action_code, u8 dialog_token, + u16 status_code, u32 peer_capability, + const u8 *buf, size_t len); +#endif + +int mtk_cfg80211_tdls_oper(struct wiphy *wiphy, + struct net_device *dev, + const u8 *peer, enum nl80211_tdls_operation oper); +#else +int +mtk_cfg80211_change_station(struct wiphy *wiphy, + struct net_device *ndev, u8 *mac, + struct station_parameters *params); + +int mtk_cfg80211_add_station(struct wiphy *wiphy, + struct net_device *ndev, u8 *mac, + struct station_parameters *params); + +int mtk_cfg80211_del_station(struct wiphy *wiphy, + struct net_device *ndev, u8 *mac); + +int +mtk_cfg80211_tdls_mgmt(struct wiphy *wiphy, + struct net_device *dev, + u8 *peer, u8 action_code, + u8 dialog_token, u16 status_code, + const u8 *buf, size_t len); + +int mtk_cfg80211_tdls_oper(struct wiphy *wiphy, + struct net_device *dev, u8 *peer, + enum nl80211_tdls_operation oper); +#endif + +int32_t mtk_cfg80211_process_str_cmd(struct GLUE_INFO + *prGlueInfo, uint8_t *cmd, int32_t len); + +void mtk_reg_notify(IN struct wiphy *pWiphy, + IN struct regulatory_request *pRequest); +void cfg80211_regd_set_wiphy(IN struct wiphy *pWiphy); + +int mtk_cfg80211_suspend(struct wiphy *wiphy, + struct cfg80211_wowlan *wow); + +int mtk_cfg80211_resume(struct wiphy *wiphy); + +/* cfg80211 wrapper hooks */ +#if CFG_ENABLE_UNIFY_WIPHY +#if KERNEL_VERSION(4, 12, 0) <= CFG80211_VERSION_CODE +struct wireless_dev *mtk_cfg_add_iface(struct wiphy *wiphy, + const char *name, + unsigned char name_assign_type, + enum nl80211_iftype type, + struct vif_params *params); +#elif KERNEL_VERSION(4, 1, 0) <= CFG80211_VERSION_CODE +struct wireless_dev *mtk_cfg_add_iface(struct wiphy *wiphy, + const char *name, + unsigned char name_assign_type, + enum nl80211_iftype type, + u32 *flags, + struct vif_params *params); +#else +struct wireless_dev *mtk_cfg_add_iface(struct wiphy *wiphy, + const char *name, + enum nl80211_iftype type, u32 *flags, + struct vif_params *params); +#endif +int mtk_cfg_del_iface(struct wiphy *wiphy, + struct wireless_dev *wdev); +#if KERNEL_VERSION(4, 12, 0) <= CFG80211_VERSION_CODE +int mtk_cfg_change_iface(struct wiphy *wiphy, + struct net_device *ndev, + enum nl80211_iftype type, + struct vif_params *params); +#else +int mtk_cfg_change_iface(struct wiphy *wiphy, + struct net_device *ndev, + enum nl80211_iftype type, u32 *flags, + struct vif_params *params); +#endif +int mtk_cfg_add_key(struct wiphy *wiphy, + struct net_device *ndev, u8 key_index, + bool pairwise, const u8 *mac_addr, + struct key_params *params); +int mtk_cfg_get_key(struct wiphy *wiphy, + struct net_device *ndev, u8 key_index, + bool pairwise, const u8 *mac_addr, void *cookie, + void (*callback)(void *cookie, struct key_params *)); +int mtk_cfg_del_key(struct wiphy *wiphy, + struct net_device *ndev, u8 key_index, + bool pairwise, const u8 *mac_addr); +int mtk_cfg_set_default_key(struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index, bool unicast, bool multicast); + +int mtk_cfg_set_default_mgmt_key(struct wiphy *wiphy, + struct net_device *ndev, u8 key_index); + +#if KERNEL_VERSION(3, 16, 0) <= CFG80211_VERSION_CODE +int mtk_cfg_get_station(struct wiphy *wiphy, + struct net_device *ndev, + const u8 *mac, struct station_info *sinfo); +#else +int mtk_cfg_get_station(struct wiphy *wiphy, + struct net_device *ndev, + u8 *mac, struct station_info *sinfo); +#endif + +#if CFG_SUPPORT_TDLS +#if KERNEL_VERSION(3, 16, 0) <= CFG80211_VERSION_CODE +int mtk_cfg_change_station(struct wiphy *wiphy, + struct net_device *ndev, + const u8 *mac, struct station_parameters *params); +#else +int mtk_cfg_change_station(struct wiphy *wiphy, + struct net_device *ndev, + u8 *mac, struct station_parameters *params); +#endif +#if KERNEL_VERSION(3, 16, 0) <= CFG80211_VERSION_CODE +int mtk_cfg_add_station(struct wiphy *wiphy, + struct net_device *ndev, + const u8 *mac, struct station_parameters *params); +#else +int mtk_cfg_add_station(struct wiphy *wiphy, + struct net_device *ndev, + u8 *mac, struct station_parameters *params); +#endif +#if KERNEL_VERSION(3, 16, 0) <= CFG80211_VERSION_CODE +int mtk_cfg_tdls_oper(struct wiphy *wiphy, + struct net_device *ndev, + const u8 *peer, enum nl80211_tdls_operation oper); +#else +int mtk_cfg_tdls_oper(struct wiphy *wiphy, + struct net_device *ndev, + u8 *peer, enum nl80211_tdls_operation oper); +#endif +#if KERNEL_VERSION(3, 18, 0) <= CFG80211_VERSION_CODE +int mtk_cfg_tdls_mgmt(struct wiphy *wiphy, + struct net_device *ndev, + const u8 *peer, u8 action_code, u8 dialog_token, + u16 status_code, + u32 peer_capability, bool initiator, const u8 *buf, + size_t len); +#elif KERNEL_VERSION(3, 16, 0) <= CFG80211_VERSION_CODE +int mtk_cfg_tdls_mgmt(struct wiphy *wiphy, + struct net_device *ndev, + const u8 *peer, u8 action_code, u8 dialog_token, + u16 status_code, + u32 peer_capability, const u8 *buf, size_t len); +#else +int mtk_cfg_tdls_mgmt(struct wiphy *wiphy, + struct net_device *ndev, + u8 *peer, u8 action_code, + u8 dialog_token, u16 status_code, + const u8 *buf, size_t len); +#endif +#endif /* CFG_SUPPORT_TDLS */ + +#if KERNEL_VERSION(3, 19, 0) <= CFG80211_VERSION_CODE +int mtk_cfg_del_station(struct wiphy *wiphy, + struct net_device *ndev, + struct station_del_parameters *params); +#elif KERNEL_VERSION(3, 16, 0) <= CFG80211_VERSION_CODE +int mtk_cfg_del_station(struct wiphy *wiphy, + struct net_device *ndev, + const u8 *mac); +#else +int mtk_cfg_del_station(struct wiphy *wiphy, + struct net_device *ndev, u8 *mac); +#endif +int mtk_cfg_scan(struct wiphy *wiphy, + struct cfg80211_scan_request *request); +#if KERNEL_VERSION(4, 5, 0) <= CFG80211_VERSION_CODE +void mtk_cfg_abort_scan(struct wiphy *wiphy, + struct wireless_dev *wdev); +#endif + +#if CFG_SUPPORT_SCHED_SCAN +int mtk_cfg_sched_scan_start(IN struct wiphy *wiphy, + IN struct net_device *ndev, + IN struct cfg80211_sched_scan_request *request); + +#if KERNEL_VERSION(4, 12, 0) <= CFG80211_VERSION_CODE +int mtk_cfg_sched_scan_stop(IN struct wiphy *wiphy, + IN struct net_device *ndev, + IN u64 reqid); +#else +int mtk_cfg_sched_scan_stop(IN struct wiphy *wiphy, + IN struct net_device *ndev); +#endif + +#endif /* CFG_SUPPORT_SCHED_SCAN */ + +int mtk_cfg_connect(struct wiphy *wiphy, + struct net_device *ndev, + struct cfg80211_connect_params *sme); +int mtk_cfg_disconnect(struct wiphy *wiphy, + struct net_device *ndev, + u16 reason_code); +int mtk_cfg_join_ibss(struct wiphy *wiphy, + struct net_device *ndev, + struct cfg80211_ibss_params *params); +int mtk_cfg_leave_ibss(struct wiphy *wiphy, + struct net_device *ndev); +int mtk_cfg_set_power_mgmt(struct wiphy *wiphy, + struct net_device *ndev, + bool enabled, int timeout); +int mtk_cfg_set_pmksa(struct wiphy *wiphy, + struct net_device *ndev, + struct cfg80211_pmksa *pmksa); +int mtk_cfg_del_pmksa(struct wiphy *wiphy, + struct net_device *ndev, + struct cfg80211_pmksa *pmksa); +int mtk_cfg_flush_pmksa(struct wiphy *wiphy, + struct net_device *ndev); +#if CONFIG_SUPPORT_GTK_REKEY +int mtk_cfg_set_rekey_data(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_gtk_rekey_data *data); +#endif /* CONFIG_SUPPORT_GTK_REKEY */ +int mtk_cfg_suspend(struct wiphy *wiphy, + struct cfg80211_wowlan *wow); +int mtk_cfg_resume(struct wiphy *wiphy); +int mtk_cfg_assoc(struct wiphy *wiphy, + struct net_device *ndev, + struct cfg80211_assoc_request *req); +int mtk_cfg_remain_on_channel(struct wiphy *wiphy, + struct wireless_dev *wdev, + struct ieee80211_channel *chan, + unsigned int duration, + u64 *cookie); +int mtk_cfg_cancel_remain_on_channel(struct wiphy *wiphy, + struct wireless_dev *wdev, u64 cookie); +uint16_t cfg80211_get_non_wfa_vendor_ie(struct GLUE_INFO + *prGlueInfo, uint8_t *ies, int32_t len); + +#if KERNEL_VERSION(3, 14, 0) <= CFG80211_VERSION_CODE +int mtk_cfg_mgmt_tx(struct wiphy *wiphy, + struct wireless_dev *wdev, + struct cfg80211_mgmt_tx_params *params, u64 *cookie); +#else +int mtk_cfg_mgmt_tx(struct wiphy *wiphy, + struct wireless_dev *wdev, + struct ieee80211_channel *channel, bool offscan, + unsigned int wait, + const u8 *buf, size_t len, bool no_cck, + bool dont_wait_for_ack, + u64 *cookie); +#endif +void mtk_cfg_mgmt_frame_register(struct wiphy *wiphy, + struct wireless_dev *wdev, + u16 frame_type, bool reg); + +#ifdef CONFIG_NL80211_TESTMODE +#if KERNEL_VERSION(3, 12, 0) <= CFG80211_VERSION_CODE +int mtk_cfg_testmode_cmd(struct wiphy *wiphy, + struct wireless_dev *wdev, + void *data, int len); +#else +int mtk_cfg_testmode_cmd(struct wiphy *wiphy, void *data, + int len); +#endif +#endif /* CONFIG_NL80211_TESTMODE */ + +#if (CFG_SUPPORT_DFS_MASTER == 1) +#if KERNEL_VERSION(3, 15, 0) <= CFG80211_VERSION_CODE +int mtk_cfg_start_radar_detection(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_chan_def *chandef, + unsigned int cac_time_ms); +#else +int mtk_cfg_start_radar_detection(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_chan_def *chandef); +#endif + + +#if KERNEL_VERSION(3, 13, 0) <= CFG80211_VERSION_CODE +int mtk_cfg_channel_switch(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_csa_settings *params); +#endif +#endif + + +#if (CFG_ENABLE_WIFI_DIRECT_CFG_80211 != 0) +int mtk_cfg_change_bss(struct wiphy *wiphy, + struct net_device *dev, + struct bss_parameters *params); +int mtk_cfg_mgmt_tx_cancel_wait(struct wiphy *wiphy, + struct wireless_dev *wdev, + u64 cookie); +int mtk_cfg_deauth(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_deauth_request *req); +int mtk_cfg_disassoc(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_disassoc_request *req); +int mtk_cfg_start_ap(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_ap_settings *settings); +int mtk_cfg_change_beacon(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_beacon_data *info); +int mtk_cfg_stop_ap(struct wiphy *wiphy, + struct net_device *dev); +int mtk_cfg_set_wiphy_params(struct wiphy *wiphy, + u32 changed); +int mtk_cfg_set_bitrate_mask(struct wiphy *wiphy, + struct net_device *dev, + const u8 *peer, + const struct cfg80211_bitrate_mask *mask); +int mtk_cfg_set_txpower(struct wiphy *wiphy, + struct wireless_dev *wdev, + enum nl80211_tx_power_setting type, int mbm); +int mtk_cfg_get_txpower(struct wiphy *wiphy, + struct wireless_dev *wdev, + int *dbm); +#endif /* (CFG_ENABLE_WIFI_DIRECT_CFG_80211 != 0) */ + +#endif /* CFG_ENABLE_UNIFY_WIPHY */ + +int mtk_cfg80211_update_ft_ies(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_update_ft_ies_params *ftie); +#endif + +#ifdef CFG_REMIND_IMPLEMENT +#define mtk_cfg80211_find_ie_match_mask(_eid, _ies, _len, _match,\ + _match_len, _match_offset, _match_mask) \ + ((uint8_t *) KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__)) +#else +const uint8_t *mtk_cfg80211_find_ie_match_mask(uint8_t eid, + const uint8_t *ies, int len, + const uint8_t *match, + int match_len, int match_offset, + const uint8_t *match_mask); +#endif + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#endif /* _GL_CFG80211_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/include/gl_dependent.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/include/gl_dependent.h new file mode 100644 index 0000000000000000000000000000000000000000..6d66b1f00c3a383687ef03789a8f7cbbb62b97a5 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/include/gl_dependent.h @@ -0,0 +1,1100 @@ + +/***************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ***************************************************************************/ +/*! \file gl_dependency.h + * \brief List the os-dependent structure/API that need to implement + * to align with common part + * + * not to modify *.c while put current used linux-type strucutre/API here + * For porting to new OS, the API listed in this file needs to be + * implemented + */ + +#ifndef _GL_DEPENDENT_H +#define _GL_DEPENDENT_H + +#ifndef IS_ENABLED +#define IS_ENABLED(_val) defined(_val) +#endif +/* + * TODO: implement defined structure to let + * other OS aligned to linux style for common part logic workaround + */ +/* + * TODO: os-related?, CHN_DIRTY_WEIGHT_UPPERBOUND + * should we remove gl_*_ioctl.h in os/none? + * defined in os/linux/include/gl_p2p_ioctl.h + * used in + * 1) os/linux/gl_p2p_cfg80211.c + * 2) mgmt/cnm.c + * > is it related to ioctl?, or should it put in wlan_p2p.h + */ +#if 0 +#define CHN_DIRTY_WEIGHT_UPPERBOUND 4 +#endif + +/* some arch's have a small-data section that can be accessed register-relative + * but that can only take up to, say, 4-byte variables. jiffies being part of + * an 8-byte variable may not be correctly accessed unless we force the issue + * #define __jiffy_data __attribute__((section(".data"))) + * + * The 64-bit value is not atomic - you MUST NOT read it + * without sampling the sequence number in jiffies_lock. + + * extern u64 __jiffy_data jiffies_64; + * extern unsigned long volatile __jiffy_data jiffies; + * TODO: no idea how to implement jiffies here + */ +#ifndef HZ +#define HZ (1000) +#endif +#define jiffies (0) + +/* + * comment: cipher type should not related to os + * defined in os/linux/gl_wext.h, + * while it looks like also defined in linux/wireless.h + * are we trying to be an self-fulfilled driver then + * should not put it under os folder? or we should just include from linux + */ +/* IW_AUTH_PAIRWISE_CIPHER and IW_AUTH_GROUP_CIPHER values (bit field) */ +#define IW_AUTH_CIPHER_NONE 0x00000001 +#define IW_AUTH_CIPHER_WEP40 0x00000002 +#define IW_AUTH_CIPHER_TKIP 0x00000004 +#define IW_AUTH_CIPHER_CCMP 0x00000008 +#define IW_AUTH_CIPHER_WEP104 0x00000010 + +/* + * comment: + * 1) access GlueInfo member from core logic + * 2) IW_AUTH_WPA_VERSION_DISABLED is defined in os/linux/include/gl_wext.h + * > is the an os-dependent value/ protocol value. + * should implement depends on OS/ its WiFi + * needed by, + * mgmt/ais_fsm.c + * mgmt/assoc.c + */ +/* IW_AUTH_WPA_VERSION values (bit field) */ +#define IW_AUTH_WPA_VERSION_DISABLED 0x00000001 +#define IW_AUTH_WPA_VERSION_WPA 0x00000002 +#define IW_AUTH_WPA_VERSION_WPA2 0x00000004 + +#define IW_AUTH_ALG_FT 0x00000008 + +#define IW_PMKID_LEN 16 +/* + * this highly depends on kernel version + * why can't we just use kalGetTimeTick (?) + * needed by + * wmm.c + */ +#if 0 +struct timespec { + __kernel_time_t tv_sec; /* seconds */ + long tv_nsec; /* nanoseconds */ +}; +#endif + +/* + * defined in linux/time64.h + * in cnm_timer.h + * we do (?!), we may just add undef NSEC_PER_MSEC then define ours + * #undef MSEC_PER_SEC + * #define MSEC_PER_SEC 1000 + * #undef USEC_PER_MSEC + * #define USEC_PER_MSEC 1000 + * #undef USEC_PER_SEC + * #define USEC_PER_SEC 1000000 + */ +#define NSEC_PER_MSEC 1000000L + +/* + * needed by nic/nic_cmd_event.c + * defined in uapi/asm-generic/fcntl.h + */ +#define O_RDONLY 00000000 + +/* + * needed by que_mgt.c + * ETH_P_IP, include/linux/if_ether.h + */ +#define ETH_P_IP 0x0800 /* Internet Protocol packet */ + +/* + * needed by cmm_asic_connac.c + * Potential risk in this function + * #ifdef CONFIG_PHYS_ADDR_T_64BIT + * typedef u64 phys_addr_t; + * #else + * typedef u32 phys_addr_t; + * #endif + * while anyway the rDmaAddr is transfer to u8Addr still u64 + * , and filled into u4Ptr0 which is uint32_t (?) + */ +#define phys_addr_t uint32_t + +/* + * needed by nic_tx.h + * defined in linux/types.h + * #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT + * typedef u64 dma_addr_t; + * #else + * typedef u32 dma_addr_t; + * #endif + */ +#define dma_addr_t uint32_t + +/* needed by: + * common/debug.c + * source/include/linux/printk.h + */ +enum { + DUMP_PREFIX_NONE, + DUMP_PREFIX_ADDRESS, + DUMP_PREFIX_OFFSET +}; + +/* needed by + * common/wlan_lib.c + * include/mgmt/rsn.h + */ +#define LINUX_VERSION_CODE 199947 +#define CFG80211_VERSION_CODE LINUX_VERSION_CODE +#define KERNEL_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c)) + +/* needed by nic/nic_cmd_event.c */ +struct wireless_dev { + + struct wiphy *wiphy; + struct net_device *netdev; + +}; +/* needed by + * common/wlan_lib.c & wlan_lib.h + * mgmt/tdls.c + * mgmt/p2p_role_fsm.c + * nic/nic_cmd_event.c + */ +struct net_device { + /* + * access member of member of GlueInfo directly + * in mgmt/p2p_role_fsm.c + */ + unsigned char *dev_addr; + /* needed by nic/nic_cmd_event.c */ + struct wireless_dev *ieee80211_ptr; +}; + +struct device { +}; + +/* needed by + * common/debug.c + * mgmt/stats.c + * include/nic/nic_tx.h, nic/nic_tx.c + * cb for driver private for data packet + * dev needed by mgmt/tdls.c + * mgmt/tkip_mic.c, and do dev_alloc_skb + * nic/nic_rx.c + * nic/que_mgt.c + */ +struct sk_buff { + char cb[48]; + unsigned char *data; + unsigned int len; + struct net_device *dev; +}; + +/* + * needed by common/wlan_oid.c + * struct cfg80211_update_ft_ies_params - FT IE Information + * This structure provides information needed to update the fast transition IE + * + * @md: The Mobility Domain ID, 2 Octet value + * @ie: Fast Transition IEs + * @ie_len: Length of ft_ie in octets + */ +struct cfg80211_update_ft_ies_params { + u16 md; + const u8 *ie; + size_t ie_len; +}; + +/* + * needed by + * include/mgmt/rlm_domain.h + * mgmt/p2p_func.c + * + * enum nl80211_dfs_regions - regulatory DFS regions + * + * @NL80211_DFS_UNSET: Country has no DFS master region specified + * @NL80211_DFS_FCC: Country follows DFS master rules from FCC + * @NL80211_DFS_ETSI: Country follows DFS master rules from ETSI + * @NL80211_DFS_JP: Country follows DFS master rules from JP/MKK/Telec + */ +enum nl80211_dfs_regions { + NL80211_DFS_UNSET = 0, + NL80211_DFS_FCC = 1, + NL80211_DFS_ETSI = 2, + NL80211_DFS_JP = 3, +}; + +/* + * needed by mgmt/rlm_domain.c + * enum ieee80211_channel_flags - channel flags + * + * Channel flags set by the regulatory control code. + * + * @IEEE80211_CHAN_DISABLED: This channel is disabled. + * @IEEE80211_CHAN_NO_IR: do not initiate radiation, this includes + * sending probe requests or beaconing. + * @IEEE80211_CHAN_RADAR: Radar detection is required on this channel. + * @IEEE80211_CHAN_NO_HT40PLUS: extension channel above this channel + * is not permitted. + * @IEEE80211_CHAN_NO_HT40MINUS: extension channel below this channel + * is not permitted. + * @IEEE80211_CHAN_NO_OFDM: OFDM is not allowed on this channel. + * @IEEE80211_CHAN_NO_80MHZ: If the driver supports 80 MHz on the band, + * this flag indicates that an 80 MHz channel cannot use this + * channel as the control or any of the secondary channels. + * This may be due to the driver or due to regulatory bandwidth + * restrictions. + * @IEEE80211_CHAN_NO_160MHZ: If the driver supports 160 MHz on the band, + * this flag indicates that an 160 MHz channel cannot use this + * channel as the control or any of the secondary channels. + * This may be due to the driver or due to regulatory bandwidth + * restrictions. + * @IEEE80211_CHAN_INDOOR_ONLY: see %NL80211_FREQUENCY_ATTR_INDOOR_ONLY + * @IEEE80211_CHAN_GO_CONCURRENT: see %NL80211_FREQUENCY_ATTR_GO_CONCURRENT + * @IEEE80211_CHAN_NO_20MHZ: 20 MHz bandwidth is not permitted + * on this channel. + * @IEEE80211_CHAN_NO_10MHZ: 10 MHz bandwidth is not permitted + * on this channel. + * + */ +enum ieee80211_channel_flags { + IEEE80211_CHAN_DISABLED = 1<<0, + IEEE80211_CHAN_NO_IR = 1<<1, + /* hole at 1<<2 */ + IEEE80211_CHAN_RADAR = 1<<3, + IEEE80211_CHAN_NO_HT40PLUS = 1<<4, + IEEE80211_CHAN_NO_HT40MINUS = 1<<5, + IEEE80211_CHAN_NO_OFDM = 1<<6, + IEEE80211_CHAN_NO_80MHZ = 1<<7, + IEEE80211_CHAN_NO_160MHZ = 1<<8, + IEEE80211_CHAN_INDOOR_ONLY = 1<<9, + IEEE80211_CHAN_GO_CONCURRENT = 1<<10, + IEEE80211_CHAN_NO_20MHZ = 1<<11, + IEEE80211_CHAN_NO_10MHZ = 1<<12, +}; + +/* needed by mgmt/rlm_domain.c */ +#define IEEE80211_CHAN_NO_HT40 \ + (IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS) + +/* + * needed by + * mgmt/p2p_func.c + * + * enum nl80211_dfs_state - DFS states for channels + * + * Channel states used by the DFS code. + * + * @NL80211_DFS_USABLE: The channel can be used, but channel availability + * check (CAC) must be performed before using it for AP or IBSS. + * @NL80211_DFS_UNAVAILABLE: A radar has been detected on this channel, it + * is therefore marked as not available. + * @NL80211_DFS_AVAILABLE: The channel has been CAC checked and is available. + */ +enum nl80211_dfs_state { + NL80211_DFS_USABLE, + NL80211_DFS_UNAVAILABLE, + NL80211_DFS_AVAILABLE, +}; +/* + * needed by mgmt/rlm_domain.c + * needed by mgmt/p2p_func.c + * enum nl80211_band - Frequency band + * @NL80211_BAND_2GHZ: 2.4 GHz ISM band + * @NL80211_BAND_5GHZ: around 5 GHz band (4.9 - 5.7 GHz) + * @NL80211_BAND_60GHZ: around 60 GHz band (58.32 - 69.12 GHz) + * @NUM_NL80211_BANDS: number of bands, avoid using this in userspace + * since newer kernel versions may support more bands + */ +enum nl80211_band { + NL80211_BAND_2GHZ, + NL80211_BAND_5GHZ, + NL80211_BAND_60GHZ, + NUM_NL80211_BANDS, +}; + +/* + * enum nl80211_initiator - Indicates the initiator of a reg domain request + * @NL80211_REGDOM_SET_BY_CORE: Core queried CRDA for a dynamic world + * regulatory domain. + * @NL80211_REGDOM_SET_BY_USER: User asked the wireless core to set the + * regulatory domain. + * @NL80211_REGDOM_SET_BY_DRIVER: a wireless drivers has hinted to the + * wireless core it thinks its knows the regulatory domain we should be in. + * @NL80211_REGDOM_SET_BY_COUNTRY_IE: the wireless core has received an + * 802.11 country information element with regulatory information it + * thinks we should consider. cfg80211 only processes the country + * code from the IE, and relies on the regulatory domain information + * structure passed by userspace (CRDA) from our wireless-regdb. + * If a channel is enabled but the country code indicates it should + * be disabled we disable the channel and re-enable it upon disassociation. + */ +enum nl80211_reg_initiator { + L80211_REGDOM_SET_BY_CORE, + NL80211_REGDOM_SET_BY_USER, + NL80211_REGDOM_SET_BY_DRIVER, + NL80211_REGDOM_SET_BY_COUNTRY_IE, +}; +/* needed by + * mgmt/rlm_domain.c + * mgmt/cnm.c + * mgmt/p2p_func.c + */ +struct ieee80211_channel { + enum nl80211_band band; + u32 center_freq; + u16 hw_value; + u32 flags; + enum nl80211_dfs_state dfs_state; +}; + +/* + * needed by mgmt/cnm.c + * enum nl80211_chan_width - channel width definitions + * + * These values are used with the %NL80211_ATTR_CHANNEL_WIDTH + * attribute. + * + * @NL80211_CHAN_WIDTH_20_NOHT: 20 MHz, non-HT channel + * @NL80211_CHAN_WIDTH_20: 20 MHz HT channel + * @NL80211_CHAN_WIDTH_40: 40 MHz channel, the %NL80211_ATTR_CENTER_FREQ1 + * attribute must be provided as well + * @NL80211_CHAN_WIDTH_80: 80 MHz channel, the %NL80211_ATTR_CENTER_FREQ1 + * attribute must be provided as well + * @NL80211_CHAN_WIDTH_80P80: 80+80 MHz channel, the %NL80211_ATTR_CENTER_FREQ1 + * and %NL80211_ATTR_CENTER_FREQ2 attributes must be provided as well + * @NL80211_CHAN_WIDTH_160: 160 MHz channel, the %NL80211_ATTR_CENTER_FREQ1 + * attribute must be provided as well + * @NL80211_CHAN_WIDTH_5: 5 MHz OFDM channel + * @NL80211_CHAN_WIDTH_10: 10 MHz OFDM channel + */ +enum nl80211_chan_width { + NL80211_CHAN_WIDTH_20_NOHT, + NL80211_CHAN_WIDTH_20, + NL80211_CHAN_WIDTH_40, + NL80211_CHAN_WIDTH_80, + NL80211_CHAN_WIDTH_80P80, + NL80211_CHAN_WIDTH_160, + NL80211_CHAN_WIDTH_5, + NL80211_CHAN_WIDTH_10, +}; + +/* needed by mgmt/rlm_domain.c */ +struct ieee80211_supported_band { + struct ieee80211_channel *channels; + int n_channels; +}; + +/* + * too many os dependent in regular domain + * on/off fail + */ +#if CFG_SUPPORT_SINGLE_SKU_LOCAL_DB == 1 +/* at leat 7 is needed for regdom_jp */ +#define MAX_NUMER_REG_RULES 7 + +struct ieee80211_power_rule { + u32 max_antenna_gain; + u32 max_eirp; +}; + +struct ieee80211_freq_range { + u32 start_freq_khz; + u32 end_freq_khz; + u32 max_bandwidth_khz; +}; + +struct ieee80211_reg_rule { + struct ieee80211_freq_range freq_range; + struct ieee80211_power_rule power_rule; + u32 flags; /* enum reg_flags */ + u32 dfs_cac_ms; +}; + +struct ieee80211_regdomain { + char alpha2[3]; + u32 n_reg_rules; + enum nl80211_dfs_regions dfs_region; + struct ieee80211_reg_rule reg_rules[MAX_NUMER_REG_RULES]; +}; + +#define MHZ_TO_KHZ(freq) ((freq) * 1000) +#define KHZ_TO_MHZ(freq) ((freq) / 1000) +#define DBI_TO_MBI(gain) ((gain) * 100) +#define MBI_TO_DBI(gain) ((gain) / 100) +#define DBM_TO_MBM(gain) ((gain) * 100) +#define MBM_TO_DBM(gain) ((gain) / 100) + +#define REG_RULE_EXT(start, end, bw, gain, eirp, dfs_cac, reg_flags) \ +{ \ + .freq_range.start_freq_khz = MHZ_TO_KHZ(start), \ + .freq_range.end_freq_khz = MHZ_TO_KHZ(end), \ + .freq_range.max_bandwidth_khz = MHZ_TO_KHZ(bw), \ + .power_rule.max_eirp = DBM_TO_MBM(eirp), \ + .flags = reg_flags, \ + .dfs_cac_ms = dfs_cac, \ +} + +#define REG_RULE(start, end, bw, gain, eirp, reg_flags) \ +{ \ + .freq_range.start_freq_khz = MHZ_TO_KHZ(start), \ + .freq_range.end_freq_khz = MHZ_TO_KHZ(end), \ + .freq_range.max_bandwidth_khz = MHZ_TO_KHZ(bw), \ + .power_rule.max_antenna_gain = DBI_TO_MBI(gain),\ + .power_rule.max_eirp = DBM_TO_MBM(eirp), \ + .flags = reg_flags, \ +} +#endif +/* needed by + * mgmt/rlm_domain.c + * nic/nic_cmd_event.c + */ +struct wiphy { + struct ieee80211_supported_band *bands[NUM_NL80211_BANDS]; +}; + +/* + * needed by include/mgmt/rlm_domain.h & mgmt/rlm_domain.c + * but parameter not used + */ +struct regulatory_request { + enum nl80211_reg_initiator initiator; +}; + +/* needed by mgmt/stats.c */ +struct rtc_time { + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; +}; + +#define NSEC_PER_USEC 1000L + +/* + * needed by + * mgmt/tdls.c + * mgmt/saa_fsm.c, saaFsmSteps + * + * enum nl80211_tdls_operation - values for %NL80211_ATTR_TDLS_OPERATION + * @NL80211_TDLS_DISCOVERY_REQ: Send a TDLS discovery request + * @NL80211_TDLS_SETUP: Setup TDLS link + * @NL80211_TDLS_TEARDOWN: Teardown a TDLS link which is already established + * @NL80211_TDLS_ENABLE_LINK: Enable TDLS link + * @NL80211_TDLS_DISABLE_LINK: Disable TDLS link + */ +enum nl80211_tdls_operation { + NL80211_TDLS_DISCOVERY_REQ, + NL80211_TDLS_SETUP, + NL80211_TDLS_TEARDOWN, + NL80211_TDLS_ENABLE_LINK, + NL80211_TDLS_DISABLE_LINK, +}; + +/* + * needed by mgmt/tdls.c + */ +enum gfp_t { + GFP_KERNEL, + GFP_ATOMIC, + __GFP_HIGHMEM, + __GFP_HIGH +}; + +/* needed by include/nic/adapter.h + * for DIRECT_TX implementation in os folder + */ +struct timer_list { + /* TODO: from the comment in linux/timer.h. Its difficult to implement + * All fields that change during normal runtime grouped to the + * same cacheline + */ +}; + +/* needed by include/nic/adapter.h + * for DIRECT_TX implementation in os folder + */ +struct sk_buff_head { + /* These two members must be first. */ + /* struct sk_buff *next; */ + /* struct sk_buff *prev; */ + uint32_t qlen; +}; + +/* + * should be defined as lock in corresponding os + * access directly by + * nic/nic_tx.c + * nic/nic_rx.c + * nic/que_mgt.c + * + * reference: + * typedef struct spinlock { + * } spinlock_t; + */ +#define spinlock_t uint32_t + +/* + * needed by mgmt/auth.c + * struct cfg80211_ft_event - FT Information Elements + * @ies: FT IEs + * @ies_len: length of the FT IE in bytes + * @target_ap: target AP's MAC address + * @ric_ies: RIC IE + * @ric_ies_len: length of the RIC IE in bytes + */ +struct cfg80211_ft_event_params { + const u8 *ies; + size_t ies_len; + const u8 *target_ap; + const u8 *ric_ies; + size_t ric_ies_len; +}; + +/* + * needed by + * mgmt/cnm.c, which access struct GL_P2P_INFO directly + * mgmt/p2p_func.c, do cnmMemAlloc + * mgmt/p2p_role_fsm.c + * + * struct cfg80211_chan_def - channel definition + * @chan: the (control) channel + * @width: channel width + * @center_freq1: center frequency of first segment + * @center_freq2: center frequency of second segment + * (only with 80+80 MHz) + */ +struct cfg80211_chan_def { + struct ieee80211_channel *chan; + enum nl80211_chan_width width; + u32 center_freq1; + u32 center_freq2; +}; + +/* + * needed by + * mgmt/p2p_scan.c + */ +struct cfg80211_scan_request { +}; + +/* need by include/hal.h, halDeAggRxPktWorker + * comment: use os-related structure directly outside headers of gl layer + * while the implementation is in os/linux/hif* + * possible actions: + * 1) should we just move the function prototype to os gl layer? + */ +struct work_struct { + /* atomic_long_t data; */ + /* struct list_head entry; */ + /* work_func_t func; */ +}; + +/* needed by include/nic/mt66xx_reg.h + * struct mt66xx_chip_info + * comment: use with #if CFG_MTK_ANDROID_WMT + * implementation: extern void connectivity_export_show_stack + * which is outside our driver, but defined in chips/connac* + * should we move to glue layer ? other os can also show StakInfo + */ +struct task_struct { +}; +/* + * TODO: Functions need implementation + */ + +/**************************************************************************** + * TODO: Functions prototype, which could be realized as follows + * 1) inline function + * 2) os API with same functionality + * 3) implemented in gl_dependent.c + **************************************************************************** + */ +/* + * KAL_NEED_IMPLEMENT: wrapper to caution user to implement func when porting + * @file: from which file + * @func: called by which func + * @line: at which line + */ +long KAL_NEED_IMPLEMENT(const char *file, const char *func, int line, ...); + +/* + * kal_dbg_print: print debug message to screen + * + * needed by common/debug.c + * source/include/linux/printk.h + */ +int kal_dbg_print(const char *s, ...); +#define pr_info(fmt, ...) printf(fmt) + +/* + * kal_hex_dump_to_buffer: convert a blob of data to "hex ASCII" in memory + * @buf: data blob to dump + * @len: number of bytes in the @buf + * @rowsize: number of bytes to print per line; must be 16 or 32 + * @groupsize: number of bytes to print at a time (1, 2, 4, 8; default = 1) + * @linebuf: where to put the converted data + * @linebuflen: total size of @linebuf, including space for terminating NUL + * @ascii: include ASCII after the hex output + * + * needed by common/debug.c + * source/include/linux/printk.h + */ +int kal_hex_dump_to_buffer(const void *buf, size_t len, int rowsize, + int groupsize, char *linebuf, size_t linebuflen, + bool ascii); +#define hex_dump_to_buffer(_buf, _len, _rowsize, _groupsize, _linebuf, \ + _linebuflen, _ascii) \ + kal_hex_dump_to_buffer(_buf, _len, _rowsize, _groupsize, _linebuf, \ + _linebuflen, _ascii) + +/* + * purpose: + * polite version of BUG_ON() - WARN_ON() which doesn't + * kill the machine, replace panic() to dump_stack() + * needed by mgmt/rlm_domain.c + */ +void kal_warn_on(uint8_t condition); +#define WARN_ON(_condition) kal_warn_on(_condition) + +/* + * kal_do_gettimeofday - Returns the time of day in a timeval + * @tv: pointer to the timeval to be set + * needed by + * common/debug.c + * mgmt/stats.c + */ +void kal_do_gettimeofday(struct timeval *tv); +#define do_gettimeofday(_tv) kal_do_gettimeofday(_tv) + +/* + * needed by: mgmt/wmm.c + * anything on kalGetTimeTick (?) + * Timespec interfaces utilizing the ktime based ones + * ktime_to_timespec(ktime_get_boottime()); + */ +void kal_get_monotonic_boottime(struct timespec *ts); +#define get_monotonic_boottime(_ts) kal_get_monotonic_boottime(_ts) + +/* + * needed by nic_tx.c + * kal_mod_timer - modify a timer's timeout + * @timer: the timer to be modified + * @expires: new timeout in jiffies + * The function returns whether it has modified a pending timer or not. + * (ie. mod_timer() of an inactive timer returns 0, mod_timer() of an + * active timer returns 1.) + */ +int kal_mod_timer(struct timer_list *timer, unsigned long expires); +#define mod_timer(_timer, _expires) kal_mod_timer(_timer, _expires) + +/* + * kstrto* - convert a string to an * + * @s: The start of the string. The string must be null-terminated, and may also + * include a single newline before its terminating null. The first character + * may also be a plus sign or a minus sign. + * @base: The number base to use. The maximum supported base is 16. If base is + * given as 0, then the base of the string is automatically detected with the + * conventional semantics - If it begins with 0x the number will be parsed as a + * hexadecimal (case insensitive), if it otherwise begins with 0, it will be + * parsed as an octal number. Otherwise it will be parsed as a decimal. + * @res: Where to write the result of the conversion on success. + * + * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error. + * Used as a replacement for the obsolete simple_strtoull. Return code must + * be checked. + */ +int kal_strtoint(const char *s, unsigned int base, int *res); +int kal_strtou8(const char *s, unsigned int base, uint8_t *res); +int kal_strtou16(const char *s, unsigned int base, uint16_t *res); +int kal_strtou32(const char *s, unsigned int base, uint32_t *res); +int kal_strtos32(const char *s, unsigned int base, int32_t *res); + +/* + * kstrtoul - convert a string to an unsigned long + * @s: The start of the string. The string must be null-terminated, and may also + * include a single newline before its terminating null. The first character + * may also be a plus sign, but not a minus sign. + * @base: The number base to use. The maximum supported base is 16. If base is + * given as 0, then the base of the string is automatically detected with the + * conventional semantics - If it begins with 0x the number will be parsed as a + * hexadecimal (case insensitive), if it otherwise begins with 0, it will be + * parsed as an octal number. Otherwise it will be parsed as a decimal. + * @res: Where to write the result of the conversion on success. + * + * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error. + * Used as a replacement for the obsolete simple_strtoull. Return code must + * be checked. + */ +int kal_strtoul(const char *s, unsigned int base, unsigned long *res); + +/* + * scnprintf - Format a string and place it in a buffer + * @buf: The buffer to place the result into + * @size: The size of the buffer, including the trailing null space + * @fmt: The format string to use + * @...: Arguments for the format string + * + * The return value is the number of characters written into @buf not including + * the trailing '\0'. If @size is == 0 the function returns 0. + */ +int kal_scnprintf(char *buf, size_t size, const char *fmt, ...); + +void *kal_kmalloc(size_t size, enum gfp_t type); +void *kal_vmalloc(size_t size); + +void kal_kfree(void *addr); +void kal_vfree(void *addr); +/* + * kal_spin_lock_bh: lock in bottom half, os-dependent + * nic/nic_tx.c + * nic/nic_rx.c + * nic/que_mgt.c + */ +void kal_spin_lock_bh(spinlock_t *lock); +#define spin_lock_bh(_lock) kal_spin_lock_bh(_lock) + +/* + * kal_spin_unlock_bh: unlock in bottom half, os-dependent + * paired with kal_spin_lock_bh + * nic/nic_tx.c + * nic/nic_rx.c + * nic/que_mgt.c + */ +void kal_spin_unlock_bh(spinlock_t *lock); +#define spin_unlock_bh(_lock) kal_spin_unlock_bh(_lock) + +/* + * kal_spin_lock_irqsave: lock exclude irq, os-dependent + * nic/nic_tx.c + * nic/nic_rx.c + * nic/que_mgt.c + */ +void kal_spin_lock_irqsave(spinlock_t *lock, unsigned long flags); +#define spin_lock_irqsave(_lock, _flag) kal_spin_lock_irqsave(_lock, _flag) + +/* + * kal_spin_unlock_irqsave: unlock, os-dependent + * paired with kal_spin_lock_irqsave + * nic/nic_tx.c + * nic/nic_rx.c + * nic/que_mgt.c + */ +void kal_spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags); +#define spin_unlock_irqrestore(_lock, _flag) \ + kal_spin_unlock_irqrestore(_lock, _flag) +/* + * kal_skb_queue_len - get queue length + * @list_: list to measure + * Return the length of an &sk_buff queue. + * + * needed by nic_tx.c + */ +uint32_t kal_skb_queue_len(const struct sk_buff_head *list); +#define skb_queue_len(_list) kal_skb_queue_len(_list) + +/* kal_skb_queue_tail - queue a buffer at the list tail + * @list: list to use + * @newsk: buffer to queue + * Queue a buffer at the end of a list. This function takes no locks + * and you must therefore hold required locks before calling it. + * A buffer cannot be placed on two lists at the same time. + * + * needed by nic_tx.c, what's wrong with struct QUE? + */ +void kal_skb_queue_tail(struct sk_buff_head *list, struct sk_buff *newsk); +#define skb_queue_tail(_list, _newsk) kal_skb_queue_tail(_list, _newsk) + +/* + * skb_put - add data to a buffer + * @skb: buffer to use + * @len: amount of data to add + * This function extends the used data area of the buffer. If this would + * exceed the total buffer size the kernel will panic. A pointer to the + * first byte of the extra data is returned. + * + * needed by nic_rx.c + */ +unsigned char *kal_skb_put(struct sk_buff *skb, unsigned int len); +#define skb_put(_skb, _len) kal_skb_put(_skb, _len) + +/* + * kal_skb_push - add data to the start of a buffer + * @skb: buffer to use + * @len: amount of data to add + * This function extends the used data area of the buffer at the buffer + * start. If this would exceed the total buffer headroom the kernel will + * panic. A pointer to the first byte of the extra data is returned. + * + * needed by nic_tx.c + */ +void *kal_skb_push(struct sk_buff *skb, unsigned int len); +#define skb_push(_skb, _len) kal_skb_push(_skb, _len) + +/* + * needed by nic_tx.c + * __skb_dequeue - remove from the head of the queue + * @list: list to dequeue from + * + * Remove the head of the list. This function does not take any locks + * so must be used with appropriate locks held only. The head item is + * returned or %NULL if the list is empty. + */ +struct sk_buff *kal_skb_dequeue_tail(struct sk_buff_head *list); +#define skb_dequeue(_list) kal_skb_dequeue_tail(_list) + +/* + * needed by nic_tx.c, what's wrong with struct QUE? + * __skb_queue_head - queue a buffer at the list head + * @list: list to use + * @newsk: buffer to queue + * + * Queue a buffer at the start of a list. This function takes no locks + * and you must therefore hold required locks before calling it. + * + * A buffer cannot be placed on two lists at the same time. + */ +void kal_skb_queue_head(struct sk_buff_head *list, struct sk_buff *newsk); +#define skb_queue_head(_list, _newsk) kal_skb_queue_head(_list, _newsk) + +/* + * needed by nic_rx.c + * make the tail pointer in skb point to beginning of data + */ +void kal_skb_reset_tail_pointer(struct sk_buff *skb); +#define skb_reset_tail_pointer(_skb) kal_skb_reset_tail_pointer(_skb) + +/* + * needed by nic_rx.c + * remove end from a buffer + * @len: len of skb after trim + */ +void kal_skb_trim(struct sk_buff *skb, unsigned int len); +#define skb_trim(_skb, _len) kal_skb_trim(_skb, _len) + +/* + * needed by mgmt/tkip_mic.c + * legacy helper around netdev_alloc_skb() + */ +struct sk_buff *kal_dev_alloc_skb(unsigned int length); +#define dev_alloc_skb(_length) kal_dev_alloc_skb(_length) + +/* needed by mgmt/tkip_mic.c */ +void kal_kfree_skb(struct sk_buff *skb); +#define kfree_skb(_skb) kal_kfree_skb(_skb) + +/**************************************************************************** + * TODO: Functions need implementation + **************************************************************************** + */ +/* needed by + * common/debug.c + * common/wlan_lib.c + * mgmt/stats.c + * ais_fsm.c + */ +#define kal_sched_clock() KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#define sched_clock() kal_sched_clock() + +/* looks like min/max not in C + * https://stackoverflow.com/questions/3437404/min-and-max-in-c + * needed by: + * common/debug.c + * mgmt/scan.c + */ +#define min(_a, _b) KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + + +/* needed by mgmt/stats.c */ +#define rtc_time_to_tm(_time, _tm) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +/* implemented: os/linux/gl_wext.c + * used: common/wlan_oid.c, wlanoidSetWapiAssocInfo + * why function called "search WPAIIE" has been implement under wext + * first used in wext_get_scan. Should it be part of wlan_oid? + */ +#if CFG_SUPPORT_WAPI +#define wextSrchDesiredWAPIIE(_pucIEStart, _i4TotalIeLen, \ + _ppucDesiredIE) KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#endif + +/* common/wlan_lib.c */ +#define netdev_priv(_ndev) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _ndev) + +/* + * needed by + * mgmt/rlm_domain.c + * nic/nic_cmd_event.c + */ +#define priv_to_wiphy(_priv) \ +((void *) KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _priv)) + + +/* needed by mgmt/rlm_domain.c + * implementation in linux is in gl_cfg80211.c + * while other operating system may also need to notify reg change + */ +#define mtk_reg_notify(_pWiphy, _pRequest) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +/* needed by mgmt/rlm_domain.c */ +#define regulatory_hint(_wiphy, _alpha2) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +/* needed by mgmt/tdls.c */ +#define cfg80211_tdls_oper_request(_dev, _peer, _oper, \ + _reason_code, _gfp) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +/* + * needed by + * mgmt/p2p_func.c + * + * cfg80211_ch_switch_notify - update wdev channel and notify userspace + * @dev: the device which switched channels + * @chandef: the new channel definition + * + * Caller must acquire wdev_lock, therefore must only be called from sleepable + * driver context! + */ +#define cfg80211_ch_switch_notify(_dev, _chandef) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +/* + * needed by mgmt/rlm.c + */ +#define get_random_bytes(_buf, _nbytes) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +/* + * needed by: nic/nic_cmd_event.c + * 0: no error !0: error + * defeined in include/linux/err.h + */ +#define IS_ERR(_ptr) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +/* + * os endian related, need to find corresponding API in OS + * eg. + * #if __BYTE_ORDER == __BIG_ENDIAN + * #define cpu_to_le16 bswap_16 + * #else + * #define cpu_to_le16 + * #endif + */ +#define cpu_to_le16(_val) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +#define cpu_to_le32(_val) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +#define cpu_to_le64(_val) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +#define le16_to_cpu(_val) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#define le32_to_cpu(_val) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#define le64_to_cpu(_val) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +#define div_u64(_val, _div) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +int kal_test_and_clear_bit(unsigned long bit, unsigned long *p); +#ifndef test_and_clear_bit +#define test_and_clear_bit(_offset, _val) \ + kal_test_and_clear_bit(_offset, _val) +#endif + +void kal_clear_bit(unsigned long bit, unsigned long *p); +#ifndef clear_bit +#define clear_bit(_offset, _val) kal_clear_bit(_offset, _val) +#endif + +/* + * kal_set_bit: set bit atomically + * @nr: bit to set + * @addr: addr to set bit + */ +void kal_set_bit(unsigned long bit, unsigned long *p); +#ifndef set_bit +#define set_bit(_offset, _val) kal_set_bit(_offset, _val) +#endif + +/* needed by mgmt/scan.c */ +int kal_test_bit(unsigned long bit, unsigned long *p); +#ifndef test_bit +#define test_bit(_offset, _val) kal_test_bit(_offset, _val) +#endif +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/include/gl_kal.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/include/gl_kal.h new file mode 100644 index 0000000000000000000000000000000000000000..ffdbb13df622c6b862f3248081d9284e6b9b3e0c --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/include/gl_kal.h @@ -0,0 +1,1984 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: /os/linux/include/gl_kal.h + */ + +/*! \file gl_kal.h + * \brief Declaration of KAL functions - kal*() which is provided + * by GLUE Layer. + * + * Any definitions in this file will be shared among GLUE Layer + * and internal Driver Stack. + */ + +#ifndef _GL_KAL_H +#define _GL_KAL_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "config.h" +#include "gl_os.h" +#include "gl_typedef.h" +#include "gl_wext_priv.h" +#include "link_drv.h" +#include "nic/mac.h" +#include "nic/wlan_def.h" +#include "wlan_lib.h" +#include "wlan_oid.h" + +#if CFG_ENABLE_BT_OVER_WIFI +#include "nic/bow.h" +#endif + +#if DBG +extern int allocatedMemSize; +#endif + +extern int g_u4HaltFlag; +extern int g_u4WlanInitFlag; + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +/* Define how many concurrent operation networks. */ +#define KAL_BSS_NUM 4 + +#define KAL_AIS_NUM 1 + +#if CFG_DUAL_P2PLIKE_INTERFACE +#define KAL_P2P_NUM 2 +#else +#define KAL_P2P_NUM 1 +#endif + +/* Threading */ +#if CFG_SUPPORT_MULTITHREAD +#define GLUE_FLAG_MAIN_PROCESS \ + (GLUE_FLAG_HALT | GLUE_FLAG_SUB_MOD_MULTICAST | \ + GLUE_FLAG_TX_CMD_DONE | GLUE_FLAG_TXREQ | GLUE_FLAG_TIMEOUT | \ + GLUE_FLAG_FRAME_FILTER | GLUE_FLAG_OID | GLUE_FLAG_RX) + +#define GLUE_FLAG_HIF_PROCESS \ + (GLUE_FLAG_HALT | GLUE_FLAG_INT | GLUE_FLAG_HIF_TX | \ + GLUE_FLAG_HIF_TX_CMD | GLUE_FLAG_HIF_FW_OWN | \ + GLUE_FLAG_HIF_PRT_HIF_DBG_INFO | \ + GLUE_FLAG_UPDATE_WMM_QUOTA | \ + GLUE_FLAG_NOTIFY_MD_CRASH) + +#define GLUE_FLAG_RX_PROCESS (GLUE_FLAG_HALT | GLUE_FLAG_RX_TO_OS) +#else +/* All flags for single thread driver */ +#define GLUE_FLAG_TX_PROCESS 0xFFFFFFFF +#endif + +#if CFG_SUPPORT_SNIFFER +#define RADIOTAP_FIELD_TSFT BIT(0) +#define RADIOTAP_FIELD_FLAGS BIT(1) +#define RADIOTAP_FIELD_RATE BIT(2) +#define RADIOTAP_FIELD_CHANNEL BIT(3) +#define RADIOTAP_FIELD_ANT_SIGNAL BIT(5) +#define RADIOTAP_FIELD_ANT_NOISE BIT(6) +#define RADIOTAP_FIELD_ANT BIT(11) +#define RADIOTAP_FIELD_MCS BIT(19) +#define RADIOTAP_FIELD_AMPDU BIT(20) +#define RADIOTAP_FIELD_VHT BIT(21) +#define RADIOTAP_FIELD_VENDOR BIT(30) + +#define RADIOTAP_LEN_VHT 48 +#define RADIOTAP_FIELDS_VHT (RADIOTAP_FIELD_TSFT | \ + RADIOTAP_FIELD_FLAGS | \ + RADIOTAP_FIELD_RATE | \ + RADIOTAP_FIELD_CHANNEL | \ + RADIOTAP_FIELD_ANT_SIGNAL | \ + RADIOTAP_FIELD_ANT_NOISE | \ + RADIOTAP_FIELD_ANT | \ + RADIOTAP_FIELD_AMPDU | \ + RADIOTAP_FIELD_VHT | \ + RADIOTAP_FIELD_VENDOR) + +#define RADIOTAP_LEN_HT 36 +#define RADIOTAP_FIELDS_HT (RADIOTAP_FIELD_TSFT | \ + RADIOTAP_FIELD_FLAGS | \ + RADIOTAP_FIELD_RATE | \ + RADIOTAP_FIELD_CHANNEL | \ + RADIOTAP_FIELD_ANT_SIGNAL | \ + RADIOTAP_FIELD_ANT_NOISE | \ + RADIOTAP_FIELD_ANT | \ + RADIOTAP_FIELD_MCS | \ + RADIOTAP_FIELD_AMPDU | \ + RADIOTAP_FIELD_VENDOR) + +#define RADIOTAP_LEN_LEGACY 26 +#define RADIOTAP_FIELDS_LEGACY (RADIOTAP_FIELD_TSFT | \ + RADIOTAP_FIELD_FLAGS | \ + RADIOTAP_FIELD_RATE | \ + RADIOTAP_FIELD_CHANNEL | \ + RADIOTAP_FIELD_ANT_SIGNAL | \ + RADIOTAP_FIELD_ANT_NOISE | \ + RADIOTAP_FIELD_ANT | \ + RADIOTAP_FIELD_VENDOR) +#endif + +/* performance monitor feature */ +#define PERF_MON_INIT_BIT (0) +#define PERF_MON_DISABLE_BIT (1) +#define PERF_MON_STOP_BIT (2) +#define PERF_MON_RUNNING_BIT (3) + +#define PERF_MON_UPDATE_INTERVAL (1000) +#define PERF_MON_TP_MAX_THRESHOLD (10) + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +/* Lock for process */ +enum ENUM_SPIN_LOCK_CATEGORY_E { + SPIN_LOCK_FSM = 0, + +#if CFG_SUPPORT_MULTITHREAD + SPIN_LOCK_TX_PORT_QUE, + SPIN_LOCK_TX_CMD_QUE, + SPIN_LOCK_TX_CMD_DONE_QUE, + SPIN_LOCK_TC_RESOURCE, + SPIN_LOCK_RX_TO_OS_QUE, +#endif + + /* FIX ME */ + SPIN_LOCK_RX_QUE, + SPIN_LOCK_RX_FREE_QUE, + SPIN_LOCK_TX_QUE, + SPIN_LOCK_CMD_QUE, + SPIN_LOCK_TX_RESOURCE, + SPIN_LOCK_CMD_RESOURCE, + SPIN_LOCK_QM_TX_QUEUE, + SPIN_LOCK_CMD_PENDING, + SPIN_LOCK_CMD_SEQ_NUM, + SPIN_LOCK_TX_MSDU_INFO_LIST, + SPIN_LOCK_TXING_MGMT_LIST, + SPIN_LOCK_TX_SEQ_NUM, + SPIN_LOCK_TX_COUNT, + SPIN_LOCK_TXS_COUNT, + /* end */ + SPIN_LOCK_TX, + /* TX/RX Direct : BEGIN */ + SPIN_LOCK_TX_DIRECT, + SPIN_LOCK_RX_DIRECT, + SPIN_LOCK_RX_DIRECT_REORDER, + /* TX/RX Direct : END */ + SPIN_LOCK_IO_REQ, + SPIN_LOCK_INT, + SPIN_LOCK_UPDATE_WMM_QUOTA, + + SPIN_LOCK_MGT_BUF, + SPIN_LOCK_MSG_BUF, + SPIN_LOCK_STA_REC, + + SPIN_LOCK_MAILBOX, + SPIN_LOCK_TIMER, + + /* SPIN_LOCK_BOW_TABLE,*/ + + SPIN_LOCK_EHPI_BUS, /* only for EHPI */ + SPIN_LOCK_NET_DEV, + SPIN_LOCK_NUM +}; + +enum ENUM_MUTEX_CATEGORY_E { + MUTEX_TX_CMD_CLEAR, + MUTEX_TX_DATA_DONE_QUE, + MUTEX_DEL_INF, + MUTEX_CHIP_RST, + MUTEX_SET_OWN, + MUTEX_BOOST_CPU, + MUTEX_NUM +}; + +/* event for assoc information update */ +struct EVENT_ASSOC_INFO { + uint8_t ucAssocReq; /* 1 for assoc req, 0 for assoc rsp */ + uint8_t ucReassoc; /* 0 for assoc, 1 for reassoc */ + uint16_t u2Length; + uint8_t *pucIe; +}; + +/* network type */ +enum ENUM_KAL_NETWORK_TYPE_INDEX { + KAL_NETWORK_TYPE_AIS_INDEX = 0, +#if CFG_ENABLE_WIFI_DIRECT + KAL_NETWORK_TYPE_P2P_INDEX, +#endif +#if CFG_ENABLE_BT_OVER_WIFI + KAL_NETWORK_TYPE_BOW_INDEX, +#endif + KAL_NETWORK_TYPE_INDEX_NUM +}; + +/* malloc type */ +enum ENUM_KAL_MEM_ALLOCATION_TYPE_E { + PHY_MEM_TYPE, /* physically continuous */ + VIR_MEM_TYPE, /* virtually continuous */ + MEM_TYPE_NUM +}; + +/* suspend/resume related */ +#define KAL_WAKE_LOCK_T uint32_t + +/* TODO: unknown feature */ +#if CFG_SUPPORT_AGPS_ASSIST +enum ENUM_MTK_AGPS_ATTR { + MTK_ATTR_AGPS_INVALID, + MTK_ATTR_AGPS_CMD, + MTK_ATTR_AGPS_DATA, + MTK_ATTR_AGPS_IFINDEX, + MTK_ATTR_AGPS_IFNAME, + MTK_ATTR_AGPS_MAX +}; + +enum ENUM_AGPS_EVENT { + AGPS_EVENT_WLAN_ON, + AGPS_EVENT_WLAN_OFF, + AGPS_EVENT_WLAN_AP_LIST, +}; +u_int8_t kalIndicateAgpsNotify(struct ADAPTER *prAdapter, + uint8_t cmd, + uint8_t *data, uint16_t dataLen); +#endif /* CFG_SUPPORT_AGPS_ASSIST */ + +#if CFG_SUPPORT_SNIFFER +/* Vendor Namespace + * Bit Number 30 + * Required Alignment 2 bytes + */ +struct RADIOTAP_FIELD_VENDOR_ { + uint8_t aucOUI[3]; + uint8_t ucSubNamespace; + uint16_t u2DataLen; + uint8_t ucData; +} __KAL_ATTRIB_PACKED__; + +struct MONITOR_RADIOTAP { + /* radiotap header */ + uint8_t ucItVersion; /* set to 0 */ + uint8_t ucItPad; + uint16_t u2ItLen; /* entire length */ + uint32_t u4ItPresent; /* fields present */ + + /* TSFT + * Bit Number 0 + * Required Alignment 8 bytes + * Unit microseconds + */ + uint64_t u8MacTime; + + /* Flags + * Bit Number 1 + */ + uint8_t ucFlags; + + /* Rate + * Bit Number 2 + * Unit 500 Kbps + */ + uint8_t ucRate; + + /* Channel + * Bit Number 3 + * Required Alignment 2 bytes + */ + uint16_t u2ChFrequency; + uint16_t u2ChFlags; + + /* Antenna signal + * Bit Number 5 + * Unit dBm + */ + uint8_t ucAntennaSignal; + + /* Antenna noise + * Bit Number 6 + * Unit dBm + */ + uint8_t ucAntennaNoise; + + /* Antenna + * Bit Number 11 + * Unit antenna index + */ + uint8_t ucAntenna; + + /* MCS + * Bit Number 19 + * Required Alignment 1 byte + */ + uint8_t ucMcsKnown; + uint8_t ucMcsFlags; + uint8_t ucMcsMcs; + + /* A-MPDU status + * Bit Number 20 + * Required Alignment 4 bytes + */ + uint32_t u4AmpduRefNum; + uint16_t u2AmpduFlags; + uint8_t ucAmpduDelimiterCRC; + uint8_t ucAmpduReserved; + + /* VHT + * Bit Number 21 + * Required Alignment 2 bytes + */ + uint16_t u2VhtKnown; + uint8_t ucVhtFlags; + uint8_t ucVhtBandwidth; + uint8_t aucVhtMcsNss[4]; + uint8_t ucVhtCoding; + uint8_t ucVhtGroupId; + uint16_t u2VhtPartialAid; + + /* extension space */ + uint8_t aucReserve[12]; +} __KAL_ATTRIB_PACKED__; +#endif + +/* driver halt */ +struct KAL_HALT_CTRL_T { +/* TODO: os-related */ +#if 0 + struct semaphore lock; + struct task_struct *owner; +#endif + u_int8_t fgHalt; + u_int8_t fgHeldByKalIoctl; + OS_SYSTIME u4HoldStart; +}; + +struct KAL_THREAD_SCHEDSTATS { + /* when marked: the profiling start time(ms), + * when unmarked: total duration(ms) + */ + unsigned long long time; + /* time spent in exec (sum_exec_runtime) */ + unsigned long long exec; + /* time spent in run-queue while not being scheduled (wait_sum) */ + unsigned long long runnable; + /* time spent waiting for I/O (iowait_sum) */ + unsigned long long iowait; +}; + +enum ENUM_CMD_TX_RESULT { + CMD_TX_RESULT_SUCCESS, + CMD_TX_RESULT_FAILED, + CMD_TX_RESULT_QUEUED, + CMD_TX_RESULT_NUM +}; + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ +/* os-related: need implementation */ +#define KAL_SET_BIT(bitOffset, value) set_bit(bitOffset, &value) +#define KAL_CLR_BIT(bitOffset, value) clear_bit(bitOffset, &value) +#define KAL_TEST_AND_CLEAR_BIT(bitOffset, value) \ + test_and_clear_bit(bitOffset, &value) +#define KAL_TEST_BIT(bitOffset, value) test_bit(bitOffset, &value) +#define SUSPEND_FLAG_FOR_WAKEUP_REASON (0) +#define SUSPEND_FLAG_CLEAR_WHEN_RESUME (1) + + +/*----------------------------------------------------------------------------*/ +/* Macros of getting current thread id */ +/*----------------------------------------------------------------------------*/ +/* TODO: os-related: need implementation */ +#define KAL_GET_CURRENT_THREAD_ID() (0) +#define KAL_GET_CURRENT_THREAD_NAME() ("n/a") + +/*----------------------------------------------------------------------------*/ +/* Macros of SPIN LOCK operations for using in Driver Layer */ +/*----------------------------------------------------------------------------*/ +#define KAL_SPIN_LOCK_DECLARATION() unsigned long __ulFlags + +#define KAL_ACQUIRE_SPIN_LOCK(_prAdapter, _rLockCategory) \ + kalAcquireSpinLock(((struct ADAPTER *)_prAdapter)->prGlueInfo, \ + _rLockCategory, &__ulFlags) + +#define KAL_RELEASE_SPIN_LOCK(_prAdapter, _rLockCategory) \ + kalReleaseSpinLock(((struct ADAPTER *)_prAdapter)->prGlueInfo, \ + _rLockCategory, __ulFlags) + +/*----------------------------------------------------------------------------*/ +/* Macros of MUTEX operations for using in Driver Layer */ +/*----------------------------------------------------------------------------*/ +#define KAL_ACQUIRE_MUTEX(_prAdapter, _rLockCategory) \ + kalAcquireMutex(((struct ADAPTER *)_prAdapter)->prGlueInfo, \ + _rLockCategory) + +#define KAL_RELEASE_MUTEX(_prAdapter, _rLockCategory) \ + kalReleaseMutex(((struct ADAPTER *)_prAdapter)->prGlueInfo, \ + _rLockCategory) + +/*----------------------------------------------------------------------------*/ +/* Macros for accessing Reserved Fields of native packet */ +/*----------------------------------------------------------------------------*/ +#define KAL_GET_PKT_QUEUE_ENTRY(_p) GLUE_GET_PKT_QUEUE_ENTRY(_p) +#define KAL_GET_PKT_DESCRIPTOR(_prQueueEntry) \ + GLUE_GET_PKT_DESCRIPTOR(_prQueueEntry) +#define KAL_GET_PKT_TID(_p) GLUE_GET_PKT_TID(_p) +#define KAL_GET_PKT_IS1X(_p) GLUE_GET_PKT_IS1X(_p) +#define KAL_GET_PKT_HEADER_LEN(_p) GLUE_GET_PKT_HEADER_LEN(_p) +#define KAL_GET_PKT_PAYLOAD_LEN(_p) GLUE_GET_PKT_PAYLOAD_LEN(_p) +#define KAL_GET_PKT_ARRIVAL_TIME(_p) GLUE_GET_PKT_ARRIVAL_TIME(_p) + +/*----------------------------------------------------------------------------*/ +/* Macros for kernel related defines */ +/*----------------------------------------------------------------------------*/ +/* TODO: os-related: need implementation */ +#define IEEE80211_CHAN_PASSIVE_FLAG (0) +#define IEEE80211_CHAN_PASSIVE_STR "PASSIVE" + +/** + * enum nl80211_band - Frequency band + * @NL80211_BAND_2GHZ: 2.4 GHz ISM band + * @NL80211_BAND_5GHZ: around 5 GHz band (4.9 - 5.7 GHz) + * @NL80211_BAND_60GHZ: around 60 GHz band (58.32 - 64.80 GHz) + * @NUM_NL80211_BANDS: number of bands, avoid using this in userspace + * since newer kernel versions may support more bands + */ +#define KAL_BAND_2GHZ (0) +#define KAL_BAND_5GHZ (1) +#define KAL_NUM_BANDS (2) + +/** + * enum nl80211_reg_rule_flags - regulatory rule flags + * @NL80211_RRF_NO_OFDM: OFDM modulation not allowed + * @NL80211_RRF_AUTO_BW: maximum available bandwidth should be calculated + * base on contiguous rules and wider channels will be allowed to cross + * multiple contiguous/overlapping frequency ranges. + * @NL80211_RRF_DFS: DFS support is required to be used + */ +#define KAL_RRF_NO_OFDM (0) +#define KAL_RRF_DFS (1) +#define KAL_RRF_AUTO_BW 0 + +/** + * kalCfg80211ScanDone - abstraction of cfg80211_scan_done + * + * @request: the corresponding scan request (sanity checked by callers!) + * @aborted: set to true if the scan was aborted for any reason, + * userspace will be notified of that + * + * Since linux-4.8.y the 2nd parameter is changed from bool to + * struct cfg80211_scan_info, but we don't use all fields yet. + */ +#define kalCfg80211ScanDone(_request, aborted) + +/* Consider on some Android platform, using request_firmware_direct() + * may cause system failed to load firmware. So we still use + * request_firmware(). + */ +#define REQUEST_FIRMWARE(_fw, _name, _dev) + +/*----------------------------------------------------------------------------*/ +/* Macros of wake_lock operations for using in Driver Layer */ +/*----------------------------------------------------------------------------*/ +#define KAL_WAKE_LOCK_INIT(_prAdapter, _prWakeLock, _pcName) +#define KAL_WAKE_LOCK_DESTROY(_prAdapter, _prWakeLock) +#define KAL_WAKE_LOCK(_prAdapter, _prWakeLock) +#define KAL_WAKE_LOCK_TIMEOUT(_prAdapter, _prWakeLock, _u4Timeout) +#define KAL_WAKE_UNLOCK(_prAdapter, _prWakeLock) +#define KAL_WAKE_LOCK_ACTIVE(_prAdapter, _prWakeLock) + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Cache memory allocation + * + * \param[in] u4Size Required memory size. + * \param[in] eMemType Memory allocation type + * + * \return Pointer to allocated memory + * or NULL + */ +/*----------------------------------------------------------------------------*/ +#define kmalloc(_size, _type) kal_kmalloc(_size, _type) +#define vmalloc(_size) kal_vmalloc(_size) +#define in_interrupt() (FALSE) +#define kfree(_addr) kal_kfree(_addr) +#define vfree(_addr) kal_vfree(_addr) + +#if DBG +#define kalMemAlloc(u4Size, eMemType) ({ \ + void *pvAddr; \ + if (eMemType == PHY_MEM_TYPE) { \ + if (in_interrupt()) \ + pvAddr = kmalloc(u4Size, GFP_ATOMIC); \ + else \ + pvAddr = kmalloc(u4Size, GFP_KERNEL); \ + } \ + else { \ + pvAddr = vmalloc(u4Size); \ + } \ + if (pvAddr) { \ + allocatedMemSize += u4Size; \ + DBGLOG(INIT, INFO, "0x%p(%ld) allocated (%s:%s)\n", \ + pvAddr, (uint32_t)u4Size, __FILE__, __func__); \ + } \ + pvAddr; \ +}) +#else +#define kalMemAlloc(u4Size, eMemType) ({ \ + void *pvAddr; \ + if (eMemType == PHY_MEM_TYPE) { \ + if (in_interrupt()) \ + pvAddr = kmalloc(u4Size, GFP_ATOMIC); \ + else \ + pvAddr = kmalloc(u4Size, GFP_KERNEL); \ + } \ + else { \ + pvAddr = vmalloc(u4Size); \ + } \ + if (!pvAddr) \ + ASSERT_NOMEM(); \ + pvAddr; \ +}) +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Free allocated cache memory + * + * \param[in] pvAddr Required memory size. + * \param[in] eMemType Memory allocation type + * \param[in] u4Size Allocated memory size. + * + * \return - + */ +/*----------------------------------------------------------------------------*/ +#if DBG +#define kalMemFree(pvAddr, eMemType, u4Size) \ +{ \ + if (pvAddr) { \ + allocatedMemSize -= u4Size; \ + DBGLOG(INIT, INFO, "0x%p(%ld) freed (%s:%s)\n", \ + pvAddr, (uint32_t)u4Size, __FILE__, __func__); \ + } \ + if (eMemType == PHY_MEM_TYPE) { \ + kfree(pvAddr); \ + } \ + else { \ + vfree(pvAddr); \ + } \ +} +#else +#define kalMemFree(pvAddr, eMemType, u4Size) \ +{ \ + if (eMemType == PHY_MEM_TYPE) { \ + kfree(pvAddr); \ + } \ + else { \ + vfree(pvAddr); \ + } \ +} +#endif + +#define kalUdelay(u4USec) KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#define kalMdelay(u4MSec) KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#define kalMsleep(u4MSec) KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#define kalUsleep_range(u4MinUSec, u4MaxUSec) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +/* Copy memory from user space to kernel space */ +#define kalMemCopyFromUser(_pvTo, _pvFrom, _u4N) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +/* Copy memory from kernel space to user space */ +#define kalMemCopyToUser(_pvTo, _pvFrom, _u4N) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +/* Copy memory block with specific size */ +#define kalMemCopy(pvDst, pvSrc, u4Size) \ + memcpy(pvDst, pvSrc, u4Size) + +/* Set memory block with specific pattern */ +#define kalMemSet(pvAddr, ucPattern, u4Size) \ + memset(pvAddr, ucPattern, u4Size) + +/* Compare two memory block with specific length. + * Return zero if they are the same. + */ +#define kalMemCmp(pvAddr1, pvAddr2, u4Size) \ + memcmp(pvAddr1, pvAddr2, u4Size) + +/* Zero specific memory block */ +#define kalMemZero(pvAddr, u4Size) \ + memset(pvAddr, 0, u4Size) + +/* Move memory block with specific size */ +#define kalMemMove(pvDst, pvSrc, u4Size) \ + memmove(pvDst, pvSrc, u4Size) + +#define strnicmp(s1, s2, n) KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +/* string operation */ +#define kalStrCpy(dest, src) strcpy(dest, src) +#define kalStrnCpy(dest, src, n) strncpy(dest, src, n) +#define kalStrCmp(ct, cs) strcmp(ct, cs) +#define kalStrnCmp(ct, cs, n) strncmp(ct, cs, n) +#define kalStrChr(s, c) strchr(s, c) +#define kalStrrChr(s, c) strrchr(s, c) +#define kalStrnChr(s, n, c) strnchr(s, n, c) +#define kalStrLen(s) strlen(s) +#define kalStrnLen(s, b) strnlen(s, b) +#define kalStrniCmp(ct, cs, n) strncasecmp(ct, cs, n) +/* #define kalStrtoul(cp, endp, base) simple_strtoul(cp, endp, base) */ +/* #define kalStrtol(cp, endp, base) simple_strtol(cp, endp, base) */ +#define kalkStrtou8(cp, base, resp) kal_strtou8(cp, base, resp) +#define kalkStrtou16(cp, base, resp) kal_strtou16(cp, base, resp) +#define kalkStrtou32(cp, base, resp) kal_strtou32(cp, base, resp) +#define kalkStrtos32(cp, base, resp) kal_strtos32(cp, base, resp) +#define kalSnprintf(buf, size, fmt, ...) \ + snprintf(buf, size, fmt, ##__VA_ARGS__) +#define kalScnprintf(buf, size, fmt, ...) \ + kal_scnprintf(buf, size, fmt, ##__VA_ARGS__) +#define kalSprintf(buf, fmt, ...) sprintf(buf, fmt, __VA_ARGS__) +/* remove for AOSP */ +/* #define kalSScanf(buf, fmt, ...) sscanf(buf, fmt, __VA_ARGS__) */ +#define kalStrStr(ct, cs) strstr(ct, cs) +#define kalStrSep(s, ct) strsep(s, ct) +#define kalStrCat(dest, src) strcat(dest, src) +#define kalIsXdigit(c) isxdigit(c) +#define kalStrtoint(_data, _base, _res) kal_strtoint(_data, _base, _res) +#define kalStrtoul(_data, _base, _res) kal_strtoul(_data, _base, _res) +#define kalStrtokR(_buf, _tok, _saved) \ + strtok_r((char *)_buf, _tok, (char **)_saved) +/* implementation for no op API */ +int8_t kal_atoi(uint8_t ch); +#define kalAtoi(_ch) KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +/* defined for wince sdio driver only */ +#if defined(_HIF_SDIO) +#define kalDevSetPowerState(prGlueInfo, ePowerMode) \ + glSetPowerState(prGlueInfo, ePowerMode) +#else +#define kalDevSetPowerState(prGlueInfo, ePowerMode) +#endif + +/*----------------------------------------------------------------------------*/ +/*! + * \brief Notify OS with SendComplete event of the specific packet. + * Linux should free packets here. + * + * \param[in] prGlueInfo Pointer of GLUE Data Structure + * \param[in] pvPacket Pointer of Packet Handle + * \param[in] status Status Code for OS upper layer + * + * \return - + */ +/*----------------------------------------------------------------------------*/ +#define kalSendComplete(prGlueInfo, pvPacket, status) \ + kalSendCompleteAndAwakeQueue(prGlueInfo, pvPacket) + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is used to locate the starting address of incoming + * ethernet frame for skb. + * + * \param[in] prGlueInfo Pointer of GLUE Data Structure + * \param[in] pvPacket Pointer of Packet Handle + * + * \return starting address of ethernet frame buffer. + */ +/*----------------------------------------------------------------------------*/ +#define kalQueryBufferPointer(prGlueInfo, pvPacket) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is used to query the length of valid buffer which is + * accessible during port read/write. + * + * \param[in] prGlueInfo Pointer of GLUE Data Structure + * \param[in] pvPacket Pointer of Packet Handle + * + * \return starting address of ethernet frame buffer. + */ +/*----------------------------------------------------------------------------*/ +#define kalQueryValidBufferLength(prGlueInfo, pvPacket) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +/*----------------------------------------------------------------------------*/ +/*! + * \brief This function is used to copy the entire frame from skb to the + * destination address in the input parameter. + * + * \param[in] prGlueInfo Pointer of GLUE Data Structure + * \param[in] pvPacket Pointer of Packet Handle + * \param[in] pucDestBuffer Destination Address + * + * \return - + */ +/*----------------------------------------------------------------------------*/ +#define kalCopyFrame(prGlueInfo, pvPacket, pucDestBuffer) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +#define kalGetTimeTick() KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +#define WLAN_TAG "[wlan]" +#define kalPrint(_Fmt...) printf(WLAN_TAG _Fmt) +#define kalPrintLimited(_Fmt...) printf(WLAN_TAG _Fmt) + +#define kalBreakPoint() \ +do { \ + DBGLOG(INIT, ERROR, "WARN_ON()"); \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__); \ +} while (0) + +#if CFG_ENABLE_AEE_MSG +#else +#define kalSendAeeException(_module, _desc, ...) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#define kalSendAeeWarning(_module, _desc, ...) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#define kalSendAeeReminding(_module, _desc, ...) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#endif + +#define PRINTF_ARG(...) __VA_ARGS__ +#define SPRINTF(buf, arg) {buf += sprintf((char *)(buf), PRINTF_ARG arg); } + +#define USEC_TO_SYSTIME(_usec) ((_usec) / USEC_PER_MSEC) +#define MSEC_TO_SYSTIME(_msec) (_msec) + +#define MSEC_TO_JIFFIES(_msec) KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +#define KAL_TIME_INTERVAL_DECLARATION() uint32_t timeval __rTs, __rTe +#define KAL_REC_TIME_START() do_gettimeofday(&__rTs) +#define KAL_REC_TIME_END() do_gettimeofday(&__rTe) +#define KAL_GET_TIME_INTERVAL() \ + ((SEC_TO_USEC(__rTe.tv_sec) + __rTe.tv_usec) - \ + (SEC_TO_USEC(__rTs.tv_sec) + __rTs.tv_usec)) +#define KAL_ADD_TIME_INTERVAL(_Interval) \ + { \ + (_Interval) += KAL_GET_TIME_INTERVAL(); \ + } + +/* TODO: os-related HIF should we move to os/xxx/hif/include? */ +#if defined(_HIF_PCIE) +#define KAL_DMA_TO_DEVICE PCI_DMA_TODEVICE +#define KAL_DMA_FROM_DEVICE PCI_DMA_FROMDEVICE + +#define KAL_DMA_ALLOC_COHERENT(_dev, _size, _handle) \ +KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +#define KAL_DMA_FREE_COHERENT(_dev, _size, _addr, _handle) \ +KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +#define KAL_DMA_MAP_SINGLE(_dev, _ptr, _size, _dir) \ +KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +#define KAL_DMA_UNMAP_SINGLE(_dev, _addr, _size, _dir) \ +KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +#define KAL_DMA_MAPPING_ERROR(_dev, _addr) \ +KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#else +#define KAL_DMA_TO_DEVICE DMA_TO_DEVICE +#define KAL_DMA_FROM_DEVICE DMA_FROM_DEVICE + +#define KAL_DMA_ALLOC_COHERENT(_dev, _size, _handle) \ +KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +#define KAL_DMA_FREE_COHERENT(_dev, _size, _addr, _handle) \ +KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +#define KAL_DMA_MAP_SINGLE(_dev, _ptr, _size, _dir) \ +KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +#define KAL_DMA_UNMAP_SINGLE(_dev, _addr, _size, _dir) \ +KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +#define KAL_DMA_MAPPING_ERROR(_dev, _addr) \ +KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#endif + +#if defined(_HIF_AXI) +#define KAL_ARCH_SETUP_DMA_OPS(_dev, _base, _size, _iommu, _coherent) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#else +#define KAL_ARCH_SETUP_DMA_OPS(_dev, _base, _size, _iommu, _coherent) +#endif + +/*----------------------------------------------------------------------------*/ +/* Macros of show stack operations for using in Driver Layer */ +/*----------------------------------------------------------------------------*/ +#define kal_show_stack(_adapter, _task, _sp) + +/*----------------------------------------------------------------------------*/ +/* Macros of systrace operations for using in Driver Layer */ +/*----------------------------------------------------------------------------*/ +#define kalTraceBegin(_fmt, ...) +#define kalTraceEnd() +#define kalTraceInt(_value, _fmt, ...) +#define kalTraceCall() +#define kalTraceEvent(_fmt, ...) +#define TRACE(_expr, _fmt, ...) _expr + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +/*----------------------------------------------------------------------------*/ +/* Routines in gl_kal.c */ +/*----------------------------------------------------------------------------*/ +#ifdef CFG_REMIND_IMPLEMENT +#define kalAcquireSpinLock(_pr, _rLockCate, _plFlags) \ +KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _pr, _rLockCate, _plFlags) + +#define kalReleaseSpinLock(_prGlueInfo, _rLockCategory, _ulFlags) \ +KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalUpdateMACAddress(_prGlueInfo, _pucMacAddr) \ +KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo, _pucMacAddr) + +#define kalAcquireMutex(_prGlueInfo, _rMutexCategory) \ +KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo, _rMutexCategory) + +#define kalReleaseMutex(_prGlueInfo, _rMutexCategory) \ +KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo, _rMutexCategory) + +#define kalPacketFree(_prGlueInfo, _pvPacket) \ +KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo, _pvPacket) + +#define kalPacketAlloc(_prGlueInfo, _u4Size, _ppucData) \ +((void *) KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo)) + +#define kalPacketAllocWithHeadroom(_prGlueInfo, _u4Size, _ppucData) \ +((void *) KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo)) +#else +void kalAcquireSpinLock(IN struct GLUE_INFO *prGlueInfo, + IN enum ENUM_SPIN_LOCK_CATEGORY_E rLockCategory, + OUT unsigned long *plFlags); + +void kalReleaseSpinLock(IN struct GLUE_INFO *prGlueInfo, + IN enum ENUM_SPIN_LOCK_CATEGORY_E rLockCategory, + IN unsigned long ulFlags); + +void kalUpdateMACAddress(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t *pucMacAddr); + +void kalAcquireMutex(IN struct GLUE_INFO *prGlueInfo, + IN enum ENUM_MUTEX_CATEGORY_E rMutexCategory); + +void kalReleaseMutex(IN struct GLUE_INFO *prGlueInfo, + IN enum ENUM_MUTEX_CATEGORY_E rMutexCategory); + +void kalPacketFree(IN struct GLUE_INFO *prGlueInfo, + IN void *pvPacket); + +void *kalPacketAlloc(IN struct GLUE_INFO *prGlueInfo, + IN uint32_t u4Size, + OUT uint8_t **ppucData); + +void *kalPacketAllocWithHeadroom(IN struct GLUE_INFO + *prGlueInfo, + IN uint32_t u4Size, OUT uint8_t **ppucData); +#endif + +void kalOsTimerInitialize(IN struct GLUE_INFO *prGlueInfo, + IN void *prTimerHandler); + +u_int8_t kalSetTimer(IN struct GLUE_INFO *prGlueInfo, + IN OS_SYSTIME rInterval); + +#ifdef CFG_REMIND_IMPLEMENT +#define kalProcessRxPacket(_prGlueInfo, _pvPacket, _pucPacketStart, \ + _u4PacketLen, _fgIsRetain, _aeCSUM) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) +#else +uint32_t +kalProcessRxPacket(IN struct GLUE_INFO *prGlueInfo, + IN void *pvPacket, + IN uint8_t *pucPacketStart, IN uint32_t u4PacketLen, + /* IN PBOOLEAN pfgIsRetain, */ + IN u_int8_t fgIsRetain, IN enum ENUM_CSUM_RESULT aeCSUM[]); +#endif + +uint32_t kalRxIndicatePkts(IN struct GLUE_INFO *prGlueInfo, + IN void *apvPkts[], + IN uint8_t ucPktNum); + +#ifdef CFG_REMIND_IMPLEMENT +#define kalRxIndicateOnePkt(_prGlueInfo, _pvPkt) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +#define kalIndicateStatusAndComplete(_prGlInfo, _eStatus, _pvBuf, _u4BufLen, \ + _ucBssIndex) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +#define kalUpdateReAssocReqInfo(_prGlueInfo, _pucFrameBody, _u4FrameBodyLen, \ + _fgReassocRequest, _ucBssIndex) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +#define kalUpdateReAssocRspInfo(_prGlueInfo, _pucFrameBody, _u4FrameBodyLen, \ + _ucBssIndex) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#else +uint32_t kalRxIndicateOnePkt(IN struct GLUE_INFO + *prGlueInfo, IN void *pvPkt); + +void +kalIndicateStatusAndComplete(IN struct GLUE_INFO + *prGlueInfo, + IN uint32_t eStatus, IN void *pvBuf, + IN uint32_t u4BufLen, + IN uint8_t ucBssIndex); + +void +kalUpdateReAssocReqInfo(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t *pucFrameBody, IN uint32_t u4FrameBodyLen, + IN u_int8_t fgReassocRequest, + IN uint8_t ucBssIndex); + +void kalUpdateReAssocRspInfo(IN struct GLUE_INFO + *prGlueInfo, + IN uint8_t *pucFrameBody, + IN uint32_t u4FrameBodyLen, + IN uint8_t ucBssIndex); +#endif + +#if CFG_TX_FRAGMENT +u_int8_t +kalQueryTxPacketHeader(IN struct GLUE_INFO *prGlueInfo, + IN void *pvPacket, OUT uint16_t *pu2EtherTypeLen, + OUT uint8_t *pucEthDestAddr); +#endif /* CFG_TX_FRAGMENT */ + +#ifdef CFG_REMIND_IMPLEMENT +#define kalSendCompleteAndAwakeQueue(_prGlueInfo, _pvPacket) \ +KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo, _pvPacket) +#else +void kalSendCompleteAndAwakeQueue(IN struct GLUE_INFO + *prGlueInfo, + IN void *pvPacket); +#endif + +#if CFG_TCP_IP_CHKSUM_OFFLOAD +#ifdef CFG_REMIND_IMPLEMENT +#define kalQueryTxChksumOffloadParam(_pvPacket, _pucFlag) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#else +void kalQueryTxChksumOffloadParam(IN void *pvPacket, + OUT uint8_t *pucFlag); +#endif + +void kalUpdateRxCSUMOffloadParam(IN void *pvPacket, + IN enum ENUM_CSUM_RESULT eCSUM[]); +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ + +#ifdef CFG_REMIND_IMPLEMENT +#define kalRetrieveNetworkAddress(_prGlueInfo, _prMacAddr) \ +KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo, _prMacAddr) + +#define kalReadyOnChannel(_prGlueInfo, _u8Cookie, _eBand, _eSco, \ + _ucChannelNum, _u4DurationMs, _ucBssIndex) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalRemainOnChannelExpired(_prGlueInfo, _u8Cookie, _eBand, \ + _eSco, _ucChannelNum, _ucBssIndex) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#if CFG_SUPPORT_DFS +#define kalIndicateChannelSwitch(_prGlueInfo, _eSco, _ucChannelNum) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) +#endif + + +#define kalIndicateMgmtTxStatus(_prGlueInfo, _u8Cookie, _fgIsAck, \ + _pucFrameBuf, _u4FrameLen, _ucBssIndex) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalIndicateRxMgmtFrame(_prGlueInfo, _prSwRfb, _ucBssIndex) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) +#else +u_int8_t kalRetrieveNetworkAddress(IN struct GLUE_INFO *prGlueInfo, + IN OUT uint8_t *prMacAddr); + +void +kalReadyOnChannel(IN struct GLUE_INFO *prGlueInfo, + IN uint64_t u8Cookie, + IN enum ENUM_BAND eBand, IN enum ENUM_CHNL_EXT eSco, + IN uint8_t ucChannelNum, IN uint32_t u4DurationMs, + IN uint8_t ucBssIndex); + +void +kalRemainOnChannelExpired(IN struct GLUE_INFO *prGlueInfo, + IN uint64_t u8Cookie, IN enum ENUM_BAND eBand, + IN enum ENUM_CHNL_EXT eSco, IN uint8_t ucChannelNum, + IN uint8_t ucBssIndex); + +#if CFG_SUPPORT_DFS +void +kalIndicateChannelSwitch(IN struct GLUE_INFO *prGlueInfo, + IN enum ENUM_CHNL_EXT eSco, + IN uint8_t ucChannelNum); +#endif + +void +kalIndicateMgmtTxStatus(IN struct GLUE_INFO *prGlueInfo, + IN uint64_t u8Cookie, IN u_int8_t fgIsAck, + IN uint8_t *pucFrameBuf, IN uint32_t u4FrameLen, + IN uint8_t ucBssIndex); + +void kalIndicateRxMgmtFrame(IN struct GLUE_INFO *prGlueInfo, + IN struct SW_RFB *prSwRfb, + IN uint8_t ucBssIndex); +#endif +/*----------------------------------------------------------------------------*/ +/* Routines in interface - ehpi/sdio.c */ +/*----------------------------------------------------------------------------*/ +#ifdef CFG_REMIND_IMPLEMENT +#define kalDevRegRead(_prGlueInfo, _u4Register, _pu4Value) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) +#else +u_int8_t kalDevRegRead(IN struct GLUE_INFO *prGlueInfo, + IN uint32_t u4Register, + OUT uint32_t *pu4Value); +#endif +u_int8_t kalDevRegRead_mac(IN struct GLUE_INFO *prGlueInfo, + IN uint32_t u4Register, OUT uint32_t *pu4Value); + +#ifdef CFG_REMIND_IMPLEMENT +#define kalDevRegWrite(_prGlueInfo, _u4Register, _u4Value) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) +#else +u_int8_t kalDevRegWrite(struct GLUE_INFO *prGlueInfo, + IN uint32_t u4Register, + IN uint32_t u4Value); +#endif +u_int8_t kalDevRegWrite_mac(struct GLUE_INFO *prGlueInfo, + IN uint32_t u4Register, IN uint32_t u4Value); + +u_int8_t +kalDevPortRead(IN struct GLUE_INFO *prGlueInfo, + IN uint16_t u2Port, IN uint32_t u2Len, OUT uint8_t *pucBuf, + IN uint32_t u2ValidOutBufSize); + +u_int8_t +kalDevPortWrite(struct GLUE_INFO *prGlueInfo, + IN uint16_t u2Port, IN uint32_t u2Len, IN uint8_t *pucBuf, + IN uint32_t u2ValidInBufSize); + +#ifdef CFG_REMIND_IMPLEMENT +#define kalDevWriteData(_prGlueInfo, _prMsduInfo) \ +KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalDevWriteCmd(_prGlueInfo, _prCmdInfo, _ucTC) \ +KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalDevKickData(_prGlueInfo) \ +KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) +#else +u_int8_t kalDevWriteData(IN struct GLUE_INFO *prGlueInfo, + IN struct MSDU_INFO *prMsduInfo); +enum ENUM_CMD_TX_RESULT kalDevWriteCmd(IN struct GLUE_INFO *prGlueInfo, + IN struct CMD_INFO *prCmdInfo, IN uint8_t ucTC); +u_int8_t kalDevKickData(IN struct GLUE_INFO *prGlueInfo); +#endif +void kalDevReadIntStatus(IN struct ADAPTER *prAdapter, + OUT uint32_t *pu4IntStatus); + +u_int8_t kalDevWriteWithSdioCmd52(IN struct GLUE_INFO + *prGlueInfo, + IN uint32_t u4Addr, IN uint8_t ucData); + +#if CFG_SUPPORT_EXT_CONFIG +uint32_t kalReadExtCfg(IN struct GLUE_INFO *prGlueInfo); +#endif + +#ifdef CFG_REMIND_IMPLEMENT +#define kalQoSFrameClassifierAndPacketInfo(_pr, _prPacket, _prTxPktInfo) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _pr) + +#define kalGetEthDestAddr(_prGlueInfo, _prPacket, _pucEthDestAddr) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalOidComplete(_prGlueInfo, _fgSetQuery, _u4SetQueryInfoLen, \ + _rOidStatus) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalIoctl(_pr, _pfnOidHandler, _pvInfoBuf, _u4InfoBufLen, \ + _fgRead, _fgWaitResp, _fgCmd, _pu4QryInfoLen) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _pr, \ + _pfnOidHandler, _pvInfoBuf, _u4InfoBufLen, \ + _fgRead, _fgWaitResp, _fgCmd, _pu4QryInfoLen) + +#define kalIoctlByBssIdx(_pr, _pfnOidHandler, _pvInfoBuf, _u4InfoBufLen, \ + _fgRead, _fgWaitResp, _fgCmd, _pu4QryInfoLen, _ucBssIndex) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _pr, \ + _pfnOidHandler, _pvInfoBuf, _u4InfoBufLen, \ + _fgRead, _fgWaitResp, _fgCmd, _pu4QryInfoLen, _ucBssIndex) + +#define SET_IOCTL_BSSIDX(_pr, _ucBssIndex) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _pr, \ + _ucBssIndex) + +#define GET_IOCTL_BSSIDX(_pr) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _pr) + +#else +u_int8_t +kalQoSFrameClassifierAndPacketInfo(IN struct GLUE_INFO + *prGlueInfo, + IN void *prPacket, + OUT struct TX_PACKET_INFO *prTxPktInfo); + +u_int8_t kalGetEthDestAddr(IN struct GLUE_INFO *prGlueInfo, + IN void *prPacket, + OUT uint8_t *pucEthDestAddr); + +void +kalOidComplete(IN struct GLUE_INFO *prGlueInfo, + IN u_int8_t fgSetQuery, IN uint32_t u4SetQueryInfoLen, + IN uint32_t rOidStatus); + +uint32_t +kalIoctl(IN struct GLUE_INFO *prGlueInfo, + IN PFN_OID_HANDLER_FUNC pfnOidHandler, + IN void *pvInfoBuf, + IN uint32_t u4InfoBufLen, IN u_int8_t fgRead, + IN u_int8_t fgWaitResp, + IN u_int8_t fgCmd, OUT uint32_t *pu4QryInfoLen); + +uint32_t +kalIoctlByBssIdx(IN struct GLUE_INFO *prGlueInfo, + IN PFN_OID_HANDLER_FUNC pfnOidHandler, + IN void *pvInfoBuf, + IN uint32_t u4InfoBufLen, IN u_int8_t fgRead, + IN u_int8_t fgWaitResp, IN u_int8_t fgCmd, + OUT uint32_t *pu4QryInfoLen, + IN uint8_t ucBssIndex); + +void SET_IOCTL_BSSIDX( + IN struct ADAPTER *prAdapter, + IN uint8_t ucBssIndex); + +uint8_t GET_IOCTL_BSSIDX( + IN struct ADAPTER *prAdapter); + +#endif + +void kalHandleAssocInfo(IN struct GLUE_INFO *prGlueInfo, + IN struct EVENT_ASSOC_INFO *prAssocInfo); + +#if CFG_ENABLE_FW_DOWNLOAD +#ifdef CFG_REMIND_IMPLEMENT +#define kalFirmwareImageMapping(_prGlueInfo, _ppvMapFileBuf, \ + _pu4FileLength, _eDlIdx) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalFirmwareImageUnmapping(_prGlueInfo, _prFwHandle, _pvMapFileBuf) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) +#else +void *kalFirmwareImageMapping(IN struct GLUE_INFO + *prGlueInfo, + OUT void **ppvMapFileBuf, + OUT uint32_t *pu4FileLength, + IN enum ENUM_IMG_DL_IDX_T eDlIdx); +void kalFirmwareImageUnmapping(IN struct GLUE_INFO + *prGlueInfo, + IN void *prFwHandle, IN void *pvMapFileBuf); +#endif +#endif + +/*----------------------------------------------------------------------------*/ +/* Card Removal Check */ +/*----------------------------------------------------------------------------*/ +#ifdef CFG_REMIND_IMPLEMENT +#define kalIsCardRemoved(_prGlueInfo) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) +#else +u_int8_t kalIsCardRemoved(IN struct GLUE_INFO *prGlueInfo); +#endif +/*----------------------------------------------------------------------------*/ +/* TX */ +/*----------------------------------------------------------------------------*/ +#ifdef CFG_REMIND_IMPLEMENT +#define kalFlushPendingTxPackets(_prGlueInfo) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) +#else +void kalFlushPendingTxPackets(IN struct GLUE_INFO + *prGlueInfo); +#endif + +/*----------------------------------------------------------------------------*/ +/* Media State Indication */ +/*----------------------------------------------------------------------------*/ +#ifdef CFG_REMIND_IMPLEMENT +#define kalGetMediaStateIndicated(_prGlueInfo, _ucBssIndex) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalSetMediaStateIndicated(_prGlueInfo, _eParamMediaStateIndicate, \ + _ucBssIndex) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) +#else +enum ENUM_PARAM_MEDIA_STATE kalGetMediaStateIndicated( + IN struct GLUE_INFO + *prGlueInfo, + IN uint8_t ucBssIndex); + +void kalSetMediaStateIndicated(IN struct GLUE_INFO *prGlueInfo, + IN enum ENUM_PARAM_MEDIA_STATE eParamMediaStateIndicate, + IN uint8_t ucBssIndex); +#endif + +/*----------------------------------------------------------------------------*/ +/* OID handling */ +/*----------------------------------------------------------------------------*/ +#ifdef CFG_REMIND_IMPLEMENT +#define kalOidCmdClearance(_prGlueInfo) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalOidClearance(_prGlueInfo) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalEnqueueCommand(_prGlueInfo, _prQueueEntry) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) +#else +void kalOidCmdClearance(IN struct GLUE_INFO *prGlueInfo); + +void kalOidClearance(IN struct GLUE_INFO *prGlueInfo); + +void kalEnqueueCommand(IN struct GLUE_INFO *prGlueInfo, + IN struct QUE_ENTRY *prQueueEntry); +#endif + +#if CFG_ENABLE_BT_OVER_WIFI +/*----------------------------------------------------------------------------*/ +/* Bluetooth over Wi-Fi handling */ +/*----------------------------------------------------------------------------*/ +void kalIndicateBOWEvent(IN struct GLUE_INFO *prGlueInfo, + IN struct BT_OVER_WIFI_EVENT *prEvent); + +enum ENUM_BOW_DEVICE_STATE kalGetBowState( + IN struct GLUE_INFO *prGlueInfo, + IN uint8_t rPeerAddr[PARAM_MAC_ADDR_LEN]); + +u_int8_t kalSetBowState(IN struct GLUE_INFO *prGlueInfo, + IN enum ENUM_BOW_DEVICE_STATE eBowState, + uint8_t rPeerAddr[PARAM_MAC_ADDR_LEN]); + +enum ENUM_BOW_DEVICE_STATE kalGetBowGlobalState( + IN struct GLUE_INFO + *prGlueInfo); + +uint32_t kalGetBowFreqInKHz(IN struct GLUE_INFO + *prGlueInfo); + +uint8_t kalGetBowRole(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t rPeerAddr[PARAM_MAC_ADDR_LEN]); + +void kalSetBowRole(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRole, + IN uint8_t rPeerAddr[PARAM_MAC_ADDR_LEN]); + +uint8_t kalGetBowAvailablePhysicalLinkCount( + IN struct GLUE_INFO *prGlueInfo); + +#if CFG_BOW_SEPARATE_DATA_PATH +/*----------------------------------------------------------------------------*/ +/* Bluetooth over Wi-Fi Net Device Init/Uninit */ +/*----------------------------------------------------------------------------*/ +u_int8_t kalInitBowDevice(IN struct GLUE_INFO *prGlueInfo, + IN const char *prDevName); + +u_int8_t kalUninitBowDevice(IN struct GLUE_INFO + *prGlueInfo); +#endif /* CFG_BOW_SEPARATE_DATA_PATH */ +#endif /* CFG_ENABLE_BT_OVER_WIFI */ + +/*----------------------------------------------------------------------------*/ +/* Security Frame Clearance */ +/*----------------------------------------------------------------------------*/ +#ifdef CFG_REMIND_IMPLEMENT +#define kalClearSecurityFrames(_prGlueInfo) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalClearSecurityFramesByBssIdx(_prGlueInfo, _ucBssIndex) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalSecurityFrameSendComplete(_prGlueInfo, _pvPacket, _rStatus) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) +#else +void kalClearSecurityFrames(IN struct GLUE_INFO + *prGlueInfo); + +void kalClearSecurityFramesByBssIdx(IN struct GLUE_INFO + *prGlueInfo, + IN uint8_t ucBssIndex); + +void kalSecurityFrameSendComplete(IN struct GLUE_INFO + *prGlueInfo, + IN void *pvPacket, IN uint32_t rStatus); +#endif +/*----------------------------------------------------------------------------*/ +/* Management Frame Clearance */ +/*----------------------------------------------------------------------------*/ +#ifdef CFG_REMIND_IMPLEMENT +#define kalClearMgmtFrames(_prGlueInfo) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalClearMgmtFramesByBssIdx(_prGlueInfo, _ucBssIndex) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalGetTxPendingFrameCount(_prGlueInfo) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalGetTxPendingCmdCount(_prGlueInfo) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalClearCommandQueue(_prGlueInfo) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalSetTimer(_prGlueInfo, _u4Interval) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) +#else +void kalClearMgmtFrames(IN struct GLUE_INFO *prGlueInfo); + +void kalClearMgmtFramesByBssIdx(IN struct GLUE_INFO + *prGlueInfo, + IN uint8_t ucBssIndex); + +uint32_t kalGetTxPendingFrameCount(IN struct GLUE_INFO + *prGlueInfo); + +uint32_t kalGetTxPendingCmdCount(IN struct GLUE_INFO + *prGlueInfo); + +void kalClearCommandQueue(IN struct GLUE_INFO *prGlueInfo); + +u_int8_t kalSetTimer(IN struct GLUE_INFO *prGlueInfo, + IN uint32_t u4Interval); +#endif + +u_int8_t kalCancelTimer(IN struct GLUE_INFO *prGlueInfo); + +#ifdef CFG_REMIND_IMPLEMENT +#define kalScanDone(_prGlueInfo, _eNetTypeIdx, _status) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) +#else +void kalScanDone(IN struct GLUE_INFO *prGlueInfo, + IN enum ENUM_KAL_NETWORK_TYPE_INDEX eNetTypeIdx, + IN uint32_t status); +#endif + +#if CFG_SUPPORT_SCAN_CACHE_RESULT +uint8_t kalUpdateBssTimestamp(IN struct GLUE_INFO *prGlueInfo); +#endif /* CFG_SUPPORT_SCAN_CACHE_RESULT */ + +void kalTimeoutHandler(unsigned long arg); + +#ifdef CFG_REMIND_IMPLEMENT +#define kalRandomNumber() KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +#define kalSetEvent(_pr) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _pr) + +#define kalSetIntEvent(_pr) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _pr) + +#define kalSetWmmUpdateEvent(_pr) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _pr) + +#define kalSetMdCrashEvent(_pr) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _pr) + +#define kalSetHifDbgEvent(_pr) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _pr) +#else +uint32_t kalRandomNumber(void); + +void kalSetEvent(struct GLUE_INFO *pr); + +void kalSetIntEvent(struct GLUE_INFO *pr); + +void kalSetWmmUpdateEvent(struct GLUE_INFO *pr); + +void kalSetMdCrashEvent(struct GLUE_INFO *pr); + +void kalSetHifDbgEvent(struct GLUE_INFO *pr); +#endif + +#if CFG_SUPPORT_MULTITHREAD +#ifdef CFG_REMIND_IMPLEMENT +#define kalSetTxEvent2Hif(_pr) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _pr) + +#define kalSetTxEvent2Rx(_pr) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _pr) + +#define kalSetTxCmdEvent2Hif(_pr) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _pr) +#define kalSetTxCmdDoneEvent(_pr) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _pr) + +#define kalSetRxProcessEvent(_pr) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _pr) +#else +void kalSetTxEvent2Hif(struct GLUE_INFO *pr); + +void kalSetTxEvent2Rx(struct GLUE_INFO *pr); + +void kalSetTxCmdEvent2Hif(struct GLUE_INFO *pr); + +void kalSetTxCmdDoneEvent(struct GLUE_INFO *pr); + +void kalSetRxProcessEvent(struct GLUE_INFO *pr); +#endif +#endif +/*----------------------------------------------------------------------------*/ +/* NVRAM/Registry Service */ +/*----------------------------------------------------------------------------*/ +#ifdef CFG_REMIND_IMPLEMENT +#define kalIsConfigurationExist(_prGlueInfo) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalGetConfiguration(_prGlueInfo) \ +((struct REG_INFO *)KAL_NEED_IMPLEMENT(__FILE__, __func__, \ + __LINE__, _prGlueInfo)) + +#define kalCfgDataRead16(_prGlueInfo, _u4Offset, _pu2Data) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalCfgDataWrite16(_prGlueInfo, _u4Offset, _u2Data) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) +#else +u_int8_t kalIsConfigurationExist(IN struct GLUE_INFO + *prGlueInfo); + +struct REG_INFO *kalGetConfiguration(IN struct GLUE_INFO + *prGlueInfo); + +u_int8_t kalCfgDataRead(IN struct GLUE_INFO *prGlueInfo, + IN uint32_t u4Offset, + IN ssize_t len, OUT uint16_t *pu2Data); + +u_int8_t kalCfgDataRead16(IN struct GLUE_INFO *prGlueInfo, + IN uint32_t u4Offset, + OUT uint16_t *pu2Data); + +u_int8_t kalCfgDataWrite16(IN struct GLUE_INFO *prGlueInfo, + IN uint32_t u4Offset, IN uint16_t u2Data); +#endif +/*----------------------------------------------------------------------------*/ +/* WSC Connection */ +/*----------------------------------------------------------------------------*/ +#ifdef CFG_REMIND_IMPLEMENT +#define kalWSCGetActiveState(_prGlueInfo) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) +#else +u_int8_t kalWSCGetActiveState(IN struct GLUE_INFO + *prGlueInfo); +#endif + +/*----------------------------------------------------------------------------*/ +/* RSSI Updating */ +/*----------------------------------------------------------------------------*/ +#ifdef CFG_REMIND_IMPLEMENT +#define kalUpdateRSSI(_prGlueInfo, _ucBssIndex, _cRssi, _cLinkQuality) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) +#else +void +kalUpdateRSSI(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucBssIndex, + IN int8_t cRssi, + IN int8_t cLinkQuality); +#endif + +/*----------------------------------------------------------------------------*/ +/* I/O Buffer Pre-allocation */ +/*----------------------------------------------------------------------------*/ +u_int8_t kalInitIOBuffer(u_int8_t is_pre_alloc); + +void kalUninitIOBuffer(void); + +#ifdef CFG_REMIND_IMPLEMENT +#define kalAllocateIOBuffer(_u4AllocSize) \ +((uint8_t *) KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__)) + +#define kalReleaseIOBuffer(_pvAddr, _u4Size) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#else +void *kalAllocateIOBuffer(IN uint32_t u4AllocSize); + +void kalReleaseIOBuffer(IN void *pvAddr, + IN uint32_t u4Size); +#endif + +void +kalGetChannelList(IN struct GLUE_INFO *prGlueInfo, + IN enum ENUM_BAND eSpecificBand, + IN uint8_t ucMaxChannelNum, IN uint8_t *pucNumOfChannel, + IN struct RF_CHANNEL_INFO *paucChannelList); + +u_int8_t kalIsAPmode(IN struct GLUE_INFO *prGlueInfo); + +#if CFG_SUPPORT_802_11W +/*----------------------------------------------------------------------------*/ +/* 802.11W */ +/*----------------------------------------------------------------------------*/ +#ifdef CFG_REMIND_IMPLEMENT +#define kalGetMfpSetting(_prGlueInfo, _ucBssIndex) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#define kalGetRsnIeMfpCap(_prGlueInfo, _ucBssIndex) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#else +uint32_t kalGetMfpSetting(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucBssIndex); +uint8_t kalGetRsnIeMfpCap(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucBssIndex); +#endif +#endif + +/*----------------------------------------------------------------------------*/ +/* file opetation */ +/*----------------------------------------------------------------------------*/ +#ifdef CFG_REMIND_IMPLEMENT +#define kalWriteToFile(_pucPath, _fgDoAppend, _pucData, _u4Size) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +#define kalCheckPath(_pucPath) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +#define kalTrunkPath(_pucPath) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +#define kalReadToFile(_pucPath, _pucData, _u4Size, _pu4ReadSize) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +/* used only under os folder */ +#define kalRequestFirmware(_pucPath, _pucData, _u4Size, _pu4ReadSize, _dev) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#else +uint32_t kalWriteToFile(const uint8_t *pucPath, + u_int8_t fgDoAppend, + uint8_t *pucData, uint32_t u4Size); + +uint32_t kalCheckPath(const uint8_t *pucPath); + +uint32_t kalTrunkPath(const uint8_t *pucPath); + +int32_t kalReadToFile(const uint8_t *pucPath, + uint8_t *pucData, + uint32_t u4Size, uint32_t *pu4ReadSize); + +/* used only under os folder */ +int32_t kalRequestFirmware(const uint8_t *pucPath, + uint8_t *pucData, + uint32_t u4Size, uint32_t *pu4ReadSize, + void *dev); +#endif +/*----------------------------------------------------------------------------*/ +/* NL80211 */ +/*----------------------------------------------------------------------------*/ +#ifdef CFG_REMIND_IMPLEMENT +#define kalIndicateBssInfo(_prGlueInfo, _pucFrameBuf, _u4BufLen, \ + _ucChannelNum, _i4SignalStrength) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) +#else +void +kalIndicateBssInfo(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t *pucFrameBuf, IN uint32_t u4BufLen, + IN uint8_t ucChannelNum, IN int32_t i4SignalStrength); +#endif +/*----------------------------------------------------------------------------*/ +/* Net device */ +/*----------------------------------------------------------------------------*/ +#ifdef CFG_REMIND_IMPLEMENT +#define kalHardStartXmit(_prSkb, _prDev, _prGlueInfo, _ucBssIndex) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +#define kalIsPairwiseEapolPacket(_prPacket) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +#define kalGetIPv4Address(_prDev, _u4MaxNumOfAddr, _pucIpv4Addrs, \ + _pu4NumOfIpv4Addr) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +#if IS_ENABLED(CONFIG_IPV6) +#define kalGetIPv6Address(_prDev, _u4MaxNumOfAddr, _pucIpv6Addrs, \ + _pu4NumOfIpv6Addr) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#endif /* IS_ENABLED(CONFIG_IPV6) */ + +#define kalSetNetAddressFromInterface(_prGlueInfo, _prDev, _fgSet) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +#define kalResetStats(_prDev) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +#define kalGetStats(_prDev) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#else +uint32_t +kalHardStartXmit(struct sk_buff *prSkb, + IN struct net_device *prDev, + struct GLUE_INFO *prGlueInfo, uint8_t ucBssIndex); + +u_int8_t kalIsPairwiseEapolPacket(IN void *prPacket); + +u_int8_t +kalGetIPv4Address(IN struct net_device *prDev, + IN uint32_t u4MaxNumOfAddr, OUT uint8_t *pucIpv4Addrs, + OUT uint32_t *pu4NumOfIpv4Addr); + +#if IS_ENABLED(CONFIG_IPV6) +u_int8_t +kalGetIPv6Address(IN struct net_device *prDev, + IN uint32_t u4MaxNumOfAddr, OUT uint8_t *pucIpv6Addrs, + OUT uint32_t *pu4NumOfIpv6Addr); +#else +static inline u_int8_t +kalGetIPv6Address(IN struct net_device *prDev, + IN uint32_t u4MaxNumOfAddr, OUT uint8_t *pucIpv6Addrs, + OUT uint32_t *pu4NumOfIpv6Addr) { + /* Not support IPv6 */ + *pu4NumOfIpv6Addr = 0; + return 0; +} +#endif /* IS_ENABLED(CONFIG_IPV6) */ + +void kalSetNetAddressFromInterface(IN struct GLUE_INFO + *prGlueInfo, + IN struct net_device *prDev, + IN u_int8_t fgSet); + +uint32_t kalResetStats(IN struct net_device *prDev); + +void *kalGetStats(IN struct net_device *prDev); +#endif + +void kalResetPacket(IN struct GLUE_INFO *prGlueInfo, + IN void *prPacket); + +#if CFG_SUPPORT_QA_TOOL +#ifdef CFG_REMIND_IMPLEMENT +#define kalFileOpen(_path, _flags, _rights) \ +((void *) KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__)) + +#define kalFileClose(_file) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +#define kalFileRead(_file, _offset, _data, _size) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#else +struct file *kalFileOpen(const char *path, int flags, + int rights); + +void kalFileClose(struct file *file); + +uint32_t kalFileRead(struct file *file, + unsigned long long offset, + unsigned char *data, unsigned int size); +#endif +#endif + +#if CFG_SUPPORT_SDIO_READ_WRITE_PATTERN +/*----------------------------------------------------------------------------*/ +/* SDIO Read/Write Pattern Support */ +/*----------------------------------------------------------------------------*/ +#ifdef CFG_REMIND_IMPLEMENT +#define kalSetSdioTestPattern(_prGlueInfo, _fgEn, _fgRead) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) +#else +u_int8_t kalSetSdioTestPattern(IN struct GLUE_INFO + *prGlueInfo, + IN u_int8_t fgEn, IN u_int8_t fgRead); +#endif +#endif + +/*----------------------------------------------------------------------------*/ +/* PNO Support */ +/*----------------------------------------------------------------------------*/ +#ifdef CFG_REMIND_IMPLEMENT +#define kalSchedScanResults(_prGlueInfo) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalSchedScanStopped(_prGlueInfo, _fgDriverTriggerd) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalSetFwOwnEvent2Hif(_pr) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _pr) +#else +void kalSchedScanResults(IN struct GLUE_INFO *prGlueInfo); + +void kalSchedScanStopped(IN struct GLUE_INFO *prGlueInfo, + u_int8_t fgDriverTriggerd); + +void kalSetFwOwnEvent2Hif(struct GLUE_INFO *pr); +#endif + +#if CFG_ASSERT_DUMP +#ifdef CFG_REMIND_IMPLEMENT +#define kalOpenCorDumpFile(_fgIsN9) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#define kalWriteCorDumpFile(_pucBuffer, _u2Size, _fgIsN9) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#define kalCloseCorDumpFile(_fgIsN9) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#else +/* Core Dump out put file */ +uint32_t kalOpenCorDumpFile(u_int8_t fgIsN9); +uint32_t kalWriteCorDumpFile(uint8_t *pucBuffer, + uint16_t u2Size, + u_int8_t fgIsN9); +uint32_t kalCloseCorDumpFile(u_int8_t fgIsN9); +#endif +#endif +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#if CFG_WOW_SUPPORT +#ifdef CFG_REMIND_IMPLEMENT +#define kalWowInit(_glueinfo) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#define kalWowProcess(_glueinfo, _enable) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#else +void kalWowInit(IN struct GLUE_INFO *prGlueInfo); +void kalWowProcess(IN struct GLUE_INFO *prGlueInfo, + uint8_t enable); +#endif +#endif + +int main_thread(void *data); + +#if CFG_SUPPORT_MULTITHREAD +int hif_thread(void *data); +int rx_thread(void *data); +#endif + +#ifdef CFG_REMIND_IMPLEMENT +#define kalGetBootTime() KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#else +uint64_t kalGetBootTime(void); +#endif + +int kalMetInitProcfs(IN struct GLUE_INFO *prGlueInfo); +int kalMetRemoveProcfs(void); + +uint8_t kalGetEapolKeyType(void *prPacket); + +#if CFG_SUPPORT_WAKEUP_REASON_DEBUG +#ifdef CFG_REMIND_IMPLEMENT +#define kalIsWakeupByWlan(_prAdapter) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#else +u_int8_t kalIsWakeupByWlan(struct ADAPTER *prAdapter); +#endif +#endif + +int32_t kalHaltLock(uint32_t waitMs); +int32_t kalHaltTryLock(void); +void kalHaltUnlock(void); +void kalSetHalted(u_int8_t fgHalt); +u_int8_t kalIsHalted(void); + +#ifdef CFG_REMIND_IMPLEMENT +#define kalFreeTxMsduWorker(_work) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#else +void kalFreeTxMsduWorker(struct work_struct *work); +#endif +void kalFreeTxMsdu(struct ADAPTER *prAdapter, + struct MSDU_INFO *prMsduInfo); + +int32_t kalPerMonInit(IN struct GLUE_INFO *prGlueInfo); +int32_t kalPerMonDisable(IN struct GLUE_INFO *prGlueInfo); +int32_t kalPerMonEnable(IN struct GLUE_INFO *prGlueInfo); +#ifdef CFG_REMIND_IMPLEMENT +#define kalPerMonStart(_prGlueInfo) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) +#else +int32_t kalPerMonStart(IN struct GLUE_INFO *prGlueInfo); +#endif +int32_t kalPerMonStop(IN struct GLUE_INFO *prGlueInfo); +int32_t kalPerMonDestroy(IN struct GLUE_INFO *prGlueInfo); +void kalPerMonHandler(IN struct ADAPTER *prAdapter, + unsigned long ulParam); +uint32_t kalPerMonGetInfo(IN struct ADAPTER *prAdapter, + IN uint8_t *pucBuf, + IN uint32_t u4Max); +int32_t kalBoostCpu(IN struct ADAPTER *prAdapter, + IN uint32_t u4TarPerfLevel, + IN uint32_t u4BoostCpuTh); +int32_t kalCheckTputLoad(IN struct ADAPTER *prAdapter, + IN uint32_t u4CurrPerfLevel, + IN uint32_t u4TarPerfLevel, + IN int32_t i4Pending, + IN uint32_t u4Used); +void kalSetRpsMap(IN struct GLUE_INFO *glue, IN unsigned long value); +#if CFG_MTK_ANDROID_EMI +void kalSetEmiMpuProtection(phys_addr_t emiPhyBase, uint32_t offset, + uint32_t size, bool enable); +void kalSetDrvEmiMpuProtection(phys_addr_t emiPhyBase, uint32_t offset, + uint32_t size); +#endif +int32_t kalSetCpuNumFreq(uint32_t u4CoreNum, + uint32_t u4Freq); +int32_t kalPerMonSetForceEnableFlag(uint8_t uFlag); +int32_t kalFbNotifierReg(IN struct GLUE_INFO *prGlueInfo); +void kalFbNotifierUnReg(void); + +#ifdef CFG_REMIND_IMPLEMENT +#define kalInitDevWakeup(_prAdapter, _prDev) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#else +void kalInitDevWakeup(struct ADAPTER *prAdapter, struct device *prDev); +#endif + +#ifdef CFG_REMIND_IMPLEMENT +#define kalIsValidMacAddr(_addr) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +#define kalScanParseRandomMac(_prdev, prRrequest, _pucRandomMac) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +#define kalSchedScanParseRandomMac(_prdev, prRrequest, _pucRandomMac \ + , _pucRandomMacMask) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +#define kalScanReqLog(prRrequest) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#define kalScanResultLog(_prAdapter, _prMgmt) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#else +u_int8_t kalIsValidMacAddr(const uint8_t *addr); + +u_int8_t kalScanParseRandomMac(const struct net_device *ndev, + const struct cfg80211_scan_request *request, uint8_t *pucRandomMac); + +u_int8_t kalSchedScanParseRandomMac(const struct net_device *ndev, + const struct cfg80211_sched_scan_request *request, + uint8_t *pucRandomMac, uint8_t *pucRandomMacMask); + +void kalScanReqLog(struct cfg80211_scan_request *request); +void kalScanResultLog(struct ADAPTER *prAdapter, struct ieee80211_mgmt *mgmt); +#endif +void kalScanLogCacheFlushBSS(struct ADAPTER *prAdapter, + const uint16_t logBufLen); + +#ifdef CFG_REMIND_IMPLEMENT +#define kalMaskMemCmp(_cs, _ct, _mask, _count) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +#define kalChannelScoSwitch(_channel_type, _prChnlSco) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +#define kalChannelFormatSwitch(_prChannel_def, _prChannel \ + , _prRfChnlInfo) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +#define kalRemoveBss(_prGlueInfo, \ + _aucBSSID, _ucChannelNum, \ + _eBand) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +#define kalIsResetting(_void) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#else +int kalMaskMemCmp(const void *cs, const void *ct, + const void *mask, size_t count); + +u_int8_t +kalChannelScoSwitch(IN enum nl80211_channel_type channel_type, + IN enum ENUM_CHNL_EXT *prChnlSco); + +u_int8_t +kalChannelFormatSwitch(IN struct cfg80211_chan_def *channel_def, + IN struct ieee80211_channel *channel, + IN struct RF_CHANNEL_INFO *prRfChnlInfo); + +void kalRemoveBss(struct GLUE_INFO *prGlueInfo, + uint8_t aucBSSID[], + uint8_t ucChannelNum, + enum ENUM_BAND eBand); + +u_int8_t kalIsResetting(void); +#endif + +#if CFG_CHIP_RESET_SUPPORT +void kalRemoveProbe(IN struct GLUE_INFO *prGlueInfo); +#endif + +#endif /* _GL_KAL_H */ + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/include/gl_os.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/include/gl_os.h new file mode 100644 index 0000000000000000000000000000000000000000..b10ba44e2b5854b8a4f08065f873f2af59fea3f8 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/include/gl_os.h @@ -0,0 +1,1279 @@ + +/******************************************************************************* + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ +/*! \file gl_os.h + * \brief List the external reference to OS for GLUE Layer. + * + * In this file we define the data structure - GLUE_INFO_T to store those + * objects + * we acquired from OS - e.g. TIMER, SPINLOCK, NET DEVICE ... . And all the + * external reference (header file, extern func() ..) to OS for GLUE Layer + * should also list down here. + * For porting to new OS, the API listed in this file needs to be + * implemented + */ + + +#ifndef _GL_OS_H +#define _GL_OS_H + +/* Standard C, for implementation on differenct OS + * the following include files needs to be refined + */ +/* types */ +#include +#include "sys/types.h" + +/* bool type */ +#include + +/* memory operation */ +#include + +/* networking */ +#include + +/* offsetof series */ +#include + +/* sprintf series */ +#include + +/* error code */ +#include +#include + +/* va_* series */ +#include + +/* for INT_MAX for some reason include fail not checked */ +#if 0 +/* when there is platform specific toolchain + * there should be this file + * eg. gcc-arm-none-eabi/arm-none-eabi/include/limits.h + */ +#include +#else +/* Minimum and maximum values a `signed int' can hold. */ +# define INT_MIN (-INT_MAX - 1) +# define INT_MAX 2147483647 +#endif +/* cannot find the necessary include header */ +typedef uint64_t u64; +typedef uint32_t u32; +typedef uint16_t u16; +typedef uint8_t u8; + +/* driver internal */ +#include "version.h" +#include "config.h" +#include "gl_dependent.h" + +#include "gl_typedef.h" +#include "typedef.h" +#include "queue.h" +#include "gl_kal.h" +#include "gl_rst.h" +#include "hif.h" + +#if CFG_SUPPORT_TDLS +#include "tdls.h" +#endif + +#include "debug.h" + +#include "wlan_oid.h" + +/* + * comment: declared in wlan_lib.c + * and almost all of the glue layer includes #include "precomp.h" + * should we just but it in wlan_lib.h + */ +extern u_int8_t fgIsBusAccessFailed; + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ +#ifndef __weak +#define __weak __attribute__((weak)) +#endif +/*------------------------------------------------------------------------------ + * Flags for OS dependent + *------------------------------------------------------------------------------ + */ +#define CFG_MAX_WLAN_DEVICES 1 /* number of wlan card will coexist */ + +#define CFG_MAX_TXQ_NUM 4 /* number of tx queue for support multi-queue h/w */ + +/* 1: Enable use of SPIN LOCK Bottom Half for LINUX */ +/* 0: Disable - use SPIN LOCK IRQ SAVE instead */ +#define CFG_USE_SPIN_LOCK_BOTTOM_HALF 0 + +/* 1: Enable - Drop ethernet packet if it < 14 bytes. + * And pad ethernet packet with dummy 0 if it < 60 bytes. + * 0: Disable + */ +#define CFG_TX_PADDING_SMALL_ETH_PACKET 0 + +#define CFG_TX_STOP_NETIF_QUEUE_THRESHOLD 256 /* packets */ + +#define CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD 256 /* packets */ +#define CFG_TX_START_NETIF_PER_QUEUE_THRESHOLD 128 /* packets */ + +#define CHIP_NAME "MT6632" + +#define DRV_NAME "["CHIP_NAME"]: " + +/* Define if target platform is Android. + * It should already be defined in Android kernel source + */ +#ifndef CONFIG_ANDROID +/* #define CONFIG_ANDROID 0 */ +#endif + +/* for CFG80211 IE buffering mechanism */ +#define CFG_CFG80211_IE_BUF_LEN (512) +#define GLUE_INFO_WSCIE_LENGTH (500) +/* for non-wfa vendor specific IE buffer */ +#define NON_WFA_VENDOR_IE_MAX_LEN (128) + + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +/* driver events for threading */ +#define GLUE_FLAG_HALT BIT(0) +#define GLUE_FLAG_INT BIT(1) +#define GLUE_FLAG_OID BIT(2) +#define GLUE_FLAG_TIMEOUT BIT(3) +#define GLUE_FLAG_TXREQ BIT(4) +#define GLUE_FLAG_SUB_MOD_MULTICAST BIT(7) +#define GLUE_FLAG_FRAME_FILTER BIT(8) +#define GLUE_FLAG_FRAME_FILTER_AIS BIT(9) + +#define GLUE_FLAG_HALT_BIT (0) +#define GLUE_FLAG_INT_BIT (1) +#define GLUE_FLAG_OID_BIT (2) +#define GLUE_FLAG_TIMEOUT_BIT (3) +#define GLUE_FLAG_TXREQ_BIT (4) +#define GLUE_FLAG_SUB_MOD_MULTICAST_BIT (7) +#define GLUE_FLAG_FRAME_FILTER_BIT (8) +#define GLUE_FLAG_FRAME_FILTER_AIS_BIT (9) + +#if CFG_SUPPORT_MULTITHREAD +#define GLUE_FLAG_RX BIT(10) +#define GLUE_FLAG_TX_CMD_DONE BIT(11) +#define GLUE_FLAG_HIF_TX BIT(12) +#define GLUE_FLAG_HIF_TX_CMD BIT(13) +#define GLUE_FLAG_RX_TO_OS BIT(14) +#define GLUE_FLAG_HIF_FW_OWN BIT(15) +#define GLUE_FLAG_HIF_PRT_HIF_DBG_INFO BIT(16) +#define GLUE_FLAG_UPDATE_WMM_QUOTA BIT(17) +#define GLUE_FLAG_NOTIFY_MD_CRASH BIT(18) + +#define GLUE_FLAG_RX_BIT (10) +#define GLUE_FLAG_TX_CMD_DONE_BIT (11) +#define GLUE_FLAG_HIF_TX_BIT (12) +#define GLUE_FLAG_HIF_TX_CMD_BIT (13) +#define GLUE_FLAG_RX_TO_OS_BIT (14) +#define GLUE_FLAG_HIF_FW_OWN_BIT (15) +#define GLUE_FLAG_HIF_PRT_HIF_DBG_INFO_BIT (16) +#define GLUE_FLAG_UPDATE_WMM_QUOTA_BIT (17) +#define GLUE_FLAG_NOTIFY_MD_CRASH_BIT (18) +#endif + +#if CFG_ENABLE_BT_OVER_WIFI +#define GLUE_BOW_KFIFO_DEPTH (1024) +/* #define GLUE_BOW_DEVICE_NAME "MT6620 802.11 AMP" */ +#define GLUE_BOW_DEVICE_NAME "ampc0" +#endif + +/* wake lock for suspend/resume */ +#define WAKE_LOCK_RX_TIMEOUT 300 /* ms */ +#define WAKE_LOCK_THREAD_WAKEUP_TIMEOUT 50 /* ms */ + +#define STR_HELPER(x) #x +#define STR(x) STR_HELPER(x) + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +struct GLUE_INFO; + +struct GL_WPA_INFO { + uint32_t u4WpaVersion; + uint32_t u4KeyMgmt; + uint32_t u4CipherGroup; + uint32_t u4CipherPairwise; + uint32_t u4AuthAlg; + u_int8_t fgPrivacyInvoke; +#if CFG_SUPPORT_802_11W + uint32_t u4Mfp; + uint8_t ucRSNMfpCap; +#endif +}; + +#if CFG_SUPPORT_REPLAY_DETECTION +struct GL_REPLEY_PN_INFO { + uint8_t auPN[16]; + u_int8_t fgRekey; + u_int8_t fgFirstPkt; +}; +struct GL_DETECT_REPLAY_INFO { + uint8_t ucCurKeyId; + uint8_t ucKeyType; + struct GL_REPLEY_PN_INFO arReplayPNInfo[4]; +}; +#endif + +enum ENUM_NET_DEV_IDX { + NET_DEV_WLAN_IDX = 0, + NET_DEV_P2P_IDX, + NET_DEV_BOW_IDX, + NET_DEV_NUM +}; + +enum ENUM_RSSI_TRIGGER_TYPE { + ENUM_RSSI_TRIGGER_NONE, + ENUM_RSSI_TRIGGER_GREATER, + ENUM_RSSI_TRIGGER_LESS, + ENUM_RSSI_TRIGGER_TRIGGERED, + ENUM_RSSI_TRIGGER_NUM +}; + +#if CFG_ENABLE_WIFI_DIRECT +enum ENUM_NET_REG_STATE { + ENUM_NET_REG_STATE_UNREGISTERED, + ENUM_NET_REG_STATE_REGISTERING, + ENUM_NET_REG_STATE_REGISTERED, + ENUM_NET_REG_STATE_UNREGISTERING, + ENUM_NET_REG_STATE_NUM +}; +#endif + +enum ENUM_PKT_FLAG { + ENUM_PKT_802_11, /* 802.11 or non-802.11 */ + ENUM_PKT_802_3, /* 802.3 or ethernetII */ + ENUM_PKT_1X, /* 1x frame or not */ + ENUM_PKT_PROTECTED_1X, /* protected 1x frame */ + ENUM_PKT_NON_PROTECTED_1X, /* Non protected 1x frame */ + ENUM_PKT_VLAN_EXIST, /* VLAN tag exist */ + ENUM_PKT_DHCP, /* DHCP frame */ + ENUM_PKT_ARP, /* ARP */ + ENUM_PKT_ICMP, /* ICMP */ + ENUM_PKT_TDLS, /* TDLS */ + ENUM_PKT_DNS, /* DNS */ + + ENUM_PKT_FLAG_NUM +}; + +struct GL_IO_REQ { + struct QUE_ENTRY rQueEntry; + /* wait_queue_head_t cmdwait_q; */ + u_int8_t fgRead; + u_int8_t fgWaitResp; + struct ADAPTER *prAdapter; + PFN_OID_HANDLER_FUNC pfnOidHandler; + void *pvInfoBuf; + uint32_t u4InfoBufLen; + uint32_t *pu4QryInfoLen; + uint32_t rStatus; + uint32_t u4Flag; +}; + +#if CFG_ENABLE_BT_OVER_WIFI +struct GL_BOW_INFO { +/* TODO: os-related */ +#if 0 + u_int8_t fgIsRegistered; + dev_t u4DeviceNumber; /* dynamic device number */ + struct kfifo rKfifo; /* for buffering indicated events */ + spinlock_t rSpinLock; /* spin lock for kfifo */ + struct cdev cdev; + uint32_t u4FreqInKHz; /* frequency */ + + uint8_t aucRole[CFG_BOW_PHYSICAL_LINK_NUM]; /* 0: Responder, + * 1: Initiator + */ + enum ENUM_BOW_DEVICE_STATE + aeState[CFG_BOW_PHYSICAL_LINK_NUM]; + uint8_t arPeerAddr[CFG_BOW_PHYSICAL_LINK_NUM][PARAM_MAC_ADDR_LEN]; + + wait_queue_head_t outq; + +#if CFG_BOW_SEPARATE_DATA_PATH + /* Device handle */ + struct net_device *prDevHandler; + u_int8_t fgIsNetRegistered; +#endif +#endif +}; +#endif + +#if CFG_SUPPORT_SCAN_CACHE_RESULT +struct GL_SCAN_CACHE_INFO { + struct GLUE_INFO *prGlueInfo; +/* TODO: os-related? */ + /* total number of channels to scan */ + uint32_t n_channels; + + /* Scan period time */ + OS_SYSTIME u4LastScanTime; +/* TODO: os-related */ +#if 0 + /* for cfg80211 scan done indication */ + struct cfg80211_scan_request *prRequest; +#endif +}; +#endif /* CFG_SUPPORT_SCAN_CACHE_RESULT */ + +struct FT_IES { + uint16_t u2MDID; + struct IE_MOBILITY_DOMAIN *prMDIE; + struct IE_FAST_TRANSITION *prFTIE; + struct IE_TIMEOUT_INTERVAL *prTIE; + struct RSN_INFO_ELEM *prRsnIE; + uint8_t *pucIEBuf; + uint32_t u4IeLength; +}; + +/* + * type definition of pointer to p2p structure + */ +struct GL_P2P_INFO; /* declare GL_P2P_INFO_T */ +struct GL_P2P_DEV_INFO; /* declare GL_P2P_DEV_INFO_T */ + +struct GLUE_INFO { + /* Pointer to ADAPTER_T - main data structure of internal protocol + * stack + */ + struct ADAPTER *prAdapter; + + /* OID related */ + struct QUE rCmdQueue; + + spinlock_t rSpinLock[SPIN_LOCK_NUM]; + + /* Number of pending frames, also used for debuging if any frame is + * missing during the process of unloading Driver. + * + * NOTE(Kevin): In Linux, we also use this variable as the threshold + * for manipulating the netif_stop(wake)_queue() func. + */ + int32_t ai4TxPendingFrameNumPerQueue[MAX_BSSID_NUM][CFG_MAX_TXQ_NUM]; + int32_t i4TxPendingFrameNum; + int32_t i4TxPendingSecurityFrameNum; + int32_t i4TxPendingCmdNum; + + /*! \brief wext wpa related information */ + struct GL_WPA_INFO rWpaInfo[KAL_AIS_NUM]; +#if CFG_SUPPORT_REPLAY_DETECTION + struct GL_DETECT_REPLAY_INFO prDetRplyInfo[KAL_AIS_NUM]; +#endif + + uint32_t u4RoamFailCnt; + uint64_t u8RoamFailTime; + + /* 11R */ + struct FT_IES rFtIeForTx; + struct cfg80211_ft_event_params rFtEventParam; + + uint32_t IsrAbnormalCnt; + uint32_t IsrSoftWareCnt; + + /* Indicated media state */ + enum ENUM_PARAM_MEDIA_STATE eParamMediaStateIndicated; + + /* NVRAM availability */ + u_int8_t fgNvramAvailable; + + struct SET_TXPWR_CTRL rTxPwr; + + uint32_t IsrCnt; + uint32_t IsrPassCnt; + uint32_t TaskIsrCnt; + + uint32_t IsrTxCnt; + uint32_t IsrRxCnt; + + /* Tx: for NetDev to BSS index mapping */ + struct NET_INTERFACE_INFO arNetInterfaceInfo[MAX_BSSID_NUM]; + + u_int8_t fgTxDoneDelayIsARP; + + uint32_t u4ArriveDrvTick; + uint32_t u4EnQueTick; + uint32_t u4DeQueTick; + uint32_t u4LeaveDrvTick; + uint32_t u4CurrTick; + uint64_t u8CurrTime; + + /* + * Buffer to hold non-wfa vendor specific IEs set + * from wpa_supplicant. This is used in sending + * Association Request in AIS mode. + */ + uint16_t non_wfa_vendor_ie_len; + uint8_t non_wfa_vendor_ie_buf[NON_WFA_VENDOR_IE_MAX_LEN]; + +#if CFG_ENABLE_WIFI_DIRECT + struct GL_P2P_DEV_INFO *prP2PDevInfo; + struct GL_P2P_INFO *prP2PInfo[KAL_P2P_NUM]; +#endif + +#if CFG_SUPPORT_SNIFFER + u_int8_t fgIsEnableMon; +#endif + + u_int8_t fgIsInSuspendMode; + + /* registry info */ + struct REG_INFO rRegInfo; + + /* + * needed by + * common/cmm_asic_connac.c + */ + uint32_t u4InfType; + + /* + * needed by + * mgmt/tdls.c + */ + /* Device handle */ + struct net_device *prDevHandler; + + /* Device */ + struct device *prDev; + /* not necessary for built */ + /* TODO: os-related */ + uint32_t u4ReadyFlag; /* check if card is ready */ +#if 0 + + /* Device */ + struct device *prDev; + + /* Device Index(index of arWlanDevInfo[]) */ + int32_t i4DevIdx; + + /* Device statistics */ + /* struct net_device_stats rNetDevStats; */ + + /* Wireless statistics struct net_device */ + struct iw_statistics rIwStats; + + /* spinlock to sync power save mechanism */ + spinlock_t rSpinLock[SPIN_LOCK_NUM]; + + /* Mutex to protect interruptible section */ + struct mutex arMutex[MUTEX_NUM]; + + /* semaphore for ioctl */ + struct semaphore ioctl_sem; + + uint64_t u8Cookie; + + unsigned long ulFlag; /* GLUE_FLAG_XXX */ + uint32_t u4PendFlag; + /* UINT_32 u4TimeoutFlag; */ + uint32_t u4OidCompleteFlag; + uint32_t u4ReadyFlag; /* check if card is ready */ + + uint32_t u4OsMgmtFrameFilter; + + /* Number of pending frames, also used for debuging if any frame is + * missing during the process of unloading Driver. + * + * NOTE(Kevin): In Linux, we also use this variable as the threshold + * for manipulating the netif_stop(wake)_queue() func. + */ + int32_t ai4TxPendingFrameNumPerQueue[MAX_BSSID_NUM][CFG_MAX_TXQ_NUM]; + int32_t i4TxPendingFrameNum; + int32_t i4TxPendingSecurityFrameNum; + int32_t i4TxPendingCmdNum; + + /* Tx: for NetDev to BSS index mapping */ + struct NET_INTERFACE_INFO arNetInterfaceInfo[MAX_BSSID_NUM]; + + /* Rx: for BSS index to NetDev mapping */ + /* P_NET_INTERFACE_INFO_T aprBssIdxToNetInterfaceInfo[HW_BSSID_NUM]; */ + + /* current IO request for kalIoctl */ + struct GL_IO_REQ OidEntry; + + /* registry info */ + struct REG_INFO rRegInfo; + + /* firmware */ + struct firmware *prFw; + + /* Host interface related information */ + /* defined in related hif header file */ + struct GL_HIF_INFO rHifInfo; + + /*! \brief wext wpa related information */ + struct GL_WPA_INFO rWpaInfo; +#if CFG_SUPPORT_REPLAY_DETECTION + struct GL_DETECT_REPLAY_INFO prDetRplyInfo; +#endif + + /* Pointer to ADAPTER_T - main data structure of internal protocol + * stack + */ + struct ADAPTER *prAdapter; + +#if WLAN_INCLUDE_PROC + struct proc_dir_entry *pProcRoot; +#endif /* WLAN_INCLUDE_PROC */ + + /* Indicated media state */ + enum ENUM_PARAM_MEDIA_STATE eParamMediaStateIndicated; + + /* Device power state D0~D3 */ + enum PARAM_DEVICE_POWER_STATE ePowerState; + + struct completion rScanComp; /* indicate scan complete */ + struct completion + rHaltComp; /* indicate main thread halt complete */ + struct completion + rPendComp; /* indicate main thread halt complete */ +#if CFG_SUPPORT_MULTITHREAD + struct completion + rHifHaltComp; /* indicate hif_thread halt complete */ + struct completion + rRxHaltComp; /* indicate hif_thread halt complete */ + + uint32_t u4TxThreadPid; + uint32_t u4RxThreadPid; + uint32_t u4HifThreadPid; +#endif + +#if CFG_SUPPORT_NCHO + struct completion + rAisChGrntComp; /* indicate Ais channel grant complete */ +#endif + + uint32_t rPendStatus; + + struct QUE rTxQueue; + + /* OID related */ + struct QUE rCmdQueue; + /* PVOID pvInformationBuffer; */ + /* UINT_32 u4InformationBufferLength; */ + /* PVOID pvOidEntry; */ + /* PUINT_8 pucIOReqBuff; */ + /* QUE_T rIOReqQueue; */ + /* QUE_T rFreeIOReqQueue; */ + + wait_queue_head_t waitq; + struct task_struct *main_thread; + +#if CFG_SUPPORT_MULTITHREAD + wait_queue_head_t waitq_hif; + struct task_struct *hif_thread; + + wait_queue_head_t waitq_rx; + struct task_struct *rx_thread; + +#endif + struct tasklet_struct rRxTask; + struct tasklet_struct rTxCompleteTask; + + struct work_struct rTxMsduFreeWork; + struct delayed_work rRxPktDeAggWork; + + struct timer_list tickfn; + +#if CFG_SUPPORT_EXT_CONFIG + uint16_t au2ExtCfg[256]; /* NVRAM data buffer */ + uint32_t u4ExtCfgLength; /* 0 means data is NOT valid */ +#endif + +#if 1 /* CFG_SUPPORT_WAPI */ + /* Should be large than the PARAM_WAPI_ASSOC_INFO_T */ + uint8_t aucWapiAssocInfoIEs[42]; + uint16_t u2WapiAssocInfoIESz; +#endif + +#if CFG_ENABLE_BT_OVER_WIFI + struct GL_BOW_INFO rBowInfo; +#endif + +#if CFG_ENABLE_WIFI_DIRECT + struct GL_P2P_DEV_INFO *prP2PDevInfo; + struct GL_P2P_INFO *prP2PInfo[KAL_P2P_NUM]; +#if CFG_SUPPORT_P2P_RSSI_QUERY + /* Wireless statistics struct net_device */ + struct iw_statistics rP2pIwStats; +#endif +#endif + u_int8_t fgWpsActive; + uint8_t aucWSCIE[GLUE_INFO_WSCIE_LENGTH]; /*for probe req */ + uint16_t u2WSCIELen; + uint8_t aucWSCAssocInfoIE[200]; /*for Assoc req */ + uint16_t u2WSCAssocInfoIELen; + + /* NVRAM availability */ + u_int8_t fgNvramAvailable; + + u_int8_t fgMcrAccessAllowed; + + /* MAC Address Overridden by IOCTL */ + u_int8_t fgIsMacAddrOverride; + uint8_t rMacAddrOverride[PARAM_MAC_ADDR_LEN]; + + struct SET_TXPWR_CTRL rTxPwr; + + /* for cfg80211 scan done indication */ + struct cfg80211_scan_request *prScanRequest; + + /* for cfg80211 scheduled scan */ + struct cfg80211_sched_scan_request *prSchedScanRequest; + + /* to indicate registered or not */ + u_int8_t fgIsRegistered; + + /* for cfg80211 connected indication */ + uint32_t u4RspIeLength; + uint8_t aucRspIe[CFG_CFG80211_IE_BUF_LEN]; + + uint32_t u4ReqIeLength; + uint8_t aucReqIe[CFG_CFG80211_IE_BUF_LEN]; + + /* + * Buffer to hold non-wfa vendor specific IEs set + * from wpa_supplicant. This is used in sending + * Association Request in AIS mode. + */ + uint16_t non_wfa_vendor_ie_len; + uint8_t non_wfa_vendor_ie_buf[NON_WFA_VENDOR_IE_MAX_LEN]; + +#if CFG_SUPPORT_SDIO_READ_WRITE_PATTERN + u_int8_t fgEnSdioTestPattern; + u_int8_t fgSdioReadWriteMode; + u_int8_t fgIsSdioTestInitialized; + uint8_t aucSdioTestBuffer[256]; +#endif + + u_int8_t fgIsInSuspendMode; + +#if CFG_SUPPORT_PASSPOINT + uint8_t aucHS20AssocInfoIE[200]; /*for Assoc req */ + uint16_t u2HS20AssocInfoIELen; + uint8_t ucHotspotConfig; + u_int8_t fgConnectHS20AP; + + u_int8_t fgIsDad; + uint8_t aucDADipv4[4]; + u_int8_t fgIs6Dad; + uint8_t aucDADipv6[16]; +#endif /* CFG_SUPPORT_PASSPOINT */ + + KAL_WAKE_LOCK_T rIntrWakeLock; + KAL_WAKE_LOCK_T rTimeoutWakeLock; + +#if CFG_MET_PACKET_TRACE_SUPPORT + u_int8_t fgMetProfilingEn; + uint16_t u2MetUdpPort; +#endif + +#if CFG_SUPPORT_SNIFFER + u_int8_t fgIsEnableMon; + struct net_device *prMonDevHandler; + struct work_struct monWork; +#endif + + int32_t i4RssiCache; + uint32_t u4LinkSpeedCache; + + + uint32_t u4InfType; + + uint32_t IsrCnt; + uint32_t IsrPassCnt; + uint32_t TaskIsrCnt; + + uint32_t IsrAbnormalCnt; + uint32_t IsrSoftWareCnt; + uint32_t IsrTxCnt; + uint32_t IsrRxCnt; + uint64_t u8HifIntTime; + + /* save partial scan channel information */ + /* PARTIAL_SCAN_INFO rScanChannelInfo; */ + uint8_t *pucScanChannel; + +#if CFG_SUPPORT_SCAN_CACHE_RESULT + struct GL_SCAN_CACHE_INFO scanCache; +#endif /* CFG_SUPPORT_SCAN_CACHE_RESULT */ + + /* Full2Partial */ + OS_SYSTIME u4LastFullScanTime; + /* full scan or partial scan */ + uint8_t ucTrScanType; + /* UINT_8 aucChannelNum[FULL_SCAN_MAX_CHANNEL_NUM]; */ + /* PARTIAL_SCAN_INFO rFullScanApChannel; */ + uint8_t *pucFullScan2PartialChannel; + + uint32_t u4RoamFailCnt; + uint64_t u8RoamFailTime; + u_int8_t fgTxDoneDelayIsARP; + uint32_t u4ArriveDrvTick; + uint32_t u4EnQueTick; + uint32_t u4DeQueTick; + uint32_t u4LeaveDrvTick; + uint32_t u4CurrTick; + uint64_t u8CurrTime; + + /* FW Roaming */ + /* store the FW roaming enable state which FWK determines */ + /* if it's = 0, ignore the black/whitelists settings from FWK */ + uint32_t u4FWRoamingEnable; + + /* 11R */ + struct FT_IES rFtIeForTx; + struct cfg80211_ft_event_params rFtEventParam; +#endif +}; + +#if 0 /* irq & time in Linux */ +typedef irqreturn_t(*PFN_WLANISR) (int irq, void *dev_id, + struct pt_regs *regs); + +typedef void (*PFN_LINUX_TIMER_FUNC) (unsigned long); +#endif + +/* generic sub module init/exit handler + * now, we only have one sub module, p2p + */ +#if CFG_ENABLE_WIFI_DIRECT +typedef u_int8_t(*SUB_MODULE_INIT) (struct GLUE_INFO + *prGlueInfo); +typedef u_int8_t(*SUB_MODULE_EXIT) (struct GLUE_INFO + *prGlueInfo); + +struct SUB_MODULE_HANDLER { + SUB_MODULE_INIT subModInit; + SUB_MODULE_EXIT subModExit; + u_int8_t fgIsInited; +}; + +#endif + +#ifdef CONFIG_NL80211_TESTMODE + +enum TestModeCmdType { + TESTMODE_CMD_ID_SW_CMD = 1, + TESTMODE_CMD_ID_WAPI = 2, + TESTMODE_CMD_ID_HS20 = 3, + + /* Hotspot managerment testmode command */ + TESTMODE_CMD_ID_HS_CONFIG = 51, + + TESTMODE_CMD_ID_STR_CMD = 102, + NUM_OF_TESTMODE_CMD_ID +}; + +#if CFG_SUPPORT_PASSPOINT +enum Hs20CmdType { + HS20_CMD_ID_SET_BSSID_POOL = 0, + NUM_OF_HS20_CMD_ID +}; +#endif /* CFG_SUPPORT_PASSPOINT */ + +struct NL80211_DRIVER_TEST_MODE_PARAMS { + uint32_t index; + uint32_t buflen; +}; + +struct NL80211_DRIVER_STRING_CMD_PARAMS { + struct NL80211_DRIVER_TEST_MODE_PARAMS hdr; + uint32_t reply_buf_size; + uint32_t reply_len; + uint8_t *reply_buf; +}; + +/*SW CMD */ +struct NL80211_DRIVER_SW_CMD_PARAMS { + struct NL80211_DRIVER_TEST_MODE_PARAMS hdr; + uint8_t set; + uint32_t adr; + uint32_t data; +}; + +struct iw_encode_exts { + __u32 ext_flags; /*!< IW_ENCODE_EXT_* */ + __u8 tx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /*!< LSB first */ + __u8 rx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /*!< LSB first */ + /*!< ff:ff:ff:ff:ff:ff for broadcast/multicast + * (group) keys or unicast address for + * individual keys + */ + __u8 addr[MAC_ADDR_LEN]; + __u16 alg; /*!< IW_ENCODE_ALG_* */ + __u16 key_len; + __u8 key[32]; +}; + +/*SET KEY EXT */ +struct NL80211_DRIVER_SET_KEY_EXTS { + struct NL80211_DRIVER_TEST_MODE_PARAMS hdr; + uint8_t key_index; + uint8_t key_len; + struct iw_encode_exts ext; +}; + +#if CFG_SUPPORT_PASSPOINT + +struct param_hs20_set_bssid_pool { + uint8_t fgBssidPoolIsEnable; + uint8_t ucNumBssidPool; + uint8_t arBssidPool[8][ETH_ALEN]; +}; + +struct wpa_driver_hs20_data_s { + struct NL80211_DRIVER_TEST_MODE_PARAMS hdr; + enum Hs20CmdType CmdType; + struct param_hs20_set_bssid_pool hs20_set_bssid_pool; +}; + +#endif /* CFG_SUPPORT_PASSPOINT */ + +#endif + +struct NETDEV_PRIVATE_GLUE_INFO { + struct GLUE_INFO *prGlueInfo; + uint8_t ucBssIdx; +#if CFG_ENABLE_UNIFY_WIPHY + u_int8_t ucIsP2p; +#endif +}; + +struct PACKET_PRIVATE_DATA { + /* tx/rx both use cb */ + struct QUE_ENTRY rQueEntry; /* 16byte total:16 */ + + uint8_t ucBssIdx; /* 1byte */ + /* only rx use cb */ + u_int8_t fgIsIndependentPkt; /* 1byte */ + /* only tx use cb */ + uint8_t ucTid; /* 1byte */ + uint8_t ucHeaderLen; /* 1byte */ + uint8_t ucProfilingFlag; /* 1byte */ + uint8_t ucSeqNo; /* 1byte */ + uint16_t u2Flag; /* 2byte total:24 */ + + uint16_t u2IpId; /* 2byte */ + uint16_t u2FrameLen; /* 2byte */ + OS_SYSTIME rArrivalTime;/* 4byte total:32 */ + + uint64_t u8ArriveTime; /* 8byte total:40 */ +}; + +struct PACKET_PRIVATE_RX_DATA { + uint64_t u8IntTime; /* 8byte */ + uint64_t u8RxTime; /* 8byte */ +}; + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ +/*----------------------------------------------------------------------------*/ +/* Macros of SPIN LOCK operations for using in Glue Layer */ +/*----------------------------------------------------------------------------*/ +/* TODO: we have to lock source another is in kalAcquireSpinLock */ +#define GLUE_SPIN_LOCK_DECLARATION() +#define GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, rLockCategory) +#define GLUE_RELEASE_SPIN_LOCK(prGlueInfo, rLockCategory) +/*----------------------------------------------------------------------------*/ +/* Macros for accessing Reserved Fields of native packet */ +/*----------------------------------------------------------------------------*/ +/* TODO: os-related, implementation may refer to os/linux */ +#define GLUE_GET_PKT_PRIVATE_DATA(_p) ((struct PACKET_PRIVATE_DATA *)0) + +#define GLUE_GET_PKT_QUEUE_ENTRY(_p) \ + (&(GLUE_GET_PKT_PRIVATE_DATA(_p)->rQueEntry)) + +/* TODO: os-related implementation */ +#define GLUE_GET_PKT_DESCRIPTOR(_prQueueEntry) ((struct PACKET_PRIVATE_DATA *)0) + +#define GLUE_SET_PKT_TID(_p, _tid) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->ucTid = (uint8_t)(_tid)) + +#define GLUE_GET_PKT_TID(_p) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->ucTid) + +#define GLUE_SET_PKT_FLAG(_p, _flag) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->u2Flag |= BIT(_flag)) + +#define GLUE_TEST_PKT_FLAG(_p, _flag) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->u2Flag & BIT(_flag)) + +#define GLUE_IS_PKT_FLAG_SET(_p) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->u2Flag) + +#define GLUE_SET_PKT_BSS_IDX(_p, _ucBssIndex) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->ucBssIdx = (uint8_t)(_ucBssIndex)) + +#define GLUE_GET_PKT_BSS_IDX(_p) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->ucBssIdx) + +#define GLUE_SET_PKT_HEADER_LEN(_p, _ucMacHeaderLen) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->ucHeaderLen = \ + (uint8_t)(_ucMacHeaderLen)) + +#define GLUE_GET_PKT_HEADER_LEN(_p) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->ucHeaderLen) + +#define GLUE_SET_PKT_FRAME_LEN(_p, _u2PayloadLen) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->u2FrameLen = (uint16_t)(_u2PayloadLen)) + +#define GLUE_GET_PKT_FRAME_LEN(_p) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->u2FrameLen) + +#define GLUE_SET_PKT_ARRIVAL_TIME(_p, _rSysTime) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->rArrivalTime = (OS_SYSTIME)(_rSysTime)) + +#define GLUE_GET_PKT_ARRIVAL_TIME(_p) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->rArrivalTime) + +#define GLUE_SET_PKT_IP_ID(_p, _u2IpId) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->u2IpId = (uint16_t)(_u2IpId)) + +#define GLUE_GET_PKT_IP_ID(_p) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->u2IpId) + +#define GLUE_SET_PKT_SEQ_NO(_p, _ucSeqNo) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->ucSeqNo = (uint8_t)(_ucSeqNo)) + +#define GLUE_GET_PKT_SEQ_NO(_p) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->ucSeqNo) + +#define GLUE_SET_PKT_FLAG_PROF_MET(_p) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->ucProfilingFlag |= BIT(0)) + +#define GLUE_GET_PKT_IS_PROF_MET(_p) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->ucProfilingFlag & BIT(0)) + +#define GLUE_SET_PKT_XTIME(_p, _rSysTime) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->u8ArriveTime = (uint64_t)(_rSysTime)) + +#define GLUE_GET_PKT_XTIME(_p) \ + (GLUE_GET_PKT_PRIVATE_DATA(_p)->u8ArriveTime) + +/* TODO: os-related implementation */ +#define GLUE_GET_PKT_PRIVATE_RX_DATA(_p) \ + ((struct PACKET_PRIVATE_RX_DATA *)(&(((struct sk_buff *)(_p))->cb[24]))) + +#define GLUE_RX_SET_PKT_INT_TIME(_p, _rTime) \ + (GLUE_GET_PKT_PRIVATE_RX_DATA(_p)->u8IntTime = (uint64_t)(_rTime)) + +#define GLUE_RX_GET_PKT_INT_TIME(_p) \ + (GLUE_GET_PKT_PRIVATE_RX_DATA(_p)->u8IntTime) + +#define GLUE_RX_SET_PKT_RX_TIME(_p, _rTime) \ + (GLUE_GET_PKT_PRIVATE_RX_DATA(_p)->u8RxTime = (uint64_t)(_rTime)) + +#define GLUE_RX_GET_PKT_RX_TIME(_p) \ + (GLUE_GET_PKT_PRIVATE_RX_DATA(_p)->u8RxTime) + +/* TODO: os-related implementation */ +#define GLUE_GET_PKT_ETHER_DEST_ADDR(_p) + +/* Check validity of prDev, private data, and pointers */ +/* TODO: os-related implementation */ +#define GLUE_CHK_DEV(prDev) + +#define GLUE_CHK_PR2(prDev, pr2) \ + ((GLUE_CHK_DEV(prDev) && pr2) ? TRUE : FALSE) + +#define GLUE_CHK_PR3(prDev, pr2, pr3) \ + ((GLUE_CHK_PR2(prDev, pr2) && pr3) ? TRUE : FALSE) + +#define GLUE_CHK_PR4(prDev, pr2, pr3, pr4) \ + ((GLUE_CHK_PR3(prDev, pr2, pr3) && pr4) ? TRUE : FALSE) + +#define GLUE_SET_EVENT(pr) \ + kalSetEvent(pr) +/* TODO: os-related implementation */ +#define GLUE_INC_REF_CNT(_refCount) (_refCount++) +#define GLUE_DEC_REF_CNT(_refCount) (_refCount--) +#define GLUE_ADD_REF_CNT(_value, _refCount) \ + (_refCount += _value) +#define GLUE_SUB_REF_CNT(_value, _refCount) \ + (_refCount -= _value) +#define GLUE_GET_REF_CNT(_refCount) (_refCount) + +#define DbgPrint(...) + +#define GLUE_LOOKUP_FUN(fun_name) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + + +#if CFG_MET_TAG_SUPPORT +#define GL_MET_TAG_START(_id, _name) met_tag_start(_id, _name) +#define GL_MET_TAG_END(_id, _name) met_tag_end(_id, _name) +#define GL_MET_TAG_ONESHOT(_id, _name, _value) \ + met_tag_oneshot(_id, _name, _value) +#define GL_MET_TAG_DISABLE(_id) met_tag_disable(_id) +#define GL_MET_TAG_ENABLE(_id) met_tag_enable(_id) +#define GL_MET_TAG_REC_ON() met_tag_record_on() +#define GL_MET_TAG_REC_OFF() met_tag_record_off() +#define GL_MET_TAG_INIT() met_tag_init() +#define GL_MET_TAG_UNINIT() met_tag_uninit() +#else +#define GL_MET_TAG_START(_id, _name) +#define GL_MET_TAG_END(_id, _name) +#define GL_MET_TAG_ONESHOT(_id, _name, _value) +#define GL_MET_TAG_DISABLE(_id) +#define GL_MET_TAG_ENABLE(_id) +#define GL_MET_TAG_REC_ON() +#define GL_MET_TAG_REC_OFF() +#define GL_MET_TAG_INIT() +#define GL_MET_TAG_UNINIT() +#endif + +#define MET_TAG_ID 0 + +/*----------------------------------------------------------------------------*/ +/* Macros of Data Type Check */ +/*----------------------------------------------------------------------------*/ +/* Kevin: we don't have to call following function to inspect the data + * structure. + * It will check automatically while at compile time. + */ +/* TODO: os-related, API implementation, may refer to Linux */ +#define glPacketDataTypeCheck() + +#define mtk_wlan_ndev_select_queue(_prSkb) + +#define netdev_for_each_mc_addr(mclist, dev) + +#define GET_ADDR(ha) + +#define LIST_FOR_EACH_IPV6_ADDR(_prIfa, _ip6_ptr) + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +#if WLAN_INCLUDE_PROC +int32_t procCreateFsEntry(struct GLUE_INFO *prGlueInfo); +int32_t procRemoveProcfs(void); + + +int32_t procInitFs(void); +int32_t procUninitProcFs(void); + + + +/* TODO: os-related, API implementation, may refer to Linux */ +#define procInitProcfs(_prDev, _pucDevName) +#endif /* WLAN_INCLUDE_PROC */ + +#if CFG_ENABLE_BT_OVER_WIFI +u_int8_t glRegisterAmpc(struct GLUE_INFO *prGlueInfo); + +u_int8_t glUnregisterAmpc(struct GLUE_INFO *prGlueInfo); +#endif + +#if CFG_ENABLE_WIFI_DIRECT +void p2pSetMulticastListWorkQueueWrapper(struct GLUE_INFO + *prGlueInfo); +#endif + +struct GLUE_INFO *wlanGetGlueInfo(void); + +#ifdef CFG_REMIND_IMPLEMENT +#define wlanSelectQueue(_dev, _skb) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#define wlanDebugInit() \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#else +u16 wlanSelectQueue(struct net_device *dev, + struct sk_buff *skb); + +void wlanDebugInit(void); +#endif + +uint32_t wlanSetDriverDbgLevel(IN uint32_t u4DbgIdx, + IN uint32_t u4DbgMask); + +uint32_t wlanGetDriverDbgLevel(IN uint32_t u4DbgIdx, + OUT uint32_t *pu4DbgMask); + +void wlanSetSuspendMode(struct GLUE_INFO *prGlueInfo, + u_int8_t fgEnable); + +#ifdef CFG_REMIND_IMPLEMENT +#define wlanGetConfig(_prAdapter) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#else +void wlanGetConfig(struct ADAPTER *prAdapter); +#endif + +uint32_t wlanDownloadBufferBin(struct ADAPTER *prAdapter); + +uint32_t wlanConnacDownloadBufferBin(struct ADAPTER + *prAdapter); + +/******************************************************************************* + * E X T E R N A L F U N C T I O N S / V A R I A B L E + ******************************************************************************* + */ +extern struct net_device *gPrP2pDev[KAL_P2P_NUM]; +extern struct net_device *gPrDev; +extern struct wireless_dev *gprWdev[KAL_AIS_NUM]; +extern uint32_t g_u4DevIdx[KAL_P2P_NUM]; +extern enum ENUM_NVRAM_STATE g_NvramFsm; + +#ifdef CFG_DRIVER_INF_NAME_CHANGE +extern char *gprifnameap; +extern char *gprifnamep2p; +extern char *gprifnamesta; +#endif /* CFG_DRIVER_INF_NAME_CHANGE */ + +extern void wlanRegisterNotifier(void); +extern void wlanUnregisterNotifier(void); +#if CFG_MTK_ANDROID_WMT +typedef int (*set_p2p_mode) (struct net_device *netdev, + struct PARAM_CUSTOM_P2P_SET_STRUCT p2pmode); +extern void register_set_p2p_mode_handler( + set_p2p_mode handler); +#endif + +#if CFG_ENABLE_EARLY_SUSPEND +extern int glRegisterEarlySuspend(struct early_suspend + *prDesc, + early_suspend_callback wlanSuspend, + late_resume_callback wlanResume); + +extern int glUnregisterEarlySuspend(struct early_suspend + *prDesc); +#endif + +#if CFG_MET_PACKET_TRACE_SUPPORT +#ifdef CFG_REMIND_IMPLEMENT +#define kalMetTagPacket(_prGlueInfo, _prPacket, _eTag) \ +KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#else +void kalMetTagPacket(IN struct GLUE_INFO *prGlueInfo, + IN void *prPacket, IN enum ENUM_TX_PROFILING_TAG eTag); +#endif + +void kalMetInit(IN struct GLUE_INFO *prGlueInfo); +#endif + +#ifdef CFG_REMIND_IMPLEMENT +#define wlanUpdateChannelTable(_prGlueInfo) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#else +void wlanUpdateChannelTable(struct GLUE_INFO *prGlueInfo); +#endif + +#if CFG_SUPPORT_SAP_DFS_CHANNEL +#ifdef CFG_REMIND_IMPLEMENT +#define wlanUpdateDfsChannelTable(_prGlueInfo, \ + _ucRoleIdx, _ucChannel, _ucBandWidth, \ + _eBssSCO, _u4CenterFreq) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#else +void wlanUpdateDfsChannelTable(struct GLUE_INFO *prGlueInfo, + uint8_t ucRoleIdx, uint8_t ucChannel, uint8_t ucBandWidth, + enum ENUM_CHNL_EXT eBssSCO, uint32_t u4CenterFreq); +#endif +#endif + +#if (CFG_MTK_ANDROID_WMT || WLAN_INCLUDE_PROC) +int set_p2p_mode_handler(struct net_device *netdev, + struct PARAM_CUSTOM_P2P_SET_STRUCT p2pmode); +#endif + +#if CFG_ENABLE_UNIFY_WIPHY +const struct net_device_ops *wlanGetNdevOps(void); +#endif + +#if CFG_MTK_ANDROID_WMT +extern void connectivity_flush_dcache_area(void *addr, size_t len); +extern void connectivity_arch_setup_dma_ops( + struct device *dev, u64 dma_base, + u64 size, struct iommu_ops *iommu, + bool coherent); +#endif + +#define wlanHardStartXmit(_prSkb, _prDev) + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(arr) \ + (sizeof(arr) / sizeof(((typeof(arr)){})[0])) +#endif +#endif /* _GL_OS_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/include/gl_p2p_ioctl.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/include/gl_p2p_ioctl.h new file mode 100644 index 0000000000000000000000000000000000000000..31f5cbc3199e450085dc46cb601438a1acf8c413 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/include/gl_p2p_ioctl.h @@ -0,0 +1,857 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * os/none/include/gl_p2p_ioctl.h#9 + */ + +/*! \file gl_p2p_ioctl.h + * \brief This file is for custom ioctls for Wi-Fi Direct only + */ + + +#ifndef _GL_P2P_IOCTL_H +#define _GL_P2P_IOCTL_H + +/****************************************************************************** + * C O M P I L E R F L A G S + ****************************************************************************** + */ + +/****************************************************************************** + * E X T E R N A L R E F E R E N C E S + ****************************************************************************** + */ +#include "wlan_oid.h" + +/****************************************************************************** + * C O N S T A N T S + ****************************************************************************** + */ + +/* (WirelessExtension) Private I/O Controls */ +#define IOC_P2P_CFG_DEVICE (SIOCIWFIRSTPRIV+0) +#define IOC_P2P_PROVISION_COMPLETE (SIOCIWFIRSTPRIV+2) +#define IOC_P2P_START_STOP_DISCOVERY (SIOCIWFIRSTPRIV+4) +#define IOC_P2P_DISCOVERY_RESULTS (SIOCIWFIRSTPRIV+5) +#define IOC_P2P_WSC_BEACON_PROBE_RSP_IE (SIOCIWFIRSTPRIV+6) +#define IOC_P2P_GO_WSC_IE IOC_P2P_WSC_BEACON_PROBE_RSP_IE +#define IOC_P2P_CONNECT_DISCONNECT (SIOCIWFIRSTPRIV+8) +#define IOC_P2P_PASSWORD_READY (SIOCIWFIRSTPRIV+10) +/* #define IOC_P2P_SET_PWR_MGMT_PARAM (SIOCIWFIRSTPRIV+12) */ +#define IOC_P2P_SET_INT (SIOCIWFIRSTPRIV+12) +#define IOC_P2P_GET_STRUCT (SIOCIWFIRSTPRIV+13) +#define IOC_P2P_SET_STRUCT (SIOCIWFIRSTPRIV+14) +#define IOC_P2P_GET_REQ_DEVICE_INFO (SIOCIWFIRSTPRIV+15) + +#define PRIV_CMD_INT_P2P_SET 0 + +/* IOC_P2P_PROVISION_COMPLETE (iw_point . flags) */ +#define P2P_PROVISIONING_SUCCESS 0 +#define P2P_PROVISIONING_FAIL 1 + +/* IOC_P2P_START_STOP_DISCOVERY (iw_point . flags) */ +#define P2P_STOP_DISCOVERY 0 +#define P2P_START_DISCOVERY 1 + +/* IOC_P2P_CONNECT_DISCONNECT (iw_point . flags) */ +#define P2P_CONNECT 0 +#define P2P_DISCONNECT 1 + +/* IOC_P2P_START_STOP_DISCOVERY (scan_type) */ +#define P2P_SCAN_FULL_AND_FIND 0 +#define P2P_SCAN_FULL 1 +#define P2P_SCAN_SEARCH_AND_LISTEN 2 +#define P2P_LISTEN 3 + +/* IOC_P2P_GET_STRUCT/IOC_P2P_SET_STRUCT */ +#define P2P_SEND_SD_RESPONSE 0 +#define P2P_GET_SD_REQUEST 1 +#define P2P_SEND_SD_REQUEST 2 +#define P2P_GET_SD_RESPONSE 3 +#define P2P_TERMINATE_SD_PHASE 4 + +#define CHN_DIRTY_WEIGHT_UPPERBOUND 4 + +/****************************************************************************** + * D A T A T Y P E S + ****************************************************************************** + */ +/*------------------------------------------------------------------------*/ +/* Wireless Extension: Private I/O Control */ +/*------------------------------------------------------------------------*/ + +#if 0 +struct iw_p2p_cfg_device_type { + void __user *ssid; + uint8_t ssid_len; + uint8_t pri_device_type[8]; + uint8_t snd_device_type[8]; + void __user *device_name; + uint8_t device_name_len; + uint8_t intend; + uint8_t persistence; + uint8_t sec_mode; + uint8_t ch; + uint8_t ch_width; /* 0: 20 Mhz 1:20/40 Mhz auto */ + uint8_t max_scb; +}; + +struct iw_p2p_hostapd_param { + uint8_t cmd; + uint8_t rsv[3]; + uint8_t sta_addr[6]; + void __user *data; + uint16_t len; +}; + +struct iw_p2p_req_device_type { + uint8_t scan_type; /* 0: Full scan + Find + * 1: Full scan + * 2: Scan (Search +Listen) + * 3: Listen + * other : reserved + */ + uint8_t pri_device_type[8]; + void __user *probe_req_ie; + uint16_t probe_req_len; + void __user *probe_rsp_ie; + uint16_t probe_rsp_len; +}; + +struct iw_p2p_connect_device { + uint8_t sta_addr[6]; + /* 0: P2P Device, 1:GC, 2: GO */ + uint8_t p2pRole; + /* 0: Don't needed provision, 1: doing the wsc provision first */ + uint8_t needProvision; + /* 1: auth peer invitation request */ + uint8_t authPeer; + /* Request Peer Device used config method */ + uint8_t intend_config_method; +}; + +struct iw_p2p_password_ready { + uint8_t active_config_method; + void __user *probe_req_ie; + uint16_t probe_req_len; + void __user *probe_rsp_ie; + uint16_t probe_rsp_len; +}; + +struct iw_p2p_device_req { + uint8_t name[33]; + uint32_t name_len; + uint8_t device_addr[6]; + uint8_t device_type; + int32_t config_method; + int32_t active_config_method; +}; + +struct iw_p2p_transport_struct { + uint32_t u4CmdId; + uint32_t inBufferLength; + uint32_t outBufferLength; + uint8_t aucBuffer[16]; +}; + +/* For Invitation */ +struct iw_p2p_ioctl_invitation_struct { + uint8_t aucDeviceID[6]; + /* BSSID */ + uint8_t aucGroupID[6]; + uint8_t aucSsid[32]; + uint32_t u4SsidLen; + uint8_t ucReinvoke; +}; + +struct iw_p2p_ioctl_abort_invitation { + uint8_t dev_addr[6]; +}; + +struct iw_p2p_ioctl_invitation_indicate { + uint8_t dev_addr[6]; + uint8_t group_bssid[6]; + /* peer device supported config method */ + int32_t config_method; + /* for reinvoke */ + uint8_t dev_name[32]; + uint32_t name_len; + /* for re-invoke, target operating channel */ + uint8_t operating_channel; + /* invitation or re-invoke */ + uint8_t invitation_type; +}; + +struct iw_p2p_ioctl_invitation_status { + uint32_t status_code; +}; + +/* For Formation */ +struct iw_p2p_ioctl_start_formation { + /* bssid */ + uint8_t dev_addr[6]; + /* 0: P2P Device, 1:GC, 2: GO */ + uint8_t role; + /* 0: Don't needed provision, 1: doing the wsc provision first */ + uint8_t needProvision; + /* 1: auth peer invitation request */ + uint8_t auth; + /* Request Peer Device used config method */ + + uint8_t config_method; +}; +#endif +/* SET_STRUCT / GET_STRUCT */ +enum ENUM_P2P_CMD_ID { + P2P_CMD_ID_SEND_SD_RESPONSE = 0, /* 0x00 (Set) */ + P2P_CMD_ID_GET_SD_REQUEST, /* 0x01 (Get) */ + P2P_CMD_ID_SEND_SD_REQUEST, /* 0x02 (Set) */ + P2P_CMD_ID_GET_SD_RESPONSE, /* 0x03 (Get) */ + P2P_CMD_ID_TERMINATE_SD_PHASE, /* 0x04 (Set) */ + /* CFG_SUPPORT_ANTI_PIRACY */ + P2P_CMD_ID_SEC_CHECK, /* 0x05(Set) */ + P2P_CMD_ID_INVITATION, /* 0x06 (Set) */ + P2P_CMD_ID_INVITATION_INDICATE, /* 0x07 (Get) */ + P2P_CMD_ID_INVITATION_STATUS, /* 0x08 (Get) */ + P2P_CMD_ID_INVITATION_ABORT, /* 0x09 (Set) */ + P2P_CMD_ID_START_FORMATION, /* 0x0A (Set) */ + P2P_CMD_ID_P2P_VERSION, /* 0x0B (Set/Get) */ + P2P_CMD_ID_GET_CH_LIST = 12, /* 0x0C (Get) */ + P2P_CMD_ID_GET_OP_CH = 14 /* 0x0E (Get) */ +}; + +#if 0 /* not used though ... */ +/* Service Discovery */ +struct iw_p2p_cmd_send_sd_response { + uint8_t rReceiverAddr[PARAM_MAC_ADDR_LEN]; + uint8_t fgNeedTxDoneIndication; + uint8_t ucSeqNum; + uint16_t u2PacketLength; + uint8_t aucPacketContent[0]; /*native 802.11 */ +}; + +struct iw_p2p_cmd_get_sd_request { + uint8_t rTransmitterAddr[PARAM_MAC_ADDR_LEN]; + uint16_t u2PacketLength; + uint8_t aucPacketContent[0]; /*native 802.11 */ +}; + +struct iw_p2p_cmd_send_service_discovery_request { + uint8_t rReceiverAddr[PARAM_MAC_ADDR_LEN]; + uint8_t fgNeedTxDoneIndication; + uint8_t ucSeqNum; + uint16_t u2PacketLength; + uint8_t aucPacketContent[0]; /*native 802.11 */ +}; + +struct iw_p2p_cmd_get_sd_response { + uint8_t rTransmitterAddr[PARAM_MAC_ADDR_LEN]; + uint16_t u2PacketLength; + uint8_t aucPacketContent[0]; /*native 802.11 */ +}; + +struct iw_p2p_cmd_terminate_sd_phase { + uint8_t rPeerAddr[PARAM_MAC_ADDR_LEN]; +}; + +struct iw_p2p_version { + uint32_t u4Version; +}; +#endif + +/****************************************************************************** + * P U B L I C D A T A + ****************************************************************************** + */ +extern struct ieee80211_supported_band mtk_band_2ghz; +extern struct ieee80211_supported_band mtk_band_5ghz; + +extern const uint32_t mtk_cipher_suites[6]; + + +/****************************************************************************** + * P R I V A T E D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * M A C R O S + ****************************************************************************** + */ +/* Macros used for cfg80211 */ +#define RATETAB_ENT(_rate, _rateid, _flags) \ +{ \ + .bitrate = (_rate), \ + .hw_value = (_rateid), \ + .flags = (_flags), \ +} + +#define CHAN2G(_channel, _freq, _flags) \ +{ \ + .band = KAL_BAND_2GHZ, \ + .center_freq = (_freq), \ + .hw_value = (_channel), \ + .flags = (_flags), \ + .max_antenna_gain = 0, \ + .max_power = 30, \ +} + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +#if (CFG_ENABLE_WIFI_DIRECT_CFG_80211 != 0) +/* + * TODO: function is os-related, while may depend on the purpose of function + * to implement on other os + */ +#if 0 +#if KERNEL_VERSION(4, 1, 0) <= CFG80211_VERSION_CODE +struct wireless_dev *mtk_p2p_cfg80211_add_iface(struct wiphy *wiphy, + const char *name, + unsigned char name_assign_type, + enum nl80211_iftype type, + u32 *flags, + struct vif_params *params); +#else +struct wireless_dev *mtk_p2p_cfg80211_add_iface(struct wiphy *wiphy, + const char *name, + enum nl80211_iftype type, + u32 *flags, + struct vif_params *params); +#endif + +int +mtk_p2p_cfg80211_change_iface(struct wiphy *wiphy, + struct net_device *ndev, + enum nl80211_iftype type, + u32 *flags, + struct vif_params *params); + +int mtk_p2p_cfg80211_del_iface(struct wiphy *wiphy, + struct wireless_dev *wdev); + +int +mtk_p2p_cfg80211_add_key(struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index, + bool pairwise, + const u8 *mac_addr, + struct key_params *params); + +int +mtk_p2p_cfg80211_get_key(struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index, + bool pairwise, + const u8 *mac_addr, + void *cookie, + void (*callback)(void *cookie, struct key_params *)); + +int +mtk_p2p_cfg80211_del_key(struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index, + bool pairwise, + const u8 *mac_addr); + +int +mtk_p2p_cfg80211_set_default_key(struct wiphy *wiphy, + struct net_device *netdev, + u8 key_index, + bool unicast, + bool multicast); + +int +mtk_p2p_cfg80211_set_mgmt_key(struct wiphy *wiphy, + struct net_device *dev, + u8 key_index); + +#if KERNEL_VERSION(3, 16, 0) <= CFG80211_VERSION_CODE +int mtk_p2p_cfg80211_get_station(struct wiphy *wiphy, + struct net_device *ndev, + const u8 *mac, + struct station_info *sinfo); +#else +int mtk_p2p_cfg80211_get_station(struct wiphy *wiphy, + struct net_device *ndev, + u8 *mac, + struct station_info *sinfo); +#endif +int mtk_p2p_cfg80211_scan(struct wiphy *wiphy, + struct cfg80211_scan_request *request); + +void mtk_p2p_cfg80211_abort_scan(struct wiphy *wiphy, + struct wireless_dev *wdev); + +int mtk_p2p_cfg80211_set_wiphy_params(struct wiphy *wiphy, + u32 changed); + +int mtk_p2p_cfg80211_connect(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_connect_params *sme); + +int mtk_p2p_cfg80211_disconnect(struct wiphy *wiphy, + struct net_device *dev, + u16 reason_code); + +int mtk_p2p_cfg80211_join_ibss(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_ibss_params *params); + +int mtk_p2p_cfg80211_leave_ibss(struct wiphy *wiphy, + struct net_device *dev); + +int mtk_p2p_cfg80211_set_txpower(struct wiphy *wiphy, + struct wireless_dev *wdev, + enum nl80211_tx_power_setting type, + int mbm); + +int mtk_p2p_cfg80211_get_txpower(struct wiphy *wiphy, + struct wireless_dev *wdev, + int *dbm); + +int mtk_p2p_cfg80211_remain_on_channel(struct wiphy *wiphy, + struct wireless_dev *wdev, + struct ieee80211_channel *chan, + unsigned int duration, + u64 *cookie); + +int mtk_p2p_cfg80211_cancel_remain_on_channel( + struct wiphy *wiphy, + struct wireless_dev *wdev, + u64 cookie); + +int mtk_p2p_cfg80211_set_power_mgmt(struct wiphy *wiphy, + struct net_device *dev, + bool enabled, + int timeout); + +#if (CFG_SUPPORT_DFS_MASTER == 1) + +#if KERNEL_VERSION(3, 15, 0) <= CFG80211_VERSION_CODE +int mtk_p2p_cfg80211_start_radar_detection(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_chan_def *chandef, + unsigned int cac_time_ms); +#else +int mtk_p2p_cfg80211_start_radar_detection(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_chan_def *chandef); +#endif + + +#if KERNEL_VERSION(3, 13, 0) <= CFG80211_VERSION_CODE +int mtk_p2p_cfg80211_channel_switch(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_csa_settings *params); +#endif +#endif + +int mtk_p2p_cfg80211_change_bss(struct wiphy *wiphy, + struct net_device *dev, + struct bss_parameters *params); + +int mtk_p2p_cfg80211_deauth(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_deauth_request *req); + +int mtk_p2p_cfg80211_disassoc(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_disassoc_request *req); + +int mtk_p2p_cfg80211_start_ap(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_ap_settings *settings); + +int mtk_p2p_cfg80211_change_beacon(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_beacon_data *info); + +#if KERNEL_VERSION(3, 14, 0) <= CFG80211_VERSION_CODE +int mtk_p2p_cfg80211_mgmt_tx(struct wiphy *wiphy, + struct wireless_dev *wdev, + struct cfg80211_mgmt_tx_params *params, + u64 *cookie); +#else +int mtk_p2p_cfg80211_mgmt_tx(struct wiphy *wiphy, + struct wireless_dev *wdev, + struct ieee80211_channel *chan, + bool offchan, + unsigned int wait, + const u8 *buf, + size_t len, + bool no_cck, + bool dont_wait_for_ack, + u64 *cookie); +#endif + +#if KERNEL_VERSION(3, 19, 0) <= CFG80211_VERSION_CODE +int mtk_p2p_cfg80211_del_station(struct wiphy *wiphy, + struct net_device *dev, + struct station_del_parameters *params); +#elif KERNEL_VERSION(3, 16, 0) <= CFG80211_VERSION_CODE +int mtk_p2p_cfg80211_del_station(struct wiphy *wiphy, + struct net_device *dev, + const u8 *mac); +#else +int mtk_p2p_cfg80211_del_station(struct wiphy *wiphy, + struct net_device *dev, + u8 *mac); +#endif + +int mtk_p2p_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, + struct wireless_dev *wdev, + u64 cookie); + +int mtk_p2p_cfg80211_stop_ap(struct wiphy *wiphy, + struct net_device *dev); + +int mtk_p2p_cfg80211_set_channel(struct wiphy *wiphy, + struct cfg80211_chan_def *chandef); + +void mtk_p2p_cfg80211_mgmt_frame_register(IN struct wiphy *wiphy, + struct wireless_dev *wdev, + IN u16 frame_type, + IN bool reg); + +int +mtk_p2p_cfg80211_set_bitrate_mask(IN struct wiphy *wiphy, + IN struct net_device *dev, + IN const u8 *peer, + IN const struct cfg80211_bitrate_mask *mask); + +#ifdef CONFIG_NL80211_TESTMODE +#if KERNEL_VERSION(3, 12, 0) <= CFG80211_VERSION_CODE +int mtk_p2p_cfg80211_testmode_cmd(struct wiphy *wiphy, + struct wireless_dev *wdev, + void *data, + int len); +#else +int mtk_p2p_cfg80211_testmode_cmd(struct wiphy *wiphy, + void *data, + int len); +#endif +int mtk_p2p_cfg80211_testmode_p2p_sigma_pre_cmd(IN struct wiphy *wiphy, + IN void *data, + IN int len); + +int mtk_p2p_cfg80211_testmode_p2p_sigma_cmd(IN struct wiphy *wiphy, + IN void *data, + IN int len); + +#if CFG_SUPPORT_WFD +int mtk_p2p_cfg80211_testmode_wfd_update_cmd(IN struct wiphy *wiphy, + IN void *data, + IN int len); +#endif + +int mtk_p2p_cfg80211_testmode_hotspot_block_list_cmd(IN struct wiphy *wiphy, + IN void *data, + IN int len); + +#if CFG_AUTO_CHANNEL_SEL_SUPPORT +int mtk_p2p_cfg80211_testmode_get_best_channel(IN struct wiphy *wiphy, + IN void *data, + IN int len); +#endif + +int mtk_p2p_cfg80211_testmode_hotspot_config_cmd(IN struct wiphy *wiphy, + IN void *data, + IN int len); + +#else +/* IGNORE KERNEL DEPENCY ERRORS*/ +/*#error "Please ENABLE kernel config (CONFIG_NL80211_TESTMODE) + * to support Wi-Fi Direct" + */ +#endif +#endif +#endif + +/* I/O control handlers */ +/* + * TODO: function is os-related, while may depend on the purpose of function + * to implement on other os + */ +#if 0 +int +mtk_p2p_wext_get_priv(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_reconnect(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_set_auth(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_set_key(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_mlme_handler(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_set_powermode(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_get_powermode(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +/* Private Wireless I/O Controls takes use of iw_handler */ +int +mtk_p2p_wext_set_local_dev_info(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_set_provision_complete(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_start_stop_discovery(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_discovery_results(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_wsc_ie(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_connect_disconnect(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_password_ready(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_request_dev_info(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_invitation_indicate(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_invitation_status(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_set_pm_param(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_set_ps_profile(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_set_network_address(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_set_int(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +/* Private Wireless I/O Controls for IOC_SET_STRUCT/IOC_GET_STRUCT */ +int +mtk_p2p_wext_set_struct(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_get_struct(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +/* IOC_SET_STRUCT/IOC_GET_STRUCT: Service Discovery */ +int +mtk_p2p_wext_get_service_discovery_request(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_get_service_discovery_response(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_send_service_discovery_request(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_send_service_discovery_response(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_terminate_service_discovery_phase(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +#if CFG_SUPPORT_ANTI_PIRACY +int +mtk_p2p_wext_set_sec_check_request(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_get_sec_check_response(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); +#endif + +int +mtk_p2p_wext_set_noa_param(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_set_oppps_param(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_set_p2p_version(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +int +mtk_p2p_wext_get_p2p_version(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +void mtk_p2p_wext_set_Multicastlist(IN struct GLUE_INFO *prGlueInfo); + +#if CFG_SUPPORT_P2P_RSSI_QUERY +int +mtk_p2p_wext_get_rssi(IN struct net_device *prDev, + IN struct iw_request_info *info, + IN OUT union iwreq_data *wrqu, + IN OUT char *extra); + +struct iw_statistics *mtk_p2p_wext_get_wireless_stats( + struct net_device *prDev); + +#endif + +int +mtk_p2p_wext_set_txpow(IN struct net_device *prDev, + IN struct iw_request_info *prIwrInfo, + IN OUT union iwreq_data *prTxPow, + IN char *pcExtra); +#endif +#endif /* _GL_P2P_IOCTL_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/include/gl_p2p_kal.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/include/gl_p2p_kal.h new file mode 100644 index 0000000000000000000000000000000000000000..b81772d2b198dd37037c551e23ce7e42338d02c4 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/include/gl_p2p_kal.h @@ -0,0 +1,479 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/ + * os/linux/include/gl_p2p_kal.h#2 + */ + +/*! \file gl_p2p_kal.h + * \brief Declaration of KAL functions for Wi-Fi Direct support + * - kal*() which is provided by GLUE Layer. + * + * Any definitions in this file will be shared among GLUE Layer + * and internal Driver Stack. + */ + + +#ifndef _GL_P2P_KAL_H +#define _GL_P2P_KAL_H + +/****************************************************************************** + * C O M P I L E R F L A G S + ****************************************************************************** + */ + +/****************************************************************************** + * E X T E R N A L R E F E R E N C E S + ****************************************************************************** + */ +#include "config.h" +#include "gl_typedef.h" +#include "gl_os.h" +#include "wlan_lib.h" +#include "wlan_oid.h" +#include "wlan_p2p.h" +#include "gl_kal.h" +/* for some structure in p2p_ioctl.h */ +#include "gl_p2p_ioctl.h" +#include "nic/p2p.h" + +#if DBG +extern int allocatedMemSize; +#endif + + +#define kalP2pFuncGetChannelType(_rChnlSco, _prChannelType) + +/****************************************************************************** + * C O N S T A N T S + ****************************************************************************** + */ + +/****************************************************************************** + * M A C R O S + ****************************************************************************** + */ + +/****************************************************************************** + * D A T A T Y P E S + ****************************************************************************** + */ + +/****************************************************************************** + * P U B L I C D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * P R I V A T E D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N D E C L A R A T I O N S + ****************************************************************************** + */ + +/* Service Discovery */ +void kalP2PIndicateSDRequest(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t rPeerAddr[PARAM_MAC_ADDR_LEN], + IN uint8_t ucSeqNum); + +void kalP2PIndicateSDResponse(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t rPeerAddr[PARAM_MAC_ADDR_LEN], + IN uint8_t ucSeqNum); + +void kalP2PIndicateTXDone(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucSeqNum, IN uint8_t ucStatus); + +/*------------------------------------------------------------------------*/ +/* Wi-Fi Direct handling */ +/*------------------------------------------------------------------------*/ +/*ENUM_PARAM_MEDIA_STATE_T kalP2PGetState(IN P_GLUE_INFO_T prGlueInfo);*/ + +/*VOID + *kalP2PSetState(IN P_GLUE_INFO_T prGlueInfo, + * IN ENUM_PARAM_MEDIA_STATE_T eState, + * IN PARAM_MAC_ADDRESS rPeerAddr, + * IN UINT_8 ucRole); + */ + +/*UINT_32 kalP2PGetFreqInKHz(IN P_GLUE_INFO_T prGlueInfo);*/ + +int32_t mtk_Netdev_To_RoleIdx(struct GLUE_INFO *prGlueInfo, + struct net_device *ndev, + uint8_t *pucRoleIdx); + +#ifdef CFG_REMIND_IMPLEMENT +#define kalP2PUpdateAssocInfo(_prGlueInfo, _pucFrameBody, _u4FrameBodyLen, \ + _fgReassocRequest, _ucBssIndex) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalP2PGetRole(_prGlueInfo, _ucRoleIdx) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalP2PSetRole(_prGlueInfo, _ucRole, _ucRoleIdx) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalP2PSetCipher(_prGlueInfo, _u4Cipher, _ucRoleIdx) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalP2PGetCipher(_prGlueInfo, _ucRoleIdx) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalP2PGetWepCipher(_prGlueInfo, _ucRoleIdx) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalP2PGetTkipCipher(_prGlueInfo, _ucRoleIdx) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalP2PGetCcmpCipher(_prGlueInfo, _ucRoleIdx) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) +#else +void +kalP2PUpdateAssocInfo(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t *pucFrameBody, + IN uint32_t u4FrameBodyLen, + IN u_int8_t fgReassocRequest, + IN uint8_t ucBssIndex); + +uint8_t kalP2PGetRole(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRoleIdx); + +void kalP2PSetRole(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRole, + IN uint8_t ucRoleIdx); + +void kalP2PSetCipher(IN struct GLUE_INFO *prGlueInfo, + IN uint32_t u4Cipher, + IN uint8_t ucRoleIdx); + +u_int8_t kalP2PGetCipher(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRoleIdx); + +u_int8_t kalP2PGetWepCipher(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRoleIdx); + +u_int8_t kalP2PGetTkipCipher(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRoleIdx); + +u_int8_t kalP2PGetCcmpCipher(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRoleIdx); +#endif + +void kalP2PSetWscMode(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucWscMode); + +uint8_t kalP2PGetWscMode(IN struct GLUE_INFO *prGlueInfo); + +#ifdef CFG_REMIND_IMPLEMENT +#define kalP2PCalWSC_IELen(_prGlueInfo, _ucType, _ucRoleIdx) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalP2PGenWSC_IE(_prGlueInfo, _ucType, _pucBuffer, _ucRoleIdx) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalP2PUpdateWSC_IE(_prGlueInfo, _ucType, _pucBuffer, \ + _u2BufferLength, _ucRoleIdx) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalP2PCalP2P_IELen(_prGlueInfo, _ucIndex, _ucRoleIdx) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalP2PGenP2P_IE(_prGlueInfo, _ucIndex, _pucBuffer, _ucRoleIdx) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalP2PUpdateP2P_IE(_prGlueInfo, _ucIndex, _pucBuffer, \ + _u2BufferLength, _ucRoleIdx) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) +#else +uint16_t kalP2PCalWSC_IELen(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucType, + IN uint8_t ucRoleIdx); + +void kalP2PGenWSC_IE(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucType, + IN uint8_t *pucBuffer, + IN uint8_t ucRoleIdx); + +void kalP2PUpdateWSC_IE(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucType, + IN uint8_t *pucBuffer, + IN uint16_t u2BufferLength, + IN uint8_t ucRoleIdx); + +uint16_t kalP2PCalP2P_IELen(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucIndex, + IN uint8_t ucRoleIdx); + +void kalP2PGenP2P_IE(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucIndex, + IN uint8_t *pucBuffer, + IN uint8_t ucRoleIdx); + +void kalP2PUpdateP2P_IE(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucIndex, + IN uint8_t *pucBuffer, + IN uint16_t u2BufferLength, + IN uint8_t ucRoleIdx); +#endif + +u_int8_t kalP2PIndicateFound(IN struct GLUE_INFO *prGlueInfo); + +void kalP2PIndicateConnReq(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t *pucDevName, + IN int32_t u4NameLength, + IN uint8_t rPeerAddr[PARAM_MAC_ADDR_LEN], + IN uint8_t ucDevType, /* 0: P2P Device / 1: GC / 2: GO */ + IN int32_t i4ConfigMethod, + IN int32_t i4ActiveConfigMethod); + +/*VOID kalP2PInvitationStatus(IN P_GLUE_INFO_T prGlueInfo, + * IN UINT_32 u4InvStatus); + */ + +void +kalP2PInvitationIndication(IN struct GLUE_INFO *prGlueInfo, + IN struct P2P_DEVICE_DESC *prP2pDevDesc, + IN uint8_t *pucSsid, + IN uint8_t ucSsidLen, + IN uint8_t ucOperatingChnl, + IN uint8_t ucInvitationType, + IN uint8_t *pucGroupBssid); + +struct net_device *kalP2PGetDevHdlr(struct GLUE_INFO *prGlueInfo); + +void +kalGetChnlList(IN struct GLUE_INFO *prGlueInfo, + IN enum ENUM_BAND eSpecificBand, + IN uint8_t ucMaxChannelNum, + IN uint8_t *pucNumOfChannel, + IN struct RF_CHANNEL_INFO *paucChannelList); + +#if CFG_SUPPORT_ANTI_PIRACY +void kalP2PIndicateSecCheckRsp(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t *pucRsp, + IN uint16_t u2RspLen); +#endif + +/****************************************************************************** + * F U N C T I O N S + ****************************************************************************** + */ + +#ifdef CFG_REMIND_IMPLEMENT +#define kalP2PIndicateChannelReady(_prGlueInfo, _u8SeqNum, _u4ChannelNum, \ + _eBand, _eSco, _u4Duration) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalP2PIndicateScanDone(_prGlueInfo, _ucRoleIndex, _fgIsAbort) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalP2PIndicateBssInfo(_prGlueInfo, _pucFrameBuf, _u4BufLen, \ + _prChannelInfo, _i4SignalStrength) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalP2PIndicateRxMgmtFrame(_prGlueInfo, _prSwRfb, \ + _fgIsDevInterface, _ucRoleIdx) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalP2PIndicateMgmtTxStatus(_prGlueInfo, _prMsduInfo, _fgIsAck) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalP2PIndicateChannelExpired(_prGlueInfo, _u8SeqNum, \ + _u4ChannelNum, _eBand, _eSco) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalP2PGCIndicateConnectionStatus(_prGlueInfo, _ucRoleIndex, \ + _prP2pConnInfo, _pucRxIEBuf, _u2RxIELen, _u2StatusReason) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalP2PGOStationUpdate(_pr, _ucRoleIndex, _prCliStaRec, _fgIsNew) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _pr) +#else +void +kalP2PIndicateChannelReady(IN struct GLUE_INFO *prGlueInfo, + IN uint64_t u8SeqNum, + IN uint32_t u4ChannelNum, + IN enum ENUM_BAND eBand, + IN enum ENUM_CHNL_EXT eSco, + IN uint32_t u4Duration); + +void kalP2PIndicateScanDone(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRoleIndex, + IN u_int8_t fgIsAbort); + +void +kalP2PIndicateBssInfo(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t *pucFrameBuf, + IN uint32_t u4BufLen, + IN struct RF_CHANNEL_INFO *prChannelInfo, + IN int32_t i4SignalStrength); + +void +kalP2PIndicateRxMgmtFrame(IN struct GLUE_INFO *prGlueInfo, + IN struct SW_RFB *prSwRfb, + IN u_int8_t fgIsDevInterface, + IN uint8_t ucRoleIdx); + +void kalP2PIndicateMgmtTxStatus(IN struct GLUE_INFO *prGlueInfo, + IN struct MSDU_INFO *prMsduInfo, + IN u_int8_t fgIsAck); + +void +kalP2PIndicateChannelExpired(IN struct GLUE_INFO *prGlueInfo, + IN uint64_t u8SeqNum, + IN uint32_t u4ChannelNum, + IN enum ENUM_BAND eBand, + IN enum ENUM_CHNL_EXT eSco); + +void +kalP2PGCIndicateConnectionStatus(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRoleIndex, + IN struct P2P_CONNECTION_REQ_INFO *prP2pConnInfo, + IN uint8_t *pucRxIEBuf, + IN uint16_t u2RxIELen, + IN uint16_t u2StatusReason); + +void +kalP2PGOStationUpdate(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRoleIndex, + IN struct STA_RECORD *prCliStaRec, + IN u_int8_t fgIsNew); +#endif + +#if (CFG_SUPPORT_DFS_MASTER == 1) +#ifdef CFG_REMIND_IMPLEMENT +#define kalP2PRddDetectUpdate(_prGlueInfo, _ucRoleIndex) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalP2PCacFinishedUpdate(_prGlueInfo, _ucRoleIndex) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) +#else +void +kalP2PRddDetectUpdate(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRoleIndex); + +void +kalP2PCacFinishedUpdate(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRoleIndex); +#endif +#endif + +#if CFG_SUPPORT_HOTSPOT_WPS_MANAGER + +u_int8_t kalP2PSetBlackList(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t rbssid[PARAM_MAC_ADDR_LEN], + IN u_int8_t fgIsblock, + IN uint8_t ucRoleIndex); + +u_int8_t kalP2PResetBlackList(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRoleIndex); + +void kalP2PSetMaxClients(IN struct GLUE_INFO *prGlueInfo, + IN uint32_t u4MaxClient, + IN uint8_t ucRoleIndex); + +#ifdef CFG_REMIND_IMPLEMENT +#define kalP2PCmpBlackList(_prGlueInfo, _rbssid, _ucRoleIndex) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalP2PMaxClients(_prGlueInfo, _u4NumClient, _ucRoleIndex) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) +#else +u_int8_t kalP2PCmpBlackList(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t rbssid[PARAM_MAC_ADDR_LEN], + IN uint8_t ucRoleIndex); + +u_int8_t kalP2PMaxClients(IN struct GLUE_INFO *prGlueInfo, + IN uint32_t u4NumClient, + IN uint8_t ucRoleIndex); +#endif +#endif + +#ifdef CFG_REMIND_IMPLEMENT +#define kalP2pUnlinkBss(_prGlueInfo, _aucBSSID) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalP2pIndicateQueuedMgmtFrame(_prGlueInfo, _prFrame) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalP2pIndicateAcsResult(_prGlueInfo, _ucRoleIndex, _ucPrimaryCh,\ + _ucSecondCh, _ucSeg0Ch, _ucSeg1Ch, _eChnlBw) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__, _prGlueInfo) + +#define kalP2pNotifyStopApComplete(_prAdapter, _ucRoleIndex) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +#define kalP2pIndicateChnlSwitch(_prAdapter, _prBssInfo) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#else +void kalP2pUnlinkBss(IN struct GLUE_INFO *prGlueInfo, IN uint8_t aucBSSID[]); + +void kalP2pIndicateQueuedMgmtFrame(IN struct GLUE_INFO *prGlueInfo, + IN struct P2P_QUEUED_ACTION_FRAME *prFrame); + +void kalP2pIndicateAcsResult(IN struct GLUE_INFO *prGlueInfo, + IN uint8_t ucRoleIndex, + IN uint8_t ucPrimaryCh, + IN uint8_t ucSecondCh, + IN uint8_t ucSeg0Ch, + IN uint8_t ucSeg1Ch, + IN enum ENUM_MAX_BANDWIDTH_SETTING eChnlBw); + +void kalP2pNotifyStopApComplete(IN struct ADAPTER *prAdapter, + IN uint8_t ucRoleIndex); + +void kalP2pIndicateChnlSwitch(IN struct ADAPTER *prAdapter, + IN struct BSS_INFO *prBssInfo); +#endif +#endif /* _GL_P2P_KAL_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/include/gl_p2p_os.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/include/gl_p2p_os.h new file mode 100644 index 0000000000000000000000000000000000000000..05842f3ede650555fe00781e2f1c971e5977dd61 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/include/gl_p2p_os.h @@ -0,0 +1,386 @@ +/****************************************************************************** + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + ** Id: + * //Department/DaVinci/TRUNK/MT6620_5931_WiFi_Driver/ + * os/linux/include/gl_p2p_os.h#28 + */ + +/*! \file gl_p2p_os.h + * \brief List the external reference to OS for p2p GLUE Layer. + * + * In this file we define the data structure - GLUE_INFO_T to + * store those objects we acquired from OS - + * e.g. TIMER, SPINLOCK, NET DEVICE ... . And all the + * external reference (header file, extern func() ..) to OS + * for GLUE Layer should also list down here. + */ + +#ifndef _GL_P2P_OS_H +#define _GL_P2P_OS_H + +/****************************************************************************** + * C O M P I L E R F L A G S + ****************************************************************************** + */ + +/****************************************************************************** + * E X T E R N A L R E F E R E N C E S + ****************************************************************************** + */ + +/****************************************************************************** + * E X T E R N A L V A R I A B L E + ****************************************************************************** + */ +#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_WIFI_DIRECT_CFG_80211 +extern const struct net_device_ops p2p_netdev_ops; +#endif + +/****************************************************************************** + * C O N S T A N T S + ****************************************************************************** + */ + +/****************************************************************************** + * M A C R O S + ****************************************************************************** + */ + +/* For SET_STRUCT/GET_STRUCT */ +#define OID_SET_GET_STRUCT_LENGTH 4096 + +#define MAX_P2P_IE_SIZE 5 + +#define P2P_MAXIMUM_CLIENT_COUNT 16 +#define P2P_DEFAULT_CLIENT_COUNT 4 + +/****************************************************************************** + * D A T A T Y P E S + ****************************************************************************** + */ + +/****************************************************************************** + * P U B L I C D A T A + ****************************************************************************** + */ + +extern struct net_device *g_P2pPrDev; +extern struct wireless_dev *gprP2pWdev; +extern struct wireless_dev *gprP2pRoleWdev[KAL_P2P_NUM]; + +/****************************************************************************** + * P R I V A T E D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * F U N C T I O N D E C L A R A T I O N S + ****************************************************************************** + */ + +struct GL_P2P_INFO { + + /* P2P Device interface handle */ + /*only first p2p have this devhandler*/ + struct net_device *prDevHandler; + /*struct net_device *prRoleDevHandler;*//* TH3 multiple P2P */ + + struct net_device *aprRoleHandler; + + /* Todo : should move to the glueinfo or not*/ + /*UINT_8 ucRoleInterfaceNum;*//* TH3 multiple P2P */ + +#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 + /* cfg80211 */ + struct wireless_dev *prWdev; + /*struct wireless_dev *prRoleWdev[KAL_P2P_NUM];*//* TH3 multiple P2P */ + + /*struct cfg80211_scan_request *prScanRequest;*//* TH3 multiple P2P */ + + /*UINT_64 u8Cookie;*//* TH3 multiple P2P */ + + /* Generation for station list update. */ + int32_t i4Generation; + + /*UINT_32 u4OsMgmtFrameFilter;*//* TH3 multiple P2P */ + +#endif + + /* Device statistics */ + /*struct net_device_stats rNetDevStats;*//* TH3 multiple P2P */ + + /* glue layer variables */ + /*move to glueinfo->adapter */ + /* BOOLEAN fgIsRegistered; */ + /*UINT_32 u4FreqInKHz;*//* TH3 multiple P2P */ /* frequency */ + /* 0: P2P Device, 1: Group Client, 2: Group Owner */ + uint8_t ucRole; + /*UINT_8 ucIntent;*//* TH3 multiple P2P */ /* range: 0-15 */ + /* 0: Search & Listen, 1: Scan without probe response */ + /*UINT_8 ucScanMode;*//* TH3 multiple P2P */ + + /*ENUM_PARAM_MEDIA_STATE_T eState;*//* TH3 multiple P2P */ + /*UINT_32 u4PacketFilter;*//* TH3 multiple P2P */ + /* TH3 multiple P2P */ + /*PARAM_MAC_ADDRESS aucMCAddrList[MAX_NUM_GROUP_ADDR];*/ + + /* connection-requested peer information *//* TH3 multiple P2P */ + /*UINT_8 aucConnReqDevName[32];*//* TH3 multiple P2P */ + /*INT_32 u4ConnReqNameLength;*//* TH3 multiple P2P */ + /*PARAM_MAC_ADDRESS rConnReqPeerAddr;*//* TH3 multiple P2P */ + /* For invitation group. */ + /*PARAM_MAC_ADDRESS rConnReqGroupAddr;*//* TH3 multiple P2P */ + /*UINT_8 ucConnReqDevType;*//* TH3 multiple P2P */ + /*INT_32 i4ConnReqConfigMethod;*//* TH3 multiple P2P */ + /*INT_32 i4ConnReqActiveConfigMethod;*//* TH3 multiple P2P */ + + uint32_t u4CipherPairwise; + /*UINT_8 ucWSCRunning;*//* TH3 multiple P2P */ + + /* 0: beacon, 1: probe req, 2:probe response, 3: assoc response */ + uint8_t aucWSCIE[4][400]; + uint16_t u2WSCIELen[4]; + + uint8_t aucP2PIE[MAX_P2P_IE_SIZE][400]; + uint16_t u2P2PIELen[MAX_P2P_IE_SIZE]; + +#if CFG_SUPPORT_WFD + /* 0 for beacon, 1 for probe req, 2 for probe response */ + uint8_t aucWFDIE[400]; + uint16_t u2WFDIELen; + /* Save the other IE for probe resp */ +#if CFG_SUPPORT_CUSTOM_VENDOR_IE + uint8_t aucVenderIE[1024]; + uint16_t u2VenderIELen; +#endif +#endif + + /*UINT_8 ucOperatingChnl;*//* TH3 multiple P2P */ + /*UINT_8 ucInvitationType;*//* TH3 multiple P2P */ + + /*UINT_32 u4InvStatus;*//* TH3 multiple P2P */ + + /* For SET_STRUCT/GET_STRUCT */ + /*UINT_8 aucOidBuf[OID_SET_GET_STRUCT_LENGTH];*//* TH3 multiple P2P */ + +#if 1 /* CFG_SUPPORT_ANTI_PIRACY */ + /*UINT_8 aucSecCheck[256];*//* TH3 multiple P2P */ + /*UINT_8 aucSecCheckRsp[256];*//* TH3 multiple P2P */ +#endif + +#if (CFG_SUPPORT_DFS_MASTER == 1) + struct cfg80211_chan_def *chandef; + uint32_t cac_time_ms; +#endif + +#if CFG_SUPPORT_HOTSPOT_WPS_MANAGER + uint8_t aucblackMACList[P2P_MAXIMUM_CLIENT_COUNT][PARAM_MAC_ADDR_LEN]; + uint8_t ucMaxClients; +#endif + +#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION + /*BOOLEAN fgEnableHotspotOptimization;*//* TH3 multiple P2P */ + /*UINT_32 u4PsLevel;*//* TH3 multiple P2P */ +#endif + + enum ENUM_CHNL_SWITCH_POLICY eChnlSwitchPolicy; +}; + +struct GL_P2P_DEV_INFO { +#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 + struct cfg80211_scan_request *prScanRequest; +#if 0 + struct cfg80211_scan_request rBackupScanRequest; +#endif + uint64_t u8Cookie; + uint32_t u4OsMgmtFrameFilter; +#endif + uint32_t u4PacketFilter; + uint8_t aucMCAddrList[MAX_NUM_GROUP_ADDR][PARAM_MAC_ADDR_LEN]; + uint8_t ucWSCRunning; +}; + +#ifdef CONFIG_NL80211_TESTMODE +struct NL80211_DRIVER_TEST_PRE_PARAMS { + uint16_t idx_mode; + uint16_t idx; + uint32_t value; +}; + +struct NL80211_DRIVER_TEST_PARAMS { + uint32_t index; + uint32_t buflen; +}; + +/* P2P Sigma*/ +struct NL80211_DRIVER_P2P_SIGMA_PARAMS { + struct NL80211_DRIVER_TEST_PARAMS hdr; + uint32_t idx; + uint32_t value; +}; + +/* Hotspot Client Management */ +struct NL80211_DRIVER_hotspot_block_PARAMS { + struct NL80211_DRIVER_TEST_PARAMS hdr; + uint8_t ucblocked; + uint8_t aucBssid[MAC_ADDR_LEN]; +}; + +/* Hotspot Management set config */ +struct NL80211_DRIVER_HOTSPOT_CONFIG_PARAMS { + struct NL80211_DRIVER_TEST_PARAMS hdr; + uint32_t idx; + uint32_t value; +}; + +#if CFG_SUPPORT_WFD +struct NL80211_DRIVER_WFD_PARAMS { + struct NL80211_DRIVER_TEST_PARAMS hdr; + uint32_t WfdCmdType; + uint8_t WfdEnable; + uint8_t WfdCoupleSinkStatus; + uint8_t WfdSessionAvailable; + uint8_t WfdSigmaMode; + uint16_t WfdDevInfo; + uint16_t WfdControlPort; + uint16_t WfdMaximumTp; + uint16_t WfdExtendCap; + uint8_t WfdCoupleSinkAddress[MAC_ADDR_LEN]; + uint8_t WfdAssociatedBssid[MAC_ADDR_LEN]; + uint8_t WfdVideoIp[4]; + uint8_t WfdAudioIp[4]; + uint16_t WfdVideoPort; + uint16_t WfdAudioPort; + uint32_t WfdFlag; + uint32_t WfdPolicy; + uint32_t WfdState; + /* Include Subelement ID, length */ + uint8_t WfdSessionInformationIE[24 * 8]; + uint16_t WfdSessionInformationIELen; + uint8_t aucReserved1[2]; + uint8_t aucWfdPrimarySinkMac[MAC_ADDR_LEN]; + uint8_t aucWfdSecondarySinkMac[MAC_ADDR_LEN]; + uint32_t WfdAdvanceFlag; + /* Group 1 64 bytes */ + uint8_t aucWfdLocalIp[4]; + uint16_t WfdLifetimeAc2; /* Unit is 2 TU */ + uint16_t WfdLifetimeAc3; /* Unit is 2 TU */ + uint16_t WfdCounterThreshold; /* Unit is ms */ + uint8_t aucReserved2[54]; + /* Group 3 64 bytes */ + uint8_t aucReserved3[64]; + /* Group 3 64 bytes */ + uint8_t aucReserved4[64]; +}; +#endif +#endif + +/****************************************************************************** + * P U B L I C D A T A + ****************************************************************************** + */ + +/****************************************************************************** + * P R I V A T E D A T A + ****************************************************************************** + */ + +u_int8_t p2pRegisterToWlan(struct GLUE_INFO *prGlueInfo); + +u_int8_t p2pUnregisterToWlan(struct GLUE_INFO *prGlueInfo); + +#ifdef CFG_REMIND_IMPLEMENT +#define p2pLaunch(_prGlueInfo) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +#define p2pRemove(_prGlueInfo) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +#define p2pSetMode(_ucAPMode) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#else +u_int8_t p2pLaunch(struct GLUE_INFO *prGlueInfo); + +u_int8_t p2pRemove(struct GLUE_INFO *prGlueInfo); + +void p2pSetMode(IN uint8_t ucAPMode); +#endif + +u_int8_t glRegisterP2P(struct GLUE_INFO *prGlueInfo, + const char *prDevName, + const char *prDevName2, + uint8_t ucApMode); + +int glSetupP2P(struct GLUE_INFO *prGlueInfo, + struct wireless_dev *prP2pWdev, + struct net_device *prP2pDev, + uint8_t u4Idx, + u_int8_t fgIsApMode); + +u_int8_t glUnregisterP2P(struct GLUE_INFO *prGlueInfo, uint8_t ucIdx); + +u_int8_t p2pNetRegister(struct GLUE_INFO *prGlueInfo, + u_int8_t fgIsRtnlLockAcquired); + +u_int8_t p2pNetUnregister(struct GLUE_INFO *prGlueInfo, + u_int8_t fgIsRtnlLockAcquired); + + +u_int8_t p2PAllocInfo(IN struct GLUE_INFO *prGlueInfo, IN uint8_t ucIdex); +u_int8_t p2PFreeInfo(struct GLUE_INFO *prGlueInfo, uint8_t ucIdx); + +void p2pSetSuspendMode(struct GLUE_INFO *prGlueInfo, u_int8_t fgEnable); +u_int8_t glP2pCreateWirelessDevice(struct GLUE_INFO *prGlueInfo); +void glP2pDestroyWirelessDevice(void); +void p2pUpdateChannelTableByDomain(struct GLUE_INFO *prGlueInfo); +#endif diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/include/gl_qa_agent.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/include/gl_qa_agent.h new file mode 100644 index 0000000000000000000000000000000000000000..dd9f67f718afd3173ba546fe5d0562603fde2256 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/include/gl_qa_agent.h @@ -0,0 +1,349 @@ +/******************************************************************************* + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ +/*! \file gl_qa_agent.h + * \brief This file includes private ioctl support. + */ + +#ifndef _GL_QA_AGENT_H +#define _GL_QA_AGENT_H + +#if CFG_SUPPORT_QA_TOOL + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#if CFG_MTK_ANDROID_EMI +extern phys_addr_t gConEmiPhyBaseFinal; +extern unsigned long long gConEmiSizeFinal; +#endif + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +/* Trigger Event */ +#define CAP_FREE_RUN 0 + +/* Ring Mode */ +#define CAP_RING_MODE_ENABLE 1 +#define CAP_RING_MODE_DISABLE 0 + +/* Capture Bit Width */ +#define CAP_96BIT 0 +#define CAP_128BIT + +/* I/Q Type */ +#define CAP_I_TYPE 0 +#define CAP_Q_TYPE 1 +#define NUM_OF_CAP_TYPE 2 + +/* ACTION */ +#define ACTION_SWITCH_TO_RFTEST 0 /* to switch firmware mode between normal mode + * or rf test mode + */ +#define ACTION_IN_RFTEST 1 + +#define HQA_CMD_MAGIC_NO 0x18142880 +#define HQA_CHIP_ID_6632 0x6632 +#define HQA_CHIP_ID_7668 0x7668 + +/* (4096(Samples/Bank) * 6Banks * 3(IQSamples/Sample) * 32bits)/96bits */ +#define MAX_ICAP_IQ_DATA_CNT (4096 * 8) +#define ICAP_EVENT_DATA_SAMPLE 256 + + +#if CFG_SUPPORT_TX_BF +#define HQA_BF_STR_SIZE 512 +#endif + +#define HQA_RX_STATISTIC_NUM 66 + +#ifdef MAX_EEPROM_BUFFER_SIZE +#undef MAX_EEPROM_BUFFER_SIZE +#endif +#define MAX_EEPROM_BUFFER_SIZE 1200 + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +extern uint8_t uacEEPROMImage[MAX_EEPROM_BUFFER_SIZE]; + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +#if 0 +struct PARAM_RX_STAT { + uint32_t MacFCSErr; /* Y 0x820F_D014 */ + uint32_t MacMdrdy; /* Y 0x820F_D030 */ + uint32_t FCSErr_CCK; /* Y 0x8207_021C [15:00] */ + uint32_t FCSErr_OFDM; /* Y 0x8207_021C [31:16] */ + uint32_t CCK_PD; /* Y 0x8207_020C [15:00] */ + uint32_t OFDM_PD; /* Y 0x8207_020C [15:00] */ + uint32_t CCK_SIG_Err; /* Y 0x8207_0210 [31:16] */ + uint32_t CCK_SFD_Err; /* Y 0x8207_0210 [15:00] */ + uint32_t OFDM_SIG_Err; /* Y 0x8207_0214 [31:16] */ + uint32_t OFDM_TAG_Err; /* Y 0x8207_0214 [15:00] */ + uint32_t WB_RSSSI0; /* Y 0x8207_21A8 [23:16] */ + uint32_t IB_RSSSI0; /* Y 0x8207_21A8 [31:24] */ + uint32_t WB_RSSSI1; /* Y 0x8207_21A8 [07:00] */ + uint32_t IB_RSSSI1; /* Y 0x8207_21A8 [15:08] */ + uint32_t PhyMdrdyCCK; /* Y 0x8207_0220 [15:00] */ + uint32_t PhyMdrdyOFDM; /* Y 0x8207_0220 [31:16] */ + uint32_t DriverRxCount; /* Y FW Counter Band0 */ + uint32_t RCPI0; /* Y RXV4 [07:00] */ + uint32_t RCPI1; /* Y RXV4 [15:08] */ + uint32_t FreqOffsetFromRX; /* Y RXV5 MISC1[24:00] OFDM:[11:00] + * CCK:[10:00] + */ + uint32_t RSSI0; /* N */ + uint32_t RSSI1; /* N */ + uint32_t rx_fifo_full; /* N */ + uint32_t RxLenMismatch; /* N */ + uint32_t MacFCSErr_band1; /* Y 0x820F_D214 */ + uint32_t MacMdrdy_band1; /* Y 0x820F_D230 */ + /* Y RXV3 [23:16] (must set 0x8207066C[1:0] = 0x0 ~ 0x3) */ + uint32_t FAGC_IB_RSSSI[4]; + /* Y RXV3 [31:24] (must set 0x8207066C[1:0] = 0x0 ~ 0x3) */ + uint32_t FAGC_WB_RSSSI[4]; + /* Y 0x8207_21A8 [31:24] [15:08] 0x8207_29A8 [31:24] [15:08] */ + uint32_t Inst_IB_RSSSI[4]; + /* Y 0x8207_21A8 [23:16] [07:00] 0x8207_29A8 [23:16] [07:00] */ + uint32_t Inst_WB_RSSSI[4]; + uint32_t ACIHitLow; /* Y 0x8207_21B0 [18] */ + uint32_t ACIHitHigh; /* Y 0x8207_29B0 [18] */ + uint32_t DriverRxCount1; /* Y FW Counter Band1 */ + uint32_t RCPI2; /* Y RXV4 [23:16] */ + uint32_t RCPI3; /* Y RXV4 [31:24] */ + uint32_t RSSI2; /* N */ + uint32_t RSSI3; /* N */ + uint32_t SNR0; /* Y RXV5 (MISC1 >> 19) - 16 */ + uint32_t SNR1; /* N */ + uint32_t SNR2; /* N */ + uint32_t SNR3; /* N */ + uint32_t rx_fifo_full_band1; /* N */ + uint32_t RxLenMismatch_band1; /* N */ + uint32_t CCK_PD_band1; /* Y 0x8207_040C [15:00] */ + uint32_t OFDM_PD_band1; /* Y 0x8207_040C [31:16] */ + uint32_t CCK_SIG_Err_band1; /* Y 0x8207_0410 [31:16] */ + uint32_t CCK_SFD_Err_band1; /* Y 0x8207_0410 [15:00] */ + uint32_t OFDM_SIG_Err_band1; /* Y 0x8207_0414 [31:16] */ + uint32_t OFDM_TAG_Err_band1; /* Y 0x8207_0414 [15:00] */ + uint32_t PhyMdrdyCCK_band1; /* Y 0x8207_0420 [15:00] */ + uint32_t PhyMdrdyOFDM_band1; /* Y 0x8207_0420 [31:16] */ + uint32_t CCK_FCS_Err_band1; /* Y 0x8207_041C [15:00] */ + uint32_t OFDM_FCS_Err_band1; /* Y 0x8207_041C [31:16] */ + uint32_t MuPktCount; /* Y MT_ATEUpdateRxStatistic + * RXV1_2ND_CYCLE->GroupId + */ +}; +#else +struct PARAM_RX_STAT { + uint32_t MAC_FCS_Err; /* b0 */ + uint32_t MAC_Mdrdy; /* b0 */ + uint32_t FCSErr_CCK; + uint32_t FCSErr_OFDM; + uint32_t CCK_PD; + uint32_t OFDM_PD; + uint32_t CCK_SIG_Err; + uint32_t CCK_SFD_Err; + uint32_t OFDM_SIG_Err; + uint32_t OFDM_TAG_Err; + uint32_t WB_RSSI0; + uint32_t IB_RSSI0; + uint32_t WB_RSSI1; + uint32_t IB_RSSI1; + uint32_t PhyMdrdyCCK; + uint32_t PhyMdrdyOFDM; + uint32_t DriverRxCount; + uint32_t RCPI0; + uint32_t RCPI1; + uint32_t FreqOffsetFromRX; + uint32_t RSSI0; + uint32_t RSSI1; /* insert new member here */ + uint32_t OutOfResource; /* MT7615 begin here */ + uint32_t LengthMismatchCount_B0; + uint32_t MAC_FCS_Err1; /* b1 */ + uint32_t MAC_Mdrdy1; /* b1 */ + uint32_t FAGCRssiIBR0; + uint32_t FAGCRssiIBR1; + uint32_t FAGCRssiIBR2; + uint32_t FAGCRssiIBR3; + uint32_t FAGCRssiWBR0; + uint32_t FAGCRssiWBR1; + uint32_t FAGCRssiWBR2; + uint32_t FAGCRssiWBR3; + + uint32_t InstRssiIBR0; + uint32_t InstRssiIBR1; + uint32_t InstRssiIBR2; + uint32_t InstRssiIBR3; + uint32_t InstRssiWBR0; + uint32_t InstRssiWBR1; + uint32_t InstRssiWBR2; + uint32_t InstRssiWBR3; + uint32_t ACIHitLower; + uint32_t ACIHitUpper; + uint32_t DriverRxCount1; + uint32_t RCPI2; + uint32_t RCPI3; + uint32_t RSSI2; + uint32_t RSSI3; + uint32_t SNR0; + uint32_t SNR1; + uint32_t SNR2; + uint32_t SNR3; + uint32_t OutOfResource1; + uint32_t LengthMismatchCount_B1; + uint32_t CCK_PD_Band1; + uint32_t OFDM_PD_Band1; + uint32_t CCK_SIG_Err_Band1; + uint32_t CCK_SFD_Err_Band1; + uint32_t OFDM_SIG_Err_Band1; + uint32_t OFDM_TAG_Err_Band1; + uint32_t PHY_CCK_MDRDY_Band1; + uint32_t PHY_OFDM_MDRDY_Band1; + uint32_t CCK_FCS_Err_Band1; + uint32_t OFDM_FCS_Err_Band1; + uint32_t MRURxCount; + uint32_t SIGMCS; + uint32_t SINR; + uint32_t RXVRSSI; + uint32_t Reserved[184]; + uint32_t PHY_Mdrdy; + uint32_t Noise_Floor; + uint32_t AllLengthMismatchCount_B0; + uint32_t AllLengthMismatchCount_B1; + uint32_t AllMacMdrdy0; + uint32_t AllMacMdrdy1; + uint32_t AllFCSErr0; + uint32_t AllFCSErr1; + uint32_t RXOK0; + uint32_t RXOK1; + uint32_t PER0; + uint32_t PER1; +}; +extern struct PARAM_RX_STAT g_HqaRxStat; +#endif + +struct HQA_CMD_FRAME { + uint32_t MagicNo; + uint16_t Type; + uint16_t Id; + uint16_t Length; + uint16_t Sequence; + uint8_t Data[2048]; +} __KAL_ATTRIB_PACKED__; + +/* TODO: os-related, implement with correspoinding structure in OS */ +typedef int32_t(*HQA_CMD_HANDLER) (void *prNetDev, + IN void *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame); + +struct HQA_CMD_TABLE { + HQA_CMD_HANDLER *CmdSet; + uint32_t CmdSetSize; + uint32_t CmdOffset; +}; + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/* TODO: os-related, implement with correspoinding structure in OS + * just use linux as function declare prototype + */ +int HQA_CMDHandler(void *prNetDev, + void *prIwReqData, + struct HQA_CMD_FRAME *HqaCmdFrame); + +int priv_qa_agent(IN void *prNetDev, + IN void *prIwReqInfo, + IN void *prIwReqData, IN char *pcExtra); + +int32_t mt6632SetICapStart(struct GLUE_INFO *prGlueInfo, + uint32_t u4Trigger, uint32_t u4RingCapEn, + uint32_t u4Event, uint32_t u4Node, uint32_t u4Len, + uint32_t u4StopCycle, + uint32_t u4BW, uint32_t u4MacTriggerEvent, + uint32_t u4SourceAddrLSB, + uint32_t u4SourceAddrMSB, uint32_t u4Band); +int32_t mt6632GetICapStatus(struct GLUE_INFO *prGlueInfo); + +int32_t connacSetICapStart(struct GLUE_INFO *prGlueInfo, + uint32_t u4Trigger, uint32_t u4RingCapEn, + uint32_t u4Event, uint32_t u4Node, uint32_t u4Len, + uint32_t u4StopCycle, + uint32_t u4BW, uint32_t u4MacTriggerEvent, + uint32_t u4SourceAddrLSB, + uint32_t u4SourceAddrMSB, uint32_t u4Band); +int32_t connacGetICapStatus(struct GLUE_INFO *prGlueInfo); + +int32_t commonGetICapIQData(struct GLUE_INFO *prGlueInfo, + uint8_t *pData, uint32_t u4IQType, uint32_t u4WFNum); +int32_t connacGetICapIQData(struct GLUE_INFO *prGlueInfo, + uint8_t *pData, uint32_t u4IQType, uint32_t u4WFNum); + + +#endif /*CFG_SUPPORT_QA_TOOL */ +#endif /* _GL_QA_AGENT_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/include/gl_rst.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/include/gl_rst.h new file mode 100644 index 0000000000000000000000000000000000000000..ccf4fad18d9d90781bdb2b5b9d135fc09a5b9190 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/include/gl_rst.h @@ -0,0 +1,218 @@ +/******************************************************************************* + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include + * /gl_rst.h#1 + */ + +/*! \file gl_rst.h + * \brief Declaration of functions and finite state machine for + * MT6620 Whole-Chip Reset Mechanism + */ + +#ifndef _GL_RST_H +#define _GL_RST_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "gl_typedef.h" + +#if 0 +#include "mtk_porting.h" +#endif +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#if (MTK_WCN_HIF_SDIO == 1) || (MTK_WCN_HIF_AXI == 1) +#define CFG_WMT_RESET_API_SUPPORT 1 +#else +#define CFG_WMT_RESET_API_SUPPORT 0 +#endif + +#define RST_FLAG_CHIP_RESET 0 +#define RST_FLAG_DO_CORE_DUMP BIT(0) +#define RST_FLAG_PREVENT_POWER_OFF BIT(1) +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +enum ENUM_RESET_STATUS { + RESET_FAIL, + RESET_SUCCESS +}; + +/* TODO: os-related, implementation reference */ +#if 0 +struct RESET_STRUCT { + enum ENUM_RESET_STATUS rst_data; + struct work_struct rst_work; + struct work_struct rst_trigger_work; + uint32_t rst_trigger_flag; +}; +#endif + +#if (CFG_SUPPORT_CONNINFRA == 1) +enum ENUM_WMTMSG_TYPE { + WMTMSG_TYPE_POWER_ON = 0, + WMTMSG_TYPE_POWER_OFF = 1, + WMTMSG_TYPE_RESET = 2, + WMTMSG_TYPE_STP_RDY = 3, + WMTMSG_TYPE_HW_FUNC_ON = 4, + WMTMSG_TYPE_MAX +}; + +enum ENUM_WMTRSTMSG_TYPE { + WMTRSTMSG_RESET_START = 0x0, /*whole chip reset (include other radio)*/ + WMTRSTMSG_RESET_END = 0x1, + WMTRSTMSG_RESET_END_FAIL = 0x2, + WMTRSTMSG_0P5RESET_START = 0x3, /*wfsys reset ( wifi only )*/ + WMTRSTMSG_RESET_MAX, + WMTRSTMSG_RESET_INVALID = 0xff +}; + +enum ENUM_WF_RST_SOURCE { + WF_RST_SOURCE_NONE = 0x0, + WF_RST_SOURCE_DRIVER = 0x1, + WF_RST_SOURCE_FW = 0x2, + WF_RST_SOURCE_MAX +}; +#endif + +enum _ENUM_CHIP_RESET_REASON_TYPE_T { + RST_PROCESS_ABNORMAL_INT = 1, + RST_DRV_OWN_FAIL, + RST_FW_ASSERT, + RST_BT_TRIGGER, + RST_OID_TIMEOUT, + RST_CMD_TRIGGER, + RST_REASON_MAX +}; + +/******************************************************************************* + * E X T E R N A L F U N C T I O N S + ******************************************************************************* + */ + +#if CFG_CHIP_RESET_SUPPORT +extern int wifi_reset_start(void); +extern int wifi_reset_end(enum ENUM_RESET_STATUS); +#endif + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ +#if CFG_CHIP_RESET_SUPPORT +#define GL_RESET_TRIGGER(_prAdapter, _u4Flags) \ + glResetTrigger(_prAdapter, (_u4Flags), \ + (const uint8_t *)__FILE__, __LINE__) +#else +#define GL_RESET_TRIGGER(_prAdapter, _u4Flags) \ + DBGLOG(INIT, INFO, "DO NOT support chip reset\n") +#endif + +extern uint64_t u8ResetTime; +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ +void glResetInit(void); + +void glResetUninit(void); + +void glSendResetRequest(void); + +int32_t glIsWmtCodeDump(void); + +#ifdef CFG_REMIND_IMPLEMENT +#define glSetRstReason(_eReason) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +#define glGetRstReason() \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) + +#define glResetTrigger(prAdapter, u4RstFlag, pucFile, u4Line) \ + KAL_NEED_IMPLEMENT(__FILE__, __func__, __LINE__) +#else +void glSetRstReason(enum _ENUM_CHIP_RESET_REASON_TYPE_T + eReason); + +int glSetRstReason(void); +u_int8_t glResetTrigger(struct ADAPTER *prAdapter, + uint32_t u4RstFlag, const uint8_t *pucFile, + uint32_t u4Line); +#endif + +#endif /* _GL_RST_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/include/gl_typedef.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/include/gl_typedef.h new file mode 100644 index 0000000000000000000000000000000000000000..9b9ff2618fd50dafd1fceaf6f21a906627df0a74 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/include/gl_typedef.h @@ -0,0 +1,310 @@ +/******************************************************************************* + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ +/* + * Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include + * /gl_typedef.h#1 + */ + +/*! \file gl_typedef.h + * \brief Definition of basic data type(os dependent). + * + * In this file we define the basic data type. + */ + + +#ifndef _GL_TYPEDEF_H +#define _GL_TYPEDEF_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +/* Define HZ of timer tick for function kalGetTimeTick() */ +#define KAL_HZ (1000) + +/* Miscellaneous Equates */ +#ifndef FALSE +#define FALSE ((u_int8_t) 0) +#define TRUE ((u_int8_t) 1) +#endif /* FALSE */ + +#ifndef NULL +#if defined(__cplusplus) +#define NULL 0 +#else +#define NULL ((void *) 0) +#endif +#endif + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +/* Type definition for void */ + +/* Type definition for Boolean */ + +/* Type definition for signed integers */ + +/* Type definition for unsigned integers */ + + +#define OS_SYSTIME uint32_t + +/* Type definition of large integer (64bits) union to be comptaible with + * Windows definition, so we won't apply our own coding style to these data + * types. + * NOTE: LARGE_INTEGER must NOT be floating variable. + * : Check for big-endian compatibility. + */ +union LARGE_INTEGER { + struct { + uint32_t LowPart; + int32_t HighPart; + } u; + int64_t QuadPart; +}; + +union ULARGE_INTEGER { + struct { + uint32_t LowPart; + uint32_t HighPart; + } u; + uint64_t QuadPart; +}; + +typedef int32_t(*probe_card) (void *pvData, + void *pvDriverData); +typedef void(*remove_card) (void); + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ +#define IN /* volatile */ +#define OUT /* volatile */ + +#define __KAL_INLINE__ inline +#define __KAL_ATTRIB_PACKED__ __attribute__((__packed__)) +#define __KAL_ATTRIB_ALIGN_4__ __aligned(4) + +#ifndef BIT +#define BIT(n) ((uint32_t) 1UL << (n)) +#endif /* BIT */ + +#ifndef BITS +/* bits range: for example BITS(16,23) = 0xFF0000 + * ==> (BIT(m)-1) = 0x0000FFFF ~(BIT(m)-1) => 0xFFFF0000 + * ==> (BIT(n+1)-1) = 0x00FFFFFF + */ +#define BITS(m, n) (~(BIT(m)-1) & ((BIT(n) - 1) | BIT(n))) +#endif /* BIT */ + +/* This macro returns the byte offset of a named field in a known structure + * type. + * _type - structure name, + * _field - field name of the structure + */ +#ifndef OFFSET_OF +#define OFFSET_OF(_type, _field) ((unsigned long)&(((_type *)0)->_field)) +#endif /* OFFSET_OF */ + +/* This macro returns the base address of an instance of a structure + * given the type of the structure and the address of a field within the + * containing structure. + * _addrOfField - address of current field of the structure, + * _type - structure name, + * _field - field name of the structure + */ +#ifndef ENTRY_OF +#define ENTRY_OF(_addrOfField, _type, _field) \ + ((_type *)((int8_t *)(_addrOfField) - \ + (int8_t *)OFFSET_OF(_type, _field))) +#endif /* ENTRY_OF */ + +/* This macro align the input value to the DW boundary. + * _value - value need to check + */ +#ifndef ALIGN_4 +#define ALIGN_4(_value) (((_value) + 3) & ~3u) +#endif /* ALIGN_4 */ + +#ifndef ALIGN_8 +#define ALIGN_8(_value) (((_value) + 7) & ~7u) +#endif /* ALIGN_4 */ + +/* This macro check the DW alignment of the input value. + * _value - value of address need to check + */ +#ifndef IS_ALIGN_4 +#define IS_ALIGN_4(_value) (((_value) & 0x3) ? FALSE : TRUE) +#endif /* IS_ALIGN_4 */ + +#ifndef IS_NOT_ALIGN_4 +#define IS_NOT_ALIGN_4(_value) (((_value) & 0x3) ? TRUE : FALSE) +#endif /* IS_NOT_ALIGN_4 */ + +/* This macro evaluate the input length in unit of Double Word(4 Bytes). + * _value - value in unit of Byte, output will round up to DW boundary. + */ +#ifndef BYTE_TO_DWORD +#define BYTE_TO_DWORD(_value) ((_value + 3) >> 2) +#endif /* BYTE_TO_DWORD */ + +/* This macro evaluate the input length in unit of Byte. + * _value - value in unit of DW, output is in unit of Byte. + */ +#ifndef DWORD_TO_BYTE +#define DWORD_TO_BYTE(_value) ((_value) << 2) +#endif /* DWORD_TO_BYTE */ + +#if 1 /* Little-Endian */ +#define CONST_NTOHS(_x) ntohs(_x) + +#define CONST_HTONS(_x) htons(_x) + +#define NTOHS(_x) ntohs(_x) + +#define HTONS(_x) htons(_x) + +#define NTOHL(_x) ntohl(_x) + +#define HTONL(_x) htonl(_x) + +#else /* Big-Endian */ + +#define CONST_NTOHS(_x) + +#define CONST_HTONS(_x) + +#define NTOHS(_x) + +#define HTONS(_x) + +#endif + +#define CPU_TO_LE16 cpu_to_le16 +#define CPU_TO_LE32 cpu_to_le32 +#define CPU_TO_LE64 cpu_to_le64 + +#define LE16_TO_CPU le16_to_cpu +#define LE32_TO_CPU le32_to_cpu +#define LE64_TO_CPU le64_to_cpu + +#define SWAP32(x) \ + ((uint32_t) (\ + (((uint32_t) (x) & (uint32_t) 0x000000ffUL) << 24) | \ + (((uint32_t) (x) & (uint32_t) 0x0000ff00UL) << 8) | \ + (((uint32_t) (x) & (uint32_t) 0x00ff0000UL) >> 8) | \ + (((uint32_t) (x) & (uint32_t) 0xff000000UL) >> 24))) + +/* Endian byte swapping codes */ +#ifdef __LITTLE_ENDIAN +#define LE48_TO_CPU(x) (x) +#define CPU_TO_LE48(x) (x) +#define cpu2le32(x) ((uint32_t)(x)) +#define le2cpu32(x) ((uint32_t)(x)) +#define cpu2be32(x) SWAP32((x)) +#define be2cpu32(x) SWAP32((x)) + +#else + + +#define SWAP48(x) \ + ((uint64_t)( \ + (uint64_t)(((UINT_64)(x) & (uint64_t) 0x0000000000ffULL) << 40) | \ + (uint64_t)(((UINT_64)(x) & (uint64_t) 0x00000000ff00ULL) << 24) | \ + (uint64_t)(((UINT_64)(x) & (uint64_t) 0x000000ff0000ULL) << 8) | \ + (uint64_t)(((UINT_64)(x) & (uint64_t) 0x0000ff000000ULL) >> 8) | \ + (uint64_t)(((UINT_64)(x) & (uint64_t) 0x00ff00000000ULL) >> 24) | \ + (uint64_t)(((UINT_64)(x) & (uint64_t) 0xff0000000000ULL) >> 40))) +#define LE48_TO_CPU(x) SWAP48(x) +#define CPU_TO_LE48(x) SWAP48(x) +#define cpu2le32(x) SWAP32((x)) +#define le2cpu32(x) SWAP32((x)) +#define cpu2be32(x) ((uint32_t)(x)) +#define be2cpu32(x) ((uint32_t)(x)) + + +#endif + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#endif /* _GL_TYPEDEF_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/include/gl_vendor.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/include/gl_vendor.h new file mode 100644 index 0000000000000000000000000000000000000000..35cf0b7497901a4e97ff553b86ecba540617f27e --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/include/gl_vendor.h @@ -0,0 +1,714 @@ +/******************************************************************************* + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ +/* + * Log: gl_vendor.h + * + * 10 14 2014 + * add vendor declaration + * some structure is needed by common part in this file + * 1) struct PARAM_PACKET_KEEPALIVE_T needed by nic_cmd_event.h + */ + +#ifndef _GL_VENDOR_H +#define _GL_VENDOR_H + +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ +#include "wlan_lib.h" + + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +#define GOOGLE_OUI 0x001A11 +#define OUI_QCA 0x001374 + +#define NL80211_VENDOR_SUBCMD_GET_PREFER_FREQ_LIST 103 +#define QCA_NL80211_VENDOR_SUBCMD_ROAM 64 +#define QCA_NL80211_VENDOR_SUBCMD_SETBAND 105 + +enum ANDROID_VENDOR_SUB_COMMAND { + /* Don't use 0 as a valid subcommand */ + ANDROID_NL80211_SUBCMD_UNSPECIFIED, + + /* Define all vendor startup commands between 0x0 and 0x0FFF */ + ANDROID_NL80211_SUBCMD_WIFI_RANGE_START = 0x0001, + ANDROID_NL80211_SUBCMD_WIFI_RANGE_END = 0x0FFF, + + /* Define all GScan related commands between 0x1000 and 0x10FF */ + ANDROID_NL80211_SUBCMD_GSCAN_RANGE_START = 0x1000, + ANDROID_NL80211_SUBCMD_GSCAN_RANGE_END = 0x10FF, + + /* Define all RTT related commands between 0x1100 and 0x11FF */ + ANDROID_NL80211_SUBCMD_RTT_RANGE_START = 0x1100, + ANDROID_NL80211_SUBCMD_RTT_RANGE_END = 0x11FF, + + ANDROID_NL80211_SUBCMD_LSTATS_RANGE_START = 0x1200, + ANDROID_NL80211_SUBCMD_LSTATS_RANGE_END = 0x12FF, + + /* Define all Logger related commands between 0x1400 and 0x14FF */ + ANDROID_NL80211_SUBCMD_DEBUG_RANGE_START = 0x1400, + ANDROID_NL80211_SUBCMD_DEBUG_RANGE_END = 0x14FF, + + /* Define all wifi offload related commands between 0x1600 and 0x16FF */ + ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_START = 0x1600, + ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_END = 0x16FF, + + /* This is reserved for future usage */ + +}; + +enum WIFI_SUB_COMMAND { + WIFI_SUBCMD_GET_CHANNEL_LIST = ANDROID_NL80211_SUBCMD_WIFI_RANGE_START, + + WIFI_SUBCMD_GET_FEATURE_SET, /* 0x0002 */ + WIFI_SUBCMD_GET_FEATURE_SET_MATRIX, /* 0x0003 */ + WIFI_SUBCMD_SET_PNO_RANDOM_MAC_OUI, /* 0x0004 */ + WIFI_SUBCMD_NODFS_SET, /* 0x0005 */ + WIFI_SUBCMD_SET_COUNTRY_CODE, /* 0x0006 */ + WIFI_SUBCMD_SET_RSSI_MONITOR, /* 0x0007 */ + + /* Add more sub commands here */ + WIFI_SUBCMD_GET_ROAMING_CAPABILITIES, /* 0x0008 */ + WIFI_SUBCMD_SET_ROAMING = 0x0009, /* 0x0009 */ + WIFI_SUBCMD_CONFIG_ROAMING = 0x000a, /* 0x000a */ + WIFI_SUBCMD_ENABLE_ROAMING /* 0x000b */ +}; + +enum RTT_SUB_COMMAND { + RTT_SUBCMD_SET_CONFIG = ANDROID_NL80211_SUBCMD_RTT_RANGE_START, + RTT_SUBCMD_CANCEL_CONFIG, + RTT_SUBCMD_GETCAPABILITY, +}; + +enum LSTATS_SUB_COMMAND { + LSTATS_SUBCMD_GET_INFO = ANDROID_NL80211_SUBCMD_LSTATS_RANGE_START, +}; + +/* moved from wifi_logger.cpp */ +enum DEBUG_SUB_COMMAND { + LOGGER_START_LOGGING = ANDROID_NL80211_SUBCMD_DEBUG_RANGE_START, + LOGGER_GET_VER +}; + +enum WIFI_OFFLOAD_SUB_COMMAND { + WIFI_OFFLOAD_START_MKEEP_ALIVE = + ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_START, + WIFI_OFFLOAD_STOP_MKEEP_ALIVE, +}; + +enum WIFI_VENDOR_EVENT { + GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS, + GSCAN_EVENT_HOTLIST_RESULTS_FOUND, + GSCAN_EVENT_SCAN_RESULTS_AVAILABLE, + GSCAN_EVENT_FULL_SCAN_RESULTS, + RTT_EVENT_COMPLETE, + GSCAN_EVENT_COMPLETE_SCAN, + GSCAN_EVENT_HOTLIST_RESULTS_LOST, + WIFI_EVENT_RSSI_MONITOR +}; + +enum WIFI_ATTRIBUTE { + WIFI_ATTRIBUTE_BAND = 1, + WIFI_ATTRIBUTE_NUM_CHANNELS, + WIFI_ATTRIBUTE_CHANNEL_LIST, + + WIFI_ATTRIBUTE_NUM_FEATURE_SET, + WIFI_ATTRIBUTE_FEATURE_SET, + WIFI_ATTRIBUTE_PNO_RANDOM_MAC_OUI, + WIFI_ATTRIBUTE_NODFS_VALUE, + WIFI_ATTRIBUTE_COUNTRY_CODE, + + WIFI_ATTRIBUTE_MAX_RSSI, + WIFI_ATTRIBUTE_MIN_RSSI, + WIFI_ATTRIBUTE_RSSI_MONITOR_START, + + WIFI_ATTRIBUTE_ROAMING_CAPABILITIES, + WIFI_ATTRIBUTE_ROAMING_BLACKLIST_NUM, + WIFI_ATTRIBUTE_ROAMING_BLACKLIST_BSSID, + WIFI_ATTRIBUTE_ROAMING_WHITELIST_NUM, + WIFI_ATTRIBUTE_ROAMING_WHITELIST_SSID, + WIFI_ATTRIBUTE_ROAMING_STATE +}; + +/* moved from wifi_logger.cpp */ +enum LOGGER_ATTRIBUTE { + LOGGER_ATTRIBUTE_DRIVER_VER, + LOGGER_ATTRIBUTE_FW_VER +}; + +enum RTT_ATTRIBUTE { + RTT_ATTRIBUTE_CAPABILITIES = 1, + + RTT_ATTRIBUTE_TARGET_CNT = 10, + RTT_ATTRIBUTE_TARGET_INFO, + RTT_ATTRIBUTE_TARGET_MAC, + RTT_ATTRIBUTE_TARGET_TYPE, + RTT_ATTRIBUTE_TARGET_PEER, + RTT_ATTRIBUTE_TARGET_CHAN, + RTT_ATTRIBUTE_TARGET_PERIOD, + RTT_ATTRIBUTE_TARGET_NUM_BURST, + RTT_ATTRIBUTE_TARGET_NUM_FTM_BURST, + RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTM, + RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTMR, + RTT_ATTRIBUTE_TARGET_LCI, + RTT_ATTRIBUTE_TARGET_LCR, + RTT_ATTRIBUTE_TARGET_BURST_DURATION, + RTT_ATTRIBUTE_TARGET_PREAMBLE, + RTT_ATTRIBUTE_TARGET_BW, + RTT_ATTRIBUTE_RESULTS_COMPLETE = 30, + RTT_ATTRIBUTE_RESULTS_PER_TARGET, + RTT_ATTRIBUTE_RESULT_CNT, + RTT_ATTRIBUTE_RESULT +}; + +enum LSTATS_ATTRIBUTE { + LSTATS_ATTRIBUTE_STATS = 2, +}; + +enum WIFI_MKEEP_ALIVE_ATTRIBUTE { + MKEEP_ALIVE_ATTRIBUTE_ID = 1, + MKEEP_ALIVE_ATTRIBUTE_IP_PKT_LEN, + MKEEP_ALIVE_ATTRIBUTE_IP_PKT, + MKEEP_ALIVE_ATTRIBUTE_SRC_MAC_ADDR, + MKEEP_ALIVE_ATTRIBUTE_DST_MAC_ADDR, + MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC +}; + +/* QCA Vender CMD */ +enum QCA_SET_BAND { + QCA_SETBAND_AUTO, + QCA_SETBAND_5G, + QCA_SETBAND_2G, +}; + +enum QCA_ATTR_ROAM_SUBCMD { + QCA_ATTR_ROAM_SUBCMD_INVALID = 0, + QCA_ATTR_ROAM_SUBCMD_SET_BLACKLIST_BSSID = 6, + + /* keep last */ + QCA_ATTR_ROAM_SUBCMD_AFTER_LAST, + QCA_ATTR_ROAM_SUBCMD_MAX = + QCA_ATTR_ROAM_SUBCMD_AFTER_LAST - 1, +}; + +enum QCA_ATTR_ROAMING_PARAMS { + QCA_ATTR_ROAMING_PARAM_INVALID = 0, + + QCA_ATTR_ROAMING_SUBCMD = 1, + + /* Attribute for set_blacklist bssid params */ + QCA_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS = 18, + QCA_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_NUM_BSSID = 19, + QCA_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_BSSID = 20, + + /* keep last */ + QCA_ATTR_ROAMING_PARAM_AFTER_LAST, + QCA_ATTR_ROAMING_PARAM_MAX = + QCA_ATTR_ROAMING_PARAM_AFTER_LAST - 1, +}; + +enum WIFI_VENDOR_ATTR_PREFERRED_FREQ_LIST { + WIFI_VENDOR_ATTR_PREFERRED_FREQ_LIST_INVALID, + WIFI_VENDOR_ATTR_PREFERRED_FREQ_LIST_IFACE_TYPE, + WIFI_VENDOR_ATTR_PREFERRED_FREQ_LIST_GET, + WIFI_VENDOR_ATTR_PREFERRED_FREQ_LIST_LAST, + WIFI_VENDOR_ATTR_PREFERRED_FREQ_LIST_MAX = + WIFI_VENDOR_ATTR_PREFERRED_FREQ_LIST_LAST - 1 +}; + +#define MAX_FW_ROAMING_BLACKLIST_SIZE 16 +#define MAX_FW_ROAMING_WHITELIST_SIZE 8 + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ +#if CFG_SUPPORT_WAPI +extern uint8_t +keyStructBuf[1024]; /* add/remove key shared buffer */ +#else +extern uint8_t +keyStructBuf[100]; /* add/remove key shared buffer */ +#endif + +/******************************************************************************* + * MACROS + ******************************************************************************* + */ +/* + * TODO: function is os-related, while may depend on the purpose of function + * to implement on other os + */ +#if 0 +#if KERNEL_VERSION(3, 5, 0) <= LINUX_VERSION_CODE +/* + * #define NLA_PUT(skb, attrtype, attrlen, data) \ + * do { \ + * if (unlikely(nla_put(skb, attrtype, attrlen, data) < 0)) \ + * goto nla_put_failure; \ + * } while (0) + * + *#define NLA_PUT_TYPE(skb, type, attrtype, value) \ + * do { \ + * type __tmp = value; \ + * NLA_PUT(skb, attrtype, sizeof(type), &__tmp); \ + * } while (0) + */ +#define NLA_PUT(skb, attrtype, attrlen, data) \ + mtk_cfg80211_NLA_PUT(skb, attrtype, attrlen, data) + +#define NLA_PUT_TYPE(skb, type, attrtype, value) \ + mtk_cfg80211_nla_put_type(skb, type, attrtype, value) + +#define NLA_PUT_U8(skb, attrtype, value) \ + NLA_PUT_TYPE(skb, NLA_PUT_DATE_U8, attrtype, value) + +#define NLA_PUT_U16(skb, attrtype, value) \ + NLA_PUT_TYPE(skb, NLA_PUT_DATE_U16, attrtype, value) + +#define NLA_PUT_U32(skb, attrtype, value) \ + NLA_PUT_TYPE(skb, NLA_PUT_DATE_U32, attrtype, value) + +#define NLA_PUT_U64(skb, attrtype, value) \ + NLA_PUT_TYPE(skb, NLA_PUT_DATE_U64, attrtype, value) + +#endif + +#if KERNEL_VERSION(4, 12, 0) <= CFG80211_VERSION_CODE +#define NLA_PARSE_NESTED(nlattr, maxtype, nla, policy) \ + nla_parse_nested(nlattr, maxtype, nla, policy, NULL) +#define NLA_PARSE(tb, maxtype, head, len, policy) \ + nla_parse(tb, maxtype, head, len, policy, NULL) +#else +#define NLA_PARSE_NESTED(nlattr, maxtype, nla, policy) \ + nla_parse_nested(nlattr, maxtype, nla, policy) +#define NLA_PARSE(tb, maxtype, head, len, policy) \ + nla_parse(tb, maxtype, head, len, policy) +#endif +#endif +/******************************************************************************* + * P R I V A T E D A T A + * + ******************************************************************************* + */ +struct PARAM_WIFI_CHANGE_RESULT { + uint16_t flags; + uint16_t channel; + uint8_t bssid[6]; /* BSSID */ + int8_t rssi[8]; /* RSSI history in db */ +}; + +struct PARAM_AP_THRESHOLD { + uint8_t bssid[6]; /* AP BSSID */ + int32_t low; /* low threshold */ + int32_t high; /* high threshold */ + uint32_t channel; /* channel hint */ +}; + +/* channel operating width */ +enum WIFI_CHANNEL_WIDTH { + WIFI_CHAN_WIDTH_20 = 0, + WIFI_CHAN_WIDTH_40 = 1, + WIFI_CHAN_WIDTH_80 = 2, + WIFI_CHAN_WIDTH_160 = 3, + WIFI_CHAN_WIDTH_80P80 = 4, + WIFI_CHAN_WIDTH_5 = 5, + WIFI_CHAN_WIDTH_10 = 6, + WIFI_CHAN_WIDTH_INVALID = -1 +}; + +/* channel information */ +struct WIFI_CHANNEL_INFO { + enum WIFI_CHANNEL_WIDTH width; + uint32_t center_freq; + uint32_t center_freq0; + uint32_t center_freq1; +}; + +/* channel statistics */ +struct WIFI_CHANNEL_STAT { + struct WIFI_CHANNEL_INFO channel; + uint32_t on_time; + uint32_t cca_busy_time; +}; + +/* radio statistics */ +struct WIFI_RADIO_STAT { + uint32_t radio; + uint32_t on_time; + uint32_t tx_time; + uint32_t rx_time; + uint32_t on_time_scan; + uint32_t on_time_nbd; + uint32_t on_time_gscan; + uint32_t on_time_roam_scan; + uint32_t on_time_pno_scan; + uint32_t on_time_hs20; + uint32_t num_channels; + struct WIFI_CHANNEL_STAT channels[]; +}; + +/* wifi rate */ +struct WIFI_RATE { + uint32_t preamble: 3; + uint32_t nss: 2; + uint32_t bw: 3; + uint32_t rateMcsIdx: 8; + + uint32_t reserved: 16; + uint32_t bitrate; +}; + +/* per rate statistics */ +struct WIFI_RATE_STAT { + struct WIFI_RATE rate; + uint32_t tx_mpdu; + uint32_t rx_mpdu; + uint32_t mpdu_lost; + uint32_t retries; + uint32_t retries_short; + uint32_t retries_long; +}; + +/*wifi_interface_link_layer_info*/ +enum WIFI_CONNECTION_STATE { + WIFI_DISCONNECTED = 0, + WIFI_AUTHENTICATING = 1, + WIFI_ASSOCIATING = 2, + WIFI_ASSOCIATED = 3, + WIFI_EAPOL_STARTED = 4, + WIFI_EAPOL_COMPLETED = 5, +}; + +enum WIFI_ROAM_STATE { + WIFI_ROAMING_IDLE = 0, + WIFI_ROAMING_ACTIVE = 1, +}; + +enum WIFI_INTERFACE_MODE { + WIFI_INTERFACE_STA = 0, + WIFI_INTERFACE_SOFTAP = 1, + WIFI_INTERFACE_IBSS = 2, + WIFI_INTERFACE_P2P_CLIENT = 3, + WIFI_INTERFACE_P2P_GO = 4, + WIFI_INTERFACE_NAN = 5, + WIFI_INTERFACE_MESH = 6, + WIFI_INTERFACE_UNKNOWN = -1 +}; + +struct WIFI_INTERFACE_LINK_LAYER_INFO { + enum WIFI_INTERFACE_MODE mode; + u8 mac_addr[6]; + enum WIFI_CONNECTION_STATE state; + enum WIFI_ROAM_STATE roaming; + u32 capabilities; + u8 ssid[33]; + u8 bssid[6]; + u8 ap_country_str[3]; + u8 country_str[3]; +}; + +/* access categories */ +enum WIFI_TRAFFIC_AC { + WIFI_AC_VO = 0, + WIFI_AC_VI = 1, + WIFI_AC_BE = 2, + WIFI_AC_BK = 3, + WIFI_AC_MAX = 4, +}; + +/* wifi peer type */ +enum WIFI_PEER_TYPE { + WIFI_PEER_STA, + WIFI_PEER_AP, + WIFI_PEER_P2P_GO, + WIFI_PEER_P2P_CLIENT, + WIFI_PEER_NAN, + WIFI_PEER_TDLS, + WIFI_PEER_INVALID, +}; + +/* per peer statistics */ +struct WIFI_PEER_INFO { + enum WIFI_PEER_TYPE type; + uint8_t peer_mac_address[6]; + uint32_t capabilities; + uint32_t num_rate; + struct WIFI_RATE_STAT rate_stats[]; +}; + +/* per access category statistics */ +struct WIFI_WMM_AC_STAT_ { + enum WIFI_TRAFFIC_AC ac; + uint32_t tx_mpdu; + uint32_t rx_mpdu; + uint32_t tx_mcast; + + uint32_t rx_mcast; + uint32_t rx_ampdu; + uint32_t tx_ampdu; + uint32_t mpdu_lost; + uint32_t retries; + uint32_t retries_short; + uint32_t retries_long; + uint32_t contention_time_min; + uint32_t contention_time_max; + uint32_t contention_time_avg; + uint32_t contention_num_samples; +}; + +/* RTT Capabilities */ +struct PARAM_WIFI_RTT_CAPABILITIES { + /* if 1-sided rtt data collection is supported */ + uint8_t rtt_one_sided_supported; + /* if ftm rtt data collection is supported */ + uint8_t rtt_ftm_supported; + /* if initiator supports LCI request. Applies to 2-sided RTT */ + uint8_t lci_support; + /* if initiator supports LCR request. Applies to 2-sided RTT */ + uint8_t lcr_support; + /* bit mask indicates what preamble is supported by initiator */ + uint8_t preamble_support; + /* bit mask indicates what BW is supported by initiator */ + uint8_t bw_support; +}; + +/* interface statistics */ +struct WIFI_IFACE_STAT { + struct WIFI_INTERFACE_LINK_LAYER_INFO info; + uint32_t beacon_rx; + uint32_t mgmt_rx; + uint32_t mgmt_action_rx; + uint32_t mgmt_action_tx; + int32_t rssi_mgmt; + int32_t rssi_data; + int32_t rssi_ack; + struct WIFI_WMM_AC_STAT_ ac[WIFI_AC_MAX]; + uint32_t num_peers; + struct WIFI_PEER_INFO peer_info[]; +}; + +enum ENUM_NLA_PUT_DATE_TYPE { + NLA_PUT_DATE_U8 = 0, + NLA_PUT_DATE_U16, + NLA_PUT_DATE_U32, + NLA_PUT_DATE_U64, +}; + +/* RSSI Monitoring */ +struct PARAM_RSSI_MONITOR_T { + bool enable; /* 1=Start, 0=Stop*/ + int8_t max_rssi_value; + int8_t min_rssi_value; + uint8_t reserved[1]; + uint8_t reserved2[4]; /* reserved for MT6632 */ +}; + +struct PARAM_RSSI_MONITOR_EVENT { + uint8_t version; + int8_t rssi; + uint8_t BSSID[PARAM_MAC_ADDR_LEN]; +}; + +/* Packet Keep Alive */ +struct PARAM_PACKET_KEEPALIVE_T { + bool enable; /* 1=Start, 0=Stop*/ + uint8_t index; + int16_t u2IpPktLen; + uint8_t pIpPkt[256]; + uint8_t ucSrcMacAddr[PARAM_MAC_ADDR_LEN]; + uint8_t ucDstMacAddr[PARAM_MAC_ADDR_LEN]; + uint32_t u4PeriodMsec; + uint8_t reserved[8]; /* reserved for MT6632 */ +}; + +struct PARAM_BSS_MAC_OUI { + uint8_t ucBssIndex; + uint8_t ucMacOui[MAC_OUI_LEN]; +}; + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + + + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +/* + * TODO: function is os-related, while may depend on the purpose of function + * to implement on other os + */ +#if 0 +int mtk_cfg80211_NLA_PUT(struct sk_buff *skb, int attrtype, + int attrlen, const void *data); + +int mtk_cfg80211_nla_put_type(struct sk_buff *skb, + enum ENUM_NLA_PUT_DATE_TYPE type, int attrtype, + const void *value); + +int mtk_cfg80211_vendor_get_capabilities(struct wiphy + *wiphy, struct wireless_dev *wdev, + const void *data, int data_len); + +int mtk_cfg80211_vendor_set_config(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len); + +int mtk_cfg80211_vendor_set_scan_config(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len); + +int mtk_cfg80211_vendor_set_significant_change( + struct wiphy *wiphy, struct wireless_dev *wdev, + const void *data, int data_len); + +int mtk_cfg80211_vendor_set_hotlist(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len); + +int mtk_cfg80211_vendor_enable_scan(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len); + +int mtk_cfg80211_vendor_enable_full_scan_results( + struct wiphy *wiphy, struct wireless_dev *wdev, + const void *data, int data_len); + +int mtk_cfg80211_vendor_get_scan_results(struct wiphy + *wiphy, struct wireless_dev *wdev, + const void *data, int data_len); + +int mtk_cfg80211_vendor_get_channel_list(struct wiphy + *wiphy, struct wireless_dev *wdev, + const void *data, int data_len); + +int mtk_cfg80211_vendor_set_country_code(struct wiphy + *wiphy, struct wireless_dev *wdev, + const void *data, int data_len); + +int mtk_cfg80211_vendor_get_rtt_capabilities( + struct wiphy *wiphy, struct wireless_dev *wdev, + const void *data, int data_len); + +int mtk_cfg80211_vendor_llstats_get_info(struct wiphy + *wiphy, struct wireless_dev *wdev, + const void *data, int data_len); + +int mtk_cfg80211_vendor_set_band(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len); + +int mtk_cfg80211_vendor_set_scan_mac_oui(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len); + +int mtk_cfg80211_vendor_set_roaming_policy( + struct wiphy *wiphy, struct wireless_dev *wdev, + const void *data, int data_len); + +int mtk_cfg80211_vendor_get_roaming_capabilities( + struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int data_len); + +int mtk_cfg80211_vendor_config_roaming(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len); + +int mtk_cfg80211_vendor_enable_roaming(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len); + +int mtk_cfg80211_vendor_set_rssi_monitoring( + struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int data_len); + +int mtk_cfg80211_vendor_packet_keep_alive_start( + struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int data_len); + +int mtk_cfg80211_vendor_packet_keep_alive_stop( + struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int data_len); + +int mtk_cfg80211_vendor_get_version(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len); + +int mtk_cfg80211_vendor_event_rssi_beyond_range( + struct wiphy *wiphy, + struct wireless_dev *wdev, int rssi); + +int mtk_cfg80211_vendor_get_preferred_freq_list(struct wiphy + *wiphy, struct wireless_dev *wdev, const void *data, + int data_len); +#endif +#endif /* _GL_VENDOR_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/include/gl_wext_priv.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/include/gl_wext_priv.h new file mode 100644 index 0000000000000000000000000000000000000000..698ea57c8a3eea8fffa1e03e1513623219e012b7 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/none/include/gl_wext_priv.h @@ -0,0 +1,402 @@ +/******************************************************************************* + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ +/* + * Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include + /gl_wext_priv.h#3 + */ + +/*! \file gl_wext_priv.h + * \brief This file includes private ioctl support. + */ + + +#ifndef _GL_WEXT_PRIV_H +#define _GL_WEXT_PRIV_H +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ +/* If it is set to 1, iwpriv will support register read/write */ +#define CFG_SUPPORT_PRIV_MCR_RW 1 + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ +/* New wireless extensions API - SET/GET convention (even ioctl numbers are + * root only) + */ +/* TODO: os-related */ +#if 0 +#define IOCTL_SET_INT (SIOCIWFIRSTPRIV + 0) +#define IOCTL_GET_INT (SIOCIWFIRSTPRIV + 1) + +#define IOCTL_SET_ADDRESS (SIOCIWFIRSTPRIV + 2) +#define IOCTL_GET_ADDRESS (SIOCIWFIRSTPRIV + 3) +#define IOCTL_SET_STR (SIOCIWFIRSTPRIV + 4) +#define IOCTL_GET_STR (SIOCIWFIRSTPRIV + 5) +#define IOCTL_SET_KEY (SIOCIWFIRSTPRIV + 6) +#define IOCTL_GET_KEY (SIOCIWFIRSTPRIV + 7) +#define IOCTL_SET_STRUCT (SIOCIWFIRSTPRIV + 8) +#define IOCTL_GET_STRUCT (SIOCIWFIRSTPRIV + 9) +#define IOCTL_SET_STRUCT_FOR_EM (SIOCIWFIRSTPRIV + 11) +#define IOCTL_SET_INTS (SIOCIWFIRSTPRIV + 12) +#define IOCTL_GET_INTS (SIOCIWFIRSTPRIV + 13) +#define IOCTL_SET_DRIVER (SIOCIWFIRSTPRIV + 14) +#define IOCTL_GET_DRIVER (SIOCIWFIRSTPRIV + 15) + +#if CFG_SUPPORT_QA_TOOL +#define IOCTL_QA_TOOL_DAEMON (SIOCIWFIRSTPRIV + 16) +#define IOCTL_IWPRIV_ATE (SIOCIWFIRSTPRIV + 17) +#endif + +#define IOC_AP_GET_STA_LIST (SIOCIWFIRSTPRIV+19) +#define IOC_AP_SET_MAC_FLTR (SIOCIWFIRSTPRIV+21) +#define IOC_AP_SET_CFG (SIOCIWFIRSTPRIV+23) +#define IOC_AP_STA_DISASSOC (SIOCIWFIRSTPRIV+25) + +#define PRIV_CMD_REG_DOMAIN 0 +#define PRIV_CMD_BEACON_PERIOD 1 +#define PRIV_CMD_ADHOC_MODE 2 + +#if CFG_TCP_IP_CHKSUM_OFFLOAD +#define PRIV_CMD_CSUM_OFFLOAD 3 +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ + +#define PRIV_CMD_ROAMING 4 +#define PRIV_CMD_VOIP_DELAY 5 +#define PRIV_CMD_POWER_MODE 6 + +#define PRIV_CMD_WMM_PS 7 +#define PRIV_CMD_BT_COEXIST 8 +#define PRIV_GPIO2_MODE 9 + +#define PRIV_CUSTOM_SET_PTA 10 +#define PRIV_CUSTOM_CONTINUOUS_POLL 11 +#define PRIV_CUSTOM_SINGLE_ANTENNA 12 +#define PRIV_CUSTOM_BWCS_CMD 13 +#define PRIV_CUSTOM_DISABLE_BEACON_DETECTION 14 /* later */ +#define PRIV_CMD_OID 15 +#define PRIV_SEC_MSG_OID 16 + +#define PRIV_CMD_TEST_MODE 17 +#define PRIV_CMD_TEST_CMD 18 +#define PRIV_CMD_ACCESS_MCR 19 +#define PRIV_CMD_SW_CTRL 20 + +#define PRIV_SEC_CHECK_OID 21 + +#define PRIV_CMD_WSC_PROBE_REQ 22 + +#define PRIV_CMD_P2P_VERSION 23 + +#define PRIV_CMD_GET_CH_LIST 24 + +#define PRIV_CMD_SET_TX_POWER 25 + +#define PRIV_CMD_BAND_CONFIG 26 + +#define PRIV_CMD_DUMP_MEM 27 + +#define PRIV_CMD_P2P_MODE 28 + +#if CFG_SUPPORT_QA_TOOL +#define PRIV_QACMD_SET 29 +#endif + +#define PRIV_CMD_MET_PROFILING 33 + +#if CFG_WOW_SUPPORT +#define PRIV_CMD_SET_WOW_ENABLE 34 +#define PRIV_CMD_SET_WOW_PAR 35 +#endif + +#ifdef UT_TEST_MODE +#define PRIV_CMD_UT 36 +#endif /* UT_TEST_MODE */ + +#define PRIV_CMD_SET_SER 37 + +/* 802.3 Objects (Ethernet) */ +#define OID_802_3_CURRENT_ADDRESS 0x01010102 + +/* IEEE 802.11 OIDs */ +#define OID_802_11_SUPPORTED_RATES 0x0D01020E +#define OID_802_11_CONFIGURATION 0x0D010211 + +/* PnP and PM OIDs, NDIS default OIDS */ +#define OID_PNP_SET_POWER 0xFD010101 + +#define OID_CUSTOM_OID_INTERFACE_VERSION 0xFFA0C000 + +/* MT5921 specific OIDs */ +#define OID_CUSTOM_BT_COEXIST_CTRL 0xFFA0C580 +#define OID_CUSTOM_POWER_MANAGEMENT_PROFILE 0xFFA0C581 +#define OID_CUSTOM_PATTERN_CONFIG 0xFFA0C582 +#define OID_CUSTOM_BG_SSID_SEARCH_CONFIG 0xFFA0C583 +#define OID_CUSTOM_VOIP_SETUP 0xFFA0C584 +#define OID_CUSTOM_ADD_TS 0xFFA0C585 +#define OID_CUSTOM_DEL_TS 0xFFA0C586 +#define OID_CUSTOM_SLT 0xFFA0C587 +#define OID_CUSTOM_ROAMING_EN 0xFFA0C588 +#define OID_CUSTOM_WMM_PS_TEST 0xFFA0C589 +#define OID_CUSTOM_COUNTRY_STRING 0xFFA0C58A +#define OID_CUSTOM_MULTI_DOMAIN_CAPABILITY 0xFFA0C58B +#define OID_CUSTOM_GPIO2_MODE 0xFFA0C58C +#define OID_CUSTOM_CONTINUOUS_POLL 0xFFA0C58D +#define OID_CUSTOM_DISABLE_BEACON_DETECTION 0xFFA0C58E + +/* CR1460, WPS privacy bit check disable */ +#define OID_CUSTOM_DISABLE_PRIVACY_CHECK 0xFFA0C600 + +/* Precedent OIDs */ +#define OID_CUSTOM_MCR_RW 0xFFA0C801 +#define OID_CUSTOM_EEPROM_RW 0xFFA0C803 +#define OID_CUSTOM_SW_CTRL 0xFFA0C805 +#define OID_CUSTOM_MEM_DUMP 0xFFA0C807 + +/* RF Test specific OIDs */ +#define OID_CUSTOM_TEST_MODE 0xFFA0C901 +#define OID_CUSTOM_TEST_RX_STATUS 0xFFA0C903 +#define OID_CUSTOM_TEST_TX_STATUS 0xFFA0C905 +#define OID_CUSTOM_ABORT_TEST_MODE 0xFFA0C906 +#define OID_CUSTOM_MTK_WIFI_TEST 0xFFA0C911 +#define OID_CUSTOM_TEST_ICAP_MODE 0xFFA0C913 + +/* BWCS */ +#define OID_CUSTOM_BWCS_CMD 0xFFA0C931 +#define OID_CUSTOM_SINGLE_ANTENNA 0xFFA0C932 +#define OID_CUSTOM_SET_PTA 0xFFA0C933 + +/* NVRAM */ +#define OID_CUSTOM_MTK_NVRAM_RW 0xFFA0C941 +#define OID_CUSTOM_CFG_SRC_TYPE 0xFFA0C942 +#define OID_CUSTOM_EEPROM_TYPE 0xFFA0C943 + +#if CFG_SUPPORT_WAPI +#define OID_802_11_WAPI_MODE 0xFFA0CA00 +#define OID_802_11_WAPI_ASSOC_INFO 0xFFA0CA01 +#define OID_802_11_SET_WAPI_KEY 0xFFA0CA02 +#endif + +#if CFG_SUPPORT_WPS2 +#define OID_802_11_WSC_ASSOC_INFO 0xFFA0CB00 +#endif + +#if CFG_SUPPORT_LOWLATENCY_MODE +#define OID_CUSTOM_LOWLATENCY_MODE 0xFFA0CC00 +#endif /* CFG_SUPPORT_LOWLATENCY_MODE */ + +#define OID_IPC_WIFI_LOG_UI 0xFFA0CC01 +#define OID_IPC_WIFI_LOG_LEVEL 0xFFA0CC02 +#endif + +#if CFG_SUPPORT_NCHO +#define CMD_NCHO_COMP_TIMEOUT 1500 /* ms */ +#define CMD_NCHO_AF_DATA_LENGTH 1040 +#endif + +#ifdef UT_TEST_MODE +#define OID_UT 0xFFA0CD00 +#endif /* UT_TEST_MODE */ + +/* Define magic key of test mode (Don't change it for future compatibity) */ +#define PRIV_CMD_TEST_MAGIC_KEY 2011 +#define PRIV_CMD_TEST_MAGIC_KEY_ICAP 2013 + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ +/* NIC BBCR configuration entry structure */ +struct PRIV_CONFIG_ENTRY { + uint8_t ucOffset; + uint8_t ucValue; +}; + +typedef uint32_t(*PFN_OID_HANDLER_FUNC_REQ) ( + IN void *prAdapter, + IN OUT void *pvBuf, IN uint32_t u4BufLen, + OUT uint32_t *pu4OutInfoLen); + +enum ENUM_OID_METHOD { + ENUM_OID_GLUE_ONLY, + ENUM_OID_GLUE_EXTENSION, + ENUM_OID_DRIVER_CORE +}; + +/* OID set/query processing entry */ +struct WLAN_REQ_ENTRY { + uint32_t rOid; /* OID */ + uint8_t *pucOidName; /* OID name text */ + u_int8_t fgQryBufLenChecking; + u_int8_t fgSetBufLenChecking; + enum ENUM_OID_METHOD eOidMethod; + uint32_t u4InfoBufLen; + PFN_OID_HANDLER_FUNC_REQ pfOidQueryHandler; /* PFN_OID_HANDLER_FUNC */ + PFN_OID_HANDLER_FUNC_REQ pfOidSetHandler; /* PFN_OID_HANDLER_FUNC */ +}; + +struct NDIS_TRANSPORT_STRUCT { + uint32_t ndisOidCmd; + uint32_t inNdisOidlength; + uint32_t outNdisOidLength; + uint8_t ndisOidContent[16]; +}; + +enum AGG_RANGE_TYPE_T { + ENUM_AGG_RANGE_TYPE_TX = 0, + ENUM_AGG_RANGE_TYPE_TRX = 1, + ENUM_AGG_RANGE_TYPE_RX = 2 +}; + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ +#if 0 +int +priv_set_int(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN union iwreq_data *prIwReqData, IN char *pcExtra); + +int +priv_get_int(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN union iwreq_data *prIwReqData, IN OUT char *pcExtra); + +int +priv_set_ints(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN union iwreq_data *prIwReqData, IN char *pcExtra); + +int +priv_get_ints(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN union iwreq_data *prIwReqData, IN OUT char *pcExtra); + +int +priv_set_struct(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN union iwreq_data *prIwReqData, IN char *pcExtra); + +int +priv_get_struct(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN union iwreq_data *prIwReqData, IN OUT char *pcExtra); + +#if CFG_SUPPORT_NCHO +uint8_t CmdString2HexParse(IN uint8_t *InStr, + OUT uint8_t **OutStr, OUT uint8_t *OutLen); +#endif + +int +priv_set_driver(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN union iwreq_data *prIwReqData, IN OUT char *pcExtra); + +int +priv_set_ap(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN union iwreq_data *prIwReqData, IN OUT char *pcExtra); + +int priv_support_ioctl(IN struct net_device *prDev, + IN OUT struct ifreq *prReq, IN int i4Cmd); + +int priv_support_driver_cmd(IN struct net_device *prDev, + IN OUT struct ifreq *prReq, IN int i4Cmd); + +#ifdef CFG_ANDROID_AOSP_PRIV_CMD +int android_private_support_driver_cmd(IN struct net_device *prDev, +IN OUT struct ifreq *prReq, IN int i4Cmd); +#endif /* CFG_ANDROID_AOSP_PRIV_CMD */ + +int32_t priv_driver_cmds(IN struct net_device *prNetDev, + IN int8_t *pcCommand, IN int32_t i4TotalLen); + +int priv_driver_set_cfg(IN struct net_device *prNetDev, + IN char *pcCommand, IN int i4TotalLen); + +#if CFG_SUPPORT_QA_TOOL +int +priv_ate_set(IN struct net_device *prNetDev, + IN struct iw_request_info *prIwReqInfo, + IN union iwreq_data *prIwReqData, IN char *pcExtra); +#endif +#else +#endif +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#endif /* _GL_WEXT_PRIV_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/version.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/version.h new file mode 100644 index 0000000000000000000000000000000000000000..26273a1d935435acf1eaf7f72efbee036fa9cb4b --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/os/version.h @@ -0,0 +1,138 @@ +/******************************************************************************* + * + * This file is provided under a dual license. When you use or + * distribute this software, you may choose to be licensed under + * version 2 of the GNU General Public License ("GPLv2 License") + * or BSD License. + * + * GPLv2 License + * + * Copyright(C) 2016 MediaTek Inc. + * + * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. + * + * BSD LICENSE + * + * Copyright(C) 2016 MediaTek Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ +/* + ** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/version.h#1 + */ + +/*! \file "version.h" + * \brief Driver's version definition + * + */ + + +#ifndef _VERSION_H +#define _VERSION_H +/******************************************************************************* + * C O M P I L E R F L A G S + ******************************************************************************* + */ + +/******************************************************************************* + * E X T E R N A L R E F E R E N C E S + ******************************************************************************* + */ + +/******************************************************************************* + * C O N S T A N T S + ******************************************************************************* + */ + +#ifndef NIC_AUTHOR +#define NIC_AUTHOR "NIC_AUTHOR" +#endif +#ifndef NIC_DESC +#define NIC_DESC "NIC_DESC" +#endif + +#ifndef NIC_NAME +#define NIC_NAME "MT6632" +#define NIC_DEVICE_ID "MT6632" +#define NIC_DEVICE_ID_LOW "mt6632" +#endif + +/* NIC driver information */ +#define NIC_VENDOR "MediaTek Inc." +#define NIC_VENDOR_OUI {0x00, 0x0C, 0xE7} + +#define NIC_PRODUCT_NAME "MediaTek Inc. Wireless LAN Adapter" +#define NIC_DRIVER_NAME "MediaTek Inc. Wireless LAN Adapter Driver" + +/* Define our driver version */ +#define NIC_DRIVER_MAJOR_VERSION 1 +#define NIC_DRIVER_MINOR_VERSION 0 +#define NIC_DRIVER_SERIAL_VERSION 1 +#define NIC_DRIVER_VERSION (NIC_DRIVER_MAJOR_VERSION, \ + NIC_DRIVER_MINOR_VERSION, \ + NIC_DRIVER_SERIAL_VERSION) +#define NIC_DRIVER_VERSION_STRING "1.0.1" + +/******************************************************************************* + * D A T A T Y P E S + ******************************************************************************* + */ + +/******************************************************************************* + * P U B L I C D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * P R I V A T E D A T A + ******************************************************************************* + */ + +/******************************************************************************* + * M A C R O S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N D E C L A R A T I O N S + ******************************************************************************* + */ + +/******************************************************************************* + * F U N C T I O N S + ******************************************************************************* + */ + +#endif /* _VERSION_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/agent/agent.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/agent/agent.c new file mode 100644 index 0000000000000000000000000000000000000000..2fab2704a68a7a900c63882664bfbe24d5a34e11 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/agent/agent.c @@ -0,0 +1,5276 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#include "agent.h" + +u_char *agnt_rstrtok; +u_char *agent_trtok(u_char *s, const u_char *ct) +{ + u_char *sbegin, *send; + + sbegin = s ? s : agnt_rstrtok; + + if (!sbegin) + return NULL; + + sbegin += strspn(sbegin, ct); + + if (*sbegin == '\0') { + agnt_rstrtok = NULL; + return NULL; + } + + send = strpbrk(sbegin, ct); + + if (send && *send != '\0') + *send++ = '\0'; + + agnt_rstrtok = send; + return sbegin; +} + + +/***************************************************************************** + * HQA DLL handler + *****************************************************************************/ +static s_int32 agent_cfg_find_next_token(struct agent_cfg_parse_state_s + *state) +{ + s_int8 *x = state->ptr; + s_int8 *s; + + if (state->nexttoken) { + s_int32 t = state->nexttoken; + + state->nexttoken = 0; + return t; + } + + for (;;) { + switch (*x) { + case 0: + state->ptr = x; + return AGENT_STATE_EOF; + case '\n': + x++; + state->ptr = x; + return AGENT_STATE_NEWLINE; + case ' ': + case ',': + /*case ':': should not including : , mac addr would be fail*/ + case '\t': + case '\r': + x++; + continue; + case '#': + while (*x && (*x != '\n')) + x++; + if (*x == '\n') { + state->ptr = x + 1; + return AGENT_STATE_NEWLINE; + } + state->ptr = x; + return AGENT_STATE_EOF; + + default: + goto text; + } + } + +textdone: + state->ptr = x; + *s = 0; + return AGENT_STATE_TEXT; +text: + state->text = s = x; +textresume: + for (;;) { + switch (*x) { + case 0: + goto textdone; + case ' ': + case ',': + /* case ':': */ + case '\t': + case '\r': + x++; + goto textdone; + case '\n': + state->nexttoken = AGENT_STATE_NEWLINE; + x++; + goto textdone; + case '"': + x++; + for (;;) { + switch (*x) { + case 0: + /* unterminated quoted thing */ + state->ptr = x; + return AGENT_STATE_EOF; + case '"': + x++; + goto textresume; + default: + *s++ = *x++; + } + } + break; + case '\\': + x++; + switch (*x) { + case 0: + goto textdone; + case 'n': + *s++ = '\n'; + break; + case 'r': + *s++ = '\r'; + break; + case 't': + *s++ = '\t'; + break; + case '\\': + *s++ = '\\'; + break; + case '\r': + /* \ -> line continuation */ + if (x[1] != '\n') { + x++; + continue; + } + case '\n': + /* \ -> line continuation */ + x++; + /* eat any extra whitespace */ + while ((*x == ' ') || (*x == '\t')) + x++; + continue; + default: + /* unknown escape -- just copy */ + *s++ = *x++; + } + continue; + default: + *s++ = *x++; + state->textsize++; + + } + } + return AGENT_STATE_EOF; +} + +static u_int32 agent_cfg_parse_argument(s_int8 *cmd_line, + s_int32 *argc, s_int8 *argv[]) +{ + struct agent_cfg_parse_state_s state; + s_int8 **args; + s_int32 nargs; + + if (cmd_line == NULL || argc == NULL || argv == NULL) { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("parameter is NULL: %p, %p, %p\n", + cmd_line, argc, argv)); + + return SERV_STATUS_AGENT_INVALID_NULL_POINTER; + } + args = argv; + nargs = 0; + state.ptr = cmd_line; + state.nexttoken = 0; + state.maxsize = 0; + state.textsize = 0; + state.text = 0; + + if (strnlen(cmd_line, 512) >= 512) { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("cmd_line >= 512\n")); + return SERV_STATUS_AGENT_INVALID_LEN; + } + + for (;;) { + switch (agent_cfg_find_next_token(&state)) { + case AGENT_STATE_EOF: + goto exit; + case AGENT_STATE_NEWLINE: + goto exit; + case AGENT_STATE_TEXT: + if (nargs < AGENT_CFG_ARGV_MAX) + args[nargs++] = state.text; + break; + } + } + +exit: + *argc = nargs; + return SERV_STATUS_SUCCESS; +} + + +static s_int32 set_param_and_shift_buf( + boolean convert, u_int32 size, u_char *in, u_char **out) +{ + if (!(*out)) { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("*buf NULL pointer with size=%u\n", size)); + return SERV_STATUS_AGENT_INVALID_NULL_POINTER; + } + + if (!in) { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("out NULL pointer with size=%u\n", size)); + return SERV_STATUS_AGENT_INVALID_NULL_POINTER; + } + + if (convert) { + if (size == sizeof(u_int32)) { + u_int32 *tmp = (u_int32 *) in; + + *tmp = SERV_OS_HTONL(*tmp); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: size=%u, val=%u\n", __func__, size, *tmp)); + } else if (size == sizeof(u_int16)) { + u_int16 *tmp = (u_int16 *) in; + + *tmp = SERV_OS_HTONS(*tmp); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: size=%u, val=%u\n", __func__, size, *tmp)); + } else { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_WARN, + ("%s: size %u not supported\n", __func__, size)); + return SERV_STATUS_AGENT_NOT_SUPPORTED; + } + } + + sys_ad_move_mem(*out, in, size); + *out = *out + size; + + return SERV_STATUS_SUCCESS; +} + +static s_int32 get_param_and_shift_buf( + boolean convert, u_int32 size, u_char **buf, u_char *out) +{ + if (!(*buf)) { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("*buf NULL pointer with size=%u\n", size)); + return SERV_STATUS_AGENT_INVALID_NULL_POINTER; + } + + if (!out) { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("out NULL pointer with size=%u\n", size)); + return SERV_STATUS_AGENT_INVALID_NULL_POINTER; + } + + sys_ad_move_mem(out, *buf, size); + *buf = *buf + size; + + if (!convert) { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: size=%u", __func__, size)); + return SERV_STATUS_SUCCESS; + } + + if (size == sizeof(u_int32)) { + u_int32 *tmp = (u_int32 *) out; + + *tmp = SERV_OS_NTOHL(*tmp); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: size=%u, val=%u\n", __func__, size, *tmp)); + } else if (size == sizeof(u_int16)) { + u_int16 *tmp = (u_int16 *) out; + + *tmp = SERV_OS_NTOHS(*tmp); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: size=%u, val=%u\n", __func__, size, *tmp)); + } else { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_WARN, + ("%s: size %u not supported\n", __func__, size)); + return SERV_STATUS_AGENT_NOT_SUPPORTED; + } + + return SERV_STATUS_SUCCESS; +} + +static s_int32 update_hqa_frame( + struct hqa_frame *hqa_frame, s_int32 length, s_int32 status) +{ + hqa_frame->length = SERV_OS_HTONS((length)); + status = SERV_OS_HTONS((status)); + sys_ad_move_mem(hqa_frame->data, &status, 2); + return SERV_STATUS_SUCCESS; +} + +static s_int32 legacy_function( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + /* + * Legacy function means older chips use only, + * but not support in following CONNAC2 projects. + */ + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + update_hqa_frame(hqa_frame, 2, SERV_STATUS_SUCCESS); + return SERV_STATUS_SUCCESS; +} + +static s_int32 todo_function( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + update_hqa_frame(hqa_frame, 2, SERV_STATUS_SUCCESS); + return SERV_STATUS_SUCCESS; +} + +static s_int32 hqa_open_adapter( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + ret = mt_serv_start(serv_test); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; +} + +static s_int32 hqa_close_adapter( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + ret = mt_serv_stop(serv_test); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; +} + +static s_int32 hqa_set_tx_path( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS, value = 0; + u_char *data = hqa_frame->data; + u_char band_idx = SERV_GET_PARAM(serv_test, ctrl_band_idx); + u_int16 tx_ant = 0; + + if (hqa_frame->length > 2) { + /* new format with band index, + * and data length extedned to 8 bytes + */ + /* tx path in bitwise */ + get_param_and_shift_buf(TRUE, sizeof(value), + &data, (u_char *)&value); + tx_ant = value; + /* band index */ + get_param_and_shift_buf(TRUE, sizeof(value), + &data, (u_char *)&value); + band_idx = value; + + /* Set Band idx */ + SERV_SET_PARAM(serv_test, ctrl_band_idx, (u_char)band_idx); + + if (band_idx && tx_ant > 0x3) + tx_ant >>= 2; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: tx_path:%d, band:%d\n", __func__, + tx_ant, band_idx)); + } else { + /* legacy command format, + * data length is 2 bytes without band index + */ + get_param_and_shift_buf(TRUE, sizeof(tx_ant), + &data, (u_char *)&tx_ant); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: tx_path:%d\n", __func__, tx_ant)); + } + + /* Set parameters */ + CONFIG_SET_PARAM(serv_test, tx_ant, tx_ant, band_idx); + + ret = mt_serv_set_tx_path(serv_test); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; +} + +static s_int32 hqa_set_rx_path( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS, value = 0; + u_char *data = hqa_frame->data; + u_char band_idx = SERV_GET_PARAM(serv_test, ctrl_band_idx); + u_int16 rx_ant = 0; + + if (hqa_frame->length > 2) { + /* new format with band index, + * and data length extedned to 8 bytes + */ + /* rx path in bitwise */ + get_param_and_shift_buf(TRUE, sizeof(value), + &data, (u_char *)&value); + rx_ant = value; + /* band index */ + get_param_and_shift_buf(TRUE, sizeof(value), + &data, (u_char *)&value); + band_idx = value; + + /* Set Band idx */ + SERV_SET_PARAM(serv_test, ctrl_band_idx, (u_char)band_idx); + + if (band_idx && rx_ant > 0x3) + rx_ant >>= 2; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: rx_path:%d, band:%d\n", __func__, + rx_ant, band_idx)); + } else { + /* legacy command format, + * data length is 2 bytes without band index + */ + get_param_and_shift_buf(TRUE, sizeof(rx_ant), + &data, (u_char *)&rx_ant); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: rx_path:%d\n", __func__, rx_ant)); + } + + /* Set parameters */ + CONFIG_SET_PARAM(serv_test, rx_ant, rx_ant, band_idx); + + ret = mt_serv_set_rx_path(serv_test); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; +} + +static s_int32 hqa_set_tx_power_ext( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char *data = hqa_frame->data; + u_int32 power = 0, band_idx = 0, channel = 0; + u_int32 ch_band = 0, ant_idx = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + /* Request format type */ + get_param_and_shift_buf(TRUE, sizeof(power), + &data, (u_char *)&power); + get_param_and_shift_buf(TRUE, sizeof(band_idx), + &data, (u_char *)&band_idx); + get_param_and_shift_buf(TRUE, sizeof(channel), + &data, (u_char *)&channel); + get_param_and_shift_buf(TRUE, sizeof(ch_band), + &data, (u_char *)&ch_band); + get_param_and_shift_buf(TRUE, sizeof(ant_idx), + &data, (u_char *)&ant_idx); + + /* Set parameters */ + SERV_SET_PARAM(serv_test, ctrl_band_idx, (u_char)band_idx); + CONFIG_SET_PARAM(serv_test, pwr_param.ant_idx, + (u_int32)ant_idx, band_idx); + CONFIG_SET_PARAM(serv_test, pwr_param.power, + (u_int32)power, band_idx); + CONFIG_SET_PARAM(serv_test, pwr_param.channel, + (u_int32)channel, band_idx); + CONFIG_SET_PARAM(serv_test, pwr_param.band_idx, + (u_int32)band_idx, band_idx); + CONFIG_SET_PARAM(serv_test, pwr_param.ch_band, + (u_int32)ch_band, band_idx); + + ret = mt_serv_tx_power_operation(serv_test, SERV_TEST_TXPWR_SET_PWR); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: power=%u, band_idx=%u, channel=%u\n", + __func__, power, band_idx, channel)); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: ch_band=%u, ant_idx=%u\n", + __func__, ch_band, ant_idx)); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; +} + +static struct hqa_cmd_entry CMD_SET0[] = { + /* cmd id start from 0x1000 */ + {0x0, hqa_open_adapter}, + {0x1, hqa_close_adapter}, + {0x2, legacy_function}, + {0x3, legacy_function}, + {0x4, legacy_function}, + {0x6, legacy_function}, + {0x7, legacy_function}, + {0x8, legacy_function}, + {0xa, legacy_function}, + {0xb, hqa_set_tx_path}, + {0xc, hqa_set_rx_path}, + {0xd, legacy_function}, + {0xe, legacy_function}, + {0xf, legacy_function}, + {0x10, legacy_function}, + {0x11, hqa_set_tx_power_ext}, + {0x14, legacy_function}, + {0x15, todo_function}, + {0x18, legacy_function} +}; + +static s_int32 hqa_set_preamble( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char *data = hqa_frame->data; + u_char band_idx = SERV_GET_PARAM(serv_test, ctrl_band_idx); + u_int32 tx_mode = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + /* Request format type: Mode (4 bytes) */ + get_param_and_shift_buf(TRUE, sizeof(tx_mode), + &data, (u_char *)&tx_mode); + + /* Set parameters */ + /* + * 000: Legacy CCK + * 001: Legacy OFDM + * 010: HT Mixed mode + * 011: HT Green field mode + * 100: VHT mode + */ + CONFIG_SET_PARAM(serv_test, tx_mode, (u_char)tx_mode, band_idx); + + ret = mt_serv_set_preamble(serv_test); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: phy_mode=%u\n", __func__, tx_mode)); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; +} + +static s_int32 hqa_set_rate( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char *data = hqa_frame->data; + u_char band_idx = SERV_GET_PARAM(serv_test, ctrl_band_idx); + u_int32 mcs = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + /* Request format type: MCS (4 bytes) */ + get_param_and_shift_buf(TRUE, sizeof(mcs), + &data, (u_char *)&mcs); + + /* Set parameters */ + CONFIG_SET_PARAM(serv_test, mcs, (u_char)mcs, band_idx); + + ret = mt_serv_set_rate(serv_test); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: mcs=%u\n", __func__, mcs)); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; +} + +static s_int32 hqa_set_nss( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char *data = hqa_frame->data; + u_char band_idx = SERV_GET_PARAM(serv_test, ctrl_band_idx); + u_int32 nss = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + /* Request format type: NSS (4 bytes) */ + get_param_and_shift_buf(TRUE, sizeof(nss), + &data, (u_char *)&nss); + + /* Set parameters */ + CONFIG_SET_PARAM(serv_test, nss, (u_char)nss, band_idx); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: nss=%u\n", __func__, nss)); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; +} + +static s_int32 hqa_set_system_bw( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char *data = hqa_frame->data; + u_char band_idx = SERV_GET_PARAM(serv_test, ctrl_band_idx); + u_int32 bw = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + /* Request format type: BW (4 bytes) */ + get_param_and_shift_buf(TRUE, sizeof(bw), + &data, (u_char *)&bw); + + /* Set parameters */ + CONFIG_SET_PARAM(serv_test, bw, (u_char)bw, band_idx); + + ret = mt_serv_set_system_bw(serv_test); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: bw=%u\n", __func__, bw)); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; +} + +static s_int32 hqa_set_per_pkt_bw( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char *data = hqa_frame->data; + u_char band_idx = SERV_GET_PARAM(serv_test, ctrl_band_idx); + u_int32 per_pkt_bw = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + /* Request format type: Per-Pkt BW (4 bytes) */ + get_param_and_shift_buf(TRUE, sizeof(per_pkt_bw), + &data, (u_char *)&per_pkt_bw); + + /* Set parameters */ + CONFIG_SET_PARAM(serv_test, per_pkt_bw, (u_char)per_pkt_bw, band_idx); + + ret = mt_serv_set_per_pkt_bw(serv_test); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: per_pkt_bw=%u\n", __func__, per_pkt_bw)); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; +} + +static s_int32 hqa_set_freq_offset( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char *data = hqa_frame->data; + u_char band_idx = SERV_GET_PARAM(serv_test, ctrl_band_idx); + u_int32 freq_offset = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + /* Request format type: freq offset (4 bytes) */ + get_param_and_shift_buf(TRUE, sizeof(freq_offset), + &data, (u_char *)&freq_offset); + + /* Set parameters */ + CONFIG_SET_PARAM(serv_test, rf_freq_offset, + (u_int32)freq_offset, band_idx); + + ret = mt_serv_set_freq_offset(serv_test); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: freq offset=%u\n", __func__, freq_offset)); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; +} + +static s_int32 hqa_low_power( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char *data = hqa_frame->data; + u_int32 control = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + get_param_and_shift_buf(TRUE, sizeof(control), + &data, (u_char *)&control); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: control=%u\n", __func__, control)); + + /* + * 0: enter low power mode + * 1: leave low power mode + */ + ret = mt_serv_set_low_power(serv_test, control); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; +} + +static s_int32 hqa_get_antswap_capability( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_int32 antswap_support = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, ("%s\n", __func__)); + + ret = mt_serv_get_antswap_capability(serv_test, &antswap_support); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("antswap_support = %x\n", antswap_support)); + + antswap_support = SERV_OS_HTONL(antswap_support); + sys_ad_move_mem(hqa_frame->data + 2, &antswap_support, + sizeof(antswap_support)); + update_hqa_frame(hqa_frame, 2 + sizeof(antswap_support), ret); + + return ret; +} + +static s_int32 hqa_set_antswap( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char *data = hqa_frame->data; + u_int32 band, ant = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + get_param_and_shift_buf(TRUE, sizeof(u_int32), + &data, (u_char *)&band); + get_param_and_shift_buf(TRUE, sizeof(u_int32), + &data, (u_char *)&ant); + + ret = mt_serv_set_antswap(serv_test, ant); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; +} + +static struct hqa_cmd_entry CMD_SET1[] = { + /* cmd id start from 0x1100 */ + {0x0, legacy_function}, + {0x1, hqa_set_preamble}, + {0x2, hqa_set_rate}, + {0x3, hqa_set_nss}, + {0x4, hqa_set_system_bw}, + {0x5, hqa_set_per_pkt_bw}, + {0x6, legacy_function}, + {0x7, hqa_set_freq_offset}, + {0x9, legacy_function}, + {0xb, hqa_low_power}, + {0xd, hqa_get_antswap_capability}, + {0xe, hqa_set_antswap} +}; + +static s_int32 hqa_reset_txrx_counter( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + ret = mt_serv_reset_txrx_counter(serv_test); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; +} + +static s_int32 hqa_cal_bypass( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char *data = hqa_frame->data; + u_int32 item = 0, band_idx = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + /* Request format type */ + get_param_and_shift_buf(TRUE, sizeof(item), + &data, (u_char *)&item); + get_param_and_shift_buf(TRUE, sizeof(band_idx), + &data, (u_char *)&band_idx); + + /* Set parameters */ + SERV_SET_PARAM(serv_test, ctrl_band_idx, (u_char)band_idx); + + ret = mt_serv_set_cal_bypass(serv_test, item); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: item=%u, band_idx=%u\n", + __func__, item, band_idx)); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; +} + +static s_int32 hqa_set_rx_vector_idx( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char *data = hqa_frame->data; + u_int32 band_idx = 0, group1 = 0, group2 = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + get_param_and_shift_buf(TRUE, sizeof(band_idx), + &data, (u_char *)&band_idx); + get_param_and_shift_buf(TRUE, sizeof(group1), + &data, (u_char *)&group1); + get_param_and_shift_buf(TRUE, sizeof(group2), + &data, (u_char *)&group2); + + /* Set parameters */ + SERV_SET_PARAM(serv_test, ctrl_band_idx, (u_char)band_idx); + + ret = mt_serv_set_rx_vector_idx(serv_test, group1, group2); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; +} + +static s_int32 hqa_set_fagc_rssi_path( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char *data = hqa_frame->data; + u_int32 band_idx = 0, fagc_path = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + get_param_and_shift_buf(TRUE, sizeof(band_idx), + &data, (u_char *)&band_idx); + get_param_and_shift_buf(TRUE, sizeof(fagc_path), + &data, (u_char *)&fagc_path); + + /* Set parameters */ + SERV_SET_PARAM(serv_test, ctrl_band_idx, (u_char)band_idx); + CONFIG_SET_PARAM(serv_test, fagc_path, (u_char)fagc_path, band_idx); + + ret = mt_serv_set_fagc_rssi_path(serv_test); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; +} + +static struct hqa_cmd_entry CMD_SET2[] = { + /* cmd id start from 0x1200 */ + {0x0, hqa_reset_txrx_counter}, + {0x5, legacy_function}, + {0x8, hqa_cal_bypass}, + {0x9, hqa_set_rx_vector_idx}, + {0xa, hqa_set_fagc_rssi_path} +}; + +static s_int32 hqa_mac_bbp_reg_read( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_register *test_regs = &serv_test->test_reg; + u_char *data = hqa_frame->data; + u_int32 cr_val; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + get_param_and_shift_buf(TRUE, sizeof(u_int32), + &data, (u_char *)&test_regs->cr_addr); + + test_regs->cr_num = 1; + + /* Allocate cr_val memory */ + ret = sys_ad_alloc_mem((u_char **)&test_regs->cr_val, sizeof(u_int32)); + if (ret) { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: allocate register memory fail\n", __func__)); + ret = SERV_STATUS_AGENT_INVALID_NULL_POINTER; + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; + } + + ret = mt_serv_reg_eprm_operation(serv_test, SERV_TEST_REG_MAC_READ); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: cr_addr=0x%08x, cr_val=0x%08x\n", + __func__, test_regs->cr_addr, *test_regs->cr_val)); + + cr_val = SERV_OS_HTONL(*test_regs->cr_val); + + /* Update hqa_frame with response: status (2 bytes) */ + sys_ad_move_mem(hqa_frame->data + 2, &cr_val, sizeof(cr_val)); + update_hqa_frame(hqa_frame, 2 + sizeof(cr_val), ret); + + /* Free cr_val memory */ + sys_ad_free_mem(test_regs->cr_val); + + return ret; +} + +static s_int32 hqa_mac_bbp_reg_write( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_register *test_regs = &serv_test->test_reg; + u_char *data = hqa_frame->data; + u_int32 cr_val; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + get_param_and_shift_buf(TRUE, sizeof(u_int32), + &data, (u_char *)&test_regs->cr_addr); + get_param_and_shift_buf(TRUE, sizeof(u_int32), + &data, (u_char *)&cr_val); + + /* Allocate cr_val memory */ + ret = sys_ad_alloc_mem((u_char **)&test_regs->cr_val, sizeof(u_int32)); + if (ret) { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: allocate register memory fail\n", __func__)); + ret = SERV_STATUS_AGENT_INVALID_NULL_POINTER; + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; + } + sys_ad_move_mem(test_regs->cr_val, &cr_val, sizeof(cr_val)); + + ret = mt_serv_reg_eprm_operation(serv_test, SERV_TEST_REG_MAC_WRITE); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: cr_addr=0x%08x, cr_val=0x%08x\n", + __func__, test_regs->cr_addr, *test_regs->cr_val)); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + /* Free cr_val memory */ + sys_ad_free_mem(test_regs->cr_val); + + return ret; +} + +static s_int32 hqa_mac_bbp_reg_bulk_read( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_int16 cr_seq = 0; + struct test_register *test_regs = &serv_test->test_reg; + u_char *data = hqa_frame->data; + u_int32 cr_total_len, cr_value = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + get_param_and_shift_buf(TRUE, sizeof(test_regs->cr_addr), + &data, (u_char *)&test_regs->cr_addr); + get_param_and_shift_buf(TRUE, sizeof(test_regs->cr_num), + &data, (u_char *)&test_regs->cr_num); + + /* Allocate cr_val memory */ + cr_total_len = test_regs->cr_num << 2; + ret = sys_ad_alloc_mem((u_char **)&test_regs->cr_val, cr_total_len); + if (ret) { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: allocate register memory fail\n", __func__)); + ret = SERV_STATUS_AGENT_INVALID_NULL_POINTER; + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; + } + + if (test_regs->cr_num > 371) { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: requested len is longer, make it smaller\n", + __func__)); + ret = SERV_STATUS_AGENT_INVALID_LEN; + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; + } + + ret = mt_serv_reg_eprm_operation(serv_test, + SERV_TEST_REG_MAC_READ_BULK); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: cr_addr=0x%08x, cr_num(unit: 4bytes)=%d\n", + __func__, test_regs->cr_addr, test_regs->cr_num)); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: cr_val = 0x%08x\n", __func__, *test_regs->cr_val)); + + for (cr_seq = 0; cr_seq < test_regs->cr_num; cr_seq++) { + cr_value = test_regs->cr_val[cr_seq]; + test_regs->cr_val[cr_seq] = SERV_OS_HTONL(cr_value); + } + + /* Update hqa_frame with response: status (2 bytes) */ + sys_ad_move_mem(hqa_frame->data + 2, test_regs->cr_val, cr_total_len); + update_hqa_frame(hqa_frame, 2 + cr_total_len, ret); + + /* Free cr_val memory */ + sys_ad_free_mem(test_regs->cr_val); + + return ret; +} + +static s_int32 hqa_rf_reg_bulk_read( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_int16 cr_seq = 0; + struct test_register *test_regs = &serv_test->test_reg; + u_char *data = hqa_frame->data; + u_int32 cr_total_len, cr_value = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + get_param_and_shift_buf(TRUE, sizeof(u_int32), + &data, (u_char *)&test_regs->wf_sel); + get_param_and_shift_buf(TRUE, sizeof(u_int32), + &data, (u_char *)&test_regs->cr_addr); + get_param_and_shift_buf(TRUE, sizeof(u_int32), + &data, (u_char *)&test_regs->cr_num); + + /* Allocate cr_val memory */ + cr_total_len = test_regs->cr_num << 2; + ret = sys_ad_alloc_mem((u_char **)&test_regs->cr_val, cr_total_len); + if (ret) { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: allocate register memory fail\n", __func__)); + ret = SERV_STATUS_AGENT_INVALID_NULL_POINTER; + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; + } + + ret = mt_serv_reg_eprm_operation(serv_test, + SERV_TEST_REG_RF_READ_BULK); + + for (cr_seq = 0; cr_seq < test_regs->cr_num; cr_seq++) { + cr_value = test_regs->cr_val[cr_seq]; + test_regs->cr_val[cr_seq] = SERV_OS_HTONL(cr_value); + } + /* Update hqa_frame with response: status (2 bytes) */ + sys_ad_move_mem(hqa_frame->data + 2, test_regs->cr_val, cr_total_len); + update_hqa_frame(hqa_frame, 2 + cr_total_len, ret); + + /* Free cr_val memory */ + sys_ad_free_mem(test_regs->cr_val); + + return ret; +} + +static s_int32 hqa_rf_reg_bulk_write( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_register *test_regs = &serv_test->test_reg; + u_char *data = hqa_frame->data; + u_int32 idx, cr_total_len; + u_int32 *dst; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + get_param_and_shift_buf(TRUE, sizeof(u_int32), + &data, (u_char *)&test_regs->wf_sel); + get_param_and_shift_buf(TRUE, sizeof(u_int32), + &data, (u_char *)&test_regs->cr_addr); + get_param_and_shift_buf(TRUE, sizeof(u_int32), + &data, (u_char *)&test_regs->cr_num); + + /* Allocate cr_val memory */ + cr_total_len = test_regs->cr_num << 2; + ret = sys_ad_alloc_mem((u_char **)&test_regs->cr_val, cr_total_len); + if (ret) { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: allocate register memory fail\n", __func__)); + ret = SERV_STATUS_AGENT_INVALID_NULL_POINTER; + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; + } + + for (idx = 0; idx < test_regs->cr_num; idx++) { + dst = test_regs->cr_val + idx; + get_param_and_shift_buf(TRUE, sizeof(u_int32), + &data, (u_char *) dst); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: cr_addr=0x%08x, cr_val=0x%08x\n", + __func__, test_regs->cr_addr, *dst)); + } + + ret = mt_serv_reg_eprm_operation(serv_test, + SERV_TEST_REG_RF_WRITE_BULK); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + /* Free cr_val memory */ + sys_ad_free_mem(test_regs->cr_val); + + return ret; +} + +static s_int32 hqa_read_eeprom( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_eeprom *test_eprms = &serv_test->test_eprm; + u_char *data = hqa_frame->data; + u_int16 value; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + get_param_and_shift_buf(TRUE, sizeof(u_int16), + &data, (u_char *)&test_eprms->offset); + + /* Allocate value memory */ + ret = sys_ad_alloc_mem((u_char **)&test_eprms->value, sizeof(u_int16)); + if (ret) { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: allocate eeprom memory fail\n", __func__)); + ret = SERV_STATUS_AGENT_INVALID_NULL_POINTER; + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; + } + + ret = mt_serv_reg_eprm_operation(serv_test, SERV_TEST_EEPROM_READ); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: offset=0x%04x, value=0x%04x\n", + __func__, test_eprms->offset, *test_eprms->value)); + + value = SERV_OS_HTONS(*test_eprms->value); + + /* Update hqa_frame with response: status (2 bytes) */ + sys_ad_move_mem(hqa_frame->data + 2, &value, sizeof(value)); + update_hqa_frame(hqa_frame, 2 + sizeof(value), ret); + + /* Free value memory */ + sys_ad_free_mem(test_eprms->value); + + return ret; +} + +static s_int32 hqa_write_eeprom( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_eeprom *test_eprms = &serv_test->test_eprm; + u_char *data = hqa_frame->data; + u_int16 value; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + get_param_and_shift_buf(TRUE, sizeof(u_int16), + &data, (u_char *)&test_eprms->offset); + get_param_and_shift_buf(TRUE, sizeof(u_int16), + &data, (u_char *)&value); + + /* Allocate value memory */ + ret = sys_ad_alloc_mem((u_char **)&test_eprms->value, sizeof(u_int16)); + if (ret) { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: allocate eeprom memory fail\n", __func__)); + ret = SERV_STATUS_AGENT_INVALID_NULL_POINTER; + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; + } + sys_ad_move_mem(test_eprms->value, &value, sizeof(value)); + + ret = mt_serv_reg_eprm_operation(serv_test, SERV_TEST_EEPROM_WRITE); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: offset=0x%04x, value=0x%04x\n", + __func__, test_eprms->offset, *test_eprms->value)); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + /* Free value memory */ + sys_ad_free_mem(test_eprms->value); + + return ret; +} + +static void memcpy_eeprom(u_char *dst, u_char *src, u_long len) +{ + u_long i; + u_short *p_dst, *p_src; + + p_dst = (u_short *) dst; + p_src = (u_short *) src; + + for (i = 0; i < (len >> 1); i++) { + *p_dst = SERV_OS_NTOHS(*p_src); + p_dst++; + p_src++; + } + + if ((len % 2) != 0) { + sys_ad_move_mem(p_dst, p_src, (len % 2)); + *p_dst = SERV_OS_NTOHS(*p_dst); + } +} + +static s_int32 hqa_read_bulk_eeprom( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_eeprom *test_eprms = &serv_test->test_eprm; + u_char *data = hqa_frame->data; + u_int32 eeprom_size; + u_int16 offset, length; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + get_param_and_shift_buf(TRUE, sizeof(test_eprms->offset), + &data, (u_char *)&test_eprms->offset); + get_param_and_shift_buf(TRUE, sizeof(test_eprms->length), + &data, (u_char *)&test_eprms->length); + + /* Allocate value memory */ + eeprom_size = serv_test->test_winfo->chip_cap.efuse_size; + offset = test_eprms->offset; + length = test_eprms->length; + ret = sys_ad_alloc_mem((u_char **)&test_eprms->value, eeprom_size); + if (ret) { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: allocate eeprom memory fail\n", __func__)); + ret = SERV_STATUS_AGENT_INVALID_NULL_POINTER; + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; + } + + ret = mt_serv_reg_eprm_operation(serv_test, + SERV_TEST_EEPROM_READ_BULK); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: offset=0x%04x, length=%d\n", __func__, offset, length)); + + /* Update hqa_frame with response: status (2 bytes) */ + if (offset + length <= eeprom_size) + memcpy_eeprom(hqa_frame->data + 2, + (u_char *)test_eprms->value + offset, length); + else { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: exceed eeprom size (offset=0x%04x, size=%d)\n", + __func__, offset+length, eeprom_size)); + length = 0; + ret = SERV_STATUS_AGENT_INVALID_LEN; + } + update_hqa_frame(hqa_frame, 2 + length, ret); + + /* Free value memory */ + sys_ad_free_mem(test_eprms->value); + + return ret; +} + +static s_int32 hqa_write_bulk_eeprom( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_eeprom *test_eprms = &serv_test->test_eprm; + u_char *data = hqa_frame->data; + u_int32 eeprom_size; + u_int16 offset = 0, length = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + get_param_and_shift_buf(TRUE, sizeof(test_eprms->offset), + &data, (u_char *)&test_eprms->offset); + get_param_and_shift_buf(TRUE, sizeof(test_eprms->length), + &data, (u_char *)&test_eprms->length); + + /* Allocate value memory */ + eeprom_size = serv_test->test_winfo->chip_cap.efuse_size; + ret = sys_ad_alloc_mem((u_char **)&test_eprms->value, eeprom_size); + if (ret) { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: allocate eeprom memory fail\n", __func__)); + ret = SERV_STATUS_AGENT_INVALID_NULL_POINTER; + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; + } + memcpy_eeprom((u_char *)test_eprms->value + (test_eprms->offset & ~0x1), + data, test_eprms->length); + + ret = mt_serv_reg_eprm_operation(serv_test, + SERV_TEST_EEPROM_WRITE_BULK); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: offset=0x%04x, length=%d\n", __func__, offset, length)); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + /* Free value memory */ + sys_ad_free_mem(test_eprms->value); + + return ret; +} + +static s_int32 hqa_check_efuse_mode( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_int32 efuse_mode; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + if (WINFO_GET_PARAM(serv_test, use_efuse)) + efuse_mode = 1; + else + efuse_mode = 0; + + efuse_mode = SERV_OS_HTONL(efuse_mode); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: efuse_mode=%u\n", __func__, efuse_mode)); + + /* Update hqa_frame with response: status (2 bytes) */ + sys_ad_move_mem(hqa_frame->data + 2, &efuse_mode, sizeof(efuse_mode)); + update_hqa_frame(hqa_frame, 6, ret); + + return ret; +} + +static s_int32 hqa_get_free_efuse_block( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_int32 free_block; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + ret = mt_serv_reg_eprm_operation(serv_test, + SERV_TEST_EEPROM_GET_FREE_EFUSE_BLOCK); + + free_block = EEPROM_GET_PARAM(serv_test, efuse_free_block); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: efuse_free_block=%u\n", __func__, free_block)); + + free_block = SERV_OS_HTONL(free_block); + + /* Update hqa_frame with response: status (2 bytes) */ + sys_ad_move_mem(hqa_frame->data + 2, &free_block, sizeof(free_block)); + update_hqa_frame(hqa_frame, 2 + sizeof(free_block), ret); + + return ret; +} + +static s_int32 hqa_get_tx_power( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char *data = hqa_frame->data; + u_int32 power = 0, band_idx = 0, channel = 0; + u_int32 ch_band = 0, ant_idx = 0, efuse_offset = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + /* Request format type */ + get_param_and_shift_buf(TRUE, sizeof(channel), + &data, (u_char *)&channel); + get_param_and_shift_buf(TRUE, sizeof(band_idx), + &data, (u_char *)&band_idx); + get_param_and_shift_buf(TRUE, sizeof(ch_band), + &data, (u_char *)&ch_band); + get_param_and_shift_buf(TRUE, sizeof(ant_idx), + &data, (u_char *)&ant_idx); + + /* set parameters */ + SERV_SET_PARAM(serv_test, ctrl_band_idx, (u_char)band_idx); + CONFIG_SET_PARAM(serv_test, pwr_param.ant_idx, + (u_int32)ant_idx, band_idx); + CONFIG_SET_PARAM(serv_test, pwr_param.channel, + (u_int32)channel, band_idx); + CONFIG_SET_PARAM(serv_test, pwr_param.band_idx, + (u_int32)band_idx, band_idx); + CONFIG_SET_PARAM(serv_test, pwr_param.ch_band, + (u_int32)ch_band, band_idx); + + ret = mt_serv_tx_power_operation(serv_test, SERV_TEST_TXPWR_GET_PWR); + + power = CONFIG_GET_PARAM(serv_test, pwr_param.power, band_idx); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: power=%u, band_idx=%u, channel=%u\n", + __func__, power, band_idx, channel)); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: ch_band=%u, ant_idx=%u\n", + __func__, ch_band, ant_idx)); + + /* update hqa_frame with response: status (2 bytes) */ + efuse_offset = SERV_OS_HTONL(efuse_offset); + sys_ad_move_mem(hqa_frame->data + 2, &efuse_offset, + sizeof(efuse_offset)); + power = SERV_OS_HTONL(power); + sys_ad_move_mem(hqa_frame->data + 2 + 4, &power, sizeof(power)); + update_hqa_frame(hqa_frame, + 2 + sizeof(power) + sizeof(efuse_offset), ret); + + return ret; +} + +static s_int32 hqa_set_cfg_on_off( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char *data = hqa_frame->data; + u_int32 type, enable = 0, band_idx = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + /* Request format type */ + get_param_and_shift_buf(TRUE, sizeof(type), + &data, (u_char *)&type); + get_param_and_shift_buf(TRUE, sizeof(enable), + &data, (u_char *)&enable); + get_param_and_shift_buf(TRUE, sizeof(band_idx), + &data, (u_char *)&band_idx); + + /* Set parameters */ + SERV_SET_PARAM(serv_test, ctrl_band_idx, (u_char)band_idx); + CONFIG_SET_PARAM(serv_test, log_type, (u_char)type, band_idx); + CONFIG_SET_PARAM(serv_test, log_enable, (u_char)enable, band_idx); + + ret = mt_serv_set_cfg_on_off(serv_test); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: type=%u, enable=%u, band_idx=%u\n", + __func__, type, enable, band_idx)); + + update_hqa_frame(hqa_frame, 2, ret); + + return ret; +} + +static s_int32 hqa_get_freq_offset( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_int32 freq_offset = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + ret = mt_serv_get_freq_offset(serv_test, &freq_offset); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: freq offset: %d\n", __func__, freq_offset)); + + /* update hqa_frame with response: status (2 bytes) */ + freq_offset = SERV_OS_HTONL(freq_offset); + sys_ad_move_mem(hqa_frame->data + 2, &freq_offset, sizeof(freq_offset)); + update_hqa_frame(hqa_frame, 2 + sizeof(freq_offset), ret); + + return ret; +} + +static s_int32 hqa_dbdc_tx_tone( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct hqa_tx_tone param; + u_char *data = hqa_frame->data; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + sys_ad_zero_mem(¶m, sizeof(param)); + + /* Request format type */ + get_param_and_shift_buf(TRUE, sizeof(param.band_idx), + &data, (u_char *)¶m.band_idx); + get_param_and_shift_buf(TRUE, sizeof(param.tx_tone_en), + &data, (u_char *)¶m.tx_tone_en); + get_param_and_shift_buf(TRUE, sizeof(param.ant_idx), + &data, (u_char *)¶m.ant_idx); + get_param_and_shift_buf(TRUE, sizeof(param.tone_type), + &data, (u_char *)¶m.tone_type); + get_param_and_shift_buf(TRUE, sizeof(param.tone_freq), + &data, (u_char *)¶m.tone_freq); + get_param_and_shift_buf(TRUE, sizeof(param.dc_offset_I), + &data, (u_char *)¶m.dc_offset_I); + get_param_and_shift_buf(TRUE, sizeof(param.dc_offset_Q), + &data, (u_char *)¶m.dc_offset_Q); + get_param_and_shift_buf(TRUE, sizeof(param.band), + &data, (u_char *)¶m.band); + get_param_and_shift_buf(TRUE, sizeof(param.rf_pwr), + &data, (u_char *)¶m.rf_pwr); + get_param_and_shift_buf(TRUE, sizeof(param.digi_pwr), + &data, (u_char *)¶m.digi_pwr); + + /* Set parameters */ + SERV_SET_PARAM(serv_test, ctrl_band_idx, (u_char)param.band_idx); + CONFIG_SET_PARAM(serv_test, tx_tone_en, + (u_int32)param.tx_tone_en, param.band_idx); + CONFIG_SET_PARAM(serv_test, ant_idx, + (u_int32)param.ant_idx, param.band_idx); + CONFIG_SET_PARAM(serv_test, tone_type, + (u_int32)param.tone_type, param.band_idx); + CONFIG_SET_PARAM(serv_test, tone_freq, + (u_int32)param.tone_freq, param.band_idx); + CONFIG_SET_PARAM(serv_test, dc_offset_I, + (u_int32)param.dc_offset_I, param.band_idx); + CONFIG_SET_PARAM(serv_test, dc_offset_Q, + (u_int32)param.dc_offset_Q, param.band_idx); + CONFIG_SET_PARAM(serv_test, ch_band, + (u_char)param.band, param.band_idx); + CONFIG_SET_PARAM(serv_test, rf_pwr, + (u_int32)param.rf_pwr, param.band_idx); + CONFIG_SET_PARAM(serv_test, digi_pwr, + (u_int32)param.digi_pwr, param.band_idx); + + ret = mt_serv_dbdc_tx_tone(serv_test); + ret = mt_serv_dbdc_tx_tone_pwr(serv_test); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: band_idx=%u, tx_tone_en=%u, ant_idx=0x%x\n", + __func__, param.band_idx, param.tx_tone_en, param.ant_idx)); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: tone_type=%u, tone_freq=%u, dc_offset_I=0x%x\n", + __func__, param.tone_type, param.tone_freq, + param.dc_offset_I)); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: dc_offset_Q=%u, band=%u, rf_pwr=0x%x, digi_pwr=0x%x\n", + __func__, param.dc_offset_Q, param.band, param.rf_pwr, + param.digi_pwr)); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; +} + +static s_int32 hqa_dbdc_continuous_tx( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct hqa_continuous_tx param; + u_char *data = hqa_frame->data; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + sys_ad_zero_mem(¶m, sizeof(param)); + + get_param_and_shift_buf(TRUE, sizeof(param.band_idx), + &data, (u_char *) ¶m.band_idx); + get_param_and_shift_buf(TRUE, sizeof(param.tx_tone_en), + &data, (u_char *) ¶m.tx_tone_en); + get_param_and_shift_buf(TRUE, sizeof(param.ant_mask), + &data, (u_char *) ¶m.ant_mask); + get_param_and_shift_buf(TRUE, sizeof(param.tx_mode), + &data, (u_char *) ¶m.tx_mode); + get_param_and_shift_buf(TRUE, sizeof(param.bw), + &data, (u_char *) ¶m.bw); + get_param_and_shift_buf(TRUE, sizeof(param.pri_ch), + &data, (u_char *) ¶m.pri_ch); + get_param_and_shift_buf(TRUE, sizeof(param.rate), + &data, (u_char *) ¶m.rate); + get_param_and_shift_buf(TRUE, sizeof(param.central_ch), + &data, (u_char *) ¶m.central_ch); + get_param_and_shift_buf(TRUE, sizeof(param.tx_fd_mode), + &data, (u_char *) ¶m.tx_fd_mode); + + /* Set parameters */ + SERV_SET_PARAM(serv_test, ctrl_band_idx, (u_char)param.band_idx); + CONFIG_SET_PARAM(serv_test, tx_tone_en, + (u_int32)param.tx_tone_en, param.band_idx); + CONFIG_SET_PARAM(serv_test, ant_mask, + (u_int32)param.ant_mask, param.band_idx); + CONFIG_SET_PARAM(serv_test, tx_mode, + (u_char)param.tx_mode, param.band_idx); + CONFIG_SET_PARAM(serv_test, bw, + (u_char)param.bw, param.band_idx); + CONFIG_SET_PARAM(serv_test, ctrl_ch, + (u_char)param.pri_ch, param.band_idx); + CONFIG_SET_PARAM(serv_test, rate, + (u_int32)param.rate, param.band_idx); + CONFIG_SET_PARAM(serv_test, channel, + (u_char)param.central_ch, param.band_idx); + CONFIG_SET_PARAM(serv_test, tx_fd_mode, + (u_int32)param.tx_fd_mode, param.band_idx); + + ret = mt_serv_dbdc_continuous_tx(serv_test); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: param band_idx=%u, tx_tone_en=%u, ant_mask=0x%x\n", + __func__, param.band_idx, param.tx_tone_en, param.ant_mask)); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: param phy_mode=%u, bw=%u, pri_ch=%u\n", + __func__, param.tx_mode, param.bw, param.pri_ch)); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: param rate=%u, central_ch=%u, tx_fd_mode=%u\n", + __func__, param.rate, param.central_ch, param.tx_fd_mode)); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; +} + +static s_int32 hqa_set_rx_filter_pkt_len( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char *data = hqa_frame->data; + u_int32 band_idx = 0, enable = 0, rx_pkt_len = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + get_param_and_shift_buf(TRUE, sizeof(band_idx), + &data, (u_char *)&band_idx); + get_param_and_shift_buf(TRUE, sizeof(enable), + &data, (u_char *)&enable); + get_param_and_shift_buf(TRUE, sizeof(rx_pkt_len), + &data, (u_char *)&rx_pkt_len); + + /* Set parameters */ + SERV_SET_PARAM(serv_test, ctrl_band_idx, (u_char)band_idx); + CONFIG_SET_PARAM(serv_test, rx_filter_en, + (u_int8)enable, band_idx); + CONFIG_SET_PARAM(serv_test, rx_filter_pkt_len, + (u_int32)rx_pkt_len, band_idx); + + ret = mt_serv_set_rx_filter_pkt_len(serv_test); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; +} + +static s_int32 hqa_get_tx_info( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_int32 tx_cnt0 = 0, tx_cnt1 = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + ret = mt_serv_get_tx_info(serv_test); + + /* Get parameters */ + tx_cnt0 = CONFIG_GET_PARAM(serv_test, tx_stat.tx_done_cnt, + TEST_DBDC_BAND0); + tx_cnt0 = SERV_OS_HTONL(tx_cnt0); +/* #ifdef DBDC_MODE */ +#if 1 + if (IS_TEST_DBDC(serv_test->test_winfo)) { + tx_cnt1 = CONFIG_GET_PARAM(serv_test, tx_stat.tx_done_cnt, + TEST_DBDC_BAND1); + tx_cnt1 = SERV_OS_HTONL(tx_cnt1); + } +#endif + /* Update hqa_frame with response: status (2 bytes) */ + sys_ad_move_mem((hqa_frame->data + 2), + &tx_cnt0, sizeof(tx_cnt0)); + sys_ad_move_mem((hqa_frame->data + 2 + sizeof(tx_cnt0)), + &tx_cnt1, sizeof(tx_cnt1)); + update_hqa_frame(hqa_frame, + 2 + sizeof(tx_cnt0) + sizeof(tx_cnt1), ret); + + return ret; +} + +static s_int32 hqa_get_cfg_on_off( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char *data = hqa_frame->data; + s_int32 type = 0, band_idx = 0; + u_int32 result = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + /* Request format type */ + get_param_and_shift_buf(TRUE, sizeof(type), + &data, (u_char *)&type); + get_param_and_shift_buf(TRUE, sizeof(band_idx), + &data, (u_char *)&band_idx); + + ret = mt_serv_get_cfg_on_off(serv_test, type, &result); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: type=%u, result=%u\n", __func__, type, result)); + + /* Update hqa_frame with response: status (2 bytes) */ + result = SERV_OS_HTONL(result); + sys_ad_move_mem(hqa_frame->data + 2, &result, sizeof(result)); + update_hqa_frame(hqa_frame, 2 + sizeof(result), ret); + + return ret; +} + +static s_int32 hqa_ca53_reg_read( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_register *test_regs = &serv_test->test_reg; + u_char *data = hqa_frame->data; + u_long cr_val; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + /* Use u_long here to get 4bytes firmly */ + get_param_and_shift_buf(TRUE, sizeof(u_long), + &data, (u_char *)&test_regs->cr_addr); + + /* Allocate cr_val memory */ + ret = sys_ad_alloc_mem((u_char **)&test_regs->cr_val, sizeof(u_long)); + if (ret) { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: allocate register memory fail\n", __func__)); + ret = SERV_STATUS_AGENT_INVALID_NULL_POINTER; + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; + } + + ret = mt_serv_reg_eprm_operation(serv_test, SERV_TEST_REG_CA53_READ); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: cr_addr=0x%08x, cr_val=0x%08x\n", + __func__, test_regs->cr_addr, *test_regs->cr_val)); + + cr_val = SERV_OS_HTONL(*test_regs->cr_val); + + /* Update hqa_frame with response: status (2 bytes) */ + sys_ad_move_mem(hqa_frame->data + 2, &cr_val, sizeof(cr_val)); + update_hqa_frame(hqa_frame, 2 + sizeof(cr_val), ret); + + /* Free cr_val memory */ + sys_ad_free_mem(test_regs->cr_val); + + return ret; +} + +static s_int32 hqa_ca53_reg_write( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_register *test_regs = &serv_test->test_reg; + u_char *data = hqa_frame->data; + u_int32 cr_val; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + /* Use u_long here to get 4bytes firmly */ + get_param_and_shift_buf(TRUE, sizeof(u_long), + &data, (u_char *)&test_regs->cr_addr); + get_param_and_shift_buf(TRUE, sizeof(u_int32), + &data, (u_char *)&cr_val); + + /* Allocate cr_val memory */ + ret = sys_ad_alloc_mem((u_char **)&test_regs->cr_val, sizeof(u_int32)); + if (ret) { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: allocate register memory fail\n", __func__)); + ret = SERV_STATUS_AGENT_INVALID_NULL_POINTER; + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; + } + sys_ad_move_mem(test_regs->cr_val, &cr_val, sizeof(cr_val)); + + ret = mt_serv_reg_eprm_operation(serv_test, SERV_TEST_REG_CA53_WRITE); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: cr_addr=0x%08x, cr_val=0x%08x\n", + __func__, test_regs->cr_addr, *test_regs->cr_val)); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + /* Free cr_val memory */ + sys_ad_free_mem(test_regs->cr_val); + + return ret; +} + +static s_int32 hqa_get_tx_tone_pwr( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char *data = hqa_frame->data; + u_int32 power = 0, ant_idx = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + /* request format type */ + get_param_and_shift_buf(TRUE, sizeof(ant_idx), + &data, (u_char *)&ant_idx); + + ret = mt_serv_get_tx_tone_pwr(serv_test, ant_idx, &power); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: ant_idx: %d, power: %d\n", + __func__, ant_idx, power)); + + /* update hqa_frame with response: status (2 bytes) */ + power = SERV_OS_HTONL(power); + sys_ad_move_mem(hqa_frame->data + 2, &power, sizeof(power)); + update_hqa_frame(hqa_frame, 2 + sizeof(power), ret); + + return ret; +} + +static struct hqa_cmd_entry CMD_SET3[] = { + /* cmd id start from 0x1300 */ + {0x0, hqa_mac_bbp_reg_read}, + {0x1, hqa_mac_bbp_reg_write}, + {0x2, hqa_mac_bbp_reg_bulk_read}, + {0x3, hqa_rf_reg_bulk_read}, + {0x4, hqa_rf_reg_bulk_write}, + {0x5, hqa_read_eeprom}, + {0x6, hqa_write_eeprom}, + {0x7, hqa_read_bulk_eeprom}, + {0x8, hqa_write_bulk_eeprom}, + {0x9, hqa_check_efuse_mode}, + {0xa, hqa_get_free_efuse_block}, + {0xd, hqa_get_tx_power}, + {0xe, hqa_set_cfg_on_off}, + {0xf, hqa_get_freq_offset}, + {0x10, hqa_dbdc_tx_tone}, + {0x11, hqa_dbdc_continuous_tx}, + {0x12, hqa_set_rx_filter_pkt_len}, + {0x13, hqa_get_tx_info}, + {0x14, hqa_get_cfg_on_off}, + {0x15, legacy_function}, + {0x17, legacy_function}, + {0x18, hqa_ca53_reg_read}, + {0x19, hqa_ca53_reg_write}, + {0x1a, hqa_get_tx_tone_pwr} +}; + +static s_int32 hqa_get_thermal_val( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_int32 value = 0; + u_char band_idx; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + /* request format type */ + band_idx = serv_test->ctrl_band_idx; + + ret = mt_serv_get_thermal_val(serv_test, band_idx, &value); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: value: %d\n", __func__, value)); + + /* update hqa_frame with response: status (2 bytes) */ + value = SERV_OS_HTONL(value); + sys_ad_move_mem(hqa_frame->data + 2, &value, sizeof(value)); + update_hqa_frame(hqa_frame, 2 + sizeof(value), ret); + + return ret; +} + +static struct hqa_cmd_entry CMD_SET4[] = { + /* cmd id start from 0x1400 */ + {0x1, hqa_get_thermal_val} +}; + +static s_int32 hqa_get_fw_info( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct serv_fw_info *fw_info = NULL; + u_char op_mode; + u_int8 loop, month = 0; + u_char date[8], time[6]; + u_char *kernel_info = NULL; + u_char *month_array[12] = { + "Jan", + "Feb", + "Mar", + "Apr", + "May", + "Jun", + "Jul", + "Aug", + "Sep", + "Oct", + "Nov", + "Dec", + }; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + fw_info = WINFO_GET_PADDR(serv_test, wm_fw_info); + sys_ad_zero_mem(&date[0], sizeof(date)); + sys_ad_zero_mem(&time[0], sizeof(time)); + + /* Get information from kernel */ + for (loop = 0; loop < 12; loop++) { + kernel_info = strstr(utsname()->version, month_array[loop]); + + if (kernel_info) + break; + } + + /* SW package build time */ + sys_ad_move_mem(&time[0], kernel_info + 7, 2); + sys_ad_move_mem(&time[2], kernel_info + 10, 2); + sys_ad_move_mem(&time[4], kernel_info + 13, 2); + + /* SW package build date */ + sys_ad_move_mem(&date[0], kernel_info + 20, 4); + sys_ad_move_mem(&date[6], kernel_info + 4, 2); + + for (loop = 0; loop < 12; loop++) { + if (sys_ad_cmp_mem(month_array[loop], kernel_info, 3) == 0) { + month = loop + 1; + break; + } + } + + date[4] = month / 10 % 10 + '0'; + date[5] = month % 10 + '0'; + + /* Update hqa_frame with response: status (2 bytes) */ + /* The 1 byte for op_mode doesn't use anymore but still keep it */ + sys_ad_move_mem((hqa_frame->data + 2), &op_mode, sizeof(op_mode)); + sys_ad_move_mem((hqa_frame->data + 2 + sizeof(op_mode)), + &date, sizeof(date)); + sys_ad_move_mem((hqa_frame->data + 2 + sizeof(op_mode) + sizeof(date)), + &time, sizeof(time)); + sys_ad_move_mem((hqa_frame->data + 2 + sizeof(op_mode) + + sizeof(date) + sizeof(time)), + &fw_info->ram_built_date[0], + sizeof(fw_info->ram_built_date)); + update_hqa_frame(hqa_frame, (2+1+8+6+15), ret); + + return ret; +} + +static s_int32 hqa_set_stbc( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char *data = hqa_frame->data; + u_char band_idx = SERV_GET_PARAM(serv_test, ctrl_band_idx); + u_int32 stbc = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + /* Request format type: Enable (4 bytes) */ + get_param_and_shift_buf(TRUE, sizeof(stbc), + &data, (u_char *)&stbc); + + /* Set parameters */ + CONFIG_SET_PARAM(serv_test, stbc, (u_char)stbc, band_idx); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: stbc enable=%u\n", __func__, stbc)); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; +} + +static s_int32 hqa_set_short_gi( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char *data = hqa_frame->data; + u_char band_idx = SERV_GET_PARAM(serv_test, ctrl_band_idx); + u_int32 sgi = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + /* Request format type: Enable (4 bytes) */ + get_param_and_shift_buf(TRUE, sizeof(sgi), + &data, (u_char *)&sgi); + + /* Set parameters */ + CONFIG_SET_PARAM(serv_test, sgi, (u_char)sgi, band_idx); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: sgi enable=%u\n", __func__, sgi)); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; +} + +static s_int32 hqa_set_dpd( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char *data = hqa_frame->data; + u_int32 on_off = 0, wf_sel = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + /* Request format type */ + get_param_and_shift_buf(TRUE, sizeof(on_off), + &data, (u_char *)&on_off); + get_param_and_shift_buf(TRUE, sizeof(wf_sel), + &data, (u_char *)&wf_sel); + + ret = mt_serv_set_dpd(serv_test, on_off, wf_sel); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: on_off: %d, wf_sel: %d\n", __func__, on_off, wf_sel)); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; +} + +static s_int32 hqa_set_tssi_onoff( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char *data = hqa_frame->data; + u_int32 on_off = 0, wf_sel = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + /* Request format type */ + get_param_and_shift_buf(TRUE, sizeof(on_off), + &data, (u_char *)&on_off); + get_param_and_shift_buf(TRUE, sizeof(wf_sel), + &data, (u_char *)&wf_sel); + + ret = mt_serv_set_tssi(serv_test, on_off, wf_sel); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: on_off: %d\n", __func__, on_off)); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; +} + +static s_int32 hqa_get_rx_statistics_leg( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct hqa_rx_stat_leg rx_stat; + struct test_rx_stat_leg test_rx_stat; + u_char dw_cnt = 0, dw_idx = 0; + u_char *ptr2 = NULL; + u_int32 *ptr = NULL; + u_int32 buf; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + ret = mt_serv_get_rx_stat_leg(serv_test, &test_rx_stat); + sys_ad_move_mem(&rx_stat, &test_rx_stat, + sizeof(struct hqa_rx_stat_leg)); + dw_cnt = sizeof(struct hqa_rx_stat_leg) >> 2; + + for (dw_idx = 0, ptr = (u_int32 *)&rx_stat, ptr2 = hqa_frame->data + 2; + dw_idx < dw_cnt; dw_idx++, ptr++, ptr2 += 4) { + buf = SERV_OS_HTONL(*ptr); + sys_ad_move_mem(ptr2, &buf, sizeof(u_int32)); + } + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2 + sizeof(struct hqa_rx_stat_leg), ret); + + return ret; +} + +static s_int32 hqa_get_rx_statistics_all( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + u_int32 buf_size = 0; + s_int32 ret = SERV_STATUS_SUCCESS; + u_int32 type_mask = 0, band_idx = 0, type_num = 0, length; + u_int32 blk_idx = 0, type_idx = 0, buf = 0; + u_int32 dw_idx = 0, dw_cnt = 0; + u_int32 *ptr2 = NULL; + struct test_rx_stat_u *rx_stat = NULL; + boolean dbdc_mode = FALSE; + u_int8 path[TEST_ANT_NUM] = {0}; + u_int8 path_len = 0; + u_int8 *ptr = NULL; + u_char *data = hqa_frame->data; + struct hqa_rx_stat_resp_format st_form[SERV_RX_STAT_TYPE_NUM] = { + {SERV_RX_STAT_TYPE_BAND, 0, 0, 0, + sizeof(struct hqa_rx_stat_band_info)}, + {SERV_RX_STAT_TYPE_PATH, 0, 0, 0, + sizeof(struct hqa_rx_stat_path_info)}, + {SERV_RX_STAT_TYPE_USER, 0, 0, 0, + sizeof(struct hqa_rx_stat_user_info)}, + {SERV_RX_STAT_TYPE_COMM, 0, 0, 0, + sizeof(struct hqa_rx_stat_comm_info)} + }; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + /* Request format type */ + get_param_and_shift_buf(TRUE, sizeof(type_mask), + &data, (u_char *)&type_mask); + get_param_and_shift_buf(TRUE, sizeof(band_idx), + &data, (u_char *)&band_idx); + + /* check dbdc mode condition */ + dbdc_mode = IS_TEST_DBDC(serv_test->test_winfo); + + /* sanity check for band index param */ + if ((!dbdc_mode) && (band_idx != TEST_DBDC_BAND0)) + goto error2; + + /* check wifi path combination for specific band */ + ret = mt_serv_get_wf_path_comb(serv_test, + band_idx, + dbdc_mode, + path, + &path_len); + + /* TODO: check user combination for specific band */ + /* host driver not support related utility */ + /* if need this function, need host driver support */ + + /* update item mask for each type */ + st_form[SERV_RX_STAT_TYPE_BAND].item_mask = BIT(band_idx); + for (blk_idx = 0; blk_idx < path_len; blk_idx++) + st_form[SERV_RX_STAT_TYPE_PATH].item_mask |= BIT(path[blk_idx]); + for (blk_idx = 0; blk_idx < TEST_USER_NUM; blk_idx++) + st_form[SERV_RX_STAT_TYPE_USER].item_mask |= BIT(blk_idx); + st_form[SERV_RX_STAT_TYPE_COMM].item_mask = BIT(0); + + /* update block count for each type */ + for (type_idx = SERV_RX_STAT_TYPE_BAND; + type_idx < SERV_RX_STAT_TYPE_NUM; type_idx++) { + for (blk_idx = 0; blk_idx < 32; blk_idx++) { + if (st_form[type_idx].item_mask & BIT(blk_idx)) + st_form[type_idx].blk_cnt++; + } + } + + ptr = hqa_frame->data + 2 + sizeof(type_num); + + /* allocate dynamic memory for rx stat info */ + ret = sys_ad_alloc_mem((u_char **)&rx_stat, + sizeof(struct test_rx_stat_u)); + if (ret != SERV_STATUS_SUCCESS) + goto error1; + + for (type_idx = SERV_RX_STAT_TYPE_BAND; + type_idx < SERV_RX_STAT_TYPE_NUM; type_idx++) { + if (type_mask & BIT(type_idx)) { + type_num++; + length = st_form[type_idx].blk_cnt * + st_form[type_idx].blk_size; + + /* fill in type */ + buf = SERV_OS_HTONL(st_form[type_idx].type); + sys_ad_move_mem(ptr, &buf, sizeof(buf)); + ptr += sizeof(st_form[type_idx].type); + buf_size += sizeof(st_form[type_idx].type); + + /* fill in version */ + buf = SERV_OS_HTONL(st_form[type_idx].version); + sys_ad_move_mem(ptr, &buf, sizeof(buf)); + ptr += sizeof(st_form[type_idx].version); + buf_size += sizeof(st_form[type_idx].version); + + /* fill in item mask */ + buf = SERV_OS_HTONL(st_form[type_idx].item_mask); + sys_ad_move_mem(ptr, &buf, sizeof(buf)); + ptr += sizeof(st_form[type_idx].item_mask); + buf_size += sizeof(st_form[type_idx].item_mask); + + /* fill in length */ + buf = SERV_OS_HTONL(length); + sys_ad_move_mem(ptr, &buf, sizeof(buf)); + ptr += sizeof(length); + buf_size += sizeof(length); + + for (blk_idx = 0; blk_idx < 32; blk_idx++) { + if (st_form[type_idx].item_mask + & BIT(blk_idx)) { + /* service handle for rx stat info */ + mt_serv_get_rx_stat(serv_test, + band_idx, + blk_idx, + type_idx, + rx_stat); + + ptr2 = (u_int32 *) rx_stat; + dw_cnt = st_form[type_idx].blk_size + >> 2; + for (dw_idx = 0; dw_idx < dw_cnt; + dw_idx++, ptr2++, + ptr += 4) { + /* endian transform */ + buf = SERV_OS_HTONL(*ptr2); + /* fill in block content */ + sys_ad_move_mem(ptr, &buf, + sizeof(buf)); + } + + buf_size += st_form[type_idx].blk_size; + } + } + } + } + + /* free allocated memory */ + sys_ad_free_mem(rx_stat); + + /* fill in type num */ + ptr = hqa_frame->data + 2; + buf = SERV_OS_HTONL(type_num); + sys_ad_move_mem(ptr, &buf, sizeof(buf)); + buf_size += sizeof(type_num); + update_hqa_frame(hqa_frame, (2 + buf_size), ret); + + return ret; + +error1: + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: memory allocation fail for rx stat.\n", + __func__)); + update_hqa_frame(hqa_frame, 2, ret); + return ret; + +error2: + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: invalid band index for non-dbdc mode.\n", + __func__)); + update_hqa_frame(hqa_frame, 2, ret); + return ret; +} + +static s_int32 hqa_get_capability( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_int8 *ptr = hqa_frame->data + 2; + struct test_capability capability; + u_int32 convert, i, *cast = NULL; + u_int32 item_num = sizeof(struct test_capability) / 4; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + /* get content */ + ret = mt_serv_get_capability(serv_test, &capability); + + /* fill header */ + capability.version = GET_CAPABILITY_VER; + capability.tag_num = GET_CAPABILITY_TAG_NUM; + capability.ph_cap.tag = GET_CAPABILITY_TAG_PHY; + capability.ph_cap.tag_len = GET_CAPABILITY_TAG_PHY_LEN; + capability.ext_cap.tag = GET_CAPABILITY_TAG_PHY_EXT; + capability.ext_cap.tag_len = GET_CAPABILITY_TAG_PHY_EXT_LEN; + + cast = (u_int32 *)&capability; + + /* convert and put data */ + for (i = 0; i < item_num; i++) { + convert = SERV_OS_HTONL(cast[i]); + sys_ad_move_mem(ptr, &convert, sizeof(convert)); + ptr += sizeof(convert); + } + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, (item_num*4) + 2, ret); + return ret; +} + +static s_int32 hqa_calibration_test_mode( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_configuration *test_config; + u_char *data = hqa_frame->data; + u_int32 mode, icap_len, resp_len = 2; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + get_param_and_shift_buf(TRUE, sizeof(mode), + &data, (u_char *)&mode); + get_param_and_shift_buf(TRUE, sizeof(icap_len), + &data, (u_char *)&icap_len); + + /* Set parameters */ + test_config = &serv_test->test_config[serv_test->ctrl_band_idx]; + + if (test_config) { + if (mode == fTEST_OPER_NORMAL_MODE) { + test_config->op_mode &= + ~(fTEST_FFT_ENABLE | fTEST_IN_RFTEST); + } else if (mode == fTEST_OPER_RFTEST_MODE) { + test_config->op_mode |= fTEST_IN_RFTEST; + } else if (mode == fTEST_OPER_ICAP_MODE) { + test_config->op_mode |= fTEST_IN_RFTEST; + } else { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: Mode = %d error!!!\n", __func__, mode)); + } + } else + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: Mode = test_config is null!!!\n", __func__)); + + ret = mt_serv_calibration_test_mode(serv_test, mode); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, resp_len, ret); + + return ret; +} + +static s_int32 hqa_do_cal_item( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char *data = hqa_frame->data; + u_int32 item = 0, band_idx = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + get_param_and_shift_buf(TRUE, sizeof(item), + &data, (u_char *)&item); + get_param_and_shift_buf(TRUE, sizeof(band_idx), + &data, (u_char *)&band_idx); + + serv_test->ctrl_band_idx = (u_char)band_idx; + + ret = mt_serv_do_cal_item(serv_test, item); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: item: %d, band_idx: %d\n", __func__, item, band_idx)); + + update_hqa_frame(hqa_frame, 2, ret); + + return ret; +} + +static s_int32 hqa_tmr_setting( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_tmr_info *tmr_info = &serv_test->test_tmr; + u_char *data = hqa_frame->data; + + get_param_and_shift_buf(TRUE, sizeof(tmr_info->setting), + &data, (u_char *)&tmr_info->setting); + get_param_and_shift_buf(TRUE, sizeof(tmr_info->version), + &data, (u_char *)&tmr_info->version); + get_param_and_shift_buf(TRUE, sizeof(tmr_info->through_hold), + &data, (u_char *)&tmr_info->through_hold); + get_param_and_shift_buf(TRUE, sizeof(tmr_info->iter), + &data, (u_char *)&tmr_info->iter); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: setting=%d, version=%d, through_hold=%d, iter=%d\n", + __func__, tmr_info->setting, tmr_info->version, + tmr_info->through_hold, tmr_info->iter)); + + ret = mt_serv_set_tmr(serv_test); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; +} + +static s_int32 hqa_get_chipid( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_int32 chip_id; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + ret = mt_serv_get_chipid(serv_test); + + chip_id = WINFO_GET_PARAM(serv_test, chip_id); + chip_id = SERV_OS_HTONL(chip_id); + + /* Update hqa_frame with response: status (2 bytes) */ + sys_ad_move_mem(hqa_frame->data + 2, &chip_id, sizeof(chip_id)); + update_hqa_frame(hqa_frame, 2 + sizeof(chip_id), ret); + + return ret; +} + +static s_int32 hqa_mps_set_seq_data( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_configuration *test_config = NULL; + struct test_mps_cb *mps_cb = NULL; + struct test_mps_setting *mps_setting = NULL; + u_char *data = hqa_frame->data; + u_int32 *param = NULL; + u_int32 band_idx, idx, value = 0; + u_int16 len; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + get_param_and_shift_buf(TRUE, sizeof(band_idx), + &data, (u_char *)&band_idx); + + len = hqa_frame->length / sizeof(u_int32) - 1; + if ((len > TEST_MPS_ITEM_LEN) || (len == 0)) { + ret = SERV_STATUS_AGENT_INVALID_LEN; + goto err; + } + + ret = sys_ad_alloc_mem((u_char **)¶m, sizeof(u_int32) * len); + if (ret) { + ret = SERV_STATUS_AGENT_INVALID_NULL_POINTER; + goto err; + } + + for (idx = 0; idx < len; idx++) { + get_param_and_shift_buf(TRUE, sizeof(u_int32), + &data, (u_char *)&value); + param[idx] = value; + } + + /* Set parameters */ + serv_test->ctrl_band_idx = (u_char)band_idx; + test_config = &serv_test->test_config[band_idx]; + mps_cb = &test_config->mps_cb; + + if (mps_cb->mps_setting == NULL) { + ret = sys_ad_alloc_mem((u_char **)&mps_cb->mps_setting, + sizeof(struct test_mps_setting) * (len+1)); + if (ret) { + sys_ad_free_mem(param); + ret = SERV_STATUS_AGENT_INVALID_NULL_POINTER; + goto err; + } + sys_ad_zero_mem(mps_cb->mps_setting, + sizeof(struct test_mps_setting) * (len+1)); + } + + mps_cb->mps_cnt = len; + mps_setting = mps_cb->mps_setting; + + for (idx = 0; idx < len; idx++) { + mps_setting[idx+1].tx_mode = (param[idx] & 0x0F000000) >> 24; + mps_setting[idx+1].tx_ant = (param[idx] & 0x00FFFF00) >> 8; + mps_setting[idx+1].mcs = (param[idx] & 0x000000FF); + } + sys_ad_free_mem(param); + + ret = mt_serv_mps_set_seq_data(serv_test); + +err: + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: band_idx=%d, len=%d, op_mode=0x%x, mps_cnt=%d\n", + __func__, band_idx, len, + test_config->op_mode, mps_cb->mps_cnt)); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; +} + +static s_int32 hqa_mps_set_payload_length( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_configuration *test_config = NULL; + struct test_mps_cb *mps_cb = NULL; + struct test_mps_setting *mps_setting = NULL; + u_char *data = hqa_frame->data; + u_int32 *param = NULL; + u_int32 band_idx, idx, value = 0; + u_int16 len; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + get_param_and_shift_buf(TRUE, sizeof(band_idx), + &data, (u_char *)&band_idx); + + len = hqa_frame->length / sizeof(u_int32) - 1; + if ((len > TEST_MPS_ITEM_LEN) || (len == 0)) { + ret = SERV_STATUS_AGENT_INVALID_LEN; + goto err; + } + + ret = sys_ad_alloc_mem((u_char **)¶m, sizeof(u_int32) * len); + if (ret) { + ret = SERV_STATUS_AGENT_INVALID_NULL_POINTER; + goto err; + } + + for (idx = 0; idx < len; idx++) { + get_param_and_shift_buf(TRUE, sizeof(u_int32), + &data, (u_char *)&value); + param[idx] = value; + } + + /* Set parameters */ + serv_test->ctrl_band_idx = (u_char)band_idx; + test_config = &serv_test->test_config[band_idx]; + mps_cb = &test_config->mps_cb; + + if (mps_cb->mps_setting == NULL) { + ret = sys_ad_alloc_mem((u_char **)&mps_cb->mps_setting, + sizeof(struct test_mps_setting) * (len+1)); + if (ret) { + sys_ad_free_mem(param); + ret = SERV_STATUS_AGENT_INVALID_NULL_POINTER; + goto err; + } + sys_ad_zero_mem(mps_cb->mps_setting, + sizeof(struct test_mps_setting) * (len+1)); + } + + mps_cb->mps_cnt = len; + mps_setting = mps_cb->mps_setting; + + for (idx = 0; idx < len; idx++) { + if (param[idx] > TEST_MAX_PKT_LEN) + param[idx] = TEST_MAX_PKT_LEN; + else if (param[idx] < TEST_MIN_PKT_LEN) + param[idx] = TEST_MIN_PKT_LEN; + + mps_setting[idx+1].pkt_len = param[idx]; + } + sys_ad_free_mem(param); + + ret = mt_serv_mps_set_payload_length(serv_test); + +err: + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: band_idx=%d, len=%d, op_mode=0x%x, mps_cnt=%d\n", + __func__, band_idx, len, + test_config->op_mode, mps_cb->mps_cnt)); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; +} + +static s_int32 hqa_mps_set_packet_count( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_configuration *test_config = NULL; + struct test_mps_cb *mps_cb = NULL; + struct test_mps_setting *mps_setting = NULL; + u_char *data = hqa_frame->data; + u_int32 *param = NULL; + u_int32 band_idx, idx, value = 0; + u_int16 len; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + get_param_and_shift_buf(TRUE, sizeof(band_idx), + &data, (u_char *)&band_idx); + + len = hqa_frame->length / sizeof(u_int32) - 1; + if ((len > TEST_MPS_ITEM_LEN) || (len == 0)) { + ret = SERV_STATUS_AGENT_INVALID_LEN; + goto err; + } + + ret = sys_ad_alloc_mem((u_char **)¶m, sizeof(u_int32) * len); + if (ret) { + ret = SERV_STATUS_AGENT_INVALID_NULL_POINTER; + goto err; + } + + for (idx = 0; idx < len; idx++) { + get_param_and_shift_buf(TRUE, sizeof(u_int32), + &data, (u_char *)&value); + param[idx] = value; + } + + /* Set parameters */ + serv_test->ctrl_band_idx = (u_char)band_idx; + test_config = &serv_test->test_config[band_idx]; + mps_cb = &test_config->mps_cb; + + if (mps_cb->mps_setting == NULL) { + ret = sys_ad_alloc_mem((u_char **)&mps_cb->mps_setting, + sizeof(struct test_mps_setting) * (len+1)); + if (ret) { + sys_ad_free_mem(param); + ret = SERV_STATUS_AGENT_INVALID_NULL_POINTER; + goto err; + } + sys_ad_zero_mem(mps_cb->mps_setting, + sizeof(struct test_mps_setting) * (len+1)); + } + + mps_cb->mps_cnt = len; + mps_setting = mps_cb->mps_setting; + + for (idx = 0; idx < len; idx++) + mps_setting[idx+1].pkt_cnt = param[idx]; + + sys_ad_free_mem(param); + + ret = mt_serv_mps_set_packet_count(serv_test); + +err: + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: band_idx=%d, len=%d, op_mode=0x%x, mps_cnt=%d\n", + __func__, band_idx, len, + test_config->op_mode, mps_cb->mps_cnt)); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; +} + +static s_int32 hqa_mps_set_power_gain( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_configuration *test_config = NULL; + struct test_mps_cb *mps_cb = NULL; + struct test_mps_setting *mps_setting = NULL; + u_char *data = hqa_frame->data; + u_int32 *param = NULL; + u_int32 band_idx, idx, value = 0; + u_int16 len; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + get_param_and_shift_buf(TRUE, sizeof(band_idx), + &data, (u_char *)&band_idx); + + len = hqa_frame->length / sizeof(u_int32) - 1; + if ((len > TEST_MPS_ITEM_LEN) || (len == 0)) { + ret = SERV_STATUS_AGENT_INVALID_LEN; + goto err; + } + + ret = sys_ad_alloc_mem((u_char **)¶m, sizeof(u_int32) * len); + if (ret) { + ret = SERV_STATUS_AGENT_INVALID_NULL_POINTER; + goto err; + } + + for (idx = 0; idx < len; idx++) { + get_param_and_shift_buf(TRUE, sizeof(u_int32), + &data, (u_char *)&value); + param[idx] = value; + } + + /* Set parameters */ + serv_test->ctrl_band_idx = (u_char)band_idx; + test_config = &serv_test->test_config[band_idx]; + mps_cb = &test_config->mps_cb; + + if (mps_cb->mps_setting == NULL) { + ret = sys_ad_alloc_mem((u_char **)&mps_cb->mps_setting, + sizeof(struct test_mps_setting) * (len+1)); + if (ret) { + sys_ad_free_mem(param); + ret = SERV_STATUS_AGENT_INVALID_NULL_POINTER; + goto err; + } + sys_ad_zero_mem(mps_cb->mps_setting, + sizeof(struct test_mps_setting) * (len+1)); + } + + mps_cb->mps_cnt = len; + mps_setting = mps_cb->mps_setting; + + for (idx = 0; idx < len; idx++) + mps_setting[idx+1].pwr = param[idx]; + + sys_ad_free_mem(param); + + ret = mt_serv_mps_set_power_gain(serv_test); + +err: + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: band_idx=%d, len=%d, op_mode=0x%x, mps_cnt=%d\n", + __func__, band_idx, len, + test_config->op_mode, mps_cb->mps_cnt)); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; +} + +static s_int32 hqa_mps_start( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char *data = hqa_frame->data; + u_int32 band_idx; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + get_param_and_shift_buf(TRUE, sizeof(band_idx), + &data, (u_char *)&band_idx); + + /* Set parameters */ + SERV_SET_PARAM(serv_test, ctrl_band_idx, (u_char)band_idx); + + ret = mt_serv_mps_operation(serv_test, SERV_TEST_MPS_START_TX); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; +} + +static s_int32 hqa_mps_stop( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char *data = hqa_frame->data; + u_int32 band_idx; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + get_param_and_shift_buf(TRUE, sizeof(band_idx), + &data, (u_char *)&band_idx); + + /* Set parameters */ + SERV_SET_PARAM(serv_test, ctrl_band_idx, (u_char)band_idx); + + ret = mt_serv_mps_operation(serv_test, SERV_TEST_MPS_STOP_TX); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; +} + +static s_int32 hqa_check_efuse_mode_type( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_int32 e2p_cur_mode = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + e2p_cur_mode = (u_int32)WINFO_GET_PARAM(serv_test, e2p_cur_mode); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: e2p_cur_mode=0x%x\n", __func__, e2p_cur_mode)); + + e2p_cur_mode = SERV_OS_HTONL(e2p_cur_mode); + + /* Update hqa_frame with response: status (2 bytes) */ + sys_ad_move_mem(hqa_frame->data + 2, &e2p_cur_mode, + sizeof(e2p_cur_mode)); + update_hqa_frame(hqa_frame, 2 + sizeof(e2p_cur_mode), ret); + + return ret; +} + +static s_int32 hqa_check_efuse_nativemode_type( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_int32 e2p_access_mode = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + e2p_access_mode = (u_int32)WINFO_GET_PARAM(serv_test, e2p_access_mode); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: e2p_access_mode=0x%x\n", __func__, e2p_access_mode)); + + e2p_access_mode = SERV_OS_HTONL(e2p_access_mode); + + /* Update hqa_frame with response: status (2 bytes) */ + sys_ad_move_mem(hqa_frame->data + 2, &e2p_access_mode, + sizeof(e2p_access_mode)); + update_hqa_frame(hqa_frame, 2 + sizeof(e2p_access_mode), ret); + + return ret; +} + +static s_int32 hqa_set_band_mode( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_band_state *band_state; + u_char *data = hqa_frame->data; + u_int32 band_mode = 0, band_type = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + get_param_and_shift_buf(TRUE, sizeof(band_mode), + &data, (u_char *)&band_mode); + get_param_and_shift_buf(TRUE, sizeof(band_type), + &data, (u_char *)&band_type); + + /* Set parameters */ + band_state = SERV_GET_PADDR(serv_test, test_bstat); + BSTATE_SET_PARAM(serv_test, band_mode, band_mode); + BSTATE_SET_PARAM(serv_test, band_type, band_type); + + ret = mt_serv_set_band_mode(serv_test); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: band_mode=%u, band_type=%u\n", + __func__, band_mode, band_type)); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; +} + +static s_int32 hqa_get_band_mode( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_band_state *band_state; + u_char *data = hqa_frame->data; + u_int32 band_type = 0, band_idx = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + get_param_and_shift_buf(TRUE, sizeof(band_idx), + &data, (u_char *)&band_idx); + + /* Set parameters */ + band_state = SERV_GET_PADDR(serv_test, test_bstat); + serv_test->ctrl_band_idx = (u_char)band_idx; + ret = mt_serv_get_band_mode(serv_test); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: band_type=%u\n", + __func__, band_type)); + + band_type = SERV_OS_HTONL(band_state->band_type); + + /* Update hqa_frame with response: status (2 bytes) */ + sys_ad_move_mem(hqa_frame->data + 2, &band_type, sizeof(band_type)); + update_hqa_frame(hqa_frame, 2 + sizeof(band_type), ret); + + return ret; +} + +static s_int32 hqa_rdd_start( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char *data = hqa_frame->data; + u_int32 rdd_num = 0; + u_int32 rdd_sel = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, ("%s\n", __func__)); + + get_param_and_shift_buf(TRUE, sizeof(rdd_num), + &data, (u_char *)&rdd_num); + get_param_and_shift_buf(TRUE, sizeof(rdd_sel), + &data, (u_char *)&rdd_sel); + + ret = mt_serv_set_rdd_on_off(serv_test, rdd_num, rdd_sel, TRUE); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: rdd_num: %d, rdd_sel: %d\n", + __func__, rdd_num, rdd_sel)); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; +} + +static s_int32 hqa_rdd_stop( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char *data = hqa_frame->data; + u_int32 rdd_num = 0; + u_int32 rdd_sel = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + get_param_and_shift_buf(TRUE, sizeof(rdd_num), + &data, (u_char *)&rdd_num); + get_param_and_shift_buf(TRUE, sizeof(rdd_sel), + &data, (u_char *)&rdd_sel); + + ret = mt_serv_set_rdd_on_off(serv_test, rdd_num, rdd_sel, FALSE); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: rdd_num: %d, rdd_sel: %d\n", + __func__, rdd_num, rdd_sel)); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; +} + +static s_int32 hqa_log_on_off( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char *data = hqa_frame->data; + u_int32 band_idx = 0, log_type = 0, log_ctrl = 0, log_size = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + get_param_and_shift_buf(TRUE, sizeof(band_idx), + &data, (u_char *)&band_idx); + get_param_and_shift_buf(TRUE, sizeof(log_type), + &data, (u_char *)&log_type); + get_param_and_shift_buf(TRUE, sizeof(log_ctrl), + &data, (u_char *)&log_ctrl); + get_param_and_shift_buf(TRUE, sizeof(log_size), + &data, (u_char *)&log_size); + + /* Set parameters */ + SERV_SET_PARAM(serv_test, ctrl_band_idx, (u_char)band_idx); + + ret = mt_serv_log_on_off(serv_test, log_type, log_ctrl, log_size); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; +} + +static s_int32 hqa_mps_set_nss( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_configuration *test_config = NULL; + struct test_mps_cb *mps_cb = NULL; + struct test_mps_setting *mps_setting = NULL; + u_char *data = hqa_frame->data; + u_int32 *param = NULL; + u_int32 band_idx, idx, value = 0; + u_int16 len; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + get_param_and_shift_buf(TRUE, sizeof(band_idx), + &data, (u_char *) &band_idx); + + len = hqa_frame->length / sizeof(u_int32) - 1; + if ((len > TEST_MPS_ITEM_LEN) || (len == 0)) { + ret = SERV_STATUS_AGENT_INVALID_LEN; + goto err; + } + + ret = sys_ad_alloc_mem((u_char **)¶m, sizeof(u_int32) * len); + if (ret) { + ret = SERV_STATUS_AGENT_INVALID_NULL_POINTER; + goto err; + } + + for (idx = 0; idx < len; idx++) { + get_param_and_shift_buf(TRUE, sizeof(u_int32), + &data, (u_char *) &value); + param[idx] = value; + } + + /* Set parameters */ + serv_test->ctrl_band_idx = (u_char)band_idx; + test_config = &serv_test->test_config[band_idx]; + mps_cb = &test_config->mps_cb; + + if (mps_cb->mps_setting == NULL) { + ret = sys_ad_alloc_mem((u_char **)&mps_cb->mps_setting, + sizeof(struct test_mps_setting) * (len+1)); + if (ret) { + sys_ad_free_mem(param); + ret = SERV_STATUS_AGENT_INVALID_NULL_POINTER; + goto err; + } + sys_ad_zero_mem(mps_cb->mps_setting, + sizeof(struct test_mps_setting) * (len+1)); + } + + mps_cb->mps_cnt = len; + mps_setting = mps_cb->mps_setting; + + for (idx = 0; idx < len; idx++) + mps_setting[idx+1].nss = param[idx]; + + sys_ad_free_mem(param); + + ret = mt_serv_mps_set_nss(serv_test); + +err: + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: band_idx=%d, len=%d, op_mode=0x%x, mps_cnt=%d\n", + __func__, band_idx, len, + test_config->op_mode, mps_cb->mps_cnt)); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; +} + +static s_int32 hqa_mps_set_per_packet_bw( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_configuration *test_config = NULL; + struct test_mps_cb *mps_cb = NULL; + struct test_mps_setting *mps_setting = NULL; + u_char *data = hqa_frame->data; + u_int32 *param = NULL; + u_int32 band_idx, idx, value = 0; + u_int16 len; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + get_param_and_shift_buf(TRUE, sizeof(band_idx), + &data, (u_char *)&band_idx); + + len = hqa_frame->length / sizeof(u_int32) - 1; + if ((len > TEST_MPS_ITEM_LEN) || (len == 0)) { + ret = SERV_STATUS_AGENT_INVALID_LEN; + goto err; + } + + ret = sys_ad_alloc_mem((u_char **)¶m, sizeof(u_int32) * len); + if (ret) { + ret = SERV_STATUS_AGENT_INVALID_NULL_POINTER; + goto err; + } + + for (idx = 0; idx < len; idx++) { + get_param_and_shift_buf(TRUE, sizeof(u_int32), + &data, (u_char *) &value); + + switch (value) { + case 0: + value = TEST_BW_20; + break; + + case 1: + value = TEST_BW_40; + break; + + case 2: + value = TEST_BW_80; + break; + + case 3: + value = TEST_BW_10; + break; + + case 4: + value = TEST_BW_5; + break; + + case 5: + value = TEST_BW_160C; + break; + + case 6: + value = TEST_BW_160NC; + break; + + default: + value = TEST_BW_20; + break; + } + + param[idx] = value; + } + + /* Set parameters */ + serv_test->ctrl_band_idx = (u_char)band_idx; + test_config = &serv_test->test_config[band_idx]; + mps_cb = &test_config->mps_cb; + + if (mps_cb->mps_setting == NULL) { + ret = sys_ad_alloc_mem((u_char **)&mps_cb->mps_setting, + sizeof(struct test_mps_setting) * (len+1)); + if (ret) { + sys_ad_free_mem(param); + ret = SERV_STATUS_AGENT_INVALID_NULL_POINTER; + goto err; + } + sys_ad_zero_mem(mps_cb->mps_setting, + sizeof(struct test_mps_setting) * (len+1)); + } + + mps_cb->mps_cnt = len; + mps_setting = mps_cb->mps_setting; + + for (idx = 0; idx < len; idx++) + mps_setting[idx+1].pkt_bw = param[idx]; + + sys_ad_free_mem(param); + + ret = mt_serv_mps_set_per_packet_bw(serv_test); + +err: + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: band_idx=%d, len=%d, op_mode=0x%x, mps_cnt=%d\n", + __func__, band_idx, len, + test_config->op_mode, mps_cb->mps_cnt)); + + /* Update hqa_frame with response: status (2 bytes) */ + update_hqa_frame(hqa_frame, 2, ret); + + return ret; +} + +static s_int32 hqa_icap_ctrl( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + s_int32 icap_stat = 0; + u_char *data = hqa_frame->data; + u_int32 wf_num = 0, iq_type = 0; + u_int32 control = 0, resp_len = 2; + u_int32 value = 0, i = 0; + u_long max_data_len = 0; + u_char src_addr[SERV_MAC_ADDR_LEN]; + s_int32 *icap_data = NULL; + s_int32 *icap_data_cnt = NULL; + struct hqa_rbist_cap_start icap_info; + + get_param_and_shift_buf(TRUE, sizeof(control), + &data, (u_char *)&control); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: control: %d\n", __func__, control)); + + switch (control) { + case 1: + /* clear memory */ + sys_ad_zero_mem(&icap_info, sizeof(icap_info)); + + get_param_and_shift_buf(TRUE, sizeof(icap_info.trig), + &data, (u_char *)&(icap_info.trig)); + + get_param_and_shift_buf(TRUE, sizeof(icap_info.ring_cap_en), + &data, (u_char *)&(icap_info.ring_cap_en)); + + get_param_and_shift_buf(TRUE, sizeof(icap_info.trig_event), + &data, (u_char *)&(icap_info.trig_event)); + + get_param_and_shift_buf(TRUE, sizeof(icap_info.cap_node), + &data, (u_char *)&(icap_info.cap_node)); + + get_param_and_shift_buf(TRUE, sizeof(icap_info.cap_len), + &data, (u_char *)&(icap_info.cap_len)); + + get_param_and_shift_buf(TRUE, sizeof(icap_info.cap_stop_cycle), + &data, (u_char *)&(icap_info.cap_stop_cycle)); + + get_param_and_shift_buf(TRUE, sizeof(icap_info.bw), + &data, (u_char *)&(icap_info.bw)); + + get_param_and_shift_buf(TRUE, sizeof(icap_info.mac_trig_event), + &data, (u_char *)&(icap_info.mac_trig_event)); + + get_param_and_shift_buf(FALSE, SERV_MAC_ADDR_LEN, + &data, (u_char *)src_addr); + + get_param_and_shift_buf(TRUE, sizeof(icap_info.band_idx), + &data, (u_char *)&(icap_info.band_idx)); + + get_param_and_shift_buf(TRUE, sizeof(icap_info.phy_idx), + &data, (u_char *)&(icap_info.phy_idx)); + + get_param_and_shift_buf(TRUE, sizeof(icap_info.cap_src), + &data, (u_char *)&(icap_info.cap_src)); + + /* source address lsb */ + for (i = 0; i < 4; i++) + icap_info.src_addr_lsb |= ((src_addr[i]) << (i << 3)); + + /* source address msb */ + for (i = 0; i < 2; i++) + icap_info.src_addr_msb |= ((src_addr[i+4]) << (i << 3)); + icap_info.src_addr_msb |= ((0x1) << 16); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: trig = 0x%08x, ring_cap_en = 0x%08x\n" + , __func__, icap_info.trig, icap_info.ring_cap_en)); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: trig_event = 0x%08x, cap_node = 0x%08x\n" + , __func__, icap_info.trig_event, icap_info.cap_node)); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: cap_len = 0x%08x, cap_stop_cycle = 0x%08x\n" + , __func__, icap_info.cap_len, icap_info.cap_stop_cycle)); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: bw = 0x%08x, mac_trig_event = 0x%08x\n" + , __func__, icap_info.bw, icap_info.mac_trig_event)); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: src_addr_msb = 0x%08x, src_addr_lsb = 0x%08x\n" + , __func__, icap_info.src_addr_msb, icap_info.src_addr_lsb)); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: band_idx = 0x%08x, phy_idx = 0x%08x\n" + , __func__, icap_info.band_idx, icap_info.phy_idx)); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: cap_src = 0x%08x\n", __func__, icap_info.cap_src)); + + ret = mt_serv_set_icap_start(serv_test, &icap_info); + if (ret) { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s : mt_serv_set_icap_start is failed!!\n" + , __func__)); + goto error1; + } + break; + + case 2: + ret = mt_serv_get_icap_status(serv_test, &icap_stat); + if (ret) { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s : mt_serv_get_icap_status is failed!!\n" + , __func__)); + goto error1; + } else { + ret = icap_stat; + update_hqa_frame(hqa_frame, resp_len, ret); + return SERV_STATUS_SUCCESS; + } + break; + + case 3: + get_param_and_shift_buf(TRUE, sizeof(wf_num), + &data, (u_char *)&(wf_num)); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: wf_num: %d\n", __func__, wf_num)); + + get_param_and_shift_buf(TRUE, sizeof(iq_type), + &data, (u_char *)&(iq_type)); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: iq_type: %d\n", __func__, iq_type)); + + ret = sys_ad_alloc_mem((u_char **)&icap_data_cnt + , sizeof(s_int32)); + if (ret) { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s : Not enough memory for dynamic allocating!!\n" + , __func__)); + goto error1; + } + sys_ad_zero_mem(icap_data_cnt, sizeof(s_int32)); + + ret = mt_serv_get_icap_max_data_len(serv_test, &max_data_len); + if (max_data_len > 0) { + if (ret) { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s : max_data_len is failed!!\n" + , __func__)); + goto error1; + } + + ret = sys_ad_alloc_mem( + (u_char **)&icap_data, max_data_len); + if (ret || (icap_data == NULL)) { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s : Not enough memory!!\n" + , __func__)); + goto error1; + } + sys_ad_zero_mem(icap_data, max_data_len); + + ret = mt_serv_get_icap_data(serv_test, + icap_data_cnt, icap_data, + wf_num, iq_type); + if (ret) { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s : mt_serv_get_icap_data not supported!!\n" + , __func__)); + goto error1; + } + + value = SERV_OS_HTONL(control); + sys_ad_move_mem(hqa_frame->data + resp_len, + &value, sizeof(value)); + resp_len += sizeof(value); + value = SERV_OS_HTONL(wf_num); + sys_ad_move_mem(hqa_frame->data + resp_len, + &value, sizeof(value)); + resp_len += sizeof(value); + value = SERV_OS_HTONL(iq_type); + sys_ad_move_mem(hqa_frame->data + resp_len, + &value, sizeof(value)); + resp_len += sizeof(value); + value = SERV_OS_HTONL(*icap_data_cnt); + sys_ad_move_mem(hqa_frame->data + resp_len, + &value, sizeof(value)); + resp_len += sizeof(value); + + for (i = 0; i < *icap_data_cnt; i++) { + value = SERV_OS_HTONL(icap_data[i]); + sys_ad_move_mem(hqa_frame->data + resp_len, + &value, sizeof(value)); + resp_len += sizeof(value); + } + } + break; + + default: + break; + } + +error1: + if (ret) + ret = SERV_STATUS_AGENT_NOT_SUPPORTED; + + update_hqa_frame(hqa_frame, resp_len, ret); + + if (icap_data_cnt) + sys_ad_free_mem(icap_data_cnt); + + if (icap_data) + sys_ad_free_mem(icap_data); + + return ret; +} + +static s_int32 hqa_get_dump_recal( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_int32 resp_len = 6; + u_char *data = hqa_frame->data; + u_int32 band_idx = 0; + u_int32 recal_cnt = 0, recal_dw_num = 0; + u_int32 *content = NULL, *OriAddr = NULL; + u_int32 value = 0, dw_cnt = 0, i = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + get_param_and_shift_buf(TRUE, sizeof(band_idx), + &data, (u_char *)&band_idx); + + serv_test->ctrl_band_idx = (u_char)band_idx; + + ret = mt_serv_get_recal_cnt(serv_test, + &recal_cnt, &recal_dw_num); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: band_idx: %d, rxv_cnt: %d, rxv_dw_num: %d\n", + __func__, band_idx, recal_cnt, recal_dw_num)); + + dw_cnt = recal_cnt * recal_dw_num; + + ret = sys_ad_alloc_mem((u_char **)&content, + sizeof(*content) * dw_cnt); + if (ret != SERV_STATUS_SUCCESS) + goto error1; + + OriAddr = content; + + ret = mt_serv_get_recal_content(serv_test, content); + + /* Update hqa_frame with response: status (2 bytes) */ + value = SERV_OS_HTONL(recal_cnt); + sys_ad_move_mem(hqa_frame->data + 2, + &value, sizeof(value)); + + for (i = 0; i < dw_cnt; i++, content++) { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: content[%d]: 0x%x\n", __func__, i, *content)); + + value = SERV_OS_HTONL(*content); + sys_ad_move_mem(hqa_frame->data + resp_len, + &value, sizeof(value)); + + resp_len += sizeof(value); + } + + /* Free memory */ + sys_ad_free_mem(OriAddr); + + update_hqa_frame(hqa_frame, resp_len, ret); + + return ret; + +error1: + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: dynamic memory allocate fail!!\n", __func__)); + if (content) + sys_ad_free_mem(content); + /* TODO: respond to application for error handle */ + update_hqa_frame(hqa_frame, resp_len, ret); + + return ret; +} + +static s_int32 hqa_get_dump_rxv( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_int32 resp_len = 2; + u_char *data = hqa_frame->data; + u_int32 band_idx = 0; + u_int32 rxv_cnt = 0, rxv_dw_num = 0; + u_int32 *content = NULL, *OriAddr = NULL; + u_int32 value = 0, dw_cnt = 0, i = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + get_param_and_shift_buf(TRUE, sizeof(band_idx), + &data, (u_char *)&band_idx); + + serv_test->ctrl_band_idx = (u_char)band_idx; + + ret = mt_serv_get_rxv_cnt(serv_test, &rxv_cnt, &rxv_dw_num); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: band_idx: %d, rxv_cnt: %d, rxv_dw_num: %d\n", + __func__, band_idx, rxv_cnt, rxv_dw_num)); + + dw_cnt = rxv_cnt * rxv_dw_num; + ret = sys_ad_alloc_mem((u_char **)&content, + sizeof(*content) * dw_cnt); + if (ret != SERV_STATUS_SUCCESS) + goto error1; + + OriAddr = content; + + ret = mt_serv_get_rxv_content(serv_test, dw_cnt, content); + + /* Update hqa_frame with response: Count (2 bytes) */ + value = SERV_OS_HTONL(rxv_cnt); + sys_ad_move_mem(hqa_frame->data + resp_len, + &value, sizeof(value)); + + resp_len += sizeof(value); + + for (i = 0; i < dw_cnt; i += 4, content++) { + value = SERV_OS_HTONL(*content); + sys_ad_move_mem(hqa_frame->data + resp_len, + &value, sizeof(value)); + resp_len += sizeof(value); + } + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: resp_len = %d\n", __func__, resp_len)); + + /* Free memory */ + sys_ad_free_mem(OriAddr); + + update_hqa_frame(hqa_frame, resp_len, ret); + + return ret; + +error1: + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: dynamic memory allocate fail!!\n", __func__)); + if (content) + sys_ad_free_mem(content); + /* TODO: respond to application for error handle */ + update_hqa_frame(hqa_frame, resp_len, ret); + + return ret; +} + +static s_int32 hqa_get_dump_rdd( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_int32 resp_len = 2; + u_char *data = hqa_frame->data; + u_int32 band_idx = 0; + u_int32 rdd_cnt = 0, rdd_dw_num = 0; + u_int32 *content = NULL, *OriAddr = NULL; + u_int32 value = 0, i = 0, total_cnt = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + get_param_and_shift_buf(TRUE, sizeof(band_idx), + &data, (u_char *)&band_idx); + + serv_test->ctrl_band_idx = (u_char)band_idx; + + ret = mt_serv_get_rdd_cnt(serv_test, &rdd_cnt, &rdd_dw_num); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: band_idx: %d, pulse number: %d, rdd buffer size: %d\n", + __func__, band_idx, rdd_cnt, rdd_dw_num)); + + ret = sys_ad_alloc_mem((u_char **)&content, + sizeof(*content) * rdd_dw_num); + if (ret != SERV_STATUS_SUCCESS) + goto error1; + + OriAddr = content; + + ret = mt_serv_get_rdd_content(serv_test, content, &total_cnt); + + if (total_cnt > 0) { + /* Update hqa_frame with response: status (2 bytes) */ + /* Response format: + * cmd type + cmd ID + length + Sequence + + * data: + * status (2 bytes) + + * [count (4 bytes)] + value1 (4 bytes) + value2 (4 bytes) + */ + /* Count = Total number of 4 bytes RDD values divided by 2 */ + value = SERV_OS_HTONL(total_cnt/2); + sys_ad_move_mem(hqa_frame->data + resp_len, + &value, sizeof(value)); + resp_len += sizeof(value); + + for (i = 0; i < total_cnt; i++, content++) { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: content[%d]: 0x%08x\n", + __func__, i, *content)); + + value = SERV_OS_HTONL(*content); + sys_ad_move_mem(hqa_frame->data + resp_len, + &value, sizeof(value)); + resp_len += sizeof(value); + } + + } else { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: total_cnt %d\n", __func__, total_cnt)); + sys_ad_move_mem(hqa_frame->data + resp_len, + &total_cnt, sizeof(total_cnt)); + resp_len += sizeof(total_cnt); + } + + /* Free memory */ + sys_ad_free_mem(OriAddr); + + update_hqa_frame(hqa_frame, resp_len, ret); + + return ret; + +error1: + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: dynamic memory allocate fail!!\n", __func__)); + if (content) + sys_ad_free_mem(content); + /* TODO: respond to application for error handle */ + update_hqa_frame(hqa_frame, resp_len, ret); + + return ret; +} + +static s_int32 hqa_get_hetb_info( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_int32 resp_len = 2; + u_char band_idx = serv_test->ctrl_band_idx; + u_int32 afactor = 0, ldpc_str_sym = 0, pe_disamb = 0; + u_int32 tx_pe = 0, l_sig_len = 0, value = 0; + u_int8 dmnt_ru_idx = 0; + struct test_ru_info *ru_info = NULL; + + dmnt_ru_idx = CONFIG_GET_PARAM(serv_test, dmnt_ru_idx, band_idx); + ru_info = CONFIG_GET_PADDR(serv_test, + ru_info_list[dmnt_ru_idx], + band_idx); + afactor = ru_info->afactor_init; + ldpc_str_sym = ru_info->ldpc_extr_sym; + pe_disamb = ru_info->pe_disamb; + tx_pe = ru_info->t_pe; + l_sig_len = ru_info->l_len; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: band_idx:0x%x, dmnt_ru_idx:0x%x afactor:0x%x\n", + __func__, band_idx, dmnt_ru_idx, afactor)); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("ldpc_str_sym:0x%x, pe_disamb:0x%x\n", + ldpc_str_sym, pe_disamb)); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("tx_pe:0x%x,l_sig_len:0x%x\n", + tx_pe, l_sig_len)); + + /* The response array should be a-factor, + * ldpc extra symbol, + * PE disambiguilty, + * TX PE, + * L-SIG length + */ + value = SERV_OS_HTONL(afactor); + sys_ad_move_mem(hqa_frame->data + 2, &value, sizeof(value)); + value = SERV_OS_HTONL(ldpc_str_sym); + sys_ad_move_mem(hqa_frame->data + 2 + sizeof(value), &value, + sizeof(value)); + value = SERV_OS_HTONL(pe_disamb); + sys_ad_move_mem(hqa_frame->data + 2 + sizeof(value)*2, + &value, sizeof(value)); + value = SERV_OS_HTONL(tx_pe); + sys_ad_move_mem(hqa_frame->data + 2 + sizeof(value)*3, &value, + sizeof(value)); + value = SERV_OS_HTONL(l_sig_len); + sys_ad_move_mem(hqa_frame->data + 2 + sizeof(value)*4, &value, + sizeof(value)); + resp_len += 5*sizeof(u_int32); + + update_hqa_frame(hqa_frame, resp_len, ret); + + return ret; +} + +static s_int32 hqa_translate_ru_allocation( + u_int32 user_ru_allocation, + u_int32 *allocation) +{ + u_int8 i = 0; + + *allocation = 0; + for (i = 0 ; i < sizeof(u_int32)*2 ; i++) { + *allocation |= ((user_ru_allocation & 0x1) << i); + user_ru_allocation >>= 4; + } + + return SERV_STATUS_SUCCESS; +} + +static s_int32 hqa_set_ru_info( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_int32 resp_len = 2; + u_int32 band_idx = 0; + u_int32 len = 0, seg_sta_cnt[2] = {0}, sta_seq = 0, value = 0; + u_char param_cnt = 0, segment_idx = 0, param_loop = 0; + u_char *data = hqa_frame->data; + u_int32 mpdu_length = 0; + struct test_ru_allocatoin *ru_allocation = NULL; + struct test_ru_info *ru_info = NULL; + + len = hqa_frame->length; + + get_param_and_shift_buf(TRUE, + sizeof(u_int32), + &data, + (u_char *)&band_idx); + get_param_and_shift_buf(TRUE, + sizeof(u_int32), + &data, + (u_char *)&seg_sta_cnt[0]); + get_param_and_shift_buf(TRUE, + sizeof(u_int32), + &data, + (u_char *)&seg_sta_cnt[1]); + len -= sizeof(u_int32)*3; /* array length */ + + if (seg_sta_cnt[0]+seg_sta_cnt[1] == 0) + return SERV_STATUS_AGENT_INVALID_LEN; + + len /= (seg_sta_cnt[0]+seg_sta_cnt[1]); /* per ru length */ + param_cnt = len/sizeof(u_int32); /* param count */ + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: Band:%d [ru_segment 0]:%d, [ru_segment 1]:%d\n", + __func__, band_idx, seg_sta_cnt[0], seg_sta_cnt[1])); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("\t\tparameters count:%d\n", param_cnt)); + + mpdu_length = CONFIG_GET_PARAM(serv_test, tx_len, band_idx); + ru_allocation = CONFIG_GET_PADDR(serv_test, ru_alloc, band_idx); + ru_info = CONFIG_GET_PADDR(serv_test, ru_info_list[0], band_idx); + sys_ad_zero_mem(ru_info, sizeof(struct test_ru_info)*MAX_MULTI_TX_STA); + sys_ad_set_mem(ru_allocation, sizeof(*ru_allocation), 0xff); + + /* for maximum bw 80+80/160, 2 segments only */ + for (sta_seq = 0; + sta_seq < seg_sta_cnt[0]+seg_sta_cnt[1]; + sta_seq++) { + param_loop = param_cnt; + + if (sta_seq < seg_sta_cnt[0]) + segment_idx = 0; + else + segment_idx = 1; + + ru_info[sta_seq].valid = TRUE; + /* ru caterogy */ + get_param_and_shift_buf(TRUE, + sizeof(u_int32), + &data, + (u_char *)&value); + param_loop--; + /* ru allocation */ + get_param_and_shift_buf(TRUE, + sizeof(u_int32), + &data, + (u_char *)&value); + param_loop--; + hqa_translate_ru_allocation(value, + &ru_info[sta_seq].allocation); + /* aid */ + get_param_and_shift_buf(TRUE, + sizeof(u_int32), + &data, + (u_char *)&value); + param_loop--; + ru_info[sta_seq].aid = value; + get_param_and_shift_buf(TRUE, + sizeof(u_int32), + &data, + (u_char *)&value); + param_loop--; + ru_info[sta_seq].ru_index = (value << 1) | segment_idx; + get_param_and_shift_buf(TRUE, + sizeof(u_int32), + &data, + (u_char *)&value); + param_loop--; + ru_info[sta_seq].rate = value; + get_param_and_shift_buf(TRUE, + sizeof(u_int32), + &data, + (u_char *)&value); + param_loop--; + ru_info[sta_seq].ldpc = value; + get_param_and_shift_buf(TRUE, + sizeof(u_int32), + &data, + (u_char *)&value); + param_loop--; + ru_info[sta_seq].nss = value; + if (ru_info[sta_seq].nss == 0) + ru_info[sta_seq].nss = 1; + + get_param_and_shift_buf(TRUE, + sizeof(u_int32), + &data, + (u_char *)&value); + param_loop--; + ru_info[sta_seq].start_sp_st = value-1; + get_param_and_shift_buf(TRUE, + sizeof(u_int32), + &data, + (u_char *)&value); + param_loop--; + if (value > 24) + ru_info[sta_seq].mpdu_length = value; + else + ru_info[sta_seq].mpdu_length = mpdu_length; + + if (param_loop) { + get_param_and_shift_buf(TRUE, + sizeof(u_int32), + &data, + (u_char *)&value); + param_loop--; + ru_info[sta_seq].alpha = value; + } else + ru_info[sta_seq].alpha = 1; /* default value */ + + if (param_loop) { + get_param_and_shift_buf(TRUE, + sizeof(u_int32), + &data, + (u_char *)&value); + param_loop--; + ru_info[sta_seq].ru_mu_nss = value; + } else + ru_info[sta_seq].ru_mu_nss = 1; /* default value */ + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: ru_segment[%d][0x%x]: ru_idx:%d\n", + __func__, segment_idx, + ru_info[sta_seq].allocation, + ru_info[sta_seq].ru_index >> 1)); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("\t\t\t\trate:%x, ldpc:%d\n", + ru_info[sta_seq].rate, + ru_info[sta_seq].ldpc)); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("\t\t\t\tnss:%d, mimo nss:%d\n", + ru_info[sta_seq].nss, + ru_info[sta_seq].ru_mu_nss)); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("\t\t\t\t start spatial stream:%d,\n", + ru_info[sta_seq].start_sp_st)); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("\t\t\t\tmpdu length=%d, alpha:%d\n", + ru_info[sta_seq].mpdu_length, + ru_info[sta_seq].alpha)); + } + + update_hqa_frame(hqa_frame, resp_len, ret); + + return ret; +} + +static struct hqa_cmd_entry CMD_SET5[] = { + /* cmd id start from 0x1500 */ + {0x0, hqa_get_fw_info}, + {0x1, legacy_function}, + {0x2, hqa_set_stbc}, + {0x3, hqa_set_short_gi}, + {0x4, hqa_set_dpd}, + {0x5, hqa_set_tssi_onoff}, + {0x6, hqa_get_rx_statistics_leg}, + {0x7, legacy_function}, + {0x8, legacy_function}, + {0x9, hqa_calibration_test_mode}, + {0xa, hqa_do_cal_item}, + {0xf, hqa_tmr_setting}, + {0x10, legacy_function}, + {0x11, todo_function}, + {0x12, legacy_function}, + {0x13, legacy_function}, + {0x14, hqa_get_chipid}, + {0x15, hqa_mps_set_seq_data}, + {0x16, hqa_mps_set_payload_length}, + {0x17, hqa_mps_set_packet_count}, + {0x18, hqa_mps_set_power_gain}, + {0x19, hqa_mps_start}, + {0x1a, hqa_mps_stop}, + {0x1c, hqa_get_rx_statistics_all}, + {0x1d, hqa_get_capability}, + {0x21, legacy_function}, + {0x22, hqa_check_efuse_mode_type}, + {0x23, hqa_check_efuse_nativemode_type}, + {0x24, legacy_function}, + {0x25, legacy_function}, + {0x26, legacy_function}, + {0x27, legacy_function}, + {0x28, legacy_function}, + {0x29, legacy_function}, + {0x2c, hqa_set_band_mode}, + {0x2d, hqa_get_band_mode}, + {0x2e, hqa_rdd_start}, + {0x2f, hqa_rdd_stop}, + {0x31, legacy_function}, + {0x32, legacy_function}, + {0x33, hqa_log_on_off}, + {0x34, legacy_function}, + {0x35, legacy_function}, + {0x36, hqa_mps_set_nss}, + {0x37, hqa_mps_set_per_packet_bw}, + {0x80, hqa_icap_ctrl}, + {0x81, hqa_get_dump_recal}, + {0x82, hqa_get_dump_rxv}, + {0x83, hqa_get_dump_rdd}, + {0x91, hqa_get_hetb_info}, + {0x94, hqa_set_ru_info} +}; + +static s_int32 hqa_set_channel_ext( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct hqa_set_ch param; + u_char *data = hqa_frame->data; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + sys_ad_zero_mem(¶m, sizeof(param)); + + get_param_and_shift_buf(TRUE, sizeof(param.ext_id), + &data, (u_char *)¶m.ext_id); + get_param_and_shift_buf(TRUE, sizeof(param.num_param), + &data, (u_char *)¶m.num_param); + get_param_and_shift_buf(TRUE, sizeof(param.band_idx), + &data, (u_char *)¶m.band_idx); + get_param_and_shift_buf(TRUE, sizeof(param.central_ch0), + &data, (u_char *)¶m.central_ch0); + get_param_and_shift_buf(TRUE, sizeof(param.central_ch1), + &data, (u_char *)¶m.central_ch1); + get_param_and_shift_buf(TRUE, sizeof(param.sys_bw), + &data, (u_char *)¶m.sys_bw); + get_param_and_shift_buf(TRUE, sizeof(param.perpkt_bw), + &data, (u_char *)¶m.perpkt_bw); + get_param_and_shift_buf(TRUE, sizeof(param.pri_sel), + &data, (u_char *)¶m.pri_sel); + get_param_and_shift_buf(TRUE, sizeof(param.reason), + &data, (u_char *)¶m.reason); + get_param_and_shift_buf(TRUE, sizeof(param.ch_band), + &data, (u_char *)¶m.ch_band); + get_param_and_shift_buf(TRUE, sizeof(param.out_band_freq), + &data, (u_char *)¶m.out_band_freq); + + if (param.band_idx < TEST_DBDC_BAND_NUM) { + /* Set parameters */ + SERV_SET_PARAM(serv_test, ctrl_band_idx, + (u_char)param.band_idx); + CONFIG_SET_PARAM(serv_test, channel, + (u_char)param.central_ch0, param.band_idx); + CONFIG_SET_PARAM(serv_test, channel_2nd, + (u_char)param.central_ch1, param.band_idx); + CONFIG_SET_PARAM(serv_test, per_pkt_bw, + (u_char)param.perpkt_bw, param.band_idx); + CONFIG_SET_PARAM(serv_test, bw, + (u_char)param.sys_bw, param.band_idx); + CONFIG_SET_PARAM(serv_test, pri_sel, + (u_char)param.pri_sel, param.band_idx); + CONFIG_SET_PARAM(serv_test, ch_band, + (u_char)param.ch_band, param.band_idx); + CONFIG_SET_PARAM(serv_test, out_band_freq, + (u_int32)param.out_band_freq, param.band_idx); + + ret = mt_serv_set_channel(serv_test); + } else + ret = SERV_STATUS_AGENT_INVALID_BANDIDX; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: band_idx: %d, ch0: %d, ch1: %d, sys_bw: %d, ", + __func__, param.band_idx, param.central_ch0, + param.central_ch1, param.sys_bw)); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("perpkt_bw: %d, pri_sel: %d, ch_band: %d\n", + param.perpkt_bw, param.pri_sel, param.ch_band)); + + /* Update hqa_frame with response: status (2 bytes) */ + sys_ad_move_mem(hqa_frame->data + 2, (u_char *) ¶m.ext_id, 4); + update_hqa_frame(hqa_frame, 6, ret); + + return ret; +} + +static s_int32 hqa_set_txcontent_ext( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct hqa_tx_content param; + struct serv_hdr_802_11 *phdr = NULL; + u_char *data = hqa_frame->data; + u_char *payload, sta_seq = 0; + boolean enable = FALSE; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + sys_ad_zero_mem(¶m, sizeof(param)); + + get_param_and_shift_buf(TRUE, sizeof(param.ext_id), + &data, (u_char *)¶m.ext_id); + get_param_and_shift_buf(TRUE, sizeof(param.num_param), + &data, (u_char *)¶m.num_param); + get_param_and_shift_buf(TRUE, sizeof(param.band_idx), + &data, (u_char *)¶m.band_idx); + get_param_and_shift_buf(TRUE, sizeof(param.fc), + &data, (u_char *)¶m.fc); + get_param_and_shift_buf(TRUE, sizeof(param.dur), + &data, (u_char *)¶m.dur); + get_param_and_shift_buf(TRUE, sizeof(param.seq), + &data, (u_char *)¶m.seq); + get_param_and_shift_buf(TRUE, sizeof(param.fixed_payload), + &data, (u_char *)¶m.fixed_payload); + get_param_and_shift_buf(TRUE, sizeof(param.txlen), + &data, (u_char *)¶m.txlen); + get_param_and_shift_buf(TRUE, sizeof(param.payload_len), + &data, (u_char *)¶m.payload_len); + get_param_and_shift_buf(FALSE, SERV_MAC_ADDR_LEN, + &data, param.addr1); + get_param_and_shift_buf(FALSE, SERV_MAC_ADDR_LEN, + &data, param.addr2); + get_param_and_shift_buf(FALSE, SERV_MAC_ADDR_LEN, + &data, param.addr3); + + /* 52 for the size before payload */ + if (param.payload_len > TEST_MAX_PATTERN_SIZE) + param.payload_len = TEST_MAX_PATTERN_SIZE; + + /* Set parameters */ + SERV_SET_PARAM(serv_test, ctrl_band_idx, (u_char)param.band_idx); + for (sta_seq = 0; sta_seq < MAX_MULTI_TX_STA ; sta_seq++) { + CONFIG_SET_PADDR(serv_test, addr1[sta_seq], param.addr1, + SERV_MAC_ADDR_LEN, param.band_idx); + CONFIG_SET_PADDR(serv_test, addr2[sta_seq], param.addr2, + SERV_MAC_ADDR_LEN, param.band_idx); + CONFIG_SET_PADDR(serv_test, addr3[sta_seq], param.addr3, + SERV_MAC_ADDR_LEN, param.band_idx); + } + CONFIG_SET_PARAM(serv_test, dur, + (u_short)param.dur, param.band_idx); + CONFIG_SET_PARAM(serv_test, seq, + (u_short)param.seq, param.band_idx); + CONFIG_SET_PARAM(serv_test, pl_len, + (u_int32)param.payload_len, param.band_idx); + CONFIG_SET_PARAM(serv_test, tx_len, + (u_int32)param.txlen, param.band_idx); + CONFIG_SET_PARAM(serv_test, fixed_payload, + (u_int32)param.fixed_payload, param.band_idx); + + payload = CONFIG_GET_PADDR(serv_test, payload[0], param.band_idx); + phdr = (struct serv_hdr_802_11 *)CONFIG_GET_PADDR(serv_test, + template_frame, + param.band_idx); + sys_ad_move_mem(&phdr->fc, ¶m.fc, sizeof(phdr->fc)); + phdr->duration = (u_int16)param.dur; + phdr->sequence = (u_int16)param.seq; + + /* Error check for txlen and payload_len */ + /* the fixed_payload means Normal : 0, repeat:1 , random:2*/ + /* random:2 dont follow this rule*/ + if ((param.txlen == 0) || + ((param.payload_len == 0) && (param.fixed_payload != 2))) { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: txlen/payload_len=%u/%u can't be 0!!\n", + __func__, param.txlen, param.payload_len)); + return SERV_STATUS_AGENT_INVALID_LEN; + } + + /* Packet tx time feature implementation */ + enable = CONFIG_GET_PARAM(serv_test, tx_time_param.pkt_tx_time_en, + param.band_idx); + if (enable == TRUE) { + CONFIG_SET_PARAM(serv_test, tx_time_param.pkt_tx_time, + (u_int32)param.txlen, param.band_idx); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: fc=0x%04x, dur=%u, seq=%u, plen=%u\n", + __func__, param.fc, param.dur, param.seq, + param.payload_len)); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: pkt_tx_time=%u, genpkt=%u\n", + __func__, param.txlen, + param.fixed_payload)); + } else { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: fc=0x%04x, dur=%u, seq=%u, plen=%u\n", + __func__, param.fc, param.dur, param.seq, + param.payload_len)); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: txlen=%u, genpkt=%u\n", + __func__, param.txlen, param.fixed_payload)); + } + + get_param_and_shift_buf(FALSE, param.payload_len, &data, payload); + + ret = mt_serv_set_tx_content(serv_test); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: addr1=%02x:%02x:%02x:%02x:%02x:%02x\n", + __func__, param.addr1[0], param.addr1[1], param.addr1[2], + param.addr1[3], param.addr1[4], param.addr1[5])); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: addr2=%02x:%02x:%02x:%02x:%02x:%02x\n", + __func__, param.addr2[0], param.addr2[1], param.addr2[2], + param.addr2[3], param.addr2[4], param.addr2[5])); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: addr3=%02x:%02x:%02x:%02x:%02x:%02x\n", + __func__, param.addr3[0], param.addr3[1], param.addr3[2], + param.addr3[3], param.addr3[4], param.addr3[5])); + + /* Update hqa_frame with response: status (2 bytes) */ + sys_ad_move_mem(hqa_frame->data + 2, (u_char *) ¶m.ext_id, + sizeof(param.ext_id)); + update_hqa_frame(hqa_frame, 2 + sizeof(param.ext_id), ret); + + return ret; +} + +static s_int32 hqa_start_tx_ext( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct hqa_tx param; + u_char *data = hqa_frame->data; + u_char ant_idx = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + sys_ad_zero_mem(¶m, sizeof(param)); + + get_param_and_shift_buf(TRUE, sizeof(param.ext_id), + &data, (u_char *)¶m.ext_id); + get_param_and_shift_buf(TRUE, sizeof(param.num_param), + &data, (u_char *)¶m.num_param); + get_param_and_shift_buf(TRUE, sizeof(param.band_idx), + &data, (u_char *)¶m.band_idx); + get_param_and_shift_buf(TRUE, sizeof(param.pkt_cnt), + &data, (u_char *)¶m.pkt_cnt); + get_param_and_shift_buf(TRUE, sizeof(param.tx_mode), + &data, (u_char *)¶m.tx_mode); + get_param_and_shift_buf(TRUE, sizeof(param.rate), + &data, (u_char *)¶m.rate); + get_param_and_shift_buf(TRUE, sizeof(param.pwr), + &data, (u_char *)¶m.pwr); + get_param_and_shift_buf(TRUE, sizeof(param.stbc), + &data, (u_char *)¶m.stbc); + get_param_and_shift_buf(TRUE, sizeof(param.ldpc), + &data, (u_char *)¶m.ldpc); + get_param_and_shift_buf(TRUE, sizeof(param.ibf), + &data, (u_char *)¶m.ibf); + get_param_and_shift_buf(TRUE, sizeof(param.ebf), + &data, (u_char *)¶m.ebf); + get_param_and_shift_buf(TRUE, sizeof(param.wlan_id), + &data, (u_char *)¶m.wlan_id); + get_param_and_shift_buf(TRUE, sizeof(param.aifs), + &data, (u_char *)¶m.aifs); + get_param_and_shift_buf(TRUE, sizeof(param.gi), + &data, (u_char *)¶m.gi); + get_param_and_shift_buf(TRUE, sizeof(param.tx_path), + &data, (u_char *)¶m.tx_path); + get_param_and_shift_buf(TRUE, sizeof(param.nss), + &data, (u_char *)¶m.nss); + get_param_and_shift_buf(TRUE, sizeof(param.hw_tx_enable), + &data, (u_char *)¶m.hw_tx_enable); + + if (!param.pkt_cnt) + param.pkt_cnt = 0x8fffffff; + + /* Set parameters */ + SERV_SET_PARAM(serv_test, ctrl_band_idx, (u_char)param.band_idx); + CONFIG_SET_PARAM(serv_test, tx_stat.tx_cnt, + (u_int32)param.pkt_cnt, param.band_idx); + CONFIG_SET_PARAM(serv_test, tx_mode, + (u_char)param.tx_mode, param.band_idx); + CONFIG_SET_PARAM(serv_test, mcs, + (u_char)param.rate, param.band_idx); + CONFIG_SET_PARAM(serv_test, stbc, + (u_char)param.stbc, param.band_idx); + CONFIG_SET_PARAM(serv_test, ldpc, + (u_char)param.ldpc, param.band_idx); +#if 0 /* remove tx_path setting while start Tx, + * it should be done prior to switch channel + */ + CONFIG_SET_PARAM(serv_test, tx_ant, + (u_char)param.tx_path, param.band_idx); +#endif + CONFIG_SET_PARAM(serv_test, nss, + (u_char)param.nss, param.band_idx); + CONFIG_SET_PARAM(serv_test, sgi, + (u_char)param.gi, param.band_idx); + CONFIG_SET_PARAM(serv_test, wcid_ref, + (u_int8)param.wlan_id, param.band_idx); + CONFIG_SET_PARAM(serv_test, ipg_param.ipg, + (u_int32)param.aifs, param.band_idx); + for (ant_idx = 0; ant_idx < TEST_ANT_NUM; ant_idx++) + CONFIG_SET_PARAM(serv_test, tx_pwr[ant_idx], + (u_int32)param.pwr, param.band_idx); + WINFO_SET_PARAM(serv_test, hw_tx_enable, param.hw_tx_enable); + if (mt_serv_submit_tx(serv_test) != SERV_STATUS_SUCCESS) + goto err_out; + + ret = mt_serv_start_tx(serv_test); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: band_idx=%u, pkt_cnt=0x%4x, phy=%u\n", + __func__, param.band_idx, param.pkt_cnt, param.tx_mode)); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: pwr=%u, mcs=%u, stbc=%u, ldpc=%u\n", + __func__, param.pwr, param.rate, param.stbc, param.ldpc)); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: ibf=%u, ebf=%u, wlan_id=%u, aifs=%u\n", + __func__, param.ibf, param.ebf, param.wlan_id, param.aifs)); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: gi=%u, nss=%u hwtx=%u\n", + __func__, param.gi, param.nss, param.hw_tx_enable)); + + /* Update hqa_frame with response: status (2 bytes) */ + sys_ad_move_mem(hqa_frame->data + 2, ¶m.ext_id, + sizeof(param.ext_id)); + update_hqa_frame(hqa_frame, 2 + sizeof(param.ext_id), ret); + +err_out: + return ret; +} + +static s_int32 hqa_start_rx_ext( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char *data = hqa_frame->data; + u_char own_mac[SERV_MAC_ADDR_LEN]; + u_int32 ext_id = 0, param_num = 0, band_idx = 0, rx_path = 0; + u_int32 user_idx = 0, tx_mode = 0, ltf_gi = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + sys_ad_zero_mem(own_mac, SERV_MAC_ADDR_LEN); + get_param_and_shift_buf(TRUE, sizeof(u_int32), + &data, (u_char *)&ext_id); + get_param_and_shift_buf(TRUE, sizeof(u_int32), + &data, (u_char *)¶m_num); + get_param_and_shift_buf(TRUE, sizeof(u_int32), + &data, (u_char *)&band_idx); + get_param_and_shift_buf(FALSE, SERV_MAC_ADDR_LEN, + &data, (u_char *)&own_mac); + get_param_and_shift_buf(TRUE, sizeof(u_int32), + &data, (u_char *)&rx_path); + get_param_and_shift_buf(TRUE, sizeof(u_int32), &data, + (u_char *)CONFIG_GET_PADDR(serv_test, + mu_rx_aid, + band_idx)); + if (param_num > 3) { + get_param_and_shift_buf(TRUE, sizeof(u_int32), + &data, (u_char *)&tx_mode); + get_param_and_shift_buf(TRUE, sizeof(u_int32), + &data, (u_char *)<f_gi); + get_param_and_shift_buf(TRUE, sizeof(u_int32), + &data, (u_char *)&user_idx); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: param num:%d\n", __func__, param_num)); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: \ttx_mode:%d, ltf_gi:%d, user_idx:%d\n", + __func__, tx_mode, ltf_gi, user_idx)); + } + + /* Set parameters */ + SERV_SET_PARAM(serv_test, ctrl_band_idx, (u_char)band_idx); + CONFIG_SET_PADDR(serv_test, own_mac, own_mac, + SERV_MAC_ADDR_LEN, band_idx); +#if 0 /* remove rx_path setting while start Rx, + * it should be done prior to switch channel + */ + CONFIG_SET_PARAM(serv_test, rx_ant, (u_int16)rx_path, band_idx); +#endif + CONFIG_SET_PARAM(serv_test, tx_mode, tx_mode, band_idx); + CONFIG_SET_PARAM(serv_test, sgi, ltf_gi, band_idx); + CONFIG_SET_PARAM(serv_test, user_idx, (u_int8)user_idx, band_idx); + + ret = mt_serv_start_rx(serv_test); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: param num=%u, band_idx=%u\n", + __func__, param_num, band_idx)); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: mac=%02x:%02x:%02x:%02x:%02x:%02x\n", + __func__, own_mac[0], own_mac[1], own_mac[2], + own_mac[3], own_mac[4], own_mac[5])); + + /* Update hqa_frame with response: status (2 bytes) */ + sys_ad_move_mem(hqa_frame->data + 2, (u_char *) &ext_id, + sizeof(ext_id)); + update_hqa_frame(hqa_frame, 2 + sizeof(ext_id), ret); + + return ret; +} + +static s_int32 hqa_stop_tx_ext( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char *data = hqa_frame->data; + u_int32 ext_id = 0, param_num = 0, band_idx = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + get_param_and_shift_buf(TRUE, sizeof(ext_id), + &data, (u_char *)&ext_id); + get_param_and_shift_buf(TRUE, sizeof(param_num), + &data, (u_char *)¶m_num); + get_param_and_shift_buf(TRUE, sizeof(band_idx), + &data, (u_char *)&band_idx); + + /* Set parameters */ + SERV_SET_PARAM(serv_test, ctrl_band_idx, (u_char)band_idx); + + ret = mt_serv_stop_tx(serv_test); + if (ret != SERV_STATUS_SUCCESS) + goto err_out; + + ret = mt_serv_revert_tx(serv_test); + if (ret != SERV_STATUS_SUCCESS) + goto err_out; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: band_idx=%u\n", __func__, band_idx)); + + /* Update hqa_frame with response: status (2 bytes) */ + sys_ad_move_mem(hqa_frame->data + 2, (u_char *) &ext_id, + sizeof(ext_id)); + update_hqa_frame(hqa_frame, 2 + sizeof(ext_id), ret); + +err_out: + return ret; +} + +static s_int32 hqa_stop_rx_ext( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char *data = hqa_frame->data; + u_int32 ext_id = 0, param_num = 0, band_idx = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + get_param_and_shift_buf(TRUE, sizeof(ext_id), + &data, (u_char *)&ext_id); + get_param_and_shift_buf(TRUE, sizeof(param_num), + &data, (u_char *)¶m_num); + get_param_and_shift_buf(TRUE, sizeof(band_idx), + &data, (u_char *)&band_idx); + + /* Set parameters */ + SERV_SET_PARAM(serv_test, ctrl_band_idx, (u_char)band_idx); + + ret = mt_serv_stop_rx(serv_test); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: band_idx=%u\n", __func__, band_idx)); + + /* Update hqa_frame with response: status (2 bytes) */ + sys_ad_move_mem(hqa_frame->data + 2, (u_char *) &ext_id, + sizeof(ext_id)); + update_hqa_frame(hqa_frame, 2 + sizeof(ext_id), ret); + + return ret; +} + +static s_int32 hqa_set_tx_time( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char *data = hqa_frame->data; + u_int32 ext_id = 0, is_tx_time = 0, band_idx = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + get_param_and_shift_buf(TRUE, sizeof(ext_id), + &data, (u_char *)&ext_id); + get_param_and_shift_buf(TRUE, sizeof(band_idx), + &data, (u_char *)&band_idx); + get_param_and_shift_buf(TRUE, sizeof(is_tx_time), + &data, (u_char *)&is_tx_time); + + /* Set parameters */ + SERV_SET_PARAM(serv_test, ctrl_band_idx, (u_char)band_idx); + + /* 0: use tx length, 1: use tx time */ + if (is_tx_time == 1) + CONFIG_SET_PARAM(serv_test, tx_time_param.pkt_tx_time_en, + TRUE, band_idx); + else { + CONFIG_SET_PARAM(serv_test, tx_time_param.pkt_tx_time_en, + FALSE, band_idx); + /* Reset to 0 when start tx everytime */ + CONFIG_SET_PARAM(serv_test, tx_time_param.pkt_tx_time, + 0, band_idx); + } + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: band_idx=%u, is_tx_time=%u\n", + __func__, band_idx, is_tx_time)); + + /* Update hqa_frame with response: status (2 bytes) */ + sys_ad_move_mem(hqa_frame->data + 2, (u_char *) &ext_id, + sizeof(ext_id)); + update_hqa_frame(hqa_frame, 2 + sizeof(ext_id), ret); + + return ret; +} + +static s_int32 hqa_off_ch_scan( + struct service_test *serv_test, struct hqa_frame *hqa_frame) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char *data = hqa_frame->data; + u_int32 ext_id = 0, dbdc_idx = 0, mntr_ch = 0; + u_int32 is_aband = 0, mntr_bw = 0, mntr_tx_rx_pth = 0; + u_int32 scan_mode = 0; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, ("%s\n", __func__)); + + /* Get parameters from command frame */ + /* Data sequences of command frame: + * ext_id (4 bytes) + dbdc_idx (4 bytes) + mntr_ch (4 bytes) + + * is_aband (4 bytes) + mntr_bw (4 bytes) + + * mntr_tx_rx_pth (4 bytes) + scan_mode (4 bytes) + */ + get_param_and_shift_buf(TRUE, sizeof(ext_id), + &data, (u_char *)&ext_id); + get_param_and_shift_buf(TRUE, sizeof(dbdc_idx), + &data, (u_char *)&dbdc_idx); + get_param_and_shift_buf(TRUE, sizeof(mntr_ch), + &data, (u_char *)&mntr_ch); + get_param_and_shift_buf(TRUE, sizeof(is_aband), + &data, (u_char *)&is_aband); + get_param_and_shift_buf(TRUE, sizeof(mntr_bw), + &data, (u_char *)&mntr_bw); + get_param_and_shift_buf(TRUE, sizeof(mntr_tx_rx_pth), + &data, (u_char *)&mntr_tx_rx_pth); + get_param_and_shift_buf(TRUE, sizeof(scan_mode), + &data, (u_char *)&scan_mode); + + switch (mntr_bw) { + case HQA_BAND_WIDTH_20: + mntr_bw = TEST_BW_20; + break; + + case HQA_BAND_WIDTH_40: + mntr_bw = TEST_BW_40; + break; + + case HQA_BAND_WIDTH_80: + mntr_bw = TEST_BW_80; + break; + + case HQA_BAND_WIDTH_10: + mntr_bw = TEST_BW_10; + break; + + case HQA_BAND_WIDTH_5: + mntr_bw = TEST_BW_5; + break; + + case HQA_BAND_WIDTH_160: + mntr_bw = TEST_BW_160C; + break; + + case HQA_BAND_WIDTH_8080: + mntr_bw = TEST_BW_160NC; + break; + + default: + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: bw 0x%x is out of range\n", __func__, mntr_bw)); + mntr_bw = TEST_BW_20; + break; + } + + /* Set parameters */ + SERV_SET_PARAM(serv_test, ctrl_band_idx, (u_char)dbdc_idx); + CONFIG_SET_PARAM(serv_test, off_ch_param.ext_id, + (u_int32)ext_id, dbdc_idx); + CONFIG_SET_PARAM(serv_test, off_ch_param.dbdc_idx, + (u_int32)dbdc_idx, dbdc_idx); + CONFIG_SET_PARAM(serv_test, off_ch_param.mntr_ch, + (u_int32)mntr_ch, dbdc_idx); + CONFIG_SET_PARAM(serv_test, off_ch_param.is_aband, + (u_int32)is_aband, dbdc_idx); + CONFIG_SET_PARAM(serv_test, off_ch_param.mntr_bw, + (u_int32)mntr_bw, dbdc_idx); + CONFIG_SET_PARAM(serv_test, off_ch_param.mntr_tx_rx_pth, + (u_int32)mntr_tx_rx_pth, dbdc_idx); + CONFIG_SET_PARAM(serv_test, off_ch_param.scan_mode, + (u_int32)scan_mode, dbdc_idx); + + ret = mt_serv_set_off_ch_scan(serv_test); + + /* Update hqa_frame with response: status (2 bytes) */ + sys_ad_move_mem(hqa_frame->data + 2, (u_char *) &ext_id, + sizeof(ext_id)); + update_hqa_frame(hqa_frame, 2 + sizeof(ext_id), ret); + + return ret; +} + +static struct hqa_cmd_entry CMD_SET6[] = { + /* cmd id start from 0x1600 */ + {0x1, hqa_set_channel_ext}, + {0x2, hqa_set_txcontent_ext}, + {0x3, hqa_start_tx_ext}, + {0x4, hqa_start_rx_ext}, + {0x5, hqa_stop_tx_ext}, + {0x6, hqa_stop_rx_ext}, + {0x7, legacy_function}, + {0x8, legacy_function}, + {0x9, legacy_function}, + {0xa, legacy_function}, + {0xb, legacy_function}, + {0xc, legacy_function}, + {0x26, hqa_set_tx_time}, + {0x27, hqa_off_ch_scan} +}; + +static struct hqa_cmd_table CMD_TABLES[] = { + { + CMD_SET0, + SERV_ARRAY_SIZE(CMD_SET0), + 0x1000, + } + , + { + CMD_SET1, + SERV_ARRAY_SIZE(CMD_SET1), + 0x1100, + } + , + { + CMD_SET2, + SERV_ARRAY_SIZE(CMD_SET2), + 0x1200, + } + , + { + CMD_SET3, + SERV_ARRAY_SIZE(CMD_SET3), + 0x1300, + } + , + { + CMD_SET4, + SERV_ARRAY_SIZE(CMD_SET4), + 0x1400, + } + , + { + CMD_SET5, + SERV_ARRAY_SIZE(CMD_SET5), + 0x1500, + } + , + { + CMD_SET6, + SERV_ARRAY_SIZE(CMD_SET6), + 0x1600, + } + , +}; + +static struct priv_hqa_cmd_id_mapping priv_hqa_cmd_mapping[] = { + {"OpenAdapter", 0x1000, + {0} }, + {"CloseAdapter", 0x1001, + {0} }, + {"SetBandMode", 0x152c, + {4, 4} }, + {"SetTxPath", 0x100b, + {4, 4} }, + {"SetRxPath", 0x100c, + {4, 4} }, + {"GetTxInfo", 0x1313, + {0} }, + {"DBDCStartTX", 0x1600, + {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4} }, + {"DBDCStartRX", 0x1600, + {4, 4, 4, 6, 4, 4, 4, 4, 4} }, + {"DBDCStopTX", 0x1600, + {4, 4, 4} }, + {"DBDCStopRX", 0x1600, + {4, 4, 4} }, + {"DBDCSetChannel", 0x1600, + {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4} }, + {"DBDCSetTXContent", 0x1600, + {4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6} }, + {"GetRXStatisticsAllNew", 0x151c, + {4, 4} }, + {"GetChipCapability", 0x151d, + {0} }, + {"ResetTxRxCounter", 0x1200, + {0} }, + {"CalibrationTestMode", 0x1509, + {4, 4} }, + {"CapWiFiSpectrum", 0x1580, + {4, 4, 4, 4, 4, 4, 4, 4, 4, 6} }, +}; + +s_int32 mt_agent_hqa_cmd_string_parser( + s_int8 *hqa_frame_string, struct hqa_frame *hqa_frame) +{ + s_int8 i = 0, j = 0, pattern_found = 0; + s_int8 *this_para = NULL; + s_int32 i4argc = 0; + s_int8 *apc_argv[AGENT_CFG_ARGV_MAX] = { 0 }; + u_char tmpdata[100] = { 0 }; + s_int8 tmp_mac[SERV_MAC_ADDR_LEN] = { 0 }; + u_int16 tmp_length = 0; + u_int32 tmp_value = 0; + u_int16 tmp_value2 = 0; + u_char *data = NULL; + u_int16 ret = 0; + u_int8 parasize = 0; + + for (i = 0; i < sizeof(priv_hqa_cmd_mapping) / sizeof(struct + priv_hqa_cmd_id_mapping); i++) { + if (strncasecmp(hqa_frame_string, + priv_hqa_cmd_mapping[i].cmd_str, + strlen(priv_hqa_cmd_mapping[i].cmd_str)) == 0) { + + /*Command Found in table*/ + pattern_found = 1; + + /*Parsing the parameters if it has*/ + this_para = strstr(hqa_frame_string, "="); + if (this_para) { + /*Roll over "=", get Parameters y,y,y,y...*/ + this_para++; + agent_cfg_parse_argument(this_para, + &i4argc, apc_argv); + /*debug use*/ + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("argc is %i\n", i4argc)); + for (j = 0 ; j < i4argc; j++) { + SERV_LOG(SERV_DBG_CAT_TEST, + SERV_DBG_LVL_TRACE, + ("argv is %s\n", apc_argv[j++])); + } + } + + break; + } + } + + /*pack the hqa command*/ + if (pattern_found) { + if (i4argc) { + data = tmpdata; + for (j = 0; j < i4argc; j++) { + parasize = priv_hqa_cmd_mapping[i].para_size[j]; + tmp_length += parasize; + + if (parasize == SERV_MAC_ADDR_LEN) { + ret = sscanf(apc_argv[j], + "%x:%x:%x:%x:%x:%x", + (unsigned int *)&tmp_mac[0], + (unsigned int *)&tmp_mac[1], + (unsigned int *)&tmp_mac[2], + (unsigned int *)&tmp_mac[3], + (unsigned int *)&tmp_mac[4], + (unsigned int *)&tmp_mac[5]); + + if (ret) + set_param_and_shift_buf(FALSE, parasize, + (u_char *)&tmp_mac, &data); + } else if (parasize == 4) { + ret = kstrtou32(apc_argv[j], 0, + &tmp_value); + set_param_and_shift_buf(TRUE, parasize, + (u_char *)&tmp_value, &data); + } else if (parasize == 2) { + ret = kstrtou16(apc_argv[j], 0, + &tmp_value2); + set_param_and_shift_buf(TRUE, parasize, + (u_char *)&tmp_value2, &data); + } else { + ret = kstrtou8(apc_argv[j], 0, + (u_int8 *)&tmp_value); + set_param_and_shift_buf(TRUE, parasize, + (u_char *)&tmp_value, &data); + } + } + } + + hqa_frame->magic_no = SERV_OS_HTONL(TEST_CMD_MAGIC_NO); + hqa_frame->type = 0; + hqa_frame->id = SERV_OS_HTONS(priv_hqa_cmd_mapping[i].cmd_id); + hqa_frame->length = tmp_length; + hqa_frame->sequence = 0; + memcpy(hqa_frame->data, tmpdata, tmp_length); + + /*debug use*/ + data = (u_char *)hqa_frame; + for (j = 0; j < sizeof(struct hqa_frame)/sizeof(u_char); j++) { + if (!(j % 16)) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("\n")); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + (" 0x%02x ", *data++)); + } + + return SERV_STATUS_SUCCESS; + } else + return SERV_STATUS_AGENT_NOT_SUPPORTED; +} + +s_int32 mt_agent_hqa_cmd_handler( + struct service *serv, struct hqa_frame_ctrl *hqa_frame_ctrl) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct service_test *serv_test; + u_int16 cmd_id; + u_int32 table_idx = 0, ext_cmd_id = 0; + u_int32 magic_no = 0; + struct hqa_frame *hqa_frame = NULL; + + if (hqa_frame_ctrl->type == 1) { + ret = mt_agent_hqa_cmd_string_parser( + hqa_frame_ctrl->hqa_frame_comm.hqa_frame_string, + hqa_frame_ctrl->hqa_frame_comm.hqa_frame_eth); + /*can return for debug*/ + /*return ret;*/ + if (ret != SERV_STATUS_SUCCESS) + return ret; + } + + hqa_frame = hqa_frame_ctrl->hqa_frame_comm.hqa_frame_eth; + + magic_no = SERV_OS_NTOHL(hqa_frame->magic_no); + serv_test = (struct service_test *)serv->serv_handle; + + if (magic_no != TEST_CMD_MAGIC_NO) + return SERV_STATUS_AGENT_INVALID_PARAM; + + hqa_frame->length = SERV_OS_NTOHS(hqa_frame->length); + + cmd_id = SERV_OS_NTOHS(hqa_frame->id); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: command id=0x%02x\n", __func__, cmd_id)); + + while (table_idx < + (sizeof(CMD_TABLES) / sizeof(struct hqa_cmd_table))) { + if ((cmd_id & 0xff00) == CMD_TABLES[table_idx].cmd_offset) { + u_int32 cmd_loop = 0; + struct hqa_cmd_entry *cmd_set = NULL; + + cmd_set = CMD_TABLES[table_idx].cmd_set; + /* Fix me, should align with other command set */ + if (CMD_TABLES[table_idx].cmd_offset == 0x1600) { + sys_ad_move_mem(&ext_cmd_id, + hqa_frame->data, + sizeof(ext_cmd_id)); + cmd_id = SERV_OS_NTOHL(ext_cmd_id); + } + + cmd_id &= 0xff; + ret = SERV_STATUS_AGENT_NOT_SUPPORTED; + while (cmd_loop < CMD_TABLES[table_idx].cmd_set_size) { + if (cmd_id == cmd_set[cmd_loop].index) { + ret = cmd_set[cmd_loop].handler( + serv_test, hqa_frame); + + goto done; + } else + cmd_loop++; + } + } else + table_idx++; + } + +done: + if (cmd_id == TEST_CMD_REQ) { + hqa_frame->type = TEST_CMD_RSP; + /* hqa_frame->type = 0x8005; */ + } else + hqa_frame->type = TEST_CMDRSP; + + return ret; +} + +/***************************************************************************** + * iwpriv command handler + *****************************************************************************/ + +static struct hqa_frame hqa_cmd_frame; + +static struct agent_cli_act_handler cli_act_cmds[] = { + {"ATESTART", mt_serv_start}, + {"APSTOP", mt_serv_start}, + {"ATESTOP", mt_serv_stop}, + {"APSTART", mt_serv_stop}, + {"TXCOMMIT", mt_serv_submit_tx}, + {"TXREVERT", mt_serv_revert_tx}, + {"TXFRAME", mt_serv_start_tx}, + {"TXSTOP", mt_serv_stop_tx}, + {"RXFRAME", mt_serv_start_rx}, + {"RXSTOP", mt_serv_stop_rx}, + {"", NULL} /* the last entry */ +}; + +s_int32 mt_agent_cli_act(u_char *name, struct service *serv) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct service_test *serv_test = NULL; + struct agent_cli_act_handler *entry = cli_act_cmds; + + serv_test = (struct service_test *)serv->serv_handle; + + while (strlen(entry->name)) { + if (strcmp(name, entry->name) == 0) + ret = entry->handler(serv_test); + + entry++; + } + + return ret; +} + +static struct agent_cli_set_w_handler cli_set_w_cmds[] = { + {"", NULL} /* the last entry */ +}; + +s_int32 mt_agent_cli_set_w(u_char *name, struct service *serv, u_char *param) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_long str2value = 0; + struct agent_cli_set_w_handler *entry = cli_set_w_cmds; + struct hqa_frame *hqa_cmd = &hqa_cmd_frame; + u_int16 value = 0; + + sys_ad_zero_mem(hqa_cmd, sizeof(*hqa_cmd)); + + if (kstrtol(param, 10, &str2value) == 0) { + value = str2value; + value = SERV_OS_HTONS(value); + sys_ad_move_mem(hqa_cmd->data, &value, sizeof(u_int16)); + while (strlen(entry->name)) { + if (strcmp(name, entry->name) == 0) + ret = entry->handler( + (struct service_test *)serv->serv_handle, + hqa_cmd); + entry++; + } + } else + ret = SERV_STATUS_AGENT_INVALID_PARAM; + + return ret; +} + +static struct agent_cli_set_dw_handler cli_set_dw_cmds[] = { + {"ATETXMCS", hqa_set_rate}, + {"ATETXNSS", hqa_set_nss}, + {"ATENSS", hqa_set_nss}, + {"ATETXSTBC", hqa_set_stbc}, + {"ATETXMODE", hqa_set_preamble}, + {"ATETXGI", hqa_set_short_gi}, + {"", NULL} /* the last entry */ +}; + +s_int32 mt_agent_cli_set_dw(u_char *name, struct service *serv, u_char *param) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_long str2value = 0; + struct agent_cli_set_dw_handler *entry = cli_set_dw_cmds; + struct hqa_frame *hqa_cmd = &hqa_cmd_frame; + u_int32 value = 0; + + sys_ad_zero_mem(hqa_cmd, sizeof(*hqa_cmd)); + if (kstrtol(param, 10, &str2value) == 0) { + value = str2value; + value = SERV_OS_HTONL(value); + sys_ad_move_mem(hqa_cmd->data, &value, sizeof(u_int32)); + while (strlen(entry->name)) { + if (strcmp(name, entry->name) == 0) + ret = entry->handler( + (struct service_test *)serv->serv_handle, + hqa_cmd); + entry++; + } + } else + ret = SERV_STATUS_AGENT_INVALID_PARAM; + + return ret; +} + +s_int32 mt_agent_set_bw(struct service_test *serv_test, u_char *arg) +{ + u_int32 ret = 0; + u_int32 param[2] = {0}; + u_int8 i = 0; + u_char *value; + struct hqa_frame *hqa_cmd = &hqa_cmd_frame; + u_char *data = hqa_cmd->data; + + sys_ad_zero_mem(hqa_cmd, sizeof(*hqa_cmd)); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: Bw = %s\n", __func__, arg)); + + for (i = 0, value = agent_trtok(arg, ":"); + value; value = agent_trtok(NULL, ":")) { + if (i == 2) + break; + kstrtol(value, 10, (long *)¶m[i++]); + } + + set_param_and_shift_buf(TRUE, sizeof(u_int32), + (u_char *)¶m[0], &data); + hqa_set_system_bw(serv_test, hqa_cmd); + + data = hqa_cmd->data; + set_param_and_shift_buf(TRUE, sizeof(u_int32), + (u_char *)¶m[1], &data); + hqa_set_per_pkt_bw(serv_test, hqa_cmd); + + return ret; +} + +s_int32 mt_agent_set_ctrl_band( + struct service_test *serv_test, u_char *arg) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_long str2value = 0; + u_int32 value = 0; + + if (kstrtol(arg, 10, &str2value) == 0) { + value = str2value; + SERV_SET_PARAM(serv_test, ctrl_band_idx, value); + } else + ret = SERV_STATUS_AGENT_INVALID_PARAM; + + return ret; +} + +s_int32 mt_agent_set_pwr( + struct service_test *serv_test, u_char *arg) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_int32 value = 0; + u_long input = 0; + struct hqa_frame *hqa_cmd = &hqa_cmd_frame; + u_char *data = hqa_cmd->data; + + if (kstrtol(arg, 10, (long *)&input) == 0) { + /* power */ + value = input; + set_param_and_shift_buf(TRUE, sizeof(u_int32), + (u_char *)&value, &data); + /* band index */ + value = serv_test->ctrl_band_idx; + set_param_and_shift_buf(TRUE, sizeof(u_int32), + (u_char *)&value, &data); + /* channel */ + value = CONFIG_GET_PARAM(serv_test, channel, + SERV_GET_PARAM(serv_test, + ctrl_band_idx)); + set_param_and_shift_buf(TRUE, sizeof(u_int32), + (u_char *)&value, &data); + /* channel band */ + value = CONFIG_GET_PARAM(serv_test, ch_band, + SERV_GET_PARAM(serv_test, + ctrl_band_idx)); + set_param_and_shift_buf(TRUE, sizeof(u_int32), + (u_char *)&value, &data); + /* ant index */ + value = 0; + set_param_and_shift_buf(TRUE, sizeof(u_int32), + (u_char *)&value, &data); + hqa_set_tx_power_ext(serv_test, hqa_cmd); + } else + ret = SERV_STATUS_AGENT_INVALID_PARAM; + + return ret; +} + +s_int32 mt_agent_set_channel( + struct service_test *serv_test, u_char *arg) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_int32 value = 0; + u_int32 input[4] = {0}; + u_int8 i = 0; + struct hqa_frame *hqa_cmd = &hqa_cmd_frame; + u_char *data = hqa_cmd->data, *tok = NULL; + + sys_ad_zero_mem(hqa_cmd, sizeof(*hqa_cmd)); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: control_band_idx:%x, Channel = %s\n", + __func__, serv_test->ctrl_band_idx, arg)); + + for (i = 0, tok = agent_trtok(arg, ":"); + tok; + tok = agent_trtok(NULL, ":")) { + if (i == 4) + break; + + kstrtol(tok, 10, (long *)&input[i++]); + } + + /* For backward compatibility */ + if (input[0] >= 36 && input[0] <= 181) { + if (input[1] == 0) { + input[1] = 1; /* channel_band 5G as 1*/ + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("\x1b[41m%s(): 5G Channel:%d, then force Channel_Band:%d !!\x1b[m\n", + __func__, input[0], input[1])); + } + } + + /* ext id */ + set_param_and_shift_buf(TRUE, sizeof(u_int32), + (u_char *)&value, &data); + /* parameters count */ + value = 8; + set_param_and_shift_buf(TRUE, sizeof(u_int32), + (u_char *)&value, &data); + /* band index */ + value = serv_test->ctrl_band_idx; + set_param_and_shift_buf(TRUE, sizeof(u_int32), + (u_char *)&value, &data); + /* central channel index */ + value = input[0]; + set_param_and_shift_buf(TRUE, sizeof(u_int32), + (u_char *)&value, &data); + /* 2nd central channel index */ + value = input[3]; + set_param_and_shift_buf(TRUE, sizeof(u_int32), + (u_char *)&value, &data); + /* system bandwidth */ + value = CONFIG_GET_PARAM(serv_test, bw, + serv_test->ctrl_band_idx); + set_param_and_shift_buf(TRUE, sizeof(u_int32), + (u_char *)&value, &data); + /* data band width */ + value = CONFIG_GET_PARAM(serv_test, per_pkt_bw, + serv_test->ctrl_band_idx); + set_param_and_shift_buf(TRUE, sizeof(u_int32), + (u_char *)&value, &data); + /* primary offset */ + value = input[2]; + set_param_and_shift_buf(TRUE, sizeof(u_int32), + (u_char *)&value, &data); + /* reason */ + value = 0; + set_param_and_shift_buf(TRUE, sizeof(u_int32), + (u_char *)&value, &data); + /* channel band */ + value = input[1]; + set_param_and_shift_buf(TRUE, sizeof(u_int32), + (u_char *)&value, &data); + value = 0; + /* out band frequency */ + set_param_and_shift_buf(TRUE, sizeof(u_int32), + (u_char *)&value, &data); + + hqa_set_channel_ext(serv_test, hqa_cmd); + + return ret; +} + +s_int32 mt_agent_set_ru_cli(struct service_test *serv_test, u_char *arg) +{ + s_int32 ret = SERV_STATUS_AGENT_INVALID_PARAM; + s_int32 input_cnt = 0; + u_char *value = NULL, i = 0, band_idx; + struct test_ru_info *ru_info = NULL; + + band_idx = SERV_GET_PARAM(serv_test, ctrl_band_idx); + + ru_info = (struct test_ru_info *)CONFIG_GET_PADDR(serv_test, + ru_info_list[0], + band_idx); + + if (strlen(arg) > 0) { + sys_ad_zero_mem(ru_info, + sizeof(struct test_ru_info)*MAX_MULTI_TX_STA); + + for (i = 0, value = agent_trtok(arg, ":"); + value; + value = agent_trtok((char *)NULL, ":"), i++) { + input_cnt = sscanf(value, + "%4x-%d-%d-%d-%d-%d-%d-%d-%d", + &ru_info[i].allocation, + &ru_info[i].aid, + &ru_info[i].ru_index, + &ru_info[i].rate, + &ru_info[i].ldpc, + &ru_info[i].nss, + &ru_info[i].start_sp_st, + &ru_info[i].mpdu_length, + &ru_info[i].alpha); + + if (input_cnt < 0) { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("Invalid format, %s ignored!\n", arg)); + goto err_out; + } else if (strlen(value) > 0 && input_cnt == 9) { + ru_info[i].valid = TRUE; + + if (ru_info[i].mpdu_length == 0) + ru_info[i].mpdu_length = + CONFIG_GET_PARAM(serv_test, + tx_len, + band_idx); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: segment[%d]: alloc:%04x\n", + __func__, (ru_info[i].ru_index & 0x1), + ru_info[i].allocation)); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s:\t\t\tru_idx:%d, length:%d,\n", + __func__, (ru_info[i].ru_index >> 1), + ru_info[i].mpdu_length)); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s:\t\t\talpha:%d, rate:0x%x,\n", + __func__, ru_info[i].alpha, + ru_info[i].rate)); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: \t\t\tldpc:%d, nss:%d\n", + __func__, ru_info[i].ldpc, + ru_info[i].nss)); + } else { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("Invalid format, %s ignored!\n", arg)); + goto err_out; + } + } + + ret = SERV_STATUS_SUCCESS; + } + +err_out: + return ret; +} + +s_int32 mt_agent_set_txant(struct service_test *serv_test, u_char *arg) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_int32 value = 0; + struct hqa_frame *hqa_cmd = &hqa_cmd_frame; + u_char *data = hqa_cmd->data; + u_long str2value = 0; + + sys_ad_zero_mem(hqa_cmd, sizeof(*hqa_cmd)); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: TX PATH = %s\n", __func__, arg)); + + hqa_cmd->length = 2*sizeof(u_int32); + + if (kstrtol(arg, 10, &str2value) == 0) { + value = str2value; + set_param_and_shift_buf(TRUE, sizeof(u_int32), + (u_char *)&value, &data); + value = SERV_GET_PARAM(serv_test, ctrl_band_idx); + set_param_and_shift_buf(TRUE, sizeof(u_int32), + (u_char *)&value, &data); + hqa_set_tx_path(serv_test, hqa_cmd); + } else + ret = SERV_STATUS_AGENT_INVALID_PARAM; + + return ret; +} + +s_int32 mt_agent_set_rxant(struct service_test *serv_test, u_char *arg) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_int32 value = 0; + u_long str2value = 0; + struct hqa_frame *hqa_cmd = &hqa_cmd_frame; + u_char *data = hqa_cmd->data; + + sys_ad_zero_mem(hqa_cmd, sizeof(*hqa_cmd)); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: RX PATH = %s\n", __func__, arg)); + + hqa_cmd->length = 2*sizeof(u_int32); + + if (kstrtol(arg, 10, (long *)&str2value) == 0) { + value = str2value; + set_param_and_shift_buf(TRUE, sizeof(u_int32), + (u_char *)&value, &data); + value = SERV_GET_PARAM(serv_test, ctrl_band_idx); + set_param_and_shift_buf(TRUE, sizeof(u_int32), + (u_char *)&value, &data); + hqa_set_rx_path(serv_test, hqa_cmd); + } else + ret = SERV_STATUS_AGENT_INVALID_PARAM; + + return ret; +} + +static struct agent_cli_set_ext_handler cli_set_ext_cmds[] = { + {"ATECTRLBANDIDX", mt_agent_set_ctrl_band}, + {"ATETXPOW0", mt_agent_set_pwr}, + {"ATECHANNEL", mt_agent_set_channel}, + {"ATETXBW", mt_agent_set_bw}, + {"ATERUINFO", mt_agent_set_ru_cli}, + {"ATETXANT", mt_agent_set_txant}, + {"ATERXANT", mt_agent_set_rxant}, + {"", NULL} /* the last entry */ +}; + +s_int32 mt_agent_cli_set_ext(u_char *name, struct service *serv, u_char *arg) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct agent_cli_set_ext_handler *entry = cli_set_ext_cmds; + + while (strlen(entry->name)) { + if (strcmp(name, entry->name) == 0) + ret = entry->handler( + (struct service_test *)serv->serv_handle, + arg); + + entry++; + } + + return ret; +} + +/***************************************************************************** + * Service init/exit handler + *****************************************************************************/ +s_int32 mt_agent_init_service(struct service *serv) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + switch (serv->serv_id) { + case SERV_HANDLE_TEST: + ret = mt_serv_init_test( + (struct service_test *)serv->serv_handle); + break; + + default: + return SERV_STATUS_AGENT_FAIL; + } + + return ret; +} + +s_int32 mt_agent_exit_service(struct service *serv) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + switch (serv->serv_id) { + case SERV_HANDLE_TEST: + ret = mt_serv_exit_test( + (struct service_test *)serv->serv_handle); + break; + + default: + return SERV_STATUS_AGENT_FAIL; + } + + return ret; +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/glue/hal/gen4m/operation_gen4m.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/glue/hal/gen4m/operation_gen4m.c new file mode 100644 index 0000000000000000000000000000000000000000..b48cdf342b94fbd823b48f7bd5eb25ca82d3d1b9 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/glue/hal/gen4m/operation_gen4m.c @@ -0,0 +1,2931 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#include "operation.h" + +#define CFG_WAIT_TSSI_READY 0 +extern s_int32 mt_engine_calc_phy( + struct test_ru_info *ru_info, + u_int32 apep_length, + u_int8 stbc, + u_int8 ltf_gi, + u_int8 max_tpe); + +union hetb_rx_cmm { + struct { + unsigned long long tigger_type:4; + unsigned long long ul_length:12; + unsigned long long cascade_ind:1; + unsigned long long cs_required:1; + unsigned long long ul_bw:2; + unsigned long long gi_ltf:2; + unsigned long long mimo_ltf:1; + unsigned long long ltf_sym_midiam:3; + unsigned long long stbc:1; + unsigned long long ldpc_extra_sym:1; + unsigned long long ap_tx_pwr:6; + unsigned long long t_pe:3; + unsigned long long spt_reuse:16; + unsigned long long doppler:1; + unsigned long long sig_a_reserved:9; + unsigned long long reserved:1; + } field; + unsigned long long cmm_info; +}; + +union hetb_tx_usr { + struct { + u_int32 aid:12; + u_int32 allocation:8; + u_int32 coding:1; + u_int32 mcs:4; + u_int32 dcm:1; + u_int32 ss_allocation:6; + } field; + u_int32 usr_info; +}; + +struct icap_dump_iq { + u_int32 wf_num; + u_int32 iq_type; + u_int32 icap_cnt; /*IQ Data Simple Count*/ + u_int32 icap_data_len; + u_int8 *picap_data; +}; + +/***************************************************************************** + * Enum value definition + *****************************************************************************/ +/* gen4m Function ID List */ +enum ENUM_RF_AT_FUNCID { + RF_AT_FUNCID_VERSION = 0, + RF_AT_FUNCID_COMMAND, + RF_AT_FUNCID_POWER, + RF_AT_FUNCID_RATE, + RF_AT_FUNCID_PREAMBLE, + RF_AT_FUNCID_ANTENNA, + RF_AT_FUNCID_PKTLEN, + RF_AT_FUNCID_PKTCNT, + RF_AT_FUNCID_PKTINTERVAL, + RF_AT_FUNCID_TEMP_COMPEN, + RF_AT_FUNCID_TXOPLIMIT, + RF_AT_FUNCID_ACKPOLICY, + RF_AT_FUNCID_PKTCONTENT, + RF_AT_FUNCID_RETRYLIMIT, + RF_AT_FUNCID_QUEUE, + RF_AT_FUNCID_BANDWIDTH, + RF_AT_FUNCID_GI, + RF_AT_FUNCID_STBC, + RF_AT_FUNCID_CHNL_FREQ, + RF_AT_FUNCID_RIFS, + RF_AT_FUNCID_TRSW_TYPE, + RF_AT_FUNCID_RF_SX_SHUTDOWN, + RF_AT_FUNCID_PLL_SHUTDOWN, + RF_AT_FUNCID_SLOW_CLK_MODE, + RF_AT_FUNCID_ADC_CLK_MODE, + RF_AT_FUNCID_MEASURE_MODE, + RF_AT_FUNCID_VOLT_COMPEN, + RF_AT_FUNCID_DPD_TX_GAIN, + RF_AT_FUNCID_DPD_MODE, + RF_AT_FUNCID_TSSI_MODE, + RF_AT_FUNCID_TX_GAIN_CODE, + RF_AT_FUNCID_TX_PWR_MODE, + + /* Query command */ + RF_AT_FUNCID_TXED_COUNT = 32, + RF_AT_FUNCID_TXOK_COUNT, + RF_AT_FUNCID_RXOK_COUNT, + RF_AT_FUNCID_RXERROR_COUNT, + RF_AT_FUNCID_RESULT_INFO, + RF_AT_FUNCID_TRX_IQ_RESULT, + RF_AT_FUNCID_TSSI_RESULT, + RF_AT_FUNCID_DPD_RESULT, + RF_AT_FUNCID_RXV_DUMP, + RF_AT_FUNCID_RX_PHY_STATIS, + RF_AT_FUNCID_MEASURE_RESULT, + RF_AT_FUNCID_TEMP_SENSOR, + RF_AT_FUNCID_VOLT_SENSOR, + RF_AT_FUNCID_READ_EFUSE, + RF_AT_FUNCID_RX_RSSI, + RF_AT_FUNCID_FW_INFO, + RF_AT_FUNCID_DRV_INFO, + RF_AT_FUNCID_PWR_DETECTOR, + RF_AT_FUNCID_WBRSSI_IBSSI, + + /* Set command */ + RF_AT_FUNCID_SET_DPD_RESULT = 64, + RF_AT_FUNCID_SET_CW_MODE, + RF_AT_FUNCID_SET_JAPAN_CH14_FILTER, + RF_AT_FUNCID_WRITE_EFUSE, + RF_AT_FUNCID_SET_MAC_ADDRESS, + RF_AT_FUNCID_SET_TA, + RF_AT_FUNCID_SET_RX_MATCH_RULE, + + /* 80211AC & Jmode */ + RF_AT_FUNCID_SET_CBW = 71, + RF_AT_FUNCID_SET_DBW, + RF_AT_FUNCID_SET_PRIMARY_CH, + RF_AT_FUNCID_SET_ENCODE_MODE, + RF_AT_FUNCID_SET_J_MODE, + + /* ICAP command */ + RF_AT_FUNCID_SET_ICAP_CONTENT = 80, + RF_AT_FUNCID_SET_ICAP_MODE, + RF_AT_FUNCID_SET_ICAP_STARTCAP, + RF_AT_FUNCID_SET_ICAP_SIZE = 83, + RF_AT_FUNCID_SET_ICAP_TRIGGER_OFFSET, + RF_AT_FUNCID_QUERY_ICAP_DUMP_FILE = 85, + + /* 2G 5G Band */ + RF_AT_FUNCID_SET_BAND = 90, + + /* Reset Counter */ + RF_AT_FUNCID_RESETTXRXCOUNTER = 91, + + /* FAGC RSSI Path */ + RF_AT_FUNCID_FAGC_RSSI_PATH = 92, + + /* Set RX Filter Packet Length */ + RF_AT_FUNCID_RX_FILTER_PKT_LEN = 93, + + /* Tone */ + RF_AT_FUNCID_SET_TONE_RF_GAIN = 96, + RF_AT_FUNCID_SET_TONE_DIGITAL_GAIN = 97, + RF_AT_FUNCID_SET_TONE_TYPE = 98, + RF_AT_FUNCID_SET_TONE_DC_OFFSET = 99, + RF_AT_FUNCID_SET_TONE_BW = 100, + + /* MT6632 Add */ + RF_AT_FUNCID_SET_MAC_HEADER = 101, + RF_AT_FUNCID_SET_SEQ_CTRL = 102, + RF_AT_FUNCID_SET_PAYLOAD = 103, + RF_AT_FUNCID_SET_DBDC_BAND_IDX = 104, + RF_AT_FUNCID_SET_BYPASS_CAL_STEP = 105, + + /* Set RX Path */ + RF_AT_FUNCID_SET_RX_PATH = 106, + + /* Set Frequency Offset */ + RF_AT_FUNCID_SET_FRWQ_OFFSET = 107, + + /* Get Frequency Offset */ + RF_AT_FUNCID_GET_FREQ_OFFSET = 108, + + /* Set RXV Debug Index */ + RF_AT_FUNCID_SET_RXV_INDEX = 109, + + /* Set Test Mode DBDC Enable */ + RF_AT_FUNCID_SET_DBDC_ENABLE = 110, + + /* Get Test Mode DBDC Enable */ + RF_AT_FUNCID_GET_DBDC_ENABLE = 111, + + /* Set ICAP Ring Capture */ + RF_AT_FUNCID_SET_ICAP_RING = 112, + + /* Set TX Path */ + RF_AT_FUNCID_SET_TX_PATH = 113, + + /* Set Nss */ + RF_AT_FUNCID_SET_NSS = 114, + + /* Set TX Antenna Mask */ + RF_AT_FUNCID_SET_ANTMASK = 115, + + /* TMR set command */ + RF_AT_FUNCID_SET_TMR_ROLE = 116, + RF_AT_FUNCID_SET_TMR_MODULE = 117, + RF_AT_FUNCID_SET_TMR_DBM = 118, + RF_AT_FUNCID_SET_TMR_ITER = 119, + + /* Set ADC For IRR Feature */ + RF_AT_FUNCID_SET_ADC = 120, + + /* Set RX Gain For IRR Feature */ + RF_AT_FUNCID_SET_RX_GAIN = 121, + + /* Set TTG For IRR Feature */ + RF_AT_FUNCID_SET_TTG = 122, + + /* Set TTG ON/OFF For IRR Feature */ + RF_AT_FUNCID_TTG_ON_OFF = 123, + + /* Set TSSI for QA Tool Setting */ + RF_AT_FUNCID_SET_TSSI = 124, + + /* Set Recal Cal Step */ + RF_AT_FUNCID_SET_RECAL_CAL_STEP = 125, + + /* Set iBF/eBF enable */ + RF_AT_FUNCID_SET_IBF_ENABLE = 126, + RF_AT_FUNCID_SET_EBF_ENABLE = 127, + + /* Set MPS Setting */ + RF_AT_FUNCID_SET_MPS_SIZE = 128, + RF_AT_FUNCID_SET_MPS_SEQ_DATA = 129, + RF_AT_FUNCID_SET_MPS_PAYLOAD_LEN = 130, + RF_AT_FUNCID_SET_MPS_PKT_CNT = 131, + RF_AT_FUNCID_SET_MPS_PWR_GAIN = 132, + RF_AT_FUNCID_SET_MPS_NSS = 133, + RF_AT_FUNCID_SET_MPS_PACKAGE_BW = 134, + + RF_AT_FUNCID_GET_CH_TX_PWR_OFFSET = 136, + /* Antenna swap feature*/ + RF_AT_FUNCID_SET_ANT_SWP = 153, + RF_AT_FUNCID_SET_RX_MU_AID = 157, + RF_AT_FUNCID_SET_TX_HE_TB_TTRCR0 = 158, + RF_AT_FUNCID_SET_TX_HE_TB_TTRCR1 = 159, + RF_AT_FUNCID_SET_TX_HE_TB_TTRCR2 = 160, + RF_AT_FUNCID_SET_TX_HE_TB_TTRCR3 = 161, + RF_AT_FUNCID_SET_TX_HE_TB_TTRCR4 = 162, + RF_AT_FUNCID_SET_TX_HE_TB_TTRCR5 = 163, + RF_AT_FUNCID_SET_TX_HE_TB_TTRCR6 = 164, + RF_AT_FUNCID_SET_SECURITY_MODE = 165, + RF_AT_FUNCID_SET_LP_MODE = 166, + + /* Set HW TX enable */ + RF_AT_FUNCID_SET_HWTX_MODE = 167 +}; + +/* Command */ +enum ENUM_RF_AT_COMMAND { + RF_AT_COMMAND_STOPTEST = 0, + RF_AT_COMMAND_STARTTX, + RF_AT_COMMAND_STARTRX, + RF_AT_COMMAND_RESET, + RF_AT_COMMAND_OUTPUT_POWER, /* Payload */ + /* Local freq is renamed to Local leakage */ + RF_AT_COMMAND_LO_LEAKAGE, + /* OFDM (LTF/STF), CCK (PI,PI/2) */ + RF_AT_COMMAND_CARRIER_SUPPR, + RF_AT_COMMAND_TRX_IQ_CAL, + RF_AT_COMMAND_TSSI_CAL, + RF_AT_COMMAND_DPD_CAL, + RF_AT_COMMAND_CW, + RF_AT_COMMAND_ICAP, + RF_AT_COMMAND_RDD, + RF_AT_COMMAND_CH_SWITCH_FOR_ICAP, + RF_AT_COMMAND_RESET_DUMP_NAME, + RF_AT_COMMAND_SINGLE_TONE, + RF_AT_COMMAND_RDD_OFF, + RF_AT_COMMAND_NUM +}; + +/* Preamble */ +enum ENUM_RF_AT_PREAMBLE { + RF_AT_PREAMBLE_NORMAL = 0, + RF_AT_PREAMBLE_CCK_SHORT, + RF_AT_PREAMBLE_11N_MM, + RF_AT_PREAMBLE_11N_GF, + RF_AT_PREAMBLE_11AC, + RF_AT_PREAMBLE_NUM +}; + +/* Ack Policy */ +enum ENUM_RF_AT_ACK_POLICY { + RF_AT_ACK_POLICY_NORMAL = 0, + RF_AT_ACK_POLICY_NOACK, + RF_AT_ACK_POLICY_NOEXPLICTACK, + RF_AT_ACK_POLICY_BLOCKACK, + RF_AT_ACK_POLICY_NUM +}; + +enum ENUM_RF_AUTOTEST_STATE { + RF_AUTOTEST_STATE_STANDBY = 0, + RF_AUTOTEST_STATE_TX, + RF_AUTOTEST_STATE_RX, + RF_AUTOTEST_STATE_RESET, + RF_AUTOTEST_STATE_OUTPUT_POWER, + RF_AUTOTEST_STATE_LOCA_FREQUENCY, + RF_AUTOTEST_STATE_CARRIER_SUPRRESION, + RF_AUTOTEST_STATE_NUM +}; + +enum { + ATE_LOG_RXV = 1, + ATE_LOG_RDD, + ATE_LOG_RE_CAL, + ATE_LOG_TYPE_NUM, + ATE_LOG_RXINFO, + ATE_LOG_TXDUMP, + ATE_LOG_TEST +}; + +enum { + ATE_LOG_OFF, + ATE_LOG_ON, + ATE_LOG_DUMP, + ATE_LOG_CTRL_NUM, +}; + +enum ENUM_ATE_CAP_TYPE { + /* I/Q Type */ + ATE_CAP_I_TYPE = 0, + ATE_CAP_Q_TYPE = 1, + ATE_NUM_OF_CAP_TYPE +}; +/***************************************************************************** + * Global Variable + *****************************************************************************/ +static struct hqa_m_rx_stat test_hqa_rx_stat; +static struct test_rx_stat_band_info backup_band0_info; +static struct test_rx_stat_band_info backup_band1_info; +static u_char g_tx_mode; + + + +static u_int32 tm_ch_num_to_freq(u_int32 ch_num) +{ + u_int32 ch_in_mhz; + + if (ch_num >= 1 && ch_num <= 13) + ch_in_mhz = 2412 + (ch_num - 1) * 5; + else if (ch_num == 14) + ch_in_mhz = 2484; + else if (ch_num == 133) + ch_in_mhz = 3665; /* 802.11y */ + else if (ch_num == 137) + ch_in_mhz = 3685; /* 802.11y */ + else if ((ch_num >= 34 && ch_num <= 181) + || (ch_num == 16)) + ch_in_mhz = 5000 + ch_num * 5; + else if (ch_num >= 182 && ch_num <= 196) + ch_in_mhz = 4000 + ch_num * 5; + else if (ch_num == 201) + ch_in_mhz = 2730; + else if (ch_num == 202) + ch_in_mhz = 2498; + else + ch_in_mhz = 0; + + return 1000 * ch_in_mhz; +} + +static u_int32 tm_bw_hqa_mapping_at(u_int32 bw) +{ + u_int32 bw_mapping = 0; + + /* BW Mapping in QA Tool + * 0: BW20 + * 1: BW40 + * 2: BW80 + * 3: BW10 + * 4: BW5 + * 5: BW160C + * 6: BW160NC + */ + /* BW Mapping in FW + * 0: BW20 + * 1: BW40 + * 2: BW80 + * 3: BW160C + * 4: BW160NC + * 5: BW5 + * 6: BW10 + */ + if (bw == 0) + bw_mapping = 0; + else if (bw == 1) + bw_mapping = 1; + else if (bw == 2) + bw_mapping = 2; + else if (bw == 3) + bw_mapping = 6; + else if (bw == 4) + bw_mapping = 5; + else if (bw == 5) + bw_mapping = 3; + else if (bw == 6) + bw_mapping = 4; + + return bw_mapping; +} + +static s_int32 tm_rftest_set_auto_test( + struct test_wlan_info *winfos, + u_int32 func_idx, + u_int32 func_data) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct param_mtk_wifi_test_struct rf_at_info; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + rf_at_info.func_idx = func_idx; + rf_at_info.func_data = func_data; + + ret = pr_oid_funcptr(winfos, /*call back to ServiceWlanOid*/ + OP_WLAN_OID_RFTEST_SET_AUTO_TEST, + &rf_at_info, + sizeof(rf_at_info), + NULL, + NULL); + + return ret; + +} + +static s_int32 tm_rftest_query_auto_test( + struct test_wlan_info *winfos, + struct param_mtk_wifi_test_struct *prf_at_info, + u_int32 *buf_len) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + ret = pr_oid_funcptr(winfos, /*call back to ServiceWlanOid*/ + OP_WLAN_OID_RFTEST_QUERY_AUTO_TEST, + prf_at_info, + sizeof(*prf_at_info), + NULL, + NULL); + + return ret; + +} + +static s_int32 tm_icap_mode( + struct test_wlan_info *winfos) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + ret = pr_oid_funcptr(winfos, /*call back to ServiceWlanOid*/ + OP_WLAN_OID_SET_TEST_ICAP_MODE, + NULL, + 0, + NULL, + NULL); + + SERV_LOG(SERV_DBG_CAT_MISC, SERV_DBG_LVL_WARN, + ("Switch ICAP Mode,ret=0x%08x\n", ret)); + + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_set_tr_mac( + struct test_wlan_info *winfos, + s_int32 op_type, boolean enable, u_char band_idx) +{ + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_set_tx_stream( + struct test_wlan_info *winfos, + u_int32 stream_nums, u_char band_idx) +{ + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_set_tx_path( + struct test_wlan_info *winfos, + u_char band_idx, + struct test_configuration *configs) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + ret = tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_DBDC_BAND_IDX, band_idx); + + ret = tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_TX_PATH, + (u_int32)configs->tx_ant); + + return ret; +} + +s_int32 mt_op_set_rx_path( + struct test_wlan_info *winfos, + u_char band_idx, + struct test_configuration *configs) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + u_int32 rx_ant = (u_int32)configs->rx_ant; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + ret = tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_DBDC_BAND_IDX, band_idx); + + rx_ant = ((rx_ant << 16) | (0 & BITS(0, 15))); + ret = tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_RX_PATH, + rx_ant); + + return ret; +} + +s_int32 mt_op_set_rx_filter( + struct test_wlan_info *winfos, struct rx_filter_ctrl rx_filter) +{ + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_set_clean_persta_txq( + struct test_wlan_info *winfos, + boolean sta_pause_enable, u_char omac_idx, u_char band_idx) +{ + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_set_cfg_on_off( + struct test_wlan_info *winfos, + u_int8 type, u_int8 enable, u_char band_idx) +{ + u_int32 func_index, func_data; + s_int32 ret = SERV_STATUS_SUCCESS; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + switch (type) { + case 0: /* TSSI */ + func_index = RF_AT_FUNCID_SET_TSSI; + break; + case 1: /* DPD */ + func_index = RF_AT_FUNCID_DPD_MODE; + break; + default: + ret = SERV_STATUS_HAL_OP_FAIL; + return ret; + } + + func_data = 0; + + if (enable == 0) + func_data &= ~BIT(0); + else + func_data |= BIT(0); + + if (band_idx == 0) + func_data &= ~BIT(1); + else + func_data |= BIT(1); + + ret = tm_rftest_set_auto_test( + winfos, func_index, func_data); + + return ret; +} + +s_int32 mt_op_log_on_off( + struct test_wlan_info *winfos, + u_char band_idx, + u_int32 log_type, + u_int32 log_ctrl, + u_int32 log_size) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct param_mtk_wifi_test_struct rf_at_info; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + u_int32 buf_len = 0; + u_int32 rxv; + s_int32 i, target_len = 0, max_dump_rxv_cnt = 500; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + if ((log_ctrl == ATE_LOG_DUMP) && (log_type == ATE_LOG_RXV)) { + rf_at_info.func_idx = RF_AT_FUNCID_RESULT_INFO; + rf_at_info.func_data = RF_AT_FUNCID_RXV_DUMP; + ret = tm_rftest_query_auto_test(winfos, + &rf_at_info, &buf_len); + if (ret == SERV_STATUS_SUCCESS) { + target_len = rf_at_info.func_data * 36; + if (target_len >= (max_dump_rxv_cnt * 36)) + target_len = (max_dump_rxv_cnt * 36); + } + + for (i = 0; i < target_len; i += 4) { + rf_at_info.func_idx = RF_AT_FUNCID_RXV_DUMP; + rf_at_info.func_data = i; + ret = tm_rftest_query_auto_test(winfos, + &rf_at_info, &buf_len); + + if (ret == SERV_STATUS_SUCCESS) { + rxv = rf_at_info.func_data; + if (i % 36 == 0) { + /* Todo */ + /* TOOL_PRINTLOG... */ + } + + if (((i % 36) / 4) + 1 == 9) { + /* Todo */ + /* TOOL_PRINTLOG... */ + } + } + + } + + /* TOOL_PRINTLOG(RFTEST, ERROR, "[LOG DUMP END]\n"); */ + } + + return ret; +} + +s_int32 mt_op_set_antenna_port( + struct test_wlan_info *winfos, + u_int8 rf_mode_mask, u_int8 rf_port_mask, u_int8 ant_port_mask) +{ + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_set_slot_time( + struct test_wlan_info *winfos, + u_int8 slot_time, u_int8 sifs_time, + u_int8 rifs_time, u_int16 eifs_time, u_char band_idx) +{ + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_set_power_drop_level( + struct test_wlan_info *winfos, + u_int8 pwr_drop_level, u_char band_idx) +{ + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_set_rx_filter_pkt_len( + struct test_wlan_info *winfos, + u_int8 enable, u_char band_idx, u_int32 rx_pkt_len) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + u_int32 func_data; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + func_data = rx_pkt_len & BITS(0, 23); + func_data |= (u_int32)(band_idx << 24); + + if (enable == 1) + func_data |= BIT(30); + else + func_data &= ~BIT(30); + + ret = tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_RX_FILTER_PKT_LEN, func_data); + + return ret; +} + +s_int32 mt_op_get_antswap_capability( + struct test_wlan_info *winfos, + u_int32 *antswap_support) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + ret = pr_oid_funcptr(winfos, /*call back to ServiceWlanOid*/ + OP_WLAN_OID_GET_ANTSWAP_CAPBILITY, + NULL, + 0, + antswap_support, + NULL); + + return ret; +} + +s_int32 mt_op_set_antswap( + struct test_wlan_info *winfos, + u_int32 ant) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + ret = tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_ANT_SWP, ant); + + return ret; +} + +s_int32 mt_op_set_freq_offset( + struct test_wlan_info *winfos, + u_int32 freq_offset, u_char band_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + ret = tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_FRWQ_OFFSET, freq_offset); + + return ret; +} + +s_int32 mt_op_set_phy_counter( + struct test_wlan_info *winfos, + s_int32 control, u_char band_idx) +{ + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_set_rxv_index( + struct test_wlan_info *winfos, + u_int8 group_1, u_int8 group_2, u_char band_idx) +{ + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_set_fagc_path( + struct test_wlan_info *winfos, + u_int8 path, u_char band_idx) +{ + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_set_fw_mode( + struct test_wlan_info *winfos, u_char fw_mode) +{ + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_set_rf_test_mode( + struct test_wlan_info *winfos, + u_int32 op_mode, u_int8 icap_len, u_int16 rsp_len) +{ + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_set_test_mode_start( + struct test_wlan_info *winfos) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + ret = pr_oid_funcptr(winfos, /*call back to ServiceWlanOid*/ + OP_WLAN_OID_SET_TEST_MODE_START, + NULL, + 0, + NULL, + NULL); + + return ret; +} + +s_int32 mt_op_set_test_mode_abort( + struct test_wlan_info *winfos) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + ret = pr_oid_funcptr(winfos, /*call back to ServiceWlanOid*/ + OP_WLAN_OID_SET_TEST_MODE_ABORT, + NULL, + 0, + NULL, + NULL); + + return ret; +} + +s_int32 mt_op_backup_and_set_cr( + struct test_wlan_info *winfos, + struct test_bk_cr *bks, + u_char band_idx) +{ + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_restore_cr( + struct test_wlan_info *winfos, + struct test_bk_cr *bks, + u_char band_idx) +{ + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_set_ampdu_ba_limit( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_int8 agg_limit) +{ + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_set_sta_pause_cr( + struct test_wlan_info *winfos) +{ + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_set_ifs_cr( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_char band_idx) +{ + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_write_mac_bbp_reg( + struct test_wlan_info *winfos, + struct test_register *regs) +{ + struct param_custom_mcr_rw_struct mcr_info; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + s_int32 ret = SERV_STATUS_SUCCESS; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + mcr_info.mcr_offset = regs->cr_addr; + mcr_info.mcr_data = *regs->cr_val; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: cr_val=0x%08x\n", + __func__, *regs->cr_val)); + + ret = pr_oid_funcptr(winfos, /*call back to ServiceWlanOid*/ + OP_WLAN_OID_SET_MCR_WRITE, + &mcr_info, + sizeof(mcr_info), + NULL, + NULL); + + return ret; +} + +s_int32 mt_op_read_bulk_mac_bbp_reg( + struct test_wlan_info *winfos, + struct test_register *regs) +{ + struct param_custom_mcr_rw_struct mcr_info; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + u_int32 idx; + s_int32 ret = SERV_STATUS_SUCCESS; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + for (idx = 0; idx < regs->cr_num ; idx++) { + mcr_info.mcr_offset = regs->cr_addr + idx * 4; + mcr_info.mcr_data = 0; + + ret = pr_oid_funcptr(winfos, /*call back to ServiceWlanOid*/ + OP_WLAN_OID_QUERY_MCR_READ, + &mcr_info, + sizeof(mcr_info), + NULL, + NULL); + + if (ret == SERV_STATUS_SUCCESS) { + *regs->cr_val = mcr_info.mcr_data; + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: cr_val=0x%08x\n", + __func__, *regs->cr_val)); + } else { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: read fail ret = %d\n", + __func__, ret)); + } + } + + return ret; +} + +s_int32 mt_op_read_bulk_rf_reg( + struct test_wlan_info *winfos, + struct test_register *regs) +{ + struct param_custom_mcr_rw_struct mcr_info; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + u_int32 idx; + s_int32 ret = SERV_STATUS_SUCCESS; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + if (regs->wf_sel == 0) + regs->cr_addr = regs->cr_addr | 0x99900000; + else if (regs->wf_sel == 1) + regs->cr_addr = regs->cr_addr | 0x99910000; + + for (idx = 0; idx < regs->cr_num; idx++) { + mcr_info.mcr_offset = regs->cr_addr + idx * 4; + mcr_info.mcr_data = 0; + + ret = pr_oid_funcptr(winfos, /*call back to ServiceWlanOid*/ + OP_WLAN_OID_QUERY_MCR_READ, + &mcr_info, + sizeof(mcr_info), + NULL, + NULL); + + if (ret == SERV_STATUS_SUCCESS) { + *regs->cr_val = mcr_info.mcr_data; + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: cr_val=0x%08x\n", + __func__, *regs->cr_val)); + } else { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: read fail ret = %d\n", + __func__, ret)); + } + } + + return ret; +} + +s_int32 mt_op_write_bulk_rf_reg( + struct test_wlan_info *winfos, + struct test_register *regs) +{ + struct param_custom_mcr_rw_struct mcr_info; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + s_int32 ret = SERV_STATUS_SUCCESS; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + if (regs->wf_sel == 0) + regs->cr_addr = regs->cr_addr | 0x99900000; + else if (regs->wf_sel == 1) + regs->cr_addr = regs->cr_addr | 0x99910000; + + mcr_info.mcr_offset = regs->cr_addr; + mcr_info.mcr_data = *regs->cr_val; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: cr_val=0x%08x\n", + __func__, *regs->cr_val)); + + ret = pr_oid_funcptr(winfos, /*call back to ServiceWlanOid*/ + OP_WLAN_OID_SET_MCR_WRITE, + &mcr_info, + sizeof(mcr_info), + NULL, + NULL); + + return ret; +} + +s_int32 mt_op_read_bulk_eeprom( + struct test_wlan_info *winfos, + struct test_eeprom *eprms) +{ +#if 0 + struct param_custom_mcr_rw_struct mcr_info; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + u_int32 idx; + s_int32 ret = SERV_STATUS_SUCCESS; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + for (idx = 0; idx < eprms->length; idx++) { + mcr_info.mcr_offset = eprms->offset + idx * 4; + mcr_info.mcr_data = 0; + + ret = pr_oid_funcptr(winfos, /*call back to ServiceWlanOid*/ + OP_WLAN_OID_QUERY_MCR_READ, + &mcr_info, + sizeof(mcr_info), + NULL, + NULL); + } +#endif + return SERV_STATUS_SUCCESS; +} + +static void mt_op_set_manual_he_tb_value( + struct test_wlan_info *winfos, + struct test_ru_info *ru_sta, + struct test_configuration *configs) +{ + union hetb_rx_cmm cmm; + union hetb_tx_usr usr; + u_int8 ltf_sym_code[] = { + 0, 0, 1, 2, 2, 3, 3, 4, 4 /* SS 1~8 */ + }; + + /* setup MAC start */ + /* step 1, common info of TF */ + sys_ad_zero_mem(&cmm, sizeof(cmm)); + cmm.field.sig_a_reserved = 0x1ff; + cmm.field.ul_length = ru_sta->l_len; + cmm.field.t_pe = + (ru_sta->afactor_init & 0x3) | ((ru_sta->pe_disamb & 0x1) << 2); + cmm.field.ldpc_extra_sym = ru_sta->ldpc_extr_sym; + if (configs->stbc && ru_sta->nss == 1) + cmm.field.ltf_sym_midiam = ltf_sym_code[ru_sta->nss+1]; + else + cmm.field.ltf_sym_midiam = ltf_sym_code[ru_sta->nss]; + cmm.field.gi_ltf = configs->sgi; + cmm.field.ul_bw = configs->bw; + cmm.field.stbc = configs->stbc; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: [TF TTRCR0 ] tigger_type:0x%x,\n", + __func__, cmm.field.tigger_type)); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("ul_length:0x%x cascade_ind:0x%x,\n", + cmm.field.ul_length, cmm.field.cascade_ind)); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("cs_required:0x%x, ul_bw:0x%x,\n", + cmm.field.cs_required, cmm.field.ul_bw)); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("gi_ltf:0x%x, mimo_ltf:0x%x,\n", + cmm.field.gi_ltf, cmm.field.mimo_ltf)); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("ltf_sym_midiam:0x%x, stbc:0x%x,\n", + cmm.field.ltf_sym_midiam, cmm.field.stbc)); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("ldpc_extra_sym :0x%x, ap_tx_pwr: 0x%x\n", + cmm.field.ldpc_extra_sym, cmm.field.ap_tx_pwr)); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: [TF TTRCR0 ] cr_value:0x%08x\n", + __func__, (u_int32)(cmm.cmm_info & 0xffffffff))); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: [TF TTRCR1 ] cr_value:0x%08x\n", + __func__, (u_int32)((cmm.cmm_info & 0xffffffff00000000) >> 32))); + + /* step 1, users info */ + sys_ad_zero_mem(&usr, sizeof(usr)); + usr.field.aid = 0x1; + usr.field.allocation = ru_sta->ru_index; + usr.field.coding = ru_sta->ldpc; + usr.field.mcs = ru_sta->rate & ~BIT(5); + usr.field.dcm = (ru_sta->rate & BIT(5)) >> 4; + usr.field.ss_allocation = + ((ru_sta->nss-1) << 3) | (ru_sta->start_sp_st & 0x7); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: [TF TTRCR2 ] aid:%d\n", + __func__, usr.field.aid)); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("allocation:%d, coding:%d,\n", + usr.field.allocation, usr.field.coding)); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("mcs:0x%x, dcm:%d,\n", + usr.field.mcs, usr.field.dcm)); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("ss_allocation:%d\n", + usr.field.ss_allocation)); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: [TF TTRCR2 ] cr_value:0x%08x\n", + __func__, usr.usr_info)); + + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_TX_HE_TB_TTRCR0, + (cmm.cmm_info & 0xffffffff)); + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_TX_HE_TB_TTRCR1, + ((cmm.cmm_info & 0xffffffff00000000) >> 32)); + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_TX_HE_TB_TTRCR2, usr.usr_info); + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_TX_HE_TB_TTRCR3, 0x7f); + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_TX_HE_TB_TTRCR4, 0xffffffff); + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_TX_HE_TB_TTRCR5, 0xffffffff); + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_TX_HE_TB_TTRCR6, 0xffffffff); + +} + +s_int32 mt_op_start_tx( + struct test_wlan_info *winfos, + u_char band_idx, + struct test_configuration *configs) +{ + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + u_char tx_pwr = configs->tx_pwr[configs->nss]; + u_int32 aifs = configs->ipg_param.ipg; + u_int32 pkt_cnt = configs->tx_stat.tx_cnt; + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_ru_info *ru_sta = &configs->ru_info_list[0]; + struct param_mtk_wifi_test_struct rf_at_info; + u_int32 tx_cnt = 0, buf_len = 0; +#if (CFG_WAIT_TSSI_READY == 1) + u_char i; +#endif + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_DBDC_BAND_IDX, band_idx); + + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_PKTCNT, pkt_cnt); + + if (configs->tx_mode == TEST_MODE_OFDM) { + configs->tx_mode = TEST_MODE_CCK; + configs->mcs += 4; + } else if ((configs->tx_mode == TEST_MODE_CCK) + && ((configs->mcs == 9) + || (configs->mcs == 10) || (configs->mcs == 11))) + configs->tx_mode = TEST_MODE_OFDM; + + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_PREAMBLE, configs->tx_mode); + + if (configs->tx_mode == TEST_MODE_CCK) { + configs->mcs |= 0x00000000; + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_RATE, configs->mcs); + } else if (configs->tx_mode == TEST_MODE_OFDM) { + if (configs->mcs == 9) + configs->mcs = 1; + else if (configs->mcs == 10) + configs->mcs = 2; + else if (configs->mcs == 11) + configs->mcs = 3; + configs->mcs |= 0x00000000; + + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_RATE, configs->mcs); + } else if (configs->tx_mode >= TEST_MODE_HTMIX && + configs->tx_mode <= TEST_MODE_HE_TB) { + + if (configs->tx_mode == TEST_MODE_HE_TB) { + /*do ru operation*/ + if (ru_sta->valid) { + /*Calculate HE TB PHY Info*/ + mt_engine_calc_phy(ru_sta, + ru_sta->mpdu_length+13, + configs->stbc, + configs->sgi, + configs->max_pkt_ext); + + configs->dmnt_ru_idx = 0; + + /*Replace the mcs/nss/ldpc/mpdu_len setting*/ + configs->mcs = ru_sta->rate; + configs->nss = ru_sta->nss; + configs->ldpc = ru_sta->ldpc; + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_PKTLEN, ru_sta->mpdu_length); + + /*Do Calc Manual HE TB TX*/ + mt_op_set_manual_he_tb_value(winfos, + ru_sta, configs); + } + } + configs->mcs |= 0x80000000; + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_RATE, configs->mcs); + } + + if (tx_pwr > 0x3F) + tx_pwr += 128; + + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_POWER, tx_pwr); + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_STBC, (u_int32)configs->stbc); + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_ENCODE_MODE, (u_int32)configs->ldpc); + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_IBF_ENABLE, (u_int32)configs->ibf); + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_EBF_ENABLE, (u_int32)configs->ebf); + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_PKTINTERVAL, aifs); + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_GI, configs->sgi); + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_NSS, configs->nss); + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_HWTX_MODE, winfos->hw_tx_enable); + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_COMMAND, RF_AT_COMMAND_STARTTX); + + /* For production line test, get tx count for wait calibration ready */ +#if (CFG_WAIT_TSSI_READY == 1) + for (i = 0; i < 100; i++) { +#endif + if (band_idx == TEST_DBDC_BAND0) + rf_at_info.func_idx = RF_AT_FUNCID_TXED_COUNT; + else + rf_at_info.func_idx = RF_AT_FUNCID_TXED_COUNT | BIT(8); + + rf_at_info.func_data = 0; + ret = tm_rftest_query_auto_test(winfos, + &rf_at_info, &buf_len); + if (ret == SERV_STATUS_SUCCESS) + tx_cnt = rf_at_info.func_data; + +#if (CFG_WAIT_TSSI_READY == 1) + /* For production line test, + * get tx count 16 for wait tssi ready + */ + if (tx_cnt >= 16) + break; + + msleep(20); + } +#endif + + + return ret; +} + +s_int32 mt_op_stop_tx( + struct test_wlan_info *winfos, + u_char band_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_DBDC_BAND_IDX, band_idx); + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_COMMAND, RF_AT_COMMAND_STOPTEST); + + return ret; +} + +s_int32 mt_op_start_rx( + struct test_wlan_info *winfos, + u_char band_idx, + struct test_configuration *configs) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + u_int32 func_data; + struct param_mtk_wifi_test_struct rf_at_info; + u_int32 buf_len = 0; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + /* Clear rx statistics backup buffer */ + if (band_idx == 0) { + sys_ad_zero_mem(&backup_band0_info, + sizeof(struct test_rx_stat_band_info)); + } else { + sys_ad_zero_mem(&backup_band1_info, + sizeof(struct test_rx_stat_band_info)); + } + + if (configs->tx_mode == TEST_MODE_HE_MU) { + if (configs->mu_rx_aid) + ret = tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_RX_MU_AID, + configs->mu_rx_aid); + else + ret = tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_RX_MU_AID, + 0xf800);/* 0xf800 to disable */ + } + + sys_ad_move_mem(&func_data, configs->own_mac, 4); + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_TA, func_data); + + func_data = 0; + sys_ad_move_mem(&func_data, configs->own_mac + 4, 2); + tm_rftest_set_auto_test(winfos, + (RF_AT_FUNCID_SET_TA | BIT(18)), func_data); + + ret = tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_DBDC_BAND_IDX, band_idx); + ret = tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_COMMAND, RF_AT_COMMAND_STARTRX); + + /* For production line test, get tx count for wait calibration ready */ + rf_at_info.func_idx = RF_AT_FUNCID_TXED_COUNT; + rf_at_info.func_data = 0; + ret = tm_rftest_query_auto_test(winfos, + &rf_at_info, &buf_len); + + return ret; +} + +s_int32 mt_op_stop_rx( + struct test_wlan_info *winfos, + u_char band_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_DBDC_BAND_IDX, band_idx); + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_COMMAND, RF_AT_COMMAND_STOPTEST); + + return ret; +} + +s_int32 mt_op_set_channel( + struct test_wlan_info *winfos, + u_char band_idx, + struct test_configuration *configs) +{ + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + u_char central_ch0 = configs->channel; + u_char central_ch1 = configs->channel_2nd; + u_char sys_bw = configs->bw; + u_char per_pkt_bw = configs->per_pkt_bw; + u_char ch_band = configs->ch_band; + u_char pri_sel = configs->pri_sel; + s_int32 SetFreq = 0; + s_int32 ret = SERV_STATUS_SUCCESS; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + /* For POR Cal Setting - 20160601 */ + if ((central_ch0 == central_ch1) && + (sys_bw == 6) && (per_pkt_bw == 6)) { + return ret; + } + + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_DBDC_BAND_IDX, band_idx); + + if ((central_ch0 >= 7 && central_ch0 <= 16) && ch_band == 1) { + /*Ch7 - Ch12, 5G (5035-5060) ch_band: 0:2.4G 1:5G */ + SetFreq = 1000 * (5000 + central_ch0 * 5); + } else if (central_ch0 == 6 && ch_band == 1) { + SetFreq = 1000 * 5032; + } else { + SetFreq = tm_ch_num_to_freq((u_int32)central_ch0); + } + + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_CHNL_FREQ, SetFreq); + + if (sys_bw == 6) { + SetFreq = tm_ch_num_to_freq((u_int32)central_ch1); + tm_rftest_set_auto_test(winfos, + (RF_AT_FUNCID_CHNL_FREQ | BIT(16)), SetFreq); + } + + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_CBW, + tm_bw_hqa_mapping_at((u_int32)sys_bw)); + + /* For POR Cal Setting - 20160601 */ + if ((sys_bw == 6) && (per_pkt_bw == 6)) + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_DBW, tm_bw_hqa_mapping_at(5)); + else { + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_DBW, + tm_bw_hqa_mapping_at((u_int32)per_pkt_bw)); + } + + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_PRIMARY_CH, pri_sel); + + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_BAND, ch_band); + + return ret; +} + +s_int32 mt_op_set_tx_content( + struct test_wlan_info *winfos, + u_char band_idx, + struct test_configuration *configs) +{ + struct serv_hdr_802_11 *phdr = NULL; + u_int32 func_data; + u_int16 fc_16; + u_int32 fc, dur, seq; + u_int32 gen_payload_rule = configs->fixed_payload; + u_int32 pay_load = configs->payload[0]; + u_int32 tx_len = configs->tx_len; + s_int32 ret = SERV_STATUS_SUCCESS; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + phdr = (struct serv_hdr_802_11 *)&configs->template_frame[0]; + sys_ad_move_mem(&fc_16, &phdr->fc, sizeof(fc_16)); + fc = (u_int32)fc_16; + dur = (u_int32)phdr->duration; + seq = (u_int32)phdr->sequence; + + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_DBDC_BAND_IDX, band_idx); + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_MAC_HEADER, + (fc | (dur << 16))); + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_SEQ_CTRL, seq); + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_PAYLOAD, + ((gen_payload_rule << 16) | pay_load)); + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_PKTLEN, tx_len); + + + sys_ad_move_mem(&func_data, configs->addr1[0], 4); + + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_MAC_ADDRESS, func_data); + + func_data = 0; + sys_ad_move_mem(&func_data, configs->addr1[0] + 4, 2); + tm_rftest_set_auto_test(winfos, + (RF_AT_FUNCID_SET_MAC_ADDRESS | BIT(18)), + func_data); + + sys_ad_move_mem(&func_data, configs->addr2[0], 4); + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_TA, func_data); + + func_data = 0; + sys_ad_move_mem(&func_data, configs->addr2[0] + 4, 2); + tm_rftest_set_auto_test(winfos, + (RF_AT_FUNCID_SET_TA | BIT(18)), func_data); + + return ret; +} + +s_int32 mt_op_set_preamble( + struct test_wlan_info *winfos, + u_char mode) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + g_tx_mode = mode; + + if (mode == TEST_MODE_OFDM) + mode = TEST_MODE_CCK; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: tx mode = %d\n", + __func__, mode)); + + ret = tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_PREAMBLE, mode); + + return ret; +} + +s_int32 mt_op_set_rate( + struct test_wlan_info *winfos, + u_char mcs) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + if (g_tx_mode == TEST_MODE_OFDM) { + g_tx_mode = TEST_MODE_CCK; + mcs += 4; + } + + if (g_tx_mode == TEST_MODE_CCK) + mcs |= 0x00000000; + else if (g_tx_mode == TEST_MODE_OFDM) { + if (mcs == 9) + mcs = 1; + else if (mcs == 10) + mcs = 2; + else if (mcs == 11) + mcs = 3; + mcs |= 0x00000000; + } else if (g_tx_mode >= TEST_MODE_HTMIX && + g_tx_mode <= TEST_MODE_HE_TB) + mcs |= 0x80000000; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: mcs = %d\n", + __func__, mcs)); + + ret = tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_RATE, mcs); + + return ret; +} + +s_int32 mt_op_set_system_bw( + struct test_wlan_info *winfos, + u_char sys_bw) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + ret = tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_CBW, + tm_bw_hqa_mapping_at((u_int32)sys_bw)); + + return ret; +} + +s_int32 mt_op_set_per_pkt_bw( + struct test_wlan_info *winfos, + u_char per_pkt_bw) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + ret = tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_DBW, + tm_bw_hqa_mapping_at((u_int32)per_pkt_bw)); + + return ret; +} + +s_int32 mt_op_reset_txrx_counter( + struct test_wlan_info *winfos) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + ret = tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_RESETTXRXCOUNTER, 0); + + return ret; +} + +s_int32 mt_op_set_rx_vector_idx( + struct test_wlan_info *winfos, + u_char band_idx, + u_int32 group1, + u_int32 group2) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + u_int32 func_data; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + func_data = group1; + func_data |= (group2 << 8); + func_data |= (u_int32)(band_idx << 16); + + ret = tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_RXV_INDEX, func_data); + + return ret; +} + +s_int32 mt_op_get_rx_stat_leg( + struct test_wlan_info *winfos, + struct test_rx_stat_leg *rx_stat) +{ + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_set_fagc_rssi_path( + struct test_wlan_info *winfos, + u_char band_idx, + u_int32 fagc_path) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + u_int32 func_data; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + func_data = (u_int32)(band_idx << 16) | (fagc_path & BITS(0, 15)); + + ret = tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_FAGC_RSSI_PATH, func_data); + + return ret; +} + +s_int32 mt_op_dbdc_tx_tone( + struct test_wlan_info *winfos, + u_char band_idx, + struct test_configuration *configs) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + u_int32 func_data; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + /* + * Select TX Antenna + * RF_Power: (1db) 0~15 + * Digi_Power: (0.25db) -32~31 + */ + func_data = (u_int32)configs->ant_idx << 16 | configs->rf_pwr; + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_TONE_RF_GAIN, func_data); + func_data = (u_int32)configs->ant_idx << 16 | configs->digi_pwr; + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_TONE_DIGITAL_GAIN, func_data); + + /* DBDC Band Index : Band0, Band1 */ + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_DBDC_BAND_IDX, band_idx); + + if (configs->tx_tone_en) { + /* Band : 2.4G/5G */ + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_BAND, + (u_int32)configs->ch_band); + + /* ToneType : Single or Two */ + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_TONE_TYPE, + (u_int32)configs->tone_type); + + /* ToneFreq: DC/5M/10M/20M/40M */ + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_TONE_BW, + configs->tone_freq); + + /* DC Offset I, DC Offset Q */ + func_data = (configs->dc_offset_Q << 16) | + configs->dc_offset_I; + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_TONE_DC_OFFSET, + func_data); + + /* Control TX Tone Start and Stop */ + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_COMMAND, + RF_AT_COMMAND_SINGLE_TONE); + } else { + /* Control TX Tone Start and Stop */ + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_COMMAND, RF_AT_COMMAND_STOPTEST); + } + + return ret; +} + +s_int32 mt_op_dbdc_tx_tone_pwr( + struct test_wlan_info *winfos, + u_char band_idx, + struct test_configuration *configs) +{ + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_dbdc_continuous_tx( + struct test_wlan_info *winfos, + u_char band_idx, + struct test_configuration *configs) +{ + s_int32 SetFreq = 0; + s_int32 ret = SERV_STATUS_SUCCESS; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + u_int32 tx_mode = configs->tx_mode; + u_int32 rate = configs->rate; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + if (configs->tx_tone_en) { + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_DBDC_BAND_IDX, + (u_int32)band_idx); + + SetFreq = tm_ch_num_to_freq(configs->channel); + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_CHNL_FREQ, SetFreq); + + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_PRIMARY_CH, + configs->pri_sel); + + if (tx_mode == 1) { + tx_mode = 0; + rate += 4; + } else if ((tx_mode == 0) && + ((rate == 9) || (rate == 10) || (rate == 11))) + tx_mode = 1; + + ret = tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_PREAMBLE, tx_mode); + + if (tx_mode == 0) { + rate |= 0x00000000; + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_RATE, rate); + } else if (tx_mode == 1) { + if (rate == 9) + rate = 1; + else if (rate == 10) + rate = 2; + else if (rate == 11) + rate = 3; + rate |= 0x00000000; + + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_RATE, rate); + } else if (tx_mode >= 2 && tx_mode <= 4) { + rate |= 0x80000000; + + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_RATE, rate); + } + + ret = tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_CBW, + tm_bw_hqa_mapping_at((u_int32)configs->bw)); + + ret = tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_CW_MODE, + configs->tx_fd_mode); + + if (ret != SERV_STATUS_SUCCESS) + return SERV_STATUS_HAL_OP_FAIL; + + ret = tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_ANTMASK, + (u_int32)configs->ant_mask); + + if (ret != SERV_STATUS_SUCCESS) + return SERV_STATUS_HAL_OP_FAIL; + + ret = tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_COMMAND, RF_AT_COMMAND_CW); + if (ret != SERV_STATUS_SUCCESS) + return SERV_STATUS_HAL_OP_FAIL; + + } else { + ret = tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_COMMAND, + RF_AT_COMMAND_STOPTEST); + + if (ret != SERV_STATUS_SUCCESS) + return SERV_STATUS_HAL_OP_FAIL; + } + return ret; +} + +s_int32 mt_op_get_tx_info( + struct test_wlan_info *winfos, + struct test_configuration *test_configs_band0, + struct test_configuration *test_configs_band1) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct param_mtk_wifi_test_struct rf_at_info; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + u_int32 buf_len = 0; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + rf_at_info.func_idx = RF_AT_FUNCID_TXED_COUNT; + rf_at_info.func_data = 0; + ret = tm_rftest_query_auto_test(winfos, + &rf_at_info, &buf_len); + if (ret == SERV_STATUS_SUCCESS) + test_configs_band0->tx_stat.tx_done_cnt = rf_at_info.func_data; + + rf_at_info.func_idx = RF_AT_FUNCID_TXED_COUNT | BIT(8); + rf_at_info.func_data = 0; + ret = tm_rftest_query_auto_test(winfos, + &rf_at_info, &buf_len); + if (ret == SERV_STATUS_SUCCESS) + test_configs_band1->tx_stat.tx_done_cnt = rf_at_info.func_data; + + return ret; +} + +s_int32 mt_op_get_rx_statistics_all( + struct test_wlan_info *winfos, + struct hqa_comm_rx_stat *hqa_rx_stat) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct param_custom_access_rx_stat rx_stat_test; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + rx_stat_test.seq_num = 0; + rx_stat_test.total_num = 72; + + ret = pr_oid_funcptr(winfos, /*call back to ServiceWlanOid*/ + OP_WLAN_OID_QUERY_RX_STATISTICS, + &rx_stat_test, + sizeof(rx_stat_test), + NULL, + hqa_rx_stat); + + return ret; +} + +s_int32 mt_op_get_capability( + struct test_wlan_info *winfos, + struct test_capability *capability) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + ret = pr_oid_funcptr(winfos, /*call back to ServiceWlanOid*/ + OP_WLAN_OID_GET_CAPABILITY, + NULL, + 0, + NULL, + capability); + + return ret; +} + +s_int32 mt_op_calibration_test_mode( + struct test_wlan_info *winfos, + u_char mode) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + if (mode == 2) + ret = tm_icap_mode(winfos); + + return ret; +} + +s_int32 mt_op_set_icap_start( + struct test_wlan_info *winfos, + u_int8 *data) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + struct test_struct_ext r_test_info; + struct hqa_rbist_cap_start *pr_rbist_info; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + pr_rbist_info = &(r_test_info.data.icap_info); + + /*copy icap start parameters*/ + sys_ad_move_mem(pr_rbist_info, + data, + sizeof(struct hqa_rbist_cap_start)); + + /*over write parameters for mobile setting*/ + pr_rbist_info->en_bit_width = 0; /* 0:32bit, 1:96bit, 2:128bit */ + pr_rbist_info->arch = 1; /*0:Support on-chip, 1:Support on-the fly*/ + pr_rbist_info->phy_idx = 0; + + SERV_LOG(SERV_DBG_CAT_MISC, SERV_DBG_LVL_WARN, + ("%s: en_bit_width = 0x%08x, arch = 0x%08x, phy_idx = 0x%08x\n", + __func__, + pr_rbist_info->en_bit_width, + pr_rbist_info->arch, + pr_rbist_info->phy_idx)); + + pr_rbist_info->emi_start_addr = + (u_int32) (winfos->emi_phy_base & 0xFFFFFFFF); + pr_rbist_info->emi_end_addr = + (u_int32) ((winfos->emi_phy_base + + winfos->emi_phy_size) & 0xFFFFFFFF); + pr_rbist_info->emi_msb_addr = 0; /*CONNAC 1.x useless*/ + + SERV_LOG(SERV_DBG_CAT_MISC, SERV_DBG_LVL_WARN, + ("%s: StartAddr=0x%08x,EndAddr=0x%08x,MsbAddr=0x%08x\n", + __func__, + pr_rbist_info->emi_start_addr, + pr_rbist_info->emi_end_addr, + pr_rbist_info->emi_msb_addr)); + + if (pr_rbist_info->trig == 1) { /*Start Capture data*/ + ret = pr_oid_funcptr(winfos, /*call back to ServiceWlanOid*/ + OP_WLAN_OID_SET_TEST_ICAP_START, + &r_test_info, + sizeof(r_test_info), + NULL, + NULL); + } else if (pr_rbist_info->trig == 0) { /*don't Capture data*/ + ret = pr_oid_funcptr(winfos, /*call back to ServiceWlanOid*/ + OP_WLAN_OID_SET_TEST_ICAP_ABORT, + &r_test_info, + sizeof(r_test_info), + NULL, + NULL); + } + + SERV_LOG(SERV_DBG_CAT_MISC, SERV_DBG_LVL_WARN, + ("Start ICAP trig:%d,node=0x%08x,ret=0x%08x\n", + pr_rbist_info->trig, + pr_rbist_info->cap_node, + ret)); + + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_get_icap_status( + struct test_wlan_info *winfos, + s_int32 *icap_stat) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + struct test_struct_ext r_test_info; + + ret = pr_oid_funcptr(winfos, /*call back to ServiceWlanOid*/ + OP_WLAN_OID_SET_TEST_ICAP_STATUS, + &r_test_info, + sizeof(r_test_info), + NULL, + icap_stat); + + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD; + + SERV_LOG(SERV_DBG_CAT_MISC, SERV_DBG_LVL_WARN, + ("Query Status ICAP %d, ret=0x%X\n", + *icap_stat, /*0:OK,1:WAITING,2:FAIL*/ + ret)); + + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_get_icap_max_data_len( + struct test_wlan_info *winfos, + u_long *max_data_len) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + + ret = pr_oid_funcptr(winfos, /*call back to ServiceWlanOid*/ + OP_WLAN_OID_GET_TEST_ICAP_MAX_DATA_LEN, + NULL, + 0, + NULL, + max_data_len); + + SERV_LOG(SERV_DBG_CAT_MISC, SERV_DBG_LVL_WARN, + ("ICAP max data len %lu", *max_data_len)); + + + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_get_icap_data( + struct test_wlan_info *winfos, + s_int32 *icap_cnt, + s_int32 *icap_data, + u_int32 wf_num, + u_int32 iq_type) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct icap_dump_iq r_dump_iq; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + + r_dump_iq.wf_num = wf_num; + r_dump_iq.iq_type = iq_type; + r_dump_iq.icap_cnt = 0; + r_dump_iq.icap_data_len = 0; + r_dump_iq.picap_data = (s_int8 *)icap_data; + + ret = pr_oid_funcptr(winfos, /*call back to ServiceWlanOid*/ + OP_WLAN_OID_GET_TEST_ICAP_DATA, + &r_dump_iq, + sizeof(r_dump_iq), + NULL, + NULL); + + if (ret == SERV_STATUS_SUCCESS) { + *icap_cnt = r_dump_iq.icap_cnt; + /*debug*/ + /*sys_ad_mem_dump32(icap_data, r_dump_iq.icap_data_len);*/ + } + + SERV_LOG(SERV_DBG_CAT_MISC, SERV_DBG_LVL_WARN, + ("ICAP:wf[%d][%c],cnt:%d,len:%d,data:0x%p,ret:0x%X\n", + r_dump_iq.wf_num, + (r_dump_iq.iq_type == ATE_CAP_I_TYPE)?'I':'Q', + *icap_cnt, + r_dump_iq.icap_data_len, + icap_data, + ret)); + + + return ret; +} + +s_int32 mt_op_do_cal_item( + struct test_wlan_info *winfos, + u_int32 item, + u_char band_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + ret = pr_oid_funcptr(winfos, /*call back to ServiceWlanOid*/ + OP_WLAN_OID_RESET_RECAL_COUNT, + NULL, + 0, + NULL, + NULL); + + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_DBDC_BAND_IDX, band_idx); + + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_RECAL_CAL_STEP, item); + + return ret; +} + +s_int32 mt_op_set_band_mode( + struct test_wlan_info *winfos, + struct test_band_state *band_state) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + u_int32 dbdc_enb; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + if (band_state->band_mode == TEST_BAND_MODE_DUAL) + dbdc_enb = TEST_DBDC_ENABLE; + else + dbdc_enb = TEST_DBDC_DISABLE; + + SET_TEST_DBDC(winfos, dbdc_enb); + + ret = tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_DBDC_ENABLE, dbdc_enb); + + return ret; +} + +s_int32 mt_op_get_chipid( + struct test_wlan_info *winfos) +{ + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_mps_start( + struct test_wlan_info *winfos, + u_char band_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_DBDC_BAND_IDX, band_idx); + + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_COMMAND, RF_AT_COMMAND_STARTTX); + + return ret; +} + +s_int32 mt_op_mps_set_nss( + struct test_wlan_info *winfos, + u_int32 len, + struct test_mps_setting *mps_setting) +{ + u_int32 i; + s_int32 ret = SERV_STATUS_SUCCESS; + + for (i = 0; i < len; i++) { + tm_rftest_set_auto_test(winfos, + (RF_AT_FUNCID_SET_MPS_NSS | (i << 16)), + mps_setting[i+1].nss); + } + + return ret; +} + +s_int32 mt_op_mps_set_per_packet_bw( + struct test_wlan_info *winfos, + u_int32 len, + struct test_mps_setting *mps_setting) +{ + u_int32 i; + s_int32 ret = SERV_STATUS_SUCCESS; + + for (i = 0; i < len; i++) { + tm_rftest_set_auto_test(winfos, + (RF_AT_FUNCID_SET_MPS_PACKAGE_BW | (i << 16)), + mps_setting[i+1].pkt_bw); + } + + return ret; +} + +s_int32 mt_op_mps_set_packet_count( + struct test_wlan_info *winfos, + u_int32 len, + struct test_mps_setting *mps_setting) +{ + u_int32 i; + s_int32 ret = SERV_STATUS_SUCCESS; + + for (i = 0; i < len; i++) { + tm_rftest_set_auto_test(winfos, + (RF_AT_FUNCID_SET_MPS_PKT_CNT | (i << 16)), + mps_setting[i+1].pkt_cnt); + } + + return ret; +} + +s_int32 mt_op_mps_set_payload_length( + struct test_wlan_info *winfos, + u_int32 len, + struct test_mps_setting *mps_setting) +{ + u_int32 i; + s_int32 ret = SERV_STATUS_SUCCESS; + + for (i = 0; i < len; i++) { + tm_rftest_set_auto_test(winfos, + (RF_AT_FUNCID_SET_MPS_PAYLOAD_LEN | (i << 16)), + mps_setting[i+1].pkt_len); + } + + return ret; +} + +s_int32 mt_op_mps_set_power_gain( + struct test_wlan_info *winfos, + u_int32 len, + struct test_mps_setting *mps_setting) +{ + u_int32 i; + s_int32 ret = SERV_STATUS_SUCCESS; + + for (i = 0; i < len; i++) { + tm_rftest_set_auto_test(winfos, + (RF_AT_FUNCID_SET_MPS_PWR_GAIN | (i << 16)), + mps_setting[i+1].pwr); + } + + return ret; +} + +s_int32 mt_op_mps_set_seq_data( + struct test_wlan_info *winfos, + u_int32 len, + struct test_mps_setting *mps_setting) +{ + u_int32 i; + u_int32 *mps_set = NULL; + u_int32 mode, mcs, tx_path; + s_int32 ret = SERV_STATUS_SUCCESS; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + + ret = sys_ad_alloc_mem((u_char **)&mps_set, sizeof(u_int32) * len); + + if (pr_oid_funcptr == NULL) { + sys_ad_free_mem(mps_set); + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + } + + for (i = 0; i < len; i++) { + mode = mps_setting[i+1].tx_mode; + mcs = mps_setting[i+1].mcs; + tx_path = mps_setting[i+1].tx_ant; + + if (mode == 1) { + mode = 0; + mcs += 4; + } else if ((mode == 0) && ((mcs == 9) || (mcs == 10) || + (mcs == 11))) { + mode = 1; + } + + if (mode == 0) { + mcs |= 0x00000000; + } else if (mode == 1) { + if (mcs == 9) + mcs = 1; + else if (mcs == 10) + mcs = 2; + else if (mcs == 11) + mcs = 3; + mcs |= 0x00000000; + } else if (mode >= 2 && mode <= 4) { + mcs |= 0x80000000; + } + + mps_set[i] = (mcs) | (tx_path << 8) | (mode << 24); + + } + + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_MPS_SIZE, len); + + for (i = 0; i < len; i++) { + tm_rftest_set_auto_test(winfos, + (RF_AT_FUNCID_SET_MPS_SEQ_DATA | (i << 16)), + mps_set[i]); + } + + sys_ad_free_mem(mps_set); + + return ret; +} + +s_int32 mt_op_get_tx_pwr( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_char band_idx, + u_char channel, + u_char ant_idx, + u_int32 *power) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + struct param_mtk_wifi_test_struct rf_at_info; + u_int32 buf_len = 0; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_DBDC_BAND_IDX, band_idx); + + rf_at_info.func_idx = RF_AT_FUNCID_GET_CH_TX_PWR_OFFSET; + rf_at_info.func_data = 0; + + ret = tm_rftest_query_auto_test(winfos, + &rf_at_info, &buf_len); + + if (ret == SERV_STATUS_SUCCESS) { + *power = rf_at_info.func_data; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: pwr:%u!\n", + __func__, *power)); + } else { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: fail!\n", + __func__)); + } + + return ret; +} + +s_int32 mt_op_set_tx_pwr( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_char band_idx, + struct test_txpwr_param *pwr_param) +{ + u_int32 Pwr = pwr_param->power; + s_int32 ret = SERV_STATUS_SUCCESS; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_DBDC_BAND_IDX, band_idx); + + if (Pwr > 0x3F) + Pwr += 128; + + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_POWER, Pwr); + + return ret; +} + +s_int32 mt_op_get_freq_offset( + struct test_wlan_info *winfos, + u_char band_idx, + u_int32 *freq_offset) +{ + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_get_cfg_on_off( + struct test_wlan_info *winfos, + u_char band_idx, + u_int32 type, + u_int32 *result) +{ + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_get_tx_tone_pwr( + struct test_wlan_info *winfos, + u_char band_idx, + u_int32 ant_idx, + u_int32 *power) +{ + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_reset_recal_cnt( + struct test_wlan_info *winfos +) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + ret = pr_oid_funcptr(winfos, /*call back to ServiceWlanOid*/ + OP_WLAN_OID_RESET_RECAL_COUNT, + NULL, + 0, + 0, + NULL); + + return ret; +} + +s_int32 mt_op_get_recal_cnt( + struct test_wlan_info *winfos, + u_int32 *recal_cnt, + u_int32 *recal_dw_num) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + + ret = pr_oid_funcptr(winfos, /*call back to ServiceWlanOid*/ + OP_WLAN_OID_GET_RECAL_COUNT, + NULL, + 0, + recal_cnt, + NULL); + + *recal_dw_num = 3; /* ncal_id, cal_addr, cal_value */ + + return ret; +} + +s_int32 mt_op_get_recal_content( + struct test_wlan_info *winfos, + u_int32 *content) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + ret = pr_oid_funcptr(winfos, /*call back to ServiceWlanOid*/ + OP_WLAN_OID_GET_RECAL_CONTENT, + NULL, + 0, + NULL, + content); + + return ret; +} + +s_int32 mt_op_get_rxv_cnt( + struct test_wlan_info *winfos, + u_int32 *rxv_cnt, + u_int32 *rxv_dw_num) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct param_mtk_wifi_test_struct rf_at_info; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + u_int32 buf_len = 0; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + rf_at_info.func_idx = RF_AT_FUNCID_RESULT_INFO; + rf_at_info.func_data = RF_AT_FUNCID_RXV_DUMP; + ret = tm_rftest_query_auto_test(winfos, + &rf_at_info, &buf_len); + + if (ret == SERV_STATUS_SUCCESS) { + if (rf_at_info.func_data > 56) + rf_at_info.func_data = 56; + + *rxv_cnt = rf_at_info.func_data; + *rxv_dw_num = 36; /* 9 cycle * 4 bytes = 36, 9 cycles */ + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: rxv_cnt = %d, rxv_dw_num = %d\n", + __func__, *rxv_cnt, *rxv_dw_num)); + } else { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: get rxv count fail ret = %d\n", + __func__, ret)); + + return ret; + } + + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_get_rxv_content( + struct test_wlan_info *winfos, + u_int32 dw_cnt, + u_int32 *content) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct param_mtk_wifi_test_struct rf_at_info; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + u_int32 i, buf_len = 0; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + for (i = 0; i < dw_cnt; i += 4) { + rf_at_info.func_idx = RF_AT_FUNCID_RXV_DUMP; + rf_at_info.func_data = i; + ret = tm_rftest_query_auto_test(winfos, + &rf_at_info, &buf_len); + + if (ret == SERV_STATUS_SUCCESS) { + *content = rf_at_info.func_data; + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: content[%d] = %x\n", + __func__, i, *content)); + } else { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: get rxv data fail ret = %d\n", + __func__, ret)); + + return ret; + } + } + + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_set_cal_bypass( + struct test_wlan_info *winfos, + u_char band_idx, + u_int32 cal_item) +{ + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_set_dpd( + struct test_wlan_info *winfos, + u_int32 on_off, + u_int32 wf_sel) +{ + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_set_tssi( + struct test_wlan_info *winfos, + u_int32 on_off, + u_int32 wf_sel) +{ + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_get_thermal_val( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_char band_idx, + u_int32 *value) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct param_mtk_wifi_test_struct rf_at_info; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + u_int32 buf_len = 0; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + rf_at_info.func_idx = RF_AT_FUNCID_TEMP_SENSOR; + rf_at_info.func_data = 0; + + ret = tm_rftest_query_auto_test(winfos, + &rf_at_info, &buf_len); + + if (ret == SERV_STATUS_SUCCESS) { + *value = rf_at_info.func_data; + *value = *value >> 16; + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: value = %x\n", + __func__, *value)); + } else { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: get thermal fail ret = %d\n", + __func__, ret)); + + return ret; + } + + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_set_rdd_test( + struct test_wlan_info *winfos, + u_int32 rdd_idx, + u_int32 rdd_sel, + u_int32 enable) +{ + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_set_off_ch_scan( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_char band_idx, + struct test_off_ch_param *param) +{ + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_get_rdd_cnt( + struct test_wlan_info *winfos, + u_int32 *rdd_cnt, + u_int32 *rdd_dw_num) +{ + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_get_rdd_content( + struct test_wlan_info *winfos, + u_int32 *content, + u_int32 *total_cnt) +{ + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_set_tam_arb( + struct test_wlan_info *winfos, + u_int8 arb_op_mode) +{ + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_set_muru_manual( + void *virtual_device, + struct test_wlan_info *winfos, + struct test_configuration *configs) +{ + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_hetb_ctrl( + struct test_wlan_info *winfos, + u_char band_idx, + u_char ctrl_type, + u_char enable, + u_int8 bw, + u_int8 ltf_gi, + u_int8 stbc, + u_int8 pri_ru_idx, + struct test_ru_info *ru_info) +{ + return SERV_STATUS_SUCCESS; +} + + +s_int32 mt_op_get_rx_stat_band( + struct test_wlan_info *winfos, + u_int8 band_idx, + u_int8 blk_idx, + struct test_rx_stat_band_info *rx_st_band) +{ + + s_int32 ret = SERV_STATUS_SUCCESS; + struct param_custom_access_rx_stat rx_stat_test; + wlan_oid_handler_t pr_oid_funcptr = winfos->oid_funcptr; + + if (pr_oid_funcptr == NULL) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + tm_rftest_set_auto_test(winfos, + RF_AT_FUNCID_SET_DBDC_BAND_IDX, band_idx); + + rx_stat_test.seq_num = 0; + rx_stat_test.total_num = 72; + + ret = pr_oid_funcptr(winfos, /*call back to ServiceWlanOid*/ + OP_WLAN_OID_QUERY_RX_STATISTICS, + &rx_stat_test, + sizeof(rx_stat_test), + NULL, + &test_hqa_rx_stat); + + if (band_idx == M_BAND_0) { + rx_st_band->mac_rx_fcs_err_cnt = + SERV_OS_NTOHL(test_hqa_rx_stat.mac_rx_fcs_err_cnt) + + SERV_OS_NTOHL(backup_band0_info.mac_rx_fcs_err_cnt); + rx_st_band->mac_rx_mdrdy_cnt = + SERV_OS_NTOHL(test_hqa_rx_stat.mac_rx_mdrdy_cnt) + + SERV_OS_NTOHL(backup_band0_info.mac_rx_mdrdy_cnt); + rx_st_band->mac_rx_len_mismatch = + SERV_OS_NTOHL(test_hqa_rx_stat.mac_rx_len_mismatch) + + SERV_OS_NTOHL(backup_band0_info.mac_rx_len_mismatch); + rx_st_band->mac_rx_fcs_ok_cnt = rx_st_band->mac_rx_mdrdy_cnt - + rx_st_band->mac_rx_fcs_err_cnt; + rx_st_band->phy_rx_fcs_err_cnt_cck = + SERV_OS_NTOHL(test_hqa_rx_stat.phy_rx_fcs_err_cnt_cck); + rx_st_band->phy_rx_fcs_err_cnt_ofdm = + SERV_OS_NTOHL(test_hqa_rx_stat.phy_rx_fcs_err_cnt_ofdm); + rx_st_band->phy_rx_pd_cck = + SERV_OS_NTOHL(test_hqa_rx_stat.phy_rx_pd_cck); + rx_st_band->phy_rx_pd_ofdm = + SERV_OS_NTOHL(test_hqa_rx_stat.phy_rx_pd_ofdm); + rx_st_band->phy_rx_sig_err_cck = + SERV_OS_NTOHL(test_hqa_rx_stat.phy_rx_sig_err_cck); + rx_st_band->phy_rx_sfd_err_cck = + SERV_OS_NTOHL(test_hqa_rx_stat.phy_rx_sfd_err_cck); + rx_st_band->phy_rx_sig_err_ofdm = + SERV_OS_NTOHL(test_hqa_rx_stat.phy_rx_sig_err_ofdm); + rx_st_band->phy_rx_tag_err_ofdm = + SERV_OS_NTOHL(test_hqa_rx_stat.phy_rx_tag_err_ofdm); + rx_st_band->phy_rx_mdrdy_cnt_cck = + SERV_OS_NTOHL(test_hqa_rx_stat.phy_rx_mdrdy_cnt_cck); + rx_st_band->phy_rx_mdrdy_cnt_ofdm = + SERV_OS_NTOHL(test_hqa_rx_stat.phy_rx_mdrdy_cnt_ofdm); + + /* Backup Band1 info */ + backup_band1_info.mac_rx_fcs_err_cnt += + test_hqa_rx_stat.mac_rx_fcs_err_cnt_band1; + + backup_band1_info.mac_rx_mdrdy_cnt += + test_hqa_rx_stat.mac_rx_mdrdy_cnt_band1; + + backup_band1_info.mac_rx_len_mismatch += + test_hqa_rx_stat.mac_rx_len_mismatch_band1; + + /* Reset Band0 backup info */ + sys_ad_zero_mem(&backup_band0_info, + sizeof(struct test_rx_stat_band_info)); + } else { + rx_st_band->mac_rx_fcs_err_cnt = + SERV_OS_NTOHL( + test_hqa_rx_stat.mac_rx_fcs_err_cnt_band1) + + SERV_OS_NTOHL( + backup_band1_info.mac_rx_fcs_err_cnt); + rx_st_band->mac_rx_mdrdy_cnt = + SERV_OS_NTOHL( + test_hqa_rx_stat.mac_rx_mdrdy_cnt_band1) + + SERV_OS_NTOHL( + backup_band1_info.mac_rx_mdrdy_cnt); + rx_st_band->mac_rx_len_mismatch = + SERV_OS_NTOHL( + test_hqa_rx_stat.mac_rx_len_mismatch_band1) + + SERV_OS_NTOHL( + backup_band1_info.mac_rx_len_mismatch); + rx_st_band->mac_rx_fcs_ok_cnt = rx_st_band->mac_rx_mdrdy_cnt - + rx_st_band->mac_rx_fcs_err_cnt; + rx_st_band->phy_rx_fcs_err_cnt_cck = + SERV_OS_NTOHL( + test_hqa_rx_stat.phy_rx_fcs_err_cnt_cck_band1); + rx_st_band->phy_rx_fcs_err_cnt_ofdm = + SERV_OS_NTOHL( + test_hqa_rx_stat.phy_rx_fcs_err_cnt_ofdm_band1); + rx_st_band->phy_rx_pd_cck = + SERV_OS_NTOHL( + test_hqa_rx_stat.phy_rx_pd_cck_band1); + rx_st_band->phy_rx_pd_ofdm = + SERV_OS_NTOHL( + test_hqa_rx_stat.phy_rx_pd_ofdm_band1); + rx_st_band->phy_rx_sig_err_cck = + SERV_OS_NTOHL( + test_hqa_rx_stat.phy_rx_sig_err_cck_band1); + rx_st_band->phy_rx_sfd_err_cck = + SERV_OS_NTOHL( + test_hqa_rx_stat.phy_rx_sfd_err_cck_band1); + rx_st_band->phy_rx_sig_err_ofdm = + SERV_OS_NTOHL( + test_hqa_rx_stat.phy_rx_sig_err_ofdm_band1); + rx_st_band->phy_rx_tag_err_ofdm = + SERV_OS_NTOHL( + test_hqa_rx_stat.phy_rx_tag_err_ofdm_band1); + rx_st_band->phy_rx_mdrdy_cnt_cck = + SERV_OS_NTOHL( + test_hqa_rx_stat.phy_rx_mdrdy_cnt_cck_band1); + rx_st_band->phy_rx_mdrdy_cnt_ofdm = + SERV_OS_NTOHL( + test_hqa_rx_stat.phy_rx_mdrdy_cnt_ofdm_band1); + + + /* Backup Band0 info */ + backup_band0_info.mac_rx_fcs_err_cnt += + test_hqa_rx_stat.mac_rx_fcs_err_cnt; + + backup_band0_info.mac_rx_mdrdy_cnt += + test_hqa_rx_stat.mac_rx_mdrdy_cnt; + + backup_band0_info.mac_rx_len_mismatch += + test_hqa_rx_stat.mac_rx_len_mismatch; + + /* Reset Band1 backup info */ + sys_ad_zero_mem(&backup_band1_info, + sizeof(struct test_rx_stat_band_info)); + } + + return ret; +} + +s_int32 mt_op_set_mutb_spe( + struct test_wlan_info *winfos, + u_char band_idx, + u_char tx_mode, + u_int8 spe_idx) +{ + return SERV_STATUS_SUCCESS; +} + + +s_int32 mt_op_get_rx_stat_path( + struct test_wlan_info *winfos, + u_int8 band_idx, + u_int8 blk_idx, + struct test_rx_stat_path_info *rx_st_path) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + switch (blk_idx) { + case ANT_WF0: + rx_st_path->rcpi = + SERV_OS_NTOHL(test_hqa_rx_stat.rcpi0); + rx_st_path->rssi = + SERV_OS_NTOHL(test_hqa_rx_stat.rssi0); + rx_st_path->fagc_ib_rssi = + SERV_OS_NTOHL(test_hqa_rx_stat.fagc_ib_RSSSI0); + rx_st_path->fagc_wb_rssi = + SERV_OS_NTOHL(test_hqa_rx_stat.fagc_wb_RSSSI0); + rx_st_path->inst_ib_rssi = + SERV_OS_NTOHL(test_hqa_rx_stat.inst_ib_RSSSI0); + rx_st_path->inst_wb_rssi = + SERV_OS_NTOHL(test_hqa_rx_stat.inst_wb_RSSSI0); + break; + case ANT_WF1: + rx_st_path->rcpi = + SERV_OS_NTOHL(test_hqa_rx_stat.rcpi1); + rx_st_path->rssi = + SERV_OS_NTOHL(test_hqa_rx_stat.rssi1); + rx_st_path->fagc_ib_rssi = + SERV_OS_NTOHL(test_hqa_rx_stat.fagc_ib_RSSSI1); + rx_st_path->fagc_wb_rssi = + SERV_OS_NTOHL(test_hqa_rx_stat.fagc_wb_RSSSI1); + rx_st_path->inst_ib_rssi = + SERV_OS_NTOHL(test_hqa_rx_stat.inst_ib_RSSSI1); + rx_st_path->inst_wb_rssi = + SERV_OS_NTOHL(test_hqa_rx_stat.inst_wb_RSSSI1); + break; + + default: + ret = SERV_STATUS_HAL_OP_FAIL; + break; + } + + return ret; +} + +s_int32 mt_op_set_ru_aid( + struct test_wlan_info *winfos, + u_char band_idx, + u_int16 mu_rx_aid) + +{ + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_get_rx_stat_user( + struct test_wlan_info *winfos, + u_int8 band_idx, + u_int8 blk_idx, + struct test_rx_stat_user_info *rx_st_user) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + rx_st_user->freq_offset_from_rx = + SERV_OS_NTOHL(test_hqa_rx_stat.freq_offset_from_rx); + if (band_idx == M_BAND_0) + rx_st_user->snr = SERV_OS_NTOHL(test_hqa_rx_stat.snr0); + else + rx_st_user->snr = SERV_OS_NTOHL(test_hqa_rx_stat.snr1); + + rx_st_user->fcs_error_cnt = + SERV_OS_NTOHL(test_hqa_rx_stat.mac_rx_fcs_err_cnt); + + return ret; +} + +s_int32 mt_op_get_rx_stat_comm( + struct test_wlan_info *winfos, + u_int8 band_idx, + u_int8 blk_idx, + struct test_rx_stat_comm_info *rx_st_comm) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + rx_st_comm->rx_fifo_full = + SERV_OS_NTOHL(test_hqa_rx_stat.rx_fifo_full); + rx_st_comm->aci_hit_low = + SERV_OS_NTOHL(test_hqa_rx_stat.aci_hit_low); + rx_st_comm->aci_hit_high = + SERV_OS_NTOHL(test_hqa_rx_stat.aci_hit_high); + rx_st_comm->mu_pkt_count = + SERV_OS_NTOHL(test_hqa_rx_stat.mu_pkt_count); + rx_st_comm->sig_mcs = + SERV_OS_NTOHL(test_hqa_rx_stat.sig_mcs); + rx_st_comm->sinr = + SERV_OS_NTOHL(test_hqa_rx_stat.sinr); + if (band_idx == M_BAND_0) { + rx_st_comm->driver_rx_count = + SERV_OS_NTOHL(test_hqa_rx_stat.driver_rx_count); + } else { + rx_st_comm->driver_rx_count = + SERV_OS_NTOHL(test_hqa_rx_stat.driver_rx_count1); + } + return ret; +} + +s_int32 mt_op_get_wf_path_comb( + struct test_wlan_info *winfos, + u_int8 band_idx, + boolean dbdc_mode_en, + u_int8 *path, + u_int8 *path_len) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_int8 i = 0; + + /* sanity check for null pointer */ + if (!path) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + /* sanity check for null pointer */ + if (!path_len) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + if (dbdc_mode_en) { + *path_len = 1; + if (band_idx == M_BAND_0) + *path = 0; + else + *path = 1; + } else { + *path_len = 2; + for (i = 0; i < *path_len; i++) + *(path + i) = i; + } + + if (*path_len > MAX_ANT_NUM) + ret = FALSE; + + return ret; +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/glue/hal/include/operation.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/glue/hal/include/operation.h new file mode 100644 index 0000000000000000000000000000000000000000..88865799bcf7ec774ad939d27b755a2bbc472648 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/glue/hal/include/operation.h @@ -0,0 +1,486 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#ifndef __OPERATION_H__ +#define __OPERATION_H__ + +#include "test_mac.h" +#include "net_adaption.h" + +/***************************************************************************** + * Enum value definition + *****************************************************************************/ +/* gen4m object id list */ +enum op_wlan_oid { + OP_WLAN_OID_SET_TEST_MODE_START = 0, + OP_WLAN_OID_SET_TEST_MODE_ABORT = 1, + OP_WLAN_OID_RFTEST_SET_AUTO_TEST = 2, + OP_WLAN_OID_QUERY_RX_STATISTICS = 3, + OP_WLAN_OID_SET_TEST_ICAP_MODE = 4, + OP_WLAN_OID_RFTEST_QUERY_AUTO_TEST = 5, + OP_WLAN_OID_SET_MCR_WRITE = 6, + OP_WLAN_OID_QUERY_MCR_READ = 7, + OP_WLAN_OID_GET_RECAL_COUNT = 8, + OP_WLAN_OID_GET_RECAL_CONTENT = 9, + OP_WLAN_OID_GET_ANTSWAP_CAPBILITY = 10, + OP_WLAN_OID_SET_TEST_ICAP_START = 11, + OP_WLAN_OID_SET_TEST_ICAP_ABORT = 12, + OP_WLAN_OID_SET_TEST_ICAP_STATUS = 13, + OP_WLAN_OID_GET_TEST_ICAP_MAX_DATA_LEN = 14, + OP_WLAN_OID_GET_TEST_ICAP_DATA = 15, + OP_WLAN_OID_RESET_RECAL_COUNT = 16, + OP_WLAN_OID_GET_CAPABILITY = 17, + OP_WLAN_OID_NUM +}; + +enum ENUM_ANT_NUM { + ANT_WF0 = 0, + ANT_WF1 = 1, + MAX_ANT_NUM +}; + +enum ENUM_M_BAND_NUM { + M_BAND_0 = 0, + M_BAND_1 = 1, + M_BAND_NUM +}; + +/***************************************************************************** + * Structure definition + *****************************************************************************/ +struct param_mtk_wifi_test_struct { + u_int32 func_idx; + u_int32 func_data; +}; + +struct param_custom_access_rx_stat { + u_int32 seq_num; + u_int32 total_num; +}; + +struct param_custom_mcr_rw_struct { + u_int32 mcr_offset; + u_int32 mcr_data; +}; + +struct test_txpwr_cfg { + u_int32 ant_idx; + u_int32 txpwr; + u_int32 channel; + u_int32 band_idx; + u_int32 ch_band; +}; + +struct test_ch_cfg { + u_int8 ctrl_ch; + u_int8 ctrl_ch2; + u_int8 central_ch; + u_int8 bw; + u_int8 tx_strm; + u_int8 rx_path; + boolean scan; + boolean dfs_check; + u_int8 band_idx; + u_int8 ch_band; + u_int32 out_band_freq; +}; + +/* Test rbist status for hqa command usage*/ +struct GNU_PACKED hqa_rbist_cap_start { + u_int32 trig; + u_int32 ring_cap_en; + u_int32 trig_event; + u_int32 cap_node; + u_int32 cap_len; + u_int32 cap_stop_cycle; + u_int32 mac_trig_event; + u_int32 src_addr_lsb; + u_int32 src_addr_msb; + u_int32 band_idx; + u_int32 bw; + u_int32 en_bit_width; /* 0:32bit, 1:96bit, 2:128bit */ + u_int32 arch; /* 0:on-chip, 1:on-the-fly */ + u_int32 phy_idx; + u_int32 emi_start_addr; + u_int32 emi_end_addr; + u_int32 emi_msb_addr; + u_int32 cap_src; + u_int32 resv[2]; +}; + +struct test_struct_ext { + u_int32 func_idx; + union { + u_int32 func_data; + u_int32 cal_dump; + struct hqa_rbist_cap_start icap_info; + } data; +}; + +/***************************************************************************** + * Function declaration + *****************************************************************************/ +s_int32 mt_op_set_tr_mac( + struct test_wlan_info *winfos, + s_int32 op_type, boolean enable, u_char band_idx); +s_int32 mt_op_set_tx_stream( + struct test_wlan_info *winfos, + u_int32 stream_nums, u_char band_idx); +s_int32 mt_op_set_tx_path( + struct test_wlan_info *winfos, + u_char band_idx, + struct test_configuration *configs); +s_int32 mt_op_set_rx_path( + struct test_wlan_info *winfos, + u_char band_idx, + struct test_configuration *configs); +s_int32 mt_op_set_rx_filter( + struct test_wlan_info *winfos, + struct rx_filter_ctrl rx_filter); +s_int32 mt_op_set_clean_persta_txq( + struct test_wlan_info *winfos, + boolean sta_pause_enable, u_char omac_idx, u_char band_idx); +s_int32 mt_op_set_cfg_on_off( + struct test_wlan_info *winfos, + u_int8 type, u_int8 enable, u_char band_idx); +s_int32 mt_op_log_on_off( + struct test_wlan_info *winfos, + u_char band_idx, + u_int32 log_type, + u_int32 log_ctrl, + u_int32 log_size); +s_int32 mt_op_set_antenna_port( + struct test_wlan_info *winfos, + u_int8 rf_mode_mask, u_int8 rf_port_mask, u_int8 ant_port_mask); +s_int32 mt_op_set_slot_time( + struct test_wlan_info *winfos, + u_int8 slot_time, u_int8 sifs_time, u_int8 rifs_time, + u_int16 eifs_time, u_char band_idx); +s_int32 mt_op_set_power_drop_level( + struct test_wlan_info *winfos, + u_int8 pwr_drop_level, u_char band_idx); +s_int32 mt_op_set_rx_filter_pkt_len( + struct test_wlan_info *winfos, + u_int8 enable, u_char band_idx, u_int32 rx_pkt_len); +s_int32 mt_op_get_antswap_capability( + struct test_wlan_info *winfos, + u_int32 *antswap_support); +s_int32 mt_op_set_antswap( + struct test_wlan_info *winfos, + u_int32 ant); +s_int32 mt_op_set_freq_offset( + struct test_wlan_info *winfos, + u_int32 freq_offset, u_char band_idx); +s_int32 mt_op_set_phy_counter( + struct test_wlan_info *winfos, + s_int32 control, u_char band_idx); +s_int32 mt_op_set_rxv_index( + struct test_wlan_info *winfos, + u_int8 group_1, u_int8 group_2, u_char band_idx); +s_int32 mt_op_set_fagc_path( + struct test_wlan_info *winfos, + u_int8 path, u_char band_idx); +s_int32 mt_op_set_fw_mode( + struct test_wlan_info *winfos, u_char fw_mode); +s_int32 mt_op_set_rf_test_mode( + struct test_wlan_info *winfos, + u_int32 op_mode, u_int8 icap_len, u_int16 rsp_len); +s_int32 mt_op_start_tx( + struct test_wlan_info *winfos, + u_char band_idx, + struct test_configuration *configs); +s_int32 mt_op_stop_tx( + struct test_wlan_info *winfos, + u_char band_idx); +s_int32 mt_op_start_rx( + struct test_wlan_info *winfos, + u_char band_idx, + struct test_configuration *configs); +s_int32 mt_op_stop_rx( + struct test_wlan_info *winfos, + u_char band_idx); +s_int32 mt_op_set_channel( + struct test_wlan_info *winfos, + u_char band_idx, + struct test_configuration *configs); +s_int32 mt_op_set_tx_content( + struct test_wlan_info *winfos, + u_char band_idx, + struct test_configuration *configs); +s_int32 mt_op_set_preamble( + struct test_wlan_info *winfos, + u_char mode); +s_int32 mt_op_set_rate( + struct test_wlan_info *winfos, + u_char mcs); +s_int32 mt_op_set_system_bw( + struct test_wlan_info *winfos, + u_char sys_bw); +s_int32 mt_op_set_per_pkt_bw( + struct test_wlan_info *winfos, + u_char per_pkt_bw); +s_int32 mt_op_reset_txrx_counter( + struct test_wlan_info *winfos); +s_int32 mt_op_set_rx_vector_idx( + struct test_wlan_info *winfos, + u_char band_idx, + u_int32 group1, + u_int32 group2); +s_int32 mt_op_set_fagc_rssi_path( + struct test_wlan_info *winfos, + u_char band_idx, + u_int32 fagc_path); +s_int32 mt_op_get_rx_stat_leg( + struct test_wlan_info *winfos, + struct test_rx_stat_leg *rx_stat); +s_int32 mt_op_dbdc_tx_tone( + struct test_wlan_info *winfos, + u_char band_idx, + struct test_configuration *configs); +s_int32 mt_op_dbdc_tx_tone_pwr( + struct test_wlan_info *winfos, + u_char band_idx, + struct test_configuration *configs); +s_int32 mt_op_dbdc_continuous_tx( + struct test_wlan_info *winfos, + u_char band_idx, + struct test_configuration *configs); +s_int32 mt_op_get_tx_info( + struct test_wlan_info *winfos, + struct test_configuration *test_configs_band0, + struct test_configuration *test_configs_band1); +s_int32 mt_op_get_rx_statistics_all( + struct test_wlan_info *winfos, + struct hqa_comm_rx_stat *hqa_rx_stat); +s_int32 mt_op_get_capability( + struct test_wlan_info *winfos, + struct test_capability *capability); +s_int32 mt_op_calibration_test_mode( + struct test_wlan_info *winfos, + u_char mode); +s_int32 mt_op_set_icap_start( + struct test_wlan_info *winfos, + u_int8 *data); +s_int32 mt_op_get_icap_status( + struct test_wlan_info *winfos, + s_int32 *icap_stat); +s_int32 mt_op_get_icap_max_data_len( + struct test_wlan_info *winfos, + u_long *max_data_len); +s_int32 mt_op_get_icap_data( + struct test_wlan_info *winfos, + s_int32 *icap_cnt, + s_int32 *icap_data, + u_int32 wf_num, + u_int32 iq_type); +s_int32 mt_op_do_cal_item( + struct test_wlan_info *winfos, + u_int32 item, + u_char band_idx); +s_int32 mt_op_set_band_mode( + struct test_wlan_info *winfos, + struct test_band_state *band_state); +s_int32 mt_op_get_chipid( + struct test_wlan_info *winfos); +s_int32 mt_op_mps_start( + struct test_wlan_info *winfos, + u_char band_idx); +s_int32 mt_op_mps_set_nss( + struct test_wlan_info *winfos, + u_int32 len, + struct test_mps_setting *mps_setting); +s_int32 mt_op_mps_set_per_packet_bw( + struct test_wlan_info *winfos, + u_int32 len, + struct test_mps_setting *mps_setting); +s_int32 mt_op_mps_set_packet_count( + struct test_wlan_info *winfos, + u_int32 len, + struct test_mps_setting *mps_setting); + +s_int32 mt_op_mps_set_payload_length( + struct test_wlan_info *winfos, + u_int32 len, + struct test_mps_setting *mps_setting); +s_int32 mt_op_mps_set_power_gain( + struct test_wlan_info *winfos, + u_int32 len, + struct test_mps_setting *mps_setting); +s_int32 mt_op_mps_set_seq_data( + struct test_wlan_info *winfos, + u_int32 len, + struct test_mps_setting *mps_setting); +s_int32 mt_op_set_muru_manual( + void *virtual_device, + struct test_wlan_info *winfos, + struct test_configuration *configs); +s_int32 mt_op_set_tam_arb( + struct test_wlan_info *winfos, + u_int8 arb_op_mode); + +/* gen4m operation define */ +s_int32 mt_op_set_test_mode_start(struct test_wlan_info *winfos); +s_int32 mt_op_set_test_mode_abort(struct test_wlan_info *winfos); + +/* For test mac usage */ +s_int32 mt_op_backup_and_set_cr( + struct test_wlan_info *winfos, + struct test_bk_cr *bks, + u_char band_idx); +s_int32 mt_op_restore_cr( + struct test_wlan_info *winfos, + struct test_bk_cr *bks, + u_char band_idx); +s_int32 mt_op_set_ampdu_ba_limit( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_int8 agg_limit); +s_int32 mt_op_set_sta_pause_cr( + struct test_wlan_info *winfos); +s_int32 mt_op_set_ifs_cr( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_char band_idx); +s_int32 mt_op_write_mac_bbp_reg( + struct test_wlan_info *winfos, + struct test_register *regs); +s_int32 mt_op_read_bulk_mac_bbp_reg( + struct test_wlan_info *winfos, + struct test_register *regs); +s_int32 mt_op_read_bulk_rf_reg( + struct test_wlan_info *winfos, + struct test_register *regs); +s_int32 mt_op_write_bulk_rf_reg( + struct test_wlan_info *winfos, + struct test_register *regs); +s_int32 mt_op_read_bulk_eeprom( + struct test_wlan_info *winfos, + struct test_eeprom *eprms); + +/* For test phy usage */ +s_int32 mt_op_get_tx_pwr( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_char band_idx, + u_char channel, + u_char ant_idx, + u_int32 *power); +s_int32 mt_op_set_tx_pwr( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_char band_idx, + struct test_txpwr_param *pwr_param); +s_int32 mt_op_set_freq_offset( + struct test_wlan_info *winfos, + u_int32 freq_offset, u_char band_idx); +s_int32 mt_op_get_freq_offset( + struct test_wlan_info *winfos, + u_char band_idx, + u_int32 *freq_offset); +s_int32 mt_op_get_cfg_on_off( + struct test_wlan_info *winfos, + u_char band_idx, + u_int32 type, + u_int32 *result); +s_int32 mt_op_get_tx_tone_pwr( + struct test_wlan_info *winfos, + u_char band_idx, + u_int32 ant_idx, + u_int32 *power); +s_int32 mt_op_get_recal_cnt( + struct test_wlan_info *winfos, + u_int32 *recal_cnt, + u_int32 *recal_dw_num); +s_int32 mt_op_get_recal_content( + struct test_wlan_info *winfos, + u_int32 *content); +s_int32 mt_op_get_rxv_cnt( + struct test_wlan_info *winfos, + u_int32 *rxv_cnt, + u_int32 *rxv_dw_num); +s_int32 mt_op_get_rxv_content( + struct test_wlan_info *winfos, + u_int32 dw_cnt, + u_int32 *content); +s_int32 mt_op_set_cal_bypass( + struct test_wlan_info *winfos, + u_char band_idx, + u_int32 cal_item); +s_int32 mt_op_set_dpd( + struct test_wlan_info *winfos, + u_int32 on_off, + u_int32 wf_sel); +s_int32 mt_op_set_tssi( + struct test_wlan_info *winfos, + u_int32 on_off, + u_int32 wf_sel); +s_int32 mt_op_get_thermal_val( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_char band_idx, + u_int32 *value); +s_int32 mt_op_set_rdd_test( + struct test_wlan_info *winfos, + u_int32 rdd_idx, + u_int32 rdd_sel, + u_int32 enable); +s_int32 mt_op_set_off_ch_scan( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_char band_idx, + struct test_off_ch_param *off_ch_param); +s_int32 mt_op_get_rdd_cnt( + struct test_wlan_info *winfos, + u_int32 *rdd_cnt, + u_int32 *rdd_dw_num); +s_int32 mt_op_get_rdd_content( + struct test_wlan_info *winfos, + u_int32 *content, + u_int32 *total_cnt); +s_int32 mt_op_hetb_ctrl( + struct test_wlan_info *winfos, + u_char band_idx, + u_char ctrl_type, + u_char enable, + u_int8 bw, + u_int8 ltf_gi, + u_int8 stbc, + u_int8 pri_ru_idx, + struct test_ru_info *ru_info); +s_int32 mt_op_set_ru_aid( + struct test_wlan_info *winfos, + u_char band_idx, + u_int16 mu_rx_aid); +s_int32 mt_op_set_mutb_spe( + struct test_wlan_info *winfos, + u_char band_idx, + u_char tx_mode, + u_int8 spe_idx); +s_int32 mt_op_get_rx_stat_band( + struct test_wlan_info *winfos, + u_int8 band_idx, + u_int8 blk_idx, + struct test_rx_stat_band_info *rx_st_band); +s_int32 mt_op_get_rx_stat_path( + struct test_wlan_info *winfos, + u_int8 band_idx, + u_int8 blk_idx, + struct test_rx_stat_path_info *rx_st_path); +s_int32 mt_op_get_rx_stat_user( + struct test_wlan_info *winfos, + u_int8 band_idx, + u_int8 blk_idx, + struct test_rx_stat_user_info *rx_st_user); +s_int32 mt_op_get_rx_stat_comm( + struct test_wlan_info *winfos, + u_int8 band_idx, + u_int8 blk_idx, + struct test_rx_stat_comm_info *rx_st_comm); +s_int32 mt_op_get_wf_path_comb( + struct test_wlan_info *winfos, + u_int8 band_idx, + boolean dbdc_mode_en, + u_int8 *path, + u_int8 *path_len); +#endif /* __OPERATION_H__ */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/glue/hal/include/test_mac.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/glue/hal/include/test_mac.h new file mode 100644 index 0000000000000000000000000000000000000000..b300b8c9e5adc251734386df3676cb80210d755f --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/glue/hal/include/test_mac.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#ifndef __TEST_MAC_H__ +#define __TEST_MAC_H__ + +#include "net_adaption.h" + +/***************************************************************************** + * Function declaration + *****************************************************************************/ +s_int32 mt_test_mac_backup_and_set_cr( + struct test_wlan_info *winfos, + struct test_bk_cr *bks, + u_char band_idx); +s_int32 mt_test_mac_restore_cr( + struct test_wlan_info *winfos, + struct test_bk_cr *bks, + u_char band_idx); +s_int32 mt_test_mac_set_ampdu_ba_limit( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_int8 agg_limit); +s_int32 mt_test_mac_set_sta_pause_cr( + struct test_wlan_info *winfos); +s_int32 mt_test_mac_set_ifs_cr( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_char band_idx); + +#endif /* __TEST_MAC_H__ */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/glue/hal/jedi/operation_jedi.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/glue/hal/jedi/operation_jedi.c new file mode 100644 index 0000000000000000000000000000000000000000..745a9f6014897c448f2e10a3bbe32329a27b815c --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/glue/hal/jedi/operation_jedi.c @@ -0,0 +1,2185 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#include "rt_config.h" +#include "operation.h" + +s_int32 mt_op_set_tr_mac( + struct test_wlan_info *winfos, + s_int32 op_type, boolean enable, u_char band_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; +#ifdef CONFIG_HW_HAL_OFFLOAD + struct _EXT_CMD_ATE_TEST_MODE_T param; +#endif + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + +#ifdef CONFIG_HW_HAL_OFFLOAD + sys_ad_zero_mem(¶m, sizeof(param)); + param.ucAteTestModeEn = 1; + param.ucAteIdx = EXT_ATE_SET_TRX; + param.Data.rAteSetTrx.ucType = op_type; + param.Data.rAteSetTrx.ucEnable = enable; + param.Data.rAteSetTrx.ucBand = band_idx; + /* + * Make sure FW command configuration completed + * for store tx packet in PLE first + * Use aucReserved[1] for ucATEIdx extension feasibility + */ + param.aucReserved[1] = INIT_CMD_SET_AND_WAIT_RETRY_RSP; + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: op_type=%d, enable=%u, band_idx=%u\n", + __func__, op_type, enable, band_idx)); + + ret = MtCmdATETest(ad, ¶m); +#else + ret = MtAsicSetMacTxRx(ad, op_type, enable, band_idx); +#endif + + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD; + + return ret; +} + +s_int32 mt_op_set_tx_stream( + struct test_wlan_info *winfos, + u_int32 stream_nums, u_char band_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; +#ifdef CONFIG_HW_HAL_OFFLOAD + struct _EXT_CMD_ATE_TEST_MODE_T param; +#endif + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + +#ifdef CONFIG_HW_HAL_OFFLOAD + sys_ad_zero_mem(¶m, sizeof(param)); + param.ucAteTestModeEn = 1; + param.ucAteIdx = EXT_ATE_SET_TX_STREAM; + param.Data.rAteSetTxStream.ucStreamNum = stream_nums; + param.Data.rAteSetTxStream.ucBand = band_idx; + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: stream_nums=%u, band_idx=%u\n", + __func__, stream_nums, band_idx)); + + ret = MtCmdATETest(ad, ¶m); +#else + ret = MtAsicSetTxStream(ad, stream_nums, band_idx); +#endif + + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD; + + return ret; +} + +s_int32 mt_op_set_tx_path( + struct test_wlan_info *winfos, + u_char band_idx, + struct test_configuration *configs) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + return ret; +} + +s_int32 mt_op_set_rx_path( + struct test_wlan_info *winfos, + u_char band_idx, + struct test_configuration *configs) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + return ret; +} + + +s_int32 mt_op_set_rx_filter( + struct test_wlan_info *winfos, + struct rx_filter_ctrl rx_filter) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; +#ifdef CONFIG_HW_HAL_OFFLOAD + MT_RX_FILTER_CTRL_T filter; + struct _EXT_CMD_ATE_TEST_MODE_T param; +#endif + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + +#ifdef CONFIG_HW_HAL_OFFLOAD + sys_ad_zero_mem(&filter, sizeof(MT_RX_FILTER_CTRL_T)); + sys_ad_move_mem(&filter, &rx_filter, sizeof(MT_RX_FILTER_CTRL_T)); + sys_ad_zero_mem(¶m, sizeof(param)); + param.ucAteTestModeEn = 1; + param.ucAteIdx = EXT_ATE_SET_RX_FILTER; + param.Data.rAteSetRxFilter.ucBand = filter.u1BandIdx; + + if (filter.bPromiscuous) + param.Data.rAteSetRxFilter.ucPromiscuousMode = 1; + else { + param.Data.rAteSetRxFilter.ucReportEn = + (u_char)filter.bFrameReport; + param.Data.rAteSetRxFilter.u4FilterMask = + cpu2le32(filter.filterMask); + } + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: band_idx=%u\n", __func__, filter.u1BandIdx)); + + ret = MtCmdATETest(ad, ¶m); +#else + ret = MtAsicSetRxFilter(ad, filter); +#endif + + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD; + + return ret; +} + +s_int32 mt_op_set_clean_persta_txq( + struct test_wlan_info *winfos, + boolean sta_pause_enable, u_char omac_idx, u_char band_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; +#ifdef CONFIG_HW_HAL_OFFLOAD + RTMP_ADAPTER *ad = NULL; + struct _EXT_CMD_ATE_TEST_MODE_T param; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + sys_ad_zero_mem(¶m, sizeof(param)); + param.ucAteTestModeEn = 1; + param.ucAteIdx = EXT_ATE_SET_CLEAN_PERSTA_TXQUEUE; + param.Data.rAteSetCleanPerStaTxQueue.fgStaPauseEnable = + sta_pause_enable; + /* Give a same STA ID */ + param.Data.rAteSetCleanPerStaTxQueue.ucStaID = 0; + param.Data.rAteSetCleanPerStaTxQueue.ucBand = band_idx; + /* use omac index*/ + param.Data.rAteSetCleanPerStaTxQueue.aucReserved[0] = omac_idx; + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: sta_pause_enable=%u, band_idx=%u, reserved[0]=%u\n", + __func__, sta_pause_enable, band_idx, + param.Data.rAteSetCleanPerStaTxQueue.aucReserved[0])); + + ret = MtCmdATETest(ad, ¶m); + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD; +#else + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: function does't support yet.\n", __func__)); +#endif + + return ret; +} + +s_int32 mt_op_set_cfg_on_off( + struct test_wlan_info *winfos, + u_int8 type, u_int8 enable, u_char band_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; +#ifdef CONFIG_HW_HAL_OFFLOAD + RTMP_ADAPTER *ad = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: type=%u, enable=%u, band_idx=%u\n", + __func__, type, enable, band_idx)); + + ret = MtCmdCfgOnOff(ad, type, enable, (u_int8)band_idx); + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD; +#endif + + return ret; +} + +s_int32 mt_op_log_on_off( + struct test_wlan_info *winfos, + u_char band_idx, + u_int32 log_type, + u_int32 log_ctrl, + u_int32 log_size) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + return ret; +} + + +s_int32 mt_op_set_antenna_port( + struct test_wlan_info *winfos, + u_int8 rf_mode_mask, u_int8 rf_port_mask, u_int8 ant_port_mask) +{ + s_int32 ret = SERV_STATUS_SUCCESS; +#ifdef CONFIG_HW_HAL_OFFLOAD + RTMP_ADAPTER *ad = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: rf_mode_mask=%u, rf_port_mask=%u, ant_port_mask=%u\n", + __func__, rf_mode_mask, rf_port_mask, ant_port_mask)); + + ret = MtCmdSetAntennaPort( + ad, rf_mode_mask, rf_port_mask, ant_port_mask); + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD; +#endif + + return ret; +} + +s_int32 mt_op_set_slot_time( + struct test_wlan_info *winfos, + u_int8 slot_time, u_int8 sifs_time, u_int8 rifs_time, + u_int16 eifs_time, u_char band_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + ret = MtCmdATESetSlotTime(ad, slot_time, sifs_time, + rifs_time, eifs_time, band_idx); + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD; + + return ret; +} + +s_int32 mt_op_set_power_drop_level( + struct test_wlan_info *winfos, + u_int8 pwr_drop_level, u_char band_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; +#ifdef CONFIG_HW_HAL_OFFLOAD + RTMP_ADAPTER *ad = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: pwr_drop_level=%u, band_idx=%u\n", + __func__, pwr_drop_level, band_idx)); + + ret = MtCmdATESetPowerDropLevel(ad, pwr_drop_level, band_idx); + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD; +#endif /* CONFIG_HW_HAL_OFFLOAD */ + + return ret; +} + +s_int32 mt_op_set_rx_filter_pkt_len( + struct test_wlan_info *winfos, + u_int8 enable, u_char band_idx, u_int32 rx_pkt_len) +{ + s_int32 ret = SERV_STATUS_SUCCESS; +#ifdef CONFIG_HW_HAL_OFFLOAD + RTMP_ADAPTER *ad = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: enable=%u, band_idx=%u, rx_pkt_len=%u\n", + __func__, enable, band_idx, rx_pkt_len)); + + ret = MtCmdRxFilterPktLen(ad, enable, band_idx, rx_pkt_len); + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD; +#endif + + return ret; +} + +s_int32 mt_op_get_antswap_capability( + struct test_wlan_info *winfos, + u_int32 *antswap_support) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + return ret; +} + +s_int32 mt_op_set_antswap( + struct test_wlan_info *winfos, + u_int32 ant) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + return ret; +} + +s_int32 mt_op_set_freq_offset( + struct test_wlan_info *winfos, + u_int32 freq_offset, u_char band_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + +#ifdef CONFIG_HW_HAL_OFFLOAD + ret = MtCmdSetFreqOffset(ad, freq_offset, band_idx); +#else + ret = MtAsicSetRfFreqOffset(ad, freq_offset); +#endif + + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD; + + return ret; +} + +s_int32 mt_op_set_phy_counter( + struct test_wlan_info *winfos, + s_int32 control, u_char band_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + ret = MtCmdSetPhyCounter(ad, control, (u_int8) band_idx); + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD; + + return ret; +} + +s_int32 mt_op_set_rxv_index( + struct test_wlan_info *winfos, + u_int8 group_1, u_int8 group_2, u_char band_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + ret = MtCmdSetRxvIndex(ad, group_1, group_2, (u_int8) band_idx); + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD; + + return ret; +} + +s_int32 mt_op_set_fagc_path( + struct test_wlan_info *winfos, + u_int8 path, u_char band_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + ret = MtCmdSetFAGCPath(ad, path, (u_int8) band_idx); + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD; + + return ret; +} + +s_int32 mt_op_set_fw_mode( + struct test_wlan_info *winfos, u_char fw_mode) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + ret = MtCmdATEModeCtrl(ad, fw_mode); + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD; + + return ret; +} + +s_int32 mt_op_set_rf_test_mode( + struct test_wlan_info *winfos, + u_int32 op_mode, u_int8 icap_len, u_int16 rsp_len) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + ret = MtCmdRfTestSwitchMode(ad, op_mode, icap_len, rsp_len); + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD; + + return ret; +} + +s_int32 mt_op_set_test_mode_start( + struct test_wlan_info *winfos) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + return ret; +} + +s_int32 mt_op_set_test_mode_abort( + struct test_wlan_info *winfos) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + return ret; +} + +s_int32 mt_op_backup_and_set_cr( + struct test_wlan_info *winfos, + struct test_bk_cr *bks, + u_char band_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + ret = mt_test_mac_backup_and_set_cr(winfos, bks, band_idx); + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SET_MAC; + + return ret; +} + +s_int32 mt_op_restore_cr( + struct test_wlan_info *winfos, + struct test_bk_cr *bks, + u_char band_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + ret = mt_test_mac_restore_cr(winfos, bks, band_idx); + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SET_MAC; + + return ret; +} + +s_int32 mt_op_set_ampdu_ba_limit( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_int8 agg_limit) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + ret = mt_test_mac_set_ampdu_ba_limit(winfos, configs, agg_limit); + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SET_MAC; + + return ret; +} + +s_int32 mt_op_set_sta_pause_cr( + struct test_wlan_info *winfos) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + ret = mt_test_mac_set_sta_pause_cr(winfos); + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SET_MAC; + + return ret; +} + +s_int32 mt_op_set_ifs_cr( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_char band_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + ret = mt_test_mac_set_ifs_cr(winfos, configs, band_idx); + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SET_MAC; + + return ret; +} + +s_int32 mt_op_write_mac_bbp_reg( + struct test_wlan_info *winfos, + struct test_register *regs) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + return ret; +} + +s_int32 mt_op_read_bulk_mac_bbp_reg( + struct test_wlan_info *winfos, + struct test_register *regs) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + return ret; +} + +s_int32 mt_op_read_bulk_rf_reg( + struct test_wlan_info *winfos, + struct test_register *regs) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + return ret; +} + +s_int32 mt_op_write_bulk_rf_reg( + struct test_wlan_info *winfos, + struct test_register *regs) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + return ret; +} + +s_int32 mt_op_read_bulk_eeprom( + struct test_wlan_info *winfos, + struct test_eeprom *eprms) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + return ret; +} + +s_int32 mt_op_start_tx( + struct test_wlan_info *winfos, + u_char band_idx, + struct test_configuration *configs) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + return ret; +} + +s_int32 mt_op_stop_tx( + struct test_wlan_info *winfos, + u_char band_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + return ret; +} + +s_int32 mt_op_start_rx( + struct test_wlan_info *winfos, + u_char band_idx, + struct test_configuration *configs) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + return ret; +} + +s_int32 mt_op_stop_rx( + struct test_wlan_info *winfos, + u_char band_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + return ret; +} + +s_int32 mt_op_set_channel( + struct test_wlan_info *winfos, + u_char band_idx, + struct test_configuration *configs) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + + ret = net_ad_update_wdev(band_idx, winfos, configs); + if (ret) + goto error; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: band_idx: %d, bw: %d, ch:%d", + __func__, band_idx, configs->bw, configs->channel)); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("ctrl_ch: %d, cntl_ch2: %d, pri_sel: %d\n", + configs->ctrl_ch, configs->channel_2nd, configs->pri_sel)); + + return ret; + +error: + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: set channel fail, ", __func__)); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("control channel: %d|%d\n", configs->ctrl_ch, + configs->channel)); + return SERV_STATUS_OSAL_NET_FAIL_SET_CHANNEL; +} + +s_int32 mt_op_set_tx_content( + struct test_wlan_info *winfos, + u_char band_idx, + struct test_configuration *configs) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + return ret; +} + +s_int32 mt_op_set_preamble( + struct test_wlan_info *winfos, + u_char mode) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + return ret; +} + +s_int32 mt_op_set_rate( + struct test_wlan_info *winfos, + u_char mcs) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + return ret; +} + +s_int32 mt_op_set_system_bw( + struct test_wlan_info *winfos, + u_char sys_bw) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + return ret; +} + +s_int32 mt_op_set_per_pkt_bw( + struct test_wlan_info *winfos, + u_char per_pkt_bw) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + return ret; +} + +s_int32 mt_op_reset_txrx_counter( + struct test_wlan_info *winfos) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + RX_STATISTIC_RXV *rx_stat; + u_int32 control = 0, user_idx = 0, band_idx = 0; + struct _RTMP_CHIP_DBG *chip_dbg = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: reset txrx counter\n", __func__)); + + chip_dbg = hc_get_chip_dbg(ad->hdev_ctrl); + + for (band_idx = TEST_DBDC_BAND0; + band_idx < TEST_DBDC_BAND_NUM; band_idx++) { + control = 0; + ret = MtCmdSetPhyCounter(ad, control, band_idx); + if (ret) + goto error; + + control = 1; + ret = MtCmdSetPhyCounter(ad, control, band_idx); + if (ret) + goto error; + + /* reset rx stat fcs error count */ + rx_stat = ad->rx_stat_rxv + band_idx; + for (user_idx = 0; user_idx < TEST_USER_NUM; user_idx++) { + rx_stat->fcs_error_cnt[user_idx] = 0; + rx_stat->FreqOffsetFromRx[user_idx] = 0; + rx_stat->SNR[user_idx] = 0; + } + + if (chip_dbg) { + chip_dbg->get_tx_mibinfo(ad, band_idx, + MODE_CCK, + BW_20); + chip_dbg->get_tx_mibinfo(ad, band_idx, + MODE_CCK, + BW_40); + chip_dbg->get_tx_mibinfo(ad, band_idx, + MODE_CCK, + BW_80); + chip_dbg->get_tx_mibinfo(ad, band_idx, + MODE_CCK, + BW_160); + chip_dbg->get_tx_mibinfo(ad, band_idx, + MODE_HE_MU, + BW_20); + } + } + + return ret; + +error: + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: reset tx rx phy counter fail(0x%08x).\n", __func__, ret)); + return ret; +} + +s_int32 mt_op_set_rx_vector_idx( + struct test_wlan_info *winfos, + u_char band_idx, + u_int32 group1, + u_int32 group2) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + return ret; +} + +s_int32 mt_op_set_fagc_rssi_path( + struct test_wlan_info *winfos, + u_char band_idx, + u_int32 fagc_path) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + return ret; +} + +s_int32 mt_op_get_rx_stat_leg( + struct test_wlan_info *winfos, + struct test_rx_stat_leg *rx_stat) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + TESTMODE_STATISTIC_INFO st; + RX_STATISTIC_RXV *rx_stat_rxv; + u_char band_idx, band_num, user_idx; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + if (IS_TEST_DBDC(winfos)) { + band_num = 2; + rx_stat_rxv = ad->rx_stat_rxv + 0; + rx_stat->fagc_ib_rssi[0] = rx_stat_rxv->FAGC_RSSI_IB[0]; + rx_stat->fagc_ib_rssi[1] = rx_stat_rxv->FAGC_RSSI_IB[1]; + rx_stat->fagc_wb_rssi[0] = rx_stat_rxv->FAGC_RSSI_WB[0]; + rx_stat->fagc_wb_rssi[1] = rx_stat_rxv->FAGC_RSSI_WB[1]; + rx_stat->rcpi0 = rx_stat_rxv->RCPI[0]; + rx_stat->rcpi1 = rx_stat_rxv->RCPI[1]; + rx_stat->rssi0 = rx_stat_rxv->RSSI[0]; + rx_stat->rssi1 = rx_stat_rxv->RSSI[1]; + + rx_stat_rxv = &ad->rx_stat_rxv + 1; + rx_stat->fagc_ib_rssi[2] = rx_stat_rxv->FAGC_RSSI_IB[0]; + rx_stat->fagc_ib_rssi[3] = rx_stat_rxv->FAGC_RSSI_IB[1]; + rx_stat->fagc_wb_rssi[2] = rx_stat_rxv->FAGC_RSSI_WB[0]; + rx_stat->fagc_wb_rssi[3] = rx_stat_rxv->FAGC_RSSI_WB[1]; + rx_stat->rcpi2 = rx_stat_rxv->RCPI[0]; + rx_stat->rcpi3 = rx_stat_rxv->RCPI[1]; + rx_stat->rssi2 = rx_stat_rxv->RSSI[0]; + rx_stat->rssi3 = rx_stat_rxv->RSSI[1]; + } else { + band_num = 1; + rx_stat_rxv = ad->rx_stat_rxv + 0; + rx_stat->fagc_ib_rssi[0] = rx_stat_rxv->FAGC_RSSI_IB[0]; + rx_stat->fagc_ib_rssi[1] = rx_stat_rxv->FAGC_RSSI_IB[1]; + rx_stat->fagc_ib_rssi[2] = rx_stat_rxv->FAGC_RSSI_IB[2]; + rx_stat->fagc_ib_rssi[3] = rx_stat_rxv->FAGC_RSSI_IB[3]; + rx_stat->fagc_wb_rssi[0] = rx_stat_rxv->FAGC_RSSI_WB[0]; + rx_stat->fagc_wb_rssi[1] = rx_stat_rxv->FAGC_RSSI_WB[1]; + rx_stat->fagc_wb_rssi[2] = rx_stat_rxv->FAGC_RSSI_WB[2]; + rx_stat->fagc_wb_rssi[3] = rx_stat_rxv->FAGC_RSSI_WB[3]; + rx_stat->rcpi0 = rx_stat_rxv->RCPI[0]; + rx_stat->rcpi1 = rx_stat_rxv->RCPI[1]; + rx_stat->rcpi2 = rx_stat_rxv->RCPI[2]; + rx_stat->rcpi3 = rx_stat_rxv->RCPI[3]; + rx_stat->rssi0 = rx_stat_rxv->RSSI[0]; + rx_stat->rssi1 = rx_stat_rxv->RSSI[1]; + rx_stat->rssi2 = rx_stat_rxv->RSSI[2]; + rx_stat->rssi3 = rx_stat_rxv->RSSI[3]; + } + + for (band_idx = 0; band_idx < band_num; band_idx++) { + /* read statistic from firmware */ + chip_get_rx_stat(ad, band_idx, &st); + + /* Copy statistic info */ + switch (band_idx) { + case 0: + /* MAC COUNT */ + rx_stat->mac_rx_fcs_ok_cnt = + st.mac_rx_fcs_ok_cnt; + rx_stat->mac_rx_fcs_err_cnt = + st.mac_rx_fcs_err_cnt; + rx_stat->mac_rx_len_mismatch = + st.mac_rx_len_mismatch; + rx_stat->rx_fifo_full = + st.mac_rx_fifo_full; + rx_stat->mac_rx_mdrdy_cnt = + st.mac_rx_mdrdy_cnt; + + /* PHY COUNT */ + rx_stat->phy_rx_pd_cck = + st.phy_rx_pd_cck; + rx_stat->phy_rx_pd_ofdm = + st.phy_rx_pd_ofdm; + rx_stat->phy_rx_sig_err_cck = + st.phy_rx_sig_err_cck; + rx_stat->phy_rx_sfd_err_cck = + st.phy_rx_sfd_err_cck; + rx_stat->phy_rx_sig_err_ofdm = + st.phy_rx_sig_err_ofdm; + rx_stat->phy_rx_tag_err_ofdm = + st.phy_rx_tag_err_ofdm; + rx_stat->phy_rx_mdrdy_cnt_cck = + st.phy_rx_mdrdy_cnt_cck; + rx_stat->phy_rx_mdrdy_cnt_ofdm = + st.phy_rx_mdrdy_cnt_ofdm; + rx_stat->phy_rx_fcs_err_cnt_cck = + st.phy_rx_fcs_err_cnt_cck; + rx_stat->phy_rx_fcs_err_cnt_ofdm = + st.phy_rx_fcs_err_cnt_ofdm; + break; + + case 1: + /* MAC COUNT */ + rx_stat->mac_rx_fcs_err_cnt_band1 = + st.mac_rx_fcs_err_cnt; + rx_stat->mac_rx_len_mismatch_band1 = + st.mac_rx_len_mismatch; + rx_stat->rx_fifo_full_band1 = + st.mac_rx_fifo_full; + rx_stat->mac_rx_mdrdy_cnt_band1 = + st.mac_rx_mdrdy_cnt; + + /* PHY COUNT */ + rx_stat->phy_rx_pd_cck_band1 = + st.phy_rx_pd_cck; + rx_stat->phy_rx_pd_ofdm_band1 = + st.phy_rx_pd_ofdm; + rx_stat->phy_rx_sig_err_cck_band1 = + st.phy_rx_sig_err_cck; + rx_stat->phy_rx_sfd_err_cck_band1 = + st.phy_rx_sfd_err_cck; + rx_stat->phy_rx_sig_err_ofdm_band1 = + st.phy_rx_sig_err_ofdm; + rx_stat->phy_rx_tag_err_ofdm_band1 = + st.phy_rx_tag_err_ofdm; + rx_stat->phy_rx_mdrdy_cnt_cck_band1 = + st.phy_rx_mdrdy_cnt_cck; + rx_stat->phy_rx_mdrdy_cnt_ofdm_band1 = + st.phy_rx_mdrdy_cnt_ofdm; + break; + + default: + ret = SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD; + } + } + + rx_stat->freq_offset_rx = + rx_stat_rxv->FreqOffsetFromRx[0]; + + for (user_idx = 0; user_idx < TEST_USER_NUM; user_idx++) { + rx_stat->user_rx_freq_offset[user_idx] = + rx_stat_rxv->FreqOffsetFromRx[user_idx]; + rx_stat->user_snr[user_idx] = + (u_int32)rx_stat_rxv->SNR[user_idx]; + rx_stat->fcs_error_cnt[user_idx] = + rx_stat_rxv->fcs_error_cnt[user_idx]; + } + + return ret; +} + +s_int32 mt_op_dbdc_tx_tone( + struct test_wlan_info *winfos, + u_char band_idx, + struct test_configuration *configs) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + u_int8 tx_tone_en = 0, ant_idx = 0, tone_type = 0; + u_int8 tone_freq = 0; + s_int32 dc_offset_I = 0, dc_offset_Q = 0, ch_band = 0; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + tx_tone_en = (u_int8) configs->tx_tone_en; + ant_idx = (u_int8) configs->ant_idx; + tone_type = (u_int8) configs->tone_type; + tone_freq = (u_int8) configs->tone_freq; + dc_offset_I = (s_int32) configs->dc_offset_I; + dc_offset_Q = (s_int32) configs->dc_offset_Q; + ch_band = (s_int32) configs->ch_band; + + ret = MtCmdTxTone(ad, band_idx, tx_tone_en, + ant_idx, tone_type, tone_freq, + dc_offset_I, dc_offset_Q, ch_band); + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD; + + return ret; +} + +s_int32 mt_op_dbdc_tx_tone_pwr( + struct test_wlan_info *winfos, + u_char band_idx, + struct test_configuration *configs) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + u_int8 ant_idx = 0; + u_int32 digi_pwr = 0; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + ant_idx = (u_int8) configs->ant_idx; + digi_pwr = configs->digi_pwr; + + ret = MtCmdTxTonePower(ad, 0x12, digi_pwr, ant_idx, band_idx); + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD; + + return ret; +} + +s_int32 mt_op_dbdc_continuous_tx( + struct test_wlan_info *winfos, + u_char band_idx, + struct test_configuration *configs) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + u_int8 tx_tone_en = 0; + u_int32 ant_mask = 0, tx_mode = 0, bw = 0; + u_int32 pri_sel = 0, rate = 0, channel = 0; + u_int32 tx_fd_mode = 0; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + tx_tone_en = configs->tx_tone_en; + ant_mask = configs->ant_mask; + tx_mode = configs->tx_mode; + bw = configs->bw; + pri_sel = configs->pri_sel; + rate = configs->rate; + channel = configs->channel; + tx_fd_mode = configs->tx_fd_mode; + + ret = MtCmdTxContinous(ad, tx_mode, bw, + pri_sel, channel, rate, ant_mask, + tx_fd_mode, band_idx, tx_tone_en); + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD; + + return ret; +} + +s_int32 mt_op_get_tx_info( + struct test_wlan_info *winfos, + struct test_configuration *test_configs_band0, + struct test_configuration *test_configs_band1) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_int32 mib_counter = 0; + RTMP_ADAPTER *ad = NULL; + struct _RTMP_CHIP_DBG *chip_dbg = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + chip_dbg = hc_get_chip_dbg(ad->hdev_ctrl); + + if (chip_dbg) { + mib_counter = chip_dbg->get_tx_mibinfo(ad, BAND0, + test_configs_band0->tx_mode, + test_configs_band0->per_pkt_bw); + + test_configs_band0->tx_stat.tx_done_cnt += mib_counter; + + mib_counter = chip_dbg->get_tx_mibinfo(ad, BAND1, + test_configs_band1->tx_mode, + test_configs_band1->per_pkt_bw); + + test_configs_band1->tx_stat.tx_done_cnt += mib_counter; + } else + ret = SERV_STATUS_HAL_OP_FAIL; + + return ret; +} + +s_int32 mt_op_get_rx_statistics_all( + struct test_wlan_info *winfos, + struct hqa_comm_rx_stat *hqa_rx_stat) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + return ret; +} + +s_int32 mt_op_get_capability( + struct test_wlan_info *winfos, + struct test_capability *capability) +{ + s_int32 ret = SERV_STATUS_SERV_TEST_NOT_SUPPORTED; + + return ret; +} + +s_int32 mt_op_calibration_test_mode( + struct test_wlan_info *winfos, + u_char mode) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + u_int8 icap_len = 0; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + ret = MtCmdRfTestSwitchMode(ad, mode, + icap_len, RF_TEST_DEFAULT_RESP_LEN); + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD; + + return ret; +} + +s_int32 mt_op_set_icap_start( + struct test_wlan_info *winfos, + u_int8 *data) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + RTMP_CHIP_OP *ops = NULL; +#ifdef INTERNAL_CAPTURE_SUPPORT + RBIST_CAP_START_T *prICapInfo = (RBIST_CAP_START_T *)data; +#endif/* INTERNAL_CAPTURE_SUPPORT */ + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + ops = hc_get_chip_ops(ad->hdev_ctrl); + +#ifdef INTERNAL_CAPTURE_SUPPORT + if (ops->ICapStart != NULL) + ret = ops->ICapStart(ad, (u_int8 *)prICapInfo); + else { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s : The function is not hooked !!\n", __func__)); + } +#endif/* INTERNAL_CAPTURE_SUPPORT */ + + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD; + + return ret; +} + +s_int32 mt_op_get_icap_status( + struct test_wlan_info *winfos, + s_int32 *icap_stat) +{ + RTMP_ADAPTER *ad = NULL; + RTMP_CHIP_OP *ops = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + ops = hc_get_chip_ops(ad->hdev_ctrl); + +#ifdef INTERNAL_CAPTURE_SUPPORT + if (ops->ICapStatus != NULL) + *icap_stat = ops->ICapStatus(ad); + else { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s : The function is not hooked !!\n", __func__)); + return SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD; + } +#endif/* INTERNAL_CAPTURE_SUPPORT */ + + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_get_icap_max_data_len( + struct test_wlan_info *winfos, + u_long *max_data_len) +{ + *max_data_len = (ICAP_EVENT_DATA_SAMPLE * sizeof(INT32)); + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_get_icap_data( + struct test_wlan_info *winfos, + s_int32 *icap_cnt, + s_int32 *icap_data, + u_int32 wf_num, + u_int32 iq_type) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + RTMP_CHIP_OP *ops = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + ops = hc_get_chip_ops(ad->hdev_ctrl); + +#ifdef INTERNAL_CAPTURE_SUPPORT + if (ops->ICapGetIQData != NULL) + ret = ops->ICapGetIQData(ad + , icap_data, icap_cnt, iq_type, wf_num); + else if (ops->ICapCmdSolicitRawDataProc != NULL) + ret = ops->ICapCmdSolicitRawDataProc(ad + , icap_data, icap_cnt, iq_type, wf_num); + else { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s : The function is not hooked !!\n", __func__)); + } +#endif/* INTERNAL_CAPTURE_SUPPORT */ + + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD; + + return ret; +} + +s_int32 mt_op_do_cal_item( + struct test_wlan_info *winfos, + u_int32 item, + u_char band_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + ret = MtCmdDoCalibration(ad, 0x1, item, band_idx); + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD; + + return ret; +} + +s_int32 mt_op_set_band_mode( + struct test_wlan_info *winfos, + struct test_band_state *band_state) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + return ret; +} + +s_int32 mt_op_get_chipid( + struct test_wlan_info *winfos) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + return ret; +} + +s_int32 mt_op_mps_start( + struct test_wlan_info *winfos, + u_char band_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + return ret; +} + +s_int32 mt_op_mps_set_nss( + struct test_wlan_info *winfos, + u_int32 len, + struct test_mps_setting *mps_setting) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + return ret; +} + +s_int32 mt_op_mps_set_per_packet_bw( + struct test_wlan_info *winfos, + u_int32 len, + struct test_mps_setting *mps_setting) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + return ret; +} + +s_int32 mt_op_mps_set_packet_count( + struct test_wlan_info *winfos, + u_int32 len, + struct test_mps_setting *mps_setting) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + return ret; +} + +s_int32 mt_op_mps_set_payload_length( + struct test_wlan_info *winfos, + u_int32 len, + struct test_mps_setting *mps_setting) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + return ret; +} + +s_int32 mt_op_mps_set_power_gain( + struct test_wlan_info *winfos, + u_int32 len, + struct test_mps_setting *mps_setting) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + return ret; +} + +s_int32 mt_op_mps_set_seq_data( + struct test_wlan_info *winfos, + u_int32 len, + struct test_mps_setting *mps_setting) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + return ret; +} + +s_int32 mt_op_get_tx_pwr( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_char band_idx, + u_char channel, + u_char ant_idx, + u_int32 *power) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + EXT_EVENT_ID_GET_TX_POWER_T txpwr_result; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + ret = MtCmdGetTxPower(ad, band_idx, channel, ant_idx, &txpwr_result); + *power = (u_int32)txpwr_result.i1TargetPower; + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD; + + return ret; +} + +s_int32 mt_op_set_tx_pwr( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_char band_idx, + struct test_txpwr_param *pwr_param) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + struct test_txpwr_cfg txpwr_cfg; + ATE_TXPOWER txpwr; + + /* sanity check for null pointer */ + if (!pwr_param) + return SERV_STATUS_HAL_OP_INVALID_NULL_POINTER; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + txpwr_cfg.ant_idx = pwr_param->ant_idx; + txpwr_cfg.txpwr = configs->tx_pwr[pwr_param->ant_idx]; + txpwr_cfg.channel = configs->channel; + txpwr_cfg.band_idx = band_idx; + txpwr_cfg.ch_band = configs->ch_band; + + sys_ad_zero_mem(&txpwr, sizeof(ATE_TXPOWER)); + sys_ad_move_mem(&txpwr, &txpwr_cfg, sizeof(ATE_TXPOWER)); + ret = MtCmdSetTxPowerCtrl(ad, txpwr); + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD; + + return ret; +} + +s_int32 mt_op_get_freq_offset( + struct test_wlan_info *winfos, + u_char band_idx, + u_int32 *freq_offset) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + ret = MtCmdGetFreqOffset(ad, band_idx, freq_offset); + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD; + + return ret; +} + +s_int32 mt_op_get_cfg_on_off( + struct test_wlan_info *winfos, + u_char band_idx, + u_int32 type, + u_int32 *result) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + ret = MtCmdGetCfgOnOff(ad, type, band_idx, result); + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD; + + return ret; +} + +s_int32 mt_op_get_tx_tone_pwr( + struct test_wlan_info *winfos, + u_char band_idx, + u_int32 ant_idx, + u_int32 *power) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + ret = MtCmdRfTestGetTxTonePower(ad, power, ant_idx, band_idx); + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD; + + return ret; +} + +s_int32 mt_op_get_recal_cnt( + struct test_wlan_info *winfos, + u_int32 *recal_cnt, + u_int32 *recal_dw_num) +{ + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_get_recal_content( + struct test_wlan_info *winfos, + u_int32 *content) +{ + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_get_rxv_cnt( + struct test_wlan_info *winfos, + u_int32 *rxv_cnt, + u_int32 *rxv_dw_num) +{ + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_get_rxv_content( + struct test_wlan_info *winfos, + u_int32 dw_cnt, + u_int32 *content) +{ + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_set_cal_bypass( + struct test_wlan_info *winfos, + u_char band_idx, + u_int32 cal_item) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + ret = MtCmdDoCalibration(ad, CALIBRATION_BYPASS, cal_item, band_idx); + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD; + + return ret; +} + +s_int32 mt_op_set_dpd( + struct test_wlan_info *winfos, + u_int32 on_off, + u_int32 wf_sel) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + ret = MtAsicSetDPD(ad, on_off, wf_sel); + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD; + + return ret; +} + +s_int32 mt_op_set_tssi( + struct test_wlan_info *winfos, + u_int32 on_off, + u_int32 wf_sel) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + ret = MtAsicSetTSSI(ad, on_off, wf_sel); + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD; + + return ret; +} + +s_int32 mt_op_get_thermal_val( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_char band_idx, + u_int32 *value) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + /* 0: get temperature; 1: get adc */ + ret = MtCmdGetThermalSensorResult(ad, 0, + band_idx, value); + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD; + + return ret; +} + +s_int32 mt_op_set_rdd_test( + struct test_wlan_info *winfos, + u_int32 rdd_idx, + u_int32 rdd_sel, + u_int32 enable) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: rdd_idx: %d, rdd_sel: %d, enable:%d\n", + __func__, rdd_idx, rdd_sel, enable)); + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + ret = MtCmdSetRDDTestExt(ad, rdd_idx, rdd_sel, enable); + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD; + + return ret; +} + +s_int32 mt_op_set_off_ch_scan( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_char band_idx, + struct test_off_ch_param *param) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + EXT_CMD_OFF_CH_SCAN_CTRL_T ext_cmd_param; + u_char ch = 0; + u_char work_tx_strm_pth = 0, work_rx_strm_pth = 0, off_ch_idx = 0; + u_char ch_ext_index = 0; + u_char ch_ext_above[] = { + 36, 44, 52, 60, + 100, 108, 116, 124, + 132, 140, 149, 157, 0 + }; + u_char ch_ext_below[] = { + 40, 48, 56, 64, + 104, 112, 120, 128, + 136, 144, 153, 161, 0 + }; + u_char prim_ch[off_ch_ch_idx_num] = {0, 0}; + u_char bw[off_ch_ch_idx_num] = {0, 0}; + u_char cen_ch[off_ch_ch_idx_num] = {0, 0}; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s ", __func__)); + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + work_tx_strm_pth = configs->tx_ant; + work_rx_strm_pth = configs->rx_strm_pth; + prim_ch[off_ch_wrk_ch_idx] = configs->channel; + bw[off_ch_wrk_ch_idx] = configs->bw; + prim_ch[off_ch_mntr_ch_idx] = param->mntr_ch; + bw[off_ch_mntr_ch_idx] = param->mntr_bw; + + for (off_ch_idx = 0; off_ch_idx < off_ch_ch_idx_num; off_ch_idx++) { + ch = prim_ch[off_ch_idx]; + + /* Initialize index */ + ch_ext_index = 0; + + switch (bw[off_ch_idx]) { + case TEST_BW_20: + break; + + case TEST_BW_40: + while (ch_ext_above[ch_ext_index] != 0) { + if (ch == ch_ext_above[ch_ext_index]) + ch = ch + 2; + else if (ch == ch_ext_below[ch_ext_index]) + ch = ch - 2; + + ch_ext_index++; + } + break; + + case TEST_BW_80: + case TEST_BW_160NC: + ch = vht_cent_ch_freq(ch, VHT_BW_80); + break; + + case TEST_BW_160C: + ch = vht_cent_ch_freq(ch, VHT_BW_160); + break; + + default: + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: off_ch_idx %d, BW is invalid %d\n", + __func__, off_ch_idx, bw[off_ch_idx])); + ret = NDIS_STATUS_FAILURE; + goto err0; + } + + cen_ch[off_ch_idx] = ch; + } + + /* Initialize */ + sys_ad_zero_mem(&ext_cmd_param, sizeof(ext_cmd_param)); + + /* Fill in ext_cmd_param */ + ext_cmd_param.mntr_prim_ch = param->mntr_ch; + ext_cmd_param.mntr_cntrl_ch = cen_ch[off_ch_mntr_ch_idx]; + ext_cmd_param.mntr_bw = bw[off_ch_mntr_ch_idx]; + ext_cmd_param.mntr_tx_strm_pth = param->mntr_tx_rx_pth; + ext_cmd_param.mntr_rx_strm_pth = param->mntr_tx_rx_pth; + + ext_cmd_param.work_prim_ch = prim_ch[off_ch_wrk_ch_idx]; + ext_cmd_param.work_cntrl_ch = cen_ch[off_ch_wrk_ch_idx]; + ext_cmd_param.work_bw = bw[off_ch_wrk_ch_idx]; + ext_cmd_param.work_tx_strm_pth = work_tx_strm_pth; + ext_cmd_param.work_rx_strm_pth = work_rx_strm_pth; + + ext_cmd_param.dbdc_idx = param->dbdc_idx; + ext_cmd_param.scan_mode = param->scan_mode; + ext_cmd_param.is_aband = param->is_aband; + ext_cmd_param.off_ch_scn_type = off_ch_scan_simple_rx; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: mntr_ch:%d mntr_bw:%d mntr_central_ch:%d\n", + __func__, ext_cmd_param.mntr_prim_ch, + ext_cmd_param.mntr_bw, ext_cmd_param.mntr_cntrl_ch)); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: work_prim_ch:%d work_bw:%d work_central_ch:%d\n", + __func__, ext_cmd_param.work_prim_ch, + ext_cmd_param.work_bw, ext_cmd_param.work_cntrl_ch)); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: scan_mode:%d dbdc_idx:%d is_aband:%d\n", + __func__, ext_cmd_param.scan_mode, + ext_cmd_param.dbdc_idx, ext_cmd_param.is_aband)); + + ret = mt_cmd_off_ch_scan(ad, &ext_cmd_param); + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD; + + return ret; + +err0: + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: invalid parameters\n", __func__)); + return ret; +} + +s_int32 mt_op_get_rdd_cnt( + struct test_wlan_info *winfos, + u_int32 *rdd_cnt, + u_int32 *rdd_dw_num) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + /* refactor after log onoff feature ready */ + struct _ATE_CTRL *ATECtrl = NULL; + struct _ATE_LOG_DUMP_CB *log_cb = NULL; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s:\n", __func__)); + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + ATECtrl = &(ad->ATECtrl); + log_cb = &(ATECtrl->log_dump[ATE_LOG_RDD-1]); + + /* radar pulse number */ + *rdd_cnt = log_cb->idx; + /* RDD buffer size */ + *rdd_dw_num = log_cb->len; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: radar pulse number is %d, RDD buffer size is %d\n", + __func__, log_cb->idx, log_cb->len)); + + return ret; +} + + +s_int32 mt_op_get_rdd_content( + struct test_wlan_info *winfos, + u_int32 *content, + u_int32 *total_cnt) +{ + static u_int32 idx; + s_int32 ret = SERV_STATUS_SUCCESS; + u_int32 end = 0, remindIdx = 0; + RTMP_ADAPTER *ad = NULL; + struct _ATE_CTRL *ATECtrl = NULL; + struct _ATE_LOG_DUMP_CB *log_cb = NULL; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s:\n", __func__)); + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + ATECtrl = &(ad->ATECtrl); + log_cb = &(ATECtrl->log_dump[ATE_LOG_RDD-1]); + + if (log_cb == NULL) { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: log_cb == NULL\n", __func__)); + return SERV_STATUS_HAL_OP_INVALID_PAD; + } + + /* Prepare for RDD dump */ + /* refactor after log onoff feature ready */ + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("[RDD DUMP START][HQA_GetDumpRDD]\n")); + ad->fgDumpStart = 1; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: radar pulse number is %d, RDD buffer size is %d\n", + __func__, log_cb->idx, log_cb->len)); + + if ((ATECtrl->firstRDD == TRUE) || (ATECtrl->firstQATool == TRUE)) { + /* + * Reset idx - 1. HQA RDD dump (re-)enable + * Reset idx - 2. HQA Tool (re-)open + */ + idx = 0; + } + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, ("idx: %d\n", idx)); + /* If log_cb->idx greater than log_cb->len(RDDBufferSize), + * it will re-count from 0 + */ + remindIdx = (idx > log_cb->idx) ? + ((log_cb->idx + log_cb->len) - idx) : + (log_cb->idx - idx); + + end = (remindIdx > MAX_RDD_DUMP_SIZE) ? + ((idx + MAX_RDD_DUMP_SIZE) % (log_cb->len)) : + ((idx + remindIdx) % (log_cb->len)); + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("remindIdx: %d, end: %d\n", remindIdx, end)); + + /* log on/off is not ready */ + + return ret; +} + + +s_int32 mt_op_set_muru_manual( + void *virtual_device, + struct test_wlan_info *winfos, + struct test_configuration *configs) +{ +#if defined(CFG_SUPPORT_FALCON_MURU) + RTMP_ADAPTER *ad = NULL; + u_int8 ru_seq = 0, wmm_idx = 0; + CMD_MURU_MANCFG_INTERFACER MuruManCfg; + struct _MAC_TABLE_ENTRY *mac_tbl_entry = NULL; + struct test_tx_stack *stack = &configs->stack; + struct test_ru_info *ru_info = &configs->ru_info_list[0]; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + mac_tbl_entry = (struct _MAC_TABLE_ENTRY *)stack->virtual_wtbl[0]; + + sys_ad_zero_mem(&MuruManCfg, sizeof(MuruManCfg)); + + MuruManCfg.rCfgCmm.u1PpduFmt = MURU_PPDU_HE_MU; + MuruManCfg.u4ManCfgBmpCmm = MURU_FIXED_CMM_PPDU_FMT; + net_ad_get_band_idx(virtual_device, &MuruManCfg.rCfgCmm.u1Band); + MuruManCfg.u4ManCfgBmpCmm |= MURU_FIXED_CMM_BAND; + net_ad_get_wmm_idx(virtual_device, &wmm_idx); + MuruManCfg.rCfgCmm.u1WmmSet = wmm_idx; + MuruManCfg.u4ManCfgBmpCmm |= MURU_FIXED_CMM_WMM_SET; + if (configs->per_pkt_bw > TEST_BW_80) + MuruManCfg.rCfgDl.u1Bw = 0x3; /* 0x3 imply 80+80/160 */ + else + MuruManCfg.rCfgDl.u1Bw = configs->per_pkt_bw; + MuruManCfg.u4ManCfgBmpDl |= MURU_FIXED_BW; + MuruManCfg.rCfgDl.u1SigBMcs = (configs->mcs & 0xf); + MuruManCfg.u4ManCfgBmpDl |= MURU_FIXED_SIGB_MCS; + MuruManCfg.rCfgDl.u1SigBDcm = ((configs->mcs & BIT5) ? 0x1 : 0); + MuruManCfg.u4ManCfgBmpDl |= MURU_FIXED_SIGB_DCM; + MuruManCfg.rCfgDl.u1TxMode = configs->tx_mode; + MuruManCfg.u4ManCfgBmpDl |= MURU_FIXED_TX_MODE; + MuruManCfg.rCfgDl.u1UserCnt = stack->index; + MuruManCfg.u4ManCfgBmpDl |= MURU_FIXED_TOTAL_USER_CNT; + sys_ad_move_mem(&MuruManCfg.rCfgDl.au1RU, + &configs->ru_alloc, + sizeof(configs->ru_alloc)); + MuruManCfg.u4ManCfgBmpDl |= MURU_FIXED_TONE_PLAN; + MuruManCfg.rCfgDl.u1GI = configs->stack.tx_info[0].gi; + MuruManCfg.rCfgDl.u1Ltf = configs->stack.tx_info[0].ltf; + MuruManCfg.u4ManCfgBmpDl |= (MURU_FIXED_GI | MURU_FIXED_LTF); + for (ru_seq = 0 ; ru_seq < MAX_MULTI_TX_STA ; ru_seq++) { + u_int8 seg = 0, alloc = 0; + MURU_DL_USER_INFO *user_info = NULL; + struct phy_params *phy_param = NULL; + + if (ru_info[ru_seq].valid) { + user_info = &MuruManCfg.rCfgDl.arUserInfoDl[ru_seq]; + seg = (ru_info[ru_seq].ru_index & 0x1); + alloc = (ru_info[ru_seq].ru_index >> 1); + phy_param = &mac_tbl_entry[ru_seq].phy_param; + + user_info->u2WlanIdx = mac_tbl_entry[ru_seq].wcid; + user_info->u1RuAllocBn = seg; + user_info->u1RuAllocIdx = alloc; + user_info->u1Mcs = (phy_param->rate & 0xf); + + if (phy_param->rate & BIT5) /* DCM required */ + user_info->u1Mcs |= BIT4; + + user_info->u1Nss = phy_param->vht_nss-1; + user_info->u1Ldpc = phy_param->ldpc; + + if ((ru_info[ru_seq].ru_index >> 1) == 18) { + u_int8 *au1C26 = NULL; + + au1C26 = MuruManCfg.rCfgDl.au1C26; + au1C26[(ru_info[ru_seq].ru_index & 1)] = 1; + } + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: Add user[%d] wcid:%d, ru index:%d,\n", + __func__, ru_seq, user_info->u2WlanIdx, + user_info->u1RuAllocIdx)); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("\t\tsegment:%d, mcs:%d\n", + user_info->u1RuAllocBn, + user_info->u1Mcs)); + } + } + MuruManCfg.u4ManCfgBmpDl |= MURU_FIXED_USER_WLAN_ID; + MuruManCfg.u4ManCfgBmpDl |= MURU_FIXED_USER_COD; + MuruManCfg.u4ManCfgBmpDl |= MURU_FIXED_USER_MCS; + MuruManCfg.u4ManCfgBmpDl |= MURU_FIXED_USER_NSS; + MuruManCfg.u4ManCfgBmpDl |= MURU_FIXED_USER_RU_ALLOC; + + wifi_test_muru_set_manual_config(ad, &MuruManCfg); +#endif /* CFG_SUPPORT_FALCON_MURU */ + + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_set_tam_arb( + struct test_wlan_info *winfos, + u_int8 arb_op_mode) +{ +#if defined(CFG_SUPPORT_FALCON_MURU) + RTMP_ADAPTER *ad = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + wifi_test_muru_set_arb_op_mode(ad, arb_op_mode); +#endif /* CFG_SUPPORT_FALCON_MURU */ + + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_op_get_rx_stat_band( + struct test_wlan_info *winfos, + u_int8 band_idx, + u_int8 blk_idx, + struct test_rx_stat_band_info *rx_st_band) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + TEST_RX_STAT_BAND_INFO st; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + ret = chip_get_rx_stat_band(ad, band_idx, blk_idx, &st); + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD; + + rx_st_band->mac_rx_fcs_err_cnt = st.mac_rx_fcs_err_cnt; + rx_st_band->mac_rx_mdrdy_cnt = st.mac_rx_mdrdy_cnt; + rx_st_band->mac_rx_len_mismatch = st.mac_rx_len_mismatch; + rx_st_band->mac_rx_fcs_ok_cnt = st.mac_rx_fcs_ok_cnt; + rx_st_band->phy_rx_fcs_err_cnt_cck = st.phy_rx_fcs_err_cnt_cck; + rx_st_band->phy_rx_fcs_err_cnt_ofdm = st.phy_rx_fcs_err_cnt_ofdm; + rx_st_band->phy_rx_pd_cck = st.phy_rx_pd_cck; + rx_st_band->phy_rx_pd_ofdm = st.phy_rx_pd_ofdm; + rx_st_band->phy_rx_sig_err_cck = st.phy_rx_sig_err_cck; + rx_st_band->phy_rx_sfd_err_cck = st.phy_rx_sfd_err_cck; + rx_st_band->phy_rx_sig_err_ofdm = st.phy_rx_sig_err_ofdm; + rx_st_band->phy_rx_tag_err_ofdm = st.phy_rx_tag_err_ofdm; + rx_st_band->phy_rx_mdrdy_cnt_cck = st.phy_rx_mdrdy_cnt_cck; + rx_st_band->phy_rx_mdrdy_cnt_ofdm = st.phy_rx_mdrdy_cnt_ofdm; + + return ret; +} + +s_int32 mt_op_get_rx_stat_path( + struct test_wlan_info *winfos, + u_int8 band_idx, + u_int8 blk_idx, + struct test_rx_stat_path_info *rx_st_path) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + TEST_RX_STAT_PATH_INFO st; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + ret = chip_get_rx_stat_path(ad, band_idx, blk_idx, &st); + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD; + + rx_st_path->rcpi = st.rcpi; + rx_st_path->rssi = st.rssi; + rx_st_path->fagc_ib_rssi = st.fagc_ib_rssi; + rx_st_path->fagc_wb_rssi = st.fagc_wb_rssi; + rx_st_path->inst_ib_rssi = st.inst_ib_rssi; + rx_st_path->inst_wb_rssi = st.inst_wb_rssi; + + return ret; +} + +s_int32 mt_op_get_rx_stat_user( + struct test_wlan_info *winfos, + u_int8 band_idx, + u_int8 blk_idx, + struct test_rx_stat_user_info *rx_st_user) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + TEST_RX_STAT_USER_INFO st; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + ret = chip_get_rx_stat_user(ad, band_idx, blk_idx, &st); + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD; + + rx_st_user->freq_offset_from_rx = st.freq_offset_from_rx; + rx_st_user->snr = st.snr; + rx_st_user->fcs_error_cnt = st.fcs_error_cnt; + + return ret; +} + +s_int32 mt_op_get_rx_stat_comm( + struct test_wlan_info *winfos, + u_int8 band_idx, + u_int8 blk_idx, + struct test_rx_stat_comm_info *rx_st_comm) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + TEST_RX_STAT_COMM_INFO st; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + ret = chip_get_rx_stat_comm(ad, band_idx, blk_idx, &st); + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD; + + rx_st_comm->rx_fifo_full = st.rx_fifo_full; + rx_st_comm->aci_hit_low = st.aci_hit_low; + rx_st_comm->aci_hit_high = st.aci_hit_high; + rx_st_comm->mu_pkt_count = st.mu_pkt_count; + rx_st_comm->sig_mcs = st.sig_mcs; + rx_st_comm->sinr = st.sinr; + rx_st_comm->driver_rx_count = st.driver_rx_count; + + return ret; +} + +s_int32 mt_op_get_wf_path_comb( + struct test_wlan_info *winfos, + u_int8 band_idx, + boolean dbdc_mode_en, + u_int8 *path, + u_int8 *path_len) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + ret = chip_get_wf_path_comb(ad, band_idx, dbdc_mode_en, path, path_len); + if (ret) + ret = SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD; + + return ret; +} + +s_int32 mt_op_hetb_ctrl( + struct test_wlan_info *winfos, + u_char band_idx, + u_char ctrl_type, + boolean enable, + u_int8 bw, + u_int8 ltf_gi, + u_int8 stbc, + u_int8 pri_ru_idx, + struct test_ru_info *ru_info) +{ + s_int32 ret = SERV_STATUS_SUCCESS; +#if defined(DOT11_HE_AX) + RTMP_ADAPTER *ad = NULL; + struct _RTMP_CHIP_DBG *chip_dbg = NULL; + struct _ATE_RU_STA *ru = (struct _ATE_RU_STA *)ru_info; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + chip_dbg = hc_get_chip_dbg(ad->hdev_ctrl); + + if (ctrl_type == OP_HETB_RX_CFG) { + u_int64 hetb_rx_csd = 0x240004000060FF; + + if (chip_dbg->ctrl_manual_hetb_rx) + chip_dbg->ctrl_manual_hetb_rx(ad, + band_idx, + enable, + bw, + ltf_gi, + stbc, + hetb_rx_csd, + &ru[pri_ru_idx], + ru); + else + ret = SERV_STATUS_HAL_OP_FAIL; + } else { + if (chip_dbg->ctrl_manual_hetb_tx) + chip_dbg->ctrl_manual_hetb_tx(ad, + band_idx, + ctrl_type, + bw, + ltf_gi, + stbc, + ru); + else + ret = SERV_STATUS_HAL_OP_FAIL; + } +#endif /* DOT11_HE_AX */ + return ret; +} + +s_int32 mt_op_set_ru_aid( + struct test_wlan_info *winfos, + u_char band_idx, + u_int16 mu_rx_aid) +{ + s_int32 ret = SERV_STATUS_SUCCESS; +#ifdef CONFIG_HW_HAL_OFFLOAD + RTMP_ADAPTER *ad = NULL; + struct _EXT_CMD_ATE_TEST_MODE_T param; + u_int8 testmode_en = 1; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + sys_ad_zero_mem(¶m, sizeof(param)); + param.ucAteTestModeEn = testmode_en; + param.ucAteIdx = ENUM_ATE_SET_MU_RX_AID; + param.Data.set_mu_rx_aid.band_idx = band_idx; + param.Data.set_mu_rx_aid.aid = cpu2le16(mu_rx_aid); + + param.aucReserved[1] = INIT_CMD_SET_AND_WAIT_RETRY_RSP; + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s: Set to decode MU accodring to AID:%d\n", + __func__, param.Data.set_mu_rx_aid.aid)); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("\t\t(%d means disable)\n", 0xf800)); + ret = MtCmdATETest(ad, ¶m); + + if (ret != 0) + ret = SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD; +#endif + + return ret; +} + +s_int32 mt_op_set_mutb_spe( + struct test_wlan_info *winfos, + u_char band_idx, + u_char tx_mode, + u_int8 spe_idx) +{ + RTMP_ADAPTER *ad = NULL; + struct _RTMP_CHIP_DBG *chip_dbg = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_OP_INVALID_PAD; + + chip_dbg = hc_get_chip_dbg(ad->hdev_ctrl); + if (chip_dbg->chip_ctrl_spe) + chip_dbg->chip_ctrl_spe(ad, band_idx, tx_mode, spe_idx); + + return SERV_STATUS_SUCCESS; +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/glue/hal/jedi/test_dmac.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/glue/hal/jedi/test_dmac.c new file mode 100644 index 0000000000000000000000000000000000000000..c735e1266983ebf5eb16c2d314ab19b3681e6a57 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/glue/hal/jedi/test_dmac.c @@ -0,0 +1,131 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#include "rt_config.h" +#include "test_mac.h" + +s_int32 mt_test_mac_backup_and_set_cr( + struct test_wlan_info *winfos, + struct test_bk_cr *bks, + u_char band_idx) +{ + struct _RTMP_CHIP_OP *ops = hc_get_chip_ops(winfos->hdev_ctrl); + RTMP_ADAPTER *ad = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_MAC_INVALID_PAD; + + if (ops->backup_reg_before_ate) + ops->backup_reg_before_ate(ad); + else + return SERV_STATUS_HAL_MAC_INVALID_CHIPOPS; + +#if 0 +#ifndef MT7615 + if (!IS_MT7615(pAd)) { + /* VHT20 MCS9 Support on LDPC Mode */ + net_ad_backup_cr(winfos, bks, + WF_WTBLOFF_TOP_LUECR_ADDR, SERV_TEST_MAC_BKCR); + MAC_IO_READ32(ad->hdev_ctrl, WF_WTBLOFF_TOP_LUECR_ADDR, &val); + val = 0xFFFFFFFF; + MAC_IO_WRITE32(ad->hdev_ctrl, WF_WTBLOFF_TOP_LUECR_ADDR, val); + } +#endif /* !defined(MT7615) */ +#endif + + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_test_mac_restore_cr( + struct test_wlan_info *winfos, + struct test_bk_cr *bks, + u_char band_idx) +{ + struct _RTMP_CHIP_OP *ops = hc_get_chip_ops(winfos->hdev_ctrl); + RTMP_ADAPTER *ad = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_MAC_INVALID_PAD; + + if (ops->restore_reg_after_ate) + ops->restore_reg_after_ate(ad); + else + return SERV_STATUS_HAL_MAC_INVALID_CHIPOPS; + +#if 0 +#ifndef MT7615 + if (!IS_MT7615(pAd)) { + /* VHT20 MCS9 Support on LDPC Mode backup */ + net_ad_restore_cr(winfos, WF_WTBLOFF_TOP_LUECR_ADDR); + } +#endif /* defined(MT7663) */ +#endif + + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_test_mac_set_ampdu_ba_limit( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_int8 agg_limit) +{ + struct _RTMP_CHIP_OP *ops = hc_get_chip_ops(winfos->hdev_ctrl); + RTMP_ADAPTER *ad = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_MAC_INVALID_PAD; + + if (ops->set_ba_limit) + ops->set_ba_limit(ad, configs->wmm_idx, agg_limit); + else + return SERV_STATUS_HAL_MAC_INVALID_CHIPOPS; + + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_test_mac_set_sta_pause_cr( + struct test_wlan_info *winfos) +{ + RTMP_ADAPTER *ad = NULL; + struct _RTMP_CHIP_OP *ops = hc_get_chip_ops(winfos->hdev_ctrl); + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_MAC_INVALID_PAD; + + if (ops->pause_ac_queue) + ops->pause_ac_queue(ad, 0xf); + else + return SERV_STATUS_HAL_MAC_INVALID_CHIPOPS; + + return SERV_STATUS_SUCCESS; +} + +s_int32 mt_test_mac_set_ifs_cr( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_char band_idx) +{ + RTMP_ADAPTER *ad = NULL; + struct _RTMP_CHIP_OP *ops = hc_get_chip_ops(winfos->hdev_ctrl); + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_HAL_MAC_INVALID_PAD; + + if (ops->set_ifs) + ops->set_ifs(ad, band_idx); + else + return SERV_STATUS_HAL_MAC_INVALID_CHIPOPS; + + return SERV_STATUS_SUCCESS; +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/glue/hal/jedi/test_fmac.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/glue/hal/jedi/test_fmac.c new file mode 100644 index 0000000000000000000000000000000000000000..8d80d8cb6827ae13348e52d094d1ce9a9af0c770 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/glue/hal/jedi/test_fmac.c @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#include "rt_config.h" +#include "test_mac.h" diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/glue/osal/gen4m/net_adaption_gen4m.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/glue/osal/gen4m/net_adaption_gen4m.c new file mode 100644 index 0000000000000000000000000000000000000000..3092df940d5be9a2917e68193b1489cc2bfdbfad --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/glue/osal/gen4m/net_adaption_gen4m.c @@ -0,0 +1,414 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#include "net_adaption.h" +#define GEM4M_NET_ADAPTION_SUPPORT 0 +#if GEM4M_NET_ADAPTION_SUPPORT +static struct test_thread_cb g_test_thread[SERV_THREAD_NUM]; +#endif + +struct service_test *net_ad_wrap_service(void *adapter) +{ + return (struct service_test *)adapter; +} + +void net_ad_thread_proceed_tx( + struct test_wlan_info *winfos, u_char band_idx) +{ +} + +void net_ad_thread_stop_tx( + struct test_wlan_info *winfos) +{ +} + +s_int32 net_ad_init_thread( + struct test_wlan_info *winfos, + struct test_configuration *configs, + enum service_thread_list thread_idx) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_release_thread(u_char thread_idx) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_backup_cr( + struct test_wlan_info *winfos, struct test_bk_cr *test_bkcr, + u_long offset, enum test_bk_cr_type type) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_restore_cr( + struct test_wlan_info *winfos, struct test_bk_cr *test_bkcr, + u_long offset) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_cfg_queue( + struct test_wlan_info *winfos, boolean enable) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_enter_normal( + struct test_wlan_info *winfos, + struct test_backup_params *bak) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_exit_normal( + struct test_wlan_info *winfos, + struct test_backup_params *bak) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_update_wdev( + u_int8 band_idx, + struct test_wlan_info *winfos, + struct test_configuration *configs) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_init_wdev( + struct test_wlan_info *winfos, + struct test_configuration *configs, u_char band_idx) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_release_wdev( + struct test_wlan_info *winfos, + struct test_configuration *configs) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_alloc_wtbl( + struct test_wlan_info *winfos, + u_char *da, + void *virtual_dev, + void **virtual_wtbl) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_free_wtbl( + struct test_wlan_info *winfos, + u_char *da, + void *virtual_wtbl) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_apply_wtbl( + struct test_wlan_info *winfos, + void *virtual_dev, + void *virtual_wtbl) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_match_wtbl( + void *virtual_wtbl, + u_int16 wcid) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_set_aid( + void *virtual_wtbl, + u_int16 aid) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_get_wmm_idx( + void *virtual_device, + u_int8 *wmm_idx) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_get_band_idx( + void *virtual_device, + u_char *band_idx) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_get_omac_idx( + struct test_wlan_info *winfos, + void *virtual_device, + u_char *omac_idx) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_fill_phy_info( + void *virtual_wtbl, + struct test_tx_info *tx_info) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_get_speidx( + struct test_wlan_info *winfos, + u_int16 ant_sel, + u_int8 *spe_idx) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_fill_spe_antid( + struct test_wlan_info *winfos, + void *virtual_wtbl, + u_int8 spe_idx, + u_int8 ant_pri) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_fill_pkt( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_char *buf, u_int32 txlen, u_int32 hlen) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_alloc_pkt( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_int32 mpdu_length, + void **pkt_skb) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_enq_pkt( + struct test_wlan_info *winfos, + u_short q_idx, + void *virtual_wtbl, + void *virtual_device, + void *pkt) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_free_pkt( + struct test_wlan_info *winfos, + void *pkt_skb) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_trigger_tx( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_int8 band_idx, + void *pkt) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_rx_done_handle( + struct test_wlan_info *winfos, + void *rx_blk) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_set_band_mode( + struct test_wlan_info *winfos, + struct test_band_state *band_state) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_set_txpwr_power_drop( + struct test_wlan_info *winfos, + u_char power_drop, u_char band_idx) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_set_txpwr_percentage( + struct test_wlan_info *winfos, + u_char percentage_ctrl, u_char band_idx) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_set_txpwr_backoff( + struct test_wlan_info *winfos, + u_char backoff_ctrl, u_char band_idx) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_init_txpwr( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_char band_idx) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_handle_mcs32( + struct test_wlan_info *winfos, + void *virtual_wtbl, u_int8 bw) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_cfg_wtbl( + struct test_wlan_info *winfos, + struct test_configuration *configs) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_set_wmm_param_by_qid( + u_int8 wmm_idx, + u_int8 q_idx, + struct test_wlan_info *winfos, + struct test_configuration *configs) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_clean_sta_q( + struct test_wlan_info *winfos, u_char wcid) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_set_auto_resp( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_char band_idx, u_char mode) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_set_low_power( + struct test_wlan_info *winfos, u_int32 control) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_read_mac_bbp_reg( + struct test_wlan_info *winfos, + struct test_register *regs) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_write_mac_bbp_reg( + struct test_wlan_info *winfos, + struct test_register *regs) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_read_bulk_mac_bbp_reg( + struct test_wlan_info *winfos, + struct test_configuration *configs, + struct test_register *regs) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_read_bulk_rf_reg( + struct test_wlan_info *winfos, + struct test_register *regs) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_write_bulk_rf_reg( + struct test_wlan_info *winfos, + struct test_register *regs) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +void net_ad_read_ca53_reg(struct test_register *regs) +{ +} + +void net_ad_write_ca53_reg(struct test_register *regs) +{ +} + +s_int32 net_ad_read_write_eeprom( + struct test_wlan_info *winfos, + struct test_eeprom *eprms, + boolean is_read) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_read_write_bulk_eeprom( + struct test_wlan_info *winfos, + struct test_eeprom *eprms, + boolean is_read) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_get_free_efuse_block( + struct test_wlan_info *winfos, + struct test_eeprom *eprms) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_mps_tx_operation( + struct test_wlan_info *winfos, + struct test_configuration *configs, + boolean is_start_tx) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_set_tmr( + struct test_wlan_info *winfos, + struct test_tmr_info *tmr_info) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_get_rxv_stat( + struct test_wlan_info *winfos, + u_char ctrl_band_idx, + struct test_rx_stat *rx_stat) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_get_rxv_cnt( + struct test_wlan_info *winfos, + u_char ctrl_band_idx, + u_int32 *byte_cnt) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + +s_int32 net_ad_get_rxv_content( + struct test_wlan_info *winfos, + u_char ctrl_band_idx, + void *content) +{ + return SERV_STATUS_OSAL_NET_FAIL; +} + diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/glue/osal/gen4m/sys_adaption_gen4m.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/glue/osal/gen4m/sys_adaption_gen4m.c new file mode 100644 index 0000000000000000000000000000000000000000..019782e6a4a5cbe6b89f87ae6e5f5ab3c2a1b82f --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/glue/osal/gen4m/sys_adaption_gen4m.c @@ -0,0 +1,98 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#include "sys_adaption.h" +#include "gl_os.h" +#include "gl_kal.h" +#include "gl_wext.h" +#include "precomp.h" +#include "debug.h" + +#define UNUSED(x) ((void)(x)) +/***************************************************************************** + * Packet free related functions + *****************************************************************************/ +void sys_ad_free_pkt(void *packet) +{ + +} + +/***************************************************************************** + * OS memory allocate/manage/free related functions + *****************************************************************************/ +s_int32 sys_ad_alloc_mem(u_char **mem, u_long size) +{ + *mem = (u_char *)kalMemAlloc(size, PHY_MEM_TYPE); + + if (*mem) + return SERV_STATUS_SUCCESS; + else + return SERV_STATUS_OSAL_SYS_FAIL; +} + +void sys_ad_free_mem(void *mem) +{ + ASSERT(mem); + kfree(mem); +} + +void sys_ad_zero_mem(void *ptr, u_long length) +{ + kalMemZero(ptr, length); +} + +void sys_ad_set_mem(void *ptr, u_long length, u_char value) +{ + kalMemSet(ptr, value, length); +} + + +void sys_ad_move_mem(void *dest, void *src, u_long length) +{ + kalMemMove(dest, src, length); +} + +s_int32 sys_ad_cmp_mem(void *dest, void *src, u_long length) +{ + return kalMemCmp(dest, src, length); +} + +/***************************************************************************** + * OS task create/manage/kill related functions + *****************************************************************************/ +s_int32 sys_ad_kill_os_task(struct serv_os_task *task) +{ + return SERV_STATUS_SUCCESS; +} + +s_int32 sys_ad_attach_os_task( + struct serv_os_task *task, SERV_OS_TASK_CALLBACK fn, u_long arg) +{ + return SERV_STATUS_SUCCESS; +} + +s_int32 sys_ad_init_os_task( + struct serv_os_task *task, char *task_name, + void *priv_winfos, void *priv_configs) +{ + return SERV_STATUS_SUCCESS; +} + +boolean sys_ad_wait_os_task( + void *reserved, struct serv_os_task *task, s_int32 *status) +{ + return SERV_STATUS_SUCCESS; +} + +void sys_ad_wakeup_os_task(struct serv_os_task *task) +{ + UNUSED(task); +} +/***************************************************************************** + * OS debug functions + *****************************************************************************/ +void sys_ad_mem_dump32(void *ptr, u_long length) +{ + dumpMemory32((s_int32 *)ptr, length); +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/glue/osal/include/net_adaption.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/glue/osal/include/net_adaption.h new file mode 100644 index 0000000000000000000000000000000000000000..b873f14e102be2249ab9bb497ea323613b179df8 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/glue/osal/include/net_adaption.h @@ -0,0 +1,1733 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#ifndef __NET_ADAPTION_H__ +#define __NET_ADAPTION_H__ + +#include "sys_adaption.h" + +/***************************************************************************** + * Type definition + *****************************************************************************/ + + +/***************************************************************************** + * Macro + *****************************************************************************/ +/* Service DBDC configuration */ +#define TEST_DBDC_BAND0 0 +#define TEST_DBDC_BAND1 1 + +/* #ifdef DBDC_MODE */ +#if 1 +#define SET_TEST_DBDC(_test_winfo, _boolean) \ + (_test_winfo->dbdc_mode = _boolean) +#define IS_TEST_DBDC(_test_winfo) _test_winfo->dbdc_mode +#define TEST_DBDC_BAND_NUM 2 +#else +#define IS_TEST_DBDC(_test_winfo) FALSE +#define TEST_DBDC_BAND_NUM 1 +#endif + +/* Packet */ +#define SERV_LENGTH_802_11 24 + +/* For rx stat type */ +#define SERV_TEST_RX_STAT_MACFCSERRCNT 0x1 +#define SERV_TEST_RX_STAT_MAC_MDRDYCNT 0x2 +#define SERV_TEST_RX_STAT_PHY_MDRDYCNT 0x3 +#define SERV_TEST_RX_STAT_PHY_FCSERRCNT 0x4 +#define SERV_TEST_RX_STAT_PD 0x5 +#define SERV_TEST_RX_STAT_CCK_SIG_SFD 0x6 +#define SERV_TEST_RX_STAT_OFDM_SIG_TAG 0x7 +#define SERV_TEST_RX_STAT_RSSI 0x8 +#define SERV_TEST_RX_RESET_PHY_COUNT 0x9 +#define SERV_TEST_RX_RESET_MAC_COUNT 0xa +#define SERV_TEST_RX_STAT_RSSI_RX23 0xB +#define SERV_TEST_RX_STAT_ACI_HITL 0xC +#define SERV_TEST_RX_STAT_ACI_HITH 0xD +#define SERV_TEST_RX_STAT_MACFCSERRCNT_BAND1 0xE +#define SERV_TEST_RX_STAT_MAC_MDRDYCNT_BAND1 0xF +#define SERV_TEST_RX_STAT_MAC_RXLENMISMATCH 0x10 +#define SERV_TEST_RX_STAT_MAC_RXLENMISMATCH_BAND1 0x11 +#define SERV_TEST_RX_FIFO_FULL_COUNT 0x12 +#define SERV_TEST_RX_FIFO_FULL_COUNT_BAND1 0x13 +#define SERV_TEST_RX_STAT_PHY_MDRDYCNT_BAND1 0x14 +#define SERV_TEST_RX_STAT_PHY_FCSERRCNT_BAND1 0x15 +#define SERV_TEST_RX_STAT_PD_BAND1 0x16 +#define SERV_TEST_RX_STAT_CCK_SIG_SFD_BAND1 0x17 +#define SERV_TEST_RX_STAT_OFDM_SIG_TAG_BAND1 0x18 +#define SERV_TEST_RX_ACI_HIT 0x19 +#define SERV_TEST_RX_STAT_MAC_FCS_OK_COUNT 0x1A + +/* MAC behavior control */ +#define SERV_TEST_MAC_TX 1 +#define SERV_TEST_MAC_RX 2 +#define SERV_TEST_MAC_TXRX 3 +#define SERV_TEST_MAC_TXRX_RXV 4 +#define SERV_TEST_MAC_RXV 5 +#define SERV_TEST_MAC_RX_RXV 6 + +/* Setting max packet length to 13311 after MT7615 */ +#define TEST_PKT_LEN 13311 + +#define TEST_MAX_PATTERN_SIZE 128 + +#define TEST_MAX_PKT_LEN 1496 +#define TEST_MIN_PKT_LEN 25 +#define TEST_MAX_BKCR_NUM 30 + +/* For packet tx time, in unit of byte */ +#define TEST_MAX_HT_AMPDU_LEN 65000 +#define TEST_MAX_VHT_MPDU_LEN 6700 /* 11454 */ +#define TEST_DEFAULT_MPDU_LEN 4096 +#define TEST_MAX_MSDU_LEN 2304 +#define TEST_MIN_MSDU_LEN 22 +#define TEST_DEFAULT_MAC_HDR_LEN 24 +#define TEST_QOS_MAC_HDR_LEN 26 + +/* For ipg and duty cycle, in unit of us */ +#define TEST_SIG_EXTENSION 6 +#define TEST_DEFAULT_SLOT_TIME 9 +#define TEST_DEFAULT_SIFS_TIME 10 +/* ICR: 7-bit, ATCR/TRCR limitation: 8-bit/9-bit */ +#define TEST_MAX_SIFS_TIME 127 +#define TEST_MAX_AIFSN 0xF +#define TEST_MIN_AIFSN 0x1 +#define TEST_MAX_CW 0x10 +#define TEST_MIN_CW 0x0 +#define TEST_NORMAL_CLOCK_TIME 50 /* in uint of ns */ +#define TEST_BBP_PROCESSING_TIME 1500 /* in uint of ns */ + +/* Spec related definition */ +#define TEST_RIFS_TIME 2 /* 802.11n */ +/* Refine to 60 from 360 us, 2018.05.09 */ +#define TEST_EIFS_TIME 60 + +/* The expected enqueue packet number when rx event trigger */ +#define TEST_ENQ_PKT_NUM 100 + +#define TEST_RXV_SIZE 9 +#define TEST_ANT_NUM 4 +#define TEST_USER_NUM 16 + +/* MAC address length */ +#define SERV_MAC_ADDR_LEN 6 + +/* Wcid related */ +#define SERV_WCID_ALL 0xFF + +#ifndef IFNAMELEN +#define IFNAMELEN 16 +#endif + +#define SERV_IOCTLBUFF 2048 + +/* Test log dump type */ +#define fTEST_LOG_RXV (1 << TEST_LOG_RXV) +#define fTEST_LOG_RDD (1 << TEST_LOG_RDD) +#define fTEST_LOG_RE_CAL (1 << TEST_LOG_RE_CAL) +#define fTEST_LOG_RXINFO (1 << TEST_LOG_RXINFO) +#define fTEST_LOG_TXDUMP (1 << TEST_LOG_TXDUMP) +#define fTEST_LOG_TEST (1 << TEST_LOG_TEST) +#define fTEST_LOG_TXSSHOW (1 << TEST_LOG_TXSSHOW) + +/* Test ant user select */ +#define TEST_ANT_USER_SEL 0x80000000 + +/* Test mps item length/stat */ +#define TEST_MPS_ITEM_LEN 1024 +#define TEST_MPS_ITEM_RUNNING (1<<0) +#define BITS(m, n) (~(BIT(m)-1) & ((BIT(n) - 1) | BIT(n))) + +#if defined(DOT11_HE_AX) +#define MAX_MULTI_TX_STA 16 +#else +#define MAX_MULTI_TX_STA 2 +#endif + +/***************************************************************************** + * Enum value definition + *****************************************************************************/ +/* Service queue id */ +enum { + SERV_QID_AC_BK, + SERV_QID_AC_BE, + SERV_QID_AC_VI, + SERV_QID_AC_VO, + SERV_QID_HCCA, + SERV_QID_BMC = 8, + SERV_QID_MGMT = 13, + SERV_QID_RX = 14, + SERV_QID_CTRL = 16, + SERV_QID_BCN = 17, +}; + +/* Service rx filter packet type */ +enum { + SERV_RX_FILTER_STBC_BCN_BC_MC = 1 << 0, + SERV_RX_FILTER_FCS_ERROR = 1 << 1, + /* drop 802.11 protocol version not is 0 */ + SERV_RX_FILTER_PROTOCOL_VERSION = 1 << 2, + SERV_RX_FILTER_PROB_REQ = 1 << 3, + /* drop all mcast frame */ + SERV_RX_FILTER_MC_ALL = 1 << 4, + SERV_RX_FILTER_BC_ALL = 1 << 5, + /* drop mcast frame that is not in the mcast table */ + SERV_RX_FILTER_MC_TABLE = 1 << 6, + /* drop bc/mc packet matches the following condition: */ + /* ToDS=0,FromDS=1,A3=OwnMAC0 or OwnMAC1 */ + SERV_RX_FILTER_BC_MC_OWN_MAC_A3 = 1 << 7, + /* drop bc/mc packet matches the following condition: */ + /* ToDS=0,FromDS=0,A3!=BSSID0 or BSSID1 */ + SERV_RX_FILTER_BC_MC_DIFF_BSSID_A3 = 1 << 8, + /* drop bc/mc packet matches the following condition: */ + /* ToDS=0,FromDS=1,A2!=BSSID0 or BSSID1 */ + SERV_RX_FILTER_BC_MC_DIFF_BSSID_A2 = 1 << 9, + /* drop bcn packet and A3!=BSSID0 or BSSID1 */ + SERV_RX_FILTER_BCN_DIFF_BSSID = 1 << 10, + /* drop control packets with reserve type */ + SERV_RX_FILTER_CTRL_RSV = 1 << 11, + SERV_RX_FILTER_CTS = 1 << 12, + SERV_RX_FILTER_RTS = 1 << 13, + /* drop duplicate frame, BA session not includign in this filter */ + SERV_RX_FILTER_DUPLICATE = 1 << 14, + /* drop not my BSSID0/1/2/3 if enabled */ + SERV_RX_FILTER_NOT_OWN_BSSID = 1 << 15, + /* drop uncast packet not to OWN MAC 0/1/2/3/4 */ + SERV_RX_FILTER_NOT_OWN_UCAST = 1 << 16, + /* drop diff bassid TIM broadcast */ + SERV_RX_FILTER_NOT_OWN_BTIM = 1 << 17, + /*drop NDPA control frame */ + SERV_RX_FILTER_NDPA = 1 << 18, +}; + +/* Test DBDC band mode for QA */ +enum test_band_mode { + TEST_BAND_MODE_UNUSE = 0, + TEST_BAND_MODE_SINGLE, + TEST_BAND_MODE_DUAL +}; + +/* Test DBDC band type for QA */ +enum test_band_type { + TEST_BAND_TYPE_UNUSE = 0, + TEST_BAND_TYPE_G, + TEST_BAND_TYPE_A, + TEST_BAND_TYPE_ALL +}; + +/* Test DBDC enable for QA */ +enum test_dbdc_enable { + TEST_DBDC_DISABLE = 0, + TEST_DBDC_ENABLE +}; + +/* HWTX enable for QA */ +enum test_hwtx_enable { + TEST_HWTX_DISABLE = 0, + TEST_HWTX_ENABLE +}; + + +/* Test backup CR type */ +enum test_bk_cr_type { + SERV_TEST_EMPTY_BKCR = 0, + SERV_TEST_MAC_BKCR, + SERV_TEST_HIF_BKCR, + SERV_TEST_PHY_BKCR, + SERV_TEST_HW_BKCR, + SERV_TEST_MCU_BKCR, + SERV_TEST_BKCR_TYPE_NUM +}; + +/* Test tx strategy */ +enum test_tx_strategy { + TEST_TX_STRA_TASKLET = 0, + TEST_TX_STRA_THREAD +}; + +/* Test tx type */ +enum test_tx_type { + TEST_TX_TYPE_TXD = 0, + TEST_TX_TYPE_WTBL +}; + +/* Test rx statistic type */ +enum test_rx_stat_type { + TEST_RX_STAT_RXV, + TEST_RX_STAT_PER_PKT, + TEST_RX_STAT_RESET_CNT, + TEST_RX_STAT_COUNTER_802_11, + TEST_RX_STAT_STAT_TYPE_NUM +}; + +/* Test bw definition */ +enum test_bw_type { + TEST_BW_20 = 0, + TEST_BW_40, + TEST_BW_80, + TEST_BW_10, + TEST_BW_5, + TEST_BW_160C, + TEST_BW_160NC, + TEST_BW_NUM +}; + +/* Test HE LTF definition */ +enum test_he_ltf_type { + TEST_HE_LTF_X1, + TEST_HE_LTF_X2, + TEST_HE_LTF_X4, +}; + +/* Test HE GI definition */ +enum test_he_gi_type { + TEST_GI_8, + TEST_GI_16, + TEST_GI_32, +}; + +/* Test phy mode definition */ +enum test_phy_mode_type { + TEST_MODE_CCK = 0, + TEST_MODE_OFDM, + TEST_MODE_HTMIX, + TEST_MODE_HTGREENFIELD, + TEST_MODE_VHT, + TEST_MODE_HE_24G, + TEST_MODE_HE_5G, + TEST_MODE_HE_SU = 8, + TEST_MODE_HE_ER, + TEST_MODE_HE_TB, + TEST_MODE_HE_MU, + TEST_MODE_VHT_MIMO, + TEST_MODE_NUM +}; + +/* Test payload policy */ +enum { + TEST_USER_PAYLOAD = 0, + TEST_FIXED_PAYLOAD, + TEST_RANDOM_PAYLOAD +}; + +/* Test log dump type */ +enum { + TEST_LOG_RXV = 1, + TEST_LOG_RDD, + TEST_LOG_RE_CAL, + TEST_LOG_TYPE_NUM, + TEST_LOG_RXINFO, + TEST_LOG_TXDUMP, + TEST_LOG_TEST, + TEST_LOG_TXSSHOW, +}; + +enum { + TEST_LOG_OFF, + TEST_LOG_ON, + TEST_LOG_DUMP, + TEST_LOG_CTRL_NUM, +}; + +enum { + TEST_RX_STAT_BAND = 0, + TEST_RX_STAT_PATH, + TEST_RX_STAT_USER, + TEST_RX_STAT_COMM, + TEST_RX_STAT_NUM +}; + +/***************************************************************************** + * Data struct definition + *****************************************************************************/ +/* Service IOCTL related definitions */ +struct serv_ioctl_input { + union { + s_char ifrn_name[IFNAMELEN]; /* if name, e.g. "eth0" */ + } ifr_ifrn; + union { + s_char *name; + struct { + s_char *pointer; + u_int16 length; + u_int16 flags; + } data; + } u; +}; + +/* Servoce spec related data struct */ +struct GNU_PACKED serv_frame_control { +#ifdef RT_BIG_ENDIAN + u_int16 order:1; /* Strict order expected */ + u_int16 wep:1; /* Wep data */ + u_int16 more_data:1; /* More data bit */ + u_int16 pwr_mgmt:1; /* Power management bit */ + u_int16 retry:1; /* Retry status bit */ + u_int16 more_frag:1; /* More fragment bit */ + u_int16 fr_ds:1; /* From DS indication */ + u_int16 to_ds:1; /* To DS indication */ + u_int16 sub_type:4; /* MSDU subtype */ + u_int16 type:2; /* MSDU type */ + u_int16 ver:2; /* Protocol version */ +#else + u_int16 ver:2; /* Protocol version */ + u_int16 type:2; /* MSDU type, refer to FC_TYPE_XX */ + u_int16 sub_type:4; /* MSDU subtype, refer to SUBTYPE_XXX */ + u_int16 to_ds:1; /* To DS indication */ + u_int16 fr_ds:1; /* From DS indication */ + u_int16 more_frag:1; /* More fragment bit */ + u_int16 retry:1; /* Retry status bit */ + u_int16 pwr_mgmt:1; /* Power management bit */ + u_int16 more_data:1; /* More data bit */ + u_int16 wep:1; /* Wep data */ + u_int16 order:1; /* Strict order expected */ +#endif /* !RT_BIG_ENDIAN */ +}; + +struct GNU_PACKED serv_hdr_802_11 { + struct serv_frame_control fc; + u_int16 duration; + u_char addr1[6]; + u_char addr2[6]; + u_char addr3[6]; +#ifdef RT_BIG_ENDIAN + u_int16 sequence:12; + u_int16 frag:4; +#else + u_int16 frag:4; + u_int16 sequence:12; +#endif /* !RT_BIG_ENDIAN */ + u_char octet[0]; +}; + +/* Service fw related information */ +struct serv_fw_info { + boolean ra_offload; + u_int8 chip_id; /* different with top cr*/ + u_int8 eco_ver; + u_int8 num_of_region; + u_int8 format_ver; + u_int8 format_flag; + u_int8 ram_ver[10]; + u_int8 ram_built_date[15]; + u_int32 crc; +}; + +/* Service chip capability related definition */ +struct serv_mcs_nss_caps { + boolean g_band_256_qam; + u_int8 max_nss; + u_int8 max_vht_mcs; + u_int8 bw160_max_nss; +}; + +struct serv_qos_caps { + u_char wmm_hw_num; + u_char wmm_detect_method; + u_int32 txop_scenario; + u_int32 current_txop; + u_int32 default_txop; +}; + +struct serv_spe_map { + u_int8 ant_sel; + u_int8 spe_idx; +}; + +struct serv_spe_map_list { + struct serv_spe_map *spe_map; + u_int8 size; +}; + +struct serv_chip_cap { + /* ------------------------ packet --------------------- */ + /* TxWI or LMAC TxD max size */ + u_int8 tx_wi_size; + /* RxWI or LMAC RxD max size */ + u_int8 rx_wi_size; + /* Tx Hw meta info size which including all hw info fields */ + u_int8 tx_hw_hdr_len; + /* Rx Hw meta info size */ + u_int8 rx_hw_hdr_len; + u_int8 num_of_tx_ring; + u_int8 num_of_rx_ring; + u_int16 tx_ring_size; + u_int8 ht_ampdu_exp; + u_int16 non_he_tx_ba_wsize; + u_int8 max_mpdu_len; + u_int8 vht_ampdu_exp; + u_int16 he_tx_ba_wsize; + u_int8 he_ampdu_exp; + u_int16 efuse_size; + struct serv_mcs_nss_caps mcs_nss; + struct serv_qos_caps qos; + struct serv_spe_map_list spe_map_list; + boolean swq_per_band; +}; + +/* Service channel configuration */ +struct serv_channel_cfg { + u_char ctrl_channel; + /*Only used for 80+80 case */ + u_char ctrl_channel2; + u_char central_channel; + u_char bw; + u_char tx_stream; + u_char rx_stream; + boolean scan; + boolean dfs_check; + u_char band_idx; + u_char ch_band; + u_int32 out_band_freq; +}; + +/* Test data rate map */ +struct test_data_rate_map { + u_char mcs; /* MCS index */ + u_int32 tx_data_rate; /* Data rate in K bit */ +}; + +/* Test data aggregation threshold */ +struct test_datalen_limit_map { + u_char phy_mode; /* MCS index */ + u_int32 amsdu_limit; /* Data rate in K bit */ +}; + +/* Test ant to spe_idx map */ +struct test_ant_map { + u_int32 ant_sel; + u_int32 spe_idx; +}; + +/* Test rx filter */ +/* TODO: factor out here for naming */ +struct rx_filter_ctrl { + u_int32 filterMask; + boolean bPromiscuous; + boolean bFrameReport; + u_char u1BandIdx; +}; + +/* Test backup CR */ +struct test_bk_cr { + u_long offset; + u_int32 val; + enum test_bk_cr_type type; +}; + +/* Test backup params from normal */ +struct test_backup_params { + bool en_tx_burst; + bool en_bss_coex; + u_int16 bcn_prd; +}; + +/* Test tx counters */ +struct test_tx_statistic { + u_int32 tx_cnt; + u_int32 tx_done_cnt; /* Tx DMA Done */ + u_int32 txed_cnt; +}; + +/* Test rx stat band info */ +struct test_rx_stat_band_info { + u_int32 mac_rx_fcs_err_cnt; + u_int32 mac_rx_mdrdy_cnt; + u_int32 mac_rx_len_mismatch; + u_int32 mac_rx_fcs_ok_cnt; + u_int32 phy_rx_fcs_err_cnt_cck; + u_int32 phy_rx_fcs_err_cnt_ofdm; + u_int32 phy_rx_pd_cck; + u_int32 phy_rx_pd_ofdm; + u_int32 phy_rx_sig_err_cck; + u_int32 phy_rx_sfd_err_cck; + u_int32 phy_rx_sig_err_ofdm; + u_int32 phy_rx_tag_err_ofdm; + u_int32 phy_rx_mdrdy_cnt_cck; + u_int32 phy_rx_mdrdy_cnt_ofdm; +}; + +/* Test rx stat path info */ +struct test_rx_stat_path_info { + u_int32 rcpi; + u_int32 rssi; + u_int32 fagc_ib_rssi; + u_int32 fagc_wb_rssi; + u_int32 inst_ib_rssi; + u_int32 inst_wb_rssi; +}; + +/* Test rx stat user info */ +struct test_rx_stat_user_info { + s_int32 freq_offset_from_rx; + u_int32 snr; + u_int32 fcs_error_cnt; +}; + +/* Test rx stat comm info */ +struct test_rx_stat_comm_info { + u_int32 rx_fifo_full; + u_int32 aci_hit_low; + u_int32 aci_hit_high; + u_int32 mu_pkt_count; + u_int32 sig_mcs; + u_int32 sinr; + u_int32 driver_rx_count; +}; + +/* Test rx stat */ +struct test_rx_stat { + struct test_rx_stat_band_info rx_st_band[TEST_DBDC_BAND_NUM]; + struct test_rx_stat_path_info rx_st_path[TEST_ANT_NUM]; + struct test_rx_stat_user_info rx_st_user[TEST_USER_NUM]; + struct test_rx_stat_comm_info rx_st_comm; +}; + +/* Test rx stat union */ +struct test_rx_stat_u { + union { + struct test_rx_stat_band_info rx_st_band; + struct test_rx_stat_path_info rx_st_path; + struct test_rx_stat_user_info rx_st_user; + struct test_rx_stat_comm_info rx_st_comm; + } u; +}; + +struct GNU_PACKED test_rx_stat_leg { + u_int32 mac_rx_fcs_err_cnt; + u_int32 mac_rx_mdrdy_cnt; + u_int32 phy_rx_fcs_err_cnt_cck; + u_int32 phy_rx_fcs_err_cnt_ofdm; + u_int32 phy_rx_pd_cck; + u_int32 phy_rx_pd_ofdm; + u_int32 phy_rx_sig_err_cck; + u_int32 phy_rx_sfd_err_cck; + u_int32 phy_rx_sig_err_ofdm; + u_int32 phy_rx_tag_err_ofdm; + u_int32 wb_rssi0; + u_int32 ib_rssi0; + u_int32 wb_rssi1; + u_int32 ib_rssi1; + u_int32 phy_rx_mdrdy_cnt_cck; + u_int32 phy_rx_mdrdy_cnt_ofdm; + u_int32 driver_rx_cnt; + u_int32 rcpi0; + u_int32 rcpi1; + s_int32 freq_offset_rx; + u_int32 rssi0; + u_int32 rssi1; + u_int32 rx_fifo_full; + u_int32 mac_rx_len_mismatch; + u_int32 mac_rx_fcs_err_cnt_band1; + u_int32 mac_rx_mdrdy_cnt_band1; + u_int32 fagc_ib_rssi[TEST_ANT_NUM]; + u_int32 fagc_wb_rssi[TEST_ANT_NUM]; + u_int32 inst_ib_rssi[TEST_ANT_NUM]; + u_int32 inst_wb_rssi[TEST_ANT_NUM]; + u_int32 aci_hit_low; + u_int32 aci_git_high; + u_int32 driver_rx_cnt1; + u_int32 rcpi2; + u_int32 rcpi3; + u_int32 rssi2; + u_int32 rssi3; + u_int32 snr0; + u_int32 snr1; + u_int32 snr2; + u_int32 snr3; + u_int32 rx_fifo_full_band1; + u_int32 mac_rx_len_mismatch_band1; + u_int32 phy_rx_pd_cck_band1; + u_int32 phy_rx_pd_ofdm_band1; + u_int32 phy_rx_sig_err_cck_band1; + u_int32 phy_rx_sfd_err_cck_band1; + u_int32 phy_rx_sig_err_ofdm_band1; + u_int32 phy_rx_tag_err_ofdm_band1; + u_int32 phy_rx_mdrdy_cnt_cck_band1; + u_int32 phy_rx_mdrdy_cnt_ofdm_band1; + u_int32 phy_rx_fcs_err_cnt_cck_band1; + u_int32 phy_rx_fcs_err_cnt_ofdm_band1; + u_int32 mu_pkt_cnt; + u_int32 sig_mcs; + u_int32 sinr; + u_int32 rxv_rssi; + u_int32 mac_rx_fcs_ok_cnt; + u_int32 leg_rssi_sub[8]; + s_int32 user_rx_freq_offset[TEST_USER_NUM]; + u_int32 user_snr[TEST_USER_NUM]; + u_int32 fcs_error_cnt[TEST_USER_NUM]; +}; + +/* For mobile temp use */ +struct GNU_PACKED hqa_m_rx_stat { + u_int32 mac_rx_fcs_err_cnt; + u_int32 mac_rx_mdrdy_cnt; + u_int32 phy_rx_fcs_err_cnt_cck; + u_int32 phy_rx_fcs_err_cnt_ofdm; + u_int32 phy_rx_pd_cck; + u_int32 phy_rx_pd_ofdm; + u_int32 phy_rx_sig_err_cck; + u_int32 phy_rx_sfd_err_cck; + u_int32 phy_rx_sig_err_ofdm; + u_int32 phy_rx_tag_err_ofdm; + u_int32 wb_rssi0; + u_int32 ib_rssi0; + u_int32 wb_rssi1; + u_int32 ib_rssi1; + u_int32 phy_rx_mdrdy_cnt_cck; + u_int32 phy_rx_mdrdy_cnt_ofdm; + u_int32 driver_rx_count; + u_int32 rcpi0; + u_int32 rcpi1; + s_int32 freq_offset_from_rx; + u_int32 rssi0; + u_int32 rssi1; + u_int32 rx_fifo_full; /* out_of_resource */ + u_int32 mac_rx_len_mismatch; + u_int32 mac_rx_fcs_err_cnt_band1; + u_int32 mac_rx_mdrdy_cnt_band1; + u_int32 fagc_ib_RSSSI0; + u_int32 fagc_ib_RSSSI1; + u_int32 fagc_ib_RSSSI2; + u_int32 fagc_ib_RSSSI3; + u_int32 fagc_wb_RSSSI0; + u_int32 fagc_wb_RSSSI1; + u_int32 fagc_wb_RSSSI2; + u_int32 fagc_wb_RSSSI3; + u_int32 inst_ib_RSSSI0; + u_int32 inst_ib_RSSSI1; + u_int32 inst_ib_RSSSI2; + u_int32 inst_ib_RSSSI3; + u_int32 inst_wb_RSSSI0; + u_int32 inst_wb_RSSSI1; + u_int32 inst_wb_RSSSI2; + u_int32 inst_wb_RSSSI3; + u_int32 aci_hit_low; + u_int32 aci_hit_high; + u_int32 driver_rx_count1; + u_int32 rcpi2; + u_int32 rcpi3; + u_int32 rssi2; + u_int32 rssi3; + u_int32 snr0; + u_int32 snr1; + u_int32 snr2; + u_int32 snr3; + u_int32 rx_fifo_full_band1; + u_int32 mac_rx_len_mismatch_band1; + u_int32 phy_rx_pd_cck_band1; + u_int32 phy_rx_pd_ofdm_band1; + u_int32 phy_rx_sig_err_cck_band1; + u_int32 phy_rx_sfd_err_cck_band1; + u_int32 phy_rx_sig_err_ofdm_band1; + u_int32 phy_rx_tag_err_ofdm_band1; + u_int32 phy_rx_mdrdy_cnt_cck_band1; + u_int32 phy_rx_mdrdy_cnt_ofdm_band1; + u_int32 phy_rx_fcs_err_cnt_cck_band1; + u_int32 phy_rx_fcs_err_cnt_ofdm_band1; + u_int32 mu_pkt_count; + u_int32 sig_mcs; + u_int32 sinr; + u_int32 rxv_rssi; + /* u_int32 reserved[184]; */ + u_int32 phy_mdrdy; + u_int32 noise_floor; + u_int32 all_len_mismatch_ch_cnt_band0; + u_int32 all_len_mismatch_ch_cnt_band1; + u_int32 all_mac_mdrdy0; + u_int32 all_mac_mdrdy1; + u_int32 all_fcs_err0; + u_int32 all_fcs_err1; + u_int32 rx_ok0; + u_int32 rx_ok1; + u_int32 per0; + u_int32 per1; +}; + +struct GNU_PACKED hqa_comm_rx_stat { + union { + struct hqa_m_rx_stat r_test_m_hqa_rx_stat; + } u; +}; + +/* Test capability */ +/* VER 0x0001: Init version */ +/* VER 0x0002: Add hw_tx support, channel_band_dbdc */ + +#define GET_CAPABILITY_VER 0x0002 +#define GET_CAPABILITY_TAG_NUM 2 + +/* phy capability */ +#define GET_CAPABILITY_TAG_PHY 1 +#define GET_CAPABILITY_TAG_PHY_LEN 16 + +/* phy capability ext */ +#define GET_CAPABILITY_TAG_PHY_EXT 2 +#define GET_CAPABILITY_TAG_PHY_EXT_LEN 16 + +struct test_capability_ph_cap { + /* header */ + u_int32 tag; /* GET_CAPABILITY_TAG_PHY */ + u_int32 tag_len; /* GET_CAPABILITY_TAG_PHY_LEN */ + + /* content: GET_CAPABILITY_TAG_PHY_LEN */ + + /* BIT0 : 11 a/b/g BIT1: 11n , BIT2: 11ac , BIT3: 11ax */ + u_int32 protocol; + + /* 1:1x1, 2:2x2, ... */ + u_int32 ant_num; + + /* BIT0: DBDC support */ + u_int32 dbdc; + + /* BIT0: TxLDPC , BTI1 : RxLDPC , BIT2: TxSTBC , BIT3: RxSTBC */ + u_int32 coding; + + /* BIT0 : 2.4G BIT1: 5G , BIT2: 6G */ + u_int32 channel_band; + + /* BIT0: BW20, BIT1:BW40, BIT2:BW80, BIT3:BW160, BIT4:BW80+80 */ + u_int32 bandwidth; + + /* BIT0 : Band0 2.4G BIT1: Band1 5G , BIT2: Band0 6G */ + /* BIT16 : Band1 2.4G BIT17: Band1 5G , BIT18: Band1 6G */ + u_int32 channel_band_dbdc; + + u_int32 reserved[9]; +}; + +struct test_capability_ext_cap { + /* header */ + u_int32 tag; /* GET_CAPABILITY_TAG_PHY_EXT */ + u_int32 tag_len; /* GET_CAPABILITY_TAG_PHY_EXT_LEN */ + + /* content: GET_CAPABILITY_TAG_PHY_EXT_LEN */ + + /* BIT0: AntSwap */ + /* BIT1: HW TX support */ + u_int32 feature1; + u_int32 reserved[15]; +}; + +struct test_capability { + u_int32 version; + u_int32 tag_num; + struct test_capability_ph_cap ph_cap; + struct test_capability_ext_cap ext_cap; +}; + +/* Test mps for service */ +struct test_mps_setting { + u_int32 tx_mode; + u_int16 tx_ant; + u_int32 mcs; + u_int32 pkt_len; + u_int32 pkt_cnt; + u_int32 pwr; + u_int32 nss; + u_int32 pkt_bw; +}; + +struct test_mps_cb { + SERV_OS_SPIN_LOCK lock; + u_int32 mps_cnt; + u_int32 stat; + boolean setting_inuse; + u_int32 ref_idx; + struct test_mps_setting *mps_setting; +}; + +/* Test tx time feature parameters */ +struct tx_time_param { + /* The packet transmission time feature enable or disable */ + boolean pkt_tx_time_en; + /* The target packet transmission time */ + u_int32 pkt_tx_time; + /* MPDU length in byte */ + u_int32 pkt_tx_len; + /* MSDU length in bye */ + u_int32 pkt_msdu_len; + u_int32 pkt_hdr_len; + /* count for aggregated MPDU */ + u_int32 pkt_ampdu_cnt; + /* mark as QOS data required */ + u_int8 pkt_need_qos; + /* mark as A-MSDU required */ + u_int8 pkt_need_amsdu; + /* mark as AMPDU equired */ + u_int8 pkt_need_ampdu; +}; + +/* Test ipg feature parameters */ +struct ipg_param { + /* The target idle time */ + u_int32 ipg; + /* Only OFDM/HT/VHT need to consider sig_ext */ + u_int8 sig_ext; + u_int16 slot_time; + u_int16 sifs_time; + /* 0: AC_BK, 1: AC_BE, 2: AC_VI, 3: AC_VO */ + u_int8 ac_num; + u_int8 aifsn; + u_int16 cw; + u_int16 txop; +}; + +/* Test tx power feature parameters */ +struct test_txpwr_param { + u_int32 ant_idx; + u_int32 power; + u_int32 channel; + u_int32 band_idx; + u_int32 ch_band; +}; + +/* Test off channel scan parameters */ +struct test_off_ch_param { + u_int32 ext_id; /* ExtendId of command */ + u_int32 dbdc_idx; /* DBDC index */ + u_int32 mntr_ch; /* Monitoring channel */ + u_int32 is_aband; /* 0: 2.4G channel, 1: 5G channel */ + u_int32 mntr_bw; /* Bandwidth of monitoring channel */ + u_int32 mntr_tx_rx_pth; /* Monitoring TX/RX stream path */ + u_int32 scan_mode; /* ScanStart/ScanRunning/ScanStop */ +}; + +/* Test band state for UI/driver communication */ +struct test_band_state { + /* The single/dual band which UI wants to show */ + u_int32 band_mode; + /* The a/g band type which driver shall configure */ + u_int32 band_type; +}; + +struct test_ru_info { + boolean valid; + u_int32 aid; + u_int32 allocation; + u_int32 ru_index; + u_int32 rate; + u_int32 ldpc; + u_int32 nss; + u_int32 start_sp_st; + u_int32 mpdu_length; + s_int32 alpha; + u_int32 ru_mu_nss; + /* end of user input*/ + u_int32 t_pe; + u_int32 afactor_init; + u_int32 symbol_init; + u_int32 excess; + u_int32 dbps; + u_int32 cbps; + u_int32 dbps_s; + u_int32 cbps_s; + u_int32 pld; + u_int32 avbits; + u_int32 dbps_last; + u_int32 cbps_last; + u_int8 ldpc_extr_sym; + u_int32 tx_time_x5; + u_int8 pe_disamb; + s_int16 punc; + u_int32 l_len; +}; + +struct test_tx_info { + u_int8 tx_mode; + u_int8 bw; + u_int8 stbc; + u_int8 ldpc; + u_int8 ltf; + u_int8 gi; + u_int8 mcs; + u_int8 nss; + u_int8 ibf; + u_int8 ebf; + u_int32 mpdu_length; +}; + +/* Tx stack entry for service */ +struct test_tx_stack { + u_int8 entry_limit; + u_int8 index; + u_int8 q_idx; + u_int16 quota; + u_int8 da[MAX_MULTI_TX_STA][SERV_MAC_ADDR_LEN]; + void *virtual_wtbl[MAX_MULTI_TX_STA]; + void *virtual_device[MAX_MULTI_TX_STA]; + void *pkt_skb[MAX_MULTI_TX_STA]; + struct test_tx_info tx_info[MAX_MULTI_TX_STA]; +}; + +struct test_ru_allocatoin { + /* maximum 8 sub-20MHz for 160/80+80 MHz bandwidth */ + u_int8 sub20[8]; +}; + +/* Test configuration for service */ +struct test_configuration { + /* Test operated mode */ + u_int32 op_mode; + + /* Test packet */ + u_char *test_pkt; /* Buffer for test packet */ + void *pkt_skb; + u_int32 is_alloc_skb; + + /* OS related */ + SERV_OS_COMPLETION tx_wait; + u_char tx_status; /* 0: task idle, 1: task is running */ + + /* Hardware resource */ + void *wdev[2]; + u_char wdev_idx; + u_char wmm_idx; + u_short ac_idx; + + /* Wifi related */ + u_int8 wcid_ref; + + /* Tx frame */ + u_char template_frame[32]; + u_char addr1[MAX_MULTI_TX_STA][SERV_MAC_ADDR_LEN]; + u_char addr2[MAX_MULTI_TX_STA][SERV_MAC_ADDR_LEN]; + u_char addr3[MAX_MULTI_TX_STA][SERV_MAC_ADDR_LEN]; + u_char payload[TEST_MAX_PATTERN_SIZE]; + u_short dur; + u_short seq; + u_short hdr_len; /* Header Length */ + u_int32 pl_len; + u_int32 tx_len; + u_int32 fixed_payload; /* Normal:0,Repeat:1,Random:2 */ + + /* Tx */ + u_int8 tx_strategy; + u_int8 tx_method[TEST_MODE_NUM]; + struct test_tx_stack stack; + struct test_ru_info ru_info_list[MAX_MULTI_TX_STA]; + u_int8 dmnt_ru_idx; + struct test_ru_allocatoin ru_alloc; + u_int8 rate_ctrl_type; + u_int32 duty_cycle; + struct tx_time_param tx_time_param; + struct ipg_param ipg_param; + u_int8 retry; + + /* Rx */ + u_char own_mac[SERV_MAC_ADDR_LEN]; + u_int8 rx_filter_en; + u_int32 rx_filter_pkt_len; + u_int32 mu_rx_aid; + + /* Test Tx statistic */ + boolean txs_enable; + struct test_tx_statistic tx_stat; + + /* Phy */ + u_int8 backup_tx_ant; + u_int16 tx_ant; + u_int8 backup_rx_ant; + u_int16 rx_ant; + u_char channel; + u_char ch_band; + u_char ctrl_ch; + u_int8 pri_sel; + s_int8 ch_offset; + u_char tx_mode; + u_char bw; + u_char per_pkt_bw; + u_char mcs; + u_char nss; + u_char stbc; + u_char ldpc; /* 0:BCC 1:LDPC */ + u_char sgi; + u_char preamble; + u_char fagc_path; + u_char tx_strm_num; /* TX stream number for channel */ + u_char rx_strm_pth; /* RX antenna path for channel */ + u_char backup_channel; + u_char backup_phymode; + u_char channel_2nd; + u_int32 out_band_freq; + u_int32 rf_freq_offset; + u_int32 thermal_val; + u_int8 max_pkt_ext; + u_int64 hetb_rx_csd; + u_int8 user_idx; + + /* Tx power */ + struct test_txpwr_param pwr_param; + s_int8 tx_pwr[TEST_ANT_NUM]; + boolean tx_pwr_sku_en; /* sku on/off status */ + boolean tx_pwr_percentage_en; /* power percentage on/off status */ + boolean tx_pwr_backoff_en; /* backoff on/off status */ + u_int32 tx_pwr_percentage_level; /* tx power percentage level */ + + /* Tx Tone */ + u_int32 tx_tone_en; + u_int32 ant_idx; + u_int32 tone_type; + u_int32 tone_freq; + u_int32 dc_offset_I; + u_int32 dc_offset_Q; + u_int32 rf_pwr; + u_int32 digi_pwr; + + /* Continuous Tx */ + u_int32 ant_mask; + u_int32 rate; + u_int32 tx_fd_mode; + + /* Set Cfg on off */ + u_char log_type; + u_char log_enable; + + /* MPS related */ + struct test_mps_cb mps_cb; + + /*iBF, eBF*/ + u_char ibf; + u_char ebf; + + /* off ch scan */ + struct test_off_ch_param off_ch_param; +}; + +/* Test wlan information for service */ +struct test_wlan_info { + void *os_cookie; /* save specific structure relative to OS */ + struct net_device *net_dev; + u_int32 chip_id; + + /* fw info */ + struct serv_fw_info wm_fw_info; + + /* hdev */ + void *hdev_ctrl; + + /* DBDC */ + boolean dbdc_mode; + + /* Token HW resource */ + u_int32 pkt_tx_tkid_max; + + /* Chip cap */ + struct serv_chip_cap chip_cap; + + /* EEPROM related information */ + boolean use_efuse; + u_char e2p_cur_mode; + u_char e2p_access_mode; + + /*========== gen4m only ==========*/ + /* wlan oid handler */ + wlan_oid_handler_t oid_funcptr; + + /*connsys emi phy memory start addr*/ + phys_addr_t emi_phy_base; + + /*connsys emi total phy memory size*/ + unsigned long long emi_phy_size; + + /* HW Tx on off */ + u_int32 hw_tx_enable; + +}; + +/* Test control register read/write for service */ +struct test_register { + u_int32 cr_addr; + /* For read/write bulk cr usage */ + u_int16 cr_num; + /* Determine size by cr_num */ + u_int32 *cr_val; + /* For rf reg read/write only */ + u_int32 wf_sel; +}; + +/* Test eeprom read/write for service */ +struct test_eeprom { + u_int16 offset; + /* For read/write bulk cr usage */ + u_int16 length; + /* Determine size by length */ + u_int16 *value; + /* For get efuse block count only */ + u_int32 efuse_free_block; +}; + +/* Test operation hook handlers for service */ +struct test_operation { + s_int32 (*op_set_tr_mac)( + struct test_wlan_info *winfos, + s_int32 op_type, boolean enable, u_char band_idx); + s_int32 (*op_set_tx_stream)( + struct test_wlan_info *winfos, + u_int32 stream_nums, u_char band_idx); + s_int32 (*op_set_tx_path)( + struct test_wlan_info *winfos, + u_char band_idx, + struct test_configuration *configs); + s_int32 (*op_set_rx_path)( + struct test_wlan_info *winfos, + u_char band_idx, + struct test_configuration *configs); + s_int32 (*op_set_rx_filter)( + struct test_wlan_info *winfos, + struct rx_filter_ctrl rx_filter); + s_int32 (*op_set_clean_persta_txq)( + struct test_wlan_info *winfos, + boolean sta_pause_enable, u_char wdev_idx, u_char band_idx); + s_int32 (*op_log_on_off)( + struct test_wlan_info *winfos, + u_char band_idx, + u_int32 log_type, + u_int32 log_ctrl, + u_int32 log_size); + s_int32 (*op_dbdc_tx_tone)( + struct test_wlan_info *winfos, + u_char band_idx, + struct test_configuration *configs); + s_int32 (*op_dbdc_tx_tone_pwr)( + struct test_wlan_info *winfos, + u_char band_idx, + struct test_configuration *configs); + s_int32 (*op_dbdc_continuous_tx)( + struct test_wlan_info *winfos, + u_char band_idx, + struct test_configuration *configs); + s_int32 (*op_get_tx_info)( + struct test_wlan_info *winfos, + struct test_configuration *test_configs_band0, + struct test_configuration *test_configs_band1); + s_int32 (*op_set_antenna_port)( + struct test_wlan_info *winfos, + u_int8 rf_mode_mask, u_int8 rf_port_mask, + u_int8 ant_port_mask); + s_int32 (*op_set_slot_time)( + struct test_wlan_info *winfos, + u_int8 slot_time, u_int8 sifs_time, + u_int8 rifs_time, u_int16 eifs_time, + u_char band_idx); + s_int32 (*op_set_power_drop_level)( + struct test_wlan_info *winfos, + u_int8 pwr_drop_level, u_char band_idx); + s_int32 (*op_set_rx_filter_pkt_len)( + struct test_wlan_info *winfos, + u_int8 enable, u_char band_idx, u_int32 rx_pkt_len); + s_int32 (*op_get_antswap_capability)( + struct test_wlan_info *winfos, + u_int32 *antswap_support); + s_int32 (*op_set_antswap)( + struct test_wlan_info *winfos, + u_int32 ant); + s_int32 (*op_set_freq_offset)( + struct test_wlan_info *winfos, + u_int32 freq_offset, u_char band_idx); + s_int32 (*op_set_phy_counter)( + struct test_wlan_info *winfos, + s_int32 control, u_char band_idx); + s_int32 (*op_set_rxv_index)( + struct test_wlan_info *winfos, + u_int8 group_1, u_int8 group_2, u_char band_idx); + s_int32 (*op_set_fagc_path)( + struct test_wlan_info *winfos, + u_int8 path, u_char band_idx); + s_int32 (*op_set_fw_mode)( + struct test_wlan_info *winfos, + u_char fw_mode); + s_int32 (*op_set_rf_test_mode)( + struct test_wlan_info *winfos, + u_int32 op_mode, u_int8 icap_len, u_int16 rsp_len); + s_int32 (*op_set_test_mode_start)( + struct test_wlan_info *winfos); + s_int32 (*op_set_test_mode_abort)( + struct test_wlan_info *winfos); + s_int32 (*op_start_tx)( + struct test_wlan_info *winfos, + u_char band_idx, + struct test_configuration *configs); + s_int32 (*op_stop_tx)( + struct test_wlan_info *winfos, + u_char band_idx); + s_int32 (*op_start_rx)( + struct test_wlan_info *winfos, + u_char band_idx, + struct test_configuration *configs); + s_int32 (*op_stop_rx)( + struct test_wlan_info *winfos, + u_char band_idx); + s_int32 (*op_set_channel)( + struct test_wlan_info *winfos, + u_char band_idx, + struct test_configuration *configs); + s_int32 (*op_set_tx_content)( + struct test_wlan_info *winfos, + u_char band_idx, + struct test_configuration *configs); + s_int32 (*op_set_preamble)( + struct test_wlan_info *winfos, + u_char mode); + s_int32 (*op_set_rate)( + struct test_wlan_info *winfos, + u_char mcs); + s_int32 (*op_set_system_bw)( + struct test_wlan_info *winfos, + u_char sys_bw); + s_int32 (*op_set_per_pkt_bw)( + struct test_wlan_info *winfos, + u_char per_pkt_bw); + s_int32 (*op_reset_txrx_counter)( + struct test_wlan_info *winfos); + s_int32 (*op_set_rx_vector_idx)( + struct test_wlan_info *winfos, + u_char band_idx, + u_int32 group1, + u_int32 group2); + s_int32 (*op_get_rx_stat_leg)( + struct test_wlan_info *winfos, + struct test_rx_stat_leg *rx_stat); + s_int32 (*op_set_fagc_rssi_path)( + struct test_wlan_info *winfos, + u_char band_idx, + u_int32 fagc_path); + s_int32 (*op_get_rx_statistics_all)( + struct test_wlan_info *winfos, + struct hqa_comm_rx_stat *hqa_rx_stat); + s_int32 (*op_get_capability)( + struct test_wlan_info *winfos, + struct test_capability *capability); + s_int32 (*op_calibration_test_mode)( + struct test_wlan_info *winfos, + u_char mode); + s_int32 (*op_set_icap_start)( + struct test_wlan_info *winfos, + u_int8 *data); + s_int32 (*op_get_icap_status)( + struct test_wlan_info *winfos, + s_int32 *icap_stat); + s_int32 (*op_get_icap_max_data_len)( + struct test_wlan_info *winfos, + u_long *max_data_len); + s_int32 (*op_get_icap_data)( + struct test_wlan_info *winfos, + s_int32 *icap_cnt, + s_int32 *icap_data, + u_int32 wf_num, + u_int32 iq_type); + s_int32 (*op_do_cal_item)( + struct test_wlan_info *winfos, + u_int32 item, u_char band_idx); + s_int32 (*op_set_band_mode)( + struct test_wlan_info *winfos, + struct test_band_state *band_state); + s_int32 (*op_get_chipid)( + struct test_wlan_info *winfos); + s_int32 (*op_mps_start)( + struct test_wlan_info *winfos, + u_char band_idx); + s_int32 (*op_mps_set_nss)( + struct test_wlan_info *winfos, + u_int32 len, + struct test_mps_setting *mps_setting); + s_int32 (*op_mps_set_per_packet_bw)( + struct test_wlan_info *winfos, + u_int32 len, + struct test_mps_setting *mps_setting); + s_int32 (*op_mps_set_packet_count)( + struct test_wlan_info *winfos, + u_int32 len, + struct test_mps_setting *mps_setting); + s_int32 (*op_mps_set_payload_length)( + struct test_wlan_info *winfos, + u_int32 len, + struct test_mps_setting *mps_setting); + s_int32 (*op_mps_set_power_gain)( + struct test_wlan_info *winfos, + u_int32 len, + struct test_mps_setting *mps_setting); + s_int32 (*op_mps_set_seq_data)( + struct test_wlan_info *winfos, + u_int32 len, + struct test_mps_setting *mps_setting); + s_int32 (*op_set_tam_arb)( + struct test_wlan_info *winfos, + u_int8 arb_op_mode); + s_int32 (*op_set_muru_manual)( + void *virtual_device, + struct test_wlan_info *winfos, + struct test_configuration *configs); + /* For test phy usage */ + s_int32 (*op_get_tx_pwr)( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_char band_idx, + u_char channel, + u_char ant_idx, + u_int32 *power); + s_int32 (*op_set_tx_pwr)( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_char band_idx, + struct test_txpwr_param *pwr_param); + s_int32 (*op_write_mac_bbp_reg)( + struct test_wlan_info *winfos, + struct test_register *regs); + s_int32 (*op_read_bulk_mac_bbp_reg)( + struct test_wlan_info *winfos, + struct test_register *regs); + s_int32 (*op_read_bulk_rf_reg)( + struct test_wlan_info *winfos, + struct test_register *regs); + s_int32 (*op_write_bulk_rf_reg)( + struct test_wlan_info *winfos, + struct test_register *regs); + s_int32 (*op_read_bulk_eeprom)( + struct test_wlan_info *winfos, + struct test_eeprom *eprms); + s_int32 (*op_get_freq_offset)( + struct test_wlan_info *winfos, + u_char band_idx, + u_int32 *freq_offset); + s_int32 (*op_get_cfg_on_off)( + struct test_wlan_info *winfos, + u_char band_idx, + u_int32 type, + u_int32 *result); + s_int32 (*op_get_tx_tone_pwr)( + struct test_wlan_info *winfos, + u_char band_idx, + u_int32 ant_idx, + u_int32 *power); + s_int32 (*op_get_recal_cnt)( + struct test_wlan_info *winfos, + u_int32 *recal_cnt, + u_int32 *recal_dw_num); + s_int32 (*op_get_recal_content)( + struct test_wlan_info *winfos, + u_int32 *content); + s_int32 (*op_get_rdd_content)( + struct test_wlan_info *winfos, + u_int32 *content, + u_int32 *total_cnt); + s_int32 (*op_get_rdd_cnt)( + struct test_wlan_info *winfos, + u_int32 *rdd_cnt, + u_int32 *rdd_dw_num); + s_int32 (*op_get_rxv_cnt)( + struct test_wlan_info *winfos, + u_int32 *rxv_cnt, + u_int32 *rxv_dw_num); + s_int32 (*op_get_rxv_content)( + struct test_wlan_info *winfos, + u_int32 dw_cnt, + u_int32 *content); + s_int32 (*op_get_thermal_val)( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_char band_idx, + u_int32 *value); + s_int32 (*op_set_cal_bypass)( + struct test_wlan_info *winfos, + u_char band_idx, + u_int32 cal_item); + s_int32 (*op_set_cfg_on_off)( + struct test_wlan_info *winfos, + u_int8 type, u_int8 enable, u_char band_idx); + s_int32 (*op_set_dpd)( + struct test_wlan_info *winfos, + u_int32 on_off, + u_int32 wf_sel); + s_int32 (*op_set_tssi)( + struct test_wlan_info *winfos, + u_int32 on_off, + u_int32 wf_sel); + s_int32 (*op_set_rdd_test)( + struct test_wlan_info *winfos, + u_int32 rdd_idx, + u_int32 rdd_sel, + u_int32 enable); + s_int32 (*op_set_off_ch_scan)( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_char band_idx, + struct test_off_ch_param *off_ch_param); + s_int32 (*op_get_rx_stat)( + struct test_wlan_info *winfos, + u_char band_idx, + struct test_rx_stat *rx_stat); + s_int32 (*op_hetb_ctrl)( + struct test_wlan_info *winfos, + u_char band_idx, + u_char ctrl_type, + boolean enable, + u_int8 bw, + u_int8 ltf_gi, + u_int8 stbc, + u_int8 pri_ru_idx, + struct test_ru_info *ru_info); + s_int32 (*op_set_ru_aid)( + struct test_wlan_info *winfos, + u_char band_idx, + u_int16 mu_rx_aid); + s_int32 (*op_set_mutb_spe)( + struct test_wlan_info *winfos, + u_char band_idx, + u_char phy_mode, + u_int8 spe_idx); + s_int32 (*op_get_wf_path_comb)( + struct test_wlan_info *winfos, + u_int8 band_idx, + boolean dbdc_mode_en, + u_int8 *path, + u_int8 *path_len); + s_int32 (*op_get_rx_stat_band)( + struct test_wlan_info *winfos, + u_int8 band_idx, + u_int8 blk_idx, + struct test_rx_stat_band_info *rx_st_band); + s_int32 (*op_get_rx_stat_path)( + struct test_wlan_info *winfos, + u_int8 band_idx, + u_int8 blk_idx, + struct test_rx_stat_path_info *rx_st_path); + s_int32 (*op_get_rx_stat_user)( + struct test_wlan_info *winfos, + u_int8 band_idx, + u_int8 blk_idx, + struct test_rx_stat_user_info *rx_st_user); + s_int32 (*op_get_rx_stat_comm)( + struct test_wlan_info *winfos, + u_int8 band_idx, + u_int8 blk_idx, + struct test_rx_stat_comm_info *rx_st_comm); + /* For test mac usage */ + s_int32 (*op_backup_and_set_cr)( + struct test_wlan_info *winfos, + struct test_bk_cr *bks, + u_char band_idx); + s_int32 (*op_restore_cr)( + struct test_wlan_info *winfos, + struct test_bk_cr *bks, + u_char band_idx); + s_int32 (*op_set_ampdu_ba_limit)( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_int8 agg_limit); + s_int32 (*op_set_sta_pause_cr)( + struct test_wlan_info *winfos); + s_int32 (*op_set_ifs_cr)( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_char band_idx); +}; + + +/* Test tmr for service */ +struct test_tmr_info { + u_int32 setting; + u_int32 version; + u_int32 through_hold; + u_int32 iter; +}; + +/***************************************************************************** + * Function declaration + *****************************************************************************/ +s_int32 net_ad_init_thread( + struct test_wlan_info *winfos, + struct test_configuration *configs, + enum service_thread_list thread_idx); +s_int32 net_ad_release_thread( + u_char thread_idx); +s_int32 net_ad_backup_cr( + struct test_wlan_info *winfos, + struct test_bk_cr *test_bkcr, + u_long offset, enum test_bk_cr_type type); +s_int32 net_ad_restore_cr( + struct test_wlan_info *winfos, + struct test_bk_cr *test_bkcr, + u_long offset); +s_int32 net_ad_cfg_queue( + struct test_wlan_info *winfos, boolean enable); +s_int32 net_ad_enter_normal( + struct test_wlan_info *winfos, + struct test_backup_params *configs); +s_int32 net_ad_exit_normal( + struct test_wlan_info *winfos, + struct test_backup_params *configs); +s_int32 net_ad_update_wdev( + u_int8 band_idx, + struct test_wlan_info *winfos, + struct test_configuration *configs); +s_int32 net_ad_init_wdev( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_char band_idx); +s_int32 net_ad_release_wdev( + struct test_wlan_info *winfos, + struct test_configuration *configs); +s_int32 net_ad_fill_pkt( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_char *buf, u_int32 txlen, u_int32 hlen); +s_int32 net_ad_alloc_pkt( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_int32 mpdu_length, + void **pkt_skb); +s_int32 net_ad_free_pkt( + struct test_wlan_info *winfos, + void *pkt_skb); +s_int32 net_ad_enq_pkt( + struct test_wlan_info *winfos, + u_short q_idx, + void *virtual_wtbl, + void *virtual_device, + void *pkt); +s_int32 net_ad_trigger_tx( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_int8 band_idx, + void *pkt); +s_int32 net_ad_rx_done_handle( + struct test_wlan_info *winfos, + void *rx_blk); +s_int32 net_ad_set_band_mode( + struct test_wlan_info *winfos, + struct test_band_state *band_state); +s_int32 net_ad_set_txpwr_sku( + struct test_wlan_info *winfos, + u_char sku_ctrl, u_char band_idx); +s_int32 net_ad_set_txpwr_power_drop( + struct test_wlan_info *winfos, + u_char power_drop, + u_char band_idx); +s_int32 net_ad_set_txpwr_percentage( + struct test_wlan_info *winfos, + u_char percentage_ctrl, + u_char band_idx); +s_int32 net_ad_set_txpwr_backoff( + struct test_wlan_info *winfos, + u_char backoff_ctrl, u_char band_idx); +s_int32 net_ad_init_txpwr( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_char band_idx); +s_int32 net_ad_handle_mcs32( + struct test_wlan_info *winfos, + void *virtual_device, u_int8 bw); +s_int32 net_ad_cfg_wtbl( + struct test_wlan_info *winfos, + struct test_configuration *configs); +s_int32 net_ad_set_wmm_param_by_qid( + u_int8 wmm_idx, + u_int8 q_idx, + struct test_wlan_info *winfos, + struct test_configuration *configs); +s_int32 net_ad_clean_sta_q( + struct test_wlan_info *winfos, + u_char wcid); +s_int32 net_ad_set_auto_resp( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_char band_idx, u_char mode); +s_int32 net_ad_set_low_power( + struct test_wlan_info *winfos, u_int32 control); +s_int32 net_ad_read_mac_bbp_reg( + struct test_wlan_info *winfos, + struct test_register *regs); +s_int32 net_ad_write_mac_bbp_reg( + struct test_wlan_info *winfos, + struct test_register *regs); +s_int32 net_ad_read_bulk_mac_bbp_reg( + struct test_wlan_info *winfos, + struct test_configuration *configs, + struct test_register *regs); +s_int32 net_ad_read_bulk_rf_reg( + struct test_wlan_info *winfos, + struct test_register *regs); +s_int32 net_ad_write_bulk_rf_reg( + struct test_wlan_info *winfos, + struct test_register *regs); +void net_ad_read_ca53_reg(struct test_register *regs); +void net_ad_write_ca53_reg(struct test_register *regs); +s_int32 net_ad_read_write_eeprom( + struct test_wlan_info *winfos, + struct test_eeprom *eprms, + boolean is_read); +s_int32 net_ad_read_write_bulk_eeprom( + struct test_wlan_info *winfos, + struct test_eeprom *eprms, + boolean is_read); +s_int32 net_ad_get_free_efuse_block( + struct test_wlan_info *winfos, + struct test_eeprom *eprms); +s_int32 net_ad_mps_tx_operation( + struct test_wlan_info *winfos, + struct test_configuration *configs, + boolean is_start_tx); +s_int32 net_ad_set_tmr( + struct test_wlan_info *winfos, + struct test_tmr_info *tmr_info); +s_int32 net_ad_get_rxv_stat( + struct test_wlan_info *winfos, + u_char ctrl_band_idx, + struct test_rx_stat *rx_stat + ); +s_int32 net_ad_get_rxv_cnt( + struct test_wlan_info *winfos, + u_char ctrl_band_idx, + u_int32 *byte_cnt); +s_int32 net_ad_get_rxv_content( + struct test_wlan_info *winfos, + u_char ctrl_band_idx, + void *content); + +s_int32 net_ad_alloc_wtbl( + struct test_wlan_info *winfos, + u_char *da, + void *virtual_dev, + void **virtual_wtbl); +s_int32 net_ad_free_wtbl( + struct test_wlan_info *winfos, + u_char *da, + void *virtual_wtbl); +s_int32 net_ad_apply_wtbl( + struct test_wlan_info *winfos, + void *virtual_dev, + void *virtual_wtbl); +s_int32 net_ad_match_wtbl( + void *virtual_wtbl, + u_int16 wcid); +s_int32 net_ad_get_band_idx( + void *virtual_device, + u_char *band_idx); +s_int32 net_ad_get_wmm_idx( + void *virtual_device, + u_int8 *wmm_idx); +s_int32 net_ad_get_omac_idx( + struct test_wlan_info *winfos, + void *virtual_device, + u_char *omac_idx); +s_int32 net_ad_set_aid( + void *virtual_wtbl, + u_int16 aid); +s_int32 net_ad_fill_phy_info( + void *virtual_wtbl, + struct test_tx_info *tx_info); +s_int32 net_ad_fill_spe_antid( + struct test_wlan_info *winfos, + void *virtual_wtbl, + u_int8 spe_idx, + u_int8 ant_pri); +s_int32 net_ad_get_speidx( + struct test_wlan_info *winfos, + u_int16 ant_sel, + u_int8 *spe_idx); +#endif /* __NET_ADAPTION_H__ */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/glue/osal/include/sys_adaption.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/glue/osal/include/sys_adaption.h new file mode 100644 index 0000000000000000000000000000000000000000..9382bc8c372f356d0521146cba1f35d642f05bd4 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/glue/osal/include/sys_adaption.h @@ -0,0 +1,342 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#ifndef __SYS_ADAPTION_H__ +#define __SYS_ADAPTION_H__ + +#include +#include +#include +#include +#include + +/***************************************************************************** + * Type definition + *****************************************************************************/ +#define s_int8 signed char +#define s_int16 signed short +#define s_int32 signed int +#define s_int64 signed long long +#define u_int8 unsigned char +#define u_int16 unsigned short +#define u_int32 unsigned int +#define u_int64 unsigned long long +#define s_char signed char +#define boolean unsigned char + +#ifndef NULL +#define NULL 0 +#endif + +#ifndef GNU_PACKED +#define GNU_PACKED __packed +#endif /* GNU_PACKED */ + +/* Spin lock */ +#define SERV_OS_SPIN_LOCK spinlock_t + +/* Completion */ +#define SERV_OS_COMPLETION struct completion + +/* Service task */ +#define SERV_OS_TASK_NAME_LEN 16 +struct serv_os_task { + char task_name[SERV_OS_TASK_NAME_LEN]; + void *priv_winfos; + void *priv_configs; + unsigned char task_killed; + struct task_struct *kthread_task; + wait_queue_head_t kthread_q; + boolean kthread_running; +}; +typedef s_int32(*SERV_OS_TASK_CALLBACK) (u_long); + +/*gen4m wlan oid call back function*/ +typedef uint32_t (*wlan_oid_handler_t) (void *winfos, + uint32_t oid_type, + void *param, + uint32_t param_len, + uint32_t *rsp_len, + void *rsp_data); + +/***************************************************************************** + * Macro + *****************************************************************************/ +/* Service IP return status */ +/* The first byte means module and the second byte means error status */ +/* Success */ +#define SERV_STATUS_SUCCESS 0x0000 + +/* Agent module: failure */ +#define SERV_STATUS_AGENT_FAIL 0x0100 +/* Agent module: invalid null pointer */ +#define SERV_STATUS_AGENT_INVALID_NULL_POINTER 0x0101 +/* Agent module: invalid band idx */ +#define SERV_STATUS_AGENT_INVALID_BANDIDX 0x0102 +/* Agent module: invalid length */ +#define SERV_STATUS_AGENT_INVALID_LEN 0x0103 +/* Agent module: invalid parameter */ +#define SERV_STATUS_AGENT_INVALID_PARAM 0x0104 +/* Agent module: not supported */ +#define SERV_STATUS_AGENT_NOT_SUPPORTED 0x0105 + +/* Service test module: failure */ +#define SERV_STATUS_SERV_TEST_FAIL 0x0200 +/* Service test module: invalid null pointer */ +#define SERV_STATUS_SERV_TEST_INVALID_NULL_POINTER 0x0201 +/* Service test module: invalid band idx */ +#define SERV_STATUS_SERV_TEST_INVALID_BANDIDX 0x0202 +/* Service test module: invalid length */ +#define SERV_STATUS_SERV_TEST_INVALID_LEN 0x0203 +/* Service test module: invalid parameter */ +#define SERV_STATUS_SERV_TEST_INVALID_PARAM 0x0204 +/* Service test module: not supported */ +#define SERV_STATUS_SERV_TEST_NOT_SUPPORTED 0x0205 + +/* Test engine module: failure */ +#define SERV_STATUS_ENGINE_FAIL 0x0300 +/* Test engine module: invalid null pointer */ +#define SERV_STATUS_ENGINE_INVALID_NULL_POINTER 0x0301 +/* Test engine module: invalid band idx */ +#define SERV_STATUS_ENGINE_INVALID_BANDIDX 0x0302 +/* Test engine module: invalid length */ +#define SERV_STATUS_ENGINE_INVALID_LEN 0x0303 +/* Test engine module: invalid parameter */ +#define SERV_STATUS_ENGINE_INVALID_PARAM 0x0304 +/* Test engine module: not supported */ +#define SERV_STATUS_ENGINE_NOT_SUPPORTED 0x0305 + +/* Hal test mac module: failure */ +#define SERV_STATUS_HAL_MAC_FAIL 0x0400 +/* Hal test mac module: invalid padapter */ +#define SERV_STATUS_HAL_MAC_INVALID_PAD 0x0401 +/* Hal test mac module: invalid null pointer */ +#define SERV_STATUS_HAL_MAC_INVALID_NULL_POINTER 0x0402 +/* Hal test mac module: invalid band idx */ +#define SERV_STATUS_HAL_MAC_INVALID_BANDIDX 0x0403 +/* Hal test mac module: un-registered chip ops */ +#define SERV_STATUS_HAL_MAC_INVALID_CHIPOPS 0x0404 + +/* Hal operation module: failure */ +#define SERV_STATUS_HAL_OP_FAIL 0x0500 +/* Hal operation module: failure to send fw command */ +#define SERV_STATUS_HAL_OP_FAIL_SEND_FWCMD 0x0501 +/* Hal operation module: failure to set mac behavior */ +#define SERV_STATUS_HAL_OP_FAIL_SET_MAC 0x0502 +/* Hal operation module: invalid padapter */ +#define SERV_STATUS_HAL_OP_INVALID_PAD 0x0503 +/* Hal operation module: invalid null pointer */ +#define SERV_STATUS_HAL_OP_INVALID_NULL_POINTER 0x0504 +/* Hal operation module: invalid band idx */ +#define SERV_STATUS_HAL_OP_INVALID_BANDIDX 0x0505 + +/* Osal net adaption module: failure */ +#define SERV_STATUS_OSAL_NET_FAIL 0x0600 +/* Osal net adaption module: failure to send fw command */ +#define SERV_STATUS_OSAL_NET_FAIL_SEND_FWCMD 0x0601 +/* Osal net adaption module: failure to init wdev */ +#define SERV_STATUS_OSAL_NET_FAIL_INIT_WDEV 0x0602 +/* Osal net adaption module: failure to release wdev */ +#define SERV_STATUS_OSAL_NET_FAIL_RELEASE_WDEV 0x0603 +/* Osal net adaption module: failure to update wdev */ +#define SERV_STATUS_OSAL_NET_FAIL_UPDATE_WDEV 0x0604 +/* Osal net adaption module: failure to set channel */ +#define SERV_STATUS_OSAL_NET_FAIL_SET_CHANNEL 0x0605 +/* Osal net adaption module: invalid padapter */ +#define SERV_STATUS_OSAL_NET_INVALID_PAD 0x0606 +/* Osal net adaption module: invalid null pointer */ +#define SERV_STATUS_OSAL_NET_INVALID_NULL_POINTER 0x0607 +/* Osal net adaption module: invalid band idx */ +#define SERV_STATUS_OSAL_NET_INVALID_BANDIDX 0x0608 +/* Osal net adaption module: invalid length */ +#define SERV_STATUS_OSAL_NET_INVALID_LEN 0x0609 +/* Osal net adaption module: invalid parameter */ +#define SERV_STATUS_OSAL_NET_INVALID_PARAM 0x060A + +/* Osal sys adaption module: failure */ +#define SERV_STATUS_OSAL_SYS_FAIL 0x0700 +/* Osal sys adaption module: invalid padapter */ +#define SERV_STATUS_OSAL_SYS_INVALID_PAD 0x0701 +/* Osal sys adaption module: invalid null pointer */ +#define SERV_STATUS_OSAL_SYS_INVALID_NULL_POINTER 0x0702 +/* Osal sys adaption module: invalid band idx */ +#define SERV_STATUS_OSAL_SYS_INVALID_BANDIDX 0x0703 + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +/* Use bitmap to allow coexist of OP_MODE_TXFRAME and OP_MODE_RXFRAME */ +#define fTEST_IDLE (1 << 0) +#define fTEST_TX_ENABLE (1 << 1) +#define fTEST_RX_ENABLE (1 << 2) +#define fTEST_TXCONT_ENABLE (1 << 3) +#define fTEST_TXCARR_ENABLE (1 << 4) +#define fTEST_TXCARRSUPP_ENABLE (1 << 5) +#define fTEST_MPS (1 << 6) +#define fTEST_FFT_ENABLE (1 << 7) +#define fTEST_EXIT (1 << 8) +#define fTEST_IN_RFTEST (1 << 9) +#define fTEST_IN_BF (1 << 10) +#define fTEST_IN_ICAPOVERLAP (1 << 11) + +/* OPMODE */ +#define fTEST_OPER_NORMAL_MODE 0 +#define fTEST_OPER_RFTEST_MODE 1 +#define fTEST_OPER_ICAP_MODE 2 +#define fTEST_OPER_ICAP_OVERLAP 3 +#define fTEST_OPER_WIFI_SPECTRUM 4 + +/* Stop Transmission */ +#define OP_MODE_TXSTOP ((~(fTEST_TX_ENABLE)) \ + &(~(fTEST_TXCONT_ENABLE)) \ + &(~(fTEST_TXCARR_ENABLE)) \ + &(~(fTEST_TXCARRSUPP_ENABLE)) \ + &(~(fTEST_MPS))) +/* Stop Receiving Frames */ +#define OP_MODE_RXSTOP (~(fTEST_RX_ENABLE)) +/* Enter/Reset ATE */ +#define OP_MODE_START (fTEST_IDLE) +/* Stop/Exit ATE */ +#define OP_MODE_STOP (fTEST_EXIT) +/* Continuous Transmit Frames (without time gap) */ +#define OP_MODE_TXCONT ((fTEST_TX_ENABLE) \ + |(fTEST_TXCONT_ENABLE)) +/* Transmit Carrier */ +#define OP_MODE_TXCARR ((fTEST_TX_ENABLE) \ + |(fTEST_TXCARR_ENABLE)) +/* Transmit Carrier Suppression (information without carrier) */ +#define OP_MODE_TXCARRSUPP ((fTEST_TX_ENABLE) \ + |(fTEST_TXCARRSUPP_ENABLE)) +/* Transmit Frames */ +#define OP_MODE_TXFRAME (fTEST_TX_ENABLE) +/* Receive Frames */ +#define OP_MODE_RXFRAME (fTEST_RX_ENABLE) +/* MPS */ +#define OP_MODE_MPS ((fTEST_TX_ENABLE)|(fTEST_MPS)) +/* FFT */ +#define OP_MODE_FFT ((fTEST_FFT_ENABLE)|(fTEST_IN_RFTEST)) + +/* Service debug level */ +#define SERV_DBG_LVL_OFF 0 +#define SERV_DBG_LVL_ERROR 1 +#define SERV_DBG_LVL_WARN 2 +#define SERV_DBG_LVL_TRACE 3 +#define SERV_DBG_LVL_MAX SERV_DBG_LVL_TRACE + +/* Debug category */ +#define SERV_DBG_CAT_MISC 0 /* misc */ +#define SERV_DBG_CAT_TEST 1 /* service test */ +#define SERV_DBG_CAT_ENGN 2 /* service engine */ +#define SERV_DBG_CAT_ADAPT 3 /* service adaption */ +#define SERV_DBG_CAT_ALL SERV_DBG_CAT_MISC +#define SERV_DBG_CAT_EN_ALL_MASK 0xFFFFFFFFu + +/* Debugging and printing related definitions and prototypes */ +#define SERV_PRINT printk +#define SERV_PRINT_MAC(addr) \ + (addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]) + +#define SERV_LOG(category, level, fmt) \ + do { \ + if ((0x1 << category) & (SERV_DBG_CAT_EN_ALL_MASK)) \ + if (level <= SERV_DBG_LVL_WARN) \ + SERV_PRINT fmt; \ + } while (0) + +/* OS task related data structure and definition */ +#define SERV_OS_TASK_GET(__pTask) \ + (__pTask) +#define SERV_OS_TASK_GET_WINFOS(__pTask) \ + ((__pTask)->priv_winfos) +#define SERV_OS_TASK_GET_CONFIGS(__pTask) \ + ((__pTask)->priv_configs) +#define SERV_OS_TASK_IS_KILLED(__pTask) \ + ((__pTask)->task_killed) + +#define SERV_OS_INIT_COMPLETION(__pCompletion) \ + init_completion(__pCompletion) +#define SERV_OS_EXIT_COMPLETION(__pCompletion) \ + complete(__pCompletion) +#define SERV_OS_COMPLETE(__pCompletion) \ + complete(__pCompletion) +#define SERV_OS_WAIT_FOR_COMPLETION_TIMEOUT(__pCompletion, __Timeout) \ + wait_for_completion_timeout(__pCompletion, __Timeout) + +/* Spin_lock enhanced for service spin lock */ +#define SERV_OS_ALLOCATE_SPIN_LOCK(__lock) \ + spin_lock_init((spinlock_t *)(__lock)) +#define SERV_OS_FREE_SPIN_LOCK(lock) \ + do {} while (0) +#define SERV_OS_SEM_LOCK(__lock) \ + spin_lock_bh((spinlock_t *)(__lock)) + +#define SERV_OS_SEM_UNLOCK(__lock) \ + spin_unlock_bh((spinlock_t *)(__lock)) + +/* NTOHS/NTONS/NTOHL/NTONS */ +#define SERV_OS_NTOHS(_val) (ntohs((_val))) +#define SERV_OS_HTONS(_val) (htons((_val))) +#define SERV_OS_NTOHL(_val) (ntohl((_val))) +#define SERV_OS_HTONL(_val) (htonl((_val))) + +/* Service skb packet clone */ +#define SERV_PKT_TO_OSPKT(_p) ((struct sk_buff *)(_p)) +#define SERV_OS_PKT_CLONE(_pkt, _src, _flag) \ + { \ + _src = skb_clone(SERV_PKT_TO_OSPKT(_pkt), _flag); \ + } + +/* Array size */ +#define SERV_ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) + +/***************************************************************************** + * Enum value definition + *****************************************************************************/ +/* Service thread usage list */ +enum service_thread_list { + SERV_THREAD_TEST = 0, + SERV_THREAD_NUM +}; + +/***************************************************************************** + * Data struct definition + *****************************************************************************/ +/* Service thread cb for test */ +struct test_thread_cb { + boolean is_init; + struct serv_os_task task; + SERV_OS_SPIN_LOCK lock; + u_char service_stat; + s_int32 deq_cnt; + SERV_OS_COMPLETION cmd_done; + u_long cmd_expire; +}; + +/***************************************************************************** + * Function declaration + *****************************************************************************/ +void sys_ad_free_pkt(void *packet); +s_int32 sys_ad_alloc_mem(u_char **mem, u_long size); +void sys_ad_free_mem(void *mem); +void sys_ad_zero_mem(void *ptr, u_long length); +void sys_ad_set_mem(void *ptr, u_long length, u_char value); +void sys_ad_move_mem(void *dest, void *src, u_long length); +s_int32 sys_ad_cmp_mem(void *dest, void *src, u_long length); +s_int32 sys_ad_kill_os_task(struct serv_os_task *task); +s_int32 sys_ad_attach_os_task( + struct serv_os_task *task, SERV_OS_TASK_CALLBACK fn, u_long arg); +s_int32 sys_ad_init_os_task( + struct serv_os_task *task, char *task_name, + void *priv_winfos, void *priv_configs); +boolean sys_ad_wait_os_task( + void *reserved, struct serv_os_task *task, s_int32 *status); +void sys_ad_wakeup_os_task(struct serv_os_task *task); + +void sys_ad_mem_dump32(void *ptr, u_long length); + +#endif /* __SYS_ADAPTION_H__ */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/glue/osal/jedi/net_adaption_jedi.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/glue/osal/jedi/net_adaption_jedi.c new file mode 100644 index 0000000000000000000000000000000000000000..5b89f93e1fa9bdfaae06222072d340f8b395a153 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/glue/osal/jedi/net_adaption_jedi.c @@ -0,0 +1,3696 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#include "rt_config.h" +#include "net_adaption.h" + +static s_int32 net_ad_open_inf(struct wifi_dev *wdev); +static s_int32 net_ad_close_inf(struct wifi_dev *wdev); +static s_int32 net_ad_enqueue_mlme_pkt( + RTMP_ADAPTER *ad, + void *pkt, + struct wifi_dev *wdev, + u_char q_idx, + boolean is_data_queue); +static s_int32 net_ad_tx_pkt_handle( + RTMP_ADAPTER *ad, + struct wifi_dev *wdev, + struct _TX_BLK *tx_blk); +static s_int32 net_ad_tx( + RTMP_ADAPTER *ad, + struct wifi_dev *wdev, + struct _TX_BLK *tx_blk); + +static struct test_thread_cb g_test_thread[SERV_THREAD_NUM]; +struct test_ant_map test_ant_to_spe_idx_map[] = { + /* All */ + {0x0, 0}, + {0xF, 0}, + /* 1 Ant */ + {0x1, 0}, /* Tx0 */ + {0x2, 1}, /* Tx1 */ + {0x4, 3}, /* Tx2 */ + {0x8, 9}, /* Tx3 */ + /* 2 Ant */ + {0x3, 0}, + {0x5, 2}, + {0x9, 8}, + {0x6, 4}, + {0xA, 6}, + {0xC, 16}, + /* 3 Ant */ + {0x7, 0}, /* 0_1_2 */ + {0xB, 10}, /* 0_1_3 */ + {0xD, 12}, /* 0_2_3 */ + {0xE, 18}, /* 1_2_3 */ +}; + +/***************************************************************************** + * Internal functions + *****************************************************************************/ +static s_int32 net_ad_mps_check_stat( + struct test_wlan_info *winfos, + struct test_configuration *configs) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_mps_cb *mps_cb; + struct test_mps_setting *mps_setting; + u_int32 tx_cnt, txed_cnt; + + mps_cb = &configs->mps_cb; + mps_setting = mps_cb->mps_setting; + if (!mps_setting || !mps_cb->mps_cnt) { + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_ERROR, + ("%s: mps_cb/mps_setting NULL %p/%p\n", + __func__, mps_cb, mps_setting)); + + ret = SERV_STATUS_OSAL_NET_INVALID_NULL_POINTER; + return ret; + } + + tx_cnt = configs->tx_stat.tx_cnt; + txed_cnt = configs->tx_stat.txed_cnt; + + if ((mps_cb->stat & TEST_MPS_ITEM_RUNNING) + && (txed_cnt >= tx_cnt)) { + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_TRACE, + ("%s: mps_idx finished idx=%d, mps_cnt=%d\n", + __func__, mps_cb->ref_idx, mps_cb->mps_cnt)); + SERV_OS_SEM_LOCK(&mps_cb->lock); + mps_cb->stat = 0; + SERV_OS_SEM_UNLOCK(&mps_cb->lock); + + if (mps_cb->ref_idx > mps_cb->mps_cnt) { + configs->op_mode &= ~fTEST_MPS; + mps_cb->setting_inuse = FALSE; + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_TRACE, + ("%s: mps all finished idx=%d, mps_cnt=%d\n", + __func__, mps_cb->ref_idx, mps_cb->mps_cnt)); + + ret = net_ad_mps_tx_operation(winfos, configs, FALSE); + } + } + + return ret; +} + +static s_int32 net_ad_mps_dump_setting( + struct test_configuration *configs, + u_int16 idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_mps_cb *mps_cb; + struct test_mps_setting *mps_setting; + + mps_cb = &configs->mps_cb; + mps_setting = mps_cb->mps_setting; + if (!mps_setting || !mps_cb->mps_cnt) { + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_ERROR, + ("%s: mps_cb/mps_setting NULL %p/%p\n", + __func__, mps_cb, mps_setting)); + + ret = SERV_STATUS_OSAL_NET_INVALID_NULL_POINTER; + return ret; + } + + if (idx == 0xFFFF) { + for (idx = 1; idx <= mps_cb->mps_cnt; idx++) { + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_OFF, + ("item_idx=%d, phy_mode=%d, ", + idx, mps_setting[idx].tx_mode)); + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_OFF, + ("tx_ant=0x%x, mcs=%d, ", + mps_setting[idx].tx_ant, + mps_setting[idx].mcs)); + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_OFF, + ("pkt_len=%d, pkt_cnt=%d, ", + mps_setting[idx].pkt_len, + mps_setting[idx].pkt_cnt)); + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_OFF, + ("pwr=%d, nss=%d, pkt_bw=%d\n", + mps_setting[idx].pwr, + mps_setting[idx].nss, + mps_setting[idx].pkt_bw)); + + } + } else { + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_OFF, + ("item_idx=%d, phy_mode=%d, ", + idx, mps_setting[idx].tx_mode)); + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_OFF, + ("tx_ant=0x%x, mcs=%d, ", + mps_setting[idx].tx_ant, + mps_setting[idx].mcs)); + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_OFF, + ("pkt_len=%d, pkt_cnt=%d, ", + mps_setting[idx].pkt_len, + mps_setting[idx].pkt_cnt)); + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_OFF, + ("pwr=%d, nss=%d, pkt_bw=%d\n", + mps_setting[idx].pwr, + mps_setting[idx].nss, + mps_setting[idx].pkt_bw)); + } + + return ret; +} + +static s_int32 net_ad_mps_load_setting( + struct test_wlan_info *winfos, + struct test_configuration *configs) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_mps_cb *mps_cb; + struct test_mps_setting *mps_setting; + u_char *test_pkt; + u_int32 idx, tx_mode, tx_ant, mcs, pwr; + u_int32 pkt_len, pkt_cnt, nss, pkt_bw; + + /* TODO: factor out here for tx power */ +#if 0 + ATE_TXPOWER TxPower; + + os_zero_mem(&TxPower, sizeof(TxPower)); +#endif + + test_pkt = configs->test_pkt; + mps_cb = &configs->mps_cb; + mps_setting = mps_cb->mps_setting; + if (!mps_cb || !mps_setting) + goto err0; + + SERV_OS_SEM_LOCK(&mps_cb->lock); + + if (mps_cb->stat & TEST_MPS_ITEM_RUNNING) + goto err1; + + mps_cb->stat |= TEST_MPS_ITEM_RUNNING; + idx = mps_cb->ref_idx; + + if (idx > mps_cb->mps_cnt) + goto err2; + + tx_mode = mps_setting[idx].tx_mode; + tx_ant = mps_setting[idx].tx_ant; + mcs = mps_setting[idx].mcs; + pwr = mps_setting[idx].pwr; + pkt_len = mps_setting[idx].pkt_len; + pkt_cnt = mps_setting[idx].pkt_cnt; + nss = mps_setting[idx].nss; + pkt_bw = mps_setting[idx].pkt_bw; + configs->tx_mode = tx_mode; + configs->tx_ant = tx_ant; + configs->mcs = mcs; + configs->nss = nss; + configs->per_pkt_bw = pkt_bw; + configs->tx_len = pkt_len; + configs->tx_stat.tx_cnt = pkt_cnt; + configs->tx_stat.tx_done_cnt = 0; + configs->tx_stat.txed_cnt = 0; + + /* TODO: factor out here for tx power */ +#if 0 + ATECtrl->TxPower0 = pwr; + TxPower.Power = pwr; + TxPower.Channel = Channel; + TxPower.Dbdc_idx = band_idx; + TxPower.Band_idx = Ch_Band; + ATECtrl->need_set_pwr = TRUE; +#endif + + SERV_OS_SEM_UNLOCK(&mps_cb->lock); + + /* TODO: factor out here for tx power */ +#if 0 + ret = ate_op->SetTxPower0(pAd, TxPower); +#endif + + /* Here means no need to fill packet first time */ + if (mps_cb->ref_idx != 1) { + ret = net_ad_fill_pkt(winfos, configs, test_pkt, + configs->tx_len, configs->hdr_len); + if (ret) + goto err2; + } + + ret = net_ad_mps_dump_setting(configs, mps_cb->ref_idx); + mps_cb->ref_idx++; + + return ret; + +err2: + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_TRACE, + ("%s: mps_cb->ref_idx=%d, mps_cnt=%d\n", + __func__, mps_cb->ref_idx, mps_cb->mps_cnt)); +err1: + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_TRACE, + ("%s: item=%d is running\n", + __func__, mps_cb->ref_idx - 1)); + SERV_OS_SEM_UNLOCK(&mps_cb->lock); + return ret; +err0: + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_TRACE, + ("%s: mps_cb/mps_setting NULL %p/%p\n", + __func__, mps_cb, mps_setting)); + return ret; +} + +static VOID net_ad_thread_set_service( + struct test_wlan_info *winfos, + u_char band_idx, u_int8 *stat) +{ + u_int8 mask = 0; + + if (IS_TEST_DBDC(winfos) && (band_idx == TEST_DBDC_BAND1)) + mask = 1 << TEST_DBDC_BAND1; + else + mask = 1 << TEST_DBDC_BAND0; + + *stat |= mask; +} + +VOID net_ad_thread_proceed_tx( + struct test_wlan_info *winfos, u_char band_idx) +{ + u_char thread_idx = SERV_THREAD_TEST; + + RTMP_SEM_LOCK(&g_test_thread[thread_idx].lock); + net_ad_thread_set_service(winfos, + band_idx, + &g_test_thread[thread_idx].service_stat); + RTMP_SEM_UNLOCK(&g_test_thread[thread_idx].lock); + sys_ad_wakeup_os_task(&g_test_thread[thread_idx].task); +} + +VOID net_ad_thread_stop_tx(struct test_wlan_info *winfos) +{ +} + +static s_int32 net_ad_thread_handler( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_char band_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + PQUEUE_HEADER mgmt_swq = NULL; + struct test_configuration *test_config; + struct test_tx_stack *stack = NULL; + struct ipg_param *ipg_param; + struct tx_time_param *tx_time_param; + struct wifi_dev *wdev; + u_int32 op_mode, txed_cnt = 0, tx_cnt = 0, pkt_tx_time, ipg; + s_int32 dequeue_size, multi_users = 0; + u_short q_idx; + u_int8 need_ampdu; + u_char hwq_idx; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + + if (winfos->chip_cap.swq_per_band) + mgmt_swq = &ad->mgmt_que[band_idx]; + else + mgmt_swq = &ad->mgmt_que[0]; + test_config = &configs[band_idx]; + stack = &test_config->stack; + op_mode = test_config->op_mode; + q_idx = test_config->ac_idx; + txed_cnt = test_config->tx_stat.txed_cnt; + tx_cnt = test_config->tx_stat.tx_cnt; + ipg_param = &test_config->ipg_param; + tx_time_param = &test_config->tx_time_param; + pkt_tx_time = tx_time_param->pkt_tx_time; + need_ampdu = tx_time_param->pkt_need_ampdu; + ipg = ipg_param->ipg; + wdev = (struct wifi_dev *)configs->stack.virtual_wtbl[0]; + hwq_idx = hif_get_resource_idx(ad->hdev_ctrl, wdev, TX_MGMT, q_idx); + dequeue_size = g_test_thread[SERV_THREAD_TEST].deq_cnt; + + do { + u_long free_num; + +test_thread_dequeue: + free_num = hif_get_tx_resource_free_num(ad->hdev_ctrl, hwq_idx); + +#if 0 + if (multi_users > 0) { + UCHAR *pate_pkt + = TESTMODE_GET_PARAM(pAd, band_idx, test_pkt); + + ate_ctrl->wcid_ref = multi_users; + ret = MT_ATEGenPkt(pAd, pate_pkt, band_idx); + } +#endif + + if (op_mode & OP_MODE_STOP) + break; + + if (!(op_mode & OP_MODE_TXFRAME)) + break; + + if (!free_num) + break; + +round_tx: + if (((pkt_tx_time > 0) || (ipg > 0)) && + (mgmt_swq->Number >= MGMT_QUE_MAX_NUMS)) + break; + + /* For service thread tx packet counter control */ + if (tx_cnt <= txed_cnt) + break; + + if ((pkt_tx_time > 0) && need_ampdu) + q_idx = WMM_AC_BE; + else + q_idx = WMM_AC_BK; + + ret = net_ad_enq_pkt(winfos, + q_idx, + stack->virtual_wtbl[stack->q_idx], + stack->virtual_device[stack->q_idx], + stack->pkt_skb[stack->q_idx]); + if (ret) + break; + + txed_cnt++; + stack->q_idx++; + + if (stack->q_idx == stack->index) + stack->q_idx = 0; + + if (((pkt_tx_time > 0) && need_ampdu) || (ipg > 0)) { + PKT_TOKEN_CB *cb = NULL; + PKT_TOKEN_QUEUE *que = NULL; + u_int32 free_token_cnt, pkt_tx_token_id_max; + + cb = hc_get_ct_cb(winfos->hdev_ctrl); + que = cut_through_get_token_queue_by_band(cb, 0); + free_token_cnt = + cut_through_get_free_token_cnt(que); + pkt_tx_token_id_max = que->pkt_tkid_max; + free_num = hif_get_tx_resource_free_num(ad->hdev_ctrl, + hwq_idx); + + if ((free_token_cnt + > (pkt_tx_token_id_max - TEST_ENQ_PKT_NUM)) + && (free_num > 0) + && (mgmt_swq->Number < MGMT_QUE_MAX_NUMS)) + goto round_tx; + } + + dequeue_size--; + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_TRACE, + ("%s: band_idx=%u, tx_cnt=%u, txed_cnt=%u, ", + __func__, band_idx, tx_cnt, txed_cnt)); + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_TRACE, + ("dequeue=%d, multi_user=%d, free=%lu\n", + dequeue_size, multi_users, free_num)); + + if (!dequeue_size) { + multi_users--; + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_TRACE, + ("%s: dequeue %d finish, multi_user=%d\n", + __func__, dequeue_size, multi_users)); + } else + goto test_thread_dequeue; + } while (multi_users > 0); + + test_config->tx_stat.txed_cnt = txed_cnt; + test_config->tx_stat.tx_cnt = tx_cnt; + + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_TRACE, + ("%s: band_idx=%d, tx_cnt=%u, txed_cnt=%u, dequeue=%d\n", + __func__, band_idx, tx_cnt, txed_cnt, dequeue_size)); + + return ret; +} + +static s_int32 net_ad_thread_get_band_idx( + struct test_wlan_info *winfos, + u_int8 *stat) +{ + u_int8 mask = 0; + + mask = 1 << TEST_DBDC_BAND0; + + if (*stat & mask) { + *stat &= ~mask; + return TEST_DBDC_BAND0; + } + + mask = 1 << TEST_DBDC_BAND1; + + if (IS_TEST_DBDC(winfos) && (*stat & mask)) { + *stat &= ~mask; + return TEST_DBDC_BAND1; + } + + return -1; +} + +static s_int32 net_ad_thread(u_long context) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct serv_os_task *task = (SERV_OS_TASK *) context; + struct test_wlan_info *winfos = NULL; + struct test_configuration *configs = NULL; + RTMP_ADAPTER *ad = NULL; + u_char thread_idx = SERV_THREAD_TEST; + s_int32 status; + s_int32 band_idx = 0; + u_char service_stat = 0; + + if (!task) + goto err; + + winfos = (struct test_wlan_info *)SERV_OS_TASK_GET_WINFOS(task); + configs = (struct test_configuration *)SERV_OS_TASK_GET_CONFIGS(task); + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + goto err; + + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_TRACE, + ("%s: init thread_idx %u for band %d\n", + __func__, thread_idx, band_idx)); + SERV_OS_COMPLETE(&g_test_thread[thread_idx].cmd_done); + + while (!SERV_OS_TASK_IS_KILLED(task)) { + if (sys_ad_wait_os_task(NULL, task, &status) == FALSE) { + RTMP_SET_FLAG(ad, fRTMP_ADAPTER_HALT_IN_PROGRESS); + break; + } + + SERV_OS_SEM_LOCK(&g_test_thread[thread_idx].lock); + service_stat = g_test_thread[thread_idx].service_stat; + + do { + if (!service_stat) + break; + + band_idx = net_ad_thread_get_band_idx(winfos, + &service_stat); + + if (band_idx == -1) + break; + + ret = net_ad_thread_handler( + winfos, configs, (u_char)band_idx); + } while (1); + + g_test_thread[thread_idx].service_stat = service_stat; + SERV_OS_SEM_UNLOCK(&g_test_thread[thread_idx].lock); + + if (band_idx == -1) + goto err; + + if (configs->op_mode & fTEST_MPS) { + ret = net_ad_mps_check_stat(winfos, configs); + if (ret) + break; + + ret = net_ad_mps_load_setting(winfos, configs); + if (ret) + break; + } + + schedule(); + + if (ret) + break; + } + +err: + if (ad) + RTMP_CLEAR_FLAG(ad, fRTMP_ADAPTER_HALT_IN_PROGRESS); + + g_test_thread[thread_idx].is_init = FALSE; + + if (ret) + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_ERROR, + ("%s: abnormal leave err=0x%08x\n", __func__, ret)); + + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_TRACE, + ("%s: leave\n", __func__)); + + return ret; +} + +static s_int32 net_ad_init_payload( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_char *packet, u_int32 len) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + u_int32 policy, pl_len, pos; + u_char *payload; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + + policy = configs->fixed_payload; + payload = configs->payload; + pl_len = configs->pl_len; + + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_OFF, + ("%s: len=%d, pl_len=%u, policy=%x\n", + __func__, len, pl_len, policy)); + + if (policy == TEST_RANDOM_PAYLOAD) { + for (pos = 0; pos < len; pos++) + packet[pos] = RandomByte(ad); + + return ret; + } + + if (!payload) + return SERV_STATUS_OSAL_NET_INVALID_NULL_POINTER; + + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_OFF, + ("%s: payload=%x\n", __func__, payload[0])); + + if (pl_len == 0) { + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_ERROR, + ("%s: payload length can't be 0!!\n", __func__)); + + return SERV_STATUS_OSAL_NET_INVALID_LEN; + } + + if (policy == TEST_USER_PAYLOAD) { + sys_ad_zero_mem(packet, len); + sys_ad_move_mem(packet, payload, pl_len); + } else if (policy == TEST_FIXED_PAYLOAD) { + for (pos = 0; pos < len; pos += pl_len) + sys_ad_move_mem(&packet[pos], payload, pl_len); + } + + return ret; +} + +static s_int32 net_ad_fill_tmac_info( + RTMP_ADAPTER *ad, + TMAC_INFO *tmac_info, + u_char band_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct service_test *serv_test; + struct test_configuration *configs; + struct tx_time_param *tx_time_param; + struct wifi_dev *wdev = NULL; + u_char *addr1 = NULL; + u_char tx_mode, mcs, vht_nss, wmm_idx; + u_int32 ant_sel, pkt_tx_time; + u_int8 need_qos, need_amsdu, need_ampdu; + boolean fgspe; + + /* Note: shall not use ad here */ + serv_test = (struct service_test *)ad->serv.serv_handle; + configs = &serv_test->test_config[band_idx]; + wdev = configs->wdev[0]; + tx_time_param = &configs->tx_time_param; + pkt_tx_time = tx_time_param->pkt_tx_time; + need_qos = tx_time_param->pkt_need_qos; + need_amsdu = tx_time_param->pkt_need_amsdu; + need_ampdu = tx_time_param->pkt_need_ampdu; + + if (!wdev) { + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_ERROR, + ("%s: cannot get wdev\n", __func__)); + + return SERV_STATUS_OSAL_NET_INVALID_PARAM; + } + + configs->hdr_len = LENGTH_802_11; + addr1 = configs->addr1[0]; + ant_sel = configs->tx_ant; + tx_mode = configs->tx_mode; + mcs = configs->mcs; + vht_nss = configs->nss; + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_TRACE, + ("%s: addr1=%02x:%02x:%02x:%02x:%02x:%02x\n", + __func__, SERV_PRINT_MAC(addr1))); + + /* Fill TMAC_INFO */ + sys_ad_zero_mem(tmac_info, sizeof(*tmac_info)); + tmac_info->LongFmt = TRUE; + + if (pkt_tx_time > 0) { + tmac_info->WifiHdrLen = (u_int8)tx_time_param->pkt_hdr_len; + tmac_info->PktLen = (u_int16)tx_time_param->pkt_msdu_len; + tmac_info->NeedTrans = FALSE; + + if (need_qos | need_amsdu | need_ampdu) { + tmac_info->HdrPad = 2; + tmac_info->BmcPkt = FALSE; + tmac_info->UserPriority = 0; + } else { + tmac_info->HdrPad = 0; + tmac_info->BmcPkt = IS_BM_MAC_ADDR(addr1); + tmac_info->UserPriority = 0; + } + } else { + tmac_info->WifiHdrLen = (u_int8)configs->hdr_len; + tmac_info->HdrPad = 0; + tmac_info->PktLen = (u_int16)configs->tx_len; + tmac_info->BmcPkt = IS_BM_MAC_ADDR(addr1); + } + + /* no ack */ + if ((pkt_tx_time > 0) && (need_ampdu)) + tmac_info->bAckRequired = 1; + else + tmac_info->bAckRequired = 0; + + tmac_info->FrmType = FC_TYPE_DATA; + tmac_info->SubType = SUBTYPE_QDATA; + tmac_info->OwnMacIdx = wdev->OmacIdx; + + /* no frag */ + tmac_info->FragIdx = 0; + + /* no protection */ + tmac_info->CipherAlg = 0; + + /* tx path setting */ + tmac_info->VhtNss = vht_nss ? vht_nss : 1; + tmac_info->AntPri = 0; + tmac_info->SpeEn = 0; + + /* timing measure setting */ + if ((ad->pTmrCtrlStruct != NULL) + && (ad->pTmrCtrlStruct->TmrEnable == TMR_INITIATOR)) + tmac_info->TimingMeasure = 1; + + /* band_idx for tx ring choose */ + tmac_info->band_idx = band_idx; + + switch (ant_sel) { + case 0: /* both */ + tmac_info->AntPri = 0; + tmac_info->SpeEn = 1; + break; + + case 1: /* tx0 */ + tmac_info->AntPri = 0; + tmac_info->SpeEn = 0; + break; + + case 2: /* tx1 */ + tmac_info->AntPri = 2; /* b'010 */ + tmac_info->SpeEn = 0; + break; + } + + + /* Need to modify the way of getting wmm_idx */ + wmm_idx = configs->wmm_idx; + tmac_info->WmmSet = wmm_idx; + + if (ant_sel & TEST_ANT_USER_SEL) { + ant_sel &= ~TEST_ANT_USER_SEL; + tmac_info->AntPri = ant_sel; + } else { + s_int32 map_idx; + + for (map_idx = 0; + map_idx < SERV_ARRAY_SIZE(test_ant_to_spe_idx_map); + map_idx++) { + if (ant_sel == + test_ant_to_spe_idx_map[map_idx].ant_sel) + break; + } + + if (map_idx == SERV_ARRAY_SIZE(test_ant_to_spe_idx_map)) + tmac_info->AntPri = 0; + else + tmac_info->AntPri + = test_ant_to_spe_idx_map[map_idx].spe_idx; + } + + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_TRACE, + ("%s: ant_sel=%x, ant_pri=%x, vht_nss=%x, TxD.VhtNss=%x\n", + __func__, ant_sel, tmac_info->AntPri, + vht_nss, tmac_info->VhtNss)); + + /* Fill transmit setting */ + tmac_info->TxRadioSet.RateCode = mcs; + tmac_info->TxRadioSet.PhyMode = tx_mode; + tmac_info->TxRadioSet.CurrentPerPktBW = configs->per_pkt_bw; + tmac_info->TxRadioSet.ShortGI = configs->sgi; + tmac_info->TxRadioSet.Stbc = configs->stbc; + tmac_info->TxRadioSet.Ldpc = configs->ldpc; + + tmac_info->QueIdx = + asic_get_hwq_from_ac(ad, tmac_info->WmmSet, configs->ac_idx); + + if ((pkt_tx_time > 0) && (need_ampdu)) { + tmac_info->Wcid = configs->wcid_ref; + tmac_info->FixRate = 0; + tmac_info->BaDisable = FALSE; + tmac_info->RemainTxCnt = 1; + } else { + tmac_info->Wcid = 0; + tmac_info->FixRate = 1; + tmac_info->BaDisable = TRUE; + tmac_info->RemainTxCnt = 15; + } + + if (configs->txs_enable) { + tmac_info->TxS2Host = TRUE; + tmac_info->TxS2Mcu = FALSE; + tmac_info->TxSFmt = 1; + } + + if (tx_mode == TEST_MODE_CCK) { + tmac_info->TxRadioSet.Premable = LONG_PREAMBLE; + + if (mcs == MCS_9) { + tmac_info->TxRadioSet.RateCode = 0; + tmac_info->TxRadioSet.Premable = SHORT_PREAMBLE; + } else if (mcs == MCS_10) { + tmac_info->TxRadioSet.RateCode = 1; + tmac_info->TxRadioSet.Premable = SHORT_PREAMBLE; + } else if (mcs == MCS_11) { + tmac_info->TxRadioSet.RateCode = 2; + tmac_info->TxRadioSet.Premable = SHORT_PREAMBLE; + } + } + + tmac_info->Wcid = configs->wcid_ref; + if (tmac_info->AntPri >= 24) + fgspe = TRUE; + else + fgspe = FALSE; + + if ((pkt_tx_time > 0) && (need_ampdu)) { + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_TRACE, + ("%s: tmac_info->Wcid/Wmmset/QueIdx=%d/%d/%d\n", + __func__, tmac_info->Wcid, + tmac_info->WmmSet, tmac_info->QueIdx)); + } + + return ret; +} + +static s_int32 net_ad_fill_non_offload_tx_blk( + RTMP_ADAPTER *ad, + struct wifi_dev *wdev, + void *tx_blk) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + PACKET_INFO pkt_info; + void *packet; + TX_BLK *txblk = (TX_BLK *)tx_blk; + + packet = txblk->pPacket; + txblk->Wcid = RTMP_GET_PACKET_WCID(packet); + RTMP_QueryPacketInfo( + packet, &pkt_info, &txblk->pSrcBufHeader, &txblk->SrcBufLen); + + TX_BLK_SET_FLAG(txblk, fTX_CT_WithTxD); + + if (RTMP_GET_PACKET_CLEAR_EAP_FRAME(packet)) + TX_BLK_SET_FLAG(txblk, fTX_bClearEAPFrame); + + if (IS_ASIC_CAP(ad, fASIC_CAP_TX_HDR_TRANS)) { + if ((txblk->TxFrameType == TX_LEGACY_FRAME) + || (txblk->TxFrameType == TX_AMSDU_FRAME) + || (txblk->TxFrameType == TX_MCAST_FRAME)) + TX_BLK_SET_FLAG(txblk, fTX_HDR_TRANS); + } + + txblk->pSrcBufData = txblk->pSrcBufHeader; + + return ret; +} + +static boolean net_ad_fill_offload_tx_blk( + RTMP_ADAPTER *ad, + struct wifi_dev *wdev, + void *tx_blk, + boolean retry) +{ + struct _RTMP_CHIP_CAP *cap = hc_get_chip_cap(ad->hdev_ctrl); + PACKET_INFO pkt_info; + PNDIS_PACKET pPacket; + TX_BLK *txblk = (TX_BLK *)tx_blk; + + pPacket = txblk->pPacket; + txblk->Wcid = RTMP_GET_PACKET_WCID(pPacket); + RTMP_QueryPacketInfo(pPacket, + &pkt_info, + &txblk->pSrcBufHeader, + &txblk->SrcBufLen); + txblk->pSrcBufHeader += cap->TXWISize; + /* Due to testmode allocate size include TXWISize */ + txblk->SrcBufLen -= cap->TXWISize; + + TX_BLK_SET_FLAG(txblk, fTX_CT_WithTxD); + + if (RTMP_GET_PACKET_CLEAR_EAP_FRAME(pPacket)) + TX_BLK_SET_FLAG(txblk, fTX_bClearEAPFrame); + + /* testmode data does not support fTX_HDR_TRANS yet + if (IS_ASIC_CAP(pAd, fASIC_CAP_TX_HDR_TRANS)) { + if ((txblk->TxFrameType == TX_LEGACY_FRAME) + || (txblk->TxFrameType == TX_AMSDU_FRAME) + || (txblk->TxFrameType == TX_MCAST_FRAME)) + TX_BLK_SET_FLAG(tx_blk, fTX_HDR_TRANS); + } + */ + + txblk->pSrcBufData = txblk->pSrcBufHeader; + txblk->wmm_set = HcGetWmmIdx(ad, wdev); + + if (retry) + TX_BLK_SET_FLAG(txblk, fTX_bRetryUnlimit); + else + TX_BLK_SET_FLAG(txblk, fTX_bNoRetry); + + txblk->UserPriority = 0; + + /* no frag */ + txblk->FragIdx = 0; + /* no protection */ + SET_CIPHER_NONE(txblk->CipherAlg); + return TRUE; +} + +/***************************************************************************** + * Extern functions + *****************************************************************************/ +struct service_test *net_ad_wrap_service(void *adapter) +{ + struct _RTMP_ADAPTER *ad = (struct _RTMP_ADAPTER *)adapter; + struct service *serv = &ad->serv; + + return (struct service_test *)serv->serv_handle; +} + +struct wifi_dev_ops serv_wdev_ops = { + .open = net_ad_open_inf, + .close = net_ad_close_inf, + .send_mlme_pkt = net_ad_enqueue_mlme_pkt, + .tx_pkt_handle = net_ad_tx_pkt_handle, + .ate_tx = net_ad_tx, + .disconn_act = wifi_sys_disconn_act +}; + +s_int32 net_ad_open_inf(struct wifi_dev *wdev) +{ + struct _RTMP_ADAPTER *ad = (struct _RTMP_ADAPTER *)wdev->sys_handle; + +#ifdef RELEASE_EXCLUDE + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_OFF, + ("%s --->\n", __func__)); +#endif /* RELEASE_EXCLUDE */ + + if (wifi_sys_open(wdev) != TRUE) { + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_OFF, + ("%s: open fail!!!\n", __func__)); + return FALSE; + } + + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_OFF, + ("%s: inf up for ra_%x(func_idx) OmacIdx=%d\n", + __func__, wdev->func_idx, wdev->OmacIdx)); + + MlmeRadioOn(ad, wdev); + + wdev->bAllowBeaconing = FALSE; + +#ifdef RELEASE_EXCLUDE + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_OFF, + ("%s <---\n", __func__)); +#endif /* RELEASE_EXCLUDE */ + + return TRUE; +} + +s_int32 net_ad_close_inf(struct wifi_dev *wdev) +{ + struct _RTMP_ADAPTER *ad = (struct _RTMP_ADAPTER *)wdev->sys_handle; + +#ifdef RELEASE_EXCLUDE + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_OFF, + ("%s --->\n", __func__)); +#endif /* RELEASE_EXCLUDE */ + + if (ad == NULL) + return FALSE; + + if (wifi_sys_close(wdev) != TRUE) { + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_TRACE, + ("%s: close fail!!!\n", __func__)); + return FALSE; + } + +#ifdef RELEASE_EXCLUDE + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_OFF, + ("%s <---\n", __func__)); +#endif /* RELEASE_EXCLUDE */ + + return TRUE; +} + +s_int32 net_ad_enqueue_mlme_pkt( + RTMP_ADAPTER *ad, + void *pkt, + struct wifi_dev *wdev, + u_char q_idx, + boolean is_data_queue) +{ + s_int32 ret; + struct qm_ops *ops = ad->qm_ops; + + RTMP_SET_PACKET_MGMT_PKT(pkt, 1); + + ret = ops->enq_mgmtq_pkt(ad, wdev, pkt); + + return ret; +} + +s_int32 net_ad_tx_pkt_handle( + RTMP_ADAPTER *ad, + struct wifi_dev *wdev, + struct _TX_BLK *tx_blk) +{ + struct wifi_dev_ops *ops = NULL; + s_int32 ret = NDIS_STATUS_SUCCESS; + + if (!wdev) { + RELEASE_NDIS_PACKET(ad, tx_blk->pPacket, NDIS_STATUS_FAILURE); + return NDIS_STATUS_FAILURE; + } + + ops = wdev->wdev_ops; + ret = ops->ate_tx(ad, wdev, tx_blk); + + return ret; +} + +s_int32 net_ad_tx( + RTMP_ADAPTER *ad, + struct wifi_dev *wdev, + struct _TX_BLK *tx_blk) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + TMAC_INFO tmac_info; + PQUEUE_ENTRY q_entry; + RTMP_ARCH_OP *arch_ops = hc_get_arch_ops(ad->hdev_ctrl); + u_int32 band_idx = HcGetBandByWdev(wdev); + + q_entry = RemoveHeadQueue(&tx_blk->TxPacketList); + tx_blk->pPacket = QUEUE_ENTRY_TO_PACKET(q_entry); + RTMP_SET_PACKET_WCID(tx_blk->pPacket, 0); + + /* Fill tx blk for test mode */ + ret = net_ad_fill_non_offload_tx_blk(ad, wdev, tx_blk); + + /* TMAC_INFO setup for test mode */ + ret = net_ad_fill_tmac_info(ad, &tmac_info, band_idx); + if (ret) + return ret; + + return arch_ops->ate_hw_tx(ad, &tmac_info, tx_blk); +} + +s_int32 net_ad_tx_v2( + struct _RTMP_ADAPTER *ad, + struct wifi_dev *wdev, + struct _TX_BLK *tx_blk) +{ + u_int8 band_idx = 0, need_ampdu = 0, need_amsdu = 0; + s_int32 ret = 0; + PQUEUE_ENTRY q_entry; + RTMP_ARCH_OP *arch_ops = hc_get_arch_ops(ad->hdev_ctrl); + struct service_test *serv_test = NULL; + struct test_configuration *configs = NULL; + struct tx_time_param *tx_time_settings = NULL; + + serv_test = (struct service_test *)ad->serv.serv_handle; + q_entry = RemoveHeadQueue(&tx_blk->TxPacketList); + tx_blk->pPacket = QUEUE_ENTRY_TO_PACKET(q_entry); + + band_idx = HcGetBandByWdev(wdev); + configs = &serv_test->test_config[band_idx]; + tx_time_settings = &configs->tx_time_param; + need_ampdu = tx_time_settings->pkt_need_ampdu; + need_amsdu = tx_time_settings->pkt_need_amsdu; + + if (tx_time_settings->pkt_need_qos) { + tx_blk->wifi_hdr_len = (UINT8) tx_time_settings->pkt_hdr_len; + tx_blk->MpduHeaderLen = (UINT8) tx_time_settings->pkt_hdr_len; + } else { + tx_blk->wifi_hdr_len = (UINT8) LENGTH_802_11; + tx_blk->MpduHeaderLen = (UINT8) LENGTH_802_11; + } + + if (need_ampdu) { + TX_BLK_CLEAR_FLAG(tx_blk, fTX_ForceRate); + TX_BLK_SET_FLAG(tx_blk, fTX_bAckRequired); + TX_BLK_SET_FLAG(tx_blk, fTX_bAteAgg); + tx_blk->HdrPadLen = 2; + } else { + TX_BLK_SET_FLAG(tx_blk, fTX_ForceRate); + TX_BLK_CLEAR_FLAG(tx_blk, fTX_bAckRequired); + tx_blk->HdrPadLen = 0; + } + + /* Fill TX blk for ATE mode */ + if (configs->tx_mode == TEST_MODE_HE_MU && configs->retry) + ret = net_ad_fill_offload_tx_blk(ad, wdev, tx_blk, TRUE); + else + ret = net_ad_fill_offload_tx_blk(ad, wdev, tx_blk, FALSE); + + tx_blk->QueIdx = configs->ac_idx; + if (mt_engine_search_stack(configs, + RTMP_GET_PACKET_WCID(tx_blk->pPacket), + (void **)&tx_blk->pMacEntry) != SERV_STATUS_SUCCESS) { + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_ERROR, + ("%s: wcid:%d is in-valid in stack!\n", __func__, + RTMP_GET_PACKET_WCID(tx_blk->pPacket))); + + return NDIS_STATUS_FAILURE; + } +#if defined(CONFIG_AP_SUPPORT) + if (tx_blk->pMacEntry) + tx_blk->pMbss = tx_blk->pMacEntry->pMbss; +#endif + if (configs->txs_enable) + TX_BLK_SET_FLAG(tx_blk, fTX_bAteTxsRequired); + + return arch_ops->hw_tx(ad, tx_blk); +} + +s_int32 net_ad_init_thread( + struct test_wlan_info *winfos, + struct test_configuration *configs, + enum service_thread_list thread_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + + /* Init test_thread_cb */ + if (thread_idx == SERV_THREAD_TEST) { + g_test_thread[thread_idx].deq_cnt = 1; + g_test_thread[thread_idx].cmd_expire = RTMPMsecsToJiffies(3000); + SERV_OS_INIT_COMPLETION(&g_test_thread[thread_idx].cmd_done); + + if (!g_test_thread[thread_idx].is_init) { + ret = sys_ad_init_os_task( + &g_test_thread[thread_idx].task, + "serv_thread_tx", + (VOID *)winfos, + (VOID *)configs); + if (ret) + goto err; + + NdisAllocateSpinLock( + ad, &g_test_thread[thread_idx].lock); + + ret = sys_ad_attach_os_task( + &g_test_thread[thread_idx].task, + net_ad_thread, + (ULONG)&g_test_thread[thread_idx].task); + + if (!RTMP_OS_WAIT_FOR_COMPLETION_TIMEOUT + (&g_test_thread[thread_idx].cmd_done, + g_test_thread[thread_idx].cmd_expire)) + goto err; + + if (ret) + goto err; + + g_test_thread[thread_idx].is_init = TRUE; + } + + g_test_thread[thread_idx].service_stat = 0; + } + + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_OFF, + ("%s: initialize thread_idx=%d\n", __func__, thread_idx)); + + return ret; + +err: + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_ERROR, + ("%s: tx thread init fail err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 net_ad_release_thread( + u_char thread_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + if (&g_test_thread[thread_idx].task) + ret = sys_ad_kill_os_task(&g_test_thread[thread_idx].task); + + if (ret != SERV_STATUS_SUCCESS) + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_ERROR, + ("kill test mode tx task failed!\n")); + else + g_test_thread[thread_idx].is_init = FALSE; + + NdisFreeSpinLock(&g_test_thread[thread_idx].lock); + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_OFF, + ("%s: release thread_idx=%d\n", __func__, thread_idx)); + + return ret; +} + +s_int32 net_ad_backup_cr( + struct test_wlan_info *winfos, + struct test_bk_cr *test_bkcr, + u_long offset, enum test_bk_cr_type type) +{ + struct test_bk_cr *entry = NULL; + RTMP_ADAPTER *ad = NULL; + u_int32 entry_idx; + + if ((type >= SERV_TEST_BKCR_TYPE_NUM) + || (type == SERV_TEST_EMPTY_BKCR)) + return SERV_STATUS_OSAL_NET_FAIL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + + for (entry_idx = 0; entry_idx < TEST_MAX_BKCR_NUM; entry_idx++) { + struct test_bk_cr *tmp = &test_bkcr[entry_idx]; + + if ((tmp->type == SERV_TEST_EMPTY_BKCR) && (entry == NULL)) { + entry = tmp; + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_TRACE, + ("%s: find empty bk entry %d\n", + __func__, entry_idx)); + } else if ((tmp->type == type) && (tmp->offset == offset)) { + entry = tmp; + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_TRACE, + ("%s: update bk entry %d\n", + __func__, entry_idx)); + break; + } + } + + if (!entry) + return SERV_STATUS_OSAL_NET_FAIL; + + entry->type = type; + entry->offset = offset; + + switch (type) { + case SERV_TEST_MAC_BKCR: + MAC_IO_READ32(ad->hdev_ctrl, offset, &entry->val); + break; + + case SERV_TEST_HIF_BKCR: + HIF_IO_READ32(ad->hdev_ctrl, offset, &entry->val); + break; + + case SERV_TEST_PHY_BKCR: + PHY_IO_READ32(ad->hdev_ctrl, offset, &entry->val); + break; + + case SERV_TEST_HW_BKCR: + HW_IO_READ32(ad->hdev_ctrl, offset, &entry->val); + break; + + case SERV_TEST_MCU_BKCR: + MCU_IO_READ32(ad->hdev_ctrl, offset, &entry->val); + break; + + default: + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_WARN, + ("%s: bk-type not supported\n", __func__)); + entry->type = SERV_TEST_EMPTY_BKCR; + entry->offset = 0; + break; + } + + return SERV_STATUS_SUCCESS; +} + +s_int32 net_ad_restore_cr( + struct test_wlan_info *winfos, + struct test_bk_cr *test_bkcr, + u_long offset) +{ + struct test_bk_cr *entry = NULL; + RTMP_ADAPTER *ad = NULL; + u_int32 entry_idx; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + + for (entry_idx = 0; entry_idx < TEST_MAX_BKCR_NUM; entry_idx++) { + struct test_bk_cr *tmp = &test_bkcr[entry_idx]; + + if (tmp->offset == offset) { + entry = tmp; + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_TRACE, + ("%s: find entry %d\n", __func__, entry_idx)); + break; + } + } + + if (!entry) + return SERV_STATUS_OSAL_NET_FAIL; + + switch (entry->type) { + case SERV_TEST_MAC_BKCR: + MAC_IO_WRITE32(ad->hdev_ctrl, offset, entry->val); + break; + + case SERV_TEST_HIF_BKCR: + HIF_IO_WRITE32(ad->hdev_ctrl, offset, entry->val); + break; + + case SERV_TEST_PHY_BKCR: + PHY_IO_WRITE32(ad->hdev_ctrl, offset, entry->val); + break; + + case SERV_TEST_HW_BKCR: + HW_IO_WRITE32(ad->hdev_ctrl, offset, entry->val); + break; + + case SERV_TEST_MCU_BKCR: + MCU_IO_WRITE32(ad->hdev_ctrl, offset, entry->val); + break; + + default: + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_WARN, + ("%s: bk-type not supported\n", __func__)); + entry->type = SERV_TEST_EMPTY_BKCR; + entry->offset = 0; + break; + } + + entry->type = SERV_TEST_EMPTY_BKCR; + entry->offset = 0; + entry->val = 0; + + return SERV_STATUS_SUCCESS; +} + +s_int32 net_ad_cfg_queue( + struct test_wlan_info *winfos, boolean enable) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; +#ifdef CONFIG_AP_SUPPORT + s_int32 bss_id, max_num_bss; +#endif /* CONFIG_AP_SUPPROT */ + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + +#ifdef CONFIG_AP_SUPPORT + max_num_bss = ad->ApCfg.BssidNum; +#endif + + if (enable) { + /* Start DMA */ + chip_set_hif_dma(ad, DMA_TX_RX, TRUE); + + /* Start to deq sw queue */ + RTMP_CLEAR_FLAG(ad, fRTMP_ADAPTER_DISABLE_DEQUEUEPACKET); + + /* Start tcp/ip layer queue */ + RTMP_OS_NETDEV_START_QUEUE(ad->net_dev); +#ifdef CONFIG_AP_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_AP(ad) { + if (max_num_bss > MAX_MBSSID_NUM(ad)) + max_num_bss = MAX_MBSSID_NUM(ad); + + for (bss_id = FIRST_MBSSID; + bss_id < MAX_MBSSID_NUM(ad); bss_id++) { + if (ad->ApCfg.MBSSID[bss_id].wdev.if_dev) + RTMP_OS_NETDEV_START_QUEUE( + ad->ApCfg.MBSSID[bss_id].wdev.if_dev); + } + } +#endif /* CONFIG_AP_SUPPROT */ + } else { + /* Stop tcp/ip layer queue */ + RTMP_OS_NETDEV_STOP_QUEUE(ad->net_dev); +#ifdef CONFIG_AP_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_AP(ad) { + if (max_num_bss > MAX_MBSSID_NUM(ad)) + max_num_bss = MAX_MBSSID_NUM(ad); + + for (bss_id = FIRST_MBSSID; + bss_id < MAX_MBSSID_NUM(ad); bss_id++) { + if (ad->ApCfg.MBSSID[bss_id].wdev.if_dev) + RTMP_OS_NETDEV_STOP_QUEUE( + ad->ApCfg.MBSSID[bss_id].wdev.if_dev); + } + } +#endif /* CONFIG_AP_SUPPROT */ + /* Stop to deq sw queue */ + RTMP_SET_FLAG(ad, fRTMP_ADAPTER_DISABLE_DEQUEUEPACKET); + + /* Stop DMA */ + chip_set_hif_dma(ad, DMA_TX_RX, FALSE); + } + + return ret; +} + +s_int32 net_ad_startup_ap( + struct test_wlan_info *winfos) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; +#ifdef CONFIG_AP_SUPPORT + BSS_STRUCT *mbss = NULL; +#endif /* CONFIG_AP_SUPPROT */ + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + +#ifdef CONFIG_AP_SUPPORT + mbss = &ad->ApCfg.MBSSID[MAIN_MBSSID]; +#endif /* CONFIG_AP_SUPPROT */ + + ret = NICInitializeAdapter(ad); + if (ret != NDIS_STATUS_SUCCESS) + return SERV_STATUS_OSAL_NET_FAIL; + + RTMPSetTimer(&ad->Mlme.PeriodicTimer, MLME_TASK_EXEC_INTV); + +#ifdef CONFIG_AP_SUPPORT + APStartUp(ad, mbss, AP_BSS_OPER_ALL); +#endif /* CONFIG_AP_SUPPROT */ + + /* Start tx path queues */ + ret = net_ad_cfg_queue(winfos, TRUE); + + return ret; +} + +s_int32 net_ad_stop_ap( + struct test_wlan_info *winfos) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + boolean cancelled; +#ifdef CONFIG_AP_SUPPORT + s_int32 bss_id, max_num_bss; + BSS_STRUCT *mbss = NULL; +#endif + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + +#ifdef CONFIG_AP_SUPPORT + max_num_bss = ad->ApCfg.BssidNum; + mbss = &ad->ApCfg.MBSSID[MAIN_MBSSID]; +#endif + + /* Stop tx path queues */ + ret = net_ad_cfg_queue(winfos, FALSE); + +#ifdef CONFIG_AP_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_AP(ad) { + if (max_num_bss > MAX_MBSSID_NUM(ad)) + max_num_bss = MAX_MBSSID_NUM(ad); + + /* First IdBss must not be 0 (BSS0), must be 1 (BSS1) */ + for (bss_id = FIRST_MBSSID; + bss_id < MAX_MBSSID_NUM(ad); bss_id++) { + if (ad->ApCfg.MBSSID[bss_id].wdev.if_dev) + ad->ApCfg.MBSSID[bss_id].wdev.protection = 0; + } + } +#endif + chip_set_hif_dma(ad, DMA_TX_RX, TRUE); +#ifdef CONFIG_AP_SUPPORT + APStop(ad, mbss, AP_BSS_OPER_ALL); +#endif /* CONFIG_AP_SUPPORT */ + RTMP_CLEAR_FLAG(ad, fRTMP_ADAPTER_HALT_IN_PROGRESS); + + RTMPCancelTimer(&ad->Mlme.PeriodicTimer, &cancelled); + RTMP_SET_FLAG(ad, fRTMP_ADAPTER_SYSEM_READY); + + return ret; +} + +s_int32 net_ad_enter_normal( + struct test_wlan_info *winfos, + struct test_backup_params *bak) +{ + RTMP_ADAPTER *ad = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + + ad->CommonCfg.bEnableTxBurst = bak->en_tx_burst; + ad->CommonCfg.BeaconPeriod = bak->bcn_prd; + net_ad_startup_ap(winfos); + ad->CommonCfg.bBssCoexEnable = bak->en_bss_coex; + + return SERV_STATUS_SUCCESS; +} + +s_int32 net_ad_exit_normal( + struct test_wlan_info *winfos, + struct test_backup_params *bak) +{ + RTMP_ADAPTER *ad = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + + net_ad_stop_ap(winfos); + + bak->en_tx_burst = ad->CommonCfg.bEnableTxBurst; + ad->CommonCfg.bEnableTxBurst = FALSE; + bak->en_bss_coex = ad->CommonCfg.bBssCoexEnable; + /* To prevent BSS scan occupy execution time */ + ad->CommonCfg.bBssCoexEnable = FALSE; + bak->bcn_prd = ad->CommonCfg.BeaconPeriod; + /* To disable TBTT interrupt */ + ad->CommonCfg.BeaconPeriod = 0; + + return SERV_STATUS_SUCCESS; +} + +s_int32 net_ad_update_wdev( + u_int8 band_idx, + struct test_wlan_info *winfos, + struct test_configuration *configs) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct wifi_dev *wdev = NULL; +#if defined(DOT11_HE_AX) + struct wifi_dev *wdev_txd = NULL; +#endif + RTMP_ADAPTER *ad = NULL; + u_char ch_band; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + + /* To update wdev setting according to ch_band */ +#if defined(DOT11_HE_AX) + wdev_txd = (struct wifi_dev *)configs->wdev[1]; + + if (!wdev_txd) + goto err; + + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_OFF, + ("%s: wdev_idx(txd)=%d, ch=%d\n", + __func__, wdev_txd->wdev_idx, wdev_txd->channel)); + + HcReleaseRadioForWdev(ad, wdev_txd); +#endif /* DOT11_HE_AX */ + wdev = (struct wifi_dev *)configs->wdev[0]; + + if (!wdev) + goto err; + + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_OFF, + ("%s: wdev_idx=%d, ch=%d\n", + __func__, wdev->wdev_idx, wdev->channel)); + + HcReleaseRadioForWdev(ad, wdev); + +/* #ifdef DBDC_MODE */ +#if 1 + if (IS_MT7915(ad) && IS_TEST_DBDC(winfos)) { + u_int8 rx_sel = (configs->rx_ant & 0x3); + + if (band_idx == DBDC_BAND0) + ad->dbdc_band0_rx_path = rx_sel; + else + ad->dbdc_band1_rx_path = rx_sel; + } else +#endif /* DBDC_MODE */ + { + ad->Antenna.field.TxPath = configs->tx_ant; + ad->Antenna.field.RxPath = configs->rx_ant; + } + + ch_band = configs->ch_band; + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_OFF, + ("%s: ch_band=%d\n", __func__, ch_band)); + + if (ch_band == 0) + wdev->PhyMode = PHYMODE_CAP_24G; + else + wdev->PhyMode = PHYMODE_CAP_5G; +#if defined(DOT11_HE_AX) + if (ch_band == 0) + wdev_txd->PhyMode = PHYMODE_CAP_24G; + else + wdev_txd->PhyMode = PHYMODE_CAP_5G; +#endif + /* + * QA mode used central ch, + * thus wdev ch set as qa mode's control ch of relating bw setting + */ + wdev->channel = configs->ctrl_ch; + wlan_config_set_ch_band(wdev, ch_band); + wlan_config_set_tx_stream(wdev, configs->tx_ant); + wlan_config_set_rx_stream(wdev, configs->rx_ant); + wlan_config_set_ht_bw(wdev, + ((configs->bw > TEST_BW_20) ? HT_BW_40 : HT_BW_20)); + wlan_config_set_ext_cha(wdev, configs->ch_offset); + wlan_config_set_cen_ch_2(wdev, configs->channel_2nd); + if (configs->bw > TEST_BW_5) + wlan_config_set_vht_bw(wdev, + (VHT_BW_80+(configs->bw-TEST_BW_5))); + else + wlan_config_set_vht_bw(wdev, + ((configs->bw > TEST_BW_40) ? + (VHT_BW_80+(configs->bw-BW_80)) : VHT_BW_2040)); +#if defined(DOT11_HE_AX) + if (configs->per_pkt_bw > TEST_BW_80) + wlan_config_set_ap_bw(wdev, VHT_BW_160); + else + wlan_config_set_ap_bw(wdev, configs->per_pkt_bw); + wlan_config_set_ap_cen(wdev, configs->channel-configs->ch_offset); +#endif /* DOT11_HE_AX */ + + if (wdev_attr_update(ad, wdev) != TRUE) { + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_ERROR, + ("%s: error to update wdev\n", __func__)); + goto err; + } + + if (wdev_edca_acquire(ad, wdev) != TRUE) { + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_ERROR, + ("%s: error to acquire edca\n", __func__)); + goto err; + } + +#if defined(DOT11_HE_AX) + wdev_txd->channel = configs->ctrl_ch; + + wlan_config_set_ch_band(wdev_txd, ch_band); + wlan_config_set_tx_stream(wdev_txd, configs->tx_ant); + wlan_config_set_rx_stream(wdev_txd, configs->rx_ant); + wlan_config_set_ht_bw(wdev_txd, + ((configs->bw > TEST_BW_20) ? HT_BW_40 : HT_BW_20)); + wlan_config_set_ext_cha(wdev_txd, configs->ch_offset); + wlan_config_set_cen_ch_2(wdev_txd, configs->channel_2nd); + if (configs->bw > TEST_BW_5) + wlan_config_set_vht_bw(wdev_txd, + (VHT_BW_80+(configs->bw-TEST_BW_5))); + else + wlan_config_set_vht_bw(wdev_txd, + ((configs->bw > TEST_BW_40) ? + (VHT_BW_80+(configs->bw-BW_80)) : VHT_BW_2040)); + if (configs->per_pkt_bw > TEST_BW_80) + wlan_config_set_ap_bw(wdev, VHT_BW_160); + else + wlan_config_set_ap_bw(wdev_txd, configs->per_pkt_bw); + wlan_config_set_ap_cen(wdev_txd, configs->channel-configs->ch_offset); + + if (wdev_attr_update(ad, wdev_txd) != TRUE) { + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_ERROR, + ("%s: error to update wdev\n", __func__)); + goto err; + } + + if (wdev_edca_acquire(ad, wdev_txd) != TRUE) { + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_ERROR, + ("%s: error to acquire edca\n", __func__)); + goto err; + } +#endif + + return ret; + +err: + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_ERROR, + ("%s: updats wdev failed!\n", __func__)); + + return SERV_STATUS_OSAL_NET_FAIL_UPDATE_WDEV; +} + +s_int32 net_ad_init_wdev( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_char band_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct wifi_dev *wdev = NULL; + RTMP_ADAPTER *ad = NULL; + u_char *own_mac_addr = NULL, *bssid = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + + /* To init wdev */ + wdev = (struct wifi_dev *)configs->wdev[0]; + + if (wdev_init(ad, wdev, WDEV_TYPE_SERVICE_TXD, + ad->wdev_list[band_idx]->if_dev, + band_idx, NULL, (void *)ad) != TRUE) + goto err; + + if (!wdev) + return SERV_STATUS_OSAL_NET_INVALID_PARAM; + + if (IS_AXE(ad) || IS_MT7915(ad)) + serv_wdev_ops.ate_tx = net_ad_tx_v2; + + if (wdev_ops_register(wdev, WDEV_TYPE_SERVICE_TXD, &serv_wdev_ops, 0) + != TRUE) + goto err; + + configs->wdev_idx = wdev->wdev_idx; + wdev->channel = configs->channel; + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_OFF, + ("%s: wdev_idx=%d, channel=%d\n", + __func__, wdev->wdev_idx, wdev->channel)); + + if (wdev->channel > 14) + wdev->PhyMode = PHYMODE_CAP_5G; + else + wdev->PhyMode = PHYMODE_CAP_24G; + +#ifdef CONFIG_AP_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_AP(ad) + own_mac_addr = (u_char *)&configs->addr3[0]; + +#endif +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(ad) + own_mac_addr = (u_char *)&configs->addr2[0]; +#endif + sys_ad_move_mem(wdev->if_addr, own_mac_addr, SERV_MAC_ADDR_LEN); + + if (wdev_do_open(wdev) != TRUE) + goto err; + +#ifdef CONFIG_AP_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_AP(ad) + bssid = (u_char *)&configs->addr2[0]; + +#endif +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(ad) + bssid = (u_char *)&configs->addr1[0]; +#endif + sys_ad_move_mem(wdev->bssid, bssid, SERV_MAC_ADDR_LEN); + + if (wifi_sys_linkup(wdev, NULL) != TRUE) + goto err; + +#if defined(DOT11_HE_AX) + wdev = (struct wifi_dev *)configs->wdev[1]; + + if (wdev_init(ad, wdev, WDEV_TYPE_SERVICE_TXC, + ad->wdev_list[band_idx]->if_dev, + band_idx, NULL, (void *)ad) != TRUE) + goto err; + + if (!wdev) + return SERV_STATUS_OSAL_NET_INVALID_PARAM; + + if (IS_AXE(ad) || IS_MT7915(ad)) + serv_wdev_ops.ate_tx = net_ad_tx_v2; + + if (wdev_ops_register(wdev, WDEV_TYPE_SERVICE_TXC, &serv_wdev_ops, 0) + != TRUE) + goto err; + + wdev->channel = configs->channel; + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_OFF, + ("%s: wdev_idx=%d, channel=%d\n", + __func__, wdev->wdev_idx, wdev->channel)); + + if (wdev->channel > 14) + wdev->PhyMode = PHYMODE_CAP_5G; + else + wdev->PhyMode = PHYMODE_CAP_24G; + +#ifdef CONFIG_AP_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_AP(ad) + own_mac_addr = (u_char *)&configs->addr3[0]; + +#endif +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(ad) + own_mac_addr = (u_char *)&configs->addr2[0]; +#endif + own_mac_addr[0] |= 0x2; + sys_ad_move_mem(wdev->if_addr, own_mac_addr, SERV_MAC_ADDR_LEN); + + if (wdev_do_open(wdev) != TRUE) + goto err; + +#ifdef CONFIG_AP_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_AP(ad) + bssid = (u_char *)&configs->addr2[0]; + +#endif +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(ad) + bssid = (u_char *)&configs->addr1[0]; +#endif + bssid[0] |= 0x2; + sys_ad_move_mem(wdev->bssid, bssid, SERV_MAC_ADDR_LEN); + + if (wifi_sys_linkup(wdev, NULL) != TRUE) + goto err; +#endif /* DOT11_HE_AX */ + + return ret; + +err: + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_ERROR, + ("%s: inits wdev failed!\n", __func__)); + + return SERV_STATUS_OSAL_NET_FAIL_INIT_WDEV; +} + +s_int32 net_ad_release_wdev( + struct test_wlan_info *winfos, + struct test_configuration *configs) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct wifi_dev *wdev; + RTMP_ADAPTER *ad = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_TRACE, + ("%s\n", __func__)); + + /* To release wdev */ + wdev = configs->wdev[0]; + + if (!wdev) + goto err; + + if (wifi_sys_linkdown(wdev) != TRUE) { + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_ERROR, + ("%s: linkdown failed!\n", __func__)); + goto err; + } + + if (wdev_do_close(wdev) != TRUE) + goto err; + + if (wdev_deinit(ad, wdev) != TRUE) + goto err; + +#if defined(DOT11_HE_AX) + wdev = configs->wdev[1]; + + if (!wdev) + goto err; + + if (wifi_sys_linkdown(wdev) != TRUE) { + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_ERROR, + ("%s: linkdown failed!\n", __func__)); + goto err; + } + + if (wdev_do_close(wdev) != TRUE) + goto err; + + if (wdev_deinit(ad, wdev) != TRUE) + goto err; +#endif /* DOT11_HE_AX */ + + return ret; + +err: + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_ERROR, + ("%s: releases wdev failed!\n", __func__)); + + return SERV_STATUS_OSAL_NET_FAIL_RELEASE_WDEV; +} + +s_int32 net_ad_alloc_wtbl( + struct test_wlan_info *winfos, + u_char *da, + void *virtual_device, + void **virtual_wtbl) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) { + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_ERROR, + ("%s: invalid adapter!\n", __func__)); + ret = SERV_STATUS_OSAL_NET_INVALID_PAD; + goto err_out; + } + + if (virtual_device == NULL) { + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_ERROR, + ("%s: invalid wdev!\n", __func__)); + ret = SERV_STATUS_OSAL_NET_INVALID_NULL_POINTER; + goto err_out; + } + + *virtual_wtbl = (void *)MacTableInsertEntry(ad, + da, + virtual_device, + ENTRY_ATE, + OPMODE_ATE, + TRUE); + + if (*virtual_wtbl == NULL) + ret = SERV_STATUS_OSAL_NET_FAIL; + +err_out: + return ret; +} + +s_int32 net_ad_free_wtbl( + struct test_wlan_info *winfos, + u_char *da, + void *virtual_wtbl) +{ + RTMP_ADAPTER *ad = NULL; + struct _MAC_TABLE_ENTRY *mac_tbl_entry = NULL; + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + + if (virtual_wtbl) { + mac_tbl_entry = (struct _MAC_TABLE_ENTRY *)virtual_wtbl; + MacTableDeleteEntry(ad, mac_tbl_entry->wcid, da); + } else + return SERV_STATUS_OSAL_NET_INVALID_NULL_POINTER; + + return SERV_STATUS_SUCCESS; +} + +s_int32 net_ad_apply_wtbl( + struct test_wlan_info *winfos, + void *virtual_dev, + void *virtual_wtbl) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + struct serv_chip_cap *chip_cap = NULL; + struct caps_info *cap = NULL; + struct ampdu_caps *ampdu = NULL; + u_short bw_winsiz = 0, tid_idx = 0; + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + + chip_cap = &winfos->chip_cap; + + if (virtual_wtbl) { + struct _MAC_TABLE_ENTRY *entry = NULL; + struct phy_params *phy_info = NULL; + + entry = (struct _MAC_TABLE_ENTRY *)virtual_wtbl; + phy_info = &entry->phy_param; + cap = &entry->cap; + ampdu = &entry->cap.ampdu; + + if (phy_info->phy_mode > MODE_VHT) + entry->MaxHTPhyMode.field.MODE = MODE_VHT; + else + entry->MaxHTPhyMode.field.MODE = phy_info->phy_mode; + + if (phy_info->phy_mode > MODE_OFDM) { + entry->MaxRAmpduFactor = chip_cap->ht_ampdu_exp; + ampdu->max_ht_ampdu_len_exp = chip_cap->ht_ampdu_exp; + } + if (phy_info->phy_mode > MODE_HTGREENFIELD) { + entry->MaxRAmpduFactor = chip_cap->vht_ampdu_exp; + ampdu->max_mpdu_len = chip_cap->max_mpdu_len; + ampdu->max_vht_ampdu_len_exp = chip_cap->vht_ampdu_exp; + } +#if defined(DOT11_HE_AX) + if (phy_info->phy_mode > MODE_VHT) { + cap->modes |= (HE_24G_SUPPORT | HE_5G_SUPPORT); + cap->he_mac_cap |= HE_AMSDU_IN_ACK_EN_AMPDU; + ampdu->max_he_ampdu_len_exp = chip_cap->he_ampdu_exp; + } +#endif + CLIENT_STATUS_SET_FLAG(entry, fCLIENT_STATUS_WMM_CAPABLE); + cap->ch_bw.he_ch_width = BW_80; + + if (wifi_sys_conn_act(virtual_dev, virtual_wtbl) != TRUE) { + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_ERROR, + ("%s(): connect action fail!\n", __func__)); + } + +#if defined(DOT11_VHT_AC) + if (IS_HIF_TYPE(ad, HIF_MT)) + RAInit(ad, entry); +#endif + + if (phy_info->phy_mode <= MODE_VHT) + bw_winsiz = chip_cap->non_he_tx_ba_wsize; +#if defined(DOT11_HE_AX) + else + bw_winsiz = chip_cap->he_tx_ba_wsize; +#endif /* DIT11_HE_AX */ + + for (tid_idx = 0; tid_idx < 8 ; tid_idx++) + AsicUpdateBASession(ad, + entry->wcid, + tid_idx, + 0, + bw_winsiz, + TRUE, + BA_SESSION_ORI, + 0); + +#ifdef RACTRL_FW_OFFLOAD_SUPPORT + if (winfos->wm_fw_info.ra_offload == TRUE) { + CMD_STAREC_AUTO_RATE_UPDATE_T rRaParam; + RA_PHY_CFG_T *rate_cfg = NULL; + u_int8 gi_type = phy_info->gi_type; + u_int8 ltf_type = phy_info->ltf_type; + + entry->bAutoTxRateSwitch = FALSE; + sys_ad_zero_mem(&rRaParam, + sizeof(CMD_STAREC_AUTO_RATE_UPDATE_T)); + rate_cfg = &rRaParam.FixedRateCfg; + rate_cfg->MODE = phy_info->phy_mode; + if (phy_info->phy_mode == TEST_MODE_HE_MU || + phy_info->phy_mode == TEST_MODE_VHT_MIMO) { + /* work-around to prevent TX CCK + * while 5GHz band + */ + rate_cfg->MODE = TEST_MODE_OFDM; + phy_info->rate = 7; + } + rate_cfg->STBC = phy_info->stbc; + if (phy_info->phy_mode < MODE_HE_SU) { + if (phy_info->gi_type) + rate_cfg->ShortGI = BIT(phy_info->bw); + else + rate_cfg->ShortGI = 0; + } +#if defined(DOT11_HE_AX) + else { + switch (phy_info->bw) { + case BW_40: + rate_cfg->ShortGI = (gi_type << 2); + rate_cfg->he_ltf = (ltf_type << 2); + break; + case BW_80: + rate_cfg->ShortGI = (gi_type << 4); + rate_cfg->he_ltf = (ltf_type << 4); + break; + case BW_160: + rate_cfg->ShortGI = (gi_type << 6); + rate_cfg->he_ltf = (ltf_type << 6); + break; + default: + rate_cfg->ShortGI = gi_type; + rate_cfg->he_ltf = ltf_type; + } + } +#endif /* DOT11_HE_AX */ + rate_cfg->BW = phy_info->bw; + if (phy_info->ldpc) { + switch (phy_info->phy_mode) { + case MODE_HTMIX: + case MODE_HTGREENFIELD: + rate_cfg->ldpc = 1; + break; + case MODE_VHT: + rate_cfg->ldpc = 2; + break; +#if defined(DOT11_HE_AX) + case MODE_HE_SU: + case MODE_HE_EXT_SU: + case MODE_HE_TRIG: + case MODE_HE_MU: + rate_cfg->ldpc = 4; + break; +#endif /* DOT11_HE_AX */ + default:/* should not happen */ + rate_cfg->ldpc = 0; + } + } + rate_cfg->MCS = phy_info->rate; + if (phy_info->dcm) + rate_cfg->MCS |= BIT(4); + if (phy_info->su_ext_tone) + rate_cfg->MCS |= BIT(5); + rate_cfg->VhtNss = phy_info->vht_nss; + #if 0 /* ToDO */ + rRaParam.ucShortPreamble = + TESTMODE_GET_PARAM(pAd, + HcGetBandByWdev(virtual_dev), + preamble); + #endif + rRaParam.u4Field = RA_PARAM_FIXED_RATE; + RAParamUpdate(ad, entry, &rRaParam); + } +#endif + } else + ret = SERV_STATUS_OSAL_NET_INVALID_NULL_POINTER; + + return ret; +} + +s_int32 net_ad_match_wtbl( + void *virtual_wtbl, + u_int16 wcid) +{ + struct _MAC_TABLE_ENTRY *mac_tbl_entry = NULL; + /* Get adapter from jedi driver first */ + + mac_tbl_entry = (struct _MAC_TABLE_ENTRY *)virtual_wtbl; + + if (mac_tbl_entry->wcid == wcid) + return TRUE; + + return FALSE; +} + +s_int32 net_ad_set_aid( + void *virtual_wtbl, + u_int16 aid) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct _MAC_TABLE_ENTRY *entry = NULL; + + entry = (struct _MAC_TABLE_ENTRY *)virtual_wtbl; + + if (entry) + entry->Aid = aid; + else + ret = SERV_STATUS_OSAL_NET_INVALID_NULL_POINTER; + + return ret; +} + +s_int32 net_ad_get_wmm_idx( + void *virtual_device, + u_int8 *wmm_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct wifi_dev *wdev = (struct wifi_dev *)virtual_device; + + if (wdev == NULL) { + ret = SERV_STATUS_OSAL_NET_INVALID_NULL_POINTER; + goto err_out; + } + + *wmm_idx = HcGetWmmIdx(NULL, (struct wifi_dev *)virtual_device); + +err_out: + return ret; +} + +s_int32 net_ad_get_band_idx( + void *virtual_device, + u_char *band_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + if (virtual_device == NULL) + ret = SERV_STATUS_OSAL_NET_INVALID_NULL_POINTER; + else { + struct wifi_dev *wdev = (struct wifi_dev *)virtual_device; + + *band_idx = HcGetBandByWdev(wdev); + } + + return ret; +} + +s_int32 net_ad_get_omac_idx( + struct test_wlan_info *winfos, + void *virtual_device, + u_char *omac_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) { + ret = SERV_STATUS_OSAL_NET_INVALID_PAD; + goto err_out; + } + + if (virtual_device == NULL) + ret = SERV_STATUS_OSAL_NET_INVALID_NULL_POINTER; + else { + struct wifi_dev *wdev = (struct wifi_dev *)virtual_device; + + *omac_idx = HcGetOmacIdx(ad, wdev); + } + +err_out: + return ret; +} + +s_int32 net_ad_fill_phy_info( + void *virtual_wtbl, + struct test_tx_info *tx_info) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct _MAC_TABLE_ENTRY *entry = NULL; + struct phy_params *phy_info = NULL; + + entry = (struct _MAC_TABLE_ENTRY *)virtual_wtbl; + phy_info = &entry->phy_param; + + sys_ad_zero_mem(phy_info, sizeof(*phy_info)); + + phy_info->phy_mode = tx_info->tx_mode; +#ifdef TXBF_SUPPORT + phy_info->tx_ibf = tx_info->ibf; + phy_info->tx_ebf = tx_info->ebf; +#endif + phy_info->stbc = tx_info->stbc; + phy_info->ldpc = tx_info->ldpc; + phy_info->bw = tx_info->bw; + phy_info->vht_nss = tx_info->nss; + phy_info->gi_type = tx_info->gi; + phy_info->ltf_type = tx_info->ltf; + +#if defined(DOT11_HE_AX) + if (phy_info->phy_mode > TEST_MODE_VHT) { + phy_info->rate = (tx_info->mcs & 0xf); + /* b'5 for DCM */ + phy_info->dcm = (tx_info->mcs & BIT(5)) ? TRUE : FALSE; + + if (phy_info->phy_mode == TEST_MODE_HE_ER) { + /* b'4 for tone*/ + if (tx_info->mcs & BIT(4)) + phy_info->su_ext_tone = TRUE; + else + phy_info->su_ext_tone = FALSE; + } + } else +#endif /* DOT11_HE_AX */ + { + phy_info->rate = (tx_info->mcs & 0x1f); + } + + return ret; +} + +s_int32 net_ad_get_speidx( + struct test_wlan_info *winfos, + u_int16 ant_sel, + u_int8 *spe_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + u_int8 map_idx = 0; + struct serv_spe_map *spe_map = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) { + ret = SERV_STATUS_OSAL_NET_INVALID_PAD; + goto err_out; + } + + *spe_idx = 0; + spe_map = winfos->chip_cap.spe_map_list.spe_map; + for (map_idx = 0; + map_idx < winfos->chip_cap.spe_map_list.size; + map_idx++) { + if (ant_sel == spe_map[map_idx].ant_sel) { + *spe_idx = spe_map[map_idx].spe_idx; + break; + } + } + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_TRACE, + ("%s spe idx=%d(map_idx:%d/%d)\n", + __func__, *spe_idx, map_idx, + winfos->chip_cap.spe_map_list.size)); + +err_out: + return ret; +} + + +s_int32 net_ad_fill_spe_antid( + struct test_wlan_info *winfos, + void *virtual_wtbl, + u_int8 spe_idx, + u_int8 ant_pri) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + struct _MAC_TABLE_ENTRY *entry = NULL; + struct phy_params *phy_info = NULL; +#ifdef RACTRL_FW_OFFLOAD_SUPPORT + CMD_STAREC_AUTO_RATE_UPDATE_T rRaParam; +#endif /* RACTRL_FW_OFFLOAD_SUPPORT */ + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) { + ret = SERV_STATUS_OSAL_NET_INVALID_PAD; + goto err_out; + } + + if (virtual_wtbl == NULL) { + ret = SERV_STATUS_OSAL_NET_INVALID_NULL_POINTER; + goto err_out; + } + + entry = (struct _MAC_TABLE_ENTRY *)virtual_wtbl; + phy_info = &entry->phy_param; + + phy_info->spe_idx = spe_idx; + phy_info->ant_pri = ant_pri; + +#ifdef RACTRL_FW_OFFLOAD_SUPPORT + sys_ad_zero_mem(&rRaParam, sizeof(CMD_STAREC_AUTO_RATE_UPDATE_T)); + + rRaParam.ucSpeEn = spe_idx; + rRaParam.u4Field = RA_PARAM_SPE_UPDATE; + RAParamUpdate(ad, entry, &rRaParam); +#endif /* RACTRL_FW_OFFLOAD_SUPPORT */ + +err_out: + return ret; +} + + +s_int32 net_ad_fill_pkt( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_char *buf, u_int32 txlen, u_int32 hlen) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + u_char *tmac_info, *pheader, *payload; + u_char *addr1, *addr2, *addr3, *template; + u_int8 tx_hw_hdr_len; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + + tx_hw_hdr_len = winfos->chip_cap.tx_wi_size; + addr1 = configs->addr1[0]; + addr2 = configs->addr2[0]; + addr3 = configs->addr3[0]; + template = configs->template_frame; + + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_TRACE, + ("%s(wcid:%d):: DA: %02x:%02x:%02x:%02x:%02x:%02x\n\t", + __func__, configs->wcid_ref, SERV_PRINT_MAC(addr1))); + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_TRACE, + ("SA: %02x:%02x:%02x:%02x:%02x:%02x\n\t", + SERV_PRINT_MAC(addr2))); + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_TRACE, + ("BSSID: %02x:%02x:%02x:%02x:%02x:%02x\n", + SERV_PRINT_MAC(addr3))); + + /* Error check for txlen */ + if (txlen == 0) { + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_ERROR, + ("%s: tx length can't be 0!!\n", __func__)); + + return SERV_STATUS_OSAL_NET_INVALID_LEN; + } + + tmac_info = buf; + pheader = (buf + tx_hw_hdr_len); + payload = (pheader + hlen); + sys_ad_zero_mem(buf, TEST_PKT_LEN); + + /* TODO: factor out here for BF */ +#if 0 +#ifdef TXBF_SUPPORT + { + UCHAR iTxBf = TESTMODE_GET_PARAM(pAd, band_idx, ibf); + UCHAR eTxBf = TESTMODE_GET_PARAM(pAd, band_idx, ebf); + + /* Use wcid 1~4 */ + if (iTxBf || eTxBf) { + if ((ATECtrl->wcid_ref > ATE_BFMU_NUM) + || (ATECtrl->wcid_ref < 1)) + ATECtrl->wcid_ref = ATE_BF_WCID; + + addr1 = ATECtrl->pfmu_info[ATECtrl->wcid_ref - 1].addr; + } + + SERV_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s:: DA: %02x:%02x:%02x:%02x:%02x:%02x, wcid=%u\n", + __func__, PRINT_MAC(addr1), ATECtrl->wcid_ref)); + } +#endif +#endif + + sys_ad_move_mem(pheader, template, hlen); + sys_ad_move_mem(pheader + 4, addr1, SERV_MAC_ADDR_LEN); + sys_ad_move_mem(pheader + 10, addr2, SERV_MAC_ADDR_LEN); + sys_ad_move_mem(pheader + 16, addr3, SERV_MAC_ADDR_LEN); + + ret = net_ad_init_payload(winfos, configs, payload, txlen - hlen); + if (ret) + return ret; + + /* TODO: factor out here for log dump */ +#if 0 +#if !defined(COMPOS_TESTMODE_WIN) + + if (ATECtrl->en_log & fATE_LOG_TXDUMP) { + INT i = 0; + PHEADER_802_11 hdr = (HEADER_802_11 *) pheader; + + SERV_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("[TXCONTENT DUMP START]\n")); + asic_dump_tmac_info(pAd, tmac_info); + SERV_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, + DBG_LVL_OFF, ("[TXD RAW]: ")); + + for (i = 0; i < tx_hw_hdr_len; i++) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%04x", tmac_info[i])); + + SERV_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\nADDR1: %02x:%02x:%02x:%02x:%02x:%02x\n", + PRINT_MAC(hdr->Addr1))); + SERV_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("ADDR2: %02x:%02x:%02x:%02x:%02x:%02x\n", + PRINT_MAC(hdr->Addr2))); + SERV_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("ADDR3: %02x:%02x:%02x:%02x:%02x:%02x\n", + PRINT_MAC(hdr->Addr3))); + SERV_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("FC: %04x\n", *(UINT16 *) (&hdr->FC))); + SERV_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tFrom DS: %x\n", hdr->FC.FrDs)); + SERV_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tTo DS: %x\n", hdr->FC.ToDs)); + SERV_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("[CONTENT RAW]: ")); + + for (i = 0; i < (txlen - hlen); i++) + SERV_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%02x", payload[i])); + + SERV_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\n[TXCONTENT DUMP END]\n")); + } +#endif /* !defined(COMPOS_TESTMODE_WIN) */ +#endif + +#ifdef RT_BIG_ENDIAN + RTMPFrameEndianChange(ad, (u_char *) pheader, DIR_WRITE, FALSE); +#ifdef MT_MAC + if (IS_HIF_TYPE(ad, HIF_MT)) + MTMacInfoEndianChange(ad, tmac_info, TYPE_TMACINFO, + sizeof(TMAC_TXD_L)); +#endif +#endif + + return ret; +} + +s_int32 net_ad_alloc_pkt( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_int32 mpdu_length, + void **pkt_skb) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + u_char *src_buff; + u_short qid; + u_int8 tx_hw_hdr_len; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + + src_buff = configs->test_pkt; + qid = configs->ac_idx; + tx_hw_hdr_len = winfos->chip_cap.tx_hw_hdr_len; + + if (!src_buff) { + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_ERROR, + ("%s: invalid test_pkt\n", __func__)); + goto err_out; + } + + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_TRACE, + ("%s: test_pkt=%p, ring idx=%u\n", __func__, src_buff, qid)); + + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_TRACE, + ("%s: txlen=%d, tx_hw_hdr_len=%d, total=%d\n", + __func__, mpdu_length, tx_hw_hdr_len, + mpdu_length + tx_hw_hdr_len)); + + ret = RTMPAllocateNdisPacket(ad, + pkt_skb, + NULL, + 0, + src_buff, + mpdu_length + tx_hw_hdr_len); + + if (ret != NDIS_STATUS_SUCCESS) { + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_ERROR, + ("%s: AllocateNdisPacket fail\n", __func__)); + goto err_out; + } + +err_out: + return ret; +} + +s_int32 net_ad_free_pkt( + struct test_wlan_info *winfos, + void *pkt_skb) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + + RTMPFreeNdisPacket(ad, pkt_skb); + + return ret; +} + +s_int32 net_ad_enq_pkt( + struct test_wlan_info *winfos, + u_short q_idx, + void *virtual_wtbl, + void *virtual_device, + void *pkt_skb) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + PNDIS_PACKET pkt = NULL; + struct sk_buff *skb = NULL, *skb2 = NULL; + struct wifi_dev *wdev = (struct wifi_dev *)virtual_device; + struct _MAC_TABLE_ENTRY *entry = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) { + ret = SERV_STATUS_OSAL_NET_INVALID_PAD; + goto err_out; + } + + if (virtual_device) + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_TRACE, + ("%s: wdev_idx=%d, q_idx=%d, pkt_va=%p\n", + __func__, wdev->wdev_idx, q_idx, pkt_skb)); + else { + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_ERROR, + ("%s: invalid wdev(%p)!\n", __func__, wdev)); + ret = SERV_STATUS_OSAL_NET_INVALID_NULL_POINTER; + goto err_out; + } + + if (virtual_wtbl) + entry = (struct _MAC_TABLE_ENTRY *)virtual_wtbl; + else { + ret = SERV_STATUS_OSAL_NET_INVALID_NULL_POINTER; + goto err_out; + } + + if (pkt_skb) { + skb = (struct sk_buff *)pkt_skb; + SERV_OS_PKT_CLONE(skb, skb2, GFP_ATOMIC); + + if (skb2 == NULL) { + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_ERROR, + ("%s: clone packet fail\n", __func__)); + ret = SERV_STATUS_OSAL_NET_FAIL; + goto err_out; + } else { + pkt = (PNDIS_PACKET)skb2; + RTMP_SET_PACKET_WCID(pkt, entry->wcid); + RTMP_SET_PACKET_WDEV(pkt, wdev->wdev_idx); + + RTMP_SET_PACKET_TXTYPE(pkt, TX_ATE_FRAME); + + if (q_idx > 0) { + RTMP_SET_PACKET_QUEIDX(pkt, QID_AC_BE); + RTMP_SET_PACKET_TYPE(pkt, TX_DATA); + } else { + RTMP_SET_PACKET_QUEIDX(pkt, 0); + RTMP_SET_PACKET_TYPE(pkt, TX_MGMT); + } + } + + ret = send_mlme_pkt(ad, pkt, wdev, q_idx, FALSE); + } + + if (ret) + ret = SERV_STATUS_OSAL_NET_FAIL; + +err_out: + return ret; +} + +s_int32 net_ad_trigger_tx( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_int8 band_idx, + void *pkt) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + u_int32 txdone_cnt = 0, tx_cnt = 0, op_mode = 0; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + + if (band_idx >= TEST_DBDC_BAND_NUM) { + ret = SERV_STATUS_OSAL_NET_INVALID_BANDIDX; + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_ERROR, + ("%s: wrong band_idx %u, ret=0x%08x\n", + __func__, band_idx, ret)); + goto done; + } + + tx_cnt = configs->tx_stat.tx_cnt; + op_mode = configs->op_mode; + + /* Do not count in packet number when tx is not in start stage */ + if (!(op_mode & OP_MODE_TXFRAME)) + goto done; + + /* Triggered when RX tasklet free token */ + if (pkt) { + ad->RalinkCounters.KickTxCount++; + txdone_cnt++; + } + + if (configs->tx_strategy == TEST_TX_STRA_THREAD) + net_ad_thread_proceed_tx(winfos, band_idx); + else if (configs->tx_strategy == TEST_TX_STRA_TASKLET) { + if ((op_mode & OP_MODE_TXFRAME) && (txdone_cnt < tx_cnt)) + ret = net_ad_enq_pkt(winfos, + configs->ac_idx, + configs->stack.virtual_wtbl[0], + configs->stack.virtual_device[0], + configs->stack.pkt_skb[0]); + else if ((op_mode & OP_MODE_TXFRAME) + && (txdone_cnt == tx_cnt)) { + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_TRACE, + ("%s: all tx is done\n", __func__)); + + if (op_mode & fTEST_MPS) { + SERV_OS_COMPLETION *tx_wait; + + tx_wait = &configs->tx_wait; + SERV_OS_COMPLETE(tx_wait); + SERV_LOG(SERV_DBG_CAT_ADAPT, + SERV_DBG_LVL_TRACE, + ("%s: finish one MPS item\n", + __func__)); + } + + /* Tx status enters idle mode */ + configs->tx_status = 0; + } else if (!(op_mode & OP_MODE_TXFRAME)) { + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_TRACE, + ("%s: stop tx bottom is pressed\n", + __func__)); + + if (op_mode & fTEST_MPS) { + SERV_OS_COMPLETION *tx_wait; + + tx_wait = &configs->tx_wait; + op_mode &= ~fTEST_MPS; + configs->op_mode = op_mode; + SERV_OS_COMPLETE(tx_wait); + SERV_LOG(SERV_DBG_CAT_ADAPT, + SERV_DBG_LVL_TRACE, + ("%s: MPS stop\n", __func__)); + } + } else { + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_WARN, + ("%s: do not match any condition, ", + __func__)); + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_WARN, + ("op_mode:0x%x, tx_cnt:%u, txdone_cnt:%u\n", + op_mode, tx_cnt, txdone_cnt)); + } + } else { + ret = SERV_STATUS_OSAL_NET_INVALID_PARAM; + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_ERROR, + ("%s: wrong tx strategy=%d, ret=0x%08x\n", + __func__, configs->tx_strategy, ret)); + goto done; + } + +done: + return ret; +} + +s_int32 net_ad_rx_done_handle( + struct test_wlan_info *winfos, + void *rx_blk) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + struct service_test *serv_test; + RX_BLK *rxblk = (RX_BLK *)rx_blk; + u_char band_idx; + u_int32 chfreq0 = 0, chfreq1 = 0; + u_int32 bn0_cr_addr = RMAC_CHFREQ0; +/* #ifdef DBDC_MODE */ +#if 1 + u_int32 bn1_cr_addr = RMAC_CHFREQ1; +#endif /* DBDC_MODE */ + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + + if (IS_MT7915(ad)) + band_idx = rxblk->band; + else { + MAC_IO_READ32(ad->hdev_ctrl, bn0_cr_addr, &chfreq0); +/* #ifdef DBDC_MODE */ +#if 1 + MAC_IO_READ32(ad->hdev_ctrl, bn1_cr_addr, &chfreq1); +#endif /* DBDC_MODE */ + + /* Note: shall not use ad here */ + serv_test = (struct service_test *)ad->serv.serv_handle; + + /* RX packet counter calculate by chfreq of RXD */ + if (rxblk->channel_freq == chfreq0) + band_idx = TEST_DBDC_BAND0; +/* #ifdef DBDC_MODE */ +#if 1 + else if (rxblk->channel_freq == chfreq1) + band_idx = TEST_DBDC_BAND1; +#endif /* DBDC_MODE */ + else { + SERV_LOG(SERV_DBG_CAT_ALL, SERV_DBG_LVL_ERROR, + ("%s: wrong chfreq!!\n" + "\tRXD.ch_freq=%u, chfreq0=%u, chfreq1=%u\n", + __func__, rxblk->channel_freq, + chfreq0, chfreq1)); + return SERV_STATUS_OSAL_NET_INVALID_PARAM; + } + } + + return ret; +} + +s_int32 net_ad_set_band_mode( + struct test_wlan_info *winfos, + struct test_band_state *band_state) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + + if (band_state->band_mode == TEST_BAND_MODE_SINGLE) { + if (band_state->band_type == TEST_BAND_TYPE_A) + Set_WirelessMode_Proc(ad, "14"); + else if (band_state->band_type == TEST_BAND_TYPE_G) + Set_WirelessMode_Proc(ad, "9"); + else + ret = SERV_STATUS_OSAL_NET_INVALID_PARAM; + } + + return ret; +} + +s_int32 net_ad_set_txpwr_sku( + struct test_wlan_info *winfos, + u_char sku_ctrl, u_char band_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + + ret = MtCmdTxPowerSKUCtrl(ad, sku_ctrl, band_idx); + if (ret) + ret = SERV_STATUS_OSAL_NET_FAIL_SEND_FWCMD; + + return ret; +} + +s_int32 net_ad_set_txpwr_power_drop( + struct test_wlan_info *winfos, + u_char power_drop, u_char band_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + + ret = MtCmdTxPowerDropCtrl(ad, power_drop, band_idx); + if (ret) + ret = SERV_STATUS_OSAL_NET_FAIL_SEND_FWCMD; + + return ret; +} + +s_int32 net_ad_set_txpwr_percentage( + struct test_wlan_info *winfos, + u_char percentage_ctrl, u_char band_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + + ret = MtCmdTxPowerPercentCtrl(ad, percentage_ctrl, band_idx); + if (ret) + ret = SERV_STATUS_OSAL_NET_FAIL_SEND_FWCMD; + + return ret; +} + +s_int32 net_ad_set_txpwr_backoff( + struct test_wlan_info *winfos, + u_char backoff_ctrl, u_char band_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + + ret = MtCmdTxBfBackoffCtrl(ad, backoff_ctrl, band_idx); + if (ret) + ret = SERV_STATUS_OSAL_NET_FAIL_SEND_FWCMD; + + return ret; +} + +s_int32 net_ad_init_txpwr( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_char band_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + if (band_idx >= TEST_DBDC_BAND_NUM) + return SERV_STATUS_OSAL_NET_INVALID_BANDIDX; + + /* Disable tx power related function for test mode */ + ret = net_ad_set_txpwr_sku(winfos, configs->tx_pwr_sku_en, band_idx); + if (ret) + goto error; + + ret = net_ad_set_txpwr_power_drop( + winfos, configs->tx_pwr_percentage_level, band_idx); + if (ret) + goto error; + + ret = net_ad_set_txpwr_percentage( + winfos, configs->tx_pwr_percentage_en, band_idx); + if (ret) + goto error; + + ret = net_ad_set_txpwr_backoff( + winfos, configs->tx_pwr_backoff_en, band_idx); + if (ret) + goto error; + + return ret; + +error: + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_ERROR, + ("%s: engine init tx power fail, err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 net_ad_handle_mcs32( + struct test_wlan_info *winfos, + void *virtual_wtbl, u_int8 bw) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + union WTBL_DW5 wtbl_txcap; + u_int32 dw_mask = 0; + struct _MAC_TABLE_ENTRY *entry = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + + if (entry == NULL) { + ret = SERV_STATUS_OSAL_NET_INVALID_NULL_POINTER; + goto err_out; + } else + entry = (struct _MAC_TABLE_ENTRY *)virtual_wtbl; + + dw_mask = ~(3 << 12); /* only update fcap bit[13:12] */ + wtbl_txcap.field.fcap = bw; + + /* WTBLDW5 */ + ret = WtblDwSet(ad, entry->wcid, 1, 5, dw_mask, wtbl_txcap.word); + if (ret) + ret = SERV_STATUS_OSAL_NET_FAIL_SEND_FWCMD; + +err_out: + return ret; +} + +s_int32 net_ad_cfg_wtbl( + struct test_wlan_info *winfos, + struct test_configuration *configs +) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + struct _RTMP_CHIP_CAP *cap = NULL; + struct _EXT_CMD_ATE_TEST_MODE_T param; + struct tx_time_param *tx_time_param; + P_HT_CAP_T wtbl_ht_cap; + P_VHT_CAP_T wtbl_vht_cap; + P_ANT_CAP_T wtbl_ant_cap; + P_BA_CAP_T wtbl_ba_cap; + P_RATE_CAP_T wtbl_rate_cap; + u_int8 need_qos, need_amsdu, need_ampdu; + u_char tx_mode, mcs, nss, bw, sgi, stbc, ldpc, preamble, u4Stbc; + u_int32 ant_sel = 0; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + + cap = hc_get_chip_cap(ad->hdev_ctrl); + tx_time_param = &configs->tx_time_param; + wtbl_ht_cap = ¶m.Data.rAteSetAmpduWtbl.rWtblHt; + wtbl_vht_cap = ¶m.Data.rAteSetAmpduWtbl.rWtblVht; + wtbl_ant_cap = ¶m.Data.rAteSetAmpduWtbl.rWtblAnt; + wtbl_ba_cap = ¶m.Data.rAteSetAmpduWtbl.rWtblBa; + wtbl_rate_cap = ¶m.Data.rAteSetAmpduWtbl.rWtblRate; + + need_qos = tx_time_param->pkt_need_qos; + need_amsdu = tx_time_param->pkt_need_amsdu; + need_ampdu = tx_time_param->pkt_need_ampdu; + tx_mode = configs->tx_mode; + mcs = configs->mcs; + nss = configs->nss; + bw = configs->bw; + sgi = configs->sgi; + stbc = configs->stbc; + ldpc = configs->ldpc; + ant_sel = configs->tx_ant; + preamble = configs->preamble; + + sys_ad_zero_mem(¶m, sizeof(param)); + param.ucAteTestModeEn = TRUE; + param.ucAteIdx = ENUM_ATE_SET_AMPDU_WTBL; + + switch (tx_mode) { + case TEST_MODE_HTMIX: + case TEST_MODE_HTGREENFIELD: + wtbl_ht_cap->fgIsHT = TRUE; + wtbl_ht_cap->fgLDPC = ldpc; + + if (cap) + wtbl_ht_cap->ucAmpduFactor + = winfos->chip_cap.ht_ampdu_exp; + else + wtbl_ht_cap->ucAmpduFactor = 3; + + break; + + case TEST_MODE_VHT: + wtbl_ht_cap->fgIsHT = 1; + wtbl_vht_cap->fgIsVHT = 1; + wtbl_vht_cap->fgVhtLDPC = ldpc; + + if (cap) + wtbl_ht_cap->ucAmpduFactor + = winfos->chip_cap.vht_ampdu_exp; + else + wtbl_ht_cap->ucAmpduFactor = 7; + + break; + + default: + wtbl_ht_cap->fgIsHT = 0; + wtbl_vht_cap->fgIsVHT = 0; + break; + } + + if (need_ampdu) { + if (ant_sel & TEST_ANT_USER_SEL) { + ant_sel &= ~TEST_ANT_USER_SEL; + } else { + s_int32 map_idx = 0; + s_int32 map_idx_len = sizeof(test_ant_to_spe_idx_map) + / sizeof(test_ant_to_spe_idx_map[0]); + + for (map_idx = 0; map_idx < map_idx_len; map_idx++) { + if (ant_sel == + test_ant_to_spe_idx_map[map_idx].ant_sel) + break; + } + if (map_idx == map_idx_len) + ant_sel = 0; + else + ant_sel + = test_ant_to_spe_idx_map[map_idx].spe_idx; + } + + wtbl_ant_cap->ucSpe = (ant_sel & 0x1F); + wtbl_ant_cap->AntIDConfig.ucANTIDSts0 = ant_sel; + wtbl_ant_cap->AntIDConfig.ucANTIDSts1 = ant_sel; + wtbl_ant_cap->AntIDConfig.ucANTIDSts2 = ant_sel; + wtbl_ant_cap->AntIDConfig.ucANTIDSts3 = ant_sel; + + wtbl_ba_cap->ucBaEn = 1; + wtbl_ba_cap->ucBaSize = 7; + param.Data.rAteSetAmpduWtbl.ucIPsm = 1; + } + + wtbl_rate_cap->ucFcap = bw; + + if (sgi) { + switch (bw) { + case TEST_BW_20: + wtbl_rate_cap->fgG2 = TRUE; + break; + + case TEST_BW_40: + wtbl_rate_cap->fgG4 = TRUE; + break; + + case TEST_BW_80: + wtbl_rate_cap->fgG8 = TRUE; + break; + + case TEST_BW_160C: + wtbl_rate_cap->fgG16 = TRUE; + break; + + default: + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_OFF, + ("%s: can't find such bw, use default\n", + __func__)); + break; + } + } + + u4Stbc = raStbcSettingCheck(stbc, tx_mode, mcs, nss, 0, 0); + + wtbl_rate_cap->ucStbc = u4Stbc; + wtbl_rate_cap->ucMode = tx_mode; + wtbl_rate_cap->ucSgi = sgi; + wtbl_rate_cap->ucBw = bw; + wtbl_rate_cap->ucNss = nss; + wtbl_rate_cap->ucPreamble = preamble; + wtbl_rate_cap->ucLdpc = ldpc; + wtbl_rate_cap->au2RateCode = mcs; + + if (need_qos) + param.Data.rAteSetAmpduWtbl.ucQos = 1; + +#ifdef CONFIG_HW_HAL_OFFLOAD + ret = MtCmdATETest(ad, ¶m); +#endif + + return ret; +} + +s_int32 net_ad_set_wmm_param_by_qid( + u_char wmm_idx, + u_int8 q_idx, + struct test_wlan_info *winfos, + struct test_configuration *configs) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + struct ipg_param *ipg_param; + u_int16 slot_time, sifs_time, cw; + u_int8 ac_num, aifsn; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + + ipg_param = &configs->ipg_param; + + if (wmm_idx > 3) { + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_ERROR, + ("%s: invalid wmm_idx=%d, ", + __func__, wmm_idx)); + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_ERROR, + ("reset to 0xff!\n")); + wmm_idx = 0xFF; + } + + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_TRACE, + ("%s: wmm_idx=%d\n", __func__, wmm_idx)); + + if ((q_idx != QID_AC_BE) + && (q_idx != TxQ_IDX_ALTX0) + && (q_idx != TxQ_IDX_ALTX1)) { + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_ERROR, + ("%s: impossible!\n", __func__)); + return SERV_STATUS_OSAL_NET_INVALID_PARAM; + } + + slot_time = ipg_param->slot_time; + sifs_time = ipg_param->sifs_time; + ac_num = q_idx; + aifsn = ipg_param->aifsn; + cw = ipg_param->cw; + ret = AsicSetWmmParam(ad, wmm_idx, + (u_int32) ac_num, WMM_PARAM_AIFSN, + (u_int32) aifsn); + if (ret) + return ret; + + ret = AsicSetWmmParam(ad, wmm_idx, + (u_int32) ac_num, WMM_PARAM_CWMIN, + (u_int32) cw); + if (ret) + return ret; + + ret = AsicSetWmmParam(ad, wmm_idx, + (u_int32) ac_num, WMM_PARAM_CWMAX, + (u_int32) cw); + + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_TRACE, + ("%s: qid=%d, slot_time=%d, sifs_time=%d, ", + __func__, q_idx, slot_time, sifs_time)); + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_TRACE, + ("ac_num=%d, aifsn=%d, cw=%d\n", ac_num, aifsn, cw)); + + return ret; +} + +s_int32 net_ad_clean_sta_q( + struct test_wlan_info *winfos, u_char wcid) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + struct qm_ops *ops = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + + ops = ad->qm_ops; + + if (ops->sta_clean_queue) { + ret = ops->sta_clean_queue(ad, wcid); + if (ret) + ret = SERV_STATUS_OSAL_NET_FAIL_SEND_FWCMD; + } + + return ret; +} + +s_int32 net_ad_set_auto_resp( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_char band_idx, u_char mode) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + u_char *sa = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + +#ifdef CONFIG_AP_SUPPORT + sa = configs->addr3[0]; +#endif +#ifdef CONFIG_STA_SUPPORT + sa = configs->addr2[0]; +#endif + + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_TRACE, + ("%s\n", __func__)); + + if (mode) { + if (sa) + sys_ad_move_mem(sa, &configs->own_mac, + SERV_MAC_ADDR_LEN); + + AsicDevInfoUpdate(ad, 0x0, (u_int8 *)&configs->own_mac, + band_idx, TRUE, DEVINFO_ACTIVE_FEATURE); + } else { + AsicDevInfoUpdate(ad, 0x0, (u_int8 *)ad->CurrentAddress, + band_idx, TRUE, DEVINFO_ACTIVE_FEATURE); + } + + return ret; +} + +s_int32 net_ad_set_low_power( + struct test_wlan_info *winfos, u_int32 control) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + + if (control) + MlmeLpEnter(ad); + else + MlmeLpExit(ad); + + return ret; +} + +s_int32 net_ad_read_mac_bbp_reg( + struct test_wlan_info *winfos, + struct test_register *regs) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + + RTMP_IO_READ32(ad->hdev_ctrl, regs->cr_addr, regs->cr_val); + + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_TRACE, + ("%s: cr_addr=0x%08x, cr_val=0x%08x\n", + __func__, regs->cr_addr, *regs->cr_val)); + + return ret; +} + +s_int32 net_ad_write_mac_bbp_reg( + struct test_wlan_info *winfos, + struct test_register *regs) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + + RTMP_IO_WRITE32(ad->hdev_ctrl, regs->cr_addr, *regs->cr_val); + + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_TRACE, + ("%s: cr_addr=0x%08x, cr_val=0x%08x\n", + __func__, regs->cr_addr, *regs->cr_val)); + + return ret; +} + +s_int32 net_ad_read_bulk_mac_bbp_reg( + struct test_wlan_info *winfos, + struct test_configuration *configs, + struct test_register *regs) +{ +#define REG_BLOCK_SIZE 128 + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + u_int32 reg_seq, addr, reg_total, value; + u_char offset_byte = 0x4; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + + addr = regs->cr_addr; + reg_total = regs->cr_num; + + for (reg_seq = 0; reg_seq < reg_total; reg_seq++) { + RTMP_IO_READ32(ad->hdev_ctrl, + addr, + &value); + + sys_ad_move_mem(regs->cr_val+reg_seq, + &value, sizeof(value)); + addr += offset_byte; + } + + return ret; +} + +s_int32 net_ad_read_bulk_rf_reg( + struct test_wlan_info *winfos, + struct test_register *regs) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + u_int32 idx, addr, value; + u_int32 *dst; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + + for (idx = 0; idx < regs->cr_num; idx++) { + addr = regs->cr_addr + (idx << 2); + dst = regs->cr_val + idx; + ret = MtCmdRFRegAccessRead(ad, regs->wf_sel, addr, &value); + if (ret) { + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_ERROR, + ("wf_sel=%d, cr_addr=0x%08x, ", + regs->wf_sel, addr)); + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_ERROR, + ("cr_val=0x%08x fail\n", value)); + break; + } + + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_TRACE, + ("%s: wf_sel=%d, cr_addr=0x%08x, cr_val=0x%08x\n", + __func__, regs->wf_sel, addr, value)); + + sys_ad_move_mem(dst, &value, sizeof(value)); + } + + return ret; +} + +s_int32 net_ad_write_bulk_rf_reg( + struct test_wlan_info *winfos, + struct test_register *regs) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + u_int32 idx, addr, value; + u_int32 *src; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + + for (idx = 0; idx < regs->cr_num; idx++) { + addr = regs->cr_addr + (idx << 2); + src = regs->cr_val + idx; + sys_ad_move_mem(&value, src, sizeof(value)); + + ret = MtCmdRFRegAccessWrite(ad, regs->wf_sel, addr, value); + if (ret) { + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_ERROR, + ("wf_sel=%d, cr_addr=0x%08x, ", + regs->wf_sel, addr)); + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_ERROR, + ("cr_val=0x%08x fail\n", value)); + break; + } + + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_TRACE, + ("%s: wf_sel=%d, cr_addr=0x%08x, cr_val=0x%08x\n", + __func__, regs->wf_sel, addr, value)); + } + + return ret; +} + +void net_ad_read_ca53_reg(struct test_register *regs) +{ + u_long offset; + + regs->cr_addr = (u_long)ioremap(regs->cr_addr, CA53_GPIO_REMAP_SIZE); + sys_ad_move_mem((u_char *)&offset, (u_char *)®s->cr_addr, + sizeof(u_long)); + RTMP_SYS_IO_READ32(offset, regs->cr_val); + iounmap((void *)offset); +} + +void net_ad_write_ca53_reg(struct test_register *regs) +{ + u_long offset; + + regs->cr_addr = (u_long)ioremap(regs->cr_addr, CA53_GPIO_REMAP_SIZE); + sys_ad_move_mem((u_char *)&offset, (u_char *)®s->cr_addr, + sizeof(u_long)); + RTMP_SYS_IO_WRITE32(offset, *regs->cr_val); + iounmap((void *)offset); +} + +s_int32 net_ad_read_write_eeprom( + struct test_wlan_info *winfos, + struct test_eeprom *eprms, + boolean is_read) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + u_int16 value; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + + if (is_read) { + RT28xx_EEPROM_READ16(ad, eprms->offset, value); + sys_ad_move_mem(eprms->value, &value, sizeof(value)); + } else + RT28xx_EEPROM_WRITE16(ad, eprms->offset, *eprms->value); + + return ret; +} + +s_int32 net_ad_read_write_bulk_eeprom( + struct test_wlan_info *winfos, + struct test_eeprom *eprms, + boolean is_read) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + u_int16 offset, length, value, eeprom_size = 0; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + + eeprom_size = winfos->chip_cap.efuse_size; + if (is_read) { + RTMP_OS_NETDEV_STOP_QUEUE(ad->net_dev); + for (offset = 0 ; offset < (eeprom_size >> 1) ; offset++) { + RT28xx_EEPROM_READ16(ad, (offset << 1), value); + eprms->value[offset] = value; + } + + RTMP_OS_NETDEV_START_QUEUE(ad->net_dev); + } else { + offset = eprms->offset; + length = eprms->length; + +#if defined(RTMP_FLASH_SUPPORT) + + if (length == 16) + sys_ad_move_mem(ad->EEPROMImage + offset, + eprms->value + offset, length); + + else if (length == eeprom_size) + rtmp_ee_flash_write_all(ad); + + if (length != 16) +#endif /* RTMP_FLASH_SUPPORT */ + { + if ((offset + length) <= eeprom_size) { + u_int16 val_seq = 0; + + for (val_seq = 0; + val_seq < (length >> 1); + val_seq++) { + value = eprms->value[offset >> 1]; + RT28xx_EEPROM_WRITE16(ad, + offset, + value); + } + } else { + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_ERROR, + ("%s: exceed eeprom size(%d), ", + __func__, EEPROM_SIZE)); + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_ERROR, + ("offset=0x%08x, length=%d, ", + offset, length)); + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_ERROR, + ("offset+length=0x%08x\n", + offset+length)); + } + } + } + + return ret; +} + +s_int32 net_ad_get_free_efuse_block( + struct test_wlan_info *winfos, + struct test_eeprom *eprms) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + + eFuseGetFreeBlockCount(ad, &eprms->efuse_free_block); + + return ret; +} + +s_int32 net_ad_mps_tx_operation( + struct test_wlan_info *winfos, + struct test_configuration *configs, + boolean is_start_tx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_mps_cb *mps_cb; + struct test_mps_setting *mps_setting; + + mps_cb = &configs->mps_cb; + mps_setting = mps_cb->mps_setting; + if (!mps_setting || !mps_cb->mps_cnt) { + ret = SERV_STATUS_OSAL_NET_INVALID_NULL_POINTER; + goto err; + } + + if (is_start_tx) { + if (configs->op_mode & OP_MODE_MPS) { + ret = SERV_STATUS_OSAL_NET_FAIL; + goto err; + } + + if (mps_cb->setting_inuse) { + ret = SERV_STATUS_OSAL_NET_FAIL; + goto err; + } + + configs->op_mode |= fTEST_MPS; + mps_cb->ref_idx = 1; + mps_cb->setting_inuse = TRUE; + ret = net_ad_mps_load_setting(winfos, configs); + if (ret) + goto err; + + ret = net_ad_mps_dump_setting(configs, 0xFFFF); + } else { + configs->op_mode &= ~OP_MODE_TXFRAME; + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_TRACE, + ("%s: op_mode=0x%x, inuse=0x%x, setting_addr=%p\n", + __func__, configs->op_mode, mps_cb->setting_inuse, + mps_setting)); + + if (!(configs->op_mode & OP_MODE_MPS) + && !mps_cb->setting_inuse) { + struct test_mps_setting **setting_addr = + &(mps_cb->mps_setting); + mps_cb->mps_cnt = 0; + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_TRACE, + ("%s: before free mem=%p\n", + __func__, mps_setting)); + sys_ad_free_mem(*setting_addr); + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_TRACE, + ("%s: after free mem=%p\n", + __func__, mps_setting)); + *setting_addr = NULL; + } + } + + return ret; +err: + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_ERROR, + ("%s: error, mps_cnt=%d, mps_setting=%p\n", + __func__, mps_cb->mps_cnt, mps_setting)); + SERV_LOG(SERV_DBG_CAT_ADAPT, SERV_DBG_LVL_ERROR, + ("%s: error, op_mode=0x%x, setting_inuse=0x%x\n", + __func__, configs->op_mode, mps_cb->setting_inuse)); + + return ret; +} + +s_int32 net_ad_set_tmr( + struct test_wlan_info *winfos, + struct test_tmr_info *tmr_info) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + s_char tmr_setting[8], tmr_hw_version[8]; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + + if (tmr_info->version == TMR_HW_VER_100) + tmr_info->version = TMR_VER_1_0; + else if (tmr_info->version == TMR_HW_VER_150) + tmr_info->version = TMR_VER_1_5; + else if (tmr_info->version == TMR_HW_VER_200) + tmr_info->version = TMR_VER_2_0; + else { + SERV_LOG(SERV_DBG_CAT_ALL, SERV_DBG_LVL_ERROR, + ("%s: wrong version %d!!\n", + __func__, tmr_info->version)); + return SERV_STATUS_OSAL_NET_INVALID_PARAM; + } + + sprintf(tmr_setting, "%d", tmr_info->setting); + sprintf(tmr_hw_version, "%d", tmr_info->version); + + ret = TmrUpdateParameter(ad, tmr_info->through_hold, tmr_info->iter); + if (ret) + return SERV_STATUS_OSAL_NET_FAIL; + ret = setTmrVerProc(ad, tmr_hw_version); + if (ret) + return SERV_STATUS_OSAL_NET_FAIL; + ret = setTmrEnableProc(ad, tmr_setting); + + return ret; +} + +s_int32 net_ad_get_rxv_stat( + struct test_wlan_info *winfos, + u_char ctrl_band_idx, + struct test_rx_stat *rx_stat) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + RX_STATISTIC_RXV *rxv_stat; + u_char ant_idx = 0, user_idx = 0; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + + rxv_stat = ad->rx_stat_rxv + ctrl_band_idx; + + /* update rx stat info (per antenna path) */ + for (ant_idx = 0; ant_idx < TEST_ANT_NUM; ant_idx++) { + rx_stat->rx_st_path[ant_idx].fagc_ib_rssi = + rxv_stat->FAGC_RSSI_IB[ant_idx]; + rx_stat->rx_st_path[ant_idx].fagc_wb_rssi = + rxv_stat->FAGC_RSSI_WB[ant_idx]; + rx_stat->rx_st_path[ant_idx].rcpi = + rxv_stat->RCPI[ant_idx]; + rx_stat->rx_st_path[ant_idx].rssi = + rxv_stat->RSSI[ant_idx]; + } + + /* update rx stat info (per user) */ + for (user_idx = 0; user_idx < TEST_USER_NUM; user_idx++) { + rx_stat->rx_st_user[user_idx].freq_offset_from_rx = + rxv_stat->FreqOffsetFromRx[user_idx]; + rx_stat->rx_st_user[user_idx].snr = + (u_int32)rxv_stat->SNR[user_idx]; + rx_stat->rx_st_user[user_idx].fcs_error_cnt = + rxv_stat->fcs_error_cnt[user_idx]; + } + + return ret; +} + +s_int32 net_ad_get_rxv_cnt( + struct test_wlan_info *winfos, + u_char ctrl_band_idx, + u_int32 *byte_cnt) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + + chip_get_rxv_cnt(ad, ctrl_band_idx, byte_cnt); + + return ret; +} + +s_int32 net_ad_get_rxv_content( + struct test_wlan_info *winfos, + u_char ctrl_band_idx, + void *content) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + RTMP_ADAPTER *ad = NULL; + + /* Get adapter from jedi driver first */ + GET_PAD_FROM_NET_DEV(ad, winfos->net_dev); + if (ad == NULL) + return SERV_STATUS_OSAL_NET_INVALID_PAD; + + chip_get_rxv_content(ad, ctrl_band_idx, content); + + return ret; +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/glue/osal/jedi/sys_adaption_jedi.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/glue/osal/jedi/sys_adaption_jedi.c new file mode 100644 index 0000000000000000000000000000000000000000..b834d6db9c9fbfa038ad3322f31c22bc2986a532 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/glue/osal/jedi/sys_adaption_jedi.c @@ -0,0 +1,179 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#include "rt_config.h" +#include "sys_adaption.h" + +/***************************************************************************** + * Packet free related functions + *****************************************************************************/ +void sys_ad_free_pkt(void *packet) +{ + if (packet) { + dev_kfree_skb_any(SERV_PKT_TO_OSPKT(packet)); + packet = NULL; + } +} + +/***************************************************************************** + * OS memory allocate/manage/free related functions + *****************************************************************************/ +s_int32 sys_ad_alloc_mem(u_char **mem, u_long size) +{ + *mem = kmalloc(size, GFP_ATOMIC); + + if (*mem) + return SERV_STATUS_SUCCESS; + else + return SERV_STATUS_OSAL_SYS_FAIL; +} + +void sys_ad_free_mem(void *mem) +{ + ASSERT(mem); + kfree(mem); +} + +void sys_ad_zero_mem(void *ptr, u_long length) +{ + memset(ptr, 0, length); +} + +void sys_ad_set_mem(void *ptr, u_long length, u_char value) +{ + memset(ptr, value, length); +} + +void sys_ad_move_mem(void *dest, void *src, u_long length) +{ + memmove(dest, src, length); +} + +s_int32 sys_ad_cmp_mem(void *dest, void *src, u_long length) +{ + return memcmp(dest, src, length); +} + +/***************************************************************************** + * OS task create/manage/kill related functions + *****************************************************************************/ +static inline s_int32 _sys_ad_kill_os_task(struct serv_os_task *task) +{ + s_int32 ret = SERV_STATUS_OSAL_SYS_FAIL; + + if (task->kthread_task) { + if (kthread_stop(task->kthread_task) == 0) { + task->kthread_task = NULL; + ret = SERV_STATUS_SUCCESS; + } else { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_WARN, + ("%s kthread_task %s stop failed\n", __func__, + task->task_name)); + } + } else + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_WARN, + ("%s null kthread_task %s\n", __func__, + task->task_name)); + + return ret; +} + +static inline s_int32 _sys_ad_attach_os_task( + IN struct serv_os_task *task, IN SERV_OS_TASK_CALLBACK fn, + IN u_long arg) +{ + s_int32 status = SERV_STATUS_SUCCESS; + + task->task_killed = 0; + + if (task->kthread_task) { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s non-null kthread_task %s\n", __func__, + task->task_name)); + status = SERV_STATUS_OSAL_SYS_FAIL; + goto done; + } + + task->kthread_task = kthread_run((cast_fn) fn, (void *)arg, + task->task_name); + + if (IS_ERR(task->kthread_task)) { + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s kthread_run %s err %ld\n", __func__, + task->task_name, PTR_ERR(task->kthread_task))); + task->kthread_task = NULL; + status = SERV_STATUS_OSAL_SYS_FAIL; + goto done; + } + +done: + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s %s end %d\n", __func__, task->task_name, status)); + + return status; +} + +static inline s_int32 _sys_ad_init_os_task( + IN struct serv_os_task *task, IN char *task_name, + IN void *priv_winfos, IN void *priv_configs) +{ + s_int32 len; + + ASSERT(task); + len = strlen(task_name); + len = len > (SERV_OS_TASK_NAME_LEN - 1) + ? (SERV_OS_TASK_NAME_LEN - 1) : len; + os_move_mem(&task->task_name[0], task_name, len); + + if (priv_winfos) + task->priv_winfos = priv_winfos; + + if (priv_configs) + task->priv_configs = priv_configs; + + init_waitqueue_head(&(task->kthread_q)); + + return SERV_STATUS_SUCCESS; +} + +boolean _sys_ad_wait_os_task( + IN void *reserved, IN struct serv_os_task *task, IN s_int32 *status) +{ + RTMP_WAIT_EVENT_INTERRUPTIBLE((*status), task); + + if ((task->task_killed == 1) || ((*status) != 0)) + return FALSE; + + return TRUE; +} + +s_int32 sys_ad_kill_os_task(struct serv_os_task *task) +{ + return _sys_ad_kill_os_task(task); +} + +s_int32 sys_ad_attach_os_task( + struct serv_os_task *task, SERV_OS_TASK_CALLBACK fn, u_long arg) +{ + return _sys_ad_attach_os_task(task, fn, arg); +} + +s_int32 sys_ad_init_os_task( + struct serv_os_task *task, char *task_name, + void *priv_winfos, void *priv_configs) +{ + return _sys_ad_init_os_task(task, task_name, + priv_winfos, priv_configs); +} + +boolean sys_ad_wait_os_task( + void *reserved, struct serv_os_task *task, s_int32 *status) +{ + return _sys_ad_wait_os_task(reserved, task, status); +} + +VOID sys_ad_wakeup_os_task(struct serv_os_task *task) +{ + WAKE_UP(task); +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/include/agent.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/include/agent.h new file mode 100644 index 0000000000000000000000000000000000000000..c170bbcdadc0ff48cfc3ccec41c5e2f5f66c093a --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/include/agent.h @@ -0,0 +1,344 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc + */ +#ifndef __AGENT_H__ +#define __AGENT_H__ + +#include "service_test.h" + +/***************************************************************************** + * Type definition + *****************************************************************************/ + +/***************************************************************************** + * Macro + *****************************************************************************/ +#define AGENT_CFG_ARGV_MAX 20 +#define SERV_TEST_ON(_config) ((((_config)->op_mode) & \ + OP_MODE_START) == OP_MODE_START) + +#define TEST_CMDREQ 0x0008 +#define TEST_CMDRSP 0x8008 +#define TEST_CMD_MAGIC_NO 0x18142880 + +#define TEST_CMD_REQ 0x0005 +#define TEST_CMD_RSP 0x8005 + +/***************************************************************************** + * Enum value definition + *****************************************************************************/ +/* String Parser State */ +enum { + AGENT_STATE_EOF = 0, + AGENT_STATE_TEXT = 1, + AGENT_STATE_NEWLINE = 2 +}; + +/* Service handle id */ +enum { + SERV_HANDLE_RESV = 0, + SERV_HANDLE_TEST = 1 +}; + +enum { + SERV_RX_STAT_TYPE_BAND = 0, + SERV_RX_STAT_TYPE_PATH, + SERV_RX_STAT_TYPE_USER, + SERV_RX_STAT_TYPE_COMM, + SERV_RX_STAT_TYPE_NUM +}; + +enum { + HQA_BAND_WIDTH_20 = 0, + HQA_BAND_WIDTH_40, + HQA_BAND_WIDTH_80, + HQA_BAND_WIDTH_10, + HQA_BAND_WIDTH_5, + HQA_BAND_WIDTH_160, + HQA_BAND_WIDTH_8080, + HQA_BAND_WIDTH_NUM +}; + +/***************************************************************************** + * Data struct definition + *****************************************************************************/ +/* Main service data struct */ +struct service { + u_int32 serv_id; + void *serv_handle; +}; + +#pragma pack(1) +struct GNU_PACKED hqa_set_ch { + u_int32 ext_id; + u_int32 num_param; + u_int32 band_idx; + u_int32 central_ch0; + u_int32 central_ch1; + u_int32 sys_bw; + u_int32 perpkt_bw; + u_int32 pri_sel; + u_int32 reason; + u_int32 ch_band; + u_int32 out_band_freq; +}; + +struct GNU_PACKED hqa_tx_content { + u_int32 ext_id; + u_int32 num_param; + u_int32 band_idx; + u_int32 fc; + u_int32 dur; + u_int32 seq; + u_int32 fixed_payload; /* Normal:0,Repeat:1,Random:2 */ + u_int32 txlen; + u_int32 payload_len; + u_char addr1[SERV_MAC_ADDR_LEN]; + u_char addr2[SERV_MAC_ADDR_LEN]; + u_char addr3[SERV_MAC_ADDR_LEN]; + u_char payload[0]; +}; + +struct GNU_PACKED hqa_tx { + u_int32 ext_id; + u_int32 num_param; + u_int32 band_idx; + u_int32 pkt_cnt; + u_int32 tx_mode; + u_int32 rate; + u_int32 pwr; + u_int32 stbc; + u_int32 ldpc; + u_int32 ibf; + u_int32 ebf; + u_int32 wlan_id; + u_int32 aifs; + u_int32 gi; + u_int32 tx_path; + u_int32 nss; + u_int32 hw_tx_enable; +}; + +struct GNU_PACKED hqa_frame { + u_int32 magic_no; + u_int16 type; + u_int16 id; + u_int16 length; + u_int16 sequence; + u_int8 data[SERV_IOCTLBUFF]; +}; + +struct GNU_PACKED hqa_frame_ctrl { + int8_t type; + union { + struct hqa_frame *hqa_frame_eth; + int8_t *hqa_frame_string; + } hqa_frame_comm; +}; + +struct GNU_PACKED hqa_tx_tone { + u_int32 band_idx; + u_int32 tx_tone_en; + u_int32 ant_idx; + u_int32 tone_type; + u_int32 tone_freq; + u_int32 dc_offset_I; + u_int32 dc_offset_Q; + u_int32 band; + u_int32 rf_pwr; + u_int32 digi_pwr; +}; + +struct GNU_PACKED hqa_continuous_tx { + u_int32 band_idx; + u_int32 tx_tone_en; + u_int32 ant_mask; + u_int32 tx_mode; + u_int32 bw; + u_int32 pri_ch; + u_int32 rate; + u_int32 central_ch; + u_int32 tx_fd_mode; +}; + +struct GNU_PACKED hqa_rx_stat_resp_format { + u_int32 type; + u_int32 version; + u_int32 item_mask; + u_int32 blk_cnt; + u_int32 blk_size; +}; + +struct GNU_PACKED hqa_rx_stat_band_info { + u_int32 mac_rx_fcs_err_cnt; + u_int32 mac_rx_mdrdy_cnt; + u_int32 mac_rx_len_mismatch; + u_int32 mac_rx_fcs_ok_cnt; + u_int32 phy_rx_fcs_err_cnt_cck; + u_int32 phy_rx_fcs_err_cnt_ofdm; + u_int32 phy_rx_pd_cck; + u_int32 phy_rx_pd_ofdm; + u_int32 phy_rx_sig_err_cck; + u_int32 phy_rx_sfd_err_cck; + u_int32 phy_rx_sig_err_ofdm; + u_int32 phy_rx_tag_err_ofdm; + u_int32 phy_rx_mdrdy_cnt_cck; + u_int32 phy_rx_mdrdy_cnt_ofdm; +}; + +struct GNU_PACKED hqa_rx_stat_path_info { + u_int32 rcpi; + u_int32 rssi; + u_int32 fagc_ib_rssi; + u_int32 fagc_wb_rssi; + u_int32 inst_ib_rssi; + u_int32 inst_wb_rssi; +}; + +struct GNU_PACKED hqa_rx_stat_user_info { + s_int32 freq_offset_from_rx; + u_int32 snr; + u_int32 fcs_error_cnt; +}; + +struct GNU_PACKED hqa_rx_stat_comm_info { + u_int32 rx_fifo_full; + u_int32 aci_hit_low; + u_int32 aci_hit_high; + u_int32 mu_pkt_count; + u_int32 sig_mcs; + u_int32 sinr; + u_int32 driver_rx_count; +}; + +struct GNU_PACKED hqa_rx_stat_leg { + u_int32 mac_rx_fcs_err_cnt; + u_int32 mac_rx_mdrdy_cnt; + u_int32 phy_rx_fcs_err_cnt_cck; + u_int32 phy_rx_fcs_err_cnt_ofdm; + u_int32 phy_rx_pd_cck; + u_int32 phy_rx_pd_ofdm; + u_int32 phy_rx_sig_err_cck; + u_int32 phy_rx_sfd_err_cck; + u_int32 phy_rx_sig_err_ofdm; + u_int32 phy_rx_tag_err_ofdm; + u_int32 wb_rssi0; + u_int32 ib_rssi0; + u_int32 wb_rssi1; + u_int32 ib_rssi1; + u_int32 phy_rx_mdrdy_cnt_cck; + u_int32 phy_rx_mdrdy_cnt_ofdm; + u_int32 driver_rx_cnt; + u_int32 rcpi0; + u_int32 rcpi1; + s_int32 freq_offset_rx; + u_int32 rssi0; + u_int32 rssi1; + u_int32 rx_fifo_full; + u_int32 mac_rx_len_mismatch; + u_int32 mac_rx_fcs_err_cnt_band1; + u_int32 mac_rx_mdrdy_cnt_band1; + u_int32 fagc_ib_rssi[TEST_ANT_NUM]; + u_int32 fagc_wb_rssi[TEST_ANT_NUM]; + u_int32 inst_ib_rssi[TEST_ANT_NUM]; + u_int32 inst_wb_rssi[TEST_ANT_NUM]; + u_int32 aci_hit_low; + u_int32 aci_git_high; + u_int32 driver_rx_cnt1; + u_int32 rcpi2; + u_int32 rcpi3; + u_int32 rssi2; + u_int32 rssi3; + u_int32 snr0; + u_int32 snr1; + u_int32 snr2; + u_int32 snr3; + u_int32 rx_fifo_full_band1; + u_int32 mac_rx_len_mismatch_band1; + u_int32 phy_rx_pd_cck_band1; + u_int32 phy_rx_pd_ofdm_band1; + u_int32 phy_rx_sig_err_cck_band1; + u_int32 phy_rx_sfd_err_cck_band1; + u_int32 phy_rx_sig_err_ofdm_band1; + u_int32 phy_rx_tag_err_ofdm_band1; + u_int32 phy_rx_mdrdy_cnt_cck_band1; + u_int32 phy_rx_mdrdy_cnt_ofdm_band1; + u_int32 phy_rx_fcs_err_cnt_cck_band1; + u_int32 phy_rx_fcs_err_cnt_ofdm_band1; + u_int32 mu_pkt_cnt; + u_int32 sig_mcs; + u_int32 sinr; + u_int32 rxv_rssi; + u_int32 mac_rx_fcs_ok_cnt; + u_int32 leg_rssi_sub[8]; + s_int32 user_rx_freq_offset[TEST_USER_NUM]; + u_int32 user_snr[TEST_USER_NUM]; + u_int32 fcs_error_cnt[TEST_USER_NUM]; +}; + +#pragma pack() + +struct hqa_cmd_entry { + u_int8 index; + s_int32 (*handler)(struct service_test *serv_test, + struct hqa_frame *hqa_frame); +}; + +struct hqa_cmd_table { + struct hqa_cmd_entry *cmd_set; + u_int32 cmd_set_size; + u_int32 cmd_offset; +}; + +struct agent_cfg_parse_state_s { + s_int8 *ptr; + s_int8 *text; + u_int32 textsize; + s_int32 nexttoken; + u_int32 maxsize; +}; + +struct priv_hqa_cmd_id_mapping { + u_int8 *cmd_str; + u_int16 cmd_id; + u_int8 para_size[AGENT_CFG_ARGV_MAX]; +}; + +struct agent_cli_act_handler { + u_char name[100]; + s_int32 (*handler)(struct service_test *serv_test); +}; + +struct agent_cli_set_w_handler { + u_char name[100]; + s_int32 (*handler)(struct service_test *serv_test, + struct hqa_frame *hqa_cmd); +}; + +struct agent_cli_set_dw_handler { + u_char name[100]; + s_int32 (*handler)(struct service_test *serv_test, + struct hqa_frame *hqa_cmd); +}; + +struct agent_cli_set_ext_handler { + u_char name[100]; + s_int32 (*handler)(struct service_test *serv_test, + u_char *arg); +}; + +/***************************************************************************** + * Function declaration + *****************************************************************************/ +s_int32 mt_agent_hqa_cmd_handler( + struct service *serv, struct hqa_frame_ctrl *hqa_frame_ctrl); +s_int32 mt_agent_init_service(struct service *serv); +s_int32 mt_agent_exit_service(struct service *serv); +s_int32 mt_agent_cli_act(u_char *name, struct service *serv); +s_int32 mt_agent_cli_set_w(u_char *name, struct service *serv, u_char *param); +s_int32 mt_agent_cli_set_dw(u_char *name, struct service *serv, u_char *param); +s_int32 mt_agent_cli_set_ext(u_char *name, + struct service *serv, u_char *arg); + +#endif /* __AGENT_H__ */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/service/include/service_test.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/service/include/service_test.h new file mode 100644 index 0000000000000000000000000000000000000000..d38f11825770262524d25e0092ea7afa991216cb --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/service/include/service_test.h @@ -0,0 +1,282 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#ifndef __SERVICE_TEST_H__ +#define __SERVICE_TEST_H__ + +#include "test_engine.h" +#include "operation.h" + +/***************************************************************************** + * Macro + *****************************************************************************/ +#define SERV_GET_PARAM(_struct, _member) \ + (_struct->_member) +#define SERV_GET_PADDR(_struct, _member) \ + (&_struct->_member) +#define SERV_SET_PARAM(_struct, _member, _val) \ + (_struct->_member = _val) +#define WINFO_GET_PARAM(_struct, _member) \ + (_struct->test_winfo->_member) +#define WINFO_GET_PADDR(_struct, _member) \ + (&_struct->test_winfo->_member) +#define WINFO_SET_PARAM(_struct, _member, _val) \ + (_struct->test_winfo->_member = _val) +#define BSTATE_GET_PARAM(_struct, _member) \ + (_struct->test_bstat._member) +#define BSTATE_SET_PARAM(_struct, _member, _val) \ + (_struct->test_bstat._member = _val) +#define CONFIG_GET_PARAM(_struct, _member, _bandidx) \ + (_struct->test_config[_bandidx]._member) +#define CONFIG_GET_PADDR(_struct, _member, _bandidx) \ + (&_struct->test_config[_bandidx]._member) +#define CONFIG_SET_PARAM(_struct, _member, _val, _bandidx) \ + (_struct->test_config[_bandidx]._member = _val) +#define CONFIG_SET_PADDR(_struct, _member, _val, _size, _bandidx) ({ \ + struct test_configuration *configs; \ + configs = &_struct->test_config[_bandidx]; \ + (sys_ad_move_mem(configs->_member, _val, _size)); \ + }) +#define EEPROM_GET_PARAM(_struct, _member) \ + (_struct->test_eprm._member) +#define EEPROM_SET_PARAM(_struct, _member, _val) \ + (_struct->test_eprm._member = _val) + + +/***************************************************************************** + * Enum value definition + *****************************************************************************/ +/* Service test item id */ +enum { + SERV_TEST_ITEM_INIT = 0, + SERV_TEST_ITEM_EXIT, + SERV_TEST_ITEM_START, + SERV_TEST_ITEM_STOP, + SERV_TEST_ITEM_START_TX, + SERV_TEST_ITEM_STOP_TX, + SERV_TEST_ITEM_START_RX, + SERV_TEST_ITEM_STOP_RX +}; + +/* Service test register/eeprom related operation */ +enum { + SERV_TEST_REG_MAC_READ = 0, + SERV_TEST_REG_MAC_WRITE, + SERV_TEST_REG_MAC_READ_BULK, + SERV_TEST_REG_RF_READ_BULK, + SERV_TEST_REG_RF_WRITE_BULK, + SERV_TEST_REG_CA53_READ, + SERV_TEST_REG_CA53_WRITE, + + SERV_TEST_EEPROM_READ = 10, + SERV_TEST_EEPROM_WRITE, + SERV_TEST_EEPROM_READ_BULK, + SERV_TEST_EEPROM_WRITE_BULK, + SERV_TEST_EEPROM_GET_FREE_EFUSE_BLOCK +}; + +/* Service test mps related operation */ +enum { + SERV_TEST_MPS_START_TX = 0, + SERV_TEST_MPS_STOP_TX +}; + +/* Service test tx power related operation */ +enum { + SERV_TEST_TXPWR_SET_PWR = 0, + SERV_TEST_TXPWR_GET_PWR, + SERV_TEST_TXPWR_SET_PWR_INIT, + SERV_TEST_TXPWR_SET_PWR_MAN, +}; + +/***************************************************************************** + * Data struct definition + *****************************************************************************/ +/* Service data struct for test mode usage */ +struct service_test { + /*========== Jedi only ==========*/ + /* Wlan related information which test needs */ + struct test_wlan_info *test_winfo; + + /* Test backup CR */ + struct test_bk_cr test_bkcr[TEST_MAX_BKCR_NUM]; + + /* Test Rx statistic */ + struct test_rx_stat test_rx_statistic[TEST_DBDC_BAND_NUM]; + + /* The band related state which communicate between UI/driver */ + struct test_band_state test_bstat; + + /* The band_idx which user wants to control currently */ + u_char ctrl_band_idx; + + struct test_backup_params test_backup; + + /*========== Common part ==========*/ + /* Test configuration */ + struct test_configuration test_config[TEST_DBDC_BAND_NUM]; + + /* Test operation */ + struct test_operation *test_op; + + /* Test control register read/write */ + struct test_register test_reg; + + /* Test eeprom read/write */ + struct test_eeprom test_eprm; + + /* Test tmr related configuration */ + struct test_tmr_info test_tmr; + + /* Jedi: false, Gen4m: true */ + boolean engine_offload; + + /* TODO: factor out here for log dump */ + u_int32 en_log; + /* struct _ATE_LOG_DUMP_CB log_dump[ATE_LOG_TYPE_NUM]; */ +}; + +/***************************************************************************** + * Function declaration + *****************************************************************************/ +s_int32 mt_serv_init_test(struct service_test *serv_test); +s_int32 mt_serv_exit_test(struct service_test *serv_test); +s_int32 mt_serv_start(struct service_test *serv_test); +s_int32 mt_serv_stop(struct service_test *serv_test); +s_int32 mt_serv_set_channel(struct service_test *serv_test); +s_int32 mt_serv_set_tx_content(struct service_test *serv_test); +s_int32 mt_serv_set_tx_path(struct service_test *serv_test); +s_int32 mt_serv_set_rx_path(struct service_test *serv_test); +s_int32 mt_serv_submit_tx(struct service_test *serv_test); +s_int32 mt_serv_revert_tx(struct service_test *serv_test); +s_int32 mt_serv_start_tx(struct service_test *serv_test); +s_int32 mt_serv_stop_tx(struct service_test *serv_test); +s_int32 mt_serv_start_rx(struct service_test *serv_test); +s_int32 mt_serv_stop_rx(struct service_test *serv_test); +s_int32 mt_serv_set_freq_offset(struct service_test *serv_test); +s_int32 mt_serv_tx_power_operation( + struct service_test *serv_test, u_int32 item); +s_int32 mt_serv_get_freq_offset( + struct service_test *serv_test, u_int32 *freq_offset); +s_int32 mt_serv_get_cfg_on_off( + struct service_test *serv_test, + u_int32 type, u_int32 *result); +s_int32 mt_serv_get_tx_tone_pwr( + struct service_test *serv_test, + u_int32 ant_idx, u_int32 *power); +s_int32 mt_serv_get_thermal_val( + struct service_test *serv_test, + u_char band_idx, + u_int32 *value); +s_int32 mt_serv_set_cal_bypass( + struct service_test *serv_test, + u_int32 cal_item); +s_int32 mt_serv_set_dpd( + struct service_test *serv_test, + u_int32 on_off, + u_int32 wf_sel); +s_int32 mt_serv_set_tssi( + struct service_test *serv_test, + u_int32 on_off, + u_int32 wf_sel); +s_int32 mt_serv_set_rdd_on_off( + struct service_test *serv_test, + u_int32 rdd_num, + u_int32 rdd_sel, + u_int32 enable); +s_int32 mt_serv_set_off_ch_scan( + struct service_test *serv_test); +s_int32 mt_serv_set_icap_start( + struct service_test *serv_test, + struct hqa_rbist_cap_start *icap_info); +s_int32 mt_serv_get_icap_status( + struct service_test *serv_test, + s_int32 *icap_stat); +s_int32 mt_serv_get_icap_max_data_len( + struct service_test *serv_test, + u_long *max_data_len); +s_int32 mt_serv_get_icap_data( + struct service_test *serv_test, + s_int32 *icap_cnt, + s_int32 *icap_data, + u_int32 wf_num, + u_int32 iq_type); +s_int32 mt_serv_get_recal_cnt( + struct service_test *serv_test, + u_int32 *recal_cnt, + u_int32 *recal_dw_num); +s_int32 mt_serv_get_recal_content( + struct service_test *serv_test, + u_int32 *content); +s_int32 mt_serv_get_rxv_cnt( + struct service_test *serv_test, + u_int32 *rxv_cnt, + u_int32 *rxv_dw_num); +s_int32 mt_serv_get_rxv_content( + struct service_test *serv_test, + u_int32 dw_cnt, + u_int32 *content); +s_int32 mt_serv_get_rdd_cnt( + struct service_test *serv_test, + u_int32 *rdd_cnt, + u_int32 *rdd_dw_num); +s_int32 mt_serv_get_rdd_content( + struct service_test *serv_test, + u_int32 *content, + u_int32 *total_cnt); +s_int32 mt_serv_reset_txrx_counter(struct service_test *serv_test); +s_int32 mt_serv_set_rx_vector_idx( + struct service_test *serv_test, u_int32 group1, u_int32 group2); +s_int32 mt_serv_set_fagc_rssi_path( + struct service_test *serv_test); +s_int32 mt_serv_get_rx_stat_leg( + struct service_test *serv_test, + struct test_rx_stat_leg *rx_stat); +s_int32 mt_serv_get_capability( + struct service_test *serv_test, + struct test_capability *capability); +s_int32 mt_serv_calibration_test_mode( + struct service_test *serv_test, u_char mode); +s_int32 mt_serv_do_cal_item( + struct service_test *serv_test, u_int32 item); +s_int32 mt_serv_set_band_mode(struct service_test *serv_test); +s_int32 mt_serv_get_band_mode(struct service_test *serv_test); +s_int32 mt_serv_log_on_off( + struct service_test *serv_test, u_int32 log_type, + u_int32 log_ctrl, u_int32 log_size); +s_int32 mt_serv_set_cfg_on_off(struct service_test *serv_test); +s_int32 mt_serv_set_rx_filter_pkt_len(struct service_test *serv_test); +s_int32 mt_serv_get_wf_path_comb(struct service_test *serv_test, + u_int8 band_idx, boolean dbdc_mode_en, u_int8 *path, u_int8 *path_len); +s_int32 mt_serv_set_low_power( + struct service_test *serv_test, u_int32 control); +s_int32 mt_serv_get_antswap_capability( + struct service_test *serv_test, u_int32 *antswap_support); +s_int32 mt_serv_set_antswap( + struct service_test *serv_test, u_int32 ant); +s_int32 mt_serv_reg_eprm_operation( + struct service_test *serv_test, u_int32 item); +s_int32 mt_serv_mps_operation( + struct service_test *serv_test, u_int32 item); +s_int32 mt_serv_get_chipid(struct service_test *serv_test); +s_int32 mt_serv_mps_set_nss(struct service_test *serv_test); +s_int32 mt_serv_mps_set_per_packet_bw(struct service_test *serv_test); +s_int32 mt_serv_mps_set_packet_count(struct service_test *serv_test); +s_int32 mt_serv_mps_set_payload_length(struct service_test *serv_test); +s_int32 mt_serv_mps_set_power_gain(struct service_test *serv_test); +s_int32 mt_serv_mps_set_seq_data(struct service_test *serv_test); +s_int32 mt_serv_set_tmr(struct service_test *serv_test); +s_int32 mt_serv_set_preamble(struct service_test *serv_test); +s_int32 mt_serv_set_rate(struct service_test *serv_test); +s_int32 mt_serv_set_system_bw(struct service_test *serv_test); +s_int32 mt_serv_set_per_pkt_bw(struct service_test *serv_test); +s_int32 mt_serv_dbdc_tx_tone(struct service_test *serv_test); +s_int32 mt_serv_dbdc_tx_tone_pwr(struct service_test *serv_test); +s_int32 mt_serv_dbdc_continuous_tx(struct service_test *serv_test); +s_int32 mt_serv_get_tx_info(struct service_test *serv_test); +s_int32 mt_serv_main(struct service_test *serv_test, u_int32 test_item); +s_int32 mt_serv_get_rx_stat(struct service_test *serv_test, u_int8 band_idx, + u_int8 blk_idx, u_int8 test_rx_stat_cat, struct test_rx_stat_u *st); + +#endif /* __SERVICE_TEST_H__ */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/service/include/test_engine.h b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/service/include/test_engine.h new file mode 100644 index 0000000000000000000000000000000000000000..d08b0adf3e2884243720299f19f19888547fa730 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/service/include/test_engine.h @@ -0,0 +1,98 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#ifndef __TEST_ENGINE_H__ +#define __TEST_ENGINE_H__ + +#include "operation.h" + +/***************************************************************************** + * Macrolog_dump + *****************************************************************************/ +#define engine_min(_a, _b) ((_a > _b) ? _b : _a) + +#define engine_max(_a, _b) ((_a > _b) ? _a : _b) + +#define engine_ceil(_a, _b) (((_a%_b) > 0) ? ((_a/_b)+1) : (_a/_b)) + +#define TEST_ANT_USER_DEF 0x80000000 + +/***************************************************************************** + * Enum value definition + *****************************************************************************/ +enum TEST_HETB_CTRL { + OP_HETB_TX_CFG = 0, + OP_HETB_TX_START = 1, + OP_HETB_TX_STOP = 2, + OP_HETB_RX_CFG = 3, +}; + +/***************************************************************************** + * Data struct definition + *****************************************************************************/ +struct test_he_ru_const { + u_int8 max_index; + u_int16 sd; /* data subcarriers */ + u_int16 sd_d; /* data subcarriers for DCM */ + u_int16 sd_s; /* data subcarriers short */ + u_int16 sd_s_d; /* data subcarriers short for DCM*/ +}; + +/***************************************************************************** + * Function declaration + *****************************************************************************/ +s_int32 mt_engine_search_stack( + struct test_configuration *configs, + u_int8 wcid, + void **virtual_wtbl); +s_int32 mt_engine_subscribe_tx( + struct test_operation *ops, + struct test_wlan_info *winfos, + struct test_configuration *configs); +s_int32 mt_engine_unsubscribe_tx( + struct test_operation *ops, + struct test_wlan_info *winfos, + struct test_configuration *configs); +s_int32 mt_engine_start( + struct test_wlan_info *winfos, + struct test_backup_params *bak, + struct test_configuration *configs, + struct test_operation *ops, + struct test_bk_cr *bks, + struct test_rx_stat *rx_stat, + u_int32 en_log); +s_int32 mt_engine_stop( + struct test_wlan_info *winfos, + struct test_backup_params *bak, + struct test_configuration *configs, + struct test_operation *ops, + struct test_bk_cr *bks); +s_int32 mt_engine_calc_ipg_param_by_ipg( + struct test_configuration *configs); +s_int32 mt_engine_set_auto_resp( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_char band_idx, u_char mode); +s_int32 mt_engine_start_tx( + struct test_wlan_info *winfos, + struct test_configuration *configs, + struct test_operation *ops, + u_char band_idx); +s_int32 mt_engine_stop_tx( + struct test_wlan_info *winfos, + struct test_configuration *configs, + struct test_operation *ops, + u_char band_idx); +s_int32 mt_engine_start_rx( + struct test_wlan_info *winfos, + struct test_configuration *configs, + struct test_operation *ops, + u_char band_idx); +s_int32 mt_engine_stop_rx( + struct test_wlan_info *winfos, + struct test_configuration *configs, + struct test_operation *ops, + u_char band_idx); + +#endif /* __TEST_ENGINE_H__ */ diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/service/service_test.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/service/service_test.c new file mode 100644 index 0000000000000000000000000000000000000000..ba6985f64ca0639c8f5aa66b83f901dcefcd1248 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/service/service_test.c @@ -0,0 +1,2479 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#include "service_test.h" + +u_char template_frame[32] = { 0x88, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0xAA, 0xBB, 0x12, 0x34, 0x56, + 0x00, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +/***************************************************************************** + * Internal functions + *****************************************************************************/ +static s_int32 mt_serv_init_op(struct test_operation *ops) +{ + ops->op_set_tr_mac = mt_op_set_tr_mac; + ops->op_set_tx_stream = mt_op_set_tx_stream; + ops->op_set_tx_path = mt_op_set_tx_path; + ops->op_set_rx_path = mt_op_set_rx_path; + ops->op_set_rx_filter = mt_op_set_rx_filter; + ops->op_set_clean_persta_txq = mt_op_set_clean_persta_txq; + ops->op_set_cfg_on_off = mt_op_set_cfg_on_off; + ops->op_log_on_off = mt_op_log_on_off; + ops->op_dbdc_tx_tone = mt_op_dbdc_tx_tone; + ops->op_dbdc_tx_tone_pwr = mt_op_dbdc_tx_tone_pwr; + ops->op_dbdc_continuous_tx = mt_op_dbdc_continuous_tx; + ops->op_get_tx_info = mt_op_get_tx_info; + ops->op_set_antenna_port = mt_op_set_antenna_port; + ops->op_set_slot_time = mt_op_set_slot_time; + ops->op_set_power_drop_level = mt_op_set_power_drop_level; + ops->op_get_antswap_capability = mt_op_get_antswap_capability; + ops->op_set_antswap = mt_op_set_antswap; + ops->op_set_rx_filter_pkt_len = mt_op_set_rx_filter_pkt_len; + ops->op_set_freq_offset = mt_op_set_freq_offset; + ops->op_set_phy_counter = mt_op_set_phy_counter; + ops->op_set_rxv_index = mt_op_set_rxv_index; + ops->op_set_fagc_path = mt_op_set_fagc_path; + ops->op_set_fw_mode = mt_op_set_fw_mode; + ops->op_set_rf_test_mode = mt_op_set_rf_test_mode; + ops->op_set_test_mode_start = mt_op_set_test_mode_start; + ops->op_set_test_mode_abort = mt_op_set_test_mode_abort; + ops->op_start_tx = mt_op_start_tx; + ops->op_stop_tx = mt_op_stop_tx; + ops->op_start_rx = mt_op_start_rx; + ops->op_stop_rx = mt_op_stop_rx; + ops->op_set_channel = mt_op_set_channel; + ops->op_set_tx_content = mt_op_set_tx_content; + ops->op_set_preamble = mt_op_set_preamble; + ops->op_set_rate = mt_op_set_rate; + ops->op_set_system_bw = mt_op_set_system_bw; + ops->op_set_per_pkt_bw = mt_op_set_per_pkt_bw; + ops->op_reset_txrx_counter = mt_op_reset_txrx_counter; + ops->op_set_rx_vector_idx = mt_op_set_rx_vector_idx; + ops->op_set_fagc_rssi_path = mt_op_set_fagc_rssi_path; + ops->op_get_rx_stat_leg = mt_op_get_rx_stat_leg; + ops->op_get_rx_statistics_all = mt_op_get_rx_statistics_all; + ops->op_get_capability = mt_op_get_capability; + ops->op_calibration_test_mode = mt_op_calibration_test_mode; + ops->op_set_icap_start = mt_op_set_icap_start; + ops->op_get_icap_status = mt_op_get_icap_status; + ops->op_get_icap_max_data_len = mt_op_get_icap_max_data_len; + ops->op_get_icap_data = mt_op_get_icap_data; + ops->op_do_cal_item = mt_op_do_cal_item; + ops->op_set_band_mode = mt_op_set_band_mode; + ops->op_get_chipid = mt_op_get_chipid; + ops->op_mps_start = mt_op_mps_start; + ops->op_mps_set_nss = mt_op_mps_set_nss; + ops->op_mps_set_per_packet_bw = mt_op_mps_set_per_packet_bw; + ops->op_mps_set_packet_count = mt_op_mps_set_packet_count; + ops->op_mps_set_payload_length = mt_op_mps_set_payload_length; + ops->op_mps_set_power_gain = mt_op_mps_set_power_gain; + ops->op_mps_set_seq_data = mt_op_mps_set_seq_data; + ops->op_get_tx_pwr = mt_op_get_tx_pwr; + ops->op_set_tx_pwr = mt_op_set_tx_pwr; + ops->op_get_freq_offset = mt_op_get_freq_offset; + ops->op_get_cfg_on_off = mt_op_get_cfg_on_off; + ops->op_get_tx_tone_pwr = mt_op_get_tx_tone_pwr; + ops->op_get_recal_cnt = mt_op_get_recal_cnt; + ops->op_get_recal_content = mt_op_get_recal_content; + ops->op_get_rxv_cnt = mt_op_get_rxv_cnt; + ops->op_get_rxv_content = mt_op_get_rxv_content; + ops->op_get_thermal_val = mt_op_get_thermal_val; + ops->op_set_cal_bypass = mt_op_set_cal_bypass; + ops->op_set_dpd = mt_op_set_dpd; + ops->op_set_tssi = mt_op_set_tssi; + ops->op_set_rdd_test = mt_op_set_rdd_test; + ops->op_get_wf_path_comb = mt_op_get_wf_path_comb; + ops->op_set_off_ch_scan = mt_op_set_off_ch_scan; + ops->op_get_rdd_cnt = mt_op_get_rdd_cnt; + ops->op_get_rdd_content = mt_op_get_rdd_content; + ops->op_set_muru_manual = mt_op_set_muru_manual; + ops->op_set_tam_arb = mt_op_set_tam_arb; + ops->op_hetb_ctrl = mt_op_hetb_ctrl; + ops->op_set_ru_aid = mt_op_set_ru_aid; + ops->op_set_mutb_spe = mt_op_set_mutb_spe; + ops->op_get_rx_stat_band = mt_op_get_rx_stat_band; + ops->op_get_rx_stat_path = mt_op_get_rx_stat_path; + ops->op_get_rx_stat_user = mt_op_get_rx_stat_user; + ops->op_get_rx_stat_comm = mt_op_get_rx_stat_comm; + /* For test mac usage */ + ops->op_backup_and_set_cr = mt_op_backup_and_set_cr; + ops->op_restore_cr = mt_op_restore_cr; + ops->op_set_ampdu_ba_limit = mt_op_set_ampdu_ba_limit; + ops->op_set_sta_pause_cr = mt_op_set_sta_pause_cr; + ops->op_set_ifs_cr = mt_op_set_ifs_cr; + ops->op_write_mac_bbp_reg = mt_op_write_mac_bbp_reg; + ops->op_read_bulk_mac_bbp_reg = mt_op_read_bulk_mac_bbp_reg; + ops->op_read_bulk_rf_reg = mt_op_read_bulk_rf_reg; + ops->op_write_bulk_rf_reg = mt_op_write_bulk_rf_reg; + ops->op_read_bulk_eeprom = mt_op_read_bulk_eeprom; + + return SERV_STATUS_SUCCESS; +} + +static s_int32 mt_serv_init_config( + struct test_configuration *configs, u_char band_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + if (band_idx == TEST_DBDC_BAND0) { + /* Operated mode init */ + configs->op_mode = OP_MODE_STOP; + + /* Test packet init */ + ret = sys_ad_alloc_mem((u_char **) &configs->test_pkt, + TEST_PKT_LEN); + configs->pkt_skb = NULL; + + /* OS related init */ + SERV_OS_INIT_COMPLETION(&configs->tx_wait); + configs->tx_status = 0; + + /* Hardware resource init */ + configs->wdev_idx = 0; + configs->wmm_idx = 0; + configs->ac_idx = SERV_QID_AC_BE; + + /* Tx frame init */ + sys_ad_move_mem(&configs->template_frame, &template_frame, 32); + configs->addr1[0][0] = 0x00; + configs->addr1[0][1] = 0x11; + configs->addr1[0][2] = 0x22; + configs->addr1[0][3] = 0xAA; + configs->addr1[0][4] = 0xBB; + configs->addr1[0][5] = 0xCC; + sys_ad_move_mem(configs->addr2[0], configs->addr1[0], + SERV_MAC_ADDR_LEN); + sys_ad_move_mem(configs->addr3[0], &configs->addr1[0], + SERV_MAC_ADDR_LEN); + configs->payload[0] = 0xAA; + configs->seq = 0; + configs->hdr_len = SERV_LENGTH_802_11; + configs->pl_len = 1; + configs->tx_len = 1058; + configs->fixed_payload = 1; + configs->max_pkt_ext = 2; + configs->retry = 1; + + /* Tx strategy/type init */ + configs->txs_enable = FALSE; + configs->tx_strategy = TEST_TX_STRA_THREAD; + configs->rate_ctrl_type = TEST_TX_TYPE_TXD; + + /* Tx timing init */ + configs->duty_cycle = 0; + configs->tx_time_param.pkt_tx_time_en = FALSE; + configs->tx_time_param.pkt_tx_time = 0; + configs->ipg_param.ipg = 0; + configs->ipg_param.sig_ext = TEST_SIG_EXTENSION; + configs->ipg_param.slot_time = TEST_DEFAULT_SLOT_TIME; + configs->ipg_param.sifs_time = TEST_DEFAULT_SIFS_TIME; + configs->ipg_param.ac_num = SERV_QID_AC_BE; + configs->ipg_param.aifsn = TEST_MIN_AIFSN; + configs->ipg_param.cw = TEST_MIN_CW; + configs->ipg_param.txop = 0; + + /* Rx init */ + sys_ad_zero_mem(&configs->own_mac, SERV_MAC_ADDR_LEN); + + /* Test tx statistic and txs init */ + configs->txs_enable = FALSE; + sys_ad_zero_mem(&configs->tx_stat, + sizeof(struct test_tx_statistic)); + + /* Phy */ + configs->tx_ant = 1; + configs->rx_ant = 1; + + /* TODO: factor out here for phy */ + configs->channel = 1; + configs->ch_band = 0; + configs->ctrl_ch = 1; +#if 0 + if (BOARD_IS_5G_ONLY(pAd)) + configs->channel = 36; + else + configs->channel = 1; +#endif + configs->tx_mode = TEST_MODE_OFDM; + configs->bw = TEST_BW_20; + configs->mcs = 7; + configs->sgi = 0; + + /* tx power */ + configs->tx_pwr_sku_en = FALSE; + configs->tx_pwr_percentage_en = FALSE; + configs->tx_pwr_backoff_en = FALSE; + configs->tx_pwr_percentage_level = 100; + } +/* #ifdef DBDC_MODE */ +#if 0 + else if (band_idx == TEST_DBDC_BAND1) { + /* Operated mode init */ + configs->op_mode = OP_MODE_STOP; + + /* Test packet init */ + ret = sys_ad_alloc_mem((u_char **) &configs->test_pkt, + TEST_PKT_LEN); + configs->pkt_skb = NULL; + + /* OS related init */ + SERV_OS_INIT_COMPLETION(&configs->tx_wait); + configs->tx_status = 0; + + /* Hardware resource init */ + configs->wdev_idx = 1; + configs->wmm_idx = 1; + configs->ac_idx = SERV_QID_AC_BE; + + /* Tx frame init */ + sys_ad_move_mem(&configs->template_frame, &template_frame, 32); + configs->addr1[0][0] = 0x00; + configs->addr1[1][0] = 0x11; + configs->addr1[2][0] = 0x22; + configs->addr1[3][0] = 0xAA; + configs->addr1[4][0] = 0xBB; + configs->addr1[5][0] = 0xCC; + sys_ad_move_mem(&configs->addr2, &configs->addr1, + SERV_MAC_ADDR_LEN); + sys_ad_move_mem(&configs->addr3, &configs->addr1, + SERV_MAC_ADDR_LEN); + configs->payload[0] = 0xAA; + configs->seq = 0; + configs->hdr_len = SERV_LENGTH_802_11; + configs->pl_len = 1; + configs->tx_len = 1024; + configs->fixed_payload = 1; + configs->max_pkt_ext = 2; + configs->retry = 1; + + /* Tx strategy/type init */ + configs->tx_strategy = TEST_TX_STRA_THREAD; + configs->rate_ctrl_type = TEST_TX_TYPE_TXD; + + /* Tx timing init */ + configs->duty_cycle = 0; + configs->tx_time_param.pkt_tx_time_en = FALSE; + configs->tx_time_param.pkt_tx_time = 0; + configs->ipg_param.ipg = 0; + configs->ipg_param.sig_ext = TEST_SIG_EXTENSION; + configs->ipg_param.slot_time = TEST_DEFAULT_SLOT_TIME; + configs->ipg_param.sifs_time = TEST_DEFAULT_SIFS_TIME; + configs->ipg_param.ac_num = SERV_QID_AC_BE; + configs->ipg_param.aifsn = TEST_MIN_AIFSN; + configs->ipg_param.cw = TEST_MIN_CW; + configs->ipg_param.txop = 0; + + /* Rx init */ + sys_ad_zero_mem(&configs->own_mac, SERV_MAC_ADDR_LEN); + + /* Test tx statistic and txs init */ + configs->txs_enable = FALSE; + sys_ad_zero_mem(&configs->tx_stat, + sizeof(struct test_tx_statistic)); + + /* Phy */ + configs->tx_ant = 1; + configs->rx_ant = 1; + + /* TODO: factor out here for phy */ + configs->channel = 36; + configs->ch_band = 1; + configs->ctrl_ch = 36; +#if 0 + if (pAd->CommonCfg.eDBDC_mode == ENUM_DBDC_5G5G) { + configs->channel = 100; + configs->ctrl_ch = 100; + } else { + configs->channel = 36; + configs->ctrl_ch = 36; + } +#endif + configs->tx_mode = TEST_MODE_OFDM; + configs->bw = TEST_BW_20; + configs->mcs = 7; + configs->sgi = 0; + + /* TODO: factor out here for Tx power */ + } +#endif /* DBDC_MODE */ + else + return SERV_STATUS_SERV_TEST_INVALID_BANDIDX; + + return ret; +} + +static s_int32 mt_serv_release_config( + struct test_configuration *configs, u_char band_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + if (band_idx == TEST_DBDC_BAND0) { + if (configs->test_pkt) { + sys_ad_free_mem(configs->test_pkt); + configs->test_pkt = NULL; + } + } +/* #ifdef DBDC_MODE */ +#if 1 + else if (band_idx == TEST_DBDC_BAND1) { + if (configs->test_pkt) { + sys_ad_free_mem(configs->test_pkt); + configs->test_pkt = NULL; + } + } +#endif /* DBDC_MODE */ + else + return SERV_STATUS_SERV_TEST_INVALID_BANDIDX; + + return ret; +} + +/***************************************************************************** + * Extern functions + *****************************************************************************/ +/* For test mode init of service.git */ +s_int32 mt_serv_init_test(struct service_test *serv_test) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char band_idx; + + if (!serv_test->engine_offload) { + for (band_idx = TEST_DBDC_BAND0; + band_idx < TEST_DBDC_BAND_NUM; band_idx++) { + ret = mt_serv_init_config( + &serv_test->test_config[band_idx], band_idx); + if (ret != SERV_STATUS_SUCCESS) + return SERV_STATUS_SERV_TEST_FAIL; + } + + /* Control band0 as default setting */ + serv_test->ctrl_band_idx = TEST_DBDC_BAND0; + + /* Init test mode backup CR data struct */ + sys_ad_zero_mem(serv_test->test_bkcr, + sizeof(struct test_bk_cr) * TEST_MAX_BKCR_NUM); + + /* Init test mode rx statistic data struct */ + sys_ad_zero_mem(serv_test->test_rx_statistic, + sizeof(struct test_rx_stat) * TEST_DBDC_BAND_NUM); + + /* Init test mode rx statistic data struct */ + sys_ad_zero_mem(&serv_test->test_bstat, + sizeof(struct test_band_state)); + } else { + serv_test->test_winfo->dbdc_mode = TEST_DBDC_DISABLE; + serv_test->test_winfo->hw_tx_enable = TEST_HWTX_DISABLE; + } + ret = mt_serv_init_op(serv_test->test_op); + + /* Init test mode control register data struct */ + sys_ad_zero_mem(&serv_test->test_reg, + sizeof(struct test_register)); + + /* Init test mode eeprom data struct */ + sys_ad_zero_mem(&serv_test->test_eprm, + sizeof(struct test_eeprom)); + + /* Init test mode eeprom data struct */ + serv_test->ctrl_band_idx = 0; + + /* TODO: factor out here */ + /* Common Part */ + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +/* For test mode exit of service.git */ +s_int32 mt_serv_exit_test(struct service_test *serv_test) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char band_idx; + + if (!serv_test->engine_offload) { + for (band_idx = TEST_DBDC_BAND0; + band_idx < TEST_DBDC_BAND_NUM; band_idx++) { + ret = mt_serv_release_config( + &serv_test->test_config[band_idx], band_idx); + if (ret != SERV_STATUS_SUCCESS) + return SERV_STATUS_SERV_TEST_FAIL; + } + } + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_start(struct service_test *serv_test) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + if (!serv_test->engine_offload) { + ret = mt_engine_start(serv_test->test_winfo, + &serv_test->test_backup, + serv_test->test_config, + serv_test->test_op, + serv_test->test_bkcr, + &serv_test->test_rx_statistic[0], + serv_test->en_log); + } else { + ret = serv_test->test_op->op_set_test_mode_start( + serv_test->test_winfo); + } + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_stop(struct service_test *serv_test) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + if (!serv_test->engine_offload) { + ret = mt_engine_stop(serv_test->test_winfo, + &serv_test->test_backup, + serv_test->test_config, + serv_test->test_op, + serv_test->test_bkcr); + } else { + ret = serv_test->test_op->op_set_test_mode_abort( + serv_test->test_winfo); + } + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_set_channel(struct service_test *serv_test) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char ctrl_band_idx = serv_test->ctrl_band_idx; + struct test_configuration *configs; + struct test_wlan_info *winfos = serv_test->test_winfo; + struct test_operation *ops = serv_test->test_op; + struct serv_chip_cap *cap = &winfos->chip_cap; + s_int32 ant_loop; + u_char ant_mask = 0; + u_int32 tx_stream_num = 0, max_stream_num = 0; + s_int8 ch_offset = 0; +#if 0 + u_char tmp = 0; +#endif + u_char pri_sel = 0, channel = 0, channel_2nd = 0; + const s_int8 bw40_sel[] = { -2, 2}; + const s_int8 bw80_sel[] = { -6, -2, 2, 6}; + const s_int8 bw160_sel[] = { -14, -10, -6, -2, 2, 6, 10, 14}; + + configs = &serv_test->test_config[ctrl_band_idx]; + + /* update max stream num cap */ + max_stream_num = cap->mcs_nss.max_nss; + if (IS_TEST_DBDC(winfos)) + max_stream_num /= 2; + + for (ant_loop = 0; ant_loop < max_stream_num; ant_loop++) { + if (configs->tx_ant & (0x1 << ant_loop)) + ant_mask |= (0x1 << ant_loop); + } + + /* update tx anteena config */ + configs->tx_ant = ant_mask; + + /* + * To get TX max stream number from TX antenna bit mask + * tx_sel=2 -> tx_stream_num=2 + * tx_sel=4 -> tx_stream_num=3 + * tx_sel=8 -> tx_stream_num=4 + */ + + /* + * tx stream for arbitrary tx ant bitmap + * (ex: tx_sel=5 -> tx_stream_num=3, not 2) + */ + for (ant_loop = max_stream_num; ant_loop > 0; ant_loop--) { + if (ant_mask & BIT(ant_loop - 1)) { + tx_stream_num = ant_loop; + break; + } + } + + /* tx stream parameter sanity protection */ + tx_stream_num = tx_stream_num ? tx_stream_num : 1; + tx_stream_num = (tx_stream_num <= max_stream_num) + ? tx_stream_num : max_stream_num; + + /* update tx stream num config */ + configs->tx_strm_num = tx_stream_num; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: tx_ant:0x%x, tx stream:%u\n", + __func__, configs->tx_ant, configs->tx_strm_num)); + + for (ant_loop = 0; ant_loop < max_stream_num; ant_loop++) { + if (configs->rx_ant & (0x1 << ant_loop)) + ant_mask |= (0x1 << ant_loop); + } + + /* fw need parameter rx stream path */ + configs->rx_ant = ant_mask; + configs->rx_strm_pth = ant_mask; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: rx_ant:0x%x, rx path:0x%x\n", __func__, + configs->rx_ant, configs->rx_strm_pth)); + + /* read test config info */ + pri_sel = configs->pri_sel; + channel = configs->channel; + channel_2nd = configs->channel_2nd; + + switch (configs->bw) { + case TEST_BW_20: + configs->ctrl_ch = channel; + if (configs->per_pkt_bw > configs->bw) { + switch (configs->per_pkt_bw) { + case TEST_BW_80: + if (pri_sel >= 4) + goto error; + + ch_offset = bw80_sel[pri_sel]; + break; + case TEST_BW_160C: + case TEST_BW_160NC: + if (pri_sel >= 8) + goto error; + + ch_offset = bw160_sel[pri_sel]; + break; + default: /* BW_40 */ + if (pri_sel > 1) + goto error; + + ch_offset = bw40_sel[pri_sel]; + } + } + + break; + case TEST_BW_40: + if (pri_sel >= 2) + goto error; + + configs->ctrl_ch = channel + bw40_sel[pri_sel]; + ch_offset = bw40_sel[pri_sel]; + + break; + + case TEST_BW_160NC: + if (pri_sel >= 8) + goto error; + + if (!channel_2nd) + goto error2; + +#if 0 + /* swap control channel to be in order */ + if (channel_2nd < channel) { + tmp = channel; + channel = channel_2nd; + channel_2nd = tmp; + } +#endif + /* TODO: bw80+80 primary select definition */ + if (pri_sel < 4) { + configs->ctrl_ch = channel + bw80_sel[pri_sel]; + ch_offset = bw80_sel[pri_sel]; + } else { + configs->ctrl_ch = channel + bw80_sel[pri_sel - 4]; + ch_offset = bw80_sel[pri_sel - 4]; + } + + break; + + case TEST_BW_80: + if (pri_sel >= 4) + goto error; + + configs->ctrl_ch = channel + bw80_sel[pri_sel]; + ch_offset = bw80_sel[pri_sel]; + + break; + + case TEST_BW_160C: + if (pri_sel >= 8) + goto error; + + configs->ctrl_ch = channel + bw160_sel[pri_sel]; + ch_offset = bw160_sel[pri_sel]; + + break; + + default: + goto error3; + } + + /* sanity check for channel parameter */ + if (((channel + ch_offset) <= 0) || + ((channel - ch_offset) <= 0)) + goto error; + + /* update test config info */ + configs->pri_sel = pri_sel; + configs->ch_offset = ch_offset; + configs->channel = channel; + configs->channel_2nd = channel_2nd; + + /* set channel */ + ret = ops->op_set_channel(winfos, ctrl_band_idx, configs); + if (ret) + goto error; + + return ret; + +error: + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: set channel fail, ", __func__)); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("control channel: %d|%d\n", configs->ctrl_ch, + channel - ch_offset)); + return SERV_STATUS_OSAL_NET_FAIL_SET_CHANNEL; + +error2: + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: set channel fail, ", __func__)); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("second control channel is 0 for bw 80+80\n")); + return SERV_STATUS_OSAL_NET_FAIL_SET_CHANNEL; + +error3: + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: set channel fail, ", __func__)); + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("bw=%d is invalid\n", configs->bw)); + return SERV_STATUS_OSAL_NET_FAIL_SET_CHANNEL; +} + +s_int32 mt_serv_set_tx_content(struct service_test *serv_test) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char ctrl_band_idx = serv_test->ctrl_band_idx; + struct test_configuration *configs; + + configs = &serv_test->test_config[ctrl_band_idx]; + + ret = serv_test->test_op->op_set_tx_content( + serv_test->test_winfo, + ctrl_band_idx, + configs); + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_set_tx_path(struct service_test *serv_test) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char ctrl_band_idx = serv_test->ctrl_band_idx; + struct test_configuration *configs; + + configs = &serv_test->test_config[ctrl_band_idx]; + + ret = serv_test->test_op->op_set_tx_path( + serv_test->test_winfo, + ctrl_band_idx, + configs); + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_set_rx_path(struct service_test *serv_test) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char ctrl_band_idx = serv_test->ctrl_band_idx; + struct test_configuration *configs; + + configs = &serv_test->test_config[ctrl_band_idx]; + + ret = serv_test->test_op->op_set_rx_path( + serv_test->test_winfo, + ctrl_band_idx, + configs); + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_submit_tx(struct service_test *serv_test) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char ctrl_band_idx = serv_test->ctrl_band_idx; + struct test_configuration *configs; + struct test_operation *ops = serv_test->test_op; + struct test_wlan_info *winfos = serv_test->test_winfo; + + configs = &serv_test->test_config[ctrl_band_idx]; + + if (!serv_test->engine_offload) { + ret = mt_engine_subscribe_tx(ops, winfos, configs); + if (ret) + goto err_out; + } else { + /* TBD */ + } + +err_out: + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%04x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_revert_tx(struct service_test *serv_test) +{ + u_int32 ret = SERV_STATUS_SUCCESS; + u_char ctrl_band_idx = serv_test->ctrl_band_idx; + struct test_configuration *configs; + struct test_operation *ops = serv_test->test_op; + struct test_wlan_info *winfos = serv_test->test_winfo; + + configs = &serv_test->test_config[ctrl_band_idx]; + + if (!serv_test->engine_offload) { + ret = mt_engine_unsubscribe_tx(ops, winfos, configs); + if (ret) + goto err_out; + } else { + /* TBD */ + } + +err_out: + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_start_tx(struct service_test *serv_test) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char ctrl_band_idx = serv_test->ctrl_band_idx; + struct test_configuration *configs; + struct test_operation *ops = serv_test->test_op; + struct test_wlan_info *winfos = serv_test->test_winfo; + struct test_txpwr_param *pwr_param = NULL; + + configs = &serv_test->test_config[ctrl_band_idx]; + pwr_param = &configs->pwr_param; + + if (!pwr_param) { + ret = SERV_STATUS_SERV_TEST_INVALID_NULL_POINTER; + goto err_out; + } + + if (configs->tx_mode < TEST_MODE_HE_SU) { + if (configs->mcs == 32 + && configs->per_pkt_bw != TEST_BW_40 + && configs->bw != TEST_BW_40) { + ret = SERV_STATUS_SERV_TEST_INVALID_PARAM; + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: bandwidth must to be 40 at MCS 32\n", __func__)); + goto err_out; + } + } + + if (!serv_test->engine_offload) { + ret = ops->op_set_tx_pwr( + winfos, configs, ctrl_band_idx, pwr_param); + if (ret) + return ret; + + ret = mt_engine_calc_ipg_param_by_ipg( + &serv_test->test_config[ctrl_band_idx]); + if (ret) + goto err_out; + + ret = mt_engine_start_tx(serv_test->test_winfo, + &serv_test->test_config[ctrl_band_idx], + serv_test->test_op, ctrl_band_idx); + } else { + ret = serv_test->test_op->op_start_tx( + serv_test->test_winfo, + ctrl_band_idx, + &serv_test->test_config[ctrl_band_idx]); + } + +err_out: + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_stop_tx(struct service_test *serv_test) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char ctrl_band_idx = serv_test->ctrl_band_idx; + + if (!serv_test->engine_offload) { + ret = mt_engine_stop_tx(serv_test->test_winfo, + &serv_test->test_config[ctrl_band_idx], + serv_test->test_op, ctrl_band_idx); + } else { + ret = serv_test->test_op->op_stop_tx( + serv_test->test_winfo, + ctrl_band_idx); + } + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_start_rx(struct service_test *serv_test) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char ctrl_band_idx = serv_test->ctrl_band_idx; + struct test_wlan_info *winfos = serv_test->test_winfo; + struct serv_chip_cap *cap = &winfos->chip_cap; + struct test_configuration *configs; + s_int32 ant_loop; + u_char ant_mask = 0; + u_int32 max_stream_num = 0; + + configs = &serv_test->test_config[ctrl_band_idx]; + + if (!serv_test->engine_offload) { + ret = mt_engine_set_auto_resp(serv_test->test_winfo, + &serv_test->test_config[ctrl_band_idx], + ctrl_band_idx, 1); + if (ret) + return ret; + + /* update max stream num cap */ + max_stream_num = cap->mcs_nss.max_nss; + + for (ant_loop = 0; ant_loop < max_stream_num; ant_loop++) { + if (configs->rx_ant & (0x1 << ant_loop)) + ant_mask |= (0x1 << ant_loop); + } + + /* fw need parameter rx stream path */ + configs->rx_ant = ant_mask; + configs->rx_strm_pth = ant_mask; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: rx_ant:0x%x, rx path:0x%x\n", __func__, + configs->rx_ant, configs->rx_strm_pth)); + + ret = mt_engine_start_rx(serv_test->test_winfo, + &serv_test->test_config[ctrl_band_idx], + serv_test->test_op, ctrl_band_idx); + } else { + ret = serv_test->test_op->op_start_rx( + serv_test->test_winfo, + ctrl_band_idx, + configs); + } + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_stop_rx(struct service_test *serv_test) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char ctrl_band_idx = serv_test->ctrl_band_idx; + + if (!serv_test->engine_offload) { + ret = mt_engine_stop_rx(serv_test->test_winfo, + &serv_test->test_config[ctrl_band_idx], + serv_test->test_op, ctrl_band_idx); + } else { + ret = serv_test->test_op->op_stop_rx( + serv_test->test_winfo, + ctrl_band_idx); + } + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_set_freq_offset(struct service_test *serv_test) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char ctrl_band_idx = serv_test->ctrl_band_idx; + struct test_configuration *configs; + struct test_operation *ops = serv_test->test_op; + u_int32 rf_freq_offset; + + configs = &serv_test->test_config[ctrl_band_idx]; + + rf_freq_offset = configs->rf_freq_offset; + + ret = ops->op_set_freq_offset( + serv_test->test_winfo, + rf_freq_offset, + ctrl_band_idx); + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_tx_power_operation( + struct service_test *serv_test, u_int32 item) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char ctrl_band_idx = serv_test->ctrl_band_idx; + struct test_configuration *configs; + struct test_wlan_info *winfos = serv_test->test_winfo; + struct test_operation *ops = serv_test->test_op; + struct test_txpwr_param *pwr_param = NULL; + + configs = &serv_test->test_config[ctrl_band_idx]; + if (!configs) + return SERV_STATUS_SERV_TEST_INVALID_NULL_POINTER; + + pwr_param = &configs->pwr_param; + if (!pwr_param) + return SERV_STATUS_SERV_TEST_INVALID_NULL_POINTER; + + if (pwr_param->ant_idx >= TEST_ANT_NUM) + goto error; + + switch (item) { + case SERV_TEST_TXPWR_SET_PWR: + configs->tx_pwr[pwr_param->ant_idx] = pwr_param->power; + ret = ops->op_set_tx_pwr( + winfos, configs, ctrl_band_idx, pwr_param); + break; + + case SERV_TEST_TXPWR_GET_PWR: + ret = ops->op_get_tx_pwr( + winfos, configs, ctrl_band_idx, + configs->channel, (u_char)pwr_param->ant_idx, + &(pwr_param->power)); + break; + + case SERV_TEST_TXPWR_SET_PWR_INIT: + /* TODO: */ + break; + + case SERV_TEST_TXPWR_SET_PWR_MAN: + /* TODO: */ + break; + + default: + return SERV_STATUS_SERV_TEST_INVALID_PARAM; + } + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; + +error: + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_TRACE, + ("%s: invalid parameter for ant_idx(0x%x).\n", + __func__, pwr_param->ant_idx)); + return SERV_STATUS_SERV_TEST_INVALID_PARAM; +} + +s_int32 mt_serv_get_freq_offset( + struct service_test *serv_test, u_int32 *freq_offset) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char ctrl_band_idx = serv_test->ctrl_band_idx; + struct test_operation *ops; + + ops = serv_test->test_op; + ret = ops->op_get_freq_offset( + serv_test->test_winfo, + ctrl_band_idx, + freq_offset); + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_get_cfg_on_off( + struct service_test *serv_test, + u_int32 type, + u_int32 *result) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char ctrl_band_idx = serv_test->ctrl_band_idx; + struct test_operation *ops; + + ops = serv_test->test_op; + ret = ops->op_get_cfg_on_off( + serv_test->test_winfo, + ctrl_band_idx, + type, + result); + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_get_tx_tone_pwr( + struct service_test *serv_test, + u_int32 ant_idx, + u_int32 *power) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char ctrl_band_idx = serv_test->ctrl_band_idx; + struct test_operation *ops; + + ops = serv_test->test_op; + ret = ops->op_get_tx_tone_pwr( + serv_test->test_winfo, + ctrl_band_idx, + ant_idx, + power); + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_get_thermal_val( + struct service_test *serv_test, + u_char band_idx, + u_int32 *value) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char ctrl_band_idx = serv_test->ctrl_band_idx; + struct test_configuration *configs; + struct test_operation *ops; + + configs = &serv_test->test_config[ctrl_band_idx]; + + ops = serv_test->test_op; + ret = ops->op_get_thermal_val( + serv_test->test_winfo, + configs, + ctrl_band_idx, + value); + + /* update config */ + configs->thermal_val = *value; + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_set_cal_bypass( + struct service_test *serv_test, + u_int32 cal_item) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char ctrl_band_idx = serv_test->ctrl_band_idx; + struct test_operation *ops; + + ops = serv_test->test_op; + ret = ops->op_set_cal_bypass( + serv_test->test_winfo, + ctrl_band_idx, + cal_item); + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_set_dpd( + struct service_test *serv_test, + u_int32 on_off, + u_int32 wf_sel) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_operation *ops; + + ops = serv_test->test_op; + ret = ops->op_set_dpd( + serv_test->test_winfo, + on_off, + wf_sel); + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_set_tssi( + struct service_test *serv_test, + u_int32 on_off, + u_int32 wf_sel) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_operation *ops; + + ops = serv_test->test_op; + ret = ops->op_set_tssi( + serv_test->test_winfo, + on_off, + wf_sel); + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_set_rdd_on_off( + struct service_test *serv_test, + u_int32 rdd_num, + u_int32 rdd_sel, + u_int32 enable) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char ctrl_band_idx = serv_test->ctrl_band_idx; + struct test_operation *ops; + struct test_wlan_info *winfos; + + ops = serv_test->test_op; + winfos = serv_test->test_winfo; + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_OFF, + ("%s(): ctrl_band_idx %d, enable %d\n", + __func__, ctrl_band_idx, enable)); + + if (ops->op_set_tr_mac) + ret = ops->op_set_tr_mac(winfos, SERV_TEST_MAC_RX, + enable, ctrl_band_idx); + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: op_set_tr_mac, err=0x%08x\n", __func__, ret)); + + if (ops->op_set_rdd_test) + ops->op_set_rdd_test(winfos, rdd_num, rdd_sel, enable); + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: op_set_rdd_test, err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_set_off_ch_scan( + struct service_test *serv_test) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char ctrl_band_idx = serv_test->ctrl_band_idx; + struct test_configuration *configs; + struct test_wlan_info *winfos = serv_test->test_winfo; + struct test_operation *ops = serv_test->test_op; + struct test_off_ch_param *param = NULL; + + configs = &serv_test->test_config[ctrl_band_idx]; + if (!configs) + return SERV_STATUS_SERV_TEST_INVALID_NULL_POINTER; + + param = &configs->off_ch_param; + if (!param) + return SERV_STATUS_SERV_TEST_INVALID_NULL_POINTER; + + ret = ops->op_set_off_ch_scan( + winfos, configs, ctrl_band_idx, param); + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + + +s_int32 mt_serv_set_icap_start( + struct service_test *serv_test, + struct hqa_rbist_cap_start *icap_info) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_operation *op = serv_test->test_op; + struct test_wlan_info *winfos = serv_test->test_winfo; + + if (op->op_set_icap_start) + ret = op->op_set_icap_start(winfos, (u_int8 *)icap_info); + else + ret = SERV_STATUS_SERV_TEST_NOT_SUPPORTED; + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err = 0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_get_icap_status( + struct service_test *serv_test, + s_int32 *icap_stat) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_operation *op = serv_test->test_op; + struct test_wlan_info *winfos = serv_test->test_winfo; + + if (op->op_get_icap_status) + ret = op->op_get_icap_status(winfos, icap_stat); + else + ret = SERV_STATUS_SERV_TEST_NOT_SUPPORTED; + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err = 0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_get_icap_max_data_len( + struct service_test *serv_test, + u_long *max_data_len) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_operation *op = serv_test->test_op; + struct test_wlan_info *winfos = serv_test->test_winfo; + + if (op->op_get_icap_max_data_len) + ret = op->op_get_icap_max_data_len(winfos, max_data_len); + else + ret = SERV_STATUS_SERV_TEST_NOT_SUPPORTED; + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err = 0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_get_icap_data( + struct service_test *serv_test, + s_int32 *icap_cnt, + s_int32 *icap_data, + u_int32 wf_num, + u_int32 iq_type) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_operation *op = serv_test->test_op; + struct test_wlan_info *winfos = serv_test->test_winfo; + + if (op->op_get_icap_data) + ret = op->op_get_icap_data(winfos, icap_cnt + , icap_data, wf_num, iq_type); + else + ret = SERV_STATUS_SERV_TEST_NOT_SUPPORTED; + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err = 0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_get_recal_cnt( + struct service_test *serv_test, + u_int32 *recal_cnt, + u_int32 *recal_dw_num) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_operation *ops; + + ops = serv_test->test_op; + + ret = ops->op_get_recal_cnt( + serv_test->test_winfo, + recal_cnt, + recal_dw_num); + + return ret; +} + +s_int32 mt_serv_get_recal_content( + struct service_test *serv_test, + u_int32 *content) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_operation *ops; + + ops = serv_test->test_op; + + ret = ops->op_get_recal_content( + serv_test->test_winfo, + content); + + return ret; +} + +s_int32 mt_serv_get_rxv_cnt( + struct service_test *serv_test, + u_int32 *rxv_cnt, + u_int32 *rxv_dw_num) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_wlan_info *winfos; + struct test_operation *ops; + u_char ctrl_band_idx = serv_test->ctrl_band_idx; + + u_int32 byte_cnt = 0; + + if (!serv_test->engine_offload) { + winfos = serv_test->test_winfo; + + /* Note: only support single rxv count report */ + *rxv_cnt = 1; + + /* query rxv byte count */ + ret = net_ad_get_rxv_cnt(winfos, ctrl_band_idx, &byte_cnt); + } else { + ops = serv_test->test_op; + ret = ops->op_get_rxv_cnt( + serv_test->test_winfo, + rxv_cnt, + rxv_dw_num); + } + + return ret; +} + +s_int32 mt_serv_get_rxv_content( + struct service_test *serv_test, + u_int32 dw_cnt, + u_int32 *content) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_wlan_info *winfos; + struct test_operation *ops; + u_char ctrl_band_idx = serv_test->ctrl_band_idx; + + if (!serv_test->engine_offload) { + /* query rxv content */ + winfos = serv_test->test_winfo; + ret = net_ad_get_rxv_content(winfos, ctrl_band_idx, content); + } else { + ops = serv_test->test_op; + ret = ops->op_get_rxv_content( + serv_test->test_winfo, + dw_cnt, + content); + } + + return ret; +} + +s_int32 mt_serv_get_rdd_cnt( + struct service_test *serv_test, + u_int32 *rdd_cnt, + u_int32 *rdd_dw_num) +{ + struct test_operation *ops; + s_int32 ret = SERV_STATUS_SUCCESS; + + ops = serv_test->test_op; + ret = ops->op_get_rdd_cnt( + serv_test->test_winfo, + rdd_cnt, + rdd_dw_num); + + return ret; +} + +s_int32 mt_serv_get_rdd_content( + struct service_test *serv_test, + u_int32 *content, + u_int32 *total_cnt) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_operation *ops; + + ops = serv_test->test_op; + ret = ops->op_get_rdd_content( + serv_test->test_winfo, + content, total_cnt); + + return ret; +} + +s_int32 mt_serv_reset_txrx_counter( + struct service_test *serv_test) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_wlan_info *winfos; + struct test_configuration *config_band0; + struct test_configuration *config_band1; + struct test_rx_stat *test_rx_st; + u_int8 ant_idx = 0, band_idx = 0; + + winfos = serv_test->test_winfo; + config_band0 = &serv_test->test_config[TEST_DBDC_BAND0]; + config_band1 = &serv_test->test_config[TEST_DBDC_BAND1]; + + for (band_idx = TEST_DBDC_BAND0; + band_idx < TEST_DBDC_BAND_NUM; band_idx++) { + test_rx_st = serv_test->test_rx_statistic + band_idx; + sys_ad_zero_mem(test_rx_st, + sizeof(struct test_rx_stat)); + + for (ant_idx = 0; ant_idx < TEST_ANT_NUM; ant_idx++) { + test_rx_st->rx_st_path[ant_idx].rssi = 0xFF; + test_rx_st->rx_st_path[ant_idx].rcpi = 0xFF; + test_rx_st->rx_st_path[ant_idx].fagc_ib_rssi = 0xFF; + test_rx_st->rx_st_path[ant_idx].fagc_wb_rssi = 0xFF; + } + } + + config_band0->tx_stat.tx_done_cnt = 0; + if (IS_TEST_DBDC(winfos)) + config_band1->tx_stat.tx_done_cnt = 0; + + ret = serv_test->test_op->op_reset_txrx_counter( + serv_test->test_winfo); + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_set_rx_vector_idx( + struct service_test *serv_test, u_int32 group1, u_int32 group2) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_operation *ops; + + ops = serv_test->test_op; + ret = ops->op_set_rx_vector_idx( + serv_test->test_winfo, + serv_test->ctrl_band_idx, + group1, + group2); + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_set_fagc_rssi_path( + struct service_test *serv_test) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_operation *ops; + + ops = serv_test->test_op; + ret = ops->op_set_fagc_rssi_path( + serv_test->test_winfo, + serv_test->ctrl_band_idx, + serv_test->test_config[TEST_DBDC_BAND0].fagc_path); + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_get_rx_stat_leg( + struct service_test *serv_test, + struct test_rx_stat_leg *rx_stat) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_operation *ops; + + ops = serv_test->test_op; + ret = ops->op_get_rx_stat_leg( + serv_test->test_winfo, rx_stat); + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_get_rx_stat( + struct service_test *serv_test, + u_int8 band_idx, + u_int8 blk_idx, + u_int8 test_rx_stat_cat, + struct test_rx_stat_u *st) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_operation *ops; + struct test_wlan_info *winfos; + struct test_rx_stat *stat; + boolean dbdc_mode = FALSE; + + ops = serv_test->test_op; + winfos = serv_test->test_winfo; + stat = &serv_test->test_rx_statistic[band_idx]; + + /* check dbdc mode condition */ + dbdc_mode = IS_TEST_DBDC(serv_test->test_winfo); + + /* sanity check for band index param */ + if ((!dbdc_mode) && (band_idx != TEST_DBDC_BAND0)) + goto error1; + + switch (test_rx_stat_cat) { + case TEST_RX_STAT_BAND: + ret = ops->op_get_rx_stat_band( + serv_test->test_winfo, + band_idx, + blk_idx, + stat->rx_st_band + blk_idx); + + sys_ad_move_mem(st, stat->rx_st_band + blk_idx, + sizeof(struct test_rx_stat_band_info)); + break; + case TEST_RX_STAT_PATH: + ret = ops->op_get_rx_stat_path( + serv_test->test_winfo, + band_idx, + blk_idx, + stat->rx_st_path + blk_idx); + + sys_ad_move_mem(st, stat->rx_st_path + blk_idx, + sizeof(struct test_rx_stat_path_info)); + break; + case TEST_RX_STAT_USER: + ret = ops->op_get_rx_stat_user( + serv_test->test_winfo, + band_idx, + blk_idx, + stat->rx_st_user + blk_idx); + + sys_ad_move_mem(st, stat->rx_st_user + blk_idx, + sizeof(struct test_rx_stat_user_info)); + break; + case TEST_RX_STAT_COMM: + ret = ops->op_get_rx_stat_comm( + serv_test->test_winfo, + band_idx, + blk_idx, + &stat->rx_st_comm); + + sys_ad_move_mem(st, &stat->rx_st_comm, + sizeof(struct test_rx_stat_comm_info)); + break; + default: + break; + } + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; + +error1: + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: invalid band index for non-dbdc mode.\n", + __func__)); + return ret; +} + +s_int32 mt_serv_get_capability( + struct service_test *serv_test, + struct test_capability *capability) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_operation *op = serv_test->test_op; + struct test_wlan_info *winfo = serv_test->test_winfo; + + ret = op->op_get_capability(winfo, capability); + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_calibration_test_mode( + struct service_test *serv_test, u_char mode) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_operation *op = serv_test->test_op; + struct test_wlan_info *winfo = serv_test->test_winfo; + + ret = op->op_calibration_test_mode(winfo, mode); + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_do_cal_item( + struct service_test *serv_test, u_int32 item) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char ctrl_band_idx = serv_test->ctrl_band_idx; + + ret = serv_test->test_op->op_do_cal_item( + serv_test->test_winfo, + item, ctrl_band_idx); + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_set_band_mode( + struct service_test *serv_test) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_operation *ops; + + ops = serv_test->test_op; + + if (!serv_test->engine_offload) { + ret = net_ad_set_band_mode( + serv_test->test_winfo, + &serv_test->test_bstat); + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + } else { + ret = ops->op_set_band_mode( + serv_test->test_winfo, + &serv_test->test_bstat); + } + + return ret; +} + +s_int32 mt_serv_get_band_mode( + struct service_test *serv_test) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char ctrl_band_idx = serv_test->ctrl_band_idx; + u_int32 band_type; + struct test_operation *ops; + + ops = serv_test->test_op; + + if (!serv_test->engine_offload) { + /* + * DLL will query two times per band0/band1 if DBDC chip set. + * 0: no this band + * 1: 2.4G + * 2: 5G + * 3. 2.4G+5G + */ + if (IS_TEST_DBDC(serv_test->test_winfo)) + band_type = (ctrl_band_idx == TEST_DBDC_BAND0) + ? TEST_BAND_TYPE_G : TEST_BAND_TYPE_A; + else { + /* Always report 2.4+5G*/ + band_type = TEST_BAND_TYPE_ALL; + + /* + * If IS_TEST_DBDC=0, + * band_idx should not be 1 so return band_mode=0 + */ + if (ctrl_band_idx == TEST_DBDC_BAND1) + band_type = TEST_BAND_TYPE_UNUSE; + } + + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: band_type=%u\n", __func__, band_type)); + } else { + ret = ops->op_set_band_mode( + serv_test->test_winfo, + &serv_test->test_bstat); + + if (ctrl_band_idx == TEST_DBDC_BAND0) + band_type = TEST_BAND_TYPE_ALL; + else { + if (serv_test->test_bstat.band_mode == + TEST_BAND_MODE_DUAL) + band_type = TEST_BAND_TYPE_ALL; + else + band_type = TEST_BAND_TYPE_UNUSE; + } + } + + BSTATE_SET_PARAM(serv_test, band_type, band_type); + + return ret; +} + +s_int32 mt_serv_log_on_off( + struct service_test *serv_test, u_int32 log_type, + u_int32 log_ctrl, u_int32 log_size) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_operation *ops; + + ops = serv_test->test_op; + ret = ops->op_log_on_off( + serv_test->test_winfo, + serv_test->ctrl_band_idx, + log_type, + log_ctrl, + log_size); + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + + +s_int32 mt_serv_set_cfg_on_off( + struct service_test *serv_test) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_configuration *configs; + u_char ctrl_band_idx = serv_test->ctrl_band_idx; + struct test_operation *ops; + + configs = &serv_test->test_config[ctrl_band_idx]; + + ops = serv_test->test_op; + ret = ops->op_set_cfg_on_off( + serv_test->test_winfo, + (u_int8)configs->log_type, + (u_int8)configs->log_enable, + ctrl_band_idx); + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_set_rx_filter_pkt_len(struct service_test *serv_test) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_configuration *configs; + struct test_operation *ops; + + configs = &serv_test->test_config[serv_test->ctrl_band_idx]; + ops = serv_test->test_op; + ret = ops->op_set_rx_filter_pkt_len( + serv_test->test_winfo, + configs->rx_filter_en, + serv_test->ctrl_band_idx, + configs->rx_filter_pkt_len); + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_set_low_power( + struct service_test *serv_test, u_int32 control) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + ret = net_ad_set_low_power(serv_test->test_winfo, control); + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_get_antswap_capability( + struct service_test *serv_test, u_int32 *antswap_support) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + struct test_operation *ops; + + ops = serv_test->test_op; + + ret = ops->op_get_antswap_capability( + serv_test->test_winfo, + antswap_support); + + return ret; +} + +s_int32 mt_serv_set_antswap( + struct service_test *serv_test, u_int32 ant) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + struct test_operation *ops; + + ops = serv_test->test_op; + + ret = ops->op_set_antswap( + serv_test->test_winfo, + ant); + + return ret; +} + +s_int32 mt_serv_reg_eprm_operation( + struct service_test *serv_test, u_int32 item) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_operation *ops; + + ops = serv_test->test_op; + + switch (item) { + case SERV_TEST_REG_MAC_READ: + if (!serv_test->engine_offload) { + ret = net_ad_read_mac_bbp_reg(serv_test->test_winfo, + &serv_test->test_reg); + } else { + ops = serv_test->test_op; + ret = ops->op_read_bulk_mac_bbp_reg( + serv_test->test_winfo, + &serv_test->test_reg); + } + break; + + case SERV_TEST_REG_MAC_WRITE: + if (!serv_test->engine_offload) { + + ret = net_ad_write_mac_bbp_reg(serv_test->test_winfo, + &serv_test->test_reg); + } else { + ops = serv_test->test_op; + ret = ops->op_write_mac_bbp_reg(serv_test->test_winfo, + &serv_test->test_reg); + } + break; + + case SERV_TEST_REG_MAC_READ_BULK: + if (!serv_test->engine_offload) { + ret = net_ad_read_bulk_mac_bbp_reg( + serv_test->test_winfo, + &serv_test->test_config[TEST_DBDC_BAND0], + &serv_test->test_reg); + } else { + ops = serv_test->test_op; + ret = ops->op_read_bulk_mac_bbp_reg( + serv_test->test_winfo, + &serv_test->test_reg); + } + break; + + case SERV_TEST_REG_RF_READ_BULK: + if (!serv_test->engine_offload) { + ret = net_ad_read_bulk_rf_reg(serv_test->test_winfo, + &serv_test->test_reg); + } else { + ops = serv_test->test_op; + ret = ops->op_read_bulk_rf_reg(serv_test->test_winfo, + &serv_test->test_reg); + } + break; + + case SERV_TEST_REG_RF_WRITE_BULK: + if (!serv_test->engine_offload) { + ret = net_ad_write_bulk_rf_reg(serv_test->test_winfo, + &serv_test->test_reg); + } else { + ops = serv_test->test_op; + ret = ops->op_write_bulk_rf_reg(serv_test->test_winfo, + &serv_test->test_reg); + } + break; + + case SERV_TEST_REG_CA53_READ: + net_ad_read_ca53_reg(&serv_test->test_reg); + break; + + case SERV_TEST_REG_CA53_WRITE: + net_ad_write_ca53_reg(&serv_test->test_reg); + break; + + case SERV_TEST_EEPROM_READ: + ret = net_ad_read_write_eeprom(serv_test->test_winfo, + &serv_test->test_eprm, + TRUE); + break; + + case SERV_TEST_EEPROM_WRITE: + ret = net_ad_read_write_eeprom(serv_test->test_winfo, + &serv_test->test_eprm, + FALSE); + break; + + case SERV_TEST_EEPROM_READ_BULK: + if (!serv_test->engine_offload) { + ret = net_ad_read_write_bulk_eeprom(serv_test->test_winfo, + &serv_test->test_eprm, + TRUE); + } else { + ops = serv_test->test_op; + ret = ops->op_read_bulk_eeprom(serv_test->test_winfo, + &serv_test->test_eprm); + } + break; + + case SERV_TEST_EEPROM_WRITE_BULK: + ret = net_ad_read_write_bulk_eeprom(serv_test->test_winfo, + &serv_test->test_eprm, + FALSE); + break; + + case SERV_TEST_EEPROM_GET_FREE_EFUSE_BLOCK: + ret = net_ad_get_free_efuse_block(serv_test->test_winfo, + &serv_test->test_eprm); + break; + + default: + return SERV_STATUS_SERV_TEST_INVALID_PARAM; + } + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_mps_operation( + struct service_test *serv_test, u_int32 item) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char ctrl_band_idx = serv_test->ctrl_band_idx; + + if (!serv_test->engine_offload) { + switch (item) { + case SERV_TEST_MPS_START_TX: + ret = net_ad_mps_tx_operation(serv_test->test_winfo, + &serv_test->test_config[ctrl_band_idx], + TRUE); + + if (ret) + return ret; + + ret = mt_engine_start_tx(serv_test->test_winfo, + &serv_test->test_config[ctrl_band_idx], + serv_test->test_op, ctrl_band_idx); + break; + + case SERV_TEST_MPS_STOP_TX: + ret = net_ad_mps_tx_operation(serv_test->test_winfo, + &serv_test->test_config[ctrl_band_idx], + FALSE); + break; + + default: + return SERV_STATUS_SERV_TEST_INVALID_PARAM; + } + } else { + switch (item) { + case SERV_TEST_MPS_START_TX: + ret = serv_test->test_op->op_mps_start( + serv_test->test_winfo, + ctrl_band_idx); + break; + + case SERV_TEST_MPS_STOP_TX: + ret = serv_test->test_op->op_stop_tx( + serv_test->test_winfo, + ctrl_band_idx); + break; + + default: + return SERV_STATUS_SERV_TEST_INVALID_PARAM; + } + + } + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_get_chipid( + struct service_test *serv_test) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + ret = serv_test->test_op->op_get_chipid( + serv_test->test_winfo); + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_mps_set_nss( + struct service_test *serv_test) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char ctrl_band_idx = serv_test->ctrl_band_idx; + struct test_configuration *test_config; + struct test_mps_cb *mps_cb; + u_int32 len; + + test_config = &serv_test->test_config[ctrl_band_idx]; + mps_cb = &test_config->mps_cb; + len = mps_cb->mps_cnt; + + ret = serv_test->test_op->op_mps_set_nss( + serv_test->test_winfo, + mps_cb->mps_cnt, + mps_cb->mps_setting); + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_mps_set_per_packet_bw( + struct service_test *serv_test) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char ctrl_band_idx = serv_test->ctrl_band_idx; + struct test_configuration *test_config; + struct test_mps_cb *mps_cb; + u_int32 len; + + test_config = &serv_test->test_config[ctrl_band_idx]; + mps_cb = &test_config->mps_cb; + len = mps_cb->mps_cnt; + + ret = serv_test->test_op->op_mps_set_per_packet_bw( + serv_test->test_winfo, + mps_cb->mps_cnt, + mps_cb->mps_setting); + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_mps_set_packet_count( + struct service_test *serv_test) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char ctrl_band_idx = serv_test->ctrl_band_idx; + struct test_configuration *test_config; + struct test_mps_cb *mps_cb; + u_int32 len; + + test_config = &serv_test->test_config[ctrl_band_idx]; + mps_cb = &test_config->mps_cb; + len = mps_cb->mps_cnt; + + ret = serv_test->test_op->op_mps_set_packet_count( + serv_test->test_winfo, + mps_cb->mps_cnt, + mps_cb->mps_setting); + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + + +s_int32 mt_serv_mps_set_payload_length( + struct service_test *serv_test) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char ctrl_band_idx = serv_test->ctrl_band_idx; + struct test_configuration *test_config; + struct test_mps_cb *mps_cb; + u_int32 len; + + test_config = &serv_test->test_config[ctrl_band_idx]; + mps_cb = &test_config->mps_cb; + len = mps_cb->mps_cnt; + + ret = serv_test->test_op->op_mps_set_payload_length( + serv_test->test_winfo, + mps_cb->mps_cnt, + mps_cb->mps_setting); + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + + +s_int32 mt_serv_mps_set_power_gain( + struct service_test *serv_test) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char ctrl_band_idx = serv_test->ctrl_band_idx; + struct test_configuration *test_config; + struct test_mps_cb *mps_cb; + u_int32 len; + + test_config = &serv_test->test_config[ctrl_band_idx]; + mps_cb = &test_config->mps_cb; + len = mps_cb->mps_cnt; + + ret = serv_test->test_op->op_mps_set_power_gain( + serv_test->test_winfo, + mps_cb->mps_cnt, + mps_cb->mps_setting); + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_mps_set_seq_data( + struct service_test *serv_test) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char ctrl_band_idx = serv_test->ctrl_band_idx; + struct test_configuration *test_config; + struct test_mps_cb *mps_cb; + u_int32 len; + + test_config = &serv_test->test_config[ctrl_band_idx]; + mps_cb = &test_config->mps_cb; + len = mps_cb->mps_cnt; + + if (!serv_test->engine_offload) { + + } else { + ret = serv_test->test_op->op_mps_set_seq_data( + serv_test->test_winfo, + mps_cb->mps_cnt, + mps_cb->mps_setting); + } + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_set_tmr(struct service_test *serv_test) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + ret = net_ad_set_tmr(serv_test->test_winfo, &serv_test->test_tmr); + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_set_preamble(struct service_test *serv_test) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char ctrl_band_idx = serv_test->ctrl_band_idx; + u_char tx_mode = serv_test->test_config[ctrl_band_idx].tx_mode; + + if (!serv_test->engine_offload) { + + } else { + ret = serv_test->test_op->op_set_preamble( + serv_test->test_winfo, + tx_mode); + } + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_set_rate(struct service_test *serv_test) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char ctrl_band_idx = serv_test->ctrl_band_idx; + u_char mcs = serv_test->test_config[ctrl_band_idx].mcs; + + if (!serv_test->engine_offload) { + + } else { + ret = serv_test->test_op->op_set_rate( + serv_test->test_winfo, + mcs); + } + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_set_system_bw(struct service_test *serv_test) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char ctrl_band_idx = serv_test->ctrl_band_idx; + u_char sys_bw = serv_test->test_config[ctrl_band_idx].bw; + + if (!serv_test->engine_offload) { + + } else { + ret = serv_test->test_op->op_set_system_bw( + serv_test->test_winfo, + sys_bw); + } + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_set_per_pkt_bw(struct service_test *serv_test) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char ctrl_band_idx = serv_test->ctrl_band_idx; + u_char per_pkt_bw = serv_test->test_config[ctrl_band_idx].per_pkt_bw; + + if (!serv_test->engine_offload) { + + } else { + ret = serv_test->test_op->op_set_per_pkt_bw( + serv_test->test_winfo, + per_pkt_bw); + } + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_dbdc_tx_tone(struct service_test *serv_test) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char ctrl_band_idx = serv_test->ctrl_band_idx; + struct test_configuration *configs; + + configs = &serv_test->test_config[ctrl_band_idx]; + + ret = serv_test->test_op->op_dbdc_tx_tone( + serv_test->test_winfo, + ctrl_band_idx, + configs); + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_dbdc_tx_tone_pwr(struct service_test *serv_test) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char ctrl_band_idx = serv_test->ctrl_band_idx; + struct test_configuration *configs; + + configs = &serv_test->test_config[ctrl_band_idx]; + + ret = serv_test->test_op->op_dbdc_tx_tone_pwr( + serv_test->test_winfo, + ctrl_band_idx, + configs); + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_dbdc_continuous_tx(struct service_test *serv_test) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_char ctrl_band_idx = serv_test->ctrl_band_idx; + struct test_configuration *configs; + + configs = &serv_test->test_config[ctrl_band_idx]; + + ret = serv_test->test_op->op_dbdc_continuous_tx( + serv_test->test_winfo, + ctrl_band_idx, + configs); + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_get_tx_info(struct service_test *serv_test) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_configuration *test_configs_band0; + struct test_configuration *test_configs_band1; + + test_configs_band0 = &serv_test->test_config[TEST_DBDC_BAND0]; + test_configs_band1 = &serv_test->test_config[TEST_DBDC_BAND1]; + + ret = serv_test->test_op->op_get_tx_info( + serv_test->test_winfo, + test_configs_band0, + test_configs_band1); + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_get_wf_path_comb( + struct service_test *serv_test, + u_int8 band_idx, + boolean dbdc_mode_en, + u_int8 *path, + u_int8 *path_len +) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_configuration *test_configs; + + test_configs = &serv_test->test_config[TEST_DBDC_BAND0]; + + ret = serv_test->test_op->op_get_wf_path_comb( + serv_test->test_winfo, + band_idx, + dbdc_mode_en, + path, + path_len); + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_serv_main(struct service_test *serv_test, u_int32 test_item) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + + switch (test_item) { + case SERV_TEST_ITEM_INIT: + ret = mt_serv_init_test(serv_test); + break; + + case SERV_TEST_ITEM_EXIT: + ret = mt_serv_exit_test(serv_test); + break; + + case SERV_TEST_ITEM_START: + ret = mt_serv_start(serv_test); + break; + + case SERV_TEST_ITEM_STOP: + ret = mt_serv_stop(serv_test); + break; + + case SERV_TEST_ITEM_START_TX: + ret = mt_serv_start_tx(serv_test); + break; + + case SERV_TEST_ITEM_STOP_TX: + ret = mt_serv_stop_tx(serv_test); + break; + + case SERV_TEST_ITEM_START_RX: + ret = mt_serv_start_rx(serv_test); + break; + + case SERV_TEST_ITEM_STOP_RX: + ret = mt_serv_stop_rx(serv_test); + break; + + default: + return SERV_STATUS_SERV_TEST_NOT_SUPPORTED; + } + + if (ret) + SERV_LOG(SERV_DBG_CAT_TEST, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} diff --git a/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/service/test_engine.c b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/service/test_engine.c new file mode 100644 index 0000000000000000000000000000000000000000..0fe0faf5302bed78561f97315db28409f752cd04 --- /dev/null +++ b/drivers/misc/mediatek/connectivity/wlan/core/gen4m/wlan_service/service/test_engine.c @@ -0,0 +1,2894 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#include "test_engine.h" + +static u_int8 sigext_time_list[] = { + 0, /* CCK */ + 6, /* OFDM */ + 6, /* HTMIX */ + 6, /* HTGREENFIELD */ + 6, /* VHT */ +}; + +static u_int16 slot_time_list[] = { + 9, /* CCK */ + 9, /* OFDM */ + 9, /* HTMIX */ + 9, /* HTGREENFIELD */ + 9, /* VHT */ +}; + +struct test_data_rate_map cck_mode_map[] = { + {0, 1000}, + {1, 2000}, + {2, 5500}, + {3, 11000}, + {9, 2000}, + {10, 5500}, + {11, 11000}, +}; + +struct test_data_rate_map ofdm_mode_map[] = { + {0, 6000}, + {1, 9000}, + {2, 12000}, + {3, 18000}, + {4, 24000}, + {5, 36000}, + {6, 48500}, + {7, 54000}, +}; + +struct test_data_rate_map n_mode_map[] = { + {0, 6500}, + {1, 13000}, + {2, 19500}, + {3, 26000}, + {4, 39000}, + {5, 52000}, + {6, 58500}, + {7, 65000}, + {32, 6000}, /* MCS32 */ +}; + +struct test_data_rate_map ac_mode_map_bw20[] = { + {0, 65}, /* in unit of 100k */ + {1, 130}, + {2, 195}, + {3, 260}, + {4, 390}, + {5, 520}, + {6, 585}, + {7, 650}, + {8, 780}, +}; + +struct test_data_rate_map ac_mode_map_bw40[] = { + {0, 135}, /* in unit of 100k */ + {1, 270}, + {2, 405}, + {3, 540}, + {4, 810}, + {5, 1080}, + {6, 1215}, + {7, 1350}, + {8, 1620}, + {9, 1800}, +}; + +struct test_data_rate_map ac_mode_map_bw80[] = { + {0, 293}, /* in unit of 100k */ + {1, 585}, + {2, 878}, + {3, 1170}, + {4, 1755}, + {5, 2340}, + {6, 2633}, + {7, 2925}, + {8, 3510}, + {9, 3900}, +}; + +struct test_data_rate_map ac_mode_map_bw160[] = { + {0, 585}, /* in unit of 100k */ + {1, 1170}, + {2, 1755}, + {3, 2340}, + {4, 3510}, + {5, 4680}, + {6, 5265}, + {7, 5850}, + {8, 7020}, + {9, 7800}, +}; + +/* phy rates comes from NSS = 1, Long GI */ +static struct test_data_rate_map he_su_mode_map_bw20[] = { + /*index, nss1, nss2, nss3, nss4*/ + {0, 73}, /* in unit of 100k */ + {1, 146}, + {2, 219}, + {3, 293}, + {4, 439}, + {5, 585}, + {6, 658}, + {7, 731}, + {8, 878}, + {9, 975}, + {10, 1097}, + {11, 1219}, + {33, 36}, /* MCS0 DCM */ + {34, 73}, /* MCS1 DCM */ +}; + +static struct test_data_rate_map he_su_mode_map_bw40[] = { + /*index, nss1{0.8gi, 1.6gi, 3.2gi}, nss2{0.8gi, 1.6gi, 3.2gi}, + *nss3{0.8gi, 1.6gi, 3.2gi}, nss4{0.8gi, 1.6gi, 3.2gi} + */ + {0, 146}, /* in unit of 100k */ + {1, 293}, + {2, 439}, + {3, 585}, + {4, 878}, + {5, 1170}, + {6, 1316}, + {7, 1463}, + {8, 1755}, + {9, 1950}, + {10, 2194}, + {11, 2438}, + {33, 73}, /* MCS0 DCM */ + {34, 146}, /* MCS1 DCM */ +}; + + +static struct test_data_rate_map he_su_mode_map_bw80[] = { + /*index, nss1{0.8gi, 1.6gi, 3.2gi}, nss2{0.8gi, 1.6gi, 3.2gi}, + * nss3{0.8gi, 1.6gi, 3.2gi}, nss4{0.8gi, 1.6gi, 3.2gi} + */ + {0, 306}, /* in unit of 100k */ + {1, 613}, + {2, 919}, + {3, 1225}, + {4, 1838}, + {5, 2450}, + {6, 2756}, + {7, 3063}, + {8, 3675}, + {9, 4083}, + {10, 4594}, + {11, 5104}, + {33, 153}, /* MCS0 DCM */ + {34, 306}, /* MCS1 DCM */ +}; + +static struct test_data_rate_map he_su_mode_map_bw160[] = { + /*index, nss1{0.8gi, 1.6gi, 3.2gi}, nss2{0.8gi, 1.6gi, 3.2gi}, + *nss3{0.8gi, 1.6gi, 3.2gi}, nss4{0.8gi, 1.6gi, 3.2gi} + */ + {0, 613}, /* in unit of 100k */ + {1, 1225}, + {2, 1838}, + {3, 2450}, + {4, 3675}, + {5, 4900}, + {6, 5513}, + {7, 6125}, + {8, 7350}, + {9, 8166}, + {10, 9188}, + {11, 10208}, + {33, 306}, /* MCS0 DCM */ + {34, 613}, /* MCS1 DCM */ +}; + +static struct test_datalen_limit_map datalen_limit[] = { + {TEST_MODE_CCK, 2304}, + {TEST_MODE_OFDM, 2304}, + {TEST_MODE_HTMIX, 7935}, + {TEST_MODE_HTGREENFIELD, 7935}, + {TEST_MODE_VHT, 11454}, + {0}, /* reserved */ + {0}, /* reserved */ + {0}, /* reserved */ + {TEST_MODE_HE_SU, 11454}, + {TEST_MODE_HE_ER, 11454}, + {TEST_MODE_HE_MU, 11454}, + {TEST_MODE_HE_TB, 11454}, + {TEST_MODE_VHT_MIMO, 11454}, +}; + +static u_int8 test_he_bpscs[] = { + 1, 2, 2, 4, 4, 6, 6, 6, 8, 8, 10, 10 /* MCS0~11 */ +}; + +static u_int8 test_he_rate_density[] = { + 2, 2, 4, 2, 4, 3, 4, 6, 4, 6, 4, 6 /* MCS0~11 */ +}; + +static u_int8 test_ltf_sym[] = { + 0, 1, 2, 4, 4, 6, 6, 8, 8 /* SS 1~8 */ +}; + +static u_int8 test_he_t_ltf_sym_x5[] = { + 24, 40, 80 /* 3.2+1.6 us, 6.4+1.6, 12.8+3.2 */ +}; + +static u_int8 test_he_t_sym_x5[] = { + 68, 72, 80 /* base GI, double GI, quadruple GI */ +}; + +static u_int8 test_he_t_pe_x5[] = { + 0, 20, 40, 60, 80 /* 0us, 4us, 8us, 12us, 16us */ +}; + +static struct test_he_ru_const test_ru_const[] = { + {37, 24, 12, 6, 2}, + {53, 48, 24, 12, 6}, + {61, 102, 51, 24, 12}, + {65, 234, 117, 60, 30}, + {67, 468, 234, 120, 60}, + {68, 980, 490, 240, 120}, + {69, 1960, 980, 492, 246} +}; + +/***************************************************************************** + * Internal functions + *****************************************************************************/ +static s_int32 mt_engine_init_mps( + struct test_configuration *configs) +{ + struct test_mps_cb *mps_cb = NULL; + + mps_cb = &configs->mps_cb; + + if (mps_cb->mps_setting) + sys_ad_free_mem(mps_cb->mps_setting); + + sys_ad_zero_mem(mps_cb, sizeof(*mps_cb)); + mps_cb->setting_inuse = FALSE; + mps_cb->mps_cnt = 0; + mps_cb->stat = 0; + mps_cb->ref_idx = 1; + mps_cb->mps_setting = NULL; + SERV_OS_ALLOCATE_SPIN_LOCK(&mps_cb->lock); + + return SERV_STATUS_SUCCESS; +} + +static s_int32 mt_engine_release_mps( + struct test_configuration *configs) +{ + struct test_mps_cb *mps_cb = NULL; + + mps_cb = &configs->mps_cb; + + if (mps_cb->mps_setting) + sys_ad_free_mem(mps_cb->mps_setting); + + mps_cb->mps_setting = NULL; + mps_cb->setting_inuse = FALSE; + mps_cb->mps_cnt = 0; + mps_cb->stat = 0; + mps_cb->ref_idx = 1; + SERV_OS_FREE_SPIN_LOCK(&mps_cb->lock); + + return SERV_STATUS_SUCCESS; +} + +static u_int8 mt_engine_get_sigext_time_by_phymode(u_char tx_mode) +{ + u_int8 sigext_time = 0; + + switch (tx_mode) { + case TEST_MODE_CCK: + sigext_time = sigext_time_list[TEST_MODE_CCK]; + break; + + case TEST_MODE_OFDM: + sigext_time = sigext_time_list[TEST_MODE_OFDM]; + break; + + case TEST_MODE_HTMIX: + sigext_time = sigext_time_list[TEST_MODE_HTMIX]; + break; + + case TEST_MODE_HTGREENFIELD: + sigext_time = sigext_time_list[TEST_MODE_HTGREENFIELD]; + break; + + case TEST_MODE_VHT: + sigext_time = sigext_time_list[TEST_MODE_VHT]; + break; + + default: + sigext_time = sigext_time_list[TEST_MODE_OFDM]; + break; + } + + return sigext_time; +} + +static u_int16 mt_engine_get_slot_time_by_phymode(u_char tx_mode) +{ + u_int16 slot_time = 0; + + switch (tx_mode) { + case TEST_MODE_CCK: + slot_time = slot_time_list[TEST_MODE_CCK]; + break; + + case TEST_MODE_OFDM: + slot_time = slot_time_list[TEST_MODE_OFDM]; + break; + + case TEST_MODE_HTMIX: + slot_time = slot_time_list[TEST_MODE_HTMIX]; + break; + + case TEST_MODE_HTGREENFIELD: + slot_time = slot_time_list[TEST_MODE_HTGREENFIELD]; + break; + + case TEST_MODE_VHT: + slot_time = slot_time_list[TEST_MODE_VHT]; + break; + + default: + slot_time = slot_time_list[TEST_MODE_OFDM]; + break; + } + + return slot_time; +} + +static u_int8 mt_engine_trans_gi(u_int8 tx_mode, u_int32 ltf_gi) +{ + u_int8 gi_type = 0; + + if (tx_mode == TEST_MODE_HE_SU || + tx_mode == TEST_MODE_HE_ER || + tx_mode == TEST_MODE_HE_MU) { + switch (ltf_gi) { + case 1: + case 2: + gi_type = TEST_GI_8+(ltf_gi-1); + break; + case 3: + case 4: + gi_type = TEST_GI_8+((ltf_gi-3) ? 0:2); + break; + default: + gi_type = TEST_GI_8; + break; + } + } else if (tx_mode == TEST_MODE_HE_TB) { + switch (ltf_gi) { + case 2: + gi_type = TEST_GI_32; + break; + default: + gi_type = TEST_GI_16; + break; + } + } else /* for non-HE PPDU types, gi equavalent to Sgi. */ + gi_type = ltf_gi; + + return gi_type; +} + +static u_int8 mt_engine_trans_ltf(u_int8 tx_mode, u_int32 ltf_gi) +{ + u_int8 ltf_type = 0; + + if (tx_mode == TEST_MODE_HE_SU || tx_mode == TEST_MODE_HE_ER) { + switch (ltf_gi) { + case 1: + case 2: + ltf_type = TEST_HE_LTF_X2; + break; + case 3: + case 4: + ltf_type = TEST_HE_LTF_X4; + break; + default: + ltf_type = TEST_HE_LTF_X1; + break; + } + } else if (tx_mode == TEST_MODE_HE_MU) { + switch (ltf_gi) { + case 0: + case 3: + ltf_type = TEST_HE_LTF_X4; + break; + default: + ltf_type = TEST_HE_LTF_X2; + break; + } + } else if (tx_mode == TEST_MODE_HE_TB) { + ltf_type = ltf_gi; + } else /* for non-HE PPDU types, ltf is not required. */ + ltf_type = 0; + + return ltf_type; +} + + +static u_int16 mt_engine_get_cw(u_int32 ipg, u_int16 slot_time) +{ + u_int32 cnt = 0, val; + + val = (ipg + slot_time) / slot_time; + + while (val >>= 1) + cnt++; + + if (cnt >= TEST_MAX_CW) + cnt = TEST_MAX_CW; + + return cnt; +} + +static s_int32 mt_engine_calc_duty_cycle(struct test_configuration *configs) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct ipg_param *ipg_param; + struct tx_time_param *tx_time_param; + u_int32 ipg, pkt_tx_time, duty_cycle; + + ipg_param = &configs->ipg_param; + tx_time_param = &configs->tx_time_param; + + ipg = ipg_param->ipg; + pkt_tx_time = tx_time_param->pkt_tx_time; + duty_cycle = configs->duty_cycle; + + /* Calculate needed ipg/pkt_tx_time and duty_cycle */ + if ((duty_cycle > 0) && (pkt_tx_time == 0) && (ipg == 0)) { + /* TODO: need to consider this case in the future */ + duty_cycle = 0; + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_OFF, + ("%s: there are no pkt_tx_time/ipg!! ", + __func__)); + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_OFF, + ("use default setting and set duty_cycle=%d\n", + duty_cycle)); + } else if ((duty_cycle > 0) && (pkt_tx_time > 0) && (ipg == 0)) { + ipg = ((pkt_tx_time * 100) / duty_cycle) - pkt_tx_time; + ipg_param->ipg = ipg; + /* + * If ipg value does't make sense, + * there's error handle when get ipg parameter + */ + ret = mt_engine_calc_ipg_param_by_ipg(configs); + if (ret) { + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_ERROR, + ("%s: calculate ipg_param fail!!\n", + __func__)); + } + } else if ((duty_cycle > 0) && (pkt_tx_time == 0) && (ipg > 0)) { + /* + * If pkt_tx_time does't make sense, + * there's error handle when start tx + */ + pkt_tx_time = (duty_cycle * ipg) / (100 - duty_cycle); + } else { + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_OFF, + ("%s: already existed pkt_tx_time/ipg, ", + __func__)); + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_OFF, + ("can't set duty_cycle!! ")); + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_OFF, + ("expected duty_cycle=%d%%\n", duty_cycle)); + + duty_cycle = (pkt_tx_time * 100) / (pkt_tx_time + ipg); + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_OFF, + ("%s: real duty_cycle=%d%%\n", __func__, duty_cycle)); + } + + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_OFF, + ("%s: duty_cycle=%d%%, ipg=%dus, pkt_tx_time=%dus\n", + __func__, duty_cycle, ipg, pkt_tx_time)); + + tx_time_param->pkt_tx_time = pkt_tx_time; + configs->duty_cycle = duty_cycle; + + return ret; +} + +static s_int32 mt_engine_map_subcarriers( + u_int8 ru_index, u_int8 dcm) +{ + s_int32 subcarriers = 0, idx = 0; + + for (idx = 0 ; idx < SERV_ARRAY_SIZE(test_ru_const) ; idx++) { + if (ru_index < test_ru_const[idx].max_index) { + if (dcm) + subcarriers = test_ru_const[idx].sd_d; + else + subcarriers = test_ru_const[idx].sd; + + break; + } + } + + return subcarriers; +} + +static s_int32 mt_engine_map_subcarriers_short( + u_int8 ru_index, u_int8 dcm) +{ + s_int32 subcarriers_short = 0, idx = 0; + + for (idx = 0 ; idx < SERV_ARRAY_SIZE(test_ru_const) ; idx++) { + if (ru_index < test_ru_const[idx].max_index) { + if (dcm) + subcarriers_short = test_ru_const[idx].sd_s_d; + else + subcarriers_short = test_ru_const[idx].sd_s; + + break; + } + } + + return subcarriers_short; +} + +static s_int32 mt_engine_calc_bytes_by_time( + u_char tx_mode, u_char nss, u_char t_pe, u_char ltf, + u_char gi, s_int32 dbps, s_int32 tx_time) +{ + u_int8 m_stbc = 1, tail = 6; + u_int32 data_time = 0; + u_int32 symbol_cnt = 0, psdu_length = 0; + u_int32 ltf_time = test_ltf_sym[nss]*test_he_t_ltf_sym_x5[ltf]; + + data_time = tx_time*5; + data_time -= (5 * 20 + (20+40+40+ltf_time) + test_he_t_pe_x5[t_pe]); + symbol_cnt = engine_ceil(data_time, test_he_t_sym_x5[gi]); + + if (symbol_cnt > 0x3fff) /* H/W limitation */ + symbol_cnt = 0x3fff; + + psdu_length = ((symbol_cnt / m_stbc) * dbps - 16 - tail) / 8; + + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_OFF, + ("\t%s: \tsymbol=%d, PSDU length:%d\n", + __func__, symbol_cnt, psdu_length)); + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_OFF, + ("\t\t: \t(0x3fff is H/W limiation)\n")); + + return psdu_length; +} + +static u_int32 mt_engine_calc_txlen( + struct test_configuration *configs) +{ + struct tx_time_param *tx_time_param; + u_int32 txlen = 0, hlen = 0, tx_data_rate = 0, pkt_tx_time = 0; + u_char tx_mode, mcs, mcs_1ss, nss = 1; + u_char bw = 0, bw_fact = 1, sgi = 0; + + /* + * 1. Get the tx data rate + * 2. Get the packet tx time + * 3. Calculate the packet length by tx_data_rate and packet_tx_time + * 4. Return txlen + */ + tx_time_param = &configs->tx_time_param; + pkt_tx_time = tx_time_param->pkt_tx_time; + hlen = configs->hdr_len; + tx_mode = configs->tx_mode; + mcs = configs->mcs; + bw = configs->bw; + sgi = configs->sgi; + mcs_1ss = mcs; + + if (tx_mode == TEST_MODE_CCK) { + /* Legacy CCK mode */ + u_int8 cck_map_idx; + + for (cck_map_idx = 0; + cck_map_idx < SERV_ARRAY_SIZE(cck_mode_map); + cck_map_idx++) { + if (mcs_1ss == cck_mode_map[cck_map_idx].mcs) + break; + } + + if (cck_map_idx == SERV_ARRAY_SIZE(cck_mode_map)) { + tx_data_rate = cck_mode_map[0].tx_data_rate; + mcs = mcs_1ss = cck_mode_map[0].mcs; + configs->mcs = mcs; + } else + tx_data_rate = cck_mode_map[cck_map_idx].tx_data_rate; + + /* Transfer from bit to byte with expected tx time */ + txlen = pkt_tx_time * tx_data_rate / 1000 / 8; + } else if (tx_mode == TEST_MODE_OFDM) { + /* Legacy OFDM mode */ + u_int8 ofdm_map_idx; + + for (ofdm_map_idx = 0; + ofdm_map_idx < SERV_ARRAY_SIZE(ofdm_mode_map); + ofdm_map_idx++) { + if (mcs_1ss == ofdm_mode_map[ofdm_map_idx].mcs) + break; + } + + if (ofdm_map_idx == SERV_ARRAY_SIZE(ofdm_mode_map)) { + tx_data_rate = ofdm_mode_map[0].tx_data_rate; + mcs = mcs_1ss = ofdm_mode_map[0].mcs; + configs->mcs = mcs; + } else + tx_data_rate = ofdm_mode_map[ofdm_map_idx].tx_data_rate; + + /* Transfer from bit to byte with expected tx time */ + txlen = pkt_tx_time * tx_data_rate / 1000 / 8; + } else if (tx_mode == TEST_MODE_HTMIX + || tx_mode == TEST_MODE_HTGREENFIELD) { + /* HT mode */ + u_int8 n_map_idx; + + if (mcs != 32) { + mcs_1ss = mcs % 8; + nss = (mcs / 8) + 1; + bw_fact = (bw == TEST_BW_40) ? 2 : 1; + } else { + bw_fact = 1; + nss = 1; + } + + for (n_map_idx = 0; + n_map_idx < SERV_ARRAY_SIZE(n_mode_map); n_map_idx++) { + if (mcs_1ss == n_mode_map[n_map_idx].mcs) + break; + } + + if (n_map_idx == SERV_ARRAY_SIZE(n_mode_map)) { + tx_data_rate = n_mode_map[0].tx_data_rate; + mcs = mcs_1ss = n_mode_map[0].mcs; + configs->mcs = mcs; + } else + tx_data_rate = n_mode_map[n_map_idx].tx_data_rate; + + tx_data_rate = tx_data_rate * nss * bw_fact; + + if (sgi == 1) + tx_data_rate = (tx_data_rate / 9) * 10; + + /* Transfer from bit to byte with expected tx time */ + txlen = pkt_tx_time * tx_data_rate / 1000 / 8; + } else if (tx_mode == TEST_MODE_VHT) { + /* VHT mode */ + u_int8 ac_map_idx; + struct test_data_rate_map *vht_mode_map; + u_int32 array_cnt = 0; + + if (bw == TEST_BW_20) { + vht_mode_map = ac_mode_map_bw20; + array_cnt = SERV_ARRAY_SIZE(ac_mode_map_bw20); + } else if (bw == TEST_BW_40) { + vht_mode_map = ac_mode_map_bw40; + array_cnt = SERV_ARRAY_SIZE(ac_mode_map_bw40); + } else if (bw == TEST_BW_80) { + vht_mode_map = ac_mode_map_bw80; + array_cnt = SERV_ARRAY_SIZE(ac_mode_map_bw80); + } else if (bw == TEST_BW_160C) { + vht_mode_map = ac_mode_map_bw160; + array_cnt = SERV_ARRAY_SIZE(ac_mode_map_bw160); + } else { + vht_mode_map = ac_mode_map_bw20; + array_cnt = SERV_ARRAY_SIZE(ac_mode_map_bw20); + } + + for (ac_map_idx = 0; ac_map_idx < array_cnt; ac_map_idx++) { + if (mcs == vht_mode_map[ac_map_idx].mcs) + break; + } + + if (ac_map_idx == array_cnt) { + tx_data_rate = vht_mode_map[0].tx_data_rate; + mcs = mcs_1ss = vht_mode_map[0].mcs; + configs->mcs = mcs; + } else + tx_data_rate = vht_mode_map[ac_map_idx].tx_data_rate; + + /* TODO: need to check for sgi equation */ + if (sgi == 1) + tx_data_rate = (tx_data_rate / 9) * 10; + + /* Transfer from bit to byte with expected tx time */ + txlen = pkt_tx_time * tx_data_rate / 10 / 8; + } else if (tx_mode == TEST_MODE_HE_SU) { + u_int8 map_idx = 0; + struct test_data_rate_map *rate_map = NULL; + u_int32 array_cnt = 0; + + switch (sgi) { + case 0: + case 1: + case 4: + sgi = 0; + break; + case 2: + sgi = 1; + break; + case 3: + sgi = 2; + break; + } + + nss = configs->nss; + + if (bw == TEST_BW_20) { + rate_map = he_su_mode_map_bw20; + array_cnt = SERV_ARRAY_SIZE(he_su_mode_map_bw20); + } else if (bw == TEST_BW_40) { + rate_map = he_su_mode_map_bw40; + array_cnt = SERV_ARRAY_SIZE(he_su_mode_map_bw40); + } else if (bw == TEST_BW_80) { + rate_map = he_su_mode_map_bw80; + array_cnt = SERV_ARRAY_SIZE(he_su_mode_map_bw80); + } else if (bw == TEST_BW_160NC || bw == TEST_BW_160C) { + rate_map = he_su_mode_map_bw160; + array_cnt = SERV_ARRAY_SIZE(he_su_mode_map_bw160); + } else { + rate_map = he_su_mode_map_bw20; + array_cnt = SERV_ARRAY_SIZE(he_su_mode_map_bw20); + } + + for (map_idx = 0; + map_idx < array_cnt; + map_idx++) { + if (mcs == rate_map[map_idx].mcs) + break; + } + + if (map_idx == array_cnt) { + tx_data_rate = rate_map[0].tx_data_rate; + mcs = mcs_1ss = rate_map[0].mcs; + configs->mcs = mcs; + } else + tx_data_rate = rate_map[map_idx].tx_data_rate; + + tx_data_rate *= nss; + + switch (sgi) { + case 1: + tx_data_rate = (tx_data_rate * 100) / 90; + break; + + case 2: + tx_data_rate = (tx_data_rate * 100) / 85; + break; + + default: + if (sgi > 0) + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_ERROR, + ("%s: invalid gi=%d, ignored as 0.\n", + __func__, sgi)); + break; + } + /* Transfer from bit to byte with expected tx time */ + txlen = pkt_tx_time * tx_data_rate / 10 / 8; + } else if (tx_mode == TEST_MODE_HE_TB) { + struct test_ru_info *ru_info = NULL; + u_int32 ds = 0, dss = 0; + + ru_info = &configs->ru_info_list[0]; + mcs = (ru_info->rate & 0xf); + ds = mt_engine_map_subcarriers(ru_info->ru_index >> 1, + (ru_info->rate & BIT(5))); + + if (ds) { + dss = mt_engine_map_subcarriers_short( + ru_info->ru_index >> 1, + (ru_info->rate & BIT(5))); + + nss = ru_info->nss; + ru_info->cbps = ds * nss * test_he_bpscs[mcs]; + + ru_info->dbps = test_he_rate_density[mcs]-1; + ru_info->dbps *= ru_info->cbps; + ru_info->dbps /= test_he_rate_density[mcs]; + + txlen = mt_engine_calc_bytes_by_time(tx_mode, + nss, + 0, + mt_engine_trans_ltf(tx_mode, sgi), + mt_engine_trans_gi(tx_mode, sgi), + ru_info->dbps, + pkt_tx_time); + /* reserve FCS(4)+Delimiter(4)+ + * A-Control(4)+H/W revered(1) + */ + txlen -= 13; + ru_info->mpdu_length = txlen; + } else { + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_ERROR, + ("%s: unknown RU Index:[%d],\n", __func__, + (ru_info->ru_index >> 1))); + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_ERROR, + ("\t\tforced transmit l024 bytes MPDU!\n")); + + /* reserve FCS(4)+Delimiter(4)+ + * A-Control(4)+H/W revered(1) + */ + txlen = 1024 - 13; + } + } + + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_OFF, + ("%s: phy_mode=%d, mcs/mcs_1ss=%d/%d, nss=%d, ", + __func__, tx_mode, mcs, mcs_1ss, nss)); + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_OFF, + ("bw/bw_fact=%d/%d, sgi=%d, ", bw, bw_fact, sgi)); + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_OFF, + ("txlen=%d, pkt_tx_time=%d, tx_data_rate=%d\n", + txlen, pkt_tx_time, tx_data_rate)); + + if (tx_mode > TEST_MODE_VHT) { + if (txlen >= (TEST_MAX_VHT_MPDU_LEN * 256)) { + txlen = (TEST_MAX_VHT_MPDU_LEN * 256); + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_OFF, + ("%s: expected txlen > HE PPDU max len, ", + __func__)); + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_OFF, + ("reduce the txlen=%d\n", txlen)); + } + } else if (tx_mode == TEST_MODE_VHT) { + if (txlen >= (TEST_MAX_VHT_MPDU_LEN * 64)) { + txlen = (TEST_MAX_VHT_MPDU_LEN * 64); + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_OFF, + ("%s: expected txlen > VHT PPDU max len, ", + __func__)); + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_OFF, + ("reduce the txlen=%d\n", txlen)); + } + } else if (tx_mode == TEST_MODE_HTMIX + || tx_mode == TEST_MODE_HTGREENFIELD) { + if (txlen >= TEST_MAX_HT_AMPDU_LEN) { + txlen = TEST_MAX_HT_AMPDU_LEN; + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_OFF, + ("%s: expected txlen > HT PPDU max len, ", + __func__)); + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_OFF, + ("reduce the txlen=%d\n", txlen)); + } + } else if (tx_mode == TEST_MODE_OFDM) { + if (txlen >= TEST_MAX_MSDU_LEN) { + txlen = TEST_MAX_MSDU_LEN; + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_OFF, + ("%s: expected txlen > OFDM PPDU max len, ", + __func__)); + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_OFF, + ("reduce the txlen=%d\n", txlen)); + } + } else if (tx_mode == TEST_MODE_CCK) { + if (txlen >= TEST_MAX_MSDU_LEN) { + txlen = TEST_MAX_MSDU_LEN; + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_OFF, + ("%s: expected txlen > CCK PPDU max len, ", + __func__)); + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_OFF, + ("reduce the txlen=%d\n", txlen)); + } + } + + return txlen; +} + +static u_int32 mt_engine_calc_hlen( + struct test_configuration *configs, + boolean *need_qos, boolean *need_amsdu, boolean *need_ampdu) +{ + u_int32 txlen = 0, hlen = TEST_DEFAULT_MAC_HDR_LEN; + u_char tx_mode, use_data_frame = 1; + + /* + * 1. Get the tx data rate + * 2. Check if need to send packet with AMPDU format + * 3. Check if need to send packet with AMSDU-in-AMPDU format + * 4. Return the expected packet header length by tx packet type + * if need to has QoS field and HTC field. + */ + txlen = configs->tx_len; + tx_mode = configs->tx_mode; + + if (txlen <= TEST_MIN_MSDU_LEN) { + use_data_frame = 0; + /* Here we need to go mgmt/ctrl frame mode */ + } else if (txlen > TEST_MAX_MSDU_LEN) { + if (tx_mode > TEST_MODE_OFDM) { + *need_qos = TRUE; + /* mark need_amsdu to notify A-MSDU like packet */ + *need_amsdu = TRUE; + } + + if (txlen > datalen_limit[tx_mode].amsdu_limit) + *need_ampdu = TRUE; + } + + /* Force aggregation due to TXCMD required */ + if (tx_mode == TEST_MODE_VHT_MIMO || tx_mode == TEST_MODE_HE_MU) { + *need_qos = TRUE; + *need_ampdu = TRUE; + } + + if (use_data_frame && *need_qos) + hlen = TEST_QOS_MAC_HDR_LEN; + + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_OFF, + ("%s: header len=%d -> %d\n", __func__, + configs->hdr_len, hlen)); + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_OFF, + ("%s: txlen=%d, ", __func__, txlen)); + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_OFF, + ("need_qos/amsdu/ampdu/dataframe=%d/%d/%d/%d/%d\n", + *need_qos, *need_amsdu, *need_ampdu, use_data_frame, hlen)); + + return hlen; +} + +static s_int32 mt_engine_handle_ampdu( + struct test_wlan_info *winfos, + struct test_configuration *configs, + struct test_operation *ops, + u_char *buf) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct tx_time_param *tx_time_param = NULL; + u_int32 txlen, per_mpdu_len; + u_int8 tx_hw_hdr_len; + u_int8 ampdu_agg_cnt = 0; + + /* Update WTBL first */ + ret = net_ad_cfg_wtbl(winfos, configs); + if (ret) + return ret; + + tx_time_param = &configs->tx_time_param; + tx_hw_hdr_len = winfos->chip_cap.tx_wi_size; + txlen = tx_time_param->pkt_tx_len; + + per_mpdu_len = TEST_MAX_MSDU_LEN; + ampdu_agg_cnt = txlen / per_mpdu_len; + + if (txlen % per_mpdu_len) + ampdu_agg_cnt++; + + tx_time_param->pkt_msdu_len = txlen/ampdu_agg_cnt; + tx_time_param->pkt_ampdu_cnt = ampdu_agg_cnt; + + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_OFF, + ("txlen/msdu len/agg cnt=%d/%d/%d\n", + txlen, tx_time_param->pkt_msdu_len, + tx_time_param->pkt_ampdu_cnt)); + + ret = net_ad_fill_pkt(winfos, configs, buf, + tx_time_param->pkt_msdu_len, + tx_time_param->pkt_hdr_len); + + return ret; +} + +static s_int32 mt_engine_handle_non_ampdu( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_char *buf) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct tx_time_param *tx_time_param; + + tx_time_param = &configs->tx_time_param; + + ret = net_ad_fill_pkt(winfos, configs, buf, + tx_time_param->pkt_msdu_len, + tx_time_param->pkt_hdr_len); + + return ret; +} + +static s_int32 mt_engine_gen_burst_pkt( + struct test_wlan_info *winfos, + struct test_configuration *configs, + struct test_operation *ops, + u_char *buf) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct tx_time_param *tx_time_param; + u_int32 txlen, hlen; + u_int8 need_qos, need_amsdu, need_ampdu; + + tx_time_param = &configs->tx_time_param; + + txlen = tx_time_param->pkt_tx_len; + hlen = tx_time_param->pkt_hdr_len; + need_qos = tx_time_param->pkt_need_qos; + need_amsdu = tx_time_param->pkt_need_amsdu; + need_ampdu = tx_time_param->pkt_need_ampdu; + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_TRACE, + ("%s: txlen/hlen=%d/%d, ", + __func__, txlen, hlen)); + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_TRACE, + ("qos/amsdu/ampdu=%d/%d/%d\n", + need_qos, need_amsdu, need_ampdu)); + + /* Update WTBL if necessary */ + /* Generate tx packet */ + /* + * Note: the difference between handle_ampdu/handle_non_ampdu + * is txlen and hlen, maybe reduce API here and call fill_pkt directly + */ + if (need_ampdu) { + ret = mt_engine_handle_ampdu(winfos, configs, ops, buf); + } else { + /* + * No aggregation, directly go with specific length + * and through ALTX queue + */ + tx_time_param->pkt_msdu_len = txlen; + ret = mt_engine_handle_non_ampdu(winfos, configs, buf); + } + + return ret; +} + +static s_int32 mt_engine_gen_pkt( + struct test_wlan_info *winfos, + struct test_configuration *configs, + struct test_operation *ops, + u_char *buf) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct tx_time_param *tx_time_param; + u_int32 pkt_tx_time; + + tx_time_param = &configs->tx_time_param; + + if (!buf) { + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_ERROR, + ("%s: null buf\n", __func__)); + + return SERV_STATUS_ENGINE_INVALID_NULL_POINTER; + } + + /* For long packet implementation */ + tx_time_param->pkt_tx_len = configs->tx_len; + tx_time_param->pkt_hdr_len = configs->hdr_len; + tx_time_param->pkt_need_qos = 0; + tx_time_param->pkt_need_amsdu = 0; + tx_time_param->pkt_need_ampdu = 0; + tx_time_param->pkt_ampdu_cnt = 1; + pkt_tx_time = tx_time_param->pkt_tx_time; + + if (pkt_tx_time > 0) { + u_int32 new_txlen; + + new_txlen = mt_engine_calc_txlen(configs); + + if (new_txlen > 0) + configs->tx_len = new_txlen; + else { + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_ERROR, + ("%s: can't get txlen by pkt tx time\n", + __func__)); + } + + tx_time_param->pkt_tx_len = new_txlen; + } + + tx_time_param->pkt_hdr_len = mt_engine_calc_hlen( + configs, &tx_time_param->pkt_need_qos, + &tx_time_param->pkt_need_amsdu, + &tx_time_param->pkt_need_ampdu); + + ret = mt_engine_gen_burst_pkt(winfos, configs, ops, buf); + + return ret; +} + +static s_int32 mt_engine_apply_ipg_param( + struct test_wlan_info *winfos, + struct test_configuration *configs, + struct test_operation *ops, + u_char band_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct ipg_param *ipg_param; + u_int32 ipg; + u_int16 slot_time, sifs_time, cw; + u_int8 aifsn, wmm_idx = 0; + + ipg_param = &configs->ipg_param; + ipg = ipg_param->ipg; + + if (ipg > 0) { + /* Get packet q_idx and decide which CR need to be changed */ + slot_time = ipg_param->slot_time; + sifs_time = ipg_param->sifs_time; + aifsn = ipg_param->aifsn; + cw = ipg_param->cw; + } else { + /* Write default value back to HW */ + slot_time = TEST_DEFAULT_SLOT_TIME; + sifs_time = TEST_DEFAULT_SIFS_TIME; + aifsn = TEST_MIN_AIFSN; + cw = 0; + } + + ipg_param->slot_time = slot_time; + ipg_param->sifs_time = sifs_time; + ipg_param->aifsn = aifsn; + ipg_param->cw = cw; + + ret = ops->op_set_ifs_cr(winfos, configs, band_idx); + if (ret) + goto err_out; + + ret = ops->op_set_slot_time(winfos, + (u_int8) slot_time, + (u_int8) sifs_time, + TEST_RIFS_TIME, + TEST_EIFS_TIME, + (u_int8) band_idx); + if (ret) + goto err_out; + + ret = net_ad_get_wmm_idx(configs->stack.virtual_device[0], &wmm_idx); + if (ret) + goto err_out; + + ret = net_ad_set_wmm_param_by_qid(wmm_idx, configs->ac_idx, + winfos, configs); + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_OFF, + ("%s: ipg=%d, slot_time=%d, sifs_time=%d, aifsn=%d, cw=%d\n", + __func__, ipg, slot_time, sifs_time, aifsn, cw)); + +err_out: + return ret; +} + +static boolean is_mt_engine_stack_full(struct test_configuration *configs) +{ + boolean ret = FALSE; + struct test_tx_stack *stack = &configs->stack; + + if (stack->index == stack->entry_limit) + ret = TRUE; + + return ret; +} + +static boolean is_mt_engine_stack_empty(struct test_configuration *configs) +{ + boolean ret = FALSE; + struct test_tx_stack *stack = &configs->stack; + + if (stack->index == 0) + ret = TRUE; + + return ret; +} + + +static s_int32 mt_engine_stack_push( + struct test_configuration *configs, + void *virtual_device, + u_int8 *da, + void *virtual_wtbl, + struct test_tx_info *tx_info) +{ + u_int32 ret = -1; + struct test_tx_stack *stack = &configs->stack; + + if (stack->index < stack->entry_limit) { + sys_ad_move_mem(stack->da[stack->index], da, SERV_MAC_ADDR_LEN); + stack->virtual_device[stack->index] = virtual_device; + stack->virtual_wtbl[stack->index] = virtual_wtbl; + sys_ad_move_mem(&stack->tx_info[stack->index], + tx_info, sizeof(*tx_info)); + ret = stack->index; + + stack->index++; + } else { + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_ERROR, + ("(%s)Stack for TX is full!\n", __func__)); + } + + return ret; +} + +static u_int32 mt_engine_stack_pop( + struct test_configuration *configs, + u_char **da, + void **virtual_wtbl) +{ + u_int32 ret = SERV_STATUS_SUCCESS; + struct test_tx_stack *stack = &configs->stack; + + if (stack->index > 0) { + *virtual_wtbl = stack->virtual_wtbl[stack->index-1]; + stack->virtual_wtbl[stack->index-1] = NULL; + stack->virtual_device[stack->index-1] = NULL; + *da = stack->da[stack->index-1]; + sys_ad_zero_mem(&stack->tx_info[stack->index-1], + sizeof(stack->tx_info[stack->index-1])); + + stack->index--; + } else { + ret = SERV_STATUS_ENGINE_FAIL; + *virtual_wtbl = NULL; + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_ERROR, + ("(%s)Stack for Tx is empty, dismissed\n", __func__)); + } + + return ret; +} + +static s_int32 mt_engine_store_tx_info( + struct test_operation *ops, + struct test_wlan_info *winfos, + struct test_configuration *configs, + void *virtual_device, + u_char *da, + void *virtual_wtbl, + struct test_tx_info *tx_info) +{ + s_int32 ret = SERV_STATUS_SUCCESS, sta_idx = -1; + u_char *pate_pkt = (u_char *)configs->test_pkt; + struct test_tx_stack *stack = &configs->stack; + + if (pate_pkt == NULL) { + ret = -1; + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_ERROR, + ("%s: Invalid pre-allocated buffer for MPDU\n", + __func__)); + + goto err_out; + } + + if (is_mt_engine_stack_full(configs) == FALSE) { + if (tx_info) { + net_ad_fill_phy_info(virtual_wtbl, tx_info); + + if ((configs->tx_mode < TEST_MODE_HE_SU) && + (tx_info->mcs & 0x7f) == 32) + net_ad_handle_mcs32(winfos, + virtual_wtbl, + tx_info->bw); + } else { + ret = SERV_STATUS_ENGINE_INVALID_NULL_POINTER; + goto err_out; + } + + net_ad_apply_wtbl(winfos, virtual_device, virtual_wtbl); + + sta_idx = mt_engine_stack_push(configs, + virtual_device, + da, + virtual_wtbl, + tx_info); + + if (sta_idx > -1 && sta_idx < MAX_MULTI_TX_STA) { + u_int8 *pate_pkt = configs->test_pkt; + struct tx_time_param *tx_time_param = NULL; + u_int32 pkt_tx_time = 0; + u_int32 tx_len = 0; + + tx_time_param = &configs->tx_time_param; + pkt_tx_time = tx_time_param->pkt_tx_time; + + tx_len = tx_info->mpdu_length; + configs->tx_len = tx_info->mpdu_length; + + /* Prepare tx packet */ + ret = mt_engine_gen_pkt(winfos, + configs, + ops, + pate_pkt); + + if (ret != SERV_STATUS_SUCCESS) { + SERV_LOG(SERV_DBG_CAT_ENGN, + SERV_DBG_LVL_ERROR, + ("%s: Generate packets failed(0x%04x)\n", + __func__, ret)); + goto err_out; + } + + if (stack->pkt_skb[sta_idx]) + ret = net_ad_free_pkt(winfos, + stack->pkt_skb[sta_idx]); + + if (ret != SERV_STATUS_SUCCESS) { + SERV_LOG(SERV_DBG_CAT_ENGN, + SERV_DBG_LVL_ERROR, + ("%s: Free Packet fail(0x%04x)\n", + __func__, ret)); + goto err_out; + } else + stack->pkt_skb[sta_idx] = NULL; + + ret = net_ad_alloc_pkt(winfos, + configs, + tx_time_param->pkt_msdu_len, + &stack->pkt_skb[sta_idx]); + + if (ret != SERV_STATUS_SUCCESS) { + SERV_LOG(SERV_DBG_CAT_ENGN, + SERV_DBG_LVL_ERROR, + ("%s: Allocate Packet fail(0x%04x)\n", + __func__, ret)); + goto err_out; + } else { + configs->is_alloc_skb |= BIT(sta_idx); + } + } else { + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_ERROR, + ("%s: TX stack entry stored failed\n", + __func__)); + } + } else { + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_ERROR, + ("%s: Tx stack is full!\n", __func__)); + } + +err_out: + return ret; +} + +static u_int8 mt_engine_decode_gi( + u_int8 tx_mode, + u_int32 ltf_gi) +{ + u_int8 gi_type = 0; + + if (tx_mode == TEST_MODE_HE_SU || + tx_mode == TEST_MODE_HE_ER || + tx_mode == TEST_MODE_HE_MU) { + switch (ltf_gi) { + case 1: + case 2: + gi_type = TEST_GI_8+(ltf_gi-1); + break; + case 3: + case 4: + gi_type = TEST_GI_8+((ltf_gi-3) ? 0:2); + break; + default: + gi_type = TEST_GI_8; + break; + } + } else if (tx_mode == TEST_MODE_HE_TB) { + switch (ltf_gi) { + case 2: + gi_type = TEST_GI_32; + break; + default: + gi_type = TEST_GI_16; + break; + } + } else /* for non-HE PPDU types, gi equavalent to Sgi. */ + gi_type = ltf_gi; + + return gi_type; +} + +static u_int8 mt_engine_decode_ltf( + u_int8 tx_mode, + u_int32 ltf_gi) +{ + u_int8 ltf_type = 0; + + if (tx_mode == TEST_MODE_HE_SU || tx_mode == TEST_MODE_HE_ER) { + switch (ltf_gi) { + case 1: + case 2: + ltf_type = TEST_HE_LTF_X2; + break; + case 3: + case 4: + ltf_type = TEST_HE_LTF_X4; + break; + default: + ltf_type = TEST_HE_LTF_X1; + break; + } + } else if (tx_mode == TEST_MODE_HE_MU) { + switch (ltf_gi) { + case 0: + case 3: + ltf_type = TEST_HE_LTF_X4; + break; + default: + ltf_type = TEST_HE_LTF_X2; + break; + } + } else if (tx_mode == TEST_MODE_HE_TB) { + ltf_type = ltf_gi; + } else /* for non-HE PPDU types, ltf is not required. */ + ltf_type = TEST_HE_LTF_X1; + + return ltf_type; +} + +static u_int8 mt_engine_get_sub_band(u_int32 ru_index) +{ + u_int8 sub_band_idx = 0; + + if (ru_index == 68 || ru_index == 67) + sub_band_idx = 0; + else if (ru_index > 64) + sub_band_idx = ((ru_index % 65) * 2); + else if (ru_index > 60) + sub_band_idx = (ru_index % 61); + else if (ru_index > 52) + sub_band_idx = ((ru_index % 53) >> 1); + else if (ru_index > 36) + sub_band_idx = ((ru_index % 37) >> 2); + else + sub_band_idx = (ru_index / 9); + + return sub_band_idx; +} + +static u_int32 mt_engine_add_allocation( + struct test_ru_allocatoin *alloc_info, + u_int8 allocation, + u_int8 seg, + u_int32 ru_index) +{ + u_int8 sub_band_idx = 0; + + sub_band_idx = mt_engine_get_sub_band(ru_index) + seg*4; + + if ((sub_band_idx > 4) || (sub_band_idx < 0)) { + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_TRACE, + ("%s: idx is invaild:%d\n ", + __func__, sub_band_idx)); + + sys_ad_set_mem(&alloc_info->sub20[0], 8, 0x72); + + return SERV_STATUS_ENGINE_INVALID_PARAM; + } + + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_TRACE, + ("%s: ru index:%d (%d), ", + __func__, ru_index, sub_band_idx)); + /* 0x7f is center-26 tone, should be ignored */ + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_TRACE, + ("%2x -> %2x\n", + alloc_info->sub20[sub_band_idx], allocation)); + if ((alloc_info->sub20[sub_band_idx] != allocation) + && (allocation != 0x7f)) { + if (alloc_info->sub20[sub_band_idx] == 0xff) { + alloc_info->sub20[sub_band_idx] = allocation; + + if (allocation == 0xc8) { + /* D3.1, Table 28-24, 0xc8 is 484-tone + * D3.1, Table 28-24, 0x72 is 484-empty-tone + */ + alloc_info-> + sub20[sub_band_idx+1] = 0x72; + + } else if (allocation == 0xd0) { + /* D3.1, Table 28-24, 0xd0 is 996-tone + * D3.1, Table 28-24, 0x73 is 484-empty-tone + */ + alloc_info-> + sub20[sub_band_idx+1] = 0x73; + alloc_info-> + sub20[sub_band_idx+2] = 0x73; + alloc_info-> + sub20[sub_band_idx+3] = 0x73; + } + } + } + + return SERV_STATUS_SUCCESS; +} + +static s_int32 mt_engine_fill_empty_allocation( + struct test_ru_allocatoin *alloc_info) +{ + u_int8 alloc_idx = 0; + + for (alloc_idx = 0 ; alloc_idx < sizeof(*alloc_info) ; alloc_idx++) { + /* D3.1, Table 28-24, 0x71 is 242-empty */ + if (alloc_info->sub20[alloc_idx] == 0xff) + alloc_info->sub20[alloc_idx] = 0x71; + } + + return SERV_STATUS_SUCCESS; +} + +static s_int32 mt_engine_calc_symbol_by_bytes( + struct test_ru_info *ru_info, boolean stbc, + u_char rate_den, u_int32 apep_length) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + s_int32 m_stbc = 1, tail = 6; + u_int32 rate = 0; + s_int32 ds = 0, dss = 0; + + ds = mt_engine_map_subcarriers(ru_info->ru_index >> 1, + (ru_info->rate & BIT(5))); + + if (ds) + dss = mt_engine_map_subcarriers_short(ru_info->ru_index >> 1, + (ru_info->rate & BIT(5))); + else { + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_ERROR, + ("%s: unknown RU Index:[%d]!\n", + __func__, (ru_info->ru_index >> 1))); + + ret = SERV_STATUS_ENGINE_INVALID_PARAM; + goto err_out; + } + + rate = ru_info->rate & (~BIT(5)); + + if (stbc) + m_stbc++; + + if (ru_info->ldpc) + tail = 0; + + ru_info->cbps = ds * ru_info->nss * test_he_bpscs[rate]; + ru_info->dbps = ru_info->cbps * (rate_den-1) / rate_den; + ru_info->cbps_s = dss * ru_info->nss * test_he_bpscs[rate]; + ru_info->dbps_s = ru_info->cbps_s * (rate_den-1) / rate_den; + + apep_length *= 8; + apep_length += (16 + tail); + ru_info->symbol_init = engine_ceil(apep_length, + (m_stbc * ru_info->dbps)); + ru_info->symbol_init *= m_stbc; + ru_info->excess = (apep_length % (m_stbc * ru_info->dbps)); + + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_ERROR, + ("%s: RU index[%d], apep length:%d symbol_init:%d,\n", + __func__, ru_info->ru_index >> 1, + apep_length, ru_info->symbol_init)); + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_ERROR, + ("\t%s: R[%d/%d], cbps:%d, dbps:%d,\n", + __func__, rate_den-1, rate_den, ru_info->cbps, ru_info->dbps)); + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_ERROR, + ("\t%s: cbps_s:%d, dbps_s:%d excess:%d\n", + __func__, ru_info->cbps_s, + ru_info->dbps_s, ru_info->excess)); + +err_out: + return ret; +} + +static s_int32 mt_engine_calc_afactor(struct test_ru_info *ru_info) +{ + s_int32 ret = 0, m_stbc = 1; + + if (ru_info->excess == 0) { + ru_info->excess = m_stbc * ru_info->dbps; + ru_info->afactor_init = 4; + } else { + u_int32 sym_short = (m_stbc * ru_info->dbps_s); + u_int32 symbol = engine_ceil(ru_info->excess, sym_short); + + ru_info->afactor_init = engine_min(4, symbol); + } + + /* prepare for caculate ldpc extra symbol */ + if (ru_info->afactor_init == 4) { + ru_info->dbps_last = ru_info->dbps; + ru_info->cbps_last = ru_info->cbps; + } else { + ru_info->dbps_last = ru_info->afactor_init * ru_info->dbps_s; + ru_info->cbps_last = ru_info->afactor_init * ru_info->cbps_s; + } + + ru_info->pld = (ru_info->symbol_init - m_stbc) * ru_info->dbps; + ru_info->pld += m_stbc * ru_info->dbps_last; + ru_info->avbits = (ru_info->symbol_init - m_stbc) * ru_info->cbps; + ru_info->avbits += m_stbc * ru_info->cbps_last; + + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_ERROR, + ("\t%s: \tafactor=%d, symbol cnt=%d\n", + __func__, ru_info->afactor_init, ru_info->symbol_init)); + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_ERROR, + ("\t%s: cbps_l:%d, dbps_l:%d, pld:%d, avbits:%d\n", + __func__, ru_info->cbps_last, ru_info->dbps_last, + ru_info->pld, ru_info->avbits)); + + return ret; +} + +static s_int32 mt_engine_calc_l_ldpc( + s_int32 avbits, s_int32 pld, u_char rate_den, + s_int32 *cw, s_int32 *l_ldpc) +{ + if (avbits <= 648) { + *cw = 1; + *l_ldpc = ((avbits >= (pld + 912/rate_den)) ? 2 : 1) * 648; + } else if (avbits <= (648 * 2)) { + *cw = 1; + *l_ldpc = ((avbits >= (pld + 1464/rate_den)) ? 3 : 2) * 648; + } else if (avbits <= (648 * 3)) { + *cw = 1; + *l_ldpc = (648 * 3); + } else if (avbits <= (648 * 4)) { + *cw = 2; + *l_ldpc = ((avbits >= (pld + 2916/rate_den)) ? 3 : 2) * 648; + } else { + *cw = engine_ceil((pld * rate_den), ((648 * 3) * (rate_den-1))); + *l_ldpc = (648 * 3); + } + + return 0; +} + +static boolean mt_engine_calc_extr_sym( + struct test_ru_info *ru_info, boolean stbc, u_char rd) +{ + boolean ret = FALSE; + s_int32 cw = 0, l_ldpc = 0, shrt = 0; + + mt_engine_calc_l_ldpc(ru_info->avbits, ru_info->pld, rd, &cw, &l_ldpc); + + shrt = (s_int32)((cw * l_ldpc * (rd-1) / rd) - ru_info->pld); + if (shrt < 0) + shrt = 0; + ru_info->punc = (s_int16)(cw * l_ldpc - ru_info->avbits - shrt); + if (ru_info->punc < 0) + ru_info->punc = 0; + + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_TRACE, + ("\t%s: cw:%d, avbits:%d, punc:%d, l_ldpc:%d, shrt:%d\n", + __func__, cw, ru_info->avbits, ru_info->punc, l_ldpc, shrt)); + + if (((10 * ru_info->punc > cw * l_ldpc / rd) && + (5 * shrt < 6 * ru_info->punc * (rd-1))) || + (10 * ru_info->punc > 3 * cw * l_ldpc / rd)) + ret = TRUE; + + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_OFF, + ("\t%s: LDPC extra symbol:%d\n", __func__, ret)); + + return ret; +} + +static s_int32 mt_engine_calc_pe_disamb( + struct test_ru_info *ru_info, u_char ltf_gi, u_char max_pe) +{ + u_int8 pe_symbol_x5 = 0; + s_int32 ret = 0, gi = 0; + u_int32 t_pe = ru_info->afactor_init; + s_int32 ltf_time = 0; + u_int32 nss = engine_max(ru_info->ru_mu_nss, ru_info->nss); + + ltf_time = test_ltf_sym[nss]; + ltf_time *= test_he_t_ltf_sym_x5[ltf_gi]; + + if (ltf_gi == 2) + gi = TEST_GI_32; + else + gi = TEST_GI_16; + + /* txtime = 20 + T_HE-PREAMBLE + N_SYM*T_SYM + + * N_MA*N_HE-LTF*T_HE-LTF-SYM + T_PE + + * SignalExtension (28-135) + * T_HE-PREAMBLE = T_RL-SIG + T_HE-SIG-A + + * T_HE-STF-T + N_HE-LTF*T_HE-LTF-SYM, + * for an HE TB PPDU + * According to Table 28-12 of 802.11ax D3.0, T_RL-SIG = 4, + * T_HE-SIG-A = 8, T_HE-STF-T = 8, + * N_HE-LTF*T_HE-LTF-SYM (N_HE-LTF = {1,2,4,6})) + * N_MA = 0 due to doppler is not support, and SignalExtension = 0 + * due to not supported + */ + ru_info->tx_time_x5 = 5 * 20 + (20+40+40+ltf_time) + + ru_info->symbol_init * test_he_t_sym_x5[gi] + 0 + + test_he_t_pe_x5[t_pe] + 0; + ru_info->l_len = engine_ceil((ru_info->tx_time_x5-20*5), (4*5))*3-3-2; + + pe_symbol_x5 = test_he_t_pe_x5[t_pe]; + pe_symbol_x5 += (4 * (((ru_info->tx_time_x5 - 20 * 5)%20) ? 1 : 0)); + if (pe_symbol_x5 >= test_he_t_sym_x5[gi]) + ru_info->pe_disamb = 1; + else + ru_info->pe_disamb = 0; + + ru_info->t_pe = t_pe; + + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_OFF, + ("\t%s: L-Len=%d, PE Disambiguilty=%d\n", + __func__, ru_info->l_len, ru_info->pe_disamb)); + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_OFF, + ("\t\t%s: tx_time(x5)=%d, tx_ltf_sym(x5):%d,\n", + __func__, ru_info->tx_time_x5, ltf_time)); + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_OFF, + ("\t\t%s: tx_sym(x5):%d, tx_pe(x5):%d\n", + __func__, test_he_t_sym_x5[gi], test_he_t_pe_x5[t_pe])); + + return ret; +} + +static s_int32 mt_engine_recalc_phy_info( + struct test_ru_info *ru_info, u_int8 stbc, u_int8 ltf_gi, u_int8 max_pe) +{ + u_char rd = 0; + u_char m_stbc = (stbc) ? 2 : 1; + s_int32 shrt = 0; + u_int32 cw = 0, l_ldpc = 0; + + rd = test_he_rate_density[ru_info->rate & ~BIT(5)]; + + if (ru_info->afactor_init == 3) { + u_int32 short_sym = ru_info->afactor_init * ru_info->cbps_s; + + ru_info->avbits += m_stbc * (ru_info->cbps - short_sym); + } else + ru_info->avbits += m_stbc * ru_info->cbps_s; + + mt_engine_calc_l_ldpc(ru_info->avbits, ru_info->pld, + rd, &cw, &l_ldpc); + + shrt = (s_int32)(cw * l_ldpc * (rd-1) / rd - ru_info->pld); + if (shrt < 0) + shrt = 0; + ru_info->punc = (s_int32)(cw * l_ldpc - ru_info->avbits - shrt); + if (ru_info->punc < 0) + ru_info->punc = 0; + + if (ru_info->afactor_init == 4) { + ru_info->symbol_init += m_stbc; + ru_info->afactor_init = 1; + } else + ru_info->afactor_init++; + + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_OFF, + ("\t\t%s: (re)afactor:%d\n", + __func__, ru_info->afactor_init)); + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_TRACE, + ("\t\t%s: (re)cw:%d, (re)avbits:%d,\n", + __func__, cw, ru_info->avbits)); + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_TRACE, + ("\t\t%s: (re)punc:%d, (re)l_ldpc:%d, (re)shrt:%d\n", + __func__, ru_info->punc, l_ldpc, shrt)); + + mt_engine_calc_pe_disamb(ru_info, ltf_gi, max_pe); + + return SERV_STATUS_SUCCESS; +} + + +s_int32 mt_engine_calc_phy( + struct test_ru_info *ru_info, + u_int32 apep_length, + u_int8 stbc, + u_int8 ltf_gi, + u_int8 max_tpe) +{ + u_char rate_den = 0; + + rate_den = test_he_rate_density[ru_info->rate & ~BIT(5)]; + mt_engine_calc_symbol_by_bytes(ru_info, stbc, rate_den, apep_length); + mt_engine_calc_afactor(ru_info); + mt_engine_calc_pe_disamb(ru_info, ltf_gi, max_tpe); + + if (ru_info->ldpc && + mt_engine_calc_extr_sym(ru_info, stbc, rate_den)) { + ru_info->ldpc_extr_sym = 1; + + mt_engine_recalc_phy_info(ru_info, stbc, ltf_gi, max_tpe); + } + + return SERV_STATUS_SUCCESS; +} + +static struct test_ru_info *mt_engine_search_dom_ru( + struct test_configuration *configs) +{ + u_int8 sta_idx = 0; + u_int8 dominate_user_idx = 0; + u_int32 max_tx_time = 0; + struct test_ru_info *ru_info = &configs->ru_info_list[0]; + + for (sta_idx = 0 ; sta_idx < MAX_MULTI_TX_STA ; sta_idx++) { + if (ru_info[sta_idx].valid) { + if (ru_info[sta_idx].tx_time_x5 > max_tx_time) { + max_tx_time = ru_info[sta_idx].tx_time_x5; + dominate_user_idx = sta_idx; + } + } + } + + configs->dmnt_ru_idx = dominate_user_idx; + ru_info = &configs->ru_info_list[dominate_user_idx]; + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_OFF, + ("%s: dominated by user[%d], RU index:%d\n", + __func__, dominate_user_idx, ru_info->ru_index >> 1)); + + return ru_info; +} + +static s_int32 mt_engine_apply_spe_antid( + struct test_operation *ops, + struct test_wlan_info *winfos, + struct test_configuration *configs) +{ + u_int8 band_idx = 0; + u_int8 ant_pri = 0, spe_idx = 0, stack_idx = 0; + s_int32 ret = SERV_STATUS_SUCCESS; + u_int32 ant_sel = configs->tx_ant; + struct test_tx_stack *stack = &configs->stack; + + net_ad_get_band_idx(stack->virtual_device[0], &band_idx); + + if (ant_sel & TEST_ANT_USER_DEF) { + ant_sel &= ~TEST_ANT_USER_DEF; + spe_idx = ant_sel; + } else { + /* fix me, ant_sel should not depend on band index */ + ant_sel >>= 2*band_idx; + + net_ad_get_speidx(winfos, ant_sel, &spe_idx); + } + + + /* store SPE index to TXD and WTBL */ + while (stack->virtual_wtbl[stack_idx] && (stack_idx < (stack->index))) { + net_ad_fill_spe_antid(winfos, stack->virtual_wtbl[stack_idx], + spe_idx, ant_pri); + stack_idx++; + } + ops->op_set_mutb_spe(winfos, band_idx, configs->tx_mode, spe_idx); + + return ret; +} + +/***************************************************************************** + * Extern functions + *****************************************************************************/ +s_int32 mt_engine_search_stack( + struct test_configuration *configs, + u_int8 wcid, + void **virtual_wtbl) +{ + s_int32 ret = SERV_STATUS_ENGINE_FAIL, idx = 0; + struct test_tx_stack *stack = &configs->stack; + + if (stack->index == 0) { + SERV_LOG(SERV_DBG_CAT_ENGN, + SERV_DBG_LVL_ERROR, + ("(%s)Stack for Tx is empty, dismissed!\n", __func__)); + + goto end; + } else { + for (idx = 0 ; idx < stack->index ; idx++) { + if (stack->virtual_wtbl[idx] && + net_ad_match_wtbl(stack->virtual_wtbl[idx], + wcid)) { + *virtual_wtbl = stack->virtual_wtbl[idx]; + ret = SERV_STATUS_SUCCESS; + break; + } + } + } + +end: + return ret; +} + +s_int32 mt_engine_unsubscribe_tx( + struct test_operation *ops, + struct test_wlan_info *winfos, + struct test_configuration *configs) +{ + u_char *da = NULL; + u_int32 ret = SERV_STATUS_SUCCESS; + void *virtual_wtbl = NULL; + + while (is_mt_engine_stack_empty(configs) == FALSE) { + mt_engine_stack_pop(configs, &da, &virtual_wtbl); + + net_ad_free_wtbl(winfos, da, virtual_wtbl); + } + +#if defined(CONFIG_AP_SUPPORT) && defined(CFG_SUPPORT_FALCON_MURU) + if (ops->op_set_tam_arb) + ops->op_set_tam_arb(winfos, 0x1); +#endif + + return ret; +} + +s_int32 mt_engine_subscribe_tx( + struct test_operation *ops, + struct test_wlan_info *winfos, + struct test_configuration *configs) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_tx_info tx_info; + u_int8 tx_mthd = 0, tone_idx = 0; + void *virtual_device = NULL, *virtual_wtbl = NULL; + + if (!is_mt_engine_stack_empty(configs)) { + mt_engine_unsubscribe_tx(ops, winfos, configs); + + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_ERROR, + ("%s: Preiously stored TX information will be flushed!\n", + __func__)); + } + + sys_ad_zero_mem(&tx_info, sizeof(tx_info)); + + /* Calculate duty_cycle related parameter first */ + if (configs->duty_cycle > 0) + ret = mt_engine_calc_duty_cycle(configs); + + tx_info.tx_mode = configs->tx_mode; + if (configs->per_pkt_bw >= TEST_BW_160C) + tx_info.bw = 0x3; + else + tx_info.bw = configs->per_pkt_bw; + tx_info.stbc = configs->stbc; + tx_info.ldpc = configs->ldpc; + tx_info.mpdu_length = configs->tx_len; + tx_info.gi = mt_engine_decode_gi(configs->tx_mode, configs->sgi); + tx_info.ltf = mt_engine_decode_ltf(configs->tx_mode, configs->sgi); + tx_info.ibf = configs->ibf; + tx_info.ebf = configs->ebf; + + tx_mthd = configs->tx_method[configs->tx_mode]; + virtual_device = (struct wifi_dev *)configs->wdev[tx_mthd]; + + if (tx_info.tx_mode < TEST_MODE_HE_TB) { + if (ops->op_set_tam_arb) + ops->op_set_tam_arb(winfos, 0x5); + + tx_info.mcs = configs->mcs; + tx_info.nss = configs->nss; + + if (net_ad_alloc_wtbl(winfos, + configs->addr1[0], + virtual_device, + &virtual_wtbl) == SERV_STATUS_SUCCESS) + mt_engine_store_tx_info(ops, + winfos, + configs, + virtual_device, + configs->addr1[0], + virtual_wtbl, + &tx_info); + else { + ret = SERV_STATUS_OSAL_NET_INVALID_NULL_POINTER; + goto err_out; + } + } else { + u_int8 idx = 0, *da = NULL; + struct test_ru_info *ru_info = &configs->ru_info_list[0]; + + if (tx_info.tx_mode == TEST_MODE_VHT_MIMO) + tx_info.tx_mode = TEST_MODE_VHT; + + for (idx = 0 ; idx < MAX_MULTI_TX_STA ; idx++) { + da = configs->addr1[idx]; + if (ru_info[idx].valid) { + tx_info.mcs = ru_info[idx].rate; + tx_info.nss = ru_info[idx].nss; + tx_info.ldpc = ru_info[idx].ldpc; + if (ru_info[idx].mpdu_length > + TEST_QOS_MAC_HDR_LEN) + tx_info.mpdu_length = + ru_info[idx].mpdu_length; + + ret = net_ad_alloc_wtbl(winfos, + configs->addr1[idx], + virtual_device, + &virtual_wtbl); + + if (ret == SERV_STATUS_SUCCESS) { + if (ru_info[idx].aid) + net_ad_set_aid(virtual_wtbl, + ru_info[idx].aid); + mt_engine_store_tx_info(ops, + winfos, + configs, + virtual_device, + configs->addr1[idx], + virtual_wtbl, + &tx_info); + } else + goto err_out; + + + if (tx_info.tx_mode == TEST_MODE_HE_MU) { + mt_engine_add_allocation( + &configs->ru_alloc, + ru_info[idx].allocation, + (ru_info[idx].ru_index & 0x1), + (ru_info[idx].ru_index >> 1)); + } else { + /* TEST_MODE_HE_TB */ + mt_engine_calc_phy(&ru_info[idx], + tx_info.mpdu_length+13, + tx_info.stbc, + configs->sgi, + configs->max_pkt_ext); + } + } + } + if (tx_info.tx_mode == TEST_MODE_HE_MU) { + mt_engine_fill_empty_allocation(&configs->ru_alloc); + + for (tone_idx = 0; + tone_idx < sizeof(configs->ru_alloc); + tone_idx++) { + SERV_LOG(SERV_DBG_CAT_ENGN, + SERV_DBG_LVL_ERROR, + ("%s: allocation[%d] = 0x%x\n", + __func__, + tone_idx, + configs->ru_alloc.sub20[tone_idx])); + } + + if (ops->op_set_tam_arb) { + ret = ops->op_set_tam_arb(winfos, 0x2); + if (ret != SERV_STATUS_SUCCESS) + goto err_out; + } + + if (ops->op_set_muru_manual) { + ret = ops->op_set_muru_manual(virtual_device, + winfos, + configs); + if (ret != SERV_STATUS_SUCCESS) + goto err_out; + } + } + } + + if (ops->op_set_ampdu_ba_limit) { + ret = ops->op_set_ampdu_ba_limit(winfos, + configs, + configs->tx_time_param.pkt_ampdu_cnt); + if (ret) + return ret; + } + + if (ops->op_set_sta_pause_cr) { + ret = ops->op_set_sta_pause_cr(winfos); + if (ret) + return ret; + } + + ret = mt_engine_apply_spe_antid(ops, winfos, configs); + if (ret != SERV_STATUS_SUCCESS) + goto err_out; + +#if 0 +#ifdef SINGLE_SKU_V2 + Ret = mt_engine_apply_pwr_offset(ad, ctrl_band_idx); +#endif +#endif +err_out: + if (ret) + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_ERROR, + ("%s: err=0x%04x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_engine_start( + struct test_wlan_info *winfos, + struct test_backup_params *bak, + struct test_configuration *configs, + struct test_operation *ops, + struct test_bk_cr *bks, + struct test_rx_stat *rx_stat, + u_int32 en_log) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_configuration *test_config; + /* TODO: factor out here for rx_filter data struct */ + struct rx_filter_ctrl rx_filter; + u_char band_idx; + + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + for (band_idx = TEST_DBDC_BAND0; + band_idx < TEST_DBDC_BAND_NUM; band_idx++) { + test_config = &configs[band_idx]; + + /*** Step1: Sanity check ***/ + /* Make sure mt_engine_init_band_info successfully + when interface up + */ + if (test_config->op_mode & OP_MODE_START) { + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_WARN, + ("%s: test mode has already started, ", + __func__)); + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_WARN, + ("wdev_idx:%u, band_idx:%u\n", + test_config->wdev_idx, band_idx)); + + goto done; + } + + /* Allocate tx packet buffer */ + if (!test_config->test_pkt) { + ret = sys_ad_alloc_mem( + (u_char **)&test_config->test_pkt, + TEST_PKT_LEN); + if (ret) + goto err; + } + + /*** Step2: Remind firmware that enable test mode ***/ + ret = ops->op_set_fw_mode(winfos, 1); + if (ret) + goto err; + + /* TODO: factor out here for BF related init */ +#if 0 +#if (defined(MT_MAC)) +#ifdef TXBF_SUPPORT + /* Before going into ATE mode, stop sounding first */ + mt_Trigger_Sounding_Packet(pAd, FALSE, 0, 0, 0, NULL); +#endif /* TXBF_SUPPORT */ +#endif /* MT_MAC */ +#endif + /* TODO: factor out here for PCIE related init */ +#if 0 +#ifdef PCIE_ASPM_DYM_CTRL_SUPPORT + mt_asic_pcie_aspm_dym_ctrl(pAd, band_idx, FALSE, FALSE); + set_pcie_aspm_dym_ctrl_cap(pAd, FALSE); +#endif /* PCIE_ASPM_DYM_CTRL_SUPPORT */ +#endif + + /*** Step3: Backup and set CRs for test mode ***/ + /* + * Backup original CRs and change to + * test mode specific CR settings. + * Restore it back when go back to normal mode. + */ + ret = ops->op_backup_and_set_cr(winfos, bks, band_idx); + if (ret) + goto err; + + /*** Step4: Init mps/rx stat ***/ + ret = mt_engine_init_mps(test_config); + if (ret) + goto err; + + /*** Step5: Disable rmac and configure rx filter ***/ + ret = ops->op_set_tr_mac( + winfos, SERV_TEST_MAC_RX, FALSE, band_idx); + if (ret) + goto err; + + /* Rx filter */ + sys_ad_zero_mem(&rx_filter, sizeof(rx_filter)); + rx_filter.bPromiscuous = FALSE; + rx_filter.bFrameReport = TRUE; + rx_filter.filterMask = SERV_RX_FILTER_NDPA + | SERV_RX_FILTER_NOT_OWN_BTIM + | SERV_RX_FILTER_NOT_OWN_UCAST + | SERV_RX_FILTER_RTS + | SERV_RX_FILTER_CTS + | SERV_RX_FILTER_CTRL_RSV + | SERV_RX_FILTER_BC_MC_DIFF_BSSID_A2 + | SERV_RX_FILTER_BC_MC_DIFF_BSSID_A3 + | SERV_RX_FILTER_BC_MC_OWN_MAC_A3 + | SERV_RX_FILTER_PROTOCOL_VERSION + | SERV_RX_FILTER_FCS_ERROR; + rx_filter.u1BandIdx = band_idx; + ret = ops->op_set_rx_filter(winfos, rx_filter); + if (ret) + goto err; + } + + /*** Step6: Init tx thread ***/ + ret = net_ad_init_thread(winfos, configs, SERV_THREAD_TEST); + if (ret) + goto err; + + /*** Step7: Stop normal function ***/ + ret = net_ad_exit_normal(winfos, bak); + if (ret) + goto err; + + for (band_idx = TEST_DBDC_BAND0; + band_idx < TEST_DBDC_BAND_NUM; band_idx++) { + test_config = &configs[band_idx]; + sys_ad_zero_mem(&test_config->stack, + sizeof(test_config->stack)); + + /*** Step8: Set op mode and init wdev/txpwr ***/ + /* call wdev_do_open must be behind ATE status set */ + /* call wdev_do_open must be after mt_adaption_stop_ap */ + test_config->op_mode = OP_MODE_START; + ret = net_ad_init_wdev(winfos, test_config, band_idx); + if (ret) + goto err; + + /* Init tx power feature */ + ret = net_ad_init_txpwr(winfos, test_config, band_idx); + if (ret) + goto err; + + if (winfos->dbdc_mode) + test_config->stack.entry_limit = MAX_MULTI_TX_STA/2; + else + test_config->stack.entry_limit = MAX_MULTI_TX_STA; + + test_config->is_alloc_skb = 0; + + sys_ad_zero_mem(test_config->tx_method, + sizeof(u_int8)*TEST_MODE_NUM); + test_config->tx_method[TEST_MODE_HE_MU] = 1; + test_config->tx_method[TEST_MODE_VHT_MIMO] = 1; + test_config->max_pkt_ext = 2; + test_config->hetb_rx_csd = 0x240004000060FF; + } + + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_OFF, + ("%s: enter test mode, wdev_idx=%u\n", + __func__, test_config->wdev_idx)); + +done: + return ret; + +err: + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_ERROR, + ("%s: enter test mode fail, err=0x%8x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_engine_stop( + struct test_wlan_info *winfos, + struct test_backup_params *bak, + struct test_configuration *configs, + struct test_operation *ops, + struct test_bk_cr *bks) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct test_configuration *test_config; + void **pkt_skb = NULL; + /* TODO: factor out here for rx_filter data struct */ + struct rx_filter_ctrl rx_filter; + u_char band_idx; + u_int16 rsp_len = 8; + u_int8 icap_len = 0; + + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_TRACE, ("%s\n", __func__)); + + for (band_idx = TEST_DBDC_BAND0; + band_idx < TEST_DBDC_BAND_NUM; band_idx++) { + test_config = &configs[band_idx]; + + /*** Step1: Sanity check ***/ + if ((test_config->op_mode & OP_MODE_STOP) + || !(test_config->op_mode & OP_MODE_START)) { + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_WARN, + ("%s: test mode has already stopped, ", + __func__)); + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_WARN, + ("wdev_idx=%u, band_idx=%u\n", + test_config->wdev_idx, band_idx)); + + test_config->op_mode = OP_MODE_STOP; + + goto done; + } + + /*** Step2: Restore CRs for normal mode ***/ + ret = ops->op_restore_cr(winfos, bks, band_idx); + if (ret) + goto err; + + /*** Step3: Remind FW that switch mode ***/ + /* + * TODO: factor out here for rf test mode + * duplicated behavior reviewing + */ + if (test_config->op_mode & OP_MODE_FFT) { + + ret = ops->op_set_rf_test_mode(winfos, + fTEST_OPER_NORMAL_MODE, + icap_len, + rsp_len); + + /* For FW to switch back to normal mode stable time */ + /* mdelay(2000); */ + if (ret) + goto err; + + test_config->op_mode &= ~OP_MODE_FFT; + } + + if (test_config->op_mode & fTEST_IN_RFTEST) { + + ret = ops->op_set_rf_test_mode(winfos, + fTEST_OPER_NORMAL_MODE, + icap_len, + rsp_len); + + /* For FW to switch back to normal mode stable time */ + /* mdelay(2000); */ + if (ret) + goto err; + + test_config->op_mode &= ~fTEST_IN_RFTEST; + } + + /*** Step4: Configure rx filter ***/ + sys_ad_zero_mem(&rx_filter, sizeof(rx_filter)); + rx_filter.bPromiscuous = FALSE; + rx_filter.bFrameReport = FALSE; + rx_filter.filterMask = SERV_RX_FILTER_NDPA + | SERV_RX_FILTER_NOT_OWN_BTIM + | SERV_RX_FILTER_NOT_OWN_UCAST + | SERV_RX_FILTER_RTS + | SERV_RX_FILTER_CTS + | SERV_RX_FILTER_CTRL_RSV + | SERV_RX_FILTER_BC_MC_DIFF_BSSID_A2 + | SERV_RX_FILTER_BC_MC_DIFF_BSSID_A3 + | SERV_RX_FILTER_BC_MC_OWN_MAC_A3 + | SERV_RX_FILTER_PROTOCOL_VERSION + | SERV_RX_FILTER_FCS_ERROR; + rx_filter.u1BandIdx = band_idx; + ret = ops->op_set_rx_filter(winfos, rx_filter); + if (ret) + goto err; + + /*** Step5: Release mps/skb ***/ + ret = mt_engine_release_mps(test_config); + if (ret) + goto err; + + /* Release skb */ + pkt_skb = &test_config->pkt_skb; + + if (*pkt_skb) { + sys_ad_free_pkt(*pkt_skb); + *pkt_skb = NULL; + } + + /*** Step6: Release wdev and set op mode ***/ + /* call wdev_do_close must be before mt_adaption_startup_ap */ + ret = net_ad_release_wdev(winfos, test_config); + if (ret) + goto err; + + test_config->op_mode = OP_MODE_STOP; + + /*** Step7: Remind FW that disable test mode ***/ + ret = ops->op_set_fw_mode(winfos, 0); + if (ret) + goto err; + + /*** Step8: Enable tmac/rmac/rxv ***/ + ret = ops->op_set_tr_mac( + winfos, SERV_TEST_MAC_TXRX, TRUE, band_idx); + if (ret) + goto err; + } + + /*** Step9: resume normal function ***/ + ret = net_ad_enter_normal(winfos, bak); + if (ret) + goto err; + + /*** Step10: Release tx thread ***/ + ret = net_ad_release_thread(0); + /* msleep(2); */ + if (ret) + goto err; + + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_OFF, + ("%s: leave test mode, wdev_idx=%u\n", + __func__, test_config->wdev_idx)); + +done: + return ret; + +err: + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_ERROR, + ("%s: leave test mode fail, err=0x%8x\n", __func__, ret)); + + test_config->op_mode = OP_MODE_STOP; + + return ret; +} + +s_int32 mt_engine_calc_ipg_param_by_ipg( + struct test_configuration *configs) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct ipg_param *ipg_param; + u_char tx_mode; + u_int32 ipg, real_ipg; + u_int8 sig_ext, aifsn; + u_int16 slot_time, sifs_time, cw; + + ipg_param = &configs->ipg_param; + tx_mode = configs->tx_mode; + ipg = ipg_param->ipg; + sig_ext = mt_engine_get_sigext_time_by_phymode(tx_mode); + slot_time = mt_engine_get_slot_time_by_phymode(tx_mode); + sifs_time = TEST_DEFAULT_SIFS_TIME; + + /* + * 1. ipg = sig_ext + sifs_time + slot_time + * 2. ipg = sig_ext + sifs_time + aifsn * slot_time + * + ((1 << cw) - 1) * slot_time + * If it's CCK mode, there's no need to consider sig_ext + * And it's no need to count in backoff time in older design + * Configure SIFS/SLOT only + * Consider which ac queue will be used each case + */ + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_OFF, + ("%s: expected ipg=%d\n", __func__, ipg)); + + if (ipg < (sig_ext + sifs_time + slot_time)) { + ipg_param->ipg = 0; + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_ERROR, + ("%s: invalid ipg!! ", __func__)); + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_ERROR, + ("sig_ext/slot_time/sifs_time=%d/%d/%d, ", + sig_ext, slot_time, sifs_time)); + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_ERROR, + ("set ipg=%d\n", ipg)); + + if (configs->duty_cycle > 0) { + configs->duty_cycle = 0; + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_ERROR, + ("%s: invalid ipg!! ", __func__)); + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_ERROR, + ("set duty_cycle=%d\n", configs->duty_cycle)); + } + + return ret; + } + + ipg -= sig_ext; + + if (ipg <= (TEST_MAX_SIFS_TIME + slot_time)) { + sifs_time = ipg - slot_time; + aifsn = TEST_MIN_AIFSN; + cw = 0; + } else { + cw = mt_engine_get_cw(ipg, slot_time); + ipg -= ((1 << cw) - 1) * slot_time; + aifsn = ipg / slot_time; + + if (aifsn >= TEST_MAX_AIFSN) + aifsn = TEST_MAX_AIFSN; + + ipg -= aifsn * slot_time; + + if (ipg <= TEST_DEFAULT_SIFS_TIME) + sifs_time = TEST_DEFAULT_SIFS_TIME; + else if ((ipg > TEST_DEFAULT_SIFS_TIME) && + (ipg <= TEST_MAX_SIFS_TIME)) + sifs_time = ipg; + else + sifs_time = TEST_MAX_SIFS_TIME; + } + + real_ipg = sig_ext + sifs_time + aifsn * slot_time + + ((1 << cw) - 1) * slot_time; + + ipg_param->sig_ext = sig_ext; + ipg_param->slot_time = slot_time; + ipg_param->sifs_time = sifs_time; + ipg_param->aifsn = aifsn; + ipg_param->cw = cw; + ipg_param->txop = 0; + + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_OFF, + ("%s: sig_ext=%d, slot_time=%d, sifs_time=%d, ", + __func__, sig_ext, slot_time, sifs_time)); + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_OFF, + ("aifsn=%d, cw=%d, ", aifsn, cw)); + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_OFF, + ("real ipg=%d\n", real_ipg)); + + return ret; +} + +s_int32 mt_engine_set_auto_resp( + struct test_wlan_info *winfos, + struct test_configuration *configs, + u_char band_idx, u_char mode) +{ + return net_ad_set_auto_resp(winfos, configs, band_idx, mode); +} + +s_int32 mt_engine_start_tx( + struct test_wlan_info *winfos, + struct test_configuration *configs, + struct test_operation *ops, + u_char band_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + struct ipg_param *ipg_param; + struct tx_time_param *tx_time_param; + struct test_tx_stack *stack = NULL; + u_int32 op_mode, tx_cnt, mcs, duty_cycle, ipg, pkt_tx_time; + u_char *test_pkt, stack_idx = 0; + u_char ctrl_ch, ch, bw; + + ipg_param = &configs->ipg_param; + tx_time_param = &configs->tx_time_param; + op_mode = configs->op_mode; + tx_cnt = configs->tx_stat.tx_cnt; + mcs = configs->mcs; + duty_cycle = configs->duty_cycle; + test_pkt = configs->test_pkt; + ctrl_ch = configs->ctrl_ch; + stack = &configs->stack; + ch = configs->channel; + bw = configs->bw; + + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_OFF, + ("%s: band_idx=%u, ch=%u, ctrl_ch=%u, wdev_idx=%u\n", + __func__, band_idx, ch, ctrl_ch, configs->wdev_idx)); + + if (!test_pkt) { + ret = SERV_STATUS_ENGINE_INVALID_NULL_POINTER; + goto err; + } + + if (op_mode & OP_MODE_TXFRAME) { + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_WARN, + ("%s: already in TXFRAME mode now, tx is ongoing!\n", + __func__)); + goto done; + } + + /* Turn on tx again if set before */ + if (op_mode & OP_MODE_TXFRAME) { + ret = ops->op_set_tr_mac( + winfos, SERV_TEST_MAC_TX, FALSE, band_idx); + if (ret) + goto err; + } + + ret = ops->op_set_tr_mac( + winfos, SERV_TEST_MAC_RX_RXV, FALSE, band_idx); + if (ret) + goto err; + + if (configs->tx_mode == TEST_MODE_HE_TB) + ops->op_hetb_ctrl(winfos, band_idx, OP_HETB_TX_CFG, + TRUE, configs->per_pkt_bw, configs->sgi, + configs->stbc, configs->dmnt_ru_idx, + &configs->ru_info_list[0]); + + /* Stop tx/rx path queues */ + ret = net_ad_cfg_queue(winfos, FALSE); + + /* NOTE: here needs to polling tx/rx path until packets empty */ + + /* Start tx/rx path queues */ + ret = net_ad_cfg_queue(winfos, TRUE); + + /* Apply ipg setting to HW */ + ret = mt_engine_apply_ipg_param(winfos, configs, ops, band_idx); + if (ret) + goto err; + + if (tx_cnt != 0xFFFFFFFF) { + if (configs->tx_strategy != TEST_TX_STRA_THREAD) + tx_cnt += configs->tx_stat.tx_done_cnt; + + /* work aound to prevent refill flow interrupted */ + if (configs->tx_mode == TEST_MODE_HE_MU && configs->retry) + tx_cnt = 1; + + configs->tx_stat.tx_cnt = tx_cnt; + } + + /* Tx frame */ + op_mode |= OP_MODE_TXFRAME; + configs->op_mode = op_mode; + ipg = ipg_param->ipg; + pkt_tx_time = tx_time_param->pkt_tx_time; + + if ((pkt_tx_time > 0) || (ipg > 0)) { + u_int32 pkt_cnt, input_cnt; + u_int32 round = configs->tx_stat.tx_cnt; + u_int32 rounded = configs->tx_stat.txed_cnt; + u_int32 ampdu_cnt = tx_time_param->pkt_ampdu_cnt; + u_int32 token_limit = winfos->pkt_tx_tkid_max / 2; + + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_OFF, + ("%s: repeat=0x%x, pkt_ampdu_cnt=%d, ", + __func__, round, ampdu_cnt)); + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_OFF, + ("token_limit=%d, pkt_tx_time=%d, ipg=%d\n", + token_limit, pkt_tx_time, ipg)); + + input_cnt = round*ampdu_cnt*stack->index; + input_cnt = input_cnt > token_limit ? token_limit : input_cnt; + + /* Enqueue packet in HW queue in advance */ + for (pkt_cnt = 0; + pkt_cnt < input_cnt; + pkt_cnt += configs->stack.index) { + for (stack_idx = 0; + stack_idx < configs->stack.index; + stack_idx++) + net_ad_enq_pkt(winfos, + configs->ac_idx, + stack->virtual_wtbl[stack_idx], + stack->virtual_device[stack_idx], + stack->pkt_skb[stack_idx]); + + rounded++; + } + + configs->stack.q_idx = 0; + configs->tx_stat.txed_cnt = rounded; + } + + /* workaround to prevent: + * 1.packet of primary RU dropped then queue length mismatched + * 2.packets stay at PLE after TxStop + */ + if (configs->tx_mode == TEST_MODE_HE_MU || + configs->tx_mode == TEST_MODE_VHT_MIMO) + net_ad_enq_pkt(winfos, + configs->ac_idx, + stack->virtual_wtbl[0], + stack->virtual_device[0], + stack->pkt_skb[0]); + + if (configs->tx_mode == TEST_MODE_HE_TB) + ops->op_hetb_ctrl(winfos, band_idx, OP_HETB_TX_START, + TRUE, 0, 0, 0, 0, NULL); + + ret = net_ad_trigger_tx(winfos, + configs, + band_idx, + NULL); + if (ret) + goto err; + + ret = ops->op_set_tr_mac(winfos, SERV_TEST_MAC_TX, TRUE, band_idx); + if (ret) + goto err; + + if (op_mode & OP_MODE_RXFRAME) { + ret = ops->op_set_tr_mac( + winfos, SERV_TEST_MAC_RX_RXV, TRUE, band_idx); + if (ret) + goto err; + } + +done: + return ret; +err: + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x, wdev_idx=%x\n", + __func__, ret, configs->wdev_idx)); + + return ret; +} + +s_int32 mt_engine_stop_tx( + struct test_wlan_info *winfos, + struct test_configuration *configs, + struct test_operation *ops, + u_char band_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_int32 op_mode, ipg, pkt_tx_time; + struct ipg_param *ipg_param; + struct tx_time_param *tx_time_param; + + ipg_param = &configs->ipg_param; + tx_time_param = &configs->tx_time_param; + op_mode = configs->op_mode; + ipg = ipg_param->ipg; + pkt_tx_time = tx_time_param->pkt_tx_time; + + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_TRACE, + ("%s: band_idx=%u\n", __func__, band_idx)); + + configs->tx_stat.txed_cnt = 0; + +#ifdef ATE_TXTHREAD + net_ad_thread_stop_tx(winfos); +#endif + + if ((op_mode & OP_MODE_TXFRAME) || (op_mode == OP_MODE_STOP)) { + op_mode &= ~OP_MODE_TXFRAME; + configs->op_mode = op_mode; + + ret = ops->op_set_tr_mac( + winfos, SERV_TEST_MAC_TX, FALSE, band_idx); + if (ret) + goto err; + + if ((pkt_tx_time > 0) || (ipg > 0)) { + u_char omac_idx = 0; + /* Flush SW queue */ + ret = net_ad_clean_sta_q(winfos, SERV_WCID_ALL); + if (ret) + return ret; + + ret = net_ad_get_omac_idx( + winfos, + configs->stack.virtual_device[0], + &omac_idx); + if (ret != SERV_STATUS_SUCCESS) + goto err; + + /* + * Clean per sta tx queue and disable STA pause CRs + * for transmitting packet + */ + ret = ops->op_set_clean_persta_txq( + winfos, FALSE, omac_idx, band_idx); + if (ret != SERV_STATUS_SUCCESS) + goto err; + } + } + + if (configs->tx_mode == TEST_MODE_HE_TB) + ops->op_hetb_ctrl(winfos, band_idx, OP_HETB_TX_STOP, + TRUE, 0, 0, 0, 0, NULL); + +err: + return ret; +} + +s_int32 mt_engine_start_rx( + struct test_wlan_info *winfos, + struct test_configuration *configs, + struct test_operation *ops, + u_char band_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_int32 op_mode; + + op_mode = configs->op_mode; + if (op_mode & OP_MODE_RXFRAME) { + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_WARN, + ("%s: already in RXFRAME mode now, rx is ongoing!\n", + __func__)); + goto done; + } + + /* Turn off tx if set before */ + if (op_mode & OP_MODE_TXFRAME) { + ret = ops->op_set_tr_mac( + winfos, SERV_TEST_MAC_TX, FALSE, band_idx); + if (ret) + goto err; + } + + ret = ops->op_set_tr_mac( + winfos, SERV_TEST_MAC_RX_RXV, FALSE, band_idx); + if (ret) + goto err; + + /* Stop tx/rx path queues */ + ret = net_ad_cfg_queue(winfos, FALSE); + + /* NOTE: here needs to polling tx/rx path until packets empty */ + + /* Start tx/rx path queues */ + ret = net_ad_cfg_queue(winfos, TRUE); + + /* Turn on tx again if set before */ + if (op_mode & OP_MODE_TXFRAME) { + ret = ops->op_set_tr_mac( + winfos, SERV_TEST_MAC_TX, TRUE, band_idx); + if (ret) + goto err; + } + + ret = ops->op_set_tr_mac( + winfos, SERV_TEST_MAC_RX_RXV, TRUE, band_idx); + if (ret) + goto err; + + ret = ops->op_set_phy_counter(winfos, 0, TEST_DBDC_BAND0); + if (ret) + goto err; + + ret = ops->op_set_phy_counter(winfos, 1, TEST_DBDC_BAND0); + if (ret) + goto err; + + if (IS_TEST_DBDC(winfos)) { + ret = ops->op_set_phy_counter(winfos, 0, TEST_DBDC_BAND1); + if (ret) + goto err; + + ret = ops->op_set_phy_counter(winfos, 1, TEST_DBDC_BAND1); + if (ret) + goto err; + } + + op_mode |= OP_MODE_RXFRAME; + configs->op_mode = op_mode; + + if (configs->tx_mode == TEST_MODE_HE_TB) { + u_int8 sta_idx = 0; + struct test_ru_info *ru_info = &configs->ru_info_list[0]; + + for (sta_idx = 0 ; sta_idx < MAX_MULTI_TX_STA ; sta_idx++) { + if (ru_info[sta_idx].valid) { + /* 13 bytes for Delimiter+FCS+A_control+HW reserved */ + mt_engine_calc_phy(&ru_info[sta_idx], + ru_info[sta_idx].mpdu_length+13, + configs->stbc, + configs->sgi, + configs->max_pkt_ext*2); + } + } + if (mt_engine_search_dom_ru(configs) == NULL) { + ret = SERV_STATUS_ENGINE_FAIL; + goto err; + } + + ops->op_hetb_ctrl(winfos, band_idx, OP_HETB_RX_CFG, + TRUE, configs->per_pkt_bw, configs->sgi, + configs->stbc, configs->dmnt_ru_idx, + &configs->ru_info_list[0]); + } else if (configs->tx_mode == TEST_MODE_HE_MU) { + if (configs->mu_rx_aid) + ops->op_set_ru_aid(winfos, band_idx, + configs->mu_rx_aid); + else { + /* 0xf800 to disable */ + ops->op_set_ru_aid(winfos, band_idx, 0xf800); + } + } + +done: + return ret; + +err: + SERV_LOG(SERV_DBG_CAT_ENGN, SERV_DBG_LVL_ERROR, + ("%s: err=0x%08x\n", __func__, ret)); + + return ret; +} + +s_int32 mt_engine_stop_rx( + struct test_wlan_info *winfos, + struct test_configuration *configs, + struct test_operation *ops, + u_char band_idx) +{ + s_int32 ret = SERV_STATUS_SUCCESS; + u_int32 op_mode; + + op_mode = configs->op_mode; + + ret = ops->op_set_tr_mac( + winfos, SERV_TEST_MAC_RX_RXV, FALSE, band_idx); + + op_mode &= ~OP_MODE_RXFRAME; + configs->op_mode = op_mode; + + if (configs->tx_mode == TEST_MODE_HE_TB) { + ops->op_hetb_ctrl(winfos, band_idx, OP_HETB_RX_CFG, + FALSE, configs->per_pkt_bw, configs->sgi, + configs->stbc, configs->dmnt_ru_idx, + &configs->ru_info_list[0]); + } else if (configs->tx_mode == TEST_MODE_HE_MU) { + /* 0xf800 to disable */ + ops->op_set_ru_aid(winfos, band_idx, 0xf800); + } + + return ret; +} diff --git a/drivers/misc/mediatek/fpsgo_cus/Makefile b/drivers/misc/mediatek/fpsgo_cus/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..c8fb34ef47d5bf0e9de5311685f6fac5b64c77af --- /dev/null +++ b/drivers/misc/mediatek/fpsgo_cus/Makefile @@ -0,0 +1,71 @@ +# Copyright Statement: +# +# This software/firmware and related documentation ("MediaTek Software") are +# protected under relevant copyright laws. The information contained herein +# is confidential and proprietary to MediaTek Inc. and/or its licensors. +# Without the prior written permission of MediaTek inc. and/or its licensors, +# any reproduction, modification, use or disclosure of MediaTek Software, +# and information contained herein, in whole or in part, shall be strictly prohibited. +# +# MediaTek Inc. (C) 2017. All rights reserved. +# +# BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES +# THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") +# RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON +# AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. +# NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE +# SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR +# SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH +# THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES +# THAT IT IS RECEIVER\'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES +# CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK +# SOFTWARE RELEASES MADE TO RECEIVER\'S SPECIFICATION OR TO CONFORM TO A PARTICULAR +# STANDARD OR OPEN FORUM. RECEIVER\'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK\'S ENTIRE AND +# CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, +# AT MEDIATEK\'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, +# OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO +# MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +# +# The following software/firmware and/or related documentation ("MediaTek Software") +# have been modified by MediaTek Inc. All revisions are subject to any receiver\'s +# applicable license agreements with MediaTek Inc. +# + +FBT_TOP = $(srctree)/drivers/misc/mediatek/performance/fpsgo_v3/fbt +MTK_TOP = $(srctree)/drivers/misc/mediatek/ + +ifeq ($(CONFIG_MTK_FPSGO_V3),$(filter $(CONFIG_MTK_FPSGO_V3),m)) +ccflags-y += -DCONFIG_MTK_FPSGO_V3 +subdir-ccflags-y += -DCONFIG_MTK_FPSGO_V3 +endif + +ccflags-y += \ + -I$(srctree)/include/ \ + -I$(MTK_TOP)/include/ \ + -I$(FBT_TOP)/include/ \ + +obj-m += fpsgo.o +fpsgo-y += src/fpsgo_main.o + +ifeq (y,$(CONFIG_MTK_FPSGO_V3)) + ifeq (y,$(CONFIG_THUMB2_KERNEL)) + fpsgo-y += src/xgf_v3_ko_thumb2.o + else + fpsgo-$(CONFIG_ARM) += src/xgf_v3_ko_arm32.o + ifeq (y,$(CONFIG_CFI_CLANG)) + ifeq (y,$(CONFIG_CFI_PERMISSIVE)) + fpsgo-$(CONFIG_ARM64) += src/xgf_v3_ko_arm64_cfi_d.o + else + fpsgo-$(CONFIG_ARM64) += src/xgf_v3_ko_arm64_cfi.o + endif + else + fpsgo-$(CONFIG_ARM64) += src/xgf_v3_ko_arm64.o + endif + endif +else + ifeq (m,$(CONFIG_MTK_FPSGO_V3)) + fpsgo-y += src/xgf_v3_ko_quark.o + endif +endif \ No newline at end of file diff --git a/drivers/misc/mediatek/fpsgo_cus/src/fpsgo_ko.h b/drivers/misc/mediatek/fpsgo_cus/src/fpsgo_ko.h new file mode 100644 index 0000000000000000000000000000000000000000..9e8a3368a32f3630bd4f9ca1b6a719c67f8c5fa8 --- /dev/null +++ b/drivers/misc/mediatek/fpsgo_cus/src/fpsgo_ko.h @@ -0,0 +1,41 @@ +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are + * protected under relevant copyright laws. The information contained herein + * is confidential and proprietary to MediaTek Inc. and/or its licensors. + * Without the prior written permission of MediaTek inc. and/or its licensors, + * any reproduction, modification, use or disclosure of MediaTek Software, + * and information contained herein, in whole or in part, shall be strictly prohibited. + */ +/* MediaTek Inc. (C) 2017. All rights reserved. + * + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES + * THAT IT IS RECEIVER\'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK + * SOFTWARE RELEASES MADE TO RECEIVER\'S SPECIFICATION OR TO CONFORM TO A PARTICULAR + * STANDARD OR OPEN FORUM. RECEIVER\'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK\'S ENTIRE AND + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, + * AT MEDIATEK\'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * The following software/firmware and/or related documentation ("MediaTek Software") + * have been modified by MediaTek Inc. All revisions are subject to any receiver\'s + * applicable license agreements with MediaTek Inc. + */ + +#ifndef _FPSGO_KO_H_ +#define _FPSGO_KO_H_ + +int xgf_ko_init(void); + +#endif diff --git a/drivers/misc/mediatek/fpsgo_cus/src/fpsgo_main.c b/drivers/misc/mediatek/fpsgo_cus/src/fpsgo_main.c new file mode 100644 index 0000000000000000000000000000000000000000..75f399e1b457f9e127e5e25c74ce1dfda2792fb4 --- /dev/null +++ b/drivers/misc/mediatek/fpsgo_cus/src/fpsgo_main.c @@ -0,0 +1,97 @@ +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are + * protected under relevant copyright laws. The information contained herein + * is confidential and proprietary to MediaTek Inc. and/or its licensors. + * Without the prior written permission of MediaTek inc. and/or its licensors, + * any reproduction, modification, use or disclosure of MediaTek Software, + * and information contained herein, in whole or in part, shall be strictly prohibited. + */ +/* MediaTek Inc. (C) 2017. All rights reserved. + * + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES + * THAT IT IS RECEIVER\'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK + * SOFTWARE RELEASES MADE TO RECEIVER\'S SPECIFICATION OR TO CONFORM TO A PARTICULAR + * STANDARD OR OPEN FORUM. RECEIVER\'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK\'S ENTIRE AND + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, + * AT MEDIATEK\'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * The following software/firmware and/or related documentation ("MediaTek Software") + * have been modified by MediaTek Inc. All revisions are subject to any receiver\'s + * applicable license agreements with MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined (CONFIG_MTK_FPSGO) || defined (CONFIG_MTK_FPSGO_V3) +#include "xgf.h" +#endif +#include "fpsgo_ko.h" + +#line __LINE__ "vendor/mediatek/kernel_modules/fpsgo_cus/src/fpsgo_main.c" + +static void __exit fpsgo_exit(void) {} + +static int __init fpsgo_init(void) +{ +#ifdef CONFIG_MTK_FPSGO + xgf_est_slptime_fp = xgf_est_slptime; +#endif + +#ifdef CONFIG_MTK_FPSGO_V3 + int ret; + + ret = xgf_ko_init(); + + pr_debug("%s %d: xgf_ko_init %d", __func__, __LINE__, ret); + + if (ret) + return -1; + + xgf_est_runtime_fp = xgf_est_runtime; + xgf_stat_xchg_fp = xgf_stat_xchg; + + notify_xgf_ko_ready(); + + pr_debug("%s %d: finish", __func__, __LINE__); +#endif + + return 0; +} + +module_init(fpsgo_init); +module_exit(fpsgo_exit); + +MODULE_LICENSE("Proprietary"); +MODULE_DESCRIPTION("MediaTek FPSGO"); +MODULE_AUTHOR("MediaTek Inc."); diff --git a/drivers/misc/mediatek/fpsgo_cus/src/xgf_v3_ko_arm32.o_shipped b/drivers/misc/mediatek/fpsgo_cus/src/xgf_v3_ko_arm32.o_shipped new file mode 100644 index 0000000000000000000000000000000000000000..8a98fd54feb03f37c3748c5a811a3d5fe17423c1 Binary files /dev/null and b/drivers/misc/mediatek/fpsgo_cus/src/xgf_v3_ko_arm32.o_shipped differ diff --git a/drivers/misc/mediatek/fpsgo_cus/src/xgf_v3_ko_arm64.o_shipped b/drivers/misc/mediatek/fpsgo_cus/src/xgf_v3_ko_arm64.o_shipped new file mode 100644 index 0000000000000000000000000000000000000000..07ee42b6e7d5a7842c0d112a1371d2f88c984a49 Binary files /dev/null and b/drivers/misc/mediatek/fpsgo_cus/src/xgf_v3_ko_arm64.o_shipped differ diff --git a/drivers/misc/mediatek/fpsgo_cus/src/xgf_v3_ko_arm64_cfi.o_shipped b/drivers/misc/mediatek/fpsgo_cus/src/xgf_v3_ko_arm64_cfi.o_shipped new file mode 100644 index 0000000000000000000000000000000000000000..a569ad65433ec2ca24df7b68733e072b3280f4cd Binary files /dev/null and b/drivers/misc/mediatek/fpsgo_cus/src/xgf_v3_ko_arm64_cfi.o_shipped differ diff --git a/drivers/misc/mediatek/fpsgo_cus/src/xgf_v3_ko_arm64_cfi_d.o_shipped b/drivers/misc/mediatek/fpsgo_cus/src/xgf_v3_ko_arm64_cfi_d.o_shipped new file mode 100644 index 0000000000000000000000000000000000000000..0341c6ba9b66d4c5ab69e7df1119be403ca077ff Binary files /dev/null and b/drivers/misc/mediatek/fpsgo_cus/src/xgf_v3_ko_arm64_cfi_d.o_shipped differ diff --git a/drivers/misc/mediatek/fpsgo_cus/src/xgf_v3_ko_quark.o_shipped b/drivers/misc/mediatek/fpsgo_cus/src/xgf_v3_ko_quark.o_shipped new file mode 100644 index 0000000000000000000000000000000000000000..07cd5254fd296fc7a2455fb13dde06a671c8f8a2 Binary files /dev/null and b/drivers/misc/mediatek/fpsgo_cus/src/xgf_v3_ko_quark.o_shipped differ diff --git a/drivers/misc/mediatek/fpsgo_cus/src/xgf_v3_ko_thumb2.o_shipped b/drivers/misc/mediatek/fpsgo_cus/src/xgf_v3_ko_thumb2.o_shipped new file mode 100644 index 0000000000000000000000000000000000000000..10cca463a514c5026d09a5eace3c25d8fb9eb5ad Binary files /dev/null and b/drivers/misc/mediatek/fpsgo_cus/src/xgf_v3_ko_thumb2.o_shipped differ diff --git a/drivers/misc/mediatek/met_drv_v2/Makefile b/drivers/misc/mediatek/met_drv_v2/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..c29973b32faff194ab787de413c874f790d8b727 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/Makefile @@ -0,0 +1,49 @@ +MTK_PLATFORM := $(subst ",,$(CONFIG_MTK_PLATFORM)) +MET_ROOT_DIR := $(srctree)/drivers/misc/mediatek/met_drv_v2 +MET_COMMON_DIR := $(wildcard $(MET_ROOT_DIR)/common) +MET_BUILD_DEFAULT := n + +ifneq ($(MTK_PLATFORM),) + MET_PLF_DIR := $(wildcard $(MET_ROOT_DIR)/$(MTK_PLATFORM)) +else + MET_PLF_DIR := +endif + +ifeq ($(CONFIG_MODULES),y) + +ifeq ($(CONFIG_FTRACE),y) + ifeq ($(CONFIG_TRACING),y) + FTRACE_READY := y + endif +endif + +ifeq ($(CONFIG_MTK_MET_PLF),m) + MET_BUILD_KO := y +endif + +$(info ******** Start to build met_drv for $(MTK_PLATFORM) ********) +ifneq ($(MET_PLF_DIR),) + ifeq ($(FTRACE_READY),y) + ifeq ($(MET_BUILD_KO),y) + include $(MET_COMMON_DIR)/Kbuild + else + $(warning Not building met.ko due to CONFIG_MTK_MET_PLF is not set to m, build met default) + MET_BUILD_DEFAULT = y + endif + else + $(warning Not building met.ko due to CONFIG_FTRACE/CONFIG_TRACING is not set, build met default) + MET_BUILD_DEFAULT = y + endif +else + $(warning not support "$(MTK_PLATFORM)", build met default) + MET_BUILD_DEFAULT = y +endif +else #CONFIG_MODULES = n + $(warning Not building met.ko due to CONFIG_MODULES is not set, build met default) + MET_BUILD_DEFAULT := y +endif + +ifeq ($(MET_BUILD_DEFAULT),y) + MET_DEF_DIR := $(MET_ROOT_DIR)/default + include $(MET_DEF_DIR)/Kbuild +endif diff --git a/drivers/misc/mediatek/met_drv_v2/common/Kbuild b/drivers/misc/mediatek/met_drv_v2/common/Kbuild new file mode 100644 index 0000000000000000000000000000000000000000..1032e831c7a53982abe47709e2ec3bbd898bc195 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/Kbuild @@ -0,0 +1,556 @@ +################################################################################ +# MET Kernel module mode +################################################################################ +ifeq ("$(CONFIG_MTK_MET_PLF)","m") +$(info ======== Build met.ko ... ========) +else +$(info ======== MET Built in ... ========) +endif + +MET_CORE := common + +obj-$(CONFIG_MTK_MET_PLF) := met.o + +ifneq ($(wildcard $(MET_PLF_DIR)/Kbuild.platform.inc),) + include $(MET_PLF_DIR)/Kbuild.platform.inc +else + $(info ======= Missing $(MET_PLF_DIR)/Kbuild.platform.inc ========) +endif + +ifneq ($(wildcard $(srctree)/drivers/misc/mediatek/include/mt-plat/sync_write.h),) + ccflags-y += -DUSE_KERNEL_SYNC_WRITE_H +endif + +ifneq ($(wildcard $(srctree)/drivers/misc/mediatek/include/mt-plat/mtk_io.h),) + ccflags-y += -DUSE_KERNEL_MTK_IO_H +endif + +ccflags-y += -DCONFIG_MET_MODULE +ccflags-y += -DMET_PLF_USE +ccflags-y += -I$(MET_COMMON_DIR) +ccflags-y += -I$(MET_PLF_DIR) +ccflags-y += -I$(srctree)/include/ +ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/ +ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/ +ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include/ +ccflags-y += -I$(srctree)/drivers/misc/mediatek/base/power/$(MTK_PLATFORM)/ +ccflags-y += -I$(srctree)/drivers/misc/mediatek/leds/ +ccflags-y += -I$(srctree)/drivers/misc/mediatek/leds/$(MTK_PLATFORM)/ +ccflags-y += -I$(srctree)/drivers/misc/mediatek/met_drv/core/ + +ccflags-y += $(EXTRA_ARGS) $(EXTRA_CFLAGS) +ccflags-y += -DMTK_PLATFORM=$(MTK_PLATFORM) +#ccflags-y += -DONDIEMET_MOUNT_DEBUGFS + +met-y := $(MET_CORE)/met_main.o \ + $(MET_CORE)/met_tag_ex.o \ + $(MET_CORE)/interface.o \ + $(MET_CORE)/sampler.o \ + $(MET_CORE)/dummy_header.o \ + $(MET_CORE)/util.o \ + $(MET_CORE)/stat.o \ + $(MET_CORE)/cookie.o \ + $(MET_CORE)/mem_stat.o \ + $(MET_CORE)/switch.o \ + $(MET_CORE)/trace_event.o \ + $(MET_CORE)/core_plf_init.o \ + $(MET_CORE)/core_plf_trace.o + +CFLAGS_interface.o += -DMET_USER_EVENT_SUPPORT +CFLAGS_met_tag_ex.o += -DMET_USER_EVENT_SUPPORT + +################################################################################ +# MET feature declaration +################################################################################ +FEATURE_SPMTWAM := $(if $(FEATURE_SPMTWAM),$(FEATURE_SPMTWAM),y) +FEATURE_SSPM_EMI := $(if $(FEATURE_SSPM_EMI),$(FEATURE_SSPM_EMI),y) +FEATURE_GPU := $(if $(FEATURE_GPU),$(FEATURE_GPU),y) +FEATURE_VCOREDVFS := $(if $(FEATURE_VCOREDVFS),$(FEATURE_VCOREDVFS),y) +FEATURE_PTPOD := $(if $(FEATURE_PTPOD),$(FEATURE_PTPOD),y) +FEATURE_CPUDSU := $(if $(FEATURE_CPUDSU),$(FEATURE_CPUDSU),y) +FEATURE_WALLTIME := $(if $(FEATURE_WALLTIME),$(FEATURE_WALLTIME),y) +FEATURE_SMI := $(if $(FEATURE_SMI),$(FEATURE_SMI),y) +FEATURE_MET_BACKLIGHT := $(if $(FEATURE_MET_BACKLIGHT),$(FEATURE_MET_BACKLIGHT),y) +FEATURE_EVENT_POWER := $(if $(FEATURE_EVENT_POWER),$(FEATURE_EVENT_POWER),y) +FEATURE_ONDIEMET := $(if $(FEATURE_ONDIEMET),$(FEATURE_ONDIEMET),y) +FEATURE_TINYSYS := $(if $(FEATURE_TINYSYS),$(FEATURE_TINYSYS),n) + +################################################################################ +# MET_CPU_PMU +################################################################################ +$(info CPUPMU_VERSION = $(CPUPMU_VERSION)) +ifeq ("$(CPUPMU_VERSION)", "V8_2") + ccflags-y += -DCPUPMU_V8_2 +endif + +$(info ARCH = $(ARCH)) +ifeq ($(ARCH), mips) + met-y += $(MET_CORE)/mips_pmu_hw.o +endif #ifeq ($(ARCH), mips) + +ifeq ($(ARCH), arm) + ccflags-y += -DCONFIG_MET_ARM_32BIT + met-y += $(MET_CORE)/cpu_pmu.o + met-y += $(MET_CORE)/v7_pmu_hw.o + met-y += $(MET_CORE)/v6_pmu_hw.o +endif #ifeq ($(ARCH), arm) + +ifeq ($(ARCH), arm64) + met-y += $(MET_CORE)/cpu_pmu.o + met-y += $(MET_CORE)/v8_pmu_hw.o +endif + +################################################################################ +# MET_CPU_FREQ +################################################################################ +$(info CONFIG_CPU_FREQ = $(CONFIG_CPU_FREQ)) +ifeq ($(CONFIG_CPU_FREQ),y) + met-y += $(MET_CORE)/power.o +endif + +################################################################################ +# MET_SPM_TWAM +################################################################################ +$(info FEATURE_SPMTWAM = $(FEATURE_SPMTWAM)) + +ifneq ($(FEATURE_SPMTWAM), n) + MET_SPM_TWAM := y + + # for mtk_spm.h + ifneq ("$(wildcard $(srctree)/drivers/misc/mediatek/base/power/include/mtk_spm.h)","") + ccflags-y += -I$(srctree)/drivers/misc/mediatek/base/power/include/ + ccflags-y += -I$(MET_COMMON_DIR)/spmtwam/include/ + else + MET_SPM_TWAM = n + $(info ========= Missing $(srctree)/drivers/misc/mediatek/base/power/include/mtk_spm.h ========) + $(info ======== disable MET_SPM_TWAM ========) + endif +else + MET_SPM_TWAM := n +endif + +$(info SPMTWAM_VERSION = $(SPMTWAM_VERSION)) +$(info SPMTWAM_IDLE_SIGNAL_SUPPORT = $(SPMTWAM_IDLE_SIGNAL_SUPPORT)) + +ifeq ("$(SPMTWAM_IDLE_SIGNAL_SUPPORT)", "single") + ccflags-y += -DSPMTWAM_SINGLE_IDLE_SIGNAL +endif + +ifeq ("$(SPMTWAM_IDLE_SIGNAL_SUPPORT)", "multiple") + ccflags-y += -DSPMTWAM_MULTIPLE_IDLE_SIGNAL +endif + +ifeq ("$(SPMTWAM_VERSION)", "ap") + ccflags-y += -DSPMTWAM_AP + met-$(MET_SPM_TWAM) += $(MET_CORE)/spmtwam/ap/met_spmtwam.o +endif + +ifeq ("$(SPMTWAM_VERSION)", "sspm") + ccflags-y += -DSPMTWAM_SSPM + met-$(MET_SPM_TWAM) += $(MET_CORE)/spmtwam/sspm/met_spmtwam.o +endif + +################################################################################ +# MET_EMI +################################################################################ +$(info FEATURE_SSPM_EMI = $(FEATURE_SSPM_EMI)) + +ifeq ($(CONFIG_MTK_TINYSYS_SSPM_SUPPORT),y) + ifneq ($(FEATURE_ONDIEMET), n) + BUILD_SSPM_EMI := y + else ifneq ($(FEATURE_TINYSYS), n) + BUILD_SSPM_EMI := y + else + BUILD_SSPM_EMI := n + endif +endif + +ifeq ($(BUILD_SSPM_EMI),y) + MET_EMI := $(if $(filter n,$(FEATURE_SSPM_EMI)),n,y) + ifeq ("$(EMI_SEDA_VERSION)", "SEDA3_5") + met-$(MET_EMI) += $(MET_CORE)/emi/SEDA3_5/met_emi.o \ + $(MET_CORE)/emi/SEDA3_5/mtk_emi_bm.o + else ifeq ("$(EMI_SEDA_VERSION)", "SEDA3_6") + met-$(MET_EMI) += $(MET_CORE)/emi/SEDA3_6/met_emi.o \ + $(MET_CORE)/emi/SEDA3_6/mtk_emi_bm.o + else + met-$(MET_EMI) += $(MET_CORE)/emi/SEDA3/met_emi.o \ + $(MET_CORE)/emi/SEDA3/mtk_emi_bm.o + endif +endif + +EMI_LOWEFF_SUPPORT := $(if $(EMI_LOWEFF_SUPPORT),$(EMI_LOWEFF_SUPPORT),n) +ifeq ($(EMI_LOWEFF_SUPPORT), y) + subdir-ccflags-y += -DEMI_LOWEFF_SUPPORT +endif + +ifneq ($(wildcard $(MET_PLF_DIR)/met_reg_addr.h),) + ccflags-y += -DMET_REG_ARRD +else + $(info ======= there is no $(MET_PLF_DIR)/met_reg_addr.h, will use API to get addr info ========) +endif + +################################################################################ +# MET_GPU +################################################################################ +$(info FEATURE_GPU = $(FEATURE_GPU)) + +ifneq ($(FEATURE_GPU), n) + MET_GPU := y + + # for mtk_gpufreq.h + ifneq ("$(wildcard $(srctree)/drivers/misc/mediatek/base/power/$(MTK_PLATFORM)/mtk_gpufreq.h)","") + ccflags-y += -I$(srctree)/drivers/misc/mediatek/base/power/$(MTK_PLATFORM)/ + else ifneq ("$(wildcard $(srctree)/drivers/misc/mediatek/base/power/include/mtk_gpufreq.h)","") + ccflags-y += -I$(srctree)/drivers/misc/mediatek/base/power/include/ + else ifneq ("$(wildcard $(srctree)/drivers/gpu/mediatek/gpufreq/include/mtk_gpufreq.h)","") + ccflags-y += -I$(srctree)/drivers/gpu/mediatek/gpufreq/include/ + else + MET_GPU = n + $(info ======= Missing $(srctree)/drivers/misc/mediatek/base/power/$(MTK_PLATFORM)/mtk_gpufreq.h ========) + $(info ======= Missing $(srctree)/drivers/misc/mediatek/base/power/include/mtk_gpufreq.h ========) + $(info ======= Missing $(srctree)/drivers/gpu/mediatek/gpufreq/include/mtk_gpufreq.h ========) + $(info ======== disable MET_GPU ========) + endif + + # for mtk_gpu_utility.h + ifneq ("$(wildcard $(srctree)/drivers/misc/mediatek/include/mt-plat/mtk_gpu_utility.h)","") + ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/ + else ifneq ("$(wildcard $(srctree)/drivers/gpu/mediatek/mt-plat/mtk_gpu_utility.h)","") + ccflags-y += -I$(srctree)/drivers/gpu/mediatek/mt-plat/ + else + MET_GPU = n + $(info ======== Missing $(srctree)/drivers/misc/mediatek/include/mt-plat/mtk_gpu_utility.h ========) + $(info ======== Missing $(srctree)/drivers/gpu/mediatek/mt-plat/mtk_gpu_utility.h ========) + $(info ======== disable MET_GPU ========) + endif + + ifneq ($(CONFIG_MTK_GPU_SUPPORT), y) + MET_GPU = n + $(info ======== CONFIG_MTK_GPU_SUPPORT = n ========) + $(info ======== disable MET_GPU ========) + endif + + GPU_STALL_CNT_TYPE := $(if $(GPU_STALL_CNT_TYPE),$(GPU_STALL_CNT_TYPE),multiple) + $(info GPU_STALL_CNT_TYPE = $(GPU_STALL_CNT_TYPE)) + + ifeq ("$(GPU_STALL_CNT_TYPE)", "single") + ccflags-y += -DGPU_STALL_CNT_SINGLE + endif +else + MET_GPU := n +endif + +met-$(MET_GPU) += $(MET_CORE)/mtk_gpu_metmonitor.o + + +################################################################################ +# MET_VCOREDVFS +################################################################################ +$(info FEATURE_VCOREDVFS = $(FEATURE_VCOREDVFS)) + +ifneq ($(FEATURE_VCOREDVFS), n) + MET_VCOREDVFS := y + + # for dvfsrc-exp.h + ifneq ("$(wildcard $(srctree)/drivers/misc/mediatek/include/mt-plat/dvfsrc-exp.h)","") + ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/ + else + MET_VCOREDVFS = n + $(info ======== Missing $(srctree)/drivers/misc/mediatek/include/mt-plat/dvfsrc-exp.h ========) + $(info ======== disable MET_VCOREDVFS ========) + endif +else + MET_VCOREDVFS := n +endif + +ifneq ($(VCOREDVFS_OLD_VER),y) + met-$(MET_VCOREDVFS) += $(MET_CORE)/met_vcoredvfs.o +else + ccflags-y += -DVCOREDVFS_OLD_VER + met-$(MET_VCOREDVFS) += $(MET_CORE)/met_vcoredvfs_44.o +endif + +################################################################################ +# MET_PTPOD +################################################################################ +$(info FEATURE_PTPOD = $(FEATURE_PTPOD)) + +ifneq ($(FEATURE_PTPOD), n) + MET_PTPOD := y + + # for mtk_gpufreq.h + ifneq ("$(wildcard $(srctree)/drivers/misc/mediatek/base/power/$(MTK_PLATFORM)/mtk_gpufreq.h)","") + ccflags-y += -I$(srctree)/drivers/misc/mediatek/base/power/$(MTK_PLATFORM)/ + else ifneq ("$(wildcard $(srctree)/drivers/misc/mediatek/base/power/include/mtk_gpufreq.h)","") + ccflags-y += -I$(srctree)/drivers/misc/mediatek/base/power/include/ + else ifneq ("$(wildcard $(srctree)/drivers/gpu/mediatek/gpufreq/include/mtk_gpufreq.h)","") + ccflags-y += -I$(srctree)/drivers/gpu/mediatek/gpufreq/include/ + else + MET_PTPOD = n + $(info ======== Missing $(srctree)/drivers/misc/mediatek/base/power/$(MTK_PLATFORM)/mtk_gpufreq.h ========) + $(info ======== Missing $(srctree)/drivers/misc/mediatek/base/power/include/mtk_gpufreq.h ========) + $(info ======== Missing $(srctree)/drivers/gpu/mediatek/gpufreq/include/mtk_gpufreq.h ========) + $(info ======== disable MET_PTPOD ========) + endif + + # for mtk_cpufreq_api.h + ifneq ("$(wildcard $(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include/mach/mtk_cpufreq_api.h)","") + ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include/ + else + MET_PTPOD = n + $(info ======== Missing $(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include/mach/mtk_cpufreq_api.h ========) + $(info ======== disable MET_PTPOD ========) + endif + + # for mtk_cpufreq_config.h + ifneq ("$(wildcard $(MET_PTPOD_INC)/mtk_cpufreq_config.h)","") + ccflags-y += -I$(MET_PTPOD_INC) + else + MET_PTPOD = n + $(info ======== Missing $(MET_PTPOD_INC)/mtk_cpufreq_config.h ========) + $(info ======== disable MET_PTPOD ========) + endif +else + MET_PTPOD := n +endif + +met-$(MET_PTPOD) += $(MET_CORE)/met_ptpod.o + + +################################################################################ +# MET_CPUDSU +################################################################################ +$(info FEATURE_CPUDSU = $(FEATURE_CPUDSU)) + +MET_CPUDSU := $(if $(filter n,$(FEATURE_CPUDSU)),n,y) + +met-$(MET_CPUDSU) += $(MET_CORE)/cpu_dsu.o \ + $(MET_CORE)/v8_dsu_hw.o + +################################################################################ +# MET_WALLTIME +################################################################################ +$(info FEATURE_WALLTIME = $(FEATURE_WALLTIME)) + +MET_WALLTIME := $(if $(filter n,$(FEATURE_WALLTIME)),n,y) + +met-$(MET_WALLTIME) += $(MET_CORE)/met_wall_time.o + +################################################################################ +# MET_SMI +################################################################################ +$(info FEATURE_SMI = $(FEATURE_SMI)) + +################################################################################ +# MET_BACKLIGHT +################################################################################ +$(info FEATURE_MET_BACKLIGHT = $(FEATURE_MET_BACKLIGHT)) + +MET_BACKLIGHT := $(if $(filter n,$(FEATURE_MET_BACKLIGHT)),n,y) + +met-$(MET_BACKLIGHT) += $(MET_CORE)/met_backlight.o + +################################################################################ +# EVENT_POWER +################################################################################ +$(info FEATURE_EVENT_POWER = $(FEATURE_EVENT_POWER)) + +ifeq ($(FEATURE_EVENT_POWER), y) + ccflags-y += -DMET_EVENT_POWER_SUPPORT +endif + +################################################################################ +# On-die-met SSPM only module +################################################################################ +ifeq ($(FEATURE_ONDIEMET), y) + FEATURE_ONDIEMET_WALLTIME := $(if $(FEATURE_ONDIEMET_WALLTIME),$(FEATURE_ONDIEMET_WALLTIME),y) +else + FEATURE_ONDIEMET_WALLTIME := n +endif + +$(info FEATURE_ONDIEMET = $(FEATURE_ONDIEMET)) +$(info FEATURE_ONDIEMET_WALLTIME = $(FEATURE_ONDIEMET_WALLTIME)) + +ifneq ($(FEATURE_ONDIEMET), n) + subdir-ccflags-y += -DONDIEMET_SUPPORT + + ifeq ($(CONFIG_MTK_TINYSYS_SSPM_SUPPORT),) + $(info CONFIG_MTK_TINYSYS_SSPM_SUPPORT = n) + else + $(info CONFIG_MTK_TINYSYS_SSPM_SUPPORT = $(CONFIG_MTK_TINYSYS_SSPM_SUPPORT)) + endif + + ifeq ($(CONFIG_MTK_TINYSYS_SSPM_SUPPORT),y) + subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/sspm + subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/sspm/$(MTK_PLATFORM) + + met-y += $(MET_CORE)/ondiemet.o + met-y += $(MET_CORE)/ondiemet_log.o + met-y += $(MET_CORE)/sspm/ondiemet_sspm.o + met-y += $(MET_CORE)/sspm/sspm_ipi_handle.o + met-y += $(MET_CORE)/sspm/sspm_common.o + ccflags-y += -DMTK_TINYSYS_SSPM_SUPPORT + + MET_SSPM_IF_INC := $(srctree)/drivers/misc/mediatek/sspm/ + MET_SSPM_IF := sspm_ipi.h + + # for sspm ipi interface + ifneq ("$(wildcard $(MET_SSPM_IF_INC)/$(MET_SSPM_IF))","") + ccflags-y += -I$(MET_SSPM_IF_INC) + SYS_SSPM_READY := y + else + $(info ======== Missing $(MET_SSPM_IF_INC)/$(MET_SSPM_IF) ========) + $(info ======== disable ALL ondiemet feature ========) + + SYS_SSPM_READY := n + endif + + # for dynamic allocate ondiemet dram buffer size + ifneq ($(DYNAMIC_ALLOC_ODM_BUF_SIZE),) + ccflags-y += -DDYNAMIC_ALLOC_ODM_BUF_SIZE=$(DYNAMIC_ALLOC_ODM_BUF_SIZE) + endif + else + $(info ======== CONFIG_MTK_TINYSYS_SSPM_SUPPORT = n ========) + $(info ======== disable ALL ondiemet feature ========) + + SYS_SSPM_READY := n + endif + + ifeq ($(SYS_SSPM_READY), y) + MET_SSPM_WALLTIME := $(if $(filter n,$(FEATURE_ONDIEMET_WALLTIME)),n,y) + met-$(MET_SSPM_WALLTIME) += $(MET_CORE)/sspm/sspm_walltime.o + + MET_SMI := $(if $(filter n,$(FEATURE_SMI)),n,y) + met-$(MET_SMI) += $(MET_CORE)/sspm/sspm_met_smi.o + endif +endif + +################################################################################ +# Tinysys MET module +################################################################################ +$(info FEATURE_TINYSYS = $(FEATURE_TINYSYS)) +ifeq ($(FEATURE_TINYSYS),y) + ifeq ($(CONFIG_MTK_TINYSYS_MCUPM_SUPPORT),y) + $(info CONFIG_MTK_TINYSYS_MCUPM_SUPPORT = y) + else + $(info CONFIG_MTK_TINYSYS_MCUPM_SUPPORT = n) + FEATURE_MCUPM_NUM := 0 + endif + ifeq ($(CONFIG_MTK_TINYSYS_SCP_SUPPORT),y) + $(info CONFIG_MTK_TINYSYS_SCP_SUPPORT = y) + else + $(info CONFIG_MTK_TINYSYS_SCP_SUPPORT = n) + FEATURE_SCP_NUM := 0 + endif + ifeq ($(CONFIG_MTK_TINYSYS_SSPM_SUPPORT),y) + $(info CONFIG_MTK_TINYSYS_SSPM_SUPPORT = y) + else + $(info CONFIG_MTK_TINYSYS_SSPM_SUPPORT = n) + FEATURE_SSPM_NUM := 0 + endif + + met-y += $(MET_CORE)/tinysys/$(TINYSYS_VERSION)/tinysys_log.o + met-y += $(MET_CORE)/tinysys/$(TINYSYS_VERSION)/tinysys_mgr.o + ccflags-y += -I$(MET_COMMON_DIR)/tinysys/$(TINYSYS_VERSION) + + ccflags-y += -DFEATURE_SSPM_NUM=$(FEATURE_SSPM_NUM) + ccflags-y += -DFEATURE_MCUPM_NUM=$(FEATURE_MCUPM_NUM) + ccflags-y += -DFEATURE_SCP_NUM=$(FEATURE_SCP_NUM) + + ifneq ($(FEATURE_MCUPM_NUM),0) + $(info FEATURE_MCUPM_NUM = $(FEATURE_MCUPM_NUM)) + met-y += $(MET_CORE)/tinysys/$(TINYSYS_VERSION)/mcupm/mcupm_met.o + met-y += $(MET_CORE)/tinysys/$(TINYSYS_VERSION)/mcupm/mcupm_met_log.o + met-y += $(MET_CORE)/tinysys/$(TINYSYS_VERSION)/mcupm/mcupm_met_ipi_handle.o + ccflags-y += -I$(MET_COMMON_DIR)/tinysys/$(TINYSYS_VERSION)/mcupm/ + ccflags-y += -I$(srctree)/drivers/misc/mediatek/mcupm/$(MTK_PLATFORM) + ccflags-y += -DTINYSYS_MUCPM_SUPPORT + endif + + ifneq ($(FEATURE_SCP_NUM),0) + $(info FEATURE_SCP_NUM = $(FEATURE_SCP_NUM)) + ccflags-y += -DTINYSYS_SCP_SUPPORT + endif + + ifneq ($(FEATURE_SSPM_NUM),0) + $(info FEATURE_SSPM_NUM = $(FEATURE_SSPM_NUM)) + met-y += $(MET_CORE)/tinysys/$(TINYSYS_VERSION)/sspm/sspm_met_log.o + met-y += $(MET_CORE)/tinysys/$(TINYSYS_VERSION)/sspm/sspm_met_ipi_handle.o + met-y += $(MET_CORE)/tinysys/$(TINYSYS_VERSION)/sspm/sspm_met_common.o + ccflags-y += -I$(MET_CORE)/tinysys/$(TINYSYS_VERSION)/sspm + ccflags-y += -I$(srctree)/drivers/misc/mediatek/include + ccflags-y += -I$(srctree)/drivers/misc/mediatek/sspm + ccflags-y += -I$(srctree)/drivers/misc/mediatek/sspm/$(MTK_PLATFORM) + ccflags-y += -DTINYSYS_SSPM_SUPPORT + ccflags-y += -DMTK_TINYSYS_SSPM_SUPPORT + + SSPM_VERSION := $(if $(SSPM_VERSION),$(SSPM_VERSION),v1) + $(info SSPM_VERSION = $(SSPM_VERSION)) + ifneq ($(SSPM_VERSION), v2) + MET_SSPM_COMM_INC := $(srctree)/drivers/misc/mediatek/sspm/$(SSPM_VERSION) + MET_SSPM_IF_INC := $(srctree)/drivers/misc/mediatek/sspm/$(SSPM_VERSION) + MET_SSPM_IF := sspm_ipi.h + MET_SSPM_IPI := sspm_ipi_define.h + else + MET_SSPM_COMM_INC := $(srctree)/drivers/misc/mediatek/sspm/$(SSPM_VERSION) + MET_SSPM_IF_INC := $(srctree)/drivers/misc/mediatek/include/mt-plat/ + MET_SSPM_IF := mtk_tinysys_ipi.h + MET_SSPM_IPI := sspm_ipi_table.h + endif + + ifneq ("$(wildcard $(srctree)/drivers/misc/mediatek/sspm/$(MTK_PLATFORM)/$(MET_SSPM_IPI))","") + subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/sspm + subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/sspm/$(MTK_PLATFORM) + TINYSYS_SSPM_READY := y + else + $(info ======== Missing $(srctree)/drivers/misc/mediatek/sspm/$(MTK_PLATFORM)/$(MET_SSPM_IPI)========) + $(info ======== disable ALL tinysys SSPM feature ========) + TINYSYS_SSPM_READY := n + endif + + # for smi_met_conf format + ifeq ($(SSPM_VERSION), v2) + ccflags-y += -DSSPM_VERSION_V2 + ccflags-y += -DSMI_MASTER_8BIT + endif + + # for sspm ipi interface + ifneq ("$(wildcard $(MET_SSPM_IF_INC)/$(MET_SSPM_IF))","") + ccflags-y += -I$(MET_SSPM_IF_INC) + ccflags-y += -I$(MET_SSPM_COMM_INC) + else + $(info ======== Missing $(MET_SSPM_IF_INC)/$(MET_SSPM_IF) ========) + $(info ======== disable ALL tinysys SSPM feature ========) + TINYSYS_SSPM_READY := n + endif + + # for dynamic allocate ondiemet dram buffer size + ifneq ($(DYNAMIC_ALLOC_ODM_BUF_SIZE),) + ccflags-y += -DDYNAMIC_ALLOC_ODM_BUF_SIZE=$(DYNAMIC_ALLOC_ODM_BUF_SIZE) + endif + else + $(info ======== CONFIG_MTK_TINYSYS_SSPM_SUPPORT = n ========) + $(info ======== disable ALL tinysys SSPM feature ========) + TINYSYS_SSPM_READY := n + endif + + ifeq ($(TINYSYS_SSPM_READY), y) + MET_SMI := $(if $(filter n,$(FEATURE_SMI)),n,y) + met-$(MET_SMI) += $(MET_CORE)/tinysys/$(TINYSYS_VERSION)/sspm/sspm_met_smi.o + endif +endif + +############################################################################################## +# include $(MET_PLF_DIR)/Kbuild +############################################################################################## +ifneq ($(wildcard $(MET_PLF_DIR)/Kbuild),) + include $(MET_PLF_DIR)/Kbuild +else + $(info ======= Missing $(MET_PLF_DIR)/Kbuild ========) +endif + +################################################################################# +# add met_device flags +################################################################################# +ccflags-y += $(foreach v, $(filter MET_%,$(.VARIABLES)), $(if $(filter $($(v)),y),-D$(v))) diff --git a/drivers/misc/mediatek/met_drv_v2/common/cookie.c b/drivers/misc/mediatek/met_drv_v2/common/cookie.c new file mode 100644 index 0000000000000000000000000000000000000000..78a67c20fb4f03c605bc0578a7cc08df612c26da --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/cookie.c @@ -0,0 +1,273 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "interface.h" +#include "met_drv.h" + +#define LINE_SIZE 256 + +struct cookie_info { + int depth; + int strlen; + char strbuf[LINE_SIZE]; +}; + +static unsigned int back_trace_depth; +static DEFINE_PER_CPU(struct cookie_info, info); +static DEFINE_PER_CPU(int, cpu_status); + +static int reset_driver_stat(void) +{ + back_trace_depth = 0; + met_cookie.mode = 0; + return 0; +} + + +noinline void cookie(char *strbuf) +{ + MET_TRACE("%s\n", strbuf); +} + +noinline void cookie2(char *strbuf) +{ + MET_TRACE("%s\n", strbuf); +} + +static void get_kernel_cookie(unsigned long pc, struct cookie_info *pinfo) +{ + int ret; +#if IS_ENABLED(CONFIG_MODULES) + off_t off; + struct module *mod = __module_address(pc); + + if (mod) { + off = pc - (unsigned long)mod->core_layout.base; + ret = snprintf(pinfo->strbuf + pinfo->strlen, LINE_SIZE - pinfo->strlen, + ",%s.ko,%lx", mod->name, off); + pinfo->strlen += ret; + /* cookie(current->comm, pc, mod->name, off, 1); */ + } else +#endif + { + ret = + snprintf(pinfo->strbuf + pinfo->strlen, LINE_SIZE - pinfo->strlen, + ",vmlinux,%lx", pc); + pinfo->strlen += ret; + /* cookie(current->comm, pc, "vmlinux", pc, 0); */ + } +} + +#if defined(__arm__) +static int report_trace(struct stackframe *frame, void *d) +{ + struct cookie_info *pinfo = d; + unsigned long pc = frame->pc; + + if (pinfo->depth > 0) { + get_kernel_cookie(pc, pinfo); + pinfo->depth--; + return 0; + } + return 1; +} +#endif + +static void kernel_backtrace(struct pt_regs *const regs, struct cookie_info *pinfo) +{ +#if defined(__arm__) + struct stackframe frame; + + frame.fp = regs->ARM_fp; + frame.sp = regs->ARM_sp; + frame.lr = regs->ARM_lr; + frame.pc = regs->ARM_pc; + walk_stackframe(&frame, report_trace, pinfo); +#else + return; +#endif +} + + +void met_cookie_polling(unsigned long long stamp, int cpu) +{ + struct pt_regs *regs; + struct cookie_info *pinfo; + unsigned long pc; + int ret, outflag = 0; + off_t off; + + if (per_cpu(cpu_status, cpu) != MET_CPU_ONLINE) + return; + + regs = get_irq_regs(); + + if (regs == 0) + return; + + pc = profile_pc(regs); + + pinfo = &(per_cpu(info, cpu)); + pinfo->strlen = snprintf(pinfo->strbuf, LINE_SIZE, "%s,%lx", current->comm, pc); + + if (user_mode(regs)) { + struct mm_struct *mm; + struct vm_area_struct *vma; + struct path *ppath; + + mm = current->mm; + for (vma = find_vma(mm, pc); vma; vma = vma->vm_next) { + + if (pc < vma->vm_start || pc >= vma->vm_end) + continue; + + if (vma->vm_file) { + ppath = &(vma->vm_file->f_path); + + if (vma->vm_flags & VM_DENYWRITE) + off = pc; + else + off = (vma->vm_pgoff << PAGE_SHIFT) + pc - vma->vm_start; + + ret = + snprintf(pinfo->strbuf + pinfo->strlen, + LINE_SIZE - pinfo->strlen, ",%s,%lx", + (char *)(ppath->dentry->d_name.name), off); + pinfo->strlen += ret; + outflag = 1; + } else { + /* must be an anonymous map */ + ret = + snprintf(pinfo->strbuf + pinfo->strlen, + LINE_SIZE - pinfo->strlen, ",nofile,%lx", pc); + pinfo->strlen += ret; + outflag = 1; + } + break; + } + } else { + /* kernel mode code */ + if (back_trace_depth > 0) { + pinfo->depth = back_trace_depth + 1; + kernel_backtrace(regs, pinfo); + } else + get_kernel_cookie(pc, pinfo); + outflag = 1; + } + + /* check task is resolvable */ + if (outflag == 0) + return; + + if (back_trace_depth == 0) + cookie(pinfo->strbuf); + else + cookie2(pinfo->strbuf); +} + + +static void met_cookie_start(void) +{ + int cpu = raw_smp_processor_id(); + per_cpu(cpu_status, cpu) = MET_CPU_ONLINE; + /* return; */ +} + +static void met_cookie_stop(void) +{ + /* return; */ +} + + +static int met_cookie_process_argument(const char *arg, int len) +{ + unsigned int value; + + if (met_parse_num(arg, &value, len) < 0) { + met_cookie.mode = 0; + return -EINVAL; + } + + back_trace_depth = value; + met_cookie.mode = 1; + + return 0; +} + +static const char help[] = +" --cookie enable sampling task and PC\n" +" --cookie=N enable back trace (depth is N)\n"; + +static int met_cookie_print_help(char *buf, int len) +{ + len = snprintf(buf, PAGE_SIZE, help); + return len; +} + + +static const char header[] = +"# cookie: task_name,PC,cookie_name,offset\n" +"met-info [000] 0.0: cookie_header: task_name,PC,cookie_name,offset\n"; + +static const char header2_1[] = "# cookie2: task_name,PC,cookie,offset"; +static const char header2_2[] = "met-info [000] 0.0: cookie2_header: task_name,PC,cookie,offset"; + +static int met_cookie_print_header(char *buf, int len) +{ + int i, ret; + + if (back_trace_depth == 0) { + len = snprintf(buf, PAGE_SIZE, header); + } else { + len = snprintf(buf, PAGE_SIZE, header2_1); + for (i = 0; i < back_trace_depth; i++) { + ret = snprintf(buf + len, PAGE_SIZE, ",cookie%d,offset%d", i + 1, i + 1); + len += ret; + } + ret = snprintf(buf + len, PAGE_SIZE, "\n"); + len += ret; + + ret = snprintf(buf + len, PAGE_SIZE, header2_2); + len += ret; + for (i = 0; i < back_trace_depth; i++) { + ret = snprintf(buf + len, PAGE_SIZE, ",cookie%d,offset%d", i + 1, i + 1); + len += ret; + } + ret = snprintf(buf + len, PAGE_SIZE, "\n"); + len += ret; + } + + return len; +} + +static void met_cookie_cpu_state_notify(long cpu, unsigned long action) +{ + per_cpu(cpu_status, cpu) = action; +} + +struct metdevice met_cookie = { + .name = "cookie", + .type = MET_TYPE_PMU, + .cpu_related = 1, + .start = met_cookie_start, + .stop = met_cookie_stop, + .reset = reset_driver_stat, + .polling_interval = 1, + .timed_polling = met_cookie_polling, + .process_argument = met_cookie_process_argument, + .print_help = met_cookie_print_help, + .print_header = met_cookie_print_header, + .cpu_state_notify = met_cookie_cpu_state_notify, +}; diff --git a/drivers/misc/mediatek/met_drv_v2/common/core_plf_init.c b/drivers/misc/mediatek/met_drv_v2/common/core_plf_init.c new file mode 100644 index 0000000000000000000000000000000000000000..df8de634381d0b2d68cf24bee4cf0a8d4024c108 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/core_plf_init.c @@ -0,0 +1,422 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include +#include +#include +#include +#include "met_drv.h" +#include "met_api.h" +#include "interface.h" +#include "core_plf_init.h" +#include "met_kernel_symbol.h" + +#undef DEBUG + +#ifdef MET_GPU +/* + * GPU + */ +bool (*mtk_get_gpu_loading_symbol)(unsigned int *pLoading); +bool (*mtk_get_gpu_block_symbol)(unsigned int *pBlock); +bool (*mtk_get_gpu_idle_symbol)(unsigned int *pIdle); +bool (*mtk_get_gpu_dvfs_from_symbol)(enum MTK_GPU_DVFS_TYPE *peType, unsigned long *pulFreq); +bool (*mtk_get_gpu_sub_loading_symbol)(unsigned int *pLoading); +bool (*mtk_get_3D_fences_count_symbol)(int *pi32Count); +bool (*mtk_get_gpu_memory_usage_symbol)(unsigned int *pMemUsage); +bool (*mtk_get_gpu_power_loading_symbol)(unsigned int *pLoading); +bool (*mtk_get_custom_boost_gpu_freq_symbol)(unsigned int *pulFreq); +bool (*mtk_get_custom_upbound_gpu_freq_symbol)(unsigned int *pulFreq); +bool (*mtk_get_vsync_based_target_freq_symbol)(unsigned long *pulFreq); +bool (*mtk_get_vsync_offset_event_status_symbol)(unsigned int *pui32EventStatus); +bool (*mtk_get_vsync_offset_debug_status_symbol)(unsigned int *pui32EventStatus); +bool (*mtk_enable_gpu_perf_monitor_symbol)(bool enable); +bool (*mtk_get_gpu_pmu_init_symbol)(struct GPU_PMU *pmus, int pmu_size, int *ret_size); +bool (*mtk_get_gpu_pmu_swapnreset_symbol)(struct GPU_PMU *pmus, int pmu_size); +#if 1 +bool (*mtk_get_gpu_pmu_deinit_symbol)(void); +bool (*mtk_get_gpu_pmu_swapnreset_stop_symbol)(void); +#endif +unsigned int (*mt_gpufreq_get_cur_freq_symbol)(void); +unsigned int (*mt_gpufreq_get_thermal_limit_freq_symbol)(void); +bool (*mtk_register_gpu_power_change_symbol)(const char *name, void (*callback)(int power_on)); +bool (*mtk_unregister_gpu_power_change_symbol)(const char *name); +#endif /* MET_GPU */ + +#ifdef MET_VCOREDVFS +/* + * VCORE DVFS + */ +#ifdef VCOREDVFS_OLD_VER + +#include +#include + +u32 (*spm_vcorefs_get_MD_status_symbol)(void); +void (*spm_vcorefs_register_handler_symbol)(vcorefs_handler_t handler); +void (*vcorefs_register_req_notify_symbol)(vcorefs_req_handler_t handler); +char *(*governor_get_kicker_name_symbol)(int id); +int (*vcorefs_enable_debug_isr_symbol)(bool); +int (*vcorefs_get_hw_opp_symbol)(void); +int (*vcorefs_get_curr_vcore_symbol)(void); +int (*vcorefs_get_curr_ddr_symbol)(void); +int *kicker_table_symbol; +#else + +#include + +#endif /* end else VCOREDVFS_OLD_VER*/ +int (*vcorefs_get_opp_info_num_symbol)(void); +char ** (*vcorefs_get_opp_info_name_symbol)(void); +unsigned int * (*vcorefs_get_opp_info_symbol)(void); +int (*vcorefs_get_src_req_num_symbol)(void); +char ** (*vcorefs_get_src_req_name_symbol)(void); +unsigned int * (*vcorefs_get_src_req_symbol)(void); +int (*vcorefs_get_num_opp_symbol)(void); + +#endif /* MET_VCOREDVFS */ + + +#ifdef MET_EMI +void *(*mt_cen_emi_base_get_symbol)(void); +void *(*mt_chn_emi_base_get_symbol)(int chn); +unsigned int (*mtk_dramc_get_data_rate_symbol)(void); +unsigned int (*mtk_dramc_get_ddr_type_symbol)(void); +int (*get_cur_ddr_ratio_symbol)(void); +/* legacy emi api before mt6885 */ +unsigned int (*get_dram_data_rate_symbol)(void); +int (*get_ddr_type_symbol)(void); +#endif /* MET_EMI */ + +#ifdef MET_PTPOD +unsigned int (*mt_gpufreq_get_cur_volt_symbol)(void); +unsigned int (*mt_cpufreq_get_cur_volt_symbol)(unsigned int cluster_id); +#endif /* MET_PTPOD */ + +#ifdef MET_SPM_TWAM +/* ap side used */ +#ifdef SPMTWAM_AP +void (*spm_twam_enable_monitor_symbol)(const struct twam_sig *twamsig, bool speed_mode); +void (*spm_twam_register_handler_symbol)(twam_handler_t handler); +void (*spm_twam_disable_monitor_symbol)(void); +void (*spm_twam_set_idle_select_symbol)(unsigned int sel); +void (*spm_twam_set_window_length_symbol)(unsigned int len); +void (*spm_twam_set_mon_type_symbol)(struct twam_sig *mon); +#endif + +/* sspm side used */ +#ifdef SPMTWAM_SSPM +void (*spm_twam_enable_monitor_symbol)(bool en_monitor, bool debug_signal, twam_handler_t cb_handler); +bool (*spm_twam_met_enable_symbol)(void); +void (*spm_twam_config_channel_symbol)(struct twam_cfg *cfg, bool speed_mode, unsigned int window_len_hz); +#endif +#endif + + +static int met_symbol_get(void) +{ +#ifdef MET_GPU + _MET_SYMBOL_GET(mtk_get_gpu_loading); + _MET_SYMBOL_GET(mtk_get_gpu_block); + _MET_SYMBOL_GET(mtk_get_gpu_idle); + _MET_SYMBOL_GET(mtk_get_gpu_dvfs_from); + _MET_SYMBOL_GET(mtk_get_gpu_sub_loading); + _MET_SYMBOL_GET(mtk_get_3D_fences_count); + _MET_SYMBOL_GET(mtk_get_gpu_memory_usage); + _MET_SYMBOL_GET(mtk_get_gpu_power_loading); + _MET_SYMBOL_GET(mtk_get_custom_boost_gpu_freq); + _MET_SYMBOL_GET(mtk_get_custom_upbound_gpu_freq); + _MET_SYMBOL_GET(mtk_get_vsync_based_target_freq); + _MET_SYMBOL_GET(mtk_get_vsync_offset_event_status); + _MET_SYMBOL_GET(mtk_get_vsync_offset_debug_status); + _MET_SYMBOL_GET(mtk_enable_gpu_perf_monitor); + _MET_SYMBOL_GET(mtk_get_gpu_pmu_init); + _MET_SYMBOL_GET(mtk_get_gpu_pmu_swapnreset); + _MET_SYMBOL_GET(mt_gpufreq_get_cur_freq); + _MET_SYMBOL_GET(mt_gpufreq_get_thermal_limit_freq); + _MET_SYMBOL_GET(mtk_register_gpu_power_change); + _MET_SYMBOL_GET(mtk_unregister_gpu_power_change); +#if 1 + _MET_SYMBOL_GET(mtk_get_gpu_pmu_swapnreset_stop); + _MET_SYMBOL_GET(mtk_get_gpu_pmu_deinit); +#endif +#endif /* MET_GPU */ + +#ifdef MET_VCOREDVFS + _MET_SYMBOL_GET(vcorefs_get_num_opp); + _MET_SYMBOL_GET(vcorefs_get_opp_info_num); + _MET_SYMBOL_GET(vcorefs_get_opp_info_name); + _MET_SYMBOL_GET(vcorefs_get_opp_info); + _MET_SYMBOL_GET(vcorefs_get_src_req_num); + _MET_SYMBOL_GET(vcorefs_get_src_req_name); + _MET_SYMBOL_GET(vcorefs_get_src_req); + +#ifdef VCOREDVFS_OLD_VER + _MET_SYMBOL_GET(spm_vcorefs_get_MD_status); + _MET_SYMBOL_GET(spm_vcorefs_register_handler); + _MET_SYMBOL_GET(vcorefs_register_req_notify); + _MET_SYMBOL_GET(governor_get_kicker_name); + _MET_SYMBOL_GET(vcorefs_enable_debug_isr); + _MET_SYMBOL_GET(vcorefs_get_hw_opp); + _MET_SYMBOL_GET(vcorefs_get_curr_vcore); + _MET_SYMBOL_GET(vcorefs_get_curr_ddr); + _MET_SYMBOL_GET(kicker_table); +#endif + +#endif + +#ifdef MET_EMI + _MET_SYMBOL_GET(mt_cen_emi_base_get); + _MET_SYMBOL_GET(mt_chn_emi_base_get); + _MET_SYMBOL_GET(mtk_dramc_get_data_rate); + _MET_SYMBOL_GET(mtk_dramc_get_ddr_type); + _MET_SYMBOL_GET(get_cur_ddr_ratio); + /* legacy emi api before mt6885 */ + _MET_SYMBOL_GET(get_dram_data_rate); + _MET_SYMBOL_GET(get_ddr_type); +#endif + +#ifdef MET_PTPOD + _MET_SYMBOL_GET(mt_gpufreq_get_cur_volt); + _MET_SYMBOL_GET(mt_cpufreq_get_cur_volt); +#endif + +#ifdef MET_SPM_TWAM + /* ap side used */ +#ifdef SPMTWAM_AP + _MET_SYMBOL_GET(spm_twam_enable_monitor); + _MET_SYMBOL_GET(spm_twam_register_handler); + _MET_SYMBOL_GET(spm_twam_disable_monitor); + _MET_SYMBOL_GET(spm_twam_set_idle_select); + _MET_SYMBOL_GET(spm_twam_set_window_length); + _MET_SYMBOL_GET(spm_twam_set_mon_type); +#endif + + /* sspm side used */ +#ifdef SPMTWAM_SSPM + _MET_SYMBOL_GET(spm_twam_enable_monitor); + _MET_SYMBOL_GET(spm_twam_met_enable); + _MET_SYMBOL_GET(spm_twam_config_channel); +#endif +#endif + + return 0; +} + +static int met_symbol_put(void) +{ +#ifdef MET_GPU + _MET_SYMBOL_PUT(mtk_get_gpu_loading); + _MET_SYMBOL_PUT(mtk_get_gpu_block); + _MET_SYMBOL_PUT(mtk_get_gpu_idle); + _MET_SYMBOL_PUT(mtk_get_gpu_dvfs_from); + _MET_SYMBOL_PUT(mtk_get_gpu_sub_loading); + _MET_SYMBOL_PUT(mtk_get_3D_fences_count); + _MET_SYMBOL_PUT(mtk_get_gpu_memory_usage); + _MET_SYMBOL_PUT(mtk_get_gpu_power_loading); + _MET_SYMBOL_PUT(mtk_get_custom_boost_gpu_freq); + _MET_SYMBOL_PUT(mtk_get_custom_upbound_gpu_freq); + _MET_SYMBOL_PUT(mtk_get_vsync_based_target_freq); + _MET_SYMBOL_PUT(mtk_get_vsync_offset_event_status); + _MET_SYMBOL_PUT(mtk_get_vsync_offset_debug_status); + _MET_SYMBOL_PUT(mtk_enable_gpu_perf_monitor); + _MET_SYMBOL_PUT(mtk_get_gpu_pmu_init); + _MET_SYMBOL_PUT(mtk_get_gpu_pmu_swapnreset); + _MET_SYMBOL_PUT(mt_gpufreq_get_cur_freq); + _MET_SYMBOL_PUT(mt_gpufreq_get_thermal_limit_freq); + _MET_SYMBOL_PUT(mtk_register_gpu_power_change); + _MET_SYMBOL_PUT(mtk_unregister_gpu_power_change); +#if 1 + _MET_SYMBOL_PUT(mtk_get_gpu_pmu_swapnreset_stop); + _MET_SYMBOL_PUT(mtk_get_gpu_pmu_deinit); +#endif +#endif /* MET_GPU */ + +#ifdef MET_VCOREDVFS + _MET_SYMBOL_PUT(vcorefs_get_num_opp); + _MET_SYMBOL_PUT(vcorefs_get_opp_info_num); + _MET_SYMBOL_PUT(vcorefs_get_opp_info_name); + _MET_SYMBOL_PUT(vcorefs_get_opp_info); + _MET_SYMBOL_PUT(vcorefs_get_src_req_num); + _MET_SYMBOL_PUT(vcorefs_get_src_req_name); + _MET_SYMBOL_PUT(vcorefs_get_src_req); + +#ifdef VCOREDVFS_OLD_VER + _MET_SYMBOL_PUT(spm_vcorefs_get_MD_status); + _MET_SYMBOL_PUT(spm_vcorefs_register_handler); + _MET_SYMBOL_PUT(vcorefs_register_req_notify); + _MET_SYMBOL_PUT(governor_get_kicker_name); + _MET_SYMBOL_PUT(vcorefs_enable_debug_isr); + _MET_SYMBOL_PUT(vcorefs_get_hw_opp); + _MET_SYMBOL_PUT(vcorefs_get_curr_vcore); + _MET_SYMBOL_PUT(vcorefs_get_curr_ddr); + _MET_SYMBOL_PUT(kicker_table); +#endif + +#endif + +#ifdef MET_EMI + _MET_SYMBOL_PUT(mt_cen_emi_base_get); + _MET_SYMBOL_PUT(mt_chn_emi_base_get); + _MET_SYMBOL_PUT(mtk_dramc_get_data_rate); + _MET_SYMBOL_PUT(mtk_dramc_get_ddr_type); + _MET_SYMBOL_PUT(get_cur_ddr_ratio); + /* legacy emi api before mt6885 */ + _MET_SYMBOL_PUT(get_dram_data_rate); + _MET_SYMBOL_PUT(get_ddr_type); +#endif + +#ifdef MET_PTPOD + _MET_SYMBOL_PUT(mt_gpufreq_get_cur_volt); + _MET_SYMBOL_PUT(mt_cpufreq_get_cur_volt); +#endif + +#ifdef MET_SPM_TWAM + /* ap side used */ +#ifdef SPMTWAM_AP + _MET_SYMBOL_PUT(spm_twam_enable_monitor); + _MET_SYMBOL_PUT(spm_twam_register_handler); + _MET_SYMBOL_PUT(spm_twam_disable_monitor); + _MET_SYMBOL_PUT(spm_twam_set_idle_select); + _MET_SYMBOL_PUT(spm_twam_set_window_length); + _MET_SYMBOL_PUT(spm_twam_set_mon_type); +#endif + + /* sspm side used */ +#ifdef SPMTWAM_SSPM + _MET_SYMBOL_PUT(spm_twam_enable_monitor); + _MET_SYMBOL_PUT(spm_twam_met_enable); + _MET_SYMBOL_PUT(spm_twam_config_channel); +#endif +#endif + + return 0; +} + +int core_plf_init(void) +{ + /*initial met external symbol*/ + met_symbol_get(); + +#ifdef MET_GPU + met_register(&met_gpu); + met_register(&met_gpudvfs); + met_register(&met_gpumem); + met_register(&met_gpupwr); + met_register(&met_gpu_pmu); +#ifdef MET_GPU_STALL_MONITOR + met_register(&met_gpu_stall); +#endif +#endif + +#ifdef MET_VCOREDVFS + met_register(&met_vcoredvfs); +#endif + +#ifdef MET_EMI + met_register(&met_sspm_emi); +#endif + +#ifdef MET_SMI + met_register(&met_sspm_smi); +#endif + +#ifdef MET_PTPOD + met_register(&met_ptpod); +#endif + +#ifdef MET_WALLTIME + met_register(&met_wall_time); +#endif + +#ifdef MTK_TINYSYS_SSPM_SUPPORT + met_register(&met_sspm_common); +#endif + +#if IS_ENABLED(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) +#if defined(ONDIEMET_SUPPORT) || defined(TINYSYS_SSPM_SUPPORT) +#ifdef MET_SSPM_WALLTIME + met_register(&met_sspm_walltime); +#endif +#endif +#endif + +#ifdef MET_CPUDSU + met_register(&met_cpudsu); +#endif + +#ifdef MET_SPM_TWAM + met_register(&met_spmtwam); +#endif + +#ifdef MET_BACKLIGHT + met_register(&met_backlight); +#endif + + return 0; +} + +void core_plf_exit(void) +{ + /*release met external symbol*/ + met_symbol_put(); + +#ifdef MET_GPU + met_deregister(&met_gpu); + met_deregister(&met_gpudvfs); + met_deregister(&met_gpumem); + met_deregister(&met_gpupwr); + met_deregister(&met_gpu_pmu); +#ifdef MET_GPU_STALL_MONITOR + met_deregister(&met_gpu_stall); +#endif +#endif + +#ifdef MET_VCOREDVFS + met_deregister(&met_vcoredvfs); +#endif + +#ifdef MET_EMI + met_deregister(&met_sspm_emi); +#endif + +#ifdef MET_SMI + met_deregister(&met_sspm_smi); +#endif + +#ifdef MET_PTPOD + met_deregister(&met_ptpod); +#endif + +#ifdef MET_WALLTIME + met_deregister(&met_wall_time); +#endif + +#ifdef MTK_TINYSYS_SSPM_SUPPORT +#if defined(ONDIEMET_SUPPORT) || defined(TINYSYS_SSPM_SUPPORT) + met_deregister(&met_sspm_common); +#endif +#endif + +#if IS_ENABLED(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) +#if defined(ONDIEMET_SUPPORT) || defined(TINYSYS_SSPM_SUPPORT) +#ifdef MET_SSPM_WALLTIME + met_deregister(&met_sspm_walltime); +#endif +#endif +#endif + +#ifdef MET_CPUDSU + met_deregister(&met_cpudsu); +#endif + +#ifdef MET_SPM_TWAM + met_deregister(&met_spmtwam); +#endif + +#ifdef MET_BACKLIGHT + met_deregister(&met_backlight); +#endif +} diff --git a/drivers/misc/mediatek/met_drv_v2/common/core_plf_init.h b/drivers/misc/mediatek/met_drv_v2/common/core_plf_init.h new file mode 100644 index 0000000000000000000000000000000000000000..b5a32584b05db2033c420c5b69965dff32720e01 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/core_plf_init.h @@ -0,0 +1,226 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef __CORE_PLF_INIT_H__ +#define __CORE_PLF_INIT_H__ + +extern struct miscdevice met_device; + +/* + * MET External Symbol + */ + +#ifdef MET_GPU +/* + * GPU + */ +#include +#include +#include "met_gpu_monitor.h" + +extern bool mtk_get_gpu_loading(unsigned int *pLoading); +extern bool mtk_get_gpu_block(unsigned int *pBlock); +extern bool mtk_get_gpu_idle(unsigned int *pIdle); +extern bool mtk_get_gpu_dvfs_from(enum MTK_GPU_DVFS_TYPE *peType, unsigned long *pulFreq); +extern bool mtk_get_gpu_sub_loading(unsigned int *pLoading); +extern bool mtk_get_3D_fences_count(int *pi32Count); +extern bool mtk_get_gpu_memory_usage(unsigned int *pMemUsage); +extern bool mtk_get_gpu_power_loading(unsigned int *pLoading); +extern bool mtk_get_custom_boost_gpu_freq(unsigned int *pui32FreqLevel); +extern bool mtk_get_custom_upbound_gpu_freq(unsigned int *pui32FreqLevel); +extern bool mtk_get_vsync_based_target_freq(unsigned long *pulFreq); +extern bool mtk_get_vsync_offset_event_status(unsigned int *pui32EventStatus); +extern bool mtk_get_vsync_offset_debug_status(unsigned int *pui32EventStatus); +extern bool mtk_enable_gpu_perf_monitor(bool enable); +extern bool mtk_get_gpu_pmu_init(struct GPU_PMU *pmus, int pmu_size, int *ret_size); +extern bool mtk_get_gpu_pmu_swapnreset(struct GPU_PMU *pmus, int pmu_size); +extern bool mtk_get_gpu_pmu_deinit(void); +extern bool mtk_get_gpu_pmu_swapnreset_stop(void); + +extern bool (*mtk_get_gpu_loading_symbol)(unsigned int *pLoading); +extern bool (*mtk_get_gpu_block_symbol)(unsigned int *pBlock); +extern bool (*mtk_get_gpu_idle_symbol)(unsigned int *pIdle); +extern bool (*mtk_get_gpu_dvfs_from_symbol)(enum MTK_GPU_DVFS_TYPE *peType, unsigned long *pulFreq); +extern bool (*mtk_get_gpu_sub_loading_symbol)(unsigned int *pLoading); +extern bool (*mtk_get_3D_fences_count_symbol)(int *pi32Count); +extern bool (*mtk_get_gpu_memory_usage_symbol)(unsigned int *pMemUsage); +extern bool (*mtk_get_gpu_power_loading_symbol)(unsigned int *pLoading); +extern bool (*mtk_get_custom_boost_gpu_freq_symbol)(unsigned int *pulFreq); +extern bool (*mtk_get_custom_upbound_gpu_freq_symbol)(unsigned int *pulFreq); +extern bool (*mtk_get_vsync_based_target_freq_symbol)(unsigned long *pulFreq); +extern bool (*mtk_get_vsync_offset_event_status_symbol)(unsigned int *pui32EventStatus); +extern bool (*mtk_get_vsync_offset_debug_status_symbol)(unsigned int *pui32EventStatus); +extern bool (*mtk_enable_gpu_perf_monitor_symbol)(bool enable); +extern bool (*mtk_get_gpu_pmu_init_symbol)(struct GPU_PMU *pmus, int pmu_size, int *ret_size); +extern bool (*mtk_get_gpu_pmu_swapnreset_symbol)(struct GPU_PMU *pmus, int pmu_size); +extern bool (*mtk_get_gpu_pmu_deinit_symbol)(void); +extern bool (*mtk_get_gpu_pmu_swapnreset_stop_symbol)(void); + +extern bool mtk_register_gpu_power_change(const char *name, void (*callback)(int power_on)); +extern bool mtk_unregister_gpu_power_change(const char *name); +extern bool (*mtk_register_gpu_power_change_symbol)(const char *name, + void (*callback)(int power_on)); +extern bool (*mtk_unregister_gpu_power_change_symbol)(const char *name); + + +extern unsigned int mt_gpufreq_get_cur_freq(void); +extern unsigned int mt_gpufreq_get_thermal_limit_freq(void); +extern unsigned int (*mt_gpufreq_get_cur_freq_symbol)(void); +extern unsigned int (*mt_gpufreq_get_thermal_limit_freq_symbol)(void); + +extern struct metdevice met_gpu; +extern struct metdevice met_gpudvfs; +extern struct metdevice met_gpumem; +extern struct metdevice met_gpupwr; +extern struct metdevice met_gpu_pmu; +#ifdef MET_GPU_STALL_MONITOR +extern struct metdevice met_gpu_stall; +#endif +#endif /* MET_GPU */ + + +#ifdef MET_VCOREDVFS +/* + * VCORE DVFS + */ +extern int vcorefs_get_num_opp(void); +extern int vcorefs_get_opp_info_num(void); +extern char ** vcorefs_get_opp_info_name(void); +extern unsigned int * vcorefs_get_opp_info(void); +extern int vcorefs_get_src_req_num(void); +extern char ** vcorefs_get_src_req_name(void); +extern unsigned int * vcorefs_get_src_req(void); + +extern int (*vcorefs_get_num_opp_symbol)(void); +extern int (*vcorefs_get_opp_info_num_symbol)(void); +extern char ** (*vcorefs_get_opp_info_name_symbol)(void); +extern unsigned int * (*vcorefs_get_opp_info_symbol)(void); +extern int (*vcorefs_get_src_req_num_symbol)(void); +extern char ** (*vcorefs_get_src_req_name_symbol)(void); +extern unsigned int * (*vcorefs_get_src_req_symbol)(void); + + +#ifdef VCOREDVFS_OLD_VER + +#include +#include + +extern char *governor_get_kicker_name(int id); +extern int vcorefs_enable_debug_isr(bool); + +extern u32 (*spm_vcorefs_get_MD_status_symbol)(void); +extern void (*spm_vcorefs_register_handler_symbol)(vcorefs_handler_t handler); +extern void (*vcorefs_register_req_notify_symbol)(vcorefs_req_handler_t handler); +extern char *(*governor_get_kicker_name_symbol)(int id); +extern int (*vcorefs_enable_debug_isr_symbol)(bool); +extern int (*vcorefs_get_hw_opp_symbol)(void); +extern int (*vcorefs_get_curr_vcore_symbol)(void); +extern int (*vcorefs_get_curr_ddr_symbol)(void); +extern int *kicker_table_symbol; + +#endif /* VCOREDVFS_OLD_VER */ + +extern struct metdevice met_vcoredvfs; + +#endif /* MET_VCOREDVFS */ + + +#ifdef MET_EMI +extern void *mt_cen_emi_base_get(void); +extern void *mt_chn_emi_base_get(void); +extern unsigned int mtk_dramc_get_data_rate(void); /* in Mhz */ +extern unsigned int mtk_dramc_get_ddr_type(void); +extern int get_cur_ddr_ratio(void); +/* legacy emi api before mt6885 */ +extern unsigned int get_dram_data_rate(void); /* in Mhz */ +extern int get_ddr_type(void); + +extern void *(*mt_cen_emi_base_get_symbol)(void); +extern unsigned int (*mtk_dramc_get_data_rate_symbol)(void); /* in Mhz */ +extern unsigned int (*mtk_dramc_get_ddr_type_symbol)(void); +extern int (*get_cur_ddr_ratio_symbol)(void); +/* legacy emi api before mt6885 */ +extern unsigned int (*get_dram_data_rate_symbol)(void); /* in Mhz */ +extern int (*get_ddr_type_symbol)(void); + + +extern struct metdevice met_sspm_emi; +#endif /* MET_EMI */ + +#ifdef MET_SMI +extern struct metdevice met_sspm_smi; +#endif + +#ifdef MET_PTPOD +#include +#include +#include + +extern unsigned int mt_gpufreq_get_cur_volt(void); +extern unsigned int mt_cpufreq_get_cur_volt(unsigned int cluster_id); +extern unsigned int (*mt_gpufreq_get_cur_volt_symbol)(void); +extern unsigned int (*mt_cpufreq_get_cur_volt_symbol)(unsigned int cluster_id); + +extern struct metdevice met_ptpod; +#endif /* MET_PTPOD */ + +#ifdef MET_WALLTIME +extern struct metdevice met_wall_time; +#endif + +#ifdef MTK_TINYSYS_SSPM_SUPPORT +#if defined(ONDIEMET_SUPPORT) || defined(TINYSYS_SSPM_SUPPORT) +extern struct metdevice met_sspm_common; +#endif +#endif /* MTK_TINYSYS_SSPM_SUPPORT */ + +#if IS_ENABLED(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) +#if defined(ONDIEMET_SUPPORT) || defined(TINYSYS_SSPM_SUPPORT) +#ifdef MET_SSPM_WALLTIME +extern struct metdevice met_sspm_walltime; +#endif +#endif +#endif /* CONFIG_MTK_TINYSYS_SSPM_SUPPORT */ + +#ifdef MET_CPUDSU +extern struct metdevice met_cpudsu; +#endif + +#ifdef MET_SPM_TWAM +#include "mtk_spm.h" + +/* ap side used */ +#ifdef SPMTWAM_AP +extern void spm_twam_enable_monitor(const struct twam_sig *twamsig, bool speed_mode); +extern void spm_twam_register_handler(twam_handler_t handler); +extern void spm_twam_disable_monitor(void); +extern void spm_twam_set_idle_select(unsigned int sel); +extern void spm_twam_set_window_length(unsigned int len); +extern void spm_twam_set_mon_type(struct twam_sig *mon); + +extern void (*spm_twam_enable_monitor_symbol)(const struct twam_sig *twamsig, bool speed_mode); +extern void (*spm_twam_register_handler_symbol)(twam_handler_t handler); +extern void (*spm_twam_disable_monitor_symbol)(void); +extern void (*spm_twam_set_idle_select_symbol)(unsigned int sel); +extern void (*spm_twam_set_window_length_symbol)(unsigned int len); +extern void (*spm_twam_set_mon_type_symbol)(struct twam_sig *mon); +#endif + +/* sspm side used */ +#ifdef SPMTWAM_SSPM +extern void spm_twam_enable_monitor(bool en_monitor, bool debug_signal, twam_handler_t cb_handler); +extern bool spm_twam_met_enable(void); +extern void spm_twam_config_channel(struct twam_cfg *cfg, bool speed_mode, unsigned int window_len_hz); + +extern void (*spm_twam_enable_monitor_symbol)(bool en_monitor, bool debug_signal, twam_handler_t cb_handler); +extern bool (*spm_twam_met_enable_symbol)(void); +extern void (*spm_twam_config_channel_symbol)(struct twam_cfg *cfg, bool speed_mode, unsigned int window_len_hz); +#endif + +extern struct metdevice met_spmtwam; +#endif + + +#endif /*__CORE_PLF_INIT_H__*/ diff --git a/drivers/misc/mediatek/met_drv_v2/common/core_plf_trace.c b/drivers/misc/mediatek/met_drv_v2/common/core_plf_trace.c new file mode 100644 index 0000000000000000000000000000000000000000..2dcb8962632d43617c06d458b3086764be50b161 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/core_plf_trace.c @@ -0,0 +1,314 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include +#include + +#include "met_drv.h" +#include "interface.h" +#include "trace.h" + +char *ms_formatH(char *__restrict__ buf, unsigned char cnt, unsigned int *__restrict__ value) +{ + char *s = buf; + int len; + + if (cnt == 0) { + buf[0] = '\0'; + return buf; + } + + switch (cnt % 4) { + case 1: + len = sprintf(s, "%x", value[0]); + s += len; + value += 1; + cnt -= 1; + break; + case 2: + len = sprintf(s, "%x,%x", value[0], value[1]); + s += len; + value += 2; + cnt -= 2; + break; + case 3: + len = sprintf(s, "%x,%x,%x", value[0], value[1], value[2]); + s += len; + value += 3; + cnt -= 3; + break; + case 0: + len = sprintf(s, "%x,%x,%x,%x", value[0], value[1], value[2], value[3]); + s += len; + value += 4; + cnt -= 4; + break; + } + + while (cnt) { + len = sprintf(s, ",%x,%x,%x,%x", value[0], value[1], value[2], value[3]); + s += len; + value += 4; + cnt -= 4; + } + + s[0] = '\0'; + + return s; +} +EXPORT_SYMBOL(ms_formatH); + +char *ms_formatD(char *__restrict__ buf, unsigned char cnt, unsigned int *__restrict__ value) +{ + char *s = buf; + int len; + + if (cnt == 0) { + buf[0] = '\0'; + return buf; + } + + switch (cnt % 4) { + case 1: + len = sprintf(s, "%u", value[0]); + s += len; + value += 1; + cnt -= 1; + break; + case 2: + len = sprintf(s, "%u,%u", value[0], value[1]); + s += len; + value += 2; + cnt -= 2; + break; + case 3: + len = sprintf(s, "%u,%u,%u", value[0], value[1], value[2]); + s += len; + value += 3; + cnt -= 3; + break; + case 0: + len = sprintf(s, "%u,%u,%u,%u", value[0], value[1], value[2], value[3]); + s += len; + value += 4; + cnt -= 4; + break; + } + + while (cnt) { + len = sprintf(s, ",%u,%u,%u,%u", value[0], value[1], value[2], value[3]); + s += len; + value += 4; + cnt -= 4; + } + + s[0] = '\0'; + + return s; +} +EXPORT_SYMBOL(ms_formatD); + +char *ms_formatH_ulong(char *__restrict__ buf, unsigned char cnt, unsigned long *__restrict__ value) +{ + char *s = buf; + int len; + + if (cnt == 0) { + buf[0] = '\0'; + return buf; + } + + switch (cnt % 4) { + case 1: + len = sprintf(s, "%lx", value[0]); + s += len; + value += 1; + cnt -= 1; + break; + case 2: + len = sprintf(s, "%lx,%lx", value[0], value[1]); + s += len; + value += 2; + cnt -= 2; + break; + case 3: + len = sprintf(s, "%lx,%lx,%lx", value[0], value[1], value[2]); + s += len; + value += 3; + cnt -= 3; + break; + case 0: + len = sprintf(s, "%lx,%lx,%lx,%lx", value[0], value[1], value[2], value[3]); + s += len; + value += 4; + cnt -= 4; + break; + } + + while (cnt) { + len = sprintf(s, ",%lx,%lx,%lx,%lx", value[0], value[1], value[2], value[3]); + s += len; + value += 4; + cnt -= 4; + } + + s[0] = '\0'; + + return buf; +} +EXPORT_SYMBOL(ms_formatH_ulong); + +char *ms_formatD_ulong(char *__restrict__ buf, unsigned char cnt, unsigned long *__restrict__ value) +{ + char *s = buf; + int len; + + if (cnt == 0) { + buf[0] = '\0'; + return buf; + } + + switch (cnt % 4) { + case 1: + len = sprintf(s, "%lu", value[0]); + s += len; + value += 1; + cnt -= 1; + break; + case 2: + len = sprintf(s, "%lu,%lu", value[0], value[1]); + s += len; + value += 2; + cnt -= 2; + break; + case 3: + len = sprintf(s, "%lu,%lu,%lu", value[0], value[1], value[2]); + s += len; + value += 3; + cnt -= 3; + break; + case 0: + len = sprintf(s, "%lu,%lu,%lu,%lu", value[0], value[1], value[2], value[3]); + s += len; + value += 4; + cnt -= 4; + break; + } + + while (cnt) { + len = sprintf(s, ",%lu,%lu,%lu,%lu", value[0], value[1], value[2], value[3]); + s += len; + value += 4; + cnt -= 4; + } + + s[0] = '\0'; + + return buf; +} +EXPORT_SYMBOL(ms_formatD_ulong); + +char *ms_formatH_EOL(char *__restrict__ buf, unsigned char cnt, unsigned int *__restrict__ value) +{ + char *s = buf; + int len; + + if (cnt == 0) { + buf[0] = '\0'; + return buf; + } + + switch (cnt % 4) { + case 1: + len = sprintf(s, "%x", value[0]); + s += len; + value += 1; + cnt -= 1; + break; + case 2: + len = sprintf(s, "%x,%x", value[0], value[1]); + s += len; + value += 2; + cnt -= 2; + break; + case 3: + len = sprintf(s, "%x,%x,%x", value[0], value[1], value[2]); + s += len; + value += 3; + cnt -= 3; + break; + case 0: + len = sprintf(s, "%x,%x,%x,%x", value[0], value[1], value[2], value[3]); + s += len; + value += 4; + cnt -= 4; + break; + } + + while (cnt) { + len = sprintf(s, ",%x,%x,%x,%x", value[0], value[1], value[2], value[3]); + s += len; + value += 4; + cnt -= 4; + } + + s[0] = '\n'; + s[1] = '\0'; + + return s + 1; +} +EXPORT_SYMBOL(ms_formatH_EOL); + +char *ms_formatD_EOL(char *__restrict__ buf, unsigned char cnt, unsigned int *__restrict__ value) +{ + char *s = buf; + int len; + + if (cnt == 0) { + buf[0] = '\0'; + return buf; + } + + switch (cnt % 4) { + case 1: + len = sprintf(s, "%u", value[0]); + s += len; + value += 1; + cnt -= 1; + break; + case 2: + len = sprintf(s, "%u,%u", value[0], value[1]); + s += len; + value += 2; + cnt -= 2; + break; + case 3: + len = sprintf(s, "%u,%u,%u", value[0], value[1], value[2]); + s += len; + value += 3; + cnt -= 3; + break; + case 0: + len = sprintf(s, "%u,%u,%u,%u", value[0], value[1], value[2], value[3]); + s += len; + value += 4; + cnt -= 4; + break; + } + + while (cnt) { + len = sprintf(s, ",%u,%u,%u,%u", value[0], value[1], value[2], value[3]); + s += len; + value += 4; + cnt -= 4; + } + + s[0] = '\n'; + s[1] = '\0'; + + return s + 1; +} +EXPORT_SYMBOL(ms_formatD_EOL); + diff --git a/drivers/misc/mediatek/met_drv_v2/common/core_plf_trace.h b/drivers/misc/mediatek/met_drv_v2/common/core_plf_trace.h new file mode 100644 index 0000000000000000000000000000000000000000..7387b68b57446368ca74482d8185856c417b9d0a --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/core_plf_trace.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef _CORE_PLF_TRACE_H_ +#define _CORE_PLF_TRACE_H_ + +#define HVALUE_SIZE 9 /* 8 chars (max value ffffffff) + 1 char (',' or NULL) */ +#define DVALUE_SIZE 12 /* 10 chars (max value 4,294,967,295) + 1 char (',' or NULL) */ + +char *ms_formatH(char *__restrict__ buf, unsigned char cnt, unsigned int *__restrict__ value); +char *core_ms_formatD(char *__restrict__ buf, unsigned char cnt, unsigned int *__restrict__ value); +char *ms_formatH_ulong(char *__restrict__ buf, unsigned char cnt, + unsigned long *__restrict__ value); +char *ms_formatD_ulong(char *__restrict__ buf, unsigned char cnt, + unsigned long *__restrict__ value); +char *ms_formatH_EOL(char *__restrict__ buf, unsigned char cnt, unsigned int *__restrict__ value); +char *ms_formatD_EOL(char *__restrict__ buf, unsigned char cnt, unsigned int *__restrict__ value); + +#endif /* _CORE_PLF_TRACE_H_ */ diff --git a/drivers/misc/mediatek/met_drv_v2/common/cpu_dsu.c b/drivers/misc/mediatek/met_drv_v2/common/cpu_dsu.c new file mode 100644 index 0000000000000000000000000000000000000000..a523aa57a4898de7ed247a79b5d29f5487802839 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/cpu_dsu.c @@ -0,0 +1,367 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include +#include "met_drv.h" +#include "met_kernel_symbol.h" +#include "interface.h" +#include "trace.h" +#include "cpu_dsu.h" +#include "core_plf_init.h" + + +struct cpu_dsu_hw *cpu_dsu; +static int counter_cnt; +static struct kobject *kobj_dsu; +static int nr_arg; +static unsigned long long perfCurr[MXNR_DSU_EVENTS]; +static unsigned long long perfPrev[MXNR_DSU_EVENTS]; +static int perfCntFirst[MXNR_DSU_EVENTS]; +static struct perf_event * pevent[MXNR_DSU_EVENTS]; +static struct perf_event_attr pevent_attr[MXNR_DSU_EVENTS]; +static unsigned int perf_device_type = 7; +static ssize_t perf_type_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", perf_device_type); +} + +static ssize_t perf_type_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t n) +{ + if (kstrtouint(buf, 0, &perf_device_type) != 0) + return -EINVAL; + + return n; +} +static struct kobj_attribute perf_type_attr = __ATTR(perf_type, 0664, perf_type_show, perf_type_store); + +noinline void mp_dsu(unsigned char cnt, unsigned int *value) +{ + MET_GENERAL_PRINT(MET_TRACE, cnt, value); +} + +static void dummy_handler(struct perf_event *event, struct perf_sample_data *data, + struct pt_regs *regs) +{ + /* + * Required as perf_event_create_kernel_counter() requires an overflow handler, + * even though all we do is poll. + */ +} + +static void perf_cpudsu_polling(unsigned long long stamp, int cpu) +{ + int event_count = cpu_dsu->event_count; + struct met_dsu *pmu = cpu_dsu->pmu; + int i, count; + unsigned long long delta; + struct perf_event *ev; + unsigned int pmu_value[MXNR_DSU_EVENTS]; + u64 value; + int ret; + + count = 0; + for (i = 0; i < event_count; i++) { + if (pmu[i].mode == 0) + continue; + + ev = pevent[i]; + if ((ev != NULL) && (ev->state == PERF_EVENT_STATE_ACTIVE)) { + if (!met_export_api_symbol->met_perf_event_read_local) + continue; + + ret = met_export_api_symbol->met_perf_event_read_local(ev, &value); + if (ret < 0) { + PR_BOOTMSG_ONCE("[MET_DSU] perf_event_read_local fail (ret=%d)\n", ret); + pr_debug("[MET_DSU] perf_event_read_local fail (ret=%d)\n", ret); + continue; + } + + perfCurr[i] = value; + delta = (perfCurr[i] - perfPrev[i]); + perfPrev[i] = perfCurr[i]; + if (perfCntFirst[i] == 1) { + /* we shall omit delta counter when we get first counter */ + perfCntFirst[i] = 0; + continue; + } + pmu_value[count] = (unsigned int)delta; + count++; + } + } + + if (count == counter_cnt) + mp_dsu(count, pmu_value); +} + +static int perf_thread_set_perf_events(unsigned int cpu) +{ + int i, size; + struct perf_event *ev; + struct perf_event_attr *ev_attr; + int event_count = cpu_dsu->event_count; + struct met_dsu *pmu = cpu_dsu->pmu; + + size = sizeof(struct perf_event_attr); + + for (i = 0; i < event_count; i++) { + pevent[i] = NULL; + if (!pmu[i].mode) + continue; /* Skip disabled counters */ + perfPrev[i] = 0; + perfCurr[i] = 0; + ev_attr = pevent_attr+i; + memset(ev_attr, 0, size); + ev_attr->config = pmu[i].event; + ev_attr->type = perf_device_type; + ev_attr->size = size; + ev_attr->sample_period = 0; + ev_attr->pinned = 1; + + ev = perf_event_create_kernel_counter(ev_attr, cpu, NULL, dummy_handler, NULL); + if (IS_ERR(ev)) + continue; + if (ev->state != PERF_EVENT_STATE_ACTIVE) { + perf_event_release_kernel(ev); + continue; + } + pevent[i] = ev; + if (ev != NULL) + perf_event_enable(ev); + + perfCntFirst[i] = 1; + } /* for all PMU counter */ + return 0; +} + +void met_perf_cpudsu_down(void) +{ + int i; + struct perf_event *ev; + int event_count; + struct met_dsu *pmu; + + if (met_cpudsu.mode == 0) + return; + event_count = cpu_dsu->event_count; + pmu = cpu_dsu->pmu; + for (i = 0; i < event_count; i++) { + if (!pmu[i].mode) + continue; + ev = pevent[i]; + if ((ev != NULL) && (ev->state == PERF_EVENT_STATE_ACTIVE)) { + perf_event_disable(ev); + perf_event_release_kernel(ev); + } + pevent[i] = NULL; + } + //perf_delayed_work_setup = NULL; +} + +inline static void met_perf_cpudsu_start(int cpu) +{ + if (met_cpudsu.mode == 0) + return; + if (cpu != 0) + return; + perf_thread_set_perf_events(cpu); +} + +static int cpudsu_create_subfs(struct kobject *parent) +{ + int ret = 0; + cpu_dsu = cpu_dsu_hw_init(); + if (cpu_dsu == NULL) { + PR_BOOTMSG("Failed to init CPU PMU HW!!\n"); + return -ENODEV; + } + kobj_dsu = parent; + ret = sysfs_create_file(kobj_dsu, &perf_type_attr.attr); + if (ret != 0) { + PR_BOOTMSG("Failed to create perf_type in sysfs\n"); + goto out; + } + out: + return ret; +} + +static void cpudsu_delete_subfs(void) +{ +} + +void met_perf_cpudsu_polling(unsigned long long stamp, int cpu) +{ + perf_cpudsu_polling(stamp, cpu); +} + +static void cpudsu_start(void) +{ + int cpu = raw_smp_processor_id(); + for_each_online_cpu(cpu) + met_perf_cpudsu_start(cpu); +} + +static void cpudsu_stop(void) +{ + met_perf_cpudsu_down(); +} + +static const char header[] = + "met-info [000] 0.0: met_dsu_pmu_header: DSU"; + +static const char help[] = + " --dsu=EVENT select DSU-PMU events.\n" + " you can enable at most \"%d general purpose events\"\n"; + +static int cpudsu_print_help(char *buf, int len) +{ + return snprintf(buf, PAGE_SIZE, help, cpu_dsu->event_count); +} + +static int reset_driver_stat(void) +{ + int i; + int event_count; + struct met_dsu *pmu; + + met_cpudsu.mode = 0; + event_count = cpu_dsu->event_count; + pmu = cpu_dsu->pmu; + counter_cnt = 0; + nr_arg = 0; + for (i = 0; i < event_count; i++) { + pmu[i].mode = MODE_DISABLED; + pmu[i].event = 0; + pmu[i].freq = 0; + } + return 0; +} + +static int cpudsu_print_header(char *buf, int len) +{ + int first; + int i, ret; + int event_count; + struct met_dsu *pmu; + ret = 0; + + ret += snprintf(buf + ret, PAGE_SIZE - ret, "# mp_dsu: pmu_value1, ...\n"); + event_count = cpu_dsu->event_count; + pmu = cpu_dsu->pmu; + first = 1; + for (i = 0; i < event_count; i++) { + if (pmu[i].mode == 0) + continue; + if (first) { + ret += snprintf(buf + ret, PAGE_SIZE - ret, header); + first = 0; + } + ret += snprintf(buf + ret, PAGE_SIZE - ret, ",0x%x", pmu[i].event); + pmu[i].mode = 0; + } + ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n"); + reset_driver_stat(); + return ret; +} + +static int met_parse_num_list(char *arg, int len, int *list, int list_cnt) +{ + int nr_num = 0; + char *num; + int num_len; + + /* search ',' as the splitter */ + while (len) { + num = arg; + num_len = 0; + if (list_cnt <= 0) + return -1; + while (len) { + len--; + if (*arg == ',') { + *(arg++) = '\0'; + break; + } + arg++; + num_len++; + } + if (met_parse_num(num, list, num_len) < 0) + return -1; + list++; + list_cnt--; + nr_num++; + } + return nr_num; +} + +static int cpudsu_process_argument(const char *arg, int len) +{ + int nr_events, event_list[MXNR_DSU_EVENTS]; + int i; + int nr_counters; + struct met_dsu *pmu; + int arg_nr; + int counters; + int event_no; + + /* get event_list */ + if ((nr_events = met_parse_num_list((char*)arg, len, event_list, ARRAY_SIZE(event_list))) <= 0) + goto arg_out; + + /* for each cpu in cpu_list, add all the events in event_list */ + nr_counters = cpu_dsu->event_count; + pmu = cpu_dsu->pmu; + arg_nr = nr_arg; + + /* + * setup nr_counters for linux native perf mode. + * because the selected events are stored in pmu, + * so nr_counters can't large then event count in pmu. + */ + counters = perf_num_counters(); + if (counters < nr_counters) + nr_counters = counters; + + if (nr_counters == 0) + goto arg_out; + + for (i = 0; i < nr_events; i++) { + event_no = event_list[i]; + /* + * check if event is duplicate, + * but may not include 0xff when met_cpu_dsu_method == 0. + */ + if (cpu_dsu->check_event(pmu, arg_nr, event_no) < 0) + goto arg_out; + if (arg_nr >= nr_counters) + goto arg_out; + pmu[arg_nr].mode = MODE_POLLING; + pmu[arg_nr].event = event_no; + pmu[arg_nr].freq = 0; + arg_nr++; + counter_cnt++; + } + nr_arg = arg_nr; + met_cpudsu.mode = 1; + return 0; + +arg_out: + reset_driver_stat(); + return -EINVAL; +} + +struct metdevice met_cpudsu = { + .name = "dsu", + .type = MET_TYPE_PMU, + .cpu_related = 0, + .create_subfs = cpudsu_create_subfs, + .delete_subfs = cpudsu_delete_subfs, + .start = cpudsu_start, + .stop = cpudsu_stop, + .polling_interval = 1, + .timed_polling = met_perf_cpudsu_polling, + .print_help = cpudsu_print_help, + .print_header = cpudsu_print_header, + .process_argument = cpudsu_process_argument +}; diff --git a/drivers/misc/mediatek/met_drv_v2/common/cpu_dsu.h b/drivers/misc/mediatek/met_drv_v2/common/cpu_dsu.h new file mode 100644 index 0000000000000000000000000000000000000000..373857fb194025903b4256ffc39379bf647ddc40 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/cpu_dsu.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef _CPU_DSU_H_ +#define _CPU_DSU_H_ + +#include + +#define MODE_DISABLED 0 +#define MODE_INTERRUPT 1 +#define MODE_POLLING 2 + +#define MXNR_CPU NR_CPUS + +#define MXNR_DSU_EVENTS 8 /* max number of pmu counter for armv8 is 6+1 */ +struct met_dsu { + unsigned char mode; + unsigned short event; + unsigned long freq; + struct kobject *kobj_cpu_dsu; +}; + +struct cpu_dsu_hw { + const char *name; + int nr_cnt; + int (*check_event)(struct met_dsu *pmu, int idx, int event); + void (*start)(struct met_dsu *pmu, int count); + void (*stop)(int count); + unsigned int (*polling)(struct met_dsu *pmu, int count, unsigned int *pmu_value); + struct met_dsu *pmu; + int event_count; +}; + + +struct cpu_dsu_hw *cpu_dsu_hw_init(void); + + + +#endif /* _CPU_DSU_H_ */ diff --git a/drivers/misc/mediatek/met_drv_v2/common/cpu_pmu.c b/drivers/misc/mediatek/met_drv_v2/common/cpu_pmu.c new file mode 100644 index 0000000000000000000000000000000000000000..d8dc16634f8a123ed9ad61251719de1379c97639 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/cpu_pmu.c @@ -0,0 +1,1195 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include +#include +#include + +#if (IS_ENABLED(CONFIG_ARM64) || IS_ENABLED(CONFIG_ARM)) +#include +#include +#endif + +#include +#include +#include +#include +#include +#include "met_drv.h" +#include "met_kernel_symbol.h" +#include "interface.h" +#include "trace.h" +#include "cpu_pmu.h" +#include "mtk_typedefs.h" + +#if IS_ENABLED(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) +#if defined(ONDIEMET_SUPPORT) +#include "sspm/ondiemet_sspm.h" +#elif defined(TINYSYS_SSPM_SUPPORT) +#include "tinysys_sspm.h" +#include "tinysys_mgr.h" /* for ondiemet_module */ +#include "sspm_met_ipi_handle.h" +#endif +#endif + +struct cpu_pmu_hw *cpu_pmu; +static int counter_cnt[MXNR_CPU]; +static int nr_arg[MXNR_CPU]; + +int met_perf_cpupmu_status; + +static int mtk_pmu_event_enable = 0; +static struct kobject *kobj_cpu; +DECLARE_KOBJ_ATTR_INT(mtk_pmu_event_enable, mtk_pmu_event_enable); +#define KOBJ_ATTR_LIST \ + do { \ + KOBJ_ATTR_ITEM(mtk_pmu_event_enable); \ + } while (0) + +DEFINE_MUTEX(handle_irq_lock); +irqreturn_t (*handle_irq_orig)(struct arm_pmu *pmu); + +#if IS_ENABLED(CONFIG_CPU_PM) +static int use_cpu_pm_pmu_notifier = 0; + +/* helper notifier for maintaining pmu states before cpu state transition */ +static int cpu_pm_pmu_notify(struct notifier_block *b, + unsigned long cmd, + void *p) +{ + int ii; + int cpu, count; + unsigned int pmu_value[MXNR_PMU_EVENTS]; + + if (!met_perf_cpupmu_status) + return NOTIFY_OK; + + cpu = raw_smp_processor_id(); + + switch (cmd) { + case CPU_PM_ENTER: + count = cpu_pmu->polling(cpu_pmu->pmu[cpu], cpu_pmu->event_count[cpu], pmu_value); + for (ii = 0; ii < count; ii ++) + cpu_pmu->cpu_pm_unpolled_loss[cpu][ii] += pmu_value[ii]; + + cpu_pmu->stop(cpu_pmu->event_count[cpu]); + break; + case CPU_PM_ENTER_FAILED: + case CPU_PM_EXIT: + cpu_pmu->start(cpu_pmu->pmu[cpu], cpu_pmu->event_count[cpu]); + break; + default: + return NOTIFY_DONE; + } + return NOTIFY_OK; +} + +struct notifier_block cpu_pm_pmu_notifier = { + .notifier_call = cpu_pm_pmu_notify, +}; +#endif + +static DEFINE_PER_CPU(unsigned long long[MXNR_PMU_EVENTS], perfCurr); +static DEFINE_PER_CPU(unsigned long long[MXNR_PMU_EVENTS], perfPrev); +static DEFINE_PER_CPU(int[MXNR_PMU_EVENTS], perfCntFirst); +static DEFINE_PER_CPU(struct perf_event * [MXNR_PMU_EVENTS], pevent); +static DEFINE_PER_CPU(struct perf_event_attr [MXNR_PMU_EVENTS], pevent_attr); +static DEFINE_PER_CPU(int, perfSet); +static DEFINE_PER_CPU(int, cpu_status); + +#ifdef CPUPMU_V8_2 +#include +#include + +#ifdef USE_KERNEL_SYNC_WRITE_H +#include +#else +#include "sync_write.h" +#endif + +#ifdef USE_KERNEL_MTK_IO_H +#include +#else +#include "mtk_io.h" +#endif + +static char mcucfg_desc[] = "mediatek,mcucfg"; +static void __iomem *mcucfg_base = NULL; +#define DBG_CONTROL_CPU6 ((unsigned long)mcucfg_base + 0x3000 + 0x308) /* DBG_CONTROL */ +#define DBG_CONTROL_CPU7 ((unsigned long)mcucfg_base + 0x3800 + 0x308) /* DBG_CONTROL */ +#define ENABLE_MTK_PMU_EVENTS_OFFSET 1 +static int restore_dbg_ctrl_cpu6; +static int restore_dbg_ctrl_cpu7; + +int cpu_pmu_debug_init(void) +{ + struct device_node *node = NULL; + unsigned int value6,value7; + + /*for A75 MTK internal event*/ + if (mcucfg_base == NULL) { + node = of_find_compatible_node(NULL, NULL, mcucfg_desc); + if (node == NULL) { + MET_TRACE("[MET_PMU_DB] of_find node == NULL\n"); + pr_debug("[MET_PMU_DB] of_find node == NULL\n"); + goto out; + } + mcucfg_base = of_iomap(node, 0); + of_node_put(node); + if (mcucfg_base == NULL) { + MET_TRACE("[MET_PMU_DB] mcucfg_base == NULL\n"); + pr_debug("[MET_PMU_DB] mcucfg_base == NULL\n"); + goto out; + } + MET_TRACE("[MET_PMU_DB] regbase %08lx\n", DBG_CONTROL_CPU7); + pr_debug("[MET_PMU_DB] regbase %08lx\n", DBG_CONTROL_CPU7); + } + + value6 = readl(IOMEM(DBG_CONTROL_CPU6)); + if (value6 & (1 << ENABLE_MTK_PMU_EVENTS_OFFSET)) { + restore_dbg_ctrl_cpu6 = 1; + } else { + restore_dbg_ctrl_cpu6 = 0; + mt_reg_sync_writel(value6 | (1 << ENABLE_MTK_PMU_EVENTS_OFFSET), DBG_CONTROL_CPU6); + } + + value7 = readl(IOMEM(DBG_CONTROL_CPU7)); + if (value7 & (1 << ENABLE_MTK_PMU_EVENTS_OFFSET)) { + restore_dbg_ctrl_cpu7 = 1; + } else { + restore_dbg_ctrl_cpu7 = 0; + mt_reg_sync_writel(value7 | (1 << ENABLE_MTK_PMU_EVENTS_OFFSET), DBG_CONTROL_CPU7); + } + + value6 = readl(IOMEM(DBG_CONTROL_CPU6)); + value7 = readl(IOMEM(DBG_CONTROL_CPU7)); + MET_TRACE("[MET_PMU_DB]DBG_CONTROL_CPU6 = %08x, DBG_CONTROL_CPU7 = %08x\n", value6, value7); + pr_debug("[MET_PMU_DB]DBG_CONTROL_CPU6 = %08x, DBG_CONTROL_CPU7 = %08x\n", value6, value7); + return 1; + +out: + if (mcucfg_base != NULL) { + iounmap(mcucfg_base); + mcucfg_base = NULL; + } + MET_TRACE("[MET_PMU_DB]DBG_CONTROL init error"); + pr_debug("[MET_PMU_DB]DBG_CONTROL init error"); + return 0; +} + +int cpu_pmu_debug_uninit(void) +{ + unsigned int value6,value7; + + if (restore_dbg_ctrl_cpu6 == 0) { + value6 = readl(IOMEM(DBG_CONTROL_CPU6)); + mt_reg_sync_writel(value6 & (~(1 << ENABLE_MTK_PMU_EVENTS_OFFSET)), DBG_CONTROL_CPU6); + } + if (restore_dbg_ctrl_cpu7 == 0) { + value7 = readl(IOMEM(DBG_CONTROL_CPU7)); + mt_reg_sync_writel(value7 & (~(1 << ENABLE_MTK_PMU_EVENTS_OFFSET)), DBG_CONTROL_CPU7); + } + + value6 = readl(IOMEM(DBG_CONTROL_CPU6)); + value7 = readl(IOMEM(DBG_CONTROL_CPU7)); + MET_TRACE("[MET_PMU_DB]DBG_CONTROL_CPU6 = %08x, DBG_CONTROL_CPU7 = %08x\n", value6, value7); + pr_debug("[MET_PMU_DB]DBG_CONTROL_CPU6 = %08x, DBG_CONTROL_CPU7 = %08x\n", value6, value7); + + if (mcucfg_base != NULL) { + iounmap(mcucfg_base); + mcucfg_base = NULL; + } + restore_dbg_ctrl_cpu6 = 0; + restore_dbg_ctrl_cpu7 = 0; + return 1; +} +#endif + + + + +noinline void mp_cpu(unsigned char cnt, unsigned int *value) +{ + MET_GENERAL_PRINT(MET_TRACE, cnt, value); +} + +static void dummy_handler(struct perf_event *event, struct perf_sample_data *data, + struct pt_regs *regs) +{ + /* + * Required as perf_event_create_kernel_counter() requires an overflow handler, + * even though all we do is poll. + */ +} + +static void perf_cpupmu_polling(unsigned long long stamp, int cpu) +{ + int event_count = cpu_pmu->event_count[cpu]; + struct met_pmu *pmu = cpu_pmu->pmu[cpu]; + int i, count; + unsigned long long delta; + struct perf_event *ev; + unsigned int pmu_value[MXNR_PMU_EVENTS]; + u64 value; + int ret; + + if (per_cpu(perfSet, cpu) == 0) + return; + + count = 0; + for (i = 0; i < event_count; i++) { + if (pmu[i].mode == 0) + continue; + + ev = per_cpu(pevent, cpu)[i]; + if ((ev != NULL) && (ev->state == PERF_EVENT_STATE_ACTIVE)) { + if (!met_export_api_symbol->met_perf_event_read_local) + continue; + + ret = met_export_api_symbol->met_perf_event_read_local(ev, &value); + if (ret < 0) { + PR_BOOTMSG_ONCE("[MET_PMU] perf_event_read_local fail (ret=%d)\n", ret); + pr_debug("[MET_PMU] perf_event_read_local fail (ret=%d)\n", ret); + continue; + } + + per_cpu(perfCurr, cpu)[i] = value; + delta = (per_cpu(perfCurr, cpu)[i] - per_cpu(perfPrev, cpu)[i]); + per_cpu(perfPrev, cpu)[i] = per_cpu(perfCurr, cpu)[i]; + if (per_cpu(perfCntFirst, cpu)[i] == 1) { + /* we shall omit delta counter when we get first counter */ + per_cpu(perfCntFirst, cpu)[i] = 0; + continue; + } + pmu_value[count] = (unsigned int)delta; + count++; + } + } + + if (count == counter_cnt[cpu]) + mp_cpu(count, pmu_value); +} + +static struct perf_event* perf_event_create(int cpu, unsigned short event, int count) +{ + struct perf_event_attr *ev_attr; + struct perf_event *ev; + + ev_attr = per_cpu(pevent_attr, cpu)+count; + memset(ev_attr, 0, sizeof(*ev_attr)); + if (event == 0xff) { + ev_attr->config = PERF_COUNT_HW_CPU_CYCLES; + ev_attr->type = PERF_TYPE_HARDWARE; + } else { + ev_attr->config = event; + ev_attr->type = PERF_TYPE_RAW; + } + ev_attr->size = sizeof(*ev_attr); + ev_attr->sample_period = 0; + ev_attr->pinned = 1; + + ev = perf_event_create_kernel_counter(ev_attr, cpu, NULL, dummy_handler, NULL); + if (IS_ERR(ev)) + return NULL; + do { + if (ev->state == PERF_EVENT_STATE_ACTIVE) + break; + if (ev->state == PERF_EVENT_STATE_ERROR) { + perf_event_enable(ev); + if (ev->state == PERF_EVENT_STATE_ACTIVE) + break; + } + perf_event_release_kernel(ev); + return NULL; + } while (0); + + return ev; +} + +static void perf_event_release(int cpu, struct perf_event *ev) +{ + if (ev->state == PERF_EVENT_STATE_ACTIVE) + perf_event_disable(ev); + perf_event_release_kernel(ev); +} + +#if IS_ENABLED(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) +#if defined(ONDIEMET_SUPPORT) || defined(TINYSYS_SSPM_SUPPORT) +#define PMU_OVERFLOWED_MASK 0xffffffff + +static inline int pmu_has_overflowed(u32 pmovsr) +{ + return pmovsr & PMU_OVERFLOWED_MASK; +} + +static irqreturn_t perf_event_handle_irq_ignore_overflow(struct arm_pmu *pmu) +{ + u32 pmovsr; + + pmovsr = cpu_pmu->pmu_read_clear_overflow_flag(); + + if (!pmu_has_overflowed(pmovsr)) { + return IRQ_NONE; + } + else { + irq_work_run(); + return IRQ_HANDLED; + } +} +#endif +#endif + +static int perf_thread_set_perf_events(int cpu) +{ + int i, size; + struct perf_event *ev; + + size = sizeof(struct perf_event_attr); + if (per_cpu(perfSet, cpu) == 0) { + int event_count = cpu_pmu->event_count[cpu]; + struct met_pmu *pmu = cpu_pmu->pmu[cpu]; + for (i = 0; i < event_count; i++) { + if (!pmu[i].mode) + continue; /* Skip disabled counters */ + ev = perf_event_create(cpu, pmu[i].event, i); + if (ev == NULL) { + met_cpupmu.mode = 0; + met_perf_cpupmu_status = 0; + + MET_TRACE("[MET_PMU] cpu %d failed to register pmu event %4x\n", cpu, pmu[i].event); + pr_notice("[MET_PMU] cpu %d failed to register pmu event %4x\n", cpu, pmu[i].event); + continue; + } + + /* + * in perf-event implementation, hardware pmu slot and cycle counter + * was mapped to perf_event::hw::idx as follows: + * + * | idx | hardware slot | + * |-----+---------------| + * | 0 | pmccntr_el0 | + * | 1 | 0 | + * | 2 | 1 | + * | 3 | 2 | + * | 4 | 3 | + * | 5 | 4 | + * | 6 | 5 | + */ + if (ev->hw.idx != 0) { + MET_TRACE("[MET_PMU] cpu %d registered in pmu slot: [%d] evt=%#04x\n", + cpu, ev->hw.idx-1, pmu[i].event); + pr_debug("[MET_PMU] cpu %d registered in pmu slot: [%d] evt=%#04x\n", + cpu, ev->hw.idx-1, pmu[i].event); + } else if (ev->hw.idx == 0) { + MET_TRACE("[MET_PMU] cpu %d registered cycle count evt=%#04x\n", + cpu, pmu[i].event); + pr_debug("[MET_PMU] cpu %d registered cycle count evt=%#04x\n", + cpu, pmu[i].event); + } + + per_cpu(pevent, cpu)[i] = ev; + per_cpu(perfPrev, cpu)[i] = 0; + per_cpu(perfCurr, cpu)[i] = 0; + perf_event_enable(ev); + per_cpu(perfCntFirst, cpu)[i] = 1; + +#if IS_ENABLED(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) +#if defined(ONDIEMET_SUPPORT) || defined(TINYSYS_SSPM_SUPPORT) + if (met_cpupmu.ondiemet_mode) { + struct arm_pmu *armpmu; + armpmu = container_of(ev->pmu, struct arm_pmu, pmu); + mutex_lock(&handle_irq_lock); + if (armpmu && armpmu->handle_irq != perf_event_handle_irq_ignore_overflow) { + pr_debug("[MET_PMU] replaced original handle_irq=%p with dummy function\n", + armpmu->handle_irq); + handle_irq_orig = armpmu->handle_irq; + armpmu->handle_irq = perf_event_handle_irq_ignore_overflow; + } + mutex_unlock(&handle_irq_lock); + } +#endif +#endif + } /* for all PMU counter */ + per_cpu(perfSet, cpu) = 1; + } /* for perfSet */ + + return 0; +} + +static void met_perf_cpupmu_start(int cpu) +{ + if (met_cpupmu.mode == 0) + return; + + perf_thread_set_perf_events(cpu); +} + +static void perf_thread_down(int cpu) +{ + int i; + struct perf_event *ev; + int event_count; + struct met_pmu *pmu; + + if (per_cpu(perfSet, cpu) == 0) + return; + + per_cpu(perfSet, cpu) = 0; + event_count = cpu_pmu->event_count[cpu]; + pmu = cpu_pmu->pmu[cpu]; + for (i = 0; i < event_count; i++) { + ev = per_cpu(pevent, cpu)[i]; + if (ev != NULL) { + +#if IS_ENABLED(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) +#if defined(ONDIEMET_SUPPORT) || defined(TINYSYS_SSPM_SUPPORT) + if (met_cpupmu.ondiemet_mode) { + struct arm_pmu *armpmu; + armpmu = container_of(ev->pmu, struct arm_pmu, pmu); + mutex_lock(&handle_irq_lock); + if (armpmu && armpmu->handle_irq == perf_event_handle_irq_ignore_overflow) { + pr_debug("[MET_PMU] restore original handle_irq=%p\n", handle_irq_orig); + armpmu->handle_irq = handle_irq_orig; + handle_irq_orig = NULL; + } + mutex_unlock(&handle_irq_lock); + } +#endif +#endif + + perf_event_release(cpu, ev); + per_cpu(pevent, cpu)[i] = NULL; + } + } +} + +static void met_perf_cpupmu_stop(int cpu) +{ + perf_thread_down(cpu); +} + +static int cpupmu_create_subfs(struct kobject *parent) +{ + int ret = 0; + + cpu_pmu = cpu_pmu_hw_init(); + if (cpu_pmu == NULL) { + PR_BOOTMSG("Failed to init CPU PMU HW!!\n"); + return -ENODEV; + } + + kobj_cpu = parent; + +#define KOBJ_ATTR_ITEM(attr_name) \ + do { \ + ret = sysfs_create_file(kobj_cpu, &attr_name ## _attr.attr); \ + if (ret != 0) { \ + pr_notice("Failed to create " #attr_name " in sysfs\n"); \ + return ret; \ + } \ + } while (0) + KOBJ_ATTR_LIST; +#undef KOBJ_ATTR_ITEM + + return 0; +} + +static void cpupmu_delete_subfs(void) +{ +#define KOBJ_ATTR_ITEM(attr_name) \ + sysfs_remove_file(kobj_cpu, &attr_name ## _attr.attr) + + if (kobj_cpu != NULL) { + KOBJ_ATTR_LIST; + kobj_cpu = NULL; + } +#undef KOBJ_ATTR_ITEM +} + +void met_perf_cpupmu_polling(unsigned long long stamp, int cpu) +{ + int count; + unsigned int pmu_value[MXNR_PMU_EVENTS]; + + if (per_cpu(cpu_status, cpu) != MET_CPU_ONLINE) + return; + + if (met_cpu_pmu_method) { + perf_cpupmu_polling(stamp, cpu); + } else { + count = cpu_pmu->polling(cpu_pmu->pmu[cpu], cpu_pmu->event_count[cpu], pmu_value); + +#if IS_ENABLED(CONFIG_CPU_PM) + if (met_cpu_pm_pmu_reconfig) { + int ii; + for (ii = 0; ii < count; ii ++) + pmu_value[ii] += cpu_pmu->cpu_pm_unpolled_loss[cpu][ii]; + } +#endif + + mp_cpu(count, pmu_value); + +#if IS_ENABLED(CONFIG_CPU_PM) + if (met_cpu_pm_pmu_reconfig) { + memset(cpu_pmu->cpu_pm_unpolled_loss[cpu], 0, sizeof (cpu_pmu->cpu_pm_unpolled_loss[0])); + } +#endif + } +} + +static void cpupmu_start(void) +{ + int cpu = raw_smp_processor_id(); + + if (!met_cpu_pmu_method) { + nr_arg[cpu] = 0; + cpu_pmu->start(cpu_pmu->pmu[cpu], cpu_pmu->event_count[cpu]); + + met_perf_cpupmu_status = 1; + per_cpu(cpu_status, cpu) = MET_CPU_ONLINE; + } +} + + +static void cpupmu_unique_start(void) +{ + int cpu; + +#ifdef CPUPMU_V8_2 + int ret = 0; + if (mtk_pmu_event_enable == 1){ + ret = cpu_pmu_debug_init(); + if (ret == 0) + PR_BOOTMSG("Failed to init CPU PMU debug!!\n"); + } +#endif + +#if IS_ENABLED(CONFIG_CPU_PM) + use_cpu_pm_pmu_notifier = 0; + if (met_cpu_pm_pmu_reconfig) { + if (met_cpu_pmu_method) { + met_cpu_pm_pmu_reconfig = 0; + MET_TRACE("[MET_PMU] met_cpu_pmu_method=%d, met_cpu_pm_pmu_reconfig forced disabled\n", met_cpu_pmu_method); + pr_debug("[MET_PMU] met_cpu_pmu_method=%d, met_cpu_pm_pmu_reconfig forced disabled\n", met_cpu_pmu_method); + } else { + memset(cpu_pmu->cpu_pm_unpolled_loss, 0, sizeof (cpu_pmu->cpu_pm_unpolled_loss)); + cpu_pm_register_notifier(&cpu_pm_pmu_notifier); + use_cpu_pm_pmu_notifier = 1; + } + } +#else + if (met_cpu_pm_pmu_reconfig) { + met_cpu_pm_pmu_reconfig = 0; + MET_TRACE("[MET_PMU] CONFIG_CPU_PM=%d, met_cpu_pm_pmu_reconfig forced disabled\n", CONFIG_CPU_PM); + pr_debug("[MET_PMU] CONFIG_CPU_PM=%d, met_cpu_pm_pmu_reconfig forced disabled\n", CONFIG_CPU_PM); + } +#endif + MET_TRACE("[MET_PMU] met_cpu_pm_pmu_reconfig=%u\n", met_cpu_pm_pmu_reconfig); + pr_debug("[MET_PMU] met_cpu_pm_pmu_reconfig=%u\n", met_cpu_pm_pmu_reconfig); + + if (met_cpu_pmu_method) { + for_each_possible_cpu(cpu) { + met_perf_cpupmu_start(cpu); + + met_perf_cpupmu_status = 1; + per_cpu(cpu_status, cpu) = MET_CPU_ONLINE; + } + } + + return; +} + +static void cpupmu_stop(void) +{ + int cpu = raw_smp_processor_id(); + + met_perf_cpupmu_status = 0; + + if (!met_cpu_pmu_method) + cpu_pmu->stop(cpu_pmu->event_count[cpu]); +} + +static void cpupmu_unique_stop(void) +{ + int cpu; + + if (met_cpu_pmu_method) { + for_each_possible_cpu(cpu) { + met_perf_cpupmu_stop(cpu); + } + } + +#ifdef CPUPMU_V8_2 + if (mtk_pmu_event_enable == 1) + cpu_pmu_debug_uninit(); +#endif + +#if IS_ENABLED(CONFIG_CPU_PM) + if (use_cpu_pm_pmu_notifier) { + cpu_pm_unregister_notifier(&cpu_pm_pmu_notifier); + } +#endif + return; +} + +static const char cache_line_header[] = + "met-info [000] 0.0: met_cpu_cache_line_size: %d\n"; +static const char header[] = + "met-info [000] 0.0: met_cpu_header_v2: %d"; + +static const char help[] = + " --pmu-cpu-evt=[cpu_list:]event_list select CPU-PMU events in %s\n" + " cpu_list: specify the cpu_id list or apply to all the cores\n" + " example: 0,1,2\n" + " event_list: specify the event number\n" + " example: 0x8,0xff\n"; + +static int cpupmu_print_help(char *buf, int len) +{ + return snprintf(buf, PAGE_SIZE, help, cpu_pmu->cpu_name); +} + +static int reset_driver_stat(void) +{ + int cpu, i; + int event_count; + struct met_pmu *pmu; + + met_cpupmu.mode = 0; + for_each_possible_cpu(cpu) { + event_count = cpu_pmu->event_count[cpu]; + pmu = cpu_pmu->pmu[cpu]; + counter_cnt[cpu] = 0; + nr_arg[cpu] = 0; + for (i = 0; i < event_count; i++) { + pmu[i].mode = MODE_DISABLED; + pmu[i].event = 0; + pmu[i].freq = 0; + } + } + + return 0; +} + +static int cpupmu_print_header(char *buf, int len) +{ + int cpu, i, ret, first; + int event_count; + struct met_pmu *pmu; + + ret = 0; + + /*append CPU PMU access method*/ + if (met_cpu_pmu_method) + ret += snprintf(buf + ret, len, + "met-info [000] 0.0: CPU_PMU_method: perf APIs\n"); + else + ret += snprintf(buf + ret, len, + "met-info [000] 0.0: CPU_PMU_method: MET pmu driver\n"); + + /*append cache line size*/ + ret += snprintf(buf + ret, len - ret, cache_line_header, cache_line_size()); + ret += snprintf(buf + ret, len - ret, "# mp_cpu: pmu_value1, ...\n"); + + for_each_possible_cpu(cpu) { + event_count = cpu_pmu->event_count[cpu]; + pmu = cpu_pmu->pmu[cpu]; + first = 1; + for (i = 0; i < event_count; i++) { + if (pmu[i].mode == 0) + continue; + if (first) { + ret += snprintf(buf + ret, len - ret, header, cpu); + first = 0; + } + ret += snprintf(buf + ret, len - ret, ",0x%x", pmu[i].event); + pmu[i].mode = 0; + } + if (!first) + ret += snprintf(buf + ret, len - ret, "\n"); + } + + reset_driver_stat(); + + return ret; +} + +static int met_parse_num_list(char *arg, int len, int *list, int list_cnt) +{ + int nr_num = 0; + char *num; + int num_len; + + /* search ',' as the splitter */ + while (len) { + num = arg; + num_len = 0; + if (list_cnt <= 0) + return -1; + while (len) { + len--; + if (*arg == ',') { + *(arg++) = '\0'; + break; + } + arg++; + num_len++; + } + if (met_parse_num(num, list, num_len) < 0) + return -1; + list++; + list_cnt--; + nr_num++; + } + + return nr_num; +} + +static const struct perf_pmu_events_attr * +perf_event_get_evt_attr_by_name(const struct perf_event *ev, + const char *name) { + struct arm_pmu *arm_pmu; + struct attribute **attrp; + struct device_attribute *dev_attr_p; + struct perf_pmu_events_attr *ev_attr_p; + + arm_pmu = container_of(ev->pmu, struct arm_pmu, pmu); + + for (attrp = arm_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS]->attrs; + *attrp != NULL; + attrp ++) { + + dev_attr_p = container_of(*attrp, struct device_attribute, attr); + ev_attr_p = container_of(dev_attr_p, struct perf_pmu_events_attr, attr); + + if (0 == strcmp((*attrp)->name, name)) { + return ev_attr_p; + } + } + + return NULL; +} + +static int cpupmu_process_argument(const char *arg, int len) +{ + char *arg1 = (char*)arg; + int len1 = len; + int cpu, cpu_list[MXNR_CPU]; + int nr_events, event_list[MXNR_PMU_EVENTS]; + int i; + int nr_counters; + struct met_pmu *pmu; + int arg_nr; + int event_no; + int is_cpu_cycle_evt; + const struct perf_pmu_events_attr *ev_attr_p; + + /* + * split cpu_list and event_list by ':' + * arg, len: cpu_list when found (i < len) + * arg1, len1: event_list + */ + for (i = 0; i < len; i++) { + if (arg[i] == ':') { + arg1[i] = '\0'; + arg1 += i+1; + len1 = len - i - 1; + len = i; + break; + } + } + + /* + * setup cpu_list array + * 1: selected + * 0: unselected + */ + if (arg1 != arg) { /* is cpu_id list specified? */ + int list[MXNR_CPU], cnt; + int cpu_id; + if ((cnt = met_parse_num_list((char*)arg, len, list, ARRAY_SIZE(list))) <= 0) + goto arg_out; + memset(cpu_list, 0, sizeof(cpu_list)); + for (i = 0; i < cnt; i++) { + cpu_id = list[i]; + if (cpu_id < 0 || cpu_id >= ARRAY_SIZE(cpu_list)) + goto arg_out; + cpu_list[cpu_id] = 1; + } + } + else + memset(cpu_list, 1, sizeof(cpu_list)); + + /* get event_list */ + if ((nr_events = met_parse_num_list(arg1, len1, event_list, ARRAY_SIZE(event_list))) <= 0) + goto arg_out; + + /* for each cpu in cpu_list, add all the events in event_list */ + for_each_possible_cpu(cpu) { + pmu = cpu_pmu->pmu[cpu]; + arg_nr = nr_arg[cpu]; + + if (cpu_list[cpu] == 0) + continue; + + if (met_cpu_pmu_method) { + nr_counters = perf_num_counters(); + } else { + nr_counters = cpu_pmu->event_count[cpu]; + } + + pr_debug("[MET_PMU] pmu slot count=%d\n", nr_counters); + + if (nr_counters == 0) + goto arg_out; + + for (i = 0; i < nr_events; i++) { + event_no = event_list[i]; + is_cpu_cycle_evt = 0; + /* + * check if event is duplicate, but does not include 0xff + */ + if (cpu_pmu->check_event(pmu, arg_nr, event_no) < 0) + goto arg_out; + + /* + * test if this event is available when in perf_APIs mode + */ + if (met_cpu_pmu_method) { + struct perf_event *ev; + + if (!cpu_pmu->perf_event_get_evttype) { + MET_TRACE("[MET_PMU] cpu_pmu->perf_event_get_evttype=NULL, " + "met pmu on perf-event was not supported on this platform\n"); + pr_debug("[MET_PMU] cpu_pmu->perf_event_get_evttype=NULL, " + "met pmu on perf-event was not supported on this platform\n"); + goto arg_out; + } + + ev = perf_event_create(cpu, event_no, arg_nr); + if (ev == NULL) { + pr_debug("!!!!!!!! [MET_PMU] failed pmu alloction test (event_no=%#04x)\n", event_no); + goto arg_out; + } else { + perf_event_release(cpu, ev); + } + + ev_attr_p = perf_event_get_evt_attr_by_name(ev, "cpu_cycles"); + if (ev_attr_p && cpu_pmu->perf_event_get_evttype(ev) == ev_attr_p->id) + is_cpu_cycle_evt = 1; + } + + if (met_cpu_pmu_method) { + if (is_cpu_cycle_evt) { + if (pmu[nr_counters-1].mode == MODE_POLLING) + goto arg_out; + pmu[nr_counters-1].mode = MODE_POLLING; + pmu[nr_counters-1].event = event_no; + pmu[nr_counters-1].freq = 0; + } else { + if (arg_nr >= (nr_counters - 1)) + goto arg_out; + pmu[arg_nr].mode = MODE_POLLING; + pmu[arg_nr].event = event_no; + pmu[arg_nr].freq = 0; + arg_nr++; + } + } else { + if (event_no == 0xff) { + if (pmu[nr_counters-1].mode == MODE_POLLING) + goto arg_out; + pmu[nr_counters-1].mode = MODE_POLLING; + pmu[nr_counters-1].event = 0xff; + pmu[nr_counters-1].freq = 0; + } else { + if (arg_nr >= (nr_counters - 1)) + goto arg_out; + pmu[arg_nr].mode = MODE_POLLING; + pmu[arg_nr].event = event_no; + pmu[arg_nr].freq = 0; + arg_nr++; + } + } + counter_cnt[cpu]++; + } + nr_arg[cpu] = arg_nr; + } + + met_cpupmu.mode = 1; + return 0; + +arg_out: + reset_driver_stat(); + return -EINVAL; +} + +static void cpupmu_cpu_state_notify(long cpu, unsigned long action) +{ + per_cpu(cpu_status, cpu) = action; + +#if (IS_ENABLED(CONFIG_ARM64) || IS_ENABLED(CONFIG_ARM)) + if (met_cpu_pmu_method && action == MET_CPU_OFFLINE) { + struct perf_event *event = NULL; + struct arm_pmu *armpmu = NULL; + struct platform_device *pmu_device = NULL; + int irq = 0; + + event = per_cpu(pevent, cpu)[0]; + if (event) + armpmu = to_arm_pmu(event->pmu); + pr_debug("!!!!!!!! %s_%ld, event=%p\n", __FUNCTION__, cpu, event); + + if (armpmu) + pmu_device = armpmu->plat_device; + pr_debug("!!!!!!!! %s_%ld, armpmu=%p\n", __FUNCTION__, cpu, armpmu); + + if (pmu_device) + irq = platform_get_irq(pmu_device, 0); + pr_debug("!!!!!!!! %s_%ld, pmu_device=%p\n", __FUNCTION__, cpu, pmu_device); + + if (irq > 0) + disable_percpu_irq(irq); + pr_debug("!!!!!!!! %s_%ld, irq=%d\n", __FUNCTION__, cpu, irq); + } +#endif +} + +#if IS_ENABLED(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) +#if defined(ONDIEMET_SUPPORT) || defined(TINYSYS_SSPM_SUPPORT) +static void sspm_pmu_start(void) +{ + ondiemet_module[ONDIEMET_SSPM] |= ID_PMU; + + if (met_cpupmu.ondiemet_mode == 1) + cpupmu_start(); +} + +static int cycle_count_mode_enabled(int cpu) { + + int event_cnt; + struct met_pmu *pmu; + + pmu = cpu_pmu->pmu[cpu]; + + if (met_cpu_pmu_method) { + event_cnt = perf_num_counters(); + } else { + event_cnt = cpu_pmu->event_count[cpu]; + } + + return pmu[event_cnt-1].mode == MODE_POLLING; +} + +static void ipi_config_pmu_counter_cnt(void) { + + int ret, cpu, ii, cnt_num; + unsigned int rdata; + unsigned int ipi_buf[4]; + struct hw_perf_event *hwc; + unsigned int base_offset; + + for_each_possible_cpu(cpu) { + for (ii = 0; ii < 4; ii++) + ipi_buf[ii] = 0; + + ipi_buf[0] = MET_MAIN_ID | (MID_PMU << MID_BIT_SHIFT) | MET_ARGU | SET_PMU_EVT_CNT; + /* + * XXX: on sspm side, cycle counter was not counted in + * total event number `counter_cnt', but controlled by + * an addtional argument `SET_PMU_CYCCNT_ENABLE' instead + */ + cnt_num = (cycle_count_mode_enabled(cpu) ? + (counter_cnt[cpu]-1) : counter_cnt[cpu]); + ipi_buf[1] = (cpu << 16) | (cnt_num & 0xffff); + + MET_TRACE("[MET_PMU][IPI_CONFIG] core=%d, pmu_counter_cnt=%d\n", cpu, cnt_num); + pr_debug("[MET_PMU][IPI_CONFIG] core=%d, pmu_counter_cnt=%d\n", cpu, cnt_num); + + MET_TRACE("[MET_PMU][IPI_CONFIG] sspm_buf_available=%d, in_interrupt()=%lu\n", sspm_buf_available, in_interrupt()); + pr_debug("[MET_PMU][IPI_CONFIG] sspm_buf_available=%d, in_interrupt()=%lu\n", sspm_buf_available, in_interrupt()); + + if (sspm_buf_available == 1) { + ret = met_ipi_to_sspm_command((void *) ipi_buf, 0, &rdata, 1); + } + + for (ii = 0; ii < 4; ii++) + ipi_buf[ii] = 0; + + if (per_cpu(pevent, cpu)[0]) { + hwc = &(per_cpu(pevent, cpu)[0]->hw); + base_offset = hwc->idx-1; + } else { + base_offset = 0; + } + + ipi_buf[0] = MET_MAIN_ID | (MID_PMU << MID_BIT_SHIFT) | MET_ARGU | SET_PMU_BASE_OFFSET; + ipi_buf[1] = (cpu << 16) | (base_offset & 0xffff); + + MET_TRACE("[MET_PMU][IPI_CONFIG] core=%d, base offset set to %lu\n", cpu, base_offset); + pr_debug("[MET_PMU][IPI_CONFIG] core=%d, base offset set to %lu\n", cpu, base_offset); + + if (sspm_buf_available == 1) { + ret = met_ipi_to_sspm_command((void *) ipi_buf, 0, &rdata, 1); + } + + if (cycle_count_mode_enabled(cpu)) { + + for (ii = 0; ii < 4; ii++) + ipi_buf[ii] = 0; + + ipi_buf[0] = MET_MAIN_ID | (MID_PMU << MID_BIT_SHIFT) | MET_ARGU | SET_PMU_CYCCNT_ENABLE; + ipi_buf[1] = cpu & 0xffff; + + MET_TRACE("[MET_PMU][IPI_CONFIG] core=%d, pmu cycle cnt enable\n", cpu); + pr_debug("[MET_PMU][IPI_CONFIG] core=%d, pmu cycle cnt enable\n", cpu); + + if (sspm_buf_available == 1) { + ret = met_ipi_to_sspm_command((void *) ipi_buf, 0, &rdata, 1); + } + } + } +} + +static int __is_perf_event_hw_slot_seq_order(int cpu) { + + struct hw_perf_event *hwc, *hwc_prev; + int event_count = cpu_pmu->event_count[cpu]; + int ii; + + /* + * perf-event descriptor list would not have any hole + * (excepts special 0xff, which will always be the last element) + */ + if (per_cpu(pevent, cpu)[0] == NULL) + return 1; + + /* + * XXX: no need to check the last slot, + * which is reserved for 0xff + */ + for (ii = 1; ii < event_count - 1; ii++) { + + if (per_cpu(pevent, cpu)[ii] == NULL) + return 1; + + hwc = &(per_cpu(pevent, cpu)[ii]->hw); + hwc_prev = &(per_cpu(pevent, cpu)[ii-1]->hw); + + if (hwc->idx != hwc_prev->idx + 1) + return 0; + } + + return 1; +} + +static int __validate_sspm_compatibility(void) { + + int cpu; + + for_each_possible_cpu(cpu) { + + if (!__is_perf_event_hw_slot_seq_order(cpu)) { + MET_TRACE("[MET_PMU] pmu not sequentially allocated on cpu %d\n" + ,cpu); + pr_debug("[MET_PMU] pmu not sequentially allocated on cpu %d\n" + ,cpu); + return -1; + } + } + + return 0; +} + +static void sspm_pmu_unique_start(void) { + + if (met_cpupmu.ondiemet_mode == 1) + cpupmu_unique_start(); + + if (met_cpupmu.ondiemet_mode == 1) { + if (__validate_sspm_compatibility() == -1) { + MET_TRACE("[MET_PMU] turned off sspm side polling\n"); + pr_debug("[MET_PMU] turned off sspm side polling\n"); + /* return without sending init IPIs, leaving sspm side to poll nothing */ + return; + } + } + + ipi_config_pmu_counter_cnt(); +} + +static void sspm_pmu_unique_stop(void) +{ + if (met_cpupmu.ondiemet_mode == 1) + cpupmu_unique_stop(); + return; +} + +static void sspm_pmu_stop(void) +{ + if (met_cpupmu.ondiemet_mode == 1) + cpupmu_stop(); +} + +static const char sspm_pmu_header[] = "met-info [000] 0.0: pmu_sampler: sspm\n"; + +static int sspm_pmu_print_header(char *buf, int len) +{ + int ret; + + ret = snprintf(buf, len, sspm_pmu_header); + + if (met_cpupmu.ondiemet_mode == 1) + ret += cpupmu_print_header(buf + ret, len - ret); + + return ret; +} + +static int sspm_pmu_process_argument(const char *arg, int len) +{ + if (met_cpupmu.ondiemet_mode == 1) { + + if (!cpu_pmu->pmu_read_clear_overflow_flag) { + MET_TRACE("[MET_PMU] cpu_pmu->pmu_read_clear_overflow_flag=NULL, " + "pmu on sspm was not supported on this platform\n"); + pr_debug("[MET_PMU] cpu_pmu->pmu_read_clear_overflow_flag=NULL, " + "pmu on sspm was not supported on this platform\n"); + return -EINVAL; + } + + return cpupmu_process_argument(arg, len); + } + return 0; +} +#endif /* end of #if defined(ONDIEMET_SUPPORT) || defined(TINYSYS_SSPM_SUPPORT) */ +#endif /* end of #if defined(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) */ + +struct metdevice met_cpupmu = { + .name = "cpu", + .type = MET_TYPE_PMU, + .cpu_related = 1, + .create_subfs = cpupmu_create_subfs, + .delete_subfs = cpupmu_delete_subfs, + .start = cpupmu_start, + .uniq_start = cpupmu_unique_start, + .stop = cpupmu_stop, + .uniq_stop = cpupmu_unique_stop, + .polling_interval = 1, + .timed_polling = met_perf_cpupmu_polling, + .print_help = cpupmu_print_help, + .print_header = cpupmu_print_header, + .process_argument = cpupmu_process_argument, + .cpu_state_notify = cpupmu_cpu_state_notify, +#if IS_ENABLED(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) +#if defined(ONDIEMET_SUPPORT) || defined(TINYSYS_SSPM_SUPPORT) + .ondiemet_mode = 1, + .ondiemet_start = sspm_pmu_start, + .uniq_ondiemet_start = sspm_pmu_unique_start, + .uniq_ondiemet_stop = sspm_pmu_unique_stop, + .ondiemet_stop = sspm_pmu_stop, + .ondiemet_print_header = sspm_pmu_print_header, + .ondiemet_process_argument = sspm_pmu_process_argument +#endif +#endif +}; diff --git a/drivers/misc/mediatek/met_drv_v2/common/cpu_pmu.h b/drivers/misc/mediatek/met_drv_v2/common/cpu_pmu.h new file mode 100644 index 0000000000000000000000000000000000000000..462346233b1b5c96dc54629cdd42e2b5b8f5d5fc --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/cpu_pmu.h @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef _CPU_PMU_H_ +#define _CPU_PMU_H_ + +#include +#include + +#define MODE_DISABLED 0 +#define MODE_INTERRUPT 1 +#define MODE_POLLING 2 + +#define MXSIZE_PMU_DESC 32 +#define MXNR_CPU NR_CPUS + +#define MXNR_PMU_EVENTS 8 /* max number of pmu counter for armv8 is 6+1 */ +struct met_pmu { + unsigned char mode; + unsigned short event; + unsigned long freq; + struct kobject *kobj_cpu_pmu; +}; + +struct cpu_pmu_hw { + const char *name; + const char *cpu_name; + int nr_cnt; + int (*get_event_desc)(int idx, int event, char *event_desc); + int (*check_event)(struct met_pmu *pmu, int idx, int event); + void (*start)(struct met_pmu *pmu, int count); + void (*stop)(int count); + unsigned int (*polling)(struct met_pmu *pmu, int count, unsigned int *pmu_value); + unsigned long (*perf_event_get_evttype)(struct perf_event *ev); + u32 (*pmu_read_clear_overflow_flag)(void); + struct met_pmu *pmu[MXNR_CPU]; + int event_count[MXNR_CPU]; + /* + * used for compensation of pmu counter loss + * between end of polling and start of cpu pm + */ + unsigned int cpu_pm_unpolled_loss[MXNR_CPU][MXNR_PMU_EVENTS]; +}; + +struct pmu_desc { + unsigned int event; + char name[MXSIZE_PMU_DESC]; +}; + +typedef enum { + SET_PMU_EVT_CNT = 0x0, + SET_PMU_CYCCNT_ENABLE = 0x1, + SET_PMU_BASE_OFFSET = 0x02 +} PMU_IPI_Type; + +struct cpu_pmu_hw *cpu_pmu_hw_init(void); + +extern struct cpu_pmu_hw *cpu_pmu; +extern noinline void mp_cpu(unsigned char cnt, unsigned int *value); + +extern int met_perf_cpupmu_status; +extern void met_perf_cpupmu_polling(unsigned long long stamp, int cpu); + +#endif /* _CPU_PMU_H_ */ diff --git a/drivers/misc/mediatek/met_drv_v2/common/dummy_header.c b/drivers/misc/mediatek/met_drv_v2/common/dummy_header.c new file mode 100644 index 0000000000000000000000000000000000000000..c09e378b5bcf3314c4e279895185439c0f12d95d --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/dummy_header.c @@ -0,0 +1,100 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include +#include +#include + +#include "interface.h" +#include "met_drv.h" + +static struct kobject *kobj_met_dummy; +static char header_str[PAGE_SIZE]; +static int header_str_len; +struct metdevice met_dummy_header; + +static ssize_t dummy_str_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf); +static ssize_t dummy_str_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, size_t n); +static struct kobj_attribute dummy_attr = __ATTR(dummy_str, 0664, dummy_str_show, dummy_str_store); + + +static ssize_t dummy_str_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + int ret; + + ret = snprintf(buf, PAGE_SIZE, "%s", header_str); + + return ret; +} + +static ssize_t dummy_str_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, size_t n) +{ + int ret = 0; + char *ptr = header_str; + + if ((header_str_len + strlen(buf)) < PAGE_SIZE) { + ret = snprintf(ptr + header_str_len, PAGE_SIZE - header_str_len, "%s\n", buf); + header_str_len += ret; + } + met_dummy_header.mode = 1; + + return n; +} + +static int dummy_reset(void) +{ + met_dummy_header.mode = 0; + memset(header_str, 0x00, PAGE_SIZE); + header_str_len = 0; + + return 0; +} + +static int dummy_print_header(char *buf, int len) +{ + if (header_str_len > 0) + len = snprintf(buf, PAGE_SIZE, "%s", header_str); + else + len = snprintf(buf, PAGE_SIZE, "# dummy header is empty\n"); + + return len; +} + +static int dummy_create(struct kobject *parent) +{ + int ret = 0; + + kobj_met_dummy = parent; + ret = sysfs_create_file(kobj_met_dummy, &dummy_attr.attr); + if (ret != 0) { + pr_debug("Failed to create montype0 in sysfs\n"); + return ret; + } + + return ret; +} + +static void dummy_delete(void) +{ + sysfs_remove_file(kobj_met_dummy, &dummy_attr.attr); + kobj_met_dummy = NULL; +} + +struct metdevice met_dummy_header = { + .name = "dummy_header", + .type = MET_TYPE_MISC, + .cpu_related = 0, + .start = NULL, + .stop = NULL, + .reset = dummy_reset, + .polling_interval = 0, + .timed_polling = NULL, + .print_help = NULL, + .print_header = dummy_print_header, + .create_subfs = dummy_create, + .delete_subfs = dummy_delete, +}; diff --git a/drivers/misc/mediatek/met_drv_v2/common/emi/SEDA3/met_emi.c b/drivers/misc/mediatek/met_drv_v2/common/emi/SEDA3/met_emi.c new file mode 100644 index 0000000000000000000000000000000000000000..d035417ea3ef4df3a45687005001af25b99a6b62 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/emi/SEDA3/met_emi.c @@ -0,0 +1,1062 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2019 MediaTek Inc. + * + */ + +#include +#include +#include +#include +#include +#include + +#if IS_ENABLED(CONFIG_ARM) +//#include /* arm_coherent_dma_ops */ +#endif /* CONFIG_ARM */ + +#include + +#define MET_USER_EVENT_SUPPORT +#include "met_drv.h" +#include "trace.h" + +#include "mtk_typedefs.h" +#include "core_plf_init.h" +/* #include "plf_trace.h" */ +#include "mtk_emi_bm.h" +#include "interface.h" +#include "met_dramc.h" + +#if IS_ENABLED(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) +#if defined(ONDIEMET_SUPPORT) +#include "sspm/ondiemet_sspm.h" +#elif defined(TINYSYS_SSPM_SUPPORT) +#include "tinysys_sspm.h" +#include "tinysys_mgr.h" /* for ondiemet_module */ +#endif +#endif + + +/*======================================================================*/ +/* Global variable definitions */ +/*======================================================================*/ +int emi_TP_busfiltr_enable; +int emi_tsct_enable = 1; +int emi_mdct_enable = 1; + +static int bw_limiter_enable = BM_BW_LIMITER_ENABLE; + +static int msel_enable; +static unsigned int msel_group1 = _GP_1_Default; +static unsigned int msel_group2 = _GP_2_Default; +static unsigned int msel_group3 = _GP_3_Default; + +/* Global variables */ +static struct kobject *kobj_emi; + +static int ttype1_16_en = BM_TTYPE1_16_DISABLE; +static int ttype17_21_en = BM_TTYPE17_21_DISABLE; + +static int dramc_pdir_enable = 1; +static int dram_chann_num = 1; + +static int times; +static ssize_t test_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t n) +{ + int i; + unsigned int *src_addr_v = NULL; + dma_addr_t src_addr_p = 0; +#if IS_ENABLED(CONFIG_ARM) + struct dma_map_ops *ops = (struct dma_map_ops *)symbol_get(arm_dma_ops); +#endif /* CONFIG_ARM */ + + if ((n == 0) || (buf == NULL)) + return -EINVAL; + if (kstrtoint(buf, 10, ×) != 0) + return -EINVAL; + if (times < 0) + return -EINVAL; + + if (times > 5000) + return -EINVAL; + +#if IS_ENABLED(CONFIG_ARM) + if (ops && ops->alloc) { + (met_device.this_device)->coherent_dma_mask = DMA_BIT_MASK(32); + src_addr_v = ops->alloc(met_device.this_device, + PAGE_SIZE, + &src_addr_p, + GFP_KERNEL, + 0); + } +#endif /* CONFIG_ARM */ + +#if IS_ENABLED(CONFIG_ARM64) + /* dma_alloc */ + src_addr_v = dma_alloc_coherent(met_device.this_device, + PAGE_SIZE, + &src_addr_p, + GFP_KERNEL); +#endif /* CONFIG_ARM64 */ + + if (src_addr_v == NULL) { +#ifdef CONFIG_MET_MODULE + met_tag_oneshot_real(0, "test dma alloc fail", PAGE_SIZE); +#else + met_tag_oneshot(0, "test dma alloc fail", PAGE_SIZE); +#endif + return -ENOMEM; + } + + preempt_disable(); +#ifdef CONFIG_MET_MODULE + met_tag_start_real(0, "TEST_EMI"); +#else + met_tag_start(0, "TEST_EMI"); +#endif + for (i = 0; i < times; i++) { + memset(src_addr_v, 2*i, PAGE_SIZE); +#ifdef CONFIG_MET_MODULE + met_tag_oneshot_real(0, "TEST_EMI", PAGE_SIZE); +#else + met_tag_oneshot(0, "TEST_EMI", PAGE_SIZE); +#endif + } +#ifdef CONFIG_MET_MODULE + met_tag_end_real(0, "TEST_EMI"); +#else + met_tag_end(0, "TEST_EMI"); +#endif + + my_preempt_enable(); + +#if IS_ENABLED(CONFIG_ARM) + /* dma_free */ + if (ops && ops->free) { + ops->free(met_device.this_device, + PAGE_SIZE, + src_addr_v, + src_addr_p, + 0); + } +#endif /* CONFIG_ARM */ + +#if IS_ENABLED(CONFIG_ARM64) + /* dma_free */ + if (src_addr_v != NULL) + dma_free_coherent(met_device.this_device, + PAGE_SIZE, + src_addr_v, + src_addr_p); +#endif /* CONFIG_ARM64 */ + + return n; +} + +/*======================================================================*/ +/* KOBJ Declarations */ +/*======================================================================*/ +DECLARE_KOBJ_ATTR_INT(emi_TP_busfiltr_enable, emi_TP_busfiltr_enable); +DECLARE_KOBJ_ATTR_INT(msel_enable, msel_enable); +DECLARE_KOBJ_ATTR_HEX_CHECK(msel_group1, msel_group1, msel_group1 > 0 && msel_group1 <= _ALL); +DECLARE_KOBJ_ATTR_HEX_CHECK(msel_group2, msel_group2, msel_group2 > 0 && msel_group2 <= _ALL); +DECLARE_KOBJ_ATTR_HEX_CHECK(msel_group3, msel_group3, msel_group3 > 0 && msel_group3 <= _ALL); + + +DECLARE_KOBJ_ATTR_STR_LIST_ITEM( + ttype1_16_en, + KOBJ_ITEM_LIST( + { BM_TTYPE1_16_ENABLE, "ENABLE" }, + { BM_TTYPE1_16_DISABLE, "DISABLE" } + ) + ); +DECLARE_KOBJ_ATTR_STR_LIST(ttype1_16_en, ttype1_16_en, ttype1_16_en); + + +DECLARE_KOBJ_ATTR_STR_LIST_ITEM( + ttype17_21_en, + KOBJ_ITEM_LIST( + { BM_TTYPE17_21_ENABLE, "ENABLE" }, + { BM_TTYPE17_21_DISABLE, "DISABLE" } + ) + ); +DECLARE_KOBJ_ATTR_STR_LIST(ttype17_21_en, ttype17_21_en, ttype17_21_en); + +DECLARE_KOBJ_ATTR_STR_LIST_ITEM( + ttype_master, + KOBJ_ITEM_LIST( + { _M0, "M0" }, + { _M1, "M1" }, + { _M2, "M2" }, + { _M3, "M3" }, + { _M4, "M4" }, + { _M5, "M5" }, + { _M6, "M6" }, + { _M7, "M7" } + ) + ); + + +DECLARE_KOBJ_ATTR_INT_LIST_ITEM( + ttype_nbeat, + KOBJ_ITEM_LIST( + { BM_TRANS_TYPE_1BEAT, 1 }, + { BM_TRANS_TYPE_2BEAT, 2 }, + { BM_TRANS_TYPE_3BEAT, 3 }, + { BM_TRANS_TYPE_4BEAT, 4 }, + { BM_TRANS_TYPE_5BEAT, 5 }, + { BM_TRANS_TYPE_6BEAT, 6 }, + { BM_TRANS_TYPE_7BEAT, 7 }, + { BM_TRANS_TYPE_8BEAT, 8 }, + { BM_TRANS_TYPE_9BEAT, 9 }, + { BM_TRANS_TYPE_10BEAT, 10 }, + { BM_TRANS_TYPE_11BEAT, 11 }, + { BM_TRANS_TYPE_12BEAT, 12 }, + { BM_TRANS_TYPE_13BEAT, 13 }, + { BM_TRANS_TYPE_14BEAT, 14 }, + { BM_TRANS_TYPE_15BEAT, 15 }, + { BM_TRANS_TYPE_16BEAT, 16 } + ) + ); +DECLARE_KOBJ_ATTR_INT_LIST_ITEM( + ttype_nbyte, + KOBJ_ITEM_LIST( + { BM_TRANS_TYPE_1Byte, 1 }, + { BM_TRANS_TYPE_2Byte, 2 }, + { BM_TRANS_TYPE_4Byte, 4 }, + { BM_TRANS_TYPE_8Byte, 8 }, + { BM_TRANS_TYPE_16Byte, 16 }, + { BM_TRANS_TYPE_32Byte, 32 } + ) + ); +DECLARE_KOBJ_ATTR_STR_LIST_ITEM( + ttype_burst, + KOBJ_ITEM_LIST( + { BM_TRANS_TYPE_BURST_INCR, "INCR" }, + { BM_TRANS_TYPE_BURST_WRAP, "WRAP" } + ) + ); + +DECLARE_KOBJ_ATTR_STR_LIST_ITEM( + ttype_rw, + KOBJ_ITEM_LIST( + { BM_TRANS_RW_DEFAULT, "DEFAULT" }, + { BM_TRANS_RW_READONLY, "R" }, + { BM_TRANS_RW_WRITEONLY, "W" }, + { BM_TRANS_RW_RWBOTH, "BOTH" } + ) + ); + + +DECLARE_KOBJ_ATTR_SHOW_INT(test, times); + +DECLARE_KOBJ_ATTR(test); + + +static int high_priority_filter; +DECLARE_KOBJ_ATTR_HEX(high_priority_filter, high_priority_filter); + + +static int ttype_master_val[21]; +static int ttype_busid_val[21]; +static int ttype_nbeat_val[21]; +static int ttype_nbyte_val[21]; +static int ttype_burst_val[21]; +static int ttype_rw_val[21]; + +#define DECLARE_KOBJ_TTYPE_MASTER(nr) \ + DECLARE_KOBJ_ATTR_STR_LIST(ttype ## nr ## _master, ttype_master_val[nr - 1], ttype_master) + +#define DECLARE_KOBJ_TTYPE_NBEAT(nr) \ + DECLARE_KOBJ_ATTR_INT_LIST(ttype ## nr ## _nbeat, ttype_nbeat_val[nr - 1], ttype_nbeat) + +#define DECLARE_KOBJ_TTYPE_NBYTE(nr) \ + DECLARE_KOBJ_ATTR_INT_LIST(ttype ## nr ## _nbyte, ttype_nbyte_val[nr - 1], ttype_nbyte) + +#define DECLARE_KOBJ_TTYPE_BURST(nr) \ + DECLARE_KOBJ_ATTR_STR_LIST(ttype ## nr ## _burst, ttype_burst_val[nr - 1], ttype_burst) + +#define DECLARE_KOBJ_TTYPE_RW(nr) \ + DECLARE_KOBJ_ATTR_STR_LIST(ttype ## nr ## _rw, ttype_rw_val[nr - 1], ttype_rw) + +#define DECLARE_KOBJ_TTYPE_BUSID_VAL(nr) \ + DECLARE_KOBJ_ATTR_HEX(ttype ## nr ## _busid, ttype_busid_val[nr - 1]) + +DECLARE_KOBJ_TTYPE_MASTER(1); +DECLARE_KOBJ_TTYPE_NBEAT(1); +DECLARE_KOBJ_TTYPE_NBYTE(1); +DECLARE_KOBJ_TTYPE_BURST(1); +DECLARE_KOBJ_TTYPE_RW(1); +DECLARE_KOBJ_TTYPE_BUSID_VAL(1); + +DECLARE_KOBJ_TTYPE_MASTER(2); +DECLARE_KOBJ_TTYPE_NBEAT(2); +DECLARE_KOBJ_TTYPE_NBYTE(2); +DECLARE_KOBJ_TTYPE_BURST(2); +DECLARE_KOBJ_TTYPE_RW(2); +DECLARE_KOBJ_TTYPE_BUSID_VAL(2); + +DECLARE_KOBJ_TTYPE_MASTER(3); +DECLARE_KOBJ_TTYPE_NBEAT(3); +DECLARE_KOBJ_TTYPE_NBYTE(3); +DECLARE_KOBJ_TTYPE_BURST(3); +DECLARE_KOBJ_TTYPE_RW(3); +DECLARE_KOBJ_TTYPE_BUSID_VAL(3); + +DECLARE_KOBJ_TTYPE_MASTER(4); +DECLARE_KOBJ_TTYPE_NBEAT(4); +DECLARE_KOBJ_TTYPE_NBYTE(4); +DECLARE_KOBJ_TTYPE_BURST(4); +DECLARE_KOBJ_TTYPE_RW(4); +DECLARE_KOBJ_TTYPE_BUSID_VAL(4); + +DECLARE_KOBJ_TTYPE_MASTER(5); +DECLARE_KOBJ_TTYPE_NBEAT(5); +DECLARE_KOBJ_TTYPE_NBYTE(5); +DECLARE_KOBJ_TTYPE_BURST(5); +DECLARE_KOBJ_TTYPE_RW(5); +DECLARE_KOBJ_TTYPE_BUSID_VAL(5); + +DECLARE_KOBJ_TTYPE_MASTER(6); +DECLARE_KOBJ_TTYPE_NBEAT(6); +DECLARE_KOBJ_TTYPE_NBYTE(6); +DECLARE_KOBJ_TTYPE_BURST(6); +DECLARE_KOBJ_TTYPE_RW(6); +DECLARE_KOBJ_TTYPE_BUSID_VAL(6); + +DECLARE_KOBJ_TTYPE_MASTER(7); +DECLARE_KOBJ_TTYPE_NBEAT(7); +DECLARE_KOBJ_TTYPE_NBYTE(7); +DECLARE_KOBJ_TTYPE_BURST(7); +DECLARE_KOBJ_TTYPE_RW(7); +DECLARE_KOBJ_TTYPE_BUSID_VAL(7); + +DECLARE_KOBJ_TTYPE_MASTER(8); +DECLARE_KOBJ_TTYPE_NBEAT(8); +DECLARE_KOBJ_TTYPE_NBYTE(8); +DECLARE_KOBJ_TTYPE_BURST(8); +DECLARE_KOBJ_TTYPE_RW(8); +DECLARE_KOBJ_TTYPE_BUSID_VAL(8); + +DECLARE_KOBJ_TTYPE_MASTER(9); +DECLARE_KOBJ_TTYPE_NBEAT(9); +DECLARE_KOBJ_TTYPE_NBYTE(9); +DECLARE_KOBJ_TTYPE_BURST(9); +DECLARE_KOBJ_TTYPE_RW(9); +DECLARE_KOBJ_TTYPE_BUSID_VAL(9); + +DECLARE_KOBJ_TTYPE_MASTER(10); +DECLARE_KOBJ_TTYPE_NBEAT(10); +DECLARE_KOBJ_TTYPE_NBYTE(10); +DECLARE_KOBJ_TTYPE_BURST(10); +DECLARE_KOBJ_TTYPE_RW(10); +DECLARE_KOBJ_TTYPE_BUSID_VAL(10); + +DECLARE_KOBJ_TTYPE_MASTER(11); +DECLARE_KOBJ_TTYPE_NBEAT(11); +DECLARE_KOBJ_TTYPE_NBYTE(11); +DECLARE_KOBJ_TTYPE_BURST(11); +DECLARE_KOBJ_TTYPE_RW(11); +DECLARE_KOBJ_TTYPE_BUSID_VAL(11); + +DECLARE_KOBJ_TTYPE_MASTER(12); +DECLARE_KOBJ_TTYPE_NBEAT(12); +DECLARE_KOBJ_TTYPE_NBYTE(12); +DECLARE_KOBJ_TTYPE_BURST(12); +DECLARE_KOBJ_TTYPE_RW(12); +DECLARE_KOBJ_TTYPE_BUSID_VAL(12); + +DECLARE_KOBJ_TTYPE_MASTER(13); +DECLARE_KOBJ_TTYPE_NBEAT(13); +DECLARE_KOBJ_TTYPE_NBYTE(13); +DECLARE_KOBJ_TTYPE_BURST(13); +DECLARE_KOBJ_TTYPE_RW(13); +DECLARE_KOBJ_TTYPE_BUSID_VAL(13); + +DECLARE_KOBJ_TTYPE_MASTER(14); +DECLARE_KOBJ_TTYPE_NBEAT(14); +DECLARE_KOBJ_TTYPE_NBYTE(14); +DECLARE_KOBJ_TTYPE_BURST(14); +DECLARE_KOBJ_TTYPE_RW(14); +DECLARE_KOBJ_TTYPE_BUSID_VAL(14); + +DECLARE_KOBJ_TTYPE_MASTER(15); +DECLARE_KOBJ_TTYPE_NBEAT(15); +DECLARE_KOBJ_TTYPE_NBYTE(15); +DECLARE_KOBJ_TTYPE_BURST(15); +DECLARE_KOBJ_TTYPE_RW(15); +DECLARE_KOBJ_TTYPE_BUSID_VAL(15); + +DECLARE_KOBJ_TTYPE_MASTER(16); +DECLARE_KOBJ_TTYPE_NBEAT(16); +DECLARE_KOBJ_TTYPE_NBYTE(16); +DECLARE_KOBJ_TTYPE_BURST(16); +DECLARE_KOBJ_TTYPE_RW(16); +DECLARE_KOBJ_TTYPE_BUSID_VAL(16); + +DECLARE_KOBJ_TTYPE_MASTER(17); +DECLARE_KOBJ_TTYPE_NBEAT(17); +DECLARE_KOBJ_TTYPE_NBYTE(17); +DECLARE_KOBJ_TTYPE_BURST(17); +DECLARE_KOBJ_TTYPE_RW(17); +DECLARE_KOBJ_TTYPE_BUSID_VAL(17); + +DECLARE_KOBJ_TTYPE_MASTER(18); +DECLARE_KOBJ_TTYPE_NBEAT(18); +DECLARE_KOBJ_TTYPE_NBYTE(18); +DECLARE_KOBJ_TTYPE_BURST(18); +DECLARE_KOBJ_TTYPE_RW(18); +DECLARE_KOBJ_TTYPE_BUSID_VAL(18); + +DECLARE_KOBJ_TTYPE_MASTER(19); +DECLARE_KOBJ_TTYPE_NBEAT(19); +DECLARE_KOBJ_TTYPE_NBYTE(19); +DECLARE_KOBJ_TTYPE_BURST(19); +DECLARE_KOBJ_TTYPE_RW(19); +DECLARE_KOBJ_TTYPE_BUSID_VAL(19); + +DECLARE_KOBJ_TTYPE_MASTER(20); +DECLARE_KOBJ_TTYPE_NBEAT(20); +DECLARE_KOBJ_TTYPE_NBYTE(20); +DECLARE_KOBJ_TTYPE_BURST(20); +DECLARE_KOBJ_TTYPE_RW(20); +DECLARE_KOBJ_TTYPE_BUSID_VAL(20); + +DECLARE_KOBJ_TTYPE_MASTER(21); +DECLARE_KOBJ_TTYPE_NBEAT(21); +DECLARE_KOBJ_TTYPE_NBYTE(21); +DECLARE_KOBJ_TTYPE_BURST(21); +DECLARE_KOBJ_TTYPE_RW(21); +DECLARE_KOBJ_TTYPE_BUSID_VAL(21); + +#define KOBJ_ATTR_ITEM_SERIAL_FNODE(nr) \ + do { \ + KOBJ_ATTR_ITEM(ttype ## nr ## _master); \ + KOBJ_ATTR_ITEM(ttype ## nr ## _nbeat); \ + KOBJ_ATTR_ITEM(ttype ## nr ## _nbyte); \ + KOBJ_ATTR_ITEM(ttype ## nr ## _burst); \ + KOBJ_ATTR_ITEM(ttype ## nr ## _busid); \ + KOBJ_ATTR_ITEM(ttype ## nr ## _rw); \ + } while (0) + +#define KOBJ_ATTR_LIST \ + do { \ + KOBJ_ATTR_ITEM(high_priority_filter); \ + KOBJ_ATTR_ITEM(emi_TP_busfiltr_enable); \ + KOBJ_ATTR_ITEM(msel_enable); \ + KOBJ_ATTR_ITEM(msel_group1); \ + KOBJ_ATTR_ITEM(msel_group2); \ + KOBJ_ATTR_ITEM(msel_group3); \ + KOBJ_ATTR_ITEM(ttype17_21_en); \ + KOBJ_ATTR_ITEM(ttype1_16_en); \ + KOBJ_ATTR_ITEM_SERIAL_FNODE(1); \ + KOBJ_ATTR_ITEM_SERIAL_FNODE(2); \ + KOBJ_ATTR_ITEM_SERIAL_FNODE(3); \ + KOBJ_ATTR_ITEM_SERIAL_FNODE(4); \ + KOBJ_ATTR_ITEM_SERIAL_FNODE(5); \ + KOBJ_ATTR_ITEM_SERIAL_FNODE(6); \ + KOBJ_ATTR_ITEM_SERIAL_FNODE(7); \ + KOBJ_ATTR_ITEM_SERIAL_FNODE(8); \ + KOBJ_ATTR_ITEM_SERIAL_FNODE(9); \ + KOBJ_ATTR_ITEM_SERIAL_FNODE(10); \ + KOBJ_ATTR_ITEM_SERIAL_FNODE(11); \ + KOBJ_ATTR_ITEM_SERIAL_FNODE(12); \ + KOBJ_ATTR_ITEM_SERIAL_FNODE(13); \ + KOBJ_ATTR_ITEM_SERIAL_FNODE(14); \ + KOBJ_ATTR_ITEM_SERIAL_FNODE(15); \ + KOBJ_ATTR_ITEM_SERIAL_FNODE(16); \ + KOBJ_ATTR_ITEM_SERIAL_FNODE(17); \ + KOBJ_ATTR_ITEM_SERIAL_FNODE(18); \ + KOBJ_ATTR_ITEM_SERIAL_FNODE(19); \ + KOBJ_ATTR_ITEM_SERIAL_FNODE(20); \ + KOBJ_ATTR_ITEM_SERIAL_FNODE(21); \ + KOBJ_ATTR_ITEM(test); \ + } while (0) + +/*======================================================================*/ +/* EMI Operations */ +/*======================================================================*/ +static void emi_init(void) +{ + unsigned int bmrw0_val = 0, bmrw1_val = 0, i, enable; + unsigned int msel_group_val[4]; + + MET_BM_SaveCfg(); + + /* get dram channel number */ + dram_chann_num = MET_EMI_GetDramChannNum(); + + if ((ttype1_16_en != BM_TTYPE1_16_ENABLE) && (emi_TP_busfiltr_enable != 1)) { + if (msel_enable) { + msel_group_val[0] = _ALL; + msel_group_val[1] = msel_group1; + msel_group_val[2] = msel_group2; + msel_group_val[3] = msel_group3; + } else { + msel_group_val[0] = _ALL; + msel_group_val[1] = _ALL; + msel_group_val[2] = _ALL; + msel_group_val[3] = _ALL; + } + + MET_BM_SetLatencyCounter(1); + + for (i = 1; i <= 4; i++) { + MET_BM_SetMonitorCounter(i, + msel_group_val[i - 1] & _ALL, + BM_TRANS_TYPE_4BEAT | + BM_TRANS_TYPE_8Byte | + BM_TRANS_TYPE_BURST_WRAP); + MET_BM_SetbusID(i, 0); + MET_BM_SetbusID_En(i, 0); + } + for (i = 0; i < 4; i++) + MET_BM_Set_WsctTsct_id_sel(i, 0); + + } else if ((ttype1_16_en != BM_TTYPE1_16_ENABLE) && (emi_TP_busfiltr_enable == 1)) { + MET_BM_SetLatencyCounter(1); + + for (i = 1; i <= 4; i++) { + MET_BM_SetMonitorCounter(i, + ttype_master_val[i - 1], + ttype_nbeat_val[i - 1] | + ttype_nbyte_val[i - 1] | + ttype_burst_val[i - 1]); + MET_BM_SetbusID(i, ttype_busid_val[i - 1]); + MET_BM_SetbusID_En(i, 0); + } + for (i = 0; i < 4; i++) + MET_BM_Set_WsctTsct_id_sel(i, 1); + + } else if ((ttype1_16_en == BM_TTYPE1_16_ENABLE) && (emi_TP_busfiltr_enable != 1)) { + MET_BM_SetLatencyCounter(0); + + for (i = 1; i <= 16; i++) { + MET_BM_SetMonitorCounter(i, + ttype_master_val[i - 1], + ttype_nbeat_val[i - 1] | + ttype_nbyte_val[i - 1] | + ttype_burst_val[i - 1]); + + MET_BM_SetbusID(i, ttype_busid_val[i - 1]); + + MET_BM_SetbusID_En(i, (ttype_busid_val[i - 1] > 0xffff) ? 0 : 1); + } + for (i = 0; i < 4; i++) + MET_BM_Set_WsctTsct_id_sel(i, 0); + } else { /* (ttype1_16_en == BM_TTYPE1_16_ENABLE) && (emi_TP_busfiltr_enable == 1) */ + + MET_BM_SetLatencyCounter(0); + + for (i = 1; i <= 16; i++) { + MET_BM_SetMonitorCounter(i, + ttype_master_val[i - 1], + ttype_nbeat_val[i - 1] | + ttype_nbyte_val[i - 1] | + ttype_burst_val[i - 1]); + + MET_BM_SetbusID(i, ttype_busid_val[i - 1]); + + MET_BM_SetbusID_En(i, (ttype_busid_val[i - 1] > 0xffff) ? 0 : 1); + } + for (i = 0; i < 4; i++) + MET_BM_Set_WsctTsct_id_sel(i, 1); + } + + if (ttype17_21_en == BM_TTYPE17_21_ENABLE) { + for (i = 17; i <= 21; i++) { + MET_BM_SetMonitorCounter(i, + ttype_master_val[i - 1], + ttype_nbeat_val[i - 1] | + ttype_nbyte_val[i - 1] | + ttype_burst_val[i - 1]); + MET_BM_SetbusID(i, ttype_busid_val[i - 1]); + + MET_BM_SetbusID_En(i, (ttype_busid_val[i - 1] > 0xffff) ? 0 : 1); + } + } + + bmrw0_val = ( + (ttype_rw_val[0] << 0) | (ttype_rw_val[1] << 2) | + (ttype_rw_val[2] << 4) | (ttype_rw_val[3] << 6) | + (ttype_rw_val[4] << 8) | (ttype_rw_val[5] << 10) | + (ttype_rw_val[6] << 12) | (ttype_rw_val[7] << 14) | + (ttype_rw_val[8] << 16) | (ttype_rw_val[9] << 18) | + (ttype_rw_val[10] << 20) | (ttype_rw_val[11] << 22) | + (ttype_rw_val[12] << 24) | (ttype_rw_val[13] << 26) | + (ttype_rw_val[14] << 28) | (ttype_rw_val[15] << 30)); + + bmrw1_val = ( + (ttype_rw_val[16] << 0) | (ttype_rw_val[17] << 2) | + (ttype_rw_val[18] << 4) | (ttype_rw_val[19] << 6) | + (ttype_rw_val[20] << 8)); + + MET_BM_SetTtypeCounterRW(bmrw0_val, bmrw1_val); + + for (i = 0; i < BM_COUNTER_MAX; i++) { + if ((high_priority_filter & (1 << i)) == 0) + enable = 0; + else + enable = 1; + + MET_BM_SetUltraHighFilter(i + 1, enable); + } + +} + +static inline int do_emi(void) +{ + return met_sspm_emi.mode; +} + +/*======================================================================*/ +/* MET Device Operations */ +/*======================================================================*/ +static int emi_inited; +static int met_emi_create(struct kobject *parent) +{ + int ret = 0; + int i; + + for (i = 0; i < 21; i++) { + ttype_master_val[i] = _M0; + ttype_nbeat_val[i] = BM_TRANS_TYPE_1BEAT; + ttype_nbyte_val[i] = BM_TRANS_TYPE_8Byte; + ttype_burst_val[i] = BM_TRANS_TYPE_BURST_INCR; + ttype_busid_val[i] = 0xfffff; + ttype_rw_val[i] = BM_TRANS_RW_DEFAULT; + } + ret = MET_BM_Init(); + if (ret != 0) { + pr_debug("MET_BM_Init failed!!!\n"); + ret = 0; + } else + emi_inited = 1; + + kobj_emi = parent; + +#define KOBJ_ATTR_ITEM(attr_name) \ +do { \ + ret = sysfs_create_file(kobj_emi, &attr_name##_attr.attr); \ + if (ret != 0) { \ + pr_debug("Failed to create " #attr_name " in sysfs\n"); \ + return ret; \ + } \ +} while (0) + KOBJ_ATTR_LIST; +#undef KOBJ_ATTR_ITEM + + return ret; +} + +static void met_emi_delete(void) +{ +#define KOBJ_ATTR_ITEM(attr_name) \ + sysfs_remove_file(kobj_emi, &attr_name##_attr.attr) + if (kobj_emi != NULL) { + KOBJ_ATTR_LIST; + kobj_emi = NULL; + } +#undef KOBJ_ATTR_ITEM + + if (emi_inited) + MET_BM_DeInit(); +} + + +static void met_emi_resume(void) +{ + if (!do_emi()) + return; + + emi_init(); +} + + +#if IS_ENABLED(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) +#if defined(ONDIEMET_SUPPORT) || defined(TINYSYS_SSPM_SUPPORT) +static const char help[] = " --emi monitor EMI banwidth\n"; + +#define TTYPE_NAME_STR_LEN 64 +/* static char ttype_name[21][TTYPE_NAME_STR_LEN]; */ + +static int emi_print_help(char *buf, int len) +{ + return snprintf(buf, PAGE_SIZE, help); +} + +static int emi_print_header(char *buf, int len) +{ + int ret = 0; +/* int ret_m[21]; */ + int i = 0; + int err; + unsigned int dram_data_rate_MHz; + unsigned int DRAM_TYPE; + + if ((ttype1_16_en != BM_TTYPE1_16_ENABLE) && (emi_TP_busfiltr_enable != 1)) { + if (msel_enable) { + ret += snprintf(buf + ret, PAGE_SIZE - ret, + "met-info [000] 0.0: met_emi_msel: %x,%x,%x\n", + msel_group1 & _ALL, + msel_group2 & _ALL, + msel_group3 & _ALL); + } else { + ret += snprintf(buf + ret, PAGE_SIZE - ret, + "met-info [000] 0.0: met_emi_msel: %x,%x,%x\n", + _ALL & _ALL, + _ALL & _ALL, + _ALL & _ALL); + } + } else { + ret += snprintf(buf + ret, PAGE_SIZE - ret, + "met-info [000] 0.0: met_emi_ttype_master: %x,%x,%x,%x\n", + ttype_master_val[0], ttype_master_val[1], ttype_master_val[2], ttype_master_val[3]); + + if (emi_TP_busfiltr_enable == 1) { + + ret += snprintf(buf + ret, PAGE_SIZE - ret, + "met-info [000] 0.0: met_emi_ttype_busid: %x,%x,%x,%x\n", + ttype_busid_val[0], ttype_busid_val[1], ttype_busid_val[2], ttype_busid_val[3]); + } + } + + ret += snprintf(buf + ret, PAGE_SIZE - ret, "met-info [000] 0.0: met_emi_rw_cfg: "); + ret += snprintf(buf + ret, PAGE_SIZE - ret, "BOTH"); + + for (i = 0; i < 21; i++) { + if (ttype_rw_val[i] == BM_TRANS_RW_DEFAULT) + ret += snprintf(buf + ret, PAGE_SIZE - ret, ",DEFAULT"); + else if (ttype_rw_val[i] == BM_TRANS_RW_READONLY) + ret += snprintf(buf + ret, PAGE_SIZE - ret, ",R"); + else if (ttype_rw_val[i] == BM_TRANS_RW_WRITEONLY) + ret += snprintf(buf + ret, PAGE_SIZE - ret, ",W"); + else + ret += snprintf(buf + ret, PAGE_SIZE - ret, ",BOTH"); + } + ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n"); + + ret += snprintf(buf + ret, PAGE_SIZE - ret, + "met-info [000] 0.0: met_emi_ultra_filter: %x\n", high_priority_filter); + + /* ttype header */ + if (ttype17_21_en == BM_TTYPE17_21_ENABLE) { + int i = 0; + int j = 0; + + /* ttype master list */ + ret += snprintf(buf + ret, PAGE_SIZE - ret, "met-info [000] 0.0: met_emi_ttype_master_list: "); + for (i = 0; i < 21; i++) { + for (j = 0; j < ARRAY_SIZE(ttype_master_list_item); j++) { + if (ttype_master_val[i] == ttype_master_list_item[j].key) { + ret += snprintf(buf + ret, PAGE_SIZE - ret, "%s,", ttype_master_list_item[j].val); + } + } + } + /* remove the last comma */ + err = snprintf(buf + ret -1, PAGE_SIZE - ret + 1, "\n"); + if (err < 0) return err; + + /* ttype busid list */ + ret += snprintf(buf + ret, PAGE_SIZE - ret, "met-info [000] 0.0: met_emi_ttype_busid_list: "); + for (i = 0; i < 21; i++) + ret += snprintf(buf + ret, PAGE_SIZE - ret, "%x,", ttype_busid_val[i]); + + err = snprintf(buf + ret -1, PAGE_SIZE - ret + 1, "\n"); + if (err < 0) return err; + + /* ttype nbeat list */ + ret += snprintf(buf + ret, PAGE_SIZE - ret, "met-info [000] 0.0: met_emi_ttype_nbeat_list: "); + for (i = 0; i < 21; i++) { + for (j = 0; j < ARRAY_SIZE(ttype_nbeat_list_item); j++) { + if (ttype_nbeat_val[i] == ttype_nbeat_list_item[j].key) { + ret += snprintf(buf + ret, PAGE_SIZE - ret, "%d,", ttype_nbeat_list_item[j].val); + } + } + } + err = snprintf(buf + ret -1, PAGE_SIZE - ret + 1, "\n"); + if (err < 0) return err; + + /* ttype nbyte list */ + ret += snprintf(buf + ret, PAGE_SIZE - ret, "met-info [000] 0.0: met_emi_ttype_nbyte_list: "); + for (i = 0; i < 21; i++) { + for (j = 0; j < ARRAY_SIZE(ttype_nbyte_list_item); j++) { + if (ttype_nbyte_val[i] == ttype_nbyte_list_item[j].key) { + ret += snprintf(buf + ret, PAGE_SIZE - ret, "%d,", ttype_nbyte_list_item[j].val); + } + } + } + err = snprintf(buf + ret -1, PAGE_SIZE - ret + 1, "\n"); + if (err < 0) return err; + + /* ttype burst list */ + ret += snprintf(buf + ret, PAGE_SIZE - ret, "met-info [000] 0.0: met_emi_ttype_burst_list: "); + for (i = 0; i < 21; i++) { + for (j = 0; j < ARRAY_SIZE(ttype_burst_list_item); j++) { + if (ttype_burst_val[i] == ttype_burst_list_item[j].key) { + ret += snprintf(buf + ret, PAGE_SIZE - ret, "%s,", ttype_burst_list_item[j].val); + } + } + } + err = snprintf(buf + ret -1, PAGE_SIZE - ret + 1, "\n"); + if (err < 0) return err; + + /* ttype enable */ + ret += snprintf(buf + ret, PAGE_SIZE - ret, "met-info [000] 0.0: met_emi_ttype_enable: %d,%d\n",ttype1_16_en, ttype17_21_en); + } + /*IP version*/ + ret += snprintf(buf + ret, PAGE_SIZE - ret, + "met-info [000] 0.0: DRAMC_VER: %d\n", DRAMC_VER); + + ret += snprintf(buf + ret, PAGE_SIZE - ret, + "met-info [000] 0.0: EMI_VER: %d.%d\n", EMI_VER_MAJOR, EMI_VER_MINOR); +#if 1 /* move to AP side print header */ +//#ifndef CONFIG_MTK_TINYSYS_SSPM_SUPPORT + dram_chann_num = MET_EMI_GetDramChannNum(); + /* met_dram_chann_num_header + * channel number + * LP4: 2, LP3: 1 + */ + + /* + * the ddr type define : + * enum DDRTYPE { + * TYPE_LPDDR3 = 1, + * TYPE_LPDDR4, + * TYPE_LPDDR4X, + * TYPE_LPDDR2 + * }; + */ + if (mtk_dramc_get_ddr_type_symbol) + DRAM_TYPE = mtk_dramc_get_ddr_type_symbol(); + else if (get_ddr_type_symbol) + DRAM_TYPE = get_ddr_type_symbol(); + + if (mtk_dramc_get_ddr_type_symbol || get_ddr_type_symbol) { + ret += snprintf(buf + ret, PAGE_SIZE - ret, "met-info [000] 0.0: met_dram_type: %d\n", DRAM_TYPE); + + if ((DRAM_TYPE == 2) || (DRAM_TYPE == 3)) + ret += snprintf(buf + ret, PAGE_SIZE - ret, "met-info [000] 0.0: met_dram_chann_num_header: %d,%d,%d,%d\n", + dram_chann_num, DRAM_EMI_BASECLOCK_RATE_LP4, + DRAM_IO_BUS_WIDTH_LP4, DRAM_DATARATE); + else + ret += snprintf(buf + ret, PAGE_SIZE - ret, "met-info [000] 0.0: met_dram_chann_num_header: %d,%d,%d,%d\n", + dram_chann_num, DRAM_EMI_BASECLOCK_RATE_LP3, + DRAM_IO_BUS_WIDTH_LP3, DRAM_DATARATE); + } else + METERROR("[%s][%d]mtk_dramc_get_ddr_type_symbol = NULL , use the TYPE_LPDDR3 setting\n", __func__, __LINE__); + + + /* met_emi_clockrate */ + if (mtk_dramc_get_data_rate_symbol) + dram_data_rate_MHz = mtk_dramc_get_data_rate_symbol(); + else if (get_dram_data_rate_symbol) + dram_data_rate_MHz = get_dram_data_rate_symbol(); + else { + METERROR("mtk_dramc_get_data_rate_symbol = NULL\n"); + dram_data_rate_MHz = 0; + } + + ret += snprintf(buf + ret, PAGE_SIZE - ret, + "met-info [000] 0.0: met_dram_clockrate: %d\n", + dram_data_rate_MHz); + + /*dram bank num*/ + ret += snprintf(buf + ret, PAGE_SIZE - ret, + "met-info [000] 0.0: met_dram_rank_num_header: %u,%u\n", MET_EMI_GetDramRankNum(), + MET_EMI_GetDramRankNum()); +#if 0 + /* ms_emi header */ + ret += snprintf(buf + ret, PAGE_SIZE - ret, + "# ms_emi: TS0,TS1,GP0_WSCT,GP1_WSCT,GP2_WSCT,GP3_WSCT,"); + ret += snprintf(buf + ret, PAGE_SIZE - ret, + "M0_LATENCY,M1_LATENCY,M2_LATENCY,M3_LATENCY,M4_LATENCY,M5_LATENCY,M6_LATENCY,M7_LATENCY,"); + ret += snprintf(buf + ret, PAGE_SIZE - ret, + "M0_TRANS,M1_TRANS,M2_TRANS,M3_TRANS,M4_TRANS,M5_TRANS,M6_TRANS,M7_TRANS,"); + ret += snprintf(buf + ret, PAGE_SIZE - ret, + "BACT,BSCT,BCNT,WACT,DCM_CTRL,TACT,"); + + for (i = 0; i < dram_chann_num; i++) { + if (i != 0) + ret += snprintf(buf + ret, PAGE_SIZE - ret, + ","); + ret += snprintf(buf + ret, PAGE_SIZE - ret, + "PageHit_%d,PageMiss_%d,InterBank_%d,Idle_%d,", i, i, i, i); + ret += snprintf(buf + ret, PAGE_SIZE - ret, + "mr4_%d,refresh_pop_%d,freerun_26m_%d,", i, i, i); + ret += snprintf(buf + ret, PAGE_SIZE - ret, + "read_bytes_%d,write_bytes_%d", i, i); + } + ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n"); +#endif + + ret += snprintf(buf + ret, PAGE_SIZE - ret, + "met-info [000] 0.0: met_emi_header: TS0,TS1,GP0_WSCT,GP1_WSCT,GP2_WSCT,GP3_WSCT,"); + ret += snprintf(buf + ret, PAGE_SIZE - ret, + "M0_LATENCY,M1_LATENCY,M2_LATENCY,M3_LATENCY,M4_LATENCY,M5_LATENCY,M6_LATENCY,M7_LATENCY,"); + ret += snprintf(buf + ret, PAGE_SIZE - ret, + "M0_TRANS,M1_TRANS,M2_TRANS,M3_TRANS,M4_TRANS,M5_TRANS,M6_TRANS,M7_TRANS,"); + ret += snprintf(buf + ret, PAGE_SIZE - ret, + "BACT,BSCT,BCNT,WACT,DCM_CTRL,TACT,"); + + for (i = 0; i < dram_chann_num; i++) { + if (i != 0) + ret += snprintf(buf + ret, PAGE_SIZE - ret, + ","); + ret += snprintf(buf + ret, PAGE_SIZE - ret, + "PageHit_%d,PageMiss_%d,InterBank_%d,Idle_%d,", i, i, i, i); + ret += snprintf(buf + ret, PAGE_SIZE - ret, + "mr4_%d,refresh_pop_%d,freerun_26m_%d,", i, i, i); + ret += snprintf(buf + ret, PAGE_SIZE - ret, + "read_bytes_%d,write_bytes_%d", i, i); + } + ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n"); + + /*TSCT header*/ + if (emi_tsct_enable == 1) { + ret += snprintf(buf + ret, PAGE_SIZE - ret, + "met-info [000] 0.0: ms_emi_tsct_header: ms_emi_tsct,"); + ret += snprintf(buf + ret, PAGE_SIZE - ret, + "tsct1,tsct2,tsct3\n"); + } + + /*MDCT header*/ + if (emi_mdct_enable == 1) { + ret += snprintf(buf + ret, PAGE_SIZE - ret, + "met-info [000] 0.0: ms_emi_mdct_header: ms_emi_mdct,"); + ret += snprintf(buf + ret, PAGE_SIZE - ret, + "RD_ULTRA,RD_MDMCU\n"); + } + + /* met_bw_limiter_header */ + if (bw_limiter_enable == BM_BW_LIMITER_ENABLE) { + ret += snprintf(buf + ret, PAGE_SIZE - ret, + "met-info [000] 0.0: met_bw_limiter_header: CLK,"); + ret += snprintf(buf + ret, PAGE_SIZE - ret, + "ARBA,ARBB,ARBC,ARBD,ARBE,ARBF,ARBG,ARBH,BWCT0,BWCT1,BWCT2,BWCT3,BWCT4,BWST0,BWST1,BWCT0_2ND,BWCT1_2ND,BWST_2ND\n"); + } + + /* DRAM DVFS header */ + ret += snprintf(buf + ret, PAGE_SIZE - ret, + "met-info [000] 0.0: DRAM_DVFS_header: datarate(MHz)\n"); + + /*PDIR met_dramc_header*/ +#if DRAMC_VER >= 2 + if (dramc_pdir_enable == 1) { + ret += snprintf(buf + ret, PAGE_SIZE - ret, + "met-info [000] 0.0: met_dramc_header: "); + for (i = 0; i < dram_chann_num; i++) { + if (i != 0) + ret += snprintf(buf + ret, PAGE_SIZE - ret, + ","); + ret += snprintf(buf + ret, PAGE_SIZE - ret, "freerun_26m_%d,", i); + ret += snprintf(buf + ret, PAGE_SIZE - ret, + "rk0_pre_sb_%d,rk0_pre_pd_%d,rk0_act_sb_%d,rk0_act_pd_%d,", i, i, i, i); + ret += snprintf(buf + ret, PAGE_SIZE - ret, + "rk1_pre_sb_%d,rk1_pre_pd_%d,rk1_act_sb_%d,rk1_act_pd_%d,", i, i, i, i); + ret += snprintf(buf + ret, PAGE_SIZE - ret, + "rk2_pre_sb_%d,rk2_pre_pd_%d,rk2_act_sb_%d,rk2_act_pd_%d", i, i, i, i); + } + ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n"); + } +#endif + + /* DRS header */ + ret += snprintf(buf + ret, PAGE_SIZE - ret, + "met-info [000] 0.0: emi_drs_header: ch0_RANK1_GP(%%),ch0_RANK1_SF(%%),ch0_ALL_SF(%%),ch1_RANK1_GP(%%),ch1_RANK1_SF(%%),ch1_ALL_SF(%%)\n"); +#endif + return ret; +} + +static int ondiemet_emi_print_header(char *buf, int len) +{ + return emi_print_header(buf, len); +} + +static void MET_BM_IPI_REGISTER_CB(void) +{ + int ret, i; + unsigned int rdata; + unsigned int ipi_buf[4]; + + for (i = 0; i < 4; i++) + ipi_buf[i] = 0; + + if (sspm_buf_available == 1) { + ipi_buf[0] = MET_MAIN_ID | (MID_EMI << MID_BIT_SHIFT) | MET_ARGU | SET_REGISTER_CB; + ret = met_ipi_to_sspm_command((void *)ipi_buf, 0, &rdata, 1); + } +} + +static void MET_BM_IPI_configs(void) +{ + int ret, i; + unsigned int rdata; + unsigned int ipi_buf[4]; + + for (i = 0; i < 4; i++) + ipi_buf[i] = 0; + + if (sspm_buf_available == 1) { + ipi_buf[0] = MET_MAIN_ID | (MID_EMI << MID_BIT_SHIFT) | MET_ARGU | SET_EBM_CONFIGS1; + ret = met_ipi_to_sspm_command((void *)ipi_buf, 0, &rdata, 1); + } +} + +static void ondiemet_emi_start(void) +{ + MET_BM_IPI_REGISTER_CB(); + if (!emi_inited) { + if (MET_BM_Init() != 0) { + met_sspm_emi.mode = 0; + pr_notice("MET_BM_Init failed!!!\n"); + return; + } + emi_inited = 1; + } + MET_BM_IPI_configs(); + + if (do_emi()) + emi_init(); + + ondiemet_module[ONDIEMET_SSPM] |= ID_EMI; +} + +static void emi_uninit(void) +{ + MET_BM_RestoreCfg(); +} + +static void ondiemet_emi_stop(void) +{ + if (!emi_inited) + return; + + if (do_emi()) + emi_uninit(); +} +#endif /* end of #if defined(ONDIEMET_SUPPORT) || defined(TINYSYS_SSPM_SUPPORT) */ +#endif /* end of #if defined(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) */ + +struct metdevice met_sspm_emi = { + .name = "emi", + .owner = THIS_MODULE, + .type = MET_TYPE_BUS, + .create_subfs = met_emi_create, + .delete_subfs = met_emi_delete, + .resume = met_emi_resume, +#if IS_ENABLED(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) +#if defined(ONDIEMET_SUPPORT) || defined(TINYSYS_SSPM_SUPPORT) + .ondiemet_start = ondiemet_emi_start, + .ondiemet_stop = ondiemet_emi_stop, + .ondiemet_print_help = emi_print_help, + .ondiemet_print_header = ondiemet_emi_print_header, +#endif +#endif + .ondiemet_mode = 1, +}; +EXPORT_SYMBOL(met_sspm_emi); diff --git a/drivers/misc/mediatek/met_drv_v2/common/emi/SEDA3/mtk_emi_bm.c b/drivers/misc/mediatek/met_drv_v2/common/emi/SEDA3/mtk_emi_bm.c new file mode 100644 index 0000000000000000000000000000000000000000..dafeff3cbd7d2299a20365f3a1c75a5bea1ce964 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/emi/SEDA3/mtk_emi_bm.c @@ -0,0 +1,344 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2019 MediaTek Inc. + * + */ + +#include +#include +#include +#include + +#ifdef USE_KERNEL_SYNC_WRITE_H +#include +#else +#include "sync_write.h" +#endif + +#ifdef USE_KERNEL_MTK_IO_H +#include +#else +#include "mtk_io.h" +#endif + +/* #include "mtk_typedefs.h" */ +#include "core_plf_init.h" +#include "mtk_emi_bm.h" +#include "met_drv.h" +#include "interface.h" + +#if IS_ENABLED(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) +#if defined(ONDIEMET_SUPPORT) +#include "sspm/ondiemet_sspm.h" +#elif defined(TINYSYS_SSPM_SUPPORT) +#include "tinysys_sspm.h" +#include "tinysys_mgr.h" /* for ondiemet_module */ +#endif +#endif + +#undef DEBUG + +#define emi_readl readl +#define emi_reg_sync_writel mt_reg_sync_writel + +#define MASK_MASTER 0xFF +#define MASK_TRANS_TYPE 0xFF + +static void __iomem *BaseAddrEMI; +const unsigned int emi_config[] = { + EMI_BMEN, + EMI_MSEL, + EMI_MSEL2, + EMI_MSEL3, + EMI_MSEL4, + EMI_MSEL5, + EMI_MSEL6, + EMI_MSEL7, + EMI_MSEL8, + EMI_MSEL9, + EMI_MSEL10, + EMI_BMID0, + EMI_BMID1, + EMI_BMID2, + EMI_BMID3, + EMI_BMID4, + EMI_BMID5, + EMI_BMID6, + EMI_BMID7, + EMI_BMID8, + EMI_BMID9, + EMI_BMID10, + EMI_BMEN1, + EMI_BMEN2, + EMI_BMRW0, + EMI_BMRW1 +}; +#define EMI_CONFIG_MX_NR (sizeof(emi_config)/sizeof(unsigned int)) +static unsigned int emi_config_val[EMI_CONFIG_MX_NR]; + +int MET_BM_Init(void) +{ + /*emi*/ + if (mt_cen_emi_base_get_symbol) { + BaseAddrEMI = mt_cen_emi_base_get_symbol(); + } else { + pr_debug("mt_cen_emi_base_get_symbol = NULL\n"); + PR_BOOTMSG_ONCE("mt_cen_emi_base_get_symbol = NULL\n"); + BaseAddrEMI = 0; + } + + if (BaseAddrEMI == 0) { + pr_debug("BaseAddrEMI = 0\n"); + PR_BOOTMSG_ONCE("BaseAddrEMI = 0\n"); + return -1; + } + pr_debug("MET EMI: map emi to %p\n", BaseAddrEMI); + PR_BOOTMSG("MET EMI: map emi to %p\n", BaseAddrEMI); + + return 0; +} + +void MET_BM_DeInit(void) +{ +} + +void MET_BM_SaveCfg(void) +{ + int i; + + for (i = 0; i < EMI_CONFIG_MX_NR; i++) + emi_config_val[i] = emi_readl(IOMEM(ADDR_EMI + emi_config[i])); +} + +void MET_BM_RestoreCfg(void) +{ + int i; + + for (i = 0; i < EMI_CONFIG_MX_NR; i++) + emi_reg_sync_writel(emi_config_val[i], ADDR_EMI + emi_config[i]); +} + +int MET_BM_SetMonitorCounter(const unsigned int counter_num, + const unsigned int master, const unsigned int trans_type) +{ + unsigned int value, addr; + const unsigned int iMask = (MASK_TRANS_TYPE << 8) | MASK_MASTER; + + if (counter_num < 1 || counter_num > BM_COUNTER_MAX) + return BM_ERR_WRONG_REQ; + + + if (counter_num == 1) { + addr = EMI_BMEN; + value = (emi_readl(IOMEM(ADDR_EMI + addr)) & ~(iMask << 16)) | + ((trans_type & MASK_TRANS_TYPE) << 24) | ((master & MASK_MASTER) << 16); + } else { + addr = (counter_num <= 3) ? EMI_MSEL : (EMI_MSEL2 + (counter_num / 2 - 2) * 8); + + + value = emi_readl(IOMEM(ADDR_EMI + addr)) & ~(iMask << ((counter_num % 2) * 16)); + + + value |= (((trans_type & MASK_TRANS_TYPE) << 8) | + (master & MASK_MASTER)) << ((counter_num % 2) * 16); + } + + emi_reg_sync_writel(value, ADDR_EMI + addr); + + return BM_REQ_OK; +} + +int MET_BM_SetTtypeCounterRW(unsigned int bmrw0_val, unsigned int bmrw1_val) +{ + + unsigned int value_origin; + + value_origin = emi_readl(IOMEM(ADDR_EMI + EMI_BMRW0)); + MET_TRACE("[MET_EMI_settype1] value_origin: %x\n", value_origin); + if (value_origin != bmrw0_val) { + emi_reg_sync_writel(bmrw0_val, ADDR_EMI + EMI_BMRW0); + MET_TRACE("[MET_EMI_settype1] bmrw0_val: %x, value_origin: %x\n", bmrw0_val, + value_origin); + } + + value_origin = emi_readl(IOMEM(ADDR_EMI + EMI_BMRW1)); + MET_TRACE("[MET_EMI_settype2] value_origin: %x\n", value_origin); + if (value_origin != bmrw1_val) { + emi_reg_sync_writel(bmrw1_val, ADDR_EMI + EMI_BMRW1); + MET_TRACE("[MET_EMI_settype2] bmrw0_val: %x, value_origin: %x\n", bmrw1_val, + value_origin); + + } + return BM_REQ_OK; +} + +int MET_BM_Set_WsctTsct_id_sel(unsigned int counter_num, unsigned int enable) +{ + unsigned int value; + + if (counter_num > 3) + return BM_ERR_WRONG_REQ; + + value = + ((emi_readl(IOMEM(ADDR_EMI + EMI_BMEN2)) & (~(1 << (28 + counter_num)))) | + (enable << (28 + counter_num))); + emi_reg_sync_writel(value, ADDR_EMI + EMI_BMEN2); + + return BM_REQ_OK; +} + +int MET_BM_SetbusID_En(const unsigned int counter_num, + const unsigned int enable) +{ + unsigned int value; + + if ((counter_num < 1 || counter_num > BM_COUNTER_MAX) || (enable > 1)) + return BM_ERR_WRONG_REQ; + + if (enable == 0) { + + value = (emi_readl(IOMEM(ADDR_EMI + EMI_BMEN2)) + & ~(1 << (counter_num - 1))); + } else { + + value = (emi_readl(IOMEM(ADDR_EMI + EMI_BMEN2)) + | (1 << (counter_num - 1))); + } + emi_reg_sync_writel(value, ADDR_EMI + EMI_BMEN2); + + return BM_REQ_OK; +} + +int MET_BM_SetbusID(const unsigned int counter_num, + const unsigned int id) +{ + unsigned int value, addr, shift_num; + + if ((counter_num < 1 || counter_num > BM_COUNTER_MAX)) + return BM_ERR_WRONG_REQ; + + + addr = EMI_BMID0 + (counter_num - 1) / 2 * 4; + shift_num = ((counter_num - 1) % 2) * 16; + + value = emi_readl(IOMEM(ADDR_EMI + addr)) & ~(EMI_BMID_MASK << shift_num); + + + if (id <= 0xffff) + value |= id << shift_num; + + emi_reg_sync_writel(value, ADDR_EMI + addr); + + return BM_REQ_OK; +} + +int MET_BM_SetUltraHighFilter(const unsigned int counter_num, const unsigned int enable) +{ + unsigned int value; + + if ((counter_num < 1 || counter_num > BM_COUNTER_MAX) || (enable > 1)) + return BM_ERR_WRONG_REQ; + + + value = (emi_readl(IOMEM(ADDR_EMI + EMI_BMEN1)) + & ~(1 << (counter_num - 1))) + | (enable << (counter_num - 1)); + + emi_reg_sync_writel(value, ADDR_EMI + EMI_BMEN1); + + return BM_REQ_OK; +} + +int MET_BM_SetLatencyCounter(unsigned int enable) +{ + unsigned int value; + + value = emi_readl(IOMEM(ADDR_EMI + EMI_BMEN2)) & ~(0x3 << 24); + if (enable == 1) + value |= (0x2 << 24); + + emi_reg_sync_writel(value, ADDR_EMI + EMI_BMEN2); + + return BM_REQ_OK; +} + +unsigned int MET_EMI_GetDramChannNum(void) +{ + int num = -1; + + if (BaseAddrEMI) { + num = emi_readl(IOMEM(ADDR_EMI + EMI_CONA)); + num = ((num >> 8) & 0x0000003); + } else { + return 1; + } + + if (num == M0_DOUBLE_HALF_BW_1CH) + return 1; + else if (num == M0_DOUBLE_HALF_BW_2CH) + return 2; + else if (num == M0_DOUBLE_HALF_BW_4CH) + return 4; + else /* default return single channel */ + return 1; +} + + +unsigned int MET_EMI_GetDramRankNum(void) +{ + int dual_rank = 0; + + if (BaseAddrEMI) { + dual_rank = emi_readl(IOMEM(ADDR_EMI + EMI_CONA)); + dual_rank = ((dual_rank >> 17) & RANK_MASK); + } else { + return DUAL_RANK; + } + + if (dual_rank == DISABLE_DUAL_RANK_MODE) + return ONE_RANK; + else /* default return dual rank */ + return DUAL_RANK; +} + + +unsigned int MET_EMI_GetDramRankNum_CHN1(void) +{ + int dual_rank = 0; + + if (BaseAddrEMI) { + dual_rank = emi_readl(IOMEM(ADDR_EMI + EMI_CONA)); + dual_rank = ((dual_rank >> 16) & RANK_MASK); + } else { + return DUAL_RANK; + } + + if (dual_rank == DISABLE_DUAL_RANK_MODE) + return ONE_RANK; + else /* default return dual rank */ + return DUAL_RANK; +} + +unsigned int MET_EMI_Get_BaseClock_Rate(void) +{ + unsigned int DRAM_TYPE; + + if (get_cur_ddr_ratio_symbol) + return get_cur_ddr_ratio_symbol(); + else { + if (mtk_dramc_get_ddr_type_symbol) + DRAM_TYPE = mtk_dramc_get_ddr_type_symbol(); + else if (get_ddr_type_symbol) + DRAM_TYPE = get_ddr_type_symbol(); + + if (mtk_dramc_get_ddr_type_symbol || get_ddr_type_symbol) { + if ((DRAM_TYPE == 2) || (DRAM_TYPE == 3)) + return DRAM_EMI_BASECLOCK_RATE_LP4; + else + return DRAM_EMI_BASECLOCK_RATE_LP3; + + } else { + return DRAM_EMI_BASECLOCK_RATE_LP4; + } + } +} diff --git a/drivers/misc/mediatek/met_drv_v2/common/emi/SEDA3/mtk_emi_bm.h b/drivers/misc/mediatek/met_drv_v2/common/emi/SEDA3/mtk_emi_bm.h new file mode 100644 index 0000000000000000000000000000000000000000..4e8baf64e3d52024ecf8ba9adefb360ada934727 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/emi/SEDA3/mtk_emi_bm.h @@ -0,0 +1,182 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2019 MediaTek Inc. + * + */ + +#ifndef __MT_MET_EMI_BM_H__ +#define __MT_MET_EMI_BM_H__ + +#define EMI_VER_MAJOR 3 +#define EMI_VER_MINOR 0 + + +#define DRAM_EMI_BASECLOCK_RATE_LP4 4 +#define DRAM_EMI_BASECLOCK_RATE_LP3 2 + +#define DRAM_IO_BUS_WIDTH_LP4 16 +#define DRAM_IO_BUS_WIDTH_LP3 32 + +#define DRAM_DATARATE 2 + +#define ADDR_EMI ((unsigned long) BaseAddrEMI) + +/*========================================================*/ +/*EMI configuration by project*/ +/*Change config start*/ +/*========================================================*/ +#define _GP_1_Default (_M0 | _M1) +#define _GP_2_Default (_M2 | _M5) +#define _GP_3_Default (_M6 | _M7) + + +/*========================================================*/ +/*Change config end*/ +/*========================================================*/ + + +#define _M0 (0x01) +#define _M1 (0x02) +#define _M2 (0x04) +#define _M3 (0x08) +#define _M4 (0x10) +#define _M5 (0x20) +#define _M6 (0x40) +#define _M7 (0x80) +#define _ALL (0xFF) + +enum BM_RW_Type { + BM_BOTH_READ_WRITE, + BM_READ_ONLY, + BM_WRITE_ONLY +}; + +enum { + BM_TRANS_TYPE_1BEAT = 0x0, + BM_TRANS_TYPE_2BEAT, + BM_TRANS_TYPE_3BEAT, + BM_TRANS_TYPE_4BEAT, + BM_TRANS_TYPE_5BEAT, + BM_TRANS_TYPE_6BEAT, + BM_TRANS_TYPE_7BEAT, + BM_TRANS_TYPE_8BEAT, + BM_TRANS_TYPE_9BEAT, + BM_TRANS_TYPE_10BEAT, + BM_TRANS_TYPE_11BEAT, + BM_TRANS_TYPE_12BEAT, + BM_TRANS_TYPE_13BEAT, + BM_TRANS_TYPE_14BEAT, + BM_TRANS_TYPE_15BEAT, + BM_TRANS_TYPE_16BEAT, + BM_TRANS_TYPE_1Byte = 0 << 4, + BM_TRANS_TYPE_2Byte = 1 << 4, + BM_TRANS_TYPE_4Byte = 2 << 4, + BM_TRANS_TYPE_8Byte = 3 << 4, + BM_TRANS_TYPE_16Byte = 4 << 4, + BM_TRANS_TYPE_32Byte = 5 << 4, + BM_TRANS_TYPE_BURST_WRAP = 0 << 7, + BM_TRANS_TYPE_BURST_INCR = 1 << 7 +}; + +enum { + BM_TRANS_RW_DEFAULT = 0x0, + BM_TRANS_RW_READONLY, + BM_TRANS_RW_WRITEONLY, + BM_TRANS_RW_RWBOTH +}; + + +#define EMI_BMID_MASK (0xFFFF) +#define BM_COUNTER_MAX (21) + +#define BM_REQ_OK (0) +#define BM_ERR_WRONG_REQ (-1) +#define BM_ERR_OVERRUN (-2) + +#define BM_TTYPE1_16_ENABLE (0) +#define BM_TTYPE1_16_DISABLE (-1) +#define BM_TTYPE17_21_ENABLE (0) +#define BM_TTYPE17_21_DISABLE (-1) + +#define BM_BW_LIMITER_ENABLE (0) +#define BM_BW_LIMITER_DISABLE (-1) + +#define M0_DOUBLE_HALF_BW_1CH (0x0) +#define M0_DOUBLE_HALF_BW_2CH (0x1) +#define M0_DOUBLE_HALF_BW_4CH (0x2) + +/* EMI Rank configuration */ +enum { + DISABLE_DUAL_RANK_MODE = 0, + ENABLE_DUAL_RANK_MODE, +}; + +#define RANK_MASK 0x1 +#define ONE_RANK 1 +#define DUAL_RANK 2 + +#if IS_ENABLED(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) +#if defined(ONDIEMET_SUPPORT) || defined(TINYSYS_SSPM_SUPPORT) +enum BM_EMI_IPI_Type { + SET_BASE_EMI = 0x0, + SET_EBM_CONFIGS1 = 0x7, + SET_EBM_CONFIGS2 = 0x8, + SET_REGISTER_CB = 0x9, +}; +#endif +#endif + +#define EMI_OFF 0x0000 +#define EMI_CONA (0x000-EMI_OFF) +#define EMI_BMEN (0x400-EMI_OFF) +#define EMI_MSEL (0x440-EMI_OFF) +#define EMI_MSEL2 (0x468-EMI_OFF) +#define EMI_MSEL3 (0x470-EMI_OFF) +#define EMI_MSEL4 (0x478-EMI_OFF) +#define EMI_MSEL5 (0x480-EMI_OFF) +#define EMI_MSEL6 (0x488-EMI_OFF) +#define EMI_MSEL7 (0x490-EMI_OFF) +#define EMI_MSEL8 (0x498-EMI_OFF) +#define EMI_MSEL9 (0x4A0-EMI_OFF) +#define EMI_MSEL10 (0x4A8-EMI_OFF) + +#define EMI_BMID0 (0x4B0-EMI_OFF) +#define EMI_BMID1 (0x4B4-EMI_OFF) +#define EMI_BMID2 (0x4B8-EMI_OFF) +#define EMI_BMID3 (0x4BC-EMI_OFF) +#define EMI_BMID4 (0x4C0-EMI_OFF) +#define EMI_BMID5 (0x4C4-EMI_OFF) +#define EMI_BMID6 (0x4C8-EMI_OFF) +#define EMI_BMID7 (0x4CC-EMI_OFF) +#define EMI_BMID8 (0x4D0-EMI_OFF) +#define EMI_BMID9 (0x4D4-EMI_OFF) +#define EMI_BMID10 (0x4D8-EMI_OFF) + +#define EMI_BMEN1 (0x4E0-EMI_OFF) +#define EMI_BMEN2 (0x4E8-EMI_OFF) +#define EMI_BMRW0 (0x4F8-EMI_OFF) +#define EMI_BMRW1 (0x4FC-EMI_OFF) + + +extern unsigned int MET_EMI_GetDramRankNum(void); +extern unsigned int MET_EMI_GetDramRankNum_CHN1(void); + + +unsigned int MET_EMI_GetDramChannNum(void); + +extern int MET_BM_Init(void); +extern void MET_BM_DeInit(void); +extern void MET_BM_SaveCfg(void); +extern void MET_BM_RestoreCfg(void); +extern int MET_BM_SetMonitorCounter(const unsigned int counter_num, + const unsigned int master, const unsigned int trans_type); +extern int MET_BM_SetTtypeCounterRW(unsigned int bmrw0_val, unsigned int bmrw1_val); +extern int MET_BM_Set_WsctTsct_id_sel(unsigned int counter_num, unsigned int enable); +extern int MET_BM_SetbusID_En(const unsigned int counter_num, + const unsigned int enable); +extern int MET_BM_SetbusID(const unsigned int counter_num, + const unsigned int id); +extern int MET_BM_SetUltraHighFilter(const unsigned int counter_num, const unsigned int enable); +extern int MET_BM_SetLatencyCounter(unsigned int enable); +extern unsigned int MET_EMI_Get_BaseClock_Rate(void); +#endif /* !__MT_MET_EMI_BM_H__ */ diff --git a/drivers/misc/mediatek/met_drv_v2/common/emi/SEDA3_5/met_emi.c b/drivers/misc/mediatek/met_drv_v2/common/emi/SEDA3_5/met_emi.c new file mode 100644 index 0000000000000000000000000000000000000000..6ce09958b02d0d3da182fc9d2bc4467c0f938a5f --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/emi/SEDA3_5/met_emi.c @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2019 MediaTek Inc. + * + */ +#include +#include +#include +#include +#include +#include +#include + +#define MET_USER_EVENT_SUPPORT +#include "met_drv.h" +#include "trace.h" + +#include "mtk_typedefs.h" +#include "core_plf_init.h" +#include "mtk_emi_bm.h" +#include "interface.h" +#include "met_dramc.h" + + +/*======================================================================*/ +/* MET Device Operations */ +/*======================================================================*/ + +static int met_emi_create(struct kobject *parent) +{ + int ret = 0; + + ret = met_emi_create_basic(parent, &met_sspm_emi); + return ret; +} + +static void met_emi_delete(void) +{ + met_emi_delete_basic(); +} + +static void met_emi_resume(void) +{ + met_emi_resume_basic(); +} + +static int emi_print_header(char *buf, int len) +{ + len = emi_print_header_basic(buf,len); + return len; +} + +#if IS_ENABLED(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) +#if defined(ONDIEMET_SUPPORT) || defined(TINYSYS_SSPM_SUPPORT) +static int emi_print_help(char *buf, int len) +{ + return snprintf(buf, PAGE_SIZE, emi_help_msg); +} + +static int ondiemet_emi_print_header(char *buf, int len) +{ + return emi_print_header(buf, len); +} + +static void ondiemet_emi_start(void) +{ + ondiemet_emi_start_basic(); +} + +static void ondiemet_emi_stop(void) +{ + ondiemet_emi_stop_basic(); +} +#endif +#endif + +struct metdevice met_sspm_emi = { + .name = "emi", + .owner = THIS_MODULE, + .type = MET_TYPE_BUS, + .create_subfs = met_emi_create, + .delete_subfs = met_emi_delete, + .resume = met_emi_resume, + .print_header = emi_print_header, +#if IS_ENABLED(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) +#if defined(ONDIEMET_SUPPORT) || defined(TINYSYS_SSPM_SUPPORT) + .ondiemet_start = ondiemet_emi_start, + .ondiemet_stop = ondiemet_emi_stop, + .ondiemet_print_help = emi_print_help, + .ondiemet_print_header = ondiemet_emi_print_header, +#endif +#endif + .ondiemet_mode = 1, +}; +EXPORT_SYMBOL(met_sspm_emi); diff --git a/drivers/misc/mediatek/met_drv_v2/common/emi/SEDA3_5/mtk_emi_bm.c b/drivers/misc/mediatek/met_drv_v2/common/emi/SEDA3_5/mtk_emi_bm.c new file mode 100644 index 0000000000000000000000000000000000000000..b7bad6699c3e0ad3886655d6688fd4c1391c05e9 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/emi/SEDA3_5/mtk_emi_bm.c @@ -0,0 +1,3341 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2019 MediaTek Inc. + * + */ +#include +#include +#include +#include + +#ifdef USE_KERNEL_SYNC_WRITE_H +#include +#else +#include "sync_write.h" +#endif + +#ifdef USE_KERNEL_MTK_IO_H +#include +#else +#include "mtk_io.h" +#endif + +#include "mtk_typedefs.h" +#include "core_plf_init.h" +#include "mtk_emi_bm.h" + +#include "met_drv.h" +#include "interface.h" + +#include "met_dramc.h" + +#ifdef MET_REG_ARRD +#include "met_reg_addr.h" +#endif + +#undef DEBUG +#undef debug_reg +#ifdef debug_reg +static inline unsigned int emi_readl(void __iomem *padr) +{ + unsigned int tmp; + + tmp = readl(padr); + MET_TRACE("[MET_EMI] RD_Reg: %p: %08x\n", padr, tmp); + return tmp; +} + +static inline void __emi_reg_sync_writel(unsigned int data, void __iomem *padr) +{ + unsigned int tmp; + + mt_reg_sync_writel(data, padr); + tmp = readl(padr); + MET_TRACE("[MET_EMI] WR_Reg: %p: %08x, %08x\n", padr, data, tmp); +} + +#define emi_reg_sync_writel(data, adr) __emi_reg_sync_writel(data, IOMEM(adr)) + +#else +#define emi_readl readl +#define emi_reg_sync_writel mt_reg_sync_writel +#endif + + + + +void __iomem *BaseAddrEMI; +void __iomem *BaseAddrCHN_EMI[2]; + + +#define CH0_MISC_CG_CTRL0 (((unsigned long) BaseAddrDDRPHY_AO[0]) + 0x284) +#define CH1_MISC_CG_CTRL0 (((unsigned long) BaseAddrDDRPHY_AO[1]) + 0x284) +const unsigned int emi_config[] = { + EMI_BMEN, + EMI_MSEL, + EMI_MSEL2, + EMI_MSEL3, + EMI_MSEL4, + EMI_MSEL5, + EMI_MSEL6, + EMI_MSEL7, + EMI_MSEL8, + EMI_MSEL9, + EMI_MSEL10, + EMI_BMID0, + EMI_BMID1, + EMI_BMID2, + EMI_BMID3, + EMI_BMID4, + EMI_BMID5, + EMI_BMID6, + EMI_BMID7, + EMI_BMID8, + EMI_BMID9, + EMI_BMID10, + EMI_BMEN1, + EMI_BMEN2, + EMI_BMRW0, + EMI_BMRW1, + EMI_DBWA, + EMI_DBWB, + EMI_DBWC, + EMI_DBWD, + EMI_DBWE, + EMI_DBWF, + EMI_DBWI, + EMI_DBWJ, + EMI_DBWK, + EMI_DBWA_2ND, + EMI_DBWB_2ND, + EMI_DBWC_2ND, + EMI_DBWD_2ND, + EMI_DBWE_2ND, + EMI_DBWF_2ND, + EMI_TTYPE1_CONA, + EMI_TTYPE1_CONB, + EMI_TTYPE2_CONA, + EMI_TTYPE2_CONB, + EMI_TTYPE3_CONA, + EMI_TTYPE3_CONB, + EMI_TTYPE4_CONA, + EMI_TTYPE4_CONB, + EMI_TTYPE5_CONA, + EMI_TTYPE5_CONB, + EMI_TTYPE6_CONA, + EMI_TTYPE6_CONB, + EMI_TTYPE7_CONA, + EMI_TTYPE7_CONB, + EMI_TTYPE8_CONA, + EMI_TTYPE8_CONB, + EMI_TTYPE9_CONA, + EMI_TTYPE9_CONB, + EMI_TTYPE10_CONA, + EMI_TTYPE10_CONB, + EMI_TTYPE11_CONA, + EMI_TTYPE11_CONB, + EMI_TTYPE12_CONA, + EMI_TTYPE12_CONB, + EMI_TTYPE13_CONA, + EMI_TTYPE13_CONB, + EMI_TTYPE14_CONA, + EMI_TTYPE14_CONB, + EMI_TTYPE15_CONA, + EMI_TTYPE15_CONB, + EMI_TTYPE16_CONA, + EMI_TTYPE16_CONB, + EMI_TTYPE17_CONA, + EMI_TTYPE17_CONB, + EMI_TTYPE18_CONA, + EMI_TTYPE18_CONB, + EMI_TTYPE19_CONA, + EMI_TTYPE19_CONB, + EMI_TTYPE20_CONA, + EMI_TTYPE20_CONB, + EMI_TTYPE21_CONA, + EMI_TTYPE21_CONB +}; +#define EMI_CONFIG_MX_NR (sizeof(emi_config)/sizeof(unsigned int)) +static unsigned int emi_config_val[EMI_CONFIG_MX_NR]; + +const unsigned int emi_chn_config[] = { + CHN_EMI_LOWEFF_CTL0 +}; +#define EMI_CHN_CONFIG_MX_NR (sizeof(emi_chn_config)/sizeof(unsigned int)) +static unsigned int emi_chn_config_val[MET_MAX_DRAM_CH_NUM][EMI_CHN_CONFIG_MX_NR]; + +enum MET_EMI_DEFAULT_VAL_LIST{ + e_MET_DRAM_FREQ = 0, + e_MET_DRAM_TYPE, + e_MET_DDR_RATIO, + + NR_MET_DEFAULT_VAL, +}; + +unsigned int met_emi_default_val[NR_MET_DEFAULT_VAL]; + + +/* get the emi base addr */ +int MET_BM_Init(void) +{ + int i; + /*emi*/ +#ifndef EMI_REG_BASE + if (mt_cen_emi_base_get_symbol) { + BaseAddrEMI = mt_cen_emi_base_get_symbol(); + } else { + METERROR("mt_cen_emi_base_get_symbol = NULL, use the pre-define addr to mmap\n"); + PR_BOOTMSG_ONCE("mt_cen_emi_base_get_symbol = NULL, use the pre-define addr to mmap\n"); + BaseAddrEMI = 0; + } +#else + BaseAddrEMI = ioremap(EMI_REG_BASE, EMI_REG_SIZE); +#endif + + if (BaseAddrEMI == 0) { + METERROR("BaseAddrEMI = 0\n"); + PR_BOOTMSG_ONCE("BaseAddrEMI = 0\n"); + return -1; + } + pr_debug("MET EMI: map emi to %p\n", BaseAddrEMI); + PR_BOOTMSG("MET EMI: map emi to %p\n", BaseAddrEMI); + + /* emi channel */ + dram_chann_num = MET_EMI_GetDramChannNum(); + +#ifndef EMI_CHN_BASE + if (!mt_chn_emi_base_get_symbol) { + for(i=0; i both R/W + * 01 --> only R + * 10 --> only W + */ + emi_reg_sync_writel((value & 0xFFFFFFCF) | (ReadWriteType << 4), ADDR_EMI + EMI_BMEN); +} + +int MET_BM_SetMonitorCounter(const unsigned int counter_num, + const unsigned int master, const unsigned int trans_type) +{ + unsigned int value, addr; + const unsigned int iMask = (MASK_TRANS_TYPE << 8) | MASK_MASTER; + + if (counter_num < 1 || counter_num > BM_COUNTER_MAX) + return BM_ERR_WRONG_REQ; + + + if (counter_num == 1) { + addr = EMI_BMEN; + value = (emi_readl(IOMEM(ADDR_EMI + addr)) & ~(iMask << 16)) | + ((trans_type & MASK_TRANS_TYPE) << 24) | ((master & MASK_MASTER) << 16); + } else { + addr = (counter_num <= 3) ? EMI_MSEL : (EMI_MSEL2 + (counter_num / 2 - 2) * 8); + + /* clear master and transaction type fields */ + value = emi_readl(IOMEM(ADDR_EMI + addr)) & ~(iMask << ((counter_num % 2) * 16)); + + /* set master and transaction type fields */ + value |= (((trans_type & MASK_TRANS_TYPE) << 8) | + (master & MASK_MASTER)) << ((counter_num % 2) * 16); + } + + emi_reg_sync_writel(value, ADDR_EMI + addr); + + return BM_REQ_OK; +} + +int MET_BM_SetTtypeCounterRW(unsigned int bmrw0_val, unsigned int bmrw1_val) +{ + + unsigned int value_origin; + + value_origin = emi_readl(IOMEM(ADDR_EMI + EMI_BMRW0)); + MET_TRACE("[MET_EMI_settype1] value_origin: %x\n", value_origin); + if (value_origin != bmrw0_val) { + emi_reg_sync_writel(bmrw0_val, ADDR_EMI + EMI_BMRW0); + MET_TRACE("[MET_EMI_settype1] bmrw0_val: %x, value_origin: %x\n", bmrw0_val, + value_origin); + } + + + value_origin = emi_readl(IOMEM(ADDR_EMI + EMI_BMRW1)); + MET_TRACE("[MET_EMI_settype2] value_origin: %x\n", value_origin); + if (value_origin != bmrw1_val) { + emi_reg_sync_writel(bmrw1_val, ADDR_EMI + EMI_BMRW1); + MET_TRACE("[MET_EMI_settype2] bmrw0_val: %x, value_origin: %x\n", bmrw1_val, + value_origin); + + } + return BM_REQ_OK; +} + +int MET_BM_Set_WsctTsct_id_sel(unsigned int counter_num, unsigned int enable) +{ + unsigned int value; + + if (counter_num > 3) + return BM_ERR_WRONG_REQ; + + value = + ((emi_readl(IOMEM(ADDR_EMI + EMI_BMEN2)) & (~(1 << (28 + counter_num)))) | + (enable << (28 + counter_num))); + emi_reg_sync_writel(value, ADDR_EMI + EMI_BMEN2); + + return BM_REQ_OK; +} + +int MET_BM_SetMaster(const unsigned int counter_num, const unsigned int master) +{ + unsigned int value, addr; + const unsigned int iMask = 0x7F; + + if (counter_num < 1 || counter_num > BM_COUNTER_MAX) + return BM_ERR_WRONG_REQ; + + + if (counter_num == 1) { + addr = EMI_BMEN; + value = + (emi_readl(IOMEM(ADDR_EMI + addr)) & ~(iMask << 16)) | ((master & iMask) << 16); + } else { + addr = (counter_num <= 3) ? EMI_MSEL : (EMI_MSEL2 + (counter_num / 2 - 2) * 8); + + /* clear master and transaction type fields */ + value = emi_readl(IOMEM(ADDR_EMI + addr)) & ~(iMask << ((counter_num % 2) * 16)); + + /* set master and transaction type fields */ + value |= ((master & iMask) << ((counter_num % 2) * 16)); + } + + emi_reg_sync_writel(value, ADDR_EMI + addr); + + return BM_REQ_OK; +} + + +int MET_BM_SetbusID_En(const unsigned int counter_num, + const unsigned int enable) +{ + unsigned int value; + + if ((counter_num < 1 || counter_num > BM_COUNTER_MAX) || (enable > 1)) + return BM_ERR_WRONG_REQ; + + if (enable == 0) { + /* clear EMI ID selection Enabling SEL_ID_EN */ + value = (emi_readl(IOMEM(ADDR_EMI + EMI_BMEN2)) + & ~(1 << (counter_num - 1))); + } else { + /* enable EMI ID selection Enabling SEL_ID_EN */ + value = (emi_readl(IOMEM(ADDR_EMI + EMI_BMEN2)) + | (1 << (counter_num - 1))); + } + emi_reg_sync_writel(value, ADDR_EMI + EMI_BMEN2); + + return BM_REQ_OK; +} + + +int MET_BM_SetbusID(const unsigned int counter_num, + const unsigned int id) +{ + unsigned int value, addr, shift_num; + + if ((counter_num < 1 || counter_num > BM_COUNTER_MAX)) + return BM_ERR_WRONG_REQ; + + /* offset of EMI_BMIDx register */ + addr = EMI_BMID0 + (counter_num - 1) / 2 * 4; + shift_num = ((counter_num - 1) % 2) * 16; + /* clear SELx_ID field */ + value = emi_readl(IOMEM(ADDR_EMI + addr)) & ~(EMI_BMID_MASK << shift_num); + + /* set SELx_ID field */ + if (id <= 0xffff) /*bigger then 0xff_ff : no select busid in master, reset busid as 0*/ + value |= id << shift_num; + + emi_reg_sync_writel(value, ADDR_EMI + addr); + + return BM_REQ_OK; +} + + +int MET_BM_SetUltraHighFilter(const unsigned int counter_num, const unsigned int enable) +{ + unsigned int value; + + if ((counter_num < 1 || counter_num > BM_COUNTER_MAX) || (enable > 1)) + return BM_ERR_WRONG_REQ; + + + value = (emi_readl(IOMEM(ADDR_EMI + EMI_BMEN1)) + & ~(1 << (counter_num - 1))) + | (enable << (counter_num - 1)); + + emi_reg_sync_writel(value, ADDR_EMI + EMI_BMEN1); + + return BM_REQ_OK; +} + + +int MET_BM_SetLatencyCounter(unsigned int enable) +{ + unsigned int value; + + value = emi_readl(IOMEM(ADDR_EMI + EMI_BMEN2)) & ~(0x3 << 24); + /* + * emi_ttype1 -- emi_ttype8 change as total latencies + * for m0 -- m7, + * and emi_ttype9 -- emi_ttype16 change as total transaction counts + * for m0 -- m7 + */ + if (enable == 1) + value |= (0x2 << 24); + + emi_reg_sync_writel(value, ADDR_EMI + EMI_BMEN2); + + return BM_REQ_OK; +} + + + +unsigned int MET_EMI_GetDramChannNum(void) +{ + int num = -1; + + if (BaseAddrEMI) { + num = emi_readl(IOMEM(ADDR_EMI + EMI_CONA)); + num = ((num >> 8) & 0x0000003); + } else { + return 1; + } + + if (num == M0_DOUBLE_HALF_BW_1CH) + return 1; + else if (num == M0_DOUBLE_HALF_BW_2CH) + return 2; + else if (num == M0_DOUBLE_HALF_BW_4CH) + return 4; + else /* default return single channel */ + return 1; +} + + +unsigned int MET_EMI_GetDramRankNum(void) +{ + int dual_rank = 0; + + if (BaseAddrEMI) { + dual_rank = emi_readl(IOMEM(ADDR_EMI + EMI_CONA)); + dual_rank = ((dual_rank >> 17) & RANK_MASK); + } else { + return DUAL_RANK; + } + + if (dual_rank == DISABLE_DUAL_RANK_MODE) + return ONE_RANK; + else /* default return dual rank */ + return DUAL_RANK; +} + + +unsigned int MET_EMI_GetDramRankNum_CHN1(void) +{ + int dual_rank = 0; + + if (BaseAddrEMI) { + dual_rank = emi_readl(IOMEM(ADDR_EMI + EMI_CONA)); + dual_rank = ((dual_rank >> 16) & RANK_MASK); + } else { + return DUAL_RANK; + } + + if (dual_rank == DISABLE_DUAL_RANK_MODE) + return ONE_RANK; + else /* default return dual rank */ + return DUAL_RANK; +} + + +#ifdef EMI_LOWEFF_SUPPORT +int MET_EMI_Get_LOWEFF_CTL0(int channel){ + + if ( (channel<0) || (channel>=MET_MAX_DRAM_CH_NUM)) + return 0; + + if (BaseAddrCHN_EMI[channel]) { + return emi_readl(IOMEM(BaseAddrCHN_EMI[channel] + CHN_EMI_LOWEFF_CTL0)); + } else { + return 0; + } +} + +int MET_BM_SetLOWEFF_master_rw(unsigned chan, unsigned int *wmask_msel , unsigned int *ageexp_msel, unsigned int *ageexp_rw) +{ + unsigned int value; + + const unsigned int Mask_master = 0xFF; + const unsigned int offset_wmask_master= 16; + const unsigned int offset_ageexp_master= 24; + + const unsigned int Mask_rw = 0x3; + const unsigned int offset_rw = 3; + + if ( (chan < 0) || (chan >= MET_MAX_DRAM_CH_NUM)) + return -1; + + if (BaseAddrCHN_EMI[chan]) { + value = emi_readl(IOMEM(BaseAddrCHN_EMI[chan] + CHN_EMI_LOWEFF_CTL0)); + + /* wmask msel */ + value = (value & ~(Mask_master << offset_wmask_master)) | ((*(wmask_msel + chan) & Mask_master) << offset_wmask_master); + /* age msel */ + value = (value & ~(Mask_master << offset_ageexp_master)) | ((*(ageexp_msel + chan) & Mask_master) << offset_ageexp_master); + /* age rw */ + value = (value & ~(Mask_rw << offset_rw)) | ((*(ageexp_rw + chan) & Mask_rw) << offset_rw); + + emi_reg_sync_writel(value, BaseAddrCHN_EMI[chan] + CHN_EMI_LOWEFF_CTL0); + } else { + return -1; + } + return BM_REQ_OK; +} + +#endif + +/* For SEDA3.5 wsct setting*/ +/* EMI_DBWX[15:8], X=A~F (SEL_MASTER) */ +/* RW: EMI_DBWX[1:0], X=A~F */ +int MET_BM_SetWSCT_master_rw(unsigned int *master , unsigned int *rw) +{ + unsigned int value, addr; + int i; + + const unsigned int Mask_master = 0xFF; + const unsigned int offset_master = 8; + + const unsigned int Mask_rw = 0x3; + const unsigned int offset_rw = 0; + + for (i=0; i0xffff) { + enable_tmp = 0; + busid_tmp = 0xFFFF; + idmask_tmp = 0xFFFF; + } + else { + enable_tmp = 1; + busid_tmp = *(busid+i) & Mask_busid; + idmask_tmp = *(idMask+i) & Mask_idMask; + } + + + addr = EMI_DBWA + i*4; + value = emi_readl(IOMEM(ADDR_EMI + addr)); + + value = (value & ~(Mask_busid << offset_busid)) | (busid_tmp << offset_busid); + value = (value & ~(Mask_enable << offset_enable)) | (enable_tmp << offset_enable); + + emi_reg_sync_writel(value, ADDR_EMI + addr); + + /*SEL_ID_MSK*/ + addr = EMI_DBWI + (i/2)*4; + + value = emi_readl(IOMEM(ADDR_EMI + addr)); + + if (i%2==0) + value = (value & ~(Mask_idMask << offset_idMask_even)) | (idmask_tmp << offset_idMask_even); + else + value = (value & ~(Mask_idMask << offset_idMask_odd)) | (idmask_tmp << offset_idMask_odd); + + emi_reg_sync_writel(value, ADDR_EMI + addr); + } + + + return BM_REQ_OK; +} + + +int MET_BM_SetWSCT_chn_rank_sel(unsigned int *chn_rank_sel) +{ + unsigned int value, addr; + int i; + + const unsigned int Mask = 0xF; + const unsigned int offset = 12; + + + for (i=0;i 0xffff) ? 0 : 1); + + /* set idMask */ + addr = EMI_TTYPE1_CONA + (i-1)*8; + value = emi_readl(IOMEM(ADDR_EMI + addr)); + + value = (value & ~(Mask_idMask << offset_idMask)) | ((*(idMask+i-1) & Mask_idMask) << offset_idMask); + + emi_reg_sync_writel(value, ADDR_EMI + addr); + + } + + return BM_REQ_OK; +} + + +int MET_BM_SetTtype_chn_rank_sel(unsigned int *chn_rank_sel) +{ + unsigned int value, addr; + int i; + + const unsigned int Mask = 0xF; + const unsigned int offset = 16; + + + for (i=0;i= 0 && id_int < NR_MET_DEFAULT_VAL) { + if (kstrtouint(_value, 0, &met_emi_default_val[id_int]) != 0) { + PR_BOOTMSG("_value[%s] trans to hex err\n",_value); + _clear_default_val(); + return -EINVAL; + } + } else { + PR_BOOTMSG("id[%d] exceed the range, it must be 0~%d\n",id_int, NR_MET_DEFAULT_VAL-1); + _clear_default_val(); + return -EINVAL; + } + } + return n; +} + +ssize_t default_val_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + int i; + int ret = 0; + + for (i=0; i clear_setting + */ + + int ret; + char *token, *cur= msel_group_ext; + char *_id = NULL, *_master_group = NULL; + int id_int = 0; + + _clear_msel_group_ext(); + + ret = snprintf(msel_group_ext, FILE_NODE_DATA_LEN, "%s", buf); + if (ret < 0) return -EINVAL; + + msel_group_ext[n-1]='\0'; + + while (cur != NULL) { + token = strsep(&cur, delim_comma); + /*PR_BOOTMSG("token: %s\n",token);*/ + /*token EX: 4:0xff , (ID,master_group)*/ + + _id = strsep(&token, delim_coclon); // ID + _master_group = strsep(&token, delim_coclon); + + // PR_BOOTMSG("_id[%s] _master_group[%s]\n",_id,_master_group); + + if (_id == NULL || _master_group == NULL) { + PR_BOOTMSG("err: _id[%s] _master_group[%s], para can't be NULL\n",_id,_master_group); + _clear_msel_group_ext(); + return -EINVAL; + } + + if (kstrtouint(_id, 0, &id_int) != 0) { + PR_BOOTMSG("_id[%s] trans to hex err\n",_id); + _clear_msel_group_ext(); + return -EINVAL; + } + + + if ( id_int >= 0 && id_int < WSCT_AMOUNT) { + if (kstrtouint(_master_group, 0, &msel_group_ext_val[id_int]) != 0) { + PR_BOOTMSG("master_group[%s] trans to hex err\n",_master_group); + _clear_msel_group_ext(); + return -EINVAL; + } + } else { + PR_BOOTMSG("id[%d] exceed the range, it must be 0~%d\n",id_int, WSCT_AMOUNT-1); + _clear_msel_group_ext(); + return -EINVAL; + } + } +#ifdef FILE_NODE_DBG + PR_BOOTMSG("input data [%s]\n",msel_group_ext); + /*PR_BOOTMSG("msel_group_ext_store size para n[%d]\n",n);*/ + int i; + PR_BOOTMSG("save data\n"); + for (i=0;i= 0 && id_int < WSCT_AMOUNT) { + if ( 0 == strncmp("NONE",_rw_type,4)) + wsct_rw_val[id_int] = BM_WSCT_RW_DISABLE; + else if (0 == strncmp("R",_rw_type,4)) + wsct_rw_val[id_int] = BM_WSCT_RW_READONLY; + else if (0 == strncmp("W",_rw_type,4)) + wsct_rw_val[id_int] = BM_WSCT_RW_WRITEONLY; + else if (0 == strncmp("RW",_rw_type,4)) + wsct_rw_val[id_int] = BM_WSCT_RW_RWBOTH; + else { + PR_BOOTMSG("_id[%s] has err rwtype[%s]\n", _id, _rw_type); + _clear_wsct_rw(); + return -EINVAL; + } + + } else { + PR_BOOTMSG("id[%d] exceed the range, it must be 0~%d\n",id_int, WSCT_AMOUNT-1); + _clear_wsct_rw(); + return -EINVAL; + } + } + +#ifdef FILE_NODE_DBG + PR_BOOTMSG("wsct_rw_store input data [%s]\n",wsct_rw); + int i; + PR_BOOTMSG("rwtype save data\n"); + for (i=0;i= 0 && id_int < WSCT_AMOUNT) { + if ( 0 == strncmp("disable", _enable, 7)) { + + WSCT_HPRI_DIS[id_int] = 1; + WSCT_HPRI_SEL[id_int] = 0xf; + } else if ( 0 == strncmp("enable", _enable, 6)) { + + WSCT_HPRI_DIS[id_int] = 0; + if (kstrtouint(_level, 0, &level_int) != 0) { + PR_BOOTMSG("_id[%s] trans ultraLevel[%s] to hex err\n",_id, _level); + _clear_wsct_high_priority_enable(); + return -EINVAL; + } + WSCT_HPRI_SEL[id_int] = level_int & 0xF; + } else { + PR_BOOTMSG("_id[%s] has err enable[%s] (enable/disable)\n", _id, _enable); + _clear_wsct_high_priority_enable(); + return -EINVAL; + } + + } else { + PR_BOOTMSG("id[%d] exceed the range, it must be 0~%d\n",id_int, WSCT_AMOUNT-1); + _clear_wsct_high_priority_enable(); + return -EINVAL; + } + } +#ifdef FILE_NODE_DBG + PR_BOOTMSG("input data [%s]\n",wsct_high_priority_enable); + int i; + PR_BOOTMSG("wsct_high_priority_enable save data\n"); + for (i=0;i= 0 && id_int < WSCT_AMOUNT) { + wsct_busid_val[id_int] = busid_int; + wsct_idMask_val[id_int] = idMask_int; + + } else { + PR_BOOTMSG("id[%d] exceed the range, it must be 0~%d\n",id_int, WSCT_AMOUNT-1); + _clear_wsct_busid(); + return -EINVAL; + } + } +#ifdef FILE_NODE_DBG + PR_BOOTMSG("input data [%s]\n",wsct_busid); + int i; + PR_BOOTMSG("wsct_busid save data\n"); + for (i=0;i= 0 && id_int < WSCT_AMOUNT) { + wsct_chn_rank_sel_val[id_int] = chn_rank_int; + + } else { + PR_BOOTMSG("id[%d] exceed the range, it must be 0~%d\n",id_int, WSCT_AMOUNT-1); + _clear_wsct_chn_rank_sel(); + return -EINVAL; + } + } + +#ifdef FILE_NODE_DBG + PR_BOOTMSG("wsct_chn_rank_sel input data [%s]\n",wsct_chn_rank_sel); + int i; + PR_BOOTMSG("wsct_chn_rank_sel_val save data\n"); + for (i=0;i= 0 && id_int < WSCT_AMOUNT) { + wsct_byte_low_bnd_val[id_int] = low_bnd_int; + wsct_byte_up_bnd_val[id_int] = up_bnd_int; + wsct_byte_bnd_dis[id_int] = 0; + } else { + PR_BOOTMSG("id[%d] exceed the range, it must be 0~%d\n",id_int, WSCT_AMOUNT-1); + _clear_wsct_burst_range(); + return -EINVAL; + } + } + +#ifdef FILE_NODE_DBG + PR_BOOTMSG("wsct_burst_range_store input data [%s]\n",wsct_burst_range); + int i; + PR_BOOTMSG("wsct_burst_range save data\n"); + for (i=0;i= 0 && id_int < TSCT_AMOUNT) { + if ( 0 == strncmp("disable", _enable, 7)) { + tsct_busid_enable_val[id_int] = 0; + } else if ( 0 == strncmp("enable", _enable, 6)) { + tsct_busid_enable_val[id_int] = 1; + } else { + PR_BOOTMSG("_id[%s] has err enable[%s] (enable/disable)\n", _id, _enable); + _clear_tsct_busid_enable(); + return -EINVAL; + } + + } else { + PR_BOOTMSG("id[%d] exceed the range, it must be 0~%d\n",id_int, TSCT_AMOUNT-1); + _clear_tsct_busid_enable(); + return -EINVAL; + } + } +#ifdef FILE_NODE_DBG + PR_BOOTMSG("tsct_busid_enable input data [%s]\n",tsct_busid_enable); + int i; + PR_BOOTMSG("wsct_high_priority_enable save data\n"); + for (i=0;i= 0 && id_int < BM_COUNTER_MAX) { + if ( 0 == strncmp("disable", _enable, 7)) { + + high_priority_filter = ( high_priority_filter & ~(1<>i & 0x1, TTYPE_HPRI_SEL[i]); + } +#endif + return n; +} + +ssize_t ttype_high_priority_ext_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + ssize_t ret = 0; + int i; + + for (i=0;i>i & 0x1, TTYPE_HPRI_SEL[i]); + } + return strlen(buf); +} + +void _clear_ttype_busid_ext(void) { + int i; + + for (i=0;i= 0 && id_int < BM_COUNTER_MAX) { + ttype_busid_val[id_int] = busid_int; + ttype_idMask_val[id_int] = idMask_int; + + } else { + PR_BOOTMSG("ttype_busid_ext id[%d] exceed the range, it must be 1~%d\n",id_int+1, BM_COUNTER_MAX); + _clear_ttype_busid_ext(); + return -EINVAL; + } + } +#ifdef FILE_NODE_DBG + PR_BOOTMSG("ttype_busid_ext input data [%s]\n",ttype_busid_ext); + + int i; + PR_BOOTMSG("ttype_busid_ext save data\n"); + for (i=0;i= 0 && id_int < BM_COUNTER_MAX) { + ttype_chn_rank_sel[id_int] = chn_rank_int; + + } else { + PR_BOOTMSG("id[%d] exceed the range, it must be 1~%d\n",id_int+1, BM_COUNTER_MAX); + _clear_ttype_chn_rank_sel(); + return -EINVAL; + } + } + +#ifdef FILE_NODE_DBG + PR_BOOTMSG("ttype_chn_rank_sel input data [%s]\n",ttype_chn_rank_sel); + + int i; + PR_BOOTMSG("wsct_chn_rank_sel_val save data\n"); + for (i=0;i= 0 && id_int < BM_COUNTER_MAX) { + ttype_byte_low_bnd_val[id_int] = low_bnd_int; + ttype_byte_up_bnd_val[id_int] = up_bnd_int; + ttype_byte_bnd_dis[id_int] = 0; + } else { + PR_BOOTMSG("id[%d] exceed the range, it must be 1~%d\n",id_int, BM_COUNTER_MAX); + _clear_ttype_burst_range(); + return -EINVAL; + } + } + +#ifdef FILE_NODE_DBG + PR_BOOTMSG("ttype_burst_range_store input data [%s]\n",ttype_burst_range); + + int i; + PR_BOOTMSG("ttype_burst_range save data\n"); + for (i=0;i= 0 && id_int < MET_MAX_DRAM_CH_NUM) { + if (kstrtouint(_master_group, 0, &wmask_msel_val[id_int]) != 0) { + PR_BOOTMSG("master_group[%s] trans to hex err\n",_master_group); + _clear_wmask_msel(); + return -EINVAL; + } + } else { + PR_BOOTMSG("wmask_msel id[%d] exceed the range, it must be 0~%d\n",id_int, MET_MAX_DRAM_CH_NUM-1); + _clear_wmask_msel(); + return -EINVAL; + } + } +#ifdef FILE_NODE_DBG + PR_BOOTMSG("input data [%s]\n",wmask_msel); + /*PR_BOOTMSG("msel_group_ext_store size para n[%d]\n",n);*/ + int i; + PR_BOOTMSG("save data\n"); + for (i=0;i= 0 && id_int < MET_MAX_DRAM_CH_NUM) { + if (kstrtouint(_master_group, 0, &ageexp_msel_val[id_int]) != 0) { + PR_BOOTMSG("ageexp_msel_rw master_group[%s] trans to hex err\n",_master_group); + _clear_ageexp_msel_rw(); + return -EINVAL; + } + + if ( 0 == strncmp("NONE",_rw_type,4)) + ageexp_rw_val[id_int] = BM_WSCT_RW_DISABLE; + else if (0 == strncmp("R",_rw_type,4)) + ageexp_rw_val[id_int] = BM_WSCT_RW_READONLY; + else if (0 == strncmp("W",_rw_type,4)) + ageexp_rw_val[id_int] = BM_WSCT_RW_WRITEONLY; + else if (0 == strncmp("RW",_rw_type,4)) + ageexp_rw_val[id_int] = BM_WSCT_RW_RWBOTH; + else { + PR_BOOTMSG("ageexp_msel_rw _id[%s] has err rwtype[%s]\n", _id, _rw_type); + _clear_ageexp_msel_rw(); + return -EINVAL; + } + } else { + PR_BOOTMSG("ageexp_msel_rw id[%d] exceed the range, it must be 0~%d\n",id_int, MET_MAX_DRAM_CH_NUM-1); + _clear_ageexp_msel_rw(); + return -EINVAL; + } + } +#ifdef FILE_NODE_DBG + PR_BOOTMSG("input data [%s]\n",ageexp_msel_rw); + /*PR_BOOTMSG("msel_group_ext_store size para n[%d]\n",n);*/ + int i; + PR_BOOTMSG("save data\n"); + for (i=0;i 0xff_ff */ + ttype_rw_val[i] = BM_TRANS_RW_DEFAULT; + } + emi_tsct_enable = 0; + emi_mdct_enable = 0; + metemi_func_opt = 0xf00e; + rd_mdmcu_rsv_num = 0; + mdmcu_sel_enable = 0; + +} + +ssize_t clear_setting_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t n) +{ + int value; + + if ((n == 0) || (buf == NULL)) + return -EINVAL; + + if (kstrtoint(buf, 0, &value) != 0) + return -EINVAL; + + if (value == 1) + _clear_setting(); + + return n; +} + + + +struct kobj_attribute clear_setting_attr = __ATTR_WO(clear_setting); // OK +struct kobj_attribute msel_group_ext_attr = __ATTR(msel_group_ext, 0664, msel_group_ext_show, msel_group_ext_store); //OK +struct kobj_attribute wsct_rw_attr = __ATTR(wsct_rw, 0664, wsct_rw_show, wsct_rw_store); +struct kobj_attribute wsct_high_priority_enable_attr = __ATTR(wsct_high_priority_enable, 0664, wsct_high_priority_enable_show, wsct_high_priority_enable_store); +struct kobj_attribute wsct_busid_attr = __ATTR(wsct_busid, 0664, wsct_busid_show, wsct_busid_store); +struct kobj_attribute wsct_chn_rank_sel_attr = __ATTR(wsct_chn_rank_sel, 0664, wsct_chn_rank_sel_show, wsct_chn_rank_sel_store); +struct kobj_attribute wsct_burst_range_attr = __ATTR(wsct_burst_range, 0664, wsct_burst_range_show, wsct_burst_range_store); +struct kobj_attribute tsct_busid_enable_attr = __ATTR(tsct_busid_enable, 0664, tsct_busid_enable_show, tsct_busid_enable_store); +struct kobj_attribute ttype_high_priority_ext_attr = __ATTR(ttype_high_priority_ext, 0664, ttype_high_priority_ext_show, ttype_high_priority_ext_store); +struct kobj_attribute ttype_busid_ext_attr = __ATTR(ttype_busid_ext, 0664, ttype_busid_ext_show, ttype_busid_ext_store); +struct kobj_attribute ttype_chn_rank_sel_attr = __ATTR(ttype_chn_rank_sel, 0664, ttype_chn_rank_sel_show, ttype_chn_rank_sel_store); +struct kobj_attribute ttype_burst_range_attr = __ATTR(ttype_burst_range, 0664, ttype_burst_range_show, ttype_burst_range_store); + +struct kobj_attribute wmask_msel_attr = __ATTR(wmask_msel, 0664, wmask_msel_show, wmask_msel_store); +struct kobj_attribute ageexp_msel_rw_attr = __ATTR(ageexp_msel_rw, 0664, ageexp_msel_rw_show, ageexp_msel_rw_store); +struct kobj_attribute default_val_attr = __ATTR(default_val, 0664, default_val_show, default_val_store); //OK +DECLARE_KOBJ_ATTR_RO(sspm_support_feature); + +void emi_init(void) +{ + unsigned int bmrw0_val, bmrw1_val, i; + /*unsigned int msel_group_val[4];*/ + + /*save origianl EMI config*/ + MET_BM_SaveCfg(); + + /* get dram channel number */ + dram_chann_num = MET_EMI_GetDramChannNum(); + + /* Init. EMI bus monitor */ + MET_BM_SetReadWriteType(rwtype); + + /*handle the ori */ + + if (ttype1_16_en != BM_TTYPE1_16_ENABLE) { + MET_BM_SetLatencyCounter(1); /*enable latency count*/ + } + else { + MET_BM_SetLatencyCounter(0); /*disable latency count*/ + + for (i = 1; i <= 16; i++) { + MET_BM_SetMonitorCounter(i, + ttype_master_val[i - 1], + ttype_nbeat_val[i - 1] | + ttype_nbyte_val[i - 1] | + ttype_burst_val[i - 1]); + } + } + + if (ttype17_21_en == BM_TTYPE17_21_ENABLE) { + for (i = 17; i <= 21; i++) { + MET_BM_SetMonitorCounter(i, + ttype_master_val[i - 1], + ttype_nbeat_val[i - 1] | + ttype_nbyte_val[i - 1] | + ttype_burst_val[i - 1]); + } + } + + PR_BOOTMSG("[%s]reserve_wsct_setting=%d\n",__func__,reserve_wsct_setting); + + if (reserve_wsct_setting == 0) { + /* wsct 0 : total-all*/ + msel_group_ext_val[0] = BM_MASTER_ALL; + wsct_rw_val[0] = BM_WSCT_RW_RWBOTH; + WSCT_HPRI_DIS[0] = 1; + WSCT_HPRI_SEL[0] = 0xF; + wsct_busid_val[0] = 0xFFFFF; + wsct_idMask_val[0] = 0xFFFF; + wsct_chn_rank_sel_val[0] = 0xF; + wsct_byte_bnd_dis[0] = 1; + + /* wsct 4 : total-ultra*/ + msel_group_ext_val[4] = BM_MASTER_ALL; + wsct_rw_val[4] = BM_WSCT_RW_RWBOTH; + WSCT_HPRI_DIS[4] = 0; + WSCT_HPRI_SEL[4] = 0x8; /* ultra */ + wsct_busid_val[4] = 0xFFFFF; + wsct_idMask_val[4] = 0xFFFF; + wsct_chn_rank_sel_val[4] = 0xF; + wsct_byte_bnd_dis[4] = 1; + + /* wsct 5 : total-pre_ultra*/ + msel_group_ext_val[5] = BM_MASTER_ALL; + wsct_rw_val[5] = BM_WSCT_RW_RWBOTH; + WSCT_HPRI_DIS[5] = 0; + WSCT_HPRI_SEL[5] = 0x4; /* pre_ultra */ + wsct_busid_val[5] = 0xFFFFF; + wsct_idMask_val[5] = 0xFFFF; + wsct_chn_rank_sel_val[5] = 0xF; + wsct_byte_bnd_dis[5] = 1; + } + + if (msel_enable) { + /* if old file node set, use the value */ + if ( msel_group1 != BM_MASTER_ALL ) + msel_group_ext_val[1] = msel_group1; + + if ( msel_group2 != BM_MASTER_ALL ) + msel_group_ext_val[2] = msel_group2; + + if ( msel_group3 != BM_MASTER_ALL ) + msel_group_ext_val[3] = msel_group3; + + } else { + for ( i=1; i<=3; i++) { + msel_group_ext_val[i] = BM_MASTER_ALL; + } + } + + MET_BM_SetWSCT_master_rw(msel_group_ext_val, wsct_rw_val); + MET_BM_SetWSCT_high_priority(WSCT_HPRI_DIS, WSCT_HPRI_SEL); + MET_BM_SetWSCT_busid_idmask(wsct_busid_val, wsct_idMask_val); + MET_BM_SetWSCT_chn_rank_sel(wsct_chn_rank_sel_val); + MET_BM_SetWSCT_burst_range(wsct_byte_bnd_dis, wsct_byte_low_bnd_val, wsct_byte_up_bnd_val); + MET_BM_SetTSCT_busid_enable(tsct_busid_enable_val); + + MET_BM_SetTtype_high_priority_sel(high_priority_filter, TTYPE_HPRI_SEL); + MET_BM_SetTtype_busid_idmask(ttype_busid_val, ttype_idMask_val, ttype1_16_en, ttype17_21_en); + MET_BM_SetTtype_chn_rank_sel(ttype_chn_rank_sel_val); + MET_BM_SetTtype_burst_range(ttype_byte_bnd_dis, ttype_byte_low_bnd_val, ttype_byte_up_bnd_val); + +#ifdef EMI_LOWEFF_SUPPORT + /* + for (i=0; i= 2 ) { + ret += snprintf(buf + ret, buf_len - ret, + "met-info [000] 0.0: met_dramc_header: "); + for (i = 0; i < dram_chann_num; i++) { + if (i != 0) + ret += snprintf(buf + ret, buf_len - ret, + ","); + ret += snprintf(buf + ret, buf_len - ret, "freerun_26m_%d,", i); + ret += snprintf(buf + ret, buf_len - ret, + "rk0_pre_sb_%d,rk0_pre_pd_%d,rk0_act_sb_%d,rk0_act_pd_%d,", i, i, i, i); + ret += snprintf(buf + ret, buf_len - ret, + "rk1_pre_sb_%d,rk1_pre_pd_%d,rk1_act_sb_%d,rk1_act_pd_%d,", i, i, i, i); + ret += snprintf(buf + ret, buf_len - ret, + "rk2_pre_sb_%d,rk2_pre_pd_%d,rk2_act_sb_%d,rk2_act_pd_%d", i, i, i, i); + } + ret += snprintf(buf + ret, buf_len - ret, "\n"); + } + + /* DRS header */ + ret += snprintf(buf + ret, buf_len - ret, + "met-info [000] 0.0: emi_drs_header: ch0_RANK1_GP(%%),ch0_RANK1_SF(%%),ch0_ALL_SF(%%),ch1_RANK1_GP(%%),ch1_RANK1_SF(%%),ch1_ALL_SF(%%)\n"); +#endif + +#ifdef EMI_LOWEFF_SUPPORT + ret += snprintf(buf + ret, buf_len - ret, "met-info [000] 0.0: chn_emi_loweff_ctl0: "); + /* + for (i = 0; i < dram_chann_num && imode; +} + +void met_emi_delete_basic(void) +{ +#define KOBJ_ATTR_ITEM(attr_name) \ + sysfs_remove_file(kobj_emi, &attr_name##_attr.attr) + if (kobj_emi != NULL) { + KOBJ_ATTR_LIST; + kobj_emi = NULL; + } +#undef KOBJ_ATTR_ITEM + + if (emi_inited) + MET_BM_DeInit(); + + emi_device = NULL; +} + +void met_emi_resume_basic(void) +{ + if (!do_emi()) + return; + + emi_init(); +} + +int emi_print_header_basic(char *buf, int len) +{ + if( (strlen(header_str) - output_str_len) > PAGE_SIZE ){ + char output_buf[PAGE_SIZE/4]; + + strncpy(output_buf, header_str+output_str_len, (PAGE_SIZE/4) -1); + output_buf[(PAGE_SIZE/4) - 1] = '\0'; + + len = snprintf(buf, PAGE_SIZE, "%s", output_buf); + if (len > 0) + output_str_len += len; + emi_device->header_read_again = 1; + + PR_BOOTMSG("EMI header read again!\n"); + } + else{ + len = snprintf(buf, PAGE_SIZE, "%s\n", header_str+output_str_len); + if (len < 0) return -1; + + /* reset state */ + emi_device->header_read_again = 0; + output_header_len = 0; + output_str_len = 0; + } + return len; +} + +#if IS_ENABLED(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) +#if defined(ONDIEMET_SUPPORT) || defined(TINYSYS_SSPM_SUPPORT) +void ondiemet_emi_start_basic(void) +{ + int ret; + + emi_use_ondiemet = 1; + + MET_BM_IPI_REGISTER_CB(); + if (!emi_inited) { + if (MET_BM_Init() != 0) { + emi_device->mode = 0; + pr_notice("MET_BM_Init failed!!!\n"); + return; + } + emi_inited = 1; + } + MET_BM_IPI_configs(); + + if (do_emi()) + emi_init(); + + ondiemet_module[ONDIEMET_SSPM] |= ID_EMI; + ret = emi_create_header(header_str, MAX_HEADER_LEN); + + emi_device->header_read_again = 0; + output_header_len = 0; + output_str_len = 0; +} + +void ondiemet_emi_stop_basic(void) +{ + if (!emi_inited) + return; + + if (do_emi()) + emi_uninit(); +} +#endif +#endif + +/*para*/ +EXPORT_SYMBOL(emi_inited); +EXPORT_SYMBOL(output_str_len); +EXPORT_SYMBOL(dramc_pdir_enable); +EXPORT_SYMBOL(kobj_emi); +EXPORT_SYMBOL(emi_mdct_enable); +EXPORT_SYMBOL(rd_mdmcu_rsv_num); +EXPORT_SYMBOL(met_emi_regdump); +EXPORT_SYMBOL(output_header_len); +EXPORT_SYMBOL(BaseAddrEMI); +EXPORT_SYMBOL(BaseAddrCHN_EMI); +EXPORT_SYMBOL(header_str); +EXPORT_SYMBOL(ttype1_16_en); +EXPORT_SYMBOL(ttype17_21_en); +EXPORT_SYMBOL(emi_tsct_enable); +EXPORT_SYMBOL(emi_use_ondiemet); +EXPORT_SYMBOL(dram_chann_num); +EXPORT_SYMBOL(metemi_func_opt); +EXPORT_SYMBOL(mdmcu_sel_enable); + + + +/*func*/ +EXPORT_SYMBOL(emi_init); +#if IS_ENABLED(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) +#if defined(ONDIEMET_SUPPORT) || defined(TINYSYS_SSPM_SUPPORT) +EXPORT_SYMBOL(ondiemet_emi_start_basic); +#endif +#endif +EXPORT_SYMBOL(do_emi); +EXPORT_SYMBOL(emi_create_header); +EXPORT_SYMBOL(MET_EMI_Get_BaseClock_Rate); +EXPORT_SYMBOL(emi_uninit); +EXPORT_SYMBOL(met_emi_create_basic); +EXPORT_SYMBOL(met_emi_delete_basic); +EXPORT_SYMBOL(emi_print_header_basic); +EXPORT_SYMBOL(MET_EMI_GetDramChannNum); +EXPORT_SYMBOL(MET_BM_Init); +EXPORT_SYMBOL(check_sspm_support); +EXPORT_SYMBOL(met_get_dram_data_rate); diff --git a/drivers/misc/mediatek/met_drv_v2/common/emi/SEDA3_5/mtk_emi_bm.h b/drivers/misc/mediatek/met_drv_v2/common/emi/SEDA3_5/mtk_emi_bm.h new file mode 100644 index 0000000000000000000000000000000000000000..73744f3153f6e8a7741d2ce65111985f026d525e --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/emi/SEDA3_5/mtk_emi_bm.h @@ -0,0 +1,911 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2019 MediaTek Inc. + * + */ + +#ifndef __MT_MET_EMI_BM_BASIC_H__ +#define __MT_MET_EMI_BM_BASIC_H__ + +#if IS_ENABLED(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) +#if defined(ONDIEMET_SUPPORT) +#include "sspm/ondiemet_sspm.h" +#elif defined(TINYSYS_SSPM_SUPPORT) +#include "tinysys_sspm.h" +#include "tinysys_mgr.h" /* for ondiemet_module */ +#include "sspm_met_ipi_handle.h" +#endif +#endif + + +/*define MARGAUX*/ + +#define EMI_VER_MAJOR 3 +#define EMI_VER_MINOR 5 + +#define MET_MAX_DRAM_CH_NUM 4 + +#define FILE_NODE_DATA_LEN 512 +#define WSCT_AMOUNT 6 +#define TSCT_AMOUNT 3 + + +#define DRAM_EMI_BASECLOCK_RATE_LP4 4 +#define DRAM_EMI_BASECLOCK_RATE_LP3 2 + +#define DRAM_IO_BUS_WIDTH_LP4 16 +#define DRAM_IO_BUS_WIDTH_LP3 32 + +#define DRAM_DATARATE 2 + +#define DRAM_FREQ_DEFAULT 3733 +#define DDR_RATIO_DEFAULT 8 +#define DRAM_TYPE_DEFAULT 3 + +#define ADDR_EMI ((unsigned long)BaseAddrEMI) + +#define MASK_MASTER 0xFF +#define MASK_TRANS_TYPE 0xFF + +#define BM_MASTER_M0 (0x01) +#define BM_MASTER_M1 (0x02) +#define BM_MASTER_M2 (0x04) +#define BM_MASTER_M3 (0x08) +#define BM_MASTER_M4 (0x10) +#define BM_MASTER_M5 (0x20) +#define BM_MASTER_M6 (0x40) +#define BM_MASTER_M7 (0x80) +#define BM_MASTER_ALL (0xFF) + + +enum BM_RW_Type { + BM_BOTH_READ_WRITE, + BM_READ_ONLY, + BM_WRITE_ONLY +}; + +enum { + BM_TRANS_TYPE_1BEAT = 0x0, + BM_TRANS_TYPE_2BEAT, + BM_TRANS_TYPE_3BEAT, + BM_TRANS_TYPE_4BEAT, + BM_TRANS_TYPE_5BEAT, + BM_TRANS_TYPE_6BEAT, + BM_TRANS_TYPE_7BEAT, + BM_TRANS_TYPE_8BEAT, + BM_TRANS_TYPE_9BEAT, + BM_TRANS_TYPE_10BEAT, + BM_TRANS_TYPE_11BEAT, + BM_TRANS_TYPE_12BEAT, + BM_TRANS_TYPE_13BEAT, + BM_TRANS_TYPE_14BEAT, + BM_TRANS_TYPE_15BEAT, + BM_TRANS_TYPE_16BEAT, + BM_TRANS_TYPE_1Byte = 0 << 4, + BM_TRANS_TYPE_2Byte = 1 << 4, + BM_TRANS_TYPE_4Byte = 2 << 4, + BM_TRANS_TYPE_8Byte = 3 << 4, + BM_TRANS_TYPE_16Byte = 4 << 4, + BM_TRANS_TYPE_32Byte = 5 << 4, + BM_TRANS_TYPE_BURST_WRAP = 0 << 7, + BM_TRANS_TYPE_BURST_INCR = 1 << 7 +}; + +enum { + BM_TRANS_RW_DEFAULT = 0x0, + BM_TRANS_RW_READONLY, + BM_TRANS_RW_WRITEONLY, + BM_TRANS_RW_RWBOTH +}; + +enum { + BM_WSCT_RW_DISABLE = 0x0, + BM_WSCT_RW_READONLY, + BM_WSCT_RW_WRITEONLY, + BM_WSCT_RW_RWBOTH +}; + +/*coda busid 12bit, but HW support 16 bit*/ +#define EMI_BMID_MASK (0xFFFF) +#define BM_COUNTER_MAX (21) + +enum { + BUS_MON_EN_SHIFT = 0, + BUS_MON_PAUSE_SHIFT = 1, + BUS_MON_IDLE_SHIFT = 3, + BC_OVERRUN_SHIFT = 8, + DRAMC_CG_SHIFT = 9, +}; + +#define BM_REQ_OK (0) +#define BM_ERR_WRONG_REQ (-1) +#define BM_ERR_OVERRUN (-2) + +#define BM_WSCT_TSCT_IDSEL_ENABLE (0) +#define BM_WSCT_TSCT_IDSEL_DISABLE (-1) +#define BM_TTYPE1_16_ENABLE (0) +#define BM_TTYPE1_16_DISABLE (-1) +#define BM_TTYPE17_21_ENABLE (0) +#define BM_TTYPE17_21_DISABLE (-1) +#define BM_BW_LIMITER_ENABLE (0) +#define BM_BW_LIMITER_DISABLE (-1) + +#define M0_DOUBLE_HALF_BW_1CH (0x0) +#define M0_DOUBLE_HALF_BW_2CH (0x1) +#define M0_DOUBLE_HALF_BW_4CH (0x2) + +/* EMI Rank configuration */ +enum { + DISABLE_DUAL_RANK_MODE = 0, + ENABLE_DUAL_RANK_MODE, +}; + +#define RANK_MASK 0x1 +#define ONE_RANK 1 +#define DUAL_RANK 2 + + +#if IS_ENABLED(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) +#if defined(ONDIEMET_SUPPORT) || defined(TINYSYS_SSPM_SUPPORT) +enum BM_EMI_IPI_Type { + SET_BASE_EMI = 0x0, + SET_EBM_CONFIGS1 = 0x7, + SET_EBM_CONFIGS2 = 0x8, + SET_REGISTER_CB = 0x9, +}; +#endif +#endif + + +#define EMI_OFF 0x0000 +#define EMI_CONA (0x000-EMI_OFF) +#define EMI_CONH (0x038-EMI_OFF) +#define EMI_CONH_2ND (0x03C-EMI_OFF) +#define EMI_CONM (0x060-EMI_OFF) +#define EMI_CONO (0x070-EMI_OFF) + +#define EMI_MDCT (0x078 - EMI_OFF) +#define EMI_MDCT_2ND (0x07C - EMI_OFF) + +#define EMI_ARBA (0x100 - EMI_OFF) +#define EMI_ARBB (0x108 - EMI_OFF) +#define EMI_ARBC (0x110 - EMI_OFF) +#define EMI_ARBD (0x118 - EMI_OFF) +#define EMI_ARBE (0x120 - EMI_OFF) +#define EMI_ARBF (0x128 - EMI_OFF) +#define EMI_ARBG (0x130 - EMI_OFF) +#define EMI_ARBG_2ND (0x134 - EMI_OFF) +#define EMI_ARBH (0x138 - EMI_OFF) + + +#define EMI_BMEN (0x400-EMI_OFF) +#define EMI_MSEL (0x440 - EMI_OFF) +#define EMI_MSEL2 (0x468 - EMI_OFF) +#define EMI_MSEL3 (0x470 - EMI_OFF) +#define EMI_MSEL4 (0x478 - EMI_OFF) +#define EMI_MSEL5 (0x480 - EMI_OFF) +#define EMI_MSEL6 (0x488 - EMI_OFF) +#define EMI_MSEL7 (0x490 - EMI_OFF) +#define EMI_MSEL8 (0x498 - EMI_OFF) +#define EMI_MSEL9 (0x4A0 - EMI_OFF) +#define EMI_MSEL10 (0x4A8 - EMI_OFF) + +#define EMI_BMID0 (0x4B0 - EMI_OFF) +#define EMI_BMID1 (0x4B4 - EMI_OFF) +#define EMI_BMID2 (0x4B8 - EMI_OFF) +#define EMI_BMID3 (0x4BC - EMI_OFF) +#define EMI_BMID4 (0x4C0 - EMI_OFF) +#define EMI_BMID5 (0x4C4 - EMI_OFF) +#define EMI_BMID6 (0x4C8 - EMI_OFF) +#define EMI_BMID7 (0x4CC - EMI_OFF) +#define EMI_BMID8 (0x4D0 - EMI_OFF) +#define EMI_BMID9 (0x4D4 - EMI_OFF) +#define EMI_BMID10 (0x4D8 - EMI_OFF) + +#define EMI_BMEN1 (0x4E0 - EMI_OFF) +#define EMI_BMEN2 (0x4E8 - EMI_OFF) +#define EMI_BMRW0 (0x4F8 - EMI_OFF) +#define EMI_BMRW1 (0x4FC - EMI_OFF) + + +/* SEDA 3.5 New! reg*/ +/* For WSCT setting*/ +#define EMI_DBWA (0xF00 - EMI_OFF) +#define EMI_DBWB (0xF04 - EMI_OFF) +#define EMI_DBWC (0xF08 - EMI_OFF) +#define EMI_DBWD (0xF0C - EMI_OFF) +#define EMI_DBWE (0xF10 - EMI_OFF) +#define EMI_DBWF (0xF14 - EMI_OFF) + + +#define EMI_DBWA_2ND (0xF2C - EMI_OFF) +#define EMI_DBWB_2ND (0xF30 - EMI_OFF) +#define EMI_DBWC_2ND (0xF34 - EMI_OFF) +#define EMI_DBWD_2ND (0xF38 - EMI_OFF) +#define EMI_DBWE_2ND (0xF3C - EMI_OFF) +#define EMI_DBWF_2ND (0xF40 - EMI_OFF) + +#define EMI_DBWI (0xF20 - EMI_OFF) /* SEL_ID_MSK*/ +#define EMI_DBWJ (0xF24 - EMI_OFF) +#define EMI_DBWK (0xF28 - EMI_OFF) + +/* For Ttype setting */ +#define EMI_TTYPE1_CONA (0xF50 - EMI_OFF) +#define EMI_TTYPE1_CONB (0xF54 - EMI_OFF) +#define EMI_TTYPE2_CONA (0xF58 - EMI_OFF) +#define EMI_TTYPE2_CONB (0xF5C - EMI_OFF) +#define EMI_TTYPE3_CONA (0xF60 - EMI_OFF) +#define EMI_TTYPE3_CONB (0xF64 - EMI_OFF) +#define EMI_TTYPE4_CONA (0xF68 - EMI_OFF) +#define EMI_TTYPE4_CONB (0xF6C - EMI_OFF) +#define EMI_TTYPE5_CONA (0xF70 - EMI_OFF) +#define EMI_TTYPE5_CONB (0xF74 - EMI_OFF) +#define EMI_TTYPE6_CONA (0xF78 - EMI_OFF) +#define EMI_TTYPE6_CONB (0xF7C - EMI_OFF) +#define EMI_TTYPE7_CONA (0xF80 - EMI_OFF) +#define EMI_TTYPE7_CONB (0xF84 - EMI_OFF) +#define EMI_TTYPE8_CONA (0xF88 - EMI_OFF) +#define EMI_TTYPE8_CONB (0xF8C - EMI_OFF) +#define EMI_TTYPE9_CONA (0xF90 - EMI_OFF) +#define EMI_TTYPE9_CONB (0xF94 - EMI_OFF) +#define EMI_TTYPE10_CONA (0xF98 - EMI_OFF) +#define EMI_TTYPE10_CONB (0xF9C - EMI_OFF) +#define EMI_TTYPE11_CONA (0xFA0 - EMI_OFF) +#define EMI_TTYPE11_CONB (0xFA4 - EMI_OFF) +#define EMI_TTYPE12_CONA (0xFA8 - EMI_OFF) +#define EMI_TTYPE12_CONB (0xFAC - EMI_OFF) +#define EMI_TTYPE13_CONA (0xFB0 - EMI_OFF) +#define EMI_TTYPE13_CONB (0xFB4 - EMI_OFF) +#define EMI_TTYPE14_CONA (0xFB8 - EMI_OFF) +#define EMI_TTYPE14_CONB (0xFBC - EMI_OFF) +#define EMI_TTYPE15_CONA (0xFC0 - EMI_OFF) +#define EMI_TTYPE15_CONB (0xFC4 - EMI_OFF) +#define EMI_TTYPE16_CONA (0xFC8 - EMI_OFF) +#define EMI_TTYPE16_CONB (0xFCC - EMI_OFF) +#define EMI_TTYPE17_CONA (0xFD0 - EMI_OFF) +#define EMI_TTYPE17_CONB (0xFD4 - EMI_OFF) +#define EMI_TTYPE18_CONA (0xFD8 - EMI_OFF) +#define EMI_TTYPE18_CONB (0xFDC - EMI_OFF) +#define EMI_TTYPE19_CONA (0xFE0 - EMI_OFF) +#define EMI_TTYPE19_CONB (0xFE4 - EMI_OFF) +#define EMI_TTYPE20_CONA (0xFE8 - EMI_OFF) +#define EMI_TTYPE20_CONB (0xFEC - EMI_OFF) +#define EMI_TTYPE21_CONA (0xFF0 - EMI_OFF) +#define EMI_TTYPE21_CONB (0xFF4 - EMI_OFF) + +/* low effeciency */ +#define CHN_EMI_LOWEFF_CTL0 (0x500) +// #define WMASK_PID_OFFSET +// #define AGEXP_PID_OFFSET + + +/* met_drv define & global var */ +#define CNT_COUNTDOWN (0) + +/* extern struct metdevice met_sspm_emi; */ + +extern int emi_tsct_enable; +extern int emi_mdct_enable; +extern int emi_TP_busfiltr_enable; +extern int mdmcu_sel_enable; +extern unsigned int rd_mdmcu_rsv_num; +extern int metemi_func_opt; + +extern int met_emi_regdump; + +extern int msel_enable; +extern unsigned int msel_group1; +extern unsigned int msel_group2; +extern unsigned int msel_group3; + +extern struct kobject *kobj_emi; +extern int rwtype; + + /* 1ms */ +extern int bw_limiter_enable; + +extern int ttype1_16_en; +extern int ttype17_21_en; + +extern int dramc_pdir_enable; +extern int dram_chann_num; + +extern int high_priority_filter; + +extern int ttype_master_val[21]; +extern int ttype_busid_val[21]; +extern int ttype_nbeat_val[21]; +extern int ttype_nbyte_val[21]; +extern int ttype_burst_val[21]; +extern int ttype_rw_val[21]; + +extern unsigned int msel_group_ext_val[WSCT_AMOUNT]; +extern unsigned int wsct_rw_val[WSCT_AMOUNT]; +extern char* const delim_comma; +extern char* const delim_coclon; + +extern char msel_group_ext[FILE_NODE_DATA_LEN]; + +extern unsigned int WSCT_HPRI_DIS[WSCT_AMOUNT]; +extern unsigned int WSCT_HPRI_SEL[WSCT_AMOUNT]; +extern char wsct_high_priority_enable[FILE_NODE_DATA_LEN]; + +/*wsct_busid*/ +extern unsigned int wsct_busid_val[WSCT_AMOUNT]; +extern unsigned int wsct_idMask_val[WSCT_AMOUNT]; +extern char wsct_busid[FILE_NODE_DATA_LEN]; + +/* wsct_chn_rank_sel */ +extern unsigned int wsct_chn_rank_sel_val[WSCT_AMOUNT]; +extern char wsct_chn_rank_sel[FILE_NODE_DATA_LEN]; + +/* wsct_burst_range */ +extern unsigned int wsct_byte_low_bnd_val[WSCT_AMOUNT]; +extern unsigned int wsct_byte_up_bnd_val[WSCT_AMOUNT]; +extern unsigned int wsct_byte_bnd_dis[WSCT_AMOUNT]; +extern char wsct_burst_range[FILE_NODE_DATA_LEN]; + +/* tsct_busid_enable */ +extern unsigned int tsct_busid_enable_val[TSCT_AMOUNT]; +extern char tsct_busid_enable[FILE_NODE_DATA_LEN]; +/* ttype_high_priority_ext */ +extern unsigned int TTYPE_HPRI_SEL[BM_COUNTER_MAX]; +extern char ttype_high_priority_ext[FILE_NODE_DATA_LEN]; +/* ttype_busid_ext */ +extern unsigned int ttype_idMask_val[BM_COUNTER_MAX]; +extern char ttype_busid_ext[FILE_NODE_DATA_LEN]; +/* ttype_chn_rank_sel */ +extern unsigned int ttype_chn_rank_sel_val[BM_COUNTER_MAX]; +extern char ttype_chn_rank_sel[FILE_NODE_DATA_LEN]; + +/* ttype_burst_range */ +extern unsigned int ttype_byte_low_bnd_val[BM_COUNTER_MAX]; +extern unsigned int ttype_byte_up_bnd_val[BM_COUNTER_MAX]; +extern unsigned int ttype_byte_bnd_dis[BM_COUNTER_MAX]; +extern char ttype_burst_range[FILE_NODE_DATA_LEN]; + + +extern unsigned int wmask_msel_val[MET_MAX_DRAM_CH_NUM]; +extern char wmask_msel[FILE_NODE_DATA_LEN]; + +extern unsigned int ageexp_msel_val[MET_MAX_DRAM_CH_NUM]; +extern unsigned int ageexp_rw_val[MET_MAX_DRAM_CH_NUM]; +extern char ageexp_msel_rw[FILE_NODE_DATA_LEN]; + +extern char default_val[FILE_NODE_DATA_LEN]; + +extern int reserve_wsct_setting; + +extern struct kobj_attribute clear_setting_attr; +extern struct kobj_attribute msel_group_ext_attr; +extern struct kobj_attribute wsct_rw_attr; +extern struct kobj_attribute wsct_high_priority_enable_attr; +extern struct kobj_attribute wsct_busid_attr; +extern struct kobj_attribute wsct_chn_rank_sel_attr; +extern struct kobj_attribute wsct_burst_range_attr; +extern struct kobj_attribute tsct_busid_enable_attr; +extern struct kobj_attribute ttype_high_priority_ext_attr; +extern struct kobj_attribute ttype_busid_ext_attr; +extern struct kobj_attribute ttype_chn_rank_sel_attr; +extern struct kobj_attribute ttype_burst_range_attr; + +/* for header print*/ +#define MAX_HEADER_LEN (1024 * 6) +extern char header_str[MAX_HEADER_LEN]; +extern unsigned int output_header_len; +extern unsigned int output_str_len; + +#define emi_help_msg " --emi monitor EMI banwidth\n" + +extern int emi_use_ondiemet; +extern int emi_inited; + +enum SSPM_Mode { + CUSTOMER_MODE = 0x0, + UNDEFINE_MODE = 0x1, + INTERNAL_MODE = 0X2780 +}; + + +/*======================================================================*/ +/* KOBJ Declarations */ +/*======================================================================*/ +DECLARE_KOBJ_ATTR_INT(emi_TP_busfiltr_enable, emi_TP_busfiltr_enable); +DECLARE_KOBJ_ATTR_INT(emi_regdump, met_emi_regdump); +DECLARE_KOBJ_ATTR_INT(msel_enable, msel_enable); +DECLARE_KOBJ_ATTR_HEX_CHECK(msel_group1, msel_group1, msel_group1 > 0 && msel_group1 <= BM_MASTER_ALL); +DECLARE_KOBJ_ATTR_HEX_CHECK(msel_group2, msel_group2, msel_group2 > 0 && msel_group2 <= BM_MASTER_ALL); +DECLARE_KOBJ_ATTR_HEX_CHECK(msel_group3, msel_group3, msel_group3 > 0 && msel_group3 <= BM_MASTER_ALL); + + +/* KOBJ: rwtype */ +DECLARE_KOBJ_ATTR_INT_CHECK(rwtype, rwtype, rwtype >= 0 && rwtype <= BM_WRITE_ONLY); + + +/* KOBJ: ttype1_16_en */ +DECLARE_KOBJ_ATTR_STR_LIST_ITEM( + ttype1_16_en, + KOBJ_ITEM_LIST( + { BM_TTYPE1_16_ENABLE, "ENABLE" }, + { BM_TTYPE1_16_DISABLE, "DISABLE" } + ) + ); +DECLARE_KOBJ_ATTR_STR_LIST(ttype1_16_en, ttype1_16_en, ttype1_16_en); + +/* KOBJ: ttype17_21_en */ +DECLARE_KOBJ_ATTR_STR_LIST_ITEM( + ttype17_21_en, + KOBJ_ITEM_LIST( + { BM_TTYPE17_21_ENABLE, "ENABLE" }, + { BM_TTYPE17_21_DISABLE, "DISABLE" } + ) + ); +DECLARE_KOBJ_ATTR_STR_LIST(ttype17_21_en, ttype17_21_en, ttype17_21_en); + +/* KOBJ: bw_limiter_enable */ +DECLARE_KOBJ_ATTR_STR_LIST_ITEM( + bw_limiter_enable, + KOBJ_ITEM_LIST( + { BM_BW_LIMITER_ENABLE, "ENABLE" }, + { BM_BW_LIMITER_DISABLE, "DISABLE" } + ) + ); + +DECLARE_KOBJ_ATTR_STR_LIST(bw_limiter_enable, bw_limiter_enable, bw_limiter_enable); + +/* KOBJ: ttype_master */ +DECLARE_KOBJ_ATTR_STR_LIST_ITEM( + ttype_master, + KOBJ_ITEM_LIST( + { BM_MASTER_M0, "M0" }, + { BM_MASTER_M1, "M1" }, + { BM_MASTER_M2, "M2" }, + { BM_MASTER_M3, "M3" }, + { BM_MASTER_M4, "M4" }, + { BM_MASTER_M5, "M5" }, + { BM_MASTER_M6, "M6" }, + { BM_MASTER_M7, "M7" } + ) + ); + + +/* KOBJ: ttypeX_nbeat, ttypeX_nbyte, ttypeX_burst */ +DECLARE_KOBJ_ATTR_INT_LIST_ITEM( + ttype_nbeat, + KOBJ_ITEM_LIST( + { BM_TRANS_TYPE_1BEAT, 1 }, + { BM_TRANS_TYPE_2BEAT, 2 }, + { BM_TRANS_TYPE_3BEAT, 3 }, + { BM_TRANS_TYPE_4BEAT, 4 }, + { BM_TRANS_TYPE_5BEAT, 5 }, + { BM_TRANS_TYPE_6BEAT, 6 }, + { BM_TRANS_TYPE_7BEAT, 7 }, + { BM_TRANS_TYPE_8BEAT, 8 }, + { BM_TRANS_TYPE_9BEAT, 9 }, + { BM_TRANS_TYPE_10BEAT, 10 }, + { BM_TRANS_TYPE_11BEAT, 11 }, + { BM_TRANS_TYPE_12BEAT, 12 }, + { BM_TRANS_TYPE_13BEAT, 13 }, + { BM_TRANS_TYPE_14BEAT, 14 }, + { BM_TRANS_TYPE_15BEAT, 15 }, + { BM_TRANS_TYPE_16BEAT, 16 } + ) + ); +DECLARE_KOBJ_ATTR_INT_LIST_ITEM( + ttype_nbyte, + KOBJ_ITEM_LIST( + { BM_TRANS_TYPE_1Byte, 1 }, + { BM_TRANS_TYPE_2Byte, 2 }, + { BM_TRANS_TYPE_4Byte, 4 }, + { BM_TRANS_TYPE_8Byte, 8 }, + { BM_TRANS_TYPE_16Byte, 16 }, + { BM_TRANS_TYPE_32Byte, 32 } + ) + ); +DECLARE_KOBJ_ATTR_STR_LIST_ITEM( + ttype_burst, + KOBJ_ITEM_LIST( + { BM_TRANS_TYPE_BURST_INCR, "INCR" }, + { BM_TRANS_TYPE_BURST_WRAP, "WRAP" } + ) + ); + +DECLARE_KOBJ_ATTR_STR_LIST_ITEM( + ttype_rw, + KOBJ_ITEM_LIST( + { BM_TRANS_RW_DEFAULT, "DEFAULT" }, + { BM_TRANS_RW_READONLY, "R" }, + { BM_TRANS_RW_WRITEONLY, "W" }, + { BM_TRANS_RW_RWBOTH, "BOTH" } + ) + ); + + +DECLARE_KOBJ_ATTR_INT(dramc_pdir_enable, dramc_pdir_enable); + +DECLARE_KOBJ_ATTR_HEX(high_priority_filter, high_priority_filter); + +#define DECLARE_KOBJ_TTYPE_MASTER(nr) \ + DECLARE_KOBJ_ATTR_STR_LIST(ttype ## nr ## _master, ttype_master_val[nr - 1], ttype_master) + +#define DECLARE_KOBJ_TTYPE_NBEAT(nr) \ + DECLARE_KOBJ_ATTR_INT_LIST(ttype ## nr ## _nbeat, ttype_nbeat_val[nr - 1], ttype_nbeat) + +#define DECLARE_KOBJ_TTYPE_NBYTE(nr) \ + DECLARE_KOBJ_ATTR_INT_LIST(ttype ## nr ## _nbyte, ttype_nbyte_val[nr - 1], ttype_nbyte) + +#define DECLARE_KOBJ_TTYPE_BURST(nr) \ + DECLARE_KOBJ_ATTR_STR_LIST(ttype ## nr ## _burst, ttype_burst_val[nr - 1], ttype_burst) + +#define DECLARE_KOBJ_TTYPE_RW(nr) \ + DECLARE_KOBJ_ATTR_STR_LIST(ttype ## nr ## _rw, ttype_rw_val[nr - 1], ttype_rw) + +#define DECLARE_KOBJ_TTYPE_BUSID_VAL(nr) \ + DECLARE_KOBJ_ATTR_HEX(ttype ## nr ## _busid, ttype_busid_val[nr - 1]) + +DECLARE_KOBJ_TTYPE_MASTER(1); +DECLARE_KOBJ_TTYPE_NBEAT(1); +DECLARE_KOBJ_TTYPE_NBYTE(1); +DECLARE_KOBJ_TTYPE_BURST(1); +DECLARE_KOBJ_TTYPE_RW(1); +DECLARE_KOBJ_TTYPE_BUSID_VAL(1); + +DECLARE_KOBJ_TTYPE_MASTER(2); +DECLARE_KOBJ_TTYPE_NBEAT(2); +DECLARE_KOBJ_TTYPE_NBYTE(2); +DECLARE_KOBJ_TTYPE_BURST(2); +DECLARE_KOBJ_TTYPE_RW(2); +DECLARE_KOBJ_TTYPE_BUSID_VAL(2); + +DECLARE_KOBJ_TTYPE_MASTER(3); +DECLARE_KOBJ_TTYPE_NBEAT(3); +DECLARE_KOBJ_TTYPE_NBYTE(3); +DECLARE_KOBJ_TTYPE_BURST(3); +DECLARE_KOBJ_TTYPE_RW(3); +DECLARE_KOBJ_TTYPE_BUSID_VAL(3); + +DECLARE_KOBJ_TTYPE_MASTER(4); +DECLARE_KOBJ_TTYPE_NBEAT(4); +DECLARE_KOBJ_TTYPE_NBYTE(4); +DECLARE_KOBJ_TTYPE_BURST(4); +DECLARE_KOBJ_TTYPE_RW(4); +DECLARE_KOBJ_TTYPE_BUSID_VAL(4); + +DECLARE_KOBJ_TTYPE_MASTER(5); +DECLARE_KOBJ_TTYPE_NBEAT(5); +DECLARE_KOBJ_TTYPE_NBYTE(5); +DECLARE_KOBJ_TTYPE_BURST(5); +DECLARE_KOBJ_TTYPE_RW(5); +DECLARE_KOBJ_TTYPE_BUSID_VAL(5); + +DECLARE_KOBJ_TTYPE_MASTER(6); +DECLARE_KOBJ_TTYPE_NBEAT(6); +DECLARE_KOBJ_TTYPE_NBYTE(6); +DECLARE_KOBJ_TTYPE_BURST(6); +DECLARE_KOBJ_TTYPE_RW(6); +DECLARE_KOBJ_TTYPE_BUSID_VAL(6); + +DECLARE_KOBJ_TTYPE_MASTER(7); +DECLARE_KOBJ_TTYPE_NBEAT(7); +DECLARE_KOBJ_TTYPE_NBYTE(7); +DECLARE_KOBJ_TTYPE_BURST(7); +DECLARE_KOBJ_TTYPE_RW(7); +DECLARE_KOBJ_TTYPE_BUSID_VAL(7); + +DECLARE_KOBJ_TTYPE_MASTER(8); +DECLARE_KOBJ_TTYPE_NBEAT(8); +DECLARE_KOBJ_TTYPE_NBYTE(8); +DECLARE_KOBJ_TTYPE_BURST(8); +DECLARE_KOBJ_TTYPE_RW(8); +DECLARE_KOBJ_TTYPE_BUSID_VAL(8); + +DECLARE_KOBJ_TTYPE_MASTER(9); +DECLARE_KOBJ_TTYPE_NBEAT(9); +DECLARE_KOBJ_TTYPE_NBYTE(9); +DECLARE_KOBJ_TTYPE_BURST(9); +DECLARE_KOBJ_TTYPE_RW(9); +DECLARE_KOBJ_TTYPE_BUSID_VAL(9); + +DECLARE_KOBJ_TTYPE_MASTER(10); +DECLARE_KOBJ_TTYPE_NBEAT(10); +DECLARE_KOBJ_TTYPE_NBYTE(10); +DECLARE_KOBJ_TTYPE_BURST(10); +DECLARE_KOBJ_TTYPE_RW(10); +DECLARE_KOBJ_TTYPE_BUSID_VAL(10); + +DECLARE_KOBJ_TTYPE_MASTER(11); +DECLARE_KOBJ_TTYPE_NBEAT(11); +DECLARE_KOBJ_TTYPE_NBYTE(11); +DECLARE_KOBJ_TTYPE_BURST(11); +DECLARE_KOBJ_TTYPE_RW(11); +DECLARE_KOBJ_TTYPE_BUSID_VAL(11); + +DECLARE_KOBJ_TTYPE_MASTER(12); +DECLARE_KOBJ_TTYPE_NBEAT(12); +DECLARE_KOBJ_TTYPE_NBYTE(12); +DECLARE_KOBJ_TTYPE_BURST(12); +DECLARE_KOBJ_TTYPE_RW(12); +DECLARE_KOBJ_TTYPE_BUSID_VAL(12); + +DECLARE_KOBJ_TTYPE_MASTER(13); +DECLARE_KOBJ_TTYPE_NBEAT(13); +DECLARE_KOBJ_TTYPE_NBYTE(13); +DECLARE_KOBJ_TTYPE_BURST(13); +DECLARE_KOBJ_TTYPE_RW(13); +DECLARE_KOBJ_TTYPE_BUSID_VAL(13); + +DECLARE_KOBJ_TTYPE_MASTER(14); +DECLARE_KOBJ_TTYPE_NBEAT(14); +DECLARE_KOBJ_TTYPE_NBYTE(14); +DECLARE_KOBJ_TTYPE_BURST(14); +DECLARE_KOBJ_TTYPE_RW(14); +DECLARE_KOBJ_TTYPE_BUSID_VAL(14); + +DECLARE_KOBJ_TTYPE_MASTER(15); +DECLARE_KOBJ_TTYPE_NBEAT(15); +DECLARE_KOBJ_TTYPE_NBYTE(15); +DECLARE_KOBJ_TTYPE_BURST(15); +DECLARE_KOBJ_TTYPE_RW(15); +DECLARE_KOBJ_TTYPE_BUSID_VAL(15); + +DECLARE_KOBJ_TTYPE_MASTER(16); +DECLARE_KOBJ_TTYPE_NBEAT(16); +DECLARE_KOBJ_TTYPE_NBYTE(16); +DECLARE_KOBJ_TTYPE_BURST(16); +DECLARE_KOBJ_TTYPE_RW(16); +DECLARE_KOBJ_TTYPE_BUSID_VAL(16); + +DECLARE_KOBJ_TTYPE_MASTER(17); +DECLARE_KOBJ_TTYPE_NBEAT(17); +DECLARE_KOBJ_TTYPE_NBYTE(17); +DECLARE_KOBJ_TTYPE_BURST(17); +DECLARE_KOBJ_TTYPE_RW(17); +DECLARE_KOBJ_TTYPE_BUSID_VAL(17); + +DECLARE_KOBJ_TTYPE_MASTER(18); +DECLARE_KOBJ_TTYPE_NBEAT(18); +DECLARE_KOBJ_TTYPE_NBYTE(18); +DECLARE_KOBJ_TTYPE_BURST(18); +DECLARE_KOBJ_TTYPE_RW(18); +DECLARE_KOBJ_TTYPE_BUSID_VAL(18); + +DECLARE_KOBJ_TTYPE_MASTER(19); +DECLARE_KOBJ_TTYPE_NBEAT(19); +DECLARE_KOBJ_TTYPE_NBYTE(19); +DECLARE_KOBJ_TTYPE_BURST(19); +DECLARE_KOBJ_TTYPE_RW(19); +DECLARE_KOBJ_TTYPE_BUSID_VAL(19); + +DECLARE_KOBJ_TTYPE_MASTER(20); +DECLARE_KOBJ_TTYPE_NBEAT(20); +DECLARE_KOBJ_TTYPE_NBYTE(20); +DECLARE_KOBJ_TTYPE_BURST(20); +DECLARE_KOBJ_TTYPE_RW(20); +DECLARE_KOBJ_TTYPE_BUSID_VAL(20); + +DECLARE_KOBJ_TTYPE_MASTER(21); +DECLARE_KOBJ_TTYPE_NBEAT(21); +DECLARE_KOBJ_TTYPE_NBYTE(21); +DECLARE_KOBJ_TTYPE_BURST(21); +DECLARE_KOBJ_TTYPE_RW(21); +DECLARE_KOBJ_TTYPE_BUSID_VAL(21); + + +#define KOBJ_ATTR_ITEM_SERIAL_FNODE(nr) \ + do { \ + KOBJ_ATTR_ITEM(ttype ## nr ## _master); \ + KOBJ_ATTR_ITEM(ttype ## nr ## _nbeat); \ + KOBJ_ATTR_ITEM(ttype ## nr ## _nbyte); \ + KOBJ_ATTR_ITEM(ttype ## nr ## _burst); \ + KOBJ_ATTR_ITEM(ttype ## nr ## _busid); \ + KOBJ_ATTR_ITEM(ttype ## nr ## _rw); \ + } while (0) + +#define KOBJ_ATTR_LIST \ + do { \ + KOBJ_ATTR_ITEM(high_priority_filter); \ + KOBJ_ATTR_ITEM(emi_TP_busfiltr_enable); \ + KOBJ_ATTR_ITEM(msel_enable); \ + KOBJ_ATTR_ITEM(msel_group1); \ + KOBJ_ATTR_ITEM(msel_group2); \ + KOBJ_ATTR_ITEM(msel_group3); \ + KOBJ_ATTR_ITEM(rwtype); \ + KOBJ_ATTR_ITEM(ttype17_21_en); \ + KOBJ_ATTR_ITEM(ttype1_16_en); \ + KOBJ_ATTR_ITEM_SERIAL_FNODE(1); \ + KOBJ_ATTR_ITEM_SERIAL_FNODE(2); \ + KOBJ_ATTR_ITEM_SERIAL_FNODE(3); \ + KOBJ_ATTR_ITEM_SERIAL_FNODE(4); \ + KOBJ_ATTR_ITEM_SERIAL_FNODE(5); \ + KOBJ_ATTR_ITEM_SERIAL_FNODE(6); \ + KOBJ_ATTR_ITEM_SERIAL_FNODE(7); \ + KOBJ_ATTR_ITEM_SERIAL_FNODE(8); \ + KOBJ_ATTR_ITEM_SERIAL_FNODE(9); \ + KOBJ_ATTR_ITEM_SERIAL_FNODE(10); \ + KOBJ_ATTR_ITEM_SERIAL_FNODE(11); \ + KOBJ_ATTR_ITEM_SERIAL_FNODE(12); \ + KOBJ_ATTR_ITEM_SERIAL_FNODE(13); \ + KOBJ_ATTR_ITEM_SERIAL_FNODE(14); \ + KOBJ_ATTR_ITEM_SERIAL_FNODE(15); \ + KOBJ_ATTR_ITEM_SERIAL_FNODE(16); \ + KOBJ_ATTR_ITEM_SERIAL_FNODE(17); \ + KOBJ_ATTR_ITEM_SERIAL_FNODE(18); \ + KOBJ_ATTR_ITEM_SERIAL_FNODE(19); \ + KOBJ_ATTR_ITEM_SERIAL_FNODE(20); \ + KOBJ_ATTR_ITEM_SERIAL_FNODE(21); \ + KOBJ_ATTR_ITEM(bw_limiter_enable); \ + KOBJ_ATTR_ITEM(dramc_pdir_enable); \ + KOBJ_ATTR_ITEM(clear_setting);\ + KOBJ_ATTR_ITEM(msel_group_ext);\ + KOBJ_ATTR_ITEM(wsct_rw);\ + KOBJ_ATTR_ITEM(wsct_high_priority_enable);\ + KOBJ_ATTR_ITEM(wsct_busid);\ + KOBJ_ATTR_ITEM(wsct_chn_rank_sel);\ + KOBJ_ATTR_ITEM(wsct_burst_range);\ + KOBJ_ATTR_ITEM(tsct_busid_enable);\ + KOBJ_ATTR_ITEM(ttype_high_priority_ext);\ + KOBJ_ATTR_ITEM(ttype_busid_ext);\ + KOBJ_ATTR_ITEM(ttype_chn_rank_sel);\ + KOBJ_ATTR_ITEM(ttype_burst_range);\ + KOBJ_ATTR_ITEM(reserve_wsct_setting);\ + KOBJ_ATTR_ITEM(emi_regdump); \ + KOBJ_ATTR_ITEM(wmask_msel); \ + KOBJ_ATTR_ITEM(ageexp_msel_rw); \ + KOBJ_ATTR_ITEM(default_val); \ + KOBJ_ATTR_ITEM(sspm_support_feature); \ + } while (0) + + +DECLARE_KOBJ_ATTR_INT(reserve_wsct_setting, reserve_wsct_setting); + +extern int MET_BM_Init(void); +extern void MET_BM_DeInit(void); +extern void MET_BM_SaveCfg(void); +extern void MET_BM_RestoreCfg(void); + + + +extern int MET_BM_SetMonitorCounter(const unsigned int counter_num, + const unsigned int master, const unsigned int trans_type); +extern int MET_BM_SetTtypeCounterRW(unsigned int bmrw0_val, unsigned int bmrw1_val); +extern int MET_BM_Set_WsctTsct_id_sel(unsigned int counter_num, unsigned int enable); +extern int MET_BM_SetMaster(const unsigned int counter_num, const unsigned int master); +extern int MET_BM_SetbusID_En(const unsigned int counter_num, + const unsigned int enable); +extern int MET_BM_SetbusID(const unsigned int counter_num, + const unsigned int id); +extern int MET_BM_SetUltraHighFilter(const unsigned int counter_num, const unsigned int enable); +extern int MET_BM_SetLatencyCounter(unsigned int enable); +extern void MET_BM_SetReadWriteType(const unsigned int ReadWriteType); + +extern unsigned int MET_EMI_GetDramRankNum(void); +extern unsigned int MET_EMI_GetDramRankNum_CHN1(void); + + +extern unsigned int MET_EMI_GetDramChannNum(void); +extern unsigned int MET_EMI_Get_CONH_2ND(void); + +/* SEDA 3.5 NEW */ +extern int MET_BM_SetWSCT_master_rw(unsigned int *master , unsigned int *rw); +extern int MET_BM_SetWSCT_high_priority(unsigned int *disable, unsigned int *select); +extern int MET_BM_SetWSCT_busid_idmask(unsigned int *busid, unsigned int *idMask); +extern int MET_BM_SetWSCT_chn_rank_sel(unsigned int *chn_rank_sel); +extern int MET_BM_SetWSCT_burst_range(unsigned int *bnd_dis, unsigned int *low_bnd, unsigned int *up_bnd); +extern int MET_BM_SetTSCT_busid_enable(unsigned int *enable); +extern int MET_BM_SetTtype_high_priority_sel(unsigned int _high_priority_filter, unsigned int *select); +extern int MET_BM_SetTtype_busid_idmask(unsigned int *busid, unsigned int *idMask, int _ttype1_16_en, int _ttype17_21_en); +extern int MET_BM_SetTtype_chn_rank_sel(unsigned int *chn_rank_sel); +extern int MET_BM_SetTtype_burst_range(unsigned int *bnd_dis, unsigned int *low_bnd, unsigned int *up_bnd); +extern unsigned int MET_EMI_Get_BaseClock_Rate(void); + + +/* file node controll */ +extern void _clear_msel_group_ext(void); +extern ssize_t msel_group_ext_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t n); +extern ssize_t msel_group_ext_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf); +extern void _clear_wsct_rw(void); +extern ssize_t wsct_rw_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t n); +extern ssize_t wsct_rw_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf); +extern void _clear_wsct_high_priority_enable(void); +extern ssize_t wsct_high_priority_enable_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t n); +extern ssize_t wsct_high_priority_enable_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf); +extern void _clear_wsct_busid(void); +extern ssize_t wsct_busid_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t n); +extern ssize_t wsct_busid_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf); +extern void _clear_wsct_chn_rank_sel(void); +extern ssize_t wsct_chn_rank_sel_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t n); +extern ssize_t wsct_chn_rank_sel_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf); +extern void _clear_wsct_burst_range(void); +extern ssize_t wsct_burst_range_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t n); +extern ssize_t wsct_burst_range_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf); +extern void _clear_tsct_busid_enable(void); +extern ssize_t tsct_busid_enable_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t n); +extern ssize_t tsct_busid_enable_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf); +extern void _clear_ttype_high_priority_ext(void); +extern ssize_t ttype_high_priority_ext_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t n); +extern ssize_t ttype_high_priority_ext_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf); +extern void _clear_ttype_busid_ext(void); +extern ssize_t ttype_busid_ext_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t n); +extern ssize_t ttype_busid_ext_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf); +extern void _clear_ttype_chn_rank_sel(void); +extern ssize_t ttype_chn_rank_sel_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t n); +extern ssize_t ttype_chn_rank_sel_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf); +extern void _clear_ttype_burst_range(void); +extern ssize_t ttype_burst_range_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t n); +extern ssize_t ttype_burst_range_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf); + +extern ssize_t wmask_msel_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t n); +extern ssize_t wmask_msel_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf); + +extern ssize_t ageexp_msel_rw_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t n); +extern ssize_t ageexp_msel_rw_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf); + +extern void _clear_setting(void); +extern ssize_t clear_setting_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t n); + +extern void emi_init(void); +extern void emi_uninit(void); + +extern void MET_BM_IPI_configs(void); +extern void MET_BM_IPI_REGISTER_CB(void); + + +extern unsigned int get_sspm_support_feature(void); +extern unsigned check_sspm_support(unsigned int module_id); +extern int emi_create_header(char *buf, int buf_len); + +extern int met_emi_create_basic(struct kobject *parent, struct metdevice *emi_dev); +extern void met_emi_delete_basic(void); +extern void met_emi_resume_basic(void); + +extern int do_emi(void); +extern int emi_print_header_basic(char *buf, int len); +extern void ondiemet_emi_start_basic(void); +extern void ondiemet_emi_stop_basic(void); + +extern unsigned met_get_dram_data_rate(void); +extern unsigned int MET_GET_DRAM_TYPE(void); + +#endif /* !__MT_MET_EMI_BM_BASIC_H__ */ diff --git a/drivers/misc/mediatek/met_drv_v2/common/emi/SEDA3_6/met_emi.c b/drivers/misc/mediatek/met_drv_v2/common/emi/SEDA3_6/met_emi.c new file mode 100644 index 0000000000000000000000000000000000000000..fc51f520d5fb7998083fa941f5c7ee1f42fdb0ea --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/emi/SEDA3_6/met_emi.c @@ -0,0 +1,2323 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2019 MediaTek Inc. + * + */ +#include +#include +#include +#include +#include +#include +#include + +#define MET_USER_EVENT_SUPPORT +#include "met_drv.h" +#include "trace.h" + +#include "mtk_typedefs.h" +#include "core_plf_init.h" +#include "mtk_emi_bm.h" +#include "interface.h" +#include "met_dramc.h" + +#if IS_ENABLED(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) +#if defined(ONDIEMET_SUPPORT) +#include "sspm/ondiemet_sspm.h" +#elif defined(TINYSYS_SSPM_SUPPORT) +#include "tinysys_sspm.h" +#include "tinysys_mgr.h" /* for ondiemet_module */ +#endif +#endif + +#define MAX_HEADER_LEN (1024 * 6) +static char header_str[MAX_HEADER_LEN]; + +static unsigned int output_header_len; +static unsigned int output_str_len; + +/* #define FILE_NODE_DBG */ + +/*======================================================================*/ +/* Global variable definitions */ +/*======================================================================*/ +/*ondiemet emi sampling interval in us */ +int emi_tsct_enable = 1; +int emi_mdct_enable = 1; +int emi_TP_busfiltr_enable; + + +/* Dynamic MonitorCounter selection !!!EXPERIMENT!!! */ +static int msel_enable; +static unsigned int msel_group1 = BM_MASTER_ALL; +static unsigned int msel_group2 = BM_MASTER_ALL; +static unsigned int msel_group3 = BM_MASTER_ALL; + + +/* Global variables */ +static struct kobject *kobj_emi; +static int rwtype = BM_BOTH_READ_WRITE; + +/* BW Limiter */ +/*#define CNT_COUNTDOWN (1000-1)*/ /* 1000 * 1ms = 1sec */ +#define CNT_COUNTDOWN (0) /* 1ms */ +/* static int countdown; */ +static int bw_limiter_enable = BM_BW_LIMITER_ENABLE; + +/* TTYPE counter */ +static int ttype1_16_en = BM_TTYPE1_16_DISABLE; +static int ttype17_21_en = BM_TTYPE17_21_DISABLE; + +static int dramc_pdir_enable; +static int dram_chann_num = 1; + +enum SSPM_Mode { + CUSTOMER_MODE = 0x0, + UNDEFINE_MODE = 0x1, + INTERNAL_MODE = 0X2780 +}; + + + +/*======================================================================*/ +/* KOBJ Declarations */ +/*======================================================================*/ + + +DECLARE_KOBJ_ATTR_INT(emi_TP_busfiltr_enable, emi_TP_busfiltr_enable); + + +DECLARE_KOBJ_ATTR_INT(msel_enable, msel_enable); +DECLARE_KOBJ_ATTR_HEX_CHECK(msel_group1, msel_group1, msel_group1 > 0 && msel_group1 <= BM_MASTER_ALL); +DECLARE_KOBJ_ATTR_HEX_CHECK(msel_group2, msel_group2, msel_group2 > 0 && msel_group2 <= BM_MASTER_ALL); +DECLARE_KOBJ_ATTR_HEX_CHECK(msel_group3, msel_group3, msel_group3 > 0 && msel_group3 <= BM_MASTER_ALL); + + + +/* KOBJ: rwtype */ +DECLARE_KOBJ_ATTR_INT_CHECK(rwtype, rwtype, rwtype >= 0 && rwtype <= BM_WRITE_ONLY); + +/* +static unsigned int get_emi_clock_rate(unsigned int dram_data_rate_MHz) +{ + unsigned int DRAM_TYPE; + + if (mtk_dramc_get_ddr_type_symbol) { + DRAM_TYPE = mtk_dramc_get_ddr_type_symbol(); + + if ((DRAM_TYPE == 5) || (DRAM_TYPE == 6) || (DRAM_TYPE == 7)) + return dram_data_rate_MHz / DRAM_EMI_BASECLOCK_RATE_LP4 / DRAM_DATARATE; + else + return dram_data_rate_MHz / DRAM_EMI_BASECLOCK_RATE_LP3 / DRAM_DATARATE; + } else { + METERROR("[%s][%d]mtk_dramc_get_ddr_type_symbol = NULL , use the TYPE_LPDDR4 setting\n", __func__, __LINE__); + return dram_data_rate_MHz / DRAM_EMI_BASECLOCK_RATE_LP4 / DRAM_DATARATE; + } +} +*/ + +/* KOBJ: ttype1_16_en */ +DECLARE_KOBJ_ATTR_STR_LIST_ITEM( + ttype1_16_en, + KOBJ_ITEM_LIST( + { BM_TTYPE1_16_ENABLE, "ENABLE" }, + { BM_TTYPE1_16_DISABLE, "DISABLE" } + ) + ); +DECLARE_KOBJ_ATTR_STR_LIST(ttype1_16_en, ttype1_16_en, ttype1_16_en); + +/* KOBJ: ttype17_21_en */ +DECLARE_KOBJ_ATTR_STR_LIST_ITEM( + ttype17_21_en, + KOBJ_ITEM_LIST( + { BM_TTYPE17_21_ENABLE, "ENABLE" }, + { BM_TTYPE17_21_DISABLE, "DISABLE" } + ) + ); +DECLARE_KOBJ_ATTR_STR_LIST(ttype17_21_en, ttype17_21_en, ttype17_21_en); + +/* KOBJ: bw_limiter_enable */ +DECLARE_KOBJ_ATTR_STR_LIST_ITEM( + bw_limiter_enable, + KOBJ_ITEM_LIST( + { BM_BW_LIMITER_ENABLE, "ENABLE" }, + { BM_BW_LIMITER_DISABLE, "DISABLE" } + ) + ); + +DECLARE_KOBJ_ATTR_STR_LIST(bw_limiter_enable, bw_limiter_enable, bw_limiter_enable); + +/* KOBJ: ttype_master */ +DECLARE_KOBJ_ATTR_STR_LIST_ITEM( + ttype_master, + KOBJ_ITEM_LIST( + { BM_MASTER_M0, "M0" }, + { BM_MASTER_M1, "M1" }, + { BM_MASTER_M2, "M2" }, + { BM_MASTER_M3, "M3" }, + { BM_MASTER_M4, "M4" }, + { BM_MASTER_M5, "M5" }, + { BM_MASTER_M6, "M6" }, + { BM_MASTER_M7, "M7" } + ) + ); + + +/* KOBJ: ttypeX_nbeat, ttypeX_nbyte, ttypeX_burst */ +DECLARE_KOBJ_ATTR_INT_LIST_ITEM( + ttype_nbeat, + KOBJ_ITEM_LIST( + { BM_TRANS_TYPE_1BEAT, 1 }, + { BM_TRANS_TYPE_2BEAT, 2 }, + { BM_TRANS_TYPE_3BEAT, 3 }, + { BM_TRANS_TYPE_4BEAT, 4 }, + { BM_TRANS_TYPE_5BEAT, 5 }, + { BM_TRANS_TYPE_6BEAT, 6 }, + { BM_TRANS_TYPE_7BEAT, 7 }, + { BM_TRANS_TYPE_8BEAT, 8 }, + { BM_TRANS_TYPE_9BEAT, 9 }, + { BM_TRANS_TYPE_10BEAT, 10 }, + { BM_TRANS_TYPE_11BEAT, 11 }, + { BM_TRANS_TYPE_12BEAT, 12 }, + { BM_TRANS_TYPE_13BEAT, 13 }, + { BM_TRANS_TYPE_14BEAT, 14 }, + { BM_TRANS_TYPE_15BEAT, 15 }, + { BM_TRANS_TYPE_16BEAT, 16 } + ) + ); +DECLARE_KOBJ_ATTR_INT_LIST_ITEM( + ttype_nbyte, + KOBJ_ITEM_LIST( + { BM_TRANS_TYPE_1Byte, 1 }, + { BM_TRANS_TYPE_2Byte, 2 }, + { BM_TRANS_TYPE_4Byte, 4 }, + { BM_TRANS_TYPE_8Byte, 8 }, + { BM_TRANS_TYPE_16Byte, 16 }, + { BM_TRANS_TYPE_32Byte, 32 } + ) + ); +DECLARE_KOBJ_ATTR_STR_LIST_ITEM( + ttype_burst, + KOBJ_ITEM_LIST( + { BM_TRANS_TYPE_BURST_INCR, "INCR" }, + { BM_TRANS_TYPE_BURST_WRAP, "WRAP" } + ) + ); + +DECLARE_KOBJ_ATTR_STR_LIST_ITEM( + ttype_rw, + KOBJ_ITEM_LIST( + { BM_TRANS_RW_DEFAULT, "DEFAULT" }, + { BM_TRANS_RW_READONLY, "R" }, + { BM_TRANS_RW_WRITEONLY, "W" }, + { BM_TRANS_RW_RWBOTH, "BOTH" } + ) + ); + + +DECLARE_KOBJ_ATTR_INT(dramc_pdir_enable, dramc_pdir_enable); + +/*enable high priority filter*/ +static int high_priority_filter; +DECLARE_KOBJ_ATTR_HEX(high_priority_filter, high_priority_filter); + + + +/**/ +static int ttype_master_val[21]; +static int ttype_busid_val[21]; +static int ttype_nbeat_val[21]; +static int ttype_nbyte_val[21]; +static int ttype_burst_val[21]; +static int ttype_rw_val[21]; + +#define DECLARE_KOBJ_TTYPE_MASTER(nr) \ + DECLARE_KOBJ_ATTR_STR_LIST(ttype ## nr ## _master, ttype_master_val[nr - 1], ttype_master) + +#define DECLARE_KOBJ_TTYPE_NBEAT(nr) \ + DECLARE_KOBJ_ATTR_INT_LIST(ttype ## nr ## _nbeat, ttype_nbeat_val[nr - 1], ttype_nbeat) + +#define DECLARE_KOBJ_TTYPE_NBYTE(nr) \ + DECLARE_KOBJ_ATTR_INT_LIST(ttype ## nr ## _nbyte, ttype_nbyte_val[nr - 1], ttype_nbyte) + +#define DECLARE_KOBJ_TTYPE_BURST(nr) \ + DECLARE_KOBJ_ATTR_STR_LIST(ttype ## nr ## _burst, ttype_burst_val[nr - 1], ttype_burst) + +#define DECLARE_KOBJ_TTYPE_RW(nr) \ + DECLARE_KOBJ_ATTR_STR_LIST(ttype ## nr ## _rw, ttype_rw_val[nr - 1], ttype_rw) + +#define DECLARE_KOBJ_TTYPE_BUSID_VAL(nr) \ + DECLARE_KOBJ_ATTR_HEX(ttype ## nr ## _busid, ttype_busid_val[nr - 1]) + +DECLARE_KOBJ_TTYPE_MASTER(1); +DECLARE_KOBJ_TTYPE_NBEAT(1); +DECLARE_KOBJ_TTYPE_NBYTE(1); +DECLARE_KOBJ_TTYPE_BURST(1); +DECLARE_KOBJ_TTYPE_RW(1); +DECLARE_KOBJ_TTYPE_BUSID_VAL(1); + +DECLARE_KOBJ_TTYPE_MASTER(2); +DECLARE_KOBJ_TTYPE_NBEAT(2); +DECLARE_KOBJ_TTYPE_NBYTE(2); +DECLARE_KOBJ_TTYPE_BURST(2); +DECLARE_KOBJ_TTYPE_RW(2); +DECLARE_KOBJ_TTYPE_BUSID_VAL(2); + +DECLARE_KOBJ_TTYPE_MASTER(3); +DECLARE_KOBJ_TTYPE_NBEAT(3); +DECLARE_KOBJ_TTYPE_NBYTE(3); +DECLARE_KOBJ_TTYPE_BURST(3); +DECLARE_KOBJ_TTYPE_RW(3); +DECLARE_KOBJ_TTYPE_BUSID_VAL(3); + +DECLARE_KOBJ_TTYPE_MASTER(4); +DECLARE_KOBJ_TTYPE_NBEAT(4); +DECLARE_KOBJ_TTYPE_NBYTE(4); +DECLARE_KOBJ_TTYPE_BURST(4); +DECLARE_KOBJ_TTYPE_RW(4); +DECLARE_KOBJ_TTYPE_BUSID_VAL(4); + +DECLARE_KOBJ_TTYPE_MASTER(5); +DECLARE_KOBJ_TTYPE_NBEAT(5); +DECLARE_KOBJ_TTYPE_NBYTE(5); +DECLARE_KOBJ_TTYPE_BURST(5); +DECLARE_KOBJ_TTYPE_RW(5); +DECLARE_KOBJ_TTYPE_BUSID_VAL(5); + +DECLARE_KOBJ_TTYPE_MASTER(6); +DECLARE_KOBJ_TTYPE_NBEAT(6); +DECLARE_KOBJ_TTYPE_NBYTE(6); +DECLARE_KOBJ_TTYPE_BURST(6); +DECLARE_KOBJ_TTYPE_RW(6); +DECLARE_KOBJ_TTYPE_BUSID_VAL(6); + +DECLARE_KOBJ_TTYPE_MASTER(7); +DECLARE_KOBJ_TTYPE_NBEAT(7); +DECLARE_KOBJ_TTYPE_NBYTE(7); +DECLARE_KOBJ_TTYPE_BURST(7); +DECLARE_KOBJ_TTYPE_RW(7); +DECLARE_KOBJ_TTYPE_BUSID_VAL(7); + +DECLARE_KOBJ_TTYPE_MASTER(8); +DECLARE_KOBJ_TTYPE_NBEAT(8); +DECLARE_KOBJ_TTYPE_NBYTE(8); +DECLARE_KOBJ_TTYPE_BURST(8); +DECLARE_KOBJ_TTYPE_RW(8); +DECLARE_KOBJ_TTYPE_BUSID_VAL(8); + +DECLARE_KOBJ_TTYPE_MASTER(9); +DECLARE_KOBJ_TTYPE_NBEAT(9); +DECLARE_KOBJ_TTYPE_NBYTE(9); +DECLARE_KOBJ_TTYPE_BURST(9); +DECLARE_KOBJ_TTYPE_RW(9); +DECLARE_KOBJ_TTYPE_BUSID_VAL(9); + +DECLARE_KOBJ_TTYPE_MASTER(10); +DECLARE_KOBJ_TTYPE_NBEAT(10); +DECLARE_KOBJ_TTYPE_NBYTE(10); +DECLARE_KOBJ_TTYPE_BURST(10); +DECLARE_KOBJ_TTYPE_RW(10); +DECLARE_KOBJ_TTYPE_BUSID_VAL(10); + +DECLARE_KOBJ_TTYPE_MASTER(11); +DECLARE_KOBJ_TTYPE_NBEAT(11); +DECLARE_KOBJ_TTYPE_NBYTE(11); +DECLARE_KOBJ_TTYPE_BURST(11); +DECLARE_KOBJ_TTYPE_RW(11); +DECLARE_KOBJ_TTYPE_BUSID_VAL(11); + +DECLARE_KOBJ_TTYPE_MASTER(12); +DECLARE_KOBJ_TTYPE_NBEAT(12); +DECLARE_KOBJ_TTYPE_NBYTE(12); +DECLARE_KOBJ_TTYPE_BURST(12); +DECLARE_KOBJ_TTYPE_RW(12); +DECLARE_KOBJ_TTYPE_BUSID_VAL(12); + +DECLARE_KOBJ_TTYPE_MASTER(13); +DECLARE_KOBJ_TTYPE_NBEAT(13); +DECLARE_KOBJ_TTYPE_NBYTE(13); +DECLARE_KOBJ_TTYPE_BURST(13); +DECLARE_KOBJ_TTYPE_RW(13); +DECLARE_KOBJ_TTYPE_BUSID_VAL(13); + +DECLARE_KOBJ_TTYPE_MASTER(14); +DECLARE_KOBJ_TTYPE_NBEAT(14); +DECLARE_KOBJ_TTYPE_NBYTE(14); +DECLARE_KOBJ_TTYPE_BURST(14); +DECLARE_KOBJ_TTYPE_RW(14); +DECLARE_KOBJ_TTYPE_BUSID_VAL(14); + +DECLARE_KOBJ_TTYPE_MASTER(15); +DECLARE_KOBJ_TTYPE_NBEAT(15); +DECLARE_KOBJ_TTYPE_NBYTE(15); +DECLARE_KOBJ_TTYPE_BURST(15); +DECLARE_KOBJ_TTYPE_RW(15); +DECLARE_KOBJ_TTYPE_BUSID_VAL(15); + +DECLARE_KOBJ_TTYPE_MASTER(16); +DECLARE_KOBJ_TTYPE_NBEAT(16); +DECLARE_KOBJ_TTYPE_NBYTE(16); +DECLARE_KOBJ_TTYPE_BURST(16); +DECLARE_KOBJ_TTYPE_RW(16); +DECLARE_KOBJ_TTYPE_BUSID_VAL(16); + +DECLARE_KOBJ_TTYPE_MASTER(17); +DECLARE_KOBJ_TTYPE_NBEAT(17); +DECLARE_KOBJ_TTYPE_NBYTE(17); +DECLARE_KOBJ_TTYPE_BURST(17); +DECLARE_KOBJ_TTYPE_RW(17); +DECLARE_KOBJ_TTYPE_BUSID_VAL(17); + +DECLARE_KOBJ_TTYPE_MASTER(18); +DECLARE_KOBJ_TTYPE_NBEAT(18); +DECLARE_KOBJ_TTYPE_NBYTE(18); +DECLARE_KOBJ_TTYPE_BURST(18); +DECLARE_KOBJ_TTYPE_RW(18); +DECLARE_KOBJ_TTYPE_BUSID_VAL(18); + +DECLARE_KOBJ_TTYPE_MASTER(19); +DECLARE_KOBJ_TTYPE_NBEAT(19); +DECLARE_KOBJ_TTYPE_NBYTE(19); +DECLARE_KOBJ_TTYPE_BURST(19); +DECLARE_KOBJ_TTYPE_RW(19); +DECLARE_KOBJ_TTYPE_BUSID_VAL(19); + +DECLARE_KOBJ_TTYPE_MASTER(20); +DECLARE_KOBJ_TTYPE_NBEAT(20); +DECLARE_KOBJ_TTYPE_NBYTE(20); +DECLARE_KOBJ_TTYPE_BURST(20); +DECLARE_KOBJ_TTYPE_RW(20); +DECLARE_KOBJ_TTYPE_BUSID_VAL(20); + +DECLARE_KOBJ_TTYPE_MASTER(21); +DECLARE_KOBJ_TTYPE_NBEAT(21); +DECLARE_KOBJ_TTYPE_NBYTE(21); +DECLARE_KOBJ_TTYPE_BURST(21); +DECLARE_KOBJ_TTYPE_RW(21); +DECLARE_KOBJ_TTYPE_BUSID_VAL(21); + + +static unsigned int get_sspm_support_feature(void) +{ + unsigned int rdata=0; +#if IS_ENABLED(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) +#if defined(ONDIEMET_SUPPORT) || defined(TINYSYS_SSPM_SUPPORT) + int ret, i; + unsigned int ipi_buf[4]; + + for (i = 0; i < 4; i++) + ipi_buf[i] = 0; + + if (sspm_buf_available == 1) { + ipi_buf[0] = MET_MAIN_ID | (MID_EMI << MID_BIT_SHIFT) | MET_REQ_AP2MD ; + ret = met_ipi_to_sspm_command((void *)ipi_buf, 0, &rdata, 1); + } +#endif +#endif + return rdata; +} + +/* SEDA 3.5 ext */ +static unsigned int msel_group_ext_val[WSCT_AMOUNT]; +static unsigned int wsct_rw_val[WSCT_AMOUNT]; + +char* const delim_comma = ","; +char* const delim_coclon = ":"; + + +char msel_group_ext[FILE_NODE_DATA_LEN] = {'\0'}; + +static void _clear_msel_group_ext(void) { + int i; + + for (i=0;i clear_setting + */ + + char *token, *cur= msel_group_ext; + char *_id = NULL, *_master_group = NULL; + int id_int = 0; + + _clear_msel_group_ext(); + + snprintf(msel_group_ext, FILE_NODE_DATA_LEN, "%s", buf); + msel_group_ext[n-1]='\0'; + + + while (cur != NULL) { + token = strsep(&cur, delim_comma); + PR_BOOTMSG("token: %s\n",token); + /*token EX: 4:0xff , (ID,master_group)*/ + + _id = strsep(&token, delim_coclon); // ID + _master_group = strsep(&token, delim_coclon); + + PR_BOOTMSG("_id[%s] _master_group[%s]\n",_id,_master_group); + + if (_id == NULL || _master_group == NULL) { + PR_BOOTMSG("err: _id[%s] _master_group[%s], para can't be NULL\n",_id,_master_group); + _clear_msel_group_ext(); + return -EINVAL; + } + + if (kstrtouint(_id, 0, &id_int) != 0) { + PR_BOOTMSG("_id[%s] trans to hex err\n",_id); + _clear_msel_group_ext(); + return -EINVAL; + } + + + if ( id_int >= 0 && id_int < WSCT_AMOUNT) { + if (kstrtouint(_master_group, 0, &msel_group_ext_val[id_int]) != 0) { + PR_BOOTMSG("master_group[%s] trans to hex err\n",_master_group); + _clear_msel_group_ext(); + return -EINVAL; + } + } else { + PR_BOOTMSG("id[%d] exceed the range, it must be 0~%d\n",id_int, WSCT_AMOUNT-1); + _clear_msel_group_ext(); + return -EINVAL; + } + } +#ifdef FILE_NODE_DBG + PR_BOOTMSG("input data [%s]\n",msel_group_ext); + /*PR_BOOTMSG("msel_group_ext_store size para n[%d]\n",n);*/ + int i; + PR_BOOTMSG("save data\n"); + for (i=0;i= 0 && id_int < WSCT_AMOUNT) { + if ( 0 == strncmp("NONE",_rw_type,4)) + wsct_rw_val[id_int] = BM_WSCT_RW_DISABLE; + else if (0 == strncmp("R",_rw_type,4)) + wsct_rw_val[id_int] = BM_WSCT_RW_READONLY; + else if (0 == strncmp("W",_rw_type,4)) + wsct_rw_val[id_int] = BM_WSCT_RW_WRITEONLY; + else if (0 == strncmp("RW",_rw_type,4)) + wsct_rw_val[id_int] = BM_WSCT_RW_RWBOTH; + else { + PR_BOOTMSG("_id[%s] has err rwtype[%s]\n", _id, _rw_type); + _clear_wsct_rw(); + return -EINVAL; + } + + } else { + PR_BOOTMSG("id[%d] exceed the range, it must be 0~%d\n",id_int, WSCT_AMOUNT-1); + _clear_wsct_rw(); + return -EINVAL; + } + } + +#ifdef FILE_NODE_DBG + PR_BOOTMSG("wsct_rw_store input data [%s]\n",wsct_rw); + int i; + PR_BOOTMSG("rwtype save data\n"); + for (i=0;i= 0 && id_int < WSCT_AMOUNT) { + if ( 0 == strncmp("disable", _enable, 7)) { + + WSCT_HPRI_DIS[id_int] = 1; + WSCT_HPRI_SEL[id_int] = 0xf; + } else if ( 0 == strncmp("enable", _enable, 6)) { + + WSCT_HPRI_DIS[id_int] = 0; + if (kstrtouint(_level, 0, &level_int) != 0) { + PR_BOOTMSG("_id[%s] trans ultraLevel[%s] to hex err\n",_id, _level); + _clear_wsct_high_priority_enable(); + return -EINVAL; + } + WSCT_HPRI_SEL[id_int] = level_int & 0xF; + } else { + PR_BOOTMSG("_id[%s] has err enable[%s] (enable/disable)\n", _id, _enable); + _clear_wsct_high_priority_enable(); + return -EINVAL; + } + + } else { + PR_BOOTMSG("id[%d] exceed the range, it must be 0~%d\n",id_int, WSCT_AMOUNT-1); + _clear_wsct_high_priority_enable(); + return -EINVAL; + } + } +#ifdef FILE_NODE_DBG + PR_BOOTMSG("input data [%s]\n",wsct_high_priority_enable); + int i; + PR_BOOTMSG("wsct_high_priority_enable save data\n"); + for (i=0;i= 0 && id_int < WSCT_AMOUNT) { + wsct_busid_val[id_int] = busid_int; + wsct_idMask_val[id_int] = idMask_int; + + } else { + PR_BOOTMSG("id[%d] exceed the range, it must be 0~%d\n",id_int, WSCT_AMOUNT-1); + _clear_wsct_busid(); + return -EINVAL; + } + } +#ifdef FILE_NODE_DBG + PR_BOOTMSG("input data [%s]\n",wsct_busid); + int i; + PR_BOOTMSG("wsct_busid save data\n"); + for (i=0;i= 0 && id_int < WSCT_AMOUNT) { + wsct_chn_rank_sel_val[id_int] = chn_rank_int; + + } else { + PR_BOOTMSG("id[%d] exceed the range, it must be 0~%d\n",id_int, WSCT_AMOUNT-1); + _clear_wsct_chn_rank_sel(); + return -EINVAL; + } + } + +#ifdef FILE_NODE_DBG + PR_BOOTMSG("wsct_chn_rank_sel input data [%s]\n",wsct_chn_rank_sel); + int i; + PR_BOOTMSG("wsct_chn_rank_sel_val save data\n"); + for (i=0;i= 0 && id_int < WSCT_AMOUNT) { + wsct_byte_low_bnd_val[id_int] = low_bnd_int; + wsct_byte_up_bnd_val[id_int] = up_bnd_int; + wsct_byte_bnd_dis[id_int] = 0; + } else { + PR_BOOTMSG("id[%d] exceed the range, it must be 0~%d\n",id_int, WSCT_AMOUNT-1); + _clear_wsct_burst_range(); + return -EINVAL; + } + } + +#ifdef FILE_NODE_DBG + PR_BOOTMSG("wsct_burst_range_store input data [%s]\n",wsct_burst_range); + int i; + PR_BOOTMSG("wsct_burst_range save data\n"); + for (i=0;i= 0 && id_int < TSCT_AMOUNT) { + if ( 0 == strncmp("disable", _enable, 7)) { + tsct_busid_enable_val[id_int] = 0; + } else if ( 0 == strncmp("enable", _enable, 6)) { + tsct_busid_enable_val[id_int] = 1; + } else { + PR_BOOTMSG("_id[%s] has err enable[%s] (enable/disable)\n", _id, _enable); + _clear_tsct_busid_enable(); + return -EINVAL; + } + + } else { + PR_BOOTMSG("id[%d] exceed the range, it must be 0~%d\n",id_int, TSCT_AMOUNT-1); + _clear_tsct_busid_enable(); + return -EINVAL; + } + } +#ifdef FILE_NODE_DBG + PR_BOOTMSG("tsct_busid_enable input data [%s]\n",tsct_busid_enable); + int i; + PR_BOOTMSG("wsct_high_priority_enable save data\n"); + for (i=0;i= 0 && id_int < BM_COUNTER_MAX) { + if ( 0 == strncmp("disable", _enable, 7)) { + + high_priority_filter = ( high_priority_filter & ~(1<>i & 0x1, TTYPE_HPRI_SEL[i]); + } +#endif + return n; +} + +static ssize_t ttype_high_priority_ext_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%s\n", ttype_high_priority_ext); +} + + +static unsigned int ttype_idMask_val[BM_COUNTER_MAX]; +char ttype_busid_ext[FILE_NODE_DATA_LEN] = {'\0'}; + +static void _clear_ttype_busid_ext(void) { + int i; + + for (i=0;i= 0 && id_int < BM_COUNTER_MAX) { + ttype_busid_val[id_int] = busid_int; + ttype_idMask_val[id_int] = idMask_int; + + } else { + PR_BOOTMSG("ttype_busid_ext id[%d] exceed the range, it must be 1~%d\n",id_int+1, BM_COUNTER_MAX); + _clear_ttype_busid_ext(); + return -EINVAL; + } + } +#ifdef FILE_NODE_DBG + PR_BOOTMSG("ttype_busid_ext input data [%s]\n",ttype_busid_ext); + + int i; + PR_BOOTMSG("ttype_busid_ext save data\n"); + for (i=0;i= 0 && id_int < BM_COUNTER_MAX) { + ttype_chn_rank_sel[id_int] = chn_rank_int; + + } else { + PR_BOOTMSG("id[%d] exceed the range, it must be 1~%d\n",id_int+1, BM_COUNTER_MAX); + _clear_ttype_chn_rank_sel(); + return -EINVAL; + } + } + +#ifdef FILE_NODE_DBG + PR_BOOTMSG("ttype_chn_rank_sel input data [%s]\n",ttype_chn_rank_sel); + + int i; + PR_BOOTMSG("wsct_chn_rank_sel_val save data\n"); + for (i=0;i= 0 && id_int < BM_COUNTER_MAX) { + ttype_byte_low_bnd_val[id_int] = low_bnd_int; + ttype_byte_up_bnd_val[id_int] = up_bnd_int; + ttype_byte_bnd_dis[id_int] = 0; + } else { + PR_BOOTMSG("id[%d] exceed the range, it must be 1~%d\n",id_int, BM_COUNTER_MAX); + _clear_ttype_burst_range(); + return -EINVAL; + } + } + +#ifdef FILE_NODE_DBG + PR_BOOTMSG("ttype_burst_range_store input data [%s]\n",ttype_burst_range); + + int i; + PR_BOOTMSG("ttype_burst_range save data\n"); + for (i=0;i 0xff_ff */ + ttype_rw_val[i] = BM_TRANS_RW_DEFAULT; + } + + _clear_msel_group_ext(); + _clear_wsct_rw(); + _clear_wsct_high_priority_enable(); + _clear_wsct_busid(); + _clear_wsct_chn_rank_sel(); + _clear_wsct_burst_range(); + + _clear_tsct_busid_enable(); + _clear_ttype_high_priority_ext(); + _clear_ttype_high_priority_ext(); + _clear_ttype_busid_ext(); + _clear_ttype_chn_rank_sel(); + _clear_ttype_burst_range(); + + reserve_wsct_setting = 0; + + + ret = MET_BM_Init(); + if (ret != 0) { + pr_notice("MET_BM_Init failed!!!\n"); + ret = 0; /* will retry later */ + } else { + emi_inited = 1; + } + + kobj_emi = parent; + +#define KOBJ_ATTR_ITEM(attr_name) \ + do { \ + ret = sysfs_create_file(kobj_emi, &attr_name ## _attr.attr); \ + if (ret != 0) { \ + pr_notice("Failed to create " #attr_name " in sysfs\n"); \ + return ret; \ + } \ + } while (0) + KOBJ_ATTR_LIST; +#undef KOBJ_ATTR_ITEM + + return ret; +} + + +static void met_emi_delete(void) +{ +#define KOBJ_ATTR_ITEM(attr_name) \ + sysfs_remove_file(kobj_emi, &attr_name##_attr.attr) + if (kobj_emi != NULL) { + KOBJ_ATTR_LIST; + kobj_emi = NULL; + } +#undef KOBJ_ATTR_ITEM + + if (emi_inited) + MET_BM_DeInit(); +} + + + +static void met_emi_resume(void) +{ + if (!do_emi()) + return; + + emi_init(); +} + + +static const char help[] = " --emi monitor EMI banwidth\n"; + +static int emi_print_header(char *buf, int len) +{ + + if( (strlen(header_str) - output_str_len) > PAGE_SIZE ){ + char output_buf[PAGE_SIZE/4]; + + strncpy(output_buf, header_str+output_str_len, (PAGE_SIZE/4) -1); + output_buf[(PAGE_SIZE/4) - 1] = '\0'; + + len = snprintf(buf, PAGE_SIZE, "%s", output_buf); + if (len < 0) + PR_BOOTMSG("emi_print_header snprintf return err[%d]\n",len); + + output_str_len += len; + met_sspm_emi.header_read_again = 1; + + PR_BOOTMSG("EMI header read again!\n"); + } + else{ + len = snprintf(buf, PAGE_SIZE, "%s\n", header_str+output_str_len); + if (len < 0) + PR_BOOTMSG("emi_print_header snprintf return err[%d]\n",len); + /* reset state */ + met_sspm_emi.header_read_again = 0; + output_header_len = 0; + output_str_len = 0; + } + + + return len; +} + + +#define TTYPE_NAME_STR_LEN 64 +/* static char ttype_name[21][TTYPE_NAME_STR_LEN]; */ + +static int emi_create_header(char *buf, int buf_len) +{ + int ret = 0; +/* int ret_m[21]; */ + int i = 0; + +#if 1 /* move to AP side print header */ +/*#ifndef CONFIG_MTK_TINYSYS_SSPM_SUPPORT*/ + unsigned int dram_data_rate_MHz; + unsigned int DRAM_TYPE; + unsigned int base_clock_rate; +#endif + + + ret += snprintf(buf + ret, buf_len - ret, + "met-info [000] 0.0: met_emi_wsct_amount: %d\n",WSCT_AMOUNT); + + /* master selection header */ + ret += snprintf(buf + ret, buf_len - ret, + "met-info [000] 0.0: met_emi_msel: %x,%x,%x\n", + msel_group_ext_val[1] & BM_MASTER_ALL, + msel_group_ext_val[2] & BM_MASTER_ALL, + msel_group_ext_val[3] & BM_MASTER_ALL); + + /*Ttype RW type header*/ + PR_BOOTMSG("rwtype=%d\n",rwtype); + ret += snprintf(buf + ret, buf_len - ret, "met-info [000] 0.0: met_emi_rw_cfg: "); + if (rwtype == BM_READ_ONLY) + ret += snprintf(buf + ret, buf_len - ret, "R"); + else if (rwtype == BM_WRITE_ONLY) + ret += snprintf(buf + ret, buf_len - ret, "W"); + else + ret += snprintf(buf + ret, buf_len - ret, "BOTH"); + + for (i = 0; i < 21; i++) { + if (ttype_rw_val[i] == BM_TRANS_RW_DEFAULT) + ret += snprintf(buf + ret, buf_len - ret, ",DEFAULT"); + else if (ttype_rw_val[i] == BM_TRANS_RW_READONLY) + ret += snprintf(buf + ret, buf_len - ret, ",R"); + else if (ttype_rw_val[i] == BM_TRANS_RW_WRITEONLY) + ret += snprintf(buf + ret, buf_len - ret, ",W"); + else /*BM_TRANS_RW_RWBOTH*/ + ret += snprintf(buf + ret, buf_len - ret, ",BOTH"); + } + ret += snprintf(buf + ret, buf_len - ret, "\n"); + + /*ultra header*/ + ret += snprintf(buf + ret, buf_len - ret, + "met-info [000] 0.0: met_emi_ultra_filter: %x\n", high_priority_filter); + + /* ttype header */ + if (ttype17_21_en == BM_TTYPE17_21_ENABLE) { + int i = 0; + int j = 0; + + /* ttype master list */ + ret += snprintf(buf + ret, buf_len - ret, "met-info [000] 0.0: met_emi_ttype_master_list: "); + for (i = 0; i < 21; i++) { + for (j = 0; j < ARRAY_SIZE(ttype_master_list_item); j++) { + if (ttype_master_val[i] == ttype_master_list_item[j].key) { + ret += snprintf(buf + ret, buf_len - ret, "%s,", ttype_master_list_item[j].val); + } + } + } + /* remove the last comma */ + snprintf(buf + ret -1, buf_len - ret + 1, "\n"); + + /* ttype busid list */ + ret += snprintf(buf + ret, buf_len - ret, "met-info [000] 0.0: met_emi_ttype_busid_list: "); + for (i = 0; i < 21; i++) + ret += snprintf(buf + ret, buf_len - ret, "%x,", ttype_busid_val[i]); + + snprintf(buf + ret -1, buf_len - ret + 1, "\n"); + + /* ttype nbeat list */ + ret += snprintf(buf + ret, buf_len - ret, "met-info [000] 0.0: met_emi_ttype_nbeat_list: "); + for (i = 0; i < 21; i++) { + for (j = 0; j < ARRAY_SIZE(ttype_nbeat_list_item); j++) { + if (ttype_nbeat_val[i] == ttype_nbeat_list_item[j].key) { + ret += snprintf(buf + ret, buf_len - ret, "%d,", ttype_nbeat_list_item[j].val); + } + } + } + snprintf(buf + ret -1, buf_len - ret + 1, "\n"); + + /* ttype nbyte list */ + ret += snprintf(buf + ret, buf_len - ret, "met-info [000] 0.0: met_emi_ttype_nbyte_list: "); + for (i = 0; i < 21; i++) { + for (j = 0; j < ARRAY_SIZE(ttype_nbyte_list_item); j++) { + if (ttype_nbyte_val[i] == ttype_nbyte_list_item[j].key) { + ret += snprintf(buf + ret, buf_len - ret, "%d,", ttype_nbyte_list_item[j].val); + } + } + } + snprintf(buf + ret -1, buf_len - ret + 1, "\n"); + + /* ttype burst list */ + ret += snprintf(buf + ret, buf_len - ret, "met-info [000] 0.0: met_emi_ttype_burst_list: "); + for (i = 0; i < 21; i++) { + for (j = 0; j < ARRAY_SIZE(ttype_burst_list_item); j++) { + if (ttype_burst_val[i] == ttype_burst_list_item[j].key) { + ret += snprintf(buf + ret, buf_len - ret, "%s,", ttype_burst_list_item[j].val); + } + } + } + snprintf(buf + ret -1, buf_len - ret + 1, "\n"); + + } + /* ttype enable */ + ret += snprintf(buf + ret, buf_len - ret, "met-info [000] 0.0: met_emi_ttype_enable: %d,%d\n",ttype1_16_en, ttype17_21_en); + + +#if 1 /*SEDA 3.5*/ + + ret += snprintf(buf + ret, buf_len - ret, + "met-info [000] 0.0: met_emi_msel_ext: %x,%x,%x\n", + msel_group_ext_val[0] & BM_MASTER_ALL, + msel_group_ext_val[4] & BM_MASTER_ALL, + msel_group_ext_val[5] & BM_MASTER_ALL); + + ret += snprintf(buf + ret, buf_len - ret, "met-info [000] 0.0: met_emi_wsct_rw: "); + + for (i=0;i= 2 ) { + ret += snprintf(buf + ret, buf_len - ret, + "met-info [000] 0.0: met_dramc_header: "); + for (i = 0; i < dram_chann_num; i++) { + if (i != 0) + ret += snprintf(buf + ret, buf_len - ret, + ","); + ret += snprintf(buf + ret, buf_len - ret, "freerun_26m_%d,", i); + ret += snprintf(buf + ret, buf_len - ret, + "rk0_pre_sb_%d,rk0_pre_pd_%d,rk0_act_sb_%d,rk0_act_pd_%d,", i, i, i, i); + ret += snprintf(buf + ret, buf_len - ret, + "rk1_pre_sb_%d,rk1_pre_pd_%d,rk1_act_sb_%d,rk1_act_pd_%d,", i, i, i, i); + ret += snprintf(buf + ret, buf_len - ret, + "rk2_pre_sb_%d,rk2_pre_pd_%d,rk2_act_sb_%d,rk2_act_pd_%d", i, i, i, i); + } + ret += snprintf(buf + ret, buf_len - ret, "\n"); + } + + /* DRS header */ + ret += snprintf(buf + ret, buf_len - ret, + "met-info [000] 0.0: emi_drs_header: ch0_RANK1_GP(%%),ch0_RANK1_SF(%%),ch0_ALL_SF(%%),ch1_RANK1_GP(%%),ch1_RANK1_SF(%%),ch1_ALL_SF(%%)\n"); +#endif + + met_sspm_emi.header_read_again = 0; + output_header_len = 0; + output_str_len = 0; + + return ret; +} + + +#if IS_ENABLED(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) +#if defined(ONDIEMET_SUPPORT) || defined(TINYSYS_SSPM_SUPPORT) +static int emi_print_help(char *buf, int len) +{ + return snprintf(buf, PAGE_SIZE, help); +} + +static int ondiemet_emi_print_header(char *buf, int len) +{ + return emi_print_header(buf, len); +} + +static void MET_BM_IPI_REGISTER_CB(void) +{ + int ret, i; + unsigned int rdata; + unsigned int ipi_buf[4]; + + for (i = 0; i < 4; i++) + ipi_buf[i] = 0; + + if (sspm_buf_available == 1) { + ipi_buf[0] = MET_MAIN_ID | (MID_EMI << MID_BIT_SHIFT) | MET_ARGU | SET_REGISTER_CB; + ret = met_ipi_to_sspm_command((void *)ipi_buf, 0, &rdata, 1); + } +} + + +static void MET_BM_IPI_configs(void) +{ + int ret, i; + unsigned int rdata; + unsigned int ipi_buf[4]; + + for (i = 0; i < 4; i++) + ipi_buf[i] = 0; + + if (sspm_buf_available == 1) { + ipi_buf[0] = MET_MAIN_ID | (MID_EMI << MID_BIT_SHIFT) | MET_ARGU | SET_EBM_CONFIGS1; + ipi_buf[2] = EMI_VER_MAJOR << 24 | EMI_VER_MINOR << 16 | DRAMC_VER << 8 | 0; + ret = met_ipi_to_sspm_command((void *)ipi_buf, 0, &rdata, 1); + } +} + + +static void ondiemet_emi_start(void) +{ + MET_BM_IPI_REGISTER_CB(); + if (!emi_inited) { + if (MET_BM_Init() != 0) { + met_sspm_emi.mode = 0; + pr_notice("MET_BM_Init failed!!!\n"); + return; + } + emi_inited = 1; + } + MET_BM_IPI_configs(); + + if (do_emi()) + emi_init(); + + ondiemet_module[ONDIEMET_SSPM] |= ID_EMI; + + emi_create_header(header_str, MAX_HEADER_LEN); +} + +static void ondiemet_emi_stop(void) +{ + if (!emi_inited) + return; + + if (do_emi()) + emi_uninit(); +} +#endif +#endif + + +struct metdevice met_sspm_emi = { + .name = "emi", + .owner = THIS_MODULE, + .type = MET_TYPE_BUS, + .create_subfs = met_emi_create, + .delete_subfs = met_emi_delete, + .resume = met_emi_resume, +#if IS_ENABLED(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) +#if defined(ONDIEMET_SUPPORT) || defined(TINYSYS_SSPM_SUPPORT) + .ondiemet_start = ondiemet_emi_start, + .ondiemet_stop = ondiemet_emi_stop, + .ondiemet_print_help = emi_print_help, + .ondiemet_print_header = ondiemet_emi_print_header, +#endif +#endif + .ondiemet_mode = 1, +}; +EXPORT_SYMBOL(met_sspm_emi); diff --git a/drivers/misc/mediatek/met_drv_v2/common/emi/SEDA3_6/mtk_emi_bm.c b/drivers/misc/mediatek/met_drv_v2/common/emi/SEDA3_6/mtk_emi_bm.c new file mode 100644 index 0000000000000000000000000000000000000000..1fb850987da19a2a6cb30f638c03f745711cdb8f --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/emi/SEDA3_6/mtk_emi_bm.c @@ -0,0 +1,932 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2019 MediaTek Inc. + * + */ +#include +#include +#include +#include + +#ifdef USE_KERNEL_SYNC_WRITE_H +#include +#else +#include "sync_write.h" +#endif + +#ifdef USE_KERNEL_MTK_IO_H +#include +#else +#include "mtk_io.h" +#endif + +#include "mtk_typedefs.h" +#include "core_plf_init.h" +#include "mtk_emi_bm.h" + +#ifdef MET_REG_ARRD +#include "met_reg_addr.h" +#endif + +#include "met_drv.h" +#include "interface.h" + +#undef DEBUG +#undef debug_reg +#ifdef debug_reg +static inline unsigned int emi_readl(void __iomem *padr) +{ + unsigned int tmp; + + tmp = readl(padr); + MET_TRACE("[MET_EMI] RD_Reg: %p: %08x\n", padr, tmp); + return tmp; +} + +static inline void __emi_reg_sync_writel(unsigned int data, void __iomem *padr) +{ + unsigned int tmp; + + mt_reg_sync_writel(data, padr); + tmp = readl(padr); + MET_TRACE("[MET_EMI] WR_Reg: %p: %08x, %08x\n", padr, data, tmp); +} + +#define emi_reg_sync_writel(data, adr) __emi_reg_sync_writel(data, IOMEM(adr)) + +#else +#define emi_readl readl +#define emi_reg_sync_writel mt_reg_sync_writel +#endif + +#define MASK_MASTER 0xFF +#define MASK_TRANS_TYPE 0xFF + +/* static int dram_chann_num; */ +static void __iomem *BaseAddrEMI[EMI_NUM_MAX]; +/* static void __iomem *BaseAddrCHN_EMI[2]; */ + +/* static int dramc0_dcm_enable; +static int dramc1_dcm_enable; */ + +#define CH0_MISC_CG_CTRL0 (((unsigned long) BaseAddrDDRPHY_AO[0]) + 0x284) +#define CH1_MISC_CG_CTRL0 (((unsigned long) BaseAddrDDRPHY_AO[1]) + 0x284) +#define CH2_MISC_CG_CTRL0 (((unsigned long) BaseAddrDDRPHY_AO[2]) + 0x284) +#define CH3_MISC_CG_CTRL0 (((unsigned long) BaseAddrDDRPHY_AO[3]) + 0x284) + + +const unsigned int emi_config[] = { + EMI_BMEN, + EMI_MSEL, + EMI_MSEL2, + EMI_MSEL3, + EMI_MSEL4, + EMI_MSEL5, + EMI_MSEL6, + EMI_MSEL7, + EMI_MSEL8, + EMI_MSEL9, + EMI_MSEL10, + EMI_BMID0, + EMI_BMID1, + EMI_BMID2, + EMI_BMID3, + EMI_BMID4, + EMI_BMID5, + EMI_BMID6, + EMI_BMID7, + EMI_BMID8, + EMI_BMID9, + EMI_BMID10, + EMI_BMEN1, + EMI_BMEN2, + EMI_BMRW0, + EMI_BMRW1, + EMI_DBWA, + EMI_DBWB, + EMI_DBWC, + EMI_DBWD, + EMI_DBWE, + EMI_DBWF, + EMI_DBWI, + EMI_DBWJ, + EMI_DBWK, + EMI_DBWA_2ND, + EMI_DBWB_2ND, + EMI_DBWC_2ND, + EMI_DBWD_2ND, + EMI_DBWE_2ND, + EMI_DBWF_2ND, + EMI_TTYPE1_CONA, + EMI_TTYPE1_CONB, + EMI_TTYPE2_CONA, + EMI_TTYPE2_CONB, + EMI_TTYPE3_CONA, + EMI_TTYPE3_CONB, + EMI_TTYPE4_CONA, + EMI_TTYPE4_CONB, + EMI_TTYPE5_CONA, + EMI_TTYPE5_CONB, + EMI_TTYPE6_CONA, + EMI_TTYPE6_CONB, + EMI_TTYPE7_CONA, + EMI_TTYPE7_CONB, + EMI_TTYPE8_CONA, + EMI_TTYPE8_CONB, + EMI_TTYPE9_CONA, + EMI_TTYPE9_CONB, + EMI_TTYPE10_CONA, + EMI_TTYPE10_CONB, + EMI_TTYPE11_CONA, + EMI_TTYPE11_CONB, + EMI_TTYPE12_CONA, + EMI_TTYPE12_CONB, + EMI_TTYPE13_CONA, + EMI_TTYPE13_CONB, + EMI_TTYPE14_CONA, + EMI_TTYPE14_CONB, + EMI_TTYPE15_CONA, + EMI_TTYPE15_CONB, + EMI_TTYPE16_CONA, + EMI_TTYPE16_CONB, + EMI_TTYPE17_CONA, + EMI_TTYPE17_CONB, + EMI_TTYPE18_CONA, + EMI_TTYPE18_CONB, + EMI_TTYPE19_CONA, + EMI_TTYPE19_CONB, + EMI_TTYPE20_CONA, + EMI_TTYPE20_CONB, + EMI_TTYPE21_CONA, + EMI_TTYPE21_CONB +}; +#define EMI_CONFIG_MX_NR (sizeof(emi_config)/sizeof(unsigned int)) +static unsigned int emi_config_val[EMI_NUM][EMI_CONFIG_MX_NR]; + + + +static inline void MET_REG_BCLR(unsigned long reg, u32 shift) +{ + unsigned int read_val = 0; + + read_val = emi_readl(IOMEM(reg)); + emi_reg_sync_writel(read_val & (~((1 << shift) & 0xFFFFFFFF)), reg); +} + + +int MET_BM_Init(void) +{ + /*emi*/ + /*int idx;*/ + unsigned int emi_no; +#ifdef MET_REG_ARRD + for(emi_no=0; emi_no both R/W + * 01 --> only R + * 10 --> only W + */ + volatile unsigned int value; + unsigned int emi_no; + for(emi_no=0; emi_no BM_COUNTER_MAX) + return BM_ERR_WRONG_REQ; + + for(emi_no=0; emi_no 3) + return BM_ERR_WRONG_REQ; + + for(emi_no=0; emi_no BM_COUNTER_MAX) + return BM_ERR_WRONG_REQ; + + for(emi_no=0; emi_no BM_COUNTER_MAX) || (enable > 1)) + return BM_ERR_WRONG_REQ; + + for(emi_no=0; emi_no BM_COUNTER_MAX)) + return BM_ERR_WRONG_REQ; + + for(emi_no=0; emi_no BM_COUNTER_MAX) || (enable > 1)) + return BM_ERR_WRONG_REQ; + + for(emi_no=0; emi_no> 8) & 0x0000003); + } else { + return 1; + } + + if (num == M0_DOUBLE_HALF_BW_1CH) + return 1; + else if (num == M0_DOUBLE_HALF_BW_2CH) + return 2; + else if (num == M0_DOUBLE_HALF_BW_4CH) + return 4; + else /* default return single channel */ + return 1; +} + + +unsigned int MET_EMI_GetDramRankNum(unsigned int emi_no) +{ + int dual_rank = 0; + + if (BaseAddrEMI[emi_no]) { + dual_rank = emi_readl(IOMEM((unsigned long)BaseAddrEMI[emi_no] + EMI_CONA)); + dual_rank = ((dual_rank >> 17) & RANK_MASK); + } else { + return DUAL_RANK; + } + + if (dual_rank == DISABLE_DUAL_RANK_MODE) + return ONE_RANK; + else /* default return dual rank */ + return DUAL_RANK; +} + + +unsigned int MET_EMI_GetDramRankNum_CHN1(unsigned int emi_no) +{ + int dual_rank = 0; + + if (BaseAddrEMI[emi_no]) { + dual_rank = emi_readl(IOMEM((unsigned long)BaseAddrEMI[emi_no] + EMI_CONA)); + dual_rank = ((dual_rank >> 16) & RANK_MASK); + } else { + return DUAL_RANK; + } + + if (dual_rank == DISABLE_DUAL_RANK_MODE) + return ONE_RANK; + else /* default return dual rank */ + return DUAL_RANK; +} + + + +unsigned int MET_EMI_Get_BaseClock_Rate(void) +{ + unsigned int DRAM_TYPE; + + if (get_cur_ddr_ratio_symbol) + return get_cur_ddr_ratio_symbol(); + else { + + if (mtk_dramc_get_ddr_type_symbol) { + DRAM_TYPE = mtk_dramc_get_ddr_type_symbol(); + + if ((DRAM_TYPE == 5) || (DRAM_TYPE == 6) || (DRAM_TYPE == 7)) + return DRAM_EMI_BASECLOCK_RATE_LP4; + else + return DRAM_EMI_BASECLOCK_RATE_LP3; + + } else { + return DRAM_EMI_BASECLOCK_RATE_LP4; + } + } +} + +/* For SEDA3.5 wsct setting*/ +/* EMI_DBWX[15:8], X=A~F (SEL_MASTER) */ +/* RW: EMI_DBWX[1:0], X=A~F */ +int MET_BM_SetWSCT_master_rw(unsigned int *master , unsigned int *rw) +{ + volatile unsigned int value, addr; + int i; + unsigned int emi_no; + + const unsigned int Mask_master = 0xFF; + const unsigned int offset_master = 8; + + const unsigned int Mask_rw = 0x3; + const unsigned int offset_rw = 0; + + for(emi_no=0; emi_no0xffff) { + enable_tmp = 0; + busid_tmp = 0xFFFF; + idmask_tmp = 0xFFFF; + } + else { + enable_tmp = 1; + busid_tmp = *(busid+i) & Mask_busid; + idmask_tmp = *(idMask+i) & Mask_idMask; + } + + + addr = EMI_DBWA + i*4; + value = emi_readl(IOMEM((unsigned long)BaseAddrEMI[emi_no] + addr)); + + value = (value & ~(Mask_busid << offset_busid)) | (busid_tmp << offset_busid); + value = (value & ~(Mask_enable << offset_enable)) | (enable_tmp << offset_enable); + + emi_reg_sync_writel(value, (unsigned long)BaseAddrEMI[emi_no] + addr); + + /*SEL_ID_MSK*/ + addr = EMI_DBWI + (i/2)*4; + + value = emi_readl(IOMEM((unsigned long)BaseAddrEMI[emi_no] + addr)); + + if (i%2==0) + value = (value & ~(Mask_idMask << offset_idMask_even)) | (idmask_tmp << offset_idMask_even); + else + value = (value & ~(Mask_idMask << offset_idMask_odd)) | (idmask_tmp << offset_idMask_odd); + + emi_reg_sync_writel(value, (unsigned long)BaseAddrEMI[emi_no] + addr); + } + } + + return BM_REQ_OK; +} + + +int MET_BM_SetWSCT_chn_rank_sel(unsigned int *chn_rank_sel) +{ + volatile unsigned int value, addr; + int i; + unsigned int emi_no; + + const unsigned int Mask = 0xF; + const unsigned int offset = 12; + + for(emi_no=0; emi_no 0xffff) ? 0 : 1); + + /* set idMask */ + addr = EMI_TTYPE1_CONA + (i-1)*8; + value = emi_readl(IOMEM((unsigned long)BaseAddrEMI[emi_no] + addr)); + + value = (value & ~(Mask_idMask << offset_idMask)) | ((*(idMask+i-1) & Mask_idMask) << offset_idMask); + + emi_reg_sync_writel(value, (unsigned long)BaseAddrEMI[emi_no] + addr); + + } + } + return BM_REQ_OK; +} + + +int MET_BM_SetTtype_chn_rank_sel(unsigned int *chn_rank_sel) +{ + volatile unsigned int value, addr; + int i; + unsigned int emi_no; + + const unsigned int Mask = 0xF; + const unsigned int offset = 16; + + for(emi_no=0; emi_no +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "interface.h" +#include "sampler.h" +#include "util.h" + +#if IS_ENABLED(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) +#if defined(ONDIEMET_SUPPORT) +#include "ondiemet.h" +#elif defined(TINYSYS_SSPM_SUPPORT) +#include "tinysys_mgr.h" +#include "sspm_met_log.h" +#endif +#endif + +#include "met_drv.h" +#include "met_tag.h" +#include "met_kernel_symbol.h" +#include "met_power.h" +#include "met_api.h" +#include "version.h" + +extern int enable_met_backlight_tag(void); +extern int output_met_backlight_tag(int level); + +static int run = -1; +static int sample_rate = 1000; /* Default: 1000 Hz */ +static int met_suspend_compensation_mode; +static int met_suspend_compensation_flag; + +/* + * met_cpu_pmu_method: + * 0: MET pmu driver + * 1: perf APIs + */ +unsigned int met_cpu_pmu_method = 1; +/* + * controls whether re-configuring pmu events after leaving cpu off state + */ +unsigned int met_cpu_pm_pmu_reconfig = 1; + +int met_hrtimer_expire; /* in ns */ +int met_timer_expire; /* in jiffies */ +unsigned int ctrl_flags; +int met_mode; +EXPORT_SYMBOL(met_mode); + +DEFINE_PER_CPU(char[MET_STRBUF_SIZE], met_strbuf_nmi); +EXPORT_SYMBOL(met_strbuf_nmi); + +DEFINE_PER_CPU(char[MET_STRBUF_SIZE], met_strbuf_irq); +EXPORT_SYMBOL(met_strbuf_irq); + +DEFINE_PER_CPU(char[MET_STRBUF_SIZE], met_strbuf_sirq); +EXPORT_SYMBOL(met_strbuf_sirq); + +DEFINE_PER_CPU(char[MET_STRBUF_SIZE], met_strbuf); +EXPORT_SYMBOL(met_strbuf); + +static void calc_timer_value(int rate) +{ + sample_rate = rate; + + if (rate == 0) { + met_hrtimer_expire = 0; + met_timer_expire = 0; + return; + } + + met_hrtimer_expire = 1000000000 / rate; + + /* Case 1: hrtimer < 1 OS tick, met_timer_expire = 1 OS tick */ + if (rate > HZ) + met_timer_expire = 1; + /* Case 2: hrtimer > 1 OS tick, met_timer_expire is hrtimer + 1 OS tick */ + else + met_timer_expire = (HZ / rate) + 1; + + /* pr_debug("JBK HZ=%d, met_hrtimer_expire=%d ns, met_timer_expire=%d ticks\n", */ + /* HZ, met_hrtimer_expire, met_timer_expire); */ +} + +int met_parse_num(const char *str, unsigned int *value, int len) +{ + int ret; + + if (len <= 0) + return -1; + + if ((len > 2) && + ((str[0] == '0') && + ((str[1] == 'x') || (str[1] == 'X')))) { + ret = kstrtoint(str, 16, value); + } else { + ret = kstrtoint(str, 10, value); + } + + if (ret != 0) + return -1; + + return 0; +} + +void met_set_suspend_notify(int flag) +{ + if (met_suspend_compensation_mode == 1) + met_suspend_compensation_flag = flag; + else + met_suspend_compensation_flag = 0; +} + +LIST_HEAD(met_list); +static struct kobject *kobj_misc; +static struct kobject *kobj_pmu; +static struct kobject *kobj_bus; + +static ssize_t ver_show(struct device *dev, struct device_attribute *attr, char *buf); +static DEVICE_ATTR(ver, 0444, ver_show, NULL); + +static ssize_t plf_show(struct device *dev, struct device_attribute *attr, char *buf); +static DEVICE_ATTR(plf, 0444, plf_show, NULL); + +static ssize_t chip_id_show(struct device *dev, struct device_attribute *attr, char *buf); +static DEVICE_ATTR(chip_id, 0444, chip_id_show, NULL); + +static ssize_t core_topology_show(struct device *dev, struct device_attribute *attr, char *buf); +static DEVICE_ATTR(core_topology, 0444, core_topology_show, NULL); + +static ssize_t devices_show(struct device *dev, struct device_attribute *attr, char *buf); +static DEVICE_ATTR(devices, 0444, devices_show, NULL); + +static ssize_t ctrl_show(struct device *dev, struct device_attribute *attr, char *buf); +static ssize_t ctrl_store(struct device *dev, struct device_attribute *attr, const char *buf, + size_t count); +static DEVICE_ATTR(ctrl, 0664, ctrl_show, ctrl_store); + +static ssize_t spr_show(struct device *dev, struct device_attribute *attr, char *buf); +static ssize_t spr_store(struct device *dev, struct device_attribute *attr, const char *buf, + size_t count); +static DEVICE_ATTR(sample_rate, 0664, spr_show, spr_store); + +static ssize_t run_show(struct device *dev, struct device_attribute *attr, char *buf); +static ssize_t run_store(struct device *dev, struct device_attribute *attr, const char *buf, + size_t count); +static DEVICE_ATTR(run, 0664, run_show, run_store); + +static ssize_t ksym_show(struct device *dev, struct device_attribute *attr, char *buf); +static ssize_t ksym_store(struct device *dev, struct device_attribute *attr, const char *buf, + size_t count); +static DEVICE_ATTR(ksym, 0664, ksym_show, ksym_store); + +static ssize_t cpu_pmu_method_show(struct device *dev, struct device_attribute *attr, char *buf); +static ssize_t cpu_pmu_method_store(struct device *dev, struct device_attribute *attr, const char *buf, + size_t count); +static DEVICE_ATTR(cpu_pmu_method, 0664, cpu_pmu_method_show, cpu_pmu_method_store); + +static ssize_t cpu_pm_pmu_reconfig_show(struct device *dev, + struct device_attribute *attr, + char *buf); +static ssize_t cpu_pm_pmu_reconfig_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count); +static DEVICE_ATTR(cpu_pm_pmu_reconfig, + 0664, + cpu_pm_pmu_reconfig_show, + cpu_pm_pmu_reconfig_store); + +#ifdef PR_CPU_NOTIFY +int met_cpu_notify; +static ssize_t cpu_notify_show(struct device *dev, struct device_attribute *attr, char *buf); +static ssize_t cpu_notify_store(struct device *dev, struct device_attribute *attr, const char *buf, + size_t count); +static DEVICE_ATTR(cpu_notify, 0664, cpu_notify_show, cpu_notify_store); +#endif + +#if IS_ENABLED(CONFIG_CPU_FREQ) +static ssize_t dvfs_show(struct device *dev, struct device_attribute *attr, char *buf); +static ssize_t dvfs_store(struct device *dev, struct device_attribute *attr, const char *buf, + size_t count); +static DEVICE_ATTR(dvfs, 0664, dvfs_show, dvfs_store); +#endif + +static ssize_t suspend_compensation_enable_show(struct device *dev, struct device_attribute *attr, char *buf); +static ssize_t suspend_compensation_enable_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count); +static DEVICE_ATTR(suspend_compensation_enable, 0664, suspend_compensation_enable_show, + suspend_compensation_enable_store); + +static ssize_t suspend_compensation_flag_show(struct device *dev, struct device_attribute *attr, char *buf); +static DEVICE_ATTR(suspend_compensation_flag, 0444, suspend_compensation_flag_show, NULL); + +static ssize_t ipi_test_store(struct device *dev, struct device_attribute *attr, const char *buf, + size_t count); +static DEVICE_ATTR(ipi_test, 0220, NULL, ipi_test_store); + +static const struct file_operations met_file_ops = { + .owner = THIS_MODULE +}; + +struct miscdevice met_device = { + .minor = MISC_DYNAMIC_MINOR, + .name = "met", + .mode = 0664, + .fops = &met_file_ops +}; +EXPORT_SYMBOL(met_device); + +static int met_run(void) +{ + sampler_start(); +#ifdef MET_USER_EVENT_SUPPORT + bltab.flag &= (~MET_CLASS_ALL); +#endif + +#if IS_ENABLED(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) +#if defined(ONDIEMET_SUPPORT) || defined(TINYSYS_SSPM_SUPPORT) + ondiemet_start(); +#endif +#endif + + return 0; +} + +static void met_stop(void) +{ +#ifdef MET_USER_EVENT_SUPPORT + bltab.flag |= MET_CLASS_ALL; +#endif + sampler_stop(); + +#if IS_ENABLED(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) +#if defined(ONDIEMET_SUPPORT) || defined(TINYSYS_SSPM_SUPPORT) + /* the met.ko will be use by script "cat ...", release it */ + if ((ondiemet_module[ONDIEMET_SSPM] == 0) || (sspm_buffer_size == -1)) + ondiemet_log_manager_stop(); + ondiemet_stop(); + ondiemet_extract(); +#endif +#endif +} + +static ssize_t ver_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int i; + + mutex_lock(&dev->mutex); + i = snprintf(buf, PAGE_SIZE, "%s\n", MET_BACKEND_VERSION); + mutex_unlock(&dev->mutex); + return i; +} + +static ssize_t devices_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int len, total_len = 0; + struct metdevice *c = NULL; + + mutex_lock(&dev->mutex); + list_for_each_entry(c, &met_list, list) { + len = 0; + if (c->type == MET_TYPE_PMU) + len = snprintf(buf, PAGE_SIZE - total_len, "pmu/%s:0\n", c->name); + else if (c->type == MET_TYPE_BUS) + len = snprintf(buf, PAGE_SIZE - total_len, "bus/%s:0\n", c->name); + else if (c->type == MET_TYPE_MISC) + len = snprintf(buf, PAGE_SIZE - total_len, "misc/%s:0\n", c->name); + + if (c->ondiemet_mode == 0) { + if (c->process_argument) + buf[len - 2]++; + } else if (c->ondiemet_mode == 1) { + if (c->ondiemet_process_argument) + buf[len - 2]++; + } else if (c->ondiemet_mode == 2) { + if (c->process_argument) + buf[len - 2]++; + if (c->ondiemet_process_argument) + buf[len - 2]++; + } + + buf += len; + total_len += len; + } + + mutex_unlock(&dev->mutex); + return total_len; +} + +static char met_platform[16] = "none"; +static ssize_t plf_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int i; + + mutex_lock(&dev->mutex); + i = snprintf(buf, PAGE_SIZE, "%s\n", met_platform); + mutex_unlock(&dev->mutex); + return i; +} + +static unsigned int met_chip_id = 0; +static ssize_t chip_id_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int i; + + mutex_lock(&dev->mutex); + i = snprintf(buf, PAGE_SIZE, "0x%08X\n", met_chip_id); + mutex_unlock(&dev->mutex); + return i; +} + +static char met_topology[64] = "none"; +static ssize_t core_topology_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int i; + + mutex_lock(&dev->mutex); + i = snprintf(buf, PAGE_SIZE, "%s\n", met_topology); + mutex_unlock(&dev->mutex); + return i; +} + +static ssize_t ctrl_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", ctrl_flags); +} + +static ssize_t ctrl_store(struct device *dev, struct device_attribute *attr, const char *buf, + size_t count) +{ + unsigned int value = 0; + + if (met_parse_num(buf, &value, count) < 0) + return -EINVAL; + + ctrl_flags = value; + return count; +} + +static ssize_t cpu_pmu_method_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", met_cpu_pmu_method); +} + +static ssize_t cpu_pmu_method_store(struct device *dev, struct device_attribute *attr, const char *buf, + size_t count) +{ + unsigned int value; + + if (met_parse_num(buf, &value, count) < 0) + return -EINVAL; + + met_cpu_pmu_method = value; + return count; +} + +static ssize_t cpu_pm_pmu_reconfig_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", met_cpu_pm_pmu_reconfig); +} + +static ssize_t cpu_pm_pmu_reconfig_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + unsigned int value; + + if (met_parse_num(buf, &value, count) < 0) + return -EINVAL; + + met_cpu_pm_pmu_reconfig = value; + return count; +} + +static void _test_trace_ipi_raise(void *info) +{ + unsigned int *cpu = (unsigned int *)info; + + if (met_export_api_symbol->met_arch_send_call_function_single_ipi) + met_export_api_symbol->met_arch_send_call_function_single_ipi(*cpu); +} + + +static ssize_t ipi_test_store(struct device *dev, struct device_attribute *attr, const char *buf, + size_t count) +{ + int this_cpu = smp_processor_id(); + unsigned int cpu = 0; + unsigned int value; + + if (met_parse_num(buf, &value, count) < 0) + return -EINVAL; + + cpu = value; + if (cpu == this_cpu) + _test_trace_ipi_raise(&cpu); + else { + if (met_export_api_symbol->met_smp_call_function_single) + met_export_api_symbol->met_smp_call_function_single(cpu, + _test_trace_ipi_raise, &cpu, 1); + } + + return count; +} + + +#if defined(MET_BOOT_MSG) +char met_boot_msg_tmp[256]; +char met_boot_msg[PAGE_SIZE]; +int met_boot_msg_idx; + +int pr_bootmsg(int str_len, char *str) +{ + if (met_boot_msg_idx+str_len+1 > PAGE_SIZE) + return -1; + memcpy(met_boot_msg+met_boot_msg_idx, str, str_len); + met_boot_msg_idx += str_len; + return 0; +} + +static ssize_t bootmsg_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int i; + + mutex_lock(&dev->mutex); + i = snprintf(buf, PAGE_SIZE, "%s\n", met_boot_msg); + mutex_unlock(&dev->mutex); + return i; +} + +static DEVICE_ATTR_RO(bootmsg); +EXPORT_SYMBOL(met_boot_msg_tmp); +EXPORT_SYMBOL(pr_bootmsg); +#endif + +static ssize_t spr_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int i; + + mutex_lock(&dev->mutex); + i = snprintf(buf, PAGE_SIZE, "%d\n", sample_rate); + mutex_unlock(&dev->mutex); + return i; +} + +static ssize_t spr_store(struct device *dev, struct device_attribute *attr, const char *buf, + size_t count) +{ + int value; + struct metdevice *c = NULL; + + mutex_lock(&dev->mutex); + + if ((run == 1) || (count == 0) || (buf == NULL)) { + mutex_unlock(&dev->mutex); + return -EINVAL; + } + if (kstrtoint(buf, 0, &value) != 0) { + mutex_unlock(&dev->mutex); + return -EINVAL; + } + + if ((value < 0) || (value > 10000)) { + mutex_unlock(&dev->mutex); + return -EINVAL; + } + + calc_timer_value(value); + + list_for_each_entry(c, &met_list, list) { + if (c->polling_interval > 0) + c->polling_count_reload = ((c->polling_interval * sample_rate) - 1) / 1000; + else + c->polling_count_reload = 0; + } + + mutex_unlock(&dev->mutex); + + return count; +} + +static ssize_t run_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int i; + + mutex_lock(&dev->mutex); + i = snprintf(buf, PAGE_SIZE, "%d\n", run); + mutex_unlock(&dev->mutex); + return i; +} + +static ssize_t run_store(struct device *dev, struct device_attribute *attr, const char *buf, + size_t count) +{ + int value; + + mutex_lock(&dev->mutex); + + if ((count == 0) || (buf == NULL)) { + mutex_unlock(&dev->mutex); + return -EINVAL; + } + if (kstrtoint(buf, 0, &value) != 0) { + mutex_unlock(&dev->mutex); + return -EINVAL; + } + + switch (value) { + case 1: + if (run != 1) { + run = 1; + met_run(); + } + break; + case 0: + if (run != 0) { + if (run == 1) { + met_stop(); +#ifdef MET_USER_EVENT_SUPPORT +#ifdef CONFIG_MET_MODULE + met_save_dump_buffer_real("/data/trace.dump"); +#else + met_save_dump_buffer("/data/trace.dump"); +#endif +#endif + run = 0; + } else + /* run == -1 */ + run = 0; + } + break; + case -1: + if (run != -1) { + if (run == 1) + met_stop(); + + run = -1; + } + break; + default: + mutex_unlock(&dev->mutex); + return -EINVAL; + } + + mutex_unlock(&dev->mutex); + + return count; +} + +static unsigned int met_ksym_addr; +static char met_func_name[512]; +static ssize_t ksym_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int i; + int len = 0; + int idx = 0; + + mutex_lock(&dev->mutex); + if (met_ksym_addr != 0) + len = sprint_symbol_no_offset(met_func_name, met_ksym_addr); + if (len != 0) { + for (idx = 0; idx < 512; idx++) + if (met_func_name[idx] == ' ') + met_func_name[idx] = '\0'; + i = snprintf(buf, PAGE_SIZE, "%s\n", met_func_name); + } else + i = snprintf(buf, PAGE_SIZE, "ksymlookup fail(%x)\n", met_ksym_addr); + + mutex_unlock(&dev->mutex); + return i; +} + +static ssize_t ksym_store(struct device *dev, struct device_attribute *attr, const char *buf, + size_t count) +{ + mutex_lock(&dev->mutex); + + if ((count == 0) || (buf == NULL)) { + mutex_unlock(&dev->mutex); + return -EINVAL; + } + if (kstrtoint(buf, 16, &met_ksym_addr) != 0) { + mutex_unlock(&dev->mutex); + return -EINVAL; + } + + mutex_unlock(&dev->mutex); + + return count; +} + +#if defined(PR_CPU_NOTIFY) +static ssize_t cpu_notify_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int i; + + i = snprintf(buf, PAGE_SIZE, "%d\n", met_cpu_notify); + return i; +} + +static ssize_t cpu_notify_store(struct device *dev, struct device_attribute *attr, const char *buf, + size_t count) +{ + if ((count == 0) || (buf == NULL)) + return -EINVAL; + + if (kstrtoint(buf, 0, &met_cpu_notify) != 0) + return -EINVAL; + + return count; +} +#endif + +#if IS_ENABLED(CONFIG_CPU_FREQ) +static ssize_t dvfs_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int i; + + i = snprintf(buf, PAGE_SIZE, "%d\n", 0); + return i; +} + +static ssize_t dvfs_store(struct device *dev, struct device_attribute *attr, const char *buf, + size_t count) +{ + return count; +} +#endif + +static ssize_t suspend_compensation_enable_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int ret; + + ret = snprintf(buf, PAGE_SIZE, "%d\n", met_suspend_compensation_mode); + + return ret; +} + +static ssize_t suspend_compensation_enable_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + int value; + + if ((count == 0) || (buf == NULL)) + return -EINVAL; + + if (kstrtoint(buf, 0, &value) != 0) + return -EINVAL; + + if (value < 0) + return -EINVAL; + + met_suspend_compensation_mode = value; + + return count; +} + +static ssize_t suspend_compensation_flag_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int ret; + + ret = snprintf(buf, PAGE_SIZE, "%d\n", met_suspend_compensation_flag); + + return ret; +} + +static ssize_t hash_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + return 0; +} + +static ssize_t hash_store(struct device *dev, struct device_attribute *attr, const char *buf, + size_t count) +{ + return 0; +} + +static DEVICE_ATTR(hash, 0664, hash_show, hash_store); + +static ssize_t mode_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + struct metdevice *c = NULL; + + list_for_each_entry(c, &met_list, list) { + if (c->kobj == kobj) + break; + } + if (c == NULL) + return -ENOENT; + + return snprintf(buf, PAGE_SIZE, "%d\n", c->mode); +} + +static ssize_t mode_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, + size_t n) +{ + struct metdevice *c = NULL; + + list_for_each_entry(c, &met_list, list) { + if (c->kobj == kobj) + break; + } + if (c == NULL) + return -ENOENT; + + if (kstrtoint(buf, 0, &(c->mode)) != 0) + return -EINVAL; + + return n; +} + +static struct kobj_attribute mode_attr = __ATTR(mode, 0664, mode_show, mode_store); + +#if IS_ENABLED(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) +#if defined(ONDIEMET_SUPPORT) || defined(TINYSYS_SSPM_SUPPORT) +static ssize_t ondiemet_mode_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + struct metdevice *c = NULL; + + list_for_each_entry(c, &met_list, list) { + if (c->kobj == kobj) + break; + } + if (c == NULL) + return -ENOENT; + + return snprintf(buf, PAGE_SIZE, "%d\n", c->ondiemet_mode); +} + +static ssize_t ondiemet_mode_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, + size_t n) +{ + struct metdevice *c = NULL; + + list_for_each_entry(c, &met_list, list) { + if (c->kobj == kobj) + break; + } + if (c == NULL) + return -ENOENT; + + if (kstrtoint(buf, 0, &(c->ondiemet_mode)) != 0) + return -EINVAL; + + return n; +} + +static struct kobj_attribute ondiemet_mode_attr = __ATTR(ondiemet_mode, 0664, ondiemet_mode_show, ondiemet_mode_store); +#endif +#endif + +static ssize_t polling_interval_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + int interval = 1; + struct metdevice *c = NULL; + + list_for_each_entry(c, &met_list, list) { + if (c->kobj == kobj) + break; + } + if (c == NULL) + return -ENOENT; + + if (c->polling_interval) + interval = c->polling_interval; + + return snprintf(buf, PAGE_SIZE, "%d\n", interval); +} + +static ssize_t polling_interval_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t n) +{ + struct metdevice *c = NULL; + + list_for_each_entry(c, &met_list, list) { + if (c->kobj == kobj) + break; + } + if (c == NULL) + return -ENOENT; + + if (kstrtoint(buf, 0, &(c->polling_interval)) != 0) + return -EINVAL; + + if (c->polling_interval > 0) + c->polling_count_reload = ((c->polling_interval * sample_rate) - 1) / 1000; + else + c->polling_count_reload = 0; + + return n; +} + +static struct kobj_attribute polling_interval_attr = +__ATTR(polling_ms, 0664, polling_interval_show, polling_interval_store); + +static ssize_t header_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + struct metdevice *c = NULL; + ssize_t count = 0; + + list_for_each_entry(c, &met_list, list) { + if (c->kobj == kobj) + break; + } + if (c == NULL) + return -ENOENT; + + if (c->ondiemet_mode == 0) { + if ((c->mode) && (c->print_header)) + return c->print_header(buf, PAGE_SIZE); + } else if (c->ondiemet_mode == 1) { + if ((c->mode) && (c->ondiemet_print_header)) + return c->ondiemet_print_header(buf, PAGE_SIZE); + } else if (c->ondiemet_mode == 2) { + if ((c->mode) && (c->print_header)) + count = c->print_header(buf, PAGE_SIZE); + if (count < PAGE_SIZE) { + if ((c->mode) && (c->ondiemet_print_header)) + count += c->ondiemet_print_header(buf+count, PAGE_SIZE - count); + } + return count; + } + + return 0; +} + +static struct kobj_attribute header_attr = __ATTR(header, 0444, header_show, NULL); + +static ssize_t help_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + struct metdevice *c = NULL; + ssize_t count = 0; + + list_for_each_entry(c, &met_list, list) { + if (c->kobj == kobj) + break; + } + if (c == NULL) + return -ENOENT; + + if (c->ondiemet_mode == 0) { + if (c->print_help) + return c->print_help(buf, PAGE_SIZE); + } else if (c->ondiemet_mode == 1) { + if (c->ondiemet_print_help) + return c->ondiemet_print_help(buf, PAGE_SIZE); + } else if (c->ondiemet_mode == 2) { + if (c->print_help) + count = c->print_help(buf, PAGE_SIZE); + if (count < PAGE_SIZE) { + if (c->ondiemet_print_help) + count += c->ondiemet_print_help(buf+count, PAGE_SIZE - count); + } + return count; + } + + return 0; +} + +static struct kobj_attribute help_attr = __ATTR(help, 0444, help_show, NULL); + +static int argu_status = -1; +static ssize_t argu_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, + size_t n) +{ + int ret = 0; + struct metdevice *c = NULL; + + argu_status = -1; + + list_for_each_entry(c, &met_list, list) { + if (c->kobj == kobj) + break; + } + if (c == NULL) + return -ENOENT; + + if (c->ondiemet_mode == 0) { + if (c->process_argument) + ret = c->process_argument(buf, (int)n); + } else if (c->ondiemet_mode == 1) { + if (c->ondiemet_process_argument) + ret = c->ondiemet_process_argument(buf, (int)n); + } else if (c->ondiemet_mode == 2) { + if (c->process_argument) + ret = c->process_argument(buf, (int)n); + if (c->ondiemet_process_argument) + ret = c->ondiemet_process_argument(buf, (int)n); + } + + if (ret != 0) + return -EINVAL; + + argu_status = 0; + return n; +} + +static ssize_t argu_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", argu_status); +} + +static struct kobj_attribute argu_attr = __ATTR(argu, 0664, argu_show, argu_store); + +static ssize_t reset_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t n) +{ + int ret = 0; + struct metdevice *c = NULL; + + list_for_each_entry(c, &met_list, list) { + if (c->kobj == kobj) + break; + } + if (c == NULL) + return -ENOENT; + + if (c->ondiemet_mode == 0) { + if (c->reset) + ret = c->reset(); + else + c->mode = 0; + } else if (c->ondiemet_mode == 1) { + if (c->ondiemet_reset) + ret = c->ondiemet_reset(); + } else if (c->ondiemet_mode == 2) { + if (c->reset) + ret = c->reset(); + else + c->mode = 0; + if (c->ondiemet_reset) + ret = c->ondiemet_reset(); + } + + if (ret != 0) + return -EINVAL; + + return n; +} + +static struct kobj_attribute reset_attr = __ATTR(reset, 0220, NULL, reset_store); + +static ssize_t header_read_again_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + struct metdevice *c = NULL; + + list_for_each_entry(c, &met_list, list) { + if (c->kobj == kobj) + break; + } + if (c == NULL) + return -ENOENT; + + return snprintf(buf, PAGE_SIZE, "%d\n", c->header_read_again); +} + +static struct kobj_attribute header_read_again_attr = __ATTR(header_read_again, 0664, header_read_again_show, NULL); + + +int met_register(struct metdevice *met) +{ + int ret, cpu; + struct metdevice *c; + + list_for_each_entry(c, &met_list, list) { + if (!strcmp(c->name, met->name)) + return -EEXIST; + } + + PR_BOOTMSG("met_register %s ...\n", met->name); + + INIT_LIST_HEAD(&met->list); + + /* Allocate timer count for per CPU */ + met->polling_count = alloc_percpu(int); + if (met->polling_count == NULL) + return -EINVAL; + + for_each_possible_cpu(cpu) + *(per_cpu_ptr(met->polling_count, cpu)) = 0; + + if (met->polling_interval > 0) { + ret = ((met->polling_interval * sample_rate) - 1) / 1000; + met->polling_count_reload = ret; + } else + met->polling_count_reload = 0; + + met->kobj = NULL; + + if (met->type == MET_TYPE_BUS) + met->kobj = kobject_create_and_add(met->name, kobj_bus); + else if (met->type == MET_TYPE_PMU) + met->kobj = kobject_create_and_add(met->name, kobj_pmu); + else if (met->type == MET_TYPE_MISC) + met->kobj = kobject_create_and_add(met->name, kobj_misc); + else { + ret = -EINVAL; + goto err_out; + } + + if (met->kobj == NULL) { + ret = -EINVAL; + goto err_out; + } + + if (met->create_subfs) { + ret = met->create_subfs(met->kobj); + if (ret) + goto err_out; + } + + ret = sysfs_create_file(met->kobj, &mode_attr.attr); + if (ret) + goto err_out; + +#if IS_ENABLED(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) +#if defined(ONDIEMET_SUPPORT) || defined(TINYSYS_SSPM_SUPPORT) + ret = sysfs_create_file(met->kobj, &ondiemet_mode_attr.attr); + if (ret) + goto err_out; +#endif +#endif + + ret = sysfs_create_file(met->kobj, &polling_interval_attr.attr); + if (ret) + goto err_out; + + ret = sysfs_create_file(met->kobj, &header_read_again_attr.attr); + if (ret) + goto err_out; + + if (met->print_header || met->ondiemet_print_header) { + ret = sysfs_create_file(met->kobj, &header_attr.attr); + if (ret) + goto err_out; + } + + if (met->print_help || met->ondiemet_print_help) { + ret = sysfs_create_file(met->kobj, &help_attr.attr); + if (ret) + goto err_out; + } + + if (met->process_argument || met->ondiemet_process_argument) { + ret = sysfs_create_file(met->kobj, &argu_attr.attr); + if (ret) + goto err_out; + } + + if (met->reset) { + ret = sysfs_create_file(met->kobj, &reset_attr.attr); + if (ret) + goto err_out; + } + + spin_lock_init(&met->my_lock); + + list_add(&met->list, &met_list); + return 0; + + err_out: + + if (met->polling_count) + free_percpu(met->polling_count); + + if (met->kobj) { + kobject_del(met->kobj); + kobject_put(met->kobj); + met->kobj = NULL; + } + + return ret; +} +EXPORT_SYMBOL(met_register); + +int met_deregister(struct metdevice *met) +{ + struct metdevice *c = NULL; + + list_for_each_entry(c, &met_list, list) { + if (c == met) + break; + } + if (c != met) + return -ENOENT; + + if (met->print_header || met->ondiemet_print_header) + sysfs_remove_file(met->kobj, &header_attr.attr); + + if (met->print_help || met->ondiemet_print_help) + sysfs_remove_file(met->kobj, &help_attr.attr); + + if (met->process_argument || met->ondiemet_process_argument) + sysfs_remove_file(met->kobj, &argu_attr.attr); + + sysfs_remove_file(met->kobj, &reset_attr.attr); + sysfs_remove_file(met->kobj, &header_read_again_attr.attr); + sysfs_remove_file(met->kobj, &polling_interval_attr.attr); + sysfs_remove_file(met->kobj, &mode_attr.attr); +#if IS_ENABLED(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) +#if defined(ONDIEMET_SUPPORT) || defined(TINYSYS_SSPM_SUPPORT) + sysfs_remove_file(met->kobj, &ondiemet_mode_attr.attr); +#endif +#endif + + if (met->delete_subfs) + met->delete_subfs(); + + kobject_del(met->kobj); + kobject_put(met->kobj); + met->kobj = NULL; + + if (met->polling_count) + free_percpu(met->polling_count); + + list_del(&met->list); + return 0; +} +EXPORT_SYMBOL(met_deregister); + +int met_set_platform(const char *plf_name, int flag) +{ + strncpy(met_platform, plf_name, sizeof(met_platform) - 1); +#if 0 + int ret; + + if (flag) { + ret = device_create_file(met_device.this_device, &dev_attr_plf); + if (ret != 0) { + pr_debug("can not create device file: plf\n"); + return ret; + } + strncpy(met_platform, plf_name, sizeof(met_platform) - 1); + } else + device_remove_file(met_device.this_device, &dev_attr_plf); + +#endif + return 0; +} +EXPORT_SYMBOL(met_set_platform); + +char *met_get_platform(void) +{ + return met_platform; +} +EXPORT_SYMBOL(met_get_platform); + +int met_set_chip_id(const unsigned int chip_id) +{ + met_chip_id = chip_id; + + return 0; +} +EXPORT_SYMBOL(met_set_chip_id); + +const unsigned int met_get_chip_id(void) +{ + return met_chip_id; +} +EXPORT_SYMBOL(met_get_chip_id); + +unsigned int met_get_chipid_from_atag(void) +{ + struct device_node *chosen_node; + struct tag_chipid *chip_id; + int len; + + chosen_node = of_find_node_by_path("/chosen"); + if (!chosen_node) + chosen_node = of_find_node_by_path("/chosen@0"); + + if (chosen_node) { + chip_id = (struct tag_chipid*) of_get_property(chosen_node, "atag,chipid", &len); + if (chip_id == NULL) { + PR_BOOTMSG("Warning: could not found atag,chipid in chosen\n"); + return -1; + } + } else { + PR_BOOTMSG("Warning: chosen node not found in device tree\n"); + return -1; + } + + return chip_id->hw_code; +} + +int met_set_topology(const char *topology_name, int flag) +{ + strncpy(met_topology, topology_name, sizeof(met_topology) - 1); +#if 0 + int ret; + + if (flag) { + ret = device_create_file(met_device.this_device, &dev_attr_core_topology); + if (ret != 0) { + pr_debug("can not create device file: topology\n"); + return ret; + } + strncpy(met_topology, topology_name, sizeof(met_topology) - 1); + } else { + device_remove_file(met_device.this_device, &dev_attr_core_topology); + } +#endif + return 0; +} +EXPORT_SYMBOL(met_set_topology); + +#include "met_struct.h" + +void force_sample(void *unused) +{ + int cpu; + unsigned long long stamp; + struct metdevice *c; + struct met_cpu_struct *met_cpu_ptr; + + if ((run != 1) || (sample_rate == 0)) + return; + + /* to avoid met tag is coming after __met_hrtimer_stop and before run=-1 */ + met_cpu_ptr = this_cpu_ptr(&met_cpu); + if (met_cpu_ptr->work_enabled == 0) + return; + + cpu = smp_processor_id(); + + stamp = cpu_clock(cpu); + + list_for_each_entry(c, &met_list, list) { + if (c->ondiemet_mode == 0) { + if ((c->mode != 0) && (c->tagged_polling != NULL)) + c->tagged_polling(stamp, 0); + } else if (c->ondiemet_mode == 1) { + if ((c->mode != 0) && (c->ondiemet_tagged_polling != NULL)) + c->ondiemet_tagged_polling(stamp, 0); + } else if (c->ondiemet_mode == 2) { + if ((c->mode != 0) && (c->tagged_polling != NULL)) + c->tagged_polling(stamp, 0); + if ((c->mode != 0) && (c->ondiemet_tagged_polling != NULL)) + c->ondiemet_tagged_polling(stamp, 0); + } + } +} + +#define MET_SUSPEND_HAND +#ifdef MET_SUSPEND_HAND +static struct syscore_ops met_hrtimer_ops = { + .suspend = met_hrtimer_suspend, + .resume = met_hrtimer_resume, +}; +#endif + +int fs_reg(int met_minor) +{ + int ret = -1; + + ctrl_flags = 0; + met_mode = 0; + +#ifdef MET_SUSPEND_HAND + /* suspend/resume function handle register */ + register_syscore_ops(&met_hrtimer_ops); +#endif + + calc_timer_value(sample_rate); + + if ( met_minor != -1) + met_device.minor = met_minor; + ret = misc_register(&met_device); + if (ret != 0) { + pr_debug("misc register failed, minor = %d \n", met_device.minor); + return ret; + } + + /* dma map config */ + /* arch_setup_dma_ops(met_device.this_device, 0, 0, NULL, false); */ + if (met_export_api_symbol->met_arch_setup_dma_ops) + met_export_api_symbol->met_arch_setup_dma_ops(met_device.this_device); + + ret = device_create_file(met_device.this_device, &dev_attr_ksym); + if (ret != 0) { + pr_debug("can not create device file: ksym\n"); + return ret; + } + + ret = device_create_file(met_device.this_device, &dev_attr_run); + if (ret != 0) { + pr_debug("can not create device file: run\n"); + return ret; + } + +#if defined(PR_CPU_NOTIFY) + ret = device_create_file(met_device.this_device, &dev_attr_cpu_notify); + if (ret != 0) { + pr_debug("can not create device file: cpu_notify\n"); + return ret; + } +#endif + +#if IS_ENABLED(CONFIG_CPU_FREQ) + ret = device_create_file(met_device.this_device, &dev_attr_dvfs); + if (ret != 0) { + pr_debug("can not create device file: dvfs\n"); + return ret; + } +#endif + + ret = device_create_file(met_device.this_device, &dev_attr_suspend_compensation_enable); + if (ret != 0) { + pr_debug("can not create device file: suspend_compensation_enable\n"); + return ret; + } + + ret = device_create_file(met_device.this_device, &dev_attr_suspend_compensation_flag); + if (ret != 0) { + pr_debug("can not create device file: suspend_compensation_enable\n"); + return ret; + } + + ret = device_create_file(met_device.this_device, &dev_attr_ver); + if (ret != 0) { + pr_debug("can not create device file: ver\n"); + return ret; + } + + ret = device_create_file(met_device.this_device, &dev_attr_devices); + if (ret != 0) { + pr_debug("can not create device file: devices\n"); + return ret; + } + + ret = device_create_file(met_device.this_device, &dev_attr_ctrl); + if (ret != 0) { + pr_debug("can not create device file: ctrl\n"); + return ret; + } + + ret = device_create_file(met_device.this_device, &dev_attr_cpu_pmu_method); + if (ret != 0) { + pr_debug("can not create device file: cpu_pmu_method\n"); + return ret; + } + + ret = device_create_file(met_device.this_device, &dev_attr_cpu_pm_pmu_reconfig); + if (ret != 0) { + pr_debug("can not create device file: cpu_pm_pmu_reconfig\n"); + return ret; + } + +#if defined(MET_BOOT_MSG) + ret = device_create_file(met_device.this_device, &dev_attr_bootmsg); + if (ret != 0) { + pr_debug("can not create device file: bootmsg\n"); + return ret; + } +#endif + + ret = device_create_file(met_device.this_device, &dev_attr_sample_rate); + if (ret != 0) { + pr_debug("can not create device file: sample_rate\n"); + return ret; + } + + ret = device_create_file(met_device.this_device, &dev_attr_core_topology); + if (ret != 0) { + pr_debug("can not create device file: topology\n"); + return ret; + } + + ret = device_create_file(met_device.this_device, &dev_attr_plf); + if (ret != 0) { + pr_debug("can not create device file: plf\n"); + return ret; + } + + ret = device_create_file(met_device.this_device, &dev_attr_chip_id); + if (ret != 0) { + pr_debug("can not create device file: chip_id\n"); + return ret; + } + + ret = device_create_file(met_device.this_device, &dev_attr_hash); + if (ret != 0) { + pr_debug("can not create device file: hash\n"); + return ret; + } + + ret = device_create_file(met_device.this_device, &dev_attr_ipi_test); + if (ret != 0) { + pr_debug("can not create device file: ipi_test\n"); + return ret; + } + + kobj_misc = kobject_create_and_add("misc", &met_device.this_device->kobj); + if (kobj_misc == NULL) { + pr_debug("can not create kobject: kobj_misc\n"); + return -1; + } + + kobj_pmu = kobject_create_and_add("pmu", &met_device.this_device->kobj); + if (kobj_pmu == NULL) { + pr_debug("can not create kobject: kobj_pmu\n"); + return -1; + } + + kobj_bus = kobject_create_and_add("bus", &met_device.this_device->kobj); + if (kobj_bus == NULL) { + pr_debug("can not create kobject: kobj_bus\n"); + return -1; + } + + met_register(&met_cookie); + met_register(&met_cpupmu); + met_register(&met_memstat); + met_register(&met_switch); + met_register_api_symbol->met_sched_switch = met_sched_switch; +#ifdef MET_EVENT_POWER_SUPPORT + met_register(&met_trace_event); + met_register_api_symbol->met_pm_qos_update_request = pm_qos_update_request; + met_register_api_symbol->met_pm_qos_update_target = pm_qos_update_target; +#endif + + met_register(&met_dummy_header); +#ifdef FEATURE_MCUPM_NUM +#if FEATURE_MCUPM_NUM + met_register(&met_mcupm); +#endif +#endif + +#ifdef MET_USER_EVENT_SUPPORT + tag_reg((struct file_operations * const) met_device.fops, &met_device.this_device->kobj); +#endif + + met_register(&met_stat); + +#if IS_ENABLED(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) +#if defined(ONDIEMET_SUPPORT) || defined(TINYSYS_SSPM_SUPPORT) + ondiemet_log_manager_init(met_device.this_device); + ondiemet_attr_init(met_device.this_device); +#endif +#endif + + return 0; +} + +void fs_unreg(void) +{ + if (run == 1) + met_stop(); + + run = -1; + + met_deregister(&met_stat); + +#ifdef MET_USER_EVENT_SUPPORT + tag_unreg(); +#endif + +#ifdef FEATURE_MCUPM_NUM +#if FEATURE_MCUPM_NUM + met_deregister(&met_mcupm); +#endif +#endif + + met_deregister(&met_dummy_header); +#ifdef MET_EVENT_POWER_SUPPORT + met_deregister(&met_trace_event); + met_register_api_symbol->met_pm_qos_update_request = NULL; + met_register_api_symbol->met_pm_qos_update_target = NULL; +#endif + met_deregister(&met_switch); + met_deregister(&met_memstat); + met_deregister(&met_cpupmu); + met_deregister(&met_cookie); + + met_register_api_symbol->met_sched_switch = NULL; + + kobject_del(kobj_misc); + kobject_put(kobj_misc); + kobj_misc = NULL; + kobject_del(kobj_pmu); + kobject_put(kobj_pmu); + kobj_pmu = NULL; + kobject_del(kobj_bus); + kobject_put(kobj_bus); + kobj_bus = NULL; + + device_remove_file(met_device.this_device, &dev_attr_ksym); + + device_remove_file(met_device.this_device, &dev_attr_run); +#ifdef PR_CPU_NOTIFY + device_remove_file(met_device.this_device, &dev_attr_cpu_notify); +#endif +#if IS_ENABLED(CONFIG_CPU_FREQ) + device_remove_file(met_device.this_device, &dev_attr_dvfs); +#endif + device_remove_file(met_device.this_device, &dev_attr_suspend_compensation_enable); + device_remove_file(met_device.this_device, &dev_attr_suspend_compensation_flag); + + device_remove_file(met_device.this_device, &dev_attr_ver); + device_remove_file(met_device.this_device, &dev_attr_devices); + device_remove_file(met_device.this_device, &dev_attr_sample_rate); + + device_remove_file(met_device.this_device, &dev_attr_ctrl); + device_remove_file(met_device.this_device, &dev_attr_cpu_pmu_method); + device_remove_file(met_device.this_device, &dev_attr_cpu_pm_pmu_reconfig); + + device_remove_file(met_device.this_device, &dev_attr_core_topology); + device_remove_file(met_device.this_device, &dev_attr_plf); + device_remove_file(met_device.this_device, &dev_attr_chip_id); + device_remove_file(met_device.this_device, &dev_attr_hash); + device_remove_file(met_device.this_device, &dev_attr_ipi_test); + +#if IS_ENABLED(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) +#if defined(ONDIEMET_SUPPORT) || defined(TINYSYS_SSPM_SUPPORT) + ondiemet_log_manager_uninit(met_device.this_device); + ondiemet_attr_uninit(met_device.this_device); +#endif +#endif + + misc_deregister(&met_device); +#ifdef MET_SUSPEND_HAND + /* suspend/resume function handle register */ + unregister_syscore_ops(&met_hrtimer_ops); +#endif +} + +unsigned int get_ctrl_flags(void) +{ + return ctrl_flags; +} diff --git a/drivers/misc/mediatek/met_drv_v2/common/interface.h b/drivers/misc/mediatek/met_drv_v2/common/interface.h new file mode 100644 index 0000000000000000000000000000000000000000..05d07a4ea3b1cec2a7c08f053aaf1828dd846ee4 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/interface.h @@ -0,0 +1,80 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef __INTERFACE_H__ +#define __INTERFACE_H__ + +#include + +struct tag_chipid { + u32 size; + u32 hw_code; + u32 hw_subcode; + u32 hw_ver; + u32 sw_ver; +}; +extern unsigned int met_get_chipid_from_atag(void); + +#ifdef MET_USER_EVENT_SUPPORT +extern int tag_reg(struct file_operations *const fops, struct kobject *kobj); +extern int tag_unreg(void); +#include "met_drv.h" +#include "met_tag.h" +extern struct bltable_t bltab; +#endif + +extern struct metdevice met_stat; +extern struct metdevice met_cpupmu; +extern struct metdevice met_cookie; +extern struct metdevice met_memstat; +extern struct metdevice met_switch; +extern struct metdevice met_trace_event; +extern struct metdevice met_dummy_header; +extern struct metdevice met_backlight; +extern struct metdevice met_mcupm; + +/* This variable will decide which method to access the CPU PMU counter */ +/* 0: access registers directly */ +/* others: via Linux perf driver */ +extern unsigned int met_cpu_pmu_method; + +/* + * controls whether re-configuring pmu events after leaving cpu off state + */ +extern unsigned int met_cpu_pm_pmu_reconfig; + +extern int met_parse_num(const char *str, unsigned int *value, int len); +extern void met_set_suspend_notify(int flag); + +#define PR_CPU_NOTIFY +#if defined(PR_CPU_NOTIFY) +extern int met_cpu_notify; +#endif + +//#undef MET_BOOT_MSG +#define MET_BOOT_MSG +#if defined(MET_BOOT_MSG) +extern char met_boot_msg_tmp[256]; +extern int pr_bootmsg(int str_len, char *str); +#define PR_BOOTMSG(fmt, args...) { \ + int str_len = snprintf(met_boot_msg_tmp, sizeof(met_boot_msg_tmp), \ + fmt, ##args); \ + pr_bootmsg(str_len, met_boot_msg_tmp); } +#define PR_BOOTMSG_ONCE(fmt, args...) { \ + static int once; \ + if (!once) { \ + int str_len = snprintf(met_boot_msg_tmp, \ + sizeof(met_boot_msg_tmp), \ + fmt, ##args); \ + pr_bootmsg(str_len, met_boot_msg_tmp); \ + once = 1; \ + } } +#else +#define pr_bootmsg(str_len, str) +#define PR_BOOTMSG(fmt, args...) +#define PR_BOOTMSG_ONCE(fmt, args...) +#endif + +#endif /* __INTERFACE_H__ */ diff --git a/drivers/misc/mediatek/met_drv_v2/common/mem_stat.c b/drivers/misc/mediatek/met_drv_v2/common/mem_stat.c new file mode 100644 index 0000000000000000000000000000000000000000..8542b460efb65d50c5a78d2a1cfd1519ccffd027 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/mem_stat.c @@ -0,0 +1,310 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include + +#include "met_drv.h" +#include "mem_stat.h" +#include "trace.h" + + +/* define MEMSTAT_DEBUG */ +#ifdef MEMSTAT_DEBUG +#define debug_memstat(fmt, arg...) pr_debug(fmt, ##arg) +#else +#define debug_memstat(fmt, arg...) do {} while (0) +#endif + +struct metdevice met_memstat; + +unsigned int phy_memstat_mask; +unsigned int vir_memstat_mask; + +#define MAX_PHY_MEMSTAT_EVENT_AMOUNT 6 +#define MAX_VIR_MEMSTAT_EVENT_AMOUNT 6 + +struct mem_event phy_memstat_table[] = { + {FREE_MEM, "free_mem", "Free Memory"} +}; + +#define PHY_MEMSTAT_TABLE_SIZE (sizeof(phy_memstat_table) / sizeof(struct mem_event)) + +struct mem_event vir_memstat_table[] = { + {FILE_PAGES, "file_pages", "File Pages"}, + {FILE_DIRTY, "file_dirty", "FD APP->FS(KB)"}, + {NUM_DIRTIED, "num_dirtied", "Num Dirtied"}, + {WRITE_BACK, "write_back", "WB. FS->Block IO(KB)"}, + {NUM_WRITTEN, "num_written", "Num Written"}, + {PG_FAULT_CNT, "pg_fault_cnt", "Page Fault Count"} +}; + +#define VIR_MEMSTAT_TABLE_SIZE (sizeof(vir_memstat_table) / sizeof(struct mem_event)) + +int vm_event_counters_enable; +unsigned long *vm_status; +static struct delayed_work dwork; + +noinline void memstat(unsigned int cnt, unsigned int *value) +{ + MET_GENERAL_PRINT(MET_TRACE, cnt, value); +} + +static int get_phy_memstat(unsigned int *value) +{ + int i, cnt = 0; + struct sysinfo info; + +#define K(x) ((x) << (PAGE_SHIFT - 10)) + + si_meminfo(&info); + + for (i = 0; i < MAX_PHY_MEMSTAT_EVENT_AMOUNT; i++) { + if (phy_memstat_mask & (1 << i)) { + switch (i) { + case FREE_MEM: + value[cnt] = K(info.freeram); + break; + } + + cnt++; + } + } + + return cnt; +} + +static int get_vir_memstat(unsigned int *value) +{ + int i, cnt = 0; + + for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++) + vm_status[i] = global_zone_page_state(i); + + all_vm_events(vm_status + NR_VM_ZONE_STAT_ITEMS); + + for (i = 0; i < MAX_VIR_MEMSTAT_EVENT_AMOUNT; i++) { + if (vir_memstat_mask & (1 << i)) { + switch (i) { + case FILE_PAGES: + value[cnt] = vm_status[NR_FILE_PAGES] << (PAGE_SHIFT - 10); + break; + case FILE_DIRTY: + value[cnt] = vm_status[NR_FILE_DIRTY] << (PAGE_SHIFT - 10); + break; + case NUM_DIRTIED: + value[cnt] = vm_status[NR_DIRTIED] << (PAGE_SHIFT - 10); + break; + case WRITE_BACK: + value[cnt] = vm_status[NR_WRITEBACK] << (PAGE_SHIFT - 10); + break; + case NUM_WRITTEN: + value[cnt] = vm_status[NR_WRITTEN] << (PAGE_SHIFT - 10); + break; + case PG_FAULT_CNT: + value[cnt] = vm_status[NR_VM_ZONE_STAT_ITEMS + PGFAULT]; + break; + } + + cnt++; + } + } + + return cnt; +} + +static void wq_get_memstat(struct work_struct *work) +{ + int total_event_amount = 0, phy_event_amount = 0; + unsigned int stat_val[MAX_PHY_MEMSTAT_EVENT_AMOUNT + MAX_VIR_MEMSTAT_EVENT_AMOUNT]; + + memset(stat_val, 0, sizeof(unsigned int) * (MAX_PHY_MEMSTAT_EVENT_AMOUNT + MAX_VIR_MEMSTAT_EVENT_AMOUNT)); + total_event_amount = phy_event_amount = get_phy_memstat(stat_val); + + if (vm_event_counters_enable) + total_event_amount += get_vir_memstat(&(stat_val[phy_event_amount])); + + if (total_event_amount <= (MAX_PHY_MEMSTAT_EVENT_AMOUNT + MAX_VIR_MEMSTAT_EVENT_AMOUNT)) + memstat(total_event_amount-1, stat_val); +} + +void met_memstat_polling(unsigned long long stamp, int cpu) +{ + schedule_delayed_work(&dwork, 0); +} + +static void met_memstat_start(void) +{ + int stat_items_size = 0; + + stat_items_size = NR_VM_ZONE_STAT_ITEMS * sizeof(unsigned long); + +#if IS_ENABLED(CONFIG_VM_EVENT_COUNTERS) + stat_items_size += sizeof(struct vm_event_state); +#endif + + vm_status = kmalloc(stat_items_size, GFP_KERNEL); + if (vm_status == NULL) + return; + INIT_DELAYED_WORK(&dwork, wq_get_memstat); +} + +static void met_memstat_stop(void) +{ + kfree(vm_status); + cancel_delayed_work_sync(&dwork); +} + +static const char help[] = +" --memstat=[phy_mem_stat|vir_mem_stat]:event_name enable sampling physical & virtual memory status\n"; + +static int met_memstat_print_help(char *buf, int len) +{ + int i, l; + + l = snprintf(buf, PAGE_SIZE, help); + + for (i = 0; i < PHY_MEMSTAT_TABLE_SIZE; i++) + l += snprintf(buf + l, PAGE_SIZE - l, " --memstat=phy_mem_stat:%s\n", + phy_memstat_table[i].name); + +#if IS_ENABLED(CONFIG_VM_EVENT_COUNTERS) + for (i = 0; i < VIR_MEMSTAT_TABLE_SIZE; i++) + l += snprintf(buf + l, PAGE_SIZE - l, " --memstat=vir_mem_stat:%s\n", + vir_memstat_table[i].name); +#endif + + return l; +} + +static const char header[] = "met-info [000] 0.0: ms_ud_sys_header: memstat,"; + + +static int met_memstat_print_header(char *buf, int len) +{ + int i, l; + int event_amount = 0; + + l = snprintf(buf, PAGE_SIZE, header); + + for (i = 0; i < MAX_PHY_MEMSTAT_EVENT_AMOUNT; i++) { + if ((phy_memstat_mask & (1 << i)) && (i < PHY_MEMSTAT_TABLE_SIZE)) { + l += snprintf(buf + l, PAGE_SIZE - l, phy_memstat_table[i].header_name); + l += snprintf(buf + l, PAGE_SIZE - l, ","); + event_amount++; + } + } + +#if IS_ENABLED(CONFIG_VM_EVENT_COUNTERS) + for (i = 0; i < MAX_VIR_MEMSTAT_EVENT_AMOUNT; i++) { + if ((vir_memstat_mask & (1 << i)) && (i < VIR_MEMSTAT_TABLE_SIZE)) { + l += snprintf(buf + l, PAGE_SIZE - l, vir_memstat_table[i].header_name); + l += snprintf(buf + l, PAGE_SIZE - l, ","); + event_amount++; + } + } +#endif + + for (i = 0; i < event_amount; i++) { + l += snprintf(buf + l, PAGE_SIZE - l, "x"); + l += snprintf(buf + l, PAGE_SIZE - l, ","); + } + + phy_memstat_mask = 0; + vir_memstat_mask = 0; + + l += snprintf(buf + l, PAGE_SIZE - l, "\n"); + + return l; +} + +static int met_memstat_process_argument(const char *arg, int len) +{ + int i, found_event = 0; + char choice[16], event[32]; + char *pch; + int str_len; + + +#if IS_ENABLED(CONFIG_VM_EVENT_COUNTERS) + vm_event_counters_enable = 1; +#endif + + pch = strchr(arg, ':'); + if (pch == NULL) + goto error; + + memset(choice, 0, sizeof(choice)); + memset(event, 0, sizeof(event)); + + str_len = (int)(pch - arg); + if (str_len >= 16) + goto error; + memcpy(choice, arg, str_len); + + if (len - (str_len + 1) >= 32) + goto error; + memcpy(event, arg + str_len + 1, len - (str_len + 1)); + + if (strncmp(choice, "phy_mem_stat", 12) == 0) { + for (i = 0; i < PHY_MEMSTAT_TABLE_SIZE; i++) { + if (strncmp(event, phy_memstat_table[i].name, MAX_EVENT_NAME_LEN) == 0) { + phy_memstat_mask |= (1 << phy_memstat_table[i].id); + found_event = 1; + + break; + } + } + } else if (strncmp(choice, "vir_mem_stat", 12) == 0) { + if (!vm_event_counters_enable) { + pr_debug("[%s] %d: CONFIG_VM_EVENT_COUNTERS is not configured\n", __func__, + __LINE__); + goto error; + } + + for (i = 0; i < VIR_MEMSTAT_TABLE_SIZE; i++) { + if (strncmp(event, vir_memstat_table[i].name, MAX_EVENT_NAME_LEN) == 0) { + vir_memstat_mask |= (1 << vir_memstat_table[i].id); + found_event = 1; + + break; + } + } + } else { + pr_debug("[%s] %d: only support phy_mem_stat & vir_mem_stat keyword\n", __func__, + __LINE__); + goto error; + } + + if (!found_event) { + pr_debug("[%s] %d: input event name error\n", __func__, __LINE__); + goto error; + } + + met_memstat.mode = 1; + return 0; + +error: + met_memstat.mode = 0; + return -EINVAL; +} + +struct metdevice met_memstat = { + .name = "memstat", + .type = MET_TYPE_PMU, + .cpu_related = 0, + .start = met_memstat_start, + .stop = met_memstat_stop, + .polling_interval = 1, + .timed_polling = met_memstat_polling, + .tagged_polling = met_memstat_polling, + .print_help = met_memstat_print_help, + .print_header = met_memstat_print_header, + .process_argument = met_memstat_process_argument +}; diff --git a/drivers/misc/mediatek/met_drv_v2/common/mem_stat.h b/drivers/misc/mediatek/met_drv_v2/common/mem_stat.h new file mode 100644 index 0000000000000000000000000000000000000000..6e5738a7efff78f9422cb9a1d2a6f2e918b8ccdf --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/mem_stat.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef __MEM_STAT_H__ +#define __MEM_STAT_H__ + +#define MAX_EVENT_NAME_LEN 32 + +enum phy_mem_event_id { + FREE_MEM = 0 +}; + +enum vir_mem_event_id { + FILE_PAGES = 0, + FILE_DIRTY, + NUM_DIRTIED, + WRITE_BACK, + NUM_WRITTEN, + PG_FAULT_CNT +}; + +struct mem_event { + int id; + char name[32]; + char header_name[32]; +}; + +#endif diff --git a/drivers/misc/mediatek/met_drv_v2/common/met_backlight.c b/drivers/misc/mediatek/met_drv_v2/common/met_backlight.c new file mode 100644 index 0000000000000000000000000000000000000000..dbb2752c0d254917040a22253cd870155683646a --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/met_backlight.c @@ -0,0 +1,140 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include +#include +#if IS_ENABLED(CONFIG_LEDS_MTK_DISP) +#include "mtk_leds_drv.h" +#include "leds-mtk-disp.h" +#elif IS_ENABLED(CONFIG_LEDS_MTK_PWM) +#include +#include +#endif + + +#define MET_USER_EVENT_SUPPORT +#include "met_drv.h" +#include "trace.h" + +static int met_backlight_enable; +static DEFINE_SPINLOCK(met_backlight_lock); +static struct kobject *kobj_met_backlight; + +static ssize_t bl_tag_enable_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf); +static ssize_t bl_tag_enable_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, size_t n); +static struct kobj_attribute bl_tag_enable_attr = +__ATTR(backlight_tag_enable, 0664, bl_tag_enable_show, bl_tag_enable_store); + +#if IS_ENABLED(CONFIG_LEDS_MTK_DISP) || IS_ENABLED(CONFIG_LEDS_MTK_PWM) +static int led_brightness_changed_event(struct notifier_block *nb, + unsigned long event, void *v) +{ + struct led_conf_info *led_conf; + + led_conf = (struct led_conf_info *)v; + + switch (event) { + case 1: + output_met_backlight_tag_real(led_conf->cdev.brightness); + break; + default: + break; + } + + return NOTIFY_DONE; +} + +static struct notifier_block leds_change_notifier = { + .notifier_call = led_brightness_changed_event, +}; +#endif + +int enable_met_backlight_tag_real(void) +{ + return met_backlight_enable; +} + +int output_met_backlight_tag_real(int level) +{ + int ret; + unsigned long flags; + + spin_lock_irqsave(&met_backlight_lock, flags); +#ifdef CONFIG_MET_MODULE + ret = met_tag_oneshot_real(33880, "_MM_BL_", level); +#else + ret = met_tag_oneshot(33880, "_MM_BL_", level); +#endif + spin_unlock_irqrestore(&met_backlight_lock, flags); + + return ret; +} + +static ssize_t bl_tag_enable_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + int ret; + + ret = snprintf(buf, PAGE_SIZE, "%d\n", met_backlight_enable); + + return ret; +} + +static ssize_t bl_tag_enable_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, size_t n) +{ + int value; + + if ((n == 0) || (buf == NULL)) + return -EINVAL; + + if (kstrtoint(buf, 0, &value) != 0) + return -EINVAL; + + if (value < 0) + return -EINVAL; + +#if IS_ENABLED(CONFIG_LEDS_MTK_DISP) || IS_ENABLED(CONFIG_LEDS_MTK_PWM) + if (value == 1) { + mtk_leds_register_notifier(&leds_change_notifier); + } else if (value == 0) { + mtk_leds_unregister_notifier(&leds_change_notifier); + } +#endif + met_backlight_enable = value; + + return n; +} + +static int met_backlight_create(struct kobject *parent) +{ + int ret = 0; + + kobj_met_backlight = parent; + + ret = sysfs_create_file(kobj_met_backlight, &bl_tag_enable_attr.attr); + if (ret != 0) { + pr_debug("Failed to create montype0 in sysfs\n"); + return ret; + } + + return ret; +} + +static void met_backlight_delete(void) +{ + sysfs_remove_file(kobj_met_backlight, &bl_tag_enable_attr.attr); + kobj_met_backlight = NULL; +} + +struct metdevice met_backlight = { + .name = "backlight", + .owner = THIS_MODULE, + .type = MET_TYPE_BUS, + .create_subfs = met_backlight_create, + .delete_subfs = met_backlight_delete, + .cpu_related = 0, +}; +EXPORT_SYMBOL(met_backlight); diff --git a/drivers/misc/mediatek/met_drv_v2/common/met_drv.h b/drivers/misc/mediatek/met_drv_v2/common/met_drv.h new file mode 100644 index 0000000000000000000000000000000000000000..2161649def3b7c581896c3a11f7aaf73202c92a6 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/met_drv.h @@ -0,0 +1,272 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef MET_DRV +#define MET_DRV + +#include +#include +#include +#include +#include +#include + +extern int met_mode; +extern int core_plf_init(void); +extern void core_plf_exit(void); + +#define MET_MODE_TRACE_CMD_OFFSET (1) +#define MET_MODE_TRACE_CMD (1< 0) \ + TRACE_PUTS(pmet_strbuf); \ + my_preempt_enable(); \ + } while (0) + +/* + * SOB: start of buf + * EOB: end of buf + */ +#define MET_TRACE_GETBUF(pSOB, pEOB) \ + ({ \ + preempt_disable(); \ + if (in_nmi()) \ + *pSOB = per_cpu(met_strbuf_nmi, smp_processor_id()); \ + else if (in_irq()) \ + *pSOB = per_cpu(met_strbuf_irq, smp_processor_id()); \ + else if (in_softirq()) \ + *pSOB = per_cpu(met_strbuf_sirq, smp_processor_id()); \ + else \ + *pSOB = per_cpu(met_strbuf, smp_processor_id()); \ + *pEOB = *pSOB; \ + if (met_mode & MET_MODE_TRACE_CMD) \ + *pEOB += snprintf(*pEOB, MET_STRBUF_SIZE, "%s: ", __func__); \ + }) + +#define MET_TRACE_PUTBUF(SOB, EOB) \ + ({ \ + __trace_puts(_THIS_IP_, (SOB), (uintptr_t)((EOB)-(SOB))); \ + my_preempt_enable(); \ + }) + +#define MET_FTRACE_DUMP(TRACE_NAME, args...) \ + do { \ + trace_##TRACE_NAME(args);; \ + } while (0) + + +#define MET_TYPE_PMU 1 +#define MET_TYPE_BUS 2 +#define MET_TYPE_MISC 3 + +enum met_action { + MET_CPU_ONLINE, + MET_CPU_OFFLINE, + + NR_MET_ACTION, +}; + +struct metdevice { + struct list_head list; + int type; + const char *name; + struct module *owner; + struct kobject *kobj; + + int (*create_subfs)(struct kobject *parent); + void (*delete_subfs)(void); + int mode; + int ondiemet_mode; /* new for ondiemet; 1: call ondiemet functions */ + int cpu_related; + int polling_interval; + int polling_count_reload; + int __percpu *polling_count; + int header_read_again; /*for header size > 1 page */ + void (*start)(void); + void (*uniq_start)(void); + void (*stop)(void); + void (*uniq_stop)(void); + int (*reset)(void); + void (*timed_polling)(unsigned long long stamp, int cpu); + void (*tagged_polling)(unsigned long long stamp, int cpu); + int (*print_help)(char *buf, int len); + int (*print_header)(char *buf, int len); + int (*process_argument)(const char *arg, int len); + void (*cpu_state_notify)(long cpu, unsigned long action); + + void (*ondiemet_start)(void); + void (*uniq_ondiemet_start)(void); + void (*ondiemet_stop)(void); + void (*uniq_ondiemet_stop)(void); + int (*ondiemet_reset)(void); + int (*ondiemet_print_help)(char *buf, int len); + int (*ondiemet_print_header)(char *buf, int len); + int (*ondiemet_process_argument)(const char *arg, int len); + void (*ondiemet_timed_polling)(unsigned long long stamp, int cpu); + void (*ondiemet_tagged_polling)(unsigned long long stamp, int cpu); + + struct list_head exlist; /* for linked list before register */ + void (*suspend)(void); + void (*resume)(void); + + unsigned long long prev_stamp; + spinlock_t my_lock; + void *reversed1; +}; + +int met_register(struct metdevice *met); +int met_deregister(struct metdevice *met); +int met_set_platform(const char *plf_name, int flag); +int met_set_chip_id(const unsigned int chip_id); +int met_set_topology(const char *topology_name, int flag); +int met_devlink_add(struct metdevice *met); +int met_devlink_del(struct metdevice *met); +int met_devlink_register_all(void); +int met_devlink_deregister_all(void); + +int fs_reg(int met_minor); +void fs_unreg(void); + +/****************************************************************************** + * Tracepoints + ******************************************************************************/ +#define MET_DEFINE_PROBE(probe_name, proto) \ + static void probe_##probe_name(void *data, PARAMS(proto)) +#define MET_REGISTER_TRACE(probe_name) \ + register_trace_##probe_name(probe_##probe_name, NULL) +#define MET_UNREGISTER_TRACE(probe_name) \ + unregister_trace_##probe_name(probe_##probe_name, NULL) + + +/* ====================== Tagging API ================================ */ + +#define MAX_EVENT_CLASS 31 +#define MAX_TAGNAME_LEN 128 +#define MET_CLASS_ALL 0x80000000 + +/* IOCTL commands of MET tagging */ +struct mtag_cmd_t { + unsigned int class_id; + unsigned int value; + unsigned int slen; + char tname[MAX_TAGNAME_LEN]; + void *data; + unsigned int size; +}; + +#define TYPE_START 1 +#define TYPE_END 2 +#define TYPE_ONESHOT 3 +#define TYPE_ENABLE 4 +#define TYPE_DISABLE 5 +#define TYPE_REC_SET 6 +#define TYPE_DUMP 7 +#define TYPE_DUMP_SIZE 8 +#define TYPE_DUMP_SAVE 9 +#define TYPE_USRDATA 10 +#define TYPE_DUMP_AGAIN 11 +#define TYPE_ASYNC_START 12 +#define TYPE_ASYNC_END 13 +#define TYPE_MET_SUSPEND 15 +#define TYPE_MET_RESUME 16 + +/* Use 'm' as magic number */ +#define MTAG_IOC_MAGIC 'm' +/* Please use a different 8-bit number in your code */ +#define MTAG_CMD_START _IOW(MTAG_IOC_MAGIC, TYPE_START, struct mtag_cmd_t) +#define MTAG_CMD_END _IOW(MTAG_IOC_MAGIC, TYPE_END, struct mtag_cmd_t) +#define MTAG_CMD_ONESHOT _IOW(MTAG_IOC_MAGIC, TYPE_ONESHOT, struct mtag_cmd_t) +#define MTAG_CMD_ENABLE _IOW(MTAG_IOC_MAGIC, TYPE_ENABLE, int) +#define MTAG_CMD_DISABLE _IOW(MTAG_IOC_MAGIC, TYPE_DISABLE, int) +#define MTAG_CMD_REC_SET _IOW(MTAG_IOC_MAGIC, TYPE_REC_SET, int) +#define MTAG_CMD_DUMP _IOW(MTAG_IOC_MAGIC, TYPE_DUMP, struct mtag_cmd_t) +#define MTAG_CMD_DUMP_SIZE _IOWR(MTAG_IOC_MAGIC, TYPE_DUMP_SIZE, int) +#define MTAG_CMD_DUMP_SAVE _IOW(MTAG_IOC_MAGIC, TYPE_DUMP_SAVE, struct mtag_cmd_t) +#define MTAG_CMD_USRDATA _IOW(MTAG_IOC_MAGIC, TYPE_USRDATA, struct mtag_cmd_t) +#define MTAG_CMD_DUMP_AGAIN _IOW(MTAG_IOC_MAGIC, TYPE_DUMP_AGAIN, void *) +#define MTAG_CMD_ASYNC_START _IOW(MTAG_IOC_MAGIC, TYPE_ASYNC_START, struct mtag_cmd_t) +#define MTAG_CMD_ASYNC_END _IOW(MTAG_IOC_MAGIC, TYPE_ASYNC_END, struct mtag_cmd_t) + +/* include file */ +extern int met_tag_start_real(unsigned int class_id, const char *name); +extern int met_tag_end_real(unsigned int class_id, const char *name); +extern int met_tag_async_start_real(unsigned int class_id, const char *name, unsigned int cookie); +extern int met_tag_async_end_real(unsigned int class_id, const char *name, unsigned int cookie); +extern int met_tag_oneshot_real(unsigned int class_id, const char *name, unsigned int value); +extern int met_tag_userdata_real(char *pData); +extern int met_tag_dump_real(unsigned int class_id, const char *name, void *data, unsigned int length); +extern int met_tag_disable_real(unsigned int class_id); +extern int met_tag_enable_real(unsigned int class_id); +extern int met_set_dump_buffer_real(int size); +extern int met_save_dump_buffer_real(const char *pathname); +extern int met_save_log_real(const char *pathname); +extern int met_show_bw_limiter_real(void); +extern int met_reg_bw_limiter_real(void *fp); +extern int met_show_clk_tree_real(const char *name, unsigned int addr, unsigned int status); +extern int met_reg_clk_tree_real(void *fp); +extern int enable_met_backlight_tag_real(void); +extern int output_met_backlight_tag_real(int level); + +#endif /* MET_DRV */ diff --git a/drivers/misc/mediatek/met_drv_v2/common/met_kernel_symbol.h b/drivers/misc/mediatek/met_drv_v2/common/met_kernel_symbol.h new file mode 100644 index 0000000000000000000000000000000000000000..11e2dc2323b0166b0f4bf3cf19e777eda084c1eb --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/met_kernel_symbol.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef MET_KERNEL_SYMBOL +#define MET_KERNEL_SYMBOL + +/*lookup symbol*/ +#include +#include +#include +#include + +#include "met_api.h" + +#define _MET_SYMBOL_GET(_func_name_) ({\ + int ret = 0; \ + do { \ + _func_name_##_symbol = (void *)symbol_get(_func_name_); \ + if (_func_name_##_symbol == NULL) { \ + pr_debug("MET ext. symbol : %s is not found!\n", #_func_name_); \ + PR_BOOTMSG_ONCE("MET ext. symbol : %s is not found!\n", #_func_name_); \ + ret = -1; \ + } \ + } while (0); \ + ret; \ + }) + +#define _MET_SYMBOL_PUT(_func_name_) { \ + if (_func_name_##_symbol) { \ + symbol_put(_func_name_); \ + _func_name_##_symbol = NULL; \ + } \ + } + +extern struct met_register_tbl *met_register_api_symbol; +extern struct met_export_tbl *met_export_api_symbol; + +#if IS_ENABLED(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) +#if defined(ONDIEMET_SUPPORT) || defined(TINYSYS_SSPM_SUPPORT) +#ifdef SSPM_VERSION_V2 +#include "sspm/ondiemet_sspm.h" +extern struct mtk_ipi_device sspm_ipidev; +extern struct mtk_ipi_device *sspm_ipidev_symbol; +#endif +#endif +#endif + +extern unsigned int mt_get_chip_id(void); +extern unsigned int (*mt_get_chip_id_symbol)(void); + +#endif /* MET_KERNEL_SYMBOL */ diff --git a/drivers/misc/mediatek/met_drv_v2/common/met_main.c b/drivers/misc/mediatek/met_drv_v2/common/met_main.c new file mode 100644 index 0000000000000000000000000000000000000000..1a60c272cad07e20f4bfbaa947e4f05850164bde --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/met_main.c @@ -0,0 +1,361 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +/* #include */ + +#include + +#include "met_struct.h" +#include "met_drv.h" +#include "met_kernel_symbol.h" +#include "interface.h" +#include + +#if IS_ENABLED(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) +#if defined(ONDIEMET_SUPPORT) || defined(TINYSYS_SSPM_SUPPORT) +#if defined(SSPM_VERSION_V2) +#include "sspm_ipi_id.h" /* for sspm_ipidev */ +#endif +#endif +#endif + +extern struct device_node *of_root; +static const char *platform_name; + +struct cpu_type_name { + char full_name[32]; + char abbr_name[8]; +}; + +static struct cpu_type_name met_known_cpu_type[] = { + {"arm,cortex-a53", "CA53"}, + {"arm,cortex-a55", "CA55"}, + {"arm,cortex-a72", "CA72"}, + {"arm,cortex-a73", "CA73"}, + {"arm,cortex-a75", "CA75"}, + {"arm,cortex-a76", "CA76"}, +}; +#define MET_KNOWN_CPU_TYPE_COUNT \ + (sizeof(met_known_cpu_type)/sizeof(struct cpu_type_name)) + +static char met_cpu_topology[64]; + +struct met_register_tbl *met_register_api_symbol; +EXPORT_SYMBOL(met_register_api_symbol); +struct met_export_tbl *met_export_api_symbol; +EXPORT_SYMBOL(met_export_api_symbol); + +#if IS_ENABLED(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) +#if defined(ONDIEMET_SUPPORT) || defined(TINYSYS_SSPM_SUPPORT) +#if defined(SSPM_VERSION_V2) +struct mtk_ipi_device *sspm_ipidev_symbol = NULL; +#endif +#endif +#endif + +unsigned int (*mt_get_chip_id_symbol)(void); + +static int met_minor = -1; +module_param(met_minor, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); + + +#ifdef MTK_PLATFORM +#define _SHOW_MTK_PLATFORM(X) #X +#define SHOW_MTK_PLATFORM(X) _SHOW_MTK_PLATFORM(X) +#endif + +static int is_platform_name_valid(const char * buf) +{ + int len = strlen(buf); + int i; + + for (i=0; i 0) { + len = strlen(met_cpu_topology); + snprintf(met_cpu_topology + len, sizeof(met_cpu_topology) - len, "|"); + } + + met_set_cpu_topology(start_core_id, cluster_core_num); + start_core_id = cluster_core_num; + } + } + } + + return strlen(met_cpu_topology); +} + +static int met_kernel_symbol_get(void) +{ + int ret = 0; + + ret += _MET_SYMBOL_GET(met_register_api); + ret += _MET_SYMBOL_GET(met_export_api); + +#if IS_ENABLED(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) +#if defined(ONDIEMET_SUPPORT) || defined(TINYSYS_SSPM_SUPPORT) +#if defined(SSPM_VERSION_V2) + ret += _MET_SYMBOL_GET(sspm_ipidev); +#endif +#endif +#endif + return ret; +} + +static void met_kernel_symbol_put(void) +{ + _MET_SYMBOL_PUT(met_register_api); + _MET_SYMBOL_PUT(met_export_api); + +#if IS_ENABLED(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) +#if defined(ONDIEMET_SUPPORT) || defined(TINYSYS_SSPM_SUPPORT) +#ifdef SSPM_VERSION_V2 + _MET_SYMBOL_PUT(sspm_ipidev); +#endif +#endif +#endif +} + +DEFINE_PER_CPU(struct met_cpu_struct, met_cpu); + +static int __init met_drv_init(void) +{ + int cpu; + int ret; + int cpu_topology_len; + struct met_cpu_struct *met_cpu_ptr; + unsigned int chip_id; + + for_each_possible_cpu(cpu) { + met_cpu_ptr = &per_cpu(met_cpu, cpu); + /* snprintf(&(met_cpu_ptr->name[0]), sizeof(met_cpu_ptr->name), "met%02d", cpu); */ + met_cpu_ptr->cpu = cpu; + } + + ret = met_kernel_symbol_get(); + if (ret) { + pr_notice("[MET] met_kernel_symbol_get fail, ret = %d\n", ret); + return ret; + } + + ret = fs_reg(met_minor); + if (ret) { + pr_notice("[MET] met fs_reg fail, ret = %d\n", ret); + return ret; + } + + if (of_root){ + /* + mt6765.dts + model = "MT6765"; + compatible = "mediatek,MT6765"; + interrupt-parent = <&sysirq>; + */ + if (of_root->properties) { + of_property_read_string(of_root, "compatible", &platform_name); + PR_BOOTMSG("dts property compatible=%s\n", platform_name); + } + } + if (platform_name) { + char buf[7]; + int found = -1; + + found = is_platform_name_valid(platform_name); + + if ( !(found < 0) ) { + memset(buf, 0x0, 7); + buf[0] = 'm'; + buf[1] = 't'; + strncpy(&buf[2], &platform_name[found+2], 4); + met_set_platform(buf, 1); + PR_BOOTMSG("Get platform info from dts, platform_name=%s\n", buf); + } else { +#ifdef MTK_PLATFORM + memset(buf, 0x0, 7); + strcpy(buf, SHOW_MTK_PLATFORM(MTK_PLATFORM)); + found = is_platform_name_valid((const char *)buf); + if( !(found < 0) ){ + PR_BOOTMSG("Get platform info from met_drv Kbuild, platform_name=%s\n", buf); + met_set_platform(buf, 1); + } + else +#endif + { + PR_BOOTMSG("Can not get platform info from dts nor met_drv Kbuild, set platform_name=mtxxxx\n"); + met_set_platform("mtxxxx", 1); + } + } + } + + /* get the chip id */ + _MET_SYMBOL_GET(mt_get_chip_id); + if (mt_get_chip_id_symbol != NULL) + met_set_chip_id(mt_get_chip_id_symbol()); + else { + chip_id = met_get_chipid_from_atag(); + if (((int) chip_id) < 0) { + PR_BOOTMSG("Can not get chip id info, set chip_id=0x0\n"); + } else + met_set_chip_id(chip_id); + } + + cpu_topology_len = met_create_cpu_topology(); + if (cpu_topology_len) + met_set_topology(met_cpu_topology, 1); + +#ifdef MET_PLF_USE + core_plf_init(); +#endif + return 0; +} + +static void __exit met_drv_exit(void) +{ +#ifdef MET_PLF_USE + core_plf_exit(); +#endif + fs_unreg(); + + met_kernel_symbol_put(); + _MET_SYMBOL_PUT(mt_get_chip_id); +} +module_init(met_drv_init); +module_exit(met_drv_exit); + +MODULE_AUTHOR("DT_DM5"); +MODULE_DESCRIPTION("MET_CORE"); +MODULE_LICENSE("GPL"); diff --git a/drivers/misc/mediatek/met_drv_v2/common/met_power.h b/drivers/misc/mediatek/met_drv_v2/common/met_power.h new file mode 100644 index 0000000000000000000000000000000000000000..8a6290c44f454994e8266595b11a44c8f215e190 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/met_power.h @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef MET_POWER +#define MET_POWER + +enum { + _PM_QOS_RESERVED = 0, + _PM_QOS_CPU_DMA_LATENCY, + _PM_QOS_NETWORK_LATENCY, + _PM_QOS_NETWORK_THROUGHPUT, + _PM_QOS_MEMORY_BANDWIDTH, + + _PM_QOS_CPU_MEMORY_BANDWIDTH, + _PM_QOS_GPU_MEMORY_BANDWIDTH, + _PM_QOS_MM_MEMORY_BANDWIDTH, + _PM_QOS_OTHER_MEMORY_BANDWIDTH, + _PM_QOS_MM0_BANDWIDTH_LIMITER, + _PM_QOS_MM1_BANDWIDTH_LIMITER, + + _PM_QOS_DDR_OPP, + _PM_QOS_VCORE_OPP, + _PM_QOS_SCP_VCORE_REQUEST, + _PM_QOS_POWER_MODEL_DDR_REQUEST, + _PM_QOS_POWER_MODEL_VCORE_REQUEST, + _PM_QOS_VCORE_DVFS_FORCE_OPP, + + _PM_QOS_DISP_FREQ, + _PM_QOS_MDP_FREQ, + _PM_QOS_VDEC_FREQ, + _PM_QOS_VENC_FREQ, + _PM_QOS_IMG_FREQ, + _PM_QOS_CAM_FREQ, + _PM_QOS_VVPU_OPP, + _PM_QOS_VMDLA_OPP, + _PM_QOS_ISP_HRT_BANDWIDTH, + _PM_QOS_APU_MEMORY_BANDWIDTH, + /* insert new class ID */ + _PM_QOS_NUM_CLASSES, +}; +/* Action requested to pm_qos_update_target */ +enum _pm_qos_req_action { + _PM_QOS_ADD_REQ, /* Add a new request */ + _PM_QOS_UPDATE_REQ, /* Update an existing request */ + _PM_QOS_REMOVE_REQ /* Remove an existing request */ +}; + +extern void pm_qos_update_request(int pm_qos_class, s32 value); +extern void pm_qos_update_target(unsigned int action, int prev_value, int curr_value); + +#endif /* MET_DRV */ + diff --git a/drivers/misc/mediatek/met_drv_v2/common/met_ptpod.c b/drivers/misc/mediatek/met_drv_v2/common/met_ptpod.c new file mode 100644 index 0000000000000000000000000000000000000000..0d8631d931ed74cf35953f779611ad66f23188df --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/met_ptpod.c @@ -0,0 +1,356 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include +#include +#include +#include +#include + +#include "met_drv.h" +#include "trace.h" +#include "core_plf_init.h" +#include "core_plf_trace.h" + +static unsigned int MT_GPU_DVFS_IDX = NR_MT_CPU_DVFS; +static unsigned int g_u4GPUVolt; +static unsigned int g_u4Volt[NR_MT_CPU_DVFS + 1]; + +/* g_ap_ptpod: cpu volt from ap or sspm setting + * if 1: cpu volt from ap + * if 0: cpu volt from sspm */ +static unsigned int g_ap_ptpod; + +/* gpu_volt_enable: + * if 1: enable gpu volt to output + * if 0: disable gpu volt to output */ +static unsigned int gpu_volt_enable = 1; + +/* get_volt_by_wq: + * if 1: get cpu/gpu volt by workqueue + * if 0: get cpu/gpu volt in irq */ +static unsigned int get_volt_by_wq; + +static int ptpod_started; +static struct kobject *kobj_ptpod; +static struct delayed_work get_volt_dwork; + +noinline void ms_ptpod(void) +{ + char *SOB, *EOB; + + if (g_ap_ptpod) { + MET_TRACE_GETBUF(&SOB, &EOB); + + if (gpu_volt_enable) { + g_u4Volt[MT_GPU_DVFS_IDX] = g_u4GPUVolt; + EOB = ms_formatD_EOL(EOB, ARRAY_SIZE(g_u4Volt), g_u4Volt); + } else + EOB = ms_formatD_EOL(EOB, ARRAY_SIZE(g_u4Volt) - 1, g_u4Volt); + + MET_TRACE_PUTBUF(SOB, EOB); + } else { + if (gpu_volt_enable) { + MET_TRACE_GETBUF(&SOB, &EOB); + EOB = ms_formatD_EOL(EOB, 1, &g_u4GPUVolt); + MET_TRACE_PUTBUF(SOB, EOB); + } + } +} + +#if 0 +static void ptpod_cpu_voltSampler(enum mt_cpu_dvfs_id id, unsigned int volt) +{ + switch (id) { + case MT_CPU_DVFS_LL: + g_u4CPUVolt_LL = volt; + break; + case MT_CPU_DVFS_L: + g_u4CPUVolt_L = volt; + break; + case MT_CPU_DVFS_CCI: + g_u4CPUVolt_CCI = volt; + break; + default: + return; + } + ptpod(); +} +#endif + +#if 0 +static void ptpod_gpu_voltSampler(unsigned int a_u4Volt) +{ + g_u4GPUVolt = (a_u4Volt+50)/100; + + if (ptpod_started) + ptpod(); +} +#endif + +#define PTPOD_CONF_SHOW_IMPLEMENT(var) \ + do { \ + int i; \ + i = snprintf(buf, PAGE_SIZE, "%d\n", var); \ + return i; \ + } while (0) + +#define PTPOD_CONF_STORE_IMPLEMENT(var) \ + do { \ + int value; \ + if ((n == 0) || (buf == NULL)) \ + return -EINVAL; \ + if (kstrtoint(buf, 0, &value) != 0) \ + return -EINVAL; \ + if (value == 1) \ + var = 1; \ + else \ + var = 0; \ + return n; \ + } while (0) + + +static ssize_t ap_ptpod_enable_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + PTPOD_CONF_SHOW_IMPLEMENT(g_ap_ptpod); +} + +static ssize_t ap_ptpod_enable_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t n) +{ + PTPOD_CONF_STORE_IMPLEMENT(g_ap_ptpod); +} + +static ssize_t gpu_volt_enable_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + PTPOD_CONF_SHOW_IMPLEMENT(gpu_volt_enable); +} + +static ssize_t gpu_volt_enable_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t n) +{ + PTPOD_CONF_STORE_IMPLEMENT(gpu_volt_enable); +} + +static ssize_t get_volt_by_wq_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + PTPOD_CONF_SHOW_IMPLEMENT(get_volt_by_wq); +} + +static ssize_t get_volt_by_wq_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t n) +{ + PTPOD_CONF_STORE_IMPLEMENT(get_volt_by_wq); +} + +static struct kobj_attribute ap_ptpod_enable_attr = __ATTR(ap_ptpod_enable, 0664, ap_ptpod_enable_show, ap_ptpod_enable_store); +static struct kobj_attribute gpu_volt_enable_attr = __ATTR(gpu_volt_enable, 0664, gpu_volt_enable_show, gpu_volt_enable_store); +static struct kobj_attribute get_volt_by_wq_attr = __ATTR(get_volt_by_wq, 0664, get_volt_by_wq_show, get_volt_by_wq_store); + +/* create ptpod related kobj node */ +#define KOBJ_ATTR_LIST \ + do { \ + KOBJ_ATTR_ITEM(ap_ptpod_enable); \ + KOBJ_ATTR_ITEM(gpu_volt_enable); \ + KOBJ_ATTR_ITEM(get_volt_by_wq); \ + } while (0) + +static int ptpod_create(struct kobject *parent) +{ + int ret = 0; + + kobj_ptpod = parent; + +#define KOBJ_ATTR_ITEM(attr_name) \ + do { \ + ret = sysfs_create_file(kobj_ptpod, &attr_name ## _attr.attr); \ + if (ret != 0) { \ + pr_notice("Failed to create " #attr_name " in sysfs\n"); \ + return ret; \ + } \ + } while (0) + KOBJ_ATTR_LIST; +#undef KOBJ_ATTR_ITEM + + return 0; +} + +static void ptpod_delete(void) +{ +#define KOBJ_ATTR_ITEM(attr_name) \ + sysfs_remove_file(kobj_ptpod, &attr_name ## _attr.attr) + + if (kobj_ptpod != NULL) { + KOBJ_ATTR_LIST; + kobj_ptpod = NULL; + } +#undef KOBJ_ATTR_ITEM +} + +static void update_volt_value(void) +{ + int i; + + if (g_ap_ptpod && mt_cpufreq_get_cur_volt_symbol) { + /* + g_u4CPUVolt_LL = mt_cpufreq_get_cur_volt_symbol(MT_CPU_DVFS_LL)/100; + g_u4CPUVolt_L = mt_cpufreq_get_cur_volt_symbol(MT_CPU_DVFS_L)/100; + g_u4CPUVolt_CCI = mt_cpufreq_get_cur_volt_symbol(MT_CPU_DVFS_CCI)/100; + */ + for (i = 0; i < NR_MT_CPU_DVFS; i++) + g_u4Volt[i] = mt_cpufreq_get_cur_volt_symbol(i) / 100; + } + + if (gpu_volt_enable) { + if (mt_gpufreq_get_cur_volt_symbol) + g_u4GPUVolt = ((mt_gpufreq_get_cur_volt_symbol() + 50) / 100); + } +} + +static void get_volt_notify(unsigned long long stamp, int cpu) +{ + schedule_delayed_work(&get_volt_dwork, 0); +} + +static void met_ptpod_polling_by_wq(struct work_struct *work) +{ + update_volt_value(); + + ms_ptpod(); +} + +static void met_ptpod_polling(unsigned long long stamp, int cpu) +{ + update_volt_value(); + + ms_ptpod(); +} + +/* + * Called from "met-cmd --start" + */ +static void ptpod_start(void) +{ +#if 0 + met_gpufreq_setvolt_registerCB(ptpod_gpu_voltSampler, kFOR_MET_PTPOD_USE); +#endif + + if (get_volt_by_wq) { + met_ptpod.timed_polling = get_volt_notify; + + INIT_DELAYED_WORK(&get_volt_dwork, met_ptpod_polling_by_wq); + } else + met_ptpod.timed_polling = met_ptpod_polling; + + update_volt_value(); + + ms_ptpod(); + +#if 0 + /* register callback */ + if (mt_cpufreq_setvolt_registerCB_symbol) + mt_cpufreq_setvolt_registerCB_symbol(ptpod_cpu_voltSampler); +#endif + + ptpod_started = 1; +} + +/* + * Called from "met-cmd --stop" + */ +static void ptpod_stop(void) +{ + ptpod_started = 0; + +#if 0 + /* unregister callback */ + if (mt_cpufreq_setvolt_registerCB_symbol) + mt_cpufreq_setvolt_registerCB_symbol(NULL); +#endif + + if (get_volt_by_wq) + cancel_delayed_work_sync(&get_volt_dwork); + + update_volt_value(); + + ms_ptpod(); + +#if 0 + met_gpufreq_setvolt_registerCB(NULL, kFOR_MET_PTPOD_USE); +#endif +} + +static char help[] = + " --ptpod Measure CPU/GPU voltage\n"; +static int ptpod_print_help(char *buf, int len) +{ + return snprintf(buf, PAGE_SIZE, help); +} + +/* + * It will be called back when run "met-cmd --extract" and mode is 1 + */ +static int ptpod_print_header(char *buf, int len) +{ + int str_len = 0; + + if (g_ap_ptpod) { + int i; + + str_len += snprintf(buf + str_len, PAGE_SIZE - str_len, + "met-info [000] 0.0: met_ptpod_header: "); + + for (i = 0; i < NR_MT_CPU_DVFS; i++) + str_len += snprintf(buf + str_len, PAGE_SIZE - str_len, "CPUVolt_%d,", i); + + if (gpu_volt_enable) + str_len += snprintf(buf + str_len, PAGE_SIZE - str_len, "GPUVolt,"); + + buf[str_len-1] = '\n'; + + str_len += snprintf(buf + str_len, PAGE_SIZE - str_len, + "met-info [000] 0.0: met_ptpod_version: ap\n"); + } else { + if (gpu_volt_enable) { + str_len += snprintf(buf + str_len, PAGE_SIZE - str_len, + "met-info [000] 0.0: met_ptpod_header: "); + + str_len += snprintf(buf + str_len, PAGE_SIZE - str_len, "GPUVolt\n"); + } + + str_len += snprintf(buf + str_len, PAGE_SIZE - str_len, + "met-info [000] 0.0: met_ptpod_version: sspm\n"); + } + + if (gpu_volt_enable) + str_len += snprintf(buf + str_len, PAGE_SIZE - str_len, + "met-info [000] 0.0: met_ptpod_gpu_volt_enable: YES\n"); + else + str_len += snprintf(buf + str_len, PAGE_SIZE - str_len, + "met-info [000] 0.0: met_ptpod_gpu_volt_enable: NO\n"); + + return str_len; +} + +struct metdevice met_ptpod = { + .name = "ptpod", + .owner = THIS_MODULE, + .type = MET_TYPE_PMU, + .cpu_related = 0, + .create_subfs = ptpod_create, + .delete_subfs = ptpod_delete, + .start = ptpod_start, + .stop = ptpod_stop, + .timed_polling = met_ptpod_polling, + .print_help = ptpod_print_help, + .print_header = ptpod_print_header, +}; +EXPORT_SYMBOL(met_ptpod); diff --git a/drivers/misc/mediatek/met_drv_v2/common/met_struct.h b/drivers/misc/mediatek/met_drv_v2/common/met_struct.h new file mode 100644 index 0000000000000000000000000000000000000000..ee63a8eecb3aedb5de8466e4d3c1f15f8b34bcb6 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/met_struct.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef _MET_STRUCT_H_ +#define _MET_STRUCT_H_ + +#include + +struct met_cpu_struct { + struct hrtimer hrtimer; + struct delayed_work dwork; +/* struct kmem_cache *cachep; */ +/* struct list_head sample_head; */ +/* spinlock_t list_lock; */ +/* struct mutex list_sync_lock; */ + int work_enabled; + int cpu; + int hrtimer_online_check; +/* char name[16]; */ +}; + +DECLARE_PER_CPU(struct met_cpu_struct, met_cpu); + +#endif /* _MET_STRUCT_H_ */ diff --git a/drivers/misc/mediatek/met_drv_v2/common/met_tag.h b/drivers/misc/mediatek/met_drv_v2/common/met_tag.h new file mode 100644 index 0000000000000000000000000000000000000000..d13cd46195e009e6ea9e326aad63fbed6ff34056 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/met_tag.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef __MET_TAG_EX_H__ +#define __MET_TAG_EX_H__ + +#ifdef BUILD_WITH_MET +void force_sample(void *unused); +#else +#include +#endif + +/* Black List Table */ +struct bltable_t { + struct mutex mlock; + /* flag - Bit31: Global ON/OFF; Bit0~30: ON/OF slot map of class_id */ + unsigned int flag; + int class_id[MAX_EVENT_CLASS]; +}; + +extern void met_sched_switch(struct task_struct *prev, struct task_struct *next); + +extern int tracing_mark_write(int type, unsigned int class_id, + const char *name, unsigned int value, + unsigned int value2, unsigned int value3); + +#endif /* __MET_TAG_EX_H__ */ diff --git a/drivers/misc/mediatek/met_drv_v2/common/met_tag_ex.c b/drivers/misc/mediatek/met_drv_v2/common/met_tag_ex.c new file mode 100644 index 0000000000000000000000000000000000000000..f22bbee8aefb3c40f3d2deb2447e6e3187e7cc65 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/met_tag_ex.c @@ -0,0 +1,607 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#define BUILD_WITH_MET + +#ifdef MET_USER_EVENT_SUPPORT + +#include +#include +#include +#include +#include +/* #include */ +#include + +#include "met_drv.h" +#include "met_tag.h" +#include "interface.h" +#include "switch.h" + +struct bltable_t bltab; + +static int dump_buffer_size; +static int dump_data_size; +static int dump_overrun; +static int dump_overrun_size; +static int dump_seq_no; +static void *dump_buffer; + +#define OPFLAG_OVERWRITE 0x1 +static unsigned int options_flag; + +#define DEVICE_NAME "met_tag" + +/* #define ERRF_ENABLE */ +/* #define DEBF_ENABLE */ + +#ifdef ERRF_ENABLE +#define MSG_ERR "Error:["DEVICE_NAME"]" +#define ERRF(args...) pr_debug(MSG_ERR args) +#else +#define ERRF(args...) +#endif + +#ifdef DEBF_ENABLE +#define MSG_IFO "Info :["DEVICE_NAME"]" +#define DEBF(args...) pr_debug(MSG_IFO args) +#else +#define DEBF(args...) +#endif + +static int is_enabled(unsigned int class_id) +{ + int i; + + if (bltab.flag == 0) + return 1; + if (bltab.flag & MET_CLASS_ALL) + return 0; + + for (i = 0; i < MAX_EVENT_CLASS; i++) { + if ((bltab.flag & (1 << i)) && (bltab.class_id[i] == class_id)) + return 0; + } + + return 1; +} + +noinline int tracing_mark_write(int type, unsigned int class_id, + const char *name, unsigned int value, + unsigned int value2, unsigned int value3) +{ + if (type == TYPE_MET_SUSPEND) { + MET_TRACE("C|0|MET_SUSPEND|1"); + return 0; + } + if (type == TYPE_MET_RESUME) { + MET_TRACE("C|0|MET_SUSPEND|0"); + return 0; + } + if (!is_enabled(class_id)) + return 0; + switch (type) { + case TYPE_START: + MET_TRACE("B|%d|%s\n", class_id, name); + break; + case TYPE_END: + MET_TRACE("E|%s\n", name); + break; + case TYPE_ONESHOT: + MET_TRACE("C|%d|%s|%d\n", class_id, name, value); + break; + case TYPE_ASYNC_START: + MET_TRACE("S|%d|%s|%d\n", class_id, name, value); + break; + case TYPE_ASYNC_END: + MET_TRACE("F|%d|%s|%d\n", class_id, name, value); + break; + case TYPE_DUMP: + MET_TRACE("D|%d|%s|%d|%d|%d\n", class_id, name, value, value2, value3); + break; + default: + return -1; + } + return 0; +} + +int met_tag_init(void) +{ + memset(&bltab, 0, sizeof(struct bltable_t)); + bltab.flag = MET_CLASS_ALL; + mutex_init(&bltab.mlock); + return 0; +} + +int met_tag_uninit(void) +{ + met_set_dump_buffer_real(0); + return 0; +} + +int met_tag_start_real(unsigned int class_id, const char *name) +{ + int ret; + + ret = tracing_mark_write(TYPE_START, class_id, name, 0, 0, 0); +#if 0 + if ((met_switch.mode & MT_SWITCH_TAGPOLLING)) { + /* tag polling only enable when MT_SWITCH_TAGPOLLING is config */ + force_sample(NULL); + } +#endif + return ret; +} +EXPORT_SYMBOL(met_tag_start_real); + +int met_tag_end_real(unsigned int class_id, const char *name) +{ + int ret; +#if 0 + if ((met_switch.mode & MT_SWITCH_TAGPOLLING)) { + /* tag polling only enable when MT_SWITCH_TAGPOLLING is config */ + force_sample(NULL); + } +#endif + ret = tracing_mark_write(TYPE_END, class_id, name, 0, 0, 0); + + return ret; +} +EXPORT_SYMBOL(met_tag_end_real); + +int met_tag_async_start_real(unsigned int class_id, const char *name, unsigned int cookie) +{ + int ret; + + ret = tracing_mark_write(TYPE_ASYNC_START, class_id, name, cookie, 0, 0); +#if 0 + if ((met_switch.mode & MT_SWITCH_TAGPOLLING)) { + /* tag polling only enable when MT_SWITCH_TAGPOLLING is config */ + force_sample(NULL); + } +#endif + return ret; +} + +int met_tag_async_end_real(unsigned int class_id, const char *name, unsigned int cookie) +{ + int ret; + +#if 0 + if ((met_switch.mode & MT_SWITCH_TAGPOLLING)) { + /* tag polling only enable when MT_SWITCH_TAGPOLLING is config */ + force_sample(NULL); + } +#endif + ret = tracing_mark_write(TYPE_ASYNC_END, class_id, name, cookie, 0, 0); + return ret; +} + +int met_tag_oneshot_real(unsigned int class_id, const char *name, unsigned int value) +{ + int ret; + + ret = tracing_mark_write(TYPE_ONESHOT, class_id, name, value, 0, 0); +#if 0 + if ((met_switch.mode & MT_SWITCH_TAGPOLLING)) { + /* tag polling only enable when MT_SWITCH_TAGPOLLING is config */ + force_sample(NULL); + } +#endif + return ret; +} +EXPORT_SYMBOL(met_tag_oneshot_real); + +int met_tag_userdata_real(char *pData) +{ + MET_TRACE("%s\n", pData); + return 0; +} + +int met_tag_dump_real(unsigned int class_id, const char *name, void *data, unsigned int length) +{ + int ret; + + if ((dump_data_size + length + sizeof(int)) > dump_buffer_size) { + if (options_flag & OPFLAG_OVERWRITE) { + dump_overrun_size = dump_data_size; + dump_overrun++; + memcpy(dump_buffer, &dump_seq_no, sizeof(int)); + memcpy(dump_buffer + sizeof(int), data, length); + ret = tracing_mark_write(TYPE_DUMP, class_id, name, + dump_seq_no++, 0, length + sizeof(int)); + dump_data_size = length + sizeof(int); + } else { + ret = tracing_mark_write(TYPE_DUMP, class_id, name, dump_seq_no++, 0, 0); + } + } else { + memcpy(dump_buffer + dump_data_size, &dump_seq_no, sizeof(int)); + memcpy(dump_buffer + dump_data_size + sizeof(int), data, length); + ret = tracing_mark_write(TYPE_DUMP, class_id, name, + dump_seq_no++, dump_data_size, length + sizeof(int)); + dump_data_size += length + sizeof(int); + } + return ret; +} + +int met_tag_disable_real(unsigned int class_id) +{ + int i; + + mutex_lock(&bltab.mlock); + + if (class_id == MET_CLASS_ALL) { + bltab.flag |= MET_CLASS_ALL; + mutex_unlock(&bltab.mlock); + return 0; + } + + for (i = 0; i < MAX_EVENT_CLASS; i++) { + if ((bltab.flag & (1 << i)) == 0) { + bltab.class_id[i] = class_id; + bltab.flag |= (1 << i); + mutex_unlock(&bltab.mlock); + return 0; + } + } + + mutex_unlock(&bltab.mlock); + return -1; +} + +int met_tag_enable_real(unsigned int class_id) +{ + int i; + + mutex_lock(&bltab.mlock); + + if (class_id == MET_CLASS_ALL) { + bltab.flag &= (~MET_CLASS_ALL); + mutex_unlock(&bltab.mlock); + return 0; + } + + for (i = 0; i < MAX_EVENT_CLASS; i++) { + if ((bltab.flag & (1 << i)) && (bltab.class_id[i] == class_id)) { + bltab.flag &= (~(1 << i)); + bltab.class_id[i] = 0; + mutex_unlock(&bltab.mlock); + return 0; + } + } + + mutex_unlock(&bltab.mlock); + return -1; +} + +int met_set_dump_buffer_real(int size) +{ + if (dump_buffer_size && dump_buffer) { + free_pages((unsigned long)dump_buffer, get_order(dump_buffer_size)); + dump_data_size = 0; + dump_overrun = 0; + dump_overrun_size = 0; + dump_seq_no = 0; + dump_buffer_size = 0; + } + /* size is 0 means free dump buffer */ + if (size == 0) + return 0; + + if (size < 0) + return -1; + + size = (size + (PAGE_SIZE - 1)) & (~(PAGE_SIZE - 1)); + dump_buffer = (void *)__get_free_pages(GFP_KERNEL, get_order(size)); + if (dump_buffer == NULL) { + ERRF("can not allocate buffer to copy\n"); + return -ENOMEM; + } + + dump_buffer_size = size; + return dump_buffer_size; +} + +int met_save_dump_buffer_real(const char *pathname) +{ + int size, ret = 0; + struct file *outfp = NULL; + mm_segment_t oldfs; + + if (dump_data_size == 0) + return 0; + + if (dump_data_size < 0 || dump_overrun_size < 0) + return -1; + + if (dump_buffer == NULL || dump_buffer_size <= 0) + return -1; + + if (dump_overrun) + size = dump_overrun_size; + else + size = dump_data_size; + + if (size >= dump_buffer_size) + return -1; + + oldfs = get_fs(); + set_fs(KERNEL_DS); + + outfp = filp_open(pathname, O_WRONLY | O_TRUNC | O_CREAT, 0664); + if (unlikely(outfp == NULL)) { + ERRF("can not open saved file for write\n"); + return -EIO; + } + + ret = vfs_write(outfp, dump_buffer, size, &(outfp->f_pos)); + if (ret < 0) + ERRF("can not write to dump file\n"); + else { + dump_data_size = 0; + dump_overrun = 0; + dump_overrun_size = 0; + dump_seq_no = 0; + } + + set_fs(oldfs); + + if (outfp != NULL) + filp_close(outfp, NULL); + + return 0; +} + +int met_save_log_real(const char *pathname) +{ + int len, ret = 0; + struct file *infp = NULL; + struct file *outfp = NULL; + void *ptr = NULL; + mm_segment_t oldfs; + + infp = filp_open("/sys/kernel/debug/tracing/trace", O_RDONLY, 0); + if (unlikely(infp == NULL)) { + ERRF("can not open trace file for read\n"); + ret = -1; + goto save_out; + } + + outfp = filp_open(pathname, O_WRONLY | O_TRUNC | O_CREAT, 0664); + if (unlikely(outfp == NULL)) { + ERRF("can not open saved file for write\n"); + ret = -2; + goto save_out; + } + + ptr = (void *)__get_free_pages(GFP_KERNEL, 2); + if (ptr == NULL) { + ERRF("can not allocate buffer to copy\n"); + ret = -3; + goto save_out; + } + + oldfs = get_fs(); + set_fs(KERNEL_DS); + + while (1) { + len = vfs_read(infp, ptr, PAGE_SIZE << 2, &(infp->f_pos)); + if (len < 0) { + ERRF("can not read from trace file\n"); + ret = -3; + break; + } else if (len == 0) { + break; + } + + ret = vfs_write(outfp, ptr, len, &(outfp->f_pos)); + if (ret < 0) { + ERRF("can not write to saved file\n"); + break; + } + } + + set_fs(oldfs); + +save_out: + if (ptr != NULL) + free_pages((unsigned long)ptr, 2); + if (infp != NULL) + filp_close(infp, NULL); + if (outfp != NULL) + filp_close(outfp, NULL); + + return ret; +} + +#ifdef BUILD_WITH_MET +#include +#include +/* =========================================================================== */ +/* misc file nodes */ +/* =========================================================================== */ +static ssize_t enable_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + int i; + + i = snprintf(buf, PAGE_SIZE, "%d\n", (bltab.flag >> 31) ? 0 : 1); + return i; +} + +static ssize_t enable_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, + size_t n) +{ + int value; + + if ((n == 0) || (buf == NULL)) + return -EINVAL; + if (kstrtoint(buf, 0, &value) != 0) + return -EINVAL; + + mutex_lock(&bltab.mlock); + + if (value == 1) + bltab.flag &= (~MET_CLASS_ALL); + else + bltab.flag |= MET_CLASS_ALL; + + mutex_unlock(&bltab.mlock); + + return n; +} + +static struct kobject *kobj_tag; +static struct kobj_attribute enable_attr = __ATTR(enable, 0664, enable_show, enable_store); + +static ssize_t dump_buffer_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + int i, size; + + if (dump_overrun) + size = dump_overrun_size; + else + size = dump_data_size; + + i = snprintf(buf, PAGE_SIZE, "Buffer Size (KB)=%d\nData Size (KB)=%d\nOverrun=%d\n", + dump_buffer_size >> 10, size >> 10, dump_overrun); + return i; +} + +static ssize_t dump_buffer_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, + size_t n) +{ + int ret, value; + + if ((n == 0) || (buf == NULL)) + return -EINVAL; + if (kstrtoint(buf, 0, &value) != 0) + return -EINVAL; + + ret = met_set_dump_buffer_real(value << 10); + + if (ret < 0) + return ret; + + return n; +} + +static struct kobj_attribute dump_buffer_attr = +__ATTR(dump_buffer_kb, 0664, dump_buffer_show, dump_buffer_store); + +static ssize_t options_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + int i = 0; + + buf[0] = 0; + + if (options_flag == 0) { + strncat(buf, "none\n", PAGE_SIZE - 1 - i); + i += 5; + } + + if (options_flag & OPFLAG_OVERWRITE) { + strncat(buf, "overwrite\n", PAGE_SIZE - 1 - i); + i += 10; + } + + return i; +} + +static ssize_t options_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, + size_t n) +{ + if ((n == 0) || (buf == NULL)) + return -EINVAL; + + if ((n == 1) && (buf[0] == 0xA)) { + options_flag = 0; + return n; + } + + if (strncmp(buf, "overwrite", 9) == 0) + options_flag |= OPFLAG_OVERWRITE; + else + return -EINVAL; + + return n; +} + +static struct kobj_attribute options_attr = __ATTR(options, 0664, options_show, options_store); + +int tag_reg(struct file_operations *const fops, struct kobject *kobj) +{ + int ret; + + kobj_tag = kobject_create_and_add("tag", kobj); + if (kobj_tag == NULL) { + ERRF("can not create kobject: kobj_bus\n"); + return -1; + } + + ret = sysfs_create_file(kobj_tag, &enable_attr.attr); + if (ret != 0) { + ERRF("Failed to create enable in sysfs\n"); + kobject_del(kobj_tag); + kobject_put(kobj_tag); + kobj_tag = NULL; + return ret; + } + + ret = sysfs_create_file(kobj_tag, &dump_buffer_attr.attr); + if (ret != 0) { + ERRF("Failed to create dump_buffer in sysfs\n"); + sysfs_remove_file(kobj_tag, &enable_attr.attr); + kobject_del(kobj_tag); + kobject_put(kobj_tag); + kobj_tag = NULL; + return ret; + } + + ret = sysfs_create_file(kobj_tag, &options_attr.attr); + if (ret != 0) { + ERRF("Failed to create options in sysfs\n"); + sysfs_remove_file(kobj_tag, &enable_attr.attr); + sysfs_remove_file(kobj_tag, &dump_buffer_attr.attr); + kobject_del(kobj_tag); + kobject_put(kobj_tag); + kobj_tag = NULL; + return ret; + } + + met_tag_init(); + + return 0; +} + +int tag_unreg(void) +{ + met_tag_uninit(); + sysfs_remove_file(kobj_tag, &enable_attr.attr); + sysfs_remove_file(kobj_tag, &dump_buffer_attr.attr); + sysfs_remove_file(kobj_tag, &options_attr.attr); + kobject_del(kobj_tag); + kobject_put(kobj_tag); + kobj_tag = NULL; + + return 0; +} + +#endif /* BUILD_WITH_MET */ + +#else /* not MET_USER_EVENT_SUPPORT */ + +#ifdef BUILD_WITH_MET +int tag_reg(void *p, void *q) +{ + return 0; +} + +int tag_unreg(void) +{ + return 0; +} +#endif + +#endif /* MET_USER_EVENT_SUPPORT */ diff --git a/drivers/misc/mediatek/met_drv_v2/common/met_vcoredvfs.c b/drivers/misc/mediatek/met_drv_v2/common/met_vcoredvfs.c new file mode 100644 index 0000000000000000000000000000000000000000..7901ecc7365e7f56d4e4d186a656b8832130755c --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/met_vcoredvfs.c @@ -0,0 +1,306 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include +#include +#include +#include +#include + +#include + +#define MET_USER_EVENT_SUPPORT +#include "met_drv.h" +#include "trace.h" + +#include "core_plf_init.h" +#include "core_plf_trace.h" + +/*======================================================================*/ +/* Global variable definitions */ +/*======================================================================*/ + +/* Global variables */ +struct metdevice met_vcoredvfs; +int polling_mode = 1; + +/* external symbols */ +#define DEFAULT_INFO_NUM 3 +#define DEFAULT_SRC_NUM 1 + +char *default_info_name[DEFAULT_INFO_NUM] = { + "OPP", + "VOLT", + "FREQ" +}; + +char *default_src_name[DEFAULT_SRC_NUM] = { + "MD2SPM" +}; + +unsigned int opp_info[DEFAULT_INFO_NUM]; +unsigned int src_req[DEFAULT_SRC_NUM]; + +static int met_vcorefs_get_num_opp(void) +{ + if (vcorefs_get_num_opp_symbol) + return vcorefs_get_num_opp_symbol(); + else + return 0; +} + +static int met_vcorefs_get_opp_info_num(void) +{ + if (vcorefs_get_opp_info_num_symbol) + return vcorefs_get_opp_info_num_symbol(); + else + return DEFAULT_INFO_NUM; +} + + +static int met_vcorefs_get_src_req_num(void) +{ + if (vcorefs_get_src_req_num_symbol) + return vcorefs_get_src_req_num_symbol(); + else + return DEFAULT_SRC_NUM; +} + + +static char **met_vcorefs_get_opp_info_name(void) +{ + if (vcorefs_get_opp_info_name_symbol) + return vcorefs_get_opp_info_name_symbol(); + else + return default_info_name; +} + +static char **met_vcorefs_get_src_req_name(void) +{ + if (vcorefs_get_src_req_name_symbol) + return vcorefs_get_src_req_name_symbol(); + else + return default_src_name; +} + +static unsigned int *met_vcorefs_get_opp_info(void) +{ + if (vcorefs_get_opp_info_symbol) + return vcorefs_get_opp_info_symbol(); + + return opp_info; +} + +static unsigned int *met_vcorefs_get_src_req(void) +{ + if (vcorefs_get_src_req_symbol) + return vcorefs_get_src_req_symbol(); + + return src_req; +} + + +/*======================================================================*/ +/* File Node definitions */ +/*======================================================================*/ + +static struct kobject *kobj_met_vcoredvfs; + +static ssize_t vcorefs_polling_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf); +static ssize_t vcorefs_polling_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, size_t n); +static struct kobj_attribute vcorefs_polling_attr = +__ATTR(vcorefs_polling, 0664, vcorefs_polling_show, vcorefs_polling_store); + +/*======================================================================*/ +/* Utilities */ +/*======================================================================*/ + +static inline int do_vcoredvfs(void) +{ + return met_vcoredvfs.mode; +} + +/*======================================================================*/ +/* Data Output */ +/*======================================================================*/ + +noinline void vcorefs(unsigned char cnt, unsigned int *value) +{ + char *SOB, *EOB; + + MET_TRACE_GETBUF(&SOB, &EOB); + EOB = ms_formatH_EOL(EOB, cnt, value); + MET_TRACE_PUTBUF(SOB, EOB); +} + +noinline void vcorefs_kicker(unsigned char cnt, int *value) +{ + char *SOB, *EOB; + + MET_TRACE_GETBUF(&SOB, &EOB); + EOB = ms_formatH_EOL(EOB, cnt, value); + MET_TRACE_PUTBUF(SOB, EOB); +} + +noinline void ms_vcorefs(unsigned char cnt, unsigned int *value) +{ + char *SOB, *EOB; + + MET_TRACE_GETBUF(&SOB, &EOB); + EOB = ms_formatH_EOL(EOB, cnt, value); + MET_TRACE_PUTBUF(SOB, EOB); +} + +/*======================================================================*/ +/* Callback functions */ +/*======================================================================*/ +void vcoredvfs_irq(int opp) +{ + int num; + unsigned int *out; + + num = met_vcorefs_get_opp_info_num(); + out = met_vcorefs_get_opp_info(); + + vcorefs(num, out); +} + +/*======================================================================*/ +/* File Node Operations */ +/*======================================================================*/ +static ssize_t vcorefs_polling_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", polling_mode); +} + +static ssize_t vcorefs_polling_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, size_t n) +{ + int value; + + if ((n == 0) || (buf == NULL)) + return -EINVAL; + + if (kstrtoint(buf, 0, &value) != 0) + return -EINVAL; + + if (value < 0) + return -EINVAL; + + polling_mode = value; + + return n; +} + +/*======================================================================*/ +/* MET Device Operations */ +/*======================================================================*/ +static int met_vcoredvfs_create(struct kobject *parent) +{ + int ret = 0; + + kobj_met_vcoredvfs = parent; + + ret = sysfs_create_file(kobj_met_vcoredvfs, &vcorefs_polling_attr.attr); + if (ret != 0) { + pr_debug("Failed to create vcoredvfs in sysfs\n"); + return ret; + } + + return ret; +} + +static void met_vcoredvfs_delete(void) +{ + sysfs_remove_file(kobj_met_vcoredvfs, &vcorefs_polling_attr.attr); +} + +static void met_vcoredvfs_start(void) +{ + vcoredvfs_irq(-1); +} + +static void met_vcoredvfs_stop(void) +{ + vcoredvfs_irq(-1); +} + +static void met_vcoredvfs_polling(unsigned long long stamp, int cpu) +{ + int num; + unsigned int *out; + + if (!do_vcoredvfs()) + return; + + /* vcorefs opp information */ + if (polling_mode) + vcoredvfs_irq(-1); + + /* vcorefs source request */ + num = met_vcorefs_get_src_req_num(); + out = met_vcorefs_get_src_req(); + + ms_vcorefs(num, out); +} + +static const char help[] = + " --vcoredvfs monitor VCORE DVFS\n"; +static int vcoredvfs_print_help(char *buf, int len) +{ + return snprintf(buf, PAGE_SIZE, help); +} + +static const char header_dvfs[] = "met-info [000] 0.0: met_vcorefs_header:"; + +static const char header_ms_dvfs[] = "met-info [000] 0.0: ms_vcorefs_header:"; + +static int vcoredvfs_print_header(char *buf, int len) +{ + int ret = 0; + int idx = 0; + int num = 0; + char **header; + + ret = snprintf(buf, PAGE_SIZE, "met-info [000] 0.0: met_vcorefs_cfg: NUM_OPP:%d\n", met_vcorefs_get_num_opp()); + + /* opp information */ + num = met_vcorefs_get_opp_info_num(); + header = met_vcorefs_get_opp_info_name(); + + ret += snprintf(buf + ret, PAGE_SIZE, header_dvfs); + for (idx = 0; idx < num; idx++) + ret += snprintf(buf + ret, PAGE_SIZE - ret, "%s,", header[idx]); + buf[strlen(buf)-1] = '\n'; + + /* source requests */ + num = met_vcorefs_get_src_req_num(); + header = met_vcorefs_get_src_req_name(); + + ret += snprintf(buf + ret, PAGE_SIZE - ret, header_ms_dvfs); + for (idx = 0; idx < num; idx++) + ret += snprintf(buf + ret, PAGE_SIZE - ret, "%s,", header[idx]); + buf[strlen(buf)-1] = '\n'; + + met_vcoredvfs.mode = 0; + + return ret; +} + +struct metdevice met_vcoredvfs = { + .name = "vcoredvfs", + .owner = THIS_MODULE, + .type = MET_TYPE_BUS, + .create_subfs = met_vcoredvfs_create, + .delete_subfs = met_vcoredvfs_delete, + .cpu_related = 0, + .start = met_vcoredvfs_start, + .stop = met_vcoredvfs_stop, + .polling_interval = 1, /* ms */ + .timed_polling = met_vcoredvfs_polling, + .print_help = vcoredvfs_print_help, + .print_header = vcoredvfs_print_header, +}; diff --git a/drivers/misc/mediatek/met_drv_v2/common/met_vcoredvfs_44.c b/drivers/misc/mediatek/met_drv_v2/common/met_vcoredvfs_44.c new file mode 100644 index 0000000000000000000000000000000000000000..2e22bce24b0e2af1890f0457ff579ce83444c48d --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/met_vcoredvfs_44.c @@ -0,0 +1,365 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018 MediaTek Inc. + */ + +#include +#include +#include +#include +#include + +#include +#include + +#define MET_USER_EVENT_SUPPORT +#include "met_drv.h" +#include "trace.h" + +#include "core_plf_init.h" +#include "core_plf_trace.h" + +/*======================================================================*/ +/* Global variable definitions */ +/*======================================================================*/ + +/* Global variables */ +struct metdevice met_vcoredvfs; +int polling_mode = 1; + +/* external symbols */ +#define DEFAULT_INFO_NUM 3 +#define DEFAULT_SRC_NUM 1 + +char *default_info_name[DEFAULT_INFO_NUM] = { + "OPP", + "VOLT", + "FREQ" +}; + +char *default_src_name[DEFAULT_SRC_NUM] = { + "MD2SPM" +}; + +unsigned int opp_info[DEFAULT_INFO_NUM]; +unsigned int src_req[DEFAULT_SRC_NUM]; + +static char *met_governor_get_kicker_name(int id) +{ + if (governor_get_kicker_name_symbol) + return governor_get_kicker_name_symbol(id); + else + return "KIR_UNKNOWN"; +} + +static int met_vcorefs_get_num_opp(void) +{ + if (vcorefs_get_num_opp_symbol) + return vcorefs_get_num_opp_symbol(); + else + return 0; +} + +static int met_vcorefs_get_opp_info_num(void) +{ + if (vcorefs_get_opp_info_num_symbol) + return vcorefs_get_opp_info_num_symbol(); + else + return DEFAULT_INFO_NUM; +} + +static char **met_vcorefs_get_opp_info_name(void) +{ + if (vcorefs_get_opp_info_name_symbol) + return vcorefs_get_opp_info_name_symbol(); + else + return default_info_name; +} + +static char **met_vcorefs_get_src_req_name(void) +{ + if (vcorefs_get_src_req_name_symbol) + return vcorefs_get_src_req_name_symbol(); + else + return default_src_name; +} + +static int met_vcorefs_get_src_req_num(void) +{ + if (vcorefs_get_src_req_num_symbol) + return vcorefs_get_src_req_num_symbol(); + else + return DEFAULT_SRC_NUM; +} + +static unsigned int *met_vcorefs_get_opp_info(void) +{ + int count = 0; + + if (vcorefs_get_opp_info_symbol) + return vcorefs_get_opp_info_symbol(); + + if (vcorefs_get_hw_opp_symbol) + opp_info[count++] = vcorefs_get_hw_opp_symbol(); + if (vcorefs_get_curr_vcore_symbol) + opp_info[count++] = vcorefs_get_curr_vcore_symbol(); /* uV */ + if (vcorefs_get_curr_ddr_symbol) + opp_info[count++] = vcorefs_get_curr_ddr_symbol(); /* kHz */ + + return opp_info; +} + +static unsigned int *met_vcorefs_get_src_req(void) +{ + if (vcorefs_get_src_req_symbol) + return vcorefs_get_src_req_symbol(); + + if (spm_vcorefs_get_MD_status_symbol) + src_req[0] = spm_vcorefs_get_MD_status_symbol(); + return src_req; +} + + +/*======================================================================*/ +/* File Node definitions */ +/*======================================================================*/ + +static struct kobject *kobj_met_vcoredvfs; + +static ssize_t vcorefs_polling_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf); +static ssize_t vcorefs_polling_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, size_t n); +static struct kobj_attribute vcorefs_polling_attr = +__ATTR(vcorefs_polling, 0664, vcorefs_polling_show, vcorefs_polling_store); + +/*======================================================================*/ +/* Utilities */ +/*======================================================================*/ + +static inline int do_vcoredvfs(void) +{ + return met_vcoredvfs.mode; +} + +/*======================================================================*/ +/* Data Output */ +/*======================================================================*/ + +noinline void vcorefs(unsigned char cnt, unsigned int *value) +{ + char *SOB, *EOB; + + MET_TRACE_GETBUF(&SOB, &EOB); + EOB = ms_formatH_EOL(EOB, cnt, value); + MET_TRACE_PUTBUF(SOB, EOB); +} + +noinline void vcorefs_kicker(unsigned char cnt, int *value) +{ + char *SOB, *EOB; + + MET_TRACE_GETBUF(&SOB, &EOB); + EOB = ms_formatH_EOL(EOB, cnt, value); + MET_TRACE_PUTBUF(SOB, EOB); +} + +noinline void ms_vcorefs(unsigned char cnt, unsigned int *value) +{ + char *SOB, *EOB; + + MET_TRACE_GETBUF(&SOB, &EOB); + EOB = ms_formatH_EOL(EOB, cnt, value); + MET_TRACE_PUTBUF(SOB, EOB); +} + +/*======================================================================*/ +/* Callback functions */ +/*======================================================================*/ +void sw_kicker_req(enum dvfs_kicker kicker, enum dvfs_opp opp) +{ + if (!do_vcoredvfs()) + return; + + if (kicker_table_symbol) + vcorefs_kicker(NUM_KICKER, kicker_table_symbol); +} + +void vcoredvfs_irq(int opp) +{ + int num; + unsigned int *out; + + num = met_vcorefs_get_opp_info_num(); + out = met_vcorefs_get_opp_info(); + + vcorefs(num, out); +} + +/*======================================================================*/ +/* File Node Operations */ +/*======================================================================*/ +static ssize_t vcorefs_polling_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", polling_mode); +} + +static ssize_t vcorefs_polling_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, size_t n) +{ + int value; + + if ((n == 0) || (buf == NULL)) + return -EINVAL; + + if (kstrtoint(buf, 0, &value) != 0) + return -EINVAL; + + if (value < 0) + return -EINVAL; + + polling_mode = value; + + return n; +} + +/*======================================================================*/ +/* MET Device Operations */ +/*======================================================================*/ +static int met_vcoredvfs_create(struct kobject *parent) +{ + int ret = 0; + + kobj_met_vcoredvfs = parent; + + ret = sysfs_create_file(kobj_met_vcoredvfs, &vcorefs_polling_attr.attr); + if (ret != 0) { + pr_debug("Failed to create vcoredvfs in sysfs\n"); + return ret; + } + + return ret; +} + +static void met_vcoredvfs_delete(void) +{ + sysfs_remove_file(kobj_met_vcoredvfs, &vcorefs_polling_attr.attr); +} + +static void met_vcoredvfs_start(void) +{ + if (kicker_table_symbol) + vcorefs_kicker(NUM_KICKER, kicker_table_symbol); + + vcoredvfs_irq(-1); + + if (!polling_mode && spm_vcorefs_register_handler_symbol) + spm_vcorefs_register_handler_symbol(vcoredvfs_irq); + + if (vcorefs_register_req_notify_symbol) + vcorefs_register_req_notify_symbol(sw_kicker_req); + else + MET_TRACE("vcorefs_register_req_notify not exist!\n"); + + if (!polling_mode && vcorefs_enable_debug_isr_symbol) + vcorefs_enable_debug_isr_symbol(true); +} + +static void met_vcoredvfs_stop(void) +{ + if (!polling_mode && vcorefs_enable_debug_isr_symbol) + vcorefs_enable_debug_isr_symbol(false); + + if (vcorefs_register_req_notify_symbol) + vcorefs_register_req_notify_symbol(NULL); + + if (spm_vcorefs_register_handler_symbol) + spm_vcorefs_register_handler_symbol(NULL); + + if (kicker_table_symbol) + vcorefs_kicker(NUM_KICKER, kicker_table_symbol); + vcoredvfs_irq(-1); +} + +static void met_vcoredvfs_polling(unsigned long long stamp, int cpu) +{ + int num; + unsigned int *out; + + if (!do_vcoredvfs()) + return; + + /* vcorefs opp information */ + if (polling_mode) + vcoredvfs_irq(-1); + + /* vcorefs source request */ + num = met_vcorefs_get_src_req_num(); + out = met_vcorefs_get_src_req(); + + ms_vcorefs(num, out); +} + +static const char help[] = + " --vcoredvfs monitor VCORE DVFS\n"; +static int vcoredvfs_print_help(char *buf, int len) +{ + return snprintf(buf, PAGE_SIZE, help); +} + +static const char header_dvfs[] = "met-info [000] 0.0: met_vcorefs_header:"; + +static const char header_kicker[] = "met-info [000] 0.0: met_vcorefs_kicker_header:"; + +static const char header_ms_dvfs[] = "met-info [000] 0.0: ms_vcorefs_header:"; + +static int vcoredvfs_print_header(char *buf, int len) +{ + int ret; + int idx, num; + char **header; + + ret = snprintf(buf, PAGE_SIZE, "met-info [000] 0.0: met_vcorefs_cfg: NUM_OPP:%d\n", met_vcorefs_get_num_opp()); + + /* opp information */ + num = met_vcorefs_get_opp_info_num(); + header = met_vcorefs_get_opp_info_name(); + + ret += snprintf(buf + ret, PAGE_SIZE, header_dvfs); + for (idx = 0; idx < num; idx++) + ret += snprintf(buf + ret, PAGE_SIZE - ret, "%s,", header[idx]); + buf[strlen(buf)-1] = '\n'; + + /* sw kickers */ + ret += snprintf(buf + ret, PAGE_SIZE - ret, "%s", header_kicker); + for (idx = 0; idx < NUM_KICKER; idx++) + ret += snprintf(buf + ret, PAGE_SIZE - ret, "%s,", met_governor_get_kicker_name(idx)); + buf[strlen(buf)-1] = '\n'; + + /* source requests */ + num = met_vcorefs_get_src_req_num(); + header = met_vcorefs_get_src_req_name(); + + ret += snprintf(buf + ret, PAGE_SIZE - ret, header_ms_dvfs); + for (idx = 0; idx < num; idx++) + ret += snprintf(buf + ret, PAGE_SIZE - ret, "%s,", header[idx]); + buf[strlen(buf)-1] = '\n'; + + met_vcoredvfs.mode = 0; + + return ret; +} + +struct metdevice met_vcoredvfs = { + .name = "vcoredvfs", + .owner = THIS_MODULE, + .type = MET_TYPE_BUS, + .create_subfs = met_vcoredvfs_create, + .delete_subfs = met_vcoredvfs_delete, + .cpu_related = 0, + .start = met_vcoredvfs_start, + .stop = met_vcoredvfs_stop, + .polling_interval = 1, /* ms */ + .timed_polling = met_vcoredvfs_polling, + .print_help = vcoredvfs_print_help, + .print_header = vcoredvfs_print_header, +}; diff --git a/drivers/misc/mediatek/met_drv_v2/common/met_wall_time.c b/drivers/misc/mediatek/met_drv_v2/common/met_wall_time.c new file mode 100644 index 0000000000000000000000000000000000000000..4150a47697d333034fe32368293bfb0786b8ad4c --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/met_wall_time.c @@ -0,0 +1,260 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#define MET_USER_EVENT_SUPPORT +#include "met_drv.h" +#include "trace.h" +#include "interface.h" +#include "met_kernel_symbol.h" + +#define MODE_CUSOM_CLKSRC 2 +struct metdevice met_wall_time; + +/** */ +/* How to add a new clocksource: */ +/* */ +/* 1. add constant for new clocksource in #define-macro */ +/* 2. declare new weakref function */ +/* 3. implement handler functions: */ +/* (1) clksrc_attr_t::*ready: */ +/* check if ... */ +/* (i) clocksource correctly working */ +/* (ii) weakref function is not null */ +/* (2) clksrc_attr_t::*get_cnt: read clocksource from weakref function */ +/* 4. place attrs of new clocksource into clksrc_attr_tb */ +/* 5. update DEFAULT_CLKSRC_STR */ +/* 6. update help message */ +/** */ + +#define __SYS_TIMER 0x0 +#define __GPT1 0x1 +#define __GPT2 0x2 +#define __GPT3 0x3 +#define __GPT4 0x4 +#define __GPT5 0x5 +#define __GPT6 0x6 + +#define DEFAULT_CLKSRC_STR "SYS_TIMER" + +extern ktime_t ktime_get(void); + +int __sys_timer_get_cnt(u8 clksrc, u64 *cycles) +{ + if (met_export_api_symbol->met_arch_counter_get_cntvct) + *cycles = met_export_api_symbol->met_arch_counter_get_cntvct(); + return 0; +} + + +struct clksrc_attr_t { + u8 clksrc; + const char *clksrc_str; + /* checks if clksrc/get_cnt function is working/available */ + int (*clksrc_ready)(u8 clksrc); + int (*clksrc_get_cnt)(u8 clksrc, u64 *cycles); +}; + +struct clksrc_attr_t clksrc_attr_tb[] = { + {__SYS_TIMER, "SYS_TIMER", NULL, __sys_timer_get_cnt}, + /* {__GPT1, "GPT1", __gpt_timer_ready, __gpt_timer_get_cnt}, */ + /* {__GPT2, "GPT2", __gpt_timer_ready, __gpt_timer_get_cnt}, */ + /* {__GPT3, "GPT3", __gpt_timer_ready, __gpt_timer_get_cnt}, */ + /* {__GPT4, "GPT4", __gpt_timer_ready, __gpt_timer_get_cnt}, */ + /* {__GPT5, "GPT5", __gpt_timer_ready, __gpt_timer_get_cnt}, */ + /* {__GPT6, "GPT6", __gpt_timer_ready, __gpt_timer_get_cnt}, */ +}; + +static const struct clksrc_attr_t *lookup_clksrc_attr_tb(const char *clksrc_str, int len); +static const struct clksrc_attr_t *wall_time_attr; + +/* definitions for auto-sampling of working freq. of clocksource */ +/* maximum tolerable error percentage(%) of sampled clock freq */ +#define FREQ_ERR_PERCENT 3 + +/* expected working freq. of clocksources */ +static const u32 freq_level[] = { 32768, 13000000, 26000000 }; + +static u32 lookup_freq_level(u32 freq); + +/* flag indicating whether sampling is on-going */ +static u32 do_sample; +static u32 freq; +static u64 start_us_ts; +static u64 start_wall_time; +/* end definitions for sampling of freq. */ + +static void wall_time_start(void) +{ + if (met_wall_time.mode != MODE_CUSOM_CLKSRC) { + wall_time_attr = lookup_clksrc_attr_tb(DEFAULT_CLKSRC_STR, + strlen(DEFAULT_CLKSRC_STR)); + } + + freq = 0; + do_sample = 1; + + if (wall_time_attr) { + + /* XXX: always use CPU 0 */ + start_us_ts = cpu_clock(0); + wall_time_attr->clksrc_get_cnt(wall_time_attr->clksrc, &start_wall_time); + + /* us_ts = ap_ts/1000; */ + do_div(start_us_ts, 1000); + } +} + +noinline void met_mono_time(void) +{ + /* mono time vs local time */ + u64 cur_local_ns = sched_clock(); + ktime_t cur_mono_ts = ktime_get(); + + MET_TRACE("TS.APTS=%llu TS.MONO=%llu\n", (unsigned long long)cur_local_ns, + (unsigned long long)ktime_to_ns(cur_mono_ts)); +} + +noinline void met_ap_wall_time(unsigned long long ts, int cpu) +{ + u64 ap_ts; + u64 us_ts; + u64 sec; + u64 usec; + u64 cycles; + u64 f; + + if (wall_time_attr) { + + wall_time_attr->clksrc_get_cnt(wall_time_attr->clksrc, &cycles); + ap_ts = cpu_clock(cpu); + + us_ts = ap_ts; + do_div(us_ts, 1000); /* us_ts = ap_ts/1000; */ + + sec = us_ts; + usec = do_div(sec, 1000000); /* sec = us_ts/1000000; usec = us_ts%1000000; */ + MET_TRACE("TS.APTS=%llu.%06llu WCLK=%llu\n", (unsigned long long)sec, + (unsigned long long)usec, (unsigned long long)cycles); + + // print local time vs mono time for gpu time shift + met_mono_time(); + + if (do_sample) { + + do_sample = 0; + + f = (cycles - start_wall_time) * 1000000; + do_div(f, us_ts - start_us_ts); + + /* don't worry about the u64 -> u32 assignment, */ + /* sampled wall-clock freq is expected to be below 2^32-1 */ + freq = lookup_freq_level(f); + + /* debug message */ + /* MET_TRACE("wall_time debug: result: %u," */ + /* "start cycle: %llu, end cycle: %llu, cycle diff: %llu," */ + /* "start us: %llu, end us: %llu, us diff: %llu", */ + /* f, */ + /* start_wall_time, cycles, cycles - start_wall_time, */ + /* start_us_ts, us_ts, us_ts - start_us_ts); */ + + if (freq != 0) + met_tag_oneshot_real(33880, "_WCLK_FREQ_", freq); + } + } +} + +static const char help[] = +" --wall_time output wall-clock syncing info in system timer\n"; +/* " --wall_time=SYS_TIMER|GPT[1-6] output wall-clock syncing info in custom clocksource\n"; */ + +static int wall_time_print_help(char *buf, int len) +{ + return snprintf(buf, PAGE_SIZE, help); +} + +static const char *header = +"met-info [000] 0.0: WCLK: %d\n" +"met-info [000] 0.0: clocksource: %s\n"; + +static int wall_time_print_header(char *buf, int len) +{ + return snprintf(buf, len, header, + freq == 0 ? -1 : freq, + wall_time_attr ? wall_time_attr->clksrc_str : "NONE"); +} + +static int wall_time_process_argument(const char *arg, int len) +{ + /* reset wall-time clocksource */ + wall_time_attr = lookup_clksrc_attr_tb(arg, len); + + if (!wall_time_attr) { + met_wall_time.mode = 0; + return -1; + } + + met_wall_time.mode = MODE_CUSOM_CLKSRC; + return 0; +} + +static const struct clksrc_attr_t *lookup_clksrc_attr_tb(const char *clksrc_str, int len) +{ + int i; + const struct clksrc_attr_t *attr; + int tb_nmemb = sizeof(clksrc_attr_tb) / sizeof(*clksrc_attr_tb); + + for (i = 0; i < tb_nmemb; i++) { + + attr = clksrc_attr_tb + i; + + if (strlen(attr->clksrc_str) == len && + strncmp(clksrc_str, attr->clksrc_str, len) == 0) { + return attr; + } + } + + return NULL; +} + +static u32 lookup_freq_level(u32 freq) +{ + + int ii; + int freq_nmemb = sizeof(freq_level) / sizeof(*freq_level); + u32 fdiff; + + for (ii = 0; ii < freq_nmemb; ii++) { + fdiff = freq_level[ii] > freq ? freq_level[ii] - freq : freq - freq_level[ii]; + if (fdiff < freq_level[ii] * FREQ_ERR_PERCENT / 100) + return freq_level[ii]; + } + + return 0; +} + +struct metdevice met_wall_time = { + .name = "wall_time", + .owner = THIS_MODULE, + .type = MET_TYPE_BUS, + .cpu_related = 0, + .start = wall_time_start, + .polling_interval = 1000, + .timed_polling = met_ap_wall_time, + .print_help = wall_time_print_help, + .print_header = wall_time_print_header, + .process_argument = wall_time_process_argument, +}; +EXPORT_SYMBOL(met_wall_time); diff --git a/drivers/misc/mediatek/met_drv_v2/common/mips_pmu_hw.c b/drivers/misc/mediatek/met_drv_v2/common/mips_pmu_hw.c new file mode 100644 index 0000000000000000000000000000000000000000..1246d26761784c73a65b8b12a55dac425d85582d --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/mips_pmu_hw.c @@ -0,0 +1,430 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include +#include + +#include "cpu_pmu.h" +#include "mips_pmu_name.h" + +struct chip_pmu { + enum cpu_type_enum type; + struct pmu_desc **desc; + void *refptr; + const char *cpu_name; + unsigned int pmu_desc_size; + unsigned int max_hw_events; + unsigned int max_reg_count; +}; + +struct pmu_desc *mips_pmu_desc[MIPS_MAX_HWEVENTS]; + +static struct chip_pmu chips[] = { + {CPU_1004K, mips_pmu_desc, (void *)mips_1004k_pmu_desc, "MIPS_1004K", + MIPS_1004K_PMU_DESC_SIZE, MIPS_1004K_PMU_DESC_COUNT, PMU_1004K_MAX_HW_REGS}, +}; + +static struct chip_pmu chip_unknown = { CPU_UNKNOWN, NULL, NULL, "Unknown CPU", 0, 0, 0 }; + +#define CHIP_PMU_COUNT (sizeof(chips) / sizeof(struct chip_pmu)) +static struct chip_pmu *chip; +#define M_CONFIG1_PC (1 << 4) + +#define M_PERFCTL_EXL (1 << 0) +#define M_PERFCTL_KERNEL (1 << 1) +#define M_PERFCTL_SUPERVISOR (1 << 2) +#define M_PERFCTL_USER (1 << 3) +#define M_PERFCTL_INTERRUPT_ENABLE (1 << 4) +#define M_PERFCTL_EVENT(event) (((event) & 0x3ff) << 5) +#define M_PERFCTL_VPEID(vpe) ((vpe) << 16) + +#if IS_ENABLED(CONFIG_CPU_BMIPS5000) +#define M_PERFCTL_MT_EN(filter) 0 +#else /* !CONFIG_CPU_BMIPS5000 */ +#define M_PERFCTL_MT_EN(filter) ((filter) << 20) +#endif /* CONFIG_CPU_BMIPS5000 */ + +#define M_TC_EN_ALL M_PERFCTL_MT_EN(0) +#define M_TC_EN_VPE M_PERFCTL_MT_EN(1) +#define M_TC_EN_TC M_PERFCTL_MT_EN(2) +#define M_PERFCTL_TCID(tcid) ((tcid) << 22) +#define M_PERFCTL_WIDE (1 << 30) +#define M_PERFCTL_MORE (1 << 31) +#define M_PERFCTL_TC (1 << 30) + +#define M_PERFCTL_COUNT_EVENT_WHENEVER (M_PERFCTL_EXL | \ + M_PERFCTL_KERNEL | \ + M_PERFCTL_USER | \ + M_PERFCTL_SUPERVISOR | \ + M_PERFCTL_INTERRUPT_ENABLE) + +#if IS_ENABLED(CONFIG_MIPS_MT_SMP) +#define M_PERFCTL_CONFIG_MASK 0x3fff801f +#else +#define M_PERFCTL_CONFIG_MASK 0x1f +#endif +#define M_PERFCTL_EVENT_MASK 0xfe0 + +#define vpe_id() 0 + +/* To get current TCID*/ +#define read_c0_tcbind() __read_32bit_c0_register($2, 2) + +struct cpu_hw_events { + unsigned int config_base[MIPS_MAX_HWEVENTS]; + unsigned int saved_ctrl[MIPS_MAX_HWEVENTS]; +}; + +DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = { + .config_base = { + 0, 0, 0, 0}, .saved_ctrl = { +0, 0, 0, 0},}; + +static enum cpu_type_enum mips_get_ic(void) +{ + unsigned int value = current_cpu_type(); + + /* pr_debug("ic value: %X\n", value); */ + return value; +} + +static int __n_counters(void) +{ + if (!(read_c0_config1() & M_CONFIG1_PC)) + return 0; + if (!(read_c0_perfctrl0() & M_PERFCTL_MORE)) + return 1; + if (!(read_c0_perfctrl1() & M_PERFCTL_MORE)) + return 2; + if (!(read_c0_perfctrl2() & M_PERFCTL_MORE)) + return 3; + + return 4; +} + +static int n_counters(void) +{ + int counters; + + switch (current_cpu_type()) { + case CPU_R10000: + counters = 2; + break; + case CPU_R12000: + case CPU_R14000: + counters = 4; + break; + default: + counters = __n_counters(); + break; + } + + return counters; +} + +static int mips_pmu_hw_get_counters(void) +{ + int count = n_counters(); + + /* pr_debug("pmu hw event nr: %d\n", count); */ + return count; +} + +static unsigned int mipsxx_pmu_swizzle_perf_idx(unsigned int idx) +{ + if (vpe_id() == 1) + idx = (idx + 2) & 3; + return idx; +} + +static void mipsxx_pmu_write_counter(unsigned int idx, u64 val) +{ + idx = mipsxx_pmu_swizzle_perf_idx(idx); + + switch (idx) { + case 0: + write_c0_perfcntr0(val); + return; + case 1: + write_c0_perfcntr1(val); + return; + case 2: + write_c0_perfcntr2(val); + return; + case 3: + write_c0_perfcntr3(val); + return; + } +} + +static u64 mipsxx_pmu_read_counter(unsigned int idx) +{ + idx = mipsxx_pmu_swizzle_perf_idx(idx); + + switch (idx) { + case 0: + /* + * The counters are unsigned, we must cast to truncate + * off the high bits. + */ + return (u32) read_c0_perfcntr0(); + case 1: + return (u32) read_c0_perfcntr1(); + case 2: + return (u32) read_c0_perfcntr2(); + case 3: + return (u32) read_c0_perfcntr3(); + default: + WARN_ONCE(1, "Invalid performance counter number (%d)\n", idx); + return 0; + } +} + + +static unsigned int mipsxx_pmu_read_control(unsigned int idx) +{ + idx = mipsxx_pmu_swizzle_perf_idx(idx); + + switch (idx) { + case 0: + return read_c0_perfctrl0(); + case 1: + return read_c0_perfctrl1(); + case 2: + return read_c0_perfctrl2(); + case 3: + return read_c0_perfctrl3(); + default: + WARN_ONCE(1, "Invalid performance counter number (%d)\n", idx); + return 0; + } +} + +static void mipsxx_pmu_write_control(unsigned int idx, unsigned int val) +{ + idx = mipsxx_pmu_swizzle_perf_idx(idx); + + switch (idx) { + case 0: + write_c0_perfctrl0(val); + return; + case 1: + write_c0_perfctrl1(val); + return; + case 2: + write_c0_perfctrl2(val); + return; + case 3: + write_c0_perfctrl3(val); + return; + } +} + +static int mipsxx_pmu_get_vpeid(void) +{ + return read_c0_tcbind() & 0xF; +} + +static void mipsxx_pmu_reset_counters(int idx) +{ + switch (idx) { + case 3: + mipsxx_pmu_write_control(3, 0); + mipsxx_pmu_write_counter(3, 0); + break; + case 2: + mipsxx_pmu_write_control(2, 0); + mipsxx_pmu_write_counter(2, 0); + break; + case 1: + mipsxx_pmu_write_control(1, 0); + mipsxx_pmu_write_counter(1, 0); + break; + case 0: + mipsxx_pmu_write_control(0, 0); + mipsxx_pmu_write_counter(0, 0); + break; + } +} + +static void mipsxx_pmu_enable_event(int idx, int event) +{ + struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); + unsigned long flags; + + WARN_ON(idx < 0 || idx >= chip->max_hw_events); + cpuc->saved_ctrl[idx] = M_PERFCTL_EVENT(event & 0xff) | + M_PERFCTL_VPEID(mipsxx_pmu_get_vpeid()) | + (cpuc->config_base[idx] & M_PERFCTL_CONFIG_MASK); +#if IS_ENABLED(CONFIG_CPU_BMIPS5000) + /* if (IS_ENABLED(CONFIG_CPU_BMIPS5000)) */ + /* enable the counter for the calling thread */ + cpuc->saved_ctrl[idx] |= (1 << (12 + vpe_id())) | M_PERFCTL_TC; +#endif + /* + * To enable pmu count + */ + local_irq_save(flags); + mipsxx_pmu_write_control(idx, cpuc->saved_ctrl[idx]); + local_irq_restore(flags); +} + +static void mipsxx_pmu_disable_event(int idx) +{ + struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); + unsigned long flags; + + /* WARN_ON(idx < 0 || idx >= mipspmu.num_counters); */ + WARN_ON(idx < 0 || idx >= chip->max_hw_events); + + local_irq_save(flags); + cpuc->saved_ctrl[idx] = mipsxx_pmu_read_control(idx) & ~M_PERFCTL_COUNT_EVENT_WHENEVER; + mipsxx_pmu_write_control(idx, cpuc->saved_ctrl[idx]); + local_irq_restore(flags); +} + +static int mips_pmu_hw_get_event_desc(int idx, int event, char *event_desc) +{ + int i; + + if (event_desc == NULL) { + pr_debug("event_desc is NULL\n"); + return -1; + } + + for (i = 0; i < chip->max_reg_count; i++) { + if (chip->desc[idx][i].event == event) { + strncpy(event_desc, chip->desc[idx][i].name, MXSIZE_PMU_DESC - 1); + break; + } + } + if (i == chip->max_reg_count) + return -1; + + return 0; +} + + +static int mips_pmu_hw_check_event(struct met_pmu *pmu, int idx, int event) +{ + int i; + + /* to check index over run */ + if (!chip) + return -1; + + if (idx >= chip->max_hw_events) + return -1; + + for (i = 0; i < chip->max_reg_count; i++) { + if (chip->desc[idx][i].event == event) + break; + } + if (i == chip->max_reg_count) + return -1; + + return 0; +} + +static void mips_pmu_hw_start(struct met_pmu *pmu, int count) +{ + int i; + int generic = count - 1; + struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); + + /* pr_debug("hw_start generic: %d\n", generic); */ + for (i = 0; i < generic; i++) { + /* init config */ + cpuc->config_base[i] = 0; + cpuc->config_base[i] |= M_TC_EN_VPE; + cpuc->config_base[i] |= M_PERFCTL_USER; + cpuc->config_base[i] |= M_PERFCTL_KERNEL; + cpuc->config_base[i] |= M_PERFCTL_EXL; + cpuc->config_base[i] |= M_PERFCTL_SUPERVISOR; + cpuc->config_base[i] &= M_PERFCTL_CONFIG_MASK; + /**/ mipsxx_pmu_reset_counters(i); + if (pmu[i].mode == MODE_POLLING) + mipsxx_pmu_enable_event(i, pmu[i].event); + } + if (pmu[count - 1].mode == MODE_POLLING) + pr_debug("%s %d BUG!!! index over run!!\n", __func__, __LINE__); +} + +static void mips_pmu_hw_stop(int count) +{ + int idx = 0; + int generic = count - 1; + /* pr_debug("reset %d\n", generic); */ + for (idx = 0; idx < generic; idx++) { + mipsxx_pmu_reset_counters(idx); + mipsxx_pmu_disable_event(idx); + } +} + + +static unsigned int mips_pmu_hw_polling(struct met_pmu *pmu, int count, unsigned int *pmu_value) +{ + int i, cnt = 0; + int generic = count - 1; + + for (i = 0; i < generic; i++) { + if (pmu[i].mode == MODE_POLLING) { + pmu_value[cnt] = mipsxx_pmu_read_counter(i); + cnt++; + mipsxx_pmu_reset_counters(i); + mipsxx_pmu_enable_event(i, pmu[i].event); + } + } + if (pmu[count - 1].mode == MODE_POLLING) { + pr_debug("%s %d BUG!!! index over run!!\n", __func__, __LINE__); + pmu_value[cnt] = 0xFFFF; + cnt++; + } + + return cnt; +} + + + +struct cpu_pmu_hw mips_pmu = { + .name = "mips_pmu", + .get_event_desc = mips_pmu_hw_get_event_desc, + .check_event = mips_pmu_hw_check_event, + .start = mips_pmu_hw_start, + .stop = mips_pmu_hw_stop, + .polling = mips_pmu_hw_polling, +}; + +struct cpu_pmu_hw *cpu_pmu_hw_init(void) +{ + int i = 0; + enum cpu_type_enum type; + int pmu_hw_count = 0; + + type = mips_get_ic(); + + if (CPU_UNKNOWN == type || CPU_LAST == type) { + chip = &chip_unknown; + return NULL; + } + for (i = 0; i < CHIP_PMU_COUNT; i++) { + if (chips[i].type == type) { + chip = &(chips[i]); + break; + } + } + if (i == CHIP_PMU_COUNT) { + chip = &chip_unknown; + return NULL; + } + + pmu_hw_count = mips_pmu_hw_get_counters(); + for (i = 0; i < pmu_hw_count; i++) + chip->desc[i] = chip->refptr + (chip->pmu_desc_size * i); + + mips_pmu.nr_cnt = pmu_hw_count + 1; + mips_pmu.cpu_name = chip->cpu_name; + return &mips_pmu; +} diff --git a/drivers/misc/mediatek/met_drv_v2/common/mips_pmu_name.h b/drivers/misc/mediatek/met_drv_v2/common/mips_pmu_name.h new file mode 100644 index 0000000000000000000000000000000000000000..9feef56b23a604cfc91b340eb294e35c0189290b --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/mips_pmu_name.h @@ -0,0 +1,164 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef _MIPS_PMU_NAME_H_ +#define _MIPS_PMU_NAME_H_ + +/* MIPS 1004K */ +#define MIPS_MAX_HWEVENTS (4) + +#define PMU_1004K_MAX_HW_REGS (128) +struct pmu_desc mips_1004k_pmu_desc[][PMU_1004K_MAX_HW_REGS] = { + /* COUNT 0 */ + { + {0, "CPU_CYCLES"}, + {1, "CPU_INST"}, + {2, "BRANCH_INSNS"}, + {3, "JR_31_INSNS"}, + {4, "JR_NON_31_INSNS"}, + {5, "ITLB_ACCESSES"}, + {6, "DTLB_ACCESSES"}, + {7, "JTLB_INSN_ACCESSES"}, + {8, "JTLB_DATA_ACCESSES"}, + {9, "ICACHE_ACCESSES"}, + {10, "DCACHE_ACCESSES"}, + {11, "DCACHE_MISSES"}, + {12, "RESERVED"}, + {13, "STORE_MISS_INSNS"}, + {14, "INTEGER_INSNS"}, + {15, "LOAD_INSNS"}, + {16, "J_JAL_INSNS"}, + {17, "NO_OPS_INSNS"}, + {18, "ALL_STALLS"}, + {19, "SC_INSNS"}, + {20, "PREFETCH_INSNS"}, + {21, "L2_CACHE_WRITEBACKS"}, + {22, "L2_CACHE_MISSES"}, + {23, "EXCEPTIONS_TAKEN"}, + {24, "CACHE_FIXUP_CYCLES"}, + {25, "IFU_STALLS"}, + {26, "DSP_INSNS"}, + {27, "RESERVED"}, + {28, "POLICY_EVENTS"}, + {29, "ISPRAM_EVENTS"}, + {30, "COREEXTEND_EVENTS"}, + {31, "YIELD_EVENTS"}, + {32, "ITC_LOADS"}, + {33, "UNCACHED_LOAD_INSNS"}, + {34, "FORK_INSNS"}, + {35, "CP2_ARITH_INSNS"}, + {36, "INTERVENTION_STALLS"}, + {37, "ICACHE_MISS_STALLS"}, + {38, "RESERVED"}, + {39, "DCACHE_MISS_CYCLES"}, + {40, "UNCACHED_STALLS"}, + {41, "MDU_STALLS"}, + {42, "CP2_STALLS"}, + {43, "ISPRAM_STALLS"}, + {44, "CACHE_INSN_STALLS"}, + {45, "LOAD_USE_STALLS"}, + {46, "INTERLOCK_STALLS"}, + {47, "RELAX_STALLS"}, + {48, "IFU_FB_FULL_REFETCHES"}, + {49, "EJTAG_INSN_TRIGGERS"}, + {50, "FSB_LESS_25_FULL"}, + {51, "FSB_OVER_50_FULL"}, + {52, "LDQ_LESS_25_FULL"}, + {53, "LDQ_OVER_50_FULL"}, + {54, "WBB_LESS_25_FULL"}, + {55, "WBB_OVER_50_FULL"}, + {56, "INTERVENTION_HIT_COUNT"}, + {57, "INVALIDATE_INTERVENTION_COUNT"}, + {58, "EVICTION_COUNT"}, + {59, "MESI_INVAL_COUNT"}, + {60, "MESI_MODIFIED_COUNT"}, + {61, "SELF_INTERVENTION_LATENCY"}, + {62, "READ_RESPONSE_LATENCY"}, + {63, "RESERVED"}, + {64, "SI_PCEVENT1"}, + {65, "SI_PCEVENT3"}, + {66, "SI_PCEVENT5"}, + {67, "SI_PCEVENT7"}, + {-1, "RESERVED"}, + /* 68 - 127 for Reserved */ + }, + /* COUNT 1 */ + { + {0, "CPU_CYCLES"}, + {1, "CPU_INST"}, + {2, "MISPREDICTED_BRANCH_INSNS"}, + {3, "JR_31_MISPREDICTIONS"}, + {4, "JR_31_NO_PREDICTIONS"}, + {5, "ITLB_MISSES"}, + {6, "DTLB_MISSES"}, + {7, "JTLB_INSN_MISSES"}, + {8, "JTLB_DATA_MISSES"}, + {9, "ICACHE_MISSES"}, + {10, "DCACHE_WRITEBACKS"}, + {11, "DCACHE_MISSES"}, + {12, "RESERVED"}, + {13, "LOAD_MISS_INSNS"}, + {14, "FPU_INSNS"}, + {15, "STORE_INSNS"}, + {16, "MIPS16_INSNS"}, + {17, "INT_MUL_DIV_INSNS"}, + {18, "REPLAYED_INSNS"}, + {19, "SC_INSNS_FAILED"}, + {20, "CACHE_HIT_PREFETCH_INSNS"}, + {21, "L2_CACHE_ACCESSES"}, + {22, "L2_CACHE_SINGLE_BIT_ERRORS"}, + {23, "SINGLE_THREADED_CYCLES"}, + {24, "REFETCHED_INSNS"}, + {25, "ALU_STALLS"}, + {26, "ALU_DSP_SATURATION_INSNS"}, + {27, "MDU_DSP_SATURATION_INSNS"}, + {28, "CP2_EVENTS"}, + {29, "DSPRAM_EVENTS"}, + {30, "RESERVED"}, + {31, "ITC_EVENT"}, + {33, "UNCACHED_STORE_INSNS"}, + {34, "YIELD_IN_COMP"}, + {35, "CP2_TO_FROM_INSNS"}, + {36, "INTERVENTION_MISS_STALLS"}, + {37, "DCACHE_MISS_STALLS"}, + {38, "RESERVED"}, + /* 38 was listed in OPROFILE web page, but not listed 1004k mips spec */ + /* {38, "FSB_INDEX_CONFLICT_STALLS"}, */ + {39, "L2_CACHE_MISS_CYCLES"}, + {40, "ITC_STALLS"}, + {41, "FPU_STALLS"}, + {42, "COREEXTEND_STALLS"}, + {43, "DSPRAM_STALLS"}, + {45, "ALU_TO_AGEN_STALLS"}, + {46, "MISPREDICTION_STALLS"}, + {47, "RESERVED"}, + {48, "FB_ENTRY_ALLOCATED_CYCLES"}, + {49, "EJTAG_DATA_TRIGGERS"}, + {50, "FSB_25_50_FULL"}, + {51, "FSB_FULL_STALLS"}, + {52, "LDQ_25_50_FULL"}, + {53, "LDQ_FULL_STALLS"}, + {54, "WBB_25_50_FULL"}, + {55, "WBB_FULL_STALLS"}, + {56, "INTERVENTION_COUNT"}, + {57, "INVALID_INTERVENT_HIT_CNT"}, + {58, "WRITEBACK_COUNT"}, + {59, "MESI_EXCLUSIVE_COUNT"}, + {60, "MESI_SHARED_COUNT"}, + {61, "SELF_INTERVENTION_COUNT"}, + {62, "READ_RESPONSE_COUNT"}, + {63, "RESERVED"}, + {64, "SI_PCEVENT0"}, + {65, "SI_PCEVENT2"}, + {66, "SI_PCEVENT4"}, + {67, "SI_PCEVENT6"}, + {-1, "RESERVED"}, + }, +}; + +#define MIPS_1004K_PMU_DESC_SIZE (sizeof(mips_1004k_pmu_desc[0])) +#define MIPS_1004K_PMU_DESC_COUNT (sizeof(mips_1004k_pmu_desc) / MIPS_1004K_PMU_DESC_SIZE) + +#endif /* _V8_PMU_NAME_H_ */ diff --git a/drivers/misc/mediatek/met_drv_v2/common/mtk_gpu_metmonitor.c b/drivers/misc/mediatek/met_drv_v2/common/mtk_gpu_metmonitor.c new file mode 100644 index 0000000000000000000000000000000000000000..4c672ee0120dbb162890b61c4f0e9f3c7550a1cb --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/mtk_gpu_metmonitor.c @@ -0,0 +1,854 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "met_drv.h" +#include "trace.h" +#include "interface.h" + +#include "mtk_gpu_metmonitor.h" +#include "core_plf_init.h" +#include "core_plf_trace.h" + + +/* + * define if the hal implementation might re-schedule, cannot run inside softirq + * undefine this is better for sampling jitter if HAL support it + */ +#undef GPU_HAL_RUN_PREMPTIBLE + +#ifdef GPU_HAL_RUN_PREMPTIBLE +static struct delayed_work gpu_dwork; +static struct delayed_work gpu_pwr_dwork; +#endif + +/* the mt_gpufreq_get_thermal_limit_freq use mutex_lock to do its job */ +/* so, change the gpu-dvfs implementation to dwork */ +static struct delayed_work gpu_dvfs_dwork; + +/* + * GPU monitor HAL comes from alps\mediatek\kernel\include\linux\mtk_gpu_utility.h + * + * mtk_get_gpu_memory_usage(unsigned int* pMemUsage) in unit of bytes + * + * mtk_get_gpu_xxx_loading are in unit of % +*/ + +enum MET_GPU_PROFILE_INDEX { + eMET_GPU_LOADING = 0, + eMET_GPU_BLOCK_LOADING, /* 1 */ + eMET_GPU_IDLE_LOADING, /* 2 */ + eMET_GPU_PROFILE_CNT +}; + +static unsigned long g_u4AvailableInfo; + +static unsigned int output_header_pmu_len; +static unsigned int output_pmu_str_len; + +noinline void GPU_Loading(unsigned char cnt, unsigned int *value) +{ + switch (cnt) { + case 1: + MET_TRACE("%u\n", value[0]); + break; + case 2: + MET_TRACE("%u,%u\n", value[0], value[1]); + break; + case 3: + MET_TRACE("%u,%u,%u\n", value[0], value[1], value[2]); + break; + case 4: + MET_TRACE("%u,%u,%u,%u\n", value[0], value[1], value[2], value[3]); + break; + default: + break; + } + +} + +noinline void GPU_Sub_Loading(unsigned int loading) +{ + MET_TRACE("%u\n", loading); +} + +noinline void GPU_3D_Fences_Count(int count) +{ + MET_TRACE("%d\n", count); +} + +#ifdef GPU_HAL_RUN_PREMPTIBLE +static void gpu_GPULoading(struct work_struct *work) +{ + unsigned int pu4Value[eMET_GPU_PROFILE_CNT]; + unsigned long u4Index = 0; + unsigned int loading = 0; + int count = 0; + + memset(pu4Value, 0x00, eMET_GPU_PROFILE_CNT); + if ((1 << eMET_GPU_LOADING) & g_u4AvailableInfo) { + if (mtk_get_gpu_loading_symbol && mtk_get_gpu_loading_symbol(&pu4Value[u4Index])) + u4Index += 1; + } + + if ((1 << eMET_GPU_BLOCK_LOADING) & g_u4AvailableInfo) { + if (mtk_get_gpu_block_symbol && mtk_get_gpu_block_symbol(&pu4Value[u4Index])) + u4Index += 1; + } + + if ((1 << eMET_GPU_IDLE_LOADING) & g_u4AvailableInfo) { + if (mtk_get_gpu_idle_symbol && mtk_get_gpu_idle_symbol(&pu4Value[u4Index])) + u4Index += 1; + } + + if (g_u4AvailableInfo) + GPU_Loading(u4Index, pu4Value); + + if (mtk_get_gpu_sub_loading_symbol && mtk_get_gpu_sub_loading_symbol(&loading)) + GPU_Sub_Loading(loading); + + if (mtk_get_3D_fences_count_symbol && mtk_get_3D_fences_count_symbol(&count)) + GPU_3D_Fences_Count(count); +} +#else +static void gpu_GPULoading(unsigned long long stamp, int cpu) +{ + unsigned int pu4Value[eMET_GPU_PROFILE_CNT]; + unsigned long u4Index = 0; + unsigned int loading = 0; + int count = 0; + + memset(pu4Value, 0x00, eMET_GPU_PROFILE_CNT); + if ((1 << eMET_GPU_LOADING) & g_u4AvailableInfo) { + if (mtk_get_gpu_loading_symbol) { + mtk_get_gpu_loading_symbol(&pu4Value[u4Index]); + u4Index += 1; + } + } + + if ((1 << eMET_GPU_BLOCK_LOADING) & g_u4AvailableInfo) { + if (mtk_get_gpu_block_symbol) { + mtk_get_gpu_block_symbol(&pu4Value[u4Index]); + u4Index += 1; + } + } + + if ((1 << eMET_GPU_IDLE_LOADING) & g_u4AvailableInfo) { + if (mtk_get_gpu_idle_symbol) { + mtk_get_gpu_idle_symbol(&pu4Value[u4Index]); + u4Index += 1; + } + } + + if (g_u4AvailableInfo) + GPU_Loading(u4Index, pu4Value); + + if (mtk_get_gpu_sub_loading_symbol) { + mtk_get_gpu_sub_loading_symbol(&loading); + GPU_Sub_Loading(loading); + } + + if (mtk_get_3D_fences_count_symbol) { + mtk_get_3D_fences_count_symbol(&count); + GPU_3D_Fences_Count(count); + } +} +#endif + +static void gpu_monitor_start(void) +{ + if (mtk_get_gpu_loading_symbol) + g_u4AvailableInfo |= (1 << eMET_GPU_LOADING); + if (mtk_get_gpu_block_symbol) + g_u4AvailableInfo |= (1 << eMET_GPU_BLOCK_LOADING); + if (mtk_get_gpu_idle_symbol) + g_u4AvailableInfo |= (1 << eMET_GPU_IDLE_LOADING); + +#ifdef GPU_HAL_RUN_PREMPTIBLE + INIT_DELAYED_WORK(&gpu_dwork, gpu_GPULoading); +#endif +} + +#ifdef GPU_HAL_RUN_PREMPTIBLE +static void gpu_monitor_stop(void) +{ + cancel_delayed_work_sync(&gpu_dwork); +} + +static void GPULoadingNotify(unsigned long long stamp, int cpu) +{ + schedule_delayed_work(&gpu_dwork, 0); +} +#endif + +static char help[] = + " --gpu monitor gpu status\n"; +static int gpu_status_print_help(char *buf, int len) +{ + return snprintf(buf, PAGE_SIZE, help); +} + +static char g_pComGPUStatusHeader[] = + "met-info [000] 0.0: met_gpu_loading_header: "; +static int gpu_status_print_header(char *buf, int len) +{ + int ret = 0; + + ret = snprintf(buf, PAGE_SIZE, "%s", g_pComGPUStatusHeader); + + if ((1 << eMET_GPU_LOADING) & g_u4AvailableInfo) + ret += snprintf(buf+ret, PAGE_SIZE-ret, "%s", "Loading,"); + + if ((1 << eMET_GPU_BLOCK_LOADING) & g_u4AvailableInfo) + ret += snprintf(buf+ret, PAGE_SIZE-ret, "%s", "Blcok,"); + + if ((1 << eMET_GPU_IDLE_LOADING) & g_u4AvailableInfo) + ret += snprintf(buf+ret, PAGE_SIZE-ret, "%s", "Idle"); + + ret += snprintf(buf+ret, PAGE_SIZE-ret, "%s", "\n"); + + ret += snprintf(buf+ret, PAGE_SIZE-ret, + "met-info [000] 0.0: met_gpu_sub_loading_header: Loading\n"); + ret += snprintf(buf+ret, PAGE_SIZE-ret, + "met-info [000] 0.0: met_gpu_3d_fences_count_header: Count\n"); + + return ret; +} + +struct metdevice met_gpu = { + .name = "gpu", + .owner = THIS_MODULE, + .type = MET_TYPE_BUS, + .cpu_related = 0, + .start = gpu_monitor_start, + .mode = 0, + .polling_interval = 1, /* ms */ +#ifdef GPU_HAL_RUN_PREMPTIBLE + .timed_polling = GPULoadingNotify, + .stop = gpu_monitor_stop, +#else + .timed_polling = gpu_GPULoading, +#endif + .print_help = gpu_status_print_help, + .print_header = gpu_status_print_header, +}; + +/* + * GPU DVFS Monitor + */ +#define MTK_GPU_DVFS_TYPE_ITEM(type) #type, +static char *gpu_dvfs_type_name[] = MTK_GPU_DVFS_TYPE_LIST; +#undef MTK_GPU_DVFS_TYPE_ITEM + +static enum MTK_GPU_DVFS_TYPE gpu_dvfs_type_prev; +static unsigned long gpu_dvfs_type_freq_prev; +static unsigned int gpu_dvfs_type_freq[ARRAY_SIZE(gpu_dvfs_type_name)]; + +noinline void GPU_DVFS(unsigned int Freq, unsigned int ThermalLimit, + unsigned int CustomBoost, unsigned int CustomUpbound) +{ + MET_TRACE("%u,%u,%u,%u\n", Freq, ThermalLimit, CustomBoost, CustomUpbound); +} + +noinline void GPU_DVFS_TYPE(void) +{ + char *SOB, *EOB; + + MET_TRACE_GETBUF(&SOB, &EOB); + EOB = ms_formatD_EOL(EOB, ARRAY_SIZE(gpu_dvfs_type_freq), gpu_dvfs_type_freq); + MET_TRACE_PUTBUF(SOB, EOB); +} + +noinline void GPU_DVFS_VSYNC(unsigned long freq) +{ + MET_TRACE("%lu\n", freq); +} + +noinline void GPU_VSYNC_OFFSET_STATUS(unsigned int event_status, unsigned int debug_status) +{ + MET_TRACE("%u,%u\n", event_status, debug_status); +} + +static void gpu_dvfs(void) +{ + unsigned int freq = 0; + unsigned int ThermalLimit = 0; + enum MTK_GPU_DVFS_TYPE peType; + unsigned long pulFreq = 0; + unsigned int CustomBoost = 0; + unsigned int CustomUpbound = 0; + unsigned int event_status = 0; + unsigned int debug_status = 0; + + freq = mt_gpufreq_get_cur_freq_symbol ? mt_gpufreq_get_cur_freq_symbol() : 0; + ThermalLimit = mt_gpufreq_get_thermal_limit_freq_symbol ? mt_gpufreq_get_thermal_limit_freq_symbol() : 0; + if (mtk_get_custom_boost_gpu_freq_symbol) + mtk_get_custom_boost_gpu_freq_symbol(&CustomBoost); + if (mtk_get_custom_upbound_gpu_freq_symbol) + mtk_get_custom_upbound_gpu_freq_symbol(&CustomUpbound); + GPU_DVFS(freq, ThermalLimit, CustomBoost, CustomUpbound); + + /* gpu dvfs type */ + if (mtk_get_gpu_dvfs_from_symbol && mtk_get_gpu_dvfs_from_symbol(&peType, &pulFreq)) { + if (gpu_dvfs_type_prev != peType || gpu_dvfs_type_freq_prev != pulFreq) { + gpu_dvfs_type_freq[gpu_dvfs_type_prev] = 0; + gpu_dvfs_type_prev = peType; + gpu_dvfs_type_freq_prev = pulFreq; + gpu_dvfs_type_freq[gpu_dvfs_type_prev] = gpu_dvfs_type_freq_prev; + GPU_DVFS_TYPE(); + } + } + + if (mtk_get_vsync_based_target_freq_symbol && mtk_get_vsync_based_target_freq_symbol(&pulFreq)) + GPU_DVFS_VSYNC(pulFreq); + + if (mtk_get_vsync_offset_event_status_symbol && mtk_get_vsync_offset_debug_status_symbol) { + if (mtk_get_vsync_offset_event_status_symbol(&event_status) + && mtk_get_vsync_offset_debug_status_symbol(&debug_status)) { + GPU_VSYNC_OFFSET_STATUS(event_status, debug_status); + } + } +} + +static void gpu_dvfs_work(struct work_struct *work) +{ + gpu_dvfs(); +} + +static void gpu_dvfs_monitor_start(void) +{ + gpu_dvfs(); + INIT_DELAYED_WORK(&gpu_dvfs_dwork, gpu_dvfs_work); +} + +static void gpu_dvfs_monitor_stop(void) +{ + cancel_delayed_work_sync(&gpu_dvfs_dwork); + gpu_dvfs(); + + /* reset status */ + gpu_dvfs_type_prev = 0; + gpu_dvfs_type_freq_prev = 0; +} + +static void gpu_dvfs_monitor_polling(unsigned long long stamp, int cpu) +{ + schedule_delayed_work(&gpu_dvfs_dwork, 0); +} + +static int gpu_dvfs_print_help(char *buf, int len) +{ + return snprintf(buf, PAGE_SIZE, + " --gpu-dvfs monitor gpu freq\n"); +} + +static int gpu_dvfs_print_header(char *buf, int len) +{ + int ret = 0; + int i = 0; + + ret = snprintf(buf, PAGE_SIZE, + "met-info [000] 0.0: met_gpu_dvfs_header: "); + ret += snprintf(buf+ret, PAGE_SIZE-ret, + "Freq(kHz),ThermalLimit(kHz),CustomBoost,CustomUpbound\n"); + + ret += snprintf(buf+ret, PAGE_SIZE-ret, + "met-info [000] 0.0: met_gpu_dvfs_type_header: %s", gpu_dvfs_type_name[0]); + for (i = 1; i < ARRAY_SIZE(gpu_dvfs_type_name); i++) + ret += snprintf(buf+ret, PAGE_SIZE-ret, ",%s", gpu_dvfs_type_name[i]); + ret += snprintf(buf+ret, PAGE_SIZE-ret, "%s", "\n"); + + ret += snprintf(buf+ret, PAGE_SIZE-ret, + "met-info [000] 0.0: met_gpu_dvfs_vsync_header: VSYNC Based Freq\n"); + ret += snprintf(buf+ret, PAGE_SIZE-ret, + "met-info [000] 0.0: met_gpu_vsync_offset_status_header: Event Status,Debug Status\n"); + + return ret; +} + +struct metdevice met_gpudvfs = { + .name = "gpu-dvfs", + .owner = THIS_MODULE, + .type = MET_TYPE_BUS, + .cpu_related = 0, + .start = gpu_dvfs_monitor_start, + .stop = gpu_dvfs_monitor_stop, + .polling_interval = 1, /* ms */ + .timed_polling = gpu_dvfs_monitor_polling, + .print_help = gpu_dvfs_print_help, + .print_header = gpu_dvfs_print_header, + .ondiemet_mode = 0, +}; + +/* + * GPU MEM monitor + */ +static unsigned long g_u4MemProfileIsOn; + +static void gpu_mem_monitor_start(void) +{ + if (!mtk_get_gpu_memory_usage_symbol) + return; + +#if 0 + if (mtk_get_gpu_memory_usage_symbol(&u4Value)) + g_u4MemProfileIsOn = 1; +#endif + g_u4MemProfileIsOn = 1; +} + +noinline void GPU_MEM(unsigned long long stamp, int cpu) +{ + unsigned int u4Value = 0; + + if (!mtk_get_gpu_memory_usage_symbol) + return; + + if (g_u4MemProfileIsOn == 1) { + mtk_get_gpu_memory_usage_symbol(&u4Value); + MET_TRACE("%d\n", u4Value); + } +} + +static void gpu_mem_monitor_stop(void) +{ + g_u4MemProfileIsOn = 0; +} + +static char help_mem[] = + " --gpu-mem monitor gpu memory status\n"; +static int gpu_mem_status_print_help(char *buf, int len) +{ + return snprintf(buf, PAGE_SIZE, help_mem); +} + +static char g_pComGPUMemHeader[] = + "met-info [000] 0.0: met_gpu_mem_header: Usage\n"; +static int gpu_mem_status_print_header(char *buf, int len) +{ + return snprintf(buf, PAGE_SIZE, g_pComGPUMemHeader); +} + +struct metdevice met_gpumem = { + .name = "gpu-mem", + .owner = THIS_MODULE, + .type = MET_TYPE_BUS, + .cpu_related = 0, + .start = gpu_mem_monitor_start, + .stop = gpu_mem_monitor_stop, + .mode = 0, + .polling_interval = 1, /* ms */ + .timed_polling = GPU_MEM, + .print_help = gpu_mem_status_print_help, + .print_header = gpu_mem_status_print_header, +}; + +/* + * GPU power monitor + */ +static unsigned long g_u4PowerProfileIsOn; + +#ifdef GPU_HAL_RUN_PREMPTIBLE +noinline void GPU_Power(struct work_struct *work) +{ + unsigned int u4Value = 0; + + if (!mtk_get_gpu_power_loading_symbol) + return; + + mtk_get_gpu_power_loading_symbol(&u4Value); + MET_TRACE("%d\n", u4Value); +} + +static void GPU_PowerNotify(unsigned long long stamp, int cpu) +{ + if (g_u4PowerProfileIsOn == 1) + schedule_delayed_work(&gpu_pwr_dwork, 0); +} +#else +noinline void GPU_Power(unsigned long long stamp, int cpu) +{ + unsigned int u4Value = 0; + + if (!mtk_get_gpu_power_loading_symbol) + return; + + if (g_u4PowerProfileIsOn == 1) { + mtk_get_gpu_power_loading_symbol(&u4Value); + MET_TRACE("%d\n", u4Value); + } +} +#endif + +static void gpu_Power_monitor_start(void) +{ + if (!mtk_get_gpu_power_loading_symbol) + return; + +#if 0 + if (mtk_get_gpu_power_loading_symbol(&u4Value)) + g_u4PowerProfileIsOn = 1; +#endif + g_u4PowerProfileIsOn = 1; +#ifdef GPU_HAL_RUN_PREMPTIBLE + INIT_DELAYED_WORK(&gpu_pwr_dwork, GPU_Power); +#endif +} + +static void gpu_Power_monitor_stop(void) +{ + g_u4PowerProfileIsOn = 0; + +#ifdef GPU_HAL_RUN_PREMPTIBLE + cancel_delayed_work_sync(&gpu_pwr_dwork); +#endif +} + +static char help_pwr[] = + " --gpu-pwr monitor gpu power status\n"; +static int gpu_Power_status_print_help(char *buf, int len) +{ + return snprintf(buf, PAGE_SIZE, help_pwr); +} + +static char g_pComGPUPowerHeader[] = + "met-info [000] 0.0: met_gpu_power_header: Loading\n"; +static int gpu_Power_status_print_header(char *buf, int len) +{ + return snprintf(buf, PAGE_SIZE, g_pComGPUPowerHeader); +} + +struct metdevice met_gpupwr = { + .name = "gpu-pwr", + .owner = THIS_MODULE, + .type = MET_TYPE_BUS, + .cpu_related = 0, + .start = gpu_Power_monitor_start, + .stop = gpu_Power_monitor_stop, + .mode = 0, + .polling_interval = 1, /* ms */ +#ifdef GPU_HAL_RUN_PREMPTIBLE + .timed_polling = GPU_PowerNotify, +#else + .timed_polling = GPU_Power, +#endif + .print_help = gpu_Power_status_print_help, + .print_header = gpu_Power_status_print_header, +}; + + +/* + * GPU PMU + */ +#define UNUSE_ARG(arg) ((void)arg) + +#ifdef GPU_HAL_RUN_PREMPTIBLE +static struct delayed_work gpu_pmu_dwork; +#endif + +#define MAX_PMU_STR_LEN (1024 * 5) + +static const char help_pmu[] = " --gpu-pmu monitor gpu pmu status"; +static const char header_pmu[] = "met-info [000] 0.0: met_gpu_pmu_header: "; +static char pmu_str[MAX_PMU_STR_LEN]; +static int pmu_cnt; +/* static int gpu_pwr_status = 1; */ +static struct GPU_PMU *pmu_list; + + +noinline void GPU_PMU_RAW( + unsigned long long stamp, + int cpu) +{ + bool ret; + int i = 0; + char *SOB, *EOB; + unsigned int value[pmu_cnt]; + + if (stamp == 0 && cpu == 0) { + for (i = 0; i < pmu_cnt; i++) + value[i] = 0; + + MET_TRACE_GETBUF(&SOB, &EOB); + EOB = ms_formatH(EOB, pmu_cnt, value); + MET_TRACE_PUTBUF(SOB, EOB); + return; + } + + if (mtk_get_gpu_pmu_swapnreset_symbol) { + ret = mtk_get_gpu_pmu_swapnreset_symbol(pmu_list, pmu_cnt); + if (ret) { + for (i = 0; i < pmu_cnt; i++) { + if (pmu_list[i].overflow) + pmu_list[i].value = 0xFFFFFFFF; + value[i] = pmu_list[i].value; + } + MET_TRACE_GETBUF(&SOB, &EOB); + EOB = ms_formatH(EOB, pmu_cnt, value); + MET_TRACE_PUTBUF(SOB, EOB); + } + } +} + +static int create_gpu_pmu_list(void) +{ + int ret = 0; + int len = 0; + int i = 0; + + if (mtk_get_gpu_pmu_init_symbol) { + ret = mtk_get_gpu_pmu_init_symbol(NULL, 0, &pmu_cnt); + if (pmu_cnt == 0 || ret == 0) + return 0; + } else + return 0; + + pmu_list = kmalloc_array(pmu_cnt, sizeof(struct GPU_PMU), GFP_KERNEL); + if (pmu_list) { + memset(pmu_list, 0x00, sizeof(struct GPU_PMU)*pmu_cnt); + ret = mtk_get_gpu_pmu_init_symbol(pmu_list, pmu_cnt, NULL); + + memset(pmu_str, 0x00, MAX_PMU_STR_LEN); + len = snprintf(pmu_str, MAX_PMU_STR_LEN, "%s", pmu_list[0].name); + for (i = 1; i < pmu_cnt; i++) + len += snprintf(pmu_str + len, MAX_PMU_STR_LEN - len, ",%s", pmu_list[i].name); + + /* + * dummy read in order to reset GPU PMU counter + */ + if (mtk_get_gpu_pmu_swapnreset_symbol) + mtk_get_gpu_pmu_swapnreset_symbol(pmu_list, pmu_cnt); + } + + /* init state */ + met_gpu_pmu.header_read_again = 0; + output_header_pmu_len = 0; + output_pmu_str_len = 0; + + return ret; +} + +static void delete_gpu_pmu_list(void) +{ + kfree(pmu_list); + pmu_list = NULL; + pmu_cnt = 0; +} + +static void gpu_pmu_monitor_start(void) +{ + int ret; + + ret = create_gpu_pmu_list(); + if (ret == 0) + return; + +#ifdef GPU_HAL_RUN_PREMPTIBLE + INIT_DELAYED_WORK(&gpu_pmu_dwork, GPU_PMU_RAW); +#endif +} + +static void gpu_pmu_monitor_stop(void) +{ +#ifdef GPU_HAL_RUN_PREMPTIBLE + cancel_delayed_work_sync(&gpu_pmu_dwork); +#endif + + delete_gpu_pmu_list(); + +#if 1 + /* stop polling counter */ + if (mtk_get_gpu_pmu_swapnreset_stop_symbol) + mtk_get_gpu_pmu_swapnreset_stop_symbol(); + /* release resource */ + if (mtk_get_gpu_pmu_deinit_symbol) + mtk_get_gpu_pmu_deinit_symbol(); +#endif +} + +#ifdef GPU_HAL_RUN_PREMPTIBLE +static void gpu_pmu_timed_polling_notify( + unsigned long long stamp, + int cpu) +{ + UNUSE_ARG(stamp); + UNUSE_ARG(cpu); + + if (gpu_pwr_status == 1) + schedule_delayed_work(&gpu_pmu_dwork, 0); +} +#else +static void gpu_pmu_timed_polling( + unsigned long long stamp, + int cpu) +{ + UNUSE_ARG(stamp); + UNUSE_ARG(cpu); + + GPU_PMU_RAW(stamp, cpu); +} +#endif + +static int gpu_pmu_print_help( + char *buf, + int len) +{ + UNUSE_ARG(len); + return snprintf(buf, PAGE_SIZE, "%s\n", help_pmu); +} + +static int gpu_pmu_print_header( + char *buf, + int len) +{ + if(output_header_pmu_len == 0){ + len = snprintf(buf, PAGE_SIZE, "%s", header_pmu); + met_gpu_pmu.header_read_again = 1; + output_header_pmu_len = len; + } + else{ + if( (strlen(pmu_str) - output_pmu_str_len) > PAGE_SIZE ){ + char output_buf[PAGE_SIZE/4]; + + strncpy(output_buf, pmu_str+output_pmu_str_len, PAGE_SIZE/4); + len = snprintf(buf, PAGE_SIZE, "%s", output_buf); + output_pmu_str_len += len; + } + else{ + len = snprintf(buf, PAGE_SIZE, "%s\n", pmu_str+output_pmu_str_len); + + /* reset state */ + met_gpu_pmu.header_read_again = 0; + output_header_pmu_len = 0; + output_pmu_str_len = 0; + } + } + + return len; +} + +struct metdevice met_gpu_pmu = { + .name = "gpu-pmu", + .owner = THIS_MODULE, + .type = MET_TYPE_PMU, + .cpu_related = 0, + .start = gpu_pmu_monitor_start, + .stop = gpu_pmu_monitor_stop, + .mode = 0, + .polling_interval = 1, /* ms */ +#ifdef GPU_HAL_RUN_PREMPTIBLE + .timed_polling = gpu_pmu_timed_polling_notify, +#else + .timed_polling = gpu_pmu_timed_polling, +#endif + .print_help = gpu_pmu_print_help, + .print_header = gpu_pmu_print_header, +}; + +/* + * GPU stall counters + */ +#ifdef MET_GPU_STALL_MONITOR +static void __iomem *io_addr_gpu_stall; + +static int gpu_stall_create_subfs(struct kobject *parent) +{ + io_addr_gpu_stall = ioremap(IO_ADDR_GPU_STALL, IO_SIZE_GPU_STALL); + if (!io_addr_gpu_stall) { + PR_BOOTMSG("Failed to init GPU stall counters!!\n"); + return -ENODEV; + } + + return 0; +} + +static void gpu_stall_delete_subfs(void) +{ + if (io_addr_gpu_stall) { + iounmap(io_addr_gpu_stall); + io_addr_gpu_stall = NULL; + } +} + +static void gpu_stall_start(void) +{ +#ifdef GPU_STALL_CNT_SINGLE + unsigned int value = 0x00000001; +#else + unsigned int value = 0x00010001; +#endif + writel(value, io_addr_gpu_stall+OFFSET_STALL_GPU_M0_CHECK); + writel(value, io_addr_gpu_stall+OFFSET_STALL_GPU_M1_CHECK); + writel(value, io_addr_gpu_stall+OFFSET_STALL_GPU_M0_EMI_CHECK); + writel(value, io_addr_gpu_stall+OFFSET_STALL_GPU_M1_EMI_CHECK); +} + +static void gpu_stall_stop(void) +{ + writel(0x00000000, io_addr_gpu_stall+OFFSET_STALL_GPU_M0_CHECK); + writel(0x00000000, io_addr_gpu_stall+OFFSET_STALL_GPU_M1_CHECK); + writel(0x00000000, io_addr_gpu_stall+OFFSET_STALL_GPU_M0_EMI_CHECK); + writel(0x00000000, io_addr_gpu_stall+OFFSET_STALL_GPU_M1_EMI_CHECK); +} + +noinline void GPU_STALL_RAW(void) +{ + unsigned int stall_counters[4]; + char *SOB, *EOB; + + stall_counters[0] = (unsigned int)readl(io_addr_gpu_stall+OFFSET_STALL_GPU_M0_CHECK); + stall_counters[1] = (unsigned int)readl(io_addr_gpu_stall+OFFSET_STALL_GPU_M1_CHECK); + stall_counters[2] = (unsigned int)readl(io_addr_gpu_stall+OFFSET_STALL_GPU_M0_EMI_CHECK); + stall_counters[3] = (unsigned int)readl(io_addr_gpu_stall+OFFSET_STALL_GPU_M1_EMI_CHECK); + + MET_TRACE_GETBUF(&SOB, &EOB); + EOB = ms_formatH(EOB, ARRAY_SIZE(stall_counters), stall_counters); + MET_TRACE_PUTBUF(SOB, EOB); +} + +static void gpu_stall_timed_polling(unsigned long long stamp, int cpu) +{ + GPU_STALL_RAW(); +} + +#ifdef GPU_STALL_CNT_SINGLE +static char g_pComGPUStallHeader[] = + "met-info [000] 0.0: met_gpu_stall_header: M0_WR,M0_RD,M1_WR,M1_RD\n"; +#else +static char g_pComGPUStallHeader[] = + "met-info [000] 0.0: met_gpu_stall_header: M0_STATUS_1,M1_STATUS_1,M0_STATUS_2,M1_STATUS_2\n"; +#endif +static int gpu_stall_print_header(char *buf, int len) +{ + return snprintf(buf, PAGE_SIZE, g_pComGPUStallHeader); +} + +struct metdevice met_gpu_stall = { + .name = "gpu-stall", + .owner = THIS_MODULE, + .type = MET_TYPE_BUS, + .cpu_related = 0, + .create_subfs = gpu_stall_create_subfs, + .delete_subfs = gpu_stall_delete_subfs, + .start = gpu_stall_start, + .stop = gpu_stall_stop, + .mode = 0, + .polling_interval = 1, /* ms */ + .timed_polling = gpu_stall_timed_polling, + .print_header = gpu_stall_print_header, +}; +#endif /* MET_GPU_STALL_MONITOR */ diff --git a/drivers/misc/mediatek/met_drv_v2/common/mtk_gpu_metmonitor.h b/drivers/misc/mediatek/met_drv_v2/common/mtk_gpu_metmonitor.h new file mode 100644 index 0000000000000000000000000000000000000000..3163d237ffefc02957731a69b7d7e7c58b6a401f --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/mtk_gpu_metmonitor.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef _MT_GPU_METMONITOR_H_ + +#define _MT_GPU_METMONITOR_H_ + +#endif /* _MT_GPU_METMONITOR_H_ */ diff --git a/drivers/misc/mediatek/met_drv_v2/common/mtk_io.h b/drivers/misc/mediatek/met_drv_v2/common/mtk_io.h new file mode 100644 index 0000000000000000000000000000000000000000..860c3d6c5ddee7cea8d7bb9b132b399bae8c2977 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/mtk_io.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2017 MediaTek Inc. + */ + +#ifndef __MT_IO_H__ +#define __MT_IO_H__ + +/* only for arm64 */ +#if IS_ENABLED(CONFIG_ARM64) +#define IOMEM(a) ((void __force __iomem *)((a))) +#endif + +#endif /* !__MT_IO_H__ */ + diff --git a/drivers/misc/mediatek/met_drv_v2/common/mtk_typedefs.h b/drivers/misc/mediatek/met_drv_v2/common/mtk_typedefs.h new file mode 100644 index 0000000000000000000000000000000000000000..c9a593fc50ee72202578b2c96dcb8580ba83cadb --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/mtk_typedefs.h @@ -0,0 +1,310 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef _MT_TYPEDEFS_H__ + +/* + * KOBJ ATTR Manipulations Macros + */ + +#define KOBJ_ITEM_LIST(args...) args + +/* + * Declaring KOBJ attributes + */ +#define DECLARE_KOBJ_ATTR(attr_name) \ + static struct kobj_attribute attr_name##_attr = \ + __ATTR(attr_name, 0664, attr_name##_show, attr_name##_store) + +#define DECLARE_KOBJ_ATTR_RO(attr_name) \ + static struct kobj_attribute attr_name##_attr = \ + __ATTR_RO(attr_name) + +/* + * Declaring KOBJ attributes with integer variable + */ +/* normal version */ +#define DECLARE_KOBJ_ATTR_SHOW_INT(attr_name, var_name) \ + static ssize_t attr_name##_show( \ + struct kobject *kobj, \ + struct kobj_attribute *attr, \ + char *buf) \ + { \ + return snprintf(buf, PAGE_SIZE, "%d\n", var_name); \ + } +#define DECLARE_KOBJ_ATTR_STORE_INT(attr_name, var_name) \ + static ssize_t attr_name##_store( \ + struct kobject *kobj, \ + struct kobj_attribute *attr, \ + const char *buf, \ + size_t n) \ + { \ + int val = 0; \ + if (kstrtoint(buf, 0, &val) != 0) { \ + return -EINVAL; \ + } \ + var_name = val; \ + return n; \ + } +#define DECLARE_KOBJ_ATTR_INT(attr_name, var_name) \ + DECLARE_KOBJ_ATTR_SHOW_INT(attr_name, var_name) \ + DECLARE_KOBJ_ATTR_STORE_INT(attr_name, var_name) \ + DECLARE_KOBJ_ATTR(attr_name) +#define DECLARE_KOBJ_ATTR_RO_INT(attr_name, var_name) \ + DECLARE_KOBJ_ATTR_SHOW_INT(attr_name, var_name) \ + DECLARE_KOBJ_ATTR_RO(attr_name) + +/* cond-check version */ +#define DECLARE_KOBJ_ATTR_STORE_INT_CHECK(attr_name, var_name, cond) \ + static ssize_t attr_name##_store( \ + struct kobject *kobj, \ + struct kobj_attribute *attr, \ + const char *buf, \ + size_t n) \ + { \ + int var_name##temp = var_name; \ + if (kstrtoint(buf, 0, &var_name) != 0) { \ + var_name = var_name##temp; \ + return -EINVAL; \ + } \ + if (cond) { \ + return n; \ + } else { \ + var_name = var_name##temp; \ + return -EINVAL; \ + } \ + } +/* Note: the name of val in cond can NOT be the same as var_name */ +#define DECLARE_KOBJ_ATTR_INT_CHECK(attr_name, var_name, cond) \ + DECLARE_KOBJ_ATTR_SHOW_INT(attr_name, var_name) \ + DECLARE_KOBJ_ATTR_STORE_INT_CHECK(attr_name, var_name, cond) \ + DECLARE_KOBJ_ATTR(attr_name) + +/* helper procedure version */ +#define DECLARE_KOBJ_ATTR_SHOW_INT_PROC(attr_name, var_name, func) \ + static ssize_t attr_name##_show( \ + struct kobject *kobj, \ + struct kobj_attribute *attr, \ + char *buf) \ + { \ + return func(kobj, attr, buf, var_name); \ + } +#define DECLARE_KOBJ_ATTR_STORE_INT_PROC(attr_name, var_name, func) \ + static ssize_t attr_name##_store( \ + struct kobject *kobj, \ + struct kobj_attribute *attr, \ + const char *buf, \ + size_t n) \ + { \ + return func(kobj, attr, buf, n, &(var_name)); \ + } +#define DECLARE_KOBJ_ATTR_INT_PROC(attr_name, var_name, show, store) \ + DECLARE_KOBJ_ATTR_SHOW_INT_PROC(attr_name, var_name, show) \ + DECLARE_KOBJ_ATTR_STORE_INT_PROC(attr_name, var_name, store) \ + DECLARE_KOBJ_ATTR(attr_name) + +/* + * Declaring KOBJ attributes with integer(hex) variable + */ +/* normal version */ +#define DECLARE_KOBJ_ATTR_SHOW_HEX(attr_name, var_name) \ + static ssize_t attr_name##_show( \ + struct kobject *kobj, \ + struct kobj_attribute *attr, \ + char *buf) \ + { \ + return snprintf(buf, PAGE_SIZE, "%x\n", var_name); \ + } +#define DECLARE_KOBJ_ATTR_STORE_HEX(attr_name, var_name) \ + static ssize_t attr_name##_store( \ + struct kobject *kobj, \ + struct kobj_attribute *attr, \ + const char *buf, \ + size_t n) \ + { \ + unsigned int val = 0; \ + if (kstrtouint(buf, 0, &val) != 0) { \ + return -EINVAL; \ + } \ + var_name = val; \ + return n; \ + } +#define DECLARE_KOBJ_ATTR_HEX(attr_name, var_name) \ + DECLARE_KOBJ_ATTR_SHOW_HEX(attr_name, var_name) \ + DECLARE_KOBJ_ATTR_STORE_HEX(attr_name, var_name) \ + DECLARE_KOBJ_ATTR(attr_name) +#define DECLARE_KOBJ_ATTR_RO_HEX(attr_name, var_name) \ + DECLARE_KOBJ_ATTR_SHOW_HEX(attr_name, var_name) \ + DECLARE_KOBJ_ATTR_RO(attr_name) + +/* cond-check version */ +#define DECLARE_KOBJ_ATTR_STORE_HEX_CHECK(attr_name, var_name, cond) \ + static ssize_t attr_name##_store( \ + struct kobject *kobj, \ + struct kobj_attribute *attr, \ + const char *buf, \ + size_t n) \ + { \ + unsigned int var_name##temp = var_name; \ + if (kstrtouint(buf, 0, &var_name) != 0) { \ + var_name = var_name##temp; \ + return -EINVAL; \ + } \ + if (cond) { \ + return n; \ + } else { \ + var_name = var_name##temp; \ + return -EINVAL; \ + } \ + } +/* Note: the name of val in cond can NOT be the same as var_name */ +#define DECLARE_KOBJ_ATTR_HEX_CHECK(attr_name, var_name, cond) \ + DECLARE_KOBJ_ATTR_SHOW_HEX(attr_name, var_name) \ + DECLARE_KOBJ_ATTR_STORE_HEX_CHECK(attr_name, var_name, cond) \ + DECLARE_KOBJ_ATTR(attr_name) + +/* helper procedure version */ +#define DECLARE_KOBJ_ATTR_SHOW_HEX_PROC(attr_name, var_name, func) \ + static ssize_t attr_name##_show( \ + struct kobject *kobj, \ + struct kobj_attribute *attr, \ + char *buf) \ + { \ + return func(kobj, attr, buf, var_name); \ + } +#define DECLARE_KOBJ_ATTR_STORE_HEX_PROC(attr_name, var_name, func) \ + static ssize_t attr_name##_store( \ + struct kobject *kobj, \ + struct kobj_attribute *attr, \ + const char *buf, \ + size_t n) \ + { \ + return func(kobj, attr, buf, n, &(var_name)); \ + } +#define DECLARE_KOBJ_ATTR_HEX_PROC(attr_name, var_name, show, store) \ + DECLARE_KOBJ_ATTR_SHOW_HEX_PROC(attr_name, var_name, show) \ + DECLARE_KOBJ_ATTR_STORE_HEX_PROC(attr_name, var_name, store) \ + DECLARE_KOBJ_ATTR(attr_name) + +/* + * Declaring KOBJ attributes with string variable + */ +#define DECLARE_KOBJ_ATTR_SHOW_STR(attr_name, var_name) \ + static ssize_t attr_name##_show( \ + struct kobject *kobj, \ + struct kobj_attribute *attr, \ + char *buf) \ + { \ + return snprintf(buf, PAGE_SIZE, "%s", var_name); \ + } + +#define DECLARE_KOBJ_ATTR_RO_STR(attr_name, var_name) \ + DECLARE_KOBJ_ATTR_SHOW_STR(attr_name, var_name) \ + DECLARE_KOBJ_ATTR_RO(attr_name) + +/* + * Declaring KOBJ attributes with integer list variable + */ +#define DECLARE_KOBJ_ATTR_INT_LIST_ITEM(list_name, list) \ + static struct list_name##_list_item_t { \ + int key; \ + int val; \ + } const list_name##_list_item[] = { list } +#define DECLARE_KOBJ_ATTR_SHOW_INT_LIST(attr_name, var_name, list_name) \ + static ssize_t attr_name##_show( \ + struct kobject *kobj, \ + struct kobj_attribute *attr, \ + char *buf) \ + { \ + int i; \ + for (i = 0; i < ARRAY_SIZE(list_name##_list_item); i++) { \ + if (var_name == list_name##_list_item[i].key) { \ + return snprintf(buf, \ + PAGE_SIZE, \ + "%d\n", \ + list_name##_list_item[i].val); \ + } \ + } \ + return snprintf(buf, PAGE_SIZE, "%d\n", -1); \ + } +#define DECLARE_KOBJ_ATTR_STORE_INT_LIST(attr_name, var_name, list_name) \ + static ssize_t attr_name##_store( \ + struct kobject *kobj, \ + struct kobj_attribute *attr, \ + const char *buf, \ + size_t n) \ + { \ + int value; \ + int i; \ + if (kstrtoint(buf, 10, &value) != 0) \ + return -EINVAL; \ + for (i = 0; i < ARRAY_SIZE(list_name##_list_item); i++) { \ + if (value == list_name##_list_item[i].val) { \ + var_name = list_name##_list_item[i].key; \ + return n; \ + } \ + } \ + return -EINVAL; \ + } +#define DECLARE_KOBJ_ATTR_INT_LIST(attr_name, var_name, list_name) \ + DECLARE_KOBJ_ATTR_SHOW_INT_LIST(attr_name, var_name, list_name) \ + DECLARE_KOBJ_ATTR_STORE_INT_LIST(attr_name, var_name, list_name) \ + DECLARE_KOBJ_ATTR(attr_name) + +/* + * Declaring KOBJ attributes with string list variable + */ +#define DECLARE_KOBJ_ATTR_STR_LIST_ITEM(list_name, list) \ + static struct list_name##_list_item_t { \ + int key; \ + char *val; \ + } const list_name##_list_item[] = { list } +#define DECLARE_KOBJ_ATTR_SHOW_STR_LIST(attr_name, var_name, list_name) \ + static ssize_t attr_name##_show( \ + struct kobject *kobj, \ + struct kobj_attribute *attr, \ + char *buf) \ + { \ + int i; \ + for (i = 0; i < ARRAY_SIZE(list_name##_list_item); i++) { \ + if (var_name == list_name##_list_item[i].key) { \ + return snprintf(buf, \ + PAGE_SIZE, \ + "%s\n", \ + list_name##_list_item[i].val); \ + } \ + } \ + return snprintf(buf, PAGE_SIZE, "%s\n", "ERR"); \ + } +#define DECLARE_KOBJ_ATTR_STORE_STR_LIST(attr_name, var_name, list_name) \ + static ssize_t attr_name##_store( \ + struct kobject *kobj, \ + struct kobj_attribute *attr, \ + const char *buf, \ + size_t n) \ + { \ + int i; \ + for (i = 0; i < ARRAY_SIZE(list_name##_list_item); i++) { \ + if (strncasecmp(buf, \ + list_name##_list_item[i].val, \ + strlen(list_name##_list_item[i].val)) == 0) { \ + var_name = list_name##_list_item[i].key; \ + return n; \ + } \ + } \ + return -EINVAL; \ + } +#define DECLARE_KOBJ_ATTR_STR_LIST(attr_name, var_name, list_name) \ + DECLARE_KOBJ_ATTR_SHOW_STR_LIST(attr_name, var_name, list_name) \ + DECLARE_KOBJ_ATTR_STORE_STR_LIST(attr_name, var_name, list_name) \ + DECLARE_KOBJ_ATTR(attr_name) + +/* + * MET Debug Message + */ +#define METINFO(format, ...) pr_debug("[MET]%s: "format, __func__, ##__VA_ARGS__) +#define METERROR(format, ...) pr_debug("[MET][ERR]%s: "format, __func__, ##__VA_ARGS__) + +#endif /* _MT_TYPEDEFS_H__ */ diff --git a/drivers/misc/mediatek/met_drv_v2/common/ondiemet.c b/drivers/misc/mediatek/met_drv_v2/common/ondiemet.c new file mode 100644 index 0000000000000000000000000000000000000000..206b98148142933bfd11e79f10fd455860a4c154 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/ondiemet.c @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include "ondiemet.h" + +/* record enabled modules */ +unsigned int ondiemet_module[ONDIEMET_NUM]; +EXPORT_SYMBOL(ondiemet_module); + +void (*scp_start[ONDIEMET_NUM]) (void) = { +sspm_start, NULL, NULL}; + +void (*scp_stop[ONDIEMET_NUM]) (void) = { +sspm_stop, NULL, NULL}; + +void (*scp_extract[ONDIEMET_NUM]) (void) = { +sspm_extract, NULL, NULL}; + +/* record which MCU is started to generate data */ +int ondiemet_module_started[ONDIEMET_NUM]; + +int ondiemet_attr_init(struct device *dev) +{ + int ret; + + ret = sspm_attr_init(dev); + if (ret != 0) { + pr_debug("can not create device file: sspm related\n"); + return ret; + } + + return 0; + +} + +int ondiemet_attr_uninit(struct device *dev) +{ + int ret; + + ret = sspm_attr_uninit(dev); + if (ret != 0) { + pr_debug("can not delete device file: sspm related\n"); + return ret; + } + + return 0; + +} + +void ondiemet_start(void) +{ + int i; + + for (i = 0; i < ONDIEMET_NUM; i++) { + if (ondiemet_module[i] != 0) { + ondiemet_module_started[i] = 1; + (*scp_start[i]) (); + } + } +} + +void ondiemet_stop(void) +{ + int i; + + for (i = 0; i < ONDIEMET_NUM; i++) { + if (ondiemet_module[i] != 0) { + (*scp_stop[i]) (); + ondiemet_module_started[i] = 0; + } + } +} + +void ondiemet_extract(void) +{ + int i; + + for (i = 0; i < ONDIEMET_NUM; i++) { + if (ondiemet_module[i] != 0) + (*scp_extract[i]) (); + } +} diff --git a/drivers/misc/mediatek/met_drv_v2/common/ondiemet.h b/drivers/misc/mediatek/met_drv_v2/common/ondiemet.h new file mode 100644 index 0000000000000000000000000000000000000000..57c82e148e78d640d617e4573c3fbddc1ec60821 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/ondiemet.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef __ONDIEMET_H +#define __ONDIEMET_H + +#include "ondiemet_log.h" + +extern void ondiemet_extract(void); +extern void ondiemet_stop(void); +extern void ondiemet_start(void); + +#define ONDIEMET_SSPM 0 +#define ONDIEMET_NUM 3 /* total number of supported */ +extern unsigned int ondiemet_module[]; +extern void sspm_start(void); +extern void sspm_stop(void); +extern void sspm_extract(void); +extern int sspm_attr_init(struct device *dev); +extern int sspm_attr_uninit(struct device *dev); + +extern int ondiemet_attr_init(struct device *dev); +extern int ondiemet_attr_uninit(struct device *dev); + +extern int sspm_buffer_size; + +#endif /* __ONDIEMET_H */ diff --git a/drivers/misc/mediatek/met_drv_v2/common/ondiemet_log.c b/drivers/misc/mediatek/met_drv_v2/common/ondiemet_log.c new file mode 100644 index 0000000000000000000000000000000000000000..85514eabe999f80d7821ca2881dc7917ac0af042 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/ondiemet_log.c @@ -0,0 +1,540 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ondiemet_log.h" +#include "interface.h" + +#define ONDIEMET_LOG_REQ 1 +/* TODO: abandon this constatnt */ +#define ONDIEMET_LOG_STOP 2 + +#define PID_NONE (-1) + +#define ONDIEMET_LOG_STOP_MODE 0 +#define ONDIEMET_LOG_RUN_MODE 1 +#define ONDIEMET_LOG_DEBUG_MODE 2 + +static int ondiemet_trace_run; +#ifdef ONDIEMET_MOUNT_DEBUGFS +static struct dentry *dbgfs_met_dir; +#else +static struct proc_dir_entry *procfs_met_dir; +#endif + +struct mutex lock_tracef; +struct ondiemet_log_req_q_t { + struct list_head listq; + struct mutex lockq; + /* struct semaphore new_evt_sema; */ + struct completion new_evt_comp; + int closeq_flag; +} ondiemet_log_req_q; + +struct ondiemet_log_req { + struct list_head list; + int cmd_type; + const char *src; + size_t num; + + void (*on_fini_cb)(const void *p); + const void *param; +}; + +#define __ondiemet_log_req_init(req, cmd, s, n, pf, p) \ + do { \ + INIT_LIST_HEAD(&req->list); \ + req->cmd_type = cmd; \ + req->src = s; \ + req->num = n; \ + req->on_fini_cb = pf; \ + req->param = p; \ + } while (0) + +#define __ondiemet_log_req_fini(req) \ + do { \ + if (req->on_fini_cb) \ + req->on_fini_cb(req->param); \ + kfree(req); \ + } while (0) + +static void __ondiemet_log_req_q_init(struct ondiemet_log_req_q_t *q) +{ + INIT_LIST_HEAD(&q->listq); + mutex_init(&q->lockq); + /* sema_init(&q->new_evt_sema, 0); */ + init_completion(&q->new_evt_comp); + q->closeq_flag = 1; +} + +/* undequeue is seen as a roll-back operation, so it can be done even when the queue is closed */ +static void __ondiemet_log_req_undeq(struct ondiemet_log_req *req) +{ + mutex_lock(&ondiemet_log_req_q.lockq); + list_add(&req->list, &ondiemet_log_req_q.listq); + mutex_unlock(&ondiemet_log_req_q.lockq); + + /* up(&ondiemet_log_req_q.new_evt_sema); */ + complete(&ondiemet_log_req_q.new_evt_comp); +} + +static int __ondiemet_log_req_enq(struct ondiemet_log_req *req) +{ + mutex_lock(&ondiemet_log_req_q.lockq); + if (ondiemet_log_req_q.closeq_flag) { + mutex_unlock(&ondiemet_log_req_q.lockq); + return -EBUSY; + } + + list_add_tail(&req->list, &ondiemet_log_req_q.listq); + if (req->cmd_type == ONDIEMET_LOG_STOP) + ondiemet_log_req_q.closeq_flag = 1; + mutex_unlock(&ondiemet_log_req_q.lockq); + + /* up(&ondiemet_log_req_q.new_evt_sema); */ + complete(&ondiemet_log_req_q.new_evt_comp); + + return 0; +} + +int ondiemet_log_req_enq(const char *src, size_t num, void (*on_fini_cb)(const void *p), const void *param) +{ + struct ondiemet_log_req *req = kmalloc(sizeof(*req), GFP_KERNEL); + + __ondiemet_log_req_init(req, ONDIEMET_LOG_REQ, src, num, on_fini_cb, param); + return __ondiemet_log_req_enq(req); +} + +/*int down_freezable_interruptible(struct semaphore *sem) */ +int down_freezable_interruptible(struct completion *comp) +{ + + int ret; + + freezer_do_not_count(); + /* ret = down_interruptible(sem); */ + ret = wait_for_completion_interruptible(comp); + freezer_count(); + + return ret; +} + +struct ondiemet_log_req *__ondiemet_log_req_deq(void) +{ + struct ondiemet_log_req *ret_req; + + /*if (down_freezable_interruptible(&ondiemet_log_req_q.new_evt_sema))*/ + if (down_freezable_interruptible(&ondiemet_log_req_q.new_evt_comp)) + return NULL; + + mutex_lock(&ondiemet_log_req_q.lockq); + ret_req = list_entry(ondiemet_log_req_q.listq.next, struct ondiemet_log_req, list); + list_del_init(&ret_req->list); + mutex_unlock(&ondiemet_log_req_q.lockq); + + return ret_req; +} + +void __ondiemet_log_req_open(void) +{ + mutex_lock(&ondiemet_log_req_q.lockq); + ondiemet_log_req_q.closeq_flag = 0; + mutex_unlock(&ondiemet_log_req_q.lockq); +} + +int __ondiemet_log_req_closed(void) +{ + int ret; + + mutex_lock(&ondiemet_log_req_q.lockq); + ret = ondiemet_log_req_q.closeq_flag && list_empty(&ondiemet_log_req_q.listq); + mutex_unlock(&ondiemet_log_req_q.lockq); + + return ret; +} + +int __ondiemet_log_req_working(void) +{ + int ret; + + mutex_lock(&ondiemet_log_req_q.lockq); + ret = !ondiemet_log_req_q.closeq_flag; + mutex_unlock(&ondiemet_log_req_q.lockq); + + return ret; +} + +static void *__ondiemet_trace_seq_next(struct seq_file *seqf, loff_t *offset) +{ + struct ondiemet_log_req *next_req; + + if (ondiemet_trace_run == ONDIEMET_LOG_DEBUG_MODE) + pr_debug("[met] __ondiemet_trace_seq_next: pid: %d\n", current->pid); + + if (__ondiemet_log_req_closed()) + return NULL; + + next_req = __ondiemet_log_req_deq(); + + if (next_req == NULL) + return NULL; + + if (next_req->cmd_type == ONDIEMET_LOG_STOP) { + __ondiemet_log_req_fini(next_req); + return NULL; + } + + return (void *) next_req; +} + +struct mutex lock_trace_owner_pid; +pid_t trace_owner_pid = PID_NONE; +static void *ondiemet_trace_seq_start(struct seq_file *seqf, loff_t *offset) +{ + void *ret; + + if (ondiemet_trace_run == ONDIEMET_LOG_DEBUG_MODE) { + pr_debug("[met] ondiemet_trace_seq_start: locked_pid: %d, pid: %d, offset: %llu\n", + trace_owner_pid, current->pid, *offset); + } + + if (!mutex_trylock(&lock_tracef)) + return NULL; + + mutex_lock(&lock_trace_owner_pid); + trace_owner_pid = current->pid; + current->flags |= PF_NOFREEZE; + mutex_unlock(&lock_trace_owner_pid); + + ret = __ondiemet_trace_seq_next(seqf, offset); + + return ret; +} + +static void *ondiemet_trace_seq_next(struct seq_file *seqf, void *p, loff_t *offset) +{ + if (ondiemet_trace_run == ONDIEMET_LOG_DEBUG_MODE) + pr_debug("[met] ondiemet_trace_seq_next: pid: %d\n", current->pid); + + (*offset)++; + return __ondiemet_trace_seq_next(seqf, offset); +} + +static int ondiemet_trace_seq_show(struct seq_file *seqf, void *p) +{ + struct ondiemet_log_req *req = (struct ondiemet_log_req *) p; + size_t l_sz; + size_t r_sz; + struct ondiemet_log_req *l_req; + struct ondiemet_log_req *r_req; + int ret; + + if (ondiemet_trace_run == ONDIEMET_LOG_DEBUG_MODE) + pr_debug("[met] ondiemet_trace_seq_show: pid: %d\n", current->pid); + + if (req->num >= seqf->size) { + l_req = kmalloc(sizeof(*req), GFP_KERNEL); + r_req = req; + + l_sz = seqf->size >> 1; + r_sz = req->num - l_sz; + __ondiemet_log_req_init(l_req, ONDIEMET_LOG_REQ, req->src, l_sz, NULL, NULL); + __ondiemet_log_req_init(r_req, ONDIEMET_LOG_REQ, req->src + l_sz, + r_sz, req->on_fini_cb, req->param); + + __ondiemet_log_req_undeq(r_req); + req = l_req; + + if (ondiemet_trace_run == ONDIEMET_LOG_DEBUG_MODE) + pr_debug("[met] ondiemet_trace_seq_show: split request\n"); + } + + ret = seq_write(seqf, req->src, req->num); + + if (ret) { + /* check if seq_file buffer overflows */ + if (seqf->count == seqf->size) { + __ondiemet_log_req_undeq(req); + } else { + if (ondiemet_trace_run == ONDIEMET_LOG_DEBUG_MODE) + pr_debug("[met] ondiemet_trace_seq_show: reading trace record failed, some data may be lost or corrupted\n"); + __ondiemet_log_req_fini(req); + } + return 0; + } + + __ondiemet_log_req_fini(req); + return 0; +} + +static void ondiemet_trace_seq_stop(struct seq_file *seqf, void *p) +{ + if (ondiemet_trace_run == ONDIEMET_LOG_DEBUG_MODE) + pr_debug("[met] ondiemet_trace_seq_stop: pid: %d\n", current->pid); + + mutex_lock(&lock_trace_owner_pid); + if (current->pid == trace_owner_pid) { + trace_owner_pid = PID_NONE; + mutex_unlock(&lock_tracef); + } + mutex_unlock(&lock_trace_owner_pid); +} + +static const struct seq_operations ondiemet_trace_seq_ops = { + .start = ondiemet_trace_seq_start, + .next = ondiemet_trace_seq_next, + .stop = ondiemet_trace_seq_stop, + .show = ondiemet_trace_seq_show +}; + +static int ondiemet_trace_open(struct inode *inode, struct file *fp) +{ + return seq_open(fp, &ondiemet_trace_seq_ops); +} + +static const struct file_operations ondiemet_trace_fops = { + .owner = THIS_MODULE, + .open = ondiemet_trace_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release +}; + +/*struct semaphore log_start_sema;*/ +struct completion log_start_comp; +int ondiemet_log_manager_start(void) +{ + int ret; + + /* TODO: choose a better return value */ + if (__ondiemet_log_req_working()) + return -EINVAL; + + if (!__ondiemet_log_req_closed()) { + /*ret = down_killable(&log_start_sema);*/ + ret = wait_for_completion_killable(&log_start_comp); + if (ret) + return ret; + } + + __ondiemet_log_req_open(); + + return 0; +} + +/*struct semaphore log_stop_sema;*/ +struct completion log_stop_comp; +static void __log_stop_cb(const void *p) +{ + /* up(&log_start_sema); */ + /* up(&log_stop_sema); */ + complete(&log_start_comp); + complete(&log_stop_comp); +} + +int ondiemet_log_manager_stop(void) +{ + int ret; + struct ondiemet_log_req *req; + + /* TODO: choose a better return value */ + if (__ondiemet_log_req_closed()) + return -EINVAL; + + req = kmalloc(sizeof(*req), GFP_KERNEL); + + __ondiemet_log_req_init(req, ONDIEMET_LOG_STOP, NULL, 0, __log_stop_cb, NULL); + /*sema_init(&log_start_sema, 0); */ + /*sema_init(&log_stop_sema, 0); */ + init_completion(&log_start_comp); + init_completion(&log_stop_comp); + + ret = __ondiemet_log_req_enq(req); + if (ret) + return ret; + + /* XXX: blocking may be break by SIGKILL */ + /*return down_killable(&log_stop_sema);*/ + return wait_for_completion_killable(&log_stop_comp); +} + +int ondiemet_parse_num(const char *str, unsigned int *value, int len) +{ + int ret; + + if (len <= 0) + return -1; + + if ((len > 2) && + ((str[0] == '0') && + ((str[1] == 'x') || (str[1] == 'X')))) { + ret = kstrtouint(str, 16, value); + } else { + ret = kstrtouint(str, 10, value); + } + + if (ret != 0) + return -1; + + return 0; +} + +/* XXX: seq_file will output only when a page is filled */ +static ssize_t ondiemet_log_write_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + char *plog = NULL; + + plog = kmalloc_array(count, sizeof(*plog), GFP_KERNEL); + if (!plog) { + /* TODO: use a better error code */ + return -EINVAL; + } + + memcpy(plog, buf, count); + + mutex_lock(&dev->mutex); + ondiemet_log_req_enq(plog, strnlen(plog, count), kfree, plog); + mutex_unlock(&dev->mutex); + + return count; +} + +static DEVICE_ATTR(ondiemet_log_write, 0664, NULL, ondiemet_log_write_store); + +static ssize_t ondiemet_log_run_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int sz; + + mutex_lock(&dev->mutex); + sz = snprintf(buf, PAGE_SIZE, "%d\n", ondiemet_trace_run); + mutex_unlock(&dev->mutex); + return sz; +} + +static ssize_t ondiemet_log_run_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +{ + int ret; + int prev_run_state; + + mutex_lock(&dev->mutex); + + prev_run_state = ondiemet_trace_run; + + if (kstrtoint(buf, 10, &ondiemet_trace_run) != 0) + return -EINVAL; + + if (ondiemet_trace_run <= ONDIEMET_LOG_STOP_MODE) { + ondiemet_trace_run = ONDIEMET_LOG_STOP_MODE; + ondiemet_log_manager_stop(); + + if (prev_run_state == ONDIEMET_LOG_DEBUG_MODE) + device_remove_file(dev, &dev_attr_ondiemet_log_write); + } else if (ondiemet_trace_run == ONDIEMET_LOG_RUN_MODE) { + ondiemet_trace_run = ONDIEMET_LOG_RUN_MODE; + ondiemet_log_manager_start(); + + if (prev_run_state == ONDIEMET_LOG_DEBUG_MODE) + device_remove_file(dev, &dev_attr_ondiemet_log_write); + } else { + ondiemet_trace_run = ONDIEMET_LOG_DEBUG_MODE; + ondiemet_log_manager_start(); + + if (prev_run_state != ONDIEMET_LOG_DEBUG_MODE) { + ret = device_create_file(dev, &dev_attr_ondiemet_log_write); + if (ret != 0) + pr_debug("[met] can not create device node: ondiemet_log_write\n"); + } + } + + mutex_unlock(&dev->mutex); + + return count; +} + +static DEVICE_ATTR(ondiemet_log_run, 0660, ondiemet_log_run_show, ondiemet_log_run_store); + +int ondiemet_log_manager_init(struct device *dev) +{ + int ret; +#ifdef ONDIEMET_MOUNT_DEBUGFS + struct dentry *d; +#else + struct proc_dir_entry *d; +#endif + + mutex_init(&lock_tracef); + + __ondiemet_log_req_q_init(&ondiemet_log_req_q); + + /*sema_init(&log_start_sema, 0);*/ + /*sema_init(&log_stop_sema, 0);*/ + init_completion(&log_start_comp); + init_completion(&log_stop_comp); + +#ifdef ONDIEMET_MOUNT_DEBUGFS + dbgfs_met_dir = debugfs_create_dir("ondiemet", NULL); + if (!dbgfs_met_dir) { + PR_BOOTMSG("[met] can not create debugfs directory: ondiemet\n"); + return -ENOMEM; + } +#else + procfs_met_dir = proc_mkdir("ondiemet", NULL); + if (!procfs_met_dir) { + PR_BOOTMSG("[met] can not create proc directory: ondiemet\n"); + return -ENOMEM; + } +#endif + + mutex_init(&lock_trace_owner_pid); + +#ifdef ONDIEMET_MOUNT_DEBUGFS + d = debugfs_create_file("trace", 0600, dbgfs_met_dir, NULL, &ondiemet_trace_fops); + if (!d) { + PR_BOOTMSG("[met] can not create devide node in debugfs: ondiemet_trace\n"); + return -ENOMEM; + } +#else + d = proc_create("trace", 0600, procfs_met_dir, &ondiemet_trace_fops); + if (!d) { + PR_BOOTMSG("[met] can not create devide node in procfs: ondiemet_trace\n"); + return -ENOMEM; + } +#endif + + ondiemet_trace_run = __ondiemet_log_req_working(); + ret = device_create_file(dev, &dev_attr_ondiemet_log_run); + if (ret != 0) { + pr_debug("[met] can not create device node: ondiemet_log_run\n"); + return ret; + } + + return 0; +} + +int ondiemet_log_manager_uninit(struct device *dev) +{ + device_remove_file(dev, &dev_attr_ondiemet_log_run); +#ifdef ONDIEMET_MOUNT_DEBUGFS + debugfs_remove_recursive(dbgfs_met_dir); +#else + proc_remove(procfs_met_dir); +#endif + + return 0; +} diff --git a/drivers/misc/mediatek/met_drv_v2/common/ondiemet_log.h b/drivers/misc/mediatek/met_drv_v2/common/ondiemet_log.h new file mode 100644 index 0000000000000000000000000000000000000000..9d65b18872f97ddfdac4208b9436c74d4f378e7c --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/ondiemet_log.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef _ONDIEMET_LOG_H_ +#define _ONDIEMET_LOG_H_ + +#include + +int ondiemet_log_manager_init(struct device *dev); +int ondiemet_log_manager_uninit(struct device *dev); +int ondiemet_log_manager_start(void); +/* Log manager can be reactivated by inserting new requests, i.e., calling ondiemet_log_req_enq() */ +int ondiemet_log_manager_stop(void); +int ondiemet_log_req_enq(const char *src, size_t num, void (*on_fini_cb) (const void *p), + const void *param); + +#endif /* _ONDIEMET_LOG_H_ */ diff --git a/drivers/misc/mediatek/met_drv_v2/common/power.c b/drivers/misc/mediatek/met_drv_v2/common/power.c new file mode 100644 index 0000000000000000000000000000000000000000..0176a4d0e4cec9344dde4dc39dd645d38d3655bc --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/power.c @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include +#include + +#include "power.h" +#include "met_drv.h" +#include "met_kernel_symbol.h" + +noinline void cpu_frequency(unsigned int frequency, unsigned int cpu_id) +{ + if (met_export_api_symbol->met_cpu_frequency) + met_export_api_symbol->met_cpu_frequency(frequency, cpu_id); +} + +void force_power_log(int cpu) +{ + struct cpufreq_policy *p; + + if (cpu == POWER_LOG_ALL) { + for_each_possible_cpu(cpu) { + p = cpufreq_cpu_get(cpu); + if (p != NULL) { + cpu_frequency(p->cur, cpu); + cpufreq_cpu_put(p); + } else { + cpu_frequency(0, cpu); + } + } + } else { + p = cpufreq_cpu_get(cpu); + if (p != NULL) { + cpu_frequency(p->cur, cpu); + cpufreq_cpu_put(p); + } else { + cpu_frequency(0, cpu); + } + } +} + +void force_power_log_val(unsigned int frequency, int cpu) +{ + cpu_frequency(frequency, cpu); +} diff --git a/drivers/misc/mediatek/met_drv_v2/common/power.h b/drivers/misc/mediatek/met_drv_v2/common/power.h new file mode 100644 index 0000000000000000000000000000000000000000..eceef6b7281049b0d92f563fd92564445f1f8210 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/power.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef _POWER_H_ +#define _POWER_H_ + +#define POWER_LOG_ALL -1 +void force_power_log(int cpu); +void force_power_log_val(unsigned int frequency, int cpu); + +#endif /* _POWER_H_ */ diff --git a/drivers/misc/mediatek/met_drv_v2/common/sampler.c b/drivers/misc/mediatek/met_drv_v2/common/sampler.c new file mode 100644 index 0000000000000000000000000000000000000000..a9fc9ffc28114f07f22778d4a2a2c78b932a5df4 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/sampler.c @@ -0,0 +1,718 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#if 0 /* fix me later, no such file on current tree */ +#include +#endif +#include + +#define MET_USER_EVENT_SUPPORT +#include "interface.h" +#include "sampler.h" +#include "met_struct.h" +#include "util.h" +#include "switch.h" +#include "trace.h" +#include "met_drv.h" +#include "met_tag.h" /* for tracing_mark_write */ + +#include "cpu_pmu.h" /* for using kernel perf PMU driver */ + +#include "met_kernel_symbol.h" + +#undef DEBUG_CPU_NOTIFY +/* #define DEBUG_CPU_NOTIFY */ +#if defined(DEBUG_CPU_NOTIFY) +#ifdef CONFIG_MET_MODULE +#define dbg_met_tag_oneshot met_tag_oneshot_real +#else +#define dbg_met_tag_oneshot met_tag_oneshot +#endif /* CONFIG_MET_MODULE */ +#else +#define dbg_met_tag_oneshot(class_id, name, value) ({ 0; }) +#endif + +static int start; +static unsigned int online_cpu_map; +static int curr_polling_cpu; +static int cpu_related_cnt; +static int cpu_related_polling_hdlr_cnt; + +static int preferred_cpu_list[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + +static int calc_preferred_polling_cpu(unsigned int cpu_map) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(preferred_cpu_list); i++) { + if (cpu_map & (1 << preferred_cpu_list[i])) + return preferred_cpu_list[i]; + } + + return -1; +} + +static void wq_sync_buffer(struct work_struct *work) +{ + int cpu; + struct delayed_work *dw = container_of(work, struct delayed_work, work); + struct met_cpu_struct *met_cpu_ptr = container_of(dw, struct met_cpu_struct, dwork); + + cpu = smp_processor_id(); + if (met_cpu_ptr->cpu != cpu) { + /* panic("ERROR"); */ + return; + } + + /* sync_samples(cpu); */ + /* don't re-add the work if we're shutting down */ + if (met_cpu_ptr->work_enabled) + schedule_delayed_work(dw, DEFAULT_TIMER_EXPIRE); +} + +static enum hrtimer_restart met_hrtimer_notify(struct hrtimer *hrtimer) +{ + int cpu; + int *count; + unsigned long long stamp; + struct met_cpu_struct *met_cpu_ptr = container_of(hrtimer, struct met_cpu_struct, hrtimer); + struct metdevice *c; +#if defined(DEBUG_CPU_NOTIFY) + char msg[32]; +#endif + + cpu = smp_processor_id(); +#if defined(DEBUG_CPU_NOTIFY) + { + char msg[32]; + + snprintf(msg, sizeof(msg), "met_hrtimer notify_%d", cpu); + dbg_met_tag_oneshot(0, msg, 1); + } +#endif + + if (met_cpu_ptr->cpu != cpu) { + /* panic("ERROR2"); */ + dbg_met_tag_oneshot(0, msg, -3); + return HRTIMER_NORESTART; + } + + list_for_each_entry(c, &met_list, list) { + if (c->ondiemet_mode == 0) { + if ((c->mode == 0) || (c->timed_polling == NULL)) + continue; + } else if (c->ondiemet_mode == 1) { + if ((c->mode == 0) || (c->ondiemet_timed_polling == NULL)) + continue; + } else if (c->ondiemet_mode == 2) { + if ((c->mode == 0) || ((c->timed_polling == NULL) + && (c->ondiemet_timed_polling == NULL))) + continue; + } + + count = per_cpu_ptr(c->polling_count, cpu); + if ((*count) > 0) { + (*count)--; + continue; + } + + *(count) = c->polling_count_reload; + + stamp = cpu_clock(cpu); + + if (c->cpu_related == 0) { + if (cpu == curr_polling_cpu) { + if (c->ondiemet_mode == 0) { + c->timed_polling(stamp, 0); + } else if (c->ondiemet_mode == 1) { + c->ondiemet_timed_polling(stamp, 0); + } else if (c->ondiemet_mode == 2) { + if (c->timed_polling) + c->timed_polling(stamp, 0); + if (c->ondiemet_timed_polling) + c->ondiemet_timed_polling(stamp, 0); + } + } + } else { + if (c->ondiemet_mode == 0) { + c->timed_polling(stamp, cpu); + } else if (c->ondiemet_mode == 1) { + c->ondiemet_timed_polling(stamp, cpu); + } else if (c->ondiemet_mode == 2) { + if (c->timed_polling) + c->timed_polling(stamp, 0); + if (c->ondiemet_timed_polling) + c->ondiemet_timed_polling(stamp, 0); + } + } + } + + if (met_cpu_ptr->hrtimer_online_check) { + online_cpu_map |= (1 << cpu); + met_cpu_ptr->hrtimer_online_check = 0; + dbg_met_tag_oneshot(0, "met_online check done", cpu); + if (calc_preferred_polling_cpu(online_cpu_map) == cpu) { + curr_polling_cpu = cpu; + dbg_met_tag_oneshot(0, "met_curr polling cpu", cpu); + } + } + + if (met_cpu_ptr->work_enabled) { + hrtimer_forward_now(hrtimer, ns_to_ktime(DEFAULT_HRTIMER_EXPIRE)); + dbg_met_tag_oneshot(0, msg, 0); + return HRTIMER_RESTART; + } + dbg_met_tag_oneshot(0, msg, 0); + return HRTIMER_NORESTART; +} + +static void __met_init_cpu_related_device(void *unused) +{ + struct metdevice *c; + + list_for_each_entry(c, &met_list, list) { + *(this_cpu_ptr(c->polling_count)) = 0; + if (c->ondiemet_mode == 0) { + if ((c->cpu_related) && (c->mode) && (c->start)) + c->start(); + } else if (c->ondiemet_mode == 1) { + if (((c->cpu_related)) && (c->mode) && (c->ondiemet_start)) + c->ondiemet_start(); + } else if (c->ondiemet_mode == 2) { + if ((c->cpu_related) && (c->mode) && (c->start)) + c->start(); + if (((c->cpu_related)) && (c->mode) && (c->ondiemet_start)) + c->ondiemet_start(); + } + } +} + +static void __met_hrtimer_register(void *unused) +{ + struct met_cpu_struct *met_cpu_ptr = NULL; + struct hrtimer *hrtimer = NULL; + /* struct delayed_work *dw; */ + /*struct metdevice *c;*/ + + met_cpu_ptr = this_cpu_ptr(&met_cpu); +#if defined(DEBUG_CPU_NOTIFY) + { + char msg[32]; + + snprintf(msg, sizeof(msg), "met_hrtimer status_%d", met_cpu_ptr->cpu); + dbg_met_tag_oneshot(0, msg, 1); + } +#endif + /* + * do not open HRtimer when EVENT timer enable + */ + if (!(met_switch.mode & MT_SWITCH_EVENT_TIMER)) { + + hrtimer = &met_cpu_ptr->hrtimer; + hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + hrtimer->function = met_hrtimer_notify; + + if (DEFAULT_HRTIMER_EXPIRE) { + met_cpu_ptr->work_enabled = 1; + /* schedule_delayed_work_on(smp_processor_id(), dw, DEFAULT_TIMER_EXPIRE); */ + hrtimer_start(hrtimer, ns_to_ktime(DEFAULT_HRTIMER_EXPIRE), + HRTIMER_MODE_REL_PINNED); + } + } +} + +static void __met_hrtimer_stop(void *unused) +{ + struct met_cpu_struct *met_cpu_ptr; + struct hrtimer *hrtimer; + /* struct delayed_work *dw; */ + struct metdevice *c; + + met_cpu_ptr = this_cpu_ptr(&met_cpu); +#if defined(DEBUG_CPU_NOTIFY) + { + char msg[32]; + + snprintf(msg, sizeof(msg), "met_hrtimer status_%d", met_cpu_ptr->cpu); + dbg_met_tag_oneshot(0, msg, 0); + } +#endif + /* + * do not open HRtimer when EVENT timer enable + */ + if (!(met_switch.mode & MT_SWITCH_EVENT_TIMER)) { + hrtimer = &met_cpu_ptr->hrtimer; + /* dw = &met_cpu_ptr->dwork; */ + + met_cpu_ptr->work_enabled = 0; + hrtimer_cancel(hrtimer); + + /* cancel_delayed_work_sync(dw); */ + } + list_for_each_entry(c, &met_list, list) { + if (c->ondiemet_mode == 0) { + if ((c->cpu_related) && (c->mode) && (c->stop)) + c->stop(); + } else if (c->ondiemet_mode == 1) { + if ((c->cpu_related) && (c->mode) && (c->ondiemet_stop)) + c->ondiemet_stop(); + } else if (c->ondiemet_mode == 2) { + if ((c->cpu_related) && (c->mode) && (c->stop)) + c->stop(); + if ((c->cpu_related) && (c->mode) && (c->ondiemet_stop)) + c->ondiemet_stop(); + } + *(this_cpu_ptr(c->polling_count)) = 0; + } +} + +static int met_pmu_cpu_notify(enum met_action action, unsigned int cpu) +{ + struct met_cpu_struct *met_cpu_ptr; + struct delayed_work *dw; + int preferred_polling_cpu; + struct metdevice *c; + + if (start == 0) + return NOTIFY_OK; + +#if defined(DEBUG_CPU_NOTIFY) + { + char msg[32]; + + snprintf(msg, sizeof(msg), "met_cpu notify_%d", cpu); + dbg_met_tag_oneshot(0, msg, action); + } +#elif defined(PR_CPU_NOTIFY) + { + char msg[32]; + + if (met_cpu_notify) { + snprintf(msg, sizeof(msg), "met_cpu notify_%d", cpu); + dbg_met_tag_oneshot(0, msg, action); + } + } +#endif + + if (cpu < 0 || cpu >= NR_CPUS) + return NOTIFY_OK; + + switch (action) { + case MET_CPU_ONLINE: + met_cpu_ptr = &per_cpu(met_cpu, cpu); + met_cpu_ptr->hrtimer_online_check = 1; + dbg_met_tag_oneshot(0, "met_online check", cpu); + + if (cpu_related_cnt == 0) { + /*pr_info("%s, %d: curr_polling_cpu is alive = %d\n", + * __func__, __LINE__, online_cpu_map & (1 << curr_polling_cpu)); + */ + + online_cpu_map |= (1 << cpu); + + /* check curr_polling_cpu is alive, if it is down, + * start current cpu hrtimer, and change it to be currr_pollling_cpu + */ + if ((online_cpu_map & (1 << curr_polling_cpu)) == 0) { + if (met_export_api_symbol->met_smp_call_function_single) + met_export_api_symbol->met_smp_call_function_single(cpu, + __met_hrtimer_register, NULL, 1); + curr_polling_cpu = cpu; + } + } else { + if (cpu_related_polling_hdlr_cnt) { + if (met_export_api_symbol->met_smp_call_function_single) { + met_export_api_symbol->met_smp_call_function_single(cpu, + __met_init_cpu_related_device, NULL, 1); + met_export_api_symbol->met_smp_call_function_single(cpu, + __met_hrtimer_register, NULL, 1); + } + } else { + /*pr_info("%s, %d: curr_polling_cpu is alive = %d\n", + * __func__, __LINE__, online_cpu_map & (1 << curr_polling_cpu)); + */ + + online_cpu_map |= (1 << cpu); + + /* check curr_polling_cpu is alive, if it is down, + * start current cpu hrtimer, and change it to be currr_pollling_cpu + */ + if ((online_cpu_map & (1 << curr_polling_cpu)) == 0) { + if (met_export_api_symbol->met_smp_call_function_single) { + met_export_api_symbol->met_smp_call_function_single(cpu, + __met_init_cpu_related_device, NULL, 1); + met_export_api_symbol->met_smp_call_function_single(cpu, + __met_hrtimer_register, NULL, 1); + } + curr_polling_cpu = cpu; + } + } + } + +#if IS_ENABLED(CONFIG_CPU_FREQ) + force_power_log(cpu); +#endif + list_for_each_entry(c, &met_list, list) { + if (c->cpu_state_notify) + c->cpu_state_notify(cpu, action); + } + break; + + case MET_CPU_OFFLINE: + list_for_each_entry(c, &met_list, list) { + if (c->cpu_state_notify) + c->cpu_state_notify(cpu, action); + } + + online_cpu_map &= ~(1 << cpu); + dbg_met_tag_oneshot(0, "met_offline cpu", cpu); + if (cpu == curr_polling_cpu) { + /* pr_info("%s, %d: curr_polling_cpu %d is down\n", + * __func__, __LINE__, curr_polling_cpu); + */ + preferred_polling_cpu = calc_preferred_polling_cpu(online_cpu_map); + /* pr_info("%s, %d: preferred_polling_cpu = %d\n", + * __func__, __LINE__, preferred_polling_cpu); + */ + if (preferred_polling_cpu != -1) { + curr_polling_cpu = preferred_polling_cpu; + dbg_met_tag_oneshot(0, "met_curr polling cpu", curr_polling_cpu); + + if (cpu_related_cnt == 0) { + /* pr_info("%s, %d: start cpu %d hrtimer start\n", + * __func__, __LINE__, curr_polling_cpu); + */ + if (met_export_api_symbol->met_smp_call_function_single) + met_export_api_symbol->met_smp_call_function_single(curr_polling_cpu, + __met_hrtimer_register, NULL, 1); + } else if (cpu_related_polling_hdlr_cnt == 0) { + if (met_export_api_symbol->met_smp_call_function_single) + met_export_api_symbol->met_smp_call_function_single(curr_polling_cpu, + __met_hrtimer_register, NULL, 1); + } + } + } + if (met_export_api_symbol->met_smp_call_function_single) + met_export_api_symbol->met_smp_call_function_single(cpu, + __met_hrtimer_stop, NULL, 1); + + met_cpu_ptr = &per_cpu(met_cpu, cpu); + dw = &met_cpu_ptr->dwork; + cancel_delayed_work_sync(dw); + + /* sync_samples(cpu); */ + break; + default: + list_for_each_entry(c, &met_list, list) { + if (c->cpu_state_notify) + c->cpu_state_notify(cpu, action); + } + } + + return NOTIFY_OK; +} + +static int _met_pmu_cpu_notify_online(unsigned int cpu) +{ + met_pmu_cpu_notify(MET_CPU_ONLINE, cpu); + + return 0; +} + +static int _met_pmu_cpu_notify_offline(unsigned int cpu) +{ + met_pmu_cpu_notify(MET_CPU_OFFLINE, cpu); + + return 0; +} + +int sampler_start(void) +{ + int ret, cpu; + struct met_cpu_struct *met_cpu_ptr; + struct metdevice *c; + int preferred_polling_cpu; + + met_set_suspend_notify(0); + +#if IS_ENABLED(CONFIG_CPU_FREQ) + force_power_log(POWER_LOG_ALL); +#endif + + for_each_possible_cpu(cpu) { + met_cpu_ptr = &per_cpu(met_cpu, cpu); + met_cpu_ptr->work_enabled = 0; + met_cpu_ptr->hrtimer_online_check = 0; + hrtimer_init(&met_cpu_ptr->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + met_cpu_ptr->hrtimer.function = met_hrtimer_notify; + INIT_DELAYED_WORK(&met_cpu_ptr->dwork, wq_sync_buffer); + } + + start = 0; + ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, + "met:online", + _met_pmu_cpu_notify_online, + _met_pmu_cpu_notify_offline); + + list_for_each_entry(c, &met_list, list) { + + if (try_module_get(c->owner) == 0) + continue; + + if ((c->mode) && (c->cpu_related == 1)) { + cpu_related_cnt = 1; + + if (c->ondiemet_mode == 0) { + if (c->timed_polling) + cpu_related_polling_hdlr_cnt = 1; + } else if (c->ondiemet_mode == 1) { + if (c->ondiemet_timed_polling) + cpu_related_polling_hdlr_cnt = 1; + } else if (c->ondiemet_mode == 2) { + if (c->timed_polling || c->ondiemet_timed_polling) + cpu_related_polling_hdlr_cnt = 1; + } + } + + if (c->ondiemet_mode == 0) { + if ((!(c->cpu_related)) && (c->mode) && (c->start)) + c->start(); + else if ((c->cpu_related) && (c->mode) && (c->uniq_start)) + c->uniq_start(); + } else if (c->ondiemet_mode == 1) { + if ((!(c->cpu_related)) && (c->mode) && (c->ondiemet_start)) + c->ondiemet_start(); + if ((c->cpu_related) && (c->mode) && (c->uniq_ondiemet_start)) + c->uniq_ondiemet_start(); + } else if (c->ondiemet_mode == 2) { + if ((!(c->cpu_related)) && (c->mode) && (c->start)) + c->start(); + else if ((c->cpu_related) && (c->mode) && (c->uniq_start)) + c->uniq_start(); + + if ((!(c->cpu_related)) && (c->mode) && (c->ondiemet_start)) + c->ondiemet_start(); + else if ((c->cpu_related) && (c->mode) && (c->uniq_ondiemet_start)) + c->uniq_ondiemet_start(); + } + } + + get_online_cpus(); + online_cpu_map = 0; + for_each_online_cpu(cpu) { + online_cpu_map |= (1 << cpu); + } + dbg_met_tag_oneshot(0, "met_online cpu map", online_cpu_map); + preferred_polling_cpu = calc_preferred_polling_cpu(online_cpu_map); + if (preferred_polling_cpu != -1) + curr_polling_cpu = preferred_polling_cpu; + dbg_met_tag_oneshot(0, "met_curr polling cpu", curr_polling_cpu); + start = 1; + + if (cpu_related_cnt == 0) { + if (met_export_api_symbol->met_smp_call_function_single) + met_export_api_symbol->met_smp_call_function_single(curr_polling_cpu, + __met_hrtimer_register, NULL, 1); + } + else { + //on_each_cpu(__met_hrtimer_start, NULL, 1); + for_each_online_cpu(cpu) { + if (met_export_api_symbol->met_smp_call_function_single) + met_export_api_symbol->met_smp_call_function_single(cpu, + __met_init_cpu_related_device, NULL, 1); + } + + if (cpu_related_polling_hdlr_cnt) { + for_each_online_cpu(cpu) { + if (met_export_api_symbol->met_smp_call_function_single) + met_export_api_symbol->met_smp_call_function_single(cpu, + __met_hrtimer_register, NULL, 1); + } + } else { + if (met_export_api_symbol->met_smp_call_function_single) + met_export_api_symbol->met_smp_call_function_single(curr_polling_cpu, + __met_hrtimer_register, NULL, 1); + } + } + put_online_cpus(); + + return ret; +} + +void sampler_stop(void) +{ + int cpu; + struct met_cpu_struct *met_cpu_ptr; + struct metdevice *c; + struct delayed_work *dw; + + + get_online_cpus(); + //on_each_cpu(__met_hrtimer_stop, NULL, 1); + online_cpu_map = 0; + for_each_online_cpu(cpu) { + online_cpu_map |= (1 << cpu); + } + + for_each_online_cpu(cpu) { + if (met_export_api_symbol->met_smp_call_function_single) + met_export_api_symbol->met_smp_call_function_single(cpu, + __met_hrtimer_stop, NULL, 1); + } + + /* for_each_online_cpu(cpu) { */ + for_each_possible_cpu(cpu) { /* Just for case */ + met_cpu_ptr = &per_cpu(met_cpu, cpu); + dw = &met_cpu_ptr->dwork; + cancel_delayed_work_sync(dw); + /* sync_samples(cpu); */ + } + start = 0; + put_online_cpus(); + + cpuhp_remove_state_nocalls(CPUHP_AP_ONLINE_DYN); + + list_for_each_entry(c, &met_list, list) { + if (c->ondiemet_mode == 0) { + if ((!(c->cpu_related)) && (c->mode) && (c->stop)) + c->stop(); + else if ((c->cpu_related) && (c->mode) && (c->uniq_stop)) + c->uniq_stop(); + } else if (c->ondiemet_mode == 1) { + if ((!(c->cpu_related)) && (c->mode) && (c->ondiemet_stop)) + c->ondiemet_stop(); + else if ((c->cpu_related) && (c->mode) && (c->uniq_ondiemet_stop)) + c->uniq_ondiemet_stop(); + } else if (c->ondiemet_mode == 2) { + if ((!(c->cpu_related)) && (c->mode) && (c->stop)) + c->stop(); + else if ((c->cpu_related) && (c->mode) && (c->uniq_stop)) + c->uniq_stop(); + + if ((!(c->cpu_related)) && (c->mode) && (c->ondiemet_stop)) + c->ondiemet_stop(); + else if ((c->cpu_related) && (c->mode) && (c->uniq_ondiemet_stop)) + c->uniq_ondiemet_stop(); + } + module_put(c->owner); + } + + cpu_related_cnt = 0; + cpu_related_polling_hdlr_cnt = 0; +} + +#if 0 /* cann't use static now */ +enum { + MET_SUSPEND = 1, + MET_RESUME = 2, +}; + +static noinline void tracing_mark_write(int op) +{ + switch (op) { + case MET_SUSPEND: + MET_TRACE("C|0|MET_SUSPEND|1"); + break; + case MET_RESUME: + MET_TRACE("C|0|MET_SUSPEND|0"); + break; + } +} +#endif + +int met_hrtimer_suspend(void) +{ + struct metdevice *c; + + met_set_suspend_notify(1); + /* tracing_mark_write(MET_SUSPEND); */ + tracing_mark_write(TYPE_MET_SUSPEND, 0, 0, 0, 0, 0); + if (start == 0) + return 0; + + list_for_each_entry(c, &met_list, list) { + if (c->suspend) + c->suspend(); + } + + /* get current COUNT */ + MET_TRACE("TS: %llu GPT: %llX", sched_clock(), arch_counter_get_cntvct()); + return 0; +} + +void met_hrtimer_resume(void) +{ + struct metdevice *c; + + /* get current COUNT */ + MET_TRACE("TS: %llu GPT: %llX", sched_clock(), arch_counter_get_cntvct()); + + /* tracing_mark_write(MET_RESUME); */ + tracing_mark_write(TYPE_MET_RESUME, 0, 0, 0, 0, 0); + if (start == 0) + return; + + list_for_each_entry(c, &met_list, list) { + if (c->resume) + c->resume(); + } +} + +/* + * event timer: + * register IRQ, sched_switch event to monitor Polling count + * count can be printed at any live cpu. + */ +void met_event_timer_notify(void) +{ + unsigned long long stamp; + struct metdevice *c; + int cpu = -1; + + if (start == 0) + return; + + cpu = smp_processor_id(); + list_for_each_entry(c, &met_list, list) { + stamp = local_clock(); + + if (c->prev_stamp == 0) + c->prev_stamp = stamp; + + /* Critical Section Start */ + /* try spinlock to prevent a event print twice between config time interval */ + if (!spin_trylock(&(c->my_lock))) + continue; + + /* + * DEFAULT_HRTIMER_EXPIRE (met_hrtimer_expire): + * sample_rate == 0 --> always print + * sample_rate == 1000 --> print interval larger than 1 ms + */ + if (DEFAULT_HRTIMER_EXPIRE == 0 || (stamp - c->prev_stamp) < DEFAULT_HRTIMER_EXPIRE) { + spin_unlock(&(c->my_lock)); + continue; + } + + c->prev_stamp = stamp; + spin_unlock(&(c->my_lock)); + /* Critical Section End */ + + if ((c->mode == 0) || (c->timed_polling == NULL)) + continue; + + stamp = local_clock(); + c->timed_polling(stamp, cpu); + } +} + diff --git a/drivers/misc/mediatek/met_drv_v2/common/sampler.h b/drivers/misc/mediatek/met_drv_v2/common/sampler.h new file mode 100644 index 0000000000000000000000000000000000000000..131203ee79f39f61f9da855c11952a5732a8b369 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/sampler.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef _SAMPLER_H_ +#define _SAMPLER_H_ + +/* + * sampling rate: 1ms + * log generating rate: 10ms + */ +#if 0 +#define DEFAULT_TIMER_EXPIRE (HZ / 100) +#define DEFAULT_HRTIMER_EXPIRE (TICK_NSEC / 10) +#else +extern int met_timer_expire; /* in jiffies */ +extern int met_hrtimer_expire; /* in us */ +#define DEFAULT_TIMER_EXPIRE (met_timer_expire) +#define DEFAULT_HRTIMER_EXPIRE (met_hrtimer_expire) +#endif +/* + * sampling rate: 10ms + * log generating rate: 100ms + */ +/* #define DEFAULT_TIMER_EXPIRE (HZ / 10) */ +/* #define DEFAULT_HRTIMER_EXPIRE (TICK_NSEC / 1) */ + +int met_hrtimer_start(void); +void met_hrtimer_stop(void); +int sampler_start(void); +void sampler_stop(void); + +extern struct list_head met_list; +extern void add_cookie(struct pt_regs *regs, int cpu); +extern int met_hrtimer_suspend(void); +extern void met_hrtimer_resume(void); +extern void met_event_timer_notify(void); + +#if IS_ENABLED(CONFIG_CPU_FREQ) +#include "power.h" +#endif + +#endif /* _SAMPLER_H_ */ diff --git a/drivers/misc/mediatek/met_drv_v2/common/spmtwam/ap/met_spmtwam.c b/drivers/misc/mediatek/met_drv_v2/common/spmtwam/ap/met_spmtwam.c new file mode 100644 index 0000000000000000000000000000000000000000..ba6a8e660f46df80f415a07809e0a7bd5b373ab4 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/spmtwam/ap/met_spmtwam.c @@ -0,0 +1,682 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include +#include +#include +#include +#include + +#include +#include "met_drv.h" +#include "trace.h" +#include "core_plf_init.h" +#include "interface.h" +#include "met_spmtwam.h" + +/* #define SPM_TWAM_DEBUG */ + +#define INFRA_FMEM_DCM_BASE 0x1020E000 +#define INFRA_FMEM_DCM_SIZE 0x1000 +#define FMEM_MUX_ADDR_OFFSET 0x200 +#define FMEM_MUX_VALUE 0x780 +#define TWAM_DBG_SIG_BASE 0x0D0A0000 +#define TWAM_DBG_SIG_SIZE 0x100 +#define TWAM_DBG_SIG_OFFSET 0x94 + + +struct metdevice met_spmtwam; +static struct kobject *kobj_spmtwam; +/* static void __iomem *fmem_dcm_base; */ +static void __iomem *twam_dbg_signal_base; +static struct met_spmtwam_para spmtwam_para[MAX_EVENT_COUNT]; + +#ifdef SPM_TWAM_DEBUG +static unsigned int debug_signal_val; +#endif + +static struct twam_sig twamsig; +static struct twam_sig montype; /* b'00: rising, b'01: falling, b'10: high, b'11: low */ +static struct twam_sig dbgout; +static int used_count; +static int start; +static bool twam_clock_mode = TWAM_SPEED_MODE; /* true:speed mode, false:normal mode */ +static unsigned int window_len = 1300000; /* 50 ms in 26 MHz */ +static unsigned int idle_sel; + +#define MONTYPE_SHOW_IMPLEMENT(num) \ + do { \ + int i; \ + i = snprintf(buf, PAGE_SIZE, "%d\n", montype.sig ## num); \ + return i; \ + } while (0) + +#define MONTYPE_STORE_IMPLEMENT(num) \ + do { \ + int value; \ + if ((n == 0) || (buf == NULL)) \ + return -EINVAL; \ + if (kstrtoint(buf, 10, &value) != 0) \ + return -EINVAL; \ + if (value < 0 || value > 3) \ + return -EINVAL; \ + montype.sig ## num= value; \ + return n; \ + } while (0) + +#define DBGOUT_SHOW_IMPLEMENT(num) \ + do { \ + int i; \ + i = snprintf(buf, PAGE_SIZE, "%d\n", dbgout.sig ## num); \ + return i; \ + } while (0) + +#define DBGOUT_STORE_IMPLEMENT(num) \ + do { \ + int value; \ + if ((n == 0) || (buf == NULL)) \ + return -EINVAL; \ + if (kstrtoint(buf, 10, &value) != 0) \ + return -EINVAL; \ + if (value < 0 || value > 127) \ + return -EINVAL; \ + dbgout.sig ## num = value; \ + return n; \ + } while (0) + + +static ssize_t montype0_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + MONTYPE_SHOW_IMPLEMENT(0); +} + +static ssize_t montype0_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t n) +{ + MONTYPE_STORE_IMPLEMENT(0); +} + +static ssize_t montype1_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + MONTYPE_SHOW_IMPLEMENT(1); +} + +static ssize_t montype1_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t n) +{ + MONTYPE_STORE_IMPLEMENT(1); +} + +static ssize_t montype2_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + MONTYPE_SHOW_IMPLEMENT(2); +} + +static ssize_t montype2_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t n) +{ + MONTYPE_STORE_IMPLEMENT(2); +} + +static ssize_t montype3_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + MONTYPE_SHOW_IMPLEMENT(3); +} + +static ssize_t montype3_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t n) +{ + MONTYPE_STORE_IMPLEMENT(3); +} + +static ssize_t window_len_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + int i; + + i = snprintf(buf, PAGE_SIZE, "%d\n", window_len); + + return i; +} + +static ssize_t window_len_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t n) +{ + int value; + + if ((n == 0) || (buf == NULL)) + return -EINVAL; + + if (kstrtoint(buf, 10, &value) != 0) + return -EINVAL; + + if (value < 0) + return -EINVAL; + + window_len = value; + + return n; +} + +static ssize_t dbgout0_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + DBGOUT_SHOW_IMPLEMENT(0); +} + +static ssize_t dbgout0_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t n) +{ + DBGOUT_STORE_IMPLEMENT(0); +} + +static ssize_t dbgout1_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + DBGOUT_SHOW_IMPLEMENT(1); +} + +static ssize_t dbgout1_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t n) +{ + DBGOUT_STORE_IMPLEMENT(1); +} + +static ssize_t dbgout2_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + DBGOUT_SHOW_IMPLEMENT(2); +} + +static ssize_t dbgout2_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t n) +{ + DBGOUT_STORE_IMPLEMENT(2); +} + +static ssize_t dbgout3_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + DBGOUT_SHOW_IMPLEMENT(3); +} + +static ssize_t dbgout3_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t n) +{ + DBGOUT_STORE_IMPLEMENT(3); +} + +#ifdef SPM_TWAM_DEBUG +/* extern void *mt_spm_base_get(void); */ +static ssize_t debug_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + int ret; + + ret = snprintf(buf, PAGE_SIZE, "0x%x\n", debug_signal_val); + ret += snprintf(buf+ret, PAGE_SIZE-ret, "%d, %d, %d, %d\n", + twam_sig_size[0], twam_sig_size[1], twam_sig_size[2], twam_sig_size[3]); +/* ret += snprintf(buf+ret, PAGE_SIZE-ret, "spm_base_addr: %p\n", mt_spm_base_get()); */ + + return ret; +} +static struct kobj_attribute debug_attr = __ATTR_RO(debug); +#endif + +static struct kobj_attribute montype0_attr = __ATTR(montype0, 0664, montype0_show, montype0_store); +static struct kobj_attribute montype1_attr = __ATTR(montype1, 0664, montype1_show, montype1_store); +static struct kobj_attribute montype2_attr = __ATTR(montype2, 0664, montype2_show, montype2_store); +static struct kobj_attribute montype3_attr = __ATTR(montype3, 0664, montype3_show, montype3_store); +static struct kobj_attribute window_len_attr = __ATTR(window_len, 0664, window_len_show, window_len_store); +static struct kobj_attribute dbgout0_attr = __ATTR(dbgout0, 0664, dbgout0_show, dbgout0_store); +static struct kobj_attribute dbgout1_attr = __ATTR(dbgout1, 0664, dbgout1_show, dbgout1_store); +static struct kobj_attribute dbgout2_attr = __ATTR(dbgout2, 0664, dbgout2_show, dbgout2_store); +static struct kobj_attribute dbgout3_attr = __ATTR(dbgout3, 0664, dbgout3_show, dbgout3_store); + + +/* create spmtwam related kobj node */ +#define KOBJ_ATTR_LIST \ + do { \ + KOBJ_ATTR_ITEM(montype0); \ + KOBJ_ATTR_ITEM(montype1); \ + KOBJ_ATTR_ITEM(montype2); \ + KOBJ_ATTR_ITEM(montype3); \ + KOBJ_ATTR_ITEM(window_len); \ + KOBJ_ATTR_ITEM(dbgout0); \ + KOBJ_ATTR_ITEM(dbgout1); \ + KOBJ_ATTR_ITEM(dbgout2); \ + KOBJ_ATTR_ITEM(dbgout3); \ + } while (0) + +static int met_spmtwam_create(struct kobject *parent) +{ + int ret = 0; + + kobj_spmtwam = parent; + +#define KOBJ_ATTR_ITEM(attr_name) \ + do { \ + ret = sysfs_create_file(kobj_spmtwam, &attr_name ## _attr.attr); \ + if (ret != 0) { \ + pr_notice("Failed to create " #attr_name " in sysfs\n"); \ + return ret; \ + } \ + } while (0) + KOBJ_ATTR_LIST; +#undef KOBJ_ATTR_ITEM + +#ifdef SPM_TWAM_DEBUG + ret = sysfs_create_file(kobj_spmtwam, &debug_attr.attr); + if (ret != 0) { + pr_debug("Failed to create debug in sysfs\n"); + return ret; + } +#endif + + /* init. */ + montype.sig0 = 0x2; + montype.sig1 = 0x2; + montype.sig2 = 0x2; + montype.sig3 = 0x2; + +#if 0 + dbgout.sig0 = 87; + dbgout.sig1 = 89; + dbgout.sig2 = 91; + dbgout.sig3 = 106; +#endif + + return ret; +} + +static void met_spmtwam_delete(void) +{ +#define KOBJ_ATTR_ITEM(attr_name) \ + sysfs_remove_file(kobj_spmtwam, &attr_name ## _attr.attr) + + if (kobj_spmtwam != NULL) { + KOBJ_ATTR_LIST; + kobj_spmtwam = NULL; + } +#undef KOBJ_ATTR_ITEM + +#ifdef SPM_TWAM_DEBUG + sysfs_remove_file(kobj_spmtwam, &debug_attr.attr); +#endif +} + +void ms_spmtwam(struct twam_sig *ts) +{ + switch (used_count) { + case 1: + MET_TRACE(MP_FMT1, + (ts->sig0)); + break; + case 2: + MET_TRACE(MP_FMT2, + (ts->sig0), + (ts->sig1)); + break; + case 3: + MET_TRACE(MP_FMT3, + (ts->sig0), + (ts->sig1), + (ts->sig2)); + break; + case 4: + MET_TRACE(MP_FMT4, + (ts->sig0), + (ts->sig1), + (ts->sig2), + (ts->sig3)); + break; + default: + MET_SPMTWAM_ERR("No assign profile event\n"); + break; + } +} + +static int reset_driver_stat(void) +{ + met_spmtwam.mode = 0; + used_count = 0; + start = 0; + return 0; +} + +void spm_twam_enable_debug_out(struct twam_sig *sig, void *addr) +{ + int value = 0; + + value |= ((1 << 31) | (sig->sig3 << 24) | (sig->sig2 << 16) | (sig->sig1 << 8) | (sig->sig0 << 0)); + +#ifdef SPM_TWAM_DEBUG + debug_signal_val = value; +#endif + + writel(value, addr); +} + +void spm_twam_disable_debug_out(void *addr) +{ + unsigned int value = 0; + + value = readl(addr); + value &= (((unsigned int)(1 << 31)) - 1); + +#ifdef SPM_TWAM_DEBUG + debug_signal_val = value; +#endif + + writel(value, addr); +} + +/* + * Called from "met-cmd --start" + */ +static void spmtwam_start(void) +{ + if (idle_sel == 3) { +#if 0 + /* swithc idle signal D id0 pimux to fmem */ + if (fmem_dcm_base == NULL) { + fmem_dcm_base = ioremap_nocache(INFRA_FMEM_DCM_BASE, INFRA_FMEM_DCM_SIZE); + if (!fmem_dcm_base) { + pr_debug("fmem_dcm_base ioremap fail..."); + return; + } + + writel(FMEM_MUX_VALUE, (fmem_dcm_base + FMEM_MUX_ADDR_OFFSET)); + } +#endif + } else if (idle_sel == 2) { + /* debug signal mapping */ + if (twam_dbg_signal_base == NULL) { + twam_dbg_signal_base = ioremap_nocache(TWAM_DBG_SIG_BASE, TWAM_DBG_SIG_SIZE); + if (!twam_dbg_signal_base) { + pr_debug("twam_dbg_signal_base ioremap fail..."); + return; + } + } + + spm_twam_enable_debug_out(&dbgout, (twam_dbg_signal_base + TWAM_DBG_SIG_OFFSET)); + } + + if (spm_twam_set_mon_type_symbol) + spm_twam_set_mon_type_symbol(&montype); + else { + MET_SPMTWAM_ERR("spm_twam_set_mon_type_symbol is NULL\n"); + return; + } + + if (spm_twam_set_window_length_symbol) + spm_twam_set_window_length_symbol(window_len); + else { + MET_SPMTWAM_ERR("spm_twam_set_window_length_symbol is NULL\n"); + return; + } + + if (spm_twam_set_idle_select_symbol) + spm_twam_set_idle_select_symbol(idle_sel); + else { + MET_SPMTWAM_ERR("spm_twam_set_idle_select_symbol is NULL\n"); + return; + } + + if (spm_twam_register_handler_symbol) + spm_twam_register_handler_symbol(ms_spmtwam); + else { + MET_SPMTWAM_ERR("spm_twam_register_handler_symbol is NULL\n"); + return; + } + + if (spm_twam_enable_monitor_symbol) + spm_twam_enable_monitor_symbol(&twamsig, twam_clock_mode); + else { + MET_SPMTWAM_ERR("spm_twam_enable_monitor_symbol is NULL\n"); + return; + } + + start = 1; +} + +/* + * Called from "met-cmd --stop" + */ +static void spmtwam_stop(void) +{ + if (idle_sel == 3) { +#if 0 + if (fmem_dcm_base) + iounmap(fmem_dcm_base); +#endif + } else if (idle_sel == 2) { + spm_twam_disable_debug_out(twam_dbg_signal_base + TWAM_DBG_SIG_OFFSET); + + if (twam_dbg_signal_base) { + iounmap(twam_dbg_signal_base); + twam_dbg_signal_base = NULL; + } + } + + if (spm_twam_register_handler_symbol) + spm_twam_register_handler_symbol(NULL); + else { + MET_SPMTWAM_ERR("spm_twam_register_handler_symbol is NULL\n"); + return; + } + + if (spm_twam_disable_monitor_symbol) + spm_twam_disable_monitor_symbol(); + else { + MET_SPMTWAM_ERR("spm_twam_disable_monitor_symbol is NULL\n"); + return; + } +} + +static const char header[] = "met-info [000] 0.0: ms_spmtwam_header: "; + +/* + * It will be called back when run "met-cmd --extract" and mode is 1 + */ +static int spmtwam_print_header(char *buf, int len) +{ + int i, total_size; + char idle_sig; + unsigned int event; + + total_size = snprintf(buf, PAGE_SIZE, header); + + for (i = 0; i < used_count; i++) { + idle_sig = spmtwam_para[i].idle_sig; + event = spmtwam_para[i].event; + + total_size += snprintf(buf + total_size, PAGE_SIZE - total_size, + "signal_%c_%02u,", idle_sig, event); + } + + /* cut the last comma */ + buf[total_size - 1] = '\n'; + + total_size += snprintf(buf + total_size, PAGE_SIZE - total_size, "met-info [000] 0.0: spmtwam_clock_mode: %s\n", + twam_clock_mode == TWAM_SPEED_MODE ? "speed" : "normal"); + +#ifdef SPMTWAM_SINGLE_IDLE_SIGNAL + total_size += snprintf(buf + total_size, PAGE_SIZE - total_size, "met-info [000] 0.0: spmtwam_idle_signal_support: %s\n", + TWAM_SINGLE_IDLE_SIGNAL); +#endif + +#ifdef SPMTWAM_MULTIPLE_IDLE_SIGNAL + total_size += snprintf(buf + total_size, PAGE_SIZE - total_size, "met-info [000] 0.0: spmtwam_idle_signal_support: %s\n", + TWAM_MULTIPLE_IDLE_SIGNAL); +#endif + + reset_driver_stat(); + return total_size; +} + +static int assign_slot(char idle_sig, unsigned int event) +{ + int i; + int sig2int; + + if (used_count == MAX_EVENT_COUNT) { + PR_BOOTMSG("%s exceed max used event count\n", MET_SPMTWAM_TAG); + return -1; + } + + /* check duplicated */ + for (i = 0; i < used_count; i++) { + if ((spmtwam_para[i].idle_sig == idle_sig) && + (spmtwam_para[i].event == event)) { + PR_BOOTMSG("%s input duplicated event %u\n", MET_SPMTWAM_TAG, event); + return -2; + } + } + + /* check idle_sig range in a~d or A~D */ + if (tolower(idle_sig) < 'a' || tolower(idle_sig) > 'd') { + PR_BOOTMSG("%s input idle signal %c is not in a~d range\n", + MET_SPMTWAM_TAG, idle_sig); + return -3; + } + + /* check event no */ + if (event > MAX_TWAM_EVENT_COUNT) { + PR_BOOTMSG("%s input event %u exceed max twam event %u\n", + MET_SPMTWAM_TAG, event, MAX_TWAM_EVENT_COUNT); + return -4; + } + +#ifdef SPMTWAM_SINGLE_IDLE_SIGNAL + if (used_count > 0) { + for (i = 0; i < used_count; i++) { + if (idle_sig != spmtwam_para[i].idle_sig) { + PR_BOOTMSG("%s %c idle signal is defferent previous, only support one idle signal\n", + MET_SPMTWAM_TAG, idle_sig); + return -5; + } + } + } +#endif + + spmtwam_para[used_count].idle_sig = idle_sig; + spmtwam_para[used_count].event = event; + + sig2int = (int) (tolower(idle_sig) - 'a'); +#ifdef SPMTWAM_SINGLE_IDLE_SIGNAL + idle_sel = sig2int; +#endif + + switch (used_count) { + case 0: + twamsig.sig0 = event; + break; + case 1: + twamsig.sig1 = event; + break; + case 2: + twamsig.sig2 = event; + break; + case 3: + twamsig.sig3 = event; + break; + } + + used_count++; + + return 0; +} + +static char help[] = + " --spmtwam=clock:[speed|normal] default is normal\n" + " normal mode monitors 4 channels\n" + " speed mode monitors 4 channels\n" + " --spmtwam=signal:selx\n" + " signal= a ~ d for idle signal A~D select\n" + " selx= 0 ~ 31 for for channel event\n"; + +/* + * Called from "met-cmd --help" + */ +static int spmtwam_print_help(char *buf, int len) +{ + return snprintf(buf, PAGE_SIZE, help); +} + +static int spmtwam_process_argument(const char *arg, int len) +{ + if (start == 1) + reset_driver_stat(); + + if (strncmp(arg, "clock:", 6) == 0) { + if (strncmp(&(arg[6]), "speed", 5) == 0) { + twam_clock_mode = TWAM_SPEED_MODE; + } else if (strncmp(&(arg[6]), "normal", 6) == 0) { + twam_clock_mode = TWAM_NORMAL_MODE; + } else { + PR_BOOTMSG("%s unknown clock mode\n", MET_SPMTWAM_TAG); + + goto error; + } + } else { + char signal; + int event; + int ret; + + if (len < 3) { + PR_BOOTMSG("%s input parameter is too short !!!\n", MET_SPMTWAM_TAG); + goto error; + } + + /* + * parse arguments + */ + ret = sscanf(arg, "%c:%u", &signal, &event); + if (ret < 2) { + PR_BOOTMSG("%s input parameter is wrong format !!!\n", MET_SPMTWAM_TAG); + goto error; + } + + if (assign_slot(signal, event) < 0) { + goto error; + } + } + + met_spmtwam.mode = 1; + return 0; + +error: + reset_driver_stat(); + return -1; +} + +struct metdevice met_spmtwam = { + .name = "spmtwam", + .owner = THIS_MODULE, + .type = MET_TYPE_BUS, + .create_subfs = met_spmtwam_create, + .delete_subfs = met_spmtwam_delete, + .cpu_related = 0, + .start = spmtwam_start, + .stop = spmtwam_stop, + .reset = reset_driver_stat, + .print_help = spmtwam_print_help, + .print_header = spmtwam_print_header, + .process_argument = spmtwam_process_argument +}; +EXPORT_SYMBOL(met_spmtwam); diff --git a/drivers/misc/mediatek/met_drv_v2/common/spmtwam/include/met_spmtwam.h b/drivers/misc/mediatek/met_drv_v2/common/spmtwam/include/met_spmtwam.h new file mode 100644 index 0000000000000000000000000000000000000000..def575af37b8437e5d9415a23a59637047b27844 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/spmtwam/include/met_spmtwam.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef __MET_SPMTWAM_H__ +#define __MET_SPMTWAM_H__ + +#define MET_SPMTWAM_TAG "[met_spmtwam]" +#define MET_SPMTWAM_ERR(format, ...) \ + do { \ + MET_TRACE(MET_SPMTWAM_TAG format, ##__VA_ARGS__); \ + PR_BOOTMSG(MET_SPMTWAM_TAG format, ##__VA_ARGS__); \ + } while (0) + +#define TWAM_ENABLE true +#define TWAM_DISABLE false +#define TWAM_SPEED_MODE true +#define TWAM_NORMAL_MODE false +#define TWAM_DEBUG_SIG_ENABLE 1 +#define TWAM_DEBUG_SIG_DISABLE 0 +#define TWAM_SINGLE_IDLE_SIGNAL "single" +#define TWAM_MULTIPLE_IDLE_SIGNAL "multiple" + +struct met_spmtwam_para { + char idle_sig; + int event; +}; + + +/* event counters by HW spec */ +#define MAX_EVENT_COUNT 4 +#define MAX_TWAM_EVENT_COUNT 32 + +#endif diff --git a/drivers/misc/mediatek/met_drv_v2/common/spmtwam/sspm/met_spmtwam.c b/drivers/misc/mediatek/met_drv_v2/common/spmtwam/sspm/met_spmtwam.c new file mode 100644 index 0000000000000000000000000000000000000000..bfe8d12a3e5b1d59ff8fdc9aa0552e56385975a1 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/spmtwam/sspm/met_spmtwam.c @@ -0,0 +1,469 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include +#include +#include +#include +#include + +#include +#include "met_drv.h" +#include "trace.h" +#include "core_plf_init.h" +#include "interface.h" +#include "met_spmtwam.h" + + +struct metdevice met_spmtwam; +static struct kobject *kobj_spmtwam; + +static struct twam_cfg twam_config; +static struct met_spmtwam_para spmtwam_para[MAX_EVENT_COUNT]; + +static unsigned int twam_dbg_enable = TWAM_DEBUG_SIG_DISABLE; +static bool twam_clock_mode = TWAM_SPEED_MODE; /* true:speed mode, false:normal mode */ +static unsigned int window_len = 1300000; /* 50 ms in 26 MHz */ + +static int used_count; +static int start; + + +#define MONTYPE_SHOW_IMPLEMENT(cfg) \ + do { \ + int i; \ + i = snprintf(buf, PAGE_SIZE, "%d\n", cfg.monitor_type); \ + return i; \ + } while (0) + +#define MONTYPE_STORE_IMPLEMENT(cfg) \ + do { \ + int value; \ + if ((n == 0) || (buf == NULL)) \ + return -EINVAL; \ + if (kstrtoint(buf, 10, &value) != 0) \ + return -EINVAL; \ + if (value < 0 || value > 3) \ + return -EINVAL; \ + cfg.monitor_type = value; \ + return n; \ + } while (0) + +static ssize_t montype0_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + MONTYPE_SHOW_IMPLEMENT(twam_config.byte[0]); +} + +static ssize_t montype0_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t n) +{ + MONTYPE_STORE_IMPLEMENT(twam_config.byte[0]); +} + +static ssize_t montype1_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + MONTYPE_SHOW_IMPLEMENT(twam_config.byte[1]); +} + +static ssize_t montype1_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t n) +{ + MONTYPE_STORE_IMPLEMENT(twam_config.byte[1]); +} + +static ssize_t montype2_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + MONTYPE_SHOW_IMPLEMENT(twam_config.byte[2]); +} + +static ssize_t montype2_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t n) +{ + MONTYPE_STORE_IMPLEMENT(twam_config.byte[2]); +} + +static ssize_t montype3_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + MONTYPE_SHOW_IMPLEMENT(twam_config.byte[3]); +} + +static ssize_t montype3_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t n) +{ + MONTYPE_STORE_IMPLEMENT(twam_config.byte[3]); +} + +static ssize_t window_len_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + int i; + + i = snprintf(buf, PAGE_SIZE, "%d\n", window_len); + + return i; +} + +static ssize_t window_len_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t n) +{ + int value; + + if ((n == 0) || (buf == NULL)) + return -EINVAL; + + if (kstrtoint(buf, 10, &value) != 0) + return -EINVAL; + + if (value < 0) + return -EINVAL; + + window_len = value; + + return n; +} + +static struct kobj_attribute montype0_attr = __ATTR(montype0, 0664, montype0_show, montype0_store); +static struct kobj_attribute montype1_attr = __ATTR(montype1, 0664, montype1_show, montype1_store); +static struct kobj_attribute montype2_attr = __ATTR(montype2, 0664, montype2_show, montype2_store); +static struct kobj_attribute montype3_attr = __ATTR(montype3, 0664, montype3_show, montype3_store); +static struct kobj_attribute window_len_attr = __ATTR(window_len, 0664, window_len_show, window_len_store); + + +/* create spmtwam related kobj node */ +#define KOBJ_ATTR_LIST \ + do { \ + KOBJ_ATTR_ITEM(montype0); \ + KOBJ_ATTR_ITEM(montype1); \ + KOBJ_ATTR_ITEM(montype2); \ + KOBJ_ATTR_ITEM(montype3); \ + KOBJ_ATTR_ITEM(window_len); \ + } while (0) + +static int met_spmtwam_create(struct kobject *parent) +{ + int i; + int ret = 0; + + kobj_spmtwam = parent; + +#define KOBJ_ATTR_ITEM(attr_name) \ + do { \ + ret = sysfs_create_file(kobj_spmtwam, &attr_name ## _attr.attr); \ + if (ret != 0) { \ + pr_notice("Failed to create " #attr_name " in sysfs\n"); \ + return ret; \ + } \ + } while (0) + KOBJ_ATTR_LIST; +#undef KOBJ_ATTR_ITEM + + /* init. */ + for (i = 0; i < MAX_EVENT_COUNT; i++) + twam_config.byte[i].monitor_type = 0x2; + + return ret; +} + +static void met_spmtwam_delete(void) +{ +#define KOBJ_ATTR_ITEM(attr_name) \ + sysfs_remove_file(kobj_spmtwam, &attr_name ## _attr.attr) + + if (kobj_spmtwam != NULL) { + KOBJ_ATTR_LIST; + kobj_spmtwam = NULL; + } +#undef KOBJ_ATTR_ITEM +} + +void ms_spmtwam(struct twam_cfg *cfg, struct twam_select *twam_sel) +{ + switch (used_count) { + case 1: + MET_TRACE(MP_FMT1, + (cfg->byte[0].id)); + break; + case 2: + MET_TRACE(MP_FMT2, + (cfg->byte[0].id), + (cfg->byte[1].id)); + break; + case 3: + MET_TRACE(MP_FMT3, + (cfg->byte[0].id), + (cfg->byte[1].id), + (cfg->byte[2].id)); + break; + case 4: + MET_TRACE(MP_FMT4, + (cfg->byte[0].id), + (cfg->byte[1].id), + (cfg->byte[2].id), + (cfg->byte[3].id)); + break; + default: + MET_SPMTWAM_ERR("No assign profile event\n"); + break; + } +} + +static int reset_driver_stat(void) +{ + met_spmtwam.mode = 0; + used_count = 0; + start = 0; + + return 0; +} + +#if 0 +void sspm_twam_debug(void) +{ +/* + PR_BOOTMSG("[MET_TWAM] byte0 idle=%d, event=%d, type=%d \n",twam_config.byte[0].signal,twam_config.byte[0].id,twam_config.byte[0].monitor_type); + PR_BOOTMSG("[MET_TWAM] byte1 idle=%d, event=%d, type=%d \n",twam_config.byte[1].signal,twam_config.byte[1].id,twam_config.byte[1].monitor_type); + PR_BOOTMSG("[MET_TWAM] byte2 idle=%d, event=%d, type=%d \n",twam_config.byte[2].signal,twam_config.byte[2].id,twam_config.byte[2].monitor_type); + PR_BOOTMSG("[MET_TWAM] byte3 idle=%d, event=%d, type=%d \n",twam_config.byte[3].signal,twam_config.byte[3].id,twam_config.byte[3].monitor_type); + PR_BOOTMSG("[MET_TWAM] twam_clock_mode=%d, window_len=%d \n",twam_clock_mode, window_len); +*/ +} +#endif + +/* + * Called from "met-cmd --start" + */ +static void spmtwam_start(void) +{ + if (spm_twam_met_enable_symbol) { + if (true == spm_twam_met_enable_symbol()) { + if (spm_twam_enable_monitor_symbol) + spm_twam_enable_monitor_symbol(TWAM_DISABLE, TWAM_DEBUG_SIG_DISABLE, NULL); + else { + MET_SPMTWAM_ERR("spm_twam_enable_monitor_symbol is NULL\n"); + return; + } + } + } else { + MET_SPMTWAM_ERR("spm_twam_met_enable_symbol is NULL\n"); + return; + } + + if (spm_twam_config_channel_symbol) + spm_twam_config_channel_symbol(&twam_config, twam_clock_mode, window_len); + else { + MET_SPMTWAM_ERR("spm_twam_config_channel_symbol is NULL\n"); + return; + } + + if (spm_twam_enable_monitor_symbol) { + spm_twam_enable_monitor_symbol(TWAM_ENABLE, twam_dbg_enable, ms_spmtwam); + /* sspm_twam_debug(); */ + } else { + MET_SPMTWAM_ERR("spm_twam_enable_monitor_symbol is NULL\n"); + return; + } + + start = 1; +} + +/* + * Called from "met-cmd --stop" + */ +static void spmtwam_stop(void) +{ + if (spm_twam_enable_monitor_symbol) + spm_twam_enable_monitor_symbol(TWAM_DISABLE, TWAM_DEBUG_SIG_DISABLE, NULL); + else { + MET_SPMTWAM_ERR("spm_twam_enable_monitor_symbol is NULL\n"); + return; + } +} + +static const char header[] = "met-info [000] 0.0: ms_spmtwam_header: "; + +/* + * It will be called back when run "met-cmd --extract" and mode is 1 + */ +static int spmtwam_print_header(char *buf, int len) +{ + int i, total_size; + char idle_sig; + unsigned int event; + + total_size = snprintf(buf, PAGE_SIZE, header); + + for (i = 0; i < used_count; i++) { + idle_sig = spmtwam_para[i].idle_sig; + event = spmtwam_para[i].event; + + total_size += snprintf(buf + total_size, PAGE_SIZE - total_size, + "signal_%c_%02u,", idle_sig, event); + } + + /* cut the last comma */ + buf[total_size - 1] = '\n'; + + total_size += snprintf(buf + total_size, PAGE_SIZE - total_size, "met-info [000] 0.0: spmtwam_clock_mode: %s\n", + twam_clock_mode == TWAM_SPEED_MODE ? "speed" : "normal"); + +#ifdef SPMTWAM_SINGLE_IDLE_SIGNAL + total_size += snprintf(buf + total_size, PAGE_SIZE - total_size, "met-info [000] 0.0: spmtwam_idle_signal_support: %s\n", + TWAM_SINGLE_IDLE_SIGNAL); +#endif + +#ifdef SPMTWAM_MULTIPLE_IDLE_SIGNAL + total_size += snprintf(buf + total_size, PAGE_SIZE - total_size, "met-info [000] 0.0: spmtwam_idle_signal_support: %s\n", + TWAM_MULTIPLE_IDLE_SIGNAL); +#endif + + reset_driver_stat(); + return total_size; +} + +static int assign_slot_sspm_twam(char idle_sig, unsigned int event) +{ + int i; + int sig2int; + + if (used_count == MAX_EVENT_COUNT) { + PR_BOOTMSG("%s exceed max used event count\n", MET_SPMTWAM_TAG); + return -1; + } + + /* check duplicated */ + for (i = 0; i < used_count; i++) { + if ((spmtwam_para[i].idle_sig == idle_sig) && + (spmtwam_para[i].event == event)) { + PR_BOOTMSG("%s input duplicated event %u\n", MET_SPMTWAM_TAG, event); + return -2; + } + } + + /* check idle_sig range in a~d or A~D */ + if (tolower(idle_sig) < 'a' || tolower(idle_sig) > 'd') { + PR_BOOTMSG("%s input idle signal %c is not in a~d range\n", + MET_SPMTWAM_TAG, idle_sig); + return -3; + } + + /* check event no */ + if (event > MAX_TWAM_EVENT_COUNT) { + PR_BOOTMSG("%s input event %u exceed max twam event %u\n", + MET_SPMTWAM_TAG, event, MAX_TWAM_EVENT_COUNT); + return -4; + } + +#ifdef SPMTWAM_SINGLE_IDLE_SIGNAL + if (used_count > 0) { + for (i = 0; i < used_count; i++) { + if (idle_sig != spmtwam_para[i].idle_sig) { + PR_BOOTMSG("%s %c idle signal is defferent previous, only support one idle signal\n", + MET_SPMTWAM_TAG, idle_sig); + return -5; + } + } + } +#endif + + spmtwam_para[used_count].idle_sig = idle_sig; + spmtwam_para[used_count].event = event; + + sig2int = (int) (tolower(idle_sig) - 'a'); + + twam_config.byte[used_count].id = event; + twam_config.byte[used_count].signal = sig2int; + + used_count++; + + return 0; +} + +static char help[] = + " --spmtwam=clock:[speed|normal] default is normal\n" + " normal mode monitors 4 channels\n" + " speed mode monitors 4 channels\n" + " --spmtwam=signal:selx\n" + " signal= a ~ d for idle signal A~D select\n" + " selx= 0 ~ 31 for for channel event\n"; + +/* + * Called from "met-cmd --help" + */ +static int spmtwam_print_help(char *buf, int len) +{ + return snprintf(buf, PAGE_SIZE, help); +} + +static int spmtwam_process_argument(const char *arg, int len) +{ + if (start == 1) + reset_driver_stat(); + + if (strncmp(arg, "clock:", 6) == 0) { + if (strncmp(&(arg[6]), "speed", 5) == 0) { + twam_clock_mode = TWAM_SPEED_MODE; + } else if (strncmp(&(arg[6]), "normal", 6) == 0) { + twam_clock_mode = TWAM_NORMAL_MODE; + } else { + PR_BOOTMSG("%s unknown clock mode\n", MET_SPMTWAM_TAG); + + goto error; + } + } else { + char signal; + int event; + int ret; + + if (len < 3) { + PR_BOOTMSG("%s input parameter is too short !!!\n", MET_SPMTWAM_TAG); + goto error; + } + + /* + * parse arguments + */ + ret = sscanf(arg, "%c:%u", &signal, &event); + if (ret < 2) { + PR_BOOTMSG("%s input parameter is wrong format !!!\n", MET_SPMTWAM_TAG); + goto error; + } + + if (assign_slot_sspm_twam(signal, event) < 0) { + goto error; + } + } + + met_spmtwam.mode = 1; + return 0; + +error: + reset_driver_stat(); + return -1; +} + +struct metdevice met_spmtwam = { + .name = "spmtwam", + .owner = THIS_MODULE, + .type = MET_TYPE_BUS, + .create_subfs = met_spmtwam_create, + .delete_subfs = met_spmtwam_delete, + .cpu_related = 0, + .start = spmtwam_start, + .stop = spmtwam_stop, + .reset = reset_driver_stat, + .print_help = spmtwam_print_help, + .print_header = spmtwam_print_header, + .process_argument = spmtwam_process_argument +}; +EXPORT_SYMBOL(met_spmtwam); diff --git a/drivers/misc/mediatek/met_drv_v2/common/sspm/ondiemet_sspm.c b/drivers/misc/mediatek/met_drv_v2/common/sspm/ondiemet_sspm.c new file mode 100644 index 0000000000000000000000000000000000000000..4dd1611d677c32a6c0385146e6d65cfbd07f4a8b --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/sspm/ondiemet_sspm.c @@ -0,0 +1,533 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include +#include /* symbol_get */ + +#define MET_USER_EVENT_SUPPORT +#include "met_drv.h" + +#if IS_ENABLED(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) && defined(ONDIEMET_SUPPORT) +#include "ondiemet_sspm.h" +#include "met_kernel_symbol.h" + +#if IS_ENABLED(CONFIG_MTK_GMO_RAM_OPTIMIZE) || IS_ENABLED(CONFIG_MTK_MET_MEM_ALLOC) +#ifdef CONFIG_MET_ARM_32BIT +#include /* arm_coherent_dma_ops */ +#else /* CONFIG_MET_ARM_32BIT */ +#include +#endif /* CONFIG_MET_ARM_32BIT */ +#else /* CONFIG_MTK_GMO_RAM_OPTIMIZE */ +#include "sspm_reservedmem.h" +/* #include "sspm_reservedmem_define.h" */ +#endif /* CONFIG_MTK_GMO_RAM_OPTIMIZE */ + +dma_addr_t ondiemet_sspm_log_phy_addr; +void *ondiemet_sspm_log_virt_addr; + +#ifdef DYNAMIC_ALLOC_ODM_BUF_SIZE +uint32_t ondiemet_sspm_log_size = DYNAMIC_ALLOC_ODM_BUF_SIZE; +#else +uint32_t ondiemet_sspm_log_size = 0x800000; +#endif + + +/* SSPM_LOG_FILE 0 */ +/* SSPM_LOG_SRAM 1 */ +/* SSPM_LOG_DRAM 2 */ +int sspm_log_mode; +/* SSPM_RUN_NORMAL mode 0 */ +/* SSPM_RUN_CONTINUOUS mode 1 */ +int sspm_run_mode; +int met_sspm_log_discard = -1; +int sspm_log_size = 500; + +int sspm_buffer_size; +int sspm_buf_available; +EXPORT_SYMBOL(sspm_buf_available); +int sspm_buf_mapped = -1; /* get buffer by MET itself */ + + +static ssize_t sspm_ipi_supported_show(struct device *dev, struct device_attribute *attr, char *buf); +static DEVICE_ATTR(sspm_ipi_supported, 0444, sspm_ipi_supported_show, NULL); +static ssize_t sspm_buffer_size_show(struct device *dev, struct device_attribute *attr, char *buf); +static DEVICE_ATTR(sspm_buffer_size, 0444, sspm_buffer_size_show, NULL); + +static ssize_t sspm_available_show(struct device *dev, struct device_attribute *attr, char *buf); +static DEVICE_ATTR(sspm_available, 0444, sspm_available_show, NULL); + +static ssize_t sspm_log_discard_show(struct device *dev, struct device_attribute *attr, char *buf); +static DEVICE_ATTR(sspm_log_discard, 0444, sspm_log_discard_show, NULL); + +static ssize_t sspm_log_mode_show(struct device *dev, struct device_attribute *attr, char *buf); +static ssize_t sspm_log_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); +static DEVICE_ATTR(sspm_log_mode, 0664, sspm_log_mode_show, sspm_log_mode_store); + +static ssize_t sspm_log_size_show(struct device *dev, struct device_attribute *attr, char *buf); +static ssize_t sspm_log_size_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); +static DEVICE_ATTR(sspm_log_size, 0664, sspm_log_size_show, sspm_log_size_store); + + +static ssize_t sspm_run_mode_show(struct device *dev, struct device_attribute *attr, char *buf); +static ssize_t sspm_run_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); +static DEVICE_ATTR(sspm_run_mode, 0664, sspm_run_mode_show, sspm_run_mode_store); + +static ssize_t sspm_modules_show(struct device *dev, struct device_attribute *attr, char *buf); +static ssize_t sspm_modules_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); +static DEVICE_ATTR(sspm_modules, 0664, sspm_modules_show, sspm_modules_store); + +static ssize_t sspm_op_ctrl_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); +static DEVICE_ATTR(sspm_op_ctrl, 0220, NULL, sspm_op_ctrl_store); + + +static ssize_t sspm_ipi_supported_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int ipi_supported; + int i; + + ipi_supported = 0; +#if IS_ENABLED(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) && defined(ONDIEMET_SUPPORT) + #ifndef SSPM_VERSION_V2 + ipi_supported = 1; + #else + if(sspm_ipidev_symbol) + ipi_supported = 1; + #endif +#endif + i = snprintf(buf, PAGE_SIZE, "%d\n", ipi_supported); + if (i < 0) return -1; + + return i; +} + + +static ssize_t sspm_buffer_size_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int i; + + mutex_lock(&dev->mutex); + i = snprintf(buf, PAGE_SIZE, "%d\n", sspm_buffer_size); + mutex_unlock(&dev->mutex); + return i; +} + +static ssize_t sspm_available_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int i; + + mutex_lock(&dev->mutex); + i = snprintf(buf, PAGE_SIZE, "%d\n", 1); + mutex_unlock(&dev->mutex); + return i; +} + +static ssize_t sspm_log_discard_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int i; + + mutex_lock(&dev->mutex); + i = snprintf(buf, PAGE_SIZE, "%d\n", met_sspm_log_discard); + mutex_unlock(&dev->mutex); + return i; +} + +static ssize_t sspm_log_mode_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int i; + + mutex_lock(&dev->mutex); + i = snprintf(buf, PAGE_SIZE, "%d\n", sspm_log_mode); + mutex_unlock(&dev->mutex); + return i; +} + +static ssize_t sspm_log_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +{ + int value; + + if (kstrtoint(buf, 0, &value) != 0) + return -EINVAL; + mutex_lock(&dev->mutex); + sspm_log_mode = value; + mutex_unlock(&dev->mutex); + return count; +} + + +static ssize_t sspm_log_size_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int i; + + mutex_lock(&dev->mutex); + i = snprintf(buf, PAGE_SIZE, "%d\n", sspm_log_size); + mutex_unlock(&dev->mutex); + return i; +} + +static ssize_t sspm_log_size_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +{ + int value; + + if (kstrtoint(buf, 0, &value) != 0) + return -EINVAL; + mutex_lock(&dev->mutex); + sspm_log_size = value; + mutex_unlock(&dev->mutex); + return count; +} + + +static ssize_t sspm_run_mode_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int i; + + mutex_lock(&dev->mutex); + i = snprintf(buf, PAGE_SIZE, "%d\n", sspm_run_mode); + mutex_unlock(&dev->mutex); + return i; +} + +static ssize_t sspm_run_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +{ + int value; + + if (kstrtoint(buf, 0, &value) != 0) + return -EINVAL; + mutex_lock(&dev->mutex); + sspm_run_mode = value; + mutex_unlock(&dev->mutex); + return count; +} + +static ssize_t sspm_op_ctrl_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +{ + int value; + + if (kstrtoint(buf, 0, &value) != 0) + return -EINVAL; + mutex_lock(&dev->mutex); + if (value == 1) + sspm_start(); + else if (value == 2) + sspm_stop(); + else if (value == 3) + sspm_extract(); + else if (value == 4) + sspm_flush(); + mutex_unlock(&dev->mutex); + return count; +} + +static ssize_t sspm_modules_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int i; + + mutex_lock(&dev->mutex); + i = snprintf(buf, PAGE_SIZE, "%x\n", ondiemet_module[ONDIEMET_SSPM]); + mutex_unlock(&dev->mutex); + return i; +} + +static ssize_t sspm_modules_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +{ + uint32_t value; + + if (kstrtouint(buf, 0, &value) != 0) + return -EINVAL; + mutex_lock(&dev->mutex); + ondiemet_module[ONDIEMET_SSPM] = value; + mutex_unlock(&dev->mutex); + return count; +} + +int sspm_attr_init(struct device *dev) +{ + int ret; + +#if IS_ENABLED(CONFIG_MTK_GMO_RAM_OPTIMIZE) || IS_ENABLED(CONFIG_MTK_MET_MEM_ALLOC) +#ifdef CONFIG_MET_ARM_32BIT + struct dma_map_ops *ops = (struct dma_map_ops *)symbol_get(arm_coherent_dma_ops); + + if (ops && ops->alloc) { + dev->coherent_dma_mask = DMA_BIT_MASK(32); + ondiemet_sspm_log_virt_addr = ops->alloc(dev, + ondiemet_sspm_log_size, + &ondiemet_sspm_log_phy_addr, + GFP_KERNEL, + 0); + } +#else /* CONFIG_MET_ARM_32BIT */ + /* dma_alloc */ + ondiemet_sspm_log_virt_addr = dma_alloc_coherent(dev, + ondiemet_sspm_log_size, + &ondiemet_sspm_log_phy_addr, + GFP_KERNEL); +#endif /* CONFIG_MET_ARM_32BIT */ +#else /* CONFIG_MTK_GMO_RAM_OPTIMIZE */ + + phys_addr_t (*sspm_reserve_mem_get_phys_sym)(unsigned int id) = NULL; + phys_addr_t (*sspm_reserve_mem_get_virt_sym)(unsigned int id) = NULL; + phys_addr_t (*sspm_reserve_mem_get_size_sym)(unsigned int id) = NULL; + + sspm_reserve_mem_get_phys_sym = (phys_addr_t (*)(unsigned int id))symbol_get(sspm_reserve_mem_get_virt); + sspm_reserve_mem_get_virt_sym = (phys_addr_t (*)(unsigned int id))symbol_get(sspm_reserve_mem_get_phys); + sspm_reserve_mem_get_size_sym = (phys_addr_t (*)(unsigned int id))symbol_get(sspm_reserve_mem_get_size); + if (sspm_reserve_mem_get_phys_sym) + ondiemet_sspm_log_virt_addr = (void*)sspm_reserve_mem_get_virt(MET_MEM_ID); + if (sspm_reserve_mem_get_virt_sym) + ondiemet_sspm_log_phy_addr = sspm_reserve_mem_get_phys(MET_MEM_ID); + if (sspm_reserve_mem_get_size_sym) + ondiemet_sspm_log_size = sspm_reserve_mem_get_size(MET_MEM_ID); +#endif /* CONFIG_MTK_GMO_RAM_OPTIMIZE */ + + ret = device_create_file(dev, &dev_attr_sspm_buffer_size); + if (ret != 0) { + pr_debug("can not create device file: sspm_buffer_size\n"); + return ret; + } + + ret = device_create_file(dev, &dev_attr_sspm_available); + if (ret != 0) { + pr_debug("can not create device file: sspm_available\n"); + return ret; + } + + ret = device_create_file(dev, &dev_attr_sspm_log_discard); + if (ret != 0) { + pr_debug("can not create device file: sspm_log_discard\n"); + return ret; + } + ret = device_create_file(dev, &dev_attr_sspm_log_mode); + if (ret != 0) { + pr_debug("can not create device file: sspm_log_mode\n"); + return ret; + } + ret = device_create_file(dev, &dev_attr_sspm_log_size); + if (ret != 0) { + pr_debug("can not create device file: sspm_log_size\n"); + return ret; + } + ret = device_create_file(dev, &dev_attr_sspm_run_mode); + if (ret != 0) { + pr_debug("can not create device file: sspm_run_mode\n"); + return ret; + } + ret = device_create_file(dev, &dev_attr_sspm_op_ctrl); + if (ret != 0) { + pr_debug("can not create device file: sspm_op_ctrl\n"); + return ret; + } + ret = device_create_file(dev, &dev_attr_sspm_modules); + if (ret != 0) { + pr_debug("can not create device file: sspm_modules\n"); + return ret; + } + ret = device_create_file(dev, &dev_attr_sspm_ipi_supported); + if (ret != 0) { + pr_debug("can not create device file: sspm_ipi_supported\n"); + return ret; + } + + if (ondiemet_sspm_log_virt_addr != NULL) { + start_sspm_ipi_recv_thread(); + sspm_buf_available = 1; + sspm_buffer_size = ondiemet_sspm_log_size; + } else { + sspm_buf_available = 0; + sspm_buffer_size = -1; + } + + return 0; +} + +int sspm_attr_uninit(struct device *dev) +{ + /* dma_free */ + if (ondiemet_sspm_log_virt_addr != NULL) { +#if IS_ENABLED(CONFIG_MTK_GMO_RAM_OPTIMIZE) || IS_ENABLED(CONFIG_MTK_MET_MEM_ALLOC) +#ifdef CONFIG_MET_ARM_32BIT + struct dma_map_ops *ops = (struct dma_map_ops *)symbol_get(arm_coherent_dma_ops); + + if (ops && ops->free) { + ops->free(dev, + ondiemet_sspm_log_size, + ondiemet_sspm_log_virt_addr, + ondiemet_sspm_log_phy_addr, + 0); + } +#else /* CONFIG_MET_ARM_32BIT */ + dma_free_coherent(dev, + ondiemet_sspm_log_size, + ondiemet_sspm_log_virt_addr, + ondiemet_sspm_log_phy_addr); +#endif /* CONFIG_MET_ARM_32BIT */ +#endif /* CONFIG_MTK_GMO_RAM_OPTIMIZE */ + ondiemet_sspm_log_virt_addr = NULL; + stop_sspm_ipi_recv_thread(); + } + + device_remove_file(dev, &dev_attr_sspm_buffer_size); + device_remove_file(dev, &dev_attr_sspm_available); + device_remove_file(dev, &dev_attr_sspm_log_discard); + device_remove_file(dev, &dev_attr_sspm_log_mode); + device_remove_file(dev, &dev_attr_sspm_log_size); + device_remove_file(dev, &dev_attr_sspm_run_mode); + device_remove_file(dev, &dev_attr_sspm_op_ctrl); + device_remove_file(dev, &dev_attr_sspm_modules); + device_remove_file(dev, &dev_attr_sspm_ipi_supported); + + return 0; +} + +#if 0 /* move to sspm_attr_init() */ +void sspm_get_buffer_info(void) +{ + if (ondiemet_sspm_log_virt_addr != NULL) { + sspm_buf_available = 1; + sspm_buffer_size = ondiemet_sspm_log_size; + } else { + sspm_buf_available = 0; + sspm_buffer_size = -1; + } +} +#endif + +/*extern const char *met_get_platform_name(void);*/ +extern char *met_get_platform(void); +void sspm_start(void) +{ + int32_t ret = 0; + uint32_t rdata; + uint32_t ipi_buf[4]; + const char* platform_name = NULL; + unsigned int platform_id = 0; + met_sspm_log_discard = -1; + + /* clear DRAM buffer */ + if (ondiemet_sspm_log_virt_addr != NULL) + memset_io((void *)ondiemet_sspm_log_virt_addr, 0, ondiemet_sspm_log_size); + else + return; + + /*platform_name = met_get_platform_name();*/ + platform_name = met_get_platform(); + if (platform_name) { + char buf[5]; + + memset(buf, 0x0, 5); + memcpy(buf, &platform_name[2], 4); + + ret = kstrtouint(buf, 10, &platform_id); + } + + /* send DRAM physical address */ + ipi_buf[0] = MET_MAIN_ID | MET_BUFFER_INFO; + ipi_buf[1] = (unsigned int)ondiemet_sspm_log_phy_addr; /* address */ + if (ret == 0) + ipi_buf[2] = platform_id; + else + ipi_buf[2] = 0; + + ipi_buf[3] = 0; + ret = met_ipi_to_sspm_command((void *)ipi_buf, 0, &rdata, 1); + + /* start ondiemet now */ + ipi_buf[0] = MET_MAIN_ID | MET_OP | MET_OP_START; + ipi_buf[1] = ondiemet_module[ONDIEMET_SSPM]; + ipi_buf[2] = sspm_log_mode; + ipi_buf[3] = sspm_run_mode; + ret = met_ipi_to_sspm_command((void *)ipi_buf, 0, &rdata, 1); +} + +extern unsigned int met_get_chip_id(void); +void sspm_stop(void) +{ + int32_t ret; + uint32_t rdata; + uint32_t ipi_buf[4]; + + unsigned int chip_id = 0; + chip_id = met_get_chip_id(); + + if (sspm_buf_available == 1) { + ipi_buf[0] = MET_MAIN_ID|MET_OP|MET_OP_STOP; + ipi_buf[1] = chip_id; + ipi_buf[2] = 0; + ipi_buf[3] = 0; + ret = met_ipi_to_sspm_command((void *)ipi_buf, 0, &rdata, 1); + } +} + +void sspm_extract(void) +{ + int32_t ret; + uint32_t rdata; + uint32_t ipi_buf[4]; + int32_t count; + + count = 20; + if (sspm_buf_available == 1) { + while ((sspm_buffer_dumping == 1) && (count != 0)) { + msleep(50); + count--; + } + ipi_buf[0] = MET_MAIN_ID|MET_OP|MET_OP_EXTRACT; + ipi_buf[1] = 0; + ipi_buf[2] = 0; + ipi_buf[3] = 0; + ret = met_ipi_to_sspm_command((void *)ipi_buf, 0, &rdata, 1); + } + + if (sspm_run_mode == SSPM_RUN_NORMAL) + ondiemet_module[ONDIEMET_SSPM] = 0; +} + +void sspm_flush(void) +{ + int32_t ret; + uint32_t rdata; + uint32_t ipi_buf[4]; + + if (sspm_buf_available == 1) { + ipi_buf[0] = MET_MAIN_ID|MET_OP|MET_OP_FLUSH; + ipi_buf[1] = 0; + ipi_buf[2] = 0; + ipi_buf[3] = 0; + ret = met_ipi_to_sspm_command((void *)ipi_buf, 0, &rdata, 1); + } + + if (sspm_run_mode == SSPM_RUN_NORMAL) + ondiemet_module[ONDIEMET_SSPM] = 0; +} +#else /* CONFIG_MTK_TINYSYS_SSPM_SUPPORT && ONDIEMET_SUPPORT */ +int sspm_buffer_size = -1; + +int sspm_attr_init(struct device *dev) +{ + return 0; +} + +int sspm_attr_uninit(struct device *dev) +{ + return 0; +} + +void sspm_start(void) +{ +} + +void sspm_stop(void) +{ +} + +void sspm_extract(void) +{ +} + +void sspm_flush(void) +{ +} + +#endif /* CONFIG_MTK_TINYSYS_SSPM_SUPPORT && ONDIEMET_SUPPORT */ diff --git a/drivers/misc/mediatek/met_drv_v2/common/sspm/ondiemet_sspm.h b/drivers/misc/mediatek/met_drv_v2/common/sspm/ondiemet_sspm.h new file mode 100644 index 0000000000000000000000000000000000000000..23f8b1b1aca2eec3a44a97815f5631f731d9ffd3 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/sspm/ondiemet_sspm.h @@ -0,0 +1,153 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef __ONDIEMET_SSPM_H +#define __ONDIEMET_SSPM_H + +#if IS_ENABLED(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) && defined(ONDIEMET_SUPPORT) +#include "ondiemet.h" + +#ifndef SSPM_VERSION_V2 +#include "sspm_ipi.h" +#else +#include +#endif /* SSPM_VERSION_V2 */ +#include + +/* we may use IPI_ID_PLATFORM for mt6759 to reduce SRAM */ +#ifndef SSPM_VERSION_V2 +#ifndef IPI_ID_MET +/* #define IPI_ID_MET IPI_ID_TST1 */ +#define IPI_ID_MET IPI_ID_PLATFORM +#endif +#endif /* SSPM_VERSION_V2 */ +/* MET IPI command definition: mbox 0 */ +/* main func ID: bit[31-24]; sub func ID: bit[23-18]; argu 0: bit[17-0] */ +#define MET_MAIN_ID_MASK 0xff000000 /* bit 31 - 24 */ +#define MET_SUB_ID_MASK 0x00fc0000 /* bit 23 - 18 */ +#define MET_ARGU0_MASK 0x0003ffff /* bit 17 - 0 */ +#define FUNC_BIT_SHIFT 18 +#define MID_BIT_SHIFT 9 +#define MET_MAIN_ID 0x06000000 +/* handle argument and attribute */ +#define PROCESS_ARGU 0x01 +#define PROCESS_ATTR 0x02 +#define MODULE_ID_MASK 0x3fe00 /* bit 9 - 17 */ +#define ARGUMENT_MASK 0x01ff /* bit 0 - 8 */ + +/* the following command is used for AP to MD32 */ +#define MET_OP (1 << FUNC_BIT_SHIFT) +/* argu 0: start: 0x01; stop: 0x02; extract: 0x03 */ +#define MET_OP_START 0x00000001 +#define MET_OP_STOP 0x00000002 +#define MET_OP_EXTRACT 0x00000003 +#define MET_OP_FLUSH 0x00000004 +#define MET_SR (2 << FUNC_BIT_SHIFT) /* sample rate */ +#define MET_MODULE (3 << FUNC_BIT_SHIFT) /* module enable/disable */ +#define MET_ARGU (4 << FUNC_BIT_SHIFT) /* argument passing */ +#define MET_ATTR (5 << FUNC_BIT_SHIFT) /* attribute passing */ +/* system memory information for on-die-met log data */ +#define MET_BUFFER_INFO (6 << FUNC_BIT_SHIFT) +#define MET_TIMESTAMP (7 << FUNC_BIT_SHIFT) /* timestamp info */ +#define MET_GPT (8 << FUNC_BIT_SHIFT) /* GPT counter reading */ +#define MET_REQ_AP2MD (9 << FUNC_BIT_SHIFT) /* user defined command */ +#define MET_RESP_AP2MD (10 << FUNC_BIT_SHIFT) /* may no need */ +/* mode: bit 15 - 0: */ +/* Bit 0: MD32 SRAM mode; Bit 1: System DRAM mode */ +/* value: 0: output to next level of storage; 1: loop in its own storage */ +#define MET_DATA_MODE (11 << FUNC_BIT_SHIFT) /* log output mode */ +/* start/stop read data into MD32 SRAM buffer; both DMA and met_printf() */ +#define MET_DATA_OP (12 << FUNC_BIT_SHIFT) /* data read operation */ +/* the following command is used for MD32 to AP */ +#define MET_DUMP_BUFFER (13 << FUNC_BIT_SHIFT) +#define MET_REQ_MD2AP (14 << FUNC_BIT_SHIFT) /* user defined command */ +#define MET_CLOSE_FILE (15 << FUNC_BIT_SHIFT) /* Inform to close the SD file */ +#define MET_RESP_MD2AP (16 << FUNC_BIT_SHIFT) +#define MET_RUN_MODE (17 << FUNC_BIT_SHIFT) + +/* Note: the module ID and its bit pattern should be fixed as below */ +/* DMA based module first */ +enum { + MID_PMQOS = 0, + MID_VCORE_DVFS, + MID_EMI, + MID_THERMAL_CPU, + MID_WALL_TIME, + MID_CPU_DVFS, + MID_GPU_DVFS, + MID_PTPOD, + MID_SPM, + MID_PROFILE, + MID_MET_TAG, + MID_TS, + MID_TS_ISR, + MID_TS_LAST, + MID_TS_ISR_LAST, + MID_SRAM_INFO, + MID_MET_STOP, + MID_IOP_MON, + MID_CPU_INFO_MAPPING, + MID_SMI, + MID_PMU, + + MID_COMMON = 0x1F +}; + +#define ID_PMQOS (1 << MID_PMQOS) +#define ID_SMI (1 << MID_SMI) +#define ID_EMI (1 << MID_EMI) +#define ID_THERMAL_CPU (1 << MID_THERMAL_CPU) +#define ID_WALL_TIME (1 << MID_WALL_TIME) +#define ID_CPU_DVFS (1 << MID_CPU_DVFS) +#define ID_GPU_DVFS (1 << MID_GPU_DVFS) +#define ID_VCORE_DVFS (1 << MID_VCORE_DVFS) +#define ID_PTPOD (1 << MID_PTPOD) +#define ID_SPM (1 << MID_SPM) +#define ID_PROFILE (1 << MID_PROFILE) +#define ID_COMMON (1 << MID_COMMON) +#define ID_CPU_INFO_MAPPING (1 << MID_CPU_INFO_MAPPING) +#define ID_SMI (1 << MID_SMI) +#define ID_PMU (1 << MID_PMU) + +extern void ondiemet_extract(void); +extern void ondiemet_stop(void); +extern void ondiemet_start(void); + +extern void start_sspm_ipi_recv_thread(void); +extern void stop_sspm_ipi_recv_thread(void); +extern int met_ipi_to_sspm_command(void *buffer, int slot, + unsigned int *retbuf, int retslot); +extern int met_ipi_to_sspm_command_async(void *buffer, int slot, + unsigned int *retbuf, int retslot); + + +extern unsigned int ondiemet_ipi_buf[]; + +/* extern phys_addr_t ondiemet_sspm_log_phy_addr, ondiemet_sspm_log_virt_addr; */ +extern dma_addr_t ondiemet_sspm_log_phy_addr; + +extern void *ondiemet_sspm_log_virt_addr; +extern uint32_t ondiemet_sspm_log_size; + +extern int ondiemet_attr_init(struct device *dev); +extern int ondiemet_attr_uninit(struct device *dev); +extern int met_sspm_log_discard; + +#define SSPM_LOG_FILE 0 +#define SSPM_LOG_SRAM 1 +#define SSPM_LOG_DRAM 2 +extern int sspm_log_mode; +#define SSPM_RUN_NORMAL 0 +#define SSPM_RUN_CONTINUOUS 1 +extern int sspm_run_mode; + +/* extern void sspm_get_buffer_info(void); */ +extern int sspm_buf_available; +extern int sspm_buffer_dumping; + +void sspm_flush(void); + +#endif /* CONFIG_MTK_TINYSYS_SSPM_SUPPORT && ONDIEMET_SUPPORT */ +#endif /* __ONDIEMET_SSPM_H */ diff --git a/drivers/misc/mediatek/met_drv_v2/common/sspm/sspm_common.c b/drivers/misc/mediatek/met_drv_v2/common/sspm/sspm_common.c new file mode 100644 index 0000000000000000000000000000000000000000..b42006ff394bf68b8c34cf23f9cd0e6172a684e1 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/sspm/sspm_common.c @@ -0,0 +1,271 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include +#include +#include + +#include "met_drv.h" +#include "ondiemet_sspm.h" + + +struct sspm_met_evnet_header { + unsigned int rts_event_id; + char *rts_event_name; + char *chart_line_name; + char *key_list; +}; + + +enum { + #ifdef MET_SSPM_RTS_EVNET + #undef MET_SSPM_RTS_EVNET + #endif + #define MET_SSPM_RTS_EVNET(rts_event_id, key_list) rts_event_id, + #include "met_sspm_rts_event.h" + + /**********************/ + CUR_MET_RTS_EVENT_NUM, + MAX_MET_RTS_EVENT_NUM = 128 +}; + + +struct sspm_met_evnet_header met_evnet_header[MAX_MET_RTS_EVENT_NUM] = { + #ifdef MET_SSPM_RTS_EVNET + #undef MET_SSPM_RTS_EVNET + #endif + #define MET_SSPM_RTS_EVNET(rts_event_id, key_list) {rts_event_id, #rts_event_id, #rts_event_id, key_list}, + #include "met_sspm_rts_event.h" +}; + + +static void ondiemet_sspm_start(void); +static void ondiemet_sspm_stop(void); +static int ondiemet_sspm_print_help(char *buf, int len); +static int ondiemet_sspm_process_argument(const char *arg, int len); +static int ondiemet_sspm_print_header(char *buf, int len); + + +static unsigned int event_id_flag0; +static unsigned int event_id_flag1; +static unsigned int event_id_flag2; +static unsigned int event_id_flag3; +static char *update_rts_event_tbl[MAX_MET_RTS_EVENT_NUM]; +static char sspm_help[] = " --sspm_common=rts_event_name\n"; +static char header[] = "met-info [000] 0.0: sspm_common_header: "; + +struct metdevice met_sspm_common = { + .name = "sspm_common", + .owner = THIS_MODULE, + .type = MET_TYPE_BUS, + .cpu_related = 0, + .ondiemet_mode = 1, + .ondiemet_start = ondiemet_sspm_start, + .ondiemet_stop = ondiemet_sspm_stop, + .ondiemet_process_argument = ondiemet_sspm_process_argument, + .ondiemet_print_help = ondiemet_sspm_print_help, + .ondiemet_print_header = ondiemet_sspm_print_header, +}; + + +static int ondiemet_sspm_print_help(char *buf, int len) +{ + return snprintf(buf, PAGE_SIZE, sspm_help); +} + + +static int ondiemet_sspm_print_header(char *buf, int len) +{ + int i; + int write_len; + int flag = 0; + static int is_dump_header = 0; + static int read_idx = 0; + + len = 0; + met_sspm_common.header_read_again = 0; + if (is_dump_header == 0) { + len = snprintf(buf, PAGE_SIZE, "%s", header); + is_dump_header = 1; + } + + for (i=read_idx; i=32 && i < 64) { + flag = 1<<(i-32); + flag = event_id_flag1 & flag; + } else if (i >=64 && i < 96) { + flag = 1<<(i-64); + flag = event_id_flag2 & flag; + } else if (i >=96 && i < 128) { + flag = 1<<(i-96); + flag = event_id_flag3 & flag; + } + if (flag == 0) + continue; + + write_len = strlen(met_evnet_header[i].chart_line_name) + strlen(met_evnet_header[i].key_list) + 3; + if ((len+write_len) < PAGE_SIZE) { + len += snprintf(buf+len, PAGE_SIZE-len, "%u,%s,%s;", + met_evnet_header[i].rts_event_id, + met_evnet_header[i].chart_line_name, + met_evnet_header[i].key_list); + } else { + met_sspm_common.header_read_again = 1; + read_idx = i; + return len; + } + } + } + + if (i == MAX_MET_RTS_EVENT_NUM) { + is_dump_header = 0; + read_idx = 0; + buf[len-1] = '\n'; + for (i=0; i=32 && event_id < 64) { + event_id_flag1 |= 1<<(event_id-32); + ipi_buf[0] = MET_MAIN_ID | MET_ARGU | MID_COMMON<=64 && event_id < 96) { + event_id_flag2 |= 1<<(event_id-64); + ipi_buf[0] = MET_MAIN_ID | MET_ARGU | MID_COMMON<=96 && event_id < 128) { + event_id_flag3 = 1<<(event_id-96); + ipi_buf[0] |= MET_MAIN_ID | MET_ARGU | MID_COMMON<=0) + update_event_id_flag(rts_event_id); + + return 0; +} +EXPORT_SYMBOL(met_sspm_common); diff --git a/drivers/misc/mediatek/met_drv_v2/common/sspm/sspm_ipi_handle.c b/drivers/misc/mediatek/met_drv_v2/common/sspm/sspm_ipi_handle.c new file mode 100644 index 0000000000000000000000000000000000000000..67a4451de1e4badbd8a91225673790816730b7c0 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/sspm/sspm_ipi_handle.c @@ -0,0 +1,320 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +/* #include */ +#include +#include + +#include "ondiemet_sspm.h" +#include "ondiemet_log.h" +#include "interface.h" +#include "met_kernel_symbol.h" + + +#ifndef SSPM_VERSION_V2 +static struct ipi_action ondiemet_sspm_isr; +#else +#include "core_plf_init.h" +uint32_t rdata = 0; +uint32_t ridx, widx, wlen; +uint32_t ackdata = 0; +#endif +static uint32_t log_size; +static uint32_t recv_buf[4]; +static struct task_struct *ondiemet_sspm_recv_task; +static int sspm_ipi_thread_started; +int sspm_buffer_dumping; +int sspm_recv_thread_comp; + +void log_done_cb(const void *p) +{ + uint32_t ret; + uint32_t rdata = 0; + uint32_t ipi_buf[4]; + uint32_t opt = (p != NULL); + + if (opt == 0) { + ipi_buf[0] = MET_MAIN_ID | MET_RESP_AP2MD; + ipi_buf[1] = MET_DUMP_BUFFER; + ipi_buf[2] = 0; + ipi_buf[3] = 0; + ret = met_ipi_to_sspm_command((void *)ipi_buf, 0, &rdata, 1); + } +} +#ifndef SSPM_VERSION_V2 +int ondiemet_sspm_recv_thread(void *data) +{ + uint32_t rdata = 0, cmd, ret; + uint32_t ridx, widx, wlen; + + ondiemet_sspm_isr.data = (void *)recv_buf; + ret = sspm_ipi_recv_registration(IPI_ID_TST1, &ondiemet_sspm_isr); + do { + sspm_ipi_recv_wait(IPI_ID_TST1); + if (sspm_recv_thread_comp == 1) { + while (!kthread_should_stop()) + ; + return 0; + } + cmd = recv_buf[0] & MET_SUB_ID_MASK; + switch (cmd) { + case MET_DUMP_BUFFER: /* mbox 1: start index; 2: size */ + sspm_buffer_dumping = 1; + ridx = recv_buf[1]; + widx = recv_buf[2]; + log_size = recv_buf[3]; + sspm_ipi_send_ack(IPI_ID_TST1, &rdata); + if (widx < ridx) { /* wrapping occurs */ + wlen = log_size - ridx; + ondiemet_log_req_enq((char *)(ondiemet_sspm_log_virt_addr) + (ridx << 2), + wlen * 4, log_done_cb, (void *)1); + ondiemet_log_req_enq((char *)(ondiemet_sspm_log_virt_addr), + widx * 4, log_done_cb, (void *)0); + } else { + wlen = widx - ridx; + ondiemet_log_req_enq((char *)(ondiemet_sspm_log_virt_addr) + (ridx << 2), + wlen * 4, log_done_cb, (void *)0); + } + break; + case MET_CLOSE_FILE: /* no argument */ + /* do close file */ + ridx = recv_buf[1]; + widx = recv_buf[2]; + met_sspm_log_discard = recv_buf[3]; + if (widx < ridx) { /* wrapping occurs */ + wlen = log_size - ridx; + ondiemet_log_req_enq((char *)(ondiemet_sspm_log_virt_addr) + (ridx << 2), + wlen * 4, log_done_cb, (void *)1); + ondiemet_log_req_enq((char *)(ondiemet_sspm_log_virt_addr), + widx * 4, log_done_cb, (void *)1); + } else { + wlen = widx - ridx; + ondiemet_log_req_enq((char *)(ondiemet_sspm_log_virt_addr) + (ridx << 2), + wlen * 4, log_done_cb, (void *)1); + } + ret = ondiemet_log_manager_stop(); + /* pr_debug("MET_CLOSE_FILE: ret=%d log_discard=%d\n", ret, met_sspm_log_discard); */ + sspm_ipi_send_ack(IPI_ID_TST1, &rdata); + if (sspm_run_mode == SSPM_RUN_CONTINUOUS) { + /* clear the memory */ + memset_io((void *)ondiemet_sspm_log_virt_addr, 0, + ondiemet_sspm_log_size); + /* re-start ondiemet again */ + sspm_start(); + } + break; + case MET_RESP_MD2AP: + sspm_ipi_send_ack(IPI_ID_TST1, &rdata); + sspm_buffer_dumping = 0; + break; + default: + sspm_ipi_send_ack(IPI_ID_TST1, &rdata); + break; + } + } while (!kthread_should_stop()); + return 0; +} + +#else /* SSPM_VERSION_V2 */ + +int met_ipi_cb(unsigned int ipi_id, void *prdata, void *data, unsigned int len) +{ + uint32_t *cmd_buf = (uint32_t *)data; + uint32_t cmd; + int ret; + + if (sspm_recv_thread_comp == 1) + return 0; + + cmd = cmd_buf[0] & MET_SUB_ID_MASK; + switch (cmd) { + case MET_DUMP_BUFFER: /* mbox 1: start index; 2: size */ + sspm_buffer_dumping = 1; + ridx = cmd_buf[1]; + widx = cmd_buf[2]; + log_size = cmd_buf[3]; + break; + case MET_CLOSE_FILE: /* no argument */ + /* do close file */ + ridx = cmd_buf[1]; + widx = cmd_buf[2]; + met_sspm_log_discard = cmd_buf[3]; + if (widx < ridx) { /* wrapping occurs */ + wlen = log_size - ridx; + ondiemet_log_req_enq((char *)(ondiemet_sspm_log_virt_addr) + (ridx << 2), + wlen * 4, log_done_cb, (void *)1); + ondiemet_log_req_enq((char *)(ondiemet_sspm_log_virt_addr), + widx * 4, log_done_cb, (void *)1); + } else { + wlen = widx - ridx; + ondiemet_log_req_enq((char *)(ondiemet_sspm_log_virt_addr) + (ridx << 2), + wlen * 4, log_done_cb, (void *)1); + } + ret = ondiemet_log_manager_stop(); + /* pr_debug("MET_CLOSE_FILE: ret=%d log_discard=%d\n", ret, met_sspm_log_discard); */ + break; + case MET_RESP_MD2AP: + break; + default: + break; + } + return 0; +} + +int ondiemet_sspm_recv_thread(void *data) +{ + int ret; + uint32_t cmd; + + ret = mtk_ipi_register(sspm_ipidev_symbol, IPIR_C_MET, met_ipi_cb, NULL, (void *)recv_buf); + if (ret) + pr_debug("[MET] ipi_register:%d failed:%d\n", IPIR_C_MET, ret); + + do { + mtk_ipi_recv_reply(sspm_ipidev_symbol,IPIR_C_MET, (void *)&rdata, 1); + if (sspm_recv_thread_comp == 1) { + while (!kthread_should_stop()) + ; + return 0; + } + cmd = recv_buf[0] & MET_SUB_ID_MASK; + switch (cmd) { + case MET_DUMP_BUFFER: /* mbox 1: start index; 2: size */ + if (widx < ridx) { /* wrapping occurs */ + wlen = log_size - ridx; + ondiemet_log_req_enq((char *)(ondiemet_sspm_log_virt_addr) + (ridx << 2), + wlen * 4, log_done_cb, (void *)1); + ondiemet_log_req_enq((char *)(ondiemet_sspm_log_virt_addr), + widx * 4, log_done_cb, (void *)0); + } else { + wlen = widx - ridx; + ondiemet_log_req_enq((char *)(ondiemet_sspm_log_virt_addr) + (ridx << 2), + wlen * 4, log_done_cb, (void *)0); + } + break; + case MET_CLOSE_FILE: /* no argument */ + if (sspm_run_mode == SSPM_RUN_CONTINUOUS) { + /* clear the memory */ + memset_io((void *)ondiemet_sspm_log_virt_addr, 0, + ondiemet_sspm_log_size); + /* re-start ondiemet again */ + sspm_start(); + } + break; + case MET_RESP_MD2AP: + sspm_buffer_dumping = 0; + break; + default: + break; + } + } while (!kthread_should_stop()); + return 0; +} + +#endif /* SSPM_VERSION_V2 */ + + + +void start_sspm_ipi_recv_thread(void) +{ +#ifdef SSPM_VERSION_V2 + int ret; + + if(!sspm_ipidev_symbol) + return; + + ret = mtk_ipi_register(sspm_ipidev_symbol, IPIS_C_MET, NULL, NULL, (void *) &ackdata); + if (ret) + pr_debug("[MET] ipi_register:%d failed:%d\n", IPIS_C_MET, ret); +#endif + + if (sspm_ipi_thread_started != 1) { + sspm_recv_thread_comp = 0; + ondiemet_sspm_recv_task = + kthread_run(ondiemet_sspm_recv_thread, NULL, "ondiemet_sspm_recv"); + if (IS_ERR(ondiemet_sspm_recv_task)) + pr_debug("MET: Can not create ondiemet_sspm_recv\n"); + else + sspm_ipi_thread_started = 1; + } +} + +void stop_sspm_ipi_recv_thread(void) +{ + if (ondiemet_sspm_recv_task) { + sspm_recv_thread_comp = 1; +#ifndef SSPM_VERSION_V2 + sspm_ipi_recv_complete(IPI_ID_TST1); +#endif + kthread_stop(ondiemet_sspm_recv_task); + ondiemet_sspm_recv_task = NULL; + sspm_ipi_thread_started = 0; +#ifndef SSPM_VERSION_V2 + sspm_ipi_recv_unregistration(IPI_ID_TST1); +#else + mtk_ipi_unregister(sspm_ipidev_symbol, IPIR_C_MET); + mtk_ipi_unregister(sspm_ipidev_symbol, IPIS_C_MET); +#endif + } +} + +int met_ipi_to_sspm_command(void *buffer, int slot, unsigned int *retbuf, int retslot) +{ + int ret; + +#ifndef SSPM_VERSION_V2 + ret = sspm_ipi_send_sync(IPI_ID_MET, IPI_OPT_WAIT, buffer, slot, retbuf, retslot); +#else + if(!sspm_ipidev_symbol) + ret = -1; + else { + ret = mtk_ipi_send_compl(sspm_ipidev_symbol, IPIS_C_MET, IPI_SEND_WAIT, buffer, slot, 2000); + *retbuf = ackdata; + } +#endif + if (ret != 0) + pr_debug("met_ipi_to_sspm_command error(%d)\n", ret); + + return ret; +} +EXPORT_SYMBOL(met_ipi_to_sspm_command); + + +int met_ipi_to_sspm_command_async(void *buffer, int slot, unsigned int *retbuf, int retslot) +{ + int ret; + +#ifndef SSPM_VERSION_V2 + ret = sspm_ipi_send_sync(IPI_ID_MET, IPI_OPT_WAIT, buffer, slot, retbuf, retslot); +#else + if(!sspm_ipidev_symbol) + ret = -1; + else { + ret = mtk_ipi_send(sspm_ipidev_symbol, IPIS_C_MET, IPI_SEND_WAIT, buffer, slot, 2000); + *retbuf = ackdata; + } +#endif + if (ret != 0) + pr_debug("met_ipi_to_sspm_command error(%d)\n", ret); + + return ret; +} +EXPORT_SYMBOL(met_ipi_to_sspm_command_async); + + + diff --git a/drivers/misc/mediatek/met_drv_v2/common/sspm/sspm_met_smi.c b/drivers/misc/mediatek/met_drv_v2/common/sspm/sspm_met_smi.c new file mode 100644 index 0000000000000000000000000000000000000000..81fc9cf2c0c0f9b429db649729df4265337ebfcb --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/sspm/sspm_met_smi.c @@ -0,0 +1,546 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include +#include +#include +#include + +#ifdef USE_KERNEL_SYNC_WRITE_H +#include +#else +#include "sync_write.h" +#endif + +#ifdef USE_KERNEL_MTK_IO_H +#include +#else +#include "mtk_io.h" +#endif + +#include "met_drv.h" +#include "trace.h" + +#include "mtk_typedefs.h" +#include "sspm_mtk_smi.h" +#include "sspm_met_smi.h" +#include "sspm_met_smi_name.h" +#include "core_plf_trace.h" +#include "core_plf_init.h" +#include "interface.h" +#include "sspm/ondiemet_sspm.h" + +#define MET_SMI_DEBUG 1 +#define MET_SMI_BUF_SIZE 128 +#define MET_SMI_DEBUGBUF_SIZE 512 +#define NPORT_IN_PM 4 + +// SMI Encode -- Master +#ifdef SMI_MASTER_8BIT +// bit15~bit16 +#define MET_SMI_BIT_REQ_LARB 15 +// bit13~bit14 +#define MET_SMI_BIT_REQ_COMM 13 +// bit12:Parallel Mode */ +#define MET_SMI_BIT_PM 12 +// bit9~bit8:Destination */ +#define MET_SMI_BIT_DST 10 +/* bit5~bit4:Request Type */ +#define MET_SMI_BIT_REQ 8 +/* bit3~bit0:Master */ +#define MET_SMI_BIT_MASTER 0 +#else +// bit15~bit16 +#define MET_SMI_BIT_REQ_LARB 15 +// bit13~bit14 +#define MET_SMI_BIT_REQ_COMM 13 +// bit12:Parallel Mode */ +#define MET_SMI_BIT_PM 12 +// bit9~bit8:Destination */ +#define MET_SMI_BIT_DST 8 +/* bit5~bit4:Request Type */ +#define MET_SMI_BIT_REQ 4 +/* bit3~bit0:Master */ +#define MET_SMI_BIT_MASTER 0 +#endif + +// SMI Encode -- Metadata +/* bit6~bit5:RW */ +#define MET_SMI_BIT_RW 5 +/* bit4~bit0:Port */ +#define MET_SMI_BIT_PORT 0 + +/* +*declare smi: larb0-larbn: +*real define table in met_smi_name.h +*/ +/*MET_SMI_DESC_DEFINE();*/ +/**/ + +/*======================================================================*/ +/* Global variable definitions */ +/*======================================================================*/ +#define MAX_CONFIG_ARRAY_SIZE 20 +struct metdevice met_sspm_smi; +struct met_smi_conf smi_conf_array[MAX_CONFIG_ARRAY_SIZE]; +int smi_array_index; + +//static unsigned int smi_met_larb_number = SMI_LARB_NUMBER; +static int count = SMI_LARB_NUMBER + SMI_COMM_NUMBER; +static struct kobject *kobj_smi; + +/* Request type */ +static unsigned int larb_req_type = SMI_REQ_ALL; +static unsigned int comm_req_type = SMI_REQ_ALL; + +/* Parallel mode */ +static unsigned int parallel_mode; + +/* Read/Write type in parallel mode */ +static int comm_pm_rw_type[SMI_COMM_NUMBER][NPORT_IN_PM]; +/* Error message */ +static char err_msg[MET_SMI_BUF_SIZE]; +static char debug_msg[MET_SMI_DEBUGBUF_SIZE]; + +/*======================================================================*/ +/* KOBJ Declarations */ +/*======================================================================*/ +/* KOBJ: larb_req_type */ +DECLARE_KOBJ_ATTR_INT(larb_req_type, larb_req_type); + +/* KOBJ : comm_req_type */ +DECLARE_KOBJ_ATTR_INT(comm_req_type, comm_req_type); + +/* KOBJ : enable_parallel_mode */ +DECLARE_KOBJ_ATTR_INT(enable_parallel_mode, parallel_mode); + +/* KOBJ : pm_rwtypeX */ +DECLARE_KOBJ_ATTR_STR_LIST_ITEM( + pm_rwtype, + KOBJ_ITEM_LIST( + {SMI_READ_ONLY, "READ"}, + {SMI_WRITE_ONLY, "WRITE"} + ) +); +DECLARE_KOBJ_ATTR_STR_LIST(pm_rwtype1, comm_pm_rw_type[0][0], pm_rwtype); +DECLARE_KOBJ_ATTR_STR_LIST(pm_rwtype2, comm_pm_rw_type[0][1], pm_rwtype); +DECLARE_KOBJ_ATTR_STR_LIST(pm_rwtype3, comm_pm_rw_type[0][2], pm_rwtype); +DECLARE_KOBJ_ATTR_STR_LIST(pm_rwtype4, comm_pm_rw_type[0][3], pm_rwtype); + +/* KOBJ : count */ +DECLARE_KOBJ_ATTR_RO_INT(count, count); + +/* KOBJ : err_msg */ +DECLARE_KOBJ_ATTR_RO_STR(err_msg, err_msg); + +#define KOBJ_ATTR_LIST \ +do { \ + KOBJ_ATTR_ITEM(larb_req_type); \ + KOBJ_ATTR_ITEM(comm_req_type); \ + KOBJ_ATTR_ITEM(enable_parallel_mode); \ + KOBJ_ATTR_ITEM(pm_rwtype1); \ + KOBJ_ATTR_ITEM(pm_rwtype2); \ + KOBJ_ATTR_ITEM(pm_rwtype3); \ + KOBJ_ATTR_ITEM(pm_rwtype4); \ + KOBJ_ATTR_ITEM(count); \ + KOBJ_ATTR_ITEM(err_msg); \ +} while (0) + +/*======================================================================*/ +/* SMI Operations */ +/*======================================================================*/ +static void met_smi_debug(char *debug_log) +{ + MET_TRACE("%s", debug_log); +} + +static int do_smi(void) +{ + return met_sspm_smi.mode; +} + +static void smi_init_value(void) +{ + int i; + + smi_array_index = 0; + for (i = 0; i < MAX_CONFIG_ARRAY_SIZE; i++) { + smi_conf_array[i].master = 0; + smi_conf_array[i].port[0] = -1; + smi_conf_array[i].port[1] = -1; + smi_conf_array[i].port[2] = -1; + smi_conf_array[i].port[3] = -1; + smi_conf_array[i].rwtype[0] = SMI_RW_ALL; + smi_conf_array[i].rwtype[1] = SMI_RW_ALL; + smi_conf_array[i].rwtype[2] = SMI_RW_ALL; + smi_conf_array[i].rwtype[3] = SMI_RW_ALL; + smi_conf_array[i].desttype = SMI_DEST_EMI; + smi_conf_array[i].reqtype = SMI_REQ_ALL; + } +} + +static int smi_init(void) +{ + int i; + + if (smi_array_index < MAX_CONFIG_ARRAY_SIZE) { + for (i = 0; i < (smi_array_index + 1); i++) { + snprintf(debug_msg, MET_SMI_DEBUGBUF_SIZE, + "===SMI config: parallel_mode = %d, master = %d, port0 = %d, port1 = %d, port2 = %d, port3 = %d, rwtype0 = %d, rwtype1 = %d, rwtype2 = %d, rwtype3 = %d, desttype = %d, reqtype(larb) = %d, reqtype(comm) = %d\n", + parallel_mode, + smi_conf_array[i].master, + smi_conf_array[i].port[0], + smi_conf_array[i].port[1], + smi_conf_array[i].port[2], + smi_conf_array[i].port[3], + smi_conf_array[i].rwtype[0], + smi_conf_array[i].rwtype[1], + smi_conf_array[i].rwtype[2], + smi_conf_array[i].rwtype[3], + smi_conf_array[i].desttype, + smi_conf_array[i].reqtype >> MET_SMI_BIT_REQ_LARB, + smi_conf_array[i].reqtype >> MET_SMI_BIT_REQ_COMM); + met_smi_debug(debug_msg); + } + } else { + met_smi_debug("smi_init() FAIL : smi_array_index overflow\n"); + return -1; + } + + return 0; +} + +static int met_smi_create(struct kobject *parent) +{ +#define KOBJ_ATTR_ITEM(attr_name) \ +do { \ + ret = sysfs_create_file(kobj_smi, &attr_name##_attr.attr); \ + if (ret != 0) { \ + pr_debug("Failed to create " #attr_name " in sysfs\n"); \ + return ret; \ + } \ +} while (0) + + int j; + int ret = 0; + + pr_debug(" met_smi_create\n met_smi_create\n met_smi_create\n met_smi_create\n met_smi_create\n met_smi_create\n met_smi_create\n met_smi_create\n"); + + /* Init. */ + + smi_init_value(); + + larb_req_type = SMI_REQ_ALL; + comm_req_type = SMI_REQ_ALL; + parallel_mode = 0; + + for (j = 0; j < NPORT_IN_PM; j++) + comm_pm_rw_type[0][j] = SMI_READ_ONLY; + + kobj_smi = parent; + + KOBJ_ATTR_LIST; + + return ret; + +#undef KOBJ_ATTR_ITEM +} + +void met_smi_delete(void) +{ +#define KOBJ_ATTR_ITEM(attr_name) \ + sysfs_remove_file(kobj_smi, &attr_name##_attr.attr) + + + if (kobj_smi != NULL) { + KOBJ_ATTR_LIST; + kobj_smi = NULL; + } + +#undef KOBJ_ATTR_ITEM +} + +static void met_smi_start(void) +{ + if (do_smi()) { + if (smi_init() != 0) { + met_sspm_smi.mode = 0; + smi_init_value(); + return; + } + } +} + +static void met_smi_stop(void) +{ + int j; + + if (do_smi()) { + + /* Reset */ + smi_init_value(); + + larb_req_type = SMI_REQ_ALL; + comm_req_type = SMI_REQ_ALL; + parallel_mode = 0; + + for (j = 0; j < NPORT_IN_PM; j++) + comm_pm_rw_type[0][j] = SMI_READ_ONLY; + + + met_sspm_smi.mode = 0; + } + return ; +} + +static char help[] = +" --smi=master:port:rw:dest:bus monitor specified SMI banwidth\n" +" --smi=master:p1[:p2][:p3][:p4] monitor parallel mode\n"; + +static int smi_print_help(char *buf, int len) +{ + return snprintf(buf, PAGE_SIZE, "%s", help); +} + +static int get_num(const char *__restrict__ dc, int *pValue) +{ + int value = 0, digit; + int i = 0; + + while (((*dc) >= '0') && ((*dc) <= '9')) { + digit = (int)(*dc - '0'); + value = value * 10 + digit; + dc++; + i++; + } + + if (i == 0) + return 0; + *pValue = value; + + return i; +} + +/* + * There are serveal cases as follows: + * + * 1. "met-cmd --start --smi=master:port:rwtype:desttype:bustype" => Can assign multiple master + * 2. "met-cmd --start --smi=master:port[:port1][:port2][:port3]" ==> parael mode + * + */ +static int smi_process_argument(const char *__restrict__ arg, int len) +{ + int args[5]; + int i, array_index; + int idx; + unsigned int smi_conf_index = 0; + struct met_smi_conf smi_conf; + + uint32_t ipi_buf[4]; + uint32_t ret; + uint32_t rdata; + uint16_t sspm_master = 0; + uint32_t sspm_meta = 0; + + if (len < 3) + return -1; + + /*reset local config structure*/ + memset(err_msg, 0, MET_SMI_BUF_SIZE); + for (i = 0; i < 4; i++) { + smi_conf.port[i] = -1; + smi_conf.rwtype[i] = SMI_RW_ALL; + } + smi_conf.master = 0; + smi_conf.reqtype = SMI_REQ_ALL; + smi_conf.desttype = SMI_DEST_EMI; + + if (met_sspm_smi.mode != 0 && met_sspm_smi.mode != 1) + return -1; + + /* + * parse arguments + * arg[0] = master + * arg[1] = port or port1 + * arg[2] = rwtype or port2 + * arg[3] = desttype or port3 + * arg[4] = bustype or port4 + */ + for (i = 0; i < ARRAY_SIZE(args); i++) + args[i] = -1; + idx = 0; + for (i = 0; i < ARRAY_SIZE(args); i++) { + ret = get_num(&(arg[idx]), &(args[i])); + if (ret == 0) + break; + idx += ret; + if (arg[idx] != ':') + break; + idx++; + } + + pr_debug("===SMI process argu: args[0](%d), args[1](%d), args[2](%d), args[3](%d), args[4](%d)\n", + args[0], + args[1], + args[2], + args[3], + args[4]); + + /*fill local config structure*/ + smi_conf.master = args[0]; + smi_conf.reqtype = (larb_req_type << MET_SMI_BIT_REQ_LARB) | (comm_req_type << MET_SMI_BIT_REQ_COMM); + if (parallel_mode == 0) { /*legacy mode*/ + smi_conf.rwtype[0] = args[2]; + smi_conf.desttype = args[3]; + smi_conf.port[0] = args[1]; + } else { /*parallel mode*/ + smi_conf.desttype = SMI_DEST_EMI; + for (i = 0; i < 4; i++) { + if (args[i+1] < 0) + break; + smi_conf.port[i] = args[i+1]; + smi_conf.rwtype[i] = comm_pm_rw_type[0][i]; + } + } + +/*debug log to ftrace*/ +#ifdef MET_SMI_DEBUG + snprintf(debug_msg, MET_SMI_DEBUGBUF_SIZE, + "(argu)===SMI process argu Master[%d]: parallel_mode = %d, master = %d, port0 = %d, port1 = %d, port2 = %d, port3 = %d, rwtype0 = %d, rwtype1 = %d, rwtype2 = %d, rwtype3 = %d, desttype = %d, reqtype(larb) = %d, reqtype(comm) = %d\n", + args[0], + parallel_mode, + smi_conf.master, + smi_conf.port[0], + smi_conf.port[1], + smi_conf.port[2], + smi_conf.port[3], + smi_conf.rwtype[0], + smi_conf.rwtype[1], + smi_conf.rwtype[2], + smi_conf.rwtype[3], + smi_conf.desttype, + (smi_conf.reqtype >> MET_SMI_BIT_REQ_LARB) & 0x3, + (smi_conf.reqtype >> MET_SMI_BIT_REQ_COMM) & 0x3); + met_smi_debug(debug_msg); +#endif + + /*find the empty conf_array*/ + for (i = 0; i < MAX_CONFIG_ARRAY_SIZE; i++) { + if ((smi_conf_array[i].master == smi_conf.master) && (smi_conf_array[i].port[0] != -1)) + break; + } + if (i >= MAX_CONFIG_ARRAY_SIZE) { + if (smi_conf_array[0].port[0] == -1) { + smi_array_index = 0; + array_index = 0; + } else { + smi_array_index = smi_array_index + 1; + array_index = smi_array_index; + } + } else { + array_index = i; + } + + if ((smi_array_index >= MAX_CONFIG_ARRAY_SIZE) || (array_index >= MAX_CONFIG_ARRAY_SIZE)) { + snprintf(err_msg, MET_SMI_BUF_SIZE, + "===Setting Master[%d]: check smi_array_index=%d, array_index=%d overflow (> %d)\n", + args[0], smi_array_index, array_index, MAX_CONFIG_ARRAY_SIZE); + return -1; + } + + smi_conf_array[array_index].master = smi_conf.master; + + + if (parallel_mode == 0) { /* Legacy mode */ + smi_conf_array[array_index].port[0] = smi_conf.port[0]; + } else { /* Parallel mode */ + for (i = 0; i < NPORT_IN_PM; i++) { + if (smi_conf_array[array_index].port[i] == -1) + smi_conf_array[array_index].port[i] = smi_conf.port[smi_conf_index++]; + } + } + smi_conf_array[array_index].rwtype[0] = smi_conf.rwtype[0]; + smi_conf_array[array_index].rwtype[1] = smi_conf.rwtype[1]; + smi_conf_array[array_index].rwtype[2] = smi_conf.rwtype[2]; + smi_conf_array[array_index].rwtype[3] = smi_conf.rwtype[3]; + smi_conf_array[array_index].desttype = smi_conf.desttype; + smi_conf_array[array_index].reqtype = smi_conf.reqtype; + + pr_debug("===SMI process argu Master[%d]: parallel_mode = %d, master = %d, port0 = %d, port1 = %d, port2 = %d, port3 = %d, rwtype0 = %d, rwtype1 = %d, rwtype2 = %d, rwtype3 = %d, desttype = %d, reqtype(larb) = %d, reqtype(comm) = %d\n", + args[0], + parallel_mode, + smi_conf.master, + smi_conf.port[0], + smi_conf.port[1], + smi_conf.port[2], + smi_conf.port[3], + smi_conf.rwtype[0], + smi_conf.rwtype[1], + smi_conf.rwtype[2], + smi_conf.rwtype[3], + smi_conf.desttype, + (smi_conf.reqtype >> MET_SMI_BIT_REQ_LARB) & 0x3, + (smi_conf.reqtype >> MET_SMI_BIT_REQ_COMM) & 0x3); + + // Encode SMI config: Master (request format from SMI driver) + sspm_master = sspm_master | (smi_conf_array[array_index].master << MET_SMI_BIT_MASTER); + sspm_master = sspm_master | 0 << MET_SMI_BIT_REQ; //reqtype value will be update in sspm side + sspm_master = sspm_master | (smi_conf_array[array_index].desttype << MET_SMI_BIT_DST); + sspm_master = sspm_master | (parallel_mode << MET_SMI_BIT_PM); + // Extrace info for larb and comm reqestType since of unable to recognize master belong to larb or comm. + // BIT13~BIT14: comm reqtype + // BIT15~BIT16: larb reqtype + sspm_master = sspm_master | smi_conf_array[array_index].reqtype; + + + // Encode SMI config: Meta (request format from SMI driver) + // Encode 4 Metadata into 1 unsigned int + // BIT0~BIT4: port + // BIT5~BIT6: rwtype + if(parallel_mode == 0){ + sspm_meta = sspm_meta | (smi_conf_array[array_index].port[0] << MET_SMI_BIT_PORT); + sspm_meta = sspm_meta | (smi_conf_array[array_index].rwtype[0] << MET_SMI_BIT_RW); + } + else{ + for(i = 0; i < 4; i++){ + if(smi_conf_array[array_index].port[i] == 0xFFFFFFFF){ + smi_conf_array[array_index].port[i] = USHRT_MAX; + } + sspm_meta = sspm_meta | (smi_conf_array[array_index].port[i] << (MET_SMI_BIT_PORT+8*i)); + sspm_meta = sspm_meta | (smi_conf_array[array_index].rwtype[i] << (MET_SMI_BIT_RW+8*i)); + } + } + + // Transfer to SSPM side + if (sspm_buf_available == 1) + { + ipi_buf[0] = MET_MAIN_ID | MET_ARGU | MID_SMI << MID_BIT_SHIFT | 1; + ipi_buf[1] = sspm_master; + ipi_buf[2] = sspm_meta; + ipi_buf[3] = 0; + ret = met_ipi_to_sspm_command((void *)ipi_buf, 0, &rdata, 1); + + /* Set mode */ + met_sspm_smi.mode = 1; + ondiemet_module[ONDIEMET_SSPM] |= ID_SMI; + } + + return 0; +} + +struct metdevice met_sspm_smi = { + .name = "smi", + .owner = THIS_MODULE, + .type = MET_TYPE_BUS, + .create_subfs = met_smi_create, + .delete_subfs = met_smi_delete, + .cpu_related = 0, + .ondiemet_mode = 1, + .ondiemet_start = met_smi_start, + .ondiemet_stop = met_smi_stop, + .ondiemet_process_argument = smi_process_argument, + .ondiemet_print_help = smi_print_help, +}; + diff --git a/drivers/misc/mediatek/met_drv_v2/common/sspm/sspm_met_smi.h b/drivers/misc/mediatek/met_drv_v2/common/sspm/sspm_met_smi.h new file mode 100644 index 0000000000000000000000000000000000000000..f51ac6c68c904aa88401a7aadff7b1dab8d871f7 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/sspm/sspm_met_smi.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef _SMI_H_ +#define _SMI_H_ + +#include + +struct met_smi { + int mode; + int master; + unsigned int port; + unsigned int rwtype; /* 0 for R+W, 1 for read, 2 for write */ + unsigned int desttype; /* 0 for EMI+internal mem, 1 for EMI, 3 for internal mem */ + unsigned int bustype; /* 0 for GMC, 1 for AXI */ + /* unsigned long requesttype;// 0:All, 1:ultra high, 2:pre-ultrahigh, 3:normal. */ + struct kobject *kobj_bus_smi; +}; + +struct smi_cfg { + int master; + unsigned int port; + unsigned int rwtype; /* 0 for R+W, 1 for read, 2 for write */ + unsigned int desttype; /* 0 for EMI+internal mem, 1 for EMI, 3 for internal mem */ + unsigned int bustype; /*0 for GMC, 1 for AXI */ + /*unsigned long requesttype;// 0:All, 1:ultra high, 2:pre-ultrahigh, 3:normal. */ +}; + +struct smi_mon_con { + unsigned int requesttype; /* 0:All, 1:ultra high, 2:pre-ultrahigh, 3:normal. */ +}; + +/* ====================== SMI/EMI Interface ================================ */ + +struct met_smi_conf { + unsigned int master; /*Ex : Whitney: 0~8 for larb0~larb8, 9 for common larb*/ + int port[4]; /* port select : [0] only for legacy mode, [0~3] ports for parallel mode, -1 no select*/ + unsigned int reqtype; /* Selects request type : 0 for all,1 for ultra,2 for preultra,3 for normal*/ + unsigned int rwtype[4]; /* Selects read/write: 0 for R+W, 1 for read, 2 for write;*/ + /* [0] for legacy and parallel larb0~8, [0~3] for parallel mode common*/ + unsigned int desttype; /* Selects destination: 0 and 3 for all memory, 1 for External,2 for internal*/ +}; + +#endif /* _SMI_H_ */ diff --git a/drivers/misc/mediatek/met_drv_v2/common/sspm/sspm_met_smi_name.h b/drivers/misc/mediatek/met_drv_v2/common/sspm/sspm_met_smi_name.h new file mode 100644 index 0000000000000000000000000000000000000000..c620ca00c03797bf3ce83c6f515e440ccdf19d63 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/sspm/sspm_met_smi_name.h @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef _SMI_NAME_H_ +#define _SMI_NAME_H_ +/* #include "mtk_smi.h" */ + +enum SMI_DEST { + SMI_DEST_ALL = 0, + SMI_DEST_EMI = 1, + SMI_DEST_INTERNAL = 2, + SMI_DEST_NONE = 9 +}; + +enum SMI_RW { + SMI_RW_ALL = 0, + SMI_READ_ONLY = 1, + SMI_WRITE_ONLY = 2, + SMI_RW_RESPECTIVE = 3, + SMI_RW_NONE = 9 +}; + +enum SMI_BUS { + SMI_BUS_GMC = 0, + SMI_BUS_AXI = 1, + SMI_BUS_NONE = 9 +}; + +enum SMI_REQUEST { + SMI_REQ_ALL = 0, + SMI_REQ_ULTRA = 1, + SMI_REQ_PREULTRA = 2, + SMI_NORMAL_ULTRA = 3, + SMI_REQ_NONE = 9 +}; + +struct smi_desc { + unsigned long port; + enum SMI_DEST desttype; + enum SMI_RW rwtype; + enum SMI_BUS bustype; +}; +#endif /* _SMI_NAME_H_ */ diff --git a/drivers/misc/mediatek/met_drv_v2/common/sspm/sspm_mtk_smi.h b/drivers/misc/mediatek/met_drv_v2/common/sspm/sspm_mtk_smi.h new file mode 100644 index 0000000000000000000000000000000000000000..68161a84280f1f0fbe3e375606fe88ea3684bc8c --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/sspm/sspm_mtk_smi.h @@ -0,0 +1,125 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef __MT_SMI_H__ +#define __MT_SMI_H__ + +/* the default value, but the real number will get from symbol function*/ +#define SMI_LARB_NUMBER 9 +#define SMI_COMM_NUMBER 1 +#define SMI_LARB_MONITOR_NUMBER 1 +#define SMI_COMM_MONITOR_NUMBER 1 + +#define SMI_REQ_OK (0) +#define SMI_ERR_WRONG_REQ (-1) +#define SMI_ERR_OVERRUN (-2) + +#define SMI_IOMEM_ADDR(b, off) ((void __iomem *)(((unsigned long)b)+off)) + +#define SMI_LARB_MON_ENA(b) SMI_IOMEM_ADDR((b), 0x400) +#define SMI_LARB_MON_CLR(b) SMI_IOMEM_ADDR((b), 0x404) +#define SMI_LARB_MON_PORT(b) SMI_IOMEM_ADDR((b), 0x408) +#define SMI_LARB_MON_CON(b) SMI_IOMEM_ADDR((b), 0x40C) + +#define SMI_LARB_MON_ACT_CNT(b) SMI_IOMEM_ADDR((b), 0x410) +#define SMI_LARB_MON_REQ_CNT(b) SMI_IOMEM_ADDR((b), 0x414) +#define SMI_LARB_MON_BEA_CNT(b) SMI_IOMEM_ADDR((b), 0x418) +#define SMI_LARB_MON_BYT_CNT(b) SMI_IOMEM_ADDR((b), 0x41C) +#define SMI_LARB_MON_CP_CNT(b) SMI_IOMEM_ADDR((b), 0x420) +#define SMI_LARB_MON_DP_CNT(b) SMI_IOMEM_ADDR((b), 0x424) +#define SMI_LARB_MON_OSTD_CNT(b) SMI_IOMEM_ADDR((b), 0x428) +#define SMI_LARB_MON_CP_MAX(b) SMI_IOMEM_ADDR((b), 0x430) +#define SMI_LARB_MON_OSTD_MAX(b) SMI_IOMEM_ADDR((b), 0x434) + +#define SMI_COMM_MON_ENA(b) SMI_IOMEM_ADDR((b), 0x1A0) +#define SMI_COMM_MON_CLR(b) SMI_IOMEM_ADDR((b), 0x1A4) +#define SMI_COMM_MON_TYPE(b) SMI_IOMEM_ADDR((b), 0x1AC) +#define SMI_COMM_MON_CON(b) SMI_IOMEM_ADDR((b), 0x1B0) +#define SMI_COMM_MON_ACT_CNT(b) SMI_IOMEM_ADDR((b), 0x1C0) +#define SMI_COMM_MON_REQ_CNT(b) SMI_IOMEM_ADDR((b), 0x1C4) +#define SMI_COMM_MON_OSTD_CNT(b) SMI_IOMEM_ADDR((b), 0x1C8) +#define SMI_COMM_MON_BEA_CNT(b) SMI_IOMEM_ADDR((b), 0x1CC) +#define SMI_COMM_MON_BYT_CNT(b) SMI_IOMEM_ADDR((b), 0x1D0) +#define SMI_COMM_MON_CP_CNT(b) SMI_IOMEM_ADDR((b), 0x1D4) +#define SMI_COMM_MON_DP_CNT(b) SMI_IOMEM_ADDR((b), 0x1D8) +#define SMI_COMM_MON_CP_MAX(b) SMI_IOMEM_ADDR((b), 0x1DC) +#define SMI_COMM_MON_OSTD_MAX(b) SMI_IOMEM_ADDR((b), 0x1E0) + + +/*ondiemet smi ipi command*/ +enum MET_SMI_IPI_Type { + SMI_DRIVER_INITIAL_VALUE = 0x0, + SMI_DRIVER_RESET_VALUE, + SET_BASE_SMI, + SMI_ASSIGN_PORT_START, + SMI_ASSIGN_PORT_I, + SMI_ASSIGN_PORT_II, + SMI_ASSIGN_PORT_III, + SMI_ASSIGN_PORT_END, +}; + + + + +void MET_SMI_IPI_baseaddr(void); +int MET_SMI_Init(void); +void MET_SMI_Fini(void); +void MET_SMI_Enable(int larbno); +void MET_SMI_Disable(int larbno); +void MET_SMI_Pause(int larbno); +void MET_SMI_Clear(int larbno); +int MET_SMI_PowerOn(unsigned int master); +void MET_SMI_PowerOff(unsigned int master); +int MET_SMI_LARB_SetCfg(int larbno, + unsigned int pm, + unsigned int reqtype, unsigned int rwtype, unsigned int dsttype); +int MET_SMI_LARB_SetPortNo(int larbno, unsigned int idx, unsigned int port); +int MET_SMI_COMM_SetCfg(int commonno, unsigned int pm, unsigned int reqtype); +int MET_SMI_COMM_SetPortNo(int commonno, unsigned int idx, unsigned int port); +int MET_SMI_COMM_SetRWType(int commonno, unsigned int idx, unsigned int rw); + +/* config */ +int MET_SMI_GetEna(int larbno); +int MET_SMI_GetClr(int larbno); +int MET_SMI_GetPortNo(int larbno); +int MET_SMI_GetCon(int larbno); + +/* cnt */ +int MET_SMI_GetActiveCnt(int larbno); +int MET_SMI_GetRequestCnt(int larbno); +int MET_SMI_GetBeatCnt(int larbno); +int MET_SMI_GetByteCnt(int larbno); +int MET_SMI_GetCPCnt(int larbno); +int MET_SMI_GetDPCnt(int larbno); +int MET_SMI_GetOSTDCnt(int larbno); +int MET_SMI_GetCP_MAX(int larbno); +int MET_SMI_GetOSTD_MAX(int larbno); + +/* common */ +void MET_SMI_Comm_Init(void); +void MET_SMI_Comm_Enable(int commonno); +void MET_SMI_Comm_Disable(int commonno); +void MET_SMI_Pause(int commonno); +void MET_SMI_Comm_Clear(int commonno); + +/* common config */ +int MET_SMI_Comm_GetEna(int commonno); +int MET_SMI_Comm_GetClr(int commonno); +int MET_SMI_Comm_GetType(int commonno); +int MET_SMI_Comm_GetCon(int commonno); + +/* cnt */ +int MET_SMI_Comm_GetPortNo(int commonno); +int MET_SMI_Comm_GetActiveCnt(int commonno); +int MET_SMI_Comm_GetRequestCnt(int commonno); +int MET_SMI_Comm_GetBeatCnt(int commonno); +int MET_SMI_Comm_GetByteCnt(int commonno); +int MET_SMI_Comm_GetCPCnt(int commonno); +int MET_SMI_Comm_GetDPCnt(int commonno); +int MET_SMI_Comm_GetOSTDCnt(int commonno); +int MET_SMI_Comm_GetCP_MAX(int commonno); +int MET_SMI_Comm_GetOSTD_MAX(int commonno); + +#endif /* __MT_SMI_H__ */ diff --git a/drivers/misc/mediatek/met_drv_v2/common/sspm/sspm_walltime.c b/drivers/misc/mediatek/met_drv_v2/common/sspm/sspm_walltime.c new file mode 100644 index 0000000000000000000000000000000000000000..83cfd90ea4014178a03ea532c14a972427d6a424 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/sspm/sspm_walltime.c @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include +#include +#include +#include +#include + +#include "met_drv.h" +#include "trace.h" +/* #include "plf_init.h" */ +#include "sspm/ondiemet_sspm.h" + +static void sspm_walltime_start(void) +{ + ondiemet_module[ONDIEMET_SSPM] |= ID_WALL_TIME; +} + +static void sspm_walltime_stop(void) +{ +} + +static const char sspm_walltime_header[] = "met-info [000] 0.0: sspm WCLK: freq\n"; + +static int sspm_walltime_print_header(char *buf, int len) +{ + return snprintf(buf, PAGE_SIZE, sspm_walltime_header); +} + +struct metdevice met_sspm_walltime = { + .name = "sspm_wall_time", + .owner = THIS_MODULE, + .type = MET_TYPE_BUS, + .cpu_related = 0, + .ondiemet_mode = 0, + .print_header = sspm_walltime_print_header, + .ondiemet_start = sspm_walltime_start, + .ondiemet_stop = sspm_walltime_stop, + .ondiemet_print_header = sspm_walltime_print_header, +}; +EXPORT_SYMBOL(met_sspm_walltime); diff --git a/drivers/misc/mediatek/met_drv_v2/common/stat.c b/drivers/misc/mediatek/met_drv_v2/common/stat.c new file mode 100644 index 0000000000000000000000000000000000000000..22817e4945cf39b9c77915ac805dadaef3d46b74 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/stat.c @@ -0,0 +1,190 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include +#include +/* #include */ +#include +#include +#include +#include +/* #include */ +#include +/* #include */ +/* #include */ +#include +#include +#include +/* #include */ +/* #include */ +#include +#include + +#include +#include + +#include "stat.h" +#include "met_drv.h" +#include "trace.h" + +#define MS_STAT_FMT "%5lu.%06lu" +#define FMTLX7 ",%llx,%llx,%llx,%llx,%llx,%llx,%llx\n" +#define FMTLX10 ",%llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n" + + +static DEFINE_PER_CPU(int, cpu_status); + + +/* void ms_st(unsigned long long timestamp, unsigned char cnt, unsigned int *value) */ +noinline void ms_st(unsigned long long timestamp, unsigned char cnt, u64 *value) +{ + unsigned long nano_rem = do_div(timestamp, 1000000000); + + switch (cnt) { + case 10: + MET_TRACE(MS_STAT_FMT FMTLX10, (unsigned long)(timestamp), (nano_rem/1000), + value[0], value[1], value[2], value[3], value[4], + value[5], value[6], value[7], value[8], value[9]); + break; + case 7: + MET_TRACE(MS_STAT_FMT FMTLX7, (unsigned long)(timestamp), (nano_rem/1000), + value[0], value[1], value[2], value[3], value[4], + value[5], value[6]); + break; + } +} + +static void met_stat_start(void) +{ + int cpu = raw_smp_processor_id(); + + if (get_ctrl_flags() & 1) + met_stat.mode = 0; + + per_cpu(cpu_status, cpu) = MET_CPU_ONLINE; +} + +static void met_stat_stop(void) +{ +} + +static int do_stat(void) +{ + return met_stat.mode; +} + +u64 met_usecs_to_cputime64(u64 n) +{ +#if (NSEC_PER_SEC % HZ) == 0 + /* Common case, HZ = 100, 128, 200, 250, 256, 500, 512, 1000 etc. */ + return div_u64(n, NSEC_PER_SEC / HZ); +#elif (HZ % 512) == 0 + /* overflow after 292 years if HZ = 1024 */ + return div_u64(n * HZ / 512, NSEC_PER_SEC / 512); +#else + /* + * Generic case - optimized for cases where HZ is a multiple of 3. + * overflow after 64.99 years, exact for HZ = 60, 72, 90, 120 etc. + */ + return div_u64(n * 9, (9ull * NSEC_PER_SEC + HZ / 2) / HZ); +#endif +} + +static u64 get_idle_time(int cpu) +{ + u64 idle, idle_time = get_cpu_idle_time_us(cpu, NULL); + + if (idle_time == -1ULL) { + /* !NO_HZ so we can rely on cpustat.idle */ + idle = kcpustat_cpu(cpu).cpustat[CPUTIME_IDLE]; + } else + idle = met_usecs_to_cputime64(idle_time); + + return idle; +} + +static u64 get_iowait_time(int cpu) +{ + u64 iowait, iowait_time = get_cpu_iowait_time_us(cpu, NULL); + + if (iowait_time == -1ULL) { + /* !NO_HZ so we can rely on cpustat.iowait */ + iowait = kcpustat_cpu(cpu).cpustat[CPUTIME_IOWAIT]; + } else + iowait = met_usecs_to_cputime64(iowait_time); + + return iowait; +} + + +static unsigned int stat_os_polling(u64 *value, int i) +{ + int j = -1; + + /* Copy values here to work around gcc-2.95.3, gcc-2.96 */ + value[++j] = jiffies_64_to_clock_t(kcpustat_cpu(i).cpustat[CPUTIME_USER]); /* user */ + value[++j] = jiffies_64_to_clock_t(kcpustat_cpu(i).cpustat[CPUTIME_NICE]); /* nice */ + value[++j] = jiffies_64_to_clock_t(kcpustat_cpu(i).cpustat[CPUTIME_SYSTEM]); /* system */ + value[++j] = jiffies_64_to_clock_t(get_idle_time(i)); /* idle */ + value[++j] = jiffies_64_to_clock_t(get_iowait_time(i)); /* iowait */ + value[++j] = jiffies_64_to_clock_t(kcpustat_cpu(i).cpustat[CPUTIME_IRQ]); /* irq */ + value[++j] = jiffies_64_to_clock_t(kcpustat_cpu(i).cpustat[CPUTIME_SOFTIRQ]); /* softirq */ + value[++j] = jiffies_64_to_clock_t(kcpustat_cpu(i).cpustat[CPUTIME_STEAL]); /* steal */ + value[++j] = jiffies_64_to_clock_t(kcpustat_cpu(i).cpustat[CPUTIME_GUEST]); /* guest */ + value[++j] = jiffies_64_to_clock_t(kcpustat_cpu(i).cpustat[CPUTIME_GUEST_NICE]); /* guest_nice */ + + return j + 1; +} + +static void met_stat_polling(unsigned long long stamp, int cpu) +{ + unsigned char count; + u64 value[10] = {0}; + + if (per_cpu(cpu_status, cpu) != MET_CPU_ONLINE) + return; + + /* return; */ + if (do_stat()) { + count = stat_os_polling(value, cpu); + if (count) + ms_st(stamp, count, value); + } +} + +static const char header[] = + "met-info [000] 0.0: met_st_header: user,nice,system,idle,iowait,irq,softirq,steal,guest,guest_nice\n"; + +static const char help[] = " --stat monitor stat\n"; + + +static int met_stat_print_help(char *buf, int len) +{ + return snprintf(buf, PAGE_SIZE, help); +} + +static int met_stat_print_header(char *buf, int len) +{ + return snprintf(buf, PAGE_SIZE, header); +} + +static void met_stat_cpu_state_notify(long cpu, unsigned long action) +{ + per_cpu(cpu_status, cpu) = action; +} + + +struct metdevice met_stat = { + .name = "stat", + .type = MET_TYPE_PMU, + .cpu_related = 1, + .start = met_stat_start, + .stop = met_stat_stop, + .polling_interval = 30, + .timed_polling = met_stat_polling, + .print_help = met_stat_print_help, + .print_header = met_stat_print_header, + .cpu_state_notify = met_stat_cpu_state_notify, +}; diff --git a/drivers/misc/mediatek/met_drv_v2/common/stat.h b/drivers/misc/mediatek/met_drv_v2/common/stat.h new file mode 100644 index 0000000000000000000000000000000000000000..b56c5e1903733fe1e11ce6e0ce931498afb15c6e --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/stat.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef _STAT_H_ +#define _STAT_H_ + +#include + +extern struct metdevice met_stat; + +int stat_reg(struct kobject *parent); +void stat_unreg(void); + +void stat_start(void); +void stat_stop(void); +void stat_polling(unsigned long long stamp, int cpu); + +unsigned int get_ctrl_flags(void); + +#endif /* _STAT_H_ */ diff --git a/drivers/misc/mediatek/met_drv_v2/common/switch.c b/drivers/misc/mediatek/met_drv_v2/common/switch.c new file mode 100644 index 0000000000000000000000000000000000000000..037cd9b9e293b9e8aa5c23580a9aec7a260393e3 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/switch.c @@ -0,0 +1,294 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +/* include */ +#include +#include +#include +#include + +#include "interface.h" +#include "met_drv.h" +#include "cpu_pmu.h" +#include "switch.h" +#include "sampler.h" +#include "met_kernel_symbol.h" +/* #include "trace.h" */ + +/* + * IRQ_TIRGGER and CPU_IDLE_TRIGGER + */ +/* #define IRQ_TRIGGER */ +/* #define CPU_IDLE_TRIGGER */ + +static DEFINE_PER_CPU(unsigned int, first_log); + +#ifdef __aarch64__ +/* #include */ +#include +#endif + +noinline void mt_switch(struct task_struct *prev, struct task_struct *next) +{ + int cpu; + int prev_state = 0, next_state = 0; + +#ifdef __aarch64__ + prev_state = !(is_compat_thread(task_thread_info(prev))); + next_state = !(is_compat_thread(task_thread_info(next))); +#endif + + cpu = smp_processor_id(); + if (per_cpu(first_log, cpu)) { + MET_TRACE("%d, %d, %d, %d\n", prev->pid, prev_state, next->pid, next_state); + per_cpu(first_log, cpu) = 0; + } + else if (prev_state != next_state) + MET_TRACE("%d, %d, %d, %d\n", prev->pid, prev_state, next->pid, next_state); +} + + +#if 0 /* move to kernel space */ +MET_DEFINE_PROBE(sched_switch, + TP_PROTO(bool preempt, struct task_struct *prev, struct task_struct *next)) +{ + /* speedup sched_switch callback handle */ + if (met_switch.mode == 0) + return; + + if (met_switch.mode & MT_SWITCH_EVENT_TIMER) + met_event_timer_notify(); + + if (met_switch.mode & MT_SWITCH_64_32BIT) + mt_switch(prev, next); + + if (met_switch.mode & MT_SWITCH_SCHEDSWITCH) { + if (get_pmu_profiling_version() == 1) + cpupmu_polling(0, smp_processor_id()); +#ifdef MET_SUPPORT_CPUPMU_V2 + else if (get_pmu_profiling_version() == 2) + cpupmu_polling_v2(0, smp_processor_id()); +#endif + } +} +#endif + +void met_sched_switch(struct task_struct *prev, struct task_struct *next) +{ + /* speedup sched_switch callback handle */ + if (met_switch.mode == 0) + return; + + if (met_switch.mode & MT_SWITCH_EVENT_TIMER) + met_event_timer_notify(); + + if (met_switch.mode & MT_SWITCH_64_32BIT) + mt_switch(prev, next); + + /* met_perf_cpupmu_status: 0: stop, others: polling */ + if ((met_switch.mode & MT_SWITCH_SCHEDSWITCH) && met_perf_cpupmu_status) + met_perf_cpupmu_polling(0, smp_processor_id()); +} + +#ifdef IRQ_TRIGGER +MET_DEFINE_PROBE(irq_handler_entry, TP_PROTO(int irq, struct irqaction *action)) +{ + if (met_switch.mode & MT_SWITCH_EVENT_TIMER) { + met_event_timer_notify(); + return; + } +} +#endif + +#ifdef CPU_IDLE_TRIGGER +MET_DEFINE_PROBE(cpu_idle, TP_PROTO(unsigned int state, unsigned int cpu_id)) +{ + if (met_switch.mode & MT_SWITCH_EVENT_TIMER) { + met_event_timer_notify(); + return; + } +} +#endif + +#ifdef MET_ANYTIME +/* + * create related subfs file node + */ + +static ssize_t default_on_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "1\n"); +} + +static struct kobj_attribute default_on_attr = __ATTR(default_on, 0664, default_on_show, NULL); +static struct kobject *kobj_cpu; +#endif + +static int met_switch_create_subfs(struct kobject *parent) +{ + int ret = 0; + + /* register tracepoints */ +#if 0 + if (MET_REGISTER_TRACE(sched_switch)) { + pr_debug("can not register callback of sched_switch\n"); + return -ENODEV; + } +#else + if (met_export_api_symbol->met_reg_switch) + ret = met_export_api_symbol->met_reg_switch(); +#endif +#ifdef CPU_IDLE_TRIGGER + if (MET_REGISTER_TRACE(cpu_idle)) { + pr_debug("can not register callback of irq_handler_entry\n"); + return -ENODEV; + } +#endif +#ifdef IRQ_TRIGGER + if (MET_REGISTER_TRACE(irq_handler_entry)) { + pr_debug("can not register callback of irq_handler_entry\n"); + return -ENODEV; + } +#endif + +#ifdef MET_ANYTIME + /* + * to create default_on file node + * let user space can know we can support MET default on + */ + kobj_cpu = parent; + ret = sysfs_create_file(kobj_cpu, &default_on_attr.attr); + if (ret != 0) { + pr_debug("Failed to create default_on in sysfs\n"); + return -1; + } +#endif + + return ret; +} + + +static void met_switch_delete_subfs(void) +{ +#ifdef MET_ANYTIME + if (kobj_cpu != NULL) { + sysfs_remove_file(kobj_cpu, &default_on_attr.attr); + kobj_cpu = NULL; + } +#endif +#ifdef IRQ_TRIGGER + MET_UNREGISTER_TRACE(irq_handler_entry); +#endif +#ifdef CPU_IDLE_TRIGGER + MET_UNREGISTER_TRACE(cpu_idle); +#endif +#if 0 + MET_UNREGISTER_TRACE(sched_switch); +#else + if (met_export_api_symbol->met_unreg_switch) + met_export_api_symbol->met_unreg_switch(); +#endif + +} + + +static void (*cpu_timed_polling)(unsigned long long stamp, int cpu); +/* static void (*cpu_tagged_polling)(unsigned long long stamp, int cpu); */ + +static void met_switch_start(void) +{ + int cpu; + + if (met_switch.mode & MT_SWITCH_SCHEDSWITCH) { + cpu_timed_polling = met_cpupmu.timed_polling; + /* cpu_tagged_polling = met_cpupmu.tagged_polling; */ + met_cpupmu.timed_polling = NULL; + /* met_cpupmu.tagged_polling = NULL; */ + } + + for_each_possible_cpu(cpu) { + per_cpu(first_log, cpu) = 1; + } + +} + + +static void met_switch_stop(void) +{ + int cpu; + + if (met_switch.mode & MT_SWITCH_SCHEDSWITCH) { + met_cpupmu.timed_polling = cpu_timed_polling; + /* met_cpupmu.tagged_polling = cpu_tagged_polling; */ + } + + for_each_possible_cpu(cpu) { + per_cpu(first_log, cpu) = 0; + } + +} + + +static int met_switch_process_argument(const char *arg, int len) +{ + unsigned int value; + /*ex: mxitem is 0x0005, max value should be (5-1) + (5-2) = 0x100 + 0x11 = 7 */ + unsigned int max_value = ((MT_SWITCH_MX_ITEM * 2) - 3); + + + if (met_parse_num(arg, &value, len) < 0) + goto arg_switch_exit; + + if ((value < 1) || (value > max_value)) + goto arg_switch_exit; + + met_switch.mode = value; + return 0; + +arg_switch_exit: + met_switch.mode = 0; + return -EINVAL; +} + +static const char header[] = + "met-info [000] 0.0: met_switch_header: prev_pid,prev_state,next_pid,next_state\n"; + +static const char help[] = +" --switch=mode mode:0x1 - output CPUPMU whenever sched_switch\n" +" mode:0x2 - output Aarch 32/64 state whenever state changed (no CPUPMU)\n" +" mode:0x4 - force output count at tag_start/tag_end\n" +" mode:0x8 - task switch timer\n" +" mode:0xF - mode 0x1 + 0x2 + 04 + 08\n"; + +static int met_switch_print_help(char *buf, int len) +{ + return snprintf(buf, PAGE_SIZE, help); +} + +static int met_switch_print_header(char *buf, int len) +{ + int ret = 0; + + ret = + snprintf(buf, PAGE_SIZE, "met-info [000] 0.0: mp_cpu_switch_base: %d\n", + met_switch.mode); + if (met_switch.mode & MT_SWITCH_64_32BIT) + ret += snprintf(buf + ret, PAGE_SIZE, header); + + return ret; +} + + +struct metdevice met_switch = { + .name = "switch", + .type = MET_TYPE_PMU, + .create_subfs = met_switch_create_subfs, + .delete_subfs = met_switch_delete_subfs, + .start = met_switch_start, + .stop = met_switch_stop, + .process_argument = met_switch_process_argument, + .print_help = met_switch_print_help, + .print_header = met_switch_print_header, +}; diff --git a/drivers/misc/mediatek/met_drv_v2/common/switch.h b/drivers/misc/mediatek/met_drv_v2/common/switch.h new file mode 100644 index 0000000000000000000000000000000000000000..3446df7de02737454625437ffa17553edc96b8b1 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/switch.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef __MT_SWITCH__ +#define __MT_SWITCH__ +/* + * ========================= + * !!!!!!!!!!!NOTICE!!!!!!!! + * ========================= + * MT_SWITCH OPTION must delcare as Mask value + * And sort them from smallest to largest + * MT_SWITCH_MX_ITEM was used to determine argument range +*/ +enum { + /* =================== */ + /* user define mt switch event */ + /* =================== */ + MT_SWITCH_SCHEDSWITCH = 0x0001, + MT_SWITCH_64_32BIT = 0x0002, + MT_SWITCH_TAGPOLLING = 0x0004, + MT_SWITCH_EVENT_TIMER = 0x0008, + /* =================== */ + MT_SWITCH_MX_ITEM +}; + +extern struct metdevice met_switch; +#endif diff --git a/drivers/misc/mediatek/met_drv_v2/common/sync_write.h b/drivers/misc/mediatek/met_drv_v2/common/sync_write.h new file mode 100644 index 0000000000000000000000000000000000000000..0bcac7d9b198d5b905e693ca600da8214347dcd2 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/sync_write.h @@ -0,0 +1,80 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef MT_SYNC_WRITE_H +#define MT_SYNC_WRITE_H + +#if defined(__KERNEL__) + +#include +#include + +/* + * Define macros. + */ +#define mt_reg_sync_writel(v, a) \ + do { \ + __raw_writel((v), (void __force __iomem *)((a))); \ + dsb(sy); \ + } while (0) + +#define mt_reg_sync_writew(v, a) \ + do { \ + __raw_writew((v), (void __force __iomem *)((a))); \ + dsb(sy); \ + } while (0) + +#define mt_reg_sync_writeb(v, a) \ + do { \ + __raw_writeb((v), (void __force __iomem *)((a))); \ + dsb(sy); \ + } while (0) + +#if IS_ENABLED(CONFIG_64BIT) +#define mt_reg_sync_writeq(v, a) \ + do { \ + __raw_writeq((v), (void __force __iomem *)((a))); \ + dsb(sy); \ + } while (0) +#endif + +#else /* __KERNEL__ */ + +#include +#include +#include +#include +#include + +#define mt_reg_sync_writel(v, a) mt65xx_reg_sync_writel(v, a) +#define mt_reg_sync_writew(v, a) mt65xx_reg_sync_writew(v, a) +#define mt_reg_sync_writeb(v, a) mt65xx_reg_sync_writeb(v, a) + +#define dsb() \ + { \ + __asm__ __volatile__("dsb sy" : : : "memory"); \ + } + +#define mt65xx_reg_sync_writel(v, a) \ + do { \ + *(volatile unsigned int *)(a) = (v); \ + dsb(); \ + } while (0) + +#define mt65xx_reg_sync_writew(v, a) \ + do { \ + *(volatile unsigned short *)(a) = (v); \ + dsb(); \ + } while (0) + +#define mt65xx_reg_sync_writeb(v, a) \ + do { \ + *(volatile unsigned char *)(a) = (v); \ + dsb(); \ + } while (0) + +#endif /* __KERNEL__ */ + +#endif /* !MT_SYNC_WRITE_H */ diff --git a/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/mcupm/mcupm_met.c b/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/mcupm/mcupm_met.c new file mode 100644 index 0000000000000000000000000000000000000000..0f9f6763eb1edd4bf93e784849abeb27124dde40 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/mcupm/mcupm_met.c @@ -0,0 +1,238 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ +/***************************************************************************** + * headers + *****************************************************************************/ +#include +#include /* for symbol_get */ +#include /* for of_find_node_by_name */ + +#include "met_drv.h" /* for metdevice */ +#include "interface.h" /* for PR_BOOTMSG */ +#include "tinysys_mcupm.h" +#include "tinysys_mgr.h" /* for ondiemet_module */ +#include "mcupm_met_log.h" /* for mcupm_buffer_size */ + + +/***************************************************************************** + * define declaration + *****************************************************************************/ +#define MCUPM_CPU_PMU_HEADER_LEN 1536 + + +/***************************************************************************** + * struct & enum declaration + *****************************************************************************/ + + +/***************************************************************************** + * external function declaration + *****************************************************************************/ +void mcupm_process_argument_real(const char *arg); +int mcupm_print_header_real(char *buf, int len, int cnt); + + +/***************************************************************************** + * internal function declaration + *****************************************************************************/ +static void _mcupm_start(void); +static void _mcupm_stop(void); +static int _mcupm_process_argument(const char *arg, int len); +static int _mcupm_print_help(char *buf, int len); +static int _mcupm_print_header(char *buf, int len); +static void generate_mcupm_cpu_pmu_header(void); + + +/***************************************************************************** + * external variable declaration + *****************************************************************************/ +struct metdevice met_mcupm = { + .name = "mcupm", + .owner = THIS_MODULE, + .type = MET_TYPE_MISC, + .cpu_related = 0, + .ondiemet_mode = 1, + .ondiemet_start = _mcupm_start, + .ondiemet_stop = _mcupm_stop, + .ondiemet_process_argument = _mcupm_process_argument, + .ondiemet_print_help = _mcupm_print_help, + .ondiemet_print_header = _mcupm_print_header, +}; +EXPORT_SYMBOL(met_mcupm); + + +/***************************************************************************** + * internal variable declaration + *****************************************************************************/ +static const char help[] = "--mcupm=module_name\n"; +static const char header[] = "met-info [000] 0.0: mcupm_header: "; +static char mcupm_cpu_pmu_header[MCUPM_CPU_PMU_HEADER_LEN] = ""; + + +/***************************************************************************** + * external function implement + *****************************************************************************/ +void notify_mcupm_cpu_pmu(int flag) +{ + if (flag == 1) { + ondiemet_module[ONDIEMET_MCUPM] |= (0x1 << MID_MCUPM_CPU_PMU); + } else { + ondiemet_module[ONDIEMET_MCUPM] &= ~(0x1 << MID_MCUPM_CPU_PMU); + } +} + + +/***************************************************************************** + * internal function implement + *****************************************************************************/ +static void _mcupm_start(void) +{ + if (mcupm_buffer_size == 0) { + ondiemet_module[ONDIEMET_MCUPM] = 0; + met_mcupm.mode = 0; + return; + } + + return; +} + + +static void _mcupm_stop(void) +{ + return; +} + + +static int _mcupm_process_argument(const char *arg, int len) +{ + void (*mcupm_process_argument_real_sym)(const char *arg) = NULL; + + if (strncmp(arg, "cpu_pmu", strlen("cpu_pmu")) == 0) { + ondiemet_module[ONDIEMET_MCUPM] |= (0x1 << MID_MCUPM_CPU_PMU); + } + + mcupm_process_argument_real_sym = symbol_get(mcupm_process_argument_real); + if (mcupm_process_argument_real_sym) { + mcupm_process_argument_real_sym(arg); + } + met_mcupm.mode = 1; + + return 0; +} + + +static int _mcupm_print_help(char *buf, int len) +{ + return snprintf(buf, PAGE_SIZE, help); +} + +static void generate_mcupm_cpu_pmu_header(void) +{ + int len = 0; + int ret = 0; + struct device_node *node = NULL; + struct device_node *core_node = NULL; + int cluster_num = 0; + int cord_id = 0; + char cluster_name[16]; + char core_name[16]; + int i, j; + char *ptr = mcupm_cpu_pmu_header; + + len = snprintf(ptr, MCUPM_CPU_PMU_HEADER_LEN, + "met-info [000] 0.0: met_mcupm_dsu_pmu_header: DSU,0x11,0x2A,0x2B\n"); + if (len < 0) + return ; + + len += snprintf(ptr + len, MCUPM_CPU_PMU_HEADER_LEN - len, + "met-info [000] 0.0: pmu_sampler: mcupm\n"); + if (len < 0) + return ; + + node = of_find_node_by_name(NULL, "cpu-map"); + if (!node) + node = of_find_node_by_name(NULL, "virtual-cpu-map"); + + if (node) { + cluster_num = of_get_child_count(node); + of_node_put(node); + for (i = 0; i < cluster_num; i++) { + ret = snprintf(cluster_name, sizeof(cluster_name), "cluster%d", i); + if (ret < 0) + return ; + node = of_find_node_by_name(NULL, cluster_name); + if (node) { + j = 0; + do { + ret = snprintf(core_name, sizeof(core_name), "core%d", j); + if (ret < 0) + return ; + core_node = of_get_child_by_name(node, core_name); + if (core_node) { + if (i == 0) { + len += snprintf(ptr + len, MCUPM_CPU_PMU_HEADER_LEN - len, + "met-info [000] 0.0: met_mcupm_cpu_header_v2: %d," \ + "0x3,0x4,0x8,0x11,0x16,0x17,0x19,0x1B,0x2A,0x2B,0x66," \ + "0x67,0x70,0x71,0x73,0x74,0x75,0xE7,0xE8\n", cord_id); + } else { + len += snprintf(ptr + len, MCUPM_CPU_PMU_HEADER_LEN - len, + "met-info [000] 0.0: met_mcupm_cpu_header_v2: %d," \ + "0x3,0x4,0x8,0x11,0x16,0x17,0x19,0x1B," \ + "0x2A,0x2B,0x70,0x71,0x73,0x74,0x75\n", cord_id); + } + cord_id++; + of_node_put(core_node); + } + j++; + } while (core_node); + of_node_put(node); + } + } + } +} + + +static int _mcupm_print_header(char *buf, int len) +{ + int cnt = 0; + int cpu_pmu_flag = 0; + int (*mcupm_print_header_real_sym)(char *buf, int len, int cnt) = NULL; + + if (met_mcupm.mode == 0) { + PR_BOOTMSG("mcupm %s %d\n", __FUNCTION__, __LINE__); + return 0; + } + + len = snprintf(buf, PAGE_SIZE, "%s", header); + if (len < 0) + return 0; + + if (ondiemet_module[ONDIEMET_MCUPM] & (0x1 << MID_MCUPM_CPU_PMU)) { + len += snprintf(buf + len, PAGE_SIZE - len, "cpu_pmu"); + cnt++; + cpu_pmu_flag = 1; + } + + mcupm_print_header_real_sym = symbol_get(mcupm_print_header_real); + if (mcupm_print_header_real_sym) { + len = mcupm_print_header_real_sym(buf, len, cnt); + } + + if (cpu_pmu_flag == 1) { + if (strlen(mcupm_cpu_pmu_header) == 0) { + generate_mcupm_cpu_pmu_header(); + } + len += snprintf(buf + len, PAGE_SIZE - len, mcupm_cpu_pmu_header); + } + + ondiemet_module[ONDIEMET_MCUPM] = 0; + met_mcupm.mode = 0; + + if (len < 0) + return 0; + + return len; +} + diff --git a/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/mcupm/mcupm_met.h b/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/mcupm/mcupm_met.h new file mode 100644 index 0000000000000000000000000000000000000000..ebc98d10bd2349ceee847263b8a940de9b94ded8 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/mcupm/mcupm_met.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#ifndef __MCUPM_MET_H__ +#define __MCUPM_MET_H__ +/***************************************************************************** + * headers + *****************************************************************************/ +#include "met_drv.h" /* for metdevice */ + + +/***************************************************************************** + * define declaration + *****************************************************************************/ + + +/***************************************************************************** + * struct & enum declaration + *****************************************************************************/ + + +/***************************************************************************** + * external function declaration + *****************************************************************************/ +void notify_mcupm_cpu_pmu(int flag); + + +/***************************************************************************** + * external variable declaration + *****************************************************************************/ +extern struct metdevice met_mcupm; + + +#endif /* __MCUPM_MET_H__ */ diff --git a/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/mcupm/mcupm_met_ipi_handle.c b/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/mcupm/mcupm_met_ipi_handle.c new file mode 100644 index 0000000000000000000000000000000000000000..ec635702c88d83ed4251da035da71bbcfcbda46a --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/mcupm/mcupm_met_ipi_handle.c @@ -0,0 +1,388 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ +/***************************************************************************** + * headers + *****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* for ioremap and iounmap */ + +#include "mt-plat/mtk_tinysys_ipi.h" /* for mtk_ipi_device */ +#include "mcupm_ipi_id.h" /* for mcupm_ipidev */ + +#include "mcupm_met_log.h" +#include "mcupm_met_ipi_handle.h" +#include "tinysys_mcupm.h" /* for mcupm_ipidev_symbol */ +#include "tinysys_mgr.h" /* for ondiemet_module */ +#include "interface.h" +#include "core_plf_init.h" + + +/***************************************************************************** + * define declaration + *****************************************************************************/ + + +/***************************************************************************** + * struct & enum declaration + *****************************************************************************/ + + +/***************************************************************************** + * external function declaration + *****************************************************************************/ +extern unsigned int met_get_chip_id(void); +extern char *met_get_platform(void); + + +/***************************************************************************** + * internal function declaration + *****************************************************************************/ +static void _log_done_cb(const void *p); +static int _mcupm_recv_thread(void *data); + + +/***************************************************************************** + * external variable declaration + *****************************************************************************/ +int mcupm_buf_available; + + +/***************************************************************************** + * internal variable declaration + *****************************************************************************/ +struct mtk_ipi_device *mcupm_ipidev_symbol; +static unsigned int recv_buf[4]; +static unsigned int rdata; +static unsigned int ackdata; +static unsigned int ridx, widx, wlen; +static unsigned int log_size; +static struct task_struct *_mcupm_recv_task; +static int mcupm_ipi_thread_started; +static int mcupm_buffer_dumping; +static int mcupm_recv_thread_comp; +static int mcupm_run_mode = MCUPM_RUN_NORMAL; + + +/***************************************************************************** + * internal function ipmlement + *****************************************************************************/ +void start_mcupm_ipi_recv_thread() +{ + int ret = 0; + + if (mcupm_ipidev_symbol == NULL) { + mcupm_ipidev_symbol = (struct mtk_ipi_device *)symbol_get(mcupm_ipidev); + } + + if (mcupm_ipidev_symbol == NULL) { + PR_BOOTMSG("mcupm_ipidev_symbol is NULL\n", __FUNCTION__); + return; + } + + // Tinysys send ipi to APSYS + ret = mtk_ipi_register(mcupm_ipidev_symbol, IPIR_C_MET, NULL, + NULL, (void *) &recv_buf); + if (ret) { + PR_BOOTMSG("mtk_ipi_register:%d failed:%d\n", IPIR_C_MET, ret); + } else { + PR_BOOTMSG("mtk_ipi_register IPIR_C_MET success \n"); + } + + // APSYS send ipi to Tinysys + ret = mtk_ipi_register(mcupm_ipidev_symbol, IPIS_C_MET, NULL, + NULL, (void *) &ackdata); + if (ret) { + PR_BOOTMSG("mtk_ipi_register:%d failed:%d\n", IPIS_C_MET, ret); + } else { + PR_BOOTMSG("mtk_ipi_register IPIS_C_MET success \n"); + } + + if (mcupm_ipi_thread_started != 1) { + mcupm_recv_thread_comp = 0; + _mcupm_recv_task = kthread_run(_mcupm_recv_thread, + NULL, "mcupmmcupm_recv"); + if (IS_ERR(_mcupm_recv_task)) { + PR_BOOTMSG("Can not create mcupmmcupm_recv\n"); + + } else { + mcupm_ipi_thread_started = 1; + } + } +} + + +void stop_mcupm_ipi_recv_thread() +{ + if (_mcupm_recv_task) { + mcupm_recv_thread_comp = 1; + + if (mcupm_ipidev_symbol) { + // Tinysys send ipi to APSYS + mtk_ipi_unregister(mcupm_ipidev_symbol, IPIR_C_MET); + // APSYS send ipi to Tinysys + mtk_ipi_unregister(mcupm_ipidev_symbol, IPIS_C_MET); + } + + kthread_stop(_mcupm_recv_task); + _mcupm_recv_task = NULL; + mcupm_ipi_thread_started = 0; + } +} + + +void mcupm_start(void) +{ + int ret = 0; + unsigned int rdata = 0; + unsigned int ipi_buf[4]; + const char* platform_name = NULL; + unsigned int platform_id = 0; + + /* clear DRAM buffer */ + if (mcupm_log_virt_addr != NULL) { + memset_io((void *)mcupm_log_virt_addr, 0, mcupm_buffer_size); + } else { + return; + } + + platform_name = met_get_platform(); + if (platform_name) { + char buf[5]; + + memset(buf, 0x0, 5); + memcpy(buf, &platform_name[2], 4); + ret = kstrtouint(buf, 10, &platform_id); + } + + /* send DRAM physical address */ + ipi_buf[0] = MET_MAIN_ID | MET_BUFFER_INFO; + ipi_buf[1] = (unsigned int)mcupm_log_phy_addr; /* address */ + if (ret == 0) { + ipi_buf[2] = platform_id; + } else { + ipi_buf[2] = 0; + } + + ipi_buf[3] = 0; + ret = met_ipi_to_mcupm_command((void *)ipi_buf, 4, &rdata, 1); + + /* start ondiemet now */ + ipi_buf[0] = MET_MAIN_ID | MET_OP | MET_OP_START; + ipi_buf[1] = ondiemet_module[ONDIEMET_MCUPM] ; + ipi_buf[2] = MCUPM_LOG_FILE; + ipi_buf[3] = MCUPM_RUN_NORMAL; + ret = met_ipi_to_mcupm_command((void *)ipi_buf, 4, &rdata, 1); +} + + +void mcupm_stop(void) +{ + int ret = 0; + unsigned int rdata = 0; + unsigned int ipi_buf[4]; + unsigned int chip_id = 0; + + chip_id = met_get_chip_id(); + if (mcupm_buf_available == 1) { + ipi_buf[0] = MET_MAIN_ID | MET_OP | MET_OP_STOP; + ipi_buf[1] = chip_id; + ipi_buf[2] = 0; + ipi_buf[3] = 0; + ret = met_ipi_to_mcupm_command((void *)ipi_buf, 4, &rdata, 1); + } +} + + +void mcupm_extract(void) +{ + int ret; + unsigned int rdata; + unsigned int ipi_buf[4]; + int count; + + count = 20; + if (mcupm_buf_available == 1) { + while ((mcupm_buffer_dumping == 1) && (count != 0)) { + msleep(50); + count--; + } + ipi_buf[0] = MET_MAIN_ID | MET_OP | MET_OP_EXTRACT; + ipi_buf[1] = 0; + ipi_buf[2] = 0; + ipi_buf[3] = 0; + ret = met_ipi_to_mcupm_command((void *)ipi_buf, 4, &rdata, 1); + + } +} + + +void mcupm_flush(void) +{ + int ret; + unsigned int rdata; + unsigned int ipi_buf[4]; + + if (mcupm_buf_available == 1) { + ipi_buf[0] = MET_MAIN_ID | MET_OP | MET_OP_FLUSH; + ipi_buf[1] = 0; + ipi_buf[2] = 0; + ipi_buf[3] = 0; + ret = met_ipi_to_mcupm_command((void *)ipi_buf, 4, &rdata, 1); + } +} + + +int met_ipi_to_mcupm_command( + unsigned int *buffer, + int slot, + unsigned int *retbuf, + int retslot) +{ + int ret = 0; + + if (mcupm_ipidev_symbol == NULL) { + return -1; + } + + ret = mtk_ipi_send_compl(mcupm_ipidev_symbol, IPIS_C_MET, + IPI_SEND_WAIT, (void*)buffer, slot, 2000); + *retbuf = ackdata; + if (ret != 0) { + PR_BOOTMSG("met_ipi_to_mcupm_command error(%d)\n", ret); + } + + return ret; +} +EXPORT_SYMBOL(met_ipi_to_mcupm_command); + + +int met_ipi_to_mcupm_command_async( + unsigned int *buffer, + int slot, + unsigned int *retbuf, + int retslot) +{ + int ret = 0; + + if (mcupm_ipidev_symbol == NULL) { + return -1; + } + ret = mtk_ipi_send(mcupm_ipidev_symbol, IPIS_C_MET, + IPI_SEND_WAIT, (void*)buffer, slot, 2000); + *retbuf = ackdata; + + if (ret != 0) { + PR_BOOTMSG("met_ipi_to_mcupm_command_async error(%d)\n", ret); + } + + return ret; +} +EXPORT_SYMBOL(met_ipi_to_mcupm_command_async); + + +/***************************************************************************** + * internal function ipmlement + *****************************************************************************/ +static void _log_done_cb(const void *p) +{ + unsigned int ret; + unsigned int rdata = 0; + unsigned int ipi_buf[4]; + unsigned int opt = (p != NULL); + + if (opt == 0) { + mcupm_buffer_dumping = 0; + + ipi_buf[0] = MET_MAIN_ID | MET_RESP_AP2MD; + ipi_buf[1] = MET_DUMP_BUFFER; + ipi_buf[2] = 0; + ipi_buf[3] = 0; + ret = met_ipi_to_mcupm_command((void *)ipi_buf, 0, &rdata, 1); + } +} + + +static int _mcupm_recv_thread(void *data) +{ + int ret = 0; + unsigned int cmd = 0; + + do { + ret = mtk_ipi_recv_reply(mcupm_ipidev_symbol, IPIR_C_MET, (void *)&rdata, 1); + if (ret) { + PR_BOOTMSG("ipi_register:%d failed:%d\n", IPIR_C_MET, ret); + } + if (mcupm_recv_thread_comp == 1) { + while (!kthread_should_stop()) { + ; + } + return 0; + } + + cmd = recv_buf[0] & MET_SUB_ID_MASK; + switch (cmd) { + case MET_DUMP_BUFFER: /* mbox 1: start index; 2: size */ + mcupm_buffer_dumping = 1; + ridx = recv_buf[1]; + widx = recv_buf[2]; + log_size = recv_buf[3]; + if (widx < ridx) { /* wrapping occurs */ + wlen = log_size - ridx; + mcupm_log_req_enq((char *)(mcupm_log_virt_addr) + (ridx << 2), + wlen * 4, _log_done_cb, (void *)1); + mcupm_log_req_enq((char *)(mcupm_log_virt_addr), + widx * 4, _log_done_cb, (void *)0); + } else { + wlen = widx - ridx; + mcupm_log_req_enq((char *)(mcupm_log_virt_addr) + (ridx << 2), + wlen * 4, _log_done_cb, (void *)0); + } + break; + + case MET_CLOSE_FILE: /* no argument */ + ridx = recv_buf[1]; + widx = recv_buf[2]; + if (widx < ridx) { /* wrapping occurs */ + wlen = log_size - ridx; + mcupm_log_req_enq((char *)(mcupm_log_virt_addr) + (ridx << 2), + wlen * 4, _log_done_cb, (void *)1); + mcupm_log_req_enq((char *)(mcupm_log_virt_addr), + widx * 4, _log_done_cb, (void *)1); + } else { + wlen = widx - ridx; + mcupm_log_req_enq((char *)(mcupm_log_virt_addr) + (ridx << 2), + wlen * 4, _log_done_cb, (void *)1); + } + ret = mcupm_log_stop(); + if (mcupm_run_mode == MCUPM_RUN_CONTINUOUS) { + /* clear the memory */ + memset_io((void *)mcupm_log_virt_addr, 0, + mcupm_buffer_size); + /* re-start ondiemet again */ + mcupm_start(); + } + break; + + default: + break; + } + } while (!kthread_should_stop()); + + return 0; +} + diff --git a/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/mcupm/mcupm_met_ipi_handle.h b/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/mcupm/mcupm_met_ipi_handle.h new file mode 100644 index 0000000000000000000000000000000000000000..949c1f5b8e6d4aacc383271b8724202fb48e38f4 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/mcupm/mcupm_met_ipi_handle.h @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#ifndef __MUCPM_MET_IPI_HANDLE_H__ +#define __MUCPM_MET_IPI_HANDLE_H__ +/***************************************************************************** + * headers + *****************************************************************************/ + + +/***************************************************************************** + * define declaration + *****************************************************************************/ + + +/***************************************************************************** + * struct & enum declaration + *****************************************************************************/ + + +/***************************************************************************** + * external function declaration + *****************************************************************************/ +void start_mcupm_ipi_recv_thread(void); +void stop_mcupm_ipi_recv_thread(void); + +void mcupm_start(void); +void mcupm_stop(void); +void mcupm_extract(void); +void mcupm_flush(void); + +int met_ipi_to_mcupm_command( + unsigned int *buffer, + int slot, + unsigned int *retbuf, + int retslot); +int met_ipi_to_mcupm_command_async( + unsigned int *buffer, + int slot, + unsigned int *retbuf, + int retslot); + + +/***************************************************************************** + * external variable declaration + *****************************************************************************/ + + +#endif /* __MUCPM_MET_IPI_HANDLE_H__ */ diff --git a/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/mcupm/mcupm_met_log.c b/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/mcupm/mcupm_met_log.c new file mode 100644 index 0000000000000000000000000000000000000000..71666a2bcf08e192b30866479d6f1c460a36bd7a --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/mcupm/mcupm_met_log.c @@ -0,0 +1,705 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ +/***************************************************************************** + * headers + *****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* symbol_get */ + +#include "interface.h" + +#include "mcupm_driver.h" +#include "mcupm_driver.h" + +#include "mcupm_met_log.h" +#include "mcupm_met_ipi_handle.h" + + +/***************************************************************************** + * define declaration + *****************************************************************************/ +#define MUCPM_LOG_REQ 1 +#define MUCPM_LOG_STOP 2 + +#define PID_NONE (-1) + +#define MUCPM_LOG_STOP_MODE 0 +#define MUCPM_LOG_RUN_MODE 1 +#define MUCPM_LOG_DEBUG_MODE 2 + +#define _mcupm_log_req_init(req, cmd, s, n, pf, p) \ + do { \ + INIT_LIST_HEAD(&req->list); \ + req->cmd_type = cmd; \ + req->src = s; \ + req->num = n; \ + req->on_fini_cb = pf; \ + req->param = p; \ + } while (0) + +#define _mcupm_log_req_fini(req) \ + do { \ + if (req->on_fini_cb) \ + req->on_fini_cb(req->param); \ + kfree(req); \ + } while (0) + + +/***************************************************************************** + * struct & enum declaration + *****************************************************************************/ +struct mcupm_log_req_q_t { + struct list_head listq; + struct mutex lockq; + struct completion new_evt_comp; + int closeq_flag; +} mcupm_log_req_q; + +struct mcupm_log_req { + struct list_head list; + int cmd_type; + const char *src; + size_t num; + + void (*on_fini_cb)(const void *p); + const void *param; +}; + + +/***************************************************************************** + * external function declaration + *****************************************************************************/ + + +/***************************************************************************** + * internal function declaration + *****************************************************************************/ +static void _log_stop_cb(const void *p); +static int _down_freezable_interruptible(struct completion *comp); + +static void _mcupm_log_req_q_init(struct mcupm_log_req_q_t *q); +static void _mcupm_log_req_undeq(struct mcupm_log_req *req); +static int _mcupm_log_req_enq(struct mcupm_log_req *req); +static struct mcupm_log_req *_mcupm_log_req_deq(void); +static void _mcupm_log_req_open(void); +static int _mcupm_log_req_closed(void); +static int _mcupm_log_req_working(void); +static void *_mcupm_trace_seq_next(struct seq_file *seqf, loff_t *offset); + +static void *mcupm_trace_seq_start(struct seq_file *seqf, loff_t *offset); +static void mcupm_trace_seq_stop(struct seq_file *seqf, void *p); +static void *mcupm_trace_seq_next(struct seq_file *seqf, void *p, loff_t *offset); +static int mcupm_trace_seq_show(struct seq_file *seqf, void *p); +static int mcupm_trace_open(struct inode *inode, struct file *fp); + +static ssize_t mcupm_log_write_store( + struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count); +static ssize_t mcupm_log_run_show( + struct device *dev, + struct device_attribute *attr, + char *buf); +static ssize_t mcupm_log_run_store( + struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count); + + +/***************************************************************************** + * external variable declaration + *****************************************************************************/ +void *mcupm_log_virt_addr; + +#if defined(CONFIG_MTK_GMO_RAM_OPTIMIZE) || defined(CONFIG_MTK_MET_MEM_ALLOC) +dma_addr_t mcupm_log_phy_addr; +#else +unsigned int mcupm_log_phy_addr; +#endif + +unsigned int mcupm_buffer_size; + +extern int mcupm_buf_available; + + +/***************************************************************************** + * internal variable declaration + *****************************************************************************/ +static int mcupm_trace_run; +static pid_t trace_owner_pid = PID_NONE; + +static struct mutex lock_tracef; +static struct mutex lock_trace_owner_pid; + +static struct completion log_start_comp; +static struct completion log_stop_comp; + +static DEVICE_ATTR(mcupm_log_write, 0220, NULL, mcupm_log_write_store); +static DEVICE_ATTR(mcupm_log_run, 0664, mcupm_log_run_show, mcupm_log_run_store);; + +static const struct seq_operations mcupm_trace_seq_ops = { + .start = mcupm_trace_seq_start, + .next = mcupm_trace_seq_next, + .stop = mcupm_trace_seq_stop, + .show = mcupm_trace_seq_show +}; + +static const struct file_operations mcupm_trace_fops = { + .owner = THIS_MODULE, + .open = mcupm_trace_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release +}; + + +/***************************************************************************** + * external function ipmlement + *****************************************************************************/ +int mcupm_log_init(struct device *dev) +{ + int ret = 0; +#ifdef ONDIEMET_MOUNT_DEBUGFS + struct dentry *d; + struct dentry *met_dir = NULL; +#else + struct proc_dir_entry *d; + struct proc_dir_entry *met_dir = NULL; +#endif + phys_addr_t (*get_size_sym)(unsigned int id) = NULL; + + met_dir = dev_get_drvdata(dev); + mutex_init(&lock_tracef); + _mcupm_log_req_q_init(&mcupm_log_req_q); + init_completion(&log_start_comp); + init_completion(&log_stop_comp); + mutex_init(&lock_trace_owner_pid); + +#ifdef ONDIEMET_MOUNT_DEBUGFS + d = debugfs_create_file("mcupm_trace", 0600, met_dir, NULL, &mcupm_trace_fops); + if (!d) { + PR_BOOTMSG("can not create devide node in debugfs: mcupm_trace\n"); + return -ENOMEM; + } +#else + d = proc_create("mcupm_trace", 0600, met_dir, &mcupm_trace_fops); + if (!d) { + PR_BOOTMSG("can not create devide node in procfs: mcupm_trace\n"); + return -ENOMEM; + } +#endif + + mcupm_trace_run = _mcupm_log_req_working(); + ret = device_create_file(dev, &dev_attr_mcupm_log_run); + if (ret != 0) { + PR_BOOTMSG("can not create device node: mcupm_log_run\n"); + return ret; + } + +#if defined(CONFIG_MTK_GMO_RAM_OPTIMIZE) || defined(CONFIG_MTK_MET_MEM_ALLOC) + mcupm_log_virt_addr = dma_alloc_coherent(dev, 0x800000, + &mcupm_log_phy_addr, GFP_ATOMIC); + if (mcupm_log_virt_addr) { + mcupm_buffer_size = 0x800000; + mcupm_buf_available = 1; + } else { + mcupm_buf_available = 0; + } +#else + get_size_sym = symbol_get(mcupm_reserve_mem_get_size); + if (get_size_sym) { + mcupm_buffer_size = get_size_sym(MCUPM_MET_ID); + PR_BOOTMSG("mcupm_buffer_size=%x\n", mcupm_buffer_size); + } else { + PR_BOOTMSG("symbol_get mcupm_reserve_mem_get_size failure\n"); + } + + if (mcupm_buffer_size > 0) { + phys_addr_t (*get_phys_sym)(unsigned int id) = NULL; + phys_addr_t (*get_virt_sym)(unsigned int id) = NULL; + + get_phys_sym = symbol_get(mcupm_reserve_mem_get_virt); + get_virt_sym = symbol_get(mcupm_reserve_mem_get_phys); + if (get_phys_sym) { + mcupm_log_virt_addr = (void*)get_phys_sym(MCUPM_MET_ID); + PR_BOOTMSG("mcupm_log_virt_addr=%p\n", mcupm_log_virt_addr); + } else { + PR_BOOTMSG("symbol_get mcupm_reserve_mem_get_virt failure\n"); + } + if (get_virt_sym) { + mcupm_log_phy_addr = get_virt_sym(MCUPM_MET_ID); + PR_BOOTMSG("mcupm_log_phy_addr=%p\n", mcupm_log_phy_addr); + } else { + PR_BOOTMSG("symbol_get mcupm_reserve_mem_get_phys failure\n"); + } + mcupm_buf_available = 1; + } else { + mcupm_buf_available = 0; + } +#endif /* CONFIG_MTK_GMO_RAM_OPTIMIZE */ + + start_mcupm_ipi_recv_thread(); + + return 0; +} + + +int mcupm_log_uninit(struct device *dev) +{ + stop_mcupm_ipi_recv_thread(); + + if (mcupm_log_virt_addr != NULL) { +#if defined(CONFIG_MTK_GMO_RAM_OPTIMIZE) || defined(CONFIG_MTK_MET_MEM_ALLOC) + dma_free_coherent(dev, mcupm_buffer_size, mcupm_log_virt_addr, + mcupm_log_phy_addr); +#endif /* CONFIG_MTK_GMO_RAM_OPTIMIZE */ + mcupm_log_virt_addr = NULL; + } + + device_remove_file(dev, &dev_attr_mcupm_log_run); + return 0; +} + + +int mcupm_log_start(void) +{ + int ret = 0; + + /* TODO: choose a better return value */ + if (_mcupm_log_req_working()) { + return -EINVAL; + } + + if (!_mcupm_log_req_closed()) { + /*ret = down_killable(&log_start_sema);*/ + ret = wait_for_completion_killable(&log_start_comp); + if (ret) { + return ret; + } + } + + _mcupm_log_req_open(); + + return 0; +} + + +int mcupm_log_stop(void) +{ + int ret = 0; + struct mcupm_log_req *req = NULL; + + if (_mcupm_log_req_closed()) { + return -EINVAL; + } + + req = kmalloc(sizeof(*req), GFP_ATOMIC); + if (req == NULL) { + return -EINVAL; + } + _mcupm_log_req_init(req, MUCPM_LOG_STOP, NULL, 0, _log_stop_cb, NULL); + + init_completion(&log_start_comp); + init_completion(&log_stop_comp); + + ret = _mcupm_log_req_enq(req); + if (ret) { + return ret; + } + + return wait_for_completion_killable(&log_stop_comp); +} + + +int mcupm_log_req_enq( + const char *src, size_t num, + void (*on_fini_cb)(const void *p), + const void *param) +{ + struct mcupm_log_req *req = kmalloc(sizeof(*req), GFP_ATOMIC); + + if (req == NULL) { + return -EINVAL; + } + + _mcupm_log_req_init(req, MUCPM_LOG_REQ, src, num, on_fini_cb, param); + return _mcupm_log_req_enq(req); +} + + +int mcupm_parse_num(const char *str, unsigned int *value, int len) +{ + int ret = 0; + + if (len <= 0) { + return -1; + } + + if ((len > 2) && ((str[0] == '0') && ((str[1] == 'x') || (str[1] == 'X')))) { + ret = kstrtouint(str, 16, value); + } else { + ret = kstrtouint(str, 10, value); + } + + if (ret != 0) { + return -1; + } + + return 0; +} + + +/***************************************************************************** + * internal function ipmlement + *****************************************************************************/ +static void _log_stop_cb(const void *p) +{ + complete(&log_start_comp); + complete(&log_stop_comp); +} + + +static int _down_freezable_interruptible(struct completion *comp) +{ + int ret = 0; + + freezer_do_not_count(); + ret = wait_for_completion_interruptible(comp); + freezer_count(); + + return ret; +} + + +static void _mcupm_log_req_q_init(struct mcupm_log_req_q_t *q) +{ + INIT_LIST_HEAD(&q->listq); + mutex_init(&q->lockq); + init_completion(&q->new_evt_comp); + q->closeq_flag = 1; +} + + +/* + undequeue is seen as a roll-back operation, + so it can be done even when the queue is closed +*/ +static void _mcupm_log_req_undeq(struct mcupm_log_req *req) +{ + mutex_lock(&mcupm_log_req_q.lockq); + list_add(&req->list, &mcupm_log_req_q.listq); + mutex_unlock(&mcupm_log_req_q.lockq); + + complete(&mcupm_log_req_q.new_evt_comp); +} + + +static int _mcupm_log_req_enq(struct mcupm_log_req *req) +{ + mutex_lock(&mcupm_log_req_q.lockq); + if (mcupm_log_req_q.closeq_flag) { + mutex_unlock(&mcupm_log_req_q.lockq); + return -EBUSY; + } + + list_add_tail(&req->list, &mcupm_log_req_q.listq); + if (req->cmd_type == MUCPM_LOG_STOP) { + mcupm_log_req_q.closeq_flag = 1; + } + mutex_unlock(&mcupm_log_req_q.lockq); + + complete(&mcupm_log_req_q.new_evt_comp); + + return 0; +} + + +static struct mcupm_log_req *_mcupm_log_req_deq(void) +{ + struct mcupm_log_req *ret_req; + + if (_down_freezable_interruptible(&mcupm_log_req_q.new_evt_comp)) { + return NULL; + } + + mutex_lock(&mcupm_log_req_q.lockq); + ret_req = list_entry(mcupm_log_req_q.listq.next, struct mcupm_log_req, list); + list_del_init(&ret_req->list); + mutex_unlock(&mcupm_log_req_q.lockq); + + return ret_req; +} + + +static void _mcupm_log_req_open(void) +{ + mutex_lock(&mcupm_log_req_q.lockq); + mcupm_log_req_q.closeq_flag = 0; + mutex_unlock(&mcupm_log_req_q.lockq); +} + + +static int _mcupm_log_req_closed(void) +{ + int ret = 0; + + mutex_lock(&mcupm_log_req_q.lockq); + ret = mcupm_log_req_q.closeq_flag && list_empty(&mcupm_log_req_q.listq); + mutex_unlock(&mcupm_log_req_q.lockq); + + return ret; +} + + +static int _mcupm_log_req_working(void) +{ + int ret = 0; + + mutex_lock(&mcupm_log_req_q.lockq); + ret = !mcupm_log_req_q.closeq_flag; + mutex_unlock(&mcupm_log_req_q.lockq); + + return ret; +} + + +static void *_mcupm_trace_seq_next(struct seq_file *seqf, loff_t *offset) +{ + struct mcupm_log_req *next_req; + + if (mcupm_trace_run == MUCPM_LOG_DEBUG_MODE) { + PR_BOOTMSG("_mcupm_trace_seq_next: pid: %d\n", current->pid); + } + + if (_mcupm_log_req_closed()) { + return NULL; + } + + next_req = _mcupm_log_req_deq(); + if (next_req == NULL) { + return NULL; + } + + if (next_req->cmd_type == MUCPM_LOG_STOP) { + _mcupm_log_req_fini(next_req); + return NULL; + } + + return (void *) next_req; +} + + +static void *mcupm_trace_seq_start(struct seq_file *seqf, loff_t *offset) +{ + void *ret; + + if (mcupm_trace_run == MUCPM_LOG_DEBUG_MODE) { + PR_BOOTMSG("mcupm_trace_seq_start: locked_pid: %d, pid: %d, offset: %llu\n", + trace_owner_pid, current->pid, *offset); + } + + if (!mutex_trylock(&lock_tracef)) { + return NULL; + } + + mutex_lock(&lock_trace_owner_pid); + trace_owner_pid = current->pid; + current->flags |= PF_NOFREEZE; + mutex_unlock(&lock_trace_owner_pid); + + ret = _mcupm_trace_seq_next(seqf, offset); + + return ret; +} + + +static void mcupm_trace_seq_stop(struct seq_file *seqf, void *p) +{ + if (mcupm_trace_run == MUCPM_LOG_DEBUG_MODE) { + PR_BOOTMSG("mcupm_trace_seq_stop: pid: %d\n", current->pid); + } + + mutex_lock(&lock_trace_owner_pid); + if (current->pid == trace_owner_pid) { + trace_owner_pid = PID_NONE; + mutex_unlock(&lock_tracef); + } + mutex_unlock(&lock_trace_owner_pid); +} + + +static void *mcupm_trace_seq_next(struct seq_file *seqf, void *p, loff_t *offset) +{ + if (mcupm_trace_run == MUCPM_LOG_DEBUG_MODE) { + PR_BOOTMSG("mcupm_trace_seq_next: pid: %d\n", current->pid); + } + (*offset)++; + return _mcupm_trace_seq_next(seqf, offset); +} + + +static int mcupm_trace_seq_show(struct seq_file *seqf, void *p) +{ + struct mcupm_log_req *req = (struct mcupm_log_req *) p; + size_t l_sz; + size_t r_sz; + struct mcupm_log_req *l_req; + struct mcupm_log_req *r_req; + int ret = 0; + + if (mcupm_trace_run == MUCPM_LOG_DEBUG_MODE) { + PR_BOOTMSG("mcupm_trace_seq_show: pid: %d\n", current->pid); + } + + if (req->num >= seqf->size) { + l_req = kmalloc(sizeof(*req), GFP_ATOMIC); + if (l_req == NULL) { + return -EINVAL; + } + r_req = req; + + l_sz = seqf->size >> 1; + r_sz = req->num - l_sz; + _mcupm_log_req_init(l_req, MUCPM_LOG_REQ, req->src, l_sz, NULL, NULL); + _mcupm_log_req_init(r_req, MUCPM_LOG_REQ, req->src + l_sz, + r_sz, req->on_fini_cb, req->param); + + _mcupm_log_req_undeq(r_req); + req = l_req; + + if (mcupm_trace_run == MUCPM_LOG_DEBUG_MODE) { + PR_BOOTMSG("mcupm_trace_seq_show: split request\n"); + } + } + + ret = seq_write(seqf, req->src, req->num); + if (ret) { + /* check if seq_file buffer overflows */ + if (seqf->count == seqf->size) { + _mcupm_log_req_undeq(req); + } else { + if (mcupm_trace_run == MUCPM_LOG_DEBUG_MODE) { + PR_BOOTMSG("mcupm_trace_seq_show: \ + reading trace record failed, \ + some data may be lost or corrupted\n"); + } + _mcupm_log_req_fini(req); + } + return 0; + } + + _mcupm_log_req_fini(req); + return 0; +} + + +static int mcupm_trace_open(struct inode *inode, struct file *fp) +{ + return seq_open(fp, &mcupm_trace_seq_ops); +} + + +static ssize_t mcupm_log_write_store( + struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + char *plog = NULL; + + plog = kmalloc_array(count, sizeof(*plog), GFP_ATOMIC); + if (!plog) { + /* TODO: use a better error code */ + return -EINVAL; + } + + memcpy(plog, buf, count); + + mutex_lock(&dev->mutex); + mcupm_log_req_enq(plog, strnlen(plog, count), kfree, plog); + mutex_unlock(&dev->mutex); + + return count; +} + + +static ssize_t mcupm_log_run_show( + struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int sz; + + mutex_lock(&dev->mutex); + sz = snprintf(buf, PAGE_SIZE, "%d\n", mcupm_trace_run); + mutex_unlock(&dev->mutex); + + if (sz < 0) + sz = 0; + + return sz; +} + + +static ssize_t mcupm_log_run_store( + struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + int ret = 0; + int prev_run_state; + + mutex_lock(&dev->mutex); + + prev_run_state = mcupm_trace_run; + if (kstrtoint(buf, 10, &mcupm_trace_run) != 0) { + return -EINVAL; + } + + if (mcupm_trace_run <= MUCPM_LOG_STOP_MODE) { + mcupm_trace_run = MUCPM_LOG_STOP_MODE; + mcupm_log_stop(); + + if (prev_run_state == MUCPM_LOG_DEBUG_MODE) { + device_remove_file(dev, &dev_attr_mcupm_log_write); + } + } else if (mcupm_trace_run == MUCPM_LOG_RUN_MODE) { + mcupm_trace_run = MUCPM_LOG_RUN_MODE; + mcupm_log_start(); + + if (prev_run_state == MUCPM_LOG_DEBUG_MODE) { + device_remove_file(dev, &dev_attr_mcupm_log_write); + } + } else { + mcupm_trace_run = MUCPM_LOG_DEBUG_MODE; + mcupm_log_start(); + + if (prev_run_state != MUCPM_LOG_DEBUG_MODE) { + ret = device_create_file(dev, &dev_attr_mcupm_log_write); + if (ret != 0) { + PR_BOOTMSG("can not create device node: \ + mcupm_log_write\n"); + } + } + } + + mutex_unlock(&dev->mutex); + + return count; +} + diff --git a/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/mcupm/mcupm_met_log.h b/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/mcupm/mcupm_met_log.h new file mode 100644 index 0000000000000000000000000000000000000000..69099247b3c6b166ac12c44ee2d9b5fcd445a968 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/mcupm/mcupm_met_log.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#ifndef __MCUPM_MET_LOG_H__ +#define __MCUPM_MET_LOG_H__ +/***************************************************************************** + * headers + *****************************************************************************/ +#include +#if defined(CONFIG_MTK_GMO_RAM_OPTIMIZE) || defined(CONFIG_MTK_MET_MEM_ALLOC) +#include +#endif + + +/***************************************************************************** + * define declaration + *****************************************************************************/ + + +/***************************************************************************** + * struct & enum declaration + *****************************************************************************/ + + +/***************************************************************************** + * external function declaration + *****************************************************************************/ +int mcupm_log_init(struct device *dev); +int mcupm_log_uninit(struct device *dev); +int mcupm_log_start(void); +int mcupm_log_stop(void); + +int mcupm_log_req_enq( + const char *src, size_t num, + void (*on_fini_cb)(const void *p), + const void *param); +int mcupm_parse_num(const char *str, unsigned int *value, int len); + + +/***************************************************************************** + * external variable declaration + *****************************************************************************/ +extern void *mcupm_log_virt_addr; +#if defined(CONFIG_MTK_GMO_RAM_OPTIMIZE) || defined(CONFIG_MTK_MET_MEM_ALLOC) +extern dma_addr_t mcupm_log_phy_addr; +#else +extern unsigned int mcupm_log_phy_addr; +#endif +extern unsigned int mcupm_buffer_size; + +#endif /* __MCUPM_MET_LOG_H__ */ diff --git a/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/mcupm/tinysys_mcupm.h b/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/mcupm/tinysys_mcupm.h new file mode 100644 index 0000000000000000000000000000000000000000..940346ea5f99f5ba4564d0dcd504bcca85060928 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/mcupm/tinysys_mcupm.h @@ -0,0 +1,124 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#ifndef __TINYSYS_MCUPM_H__ +#define __TINYSYS_MCUPM_H__ +/***************************************************************************** + * headers + *****************************************************************************/ +#include "mt-plat/mtk_tinysys_ipi.h" /* for mtk_ipi_device */ + + +/***************************************************************************** + * define declaration + *****************************************************************************/ +/* MET IPI command definition: mbox 0 */ +/* main func ID: bit[31-24]; sub func ID: bit[23-18]; argu 0: bit[17-0] */ +#define MET_MAIN_ID_MASK 0xff000000 /* bit 31 - 24 */ +#define MET_SUB_ID_MASK 0x00fc0000 /* bit 23 - 18 */ +#define MET_ARGU0_MASK 0x0003ffff /* bit 17 - 0 */ +#define FUNC_BIT_SHIFT 18 +#define MID_BIT_SHIFT 9 +#define MET_MAIN_ID 0x06000000 +/* handle argument and attribute */ +#define PROCESS_ARGU 0x01 +#define PROCESS_ATTR 0x02 +#define MODULE_ID_MASK 0x3fe00 /* bit 9 - 17 */ +#define ARGUMENT_MASK 0x01ff /* bit 0 - 8 */ + +/* the following command is used for AP to MD32 */ +/* argu 0: start: 0x01; stop: 0x02; extract: 0x03 */ +#define MET_OP_START 0x00000001 +#define MET_OP_STOP 0x00000002 +#define MET_OP_EXTRACT 0x00000003 +#define MET_OP_FLUSH 0x00000004 +#define MET_OP (1 << FUNC_BIT_SHIFT) +#define MET_SR (2 << FUNC_BIT_SHIFT) /* sample rate */ +#define MET_MODULE (3 << FUNC_BIT_SHIFT) /* module enable/disable */ +#define MET_ARGU (4 << FUNC_BIT_SHIFT) /* argument passing */ +#define MET_ATTR (5 << FUNC_BIT_SHIFT) /* attribute passing */ +/* system memory information for on-die-met log data */ +#define MET_BUFFER_INFO (6 << FUNC_BIT_SHIFT) +#define MET_TIMESTAMP (7 << FUNC_BIT_SHIFT) /* timestamp info */ +#define MET_GPT (8 << FUNC_BIT_SHIFT) /* GPT counter reading */ +#define MET_REQ_AP2MD (9 << FUNC_BIT_SHIFT) /* user defined command */ +#define MET_RESP_AP2MD (10 << FUNC_BIT_SHIFT) /* may no need */ +/* mode: bit 15 - 0: */ +/* Bit 0: MD32 SRAM mode; Bit 1: System DRAM mode */ +/* value: 0: output to next level of storage; 1: loop in its own storage */ +#define MET_DATA_MODE (11 << FUNC_BIT_SHIFT) /* log output mode */ +/* start/stop read data into MD32 SRAM buffer; both DMA and met_printf() */ +#define MET_DATA_OP (12 << FUNC_BIT_SHIFT) /* data read operation */ +/* the following command is used for MD32 to AP */ +#define MET_DUMP_BUFFER (13 << FUNC_BIT_SHIFT) +#define MET_REQ_MD2AP (14 << FUNC_BIT_SHIFT) /* user defined command */ +#define MET_CLOSE_FILE (15 << FUNC_BIT_SHIFT) /* Inform to close the SD file */ +#define MET_RESP_MD2AP (16 << FUNC_BIT_SHIFT) +#define MET_RUN_MODE (17 << FUNC_BIT_SHIFT) + +#define ID_PMQOS (1 << MID_PMQOS) +#define ID_SMI (1 << MID_SMI) +#define ID_EMI (1 << MID_EMI) +#define ID_THERMAL_CPU (1 << MID_THERMAL_CPU) +#define ID_WALL_TIME (1 << MID_WALL_TIME) +#define ID_CPU_DVFS (1 << MID_CPU_DVFS) +#define ID_GPU_DVFS (1 << MID_GPU_DVFS) +#define ID_VCORE_DVFS (1 << MID_VCORE_DVFS) +#define ID_PTPOD (1 << MID_PTPOD) +#define ID_SPM (1 << MID_SPM) +#define ID_PROFILE (1 << MID_PROFILE) +#define ID_COMMON (1 << MID_COMMON) +#define ID_CPU_INFO_MAPPING (1 << MID_CPU_INFO_MAPPING) +#define ID_SMI (1 << MID_SMI) +#define ID_PMU (1 << MID_PMU) + +#define MCUPM_LOG_FILE 0 +#define MCUPM_LOG_SRAM 1 +#define MCUPM_LOG_DRAM 2 + +#define MCUPM_RUN_NORMAL 0 +#define MCUPM_RUN_CONTINUOUS 1 + + +/***************************************************************************** + * struct & enum declaration + *****************************************************************************/ +/* Note: the module ID and its bit pattern should be fixed as below */ +/* DMA based module first */ +enum { + MID_PMQOS = 0, + MID_VCORE_DVFS = 1, + MID_EMI = 2, + MID_THERMAL_CPU = 3, + MID_WALL_TIME = 4, + MID_CPU_DVFS = 5, + MID_GPU_DVFS = 6, + MID_PTPOD = 7, + MID_SPM = 8, + MID_PROFILE = 9, + MID_MET_TAG = 10, + MID_TS = 11, + MID_TS_ISR = 12, + MID_TS_LAST = 13, + MID_TS_ISR_LAST = 14, + MID_SRAM_INFO = 15, + MID_MET_STOP = 16, + MID_IOP_MON = 17, + MID_CPU_INFO_MAPPING = 18, + MID_SMI = 19, + MID_PMU = 20, + + MID_MCUPM_CPU_PMU = 21, + + MID_COMMON = 0x1F +}; + + +/***************************************************************************** + * external variable declaration + *****************************************************************************/ +extern struct mtk_ipi_device *mcupm_ipidev_symbol; + + +#endif /* __TINYSYS_MCUPM_H__ */ diff --git a/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/sspm/sspm_met_common.c b/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/sspm/sspm_met_common.c new file mode 100644 index 0000000000000000000000000000000000000000..bb3d727815266d06a317d741d388625c80df06da --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/sspm/sspm_met_common.c @@ -0,0 +1,272 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ +/***************************************************************************** + * headers + *****************************************************************************/ +#include +#include +#include +#include /* for symbol_get */ + +#include "met_drv.h" +#include "tinysys_sspm.h" +#include "tinysys_mgr.h" + +#include "sspm_met_log.h" +#include "sspm_met_ipi_handle.h" /* for met_ipi_to_sspm_command */ + + +/***************************************************************************** + * struct & enum declaration + *****************************************************************************/ +struct sspm_met_evnet_header { + unsigned int rts_event_id; + char *rts_event_name; + char *chart_line_name; + char *key_list; +}; + +enum { + #ifdef MET_SSPM_RTS_EVNET + #undef MET_SSPM_RTS_EVNET + #endif + #define MET_SSPM_RTS_EVNET(rts_event_id, key_list) rts_event_id, + #include "met_sspm_rts_event.h" + + /* Note: always put at last */ + CUR_MET_RTS_EVENT_NUM, + MAX_MET_RTS_EVENT_NUM = 128 +}; + + +/***************************************************************************** + * internal function declaration + *****************************************************************************/ +static void ondiemet_sspm_start(void); +static void ondiemet_sspm_stop(void); +static int ondiemet_sspm_print_help(char *buf, int len); +static int ondiemet_sspm_process_argument(const char *arg, int len); +static int ondiemet_sspm_print_header(char *buf, int len); + + +/***************************************************************************** + * external function declaration + *****************************************************************************/ +unsigned int update_sspm_met_evnet_header( + void* met_evnet_header, + unsigned int cur_met_rts_event_num); + + +/***************************************************************************** + * internal variable + *****************************************************************************/ +static unsigned int event_id_flag[MAX_MET_RTS_EVENT_NUM / 32]; +static char *update_rts_event_tbl[MAX_MET_RTS_EVENT_NUM]; +static char sspm_help[] = " --sspm_common=rts_event_name\n"; +static char header[] = "met-info [000] 0.0: sspm_common_header: "; +static unsigned int additional_rts_cnt = 0; + +static struct sspm_met_evnet_header met_evnet_header[MAX_MET_RTS_EVENT_NUM] = { + #ifdef MET_SSPM_RTS_EVNET + #undef MET_SSPM_RTS_EVNET + #endif + #define MET_SSPM_RTS_EVNET(rts_event_id, key_list) \ + {rts_event_id, #rts_event_id, #rts_event_id, key_list}, + #include "met_sspm_rts_event.h" +}; + +struct metdevice met_sspm_common = { + .name = "sspm_common", + .owner = THIS_MODULE, + .type = MET_TYPE_BUS, + .cpu_related = 0, + .ondiemet_mode = 1, + .ondiemet_start = ondiemet_sspm_start, + .ondiemet_stop = ondiemet_sspm_stop, + .ondiemet_process_argument = ondiemet_sspm_process_argument, + .ondiemet_print_help = ondiemet_sspm_print_help, + .ondiemet_print_header = ondiemet_sspm_print_header, +}; + + +/***************************************************************************** + * internal function implement + *****************************************************************************/ +static int ondiemet_sspm_print_help(char *buf, int len) +{ + return snprintf(buf, PAGE_SIZE, sspm_help); +} + + +static int ondiemet_sspm_print_header(char *buf, int len) +{ + int i; + int write_len; + int flag = 0; + int mask = 0; + int group; + static int is_dump_header = 0; + static int read_idx = 0; + + len = 0; + met_sspm_common.header_read_again = 0; + if (is_dump_header == 0) { + len = snprintf(buf, PAGE_SIZE, "%s", header); + is_dump_header = 1; + } + + for (i = read_idx; i < CUR_MET_RTS_EVENT_NUM + additional_rts_cnt; i++) { + if (met_evnet_header[i].chart_line_name) { + group = i / 32; + mask = 1 << (i - group * 32); + flag = event_id_flag[group] & mask; + if (flag == 0) { + continue; + } + + write_len = strlen(met_evnet_header[i].chart_line_name) + strlen(met_evnet_header[i].key_list) + 3; + if ((len + write_len) < PAGE_SIZE) { + len += snprintf(buf+len, PAGE_SIZE-len, "%u,%s,%s;", + met_evnet_header[i].rts_event_id, + met_evnet_header[i].chart_line_name, + met_evnet_header[i].key_list); + } else { + met_sspm_common.header_read_again = 1; + read_idx = i; + return len; + } + } + } + + if (i == CUR_MET_RTS_EVENT_NUM + additional_rts_cnt) { + is_dump_header = 0; + read_idx = 0; + buf[len - 1] = '\n'; + for (i = 0; i < CUR_MET_RTS_EVENT_NUM + additional_rts_cnt; i++) { + if (update_rts_event_tbl[i]) { + kfree(update_rts_event_tbl[i]); + update_rts_event_tbl[i] = NULL; + } + } + met_sspm_common.mode = 0; + for (i = 0 ; i < MAX_MET_RTS_EVENT_NUM / 32; i++) { + event_id_flag[i] = 0; + } + } + + return len; +} + + +static void ondiemet_sspm_start(void) +{ + if (sspm_buffer_size == 0) { + return; + } + + ondiemet_module[ONDIEMET_SSPM] |= ID_COMMON; +} + + +static void ondiemet_sspm_stop(void) +{ + return; +} + + +static void update_event_id_flag(int event_id) +{ + unsigned int ipi_buf[4] = {0}; + unsigned int rdata = 0; + unsigned int res = 0; + unsigned int group = 0; + + if (sspm_buffer_size == 0) + return ; + + group = event_id / 32; + event_id_flag[group] |= 1 << (event_id - group * 32); + ipi_buf[0] = MET_MAIN_ID | MET_ARGU | MID_COMMON<= 0) { + update_event_id_flag(rts_event_id); + } + + return 0; +} +EXPORT_SYMBOL(met_sspm_common); diff --git a/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/sspm/sspm_met_ipi_handle.c b/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/sspm/sspm_met_ipi_handle.c new file mode 100644 index 0000000000000000000000000000000000000000..4f8e32ab8380180697c88d5dea4d06874dda57a4 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/sspm/sspm_met_ipi_handle.c @@ -0,0 +1,439 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ +/***************************************************************************** + * headers + *****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* for ioremap and iounmap */ + +#include "mt-plat/mtk_tinysys_ipi.h" /* for mtk_ipi_device */ +#include "sspm_ipi_id.h" /* for sspm_ipidev */ +#include "sspm_met_log.h" /* for sspm_ipidev_symbol */ +#include "sspm_met_ipi_handle.h" +#include "interface.h" +#include "core_plf_init.h" +#include "tinysys_sspm.h" +#include "tinysys_mgr.h" /* for ondiemet_module */ + + +/***************************************************************************** + * define declaration + *****************************************************************************/ + + +/***************************************************************************** + * struct & enum declaration + *****************************************************************************/ + + +/***************************************************************************** + * external function declaration + *****************************************************************************/ +extern unsigned int met_get_chip_id(void); +extern char *met_get_platform(void); + + +/***************************************************************************** + * internal function declaration + *****************************************************************************/ +static void _log_done_cb(const void *p); +static int _met_ipi_cb( + unsigned int ipi_id, + void *prdata, + void *data, + unsigned int len); +static int _sspm_recv_thread(void *data); + + +/***************************************************************************** + * external variable declaration + *****************************************************************************/ +int sspm_buf_available; +EXPORT_SYMBOL(sspm_buf_available); + + +/***************************************************************************** + * internal variable declaration + *****************************************************************************/ +static unsigned int ridx, widx, wlen; +static unsigned int recv_buf[4]; +static unsigned int ackdata; +static unsigned int rdata; +static unsigned int log_size; +static struct task_struct *_sspm_recv_task; +static int sspm_ipi_thread_started; +static int sspm_buffer_dumping; +static int sspm_recv_thread_comp; +static int sspm_run_mode = SSPM_RUN_NORMAL; + + + +/***************************************************************************** + * internal function ipmlement + *****************************************************************************/ +void start_sspm_ipi_recv_thread() +{ + int ret = 0; + + if (sspm_ipidev_symbol == NULL) { + sspm_ipidev_symbol = (struct mtk_ipi_device *)symbol_get(sspm_ipidev); + } + + if (sspm_ipidev_symbol == NULL) { + return; + } + + // tinysys send ipi to APSYS + ret = mtk_ipi_register(sspm_ipidev_symbol, IPIR_C_MET, _met_ipi_cb, + NULL, (void *)&recv_buf); + if (ret) { + PR_BOOTMSG("[MET] ipi_register:%d failed:%d\n", IPIR_C_MET, ret); + } else { + PR_BOOTMSG("mtk_ipi_register IPIR_C_MET success \n"); + } + + // APSYS send ipi to tinysys + ret = mtk_ipi_register(sspm_ipidev_symbol, IPIS_C_MET, NULL, + NULL, (void *)&ackdata); + if (ret) { + pr_debug("[MET] ipi_register:%d failed:%d\n", IPIS_C_MET, ret); + } else { + PR_BOOTMSG("mtk_ipi_register IPIS_C_MET success \n"); + } + + if (sspm_ipi_thread_started != 1) { + sspm_recv_thread_comp = 0; + _sspm_recv_task = kthread_run(_sspm_recv_thread, + NULL, "sspmsspm_recv"); + if (IS_ERR(_sspm_recv_task)) { + pr_debug("MET: Can not create sspmsspm_recv\n"); + } else { + sspm_ipi_thread_started = 1; + } + } +} + + +void stop_sspm_ipi_recv_thread() +{ + if (_sspm_recv_task) { + sspm_recv_thread_comp = 1; + + if (sspm_ipidev_symbol) { + // tinysys send ipi to APSYS + mtk_ipi_unregister(sspm_ipidev_symbol, IPIR_C_MET); + // APSYS send ipi to tinysys + mtk_ipi_unregister(sspm_ipidev_symbol, IPIS_C_MET); + } + + kthread_stop(_sspm_recv_task); + _sspm_recv_task = NULL; + sspm_ipi_thread_started = 0; + } +} + + +void sspm_start(void) +{ + int ret = 0; + unsigned int rdata = 0; + unsigned int ipi_buf[4]; + const char* platform_name = NULL; + unsigned int platform_id = 0; + + /* clear DRAM buffer */ + if (sspm_log_virt_addr != NULL) { + memset_io((void *)sspm_log_virt_addr, 0, sspm_buffer_size); + } else { + return; + } + + platform_name = met_get_platform(); + if (platform_name) { + char buf[5]; + + memset(buf, 0x0, 5); + memcpy(buf, &platform_name[2], 4); + + ret = kstrtouint(buf, 10, &platform_id); + } + + /* send DRAM physical address */ + ipi_buf[0] = MET_MAIN_ID | MET_BUFFER_INFO; + ipi_buf[1] = (unsigned int)sspm_log_phy_addr; /* address */ + if (ret == 0) + ipi_buf[2] = platform_id; + else + ipi_buf[2] = 0; + + ipi_buf[3] = 0; + ret = met_ipi_to_sspm_command(ipi_buf, 0, &rdata, 1); + + /* start ondiemet now */ + ipi_buf[0] = MET_MAIN_ID | MET_OP | MET_OP_START; + ipi_buf[1] = ondiemet_module[ONDIEMET_SSPM] ; + ipi_buf[2] = SSPM_LOG_FILE; + ipi_buf[3] = SSPM_RUN_NORMAL; + ret = met_ipi_to_sspm_command(ipi_buf, 0, &rdata, 1); +} + + +void sspm_stop(void) +{ + int ret = 0; + unsigned int rdata = 0; + unsigned int ipi_buf[4]; + unsigned int chip_id = 0; + + chip_id = met_get_chip_id(); + if (sspm_buf_available == 1) { + ipi_buf[0] = MET_MAIN_ID | MET_OP | MET_OP_STOP; + ipi_buf[1] = chip_id; + ipi_buf[2] = 0; + ipi_buf[3] = 0; + ret = met_ipi_to_sspm_command(ipi_buf, 0, &rdata, 1); + } +} + + +void sspm_extract(void) +{ + int ret; + unsigned int rdata; + unsigned int ipi_buf[4]; + int count; + + count = 20; + if (sspm_buf_available == 1) { + while ((sspm_buffer_dumping == 1) && (count != 0)) { + msleep(50); + count--; + } + ipi_buf[0] = MET_MAIN_ID | MET_OP | MET_OP_EXTRACT; + ipi_buf[1] = 0; + ipi_buf[2] = 0; + ipi_buf[3] = 0; + ret = met_ipi_to_sspm_command(ipi_buf, 0, &rdata, 1); + } + + if (sspm_run_mode == SSPM_RUN_NORMAL) { + ondiemet_module[ONDIEMET_SSPM] = 0; + } +} + + +void sspm_flush(void) +{ + int ret; + unsigned int rdata; + unsigned int ipi_buf[4]; + + if (sspm_buf_available == 1) { + ipi_buf[0] = MET_MAIN_ID | MET_OP | MET_OP_FLUSH; + ipi_buf[1] = 0; + ipi_buf[2] = 0; + ipi_buf[3] = 0; + ret = met_ipi_to_sspm_command((void *)ipi_buf, 0, &rdata, 1); + } + + if (sspm_run_mode == SSPM_RUN_NORMAL) { + ondiemet_module[ONDIEMET_SSPM] = 0; + } +} + + +int met_ipi_to_sspm_command( + unsigned int *buffer, + int slot, + unsigned int *retbuf, + int retslot) +{ + int ret = 0; + + if (sspm_ipidev_symbol == NULL) { + PR_BOOTMSG("%s\n", __FUNCTION__); + return -1; + } + + ret = mtk_ipi_send_compl(sspm_ipidev_symbol, IPIS_C_MET, IPI_SEND_WAIT, + (void*)buffer, slot, 2000); + *retbuf = ackdata; + + if (ret != 0) { + PR_BOOTMSG("%s 0x%X, 0x%X, 0x%X, 0x%X\n", __FUNCTION__, + buffer[0], buffer[1], buffer[2], buffer[3]); + pr_debug("met_ipi_to_sspm_command error(%d)\n", ret); + } + + return ret; +} +EXPORT_SYMBOL(met_ipi_to_sspm_command); + + +int met_ipi_to_sspm_command_async( + unsigned int *buffer, + int slot, + unsigned int *retbuf, + int retslot) +{ + int ret = 0; + + if(sspm_ipidev_symbol == NULL) { + PR_BOOTMSG("%s\n", __FUNCTION__); + return -1; + } + + ret = mtk_ipi_send(sspm_ipidev_symbol, IPIS_C_MET, IPI_SEND_WAIT, + (void*)buffer, slot, 2000); + *retbuf = ackdata; + + if (ret != 0) { + PR_BOOTMSG("%s 0x%X, 0x%X, 0x%X, 0x%X\n", __FUNCTION__, + buffer[0], buffer[1], buffer[2], buffer[3]); + pr_debug("met_ipi_to_sspm_command error(%d)\n", ret); + } + + return ret; +} +EXPORT_SYMBOL(met_ipi_to_sspm_command_async); + + +/***************************************************************************** + * internal function ipmlement + *****************************************************************************/ +static void _log_done_cb(const void *p) +{ + unsigned int ret; + unsigned int rdata = 0; + unsigned int ipi_buf[4]; + unsigned int opt = (p != NULL); + + if (opt == 0) { + ipi_buf[0] = MET_MAIN_ID | MET_RESP_AP2MD; + ipi_buf[1] = MET_DUMP_BUFFER; + ipi_buf[2] = 0; + ipi_buf[3] = 0; + ret = met_ipi_to_sspm_command((void *)ipi_buf, 0, &rdata, 1); + } +} + + +static int _met_ipi_cb(unsigned int ipi_id, void *prdata, void *data, unsigned int len) +{ + unsigned int *cmd_buf = (unsigned int *)data; + unsigned int cmd; + int ret; + + if (sspm_recv_thread_comp == 1) { + PR_BOOTMSG("%s %d\n", __FUNCTION__, __LINE__); + return 0; + } + + cmd = cmd_buf[0] & MET_SUB_ID_MASK; + switch (cmd) { + case MET_DUMP_BUFFER: /* mbox 1: start index; 2: size */ + sspm_buffer_dumping = 1; + ridx = cmd_buf[1]; + widx = cmd_buf[2]; + log_size = cmd_buf[3]; + break; + + case MET_CLOSE_FILE: /* no argument */ + /* do close file */ + ridx = cmd_buf[1]; + widx = cmd_buf[2]; + if (widx < ridx) { /* wrapping occurs */ + wlen = log_size - ridx; + sspm_log_req_enq((char *)(sspm_log_virt_addr) + (ridx << 2), + wlen * 4, _log_done_cb, (void *)1); + sspm_log_req_enq((char *)(sspm_log_virt_addr), + widx * 4, _log_done_cb, (void *)1); + } else { + wlen = widx - ridx; + sspm_log_req_enq((char *)(sspm_log_virt_addr) + (ridx << 2), + wlen * 4, _log_done_cb, (void *)1); + } + ret = sspm_log_stop(); + break; + + case MET_RESP_MD2AP: + break; + + default: + break; + } + return 0; +} + + +static int _sspm_recv_thread(void *data) +{ + int ret = 0; + unsigned int cmd = 0; + + do { + ret = mtk_ipi_recv_reply(sspm_ipidev_symbol, IPIR_C_MET, (void *)&rdata, 1); + if (ret) { + pr_debug("[MET] ipi_register:%d failed:%d\n", IPIR_C_MET, ret); + } + + if (sspm_recv_thread_comp == 1) { + while (!kthread_should_stop()) { + ; + } + return 0; + } + + cmd = recv_buf[0] & MET_SUB_ID_MASK; + switch (cmd) { + case MET_DUMP_BUFFER: /* mbox 1: start index; 2: size */ + if (widx < ridx) { /* wrapping occurs */ + wlen = log_size - ridx; + sspm_log_req_enq((char *)(sspm_log_virt_addr) + (ridx << 2), + wlen * 4, _log_done_cb, (void *)1); + sspm_log_req_enq((char *)(sspm_log_virt_addr), + widx * 4, _log_done_cb, (void *)0); + } else { + wlen = widx - ridx; + sspm_log_req_enq((char *)(sspm_log_virt_addr) + (ridx << 2), + wlen * 4, _log_done_cb, (void *)0); + } + break; + + case MET_CLOSE_FILE: /* no argument */ + if (sspm_run_mode == SSPM_RUN_CONTINUOUS) { + /* clear the memory */ + memset_io((void *)sspm_log_virt_addr, 0, + sspm_buffer_size); + /* re-start ondiemet again */ + sspm_start(); + } + break; + + case MET_RESP_MD2AP: + sspm_buffer_dumping = 0; + break; + + default: + break; + } + } while (!kthread_should_stop()); + + return 0; +} + diff --git a/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/sspm/sspm_met_ipi_handle.h b/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/sspm/sspm_met_ipi_handle.h new file mode 100644 index 0000000000000000000000000000000000000000..c0c3f60198654ef24a7eeec3b34776af791d92aa --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/sspm/sspm_met_ipi_handle.h @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#ifndef __SSPM_MET_IPI_HANDLE_H__ +#define __SSPM_MET_IPI_HANDLE_H__ +/***************************************************************************** + * headers + *****************************************************************************/ + + +/***************************************************************************** + * define declaration + *****************************************************************************/ + + +/***************************************************************************** + * struct & enum declaration + *****************************************************************************/ + + +/***************************************************************************** + * external function declaration + *****************************************************************************/ +void start_sspm_ipi_recv_thread(void); +void stop_sspm_ipi_recv_thread(void); + +void sspm_start(void); +void sspm_stop(void); +void sspm_extract(void); +void sspm_flush(void); + +int met_ipi_to_sspm_command( + unsigned int *buffer, + int slot, + unsigned int *retbuf, + int retslot); +int met_ipi_to_sspm_command_async( + unsigned int *buffer, + int slot, + unsigned int *retbuf, + int retslot); + + +/***************************************************************************** + * external variable declaration + *****************************************************************************/ + + +#endif /* __SSPM_MET_IPI_HANDLE_H__ */ diff --git a/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/sspm/sspm_met_log.c b/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/sspm/sspm_met_log.c new file mode 100644 index 0000000000000000000000000000000000000000..633b7dade9711d9283d29002b1ca7c51b387f9af --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/sspm/sspm_met_log.c @@ -0,0 +1,695 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ +/***************************************************************************** + * headers + *****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* symbol_get */ + +#include "sspm_reservedmem.h" +#include "sspm_reservedmem_define.h" + +#include "interface.h" + +#include "sspm_met_log.h" +#include "sspm_met_ipi_handle.h" + + +/***************************************************************************** + * define declaration + *****************************************************************************/ +#define SSPM_LOG_REQ 1 +#define SSPM_LOG_STOP 2 + +#define PID_NONE (-1) + +#define SSPM_LOG_STOP_MODE 0 +#define SSPM_LOG_RUN_MODE 1 +#define SSPM_LOG_DEBUG_MODE 2 + +#define _sspm_log_req_init(req, cmd, s, n, pf, p) \ + do { \ + INIT_LIST_HEAD(&req->list); \ + req->cmd_type = cmd; \ + req->src = s; \ + req->num = n; \ + req->on_fini_cb = pf; \ + req->param = p; \ + } while (0) + +#define _sspm_log_req_fini(req) \ + do { \ + if (req->on_fini_cb) \ + req->on_fini_cb(req->param); \ + kfree(req); \ + } while (0) + + +/***************************************************************************** + * struct & enum declaration + *****************************************************************************/ +struct sspm_log_req_q_t { + struct list_head listq; + struct mutex lockq; + struct completion new_evt_comp; + int closeq_flag; +} sspm_log_req_q; + +struct sspm_log_req { + struct list_head list; + int cmd_type; + const char *src; + size_t num; + + void (*on_fini_cb)(const void *p); + const void *param; +}; + + +/***************************************************************************** + * external function declaration + *****************************************************************************/ + + +/***************************************************************************** + * internal function declaration + *****************************************************************************/ +static void _log_stop_cb(const void *p); +static int _down_freezable_interruptible(struct completion *comp); + +static void _sspm_log_req_q_init(struct sspm_log_req_q_t *q); +static void _sspm_log_req_undeq(struct sspm_log_req *req); +static int _sspm_log_req_enq(struct sspm_log_req *req); +static struct sspm_log_req *_sspm_log_req_deq(void); +static void _sspm_log_req_open(void); +static int _sspm_log_req_closed(void); +static int _sspm_log_req_working(void); +static void *_sspm_trace_seq_next(struct seq_file *seqf, loff_t *offset); + +static void *sspm_trace_seq_start(struct seq_file *seqf, loff_t *offset); +static void sspm_trace_seq_stop(struct seq_file *seqf, void *p); +static void *sspm_trace_seq_next(struct seq_file *seqf, void *p, loff_t *offset); +static int sspm_trace_seq_show(struct seq_file *seqf, void *p); +static int sspm_trace_open(struct inode *inode, struct file *fp); + +static ssize_t ondiemet_log_write_store( + struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count); +static ssize_t ondiemet_log_run_show( + struct device *dev, + struct device_attribute *attr, + char *buf); +static ssize_t ondiemet_log_run_store( + struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count); + + +/***************************************************************************** + * external variable declaration + *****************************************************************************/ +void *sspm_log_virt_addr; + +#if IS_ENABLED(CONFIG_MTK_GMO_RAM_OPTIMIZE) || IS_ENABLED(CONFIG_MTK_MET_MEM_ALLOC) +dma_addr_t sspm_log_phy_addr; +#else +unsigned int sspm_log_phy_addr; +#endif + +unsigned int sspm_buffer_size; + +extern int sspm_buf_available; + + +/***************************************************************************** + * internal variable declaration + *****************************************************************************/ +static int sspm_trace_run; +static pid_t trace_owner_pid = PID_NONE; + +static struct mutex lock_tracef; +static struct mutex lock_trace_owner_pid; + +static struct completion log_start_comp; +static struct completion log_stop_comp; + +static DEVICE_ATTR(ondiemet_log_write, 0220, NULL, ondiemet_log_write_store); +static DEVICE_ATTR(ondiemet_log_run, 0664, ondiemet_log_run_show, ondiemet_log_run_store);; + +static const struct seq_operations sspm_trace_seq_ops = { + .start = sspm_trace_seq_start, + .next = sspm_trace_seq_next, + .stop = sspm_trace_seq_stop, + .show = sspm_trace_seq_show +}; + +static const struct file_operations sspm_trace_fops = { + .owner = THIS_MODULE, + .open = sspm_trace_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release +}; + + +/***************************************************************************** + * external function ipmlement + *****************************************************************************/ +int sspm_log_init(struct device *dev) +{ + int ret = 0; +#ifdef ONDIEMET_MOUNT_DEBUGFS + struct dentry *d; + struct dentry *met_dir = NULL; +#else + struct proc_dir_entry *d; + struct proc_dir_entry *met_dir = NULL; +#endif + phys_addr_t (*get_size_sym)(unsigned int id) = NULL; + + met_dir = dev_get_drvdata(dev); + mutex_init(&lock_tracef); + _sspm_log_req_q_init(&sspm_log_req_q); + init_completion(&log_start_comp); + init_completion(&log_stop_comp); + mutex_init(&lock_trace_owner_pid); + +#ifdef ONDIEMET_MOUNT_DEBUGFS + d = debugfs_create_file("trace", 0600, met_dir, NULL, &sspm_trace_fops); + if (!d) { + PR_BOOTMSG("can not create devide node in debugfs: sspm_trace\n"); + return -ENOMEM; + } +#else + d = proc_create("trace", 0600, met_dir, &sspm_trace_fops); + if (!d) { + PR_BOOTMSG("can not create devide node in procfs: sspm_trace\n"); + return -ENOMEM; + } +#endif + + sspm_trace_run = _sspm_log_req_working(); + ret = device_create_file(dev, &dev_attr_ondiemet_log_run); + if (ret != 0) { + PR_BOOTMSG("can not create device node: sspm_log_run\n"); + return ret; + } + +#if IS_ENABLED(CONFIG_MTK_GMO_RAM_OPTIMIZE) || IS_ENABLED(CONFIG_MTK_MET_MEM_ALLOC) + sspm_log_virt_addr = dma_alloc_coherent(dev, 0x800000, + &sspm_log_phy_addr, GFP_KERNEL); + if (sspm_log_virt_addr) { + sspm_buffer_size = 0x800000; + sspm_buf_available = 1; + } else { + sspm_buf_available = 0; + } +#else + get_size_sym = symbol_get(sspm_reserve_mem_get_size); + if (get_size_sym) { + sspm_buffer_size = get_size_sym(MET_MEM_ID); + PR_BOOTMSG("sspm_buffer_size=%x \n", sspm_buffer_size); + } else { + PR_BOOTMSG("symbol_get sspm_reserve_mem_get_size failure\n"); + } + + if (sspm_buffer_size > 0) { + phys_addr_t (*get_phys_sym)(unsigned int id) = NULL; + phys_addr_t (*get_virt_sym)(unsigned int id) = NULL; + + get_phys_sym = symbol_get(sspm_reserve_mem_get_virt); + get_virt_sym = symbol_get(sspm_reserve_mem_get_phys); + if (get_phys_sym) { + sspm_log_virt_addr = (void*)get_phys_sym(MET_MEM_ID); + PR_BOOTMSG("sspm_log_virt_addr=%x \n", sspm_log_virt_addr); + } else { + PR_BOOTMSG("symbol_get sspm_reserve_mem_get_virt failure\n"); + } + if (get_virt_sym) { + sspm_log_phy_addr = get_virt_sym(MET_MEM_ID); + PR_BOOTMSG("sspm_log_phy_addr=%x \n", sspm_log_phy_addr); + } else { + PR_BOOTMSG("symbol_get sspm_reserve_mem_get_phys failure\n"); + } + sspm_buf_available = 1; + } else { + sspm_buf_available = 0; + } + +#endif /* CONFIG_MTK_GMO_RAM_OPTIMIZE */ + + start_sspm_ipi_recv_thread(); + + return 0; +} + + +int sspm_log_uninit(struct device *dev) +{ + stop_sspm_ipi_recv_thread(); + + if (sspm_log_virt_addr != NULL) { +#if IS_ENABLED(CONFIG_MTK_GMO_RAM_OPTIMIZE) || IS_ENABLED(CONFIG_MTK_MET_MEM_ALLOC) + dma_free_coherent(dev, sspm_buffer_size, sspm_log_virt_addr, + sspm_log_phy_addr); +#endif /* CONFIG_MTK_GMO_RAM_OPTIMIZE */ + sspm_log_virt_addr = NULL; + } + + device_remove_file(dev, &dev_attr_ondiemet_log_run); + return 0; +} + + +int sspm_log_start(void) +{ + int ret = 0; + + /* TODO: choose a better return value */ + if (_sspm_log_req_working()) { + return -EINVAL; + } + + if (!_sspm_log_req_closed()) { + ret = wait_for_completion_killable(&log_start_comp); + if (ret) { + return ret; + } + } + + _sspm_log_req_open(); + + return 0; +} + + +int sspm_log_stop(void) +{ + int ret = 0; + struct sspm_log_req *req = NULL; + + if (_sspm_log_req_closed()) { + return -EINVAL; + } + + req = kmalloc(sizeof(*req), GFP_KERNEL); + if (req == NULL) + return -1; + _sspm_log_req_init(req, SSPM_LOG_STOP, NULL, 0, _log_stop_cb, NULL); + + init_completion(&log_start_comp); + init_completion(&log_stop_comp); + + ret = _sspm_log_req_enq(req); + if (ret) { + return ret; + } + + return wait_for_completion_killable(&log_stop_comp); +} + + +int sspm_log_req_enq( + const char *src, size_t num, + void (*on_fini_cb)(const void *p), + const void *param) +{ + struct sspm_log_req *req = kmalloc(sizeof(*req), GFP_KERNEL); + + if (req == NULL) + return -1; + _sspm_log_req_init(req, SSPM_LOG_REQ, src, num, on_fini_cb, param); + return _sspm_log_req_enq(req); +} + + +int sspm_parse_num(const char *str, unsigned int *value, int len) +{ + int ret = 0; + + if (len <= 0) { + return -1; + } + + if ((len > 2) && ((str[0] == '0') && ((str[1] == 'x') || (str[1] == 'X')))) { + ret = kstrtouint(str, 16, value); + } else { + ret = kstrtouint(str, 10, value); + } + + if (ret != 0) { + return -1; + } + + return 0; +} + + +/***************************************************************************** + * internal function ipmlement + *****************************************************************************/ +static void _log_stop_cb(const void *p) +{ + complete(&log_start_comp); + complete(&log_stop_comp); +} + + +static int _down_freezable_interruptible(struct completion *comp) +{ + int ret = 0; + + freezer_do_not_count(); + ret = wait_for_completion_interruptible(comp); + freezer_count(); + + return ret; +} + + +static void _sspm_log_req_q_init(struct sspm_log_req_q_t *q) +{ + INIT_LIST_HEAD(&q->listq); + mutex_init(&q->lockq); + init_completion(&q->new_evt_comp); + q->closeq_flag = 1; +} + + +/* + undequeue is seen as a roll-back operation, + so it can be done even when the queue is closed +*/ +static void _sspm_log_req_undeq(struct sspm_log_req *req) +{ + mutex_lock(&sspm_log_req_q.lockq); + list_add(&req->list, &sspm_log_req_q.listq); + mutex_unlock(&sspm_log_req_q.lockq); + + complete(&sspm_log_req_q.new_evt_comp); +} + + +static int _sspm_log_req_enq(struct sspm_log_req *req) +{ + mutex_lock(&sspm_log_req_q.lockq); + if (sspm_log_req_q.closeq_flag) { + mutex_unlock(&sspm_log_req_q.lockq); + return -EBUSY; + } + + list_add_tail(&req->list, &sspm_log_req_q.listq); + if (req->cmd_type == SSPM_LOG_STOP) { + sspm_log_req_q.closeq_flag = 1; + } + mutex_unlock(&sspm_log_req_q.lockq); + + complete(&sspm_log_req_q.new_evt_comp); + + return 0; +} + + +static struct sspm_log_req *_sspm_log_req_deq(void) +{ + struct sspm_log_req *ret_req; + + if (_down_freezable_interruptible(&sspm_log_req_q.new_evt_comp)) { + return NULL; + } + + mutex_lock(&sspm_log_req_q.lockq); + ret_req = list_entry(sspm_log_req_q.listq.next, struct sspm_log_req, list); + list_del_init(&ret_req->list); + mutex_unlock(&sspm_log_req_q.lockq); + + return ret_req; +} + + +static void _sspm_log_req_open(void) +{ + mutex_lock(&sspm_log_req_q.lockq); + sspm_log_req_q.closeq_flag = 0; + mutex_unlock(&sspm_log_req_q.lockq); +} + + +static int _sspm_log_req_closed(void) +{ + int ret = 0; + + mutex_lock(&sspm_log_req_q.lockq); + ret = sspm_log_req_q.closeq_flag && list_empty(&sspm_log_req_q.listq); + mutex_unlock(&sspm_log_req_q.lockq); + + return ret; +} + + +static int _sspm_log_req_working(void) +{ + int ret = 0; + + mutex_lock(&sspm_log_req_q.lockq); + ret = !sspm_log_req_q.closeq_flag; + mutex_unlock(&sspm_log_req_q.lockq); + + return ret; +} + + +static void *_sspm_trace_seq_next(struct seq_file *seqf, loff_t *offset) +{ + struct sspm_log_req *next_req; + + if (sspm_trace_run == SSPM_LOG_DEBUG_MODE) { + PR_BOOTMSG("_sspm_trace_seq_next: pid: %d\n", current->pid); + } + + if (_sspm_log_req_closed()) { + return NULL; + } + + next_req = _sspm_log_req_deq(); + if (next_req == NULL) { + return NULL; + } + + if (next_req->cmd_type == SSPM_LOG_STOP) { + _sspm_log_req_fini(next_req); + return NULL; + } + + return (void *) next_req; +} + + +static void *sspm_trace_seq_start(struct seq_file *seqf, loff_t *offset) +{ + void *ret; + + if (sspm_trace_run == SSPM_LOG_DEBUG_MODE) { + PR_BOOTMSG("sspm_trace_seq_start: locked_pid: %d, pid: %d, offset: %llu\n", + trace_owner_pid, current->pid, *offset); + } + + if (!mutex_trylock(&lock_tracef)) { + return NULL; + } + + mutex_lock(&lock_trace_owner_pid); + trace_owner_pid = current->pid; + current->flags |= PF_NOFREEZE; + mutex_unlock(&lock_trace_owner_pid); + + ret = _sspm_trace_seq_next(seqf, offset); + + return ret; +} + + +static void sspm_trace_seq_stop(struct seq_file *seqf, void *p) +{ + if (sspm_trace_run == SSPM_LOG_DEBUG_MODE) { + PR_BOOTMSG("sspm_trace_seq_stop: pid: %d\n", current->pid); + } + + mutex_lock(&lock_trace_owner_pid); + if (current->pid == trace_owner_pid) { + trace_owner_pid = PID_NONE; + mutex_unlock(&lock_tracef); + } + mutex_unlock(&lock_trace_owner_pid); +} + + +static void *sspm_trace_seq_next(struct seq_file *seqf, void *p, loff_t *offset) +{ + if (sspm_trace_run == SSPM_LOG_DEBUG_MODE) { + PR_BOOTMSG("sspm_trace_seq_next: pid: %d\n", current->pid); + } + (*offset)++; + return _sspm_trace_seq_next(seqf, offset); +} + + +static int sspm_trace_seq_show(struct seq_file *seqf, void *p) +{ + struct sspm_log_req *req = (struct sspm_log_req *)p; + size_t l_sz; + size_t r_sz; + struct sspm_log_req *l_req; + struct sspm_log_req *r_req; + int ret = 0; + + if (sspm_trace_run == SSPM_LOG_DEBUG_MODE) { + PR_BOOTMSG("sspm_trace_seq_show: pid: %d\n", current->pid); + } + + if (req->num >= seqf->size) { + l_req = kmalloc(sizeof(*req), GFP_KERNEL); + if (l_req == NULL) + return -1; + + r_req = req; + + l_sz = seqf->size >> 1; + r_sz = req->num - l_sz; + _sspm_log_req_init(l_req, SSPM_LOG_REQ, req->src, l_sz, NULL, NULL); + _sspm_log_req_init(r_req, SSPM_LOG_REQ, req->src + l_sz, + r_sz, req->on_fini_cb, req->param); + + _sspm_log_req_undeq(r_req); + req = l_req; + + if (sspm_trace_run == SSPM_LOG_DEBUG_MODE) { + PR_BOOTMSG("sspm_trace_seq_show: split request\n"); + } + } + + ret = seq_write(seqf, req->src, req->num); + if (ret) { + /* check if seq_file buffer overflows */ + if (seqf->count == seqf->size) { + _sspm_log_req_undeq(req); + } else { + if (sspm_trace_run == SSPM_LOG_DEBUG_MODE) { + PR_BOOTMSG("sspm_trace_seq_show: \ + reading trace record failed, \ + some data may be lost or corrupted\n"); + } + _sspm_log_req_fini(req); + } + return 0; + } + + _sspm_log_req_fini(req); + return 0; +} + + +static int sspm_trace_open(struct inode *inode, struct file *fp) +{ + return seq_open(fp, &sspm_trace_seq_ops); +} + + +static ssize_t ondiemet_log_write_store( + struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + char *plog = NULL; + + plog = kmalloc_array(count, sizeof(*plog), GFP_KERNEL); + if (!plog) { + /* TODO: use a better error code */ + return -EINVAL; + } + memcpy(plog, buf, count); + + mutex_lock(&dev->mutex); + sspm_log_req_enq(plog, strnlen(plog, count), kfree, plog); + mutex_unlock(&dev->mutex); + + return count; +} + + +static ssize_t ondiemet_log_run_show( + struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int sz; + + mutex_lock(&dev->mutex); + sz = snprintf(buf, PAGE_SIZE, "%d\n", sspm_trace_run); + mutex_unlock(&dev->mutex); + return sz; +} + + +static ssize_t ondiemet_log_run_store( + struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + int ret = 0; + int prev_run_state; + + mutex_lock(&dev->mutex); + prev_run_state = sspm_trace_run; + if (kstrtoint(buf, 10, &sspm_trace_run) != 0) { + return -EINVAL; + } + + if (sspm_trace_run <= SSPM_LOG_STOP_MODE) { + sspm_trace_run = SSPM_LOG_STOP_MODE; + sspm_log_stop(); + + if (prev_run_state == SSPM_LOG_DEBUG_MODE) { + device_remove_file(dev, &dev_attr_ondiemet_log_write); + } + } else if (sspm_trace_run == SSPM_LOG_RUN_MODE) { + sspm_trace_run = SSPM_LOG_RUN_MODE; + sspm_log_start(); + + if (prev_run_state == SSPM_LOG_DEBUG_MODE) { + device_remove_file(dev, &dev_attr_ondiemet_log_write); + } + } else { + sspm_trace_run = SSPM_LOG_DEBUG_MODE; + sspm_log_start(); + + if (prev_run_state != SSPM_LOG_DEBUG_MODE) { + ret = device_create_file(dev, &dev_attr_ondiemet_log_write); + if (ret != 0) { + PR_BOOTMSG("can not create device node: \ + sspm_log_write\n"); + } + } + } + mutex_unlock(&dev->mutex); + + return count; +} + diff --git a/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/sspm/sspm_met_log.h b/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/sspm/sspm_met_log.h new file mode 100644 index 0000000000000000000000000000000000000000..b06632284f348314703aad0a53d0e68995b9d3a0 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/sspm/sspm_met_log.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#ifndef _ONDIEMET_LOG_H_ +#define _ONDIEMET_LOG_H_ +/***************************************************************************** + * headers + *****************************************************************************/ +#include +#if IS_ENABLED(CONFIG_MTK_GMO_RAM_OPTIMIZE) || IS_ENABLED(CONFIG_MTK_MET_MEM_ALLOC) +#include +#endif + + +/***************************************************************************** + * define declaration + *****************************************************************************/ + + +/***************************************************************************** + * struct & enum declaration + *****************************************************************************/ + + +/***************************************************************************** + * external function declaration + *****************************************************************************/ +int sspm_log_init(struct device *dev); +int sspm_log_uninit(struct device *dev); +int sspm_log_start(void); +int sspm_log_stop(void); + +int sspm_log_req_enq( + const char *src, size_t num, + void (*on_fini_cb)(const void *p), + const void *param); +int sspm_parse_num(const char *str, unsigned int *value, int len); + + +/***************************************************************************** + * external variable declaration + *****************************************************************************/ +extern void *sspm_log_virt_addr; +#if IS_ENABLED(CONFIG_MTK_GMO_RAM_OPTIMIZE) || IS_ENABLED(CONFIG_MTK_MET_MEM_ALLOC) +extern dma_addr_t sspm_log_phy_addr; +#else +extern unsigned int sspm_log_phy_addr; +#endif +extern unsigned int sspm_buffer_size; + +#endif /* _ONDIEMET_LOG_H_ */ diff --git a/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/sspm/sspm_met_smi.c b/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/sspm/sspm_met_smi.c new file mode 100644 index 0000000000000000000000000000000000000000..c930683a220ffabb2b91b8476a1dd98d554ee8fc --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/sspm/sspm_met_smi.c @@ -0,0 +1,569 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ +/***************************************************************************** + * headers + *****************************************************************************/ +#include +#include +#include +#include + +#ifdef USE_KERNEL_SYNC_WRITE_H +#include +#else +#include "sync_write.h" +#endif + +#ifdef USE_KERNEL_MTK_IO_H +#include +#else +#include "mtk_io.h" +#endif + +#include "met_drv.h" +#include "trace.h" +#include "core_plf_trace.h" +#include "core_plf_init.h" +#include "interface.h" +#include "mtk_typedefs.h" + +#include "tinysys_mgr.h" +#include "tinysys_sspm.h" + +#include "sspm_mtk_smi.h" +#include "sspm_met_smi.h" +#include "sspm_met_smi_name.h" +#include "sspm_met_log.h" +#include "sspm_met_ipi_handle.h" /* for met_ipi_to_sspm_command */ + + +/***************************************************************************** + * define declaration + *****************************************************************************/ +#define MET_SMI_DEBUG 1 +#define MET_SMI_BUF_SIZE 128 +#define MET_SMI_DEBUGBUF_SIZE 512 +#define NPORT_IN_PM 4 + +// SMI Encode -- Master +#ifdef SMI_MASTER_8BIT +// bit15~bit16 +#define MET_SMI_BIT_REQ_LARB 15 +// bit13~bit14 +#define MET_SMI_BIT_REQ_COMM 13 +// bit12:Parallel Mode */ +#define MET_SMI_BIT_PM 12 +// bit9~bit8:Destination */ +#define MET_SMI_BIT_DST 10 +/* bit5~bit4:Request Type */ +#define MET_SMI_BIT_REQ 8 +/* bit3~bit0:Master */ +#define MET_SMI_BIT_MASTER 0 +#else +// bit15~bit16 +#define MET_SMI_BIT_REQ_LARB 15 +// bit13~bit14 +#define MET_SMI_BIT_REQ_COMM 13 +// bit12:Parallel Mode */ +#define MET_SMI_BIT_PM 12 +// bit9~bit8:Destination */ +#define MET_SMI_BIT_DST 8 +/* bit5~bit4:Request Type */ +#define MET_SMI_BIT_REQ 4 +/* bit3~bit0:Master */ +#define MET_SMI_BIT_MASTER 0 +#endif + +// SMI Encode -- Metadata +/* bit6~bit5:RW */ +#define MET_SMI_BIT_RW 5 +/* bit4~bit0:Port */ +#define MET_SMI_BIT_PORT 0 + +/* +*declare smi: larb0-larbn: +*real define table in met_smi_name.h +*/ +/*MET_SMI_DESC_DEFINE();*/ +/**/ + +/*======================================================================*/ +/* Global variable definitions */ +/*======================================================================*/ +#define MAX_CONFIG_ARRAY_SIZE 20 +struct metdevice met_sspm_smi; +struct met_smi_conf smi_conf_array[MAX_CONFIG_ARRAY_SIZE]; +int smi_array_index; + +//static unsigned int smi_met_larb_number = SMI_LARB_NUMBER; +static int count = SMI_LARB_NUMBER + SMI_COMM_NUMBER; +static struct kobject *kobj_smi; + +/* Request type */ +static unsigned int larb_req_type = SMI_REQ_ALL; +static unsigned int comm_req_type = SMI_REQ_ALL; + +/* Parallel mode */ +static unsigned int parallel_mode; + +/* Read/Write type in parallel mode */ +static int comm_pm_rw_type[SMI_COMM_NUMBER][NPORT_IN_PM]; +/* Error message */ +static char err_msg[MET_SMI_BUF_SIZE]; +static char debug_msg[MET_SMI_DEBUGBUF_SIZE]; + +/*======================================================================*/ +/* KOBJ Declarations */ +/*======================================================================*/ +/* KOBJ: larb_req_type */ +DECLARE_KOBJ_ATTR_INT(larb_req_type, larb_req_type); + +/* KOBJ : comm_req_type */ +DECLARE_KOBJ_ATTR_INT(comm_req_type, comm_req_type); + +/* KOBJ : enable_parallel_mode */ +DECLARE_KOBJ_ATTR_INT(enable_parallel_mode, parallel_mode); + +/* KOBJ : pm_rwtypeX */ +DECLARE_KOBJ_ATTR_STR_LIST_ITEM( + pm_rwtype, + KOBJ_ITEM_LIST( + {SMI_READ_ONLY, "READ"}, + {SMI_WRITE_ONLY, "WRITE"} + ) +); +DECLARE_KOBJ_ATTR_STR_LIST(pm_rwtype1, comm_pm_rw_type[0][0], pm_rwtype); +DECLARE_KOBJ_ATTR_STR_LIST(pm_rwtype2, comm_pm_rw_type[0][1], pm_rwtype); +DECLARE_KOBJ_ATTR_STR_LIST(pm_rwtype3, comm_pm_rw_type[0][2], pm_rwtype); +DECLARE_KOBJ_ATTR_STR_LIST(pm_rwtype4, comm_pm_rw_type[0][3], pm_rwtype); + +/* KOBJ : count */ +DECLARE_KOBJ_ATTR_RO_INT(count, count); + +/* KOBJ : err_msg */ +DECLARE_KOBJ_ATTR_RO_STR(err_msg, err_msg); + +#define KOBJ_ATTR_LIST \ +do { \ + KOBJ_ATTR_ITEM(larb_req_type); \ + KOBJ_ATTR_ITEM(comm_req_type); \ + KOBJ_ATTR_ITEM(enable_parallel_mode); \ + KOBJ_ATTR_ITEM(pm_rwtype1); \ + KOBJ_ATTR_ITEM(pm_rwtype2); \ + KOBJ_ATTR_ITEM(pm_rwtype3); \ + KOBJ_ATTR_ITEM(pm_rwtype4); \ + KOBJ_ATTR_ITEM(count); \ + KOBJ_ATTR_ITEM(err_msg); \ +} while (0) + +/*======================================================================*/ +/* SMI Operations */ +/*======================================================================*/ +static void met_smi_debug(char *debug_log) +{ + MET_TRACE("%s", debug_log); +} + +static int do_smi(void) +{ + return met_sspm_smi.mode; +} + +static void smi_init_value(void) +{ + int i = 0; + + smi_array_index = 0; + for (i = 0; i < MAX_CONFIG_ARRAY_SIZE; i++) { + smi_conf_array[i].master = 0; + smi_conf_array[i].port[0] = -1; + smi_conf_array[i].port[1] = -1; + smi_conf_array[i].port[2] = -1; + smi_conf_array[i].port[3] = -1; + smi_conf_array[i].rwtype[0] = SMI_RW_ALL; + smi_conf_array[i].rwtype[1] = SMI_RW_ALL; + smi_conf_array[i].rwtype[2] = SMI_RW_ALL; + smi_conf_array[i].rwtype[3] = SMI_RW_ALL; + smi_conf_array[i].desttype = SMI_DEST_EMI; + smi_conf_array[i].reqtype = SMI_REQ_ALL; + } +} + +static int smi_init(void) +{ + int i = 0; + + if (smi_array_index < MAX_CONFIG_ARRAY_SIZE) { + for (i = 0; i < (smi_array_index + 1); i++) { + snprintf(debug_msg, MET_SMI_DEBUGBUF_SIZE, + "===SMI config: parallel_mode = %d, master = %d, \ + port0 = %d, port1 = %d, port2 = %d, port3 = %d, \ + rwtype0 = %d, rwtype1 = %d, rwtype2 = %d, rwtype3 = %d, \ + desttype = %d, reqtype(larb) = %d, reqtype(comm) = %d\n", + parallel_mode, + smi_conf_array[i].master, + smi_conf_array[i].port[0], + smi_conf_array[i].port[1], + smi_conf_array[i].port[2], + smi_conf_array[i].port[3], + smi_conf_array[i].rwtype[0], + smi_conf_array[i].rwtype[1], + smi_conf_array[i].rwtype[2], + smi_conf_array[i].rwtype[3], + smi_conf_array[i].desttype, + smi_conf_array[i].reqtype >> MET_SMI_BIT_REQ_LARB, + smi_conf_array[i].reqtype >> MET_SMI_BIT_REQ_COMM); + met_smi_debug(debug_msg); + } + } else { + met_smi_debug("smi_init() FAIL : smi_array_index overflow\n"); + return -1; + } + + return 0; +} + +static int met_smi_create(struct kobject *parent) +{ +#define KOBJ_ATTR_ITEM(attr_name) \ +do { \ + ret = sysfs_create_file(kobj_smi, &attr_name##_attr.attr); \ + if (ret != 0) { \ + pr_debug("Failed to create " #attr_name " in sysfs\n"); \ + return ret; \ + } \ +} while (0) + + int j = 0; + int ret = 0; + + pr_debug("met_smi_create\n \ + met_smi_create\n \ + met_smi_create\n \ + met_smi_create\n \ + met_smi_create\n \ + met_smi_create\n \ + met_smi_create\n \ + met_smi_create\n"); + + /* Init. */ + + smi_init_value(); + + larb_req_type = SMI_REQ_ALL; + comm_req_type = SMI_REQ_ALL; + parallel_mode = 0; + + for (j = 0; j < NPORT_IN_PM; j++) + comm_pm_rw_type[0][j] = SMI_READ_ONLY; + + kobj_smi = parent; + + KOBJ_ATTR_LIST; + + return ret; + +#undef KOBJ_ATTR_ITEM +} + +void met_smi_delete(void) +{ +#define KOBJ_ATTR_ITEM(attr_name) \ + sysfs_remove_file(kobj_smi, &attr_name##_attr.attr) + + + if (kobj_smi != NULL) { + KOBJ_ATTR_LIST; + kobj_smi = NULL; + } + +#undef KOBJ_ATTR_ITEM +} + +static void met_smi_start(void) +{ + if (do_smi()) { + if (smi_init() != 0) { + met_sspm_smi.mode = 0; + smi_init_value(); + return; + } + } +} + +static void met_smi_stop(void) +{ + int j = 0; + + if (do_smi()) { + /* Reset */ + smi_init_value(); + + larb_req_type = SMI_REQ_ALL; + comm_req_type = SMI_REQ_ALL; + parallel_mode = 0; + + for (j = 0; j < NPORT_IN_PM; j++) + comm_pm_rw_type[0][j] = SMI_READ_ONLY; + + met_sspm_smi.mode = 0; + } + return ; +} + +static char help[] = +" --smi=master:port:rw:dest:bus monitor specified SMI banwidth\n" +" --smi=master:p1[:p2][:p3][:p4] monitor parallel mode\n"; + +static int smi_print_help(char *buf, int len) +{ + return snprintf(buf, PAGE_SIZE, "%s", help); +} + +static int get_num(const char *__restrict__ dc, int *pValue) +{ + int value = 0; + int digit = 0; + int i = 0; + + while (((*dc) >= '0') && ((*dc) <= '9')) { + digit = (int)(*dc - '0'); + value = value * 10 + digit; + dc++; + i++; + } + + if (i == 0) + return 0; + *pValue = value; + + return i; +} + +/* + * There are serveal cases as follows: + * + * 1. "met-cmd --start --smi=master:port:rwtype:desttype:bustype" => Can assign multiple master + * 2. "met-cmd --start --smi=master:port[:port1][:port2][:port3]" ==> parael mode + * + */ +static int smi_process_argument(const char *__restrict__ arg, int len) +{ + int args[5] = {0}; + int i = 0; + int array_index = 0; + int idx = 0; + unsigned int smi_conf_index = 0; + struct met_smi_conf smi_conf; + + uint32_t ipi_buf[4] = {0}; + uint32_t ret = 0; + uint32_t rdata = 0; + uint16_t sspm_master = 0; + uint32_t sspm_meta = 0; + + if (len < 3) + return -1; + + /*reset local config structure*/ + memset(err_msg, 0, MET_SMI_BUF_SIZE); + for (i = 0; i < 4; i++) { + smi_conf.port[i] = -1; + smi_conf.rwtype[i] = SMI_RW_ALL; + } + smi_conf.master = 0; + smi_conf.reqtype = SMI_REQ_ALL; + smi_conf.desttype = SMI_DEST_EMI; + + if (met_sspm_smi.mode != 0 && met_sspm_smi.mode != 1) + return -1; + + /* + * parse arguments + * arg[0] = master + * arg[1] = port or port1 + * arg[2] = rwtype or port2 + * arg[3] = desttype or port3 + * arg[4] = bustype or port4 + */ + for (i = 0; i < ARRAY_SIZE(args); i++) + args[i] = -1; + idx = 0; + for (i = 0; i < ARRAY_SIZE(args); i++) { + ret = get_num(&(arg[idx]), &(args[i])); + if (ret == 0) + break; + idx += ret; + if (arg[idx] != ':') + break; + idx++; + } + + pr_debug("===SMI process argu: args[0](%d), args[1](%d), args[2](%d), args[3](%d), args[4](%d)\n", + args[0], + args[1], + args[2], + args[3], + args[4]); + + /*fill local config structure*/ + smi_conf.master = args[0]; + smi_conf.reqtype = (larb_req_type << MET_SMI_BIT_REQ_LARB) | (comm_req_type << MET_SMI_BIT_REQ_COMM); + if (parallel_mode == 0) { /*legacy mode*/ + smi_conf.rwtype[0] = args[2]; + smi_conf.desttype = args[3]; + smi_conf.port[0] = args[1]; + } else { /*parallel mode*/ + smi_conf.desttype = SMI_DEST_EMI; + for (i = 0; i < 4; i++) { + if (args[i+1] < 0) + break; + smi_conf.port[i] = args[i+1]; + smi_conf.rwtype[i] = comm_pm_rw_type[0][i]; + } + } + +/*debug log to ftrace*/ +#ifdef MET_SMI_DEBUG + snprintf(debug_msg, MET_SMI_DEBUGBUF_SIZE, + "(argu)===SMI process argu Master[%d]: parallel_mode = %d, \ + master = %d, port0 = %d, port1 = %d, port2 = %d, port3 = %d, \ + rwtype0 = %d, rwtype1 = %d, rwtype2 = %d, rwtype3 = %d, \ + desttype = %d, reqtype(larb) = %d, reqtype(comm) = %d\n", + args[0], + parallel_mode, + smi_conf.master, + smi_conf.port[0], + smi_conf.port[1], + smi_conf.port[2], + smi_conf.port[3], + smi_conf.rwtype[0], + smi_conf.rwtype[1], + smi_conf.rwtype[2], + smi_conf.rwtype[3], + smi_conf.desttype, + (smi_conf.reqtype >> MET_SMI_BIT_REQ_LARB) & 0x3, + (smi_conf.reqtype >> MET_SMI_BIT_REQ_COMM) & 0x3); + met_smi_debug(debug_msg); +#endif + + /*find the empty conf_array*/ + for (i = 0; i < MAX_CONFIG_ARRAY_SIZE; i++) { + if ((smi_conf_array[i].master == smi_conf.master) && (smi_conf_array[i].port[0] != -1)) + break; + } + if (i >= MAX_CONFIG_ARRAY_SIZE) { + if (smi_conf_array[0].port[0] == -1) { + smi_array_index = 0; + array_index = 0; + } else { + smi_array_index = smi_array_index + 1; + array_index = smi_array_index; + } + } else { + array_index = i; + } + + if ((smi_array_index >= MAX_CONFIG_ARRAY_SIZE) || (array_index >= MAX_CONFIG_ARRAY_SIZE)) { + snprintf(err_msg, MET_SMI_BUF_SIZE, + "===Setting Master[%d]: check smi_array_index=%d, array_index=%d overflow (> %d)\n", + args[0], smi_array_index, array_index, MAX_CONFIG_ARRAY_SIZE); + return -1; + } + + smi_conf_array[array_index].master = smi_conf.master; + + + if (parallel_mode == 0) { /* Legacy mode */ + smi_conf_array[array_index].port[0] = smi_conf.port[0]; + } else { /* Parallel mode */ + for (i = 0; i < NPORT_IN_PM; i++) { + if (smi_conf_array[array_index].port[i] == -1) + smi_conf_array[array_index].port[i] = smi_conf.port[smi_conf_index++]; + } + } + smi_conf_array[array_index].rwtype[0] = smi_conf.rwtype[0]; + smi_conf_array[array_index].rwtype[1] = smi_conf.rwtype[1]; + smi_conf_array[array_index].rwtype[2] = smi_conf.rwtype[2]; + smi_conf_array[array_index].rwtype[3] = smi_conf.rwtype[3]; + smi_conf_array[array_index].desttype = smi_conf.desttype; + smi_conf_array[array_index].reqtype = smi_conf.reqtype; + + pr_debug("===SMI process argu Master[%d]: parallel_mode = %d, master = %d, \ + port0 = %d, port1 = %d, port2 = %d, port3 = %d, \ + rwtype0 = %d, rwtype1 = %d, rwtype2 = %d, rwtype3 = %d, \ + desttype = %d, reqtype(larb) = %d, reqtype(comm) = %d\n", + args[0], + parallel_mode, + smi_conf.master, + smi_conf.port[0], + smi_conf.port[1], + smi_conf.port[2], + smi_conf.port[3], + smi_conf.rwtype[0], + smi_conf.rwtype[1], + smi_conf.rwtype[2], + smi_conf.rwtype[3], + smi_conf.desttype, + (smi_conf.reqtype >> MET_SMI_BIT_REQ_LARB) & 0x3, + (smi_conf.reqtype >> MET_SMI_BIT_REQ_COMM) & 0x3); + + // Encode SMI config: Master (request format from SMI driver) + sspm_master = sspm_master | (smi_conf_array[array_index].master << MET_SMI_BIT_MASTER); + sspm_master = sspm_master | 0 << MET_SMI_BIT_REQ; //reqtype value will be update in sspm side + sspm_master = sspm_master | (smi_conf_array[array_index].desttype << MET_SMI_BIT_DST); + sspm_master = sspm_master | (parallel_mode << MET_SMI_BIT_PM); + // Extrace info for larb and comm reqestType since of unable to recognize master belong to larb or comm. + // BIT13~BIT14: comm reqtype + // BIT15~BIT16: larb reqtype + sspm_master = sspm_master | smi_conf_array[array_index].reqtype; + + // Encode SMI config: Meta (request format from SMI driver) + // Encode 4 Metadata into 1 unsigned int + // BIT0~BIT4: port + // BIT5~BIT6: rwtype + if (parallel_mode == 0){ + sspm_meta = sspm_meta | (smi_conf_array[array_index].port[0] << MET_SMI_BIT_PORT); + sspm_meta = sspm_meta | (smi_conf_array[array_index].rwtype[0] << MET_SMI_BIT_RW); + } else { + for (i = 0; i < 4; i++){ + if (smi_conf_array[array_index].port[i] == 0xFFFFFFFF){ + smi_conf_array[array_index].port[i] = USHRT_MAX; + } + sspm_meta = sspm_meta | (smi_conf_array[array_index].port[i] << (MET_SMI_BIT_PORT+8*i)); + sspm_meta = sspm_meta | (smi_conf_array[array_index].rwtype[i] << (MET_SMI_BIT_RW+8*i)); + } + } + + // Transfer to SSPM side + if (sspm_buffer_size > 0) { + ipi_buf[0] = MET_MAIN_ID | MET_ARGU | MID_SMI << MID_BIT_SHIFT | 1; + ipi_buf[1] = sspm_master; + ipi_buf[2] = sspm_meta; + ipi_buf[3] = 0; + ret = met_ipi_to_sspm_command((void *)ipi_buf, 0, &rdata, 1); + + /* Set mode */ + met_sspm_smi.mode = 1; + ondiemet_module[ONDIEMET_SSPM] |= ID_SMI; + } + + return 0; +} + +struct metdevice met_sspm_smi = { + .name = "smi", + .owner = THIS_MODULE, + .type = MET_TYPE_BUS, + .create_subfs = met_smi_create, + .delete_subfs = met_smi_delete, + .cpu_related = 0, + .ondiemet_mode = 1, + .ondiemet_start = met_smi_start, + .ondiemet_stop = met_smi_stop, + .ondiemet_process_argument = smi_process_argument, + .ondiemet_print_help = smi_print_help, +}; +EXPORT_SYMBOL(met_sspm_smi); diff --git a/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/sspm/sspm_met_smi.h b/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/sspm/sspm_met_smi.h new file mode 100644 index 0000000000000000000000000000000000000000..30529ee1d61888e4937f7ba4f4a1c0e72dc51545 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/sspm/sspm_met_smi.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef _SMI_H_ +#define _SMI_H_ + +#include + +struct met_smi { + int mode; + int master; + unsigned int port; + unsigned int rwtype; /* 0 for R+W, 1 for read, 2 for write */ + unsigned int desttype; /* 0 for EMI+internal mem, 1 for EMI, 3 for internal mem */ + unsigned int bustype; /* 0 for GMC, 1 for AXI */ + /* unsigned long requesttype;// 0:All, 1:ultra high, 2:pre-ultrahigh, 3:normal. */ + struct kobject *kobj_bus_smi; +}; + +struct smi_cfg { + int master; + unsigned int port; + unsigned int rwtype; /* 0 for R+W, 1 for read, 2 for write */ + unsigned int desttype; /* 0 for EMI+internal mem, 1 for EMI, 3 for internal mem */ + unsigned int bustype; /*0 for GMC, 1 for AXI */ + /*unsigned long requesttype;// 0:All, 1:ultra high, 2:pre-ultrahigh, 3:normal. */ +}; + +struct smi_mon_con { + unsigned int requesttype; /* 0:All, 1:ultra high, 2:pre-ultrahigh, 3:normal. */ +}; + +/* ====================== SMI/EMI Interface ================================ */ + +struct met_smi_conf { + unsigned int master; /*Ex : Whitney: 0~8 for larb0~larb8, 9 for common larb*/ + int port[4]; /* port select : [0] only for legacy mode, [0~3] ports for parallel mode, -1 no select*/ + unsigned int reqtype; /* Selects request type : 0 for all,1 for ultra,2 for preultra,3 for normal*/ + unsigned int rwtype[4]; /* Selects read/write: 0 for R+W, 1 for read, 2 for write;*/ + /* [0] for legacy and parallel larb0~8, [0~3] for parallel mode common*/ + unsigned int desttype; /* Selects destination: 0 and 3 for all memory, 1 for External,2 for internal*/ +}; + +#endif /* _SMI_H_ */ diff --git a/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/sspm/sspm_met_smi_name.h b/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/sspm/sspm_met_smi_name.h new file mode 100644 index 0000000000000000000000000000000000000000..9cf949aee660e4e23ff1f6c09477f9d7ac8e806e --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/sspm/sspm_met_smi_name.h @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef _SMI_NAME_H_ +#define _SMI_NAME_H_ +#include "mtk_smi.h" + +enum SMI_DEST { + SMI_DEST_ALL = 0, + SMI_DEST_EMI = 1, + SMI_DEST_INTERNAL = 2, + SMI_DEST_NONE = 9 +}; + +enum SMI_RW { + SMI_RW_ALL = 0, + SMI_READ_ONLY = 1, + SMI_WRITE_ONLY = 2, + SMI_RW_RESPECTIVE = 3, + SMI_RW_NONE = 9 +}; + +enum SMI_BUS { + SMI_BUS_GMC = 0, + SMI_BUS_AXI = 1, + SMI_BUS_NONE = 9 +}; + +enum SMI_REQUEST { + SMI_REQ_ALL = 0, + SMI_REQ_ULTRA = 1, + SMI_REQ_PREULTRA = 2, + SMI_NORMAL_ULTRA = 3, + SMI_REQ_NONE = 9 +}; + +struct smi_desc { + unsigned long port; + enum SMI_DEST desttype; + enum SMI_RW rwtype; + enum SMI_BUS bustype; +}; +#endif /* _SMI_NAME_H_ */ diff --git a/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/sspm/sspm_mtk_smi.h b/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/sspm/sspm_mtk_smi.h new file mode 100644 index 0000000000000000000000000000000000000000..82bc368c6848e76e0060916fe092186b13eaaeb0 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/sspm/sspm_mtk_smi.h @@ -0,0 +1,125 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef __MT_SMI_H__ +#define __MT_SMI_H__ + +/* the default value, but the real number will get from symbol function*/ +#define SMI_LARB_NUMBER 9 +#define SMI_COMM_NUMBER 1 +#define SMI_LARB_MONITOR_NUMBER 1 +#define SMI_COMM_MONITOR_NUMBER 1 + +#define SMI_REQ_OK (0) +#define SMI_ERR_WRONG_REQ (-1) +#define SMI_ERR_OVERRUN (-2) + +#define SMI_IOMEM_ADDR(b, off) ((void __iomem *)(((unsigned long)b)+off)) + +#define SMI_LARB_MON_ENA(b) SMI_IOMEM_ADDR((b), 0x400) +#define SMI_LARB_MON_CLR(b) SMI_IOMEM_ADDR((b), 0x404) +#define SMI_LARB_MON_PORT(b) SMI_IOMEM_ADDR((b), 0x408) +#define SMI_LARB_MON_CON(b) SMI_IOMEM_ADDR((b), 0x40C) + +#define SMI_LARB_MON_ACT_CNT(b) SMI_IOMEM_ADDR((b), 0x410) +#define SMI_LARB_MON_REQ_CNT(b) SMI_IOMEM_ADDR((b), 0x414) +#define SMI_LARB_MON_BEA_CNT(b) SMI_IOMEM_ADDR((b), 0x418) +#define SMI_LARB_MON_BYT_CNT(b) SMI_IOMEM_ADDR((b), 0x41C) +#define SMI_LARB_MON_CP_CNT(b) SMI_IOMEM_ADDR((b), 0x420) +#define SMI_LARB_MON_DP_CNT(b) SMI_IOMEM_ADDR((b), 0x424) +#define SMI_LARB_MON_OSTD_CNT(b) SMI_IOMEM_ADDR((b), 0x428) +#define SMI_LARB_MON_CP_MAX(b) SMI_IOMEM_ADDR((b), 0x430) +#define SMI_LARB_MON_OSTD_MAX(b) SMI_IOMEM_ADDR((b), 0x434) + +#define SMI_COMM_MON_ENA(b) SMI_IOMEM_ADDR((b), 0x1A0) +#define SMI_COMM_MON_CLR(b) SMI_IOMEM_ADDR((b), 0x1A4) +#define SMI_COMM_MON_TYPE(b) SMI_IOMEM_ADDR((b), 0x1AC) +#define SMI_COMM_MON_CON(b) SMI_IOMEM_ADDR((b), 0x1B0) +#define SMI_COMM_MON_ACT_CNT(b) SMI_IOMEM_ADDR((b), 0x1C0) +#define SMI_COMM_MON_REQ_CNT(b) SMI_IOMEM_ADDR((b), 0x1C4) +#define SMI_COMM_MON_OSTD_CNT(b) SMI_IOMEM_ADDR((b), 0x1C8) +#define SMI_COMM_MON_BEA_CNT(b) SMI_IOMEM_ADDR((b), 0x1CC) +#define SMI_COMM_MON_BYT_CNT(b) SMI_IOMEM_ADDR((b), 0x1D0) +#define SMI_COMM_MON_CP_CNT(b) SMI_IOMEM_ADDR((b), 0x1D4) +#define SMI_COMM_MON_DP_CNT(b) SMI_IOMEM_ADDR((b), 0x1D8) +#define SMI_COMM_MON_CP_MAX(b) SMI_IOMEM_ADDR((b), 0x1DC) +#define SMI_COMM_MON_OSTD_MAX(b) SMI_IOMEM_ADDR((b), 0x1E0) + + +/*ondiemet smi ipi command*/ +enum MET_SMI_IPI_Type { + SMI_DRIVER_INITIAL_VALUE = 0x0, + SMI_DRIVER_RESET_VALUE, + SET_BASE_SMI, + SMI_ASSIGN_PORT_START, + SMI_ASSIGN_PORT_I, + SMI_ASSIGN_PORT_II, + SMI_ASSIGN_PORT_III, + SMI_ASSIGN_PORT_END, +}; + + + + +void MET_SMI_IPI_baseaddr(void); +int MET_SMI_Init(void); +void MET_SMI_Fini(void); +void MET_SMI_Enable(int larbno); +void MET_SMI_Disable(int larbno); +void MET_SMI_Pause(int larbno); +void MET_SMI_Clear(int larbno); +int MET_SMI_PowerOn(unsigned int master); +void MET_SMI_PowerOff(unsigned int master); +int MET_SMI_LARB_SetCfg(int larbno, + unsigned int pm, + unsigned int reqtype, unsigned int rwtype, unsigned int dsttype); +int MET_SMI_LARB_SetPortNo(int larbno, unsigned int idx, unsigned int port); +int MET_SMI_COMM_SetCfg(int commonno, unsigned int pm, unsigned int reqtype); +int MET_SMI_COMM_SetPortNo(int commonno, unsigned int idx, unsigned int port); +int MET_SMI_COMM_SetRWType(int commonno, unsigned int idx, unsigned int rw); + +/* config */ +int MET_SMI_GetEna(int larbno); +int MET_SMI_GetClr(int larbno); +int MET_SMI_GetPortNo(int larbno); +int MET_SMI_GetCon(int larbno); + +/* cnt */ +int MET_SMI_GetActiveCnt(int larbno); +int MET_SMI_GetRequestCnt(int larbno); +int MET_SMI_GetBeatCnt(int larbno); +int MET_SMI_GetByteCnt(int larbno); +int MET_SMI_GetCPCnt(int larbno); +int MET_SMI_GetDPCnt(int larbno); +int MET_SMI_GetOSTDCnt(int larbno); +int MET_SMI_GetCP_MAX(int larbno); +int MET_SMI_GetOSTD_MAX(int larbno); + +/* common */ +void MET_SMI_Comm_Init(void); +void MET_SMI_Comm_Enable(int commonno); +void MET_SMI_Comm_Disable(int commonno); +void MET_SMI_Pause(int commonno); +void MET_SMI_Comm_Clear(int commonno); + +/* common config */ +int MET_SMI_Comm_GetEna(int commonno); +int MET_SMI_Comm_GetClr(int commonno); +int MET_SMI_Comm_GetType(int commonno); +int MET_SMI_Comm_GetCon(int commonno); + +/* cnt */ +int MET_SMI_Comm_GetPortNo(int commonno); +int MET_SMI_Comm_GetActiveCnt(int commonno); +int MET_SMI_Comm_GetRequestCnt(int commonno); +int MET_SMI_Comm_GetBeatCnt(int commonno); +int MET_SMI_Comm_GetByteCnt(int commonno); +int MET_SMI_Comm_GetCPCnt(int commonno); +int MET_SMI_Comm_GetDPCnt(int commonno); +int MET_SMI_Comm_GetOSTDCnt(int commonno); +int MET_SMI_Comm_GetCP_MAX(int commonno); +int MET_SMI_Comm_GetOSTD_MAX(int commonno); + +#endif /* __MT_SMI_H__ */ diff --git a/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/sspm/tinysys_sspm.h b/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/sspm/tinysys_sspm.h new file mode 100644 index 0000000000000000000000000000000000000000..9d9fad684f9ae89841090f9c342b14554f9565eb --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/sspm/tinysys_sspm.h @@ -0,0 +1,122 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#ifndef __ONDIEMET_SSPM_H__ +#define __ONDIEMET_SSPM_H__ +/***************************************************************************** + * headers + *****************************************************************************/ +#include "mt-plat/mtk_tinysys_ipi.h" /* for mtk_ipi_device */ + + +/***************************************************************************** + * define declaration + *****************************************************************************/ +/* MET IPI command definition: mbox 0 */ +/* main func ID: bit[31-24]; sub func ID: bit[23-18]; argu 0: bit[17-0] */ +#define MET_MAIN_ID_MASK 0xff000000 /* bit 31 - 24 */ +#define MET_SUB_ID_MASK 0x00fc0000 /* bit 23 - 18 */ +#define MET_ARGU0_MASK 0x0003ffff /* bit 17 - 0 */ +#define FUNC_BIT_SHIFT 18 +#define MID_BIT_SHIFT 9 +#define MET_MAIN_ID 0x06000000 +/* handle argument and attribute */ +#define PROCESS_ARGU 0x01 +#define PROCESS_ATTR 0x02 +#define MODULE_ID_MASK 0x3fe00 /* bit 9 - 17 */ +#define ARGUMENT_MASK 0x01ff /* bit 0 - 8 */ + +/* the following command is used for AP to MD32 */ +/* argu 0: start: 0x01; stop: 0x02; extract: 0x03 */ +#define MET_OP_START 0x00000001 +#define MET_OP_STOP 0x00000002 +#define MET_OP_EXTRACT 0x00000003 +#define MET_OP_FLUSH 0x00000004 +#define MET_OP (1 << FUNC_BIT_SHIFT) +#define MET_SR (2 << FUNC_BIT_SHIFT) /* sample rate */ +#define MET_MODULE (3 << FUNC_BIT_SHIFT) /* module enable/disable */ +#define MET_ARGU (4 << FUNC_BIT_SHIFT) /* argument passing */ +#define MET_ATTR (5 << FUNC_BIT_SHIFT) /* attribute passing */ +/* system memory information for on-die-met log data */ +#define MET_BUFFER_INFO (6 << FUNC_BIT_SHIFT) +#define MET_TIMESTAMP (7 << FUNC_BIT_SHIFT) /* timestamp info */ +#define MET_GPT (8 << FUNC_BIT_SHIFT) /* GPT counter reading */ +#define MET_REQ_AP2MD (9 << FUNC_BIT_SHIFT) /* user defined command */ +#define MET_RESP_AP2MD (10 << FUNC_BIT_SHIFT) /* may no need */ +/* mode: bit 15 - 0: */ +/* Bit 0: MD32 SRAM mode; Bit 1: System DRAM mode */ +/* value: 0: output to next level of storage; 1: loop in its own storage */ +#define MET_DATA_MODE (11 << FUNC_BIT_SHIFT) /* log output mode */ +/* start/stop read data into MD32 SRAM buffer; both DMA and met_printf() */ +#define MET_DATA_OP (12 << FUNC_BIT_SHIFT) /* data read operation */ +/* the following command is used for MD32 to AP */ +#define MET_DUMP_BUFFER (13 << FUNC_BIT_SHIFT) +#define MET_REQ_MD2AP (14 << FUNC_BIT_SHIFT) /* user defined command */ +#define MET_CLOSE_FILE (15 << FUNC_BIT_SHIFT) /* Inform to close the SD file */ +#define MET_RESP_MD2AP (16 << FUNC_BIT_SHIFT) +#define MET_RUN_MODE (17 << FUNC_BIT_SHIFT) + +#define ID_PMQOS (1 << MID_PMQOS) +#define ID_SMI (1 << MID_SMI) +#define ID_EMI (1 << MID_EMI) +#define ID_THERMAL_CPU (1 << MID_THERMAL_CPU) +#define ID_WALL_TIME (1 << MID_WALL_TIME) +#define ID_CPU_DVFS (1 << MID_CPU_DVFS) +#define ID_GPU_DVFS (1 << MID_GPU_DVFS) +#define ID_VCORE_DVFS (1 << MID_VCORE_DVFS) +#define ID_PTPOD (1 << MID_PTPOD) +#define ID_SPM (1 << MID_SPM) +#define ID_PROFILE (1 << MID_PROFILE) +#define ID_COMMON (1 << MID_COMMON) +#define ID_CPU_INFO_MAPPING (1 << MID_CPU_INFO_MAPPING) +#define ID_SMI (1 << MID_SMI) +#define ID_PMU (1 << MID_PMU) + +#define SSPM_LOG_FILE 0 +#define SSPM_LOG_SRAM 1 +#define SSPM_LOG_DRAM 2 + +#define SSPM_RUN_NORMAL 0 +#define SSPM_RUN_CONTINUOUS 1 + + +/***************************************************************************** + * struct & enum declaration + *****************************************************************************/ +/* Note: the module ID and its bit pattern should be fixed as below */ +/* DMA based module first */ +enum { + MID_PMQOS = 0, + MID_VCORE_DVFS, + MID_EMI, + MID_THERMAL_CPU, + MID_WALL_TIME, + MID_CPU_DVFS, + MID_GPU_DVFS, + MID_PTPOD, + MID_SPM, + MID_PROFILE, + MID_MET_TAG, + MID_TS, + MID_TS_ISR, + MID_TS_LAST, + MID_TS_ISR_LAST, + MID_SRAM_INFO, + MID_MET_STOP, + MID_IOP_MON, + MID_CPU_INFO_MAPPING, + MID_SMI, + MID_PMU, + + MID_COMMON = 0x1F +}; + + +/***************************************************************************** + * external variable declaration + *****************************************************************************/ +extern struct mtk_ipi_device *sspm_ipidev_symbol; +extern int sspm_buf_available; + +#endif /* __ONDIEMET_SSPM_H__ */ diff --git a/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/tinysys_log.c b/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/tinysys_log.c new file mode 100644 index 0000000000000000000000000000000000000000..7d7e931d9cd45bc505946f7ea3f2a547330e3837 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/tinysys_log.c @@ -0,0 +1,206 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ +/***************************************************************************** + * headers + *****************************************************************************/ +#include +#include +#include +#include +#include +#include /* symbol_get */ +#include /* timespec_to_jiffies */ +#include /* copy_to_user */ +#include /* for ioremap and iounmap */ + +#include +#include "interface.h" +#include "core_plf_init.h" + +#include "tinysys_mgr.h" +#include "tinysys_log.h" + +#if FEATURE_SSPM_NUM +#include "sspm_reservedmem.h" +#include "sspm_reservedmem_define.h" +#include "sspm/sspm_met_log.h" +#endif + +#if FEATURE_MCUPM_NUM +#include "mcupm_driver.h" +#include "mcupm/mcupm_met_log.h" +#endif + + +/***************************************************************************** + * define declaration + *****************************************************************************/ +#define IPI_COMMOND_SIZE 4 + + +/***************************************************************************** + * struct & enum declaration + *****************************************************************************/ +enum { + kTINYSYS_LOG_START, + kTINYSYS_LOG_STOP, + kTINYSYS_LOG_IDLE, +}; + + +/***************************************************************************** + * external function declaration + *****************************************************************************/ + + +/***************************************************************************** + * internal function declaration + *****************************************************************************/ +static void _reset(int status, int type); + + +/***************************************************************************** + * external variable declaration + *****************************************************************************/ + + +/***************************************************************************** + * internal variable declaration + *****************************************************************************/ +#if FEATURE_SSPM_NUM +static unsigned int _g_sspm_status; +#endif + +#if FEATURE_MCUPM_NUM +static unsigned int _g_mcupm_status; +#endif + + +/***************************************************************************** + * external function ipmlement + *****************************************************************************/ +int tinysys_log_manager_init(struct device *dev) +{ +#ifdef ONDIEMET_MOUNT_DEBUGFS + struct dentry *dbgfs_met_dir = NULL; + + dbgfs_met_dir = debugfs_create_dir("ondiemet", NULL); + if (dbgfs_met_dir == NULL) { + PR_BOOTMSG("[MET] can not create debugfs directory: ondiemet\n"); + return -ENOMEM; + } + dev_set_drvdata(dev, dbgfs_met_dir); +#else + struct proc_dir_entry *procfs_met_dir = NULL; + + procfs_met_dir = proc_mkdir("ondiemet", NULL); + if (procfs_met_dir == NULL) { + PR_BOOTMSG("[MET] can not create procfs directory: ondiemet\n"); + return -ENOMEM; + } + dev_set_drvdata(dev, procfs_met_dir); +#endif + +#if FEATURE_SSPM_NUM + sspm_log_init(dev); +#endif + +#if FEATURE_MCUPM_NUM + mcupm_log_init(dev); +#endif + + return 0; +} + + +int tinysys_log_manager_uninit(struct device *dev) +{ +#ifdef ONDIEMET_MOUNT_DEBUGFS + struct dentry *dbgfs_met_dir = NULL; +#else + struct proc_dir_entry *procfs_met_dir = NULL; +#endif + +#if FEATURE_SSPM_NUM + sspm_log_uninit(dev); +#endif + +#if FEATURE_MCUPM_NUM + mcupm_log_uninit(dev); +#endif + +#ifdef ONDIEMET_MOUNT_DEBUGFS + dbgfs_met_dir = dev_get_drvdata(dev); + if (dbgfs_met_dir) { + debugfs_remove_recursive(dbgfs_met_dir); + dev_set_drvdata(dev, met_device.this_device); + } +#else + procfs_met_dir = dev_get_drvdata(dev); + if (procfs_met_dir) { + proc_remove(procfs_met_dir); + dev_set_drvdata(dev, met_device.this_device); + } +#endif + + return 0; +} + + +int tinysys_log_manager_start(void) +{ +#if FEATURE_SSPM_NUM + sspm_log_start(); + _reset(kTINYSYS_LOG_START, ONDIEMET_SSPM); +#endif + +#if FEATURE_MCUPM_NUM + mcupm_log_start(); + _reset(kTINYSYS_LOG_START, ONDIEMET_MCUPM); +#endif + + return 0; +} + + +int tinysys_log_manager_stop(void) +{ +#if FEATURE_SSPM_NUM + sspm_log_stop(); + _reset(kTINYSYS_LOG_STOP, ONDIEMET_SSPM); +#endif + +#if FEATURE_MCUPM_NUM + mcupm_log_stop(); + _reset(kTINYSYS_LOG_STOP, ONDIEMET_MCUPM); +#endif + + return 0; +} + + +/***************************************************************************** + * internal function ipmlement + *****************************************************************************/ +static void _reset(int status, int type) +{ + switch (type) { +#if FEATURE_SSPM_NUM + case ONDIEMET_SSPM: + _g_sspm_status = status; + break; +#endif + +#if FEATURE_MCUPM_NUM + case ONDIEMET_MCUPM: + _g_mcupm_status = status; + break; +#endif + + default: + return; + } +} + diff --git a/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/tinysys_log.h b/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/tinysys_log.h new file mode 100644 index 0000000000000000000000000000000000000000..911ddcc687bb19abcd697206a1dbaa58958b5c06 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/tinysys_log.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#ifndef __TINYSYS_LOG_H__ +#define __TINYSYS_LOG_H__ +/***************************************************************************** + * headers + *****************************************************************************/ +#include + + +/***************************************************************************** + * define declaration + *****************************************************************************/ + + +/***************************************************************************** + * struct & enum declaration + *****************************************************************************/ + + +/***************************************************************************** + * external function declaration + *****************************************************************************/ +int tinysys_log_manager_init(struct device *dev); +int tinysys_log_manager_uninit(struct device *dev); +int tinysys_log_manager_start(void); +int tinysys_log_manager_stop(void); + + +/***************************************************************************** + * external variable declaration + *****************************************************************************/ + + +#endif /* __TINYSYS_LOG_H__ */ diff --git a/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/tinysys_mgr.c b/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/tinysys_mgr.c new file mode 100644 index 0000000000000000000000000000000000000000..91830ae87e27860080d60403cde470a784d89352 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/tinysys_mgr.c @@ -0,0 +1,851 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ +/***************************************************************************** + * headers + *****************************************************************************/ +#include /* DEVICE_ATTR */ + +#include "interface.h" + +#include "tinysys_mgr.h" +#include "tinysys_log.h" + +#if FEATURE_SSPM_NUM +#include "sspm/sspm_met_ipi_handle.h" +#include "sspm/sspm_met_log.h" +#endif + +#if FEATURE_MCUPM_NUM +#include "mcupm/mcupm_met_ipi_handle.h" +#include "mcupm/mcupm_met_log.h" +#endif + + +/***************************************************************************** + * define declaration + *****************************************************************************/ + + +/***************************************************************************** + * struct & enum declaration + *****************************************************************************/ + + +/***************************************************************************** + * external function declaration + *****************************************************************************/ + + +/***************************************************************************** + * internal function declaration + *****************************************************************************/ +#if FEATURE_SSPM_NUM +static ssize_t sspm_ipi_supported_show(struct device *dev, struct device_attribute *attr, char *buf); +static ssize_t sspm_buffer_size_show(struct device *dev, struct device_attribute *attr, char *buf); +static ssize_t sspm_available_show(struct device *dev, struct device_attribute *attr, char *buf); +static ssize_t sspm_log_discard_show(struct device *dev, struct device_attribute *attr, char *buf); +static ssize_t sspm_log_mode_show(struct device *dev, struct device_attribute *attr, char *buf); +static ssize_t sspm_log_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); +static ssize_t sspm_log_size_show(struct device *dev, struct device_attribute *attr, char *buf); +static ssize_t sspm_log_size_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); +static ssize_t sspm_run_mode_show(struct device *dev, struct device_attribute *attr, char *buf); +static ssize_t sspm_run_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); +static ssize_t sspm_modules_show(struct device *dev, struct device_attribute *attr, char *buf); +static ssize_t sspm_modules_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); +static ssize_t sspm_op_ctrl_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); + +static int _create_sspm_node(struct device *dev); +static void _remove_sspm_node(struct device *dev); +#endif + +#if FEATURE_MCUPM_NUM +static ssize_t _mcupm_ipi_supported_show( + struct kobject *kobj, + struct kobj_attribute *attr, + char *buf); + +static ssize_t _mcupm_buffer_size_show( + struct kobject *kobj, + struct kobj_attribute *attr, + char *buf); + +static ssize_t _mcupm_available_show( + struct kobject *kobj, + struct kobj_attribute *attr, + char *buf); + +static ssize_t _mcupm_log_discard_show( + struct kobject *kobj, + struct kobj_attribute *attr, + char *buf); + +static ssize_t _mcupm_log_size_show( + struct kobject *kobj, + struct kobj_attribute *attr, + char *buf); +static ssize_t _mcupm_log_size_store( + struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t count); + +static ssize_t _mcupm_run_mode_show( + struct kobject *kobj, + struct kobj_attribute *attr, + char *buf); +static ssize_t _mcupm_run_mode_store( + struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t count); + +static ssize_t _mcupm_modules_show( + struct kobject *kobj, + struct kobj_attribute *attr, + char *buf); +static ssize_t _mcupm_modules_store( + struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t count); + +static ssize_t _mcupm_op_ctrl_store( + struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t count); + +static int _create_mcupm_node(struct kobject *kobj); +static void _remove_mcupm_node(void); +#endif + + +/***************************************************************************** + * external variable declaration + *****************************************************************************/ +unsigned int ondiemet_module[ONDIEMET_NUM]; +EXPORT_SYMBOL(ondiemet_module); + + +/***************************************************************************** + * internal variable declaration + *****************************************************************************/ +static struct kobject *_g_tinysys_kobj; + +#if FEATURE_SSPM_NUM +static int _sspm_log_mode; +static int _sspm_run_mode; +static int _sspm_log_size; +static int _sspm_log_discard; + +static DEVICE_ATTR(sspm_ipi_supported, 0444, sspm_ipi_supported_show, NULL); +static DEVICE_ATTR(sspm_buffer_size, 0444, sspm_buffer_size_show, NULL); +static DEVICE_ATTR(sspm_available, 0444, sspm_available_show, NULL); +static DEVICE_ATTR(sspm_log_discard, 0444, sspm_log_discard_show, NULL); +static DEVICE_ATTR(sspm_log_mode, 0664, sspm_log_mode_show, sspm_log_mode_store); +static DEVICE_ATTR(sspm_log_size, 0664, sspm_log_size_show, sspm_log_size_store); +static DEVICE_ATTR(sspm_run_mode, 0664, sspm_run_mode_show, sspm_run_mode_store); +static DEVICE_ATTR(sspm_modules, 0664, sspm_modules_show, sspm_modules_store); +static DEVICE_ATTR(sspm_op_ctrl, 0220, NULL, sspm_op_ctrl_store); +#endif + +#if FEATURE_MCUPM_NUM +static int _mcupm_run_mode; +static int _mcupm_log_size; +static int _mcupm_log_discard; +static struct kobject *_mcupm_kobj; +static struct kobj_attribute _attr_mcupm_ipi_supported = \ + __ATTR(ipi_supported, 0444, _mcupm_ipi_supported_show, NULL); +static struct kobj_attribute _attr_mcupm_buffer_size = \ + __ATTR(buffer_size, 0444, _mcupm_buffer_size_show, NULL); +static struct kobj_attribute _attr_mcupm_available = \ + __ATTR(available, 0444, _mcupm_available_show, NULL); +static struct kobj_attribute _attr_mcupm_log_discard = \ + __ATTR(log_discard, 0444, _mcupm_log_discard_show, NULL); +static struct kobj_attribute _attr_mcupm_log_size = \ + __ATTR(log_size, 0664, _mcupm_log_size_show, _mcupm_log_size_store); +static struct kobj_attribute _attr_mcupm_run_mode = \ + __ATTR(run_mode, 0664, _mcupm_run_mode_show, _mcupm_run_mode_store); +static struct kobj_attribute _attr_mcupm_modules = \ + __ATTR(modules, 0664, _mcupm_modules_show, _mcupm_modules_store); +static struct kobj_attribute _attr_mcupm_op_ctrl = \ + __ATTR(op_ctrl, 0220, NULL, _mcupm_op_ctrl_store); +#endif + + +/***************************************************************************** + * external function ipmlement + *****************************************************************************/ +int ondiemet_attr_init(struct device *dev) +{ + int ret = 0; + + PR_BOOTMSG("%s\n", __FUNCTION__); + _g_tinysys_kobj = kobject_create_and_add("tinysys", &dev->kobj); + if (_g_tinysys_kobj == NULL) { + pr_debug("can not create kobject: tinysys\n"); + return -1; + } + +#if FEATURE_SSPM_NUM + ret = _create_sspm_node(dev); + if (ret != 0) { + pr_debug("can not create sspm node\n"); + return ret; + } +#endif + +#if FEATURE_MCUPM_NUM + ret = _create_mcupm_node(_g_tinysys_kobj); + if (ret != 0) { + pr_debug("can not create cpu eb node\n"); + return ret; + } +#endif + + return ret; +} + + +int ondiemet_attr_uninit(struct device *dev) +{ +#if FEATURE_SSPM_NUM + _remove_sspm_node(dev); +#endif + +#if FEATURE_MCUPM_NUM + _remove_mcupm_node(); +#endif + + if (_g_tinysys_kobj != NULL) { + kobject_del(_g_tinysys_kobj); + kobject_put(_g_tinysys_kobj); + _g_tinysys_kobj = NULL; + } + + return 0; +} + + +int ondiemet_log_manager_init(struct device *dev) +{ + return tinysys_log_manager_init(dev); +} + + +int ondiemet_log_manager_uninit(struct device *dev) +{ + return tinysys_log_manager_uninit(dev); +} + + +void ondiemet_log_manager_start() +{ + tinysys_log_manager_start(); +} + + +void ondiemet_log_manager_stop() +{ + tinysys_log_manager_stop(); +} + + +void ondiemet_start() +{ +#if FEATURE_SSPM_NUM + sspm_start(); +#endif + +#if FEATURE_MCUPM_NUM + mcupm_start(); +#endif + +} + + +void ondiemet_stop() +{ +#if FEATURE_SSPM_NUM + sspm_stop(); +#endif + +#if FEATURE_MCUPM_NUM + mcupm_stop(); +#endif + +} + + +void ondiemet_extract() +{ +#if FEATURE_SSPM_NUM + sspm_extract(); +#endif + +#if FEATURE_MCUPM_NUM + mcupm_extract(); +#endif + +} + + +/***************************************************************************** + * internal function ipmlement + *****************************************************************************/ +#if FEATURE_SSPM_NUM +static ssize_t sspm_ipi_supported_show( + struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ipi_supported = 1; + int i = 0; + + i = snprintf(buf, PAGE_SIZE, "%d\n", ipi_supported); + if (i < 0) + return 0; + + return i; +} + + +static ssize_t sspm_buffer_size_show( + struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int i = 0; + + i = snprintf(buf, PAGE_SIZE, "%d\n", sspm_buffer_size); + if (i < 0) + return 0; + + return i; +} + + +static ssize_t sspm_available_show( + struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int i = 0; + + i = snprintf(buf, PAGE_SIZE, "%d\n", 1); + if (i < 0) + return 0; + + return i; +} + + +static ssize_t sspm_log_discard_show( + struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int i = 0; + + i = snprintf(buf, PAGE_SIZE, "%d\n", _sspm_log_discard); + if (i < 0) + return 0; + + return i; +} + +static ssize_t sspm_log_mode_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int i; + + mutex_lock(&dev->mutex); + i = snprintf(buf, PAGE_SIZE, "%d\n", _sspm_log_mode); + mutex_unlock(&dev->mutex); + + if (i < 0) + return 0; + + return i; +} + + +static ssize_t sspm_log_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +{ + int value; + + if (kstrtoint(buf, 0, &value) != 0) + return -EINVAL; + mutex_lock(&dev->mutex); + _sspm_log_mode = value; + mutex_unlock(&dev->mutex); + + return count; +} + + +static ssize_t sspm_log_size_show( + struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int i = 0; + + i = snprintf(buf, PAGE_SIZE, "%d\n", _sspm_log_size); + if (i < 0) + return 0; + + return i; +} + + +static ssize_t sspm_log_size_store( + struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + int value = 0; + + if (kstrtoint(buf, 0, &value) != 0) { + return -EINVAL; + } + + _sspm_log_size = value; + + return count; +} + + +static ssize_t sspm_run_mode_show( + struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int i = 0; + + i = snprintf(buf, PAGE_SIZE, "%d\n", _sspm_run_mode); + if (i < 0) + return 0; + + return i; +} + + +static ssize_t sspm_run_mode_store( + struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + int value = 0; + + if (kstrtoint(buf, 0, &value) != 0) { + return -EINVAL; + } + + _sspm_run_mode = value; + + return count; +} + + +static ssize_t sspm_op_ctrl_store( + struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + int value = 0; + + if (kstrtoint(buf, 0, &value) != 0) { + return -EINVAL; + } + + if (value == 1) { + sspm_start(); + } else if (value == 2) { + sspm_stop(); + } else if (value == 3) { + sspm_extract(); + } else if (value == 4) { + sspm_flush(); + } + + return count; +} + + +static ssize_t sspm_modules_show( + struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int i = 0; + + i = snprintf(buf, PAGE_SIZE, "0x%X\n", ondiemet_module[ONDIEMET_SSPM]); + if (i < 0) + return 0; + + return i; +} + +static ssize_t sspm_modules_store( + struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + unsigned int value; + + if (kstrtoint(buf, 0, &value) != 0) { + return -EINVAL; + } + + ondiemet_module[ONDIEMET_SSPM] = value; + + return count; +} + + +static int _create_sspm_node(struct device *dev) +{ + int ret = 0; + + ret = device_create_file(dev, &dev_attr_sspm_ipi_supported); + if (ret != 0) { + pr_debug("can not create device file: sspm_ipi_supported\n"); + return ret; + } + + ret = device_create_file(dev, &dev_attr_sspm_buffer_size); + if (ret != 0) { + pr_debug("can not create device file: sspm_buffer_size\n"); + return ret; + } + + ret = device_create_file(dev, &dev_attr_sspm_available); + if (ret != 0) { + pr_debug("can not create device file: sspm_available\n"); + return ret; + } + + ret = device_create_file(dev, &dev_attr_sspm_log_discard); + if (ret != 0) { + pr_debug("can not create device file: sspm_log_discard\n"); + return ret; + } + + ret = device_create_file(dev, &dev_attr_sspm_log_mode); + if (ret != 0) { + pr_debug("can not create device file: sspm_log_mode\n"); + return ret; + } + + ret = device_create_file(dev, &dev_attr_sspm_log_size); + if (ret != 0) { + pr_debug("can not create device file: sspm_log_size\n"); + return ret; + } + + ret = device_create_file(dev, &dev_attr_sspm_run_mode); + if (ret != 0) { + pr_debug("can not create device file: sspm_run_mode\n"); + return ret; + } + + ret = device_create_file(dev, &dev_attr_sspm_modules); + if (ret != 0) { + pr_debug("can not create device file: sspm_modules\n"); + return ret; + } + + ret = device_create_file(dev, &dev_attr_sspm_op_ctrl); + if (ret != 0) { + pr_debug("can not create device file: sspm_op_ctrl\n"); + return ret; + } + return ret; +} + + +static void _remove_sspm_node(struct device *dev) +{ + device_remove_file(dev, &dev_attr_sspm_ipi_supported); + device_remove_file(dev, &dev_attr_sspm_buffer_size); + device_remove_file(dev, &dev_attr_sspm_available); + device_remove_file(dev, &dev_attr_sspm_log_discard); + device_remove_file(dev, &dev_attr_sspm_log_mode); + device_remove_file(dev, &dev_attr_sspm_log_size); + device_remove_file(dev, &dev_attr_sspm_run_mode); + device_remove_file(dev, &dev_attr_sspm_modules); + device_remove_file(dev, &dev_attr_sspm_op_ctrl); +} +#endif + + +#if FEATURE_MCUPM_NUM +static ssize_t _mcupm_ipi_supported_show( + struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + int ipi_supported = 1; + int i = 0; + + i = snprintf(buf, PAGE_SIZE, "%d\n", ipi_supported); + if (i < 0) + return 0; + + return i; +} + + +static ssize_t _mcupm_buffer_size_show( + struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + int i = 0; + + i = snprintf(buf, PAGE_SIZE, "%d\n", mcupm_buffer_size); + if (i < 0) + return 0; + + return i; +} + + +static ssize_t _mcupm_available_show( + struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + int i = 0; + + i = snprintf(buf, PAGE_SIZE, "%d\n", 1); + if (i < 0) + return 0; + + return i; +} + + +static ssize_t _mcupm_log_discard_show( + struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + int i = 0; + + i = snprintf(buf, PAGE_SIZE, "%d\n", _mcupm_log_discard); + if (i < 0) + return 0; + + return i; +} + + +static ssize_t _mcupm_log_size_show( + struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + int i = 0; + + i = snprintf(buf, PAGE_SIZE, "%d\n", _mcupm_log_size); + if (i < 0) + return 0; + + return i; +} + + +static ssize_t _mcupm_log_size_store( + struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t count) +{ + int value = 0; + + if (kstrtoint(buf, 0, &value) != 0) { + return -EINVAL; + } + + _mcupm_log_size = value; + + return count; +} + + +static ssize_t _mcupm_run_mode_show( + struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + int i = 0; + + i = snprintf(buf, PAGE_SIZE, "%d\n", _mcupm_run_mode); + if (i < 0) + return 0; + + return i; +} + + +static ssize_t _mcupm_run_mode_store( + struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t count) +{ + int value = 0; + + if (kstrtoint(buf, 0, &value) != 0) { + return -EINVAL; + } + + _mcupm_run_mode = value; + + return count; +} + + +static ssize_t _mcupm_op_ctrl_store( + struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t count) +{ + int value = 0; + + if (kstrtoint(buf, 0, &value) != 0) { + return -EINVAL; + } + + if (value == 1) { + mcupm_start(); + } else if (value == 2) { + mcupm_stop(); + } else if (value == 3) { + mcupm_extract(); + } else if (value == 4) { + mcupm_flush(); + } + + return count; +} + + +static ssize_t _mcupm_modules_show( + struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + int i = 0; + + i = snprintf(buf, PAGE_SIZE, "0x%X\n", ondiemet_module[ONDIEMET_MCUPM]); + if (i < 0) + return 0; + + return i; +} + +static ssize_t _mcupm_modules_store( + struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t count) +{ + unsigned int value; + + if (kstrtoint(buf, 0, &value) != 0) { + return -EINVAL; + } + + ondiemet_module[ONDIEMET_MCUPM] = value; + + return count; +} + + +static int _create_mcupm_node(struct kobject *parent) +{ + int ret = 0; + + _mcupm_kobj = kobject_create_and_add("mcupm", parent); + if (_mcupm_kobj == NULL) { + return -1; + } + + ret = sysfs_create_file(_mcupm_kobj, &_attr_mcupm_available.attr); + if (ret != 0) { + pr_debug("can not create device file: available\n"); + return ret; + } + + ret = sysfs_create_file(_mcupm_kobj, &_attr_mcupm_buffer_size.attr); + if (ret != 0) { + pr_debug("can not create device file: buffer_size\n"); + return ret; + } + + ret = sysfs_create_file(_mcupm_kobj, &_attr_mcupm_log_discard.attr); + if (ret != 0) { + pr_debug("can not create device file: log_discard\n"); + return ret; + } + + ret = sysfs_create_file(_mcupm_kobj, &_attr_mcupm_log_size.attr); + if (ret != 0) { + pr_debug("can not create device file: log_size\n"); + return ret; + } + + ret = sysfs_create_file(_mcupm_kobj, &_attr_mcupm_run_mode.attr); + if (ret != 0) { + pr_debug("can not create device file: run_mode\n"); + return ret; + } + + ret = sysfs_create_file(_mcupm_kobj, &_attr_mcupm_op_ctrl.attr); + if (ret != 0) { + pr_debug("can not create device file: op_ctrl\n"); + return ret; + } + + ret = sysfs_create_file(_mcupm_kobj, &_attr_mcupm_modules.attr); + if (ret != 0) { + pr_debug("can not create device file: modules\n"); + return ret; + } + + ret = sysfs_create_file(_mcupm_kobj, &_attr_mcupm_ipi_supported.attr); + if (ret != 0) { + pr_debug("can not create device file: ipi_supported\n"); + return ret; + } + return ret; +} + + +static void _remove_mcupm_node() +{ + if (_mcupm_kobj != NULL) { + sysfs_remove_file(_mcupm_kobj, &_attr_mcupm_buffer_size.attr); + sysfs_remove_file(_mcupm_kobj, &_attr_mcupm_available.attr); + sysfs_remove_file(_mcupm_kobj, &_attr_mcupm_log_discard.attr); + sysfs_remove_file(_mcupm_kobj, &_attr_mcupm_log_size.attr); + sysfs_remove_file(_mcupm_kobj, &_attr_mcupm_run_mode.attr); + sysfs_remove_file(_mcupm_kobj, &_attr_mcupm_op_ctrl.attr); + sysfs_remove_file(_mcupm_kobj, &_attr_mcupm_modules.attr); + sysfs_remove_file(_mcupm_kobj, &_attr_mcupm_ipi_supported.attr); + + kobject_del(_mcupm_kobj); + kobject_put(_mcupm_kobj); + _mcupm_kobj = NULL; + } +} +#endif diff --git a/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/tinysys_mgr.h b/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/tinysys_mgr.h new file mode 100644 index 0000000000000000000000000000000000000000..0e574f3398b02f15d053bc76f9aadc79a7383323 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/tinysys/v1/tinysys_mgr.h @@ -0,0 +1,63 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ +#ifndef __TINYSYS_MGR_H__ +#define __TINYSYS_MGR_H__ +/***************************************************************************** + * headers + *****************************************************************************/ +#include + + +/***************************************************************************** + * define declaration + *****************************************************************************/ +#ifndef FEATURE_SSPM_NUM +#define FEATURE_SSPM_NUM 1 +#endif + +#ifndef FEATURE_MCUPM_NUM +#define FEATURE_MCUPM_NUM 1 +#endif + +#ifndef FEATURE_SCP_NUM +#define FEATURE_SCP_NUM 0 +#endif + +#define ONDIEMET_NUM (FEATURE_SSPM_NUM + FEATURE_MCUPM_NUM + FEATURE_SCP_NUM) + + +/***************************************************************************** + * struct & enum declaration + *****************************************************************************/ +enum { + ONDIEMET_SSPM, + ONDIEMET_MCUPM, + ONDIEMET_SCP, +}; + + +/***************************************************************************** + * external function declaration + *****************************************************************************/ +int ondiemet_attr_init(struct device *dev); +int ondiemet_attr_uninit(struct device *dev); + +int ondiemet_log_manager_init(struct device *dev); +int ondiemet_log_manager_uninit(struct device *dev); +void ondiemet_log_manager_start(void); +void ondiemet_log_manager_stop(void); + +void ondiemet_start(void); +void ondiemet_stop(void); +void ondiemet_extract(void); + + +/***************************************************************************** + * external variable declaration + *****************************************************************************/ +extern unsigned int ondiemet_module[ONDIEMET_NUM]; + + +#endif /* __TINYSYS_MGR_H__ */ diff --git a/drivers/misc/mediatek/met_drv_v2/common/trace.h b/drivers/misc/mediatek/met_drv_v2/common/trace.h new file mode 100644 index 0000000000000000000000000000000000000000..8dd5d6524d190e6c52debcb805beee0bc4e9186b --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/trace.h @@ -0,0 +1,105 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef _TRACE_H_ +#define _TRACE_H_ + + +extern void (*mp_cp_ptr)(unsigned long long timestamp, + struct task_struct *task, + unsigned long program_counter, + unsigned long dcookie, + unsigned long offset, + unsigned char cnt, unsigned int *value); + +#define MP_FMT1 "%x\n" +#define MP_FMT2 "%x,%x\n" +#define MP_FMT3 "%x,%x,%x\n" +#define MP_FMT4 "%x,%x,%x,%x\n" +#define MP_FMT5 "%x,%x,%x,%x,%x\n" +#define MP_FMT6 "%x,%x,%x,%x,%x,%x\n" +#define MP_FMT7 "%x,%x,%x,%x,%x,%x,%x\n" +#define MP_FMT8 "%x,%x,%x,%x,%x,%x,%x,%x\n" +#define MP_FMT9 "%x,%x,%x,%x,%x,%x,%x,%x,%x\n" +#define MP_FMT10 "%x,%x,%x,%x,%x,%x,%x,%x,%x,%x\n" +#define MP_FMT11 "%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x\n" +#define MP_FMT12 "%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x\n" +#define MP_FMT13 "%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x\n" +#define MP_FMT14 "%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x\n" +#define MP_FMT15 "%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x\n" + +#define MET_GENERAL_PRINT(FUNC, count, value) \ +do { \ + switch (count) { \ + case 1: { \ + FUNC(MP_FMT1, value[0]); \ + } \ + break; \ + case 2: { \ + FUNC(MP_FMT2, value[0], value[1]); \ + } \ + break; \ + case 3: { \ + FUNC(MP_FMT3, value[0], value[1], value[2]); \ + } \ + break; \ + case 4: { \ + FUNC(MP_FMT4, value[0], value[1], value[2], value[3]); \ + } \ + break; \ + case 5: { \ + FUNC(MP_FMT5, value[0], value[1], value[2], value[3], value[4]); \ + } \ + break; \ + case 6: { \ + FUNC(MP_FMT6, value[0], value[1], value[2], value[3], value[4], value[5]); \ + } \ + break; \ + case 7: { \ + FUNC(MP_FMT7, value[0], value[1], value[2], value[3], value[4], value[5], value[6]); \ + } \ + break; \ + case 8: { \ + FUNC(MP_FMT8, value[0], value[1], value[2], value[3], value[4], value[5], value[6], value[7]); \ + } \ + break; \ + case 9: { \ + FUNC(MP_FMT9, value[0], value[1], value[2], value[3], value[4], value[5], value[6], value[7], \ + value[8]); \ + } \ + break; \ + case 10: { \ + FUNC(MP_FMT10, value[0], value[1], value[2], value[3], value[4], value[5], value[6], value[7], \ + value[8], value[9]); \ + } \ + break; \ + case 11: { \ + FUNC(MP_FMT11, value[0], value[1], value[2], value[3], value[4], value[5], value[6], value[7], \ + value[8], value[9], value[10]); \ + } \ + break; \ + case 12: { \ + FUNC(MP_FMT12, value[0], value[1], value[2], value[3], value[4], value[5], value[6], value[7], \ + value[8], value[9], value[10], value[11]); \ + } \ + break; \ + case 13: { \ + FUNC(MP_FMT13, value[0], value[1], value[2], value[3], value[4], value[5], value[6], value[7], \ + value[8], value[9], value[10], value[11], value[12]); \ + } \ + break; \ + case 14: { \ + FUNC(MP_FMT14, value[0], value[1], value[2], value[3], value[4], value[5], value[6], value[7], \ + value[8], value[9], value[10], value[11], value[12], value[13]); \ + } \ + break; \ + case 15: { \ + FUNC(MP_FMT15, value[0], value[1], value[2], value[3], value[4], value[5], value[6], value[7], \ + value[8], value[9], value[10], value[11], value[12], value[13], value[14]); \ + } \ + break; \ + } \ +} while (0) +#endif /* _TRACE_H_ */ diff --git a/drivers/misc/mediatek/met_drv_v2/common/trace_event.c b/drivers/misc/mediatek/met_drv_v2/common/trace_event.c new file mode 100644 index 0000000000000000000000000000000000000000..7d0002aa0344d677567544f9b5b53c9b3af5162f --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/trace_event.c @@ -0,0 +1,266 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include +#include "interface.h" +#include "met_drv.h" + +#if IS_ENABLED(CONFIG_GPU_TRACEPOINTS) +#include + +#define show_secs_from_ns(ns) \ + ({ \ + u64 t = ns + (NSEC_PER_USEC / 2); \ + do_div(t, NSEC_PER_SEC); \ + t; \ + }) + +#define show_usecs_from_ns(ns) \ + ({ \ + u64 t = ns + (NSEC_PER_USEC / 2) ; \ + u32 rem; \ + do_div(t, NSEC_PER_USEC); \ + rem = do_div(t, USEC_PER_SEC); \ + }) + +static int event_gpu_registered; +static int event_gpu_enabled; + +noinline void gpu_sched_switch(const char *gpu_name, u64 timestamp, + u32 next_ctx_id, s32 next_prio, u32 next_job_id) +{ + MET_TRACE("gpu_name=%s ts=%llu.%06lu next_ctx_id=%lu next_prio=%ld next_job_id=%lu\n", + gpu_name, + (unsigned long long)show_secs_from_ns(timestamp), + (unsigned long)show_usecs_from_ns(timestamp), + (unsigned long)next_ctx_id, (long)next_prio, (unsigned long)next_job_id); +} + +MET_DEFINE_PROBE(gpu_sched_switch, TP_PROTO(const char *gpu_name, u64 timestamp, + u32 next_ctx_id, s32 next_prio, u32 next_job_id)) +{ + gpu_sched_switch(gpu_name, timestamp, next_ctx_id, next_prio, next_job_id); +} + +noinline void gpu_job_enqueue(u32 ctx_id, u32 job_id, const char *type) +{ + MET_TRACE("ctx_id=%lu job_id=%lu type=%s", + (unsigned long)ctx_id, (unsigned long)job_id, type); +} + +MET_DEFINE_PROBE(gpu_job_enqueue, TP_PROTO(u32 ctx_id, u32 job_id, const char *type)) +{ + gpu_job_enqueue(ctx_id, job_id, type); +} +#endif + + +#ifdef MET_EVENT_POWER_SUPPORT +#include "met_power.h" +#include "met_kernel_symbol.h" + +static int event_power_registered; +static int event_power_enabled; + +const char * +met_trace_print_symbols_seq(char* pclass_name, unsigned long val, + const struct trace_print_flags *symbol_array) +{ + int i; + size_t new_fsize=0; + char _buf[32]; + const char *ret = pclass_name; + + for (i = 0; symbol_array[i].name; i++) { + + if (val != symbol_array[i].mask) + continue; + + new_fsize = sprintf(pclass_name, symbol_array[i].name, strlen(symbol_array[i].name)); + break; + } + + if (new_fsize == 0) { + snprintf(_buf, 32, "0x%lx", val); + new_fsize = sprintf(pclass_name, _buf, strlen(_buf)); + } + + return ret; +} + +#define __print_symbolic(pclass_name, value, symbol_array...) \ + ({ \ + static const struct trace_print_flags symbols[] = \ + { symbol_array, { -1, NULL }}; \ + met_trace_print_symbols_seq(pclass_name, value, symbols); \ + }) + +#ifdef pm_qos_update_request +#undef pm_qos_update_request +#endif +void pm_qos_update_request(int pm_qos_class, s32 value) +{ + char class_name[64]; + MET_TRACE("pm_qos_class=%s value=%d owner=%s\n", + __print_symbolic(class_name, pm_qos_class, + { _PM_QOS_CPU_DMA_LATENCY, "CPU_DMA_LATENCY" }, + { _PM_QOS_NETWORK_LATENCY, "NETWORK_LATENCY" }, + { _PM_QOS_NETWORK_THROUGHPUT, "NETWORK_THROUGHPUT" }), + value); +} +//#endif + +#ifdef pm_qos_update_target +#undef pm_qos_update_target +#endif +void pm_qos_update_target(unsigned int action, int prev_value, int curr_value) +{ + char class_name[64]; + + MET_TRACE("action=%s prev_value=%d curr_value=%d\n", + __print_symbolic(class_name, action, + { _PM_QOS_ADD_REQ, "ADD_REQ" }, + { _PM_QOS_UPDATE_REQ, "UPDATE_REQ" }, + { _PM_QOS_REMOVE_REQ, "REMOVE_REQ" }), + prev_value, curr_value); +} +#endif +//#endif + +static int reset_driver_stat(void) +{ +#if IS_ENABLED(CONFIG_GPU_TRACEPOINTS) + event_gpu_enabled = 0; +#endif +#ifdef MET_EVENT_POWER_SUPPORT + event_power_enabled = 0; +#endif + + met_trace_event.mode = 0; + return 0; +} + + + +static void met_event_start(void) +{ +#if IS_ENABLED(CONFIG_GPU_TRACEPOINTS) + /* register trace event for gpu */ + do { + if (!event_gpu_enabled) + break; + if (MET_REGISTER_TRACE(gpu_sched_switch)) { + pr_debug("can not register callback of gpu_sched_switch\n"); + break; + } + if (MET_REGISTER_TRACE(gpu_job_enqueue)) { + pr_debug("can not register callback of gpu_job_enqueue\n"); + MET_UNREGISTER_TRACE(gpu_sched_switch); + break; + } + event_gpu_registered = 1; + } while (0); +#endif + +#ifdef MET_EVENT_POWER_SUPPORT + /* register trace event for power */ + do { + if (!event_power_enabled) + break; + if (met_export_api_symbol->met_reg_event_power) + if (met_export_api_symbol->met_reg_event_power()) { + pr_debug("can not register callback of met_reg_event_power\n"); + break; + } + event_power_registered = 1; + } while (0); +#endif + +} + +static void met_event_stop(void) +{ +#if IS_ENABLED(CONFIG_GPU_TRACEPOINTS) + /* unregister trace event for gpu */ + if (event_gpu_registered) { + MET_UNREGISTER_TRACE(gpu_job_enqueue); + MET_UNREGISTER_TRACE(gpu_sched_switch); + event_gpu_registered = 0; + } +#endif + +#ifdef MET_EVENT_POWER_SUPPORT + /* unregister trace event for power */ + if (event_power_registered) { + if (met_export_api_symbol->met_unreg_event_power) + met_export_api_symbol->met_unreg_event_power(); + event_power_registered = 0; + } +#endif +} + +static int met_event_process_argument(const char *arg, int len) +{ + int ret = -1; + +#if IS_ENABLED(CONFIG_GPU_TRACEPOINTS) + if (strcasecmp(arg, "gpu") == 0) { + event_gpu_enabled = 1; + met_trace_event.mode = 1; + ret = 0; + } +#endif +#ifdef MET_EVENT_POWER_SUPPORT + if (strcasecmp(arg, "power") == 0) { + event_power_enabled = 1; + met_trace_event.mode = 1; + ret = 0; + } +#endif + return ret; +} + +static const char help[] = "\b" +#if IS_ENABLED(CONFIG_GPU_TRACEPOINTS) + " --event=gpu output gpu trace events\n" +#endif +#ifdef MET_EVENT_POWER_SUPPORT + " --event=power output pmqos trace events\n" +#endif + ; + +static int met_event_print_help(char *buf, int len) +{ + return snprintf(buf, PAGE_SIZE, help); +} + +static const char header[] = + "met-info [000] 0.0: met_ftrace_event:" +#if IS_ENABLED(CONFIG_GPU_TRACEPOINTS) + " gpu:gpu_sched_switch gpu:gpu_job_enqueue" +#endif +#ifdef MET_EVENT_POWER_SUPPORT + " power:pm_qos_update_request power:pm_qos_update_target" +#endif + "\n"; + +static int met_event_print_header(char *buf, int len) +{ + int ret; + + ret = snprintf(buf, PAGE_SIZE, header); + return ret; +} + +struct metdevice met_trace_event = { + .name = "event", + .type = MET_TYPE_PMU, + .start = met_event_start, + .stop = met_event_stop, + .reset = reset_driver_stat, + .process_argument = met_event_process_argument, + .print_help = met_event_print_help, + .print_header = met_event_print_header, +}; diff --git a/drivers/misc/mediatek/met_drv_v2/common/util.c b/drivers/misc/mediatek/met_drv_v2/common/util.c new file mode 100644 index 0000000000000000000000000000000000000000..a53495b759b8b50ed862898a3acee344dcc6b33a --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/util.c @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include "util.h" +#include +#include +/* #include */ +#include + +#ifdef FILELOG + +static char tmp[1000] = { 0 }; + + /*TODO*/ +/** + * open file + * @param name path to open + * @return file pointer + */ +struct file *open_file(const char *name) +{ + struct file *fp = NULL; + + fp = filp_open(name, O_WRONLY | O_APPEND /*| O_TRUNC */ | O_CREAT, 0664); + if (unlikely(fp == NULL)) { + pr_debug(KERNEL_INFO "can not open result file"); + return NULL; + } + return fp; +} + +/** + * write to file + * @param fp file pointer + * @param format format string + * @param ... variable-length subsequent arguments + */ +void write_file(struct file *fp, const char *format, ...) +{ + va_list va; + mm_segment_t fs = get_fs(); + + va_start(va, format); + vsnprintf(tmp, sizeof(tmp), format, va); + set_fs(KERNEL_DS); + vfs_write(fp, tmp, strlen(tmp), &(fp->f_pos)); + set_fs(fs); + va_end(va); +} + +/** + * close file + * @param fp file pointer + * @return exit code + */ +int close_file(struct file *fp) +{ + if (likely(fp != NULL)) { + filp_close(fp, NULL); + fp = NULL; + return 0; + } + pr_debug("cannot close file pointer:%p\n", fp); + return -1; +} + +void filelog(char *str) +{ + struct file *fp; + + fp = open_file("/data/met.log"); + if (fp != NULL) { + write_file(fp, "%s", str); + close_file(fp); + } +} + +#endif /* FILELOG */ diff --git a/drivers/misc/mediatek/met_drv_v2/common/util.h b/drivers/misc/mediatek/met_drv_v2/common/util.h new file mode 100644 index 0000000000000000000000000000000000000000..2645a089dba9bcff0c31c670aa407acf1df3f198 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/util.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef _SRC_UTIL_H_ +#define _SRC_UTIL_H_ + +/* #define FILELOG 1 */ + +#ifdef FILELOG +void filelog(char *str); +#else +#define filelog(str) +#endif + +#endif /* _SRC_UTIL_H_ */ diff --git a/drivers/misc/mediatek/met_drv_v2/common/v6_pmu_hw.c b/drivers/misc/mediatek/met_drv_v2/common/v6_pmu_hw.c new file mode 100644 index 0000000000000000000000000000000000000000..348866fe353aedf1f9445f259fbc305b236f453c --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/v6_pmu_hw.c @@ -0,0 +1,234 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include "cpu_pmu.h" + +/******************************* + * ARM v6 operations * + *******************************/ +#define ARMV6_PMCR_ENABLE (1 << 0) +#define ARMV6_PMCR_CTR01_RESET (1 << 1) +#define ARMV6_PMCR_CCOUNT_RESET (1 << 2) +#define ARMV6_PMCR_CCOUNT_DIV (1 << 3) +#define ARMV6_PMCR_COUNT0_IEN (1 << 4) +#define ARMV6_PMCR_COUNT1_IEN (1 << 5) +#define ARMV6_PMCR_CCOUNT_IEN (1 << 6) +#define ARMV6_PMCR_COUNT0_OVERFLOW (1 << 8) +#define ARMV6_PMCR_COUNT1_OVERFLOW (1 << 9) +#define ARMV6_PMCR_CCOUNT_OVERFLOW (1 << 10) +#define ARMV6_PMCR_EVT_COUNT0_SHIFT 20 +#define ARMV6_PMCR_EVT_COUNT0_MASK (0xFF << ARMV6_PMCR_EVT_COUNT0_SHIFT) +#define ARMV6_PMCR_EVT_COUNT1_SHIFT 12 +#define ARMV6_PMCR_EVT_COUNT1_MASK (0xFF << ARMV6_PMCR_EVT_COUNT1_SHIFT) + +#define ARMV6_PMCR_OVERFLOWED_MASK \ + (ARMV6_PMCR_COUNT0_OVERFLOW | ARMV6_PMCR_COUNT1_OVERFLOW | \ + ARMV6_PMCR_CCOUNT_OVERFLOW) + +enum armv6_counters { + ARMV6_COUNTER0 = 0, + ARMV6_COUNTER1, + ARMV6_CYCLE_COUNTER, +}; + +static inline unsigned long armv6_pmcr_read(void) +{ + u32 val; + + asm volatile ("mrc p15, 0, %0, c15, c12, 0":"=r" (val)); + return val; +} + +static inline void armv6_pmcr_write(unsigned long val) +{ + asm volatile ("mcr p15, 0, %0, c15, c12, 0"::"r" (val)); +} + +static inline unsigned int armv6_pmu_read_count(unsigned int idx) +{ + unsigned long value = 0; + + if (idx == ARMV6_CYCLE_COUNTER) + asm volatile ("mrc p15, 0, %0, c15, c12, 1":"=r" (value)); + else if (idx == ARMV6_COUNTER0) + asm volatile ("mrc p15, 0, %0, c15, c12, 2":"=r" (value)); + else if (idx == ARMV6_COUNTER1) + asm volatile ("mrc p15, 0, %0, c15, c12, 3":"=r" (value)); + + return value; +} + +static inline void armv6_pmu_overflow(void) +{ + unsigned int val; + + val = armv6_pmcr_read(); + val |= ARMV6_PMCR_OVERFLOWED_MASK; + armv6_pmcr_write(val); +} + +static inline unsigned int armv6_pmu_control_read(void) +{ + u32 val; + + asm volatile ("mrc p15, 0, %0, c15, c12, 0":"=r" (val)); + return val; +} + +static inline void armv6_pmu_control_write(unsigned int setting) +{ + unsigned long val; + + val = armv6_pmcr_read(); + val |= setting; + armv6_pmcr_write(val); +} + +static void armv6_pmu_hw_reset_all(void) +{ + unsigned long val; + + val = armv6_pmcr_read(); + val &= ~ARMV6_PMCR_ENABLE; /* disable all counters */ + val |= (ARMV6_PMCR_CTR01_RESET | ARMV6_PMCR_CCOUNT_RESET); /* reset CCNT, PMNC1/2 counter to zero */ + armv6_pmcr_write(val); + + armv6_pmu_overflow(); +} + +static void armv6pmu_enable_event(int idx, unsigned short config) +{ + unsigned long val, mask, evt; + + if (idx == ARMV6_CYCLE_COUNTER) { + mask = 0; + evt = ARMV6_PMCR_CCOUNT_IEN; + } else if (idx == ARMV6_COUNTER0) { + mask = ARMV6_PMCR_EVT_COUNT0_MASK; + evt = (config << ARMV6_PMCR_EVT_COUNT0_SHIFT) | ARMV6_PMCR_COUNT0_IEN; + } else if (idx == ARMV6_COUNTER1) { + mask = ARMV6_PMCR_EVT_COUNT1_MASK; + evt = (config << ARMV6_PMCR_EVT_COUNT1_SHIFT) | ARMV6_PMCR_COUNT1_IEN; + } else { + pr_debug("invalid counter number (%d)\n", idx); + return; + } + + /* + * Mask out the current event and set the counter to count the event + * that we're interested in. + */ + val = armv6_pmcr_read(); + val &= ~mask; + val |= evt; + armv6_pmcr_write(val); +} + +/*********************************** + * MET ARM v6 operations * + ***********************************/ +enum ARM_TYPE { + ARM1136 = 0xB36, + ARM1156 = 0xB56, + ARM1176 = 0xB76, + CHIP_UNKNOWN = 0xFFF +}; + +struct chip_pmu { + enum ARM_TYPE type; +}; + +static struct chip_pmu chips[] = { + {ARM1136}, + {ARM1156}, + {ARM1176}, +}; + +static int armv6_pmu_hw_check_event(struct met_pmu *pmu, int idx, int event) +{ + int i; + + /* Check if event is duplicate */ + for (i = 0; i < idx; i++) { + if (pmu[i].event == event) + break; + } + if (i < idx) { + /* pr_debug("++++++ found duplicate event 0x%02x i=%d\n", event, i); */ + return -1; + } + + return 0; +} + +static void armv6_pmu_hw_start(struct met_pmu *pmu, int count) +{ + int i; + int generic = count - 1; + + armv6_pmu_hw_reset_all(); + + for (i = 0; i < generic; i++) { + if (pmu[i].mode == MODE_POLLING) + armv6pmu_enable_event(i, pmu[i].event); + } + + if (pmu[count - 1].mode == MODE_POLLING) + armv6pmu_enable_event(2, pmu[2].event); + + armv6_pmu_control_write(ARMV6_PMCR_ENABLE); +} + +static void armv6_pmu_hw_stop(int count) +{ + armv6_pmu_hw_reset_all(); +} + +static unsigned int armv6_pmu_hw_polling(struct met_pmu *pmu, int count, unsigned int *pmu_value) +{ + int i, cnt = 0; + int generic = count - 1; + + for (i = 0; i < generic; i++) { + if (pmu[i].mode == MODE_POLLING) { + pmu_value[cnt] = armv6_pmu_read_count(i); + cnt++; + } + } + + if (pmu[count - 1].mode == MODE_POLLING) { + pmu_value[cnt] = armv6_pmu_read_count(2); + cnt++; + } + + armv6_pmu_control_write(ARMV6_PMCR_ENABLE | ARMV6_PMCR_CTR01_RESET | + ARMV6_PMCR_CCOUNT_RESET); + + return cnt; +} + +struct cpu_pmu_hw armv6_pmu = { + .name = "armv6_pmu", + .check_event = armv6_pmu_hw_check_event, + .start = armv6_pmu_hw_start, + .stop = armv6_pmu_hw_stop, + .polling = armv6_pmu_hw_polling, +}; + +struct cpu_pmu_hw *v6_cpu_pmu_hw_init(int typeid) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(chips); i++) + if (chips[i].type == typeid) + break; + + if (i == ARRAY_SIZE(chips)) + return NULL; + + armv6_pmu.nr_cnt = 3; + + return &armv6_pmu; +} diff --git a/drivers/misc/mediatek/met_drv_v2/common/v6_pmu_hw.h b/drivers/misc/mediatek/met_drv_v2/common/v6_pmu_hw.h new file mode 100644 index 0000000000000000000000000000000000000000..27eb8c1686c58d4783a1c132ab9190475c3faf67 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/v6_pmu_hw.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef __V6_PMU_HW_H__ +#define __V6_PMU_HW_H__ + +extern struct cpu_pmu_hw armv6_pmu; +extern struct cpu_pmu_hw *v6_cpu_pmu_hw_init(int typeid); + +#endif diff --git a/drivers/misc/mediatek/met_drv_v2/common/v7_pmu_hw.c b/drivers/misc/mediatek/met_drv_v2/common/v7_pmu_hw.c new file mode 100644 index 0000000000000000000000000000000000000000..3f423692e4aefeadb012b0d1e4fc95cb3d86eade --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/v7_pmu_hw.c @@ -0,0 +1,288 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include "cpu_pmu.h" +#include "v6_pmu_hw.h" + +/******************************* + * ARM v7 operations * + *******************************/ +#define ARMV7_PMCR_E (1 << 0) /* enable all counters */ +#define ARMV7_PMCR_P (1 << 1) +#define ARMV7_PMCR_C (1 << 2) +#define ARMV7_PMCR_D (1 << 3) +#define ARMV7_PMCR_X (1 << 4) +#define ARMV7_PMCR_DP (1 << 5) +#define ARMV7_PMCR_N_SHIFT 11 /* Number of counters supported */ +#define ARMV7_PMCR_N_MASK 0x1f +#define ARMV7_PMCR_MASK 0x3f /* mask for writable bits */ + +static unsigned int armv7_get_ic(void) +{ + unsigned int value; + /* Read Main ID Register */ + asm volatile ("mrc p15, 0, %0, c0, c0, 0":"=r" (value)); + + value = (value & 0xffff) >> 4; /* primary part number */ + return value; +} + +static inline void armv7_pmu_counter_select(unsigned int idx) +{ + asm volatile ("mcr p15, 0, %0, c9, c12, 5"::"r" (idx)); + isb(); +} + +static inline void armv7_pmu_type_select(unsigned int idx, unsigned int type) +{ + armv7_pmu_counter_select(idx); + asm volatile ("mcr p15, 0, %0, c9, c13, 1"::"r" (type)); +} + +static inline unsigned int armv7_pmu_read_count(unsigned int idx) +{ + unsigned int value; + + if (idx == 31) { + asm volatile ("mrc p15, 0, %0, c9, c13, 0":"=r" (value)); + } else { + armv7_pmu_counter_select(idx); + asm volatile ("mrc p15, 0, %0, c9, c13, 2":"=r" (value)); + } + return value; +} + +static inline void armv7_pmu_write_count(int idx, u32 value) +{ + if (idx == 31) { + asm volatile ("mcr p15, 0, %0, c9, c13, 0"::"r" (value)); + } else { + armv7_pmu_counter_select(idx); + asm volatile ("mcr p15, 0, %0, c9, c13, 2"::"r" (value)); + } +} + +static inline void armv7_pmu_enable_count(unsigned int idx) +{ + asm volatile ("mcr p15, 0, %0, c9, c12, 1"::"r" (1 << idx)); +} + +static inline void armv7_pmu_disable_count(unsigned int idx) +{ + asm volatile ("mcr p15, 0, %0, c9, c12, 2"::"r" (1 << idx)); +} + +static inline void armv7_pmu_enable_intr(unsigned int idx) +{ + asm volatile ("mcr p15, 0, %0, c9, c14, 1"::"r" (1 << idx)); +} + +static inline void armv7_pmu_disable_intr(unsigned int idx) +{ + asm volatile ("mcr p15, 0, %0, c9, c14, 2"::"r" (1 << idx)); +} + +static inline unsigned int armv7_pmu_overflow(void) +{ + unsigned int val; + + asm volatile ("mrc p15, 0, %0, c9, c12, 3":"=r" (val)); /* read */ + asm volatile ("mcr p15, 0, %0, c9, c12, 3"::"r" (val)); + return val; +} + +static inline unsigned int armv7_pmu_control_read(void) +{ + u32 val; + + asm volatile ("mrc p15, 0, %0, c9, c12, 0":"=r" (val)); + return val; +} + +static inline void armv7_pmu_control_write(unsigned int val) +{ + val &= ARMV7_PMCR_MASK; + isb(); + asm volatile ("mcr p15, 0, %0, c9, c12, 0"::"r" (val)); +} + +static int armv7_pmu_hw_get_counters(void) +{ + int count = armv7_pmu_control_read(); + /* N, bits[15:11] */ + count = ((count >> ARMV7_PMCR_N_SHIFT) & ARMV7_PMCR_N_MASK); + return count; +} + +static void armv7_pmu_hw_reset_all(int generic_counters) +{ + int i; + + armv7_pmu_control_write(ARMV7_PMCR_C | ARMV7_PMCR_P); + /* generic counter */ + for (i = 0; i < generic_counters; i++) { + armv7_pmu_disable_intr(i); + armv7_pmu_disable_count(i); + } + /* cycle counter */ + armv7_pmu_disable_intr(31); + armv7_pmu_disable_count(31); + armv7_pmu_overflow(); /* clear overflow */ +} + +/*********************************** + * MET ARM v7 operations * + ***********************************/ +enum ARM_TYPE { + CORTEX_A7 = 0xC07, + CORTEX_A9 = 0xC09, + CORTEX_A12 = 0xC0D, + CORTEX_A15 = 0xC0F, + CORTEX_A17 = 0xC0E, + CORTEX_A53 = 0xD03, + CORTEX_A57 = 0xD07, + CHIP_UNKNOWN = 0xFFF +}; + +struct chip_pmu { + enum ARM_TYPE type; +}; + +static struct chip_pmu chips[] = { + {CORTEX_A7}, + {CORTEX_A9}, + {CORTEX_A12}, + {CORTEX_A15}, + {CORTEX_A17}, + {CORTEX_A53}, + {CORTEX_A57}, +}; + +static int armv7_pmu_hw_check_event(struct met_pmu *pmu, int idx, int event) +{ + int i; + + /* Check if event is duplicate */ + for (i = 0; i < idx; i++) { + if (pmu[i].event == event) + break; + } + if (i < idx) { + /* pr_debug("++++++ found duplicate event 0x%02x i=%d\n", event, i); */ + return -1; + } + + return 0; +} + +static void armv7_pmu_hw_start(struct met_pmu *pmu, int count) +{ + int i; + int generic = count - 1; + + armv7_pmu_hw_reset_all(generic); + for (i = 0; i < generic; i++) { + if (pmu[i].mode == MODE_POLLING) { + armv7_pmu_type_select(i, pmu[i].event); + armv7_pmu_enable_count(i); + } + } + if (pmu[count - 1].mode == MODE_POLLING) { /* cycle counter */ + armv7_pmu_enable_count(31); + } + armv7_pmu_control_write(ARMV7_PMCR_E); +} + +static void armv7_pmu_hw_stop(int count) +{ + int generic = count - 1; + + armv7_pmu_hw_reset_all(generic); +} + +static unsigned int armv7_pmu_hw_polling(struct met_pmu *pmu, int count, unsigned int *pmu_value) +{ + int i, cnt = 0; + int generic = count - 1; + + for (i = 0; i < generic; i++) { + if (pmu[i].mode == MODE_POLLING) { + pmu_value[cnt] = armv7_pmu_read_count(i); + cnt++; + } + } + if (pmu[count - 1].mode == MODE_POLLING) { + pmu_value[cnt] = armv7_pmu_read_count(31); + cnt++; + } + armv7_pmu_control_write(ARMV7_PMCR_C | ARMV7_PMCR_P | ARMV7_PMCR_E); + + return cnt; +} + +#define ARMV7_PMU_EVTYPE_EVENT 0xff + +static unsigned long armv7_perf_event_get_evttype(struct perf_event *ev) { + + struct hw_perf_event *hwc; + + hwc = &ev->hw; + return hwc->config_base & ARMV7_PMU_EVTYPE_EVENT; +} + +#define PMU_OVSR_MASK 0xffffffff /* Mask for writable bits */ + +static u32 armv7_pmu_read_clear_overflow_flag(void) +{ + u32 value; + + asm volatile ("mrc p3, 3, %0, c9, c12, 3":"=r" (value)); + + /* Write to clear flags */ + value &= PMU_OVSR_MASK; + asm volatile ("mcr p3, 3, %0, c9, c12, 3"::"r" (value)); + + return value; +} + +static struct met_pmu pmus[MXNR_CPU][MXNR_PMU_EVENTS]; + +struct cpu_pmu_hw armv7_pmu = { + .name = "armv7_pmu", + .check_event = armv7_pmu_hw_check_event, + .start = armv7_pmu_hw_start, + .stop = armv7_pmu_hw_stop, + .polling = armv7_pmu_hw_polling, + .perf_event_get_evttype = armv7_perf_event_get_evttype, + .pmu_read_clear_overflow_flag = armv7_pmu_read_clear_overflow_flag, +}; + +struct cpu_pmu_hw *cpu_pmu_hw_init(void) +{ + int i; + enum ARM_TYPE type; + struct cpu_pmu_hw *pmu; + + type = (enum ARM_TYPE)armv7_get_ic(); + for (i = 0; i < ARRAY_SIZE(chips); i++) + if (chips[i].type == type) + break; + + if (i < ARRAY_SIZE(chips)) { + armv7_pmu.nr_cnt = armv7_pmu_hw_get_counters() + 1; + pmu = &armv7_pmu; + } else + pmu = v6_cpu_pmu_hw_init(type); + + if (pmu == NULL) + return NULL; + + for (i = 0; i < MXNR_CPU; i++) { + pmu->event_count[i] = pmu->nr_cnt; + pmu->pmu[i] = pmus[i]; + } + + return pmu; +} diff --git a/drivers/misc/mediatek/met_drv_v2/common/v8_dsu_hw.c b/drivers/misc/mediatek/met_drv_v2/common/v8_dsu_hw.c new file mode 100644 index 0000000000000000000000000000000000000000..06a56bcc9a18a9f96700fd2ded1fce1c516b5529 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/v8_dsu_hw.c @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include +#include "met_kernel_symbol.h" +#include "cpu_dsu.h" + +//dsu support 6 event +#define DSU_EVENT_MAX_CNT 6 + +static int armv8_dsu_hw_check_event(struct met_dsu *pmu, int idx, int event) +{ + int i; + + /* Check if event is duplicate */ + for (i = 0; i < idx; i++) { + if (pmu[i].event == event) + break; + } + if (i < idx) { + /* pr_debug("++++++ found duplicate event 0x%02x i=%d\n", event, i); */ + return -1; + } + return 0; +} + + +static struct met_dsu pmus[MXNR_DSU_EVENTS]; + +struct cpu_dsu_hw armv8_dsu = { + .name = "armv8_dsu", + .check_event = armv8_dsu_hw_check_event, +}; + +static void init_dsu(void) +{ + armv8_dsu.event_count = DSU_EVENT_MAX_CNT; +} + +struct cpu_dsu_hw *cpu_dsu_hw_init(void) +{ + + init_dsu(); + armv8_dsu.pmu = pmus; + return &armv8_dsu; +} diff --git a/drivers/misc/mediatek/met_drv_v2/common/v8_pmu_hw.c b/drivers/misc/mediatek/met_drv_v2/common/v8_pmu_hw.c new file mode 100644 index 0000000000000000000000000000000000000000..2b904add2a0bc85f6ae90f869150e2cbf122bed9 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/v8_pmu_hw.c @@ -0,0 +1,287 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include +#include +#include "met_kernel_symbol.h" +#include "cpu_pmu.h" + +/******************************* + * ARM v8 operations * + *******************************/ +/* + * Per-CPU PMCR: config reg + */ +#define ARMV8_PMCR_E (1 << 0) /* Enable all counters */ +#define ARMV8_PMCR_P (1 << 1) /* Reset all counters */ +#define ARMV8_PMCR_C (1 << 2) /* Cycle counter reset */ +#define ARMV8_PMCR_D (1 << 3) /* CCNT counts every 64th cpu cycle */ +#define ARMV8_PMCR_X (1 << 4) /* Export to ETM */ +#define ARMV8_PMCR_DP (1 << 5) /* Disable CCNT if non-invasive debug */ +#define ARMV8_PMCR_N_SHIFT 11 /* Number of counters supported */ +#define ARMV8_PMCR_N_MASK 0x1f +#define ARMV8_PMCR_MASK 0x3f /* Mask for writable bits */ + +/* + * PMOVSR: counters overflow flag status reg + */ +#define ARMV8_OVSR_MASK 0xffffffff /* Mask for writable bits */ +#define ARMV8_OVERFLOWED_MASK ARMV8_OVSR_MASK + +static inline void armv8_pmu_counter_select(unsigned int idx) +{ + asm volatile ("msr pmselr_el0, %x0"::"r" (idx)); + isb(); +} + +static inline void armv8_pmu_type_select(unsigned int idx, unsigned int type) +{ + armv8_pmu_counter_select(idx); + asm volatile ("msr pmxevtyper_el0, %x0"::"r" (type)); +} + +static inline unsigned int armv8_pmu_read_count(unsigned int idx) +{ + unsigned int value; + + if (idx == 31) { + asm volatile ("mrs %x0, pmccntr_el0":"=r" (value)); + } else { + armv8_pmu_counter_select(idx); + asm volatile ("mrs %x0, pmxevcntr_el0":"=r" (value)); + } + return value; +} + +static inline void armv8_pmu_enable_count(unsigned int idx) +{ + asm volatile ("msr pmcntenset_el0, %x0"::"r" (1 << idx)); +} + +static inline void armv8_pmu_disable_count(unsigned int idx) +{ + asm volatile ("msr pmcntenclr_el0, %x0"::"r" (1 << idx)); +} + +static inline void armv8_pmu_enable_intr(unsigned int idx) +{ + asm volatile ("msr pmintenset_el1, %x0"::"r" (1 << idx)); +} + +static inline void armv8_pmu_disable_intr(unsigned int idx) +{ + asm volatile ("msr pmintenclr_el1, %x0"::"r" (1 << idx)); + isb(); + asm volatile ("msr pmovsclr_el0, %x0"::"r" (1 << idx)); + isb(); +} + +static inline unsigned int armv8_pmu_overflow(void) +{ + unsigned int val; + + asm volatile ("mrs %x0, pmovsclr_el0":"=r" (val)); /* read */ + val &= ARMV8_OVSR_MASK; + asm volatile ("mrs %x0, pmovsclr_el0"::"r" (val)); + return val; +} + +static inline unsigned int armv8_pmu_control_read(void) +{ + unsigned int val; + + asm volatile ("mrs %x0, pmcr_el0":"=r" (val)); + return val; +} + +static inline void armv8_pmu_control_write(u32 val) +{ + val &= ARMV8_PMCR_MASK; + isb(); + asm volatile ("msr pmcr_el0, %x0"::"r" (val)); +} + +static void armv8_pmu_hw_reset_all(int generic_counters) +{ + int i; + + armv8_pmu_control_write(ARMV8_PMCR_C | ARMV8_PMCR_P); + /* generic counter */ + for (i = 0; i < generic_counters; i++) { + armv8_pmu_disable_intr(i); + armv8_pmu_disable_count(i); + } + /* cycle counter */ + armv8_pmu_disable_intr(31); + armv8_pmu_disable_count(31); + armv8_pmu_overflow(); /* clear overflow */ +} + +/*********************************** + * MET ARM v8 operations * + ***********************************/ +enum ARM_TYPE { + CORTEX_A53 = 0xD03, + CORTEX_A35 = 0xD04, + CORTEX_A55 = 0xD05, + CORTEX_A57 = 0xD07, + CORTEX_A72 = 0xD08, + CORTEX_A73 = 0xD09, + CORTEX_A75 = 0xD0A, + CORTEX_A76 = 0xD0B, + CORTEX_A77 = 0xD0D, + CHIP_UNKNOWN = 0xFFF +}; + +struct chip_pmu { + enum ARM_TYPE type; + unsigned int event_count; +}; + +static struct chip_pmu chips[] = { + {CORTEX_A35, 6+1}, + {CORTEX_A53, 6+1}, + {CORTEX_A55, 6+1}, + {CORTEX_A57, 6+1}, + {CORTEX_A72, 6+1}, + {CORTEX_A73, 6+1}, + {CORTEX_A75, 6+1}, + {CORTEX_A76, 6+1}, + {CORTEX_A77, 6+1}, +}; + +static int armv8_pmu_hw_check_event(struct met_pmu *pmu, int idx, int event) +{ + int i; + + /* Check if event is duplicate */ + for (i = 0; i < idx; i++) { + if (pmu[i].event == event) + break; + } + if (i < idx) { + /* pr_debug("++++++ found duplicate event 0x%02x i=%d\n", event, i); */ + return -1; + } + + return 0; +} + +static void armv8_pmu_hw_start(struct met_pmu *pmu, int count) +{ + int i; + int generic = count - 1; + + armv8_pmu_hw_reset_all(generic); + for (i = 0; i < generic; i++) { + if (pmu[i].mode == MODE_POLLING) { + armv8_pmu_type_select(i, pmu[i].event); + armv8_pmu_enable_count(i); + } + } + if (pmu[count - 1].mode == MODE_POLLING) { /* cycle counter */ + armv8_pmu_enable_count(31); + } + armv8_pmu_control_write(ARMV8_PMCR_E); +} + +static void armv8_pmu_hw_stop(int count) +{ + int generic = count - 1; + + armv8_pmu_hw_reset_all(generic); +} + +static unsigned int armv8_pmu_hw_polling(struct met_pmu *pmu, int count, unsigned int *pmu_value) +{ + int i, cnt = 0; + int generic = count - 1; + + for (i = 0; i < generic; i++) { + if (pmu[i].mode == MODE_POLLING) { + pmu_value[cnt] = armv8_pmu_read_count(i); + cnt++; + } + } + if (pmu[count - 1].mode == MODE_POLLING) { + pmu_value[cnt] = armv8_pmu_read_count(31); + cnt++; + } + armv8_pmu_control_write(ARMV8_PMCR_C | ARMV8_PMCR_P | ARMV8_PMCR_E); + + return cnt; +} + +static unsigned long armv8_perf_event_get_evttype(struct perf_event *ev) { + + struct hw_perf_event *hwc; + + hwc = &ev->hw; + return hwc->config_base & ARMV8_PMU_EVTYPE_EVENT; +} + +#define PMU_OVSR_MASK 0xffffffff /* Mask for writable bits */ + +static u32 armv8_pmu_read_clear_overflow_flag(void) +{ + u32 value; + + asm volatile ("mrs %x0, pmovsclr_el0":"=r" (value)); + + /* Write to clear flags */ + value &= PMU_OVSR_MASK; + asm volatile ("msr pmovsclr_el0, %x0"::"r" (value)); + + return value; +} + +static struct met_pmu pmus[MXNR_CPU][MXNR_PMU_EVENTS]; + +struct cpu_pmu_hw armv8_pmu = { + .name = "armv8_pmu", + .check_event = armv8_pmu_hw_check_event, + .start = armv8_pmu_hw_start, + .stop = armv8_pmu_hw_stop, + .polling = armv8_pmu_hw_polling, + .perf_event_get_evttype = armv8_perf_event_get_evttype, + .pmu_read_clear_overflow_flag = armv8_pmu_read_clear_overflow_flag, +}; + +static void init_pmus(void) +{ + int cpu; + int i; + + for_each_possible_cpu(cpu) { + struct cpuinfo_arm64 *cpuinfo = NULL; + if (cpu >= MXNR_CPU) + continue; + if (met_export_api_symbol->met_get_cpuinfo) + met_export_api_symbol->met_get_cpuinfo(cpu, &cpuinfo); + + if (cpuinfo == NULL) + continue; + + /* PR_BOOTMSG("CPU[%d]: reg_midr = %x\n", cpu, cpuinfo->reg_midr); */ + /* PR_BOOTMSG("CPU[%d]: MIDR_PARTNUM = %x\n", cpu, MIDR_PARTNUM(cpuinfo->reg_midr)); */ + for (i = 0; i < ARRAY_SIZE(chips); i++) { + if (chips[i].type == MIDR_PARTNUM(cpuinfo->reg_midr)) { + armv8_pmu.event_count[cpu] = chips[i].event_count; + break; + } + } + } +} + +struct cpu_pmu_hw *cpu_pmu_hw_init(void) +{ + int cpu; + + init_pmus(); + for (cpu = 0; cpu < MXNR_CPU; cpu++) + armv8_pmu.pmu[cpu] = pmus[cpu]; + + return &armv8_pmu; +} diff --git a/drivers/misc/mediatek/met_drv_v2/common/version.h b/drivers/misc/mediatek/met_drv_v2/common/version.h new file mode 100644 index 0000000000000000000000000000000000000000..ba33a4a5ce94e96bc211b2d73ccbcd4ac4efcf80 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/common/version.h @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#define MET_BACKEND_VERSION "6.2.0" diff --git a/drivers/misc/mediatek/met_drv_v2/default/Kbuild b/drivers/misc/mediatek/met_drv_v2/default/Kbuild new file mode 100644 index 0000000000000000000000000000000000000000..9b2bb8783febcc36f0bf2884e7f9942af1d601aa --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/default/Kbuild @@ -0,0 +1,6 @@ +obj-m := met.o + +ccflags-y += -I$(srctree)/include/ + +met-y := default/met_main.o + diff --git a/drivers/misc/mediatek/met_drv_v2/default/met_main.c b/drivers/misc/mediatek/met_drv_v2/default/met_main.c new file mode 100644 index 0000000000000000000000000000000000000000..33ada72e50c90d8260630c4f6ce725c517044def --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/default/met_main.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int __init met_drv_init(void) +{ + pr_info("Hello MET default module\n"); + return 0; +} + +static void __exit met_drv_exit(void) +{ +} +module_init(met_drv_init); +module_exit(met_drv_exit); + +MODULE_AUTHOR("DT_DM5"); +MODULE_DESCRIPTION("MET_DEFAULT"); +MODULE_LICENSE("GPL"); diff --git a/drivers/misc/mediatek/met_drv_v2/mt6765/Kbuild b/drivers/misc/mediatek/met_drv_v2/mt6765/Kbuild new file mode 100644 index 0000000000000000000000000000000000000000..b37838f03e1987accaa411747addb73c560ec7e8 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/mt6765/Kbuild @@ -0,0 +1,3 @@ +MET_PLF := $(MTK_PLATFORM) + +met-y += diff --git a/drivers/misc/mediatek/met_drv_v2/mt6765/Kbuild.platform.inc b/drivers/misc/mediatek/met_drv_v2/mt6765/Kbuild.platform.inc new file mode 100644 index 0000000000000000000000000000000000000000..e41e6a692e7553c54e0460349cb26b3fc61e4d3b --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/mt6765/Kbuild.platform.inc @@ -0,0 +1,21 @@ +################################################################################ +# Include Path +################################################################################ +#MET_VCOREDVFS_INC := $(srctree)/drivers/misc/mediatek/base/power/include/vcorefs_v3 +MET_PTPOD_INC := $(srctree)/drivers/misc/mediatek/base/power/cpufreq_v1/src/mach/$(MTK_PLATFORM)/ + +################################################################################ +# Feature Spec +# CPUPMU_VERSION: V8_0/V8_2 +# EMI_SEDA_VERSION: SEDA2/SEDA3/SEDA3_5 +################################################################################ +CPUPMU_VERSION := V8_0 +EMI_SEDA_VERSION := SEDA3 + +################################################################################ +# Feature On/Off +################################################################################ +FEATURE_SPMTWAM := n +FEATURE_EVENT_POWER := n +FEATURE_ONDIEMET := y +FEATURE_TINYSYS := n diff --git a/drivers/misc/mediatek/met_drv_v2/mt6765/met_dramc.h b/drivers/misc/mediatek/met_drv_v2/mt6765/met_dramc.h new file mode 100644 index 0000000000000000000000000000000000000000..d7aa38e8a354dd293d0be87401b21979acf6ae2e --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/mt6765/met_dramc.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +#ifndef __MTK_DRAMC_H__ +#define __MTK_DRAMC_H__ + +#define DRAMC_VER 2 + + +#endif /* __MTK_DRAMC_REG_H__ */ diff --git a/drivers/misc/mediatek/met_drv_v2/mt6765/met_gpu_monitor.h b/drivers/misc/mediatek/met_drv_v2/mt6765/met_gpu_monitor.h new file mode 100644 index 0000000000000000000000000000000000000000..8dd721183540921315e2b87bc58f7cc91b4a8457 --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/mt6765/met_gpu_monitor.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2016 MediaTek Inc. + */ + +#ifndef __MET_GPU_MONITOR_H__ +#define __MET_GPU_MONITOR_H__ + +#undef MET_GPU_STALL_MONITOR + +#endif /* __MET_GPU_MONITOR_H__ */ diff --git a/drivers/misc/mediatek/met_drv_v2/mt6765/met_sspm_rts_event.h b/drivers/misc/mediatek/met_drv_v2/mt6765/met_sspm_rts_event.h new file mode 100644 index 0000000000000000000000000000000000000000..4d235806a1f7d03910f9c9ded7a18332ff0e279b --- /dev/null +++ b/drivers/misc/mediatek/met_drv_v2/mt6765/met_sspm_rts_event.h @@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +MET_SSPM_RTS_EVNET(SSPM_PTPOD, "_id,voltage") +MET_SSPM_RTS_EVNET(SSPM_MET_UNIT_TEST, "test")